summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordaryll <daryll>1999-12-05 00:59:08 +0000
committerdaryll <daryll>1999-12-05 00:59:08 +0000
commitfdec2a5e358ec6bb9857587680f00bd2c91413b6 (patch)
tree6969674a81da39a1fcd74421ece69c010c28012e
parent504880db5611bf0f57206abe44835959c2729147 (diff)
Import XFree 3.9.16
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/man/XF86Config.man1512
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/man/XFree86.man760
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/1st.sgml104
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/CPYRIGHT.sgml267
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/Config.sgml546
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/DocIndex.sgml117
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/FreeBSD.sgml559
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/INSTALL.sgml344
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/LinkKit.sgml228
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/Linux.sgml345
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/Mach64.sgml599
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/QStart.sgml1351
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/README.sgml1007
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/RELNOTE.sgml1766
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/S3.sgml872
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/VGADriv.sgml1574
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/VidModes.sgml1142
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/ati.sgml389
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/cirrus.sgml1123
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/read98.sgml169
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/VideoModes.doc4
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/man/Imakefile15
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/man/XF86DGA.man201
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/man/XF86Misc.man216
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/man/XF86VM.man343
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/3Dlabs.sgml84
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/BUILD.sgml224
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/Bsdi.sgml327
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/Config.sgml527
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/DECtga.sgml71
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/DESIGN.sgml6903
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/DGux.sgml789
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/DocIndex.sgml132
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/FreeBSD.sgml354
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/I128.sgml90
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/Imakefile95
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/LICENSE.sgml615
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/Linux.sgml149
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/LynxOS.sgml552
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/MGA.sgml185
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/Mach32.sgml157
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/Mach64.sgml393
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/NVIDIA.sgml63
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/NetBSD.sgml600
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/OS2.sgml656
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/OS2note.sgml213
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/Oak.sgml213
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/OpenBSD.sgml411
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/P9000.sgml471
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/QStart.sgml677
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/README.sgml134
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/RELNOTES.sgml1037
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/S3.sgml933
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/SCO.sgml535
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/SOLX86.sgml327
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/SVR4.sgml451
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/SiS.sgml116
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/VGADriv.sgml916
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/VidModes.sgml1428
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/Video7.sgml107
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/WstDig.sgml217
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/add.sh13
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/agx.sgml615
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/apm.sgml73
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/ark.sgml239
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/ati.sgml491
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/chips.sgml903
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/cirrus.sgml977
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/cyrix.sgml81
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/defs.ent15
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/epson.sgml155
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/fbdev.sgml369
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/fonts.sgml749
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/i740.sgml147
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/index.post8
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/index.pre18
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/isc.sgml607
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/mouse.sgml671
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/neomagic.sgml170
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/rendition.sgml75
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/s3virge.sgml62
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/trident.sgml171
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/tseng.sgml1053
-rw-r--r--xc/programs/Xserver/hw/xfree86/doc/sgml/xinput.sgml209
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/Imakefile54
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/apm/Imakefile46
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/apm/README109
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/apm/apm.h210
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/apm/apm_accel.c587
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/apm/apm_cursor.c211
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/apm/apm_dga.c406
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/apm/apm_driver.c2068
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/apm/apm_funcs.c1062
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/apm/apm_i2c.c78
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/apm/apm_regs.h206
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/apm/apm_rush.c328
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile134
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/ati.c82
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/ati.h39
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiadapter.c46
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiadapter.h51
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiadjust.c211
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiadjust.h34
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atibank.c398
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atibank.h83
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atibios.c57
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atibios.h34
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atibus.c167
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atibus.h52
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.c436
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.h112
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/aticlock.c1356
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/aticlock.h83
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/aticonsole.c250
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/aticonsole.h44
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/aticrtc.c864
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/aticrtc.h50
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atidac.c310
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atidac.h88
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atidsp.c270
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atidsp.h37
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.c104
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.h47
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiio.c119
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiio.h134
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atilock.c316
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atilock.h33
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.c356
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.h40
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.c154
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h32
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atimono.h43
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.c89
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.h33
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atipreinit.c1645
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atipreinit.h32
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiprint.c536
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiprint.h37
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atipriv.h31
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c1703
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.h32
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiproto.h41
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiregs.h1624
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiscreen.c216
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiscreen.h33
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atistruct.h261
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiutil.c96
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiutil.h62
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/ativalid.c117
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/ativalid.h32
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/ativersion.h38
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/ativga.c428
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/ativga.h40
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atividmem.c149
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atividmem.h76
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiwonder.c296
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/ati/atiwonder.h39
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/chips/Imakefile63
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/chips/ct_BlitMM.h141
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/chips/ct_Blitter.h168
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/chips/ct_BltHiQV.h170
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/chips/ct_accel.c1733
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/chips/ct_bank.c602
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/chips/ct_cursor.c318
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/chips/ct_ddc.c283
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/chips/ct_dga.c304
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.c6229
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.h374
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/chips/ct_regs.c502
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/chips/util/Imakefile13
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/chips/util/dRegs.c277
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/chips/util/mRegs.c149
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/chips/util/modClock.c393
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/cirrus/CirrusClk.c209
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/cirrus/Imakefile57
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/cirrus/README.multihead70
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir.h105
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_dga.c75
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_driver.c2251
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_hwcurs.c250
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_i2c.c122
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_xaa.c251
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_xaam.c264
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg.h145
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_driver.c1795
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_hwcurs.c392
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_i2c.c90
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_xaa.c294
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_xaa.h209
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/confdrv.sh42
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/fbdev/Imakefile49
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c743
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.cpp56
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glide/Imakefile52
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glide/glide.cpp298
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glide/glide_driver.c1122
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/DRI.txt408
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/IBMramdac.c125
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile75
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/TIramdac.c151
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_accel.c1099
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_dac.c749
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h255
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c1876
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h57
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h296
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c2674
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h1232
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_accel.c1773
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_dac.c537
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_video.c2187
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/pm2ramdac.c156
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/pm2v_dac.c456
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/pm2vramdac.c66
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/pm_accel.c1407
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/pm_dac.c240
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/tx_accel.c1041
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/glint/tx_dac.c284
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i740/Imakefile52
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i740/README127
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i740/i740.h141
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i740/i740_accel.c397
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i740/i740_cursor.c205
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i740/i740_driver.c1713
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i740/i740_io.c92
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i740/i740_macros.h59
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/i740/i740_reg.h328
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile67
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/README185
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga.cpp122
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h271
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_arc.c217
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_bios.h143
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c1212
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c951
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dga.c443
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c2721
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_hwcurs.c41
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h74
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_map.h17
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h381
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_shadow.c254
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c1922
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/util/Makefile12
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/util/README25
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/mga/util/stormdwg.c184
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile53
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/neomagic/README150
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/neomagic/TODO20
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h248
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c276
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c343
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c430
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c455
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_bank.c95
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c267
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c2526
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c100
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h63
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h117
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/nv/Imakefile68
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/nv/nv.cpp61
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/nv/nv_const.h20
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/nv/nv_cursor.c193
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c210
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dga.c267
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c1664
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/nv/nv_include.h60
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/nv/nv_proto.h37
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c200
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/nv/nv_type.h140
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c726
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/nv/nvreg.h209
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/nv/nvvga.h84
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.c1368
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.h341
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/nv/riva_tbl.h427
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/Imakefile60
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/cscode.h37
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/rendition.c1081
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/v1kregs.h217
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/v1krisc.c504
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/v1krisc.h34
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/v2kregs.h369
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/vboard.c159
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/vboard.h34
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/vgafont-std.data527
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/vgafont-vrx.data527
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/vgapalette.data277
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/vloaduc.h41
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/vmodes.c538
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/vmodes.h36
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/vos.h88
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/vramdac.c457
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/vramdac.h52
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/vtypes.h146
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/vvga.c349
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/rendition/vvga.h38
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3virge/CALLMAP23
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3virge/Imakefile63
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3virge/README70
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3virge/TODO_NOTES184
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3virge/newmmio.h619
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3virge/regs3v.h433
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v.h377
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_accel.c848
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_dac.c109
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_dga.c309
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_driver.c3208
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_hwcurs.c233
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_i2c.c67
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_macros.h119
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_rop.h207
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3virge.cpp186
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/sis/Imakefile49
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/sis/sis.h106
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c485
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel2.c472
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c734
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c1715
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.h101
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/sis/sis_regs.h207
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/sis/sis_regs2.h171
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/Imakefile66
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx.h183
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_accel.c511
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dga.c223
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c398
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.h24
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dripriv.h24
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c1681
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_hwcurs.c136
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_io.c112
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfxdefs.h175
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tga/BT463ramdac.c140
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tga/BTramdac.c117
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tga/ICS1562.c114
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tga/Imakefile47
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tga/tga.h116
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tga/tga_accel32.c739
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tga/tga_accel8.c947
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tga/tga_cursor.c177
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tga/tga_dac.c169
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c1528
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tga/tga_regs.h182
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/trident/Imakefile56
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/trident/blade_accel.c628
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/trident/image_accel.c605
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/trident/trident.h187
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/trident/trident_accel.c692
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/trident/trident_bank.c51
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c463
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c2175
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/trident/trident_i2c.c77
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/trident/trident_regs.h304
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/trident/tridenthelper.c256
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/trident/tridentramdac.c67
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tseng/Imakefile63
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tseng/README264
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng.h357
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_accel.c942
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_acl.c402
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_acl.h241
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_bank.c87
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_clock.c509
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_colexp.c547
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_cursor.c266
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_dpms.c251
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_driver.c3207
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_inline.h238
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_ramdac.c662
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/v4l/Imakefile41
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/v4l/README39
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/v4l/v4l.c633
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/v4l/videodev.h255
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/vga/Imakefile51
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/vga/generic.c1191
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/vga/vga.cpp66
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/2key.c52
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/BM-Lynx.shar2255
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/Imakefile139
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/XdmConf.svr4777
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/apNetBSD.shar473
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/apSolx86.shar1339
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/8514-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9480-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9EGC-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9GA9-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9GAN-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9LPW-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9NKV-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9NS3-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9SPW-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9TGU-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9WEP-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9WS-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9WSN-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/AGX-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/I128-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Load-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Ma32-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Ma64-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Ma8-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Mono-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/P9K-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/S3-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/S3V-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/SVGA-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/VG16-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/bin-excl9
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/bin-list15
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/dir1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/fsrv-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/host.def3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/lib-excl12
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/lib-list2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/lkit-excl4
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/lkit-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/man-excl3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/man-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/mod-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/nest-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/prog-excl5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/prog-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/prt-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/set-list5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/vfb-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin-excl13
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin1-excl14
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin1-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin2-excl13
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin2-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/dir1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/fsrv-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/lib-excl9
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/lib-list2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/man-excl3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/man-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/mod-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/nest-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/prog-excl5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/prog-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/prt-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/set-list5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/vfb-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/xdm-excl2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/xdm-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/xserv-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/Load-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/Ma64-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/Mono-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/P9K-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/S3-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/S3V-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/SVGA-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/TGA-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/bin-excl9
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/bin-list38
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/dir1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/fsrv-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/host.def3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/lib-excl12
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/lib-list2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/lkit-excl4
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/lkit-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/man-excl3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/man-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/mod-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/nest-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/prog-excl5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/prog-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/prt-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/set-list5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/vfb-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/bin-excl8
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/bin-list52
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/dir1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/fsrv-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/host.def3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/lib-excl12
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/lib-list2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/man-excl3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/man-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/mod-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/nest-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/prog-excl5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/prog-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/prt-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/sdk-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/set-list5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/vfb-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/xserv-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/68FB-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/bin-excl10
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/bin-list39
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/dir1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/fsrv-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/lib-excl12
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/lib-list2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/man-excl3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/man-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/nest-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/prog-excl4
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/prog-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/prt-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/vfb-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/8514-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/AGX-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/I128-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/Ma32-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/Ma64-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/Ma8-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/Mono-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/P9K-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/S3-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/S3V-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/SVGA-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/VG16-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/bin-excl8
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/bin-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/dir1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/fsrv-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/host.def11
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/lib-excl12
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/lib-list2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/lkit-excl4
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/lkit-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/man-excl3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/man-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/nest-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/prog-excl4
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/prog-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/prt-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/set-list5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/vfb-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/8514-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9480-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9EGC-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9GA9-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9GAN-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9LPW-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9NKV-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9NS3-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9SPW-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9TGU-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9WEP-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9WS-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9WSN-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/AGX-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/I128-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Load-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Ma32-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Ma64-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Ma8-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Mono-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/P9K-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/S3-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/S3V-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/SVGA-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/VG16-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/bin-excl9
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/bin-list15
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/dir1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/fsrv-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/host.def3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/lib-excl12
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/lib-list2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/lkit-excl4
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/lkit-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/man-excl3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/man-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/mod-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/nest-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/prog-excl5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/prog-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/prt-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/set-list5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/vfb-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/8514-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/AGX-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/I128-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/Ma32-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/Ma64-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/Ma8-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/Mono-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/P9K-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/S3-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/S3V-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/SVGA-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/VG16-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/bin-excl9
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/bin-list16
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/dir1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/fsrv-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/host.def16
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/lib-excl12
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/lib-list2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/lkit-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/man-excl3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/man-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/nest-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/prog-excl5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/prog-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/prt-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/set-list5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/vfb-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/Mono-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/Sun24-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/bin-excl8
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/bin-list16
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/dir1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/fsrv-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/host.def14
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/lib-excl12
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/lib-list2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/man-excl3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/man-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/nest-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/prog-excl5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/prog-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/prt-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/sun-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/8514-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/AGX-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/I128-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Load-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Ma32-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Ma64-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Ma8-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Mono-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/P9K-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/S3-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/S3V-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/SVGA-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/VG16-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/bin-excl9
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/bin-list28
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/dir1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/fsrv-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/host.def3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/lib-excl12
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/lib-list2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/man-excl3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/man-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/mod-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/nest-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/prog-excl5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/prog-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/prt-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/set-list5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/vfb-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/8514-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/AGX-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/I128-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Load-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Ma32-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Ma64-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Ma8-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Mono-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/P9K-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/S3-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/S3V-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/SVGA-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/VG16-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/bin-excl9
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/bin-list28
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/dir1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/fsrv-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/host.def3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/lib-excl12
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/lib-list2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/man-excl3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/man-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/mod-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/nest-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/prog-excl5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/prog-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/prt-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/set-list5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/vfb-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/8514-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/AGX-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/I128-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Load-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Ma32-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Ma64-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Ma8-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Mono-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/P9K-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/S3-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/S3V-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/SVGA-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/VG16-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/bin-excl9
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/bin-list28
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/dir1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/fsrv-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/host.def3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/lib-excl12
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/lib-list2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/man-excl3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/man-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/mod-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/nest-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/prog-excl5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/prog-list3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/prt-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/set-list5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/vfb-list1
-rwxr-xr-xxc/programs/Xserver/hw/xfree86/etc/bindist/build-bindist118
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/common/cfg-excl2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/common/cfg-list2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/common/dir1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/common/doc-excl3
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/common/doc-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/common/extras5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/common/f100-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/common/fcyr-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/common/fenc-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/common/flat2-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/common/fnon-list11
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/common/fnts-excl5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/common/fnts-list5
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/common/fscl-list2
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/common/html-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/common/jdoc-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/bindist/common/ps-list1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/dmmap.shar601
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/et4000clock.c134
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/install.sv3652
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/install.sv437
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/joycal.c88
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/kbd_mode.c97
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/kbd_mode.man36
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/ld-wrapper.c169
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/ldterm.sdevice1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/mmapSVR3.shar2479
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/pcitweak.c418
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/postinst.sh141
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/preinst.sh141
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/ptem.sdevice1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/ptm.sdevice1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/pts.node32
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/pts.sdevice1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/pty.cfg61
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/scanpci.c2004
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/sp.node1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/sp.sdevice1
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/sun.tcap32
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/sun.tinfo56
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/svr3_patch863
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/svr3_rem_pch122
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/svr4_patch749
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/svr4_rem_pch121
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/vesamodes109
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/vga.bdf5906
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/xcode.xfree86219
-rw-r--r--xc/programs/Xserver/hw/xfree86/etc/xmodmap.std211
-rw-r--r--xc/programs/Xserver/hw/xfree86/fbdevhw/Imakefile39
-rw-r--r--xc/programs/Xserver/hw/xfree86/fbdevhw/README16
-rw-r--r--xc/programs/Xserver/hw/xfree86/fbdevhw/fb.h254
-rw-r--r--xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.c730
-rw-r--r--xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.cpp21
-rw-r--r--xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.h40
-rw-r--r--xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhwstub.c154
-rw-r--r--xc/programs/Xserver/hw/xfree86/i2c/Imakefile28
-rw-r--r--xc/programs/Xserver/hw/xfree86/i2c/xf86i2c.c840
-rw-r--r--xc/programs/Xserver/hw/xfree86/i2c/xf86i2c.h87
-rw-r--r--xc/programs/Xserver/hw/xfree86/i2c/xf86i2cmodule.c34
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/Imakefile59
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/acecad/Imakefile26
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/acecad/xf86AceCad.c1037
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/confdrv.sh45
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/dynapro/Imakefile26
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/dynapro/xf86Dyna.c619
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/dynapro/xf86Dyna.h91
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/elo2300/Imakefile26
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/elo2300/elo.c907
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/elo2300/elo.h147
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/elographics/Imakefile26
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/elographics/xf86Elo.c1613
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/joystick/Imakefile34
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/joystick/xf86Jstk.c793
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/magellan/Imakefile26
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/magellan/magellan.c543
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/magellan/magellan.h109
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/microtouch/Imakefile26
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/microtouch/microtouch.c984
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/microtouch/microtouch.h146
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/mouse/Imakefile29
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/mouse/mouse.c1714
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/mouse/mouse.h53
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/mouse/pnp.c476
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/mutouch/Imakefile26
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/mutouch/xf86MuTouch.c1626
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/sample/Imakefile26
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/sample/sample.c525
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/sample/sample.h96
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/spaceorb/Imakefile26
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/spaceorb/spaceorb.c507
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/spaceorb/spaceorb.h86
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/summa/Imakefile26
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/summa/xf86Summa.c1133
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/wacom/Imakefile26
-rw-r--r--xc/programs/Xserver/hw/xfree86/input/wacom/xf86Wacom.c3116
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/Imakefile54
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/README107
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/aout.h232
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/aoutloader.c857
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/aoutloader.h31
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/ar.h77
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/coff.h244
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/coffloader.c1361
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/coffloader.h34
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/dixsym.c304
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/dlloader.c190
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/dlloader.h32
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/elf.h570
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/elfloader.c2320
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/elfloader.h34
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/fontsym.c46
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/hash.c350
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/hash.h36
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/loader.c1212
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/loader.h262
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/loaderProcs.h83
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/loadfont.c53
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/loadmod.c1266
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/misym.c157
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/os.c49
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/os2funcs.c148
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/sym.h44
-rw-r--r--xc/programs/Xserver/hw/xfree86/loader/xf86sym.c878
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/Imakefile121
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/README.OS-lib511
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/amoeba/Imakefile35
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/amoeba/am_init.c105
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/amoeba/am_io.c192
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/amoeba/am_video.c102
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/assyntax.h725
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/Imakefile104
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_VTsw.c92
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_init.c642
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_io.c214
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_jstk.c186
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_mouse.c341
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_video.c1203
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsdi/Imakefile49
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_init.c152
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_io.c128
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_mouse.c30
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_video.c175
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bus/Imakefile61
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c1081
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.h221
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bus/axpPci.c134
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bus/ix86Pci.c617
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bus/linuxPci.c180
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bus/ppcPci.c195
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bus/sparcPci.c179
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h622
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/dgux/Imakefile30
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/dgux/bios_DGmmap.c65
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_init.c180
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_io.c84
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_kbd.c121
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_kbdEv.c43
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_tty.c171
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_video.c544
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/hurd/Imakefile46
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/hurd/bios_mmap.c91
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_init.c86
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_io.c254
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_mouse.c295
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_video.c171
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/Imakefile95
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile43
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/drmmodule.c56
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/Imakefile28
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/Makefile.kernel20
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/Makefile.linux163
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/README.drm39
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm.h361
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drmP.h731
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_ioctl.c261
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_mem.c271
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_proc.c727
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_setup.c1296
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_version.h4
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drmstat.c462
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_bufs.c311
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_dma.c1313
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_ioctl.c1374
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/gmx/gmx.h74
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/gmx/gmx_setup.c255
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/gmx/gmx_version.h4
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c1114
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c435
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRandom.c219
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmSL.c490
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_init.c264
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_io.c139
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_jstk.c184
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_mouse.c29
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c626
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/lynxos/Imakefile57
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_init.c189
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_io.c184
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_mmap.c69
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_mouse.c30
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_noinline.c255
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_ppc.S70
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_video.c263
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/mach/Imakefile35
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/mach/bios_mmap.c76
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/mach/mach_init.c70
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/mach/mach_io.c289
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/mach/mach_video.c195
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/minix/Imakefile29
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/minix/bios_devmem.c78
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/minix/local.h13
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/minix/mnx_init.c110
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/minix/mnx_io.c277
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/minix/mnx_video.c98
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/misc/BUSmemcpy.S156
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/misc/BUSmemcpy.c410
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/misc/IODelay.S53
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/misc/IODelay.c23
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/misc/Imakefile42
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/misc/SlowBcopy.S108
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/misc/SlowBcopy.c96
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/misc/SparcMulDiv.S87
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/misc/xf86_IlHack.c15
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/misc/xf86_Util.c92
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/os2/Imakefile37
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/os2/README78
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/os2/os2_VTsw.c262
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/os2/os2_bios.c119
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/os2/os2_diag.c254
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/os2/os2_init.c227
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/os2/os2_io.c216
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/os2/os2_ioperm.c136
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/os2/os2_kbdEv.c506
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/os2/os2_mouse.c300
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/os2/os2_select.c503
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/os2/os2_select.h60
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/os2/os2_serial.c339
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/os2/os2_stubs.c447
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/os2/os2_video.c226
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/pmax/Imakefile49
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_devs.c144
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_init.c469
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_map.c251
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_mouse.c58
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_pci.c1071
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_ppc.c247
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sco/Imakefile38
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sco/VTsw_sco.c95
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sco/sco_init.c249
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sco/sco_io.c110
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sco/sco_mouse.c193
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sco/sco_video.c278
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/VTsw_noop.c52
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/VTsw_usl.c81
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/bios_devmem.c69
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/bios_mmap.c143
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/inout.S111
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/ioperm_noop.c47
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/libc_wrapper.c1746
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/mapVT_noop.c43
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/posix_tty.c792
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/sigio.c82
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/stdResource.c188
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/std_kbdEv.c46
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/std_mouse.c55
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/std_mseEv.c44
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/sysv_kbd.c102
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/sysv_tty.c162
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/shared/vidmem.c233
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/solx86/Imakefile55
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_bios.c94
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_init.c387
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_iout.s104
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_misc.c99
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_mouse.c30
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_vid.c227
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sysv/Imakefile60
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_init.c250
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_io.c95
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_mouse.c62
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_video.c361
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sysv/xqueue.c799
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/sysv/xqueue.h8
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h143
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86OSpriv.h29
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86_OSlib.h744
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86_OSproc.h237
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86_ansic.h291
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86_libc.h415
-rw-r--r--xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h503
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/Configint.h188
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/DRI.c161
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/Device.c375
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/Files.c213
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/Flags.c430
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/Imakefile54
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/Input.c199
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/Keyboard.c492
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/Layout.c388
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/Module.c227
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/Monitor.c859
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/Pointer.c364
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/Screen.c573
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/Vendor.c149
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/Video.c293
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/configProcs.h103
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/cpconfig.c118
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/read.c235
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/scan.c930
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/write.c86
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/xf86Optrec.h78
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/xf86Parser.h448
-rw-r--r--xc/programs/Xserver/hw/xfree86/parser/xf86tokens.h236
-rw-r--r--xc/programs/Xserver/hw/xfree86/rac/Imakefile28
-rw-r--r--xc/programs/Xserver/hw/xfree86/rac/xf86RAC.c1164
-rw-r--r--xc/programs/Xserver/hw/xfree86/rac/xf86RAC.h18
-rw-r--r--xc/programs/Xserver/hw/xfree86/rac/xf86RACmodule.c21
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/BT.c159
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/BT.h33
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/BTPriv.h17
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/CURSOR.NOTES172
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/IBM.c624
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/IBM.h383
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/IBMPriv.h24
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/Imakefile45
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/TI.c568
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/TI.h83
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/TIPriv.h25
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/xf86Cursor.c389
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/xf86Cursor.h74
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/xf86CursorPriv.h8
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/xf86HWCurs.c468
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDac.c194
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDac.h115
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacCmap.c65
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacMod.c45
-rw-r--r--xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacPriv.h10
-rw-r--r--xc/programs/Xserver/hw/xfree86/reconfig/Imakefile22
-rw-r--r--xc/programs/Xserver/hw/xfree86/reconfig/README5
-rw-r--r--xc/programs/Xserver/hw/xfree86/reconfig/copyright.c76
-rw-r--r--xc/programs/Xserver/hw/xfree86/reconfig/keyword.i87
-rw-r--r--xc/programs/Xserver/hw/xfree86/reconfig/lex.l88
-rw-r--r--xc/programs/Xserver/hw/xfree86/reconfig/os.h37
-rw-r--r--xc/programs/Xserver/hw/xfree86/reconfig/reconfig.man22
-rw-r--r--xc/programs/Xserver/hw/xfree86/reconfig/reconfig.y730
-rw-r--r--xc/programs/Xserver/hw/xfree86/reconfig/strlist.h18
-rw-r--r--xc/programs/Xserver/hw/xfree86/scanpci/Imakefile30
-rw-r--r--xc/programs/Xserver/hw/xfree86/scanpci/xf86PciData.c46
-rw-r--r--xc/programs/Xserver/hw/xfree86/scanpci/xf86ScanPci.c223
-rw-r--r--xc/programs/Xserver/hw/xfree86/sdk/Imakefile10
-rw-r--r--xc/programs/Xserver/hw/xfree86/sdk/Imakefile.SDK35
-rw-r--r--xc/programs/Xserver/hw/xfree86/sdk/README37
-rw-r--r--xc/programs/Xserver/hw/xfree86/sdk/mkmf.cpp38
-rw-r--r--xc/programs/Xserver/hw/xfree86/sdk/site.def.SDK17
-rw-r--r--xc/programs/Xserver/hw/xfree86/shadowfb/Imakefile32
-rw-r--r--xc/programs/Xserver/hw/xfree86/shadowfb/sfbmodule.c24
-rw-r--r--xc/programs/Xserver/hw/xfree86/shadowfb/shadow.c1385
-rw-r--r--xc/programs/Xserver/hw/xfree86/shadowfb/shadowfb.h18
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/Imakefile184
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/README2
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/enhanced/SpeedUpBlt.c92
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fBitBlt.s694
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fFill.s234
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fFillSet.s261
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fLineBres.s206
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fLineH.s471
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fLineV.s237
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/enhanced/gBanks.c55
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suBBlt2.s860
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suBitBlt.s1572
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suBox.s702
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suLine.s762
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suVHLine.s413
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaBitBlt.c541
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaBltFillc.c835
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaFasm.h318
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaLinec.c71
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vga8cppl.c232
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgaAsm.h16
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgaBank.h250
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgaBank.s650
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgaBankc.c358
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgabitblt.c792
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgablt.c516
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgabltC.c245
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgabresd.c178
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgabstore.c137
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgafb.h1314
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgafillarc.c284
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgafillrct.c287
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgafillsp.c796
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgagc.c657
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgagetsp.c169
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgaglblt8.c422
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgaimage.c115
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgaline.c492
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgalined.c360
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgaply1rct.c324
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgapntwin.c405
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgapolypnt.c128
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgapush8.c182
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgapwinS.c82
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgarctstp8.c626
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgascrinit.c153
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgasetsp.c284
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgasolid.c189
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgateblt8.c721
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgategblt.c198
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgatile32.c358
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgatileodd.c1070
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgawindow.c100
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgafb/vgazerarc.c201
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgahw/Imakefile50
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgahw/vgaCmap.c306
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgahw/vgaHW.c1868
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgahw/vgaHW.h221
-rw-r--r--xc/programs/Xserver/hw/xfree86/vgahw/vgaHWmodule.c27
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/Imakefile64
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/Imakefile.EXP40
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/NOTES1904
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/XAA.HOWTO1438
-rwxr-xr-xxc/programs/Xserver/hw/xfree86/xaa/lsb_first/Imakefile15
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/lsb_fixed/Imakefile7
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/msb_first/Imakefile15
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/msb_fixed/Imakefile7
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaa.h1248
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaBitBlt.c219
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaBitOrder.c65
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaBitmap.c408
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaCpyArea.c354
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaCpyPlane.c205
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaCpyWin.c82
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaDashLine.c275
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaFallback.c352
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaFillArc.c213
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaFillPoly.c954
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaFillRect.c1076
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaGC.c630
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaGCmisc.c420
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaImage.c601
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaInit.c687
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaInitAccel.c1356
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaLine.c336
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaLineMisc.c148
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaNonTEGlyph.c198
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaNonTEText.c585
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaOffscreen.c158
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaOverlay.c324
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaOverlayDF.c1154
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaPCache.c2352
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaPaintWin.c199
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaROP.c164
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaRect.c134
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaSpans.c866
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaStipple.c642
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaTEGlyph.c1076
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaTEGlyphBlt.S960
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaTEText.c293
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaTables.c88
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaaWideLine.c948
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaacexp.h117
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaalocal.h1524
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaarop.h307
-rw-r--r--xc/programs/Xserver/hw/xfree86/xaa/xaawrap.h71
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf1bpp/Imakefile120
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf1bpp/mfbmap.h109
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf1bpp/mfbmap.sh25
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf1bpp/mfbmodule.c48
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf1bpp/mfbunmap.h109
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf1bpp/mfbunmap.sh23
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf1bpp/xf1bpp.h37
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf24_32bpp/Imakefile41
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfb24_32.h163
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfb24_32module.c37
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbbstore.c89
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbcpyarea.c714
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbgc.c667
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbgcmisc.c170
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbimage.c95
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbpixmap.c145
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbscrinit.c192
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbwindow.c124
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/Imakefile61
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/NOTES194
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/OScompiler.h59
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/emulOpStip.c100
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/emulRepAre.c67
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/emulTile.c352
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ibmTrace.h10
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/mfbbres.c162
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/mfbbresd.c199
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/mfbfillarc.c299
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/mfbhrzvert.c133
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/mfbimggblt.c515
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/mfbline.c982
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/mfbzerarc.c266
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/offscreen.c359
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcArea.c96
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcBStore.c153
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcCReduce.c236
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcClip.c154
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcCpArea.c490
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcDepth.c52
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcFillRct.c220
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcGC.c459
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcGCstr.h94
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcGetSp.c139
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcIO.c253
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcImg.c140
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPixFS.c502
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPixmap.c138
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPntWin.c218
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPolyPnt.c142
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPolyRec.c127
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcQuery.c44
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcRslvC.c176
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcSetSp.c315
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcSpMcro.h45
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcWinFS.c278
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/ppcWindow.c224
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/vgaBitBlt.c757
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/vgaGC.c218
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/vgaImages.c448
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/vgaReg.h134
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/vgaSolid.c565
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/vgaStipple.c708
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/vgaVideo.h92
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/vgamodule.c57
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/wm3.c205
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/wm3.h77
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf4bpp/xf4bpp.h803
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf86config/Cards3059
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf86config/Cards98647
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf86config/Imakefile23
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf86config/cards.c292
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf86config/cards.h38
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf86config/xf86conf.man16
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf86config/xf86config.c2628
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_16bpp/Imakefile33
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfb8_16.h69
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfb8_16module.c37
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfbscrinit.c511
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfbwindow.c173
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_32bpp/Imakefile42
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfb8_32.h233
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfb8_32module.c38
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbbstore.c102
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbcpyarea.c540
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbcpyplane.c39
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbgc.c666
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbgcmisc.c120
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbimage.c162
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbpntwin.c196
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbscrinit.c214
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbwindow.c146
-rw-r--r--xc/programs/Xserver/hw/xfree86/xf8_32bpp/xf86overlay.c1251
-rw-r--r--xc/programs/Xserver/hw/xnest/Args.c188
-rw-r--r--xc/programs/Xserver/hw/xnest/Args.h38
-rw-r--r--xc/programs/Xserver/hw/xnest/Color.c499
-rw-r--r--xc/programs/Xserver/hw/xnest/Color.h56
-rw-r--r--xc/programs/Xserver/hw/xnest/Cursor.c214
-rw-r--r--xc/programs/Xserver/hw/xnest/Cursor.h37
-rw-r--r--xc/programs/Xserver/hw/xnest/Display.c202
-rw-r--r--xc/programs/Xserver/hw/xnest/Display.h47
-rw-r--r--xc/programs/Xserver/hw/xnest/Drawable.h27
-rw-r--r--xc/programs/Xserver/hw/xnest/Events.c189
-rw-r--r--xc/programs/Xserver/hw/xnest/Events.h28
-rw-r--r--xc/programs/Xserver/hw/xnest/Font.c88
-rw-r--r--xc/programs/Xserver/hw/xnest/GC.c346
-rw-r--r--xc/programs/Xserver/hw/xnest/GCOps.c388
-rw-r--r--xc/programs/Xserver/hw/xnest/GCOps.h43
-rw-r--r--xc/programs/Xserver/hw/xnest/GetTime.c43
-rw-r--r--xc/programs/Xserver/hw/xnest/Handlers.c43
-rw-r--r--xc/programs/Xserver/hw/xnest/Handlers.h22
-rw-r--r--xc/programs/Xserver/hw/xnest/Imakefile75
-rw-r--r--xc/programs/Xserver/hw/xnest/Init.c164
-rw-r--r--xc/programs/Xserver/hw/xnest/Init.h21
-rw-r--r--xc/programs/Xserver/hw/xnest/Keyboard.c165
-rw-r--r--xc/programs/Xserver/hw/xnest/Keyboard.h26
-rw-r--r--xc/programs/Xserver/hw/xnest/Pixmap.c130
-rw-r--r--xc/programs/Xserver/hw/xnest/Pixmap.h34
-rw-r--r--xc/programs/Xserver/hw/xnest/Pointer.c73
-rw-r--r--xc/programs/Xserver/hw/xnest/Pointer.h28
-rw-r--r--xc/programs/Xserver/hw/xnest/Screen.c378
-rw-r--r--xc/programs/Xserver/hw/xnest/Screen.h26
-rw-r--r--xc/programs/Xserver/hw/xnest/TestExt.c68
-rw-r--r--xc/programs/Xserver/hw/xnest/Visual.c67
-rw-r--r--xc/programs/Xserver/hw/xnest/Visual.h26
-rw-r--r--xc/programs/Xserver/hw/xnest/Window.c556
-rw-r--r--xc/programs/Xserver/hw/xnest/XNFont.h36
-rw-r--r--xc/programs/Xserver/hw/xnest/XNGC.h43
-rw-r--r--xc/programs/Xserver/hw/xnest/XNWindow.h79
-rw-r--r--xc/programs/Xserver/hw/xnest/Xnest.h95
-rw-r--r--xc/programs/Xserver/hw/xnest/Xnest.man261
-rw-r--r--xc/programs/Xserver/hw/xnest/icon14
-rw-r--r--xc/programs/Xserver/hw/xnest/os2Stub.c386
-rw-r--r--xc/programs/Xserver/hw/xnest/screensaver686
-rw-r--r--xc/programs/Xserver/ilbm/Imakefile63
-rw-r--r--xc/programs/Xserver/ilbm/README17
-rw-r--r--xc/programs/Xserver/ilbm/ilbm.h1217
-rw-r--r--xc/programs/Xserver/ilbm/ilbmbitblt.c479
-rw-r--r--xc/programs/Xserver/ilbm/ilbmblt.c569
-rw-r--r--xc/programs/Xserver/ilbm/ilbmbres.c324
-rw-r--r--xc/programs/Xserver/ilbm/ilbmbresd.c215
-rw-r--r--xc/programs/Xserver/ilbm/ilbmbstore.c155
-rw-r--r--xc/programs/Xserver/ilbm/ilbmclip.c242
-rw-r--r--xc/programs/Xserver/ilbm/ilbmcmap.c124
-rw-r--r--xc/programs/Xserver/ilbm/ilbmfillarc.c373
-rw-r--r--xc/programs/Xserver/ilbm/ilbmfillrct.c295
-rw-r--r--xc/programs/Xserver/ilbm/ilbmfillsp.c1145
-rw-r--r--xc/programs/Xserver/ilbm/ilbmfont.c78
-rw-r--r--xc/programs/Xserver/ilbm/ilbmgc.c711
-rw-r--r--xc/programs/Xserver/ilbm/ilbmgetsp.c166
-rw-r--r--xc/programs/Xserver/ilbm/ilbmhrzvert.c209
-rw-r--r--xc/programs/Xserver/ilbm/ilbmimage.c437
-rw-r--r--xc/programs/Xserver/ilbm/ilbmimggblt.c470
-rw-r--r--xc/programs/Xserver/ilbm/ilbmline.c701
-rw-r--r--xc/programs/Xserver/ilbm/ilbmmisc.c95
-rw-r--r--xc/programs/Xserver/ilbm/ilbmpixmap.c289
-rw-r--r--xc/programs/Xserver/ilbm/ilbmply1rct.c299
-rw-r--r--xc/programs/Xserver/ilbm/ilbmplygblt.c465
-rw-r--r--xc/programs/Xserver/ilbm/ilbmpntarea.c652
-rw-r--r--xc/programs/Xserver/ilbm/ilbmpntwin.c127
-rw-r--r--xc/programs/Xserver/ilbm/ilbmpolypnt.c148
-rw-r--r--xc/programs/Xserver/ilbm/ilbmpushpxl.c259
-rw-r--r--xc/programs/Xserver/ilbm/ilbmscrinit.c247
-rw-r--r--xc/programs/Xserver/ilbm/ilbmsetsp.c265
-rw-r--r--xc/programs/Xserver/ilbm/ilbmtegblt.c595
-rw-r--r--xc/programs/Xserver/ilbm/ilbmtile.c853
-rw-r--r--xc/programs/Xserver/ilbm/ilbmwindow.c319
-rw-r--r--xc/programs/Xserver/ilbm/ilbmzerarc.c210
-rw-r--r--xc/programs/Xserver/include/Imakefile51
-rw-r--r--xc/programs/Xserver/include/XIstubs.h101
-rw-r--r--xc/programs/Xserver/include/bstore.h23
-rw-r--r--xc/programs/Xserver/include/bstorestr.h75
-rw-r--r--xc/programs/Xserver/include/closestr.h159
-rw-r--r--xc/programs/Xserver/include/closure.h53
-rw-r--r--xc/programs/Xserver/include/colormap.h230
-rw-r--r--xc/programs/Xserver/include/colormapst.h116
-rw-r--r--xc/programs/Xserver/include/cursor.h147
-rw-r--r--xc/programs/Xserver/include/cursorstr.h79
-rw-r--r--xc/programs/Xserver/include/dix.h1094
-rw-r--r--xc/programs/Xserver/include/dixevents.h256
-rw-r--r--xc/programs/Xserver/include/dixfont.h163
-rw-r--r--xc/programs/Xserver/include/dixfontstr.h95
-rw-r--r--xc/programs/Xserver/include/dixgrabs.h79
-rw-r--r--xc/programs/Xserver/include/dixstruct.h237
-rw-r--r--xc/programs/Xserver/include/exevents.h275
-rw-r--r--xc/programs/Xserver/include/extension.h80
-rw-r--r--xc/programs/Xserver/include/extinit.h210
-rw-r--r--xc/programs/Xserver/include/extnsionst.h190
-rw-r--r--xc/programs/Xserver/include/gc.h228
-rw-r--r--xc/programs/Xserver/include/gcstruct.h405
-rw-r--r--xc/programs/Xserver/include/globals.h50
-rw-r--r--xc/programs/Xserver/include/input.h531
-rw-r--r--xc/programs/Xserver/include/inputstr.h313
-rw-r--r--xc/programs/Xserver/include/misc.h284
-rw-r--r--xc/programs/Xserver/include/miscstruct.h69
-rw-r--r--xc/programs/Xserver/include/opaque.h80
-rw-r--r--xc/programs/Xserver/include/os.h805
-rw-r--r--xc/programs/Xserver/include/pixmap.h119
-rw-r--r--xc/programs/Xserver/include/pixmapstr.h79
-rw-r--r--xc/programs/Xserver/include/property.h74
-rw-r--r--xc/programs/Xserver/include/propertyst.h72
-rw-r--r--xc/programs/Xserver/include/region.h49
-rw-r--r--xc/programs/Xserver/include/regionstr.h404
-rw-r--r--xc/programs/Xserver/include/resource.h277
-rw-r--r--xc/programs/Xserver/include/rgb.h50
-rw-r--r--xc/programs/Xserver/include/screenint.h166
-rw-r--r--xc/programs/Xserver/include/scrnintstr.h958
-rw-r--r--xc/programs/Xserver/include/selection.h64
-rw-r--r--xc/programs/Xserver/include/servermd.h559
-rw-r--r--xc/programs/Xserver/include/site.h133
-rw-r--r--xc/programs/Xserver/include/swaprep.h542
-rw-r--r--xc/programs/Xserver/include/swapreq.h137
-rw-r--r--xc/programs/Xserver/include/validate.h37
-rw-r--r--xc/programs/Xserver/include/window.h346
-rw-r--r--xc/programs/Xserver/include/windowstr.h223
-rw-r--r--xc/programs/Xserver/iplan2p2/Imakefile6
-rw-r--r--xc/programs/Xserver/iplan2p4/Imakefile121
-rw-r--r--xc/programs/Xserver/iplan2p4/ipl.h1493
-rw-r--r--xc/programs/Xserver/iplan2p4/iplallpriv.c89
-rw-r--r--xc/programs/Xserver/iplan2p4/iplbitblt.c384
-rw-r--r--xc/programs/Xserver/iplan2p4/iplblt.c427
-rw-r--r--xc/programs/Xserver/iplan2p4/iplbres.c182
-rw-r--r--xc/programs/Xserver/iplan2p4/iplbresd.c208
-rw-r--r--xc/programs/Xserver/iplan2p4/iplbstore.c155
-rw-r--r--xc/programs/Xserver/iplan2p4/iplcmap.c122
-rw-r--r--xc/programs/Xserver/iplan2p4/iplfillarc.c267
-rw-r--r--xc/programs/Xserver/iplan2p4/iplfillrct.c277
-rw-r--r--xc/programs/Xserver/iplan2p4/iplfillsp.c380
-rw-r--r--xc/programs/Xserver/iplan2p4/iplgc.c782
-rw-r--r--xc/programs/Xserver/iplan2p4/iplgetsp.c162
-rw-r--r--xc/programs/Xserver/iplan2p4/iplhrzvert.c124
-rw-r--r--xc/programs/Xserver/iplan2p4/iplimage.c83
-rw-r--r--xc/programs/Xserver/iplan2p4/iplline.c754
-rw-r--r--xc/programs/Xserver/iplan2p4/iplmap.h172
-rw-r--r--xc/programs/Xserver/iplan2p4/iplmergerop.h142
-rw-r--r--xc/programs/Xserver/iplan2p4/iplmskbits.c104
-rw-r--r--xc/programs/Xserver/iplan2p4/iplmskbits.h496
-rw-r--r--xc/programs/Xserver/iplan2p4/iplpack.c316
-rw-r--r--xc/programs/Xserver/iplan2p4/iplpack.h10
-rw-r--r--xc/programs/Xserver/iplan2p4/iplpixmap.c380
-rw-r--r--xc/programs/Xserver/iplan2p4/iplply1rct.c306
-rw-r--r--xc/programs/Xserver/iplan2p4/iplpntwin.c337
-rw-r--r--xc/programs/Xserver/iplan2p4/iplpolypnt.c119
-rw-r--r--xc/programs/Xserver/iplan2p4/iplrrop.c215
-rw-r--r--xc/programs/Xserver/iplan2p4/iplrrop.h76
-rw-r--r--xc/programs/Xserver/iplan2p4/iplscrinit.c229
-rw-r--r--xc/programs/Xserver/iplan2p4/iplsetsp.c300
-rw-r--r--xc/programs/Xserver/iplan2p4/iplsolid.c217
-rw-r--r--xc/programs/Xserver/iplan2p4/ipltegblt.c217
-rw-r--r--xc/programs/Xserver/iplan2p4/ipltile32.c268
-rw-r--r--xc/programs/Xserver/iplan2p4/ipltileodd.c865
-rw-r--r--xc/programs/Xserver/iplan2p4/iplwindow.c339
-rw-r--r--xc/programs/Xserver/iplan2p8/Imakefile6
-rw-r--r--xc/programs/Xserver/lbx/Imakefile56
-rw-r--r--xc/programs/Xserver/lbx/lbxcmap.c1156
-rw-r--r--xc/programs/Xserver/lbx/lbxdata.h44
-rw-r--r--xc/programs/Xserver/lbx/lbxdix.c884
-rw-r--r--xc/programs/Xserver/lbx/lbxexts.c270
-rw-r--r--xc/programs/Xserver/lbx/lbxgfx.c867
-rw-r--r--xc/programs/Xserver/lbx/lbxmain.c1820
-rw-r--r--xc/programs/Xserver/lbx/lbxopts.c818
-rw-r--r--xc/programs/Xserver/lbx/lbxprop.c548
-rw-r--r--xc/programs/Xserver/lbx/lbxserve.h169
-rw-r--r--xc/programs/Xserver/lbx/lbxsquish.c148
-rw-r--r--xc/programs/Xserver/lbx/lbxsrvopts.h78
-rw-r--r--xc/programs/Xserver/lbx/lbxswap.c854
-rw-r--r--xc/programs/Xserver/lbx/lbxtables.c33
-rw-r--r--xc/programs/Xserver/lbx/lbxtags.c234
-rw-r--r--xc/programs/Xserver/lbx/lbxtags.h115
-rw-r--r--xc/programs/Xserver/lbx/lbxzerorep.c412
-rw-r--r--xc/programs/Xserver/mfb/Imakefile111
-rw-r--r--xc/programs/Xserver/mfb/fastblt.h114
-rw-r--r--xc/programs/Xserver/mfb/maskbits.c9868
-rw-r--r--xc/programs/Xserver/mfb/maskbits.h745
-rw-r--r--xc/programs/Xserver/mfb/mergerop.h411
-rw-r--r--xc/programs/Xserver/mfb/mfb.h1297
-rw-r--r--xc/programs/Xserver/mfb/mfbbitblt.c481
-rw-r--r--xc/programs/Xserver/mfb/mfbblt.c588
-rw-r--r--xc/programs/Xserver/mfb/mfbbres.c361
-rw-r--r--xc/programs/Xserver/mfb/mfbbresd.c200
-rw-r--r--xc/programs/Xserver/mfb/mfbbstore.c147
-rw-r--r--xc/programs/Xserver/mfb/mfbclip.c266
-rw-r--r--xc/programs/Xserver/mfb/mfbcmap.c155
-rw-r--r--xc/programs/Xserver/mfb/mfbfillarc.c325
-rw-r--r--xc/programs/Xserver/mfb/mfbfillrct.c221
-rw-r--r--xc/programs/Xserver/mfb/mfbfillsp.c1020
-rw-r--r--xc/programs/Xserver/mfb/mfbfont.c68
-rw-r--r--xc/programs/Xserver/mfb/mfbgc.c1524
-rw-r--r--xc/programs/Xserver/mfb/mfbgetsp.c150
-rw-r--r--xc/programs/Xserver/mfb/mfbhrzvert.c171
-rw-r--r--xc/programs/Xserver/mfb/mfbimage.c169
-rw-r--r--xc/programs/Xserver/mfb/mfbimggblt.c439
-rw-r--r--xc/programs/Xserver/mfb/mfbline.c749
-rw-r--r--xc/programs/Xserver/mfb/mfbmisc.c87
-rw-r--r--xc/programs/Xserver/mfb/mfbmodule.c48
-rw-r--r--xc/programs/Xserver/mfb/mfbpixmap.c290
-rw-r--r--xc/programs/Xserver/mfb/mfbply1rct.c251
-rw-r--r--xc/programs/Xserver/mfb/mfbplygblt.c387
-rw-r--r--xc/programs/Xserver/mfb/mfbpntarea.c292
-rw-r--r--xc/programs/Xserver/mfb/mfbpntwin.c119
-rw-r--r--xc/programs/Xserver/mfb/mfbpolypnt.c137
-rw-r--r--xc/programs/Xserver/mfb/mfbpushpxl.c274
-rw-r--r--xc/programs/Xserver/mfb/mfbscrclse.c55
-rw-r--r--xc/programs/Xserver/mfb/mfbscrinit.c193
-rw-r--r--xc/programs/Xserver/mfb/mfbsetsp.c275
-rw-r--r--xc/programs/Xserver/mfb/mfbtegblt.c423
-rw-r--r--xc/programs/Xserver/mfb/mfbtile.c226
-rw-r--r--xc/programs/Xserver/mfb/mfbwindow.c334
-rw-r--r--xc/programs/Xserver/mfb/mfbzerarc.c250
-rw-r--r--xc/programs/Xserver/mi/Imakefile77
-rw-r--r--xc/programs/Xserver/mi/cbrt.c39
-rw-r--r--xc/programs/Xserver/mi/mi.h768
-rw-r--r--xc/programs/Xserver/mi/miarc.c3671
-rw-r--r--xc/programs/Xserver/mi/mibank.c3173
-rw-r--r--xc/programs/Xserver/mi/mibank.h119
-rw-r--r--xc/programs/Xserver/mi/mibitblt.c829
-rw-r--r--xc/programs/Xserver/mi/mibstore.c3810
-rw-r--r--xc/programs/Xserver/mi/mibstore.h32
-rw-r--r--xc/programs/Xserver/mi/mibstorest.h85
-rw-r--r--xc/programs/Xserver/mi/miclipn.c69
-rw-r--r--xc/programs/Xserver/mi/micmap.c628
-rw-r--r--xc/programs/Xserver/mi/micmap.h61
-rw-r--r--xc/programs/Xserver/mi/micursor.c67
-rw-r--r--xc/programs/Xserver/mi/midash.c306
-rw-r--r--xc/programs/Xserver/mi/midispcur.c610
-rw-r--r--xc/programs/Xserver/mi/mieq.c187
-rw-r--r--xc/programs/Xserver/mi/miexpose.c899
-rw-r--r--xc/programs/Xserver/mi/mifillarc.c807
-rw-r--r--xc/programs/Xserver/mi/mifillarc.h220
-rw-r--r--xc/programs/Xserver/mi/mifillrct.c135
-rw-r--r--xc/programs/Xserver/mi/mifpoly.h104
-rw-r--r--xc/programs/Xserver/mi/mifpolycon.c273
-rw-r--r--xc/programs/Xserver/mi/migc.c291
-rw-r--r--xc/programs/Xserver/mi/migc.h88
-rw-r--r--xc/programs/Xserver/mi/miglblt.c246
-rw-r--r--xc/programs/Xserver/mi/miinitext.c457
-rw-r--r--xc/programs/Xserver/mi/miline.h166
-rw-r--r--xc/programs/Xserver/mi/mipointer.c532
-rw-r--r--xc/programs/Xserver/mi/mipointer.h199
-rw-r--r--xc/programs/Xserver/mi/mipointrst.h58
-rw-r--r--xc/programs/Xserver/mi/mipoly.c120
-rw-r--r--xc/programs/Xserver/mi/mipoly.h224
-rw-r--r--xc/programs/Xserver/mi/mipolycon.c241
-rw-r--r--xc/programs/Xserver/mi/mipolygen.c222
-rw-r--r--xc/programs/Xserver/mi/mipolypnt.c115
-rw-r--r--xc/programs/Xserver/mi/mipolyrect.c183
-rw-r--r--xc/programs/Xserver/mi/mipolyseg.c75
-rw-r--r--xc/programs/Xserver/mi/mipolytext.c192
-rw-r--r--xc/programs/Xserver/mi/mipolyutil.c393
-rw-r--r--xc/programs/Xserver/mi/mipushpxl.c252
-rw-r--r--xc/programs/Xserver/mi/miregion.c2468
-rw-r--r--xc/programs/Xserver/mi/miscanfill.h140
-rw-r--r--xc/programs/Xserver/mi/miscrinit.c306
-rw-r--r--xc/programs/Xserver/mi/mispans.c555
-rw-r--r--xc/programs/Xserver/mi/mispans.h128
-rw-r--r--xc/programs/Xserver/mi/misprite.c2064
-rw-r--r--xc/programs/Xserver/mi/misprite.h107
-rw-r--r--xc/programs/Xserver/mi/mispritest.h106
-rw-r--r--xc/programs/Xserver/mi/mistruct.h59
-rw-r--r--xc/programs/Xserver/mi/mivalidate.h47
-rw-r--r--xc/programs/Xserver/mi/mivaltree.c1286
-rw-r--r--xc/programs/Xserver/mi/miwideline.c2201
-rw-r--r--xc/programs/Xserver/mi/miwideline.h249
-rw-r--r--xc/programs/Xserver/mi/miwindow.c1157
-rw-r--r--xc/programs/Xserver/mi/mizerarc.c844
-rw-r--r--xc/programs/Xserver/mi/mizerarc.h133
-rw-r--r--xc/programs/Xserver/mi/mizerline.c956
-rw-r--r--xc/programs/Xserver/os/Imakefile157
-rw-r--r--xc/programs/Xserver/os/WaitFor.c773
-rw-r--r--xc/programs/Xserver/os/access.c1405
-rw-r--r--xc/programs/Xserver/os/auth.c381
-rw-r--r--xc/programs/Xserver/os/connection.c1398
-rw-r--r--xc/programs/Xserver/os/decompress.c383
-rw-r--r--xc/programs/Xserver/os/genalloca.c189
-rw-r--r--xc/programs/Xserver/os/hpsocket.c62
-rw-r--r--xc/programs/Xserver/os/io.c1274
-rw-r--r--xc/programs/Xserver/os/iopreader.c179
-rw-r--r--xc/programs/Xserver/os/k5auth.c793
-rw-r--r--xc/programs/Xserver/os/lbxio.c575
-rw-r--r--xc/programs/Xserver/os/mitauth.c191
-rw-r--r--xc/programs/Xserver/os/oscolor.c300
-rw-r--r--xc/programs/Xserver/os/osdep.h359
-rw-r--r--xc/programs/Xserver/os/osinit.c219
-rw-r--r--xc/programs/Xserver/os/rpcauth.c204
-rw-r--r--xc/programs/Xserver/os/secauth.c196
-rw-r--r--xc/programs/Xserver/os/utils.c1692
-rw-r--r--xc/programs/Xserver/os/xalloc.c792
-rw-r--r--xc/programs/Xserver/os/xdmauth.c514
-rw-r--r--xc/programs/Xserver/os/xdmcp.c1546
-rw-r--r--xc/programs/Xserver/record/Imakefile29
-rw-r--r--xc/programs/Xserver/record/record.c3024
-rw-r--r--xc/programs/Xserver/record/recordmod.c41
-rw-r--r--xc/programs/Xserver/record/set.c704
-rw-r--r--xc/programs/Xserver/record/set.h155
-rw-r--r--xc/programs/Xserver/xkb/Imakefile69
-rw-r--r--xc/programs/Xserver/xkb/ddxBeep.c359
-rw-r--r--xc/programs/Xserver/xkb/ddxConfig.c221
-rw-r--r--xc/programs/Xserver/xkb/ddxCtrls.c133
-rw-r--r--xc/programs/Xserver/xkb/ddxDevBtn.c104
-rw-r--r--xc/programs/Xserver/xkb/ddxFakeBtn.c62
-rw-r--r--xc/programs/Xserver/xkb/ddxFakeMtn.c76
-rw-r--r--xc/programs/Xserver/xkb/ddxInit.c48
-rw-r--r--xc/programs/Xserver/xkb/ddxKeyClick.c54
-rw-r--r--xc/programs/Xserver/xkb/ddxKillSrv.c51
-rw-r--r--xc/programs/Xserver/xkb/ddxLEDs.c82
-rw-r--r--xc/programs/Xserver/xkb/ddxList.c310
-rw-r--r--xc/programs/Xserver/xkb/ddxLoad.c557
-rw-r--r--xc/programs/Xserver/xkb/ddxVT.c50
-rw-r--r--xc/programs/Xserver/xkb/xkb.c6930
-rw-r--r--xc/programs/Xserver/xkb/xkbAccessX.c851
-rw-r--r--xc/programs/Xserver/xkb/xkbActions.c1463
-rw-r--r--xc/programs/Xserver/xkb/xkbDflts.h519
-rw-r--r--xc/programs/Xserver/xkb/xkbEvents.c1155
-rw-r--r--xc/programs/Xserver/xkb/xkbInit.c1003
-rw-r--r--xc/programs/Xserver/xkb/xkbLEDs.c1212
-rw-r--r--xc/programs/Xserver/xkb/xkbPrKeyEv.c198
-rw-r--r--xc/programs/Xserver/xkb/xkbPrOtherEv.c88
-rw-r--r--xc/programs/Xserver/xkb/xkbSwap.c760
-rw-r--r--xc/programs/Xserver/xkb/xkbUtils.c1140
-rw-r--r--xc/util/compress/Makefile66
-rw-r--r--xc/util/compress/README283
-rw-r--r--xc/util/compress/USERMEM1
-rw-r--r--xc/util/compress/compress.1252
-rw-r--r--xc/util/compress/compress.c1550
-rw-r--r--xc/util/compress/usermem.sh94
-rw-r--r--xc/util/memleak/Imakefile71
-rw-r--r--xc/util/memleak/README70
-rwxr-xr-xxc/util/memleak/find-rtns.sh28
-rw-r--r--xc/util/memleak/fmalloc.c1135
-rw-r--r--xc/util/memleak/ftest.c49
-rw-r--r--xc/util/memleak/getreti386.c36
-rw-r--r--xc/util/memleak/getretmips.c191
-rw-r--r--xc/util/memleak/getretspar.c62
-rw-r--r--xc/util/memleak/getrettest.c44
-rw-r--r--xc/util/memleak/mipsstack.s39
-rw-r--r--xc/util/memleak/sparcsolstack.s11
-rw-r--r--xc/util/memleak/sparcstack.s11
-rw-r--r--xc/util/memleak/stackbottom.c123
-rw-r--r--xc/util/misc/dlsym.c29
-rw-r--r--xc/util/misc/rt.stdarg.h8
-rw-r--r--xc/util/misc/thr_stubs.c27
-rw-r--r--xc/util/patch/ChangeLog290
-rwxr-xr-xxc/util/patch/Configure1476
-rw-r--r--xc/util/patch/EXTERN.h21
-rw-r--r--xc/util/patch/INTERN.h19
-rw-r--r--xc/util/patch/MANIFEST27
-rw-r--r--xc/util/patch/Makefile.SH116
-rw-r--r--xc/util/patch/Makefile.nt41
-rw-r--r--xc/util/patch/README98
-rw-r--r--xc/util/patch/backupfile.c340
-rw-r--r--xc/util/patch/backupfile.h37
-rw-r--r--xc/util/patch/common.h214
-rw-r--r--xc/util/patch/config.H33
-rw-r--r--xc/util/patch/config.h.SH146
-rw-r--r--xc/util/patch/config.h.nt82
-rw-r--r--xc/util/patch/inp.c387
-rw-r--r--xc/util/patch/inp.h18
-rw-r--r--xc/util/patch/malloc.c469
-rw-r--r--xc/util/patch/patch.c941
-rw-r--r--xc/util/patch/patch.man551
-rw-r--r--xc/util/patch/patchlevel.h2
-rw-r--r--xc/util/patch/pch.c1313
-rw-r--r--xc/util/patch/pch.h38
-rw-r--r--xc/util/patch/util.c474
-rw-r--r--xc/util/patch/util.h88
-rw-r--r--xc/util/patch/version.c25
-rw-r--r--xc/util/patch/version.h9
-rw-r--r--xc/util/patch/winnt.h25
1642 files changed, 503068 insertions, 2 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/man/XF86Config.man b/xc/programs/Xserver/hw/xfree86/doc/Japanese/man/XF86Config.man
new file mode 100644
index 000000000..d52d33221
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/man/XF86Config.man
@@ -0,0 +1,1512 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/man/XF86Config.man,v 1.3 1998/04/05 02:28:40 dawes Exp $
+.\"
+.\" Japanese Version Copyright (c) 1996 Kazuyuki Okamoto
+.\" all rights reserved.
+.\" Translated Tue Dec 10 19:45:00 JST 1996
+.\" by Kazuyuki Okamoto <ikko-@pacific.rim.or.jp>
+.\" Doc Version 3.47
+.\"
+.TH XF86Config 4/5 "Version 3.2" "XFree86"
+.\" .SH NAME
+.\" XF86Config - Configuration File for XFree86
+.SH "̾Á°"
+XF86Config - XFree86 "Íѹ½À®¾ðÊó¥Õ¥¡¥¤¥ë"
+.\" .SH DESCRIPTION
+.SH "ÀâÌÀ"
+.I XFree86
+.\" uses a configuration file called \fBXF86Config\fP for its initial
+.\" setup. This configuration file is searched for in the following
+.\" places:
+¤Ï½é´üÀßÄê¤Î¤¿¤á¤Î \fBXF86Config\fP ¤È¤¤¤¦¹½À®¾ðÊó¥Õ¥¡¥¤¥ë¤ò»ÈÍÑ
+¤·¤Þ¤¹¡£¤³¤Î¹½À®¾ðÊó¥Õ¥¡¥¤¥ë¤Ï¼¡¤Î¾ì½ê¤«¤éõ¤·¤Þ¤¹¡£
+.sp
+.in 8
+.nf
+/etc/XF86Config
+<XRoot>/lib/X11/XF86Config.\fIhostname\fP
+<XRoot>/lib/X11/XF86Config
+.fi
+.in -8
+.LP
+.\" where <XRoot> refers to the root of the X11 install tree.
+.\" When an X server is started by a `root' user, it will first search for
+.\" an \fBXF86Config\fP file in that user's home directory.
+¤³¤³¤Ç <XRoot> ¤Ï X11 ¤òƳÆþ¤·¤¿¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹¡£
+X ¥µ¡¼¥Ð¤ò 'root' ¥æ¡¼¥¶¤Ç³«»Ï¤·¤¿¤È¤­¡¢ \fBXF86Config\fP ¥Õ¥¡¥¤¥ë¤ò
+ 'root' ¥æ¡¼¥¶¤Î¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤«¤éõ¤·¤Þ¤¹¡£
+.PP
+.\" This file is composed of a number of sections. Each section has
+.\" the form:
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ï¤¤¤¯¤Ä¤«¤ÎÀá¤Ç¹½À®¤·¤Æ¤¤¤Þ¤¹¡£¤½¤ì¤¾¤ì¤ÎÀá¤Ï¼¡¤Î·Á¼°¤Ë
+¤Ê¤Ã¤Æ¤¤¤Þ¤¹:
+.sp
+.in 8
+.nf
+.\" Section "\fISectionName\fP"
+.\" \fISectionEntry\fP
+.\" ...
+.\" EndSection
+Section "\fIÀá̾¾Î\fP"
+ \fIÀá¹àÌÜ\fP
+ ...
+EndSection
+.fi
+.in -8
+.PP
+.\" The section names are:
+Àá̾¾Î¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹:
+.sp
+.in 8
+.nf
+.\" \fBFiles\fP (File pathnames)
+.\" \fBModule\fP (Dynamic module loading)
+.\" \fBServerFlags\fP (Server flags)
+.\" \fBKeyboard\fP (Keyboard configuration)
+.\" \fBPointer\fP (Pointer configuration)
+.\" \fBMonitor\fP (Monitor description)
+.\" \fBDevice\fP (Graphics device description)
+.\" \fBScreen\fP (Screen configuration)
+.\" \fBXInput\fP (Extended Input devices configuration)
+\fBFiles\fP (¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹Ì¾)
+\fBModule\fP (ưŪ¤Ê¥â¥¸¥å¡¼¥ë¤Î¥í¡¼¥É)
+\fBServerFlags\fP (¥µ¡¼¥Ð¥ª¥×¥·¥ç¥ó)
+\fBKeyboard\fP (¥­¡¼¥Ü¡¼¥É¹½À®¾ðÊó)
+\fBPointer\fP (¥Þ¥¦¥¹Åù¤Î¹½À®¾ðÊó)
+\fBMonitor\fP (¥â¥Ë¥¿¡¼¤ÎÀâÌÀ)
+\fBDevice\fP (¥Ó¥Ç¥ª¥«¡¼¥ÉÅù¤ÎÀâÌÀ)
+\fBScreen\fP (²èÌ̤ι½À®¾ðÊó)
+\fBXInput\fP (³ÈÄ¥ÆþÎϵ¡´ï¤Î¹½À®¾ðÊó)
+.fi
+.PP
+.\" The \fBFiles\fP section is used to specify the default font path
+.\" and the path to the RGB database. These paths can also be set from
+.\" the command line (see \fIXserver(1)\fP). The entries available
+.\" for this section are:
+\fBFiles\fP Àá¤Ïɸ½à¤Î¥Õ¥©¥ó¥È¤Î¥Ñ¥¹¤È RGB ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ø¤Î¥Ñ¥¹¤ò
+»ØÄꤷ¤Þ¤¹¡£¤³¤ì¤é¤Î¥Ñ¥¹¤Ï¥³¥Þ¥ó¥É¥é¥¤¥ó¤«¤é¤âÀßÄê½ÐÍè¤Þ¤¹¡£¤³¤ÎÀá¤Ë
+µ­½Ò¤¹¤ëÆâÍÆ¤Ï¼¡¤Î¤è¤¦¤Ë½ñ¤­¤Þ¤¹:
+.TP 8
+.B FontPath \fI"path"\fP
+.\" sets the search path for fonts. This path is a comma separated
+.\" list of directories which the X server searches for font databases.
+.\" Multiple \fBFontPath\fP entries may be specified, and they will be
+.\" concatenated to build up the fontpath used by the server.
+¥Õ¥©¥ó¥È¤Î¸¡º÷·ÐÏ©(¥Ñ¥¹)¤òÀßÄꤷ¤Þ¤¹¡£¤³¤Î¥Ñ¥¹¤Ï X ¥µ¡¼¥Ð¤¬¥Õ¥©¥ó¥È
+¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò¸¡º÷¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê·²¤ò¥«¥ó¥Þ¤Ç¶èÀڤ俥ꥹ¥È¤Ç¤¹¡£
+Ê£¿ô¤Î \fBFontPath\fP ¤¬µ­ºÜ¤µ¤ì¤Æ¤¤¤ë¤È»×¤¤¤Þ¤¹¤¬¡¢¤³¤ì¤é¤ò·ë¹ç
+¤·¤Æ¥µ¡¼¥Ð¤¬»ÈÍѤ¹¤ë¥Õ¥©¥ó¥È¥Ñ¥¹ (fontpath) ¤òºîÀ®¤·¤Þ¤¹¡£
+.sp
+.\" X11R6 allows the X server to request fonts from a font server. A
+.\" font server is specified by placing a "<trans>/<hostname>:<port_number>"
+.\" entry into the fontpath. For example, the fontpath
+.\" "/usr/X11R6/lib/X11/fonts/misc/,tcp/zok:7100" tells the X server
+.\" to first try to locate the font in the local directory
+.\" /usr/X11R6/lib/X11/fonts/misc. If that fails, then request the
+.\" font from the \fIfont server\fP running on machine zok listening
+.\" for connections on TCP port number 7100.
+X11R6 ¤Ï X ¥µ¡¼¥Ð¤¬¥Õ¥©¥ó¥È¥µ¡¼¥Ð¤Ë¥Õ¥©¥ó¥È¤òÍ׵᤹¤ë¤³¤È¤¬²Äǽ
+¤Ë¤Ê¤ê¤Þ¤·¤¿¡£¥Õ¥©¥ó¥È¥µ¡¼¥Ð¤Ï¾ì½ê¤ò "<trans>/<hostname>:<port_number>"
+¤È¥Õ¥©¥ó¥È¥Ñ¥¹¤Ë»ØÄꤷ¤Þ¤¹¡£Î㤨¤Ð¡¢¥Õ¥©¥ó¥È¥Ñ¥¹
+"/usr/X11R6/lib/X11/fonts/misc/,tcp/zok:7100" ¤Ï¤Þ¤ººÇ½é¤Ë¥í¡¼¥«¥ë
+¥Ç¥£¥ì¥¯¥È¥ê /usr/X11R6/lib/X11/fonts/misc ¤ò X ¥µ¡¼¥Ð¤ËÅÁ¤¨¤Þ¤¹¡£
+¤³¤ì¤¬¼ºÇÔ¤·¤¿¤È¤­¤Ë¡¢¥Ý¡¼¥ÈÈÖ¹æ 7100 ¤«¤é TCP ¤ÇÀܳ¤·¤ÆÊ¹¤¤¤Æ
+(listening) ¤¤¤ë zok ¤È¤¤¤¦¥Û¥¹¥È¤Çưºî¤·¤Æ¤¤¤ë \fI¥Õ¥©¥ó¥È¥µ¡¼¥Ð\fP
+¤Ë¥Õ¥©¥ó¥È¤òÍ׵ᤷ¤Þ¤¹¡£
+.TP 8
+.B RGBPath \fI"path"\fP
+.\" sets the path name for the RGB color database.
+¤Ï RGB ¥«¥é¡¼¥Ç¡¼¥¿¥Ù¡¼¥¹ÍѤΥѥ¹Ì¾¾Î¤òÀßÄꤷ¤Þ¤¹¡£
+.TP 8
+.B ModulePath \fI"path"\fP
+.\" sets the search path for dynamic modules. This path is a comma separated
+.\" list fo directories which the X server searches for dynamic module loading
+.\" in the order specified.
+.\" Multiple \fBModulePath\fP entries may be specified, and they will be
+.\" concatenated to build the modulepath used by the server.
+.PP
+¤ÏưŪ¥â¥¸¥å¡¼¥ë¤òõº÷¤¹¤ë·ÐÏ©(¥Ñ¥¹)¤òÀßÄꤷ¤Þ¤¹¡£¤³¤Î¥Ñ¥¹¤Ï X ¥µ¡¼¥Ð¤¬
+»ØÄꤷ¤¿½ç¤Ë¥í¡¼¥É¤¹¤ëưŪ¥â¥¸¥å¡¼¥ë¤ò¸¡º÷¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê·²¤ò¥«¥ó¥Þ¤Ç¶èÀڤä¿
+¥ê¥¹¥È¤Ç¤¹¡£
+Ê£¿ô¤Î \fBModulePath\fP ¤¬µ­ºÜ¤µ¤ì¤Æ¤¤¤ë¤È»×¤¤¤Þ¤¹¤¬¡¢¤³¤ì¤é¤ò·ë¹ç
+¤·¤Æ¥µ¡¼¥Ð¤¬»ÈÍѤ¹¤ë¥â¥¸¥å¡¼¥ë¥Ñ¥¹ (modulepath) ¤òºîÀ®¤·¤Þ¤¹¡£
+.\" The
+.B Module
+.\" section is used to specify which dynamic modules should be loaded.
+.\" At present dynamic modules are only used for XInput devices, and are
+.\" only supported on some systems (currently Linux ELF, FreeBSD 2.x and
+.\" NetBSD 1.x). The entry available for this section is:
+ Àá¤Ï¥í¡¼¥É¤¹¤ëưŪ¥â¥¸¥å¡¼¥ë¤ò»ØÄꤹ¤ë¤È¤³¤í¤Ç¤¹¡£
+¸½¹Ô¤ÎưŪ¥â¥¸¥å¡¼¥ë¤Ï XInput µ¡´ï¤Ç¤·¤«»ÈÍѤ·¤Æ¤¤¤Ê¤¯¤Æ¡¢¤¤¤¯¤Ä¤«¤Î
+¥·¥¹¥Æ¥à(º£¤Î¤È¤³¤í Linux ELF, FreeBSD 2.x ¤È NetBSD 1.x) ¤Î¤ß¥µ¥Ý¡¼
+¥È¤·¤Æ¤¤¤Þ¤¹¡£
+.TP 8
+.B Load \fI"module"\fP
+.\" This instructs the server to load \fI"module"\fP. If the module
+.\" is not specified with a full pathname, the directories specified in
+.\" the \fBModulePath\fP are searched.
+.\" Modules are currently available to support extended input devices. The
+.\" names of these are:
+¤³¤ì¤Ï¥µ¡¼¥Ð¤Ë¥í¡¼¥É¤¹¤ë \fI"module"\fP ¤Î»ØÄê¤Ç¤¹¡£¥â¥¸¥å¡¼¥ë¤Ï
+´°Á´¥Ñ¥¹Ì¾¤Ç»ØÄꤷ¤Ê¤¤¾ì¹ç¡¢ \fBModulePath\fP ¤Ç»ØÄꤷ¤¿
+¥Ç¥£¥ì¥¯¥È¥ê¤«¤éõ¤·¤Þ¤¹¡£¥â¥¸¥å¡¼¥ë¤Ïº£¤Î¤È¤³¤í³ÈÄ¥ÆþÎϵ¡´ï¤ò
+¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£¤½¤Î̾¾Î¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹:
+.sp
+.in 20
+.nf
+.B xf86Elo.so
+.B xf86Jstk.so
+.B xf86Wacom.so
+.B xf86Summa.so
+.fi
+.in -20
+.\" The PEX and XIE extension are also be available as modules on some
+.\" systems. The names for these are:
+PEX ¤È XIE µ¡Ç½³ÈÄ¥¤â¤¤¤¯¤Ä¤«¤Î¥·¥¹¥Æ¥à¤Ç¥â¥¸¥å¡¼¥ë¤È¤·¤ÆÍøÍѲÄǽ¤Ç¤¹¡£
+¤½¤Î̾¾Î¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹:
+.sp
+.in 20
+.nf
+.B pex5.so
+.B xie.so
+.fi
+.in -20
+.RS 8
+.\" For an up-to-date listing, check in <XRoot>/lib/modules.
+ºÇ¿·¤Î°ìÍ÷¤Ï <XRoot>/lib/modules ¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£
+.RE
+.PP
+.\" The \fBServerFlags\fP section is used to specify some miscellaneous
+.\" X server options. The entries available for this section are:
+\fBServerFlags\fP ¤ÎÀá¤Ï¤¤¤¯¤Ä¤«¤Î¿§¡¹¤Ê X ¥µ¡¼¥Ð¥ª¥×¥·¥ç¥ó¤ò
+»ØÄꤹ¤ë¤È¤³¤í¤Ç¤¹¡£¤³¤ÎÀá¤ÇÍøÍѲÄǽ¤Ê¹àÌܤϼ¡¤Î¤È¤ª¤ê¤Ç¤¹:
+.TP 8
+.B NoTrapSignals
+.\" This prevents the X server from trapping a range of unexpected
+.\" fatal signals and exiting cleanly. Instead, the X server will die
+.\" and drop core where the fault occurred. The default behaviour is
+.\" for the X server exit cleanly, but still drop a core file. In
+.\" general you never want to use this option unless you are debugging
+.\" an X server problem.
+¤³¤Î¹àÌÜ¤Ï X ¥µ¡¼¥Ð¤¬ÆÍȯŪ¤ÊÃ×̿Ū¤ÊÈϰϤΥ·¥°¥Ê¥ë¤òÊ᪤¹¤ë¤Î¤òËÉ»ß
+¤·¡¢Àµ¾ï¤Ë½ªÎ»¤µ¤»¤ë¤â¤Î¤Ç¤¹¡£¤³¤Î»ØÄ꤬¤Ê¤¤¤È¡¢X ¥µ¡¼¥Ð¤ÏÄä»ß¤·¤Æ
+ÉÔÀµ¤¬µ¯¤­¤¿¤È¤³¤í¤Ç¥³¥¢¥À¥ó¥×¤òºîÀ®¤·¤Þ¤¹¡£É¸½à¤Îưºî¤Ï X ¥µ¡¼¥Ð¤¬
+Àµ¾ï½ªÎ»¤·¤Þ¤¹¤¬¡¢¥³¥¢¥À¥ó¥×¤òºîÀ®¤·¤Þ¤¹¡£°ìÈÌ¤Ë X ¥µ¡¼¥Ð¤Î¥Ç¥Ð¥Ã¥°
+¤ò¹Ô¤¦»þ¤ò½ü¤¤¤Æ¤³¤Î¥ª¥×¥·¥ç¥ó¤òɬÍפȤ·¤Ê¤¤¤Ç¤·¤ç¤¦¡£
+.TP 8
+.B DontZap
+.\" This disallows the use of the \fBCtrl+Alt+Backspace\fP sequence.
+.\" This sequence allows you to terminate the X server.
+.\" Setting \fBDontZap\fP allows this key sequence to be passed to clients.
+¤³¤Î¹àÌÜ¤Ï \fBCtrl+Alt+Backspace\fP ¤ÎÆþÎϤò̵¸ú¤Ë¤·¤Þ¤¹¡£
+¤³¤Î¥­¡¼ÆþÎÏ¤Ï X ¥µ¡¼¥Ð¤ò½ªÎ»¤µ¤»¤ë¤â¤Î¤Ç¤¹¡£ \fBDontZap\fP ¤òÀßÄꤹ¤ë¤È
+¤³¤Î¥­¡¼ÆþÎϤò¥¯¥é¥¤¥¢¥ó¥È¤Ë¤½¤Î¤Þ¤ÞÅϤ·¤Þ¤¹¡£
+.TP 8
+.B DontZoom
+.\" This disallows the use of the \fBCtrl+Alt+Keypad-Plus\fP and
+.\" \fBCtrl+Alt+Keypad-Minus\fP sequences. These sequences allows you to
+.\" switch between video modes.
+.\" Setting \fBDontZoom\fP allows these key sequences to be passed to clients.
+¤³¤Î¹àÌÜ¤Ï \fBCtrl+Alt+Keypad-Plus\fP ¤È\fBCtrl+Alt+Keypad-Minus\fP
+¤Î¥­¡¼ÆþÎϤò»È¤¨¤Ê¤¤¤è¤¦¤Ë¤·¤Þ¤¹¡£¤³¤Î¥­¡¼ÆþÎϤϥӥǥª¥â¡¼¥É¤ÎÀÚ¤êÂØ¤¨¤ò
+¹Ô¤¦¤â¤Î¤Ç¤¹¡£\fBDontZoom\fP ¤ÎÀßÄê¤ò¤¹¤ë¤È¡¢¤³¤Î¥­¡¼ÆþÎϤò¥¯¥é¥¤¥¢¥ó¥È¤Ë
+¤½¤Î¤Þ¤ÞÅϤ·¤Þ¤¹¡£
+.TP 8
+.B AllowNonLocalXvidtune
+.\" This allows the xvidtune client to connect from another host. By default
+.\" non-local connections are not allowed.
+¤³¤Î¹àÌÜ¤Ï xvidtune ¥¯¥é¥¤¥¢¥ó¥È¤¬Â¾¤Î¥Û¥¹¥È¤«¤éÀܳ¤¹¤ë¤³¤È¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£
+ɸ½à¤Ç¤Ï¥í¡¼¥«¥ëÀܳ°Ê³°¤Ï½ÐÍè¤Þ¤»¤ó¡£
+.TP 8
+.B DisableVidMode
+.\" This disables the parts of the VidMode extension used by the xvidtune client
+.\" that can be used to change the video modes.
+¤³¤Î¹àÌÜ¤Ï ¥Ó¥Ç¥ª¥â¡¼¥É¤òÊѹ¹¤¹¤ë xvidtune ¥¯¥é¥¤¥¢¥ó¥È ¤¬»ÈÍѤ¹¤ë VidMode
+µ¡Ç½³ÈÄ¥¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£
+.TP 8
+.B AllowNonLocalModInDev
+.\" This allows a client to connect from another host and change keyboard
+.\" and mouse settings in the running server. By default
+.\" non-local connections are not allowed.
+¤³¤Î¹àÌܤϥ¯¥é¥¤¥¢¥ó¥È¤¬Â¾¤Î¥Û¥¹¥È¤«¤éÀܳ¤·¤Æ¥­¡¼¥Ü¡¼¥É¤È¥Þ¥¦¥¹¤ÎÀßÄê¤ò
+²ÔÆ¯Ãæ¤Î¥µ¡¼¥Ð¤ÇÊѹ¹¤¹¤ë»ö¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£É¸½à¤Ç¤Ï¥í¡¼¥«¥ëÀܳ°Ê³°¤Ï½ÐÍè
+¤Þ¤»¤ó¡£
+.TP 8
+.B DisableModInDev
+.\" This disables the parts of the Misc extension that can be used to
+.\" modify the input device settings dynamically.
+¤³¤Î¹àÌÜ¤ÏÆþÎϵ¡´ï¤ÎÀßÄê¤òưŪ¤ËÊѹ¹¤Ç¤­¤ë Misc µ¡Ç½³ÈÄ¥¤Î°ìÉô¤òÍ­¸ú¤Ë
+¤·¤Þ¤¹¡£
+.PP
+.\" The \fBKeyboard\fP section is used to specify the keyboard input
+.\" device, parameters and some default keyboard mapping options. The
+.\" entries available for this section are:
+\fBKeyboard\fP Àá¤Ï¥­¡¼¥Ü¡¼¥ÉÆþÎϵ¡´ï¡¢¥Ñ¥é¥á¡¼¥¿¤Èɸ½à¤Î¥­¡¼³ä¤êÅö¤Æ
+¤ò»ØÄꤹ¤ë¤â¤Î¤Ç¤¹¡£¤³¤ÎÀá¤Ëµ­Æþ½ÐÍè¤ëÆâÍÆ¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹:
+.TP 8
+.B Protocol \fI"kbd-protocol"\fP
+.\" \fIkbd-protocol\fP may be either \fBStandard\fP or \fBXqueue\fP.
+.\" \fBXqueue\fP is specified when using the event queue driver on SVR3
+.\" or SVR4.
+¤Î \fIkbd-protocol\fP ¤Ï \fBStandard\fP ¤« \fBXqueue\fP ¤Î¤É¤Á¤é¤«¤Ç¤¹¡£
+\fBXqueue\fP ¤Ï SVR3 ¤« SVR4 ¤Î¥¤¥Ù¥ó¥È¥­¥å¡¼¥É¥é¥¤¥Ð¤ò»ÈÍѤ¹¤ë»þ¤Ë
+»ØÄꤹ¤ë¤â¤Î¤Ç¤¹¡£
+.TP
+.B AutoRepeat \fIdelay rate\fP
+.\" changes the behavior of the autorepeat of the keyboard. This does
+.\" not work on all platforms.
+¤Ï¥­¡¼¥Ü¡¼¥É¤Î¥ª¡¼¥È¥ê¥Ô¡¼¥È¤ÎÀßÄê¤òÊѹ¹¤¹¤ë¤â¤Î¤Ç¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï
+Á´¤Æ¤Îµ¡´ï¤Çưºî¤¹¤ë¤â¤Î¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+.TP 8
+.B ServerNumLock
+.\" forces the X server to handle the numlock key internally. The X
+.\" server sends a different set of keycodes for the numpad when the
+.\" numlock key is active. This enables applications to make use of
+.\" the numpad.
+¤Ï X ¥µ¡¼¥Ð¤ÎÆâÉô¤Ç¥Ê¥à¥í¥Ã¥¯¥­¡¼(numlock)¤ò°·¤¨¤ë¤è¤¦¤Ë¤¹¤ë¤â¤Î¤Ç¤¹¡£
+X ¥µ¡¼¥Ð¤Ï¥Ê¥à¥í¥Ã¥¯¥­¡¼¤¬¥ª¥ó¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤È¤­¤Ë¤Ï°Û¤Ê¤ë¥³¡¼¥É
+¤ÎÁȤ߹ç¤ï¤»¤òÁ÷½Ð¤·¤Þ¤¹¤³¤Î¥ª¥×¥·¥ç¥ó¤¬Í­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤È¥¢¥×¥ê
+¥±¡¼¥·¥ç¥ó¤Ç¥Æ¥ó¥­¡¼¤¬»È¤¨¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
+.PP
+.nf
+.B LeftAlt \fImapping\fP
+.B RightAlt \fImapping\fP
+.B AltGr \fImapping\fP
+.B ScrollLock \fImapping\fP
+.B RightCtl \fImapping\fP
+.fi
+.RS 8
+.\" Allows a default mapping to be set for the above keys (note that
+.\" \fBAltGr\fP is a synonym for \fBRightAlt\fP). The values that may
+.\" be specified for \fImapping\fP are:
+¤³¤ì¤é¤Î¥­¡¼¤¬É¸½à¤Î¥­¡¼³ä¤êÅö¤Æ¤Ç¤¹( \fBAltGr\fP ¤Ï \fBRightAlt\fP
+¤ÈƱ°Õ¸ì)¡£\fImapping\fP ¤Ë¼¡¤Î¥­¡¼¥³¡¼¥É¤ò³ä¤êÅö¤Æ¤·¤Þ¤¹:
+.sp
+.in 20
+.nf
+Meta
+Compose
+ModeShift
+ModeLock
+ScrollLock
+Control
+.fi
+.PP
+.\" The default mapping when none of these options are specified is:
+¤É¤Î¥ª¥×¥·¥ç¥ó¤â»ØÄꤵ¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¤Îɸ½àÃͤϼ¡¤Î¤È¤ª¤ê¤Ç¤¹:
+.sp
+.in 20
+.nf
+LeftAlt Meta
+RightAlt Meta
+ScrollLock Compose
+RightCtl Control
+.fi
+.RE
+.TP 8
+.B XLeds \fIled\fP ...
+.\" makes \fIled\fP available for clients instead of using the traditional
+.\" function (Scroll Lock, Caps Lock & Num Lock). \fIled\fP is a list
+.\" of numbers in the range 1 to 3.
+¤Ï¥¯¥é¥¤¥¢¥ó¥È¤Ëµì¼°¤Îµ¡Ç½(¥¹¥¯¥í¡¼¥ë¥í¥Ã¥¯¡¢¥­¥ã¥Ã¥×¥¹¥í¥Ã¥¯¤È¥Ê¥à¥í¥Ã¥¯)¤Î
+Âå¤ï¤ê¤Ë \fIled\fP ¤òÍøÍѲÄǽ¤Ë¤·¤Þ¤¹¡£ \fIled\fP ¤Ï 1 ¤«¤é 3 ¤ÎÈϰÏ
+¤Î¿ôÃͤΥꥹ¥È¤Ç¤¹¡£
+.TP 8
+.B VTSysReq
+.\" enables the SYSV-style VT switch sequence for non-SYSV systems
+.\" which support VT switching. This sequence is Alt-SysRq followed
+.\" by a function key (Fn). This prevents the X server trapping the
+.\" keys used for the default VT switch sequence.
+¤Ï VT ÀÚ¤êÂØ¤¨¤ò»ý¤ÄÈó SYSV ¥·¥¹¥Æ¥à¤Ë SYSV »ÅÍͤΠVT ÀÚ¤êÂØ¤¨
+¼ê½ç¤ò²Äǽ¤Ë¤·¤Þ¤¹¡£¤³¤Î¼ê½ç¤Ï¥Õ¥¡¥ó¥¯¥·¥ç¥ó¥­¡¼(Fn)¤Î¸å¤Ë Alt-SysRq
+¤¬Á÷½Ð¤µ¤ì¤Þ¤¹¡£¤³¤Î¹àÌÜ¤Ï X ¥µ¡¼¥Ð¤¬É¸½à¤Î VT ÀÚ¤êÂØ¤¨¼ê½ç
+¤òÊ᪤·¤Ê¤¤¤è¤¦¤Ë¤·¤Þ¤¹¡£
+.TP 8
+.B VTInit \fI"command"\fP
+.\" Runs \fIcommand\fP after the VT used by the server has been opened.
+.\" The command string is passed to "/bin/sh -c", and is run with the
+.\" real user's id with stdin and stdout set to the VT. The purpose
+.\" of this option is to allow system dependent VT initialisation
+.\" commands to be run. One example is a command to disable the 2-key
+.\" VT switching sequence which is the default on some systems.
+¤Ï \fIcommand\fP ¤ò¥µ¡¼¥Ð¤¬»È¤Ã¤Æ¤¤¤ë VT ¤ò³«¤¤¤¿¸å¤Ç¼Â¹Ô¤·¤Þ¤¹¡£
+¥³¥Þ¥ó¥Éʸ»úÎó¤Ï "/bin/sh -c" ¤ËÅϤµ¤ì¡¢ÆâÉô¥æ¡¼¥¶¡¼ID ¤Ç¼Â¹Ô¤µ¤ì
+ɸ½àÆþ½ÐÎÏ¤Ï Åö³º VT ¤Ë³ä¤êÅö¤¿¤ê¤Þ¤¹¡£¤³¤Î¹àÌܤÎÌÜŪ¤Ï
+¥·¥¹¥Æ¥à¤Ë°Í¸¤·¤¿ VT ¤Î½é´ü²½¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤¹¤ë¤³¤È¤ò²Äǽ¤Ë¤¹¤ë¤³¤È
+¤Ç¤¹¡£¤¤¤¯¤Ä¤«¤Î¥·¥¹¥Æ¥à¤Ç¤Ïɸ½à¤Ç£²¤Ä¤Î¥­¡¼ÆþÎϤǤΠVT ÀÚ¤êÂØ¤¨¤ò
+̵¸ú¤Ë¤¹¤ë¥³¥Þ¥ó¥É¤¬¤½¤ÎÎã¤Ç¤¹¡£
+.TP 8
+.B XkbDisable
+.\" Turns the XKEYBOARD extension off, equivalent to using the -kb
+.\" command line option.
+¤Ï XKEYBOARD µ¡Ç½³ÈÄ¥¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£ -kb ¥³¥Þ¥ó¥É¥ª¥×¥·¥ç¥ó¤ÈƱÅù¤Ç¤¹¡£
+.PP
+.nf
+.B XkbRules \fI"rulesfile"\fP
+.B XkbModel \fI"model"\fP
+.B XkbLayout \fI"layout"\fP
+.B XkbVariant \fI"variant"\fP
+.B XkbOptions \fI"optionlist"\fP
+.fi
+.RS 8
+.\" These specify the definitions which are used to determine which
+.\" XKEYBOARD components to use. The optionlist, should be a comma
+.\" separated list of options.
+.\" The default mappings for each these are:
+¤³¤ì¤é¤Ï XKEYBOARD ¹½À®Í×ÁǤ¬Ç§¼±¤¹¤ë¹àÌܤòÆÃÄꤹ¤ë¤¿¤á¤Ë»ØÄꤷ¤Þ¤¹¡£
+optionlist ¤Ï¥ª¥×¥·¥ç¥ó¤ò¥«¥ó¥Þ¤Ç¶èÀڤ俥ꥹ¥È¤Ç¤¹¡£
+.sp
+.in 20
+.nf
+XkbRules "xfree86"
+XkbModel "pc101"
+XkbLayout "us"
+XkbVariant ""
+XkbOptions ""
+.fi
+.RE
+.PP
+.\" This is the preferred method of specifying the keyboard configuration,
+.\" however, you can also specify the components directly with:
+¤³¤Î¹àÌܤϥ­¡¼¥Ü¡¼¥É¹½À®¤ò»ØÄꤹ¤ë¹¥¤Þ¤·¤¤ÊýË¡¤Ç¤¹¤¬¡¢¤Þ¤¿¼¡¤Î¤è¤¦¤ËľÀÜ¡¢
+¹½À®Í×ÁǤò»ØÄê¤Ç¤­¤Þ¤¹:
+.sp
+.nf
+.B XkbKeymap \fI"keymap"\fP
+.B XkbKeycodes \fI"keycodes"\fP
+.B XkbTypes \fI"types"\fP
+.B XkbCompat \fI"compat"\fP
+.B XkbSymbols \fI"symbols"\fP
+.B XkbGeometry \fI"geometry"\fP
+.fi
+.RS 8
+.\" If you specify only some of the components, the remaining components
+.\" will use these default values:
+¤¤¤¯¤Ä¤«¤Î¹½À®Í×ÁǤÀ¤±¤ò»ØÄꤷ¤¿¾ì¹ç¡¢»Ä¤ê¤Î¹½À®Í×ÁǤϼ¡¤Î¤è¤¦¤Ëɸ½àÃͤò
+»ÈÍѤ·¤Þ¤¹:
+.sp
+.in 20
+.nf
+XkbKeymap none
+XkbKeycodes "xfree86"
+XkbTypes "default"
+XkbCompat "default"
+XkbSymbols "us(pc101)"
+XkbGeometry "pc"
+.fi
+.RE
+.PP
+.\" The \fBPointer\fP section is used to specify the pointer device
+.\" and parameters. The entries available for this section are:
+\fBPointer\fP Àá¤Ï¥Þ¥¦¥¹Åù¤È¤½¤Î¥Ñ¥é¥á¥¿¤ò»ØÄꤷ¤Þ¤¹¡£
+¤³¤ÎÀá¤Ç»ØÄê²Äǽ¤Ê¹àÌܤϼ¡¤Î¤È¤ª¤ê¤Ç¤¹:
+.TP 8
+.B Protocol \fI"protocol-type\fP"
+.\" specifies the pointer device protocol type. The protocol types
+.\" available are:
+¤Ï¥Þ¥¦¥¹Åù¤Î¥×¥í¥È¥³¥ë¤Î¼ïÎà¤ò»ØÄꤷ¤Þ¤¹¡£»ØÄê²Äǽ¤Ê¥×¥í¥È¥³¥ë¤Î¼ïÎà¤Ï
+¼¡¤Î¤È¤ª¤ê¤Ç¤¹:
+.sp
+.in 20
+.nf
+.B BusMouse
+.B Logitech
+.B Microsoft
+.B MMSeries
+.B Mouseman
+.B MouseSystems
+.B PS/2
+.B MMHitTab
+.B GlidePoint
+.B Xqueue
+.B OSMouse
+.fi
+.in -20
+.RS 8
+.PP
+.\" One should specify \fBBusMouse\fP for the Logitech bus mouse.
+.\" Also, many newer Logitech serial mice use either the \fBMicrosoft\fP
+.\" or \fBMouseMan\fP protocol. \fBXqueue\fP should be specified here
+.\" if it was used in the \fBKeyboard\fP section. \fBOSMouse\fP refers
+.\" to the event-driver mouse interface available on SCO's SVR3. This
+.\" may optionally be followed by a number specifying the number of
+.\" buttons the mouse has.
+Logitech ¥Ð¥¹¥Þ¥¦¥¹¤Ë¤Ï \fBBusMouse\fP ¤ò»ØÄꤷ¤Þ¤·¤ç¤¦¡£
+¤Þ¤¿¡¢Â¿¤¯¤Î¿·¤·¤¤ Logitech ¥·¥ê¥¢¥ë¥Þ¥¦¥¹¤Ï\fBMicrosoft\fP
+¤Þ¤¿¤Ï \fBMouseMan\fP ¥×¥í¥È¥³¥ë¤ò»ÈÍѤ·¤Þ¤¹¡£
+ \fBKeyboard\fP Àá¤Ç \fBXqueue\fP ¤ò»ØÄꤷ¤¿¾ì¹ç¤Ï¤³¤ÎÀá¤Ë
+ \fBXqueue\fP ¤ò»ØÄꤷ¤Þ¤·¤ç¤¦¡£ \fBOSMouse\fP ¤ÏSCO ¤Î SVR3 ¤Ç
+Í­¸ú¤Ê¥¤¥Ù¥ó¥È¶îư·¿¤Î¥Þ¥¦¥¹¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤ËÅö¤Æ¤Ï¤Þ¤ê¤Þ¤¹¡£
+¤½¤Î¸å¤Ç¡¢¥Þ¥¦¥¹¤Î¥Ü¥¿¥ó¤Î¿ô¤ò»ØÄꤷ¤Þ¤·¤ç¤¦¡£
+
+.PP
+.\" If you have a mouse connected to a PS/2 port, you should specify \fBPS/2\fP,
+.\" regardless of the type of mouse you are using.
+ PS/2 ¥Ý¡¼¥È¤ËÀܳ¤µ¤ì¤¿¥Þ¥¦¥¹¤ò»ÈÍѤ¹¤ë¾ì¹ç¤Ï¡¢»ÈÍѤ¹¤ë¥Þ¥¦¥¹¤Î·¿
+¤Ë¤«¤«¤ï¤é¤º \fBPS/2\fP¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+.RE
+.TP 8
+.B Device \fI"pointer-dev"\fP
+.\" specifies the device the server should open for pointer input (eg,
+.\" \fB/dev/tty00\fP or \fB/dev/mouse\fP). A device should not be
+.\" specified when using the \fBXqueue\fP or \fBOSMouse\fP protocols.
+¤Ï¥µ¡¼¥Ð¤¬ÆþÎϵ¡´ïÍѤ˥ª¡¼¥×¥ó¤¹¤ë¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð (Î㤨¤Ð,
+\fB/dev/tty00\fP ¤Þ¤¿¤Ï \fB/dev/mouse\fP) ¤ò»ØÄꤷ¤Þ¤¹¡£
+ \fBXqueue\fP ¤Þ¤¿¤Ï \fBOSMouse\fP ¥×¥í¥È¥³¥ë¤ò»ÈÍѤ¹¤ë¤È¤­¤Ï
+¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤Ï»ØÄꤷ¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£
+.TP 8
+.B Port \fI"pointer-dev"\fP
+.\" is an alternate form of the \fBDevice\fP entry.
+¤Ï \fBDevice\fP ¹àÌÜ¤ÈÆ±¤¸¤â¤Î¤Ç¤¹¡£
+.TP 8
+.B BaudRate \fIrate\fP
+.\" sets the baudrate of the serial mouse to \fIrate\fP. For mice that
+.\" allow dynamic speed adjustments (like Logitech) the baudrate is
+.\" changed in the mouse. Otherwise the rate is simply set on the
+.\" computer's side to allow mice with non-standard rates (the standard
+.\" rate is 1200).
+¤Ï¥·¥ê¥¢¥ë¥Þ¥¦¥¹¤Î¥Ü¡¼¥ì¥¤¥È(ÄÌ¿®Â®ÅÙ)¤ò \fIrate\fP ¤ËÀßÄꤷ¤Þ¤¹¡£
+ưŪ¤ËÄÌ¿®Â®ÅÙ¤òÄ´À᤹¤ë (Logitech ¤Î¤è¤¦¤Ê) ¥Þ¥¦¥¹¤Ç¤ÏÄÌ¿®Â®ÅÙ¤Ï
+¥Þ¥¦¥¹¤ÎÊý¤ÇÊѹ¹¤·¤Þ¤¹¡£¤µ¤â¤Ê¤±¤ì¤Ð¡¢Ã±½ã¤Ë¥³¥ó¥Ô¥å¡¼¥¿Â¦¤Ç
+¥Þ¥¦¥¹¤¬Âбþ¤·¤Æ¤¤¤ëɸ½à°Ê³°¤ÎÄÌ¿®Â®Å٤ΤòÀßÄꤷ¤Þ¤·¤ç¤¦
+(ɸ½à¤ÎÄÌ¿®Â®ÅÙ¤Ï 1200 ¤Ç¤¹)¡£
+.TP 8
+.B Emulate3Buttons
+.\" enables the emulation of the third mouse button for mice which only
+.\" have two physical buttons. The third button is emulated by pressing
+.\" both buttons simultaneously.
+¤ÏʪÍýŪ¤Ë£²¤Ä¤·¤«¥Ü¥¿¥ó¤¬Ìµ¤¤¥Þ¥¦¥¹¤Ç£³¤Ä¤á¤Î¥Ü¥¿¥ó¤Î¥¨¥ß¥å¥ì¡¼¥·¥ç¥ó¤ò
+²Äǽ¤Ë¤·¤Þ¤¹¡££³¤Ä¤á¤Î¥Ü¥¿¥ó¤ÏƱ»þ¤ËξÊý¤Î¥Ü¥¿¥ó¤ò²¡¤¹¤³¤È¤Ç¥¨¥ß¥å
+¥ì¡¼¥·¥ç¥ó¤·¤Þ¤¹¡£
+.TP 8
+.B Emulate3Timeout \fItimeout\fP
+.\" sets the time (in milliseconds) that the server waits before deciding if
+.\" two buttons were pressed ``simultaneously'' when 3 button emulation is
+.\" enabled. The default timeout is 50ms.
+¤Ï£³¥Ü¥¿¥ó¥¨¥ß¥å¥ì¡¼¥·¥ç¥ó¤¬Í­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤È¤­¡¢``Ʊ»þ''¤Ë£²¤Ä¤Î
+¥Ü¥¿¥ó¤¬²¡¤µ¤ì¤¿¤«¤É¤¦¤«·èÄꤹ¤ëÁ°¤ÎÂÔ¤Á»þ´Ö¤ò (¥ß¥êÉÃñ°Ì¤Ç) ÀßÄꤷ¤Þ¤¹¡£
+ɸ½à¤ÎÂÔ¤Á»þ´Ö(¥¿¥¤¥à¥¢¥¦¥È)¤Ï 50ms ¤Ç¤¹¡£
+.TP 8
+.B ChordMiddle
+.\" handles mice which send left+right events when the middle button
+.\" is used (like some Logitech Mouseman mice).
+¤Ï(¤¤¤¯¤Ä¤«¤Î Logitech Mouseman ¥Þ¥¦¥¹¤Î¤è¤¦¤Ë) Ãæ±û¤Î¥Ü¥¿¥ó¤¬²¡¤µ¤ì
+¤¿¤È¤­¡¢±¦¤Èº¸¤Î¥Ü¥¿¥ó¤¬²¡¤µ¤ì¤¿¤è¤¦¤Ê¿®¹æ¤òÁ÷¿®¤¹¤ë¤è¤¦¤Ë¥Þ¥¦¥¹¤ò
+¼è¤ê°·¤¤¤Þ¤¹¡£
+.TP 8
+.B SampleRate \fIrate\fP
+.\" sets the number of motion/button-events the mouse sends per second.
+.\" This is currently only supported for some Logitech mice.
+¤ÏËèÉäΥޥ¦¥¹°ÜưÎÌ/¥Ü¥¿¥ó¤Î¥¤¥Ù¥ó¥ÈȯÀ¸Î̤òÀßÄꤷ¤Þ¤¹¡£
+º£¤Î¤È¤³¤í¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¤¤¤¯¤Ä¤«¤Î Logitech ¥Þ¥¦¥¹¤Î¤ß¤ÇÍøÍѲÄǽ¤Ç¤¹¡£
+.TP 8
+.B ClearDTR
+.\" This option clears the DTR line on the serial port used by the
+.\" mouse. This option is only valid for a mouse using the \fBMouseSystems\fP
+.\" protocol. Some dual-protocol mice require DTR to be cleared to
+.\" operate in MouseSystems mode. Note, in versions of XFree86 prior
+.\" to 2.1, this option also cleared the RTS line. A separate
+.\" \fBClearRTS\fP option has since been added for mice which require
+.\" this.
+¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥Þ¥¦¥¹¤Ç»ÈÍѤ¹¤ë¥·¥ê¥¢¥ë¥Ý¡¼¥È¤Î DTR ¿®¹æ¤ò¥ê¥»¥Ã¥È
+¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï \fBMouseSystems\fP ¥×¥í¥È¥³¥ë¤ò»ÈÍѤ¹¤ë
+¥Þ¥¦¥¹¤Î¾ì¹ç¤ËÍ­¸ú¤Ç¤¹¡££²¤Ä¤Î¥×¥í¥È¥³¥ë¤¬»È¤¨¤ë¥Þ¥¦¥¹¤Ç MouseSystems
+¥â¡¼¥É¤ò»È¤¦¤È¤­¤Ï DTR ¿®¹æ¤ò¥ê¥»¥Ã¥È¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£Ãí°Õ»ö¹à
+¤È¤·¤Æ¡¢2.1 ¤è¤êÁ°¤Î¥Ð¡¼¥¸¥ç¥ó¤Î XFree86 ¤Ç¤Ï¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï RTS
+¿®¹æ¤â¥ê¥»¥Ã¥È¤·¤Þ¤¹¡£Ê¬Î¥¤µ¤ì¤¿ \fBClearRTS\fP ¥ª¥×¥·¥ç¥ó¤Ï RTS ¤Î
+¥ê¥»¥Ã¥È¤¬É¬Íפʥޥ¦¥¹¤Î°Ù¤ËÀߤ±¤é¤ì¤Þ¤·¤¿¡£
+.TP 8
+.B ClearRTS
+This option clears the RTS line on the serial port used by the
+mouse. This option is only valid for a mouse using the \fBMouseSystems\fP
+protocol. Some dual-protocol mice require both DTR and RTS to be
+cleared to operate in MouseSystems mode. Both the \fBClearDTR\fP
+and \fBClearRTS\fP options should be used for such mice.
+¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥Þ¥¦¥¹¤Ç»ÈÍѤ¹¤ë¥·¥ê¥¢¥ë¥Ý¡¼¥È¤Î RTS ¿®¹æ¤ò¥ê¥»¥Ã¥È
+¤·¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï \fBMouseSystems\fP ¥×¥í¥È¥³¥ë¤ò»ÈÍѤ¹¤ë
+¥Þ¥¦¥¹¤Î¾ì¹ç¤ËÍ­¸ú¤Ç¤¹¡££²¤Ä¤Î¥×¥í¥È¥³¥ë¤¬»È¤¨¤ë¥Þ¥¦¥¹¤Ç MouseSystems
+¥â¡¼¥É¤ò»È¤¦¤È¤­¤Ï DTR ¿®¹æ¤È RTS ¿®¹æ¤ò¥ê¥»¥Ã¥È¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+\fBClearDTR\fP ¤È \fBClearRTS\fP ¤ÎξÊý¤Î¥ª¥×¥·¥ç¥ó¤Ï£²¤Ä¤Î¥×¥í¥È¥³¥ë
+¤¬»È¤¨¤ë¥Þ¥¦¥¹¤Ç¤ÏÍ­¸ú¤Ç¤¹¡£
+.PP
+.\" The \fBMonitor\fP sections are used to define the specifications
+.\" of a monitor and a list of video modes suitable for use with a
+.\" monitor. More than one \fBMonitor\fP section may be present in an
+.\" XF86Config file. The entries available for this section are:
+\fBMonitor\fP Àá¤Ï¥â¥Ë¥¿¡¼¤Î»ÅÍͤȥâ¥Ë¥¿¡¼¤Ç»ÈÍѤ¹¤ë¤Î¤Ë¹çÃפ¹¤ë
+¥Ó¥Ç¥ª¥â¡¼¥É¤Î°ìÍ÷¤òÄêµÁ¤·¤Þ¤¹¡£XF86Config ¥Õ¥¡¥¤¥ë¤Î¤Ê¤«¤Ë°ì¤Ä°Ê¾å
+¤Î \fBMonitor\fP À᤬¤¢¤ë¤È»×¤¤¤Þ¤¹¡£¤³¤ÎÀá¤ÎÆâÍÆ¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹:
+.TP 8
+.B Identifier \fI"ID string"\fP
+.\" This specifies a string by which the monitor can be referred to in
+.\" a later \fBScreen\fP section. Each \fBMonitor\fP section should
+.\" have a unique ID string.
+¤³¤ì¤Ï°Ê¹ß¤Î \fBScreen\fP À᤬»²¾È¤¹¤ë¤«¤â¤·¤ì¤Ê¤¤¥â¥Ë¥¿¡¼Ì¾¤ò
+ʸ»úÎó¤Ç»ØÄꤷ¤Þ¤¹¡£¤½¤ì¤¾¤ì¤Î \fBMonitor\fP Àá¤Î̾¾Î¤Ï½Å¤Ê¤é¤Ê¤¤ÍͤË
+ʸ»úÎó¤òÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+.TP 8
+.B VendorName \fI"vendor"\fP
+.\" This optional entry specifies the monitor's manufacturer.
+¤³¤ÎÄɲùàÌܤϥâ¥Ë¥¿¡¼¤ÎÀ½Â¤²ñ¼Ò¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤
+.TP 8
+.B ModelName \fI"model"\fP
+.\" This optional entry specifies the monitor's model.
+¤³¤ÎÄɲùàÌܤϥâ¥Ë¥¿¡¼¤Î¥â¥Ç¥ë̾¾Î(·¿Ì¾)¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+.TP 8
+.B HorizSync \fIhorizsync-range\fP
+.\" gives the range(s) of horizontal sync frequencies supported by the
+.\" monitor. \fIhorizsync-range\fP may be a comma separated list of
+.\" either discrete values or ranges of values. A range of values is
+.\" two values separated by a dash. By default the values are in units
+.\" of kHz. They may be specified in MHz or Hz if \fBMHz\fP or \fBHz\fP
+.\" is added to the end of the line. The data given here is used by the X
+.\" server to determine if video modes are within the specifications
+.\" of the monitor. This information should be available in the
+.\" monitor's handbook.
+¤Ï¥â¥Ë¥¿¡¼¤Î»ÅÍÍÆâ¤Î¿åʿƱ´ü¼þÇÈ¿ô¤ÎÂÓ°èÉý¤òÀßÄꤷ¤Þ¤¹¡£
+\fIhorizsync-range\fP ¤Ï¥«¥ó¥Þ¤Ç¶èÀÚ¤é¤ì¤¿Î¥»¶¤·¤¿¿ôÃͤ«Éý¤Î¤¢¤ë¿ôÃͤÎ
+¥ê¥¹¥È¤Ç¤¹¡£Éý¤Î¤¢¤ë¿ôÃÍ¤ÏÆó¤Ä¤Î¿ô»ú¤ò¥Ï¥¤¥Õ¥ó¤Ç¶èÀڤ俤â¤Î¤Ç¤¹¡£
+ɸ½à¤Ç¤Ï¤³¤ì¤é¤Î¿ôÃͤÎñ°Ì¤Ï kHz ¤Ç¤¹¡£\fBMHz\fP ¤ä \fBHz\fP ¤ò¹Ô¤Î
+¸å¤í¤ËÉÕ¤±¤ë¤È MHz ¤ä Hz ¤Ç»ØÄꤹ¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£¤³¤³¤ÇÍ¿¤¨¤ë
+¿ôÃͤ¬¥Ó¥Ç¥ª¥â¡¼¥É¤¬¥â¥Ë¥¿¡¼¤Î»ÅÍͤ˼ý¤Þ¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï X ¥µ¡¼¥Ð
+¤Ëǧ¼±¤µ¤ì¤Þ¤¹¡£¤³¤Î»ÅÍͤϥâ¥Ë¥¿¡¼¤Î¼è°·ÀâÌÀ½ñ¤Ë½ñ¤¤¤Æ¤¢¤ë¤Ç¤·¤ç¤¦¡£
+.TP 8
+.B VertRefresh \fIvertrefresh-range\fP
+.\" gives the range(s) of vertical refresh frequencies supported by
+.\" the monitor. \fIvertrefresh-range\fP may be a comma separated list
+.\" of either discrete values or ranges of values. A range of values
+.\" is two values separated by a dash. By default the values are in
+.\" units of Hz. They may be specified in MHz or kHz if \fBMHz\fP or
+.\" \fBkHz\fP is added to the end of the line. The data given here is used
+.\" by the X server to determine if video modes are within the
+.\" specifications of the monitor. This information should be available
+.\" in the monitor's handbook.
+¤Ï¥â¥Ë¥¿¡¼¤Î»ÅÍÍÆâ¤Î¿âľƱ´ü¼þÇÈ¿ô¤ÎÂÓ°èÉý¤òÀßÄꤷ¤Þ¤¹¡£
+\fIvertrefresh-range\fP ¤Ï¥«¥ó¥Þ¤Ç¶èÀÚ¤é¤ì¤¿Î¥»¶¤·¤¿¿ôÃͤ«Éý¤Î¤¢¤ë¿ôÃͤÎ
+¥ê¥¹¥È¤Ç¤¹¡£Éý¤Î¤¢¤ë¿ôÃÍ¤ÏÆó¤Ä¤Î¿ô»ú¤ò¥Ï¥¤¥Õ¥ó¤Ç¶èÀڤ俤â¤Î¤Ç¤¹¡£
+ɸ½à¤Ç¤Ï¤³¤ì¤é¤Î¿ôÃͤÎñ°Ì¤Ï kHz ¤Ç¤¹¡£\fBMHz\fP ¤ä \fBHz\fP ¤ò¹Ô¤Î
+¸å¤í¤ËÉÕ¤±¤ë¤È MHz ¤ä Hz ¤Ç»ØÄꤹ¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£¤³¤³¤ÇÍ¿¤¨¤ë
+¿ôÃͤ¬¥Ó¥Ç¥ª¥â¡¼¥É¤¬¥â¥Ë¥¿¡¼¤Î»ÅÍͤ˼ý¤Þ¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï X ¥µ¡¼¥Ð
+¤Ëǧ¼±¤µ¤ì¤Þ¤¹¡£¤³¤Î¾ðÊó¤Ï¥â¥Ë¥¿¡¼¤Î¼è°·ÀâÌÀ½ñ¤Ë½ñ¤¤¤Æ¤¢¤ë¤Ç¤·¤ç¤¦¡£
+.TP 8
+.B Gamma \fIgamma-value(s)\fP
+.\" This is an optional entry that can be used to specify the gamma
+.\" correction for the monitor. It may be specified as either a single
+.\" value or as three separate RGB values. Not all X servers are capable
+.\" of using this information.
+¥â¥Ë¥¿¡¼¤Î¥¬¥ó¥ÞÊäÀµ¤ÎÀßÄê¤ò¹Ô¤¦¤¿¤á¤ÎÄɲùàÌܤǤ¹¡££±¤Ä¤Î¿ôÃͤ«
+RGB ¤½¤ì¤¾¤ìÂбþ¤Î£³¤Ä¤Î¿ôÃͤòÀßÄꤷ¤Þ¤¹¡£¤³¤Î¾ðÊó¤ÏÁ´¤Æ¤Î X ¥µ¡¼¥Ð
+¤Ç»È¤¨¤ëÌõ¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+.TP 8
+.B Mode \fI"name"\fP
+.\" indicates the start of a multi-line video mode description. The
+.\" mode description is terminated with an \fBEndMode\fP line. The
+.\" mode description consists of the following entries:
+¤ÏÊ£¿ô¹Ô¤Ç»ØÄꤹ¤ë¥Ó¥Ç¥ª¥â¡¼¥É¤Îµ­½Ò¤Î»Ï¤Þ¤ê¤òɽ¤ï¤·¤Þ¤¹¡£
+¥Ó¥Ç¥ª¥â¡¼¥É¤Îµ­½Ò¤Î½ª¤ï¤ê¤Ï \fBEndMode\fP ¹Ô¤Ç¤¹¡£
+¥Ó¥Ç¥ª¥â¡¼¥É¤Îµ­½Ò¤ÎÆâÍÆ¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹:
+.sp
+.RS 8
+.TP 4
+.B DotClock \fIclock\fP
+.\" is the dot clock rate to be used for the mode.
+¤Ï¤½¤Î¥â¡¼¥É¤Ç»ÈÍѤ¹¤ë¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Î¼þÇÈ¿ô¤Ç¤¹¡£
+.TP 4
+.B HTimings \fIhdisp hsyncstart hsyncend htotal\fP
+.\" specifies the horizontal timings for the mode.
+¤Ï¿åʿƱ´ü¤ÎÄ´À°Ãͤò»ØÄꤷ¤Þ¤¹¡£
+.TP 4
+.B VTimings \fIvdisp vsyncstart vsyncend vtotal\fP
+.\" specifies the vertical timings for the mode.
+¤Ï¿âľƱ´ü¤ÎÄ´À°Ãͤò»ØÄꤷ¤Þ¤¹¡£
+.TP 4
+.B Flags \fI"flag" ...\fP
+.\" specifies an optional set of mode flags. \fB"Interlace"\fP indicates
+.\" that the mode is interlaced. \fB"DoubleScan"\fP indicates a mode where
+.\" each scanline is doubled. \fB"+HSync"\fP and \fB"-HSync"\fP can
+.\" be used to select the polarity of the HSync signal. \fB"+VSync"\fP
+.\" and \fB"-VSync"\fP can be used to select the polarity of the VSync
+.\" signal. \fB"Composite"\fP, can be used to specify composite sync on
+.\" hardware where this is supported. Additionally, on some hardware,
+.\" \fB"+CSync"\fP and \fB"-CSync"\fP may be used to select the composite
+.\" sync polarity.
+¤Ï¥â¡¼¥É¥Õ¥é¥°¤ÎÄɲÃÀßÄê¤ò»ØÄꤷ¤Þ¤¹¡£ \fB"Interlace"\fP ¤Ï
+¥¤¥ó¥¿¡¼¥ì¡¼¥¹¥â¡¼¥É¤Ç¤¢¤ë¤³¤È¤ò»Ø¤·¤Þ¤¹¡£ \fB"DoubleScan"\fP ¤Ï
+¤½¤ì¤¾¤ì¤ÎÁöººÀþ¤òÆó½Å¤Ë¤¹¤ë¥â¡¼¥É¤Ç¤¹¡£
+\fB"+HSync"\fP ¤È \fB"-HSync"\fP ¤Ï¿åʿƱ´ü¿®¹æ¤Î¶ËÀ­¤òÁªÂò¤·¤Þ¤¹¡£
+\fB"+VSync"\fP ¤È \fB"-VSync"\fP ¤Ï¿âľƱ´ü¿®¹æ¤Î¶ËÀ­¤òÁªÂò¤·¤Þ¤¹¡£
+\fB"Composite"\fP ¤Ï¥°¥é¥Õ¥£¥Ã¥¯¥Ü¡¼¥É¤¬Âбþ¤·¤Æ¤¤¤ì¤Ð¡¢
+¥³¥ó¥Ý¥¸¥Ã¥ÈƱ´ü¤ò»ØÄꤷ¤Þ¤¹¡£ÉÕ¤±²Ã¤¨¤ì¤Ð¡¢¤¤¤¯¤Ä¤«¤Î¥°¥é¥Õ¥£¥Ã
+¥¯¥Ü¡¼¥É¤Ç¤Ï \fB"+CSync"\fP ¤È \fB"-CSync"\fP ¤Ç¥³¥ó¥Ý¥¸¥Ã¥ÈƱ´ü¤Î
+¶ËÀ­¤¬ÁªÂò½ÐÍè¤ë¤Ç¤·¤ç¤¦¡£
+.TP
+.B HSkew \fIhskew\fP
+.\" specifies the number of pixels (towards the right edge of the screen) by which
+.\" the display enable signal is to be skewed. Not all servers use this
+.\" information. This option might become necessary to override the default
+.\" value supplied by the server (if any). "Roving" horizontal lines indicate this
+.\" value needs to be increased. If the last few pixels on a scan line appear on
+.\" the left of the screen, this value should be decreased.
+²èÌ̤α¦Ã¼¤ËÂФ·¤ÆÉ½¼¨²Äǽ¿®¹æ¤ò·¹¤±¤ë¥Ô¥¯¥»¥ë¿ô¤ò»ØÄꤷ¤Þ¤¹¡£Á´¤Æ¤Î¥µ¡¼¥Ð¤Ç
+¤³¤Î¾ðÊó¤ò»ÈÍѤ·¤Þ¤»¤ó¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥µ¡¼¥Ð¤¬Ä󶡤·¤Æ¤¤¤ë (¤â¤·¤¢¤ì¤Ð)
+ɸ½àÃͤòÃÖ¤­´¹¤¨¤ëɬÍפ¬¤¢¤ì¤Ð»ØÄꤷ¤Þ¤·¤ç¤¦¡£¿åÊ¿Àþ¤¬"¤Õ¤é¤Ä¤¤¤Æ¤¤¤ë"¾ì¹ç¤Ï
+¤³¤Î¿ôÃͤòÁý²Ã¤·¤Æ¤¯¤À¤µ¤¤¡£ÁöººÀþ¤ÎºÇ¸å¤Î¿ô¥Ô¥¯¥»¥ë¤¬²èÌ̤κ¸¤Ë¤«¤«¤Ã¤Æ¤¤¤ë
+¾ì¹ç¤Ï¤³¤Î¿ôÃͤò¸º¤é¤·¤Æ¤¯¤À¤µ¤¤¡£
+.RE
+.TP 8
+.B Modeline \fI"name" mode-description\fP
+.\" is a single line format for specifying video modes. The
+.\" \fImode-description\fP is in four sections, the first three of
+.\" which are mandatory. The first is the pixel clock. This is a
+.\" single number specifying the pixel clock rate for the mode. The
+.\" second section is a list of four numbers specifying the horizontal
+.\" timings. These numbers are the \fIhdisp\fP, \fIhsyncstart\fP,
+.\" \fIhsyncend\fP, \fIhtotal\fP. The third section is a list of four
+.\" numbers specifying the vertical timings. These numbers are
+.\" \fIvdisp\fP, \fIvsyncstart\fP, \fIvsyncend\fP, \fIvtotal\fP. The
+.\" final section is a list of flags specifying other characteristics
+.\" of the mode. \fBInterlace\fP indicates that the mode is interlaced.
+.\" \fBDoubleScan\fP indicates a mode where each scanline is doubled.
+.\" \fB+HSync\fP and \fB\-HSync\fP can be used to select the polarity
+.\" of the HSync signal. \fB+VSync\fP and \fB\-VSync\fP can be used
+.\" to select the polarity of the VSync signal. \fBComposite\fP can be
+.\" used to specify composite sync on hardware where this is supported.
+.\" Additionally, on some hardware,
+.\" \fB+CSync\fP and \fB-CSync\fP may be used to select the composite
+.\" sync polarity. The \fBHSkew\fP option mentioned above can also be used here.
+¤Ï¥Ó¥Ç¥ª¥â¡¼¥É¤ÎÀßÄê¤ò£±¹Ô¤Ç¹Ô¤¦¤â¤Î¤Ç¤¹¡£\fImode-description\fP ¤Ï
+£´¤Ä¤ÎÉôʬ¤Ëʬ¤«¤ì¤Æ¤¤¤Æ¡¢ºÇ½é¤Î£³¤Ä¤Ïɬ¿Ü¤Ç¤¹¡£ºÇ½é¤Ï¥Ô¥¯¥»¥ë
+¥¯¥í¥Ã¥¯¤Ç¤¹¡£Âбþ¤¹¤ë¥â¡¼¥É¤Î¥Ô¥¯¥»¥ë¥¯¥í¥Ã¥¯¤Î¼þÇÈ¿ô¤ò£±¤Ä¤Î¿ôÃͤÇ
+»ØÄꤷ¤Þ¤¹¡£¼¡¤ÎÉôʬ¤Ï¿åÊ¿Êý¸þ¤ÎÄ´À°Ãͤǡ¢£´¤Ä¤Î¿ôÃͤò¥ê¥¹¥È¤Ç»ØÄê
+¤·¤Þ¤¹¡£¤½¤ì¤¾¤ì¤Î¿ôÃÍ¤Ï \fIhdisp\fP, \fIhsyncstart\fP, \fIhsyncend\fP,
+\fIhtotal\fP ¤Ç¤¹¡££³ÈÖÌܤÎÉôʬ¤Ï¿âľÊý¸þ¤ÎÄ´À°Ãͤǡ¢£´¤Ä¤Î¿ôÃͤò
+¥ê¥¹¥È¤Ç»ØÄꤷ¤Þ¤¹¡£¤½¤ì¤¾¤ì¤Î¿ôÃÍ¤Ï \fIvdisp\fP, \fIvsyncstart\fP,
+\fIvsyncend\fP, \fIvtotal\fP ¤Ç¤¹¡£ºÇ¸å¤ÎÉôʬ¤Ï¤½¤Î¾¤Î¥â¡¼¥É¤ÎÆÃħ
+¤ò»ØÄꤹ¤ë¥Õ¥é¥°¤Î¥ê¥¹¥È¤Ç¤¹¡£\fBInterlace\fP ¤Ï¥¤¥ó¥¿¡¼¥ì¡¼¥¹¥â¡¼¥É
+¤ò»Ø¤·¤Þ¤¹¡£\fB"DoubleScan"\fP ¤ÏÁöººÀþ¤òÆó½Å¤Ë¤¹¤ë¥â¡¼¥É¤Ç¤¹¡£
+\fB"+HSync"\fP ¤È \fB"-HSync"\fP ¤Ï¿åʿƱ´ü¿®¹æ¤Î¶ËÀ­¤òÁªÂò¤·¤Þ¤¹¡£
+\fB"+VSync"\fP ¤È \fB"-VSync"\fP ¤Ï¿âľƱ´ü¿®¹æ¤Î¶ËÀ­¤òÁªÂò¤·¤Þ¤¹¡£
+\fB"Composite"\fP ¤Ï¥°¥é¥Õ¥£¥Ã¥¯¥Ü¡¼¥É¤¬Âбþ¤·¤Æ¤¤¤ì¤Ð¡¢
+¥³¥ó¥Ý¥¸¥Ã¥ÈƱ´ü¤ò»ØÄꤷ¤Þ¤¹¡£ÉÕ¤±²Ã¤¨¤ì¤Ð¡¢¤¤¤¯¤Ä¤«¤Î¥°¥é¥Õ¥£¥Ã
+¥¯¥Ü¡¼¥É¤Ç¤Ï \fB"+CSync"\fP ¤È \fB"-CSync"\fP ¤Ç¥³¥ó¥Ý¥¸¥Ã¥ÈƱ´ü¤Î
+¶ËÀ­¤¬ÁªÂò½ÐÍè¤ë¤Ç¤·¤ç¤¦¡£¾åµ­¤Î \fBHSkew\fP ¤â¤³¤³¤Ç¤â»ÈÍѽÐÍè¤Þ¤¹¡£
+.PP
+.\" The \fBDevice\fP sections are used to define a graphics device
+.\" (video board). More than one \fBDevice\fP section may be present
+.\" in an XF86Config file. The entries available for this section are:
+\fBDevice\fP Àá¤Ï²èÁüµ¡´ï¡Ê¥Ó¥Ç¥ª¥Ü¡¼¥É¡Ë¤ÎÄêµÁ¤Ç¤¹¡££±¤Ä°Ê¾å¤Î
+\fBDevice\fP À᤬ XF86Config ¥Õ¥¡¥¤¥ë¤Ë¤¢¤ë¤È»×¤¤¤Þ¤¹¡£¤³¤ÎÀá¤Ç
+»ÈÍѽÐÍè¤ë¹àÌܤϼ¡¤Î¤È¤ª¤ê¤Ç¤¹:
+.TP 8
+.B Identifier \fI"ID string"\fP
+.\" This specifies a string by which the graphics device can be referred
+.\" to in a later \fBScreen\fP section. Each \fBDevice\fP section
+.\" should have a unique ID string.
+¤³¤ì¤Ï¼¡¤Î \fBScreen\fP Àá¤ÎÃæ¤Î¥Ó¥Ç¥ª¥«¡¼¥É¤Ç»²¾È¤µ¤ì¡¢Ê¸»úÎó¤Ç
+»ØÄꤷ¤Þ¤¹¡£¤½¤ì¤¾¤ì¤Î \fBDevice\fP Àá¤Ï½ÅÊ£¤·¤Ê¤¤Ì¾¾Î¤Ç¤Ê¤±¤ì¤Ð
+¤¤¤±¤Þ¤»¤ó¡£
+.TP 8
+.B VendorName \fI"vendor"\fP
+.\" This optional entry specifies the graphics device's manufacturer.
+¤³¤ÎÄɲùàÌܤϲèÁüµ¡´ï¤ÎÀ½Â¤²ñ¼Ò¤ò»ØÄꤷ¤Þ¤¹¡£
+.TP 8
+.B BoardName \fI"model"\fP
+.\" This optional entry specifies the name of the graphics device.
+¤³¤ÎÄɲùàÌܤϲèÁüµ¡´ï¤Î̾Á°¤ò»ØÄꤷ¤Þ¤¹¡£
+.TP 8
+.B Chipset \fI"chipset-type"\fP
+.\" This optional entry specifies the chipset used on the graphics
+.\" board. In most cases this entry is not required because the X
+.\" servers will probe the hardware to determine the chipset type.
+¤³¤ÎÄɲùàÌܤϥӥǥª¥Ü¡¼¥É¤Ë»È¤ï¤ì¤Æ¤¤¤ë¥Á¥Ã¥×¥»¥Ã¥È¤ò»ØÄꤷ¤Þ¤¹¡£
+X ¥µ¡¼¥Ð¤¬¥Á¥Ã¥×¥»¥Ã¥È¤Î·¿¤òǧ¼±¤¹¤ë¤¿¤á¤Ë¥Ó¥Ç¥ª¥Ü¡¼¥É¤òõºº¤¹
+¤ë¤Î¤Ç¡¢Ëؤɤξì¹çɬ¿Ü¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+.TP 8
+.B Ramdac \fI"ramdac-type"\fP
+.\" This optional entry specifies the type of RAMDAC used on the graphics
+.\" board. This is only used by a few of the X servers, and in most
+.\" cases it is not required because the X servers will probe the
+.\" hardware to determine the RAMDAC type where possible.
+¤³¤ÎÄɲùàÌܤϥӥǥª¥Ü¡¼¥É¤Ë»È¤ï¤ì¤Æ¤¤¤ë RAMDAC ¤Î·¿¤ò»ØÄꤷ¤Þ¤¹¡£
+¾¯¿ô¤Î X ¥µ¡¼¥Ð¤Ç¤Î¤ß»ÈÍѤ·¤Æ¤¤¤Þ¤¹¤¬¡¢X ¥µ¡¼¥Ð¤¬ RAMDAC ¤Î
+·¿¤òǧ¼±¤¹¤ë¤¿¤á¤Ë¥Ó¥Ç¥ª¥Ü¡¼¥É¤òõºº¤¹¤ë¤Î¤Ç¡¢Ëؤɤξì¹ç
+ɬ¿Ü¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+.TP 8
+.B DacSpeed \fIspeed\fP
+.\" This optional entry specifies the RAMDAC speed rating (which is
+.\" usually printed on the RAMDAC chip). The speed is in MHz. This
+.\" is only used by a few of the X servers, and only needs to be
+.\" specified when the speed rating of the RAMDAC is different from
+.\" the default built in to the X server.
+¤³¤ÎÄɲùàÌÜ¤Ï RAMDAC ¤Î¼þÇÈ¿ô(ÉáÄÌ RAMDAC ¥Á¥Ã¥×¤Î¾å¤Ë°õºþ¤µ¤ì¤Æ
+¤¤¤Þ¤¹)¤ò»ØÄꤷ¤Þ¤¹¡£¼þÇÈ¿ô¤Ï MHz ¤Ç»ØÄꤷ¤Þ¤¹¡£¾¯¿ô¤Î X ¥µ¡¼¥Ð
+¤Ç¤Î¤ß»ÈÍѤ·¤Æ¤¤¤Þ¤¹¤¬¡¢ RAMDAC ¤Î¼þÇÈ¿ô¤¬ X ¥µ¡¼¥Ð
+ɸ½à¤ÎÆâ¢¼þÇÈ¿ô¤È°Û¤Ê¤Ã¤Æ¤¤¤ë¾ì¹ç¤Î¤ßɬÍפˤʤê¤Þ¤¹¡£
+.TP 8
+.B Clocks \fIclock ...\fP
+.\" specifies the dotclocks that are on your graphics board. The clocks
+.\" are in MHz, and may be specified as a floating point number. The
+.\" value is stored internally to the nearest kHz. The ordering of
+.\" the clocks is important. It must match the order in which they
+.\" are selected on the graphics board. Multiple \fBClocks\fP lines
+.\" may be specified. For boards with programmable clock chips, the
+.\" \fBClockChip\fP entry should be used instead of this. A \fBClocks\fP
+.\" entry is not mandatory for boards with non-programmable clock chips,
+.\" but is highly recommended because it prevents the clock probing
+.\" phase during server startup. This clock probing phase can cause
+.\" problems for some monitors.
+¤Ï¥Ó¥Ç¥ª¥Ü¡¼¥É¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ò»ØÄꤷ¤Þ¤¹¡£¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Î¼þÇÈ¿ô¤Ï
+MHz ¤Ç¡¢ÉâÆ°¾®¿ôÅÀ¤Ç»ØÄꤹ¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£¿ôÃÍ¤ÏÆâÉôŪ¤Ë¤Ï
+°ìÈֶᤤ kHz ¤ÇÃߤ¨¤é¤ì¤Þ¤¹¡£¥¯¥í¥Ã¥¯¤Î»ØÄê½çÈÖ¤¬½ÅÍפǤ¹¡£ÁªÂò¤·¤¿
+¥Ó¥Ç¥ª¥Ü¡¼¥É¤ËÂбþ¤·¤¿½çÈ֤ˤʤäƤ¤¤ë¤³¤È¤¬É¬¿Ü¤Ç¤¹¡£Ê£¿ô¤Î
+\fBClocks\fP ¹Ô¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¤Ç¤·¤ç¤¦¡£¥×¥í¥°¥é¥Þ¥Ö¥ë¥¯¥í¥Ã¥¯¤Î
+¥Á¥Ã¥×ÅëºÜ¤Î¥Ó¥Ç¥ª¥Ü¡¼¥É¤Ç¤Ï¡¢\fBClockChip\fP ¤Î¹àÌÜ¤Ï Clocks
+¤ÎÂå¤ê¤Ë¤Ê¤ê¤Þ¤¹¡£\fBClocks\fP ¤Î¹àÌÜ¤Ï¥×¥í¥°¥é¥Þ¥Ö¥ë¥¯¥í¥Ã¥¯¤Ç¤Ï
+¤Ê¤¤¥Ü¡¼¥É¤Ç¤Ïɬ¿Ü¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¤¬¡¢¥µ¡¼¥Ð¤Îµ¯Æ°»þ¤Ë¥¯¥í¥Ã¥¯¤Îõºº
+¤¬Àµ¤·¤¯¹Ô¤¨¤Ê¤¤¾ì¹ç¤¬¤¢¤ë¤Î¤Ç»ØÄꤹ¤ë¤³¤È¤ò¶¯¤¯¤ª´«¤á¤·¤Þ¤¹¡£
+¤¤¤¯¤Ä¤«¤Î¥â¥Ë¥¿¡¼¤Ç¤Ï¥¯¥í¥Ã¥¯¤Îõºº¤ËÌäÂ꤬À¸¤¸¤Þ¤¹¡£
+.TP 8
+.B ClockChip \fI"clockchip-type"\fP
+.\" This optional entry is used to specify the clock chip type on
+.\" graphics boards which have a programmable clock generator. Only
+.\" a few X servers support programmable clock chips. For details,
+.\" see the appropriate X server manual page.
+¤³¤ÎÄɲùàÌÜ¤Ï¥×¥í¥°¥é¥Þ¥Ö¥ë¥¯¥í¥Ã¥¯¥¸¥§¥Í¥ì¡¼¥¿ÅëºÜ¤Î¥¯¥í¥Ã¥¯
+¥Á¥Ã¥×¤Î·¿¤ò»ØÄꤷ¤Þ¤¹¡£¾¯¿ô¤Î¥×¥í¥°¥é¥Þ¥Ö¥ë¥¯¥í¥Ã¥¯¥Á¥Ã¥×Âбþ¤Î
+X ¥µ¡¼¥Ð¤Ç¤Î¤ß»ÈÍѤ·¤Æ¤¤¤Þ¤¹¡£¾Ü¤·¤¯¤Ï¡¢³ºÅö¤¹¤ë X ¥µ¡¼¥Ð¤Î
+¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+.TP 8
+.B ClockProg \fI"command"\fP [\fItextclock\fP]
+.\" This optional entry runs \fIcommand\fP to set the clock on the
+.\" graphics board instead of using the internal code. The command
+.\" string must consist of the full pathname (and no flags). When
+.\" using this option, a \fBClocks\fP entry is required to specify
+.\" which clock values are to be made available to the server (up to
+.\" 128 clocks may be specified). The optional \fItextclock\fP value
+.\" is used to tell the server that \fIcommand\fP must be run to restore
+.\" the textmode clock at server exit (or when VT switching).
+.\" \fItextclock\fP must match one of the values in the \fBClocks\fP
+.\" entry. This parameter is required when the clock used for text
+.\" mode is a programmable clock.
+¤³¤ÎÄɲùàÌÜ¤ÏÆâÉô¥×¥í¥°¥é¥à¤ÎÂå¤ê¤Ë \fIcommand\fP ¤ò¼Â¹Ô¤·¤Æ
+¥Ó¥Ç¥ª¥Ü¡¼¥É¤Î¥¯¥í¥Ã¥¯¤òÀßÄꤷ¤Þ¤¹¡£¥³¥Þ¥ó¥É¤Î̾¾Î¤Ï¥Õ¥ë¥Ñ¥¹¤Ç
+Í¿¤¨¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó(¥³¥Þ¥ó¥É¤Î¥ª¥×¥·¥ç¥ó¤Ï»ØÄê¤Ç¤­¤Þ¤»¤ó)¡£
+¤³¤Î¹àÌܤò»ÈÍѤ¹¤ë¤È¤­¤Ï¡¢\fBClocks\fP ¹Ô¤Î¹àÌܤϥµ¡¼¥Ð¤ÇÍøÍÑ
+²Äǽ¤Ê¿ôÃͤò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹(128 °Ê¾å¤Î¼þÇÈ¿ô¤ò»ØÄꤹ¤ë
+ɬÍפ¬¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó)¡£ \fItextclock\fP ¤È¤¤¤¦ÄɲùàÌܤϡ¢
+¥µ¡¼¥Ð¤¬½ªÎ»¤·¤¿¤È¤­¤Î(Ëô¤Ï VT ÀÚ¤êÂØ¤¨»þ¤Î)¸µ¤Î¥Æ¥­¥¹¥È¥â¡¼¥É
+¤Î¥¯¥í¥Ã¥¯¤òÀßÄꤹ¤ë \fIcommand\fP ¤ò¼Â¹Ô¤¹¤Ù¤­¥µ¡¼¥Ð¤ËÅÁ¤¨¤ë
+¤Î¤Ë»È¤¤¤Þ¤¹¡£
+\fItextclock\fP ¤Ï \fBClocks\fP ¹àÌܤΤɤ줫¤Ë°ìÃפ·¤Ê¤±¤ì¤Ð¤¤¤±
+¤Þ¤»¤ó¡£¤³¤ÎÆÃÀ­Ãͤϥƥ­¥¹¥È¥â¡¼¥É¤¬¥×¥í¥°¥é¥Þ¥Ö¥ë¥¯¥í¥Ã¥¯¤Î¾ì¹ç¡¢
+ɬÍפˤʤê¤Þ¤¹¡£
+
+.\" The command is run with the real user's id with stdin and stdout
+.\" set to the graphics console device. Two arguments are passed to
+.\" the command. The first is the clock frequency in MHz as a floating
+.\" point number and the second is the index of the clock in the
+.\" \fBClocks\fP entry. The command should return an exit status of
+.\" 0 when successful, and something in the range 1\-254 otherwise.
+¥³¥Þ¥ó¥É¤Ïɸ½àÆþ½ÐÎϤò¥°¥é¥Õ¥£¥Ã¥¯¥³¥ó¥½¡¼¥ë¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿ÆâÉô
+¥æ¡¼¥¶ id ¤Ç¼Â¹Ô¤µ¤ì¤Þ¤¹¡£Æó¤Ä¤Î°ú¤­¿ô¤¬¥³¥Þ¥ó¥É¤ËÅϤµ¤ì¤Þ¤¹¡£
+ºÇ½é¤Î°ú¤­¿ô¤ÏÉâÆ°¾®¿ô¤Î MHz ñ°Ì¤ÇÍ¿¤¨¤ë¼þÇÈ¿ô¤Ç¡¢Æó¤ÄÌܤΰú¤­¿ô
+¤Ï \fBClocks\fP ¹àÌܤκ÷°ú¤Ç¤¹¡£¥³¥Þ¥ó¥É¤Î½ªÎ»¾õÂÖ¤¬ 0 ¤Î¾ì¹ç¤Ï
+Àµ¾ï½ªÎ»¤Ç¡¢¤½¤¦¤Ç¤Ê¤¤¾ì¹ç¤Ï 1\-254 ¤Î´Ö¤Î¿ôÃͤ¬É½¼¨¤µ¤ì¤Þ¤¹¡£
+
+.\" The command is run when the initial graphics mode is set and when
+.\" changing screen resolution with the hot-key sequences. If the
+.\" program fails at initialisation the server exits. If it fails
+.\" during a mode switch, the mode switch is aborted but the server
+.\" keeps running. It is assumed that if the command fails the clock
+.\" has not been changed.
+¥³¥Þ¥ó¥É¤Ï½é´ü¾õÂ֤Υ°¥é¥Õ¥£¥Ã¥¯¥â¡¼¥É¤òÀßÄꤷ¡¢¥Û¥Ã¥È¥­¡¼¤¬²¡¤µ
+¤ì¤¿»þ¤Î²èÌ̤βòÁüÅÙ¤òÊѹ¹¤·¤Þ¤¹¡£¥³¥Þ¥ó¥É¤¬½é´ü²½¤Ë¼ºÇÔ¤¹¤ë¤È
+¥µ¡¼¥Ð¤ò½ªÎ»¤µ¤»¤Þ¤¹¡£¥â¡¼¥ÉÀÚ¤êÂØ¤¨¤ÎÅÓÃæ¤Ç¼ºÇÔ¤¹¤ë¤È¡¢¥â¡¼¥É
+ÀÚ¤êÂØ¤¨¤ÏÃæÃǤ·¥µ¡¼¥Ð¤Ï³¹Ô¤·¤Þ¤¹¡£¥³¥Þ¥ó¥É¤¬¼ºÇÔ¤·¤¿¤È¤­¤Ï
+¥¯¥í¥Ã¥¯¤ÎÊѹ¹¤Ï¹Ô¤ï¤ì¤Þ¤»¤ó¡£
+.TP 8
+.B Option \fI"optionstring"\fP
+.\" This optional entry allows the user to select certain options
+.\" provided by the drivers. Multiple \fBOption\fP entries may be
+.\" given. The supported values for \fIoptionstring\fP are given in
+.\" the appropriate X server manual pages.
+¤³¤ÎÄɲùàÌܤϥµ¡¼¥Ð¤¬Ä󶡤¹¤ë¥É¥é¥¤¥Ð¡¼¤ÎÃæ¤«¤éŬÀڤʤâ¤Î¤ò
+¥æ¡¼¥¶¤¬ÁªÂò¤Ç¤­¤Þ¤¹¡£Ê£¿ô¤Î \fBOption\fP ¹àÌܤ¬ÄêµÁ¤·¤Æ¤¢¤ë¤È
+»×¤¤¤Þ¤¹¡£ \fIoptionstring\fP ¤ÇÍ¿¤¨¤ë¤³¤È¤¬½ÐÍè¤ë¥É¥é¥¤¥Ð¡¼¤Ï
+³ºÅö¤¹¤ë X ¥µ¡¼¥Ð¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤Ëµ­½Ò¤·¤Æ¤¤¤Þ¤¹¡£
+.TP 8
+.B VideoRam \fImem\fP
+.\" This optional entry specifies the amount of videoram that is
+.\" installed on the graphics board. This is measured in kBytes. In
+.\" most cases this is not required because the X server probes the
+.\" graphics board to determine this quantity.
+¤³¤ÎÄɲùàÌܤϥ°¥é¥Õ¥£¥Ã¥¯¥Ü¡¼¥É¤ËÅëºÜ¤·¤Æ¤¤¤ë¥Ó¥Ç¥ª¥á¥â¥ê¤Î
+Â礭¤µ¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤ì¤Ï ¥­¥í¥Ð¥¤¥È ñ°Ì¤Ç»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+¤Û¤È¤ó¤É¤Î¾ì¹ç X ¥µ¡¼¥Ð¤¬¥°¥é¥Õ¥£¥Ã¥¯¥Ü¡¼¥É¤òÄ´¤Ù¤Æ¥á¥â¥êÎ̤ò
+ǧ¼±¤·¤Þ¤¹¤Î¤ÇɬÍפ¢¤ê¤Þ¤»¤ó¡£
+.TP 8
+.B BIOSBase \fIbaseaddress\fP
+.\" This optional entry specifies the base address of the video BIOS
+.\" for the VGA board. This address is normally 0xC0000, which is the
+.\" default the X servers will use. Some systems, particularly those
+.\" with on-board VGA hardware, have the BIOS located at an alternate
+.\" address, usually 0xE0000. If your video BIOS is at an address
+.\" other than 0xC0000, you must specify the base address in the
+.\" XF86Config file. Note that some X servers don't access the BIOS
+.\" at all, and those which do only use the BIOS when searching for
+.\" information during the hardware probe phase.
+¤³¤ÎÄɲùàÌÜ¤Ï VGA ¥Ü¡¼¥É¤Î¥Ó¥Ç¥ª BIOS ¤Î´ðÄ쥢¥É¥ì¥¹¤ò»ØÄꤷ¤Þ
+¤¹¡£¤³¤Î X ¥µ¡¼¥Ð¤Çɸ½à¤Ç»ÈÍѤ¹¤ë¥¢¥É¥ì¥¹¤ÏÉáÃÊ 0xC0000 ¤Ç¤¹¡£
+ÆÃ¤Ë¥Þ¥¶¡¼¥Ü¡¼¥ÉÆâ¢¤Î VGA ¥Ó¥Ç¥ªÁõÃ֤Τ¤¤¯¤Ä¤«¤Î¥·¥¹¥Æ¥à¤Ç¤Ï¡¢
+ 0xE0000 ¤È¤¤¤¦°Û¤Ê¤ë¥¢¥É¥ì¥¹¤Ë BIOS ¤¬ÅëºÜ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¥Ó¥Ç¥ª
+BIOS ¤¬ 0xC0000 °Ê³°¤Ë¤¢¤ë¾ì¹ç¤Ï¡¢XF86Config ¥Õ¥¡¥¤¥ë¤Ë¤³¤Î´ðÄì
+¥¢¥É¥ì¥¹¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤¤¤¯¤Ä¤«¤Î X ¥µ¡¼¥Ð¤Ç¤Ï¤Þ¤Ã
+¤¿¤¯ BIOS ¤ò¥¢¥¯¥»¥¹¤·¤Ê¤¤¤â¤Î¤â¤¢¤ë»ö¤È¡¢µ¡´ï¾ðÊó¤ÎõººÃʳ¬¤Ç
+BIOS ¤ò»È¤¦¤À¤±¤Î¤â¤Î¤¬¤¢¤ë»ö¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£
+.TP 8
+.B MemBase \fIbaseaddress\fP
+.\" This optional entry specifies the memory base address of a graphics
+.\" board's linear frame buffer. This entry is only used by a few
+.\" X servers, and the interpretation of this base address may be different
+.\" for different X servers. Refer to the appropriate X server manual
+.\" page for details.
+¤³¤ÎÄɲùàÌܤϥӥǥª¥Ü¡¼¥É¤Î¥ê¥Ë¥¢¥Õ¥ì¡¼¥à¥Ð¥Ã¥Õ¥¡¤Î¥á¥â¥ê¤Î´ðÄì
+¥¢¥É¥ì¥¹¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¹àÌܤϤ鷺¤«¤Î X ¥µ¡¼¥Ð¤Ç»ÈÍѤµ¤ì¡¢
+¿§¡¹¤Ê X ¥µ¡¼¥Ð¤ÎÁê°ãÅÀ¤ò¤³¤Î´ðÄ쥢¥É¥ì¥¹¤ÇȽÃǤ·¤Þ¤¹¡£
+.TP 8
+.B IOBase \fIbaseaddress\fP
+.\" This optional entry specifies the IO base address. This entry is only
+.\" used for a few X servers. Refer to the appropriate X server manual page
+.\" for details.
+¤³¤ÎÄɲùàÌÜ¤ÏÆþ½ÐÎϤδðÄ쥢¥É¥ì¥¹¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¹àÌܤϤ鷺¤«¤Î
+ X ¥µ¡¼¥Ð¤À¤±¤Ç»ÈÍѤµ¤ì¤Þ¤¹¡£¾ÜºÙ¤Ï³ºÅö¤¹¤ë X ¥µ¡¼¥Ð¤Î¥ª¥ó¥é¥¤¥ó
+¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+.TP 8
+.B DACBase \fIbaseaddress\fP
+.\" This optional entry specifies the DAC base address. This entry is only
+.\" used for a few X servers. Refer to the appropriate X server manual page
+.\" for details.
+¤³¤ÎÄɲùàÌÜ¤Ï DAC ¤Î´ðÄ쥢¥É¥ì¥¹¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¹àÌܤϤ鷺¤«¤Î
+ X ¥µ¡¼¥Ð¤À¤±¤Ç»ÈÍѤµ¤ì¤Þ¤¹¡£¾ÜºÙ¤Ï³ºÅö¤¹¤ë X ¥µ¡¼¥Ð¤Î¥ª¥ó¥é¥¤¥ó
+¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+.TP 8
+.B POSBase \fIbaseaddress\fP
+.\" This optional entry specifies the POS base address. This entry is only
+.\" used for a few X servers. Refer to the appropriate X server manual page
+.\" for details.
+¤³¤ÎÄɲùàÌÜ¤Ï POS ¤Î´ðÄ쥢¥É¥ì¥¹¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¹àÌܤϤ鷺¤«¤Î
+ X ¥µ¡¼¥Ð¤À¤±¤Ç»ÈÍѤµ¤ì¤Þ¤¹¡£¾ÜºÙ¤Ï³ºÅö¤¹¤ë X ¥µ¡¼¥Ð¤Î¥ª¥ó¥é¥¤¥ó
+¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+.TP 8
+.B COPBase \fIbaseaddress\fP
+.\" This optional entry specifies the coprocessor base address. This entry
+.\" is only used for a few X servers. Refer to the appropriate X server
+.\" manual page for details.
+¤³¤ÎÄɲùàÌÜ¤Ï ¿ôÃͱ黻¥³¥×¥í¥»¥Ã¥µ ¤Î´ðÄ쥢¥É¥ì¥¹¤ò»ØÄꤷ¤Þ¤¹¡£
+¤³¤Î¹àÌܤϤ鷺¤«¤Î X ¥µ¡¼¥Ð¤À¤±¤Ç»ÈÍѤµ¤ì¤Þ¤¹¡£¾ÜºÙ¤Ï³ºÅö¤¹¤ë X ¥µ¡¼¥Ð
+¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+.TP 8
+.B VGABase \fIbaseaddress\fP
+.\" This optional entry specifies the VGA memory base address. This entry
+.\" is only used for a few X servers. Refer to the appropriate X server
+.\" manual page for details.
+¤³¤ÎÄɲùàÌÜ¤Ï VGA ¥á¥â¥ê ¤Î´ðÄ쥢¥É¥ì¥¹¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¹àÌܤϤ鷺¤«¤Î
+ X ¥µ¡¼¥Ð¤À¤±¤Ç»ÈÍѤµ¤ì¤Þ¤¹¡£¾ÜºÙ¤Ï³ºÅö¤¹¤ë X ¥µ¡¼¥Ð¤Î¥ª¥ó¥é¥¤¥ó
+¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+.TP 8
+.B Instance \fInumber\fP
+.\" This optional entry specifies the instance (which indicates if the
+.\" chip is integrated on the motherboard or on an expansion card).
+.\" This entry is only used for a few X servers. Refer to the appropriate
+.\" X server manual page for details.
+¤³¤ÎÄɲùàÌÜ¤Ï (¥Þ¥¶¡¼¥Ü¡¼¥É¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ë¤«¡¢³ÈÄ¥¥«¡¼¥É¤ËÅëºÜ
+¤µ¤ì¤Æ¤¤¤ë) ¼ÂÂÎ ¤Î´ðÄ쥢¥É¥ì¥¹¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¹àÌܤϤ鷺¤«¤Î
+ X ¥µ¡¼¥Ð¤À¤±¤Ç»ÈÍѤµ¤ì¤Þ¤¹¡£¾ÜºÙ¤Ï³ºÅö¤¹¤ë X ¥µ¡¼¥Ð¤Î¥ª¥ó¥é¥¤¥ó
+¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+.TP 8
+.B Speedup \fI"selection"\fP
+.\" This optional entry specifies the selection of speedups to be
+.\" enabled. This entry is only used for a few X servers. Refer to
+.\" the appropriate X server manual page for details.
+¤³¤ÎÄɲùàÌܤϲÄǽ¤Ë¤·¤¿¤¤¹â®²½¤ÎÁªÂò¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î¹àÌܤϤ鷺¤«¤Î
+ X ¥µ¡¼¥Ð¤À¤±¤Ç»ÈÍѤµ¤ì¤Þ¤¹¡£¾ÜºÙ¤Ï³ºÅö¤¹¤ë X ¥µ¡¼¥Ð¤Î¥ª¥ó¥é¥¤¥ó
+¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+.TP 8
+.B S3MNAdjust \fIM N\fP
+.\" This optional entry is specific to the S3 X server. For details, refer
+.\" to the \fIXF86_S3(1)\fP manual page.
+¤³¤ÎÄɲùàÌÜ¤Ï S3 X ¥µ¡¼¥Ð¤Ë»ØÄꤷ¤Þ¤¹¡£¾ÜºÙ¤Ï \fIXF86_S3(1)\fP ¤Î
+¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+.TP 8
+.B S3MClk \fIclock\fP
+.\" This optional entry is specific to the S3 X server. For details, refer
+.\" to the \fIXF86_S3(1)\fP manual page.
+¤³¤ÎÄɲùàÌÜ¤Ï S3 X ¥µ¡¼¥Ð¤Ë»ØÄꤷ¤Þ¤¹¡£¾ÜºÙ¤Ï \fIXF86_S3(1)\fP ¤Î
+¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+.TP 8
+.B S3RefClock \fIclock\fP
+.\" This optional entry is specific to the S3 X server. For details, refer
+.\" to the \fIXF86_S3(1)\fP manual page.
+¤³¤ÎÄɲùàÌÜ¤Ï S3 X ¥µ¡¼¥Ð¤Ë»ØÄꤷ¤Þ¤¹¡£¾ÜºÙ¤Ï \fIXF86_S3(1)\fP ¤Î
+¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+.PP
+.\" The \fBScreen\fP sections are used to specify which graphics boards
+.\" and monitors will be used with a particular X server, and the
+.\" configuration in which they are to be used. The entries available
+.\" for this section are:
+\fBScreen\fP Àá¤ÏÆÃÄê¤Î X ¥µ¡¼¥Ð¤ÇÍѤ¤¤é¤ì¤ë¥Ó¥Ç¥ª¥Ü¡¼¥É¤È¥â¥Ë¥¿¡¼
+¤Î»ØÄê¤È¡¢¤½¤³¤Ç»ÈÍѤ¹¤ë¹½À®¾ðÊó¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤ÎÀá¤ÇÍ­¸ú¤Ê¹àÌܤÏ
+¼¡¤Î¤È¤ª¤ê¤Ç¤¹:
+.TP 8
+.B Driver \fI"driver-name"\fP
+.\" Each \fBScreen\fP section must begin with a \fBDriver\fP entry,
+.\" and the \fIdriver-name\fP given in each \fBScreen\fP section must
+.\" be unique. The driver name determines which X server (or driver
+.\" type within an X server when an X server supports more than one
+.\" head) reads and uses a particular \fBScreen\fP section. The driver
+.\" names available are:
+¤½¤ì¤¾¤ì¤Î \fBScreen\fP Àá¤Ï \fBDriver\fP ¹àÌܤǽñ¤­¤Ï¤¸¤á¤ëɬÍפ¬¤¢¤ê
+¤Þ¤¹¡£\fIdriver-name\fP ¤Ï¤½¤ì¤¾¤ì¤Î \fBScreen\fP Àá¤Ç½Å¤Ê¤é¤Ê¤¤¤è¤¦¤Ë
+¤·¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£¥É¥é¥¤¥Ð̾¾Î¤Ï X ¥µ¡¼¥Ð(¼ã¤¯¤Ï X ¥µ¡¼¥Ð
+¤¬Æâ¢¤·¤Æ¤¤¤ë°ì¤Ä°Ê¾å¤Î¥É¥é¥¤¥Ð¤Î¼ïÎà)¤òÆÉ¤ß¹þ¤à¤«·èÄꤷ¡¢¸Ä¡¹¤Î
+\fBScreen\fP Àá¤Ç»ÈÍѤ·¤Þ¤¹¡£»ÈÍѲÄǽ¤Ê¥É¥é¥¤¥Ð̾¾Î¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹:
+.sp
+.in 20
+.nf
+.B Accel
+.B Mono
+.B SVGA
+.B VGA2
+.B VGA16
+.fi
+.in -20
+.RS 8
+.PP
+.\" \fBAccel\fP is used by all the accelerated X servers (see
+.\" \fIXF86_Accel(1)\fP). \fBMono\fP is used by the non-VGA mono
+.\" drivers in the 2-bit and 4-bit X servers (see \fIXF86_Mono(1)\fP
+.\" and \fIXF86_VGA16(1)\fP). \fBVGA2\fP and \fBVGA16\fP are used by
+.\" the VGA drivers in the 2-bit and 4-bit X servers respectively.
+.\" \fBSVGA\fP is used by the XF86_SVGA X server.
+\fBAccel\fP ¤ÏÁ´¤Æ¤Î¥¢¥¯¥»¥é¥ì¡¼¥¿ X ¥µ¡¼¥Ð¤ÇÍѤ¤¤Þ¤¹
+(\fIXF86_Mono(1)\fP ¤È \fIXF86_VGA16(1)\fP ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤)¡£
+\fBVGA2\fP ¤È \fBVGA16\fP ¤Ï 2-¥Ó¥Ã¥È ¤È 4-¥Ó¥Ã¥È X ¥µ¡¼¥Ð
+¤½¤ì¤¾¤ì¤Î VGA ¥É¥é¥¤¥Ð¡¼¤ÇÍѤ¤¤Þ¤¹¡£\fBSVGA\fP ¤Ï XF86_SVGA X ¥µ¡¼
+¥Ð¡¼¤ÇÍѤ¤¤Þ¤¹¡£
+.RE
+.TP 8
+.B Device \fI"device-id"\fP
+.\" specifies which graphics device description is to be used.
+¤Ï»ÈÍѤ·¤¿¤¤¥Ó¥Ç¥ª¥É¥é¥¤¥Ðµ­½Ò»Ò¤ò»ØÄꤷ¤Þ¤¹¡£
+.TP 8
+.B Monitor \fI"monitor-id"\fP
+.\" specifies which monitor description is to be used.
+¤Ï¥â¥Ë¥¿¡¼µ­½Ò»Ò¤ò»ØÄꤷ¤Þ¤¹¡£
+.TP 8
+.B DefaultColorDepth \fIbpp-number\fP
+.\" specifies which color depth the server should use, when no -bpp command
+.\" line parameter was given.
+¤Ï¥µ¡¼¥Ð¤Ç»ÈÍѤ¹¤ë¥«¥é¡¼¤Î¿¼¤µ¤ò¥³¥Þ¥ó¥É¹Ô¥Ñ¥é¥á¥¿¤Î -bpp ¤Î¿ôÃͤò»ØÄꤷ¤Þ¤¹¡£
+.TP 8
+.B ScreenNo \fIscrnum\fP
+.\" This optional entry overrides the default screen numbering in a
+.\" multi-headed configuration. The default numbering is determined by
+.\" the ordering of the \fBScreen\fP sections in the \fIXF86Config\fP
+.\" file. To override this, all relevant \fBScreen\fP sections must have
+.\" this entry specified.
+¤³¤ÎÄɲùàÌܤÏÊ£¿ô²èÌ̹½À®¤Î¾ì¹ç¤ËÈÖ¹æÉÕ¤±¤¹¤ëɸ½à¤Î¥¹¥¯¥ê¡¼¥ó¤ò
+ÃÖ¤­´¹¤¨¤Þ¤¹¡£\fIXF86Config\fP ¥Õ¥¡¥¤¥ë¤Î \fBScreen\fP Àá¤Î½çÈÖ¤Ç
+ɸ½à¤ÎÈÖ¹æÉÕ¤±¤¬·èÄꤷ¤Þ¤¹¡£¤³¤ì¤òÃÖ¤­´¹¤¨¤ë¤¿¤á¤ËÁ´¤Æ¤Î´ØÏ¢¤¹¤ë
+\fBScreen\fP Àá¤Ë¤³¤Î¹àÌܤò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+.TP 8
+.B BlankTime \fItime\fP
+.\" sets the inactivity timeout for the blanking phase of the screensaver.
+.\" \fItime\fP is in minutes, and the default is 10.
+.\" This is equivalent to the Xserver's `-s' flag, and the value can be
+.\" changed at run-time with \fIxset(1)\fP.
+¤Ï¥¹¥¯¥ê¡¼¥ó¥»¡¼¥Ð¡¼¤Ë¤è¤Ã¤Æ°Å¤¤¾õÂ֤ˤʤë¤Þ¤Ç¤Î»þ´Ö¤òÀßÄꤷ¤Þ¤¹¡£
+\fItime\fP ¤Ïʬñ°Ì¤Ç»ØÄꤷ¡¢É¸½àÃÍ¤Ï 10 ¤Ç¤¹¡£
+¤³¤ì¤Ï X ¥µ¡¼¥Ð¤Ç '-s' ¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤¿¤Î¤ÈÅù²Á¤Ç¡¢¼Â¹Ô»þ¤Ë
+¿ôÃÍ¤Ï \fIxset(1)\fP ¤ÇÊѹ¹½ÐÍè¤Þ¤¹¡£
+.TP 8
+.B SuspendTime \fItime\fP
+.\" sets the inactivity timeout for the ``suspend'' phase of the screensaver.
+.\" \fItime\fP is in minutes, the default is 15, and it can be changed
+.\" at run-time with \fIxset(1)\fP.
+.\" This is only suitable for VESA DPMS compatible monitors, and is only
+.\" supported currently by some Xservers. The "power_saver"
+.\" Option must be set for this to be enabled.
+¤Ï¥¹¥¯¥ê¡¼¥ó¥»¡¼¥Ð¡¼¤Ë¤è¤Ã¤Æ ``suspend'' ¾õÂ֤ˤʤë¤Þ¤Ç¤Î»þ´Ö¤òÀßÄꤷ¤Þ¤¹¡£
+\fItime\fP ¤Ïʬñ°Ì¤Ç»ØÄꤷ¡¢É¸½àÃÍ¤Ï 15 ¤Ç¡¢¼Â¹Ô»þ¤Ë \fIxvidtune(1)\fP
+¤ÇÊѹ¹½ÐÍè¤Þ¤¹¡£ VESA DPMS ¸ß´¹¥â¥Ë¥¿¡¼¤Ë¤Î¤ßŬ¤·¡¢¤¤¤¯¤Ä¤«¤Î X ¥µ¡¼¥Ð
+¤Ç¤Î¤ß¼Â¸½¤·¤Æ¤¤¤Þ¤¹¡£ "power_saver" ¥ª¥×¥·¥ç¥ó¤Ï¥µ¥¹¥Ú¥ó¥É¤¬Í­¸ú¤Ç¤¢¤ë
+ɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+.TP 8
+.B OffTime \fItime\fP
+.\" sets the inactivity timeout for the ``off'' phase of the screensaver.
+.\" \fItime\fP is in minutes, the default is 30, and it can be changed
+.\" at run-time with \fIxset(1)\fP.
+.\" This is only suitable for VESA DPMS compatible monitors, and is only
+.\" supported currently by some Xservers. The "power_saver"
+.\" Option must be set for this to be enabled.
+¤Ï¥¹¥¯¥ê¡¼¥ó¥»¡¼¥Ð¡¼¤Ë¤è¤Ã¤Æ ``off'' ¾õÂ֤ˤʤë¤Þ¤Ç¤Î»þ´Ö¤òÀßÄꤷ¤Þ¤¹¡£
+\fItime\fP ¤Ïʬñ°Ì¤Ç»ØÄꤷ¡¢É¸½àÃÍ¤Ï 30 ¤Ç¡¢¼Â¹Ô»þ¤Ë \fIxvidtune(1)\fP
+¤ÇÊѹ¹½ÐÍè¤Þ¤¹¡£ VESA DPMS ¸ß´¹¥â¥Ë¥¿¡¼¤Ë¤Î¤ßŬ¤·¡¢¤¤¤¯¤Ä¤«¤Î X ¥µ¡¼¥Ð
+¤Ç¤Î¤ß¼Â¸½¤·¤Æ¤¤¤Þ¤¹¡£ "power_saver" ¥ª¥×¥·¥ç¥ó¤Ï¥µ¥¹¥Ú¥ó¥É¤¬Í­¸ú¤Ç¤¢¤ë
+ɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+.TP
+.B SubSection \fB"Display"\fP
+.\" This entry is a subsection which is used to specify some display
+.\" specific parameters. This subsection is terminated by an
+.\" \fBEndSubSection\fP entry. For some X servers and drivers (those
+.\" requiring a list of video modes) this subsection is mandatory.
+.\" For X servers which support multiple display depths, more than one
+.\" \fBDisplay\fP subsection may be present. When multiple \fBDisplay\fP
+.\" subsections are present, each must have a unique \fBDepth\fP entry.
+.\" The entries available for the \fBDisplay\fP subsection are:
+¤³¤Î¹àÌܤϤ¤¤¯¤Ä¤«¤Î¥Ç¥£¥¹¥×¥ì¥¤¤ÎÆÃÀ­Ãͤò»ØÄꤹ¤ëÉûÀá(¥µ¥Ö¥»¥¯¥·¥ç¥ó)
+¤Ç¤¹¡£¤³¤ÎÉûÀá¤Ï \fBEndSubSection\fP ¹àÌܤǽªÎ»¤·¤Þ¤¹¡£¤¤¤¯¤Ä¤«¤Î X
+¥µ¡¼¥Ð¤È¥É¥é¥¤¥Ð(¤³¤ì¤é¤Ï¥Ó¥Ç¥ª¥â¡¼¥É¤Î°ìÍ÷¤ÇɬÍפˤʤê¤Þ¤¹) Âбþ¤Ë
+ɬ¿Ü¤Ç¤¹¡£Ê£¿ô¤Î¥Ç¥£¥¹¥×¥ì¥¤¤Î¿¼¤µ¤ò»È¤¨¤ë X ¥µ¡¼¥Ð¤Ç¤Ï °ì¤Ä°Ê¾å¤Î
+\fBDisplay\fP ÉûÀ᤬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤Ç¤·¤ç¤¦¡£Ê£¿ô¤Î \fBDisplay\fP ÉûÀá
+¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢¤½¤ì¤¾¤ì¤Î \fBDepth\fP ¹àÌܤϽÅÊ£¤·¤Ê¤¤¤è¤¦¤Ë¤¹¤ë
+ɬÍפ¬¤¢¤ê¤Þ¤¹¡£\fBDisplay\fP ÉûÀá¤Ç»ØÄê¤Ç¤­¤ë¹àÌܤϼ¡¤Î¤È¤ª¤ê¤Ç¤¹:
+.RS 8
+.TP 4
+.B Depth \fIbpp\fP
+.\" This entry is mandatory when more than one \fBDisplay\fP subsection
+.\" is present in a \fBScreen\fP section. When only one \fBDisplay\fP
+.\" subsection is present, it specifies the default depth that the X
+.\" server will run at. When more than one \fBDisplay\fP subsection
+.\" is present, the depth determines which gets used by the X server.
+.\" The subsection used is the one matching the depth at which the X
+.\" server is run at. Not all X servers (or drivers) support more than
+.\" one depth. Permitted values for \fIbpp\fP are 8, 15, 16, 24 and 32.
+.\" Not all X servers (or drivers) support all of these values.
+.\" \fIbpp\fP values of 24 and 32 are treated equivalently by those X
+.\" servers which support them.
+¤³¤Î¹àÌܤϣ±¤Ä¤è¤ê¿¤¯¤Î \fBDisplay\fP ÉûÀ᤬ \fBScreen\fP Àá¤ËÄêµÁ¤µ
+¤ì¤Æ¤¤¤ë¾ì¹ç¤Ëɬ¿Ü¤Ç¤¹¡£\fBDisplay\fP ÉûÀ᤬£±¤Ä¤À¤±¤Î¾ì¹ç¤Ï¡¢
+X ¥µ¡¼¥Ð¼Â¹Ô»þ¤Î¿¼¤µ¤Îɸ½àÃͤò»ØÄꤷ¤Þ¤¹¡£
+£±¤Ä¤è¤ê¿¤¯¤Î \fBDisplay\fP ÉûÀ᤬ ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢X ¥µ¡¼¥Ð
+¤¬»ÈÍѤ¹¤ë¿¼¤µ¤ò·èÄꤷ¤Þ¤¹¡£X ¥µ¡¼¥Ð¼Â¹Ô»þ¤Ë°ìÃפ¹¤ë¿¼¤µ¤òÉûÀá¤Ë
+ÄêµÁ¤·¤Þ¤¹¡£ËؤɤΠX ¥µ¡¼¥Ð(¼ã¤¯¤Ï¥É¥é¥¤¥Ð) ¤ÏÊ£¿ô¤Î¿¼¤µ¤ò¥µ¥Ý¡¼
+¥È¤·¤Æ¤¤¤Þ¤¹¡£\fIbpp\fP ¤Ç»ØÄê¤Ç¤­¤ë¿ôÃÍ¤Ï 8, 15, 16, 24 ¤È 32 ¤Ç
+¤¹¡£Á´¤Æ¤Î¥µ¡¼¥Ð(¼ã¤¯¤Ï¥É¥é¥¤¥Ð) ¤¬Á´¤Æ¤Î¿ôÃͤò¥µ¥Ý¡¼¥È¤·¤Æ¤Ï
+¤¤¤Þ¤»¤ó¡£\fIbpp\fP ¤Î¿ôÃͤ¬ 24 ¤È 32 ¤Î¾ì¹ç¡¢ X ¥µ¡¼¥Ð¤¬¤½¤ì¤ò
+¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¾ì¹ç¤ÏƱÅù¤Ë¼è¤ê°·¤ï¤ì¤Þ¤¹¡£
+.TP 4
+.B Weight \fIRGB\fP
+.\" This optional entry specifies the relative RGB weighting to be used
+.\" for an X server running at 16bpp. This may also be specified from
+.\" the command line (see \fIXFree86(1)\fP). Values supported by most
+.\" 16bpp X servers are \fB555\fP and \fB565\fP. For further details,
+.\" refer to the appropriate X server manual page.
+¤³¤ÎÄɲùàÌÜ¤Ï X ¥µ¡¼¥Ð¤¬ 16bpp ¤Ç¼Â¹Ô¤·¤Æ¤¤¤ë¾ì¹ç¤ËÁêÂÐŪ¤Ê RGB
+¤Î½Å¤ßÉÕ¤±¤ò»ØÄꤷ¤Þ¤¹¡£¤³¤Î½Å¤ßÉÕ¤±¤Ï¥³¥Þ¥ó¥É¹Ô¤«¤é¤â»ØÄê¤Ç¤­¤Þ¤¹(
+\fIXFree86(1)\fP ¤ò»²¾È¤Î¤³¤È)¡£ËؤɤΠ16bpp X ¥µ¡¼¥Ð¤Ï \fB555\fP
+¤È \fB565\fP ¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£¤µ¤é¤Ê¤ë¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï¡¢³ºÅö¤¹¤ë
+X ¥µ¡¼¥Ð¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+.TP 4
+.B Virtual \fIxdim ydim\fP
+.\" This optional entry specifies the virtual screen resolution to be
+.\" used. \fIxdim\fP must be a multiple of either 8 or 16 for most
+.\" colour X servers, and a multiple of 32 for the monochrome X server.
+.\" The given value will be rounded down if this is not the case. For
+.\" most X servers, video modes which are too large for the specified
+.\" virtual size will be rejected. If this entry is not present, the
+.\" virtual screen resolution will be set to accommodate all the valid
+.\" video modes given in the \fBModes\fP entry. Some X servers do not
+.\" support this entry. Refer to the appropriate X server manual pages
+.\" for details.
+¤³¤ÎÄɲùàÌܤϻÈÍѤ¹¤ë²¾ÁÛ²èÌ̤βòÁüÅÙ¤ò»ØÄꤷ¤Þ¤¹¡£ËؤɤΥ«¥é¡¼
+¤Î X ¥µ¡¼¥Ð¤Ç¤Ï \fIxdim\fP ¤Ï 8 ¤« 16 ¤ÎÇÜ¿ô¤Î¿§¿ô¤Ç¡¢¥â¥Î¥¯¥í¤Î
+X ¥µ¡¼¥Ð¤Ç¤Ï 32 ¤ÎÇÜ¿ô¤Ç¤¢¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤È°Û¤Ê¤ë¾ì¹ç¤Ï¡¢
+Í¿¤¨¤é¤ì¤¿¿ôÃͤò¾®¤µ¤¤¤Û¤¦¤Î¿ôÃͤ˴ݤá¤Þ¤¹¡£ËؤɤΠX ¥µ¡¼¥Ð¤Ç¤Ï¡¢
+»ØÄꤵ¤ì¤¿²¾ÁÛ²èÌ̤ÎÂ礭¤µ¤¬Â礭¤¹¤®¤ë¥Ó¥Ç¥ª¥â¡¼¥É¤ÏµñÈݤµ¤ì¤Þ¤¹¡£
+²¾ÁÛ²èÌ̤ÎÀßÄ꤬¤Ê¤¤¾ì¹ç¡¢²¾ÁÛ²èÌ̤βòÁüÅÙ¤Ï \fBModes\fP ¹àÌܤÇÍ¿¤¨
+¤é¤ì¤¿Å¬Àµ¤ÊÁ´¤Æ¤Î¥Ó¥Ç¥ª¥â¡¼¥É¤«¤éÄ´À°¤·¤ÆÀßÄꤷ¤Þ¤¹¡£¤¤¤¯¤Ä¤«¤Î X
+¥µ¡¼¥Ð¤Ç¤Ï¤³¤Î¹àÌܤϥµ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï¡¢³ºÅö¤¹¤ë
+X ¥µ¡¼¥Ð¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+.TP 4
+.B ViewPort \fIx0 y0\fP
+.\" This optional entry sets the upper left corner of the initial
+.\" display. This is only relevant when the virtual screen resolution
+.\" is different from the resolution of the initial video mode. If
+.\" this entry is not given, then the initial display will be centered
+.\" in the virtual display area.
+¤³¤ÎÄɲùàÌܤϽé´ü²èÌ̤κ¸¾å¶ù¤òÀßÄꤷ¤Þ¤¹¡£²¾ÁÛ²èÌ̤βòÁüÅÙ¤¬ºÇ½é
+¤Î¥Ó¥Ç¥ª¥â¡¼¥É¤Î²òÁüÅ٤Ȱۤʤë¾ì¹ç¤À¤±´ØÏ¢¤¬¤¢¤ê¤Þ¤¹¡£¤³¤Î¹àÌܤ¬
+¤Ê¤¤¾ì¹ç¡¢½é´ü²èÌ̤ϲ¾ÁÛ²èÌÌÎΰè¤ÎÃæ±û¤Ë¤Ê¤ê¤Þ¤¹¡£
+.TP 4
+.B Modes \fI"modename" ...\fP
+.\" This entry is mandatory for most X servers, and it specifies the
+.\" list of video modes to use. The video mode names must correspond
+.\" to those specified in the appropriate \fBMonitor\fP section. Most
+.\" X servers will delete modes from this list which don't satisfy
+.\" various requirements. The first valid mode in this list will be
+.\" the default display mode for startup. The list of valid modes is
+.\" converted internally into a circular list. It is possible to switch
+.\" to the next mode with \fBCtrl+Alt+Keypad-Plus\fP and to the previous
+.\" mode with \fBCtrl+Alt+Keypad-Minus\fP.
+¤³¤Î¹àÌܤÏËØ¤É¤Î X ¥µ¡¼¥Ð¤Ëɬ¿Ü¤Ç¡¢»ÈÍѤ¹¤ë¥Ó¥Ç¥ª¥â¡¼¥É¤Î¥ê¥¹¥È
+¤ò»ØÄꤷ¤Þ¤¹¡£¥Ó¥Ç¥ª¥â¡¼¥É̾¾Î¤ÏŬÀÚ¤Ê \fBMonitor\fP ÀáÆâ¤Ç»ØÄꤷ¤¿
+̾¾Î¤È°ìÃפ·¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£ËؤɤΠX ¥µ¡¼¥Ð¤Ç¤Ï¼ï¡¹¤ÎÍ×µá¤òËþ
+¤¿¤¹¤³¤È¤¬½ÐÍè¤Ê¤¤¤è¤¦¤Ê¥â¡¼¥É¤Ï¤³¤Î¥ê¥¹¥È¤«¤é¾Ãµî¤¹¤ë¤Ç¤·¤ç¤¦¡£
+¤³¤Î¥ê¥¹¥È¤Î¤Ê¤«¤ÇºÇ½é¤ËÍ­¸ú¤Ë¤Ê¤ë¥â¡¼¥É¤Ïµ¯Æ°»þ¤Îɸ½à¤Îɽ¼¨¥â¡¼¥É
+¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£Í­¸ú¤Ê¥â¡¼¥É¤Î¥ê¥¹¥È¤Ï½Û´Ä¥ê¥¹¥È¤ËÆâÉôŪ¤ËÊÑ´¹¤µ¤ì
+¤Þ¤¹¡£½Û´Ä¥ê¥¹¥ÈÆâ¤Î¥â¡¼¥É¤Ï \fBCtrl+Alt+Keypad-Plus\fP ¤Ç¼¡¤Î¥â¡¼
+¥É¡¢\fBCtrl+Alt+Keypad-Minus\fP ¤ÇÁ°¤Î¥â¡¼¥É¤ËÀÚ¤êÂØ¤¨¤ë¤³¤È¤¬²Äǽ
+¤Ç¤¹¡£[ÌõÃí¡§Keypad-Plus ¤Ï¥Æ¥ó¥­¡¼¤Î¡Ü¥­¡¼¡¢Keypad-Minus ¤Ï¥Æ¥ó
+¥­¡¼¤Î¡Ý¥­¡¼¤ò°ÕÌ£¤·¤Þ¤¹¡£]
+.TP 4
+.B InvertVCLK \fI"modename"\fP \fR0|1\fP
+.\" This optional entry is specific to the S3 server only. It may be used
+.\" to change the default VCLK invert/non-invert state for individual modes.
+.\" If \fI"modename"\fP is "\(**" the setting applies to all modes unless
+.\" unless overridden by later entries.
+¤³¤ÎÄɲùàÌÜ¤Ï S3 ¥µ¡¼¥Ð¤Î¤ß¤Ç»ØÄꤷ¤Þ¤¹¡£¤³¤Î¹àÌܤÏɸ½à¤Î¸Ä¡¹¤Î¥â¡¼¥É
+Ëè¤Î VCLK ¤Îȿž¡¿Èóȿž¾õÂÖ¤òÊѹ¹¤·¤Þ¤¹¡£
+\fI"modename"\fP ¤¬ "\(**" ¤Ç¤Ï¤¸¤Þ¤ë¾ì¹ç¤Ï¡¢¤³¤Î¸å¤Ë»ØÄꤹ¤ëÀßÄê¹àÌܤÇ
+¾å½ñ¤­¤µ¤ì¤Ê¤¤¸Â¤ê¡¢Á´¤Æ¤Î¥â¡¼¥É¤Ë¤½¤Î¥â¡¼¥É¤ÎÀßÄêÃͤ¬Å¬±þ¤µ¤ì¤Þ¤¹¡£
+.TP 4
+.B EarlySC \fI"modename"\fP \fR0|1\fP
+.\" This optional entry is specific to the S3 server only. It may be used
+.\" to change the default EarlySC setting for individual modes. This
+.\" setting can affect screen wrapping.
+.\" If \fI"modename"\fP is "\(**" the setting applies to all modes unless
+.\" unless overridden by later entries.
+¤³¤ÎÄɲùàÌÜ¤Ï S3 ¥µ¡¼¥Ð¤Î¤ß¤Ç»ØÄꤷ¤Þ¤¹¡£¤³¤Î¹àÌܤÏɸ½à¤Î¤½¤ì¤¾¤ì¤Î¥â¡¼¥É
+Ëè¤Î EarlySC ¤ÎÀßÄê¤òÊѹ¹¤·¤Þ¤¹¡£
+\fI"modename"\fP ¤¬ "\(**" ¤Ç¤Ï¤¸¤Þ¤ë¾ì¹ç¤Ï¡¢¤³¤Î¸å¤Ë»ØÄꤹ¤ëÀßÄê¹àÌܤÇ
+¾å½ñ¤­¤µ¤ì¤Ê¤¤¸Â¤ê¡¢Á´¤Æ¤Î¥â¡¼¥É¤Ë¤½¤Î¥â¡¼¥É¤ÎÀßÄêÃͤ¬Å¬±þ¤µ¤ì¤Þ¤¹¡£
+.TP 4
+.B BlankDelay \fI"modename" value1 value2\fP
+.\" This optional entry is specific to the S3 server only. It may be used
+.\" to change the default blank delay settings for individual modes. This
+.\" can affect screen wrapping. \fIvalue1\fP and \fIvalue2\fP must be
+.\" integers in the range 0\-7.
+.\" If \fI"modename"\fP is "\(**" the setting applies to all modes unless
+.\" unless overridden by later entries.
+¤³¤ÎÄɲùàÌÜ¤Ï S3 ¥µ¡¼¥Ð¤Î¤ß¤Ç»ØÄꤷ¤Þ¤¹¡£¤³¤Î¹àÌܤÏɸ½à¤Î¤½¤ì¤¾¤ì¤Î¥â¡¼¥É
+Ëè¤Î¶õÇòÃÙ±ä»þ´Ö¤ÎÀßÄê¤òÊѹ¹¤·¤Þ¤¹¡£¤½¤ÎÀßÄê¤Ï²èÌ̤βö¤ê¹þ¤ß¸½¾Ý¤ËºîÍѤ·
+¤Þ¤¹¡£ \fIvalue1\fP ¤È \fIvalue2\fP ¤Î¿ôÃÍ¤Ï 0\-7 ¤ÎÈϰϤÎÀ°¿ô¤ÇÍ¿¤¨¤ë
+ɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+\fI"modename"\fP ¤¬ "\(**" ¤Ç¤Ï¤¸¤Þ¤ë¾ì¹ç¤Ï¡¢¤³¤Î¸å¤Ë»ØÄꤹ¤ëÀßÄê¹àÌܤÇ
+¾å½ñ¤­¤µ¤ì¤Ê¤¤¸Â¤ê¡¢Á´¤Æ¤Î¥â¡¼¥É¤Ë¤½¤Î¥â¡¼¥É¤ÎÀßÄêÃͤ¬Å¬±þ¤µ¤ì¤Þ¤¹¡£
+.TP 4
+.B Visual \fI"visual-name"\fP
+.\" This optional entry sets the default root visual type. This may
+.\" also be specified from the command line (see \fIXserver(1)\fP).
+.\" The visual types available for 8bpp X servers are (default is
+.\" \fBPseudoColor\fP):
+¤³¤ÎÄɲùàÌܤÏɸ½à¤Î¥ë¡¼¥È¥¦¥£¥ó¥É¥¦¤Îɽ¼¨·Á¼°¤òÀßÄꤷ¤Þ¤¹¡£¤³¤Î¹àÌܤÏ
+¥³¥Þ¥ó¥É¥é¥¤¥ó¤«¤é¤â»ØÄê¤Ç¤­¤Þ¤¹( \fIXserver(1)\fP ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤)¡£
+8bpp ¤Î X ¥µ¡¼¥Ð¤Ç»ÈÍѲÄǽ¤Êɽ¼¨·Á¼°¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹(ɸ½à¤Ç¤Ï
+\fBPseudoColor\fP ¤Ç¤¹):
+.RE
+.sp
+.in 20
+.nf
+.B StaticGray
+.B GrayScale
+.B StaticColor
+.B PseudoColor
+.B TrueColor
+.B DirectColor
+.fi
+.in -20
+.RS 12
+.PP
+.\" The visual type available for the 16bpp and 32bpp X servers is
+.\" \fBTrueColor\fP.
+16bpp ¤È 32bpp ¤Î X ¥µ¡¼¥Ð¤Ç»ÈÍѲÄǽ¤Êɽ¼¨·Á¼°¤Ï \fBTrueColor\fP ¤Ç¤¹¡£
+.PP
+.\" The visual type available for the 1bpp X server is \fBStaticGray\fP.
+1bpp ¤Î X ¥µ¡¼¥Ð¤Ç»ÈÍѲÄǽ¤Êɽ¼¨·Á¼°¤Ï \fBStaticGray\fP ¤Ç¤¹¡£
+.PP
+.\" The visual types available for the 4bpp X server are (default is
+.\" \fBPseudoColor\fP):
+4bpp ¤Î X ¥µ¡¼¥Ð¤Ç»ÈÍѲÄǽ¤Êɽ¼¨·Á¼°¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹(ɸ½à¤Ç¤Ï
+\fBPseudoColor\fP ¤Ç¤¹):
+.RE
+.sp
+.in 20
+.nf
+.B StaticGray
+.B GrayScale
+.B StaticColor
+.B PseudoColor
+.fi
+.in -20
+.RS 8
+.TP 4
+.B Option \fI"optionstring"\fP
+.\" This optional entry allows the user to select certain options
+.\" provided by the drivers. Multiple \fBOption\fP entries may be
+.\" given. The supported values for \fIoptionstring\fP are given in
+.\" the appropriate X server manual pages.
+¤³¤ÎÄɲùàÌܤϥɥ饤¥Ð¤ÎÄ󶡤¹¤ë°ìÄê¤ÎÁªÂò¹àÌܤò»ØÄꤷ¤Þ¤¹¡£
+Ê£¿ô¤Î \fBOption\fP ¹àÌܤ¬»ØÄê¤Ç¤­¤Þ¤¹¡£ \fIoptionstring\fP ¤Ç
+»ÈÍѤǤ­¤ëʸ»úÎó¤Ï³ºÅö¤¹¤ë X ¥µ¡¼¥Ð¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È
+¤·¤Æ¤¯¤À¤µ¤¤¡£
+.TP 4
+.B Black \fIred green blue\fP
+.\" This optional entry allows the ``black'' colour to be specified. This
+.\" is only supported with the VGA2 driver in the XF86_Mono server (for
+.\" details see \fIXF86_Mono(1)\fP).
+¤³¤ÎÄɲùàÌÜ¤Ï ``¹õ'' ¿§¤òÄêµÁ¤·¤Þ¤¹¡£¤³¤ÎÄêµÁ¤Ï XF86_Mono ¥µ¡¼¥Ð
+¤Î VGA2 ¥É¥é¥¤¥Ð¤Î¤ß¤Ç»ØÄê¤Ç¤­¤Þ¤¹(¾ÜºÙ¤Ï \fIXF86_Mono(1)\fP ¤ò»²¾È
+¤·¤Æ¤¯¤À¤µ¤¤)¡£
+.TP 4
+.B White \fIred green blue\fP
+.\" This optional entry allows the ``white'' colour to be specified. This
+.\" is only supported with the VGA2 driver in the XF86_Mono server (for
+.\" details see \fIXF86_Mono(1)\fP).
+¤³¤ÎÄɲùàÌÜ¤Ï ``Çò'' ¿§¤òÄêµÁ¤·¤Þ¤¹¡£¤³¤ÎÄêµÁ¤Ï XF86_Mono ¥µ¡¼¥Ð
+¤Î VGA2 ¥É¥é¥¤¥Ð¤Î¤ß¤Ç»ØÄê¤Ç¤­¤Þ¤¹(¾ÜºÙ¤Ï \fIXF86_Mono(1)\fP ¤ò»²¾È
+¤·¤Æ¤¯¤À¤µ¤¤)¡£
+.RE
+.PP
+.\" The optional \fBXInput\fP section is used to specify configuration options
+.\" for the extended input devices. For some OSs, the extended device support is
+.\" dynamically loaded, and in this case you need to specify which Modules to
+.\" load in the \fBModule\fP section (this is documented above).
+.\" Each extended device has its own
+.\" subsection. To enable an extended device the corresponding subsection
+.\" must appear. The subsections names are:
+Ǥ°Õ¤Î \fBXInput\fP Àá¤Ï³ÈÄ¥ÆþÎϵ¡´ï¤Î¹½À®¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Þ¤¹¡£
+¤¤¤¯¤Ä¤«¤Î OS ¤Ç¤Ï \fBModule\fP Àá¤Ë¤¢¤ë³ÈÄ¥¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤ÏưŪ¥í¡¼¥É¤ò
+¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹(¤³¤ì¤Ï¾åµ­¤Ç½Ò¤Ù¤Þ¤·¤¿)¡£
+.sp
+.in 8
+.nf
+.\" \fBJoystick\fP (only on supported systems ie. Linux, FreeBSD and NetBSD)
+.\" \fBWacomStylus\fP (stylus of a Wacom tablet)
+.\" \fBWacomEraser\fP (eraser of a Wacom tablet)
+.\" \fBWacomCursor\fP (cursor of a Wacom tablet)
+.\" \fBElographics\fP (Elographics touchscreen)
+.\" \fBSummaSketch\fP (SummaSketch tablet)
+.\" \fBMouse\fP (Mouse)
+\fBJoystick\fP (¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¥·¥¹¥Æ¥à¤ÏÎ㤨¤Ð Linux, FreeBSD ¤È NetBSD ¤Î¤ß)
+\fBWacomStylus\fP (Wacom ¥¿¥Ö¥ì¥Ã¥È¤Î¥¹¥¿¥¤¥é¥¹¥Ú¥ó)
+\fBWacomEraser\fP (Wacom ¥¿¥Ö¥ì¥Ã¥È¤Î¥¤¥ì¡¼¥µ)
+\fBWacomCursor\fP (Wacom ¥¿¥Ö¥ì¥Ã¥È¤Î¥«¡¼¥½¥ë)
+\fBElographics\fP (Elographics ¤Î¥¿¥Ã¥Á¥¹¥¯¥ê¡¼¥ó)
+\fBSummaSketch\fP (SummaSketch ¥¿¥Ö¥ì¥Ã¥È)
+\fBMouse\fP (Mouse)
+.fi
+.TP
+.\" The \fBJoystick\fP subsection supports the following entries:
+\fBJoystick\fP ÉûÀá ¤Ç¤Ï¼¡¤Î¹àÌܤ¬»ØÄê¤Ç¤­¤Þ¤¹:
+.RS 8
+.TP 4
+.B Port \fI"path"\fP
+.\" sets the path to the special file which represents the device driver.
+¤Ï¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤ò°ÕÌ£¤¹¤ë¥¹¥Ú¥·¥ã¥ë¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤òÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B DeviceName \fI"name"\fP
+.\" sets the name of the X device.
+¥Ç¥Ð¥¤¥¹¤Î̾¾Î(name)¤òÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B TimeOut \fItimeout\fP
+.\" sets the time (in milliseconds) between two polls of the device driver.
+.\" The value given here may be overriden by the Operating System's joystick
+.\" driver.
+¤Ï¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤«¤é¤Î 2 ¤Ä¤Î¥Ñ¥ë¥¹¤Î´Ö³Ö¤ò(¥ß¥êÉäÇ)»þ´Ö¤òÀßÄꤷ¤Þ¤¹¡£
+¤³¤³¤ÇÍ¿¤¨¤¿¿ôÃͤϥª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Î¥¸¥ç¥¤¥¹¥Æ¥£¥Ã¥¯¤Î¥Ç¥Ð¥¤¥¹
+¥É¥é¥¤¥Ð¤Ç¾å½ñ¤­¤·¤Æ¤·¤Þ¤¦¤«¤â¤·¤ì¤Þ¤»¤ó¡£
+.TP 4
+.B MaximumXPosition \fIvalue\fP
+.\" sets the maximum X value reported by the device driver.
+¤Ï¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤¬Êó¹ð¤¹¤ë X ºÂɸ¤ÎºÇÂçÃͤòÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B MininimumXPosition \fIvalue\fP
+.\" sets the minimum X value reported by the device driver.
+¤Ï¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤¬Êó¹ð¤¹¤ë X ºÂɸ¤ÎºÇ¾®ÃͤòÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B MaximumYPosition \fIvalue\fP
+.\" sets the maximum Y value reported by the device driver.
+¤Ï¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤¬Êó¹ð¤¹¤ë Y ºÂɸ¤ÎºÇÂçÃͤòÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B MinimumYPosition \fIvalue\fP
+.\" sets the minimum Y value reported by the device driver.
+¤Ï¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤¬Êó¹ð¤¹¤ë Y ºÂɸ¤ÎºÇ¾®ÃͤòÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B CenterX \fIvalue\fP
+.\" sets the X center reported by the device driver when the joystick
+.\" is idle. If this value is omitted, it is assumed that the joystick
+.\" is centered when it is first enabled.
+¥¸¥ç¥¤¥¹¥Æ¥£¥Ã¥¯¤¬¥¢¥¤¥É¥ë¤Î°ÌÃ֤ˤ¢¤ë¤È¤­¤Ë¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤¬Êó¹ð¤¹¤ë
+X ºÂɸ¤ÎÃæ¿´¤òÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B CenterY \fIvalue\fP
+.\" sets the Y center reported by the device driver when the joystick
+.\" is idle. If this value is omitted, it is assumed that the joystick
+.\" is centered when it is first enabled.
+¥¸¥ç¥¤¥¹¥Æ¥£¥Ã¥¯¤¬¥¢¥¤¥É¥ë¤Î°ÌÃ֤ˤ¢¤ë¤È¤­¤Ë¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤¬Êó¹ð¤¹¤ë
+Y ºÂɸ¤ÎÃæ¿´¤òÀßÄꤷ¤Þ¤¹¡£¤³¤Î¿ôÃͤ¬¾Êά¤µ¤ì¤Æ¤¤¤ë¤ÈºÇ½é¤ËÍ­¸ú¤Ë¤Ê¤Ã¤¿
+»þ¤Î¥¸¥ç¥¤¥¹¥Æ¥£¥Ã¥¯¤Î°ÌÃÖ¤òÃæ¿´¤È¤·¤Þ¤¹¡£
+.TP 4
+.B Delta \fIvalue\fP
+.\" sets the maximum value reported to the X server. i.e. coordinates will
+.\" be incremented of \fI(+/\-)value/2\fP at maximum deflection. This determines
+.\" the sensitivity.
+¤Ï X ¥µ¡¼¥Ð¤¬Êó¹ð¤¹¤ëºÇÂç¤Î¿ôÃͤòÀßÄꤷ¤Þ¤¹¡£Î㤨¤ÐºÂɸ¤Ç¤Ï¤¤¤Ã¤Ñ¤¤¤Ë¶Ê¤²¤¿
+»þ¤Î¿ôÃͤò \fI(+/\-)value/2\fP ¤È¤·¤ÆÁýʬÃͤÇÀßÄꤷ¤Þ¤¹¡£´¶³Ð¤Ç·èÄꤷ¤Æ
+¤¯¤À¤µ¤¤¡£
+.RE
+.TP
+.\" The \fBWacomStylus\fP, \fBWacomEraser\fP and \fBWacomCursor\fP subsections
+.\" support the following entries:
+\fBWacomStylus\fP, \fBWacomEraser\fP ¤È \fBWacomCursor\fP ÉûÀá¤Ç¤Ï
+¤Ç¤Ï¼¡¤Î¹àÌܤ¬»ØÄê¤Ç¤­¤Þ¤¹:
+.RS 8
+.TP 4
+.B Port \fI"path"\fP
+.\" sets the path to the special file which represents serial line where
+.\" the tablet is plugged. You have to specify it for each subsection with
+.\" the same value if you want to have multiple devices with the same tablet.
+¤Ï¥¿¥Ö¥ì¥Ã¥È¤¬Àܳ¤µ¤ì¤Æ¤¤¤ë¥·¥ê¥¢¥ë¥Ý¡¼¥È¤Î¥¹¥Ú¥·¥ã¥ë¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤ò
+ÀßÄꤷ¤Þ¤¹¡£Æ±¤¸¥¿¥Ö¥ì¥Ã¥È¤ÇÊ£¿ô¤Î¥Ç¥Ð¥¤¥¹¤ò»È¤¤¤¿¤¤¾ì¹ç¤Ï
+¤½¤ì¤¾¤ì¤ÎÉûÀá¤Ë¤³¤Î¥¹¥Ú¥·¥ã¥ë¥Õ¥¡¥¤¥ë¤òÀßÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+.TP 4
+.B DeviceName \fI"name"\fP
+.\" sets the name of the X device.
+¤Ï¥Ç¥Ð¥¤¥¹¤Î̾¾Î(name)¤òÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B Suppress \fInumber\fP
+.\" sets the position increment under which not to transmit coordinates.
+.\" This entry must be specified only in the first Wacom subsection if you have
+.\" multiple devices for one tablet.
+¤Ï¥¿¥Ö¥ì¥Ã¥È¤¬ºÂɸ¤òžÁ÷¤·¤Ê¤¤¾õÂ֤ΰÌÃÖ¤ÎÁýʬÎ̤òÀßÄꤷ¤Þ¤¹¡£
+¤³¤Î¹àÌܤϰì¤Ä¤Î¥¿¥Ö¥ì¥Ã¥È¤ËÊ£¿ô¤Î¥Ç¥Ð¥¤¥¹¤¬ÉÕ¤¤¤Æ¤¤¤ë¾ì¹ç¡¢
+ºÇ½é¤Î Wacom ÉûÀá¤Ë¤Î¤ßÀßÄꤷ¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£
+.TP 4
+.B Mode \fIRelative|Absolute\fP
+.\" sets the mode of the device.
+¤Ï¥Ç¥Ð¥¤¥¹¤Î¥â¡¼¥É(ÁêÂаÌÃ֥⡼¥É|ÀäÂаÌÃ֥⡼¥É)¤òÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B TiltMode
+.\" enables tilt report if your tablet supports it (ROM version 1.4 and above).
+.\" If this is enabled, multiple devices at the same time will not be reported.
+¤Ï¤â¤·¥Á¥ë¥È¾ðÊó¤ò¥¿¥Ö¥ì¥Ã¥È¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¤È¤­(ROM ¤Î¥Ð¡¼¥¸¥ç¥ó¤¬ 1.4
+°Ê¾å¤Î¾ì¹ç) ¥Á¥ë¥È¾ðÊó¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£
+.TP 4
+.B HistorySize \fInumber\fP
+.\" sets the motion history size. By default the value is zero.
+¿åÊ¿Êý¸þ¤Îư¤­¤ÎÂ礭¤µ¤òÀßÄꤷ¤Þ¤¹¡£É¸½àÃÍ¤Ï 0 ¤Ç¤¹¡£
+.RE
+.TP
+.\" The \fBElographics\fP subsection support the following entries:
+\fBElographics\fP ÉûÀá¤Ç¤Ï¼¡¤Î¹àÌܤ¬»ØÄê¤Ç¤­¤Þ¤¹:
+.RS 8
+.TP 4
+.B Port \fI"path"\fP
+.\" sets the path to the special file which represents the device driver.
+¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤ò°ÕÌ£¤¹¤ë¥¹¥Ú¥·¥ã¥ë¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤òÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B DeviceName \fI"name"\fP
+.\" sets the name of the X device.
+¤Ï¥Ç¥Ð¥¤¥¹¤Î̾¾Î(name)¤òÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B MaximumXPosition \fIposition\fP
+.\" sets the maximum X position reported by the touchscreen.
+¤Ï¥¿¥Ã¥Á¥¹¥¯¥ê¡¼¥ó¤ÎÊó¹ð¤¹¤ë X ºÂɸ¤ÎºÇÂçÃͤòÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B MinimumXPosition \fIposition\fP
+.\" sets the minimum X position reported by the touchscreen.
+¤Ï¥¿¥Ã¥Á¥¹¥¯¥ê¡¼¥ó¤ÎÊó¹ð¤¹¤ë X ºÂɸ¤ÎºÇ¾®ÃͤòÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B MaximumYPosition \fIposition\fP
+¤Ï¥¿¥Ã¥Á¥¹¥¯¥ê¡¼¥ó¤ÎÊó¹ð¤¹¤ë Y ºÂɸ¤ÎºÇÂçÃͤòÀßÄꤷ¤Þ¤¹¡£
+.\" sets the maximum Y position reported by the touchscreen.
+.TP 4
+.B MinimumYPosition \fIposition\fP
+.\" sets the minimum Y position reported by the touchscreen.
+¤Ï¥¿¥Ã¥Á¥¹¥¯¥ê¡¼¥ó¤ÎÊó¹ð¤¹¤ë Y ºÂɸ¤ÎºÇ¾®ÃͤòÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B ScreenNo \fInumber\fP
+.\" sets the screen number where the touchscreen is connected.
+¤Ï¥¿¥Ã¥Á¥¹¥¯¥ê¡¼¥ó¤òÀܳ¤·¤¿¤È¤­¤Î²èÌÌÈÖ¹æ¤òÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B UntouchDelay \fIvalue\fP
+.\" sets the delay (in tens of milliseconds) after which the device
+.\" considers that an untouch occurs.
+¤Ï²èÌ̤«¤éÊü¤ì¤¿(untouch) ¤È¥Ç¥Ð¥¤¥¹¤¬¤ß¤Ê¤¹¤Þ¤Ç¤ÎÃÙ¤ì»þ´Ö¤ò
+(10 ¤ÎÇÜ¿ô¤Î¥ß¥êÉÃñ°Ì¤Ç)ÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B ReportDelay \fIvalue\fP
+.\" sets the delay (in ten of milliseconds) between two reports
+.\" of positions.
+2 ²Õ½ê¤Î°ÌÃ֤δ֤ÎÃÙ¤ì»þ´Ö¤ò(¥ß¥êÉÃñ°Ì¤Ç)ÀßÄꤷ¤Þ¤¹¡£
+.RE
+.TP
+.\" The \fBSummaSketch\fP subsection support the following entries:
+\fBSummaSketch\fP ÉûÀá¤Ç¤Ï¼¡¤Î¹àÌܤ¬»ØÄê¤Ç¤­¤Þ¤¹:
+.RS 8
+.TP 4
+.B Port \fI"path"\fP
+.\" sets the path to the special file which represents the device driver.
+¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤ò°ÕÌ£¤¹¤ë¥¹¥Ú¥·¥ã¥ë¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤òÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B DeviceName \fI"name"\fP
+.\" sets the name of the X device.
+¤Ï¥Ç¥Ð¥¤¥¹¤Î̾¾Î(name)¤òÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B Mode \fIRelative|Absolute\fP
+.\" sets the mode of the device.
+¤Ï¥Ç¥Ð¥¤¥¹¤Î¥â¡¼¥É(ÁêÂаÌÃ֥⡼¥É|ÀäÂаÌÃ֥⡼¥É)¤òÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B Cursor \fIStylus|Puck\fP
+.\" sets the cursor type, stylus or 4 button puck.
+¤Ï¥¹¥¿¥¤¥é¥¹¥Ú¥ó¤« 4 ¥Ü¥¿¥ó¥Ñ¥Ã¥¯¤Ê¤Î¤«¡¢¥«¡¼¥½¥ë¤Î·Á¼°¤òÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B Increment \fIvalue\fP
+.\" sets the maximum change in coordinates before new report.
+¤Ï¿·¤·¤¤Êó¹ð¤ò¼õ¤±¤ëÁ°¤ËºÂɸ¤ÎºÇÂçÊѲ½Î̤òÀßÄꤷ¤Þ¤¹¡£
+.TP 4
+.B HistorySize \fInumber\fP
+.\" sets the motion history size. By default the value is zero.
+¤ÏÁàºîÍúÎò¤ÎÂ礭¤µ¤òÀßÄꤷ¤Þ¤¹¡£É¸½àÃÍ¤Ï 0 ¤Ç¤¹¡£
+.RE
+.TP
+.\" The \fBMouse\fP subsection support the same entries as the
+.\" standard \fBPointer\fP section, plus the following:
+\fBMouse\fP ÉûÀá¤Ïɸ½à¤Î \fBPointer\fP Àá¤ÈƱ¤¸¤Ç¤¹¡£
+¤½¤ì¤ËÉÕ¤±²Ã¤¨¤Æ¼¡¤Î¹àÌܤ¬»ØÄê¤Ç¤­¤Þ¤¹:
+.RS 8
+.TP 4
+.B DeviceName \fI"name"\fP
+.\" sets the name of the X device.
+¤Ï¥Ç¥Ð¥¤¥¹¤Î̾¾Î(name)¤òÀßÄꤷ¤Þ¤¹¡£
+.RE
+.PP
+.\" For an example of an XF86Config file, see the file installed as
+.\" <XRoot>/lib/X11/XF86Config.eg.
+XF86Config ¥Õ¥¡¥¤¥ë¤ÎÎãÂê¤Ï<XRoot>/lib/X11/XF86Config.eg ¤Ë¤¢¤ê¤Þ¤¹¡£
+.\" .SH FILES
+.SH ¥Õ¥¡¥¤¥ë
+.PP
+.nf
+/etc/XF86Config
+<XRoot>/lib/X11/XF86Config.\fIhostname\fP
+<XRoot>/lib/X11/XF86Config
+.sp 1
+.\" Note: <XRoot> refers to the root of the X11 install tree.
+Ãí°Õ: <XRoot> ¤Ï X11 ¤òƳÆþ¤·¤¿¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹¡£
+.fi
+.\" .SH "SEE ALSO"
+.SH "´ØÏ¢¹àÌÜ"
+X(1), Xserver(1), XFree86(1), XF86_SVGA(1), XF86_VGA16(1),
+XF86_Mono(1), XF86_S3(1), XF86_8514(1), XF86_Mach8(1), XF86_Mach32(1),
+XF86_P9000(1), XF86_AGX(1), XF86_W32(1).
+.\" .SH AUTHORS
+.SH Ãø¼Ô
+.PP
+.\" Refer to the
+.I XFree86(1)
+.\" manual page.
+¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+.\" $TOG: XF86Config.man /main/1 1997/08/10 13:13:30 kaleb $
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/man/XFree86.man b/xc/programs/Xserver/hw/xfree86/doc/Japanese/man/XFree86.man
new file mode 100644
index 000000000..3e3b3d77a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/man/XFree86.man
@@ -0,0 +1,760 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/man/XFree86.man,v 1.2 1997/11/16 06:32:48 dawes Exp $
+.\"
+.\" Japanese Version Copyright (c) 1996 Kazuyuki Okamoto
+.\" all rights reserved.
+.\" Translated Tue Dec 11 21:59:36 JST 1996
+.\" by Kazuyuki Okamoto <ikko-@pacific.rim.or.jp>
+.\" Doc Version 3.47
+.\"
+.TH XFree86 1 "Version 3.2" "XFree86"
+.\" .SH NAME
+.SH ̾Á°
+.\" XFree86 - X11R6 for UNIX on x86 platforms
+XFree86 - x86 ¥Þ¥·¥ó¤Çưºî¤¹¤ë UNIX ÍѤΠX11R6
+.\" .SH DESCRIPTION
+.SH ÀâÌÀ
+.\" XFree86 is a collection of X servers for UNIX-like OSs on Intel x86 platforms.
+XFree86 ¤Ï¥¤¥ó¥Æ¥ë x86 ¥Þ¥·¥ó¤Çưºî¤¹¤ë UNIX ¤Ë»÷¤¿ OSÍѤΠX ¥µ¡¼¥Ð¤ò¼ý½¸¤·¤¿¤â¤Î¤Ç¤¹¡£
+.\" This work is derived from
+XFree86 ¤Ï
+.I "X386\ 1.2"
+¤«¤éÇÉÀ¸¤·¡¢
+.\" which was contributed to X11R5 by Snitily Graphics Consulting Service.
+Snitily Graphics Consulting Service ¤Ë¤è¤Ã¤Æ X11R5 ¤Ë´ó£¤µ¤ì¤Þ¤·¤¿¡£
+.\" .SH CONFIGURATIONS
+.SH ¹½À®
+.PP
+.I XFree86
+.\" operates under the following operating systems:
+¤Ï¼¡¤Î¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Ç»ÈÍѲÄǽ¤Ç¤¹¡£:
+.RS .5i
+.na
+.PP
+-- SVR3.2: SCO 3.2.2, 3.2.4, ISC 3.x, 4.x
+.br
+-- SVR4.0: ESIX, Microport, Dell, UHC, Consensys, MST, ISC, AT&T, NCR
+.br
+-- SVR4.2: Consensys, Univel (UnixWare)
+.br
+-- Solaris (x86) 2.1, 2.4
+.br
+.\" -- FreeBSD 1.1.5, 2.0, 2.0.5, NetBSD 1.0 (i386 port only)
+-- FreeBSD 1.1.5, 2.0, 2.0.5, NetBSD 1.0 (i386 ¤Ë¤Î¤ß°Ü¿¢¤µ¤ì¤Æ¤¤¤Þ¤¹)
+.br
+.\" -- BSD/386 version 1.1 and BSD/OS 2.0
+-- BSD/386 version 1.1 ¤È BSD/OS 2.0
+.br
+.\" -- Mach (from CMU)
+-- Mach (CMU ¤«¤é)
+.br
+-- Linux
+.br
+-- Amoeba version 5.1
+.br
+-- Minix-386vm version 1.6.25.1
+.br
+-- LynxOS AT versions 2.2.1, 2.3.0 and 2.4.0, LynxOS microSPARC 2.4.0
+.ad
+.RE
+.PP
+.\" .SH "NETWORK CONNECTIONS"
+.SH "¥Í¥Ã¥È¥ï¡¼¥¯ Àܳ"
+.\" \fIXFree86\fP supports connections made using the following reliable
+.\" byte-streams:
+\fIXFree86\fP ¤Ï°Ê²¼¤Î³Î¼Â¤Ê¥Ð¥¤¥È-¥¹¥È¥ê¡¼¥à¤Ë¤è¤ëÀܳ¤ò¥µ¥Ý¡¼¥È¤·¤Æ
+¤¤¤Þ¤¹¡£:
+.TP 4
+.I "Local"
+.\" \fIXFree86\fP supports local connections via Streams pipe via various mechanisms,
+.\" using the following paths (\fIn\fP represents the display number):
+\fIXFree86\fP ¤Ï°Ê²¼¤Î¥Ñ¥¹¤Î¼ï¡¹¤Î»Å³Ý¤±¤Î Streams ¥Ñ¥¤¥×·Ðͳ¤Î local Àܳ
+¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£(¤³¤³¤Ç \fIn\fP ¤Ï¥Ç¥£¥¹¥×¥ì¥¤ÈÖ¹æ¤Ç¤¹):
+.sp .5v
+.in 8
+.nf
+.\" /dev/X/server.\fBn\fR (SVR3 and SVR4)
+/dev/X/server.\fBn\fR (SVR3 ¤È SVR4)
+/dev/X/Nserver.\fBn\fR (SVR4)
+.ig
+/tmp/.X11-unix/X\fBn\fR (ISC SVR3)
+..
+/dev/X\fBn\fRS and /dev/X\fBn\fRR (SCO SVR3)
+.fi
+.in
+.sp .5v
+.\" On SVR4.0.4, if the \fIAdvanced Compatibility Package\fP
+.\" is installed, and in SVR4.2, \fIXFree86\fP supports local connections
+.\" from clients for SCO XSight/ODT, and (with modifications to the binary)
+.\" clients for ISC SVR3.
+SVR4.0.4 ¤Ç¤Ï¡¢\fIAdvanced Compatibility Package\fP ¤¬¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤Æ
+¤¤¤ë¾ì¹ç¤È SVR4.2 ¤Î¾ì¹ç¤Ï¡¢ \fIXFree86\fP ¤Ï SCO XSight/ODT ÍѤΥ¯¥é¥¤
+¥¢¥ó¥È¤«¤é¤È¡Ê¥Ð¥¤¥Ê¥ê¥Ñ¥Ã¥±¡¼¥¸¤ËÊѹ¹¤ò²Ã¤¨¤¿¡ËISC SVR3 ÍѤΥ¯¥é¥¤¥¢¥ó¥È
+¤«¤é¤Î local Àܳ¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£
+.TP 4
+.I "Unix Domain"
+.\" \fIXFree86\fP uses \fI/tmp/.X11-unix/X\fBn\fR as the filename for the socket,
+.\" where \fIn\fP is the display number.
+\fIXFree86\fP ¤Ï \fI/tmp/.X11-unix/X\fBn\fR ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤ò¥½¥±¥Ã¥ÈÍѤ˻ÈÍÑ
+¤·¤Þ¤¹¡£¤³¤³¤Ç \fIn\fP ¤Ï¥Ç¥£¥¹¥×¥ì¥¤ÈÖ¹æ¤Ç¤¹¡£
+.TP 4
+.I TCP\/IP
+.\" \fIXFree86\fP listens on port htons(6000+\fIn\fP), where \fIn\fP is the display
+.\" number.
+\fIXFree86\fP ¤Ï htons(6000+\fIn\fP) ¥Ý¡¼¥È¤«¤éʹ¤­ (listen) ¤Þ¤¹¡£¤³¤³¤Ç
+\fIn\fP ¤Ï¥Ç¥£¥¹¥×¥ì¥¤ÈÖ¹æ¤Ç¤¹¡£
+.TP 4
+.I "Amoeba RPC"
+.\" This is the default communication medium used under native Amoeba.
+.\" Note that under Amoeba, the server should be started
+.\" with a ``\fIhostname\fP:\fIdisplaynumber\fP'' argument.
+Amoeba ¤Ç¤Ïɸ½à¤ÎÄÌ¿®¼êÃʤǤ¹¡£Amoeba ¤Ç¤ÎÃí°Õ»ö¹à¤È¤·¤Æ¡¢¥µ¡¼¥Ð¤ò
+``\fI¥Û¥¹¥È̾\fP:\fI¥Ç¥£¥¹¥×¥ì¥¤ÈÖ¹æ\fP'' ¤ò°ú¤­¿ô¤Ë²Ã¤¨¤Æµ¯Æ°¤·¤Ê¤±¤ì¤Ð
+¤¤¤±¤Þ¤»¤ó¡£
+.\" .SH "ENVIRONMENT VARIABLES"
+.SH "´Ä¶­ÀßÄê"
+.\" For operating systems that support local connections other than Unix Domain
+.\" sockets (SVR3 and SVR4), there is a compiled-in list specifying the order
+.\" in which local connections should be attempted. This list can be overridden by
+.\" the \fIXLOCAL\fP environment variable described below. If the display name
+.\" indicates a best-choice connection should be made (e.g. \fI:0.0\fP), each
+.\" connection mechanism is tried until a connection succeeds or no more
+.\" mechanisms are available. Note: for these OSs, the Unix Domain socket
+.\" connection is treated differently from the other local connection types.
+.\" To use it the connection must be made to \fIunix:0.0\fP.
+Unix Domain ¥½¥±¥Ã¥È (SVR3 ¤È SVR4) °Ê³°¤Î¥í¡¼¥«¥ëÀܳ¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë
+¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Î¤¿¤á¤Ë¡¢Àܳ¤ò»î¤ß¤ë½çÈÖ¤¬ÁȤ߹þ¤Þ¤ì¤¿¥ê¥¹¥È¤¬¤¢¤ê¤Þ¤¹
+¤³¤Î¥ê¥¹¥È¤Ï¸å½Ò¤Î \fIXLOCAL\fP ´Ä¶­ÊÑ¿ô¤Ë¤è¤Ã¤Æ¾å½ñ¤­²Äǽ¤Ç¤¹¡£¥Ç¥£¥¹¥×¥ì¥¤Ì¾¾Î
+¤¬ºÇŬ¤ÊÀܳ¤¬½ÐÍè¤ë¤è¤¦¤Ë (Î㤨¤Ð \fI:0.0\fP) ¤Ê¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¤½¤ì¤¾¤ì¤Î
+Àܳµ¡¹½¤ÏÀܳ¤¬´°Î»¤¹¤ë¤Þ¤Ç¤«¡¢Ëô¤Ï»ÈÍѽÐÍè¤ëµ¡¹½¤¬Ìµ¤¯¤Ê¤ë¤Þ¤Ç»î¹Ô¤·¤Þ¤¹¡£
+Ãí°Õ»ö¹à: ¤³¤ì¤é¤Î OS ¤Ç¤Ï Unix Domain ¥½¥±¥Ã¥ÈÀܳ¤Ï¤½¤Î¾¤Î¥í¡¼¥«¥ëÀܳ¤Î·¿¤È¤Ï
+°Û¤Ê¤ë¼è¤ê°·¤¤¤Ç¤¹¡£Unix Domain ¥½¥±¥Ã¥ÈÀܳ¤ò»ÈÍѤ¹¤ë¤Ë¤Ï¥Ç¥£¥¹¥×¥ì¥¤Ì¾¾Î¤Ë
+\fIunix:0.0\fP ¤È»ØÄꤷ¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£
+.PP
+.\" The \fIXLOCAL\fP environment variable should contain a list of one more
+.\" more of the following:
+\fIXLOCAL\fP ´Ä¶­ÊÑ¿ô¤Ë¤Ï°Ê²¼¤Î¥ê¥¹¥È¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹:
+.sp .5v
+.in 8
+.nf
+NAMED
+PTS
+SCO
+ISC
+.fi
+.in
+.sp .5v
+.\" which represent SVR4 Named Streams pipe, Old-style USL
+.\" Streams pipe, SCO XSight Streams pipe, and ISC Streams pipe, respectively.
+.\" You can select a single mechanism (e.g. \fIXLOCAL=NAMED\fP), or an ordered
+.\" list (e.g. \fIXLOCAL="NAMED:PTS:SCO"\fP). This variable overrides the
+.\" compiled-in defaults. For SVR4 it is recommended that \fINAMED\fP be
+.\" the first preference connection. The default setting is
+.\" \fIPTS:NAMED:ISC:SCO\fP.
+¤½¤ì¤¾¤ì¤Ï¡¢SVR4 Named Streams pipe, Old-style USL Streams pipe,
+SCO XSight Streams pipe ¤È ISC Streams pipe ¤òɽ¤ï¤·¤Æ¤¤¤Þ¤¹¡£
+¤³¤ÎÆâ¡¢°ì¤Ä¤Îµ¡¹½¤òÁªÂò¤·¤Þ¤¹ (Î㤨¤Ð \fIXLOCAL=NAMED\fP)¡¢ ¼ã¤·¤¯¤Ï
+½ç½øÉÕ¤±¤·¤¿¥ê¥¹¥È¤òÁªÂò¤·¤Þ¤¹(Î㤨¤Ð \fIXLOCAL="NAMED:PTS:SCO"\fP)¡£
+¤³¤Î´Ä¶­ÊÑ¿ô¤ÏÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ëɸ½àÃͤò¾å½ñ¤­¤·¤Þ¤¹¡£SVR4 ¤Ç¤ÏºÇ½é¤ËÍ¥ÀèŪ¤Ê
+Àܳ¤Ë \fINAMED\fP ¤ò¿ä¾©¤·¤Æ¤¤¤Þ¤¹¡£É¸½àÃÍ¤Ï \fIPTS:NAMED:ISC:SCO\fP ¤Ç¤¹¡£
+.PP
+.\" To globally override the compiled-in defaults, you should define (and
+.\" export if using \fIsh\fP or \fIksh\fP) \fIXLOCAL\fP globally. If you
+.\" use \fIstartx/xinit\fP, the definition should be at the top of
+.\" your \fI.xinitrc\fP file. If you use \fIxdm\fP, the definitions should be
+.\" early on in the \fI<XRoot>/lib/X11/xdm/Xsession\fP script.
+Áȹþ¤ß¤Îɸ½àÃͤòÁ´ÂÎŪ¤ËÃÖ¤­´¹¤¨¤ë¤Ê¤é¤Ð¡¢ \fIXLOCAL\fP ¤òÁ´ÂÎŪ¤ËÄêµÁ(define)
+(¤½¤·¤Æ¡¢\fIsh\fP ¤Þ¤¿¤Ï \fIksh\fP ¤ò»È¤Ã¤Æ¤¤¤ë¤Ê¤é¤Ð export) ¤·¤Þ¤·¤ç¤¦¡£
+\fIstartx/xinit\fP ¤ò»È¤¦¤Ê¤é¤Ð¡¢\fI.xinitrc\fP ¥Õ¥¡¥¤¥ë¤ÎÀèÆ¬¤Ë
+ÄêµÁ¤·¤Þ¤·¤ç¤¦¡£\fIxdm\fP ¤ò»È¤¦¤Ê¤é¤Ð \fI<XRoot>/lib/X11/xdm/Xsession\fP
+¥¹¥¯¥ê¥×¥È¤ÎÁ°¤ÎÊý¤ËÄêµÁ¤·¤Þ¤·¤ç¤¦¡£
+.\" .SH OPTIONS
+.SH ¥ª¥×¥·¥ç¥ó
+.\" In addition to the normal server options described in the \fIXserver(1)\fP
+.\" manual page, \fIXFree86\fP accepts the following command line switches:
+\fIXserver(1)\fP ¤È¤¤¤¦¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤ËÄ̾ï¤Î¥µ¡¼¥Ð¤Ø¤Î¥ª¥×¥·¥ç¥ó
+¤Ë¤Ä¤¤¤ÆÀâÌÀ¤¬¤¢¤ë¤³¤È¡¢\fIXFree86\fP ¤Ï°Ê²¼¤Î¥³¥Þ¥ó¥É¥é¥¤¥ó¥ª¥×¥·¥ç¥ó¤ò
+¼õ¤±ÉÕ¤±¤ë»ö¤òÄɵ­¤·¤Þ¤¹:
+.TP 8
+.B vt\fIXX\fP
+.\" \fIXX\fP specifies the Virtual Terminal device number which
+.\" \fIXFree86\fP will use. Without this option, \fIXFree86\fP will pick the first
+.\" available Virtual Terminal that it can locate. This option applies only
+.\" to SVR3, SVR4, Linux, and BSD OSs with the `syscons' or `pcvt' driver.
+\fIXX\fP ¤Ï \fIXFree86\fP ¤¬»ÈÍѤ¹¤ë²¾ÁÛüËö(Virtual Terminal) ¤Î¥Ç¥Ð¥¤¥¹ÈÖ¹æ
+¤Ç¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤Ê¤¤¤È¡¢ \fIXFree86\fP ¤ÏºÇ½é¤Ë»ÈÍѲÄǽ¤Ê²¾ÁÛüËö¤ò
+³äÅö¤Æ¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï `syscons' ¤Þ¤¿¤Ï `pcvt' ¥É¥é¥¤¥Ð¤¬¤¢¤ë
+SVR3, SVR4, Linux ¤È BSD OS ¤À¤±¤ËÍ­¸ú¤Ç¤¹¡£
+.TP 8
+.B -crt /dev/tty\fIXX\fP
+.\" SCO only. This is the same as the \fBvt\fP option, and is provided for
+.\" compatibility with the native SCO X server.
+SCO ¤Î¤ß¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£ \fBvt\fP ¥ª¥×¥·¥ç¥ó¤ÈƱÅù¤Ç¡¢SCO ¾å¤Î
+X ¥µ¡¼¥Ð¤È¤Î¸ß´¹À­¤Î°Ù¤ËÄ󶡤·¤Þ¤¹¡£
+.TP 8
+.B \-probeonly
+.\" Causes the server to exit after the device probing stage. The XF86Config file
+.\" is still used when this option is given, so information that can be
+.\" auto-detected should be commented out.
+µ¡´ï¾ðÊó¤Îõºº¸å¤Ë¥µ¡¼¥Ð¤ò½ªÎ»¤µ¤»¤Þ¤¹¡£XF86Config ¥Õ¥¡¥¤¥ë¤Ï¤³¤Î¥ª¥×¥·¥ç¥ó
+¤òÉÕ¤±¤¿¤È¤­¤Ç¤â»ÈÍѤµ¤ì¤ë¤Î¤Ç¡¢¼«Æ°Ãµºº¤·¤Æ¤â¤è¤¤¾ðÊó¤Ï¥³¥á¥ó¥È¤Ë¤·¤Æ¤ª¤­¤Þ
+¤·¤ç¤¦¡£
+.TP 8
+.B \-quiet
+.\" Suppress most informational messages at startup.
+µ¯Æ°»þ¤Î¤Û¤È¤ó¤É¤Î¥á¥Ã¥»¡¼¥¸¤òÍ޻ߤ·¤Þ¤¹¡£
+.TP 8
+.B \-bpp \fIn\fP
+.\" Set number of bits per pixel. The default is 8. Legal values are
+.\" 8, 15, 16, 24, 32. Not all servers support all values.
+¥Ô¥¯¥»¥ëËè¤Î¥Ó¥Ã¥È¿ô¤òÀßÄꤷ¤Þ¤¹¡£É¸½àÃÍ¤Ï 8 ¤Ç¤¹¡£»ÈÍѲÄǽ¤ÊÃͤÏ
+8, 15, 16, 24, 32 ¤Ç¤¹¡£¤¹¤Ù¤Æ¤ÎÃͤ¬¤¹¤Ù¤Æ¤Î¥µ¡¼¥Ð¤Ç»È¤¨¤ë¤ï¤±¤Ç¤Ï
+¤¢¤ê¤Þ¤»¤ó¡£
+.TP 8
+.B \-weight \fInnn\fP
+.\" Set RGB weighting at 16 bpp. The default is 565. This applies
+.\" only to those servers which support 16 bpp.
+16 bpp ¤Ç¤Î RGB ½Å¤ßÉÕ¤±¤òÀßÄꤷ¤Þ¤¹¡£É¸½àÃÍ¤Ï 565 ¤Ç¤¹¡£¤³¤ì¤Ï
+16 bpp ¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¥µ¡¼¥Ð¤Ç¤·¤«Å¬±þ½ÐÍè¤Þ¤»¤ó¡£
+.TP 8
+.B \-flipPixels
+.\" Swap the default values for the black and white pixels.
+Çò¤È¹õ¤Î¥Ô¥¯¥»¥ë¤Îɸ½àÃͤòÆþ¤ìÂØ¤¨¤Þ¤¹¡£
+.TP 8
+.B \-disableVidMode
+.\" Disable the the parts of the VidMode extension used by the xvidtune client
+.\" that can be used to change the video modes.
+¥Ó¥Ç¥ª¥â¡¼¥É¤òÊѹ¹¤¹¤ë xvidtune ¥¯¥é¥¤¥¢¥ó¥È¤Ç»ÈÍѤ·¤Æ¤¤¤ë VidMode µ¡Ç½³ÈÄ¥
+¤Î°ìÉô¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£
+.TP 8
+.B \-allowNonLocalXvidtune
+.\" Allow the xvidtune client to connect from another host. By default non-local
+.\" connections are not allowed.
+¾¤Î¥Û¥¹¥È¤«¤éÀܳ¤·¤Æ xvidtune ¥¯¥é¥¤¥¢¥ó¥È¤Î¼Â¹Ô¤òµö²Ä¤¹¤ë¡£É¸½à¤Ç¤Ï
+¥í¡¼¥«¥ëÀܳ°Ê³°¤Ï¶Ø»ß¤·¤Æ¤¤¤Þ¤¹¡£
+.TP 8
+.B \-gamma \fIvalue\fP
+.\" Set the gamma correction. \fIvalue\fP must be between 0.1 and 10. The
+.\" default is 1.0
+.\" This value is applied equally to the R, G and B values. Not all servers
+.\" support this.
+¥¬¥ó¥ÞÊäÀµ¤òÀßÄꤷ¤Þ¤¹¡£\fIvalue\fP ¤Ï 0.1 ¤È 10 ¤Î¤¢¤¤¤À¤ÎÃͤǤʤ±¤ì¤Ð
+¤¤¤±¤Þ¤»¤ó¡£É¸½àÃÍ¤Ï 1.0 ¤Ç¤¹¡£¤³¤ÎÃÍ¤Ï R, G ¤È B ¤Ë¸øÊ¿¤ËŬ±þ¤µ¤ì¤Þ¤¹¡£
+¤³¤ì¤ÏÁ´¤Æ¤Î¥µ¡¼¥Ð¤Ç»È¤¨¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+.TP 8
+.B \-rgamma \fIvalue\fP
+.\" Set the red gamma correction. \fIvalue\fP must be between 0.1 and 10. The
+.\" default is 1.0
+.\" Not all servers support this.
+À֤Υ¬¥ó¥ÞÊäÀµ¤òÀßÄꤷ¤Þ¤¹¡£\fIvalue\fP ¤Ï 0.1 ¤È 10 ¤Î¤¢¤¤¤À¤ÎÃͤǤʤ±¤ì¤Ð
+¤¤¤±¤Þ¤»¤ó¡£É¸½àÃÍ¤Ï 1.0 ¤Ç¤¹¡£
+¤³¤ì¤ÏÁ´¤Æ¤Î¥µ¡¼¥Ð¤Ç»È¤¨¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+.TP 8
+.B \-ggamma \fIvalue\fP
+.\" Set the green gamma correction. \fIvalue\fP must be between 0.1 and 10. The
+.\" default is 1.0
+.\" Not all servers support this.
+ÎФΥ¬¥ó¥ÞÊäÀµ¤òÀßÄꤷ¤Þ¤¹¡£\fIvalue\fP ¤Ï 0.1 ¤È 10 ¤Î¤¢¤¤¤À¤ÎÃͤǤʤ±¤ì¤Ð
+¤¤¤±¤Þ¤»¤ó¡£É¸½àÃÍ¤Ï 1.0 ¤Ç¤¹¡£
+¤³¤ì¤ÏÁ´¤Æ¤Î¥µ¡¼¥Ð¤Ç»È¤¨¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+.TP 8
+.B \-bgamma \fIvalue\fP
+.\" Set the blue gamma correction. \fIvalue\fP must be between 0.1 and 10. The
+.\" default is 1.0
+.\" Not all servers support this.
+ÀĤΥ¬¥ó¥ÞÊäÀµ¤òÀßÄꤷ¤Þ¤¹¡£\fIvalue\fP ¤Ï 0.1 ¤È 10 ¤Î¤¢¤¤¤À¤ÎÃͤǤʤ±¤ì¤Ð
+¤¤¤±¤Þ¤»¤ó¡£É¸½àÃÍ¤Ï 1.0 ¤Ç¤¹¡£
+¤³¤ì¤ÏÁ´¤Æ¤Î¥µ¡¼¥Ð¤Ç»È¤¨¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+.TP 8
+.B \-showconfig
+.\" Print out the server version, patchlevel, and a list of screen drivers
+.\" configured in the server.
+¥µ¡¼¥Ð¤ËÀßÄꤵ¤ì¤Æ¤¤¤ë¥¹¥¯¥ê¡¼¥ó¥É¥é¥¤¥Ð¤Î°ìÍ÷¤òɽ¼¨¤·¤Þ¤¹¡£
+.TP 8
+.B \-verbose
+.\" Multiple occurrences of this flag increase the amount of information printed on
+.\" stderr (more than the default).
+µ¯Æ°»þ¤Ëɽ¼¨¤µ¤ì¤ë¾ðÊó¤òºÇÂç²½¤·¤Þ¤¹(ɸ½à¤è¤êÁý¤¨¤Þ¤¹)¡£
+.TP 8
+.B \-version
+.\" Same as \fB\-showconfig\fP.
+\fB\-showconfig\fP ¤ÈƱ¤¸¤Ç¤¹¡£
+.TP 8
+.B \-xf86config \fIfile\fP
+.\" Read the server configuration from \fIfile\fP. This option is only available
+.\" when the server is run as root (i.e, with real-uid 0).
+\fIfile\fP ¤«¤é¥µ¡¼¥Ð¤Î¹½À®¾ðÊó¤òÆÉ¤ß¹þ¤ß¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï
+root (Î㤨¤Ð¡¢ÆâÉô uid ÈÖ¹æ ¤¬ 0) ¤Çµ¯Æ°¤·¤¿¥µ¡¼¥Ð¤Î¤È¤­¤Ë¤Î¤ßÍ­¸ú¤Ç¤¹¡£
+.TP 8
+.B \-keeptty
+.\" Prevent the server from detaching its initial controlling terminal. This
+.\" option is only useful when debugging the server.
+ºÇ½é¤Ëµ¯Æ°¤·¤¿À©¸æÍѤÎüËö¤ò¥µ¡¼¥Ð¤¬ÀÚ¤êÎ¥¤µ¤Ê¤¤¤è¤¦¤Ë¤·¤Þ¤¹¡£
+¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥µ¡¼¥Ð¤Î¥Ç¥Ð¥Ã¥°»þ¤Ë¤Î¤ßÍ­ÍѤǤ¹¡£
+.\" .SH "KEYBOARD"
+.SH "¥­¡¼¥Ü¡¼¥É"
+.\" Multiple key presses recognized directly by \fIXFree86\fP are:
+\fIXFree86\fP ¤¬Ä¾ÀÜǧ¼±¤¹¤ëƱ»þ¤ËÊ£¿ô¤Î¥­¡¼ÆþÎϤϰʲ¼¤Î¤È¤ª¤ê¤Ç¤¹:
+.TP 8
+.B Ctrl+Alt+Backspace
+.\" Immediately kills the server -- no questions asked. (Can be disabled by
+.\" specifying "DontZap" in the \fBServerFlags\fP section of the XF86Config file.)
+®¤ä¤«¤Ë¥µ¡¼¥Ð¤òÄä»ß¤·¤Þ¤¹ -- ²¿¤â±þÅú¤Ï¤¢¤ê¤Þ¤»¤ó¡£(XF86Config ¥Õ¥¡¥¤¥ë¤Î
+\fBServerFlags\fP Àá¤Ë "DontZap" ¤È»ØÄꤹ¤ë»ö¤Ë¤è¤ê̵¸ú¤Ë½ÐÍè¤Þ¤¹¡£)
+.TP 8
+.B Ctrl+Alt+Keypad-Plus
+.\" Change video mode to next one specified in the configuration file,
+.\" (increasing video resolution order).
+¹½À®¾ðÊó¥Õ¥¡¥¤¥ë¤Ë»ØÄꤷ¤Æ¤¢¤ë¼¡¹Ô¤Î¥Ó¥Ç¥ª¥â¡¼¥É(¥Ó¥Ç¥ª¤Î²òÁüÅÙ¤¬ÁýÂ礹¤ëÊý¸þ¤Ë)
+¤ËÊѹ¹¤·¤Þ¤¹¡£
+.TP 8
+.B Ctrl+Alt+Keypad-Minus
+.\" Change video mode to previous one specified in the configuration file,
+.\" (decreasing video resolution order).
+¹½À®¾ðÊó¥Õ¥¡¥¤¥ë¤Ë»ØÄꤷ¤Æ¤¢¤ëÁ°¹Ô¤Î¥Ó¥Ç¥ª¥â¡¼¥É(¥Ó¥Ç¥ª¤Î²òÁüÅÙ¤¬¸º¾¯¤¹¤ëÊý¸þ¤Ë)
+¤ËÊѹ¹¤·¤Þ¤¹¡£
+.TP 8
+.B Ctrl+Alt+F1...F12
+.\" For BSD systems using the syscons driver and Linux, these keystroke
+.\" combinations are used to switch to Virtual
+.\" Console 1 through 12.
+syscons ¥É¥é¥¤¥Ð¤ò»ÈÍѤ·¤Æ¤¤¤ë BSD ¥·¥¹¥Æ¥à¤È Linux ¤Ç¤Ï¡¢¤³¤ÎÆþÎϤÎÁȹç¤ï¤»¤Ï
+²¾ÁÛ¥³¥ó¥½¡¼¥ë£±ÈÖ¤«¤é£±£²È֤ޤǤËÀÚ¤êÂØ¤¨¤ë¤Î¤Ë»È¤Ã¤Æ¤¤¤Þ¤¹¡£
+.\" .SH SETUP
+.SH ÀßÄê
+.I XFree86
+.\" uses a configuration file called \fBXF86Config\fP for its initial setup.
+.\" Refer to the
+¤Ï½é´ü¾õÂÖ¤Ç¤Ï \fBXF86Config\fP ¤È¸Æ¤Ð¤ì¤ë¹½À®¾ðÊó¥Õ¥¡¥¤¥ë¤ò»ÈÍѤ·¤Æ¤¤¤Þ¤¹¡£
+¤è¤ê¾Ü¤·¤¯¤Ï
+.I XF86Config(4/5)
+.\" manual page for more information.
+¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+.\" .SH FILES
+.SH ¥Õ¥¡¥¤¥ë
+.TP 30
+<XRoot>/bin/XF86_SVGA
+.\" The color SVGA X server
+¥«¥é¡¼¤Î SVGA X ¥µ¡¼¥Ð¤Ç¤¹¡£
+.TP 30
+<XRoot>/bin/XF86_Mono
+.\" The monochrome X server for VGA and other mono cards
+VGA ¤È¾¤ÎÇò¹õ¤Î¥Ó¥Ç¥ª¥«¡¼¥ÉÍѤÎÇò¹õ¤Î X ¥µ¡¼¥Ð¤Ç¤¹¡£
+.TP 30
+<XRoot>/bin/XF86_S3
+.\" The accelerated S3 X server
+S3 ÍѤΥ¢¥¯¥»¥é¥ì¡¼¥¿ X ¥µ¡¼¥Ð¤Ç¤¹¡£
+.TP 30
+<XRoot>/bin/XF86_Mach8
+.\" The accelerated Mach8 X server
+Mach8 ÍѤΥ¢¥¯¥»¥é¥ì¡¼¥¿ X ¥µ¡¼¥Ð¤Ç¤¹¡£
+.TP 30
+<XRoot>/bin/XF86_Mach32
+.\" The accelerated Mach32 X server
+Mach32 ÍѤΥ¢¥¯¥»¥é¥ì¡¼¥¿ X ¥µ¡¼¥Ð¤Ç¤¹¡£
+.TP 30
+<XRoot>/bin/XF86_Mach64
+.\" The accelerated Mach64 X server
+Mach64 ÍѤΥ¢¥¯¥»¥é¥ì¡¼¥¿ X ¥µ¡¼¥Ð¤Ç¤¹¡£
+.TP 30
+<XRoot>/bin/XF86_P9000
+.\" The accelerated P9000 X server
+P9000 ÍѤΥ¢¥¯¥»¥é¥ì¡¼¥¿ X ¥µ¡¼¥Ð¤Ç¤¹¡£
+.TP 30
+<XRoot>/bin/XF86_AGX
+.\" The accelerated AGX X server
+AGX ÍѤΥ¢¥¯¥»¥é¥ì¡¼¥¿ X ¥µ¡¼¥Ð¤Ç¤¹¡£
+.TP 30
+<XRoot>/bin/XF86_W32
+.\" The accelerated ET4000/W32 and ET6000 X server
+ET4000/W32 ÍѤΥ¢¥¯¥»¥é¥ì¡¼¥¿ X ¥µ¡¼¥Ð¤Ç¤¹¡£
+.TP 30
+<XRoot>/bin/XF86_8514
+.\" The accelerated 8514/A X server
+8514/A ÍѤΥ¢¥¯¥»¥é¥ì¡¼¥¿ X ¥µ¡¼¥Ð¤Ç¤¹¡£
+.TP 30
+/etc/XF86Config
+.\" Server configuration file
+¥µ¡¼¥Ð¹½À®¾ðÊó¥Õ¥¡¥¤¥ë¤Ç¤¹¡£
+.TP 30
+<XRoot>/lib/X11/XF86Config.\fIhostname\fP
+.\" Server configuration file
+¥µ¡¼¥Ð¹½À®¾ðÊó¥Õ¥¡¥¤¥ë¤Ç¤¹¡£
+.TP 30
+<XRoot>/lib/X11/XF86Config
+.\" Server configuration file
+¥µ¡¼¥Ð¹½À®¾ðÊó¥Õ¥¡¥¤¥ë¤Ç¤¹¡£
+.TP 30
+<XRoot>/bin/\(**
+.\" Client binaries
+¥¯¥é¥¤¥¢¥ó¥ÈÍÑ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ç¤¹¡£
+.TP 30
+<XRoot>/include/\(**
+.\" Header files
+¥Ø¥Ã¥À¡¼¥Õ¥¡¥¤¥ë¤Ç¤¹¡£
+.TP 30
+<XRoot>/lib/\(**
+.\" Libraries
+¥é¥¤¥Ö¥é¥ê¤Ç¤¹¡£
+.TP 30
+<XRoot>/lib/X11/fonts/\(**
+.\" Fonts
+¥Õ¥©¥ó¥È¤Ç¤¹¡£
+.TP 30
+<XRoot>/lib/X11/rgb.txt
+.\" Color names to RGB mapping
+¥«¥é¡¼Ì¾¾Î¤Î RGB ¤Ø¤Î³ä¤êÅö¤Æ¤Ç¤¹¡£
+.TP 30
+<XRoot>/lib/X11/XErrorDB
+.\" Client error message database
+¥¯¥é¥¤¥¢¥ó¥È¤Î¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ç¤¹¡£
+.TP 30
+<XRoot>/lib/X11/app-defaults/\(**
+.\" Client resource specifications
+¥¯¥é¥¤¥¢¥ó¥È¤Î¥ê¥½¡¼¥¹¤Î»ÅÍͤǤ¹¡£
+.TP 30
+<XRoot>/man/man?/\(**
+.\" Manual pages
+¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤Ç¤¹¡£
+.TP 30
+/etc/X\fIn\fP.hosts
+.\" Initial access control list for display \fIn\fP
+¥Ç¥£¥¹¥×¥ì¥¤ÈÖ¹æ \fIn\fP ¤ËÂФ¹¤ë¥¢¥¯¥»¥¹À©¸æ¤Î½é´ü¾õÂ֤Ǥ¹¡£
+.LP
+.\" Note: <XRoot> refers to the root of the X11 install tree.
+Ãí°Õ: <XRoot> ¤Ï X11 ¤ÎƳÆþ¥Ç¥£¥ì¥¯¥È¥ê¤Î¥ë¡¼¥È¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+.\" .SH "SEE ALSO"
+.SH "´ØÏ¢¹àÌÜ"
+X(1), Xserver(1), xdm(1), xinit(1), XF86Config(4/5), xf86config(1),
+XF86_SVGA(1), XF86_VGA16(1), XF86_Mono(1), XF86_Accel(1), xvidtune(1)
+.\" .SH AUTHORS
+.SH Ãø¼Ô
+.PP
+.\" For X11R5, \fIXF86 1.2\fP was provided by:
+X11R5 Âбþ¤Ï \fIXF86 1.2\fP ¤Ç¤Ê¤µ¤ìÄ󶡤Ï:
+.TP 8
+Thomas Roell, \fIroell@informatik.tu-muenchen.de\fP
+.\" TU-Muenchen: Server and SVR4 stuff
+TU-Muenchen: ¥µ¡¼¥Ð¤È SVR4 ¥¹¥¿¥Ã¥Õ
+.TP 8
+Mark W. Snitily, \fImark@sgcs.com\fP
+.\" SGCS: SVR3 support, X Consortium Sponsor
+SGCS: SVR3 ¥µ¥Ý¡¼¥È, X Consortium ¥¹¥Ý¥ó¥µ¡¼
+.PP
+.\" ... and many more people out there on the net who helped with ideas and
+.\" bug-fixes.
+ ... ¤½¤·¤Æ¹½ÁۤȽ¤Àµ¤ò½õ¤±¤Æ¤¯¤ì¤¿¥¤¥ó¥¿¡¼¥Í¥Ã¥È¾å¤Î¿¤¯¤Î³§ÍÍ¡£
+.PP
+.\" XFree86 was integrated into X11R6 by the following team:
+°Ê²¼¤Î¥Á¡¼¥à¤Ç XFree86 ¤ò X11R6 ¤ËÅý¹ç¤·¤Þ¤·¤¿:
+.PP
+.nf
+Stuart Anderson \fIanderson@metrolink.com\fP
+Doug Anson \fIdanson@lgc.com\fP
+Gertjan Akkerman \fIakkerman@dutiba.twi.tudelft.nl\fP
+Mike Bernson \fImike@mbsun.mlb.org\fP
+Robin Cutshaw \fIrobin@XFree86.org\fP
+David Dawes \fIdawes@XFree86.org\fP
+Marc Evans \fImarc@XFree86.org\fP
+Pascal Haible \fIhaible@izfm.uni-stuttgart.de\fP
+Matthieu Herrb \fIMatthieu.Herrb@laas.fr\fP
+Dirk Hohndel \fIhohndel@XFree86.org\fP
+David Holland \fIdavidh@use.com\fP
+Alan Hourihane \fIalanh@fairlite.demon.co.uk\fP
+Jeffrey Hsu \fIhsu@soda.berkeley.edu\fP
+Glenn Lai \fIglenn@cs.utexas.edu\fP
+Ted Lemon \fImellon@ncd.com\fP
+Rich Murphey \fIrich@XFree86.org\fP
+Hans Nasten \fInasten@everyware.se\fP
+Mark Snitily \fImark@sgcs.com\fP
+Randy Terbush \fIrandyt@cse.unl.edu\fP
+Jon Tombs \fItombs@XFree86.org\fP
+Kees Verstoep \fIversto@cs.vu.nl\fP
+Paul Vixie \fIpaul@vix.com\fP
+Mark Weaver \fIMark_Weaver@brown.edu\fP
+David Wexelblat \fIdwex@XFree86.org\fP
+Philip Wheatley \fIPhilip.Wheatley@ColumbiaSC.NCR.COM\fP
+Thomas Wolfram \fIwolf@prz.tu-berlin.de\fP
+Orest Zborowski \fIorestz@eskimo.com\fP
+.fi
+.PP
+.\" The \fIXFree86\fP enhancement package was provided by:
+\fIXFree86\fP µ¡Ç½³ÈÄ¥¥Ñ¥Ã¥±¡¼¥¸¤ÎÄ󶡤ϰʲ¼¤Î¤È¤ª¤ê:
+.TP 8
+David Dawes, \fIdawes@XFree86.org\fP
+.\" Release coordination, administration of FTP repository and mailing lists.
+.\" Source tree management
+.\" and integration, accelerated server integration, fixing, and coding.
+¸ø³«ºî¶È¤Î¼è¤êÅ»¤á¡¢FTP ¥µ¡¼¥Ð¤È¥á¡¼¥ê¥ó¥°¥ê¥¹¥È¤Î´ÉÍý¡£
+¥½¡¼¥¹¥Õ¥¡¥¤¥ë´ÉÍý¤ÈÅý¹ç¡¢¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð¤ÎÅý¹ç¡¢½¤Àµ¤È
+¥×¥í¥°¥é¥ß¥ó¥°¡£
+.TP 8
+Glenn Lai, \fIglenn@cs.utexas.edu\fP
+.\" The SpeedUp code for ET4000 based SVGA cards, and ET4000/W32 accelerated
+.\" server.
+ET4000 ¤ò´ð¤Ë¤·¤¿ SVGA ¥«¡¼¥ÉÂбþ¤Î¥×¥í¥°¥é¥à¤ÎÀ­Ç½¸þ¾å¤È ET4000/W32 ¤Î
+¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð¡£
+.TP 8
+Jim Tsillas, \fIjtsilla@ccs.neu.edu\fP
+.\" Many server speedups from the fX386 series of enhancements.
+°ìÏ¢¤Î fX386 ¤Î²þÁ±¤Ë¤è¤ë¿¤¯¤Î¥µ¡¼¥Ð¤ÎÀ­Ç½¸þ¾å¡£
+.TP 8
+David Wexelblat, \fIdwex@XFree86.org\fP
+.\" Integration of the fX386 code into the default server,
+.\" many driver fixes, and driver documentation, assembly of the VGA
+.\" card/monitor database, development of the generic video mode listing.
+.\" Accelerated server integration, fixing, and coding.
+ɸ½à¥µ¡¼¥Ð¤Ø¤Î fX386 ¤ÎÅý¹ç¡¢Â¿¤¯¤Î¥É¥é¥¤¥Ð¤Î½¤Àµ¤È¥É¥é¥¤¥Ð¤Î»ñÎÁºîÀ®¡¢
+VGA ¥«¡¼¥É¤È¥â¥Ë¥¿¡¼¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¼ý½¸¡¢ÈÆÍѥӥǥª¥â¡¼¥É°ìÍ÷¤ÎºîÀ®¡£
+¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð¤ÎÅý¹ç¡¢½¤Àµ¤È¥×¥í¥°¥é¥ß¥ó¥°¡£
+.TP 8
+Dirk Hohndel, \fIhohndel@XFree86.org\fP
+.\" Linux shared libraries and release coordination. Accelerated server
+.\" integration and fixing. Generic administrivia and documentation.
+Linux ¶¦Í­¥é¥¤¥Ö¥é¥ê¤È¸ø³«ºî¶È¤Î¼è¤êÅ»¤á¡£¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð¤ÎÅý¹ç¤È½¤Àµ¡£
+°ìÈÌ´ÉÍý¶È̳¤È»ñÎÁºîÀ®¡£
+.PP
+.TP 8
+Amancio Hasty Jr., \fIhasty@netcom.com\fP
+.\" Porting to \fB386BSD\fP version 0.1 and XS3 development.
+\fB386BSD\fP version 0.1 ¤Ø¤Î°Ü¿¢¤È XS3 ¤Î³«È¯¡£
+.TP 8
+Rich Murphey, \fIrich@XFree86.org\fP
+.\" Ported to \fB386BSD\fP version 0.1 based on the original port by Pace Willison.
+.\" Support for \fB386BSD\fP, \fBFreeBSD\fP, and \fBNetBSD\fP.
+Pace Willison »á ¤¬»Ï¤á¤¿°Ü¿¢ÈǤò´ð¤Ë¤·¤¿ \fB386BSD\fP version 0.1 ¤Ø¤Î°Ü¿¢¡£
+\fB386BSD\fP, \fBFreeBSD\fP ¤È \fBNetBSD\fP ¤ÎÊݼ顣
+.TP 8
+Robert Baron, \fIRobert.Baron@ernst.mach.cs.cmu.edu\fP
+.\" Ported to \fBMach\fP.
+\fBMach\fP ¤Ø¤Î°Ü¿¢¡£
+.TP 8
+Orest Zborowski, \fIorestz@eskimo.com\fP
+.\" Ported to \fBLinux\fP.
+\fBLinux\fP ¤Ø¤Î°Ü¿¢¡£
+.TP 8
+Doug Anson, \fIdanson@lgc.com\fP
+.\" Ported to \fBSolaris x86\fP.
+\fBSolaris x86\fP ¤Ø¤Î°Ü¿¢¡£
+.TP 8
+David Holland, \fIdavidh@use.com\fP
+.\" Ported to \fBSolaris x86\fP.
+\fBSolaris x86\fP ¤Ø¤Î°Ü¿¢¡£
+.TP 8
+David McCullough, \fIdavidm@stallion.oz.au\fP
+.\" Ported to \fBSCO SVR3\fP.
+\fBSCO SVR3\fP ¤Ø¤Î°Ü¿¢¡£
+.TP 8
+Michael Rohleder, \fImichael.rohleder@stadt-frankfurt.de\fP
+.\" Ported to \fBISC SVR3\fP.
+\fBISC SVR3\fP ¤Ø¤Î°Ü¿¢¡£
+.TP 8
+Kees Verstoep, \fIversto@cs.vu.nl\fP
+.\" Ported to \fBAmoeba\fP based on Leendert van Doorn's original Amoeba port of
+.\" X11R5.
+Leendert van Doorn ¤¬»Ï¤á¤¿ X11R5 ¤Î Amoeba ¤Ø¤Î°Ü¿¢ÈǤò´ð¤Ë¤·¤¿ \fBAmoeba\fP
+¤Ø¤Î°Ü¿¢¡£
+.TP 8
+Marc Evans, \fIMarc@XFree86.org\fP
+Port.\" ed to \fBOSF/1\fP.
+\fBOSF/1\fP ¤Ø¤Î°Ü¿¢¡£
+.TP 8
+Philip Homburg, \fIphilip@cs.vu.nl\fP
+.\" Ported to \fBMinix-386vm\fP.
+\fBMinix-386vm\fP ¤Ø¤Î°Ü¿¢¡£
+.TP 8
+Thomas Mueller, \fItm@systrix.de\fP
+.\" Ported to \fBLynxOS\fP.
+\fBLynxOS\fP ¤Ø¤Î°Ü¿¢¡£
+.TP 8
+Jon Tombs, \fItombs@XFree86.org\fP
+.\" S3 server and accelerated server coordination.
+S3 ¥µ¡¼¥Ð¤È¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð¤Î¼è¤êÅ»¤á¡£
+.TP 8
+Harald Koenig, \fIkoenig@tat.physik.uni-tuebingen.de\fP
+.\" S3 server development.
+S3 ¥µ¡¼¥Ð¤Î³«È¯¡£
+.TP 8
+Bernhard Bender, \fIbr@elsa.mhs.compuserve.com\fP
+.\" S3 server development.
+S3 ¥µ¡¼¥Ð¤Î³«È¯¡£
+.TP 8
+Kevin Martin, \fImartin@cs.unc.edu\fP
+.\" Overall work on the base accelerated servers (ATI and 8514/A), and Mach64
+.\" server.
+´ðÁäˤʤä¿¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð·² (ATI ¤È 8514/A) ¤ÎÁ´ºî¶È¤È Mach64
+¥µ¡¼¥Ð¡£
+.TP 8
+Rik Faith, \fIfaith@cs.unc.edu\fP
+.\" Overall work on the base accelerated servers (ATI and 8514/A).
+´ðÁäˤʤä¿¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð·² (ATI ¤È 8514/A) ¤ÎÁ´ºî¶È¡£
+.TP 8
+Tiago Gons, \fItiago@comosjn.hobby.nl\fP
+.\" Mach8 and 8514/A server development
+Mach8 ¤È 8514/A ¥µ¡¼¥Ð¤Î³«È¯¡£
+.TP 8
+Hans Nasten, \fInasten@everyware.se\fP
+.\" Mach8, 8514/A, and S3 server development and BSD/386 support
+Mach8, 8514/A ¤È S3 ¥µ¡¼¥Ð¤Î³«È¯¤È BSD/386 ÈǤÎÊݼ顣
+.TP 8
+Mike Bernson, \fImike@mbsun.mlb.org\fP
+.\" Mach32 server development.
+Mach32 ¥µ¡¼¥Ð¤Î³«È¯¡£
+.TP 8
+Mark Weaver, \fIMark_Weaver@brown.edu\fP
+.\" Mach32 server development.
+Mach32 ¥µ¡¼¥Ð¤Î³«È¯¡£
+.TP 8
+Craig Groeschel, \fIcraig@metrolink.com\fP
+.\" Mach32 server development.
+Mach32 ¥µ¡¼¥Ð¤Î³«È¯¡£
+.TP 8
+Henry Worth, \fIHenry.Worth@amail.amdahl.com\fP
+.\" AGX server.
+AGX ¥µ¡¼¥Ð¡£
+.TP 8
+Erik Nygren, \fInygren@mit.edu\fP
+.\" P9000 server.
+P9000 ¥µ¡¼¥Ð¡£
+.TP 8
+Harry Langenbacher \fIharry@brain.jpl.nasa.gov\fP
+.\" P9000 server.
+P9000 ¥µ¡¼¥Ð¡£
+.TP 8
+Chris Mason, \fImason@mail.csh.rit.edu\fP
+.\" P9000 server.
+P9000 ¥µ¡¼¥Ð¡£
+.TP 8
+Henrik Harmsen \fIharmsen@eritel.se\fP
+.\" P9000 server.
+P9000 ¥µ¡¼¥Ð¡£
+.TP 8
+Simon Cooper, \fIscooper@vizlab.rutgers.edu\fP
+.\" Cirrus accelerated code (based on work by Bill Reynolds).
+Cirrus ¥¢¥¯¥»¥é¥ì¡¼¥¿¤Î¥×¥í¥°¥é¥ß¥ó¥°(Bill Reynolds ¤ÎÀ®²Ì¤ò´ð¤Ë¤·¤Æ¤¤¤Þ¤¹)¡£
+.TP 8
+Harm Hanemaayer, \fIhhanemaa@cs.ruu.nl\fP
+.\" Cirrus accelerated code, and ARK driver.
+Cirrus ¥¢¥¯¥»¥é¥ì¡¼¥¿¤Î¥×¥í¥°¥é¥ß¥ó¥°¤È ARK ¥É¥é¥¤¥Ð¡£
+.TP 8
+Thomas Zerucha, \fIzerucha@shell.portal.com\fP
+.\" Support for Cirrus CL-GD7543.
+Cirrus CL-GD7543 ¤ÎÊݼ顣
+.TP 8
+Leon Bottou, \fIbottou@laforia.ibp.fr\fP
+.\" ARK driver.
+ARK ¥É¥é¥¤¥Ð¡£
+.TP 8
+Mike Tierney, \fIfloyd@eng.umd.edu\fP
+.\" WD accelerated code.
+WD ¥¢¥¯¥»¥é¥ì¡¼¥¿¤Î¥×¥í¥°¥é¥ß¥ó¥°¡£
+.TP 8
+Bill Conn, \fIconn@bnr.ca\fP
+.\" WD accelerated code.
+WD ¥¢¥¯¥»¥é¥ì¡¼¥¿¤Î¥×¥í¥°¥é¥ß¥ó¥°¡£
+.TP 8
+Brad Bosch, \fIbrad@lachman.com\fP
+.\" WD 90C24A support.
+WD 90C24A ¤ÎÊݼ顣
+.TP 8
+Alan Hourihane, \fIalanh@fairlite.demon.co.uk\fP
+.\" Trident SVGA driver, SiS SVGA driver and DEC 21030 server.
+Trident SVGA ¥É¥é¥¤¥Ð¡¢SiS SVGA ¥É¥é¥¤¥Ð¤È DEC 21030 ¥µ¡¼¥Ð¡£
+.TP 8
+Marc La France, \fIMarc.La-France@ualberta.ca\fP
+.\" ATI vgawonder SVGA driver
+ATI vgawonder SVGA ¥É¥é¥¤¥Ð¡£
+.TP 8
+Steve Goldman, \fIsgoldman@encore.com\fP
+.\" Oak 067/077 SVGA driver.
+Oak 067/077 SVGA ¥É¥é¥¤¥Ð¡£
+.TP 8
+Jorge Delgado, \fIernar@dit.upm.es\fP
+.\" Oak SVGA driver, and 087 accelerated code.
+Oak SVGA ¥É¥é¥¤¥Ð¤È 087 ¥¢¥¯¥»¥é¥ì¡¼¥¿¤Î¥×¥í¥°¥é¥ß¥ó¥°¡£
+.TP 8
+Bill Conn, \fIconn@bnr.ca\fP
+.\" WD accelerated code.
+WD ¥¢¥¯¥»¥é¥ì¡¼¥¿¤Î¥×¥í¥°¥é¥ß¥ó¥°¡£
+.TP 8
+Paolo Severini, \fIlendl@dist.dist.unige.it\fP
+.\" AL2101 SVGA driver
+AL2101 SVGA ¥É¥é¥¤¥Ð¡£
+.TP 8
+Ching-Tai Chiu, \fIcchiu@netcom.com\fP
+.\" Avance Logic ALI SVGA driver
+Avance Logic ALI SVGA ¥É¥é¥¤¥Ð¡£
+.TP 8
+Manfred Brands, \fImb@oceonics.nl\fP
+.\" Cirrus 64xx SVGA driver
+Cirrus 64xx SVGA ¥É¥é¥¤¥Ð¡£
+.TP 8
+Randy Hendry, \fIrandy@sgi.com\fP
+.\" Cirrus 6440 support in the cl64xx SVGA driver
+cl64xx SVGA ¥É¥é¥¤¥ÐÆâ¤Î Cirrus 6440 ¤ÎÊݼ顣
+.TP 8
+Frank Dikker, \fIdikker@cs.utwente.nl\fP
+.\" MX SVGA driver
+MX SVGA ¥É¥é¥¤¥Ð¡£
+.TP 8
+Regis Cridlig, \fIcridlig@dmi.ens.fr\fP
+.\" Chips & Technologies driver
+Chips & Technology ¥É¥é¥¤¥Ð¡£
+.TP 8
+Jon Block, \fIblock@frc.com\fP
+.\" Chips & Technologies driver
+Chips & Technology ¥É¥é¥¤¥Ð¡£
+.TP 8
+Mike Hollick, \fIhollick@graphics.cis.upenn.edu\fP
+.\" Chips & Technologies driver
+Chips & Technology ¥É¥é¥¤¥Ð¡£
+.TP 8
+Nozomi Ytow
+.\" Chips & Technologies driver
+Chips & Technology ¥É¥é¥¤¥Ð¡£
+.TP 8
+Egbert Eich, \fIEgbert.Eich@Physik.TH-Darmstadt.DE\fP
+.\" Chips & Technologies driver
+Chips & Technology ¥É¥é¥¤¥Ð¡£
+.TP 8
+David Bateman, \fIdbateman@ee.uts.edu.au\fP
+.\" Chips & Technologies driver
+Chips & Technology ¥É¥é¥¤¥Ð¡£
+.TP 8
+Xavier Ducoin, \fIxavier@rd.lectra.fr\fP
+.\" Chips & Technologies driver
+Chips & Technology ¥É¥é¥¤¥Ð¡£
+.TP 8
+Peter Trattler, \fIpeter@sbox.tu-graz.ac.at\fP
+.\" RealTek SVGA driver
+RealTek SVGA ¥É¥é¥¤¥Ð¡£
+.TP 8
+Craig Struble, \fIcstruble@acm.vt.edu\fP
+.\" Video7 SVGA driver
+Video7 SVGA ¥É¥é¥¤¥Ð¡£
+.TP 8
+Gertjan Akkerman, \fIakkerman@dutiba.twi.tudelft.nl\fP
+.\" 16 colour VGA server, and XF86Config parser.
+16 ¿§ VGA ¥µ¡¼¥Ð¤È XF86Config ¹½Ê¸²òÀÏ¥×¥í¥°¥é¥à¡£
+.TP 8
+Davor Matic, \fIdmatic@Athena.MIT.EDU\fP
+.\" Hercules driver.
+Hercules ¥É¥é¥¤¥Ð¡£
+.TP 8
+Pascal Haible, \fIhaible@izfm.uni-stuttgart.de\fP
+.\" Banked monochrome VGA support, Hercules support, and mono frame buffer
+.\" support for dumb monochrome devices
+¥Ð¥ó¥¯ÀÚ¤êÂØ¤¨ÉÕ¤­Çò¹õ VGA ¤ÎÊݼ顢Hercules ¤ÎÊݼ顢ÉáÄ̤ÎÇò¹õ¥Ç¥Ð¥¤¥¹ÍѤÎ
+Çò¹õ¥Õ¥ì¡¼¥à¥Ð¥Ã¥Õ¥¡¤ÎÊݼ顣
+.PP
+.\" ... and many more people out there on the net who helped with beta-testing
+.\" this enhancement.
+ ... ¤½¤·¤Æ¤³¤Îµ¡Ç½³ÈÄ¥¤Î¥Ù¡¼¥¿¥Æ¥¹¥È¤Ç½õ¤±¤Æ¤¤¤¿¤À¤¤¤¿¥¤¥ó¥¿¡¼¥Í¥Ã¥È¾å¤Î
+ ¤è¤ê¿¤¯¤Î³§ÍÍ¡£
+.PP
+.\" \fIXFree86\fP source is available from the FTP server
+.\" \fIftp.XFree86.org\fP, among others. Send email to
+.\" \fIXFree86@XFree86.org\fP for details.
+\fIXFree86\fP ¤Î¥½¡¼¥¹¤Ï \fIftp.XFree86.org\fP ¤Î FTP ¥µ¡¼¥Ð¡¢¤½¤Î¾¤Ë
+¤¢¤ê¤Þ¤¹¡£¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï \fIXFree86@XFree86.org\fP ¤ØÅŻҥ᡼¥ë¤ò²¼¤µ¤¤¡£
+.\" $XConsortium: XFree86.man /main/16 1996/01/31 10:56:20 kaleb $
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/1st.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/1st.sgml
new file mode 100644
index 000000000..b67b234d5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/1st.sgml
@@ -0,0 +1,104 @@
+<!doctype linuxdoc system>
+
+<article>
+
+<!-- Title information -->
+<title> XFree86 PC98 General Information
+<author> The XFree86 Project Inc. / X98 CORE TEAM
+<date> 1999ǯ 7·î 19Æü
+
+<sect> ¤Ï¤¸¤á¤Ë<p>
+XFree86¤Ï¡¢NEC PC98¤ª¤è¤Ó¸ß´¹µ¡¤Çưºî¤¹¤ëFreeBSD(98)¡¢NetBSD/pc98
+(based on NetBSD 1.3.2)°Ê¹ß¡¢PANIX Ver.5.0 for 98¡¢Linux/98¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£
+PC98¤Î¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤ÏXFree86¤Î¥½¡¼¥¹¥Ä¥ê¡¼¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¡¢¤½¤Î³«È¯¤È¥³¡¼¥É
+¤ÎÊݼé¤Ï¡¢The XFree86 Project Inc¤ÈX98 CORE TEAM¤¬¹Ô¤Ã¤Æ¤¤¤Þ¤¹¡£</p>
+
+<p>PC98Íѥɥ­¥å¥á¥ó¥È¤Ç¤Ï¡¢¼ç¤ËPC98ÆÃÍ­¤Î»ö¹à¤Ë¤Ä¤¤¤ÆÀâÌÀ¤·¤Þ¤¹¡£
+¤½¤Î¾¤Î»ö¤Ë¤Ä¤¤¤Æ¤Ï¡¢PC/AT¸ß´¹µ¡ÈǤȤζ¦Ḁ̈ɥ­¥å¥á¥ó¥È¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡£
+¿¤¯¤Î¥É¥­¥å¥á¥ó¥È¤¬ÆüËܸ첽¤µ¤ì¤Æ¤¤¤Þ¤¹¤Î¤Ç¡¢¤½¤ì¤é¤ò»²¾È¤¹¤ë»ö¤ò
+¤ª´«¤á¤·¤Þ¤¹¡£</p>
+
+<sect>¾ðÊ󸻡¿Ï¢ÍíÀè<p>
+
+XFree86¤ÎÁí¹çŪ¤Ê¥µ¥Ý¡¼¥È¤Ë¤Ä¤¤¤Æ¤Ï¡¢<it/&lt;XFree86@XFree86.Org&gt;/
+¤Ø±Ñ¸ì¤Ç¥³¥ó¥¿¥¯¥È¤·¤Æ²¼¤µ¤¤¡£PC98ÆÃÍ­¤ÎÌäÂê¤Ë¤Ä¤¤¤Æ¤Ï¡¢ÆüËܸì¤Ç
+³«È¯¼Ô¥á¡¼¥ê¥ó¥°¥ê¥¹¥È<it/&lt;x98@mech.titech.ac.jp&gt;/¤Ø¥³¥ó¥¿¥¯¥È¤·¤Æ
+²¼¤µ¤¤¡£</p>
+
+<p> ưºîÊó¹ð¤ä¥Ð¥°¾ðÊ󡢥ѥåÁ¤Ê¤É¤Ï̵¾ò·ï¤Ë´¿·Þ¤¤¤¿¤·¤Þ¤¹¤Î¤Ç¡¢µ¹¤·¤¯¤ª´ê¤¤
+¤¤¤¿¤·¤Þ¤¹¡£format ¤ÏÌ䤤¤Þ¤»¤ó¤¬¡¢¥É¥­¥å¥á¥ó¥È¤Ëµ­½Ò¤¬¤¢¤ëÆâÍÆ¤Ë¤Ä¤¤¤Æ¤Î
+¼ÁÌäÅù¤Ï¤´±óθ²¼¤µ¤¤¡£</p>
+
+<p>NetNews¤Îfj.windows.x¡¢fj.os.bsd.*¡¢NIFTY-SERVE(FUNIX, FEPSONX, SAISAP)¡¢
+PC-VAN(JUNIX, JSPUNIX)¡¢FreeBSD-users-jp ML¡¢FreeBSD kit ML¡¢FreeBSD98-testers
+ML¡¢FreeBSD98-hackers ML¡¢seraphim-bugs ML¡¢seraphim-beta ML¤Ç¿¤¯¤ÎµÄÏÀ¡¢
+¼Áµ¿±þÅú¤¬¹Ô¤ï¤ì¤Æ¤¤¤Þ¤¹¡£PC98¤Ë¤Ä¤¤¤Æ¤Î¾ðÊó¤Ë¤Ä¤¤¤Æ¤Ï¤³¤ì¤é¤Î¾ì¤ÇÄó¶¡
+¤·¤Þ¤¹¤Î¤Ç¡¢»²²Ã¤¹¤ë»ö¤ò¤ª´«¤á¤·¤Þ¤¹¡£</p>
+
+<sect> PC98¸ÇÍ­¤Î¥É¥­¥å¥á¥ó¥È<p>
+<itemize>
+ <ITEM>README98.1st ³µÍ×(¤³¤Î¥Õ¥¡¥¤¥ë)
+ <ITEM>README98 PC98¤Ë´Ø¤¹¤ëÀâÌÀ
+ <ITEM>XF86Config.98 ɸ½àŪ¤ÊPC98ÍÑXF86Config
+ <ITEM>VideoBoard98 Âбþ¥Ó¥Ç¥ª¥Ü¡¼¥É¤Ë´Ø¤¹¤ë¾ðÊó
+</itemize>
+
+<sect>¥¯¥ì¥¸¥Ã¥È<p>
+ PC98ÍÑ¥³¡¼¥É¤ÏThe XFree86 Project Inc¤È°Ê²¼¤ÎX98 CORE TEAM¡¢¤ª¤è¤Ó
+ ¤½¤Î¾¤Î¶¨ÎϼԤˤè¤êºîÀ®¤µ¤ì¤Þ¤·¤¿¡£
+
+<p>X98 CORE TEAM
+<itemize>
+ <ITEM>²ñÄÅ ¹¨¹¬<it/&lt;aizu@jaist.ac.jp&gt;/
+ <ITEM>ÀÐÅÄ ÏÂÀ¸<it/&lt;ishidakz@obp.cl.nec.co.jp&gt;/
+ <ITEM>»ÔÀî ¹¯¹À<it/&lt;cs94006@mbox.sist.ac.jp&gt;/
+ <ITEM>°ËÆ£ ÏÂͺ<it/&lt;ft4k-itu@asahi-net.or.jp&gt;/
+ <ITEM>¾åÌî ϵª<it/&lt;jagarl@creator.club.or.jp&gt;/
+ <ITEM>¾åÌî ½¤°ì<it/&lt;uenos@ppp.bekkoame.or.jp&gt;/
+ <ITEM>±§Ìî ÏÂɧ<it/&lt;Kazuhiko.Uno@softvision.co.jp&gt;/
+ <ITEM>±ºÅÄ ½¤°ìϺ<it/&lt;s-urata@nmit.tmg.nec.co.jp&gt;/
+ <ITEM>ÂçÀÐ ·®<it/&lt;ohishi@hf.rim.or.jp&gt;/
+ <ITEM>ÂçÀÐ ¹ÀÆó<it/&lt;atena@njk.co.jp&gt;/
+ <ITEM>³Ý»¥ ůÌé<it/&lt;kakefuda@tag.iijnet.or.jp&gt;/
+ <ITEM>²ÃÆ£ ¹¯Ç·<it/&lt;yasuyuki@acaets0.anritsu.co.jp&gt;/
+ <ITEM>ÌÚ¼ Áï<it/&lt;KFB03633@nifty.ne.jp&gt;/
+ <ITEM>¾®ÃÓ Ã£Ìé<it/&lt;koiket@focus.rim.or.jp&gt;/
+ <ITEM>H.Komatsuzaki
+ <ITEM>ºäËÜ ¿ò<it/&lt;sakamoto@yajima.kuis.kyoto-u.ac.jp&gt;/
+ <ITEM>º´µ×´Ö ½ß<it/&lt;i931361@jks.is.tsukuba.ac.jp&gt;/
+ <ITEM>¿ÀÊÝ Æ»É×<it/&lt;karl@spnet.ne.jp&gt;/
+ <ITEM>ÎëÌÚ ¹§°ìϺ<it/&lt;s-koichi@nims.nec.co.jp&gt;/
+ <ITEM>ÎëÌÚ Ãθ«<it/&lt;suzuki@grelot.elec.ryukoku.ac.jp&gt;/
+ <ITEM>ÎëÌÚ ¹¯»Ê<it/&lt;suz@d2.bs1.fc.nec.co.jp&gt;/
+ <ITEM>Âì¾å ÉÙÀ²<it/&lt;takigami@elsd.mt.nec.co.jp&gt;/
+ <ITEM>ÄÍÅÄ ¹äʸ<it/&lt;tsuka@linkt.imasy.or.jp&gt;/
+ <ITEM>±ÊÈø Ä÷·¼<it/&lt;nagao@cs.titech.ac.jp&gt;/
+ <ITEM>ÌîÅÄ Ì­<it/&lt;mnoda@cv.tottori-u.ac.jp&gt;/
+ <ITEM>Ìî¼ ¹âÌÀ<it/&lt;amadeus@yk.rim.or.jp&gt;/
+ <ITEM>Æ£±º Ë­ÆÁ<it/&lt;toyo@ibbsal.or.jp&gt;/
+ <ITEM>ËÜ¿ ¾°Ê¸<it/&lt;honda@Kururu.math.hokudai.ac.jp&gt;/
+ <ITEM>¿¹ÅÄ ¾¼É×<it/&lt;amorita@bird.scphys.kyoto-u.ac.jp&gt;/
+ <ITEM>Ȭ¿§ ¿­°ì<it/&lt;QZR00522@nifty.ne.jp&gt;/
+ <ITEM>ȬÌÚ ½Óɧ<it/&lt;j2297222@ed.kagu.sut.ac.jp&gt;/
+ <ITEM>°ÂÅÄ À»<it/&lt;yasuda@cc.hit-u.ac.jp&gt;/
+</itemize>
+<p>¤½¤Î¾¤Î¶¨ÎϼÔ
+<itemize>
+ <ITEM>»³ËÜ ¹À(x98MLµì´ÉÍý¼Ô)
+ <ITEM>ÃæÅç µá(x98ML´ÉÍý¼Ô)
+ <ITEM>µÈÅÄ Àµ¿Í(PowerWindow805iÂбþ¥³¡¼¥ÉÄó¶¡)
+ <ITEM>»°±º ÆØ»Ê(PW928IIÂßÍ¿)
+ <ITEM>À¾ÄÍ Çîʸ(Linux/98Âбþ)
+ <ITEM>°æ°Ë μÂÀ(Ʊ¾å)
+ <ITEM>PC-VAN(JUNIX, JSPUNIX), NIFTY-SERVE(FUNIX, FEPSONX, SAISAP),
+ fj, x98 ML, FreeBSD-users-jp ML, FreeBSD kit ML, FreeBSD98-testers ML,
+ FreeBSD98-hackers ML, seraphim-bugs ML, seraphim-beta ML ¤ÇưºîÊó¹ð
+ ¤ò¤¯¤À¤µ¤Ã¤¿Êý¡¹
+ <ITEM>µþÂç¥Þ¥¤¥³¥ó¥¯¥é¥Ö
+ <ITEM>FreeBSD PC98°Ü¿¢¥Á¡¼¥à
+ <ITEM>NetBSD/pc98 Core Team
+ <ITEM>¥¨¡¼¡¦¥¢¥¤¡¦¥½¥Õ¥È³ô¼°²ñ¼Ò
+</itemize>
+ ¡¡¡¡
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/CPYRIGHT.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/CPYRIGHT.sgml
new file mode 100644
index 000000000..395c4ac5e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/CPYRIGHT.sgml
@@ -0,0 +1,267 @@
+<!doctype linuxdoc system>
+
+<article>
+<title> XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò Ãøºî¸¢É½¼¨</title>
+<Author> XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò
+<trans> ²¬ËÜ¡¡°ì¹¬ Kazuyuki Okamoto &lt;ikko-@pacific.rim.or.jp&gt;
+<p>
+<sect>XFree86 Ãøºî¸¢É½¼¨
+<p>
+Ãøºî¸¢¤¬ÌÀ¼¨¤µ¤ì¤Æ¤¤¤ë¥×¥í¥°¥é¥à¤ò½ü¤¤¤Æ XFree86 ¤Î¥×¥í¥°¥é¥à¤Ï¼¡¤ÎÃøºî¸¢¤ò
+Í­¤¹¤ë:
+
+<p>
+Copyright (C) 1994, 1995, 1996 The XFree86 Project, Inc. All Rights Reserved.
+
+̵ÎÁ¤Ç¡¢Ã¯¤â¤¬¤³¤Î¥½¥Õ¥È¥¦¥§¥¢¤È´ØÏ¢¤¹¤ëʸ½ñ¥Õ¥¡¥¤¥ë¡Ê°Ê¹ß¤Þ¤È¤á¤Æ
+``¤½¤Õ¤È¤¦¤§¤¢'' ¤È¸Æ¤Ö¡Ë¤òÆþ¼ê¤¹¤ë»ö¡¢»ÈÍѸ¢¡¢Ê£¼Ì¸¢¡¢
+Êѹ¹¸¢¡¢Ê»¹ç¸¢¡¢½ÐÈǸ¢¡¢ÇÛÉÕ¸¢¡¢ºÆ¼Â»ÜµöÂú¸¢ ¤«¤Ä/¤Þ¤¿¤Ï ``¤½¤Õ¤È¤¦¤§¤¢''
+¤ÎÈÎÇ丢¤ò´Þ¤ó¤ÇÀ©Ìó̵¤·¤Ç¼è¤ê°·¤¦»ö¡¢``¤½¤Õ¤È¤¦¤§¤¢'' ¤òÀ©¸Â̵¤·¤Ç
+¶¡µë¤¹¤ë¿Í¤òµö²Ä¤¹¤ë»ö¡¢¤ò°Ê²¼¤Î¾ò·ïÉÕ¤­¤Ç¡¢¤³¤³¤Ë¾µÇ§¤¹¤ë¡£
+
+¾åµ­¤ÎÃøºî¸¢¹ð¼¨¤È¤³¤Îǧ²Ä¹ð¼¨¤ò ``¤½¤Õ¤È¤¦¤§¤¢'' ¤ÎÁ´¤Æ
+¤Þ¤¿¤Ï¡¢½ÅÍפÊÉôʬ¤È¶¦¤ËÃÖ¤¯»ö¡£
+
+
+Ç¡²¿¤Ê¤ë¼ïÎà¡¢·ÁÍÆ¡¢°ÕÌ£¤Ç¤â¡¢¾¦Éʲ½¤Î²ÄǽÀ­µÚ¤Ó¡¢ÆÃÄê¤ÎÌÜŪ¤«¤É¤¦¤«¡¢
+È󿯳²¤«Èݤ«¤ÎÊݾÚ̵¤·¤Ë¡¢``¤½¤Õ¤È¤¦¤§¤¢'' ¤ò ``¤¢¤ë¤¬¤Þ¤Þ''
+¤Î·Á¤Ç¶¡µë¤·¤Þ¤¹¡£Í׵ᡢ»³²¤ä¤½¤Î¾¤ÎÀÕǤµÚ¤ÓÇ¡²¿¤Ê¤ë·ÀÌó¤Î¼Â¹Ô¤äÉÔÀµ¹Ô°Ù¡¢
+``¤½¤Õ¤È¤¦¤§¤¢'' ¤Ë´ØÏ¢¤¬Í­¤Ã¤Æ¤â̵¤¯¤Æ¤âÀ¸¤¸¤¿¸½¾Ý¡¢Ëô¤Ï
+``¤½¤Õ¤È¤¦¤§¤¢'' ¤Î»ÈÍÑ·ë²Ì¤ä¾¤Î¼è¤ê°·¤¤·ë²Ì¤Ë¤Ä¤¤¤Æ¡¢¤É¤ó¤Êº³ºÙ¤Ê
+¤³¤È¤Ç¤â XFree86 ¥×¥í¥¸¥§¥¯¥È¤Ë¤ÏÀÕǤ¤¬¤¢¤ê¤Þ¤»¤ó¡£
+
+
+¤³¤Î¹ð¼¨¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë»ö¤ò½ü¤¤¤Æ¡¢ ``¤½¤Õ¤È¤¦¤§¤¢'' ¤ò XFree86
+¥×¥í¥¸¥§¥¯¥È¤Î̾¤Î²¼¤Ë¹­¹ð¤·¤¿¤ê¡¢ XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤«¤é°ÊÁ°¤Ëȯ¹Ô¤·¤¿
+µö²Ä½ñ̵¤·¤Ë¾¼Ô¤¬ ``¤½¤Õ¤È¤¦¤§¤¢'' ¤òÈÎÇä¡¢»ÈÍÑ¡¢¼è¤ê°·¤¤¤ò´«Í¶¤¹¤ë
+¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+
+<sect>¤½¤Î¾¤ÎÃøºî¸¢É½¼¨<p>
+<!--Portions of code are covered by the following copyrights:-->
+°ìÉô¤Î¥×¥í¥°¥é¥à¤Ï¼¡¤ÎÃøºî¸¢¤òÍ­¤¹¤ë:
+
+<sect1>X ¥³¥ó¥½¡¼¥·¥¢¥à
+<p>
+Copyright (C) 1996 X Consortium
+
+
+̵ÎÁ¤Ç¡¢Ã¯¤â¤¬¤³¤Î¥½¥Õ¥È¥¦¥§¥¢¤È´ØÏ¢¤¹¤ëʸ½ñ¥Õ¥¡¥¤¥ë¡Ê°Ê¹ß¤Þ¤È¤á¤Æ
+``¤½¤Õ¤È¤¦¤§¤¢'' ¤È¸Æ¤Ö¡Ë¤òÆþ¼ê¤¹¤ë»ö¡¢»ÈÍѸ¢¡¢Ê£¼Ì¸¢¡¢
+Êѹ¹¸¢¡¢Ê»¹ç¸¢¡¢½ÐÈǸ¢¡¢ÇÛÉÕ¸¢¡¢ºÆ¼Â»ÜµöÂú¸¢ ¤«¤Ä/¤Þ¤¿¤Ï ``¤½¤Õ¤È¤¦¤§¤¢''
+ ¤ÎÈÎÇ丢¤ò´Þ¤ó¤ÇÀ©Ìó̵¤·¤Ç¼è¤ê°·¤¦»ö¡¢``¤½¤Õ¤È¤¦¤§¤¢'' ¤òÀ©¸Â̵¤·¤Ç
+¶¡µë¤¹¤ë¿Í¤òµö²Ä¤¹¤ë»ö¡¢¤ò¼¡¤Î¾ò·ïÉÕ¤­¤Ç¡¢¤³¤³¤Ë¾µÇ§¤¹¤ë¡£
+
+¾åµ­¤ÎÃøºî¸¢¹ð¼¨¤È¤³¤Îǧ²Ä¹ð¼¨¤ò ``¤½¤Õ¤È¤¦¤§¤¢'' ¤ÎÁ´¤Æ
+¤Þ¤¿¤Ï¡¢½ÅÍפÊÉôʬ¤È¶¦¤ËÃÖ¤¯»ö¡£
+
+
+Ç¡²¿¤Ê¤ë¼ïÎà¡¢·ÁÍÆ¡¢°ÕÌ£¤Ç¤â¡¢¾¦Éʲ½¤Î²ÄǽÀ­µÚ¤Ó¡¢ÆÃÄê¤ÎÌÜŪ¤«¤É¤¦¤«¡¢
+È󿯳²¤«Èݤ«¤ÎÊݾÚ̵¤·¤Ë¡¢``¤½¤Õ¤È¤¦¤§¤¢'' ¤ò ``¤¢¤ë¤¬¤Þ¤Þ''
+¤Î·Á¤Ç¶¡µë¤·¤Þ¤¹¡£Í׵ᡢ»³²¤ä¤½¤Î¾¤ÎÀÕǤµÚ¤ÓÇ¡²¿¤Ê¤ë·ÀÌó¤Î¼Â¹Ô¤äÉÔÀµ¹Ô°Ù¡¢
+``¤½¤Õ¤È¤¦¤§¤¢'' ¤Ë´ØÏ¢¤¬Í­¤Ã¤Æ¤â̵¤¯¤Æ¤âÀ¸¤¸¤¿¸½¾Ý¡¢Ëô¤Ï
+``¤½¤Õ¤È¤¦¤§¤¢'' ¤Î»ÈÍÑ·ë²Ì¤ä¾¤Î¼è¤ê°·¤¤·ë²Ì¤Ë¤Ä¤¤¤Æ¡¢¤É¤ó¤Êº³ºÙ¤Ê
+¤³¤È¤Ç¤â X ¥³¥ó¥½¡¼¥·¥¢¥à¼Ò¤Ë¤ÏÀÕǤ¤¬¤¢¤ê¤Þ¤»¤ó¡£
+
+
+¤³¤Î¹ð¼¨¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë»ö¤ò½ü¤¤¤Æ¡¢ ``¤½¤Õ¤È¤¦¤§¤¢'' ¤ò X ¥³¥ó¥½¡¼¥·¥¢¥à¼Ò
+¤Î̾¤Î²¼¤Ë¹­¹ð¤·¤¿¤ê¡¢ X ¥³¥ó¥½¡¼¥·¥¢¥à¼Ò¤«¤é°ÊÁ°¤Ëȯ¹Ô¤·¤¿
+µö²Ä½ñ̵¤·¤Ë¾¼Ô¤¬ ``¤½¤Õ¤È¤¦¤§¤¢'' ¤òÈÎÇä¡¢»ÈÍÑ¡¢¼è¤ê°·¤¤¤ò´«Í¶¤¹¤ë
+¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+
+X ¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à ¤Ï X ¥³¥ó¥½¡¼¥·¥¢¥à¼Ò¤Î¾¦É¸¤Ç¤¹¡£
+
+<!--<sect1>Berkeley-based copyrights:-->
+<sect1>Berkeley ¤Ë´ð¤Å¤¯Ãøºî¸¢:
+<p>
+<!--<sect2>General-->
+<sect2>°ìÈÌ
+<p>
+<!--Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:-->
+ºÆÇÛÉÛ¤ÈÊѹ¹¤Î¤¢¤ê¤Ê¤·¤Ë°ø¤é¤Ê¤¤¥½¡¼¥¹¤È¥Ð¥¤¥Ê¥ê¤Î·ÁÂ֤Ǥα¿ÍѤò¼¡¤Î
+¾ò·ïÉÕ¤­¤Çµö²Ä¤¹¤ë:
+
+<enum>
+<!--<item>Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.-->
+<item>¥½¡¼¥¹¤ÎºÆÇÛÉۤˤ¢¤¿¤ê¾åµ­¤ÎÃøºî¸¢É½¼¨¤È¤³¤Î¾ò·ïʸ¤Î°ìÍ÷¤È°Ê¹ß¤Î
+ Êü´þÀë¸À¤òÊÝ»ý¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
+<!--<item>Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.-->
+<item>¥Ð¥¤¥Ê¥ê·Á¼°¤ÎºÆÇÛÉۤˤ¢¤¿¤ê¾åµ­¤ÎÃøºî¸¢É½¼¨¤È¤³¤Î¾ò·ïʸ¤Î°ìÍ÷¤È
+ °Ê¹ß¤Îʸ½ñ¤ÎÊü´þÀë¸ÀµÚ¤Ó/¤Þ¤¿¤Ï ÇÛÉÛʪ¤ËÉÕ°¤¹¤ëʸ½ñ¤òžºÜ¤·¤Ê¤±¤ì¤Ð¤Ê¤é
+¤Ê¤¤¡£
+<!--<item>The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.-->
+<item>Ãøºî¼Ô¤Î̾Á°¤ÏÌÀ³Î¤Ë°ÊÁ°¤Ëȯ¹Ô¤·¤¿µö²Ä½ñ̵¤·¤Ë¤³¤Î¤½¤Õ¤È¤¦¤§¤¢¤«¤é
+ÇÉÀ¸¤·¤¿¤â¤Î¤ò΢½ñ¤­¤·¤¿¤êÂ¥¿Ê¤¹¤ë¤â¤Î¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+</enum>
+
+<!-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.-->
+Ç¡²¿¤Ê¤ë·ÁÍÆ¡¢°ÕÌ£¤Ç¤â¡¢¾¦Éʲ½¤Î²ÄǽÀ­¤òÀ©¸Â¤»¤ºµÚ¤Ó¡¢ÆÃÄê¤ÎÌÜŪ¤ËŬ¹ç¤¹¤ë¤«
+¤É¤¦¤«
+¤ÎÊݾڤòÊü´þ¤·¤Æ¡¢``¤½¤Õ¤È¤¦¤§¤¢'' ¤ò ``¤¢¤ë¤¬¤Þ¤Þ'' ¤Î·Á¤ÇÃøºî¼Ô¤¬¶¡µë¤·¤Þ¤¹¡£
+ľÀÜŪ¡¢´ÖÀÜŪ¡¢¸Î°Õ¡¢ÆÃÊÌ¡¢ÌÏÈÏŪ¡¢É¬Á³ÅªÂ»³²¡ÊÀ©¸Â¤Î¤Ê¤¤ÂåÂØÊª¤ä¥µ¡¼¥Ó¥¹¡¢
+²ÄÍÑÀ­¤ÎÄã²¼¤ä¥Ç¡¼¥¿¤äÍø±×¤Î»¼º¤Þ¤¿¤Ï±Ä¶È˸³²¤ò´Þ¤à¡Ë¤¬À¸¤¸¤Æ¤â¡¢
+¤½¤Î¾¤ÎÀÕǤµÚ¤ÓÇ¡²¿¤Ê¤ë·ÀÌó¤Î¼Â¹Ô¡¢´°Á´¤ÊºÄ̳¤äÉÔÀµ¹Ô°Ù¡ÊÉÔÃí°Õ¤Ë¤è¤ë»ö¸ÎÅù
+¤ò´Þ¤à¡Ë¡¢
+²¾¤Ë»³²¤Î²ÄǽÀ­¤¬¤¢¤Ã¤Æ¤â``¤½¤Õ¤È¤¦¤§¤¢'' ¤Î»ÈÍÑ·ë²Ì¤Ë¤Ä¤¤¤Æ¡¢Ãøºî¼Ô¤Ë¤ÏÀÕǤ¤¬
+¤¢¤ê¤Þ¤»¤ó¡£
+
+<sect2>UCB/LBL
+<p>
+ Copyright (c) 1993
+ The Regents of the University of California. All rights reserved.
+
+<!-- This software was developed by the Computer Systems Engineering group
+ at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ contributed to Berkeley.-->
+¤³¤Î¥½¥Õ¥È¥¦¥§¥¢¤Ï DARPA ·ÀÌóÈÖ¹æ BG 91-66 ¤Ë´ð¤Å¤­
+ Lawrence Berkeley Laboratory ¤Î Computer Systems Engineering ¥°¥ë¡¼¥×¤¬
+³«È¯¤· Berkeley ¤Ë´óÉÕ¤·¤Þ¤·¤¿¡£
+
+<!-- All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ This product includes software developed by the University of
+ California, Lawrence Berkeley Laboratory.-->
+ÆÃħ¤ò½Ò¤Ù¤Æ¤¤¤ëÁ´¤Æ¤ÎÀëÅÁºàÎÁ¤È¤³¤Î¥½¥Õ¥È¥¦¥§¥¢¤ò»È¤¦¤Èɬ¤º¼¡¤Î¼Õ°Õ¤Î¥á¥Ã¥»
+¡¼¥¸¤ò
+ɽ¼¨¤·¤Þ¤¹¡£
+ This product includes software developed by the University of
+ California, Lawrence Berkeley Laboratory.
+
+<!-- Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:-->
+Êѹ¹¤Î̵ͭ¤Ë¤«¤«¤ï¤é¤ººÆÇÛÉۤȥ½¡¼¥¹¤È¥Ð¥¤¥Ê¥ê·Á¼°¤ÎÍøÍѤò¼¡¤Î¾ò·ï¤Ë½¾¤Ã¤Æ
+ǧ¤á¤ë:
+
+<enum>
+<!--<item>Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.-->
+<item>¥½¡¼¥¹¥×¥í¥°¥é¥à¤ÎºÆÇÛÉۤϾ嵭¤ÎÃøºî¸¢É½¼¨¤È¤³¤Î¾ò·ï°ìÍ÷¤È¼¡¤ÎÊü´þÀë¸À¤ò
+ɬ¤ºÊÝ»ý¤¹¤ë¤³¤È¡£
+<!--<item>Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.-->
+<item>¥Ð¥¤¥Ê¥ê·Á¼°¤ÎºÆÇÛÉۤϾ嵭¤ÎÃøºî¸¢É½¼¨¤È¤³¤Î¾ò·ï°ìÍ÷¤È
+¼¡¤ÎÊü´þÀë¸À¤òɬ¤ºÊ¸½ñ¤È¤·¤ÆÊÝ»ý¤¹¤ë¤«Ëô¤ÏÇÛÉÛʪ¤Ë´Þ¤á¤ÆÄ󶡤¹¤ë¤³¤È¡£
+<!--<item>All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:-->
+<item>ÆÃħ¤ò½Ò¤Ù¤Æ¤¤¤ëÁ´¤Æ¤ÎÀëÅÁºàÎÁ¤È¤³¤Î¥½¥Õ¥È¥¦¥§¥¢¤ò»È¤¦¤Èɬ¤º¼¡¤Î
+¼Õ°Õ¤Î¥á¥Ã¥»¡¼¥¸¤òɽ¼¨¤·¤Þ¤¹¡£
+ This product includes software developed by the University of
+ California, Berkeley and its contributors.
+<!--<item>Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.-->
+<item>Âç³Ø¤Î̾Á°¤ä´óÉÕ¼Ô¤Î̾Á°¤Î¤É¤Á¤é¤â¤³¤Î¥½¥Õ¥È¥¦¥§¥¢¤«¤é
+ÌÀ³Î¤Ê°ÊÁ°¤Ëȯ¹Ô¤·¤¿µö²Ä½ñ̵¤·¤ËÇÉÀ¸¤·¤¿¤â¤Î¤ò΢½ñ¤­¤·¤¿¤êÂ¥¿Ê¤¹¤ë¤â¤Î¤Ç¤Ï¤¢
+¤ê¤Þ¤»¤ó¡£
+</enum>
+
+<!-- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.-->
+Ç¡²¿¤Ê¤ë·ÁÍÆ¡¢°ÕÌ£¤Ç¤â¡¢¾¦Éʲ½¤Î²ÄǽÀ­¤òÀ©¸Â¤»¤ºµÚ¤Ó¡¢ÆÃÄê¤ÎÌÜŪ¤ËŬ¹ç¤¹¤ë¤«
+¤É¤¦¤«
+¤ÎÊݾڤòÊü´þ¤·¤Æ¡¢``¤½¤Õ¤È¤¦¤§¤¢'' ¤ò ``¤¢¤ë¤¬¤Þ¤Þ'' ¤Î·Á¤ÇÃøºî¼Ô¤¬¶¡µë¤·¤Þ¤¹¡£
+ľÀÜŪ¡¢´ÖÀÜŪ¡¢¸Î°Õ¡¢ÆÃÊÌ¡¢ÌÏÈÏŪ¡¢É¬Á³ÅªÂ»³²¡ÊÀ©¸Â¤Î¤Ê¤¤ÂåÂØÊª¤ä¥µ¡¼¥Ó¥¹¡¢
+²ÄÍÑÀ­¤ÎÄã²¼¤ä¥Ç¡¼¥¿¤äÍø±×¤Î»¼º¤Þ¤¿¤Ï±Ä¶È˸³²¤ò´Þ¤à¡Ë¤¬À¸¤¸¤Æ¤â¡¢
+¤½¤Î¾¤ÎÀÕǤµÚ¤ÓÇ¡²¿¤Ê¤ë·ÀÌó¤Î¼Â¹Ô¡¢´°Á´¤ÊºÄ̳¤äÉÔÀµ¹Ô°Ù¡ÊÉÔÃí°Õ¤Ë¤è¤ë»ö¸ÎÅù
+¤ò´Þ¤à¡Ë¡¢
+²¾¤Ë»³²¤Î²ÄǽÀ­¤¬¤¢¤Ã¤Æ¤â``¤½¤Õ¤È¤¦¤§¤¢'' ¤Î»ÈÍÑ·ë²Ì¤Ë¤Ä¤¤¤Æ¡¢Ãøºî¼Ô¤Ë¤ÏÀÕǤ¤¬
+¤¢¤ê¤Þ¤»¤ó¡£
+
+<sect1>NVidia Corp
+<sect1>NVidia ¼Ò
+<p>
+ Copyright (c) 1996 NVIDIA, Corp. All rights reserved.
+
+<!-- NOTICE TO USER: The source code is copyrighted under U.S. and
+ international laws. NVIDIA, Corp. of Sunnyvale, California owns
+ the copyright and as design patents pending on the design and
+ interface of the NV chips. Users and possessors of this source
+ code are hereby granted a nonexclusive, royalty-free copyright
+ and design patent license to use this code in individual and
+ commercial software.-->
+ »ÈÍѼԤؤÎÃí°Õ: ¥½¡¼¥¹¥×¥í¥°¥é¥à¤Ï¥¢¥á¥ê¥«¤ÎˡΧ¤È¹ñºÝË¡¤ÇÃøºî¸¢¤¬Êݸî
+ ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£California ½£¡¢Sunnyvale ¤Ë¤¢¤ë NVIDIA ¼Ò¤¬Ãøºî¸¢¤ò
+ ÊÝÍ­¤·¤Æ¤¤¤Æ NV ¥Á¥Ã¥×¤ÎÀ߷פȥ¤¥ó¥¿¥Õ¥§¡¼¥¹¤ÎÀß·×ÆÃµö¤òÊÝÍ­¤·¤Æ¤¤¤Þ¤¹¡£
+ ¤³¤Î¥½¡¼¥¹¥×¥í¥°¥é¥à¤Î»ÈÍѼԤȽêÍ­¼Ô¤Ï¤½¤Î¤Þ¤Þ¤Ç¤Ï¼Â¹Ô¤Ç¤­¤Ê¤¯¡¢
+ ¸Ä¿ÍÍѤȾ¦ÍÑ¥½¥Õ¥È¥¦¥§¥¢¤Ç¤Ï»ÈÍÑÎÁ¤Î¤¤¤é¤Ê¤¤Ãøºî¸¢¤ÈÆÃµö¸¢¤ò»ý¤Ã¤Æ¤¤¤Þ¤¹¡£
+
+<!-- Any use of this source code must include, in the user documentation
+ and internal comments to the code, notices to the end user
+ as follows:-->
+ ¤³¤Î¥½¡¼¥¹¥×¥í¥°¥é¥à¤òÇ¡²¿¤Ê¤ë·ÁÂ֤ǻȤ¦¤È¤·¤Æ¤â¥æ¡¼¥¶ÍÑʸ½ñ¤È¥×¥í¥°¥é¥à
+ ÆâÉô¤Î¥³¥á¥ó¥È¤È¥¨¥ó¥É¥æ¡¼¥¶ÍÑʸ½ñ¤Ë¼¡¤Îʸ¤¬´Þ¤Þ¤ì¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+
+ Copyright (c) 1996 NVIDIA, Corp. NVIDIA design patents pending
+ in the U.S. and foreign countries.
+
+<!-- NVIDIA, CORP. MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF
+ THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT
+ EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORP. DISCLAIMS
+ ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, INCLUDING ALL
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA, CORP. BE LIABLE
+ FOR ANY SPECIAL, INDIRECT, INCIDENTAL, 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 SOURCE CODE.-->
+ NVIDIA ¼Ò ¤ÏÇ¡²¿¤Ê¤ëÌÜŪ¤ËŬ¹ç¤¹¤ë¤«¤Ë¤Ä¤¤¤ÆÀÕǤ¤¬¤¢¤ê¤Þ¤»¤ó¡£Ç¡²¿¤Ê¤ë·ÁÍÆ¤ä
+ °ÕÌ£¤Ç¤âÊݾڤʤ·¤Ë ``¤¢¤ë¤¬¤Þ¤Þ'' ¶¡µë¤·¤Þ¤¹¡£NVIDIA ¼Ò ¤ÏÁ´¤Æ¤Î¾¦Éʲ½¤Î
+²ÄǽÀ­
+ µÚ¤Ó¡¢ÆÃÄê¤ÎÌÜŪ¤ËŬ¹ç¤¹¤ë¤«¤É¤¦¤«¤ÎÊݾڤòÊü´þ¤·¤Þ¤¹¡£NVIDIA ¼Ò ¤ÏÆÃÊÌ¡¢
+ ´ÖÀÜŪ¡¢¶öȯŪ¡¢É¬Á³ÅªÂ»³²¡¢¤¿¤È¤¨¤É¤Î¤è¤¦¤Ê²ÄÍÑÀ­¤ÎÄã²¼¤ä¥Ç¡¼¥¿¤äÍø±×¤Î»¼º
+ ¤¬¤¢¤Ã¤Æ¤â¡¢¤Þ¤¿±Ä¶È³èư¤äÉÔÃí°Õ¤Ë¤è¤ë»ö¸Î¤Þ¤¿¤ÏÉÔÀµ¹Ô°Ù¡¢¤³¤Î¥½¡¼¥¹¥×¥í
+¥°¥é¥à
+ ¤ÎÍøÍѤäÀ­Ç½¤Ë¤Ä¤¤¤ÆÄ¾ÀÜ´Ø·¸¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤âÀ¸¤¸¤¿»ö¾Ý¤Ë¤Ä¤¤¤ÆÀÕǤ¤Ï¤¢¤ê
+¤Þ¤»¤ó¡£
+
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/CPYRIGHT.sgml,v 3.2 1997/01/26 04:34:15 dawes Exp $
+</verb>
+<hrule>
+
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ï xc/programs/Xserver/hw/xfree86/doc/sgml/CPYRIGHT.sgml,v 3.6 1
+996/10/10 14:03:59 ¤ò¡¢²¬ËÜ °ì¹¬
+( Kazuyuki Okamoto <url url="mailto:ikko-@pacific.rim.or.jp"
+name="&lt;ikko-@pacific.rim.or.jp&gt;"> ) ¤¬ XFree86 3.2 ¤ò
+ÆüËܤǥ¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¿Í¸þ¤±¤ËÏÂÌõ¤·¤¿¤â¤Î¤Ç¤¹¡£¤³¤³¤¬¤ª¤«¤·¤¤¤È¤«¡¢
+¤³¤³¤Ï¤³¤¦¤·¤¿¤Û¤¦¤¬¤¤¤¤¤È¤¤¤Ã¤¿¤´°Õ¸«¤¬¤¢¤ê¤Þ¤·¤¿¤é¡¢ÅŻҥ᡼¥ë¤Ç
+¤ªÃΤ餻²¼¤µ¤¤¡£
+¸¶Ê¸¤ÎÃøºî¸¢¤Ï XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ÎÏÂÌõ¤ÎÃøºî¸¢¤Ï
+XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤È²¬ËÜ¡¡°ì¹¬¤Ë¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤ÎÏÂÌõ¤ÎÉÔ¶ñ¹ç¤Ï»ä¤Ë¡¢
+ÅŻҥ᡼¥ë¤ÇÁ÷¤Ã¤Æ²¼¤µ¤¤¡£
+<verb>
+Copyright (C) 1995, Kazuyuki (ikko-) Okamoto. All Rights Reserved.
+
+</verb>
+<hrule>
+&lsqb;EOF&rsqb;
+
+</article>
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/Config.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/Config.sgml
new file mode 100644
index 000000000..3b38038aa
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/Config.sgml
@@ -0,0 +1,546 @@
+<!doctype linuxdoc system>
+
+<!-- Id: README.Config.sgml,v 1.1 1994/10/05 23:31:42 klemme Exp -->
+
+ <article>
+
+ <title> XFree86 ¤ÎÀßÄê¤Ë¤Ä¤¤¤Æ
+
+ Ãʳ¬Åª¥¬¥¤¥É
+ <author> David Wexelblat ¤È XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò
+ <date> 1994 ǯ 10 ǯ 05 Æü
+ <trans> ²¬ËÜ¡¡°ì¹¬ Kazuyuki Okamoto &lt;ikko-@pacific.rim.or.jp&gt;
+<abstract>
+¤³¤Îʸ½ñ¤Ï XFree86 ¥µ¡¼¥Ð¡¼¤ò¤É¤¦¤ä¤Ã¤ÆÀßÄꤹ¤ë¤«¤Ë¤Ä¤¤¤Æ¤È¡¢
+<tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤òµ¡´ï¹½À®¤Ë°ìÃפµ¤»¤ë»ö¤Ë¤Ä¤¤¤Æ½ñ¤¤¤Æ¤¤¤Þ¤¹¡£
+¤³¤Îʸ½ñ¤Î¼ê½ç¤É¤ª¤ê¤Ëºî¶È¤¹¤ì¤Ð¡¢ÌäÂê̵¤¯¥µ¡¼¥Ð¡¼¤¬½àÈ÷¤Ç¤­¡¢
+¤¹¤°¤Ë¼Â¹Ô¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
+
+¤³¤Îʸ½ñ¤ÏÈÆÍѤˤʤë¤è¤¦¤ËÀ߷פµ¤ì¤Æ¤¤¤Þ¤¹¡£ÀßÄêÂÐ¾Ý OS ¸ÇÍ­¤Î
+<tt>README</tt> ¥Õ¥¡¥¤¥ë¡ÊÎ㤨¤Ð¡¢
+<tt>README.SVR4</tt>¡Ë¤È¡¢ÀßÄêÂоݥӥǥª¥«¡¼¥É/¥Á¥Ã¥×¥»¥Ã¥È¸ÇÍ­¤Î
+<tt>README</tt>¥Õ¥¡¥¤¥ë¡ÊÎ㤨¤Ð¡¢ <tt>README.trident</tt>¡Ë
+¤òɬ¤º»²¾È¤·¤Æ²¼¤µ¤¤¡£¤³¤ì¤é¸ÇÍ­¤Î¥Õ¥¡¥¤¥ë¤ÈÈÆÍѤˤʤäƤ¤¤ë¥Õ¥¡¥¤¥ë¤È¤Ç
+Ì·½â¤òÀ¸¤¸¤ë¾ì¹ç¤Ï¡ÊÁ´Éô¤Î¾ì¹ç¤¬¤½¤¦¤Ç¤¢¤ë¤È¤Ï¸Â¤ê¤Þ¤»¤ó¤¬¡Ë¡¢
+¸ÇÍ­¤Î¥Õ¥¡¥¤¥ë¤Î¼ê½ç¤Ë½¾¤Ã¤Æ²¼¤µ¤¤¡£
+</abstract>
+
+
+
+<toc>
+
+
+<sect> ¼ê½ç³µÍ×
+<p>
+½àÈ÷¤È¼Â¹Ô¤Ï£²¤Ä¤ÎÃʳ¬¤Ç¹Ô¤Ê¤¤¤Þ¤¹¡£¤Þ¤ººÇ½é¤Ë¡¢»ÈÍѤ·¤¿¤¤Å¬Àڤʥµ¡¼¥Ð¡¼¤ò
+ÁªÂò¤·¤Æ¡¢½é´üÃͤΤޤÞÀßÄꤷ¤Þ¤¹¡£¼¡¤Ë¡¢ <tt>XF86Config</tt>
+¥Õ¥¡¥¤¥ë¤òÀßÄꤷ¤Þ¤¹¡£¤³¤Î¥Õ¥¡¥¤¥ë¤Ï¥µ¡¼¥Ð¡¼¤Ë¡¢²èÌ̻ؼ¨ÁõÃÖ
+¡ÊÎ㤨¤Ð¡¢¥Þ¥¦¥¹¤ä¥È¥é¥Ã¥¯¥Ü¡¼¥ë¡Ë¡¢
+¥Ó¥Ç¥ª¥«¡¼¥É¤ä¥â¥Ë¥¿¡¼Åù¡¢¤½¤Î¾¾¯¤·¤Îµ¡´ï¤Ë¤Ä¤¤¤ÆÀßÄꤹ¤ë¤â¤Î¤Ç¤¹¡£
+
+<tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤Ï¤¤¤¯¤Ä¤«¤Î¹àÌܤǹ½À®¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤é¤Î¼ê
+³¤­¤Ï¤½¤ì¤¾¤ì¤ÎÉôʬ¤ò½ñ¤­¹þ¤à¤³¤È¤Ç¡¢¼«Á³¤ËƳ¤¤¤Æ¤¯¤ì¤ë¤Ç¤·¤ç¤¦¡£
+/usr/X11R6/lib/X11/XF86Config.sample ¤È¤¤¤¦¡¢½é´üÃͤΥµ¥ó¥×¥ë¤È¤·¤Æ
+<tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤¬¤¢¤ê¤Þ¤¹¡£¤³¤Î¥Õ¥¡¥¤¥ë¤ò
+<tt>/usr/X11R6/lib/X11/XF86Config.sample</tt> ¤Ë¥³¥Ô¡¼¤·¤ÆÀßÄêÂоݵ¡´ï¹½À®
+¤Ë¸ÇÍ­¤ÊÉôʬ¤ò½¤Àµ¤·¤Æ²¼¤µ¤¤¡£<it>XF86Config¡Ê4 ¾Ï / 5 ¾Ï¡Ë</it>
+¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤Ë <tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤ÎÃæ¿È¤È¥ª¥×¥·¥ç¥ó¤Î¾Ü
+ºÙ¤¬½ñ¤«¤ì¤Æ¤Þ¤¹¡£¤ª¼ê¸µ¤Î <tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤ò½ñ¤­¹þ¤à¤¿¤á¤Ë¡¢
+¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤òÄÌÆÉ¤·¤Æ²¼¤µ¤¤¡£
+
+<tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤Î³ÆÀá¤Ï¼¡¤ÎÄ̤ê¤Ç¤¹¡£:
+ <descrip>
+ <tag> Files </tag>
+ ɸ½à¥Õ¥©¥ó¥È¤È RGB ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¥Ñ¥¹¤òÀßÄꤷ¤Þ¤¹¡£
+ <tag> Server Flags</tag>
+ °ìÈÌŪ¤Ê¥µ¡¼¥Ð¡¼¤Î¾¯Î̤Υª¥×¥·¥ç¥ó¤òÀßÄꤷ¤Þ¤¹¡£¤³¤ì¤é¤Ë¤Ä¤¤¤ÆÊÙ
+ ¶¯¤·¤¿¤¤¾ì¹ç¤Ï¡¢¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡£
+ <tag> Keyboard</tag>
+ ¥­¡¼¥Ü¡¼¥ÉÁõÃÖ¤òÀßÄꤷ¤Þ¤¹¡£¾¯Î̤Υª¥×¥·¥ç¥ó¥Ñ¥é¥á¡¼¥¿¤òÀßÄꤷ¤Þ
+ ¤¹¡£
+ <tag> Pointer</tag>
+ ²èÌ̻ؼ¨ÁõÃÖ¤òÀßÄꤷ¤Þ¤¹¡£¾¯Î̤Υª¥×¥·¥ç¥ó¥Ñ¥é¥á¡¼¥¿¤òÀßÄꤷ¤Þ
+ ¤¹¡£
+ <tag> Monitor</tag>
+ ¥µ¡¼¥Ð¡¼¤ËÂФ·¤Æ¥â¥Ë¥¿¡¼¡ÊÊ£¿ô¡Ë¤òµ­½Ò¤·¤Þ¤¹¡£
+ <tag> Graphics Device</tag>
+ ¥µ¡¼¥Ð¡¼¤ËÂФ·¤Æ¥Ó¥Ç¥ª¥«¡¼¥É¤òµ­½Ò¤·¤Þ¤¹¡£
+ <tag> Screen.</tag>
+ ¥â¥Ë¥¿¡¼¤È¥Ó¥Ç¥ª¥«¡¼¥É¤É¤Î¤è¤¦¤Ë»ÈÍѤ¹¤ë¤Ù¤­¤«µ­½Ò¤·¤Þ¤¹¡£
+ </descrip>
+
+
+<sect> Àµ¤·¤¤É¸½à¥µ¡¼¥Ð¡¼¤ÎÀßÄê
+<p>
+
+ɸ½à¥µ¡¼¥Ð¡¼¤Î̾Á°¤Ï <tt>/usr/X11R6/bin/X</tt>¤Ç¤¹¡£
+¤³¤ì¤Ï<tt>/usr/X11R6/bin/</tt>¤Ë¤¢¤ëÆÃÄê¤Î¥µ¡¼¥Ð¡¼¤Î¥Ð¥¤¥Ê¥ê¥Õ¥¡¥¤¥ë¤Ç¤¢¤ë
+<tt>XF86_xxxx</tt> ¥ê¥ó¥¯¥Õ¥¡¥¤¥ë¤Ç¤¹¡£
+X ¤¬»È¤¤¤¿¤¤¥µ¡¼¥Ð¡¼¤Î¥ê¥ó¥¯¥Õ¥¡¥¤¥ë¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤«³Îǧ¤·¤Æ²¼¤µ¤¤¡£
+Àµ¤·¤¤¥ê¥ó¥¯¥Õ¥¡¥¤¥ë¤Ë¤Ê¤Ã¤Æ¤¤¤Ê¤¤¤È¤­¤Ï¡¢X ¤òºï½ü¤·¤ÆÀµ¤·¤¤
+¥µ¡¼¥Ð¡¼¤Î¿·¤·¤¤¥ê¥ó¥¯¥Õ¥¡¥¤¥ë¤òºî¤Ã¤Æ²¼¤µ¤¤¡£¥µ¡¼¥Ð¡¼¤Î¥Ð¥¤¥Ê¥ê¥Õ¥¡¥¤¥ë¤Ï
+ ¼¡¤ÎÄ̤ê¤Ç¤¹¡£:
+ <descrip>
+ <tag>XF86_SVGA:</tag>
+ Super-VGA ¥µ¡¼¥Ð¡¼¡£ Cirrus 542{0,2,4,6,8,9}¡¢543{0,4} ¤ÈWestern
+ Digital 90C3{1,3} ¤È Oak Technologies Inc. OTI087 ¤Î¥Á¥Ã¥×¥»¥Ã¥ÈÂÐ
+ ±þ¤Î¥¢¥¯¥»¥é¥ì¡¼¥¿¤È»Ä¤ê¤Î¥Á¥Ã¥×¥»¥Ã¥ÈÂбþ¤ÎÈó¥¢¥¯¥»¥é¥ì¡¼¥¿¤ò´Þ¤ó
+ ¤Ç¤¤¤Þ¤¹¡£
+ <tag>XF86_Mono:</tag> ¥ª¥×¥·¥ç¥ó¤Ç Hercules ¤Þ¤¿¤Ï¾¤ÎÇò¹õ¥Ó¥Ç¥ª
+ ¥«¡¼¥É¤ò¥µ¥Ý¡¼¥È¤¹¤ë (S)VGA Çò¹õ¥µ¡¼¥Ð¡¼¤¬Æþ¤Ã¤Æ¤¤¤Þ¤¹¡£
+ <tag>XF86_VGA16:</tag> ÈÆÍÑ VGA 16 ¿§¥µ¡¼¥Ð¡¼¡£
+ <tag>XF86_S3:</tag> S3 ¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð¡¼¡£
+ <tag>XF86_Mach32:</tag> ATI Mach32 ¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð¡¼¡£
+ <tag>XF86_Mach64:</tag> ATI Mach64 ¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð¡¼¡£
+ <tag>XF86_Mach8:</tag> ATI Mach8 ¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð¡¼¡£
+ <tag>XF86_8514:</tag> 8514/A ¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð¡¼¡£
+ <tag>XF86_P9000:</tag> P9000 ¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð¡¼¡£
+ <tag>XF86_AGX:</tag> AGX ¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð¡¼¡£
+ <tag>XF86_W32:</tag> ET4000/W32 ¤ÈET6000 ¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð¡¼¡£
+ </descrip>
+
+¤½¤ì¤¾¤ì¤Î¥µ¡¼¥Ð¡¼Âбþ¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤¬¤¢¤ê¤Þ¤¹¤Î¤Ç¡¢¥µ¥Ý¡¼¥È¤·¤Æ¤¤
+¤ë¥Á¥Ã¥×¥»¥Ã¥È¸ÇÍ­¤Î¾ÜºÙ¤È¥µ¡¼¥Ð¡¼¸ÇÍ­¤Î¹½À®¤Î¥ª¥×¥·¥ç¥ó¤Ï¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å
+¥¢¥ë¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡£
+
+LinkKit ¤Ë¤Æ¥µ¡¼¥Ð¡¼¤Ë¥É¥é¥¤¥Ð¡¼¤òÁȤ߹þ¤ß¡¢Êѹ¹¤¹¤ë¾ì¹ç¤ËÃí°Õ»ö¹à¤¬¤¢¤ê¤Þ
+¤¹¡£ÇÛÉÕʪ¤¬¤É¤¦¤æ¤¦É÷¤ËÁȤßΩ¤Æ¤é¤ì¤Æ¤¤¤ë¤«¤Ë¤è¤ê¤Þ¤¹¤¬¡¢¥µ¡¼¥Ð¡¼¤Î¥Ð¥¤¥Ê
+¥ê¥Õ¥¡¥¤¥ë¤Ë¤Ï»ÈÍѲÄǽ¤ÊÁ´¤Æ¤Î¥É¥é¥¤¥Ð¡¼¤Ï´Þ¤Þ¤ì¤Æ¤¤¤Þ¤»¤ó¡£ÁȤ߹þ¤Þ¤ì¤Æ¤¤
+¤ë¥É¥é¥¤¥Ð¡¼¤Î°ìÍ÷¤òÆÀ¤ë¤Ë¤Ï¡¢ <tt>/usr/X11R6/bin/X -showconfig</tt>
+¤ò¼Â¹Ô¤·¤Æ²¼¤µ¤¤¡£¥µ¡¼¥Ð¡¼¤òºÆ¥ê¥ó¥¯¤¹¤ëɬÍפ¬¤¢¤ë¾ì¹ç¤Ï¡¢¸ÇÍ­¤Î¾ðÊó¤Ë¤Ä¤¤¤Æ
+LinkKit ¤Î
+<url url="LinkKit.html" name="<tt>README.LinkKit</tt>"> ¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡£
+
+<sect> XF86Config ¤Î°×¤·¤¤Éôʬ
+<p>
+
+<tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤Î &dquot;Files&dquot; ¤ÎÀá¤Ï¡¢RGB (ÀÖÎÐÀÄ) ¤Î¥Ç
+¡¼¥¿¥Ù¡¼¥¹
+¥Õ¥¡¥¤¥ë¡Ê°ìÈ̤ˡ¢¤³¤ì¤òÊѹ¹¤¹¤ë¤Ù¤­¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡Ë¤Ø¤Î¥Ñ¥¹¤È¡¢É¸½à¥Õ¥©¥ó
+¥È¤Î¥Ñ¥¹¤òÆâ¢¤µ¤»¤ë¤³¤È¤Ç¤¹¡£Ê£¿ô¤Î FontPath ¹Ô¤ò <tt>XF86Config</tt> ¤Ë½ñ
+¤¤¤Æ¤¢¤ë¾ì¹ç¤Ï¡¢FontPath ¤ò·ë¹ç¤·¤Æ»ÈÍѤǤ­¤Þ¤¹¡£¤½¤ì¤¾¤ì¤Î FontPath ¤Î¥Ç¥£
+¥ì¥¯¥È¥ê¤¬Â¸ºß¤¹¤ë¤³¤È¤È¡¢¤Á¤ã¤ó¤È¥Õ¥©¥ó¥È¤¬»È¤¨¤ë¤³¤È¤ò³Îǧ¤·¤Æ²¼¤µ¤¤¡£
+¥µ¡¼¥Ð¡¼¤¬
+&dquot;Can't open default font 'fixed'&dquot;¡Êɸ½à¤Î'¸ÇÄêÉý'¥Õ¥©¥ó¥È¤¬Í­¤ê
+¤Þ¤»¤ó¡Ë¤È
+¸À¤Ã¤Æ¤­¤¿¤é¡¢¤½¤ì¤Ï¥Õ¥©¥ó¥È¤ÎÅÐÏ¿¤¬Àµ¤·¤¯¤Ê¤¤¤«¤é¤Ç¤¹¡£¤½¤ì¤¾¤ì¤Î¥Õ¥©¥ó¥È
+¤ÎÅÐÏ¿¤òÀµ¤·¤¯¤·¤¿¤¤¤Ê¤é¡¢¤½¤ì¤¾¤ì¤Î¥Õ¥©¥ó¥È¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î½ê¤Ç
+`mkfontdir' ¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤Æ¤ß¤Æ²¼¤µ¤¤¡£<it>XF86Config</it> ¤Î¥ª¥ó¥é¥¤¥ó
+¥Þ¥Ë¥å¥¢¥ë¤Î 4 ¾Ï / 5 ¾Ï¤Ë¡¢<tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤ÎºÇ½é¤ÎÉôʬ¤Î¾¤Î
+¥Ñ¥é¥á¥¿¤Ë¤Ä¤¤¤Æµ­½Ò¤·¤Æ¤¤¤Þ¤¹¡£
+
+¼¡¤Ï &dquot;Keyboard&dquot; ¤ÎÀá¤Ç¤¹¡£ ¤³¤ÎÀá¤Ë¤Ï¡¢¥­¡¼¥Ü¡¼¥É¤ÎÄÌ¿®¼ê½ç¡ÊXqu
+eue ¤Þ¤¿¤Ï
+Normal¡Ë¡¢¥­¡¼¤Î·«¤êÊÖ¤·¤Î®Å٤䤤¤¯¤Ä¤«¤Î½¤¾þ¥­¡¼¤Îɸ½àŪ¤Ê³ä¤êÉÕ¤±¤Ë¤Ä¤¤
+¤ÆÀßÄê¤Ç¤­¤Þ¤¹¡£°ìÈ̤ˤ³¤³¤ÏÊѹ¹¤¹¤ëɬÍפÏ̵¤¤¤Ç¤·¤ç¤¦¡£±Ñ¸ìÍѤǤʤ¤¥­¡¼¥Ü
+¡¼¥É¤Î¥æ¡¼¥¶¡¼¤Ï½¤¾þ¥­¡¼¤ÎÄêµÁ¤òÊѤ¨¤¿¤¤¤³¤È¤Ç¤·¤ç¤¦¡£
+¾ÜºÙ¤Ï <it>XF86Config</it> ¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤Î 4 ¾Ï / 5 ¾Ï¤ò¸«¤Æ²¼¤µ
+¤¤¡£
+&lsqb; ÌõÃí¡§½¤¾þ¥­¡¼ = ¾¤Î¥­¡¼¤È°ì½ï¤Ë²¡¤¹¡¢¥ª¥ë¥¿¥Í¥¤¥È¥­¡¼(Alt)¡¢¥³¥ó¥È¥í¡¼
+¥ë¥­¡¼(Cntl)¤ä¥·¥Õ¥È¥­¡¼(Shift) Åù²¡¤·¤Æ¤â»ú¤Î½Ð¤Ê¤¤¥­¡¼¤Î»ö¤Ç¤·¤ç¤¦ &rsqb;
+
+¼¡¤Ï &dquot;Pointer&dquot; ¤ÎÀá¤Ç¤¹¡£¤³¤ÎÀá¤Ç¤Ï²èÌ̻ؼ¨ÁõÃÖ¤ÎÄÌ¿®¼ê½ç¤ÈÁõÃÖ
+¤Ë¤Ä¤¤¤Æ»Ø
+Äê¤Ç¤­¤Þ¤¹¡£ÄÌ¿®¼ê½ç̾¾Î¤ÏÀ½Â¤¼Ô̾¾Î¤Ç¤Ï¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ²¼¤µ¤¤¡£Î㤨¤Ð¡¢
+¤¤¤¯¤Ä¤«¤Î Logitech ¤Î¥Þ¥¦¥¹¡ÊÆÃ¤Ë¿·¤·¤¤¤â¤Î¡Ë¤Î¾ì¹ç¡¢Logitech ¤ÎÄÌ¿®¼ê½ç
+̾¾Î¤Ç¤Ï¤Ê¤¯ MouseMan ¤Þ¤¿¤Ï Microsoft ¤ÎÄÌ¿®¼ê½ç̾¾Î¤òÍѤ¤¤Þ¤¹¡£¤½¤Î¾¤Î
+¥Þ¥¦¥¹¤Î¥Ñ¥é¥á¥¿¤Ï¤³¤ÎÀá¤Ç¡¢Ä´À°¤Ç¤­¤Þ¤¹¡££²¥Ü¥¿¥ó¥Þ¥¦¥¹¤ò»È¤Ã¤Æ¤¤¤ë¤È¤­
+¤Ï¡¢Emulate3Buttons ¤È¤¤¤¦¥­¡¼¥ï¡¼¥É¤ò¥³¥á¥ó¥È¤Ë¤·¤Ê¤¤¤Ç²¼¤µ¤¤¡£
+Emulate3Buttons ¥â¡¼¥É¤Ç»È¤¦¤È¤­¤Ï¡¢Æ±»þ¤Ë£²¤Ä¤Î¥Ü¥¿¥ó¤ò²¡¤¹¤³¤È¤Ç¡¢¥µ¡¼¥Ð
+¡¼¤Ë¿¿¤óÃæ¤Î¥Ü¥¿¥ó¤ò²¡¤·¤¿¤³¤È¤òÃΤ餻¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£
+
+¥µ¡¼¥Ð¡¼¤¬¥Þ¥¦¥¹¥Ç¥Ð¥¤¥¹¤òǧ¼±¤·¤Ê¤¤¡¢¤Èʸ¶ç¤ò¸À¤¦¤È¤­¤Ï¤½¤ì¤Ï¥µ¡¼¥Ð¡¼¤ÎÌä
+Âê¤Ç¤Ï¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ²¼¤µ¤¤¡£¤½¤ì¤Ï¤è¤¯µ¯¤³¤ëÀßÄê¥ß¥¹¤Ç¤¢¤ê¡¢99.999% ¤Î
+³ÎΨ¤Ç OS ¤Ë¥Ç¥Ð¥¤¥¹¤¬Àµ¤·¤¯ÀßÄꤵ¤ì¤Æ¤¤¤Ê¤¤»ö¤¬Íýͳ¤Ç¡¢¤¤¤¯¤Ä¤«¤Î OS ¤Ç¤Ï
+¥¨¥é¡¼¤È¤Ê¤ë¤Ç¤·¤ç¤¦¡£¤½¤ì¸Î¡¢OS ¥ì¥Ù¥ë¤Ç¤Î¥µ¥Ý¡¼¥È¤¬Àµ¤·¤¤¤³¤È¤ò¤è¤¯Ä´¤Ù
+¤ë¤Þ¤Ç¤Ï¡¢²æ¡¹¤Ë¥Ð¥°Êó¹ð¤ò¤·¤Ê¤¤¤Ç²¼¤µ¤¤¡£
+
+<sect> ¥Ó¥Ç¥ª¥Ü¡¼¥É¤ÎÀßÄê¤Ë¤Ä¤¤¤Æ
+<p>
+
+&dquot;Device&dquot; ¤ÎÀá¤Ç¤Ï¥Ó¥Ç¥ª¥Ü¡¼¥É¤Ë¤Ä¤¤¤Æµ­½Ò¤·¤Þ¤¹¡£Ê£¿ô¤Îµ¡´ï¤ÎÀá
+¤ò½ñ¤¯¤³¤È
+¤òµö¤·¤Æ¤ª¤ê¡¢¤½¤ì¤¾¤ì¤ÎÀᤴ¤È¤Ë£±¤Ä¤Î¥Ó¥Ç¥ª¥«¡¼¥É¤òµ­½Ò¤·¤Þ¤¹¡£
+
+ÀßÄꤷ¤è¤¦¤È¤·¤Æ¤¤¤ëÈÆÍѤǤʤ¤¾ðÊó¤Ë¤Ä¤¤¤Æ¡¢¥µ¡¼¥Ð¡¼¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢
+¥ë¤È¥Á¥Ã¥×¥»¥Ã¥È¸ÇÍ­¤Î <tt>README</tt> ¥Õ¥¡¥¤¥ë¤òÆÉ¤ó¤Ç³Îǧ¤·¤Æ²¼¤µ¤¤¡£
+
+Device ¤ÎÀá¤ò½ñ¤¯¤¿¤á¤Ë¡¢ÀßÄêÂоÝÁõÃ֤Υǡ¼¥¿¤ò½¸¤á¤ëɬÍפ¬¤¢¤ê¡¢ÀßÄêÊý¿Ë
+¤ò·è¤á¤Æ²¼¤µ¤¤¡£É¬ÍפÊÁõÃ֤Υǡ¼¥¿¤Ï¼¡¤Î¤È¤ª¤ê¤Ç¤¹¡£:
+<itemize>
+ <item> ¥Á¥Ã¥×¥»¥Ã¥È¤Î¼ïÊÌ
+ <item> ɽ¼¨ÍÑ¥á¥â¥ê¤ÎÎÌ
+ <item> »ÈÍѲÄǽ¤Ê¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ÎÃÍ¡Ê¥×¥í¥°¥é¥à²Äǽ¤Ê¾ì¹ç¡Ë
+ <item> Ramdac ¤Î¼ïÊ̡ʴö¤Ä¤«¤Î¥µ¡¼¥Ð¡¼ÍÑ¡Ë
+</itemize>
+<tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤ÎÃæ¤ÇÁ´¤Æ»ØÄê¤ÎÃͤòËä¤á¹þ¤ó¤Ç¤ª¤¯¤è¤ê¤Ï¡¢Ä̾
+¥µ¡¼¥Ð
+¡¼¤Ë¼«Ê¬¼«¿È¤ÇÁõÃ֤Υǡ¼¥¿¤ò¼è¤ê¹þ¤Þ¤»¤¿¤Û¤¦¤¬¤¤¤¤¤Ç¤·¤ç¤¦¡£¤½¤ÎÊý¤¬´Ö°ã¤¤
+¤Ê¤¯ÀßÄê¤Ç¤­¤Þ¤¹¡£'Chipset' ¤ÏÀßÄꤷ¤Æ¤¤¤ë¥É¥é¥¤¥Ð¡Ê'X -showconfig'¤ò¼Â¹Ô
+¤¹¤ì¤Ðɽ¼¨¤Ç¤­¤Þ¤¹¡ËÂбþ¤Î¥­¡¼¥ï¡¼¥É¤Î£±¤Ä¤Ç¤¹¡£¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð¡¼¤Ç
+¤Ï¡¢¸½ºß¡¢¤¤¤¯¤Ä¤«¤Î¥µ¡¼¥Ð¡¼¤¬¥Á¥Ã¥×¥»¥Ã¥È¥É¥é¥¤¥Ð¤ò»ý¤Ã¤Æ¤¤¤Þ¤¹¡£¥á¥â¥ê¤Î
+Î̤ϥ­¥í¥Ð¥¤¥Èñ°Ì¤Ç»ØÄꤷ¤Þ¤¹¤Î¤Ç¡¢£±¥á¥¬¥Ð¥¤¥È¤Î¥á¥â¥ê¤Î¾ì¹ç¤Ï 1024 ¤È»Ø
+Äꤷ¤Þ¤¹¡£
+
+¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ï¥°¥é¥Õ¥£¥Ã¥¯¥Ü¡¼¥É¤ÎÀßÄê¤Ë¤ª¤¤¤Æ°ìÈÖÊ£»¨¤ÊÉôʬ¤Ç¤¹¡£¹¬±¿¤Ë
+¤â¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ò½¸¤á¤¿Â礭¤Ê¥Ç¡¼¥¿¥Ù¡¼¥¹¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¤¤¤¯¤Ä¤«¤Î¥°¥é¥Õ
+¥£¥¯¥Ü¡¼¥ÉÂбþ¤Î Device ¤Î¥Ç¡¼¥¿¤Î°ìÍ÷¤¬ `Devices' ¥Õ¥¡¥¤¥ë¤Ë¤¢¤ê¤Þ¤¹¡£¤¢
+¤Ê¤¿¤Î¥°¥é¥Õ¥£¥Ã¥¯¥Ü¡¼¥É¤¬¸«¤Ä¤«¤ì¤Ð¡¢¤½¤Î¥Ç¡¼¥¿¤«¤é»Ï¤á¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡£
+<tt>modeDB.txt</tt> ¥Õ¥¡¥¤¥ë¤ÎºÇ½é¤ÎÉôʬ¤Ï̵¿ô¤Î SVGA ¥«¡¼¥É¤Î¾ðÊ󤬰ìÍ÷¤Ë¤Ê¤Ã¤Æ
+¤¤¤Þ¤¹¡£¥¢¥¯¥»¥é¥ì¡¼¥¿¥«¡¼¥É¤Ç¤Ï¡¢`AccelCards' ¥Õ¥¡¥¤¥ë¤ò¸«¤Æ²¼¤µ¤¤¡£¹¬±¿
+¤Ê¤é¤Ð¡¢¼«Ê¬¤Î¥«¡¼¥É¤¬²¿½è¤«¤Ë¸«¤Ä¤«¤ë¤Ç¤·¤ç¤¦¡£¤â¤·¥«¡¼¥É¤¬¸«¤Ä¤«¤Ã¤¿¤é¡¢
+<tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤Î Clocks ¹Ô¤Ë¥Ç¡¼¥¿¥Ù¡¼¥¹¤«¤é¿ôÎó¤ò¡¢¥Ç¡¼¥¿¥Ù¡¼
+¥¹¤Ëɽ
+¼¨¤µ¤ì¤Æ¤¤¤ë¤½¤Î¤Þ¤Þ¤òʤÙÂØ¤¨¤¿¤ê¤·¤Ê¤¤¤Ç»Ä¤µ¤º¥³¥Ô¡¼¤·¤Þ¤·¤ç¤¦¡£¿·¤·¤¤¥¢
+¥¯¥»¥é¥ì¡¼¥¿¥«¡¼¥É¤Ï¥×¥í¥°¥é¥Þ¥Ö¥ë¥¯¥í¥Ã¥¯¥¸¥§¥Í¥ì¡¼¥¿¤ò»È¤Ã¤Æ¤¤¤ë¤Î¤Ç
+<tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤Î ClockChip ¹Ô¤Ë°úÍÑÉä¡Ê&dquot;¡ËÉÕ¤­¤Ç¥¯¥í¥Ã¥¯
+¥¸¥§¥Í¥ì¡¼¥¿
+¤Î·¿¼°¤¬½ñ¤¤¤Æ¤¢¤ë¤³¤È¤ËÃí°Õ¤·¤Æ²¼¤µ¤¤¡£¡ÊÎ㤨¤Ð¡¢&num;9 GXe ¤ò»È¤¦¤Ê¤é¤Ð¡¢
+`ClockChip &dquot;icd2061a&dquot;' ¤ÎÍͤ˽ñ¤¤¤Æ¤¢¤ë¤Ç¤·¤ç¤¦¡Ë¡£
+
+¥°¥é¥Õ¥£¥Ã¥¯¥Ü¡¼¥É¤¬°ìÍ÷¤Ë¸«¤Ä¤«¤é¤Ê¤¤¤È¤­¤Ï¡¢¥µ¡¼¥Ð¡¼¤Ë¥°¥é¥Õ¥£¥Ã¥¯¥Ü¡¼¥É
+¤Î¸¡½Ð¤òǤ¤»¤Æ¤·¤Þ¤¤¤Þ¤·¤ç¤¦¡£sh Ëô¤Ï ksh ¤Î¾ì¹ç¤Ï¡¢
+`X -probeonly &gt;/tmp/out 2&gt;&amp;1'¡¢csh ¤Î¾ì¹ç¤Ï¡¢`X -probeonly &gt;&amp;/tmp/out' ¤È
+¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤Þ¤·¤ç¤¦¡£¤³¤Î»þ¡¢<tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤Ë Clocks ¹Ô
+¤ò<bf>½ñ¤«¤Ê¤¤</bf>¤Ç¤ª¤¤¤Æ²¼¤µ¤¤¡£¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤¿¤é¡¢¥µ¡¼¥Ð¡¼¤¬ÁÇ®¤¯¥¯
+¥í¥Ã¥¯¤ò½ä²ó¤·¤ÆÄ´¤Ù¤ë´Ö¡¢¿ôÉôֲèÌ̤¬°Å¤¯¤Ê¤ê¤Þ¤¹¡£Ä´¤Ù¤ë¤³¤È¤Ç¥â¥Ë¥¿¡¼¤ò
+Äˤá¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¤¬¡¢É½¼¨»ÅÍͰʾå¤Ç¸¡ºº¤ò¤¹¤ë¾ì¹ç¤¬¤¢¤ë¤¿¤á¡¢¿·¤·¤¤¥â
+¥Ë¥¿¡¼¤Î¾ì¹ç¤Ï¼«Æ°Åª¤Ë¤½¤ì¼«¿È¤Ç¥â¥Ë¥¿¡¼¤ÎÅŸ»¤òÍî¤È¤·¤Æ¤·¤Þ¤¦¾ì¹ç¤¬¤¢¤ê¤Þ
+¤¹¡£¤È¤Ë¤«¤¯¡¢Ä´ºº¤¬½ª¤ï¤Ã¤¿¤é¡¢¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Î¸¡½Ð·ë²Ì¤Î/tmp/out ¥Õ¥¡¥¤¥ë
+¤ò¸«¤Þ¤·¤ç¤¦¡£/tmp/out ¤Î¿ôÎó¤ò¤½¤Î¤Þ¤Þ <tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤Î
+Clocks ¹Ô¤Ë¥³¥Ô¡¼¤·¤Þ¤·¤ç¤¦¡£Ê¤ÓÊѤ¨¤¿¤ê¡¢¤¤¤«¤Ê¤ëÊѹ¹¤â¤·¤Æ¤Ï¤¤¤±¤Þ¤»¤ó¡£
+
+¥°¥é¥Õ¥£¥Ã¥¯¥Ü¡¼¥É¤¬¥×¥í¥°¥é¥Þ¥Ö¥ë¥¯¥í¥Ã¥¯¥¸¥§¥Í¥ì¡¼¥¿¤ò»ý¤Ã¤Æ¤¤¤ë²ÄǽÀ­¤¬
+¤¢¤ê¤Þ¤¹¡£¤³¤Î¾ì¹ç¤Ï¡¢2¡¢3¸Ä¤Î¥¯¥í¥Ã¥¯¤À¤±Ãͤò»ý¤Á¡¢»Ä¤ê¤¬Á´¤Æ¥¼¥í¤Ë¤Ê¤Ã¤Æ
+¤¤¤ë¤³¤È¤Ç¤·¤ç¤¦¡£¤â¤·¡¢¥Ü¡¼¥É¤¬¥Ç¡¼¥¿¥Ù¡¼¥¹¤ÎÃæ¤Ë¸«Åö¤¿¤é¤Ê¤«¤Ã¤¿¤é¡¢
+XFree86 ¥Á¡¼¥à¤ËÏ¢Íí¤ò¼è¤ë¤«¡¢ comp.windows.x.i386unix ¤Ë¥á¥Ã¥»¡¼¥¸¤ò¥Ý¥¹
+¥È¤·¤Æ²¼¤µ¤¤¡£Ëؤɤξì¹ç Diamond ¼Ò¤ÎÁõÃÖ¤¬¤³¤Î¼ï¤ÎʬÎà¤Ë¤Ê¤ê¤Þ¤¹¤¬¡¢
+Diamond ¼Ò ¤Ï¥×¥í¥°¥é¥à¤Î¾ÜºÙ¤ò¸ø³«¤·¤Æ¤¯¤ì¤Þ¤»¤ó¤Î¤Ç¡¢²æ¡¹¤Ï½õ¤±¤ë¤³¤È¤¬
+½ÐÍè¤Þ¤»¤ó¡£¥Í¥Ã¥È¥Ë¥å¡¼¥¹¤Ç¤Ï¡¢ÎÑÍýŪ¤ËÌäÂê¤Î¤¢¤ë²ò·èºö¤¬ÍøÍѲÄǽ¤Ç¤¹¤¬¡¢
+²æ¡¹¤Ï¤³¤ÎÊýË¡¤òÄó¾§½ÐÍè¤Þ¤»¤ó¤Î¤Ç¡¢¤³¤ÎÊýË¡¤Ë¤Ä¤¤¤Æ²æ¡¹¤ËÏ¢Íí¤·¤Ê¤¤¤Ç²¼¤µ
+¤¤¡£
+
+¤¤¤¯¤Ä¤«¤Î¥µ¡¼¥Ð¡¼ (S3 ¤È AGX) ¤Ë¤Ï RAMDAC ¤Î·¿¼°¤È®ÅÙ¤¬¡¢¤½¤Î¾¤ÎÁõÃÖ¤Î
+¾ðÊó¤ò¼è¤ê½Ð¤¹¤¿¤á¤ËɬÍפˤʤê¤Þ¤¹¡£¤³¤Î»ØÄê¤Ï 'Ramdac' ¤È 'DacSpeec' ¤È¤¤
+¤¦µ­ºÜ¤òÄɲ䷤ƹԤʤ¤¤Þ¤¹¡£¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë RAMDAC ¤Î¾ÜºÙ¤Ï¡¢Å¬Àڤʥµ¡¼¥Ð
+¡¼¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡£°ÊÁ°¤Î XFree86 ¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç
+¤Ï¡¢RAMDAC ¤Î·¿¼°¤Ï¥ª¥×¥·¥ç¥ó¥Õ¥é¥°¤ÇÀßÄꤷ¤Æ¤¤¤¿¤³¤È¤ËÃí°Õ¤·¤Æ²¼¤µ¤¤¡£
+
+¼«Ê¬¤ÎÁõÃ֤˹ç¤ï¤»¤Æ¡¢¤¤¤¯¤Ä¤«¤Î¥ª¥×¥·¥ç¥ó¥Õ¥é¥°¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ë¤Ç¤·¤ç
+¤¦¡£¥µ¡¼¥Ð¡¼¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤Ë¤³¤ì¤é¤Î¥ª¥×¥·¥ç¥ó¤Ë¤Ä¤¤¤Æµ­½Ò¤¬¤¢¤ê¡¢
+¥Á¥Ã¥×¥»¥Ã¥È¸ÇÍ­¤Î <tt>README</tt> ¥Õ¥¡¥¤¥ë¤Ë¤ª¼ê¸µ¤Î¥Ü¡¼¥É¤Î°Ù¤Ë¤Ê¤Ë¤¬É¬Í×
+¤«½ñ¤¤¤Æ
+¤ê¤Þ¤¹¡£
+
+<sect> ¥â¥Ë¥¿¡¼¤È¤½¤Î¥â¡¼¥É¤ÎÀßÄê¤Ë¤Ä¤¤¤Æ
+<p>
+
+¥â¥Ë¥¿¡¼¥â¡¼¥É¤ÎÀßÄê¤Ï¡¢¥â¥Ë¥¿¡¼ÁõÃÖ¤Îɸ½à²½¤¬½½Ê¬¤Ç¤Ê¤¤¤Î¤Ç¡¢»Äǰ¤Ê¤¬¤é¡¢
+¼Â¸³¤Î·«¤êÊÖ¤·¤Ç·èÄꤷ¤Þ¤¹¡£ÆÃÄê¤Î¥â¥Ë¥¿¡¼¾ðÊó¤ò¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¼ý½¸¤¹¤ë¤³¤È
+¤Ë¤è¤ê¡¢¤³¤Î¼Â¸³ºî¶È¤ò´Êñ¤Ë¤¹¤ë»ö¤È¡¢ËؤɤΥâ¥Ë¥¿¡¼¤Ë¤«¤Ê¤ê°ìÃפ¹¤ëµ¡Ç½¤ò
+½¸¤á¡¢ÈÆÍѥ⡼¥É¤ÎÁȤ߹ç¤ï¤»¤ò¤Þ¤È¤á¤ë»ö¤ò»î¤ß¤Æ¤¤¤Þ¤¹¡£·ì¤Î¤Ë¤¸¤à¤è¤¦¤ÊÅØ
+ÎϤǽÐÍ褿Á´¤Æ¤Î¥â¥Ë¥¿¡¼¥â¡¼¥É¤ÎºîÀ®¤È²þÎɤˤĤ¤¤Æ¤Î¾ÜºÙ¤Ï¡¢Eric Raymond
+»á¤¬½ñ¤¤¤¿ <url url="VidModes.html" name="VideoModes.doc"> ¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡£
+
+<tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤Î &dquot;Monitor&dquot; Àá¤Ë¥â¥Ë¥¿¡¼¤Î»ÅÍͤȥÓ
+¥Ç¥ª¤Î¥â¡¼¥É¤òµ­½Ò¤·
+¤Þ¤¹¡£Monitor ¤ÎÀá¤ò½ñ¤¯¤¿¤á¤Ë¡¢¼«Ê¬¤Î¥â¥Ë¥¿¡¼¤Î»ÅÍͤòÃΤëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ÆÃ¤Ë¡¢¥â¥Ë¥¿¡¼¤Î¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¿åʿƱ´ü¿®¹æ¤È¿âľ¥ê¥Õ¥ì¥Ã¥·¥å¿®¹æ¤Î®ÅÙ¤È
+¥Ó¥Ç¥ª¿®¹æ¤ÎÂÓ°è¤Ë¤Ä¤¤¤ÆÃΤëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤³¤Î¾ðÊó¤Ï¥â¥Ë¥¿¡¼¤Î¥æ¡¼¥¶ ¡¼
+¥Þ¥Ë¥å¥¢¥ë¤Ë½ñ¤¤¤Æ¤¢¤ë¤Ç¤·¤ç¤¦¡£¤Þ¤¿¡¢ ¼«Ê¬¤Î¥â¥Ë¥¿¡¼¤Îµ­ºÜ¤¬¤¢¤ë¤«¤â¤·¤ì
+¤Ê¤¤¤Î¤Ç 'Monitors' ¥Õ¥¡¥¤¥ë¤ò¸«¤Æ¡¢³Îǧ¤·¤Æ²¼¤µ¤¤¡£Moniter ¤ÎÀá¤Ë¤³¤Î¾ðÊó
+¤ò¤É¤¦¤ä¤Ã¤ÆÅÐÏ¿¤¹¤ë¤«¤Î¾ÜºÙ¤Ï <it>XF86Config</it> ¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤Î
+4 ¾Ï /
+5 ¾Ï¤ò¸«¤Æ²¼¤µ¤¤¡£
+
+¼¡¤Ë¡¢¥â¥Ë¥¿¡¼¤Ë¹ç¤ï¤»¤¿¥Ó¥Ç¥ª¤Î¥â¡¼¥É¤ÎÁȤòÍ¿¤¨¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤Þ¤ººÇ½é
+¤Ë'Monitors' ¤È <tt>modeDB.txt</tt> ¥Õ¥¡¥¤¥ë¤ÎÃæ¤Ë¼«Ê¬¤Î»ØÄꤹ¤ë¥â¥Ë¥¿¡¼¤ËÂбþ¤¹
+¤ë¥â¡¼¥É¤¬°ìÍ÷¤Ë¤¢¤ë¤«³Îǧ¤·¤Æ²¼¤µ¤¤¡£¤¢¤Ã¤¿¾ì¹ç¤Ï¡¢<tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤Î
+ModeDB ¤ÎÀá¤Ë¤½¤ì¤é¤Î¥â¡¼¥É¤ò¥³¥Ô¡¼¤·¤Æ²¼¤µ¤¤¡£<tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤Î
+Clocks ¹Ô¤Ë¤¢¤ë¥¯¥í¥Ã¥¯¤È¡¢³Æ¥â¡¼¥É¤Î¹Ô¤Î£²ÈÖÌܤΥѥé¥á¡¼¥¿¤Î¥É¥Ã¥È¥¯¥í¥Ã
+¥¯¤¬°ìÃפ·¤Æ¤¤¤ë¤«³Îǧ¤·¤Æ¡¢¼«Ê¬¤Î¥«¡¼¥É¤Î¥¯¥í¥Ã¥¯¤È°ìÃפ·¤Ê¤¤¥â¡¼¥É¤Î¹Ô¤Ï
+¾Ã¤·¤Æ²¼¤µ¤¤¡£¤½¤·¤Æ¥â¡¼¥É¤¬»Ä¤Ã¤¿»þ¤Ï¡¢Îɤ¤¾õÂ֤ˤʤê¤Þ¤¹¡£
+
+ÆÃÄê¤Î¥â¡¼¥É¤¬¸«¤Ä¤«¤é¤Ê¤¤¤«¡¢¤â¤Ã¤È»È¤¤¤¿¤¤²òÁüÅ٤Υ⡼¥É¤¬ÃΤꤿ¤¤¤È¤­
+¤Ï¡¢¸å½Ò¤¹¤ëÈÆÍѥӥǥª¥â¡¼¥É¤Î°ìÍ÷¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡£¥â¥Ë¥¿¡¼¤Î»ÅÍͤËÂФ·¤Æ
+ÀßÄꤹ¤ë¥â¡¼¥É¤Î»ÅÍͤò¹ç¤ï¤»¤Þ¤·¤ç¤¦; »ÅÍÍÆâ¤Ç°ìÈֹ⤤¥ê¥Õ¥ì¥Ã¥·¥å¥â¡¼¥É¤ò
+¼è¤ê½Ð¤·¤Æ¡¢Clocks ¹Ô¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ë¹ç¤Ã¤Æ¤¤¤ë¤³¤È¤ò³Îǧ¤·¤Æ²¼¤µ¤¤¡£²ò
+ÁüÅÙ¤¬°ìÃפ¹¤ë¸òÂå (Alternate) ¥â¡¼¥É¤ËÀÚ¤êÂØ¤¨¤ëÁ°¤Ë VESA ¥â¡¼¥É¤ò»î¤·¤Æ
+¤ß¤Æ²¼¤µ¤¤¡£ÀßÄê¤ò¹ç¤ï¤»¤¿¥â¡¼¥É¤ò <tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤Î Monitor ¤Î
+Àá¤Ë¥³
+¥Ô¡¼¤·¤Æ²¼¤µ¤¤¡£¤³¤ì¤é¤Î¥â¡¼¥É¤ÏºÇŬ¤ÊÃͤǤϤʤ¤»ö¤ËÃí°Õ¤·¤Æ²¼¤µ¤¤¡£¤³¤ì¤é
+¤Ï´°àú¤Ê²èÌÌ¥µ¥¤¥º¤Ç¤Ï¤Ê¤¤¤Ç¤·¤ç¤¦¤·¡¢¿¿¤óÃæ¤Ëɽ¼¨¤µ¤ì¤Æ¤Ï¤¤¤Ê¤¤¤Ç¤·¤ç¤¦¡£
+¤·¤«¤·¡¢Ä´À°²Äǽ¤Ç¤¹¡£ÀßÄêÂоݤΥâ¥Ë¥¿¡¼¤Ë¹ç¤ï¤»¤Æ¥â¡¼¥É¤òÈùÄ´À°¤·¤¿¤¤¾ì¹ç
+¤Ï¡¢VideoModes.doc ¥Õ¥¡¥¤¥ë¤Î 'ɽ¼¨¤ÎÌäÂ꽤Àµ' ¤ÎÀá¤òÆÉ¤ó¤Ç²¼¤µ¤¤¡£
+
+ÈùÄ´À°¤ò¹Ô¤Ê¤¦¤Ë¤¢¤¿¤ê¡¢Ãí°Õ»ö¹à¤¬¤¢¤ê¤Þ¤¹¡£<tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤Î M
+onitor
+¤ÎÀá¤ËƱ¤¸¥â¡¼¥É¤Î̾Á°¤¬£²¤Ä°Ê¾åÄêµÁ¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ë¡¢¥µ¡¼¥Ð¡¼¤Ï¥¯¥í¥Ã¥¯¤Î
+°ìÃפ¹¤ëºÇ½é¤Î¥â¡¼¥É¤ò»ÈÍѤ·¤Þ¤¹¡£°ìÈÌŪ¤Ë¡¢<tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤ËƱ
+¤¸¥â¡¼
+¥É¤Î̾Á°¤ò£²¤Ä°Ê¾åÄêµÁ¤¹¤ë¤³¤È¤Ï°­¤¤¹Í¤¨¤À¤È»×¤¤¤Þ¤¹¡£
+
+<sect> ¥Ó¥Ç¥ª¥Ü¡¼¥É¤È¥â¥Ë¥¿¡¼¥Ç¡¼¥¿¤ÎÁȤ߹ç¤ï¤»¤Ë¤Ä¤¤¤Æ
+<p>
+
+°ìö¡¢¥µ¡¼¥Ð¤¬ÀßÄêÂоݤΥâ¥Ë¥¿¡¼¤È¥°¥é¥Õ¥£¥Ã¥¯¥Ü¡¼¥É¤ò¤É¤Î¤è¤¦¤Ë»È¤¦¤«µ­½Ò
+¤·¤Æ»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤ò <tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤Î &dquot;Screen&dquot; ¤ÎÀá¤Ç¹Ô
+¤Ê¤¤¤Þ¤¹¡£»ÈÍѤ·¤¿¤¤¥µ¡¼¥Ð¡¼¤Î¥É¥é¥¤¥Ð¡¼¤Î·¿¼°¤Î¤½¤ì¤¾¤ì¤ò Screen Àá¤ÇÍ¿¤¨
+¤Þ¤¹¡£¥É¥é¥¤¥Ð¡¼¤Î·¿¼°¤Ï &dquot;SVGA&dquot; ¤ÎÀá¤Ç¤Ï (XF86_SVGA)¡¢ &dquot;VGA16&dquot; ¤ÎÀá¤Ç¤Ï
+(XF86_VGA16)¡¢&dquot;VGA2&dquot; ¤ÎÀá¤Ç¤Ï (XF86_Mono)¡¢&dquot;MONO&dquot; ¤Î
+Àá¤Ç¤Ï (XF86_Mono,
+XF86_VGA16) ¤È &dquot;ACCEL&dquot; ¤ÎÀá¤Ç¤Ï (XF86_S3, XF86_Mach32, XF86_Mach8,
+XF86_Mach64, XF86_8514, XF86_P9000, XF86_AGX, XF86_W32) ¤Ç¤¹¡£¤½¤ì¤¾¤ì¤Î
+Screen Àá¤Ï»ÈÍѤ¹¤ë¥â¥Ë¥¿¡¼(Monitor) ¤Îµ­½Ò¤È¥Ç¥Ð¥¤¥¹(Device) ¤Îµ­½Ò¤ò»ØÄê
+¤·¤Þ¤¹¡£
+
+Screen Àá¤Ï£±¤Ä¤Þ¤¿¤ÏÊ£¿ô¤Î &dquot;Display&dquot; ¤Î¹à¤ò´Þ¤ó¤Ç¤¤¤Þ¤¹¡££±¤Ä¤Î
+Display
+¹à¤Ï¥µ¡¼¥Ð¡¼¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¤½¤ì¤¾¤ì¤Î¿¼¤µ¤òÍ¿¤¨¤ë¤Ç¤·¤ç¤¦¡£
+&lsqb; ÌõÃí¡§¿¼¤µ¤È¤Ï¿§¿ô¤ä³¬Ä´¿ô¤òɽ¤ï¤¹¤Î¤ËɬÍפʥӥåȿô¤Ç¤¹¡£&rsqb;
+Display ¹à¤Ç¤Ï¡¢»È¤¤¤¿¤¤¥µ¡¼¥Ð¡¼¤Î²¾ÁÛ¥¹¥¯¥ê¡¼¥ó¤ÎÂ礭¤µ¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£²¾
+ÁÛ¥¹¥¯¥ê¡¼¥ó¤Ï¥â¥Ë¥¿¡¼¤Ëɽ¼¨¤Ç¤­¤ë¥¹¥¯¥ê¡¼¥ó¤ÎÂ礭¤µ¤è¤ê¤â¡¢Â礭¤¤¥ë¡¼¥È¥¦
+¥£¥ó¥É¥¦ (&dquot;root window&dquot;)¤ò»ý¤Ä¤³¤È¤¬½ÐÍè¤Þ¤¹¡ÊÎ㤨¤Ð 800x600 ¤Î
+¥Ç¥£¥¹¥×
+¥ì¥¤¤Ç1280x1024 ¤ÎÂ礭¤µ¤Î²¾ÁÛ¥¹¥¯¥ê¡¼¥ó¤ò»È¤¨¤Þ¤¹¡Ë¡£Virtual ¤È¤¤¤¦¥­¡¼¥ï
+¡¼¥É¤ò²¾ÁÛ¥¹¥¯¥ê¡¼¥ó¤ÎÂ礭¤µ¤ò»ØÄꤹ¤ë¤Î¤Ë»È¤¤¤Þ¤¹¡£Â¿¤¯¤Î¿·¤·¤¤¥¢¥¯¥»¥é¥ì
+¡¼¥¿¥µ¡¼¥Ð¤Ïɽ¼¨¤Ë»È¤ï¤ì¤Ê¤¤¥á¥â¥ê¤ò¥­¥ã¥Ã¥·¥å¤Ë»È¤¦¤³¤È¤ËÃí°Õ¤·¤Æ²¼¤µ¤¤¡£
+¥­¥ã¥Ã¥·¥å¤Ï¥á¥â¥ê¤ÎÁ´¤Æ¤ò²¾Áۥǥ£¥¹¥×¥ì¥¤¤Ë»È¤¦¤è¤¦¤ÊÌ¥ÎϤϤ¢¤ê¤Þ¤»¤ó¤¬¡¢
+¥­¥ã¥Ã¥·¥å¤Ë¥á¥â¥ê¤ò»Ä¤µ¤Ê¤¤¤è¤¦¤Ë¤·¤Æ¡¢¥á¥â¥ê¤ÎÁ´¤Æ¤ò²¾Áۥǥ£¥¹¥×¥ì¥¤¤Ë»È
+¤¦¤È¥µ¡¼¥Ð¡¼¤ÎÀ­Ç½¤Î 30 ¤«¤é 40&percnt; ¤Û¤É¤ò¾ÃÈñ¤·¤Þ¤¹¡£
+
+ºÇ¸å¤Ë¡¢Display Àá¤ÎÀßÄê¤Ï¥Ç¥£¥¹¥×¥ì¥¤¤Î¥â¡¼¥ÉÀßÄê¤Ç¤¹¡£¥µ¡¼¥Ð¡¼¤Î»ÈÍѤ·¤è
+¤¦¤È¤·¤Æ¤¤¤ëʪÍýŪ¤Ê¥Ç¥£¥¹¥×¥ì¥¤¤Î²òÁüÅ٤λØÄ꤬¤¢¤ê¤Þ¤¹¡£¤½¤Î̾Á°¤ÏǤ°Õ¤Ç
+¤¹¤¬¡¢Monitor Àá¤Ë¤¢¤ë¤É¤ì¤«¤È°ìÃפ·¤Æ¤¤¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£°ìÈ̤ˡ¢¤³¤ì¤é
+¤Î̾Á°¤Ï¥Ç¥£¥¹¥×¥ì¥¤¤Î²òÁüÅÙ¡ÊÎ㤨¤Ð &dquot;1024x768&dquot; ¡Ë¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤Ç
+¤·¤ç¤¦¤¬¡¢
+¤½¤ÎÄ̤ê¤Ç¤Ê¤±¤ì¤Ð¤¤¤±¤Ê¤¤Ìõ¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£É¬Íפʿô¤À¤±°ìÍ÷·Á¼°¤Ç»ØÄꤷ¤Þ
+¤¹¡£¤Þ¤ººÇ½é¤ÎÄêµÁ¤¬É¸½à¤Çµ¯Æ°¤µ¤ì¤ë²èÌ̤ˤʤꡢ²òÁüÅ٤ΰìÍ÷¤Ï¥³¥ó¥È¥í¡¼¥ë
+¥­¡¼ (Ctrl) ¡¢¥ª¥ë¥¿¥Í¥¤¥È¥­¡¼ (Alt) ¡¢¥Æ¥ó¥­¡¼¤Î + ¤òƱ»þ¤Ë²¡¤¹¤«¡¢¥³¥ó¥È
+¥í¡¼¥ë¥­¡¼ (Ctrl) ¡¢¥ª¥ë¥¿¥Í¥¤¥È¥­¡¼ (Alt) ¡¢¥Æ¥ó¥­¡¼¤Î - ¤òƱ»þ¤Ë²¡¤¹¤³¤È
+¤Ç½ä²ó¤Ç¤­¤ë²èÌ̤ÎÄêµÁ¤Ë¤Ê¤ê¤Þ¤¹¡£
+
+°Ê¾å¤ÇÀßÄê¤Ï½ª¤ï¤ê¤Ç¤¹¡£¤µ¤¢¡¢¿·¤·¤¤ XFree86 ¤ÎƳÆþ¥Æ¥¹¥È¤ò¤¹¤ë½àÈ÷¤¬½ÐÍè
+¤Þ¤·¤¿¡£
+
+<sect> ÈÆÍѥӥǥª¥â¡¼¥É¤Ë¤Ä¤¤¤Æ
+<p>
+&lsqb; ÌõÃí : ¤³¤³¤Ï¥Ç¡¼¥¿¤ÎºÆÍøÍѤΤ¿¤á¤ËËÝÌõ¤Ï¤·¤Þ¤»¤ó¡£ ¤¿¤È¤¨¡¢¥³¥á¥ó¥È¤Ë¤Ç
+¤â´Á»ú¤¬º®¤¸¤Ã¤Æ¸íưºî¤òµ¯¤³¤¹¤³¤È¤Ï̵¤¤¤È¡¢¿®¤¸¤Æ¤¤¤Þ¤¹¤¬¤Á¤ç¤Ã¤ÈÉݤ¤:-) &rsqb;
+
+<code>
+#
+# Mode Refresh Hor. Sync Dot-clock Interlaced? VESA?
+# ------------------------------------------------------------
+# 640x480 60Hz 31.5k 25.175M No No
+# 640x480 60Hz 31.5k 25.175M No No
+# 640x480 63Hz 32.8k 28.322M No No
+# 640x480 70Hz 36.5k 31.5M No No
+# 640x480 72Hz 37.9k 31.5M No Yes
+# 800x600 56Hz 35.1k 36.0M No Yes
+# 800x600 56Hz 35.4k 36.0M No No
+# 800x600 60Hz 37.9k 40.0M No Yes
+# 800x600 60Hz 37.9k 40.0M No No
+# 800x600 72Hz 48.0k 50.0M No Yes
+# 1024x768i 43.5Hz 35.5k 44.9M Yes No
+# 1024x768 60Hz 48.4k 65.0M No Yes
+# 1024x768 60Hz 48.4k 62.0M No No
+# 1024x768 70Hz 56.5k 75.0M No Yes
+# 1024x768 70Hz 56.25k 72.0M No No
+# 1024x768 76Hz 62.5k 85.0M No No
+# 1280x1024i 44Hz 51kHz 80.0M Yes No
+# 1280x1024i 44Hz 47.6k 75.0M Yes No
+# 1280x1024 59Hz 63.6k 110.0M No No
+# 1280x1024 61Hz 64.24k 110.0M No No
+# 1280x1024 74Hz 78.85k 135.0M No No
+
+#
+# 640x480@60Hz Non-Interlaced mode
+# Horizontal Sync = 31.5kHz
+# Timing: H=(0.95us, 3.81us, 1.59us), V=(0.35ms, 0.064ms, 1.02ms)
+#
+# name clock horizontal timing vertical timing flags
+ "640x480" 25.175 640 664 760 800 480 491 493 525
+
+#
+# Alternate 640x480@60Hz Non-Interlaced mode
+# Horizontal Sync = 31.5kHz
+# Timing: H=(1.27us, 3.81us, 1.27us) V=(0.32ms, 0.06ms, 1.05ms)
+#
+# name clock horizontal timing vertical timing flags
+ "640x480" 25.175 640 672 768 800 480 490 492 525
+
+#
+# 640x480@63Hz Non-Interlaced mode (non-standard)
+# Horizontal Sync = 32.8kHz
+# Timing: H=(1.41us, 1.41us, 5.08us) V=(0.24ms, 0.092ms, 0.92ms)
+#
+# name clock horizontal timing vertical timing flags
+ "640x480" 28.322 640 680 720 864 480 488 491 521
+
+#
+# 640x480@70Hz Non-Interlaced mode (non-standard)
+# Horizontal Sync = 36.5kHz
+# Timing: H=(1.27us, 1.27us, 4.57us) V=(0.22ms, 0.082ms, 0.82ms)
+#
+# name clock horizontal timing vertical timing flags
+ "640x480" 31.5 640 680 720 864 480 488 491 521
+
+#
+# VESA 640x480@72Hz Non-Interlaced mode
+# Horizontal Sync = 37.9kHz
+# Timing: H=(0.76us, 1.27us, 4.06us) V=(0.24ms, 0.079ms, 0.74ms)
+#
+# name clock horizontal timing vertical timing flags
+ "640x480" 31.5 640 664 704 832 480 489 492 520
+
+#
+# VESA 800x600@56Hz Non-Interlaced mode
+# Horizontal Sync = 35.1kHz
+# Timing: H=(0.67us, 2.00us, 3.56us) V=(0.03ms, 0.063ms, 0.70ms)
+#
+# name clock horizontal timing vertical timing flags
+ "800x600" 36 800 824 896 1024 600 601 603 625
+
+#
+# Alternate 800x600@56Hz Non-Interlaced mode
+# Horizontal Sync = 35.4kHz
+# Timing: H=(0.89us, 4.00us, 1.11us) V=(0.11ms, 0.057ms, 0.79ms)
+#
+# name clock horizontal timing vertical timing flags
+ "800x600" 36 800 832 976 1016 600 604 606 634
+
+#
+# VESA 800x600@60Hz Non-Interlaced mode
+# Horizontal Sync = 37.9kHz
+# Timing: H=(1.00us, 3.20us, 2.20us) V=(0.03ms, 0.106ms, 0.61ms)
+#
+# name clock horizontal timing vertical timing flags
+ "800x600" 40 800 840 968 1056 600 601 605 628 +hsync +vsync
+
+#
+# Alternate 800x600@60Hz Non-Interlaced mode
+# Horizontal Sync = 37.9kHz
+# Timing: H=(1.20us, 3.80us, 1.40us) V=(0.13ms, 0.053ms, 0.69ms)
+#
+# name clock horizontal timing vertical timing flags
+ "800x600" 40 800 848 1000 1056 600 605 607 633
+
+#
+# VESA 800x600@72Hz Non-Interlaced mode
+# Horizontal Sync = 48kHz
+# Timing: H=(1.12us, 2.40us, 1.28us) V=(0.77ms, 0.13ms, 0.48ms)
+#
+# name clock horizontal timing vertical timing flags
+ "800x600" 50 800 856 976 1040 600 637 643 666 +hsync +vsync
+
+#
+# 1024x768@43.5Hz, Interlaced mode (8514/A standard)
+# Horizontal Sync = 35.5kHz
+# Timing: H=(0.54us, 1.34us, 1.25us) V=(0.23ms, 0.23ms, 0.93ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1024x768i" 44.9 1024 1048 1208 1264 768 776 784 817 Interlace
+
+#
+# VESA 1024x768@60Hz Non-Interlaced mode
+# Horizontal Sync = 48.4kHz
+# Timing: H=(0.12us, 2.22us, 2.58us) V=(0.06ms, 0.12ms, 0.60ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1024x768" 65 1024 1032 1176 1344 768 771 777 806 -hsync -vsync
+
+#
+# 1024x768@60Hz Non-Interlaced mode (non-standard dot-clock)
+# Horizontal Sync = 48.4kHz
+# Timing: H=(0.65us, 2.84us, 0.65us) V=(0.12ms, 0.041ms, 0.66ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1024x768" 62 1024 1064 1240 1280 768 774 776 808
+
+#
+# VESA 1024x768@70Hz Non-Interlaced mode
+# Horizontal Sync=56.5kHz
+# Timing: H=(0.32us, 1.81us, 1.92us) V=(0.05ms, 0.14ms, 0.51ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1024x768" 75 1024 1048 1184 1328 768 771 777 806 -hsync -vsync
+
+#
+# 1024x768@70Hz Non-Interlaced mode (non-standard dot-clock)
+# Horizontal Sync=56.25kHz
+# Timing: H=(0.44us, 1.89us, 1.22us) V=(0.036ms, 0.11ms, 0.53ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1024x768" 72 1024 1056 1192 1280 768 770 776 806 -hsync -vsync
+
+#
+# 1024x768@76Hz Non-Interlaced mode
+# Horizontal Sync=62.5kHz
+# Timing: H=(0.09us, 1.41us, 2.45us) V=(0.09ms, 0.048ms, 0.62ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1024x768" 85 1024 1032 1152 1360 768 784 787 823
+
+#
+# 1280x1024@44Hz, Interlaced mode
+# Horizontal Sync=51kHz
+# Timing: H=(0.02us, 2.7us, 0.70us) V=(0.02ms, 0.24ms, 2.51ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1280x1024i" 80 1280 1296 1512 1568 1024 1025 1037 1165 Interlace
+
+#
+# Alternate 1280x1024@44Hz, Interlaced mode (non-standard dot-clock)
+# Horizontal Sync=47.6kHz
+# Timing: H=(0.42us, 2.88us, 0.64us) V=(0.08ms, 0.12ms, 0.96ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1280x1024i" 75 1280 1312 1528 1576 1024 1028 1034 1080 Interlace
+
+#
+# 1280x1024@59Hz Non-Interlaced mode (non-standard)
+# Horizontal Sync=63.6kHz
+# Timing: H=(0.36us, 1.45us, 2.25us) V=(0.08ms, 0.11ms, 0.65ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1280x1024" 110 1280 1320 1480 1728 1024 1029 1036 1077
+
+#
+# 1280x1024@61Hz, Non-Interlaced mode
+# Horizontal Sync=64.25kHz
+# Timing: H=(0.44us, 1.67us, 1.82us) V=(0.02ms, 0.05ms, 0.41ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1280x1024" 110 1280 1328 1512 1712 1024 1025 1028 1054
+
+#
+# 1280x1024@74Hz, Non-Interlaced mode
+# Horizontal Sync=78.85kHz
+# Timing: H=(0.24us, 1.07us, 1.90us) V=(0.04ms, 0.04ms, 0.43ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1280x1024" 135 1280 1312 1456 1712 1024 1027 1030 1064
+
+
+</code>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/Config.sgml,v 3.2 1997/01/26 04:34:16 dawes Exp $
+</verb>
+<hrule>
+
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ï xc/programs/Xserver/hw/xfree86/doc/sgml/Config.sgml,v 3.8 199
+6/08/13 11:30:51 ¤ò¡¢²¬ËÜ °ì¹¬
+( Kazuyuki Okamoto <url url="mailto:ikko-@pacific.rim.or.jp"
+name="&lt;ikko-@pacific.rim.or.jp&gt;"> ) ¤¬ XFree86 3.2 ¤ò
+ÆüËܤǥ¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¿Í¸þ¤±¤ËÏÂÌõ¤·¤¿¤â¤Î¤Ç¤¹¡£¤³¤³¤¬¤ª¤«¤·¤¤¤È¤«¡¢
+¤³¤³¤Ï¤³¤¦¤·¤¿¤Û¤¦¤¬¤¤¤¤¤È¤¤¤Ã¤¿¤´°Õ¸«¤¬¤¢¤ê¤Þ¤·¤¿¤é¡¢ÅŻҥ᡼¥ë¤Ç
+¤ªÃΤ餻²¼¤µ¤¤¡£
+¸¶Ê¸¤ÎÃøºî¸¢¤Ï XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ÎÏÂÌõ¤ÎÃøºî¸¢¤Ï
+XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤È²¬ËÜ¡¡°ì¹¬¤Ë¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤ÎÏÂÌõ¤ÎÉÔ¶ñ¹ç¤Ï»ä¤Ë¡¢
+ÅŻҥ᡼¥ë¤ÇÁ÷¤Ã¤Æ²¼¤µ¤¤¡£
+<hrule>
+&lsqb;EOF&rsqb;
+</article>
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/DocIndex.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/DocIndex.sgml
new file mode 100644
index 000000000..52e793f4f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/DocIndex.sgml
@@ -0,0 +1,117 @@
+<!doctype linuxdoc system>
+
+<article>
+
+<!-- Title information -->
+<title> XFree86 ¤Îʸ½ñ°ìÍ÷
+<author> XFree86 ¥×¥í¥¸¥§¥¯¥È ¼Ò
+<date> 1996 ǯ 10 ·î 23 Æü
+<trans> ²¬ËÜ¡¡°ì¹¬ Kazuyuki Okamoto &lt;ikko-@pacific.rim.or.jp&gt;
+
+<sect> ÍøÍѲÄǽ¤Êʸ½ñ <p>
+
+<itemize>
+<item> <htmlurl name="XFree86&tm; 3.2 ¥ê¥ê¡¼¥¹¥Î¡¼¥È"
+ url="RELNOTE.html">
+<item> <htmlurl name="XFree86&tm; 3.2 ¤Î¤¿¤á¤Î README"
+ url="README.html">
+<item> <htmlurl name="XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò Ãøºî¸¢É½¼¨"
+ url="CPYRIGHT.html">
+<item> <htmlurl name="XFree86 ¤Î¤ò¼êÁ᤯¤Ï¤¸¤á¤ë°Ù¤Î¼ê°ú¤­"
+ url="QStart.html">
+<item> <htmlurl name="XFree86 ¤Î XInput µ¡Ç½³ÈÄ¥"
+ url="xinput.html">
+<!--
+ <item> <htmlurl name="README for XFree86 3.1.2 on BSD/OS 2.0"
+ url="Bsdi.html">
+-->
+<item> <htmlurl name="README for XFree86 3.2 on FreeBSD 2.1.5"
+ url="FreeBSD.html">
+<item> <htmlurl name="Information for ISC Users"
+ url="isc.html">
+<item> <htmlurl name="Linux ¤ò»ÈÍѤ·¤Æ¤¤¤ë¿Í¤Î¤¿¤á¤Î¾ðÊó"
+ url="Linux.html">
+<item> <htmlurl name="README for XFree86 3.2 on LynxOS"
+ url="LynxOS.html">
+<!--
+<item> <htmlurl name="README for XFree86 3.2 on Mach"
+ url="Mach.html">
+-->
+<item> <htmlurl name="README for XFree86 3.2 on NetBSD and OpenBSD"
+ url="NetBSD.html">
+<item> <htmlurl name="README for XFree86 3.2 on OS/2"
+ url="OS2.html">
+<item> <htmlurl name="Notes on Rebuilding XFree86/OS2 from Scratch"
+ url="OS2note.html">
+<item> <htmlurl name="Information for SCO Users"
+ url="SCO.html">
+<item> <htmlurl name="Information for Solaris for x86 Users"
+ url="SOLX86.html">
+<item> <htmlurl name="Information for SVR4 Users"
+ url="SVR4.html">
+<item> <htmlurl name="XFree86 ¤ÎÀßÄê¤Ë¤Ä¤¤¤Æ"
+ url="Config.html">
+<item> <htmlurl name="XFree86 3.2 ¥¤¥ó¥¹¥È¡¼¥ë¥¬¥¤¥É"
+ url="INSTALL.html">
+<!--
+<item> <htmlurl name="X386/XFree86 ¤Î¥Ó¥Ç¥ª¾ðÊóÄ´À°¤ò¼«Ê¬¤Ç¹Ô¤Ê¤¦¤¿¤á¤Î¼ê°ú¤­"
+ url="VidModes.html">
+<item> <htmlurl name="XFree86 3.2 ¥ê¥ó¥¯¥­¥Ã¥È¤Î Readme"
+ url="LinkKit.html">
+-->
+<item> <htmlurl name="XFree86 ¤Ø (S)VGA ¥É¥é¥¤¥Ð¤òÄɲ乤ëÊýË¡"
+ url="VGADriv.html">
+<item> <htmlurl name="Information for using/developing external clock setting programs"
+ url="clkprog.html">
+<item> <htmlurl name="Notes on the AGX Server"
+ url="agx.html">
+<item> <htmlurl name="Information for ARK Logic Chipset Users"
+ url="ark.html">
+<item> <htmlurl name="ATI ¥Ü¡¼¥É¤Î README"
+ url="ati.html">
+<item> <htmlurl name="Cirrus ¥Á¥Ã¥×¥»¥Ã¥È¥æ¡¼¥¶¤Î¤¿¤á¤Î¾ðÊó"
+ url="cirrus.html">
+<item> <htmlurl name="Mach64 X ¥µ¡¼¥Ð¡¼ ¤Ç¤ÎÃí°Õ»ö¹à"
+ url="Mach64.html">
+<item> <htmlurl name="Information for Matrox Millennium Users"
+ url="MGA.html">
+<item> <htmlurl name="Information for NVidia NV1 / SGS-Thomson Users"
+ url="NV1.html">
+<item> <htmlurl name="Information for Oak Technologies Inc. Chipset Users"
+ url="Oak.html">
+<item> <htmlurl name="XFree86 3.2 P9000 Server Release Notes"
+ url="P9000.html">
+<item> <htmlurl name="S3 ¥Á¥Ã¥×¥»¥Ã¥È»ÈÍѼԤΤ¿¤á¤Î¾ðÊó"
+ url="S3.html">
+<item> <htmlurl name="Information for S3 ViRGE and ViRGE/VX Users"
+ url="S3V.html">
+<item> <htmlurl name="Information for Trident Chipset Users"
+ url="trident.html">
+<item> <htmlurl name="Information for Tseng Chipset Users"
+ url="tseng.html">
+<item> <htmlurl name="README.VIDEO7"
+ url="Video7.html">
+<item> <htmlurl name="Information for ET4000/W32 and ET6000 Chipset Users"
+ url="W32.html">
+<item> <htmlurl name="Information for Western Digital Chipset Users"
+ url="WstDig.html">
+</itemize>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/DocIndex.sgml,v 3.2 1997/01/26 04:34:17 dawes Exp $
+</verb>
+<hrule>
+
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ï xc/programs/Xserver/hw/xfree86/doc/sgml/DocIndex.sgml,v 3.18 1996/10/23 13:09:53 ¤ò¡¢²¬ËÜ °ì¹¬
+( Kazuyuki Okamoto <url url="mailto:ikko-@pacific.rim.or.jp"
+name="&lt;ikko-@pacific.rim.or.jp&gt;"> ) ¤¬ XFree86 3.2 ¤ò
+ÆüËܤǥ¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¿Í¸þ¤±¤ËÏÂÌõ¤·¤¿¤â¤Î¤Ç¤¹¡£¤³¤³¤¬¤ª¤«¤·¤¤¤È¤«¡¢
+¤³¤³¤Ï¤³¤¦¤·¤¿¤Û¤¦¤¬¤¤¤¤¤È¤¤¤Ã¤¿¤´°Õ¸«¤¬¤¢¤ê¤Þ¤·¤¿¤é¡¢ÅŻҥ᡼¥ë¤Ç
+¤ªÃΤ餻²¼¤µ¤¤¡£
+¸¶Ê¸¤ÎÃøºî¸¢¤Ï XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ÎÏÂÌõ¤ÎÃøºî¸¢¤Ï
+XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤È²¬ËÜ¡¡°ì¹¬¤Ë¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤ÎÏÂÌõ¤ÎÉÔ¶ñ¹ç¤Ï»ä¤Ë¡¢
+ÅŻҥ᡼¥ë¤ÇÁ÷¤Ã¤Æ²¼¤µ¤¤¡£
+<hrule>
+&lsqb;EOF&rsqb;
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/FreeBSD.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/FreeBSD.sgml
new file mode 100644
index 000000000..cf3f1aac3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/FreeBSD.sgml
@@ -0,0 +1,559 @@
+<!doctype linuxdoc system>
+
+<article>
+<title> README for XFree86 3.1.2 on FreeBSD 2.0.5
+<author>Rich Murphey, David Dawes</author>
+<date>1995ǯ7·î24Æü</date>
+<trans>Takefumi Tsukada(ÄÍÅÄ ¹äʸ)
+<abstract>
+¤³¤Îʸ½ñ¤ÏXFree86 3.1.2¤Ë´Þ¤Þ¤ì¤ë¡¢README.FreeBSD¤òÆüËܸìÌõ¤·¤¿¤â¤Î¤Ç¤¹¡£
+ÆâÍÆ¤Ë´Ø¤·¤Æ¤Ï¤Û¤È¤ó¤É½¤Àµ¤·¤Æ¤¤¤Þ¤»¤ó¤Î¤Ç¸Å¤¤ÆâÍÆ¤â»Ä¤Ã¤Æ¤¤¤Þ¤¹¡£
+</abstract>
+<toc>
+
+<sect>XFree86¤È¤Ï
+<p>XFree86¤Ï¡¢¿ô¡¹¤Î¥Ð¡¼¥¸¥ç¥ó¤Î¥¤¥ó¥Æ¥ë¥Ù¡¼¥¹¤ÎUNIX¤ò¥µ¥Ý¡¼¥È¤¹¤ë¡¢X11R6¤Î
+°Ü¿¢Êª¤Ç¤¹¡£¤½¤Îµ¯¸»¤ÏX11R5¤È¶¦¤ËÇÛÉÛ¤µ¤ì¤¿X¥µ¡¼¥Ð¤Ç¤¢¤ëX386 1.2¤ËÁ̤뤳¤È
+¤¬¤Ç¤­¤Þ¤¹¡£ËÜ¥ê¥ê¡¼¥¹¤Ï¿¤¯¤Î¥Ð¥°FIX¤À¤±¤Ç¤Ê¤¯¡¢Â¿¤¯¤Î¿·µ¡Ç½¡¦À­Ç½²þÁ±
+¤Ë¤è¤ê¹½À®¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ËÜ¥ê¥ê¡¼¥¹¤Ï¡¢X¥³¥ó¥½¡¼¥·¥¢¥à¤ÎX11R6¤ËÂФ¹¤ë¥½¡¼¥¹
+¥Ñ¥Ã¥Á¤È¤·¤Æ¡¢¤Þ¤¿¡¢Â¿¤¯¤Î¥¢¡¼¥­¥Æ¥¯¥Á¥ãÍѤ˥Х¤¥Ê¥ê¥³¡¼¥É¤È¤·¤ÆÆþ¼ê²Äǽ¤Ç
+¤¹¡£
+
+Ãøºî¸¢¹ðÃΤˤĤ¤¤Æ¤Ï¡¢<url url="COPYRIGHT.html" name="Copyright Notice">
+¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡£
+
+XFree86¤Î¥½¡¼¥¹¥³¡¼¥É¤Ï°Ê²¼¤Îanonymous FTP¥µ¥¤¥È¤è¤êÆþ¼ê²Äǽ¤Ç¤¹¡£
+
+<url name="ftp.XFree86.org:/pub/XFree86/current"
+url="ftp://ftp.XFree86.org/pub/XFree86/current">
+
+XFree86¤ÎFreeBSDÍѥХ¤¥Ê¥ê¥³¡¼¥É¤Ï°Ê²¼¤Îanonymous FTP¥µ¥¤¥È¤è¤êÆþ¼ê²Ä
+ǽ¤Ç¤¹¡£
+
+<url name="ftp.XFree86.org:/pub/XFree86/current/binaries/FreeBSD-2.0.5"
+url="ftp://ftp.XFree86.org/pub/XFree86/current/binaries/FreeBSD-2.0.5">
+<p>
+<url name="XFree86.cdrom.com:/pub/XFree86/current/binaries/FreeBSD-2.0.5"
+url="ftp://XFree86.cdrom.com/pub/XFree86/current/binaries/FreeBSD-2.0.5">
+
+
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ë´Ø¤·¤Æ¡¢¥³¥á¥ó¥È¤äÄ󰯤¬¤¢¤ë¾ì¹ç¤Ë¤Ï¡¢
+<em/Rich-Murphey@Rice.edu/ ¤Þ¤¿¤Ï¡¢<em/XFree86@XFree86.org/
+¤ËE-Mail¤òÁ÷¤Ã¤Æ²¼¤µ¤¤¡£¤½¤ì¤òÈ¿±Ç¤µ¤»¤ë¤³¤È¤¬¤Ç¤­¤ë¤Ç¤·¤ç¤¦¡£
+
+<sect>¥Ð¥¤¥Ê¥ê¥³¡¼¥É¤Î¥¤¥ó¥¹¥È¡¼¥ë
+<p>
+¥Ç¥£¥¹¥¯ÍÆÎ̤òÀáÌó¤·¤¿¤¤¾ì¹ç¤Ï¡¢¤Þ¤º¡¢Å¸³«¤¹¤ë¥¢¡¼¥«¥¤¥Ö¤òÁªÂò¤·¤Þ¤¹¡£¤É¤ì¤ò
+Ÿ³«¤¹¤Ù¤­¤«¤ï¤«¤é¤º¡¢¤«¤Ä¡¢52M¥Ð¥¤¥È°Ê¾å¤Î¤Î¥Ç¥£¥¹¥¯ÍÆÎ̤¬¤¢¤ë¾ì¹ç¤Ï¡¢Á´¤Æ
+Ÿ³«¤¹¤ë¤Î¤¬³Î¼Â¤Ç¤¹¡£
+
+ºÇÄã¸Â¡¢<tt/X312*.tgz/¤Î¤¦¤Á¡¢'ɬ¿Ü¥¢¡¼¥«¥¤¥Ö'¤Ë²Ã¤¨¡¢¾¯¤Ê¤¯¤È¤â°ì¤Ä¡¢
+»ÈÍѤ¹¤ëVGA¥«¡¼¥É¤ËŬ¹ç¤¹¤ëX¥µ¡¼¥Ð¤òŸ³«¤¹¤ë¤³¤È¤¬É¬ÍפǤ¹¡£ºÇÄã¸Âɬ
+Íפʼ¹ÔÍѥХ¤¥Ê¥ê¤Î¤ß¤ò¥¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¾ì¹ç¡¢9M¥Ð¥¤¥È¤Î¥Ç¥£¥¹¥¯ÍÆÎ̤¬É¬Í×
+¤Ç¤¹¡£
+
+<descrip>
+<tag/ɬ¿Ü¥¢¡¼¥«¥¤¥Ö(6.7Mb):/
+
+<descrip>
+<tag/X312bin.tgz/
+ Á´¤Æ¤Î¼Â¹Ô²Äǽ¤ÊX¤Î¥¯¥é¥¤¥¢¥ó¥È¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥½¥Õ¥È¤È¶¦Í­¥é¥¤¥Ö¥é¥ê
+<tag/X312fnts.tgz/
+ 75 dpi¥Õ¥©¥ó¥È¾
+<tag/X312lib.tgz/
+ ¼Â¹Ô»þ¤ËɬÍפʥǡ¼¥¿¥Õ¥¡¥£¥ë
+</descrip>
+<tag/¥«¥¹¥¿¥Þ¥¤¥ººÑ¤ß¤ÎÄêµÁ¥Õ¥¡¥¤¥ë¤¬¤Ê¤¤¾ì¹çɬÍפʥ¢¡¼¥«¥¤¥Ö:
+
+<descrip>
+<tag/X312xicf.tgz/
+ xinit¼Â¹Ô»þ¤Ë»²¾È¤µ¤ì¤ë¥«¥¹¥¿¥Þ¥¤¥ºÍÑÄêµÁ¥Õ¥¡¥¤¥ë
+<tag/X312xdcf.tgz/
+ xdm¼Â¹Ô»þ¤Ë»²¾È¤µ¤ì¤ë¥«¥¹¥¿¥Þ¥¤¥ºÍÑÄêµÁ¥Õ¥¡¥¤¥ë
+</descrip>
+
+<tag/¥µ¡¼¥Ð¥¢¡¼¥«¥¤¥Ö(¾¯¤Ê¤¯¤È¤â°ì¤ÄÁªÂò) (~2.3Mb):/
+
+<descrip>
+<tag/X3128514.tgz/
+ IBM 8514 ¤ª¤è¤Ó´°Á´¸ß´¹¥Á¥Ã¥×ÍÑ8-bit¥«¥é¡¼¥µ¡¼¥Ð
+<tag/X312AGX.tgz/
+ AGX,XGA¥Ü¡¼¥ÉÍÑ 8,16-bit¥«¥é¡¼¥µ¡¼¥Ð
+<tag/X312Ma32.tgz/
+ ATI Mach32¥Ü¡¼¥ÉÍÑ 8,16-bit¥«¥é¡¼¥µ¡¼¥Ð
+<tag/X312Ma64.tgz/
+ ATI Mach64¥Ü¡¼¥ÉÍÑ 8,16,24-bit¥«¥é¡¼¥µ¡¼¥Ð
+<tag/X312Ma8.tgz/
+ ATI Mach8¥Ü¡¼¥ÉÍÑ 8-bit¥«¥é¡¼¥µ¡¼¥Ð
+<tag/X312Mono.tgz/
+ VGA,Super-VGA,Hercules,¤½¤Î¾¤Î¥Ü¡¼¥ÉÍÑ1-bit¥â¥Î¥¯¥í¥µ¡¼¥Ð
+<tag/X312P9K.tgz/
+ Weitek P9000¥Ü¡¼¥É(Diamond Viper)ÍÑ 8,16,24-bit¥«¥é¡¼¥µ¡¼¥Ð
+<tag/X312S3.tgz/
+ S3 ¥Ü¡¼¥É(&num;9 GXE,Actix GE32,SPEA Mercury,STB Pegasus)ÍÑ 8,16,24-bit¥«¥é¡¼¥µ¡¼¥Ð
+<tag/X312SVGA.tgz/
+ Super-VGA¥«¡¼¥ÉÍÑ 8-bit¥«¥é¡¼¥µ¡¼¥Ð
+<tag/X312VG16.tgz/
+ VGA,Super-VGA¥«¡¼¥ÉÍÑ 4-bit¥«¥é¡¼¥µ¡¼¥Ð
+<tag/X312W32.tgz/
+ ET4000/W32,/W32i,W32p¥«¡¼¥ÉÍÑ 8-bit¥«¥é¡¼¥µ¡¼¥Ð
+<tag/X312nest.tgz/
+ ¾¤Îdisplay¾å¤Ç¥¯¥é¥¤¥¢¥ó¥Èwindow¤È¤·¤ÆÆ°ºî¤¹¤ë¥Í¥¹¥È¡Ê¤¤¤ì»Ò¡Ë¥µ¡¼¥Ð
+</descrip>
+
+<tag/ ¥ª¥×¥·¥ç¥Ê¥ë:/
+<descrip>
+
+<tag/X312doc.tgz/
+ (.5Mb) READMEs
+
+<tag/X312man.tgz/
+ (1.7Mb) man pages
+<tag/X312f100.tgz/
+ (1.8Mb)100dpi¥Õ¥©¥ó¥È
+<tag/X312fscl.tgz/
+ (1.6Mb)Speedo,Type1 ¥Õ¥©¥ó¥È
+<tag/X312fnon.tgz/
+ (3.3Mb)ÆüËÜ¸ì¡¢Ãæ¹ñ¸ì¡¢¤½¤Î¾¤ÎÈó±Ñ¸ìÍÑ¥Õ¥©¥ó¥È
+<tag/X312fcyr.tgz/
+ (.4Mb)¥­¥ê¥ëʸ»ú¥Õ¥©¥ó¥È
+<tag/X312fsrv.tgz/
+ (.3Mb)¥Õ¥©¥ó¥È¥µ¡¼¥Ð¤È¤½¤Îman page
+<tag/X312prog.tgz/
+ (3.9Mb)¥³¥ó¥Ñ¥¤¥ë»þ¤Ë¤Î¤ßɬÍפÊconfig,lib*.a,*.h¥Õ¥¡¥¤¥ë
+<tag/X312link.tgz/
+ (7.8Mb)X¥µ¡¼¥Ð¤ÎºÆ¹½À®¥­¥Ã¥È
+<tag/X312pex.tgz/
+ (.5Mb)PEX¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÇɬÍפÊPEX ¥Õ¥©¥ó¥È,¶¦Í­¥é¥¤¥Ö¥é¥ê
+<tag/X312lbx.tgz/
+ (.2Mb)¶¹ÂÓ°èX proxy ¥µ¡¼¥Ð¤È¤½¤Î¥é¥¤¥Ö¥é¥ê
+</descrip>
+</descrip>
+
+ÆÈΩ¤·¤¿xdm¥¢¡¼¥«¥¤¥Ö¤Ï̵¤¯¤Ê¤Ã¤¿¤³¤È¤ËÃí°Õ¤·¤Æ²¼¤µ¤¤¡£FreeBSD-2.0¤ä
+¤½¤ì°Ê¹ß¤Ç¤Ï¡¢¤³¤ì¤ò¶¦Í­¥é¥¤¥Ö¥é¥ê¤Ç°·¤Ã¤Æ¤¤¤ë¤¿¤á¡¢xdm¥Ð¥¤¥Ê¥ê¼«¿È¤Ë¤Ï
+des¤Ï´Þ¤Þ¤ì¤º¡¢ÆÈΩ¤·¤¿tar¥¢¡¼¥«¥¤¥Ö¤È¤·¤ÆÄ󶡤¹¤ëɬÍפ¬Ìµ¤¯¤Ê¤ê¤Þ¤·¤¿¡£
+
+<sect1>¥Õ¥ë¥¤¥ó¥¹¥È¡¼¥ë
+<p>
+<enum>
+<item> ¤¤¤¯¤Ä¤«¤Î¼Â¹Ô²Äǽ¥Õ¥¡¥¤¥ë¤Ïset-user-id¤µ¤ì¤ë¤Î¤Ç¥¢¡¼¥«¥¤¥Ö¤òŸ³«¤¹¤ë
+ ¤¿¤á¤Ëɬ¤ºroot¤Ç¥í¥°¥¤¥ó¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£root¤Ç¤Ê¤¯ÄÌ¾ï¥æ¡¼¥¶¤Ç
+ Ÿ³«¤¹¤ë¤È¥µ¡¼¥Ð¤Ï°Û¾ï½ªÎ»¤¹¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£¤Þ¤¿¡¢X¥µ¡¼¥Ð¤ÏÆÃÊ̤Ê
+ ¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¡Ê¥Õ¥¡¥¤¥ë°À­¡Ë¤òɬÍפȤ¹¤ë¤Î¤Ç``<tt/umask/''¤ÎÃͤò
+ <tt/022/ ¤ËÀßÄꤷ¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£
+<tscreen><verb>
+ % su
+ # umask 022
+</verb></tscreen>
+
+<item> <tt>/usr</tt>¥Ñ¡¼¥Æ¥£¥·¥ç¥ó¤Ë52Mb°Ê¾å¤Î¶õ¤­ÍÆÎ̤¬¤¢¤ë¾ì¹ç¡¢
+ ``<tt>cd /usr</tt>''¤È¤·¤Æ¡¢£³¤Ë¥¹¥­¥Ã¥×¤·¤Æ²¼¤µ¤¤¡£Ìµ¤¤¾ì¹ç¤Ï¡¢
+ ¾¤Î¥Ñ¡¼¥Æ¥£¥·¥ç¥ó¤Ë¥Ç¥£¥ì¥¯¥È¥ê¤òºî¤ê¡¢<tt>/usr</tt>¤ÎÃæ¤Ø¥·
+ ¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤ò¤Ï¤ê¤Þ¤¹¡£
+
+<tscreen><verb>
+ # cd /usr/local
+ # mkdir X11R6
+ # ln -s /usr/local/X11R6 /usr/X11R6
+</verb></tscreen>
+
+<item>Á´¥¢¡¼¥«¥¤¥Ö¤òŸ³«
+
+sh¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¡Êroot¤Ï¿¤¯¤Î¾ì¹ç¤³¤Á¤é¡Ë:
+
+<tscreen><verb>
+ # for i in X312*.tgz; do
+ # tar -xzf $i
+ # done
+</verb></tscreen>
+
+¤Þ¤¿¤Ïcsh¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç:(ÌõÃí:¸½ºß¤ÎFreeBSD¤Ç¤Ïroot¤âɸ½à¤Çcsh)
+
+<tscreen><verb>
+ % foreach i (X312*.tgz)
+ % tar -xzf $i
+ % end
+</verb></tscreen>
+
+
+<item> »ÈÍѤ·¤Æ¤¤¤ë¥Ó¥Ç¥ª¥Ü¡¼¥É¤ËŬ¹ç¤¹¤ë¥µ¡¼¥Ð¤ò»Ø¤·¼¨¤¹¤è¤¦¤Ë``<tt/X/''
+ ¤È¤¤¤¦Ì¾Á°¤Ç¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤òºîÀ®¤·¤Þ¤¹¡£¤½¤ì¤¾¤ì¤Î¥µ¡¼¥Ð¤¬¤É¤Î
+ ¥Ó¥Ç¥ª¥Á¥Ã¥×¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤«¤Ï¡¢<em/XF86_*/ ¤Îman pages¤Ë¼¨¤µ¤ì¤Æ
+ ¤¤¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢ET4000¥Ù¡¼¥¹¤Î¥«¡¼¥É¤Î¾ì¹ç¤Ï¡¢XF86_SVGA¥µ¡¼¥Ð¤ò
+ »ÈÍѤ·¤Þ¤¹¡£
+
+
+<tscreen><verb>
+ # cd /usr/X11R6/bin; rm X; ln -s XF86_SVGA X
+</verb></tscreen>
+</enum>
+
+<sect1>ºÇ¾®¥¤¥ó¥¹¥È¡¼¥ë
+<p>
+ºÇ½é¤Ë¾åµ­¤Î1,2¤ò¼Â¹Ô¤·¤Þ¤¹¡£¤½¤·¤Æ¡¢É¬¿Ü¥¢¡¼¥«¥¤¥Ö¤òŸ³«¤·¤Þ¤¹¡£
+
+<tscreen><verb>
+ # for i in bin fnts lib xicf; do
+ # tar -xzf X312$i.tgz
+ # done
+</verb></tscreen>
+
+»ÈÍѤ·¤Æ¤¤¤ëvga¥«¡¼¥É¤ËŬ¹ç¤¹¤ë¥µ¡¼¥Ð¥¢¡¼¥«¥¤¥Ö¤òŸ³«¤·¤Þ¤¹¡£
+¤½¤ì¤¾¤ì¤Î¥µ¡¼¥Ð¤¬¤É¤Î¥Ó¥Ç¥ª¥Á¥Ã¥×¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤«¤Ï¡¢¥µ¡¼¥Ð¤Î¤Îman pages
+<tt>X11R6/man/man1/XF86_*</tt>¼¨¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢ET4000¥Ù¡¼¥¹¤Î¥«
+¡¼¥É¤Î¾ì¹ç¤Ï¡¢XF86_SVGA¥µ¡¼¥Ð¤ò»ÈÍѤ·¤Þ¤¹¡£
+
+<tscreen><verb>
+ # tar -xzf X312SVGA.tgz
+ # cd /usr/X11R6/bin; rm X; ln -s XF86_SVGA X
+</verb></tscreen>
+
+<sect1>¥Õ¥ë¥¤¥ó¥¹¥È¡¼¥ë¡¢¤Þ¤¿¤ÏºÇ¾®¥¤¥ó¥¹¥È¡¼¥ë¸å¤Ë¤¹¤ë¤³¤È:
+<p>
+¤Þ¤À¹Ô¤ï¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢sh¤Î¤¿¤á¤Ë<tt>/etc/profile</tt>Æâ¤Î¥Ç¥Õ¥©¥ë¥È¤Î
+¥Ñ¥¹¤Ë¡¢¤Þ¤¿¡¢csh¤Î¤¿¤á¤Ë<tt>/etc/csh.login</tt>¤Ë/usr/X11R6/bin¤òÄɲä·¤Þ¤¹¡£
+
+<tscreen><verb>
+ # echo 'set path = ($path /usr/X11R6/bin)' >>/etc/csh.login
+ # echo 'PATH=$PATH:/usr/X11R6/bin' >>/etc/profile
+</verb></tscreen>
+
+¤Þ¤¿¤Ï¡¢X¤ò»ÈÍѤ¹¤ëÁ´¥æ¡¼¥¶¤Î¥·¥§¥ë¤Î``path''ÊÑ¿ô¤Ë<tt>/usr/X11R6/bin</tt>
+¤¬Æþ¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£
+
+¤½¤Î¸å¥ê¥Ö¡¼¥È¤¹¤ë¤«¡¢root¤Ë¤Ê¤Ã¤Æ¶¦Í­¥é¥¤¥Ö¥é¥ê¤¬<tt/ld.so/¤Î¥­¥ã¥Ã¥·¥å¤Ë
+Æþ¤ë¤è¤¦¤Ë<tt/ldconfig/¤ò¼Â¹Ô¤·¤Þ¤¹¡£
+
+<tscreen><verb>
+ # ldconfig /usr/lib /usr/local/lib /usr/X11R6/lib
+</verb></tscreen>
+
+ÀßÄêºÑ¤ß¤Î<tt>X11R6/lib/X11/xinit/xinitrc</tt>¤Þ¤¿¤Ï¡¢
+<tt>X11R6/lib/X11/xdm/* </tt>¤¬¤¢¤ë¾ì¹ç¡¢<tt/xinit-config/¤Þ¤¿¤Ï
+<tt/xdm-config/¤Î¥¢¡¼¥«¥¤¥Ö¤ò¾Êά¤¹¤ë¤«¡¢Ê̤ˤξì½ê¤ËŸ³«¤·¡¢É¬ÍפÊÀßÄê¤Ë±þ
+¤¸¤Æ¥Þ¡¼¥¸¤·¤Þ¤¹¡£
+
+<tt/fscl/¤È<tt/f100/¥¢¡¼¥«¥¤¥Ö¤Ï¥ª¥×¥·¥ç¥Ê¥ë¤Ç¡¢¥Ç¥£¥¹¥¯ÍÆÎ̤òÀáÌó¤·¤¿¤¤¾ì¹ç
+¤Ë¤Ï¾Êά²Äǽ¤Ç¤¹¡£¤Þ¤¿¡¢¥ª¥×¥·¥ç¥Ê¥ë¤Ê<tt/link/¥¢¡¼¥«¥¤¥Ö¤ÏX¥µ¡¼¥Ð¤Î¥ê¥³¥ó¥Õ
+¥£¥°¤ä¥«¥¹¥¿¥Þ¥¤¥º¤ò²Äǽ¤Ë¤·¤Þ¤¹¡£¥ª¥×¥·¥ç¥Ê¥ë¤Ê<tt/prog/¥¢¡¼¥«¥¤¥Ö¤Ï¡¢£Ø¤Î
+¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥½¥Õ¥È¤òºîÀ®¤·¤¿¤ê¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¾ì¹ç¤Ë¤Î¤ßɬÍפǤ¹¡£¥ª¥×¥·¥ç
+¥Ê¥ë¤Ê<tt/pex/¥¢¡¼¥«¥¤¥Ö¤Ïpex¥¯¥é¥¤¥¢¥ó¥È¤ä3D¥°¥é¥Õ¥£¥Ã¥¯¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥½
+¥Õ¥È¤ÎºîÀ®¤Î¤¿¤á¤Î¥é¥¤¥Ö¥é¥ê¤ò´Þ¤ß¤Þ¤¹¡£
+
+<quote>
+<bf/Note:/ ¥Õ¥©¥ó¥È¥Õ¥¡¥£¥ë¤Ïuncompress¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¤¬¡¢¤â¤·¡¢¤½¤ì¤é¤ò
+uncompress¤¹¤ë¾ì¹ç¤Ï¡¢³ºÅö¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Ç¡¢<tt/mkfontdir/¤ò¼Â¹Ô¤·¤Ê¤±¤ì
+¤Ð¤Ê¤ê¤Þ¤»¤ó¡£¤½¤ì¤ò¹Ô¤ï¤Ê¤¤¤È¡¢``<tt/could not open dfault font 'fixed'/ ''
+¤È¥á¥Ã¥»¡¼¥¸¤ò½ÐÎϤ·¤Æ¡¢¥µ¡¼¥Ð¤Ï°Û¾ï½ªÎ»¤·¤Þ¤¹¡£
+</quote>
+
+ɸ½àŪ¤ÊFreeBSD 1.1.5¥·¥¹¥Æ¥à¤Ç»ÈÍѤ¹¤ë¾ì¹ç¡¢¤³¤Î¾Ï¤Î»Ä¤ê¤ÎÉôʬ¤ò¾Êά
+¤Ç¤­¤Þ¤¹¡£¤½¤ì°Ê³°¤Î¾ì¹ç¡¢login process(getty)¤¬Æ°ºî¤·¤Æ¤¤¤ë¡¢Í½È÷¤Î
+²¾ÁÛ¥³¥ó¥½¡¼¥ë¤¬¤¢¤ë¤«³Îǧ¤·¤Þ¤¹¡£¤Þ¤º¡¢¤¤¤¯¤Ä¤Î²¾ÁÛ¥³¥ó¥½¡¼¥ë¤¬¤¢¤ë¤«
+³Îǧ¤·¤Þ¤¹¡£
+
+<tscreen><verb>
+ % dmesg|grep sc
+ sc0 at 0x60-0x6f irq 1 on motherboard
+ sc0: VGA color <8 virtual consoles>
+</verb></tscreen>
+
+¤½¤·¤Æ¡¢getty¤¬Í­¸ú²½¤µ¤ì¤Æ¤¤¤Ê¤¤<tt/ttyv?/¥Ç¥Ð¥¤¥¹¤¬¾¯¤Ê¤¯¤È¤â£±¤Ä¤¢¤ë¤«¡¢
+<tt>/etc/ttys</tt>¤ò³Îǧ¤·¤Þ¤¹¡£FreeBSD 1.1.5¤Ç¤Ï¡¢ºÇ½é¤Î3¤Ä¤¬``on''¤ÇºÇ¸å¤Î1
+¤Ä¤¬``off''¤Ë¤Ê¤Ã¤Æ¤¤¤Æ¡¢3¤Ä¤À¤±getty¤¬¼Â¹Ô¤µ¤ì¤Æ¤¤¤Þ¤¹¡£
+
+
+<tscreen><verb>
+ % grep ttyv /etc/ttys
+ ttyv0 "/usr/libexec/getty Pc" cons25 on secure
+ ttyv1 "/usr/libexec/getty Pc" cons25 on secure
+ ttyv2 "/usr/libexec/getty Pc" cons25 on secure
+ ttyv3 "/usr/libexec/getty Pc" cons25 off secure
+</verb></tscreen>
+
+¥«¡¼¥Í¥ë¤Ë¾¯¤Ê¤¯¤È¤â4¤Ä¤Î²¾ÁÛüËö(VT)¤¬¤¢¤ê¡¢3¤Ä¤À¤±getty¤¬¼Â¹Ô¤µ¤ì¤Æ¤¤
+¤ë¾ì¹ç¡¢¤³¤ì¤Ï¤¿¤¤¤Ø¤óŬÅö¤ÊÀßÄê¤Ç¤¹¡£²¾ÁÛüËö¤¬ÉÔ­¤·¤Æ¤¤¤ë¾ì¹ç¡¢
+<tt>/etc/ttys</tt>¤Ç``on''¤«¤é``off''¤ËÊѹ¹¤·¡¢getty¤ò1¤Ä̵¸ú²½¤¹¤ë¤«¡¢
+²¼µ­¤ÇÀâÌÀ¤¹¤ë¤è¤¦¤Ë¡¢¤è¤ê¿¤¯¤Î²¾ÁÛüËö(VT)¤ò»È¤¨¤ë¤è¤¦¤Ë¿·¤¿¤Ê¥«¡¼¥Í¥ë
+¤ò¹½À®¤·¤Þ¤¹¡£
+
+<sect>¥Ç¥£¥¹¥×¥ì¥¤¥Þ¥Í¡¼¥¸¥ã(xdm)¤Î¥¤¥ó¥¹¥È¡¼¥ë
+<p>
+¥Ç¥£¥¹¥×¥ì¥¤¥Þ¥Í¡¼¥¸¥ã¤Ë¤è¤Ã¤Æ¡¢PC¤òXüËö¤Î¤è¤¦¤Ë»ÈÍѤ¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£
+¥Ç¥£¥¹¥×¥ì¥¤¥Þ¥Í¡¼¥¸¥ã¤Ï¡¢X²¼¤Çưºî¤¹¤ë¥í¥°¥¤¥ó¥¹¥¯¥ê¡¼¥ó¤òÄ󶡤·¤Þ¤¹¡£
+
+ºÇ¤â´Êñ¤Ë¡¢¥Ö¡¼¥È»þ¤Ë¥Ç¥£¥¹¥×¥ì¥¤¥Þ¥Í¡¼¥¸¥ã¤ò¼«Æ°Åª¤Ëµ¯Æ°¤¹¤ë¤Ë¤Ï¡¢
+»ÈÍѤµ¤ì¤Æ¤¤¤Ê¤¤²¾ÁÛüËö¤ËÂФ·¤Æ¡¢<tt>/etc/ttys</tt>¤Ë°Ê²¼¤Î1¹Ô¤òÄɲä·
+¤Þ¤¹¡£
+
+<tscreen><verb>
+ ttyv4 "/usr/X11R6/bin/xdm -nodaemon" xterm on secure
+</verb></tscreen>
+
+<tt>/usr/X11R6/bin/X</tt>¤¬»ÈÍѤ·¤Æ¤¤¤ë¥Ó¥Ç¥ª¥«¡¼¥É¤ËŬ¹ç¤¹¤ëX¥µ¡¼¥Ð¤Ø¤Î¥·
+¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤³¤È¤ò³Îǧ¤¹¤ë¤«¡¢¤Þ¤¿¤Ï¡¢
+<tt>/usr/X11R6/lib/X11/xdm</tt>Æâ¤Î Xservers¤È¤¤¤¦¥Õ¥¡¥£¥ë¤Ç¡¢X¥µ¡¼¥Ð¤Î¥Ñ¥¹
+̾¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+
+<tt>/etc/ttys</tt>¤ÎÊѹ¹¤Ï¡¢¥ê¥Ö¡¼¥È¤¹¤ë¤«¡¢``<tt/kill -HUP 1/''¤È¤·¤Æinitd
+¤ËÂФ·¤Æ¶¯À©Åª¤Ë<tt>/etc/ttys</tt>¤ÎºÆÆÉ¹þ¤ò¹Ô¤ï¤»¤Ê¤¤¤È¸ú²Ì¤¬¤¢¤ê¤Þ¤»¤ó¡£
+¤Þ¤¿¡¢root¤Ç¥í¥°¥¤¥ó¤·¡¢¥³¥ó¥½¡¼¥ë¾å¤Ç¼êư¤Ë¤è¤ê``<tt/xdm -nodaemon/''¤È¤·
+¤Æ¥Ç¥£¥¹¥×¥ì¥¤¥Þ¥Í¡¼¥¸¥ã¤ò¥Æ¥¹¥È¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£
+
+<sect>¥Ï¡¼¥É¥¦¥¨¥¢¤Ë¹ç¤ï¤»¤¿X¤ÎÀßÄê
+<p>
+¤É¤ó¤Ê¥â¥Ë¥¿¡¢¥Ó¥Ç¥ª¥«¡¼¥É¡¢¥Þ¥¦¥¹¤Ç»ÈÍѤ¹¤ë¤«¡¢<tt/XF86Config/¤ÇX¥µ¡¼¥Ð¤Ë
+»Ø¼¨¤·¤Þ¤¹¡£»ÈÍѤ¹¤ëÀµ³Î¤Ê¥Ï¡¼¥É¥¦¥¨¥¢¤ò»Ø¼¨¤Ç¤­¤ë¤è¤¦¤Ë<tt/XF86Config/
+¤ò<em/ɬ¤º/ºîÀ®¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+
+XFree86-3.1¤Ï¿·¤·¤¤¥Õ¥¡¥¤¥ë¥Õ¥©¡¼¥Þ¥Ã¥È¤ò»ÈÍѤ·¤Æ¤¤¤Þ¤¹¡£<em/XF86Config/¤Î
+man page¤È¡¢°ìÈÌŪ¤ÊÆâÍÆ¤Î<url url=INSTALL.html name=INSTALL>¥Õ¥¡¥¤¥ë¤òÀâ
+ÌÀ½ñ¤È¤·¤Æ»²¾È¤·¤Æ²¼¤µ¤¤¡£
+
+XF86Config¤òÀ¸À®¤¹¤ë``xf86config''¤ò»ÈÍѤ¹¤ë¤³¤È¤ò¶¯¤¯¤ª´«¤á¤·¤Þ¤¹¡£
+¡ÊÌõÃí¡§PC98¤Ç¤Ï``xf86config''¤ò»ÈÍѤ·¤Ê¤¤¤Ç¥µ¥ó¥×¥ë¤ÎXF86Config.98¤ò»²¾È¤·¤Æ
+²¼¤µ¤¤¡£¡Ë
+
+XFree86 2.xÍѤÎ<tt/Xconfig/¤¬¤¢¤ë¾ì¹ç¡¢reconfig¤ò»ÈÍѤ·¤Æ¤½¤Î°ìÉôʬ¤ò¿·¤·¤¤
+¥Õ¥©¡¼¥Þ¥Ã¥È¤ËÊÑ´¹¤Ç¤­¤Þ¤¹¡£
+
+<tscreen><verb>
+ # reconfig <Xconfig >XF86Config
+</verb></tscreen>
+
+¤½¤·¤Æ¡¢<em/XF86Config(4)/¤Îman page¤ä¥Æ¥ó¥×¥ì¡¼¥È¤È¤·¤Æ<tt/XF86Config.eg/
+¤ò»²¾È¤·¤Æ»Ä¤ê¤ÎÉôʬ¤ò´°À®¤µ¤»¤Þ¤¹¡£
+
+¥Ï¡¼¥É¥¦¥¨¥¢¤Î»½ý¤«¤éÊݸ¤ë¤¿¤á¡¢¸½ºß¤Ç¤Ï°ìÈ̥桼¥¶¤Î¥Û¡¼¥à¥Ç¥£¥ì
+¥¯¥È¥ê¤Î<tt/XF86Config/¥Õ¥¡¥¤¥ë¤òÆÉ¤Þ¤º¡¢<tt>/etc/XF86Config</tt>,
+<tt>/usr/X11R6/lib/X11/XF86Config.</tt><em>hostname</em>,
+<tt>/usr/X11R6/lib/X11/XF86Config</tt> ¤Ë¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£
+
+»ÈÍѥϡ¼¥É¥¦¥¨¥¢¤Î°Ê²¼¤Î¾ðÊó¤¬É¬ÍפǤ¹¡£
+<itemize>
+<item>¥Þ¥¦¥¹¤Î¥¿¥¤¥×¡¢¥Ü¡¼¥ì¡¼¥È¡¢»ÈÍѤ¹¤ë/dev¤Î¥¨¥ó¥È¥ê
+<item>¥Ó¥Ç¥ª¥«¡¼¥É¤Î»ÈÍÑ¥Á¥Ã¥×¥»¥Ã¥È(Îã:ET4000,S3,etc)
+<item>¥â¥Ë¥¿¤ÎƱ´ü¼þÇÈ¿ô
+</itemize>
+
+¥Þ¥¦¥¹¤¬¤É¤Î¥Ç¥Ð¥¤¥¹¤ËÀܳ¤µ¤ì¤Æ¤¤¤ë¤«ÃΤëºÇ¤â´Êñ¤ÊÊýË¡¤Ï¡¢``<tt/cat/''¤ä
+``<tt/kermit/''¤ò»ÈÍѤ·¤Æ¡¢¥Þ¥¦¥¹¤Î½ÐÎϤòÄ´¤Ù¤ë¤³¤È¤Ç¤¹¡£¥Þ¥¦¥¹¤òÀܳ¤·¡¢
+¥Þ¥¦¥¹¤òư¤«¤·¤¿¤ê¥¯¥ê¥Ã¥¯¤·¤¿¤È¤­¤Ë½ÐÎϤ¬¤¢¤ë¤«³Î¤«¤á¤Þ¤¹¡£
+
+<tscreen><verb>
+ % cat < /dev/tty00
+</verb></tscreen>
+
+Àµ¤·¤¤¥Þ¥¦¥¹¤Î¥Ç¥Ð¥¤¥¹¤¬¤ï¤«¤é¤Ê¤¤¾ì¹ç¤Ï¡¢``<tt/dmesg|grep sio/''¤È¤·¤Æ¡¢
+¥Ö¡¼¥È»þ¤Ëǧ¼±¤µ¤ì¤¿¥Ç¥Ð¥¤¥¹¤Î¥ê¥¹¥È¤ò¼èÆÀ¤·¤Þ¤¹¡£
+
+<tscreen><verb>
+ % dmesg|grep sio
+ sio0 at 0x3f8-0x3ff irq 4 on isa
+</verb></tscreen>
+
+¤½¤·¤Æ¡¢¤½¤Î¥Ç¥Ð¥¤¥¹¤ËŬ¹ç¤¹¤ë<tt>/dev</tt>¥¨¥ó¥È¥ê¤ò¤µ¤é¤Ë³Îǧ¤·¤Þ¤¹¡£
+¥¨¥ó¥È¥ê¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢<tt>/dev/MAKEDEV</tt>¥¹¥¯¥ê¥×¥È¤ò»È¤Ã¤Æºî¤ê¤Þ¤¹¡£
+
+<tscreen><verb>
+ % cd /dev
+ % sh MAKEDEV tty00
+</verb></tscreen>
+
+¥â¥Ë¥¿¾å¤Î²èÌ̤ÎÂ礭¤µ¤ä°ÌÃÖ¤ò´°Á´¤ËÄ´À°¤¹¤ë¤Ë¤Ï¡¢¥â¥Ë¥¿¤ÎÀâÌÀ½ñ¤«¤é¡¢
+Ʊ´ü¼þÇÈ¿ô¤Ë´Ø¤¹¤ë¾ðÊó¤òÆþ¼ê¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+
+<sect>X¤Î¼Â¹Ô
+<p>
+X¤ò¼Â¹Ô¤¹¤ë¤Ë¤Ï¡¢ºÇ¾®8Mb¤Î¥á¥â¥ê¤¬¤¢¤ë¤³¤È¤ò¿ä¾©¤·¤Þ¤¹¡£¥µ¡¼¥Ð¤È¥¦¥¤¥ó¥É¥¦¥Þ¥Í
+¡¼¥¸¥ã¡¢¥Ç¥£¥¹¥×¥ì¥¤¥Þ¥Í¡¼¥¸¥ã¡¢1¤Ä¤Îxterm¤Ç¡¢Ìó8Mb¤Î²¾ÁÛ¥á¥â¥ê¤ò»ÈÍѤ·¤Þ¤¹¡£
+
+¤«¤ê¤Ë¾ïÃ󤹤ëÉôʬ¤Î¥µ¥¤¥º¤Ï¾®¤µ¤¤¤È¤·¤Æ¤â¡¢8Mb ¤Î¥·¥¹¥Æ¥à¤Ç¤Ïgcc
+¤Î¤è¤¦¤Ë¿ôM¥Ð¥¤¥È¤ò´üÂÔ¤·¤Æ¤¤¤ë¤è¤¦¤Ê¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ë½½Ê¬¤Ê¥¹¥Ú¡¼¥¹¤Ï
+»Ä¤ê¤Þ¤»¤ó¡£
+
+R6¤Î¥µ¡¼¥Ð¤Ï4Mb¤Î¥á¥â¥ê¤Ç¤âưºî¤¹¤ë²ÄǽÀ­¤Ï¤¢¤ê¤Þ¤¹¤¬¡¢X²¼¤Ç¤Î¥³¥ó¥Ñ¥¤¥ë¤Ë¤Ï¡¢
+Äê¾ïŪ¤Ê¥Ú¡¼¥¸¥ó¥°¤Ë¤è¤ê5,10Çܤλþ´Ö¤¬¤«¤«¤ê¤Þ¤¹¡£
+
+¿·¤·¤¤¥æ¡¼¥¶¤¬X¥¦¥£¥ó¥É¥¦¤òµ¯Æ°¤¹¤ëºÇ¤â´Êñ¤ÊÊýË¡¤Ï¡¢
+``<tt>startx >&amp; startx.log</tt>''¤ÈÆþÎϤ¹¤ë¤³¤È¤Ç¤¹¡£¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤Ï
+¥ê¥À¥¤¥ì¥¯¥È¤·¤Ê¤¤¤È¡¢¥µ¡¼¥Ð¤¬¥¹¥¯¥ê¡¼¥ó¾å¤Ë¾å½ñ¤­¤·¡¢¸«¤¨¤Ê¤¯¤Ê¤Ã¤Æ¤·¤Þ¤¤
+¤Þ¤¹¡£
+
+X¥¦¥£¥ó¥É¥¦¤«¤éÈ´¤±¤ë¤Ë¤Ï¡¢¥³¥ó¥½¡¼¥ë¤È¤·¤ÆÆ°ºî¤·¤Æ¤¤¤ëxtermÃæ¤Ç``<tt/exit/''
+¤ÈÆþÎϤ·¤Þ¤¹¡£<em/xinit/,<em/startx/¤Îman page¤ò»²¾È¤·¡¢¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê
+¤Ë¡¢<tt/.xinitrc/,<tt/.xserverrc/,<tt/.twmrc/¤Î¥Õ¥¡¥¤¥ë¤òºîÀ®¤¹¤ë¤³¤È¤Ç¡¢
+X¤ò¥«¥¹¥¿¥Þ¥¤¥º¤Ç¤­¤Þ¤¹¡£
+
+<sect>X¥µ¡¼¥ÐÍÑ¥«¡¼¥Í¥ë¤ÎºÆ¹½ÃÛ
+<p>
+
+FreeBSD-2.0,2.0.5¤ÎGENERIC¥«¡¼¥Í¥ë¤Ï¡¢Á´¤¯½¤Àµ¤¹¤ë¤³¤È¤Ê¤·¤ËXFree86¤ò¥µ¥Ý¡¼¥È
+¤·¤Æ¤¤¤Þ¤¹¡£²¿¤éGENERIC¥«¡¼¥Í¥ë¤ÎÊѹ¹¤ä¡¢ÆÃÊ̤ʥ«¡¼¥Í¥ë¤ò¹½ÃÛ¤¹¤ëɬÍפϤ¢¤ê¤Þ
+¤»¤ó¡£
+°ìÈÌŪ¤Ê¡¢BSD¥«¡¼¥Í¥ë¤Î¹½Ãۤ˴ؤ¹¤ëÀâÌÀ¤Ï¡¢
+<url name="smm.02.config.ps.Z"
+url="ftp://gatekeeper.dec.com/pub/BSD/manuals/smm.02.config.ps.Z">
+¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ì¤Ï¡¢¥·¥¹¥Æ¥à´ÉÍý¥Þ¥Ë¥å¥¢¥ë¤Î¥«¡¼¥Í¥ë¹½Ãۤ˴ؤ¹¤ë¾Ï¤Ç¡¢¤½¤Î¤Þ
+¤Þ°õºþ¤Ç¤­¤ë¥Ý¥¹¥È¥¹¥¯¥ê¥×¥È½ÐÎϤǤ¹¡£
+
+¥«¡¼¥Í¥ë¥³¥ó¥Õ¥£¥°¥ì¡¼¥·¥ç¥ó¥Õ¥¡¥¤¥ë¤òºï¸º¤·¤¿¤¤¾ì¹ç¤Ç¤â¡¢
+(<tt>/usr/src/sys/i386/conf/GENERIC</tt>Ãæ¤Ë¤¢¤ë)°Ê²¼¤Î¤è¤¦¤Ê2¹Ô¤ò¾Ã¤·¤Æ¤Ï¤¤
+¤±¤Þ¤»¤ó¡£¤É¤Á¤é¤âX¥µ¥Ý¡¼¥È¤Î¤¿¤á¤ËɬÍפǤ¹¡£
+
+<tscreen><verb>
+ options XSERVER #Xserver
+ options UCONSOLE #X Console support
+</verb></tscreen>
+
+FreeBSD 2.0,2.0.5¤ÎGENERIC¥«¡¼¥Í¥ë¤Ç¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤Çsyscons¥É¥é¥¤¥Ð¤¬
+ÀßÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£¥«¡¼¥Í¥ë¤òºÆ¹½ÃÛ¤¹¤ë¾ì¹ç¡¢
+<tt>/usr/src/sys/i386/conf/GENERIC</tt>¤ÎÃæ¤Ë¤¢¤ë°Ê²¼¤Î¤è¤¦¤Ê¹Ô¤¬É¬Í×
+¤Ç¤¹¡£
+
+<tscreen><verb>
+ device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+</verb></tscreen>
+
+²¾ÁÛüËö¤Î¿ô¤Ï¡¢NCONS ¥ª¥×¥·¥ç¥ó¤Ç»ØÄê¤Ç¤­¤Þ¤¹¡£
+
+<tscreen><verb>
+ options "NCONS=4" #4 virtual consoles
+</verb></tscreen>
+
+¤³¤Î¹Ô¤¬¤Ê¤¤¾ì¹ç¤Ï¥Ç¥Õ¥©¥ë¥È¤Î12¤Ë¤Ê¤ê¤Þ¤¹¡£3¾Ï¤Î½ª¤ï¤ê¤Ëµ­½Ò¤·¤¿¤è¤¦¤Ëgetty
+¤Î¿ô¤è¤ê¿¤¯¤Î²¾ÁÛüËö¤¬É¬Íפǡ¢4¤¬¹çÍýŪ¤ÊºÇ¾®ÃͤǤ¹¡£
+
+¥µ¡¼¥Ð¤Ï¡¢pccons,syscons,pcvt¤Ê¤É¤¤¤¯¤Ä¤«¤Î¥³¥ó¥½¡¼¥ë¥É¥é¥¤¥Ð¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£
+syscons¤Ï¡¢FreeBSD 1.1.5¤È¤½¤ì°Ê¹ß¤Ç¥Ç¥Õ¥©¥ë¥È¤Ç¤¹¡£¤³¤ì¤é¤Ï¼Â¹Ô»þ¤Ë¸¡½Ð¤µ¤ì¤ë
+¤Î¤Ç¡¢ÆÃ¤Ë¥µ¡¼¥Ð¤ËÀßÄꤹ¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£
+
+pcvt¥³¥ó¥½¡¼¥ë¥É¥é¥¤¥Ð¤ÏFreeBSD 1.0.2°Ê¹ß¤Î<tt>/usr/port/util/pcvt</tt>¤Ë¥Ð¥ó
+¥É¥ë¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤Þ¤¿¡¢°Ê²¼¤«¤éFTP¤ÇÆþ¼ê¤Ç¤­¤Þ¤¹¡£
+
+<url name="FreeBSD.cdrom.com:/pub/FreeBSD/FreeBSD-1.1/ports/util/pcvt"
+url="ftp://FreeBSD.cdrom.com/pub/FreeBSD/FreeBSD-1.1/ports/util/pcvt">
+
+<url url="ftp://FreeBSD.cdrom.com/pub/FreeBSD/FreeBSD-1.1/ports/util/pcvt/README.FreeBSD" name="README.FreeBSD"> ¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡£
+
+¤³¤ì¤Ë¤Ï´°Á´¤Ê¥¤¥ó¥¹¥È¡¼¥ë¼ê½ç¤¬¼¨¤·¤Æ¤¢¤ê¤Þ¤¹¡£
+
+XFree86¥µ¡¼¥Ð¤Ï¡¢MIT-SHM extension¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£GENERIC¥«¡¼¥Í¥ë¤Ï¡¢
+¤³¤ì¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤¤Î¤Ç¡¢¤³¤ì¤é¤ò»ÈÍѤ·¤¿¤¤¾ì¹ç¤Ï¡¢SYSV¶¦Í­¥á¥â¥ê¥µ¥Ý¡¼¥È
+¤òÍ­¸ú¤Ë¤·¤Æ¹½ÃÛ¤·¤Þ¤¹¡£¤½¤ì¤Ë¤Ï¡¢¥«¡¼¥Í¥ë¥³¥ó¥Õ¥£¥°¥ì¡¼¥·¥ç¥ó¥Õ¥¡¥¤¥ë¤Ë
+°Ê²¼¤Î¹Ô¤ò²Ã¤¨¤Þ¤¹¡£
+
+<tscreen><verb>
+ options SYSVSHM # System V shared memory
+ options SYSVSEM # System V semaphores
+ options SYSVMSG # System V message queues
+</verb></tscreen>
+
+SoundBlaster 16¤òIRQ 2(9)¤Ç»ÈÍѤ¹¤ë¾ì¹ç¡¢sb16_dsp.c¤Ë¥Ñ¥Ã¥Á¤¬É¬ÍפǤ¹¡£
+¤½¤¦¤·¤Ê¤¤¤ÈSoundBlaster¤òÍ­¸ú¤Ë¤·¤¿¥«¡¼¥Í¥ë¤Ï¡¢IRQ9¤¬Â¸ºß¤·¤Ê¤¤¤È¥¨¥é¡¼¤ò
+½Ð¤·¡¢X¥µ¡¼¥Ð¤¬¥í¥Ã¥¯¥¢¥Ã¥×¤·¤Æ¤·¤Þ¤¤¤Þ¤¹¡£
+
+IO¥¢¥É¥ì¥¹¤¬½Å¤Ê¤ë¤Î¤Ç¡¢S3¥«¡¼¥É¤È¥·¥ê¥¢¥ë¥Ý¡¼¥È¤ÎCOM4¤ÎξÊý¤òñ°ì¥·¥¹¥Æ¥à
+¾å¤Ç»ÈÍѤ¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£
+
+<sect>XFree86¤ÎºÆ¹½ÃÛ
+<p>
+X¥µ¡¼¥Ð¥ê¥ó¥¯¥­¥Ã¥È¤Ï¡¢ºÇ¾®¸Â¤Î¥Ç¥£¥¹¥¯ÍÆÎ̤ÇX¥µ¡¼¥Ð¤Î¹½ÃÛ¤ò²Äǽ¤Ë¤·¤Þ¤¹¡£
+ñ¤ËŸ³«¤·¤Æ¡¢<tt/xf86sire.def/¤òŬÅö¤ËÊѹ¹¤·¡¢``<tt>./mkmf'</tt>',
+``<tt>make</tt>''¤È¤·¤Æ¥ê¥ó¥¯¤·¤Þ¤¹¡£¾Ü¤·¤¯¤Ï¡¢
+<url name=README.LinkKit url=LinkKit.html> ¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡£
+
+¥½¡¼¥¹¥Ä¥ê¡¼¤Ï¡¢¥³¥ó¥Ñ¥¤¥ëÁ°¤ËÌó114Mb¡¢``<tt/make World/''¸å¤Ï¤µ¤é¤Ë100Mb¤Î
+¥Ç¥£¥¹¥¯ÍÆÎ̤¬É¬ÍפǤ¹¡£¥³¥ó¥Ñ¥¤¥ëÁ°¤Ë¡¢<tt>xc/config/cf</tt>Æâ¤Î
+<tt>xf86site.def</tt>,<tt>site.def</tt>¤òÊÔ½¸¤·¡¢ÇÛÉÛʪ¤òÀßÄꤷ¤Þ¤¹¡£
+¥Ç¥Õ¥©¥ë¥È¤Ç¥³¥ó¥Õ¥£¥°¥Õ¥¡¥£¥ë¤Ï¶¦Í­¥é¥¤¥Ö¥é¥ê¤ò¹½ÃÛ¤¹¤ë¤è¤¦¤ËÀßÄꤵ¤ì¤Æ¤¤
+¤Þ¤¹¡£¶¦Í­¥é¥¤¥Ö¥é¥ê¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Ê¤¤FreeBSD¤Î¥Ð¡¼¥¸¥ç¥ó¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì
+¹ç¤Ï¡¢°Ê²¼¤Î¹Ô¤ò<tt>site.def</tt>¤ËÄɲä·¤Þ¤¹¡£
+
+<tscreen><verb>
+ #define BuildBsdSharedLibs NO
+</verb></tscreen>
+
+¤Þ¤¿¡¢»ÈÍѤ·¤Æ¤¤¤ë¥·¥¹¥Æ¥à¤¬SYSV¶¦Í­¥á¥â¥ê¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤Ê¤¤¾ì¹ç¡Ê¤¿¤È¤¨¤Ð¡¢
+<tt>&lt;sys/shm.h&gt;</tt>¥Ø¥Ã¥À¡¼¤¬¤Ê¤¤¾ì¹ç¡Ë¡¢°Ê²¼¤Î¹Ô¤ò<tt/site.def/¤Ë
+Äɲ䷤ơ¢MIT-SHM extension¤ò̵¸ú¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+<tscreen><verb>
+ #define HasShm NO
+</verb></tscreen>
+
+FreeBSD-1.1°Ê¹ß¤Ç¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¾ì¹ç¡¢<tt>xc/config/cf/FreeBSD.cf</tt>¤òÊÔ½¸
+¤·¤Æ¡¢OS¥Ð¡¼¥¸¥ç¥ó¤Î¥Ñ¥é¥á¡¼¥¿¤òÀµ¤·¤¯ÀßÄꤷ¤Þ¤¹¡£¤½¤·¤Æ¡¢°Ê²¼¤Î¤è¤¦¤ËÆþÎϤ·
+¤Þ¤¹¡£
+
+<tscreen><verb>
+ make World
+</verb></tscreen>
+
+µì¥Ð¡¼¥¸¥ç¥ó¤ÎFreeBSD(1.1¤è¤êÁ°)¤Ç»ÈÍѤ¹¤ë¾ì¹ç¡¢°Ê²¼¤Î¤è¤¦¤ËÆþÎϤ·¤Þ¤¹¡£
+
+<tscreen><verb>
+ make World BOOTSTRAPCFLAGS=-D__FreeBSD__
+</verb></tscreen>
+
+
+<sect>¾¤ÎX¥¯¥é¥¤¥¢¥ó¥È¤Î¹½ÃÛ
+<p>
+¿·¤·¤¤¥¯¥é¥¤¥¢¥ó¥È(X ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó)¤ò¹½ÃÛ¤¹¤ëºÇ¤â´Êñ¤ÊÊýË¡¤Ï¡¢
+<tt/Imakefile/¤¬¤½¤ÎÃæ¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¡¢<tt/xmkmf/¤ò»È¤¦¤³¤È¤Ç¤¹¡£
+``<tt/xmkmf -a/'' ¤ÈÆþÎϤ·¡¢Makefile¤òºîÀ®¤·¡¢``<tt/make/''¤ÈÆþÎϤ·¤Þ¤¹¡£
+¿·¤·¤¯man page¤òÄɲä·¤¿¤È¤­¤Ï¤«¤Ê¤é¤º¡¢
+``<tt>makewhatis /usr/X11R6/man</tt>''¤ò¼Â¹Ô¤·¤Æ<tt/whatis.db/¤ò¥¢¥Ã¥×
+¥Ç¡¼¥È¤·¤Þ¤¹¡£
+
+FreeBSD 1.0°ÊÁ°¤Î¥·¥¹¥Æ¥à¤Ç¤Ï¡¢¥³¥ó¥Ñ¥¤¥ëÃæ¡¢cc¤Î``Virtual memory exhausted''
+¤È¤¤¤¦¥á¥Ã¥»¡¼¥¸¤òÈò¤±¤ë¤¿¤á¤Ë¡¢¥Ç¡¼¥¿¤È¥¹¥¿¥Ã¥¯¥µ¥¤¥º¤ÎÀ©¸Â¤ò°ú¤­¾å¤²¤Þ¤¹¡£
+(csh¤Ç¤Ï``<tt/limit datasize 32M/'',``<tt/limit stacksize 16M/''¤ÈÆþÎϤ·¤Þ¤¹¡£)
+FreeBSD 2.0°Ê¹ß¤Ç¤Ï¡¢¥Ç¥Õ¥©¥ë¥È¤¬½½Ê¬Â礭¤¤¤Î¤Ç¡¢¤³¤ì¤é¤ÎɬÍפϤ¢¤ê¤Þ¤»¤ó¡£
+
+<bf/Note:/ XFree86 2.1¤ÈFreeBSD 1.1¤«¤é¡¢<bf/__386BSD__/¤Î¥·¥ó¥Ü¥ë¤Ï¥³¥ó¥Ñ¥¤
+¥é¤Ç¤âX¤Î¥³¥ó¥Õ¥£¥°¥Õ¥¡¥¤¥ë¤Ç¤âÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£¥¯¥é¥¤¥¢¥ó¥È¤òBSD¥·¥¹¥Æ¥à
+¤Ë°Ü¿¢¤¹¤ë¾ì¹ç¡¢´°Á´¤ËBSD»ÅÍͤΥ³¡¼¥É¤Ë¤Ê¤ë¤è¤¦¤Ë¥·¥ó¥Ü¥ë <bf/BSD/¤ò»ÈÍѤ·¤Æ
+²¼¤µ¤¤¡£¤³¤Î¥·¥ó¥Ü¥ë¤ÎÃͤǡ¢°Û¤Ê¤Ã¤¿BSD¥ê¥ê¡¼¥¹¤ò¼±Ê̤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤¿
+¤È¤¨¤Ð¡¢Net-2¤ä¤½¤ì°Ê¹ß¤Î¥ê¥ê¡¼¥¹¤Ë°Í¸¤¹¤ë¤Î¾ì¹ç¤Ë¤Ï°Ê²¼¤Î¤è¤¦¤Ë»ÈÍѤǤ­¤Þ¤¹¡£
+
+<tscreen>
+#if (BSD >= 199103)
+</tscreen>
+
+¤³¤Î¥·¥ó¥Ü¥ë<bf/BSD/¤¬Àµ¤·¤¯ÄêµÁ¤µ¤ì¤ë¤è¤¦¤Ë¡¢¤³¤ì¤¬É¬Íפʥ½¡¼¥¹¤ÎÃæ¤Ç
+<<tt>&lt;sys/param.h&gt;</tt>
+¤ò¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡£XFree86 3.1.1°Ê¹ß¡¢*BSD¥·¥¹¥Æ¥à¤Ç¤Ï¡¢¥·¥ó¥Ü¥ë
+<bf/CSRG_BASED/¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤³¤È¤ËÃí°Õ¤·¤Æ²¼¤µ¤¤¡£¤³¤ì¤Ï¡¢
+<tt>&lt;sys/param.h&gt;</tt> ¤Î¥¤¥ó¥¯¥ë¡¼¥É¤òÊݸ¤ë¤¿¤á¤Ë»È¤ï¤ì¤Þ¤¹¡£
+
+¼ÂºÝ¤Ë¤ÏÆÃÄê¤Îi386 BSDÇÉÀ¸OS¤Ë°Í¸¤·¤¿¥³¡¼¥É¤Ç¤Ï¡¢
+
+FreeBSDÍѤË<bf/__FreeBSD__/¡¢ NetBSDÍѤË<bf/__NetBSD__/¡¢
+386BSDÍѤË<bf/__386BSD__/¡¢BSD/386ÍѤË<bf/__bsdi__/
+¤¬»È¤ï¤ì¤Æ¤¤¤Þ¤¹¡£
+
+<sect>¼Õ¼­
+<p>
+°Ê²¼¤ÎÊý¡¹¤Ë´¶¼Õ¤¤¤¿¤·¤Þ¤¹¡£
+
+ <itemize>
+<item> <bf/Pace Willison/ (ºÇ½é¤Ë*BSD¤ØÂбþ)
+<item> <bf/Amancio Hasty/ (386BSD¥«¡¼¥Í¥ë¤ÈS3¥Á¥Ã¥×¥»¥Ã¥È¤Ø¤ÎÂбþ)
+<item> <bf/David Greenman, Nate Williams, Jordan Hubbard/
+ (FreeBSD¥«¡¼¥Í¥ë¤Ø¤ÎÂбþ)
+<item> <bf/Rod Grimes/, <bf/Jordan Hubbard/,<bf/Jack Velte/
+ (Walnut Creek Cdrom¤Îµ¡ºà¤ÎÍøÍÑ)
+<item> <bf/Orest Zborowski/, <bf/Simon Cooper/ ,<bf/Dirk Hohndel/
+ (Linux¤ÎÇÛÉÛʪ¤«¤é¥¢¥¤¥Ç¥¢¤ÎÄó¶¡)
+</itemize>
+
+<p>¤Þ¤¿¡¢ÆüËܸìÌõ¤Ë¤¢¤¿¤ê¥¢¥É¥Ð¥¤¥¹¤ò¤¤¤¿¤À¤¤¤¿FreeBSD PC98°Ü¿¢¥Á¡¼¥à
+¤ÎÊý¡¹¤Ë´¶¼Õ¤¤¤¿¤·¤Þ¤¹¡£ÆüËܸìÌõ¤Ë´Ø¤¹¤ë¥³¥á¥ó¥È¤Ï
+<em/&lt;tsuka@kawalab.dnj.ynu.ac.jp&gt;/¤Þ¤Ç¤ª´ê¤¤¤·¤Þ¤¹¡£
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/FreeBSD.sgml,v 3.1 1997/01/26 04:34:17 dawes Exp $
+</verb>
+</article>
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/INSTALL.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/INSTALL.sgml
new file mode 100644
index 000000000..4d0768ab2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/INSTALL.sgml
@@ -0,0 +1,344 @@
+<!doctype linuxdoc system>
+
+<article>
+<title>XFree86 3.2 ¥¤¥ó¥¹¥È¡¼¥ë¥¬¥¤¥É
+<author>David Dawes
+<Date>1996 ǯ 10 ·î 24 Æü
+<trans> ²¬ËÜ¡¡°ì¹¬ Kazuyuki Okamoto &lt;ikko-@pacific.rim.or.jp&gt;
+<abstract>
+ ¤³¤Îʸ½ñ¤Ç¤Ï<bf>¥½¡¼¥¹</bf>ÇÛÉÛʪ¤«¤é¤É¤Î¤è¤¦¤Ë XFree86 ¤ò¹½ÃÛ¤¹¤ë¤«¤òÀâÌÀ¤·¤Æ
+ ¤¤¤Þ¤¹¡£ÇÛÉÛʪ¤ÎÁ´¤Æ¤Î¥½¡¼¥¹¤«¤é¹½ÃÛ¤¹¤ë¾ì¹ç¤ÈƱÍͤˡ¢X ¥µ¡¼¥Ð¡¼
+ ¤À¤±¤ò¹½ÃÛ¤¹¤ë¤¿¤á¤ÎÀÚ¤êµÍ¤á¤¿¥½¡¼¥¹¤«¤é¹½ÃÛ¤¹¤ë
+ ¾ì¹ç¤âÀâÌÀ¤·¤Æ¤¤¤Þ¤¹¡£³Æ¡¹¤Î OS ¤Ë°Í¸¤·¤¿ README ¥Õ¥¡¥¤¥ë¤È´ØÏ¢¤µ¤»¤Æ
+ »ÈÍѤ¹¤ë¤è¤¦¤Ë¹½ÁÛ¤·¤Æ¤¤¤Þ¤¹¡£¤³¤Îʸ½ñ¤Ç¤Ï ƳÆþÊýË¡¤ä¥Ð¥¤¥Ê¥êÇÛÉÛʪ¤Î
+ ¹¹¿·ÊýË¡¤Ë¤Ä¤¤¤Æ¤ÏÀâÌÀ¤·¤Æ¤¤¤Þ¤»¤ó¡£¤³¤ì¤é¤Î¾ðÊó¤Ï
+ <htmlurl name=RELNOTES url=RELNOTE.html>, ³Æ¡¹¤Î OS ¤Ë°Í¸¤·¤¿
+ README ¥Õ¥¡¥¤¥ëËô¤Ï¿§¡¹¤Ê¥Ð¥¤¥Ê¥êÇÛÉÛʪ¤ËźÉÕ¤·¤Æ¤¢¤ëÊÌʸ½ñ¤Ëµ­ºÜ¤·¤Æ
+ ¤¤¤Þ¤¹¡£
+</abstract>
+
+<toc>
+
+
+<sect>¥½¡¼¥¹ÇÛÉÛʪ¤«¤é¤Î XFree86 ¤ÎºîÀ®
+
+<p>
+<quote>
+<bf/Ãí°Õ:/ XFree86 ¤òºîÀ®¤·¤è¤¦¤È¤¹¤ëÁ°¤ËÆÃÄê¤Î OS ¸ÇÍ­¤Î README ¥Õ¥¡
+ ¥¤¥ë¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡£¤³¤ì¤é¤Î¥Õ¥¡¥¤¥ë¤Ë¤Ï¸Ä¡¹¤Î OS ¤Î´Ä¶­¤Î²¼¤Ç¤¦¤Þ¤¯
+ XFree86 ¤òºîÀ®¤¹¤ë¤Î¤ËɬÍפÊÄɲþðÊó¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£
+</quote>
+
+
+ GCC-2 ¤ò»È¤Ã¤Æ XFree86 ¤òºîÀ®¤¹¤ë»ö¤ò¶¯¤¯¤ª´«¤á¤·¤Þ¤¹¡£¥Ð¡¼¥¸¥ç¥ó
+ 2.6.0 Ëô¤Ï 2.4.x Åù 2.4.5 °ÊÁ°¤Îʪ¤Ï¥Ð¥°¤Î¤¿¤áºîÀ®¤ä¼Â¹Ô¤¬¼ºÇÔ¤¹¤ë¤Î¤Ç
+ »ÈÍѤ·¤Ê¤¤¤Ç²¼¤µ¤¤¡£
+ GCC ¤Î -m486 ¥ª¥×¥·¥ç¥ó¤ò
+ »È¤¨¤Ð¡¢486 ¤ÇÌó £µ% À­Ç½¤ò¸þ¾å¤µ¤»¤ë¤³¤È¤¬¤Ç¤­¤ë¤Ç¤·¤ç¤¦¡£¤è¤êÂ礭¤Ê
+ ¥Ð¥¤¥Ê¥ê¤ÏÊ̤Ȥ·¤Æ¡¢386 ¤Ç¤âÀ­Ç½¤Ï°­¤¯¤Ï¤Ê¤ê¤Þ¤»¤ó¡£¡Ê gcc-2 ¤Ï
+ prep.ai.mit.edu ¤È¾¤Î GNU ¥½¡¼¥¹¤òÃÖ¤¤¤Æ¤¤¤ë¥µ¥¤¥È¤Ë¤¢¤ê¤Þ¤¹¡£¡Ë
+
+<enum>
+<item>¼¡¤Îʪ¤¬É¬ÍפǤ¹:
+
+ <itemize>
+ <item> fix 01 ¤Î¥Ñ¥Ã¥Á¤òÅö¤Æ¤¿ X ¥³¥ó¥½¡¼¥·¥¢¥à X11R6.1 ¤ÎÇÛÉÕʪ¡£
+
+ <item> <tt/R6.1pl1-3.2.diff.gz/, <tt/cfont32.tgz/
+
+ <item> ÄɲäȤ·¤Æ X ¥³¥ó¥½¡¼¥·¥¢¥à¤Î X11R6.1 ´ó£ ÇÛÉÛʪ¡£
+
+ <item> <tt/contrib-3.2.diff.gz/ (¤¤¤¯¤Ä¤«¤Î X ¥³¥ó¥½¡¼¥·¥¢
+ ¥à¤Î ``´ó£'' ÇÛÉÕʪ¤Ø¤ÎÄɲåѥåÁ)
+
+ <item> XFree86 X ¥µ¡¼¥Ð¡¼¤À¤±¤ò¹½ÃÛ¤·¤¿¤¤¾ì¹ç¤Ï¡¢X32servonly.tgz ¤À
+ ¤±¤¬É¬Íפǡ¢¤³¤ì¤Ï ``ServersOnly'' ¤È¤¤¤¦¥½¡¼¥¹ÇÛÉÛʪ¤òÀÚ¤êµÍ
+ ¤á¤¿¤â¤Î¤ÈƱ¤¸¤â¤Î¤Ç¤¹¡£
+
+ <item> Á´¤Æ¤Î XFree86 ¥½¡¼¥¹¤«¤éºîÀ®¤¹¤ë¤ÈÌó130MB ¤Î¶õ¤­¥Ç¥£¥¹¥¯ÍÆÎÌ
+ ¤¬É¬ÍפǤ¹¡£Á´ÉôºîÀ®¤¹¤ë¤Ë¤Ï¡Ê OS ¤Î¶¦Íѥ饤¥Ö¥é¥ê¤ò»ÈÍѤ·¤Ê
+ ¤¤»þ¡Ë130MB ÄɲÃÍÆÎ̤¬É¬ÍפǤ¹¡£Á´¤Æ¤ÎÇÛÉÕʪ¤òƳÆþ¤¹¤ë¤Ë¤Ï
+ ¡Ê¶¦Íѥ饤¥Ö¥é¥ê¤ò»ÈÍѤ·¤¿¾ì¹ç¡ËÌó 55 ¤«¤é 65MB¤Î¶õ¤­¥Ç¥£¥¹¥¯
+ ÍÆÎ̤¬É¬ÍפǤ¹¡£ºîÀ®ºî¶È¤Ë½ÅÍפǤʤ¤Éôʬ¤òºï½ü¤¹¤ë¤³¤È¤Ç¡¢¤½
+ ¤ì¤¾¤ì¼¡¤Î¥Ç¥£¥¹¥¯ÍÆÎ̤òºï¸º½ÐÍè¤Þ¤¹¡£:
+
+<tscreen><verb>
+ xc/test 16MB
+ xc/doc/hardcopy 11MB
+ xc/doc/specs 27MB
+</verb></tscreen>
+
+ ¥Õ¥©¥ó¥È¤òºîÀ®¤¹¤ëɬÍפ¬¤Ê¤¤»þ¤Ï¡¢<tt>xc/fonts</tt> ¤òºï½ü¤¹¤ë
+ ¤³¤È¤Ç 30MB ÀáÌó¤Ç¤­¤Þ¤¹¡£PEX Ëô¤Ï XIE ¤òºîÀ®¤·¤¿¤¯¤Ê¤¤»þ¤Ï¡¢
+ ¤½¤ì¤é¤òºï½ü¤¹¤ë¤³¤È¤Ç¡¢¤½¤ì¤¾¤ì¼¡¤Î¥Ç¥£¥¹¥¯ÍÆÎ̤òºï¸º½ÐÍè¤Þ¤¹¡£:
+<tscreen><verb>
+ xc/programs/Xserver/XIE 3MB
+ xc/programs/Xserver/PEX5 2MB
+</verb></tscreen>
+
+ <tt>xc/programs/Xserver/hw/</tt>¤Î²¼¤Î XFree86 °Ê³°¤Î¥Ç¥£¥ì¥¯¥È¥ê¤òºï½ü
+ ¤¹¤ì¤Ð¡¢¤â¤¦¿ô MB ³«Êü½ÐÍè¤Þ¤¹¡£
+
+ <item> XFree86 ¥µ¡¼¥Ð¡¼¤ÎºîÀ®¤Ë¸Â¤Ã¤¿¾ì¹ç¡¢ÀÚ¤êµÍ¤á¤¿¥½¡¼¥¹¥Ä¥ê¡¼¤ò
+ ¹½À®¤¹¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡£¤³¤Î¥½¡¼¥¹¥Ä¥ê¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï 50 ¤«¤é 55MB
+ ¤Î¥Ç¥£¥¹¥¯¤Ë¶õ¤­¤¬É¬ÍפǤ¹¡£
+
+ <item> <tt/contrib-3.2.diff.gz/ ¤Î¥Ñ¥Ã¥Á¥Õ¥¡¥¤¥ë¤Ï
+ X ¥³¥ó¥½¡¼¥·¥¢¥à
+ ¤Î R6.1 ´ó£ÇÛÉÕʪ¤Î¤´¤¯°ìÉô¤Ø¤Î¥Ñ¥Ã¥Á¤òÄ󶡤·¤Þ¤¹¡£
+ ¤³¤Î¥Ñ¥Ã¥Á¥Õ¥¡¥¤¥ë¤òŬÍѤ¹¤ë¤È¡¢¼¡¤Î X ¥³¥ó¥½¡¼¥·
+ ¥¢¥à¤Î´ó£ÈǤκǿ·ÈǤΥե¡¥¤
+ ¥ë/¥Ç¥£¥ì¥¯¥È¥ê¤¬É¬Íפˤʤê¤Þ¤¹¡£:
+
+<tscreen><verb>
+ contrib/Imakefile
+ contrib/programs/Imakefile
+ contrib/programs/ico
+ contrib/programs/listres
+ contrib/programs/showfont
+ contrib/programs/viewres
+ contrib/programs/xbiff
+ contrib/programs/xcalc
+ contrib/programs/xditview
+ contrib/programs/xedit
+ contrib/programs/xev
+ contrib/programs/xeyes
+ contrib/programs/xfontsel
+ contrib/programs/xgc
+ contrib/programs/xload
+ contrib/programs/xman
+ contrib/programs/xmessage
+</verb></tscreen>
+ </itemize>
+
+<item> ɸ½àŪ¤Ê X ¥³¥ó¥½¡¼¥·¥¢¥à R6.1 ¤Î¥Ñ¥Ã¥Á¥ì¥Ù¥ë 1 ¤Î¥½¡¼¥¹ÇÛÉÕʪ¤«¤é»Ï¤á
+¤ë¾ì¹ç¤Ï¡¢ <tt/xc/ ¥Ç¥£¥ì¥¯¥È¥ê¤Ë°Üư¤·¤Æ¼¡¤Î¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤Æ²¼¤µ¤¤¡£:
+
+<tscreen><verb>
+ gzip -d < R6.1pl1-3.2.diff.gz | patch -p -E
+ gzip -d < cfont32.tgz | tar vxf -
+</verb></tscreen>
+
+ Êѹ¹¤·¤Æ¤¤¤Ê¤¤¥½¡¼¥¹¤«¤é¥¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¾ì¹ç¤Ï¡¢ÌäÂê¤Ï²¿¤â¤Ê¤¤¤Ç¤·¤ç
+ ¤¦¡£¥Ñ¥Ã¥Á¤Î¸å¤Ë¥Ñ¥Ã¥Á¤¬µÑ²¼¤µ¤ì¤¿·ë²Ì¡Ê rejection ¡Ë¤È¥Ñ¥Ã¥Á¤ÎʬÀÏ·ë
+ ²Ì¡Êresolve ¡Ë¤òÄ´¤Ù¤Þ¤·¤ç¤¦¡£¤¤¤¯¤Ä¤«¤Î¥Õ¥¡¥¤¥ë (Î㤨¤Ð
+ <tt/xf86site.def/ ¤ä <tt/site.def/)
+ ¤òÊѹ¹¤·¤¿¾ì¹ç¤Ï¡¢¤½¤ì¤é¤Î¥Õ¥¡¥¤¥ë̾¤òÊѤ¨¤Æ¡¢¥Ñ¥Ã¥Á¤¹¤ëÁ°¤Î
+ Ä󶡤·¤¿¾õÂÖ¤ËÌᤷ¤Þ¤·¤ç¤¦¡£ ¸µ¤Î¥Ð¥Ã¥¯¥¢¥Ã¥×¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢
+ ¸Ä¡¹¤Î¥Õ¥¡¥¤¥ë¤Ï <htmlurl url="ftp://ftp.x.org/pub/R6.1/xc"
+ name="ftp://ftp.x.org/pub/R6.1/xc"> ¤«¤éÍÆ°×¤Ë¼ê¤ËÆþ¤ì¤é¤ì¤ë¤Ç¤·¤ç¤¦¡£
+
+ ¤â¤·°ÊÁ°¤Ë»ÈÍѤ·¤Æ¤¤¤¿¥½¡¼¥¹¤Ë¥Ñ¥Ã¥Á¤òÅö¤Æ¤ë¾ì¹ç¤Ï¡¢º¹Ê¬¥Õ¥¡¥¤¥ë¤òŬ
+ ÍѤ¹¤ëÁ°¤Ë <tt/xc/ ¥Ç¥£¥ì¥¯¥È¥ê¤«¤é ``<tt/make clean/'' ¤ò˺¤ì¤º¤Ë¼Â
+ ¹Ô¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+ ´ó£Éôʬ¤Ë¥Ñ¥Ã¥Á¤¹¤ë¤Ê¤é¤Ð¡¢ <tt/contrib/ ¥Ç¥£¥ì¥¯¥È¥ê¤Ø°Üư¤·¤Æ¡¢
+ ¼¡¤ÎÁàºî¤ò¼Â¹Ô¤·¤Þ¤·¤ç¤¦:
+
+<tscreen><verb>
+ gzip -d < contrib-3.2.diff.gz | patch -p -E
+</verb></tscreen>
+<!--
+<item> XFree86 3.1.1 ¥½¡¼¥¹ÇÛÉÕʪ¤«¤é»Ï¤á¤ë¤Ê¤é¤Ð¡¢ <tt/xc/ ¥Ç¥£¥ì¥¯¥È¥ê
+¤Ø°Üư¤·¤Æ¡¢¼¡¤ÎÁàºî¤ò¼Â¹Ô¤·¤Þ¤·¤ç¤¦:
+
+<tscreen><verb>
+ gzip -d < 3.1.1-3.1.2.diff.gz | patch -p -E
+ gzip -d < cfont312.tgz | tar vxf -
+</verb></tscreen>
+
+ Êѹ¹¤·¤Æ¤¤¤Ê¤¤¥½¡¼¥¹¤«¤é¥¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¾ì¹ç¤Ï¡¢ÌäÂê¤Ï²¿¤â¤Ê¤¤¤Ç¤·¤ç
+ ¤¦¡£¥Ñ¥Ã¥Á¤Î¸å¤Ë¥Ñ¥Ã¥Á¤¬µÑ²¼¤µ¤ì¤¿·ë²Ì¡Ê rejection ¡Ë¤È¥Ñ¥Ã¥Á¤ÎʬÀÏ·ë
+ ²Ì¡Ê resolve ¡Ë¤òÄ´¤Ù¤Þ¤·¤ç¤¦¡£¤¤¤¯¤Ä¤«¤Î¥Õ¥¡¥¤¥ë¡ÊÎ㤨¤Ð
+ <tt/xf86site.def/, <tt/site.def/)
+ ¤òÊѹ¹¤·¤¿¾ì¹ç¤Ï¡¢¤½¤ì¤é¤Î¥Õ¥¡¥¤¥ë̾¤òÊѤ¨¤Æ¡¢¥Ñ¥Ã¥Á¤¹¤ëÁ°¤Î
+ Ä󶡤·¤¿¾õÂÖ¤ËÌᤷ¤Þ¤·¤ç¤¦¡£¸µ¤Î¥Ð¥Ã¥¯¥¢¥Ã¥×¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¡¢
+ ¥Ð¡¼¥¸¥ç¥ó 3.1.2 ¤Î¸Ä¡¹¤Î¥Õ¥¡¥¤¥ë¤Ï
+ <url url="ftp://ftp.xfree86.org/pub/XFree86/3.1.2/untarred"
+ name="ftp.xfree86.org:/pub/XFree86/3.1.2/untarred">¤«¤éÍÆ°×¤Ë¼ê¤ËÆþ¤ì
+ ¤é¤ì¤ë¤Ç¤·¤ç¤¦¡£
+
+ ¤â¤·°ÊÁ°¤Ë»ÈÍѤ·¤Æ¤¤¤¿¥½¡¼¥¹¤Ë¥Ñ¥Ã¥Á¤òÅö¤Æ¤ë¾ì¹ç¤Ï¡¢º¹Ê¬¥Õ¥¡¥¤¥ë¤òŬ
+ ÍѤ¹¤ëÁ°¤Ë <tt/xc/ ¥Ç¥£¥ì¥¯¥È¥ê¤«¤é ``<tt/make clean/'' ¤ò˺¤ì¤º¤Ë¼Â
+ ¹Ô¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+ ´ó£Éôʬ¤Ë¥Ñ¥Ã¥Á¤¹¤ë¤Ê¤é¤Ð¡¢<tt/contrib/ ¥Ç¥£¥ì¥¯¥È¥ê¤Ø°Üư¤·¤Æ¡¢
+ ¼¡¤ÎÁàºî¤ò¼Â¹Ô¤·¤Þ¤·¤ç¤¦:
+
+<tscreen><verb>
+ gzip -d < contrib-3.1.1-3.1.2.diff.gz | patch -p -E
+</verb></tscreen>
+-->
+<item> <tt>config/cf/xf86site.def</tt>¤òÄÌÆÉ¤·¤Æ¤¯¤À¤µ¤¤¡£ ¼«Ê¬¤Î¹½À®¤Ë
+ ¹ç¤ï¤»¤ÆÍÍ¡¹¤Ê¥Ñ¥é¥á¡¼¥¿¤òÀßÄꤷ¤Þ¤·¤ç¤¦¡£ ½é¤á¤Æ¤ÎºîÀ®¤Î¾ì¹ç¤Ï¡¢
+ <bf/BuildFonts/¤ò
+ <bf/YES/ ¤ËÀßÄꤷ¤Þ¤·¤ç¤¦¡£
+
+ ¥µ¡¼¥Ð¡¼¤À¤±¤òºîÀ®¤¹¤ë¤¿¤á¤ËÀÚ¤êµÍ¤á¤¿¥½¡¼¥¹¥Ä¥ê¡¼¤ò»È¤¦¤È¤­¤Ï
+ <bf/BuildServersOnly/ ¤ò <bf/YES/ ¤ËÀßÄꤷ¡¢<bf/XnestServer/ ¤ò
+ <bf/NO/ ¤ËÀßÄꤷ¤Þ¤·¤ç¤¦¡£
+
+ ºîÀ®¤·¤¿¤¤¥µ¡¼¥Ð¡¼¤ò»ØÄꤹ¤ë¤Ë¤Ï¡¢¼¡¤ÎÄêµÁ¤òÀßÄꤷ¤Þ¤·¤ç¤¦:
+
+<tscreen><verb>
+ Colour SVGA server (XF86_SVGA): XF86SVGAServer
+ 16 colour (S)VGA server (XF86_VGA16): XF86VGA16Server
+ ET4000/W32 accelerated server (XF86_W32): XF86W32Server
+ Monochrome server (XF86_Mono): XF86MonoServer
+ S3 accelerated server (XF86_S3): XF86S3Server
+ S3 ViRGE accelerated server (XF86_S3V): XF86S3VServer
+ 8514/A accelerated server (XF86_8514): XF86I8514Server
+ Mach8 accelerated server (XF86_Mach8): XF86Mach8Server
+ Mach32 accelerated server (XF86_Mach32): XF86Mach32Server
+ Mach64 accelerated server (XF86_Mach64): XF86Mach64Server
+ P9000 accelerated server (XF86_P9000): XF86P9000Server
+ AGX accelerated server (XF86_AGX): XF86AGXServer
+ I128 server (XF86_I128): XF86I128Server
+</verb></tscreen>
+
+ ÁÐÆ¬¤Î Mono+VGA2 ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï, <bf/XF86MonoDualServer/ ¤ò
+ <bf/YES/¤Ë¤·¤Þ¤·¤ç¤¦¡£
+
+ ÁÐÆ¬¤Î Mono+VGA16 ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï,
+ <bf/XF86VGA16DualServer/ ¤ò <bf/YES/¤Ë¤·¤Þ¤·¤ç¤¦¡£
+
+ <tt/X/ ¤Ë¥ê¥ó¥¯¤òÄ¥¤ê¤¿¤¤¥µ¡¼¥Ð¡¼¤ò <bf/ServerToInstall/ ¤ËÀßÄꤷ¤Æ²¼
+ ¤µ¤¤¡£¤³¤ì¤¬»ØÄꤵ¤ì¤Ê¤¤¤È¾åµ­¡¢¥µ¡¼¥Ð¡¼¤Î°ìÍ÷¤ÎºÇ½é¤Îʪ¤¬½é´üÃͤË
+ ¤Ê¤Ã¤ÆºîÀ®¤µ¤ì¤Þ¤¹¡£
+
+ ¥µ¡¼¥Ð¡¼¤Ë´Þ¤á¤¿¤¤¥É¥é¥¤¥Ð¡¼¤â <tt/xf86site.def/¤ÎÃæ¤ÇÁªÂò¤·
+ ¤Þ¤¹¡£SVGA ¥µ¡¼¥Ð¡¼Âбþ¤Î¥É¥é¥¤¥Ð¡¼¤Ï <bf/XF86SvgaDrivers/ ¥Ñ¥é¥á¥¿¤Ç
+ »ØÄꤷ¤Þ¤¹¡£¤³¤ì¤Ï¥É¥é¥¤¥Ð¥Ç¥£¥ì¥¯¥È¥ê¤Î°ìÍ÷ɽ·Á¼°¤Ç¡¢¾®Ê¸»ú¤Ç½ñ¤­¤Þ
+ ¤¹¡£¥Ñ¥é¥á¥¿¤Î»ØÄê½ç½ø¤Çµ¯Æ°»þ¤Ëõºº¤ò¹Ô¤¤¤Þ¤¹¡£Á´¤Æ¤ÎÄ󶡤µ¤ì¤Æ¤ë¥É
+ ¥é¥¤¥Ð¤Ï½é´üÃͤÇÀßÄꤵ¤ì¤Þ¤¹¡£¤¢¤È¤Ë³¤¯¡¢¥Ñ¥é¥á¥¿¤¬»ØÄꤹ¤ë¥É¥é¥¤¥Ð
+ ¤âƱÍͤǤ¹:
+<tscreen><verb>
+ XF86Vga16Drivers XF86_VGA16
+ XF86Vga2Drivers XF86_Mono (vga2 drivers)
+ XF86MonoDrivers XF86_Mono, XF86_VGA16 (other mono drivers)
+</verb></tscreen>
+
+ SVGA, VGA16 ¤È VGA2 ²èÌ̤Ϥ½¤ì¤¾¤ì¡¢ÈÆÍÑ(``generic'')¥É¥é¥¤¥Ð¡¼¤Ë´Þ¤Þ
+ ¤ì¡¢¤³¤ì¤é¤Ï¤É¤ó¤Ê VGA ¥«¡¼¥É¤Ç¤âõºº¤ËÀ®¸ù¤¹¤ë¤Î¤Ç¡¢¾ï¤Ë°ìÍ÷¤ÎºÇ¸å¤Ë
+ ÃÖ¤¯¤è¤¦¤Ë¤·¤Þ¤¹¡£
+
+<item> ¡Ê¸½ºß LinuxDoc/SGML ¤Î²¼¤Ë¤¢¤ë½ñ¼°¤Ë¡ËXFree86 ¤Î¥É¥­¥å¥á¥ó¥È¤òÀ°
+ ·Á¤·¤¿¤¤¾ì¹ç¡¢
+ <htmlurl name="ftp://ftp.xfree86.org/pub/XFree86/3.2/Linuxdoc"
+ url="ftp://ftp.xfree86.org/pub/XFree86/3.2/Linuxdoc"> ¤Ë¤¢¤ë
+ linuxdoc-sgml-1.2.tar.gz ¤È¥Ñ¥Ã¥Á ¤ò¼ê¤ËÆþ¤ì¤ÆÁȤ߹þ¤ó¤Ç²¼¤µ¤¤¡£
+ <tt/xf86site.def/ ¥Õ¥¡¥¤¥ë¤ò³Îǧ¤·¤Æ ŬÀÚ¤Ë Linuxdoc ¤Î¥ª¥×¥·¥ç¥ó¤òÊÔ
+ ½¸¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+<item> ÇÛÉÕʪ¤«¤éÀ¸À®¤¹¤ëÁ°¤Ë¡¢
+ <tt>xc/programs/Xserver/hw/xfree86/doc</tt> ¤Ë¤¢¤ë´Ä¶­¤Ë´ØÏ¢¤·¤¿ OS
+ ¸ÇÍ­¤Î <tt/README/ ¥Õ¥¡¥¤¥ë¤òÎɤ¯ÆÉ¤à¤³¤È¤¬ÂçÀڤǤ¹¡£
+ ¤³¤ì¤Þ¤Ç¤â¡¢¤³¤ì¤é¤Î OS ¸ÇÍ­¤Î¾ÜºÙ¥Þ¥Ë¥å¥¢¥ë¤Î¼êÆþ¤ì¤ò¤·¤Æ¤­¤Þ¤·¤¿¡£
+ <tt/xc/ ¥Ç¥£¥ì¥¯¥È¥ê¤Ø°Üư¤·¤Æ¡¢¤½¤·¤Æ OS ¸ÇÍ­¤Î README ¥Õ¥¡¥¤¥ë¤Ëµ­
+ ½Ò¤·¤Æ¤¢¤ë¤è¤¦¤ËÀßÄꤷ¤¿ <bf/BOOTSTRAPCFLAGS/ ¤òÉÕ¤±¤Æ
+ ``<tt/make World/'' ¤ò¼Â¹Ô¤·¤Æ²¼¤µ¤¤¡£¹½ÃÛ¤¹¤ë´Ö¤ËȯÀ¸¤¹¤ë¤«¤â¤·¤ì¤Ê
+ ¤¤ÌäÂê¤òÄɤ¤¤«¤±¤ë¤³¤È¤¬½ÐÍè¤ë¤è¤¦¤Ë¡¢¤³¤Î½èÍý¤Îɸ½à½ÐÎϤÈɸ½à¥¨¥é¡¼
+ ½ÐÎϤò¥ê¥À¥¤¥ì¥¯¥È¤·¤Æ <tt/World.Log/ ¤Ë¼è¤Ã¤Æ¤ª¤¯¤³¤È¤ò¤ª´«¤á¤·¤Þ
+ ¤¹¡£ÀÚ¤êµÍ¤á¤¿¥½¡¼¥¹ÇÛÉÛʪ¤Î¤É¤ì¤«¤ò»È¤¦¾ì¹ç¤Ë¤Ï¡¢Ä̾ïºÇ¾å°Ì¤Î
+ Makefile ¤ò»ÈÍѤ·¤Ê¤¤¤Ç ``<tt/make -f Makefile.ini World/'' ¤ò¼Â¹Ô¤·
+ ¤Æ¤¯¤À¤µ¤¤¡£
+
+<item>Á´¤Æ½çÄ´¤Ë¹Ô¤ï¤ì¤¿¾ì¹ç¤Ë¡¢¹½À®¤Ë°ø¤ê¤Þ¤¹¤¬¥·¥¹¥Æ¥àÀ¸À®¤Ï 2 »þ´Ö¤«
+ ¤é 12 »þ´Ö°Ì³Ý¤«¤ë¤Ç¤·¤ç¤¦¡£¥Ð¥¤¥Ê¥ê¤ÎÁȤ߹þ¤ß¤Ë²¿¤«ÌäÂ̵꤬¤«¤Ã¤¿¤«
+ <tt/World.Log/ ¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£ Á´¥½¡¼¥¹ÇÛÉÛʪ¤ò»ÈÍѤ¹¤ë¤È¤­¤Ï¡¢
+ <tt/xc/ ¥Ç¥£¥ì¥¯¥È¥ê¤«¤éÁȤ߹þ¤ß¤ò¹Ô¤¤¤Þ¤¹¡£ ServersOnly ÇÛÉÛʪ¤ò»È
+ ÍѤ¹¤ë¤È¤­¤Ï¡¢ <tt>xc/programs/Xserver</tt> ¥Ç¥£¥ì¥¯¥È¥ê¤«¤éÁȤ߹þ¤ß
+ ¤ò¹Ô¤¤¤Þ¤¹¡£ ÁȤ߹þ¤à¤Ë¤Ï¡¢ ``<tt/make install/'' ¤È ``<tt/make
+ install.man/''¤ò¼Â¹Ô¤·¤Þ¤·¤ç¤¦¡£ ¥¤¥ó¥¹¥È¡¼¥ë½ÐÍè¤ë¤À¤±¤Î½½Ê¬¤Ê¶õ¤­
+ ¥Ç¥£¥¹¥¯ÍÆÎ̤¬¡¢ <tt>/usr/X11R6</tt> ¤Ë¤¢¤ë¤³¤È¤ò³Îǧ¤·¤Þ¤·¤ç¤¦¡£
+ <tt>/usr</tt>°Ê³°¤Î¾ì½ê¤ËÁȤ߹þ¤ß¤¿¤¤¾ì¹ç¤Ï¡¢ÁȤ߹þ¤àÁ°¤Ë <tt>/usr/
+ X11R6</tt> ¤Ë¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤òÄ¥¤ê¤Þ¤·¤ç¤¦¡£
+
+ ( <tt>/usr/X11R6/lib/Server</tt> ¤Ë¤¢¤ë)¥Ð¥¤¥Ê¥ê¥ê¥ó¥¯¥­¥Ã¥È¤òÁȤ߹þ
+ ¤à»þ¤Ï¡¢¡ÊÁ´¥½¡¼¥¹ÇÛÉÛʪËô¤Ï ServersOnly ÇÛÉÛʪ¤ò»ÈÍѤ¹¤ë¾ì¹ç¡Ë¼¡¤ò
+ <tt/xc/ ¥Ç¥£¥ì¥¯¥È¥ê¤«¤é¼Â¹Ô¤·¤Þ¤·¤ç¤¦¡£:
+
+<tscreen><verb>
+ make install.linkkit
+</verb></tscreen>
+
+<item> XFree86 ¤Ç¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë´ó£ÈǤΥµ¥Ö¥»¥Ã¥È¤òºîÀ®¤¹¤ë¤È¤­¤Ï¡¢ºÇ
+ ½é¤ËºîÀ®¤·¤ÆÆ³Æþ¤·¤¿¥³¥¢ÇÛÉÕʪ¤ò³Îǧ¤·¤Æ²¼¤µ¤¤¡£ ¤½¤·¤Æ¡¢
+ <tt/contrib/ ¥Ç¥£¥ì¥¯¥È¥ê¤Ø°Üư¤·¤Æ¡¢``<tt/xmkmf -a; make/''¤ò¼Â¹Ô¤·
+ ¤Æ²¼¤µ¤¤¡£ ¤³¤ì¤¬¤¦¤Þ¤¯¤¤¤Ã¤¿¤é¡¢ ``<tt/make install/'' ¤È ``<tt/make
+ install.man/'' ¤ò¼Â¹Ô¤·¤Æ¤³¤ì¤òÁȤ߹þ¤ó¤Ç¤¯¤À¤µ¤¤¡£
+</enum>
+<!--
+<sect> XFree86 ¤Î»ÈÍÑË¡¤È¹½ÃÛ
+<p>
+<enum>
+<item> <bf/PATH/ ´Ä¶­ÊÑ¿ô ¤Ë <tt>/usr/X11R6/bin</tt> ¤ò¡¢<bf/MANPATH/ ¤Ë
+ <tt>/usr/X11R6/man</tt> ¤òÄɲä·¤Þ¤·¤ç¤¦¡£
+
+<item> <tt/XF86Config/ ¥Õ¥¡¥¤¥ë¤òÀßÄꤷ¤Þ¤·¤ç¤¦¡£ ¤³¤Î¥Õ¥¡¥¤¥ë¤Î½é´ü°ÌÃÖ
+ ¤Ï: <tt>/etc/XF86Config</tt>,
+ <tt>/usr/X11R6/lib/X11/XF86Config.</tt><em/¥Û¥¹¥È̾/, ¤È
+ <tt>/usr/X11R6/lib/X11/XF86Config</tt>. <tt/XF86Config/ ¥Õ¥¡¥¤¥ë¤ò
+ <tt/xf86config/ ¥æ¡¼¥Æ¥£¥ê¥Æ¥£¤ò»È¤Ã¤Æºî¤ë¤³¤È¤ò¤ª´«¤á¤·¤Þ¤¹¡£ ¤Þ¤¿¡¢
+ ¥µ¥ó¥×¥ë¥Õ¥¡¥¤¥ë¤¬ <tt>/usr/X11R6/lib/X11/XF86Config.eg</tt>, ¤ËÁȤß
+ ¹þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¤Î¤Ç¡¢¤³¤ì¤òÎã¤Ë¤·¤Æ»Ï¤á¤Æ¤âÎɤ¤¤Ç¤·¤ç¤¦¡£
+
+ <tt/XF86Config/ ¤Î½ñ¼°¤Ë¤Ä¤¤¤Æ¾Ü¤·¤¯¤Ï¡¢<em>XF86Config(4/5)</em>¤Î¥ª
+ ¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë (4¾Ï/5¾Ï) ¤ò»²¾È¤·¤Þ¤·¤ç¤¦¡£
+
+<item> xinit ¤Ç <tt>&dollar;{HOME}/.xserverrc</tt> ¥Õ¥¡¥¤¥ë¤ò»È¤¦¾ì¹ç
+ ¤Ï¡¢¥µ¡¼¥Ð¡¼¤ò¼Â¹Ô¤·¤Æ¤¤¤ë¥¹¥¯¥ê¥×¥È¤ò³Îǧ¤·¤Þ¤·¤ç¤¦¡ÊÎ㤨¤Ð ñ¤Ë
+ ``<tt>/usr/X11R6/bin/XF86_SVGA</tt>'' ¤ò¼Â¹Ô¤¹¤ë¤è¤ê¤â ``<tt>exec
+ /usr/X11R6/bin/XF86_SVGA</tt>'' ¤ò¼Â¹Ô¤¹¤ë¤Î¤¬¤è¤¤¤Ç¤·¤ç¤¦)¡£ ¤³¤ì¤ò
+ ¤·¤Ê¤¤¾ì¹ç¤Ï¡¢¤æ¤Ã¤¯¤ê¤È¥µ¡¼¥Ð¡¼¤¬µ¯Æ°¤¹¤ë¤Ç¤·¤ç¤¦¡¢¤Þ¤¿ºÇ¸å¤Î¥¯¥é¥¤
+ ¥¢¥ó¥È¤¬ºî¶È¤ò½ªÎ»¤¹¤ë»þ¤Ë¥µ¡¼¥Ð¡¼¤ò½ªÎ»¤·¤Ê¤¤¤è¤¦¤Ë¤·¤Þ¤·¤ç¤¦¡£
+</enum>
+-->
+<sect> ¥½¡¼¥¹ÇÛÉÕʪ¤«¤é¤Î¥µ¡¼¥Ð¡¼¤ÎºÆ¹½ÃÛ
+<p>
+¿§¡¹¤Ê¥µ¡¼¥Ð¡¼Ëô¤Ï¿§¡¹¤Ê¥É¥é¥¤¥Ð¡¼¤ÎÁȤ߹ç¤ï¤»¤Î¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¾ì¹ç:
+<enum>
+<item>¿·¤·¤¤¥É¥é¥¤¥Ð¡¼Âбþ¤Î¥½¡¼¥¹¤¬Àµ¤·¤¤¾ì½ê¤Ë¤¢¤ë¤³¤È¤ò³Îǧ¤·¤Æ²¼¤µ¤¤
+ ¡ÊÎ㤨¤Ð¡¢SVGA ¥µ¡¼¥Ð¡¼Âбþ¥½¡¼¥¹¤Ï
+ <tt>xc/programs/Xserver/hw/xfree86/vga256/drivers</tt>¤È¸À¤¦¥µ¥Ö¥Ç¥£
+ ¥ì¥¯¥È¥ê¤Ë¤¢¤ê¤Þ¤¹¡Ë¡£
+
+<item> ¥µ¡¼¥Ð¡¼¤ÎÄêµÁ¡ÊÎ㤨¤Ð¡¢¾åµ­¤Ç½Ò¤Ù¤¿ <bf/XF86SVGAServer/ ¡Ë¤Ï¡¢
+ <tt/xf86site.def/ ¤ò»È¤Ã¤ÆºîÀ®¤·¤¿¤¤¥µ¡¼¥Ð¡¼¤ò»ØÄꤷ¤ÆÀßÄꤷ¤Þ¤·¤ç
+ ¤¦¡£¤Þ¤¿¡¢¥É¥é¥¤¥Ð¡¼°ìÍ÷¤òɬÍפ˱þ¤¸¤ÆÊѹ¹¤·¤Þ¤·¤ç¤¦¡£
+
+<item> <tt>xc/programs/Xserver</tt> ¤«¤é¼¡¤Î¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤Þ¤·¤ç¤¦:
+<tscreen><verb>
+ make Makefile
+ make Makefiles
+ make depend
+ make
+</verb></tscreen>
+</enum>
+
+<sect> ¥Ð¥¤¥Ê¥êÇÛÉÕʪ¤«¤é¤Î¥µ¡¼¥Ð¡¼¤ÎºÆ¹½ÃÛ
+<p>
+ ¥µ¡¼¥Ð¡¼¤Î¥Ð¥¤¥Ê¥ê¥ê¥ó¥¯¥­¥Ã¥È¤òÁȤ߹þ¤à¤È¡¢¥µ¡¼¥Ð¡¼Æâ¤Î¥É¥é¥¤¥Ð¤È¥µ¡¼
+ ¥Ð¡¼¤Îµ¡Ç½³ÈÄ¥¤ÎºÆ¹½ÃÛ¤¬²Äǽ¤Ë¤Ê¤ê¤Þ¤¹¡£ºÆ¹½ÃÛ¤òÇ¡²¿¤Ë¹Ô¤¦¤«¤Î¾ÜºÙ¤Ï¡¢
+ <htmlurl url="LinkKit.html" name="README.LinkKit"> ¥Õ¥¡¥¤¥ë¤ò»²¾È¤·¤Æ¤¯¤À
+ ¤µ¤¤¡£
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/INSTALL.sgml,v 3.2 1997/01/26 04:34:18 dawes Exp $
+</verb>
+<hrule>
+
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ï xc/programs/Xserver/hw/xfree86/doc/sgml/INSTALL.sgml,v 3.17 1
+996/10/26 09:38:49 ¤ò¡¢²¬ËÜ °ì¹¬
+( Kazuyuki Okamoto <url url="mailto:ikko-@pacific.rim.or.jp"
+name="&lt;ikko-@pacific.rim.or.jp&gt;"> ) ¤¬ XFree86 3.2 ¤ò
+ÆüËܤǥ¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¿Í¸þ¤±¤ËÏÂÌõ¤·¤¿¤â¤Î¤Ç¤¹¡£¤³¤³¤¬¤ª¤«¤·¤¤¤È¤«¡¢
+¤³¤³¤Ï¤³¤¦¤·¤¿¤Û¤¦¤¬¤¤¤¤¤È¤¤¤Ã¤¿¤´°Õ¸«¤¬¤¢¤ê¤Þ¤·¤¿¤é¡¢ÅŻҥ᡼¥ë¤Ç
+¤ªÃΤ餻²¼¤µ¤¤¡£
+¸¶Ê¸¤ÎÃøºî¸¢¤Ï XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ÎÏÂÌõ¤ÎÃøºî¸¢¤Ï
+XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤È²¬ËÜ¡¡°ì¹¬¤Ë¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤ÎÏÂÌõ¤ÎÉÔ¶ñ¹ç¤Ï»ä¤Ë¡¢
+ÅŻҥ᡼¥ë¤ÇÁ÷¤Ã¤Æ²¼¤µ¤¤¡£
+<hrule>
+&lsqb;EOF&rsqb;
+</article>
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/LinkKit.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/LinkKit.sgml
new file mode 100644
index 000000000..a18214bfc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/LinkKit.sgml
@@ -0,0 +1,228 @@
+<!doctype linuxdoc system>
+
+<article>
+
+<title> XFree86 3.2 ¥ê¥ó¥¯¥­¥Ã¥È¤Î Readme
+<author> XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò
+<date> 1996 ǯ 10 ·î 14 Æü
+<trans> ²¬ËÜ¡¡°ì¹¬ Kazuyuki Okamoto &lt;ikko-@pacific.rim.or.jp&gt;
+<sect> XFree86 3.2 ¥ê¥ó¥¯¥­¥Ã¥È¤Î Readme <p>
+<enum>
+<item> gcc-2 ¤ò»ÈÍѤ·¤Ê¤¤¥·¥¹¥Æ¥à¤Ç¡¢gcc-2 ¤ÇºîÀ®¤µ¤ì¤¿¥Ð¥¤¥Ê¥êÇÛÉÕʪ
+ ¤ò»ÈÍѤ¹¤ë¾ì¹ç¤Ï libgcc.a ¤òÁȤ߹þ¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+
+<item> ¥ê¥ó¥¯¥­¥Ã¥È¤Ç Xnest ¤òÁȤ߹þ¤à¾ì¹ç¤Ï XFree86 3.2 ¤Î
+ <tt>/usr/X11R6</tt> ¤Î
+ ²¼¤ËÁȤ߹þ¤Þ¤ì¤¿¥é¥¤¥Ö¥é¥ê¤ò³Îǧ¤·¤Æ²¼¤µ¤¤¡£¸½ºß¡¢¥ê¥ó¥¯¥­¥Ã¥È¤Ï
+ ¾¤Î¥µ¡¼¥Ð¡¼¤Ç¤ÏÆâ¢¤·¤Æ¤¤¤Þ¤¹¡£
+
+<item> ¤É¤Î¥µ¡¼¥Ð¡¼¤òÁȤ߹þ¤ß¤¿¤¤¤«¤È¡¢¤É¤Î¥É¥é¥¤¥Ð¤Èµ¡Ç½³ÈÄ¥¤ò´Þ¤Þ
+ ¤»¤¿¤¤¤«¤òÄêµÁ¤¹¤ë¤¿¤á¤Ë <tt/xf86site.def/ ¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Æ²¼
+ ¤µ¤¤¡£
+
+ <itemize>
+ <item> ½é´üÃͤ¬Àµ¤·¤¯¤Ê¤¤¾ì¹ç¤Ë¡¢»ÈÍѤ¹¤ë¥³¥ó¥Ñ¥¤¥é¡¼¤Ë¹ç¤ï¤»¤Æ
+ <tt>HasGcc</tt> ¤È <tt>HasGcc2</tt> ¤òÀßÄꤷ¤Æ²¼¤µ¤¤¡£
+ <item> ¥ê¥ó¥¯¥­¥Ã¥È¤¬ gcc-2.x ¤ÇºîÀ®¤µ¤ì¤Æ¤¤¤Æ¡¢¤½¤ì¤È°Û¤Ê¤ë¥³¥ó
+ ¥Ñ¥¤¥é¡¼¤ò»ÈÍѤ¹¤ë¾ì¹ç¡¢
+ libgcc.a ¤È <tt>NeedLibGcc</tt> ¤ò <tt>YES</tt> ¤ËÀßÄꤹ¤ëɬÍפ¬
+ ¤¢¤ê¤Þ¤¹¡£
+ <item>256 ¿§¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF86SVGAServer</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>16 ¿§¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF86VGA16Server</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>Çò¹õ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF86MonoServer</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>S3 ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF86S3Server</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>Mach8 ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF86Mach8Server</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>Mach32 ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF86Mach32Server</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>Mach64 ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF86Mach64Server</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>P9000 ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF86P9000Server</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>AGX ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF86AGXServer</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>ET4000/W32 ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF86W32Server</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>IBM 8514/A ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF86I8514Server</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+<!--
+ <item>To build the I128 server:
+ set <tt>XF86I128Server</tt> to <tt>YES</tt>.
+ <item>To build the TGA server:
+ set <tt>XF86TGAServer</tt> to <tt>YES</tt>.
+ <item>To build the GA-98NB/WAP server:
+ set <tt>XF98GANBServer</tt> to <tt>YES</tt>.
+ <item>To build the NEC480 server:
+ set <tt>XF98NEC480Server</tt> to <tt>YES</tt>.
+ <item>To build the NEC-CIRRUS/EPSON NKV/NKV2 server:
+ set <tt>XF98NKVNECServer</tt> to <tt>YES</tt>.
+ <item>To build the WAB-S server:
+ set <tt>XF98WABSServer</tt> to <tt>YES</tt>.
+ <item>To build the WAB-EP server:
+ set <tt>XF98WABEPServer</tt> to <tt>YES</tt>.
+ <item>To build the WSN-A2F server:
+ set <tt>XF98WSNAServer</tt> to <tt>YES</tt>.
+ <item>To build the Trident Cyber9320/9680 server:
+ set <tt>XF98TGUIServer</tt> to <tt>YES</tt>.
+ <item>To build the EGC server:
+ set <tt>XF98EGCServer</tt> to <tt>YES</tt>.
+ <item>To build the NEC S3 server:
+ set <tt>XF98NECS3Server</tt> to <tt>YES</tt>.
+ <item>To build the S3 PW/PCSKB server:
+ set <tt>XF98PWSKBServer</tt> to <tt>YES</tt>.
+ <item>To build the S3 PW/LB server:
+ set <tt>XF98PWLBServer</tt> to <tt>YES</tt>.
+ <item>To build the S3 GA-968 server:
+ set <tt>XF98GA968Server</tt> to <tt>YES</tt>.
+-->
+ <item>I128 ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF86I128Server</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>TGA ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF86TGAServer</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>GA-98NB/WAP ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF98GANBServer</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>NEC480 ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF98NEC480Server</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>NEC-CIRRUS/EPSON NKV/NKV2 server:
+ <tt>XF98NKVNECServer</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>WAB-S ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF98WABSServer</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>WAB-EP ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF98WABEPServer</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>WSN-A2F ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF98WSNAServer</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>Trident Cyber9320/9680 server:
+ <tt>XF98TGUIServer</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>EGC ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF98EGCServer</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>NEC S3 ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF98NECS3Server</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>S3 PW/PCSKB ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF98PWSKBServer</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>S3 PW/LB ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF98PWLBServer</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>S3 GA-968 ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XF98GA968Server</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+
+ <item>Xnest ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤Ë¤Ï:
+ <tt>XnestServer</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+
+ <item> <tt>XF86SvgaDrivers</tt> ¤ò SVGA ¥µ¡¼¥Ð¡¼¤Ë´Þ¤á¤¿¤¤
+ ¥É¥é¥¤¥Ð¤Î°ìÍ÷¤ËÀßÄꤷ¤Æ²¼¤µ¤¤¡£
+ <item> <tt>XF86Vga16Drivers</tt> ¤ò 16 ¿§ ¥µ¡¼¥Ð¡¼¤Ë´Þ¤á¤¿¤¤
+ ¥É¥é¥¤¥Ð¤Î°ìÍ÷¤ËÀßÄꤷ¤Æ²¼¤µ¤¤¡£
+ <item> <tt>XF86Vga2Drivers</tt> ¤òÇò¹õ vga ¥µ¡¼¥Ð¡¼¤Ë´Þ¤á¤¿¤¤
+ ¥É¥é¥¤¥Ð¤Î°ìÍ÷¤ËÀßÄꤷ¤Æ²¼¤µ¤¤¡£
+ <item> <tt>XF86MonoDrivers</tt> ¤òÇò¹õËô¤Ï VGA16 ¥µ¡¼¥Ð¡¼
+ (ÁÐÆ¬¤Î¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¤È¤­)¤ò´Þ¤á¤¿¤¤Èó VGA
+ ¥É¥é¥¤¥Ð¤Î°ìÍ÷¤ËÀßÄꤷ¤Æ²¼¤µ¤¤¡£
+ <item>Ãí°Õ: ¥É¥é¥¤¥Ð¤Î½çÈ֤ϥɥ饤¥Ð¤Î¸¡½Ð¤Î½çÈÖ¤ò·èÄꤷ¤Þ¤¹¡£
+ `<tt>ÈÆÍÑ</tt>' (`<tt>generic</tt>') ¥É¥é¥¤¥Ð¤Ï¾ï¤Ë¸¡½Ð¤ËÀ®¸ù
+ ¤¹¤ë¤Î¤Ç Mono ¤È VGA16 ¤È SVGA ¥µ¡¼¥Ð¡¼¤Ë´Þ¤Þ¤»¤ë¥É¥é¥¤¥Ð¤Î
+ ºÇ¸å¤Ë»ØÄꤷ¤Æ²¼¤µ¤¤¡£
+<!--
+ <item>To use dynamically loadable modules(e.g. PEX, XIE):
+ set <tt>ExtensionsDynamicModules</tt> to <tt>YES</tt>.
+-->
+ <item>ưŪ¥í¡¼¥É²Äǽ¥â¥¸¥å¡¼¥ë(Î㤨¤Ð PEX, XIE)¤ò»ÈÍѤ¹¤ë¤Ë¤Ï:
+ <tt>ExtensionsDynamicModules</tt> ¤ò <tt>YES</tt>¡¡¤Ë¤·¤Þ¤¹¡£
+ <item>PEX µ¡Ç½³ÈÄ¥¤òÁȤ߹þ¤à¤Ë¤Ï:
+ <tt>BuildPexExt</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>X ¥¤¥á¡¼¥¸µ¡Ç½³ÈÄ¥¤òÁȤ߹þ¤à¤Ë¤Ï:
+ <tt>BuildXIE</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+<!--
+ <item>ÄãÂÓ°è X µ¡Ç½³ÈÄ¥¤òÁȤ߹þ¤à¤Ë¤Ï:
+ <tt>BuildLBX</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>¥¹¥¯¥ê¡¼¥ó¥»¡¼¥Ð¡¼µ¡Ç½³ÈÄ¥¤òÁȤ߹þ¤à¤Ë¤Ï:
+ <tt>BuildScreenSaverExt</tt> ¤ò <tt>YES</tt> ¤Ë¤·¤Þ¤¹¡£
+
+ <item>£±¤Ä°Ê¾å¤Î X ¥µ¡¼¥Ð¡¼¤òºîÀ®¤¹¤ë¾ì¹ç¤Ï¡¢<tt>ServerToInstall</tt>
+ ¹Ô¤Î¥³¥á¥ó¥È¤ò¤Ï¤º¤·¤ÆÉ¸½à¥µ¡¼¥Ð¡¼¡Ê¤Ä¤Þ¤ê¡¢``X''¤Ë¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯
+ ¤òÄ¥¤ë¥µ¡¼¥Ð¡¼¡Ë¤È¤·¤¿¤¤ X ¥µ¡¼¥Ð¡¼¤Î̾¾Î¤òÀßÄꤷ¤Æ²¼¤µ¤¤¡£
+- <item>To include the Low Bandwidth X extension:
+- set <tt>BuildLBX</tt> to <tt>YES</tt>.
+- <item>To include the Screen Saver extension:
+- set <tt>BuildScreenSaverExt</tt> to <tt>YES</tt>.
+-
+- <item>If you are building more than one Xserver, uncomment the
+- <tt>ServerToInstall</tt> line and set it to the name of the
+- Xserver you want to be the default server (i.e., the one that
+- the ``X'' sym-link points to).
++ <item>To exclude the Double Buffer Extension:
++ set <tt>BuildDBE</tt> to <tt>NO</tt>.
++ <item>To exclude the Record Extension:
++ set <tt>BuildRECORD</tt> to <tt>NO</tt>.
++ <item>To exclude the Screen Saver extension:
++ set <tt>BuildScreenSaverExt</tt> to <tt>NO</tt>.
++ <item>Although it is possible to disable other extensions through this
++ mechanism, doing so is not recommended because savings in server size
++ are not appreciable, or the resulting server might even be crippled in
++ some way.
+-->
+ <item>Æó½Å¥Ð¥Ã¥Õ¥¡µ¡Ç½³ÈÄ¥¤ò¤Ï¤º¤¹»þ¤Ï:
+ <tt>BuildDBE</tt> ¤ò <tt>NO</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>µ­Ï¿µ¡Ç½³ÈÄ¥¤ò¤Ï¤º¤¹»þ¤Ï:
+ <tt>BuildRECORD</tt> ¤ò <tt>NO</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>¥¹¥¯¥ê¡¼¥ó¥»¡¼¥Ð¡¼µ¡Ç½³ÈÄ¥¤ò¤Ï¤º¤¹»þ¤Ï:
+ <tt>BuildScreenSaverExt</tt> to <tt>NO</tt> ¤Ë¤·¤Þ¤¹¡£
+ <item>Although it is possible to disable other extensions through this
+ mechanism, doing so is not recommended because savings in server size
+ are not appreciable, or the resulting server might even be crippled in
+ some way.
+ <item>¤½¤Î¾¤Îµ¡Ç½³ÈÄ¥¤ò¤³¤Îµ¡¹½¤ò»È¤Ã¤Æ¤Ï¤º¤¹¤³¤È¤Ï½ÐÍè¤Þ¤¹¤¬¡¢¥µ¡¼¥Ð
+ ¤ÎÂ礭¤µ¤¬Ìܤ˸«¤¨¤ë¤Û¤ÉÀáÌó½ÐÍè¤Ê¤¤¡¢¤Þ¤¿¤Ï¤¤¤¯¤Ä¤«¤ÎÅÀ¤ÇÉÔÊØ¤Ë¤Ê¤ë
+ ¤Î¤Ç¤ª´«¤á¤·¤Þ¤»¤ó¡£
+
+ </itemize>
+
+<item> ɸ½àÇÛÉÕʪ¤Ë´Þ¤Þ¤ì¤Ê¤¤¥É¥é¥¤¥Ð¤òÁȤ߹þ¤à¾ì¹ç¤Ï¡¢<tt>drivers/vga256</tt>
+ (Çò¹õ¥µ¡¼¥Ð¡¼¤Î VGA2 ¤Î¾ì¹ç¤Ï <tt>drivers/vga2</tt>¡¢16 ¿§¥µ¡¼¥Ð¡¼¤Î¾ì¹ç¤Ï
+ <tt>drivers/vga16</tt>¡¢Èó VGA ¤Î Çò¹õ¤È 16 ¿§¥µ¡¼¥Ð¡¼¤Î¾ì¹ç¤Ï
+ <tt>drivers/mono</tt>) ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤òºîÀ®¤·¤Æ¡¢¤½¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Ë¥½¡¼
+ ¥¹¥Õ¥¡¥¤¥ë¤« .o ¥Õ¥¡¥¤¥ë¤Î¤¤¤º¤ì¤«¤ÈŬÀÚ¤Ê Imakefile ¤ò¥³¥Ô¡¼¤·¤Þ¤·¤ç¤¦¡£¤½
+ ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î̾¾Î¤Ï³ºÅö¤¹¤ë¥É¥é¥¤¥Ð¤Î̾¾Î¤È°ìÃפµ¤»¤Æ²¼¤µ¤¤¡Ê¤è¤ê¾Ü¤·¤¯¤Ï
+ <tt>VGADriverDoc</tt> ¥Ç¥£¥ì¥¯¥È¥ê¤ÎÃæ¤Ë¤¢¤ëʸ½ñ¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡Ë¡£
+
+<item> Makefile ¤òºîÀ®¤¹¤ë¤Ë¤Ï¡¢¼¡¤Î¥³¥Þ¥ó¥É¤ò¼Â¹Ô¤·¤Æ²¼¤µ¤¤¡£
+<verb>
+ ./mkmf
+</verb>
+<item> `<tt>make</tt>' ¤ò¼Â¹Ô¤¹¤ë¤È¹½À®ÄêµÁ¤·¤¿¥µ¡¼¥Ð¡¼¤ò·ë¹ç¤·¤Þ¤¹¡£
+
+<item> `<tt>make install</tt>' ¤ò¼Â¹Ô¤¹¤ë¤È¿·¤·¤¤¥µ¡¼¥Ð¡¼¤òÁȤ߹þ¤ß¤Þ¤¹¡£
+
+<item> `<tt>make clean</tt>' ¤ò¼Â¹Ô¤¹¤ë¤È¤³¤Î¼ê½ç¤ÇºîÀ®¤·¤¿¥Õ¥¡¥¤¥ë¤òºï½ü¤·¤Þ¤¹¡£
+
+<item> <tt/xf86site.def/ ¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¡¢ºîÀ®¤¹¤ë¥µ¡¼¥Ð¡¼¤«¥µ¡¼¥Ð¡¼¤Ë´Þ¤Þ¤»¤ë
+ ¥É¥é¥¤¥Ð¤ÎÁªÂò¤òÊѹ¹¤·¤Æ¡¢¾åµ­¤Î¼ê½ç¤ò·«¤êÊÖ¤·¤Æ²¼¤µ¤¤¡£<tt/xf86site.def/
+ ¥Õ¥¡¥¤¥ë¤Ë¤Æ X ¥µ¡¼¥Ð¡¼µ¡Ç½³ÈÄ¥¤ÎÁªÂò¤òÊѹ¹¤·¤¿¾ì¹ç¤Ï¡¢`<tt>./mkmf</tt>' ¤Î
+ ¤«¤ï¤ê¤Ë `<tt>make Makefile</tt>' ¤ò¼Â¹Ô¤¹¤ì¤Ð½½Ê¬¤Ç¤·¤ç¤¦¡£
+
+<item> X ¥µ¡¼¥Ð¡¼¤Ë `<tt>-showconfig</tt>' ¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤Æ¼Â¹Ô¤¹¤ì¤Ð X ¥µ¡¼
+ ¥Ð¡¼¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤òÄ´¤Ù¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡£¤É¤ó¤Êµ¡Ç½³ÈÄ¥¤¬´Þ¤Þ¤ì¤Æ¤¤
+ ¤ë¤«¤ò³Îǧ¤¹¤ë¤Ë¤Ï¡¢X ¥µ¡¼¥Ð¡¼¤òµ¯Æ°¤·¡¢`<tt>xdpyinfo</tt>' ¤ò¼Â¹Ô¤·¤Æ²¼¤µ
+ ¤¤¡£
+</enum>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/LinkKit.sgml,v 3.2 1997/01/26 04:34:19 dawes Exp $
+</verb>
+<hrule>
+
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ï xc/programs/Xserver/hw/xfree86/doc/sgml/LinkKit.sgml,v 3.11 1996/10/16 14:41:12 ¤ò¡¢²¬ËÜ °ì¹¬
+( Kazuyuki Okamoto <url url="mailto:ikko-@pacific.rim.or.jp"
+name="&lt;ikko-@pacific.rim.or.jp&gt;"> ) ¤¬ XFree86 3.2 ¤ò
+ÆüËܤǥ¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¿Í¸þ¤±¤ËÏÂÌõ¤·¤¿¤â¤Î¤Ç¤¹¡£¤³¤³¤¬¤ª¤«¤·¤¤¤È¤«¡¢
+¤³¤³¤Ï¤³¤¦¤·¤¿¤Û¤¦¤¬¤¤¤¤¤È¤¤¤Ã¤¿¤´°Õ¸«¤¬¤¢¤ê¤Þ¤·¤¿¤é¡¢ÅŻҥ᡼¥ë¤Ç
+¤ªÃΤ餻²¼¤µ¤¤¡£
+¸¶Ê¸¤ÎÃøºî¸¢¤Ï XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ÎÏÂÌõ¤ÎÃøºî¸¢¤Ï
+XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤È²¬ËÜ¡¡°ì¹¬¤Ë¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤ÎÏÂÌõ¤ÎÉÔ¶ñ¹ç¤Ï»ä¤Ë¡¢
+ÅŻҥ᡼¥ë¤ÇÁ÷¤Ã¤Æ²¼¤µ¤¤¡£
+<hrule>
+&lsqb;EOF&rsqb;
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/Linux.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/Linux.sgml
new file mode 100644
index 000000000..0e16e4d1f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/Linux.sgml
@@ -0,0 +1,345 @@
+<!doctype linuxdoc system>
+
+<article>
+
+<title> Linux ¤ò»ÈÍѤ·¤Æ¤¤¤ë¿Í¤Î¤¿¤á¤Î¾ðÊó
+<author> Orest Zborowski, Dirk Hohndel
+<date> 1996 ǯ 10 ·î 20 Æü
+<trans> ²¬ËÜ¡¡°ì¹¬ Kazuyuki Okamoto &lt;ikko-@pacific.rim.or.jp&gt;
+<toc>
+
+<sect> XFree86 ¤¬¥Æ¥¹¥È¤µ¤ì¤¿ Linux ¤Î¥Ð¡¼¥¸¥ç¥ó <p>
+XFree86 ¤Ï Linux ¤Î¥Ð¡¼¥¸¥ç¥ó 2.0.19 ¤Ç¥Æ¥¹¥ÈºÑ¤ß¤Ç¤¹¡£ 1.0 °Ê¹ß¤Î¥Ð¡¼¥¸¥ç
+¥ó¤Ç¤Ï¡¢XFree86 ¤ËÊѹ¹¤¬¤Ê¤±¤ì¤Ðư¤¯¤Ç¤·¤ç¤¦¡£¥Ð¥¤¥Ê¥ê¤È¥é¥¤¥Ö¥é¥ê¤Ï
+5.2.18 Elf C ¥é¥¤¥Ö¥é¥ê¤È 1.7.14 ¤Î¥À¥¤¥Ê¥ß¥Ã¥¯¡¦¥ê¥ó¥«¡¼ <tt>ld.so</tt> ¤ò´ð¤Ë¤·
+¤Æ¤¤¤Þ¤¹¡£
+DLL X ¥é¥¤¥Ö¥é¥ê
+¤Ï Eric Youngdale »á¤Ë¤è¤Ã¤Æ 2.16 DLL-tools ¤ò»ÈÍѤ·¤ÆºîÀ®¤µ¤ì¤Þ¤·¤¿¡£
+
+<sect> Á°¤Î¥Ð¡¼¥¸¥ç¥ó¤È¤Î¸ß´¹À­ <p>
+X11R6 ¤Ï X11R5 ¤«¤éÂ礭¤¯¹¹¿·¤·¤¿¤â¤Î¤È¤Ê¤Ã¤Æ¤¤¤Þ¤¹¤Î¤Ç¡¢XFree86-3.1 °Ê¹ß
+¤Î¶¦Í­¥é¥¤¥Ö¥é¥ê¤Ï¡¢XFree86-2.1.1 °ÊÁ°¤Î¸Å¤¤¥é¥¤¥Ö¥é¥ê¤È¤Ï¸ß´¹À­¤¬¤¢¤ê¤Þ¤»
+¤ó¡£X11R5 ¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ò¼Â¹Ô¤¹¤ë¤Ë¤Ï¡¢¥Þ¥·¥ó¤Î²¿½è¤«¤Ë¸Å¤¤¥é¥¤¥Ö¥é¥ê
+¤òÊݸ¤·¤Æ¤ª¤«¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£¸Å¤¤¥é¥¤¥Ö¥é¥ê¤Ï<tt>/usr/X386/lib</tt> ¤«¤é²¿½è¤«
+¤Ø°Üư¤¹¤ì¤Ð¤¤¤¤¤Î¤Ç¤¹¤¬¡¢<tt>/etc/ld.so.conf</tt> ¤Ï¹¹¿·¤·¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£Á´¤Æ
+¤Î X11R5 ¤Î¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÏÌäÂê̵¤¯ X11R6 ¤Î¥µ¡¼¥Ð¡¼¤È°ì½ï¤Ëưºî¤¹¤ë¤Ç¤·
+¤ç¤¦¡£
+
+<!--X11R6.1 is yet another update to X11R6. While the minor number for some
+libraries has been increased to '1' it is believed to be fully
+compatible with X11R6 based applications.-->
+X11R6.1 ¤ÏX11R6 ¤Î¤â¤¦°ì¤Ä¤ÎºÇ¿·ÈǤǤ¹¡£ ¤¤¤¯¤Ä¤«¤Î¥é¥¤¥Ö¥é¥ê¤Î¥Þ¥¤¥Ê¡¼Èֹ椬
+ '1'Áý²Ã¤·¤Æ¤¤¤ë»þ¡¢¤½¤Î¥é¥¤¥Ö¥é¥ê¤Ï X11R6 ¤Çưºî¤¹¤ë¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤È´°Á´¤Ë
+¸ß´¹À­¤¬¤¢¤ë¤È¹Í¤¨¤Þ¤¹¡£
+
+XFree86-1.2¡¢XFree86-1.3 ¤Þ¤¿¤Ï XFree86-2.0 ¥é¥¤¥Ö¥é¥ê¤È´ØÏ¢¤Î¤¢¤ë¸Å¤¤¥Ð¥¤
+¥Ê¥ê¤Ï°ú¤­Â³¤­Æ°ºî¤·¤Þ¤¹¤¬¡¢<tt>/lib/libX{11,t,aw}.so.3</tt>
+<tt>/usr/X386/lib/libX{11,t,aw}.so.3</tt> ¤ØÌÀ³Î¤Ë¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤òÄ¥¤ëɬÍפ¬¤¢
+¤ê¤Þ¤¹¡£XView3L5 ÇÛÉÕʪ¤ËÂФ·¤Æ <tt>ld.so</tt> ¤ò¥ê¥ó¥¯¤¹¤ë»þ¤Ï¡¢XView ¥é¥¤¥Ö¥é¥ê¤Ë
+ld.so ¤¬Æ°ºî¤·¤Ê¤¤¤è¤¦¤Ë¶¦Í­¥¤¥á¡¼¥¸¤Ø¤ÎÀäÂХѥ¹¤ò´Þ¤Þ¤»¤Ê¤¤¤È¡¢1.3 °ÊÁ°¤Î
+¥Ð¡¼¥¸¥ç¥ó¤Î <tt>ld.so</tt> ¤È¤ÏÌäÂê¤òÀ¸¤¸¤ë¤Ç¤·¤ç¤¦¡£»ÃÄêŪÂкö¤Ï¡¢<tt>/</tt>¡Ê¥ë¡¼¥È¥Ç¥£¥ì
+¥¯¥È¥ê¡Ë¤ò <tt>/etc/ld.so.config</tt> ¤ËÆþ¤ì¤ë¤³¤È¤Ç¤¹¤¬¡¢¤è¤êÎɤ¯¤¹¤ë¤Ê¤é¡¢XView
+¤òÁêÂХ饤¥Ö¥é¥ê̾¤È¥ê¥ó¥¯¤¹¤ë¤«¡¢¤è¤ê¿·¤·¤¤ <tt>ld.so</tt> ¤ò¼ê¤ËÆþ¤ì¤ë¤³¤È¤Ç¤¹¡£
+
+<sect> XFree86 ¤òƳÆþ¤¹¤ë¤Ë¤Ï <p>
+¥Ð¡¼¥¸¥ç¥ó 3.0 ¤«¤é»Ï¤á¤ë¤Ê¤é¡¢XFree86 ¤ò <tt>/usr/X11R6</tt> ¤ËƳÆþ¤·¤Þ¤¹¡£X11R5
+¤È X11R6 ¤ÎξÊý¤òƳÆþ¤¹¤ë½½Ê¬¤Ê¥Ç¥£¥¹¥¯ÍÆÎ̤¬Ìµ¤¤¾ì¹ç¤Ï¡¢X11R5 ¤ÎɬÍפÎ̵
+¤¤Éôʬ¤ò¼Î¤Æ¤ë»ö¤Ç¥Ç¥£¥¹¥¯ÍÆÎ̤ò³ÎÊݤ·¤Þ¤·¤ç¤¦¡£ÆÃ¤Ë¡¢¥Õ¥©¥ó¥È¤È¸Å¤¤
+X11R5 ¤Î¥Ð¥¤¥Ê¥ê¤Ï¡¢¾Ãµî½ÐÍè¤Þ¤¹¡£¥À¥¤¥Ê¥ß¥Ã¥¯¥ê¥ó¥¯¤ò»È¤¦ X11R5 ¤Î¥Ð¥¤¥Ê
+¥ê¤òưºî¤µ¤»¤ë¤Ë¤Ï¶¦Í­¥é¥¤¥Ö¥é¥ê¤ò¼è¤Ã¤Æ¤ª¤¤¤Æ²¼¤µ¤¤¡£
+
+XFree86 3.X ¤Î¤½¤ì¤¾¤ì¤Î¥Ð¥¤¥Ê¥êÇÛÉÕʪ¤Ë¤Ï¡¢Âбþ¤¹¤ëÈÇ¤Î¾ÜºÙ¤ÊÆ³Æþ¤Ë´Ø¤¹¤ë
+ʸ½ñ¤¬ÉÕ°¤·¤Æ¤¤¤Þ¤¹¡£Ëؤɤκǿ·¤Î¾ðÊ󤬤½¤Îʸ½ñ¤Ë¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤Îʸ½ñ¤Ë
+Linux ¤Çư¤¯ XFree86 3.X ¤Î´ðËÜŪ¤Êµ¡Ç½¤È¥½¡¼¥¹¤ò¤É¤¦¤ä¤Ã¤Æ¥³¥ó¥Ñ¥¤¥ë¤¹¤ë
+¤«¤òµ­½Ò¤·¤Æ¤¤¤Þ¤¹¡£
+
+<sect> XFree86 ¤òưºî¤µ¤»¤ë¤Ë¤Ï <p>
+XFree86 ¤òưºî¤µ¤»¤ë¤¿¤á¤Ë¤Ï 4MB ¤Î²¾ÁÛ¥á¥â¥ê¤¬É¬ÍפǤ¹¤¬¡¢²÷Ŭ¤Ëưºî¤µ¤»
+¤ëºÇ¾®¤Î´Ä¶­¤È¤·¤Æ¤Ï¡¢Â¿Ê¬ 8MB ¤Î¼Âµ­²±¤¬¤¢¤Ã¤¿¤Û¤¦¤¬¤¤¤¤¤Ç¤·¤ç¤¦¡£386 ¥×
+¥í¥»¥Ã¥µ¤Ë¤È¤Ã¤Æ 387 ¥³¥×¥í¥»¥Ã¥µ¤Ï¡¢Í­¸ú¤Ç¤¹¤¬¡¢ÊªÍýŪ¤Ê¥á¥â¥ê¤òÁýÀߤ·¤¿
+¤Û¤¦¤¬ÂÐÏýèÍý¤Î®Å٤ϳÊÃʤ˸þ¾å¤·¤Þ¤¹¡£¤Þ¤¿¡¢¹â®¤Ê¥°¥é¥Õ¥£¥Ã¥¯¥«¡¼¥É¡¢¥Ð
+¥¹¤Þ¤¿¤Ï¥á¥â¥ê¤¬¥µ¡¼¥Ð¡¼¤ÎÀ­Ç½¤ò¸þ¾å¤µ¤»¤ë¤Ç¤·¤ç¤¦¡£
+
+tar ¥Õ¥¡¥¤¥ë¤òŸ³«¤·¤¿¤é¡¢<tt>/etc/ld.so.conf</tt> ¤ÎÃæ¤«¡Ê½é´üÃͤˤè¤Ã¤Æ´û¤Ë¤½¤¦Äê
+µÁ¤µ¤ì¤Æ¤¤¤ë¤Ï¤º¤Ç¤¹¡Ë¡¢<tt>LD_LIBRARY_PATH</tt> ´Ä¶­ÊÑ¿ô¤ÎÃæ¤Ë <tt>/usr/X11R6/lib</tt> ¤òÄê
+µÁ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤Þ¤¿¡¢¹½À®ÄêµÁ¥Õ¥¡¥¤¥ë¤Ç¤¢¤ë
+<tt>README.Config</tt> ¤ò»Ø¿Ë¤È¤·¡¢<tt>XF86Config.eg</tt> ¤òÎãÂê¤Ë¤·¤Æ
+<tt>/etc/XF86Config</tt> ¤Þ¤¿¤Ï <tt>/usr/X11R6/lib/X11/XF86Config</tt>¤ò
+¥Û¥¹¥È¤Î¹½À®¤òÀµ³Î¤Ëµ­Æþ<em>¤·¤Ê¤±¤ì¤Ð</em>¤Ê¤ê¤Þ¤»¤ó¡£´Ö°ã¤Ã¤¿
+<tt>XF86Config</tt> ¤ò»È¤¦¤È¥Ï¡¼¥É¥¦¥§¥¢¤òÄˤá¤ë¾ì¹ç¤¬¤¢¤ë¤Î¤Ç¡¢
+<em>Îɤ¯Ê¸¾Ï¤òÆÉ¤ó¤Ç</em>²¼¤µ¤¤¡£
+ÆÃ¤Ë¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤È <tt>/usr/X11R6/lib/X11/doc</tt> ¤Ë¤¢¤ë¤½¤Î¾¤Î
+<tt>README</tt> ¥Õ¥¡¥¤¥ë¤òÎɤ¯ÆÉ¤ó¤Ç²¼¤µ¤¤¡£
+
+<!--Starting with XFree86-3.1.2F a new interactive setup utility
+<tt>XF86Setup</tt> has been included in the distribution. We recommend
+using this tool to setup the <tt>XF86Config</tt> file. Please read the
+corresponding documentation.-->
+XFree86-3.1.2F ¤«¤é¤Ï¤¸¤á¤ë¤Ê¤é¤ÐÇÛÉÛʪ¤ËÆþ¤Ã¤Æ¤¤¤ë¿·¤·¤¤ÀßÄê¥æ¡¼¥Æ¥£¥ê¥Æ¥£
+¤Ç¤¢¤ë <tt>XF86Setup</tt> ¤¬¤¢¤ê¤Þ¤¹¡£<tt>XF86Config</tt> ¤òÀßÄꤹ¤ë
+¤³¤Î¥Ä¡¼¥ë¤ò»ÈÍѤ¹¤ë¤³¤È¤ò¤ª´«¤á¤·¤Þ¤¹¡£Å¬ÀÚ¤Êʸ½ñ¤ò¤ªÆÉ¤ß¤¯¤À¤µ¤¤¡£
+
+XFree86 ¤Ï¡¢X ¥µ¡¼¥Ð¡¼¤È¤Î´Ö¤ÇÁÐÊý¸þ¤Ë²¾ÁÛüËö (VT) ÀÚ¤êÂØ¤¨¡Ê¥µ¡¼¥Ð¡¼¤«¤é
+²¾ÁÛüËö¤Ø¡¢²¾ÁÛüËö¤«¤é¥µ¡¼¥Ð¡¼¤ØÀÚ¤êÂØ¤¨¤ë¡Ë¤ò¤¹¤ëµ¡Ç½¤¬¤¢¤ê¤Þ¤¹¡£½é¤á¤Æ
+µ¯Æ°¤¹¤ë¤È¤­¤Ï¡¢XFree86 ¤¬¡¢À褺²¾ÁÛüËö¡Ê»ÈÍѲÄǽ¤Ê¾¤Î¥×¥í¥»¥¹¤Ë³«¤«¤ì¤Æ
+¤¤¤Ê¤¤¤â¤Î¡Ë¤ò¼«Æ°Åª¤Ëõ¤·¤Æ¡¢¤½¤Î²¾ÁÛüËö¤Çµ¯Æ°¤·¤Þ¤¹¡£¤½¤Î²¾ÁÛüËö¤¬»ÈÍÑ
+ÉԲĤξì¹ç¡¢¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤ò½Ð¤·¤Æ XFree86 ¤Ï½ªÎ»¤¹¤ë¤Ç¤·¤ç¤¦¡£
+``vt&lt;nn&gt;'' ¤È¤¤¤¦¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¥µ¡¼¥Ð¡¼¤ò»ØÄꤹ¤ë²¾ÁÛü
+Ëö¤Ç¼Â¹Ô¤µ¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤³¤³¤Ç &lt;nn&gt; ¤Ï»ÈÍѲÄǽ¤Ê²¾ÁÛüËöÈÖ¹æ¡Ê1 ¤«¤é
+»Ï¤Þ¤ê¤Þ¤¹¡Ë¤Ç¤¹¡£¶õ¤¤¤Æ¤¤¤ë²¾ÁÛüËö¤¬¤Ê¤¤¤È¤­¤Ï¡¢XFree86 ¤Ïµ¯Æ°ÉÔǽ¤Ç¤¹¡£
+<tt>include/linux/tty.h</tt> ¤ÎÃæ¤Î <tt>NR_CONSOLES</tt> ¤Î¿ô¤òÁý¤ä¤·¤Æ¥«¡¼¥Í¥ë¤ò¥³¥ó¥Ñ¥¤¥ë
+¤¹¤ì¤Ð¡¢»ÈÍѲÄǽ¤Ê²¾ÁÛüËö¤Î¿ô¤òÁý¤ä¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£
+
+°ìö¡¢XFree86 ¤¬Æ°ºî¤·¤Æ¤·¤Þ¤¨¤Ð¡¢¥³¥ó¥È¥í¡¼¥ë¥­¡¼ &lt;Ctrl&gt; ¤È¥ª¥ë¥¿¥Í¥¤¥È¥­
+¡¼ &lt;Alt&gt; ¤È¥Õ¥¡¥ó¥¯¥·¥ç¥ó¥­¡¼ &lt;Fnn&gt; ¤òƱ»þ¤Ë²¡¤¹¤³¤È¤Ç¡¢Â¾¤Î²¾ÁÛüËö¤ËÀÚ¤ê
+ÂØ¤¨¤é¤ì¤Þ¤¹¡£¤³¤³¤Î nn ¤ÏÀÚ¤êÂØ¤¨¤¿¤¤²¾ÁÛüËöÈÖ¹æ¤Ç¤¹¡£XFree86 ¥µ¡¼¥Ð¡¼¤Ë
+Ì᤹¤È¤­¤Ï¡¢¥µ¡¼¥Ð¡¼¤¬É¸½à¤Ç»È¤Ã¤Æ¤¤¤ë²¾ÁÛüËöÈÖ¹æ¤òɽ¤ï¤¹Àµ¤·¤¤¥­¡¼¤ÎÁȤß
+¹ç¤ï¤»¤ò²¡¤·¤Þ¤·¤ç¤¦¡£Àµ¤·¤¤¥­¡¼¤ÎÁȤ߹ç¤ï¤»¤È¤Ï¡¢¥ª¥ë¥¿¥Í¥¤¥È¥­¡¼ &lt;Alt&gt;
+¤È¥Õ¥¡¥ó¥¯¥·¥ç¥ó¥­¡¼ &lt;Fmm&gt; ¤Ç¤¹¡£¤³¤³¤Ç¡¢mm ¤Ï¥µ¡¼¥Ð¡¼¤¬Æ°¤¤¤Æ¤¤¤ë²¾ÁÛüËö
+¤ÎÈÖ¹æ¤Ç¤¹¡£¡Ê¤³¤ÎÈÖ¹æ¤Ï¥µ¡¼¥Ð¡¼¤¬µ¯Æ°¤¹¤ë¤È¤­¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£¡Ë´û¤Ëµ¯Æ°¤·
+¤Æ¤¤¤ë¥µ¡¼¥Ð¡¼¤«¤éµ¯Æ°¤·¤¿²¾ÁÛüËö<em>¤Ç¤Ï¤Ê¤¤</em>¤³¤È¤ËÃí°Õ¤·¤Æ²¼¤µ¤¤¡£
+
+Ãí°Õ: <tt>kbd-0.81.tar.gz</tt> °Ê¹ß¤Î¥Ð¡¼¥¸¥ç¥ó¤ÎÃæ¤Ë¤¢¤ë `<tt>loadkeys</tt>' ¥³¥Þ¥ó¥É¤Ç¡¢¥Æ
+¥­¥¹¥È¥â¡¼¥É¤Î¥­¡¼³äÅö¤òºÆÄêµÁ¤Ç¤­¤Þ¤¹¡£¤³¤ì¤ò»È¤¨¤Ð¡¢Î㤨¤Ð¡¢¥³¥ó¥È¥í¡¼¥ë
+¥­¡¼ &lt;Ctrl&gt; ¤È¥ª¥ë¥¿¥Í¥¤¥È¥­¡¼ &lt;Alt&gt; ¤È¥Õ¥¡¥ó¥¯¥·¥ç¥ó¥­¡¼ &lt;Fmm&gt; ¤òƱ»þ¤Ë»È
+ÍѤ·¤Æ X ¥µ¡¼¥Ð¡¼²¼¤«¤é°Üư¤¹¤ë¤Î¤ÈƱ¤¸¤è¤¦¤Ê¥­¡¼Áàºî¤Ç¡¢²¾ÁÛüËö¤Î¥Æ¥­¥¹
+¥È¥â¡¼¥É¤«¤é¡¢°Üư¤¹¤ë»ö¤¬½ÐÍè¤Þ¤¹¡£
+
+¥µ¡¼¥Ð¡¼¤ò½ªÎ»¤µ¤»¤ë¤È¥µ¡¼¥Ð¡¼¤òµ¯Æ°¤·¤¿²¾ÁÛüËö¤ËÌá¤ê¤Þ¤¹¤¬¡¢¤â¤·¥µ¡¼¥Ð¡¼
+¤òµ¯Æ°¤·¤¿²¾ÁÛüËö¤¬»à¤ó¤Ç¤·¤Þ¤Ã¤¿¤È¤­¤Ï¡¢¼êư¤ÇÌᤵ¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£
+XFree86 ¤«¤é¥Æ¥­¥¹¥È¥â¡¼¥É¤ËÌá¤ë»þ¤Ë¡¢Ì¤¤À²èÌ̤βóÉü¤ËÌäÂ꤬¤¢¤ë¤Î¤Ï¡¢¥°¥é
+¥Õ¥£¥Ã¥¯¥«¡¼¥É¤È¥Þ¥¶¡¼¥Ü¡¼¥É¤ÎÁêÀ­¤¬°­¤¤¤Î¤À¤È»×¤ï¤ì¤Þ¤¹¡£¤³¤ó¤Ê»þ¤Ï¡¢
+<bf>svgalib</bf> ¤È¤¤¤¦ÇÛÉÕʪ¤ËÆþ¤Ã¤Æ¤¤¤ë <tt>runx</tt> ¤È¤¤¤¦¥¹¥¯¥ê¥×¥È¤ò¼Â¹Ô¤¹¤ì¤Ð¡¢²ò¾Ã¤Ç
+¤­¤ë¤Ç¤·¤ç¤¦¡£
+
+µ¯Æ°»þ¤Ë¡¢XFree86 ¥µ¡¼¥Ð¡¼¤Ï¥«¡¼¥Í¥ë¤ËÂФ·¤Æ¥­¡¼³ä¤êÉÕ¤±¤ò³ÍÆÀ¤¹¤ë¤³¤È¤òÍ×
+µá¤·¤Þ¤¹¡£¤³¤Î³ä¤êÉÕ¤±¤Ï¥«¡¼¥Í¥ë¤ò¥³¥ó¥Ñ¥¤¥ë¤·¤¿¤È¤­ÀßÄꤵ¤ì¤ë½é´üÃͤ«¤Þ¤¿
+¤Ï¡¢`<tt>loadkeys</tt>' ¥æ¡¼¥Æ¥£¥ê¥Æ¥£¤Ë¤è¤Ã¤Æ½ñ¤­Âؤ¨¤¿Ãͤˤʤê¤Þ¤¹¡£¥µ¡¼¥Ð¡¼¤Ç¤Ï¡¢
+¥«¡¼¥Í¥ë¤Ë°Í¸¤·¤¿¤â¤Î¡¢Ê£¿ô¤Î¥­¡¼ÁȤ߹ç¤ï¤»¤ä̵¸ú¤Ê¥­¡¼¤Ï³ä¤êÉÕ¤±½ÐÍè¤Þ¤»
+¤ó¡£¤½¤Î¾¤Î¥­¡¼¤Ï X ¶¦Ä̤ËÊÑ´¹¤µ¤ì¤Þ¤¹¡£X ¥µ¡¼¥Ð¡¼¤Ï¥·¥Õ¥È¤·¤Æ¤Ê¤¤¾õÂÖ¡¢
+¥·¥Õ¥È¾õÂÖ¡¢¥â¡¼¥É¥¹¥¤¥Ã¥Á¤ò²¡¤·¤Æ¤¤¤Ê¤¤¾õÂ֤ȡ¢¥â¡¼¥É¥¹¥¤¥Ã¥Á¤ò²¡¤·¤Æ¤¤¤ë
+¾õÂ֤Σ´¼ïÎष¤«ÊÑ´¹¥Æ¡¼¥Ö¥ë¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ²¼¤µ¤¤¡£¥â¡¼¥É¥¹¥¤
+¥Ã¥Á¤¬¤É¤ó¤Ê¥­¡¼¤«¤Ë¤è¤ê¤Þ¤¹¡Ê¤³¤ì¤Ï <tt>XF86Config</tt> ¤ÇÀßÄê²Äǽ¤Ç¤¹¡£½é´üÃͤϥª
+¥ë¥¿¥Í¥¤¥È¥­¡¼ &lt;Alt&gt; ¤Ç¤¹¡£¡Ë¤¬¡¢XFree86 ¤Ï¥­¡¼¥Þ¥Ã¥×¤ÎÃæ¤ËÊÑ´¹¥Æ¡¼¥Ö¥ë¤ò
+ÆÉ¤ß¹þ¤ß¤Þ¤¹¡£¤³¤Î»ö¤Ï¡¢Linux ¤Î¥â¡¼¥É¥¹¥¤¥Ã¥Á¤Ëº¸¥³¥ó¥È¥í¡¼¥ë¥­¡¼¤ÎÍÍ¤ÊÆÃ
+Äê¤Î¥­¡¼¤ò³ä¤êÅö¤Æ¤é¤ì¤Ê¤¤»ö¤ò°ÕÌ£¤·¤Þ¤¹¡£
+
+¹½À®¤Ë¤è¤Ã¤Æ¤Ï¡¢Ä´»Ò¤¬°­¤¯¤Ê¤Ã¤Æ½¤Àµ¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤³¤È¤¬¤¢¤ë¤Ç¤·¤ç¤¦¡£
+²áµî¤Ë¡¢Linux ¤Î xload ¥³¥Þ¥ó¥É¤¬¡¢Æ°ºîÃæ¤Î¥«¡¼¥Í¥ë¤«¤é¡¢Éé²ÙÊ¿¶Ñ¤ò¼è¤ê½Ð
+¤¹¤Î¤Ë BSD ¤ÎÊýË¡¤ò»È¤Ã¤¿»ö¤¬¤¢¤ê¤Þ¤¹¡£XFree86-1.3 ÈǤǤϡ¢¥«¡¼¥Í¥ë¤Î¾­Íè
+¤ÎÈǤǤθߴ¹À­¤ò¹Íθ¤·¤Æ¡¢Æ°ºîÃæ¤Î¥«¡¼¥Í¥ë¤«¤éÉé²ÙÊ¿¶Ñ¤ò¼è¤ê½Ð¤¹Âå¤ï¤ê¤Ë¡¢
+<tt>/proc/loadavg</tt> ¤«¤é¼è¤ê½Ð¤¹ÊýË¡¤ËÊѤ¨¤Þ¤·¤¿¡£Xman ¤â BSD ¤Î nroff ¥Õ¥¡¥ß¥ê
+¡¼¤ÎÂå¤ï¤ê¤Ë GNU groff ¥Õ¥¡¥ß¥ê¡¼¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤è¤¦¤ËÊѹ¹¤µ¤ì¤Þ¤·¤¿¡£¤Á¤ç
+¤Ã¤ÈÊÔ½¸¤·¤ÆºÆ¥³¥ó¥Ñ¥¤¥ë¤¹¤ì¤Ð½¾Íè¤Î BDS ¤Î nroff ¤ÎÊý¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤è¤¦¤Ë
+Ì᤻¤Þ¤¹¡£¥¯¥é¥¤¥¢¥ó¥È¤Ë¡¢²¾ÁÛüËö¤Çưºî¤·¤Æ¤¤¤¿¤Î¤ÈƱÅù¤Ê¤è¤êÎɤ¤¥³¥ó¥½¡¼
+¥ëÀÚ¤êÂØ¤¨¤òÄ󶡤¹¤ë¤¿¤á¤Ë¡¢ <tt>/dev/console</tt> ¤È <tt>/dev/tty0</tt> ¤Î½êÍ­¸¢¤È¶¦¤Ë¥µ¡¼
+¥Ð¡¼¤¬Êѹ¹¤µ¤ì¤Þ¤·¤¿¤¬¡¢¤½¤Î¤¿¤á¤Ë root ¤Î setuid °À­¤òÉÕ¤±¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê
+¤¯¤Ê¤ê¤Þ¤·¤¿¡£Æ±Íͤˡ¢<tt>xterm</tt> ¤È <tt>xconsole</tt> ¤Ë¤â root ¤Î setuid °À­¤òÉÕ¤±¤ëɬ
+Íפ¬¤¢¤ê¤Þ¤¹¡£<tt>xconsole</tt> ¤Ï root ¤Î setuid °À­¤òÉÕ¤±¤ÆÆ°ºî¤¹¤ë¤è¤¦¤Ë¤ÏÀß·×
+¤µ¤ì¤Æ¤Ê¤¤¤Î¤Ç¡¢¤³¤ì¤Ï°ÂÁ´¾å¡¢Â礭¤ÊÌäÂ꤬À¸¤¸¤ë¤È»×¤ï¤ì¤Þ¤¹¡£
+
+<!--<sect> Installing Xdm, the display manager-->
+<sect> ¥Ç¥£¥¹¥×¥ì¥¤¥Þ¥Í¡¼¥¸¥ã Xdm ¤ÎƳÆþ
+<p>
+
+<!--Since xdm is dynamically linked, there's no issue on
+export restriction outside US for this binary distribution of xdm: it
+does not contain the DES encryption code. So it's now included in the
+bin package.-->
+xdm ¤ÏưŪ¤Ë¥ê¥ó¥¯¤·¤Æ¤¤¤ë¤Î¤Ç¡¢xdm ¤Î¥Ð¥¤¥Ê¥êÇÛÉÛʪ¤Î¥¢¥á¥ê¥«¹ñ³°¤Ø¤Î
+Í¢½ÐÀ©¸Â¤ÏÌäÂê¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤³¤ì¤Ï DES °Å¹æ²½¥×¥í¥°¥é¥à¤ò´Þ¤ó¤Ç¤¤¤Ê¤¤
+»ö¤«¤é¤Ç¤¹¡£½¾¤Ã¤Æ¸½ºß¡¢¥Ð¥¤¥Ê¥ê¥Ñ¥Ã¥±¡¼¥¸¤Ë xdm ¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£
+
+<!--However the file <tt>xc/lib/Xdmcp/WrapHelp.c</tt> is not included in the
+XFree86-3.2 source, so support for
+XDM-AUTHORIZATION-1 is not included here. You'll have to get
+WrapHelp.c and rebuild xdm after having set <tt/HasXdmAuth/ in
+<tt/xf86site.def/.-->
+<tt>xc/lib/Xdmcp/WrapHelp.c</tt> ¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬ XFree86-3.2 ¤Î¥½¡¼¥¹¤Ë
+´Þ¤Þ¤ì¤Æ¤¤¤Ê¤¤¤Î¤Ç¡¢XDM-AUTHORIZATION-1 ¤Ï¥µ¥Ý¡¼¥È¤·¤Þ¤»¤ó¡£WrapHelp.c ¤ò
+Æþ¼ê¤·¤Æ <tt/xf86site.def/ ¤ÎÃæ¤Ë <tt/HasXdmAuth/ ¤òÀßÄꤷ¤¿¸å¤Ç xdm ¤ò
+ºÆ¹½ÃÛ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+
+<!--The file is available within the US; for
+details see <htmlurl name="ftp.x.org:/pub/R6/xdm-auth/README"
+url="ftp://ftp.x.org/pub/R6/xdm-auth/README">.-->
+WrapHelp.c ¤Ï¥¢¥á¥ê¥«¹ñÆâ¤Ë¤¢¤ê¤Þ¤¹¡£¾ÜºÙ¤Ï
+<htmlurl name="ftp.x.org:/pub/R6/xdm-auth/README"
+url="ftp://ftp.x.org/pub/R6/xdm-auth/README">
+¤ò¤´Í÷¤¯¤À¤µ¤¤¡£
+
+<!--To start the display manager, log in as root on the console and type:
+``<tt/xdm -nodaemon/''.-->
+¥Ç¥£¥¹¥×¥ì¥¤¥Þ¥Í¡¼¥¸¥ã¤òµ¯Æ°¤¹¤ëÁ°¤Ë¡¢¥ë¡¼¥È (root) ¤Ç¥í¥°¥¤¥ó¤·¤Æ
+¥³¥ó¥½¡¼¥ë¤«¤é ``<tt/xdm -nodaemon/'' ¤ÈÆþÎϤ·¤Æ²¼¤µ¤¤¡£
+
+<!--You can start xdm automatically on bootup by disabling the console getty
+and modifying <tt>/etc/inittab</tt>. Details about this setup depend on the
+Linux distribution that you use, so check the documentation provided there.-->
+console getty ¤ò̵¸ú¤Ë¤·¤Æ¡¢ <tt>/etc/inittab</tt> ¤òÊѹ¹¤¹¤ë¤³¤È¤Ë¤è¤ê
+¥Ö¡¼¥È»þ¤Ë¼«Æ°Åª¤Ë xdm ¤òµ¯Æ°½ÐÍè¤Þ¤¹¡£¾ÜºÙ¤Ï»È¤ª¤¦¤È¤¹¤ë Linux ÇÛÉÛʪ¤Î
+xdm ¤ÎÀßÄê¤Ë°Í¸¤·¤Þ¤¹¤Î¤Ç¤³¤³¤Ë¤¢¤ëʸ½ñ¤ò³Îǧ¤·¤Æ²¼¤µ¤¤¡£
+
+<!--The xdm binary provided should run with both shadow- and non-shadow password
+systems.-->
+xdm ¥Ð¥¤¥Ê¥êÇÛÉÛʪ¤Ï¥·¥ã¥É¥¦¥Ñ¥¹¥ï¡¼¥É¤ÈÉáÄ̤Υѥ¹¥ï¡¼¥É¤Î¥·¥¹¥Æ¥à¤ÎξÊý¤Ç
+ưºî¤¹¤ë¤Ç¤·¤ç¤¦¡£
+
+<sect>xterm
+<p>
+<!--The XFree86-3.2 binary release contains an xterm binary that has been linked
+statically against libtermcap. This was done to make sure that it will
+correctly work with all distributions, regardless whether they rely on
+libtermcap or libncurses. Contrary to the xterm binaries in some beta version
+following XFree86-3.1.2, this binary does not rely on a recent libncurses
+being installed on your system.-->
+XFree86-3.2 ¥Ð¥¤¥Ê¥êÇÛÉÛʪ¤Ï libtermcap ¤ÈÀÅŪ¤Ë¥ê¥ó¥¯¤·¤Æ¤¤¤ë xterm ¥Ð¥¤¥Ê¥ê
+ÇÛÉÛʪ¤ò´Þ¤ó¤Ç¤¤¤Þ¤¹¡£xterm ¤Ï libtermcap ¤È libncurses ¤Î¤É¤Á¤é¤Ë¤Ç¤â´ØÏ¢¤Î
+¤¢¤ë¥×¥í¥°¥é¥à¤ÎÁ´¤Æ¤ÎÇÛÉÛʪ¤ÇÀµ¤·¤¯Æ°ºî¤¹¤ë³Îǧ¤ò¤·¤Æ¤¤¤Þ¤¹¡£µÕ¤Ë XFree86-3.1.2
+¤ËÉÕ°¤¹¤ë¤¤¤¯¤Ä¤«¤Î¥Ù¡¼¥¿ÈǤΠxterm ¥Ð¥¤¥Ê¥êÇÛÉÛʪ¤ÏƳÆþ¤·¤¿ºÇ¿·¤Î libncurses
+¤È¤Ï´ØÏ¢¤¬¤¢¤ê¤Þ¤»¤ó¡£
+
+<!--<sect>Input devices-->
+<sect>ÆþÎϵ¡´ï
+<p>
+<!--XFree86 now support the dynamic loading of drivers for external
+input devices using the <tt/XInput/ extension. Currently supported
+devices are:
+<itemize>
+<item> Joystick (<tt/xf86Jstk.so/)
+<item> Wacom tablets (Wacom IV protocol only, <tt/xf86Wacom.so/)
+<item> SummaSketch tablets (<tt/xf86Summa.so/)
+<item> Elographics touchscreen (<tt/xf86Elo.so/)
+</itemize>-->
+º£²ó¡¢<tt/XInput/ µ¡Ç½³ÈÄ¥¤ò»È¤Ã¤¿³°ÉôÆþÎϵ¡´ï¥É¥é¥¤¥Ð¤Î¥À¥¤¥Ê¥ß¥Ã¥¯
+¥í¡¼¥Ç¥£¥ó¥°¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£¸½ºß¼¡¤Îµ¡´ï¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£
+<itemize>
+<item> ¥¸¥ç¥¤¥¹¥Æ¥£¥Ã¥¯ (<tt/xf86Jstk.so/)
+<item> Wacom ¥¿¥Ö¥ì¥Ã¥È (Wacom IV ¥×¥í¥È¥³¥ë¤Ë¸ÂÄê, <tt/xf86Wacom.so/)
+<item> SummaSketch ¥¿¥Ö¥ì¥Ã¥È (<tt/xf86Summa.so/)
+<item> Elographics ¥¿¥Ã¥Á¥¹¥¯¥ê¡¼¥ó (<tt/xf86Elo.so/)
+</itemize>
+
+<!--To use a specific device, add the line
+<tscreen>
+<tt/load/ <tt/"/<em/module/<tt/"/
+</tscreen>
+in the <bf/Module/ section of <tt/XF86Config/, where <em/module/ is
+the name of the <tt/.so/ file corresponding to your device.
+You also need to set up a <bf/XInput/ section in <tt/XF86Config/.
+Refer to the <em>XF86Config(5)</em> man page for detailed
+configuration instructions.-->
+ÆÃÄê¤Îµ¡´ï¤ò»ÈÍѤ¹¤ë¤Ë¤Ï¡¢¼¡¤Î¹Ô¤ò <tt/XF86Config/ ¤Î <bf/Module/
+¤ËÄɲ䷤Ƥ¯¤À¤µ¤¤¡£¤³¤³¤Ç <em/module/ ¤Ï µ¡´ï¤ËÂбþ¤¹¤ë<tt/.so/
+¥Õ¥¡¥¤¥ë¤Î̾¾Î¤Ç¤¹¡£
+<tscreen>
+<tt/load/ <tt/"/<em/module/<tt/"/
+</tscreen>
+¤Þ¤¿¡¢<tt/XF86Config/ ¤Î <bf/XInput/ ¤ÎÉôʬ¤òÀßÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ÀßÄê¼ê½ç¤Î¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï <em>XF86Config(5)</em> ¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë
+¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+<p>
+<!--You can then change the device used to drive the X pointer with the
+<em/xsetpointer(1)/ command.-->
+<em/xsetpointer(1)/ ¥³¥Þ¥ó¥É¤ò»È¤Ã¤Æ X ¤Î¥«¡¼¥½¥ë¤ò¶îư¤¹¤ë»ÈÍѤ·¤¿¤¤
+µ¡´ï¤ËÊѹ¹½ÐÍè¤Þ¤¹¡£
+<p>
+<!--For joystick support, you'll need to install the joystick device
+driver in the kernel. -->
+¥¸¥ç¥¤¥¹¥Æ¥£¥Ã¥¯¤ò»È¤¦¤Ë¤Ï¥«¡¼¥Í¥ë¤Ë¥¸¥ç¥¤¥¹¥Æ¥£¥Ã¥¯¤Î¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð
+¤òÁȤ߹þ¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+
+<!--<sect1>Configuring PEX and XIE extensions-->
+<sect1>PEX ¤È XIE µ¡Ç½³ÈÄ¥¤ÎÀßÄê
+<p>
+<!--The PEX and XIE extensions are now supported as external modules.
+If you want to have access to these extensions, add the following
+lines to the <bf/Module/ section of <tt/XF86Config/:
+<tscreen><verb>
+ load "pex5.so"
+ load "xie.so"
+</verb></tscreen>-->
+¸½ºß¡¢PEX ¤È XIE µ¡Ç½³ÈÄ¥¤Ï³°Éô¥â¥¸¥å¡¼¥ë¤È¤·¤Æ¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+¤³¤Îµ¡Ç½³ÈÄ¥¤ò»È¤¤¤¿¤¤¾ì¹ç¤Ï¡¢¼¡¤Î¹Ô¤ò <tt/XF86Config/ ¤Î <bf/Module/
+¤ËÄɲ䷤Ƥ¯¤À¤µ¤¤
+<tscreen><verb>
+ load "pex5.so"
+ load "xie.so"
+</verb></tscreen>
+
+<!--<sect> Compiling XFree86 <p>
+Only the sources for full releases of XFree86 are freely available. The
+last full release of XFree86 is 3.2.
+
+There are no special instructions required for compiling XFree86.
+This version was compiled with gcc-2.7.2, the 5.2.18 Elf libraries and the
+1.7.14 shared, dynamic linker ld.so. -->
+
+<sect> XFree86 ¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¤Ë¤Ï <p>
+XFree86 ¤Î´°Á´ÈǤΥ½¡¼¥¹¤À¤±¤Ï̵ÎÁ¤Ç¸ø³«¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ºÇ¿·¤Î XFree86 ¤Î
+´°Á´ÈÇ¤Ï 3.2 ¤Ç¤¹¡£
+
+XFree86 ¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¤¿¤á¤Ë¤ÏÆÃÊ̤ʼê½ç½ñ¤ÏɬÍפ¢¤ê¤Þ¤»¤ó¡£
+¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Î XFree86 ¤Ï gcc-2.7.2 ¡¢Elf ¥é¥¤¥Ö¥é¥ê¤Î 5.2.18 ¤È¶¦Íѥ饤
+¥Ö¥é¥ê¤Î1.7.14 ¡¢¥À¥¤¥Ê¥ß¥Ã¥¯¡¦¥ê¥ó¥« ld.so ¤È¤Ç¥³¥ó¥Ñ¥¤¥ë¤·¤Æ¤¤¤Þ¤¹¡£
+<!-- ¶¦Í­
+¥é¥¤¥Ö¥é¥ê¤Ï DLL tools-2.16 ¥Ñ¥Ã¥±¡¼¥¸¤ÇºîÀ®¤·¡¢¿·¤·¤¤¾ì½ê (<tt>/usr/bin</tt>) ¤Ë¤¢
+¤ë¥Ä¡¼¥ë¤ò»È¤¦¤è¤¦¤Ë¥µ¡¼¥Ð¡¼¤Î¥½¡¼¥¹¤ò¹¹¿·¤·¤Þ¤·¤¿¡£ -->
+¥µ¡¼¥Ð¡¼¤Ï 486 ¥×¥í¥»
+¥Ã¥µÍѤ˺ÇŬ²½¤¹¤ë°Ù¤Ë¡¢<tt>-m486</tt> ¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤Æ¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Æ¤¤¤Þ¤¹¤¬¡¢
+¥Ð¥¤¥Ê¥ê¤Ï 386 ¥×¥í¥»¥Ã¥µ¤Çưºî¤¹¤ë¤Ç¤·¤ç¤¦¡£¡Ê -m486 ¤òÉÕ¤±¤Æ¥³¥ó¥Ñ¥¤¥ë¤·
+¤¿¤â¤Î¤Ï¡¢<tt>-m386</tt> ¤òÉÕ¤±¤Æ¥³¥ó¥Ñ¥¤¥ë¤·¤¿¤â¤Î¤è¤ê¾¯¡¹¥Õ¥¡¥¤¥ë¥µ¥¤¥º¤¬Â礭¤¯¤Ê
+¤Ã¤Æ¤¤¤Þ¤¹¤¬¡¢À­Ç½¤Î»¼º¤Ï¤¢¤ê¤Þ¤»¤ó¡£¡Ë
+
+Á´¤Æ¤Îµ¡Ç½³ÈÄ¥¤È¥¯¥é¥¤¥¢¥ó¥È¤Ï°Ü¿¢¤È¥Æ¥¹¥È¤¬½ª¤ï¤Ã¤Æ¤¤¤Þ¤¹¡£É¸½à¤Ç¤Ï¡¢¥µ¡¼
+¥Ð¡¼¤Ï³°Éôµ¡Ç½³ÈÄ¥ (PEX, XIE Åù) ̵¤·¤Ç¥³¥ó¥Ñ¥¤¥ë¤·¤Æ¤¤¤Þ¤¹¤¬¡¢¤³¤ì¤é¤Î³°
+Éôµ¡Ç½³ÈÄ¥¤Î¥é¥¤¥Ö¥é¥ê¤Ï´û¤ËÀ¸À®ºÑ¤ß¤Ç¤¹¡£
+<!--They can be loaded
+at runtime, see the XFree86 man page for details. -->
+³°Éôµ¡Ç½³ÈÄ¥¤Ï¼Â¹Ô»þ¤Ë¥í¡¼¥Ç¥£¥ó¥°¤µ¤ì¤Þ¤¹¡£¾ÜºÙ¤Ï XFree86 ¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë
+¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+<tt>site.def</tt> ¤òÊѹ¹¤¹¤ì¤Ð¡¢³°Éôµ¡Ç½
+³ÈÄ¥¤ò¥³¥ó¥Ñ¥¤¥ë¤·¤Æ¥µ¡¼¥Ð¡¼¤ËÁȤ߹þ¤á¤Þ¤¹¡£¼ã¤·¤¯¤Ï¡¢¥ê¥ó¥¯¥­¥Ã¥È¤¬¥µ¡¼¥Ð
+¡¼¤òÊѹ¹¤Ç¤­¤Þ¤¹¡£
+
+ÇÛÉÕʪ¤ÏÂçÊÑÂ礭¤¤¤â¤Î¤Ç¤¹¤¬¡¢¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¡¢PEX ¤äÂ礭¤Ê¥¯¥é¥¤¥¢¥ó
+¥È¤ò¾Ãµî¤¹¤ëÅù¤·¤Æ¥½¡¼¥¹¤òÃí°Õ¿¼¤¯À°Íý¤¹¤ì¤Ð¡¢XFree86 ¤Ï 64MB ¤Î¥Ñ¡¼¥Æ¥£¥·
+¥ç¥ó£±¤Ä¤Ç¡¢¥³¥ó¥Ñ¥¤¥ë½ÐÍè¤Þ¤¹¡£ Makefile ¤òºîÀ®¤¹¤ë¤Ë¤Ï¡¢Ã±¤Ë ``<tt>make Makefiles</tt>'' ¤ò¼Â¹Ô¤·¤Æ¤¯¤À¤µ¤¤¡£¥Õ¥¡¥¤¥ë¤¬¼«Æ°Åª¤ËºîÀ®¤µ¤ì¡¢¼Â¹Ô¤Ï½ªÎ»¤·¤Þ
+¤¹¡£¥Ç¥£¥¹¥¯¤òÀáÌ󤹤ë¤Ê¤é¤Ð¡¢``<tt>make depend</tt>'' ¤Ï¼Â¹Ô¤¹¤ëɬÍפϤʤ¤¤Ç¤·¤ç¤¦¡£
+100MB ¤Î¶õ¤­¥Ç¥£¥¹¥¯¤¬¤¢¤ì¤Ð¡¢¤â¤Ã¤ÈÍÆ°×¤Ë XFree86 ¤ò¥³¥ó¥Ñ¥¤¥ë¤Ç¤­¤Þ¤¹¡£
+¥µ¡¼¥Ð¡¼Á´¤Æ¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¤Ë¤Ï¡¢Ìó 10MB ¤Î²¾ÁÛ¥á¥â¥ê¤¬É¬ÍפǤ·¤ç¤¦¡£
+
+XFree86 ¤Î aout ÈǤòÀ¸À®¤·¤¿¤ê
+¥Ñ¥Ã¥Á¤¬¥é¥¤¥Ö¥é¥ê¤Ë½ÅÍפÊÊѹ¹¤ò¹Ô¤Ê¤¦¾ì¹ç¤Ï¡¢¹¹¿·¤·¤¿ jump_xxx ¤¬É¬ÍפǤ·
+¤ç¤¦¡£DLL tools ¥Ñ¥Ã¥±¡¼¥¸¤ËÉÕ°¤¹¤ë¼ê½ç¤Ç¥Ñ¥Ã¥Á¤¬À¸À®¤Ç¤­¡¢XFree86 ¤Î¥Ñ¥Ã
+¥Á¤òÅö¤Æ¤ë¤Î¤ËɬÍפǤ·¤ç¤¦¡£
+
+Î㤨¤Ð¡¢Xaw3d ¤Î¤è¤¦¤Ê³°Éô X ¶¦Í­¥é¥¤¥Ö¥é¥ê¤â X ¥é¥¤¥Ö¥é¥ê¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ë
+¤è¤¦¤Ë¡¢ X ¥é¥¤¥Ö¥é¥ê¤òÄêµÁ¤¹¤ë JUMP_xxx ¤ÇÄêµÁ¤·¤Æ¥³¥ó¥Ñ¥¤¥ë½ÐÍè¤Þ¤¹¡£¾Ü
+ºÙ¤Ê¼ê½ç¤Ë¤Ä¤¤¤Æ¤Ï¡¢X ¥é¥¤¥Ö¥é¥ê¤ÎÄêµÁÎã¤ò¡¢
+<tt>/usr/X11R6/lib/X11/config/lnxLib.rules</tt> ¤ËÄ󶡤·¤Æ¤¤¤Þ¤¹¡£
+
+Orest Zborowski (<it>orestz@eskimo.com</it>) »á¤¬³«È¯¤·¤¿ºÇ¿·¤ÎÊýË¡¤Ç¡¢Á´¤Æ¤Î¾ÜºÙ
+ÀâÌÀ¥Õ¥¡¥¤¥ë¤ò½ñ¤­¡¢½é¤á¤Æ XFree86 DLL ¥é¥¤¥Ö¥é¥ê¤òºîÀ®¤·¤Æ¤¯¤ì¤¿ Dirk
+Hohndel (<it>hohndel@aib.com</it>) »á¤Ë´¶¼Õ¤·¤Þ¤¹¡£
+
+<sect> ¥Ð¥°¤Î¹ðÃΤˤĤ¤¤Æ <p>
+¥Ð¥°Êó¹ð¤Ï <it>XFree86@XFree86.org</it> ¤ËÁ÷¤ë¤« <it>comp.windows.x.i386unix</it> ¤Î¥Ë¥å¡¼¥¹
+¥°¥ë¡¼¥×¤ËÅê¹Æ¤·¤Æ²¼¤µ¤¤¡£
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/Linux.sgml,v 3.2 1997/01/26 04:34:20 dawes Exp $
+</verb>
+<hrule>
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ï xc/programs/Xserver/hw/xfree86/doc/sgml/Linux.sgml,v 3.9 1996/10/20 13:33:12 ¤ò¡¢²¬ËÜ °ì¹¬
+( Kazuyuki Okamoto <url url="mailto:ikko-@pacific.rim.or.jp"
+name="&lt;ikko-@pacific.rim.or.jp&gt;"> ) ¤¬ XFree86 3.2 ¤ò
+ÆüËܤǥ¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¿Í¸þ¤±¤ËÏÂÌõ¤·¤¿¤â¤Î¤Ç¤¹¡£¤³¤³¤¬¤ª¤«¤·¤¤¤È¤«¡¢
+¤³¤³¤Ï¤³¤¦¤·¤¿¤Û¤¦¤¬¤¤¤¤¤È¤¤¤Ã¤¿¤´°Õ¸«¤¬¤¢¤ê¤Þ¤·¤¿¤é¡¢ÅŻҥ᡼¥ë¤Ç
+¤ªÃΤ餻²¼¤µ¤¤¡£
+¸¶Ê¸¤ÎÃøºî¸¢¤Ï XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ÎÏÂÌõ¤ÎÃøºî¸¢¤Ï
+XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤È²¬ËÜ¡¡°ì¹¬¤Ë¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤ÎÏÂÌõ¤ÎÉÔ¶ñ¹ç¤Ï»ä¤Ë¡¢
+ÅŻҥ᡼¥ë¤ÇÁ÷¤Ã¤Æ²¼¤µ¤¤¡£
+<hrule>
+&lsqb;EOF&rsqb;
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/Mach64.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/Mach64.sgml
new file mode 100644
index 000000000..c33f6d7fa
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/Mach64.sgml
@@ -0,0 +1,599 @@
+<!doctype linuxdoc system>
+<article>
+
+<!-- Title information -->
+
+<!--
++<title>Mach64 X Server Release Notes
++<author>Kevin E. Martin (martin@cs.unc.edu)
++<date>23 October 1996
+-->
+<title>Mach64 X ¥µ¡¼¥Ð ¤Î¥ê¥ê¡¼¥¹¥Î¡¼¥È
+<author>Kevin E. Martin (martin@cs.unc.edu)
+<date>1996 ǯ 10 ·î 23 Æü
+<trans> ²¬ËÜ¡¡°ì¹¬ Kazuyuki Okamoto &lt;ikko-@pacific.rim.or.jp&gt;
+
+<!-- Table of contents -->
+<toc>
+
+<!-- Begin the document -->
+<!-- ....1.........2.........3.........4.........5.........6...... -->
+
+<sect> ¥µ¥Ý¡¼¥È¤·¤¿ ¥«¡¼¥É, RAMDAC ¤È ¥Ô¥¯¥»¥ëÅö¤ê¤Î¥Ó¥Ã¥È¿ô<p>
+Mach64 X ¥µ¡¼¥Ð¤Ï Á´¤Æ¤Î Mach64 ¤ò´ð¤Ë¤·¤¿¥«¡¼¥É¾å¤Ç 80MHz °Ê¾å¤Î
+¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ç 8bpp ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£ ËØ¤É¤Î¥«¡¼¥É¤Ç¤Ï¤â¤Ã¤È¹â¤¤¥É¥Ã
+¥È¥¯¥í¥Ã¥¯¤È¾¤Î¿¼¤µ¤¬»ÈÍѲÄǽ¤Ç¤¹¡Ê²¼¤Îɽ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡Ë¡£
+¥«¡¼¥É¾å¤Î RAMDAC ¤Ç²¿¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¤«Ê¬¤«¤ê¤Þ¤¹¡£
+<p>
+<verb>
+ RAMDAC ºÇÂç¥É¥Ã¥È¥¯¥í¥Ã¥¯ ¿¼¤µ ºÇÂç²òÁüÅÙ Í×µá¥Ó¥Ç¥ª¥á¥â¥ê
+-------- ------------------ ---- ---------- ----------------
+ATI68860 135MHz 8 1280x1024 2Mb
+ATI68860 135MHz 16 1280x1024 4Mb
+ATI68860 80MHz 32 1024x768 4Mb
+
+ATI68875 80MHz 32 1024x768 4Mb
+
+CH8398 135MHz 8 1280x1024 2Mb
+CH8398 80MHz 16 1024x768 2Mb
+CH8398 40MHz 32 800x600 2Mb
+
+STG1702 135MHz 8 1280x1024 2Mb
+STG1702 80MHz 16 1024x768 2Mb
+STG1702 50MHz 32 800x600 2Mb
+
+STG1703 135MHz 8 1280x1024 2Mb
+STG1703 80MHz 16 1024x768 2Mb
+STG1703 50MHz 32 800x600 2Mb
+
+AT&amp;T20C408 135MHz 8 1280x1024 2Mb
+AT&amp;T20C408 80MHz 16 1024x768 2Mb
+AT&amp;T20C408 40MHz 32 800x600 2Mb
+
+Internal 135MHz 8 1280x1024 2Mb
+Internal 80MHz 16 1024x768 2Mb
+Internal 40MHz 32 800x600 2Mb
+
+IBM RGB514 220MHz 8 1600x1200 2Mb
+IBM RGB514 220MHz 16 1600x1200 4Mb
+IBM RGB514 135MHz 32 1024x768 4Mb
+
+¤½¤Î¾[*] 80MHz 8 1280x1024 2Mb
+
+</verb>
+&lsqb*&rsqb - ¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ò 80MHz ¤ËÀ©¸Â¤·¡¢bpp ¤ò 8 ¤ËÀ©¸Â¤·¤Þ¤¹¡£
+<!--
+&dquot;<tt>-probeonly</tt>&dquot; ¤Î¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤Æ Mach64 X ¥µ¡¼
+¥Ð¡¼¤ò¼Â¹Ô¤·¤¿»þ¤Ë RAMDAC ¤òÄ´¤Ù¤Þ¤¹¡£
+
+°ìÈÌ¤Ë ATI Graphics Pro Turbo ¤È ATI WinTurbo ¥«¡¼¥É¤Ë¤Ï ATI68860 ¤È
+ATI68880 RAMDAC ¤¬ÅëºÜ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£°ìÈÌ¤Ë ATI Graphics Xpression ¥«¡¼
+¥É¤Ë¤Ï¾¤Î RAMDAC ¤¬ÅëºÜ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£
+
+-The RAMDAC is reported when you run the Mach64 X server with the
+-"<tt>-probeonly</tt>" command line option.
+-
+-The ATI68860 and ATI68880 RAMDACs are usually found on ATI Graphics
+-Pro Turbo and ATI WinTurbo cards. The other RAMDACs are usually found
+-on ATI Graphics Xpression cards.
++The table above specifies the maximum resolution and the video memory
++required to run this maximum resolution. Smaller resolutions will
++require less video memory.
+-->
+¾åµ­¤Îɽ¤ÏºÇÂç²òÁüÅ٤Ȥ½¤ÎºÇÂç²òÁüÅÙ¤ò»È¤¦¤Î¤ËɬÍפʥӥǥª¥á¥â¥ê¤ò
+¼¨¤·¤Æ¤¤¤Þ¤¹¡£¤è¤ê¾®¤µ¤¤²òÁüÅ٤ˤϤè¤ê¾¯¤Ê¤¤¥Ó¥Ç¥ª¥á¥â¥ê¤ÇÂç¾æÉ×
+¤Ç¤¹¡£
+
+<!--
++The RAMDAC is reported when you run the Mach64 X server with the
++"<tt>-probeonly</tt>" command line option. The RAMDAC reported should
++be correct for all Mach64 cards. It can also be specified in the
++XF86Config file, but this is not recommended unless the RAMDAC
++reported in the probeonly output is incorrect. Before specifying the
++RAMDAC in your XF86Config file visually verify which RAMDAC is on your
++Mach64 card. If the RAMDAC reported in the probeonly output is
++definitely different than what you see on the card, then check to see
++if you have a RAMDAC specified in your XF86Config file. If you do,
++comment this line out and re-run the Mach64 X server with the
++"<tt>-probeonly</tt>". If it still reports the incorrect RAMDAC,
++please send in a bug report to XFree86@XFree86.Org.
++
++The ATI68860 RAMDACs are usually found on ATI Graphics Pro Turbo and
++ATI WinTurbo cards. The IBM RGB514 RAMDAC is found on the ATI
++Graphics Pro Turbo 1600 card. The other RAMDACs are usually found on
++ATI Graphics Xpression, ATI Video Xpression and ATI 3d Xpression
++cards. Mach64 CT, ET, VT, GT (3D Rage) and 3D Rage II chips have an
++"Internal" RAMDAC (i.e., it is built into the Mach64 chip).
+-->
+"<tt>-probeonly</tt>" ¥³¥Þ¥ó¥É¹Ô¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤Æ Mach64 X ¥µ¡¼¥Ð¤ò
+¼Â¹Ô¤·¤¿¤È¤­ RAMDAC ¤¬²¿¤«¤òÄ´¤Ù¤Þ¤¹¡£Á´¤Æ¤Î Mach64 ¥«¡¼¥É¤Ç¤Ï RAMDAC
+¤ÏÀµ¤·¤¯Ä´¤Ù¤é¤ì¤Þ¤¹¡£Ä´¤Ù¤¿·ë²Ì¤ò XF86Config ¤Ë»ØÄꤷ¤Þ¤·¤ç¤¦¡£¤·¤«¤·¡¢
+probeonly ¤Î·ë²Ì¤¬Àµ¤·¤¯¤Ê¤¤¾ì¹ç¤Ï»ØÄꤷ¤Ê¤¤¤è¤¦¤Ë¡£
+XF86Config ¤Ë RAMDAC ¤ò»ØÄꤹ¤ëÁ°¤Ë Mach64 ¥«¡¼¥É¤òÌܤǸ«¤Æ¤Î¤É¤ó¤Ê
+RAMDAC ¤¬ÅëºÜ¤µ¤ì¤Æ¤¤¤ë¤«³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£probeonly ¤Î½ÐÎÏ·ë²Ì¤Î RAMDAC
+¤È¥Ü¡¼¥È¾å¤Î¥Á¥Ã¥×¤È¤Ï¤Ã¤­¤ê¤È°ã¤¦¾ì¹ç¡¢RAMDAC ¤Î¹Ô¤ò¥³¥á¥ó¥È¤Ë¤·¤Æ
+¤â¤¦°ìÅÙ "<tt>-probeonly</tt>" ¤òÉÕ¤±¤Æ Mach64 X ¥µ¡¼¥Ð¤ò¼Â¹Ô¤·¤Æ¤¯¤À¤µ
+¤¤¡£¤³¤ì¤Ç¤â¤Þ¤À´Ö°ã¤Ã¤Æ¤¤¤ë RAMDAC ¤òÊó¹ð¤¹¤ë¾ì¹ç¤Ï XFree86@XFree86.Org
+¤Ë¥Ð¥°¥ì¥Ý¡¼¥È¤òÁ÷¤Ã¤Æ¤¯¤À¤µ¤¤¡£
+
+°ìÈÌ¤Ë ATI Graphics Pro Turbo ¤È ATI WinTurbo ¥«¡¼¥É¤Ë¤Ï ATI68860 ¤È
+ATI68880 RAMDAC ¤¬ÅëºÜ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£IBM RGB514 RAMDAC ¤Ï ATI
+Graphics Pro Turbo 1600 ¥«¡¼¥É¤ËÅëºÜ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£
+°ìÈÌ¤Ë ATI Graphics Xpression, ATI Video Xpression ¤È ATI 3d Xpression
+¥«¡¼¥É¤Ë¤Ï¾¤Î RAMDAC ¤¬ÅëºÜ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£Mach64 CT, ET, VT, GT (3D Rage)
+¤È 3D Rage II ¥Á¥Ã¥×¤Ï "Æâ¢" RAMDAC (Î㤨¤Ð Mach64 ¥Á¥Ã¥×¤ËÁȤ߹þ¤ó¤Ç)
+¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£
+
+<!--
+-(packed pixel mode), but this is not currently supported in the Mach64
+-for various reasons. The main one is that there is no current support
+-for 24bpp modes in the X Consortium's servers. Adding this support
+-will require a great programming effort.
++(packed pixel mode), but this is not currently supported in the
++Mach64 X server. This will be added in a future release.
+-->
+Mach64 ¥°¥é¥Õ¥£¥Ã¥¯¥«¡¼¥É¤ÏÆÃÊ̤Ê(¥Ñ¥Ã¥¯¥É¥Ô¥¯¥»¥ë) 24bpp ¥â¡¼¥É ¤¬»ÈÍÑ
+²Äǽ¤ÈÀëÅÁ¤·¤Æ¤¤¤Þ¤¹¤¬¡¢¤³¤Î¥â¡¼¥É¤Ï¸½ºß¡¢Mach64 ¤Ç¤Ï¥µ
+¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó¡£¤³¤ì¤«¤é½Ð¤ë¥Ð¡¼¥¸¥ç¥ó¤Ç¥µ¥Ý¡¼¥È¤¹¤ë¤Ç¤·¤ç¤¦¡£
+
+<!--
+-12Mb of main memory will not work.
++12Mb of main memory will not work. If you have a PCI based Mach64
++card or a VLB based Mach64 card, then the Mach64 X server will work
++with any amount of main memory.
+-->
+Mach64 X ¥µ¡¼¥Ð¤¬Àµ³Î¤Ëµ¡Ç½¤¹¤ë¤Ë¤Ï¥Ó¥Ç¥ª¥á¥â¥ê¤Î·ä´Ö¤¬É¬ÍפǤ¹¡£¤³¤ì
+¤Ï ISA Mach64 ¥«¡¼¥É ¤È¥·¥¹¥Æ¥à¤Î¥á¥¤¥ó¥á¥â¥ê¤Ë 12M ¥Ð¥¤¥È°Ê¾å¤Î¥á¥â¥ê
+¤¬¤¢¤ë¤Èưºî¤·¤Ê¤¤¤³¤È¤ò¼¨¤·¤Þ¤¹¡£PCI ¤Î Mach64 ¥«¡¼¥É¤Þ¤¿¤Ï VLB ¤Î
+Mach64 ¥«¡¼¥É¤Î¾ì¹ç¤Ë¡¢ Mach64 X ¥µ¡¼¥Ð¤Ï¥á¥¤¥ó¥á¥â¥ê¤Î°ìÉô¤ò»È¤Ã¤Æ
+ưºî¤¹¤ë¤Ç¤·¤ç¤¦¡£
+
+<sect>Mach64 X ¥µ¡¼¥Ð¤Îɽ¼¨Â®Å٤κÇŬ²½<p>
+Mach64 X ¥µ¡¼¥Ð¤Îɽ¼¨Â®Å٤κÇŬ²½¤Î°Ù¤Ë¡¢¼¡¤ÎºÇ¹â¤Î²òÁüÅÙ¤ò»ÈÍѤ¹¤ë¤³
+¤È¤ò¤ª´«¤á¤·¤Þ¤¹¡£¥Õ¥©¥ó¥È¤È¥Ô¥¯¥¹¥Þ¥Ã¥×¥­¥ã¥Ã¥·¥å¤È¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½
+¥ë¤ò»È¤¦Í¾Íµ¤¬½ÐÍè¤Þ¤¹¡£
+
+<verb>
+ ºÇÂç²òÁüÅÙ ¿¼¤µ ¥Ó¥Ç¥ª¥á¥â¥ê
+-------------- --- ---------
+ 1280x1024 8 4Mb
+ 1280x1024 16 4Mb
+ 1024x767 32 4Mb
+
+ 1280x1024 8 2Mb
+ 1024x767 16 2Mb
+ 800x600[*] 32 2Mb
+
+ 1024x767 8 1Mb
+ 800x600[*] 16 1Mb
+</verb>
+
+<!--
+&lsqb;*&rsqb; - 2M ¥Ð¥¤¥È¤Î¥Ó¥Ç¥ª¥«¡¼¥É¤Ç¤Ï¡¢ 640x480 ¥â¡¼¥É¤Ë¤ª¤¤¤Æ
+ 1024x480 ¤Î²¾ÁÛ²òÁüÅÙ¤ò»È¤¦¤¿¤á¤Ë¤Ï¥Õ¥©¥ó¥È¤È¥Ô¥¯¥¹¥Þ¥Ã¥×¤Î
+ ¥­¥ã¥Ã¥·¥å¤¬Í£°ì¤ÎÊýË¡¤Ç¤¹¡£¥­¥ã¥Ã¥·¥å¤«¤éÆÀ¤é¤ì¤ëɽ¼¨Â®Å٤θú
+ ²Ì¤òÆÀ¤ë¤Ë¤ÏºÇÂç²èÌÌ¥µ¥¤¥º¤ò 800x600 ¤Ë¤¹¤ë¤³¤È¤ò¤ª´«¤á¤·¤Þ¤¹¡£
+-&lsqb;*&rsqb; - With a 2Mb video card, the only way to use the font and pixmap
+- cache is to have a virtual resolution of 1024x480 with a 640x480
+- mode. I suggest using 800x600 to maximize your screen size at
+- the cost of the speed gained from the caches.
++&lsqb;*&rsqb; - With a 2MB video card, the only way to use the font
++and pixmap caches is to have a virtual resolution of 1024x480 with a
++640x480 mode. I suggest using 800x600 to maximize your screen size at
++the cost of the speed gained from the caches. The same argument can
++be made for 1MB video cards running in 16bpp mode. Note that it is
++not possible to run in 32bpp mode with 1MB of video memory.
+-->
+&lsqb;*&rsqb; - 2M ¥Ð¥¤¥È¤Î¥Ó¥Ç¥ª¥«¡¼¥É¤Ç¤Ï¡¢ 640x480 ¥â¡¼¥É¤Ë¤ª¤¤¤Æ
+1024x480 ¤Î²¾ÁÛ²òÁüÅÙ¤ò»È¤¦¤¿¤á¤Ë¤Ï¥Õ¥©¥ó¥È¤È¥Ô¥¯¥¹¥Þ¥Ã¥×¤Î
+¥­¥ã¥Ã¥·¥å¤¬Í£°ì¤ÎÊýË¡¤Ç¤¹¡£¥­¥ã¥Ã¥·¥å¤«¤éÆÀ¤é¤ì¤ëɽ¼¨Â®Å٤θú
+²Ì¤òÆÀ¤ë¤Ë¤ÏºÇÂç²èÌÌ¥µ¥¤¥º¤ò 800x600 ¤Ë¤¹¤ë¤³¤È¤ò¤ª´«¤á¤·¤Þ¤¹¡£
+Ʊ¤¸Íý¶þ¤Ç 16bpp ¤Ç 1M ¥Ð¥¤¥È¤Î¥á¥â¥ê¤Î¥«¡¼¥É¤¬Æ°ºî¤¹¤ë¤Ç¤·¤ç¤¦¡£
+1M ¥Ð¥¤¥È¤Î¥Ó¥Ç¥ª¥á¥â¥ê¤Ç¤Ï 32bpp ¤Ç¤Îưºî¤Ï½ÐÍè¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ
+¤¯¤À¤µ¤¤¡£
+
+<!--
+¾åµ­¤ÎÀâÌÀ¤Îµ»½ÑŪ¤ÊÀâÌÀ¤Ï: Mach64 X ¥µ¡¼¥Ð¤Ï²èÌ̤ÎÉý¤¬ 1024 ¤Î»þ¤Ë¤Î
+¤ß¥Õ¥©¥ó¥È¤È¥Ô¥¯¥¹¥Þ¥Ã¥×¥­¥ã¥Ã¥·¥å¤¬Í­¸ú¤Ë¤Ê¤ë¤«¤é¤Ç¤¹¡£¤³¤ÎÀ©¸Â¤Ï¾­Íè
+¤Î X ¥µ¡¼¥Ð¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï̵¤¯¤Ê¤ë¤Ç¤·¤ç¤¦¡£¥Ó¥Ç¥ª¥«¡¼¥É¤ÎºÇÂçɽ¼¨À­
+ǽ¤ò°ú¤­½Ð¤¹¤Ë¤Ï¡¢(ºÇÄã 1024x256 ¤Î)¥­¥ã¥Ã¥·¥åÍѤÎÈóɽ¼¨Îΰè¤ò½¼Ê¬¤Ë³Î
+ÊݽÐÍè¤ë»ö¤ò³Îǧ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥ã¥Ã¥·¥å¤Ë¤Ä¤¤¤ÆÉÕ¤±²Ã¤¨¤ì¤Ð¡¢
+Mach64 ¤ÏºÇ½ªÅª¤Ë¥á¥â¥ê¤Î·ä´Ö 1024 ¥Ð¥¤¥È¤ò¥á¥â¥ê¥Þ¥Ã¥×¥É¥ì¥¸¥¹¥¿¤Ë³ä¤ê
+ÉÕ¤±¤Þ¤¹¡£¥Ó¥Ç¥ª¥á¥â¥ê¤«¤é¾¤ÎÀþ¤ò¼è¤ê½ü¤­¤Þ¤¹¡£¤³¤Î»þ¡¢ºÇÄã 1024x257
+¤Î¥Ó¥Ç¥ª¥á¥â¥êÎΰ褬ɬÍפˤʤê¤Þ¤¹¡£
+-of 1024. This restriction will be removed in a future version of the
+-X server. To obtain the best performance from your video card, you
+-need to make sure that there is enough room off-screen for the caches
+-(at least 1024x256). In addition to the cache, the Mach64 uses memory
+-mapped registers which are mapped to the last 1024 bytes of the memory
+-aperture. This takes away another line from video memory. Thus, you
+-need at least a video memory area of 1024x257.
++of 1024 or greater. This restriction will be removed in a future
++version of the X server. To obtain the best performance from your
++video card, you need to make sure that there is enough room off-screen
++for the caches (at least 1024x256). In addition to the cache, the
++Mach64 uses memory mapped registers which are mapped to the last 1024
++bytes of the memory aperture. This takes away another line from video
++memory. Thus, you need at least a video memory area of 1024x257.
+-->
+¾åµ­¤ÎÀâÌÀ¤Îµ»½ÑŪ¤ÊÀâÌÀ¤Ï: Mach64 X ¥µ¡¼¥Ð¤Ï²èÌ̤ÎÉý¤¬ 1024 °Ê¾å¤Î»þ
+¤Ë¤Î
+¤ß¥Õ¥©¥ó¥È¤È¥Ô¥¯¥¹¥Þ¥Ã¥×¥­¥ã¥Ã¥·¥å¤¬Í­¸ú¤Ë¤Ê¤ë¤«¤é¤Ç¤¹¡£¤³¤ÎÀ©¸Â¤Ï¾­Íè
+¤Î X ¥µ¡¼¥Ð¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï̵¤¯¤Ê¤ë¤Ç¤·¤ç¤¦¡£¥Ó¥Ç¥ª¥«¡¼¥É¤ÎºÇÂçɽ¼¨À­
+ǽ¤ò°ú¤­½Ð¤¹¤Ë¤Ï¡¢(ºÇÄã 1024x256 ¤Î)¥­¥ã¥Ã¥·¥åÍѤÎÈóɽ¼¨Îΰè¤ò½¼Ê¬¤Ë³Î
+ÊݽÐÍè¤ë»ö¤ò³Îǧ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥­¥ã¥Ã¥·¥å¤Ë¤Ä¤¤¤ÆÉÕ¤±²Ã¤¨¤ì¤Ð¡¢
+Mach64 ¤ÏºÇ¸å¤Î¥á¥â¥ê¤Î·ä´Ö 1024 ¥Ð¥¤¥È¤ò¥á¥â¥ê¥Þ¥Ã¥×¥É¥ì¥¸¥¹¥¿¤Ë³ä¤ê
+ÉÕ¤±¤Þ¤¹¡£¥Ó¥Ç¥ª¥á¥â¥ê¤«¤é¾¤ÎÀþ¤ò¼è¤ê½ü¤­¤Þ¤¹¡£¤³¤Î»þ¡¢ºÇÄã 1024x257
+¤Î¥Ó¥Ç¥ª¥á¥â¥êÎΰ褬ɬÍפˤʤê¤Þ¤¹¡£
+
+<sect>XF86Config ¥ª¥×¥·¥ç¥ó<p>
+Mach64 X ¥µ¡¼¥ÐÍÑ¤Ë &dquot;Device&dquot; Àá¤Ç¤¤¤¯¤Ä¤«¤Î¥ª¥×¥·¥ç¥ó¤ò¥µ
+<!--
+¥Ý¡¼¥È¤·¤Æ¤¤¤Æ¤¤¤Þ¤¹¡£Mach64 X ¥µ¡¼¥Ð¤Ï BIOS ¤«¤é¥¯¥í¥Ã¥¯¤òÆÉ¤ß½Ð¤·¤Þ
+¤¹¡£XF86Config Æâ¤Î &dquot;Clocks&dquot; ¹Ô¤Ï
+&dquot;no_bios_clocks&dquot; ¥ª¥×¥·¥ç¥ó¤¬Í¿¤¨¤é¤ì¤Ê¤¤¸Â¤êÄ̾ï̵»ë¤·¤Þ
+¤¹¡£
+-server. The Mach64 X server reads the Clocks from the BIOS. The
+-"Clocks" lines in the XF86Config file are normally ignored by the
+-Mach64 X server unless the "no_bios_clocks" option is given.
++server. By default, the Mach64 X server will determine the RAMDAC
++type from the BIOS. If you wish to override the default RAMDAC type
++(not recommended unless the BIOS incorrectly reports your RAMDAC
++type), you can specify the RAMDAC type in the XF86Config file with the
++"Ramdac" entry. The Mach64 X server will also program the clocks
++based on the clock chip read from the BIOS. If you wish to override
++the default clock chip type (not recommended unless the BIOS
++incorrectly reports your clock chip type), you may specify the clock
++chip in the XF86Config file with the "ClockChip" entry. If, however,
++you wish to use the preprogrammed clocks, you can turn off the clock
++programming with the "no_program_clocks" option. In this case, the
++Mach64 X server reads the Clocks from the BIOS. The "Clocks" lines in
++the XF86Config file are normally ignored by the Mach64 X server unless
++the "no_bios_clocks" option is given.
+-->
+¥Ý¡¼¥È¤·¤Æ¤¤¤Æ¤¤¤Þ¤¹¡£É¸½à¤Ç Mach64 X ¥µ¡¼¥Ð¤Ï BIOS ¤«¤é RAMDAC ¤Î
+·¿¤òǧ¼±¤·¤Þ¤¹¡£É¸½à¤Î RAMDAC ¤Î·¿¤ò¾å½ñ¤­¤·¤¿¤¤¾ì¹ç¤Ï¡¢(BIOS ¤¬´Ö°ã¤Ã
+¤¿ RAMDAC ¤ÎÊó¹ð¤ò¤·¤Ê¤¤¸Â¤ê¤ª´«¤á¤·¤Þ¤»¤ó¤¬) XF86Config ¥Õ¥¡¥¤¥ë¤Î
+"Ramdac" ¤Î¹àÌÜ¤Ë RAMDAC ¤Î·¿¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£Mach64 X
+¥µ¡¼¥Ð¤¬Æ±ÍÍ¤Ë BIOS ¤«¤é¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤Î¥¯¥í¥Ã¥¯¤òÆÉ¤ß½Ð¤¹¤È¤­¤ÎÌäÂê
+¤¬¤¢¤ë¤Ç¤·¤ç¤¦¡£É¸½à¤Î¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤Î·¿¤ò¾å½ñ¤­¤·¤¿¤¤¾ì¹ç¤Ï¡¢(BIOS
+¤¬´Ö°ã¤Ã¤¿¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤ÎÊó¹ð¤ò¤·¤Ê¤¤¸Â¤ê¤ª´«¤á¤·¤Þ¤»¤ó¤¬) XF86Config
+¥Õ¥¡¥¤¥ë¤Î "ClockChip" ¤Î¹àÌܤ˥¯¥í¥Ã¥¯¥Á¥Ã¥×¤Î·¿¤ò»ØÄꤹ¤ë¤³¤È¤¬¤Ç¤­
+¤Þ¤¹¡£»öÁ°¤ËÁȤ߹þ¤Þ¤ì¤¿¥¯¥í¥Ã¥¯¤ò»È¤¤¤¿¤¤¾ì¹ç¤Ï "no_program_clocks"
+¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤Æ¥¯¥í¥Ã¥¯ÁȤ߹þ¤ß¤ò»ß¤á¤Æ¤¯¤À¤µ¤¤¡£¤³¤Î¾ì¹ç¡¢
+Mach64 X ¥µ¡¼¥Ð¤Ï BIOS ¤«¤é¥¯¥í¥Ã¥¯¤òÆÉ¤ß¹þ¤ß¤Þ¤¹¡£Ä̾XF86Config
+¥Õ¥¡¥¤¥ë¤Î "Clocks" ¹Ô¤Ï "no_bios_clocks" ¥ª¥×¥·¥ç¥ó¤¬Í¿¤¨¤é¤ì¤Ê¤¤
+¸Â¤ê̵»ë¤·¤Þ¤¹¡£
+
+<descrip>
+<tag>&dquot;sw_cursor&dquot; ¥ª¥×¥·¥ç¥ó</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½¥ë¤Î¤«¤ï¤ê¤Ë¥½¥Õ¥È
+ ¥¦¥§¥¢¥«¡¼¥½¥ë¤ò»ÈÍѲÄǽ¤Ë¤·¤Þ¤¹¡£
+<!--
+<tag>Option &dquot;hw_cursor&dquot;</tag>
+ This option turns on the hardware cursor. This
+ should not be necessary since the hardware cursor
+ is used by default unless the "sw_cursor" option is
+ specified.
+-->
+<tag>&dquot;hw_cursor&dquot; ¥ª¥×¥·¥ç¥ó</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½¥ë¤ò»ÈÍѲÄǽ¤Ë¤·¤Þ
+ ¤¹¡£"sw_cursor" ¥ª¥×¥·¥ç¥ó¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¤ò½ü¤¤¤Æ
+ ¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½¥ë¤òɸ½à¤Ç»È¤¦»þ¤ÏɬÍפ¢¤ê¤Þ¤»¤ó¡£
+<tag>&dquot;composite&dquot; ¥ª¥×¥·¥ç¥ó</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥³¥ó¥Ý¥¸¥Ã¥ÈƱ´üÂбþ¤Î¥â¥Ë¥¿¡¼¤ÎÀßÄê¤ò
+ ¹Ô¤¤¤Þ¤¹¡£
+<tag>&dquot;dac_8_bit&dquot; ¥ª¥×¥·¥ç¥ó</tag>
+<!--
+- This option enables 8 bits per RGB value. Note
+- this option does not work with the Chrontel 8398
+- RAMDAC.
++ This option enables 8 bits per RGB value. Note that
++ this does not work with the Chrontel 8398 RAMDAC.
++ This options is not necessary since 8 bits per RGB
++ value is the default for the Mach64 X server for all
++ Mach64 cards except those with the Chrontel 8398
++ RAMDAC.
++<tag>Option &dquot;dac_6_bit&dquot;</tag>
++ This option enables 6 bits per RGB value.
+-->
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï RGB Åö¤ê 8 ¥Ó¥Ã¥È¤ÎÃͤò²Äǽ¤Ë¤·¤Þ¤¹¡£
+ Chrontel 8398 RAMDAC ¤Ç¤Ï¤³¤Î¥ª¥×¥·¥ç¥ó¤Ïưºî¤·¤Ê¤¤
+ ¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£
+ Chrontel 8398 RAMDAC ¤ò½ü¤¯ Mach64 X ¥µ¡¼¥Ð¤Îɸ½àÃÍ
+ ¤Ï RGB Åö¤ê 8 ¥Ó¥Ã¥È¤Ê¤Î¤Ç¤³¤Î¥ª¥×¥·¥ç¥ó¤ÏɬÍפ¢¤ê¤Þ¤»
+ ¤ó¡£
+<tag>&dquot;dac_6_bit&dquot; ¥ª¥×¥·¥ç¥ó</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï RGB Åö¤ê 6 ¥Ó¥Ã¥È¤ÎÃͤò²Äǽ¤Ë¤·¤Þ¤¹¡£
+<tag>&dquot;override_bios&dquot; ¥ª¥×¥·¥ç¥ó</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥Ó¥Ç¥ª¥Ü¡¼¥É¤Î BIOS ¤Ç¤ÏÉÔÀµ¤È¹Í¤¨¤é¤ì
+ ¤Æ¤¤¤ëÆÃÊ̤ʥӥǥª¥â¡¼¥É¤ò²Äǽ¤Ë¤·¤Þ¤¹¡£¤¤¤¯¤Ä¤«¤Î BIOS
+ ¤¬´Ö°ã¤Ã¤¿ºÇÂç²òÁüÅÙ¤«¤Ä¡¿¤Þ¤¿¤Ï¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Î¾å¸Â¤ò
+<!--
+- this option with care. It is possible to specify
+- a video mode that can damage your card.
+-<tag>Option &dquot;no_block_write&dquot;</tag>
+- This option allows you to turn off block
+- write mode. Block write mode only works on
+- certain types of VRAM cards, and this option has
+- no effect on DRAM based cards. If you see noise
+- on the screen that can be captured via xmag, then
+- it is probably a problem with block write mode.
+- This ``noise'' usually looks like bits of windows/menus
++ this option with extreme care. It is possible to
++ specify a video mode that can damage your card or
++ monitor.
++<tag>Option &dquot;no_block_write&dquot;</tag>
++ This option allows you to turn off block write mode.
++ Block write mode only works on certain types of VRAM
++ cards. This option has no effect on DRAM based cards.
++ If you see noise on the screen that can be captured
++ via xmag, then it is probably a problem with block
++ write mode being turned on when it should not. This
++ ``noise'' usually looks like bits of windows/menus
+-->
+ ¤â¤Ã¤Æ¤¤¤Þ¤¹¡£Èó¾ï¤ËÃí°Õ¤·¤Æ¤³¤Î¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ
+ ¤¤¡£ÆÃÊ̤ʥӥǥª¥â¡¼¥É¤Ï¥«¡¼¥É¤ä¥â¥Ë¥¿¡¼¤òÄˤá¤ë²ÄǽÀ­¤¬¤¢
+ ¤ê¤Þ¤¹¡£
+<tag>&dquot;no_block_write&dquot; ¥ª¥×¥·¥ç¥ó</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥Ö¥í¥Ã¥¯½ñ¤­¹þ¤ß¥â¡¼¥É¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£
+ ¥Ö¥í¥Ã¥¯½ñ¤­¹þ¤ß¥â¡¼¥É¤ÏŬÀÚ¤Ê VRAM ¤Î¥«¡¼¥É¤Ç¤Î¤ßưºî
+ ¤·¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï DRAM ¤ò´ð¤Ë¤·¤¿¥«¡¼¥É¤Çưºî¤·¤Þ
+ ¤¹¡£xmag ¤ÇÀÚ¤ê¼è¤Ã¤¿²èÌ̤˥Υ¤¥º¤¬É½¼¨¤µ¤ì¤¿¤é¡¢¥Ö¥í¥Ã
+ ¥¯½ñ¤­¹þ¤ß¥â¡¼¥É¤ÎÌäÂ꤬¹Í¤¨¤é¤ì¤Þ¤¹¡£¤³¤Î &dquot;¥Î¥¤¥º&dquot;
+ ¤Ï°ìÈ̤˥¦¥¤¥ó¥É¥¦¤ä¥á¥Ë¥å¡¼¤ò·«¤êÊÖ¤·²èÌ̤Ëɽ¼¨¤·¤¿¤È
+ ¤­Åù¤Ë¸«¤é¤ì¤Þ¤¹¡£
+<tag>&dquot;block_write&dquot; ¥ª¥×¥·¥ç¥ó</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¾ï¤Ë¥Ö¥í¥Ã¥¯½ñ¤­¹þ¤ß¥â¡¼¥É¤òÍ­¸ú¤Ë¤·¤Þ
+ ¤¹¡£¥Ö¥í¥Ã¥¯½ñ¤­¹þ¤ß¥â¡¼¥É¤ÏŬÀÚ¤Ê VRAM ¤Î¥«¡¼¥É¤Ç¤Î¤ß
+ ưºî¤·¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï DRAM ¤ò´ð¤Ë¤·¤¿¥«¡¼¥É¤Çưºî¤·
+ ¤Þ¤¹¡£Ãµºº¤·¤¿½é´üÃͤò¾å½ñ¤­¤·¤¿¤¤¾ì¹ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç
+ ¥ó¤ò»È¤¦¤³¤È¤¬½ÐÍè¤Þ¤¹¡£
+<!--
++ Note that this may result in ``noise'' appearing on
++ the screen.
+-->
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï²èÌÌ¤Ë &dquot;¥Î¥¤¥º&dquot; ¤òɽ¼¨¤¹¤ë
+ ¤«¤â¤·¤ì¤Þ¤»¤ó¡£
+<tag>&dquot;power_saver&dquot; ¥ª¥×¥·¥ç¥ó</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥¹¥¯¥ê¡¼¥ó¥»¡¼¥Ð¡¼¤¬Í­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤ë»þ
+ ²èÌ̤ò°Å¤¯¤¹¤ëÂå¤ï¤ê¤ËŬÀÚ¤Ë &dquot;green&dquot; ¥â¥Ë
+ ¥¿¡¼¤Î¾ÊÅÅÎϵ¡Ç½¤ò¥µ¡¼¥Ð¤Ë»ÈÍѲÄǽ¤Ë¤·¤Þ¤¹¡£¤³¤Î¥ª¥×
+ ¥·¥ç¥ó¤Ï̤¤À¼Â¸³Ãæ¤Ç¤¹¡£
+ [ÌõÃí: &dquot;green&dquot; ¥â¥Ë¥¿¡¼¤È¤Ï´Ä¶­¤ËÍ¥¤·¤¤¥â¥Ë
+ ¥¿¡¼¤Ç¤·¤ç¤¦:-)]
+<!--
++<tag>Option &dquot;no_program_clocks&dquot;</tag>
++ This option allows you to disable the clock
++ programming. Normally the Mach64 server will program
++ the clocks based on the clock chip type unless this
++ option is given. With this option, the clocks are
++ either read from the BIOS or, if the "no_bios_clocks"
++ option is set, set from the Clocks line.
+-->
+<tag>&dquot;no_program_clocks&dquot; ¥ª¥×¥·¥ç¥ó</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¾ï»þ¥¯¥í¥Ã¥¯¥×¥í¥°¥é¥ß¥ó¥°¤ò̵¸ú¤Ë¤·¤Þ
+ ¤¹¡£Ä̾ï Mach64 ¥µ¡¼¥Ð¤Ï¤³¤Î¥ª¥×¥·¥ç¥ó¤¬Í¿¤¨¤é¤ì¤Ê¤¤¾ì¹ç
+ ¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤Î¥¯¥í¥Ã¥¯¤«¤é¤Î¥¯¥í¥Ã¥¯¤Ç¥×¥í¥°¥é¥à¤¹¤ë
+ Êý¼°¤ò¤È¤Ã¤Æ¤¤¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤ë¤È¥¯¥í¥Ã¥¯¤ò
+ BIOS ¤«¤éÆÉ¤ß½Ð¤·¡¢ "no_bios_clocks" ¤òÀßÄꤹ¤ë¤È
+ ¥¯¥í¥Ã¥¯¹Ô¤«¤éÀßÄꤹ¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
+<tag>&dquot;no_bios_clocks&dquot; ¥ª¥×¥·¥ç¥ó</tag>
+<!--
+- from the video card's BIOS. Normally the Mach64
+- server will ignore the Clocks line, but with this
+- option the clocks from the XF86Config file can
+- override the BIOS's clocks.
++ from the video card's BIOS and use the clocks
++ specified in the Clocks line in your XF86Config file.
++ Normally the Mach64 server will ignore both the BIOS
++ clocks and the clocks specified in the Clocks line
++ unless the "no_program_clocks" options is set (see
++ above).
++<tag>Option &dquot;no_font_cache&dquot;</tag>
++ This option allows you to disable the font cache. By
++ default the font cache is turned on if the horizontal
++ resolution is 1024 pixels or greater and there is
++ enough off-screen video memory to hold the cache.
++<tag>Option &dquot;no_pixmap_cache&dquot;</tag>
++ This option allows you to disable the pixmap cache.
++ By default the pixmap cache is turned on if the
++ horizontal resolution is 1024 pixels or greater and
++ there is enough off-screen video memory to hold the
++ cache.
+-->
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥Ó¥Ç¥ª¥«¡¼¥É¤Î BIOS ¤«¤éÆÉ¤ß½Ð¤·¤¿¥¯
+ ¥í¥Ã¥¯¤È XF86Config ¥Õ¥¡¥¤¥ë¤Î Clocks ¹Ô¤Î¾å½ñ¤­¤ò
+ Í­¸ú¤Ë¤·¤Þ¤¹¡£"no_program_clocks" ¥ª¥×¥·¥ç¥ó¤ò
+ ÀßÄꤹ¤ë¾ì¹ç¤ò½ü¤¤¤ÆÄ̾ï Mach64 ¥µ¡¼¥Ð¤Ï BIOS ¤Î¥¯¥í¥Ã¥¯
+ ¤È Clocks ¹Ô¤ò̵»ë¤·¤Þ¤¹(¾åµ­»²¾È)¡£
+<tag>&dquot;no_font_cache&dquot; ¥ª¥×¥·¥ç¥ó</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¾ï»þ¥Õ¥©¥ó¥È¥­¥ã¥Ã¥·¥å¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£
+ ɸ½à¤Ç¤Ï¿åÊ¿²òÁüÅÙ¤¬ 1024 ¥Ô¥¯¥»¥ë¤«¤½¤ì°Ê¾å¤Î¾ì¹ç¤È
+ ¥­¥ã¥Ã¥·¥å¤Ë»È¤¦É½¼¨¤µ¤ì¤Ê¤¤¥Ó¥Ç¥ª¥á¥â¥ê¤¬½½Ê¬¤Ë¤¢¤ë
+ ¾ì¹ç¤ËÍ­¸ú¤Ç¤¹¡£
+<tag>&dquot;no_pixmap_cache&dquot; ¥ª¥×¥·¥ç¥ó</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¾ï»þ¥Ô¥¯¥¹¥Þ¥Ã¥×¥­¥ã¥Ã¥·¥å¤ò̵¸ú¤Ë¤·¤Þ
+ ¤¹¡£É¸½à¤Ç¤Ï¤Ï¿åÊ¿²òÁüÅÙ¤¬ 1024 ¥Ô¥¯¥»¥ë¤«¤½¤ì°Ê¾å¤Î¾ì¹ç¤È
+ ¥­¥ã¥Ã¥·¥å¤Ë»È¤¦É½¼¨¤µ¤ì¤Ê¤¤¥Ó¥Ç¥ª¥á¥â¥ê¤¬½½Ê¬¤Ë¤¢¤ë
+ ¾ì¹ç¤ËÍ­¸ú¤Ç¤¹¡£
+<tag>MemBase ´ðÄ쥢¥É¥ì¥¹</tag>
+<!--
+ ¤³¤ÎÀßÄê¤Ï¥á¥â¥ê¤Î·ä´Ö¤Î¥¢¥É¥ì¥¹¤Î»ØÄê¤Ç¤¹¡£Ä̾·ä´Ö
+ ¤Î¥¢¥É¥ì¥¹¤Ï¼«Æ°Åª¤Ëǧ¼±¤µ¤ì¤Þ¤¹¤¬¡¢VESA ¥í¡¼¥«¥ë¥Ð¥¹¤Î
+ ¥·¥¹¥Æ¥à¤Ç¤Ï¥¢¥É¥ì¥¹¤ÎÁªÂò¤Ï¤¦¤Þ¤¯¤¤¤­¤Þ¤»¤ó¡£Mach64 X
+ ¤¬¥»¥°¥á¥ó¥ÈÎã³°¤Ç»ß¤Þ¤ë¾ì¹ç¤Ï¡¢·ä´Ö¤Î¥¢¥É¥ì¥¹¤ò¾¤Î¾ì
+ ½ê¤ËÂ夨¤Æ¤ß¤Þ¤·¤ç¤¦¡£
+- address. Normally the aperture address is
+- automatically determined, but on some VESA Local
+- Bus systems the address chosen will not work. If
+- the Mach64 X server is dying with a seg. fault,
+- then try setting the aperture address to another
+- location.
++ address. By default the aperture address is
++ automatically determined and this option should
++ not be necessary. If the Mach64 X server is dying
++ with a seg. fault, then the memory aperture might
++ not be correctly determined. To fix this try setting
++ the aperture address to another location.
+-->
+ ¤³¤ÎÀßÄê¤Ï¥á¥â¥ê¤Î·ä´Ö¤Î¥¢¥É¥ì¥¹¤Î»ØÄê¤Ç¤¹¡£É¸½à¤Ç¡¢·ä´Ö
+ ¤Î¥¢¥É¥ì¥¹¤Ï¼«Æ°Åª¤Ëǧ¼±¤µ¤ì¤ë¤Î¤ÇɬÍפ¢¤ê¤Þ¤»¤ó¤¬¡£
+ Mach64 X ¥µ¡¼¥Ð
+ ¤¬¥»¥°¥á¥ó¥ÈÎã³°¤Ç»ß¤Þ¤ë¾ì¹ç¤Ï¡¢·ä´Ö¤Î¥¢¥É¥ì¥¹¤¬Àµ¤·¤¯
+ ǧ¼±½ÐÍè¤Æ¤¤¤Þ¤»¤ó¡£¤³¤ÎÌäÂê¤ò²ò·è¤¹¤ë¤Ë¤Ï·ä´Ö¤Î¥¢¥É¥ì¥¹
+ ¤ò¾¤Î¾ì½ê¤ËÂ夨¤Æ¤ß¤Þ¤·¤ç¤¦¡£
+<!--
++<tag>ClockChip &dquot;<it>type</it>&dquot;</tag>
++ This entry specifies the clock chip type. The
++ following values are valid for <it>type</it>:
++ <itemize>
++ <item> ati18818
++ <item> att20c408
++ <item> ch8398
++ <item> ibm_rgb514
++ <item> ics2595
++ <item> stg1703
++ </itemize>
+-->
+<tag>ClockChip ¤Î &dquot;<it>·¿</it>&dquot;</tag>
+ ¤³¤Î¹àÌܤǤϥ¯¥í¥Ã¥¯¥Á¥Ã¥×¤Î·¿¤ò»ØÄꤷ¤Þ¤¹¡£
+ ¼¡¤Î²Á¤Ï <it>·¿</it>¤ËÍ­¸ú¤Ê¤â¤Î¤Ç¤¹ :
+ <itemize>
+ <item> ati18818
+ <item> att20c408
+ <item> ch8398
+ <item> ibm_rgb514
+ <item> ics2595
+ <item> stg1703
+ </itemize>
+<!--
++<tag>Ramdac &dquot;<it>type</it>&dquot;</tag>
++ This entry specifies the RAMDAC type. The following
++ values are valid for <it>type</it>:
++ <itemize>
++ <item> ati68860
++ <item> ati68860b
++ <item> ati68860c
++ <item> ati68875
++ <item> att20c408
++ <item> ch8398
++ <item> ibm_rgb514
++ <item> internal
++ <item> stg1702
++ <item> stg1703
++ <item> tlc34075
++ </itemize>
+-->
+<tag>Ramdac ¤Î &dquot;<it>·¿</it>&dquot;</tag>
+ ¤³¤Î¹àÌÜ¤Ï Ramdac ¤Î·¿¤ò»ØÄꤷ¤Þ¤¹¡£
+ ¼¡¤Î²Á¤Ï <it>·¿</it>¤ËÍ­¸ú¤Ê¤â¤Î¤Ç¤¹ :
+ <itemize>
+ <item> ati68860
+ <item> ati68860b
+ <item> ati68860c
+ <item> ati68875
+ <item> att20c408
+ <item> ch8398
+ <item> ibm_rgb514
+ <item> internal
+ <item> stg1702
+ <item> stg1703
+ <item> tlc34075
+ </itemize>
+</descrip>
+
+<!--
+<sect>Known Problems and Bug Reports<p>
+There are several known problems with the current version of the
+Mach64 X server. They include:
+<itemize>
+<item> Screen blanking in 16bpp and 32bpp modes on certain Mach64 CT
+ cards does not work.
+<item> In doublescan modes, only the top half of the hardware cursor
+ is displayed. The hardware cursor works fine in all other
+ modes.
+<item> 3D Rage II based Mach64 cards are not initialized properly.
+<item> Some RAMDACs are incorrectly reported by the BIOS. This can be
+ handled by explicitly specifying the RAMDAC in the XF86Config
+ file. This should no longer be a problem.
+<item> ISA cards with more than 12Mb of main memory cannot use the
+ server due to the requirement of a video memory aperture. This
+ a major project.
+</itemize>
+-->
+
+<sect>´ûÃΤÎÌäÂê¤È¥Ð¥°Êó¹ð<p>
+¸½ºß¤Î Mach64 X ¥µ¡¼¥Ð¤Ç¤Ï¤¤¤¯¤Ä¤«¤Î´ûÃΤÎÌäÂ꤬¤¢¤ê¤Þ¤¹¡£¤½¤ì¤Ï:
+<itemize>
+<item> °ìÄê¤Î Mach64 CT ¥«¡¼¥É¤Ç 16bpp ¤È 32bpp ¥â¡¼¥É¤Ç¤Î²èÌ̤ν֤­
+ ¤Ïľ¤Ã¤Æ¤¤¤Þ¤»¤ó¡£
+<item> Æó½Å¥¹¥­¥ã¥ó¥â¡¼¥É¤Ç¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½¥ë¤Î¾åȾʬ¤·¤«É½¼¨¤·¤Þ
+ ¤»¤ó¡£Â¾¤ÎÁ´¤Æ¤Î¥â¡¼¥É¤Ç¤Ï¤¦¤Þ¤¯Æ°ºî¤·¤Þ¤¹¡£
+<item> 3D Rage II ¤ò´ð¤Ë¤·¤¿ Mach64 ¥«¡¼¥É¤ÏÀµ¤·¤¯½é´ü²½½ÐÍè¤Þ¤»¤ó¡£
+<item> ¤¤¤¯¤Ä¤«¤Î RAMDAC ¤Ï BIOS ¤Ç¤Ï´Ö°ã¤Ã¤ÆÊó¹ð¤·¤Æ¤·¤Þ¤¤¤Þ¤¹¡£
+ XF86Config ¥Õ¥¡¥¤¥ë¤Ç RAMDAC ¤òÌÀ¼¨Åª¤Ë»ØÄꤷ¤Æ¤ä¤ì¤Ð¼è¤ê
+ °·¤¨¤Þ¤¹¡£¤³¤¦¤¹¤ì¤ÐÌäÂê¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+<item> 12M ¥Ð¥¤¥È°Ê¾å¤Î¥á¥¤¥ó¥á¥â¥ê¤òÅëºÜ¤·¤¿ ISA ¥«¡¼¥É¤Ï¥Ó¥Ç¥ª¥á¥â¥ê
+ ¤Î·ä´Ö¤¬¤È¤ì¤Ê¤¤¤Î¤Ç¥µ¡¼¥Ð¤¬Æ°ºî¤·¤Þ¤»¤ó¡£¤³¤ì¤ÏÂç»Å»ö¤Ç¤¹¡£
+</itemize>
+
+<!--
+If you are experiencing problems, first check to make sure that you
+have the very latest available release (including beta releases). ATI
+releases new cards throughout the year. Each of these new cards
+require additional programming to support the new Mach64 chips,
+RAMDACs and clock chips that appear on them. The most recent release
+is most likely to support your video card.
+
+Second, please check the RELNOTES and README files (as well as the
+other documentation available with the release). Third, make sure you
+do not have any Ramdac, ClockChip or Clocks lines in your XF86Config
+file (all of these are automatically detected by the Mach64 X server).
+
+If you are still experiencing problems, please send e-mail to
+XFree86@XFree86.org or post to the comp.windows.x.i386unix newsgroup.
+
+Please do NOT send e-mail to me since the developers who answer e-mail
+sent to XFree86@XFree86.org are better able to answer most questions
+and I would like to spend my minimal free time working on new
+enhancements to the X server. Thanks!
+-->
+ÌäÂê¤Ë½Ð²ñ¤Ã¤¿¤é¡¢¤Þ¤ººÇ½é¤Ë(¥Ù¡¼¥¿ÈǤâ´Þ¤ó¤Ç)ÍøÍѲÄǽ¤ÊºÇ¿·ÈǤò»È¤Ã¤Æ
+¤¤¤ë¤«³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£Ç¯´Ö¤òÄ̤¸¤Æ ATI ¤Ï¿·¤·¤¤¥«¡¼¥É¤òȯɽ¤·¤Æ¤¤¤Þ
+¤¹¡£¿·¤·¤¤¥«¡¼¥É¤¬ÅëºÜ¤·¤Æ¤¤¤ë¿·¤·¤¤ Mach64 ¥Á¥Ã¥×¡¢RAMDAC ¤ä¥¯¥í¥Ã¥¯
+¥Á¥Ã¥×¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤¿¤á¤Ë¡¢¤³¤Î¤½¤ì¤¾¤ì¤Î¿·¤·¤¤¥«¡¼¥É¤Ë¤Ï¥×¥í¥°¥é¥à
+¤ÎÄɲä¬É¬ÍפÀ¤«¤é¤Ç¤¹¡£
+
+£²ÈÖÌܤˡ¢RELNOTES ¤È README ¥Õ¥¡¥¤¥ë¤ò(¤½¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¼ê¤Ë¤Ï¤¤¤ë¾¤Î
+ʸ½ñ¤â)¤òÄ´¤Ù¤Æ¤¯¤À¤µ¤¤¡££³ÈÖÌÜ¤Ë XF86Config ¥Õ¥¡¥¤¥ë¤Ë Ramdac,
+ClockChip ¤Þ¤¿¤Ï Clocks ¹Ô¤¬¤Ê¤¤¤³¤È¤ò³Îǧ¤·¤Þ¤·¤ç¤¦¡£¤³¤ì¤é¤Ï
+Mach64 ¥µ¡¼¥Ð¤¬¼«Æ°Åª¤ËõÃΤ·¤Þ¤¹¡£
+
+¤Þ¤ÀÌäÂ꤬¤¢¤ë¾ì¹ç¤Ï¡¢XFree86@XFree86.org ¤Þ¤ÇÅŻҥ᡼¥ë¤òÁ÷¤ë¤«
+comp.windows.x.i386unix ¤È¤¤¤¦¥Ë¥å¡¼¥¹¥°¥ë¡¼¥×¤ËÅê¹Æ¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+XFree86@XFree86.org ¤ËÅŻҥ᡼¥ë¤òÁ÷¤Ã¤ÆËؤɤÎÌäÂê¤Î²óÅú¤ò³«È¯¼Ô¤¬Åú
+¤¨¤ëÊý¤¬Îɤ¤¤Î¤È¡¢»ä(Ãø¼Ô)¤¬¤ï¤º¤«¤Ê¼«Í³»þ´Ö¤ò X ¥µ¡¼¥Ð¤Ë¿·¤·¤¤µ¡Ç½
+³ÈÄ¥¤Îºî¶È¤Ë»È¤¤¤¿¤¤¤Î¤Ç¡¢»ä(Ãø¼Ô)¤ËÅŻҥ᡼¥ë¤òÁ÷¤é¤Ê¤¤¤Ç¤¯¤À¤µ
+¤¤¡£¤É¤¦¤â¤¢¤ê¤¬¤È¤¦¡£
+
+<p>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/Mach64.sgml,v 3.2 1997/01/26 04:34:21 dawes Exp $
+</verb>
+<hrule>
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ï xc/programs/Xserver/hw/xfree86/doc/sgml/Mach64.sgml,v 3.12 1996/10/24 12:30:19 ¤ò¡¢²¬ËÜ °ì¹¬
+( Kazuyuki Okamoto <url url="mailto:ikko-@pacific.rim.or.jp"
+name="&lt;ikko-@pacific.rim.or.jp&gt;"> ) ¤¬ XFree86 3.2 ¤ò
+ÆüËܤǥ¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¿Í¸þ¤±¤ËÏÂÌõ¤·¤¿¤â¤Î¤Ç¤¹¡£¤³¤³¤¬¤ª¤«¤·¤¤¤È¤«¡¢
+¤³¤³¤Ï¤³¤¦¤·¤¿¤Û¤¦¤¬¤¤¤¤¤È¤¤¤Ã¤¿¤´°Õ¸«¤¬¤¢¤ê¤Þ¤·¤¿¤é¡¢ÅŻҥ᡼¥ë¤Ç
+¤ªÃΤ餻²¼¤µ¤¤¡£
+¸¶Ê¸¤ÎÃøºî¸¢¤Ï XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ÎÏÂÌõ¤ÎÃøºî¸¢¤Ï
+XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤È²¬ËÜ¡¡°ì¹¬¤Ë¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤ÎÏÂÌõ¤ÎÉÔ¶ñ¹ç¤Ï»ä
+¤Ë¡¢ÅŻҥ᡼¥ë¤ÇÁ÷¤Ã¤Æ²¼¤µ¤¤¡£
+<hrule>
+&lsqb;EOF&rsqb;
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/QStart.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/QStart.sgml
new file mode 100644
index 000000000..d7ba5ecf4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/QStart.sgml
@@ -0,0 +1,1351 @@
+<!doctype linuxdoc system>
+
+<article>
+
+<!--
+ <title> Quick-Start Guide to XFree86 Setup
+-->
+ <title> XFree86 ¤ÎÀßÄê¤ò¼êÁ᤯¤¹¤ë°Ù¤Î¼ê°ú¤­
+
+ <author> Joe Moss
+
+<!--
+ <date> 26 August 1996
+-->
+ 1996 ǯ 8 ·î 26 Æü
+ <trans> ²¬ËÜ °ì¹¬ Kazuyuki Okamoto (ikko-@pacific.rim.or.jp)
+
+<abstract>
+<!--
+ Current releases of XFree86 include several tools that can help
+to automate the process of server configuration. Much of the existing
+documentation, however, describes how to do the job manually, including
+many technical details.
+
+ For those users with esoteric hardware or with the desire to
+get their hands dirty under the hood, this is great, but many users are
+using common hardware and just want to get X up and running quickly.
+This guide is for them.
+-->
+ºÇ¿·¤Î XFree86 ¤Ï¥µ¡¼¥Ð¤ÎÀßÄê¤Î¼ê½ç¤ò¼«Æ°²½¤¹¤ë¤Î¤ËÌò¤ËΩ¤Ä
+¥Ä¡¼¥ë¤ò´ö¤Ä¤â´Þ¤ó¤Ç¤¤¤Þ¤¹¡£¤·¤«¤·¡¢´û¸¤Îʸ½ñ¤Î¤Û¤È¤ó¤É¤ÏÀßÄêºî¶È¤ò¼ê¤Ç¤¹¤ëÏäò
+°·¤Ã¤Æ¤ª¤ê¡¢¤·¤«¤â¡¢µ»½ÑŪ¤ÊºÙ¤«¤¤Ïä¬ÂçÎ̤˽ñ¤¤¤Æ¤¢¤Ã¤¿¤ê¤·¤Þ¤¹¡£
+
+¤³¤ì¤é¤Ï¥Þ¥Ë¥¢¸þ¤±¤Îµ¡´ï¤ä¼«Ê¬¤Î¼ê¤Ç²¿¤È¤«¤·¤¿¤¤¤È»×¤Ã¤Æ¤¤¤ë¥æ¡¼¥¶¤Ë¤ÏÁÇŨ¤Ê
+¾ðÊó¤Ç¤¹¡£¤·¤«¤·¡¢°ìÈÌŪ¤Êµ¡´ï¤ò»ÈÍѤ·¤Æ¤ëËØ¤É¤Î¥æ¡¼¥¶¤Ï¤È¤Ë¤«¤¯ X ¤ò¤¹¤°¤Ë
+ư¤«¤·¤Æ¤ß¤¿¤¤¤Ç¤·¤ç¤¦¡£¤³¤Î¼ê°ú¤­¤Ï¤½¤ó¤Ê¥æ¡¼¥¶¤Î°Ù¤Î¾ðÊó¤Ç¤¹¡£
+</abstract>
+
+<toc>
+
+<!--
+<sect> Before You Start
+-->
+<sect> ¤Ï¤¸¤á¤ëÁ°¤Ë
+<p>
+<!--
+ There are a few bits of information that you will need to have
+ before you can setup the server:
+ <descrip>
+ <tag> The model name of your video card </tag>
+ Make sure you know the exact model name of the card. It
+ may help to also know the graphics chipset, RAMDAC, and
+ clock chip used on your card.
+ <tag> The amount of memory on your video card </tag>
+ Find out how many megabytes of RAM are on your video card.
+ <tag> Whether or not your card is VGA compatible </tag>
+ Most cards these days are VGA compatible, but for example,
+ if you have and older monochrome card, it might not be.
+ <tag> Your monitor's specifications </tag>
+ Specifically, you need to know the horizontal sync rate(s),
+ and vertical refresh rate(s). These are <bf>important</bf>!
+ Consult your monitor's manual.
+ <tag> The protocol used by your mouse </tag>
+ It will help speed up the process, if you know which protocol
+ is used by your mouse to communicate. Some mice are capable
+ of using two different protocols, although the method of
+ switching between them varies.
+ </descrip>
+-->
+ ¥µ¡¼¥Ð¤ÎÀßÄê¤ò¹Ô¤¦Á°¤ËÃΤäƤª¤¯É¬ÍפΤ¢¤ë¹àÌܤ¬¾¯¤·¤¢¤ê¤Þ¤¹¡£
+ <descrip>
+ <tag> ¥Ó¥Ç¥ª¥«¡¼¥É¤Î¥â¥Ç¥ë̾¾Î</tag>
+ ¥Ó¥Ç¥ª¥«¡¼¥É¤ÎÀµ³Î¤Ê¥â¥Ç¥ë̾¾Î¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£¤Þ¤¿¡¢
+ ¥Ó¥Ç¥ª¥«¡¼¥É¤ËÅëºÜ¤µ¤ì¤Æ¤¤¤ë¥°¥é¥Õ¥£¥Ã¥¯¥Á¥Ã¥×¥»¥Ã¥È,
+ RAMDAC ¤È ¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤òÃΤäƤª¤¯¤È½õ¤«¤ê¤Þ¤¹¡£
+ <tag> ¥Ó¥Ç¥ª¥«¡¼¥É¤ËÅëºÜ¤·¤Æ¤¤¤ë¥á¥â¥ê¤ÎÎÌ </tag>
+ ¥Ó¥Ç¥ª¥«¡¼¥É¤ËÅëºÜ¤·¤Æ¤¤¤ë¥á¥â¥ê¤¬²¿ MB ¥Ð¥¤¥È¤¢¤ë¤«Ä´¤Ù¤Æ
+ ¤¯¤À¤µ¤¤¡£
+ <tag> ¥Ó¥Ç¥ª¥«¡¼¥É¤¬ VGA ¸ß´¹¤Ç¤¢¤ë¤«¤É¤¦¤« </tag>
+ ºÇ¶á¤ÎËØ¤É¤Î¥Ó¥Ç¥ª¥«¡¼¥É¤Ï VGA ¸ß´¹¤Ç¤¹¤¬¡¢Î㤨¤ÐÀΤÎÇò¹õ¤Î
+ ¥Ó¥Ç¥ª¥«¡¼¥É¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï VGA ¸ß´¹¤Ç¤Ï¤Ê¤¤»þ¤¬¤¢¤ê¤Þ¤¹¡£
+ <tag> ¥â¥Ë¥¿¤Î»ÅÍÍ </tag>
+ ÆÃ¤Ë¿åʿƱ´ü¼þÇÈ¿ô (Ê£¿ô) ¤È¿âľ¥ê¥Õ¥ì¥Ã¥·¥å¥ì¡¼¥È (Ê£¿ô) ¤Ï
+ ÃΤäƤª¤¯É¬Íפ¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤é¤Ï<bf>½ÅÍ×</bf>¤Ç¤¹¡ª
+ ¥â¥Ë¥¿¤Î¥Þ¥Ë¥å¥¢¥ë¤òÄ´¤Ù¤Æ¤¯¤À¤µ¤¤¡£
+ <tag> ¥Þ¥¦¥¹¤Î»ÈÍѤ·¤Æ¤¤¤ë¥×¥í¥È¥³¥ë</tag>
+ ¥Þ¥¦¥¹¤ÈÀܳ¤¹¤ë¤Î¤Ë»ÈÍѤ·¤Æ¤¤¤ë¥×¥í¥È¥³¥ë¤òÃΤäƤª¤¯¤È¡¢
+ ÀßÄêºî¶È¤Î®ÅÙ¸þ¾å¤ËÌò¤ËΩ¤Á¤Þ¤¹¡£¤¤¤¯¤Ä¤«¤Î¥Þ¥¦¥¹¤Ï°Û¤Ê¤ë
+ £²¤Ä¤Î¥×¥í¥È¥³¥ë¤ò»ÈÍѤ·¤Æ¤¤¤Þ¤¹¤«¤é¡¢ÀÚ¤êÂØ¤¨Êý¤ÏÍÍ¡¹¤Ç¤¹¡£
+ </descrip>
+<!--
+<sect> What to Do - An Overview
+-->
+<sect> ²¿¤ò¹Ô¤¦¤Î¤« - ³µÍ×
+<p>
+<!--
+ There are three tools that can be used to set up XFree86:
+ <itemize>
+ <item>XF86Setup
+ <item>xf86config
+ <item>xvidtune
+ </itemize>
+-->
+ XFree86 ¤ÎÀßÄê¤ËÍ­ÍѤʣ³¤Ä¤Î¥Ä¡¼¥ë¤¬¤¢¤ê¤Þ¤¹¡£:
+ <itemize>
+ <item>XF86Setup
+ <item>xf86config
+ <item>xvidtune
+ </itemize>
+<p>
+<!--
+ XF86Setup primarily uses a graphical user interface and
+ is the preferred tool for initial setup, but there
+ are a few cases where it can't be used. If you are using a
+ card that is not VGA compatible, have a fixed-frequency
+ monitor, or are running OS/2, you'll not be able to use
+ XF86Setup, read about xf86config instead.
+ If you have limited RAM or a slow system, you might be better
+ off using xf86config as well.
+-->
+ XF86Setup ¤Ï¼ç¤Ë¥°¥é¥Õ¥£¥Ã¥¯¥æ¡¼¥¶¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤ò»È¤Ã¤Æ¤¤¤Æ¡¢
+ ½é´üÀßÄê¤ËÎɤ¯»ÈÍѤ·¤Æ¤¤¤Þ¤¹¤¬¡¢»È¤¨¤Ê¤¤¤¤¤¯¤Ä¤«¤Î¾ì¹ç¤¬¤¢¤ê
+ ¤Þ¤¹¡£¥Ó¥Ç¥ª¥«¡¼¥É¤¬ VGA ¸ß´¹¤Ç¤Ï¤Ê¤¤¾ì¹ç¡¢¸ÇÄê¼þÇÈ¿ô¤Î¥â¥Ë¥¿¤Î
+ ¾ì¹ç¡¢¤Þ¤¿¤Ï OS/2 ¤¬¼Â¹ÔÃæ¤Î¾ì¹ç¤Ï XF86Setup ¤Ï»È¤¨¤Þ¤»¤ó¤Î¤Ç¡¢
+ Âå¤ï¤ê¤Ë xf86config ¤Ë¤Ä¤¤¤ÆÆÉ¤ó¤Ç¤¯¤À¤µ¤¤¡£
+ ¥á¥â¥ê¤¬¾¯¤Ê¤¤Ëô¤ÏÃÙ¤¤¥·¥¹¥Æ¥à¤ò»È¤¦¾ì¹ç¤â¡¢Æ±ÍÍ¤Ë xf86config
+ ¤ò»ÈÍѤ·¤¿¤Û¤¦¤¬Îɤ¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£
+<p>
+<!--
+ The xf86config program is text based only, but works for almost
+ any hardware combination. If you have a fixed frequency
+ monitor that won't work with standard text modes, you
+ will have to read the necessary documentation and
+ do the configuration manually.
+-->
+ xf86config ¤Ï¥Æ¥­¥¹¥È¥Ù¡¼¥¹¤Ç¤¹¤¬¡¢ËؤɤΥϡ¼¥É¥¦¥§¥¢¤ÎÁȤ߹ç¤ï¤»
+ ¤Çưºî¤·¤Þ¤¹¡£ÉáÄ̤Υƥ­¥¹¥È¥â¡¼¥É¤¬Æ°ºî¤·¤Ê¤¤¤è¤¦¤Ê¸ÇÄê¼þÇÈ¿ô¤Î
+ ¥â¥Ë¥¿¡¼¤Ç¤Ï¾ì¹ç¡¢É¬ÍפÊʸ½ñ¤òÆÉ¤ó¤Ç¼«¤é¤Î¼ê¤ÇÀßÄꤷ¤Ê¤±¤ì¤Ð¤¤¤±
+ ¤Þ¤»¤ó¡£
+<p>
+<!--
+ To get things looking just right, you may need to use
+ <tt>xvidtune</tt>, a program that allows you to make adjustments
+ to the displayed image (e.g. make it wider, move it a little
+ to the left, etc.). XF86Setup will allow you to run xvidtune
+ at the appropriate time; if you use xf86config, you can use
+ xvidtune afterwards.
+-->
+ ¤Á¤ç¤¦¤ÉÎɤ¤²èÁü¤ò¸«¤Ä¤±¤ë¤Ë¤Ï¡¢É½¼¨¤µ¤ì¤¿²èÁü¤ò (Î㤨¤Ð¡¢²èÁü¤ò
+ ¹­¤²¤¿¤ê¡¢¾¯¤·º¸¤Ë°Üư¤·¤¿¤êÅù¡¹) Ä´À°¤¹¤ë <tt>xvidtune</tt>
+ ¤ò»ÈÍѤ¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£XF86Setup ¤ÏŬÀڤʻþ¤Ë xvidtune ¤ò¼Â¹Ô
+ ¤·¤Þ¤¹¡£xf86config ¤ò¼Â¹Ô¤¹¤ë¾ì¹ç¤Ï¡¢¸å¤Ç xvidtune ¤ò»ÈÍѤ·¤Þ¤¹¡£
+<p>
+<!--
+ All of these are explained in detail in the following
+ sections. If you're the type that doesn't like to read
+ the documentation, but would rather just try and figure
+ your way through things, you can just type <tt/XF86Setup/
+ now.
+ If you have problems, the documentation will still be here.
+-->
+ ¤³¤Î¼ê½ç¤Ï¼¡¾Ï°Ê¹ß¤Ç¾ÜºÙ¤ËÀâÌÀ¤·¤Þ¤¹¡£Ê¸½ñ¤òÆÉ¤ß¤¿¤¯¤Ê¤¤Êý¤Ë¤Ï¡¢
+ ¿§¡¹»î¤·¤Æ¤ß¤Æ¼«Ê¬¤Î¹Ô¤¯Æ»¤òºî¤Ã¤Æ²¼¤µ¤¤¡£¤µ¤¢ <tt/XF86Setup/
+ ¤È¤À¤±ÂǤÁ¹þ¤ó¤Ç¤¯¤À¤µ¤¤¡£
+ ÌäÂ꤬À¸¤¸¤¿¤é¡¢¤³¤³¤Ë¤¢¤ëʸ½ñ¤òÆÉ¤ß¤Þ¤·¤ç¤¦¡£
+<p>
+<!--
+ Although it is possible to use XF86Setup from within X to
+ make changes to your existing configuration, such use is
+ not specifically documented here. These instructions are
+ primarily for those initially setting up XFree86 on their
+ system.
+-->
+ X ÆâÉô¤«¤é XF86Setup ¤ò¼Â¹Ô¤·¡¤¸½ºßÍøÍѤ·¤Æ¤¤¤ëÀßÄê¤òÊѹ¹¤¹¤ë¤³¤È¤â
+ ¤Ç¤­¤Þ¤¹¤¬¡¢¤³¤³¤Ç¤Ï¤½¤Î¤è¤¦¤Ê»ÈÍÑË¡¤Ë¤Ä¤¤¤Æ¤ÏÆÃ¤ËÀâÌÀ¤·¤Þ¤»¤ó¡£
+ ¤³¤³¤ÇÀâÌÀ¤·¤Æ¤¤¤ëÁàºî¼ê½ç¤Ï¡¢¼ç¤ËXFree86 ¤ò°ì¤«¤éÀßÄꤹ¤ë¾ì¹ç¤Ë
+ ¤Ä¤¤¤Æ½Ò¤Ù¤Æ¤¤¤Þ¤¹¡£
+
+<!--
+<sect> Using <tt>XF86Setup</tt>
+-->
+<sect> <tt>XF86Setup</tt> ¤Î»ÈÍÑË¡
+<p>
+<!--
+ XF86Setup will first check around to make sure certain files
+ are installed and that you are running as root. If a problem
+ is found, it will display a message and exit. Correct the
+ problem (e.g. install the missing files) and run it again.
+-->
+ XF86Setup ¤ÏºÇ½é¤ËƳÆþ¤µ¤ì¤Æ¤¤¤ë°ìÄê¤Î¥Õ¥¡¥¤¥ë¤ò³Îǧ¤·¤Þ¤¹¤Î¤Ç
+ ¥ë¡¼¥È¤Ë¤Ê¤Ã¤Æ¼Â¹Ô¤·¤Þ¤·¤ç¤¦¡£ÌäÂ꤬ȯÀ¸¤·¤¿¤é¡¢¥á¥Ã¥»¡¼¥¸¤ò
+ ɽ¼¨¤·¤Æ½ªÎ»¤·¤Þ¤¹¡£ÌäÂê¤ò½¤Àµ (Î㤨¤Ð¡¢Ìµ¤¤¥Õ¥¡¥¤¥ë¤òƳÆþ
+ ¤¹¤ëÅù) ¤·¤Æ¤â¤¦°ìÅټ¹Ԥ·¤Þ¤·¤ç¤¦¡£
+
+<!--
+<sect1> Initial questions
+-->
+<sect1> ºÇ½é¤Îµ¿Ìä
+<p>
+<!--
+ If you have an existing XF86Config file, you will be asked if
+ you would like to use it to set the default values of various
+ configuration settings. If you've already got an (at least
+ somewhat) working configuration you will want to do this.
+
+ If you are running on an OS which has a mouse driver in the
+ kernel (e.g. SCO or SVR4), you may be asked if you'd like to
+ use it.
+
+ Once the questions (if any) are completed, you will see a message
+ indicating that the program is ready to switch into graphics mode.
+ Just press Enter. If you don't get a graphics screen saying
+ <it/Welcome to XFree86 Setup/ within a minute, something has
+ probably hung, you can try pressing Ctrl-Alt-Backspace to
+ switch back to text mode and you'll probably have to use
+ xf86config instead of XF86Setup.
+-->
+ XF86Config ¥Õ¥¡¥¤¥ë¤¬¤¹¤Ç¤Ë¤¢¤ë¾ì¹ç¤Ï¡¢ÍÍ¡¹¤ÊÀßÄê¹àÌܤÎɸ½àÃͤò
+ ÀßÄꤹ¤ë¤Î¤Ë¡¢¤½¤³¤Ë¤¢¤ë¹àÌܤòɸ½àÃͤ˻ȤäƤ⹽¤ï¤Ê¤¤¤«Ê¹¤«¤ì¤Þ
+ ¤¹¡£
+ ¤â¤· (¿¾¯¤Ê¤ê¤È¤â) ´û¤Ëưºî¤·¤Æ¤¤¤ë¹½À®¤¬Æþ¼ê¤Ç¤­¤ë¤Ê¤é¤½¤ì¤«¤é
+ »Ï¤á¤Þ¤·¤ç¤¦¡£
+
+ ¥«¡¼¥Í¥ëÆâÉô¤Ë¥Þ¥¦¥¹¥É¥é¥¤¥Ð¤¬Æâ¢¤µ¤ì¤Æ¤¤¤ë OS (Î㤨¤Ð¡¢SCO Ëô¤Ï
+ SVR4) ¤¬Æ°ºî¤·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¤½¤Î¥É¥é¥¤¥Ð¤ò»ÈÍѤ·¤Æ¤â¤è¤¤¤«³Îǧ
+ ¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+ °ìö (¤¢¤ë¤«¤â¤·¤ì¤Ê¤¤) µ¿Ì䤬²ò¾Ã¤·¤¿¤é¡¢¥°¥é¥Õ¥£¥Ã¥¯¥â¡¼¥É¤ËÀÚ¤ê
+ ÂØ¤¨¤ë½àÈ÷¤¬¤Ç¤­¤¿»ö¤ò¼¨¤¹¥á¥Ã¥»¡¼¥¸¤¬É½¼¨¤µ¤ì¤ë¤È»×¤¤¤Þ¤¹¡£
+ Ìۤäƥ¨¥ó¥¿¡¼¥­¡¼¤ò²¡¤·¤Þ¤·¤ç¤¦¡£¤Á¤ç¤Ã¤È¤·¤Æ¤«¤é¥°¥é¥Õ¥£¥Ã¥¯
+ ²èÌÌ¤Ë <it/Welcome to XFree86 Setup/ ¤¬É½¼¨¤µ¤ì¤Ê¤¤¾ì¹ç¤Ï¡¢²¿¤«¤¬
+ ¿ʬ¤À¤ó¤Þ¤ê¾õÂ֤ˤʤ俤Τǡ¢Ctrl ¥­¡¼¤È Alt ¥­¡¼¤È Backspace
+ ¥­¡¼¤òƱ»þ¤Ë²¡¤·¤Æ¥Æ¥­¥¹¥È¥â¡¼¥É¤ËÌá¤Ã¤Æ¡¢XF86Setup ¤ÎÂå¤ï¤ê¤Ë
+ xf86config ¤ò»È¤¦É¬Íפ¬¤¢¤ê¤Þ¤¹¡£
+
+<!--
+<sect1> Configuration areas
+-->
+<sect1> ¹½À®¾ðÊó¤Î¹àÌÜ
+<p>
+<!--
+ Once the VGA16 server is started, and once the program has
+ finished loading, you will see a screen with five
+ buttons along the top and three along the bottom.
+ The buttons along the top correspond to the general categories
+ of configuration settings. They can be done in any order.
+ Each of these areas is explained in detail below.
+ The bottom row consists of the <bf/Abort/,
+ <bf/Done/, and <bf/Help/ buttons.
+-->
+ °ìö¡¢VGA16 ¤Î¥µ¡¼¥Ð¤¬µ¯Æ°¤·¤Æ¡¢¥×¥í¥°¥é¥à¤Î¥í¡¼¥Ç¥£¥ó¥°
+ ¤¬´°Î»¤¹¤ì¤Ð¡¢²èÌ̤ξå¤Ë£µ¤Ä¤Î¥Ü¥¿¥ó¤È²¼¤Ë£³¤Ä¤Î¥Ü¥¿¥ó¤¬
+ ɽ¼¨¤µ¤ì¤Þ¤¹¡£
+ ¹½À®¾ðÊó¤ÎÆâ¡¢°ìÈÌŪ¤ÊʬÎà¤ËÂбþ¤¹¤ë¥Ü¥¿¥ó¤¬¾å¤Ë¤¢¤ê¤Þ¤¹¡£
+ ¼Â¹Ô¤¹¤ë½çÈÖ¤ÏÌ䤤¤Þ¤»¤ó¡£°Ê¹ß¤Ç¤½¤ì¤¾¤ì¤Î¹àÌܤξܺ٤ˤĤ¤¤Æ
+ ÀâÌÀ¤·¤Þ¤¹¡£
+ ²¼¤Î¥Ü¥¿¥ó¤Ï¤½¤ì¤¾¤ì <bf/Abort/, <bf/Done/, ¤È <bf/Help/
+ ¤È¤¤¤¦¤â¤Î¤¬É½¼¨¤µ¤ì¤Þ¤¹¡£
+<p>
+<!--
+ <bf/Abort/ does as it name implies. It exits the program
+ without saving any changes that have been made. The one
+ possible exception is the link to the mouse device. Any
+ change to that is made as soon as <bf/Apply/ is selected.
+-->
+ <bf/Abort/ ¤Ï̾Á°¤É¤ª¤ê¤Î°ÕÌ£ (Ãæ»ß) ¤Ç¤¹¡£ÀßÄꤷ¤¿Á´¤Æ¤Î
+ Êѹ¹¤ò³ÊǼ¤·¤Ê¤¤¤Ç½ªÎ»¤·¤Þ¤¹¡£(Ãæ»ß½ÐÍè¤Ê¤¤)£±¤Ä¤¢¤ê¤½¤¦¤Ê
+ Îã³°¤Ï¥Þ¥¦¥¹¤Î¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤Ø¤Î¥ê¥ó¥¯¤Ç¤¹¡£¹Ô¤Ã¤¿Êѹ¹¤ò
+ ¤¹¤°¤ËÀßÄꤷ¤¿¤¤¤È¤­¤Ï <bf/Apply/ ¤òÁªÂò¤·¤Æ¤¯¤À¤µ¤¤¡£
+<p>
+<!--
+ <bf/Done/ should be selected when you've finished
+ configuration in each of the various categories.
+-->
+ ¿§¡¹¤ÊʬÎà¤Î¹½À®¾ðÊó¤ÎÀßÄ꤬½ªÎ»¤·¤¿¤È¤­¤Ï <bf/Done/ ¤ò
+ ÁªÂò¤·¤Æ¤¯¤À¤µ¤¤¡£
+<p>
+<!--
+ The <bf/Help/ can be pressed at any time to get on-line
+ help regarding the current configuration screen.
+-->
+ ¸½¹Ô¤ÎÀßÄê²èÌ̤˴ؤ¹¤ë¥ª¥ó¥é¥¤¥ó¥Ø¥ë¥×¤¬Íߤ·¤¤¤È¤­¤Ï <bf/Help/
+ ¤ò²¡¤·¤Æ¤¯¤À¤µ¤¤¡£
+<p>
+<!--
+ You should start with configuring your mouse as it will make
+ things a lot easier to perform the configuration of other
+ categories.
+-->
+ ¾¤ÎÉôʬ¤ÎÀßÄ꤬¤â¤Ã¤È´Êñ¤Ë¤Ê¤ë¤Î¤Ç¡¢¥Þ¥¦¥¹¤ÎÀßÄ꤫¤é»Ï¤á¤Þ
+ ¤·¤ç¤¦¡£
+<!--
+<sect2> Mouse
+-->
+<sect2> ¥Þ¥¦¥¹
+<p>
+<!--
+ The mouse configuration screen is used to get the mouse working
+ properly. There are key bindings for everything so that you
+ can easily configure the mouse, if it's not already working.
+-->
+ ¥Þ¥¦¥¹¤ÎÀßÄê²èÌ̤ϡ¢¥Þ¥¦¥¹¤òÀµ¤·¤¯Æ°ºî¤µ¤»¤ë¤¿¤á¤Ë»ÈÍѤ·¤Þ¤¹¡£
+ ¤Þ¤À¥Þ¥¦¥¹¤¬Æ°ºî¤·¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ç¤â¡¢¥Þ¥¦¥¹¤ÎÀßÄê¤òÍÆ°×¤Ë¤¹
+ ¤ë¤¿¤á¡¤¥Þ¥¦¥¹¤ÎÁ´µ¡Ç½¤ËÂбþ¤¹¤ë¥­¡¼¤¬³ä¤êÅö¤Æ¤é¤ì¤Æ¤¤¤Þ¤¹¡£
+<p>
+<!--
+ The screen includes a representation of a white mouse with
+ three buttons. As you move your mouse it should show the
+ pointer coordinates on the mouse and the buttons should turn
+ black as you press the corresponding button on your mouse.
+ If that is not happening, then your mouse is not correctly
+ configured.
+-->
+ £³¥Ü¥¿¥ó¤ÎÇò¤¤¥Þ¥¦¥¹¤ÎÌϼ°¿Þ¤ò²èÌ̤Ëɽ¼¨¤·¤Þ¤¹¡£
+ ¥Þ¥¦¥¹¤òư¤«¤¹¤È¡¢²èÌ̤˥ޥ¦¥¹¥«¡¼¥½¥ë¤ÎºÂɸÃͤ¬É½¼¨¤µ¤ì¡¢
+ ¥Þ¥¦¥¹¤Î¥Ü¥¿¥ó¤ò²¡¤¹¤ÈÂбþ¤¹¤ëÌϼ°¿Þ¤Î¥Ü¥¿¥ó¤¬¹õ¤¯¿§¤¬ÊѤï
+ ¤ê¤Þ¤¹¡£
+ ¤³¤ÎÍͤˤʤé¤Ê¤¤¾ì¹ç¤Ï¡¢¥Þ¥¦¥¹¤ÏÀµ¤·¤¯ÀßÄê½ÐÍè¤Æ¤¤¤Þ¤»¤ó¡£
+<p>
+<!--
+ Along the top is a row of buttons corresponding to
+ the various possible protocols. There will also be
+ several buttons and a couple of sliders
+ for other settings, a visual representation of the mouse,
+ and a button to apply any changes.
+ There may also be an entry box in which the
+ device can be set along with a list of possible devices.
+-->
+ ²èÌ̤ξå¤Ëʤó¤Ç¤¤¤ë¥Ü¥¿¥ó¤ÎÎó¤Ï³ºÅö¤¹¤ë¿§¡¹¤Ê»ÈÍѲÄǽ¤Ê
+ ¥×¥í¥È¥³¥ë¤ËÂбþ¤·¤Æ¤¤¤Þ¤¹¡£Â¾¤ÎÀßÄê¤ò¹Ô¤¦¤¿¤á¤Î¥Ü¥¿¥ó¤ä
+ ¥¹¥é¥¤¥À¤â¤¤¤¯¤Ä¤«¤¢¤ê¤Þ¤¹¤·¡¢¥Þ¥¦¥¹¤ÎÌϼ°¿Þ¡¢¤ª¤è¤Ó
+ ÀßÄêÊѹ¹¤òÈ¿±Ç¤µ¤»¤ë¤¿¤á¤Î¥Ü¥¿¥ó¤â¤¢¤ê¤Þ¤¹¡£
+ »ÈÍѲÄǽ¤Ê¥Ç¥Ð¥¤¥¹¤Î°ìÍ÷¤ÎÃæ¤«¤é¥Ç¥Ð¥¤¥¹¤òÀßÄꤹ¤ë¥¨¥ó¥È¥ê
+ ¥Ü¥Ã¥¯¥¹¤â¤¢¤ê¤Þ¤¹¡£
+<p>
+<!--
+ First try moving your mouse around and see if the pointer moves
+ correctly. If so, try testing that the buttons are working
+ properly. If those are working as desired, go ahead and go on
+ to another configuration area.
+-->
+ ¤Þ¤ººÇ½é¤Ë¥Þ¥¦¥¹¤ò°Üư¤µ¤»¤Æ¡¢¥Þ¥¦¥¹¥«¡¼¥½¥ë¤¬Àµ¤·¤¯°Üư
+ ¤¹¤ë¤³¤È¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£¤¦¤Þ¤¯Æ°¤¤¤¿¤é¡¢¥Ü¥¿¥ó¤¬¤Á¤ã¤ó
+ ¤Èưºî¤¹¤ë¤«¥Æ¥¹¥È¤·¤Æ¤ß¤Þ¤·¤ç¤¦¡£»×¤Ã¤¿¤è¤¦¤Ëưºî¤·¤¿¤é¡¢
+ ¼¡¤Ï¾¤ÎÀßÄê¹àÌܤ˹Ԥ­¤Þ¤·¤ç¤¦¡£
+<p>
+<!--
+ If the mouse pointer doesn't move at all, you need to fix
+ either the mouse device or the protocol (or both).
+ You can press 'n' followed by a Tab, to move to the list
+ of mouse devices and select a different one.
+ Pressing 'p' will pick the next available protocol on the list.
+ After changing these, press 'a' to apply the changes and try
+ again. Repeat the process until you are getting some response
+ from your mouse.
+-->
+ ¥Þ¥¦¥¹¥«¡¼¥½¥ë¤¬Á´¤¯°Üư½ÐÍè¤Ê¤¤¾ì¹ç¡¢¥Þ¥¦¥¹¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤«
+ ¥Þ¥¦¥¹¤Î¥×¥í¥È¥³¥ë¤Î¤É¤Á¤é¤« (¼ã¤¯¤ÏξÊý) ¤ò½¤Àµ¤¹¤ëɬÍפ¬
+ ¤¢¤ê¤Þ¤¹¡£ 'n' ¤Ë³¤¤¤Æ¥¿¥Ö¥­¡¼¤ò²¡¤¹¤È¼¡¤Ë»ÈÍѲÄǽ¤Ê¥Ç¥Ð¥¤¥¹
+ ¥É¥é¥¤¥Ð¤Î°ìÍ÷¤¬É½¼¨¤µ¤ì¤Þ¤¹¤Î¤Ç°Û¤Ê¤Ã¤¿¥×¥í¥È¥³¥ë¤òÁªÂò¤·¤Æ
+ ¤¯¤À¤µ¤¤¡£'p' ¤ò²¡¤»¤Ð¼¡¤Ë»ÈÍѲÄǽ¤Ê¥×¥í¥È¥³¥ë¤Î°ìÍ÷¤¬É½¼¨¤µ
+ ¤ì¤Þ¤¹¡£
+ ¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤ä¥×¥í¥È¥³¥ë¤òÊѹ¹¤·¤¿¸å¤Ï 'a' ¤ò²¡¤»¤ÐÊѹ¹¤¬
+ È¿±Ç¤µ¤ì¤Þ¤¹¤Î¤Ç¤â¤¦°ìÅٻ¤Æ¤ß¤Þ¤·¤ç¤¦¡£¥Þ¥¦¥¹¤«¤é¤Î±þÅú¤¬
+ Ê֤äƤ¯¤ë¤Þ¤Ç¤³¤ÎÁàºî¤ò·«¤êÊÖ¤·¤Þ¤·¤ç¤¦¡£
+<p>
+<!--
+ If the mouse pointer or button indicators do something when you
+ move the mouse, but the pointer is not moving properly, you
+ probably have the wrong protocol selected. Try with a different
+ one.
+-->
+ ¥Þ¥¦¥¹¥«¡¼¥½¥ë¤«¥Ü¥¿¥ó¤¬³ÎǧÍѤÎÌϼ°¿Þ¤Ç¤Ïưºî¤¹¤ë¤Î¤Ë¡¢¼ÂºÝ¤Ë
+ ¥Þ¥¦¥¹¤ò°Üư¤µ¤»¤¿»þ¤Á¤ã¤ó¤È¥Þ¥¦¥¹¥«¡¼¥½¥ë¤¬°Üư¤·¤Ê¤¤¾ì¹ç¤Ï¡¢
+ ¿ʬ°­¤¤¥×¥í¥È¥³¥ë¤òÁªÂò¤·¤Æ¤¤¤ë¤Î¤Ç¤¹¡£°Û¤Ê¤ë¥×¥í¥È¥³¥ë¤ò»î¤·
+ ¤Æ¤ß¤Þ¤·¤ç¤¦¡£
+<p>
+<!--
+ Most mice these days use the <bf/Microsoft/ protocol, the second
+ most common is <bf/MouseSystems/. Some mice do both.
+ These <it/dual-protocol/ mice have various methods of switching
+ between the two protocols.
+ Some have a switch on the mouse itself.
+ Some are switched by sending a certain signal to the mouse
+ when opening a connection to the mouse.
+ These signals can be controlled by using different
+ combinations of the 'ClearDTR' and 'ClearRTS' settings.
+ Other mice require a button to be depressed when the mouse
+ is opened (when the mouse driver first tries to talk to it).
+ If your mouse uses this method, hold down the appropriate
+ button while selecting apply (pressing 'a').
+-->
+ ºÇ¶á¤ÎËØ¤É¤Î¥Þ¥¦¥¹¤Ï <bf/Microsoft/ ¥×¥í¥È¥³¥ë¤ò»È¤Ã¤Æ¤¤¤Æ¡¢
+ ¼¡¤ËËØ¤É¤Î¥Þ¥¦¥¹¤Ï <bf/MouseSystems/ ¥×¥í¥È¥³¥ë¤ò»È¤Ã¤Æ¤¤¤Þ
+ ¤¹¡£¤¤¤¯¤Ä¤«¤Î¥Þ¥¦¥¹¤ÏξÊý¤â¤Ã¤Æ¤¤¤Þ¤¹¡£
+ ¤³¤ÎÍÍ¤Ê <it/Æó½Å¥×¥í¥È¥³¥ë/ ( <it/dual-protocol/ ) ¤Î¥Þ¥¦
+ ¥¹¤ÏÍÍ¡¹¤ÊÊýË¡¤Ç£²¤Ä¤Î¥×¥í¥È¥³¥ë¤òÀÚ¤êÂØ¤¨¤Þ¤¹¡£
+ ¥Þ¥¦¥¹ËÜÂΤËÀÚÂØ¤¨¥¹¥¤¥Ã¥Á¤¬¤Ä¤¤¤Æ¤¤¤ë¤â¤Î¤â¤¢¤ê¤Þ¤¹¡£
+ ¤¤¤¯¤Ä¤«¤Î¥Þ¥¦¥¹¤Î¾ì¹ç¤Ï¡¢¥Þ¥¦¥¹¤È¤ÎÀܳ¤ò»Ï¤á¤¿»þ¤Ë°ìÄê¤Î¿®¹æ¤ò
+ ¥Þ¥¦¥¹¤ËÁ÷¿®¤·¤ÆÀÚ¤êÂØ¤¨¤Þ¤¹¡£¤½¤Î¿®¹æ¤Ï 'ClearDTR' ¤È
+ 'ClearRTS' ¤ÎÍÍ¡¹¤ÊÁȤ߹ç¤ï¤»¤ÇÀ©¸æ¤·¤Æ¤¤¤Þ¤¹¡£
+ ¤½¤Î¾¤Î¥Þ¥¦¥¹¤Ç¤Ï¥Þ¥¦¥¹¤È¤ÎÀܳ»þ (¥Þ¥¦¥¹¥É¥é¥¤¥Ð¤¬ºÇ½é¤Ë
+ ÄÌ¿®¤·¤è¤¦¤È¤·¤Þ¤¹) ¤Ë¥Ü¥¿¥ó¤¬²¡¤µ¤ì¤Æ¤¤¤ë¤«Ä´ºº¤¹¤ë¤â¤Î¤â
+ ¤¢¤ê¤Þ¤¹¡£»ÈÍѤ·¤¿¤¤¥Þ¥¦¥¹¤¬¤³¤Î¼ï¤Î¤â¤Î¤Ê¤é¤ÐŬÀڤʥܥ¿¥ó
+ ¤ò²¡¤µ¤¨¤Ê¤¬¤éÁªÂò»þ¤Ë ('a' ¤ò²¡¤·¤Æ) ŬÍѤ·¤Æ¤¯¤À¤µ¤¤¡£
+<p>
+<!--
+ Once the mouse pointer is moving correctly, test that all
+ three buttons are working properly. If your mouse only has
+ two buttons, select 'Emulate3Buttons' and you should be able
+ to press both buttons simultaneously to emulate the missing
+ middle button. If not all of the buttons are working, try
+ changing the 'ChordMiddle' setting or you may be using a
+ protocol that is similar to that of your mouse,
+ but not quite right.
+-->
+ ¥Þ¥¦¥¹¤Î¥«¡¼¥½¥ë¤¬Àµ¤·¤¯°Üư¤·¤¿¤é¡¢£³¤Ä¤Î¥Ü¥¿¥ó¤¬Å¬ÀÚ¤ËÆ¯¤¯
+ ¤«¥Æ¥¹¥È¤·¤Æ¤¯¤À¤µ¤¤¡££²¥Ü¥¿¥ó¥Þ¥¦¥¹¤Î¾ì¹ç¤Ï 'Emulate3Buttons'
+ ¤òÁªÂò¤·¤Æ£²¥Ü¥¿¥ó¥Þ¥¦¥¹¤Ë̵¤¤¿¿¤óÃæ¤Î¥Ü¥¿¥ó¤ÎÂå¤ï¤ê¤Ë£²¤Ä¤Î
+ ¥Ü¥¿¥ó¤òƱ»þ¤Ë²¡¤·¤Æ¤¯¤À¤µ¤¤¡£Á´¤Æ¤Î¥Ü¥¿¥ó¤¬Æ°ºî¤·¤Ê¤¤¾ì¹ç¤Ï¡¢
+ 'ChordMiddle' ¤ÎÀßÄê¤òÊѹ¹¤·¤Æ¤ß¤ë¤«¥Þ¥¦¥¹¤¬»È¤Ã¤Æ¤¤¤ë
+ ¥×¥í¥È¥³¥ë¤È¤½¤Ã¤¯¤ê¤Î»÷¤Æ¤¤¤ë¥×¥í¥È¥³¥ë¤ÎÀßÄê¤ò¤·¤Æ¤ß¤Þ¤·¤ç¤¦¡£
+<!--
+<sect2> keyboard
+-->
+<sect2> ¥­¡¼¥Ü¡¼¥É
+<p>
+<!--
+ You need to specify the model and layout of your keyboard (and
+ press apply) if they are not already correct.
+ The graphical representation of the keyboard will be
+ updated when you choose a different model.
+-->
+ ¸½ºß¤ÎÀßÄ꤬Àµ¤·¤¯¤Ê¤¤¾ì¹ç¡¢¥­¡¼¥Ü¡¼¥É¤Î·¿Ì¾¤È¥­¡¼ÇÛÎó¤òÁªÂò
+ ¤¹¤ë (ŬÍÑ (apply) ¤ò²¡¤¹) ɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+ ¥­¡¼¥Ü¡¼¥É¤ÎÌϼ°¿Þɽ¼¨¤¬ÁªÂò¤·¤¿¥­¡¼¥Ü¡¼¥É¤Î¤â¤Î¤ËÆþ¤ìÂØ¤ï¤ê¤Þ¤¹¡£
+<p>
+<!--
+ For non-U.S. keyboards you may wish to choose a variant from
+ the list (at this time there is only one available variant:
+ <tt/nodeadkeys/>).
+-->
+ ¥¢¥á¥ê¥«°Ê³°¤Î¥­¡¼¥Ü¡¼¥É¤Î¾ì¹ç¡¢°ìÍ÷¤ÎÁªÂò»è (¸½ºß¤ÎÁªÂò»è¤Ï
+ <tt/nodeadkeys/>¤Î£±¤Ä¤·¤«¤¢¤ê¤Þ¤»¤ó) ¤«¤éÀßÄꤷ¤¿¤¤¤â¤Î¤ò
+ Áª¤ó¤Ç¤¯¤À¤µ¤¤¡£
+<p>
+<!--
+ You can also pick from the options to the right, if you wish.
+-->
+ ¤Þ¤¿¡¢¥ª¥×¥·¥ç¥ó¤ÎÃæ¤«¤éÀµ¤·¤¤¤â¤Î¤òÁª¤Ö¤³¤È¤â½ÐÍè¤Þ¤¹¡£
+
+<!--
+<sect2> Card
+-->
+<sect2> ¥Ó¥Ç¥ª¥«¡¼¥É
+<p>
+<!--
+ Pick your card from the list.
+-->
+ °ìÍ÷¤«¤é¥Ó¥Ç¥ª¥«¡¼¥É¤òÁª¤ó¤Ç¤¯¤À¤µ¤¤¡£
+<p>
+<!--
+ If there are README files that may pertain to your card
+ the 'Read README file' button will then be usable (i.e. not
+ greyed out).
+ Please read them.
+-->
+ ¥Ó¥Ç¥ª¥«¡¼¥É¤ËÉÕ°¤¹¤ë README ¥Õ¥¡¥¤¥ë¤¬¤¢¤ì¤Ð 'Read README file'
+ ¤Î¥Ü¥¿¥ó¤ò²¡¤»¤Ð (¤¿¤À¤·³¥¿§¤Ë¤Ê¤Ã¤Æ¤¤¤Ê¤±¤ì¤Ð) ÆÉ¤à¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£
+<p>
+<!--
+ If your card is not in the list, or if there are any
+ special settings listed in the README file as required
+ by your card, you can press the 'Detailed Setup'
+ button to make sure that the required settings are selected.
+ Otherwise, you're finished with configuring your card.
+-->
+ ¥Ó¥Ç¥ª¥«¡¼¥É¤¬°ìÍ÷¤Ë¤Ê¤±¤ì¤Ð¡¢¤Þ¤¿¤Ï README ¥Õ¥¡¥¤¥ë¤ÎÃæ¤Ë
+ ¥Ó¥Ç¥ª¥«¡¼¥É¤Ë´Ø¤·¤ÆÆÃÊ̤ÊÀßÄ꤬ɬÍפǤ¢¤ë¤È½ñ¤«¤ì¤Æ¤¤¤ë¾ì¹ç¡¢
+ 'Detailed Setup' ¤Î¥Ü¥¿¥ó¤ò²¡¤·¤ÆÉ¬ÍפÊÀßÄ꤬ÁªÂò¤µ¤ì¤Æ¤¤¤ë
+ ¤³¤È¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£¤â¤·¤½¤¦¤Ç¤Ê¤«¤Ã¤¿¤é¡¢¥Ó¥Ç¥ª¥«¡¼¥É¤Î
+ ÀßÄê¤Ï½ªÎ»¤Ç¤¹¡£
+<p>
+<!--
+ To use 'Detailed Setup':
+ First select the appropriate server for your card.
+ Then read the README file corresponding to the selected
+ server by pressing the 'Read README file' button
+ (it won't do anything, if there is no README).
+-->
+ 'Detailed Setup'¤Î»ÈÍÑË¡:
+ À褺ºÇ½é¤Ë¥Ó¥Ç¥ª¥«¡¼¥É¤ËÂбþ¤·¤¿¥µ¡¼¥Ð¤òÁªÂò¤·¤Þ¤¹¡£
+ ¤½¤ì¤«¤éÁªÂò¤·¤¿¥µ¡¼¥Ð¤ËÂбþ¤¹¤ë README ¥Õ¥¡¥¤¥ë¤ò 'Read README file'
+ ¥Ü¥¿¥ó¤ò²¡¤·¤ÆÆÉ¤ó¤Ç¤¯¤À¤µ¤¤¡£(README ¥Õ¥¡¥¤¥ë¤¬Ìµ¤¤¾ì¹ç¤Ï²¿¤â
+ ¤¹¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£)
+<p>
+<!--
+ Next, pick the chipset, and Ramdac of your card, if
+ directed by the README file.
+ In most cases, you don't need to select these,
+ as the server will detect (probe) them automatically.
+-->
+ ³¤¤¤Æ¡¢README ¥Õ¥¡¥¤¥ë¤Ë»Ø¼¨¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¤¥Á¥Ã¥×¥»¥Ã¥È¤È
+ Ramdac ¤ò»ØÄꤷ¤Þ¤¹¡£
+ ËØ¤É¤Î¾ì¹ç¡¢¼«Æ°Åª¤ËõÃÎ (¸¡½Ð) ¤µ¤ì¤ë¤Î¤Ç¤³¤ì¤é¤òÁªÂò¤¹¤ëɬÍפÏ
+ ¤¢¤ê¤Þ¤»¤ó¡£
+<p>
+<!--
+ The clockchip should generally be picked, if your card
+ has one, as these are often impossible to probe
+ (the exception is when the clockchip is built
+ into one of the other chips).
+-->
+ ¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤ÏÄ̾︡½Ð¤Ç¤­¤Þ¤»¤ó¤Î¤Ç¡Ê¤¿¤À¤·Â¾¤Î¥Á¥Ã¥×¤ËÁȤß
+ ¹þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¤ò½ü¤­¤Þ¤¹¡Ë¡¢°ìÈÌŪ¤Ë¤Ï»ØÄꤷ¤Æ¤ª¤¯É¬Íפ¬¤¢¤ê
+ ¤Þ¤¹¡£
+<p>
+<!--
+ Choose whatever options are appropriate (again,
+ according to the README).
+-->
+ ɬÍפʥª¥×¥·¥ç¥ó¤Ï°ìÄ̤êÁªÂò¤·¤Æ¤ª¤­¤Þ¤·¤ç¤¦( README ¤Ë½¾¤Ã¤Æ¤¯
+ ¤À¤µ¤¤)¡£
+<p>
+<!--
+ You can also set the maximum speed of your Ramdac.
+ Some Ramdacs are available with various speed ratings.
+ The max speed cannot be detected by the server
+ so it will use the speed rating of the slowest version
+ of the specified Ramdac, if you don't specify one.
+-->
+ ¤Þ¤¿¡¢Ramdac ¤ÎºÇ¹â¼þÇÈ¿ô¤òÀßÄê½ÐÍè¤Þ¤¹¡£
+ ¤¤¤¯¤Ä¤«¤Î Ramdac ¤ÏÍÍ¡¹¤Ê¼þÇÈ¿ô¤ò»È¤¦¤³¤È¤¬½ÐÍè¤Þ¤¹¡£
+ ¥µ¡¼¥Ð¤ÏºÇ¹â®ÅÙ¤òõÃνÐÍè¤Ê¤¤¤Î¤Ç¡¢»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï
+ »ØÄꤷ¤¿ Ramdac ¤ÎºÇÄã®ÅÙ¤ò»ÈÍѤ·¤Þ¤¹¡£
+<p>
+<!--
+ Additionally, you can also specify the amount of RAM on your
+ card, though the server will usually be able to detect this.
+-->
+ ¤µ¤é¤Ë¡¢¥µ¡¼¥Ð¤¬Ä̾ï¥á¥â¥êÍÆÎ̤òõÃνÐÍè¤ë¤Ë¤â¤«¤«¤ï¤é¤º¡¢
+ ¥Ó¥Ç¥ª¥«¡¼¥É¤ËÅëºÜ¤·¤Æ¤¤¤ë¥á¥â¥ê¤ÎÍÆÎ̤â¤Þ¤¿»ØÄê½ÐÍè¤Þ¤¹¡£
+
+
+<!--
+<sect2> Monitor
+-->
+<sect2> ¥â¥Ë¥¿
+<p>
+<!--
+ Enter the horizontal and vertical frequency ranges that your
+ monitor supports in the corresponding entry boxes near the
+ top of the screen.
+ You can enter specific frequencies or ranges of frequencies
+ (separated by hyphens).
+ If the monitor supports several different frequencies or
+ ranges, list them all, separated by commas.
+-->
+ ¥â¥Ë¥¿¡¼¤¬¥µ¥Ý¡¼¥È¤¹¤ë¿åÊ¿¤È¿âľ¤ÎƱ´ü¼þÇÈ¿ôÂÓ°è¤ò²èÌ̤ξå¤Î
+ Âбþ¤¹¤ëÆþÎÏÎΰè¤ËÆþÎϤ·¤Æ¤¯¤À¤µ¤¤¡£
+ °ìÄê¤Î¼þÇÈ¿ô¤«¼þÇÈ¿ô¤ÎÈϰϤò (¥Ï¥¤¥Õ¥ó¤Ç¶èÀڤäÆ) »ØÄê¤Ç¤­¤Þ¤¹¡£
+ ¤¤¤¯¤Ä¤«¤Î°Û¤Ê¤ë¼þÇÈ¿ô¤Þ¤¿¤ÏÈϰϤò¥µ¥Ý¡¼¥È¤¹¤ë¤È¤­¤Ë¤Ï¡¢
+ ʤ٤ƥ«¥ó¥Þ¤Ç¶èÀڤäƤ¯¤À¤µ¤¤¡£
+<p>
+<!--
+ If you can not find this information in you monitor's manual,
+ pick one of the choices from the list of common monitor
+ capabilities. The program will use conservative values
+ for each of these, so you'll get better performance if you
+ type in the correct values from your monitor manual.
+-->
+ ¥â¥Ë¥¿¡¼¤Î¥Þ¥Ë¥å¥¢¥ë¤ËƱ´ü¼þÇÈ¿ô¤Ë´Ø¤¹¤ë¾ðÊ󤬸«¤Ä¤±¤é¤ì¤Ê¤¤
+ ¾ì¹ç¤Ï¡¢°ìÈÌŪ¤Ê¥â¥Ë¥¿¡¼¤ÎÆÃÀ­ÃͤΰìÍ÷¤«¤é°ì¤ÄÁªÂò¤·¤Æ¤¯¤À¤µ
+ ¤¤¡£¤½¤ì¤¾¤ì¤Î¼þÇÈ¿ô¤Ë¹µ¤¨ÌܤοôÃͤò¥µ¡¼¥Ð¤¬»ÈÍѤ¹¤ë¤Î¤Ç¡¢
+ ¤â¤Ã¤ÈÎɤ¤À­Ç½¤¬Íߤ·¤¤¤Ê¤é¤Ð¡¢¥â¥Ë¥¿¡¼¤Î¥Þ¥Ë¥å¥¢¥ë¤«¤éÀµ¤·¤¤
+ ¿ôÃͤòÆþÎϤ·¤Æ¤¯¤À¤µ¤¤¡£
+<!--
+<sect2> Other
+-->
+<sect2> ¤½¤Î¾
+<p>
+<!--
+ You can probably just skip this one.
+-->
+ ¿ʬ¡¢¤³¤³¤ÏÆÉ¤ßÈô¤Ð¤·¤Æ¤â¤¤¤¤¤«¤â¡£
+
+<!--
+<sect2> Completing the configuration
+-->
+<sect2> ¹½À®ÄêµÁ¤Î»Å¾å¤²
+<p>
+<!--
+ Once you've finished with the above, press the 'Done' button
+ and then the 'Okay' button which will appear. You will then
+ be switched back to text mode.
+-->
+ ¾åµ­¤òÁ´Éô½ªÎ»¤·¤¿¤é¡¢'Done' ¥Ü¥¿¥ó¤ò²¡¤·¤Æ 'Okay' ¥Ü¥¿¥ó¤¬
+ ½Ð¤¿¤é²¡¤·¤Æ¤¯¤À¤µ¤¤¡£¥Æ¥­¥¹¥È¥â¡¼¥É¤ËÌá¤ë¤Ç¤·¤ç¤¦¡£
+
+<!--
+<sect1> Back to text mode
+-->
+<sect1> ¥Æ¥­¥¹¥È¥â¡¼¥É¤ËÌá¤ë
+<p>
+<!--
+ The program will now attempt to start the appropriate server
+ for your card, with all of the
+ configuration settings you selected.
+ If for some reason it is unable to start the server, you have
+ likely selected an improper setting and will be asked if you
+ would like to return to the graphical configuration screen
+ and try again.
+-->
+ ÀßÄꤷ¤¿Á´¤Æ¤Î¾ò·ï¤Ç¥Ó¥Ç¥ª¥«¡¼¥É¤ËÂбþ¤·¤¿¥µ¡¼¥Ð¤Îµ¯Æ°¤ò»î¤ß
+ ¤Þ¤¹¡£
+ ¤¤¤¯¤Ä¤«¤ÎÍýͳ¤Ç¥µ¡¼¥Ð¤¬µ¯Æ°½ÐÍè¤Ê¤¤¾ì¹ç¤Ï¡¢ÁªÂò¤·¤Æ¤¤¤ë
+ ¹ç¤Ã¤Æ¤¤¤Ê¤¤ÀßÄê¤òÄ´¤Ù¹½À®ÄêµÁ²èÌ̤ËÌá¤Ã¤Æ¤â¤¦°ìÅٻ¤Æ
+ ¤¯¤À¤µ¤¤¡£
+<!--
+<sect1> The second server
+-->
+<sect1> Â裲¥µ¡¼¥Ð
+<p>
+<!--
+ This is unlikely to happen, but
+ if when the server starts, the display is unreadable, try
+ pressing Ctrl-Alt-+ (using the plus on the numeric keypad)
+ to switch to a different video mode.
+-->
+ »Äǰ¤Ê¤¬¤é¡¢¥µ¡¼¥Ð¤¬µ¯Æ°¤·¤¿¤±¤ì¤É¤â²èÌ̤¬ÆÉ¤ß¤Ë¤¯¤¤
+ ¾ì¹ç¤Ï¡¢(¥Æ¥ó¥­¡¼¤Î¡Ü¤ò»È¤Ã¤Æ) Ctrl-Alt-+ ¤ò²¡¤·¤Æ
+ °Û¤Ê¤ë¥Ó¥Ç¥ª¥â¡¼¥É¤ËÀÚ¤êÂØ¤¨¤Æ¤¯¤À¤µ¤¤¡£
+<p>
+<!--
+ The display will show an entry box and three buttons.
+-->
+ ÆþÎÏÎΰè¤È£³¤Ä¤Î¥Ü¥¿¥ó¤¬²èÌ̤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡£
+<p>
+<!--
+ The first button allows you to run xvidtune to adjust your
+ video modes. One important point to keep in mind when using
+ xvidtune is that switching video modes with Ctrl-Alt-+ is
+ disabled while xvidtune is running.
+ You must use the 'Next' and 'Prev' buttons to switch modes.
+ Because of this, you should be careful not to move the mouse
+ when pressing either of these. If by some chance the mode
+ you switch to doesn't produce a readable display on your
+ monitor, you can then just press the mouse button again to
+ move to the next (hopefully readable) mode.
+-->
+ ºÇ½é¤Î¥Ü¥¿¥ó¤Ï¥Ó¥Ç¥ª¥â¡¼¥É¤òÄ´À°¤¹¤ë xvidtune ¤òµ¯Æ°¤·¤Þ¤¹¡£
+ xvidtune ¤ò»È¤¦¤È¤­¤Ë³Ð¤¨¤Æ¤ª¤¯¤Ù¤­½ÅÍפʻö¤Ï xvidtune
+ ¤Î¼Â¹ÔÃæ¤Ï Ctrl-Alt-+ ¤Ç¥Ó¥Ç¥ª¥â¡¼¥É¤òÀÚ¤êÂØ¤¨¤ë¤³¤È¤¬½ÐÍè
+ ¤Ê¤¤»ö¤Ç¤¹¡£
+ 'Next' ¤È 'Prev' ¥Ü¥¿¥ó¤ò»È¤Ã¤Æ¥â¡¼¥É¤òÀÚ¤êÂØ¤¨¤Æ¤¯¤À¤µ¤¤¡£
+ ¤è¤Ã¤Æ¡¢¥Þ¥¦¥¹¤ò¤³¤ì¤é¤Î¥Ü¥¿¥ó¤ò²¡¤·¤Æ¤¤¤ë¤È¤­¤Ë°Üư¤·¤Ê¤¤
+ ¤è¤¦¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¶öÁ³¤Ë¡¢¥â¥Ë¥¿¡¼¤Ë¸«¤ä¤¹¤¤²èÌ̤ò
+ ɽ¼¨¤·¤Ê¤¤¤è¤¦¤Ê¥Ó¥Ç¥ª¥â¡¼¥É¤ËÀÚ¤êÂØ¤¨¤¿¤È¤­¤Ï¡¢¤â¤¦°ìÅÙ
+ ¥Þ¥¦¥¹¥Ü¥¿¥ó¤ò²¡¤¹¤È¼¡¤Î¥â¡¼¥É (¤¦¤Þ¤¯¤¤¤±¤Ð¸«¤ä¤¹¤¤
+ ¥â¡¼¥É) ¤Ë°Üư¤¹¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡£
+<p>
+<!--
+ The second button causes the settings you've made to be
+ written to the filename given in the entry box.
+ After saving the settings a message will appear indicating
+ that it has finished. Just press the 'Okay' button and
+ you're done.
+-->
+ £²ÈÖÌܤΥܥ¿¥ó¤ÇÆþÎÏÎΰè¤ËÀßÄê¾ðÊó¤ò½ñ¤­¹þ¤à¥Õ¥¡¥¤¥ë̾¤òÆþÎÏ
+ ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£
+ ÀßÄê¾ðÊó¤ò³ÊǼ¤·¤¿¤È¤¤¤¦¥á¥Ã¥»¡¼¥¸¤¬É½¼¨¤µ¤ì¤¿¤éºî¶È¤Î½ªÎ»¤Î
+ ¹ç¿Þ¤Ç¤¹¡£'Okay' ¥Ü¥¿¥ó¤ò²¡¤·¤¿¤é¤ª¤·¤Þ¤¤¤Ç¤¹¡£
+<p>
+<!--
+ And the third button causes the program to exit without
+ saving any of the configuration settings.
+-->
+ ¤½¤·¤Æ£³ÈÖÌܤΥܥ¿¥ó¤ÏÀßÄê¾ðÊó¤ò³ÊǼ¤·¤Ê¤¤¤Ç¥×¥í¥°¥é¥à¤ò
+ ½ªÎ»¤·¤Þ¤¹¡£
+<!--
+<sect1> Ending text
+-->
+<sect1> ºÇ¸å¤Ë
+<p>
+<!--
+ You are returned to text mode and the program will print a
+ `Configuration complete.' message. You should now have a
+ usable configuration file and can start the X server by
+ whichever method you wish (usually either the 'startx'
+ command or via 'xdm').
+-->
+ ¥Æ¥­¥¹¥È¥â¡¼¥É¤ËÌá¤Ã¤¿¤é `Configuration complete.' ¤È¤¤¤¦
+ ¥á¥Ã¥»¡¼¥¸¤òɽ¼¨¤·¤Þ¤¹¡£¤µ¤Æ¡¢»È¤¨¤ë¹½À®¾ðÊó¤ò¼ê¤Ë¤·, X
+ ¥µ¡¼¥Ð¤ò»×¤¤Ä̤ê¤ÎÊýË¡ ('startx' ¥³¥Þ¥ó¥É¤È¤« 'xdm' ·Ðͳ
+ ) ¤Çµ¯Æ°½ÐÍè¤Þ¤¹¡£
+<!--
+<sect> Running <tt>xf86config</tt>
+-->
+<sect> <tt>xf86config</tt>¤ò¼Â¹Ô¤¹¤ë
+<p>
+<!--
+ From a text screen, run the <tt/xf86config/ program. This
+ program should be run as <it/root/ (although not absolutely
+ necessary, it will allow xf86config to do more of the work
+ for you). You can press your interrupt character (usually
+ Control-C or perhaps Delete), at any time to stop the program,
+ if you need to. You can just start it over again.
+
+ The <tt/xf86config/ program provides instructions on screen
+ as to what you need to do. Following are some notes that
+ document the various stages in the process. They should help
+ you get through the process quickly and provide some
+ documentation for those people who like to know what they're
+ getting themselves into, before running a program.
+-->
+ ¥Æ¥­¥¹¥È²èÌ̤«¤é <tt/xf86config/ ¤È¤¤¤¦¥×¥í¥°¥é¥à¤ò¼Â¹Ô¤·
+ ¤Þ¤·¤ç¤¦¡£¤³¤Î¥×¥í¥°¥é¥à¤Ï <it/root/ ¤Ë¤Ê¤Ã¤Æ (ÀäÂФËɬ¿Ü¤Ç
+ ¤Ï¤¢¤ê¤Þ¤»¤ó¤¬¡¢xf86config ¤¬¤è¤ê¿¤¯¤Î»Å»ö¤ò¤·¤Þ¤¹) ¼Â¹Ô
+ ¤·¤Æ¤¯¤À¤µ¤¤¡£Ãæ»ßʸ»ú (Ä̾Control-C ¥­¡¼¼ã¤·¤¯¤Ï
+ Delete ¥­¡¼¤Ç¤¹) ¤ò¥×¥í¥°¥é¥à¤ò»ß¤á¤¿¤¤¤È»×¤Ã¤¿¤é¡¢¤¤¤Ä¤Ç¤â
+ ²¡¤¹¤³¤È¤¬½ÐÍè¤Þ¤¹¡£¤¹¤°¤Ë¤ä¤êľ¤·¤¬½ÐÍè¤Þ¤¹¡£
+
+ <tt/xf86config/ ¤ÏɬÍפʺî¶È¤ò²èÌ̤Ëɽ¼¨¤¹¤ë»ÈÍÑË¡¤òÄó¶¡
+ ¤·¤Þ¤¹¡£¼¡¤Îʸ½ñ¤Ïºî¶È¤Î²áÄø¤Î¿§¡¹¤ÊÃʳ¬¤Ç¤ÎÃí°Õ»ö¹à¤Ç¤¹¡£
+ ¤³¤Îʸ½ñ¤Ë¤Ïºî¶È¤ò¼êÁ᤯¹Ô¤¨¡¢¥×¥í¥°¥é¥à¤ò¼Â¹Ô¤¹¤ëÁ°¤Ë
+ ²¿¤¬·ë²Ì¤È¤·¤ÆÆÀ¤é¤ì¤ë¤«¤òÃΤꤿ¤¤¿Í¸þ¤±¤Ë½ñ¤¤¤Æ¤¤¤Þ¤¹¡£
+
+<!--
+<sect1> The intro screen
+-->
+<sect1> ºÇ½é¤Î²èÌÌ
+<p>
+<!--
+ First, <tt/xf86config/ begins by telling you a few things like
+ the fact that it can help you setup an XF86Config file or that
+ you can do the job yourself with an editor. Just read what
+ it says and press <sf/Enter/ when done.
+-->
+ ¤Þ¤ººÇ½é¤Ë¡¢<tt/xf86config/ ¤Ï XF86Config ¥Õ¥¡¥¤¥ë¤òÀßÄꤹ¤ë
+ ¤Î¤Ë½õ¤±¤Ë¤Ê¤ë»ö¡¢¤Þ¤¿¤Ï¥¨¥Ç¥£¥¿¤Ç¼êºî¶È¤Ç¹Ô¤¦»ö¤ò¾¯¤·É½¼¨¤·
+ ¤Þ¤¹¡£²¿¤ò¼¨¤·¤Æ¤¤¤ë¤«ÆÉ¤ó¤À¤é <sf/Enter/ ¤ò²¡¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+<!--
+<sect1> Getting your <tt>PATH</tt> right
+-->
+<sect1> Àµ¤·¤¤ <tt>PATH</tt> ¤òÆÀ¤ë
+<p>
+<!--
+ The program will next check that you have the directory
+ <tt>/usr/X11R6</tt> (the standard installation directory)
+ on your system and tell you that it needs to be in your
+ <tt/PATH/ environment variable.
+
+ It will also check if you have the
+ <tt>/usr/X386</tt> directory as used by older (pre 3.0)
+ versions of XFree86. If by chance you do, it will warn you
+ that <tt>/usr/X11R6</tt> must be before <tt>/usr/X386</tt>
+ in your <tt/PATH/.
+
+ If everything is okay, just press Enter and go on, otherwise
+ press Control-C to exit and make any necessary changes and
+ restart <tt/xf86config/.
+-->
+ ¥×¥í¥°¥é¥à¤Ï¼¡¤Ë <tt>/usr/X11R6</tt> ¤È¤¤¤¦¥Ç¥£¥ì¥¯¥È¥ê
+ (ɸ½àƳÆþ¥Ç¥£¥ì¥¯¥È¥ê) ¤¬¥·¥¹¥Æ¥à¤Ë¤¢¤ë¤«Ä´¤Ù <tt/PATH/
+ ´Ä¶­ÊÑ¿ô¤ËÄɲ乤ëɬÍפ¬¤¢¤ë¤³¤È¤òɽ¼¨¤·¤Þ¤¹¡£
+
+ XFree86 (3.0 ¤è¤êÁ°) ¤¬»È¤Ã¤Æ¤¤¤¿ <tt>/usr/X386</tt>
+ ¥Ç¥£¥ì¥¯¥È¥ê¤¬¤¢¤ë¤«¤âÄ´¤Ù¤Þ¤¹¡£¶öÁ³¤Ë¸«¤Ä¤«¤Ã¤¿¾ì¹ç¡¢
+ <tt>/usr/X386</tt> ¤ÎÁ°¤Ë <tt>/usr/X11R6</tt> ¤ò <tt/PATH/
+ ¤ËÄêµÁ¤¹¤ë¤è¤¦¤Ë·Ù¹ð¤·¤Þ¤¹¡£
+
+ Á´¤Æ¤¬Âç¾æÉפʤé¤Ð¡¢Enter ¤ò²¡¤·¤Æ¼¡¤Ë¤¤¤­¤Þ¤·¤ç¤¦¡£
+ ¤µ¤â¤Ê¤±¤ì¤Ð¡¢ Control-C ¤ò²¡¤·¤Æ½ªÎ»¤·¤ÆÉ¬ÍפÊÊѹ¹¤ò¤·¤Æ
+ <tt/xf86config/ ¤òºÆµ¯Æ°¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+<!--
+<sect1> Mouse setup
+-->
+<sect1> ¥Þ¥¦¥¹¤ÎÀßÄê
+<p>
+<!--
+ Pick the mouse type from the menu and enter the name of the
+ device to which mouse is connected, as directed.
+
+ If you are using an OS (e.g. SVR4, SCO) that has a built in
+ mouse driver that the Xserver could use, you'll need to edit
+ the XF86Config file to setup your mouse, so just pick any
+ mouse from the list and press enter when asked for the device.
+
+ If you don't know which protocol your mouse uses, you'll just
+ have to guess (the xf86config program will give you some hints
+ as to which might be most likely) and then see the
+ troubleshooting section if it doesn't work when you run the
+ server.
+-->
+ ¥á¥Ë¥å¡¼¤«¤é¥Þ¥¦¥¹¤Î¥¿¥¤¥×¤òÁª¤ó¤ÇÀܳ¤·¤Æ¤¤¤ë¥Þ¥¦¥¹¤Î¥Ç¥Ð¥¤¥¹
+ ¥É¥é¥¤¥Ð̾¤òľÀÜÆþÎϤ·¤Æ¤¯¤À¤µ¤¤¡£
+
+ Xserver ¤¬»È¤¦¥Þ¥¦¥¹¥É¥é¥¤¥Ð¤òÆâ¢¤·¤Æ¤¤¤ë OS (Î㤨¤Ð SVR4, SCO)
+ ¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¥Þ¥¦¥¹¤ÎÀßÄê¤Ï XF86Config ¥Õ¥¡¥¤¥ë¤òÊÔ½¸
+ ¤·¤Æ¥Þ¥¦¥¹¤òÀßÄꤷ¤Ê¤±¤ì¤ÐɬÍפ¬¤¢¤ë¤Î¤Ç¡¢Å¬Åö¤Ê¥Þ¥¦¥¹¤ò°ìÍ÷
+ ¤«¤éÁªÂò¤·¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð̾¤Î±þÅú¤Ï ¥¨¥ó¥¿¡¼¥­¡¼¤ò²¡¤·¤Æ¤ª¤­¤Þ
+ ¤·¤ç¤¦
+
+ ¥Þ¥¦¥¹¤¬¤É¤Î¥×¥í¥È¥³¥ë¤ò»È¤Ã¤Æ¤¤¤ë¤«ÃΤé¤Ê¤¤¾ì¹ç¡¢¿ä¬¤·¤Æ
+ (xf86config ¤ÏÂçÂλ÷¤¿¤â¤Î¤Î¤¤¤¯¤Ä¤«¥Ò¥ó¥È¤ò½Ð¤·¤Þ¤¹)²¼¤µ¤¤¡£
+ ¤½¤ì¤«¤é¥µ¡¼¥Ð¤òµ¯Æ°¤·¤¿»þ¥Þ¥¦¥¹¤¬Æ°¤«¤Ê¤¤¾ì¹ç¡¢
+ ¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¤Î¾Ï¤ò¸«¤Æ¤¯¤À¤µ¤¤¡£
+
+<!--
+<sect1> Keyboard setup
+-->
+<sect1> ¥­¡¼¥Ü¡¼¥É¤ÎÀßÄê
+<p>
+<!--
+ Simply answer yes to the question regarding keyboard setup.
+
+ If there is some reason you need to use the right-alt and
+ control keys for something else, you can enter no.
+-->
+ ¥­¡¼¥Ü¡¼¥É¤ÎÀßÄê¤Ë´Ø¤·¤Æ¤Ïñ¤Ë¼ÁÌä¤Ë yes ¤ÈÅú¤¨¤Þ¤·¤ç¤¦¡£
+
+ ²¿¤«Â¾¤Îʪ¤Î°Ù¤Ë±¦¥ª¥ë¥¿¥Í¡¼¥È¥­¡¼¤È¥³¥ó¥È¥í¡¼¥ë¥­¡¼¤È»È¤¦
+ ɬÍפ¬¤¢¤ë¤È¤­¤Ï no ¤òÅú¤¨¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡£
+
+<!--
+<sect1> Monitor setup
+-->
+<sect1> ¥â¥Ë¥¿¤ÎÀßÄê
+<p>
+<!--
+ Setting up a monitor consists of entering the specifications
+ of your monitor and a description of the model and manufacturer.
+
+ You are first asked for the horizontal sync rate. It is
+ <bf/VERY/ important to enter the correct value(s) from the
+ manual. If one of the ranges given matches the rate of your
+ monitor, then pick it, otherwise pick <tt/custom/ and enter
+ the values from your manual.
+
+ Next is the vertical refresh rate. Again, it is <bf/VERY/
+ important that this parameter be specified correctly.
+ Enter it in a manner similar to the horizontal sync rate.
+
+ <it>If either rate is mis-specified, it can result in damage
+ to your monitor.</it>
+
+ Finally, you are asked for an "identifier", your monitor
+ manufacturer, and model. You can just press enter to
+ get through these quickly.
+-->
+ ¥â¥Ë¥¿¤Î»ÅÍͤȷ¿Ì¾¤ÈÀ½Â¤²ñ¼Ò¤Ë°ìÃפ¹¤ë¹àÌܤòÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ ºÇ½é¤Ë¿åʿƱ´ü¼þÇÈ¿ô¤òÄ´¤Ù¤Þ¤·¤ç¤¦¡£¥Þ¥Ë¥å¥¢¥ë¤ò¸«¤ÆÀµ¤·¤¤
+ ¿ôÃͤòÆþÎϤ¹¤ë¤³¤È¤Ï <bf/ÂçÊÑ/ ½ÅÍפǤ¹¡£¥â¥Ë¥¿¤Î¼þÇÈ¿ô¤È
+ ÆþÎϼþÇÈ¿ô¤ÎÈϰϤΤɤ줫¤¬¤Õ¤µ¤ï¤·¤¤¾ì¹ç¡¢¤½¤ì¤òÁªÂò¤·¡¢
+ ¤µ¤â¤Ê¤±¤ì¤Ð <tt/custom/ ¤òÁªÂò¤·¤Æ¥Þ¥Ë¥å¥¢¥ë¤Ëµ­ºÜ¤µ¤ì
+ ¤Æ¤¤¤ë¿ôÃͤòÆþÎϤ·¤Æ¤¯¤À¤µ¤¤¡£
+
+ ¼¡¤Ë¿âľƱ´ü¼þÇÈ¿ô¤Ç¤¹¡£¤³¤ì¤âÀµ³Î¤Ë»ØÄꤹ¤ë»ö¤Ï <bf/ÂçÊÑ/
+ ½ÅÍפǤ¹¡£¿åʿƱ´ü¼þÇÈ¿ô¤ÈƱ¤¸ÊýË¡¤ÇÆþÎϤ·¤Æ¤¯¤À¤µ¤¤¡£
+
+ <it>¤¤¤º¤ì¤«¤Î¼þÇÈ¿ô¤ò´Ö°ã¤¨¤ÆÀßÄꤷ¤¿¾ì¹ç¡¢¥â¥Ë¥¿¤òÄˤá¤ë
+ ¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£</it>
+
+ ºÇ¸å¤Ë¡¢"¼±ÊÌ̾" ("identifier")¤È¤·¤Æ¥â¥Ë¥¿¤ÎÀ½Â¤²ñ¼Ò¤È·¿Ì¾¤ò
+ Ä´¤Ù¤Æ¤¯¤À¤µ¤¤¡£¤³¤ì¤é¤ò¼êÁ᤯ÆþÎϤ·¤Æ¥¨¥ó¥¿¡¼¥­¡¼¤ò²¡¤·¤Æ
+ ²¼¤µ¤¤¡£
+
+<!--
+<sect1> Selecting your card
+-->
+<sect1> ¥Ó¥Ç¥ª¥«¡¼¥É¤ÎÁªÂò
+<p>
+<!--
+ You are next asked if you would like to view the database of
+ cards. Picking your card from the list will cause the answers
+ to the questions in the next two sections to be filled in for
+ you and so can save a little time.
+
+ If your card does not appear in the list, just press <tt/q/
+ and enter to skip on to the next step - where you'll have to
+ answer the questions yourself.
+-->
+ ¼¡¤Ë¥Ó¥Ç¥ª¥«¡¼¥É¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò¸«¤¿¤¤¤«Ê¹¤¤¤Æ¤­¤Þ¤¹¡£
+ °ìÍ÷¤«¤é¥Ó¥Ç¥ª¥«¡¼¥É¤òÁª¤Ö¤È¼¡¤Î£²¤Ä¤Î¾Ï¤Î¼ÁÌä¤ËÅú¤¨¤Æ
+ µ­Æþ¤¹¤ë¤³¤È¤Ç»þ´Ö¤¬¾¯¤·ÀáÌó¤Ç¤­¤Þ¤¹¡£
+
+ °ìÍ÷¤Ë¥Ó¥Ç¥ª¥«¡¼¥É¤¬¸«Åö¤¿¤é¤Ê¤¤¾ì¹ç¤Ï <tt/q/ ²¡¤·¤Æ¥¨¥ó¥¿¡¼
+ ¥­¡¼¤ò²¡¤·¤Æ¼¡¤ÎÃʳ¬¤òÈô¤Ð¤·¤Æ¤¯¤À¤µ¤¤¡£¤½¤·¤Æ¼«Ê¬¤ÇÌäÂê¤Ë
+ Åú¤¨¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£
+
+<!--
+<sect1> Server selection
+-->
+<sect1> ¥µ¡¼¥Ð¤ÎÁªÂò
+<p>
+<!--
+ If you selected your card in the previous step, then server
+ selection is easy - just use the recommendation from the
+ database.
+
+ If you have a card which uses one of the chipsets for which a
+ specific server exists (Mach8, Mach32, Mach64, AGX/XGA,
+ 8514/A, S3, ET4000/W32, I128, P9000) you'll want to pick the
+ <tt/accel/ option.
+
+ Otherwise you'll probably want to use the SVGA server.
+
+ Next, answer yes when the program asks if you want it to
+ set the symbolic link for you. If you picked the <tt/accel/
+ option, you'll also need to indicate which particular
+ accelerated server to link to.
+-->
+ Á°¤ÎÃʳ¬¤Ç¥Ó¥Ç¥ª¥«¡¼¥É¤òÁªÂò¤·¤¿¾ì¹ç¡¢¥µ¡¼¥Ð¤ÎÁªÂò¤ÏÍÆ°×¤Ç¤¹¡£
+ ¥Ç¡¼¥¿¥Ù¡¼¥¹¤«¤é¤Î¿äÁ¦¤µ¤ì¤¿¤â¤Î¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡£
+
+ ÆÃÄê¤Î¥µ¡¼¥Ð¤Î¥Á¥Ã¥×¥»¥Ã¥È(Mach8, Mach32, Mach64, AGX/XGA,
+ 8514/A, S3, ET4000/W32, I128, P9000)¤ÎÆâ¡¢¥Ó¥Ç¥ª¥«¡¼¥É¤¬
+ ¤É¤ì¤«¤Ê¤é¤Ð <tt/accel/ ¥ª¥×¥·¥ç¥ó¤òÁªÂò¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+ ¤â¤·¤½¤¦¤Ç¤Ê¤«¤Ã¤¿¤é¿ʬ SVGA ¥µ¡¼¥Ð¤ò»ÈÍѤ·¤¿¤¤¤Ç¤·¤ç¤¦¡£
+
+ ¼¡¤Ë¡¢¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤òÀßÄꤷ¤¿¤¤¥µ¡¼¥Ð¤¬¤¢¤ë¾ì¹ç¡¢
+ ¥×¥í¥°¥é¥à¤¬Ê¹¤¤¤Æ¤­¤¿¤é yes ¤òÅú¤¨¤Æ¤¯¤À¤µ¤¤¡£<tt/accel/
+ ¥ª¥×¥·¥ç¥ó¤òÁªÂò¤·¤¿¾ì¹ç¤Ï¡¢¥ê¥ó¥¯¤¹¤ëÆÃÄê¤Î¥¢¥¯¥»¥é¥ì¡¼
+ ¥¿¥µ¡¼¥Ð¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+
+<!--
+<sect1> Screen/Video configuration
+-->
+<sect1> ¥¹¥¯¥ê¡¼¥ó/¥Ó¥Ç¥ª¥«¡¼¥É¤Î¹½À®
+<p>
+<!--
+ Pick the appropriate option from the list to indicate the
+ amount of memory on your video card.
+
+ Then you are asked to provide and identifier, the manufacturer,
+ and the model of your card. You can just press enter to skip
+ through these, if you wish.
+
+ Next, the program will ask for the type of RAMDAC and Clockchip
+ on your card. If your card was in the database, you should
+ just to tell it to use the values from the database.
+
+ If you don't have one of the listed RAMDACs or Clockchips
+ on your card, just press enter when asked what type you have.
+ If you do not have a programmable clock chip, the program will
+ next attempt to probe to find out what clock rates are
+ supported by your clock chip.
+-->
+ ¥á¥â¥êÎ̤ȷ¿Ì¾°ìÍ÷¤«¤é¥Ó¥Ç¥ª¥«¡¼¥É¤ËÅëºÜ¤·¤Æ¤¤¤ëŬÀÚ¤Ê
+ ¥ª¥×¥·¥ç¥ó¤òÁªÂò¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+ ¤½¤Î¤È¤­Í¿¤¨¤ë¥Ó¥Ç¥ª¥«¡¼¥É¤Î¼±ÊÌ̾¡¢À½Â¤²ñ¼Ò¤È·¿Ì¾¤òÅú¤¨¤Æ
+ ¤¯¤À¤µ¤¤¡£¤³¤ÎÀßÄê¤òÈô¤Ð¤·¤¿¤¤¤È¤­¤Ï¡¢¤¿¤À¥¨¥ó¥¿¡¼¥­¡¼¤ò
+ ²¡¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+ ¼¡¤Ë¥Ó¥Ç¥ª¥«¡¼¥É¤Î RAMDAC ¤È¥Á¥Ã¥×¥»¥Ã¥È¤Î·¿Ì¾¤òÅú¤¨¤Æ¤¯¤À
+ ¤µ¤¤¡£¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¥Ó¥Ç¥ª¥«¡¼¥É¤¬¤¢¤ë¾ì¹ç¤Ï¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î
+ ¸¡º÷·ë²Ì¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ ¥Ó¥Ç¥ª¥«¡¼¥É¤Î RAMDAC ¤È¥Á¥Ã¥×¥»¥Ã¥È¤¬°ìÍ÷¤Ë¤Ê¤«¤Ã¤¿¾ì¹ç¡¢
+ ·¿Ì¾¤òʹ¤¤¤Æ¤­¤¿¤È¤³¤í¤Ç¤¿¤À¡¢¥¨¥ó¥¿¡¼¥­¡¼¤ò²¡¤·¤Æ²¼¤µ¤¤¡£
+ ¥×¥í¥°¥é¥Þ¥Ö¥ë¥¯¥í¥Ã¥¯¤Î¥Á¥Ã¥×¥»¥Ã¥È¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¾ì¹ç¡¢
+ ¥×¥í¥°¥é¥à¤¬¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¼þÇÈ¿ô¤ò
+ õ¤¹¤è¤¦¤ËõÃΤ·¤è¤¦¤È¤·¤Þ¤¹¡£
+
+<!--
+<sect1> Mode Selection
+-->
+<sect1> ¥â¡¼¥É¤ÎÁªÂò
+<p>
+<!--
+ Now you get to tell the program which video modes you would
+ like to be able to run.
+
+ The program will show you the common modes that should work
+ with your card (some might not work with your monitor, but
+ if you've correctly specified the monitor's sync rates, the
+ X server will just ignore them when it runs).
+
+ You could just accept the settings as they are given, but
+ you'll probably wish to reverse the order. For example, if
+ you have a card with 1 Meg RAM, it will list the modes
+ <tscreen><verb>
+ "640x480" "800x600" "1024x768" for 8bpp
+ </verb></tscreen>
+
+ Select <tt/1/ to change the settings for 8bpp and the type
+ <tt/432/ to select the reverse order.
+
+ When you've select the modes, in the order you wish, select
+ option <tt/4/ to continue.
+-->
+ ¤µ¤Æ¤É¤ó¤Ê¥Ó¥Ç¥ª¥â¡¼¥É¤ò¼Â¹Ô¤·¤¿¤¤¤Î¤«¤ò¥×¥í¥°¥é¥à¤Ë¶µ¤¨¤Þ
+ ¤·¤ç¤¦¡£
+
+ ¥×¥í¥°¥é¥à¤Ï¥Ó¥Ç¥ª¥«¡¼¥É¤¬Æ°ºî¤¹¤ë°ìÈÌŪ¤Ê¥Ó¥Ç¥ª¥â¡¼¥É¤ò
+ ɽ¼¨¤·¤Þ¤¹¡£(¤ª¼ê¸µ¤Î¥â¥Ë¥¿¡¼¤Ç¤Ï¤¤¤¯¤Ä¤«¤Î¥â¡¼¥É¤Ïưºî
+ ¤·¤Ê¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¤¬¡¢¥â¥Ë¥¿¤ÎƱ´ü¼þÇÈ¿ô¤òÀµ¤·¤¯ÀßÄê
+ ¤¹¤ì¤Ð¡¢X ¥µ¡¼¥Ð¤¬¼Â¹Ô»þ¤Ëư¤«¤Ê¤¤¥â¡¼¥É¤ò̵»ë¤¹¤ë¤Ç¤·¤ç
+ ¤¦¡£)
+
+ º£¤Þ¤Ç¤ÎÀßÄê¤ò¼õ¤±Æþ¤ì¤Æ¤â½ç½ø¤òÆþ¤ìÂØ¤¨¤¿¤¤¤È»×¤¦¤Ç¤·¤ç
+ ¤¦¡£Î㤨¤Ð 1 ¥á¥¬¥Ð¥¤¥È¤Î¥á¥â¥ê¤ò¥Ó¥Ç¥ª¥«¡¼¥É¤¬»ý¤Ã¤Æ¤¤
+ ¤¿¾ì¹ç¡¢¥Ó¥Ç¥ª¥â¡¼¥É¤ò
+ <tscreen><verb>
+ "640x480" "800x600" "1024x768" ¤ò 8bpp Âбþ¤Ë
+ </verb></tscreen>
+ ÀßÄꤷ¤Æ¤¤¤Þ¤¹¡£
+
+ <tt/1/ ¤òÁªÂò¤¹¤ë¤È 8bpp ¤ÎÀßÄê¤òÊѹ¹¤·¤Æ¡¢<tt/432/ ¤È
+ ÆþÎϤ¹¤ë¤ÈµÕ½ç¤òÁªÂò¤¹¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£
+
+ ÀßÄꤷ¤¿¤¤½ç½ø¤Î¥Ó¥Ç¥ª¥â¡¼¥É¤òÁªÂò¤·¤¿¤¤»þ¤Ï <tt/4/ ¤ò
+ ÁªÂò¤·¤ÆÂ³¤±¤Þ¤·¤ç¤¦¡£
+
+<!--
+<sect1> Creating the <tt>XF86Config</tt> file
+-->
+<sect1> <tt>XF86Config</tt> ¥Õ¥¡¥¤¥ë¤ÎºîÀ®
+<p>
+<!--
+ The program will now ask if you would like to write the
+ configuration settings you've selected to the file
+ <tt/XF86Config/. Answer yes.
+-->
+ ÀßÄꤷ¤¿¹½À®¾ðÊó¤ò <tt/XF86Config/ ¥Õ¥¡¥¤¥ë¤Ë½ñ¤­¹þ¤à
+ ¤È¤­¤Ë¥×¥í¥°¥é¥à¤¬Ê¹¤¤¤Æ¤­¤Þ¤¹¤Î¤Ç yes ¤òÅú¤¨¤Æ¤¯¤À¤µ¤¤¡£
+
+<!--
+<sect1> Some final notes
+-->
+<sect1> ºÇ½ªÃí°Õ»ö¹à
+<p>
+<!--
+ Lastly, the program tells you that it's finished its part
+ of this process and counsels you to check the file before
+ using it. The next section covers the changes that are most
+ likely to be needed.
+-->
+ ºÇ¸å¤Ë¤³¤Îºî¶È¤ò½ªÎ»¤¹¤ë³Îǧ¤È¹½À®¾ðÊó¥Õ¥¡¥¤¥ë¤ò³Îǧ¤·¤Æ
+ ¤«¤é»ÈÍѤ¹¤ë¤³¤È¤ÎÃé¹ð¤òɽ¼¨¤·¤Þ¤¹¡£¼¡¤Î¾Ï¤ÇɬÍפÊÊѹ¹¹àÌÜ
+ ¤Ë¤Ä¤¤¤ÆÀâÌÀ¤·¤Þ¤¹¡£
+
+<!--
+<sect> Fixing the XF86Config file
+-->
+<sect> XF86Config ¥Õ¥¡¥¤¥ë¤Î½¤Àµ
+<p>
+<!--
+ Use an editor to look at the <tt/XF86Config/ file. Here are
+ some things that may need to be changed:
+ <itemize>
+ <item>If you are running an operating system which has
+ built-in mouse support, you'll want to change the
+ <tt/Pointer/ section. Specifically, you should set
+ the <tt/Protocol/ to <tt/OSMouse/ (SCO) or <tt/Xqueue/
+ (SVR4, some SVR3) and you should remove the <tt/Device/
+ line.
+ <item>If you are running a system with the Xqueue event driver
+ and would like to use it, change the <tt/Protocol/
+ setting in the <tt/Keyboard/ section to <tt/Xqueue/.
+-->
+ <tt/XF86Config/ ¥Õ¥¡¥¤¥ë¤ò¥¨¥Ç¥£¥¿¤Ç³«¤¤¤Æ¸«¤Æ¤¯¤À¤µ¤¤¡£
+ Êѹ¹¤¹¤ëɬÍפ¬¤¢¤ëÉôʬ¤¬¤¢¤ê¤Þ¤¹¡£:
+ <itemize>
+ <item>¥Þ¥¦¥¹¥É¥é¥¤¥Ð¤òÆâ¢¤·¤Æ¤¤¤ë¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à
+ ¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç¡¢<tt/Pointer/ Àá¤òÊѹ¹¤·¤Þ¤·¤ç¤¦¡£
+ ÆÃ¤Ë¡¢<tt/Protocol/ ¤ò <tt/OSMouse/ (SCO ¤Î¾ì¹ç) ¤Ë
+ ¤Þ¤¿¤Ï¡¢<tt/Xqueue/(SVR4, ¤¤¤¯¤Ä¤«¤Î SVR3 ¤Î¾ì¹ç) ¤Ë
+ ÀßÄꤷ¤Æ <tt/Device/ ¹Ô¤òºï½ü¤·¤Æ¤¯¤À¤µ¤¤¡£
+ <item>Xqueue ¥¤¥Ù¥ó¥È¥É¥é¥¤¥Ð¼ã¤¯¤Ï»÷¤¿¤è¤¦¤Ê¥É¥é¥¤¥Ð¤ò
+ »ÈÍѤ·¤Æ¤¤¤ë¥·¥¹¥Æ¥à¤ò²ÔƯ»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç¡¢
+ <tt/Keyboard/ Àá¤Î <tt/Protocol/ ¤ÎÀßÄê¤ò <tt/Xqueue/
+ ¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+ </itemize>
+<!-- What else should be added here? -->
+<!-- ¤³¤³¤Ë²¿¤«Äɲ乤٤­¤³¤È¤Ï¤¢¤ê¤Þ¤¹¤«¡© -->
+
+<!--
+ Once you are satisfied that the configuration is correct, copy
+ the XF86Config file to <tt>/usr/X11R6/lib/X11</tt> and run
+ the 'startx' command.
+
+ You should now have a running X server. If it's running but
+ the display doesn't look as good as you think it should (i.e.
+ it doesn't fill the whole screen, it's off-center, it's wrapping
+ around on one side, etc.) see the section on <tt/xvidtune/.
+ If there is some other problem, see the troubleshooting section.
+-->
+
+ °ìö¡¢¹½À®¾ðÊó¤¬Àµ¤·¤¤¤ÈËþ­¤·¤¿¤é¡¢XF86Config ¥Õ¥¡¥¤¥ë¤ò
+ <tt>/usr/X11R6/lib/X11</tt> ¤Ë¥³¥Ô¡¼¤·¤Æ 'startx' ¥³¥Þ¥ó¥É
+ ¤ò¼Â¹Ô¤·¤Þ¤·¤ç¤¦¡£
+
+ ¤µ¤Æ X ¥µ¡¼¥Ð¤¬²ÔƯ¤·¤Þ¤·¤¿¡£X ¥µ¡¼¥Ð¤¬²ÔƯ¤·¤¿¤±¤ì¤É»×¤Ã¤¿
+ ¤è¤êÎɤ¤É½¼¨²èÌ̤ǤϤʤ¤ (Î㤨¤ÐÁ´²èÌÌɽ¼¨¤Ë¤Ê¤Ã¤Æ¤¤¤Ê¤¤¤È¤«¡¢
+ Ãæ±û¤«¤é¤Ï¤º¤ì¤Æ¤¤¤ë¤È¤«¡¢ÏƤ˲ö¤ê¹þ¤ó¤Ç¤¤¤ëÅù) ¾ì¹ç¡¢
+ <tt/xvidtune/ ¤Î¾Ï¤ò¸«¤Æ¤¯¤À¤µ¤¤¡£¤½¤Î¾¤ÎÌäÂ꤬¤¢¤ë¾ì¹ç¡¢
+ ¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°¤Î¾Ï¤ò¸«¤Æ¤¯¤À¤µ¤¤¡£
+<!--
+<sect> Running <tt>xvidtune</tt>
+-->
+<sect> <tt>xvidtune</tt> ¤ò¼Â¹Ô¤¹¤ë
+<p>
+<!--
+ If you need to make adjustments to the video display,
+ <tt/xvidtune/ is the tool to use.
+
+ Simply enter the command <tt/xvidtune/ from a shell prompt
+ within an xterm. Read the warning and click on <tt/OK/.
+ Next click on the <tt/Auto/ button.
+
+ Now click on whatever combination of <tt>Up/Down/Left/Right</tt>
+ <tt>Shorter/Taller/Wider/Narrower</tt> is need to adjust
+ the display to your liking.
+
+ If you are using a recent S3-based card there will be some
+ extra buttons and entries at the bottom (InvertVCLK, EarlySC,
+ and Blank Delays). These can help solve problems of the
+ display wrapping around a few pixels.
+-->
+ ²èÌÌɽ¼¨¤òÄ´À°¤·¤¿¤¤¾ì¹ç¡¢<tt/xvidtune/ ¥³¥Þ¥ó¥É¤¬»È¤¨¤Þ¤¹¡£
+
+ xterm ¤Î¥·¥§¥ë¥×¥í¥ó¥×¥È¤«¤éñ¤Ë <tt/xvidtune/ ¤ÈÆþÎϤ·¤Æ
+ ¤¯¤À¤µ¤¤¡£·Ù¹ð¤òÆÉ¤ó¤Ç <tt/OK/ ¤ò¥¯¥ê¥Ã¥¯¤·¤Æ¤¯¤À¤µ¤¤¡£
+ ¼¡¤Ë <tt/Auto/ ¥Ü¥¿¥ó¤ò¥¯¥ê¥Ã¥¯¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+ <tt>¾å/²¼/º¸/±¦</tt> (<tt>Up/Down/Left/Right</tt>) ¤ä
+ <tt>½Ä¾®/½ÄÂç/²£Âç/²£¾®</tt> (<tt>Shorter/Taller/Wider/Narrower</tt>)
+ ¤òÁȤ߹ç¤ï¤»¤Æ»×¤Ã¤¿¤È¤ª¤ê¤Îɽ¼¨¤ËÄ´À°¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+
+ ºÇ¶á¤Î S3 ÅëºÜ¤Î¥Ó¥Ç¥ª¥«¡¼¥É¤Ç¤Ï¤¤¤¯¤Ä¤«¤ÎÊ̤Υܥ¿¥ó¤È
+ ÆþÎϹàÌÜ (InvertVCLK, EarlySC ¤È Blank Delays) ¤¬²èÌ̤β¼¤Î
+ ¤Û¤¦¤Ë¤¢¤ë¤Ç¤·¤ç¤¦¡£¿ô¥Ô¥¯¥»¥ë¤Î²èÌ̤βö¤ê¹þ¤ß¤ÎÌäÂê¤ò²ò·è
+ ¤¹¤ëÊä½õ¤Ë¤Ê¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£
+
+<!--
+ Once the display has been adjusted properly, press the <tt/show/
+ button to printout the correct <tt/ModeLine/ to put in the
+ <tt/XF86Config/ to make the server always use the current
+ display settings. To aid in copying this information to your
+ XF86Config file, the modeline is also made the current
+ selection allowing you to just paste it into your editor.
+
+ If you would like to adjust your other modes, you can click
+ on the <tt/Next/ and <tt/Prev/ buttons to switch modes.
+
+ When you are through using <tt/xvidtune/ simply press on the
+ <tt/Quit/ button.
+-->
+ °ìö¤Á¤ã¤ó¤È²èÌ̤òÄ´Àᤷ¤¿¤é¡¢<tt/show/ ¥Ü¥¿¥ó¤ò²¡¤·¤ÆÀµ¤·¤¤
+ <tt/ModeLine/ ¤ò°õºþ¤·¤Æ¡¢¸½ºß¤Î²èÌ̤ÎÀßÄê¤ò¾ï»þ»È¤¦¤è¤¦¤Ë
+ <tt/XF86Config/ ¥Õ¥¡¥¤¥ë¤ËÀßÄꤷ¤Þ¤·¤ç¤¦¡£¸½ºß¤Î²èÌ̾ðÊó¤ò
+ XF86Config ¥Õ¥¡¥¤¥ë¤Ë¥³¥Ô¡¼¤¹¤ë´Êñ¤ÊÊýË¡¤Ï¡¢¸½ºß¤Î
+ modeline ¤ÎÀßÄê¤ò¥¨¥Ç¥£¥¿¤ÎÊý¤Ë¥Ú¥¤¥¹¥È¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+ ¾¤Î¥Ó¥Ç¥ª¥â¡¼¥É¤òÄ´À°¤·¤¿¤¤¾ì¹ç¤Ï¡¢<tt/Next/ ¤È <tt/Prev/
+ ¥Ü¥¿¥ó¤ò¥¯¥ê¥Ã¥¯¤·¤Æ¥Ó¥Ç¥ª¥â¡¼¥É¤òÀÚ¤êÂØ¤¨¤Æ²¼¤µ¤¤¡£
+
+ <tt/xvidtune/ ¤ò½ª¤ï¤ê¤¿¤¤¤È¤­¤Ïñ¤Ë <tt/Quit/ ¥Ü¥¿¥ó¤ò²¡¤·
+ ¤Æ¤¯¤À¤µ¤¤¡£
+<!--
+<sect> Troubleshooting
+-->
+<sect> ¥È¥é¥Ö¥ë¥·¥å¡¼¥Æ¥£¥ó¥°
+<p>
+<!--
+ Since you're reading this, something must not have gone
+ the way you had hoped (or else you just really enjoy reading).
+
+ Below are listed some common problems that may occur
+ during configuration and some hints for solving them.
+ However, there are just too many different combinations
+ of hardware and software configurations, and, well, just
+ too many things that can go wrong, for this document
+ and the tools it documents, to cover every case.
+
+ If after trying the steps in the previous sections and
+ checking the hints in this section, you still are unable
+ to get your system working, you'll have to read the full
+ documentation. Read the README file for your card and
+ OS (if they exist), the XFree86 Configuration Guide
+ (README.Config), and the XF86Config man page.
+-->
+ ¤³¤³¤Þ¤ÇÆÉ¤ó¤Ç¤¤¤ë¤Î¤Ï¡¢²¿¤«Ë¾¤ó¤ÀÄ̤ê¤Î·ë²Ì¤¬ÆÀ¤é¤ì¤Æ
+ ¤¤¤Ê¤¤¡Ê¤Þ¤¿¤Ï¡¢³Ú¤·¤ó¤ÇÆÉ¤ó¤Ç¤¤¤¿¤À¤¤¤Æ¤¤¤ë¡Ë¤Î¤Ç¤·
+ ¤ç¤¦¡£
+
+ °Ê²¼¤Ï°ìÍ÷¤Ë¤Ê¤Ã¤¿¤¤¤¯¤Ä¤«¤Î°ìÈÌŪ¤ÊÀßÄêºî¶ÈÃæ¤ËÎɤ¯À¸
+ ¤¸¤ëÌäÂê¤ä²ò·è¤Î¥Ò¥ó¥È¤Ç¤¹¡£¤·¤«¤·¤Ê¤¬¤é¡¢¥Ï¡¼¥É¥¦¥§¥¢¤È
+ ¥½¥Õ¥È¥¦¥§¥¢¤ÎÀßÄê¤ÎËÄÂç¤ÊÁȤ߹ç¤ï¤»¤¬¤¢¤ê¡¢¤½¤³¤Ç¡¢
+ ËÄÂç¤ÊÉÔ¶ñ¹ç¤¬À¸¤¸¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£¤³¤Îʸ½ñ¤È¥Ä¡¼¥ë¤Î
+ ʸ½ñ¤Ç¤ÏÁ´¤Æ¤Î¾ì¹ç¤Ë¤Ä¤¤¤Æ¸ÀµÚ½ÐÍè¤Þ¤»¤ó¡£
+
+ Á°¤Î¾Ï¤Ç»î¹Ô¤·¤¿ºî¶È¤È¤³¤Î¾Ï¤Ç¤Î¥Ò¥ó¥È¤ò³Îǧ¤·¤¿¸å¤Ç¡¢
+ ¥·¥¹¥Æ¥à¤¬²ÔƯ¤·¤Ê¤¤¾ì¹ç¤Ï¡¢Á´¤Æ¤Îʸ½ñ¤òÆÉ¤àɬÍפ¬
+ ¤¢¤ê¤Þ¤¹¡£¤ª¼ê¸µ¤Î¥Ó¥Ç¥ª¥«¡¼¥É¤È OS (¤â¤·¤¢¤ì¤Ð)
+ ¤ËÂбþ¤·¤Æ¤¤¤ë README ¥Õ¥¡¥¤¥ë ¤È ¡ÖXFree86 ¤ÎÀßÄê¤Ë¤Ä¤¤¤Æ¡×
+ (XFree86 Configuration Guide : README.Config) ¤È XF86Config
+ ¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë ¤òÆÉ¤ó¤Ç¤¯¤À¤µ¤¤¡£
+
+<!--
+ You should also look at
+ <url name="the XFree86 FAQ" url="http://www.XFree86.org/FAQ">
+ for more up-to-date information,
+ especially if you are trying to configure a fairly new card.
+
+ If all else fails, you can try posting a message to
+ comp.windows.x.i386unix or comp.os.linux.x or send email
+ to XFree86@XFree86.org.
+-->
+ ÆÃ¤Ë¤«¤Ê¤ê¿·¤·¤¤¥Ó¥Ç¥ª¥«¡¼¥É¤Ë¤Ä¤¤¤Æ¤ÎºÇ¿·¤Î¾ðÊó¤Ï
+ <url name="the XFree86 FAQ" url="http://www.XFree86.org/FAQ">
+ ¤â¡¢¸«¤Æ¤¯¤À¤µ¤¤¡£
+
+ Á´Á³ÂÌÌܤʾì¹ç¤Ï¡¢comp.windows.x.i386unix ¤« comp.os.linux.x
+ ¤Ëµ­»ö¤òÅê¹Æ¤·¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£¤Þ¤¿¤Ï XFree86@XFree86.org ¤Ë
+ ÅŻҥ᡼¥ë¤òÁ÷¤Ã¤Æ¤¯¤À¤µ¤¤¡£[ÌõÃí : ±Ñ¸ì¤Ç¤ª´ê¤¤¤·¤Þ¤¹:-)]
+
+<!--
+<sect1> The mouse doesn't move correctly, it stays in one area of the screen
+-->
+<sect1> ¥Þ¥¦¥¹¤¬¤Á¤ã¤ó¤Èư¤«¤Ê¤¤¡£¤Ä¤Þ¤ê²èÌ̤ËÄ¥¤êÉÕ¤¤¤¿¤Þ¤Þư¤«¤Ê¤¤¡£
+<p>
+<!--
+ You've selected the wrong protocol for your mouse. Try a
+ different one.
+-->
+ ÁªÂò¤·¤¿¥Þ¥¦¥¹¤Î¥×¥í¥È¥³¥ë¤¬Îɤ¯¤¢¤ê¤Þ¤»¤ó¡£°ã¤¦¥×¥í¥È¥³¥ë¤ò
+ »î¤·¤Æ¤ß¤Þ¤·¤ç¤¦¡£
+
+<!--
+<sect1> The server doesn't start, it says the mouse is busy.
+-->
+<sect1> ¥µ¡¼¥Ð¤¬µ¯Æ°¤·¤Ê¤¤¡£¤³¤Î»þ¥Þ¥¦¥¹¤¬»ÈÍѺѤߤǤ¢¤ë¤Èɽ¼¨¤µ¤ì¤ë¡£
+<p>
+<!--
+ Well, it's probably right. This most often happens on
+ Linux systems that have <tt/gpm/ running. Kill the <tt/gpm/
+ process and try <tt/startx/ again.
+-->
+ ¤µ¤Æ¡¢¤³¤Î¿ÇÃǤÏ¿ʬÀµ¤·¤¤¤Ç¤·¤ç¤¦¡£¤³¤Î¸½¾Ý¤Ï Linux ¥·¥¹¥Æ¥à
+ ¤Ç <tt/gpm/ ¤¬Æ°ºî¤·¤Æ¤¤¤ë»þ¤ËÎɤ¯µ¯¤³¤ê¤Þ¤¹¡£<tt/gpm/
+ ¥×¥í¥»¥¹¤ò»ß¤á¤Æ <tt/startx/ ¤ò¤â¤¦°ìÅټ¹Ԥ·¤Æ¤¯¤À¤µ¤¤¡£
+
+<!--
+<sect1> The middle button doesn't work.
+-->
+<sect1> ¿¿¤óÃæ¤Î¥Ü¥¿¥ó¤¬»ÈÍѽÐÍè¤Ê¤¤¡£
+<p>
+<!--
+ There's no easy answer to this one. It's a lot of trial
+ and error. You need to make sure you're running the right
+ protocol for your mouse.
+
+ Many three button mice are "dual protocol" which means that
+ they have both a 2-button and 3-button mode. The way to get
+ the mouse to switch into 3-button mode (which usually then
+ uses MouseSystems protocol) varies between different models.
+
+ You may need to slide a switch on the mouse or hold down the
+ middle button when starting the server. Other methods of
+ switching modes can be done by the server, you just have to
+ find the right combination of settings for your mouse. See
+ the Pointer section of the XF86Config man page for a complete
+ list of settings.
+-->
+ ¤³¤Î¸½¾Ý¤Ï´Êñ¤Ê²ò·èºö¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤¿¤¯¤µ¤ó»î¹Ôºø¸í¤¬É¬Í×
+ ¤Ç¤¹¡£¥Þ¥¦¥¹¤Î¥×¥í¥È¥³¥ë¤¬Àµ¤·¤¤¤«³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+ ¿¤¯¤Î£³¥Ü¥¿¥ó¥Þ¥¦¥¹¤Ï£²¥Ü¥¿¥ó¥â¡¼¥É¤È£³¥Ü¥¿¥ó¥â¡¼¥É¤Î
+ "ξÊý¤Î¥×¥í¥È¥³¥ë" ¤ò»ý¤Ã¤Æ¤¤¤Þ¤¹¡££³¥Ü¥¿¥ó¥â¡¼¥É¤Ø¤Î
+ ÀÚ¤êÂØ¤¨ÊýË¡ (Ä̾ï MouseSystems ¥×¥í¥È¥³¥ë¤òÍѤ¤¤Þ¤¹) ¤Ï
+ ¥Þ¥¦¥¹¤Î¼ïÎà¤Ë¤è¤Ã¤Æ¿§¡¹¤Ç¤¹¡£
+
+ ¥µ¡¼¥Ð¤Îµ¯Æ°»þ¤Ë¥Þ¥¦¥¹¤ËÉÕ¤¤¤Æ¤¤¤ë¥¹¥¤¥Ã¥Á¤òư¤«¤¹¤«¡¢
+ ¿¿¤óÃæ¤Î¥Ü¥¿¥ó¤ò²¡¤·Â³¤±¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£Â¾¤Î¥â¡¼¥É
+ ÀÚ¤êÂØ¤¨¤Î¥µ¡¼¥Ð¦¤Ç¹Ô¤¦ÊýË¡¤Ï¡¢¥Þ¥¦¥¹¤ÎÀßÄê¤ÎÁȤ߹ç¤ï¤»¤ò
+ Àµ¤·¤¯¹Ô¤ï¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£´°àú¤ÊÀßÄê¤Î°ìÍ÷¤¬
+ XF86Config ¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤Î Pointer ¤Î¾Ï¤Ë¤¢¤ë¤Î¤Ç
+ ¤ß¤Æ¤¯¤À¤µ¤¤¡£
+
+<!--
+<sect1> The display is shifted to the left/right/top/bottom
+-->
+<sect1> ²èÌ̤¬¾å²¼º¸±¦¤ËÊÒ´ó¤ë¡£
+<p>
+<!--
+ See the section on xvidtune.
+-->
+ xvidtune ¤Î¾Ï¤ò¤ß¤Æ¤¯¤À¤µ¤¤¡£
+
+<!--
+<sect1> I don't appear to have xf86config or xvidtune on my system
+-->
+<sect1> xf86config ¤Þ¤¿¤Ï xvidtune ¤¬¥·¥¹¥Æ¥à¤ÎÃæ¤Ë¸«¤Ä¤±¤é¤ì¤Ê¤¤¡£
+<p>
+<!--
+ Hmmm. Three possibilities:
+ <enum>
+ <item>You have a version of XFree86 that is older than 3.1.2.
+ If this is the case then you probably aren't reading
+ this document either, because it wasn't included in
+ 3.1.2 and earlier releases. Please upgrade to the
+ latest version.
+ <item>Your <tt/PATH/ is not set correctly. Make sure it includes
+ the bin directory for the XFree86 binaries (usually,
+ <tt>/usr/X11R6/bin</tt>
+ <item>You don't have a complete installation of XFree86.
+ Go back to wherever you got XFree86 and get the missing
+ pieces.
+ </enum>
+-->
+ ¤¦¡¼¤ó¡££³¤Ä¤Î²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£
+ <enum>
+ <item>3.1.2 ¤è¤ê¸Å¤¤¥Ð¡¼¥¸¥ç¥ó¤Î XFree86 ¤ò»È¤Ã¤Æ¤¤¤ë¡£
+ ¿ʬ¡¢¤³¤Îʸ½ñ°Ê³°¤òÆÉ¤ó¤Ç¤¤¤Ê¤¤¾ì¹ç¤Ï 3.1.2 ¤È¤½¤ì¤è¤êÁ°¤Î
+ ¥Ð¡¼¥¸¥ç¥ó¤Ë¤Ï xf86config ¤Þ¤¿¤Ï xvidtune ¤Ï´Þ¤Þ¤ì¤Æ¤¤¤Ê¤¤
+ ¤«¤é¤Ç¤¹¡£ºÇ¿·¥Ð¡¼¥¸¥ç¥ó¤Ë¹¹¿·¤·¤Æ¤¯¤À¤µ¤¤¡£
+ <item><tt/PATH/ ¤¬Àµ¤·¤¯ÀßÄꤵ¤ì¤Æ¤¤¤Ê¤¤¡£XFree86 ¤Î¥Ð¥¤¥Ê¥ê¤Î
+ bin ¥Ç¥£¥ì¥¯¥È¥ê¤ò´Þ¤ó¤Ç¤¤¤ë¤«³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£(Ä̾ï¤Ï
+ <tt>/usr/X11R6/bin</tt>¤Ç¤¹)
+ <item>XFree86 ¤ò´°Á´¤ËƳÆþ¤·¤Æ¤¤¤Ê¤¤¡£
+ XFree86 ¤òÆþ¼ê¤·¤¿¤È¤³¤í¤ØÌá¤Ã¤Æ¡¢»Ä¤é¤ºÆþ¼ê¤·¤Æ¤¯¤À¤µ¤¤¡£
+ </enum>
+
+<!-- Lots of things still need to be added -->
+<!-- ¤³¤³¤Ë²¿¤«Äɲ乤٤­¤³¤È¤Ï¤¢¤ê¤Þ¤¹¤«¡© -->
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/QStart.sgml,v 3.1 1997/01/26 04:34:22 dawes Exp $
+</verb>
+<hrule>
+
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ï xc/programs/Xserver/hw/xfree86/doc/sgml/QStart.sgml,v 3.2 1996/08/27 03:21:12 ¤ò¡¢²¬ËÜ °ì¹¬
+( Kazuyuki Okamoto <url url="mailto:ikko-@pacific.rim.or.jp"
+name="&lt;ikko-@pacific.rim.or.jp&gt;"> ) ¤¬ XFree86 3.2 ¤ò
+ÆüËܤǥ¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¿Í¸þ¤±¤ËÏÂÌõ¤·¤¿¤â¤Î¤Ç¤¹¡£¤³¤³¤¬¤ª¤«¤·¤¤¤È¤«¡¢
+¤³¤³¤Ï¤³¤¦¤·¤¿¤Û¤¦¤¬¤¤¤¤¤È¤¤¤Ã¤¿¤´°Õ¸«¤¬¤¢¤ê¤Þ¤·¤¿¤é¡¢ÅŻҥ᡼¥ë¤Ç
+¤ªÃΤ餻²¼¤µ¤¤¡£
+¸¶Ê¸¤ÎÃøºî¸¢¤Ï XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ÎÏÂÌõ¤ÎÃøºî¸¢¤Ï
+XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤È²¬ËÜ¡¡°ì¹¬¤Ë¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤ÎÏÂÌõ¤ÎÉÔ¶ñ¹ç¤Ï»ä¤Ë¡¢
+ÅŻҥ᡼¥ë¤ÇÁ÷¤Ã¤Æ²¼¤µ¤¤¡£
+<hrule>
+&lsqb;EOF&rsqb;
+</article>
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/README.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/README.sgml
new file mode 100644
index 000000000..8d84dc22b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/README.sgml
@@ -0,0 +1,1007 @@
+<!doctype linuxdoc system>
+
+ <article>
+
+ <title>XFree86&tm; 3.2 ¤Î¤¿¤á¤Î README
+ <author> XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò
+ <date>1996 ǯ 10 ·î 26 Æü
+ <trans> ²¬ËÜ¡¡°ì¹¬ Kazuyuki Okamoto &lt;ikko-@pacific.rim.or.jp&gt;
+
+<abstract>
+
+XFree86 ¤È¤Ï¥¤¥ó¥Æ¥ë¾å¤Çư¤¯¤¤¤¯¤Ä¤«¤Î¥Ð¡¼¥¸¥ç¥ó¤Î Unix ¤È Unix ¤Ë»÷¤Æ¤¤¤ë
+¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë X11R6.1 ¤Ë°Ü¿¢¤·¤¿¤â¤Î¤Ç¤¹¡£º£²ó
+¤ÎÈǤǤϡ¢Â¿¤¯¤Î¥Ð¥°¤Î½¤Àµ¤ÈƱ»þ¤Ë¿·¤·¤¤µ¡Ç½¤ÎÄɲääÀ­Ç½¤Î¸þ¾å¤ò¿Þ¤ê
+¤Þ¤·¤¿¡£XFree86 ¤Ï¿¤¯¤Î¥¢¡¼¥­¥Æ¥¯¥Á¥ãÍѤΥХ¤¥Ê¥êÇÛÉÕʪ¤ÈƱÍÍ¤Ë X ¥³¥ó¥½
+¡¼¥·¥¢¥à¤Î X11R6.1 ¤Î¥½¡¼¥¹¥³¡¼¥É¤ËÂФ·¤Æ¤Î¥Ñ¥Ã¥Á¥Ç¡¼¥¿¤È¤·¤ÆÆþ¼ê²Äǽ¤Ç¤¹¡£
+</abstract>
+
+<toc>
+
+<sect> XFree86 3.2 ¤Ç²¿¤¬¿·¤·¤¯¤Ê¤Ã¤¿¤« ?
+<p>
+
+¼¡¤Î¹àÌܤò1995 ǯ 8·î ¤Ë¸ø³«¤·¤¿ XFree86 3.1.2 ¤Ëµ¡Ç½Äɲä·¤Þ¤·
+¤¿¡£:
+<enum>
+ <item> XFree86 3.2 ¤Ï X ¥³¥ó¥½¡¼¥·¥¢¥à¤Î X11R6.1 ¤ò´Þ¤ó¤Ç¤¤¤Þ¤¹¡£
+ <item> OS/2 ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item> DEC Alpha/AXP ¤Ç Linux/AXP (ECOFF ¤È ELF ¤ÎξÊý)¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item> Linux/m68k ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item> ÆüËܤΠPC98 ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item> ¿·¤·¤¤¥°¥é¥Õ¥£¥Ã¥¯ÀßÄê¥æ¡¼¥Æ¥£¥ê¥Æ¥£¤Î <em>XF86Setup</em>
+ <item> S3 Trio64V+ ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item> S3 ViRGE ¤È ViRGE/VX ÍѤο·¤·¤¤¥µ¡¼¥Ð (XF86_S3V)
+ <item> S3 868, 968 ¤È Trio64V+ ¥Á¥Ã¥×¥»¥Ã¥ÈÂбþ¥É¥é¥¤¥Ð
+ "newmmio" ÍѤΠS3 ¥µ¡¼¥Ð ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item> Mach64 ¥«¡¼¥É (GX rev 3, CT, VT, GT) ¤òÄɲ嵥ݡ¼¥È¤·¤Þ¤·¤¿¡£
+ <item> ET6000 ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item> ¤¤¤¯¤Ä¤«¤Î¿·¤·¤¤ Cirrus ¥Á¥Ã¥×¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item> Trident TGUI ¥Á¥Ã¥×¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item> Number Nine Imagine 128 ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item> Matrox Millennium ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item> NVidia NV1 / SGS Thomson STG2000 ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item> ¤¤¤¯¤Ä¤«¤Î SiS ¥Á¥Ã¥×¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item> Chips &amp; Technologies ¥Á¥Ã¥×¤òÄɲ嵥ݡ¼¥È¤·¤Þ¤·¤¿¡£
+ <item> DEC 21030 (aka DEC TGA; Linux/AXP ¤Î¤ß)¤òÄɲ嵥ݡ¼¥È¤·¤Þ¤·¤¿¡£
+ <item> DGA ¥µ¡¼¥Ð µ¡Ç½³ÈÄ¥¡£
+ <item> XInput µ¡Ç½³ÈÄ¥¤ò¼ÂÁõ¤·¤Þ¤·¤¿¡£
+</enum>
+
+¤µ¤é¤Ê¤ë¾ðÊó¤Ï<htmlurl name="RELNOTE" url="RELNOTE.html"> ¥Õ¥¡¥¤¥ë
+¤Ë¤¢¤ê¤Þ¤¹¡£Êѹ¹¤Î¾ÜºÙ¤Ê°ìÍ÷¤Ï¥½¡¼¥¹ÇÛÉÛʪ¤Ë¤¢¤ë CHANGELOG ¥Õ¥¡¥¤¥ë¤ò
+»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+<sect> XFree86 ¤Î¥Æ¥¹¥È¤ò¹Ô¤Ã¤¿¥·¥¹¥Æ¥à
+Ãí°Õ: ¸½ºß¤Î¥Ð¡¼¥¸¥ç¥ó¤Ï¤³¤³¤Ë°ìÍ÷¤Ë¤·¤¿Á´¤Æ¤Î¥·¥¹¥Æ¥à¤Ç¥Æ¥¹¥È¤·¤Æ¤Ï¤¤¤Þ¤»¤ó¡£
+<p>
+
+ <DESCRIP>
+ <tag/SVR4.0:/
+ <itemize>
+ <ITEM>Esix: 4.0.3A, 4.0.4, 4.0.4.1
+ <ITEM>Microport: 2.2, 3.1, 4.1, 4.2
+ <ITEM>Dell: 2.1, 2.2, 2.2.1
+ <ITEM>UHC: 2.0, 3.6
+ <ITEM>Consensys: 1.2
+ <ITEM>MST: 4.0.3 (Load 2.07 and Load 3.02)
+ <ITEM>ISC: 4.0.3
+ <ITEM>AT&amp;T: 2.1, 4.0
+ <ITEM>NCR: MP-RAS
+ <ITEM>SunSoft: Solaris x86 2.1, 2.4, 2.5
+ <ITEM>PANIX 5.0 for AT
+ </itemize>
+
+ <tag/SVR4.2:/
+ <itemize>
+ <ITEM>Consensys
+ <ITEM>Novell UnixWare
+ </itemize>
+
+ <tag/SVR3:/
+ <itemize>
+ <ITEM>SCO: 3.2.2, 3.2.4
+ <ITEM>ISC: 3.0, 4.0, 4.1
+ </itemize>
+
+ <tag/Others:/
+ <itemize>
+ <ITEM>NetBSD 1.0, 1.1, 1.2
+ <ITEM>OpenBSD 2.0
+ <ITEM>FreeBSD 1.1.5.1, 2.0.5, 2.1, 2.1.5, 2.2-current
+ <ITEM>BSD/386 1.1, BSD/OS 2.0
+ <ITEM>Mach 386
+ <ITEM>Linux (Intel x86, DEC Alpha/AXP ¤È m68k)
+ <ITEM>Amoeba
+ <ITEM>Minix-386
+ <ITEM>LynxOS AT 2.2.1, 2.3.0, 2.4.0
+ <ITEM>LynxOS microSPARC 2.4.0
+ </itemize>
+
+ <tag/PC98:/
+ <itemize>
+ <ITEM>FreeBSD(98) 2.0.5, 2.1, 2.1.5, 2.2-current
+ <ITEM>NetBSD/pc98 (NetBSD 1.2 ¤ò´ð¤Ë¤·¤¿)
+ <ITEM>98 ÍÑ PANIX 5.0
+ </itemize>
+
+ </DESCRIP>
+
+<sect> ¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¥Ó¥Ç¥ª¥«¡¼¥É¤Î¥Á¥Ã¥×¥»¥Ã¥È
+<p>
+
+¸½ºß¡¢XFree86 3.2 ¤Ï¼¡¤Î¥¢¥¯¥»¥é¥ì¡¼¥¿¥Á¥Ã¥×¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹:
+
+ <DESCRIP>
+ <tag>8514/A </tag>
+ (¤È¡¢¤½¤Î¤½¤Ã¤¯¤ê¤µ¤ó)
+ <tag/ATI /
+ Mach8, Mach32, Mach64
+ <tag/Cirrus /
+ CLGD5420, CLGD5422, CLGD5424, CLGD5426, CLGD5428, CLGD5429,
+ CLGD5430, CLGD5434 CLGD5436, CLGD5440, CLGD5446, CLGD5462,
+ CLGD5464
+ <tag/S3 /
+ 86C911, 86C924, 86C801, 86C805, 86C805i, 86C928, 86C864, 86C964,
+ 86C732, 86C764, 86C765, 86C868, 86C968, 86C325, 86C988
+ <tag/Western Digital /
+ WD90C31, WD90C33, WD90C24A
+ <tag/Weitek /
+ P9000
+ <tag/IIT /
+ AGX-014, AGX-015, AGX-016
+ <tag/IBM /
+ XGA-2
+ <tag/Tseng /
+ ET4000/W32, ET4000/W32i, ET4000/W32p, ET6000
+ <tag/Oak Technologies Inc/
+ OTI087
+ <tag/Ark Logic/
+ ARK1000PV, ARK1000VL, ARK2000PV, ARK2000MT
+ <tag/Matrox/
+ MGA2064W
+ <tag/Number Nine/
+ I128 (not accelerated yet)
+ </DESCRIP>
+
+Cirrus, Western Digital, Oak, ARK, Chips &amp; Technologies ¤È
+Matrox ¥¢¥¯¥»¥é¥ì¡¼¥¿¤Ï SVGA ¥µ¡¼¥Ð¤Ç¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£
+¤½¤Î¾¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ï¤½¤ì¼«¿ÈÍѤΥµ¡¼¥Ð¤Ç¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£
+
+²Ã¤¨¤Æ¡¢¼¡¤Î SVGA ¥Á¥Ã¥×¥»¥Ã¥È¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£:
+ <DESCRIP>
+ <tag/Tseng /
+ ET3000, ET4000AX, ET4000/W32, ET6000
+ <tag>Western Digital/Paradise </tag>
+ PVGA1
+ <tag/Western Digital /
+ WD90C00, WD90C10, WD90C11, WD90C24, WD90C24A, WD90C30, WD90C31,
+ WD90C33
+ <tag/Genoa /
+ GVGA
+ <tag/Trident /
+ TVGA8800CS, TVGA8900B, TVGA8900C, TVGA8900CL, TVGA9000,
+ TVGA9000i, TVGA9100B, TVGA9200CX, TVGA9320, TVGA9400CX,
+ TVGA9420, TGUI9420DGi, TGUI9430DGi, TGUI9440AGi, TGUI9660XGi,
+ TGUI9680
+ <tag/ATI /
+ 18800, 18800-1, 28800-2, 28800-4, 28800-5, 28800-6, 68800-3,
+ 68800-6, 68800AX, 68800LX, 88800GX-C, 88800GX-D, 88800GX-E,
+ 88800GX-F, 88800CX, 264CT, 264ET, 264VT, 264VT2, 264GT
+ <tag/NCR /
+ 77C22, 77C22E, 77C22E+
+ <tag/Cirrus Logic /
+ CLGD5420, CLGD5422, CLGD5424, CLGD5426, CLGD5428,
+ CLGD5429, CLGD5430, CLGD5434, CLGD5436, CLGD5440, CLGD5446, CLGD5462,
+ CLGD5464, CLGD6205, CLGD6215,
+ CLGD6225, CLGD6235, CLGD6410, CLGD6412, CLGD6420,
+ CLGD6440
+<!--
+ <tag/Compaq /
+ AVGA
+-->
+ <tag/OAK /
+ OTI067, OTI077, OTI087
+ <tag/Avance Logic /
+ ALG2101, ALG2228, ALG2301, ALG2302, ALG2308, ALG2401
+ <tag/Chips &amp; Technologies /
+ 65520, 65530, 65540, 65545, 65520, 65530, 65540,
+ 65545, 65546, 65548, 65550, 65554
+ <tag/MX /
+ MX68000, MX680010
+ <tag>Video 7/Headland Technologies </tag>
+ HT216-32
+ <tag/SiS /
+ 86C201, 86C202, 86C205
+ <tag/ARK Logic/
+ ARK1000PV, ARK1000VL, ARK2000PV, ARK2000MT
+ <tag/RealTek/
+ RTG3106
+ <tag/Alliance/
+ AP6422
+ <tag/Matrox/
+ MGA2064W
+ <tag>NVidia/SGS Thomson </tag>
+ NV1, STG2000
+</DESCRIP>
+
+¾åµ­¤ÎÁ´¤Æ¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ï¡¢256 ¿§¤ÈÇò¹õ¤ÎξÊý¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¤¬¡¢¤¤¤¯¤Ä¤«
+¤ÏÇò¹õ¤È 16 ¿§¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£
+
+¤³¤ì¤é¤Î¥Á¥Ã¥×¥»¥Ã¥È¤ò»È¤¦°Ù¤Î¡¢¤è¤ê¿¤¯¤Î¾ðÊó¤Ï¡¢¥Á¥Ã¥×¥»¥Ã¥È¸ÇÍ­¤Î
+<tt>README</tt> ¥Õ¥¡¥¤¥ë¡Ê¸½ºß¤Ï Tseng, Western Digital, ATI, ARK, Trident,
+Oak, Matrox, NVidia ¤È Video 7 ¤¬³ºÅö¤·¤Þ¤¹¡Ë¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡£
+
+64k ¤Î¥·¥ó¥°¥ë¥Ð¥ó¥¯¤Î¥Ó¥Ç¥ª¥á¥â¥ê¤ò»ÈÍѤ·¤Æ¤¤¤ë°ìÈÌŪ¤Ê VGA ¥«¡¼¥É¡Ê
+<!--
+Hercules Çò¹õ¥«¡¼¥É¡¢
+-->
+¸½Âå¡Ê Hyundai ¡ËHGC1280¡¢Sigma LaserView Visa Çò¹õ
+¥«¡¼¥É¤È Apollo Çò¹õ¥«¡¼¥É¡Ë¤ò¡¢Çò¹õ¥µ¡¼¥Ð¡¼¤Ï¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£64k ¥Ð¥¤
+¥È¤Î¥Ó¥Ç¥ª¥á¥â¥ê¤À¤±¤ò»ý¤Ã¤Æ¤¤¤ë Compaq AVGA ¤âÇò¹õ¥µ¡¼¥Ð¡¼¤Ç¥µ¥Ý¡¼¥È¤·¤Æ
+¤¤¤Þ¤¹¤¬¡¢64k ¥Ð¥¤¥È°Ê¾å¤Î¥Ó¥Ç¥ª¥á¥â¥ê¤Ç¤Ï¡¢GVGA ¤Ï̤¤À¥Æ¥¹¥È¤·¤Æ¤Þ¤»¤ó¡£
+
+VGA16 ¥µ¡¼¥Ð¡¼¤Ï 1MB ¤Î¥Ó¥Ç¥ª¥á¥â¥ê¤òÅëºÜ¤·¤¿»þ¡¢Ìó 1600x1200 °Ê¾å¤Î²¾ÁÛ²è
+ÌÌɽ¼¨¤¬²Äǽ¤Ê ET4000¡¢Trident¡¢ATI¡¢NCR¡¢OAK ¤È Cirrus 6420 ¤òÀѤó¤À¥á¥â
+¥ê¥Ð¥ó¥¯¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£Â¾¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Î¾ì¹ç¤Ï¡¢²èÌ̤ÎÂ礭¤µ¤ÏÌó
+800X600 ¤ËÀ©¸Â¤µ¤ì¤Þ¤¹¡£
+
+
+<bf>Ãí°Õ :</bf>
+ Diamond ¼Ò¤¬ ET4000 ¤ò»È¤Ã¤Æ¤¤¤ë¤È¤·¤Æ¤â¡¢Diamond SpeedStar 24 ¥Ü¡¼
+¥É¤Ï¡Ê¿ʬ¤¤¤¯¤Ä¤«¤Î¤Î SpeedStar+ ¤â¡Ë¥µ¥Ý¡¼¥È¤·¤Þ¤»¤ó¡£ ET4000/W32p ¤ò»È¤Ã¤Æ¤¤
+¤ë Stealth 32 ¤âÁ´µ¡Ç½¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤»¤ó¡£
+
+¡Ê Diamond Viper Pro ¤È Viper SE ¥Ü¡¼¥É¤ËÅë
+ºÜ¤·¤Æ¤¤¤ë¡ËWeitek 9100 ¤È 9130 ¤Ï¥µ¥Ý¡¼¥È¤·¤Þ¤»¤ó¡£ËؤɤΤ½¤Î¾¤Î
+Diamond ¼Ò¤Î¥Ü¡¼¥É¤Ï¤³¤ÎÈǤΠXFree86 ¤Ç²ÔƯ¤¹¤ë¤Ç¤·¤ç¤¦¡£Diamond ¼Ò
+¤Ï XFree86 Project ¼Ò ¤òÀѶËŪ¤Ë¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£
+
+
+
+
+<sect> ¹¹¤Ë¿¤¯¤Î¾ðÊó¤Ï¤É¤³¤Ë¤¢¤ë¤«
+<p>
+
+<em>XFree86(1¾Ï)</em>,
+<em>XF86Config(4¾Ï/5¾Ï)</em>, <em>XF86_SVGA(1¾Ï)</em>,
+<em>XF86_Mono(1¾Ï)</em>, <em>XF86_VGA16(1¾Ï)</em>,
+<em>XF86_Accel(1¾Ï)</em> <em>XF86Setup(1)</em> ¤È <em>xvidtune(1¾Ï)</em>
+¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤òÄɲ䷤Ƥ¤¤Þ¤¹¡£
+¤µ¤é¤Ë¡¢¤¤¤¯¤Ä¤«¤Î <tt>README</tt> ¥Õ¥¡¥¤¥ë¤È²òÀâ¤ò¶¡µë¤·¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤é¤Ï¡¢
+¥Ð¥¤¥Ê¥êÇÛÉÕʪ¤Ç¤Ï¡¢ <tt>/usr/X11R6/lib/X11/doc</tt> ¤Î¡¢¤Þ¤¿¥½¡¼¥¹ÇÛÉÕʪ¤Ç¤Ï
+<tt>xc/programs/Xserver/hw/xfree86/doc</tt> ¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¢¤ê¤Þ¤¹¡£
+
+<tt>README.Config</tt> ¤È <tt>VideoModes.doc</tt> ¤Î¥Õ¥¡¥¤¥ë¤Ï XFree86 ¥µ¡¼¥Ð¡¼
+¤ò¤É¤¦¤ä¤Ã¤ÆÀßÄꤹ¤ë¤«¤Ë¤Ä¤¤¤Æ»²¹Í¾ðÊó¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£XFree86 ¥Á¡¼¥à ¤Ë»Ù±ç¤ÎÏ¢
+Íí¤ò¼è¤ëÁ°¤Ë¡¢Ä󶡤·¤¿Á´¤Æ¤Îʸ¾Ï¤È¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤ò¡¢ÆÉ¤ó¤Ç²¼¤µ¤¤¡£
+<htmlurl name="QuickStart.doc" url="QStart.html"> ¤È
+<htmlurl name="README.Config" url="Config.html"> ¤Î¥Õ¥¡¥¤¥ë¤Ï XFree86 ¥µ¡¼¥Ð¡¼
+¤ò¤É¤¦¤ä¤Ã¤ÆÀßÄꤹ¤ë¤«¤Ë¤Ä¤¤¤Æ»²¹Í¾ðÊó¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£XFree86 ¥Á¡¼¥à ¤Ë»Ù±ç¤ÎÏ¢
+Íí¤ò¼è¤ëÁ°¤Ë¡¢Ä󶡤·¤¿Á´¤Æ¤Îʸ¾Ï¤È¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤È<url name="XFree86 FAQ"
+url="http://www.XFree86.org/FAQ">¤ò¡¢ÆÉ¤ó¤Ç²¼¤µ¤¤¡£
+
+SVGA ¥É¥é¥¤¥Ð¤Î³«È¯¤Ë¤Ä¤¤¤Æ¤Îʸ½ñ¤Ï¡¢
+¥Ð¥¤¥Ê¥êÇÛÉÕʪ¤Ç¤Ï¡¢<tt>/usr/X11R6/lib/Server/VGADriverDoc</tt> ¤Ë¡¢
+¥½¡¼¥¹ÇÛÉÕʪ¤Ç¤Ï¡¢<tt>xc/programs/Xserver/hw/xfree86/VGADriverDoc</tt> ¤Ë¤¢¤ê¤Þ
+¤¹¡£
+
+Á´¤¯Ê¬¤«¤é¤Ê¤¤¾ì¹ç¤Ï¡¢<it/&lt;XFree86@XFree86.Org&gt;/ ¤Ë¤¤¤ë XFree86 ¥µ¥Ý¡¼¥È
+¥Á¡¼¥à¤ËÏ¢Íí¤·¤Æ²¼¤µ¤¤¡£Ï¢Íí¤ò¤È¤ëÁ°¤Ë¡¢ºÇ¿·ÈǤΠXFree86 ¤ò»È¤Ã¤Æ¤¤¤ë¤³¤È¤ò³Îǧ
+¤·¤Æ¤¯¤À¤µ¤¤¡£<htmlurl name="ftp://ftp.xfree86.org/pub/XFree86"
+url="ftp://ftp.xfree86.org/pub/XFree86"> ¤Ë·ÇºÜ¤·¤Æ¤¤¤ë¥Ð¡¼¥¸¥ç¥ó¤òÄ´¤Ù¤Æ¤¯¤À¤µ
+¤¤¡£
+
+Usenet ¥Ë¥å¡¼¥¹¥°¥ë¡¼¥×¤Ç¤¢¤ë <htmlurl name="comp.windows.x.i386unix"
+url="news:comp.windows.x.i386unix"> ¤Ç¤Ï¡¢¤¿¤¤¤Æ¤¤¤Î
+XFree86 ¤È¡¢XFree86 ¤Ë´Ø·¸¤¹¤ëÏÃÂê¤Ë¤Ä¤¤¤ÆµÄÏÀ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ËؤɤμÁÌä¤Ï¤½
+¤³¤Ç²óÅú¤µ¤ì¤Æ¤¤¤Þ¤¹¡£´ðËÜŪ¤Ê¼ÁÌä¤Î²óÅú¤Ï¡¢ÆâÍÆ¤ËÁêÅö¤¹¤ë FAQ ¤Ç¸«¤Ä¤«¤ë
+¤Ç¤·¤ç¤¦¡£
+
+
+<sect>¶¨Îϼԡ¢Ä󶡼ԤˤĤ¤¤Æ
+<p>
+
+XFree86 ¤Î³«È¯¤Ï¼¡¤Î¥á¥ó¥Ð¡¼¤Ç»Ï¤á¤Þ¤·¤¿¡£:
+<itemize>
+ <item>David Dawes <it>&lt;dawes@XFree86.org&gt;</it>
+ <item>Glenn Lai <it>&lt;glenn@cs.utexas.edu&gt;</it>
+ <item>Jim Tsillas <it>&lt;jtsilla@ccs.neu.edu&gt;</it>
+ <item>David Wexelblat <it>&lt;dwex@XFree86.org&gt;</it>
+</itemize>
+
+X11R6 ¥Ñ¥Ã¥±¡¼¥¸¤Ë XFree86 ¤òÅý¹ç¤¹¤ëºî¶È¤Ï¼¡¤Î¥á¥ó¥Ð¡¼¤Ç¹Ô¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£:
+<itemize>
+ <item> Stuart Anderson <it>&lt;anderson@metrolink.com&gt;</it>
+ <item> Doug Anson <it>&lt;danson@lgc.com&gt;</it>
+ <item> Gertjan Akkerman <it>&lt;akkerman@dutiba.twi.tudelft.nl&gt;</it>
+ <item> Mike Bernson <it>&lt;mike@mbsun.mlb.org&gt;</it>
+ <item> Robin Cutshaw <it>&lt;robin@XFree86.org&gt;</it>
+ <item> David Dawes <it>&lt;dawes@XFree86.org&gt;</it>
+ <item> Marc Evans <it>&lt;marc@XFree86.org&gt;</it>
+ <item> Pascal Haible <it>&lt;haible@izfm.uni-stuttgart.de&gt;</it>
+ <item> Matthieu Herrb <it>&lt;Matthieu.Herrb@laas.fr&gt;</it>
+ <item> Dirk Hohndel <it>&lt;hohndel@XFree86.org&gt;</it>
+ <item> David Holland <it>&lt;davidh@use.com&gt;</it>
+ <item> Alan Hourihane <it>&lt;alanh@fairlite.demon.co.uk&gt;</it>
+ <item> Jeffrey Hsu <it>&lt;hsu@soda.berkeley.edu&gt;</it>
+ <item> Glenn Lai <it>&lt;glenn@cs.utexas.edu&gt;</it>
+ <item> Ted Lemon <it>&lt;mellon@ncd.com&gt;</it>
+ <item> Rich Murphey <it>&lt;rich@XFree86.org&gt;</it>
+ <item> Hans Nasten <it>&lt;nasten@everyware.se&gt;</it>
+ <item> Mark Snitily <it>&lt;mark@sgcs.com&gt;</it>
+ <item> Randy Terbush <it>&lt;randyt@cse.unl.edu&gt;</it>
+ <item> Jon Tombs <it>&lt;tombs@XFree86.org&gt;</it>
+ <item> Kees Verstoep <it>&lt;versto@cs.vu.nl&gt;</it>
+ <item> Paul Vixie <it>&lt;paul@vix.com&gt;</it>
+ <item> Mark Weaver <it>&lt;Mark_Weaver@brown.edu&gt;</it>
+ <item> David Wexelblat <it>&lt;dwex@XFree86.org&gt;</it>
+ <item> Philip Wheatley <it>&lt;Philip.Wheatley@ColumbiaSC.NCR.COM&gt;</it>
+ <item> Thomas Wolfram <it>&lt;wolf@prz.tu-berlin.de&gt;</it>
+ <item> Orest Zborowski <it>&lt;orestz@eskimo.com&gt;</it>
+</itemize>
+
+<DESCRIP>
+<tag/386BSD, FreeBSD, NetBSD ÍѤϼ¡¤Î¥á¥ó¥Ð¡¼¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£: /
+<itemize>
+ <item> Rich Murphey <it>&lt;Rich@XFree86.org&gt;</it>
+</itemize>
+<tag/NetBSD, OpenBSD ÍѤϼ¡¤Î¥á¥ó¥Ð¡¼¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£: /
+<itemize>
+ <item> Matthieu Herrb <it>&lt;Matthieu.Herrb.@laas.fr&gt;</it>
+</itemize>
+<tag/¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºÇ½é¤Ë 386BSD ¤Ë°Ü¿¢¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Pace Willison,
+ <item> Amancio Hasty Jr <it>&lt;hasty@netcom.com&gt;</it>
+</itemize>
+<tag/Mach 386 ÍѤϼ¡¤Î¥á¥ó¥Ð¡¼¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£: /
+<itemize>
+ <item> Robert Baron <it>&lt;Robert.Baron@ernst.mach.cs.cmu.edu&gt;</it>
+</itemize>
+<tag/Linux ÍѤϼ¡¤Î¥á¥ó¥Ð¡¼¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£: /
+<itemize>
+ <item> Orest Zborowski <it>&lt;orestz@eskimo.com&gt;</it>
+</itemize>
+<tag/SCO Unix ÍѤϼ¡¤Î¥á¥ó¥Ð¡¼¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£: /
+<itemize>
+ <item> David McCullough <it>&lt;davidm@stallion.oz.au&gt;</it>
+</itemize>
+<tag/Amoeba ÍѤϼ¡¤Î¥á¥ó¥Ð¡¼¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£: /
+<itemize>
+ <item> Kees Verstoep <it>&lt;versto@cs.vu.nl&gt;</it>
+</itemize>
+<tag/Minix-386 ÍѤϼ¡¤Î¥á¥ó¥Ð¡¼¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£: /
+<itemize>
+ <item> Philip Homburg <it>&lt;philip@cs.vu.nl&gt;</it>
+</itemize>
+<tag>OSF/1 ÍѤϼ¡¤Î¥á¥ó¥Ð¡¼¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£: </tag>
+<itemize>
+ <item> Marc Evans <it>&lt;Marc@XFree86.org&gt;</it>
+</itemize>
+<tag>BSD/OS ÍѤϼ¡¤Î¥á¥ó¥Ð¡¼¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£: </tag>
+<itemize>
+ <item> Hans Nasten <it>&lt;nasten@everyware.se&gt;</it>,
+ <item> Paul Vixie <it>&lt;paul@vix.com&gt;</it>
+</itemize>
+<tag/Solaris ÍѤϼ¡¤Î¥á¥ó¥Ð¡¼¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£: /
+<itemize>
+ <item> Doug Anson <it>&lt;danson@lgc.com&gt;</it>,
+ <item> David Holland <it>&lt;davidh@use.com&gt;</it>
+</itemize>
+<tag/ISC SVR3 ÍѤϼ¡¤Î¥á¥ó¥Ð¡¼¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£: /
+<itemize>
+ <item> Michael Rohleder
+<it>&lt;michael.rohleder@stadt-frankfurt.de&gt</it>
+</itemize>
+<tag/LynxOS ÍѤϼ¡¤Î¥á¥ó¥Ð¡¼¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£: /
+<itemize>
+ <item> Thomas Mueller <it>&lt;tm@systrix.de&gt</it>
+</itemize>
+<tag/Linux ÍѶ¦Í­¥é¥¤¥Ö¥é¥ê¤Ï¼¡¤Î¥á¥ó¥Ð¡¼¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£: /
+<itemize>
+ <item> Orest Zborowski <it>&lt;orestz@eskimo.com&gt;</it>,
+ <item> Dirk Hohndel <it>&lt;hohndel@XFree86.org&gt;</it>
+</itemize>
+<tag/PC98 ÍѤϼ¡¤Î¥á¥ó¥Ð¡¼¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£: /
+<itemize>
+ <item> Toyonori Fujiura <it>&lt;toyo@ibbsal.or.jp&gt;</it>,
+ <item> Hiroyuki Aizu <it>&lt;aizu@jaist.ac.jp&gt;</it>,
+ <item> Tetsuya Kakefuda <it>&lt;kakefuda@tag.iijnet.or.jp&gt;</it>,
+ <item> Takefumi Tsukada <it>&lt;tsuka@linkt.imasy.or.jp&gt;</it>,
+ <item> H.Komatsuzaki,
+ <item> Naoki Katsurakawa <it>&lt;katsura@prc.tsukuba.ac.jp&gt;</it>,
+ <item> Shuichiro Urata <it>&lt;s-urata@nmit.tmg.nec.co.jp&gt;</it>,
+ <item> Yasuyuki Kato <it>&lt;yasuyuki@acaets0.anritsu.co.jp&gt;</it>,
+ <item> Michio Jinbo <it>&lt;karl@pms.nagaokaut.ac.jp&gt;</it>,
+ <item> Tatsuya Koike <it>&lt;koiket@focus.rim.or.jp&gt;</it>,
+ <item> Koichiro Suzuki <it>&lt;ksuzuki@cc.tuat.ac.jp&gt;</it>,
+ <item> Tsuyoshi Tamaki <it>&lt;tamaki@sail.t.u-tokyo.ac.jp&gt;</it>,
+ <item> Isao Ohishi <it>&lt;ohishi@hf.rim.or.jp&gt;</it>,
+ <item> Kohji Ohishi <it>&lt;atena@njk.co.jp&gt;</it>,
+ <item> Shin'ichi Yairo <it>&lt;QZR00522@niftyserve.or.jp&gt;</it>,
+ <item> Kazuo Ito <it>&lt;ft4k-itu@asahi-net.or.jp&gt;</it>,
+ <item> Jun Sakuma <it>&lt;i931361@jks.is.tsukuba.ac.jp&gt;</it>,
+ <item> Shuichi Ueno <it>&lt;uenos@ppp.bekkoame.or.jp&gt;</it>,
+ <item> Ishida Kazuo <it>&lt;ishidakz@obp.cl.nec.co.jp&gt;</it>,
+ <item> Takaaki Nomura <it>&lt;tnomura@sfc.keio.ac.jp&gt;</it>,
+ <item> Tadaaki Nagao <it>&lt;nagao@cs.titech.ac.jp&gt;</it>,
+ <item> Minoru Noda <it>&lt;mnoda@cv.tottori-u.ac.jp&gt;</it>,
+ <item> Naofumi Honda <it>&lt;honda@Kururu.math.hokudai.ac.jp&gt;</it>,
+ <item> Akio Morita <it>&lt;amorita@bird.scphys.kyoto-u.ac.jp&gt;</it>,
+ <item> Takashi Sakamoto <it>&lt;sakamoto@yajima.kuis.kyoto-u.ac.jp&gt;</it>,
+ <item> Yasuhiro Ichikawa <it>&lt;cs94006@mbox.sist.ac.jp&gt;</it>,
+ <item> Kazunori Ueno <it>&lt;g540012@komaba.ecc.u-tokyo.ac.jp&gt;</it>,
+ <item> Yasushi Suzuki <it>&lt;suz@d2.bs1.fc.nec.co.jp&gt;</it>,
+ <item> Masato Yoshida (Contributor of PW805i support)
+</itemize>
+
+
+<tag/ºÇ½é¤Ë¥¢¥¯¥»¥é¥ì¡¼¥¿¥×¥í¥°¥é¥à¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬»Ï¤á¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Kevin Martin <it>&lt;martin@cs.unc.edu&gt;</it>,
+ <item> Rik Faith <it>&lt;faith@cs.unc.edu&gt;</it>,
+ <item> Jon Tombs <it>&lt;tombs@XFree86.org&gt;</it>
+</itemize>
+<tag/S3 ¥¢¥¯¥»¥é¥ì¡¼¥¿¥×¥í¥°¥é¥à¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Jon Tombs <it>&lt;tombs@XFree86.org&gt;</it>,
+ <item> Harald Koenig <it>&lt;koenig@tat.physik.uni-tuebingen.de&gt;</it>,
+ <item> David Wexelblat <it>&lt;dwex@XFree86.org&gt;</it>,
+ <item> David Dawes <it>&lt;dawes@XFree86.org&gt;</it>,
+ <item> Robin Cutshaw <it>&lt;robin@XFree86.org&gt;</it>,
+ <item> Amancio Hasty <it>&lt;hasty@netcom.com&gt;</it>,
+ <item> Norbert Distler
+<it>&lt;Norbert.Distler@physik.tu-muenchen.de&gt;</it>,
+ <item> Leonard N. Zubkoff <it>&lt;lnz@dandelion.com&gt;</it>,
+ <item> Bernhard Bender <it>&lt;br@elsa.mhs.compuserve.com&gt;</it>
+ <item> Dirk Hohndel <it>&lt;hohndel@XFree86.org&gt;</it>
+ <item> Joe Moss <it>&lt;joe@XFree86.org&gt;</it>
+</itemize>
+<tag/S3V ¥¢¥¯¥»¥é¥ì¡¼¥¿¥×¥í¥°¥é¥à¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Harald Koenig <it>&lt;koenig@tat.physik.uni-tuebingen.de&gt;</it>,
+</itemize>
+<tag/Mach32 ¥¢¥¯¥»¥é¥ì¡¼¥¿¥×¥í¥°¥é¥à¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Kevin Martin <it>&lt;martin@cs.unc.edu&gt;</it>,
+ <item> Rik Faith <it>&lt;faith@cs.unc.edu&gt;</it>,
+ <item> Mike Bernson <it>&lt;mike@mbsun.mlb.org&gt;</it>,
+ <item> Mark Weaver <it>&lt;Mark_Weaver@brown.edu&gt;</it>,
+ <item> Craig Groeschel <it>&lt;craig@metrolink.com&gt;</it>
+ <item> Bryan Feir <it>&lt;jenora@istar.ca&gt;</it>
+</itemize>
+<tag/Mach64 ¥¢¥¯¥»¥é¥ì¡¼¥¿¥×¥í¥°¥é¥à¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Kevin Martin <it>&lt;martin@cs.unc.edu&gt;</it>,
+</itemize>
+<tag/Mach8¡¢8514 ¥¢¥¯¥»¥é¥ì¡¼¥¿¥×¥í¥°¥é¥à¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Kevin Martin <it>&lt;martin@cs.unc.edu&gt;</it>,
+ <item> Rik Faith <it>&lt;faith@cs.unc.edu&gt;</it>,
+ <item> Tiago Gons <it>&lt;tiago@comosjn.hobby.nl&gt;</it>,
+ <item> Hans Nasten <it>&lt;nasten@everyware.se&gt;</it>,
+ <item> Scott Laird <it>&lt;scott@laird.com&gt;</it>
+</itemize>
+<tag/Cirrus ¥¢¥¯¥»¥é¥ì¡¼¥¿¥×¥í¥°¥é¥à¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Simon Cooper <it>&lt;scooper@vizlab.rutgers.edu&gt;</it>,
+ <item> Harm Hanemaayer <it>&lt;H.Hanemaayer@inter.nl.net&gt;</it>,
+ <item> Bill Reynolds <it>&lt;bill@goshawk.lanl.gov&gt;</it>,
+ <item> Corin Anderson <it>&lt;corina@bdc.cirrus.com&gt;</it>
+</itemize>
+<tag/Western Digital ¥¢¥¯¥»¥é¥ì¡¼¥¿¥×¥í¥°¥é¥à¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿
+¡£: /
+<itemize>
+ <item> Mike Tierney <it>&lt;floyd@pepsi.eng.umd.edu&gt;</it>,
+ <item> Bill Conn <it>&lt;conn@bnr.ca&gt;</it>
+</itemize>
+<tag/P9000 ¥¢¥¯¥»¥é¥ì¡¼¥¿¥×¥í¥°¥é¥à¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Erik Nygren <it>&lt;nygren@mit.edu&gt;</it>,
+ <item> Harry Langenbacher <it>&lt;harry@brain.jpl.nasa.gov&gt;</it>
+ <item> Chris Mason <it>&lt;mason@mail.csh.rit.edu&gt;</it>
+ <item> Henrik Harmsen <it>&lt;harmsen@eritel.se&gt;</it>
+</itemize>
+<tag/AGX ¥¢¥¯¥»¥é¥ì¡¼¥¿¥×¥í¥°¥é¥à¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Henry Worth <it>&lt;henry.worth@amail.amdahl.com&gt;</it>,
+</itemize>
+<tag>ET4000/W32 ¥¢¥¯¥»¥é¥ì¡¼¥¿¥×¥í¥°¥é¥à¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: <
+/tag>
+<itemize>
+ <item> Glenn Lai <it>&lt;glenn@cs.utexas.edu&gt;</it>,
+</itemize>
+<tag>ET6000 SVGA ¤È ¥¢¥¯¥»¥é¥ì¡¼¥¿¤Ï(ξÊý¤È¤â´û¸¤ÎW32¤ò´ð¤Ë¤·¤Æ) ¼¡¤Î¥á¥ó¥Ð
+¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: </tag>
+<itemize>
+ <item> Koen Gadeyne <it>&lt;koen.gadeyne@barco.com&gt;</it>,
+</itemize>
+<tag/Oak Technologies Inc. ¥¢¥¯¥»¥é¥ì¡¼¥¿¥×¥í¥°¥é¥à¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·
+ ¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Jorge Delgado <it>&lt;ernar@dit.upm.es&gt;</it>,
+</itemize>
+
+<tag/16 ¿§¤Î VGA ¥µ¡¼¥Ð¡¼¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Gertjan Akkerman <it>&lt;akkerman@dutiba.twi.tudelft.nl&gt;</it>
+</itemize>
+
+<tag/2 ¿§ VGA ¤È Èó VGA Çò¹õ ¥µ¡¼¥Ð¡¼¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Pascal Haible <it>&lt;haible@izfm.uni-stuttgart.de&gt;</it>
+</itemize>
+
+<tag/ATI SVGA ¥É¥é¥¤¥Ð¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Per Lindqvist <it>&lt;pgd@compuram.bbt.se&gt;</it> ¤È Doug Evans
+ <it>&lt;dje@cygnus.com&gt;</it>.
+ <item> Rik Faith <it>&lt;faith@cs.unc.edu&gt;</it>¤Ë¤è¤Ã¤Æ X11R5 ¤Ë°Ü¿¢¤µ
+¤ì¤Þ¤·¤¿¡£
+ <item> Marc La France <it>&lt;Marc.La-France@ualberta.ca&gt;</it>¤¬½ñ
+¤­´¹¤¨¤Þ¤·¤¿¡£
+</itemize>
+<tag/WD90C24 ¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£:/
+<itemize>
+ <item> Brad Bosch <it>&lt;brad@lachman.com&gt;</it>
+</itemize>
+<tag/Trident SVGA ¥É¥é¥¤¥Ð¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Alan Hourihane <it>&lt;alanh@fairlite.demon.co.uk&gt;</it>
+</itemize>
+<tag/SiS SVGA ¥É¥é¥¤¥Ð¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Alan Hourihane <it>&lt;alanh@fairlite.demon.co.uk&gt;</it>
+</itemize>
+<tag/DEC 21030 (TGA) ¥µ¡¼¥Ð¤Ï¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Alan Hourihane <it>&lt;alanh@fairlite.demon.co.uk&gt;</it>
+ <item> Harald Koenig <it>&lt;koenig@tat.physik.uni-tuebingen.de&gt;</it>
+</itemize>
+<tag/NCR SVGA ¥É¥é¥¤¥Ð¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Stuart Anderson <it>&lt;anderson@metrolink.com&gt;</it>
+ NCR ¼Ò¤Î¾µÂú¤òÆÀ¤Æ¤¤¤Þ¤¹¡£
+</itemize>
+<tag/Cirrus SVGA ¥É¥é¥¤¥Ð¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Bill Reynolds <it>&lt;bill@goshawk.lanl.gov&gt;</it>,
+ <item> Hank Dietz <it>&lt;hankd@ecn.purdue.edu&gt;</it>,
+ <item> Simon Cooper <it>&lt;scooper@vizlab.rutgers.edu&gt;</it>,
+ <item> Harm Hanemaayer <it>&lt;H.Hanemaayer@inter.nl.net&gt;</it>,
+ <item> Corin Anderson <it>&lt;corina@bdc.cirrus.com&gt;</it>
+</itemize>
+<tag/Cirrus CL64xx ¥É¥é¥¤¥Ð¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Manfred Brands <it>&lt;mb@oceonics.nl&gt;</it>
+ <item> Randy Hendry <it>&lt;randy@sgi.com&gt;</it>
+ <item> Jeff Kirk <it>&lt;jeff@bambam.dsd.ES.COM&gt;</it>
+</itemize>
+<tag/Compaq SVGA ¥É¥é¥¤¥Ð¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Hans Oey <it>&lt;hans@mo.hobby.nl&gt;</it>
+</itemize>
+<tag/Oak SVGA ¥É¥é¥¤¥Ð¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Steve Goldman <it>&lt;sgoldman@encore.com&gt;</it>
+ <item> Jorge Delgado <it>&lt;ernar@dit.upm.es&gt;</it>
+</itemize>
+<tag/ARK Logic SVGA ¥É¥é¥¤¥Ð¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Harm Hanemaayer <it>&lt;H.Hanemaayer@inter.nl.net&gt;</it>
+ <item> Leon Bottou <it>&lt;bottou@laforia.ibp.fr&gt;</it>
+</itemize>
+<tag/AL2101 SVGA ¥É¥é¥¤¥Ð¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Paolo Severini <it>&lt;lendl@dist.dist.unige.it&gt;</it>
+</itemize>
+<tag/Avance Logic ``ali'' SVGA ¥É¥é¥¤¥Ð¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Ching-Tai Chiu <it>&lt;cchiu@netcom.com&gt;</it>
+</itemize>
+<tag/Chips &amp; Technologies SVGA ¥É¥é¥¤¥Ð¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£:/
+<itemize>
+ <item> Regis Cridlig <it>&lt;cridlig@dmi.ens.fr&gt;</it>
+ <item> Jon Block <it>&lt;block@frc.com&gt;</it>
+ <item> Mike Hollick <it>&lt;hollick@graphics.cis.upenn.edu&gt;</it>
+ <item> Nozomi Ytow
+ <item> Egbert Eich <it>&lt;Egbert.Eich@Physik.TH-Darmstadt.DE&gt;</it>
+ <item> David Bateman <it>&lt;dbateman@ee.uts.edu.au&gt;</it>
+ <item> Xavier Ducoin <it>&lt;xavier@rd.lectra.fr&gt;</it>
+</itemize>
+<tag/MX SVGA ¥É¥é¥¤¥Ð¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Frank Dikker <it>&lt;dikker@cs.utwente.nl&gt;</it>
+</itemize>
+<tag/Video7 SVGA ¥É¥é¥¤¥Ð¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Craig Struble <it>&lt;cstruble@acm.vt.edu&gt;</it>
+</itemize>
+<tag/RealTek SVGA ¥É¥é¥¤¥Ð¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Peter Trattler <it>&lt;peter@sbox.tu-graz.ac.at&gt;</it>
+</itemize>
+
+<tag/Apollo Çò¹õ ¥É¥é¥¤¥Ð¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Hamish Coleman <it>&lt;hamish@zot.apana.org.au&gt;</it>
+</itemize>
+
+<tag/XFree86-VidMode µ¡Ç½³ÈÄ¥ ¤È xvidtune ¥¯¥é¥¤¥¢¥ó¥È¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®
+ ¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Kaleb S. Keithley <it>&lt;kaleb@x.org&gt;</it>
+ <item> David Dawes <it>&lt;dawes@XFree86.org&gt;</it>
+ <item> Jon Tombs <it>&lt;tombs@XFree86.org&gt;</it>
+ <item> Joe Moss <it>&lt;joe@XFree86.org&gt;</it>
+</itemize>
+
+<tag/XFree86-Misc µ¡Ç½³ÈÄ¥¤Ï¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Joe Moss <it>&lt;joe@XFree86.org&gt;</it>
+ <item> David Dawes <it>&lt;dawes@XFree86.org&gt;</it>
+</itemize>
+
+<tag/XFree86-DGA µ¡Ç½³ÈÄ¥¤Ï¼¡¤Î¥á¥ó¥Ð¡¼¤¬ºîÀ®¤·¤Þ¤·¤¿¡£: /
+<itemize>
+ <item> Jon Tombs <it>&lt;tombs@XFree86.org&gt;</it>
+ <item> Mark Vojkovich <it>&lt;mvojkovi@ucsd.edu&gt;</it>
+ <item> Harm Hanemaayer <it>&lt;H.Hanemaayer@inter.nl.net&gt;</it>,
+ <item> David Dawes <it>&lt;dawes@XFree86.org&gt;</it>
+</itemize>
+
+<tag/XInput Åý¹çºî¶È¤È ¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤È¥¯¥é¥¤¥¢¥ó¥È¤ÎºîÀ®¤Ï¼¡¤Î¥á¥ó¥Ð¡¼¤¬¤·¤Þ
+¤·¤¿¡£: /
+<itemize>
+ <item> Frederic Lepied <it>&lt;lepied@XFree86.Org&gt;</it> (XInput
+integration, Wacom ¥¿¥Ö¥ì¥Ã¥È, ¥¸¥ç¥¤¥¹¥Æ¥£¥Ã¥¯ ¤È ³ÈÄ¥¥Þ¥¦¥¹¥Ç¥Ð¥¤¥¹¥É¥é¥¤
+¥Ð, xsetpointer ¤È xsetmode ¥¯¥é¥¤¥¢¥ó¥È)
+ <item> Patrick Lecoanet <it>&lt;lecoanet@cena.dgac.fr&gt;</it>
+(Elographics ¥¿¥Ã¥Á¥¹¥¯¥ê¡¼¥ó¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð)
+ <item> Steven Lang <it>&lt;tiger@tyger.org&gt;</it> (Summagraphics ¥¿
+¥Ö¥ì¥Ã¥È ¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð)
+</itemize>
+
+<tag/¤½¤Î¾¤Î¹×¸¥¼Ô: /
+<itemize>
+ <item> Joerg Wunsch <it>&lt;joerg_wunsch@uriah.sax.de&gt;</it> (ET3000 ¤Î
+¥Ð¥ó¥¯¥á¥â¥ê¤ÎÇò¹õ¥µ¡¼¥Ð¡¼Ã´Åö),
+ <item> Eric Raymond <it>&lt;esr@snark.thyrsus.com&gt;</it> (¿·¤·¤¤¥Ó¥Ç¥ª
+¥â¡¼¥É¤Îʸ¾ÏôÅö),
+
+ <item> ¤½¤·¤Æ¡¢À¤³¦Ãæ¤ÎÁ´¤Æ¤Î¥Ù¡¼¥¿¥Æ¥¹¥È¤ò¹Ô¤Ê¤Ã¤Æ¤¯¤ì¤¿Â¿¤¯¤Î¿Í¡¹¡ª
+</itemize>
+</descrip>
+
+<sect>Ï¢Íí¾ðÊó
+<p>
+
+³«È¯·×²è¤È¥µ¥Ý¡¼¥È¤Ï XFree86 ¥³¥¢¥Á¡¼¥à¤Ë¤è¤Ã¤Æ¿ä¿Ê¤·¤Æ¤¤¤Þ¤¹¡£¸½ºß¡¢¥³¥¢
+¥Á¡¼¥à¤Ï¡¢¼¡¤Î¥á¥ó¥Ð¡¼¤Ç¹½À®¤·¤Æ¤¤¤Þ¤¹¡£¡Ê½çÉÔÆ±¡Ë:
+<itemize>
+ <item>Robin Cutshaw <it>&lt;robin@XFree86.org&gt;</it>
+ <item>David Dawes <it>&lt;dawes@XFree86.org&gt;</it>
+ <item>Marc Evans <it>&lt;marc@XFree86.org&gt;</it>
+ <item>Dirk Hohndel <it>&lt;hohndel@XFree86.org&gt;</it>
+ <item>Harald Koenig <it>&lt;koenig@XFree86.org&gt;</it>
+ <item>Rich Murphey <it>&lt;rich@XFree86.org&gt;</it>
+ <item>Jon Tombs <it>&lt;tombs@XFree86.org&gt;</it>
+ <item>David Wexelblat <it>&lt;dwex@XFree86.org&gt;</it>
+</itemize>
+¥³¥¢¥Á¡¼¥à¤Ø¤ÎÏ¢Íí¤Ï <it>&lt;Core@XFree86.org&gt;</it> °¸¤Æ¤ËÅŻҥ᡼¥ë¤òÁ÷¿®¤·
+¤Æ¤¯¤À¤µ¤¤¡£
+¥µ¥Ý¡¼¥È¤Ë´Ø¤¹¤ë¼ÁÌä¤Ï <it>&lt;XFree86@XFree86.org&gt;</it> °¸¤Æ¤ËÅŻҥ᡼¥ë¤òÁ÷
+¿®¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+<sect>XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò
+<p>
+
+XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Ï£²¤Ä¤ÎÂ礭¤ÊÌÜɸ¤òÀ®¤·¿ë¤²¤ë°Ù¤Ë¡¢·ëÀ®¤·¤Þ¤·¤¿¡£:
+<enum>
+ <item> XFree86 ¤ò X ¥¦¥£¥ó¥É¥¦¥·¥¹¥Æ¥à¤ÎÀ߷ס¢³«È¯¤ÈÄ󶡤ËÀÕǤ¤ò»ý¤Ä X
+ ¥³¥ó¥½¡¼¥·¥¢¥à¤ÎÃæ¤Ç¡¢Âåɽ¤Ç¤­¤ë¤è¤¦¤Ê¥½¥Õ¥È¤Ë¤¹¤ë¼êÃʤò¶¡µë¤¹¤ë¤³¤È
+ <item> XFree86 ¤Î³«È¯¤ò¿ä¿Ê¤¹¤ë¿Íºà¤È¡¢¼ç¤È¤·¤Æ¿·¤·¤¤É½¼¨ÁõÃ֤ȴðÁÃŪ¤Ê
+ÅÅ»»½èÍýÀßÈ÷¤òÆþ¼ê¤¹¤ë¤¿¤á¤Î¡¢¤¤¤¯¤é¤«¤Î´ðËܤȤʤë´ð¶â¤ò½¸¤á¡¢Ä󶡤¹¤ë¤³¤È
+</enum>
+°ì¤ÄÌܤÎÌÜɸ¤¬Âè°ì¤Îưµ¡¤Ç¤·¤¿¡£»ä¤¿¤Á¤Ï¡¢´Ë¤ä¤«¤ËÁÈ¿¥²½¤µ¤ì¤¿¥Õ¥ê¡¼¥½¥Õ¥È
+¥×¥í¥¸¥§¥¯¥È¤¬ X ¥³¥ó¥½¡¼¥·¥¢¥à¤ÎÃæ¤Çȯ¸À¸¢¤ò»ý¤Æ¤ë¤è¤¦¤ÊÈ´¤±Æ»¤Ï¤Ê¤¤¤â¤Î
+¤«¤È¡¢²¿¥«·î¤â ÃÇ³Ū¤Ë¶¨µÄ¤ò½Å¤Í¤Æ¤­¤Þ¤·¤¿¡£¥³¥ó¥½¡¼¥·¥¢¥à¤ÎÆâµ¬¤Ç¤Ï¡¢´Ë
+¤ä¤«¤ËÁÈ¿¥²½¤µ¤ì¤¿¥Õ¥ê¡¼¥½¥Õ¥È¥×¥í¥¸¥§¥¯¥È¤Î¤è¤¦¤ÊÁÈ¿¥¤Ïǧ¤á¤é¤ì¤Þ¤»¤ó¤Ç¤·
+¤¿¡£»ä¤¿¤Á¤Ï´ð¶âÊ罸¤Ë´Ø¤·¤Æ¥³¥ó¥½¡¼¥·¥¢¥à¤ÎÆâµ¬¤ÎÍ×µá¤òËþ¤¿¤·¡¢É¬Íפʴð¶â
+¤ò³ÍÆÀ¤¹¤ë¤¿¤á¤Ë¡¢Ë¡¿Í¤Î·ÁÂÖ¤ò¼è¤ë¤³¤È¤Ë·èÄꤷ¤Þ¤·¤¿¡£
+
+Ë¡¿Í²½¤·¤¿¤³¤È¤Ç¡¢X11R6 ¤Î¥Ù¡¼¥¿¥Æ¥¹¥È¤Ë»²²Ã¤¬²Äǽ¤È¤Ê¤ê¡¢XFree86 ¤Î¥³¥¢¤Î
+ÁêÅöÉôʬ¤ò X11R6 ¤È X11R6.1 ¤ËÄ󶡤Ǥ­¤Þ¤·¤¿¡£½é¤á¤Æ¤Î X11R6 ¤Î¥³¥¢¥ê¥ê¡¼¥¹
+Âбþ¤Î
+ºÇ½é¤Î XFree86 ¤Ï¥Ð¡¼¥¸¥ç¥ó 3.0 ¤Ç¤¹¡£¸½ºß¤Î X11R6.1 ¤Î XFree86 ¤Ï¥Ð¡¼¥¸
+¥ç¥ó 3.1.2C ¤Ç¤¹¡£
+&lsqb; ÌõÃí¡§X11R6.1 ¤Î¥Ñ¥Ã¥ÁÈǤΠXFree86 ¤Ï¥Ð¡¼¥¸¥ç¥ó 3.1.2C ¤Ç¤¹¡£3.2 ¤Ç¤Ï¤¢¤ê
+¤Þ¤»¤ó¡£X11R6.1 ÆâÉô¤Ç¤Ï¥Ð¡¼¥¸¥ç¥ó 3.1.2C ¤Ç¡¢¸ø³«¤·¤¿¥Ð¡¼¥¸¥ç¥ó¤¬ 3.2 ¤À¤È
+¤¤¤¦¤³¤È¤Ç¤¹¡£&rsqb;
+
+Ë¡¿ÍÁÈ¿¥¤È¤·¤¿¤³¤È¤Ë¤è¤ë¤â¤¦°ì¤Ä¤ÎÍøÅÀ¤Ï¡¢XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤¬¡¢»ä¤¿¤Á
+¤Î»Å»ö¤Î°Ù¤Ë¡¢³°Éô¤«¤é¤Î»ñ¶â±ç½õ¤ò³ÍÆÀ¤·¤¿»ö¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ì¤Ë¤è¤Ã¤Æ¡¢´ê¤ï
+¤¯¤Ð¤â¤Ã¤ÈÀѶËŪ¤Ë¿·¤·¤¤¥Ó¥Ç¥ª´ØÏ¢¤Îµ¡ºà¤òƳÆþ¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¡¢¤è¤ê¤è¤¤À½
+Éʤò¤è¤ê¤Ï¤ä¤¯¥ê¥ê¡¼¥¹¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ë¤«¤È»×¤¤¤Þ¤¹¡£¼«Ê¬¤«¤éư¤¤¤ÆÉ¬Íפʤâ
+¤Î¤ò¼ê¤ËÆþ¤ì¡¢¤½¤·¤Æ¤½¤ì¤ò¼ÂºÝ¤Î³«È¯ºî¶È¤Ë¤¿¤º¤µ¤ï¤ë¿Í¡¹¤ËÄ󶡤¹¤ë¤³¤È¤¬²Ä
+ǽ¤È¤Ê¤ë¤«¤é¤Ç¤¹¡£
+
+¸½ºß¤ÎXFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Î¼èÄùÌò²ñ¤È´´»ö²ñ¤Ï¡¢°Ê²¼¤ÎÄ̤ê:
+<itemize>
+ <item> David Dawes, President and Secretary
+ <item> Dirk Hohndel, Vice-President
+ <item> Glenn Lai, Director
+ <item> Rich Murphey, Treasurer
+ <item> Jim Tsillas, Director
+ <item> Jon Tombs, Director
+ <item> David Wexelblat, Director
+</itemize>
+¼èÄùÌò²ñ¤Ø¤ÎÏ¢Íí¤Ï <it>&lt;BOD@XFree86.org&gt;</it> ¤Þ¤ÇÅŻҥ᡼¥ë¤òÁ÷¤Ã¤Æ
+²¼¤µ¤¤¡£
+
+ÊÀ¼Ò¤ÎÆâµ¬¤Ï¡¢XFree86 ¤¬¸½ºß¤â¡¢¤½¤·¤Æ¾­Íè¤â¤º¤Ã¤È¡¢¥Õ¥ê¡¼¥½¥Õ¥È¥¦¥§¥¢¥×¥í
+¥¸¥§¥¯¥È¤Ç¤¢¤ê³¤±¤ë¤³¤È¤òÊݾڤ¹¤ë¤è¤¦¤Ê·Á¤Çµ¯Áð¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¥³¥¢¥Á¡¼¥à¤Î
+¥á¥ó¥Ð¡¼Ëô¤Ï¡¢¤½¤Î¾¤Î XFree86 ´Ø·¸¼Ô¤Îï¤Ë¤È¤Ã¤Æ¤â¡¢¸Ä¿ÍŪ¤Ê¶âÁ¬ÅªÍø±×¤¬
+̵¤¤¤è¤¦¤ËÇÛθ¤·¤Þ¤·¤¿¡£
+Á´¤Æ¤Î²ñ¼Ò¤Î»ñ»º¤Ï²ñ¼Ò¤Î°Ù¤Ë»Ä¤·¡¢²ñ¼Ò¤Î²ò»¶¤Î»þ¤Ë¤Ï¡¢Á´¤Æ¤Î»ñ»º¤ò X ¥³¥ó
+¥½¡¼¥·¥¢¥à¤Ë°Ñ¾ù¤¹¤ëͽÄê¤Ç¤¹¡£¤³¤Î¤è¤¦¤Ê·Á¼°¤ò¤È¤ë¤³¤È¤Ç¡¢ÊÀ¼Ò¤¬¤³¤ì¤Þ¤Ç¤Î
+³èư¤òñ¤Ë·Á¼°²½¤·¤¿¤â¤Î¤È¤Ê¤ë¤³¤È¤ò´õ˾¤·¤Æ¤¤¤Þ¤¹¡£½¾Íè¤Î³èư¤È¤Þ¤Ã¤¿¤¯¤Á
+¤¬¤Ã¤¿¤â¤Î¤Ë¤Ê¤ë¤Ä¤â¤ê¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+
+¤³¤³¤Ë¡¢XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Î¥¹¥Ý¥ó¥µ¡¼¤È¤Ê¤ê¡¢¶âÁ¬¤ÎÄó¶¡Ëô¤Ïµ¡ºà¤È»ñ¸»
+¤ÎÄ󶡤ò¤·¤Æ¤¯¤À¤µ¤Ã¤¿ÁÈ¿¥¤È¸Ä¿Í¤ÎÊý¤ò°ìÍ÷¤ËÃפ·¤Þ¤¹¡£XFree86 ¥×¥í¥¸¥§¥¯¥È
+¼Ò¤ÏÈà¤é¤ËÂçÊÑ´¶¼Õ¤·¡¢¥¤¥ó¥¿¡¼¥Í¥Ã¥È¼Ò²ñÁ´ÂΤβþÁ±¤Î°Ù¤Ë¹âÉʼÁ¤Ê¥Õ¥ê¡¼¥½¥Õ
+¥È¥¦¥§¥¢¤ò·Ñ³¤·¤ÆÄ󶡤¹¤ë¤³¤È¤Ç¡¢Èà¤é¤Î´üÂԤ˱褨¤ë¤³¤È¤ò´ê¤Ã¤Æ¤ª¤ê¤Þ¤¹¡£
+<itemize>
+ <item> <url url="http://www.uu.net/"
+ name = "UUNET Communications Services, Inc.">
+</itemize>
+UUNET Communications Services, Inc ¤Ï¡¢ÆÃÊ̤Ë̾Á°¤òµó¤²¤¿¤¤¤È»×¤¤¤Þ¤¹¡£
+¤³¤Î²ñ¼Ò¤ÏÀѶËŪ¤Ë¡¢¤¤¤ÁÁ᤯1994 ǯ¤Î X ¥³¥ó¥½¡¼¥·¥¢¥à¤Îǯ²ñÈñÁ´¤Æ¤ò´óÉÕ¤·
+¤Æ¤¯¤ì¤Þ¤·¤¿¡£¤³¤Î°ì²ó¤Î»ñ¶âÄ󶡤ˤè¤ê¡¢X11R6 ¤ò XFree86 ¤Ë´¬¤­¹þ¤à»ö¤¬³Î
+¼Â¤Ë¤Ê¤Ã¤¿¤Î¤Ç¤¹¡£
+
+<itemize>
+ <item> GUUG -- Â裱²ó¥É¥¤¥Ä Linux ²ñµÄ¡Ê1st German Linux Congress¡Ë
+</itemize>
+¤Þ¤¿¡¢ÅöÁ³ÆÃÊ̤Ë̾Á°¤òµó¤²¤ë¤Ù¤­¤Ï¥Ï¥ó¥Ö¥ë¥°¤Ç³«ºÅ¤µ¤ì¤¿Â裱²ó¥É¥¤¥Ä
+Linux ²ñµÄ¡Ê1st German Linux Congress¡Ë¤Î³«ºÅ¼Ô¤È»²²Ã¼Ô¤Î³§¤µ¤ó¤Ç¤¹¡£Â¿¤¯
+¤Î»ñ¶â¤ò XFree86 ¥×¥í¥¸¥§¥¯¥È¤Ë²ñµÄ¤Î¼ýÆþ¤«¤éÄ󶡤·¤Æ¤¤¤¿¤À¤­¤Þ¤·¤¿¡£
+
+<itemize>
+ <item> <url url="http://www.aib.com/"
+ name="AIB Software Corporation">, Herndon, VA
+ <item> Roland Alder, Armin Fessler, Patrick Seemann, Martin Wunderli
+ <item> American Micro Group
+ <item> <url url="http://www.attgis.com/"
+ name="AT&amp;T Global Information Services"> (formerly NCR)
+ <item> Andrew Burgess
+ <item> <url url="http://www.atitech.ca/"
+ name="ATI Technologies Inc">
+ <item> <url url="http://www.bsdi.com/"
+ name="Berkeley Software Design, Inc">, Falls Church, VA
+ <item> <url url="http://www.caldera.com/"
+ name="Caldera, Inc.">
+ <item> <url url="http://www.delix.de/"
+ name="Delix Computer GmbH">, Stuttgart, Germany
+ <item> <url url="http://www.destek.net/Destek/"
+ name="The Destek Group, Inc.">, Nashua, NH (formerly Synergytics)
+ <item> <url url="http://www.diamondmm.com/"
+ name="Diamond Multimedia Systems, Inc.">
+ <item> <url url="http://www.digital.com/"
+ name="Digital Equipment Corporation">
+ <item> <url url="http://www.elsa.de/"
+ name="Elsa GmbH">, Aachen, Germany
+ <item> Genoa Systems Corporation
+ <item> <url url="http://www.helius.com/"
+ name="Helius, Inc.">
+ <item> <url url="http://www.hercules.com/"
+ name="Hercules Computer Technology, Inc.">
+ <item> Ralf Hockens
+ <item> Dirk Hohndel
+ <item> <url url="http://www.infomagic.com/"
+ name="InfoMagic">, Flagstaff, AZ
+ <item> Daniel Kraemer
+ <item> Frank &amp; Paige McCormick
+ <item> Linux International
+ <item> Linux Support Team, Erlangen, Germany
+ <item> <url url="http://www.lunetix.de"
+ name="LunetIX Softfair">, Berlin, Germany
+ <item> <url url="http://www.morse.net"
+ name="Morse Telecommunications">, Long Beach, NY
+ <item> MIRO Computer Products AG, Braunschweig, Germany
+ <item> Rich &amp; Amy Murphey
+ <item> Brett Neumeier
+ <item> Number Nine, Lexington, MA
+ <item> Kazuyuki Okamoto, Japan
+ <item> <url url="http://www.ptf.com/"
+ name="Prime Time Freeware">, San Bruno, CA
+ <item> <url url="http://www.redhat.com/"
+ name="Red Hat Software">, Chapel Hill, NC
+ <item> Norbert Reithinger
+ <item> SPEA Software AG, Starnberg, Germany
+ <item> STB Systems
+ <item> Clifford M Stein
+ <item> Joel Storm
+ <item> <url url="http://www.suse.de"
+ name="S.u.S.E. GmbH">, Fuerth, Germany
+ <item> <url url="http://www.tekelec.com"
+ name="Tekelec Airtronic GmbH">, Muenchen, Germany
+ <item> Jim Tsillas
+ <item> Trans-Ameritech Enterprises, Inc., Santa Clara, CA
+ <item> Unifix Software GmbH, Braunschweig, Germany
+ <item> <url url="http://www.vix.com/"
+ name="Vixie Enterprises">, La Honda, CA
+ <item> <url url="http://www.cdrom.com/"
+ name="Walnut Creek CDROM">, Concord, CA
+ <item> <url url="http://www.xfree86.org/xtreme"
+ name="Xtreme s.a.s.">, Livorno, Italy
+</itemize>
+ XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Ï´ð¶â¤Èµ¡ºà¡¢Ëô¤Ï¤É¤Á¤é¤«¤ÎÄɲôó£¤ò´¿·ÞÃפ·¤Þ¤¹¡£
+ ¤³¤Î¤è¤¦¤Ê´ó£¤Ï¡¢½êÆÀÀǤιµ½üÂоݤȤʤë*¤Ï¤º*¤Ç¤¹¡Ê¤¬¤Þ¤À³ÎÄê¤Ï¤·¤Æ¤¤¤Þ¤»
+ ¤ó¡Ë¡£»ä¤¿¤Á¤ÎÊÛ¸î»Î¤¬½ñÎàºî¶È¤ò½ª¤¨¼¡Âè¡¢¤³¤ÎÅÀ¤Ï¤Ï¤Ã¤­¤ê¤¹¤ë¤Ç¤·¤ç¤¦¡£
+ ¾ÜºÙ¤Ï XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¡¢
+<it>&lt;BOD@XFree86.org&gt;</it> ¤Þ¤Ç¡£
+
+<sect>¥½¡¼¥¹¤È¥Ð¥¤¥Ê¥ê¥Õ¥¡¥¤¥ë¤Î¤¢¤ë¥µ¥¤¥È
+<p>
+
+X ¥³¥ó¥½¡¼¥·¥¢¥à ¤Î X11R6.1 PL1 ¤«¤é XFree86 3.2 ¤Ø¤Î¥½¡¼¥¹¤Î¥Ð¡¼¥¸¥ç¥ó¥¢
+¥Ã¥×ÍѥѥåÁ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¥½¡¼¥¹¤Ø¤Î¥Ñ¥Ã¥Á¤ÈÍÍ¡¹¤Ê OS ÍѤΥХ¤¥Ê¥ê¤Ï°Ê²¼
+¤Îƿ̾ FTP ¥µ¥¤¥È·Ðͳ¤Ç¼ê¤ËÆþ¤ê¤Þ¤¹:
+
+<itemize>
+<item> <htmlurl url="ftp://ftp.XFree86.org/pub/XFree86"
+ name="ftp://ftp.XFree86.org/pub/XFree86">
+</itemize>
+
+¤Þ¤¿¡¢¼¡¤Î¥ß¥é¡¼¥µ¥¤¥È¤¬ÍøÍѲÄǽ¤Ç¤¹¡£:
+<itemize>
+<item> ËÌÊÆ:
+<itemize>
+<!--
+<item> <htmlurl url="ftp://ftp.bsdi.com/contrib/X11/XFree86"
+ name="ftp://ftp.bsdi.com/contrib/X11/XFree86">
+ (¥½¡¼¥¹ ¤È BSD/OS ¥Ð¥¤¥Ê¥ê)
+-->
+<item> <htmlurl url="ftp://XFree86.cdrom.com/pub/XFree86"
+ name="ftp://XFree86.cdrom.com/pub/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+<item> <htmlurl url="ftp://ftp.redhat.com/pub/mirrors/ftp.xfree86.org"
+ name="ftp://ftp.redhat.com/pub/mirrors/ftp.xfree86.org">
+ (¥½¡¼¥¹ ¤È Linux ¥Ð¥¤¥Ê¥ê)
+<item> <htmlurl url="ftp://ftp.rge.com/pub/X/XFree86"
+ name="ftp://ftp.rge.com/pub/X/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+<item> <htmlurl url="ftp://ftp.iastate.edu/pub/XFree86/XFree86-3.2"
+ name="ftp://ftp.iastate.edu/pub/XFree86/XFree86-3.2">
+ (¥½¡¼¥¹ ¥Ñ¥Ã¥Á ¤È NetBSD ¥Ð¥¤¥Ê¥ê)<newline>
+ (Also via AFS: /afs/iastate.edu/public/ftp/pub/XFree86/XFree86-3.2)
+<item> <htmlurl url="ftp://tsx-11.mit.edu/pub/linux/packages/X11/XFree86-3.2"
+ name="ftp://tsx-11.mit.edu/pub/linux/packages/X11/XFree86-3.2">
+ (Linux ¥Ð¥¤¥Ê¥ê ¤È ¥½¡¼¥¹)
+<!--
+<item> <htmlurl url="ftp://ref.tfs.com/pub/mirrors/XFree86"
+ name="ftp://ref.tfs.com/pub/mirrors/XFree86">
+ (¥½¡¼¥¹ ¥Ñ¥Ã¥Á ¤È FreeBSD ¥Ð¥¤¥Ê¥ê)
+-->
+<item> <htmlurl url="ftp://ftp.eecs.umich.edu/BSD/XFree86"
+ name="ftp://ftp.eecs.umich.edu/BSD/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+<item> <htmlurl url="ftp://ftp.cs.umn.edu/pub/XFree86"
+ name="ftp://ftp.cs.umn.edu/pub/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+<!--
+<item> <htmlurl url="ftp://sunsite.unc.edu/pub/X11/XFree86"
+ name="ftp://sunsite.unc.edu/pub/X11/XFree86">
+ (¥½¡¼¥¹ ¥Ñ¥Ã¥Á ¤È ¥Ð¥¤¥Ê¥ê)
+<item> <htmlurl url="ftp://abode.ccd.bnl.gov/pub/XFree86"
+ name="ftp://abode.ccd.bnl.gov/pub/XFree86">
+ (Solaris, SVR4, SCO ¥Ð¥¤¥Ê¥ê)
+-->
+<item> <htmlurl url="ftp://despair.capecod.net/pub/XFree86"
+ name="ftp://despair.capecod.net/pub/XFree86">
+ (Linux, NetBSD ¤È FreeBSD ¥Ð¥¤¥Ê¥ê)
+</itemize>
+
+<item> ¥è¡¼¥í¥Ã¥Ñ:
+<itemize>
+<item> <htmlurl url="ftp://fvkma.tu-graz.ac.at/pub/XFree86"
+ name="ftp://fvkma.tu-graz.ac.at/pub/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+<!--
+<item> <htmlurl url="ftp://ftp.switch.ch/mirror/XFree86"
+ name="ftp://ftp.switch.ch/mirror/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+-->
+<item> <htmlurl url="ftp://sunsite.mff.cuni.cz/X11/XFree86"
+ name="ftp://sunsite.mff.cuni.cz/X11/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+<item> <htmlurl url="ftp://ftp.fee.vutbr.cz/pub/XFree86"
+ name="ftp://ftp.fee.vutbr.cz/pub/XFree86">
+ (¥½¡¼¥¹ ¥Ñ¥Ã¥Á ¤È ¥Ð¥¤¥Ê¥ê)
+<item> <htmlurl url="ftp://ftp.gwdg.de/pub/xfree86/XFree86"
+ name="ftp://ftp.gwdg.de/pub/xfree86/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+<item> <htmlurl url="ftp://ftp.uni-erlangen.de/pub/Linux/MIRROR.xfree86"
+ name="ftp://ftp.uni-erlangen.de/pub/Linux/MIRROR.xfree86">
+ (¥½¡¼¥¹ ¥Ñ¥Ã¥Á ¤È Linux ¥Ð¥¤¥Ê¥ê)
+<item> <htmlurl url="ftp://ftp.uni-stuttgart.de/pub/X11/Xfree86"
+ name="ftp://ftp.uni-stuttgart.de/pub/X11/Xfree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+<item> <htmlurl url="ftp://ftp.funet.fi/pub/X11/XFree86"
+ name="ftp://ftp.funet.fi/pub/X11/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+<item> <htmlurl url="ftp://ftp.calvacom.fr/pub/unix/X/XFree86"
+ name="ftp://ftp.calvacom.fr/pub/unix/X/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+<item> <htmlurl url="ftp://ftp.ibp.fr/pub/X11/XFree86"
+ name="ftp://ftp.ibp.fr/pub/X11/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+<item> <htmlurl url="ftp://ftp.laas.fr/pub/ii/NetBSD/XFree86-3.2"
+ name="ftp://ftp.laas.fr/pub/ii/NetBSD/XFree86-3.2">
+ (NetBSD ¥Ð¥¤¥Ê¥ê only)
+<!--
+<item> <htmlurl url="ftp://ftp.unipi.it/pub/mirrors/XFree86-3.2"
+ name="ftp://ftp.unipi.it/pub/mirrors/XFree86-3.2">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+-->
+<item> <htmlurl url="ftp://ftp.pvv.unit.no/pub/XFree86"
+ name="ftp://ftp.pvv.unit.no/pub/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+<item> <htmlurl url="ftp://sunsite.doc.ic.ac.uk/packages/XFree86"
+ name="ftp://sunsite.doc.ic.ac.uk/packages/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+<!--
+<item> <htmlurl url="ftp://ftp.demon.co.uk/pub/Xwindows/XFree86"
+ name="ftp.demon.co.uk:/pub/Xwindows/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+-->
+</itemize>
+
+
+<!--
+<item> ÃæÅì:
+<itemize>
+<item> <htmlurl url="ftp://orgchem.weizmann.ac.il/pub/XFree86"
+ name="ftp://orgchem.weizmann.ac.il/pub/XFree86">
+ (¥½¡¼¥¹ ¤È FreeBSD ¥Ð¥¤¥Ê¥ê)
+</itemize>
+-->
+
+<item> ¥¢¥¸¥¢/¥ª¡¼¥¹¥È¥é¥ê¥¢:
+<itemize>
+<item> <htmlurl url="ftp://x.physics.usyd.edu.au/pub/XFree86"
+ name="ftp://x.physics.usyd.edu.au/pub/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+<item> <htmlurl url="ftp://ftp.iij.ad.jp/pub/X/XFree86/XFree86"
+ name="ftp://ftp.iij.ad.jp/pub/X/XFree86/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+<item> <htmlurl url="ftp://ftp.sf.co.kr/pub/XFree86"
+ name="ftp://ftp.sf.co.kr/pub/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+<!--
+<item> <htmlurl url="ftp://ftp.hk.super.net/mirror/XFree86"
+ name="ftp://ftp.hk.super.net/mirror/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+-->
+<item> <htmlurl url="ftp://ftp.nectec.or.th/pub/mirrors/XFree86"
+ name="ftp://ftp.nectec.or.th/pub/mirrors/XFree86">
+ (¥½¡¼¥¹ ¥Ñ¥Ã¥Á ¤È ¥Ð¥¤¥Ê¥ê)
+<item> <htmlurl url="ftp://ftp.edu.tw/X/XFree86"
+ name="ftp://ftp.edu.tw/X/XFree86">
+ (¥½¡¼¥¹ ¤È ¥Ð¥¤¥Ê¥ê)
+</itemize>
+
+</itemize>
+
+
+ÇÛÉÕʪ¤«¤é XFree86 ¤òºîÀ®¤¹¤ë¤Î¤ËɬÍפʾðÊó¤Ï¡¢ÆÃÄê¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Ë¤¢
+¤ë <tt>README</tt> ¥Õ¥¡¥¤¥ë¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡£
+
+Æþ¼ê¤·¤¿ XFree86 3.1.2 ¤ò¤è¤¯³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£¤¤¤¯¤Ä¤«¤Î¥µ¥¤¥È¤Ï¡¢¸Å¤¤ÈÇ
+¤Î XFree86 ¤ò³ÊǼ¤·¤Æ¤¤¤ë¤³¤È¤¬¤è¤¯¤¢¤ê¤Þ¤¹¡£³Æ¡¹¤Î¥Ð¥¤¥Ê¥êÇÛÉÕʪ¤Ë¤Ï¡¢
+<htmlurl name="RELNOTE"
+url="RELNOTE.html"> ¤Ë³ÊǼ¾ì½ê¤«¤é¥À¥¦¥ó¤¹¤ëɬÍפΤ¢¤ë¥Õ¥¡¥¤¥ë
+¤Ë¤Ä¤¤¤Æµ­ºÜ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/README.sgml,v 3.3 1997/07/06 05:30:53 dawes Exp $
+</verb>
+<hrule>
+
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ï xc/programs/Xserver/hw/xfree86/doc/sgml/README.sgml,v 3.64 19
+96/10/26 09:38:53 ¤ò¡¢²¬ËÜ °ì¹¬
+( Kazuyuki Okamoto <url url="mailto:ikko-@pacific.rim.or.jp"
+name="&lt;ikko-@pacific.rim.or.jp&gt;"> ) ¤¬ XFree86 3.2 ¤ò
+ÆüËܤǥ¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¿Í¸þ¤±¤ËÏÂÌõ¤·¤¿¤â¤Î¤Ç¤¹¡£¤³¤³¤¬¤ª¤«¤·¤¤¤È¤«¡¢
+¤³¤³¤Ï¤³¤¦¤·¤¿¤Û¤¦¤¬¤¤¤¤¤È¤¤¤Ã¤¿¤´°Õ¸«¤¬¤¢¤ê¤Þ¤·¤¿¤é¡¢ÅŻҥ᡼¥ë¤Ç
+¤ªÃΤ餻²¼¤µ¤¤¡£
+¸¶Ê¸¤ÎÃøºî¸¢¤Ï XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ÎÏÂÌõ¤ÎÃøºî¸¢¤Ï
+XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤È²¬ËÜ¡¡°ì¹¬¤Ë¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤ÎÏÂÌõ¤ÎÉÔ¶ñ¹ç¤Ï»ä¤Ë¡¢
+ÅŻҥ᡼¥ë¤ÇÁ÷¤Ã¤Æ²¼¤µ¤¤¡£
+<hrule>
+&lsqb;EOF&rsqb;
+</article>
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/RELNOTE.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/RELNOTE.sgml
new file mode 100644
index 000000000..91e383a4b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/RELNOTE.sgml
@@ -0,0 +1,1766 @@
+<!doctype linuxdoc system>
+
+ <article>
+
+<!--
+ <title>Release Notes for XFree86&tm; 3.2
+ <author>The XFree86 Project, Inc
+ <date>26 October 1996
+-->
+ <title>XFree86&tm; 3.2 ¥ê¥ê¡¼¥¹¥Î¡¼¥È
+ <author>The XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò
+ <date>1996/10/26
+ <trans> ²¬ËÜ °ì¹¬ Kazuyuki Okamoto (ikko-@pacific.rim.or.jp)
+
+<abstract>
+
+<!--
+This document describes the rationale and conditions of this beta release,
+what is new in the XFree86 beta versions 3.1.2G, 3.1.2F, 3.1.2E, 3.1.2D,
+3.1.2B and 3.1.2A
+compared with the current release version 3.1.2, and how to install this
+beta release. Note: version 3.1.2C is included (in source form)
+in the X Consortium's X11R6.1 release.
+-->
+
+<!--
+This document describes the new features in XFree86 3.2 compared with the
+previous full release, 3.1.2. It also includes installation instructions
+for the binary distributions.
+-->
+¤³¤Îʸ½ñ¤Ï XFree86 3.2 ¤Ë¤Ä¤¤¤ÆÁ°²ó¤Î´°Á´¥Ð¡¼¥¸¥ç¥ó 3.1.2 ¤ÈÈæ¤Ù¤Æ¿·¤·¤¤
+µ¡Ç½¤òÀâÌÀ¤¹¤ë¤â¤Î¤Ç¤¹¡£¤Þ¤¿¡¢¥Ð¥¤¥Ê¥êÇÛÉÛʪ¤ÎÁȤ߹þ¤ß¼ê½ç¤â´Þ¤Þ¤ì¤Æ¤¤¤Þ
+¤¹¡£
+
+</abstract>
+
+<toc>
+
+<!--
+<sect> General Information about Beta Releases
+<p>
+This is a beta release of XFree86. XFree86 beta releases are available
+to the public in binary form only. Source code is available only to
+registered members of the XFree86 beta team. The main reason for this
+is that XFree86 beta versions often contain source code from other
+sources (such as the X Consortium) which is not yet available for public
+release. If you want to test or work on these releases at the source
+code level, you can apply for membership of the XFree86 beta team by
+sending email to <htmlurl name="XFree86@XFree86.org"
+url="mailto:XFree86@XFree86.org">.
+
+The X servers included in beta releases have a built-in expiry date.
+The reason for this is to try to prevent them from persisting beyond the
+date of the next release, and to encourage people to test new beta releases.
+The expiry date for 3.1.2G is 15 January 1997.
+
+The XFree86 binary beta releases may be freely redistributed providing that
+they are not modified in any way, and providing that an unmodified version
+of this document and the BetaReport document is included with the distribution.
+
+The reasons for making this beta release publicly available are to
+give it the widest possible testing, and also to make support for
+new hardware available.
+
+The XFree86 Project encourages people to test this beta release, and to
+send us a report. We need both success and failure reports, and we also
+need people using already supported hardware to test these beta releases
+to make sure that we haven't broken anything while adding support for
+new hardware. A template for the Beta test reports can be found in the
+file ``BetaReport'' which should be available from the same place you got
+this file. It is also installed in <tt>/usr/X11R6/lib/X11/doc/</tt>.
+Beta test reports should be sent to <htmlurl name="report@XFree86.org"
+url="mailto:report@XFree86.org">. Please do not send these reports to
+our usual support address.
+
+<url name="The XFree86 FAQ" url="http://www.xfree86.org/FAQ"> contains
+a section about the current beta version. It includes a regularly
+updated list of known problems. If you are having problems with the
+current beta version, please look here first.
+
+Note that much of the documentation provided with this release has not
+been updated and still refers to 3.1.2. If in doubt, check the date
+shown in the file(s).
+
+<sect> Who are the XFree86 Beta Releases Targeted At?
+<p>
+The XFree86 beta releases are intended for people who are prepared to
+test software which might be unstable and which might be buggy, and report
+the results of the testing. These beta releases are not intended for
+beginners, but for people who have a basic knowledge of the OS so that they
+don't require much support for issues like upgrading system libraries and
+obtaining necessary packages.
+
+If you are going to test this software, you should be prepared for the
+following:
+<itemize>
+ <item>Installation problems. The installation procedure for beta releases
+ gets only very limited testing prior to release. You should be
+ prepared for problems here, and you should be prepared to upgrade
+ other components of your system if it proves necessary. You should
+ also have facilities to backup a previous installation (and
+ preferably your entire system) so that it can be restored in case
+ of serious problems.
+ <item>New bugs. Since each beta version gets only a limited amount of
+ pre-release testing, it is likely that a new version will contain
+ new bugs. This is unavoidable, because any code change, be it
+ fixing previous bugs or adding new features, brings with it the
+ chance that new bugs have been introduced. You should be prepared
+ for the possibility that the new version will have problems with
+ your hardware. In this situation, you should first check the
+ <url name="XFree86 FAQ" url="http://www.xfree86.org/FAQ"> to
+ see if it is a known problem (possibly with a workaround), and then
+ report the problem in detail.
+ <item>Expiry date. The XFree86 beta servers have a limited lifetime.
+ Before using one, you should be aware of this and what the
+ implications of this are. If you have objections to software
+ that has an expiry date, you shouldn't use this beta software.
+ It is possible that when one version expires you may find that
+ the replacement version has problems, or perhaps binaries of the
+ replacement are not available for your OS. If you depend on a
+ server for your work/school/etc, you shouldn't be relying on
+ this beta software.
+</itemize>
+-->
+<!--
+<sect> XFree86 and X11R6.1
+-->
+<sect> XFree86 ¤È X11R6.1
+<p>
+<!--
+XFree86 releases starting with the 3.1.2D beta are based on the X Consortium's
+X11R6.1.
+
+R6.1 is an update to R6,
+and is intended to be compatible with R6 at the source and protocol
+levels. Binaries should be upward-compatible. X11R6.1 includes some
+new Xserver extensions: DOUBLE-BUFFER, XKEYBOARD and RECORD. LBX has
+been dropped from R6.1, and as such, has been dropped from XFree86 too.
+It is expected that it will reappear in some form in a future release.
+<p>
+-->
+X ¥³¥ó¥½¡¼¥·¥¢¥à¤Î X11R6.1 ¤ò´ð¤Ë¤·¤¿ XFree86 3.1.2D ¥Ù¡¼¥¿ÈÇ ¤«¤é»Ï¤Þ¤ê¤Þ¤·
+¤¿¡£
+R6.1 ¤Ï R6 ¤ÎºÇ¿·ÈǤǡ¢
+¥½¡¼¥¹¤È¥×¥í¥È¥³¥ë¤Ç R6 ¤È¸ß´¹À­¤¬¤¢¤ê¤Þ¤¹¡£¥Ð¥¤¥Ê¥ê¤Ï¾å°Ì¸ß´¹¤Ç¤¹¡£
+X11R6.1 ¤Ï DOUBLE-BUFFER, XKEYBOARD ¤È RECORD ¤È¤¤¤¦¿·¤·¤¤ X ¥µ¡¼¥Ð
+µ¡Ç½³ÈÄ¥¤ò´Þ¤ó¤Ç¤¤¤Þ¤¹¡£LBX ¤Ï R6.1 ¤«¤é̵¤¯¤Ê¤ê¤Þ¤·¤¿¡£½¾¤Ã¤Æ
+XFree86 ¤«¤é¤â̵¤¯¤Ê¤ê¤Þ¤·¤¿¡£¾­Í貿¤«¤Î·Á¤Ç¤ÎºÆÅоì¤ò´üÂÔ¤·¤Þ¤¹¡£
+
+<!--
+<sect> OS issues
+-->
+<sect> OS ¤ËͳÍ褹¤ë¹àÌÜ
+<p>
+<!--
+Always check the OS specific README files for
+special requirements or caveats.
+-->
+ÆÃÊ̤ÊÍ×µá»ö¹à¤ä·Ù¹ð¤Ë´Ø¤¹¤ë OS ÆÃÍ­¤Î README ¥Õ¥¡¥¤¥ë¤ò¾ï¤Ë³Îǧ¤·¤Æ
+¤¯¤À¤µ¤¤¡£
+<p>
+<!--
+Users running Linux/Elf (on Intel platforms) should note that they will
+need ld.so-1.7.14. This
+can be found at <url name="tsx-11.mit.edu:pub/linux/packages/GCC"
+url="ftp://tsx-11.mit.edu/pub/linux/packages/GCC">.
+-->
+¥¤¥ó¥Æ¥ë¾å¤Ç Linux/Elf ¤ò²ÔƯ¤µ¤»¤ë¾ì¹ç¤Ï ld.so-1.7.14 ¤òÆþ¼ê¤¹¤ëɬÍפ¬
+¤¢¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤³¤Î¥é¥¤¥Ö¥é¥ê¤Ï
+<url name="tsx-11.mit.edu:pub/linux/packages/GCC"
+url="ftp://tsx-11.mit.edu/pub/linux/packages/GCC">
+¤Ë¤¢¤ê¤Þ¤¹¡£
+
+<!--
+<sect> New Features in 3.2
+-->
+<sect> 3.2 ¤Ç¤Î¿·µ¡Ç½
+<p>
+<!--
+Note, items marked with `*' have been added since the last beta release
+(3.1.2G).
+-->
+'*' °õ¤¬ÉÕ¤¤¤Æ¤¤¤ë¹àÌܤϺǽª¦ÂÈÇ (3.1.2G) ¤ËÄɲä·¤¿¤Î¤ÇÃí°Õ¤·¤Æ¤¯¤À
+¤µ¤¤¡£
+<p>
+<!--
+<sect1> General
+-->
+<sect1> Á´ÈÌ
+<p>
+<!--
+<itemize>
+ <item>XFree86 3.2 includes the X Consortium's X11R6.1.
+ <item>XFree86-3.2 includes a full distribution for Linux/m68k.
+ <item>XFree86-3.2 includes a full distribution for Linux/Alpha.
+ <item>XFree86-3.2 includes a full distribution for OS/2.
+</itemize>
+-->
+<itemize>
+ <item>XFree86 3.2 ¤Ï X ¥³¥ó¥½¡¼¥·¥¢¥à¤Î X11R6.1 ¤ò´Þ¤ó¤Ç¤¤¤Þ¤¹¡£
+ <item>XFree86-3.2 Linux/m68k ÍѤÎÁ´ÇÛÉÛʪ¤ò´Þ¤ó¤Ç¤¤¤Þ¤¹¡£
+ <item>XFree86-3.2 Linux/Alpha ÍѤÎÁ´ÇÛÉÛʪ¤ò´Þ¤ó¤Ç¤¤¤Þ¤¹¡£
+ <item>XFree86-3.2 OS/2 ÍѤÎÁ´ÇÛÉÛʪ¤ò´Þ¤ó¤Ç¤¤¤Þ¤¹¡£
+</itemize>
+
+<!--
+<sect1> General X server changes
+-->
+<sect1> X ¥µ¡¼¥Ð Á´È̤ÎÊѹ¹¹àÌÜ
+<p>
+<!--
+<itemize>
+ <item>A `DefaultColorDepth' keyword has been added for the Screen section
+ in XF86Config files to allow the default bpp to be specified.
+ <item>A `-nolock' server command-line option has been added to allow
+ the server's locking mechanism to be disabled.
+ <item>All VGA cards with a set of discrete clocks (i.e. not a ClockChip or
+ a ClockProg) can now also use all the clocks mentioned in the
+ clocks line divided by 2. This presents the server with twice as
+ many clocks to choose from. Add the option "clkdiv2" to the "Device"
+ section of XF86Config to enable this.
+ <item>Some cursor colouring bugs have been fixed for servers that use
+ hardware cursors.
+ <item>A security problem related to the X server's lock files has been
+ fixed.
+ <item>The VidMode extension (as used by xvidtune) now by default only allows
+ changes to modes by clients using a local connection type. There is
+ also an option to completely disable mode changes via this extension.
+ <item>A new server extension called "XFree86-Misc" has been added. The
+ primary purpose of this is to allow reconfiguration of some parameters
+ while the server is running. Some functions previously in the
+ VidMode extension (like screen save functions) have been moved to
+ this new extension.
+ <item>Support has been added for the ALPS GlidePoint. A tap on the pad
+ is treated as a fourth button.
+ <item>The XKEYBOARD extension is included in the servers as part of X11R6.1.
+ It is enabled by default, but can be disabled either from the command
+ line (see the Xserver man page) or from the XF86Config file
+ (see XkbDisable in the XF86Config man page). With this extension
+ enabled, you may see some differences in the keyboard mappings.
+ <item>A new extension called XFree86-DGA is now provided. This allows
+ a client program to get direct access to the video card's memory.
+ This is implemented for most of the servers/drivers that can support
+ it. Connections are only allowed from clients using a local
+ connection type (e.g., DISPLAY=":0").
+ For details
+ of the client-side API, see the XF86DGA(3) man page, and the file
+ README.DGA.
+ <item>An implementation of the XInput extension is now included. It
+ has support for the following devices:
+ <itemize>
+ <item>Joystick (Linux, FreeBSD, NetBSD and OpenBSD only)
+ <item>Wacom tablet (Wacom IV protocol only)
+ <item>Elographics touchscreen
+ <item>SummaSketch tablet
+ <item>Mouse
+ </itemize>
+ Refer to the XF86Config(4/5) manual page and the <htmlurl
+ name="xinput document" url="xinput.html"> for configuration details.
+ <item>The default black and white pixel values are now black = 0 and
+ white = 1 for all servers. This may be swapped with the
+ `-flipPixels' command-line option.
+ <item>Underscore characters are now ignored in Options and keywords in the
+ XF86Config file.
+ <item>The built-in X server malloc is used by default.
+ <item>A problem that can cause the X server to crash when running
+ xvidtune has been fixed.
+ <item>Bitmap fontpath elements can have <tt>&dquot;:unscaled&dquot;</tt>
+ appended to prevent the fonts from being treated as scalable. This
+ works with the fontserver (xfs) too.
+ <item>*The PEX and XIE server extensions can now be dynamically loaded
+ for Linux/ELF, FreeBSD, NetBSD and OpenBSD.
+</itemize>
+-->
+<itemize>
+ <item>`DefaultColorDepth' ¤È¤¤¤¦¹àÌܤò XF86Config ¥Õ¥¡¥¤¥ë¤Î
+ Screen Àá¤Ë bpp ¤Îɸ½àÃͤ¬»ØÄê½ÐÍè¤ë¤è¤¦¤ËÄɲä·¤Þ¤·¤¿¡£
+ <item>`-nolock' ¤È¤¤¤¦ X ¥µ¡¼¥Ð¤Î¥ª¥×¥·¥ç¥ó¤¬¥µ¡¼¥Ð¤Î²èÌÌ¥í¥Ã¥¯µ¡¹½
+ ¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£
+ <item>ʬΥ¥¯¥í¥Ã¥¯¥Á¥Ã¥×¥»¥Ã¥È (ClockChip ¤Ç¤â ClockProg ¤Ç¤â¤Ê¤¯)
+ ¤òÅëºÜ¤·¤Æ¤¤¤ëÁ´¤Æ¤Î VGA ¥Ó¥Ç¥ª¥«¡¼¥É¤Ç clocks ¹Ô¤Ç 2 ¤Ç³ä¤Ã¤¿
+ ¥¯¥í¥Ã¥¯¼þÇÈ¿ô¤ò»ØÄê¤Ç¤­¤ë¤è¤¦¤Ë¤â¤Ê¤ê¤Þ¤·¤¿¡£¤³¤ì¤Ë¤è¤ê
+ ¥µ¡¼¥Ð¤ÇÇܤΥ¯¥í¥Ã¥¯»ØÄê·Á¼°¤òÁªÂò¤Ç¤­¤Þ¤¹¡£ XF86Config ¥Õ¥¡¥¤¥ë¤Î
+ "Device" Àá¤Ë "clkdiv2" ¥ª¥×¥·¥ç¥ó¤òÄɲ乤ë¤È²Äǽ¤Ë¤Ê¤ê¤Þ¤¹¡£
+ <item>¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½¥ë¤ò»È¤Ã¤Æ¤¤¤ë¥µ¡¼¥Ð¤Î¥«¥é¡¼²½¤·¤¿¥«¡¼¥½¥ë¤Î
+ ¥Ð¥°¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>X ¥µ¡¼¥Ð¤Î¥í¥Ã¥¯¥Õ¥¡¥¤¥ë¤Ë´Ø¤¹¤ëÊݰ¾å¤ÎÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>º£²ó¡¢É¸½à¤Ç (xvidtune ¤Ç»ÈÍѤ·¤Æ¤¤¤ë) VidMode µ¡¹½³ÈÄ¥¤Ï
+ ¥í¡¼¥«¥ëÀܳ¤Î¥¯¥é¥¤¥¢¥ó¥È¤«¤é¥Ó¥Ç¥ª¥â¡¼¥É¤òÊѹ¹½ÐÍè¤ë¤è¤¦¤Ë
+ ¤Ê¤ê¤Þ¤·¤¿¡£
+ <item>º£²ó "XFree86-Misc" ¤È¸Æ¤Ö¿·¤·¤¤¥µ¡¼¥Ð¤Îµ¡Ç½³ÈÄ¥¤òÄɲä·¤Þ¤·
+ ¤¿¡£¤³¤Îµ¡Ç½³ÈÄ¥¤Î¼ç¤¿¤ëÌÜŪ¤Ï¥µ¡¼¥Ð¤Î²ÔÆ¯Ãæ¤Ë¤¤¤¯¤Ä¤«¤Î¥Ñ¥é¥á¡¼¥¿
+ ¤òºÆ¹½À®½ÐÍè¤ë¤è¤¦¤Ë¤¹¤ë¤â¤Î¤Ç¤¹¡£°ÊÁ°¤Î VidMode µ¡Ç½³ÈÄ¥¤Î¤¤¤¯¤Ä
+ ¤«¤Î (¥¹¥ê¡¼¥ó¥»¡¼¥Ðµ¡Ç½¤ÎÍͤÊ) µ¡Ç½¤Ï¤³¤Î¿·¤·¤¤µ¡Ç½³ÈÄ¥¤Ë°Üư¤·¤Þ
+ ¤·¤¿¡£
+ <item>ALPS GlidePoint ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£¥Ñ¥Ã¥É¤ò¥¿¥Ã¥×¤¹¤ë»ö¤ò
+ Â裴¤Î¥Ü¥¿¥ó¤È¤·¤Æ»ÈÍѽÐÍè¤Þ¤¹¡£[ÌõÃí : ¥¿¥Ã¥×¤È¤Ï¥Ý¥ó¥Ý¥ó¤È᤯»ö]
+ <item>X11R6.1 ¤Î°ìÉô¤Ç¤¢¤ë XKEYBOARD µ¡Ç½³ÈÄ¥¤ò¥µ¡¼¥Ð¤Ë´Þ¤á¤Þ¤·¤¿¡£
+ ɸ½à¤Ç»ÈÍѲÄǽ¤Ç¤¹¤¬¡¢¥³¥Þ¥ó¥É¹Ô¤«¤é (Xserver ¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë
+ ¤ò»²¾È) ¤Þ¤¿¤Ï XF86Config ¥Õ¥¡¥¤¥ë¤«¤é (XF86Config ¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å
+ ¥¢¥ë¤Î XkbDisable ¤ò»²¾È) ̵¸ú¤Ë½ÐÍè¤Þ¤¹¡£¤³¤Îµ¡Ç½³ÈÄ¥¤òÍ­¸ú¤Ë
+ ¤¹¤ë¤È¡¢¥­¡¼¥Ü¡¼¥É¤Î¥­¡¼³ä¤êÉÕ¤±¤¬¤¤¤¯¤Ä¤«°Û¤Ê¤ë»ö¤¬Ê¬¤«¤ë¤Ç¤·¤ç¤¦¡£
+ <item>º£²ó¡¢XFree86-DGA ¤È¸Æ¤Ð¤ì¤ë¿·¤·¤¤µ¡Ç½³ÈÄ¥¤òÄ󶡤·¤Þ¤¹¡£
+ ¤³¤Îµ¡Ç½³ÈÄ¥¤Ë¤è¤Ã¤Æ¥¯¥é¥¤¥¢¥ó¥È¥×¥í¥°¥é¥à¤¬Ä¾Àܥӥǥª¥«¡¼¥É
+ ¤Î¥á¥â¥ê¤Ë¥¢¥¯¥»¥¹½ÐÍè¤Þ¤¹¡£ËؤɤΥµ¡¼¥Ð/¥¯¥é¥¤¥¢¥ó¥È¤ÇÍøÍѲÄǽ¤Ç¤¹¡£
+ ¥í¡¼¥«¥ëÀܳ·¿ (Î㤨¤Ð DISPLAY=":0") ¤Î¥¯¥é¥¤¥¢¥ó¥È¤Î¤ß¤Ç¤¹¡£
+ ¥¯¥é¥¤¥¢¥ó¥È¦¤Î API ¤Î¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï¡¢XF86DGA(3) ¤Î¥ª¥ó¥é¥¤¥ó¥Þ
+ ¥Ë¥å¥¢¥ë¤È README.DGA ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ <item>º£²ó¡¢XInput µ¡Ç½³ÈÄ¥¤Î¼ÂÁõ¤ò´Þ¤á¤Þ¤·¤¿¡£¤³¤Îµ¡Ç½³ÈÄ¥¤Ï¼¡¤Î
+ ¥Ç¥Ð¥¤¥¹¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£:
+ <itemize>
+ <item>¥¸¥ç¥¤¥¹¥Æ¥£¥Ã¥¯ (Linux, FreeBSD, NetBSD ¤È OpenBSD ¤Î¤ß)
+ <item>Wacom ¥¿¥Ö¥ì¥Ã¥È (Wacom IV ¥×¥í¥È¥³¥ë ¤Î¤ß)
+ <item>Elographics ¥¿¥Ã¥Á¥¹¥¯¥ê¡¼¥ó
+ <item>SummaSketch ¥¿¥Ö¥ì¥Ã¥È
+ <item>¥Þ¥¦¥¹
+ </itemize>
+ ¹½À®ÄêµÁ¤Ë¤Ä¤¤¤Æ¤Ï XF86Config(4/5) ¤È
+ <htmlurl name="xinput document" url="xinput.html">
+ ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+ <item>º£²ó¡¢É¸½à¤Î¹õ¤ÈÇò¤Î¥Ô¥¯¥»¥ë¤Î¿ôÃͤÏÁ´¤Æ¤Î¥µ¡¼¥Ð¤Ç¹õ = 0 ¤È
+ Çò = 1 ¤Ç¤¹¡£¤³¤ì¤òÆþ¤ìÂØ¤¨¤ë¤Ë¤Ï `-flipPixels' ¤Î¥³¥Þ¥ó¥É¹Ô
+ ¥ª¥×¥·¥ç¥ó¤ò»È¤¤¤Þ¤·¤ç¤¦¡£
+ <item>º£²ó¡¢²¼Àþʸ»ú¤Ï XF86Config ¥Õ¥¡¥¤¥ëÆâ¤Î Options ¤È ¥­¡¼¥ï¡¼¥É
+ ¤Ç¤Ï̵»ë¤µ¤ì¤Þ¤¹¡£
+ <item>ɸ½à¤Ç X ¥µ¡¼¥ÐÆâ¢¤Î malloc ¤ò»È¤¤¤Þ¤¹¡£
+ <item>¥Ó¥Ã¥È¥Þ¥Ã¥×¥Õ¥©¥ó¥È¥Ñ¥¹Í×ÁÇ¤Ë <tt>&dquot;:unscaled&dquot;</tt>
+ ¤òÄɲ乤ë¤È¥Õ¥©¥ó¥È¤ò³ÈÂç½Ì¾®½ÐÍè¤Ê¤¤Íͤ˽ÐÍè¤Þ¤¹¡£¤³¤ì¤Ï¥Õ¥©¥ó¥È
+ ¥µ¡¼¥Ð (xfs) ¤Ç¤âưºî¤·¤Þ¤¹¡£
+ <item>*º£²ó¡¢PEX ¤È XIE ¥µ¡¼¥Ðµ¡Ç½³ÈÄ¥¤¬ Linux/ELF, FreeBSD, NetBSD
+ ¤È OpenBSD ¤Ç¤ÏưŪ¤Ë¥í¡¼¥É½ÐÍè¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£
+</itemize>
+
+<!--
+<sect1> XF86Setup
+-->
+<sect1> XF86Setup ¤Ë¤Ä¤¤¤Æ
+<p>
+<!--
+<itemize>
+ <item>3.2 includes a new, graphical utility for X server configuration
+ called `XF86Setup'. NOTE: this utility requires that you have the
+ VGA16 server installed, as well as the server specific to your
+ video card.
+</itemize>
+-->
+<itemize>
+ <item>`XF86Setup' ¤È¸Æ¤Ö X ¥µ¡¼¥Ð¤Î¹½À®¾ðÊóÄêµÁ¤Î¿·¤·¤¤¥°¥é¥Õ¥£¥Ã¥¯
+ ¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤Î¥æ¡¼¥Æ¥£¥ê¥Æ¥£¤ò 3.2 ¤Ë´Þ¤ß¤Þ¤·¤¿¡£
+ Ãí°Õ»ö¹à: VGA ¥µ¡¼¥Ð¤¬Æ³ÆþºÑ¤Ç¥Ó¥Ç¥ª¥«¡¼¥É¤Ë¹ç¤ï¤»¤ÆÀßÄêºÑ¤¬Á°Äó
+ ¤Ç¤¹¡£
+</itemize>
+<!--
+<sect1> PC98 Support
+-->
+<sect1> PC98 ¤Î¥µ¥Ý¡¼¥È
+<p>
+<!--
+<itemize>
+ <item>Support has been added for PC98 machines. These are Intel based
+ machines which are common in Japan.
+ <item>Support has been added for the PANIX-PC98 SVR4.0 OS.
+ <item>The following PC98-specific X servers are included:
+ <itemize>
+ <item>XF98_NECS3 PC98 NEC(S3) server.
+ <item>XF98_PWSKB SKB-PowerWindow(S3) server.
+ <item>XF98_PWLB PC98 PowerWindowLB(S3) server.
+ <item>XF98_GA968 GA-968V4/PCI(S3 968).
+ <item>XF98_TGUI Cyber9320 and TGUI9680.
+ <item>XF98_NKVNEC NKV-NEC(cirrus) server.
+ <item>XF98_WABS WABS(cirrus) server.
+ <item>XF98_GANBWAP GANB-WAP(cirrus) server.
+ <item>XF98_WABEP WAB-EP(cirrus) server.
+ <item>XF98_WSNA WSN-A2F(cirrus) server.
+ <item>XF98_EGC EGC(generic vga16) server.
+ <item>XF98_NEC480 PEGC-480(generic vga256) server.
+ </itemize>
+</itemize>
+-->
+<itemize>
+ <item>PC98 ¥Ñ¥½¥³¥ó¤òÄɲ嵥ݡ¼¥È¤·¤Þ¤·¤¿¡£¤³¤Î¥Ñ¥½¥³¥ó¤Ï¥¤¥ó¥Æ¥ë¤ò
+ »È¤Ã¤¿¥Ñ¥½¥³¥ó¤ÇÆüËܤÇÉáµÚ¤·¤Æ¤¤¤Þ¤¹¡£
+ <item>PANIX-PC98 SVR4.0 ¤È¤¤¤¦ OS Âбþ¤ÇÄɲä·¤Þ¤·¤¿¡£
+ <item>¼¡¤Î PC-98 ÆÃÍ­¤Î X ¥µ¡¼¥Ð¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£
+ <itemize>
+ <item>XF98_NECS3 PC98 NEC(S3) ¥µ¡¼¥Ð¡£
+ <item>XF98_PWSKB SKB-PowerWindow(S3) ¥µ¡¼¥Ð¡£
+ <item>XF98_PWLB PC98 PowerWindowLB(S3) ¥µ¡¼¥Ð¡£
+ <item>XF98_GA968 GA-968V4/PCI(S3 968)¡£
+ <item>XF98_TGUI Cyber9320 and TGUI9680¡£
+ <item>XF98_NKVNEC NKV-NEC(cirrus) ¥µ¡¼¥Ð¡£
+ <item>XF98_WABS WABS(cirrus) ¥µ¡¼¥Ð¡£
+ <item>XF98_GANBWAP GANB-WAP(cirrus) ¥µ¡¼¥Ð¡£
+ <item>XF98_WABEP WAB-EP(cirrus) ¥µ¡¼¥Ð¡£
+ <item>XF98_WSNA WSN-A2F(cirrus) ¥µ¡¼¥Ð¡£
+ <item>XF98_EGC EGC(generic vga16) ¥µ¡¼¥Ð¡£
+ <item>XF98_NEC480 PEGC-480(generic vga256) ¥µ¡¼¥Ð¡£
+ </itemize>
+</itemize>
+<!--
+<sect1> XInput Extension
+-->
+<sect1> XInput µ¡Ç½³ÈÄ¥
+<p>
+<!--
+<itemize>
+ <item>Motion history support is included for XInput devices.
+ <item>XInput drivers are now dynamically loadable for Linux/ELF, FreeBSD,
+ and NetBSD.
+ <item>Multiple instances of XInput devices may be specified.
+</itemize>
+-->
+<itemize>
+ <item>XInput ¥Ç¥Ð¥¤¥¹Âбþ¤Î±ÇÁü·¿¤ÎÁàºîÍúÎò(¥â¡¼¥·¥ç¥ó¥Ò¥¹¥È¥ê:
+ motion history) ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item>º£²ó¡¢XInput ¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤Ï Linux/ELF, FreeBSD ¤È NetBSD¤Ç¤Ï
+ ưŪ¤Ë¥í¡¼¥Ç¥£¥ó¥°¤µ¤ì¤Þ¤¹¡£
+ <item>Ê£¿ô¤Î XInput ¥Ç¥Ð¥¤¥¹¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£
+</itemize>
+<!--
+<sect1> S3 server
+-->
+<sect1> S3 ¥µ¡¼¥Ð
+<p>
+<!--
+<itemize>
+ <item>Support for the S3 Trio64V+.
+ <item>*New server (XF86_S3V) for the S3 ViRGE and ViRGE/VX. Note that this
+ server is very new, and is considered "beta". Please report any
+ problems with it.
+ <item>Support in the S3 server for the AT&amp;T 20C409 and 20C499 RAMDACs.
+ <item>Some potential problems with the way the accelerator is used have
+ been fixed.
+ <item>A new driver has been added for the 868/968/Trio64V+ which uses
+ the new MMIO mode available with these chips. This new driver is
+ used by default for these chips on Intel platforms, but not yet
+ on Alpha platforms. It can be enabled for Alpha platforms by
+ specifying:
+ <verb>
+ Chipset "NewMMio"
+ </verb>
+ If you see any problems with the new driver, please let us know.
+ It is possible to
+ disable this new driver and use the old one by specifying:
+ <verb>
+ Chipset "mmio_928"
+ </verb>
+ in the Device section. Please test the new driver before
+ disabling it, and for any problem you see, also check if it happens
+ with the old driver, and let us know (even if the old driver fixes
+ the problem!).
+ <item>An initialisation problem with some VideoLogic cards has been fixed.
+ <item>Support for the ELSA Winner 2000PRO/X rev G and ELSA Gloria-8 (except
+ the GLint 300SX 3D chip) has been added.
+ <item>Problems with S3 dashed lines are fixed.
+ <item>Added options "slow_dram" and "slow_edodram" to avoid pixel
+ errors on the display for some broken cards.
+ <item>A Ti3026 clock problem that appears on some SPEA cards has been fixed.
+ <item>Code has been added to automatically detect the Trio32 bug that causes
+ font cache problems. When detected, a workaround is activated..
+ <item>Framebuffer address problems with some 1MB Trio64 VLB cards should
+ be fixed.
+ <item>The low ICS5342 clock limit has been removed.
+ <item>Detection of Diamond S3 cards has been improved. If you've needed
+ to use the "diamond" option to avoid screen wrapping in previous
+ releases, try removing it and let us know if there are any problems.
+ <item>Memory parameter calculations for 2MB Trio64 cards have been fixed.
+ If you've needed to add something like "S3MClk 170" to your
+ XF86Config with previous versions, you should remove it now.
+ <item>The handling of the S3RefClk XF86Config setting has been fixed
+ for cards with an IBM Ramdac.
+ <item>Support for S3 and Bt485 HW cursor in doublescan modes.
+ <item>Fix positioning of IBM RGB Ramdac HW cursor in interlace and
+ doublescan modes (the cursor shape still isn't correct).
+ <item>Improved linear fb detection for PCI cards. In particular this
+ should allow most Trio64V+ cards to use the linear fb, which
+ seems to prevent a lot of the lockups that have been reported.
+ <item>Support for the ELSA Elsa Winner2000PRO/X-2,4 Rev.G which uses
+ an ICS9161A clock chip as well as the Ti3026 RAMDAC (clock
+ doubling not supported yet).
+ <item>The default InvertVCLK settings have been changed for &num;9 Motion
+ 771 cards and Hercules Terminator 64 Pro cards. If you have
+ needed to add Invert_VCLK lines to your XF86Config file to avoid
+ screen wrapping with version 3.1.2, please remove them when
+ testing this version. If there are problems with the new
+ defaults, please report them to us.
+ <item>*Text clipping performance has been improved.
+</itemize>
+-->
+<itemize>
+ <item>S3 Trio64V+ ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£
+ <item>*S3 ViRGE ¤È ViRGE/VX Âбþ¤Î¿·¤·¤¤¥µ¡¼¥Ð (XF86_S3V) ¡£¤³¤Î¥µ¡¼¥Ð¤Ï
+ ÂçÊÑ¿·¤·¤¤¤Î¤Ç "¥Ù¡¼¥¿ÈÇ" ¤È»×¤Ã¤ÆÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤³¤ì¤Çµ¯¤­¤¿¤É¤ó¤Ê
+ ÌäÂê¤Ç¤âÊó¹ð¤·¤Æ¤¯¤À¤µ¤¤¡£
+ <item>AT&amp;T 20C409 ¤È 20C499 RAMDAC Âбþ¤Î S3 ¥µ¡¼¥Ð¡£
+ <item>¥¢¥¯¥»¥é¥ì¡¼¥¿¤ÇȯÀ¸¤·¤¦¤ëÀøºßŪ¤ÊÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>¿·¤·¤¤ MMIO ¥â¡¼¥É¤ò»È¤¦ 868/968/Trio64V+ Âбþ¤Î¿·¤·¤¤¥É¥é¥¤¥Ð¤ò
+ S3 ¥µ¡¼¥Ð¤ËÄɲä·¤Þ¤·¤¿¡£¤³¤Î¿·¤·¤¤¥É¥é¥¤¥Ð¤Ï¥¤¥ó¥Æ¥ëµ¡¤Î¤³¤ì¤é¤Î
+ ¥Á¥Ã¥×Âбþ¤Çɸ½à¤Ë»È¤¤¤Þ¤¹¡£¥¢¥ë¥Õ¥¡µ¡Âбþ¤Ç¤Ï¼¡¤Î¤è¤¦¤Ë»ØÄꤹ¤ë
+ ¤È»ÈÍѤǤ­¤Þ¤¹¡£
+ <verb>
+ Chipset "NewMMio"
+ </verb>
+ ¿·¤·¤¤¥É¥é¥¤¥Ð¤Ç²¿¤«ÌäÂ꤬µ¯¤­¤¿¤é¡¢»ä¤¿¤Á¤Ë¤ªÃΤ餻¤¯¤À¤µ¤¤¡£
+ ¤³¤Î¿·¤·¤¤¥É¥é¥¤¥Ð¤¬»È¤¨¤Ê¤¤¾ì¹ç¤È¤«¸Å¤¤¥É¥é¥¤¥Ð¤Ç¤Ï°Ê²¼¤Î¤è¤¦¤Ë
+ Device Àá¤Ç»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£:
+ <verb>
+ Chipset "mmio_928"
+ </verb>
+ ¿·¤·¤¤¥É¥é¥¤¥Ð¤ò̵¸ú¤ËÀßÄꤹ¤ëÁ°¤Ë¥Æ¥¹¥È¤·¤Æ¤¯¤À¤µ¤¤¡£²¿¤«ÌäÂ꤬
+ µ¯¤­¤¿¤é¡¢¸Å¤¤¥É¥é¥¤¥Ð¤Ç¤âÌäÂ꤬ºÆ¸½¤¹¤ë¤«»î¤·¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£
+ ·ë²Ì¤ò»ä¤¿¤Á¤Ë¶µ¤¨¤Æ¤¯¤À¤µ¤¤¡£(¸Å¤¤¥É¥é¥¤¥Ð¤Ç¤ÏÌäÂê¤Ï½¤Àµ¤·¤Æ¤¤¤ë
+ ¤Ï¤º¤Ê¤Î¤Ç¤¹¤¬¡ª)
+ <item>¤¤¤¯¤Ä¤«¤Î VideoLogic ¥Ó¥Ç¥ª¥«¡¼¥É¤ÇȯÀ¸¤¹¤ë½é´ü²½¤ÎÌäÂê¤ò
+ ½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>ELSA Winner 2000PRO/X rev G ¤È ELSA Gloria-8 (GLint 300SX 3D
+ ¥Á¥Ã¥×¤ò½ü¤¯) ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item>S3 ¥µ¡¼¥Ð¤ÎºÙ¤«¤ÊÀþ¤ÎÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>¤¤¤¯¤Ä¤«¤Î¥¤¥«¤ì¤¿¥Ó¥Ç¥ª¥«¡¼¥É¤Çɽ¼¨¾å¤Î¥Ô¥¯¥»¥ë¥¨¥é¡¼¤ò²óÈò
+ ¤¹¤ë¤¿¤á "slow_dram" ¤È "slow_edodram" ¥ª¥×¥·¥ç¥ó¤òÄɲä·¤Þ¤·¤¿¡£
+ <item>¤¤¤¯¤Ä¤«¤Î SPEA ¥Ó¥Ç¥ª¥«¡¼¥É¤ÇȯÀ¸¤¹¤ë Ti3026 ¤Î¥¯¥í¥Ã¥¯¤Î
+ ÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>¥Õ¥©¥ó¥È¥­¥ã¥Ã¥·¥å¤ÎÌäÂê¤òµ¯¤³¤¹ Trio32 ¤Î¥Ð¥°¤ò¼«Æ°Åª¤Ë¸¡½Ð
+ ¤¹¤ë¥×¥í¥°¥é¥à¤òÄɲä·¤Þ¤·¤¿¡£¸¡½Ð¤·¤¿¾ì¹ç¡¢²óÉüºî¶È¤¬³èư¤·¤Þ¤¹¡£
+ <item>¤¤¤¯¤Ä¤«¤Î 1MB Trio64 VLB ¥Ó¥Ç¥ª¥«¡¼¥É¤Ç¤Î¥Õ¥ì¡¼¥à¥Ð¥Ã¥Õ¥¡
+ ¥¢¥É¥ì¥¹¤ÎÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>ICS5342 ¥¯¥í¥Ã¥¯¤Î²¼¸Â¤ÎÀ©¸Â¤ò̵¤¯¤·¤Þ¤·¤¿¡£
+ <item>Diamond S3 ¥Ó¥Ç¥ª¥«¡¼¥É¤ÎõÃΤò²þÎɤ·¤Þ¤·¤¿¡£°ÊÁ°¤Î¥Ð¡¼¥¸¥ç¥ó
+ ¤ÇȯÀ¸¤·¤Æ¤¤¤¿²èÌ̤βö¤ê¹þ¤ß¤ò²óÈò¤¹¤ë "diamond" ¥ª¥×¥·¥ç¥ó¤ò»È¤¦
+ ɬÍפ¬Ìµ¤¤¾ì¹ç¤Ï¼è¤ê½ü¤¤¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£²¿¤«ÌäÂ꤬¤¢¤ë¾ì¹ç¤Ï»ä¤¿
+ ¤Á¤ËÏ¢Íí¤ò¤¯¤À¤µ¤¤¡£
+ <item>2MB Trio64 ¥Ó¥Ç¥ª¥«¡¼¥ÉÍѤΥá¥â¥ê¥Ñ¥é¥á¥¿¤Î·×»»¤ò½¤Àµ¤·¤Þ¤·
+ ¤¿¡£°ÊÁ°¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç XF86Config ¥Õ¥¡¥¤¥ë¤ËÄɲ乤ëɬÍפ¬¤¢¤Ã¤¿
+ "S3MClk 170" ¤ÎÍͤʥѥé¥á¥¿¤Ï¡¢º£²ó¤«¤é¼è¤ê½ü¤¤¤Æ¤¯¤À¤µ¤¤¡£
+ <item>IBM ¤Î Ramdac ¤ò»È¤Ã¤Æ¤¤¤ë¥Ó¥Ç¥ª¥«¡¼¥É¤Î XF86Config ¤ÎÀßÄê¤Ç¤Î
+ S3RefClk ¤Î¼è°·¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>¥À¥Ö¥ë¥¹¥­¥ã¥ó¥â¡¼¥É¤Ç¤Î S3 ¤È Bt485 ¤Î¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½¥ë¤ò
+ ¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item>¥¤¥ó¥¿¡¼¥ì¡¼¥¹¥â¡¼¥É¤È¥À¥Ö¥ë¥¹¥­¥ã¥ó¥â¡¼¥É¤Ç¤Î IBM RGB Ramdac
+ ¤Î¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½¥ë¤Î°ÌÃÖ·è¤á¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿(¥«¡¼¥½¥ë¤Î·Á¾õ¤Ï
+ ¤Þ¤ÀÀµ¤·¤¯¤Ê¤¤¤±¤É)¡£
+ <item>PCI ¥Ó¥Ç¥ª¥«¡¼¥ÉÂбþ¤Î¥ê¥Ë¥¢¥Õ¥ì¡¼¥à¥Ð¥Ã¥Õ¥¡¤Î¸¡½Ð¤¬¿ÊÊ⤷¤Þ¤·
+ ¤¿¡£º£¤Þ¤Ç°ìÇÕ¸°¤¬³Ý¤«¤Ã¤Æ¤¤¤Æ»È¤¨¤Ê¤¤¤ÈÊó¹ð¤µ¤ì¤Æ¤¤¤ë¡¢¥ê¥Ë¥¢¥Õ
+ ¥ì¡¼¥à¥Ð¥Ã¥Õ¥¡¤ò»È¤Ã¤Æ¤¤¤ëËØ¤É¤Î Trio64V+ ¤Ç»È¤¨¤Þ¤¹¡£
+ <item>ICS9161A ¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤Î¤ß¤Ê¤é¤º Ti3026 RAMDAC ¤òÅëºÜ¤·¤¿
+ ELSA Elsa Winner2000PRO/X-2,4 Rev.G ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹(̤¤ÀÇÜ¥¯¥í¥Ã¥¯
+ µ»½Ñ¤Ï¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó)¡£
+ <item>&num;9 Motion 771 ¥Ó¥Ç¥ª¥«¡¼¥É¤È Hercules Terminator 64 Pro
+ ¥Ó¥Ç¥ª¥«¡¼¥ÉÂбþ¤Îɸ½à InvertVCLK ¤ÎÀßÄê¤òÊѹ¹¤·¤Þ¤·¤¿¡£¥Ð¡¼¥¸¥ç¥ó
+ 3.1.2 ¤Ç²èÌ̤βö¤ê¹þ¤ß¤òËɻߤ¹¤ë¤¿¤á¤Ë Invert_VCLK ¹Ô¤ò XF86Config
+ ¥Õ¥¡¥¤¥ë¤ËÄɲ䷤Ƥ·¤Æ¤¤¤ë¾ì¹ç¤Ë¡¢¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤ò¥Æ¥¹¥È¤¹¤ë»þ¤Ï
+ ¼è¤ê½ü¤¤¤Æ¤¯¤À¤µ¤¤¡£¿·¤·¤¤É¸½àÃͤDz¿¤«ÌäÂ꤬¤¢¤Ã¤¿¤é¡¢»ä¤¿¤Á¤ËÊó¹ð
+ ¤·¤Æ¤¯¤À¤µ¤¤¡£
+ <item>*¥Æ¥­¥¹¥ÈÀÚ¤ê¼è¤ê(¥¯¥ê¥Ã¥Ô¥ó¥°) ¤ÎÀ­Ç½¤ò¸þ¾å¤·¤Þ¤·¤¿¡£
+</itemize>
+
+<!--
+<sect1> Mach64 server
+-->
+<sect1> Mach64 ¥µ¡¼¥Ð
+<p>
+<!--
+<itemize>
+ <item>Most problems in the handling of block_write have been fixed.
+ Nevertheless, you still might need to add the "no_block_write" option
+ to your XF86Config if the BIOS doesn't correctly initialise the
+ chip.
+ <item>Screen blanking for some Mach64 CT cards running at 16bpp and 32bpp
+ has been fixed. Problems remain for some revisions of the CT chip.
+ <item>The Mach64 server supports the VT and GT chipset. The GT is also
+ known as "3D Rage". The newer 3D Rage II is not yet supported.
+ <item>A problem with ol[v]wm icons has been fixed.
+ <item>A problem with ghostview scrollbars has been fixed. This may also
+ fix some Netscape font problems that have been reported.
+ <item>The Mach64 CT (also known as the 264CT or 215CT22200) chip is now
+ supported. This chip has a integrated RAMDAC and clockchip, and
+ is used on some Graphics Xpression and WinBoost cards.
+ <item>The Mach64 GX-F (GX rev 3) is now supported.
+ <item>The IBM RGB514 RAMDAC is now supported (as used on the ATI
+ Graphics Turbo Pro 1600).
+ <item>The memory base should now be correctly detected for VLB cards.
+ If you've needed to add a `MemBase' line to the XF86Config for
+ previous versions, please try removing it, and let us know if there
+ are any problems.
+ <item>Cursor colour problems at 16bpp/32bpp mode with some RAMDACs have
+ been fixed.
+ <item>Errors in detecting some RAMDACs (like the CH8398) should now be
+ fixed.
+ <item>8 bit-per-RGB mode (when running at 8bpp) is now the default for
+ RAMDACs that support it.
+ <item>Hardware cursor mask problem has been fixed.
+ <item>Support for the AT&amp;T 20C408 RAMDAC/Clockchip has been added.
+ <item>Arbitrary clocks can be used on most cards with supported clock chips.
+ <item>Hardware cursor color problem on Mach64 CT, VT and GT chips at 16bpp
+ and 32bpp has been fixed.
+ <item>Doublescan mode is supported on VT and GT chipsets. The hardware
+ cursor is not correctly displayed in doublescan modes, but functions
+ correctly. No other Mach64 chipsets can support an accelerated
+ doublescan mode.
+ <item>Video noise on certain CT, VT and GT chips has been eliminated (on
+ nearly all cards) or reduced as much as possible (on certain CT
+ based cards).
+ <item>Clock chip programming accuracy has been greatly improved on CT, ET,
+ VT and GT based cards. This may result in modes that were set up
+ for a previous release not being displayed as before. With the
+ xvidtune program, you can adjust the screen to work with the now
+ correct clock programming.
+ <item>*The reliability of the Mach64 detection code has been improved.
+</itemize>
+-->
+<itemize>
+ <item>block_write ¤Î¼è¤ê°·¤¤¤ÎËØ¤É¤ÎÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ ¤½¤ì¤Ë¤â¤«¤«¤ï¤é¤º¡¢BIOS ¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Î½é´ü²½¤¬Àµ¤·¤¯¹Ô¤ï¤ì¤Ê¤¤
+ ¾ì¹ç¤Ï¡¢ÁêÊѤï¤é¤º XF86Config ¤Ë "no_block_write" ¥ª¥×¥·¥ç¥ó¤òÄɲÃ
+ ¤¹¤ëɬÍפ¬¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£
+ <item>16bpp ¤È 32bpp ¥â¡¼¥É¤Ç Mach64 CT ¥Ó¥Ç¥ª¥«¡¼¥É¤ò²ÔƯ¤¹¤ë¾ì¹ç¡¢
+ ²èÌ̤¬°Å¤¯¤Ê¤ëÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£CT ¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤Î¤¤¤¯¤Ä¤«¤Î
+ ²þÄûÈǤǤÏÌäÂ꤬»Ä¤Ã¤Æ¤¤¤Þ¤¹¡£
+ <item>Mach64 ¥µ¡¼¥Ð¤Ï VT ¤È GT ¥Á¥Ã¥×¥»¥Ã¥È¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£GT
+ ¥Á¥Ã¥×¥»¥Ã¥È¤Ï "3D Rage" ¤È¤·¤Æ¤âÃΤé¤ì¤Æ¤¤¤Þ¤¹¡£¤è¤ê¿·¤·¤¤
+ 3D Rage II ¤Ï̤¤À¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó¡£
+ <item>ol[v]wm ¤Î¥¢¥¤¥³¥ó¤ÎÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>ghostview ¤Î¥¹¥¯¥í¡¼¥ë¥Ð¡¼¤ÎÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£¤³¤Î½¤Àµ¤Ï
+ Êó¹ð¤¬¤¢¤Ã¤¿¤¤¤¯¤Ä¤«¤Î Netscape ¤Î¥Õ¥©¥ó¥È¤ÎÌäÂê¤â²ò·è¤·¤Þ¤¹¡£
+ <item>(264CT ¤Þ¤¿¤Ï 215CT22200 ¤È¤·¤ÆÃΤé¤ì¤Æ¤¤¤ë) Mach64 CT ¥Á¥Ã¥×
+ ¥»¥Ã¥È¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£¤³¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ï RAMDAC ¤È¥¯¥í¥Ã¥¯
+ ¥Á¥Ã¥×¤òÅý¹ç¤·¤¿¤â¤Î¤Ç¡¢¤¤¤¯¤Ä¤«¤Î Graphics Xpression ¤È WinBoost
+ ¥Ó¥Ç¥ª¥«¡¼¥É¤¬ÅëºÜ¤·¤Æ¤¤¤Þ¤¹¡£
+ <item>º£²ó¡¢Mach64 GX-F (GX rev 3) ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item>º£²ó¡¢(ATI Graphics Turbo Pro 1600 ¤¬ÅëºÜ¤·¤Æ¤¤¤ë)
+ IBM RGB514 RAMDAC ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item>º£²ó¡¢VLB ¥Ó¥Ç¥ª¥«¡¼¥É¤Î¥á¥â¥ê´ðÄ쥢¥É¥ì¥¹¤òÀµ¤·¤¯ÃµÃΤ¹¤ë
+ ¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¡£Á°¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç XF86Config ¤Ë `MemBase' ¹Ô¤ò
+ Äɲ乤ëɬÍפ¬¤¢¤Ã¤¿¾ì¹ç¡¢ºï½ü¤·¤Æ¤ß¤Æ¡¢ÌäÂ꤬¤¢¤ì¤Ð»ä¤¿¤Á¤Ë
+ ¶µ¤¨¤Æ¤¯¤À¤µ¤¤¡£
+ <item>¤¤¤¯¤Ä¤«¤Î RAMDAC ¤ò 16bpp/32bpp ¤Çưºî¤µ¤»¤¿¤È¤­¤Î¥«¡¼¥½¥ë¤Î
+ ¿§¤ÎÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>º£²ó¡¢CH8398 ¤Î¤è¤¦¤Ê¤¤¤¯¤Ä¤«¤Î RAMDAC ¤ÎõÃΤλþ¤Î¥¨¥é¡¼¤ò
+ ½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>RAMDAC ¤¬ 8bpp ¤Ç¼Â¹Ô¤·¤¿¤È¤­¤Î RGB Åö¤¿¤ê 8 ¥Ó¥Ã¥È¤Î¥â¡¼¥É¤ò
+ ¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¤È¤­¤Ï¤½¤Î¥â¡¼¥É¤òɸ½àÃͤˤ·¤Þ¤·¤¿¡£
+ <item>¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½¥ë¥Þ¥¹¥¯¤ÎÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>AT&amp;T 20C408 RAMDAC/¥Á¥Ã¥×¥»¥Ã¥È ¤òÄɲä·¤Þ¤·¤¿¡£
+ <item>Ǥ°Õ¤Î¥¯¥í¥Ã¥¯¼þÇÈ¿ô¤¬²Äǽ¤Ê¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤òÅëºÜ¤·¤Æ¤¤¤ë
+ ËØ¤É¤Î¥Ó¥Ç¥ª¥«¡¼¥É¤Î¥¯¥í¥Ã¥¯¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£
+ <item>16bpp ¤È 32bpp ¥â¡¼¥É¤Ç¤Î Mach64 CT, VT ¤È GT ¥Á¥Ã¥×¥»¥Ã¥È¤Î
+ ¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½¥ë¤Î¿§¤ÎÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>VT ¤È GT ¥Á¥Ã¥×¥»¥Ã¥È¤Ç¥À¥Ö¥ë¥¹¥­¥ã¥ó¥â¡¼¥É¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ ¥À¥Ö¥ë¥¹¥­¥ã¥ó¥â¡¼¥É¤Ç¤Ï¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½¥ë¤ÏÀµ¤·¤¯É½¼¨¤µ¤ì¤Þ¤»
+ ¤ó¤¬¡¢µ¡Ç½¤ÏÀµ¤·¤¯Æ°ºî¤·¤Þ¤¹¡£¤½¤Î¾¤Î Mach64 ¥Á¥Ã¥×¥»¥Ã¥È¤Ï
+ ¥¢¥¯¥»¥é¥ì¡¼¥¿¥À¥Ö¥ë¥¹¥­¥ã¥ó¥â¡¼¥É¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó¡£
+ <item>ËØ¤É¤Î¥Ó¥Ç¥ª¥Ü¡¼¥É¤ÎË¿ CT, VT ¤È GT ¥Á¥Ã¥×¥»¥Ã¥È¤Î¥Ó¥Ç¥ª¥Î¥¤¥º
+ ¤Ï½üµî¡¢¤Þ¤¿¤ÏË¿ CT ¥Á¥Ã¥×¥»¥Ã¥È¤òÅëºÜ¤·¤¿¥Ó¥Ç¥ª¥Ü¡¼¥É¤Ç¤Ï²Äǽ¤Ê
+ ¸Â¤ê·Ú¸º¤·¤Þ¤·¤¿¡£
+ <item>CT, ET, VT ¤È GT ¤òÅëºÜ¤·¤¿¥Ó¥Ç¥ª¥Ü¡¼¥É¤Ç¥¯¥í¥Ã¥¯¥Á¥Ã¥×¥×¥í¥°
+ ¥é¥àÊýË¡¤ÎÀºÅÙ¤¬¸þ¾å¤·¤Þ¤·¤¿¡£¤³¤ÎÊýË¡¤Ç¤Ï°ÊÁ°¤ÎÊýË¡¤Ïɽ¼¨½ÐÍè¤Ê¤¤
+ ¥â¡¼¥É¤òɽ¼¨¤¹¤ë¤è¤¦¤ËÀßÄê½ÐÍè¤Þ¤¹¡£xvidtune ¥×¥í¥°¥é¥à¤Ç¤Ï¡¢º£²ó
+ ¤ÎÀµ¤·¤¤¥¯¥í¥Ã¥¯¥×¥í¥°¥é¥àÊýË¡¤Ë¤è¤ê¡¢²ÔƯ¤¹¤ë¤è¤¦¤Ê²èÌ̤òÄ´À°½ÐÍè
+ ¤Þ¤¹¡£
+ <item>*Mach64 ¤Îõºº¥×¥í¥°¥é¥à¤Î¿®ÍêÀ­¤¬¸þ¾å¤·¤Þ¤·¤¿¡£
+</itemize>
+<!--
+<sect1> Mach32 server
+-->
+<sect1> Mach32 ¥µ¡¼¥Ð
+<p>
+<!--
+<itemize>
+ <item>Hardware cursor mask problem has been fixed.
+ <item>*16bpp support has been added for the AT&amp;T 20C490 and Bt481
+ RAMDACs.
+ <item>*Some VT switching problems have been fixed.
+</itemize>
+-->
+<itemize>
+ <item>¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½¥ë¥Þ¥¹¥¯¤ÎÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>*AT&amp;T 20C490 ¤È Bt481 RAMDAC ¤Ë 16bpp ¥â¡¼¥É¤ò¥µ¥Ý¡¼¥È¤·¤Þ
+ ¤·¤¿¡£
+ <item>*¤¤¤¯¤Ä¤«¤Î VT ÀÚ¤êÂØ¤¨¤ÎÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+</itemize>
+<!--
+<sect1> W32 server
+-->
+<sect1> W32 ¥µ¡¼¥Ð
+<p>
+<!--
+<itemize>
+ <item>Support has been added for the ET6000
+ <item>Support has been added for the ICD2061A clock chip (which is used
+ on the Diamond Stealth 32).
+ <item>The server's reporting of bits/RGB resolution has been fixed.
+ <item>Support for the STG1703 RAMDAC/clock has been added. Clocks up to
+ 135MHz should be OK. To use the programmable clock add the
+ following line to the Device section of the XF86Config:
+ <tscreen><verb>
+ ClockChip "stg1703"
+ </verb></tscreen>
+ <item>Options have been added to allow PCI burst mode and W32 interleaving
+ to be turned on or off. The XF86Config Device section entries
+ for these are:
+ <tscreen><verb>
+ Option "pci_burst_on"
+ Option "pci_burst_off"
+ Option "w32_interleave_on"
+ Option "w32_interleave_off"
+ </verb></tscreen>
+ <item>Support has been added for the ICS5341 programmable clock.
+ To enable this, add the following lines to the Device section of your
+ XF86Config file:
+ <tscreen><verb>
+ Ramdac "ics5341"
+ ClockChip "ics5341"
+ </verb></tscreen>
+ <item>Problems that could cause the W32 server to crash at startup or
+ get stuck in a loop at exit have been fixed.
+ <item>*Some drawing bugs have been fixed.
+</itemize>
+-->
+<itemize>
+ <item>ET6000 ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item>(Diamond Stealth 32 ¤Ç»ÈÍѤµ¤ì¤Æ¤¤¤ë)ICD2061A ¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤ò
+ ¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item>¥µ¡¼¥Ð¤¬Êó¹ð¤¹¤ë RGB Åö¤¿¤ê¤Î bit ¿ô¤Î²òÁüÅÙ¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>STG1703 RAMDAC/¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£¥¯¥í¥Ã¥¯¤ò
+ 135MHz ¤Þ¤Ç¾å¤²¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡£¥×¥í¥°¥é¥Þ¥Ö¥ë¥¯¥í¥Ã¥¯¤ò»È¤¦¤Ë¤Ï
+ XF86Config ¤Î Device Àá¤Ë¼¡¤Î¹Ô¤òÄɲ䷤Ƥ¯¤À¤µ¤¤¡£
+ <tscreen><verb>
+ ClockChip "stg1703"
+ </verb></tscreen>
+ <item>PCI ¥Ð¡¼¥¹¥È¥â¡¼¥É¤È W32 ¥¤¥ó¥¿¡¼¥ê¡¼¥Ö¤òÆþ¤ì¤¿¤êÀڤ俤ꤹ¤ë
+ ¥ª¥×¥·¥ç¥ó¤òÄɲä·¤Þ¤·¤¿¡£XF86Config ¤Î Device Àá¤Ë¼¡¤Î¹àÌܤò»ØÄê
+ ½ÐÍè¤Þ¤¹¡£
+ <tscreen><verb>
+ Option "pci_burst_on"
+ Option "pci_burst_off"
+ Option "w32_interleave_on"
+ Option "w32_interleave_off"
+ </verb></tscreen>
+ <item>ICS5341 ¥×¥í¥°¥é¥Þ¥Ö¥ë¥¯¥í¥Ã¥¯¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ ¤³¤ì¤òÍ­¸ú¤Ë¤¹¤ë¤Ê¤é¤Ð XF86Config ¥Õ¥¡¥¤¥ë¤Î Device Àá¤Ë¼¡¤Î¹àÌܤò
+ Äɲ䷤Ƥ¯¤À¤µ¤¤¡£:
+ <tscreen><verb>
+ Ramdac "ics5341"
+ ClockChip "ics5341"
+ </verb></tscreen>
+ <item>W32 ¥µ¡¼¥Ð¤Î³«»Ï»þµÚ¤Ó½ªÎ»»þ¤Ë¸Ç¤Þ¤Ã¤Æ¤·¤Þ¤¦ÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>*¤¤¤¯¤Ä¤«¤ÎÉÁ²è¤Î¥Ð¥°¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+</itemize>
+<!--
+<sect1> AGX server
+-->
+<sect1> AGX ¥µ¡¼¥Ð
+<p>
+<!--
+<itemize>
+ <item>Fix for clock probing with AGX-010 chips.
+</itemize>
+-->
+<itemize>
+ <item>AGX-010 ¥Á¥Ã¥×¥»¥Ã¥È¤Î¥¯¥í¥Ã¥¯¤Îõºº¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+</itemize>
+<!--
+<sect1> I128 server
+-->
+<sect1> I128 ¥µ¡¼¥Ð
+<p>
+<!--
+<itemize>
+ <item>A new server for the Number Nine Imagine 128 card is included.
+ This server is currently not accelerated.
+ <item>Support has been added for the Series 2 cards.
+ <item>Support has been added for 8MB cards.
+</itemize>
+-->
+<itemize>
+ <item>Number Nine Imagine 128 ¥Ó¥Ç¥ª¥Ü¡¼¥ÉÂбþ¤Î¿·¤·¤¤¥µ¡¼¥Ð¤òÄɲä·
+ ¤Þ¤·¤¿¡£¤³¤Î¥µ¡¼¥Ð¤Ï¸½ºß¹â®²½¤·¤Æ¤¤¤Þ¤»¤ó¡£
+ <item>Series 2 ¤Î¥Ó¥Ç¥ª¥Ü¡¼¥É¤òÄɲä·¤Þ¤·¤¿¡£
+ <item>8MB ¤Î¥Ó¥Ç¥ª¥Ü¡¼¥É¤òÄɲä·¤Þ¤·¤¿¡£
+</itemize>
+<!--
+<sect1> TGA server
+-->
+<sect1> TGA ¥µ¡¼¥Ð
+<p>
+<!--
+<itemize>
+ <item>*A new server for the DEC 21030 (TGA) is included. This is only
+ available for Alpha machines. This server is currently not
+ accelerated.
+</itemize>
+-->
+<itemize>
+ <item>*DEC 21030 (TGA) Âбþ¤Î¿·¤·¤¤¥µ¡¼¥Ð¤òÄɲä·¤Þ¤·¤¿¡£¤³¤Î¥µ¡¼¥Ð¤Ï
+ Alpha ¥Ñ¥½¥³¥ó¤Ç¤Î¤ß»ÈÍѲÄǽ¤Ç¤¹¡£¤³¤Î¥µ¡¼¥Ð¤Ï¸½ºß¹â®²½¤·¤Æ¤¤¤Þ¤»
+ ¤ó¡£
+</itemize>
+<!--
+<sect1> SVGA/VGA16/Mono servers
+-->
+<sect1> SVGA/VGA16/Mono ¥µ¡¼¥Ð
+<p>
+<!--
+<itemize>
+ <item>A PCI probe has been added to these servers. If it causes problems,
+ it can be disabled by adding the line:
+ <verb>
+ Option "no_pci_probe"
+ </verb>
+ to the Device section in your XF86Config file.
+</itemize>
+-->
+<itemize>
+ <item>¤³¤ì¤é¤Î¥µ¡¼¥Ð¤Ë PCI ¤òõÃΤ¹¤ë¤³¤È¤òÄɲä·¤Þ¤·¤¿¡£ÌäÂ꤬À¸¤¸¤¿
+ ¾ì¹ç¤Ï¼¡¤Î¹Ô¤ò XF86Config ¥Õ¥¡¥¤¥ë¤Î Device Àá¤ËÄɲ䷤Ƥ¯¤À¤µ¤¤¡£:
+ <verb>
+ Option "no_pci_probe"
+ </verb>
+</itemize>
+<!--
+<sect1> VGA16 server
+-->
+<sect1> VGA16 ¥µ¡¼¥Ð
+<p>
+<!--
+<itemize>
+ <item>A problem preventing the StaticGray visual from working has been
+ fixed.
+</itemize>
+-->
+<itemize>
+ <item>StaticGray ɽ¼¨¤¬½ÐÍè¤Ê¤«¤Ã¤¿ÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+</itemize>
+<!--
+<sect1> ET3000 driver (VGA16 server)
+-->
+<sect1> ET3000 ¥É¥é¥¤¥Ð (VGA16 ¥µ¡¼¥Ð)
+<p>
+<!--
+<itemize>
+ <item>VGA16 support has been added to the ET3000 driver.
+</itemize>
+-->
+<itemize>
+ <item>ET3000 ¥É¥é¥¤¥Ð ¤ò VGA16 ¥µ¡¼¥Ð¤ËÄɲä·¤Þ¤·¤¿¡£
+</itemize>
+<!--
+<sect1> Trident driver (SVGA server)
+-->
+<sect1> Trident ¥É¥é¥¤¥Ð (SVGA ¥µ¡¼¥Ð)
+<p>
+<!--
+<itemize>
+ <item>TGUI9440 is now fully supported by the SVGA server.
+ <item>Major updates for most of the trident family of chips.
+ <item>TGUI9660/9680 chipsets are now fully supported
+ <item>Check <htmlurl name="README.trident" url="trident.html"> distributed
+ with this release for full details.
+</itemize>
+-->
+<itemize>
+ <item>º£²ó¡¢SVGA ¥µ¡¼¥Ð ¤Ç TGUI9440 ¤ò´°Á´¤Ë¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item>trident ·ÏÅý¤Î¥Á¥Ã¥×¥»¥Ã¥È¤ÎËØ¤É¤ËÂçÉý¤ÊÊѹ¹¤ò¤·¤Þ¤·¤¿¡£
+ <item>º£²ó¡¢TGUI9660/9680 ¥Á¥Ã¥×¥»¥Ã¥È¤ò´°Á´¤Ë¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item>¤³¤ÎÈǤξܺ٤ˤĤ¤¤Æ¤Ï
+ <htmlurl name="README.trident" url="trident.html">
+ ¤ò¤´Í÷¤¯¤À¤µ¤¤¡£
+</itemize>
+<!--
+<sect1> Ark driver (SVGA server)
+-->
+<sect1> Ark ¥É¥é¥¤¥Ð (SVGA ¥µ¡¼¥Ð)
+<p>
+<!--
+<itemize>
+ <item>The Ark driver will now detect the ARK2000MT, but it is treated
+ as an ARK2000PV.
+ <item>A problem which caused the server to crash when no Ramdac was given
+ in the XF86Config file has been fixed.
+ <item>ICS5342 clock support (required for the Diamond Stealth64
+ Graphics 2001 series) has been added.
+ To enable this, add the following lines to the Device section of your
+ XF86Config file:
+ <tscreen><verb>
+ Ramdac "ics5342"
+ ClockChip "ics5342"
+ </verb></tscreen>
+ Do not include any <tt>Clocks</tt> lines in your XF86Config file.
+ <item>Panning has been fixed for ARK2000PV cards with 2MB of video memory.
+ <item>*Some basic BitBlt acceleration has been added.
+ <item>*24bpp packed pixel support has been added for some cards/RAMDACs.
+ <item>*Memory bandwidth problems have been fixed.
+ <item>*Hardware cursor support has been added.
+</itemize>
+-->
+<itemize>
+ <item>Ark ¥É¥é¥¤¥Ð¤¬º£²ó ARK2000MT ¤òõÃΤ¹¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤·¤¿¤¬¡¢
+ ARK2000PV ¤È¤ß¤Ê¤·¤Æ¤¤¤Þ¤¹¡£
+ <item>XF86Config ¥Õ¥¡¥¤¥ë¤Ë Ramdac ¤Î»ØÄ꤬¤Ê¤¤¤È¤­¤Ë¥µ¡¼¥Ð¤¬Æ°ºî
+ ¤·¤Ê¤¤ÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>Diamond Stealth64 Graphics 2001 ¥·¥ê¡¼¥º¤¬Í׵ᤷ¤Æ¤¹¤ë
+ ICS5342 ¥¯¥í¥Ã¥¯¥Á¥Ã¥×¥»¥Ã¥È¤òÄɲä·¤Þ¤·¤¿¡£¤³¤ì¤òÍ­¸ú¤Ë¤¹¤ë¤Ë¤Ï
+ XF86Config ¥Õ¥¡¥¤¥ë¤Î Device Àá¤Ë¼¡¤Î¹Ô¤òÄɲ䷤Ƥ¯¤À¤µ¤¤¡£:
+ <tscreen><verb>
+ Ramdac "ics5342"
+ ClockChip "ics5342"
+ </verb></tscreen>
+ XF86Config ¥Õ¥¡¥¤¥ë¤Ë <tt>Clocks</tt> ¹Ô¤òÆþ¤ì¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£
+ <item>2MB ¤Î¥Ó¥Ç¥ª¥á¥â¥ê¤òÅëºÜ¤·¤Æ¤¤¤ë ARK2000PV ¥Ó¥Ç¥ª¥«¡¼¥É¤Ç
+ ²èÌ̤¬¾å²¼º¸±¦¤Ëư¤¯ÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>*´ðËÜŪ¤Ê BitBlt ¥¢¥¯¥»¥é¥ì¡¼¥¿¤òÄɲä·¤Þ¤·¤¿¡£
+ <item>*¤¤¤¯¤Ä¤«¤Î¥Ó¥Ç¥ª¥«¡¼¥É/RAMDAC ¤Ë 24bpp ¤Î¥Ñ¥Ã¥¯¥È¥Ô¥¯¥»¥ë¤ò
+ Äɲä·¤Þ¤·¤¿¡£
+ <item>*¥á¥â¥ê¤ÎÂÓ°èÉý¤ÎÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>*¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½¥ë¤òÄɲä·¤Þ¤·¤¿¡£
+</itemize>
+<!--
+<sect1> ET6000 driver (SVGA server)
+-->
+<sect1> ET6000 ¥É¥é¥¤¥Ð (SVGA ¥µ¡¼¥Ð)
+<p>
+<!--
+<itemize>
+ <item>*This driver includes support for linear memory and 16bpp, 24bpp and
+ 32bpp operation. Note, this support isn't currently present in
+ the W32 accelerated server.
+</itemize>
+-->
+<itemize>
+ <item>*¤³¤Î¥É¥é¥¤¥Ð¤Ï¥ê¥Ë¥¢¥á¥â¥ê¤È16bpp, 24bpp ¤È 32bpp ¤ò¥µ¥Ý¡¼¥È¤·¤Þ
+ ¤·¤¿¡£¸½ºß W32 ¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð¤Ç¤Ï¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤¤³¤È¤ËÃí°Õ¤·
+ ¤Æ¤¯¤À¤µ¤¤¡£¡£
+</itemize>
+<!--
+<sect1> Alliance ProMotion driver (SVGA server)
+-->
+<sect1> Alliance ProMotion ¥É¥é¥¤¥Ð (SVGA ¥µ¡¼¥Ð)
+<p>
+<!--
+<itemize>
+ <item>A driver for the Alliance ProMotion 6442 has been added (from
+ Alliance Semiconductor). This has not been thoroughly tested.
+</itemize>
+-->
+<itemize>
+ <item>(Alliance Semiconductor ¤¬) Alliance ProMotion 6442 ¥É¥é¥¤¥Ð¤ò
+ Äɲä·¤Þ¤·¤¿¡£Ä̤·¤Æ¥Æ¥¹¥È¤·¤¿Ìõ¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+</itemize>
+<!--
+<sect1> NVidia NV1 / SGS Thomson STG2000 driver (SVGA server)
+-->
+<sect1> NVidia NV1 / SGS Thomson STG2000 ¥É¥é¥¤¥Ð (SVGA ¥µ¡¼¥Ð)
+<p>
+<!--
+<itemize>
+ <item>*A driver for the NV1/STG2000 has been added. This chipset is used
+ on the Diamond Edge 3D card. This is a very new
+ driver, and is considered "beta". It includes support for
+ 8bpp and 16bpp.
+</itemize>
+-->
+<itemize>
+ <item>*NV1/STG2000 ¥É¥é¥¤¥Ð¤òÄɲä·¤Þ¤·¤¿¡£¤³¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ï
+ Diamond Edge 3D ¥Ó¥Ç¥ª¥«¡¼¥É¤ËÅëºÜ¤·¤Æ¤¤¤Þ¤¹¡£¤³¤Î¥É¥é¥¤¥Ð¤Ï
+ ¤È¤Æ¤â¿·¤·¤¤¤¿¤á "¥Ù¡¼¥¿ÈÇ" ¤È»×¤Ã¤Æ¤¯¤À¤µ¤¤¡£
+ 8bpp ¤È 16bpp ¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£
+</itemize>
+<!--
+<sect1> Matrox Millennium driver (SVGA server)
+-->
+<sect1> Matrox Millennium ¥É¥é¥¤¥Ð (SVGA ¥µ¡¼¥Ð)
+<p>
+<!--
+<itemize>
+ <item>*A driver for the Matrox Millennium (mga2064w) has been added. This
+ is a very new driver, and is considered "beta". It includes support
+ for 8bpp, 16bpp, 24bpp and 32bpp. The acceleration capabilities of
+ this chipset are only used to a very limited extent at this stage.
+</itemize>
+-->
+<itemize>
+ <item>*Matrox Millennium (mga2064w) ¥É¥é¥¤¥Ð¤òÄɲä·¤Þ¤·¤¿¡£¤³¤Î¥É¥é¥¤¥Ð¤Ï
+ ¤È¤Æ¤â¿·¤·¤¤¤¿¤á "¥Ù¡¼¥¿ÈÇ" ¤È»×¤Ã¤Æ¤¯¤À¤µ¤¤¡£8bpp, 16bpp, 24bpp ¤È
+ 32bpp ¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£¤³¤ÎÃʳ¬¤Ç¤Ï¤³¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Î¹â®²½µ¡Ç½¤Î
+ ¤È¤Æ¤â¸ÂÄꤷ¤¿µ¡Ç½¤À¤±¤ò»È¤Ã¤Æ¤¤¤Þ¤¹¡£
+</itemize>
+<!--
+<sect1> Cirrus driver (SVGA server)
+-->
+<sect1> Cirrus ¥É¥é¥¤¥Ð (SVGA ¥µ¡¼¥Ð)
+<p>
+<!--
+<itemize>
+ <item>Support has been added for the CL-GD5446, CL-GD5462 and CL-GD5464.
+ <item>Support has been added for the CL-GD7543.
+ <item>Support for the CL-GD754x series of laptop chips is included, but
+ it appears to be broken in this release.
+ <item>The programmable clock code has been improved to avoid unstable
+ settings.
+ <item>*Some FIFO setting problems have been fixed.
+ <item>*Packed 24bpp support has been added for the 54xx.
+ <item>*Some problems with 16bpp for a 1MB 5434 have been fixed.
+</itemize>
+-->
+<itemize>
+ <item>CL-GD5446, CL-GD5462 ¤È CL-GD5464 ¤òÄɲä·¤Þ¤·¤¿¡£
+ <item>CL-GD7543 ¤òÄɲä·¤Þ¤·¤¿¡£
+ <item>¥é¥Ã¥×¥È¥Ã¥×ÍѤΥÁ¥Ã¥×¥»¥Ã¥È¤Î CL-GD754x ·ÏÅý¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¤¬
+ ¤³¤ÎÈÇ¤Ç¤ÏÆ°¤«¤Ê¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£
+ <item>ÉÔ°ÂÄê¤ÊÀßÄê¤òÈò¤±¤ë¤¿¤á¤Ë¥×¥í¥°¥é¥Þ¥Ö¥ë¥¯¥í¥Ã¥¯¤Î¥×¥í¥°¥é¥à¤ò
+ À­Ç½¸þ¾å¤·¤Þ¤·¤¿¡£
+ <item>*¤¤¤¯¤Ä¤«¤Î FIFO ¤ÎÀßÄê¤ÎÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>*54xx Âбþ¤Ë¥Ñ¥Ã¥¯¥È¥Ô¥¯¥»¥ë 24bpp ¤òÄɲä·¤Þ¤·¤¿¡£
+ <item>*1MB 5434 Âбþ¤Î 16bpp ¤ÇÀ¸¤¸¤Æ¤¤¤¿¤¤¤¯¤Ä¤«¤ÎÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+</itemize>
+<!--
+<sect1> SiS driver (SVGA server)
+-->
+<sect1> SiS ¥É¥é¥¤¥Ð (SVGA ¥µ¡¼¥Ð)
+<p>
+<!--
+<itemize>
+ <item>Support is included for the SiS 86C201 PCI graphics card.
+ <item>256 colour support has been added.
+ <item>SiS 86c202 and 86c205 somewhat work when "sis86c201" is specified
+ as chipset.
+</itemize>
+-->
+<itemize>
+ <item>SiS 86C201 PCI ¥°¥é¥Õ¥£¥Ã¥¯¥Ó¥Ç¥ª¥«¡¼¥É¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item>256 ¿§¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item>¥Á¥Ã¥×¥»¥Ã¥È¤Ë "sis86c201" ¤È»ØÄꤷ¤¿¾ì¹ç¤Ë SiS 86c202 ¤È 86c205
+ ¤Ï¤Ê¤ó¤È¤«Æ°ºî¤·¤Þ¤¹¡£
+</itemize>
+<!--
+<sect1> Chips and Technologies driver (SVGA server)
+-->
+<sect1> Chips ¤È Technologies ¥É¥é¥¤¥Ð (SVGA ¥µ¡¼¥Ð)
+<p>
+<!--
+<itemize>
+ <item>This driver has been significantly reworked.
+ <item>Support has been added for the 65546, 65548, 65550 and 65554.
+ <item>Linear addressing support for the 65530 and above.
+ <item>16bpp and 24bpp (packed) support for the 65545 an above.
+ <item>BitBLT and some other acceleration for the 65545, 65546, 65548
+ and 65550.
+</itemize>
+-->
+<itemize>
+ <item>¤³¤Î¥É¥é¥¤¥Ð¤Ï¤«¤Ê¤êÃø¤·¤¯ºî¤êľ¤·¤Þ¤·¤¿¡£
+ <item>65546, 65548, 65550 ¤È 65554 ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item>65530 ¤È¾åµ­¥Á¥Ã¥×¥»¥Ã¥È¤Î¥ê¥Ë¥¢¥¢¥É¥ì¥Ã¥·¥ó¥°¤ò¥µ¥Ý¡¼¥È¤·¤Þ
+ ¤·¤¿¡£
+ <item>65545 ¤È¾åµ­¥Á¥Ã¥×¥»¥Ã¥È¤Î 16bpp ¤È 24bpp (¥Ñ¥Ã¥¯¥È¥Ô¥¯¥»¥ë)
+ ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item>65545, 65546, 65548 ¤È 65550 ¤Î BitBLT ¤È¤½¤Î¾¤Î¹â®²½¤ò
+ ¹Ô¤¤¤Þ¤·¤¿¡£
+</itemize>
+<!--
+<sect1> ALI driver (SVGA server)
+-->
+<sect1> ALI ¥É¥é¥¤¥Ð (SVGA ¥µ¡¼¥Ð)
+<p>
+<!--
+<itemize>
+ <item>Interlaced modes now work with this driver.
+</itemize>
+-->
+<itemize>
+ <item>º£²ó¡¢¤³¤Î¥É¥é¥¤¥Ð¤Ç¥¤¥ó¥¿¥ì¡¼¥¹¥â¡¼¥É¤¬Æ°ºî¤·¤Þ¤¹¡£
+</itemize>
+<!--
+<sect1> ATI driver (SVGA server)
+-->
+<sect1> ATI ¥É¥é¥¤¥Ð (SVGA ¥µ¡¼¥Ð)
+<p>
+<!--
+<itemize>
+ <item>Mach64 support has been improved.
+ <item>The driver name has been changed back from "vgawonder" to "ati".
+ <item>Support is included for most recent Mach64 cards.
+ <item>The "undoc_clocks" option has been removed. If you had been using
+ it, remove it from your XF86Config file.
+ <item>A colourmap problem with VGA Wonder V3 boards has been fixed.
+</itemize>
+-->
+<itemize>
+ <item>Mach64 ¤Î¥µ¥Ý¡¼¥È¤ò²þÎɤ·¤Þ¤·¤¿¡£
+ <item>¥É¥é¥¤¥Ð̾¾Î¤ò "vgawonder" ¤«¤é "ati" ¤ËÌᤷ¤Þ¤·¤¿¡£
+ <item>ËØ¤É¤Î ºÇ¶á¤Î Mach64 ¥Ó¥Ç¥ª¥«¡¼¥É¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£
+ <item>"undoc_clocks" ¥ª¥×¥·¥ç¥ó¤òºï½ü¤·¤Þ¤·¤¿¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ
+ ¤¤¤ë¾ì¹ç¤Ï XF86Config ¥Õ¥¡¥¤¥ë¤«¤éºï½ü¤·¤Æ¤¯¤À¤µ¤¤¡£
+ <item>VGA Wonder V3 ¥Ó¥Ç¥ª¥Ü¡¼¥É¤Î¥«¥é¡¼¥Þ¥Ã¥×¤ÎÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+</itemize>
+<!--
+<sect1> WD90C24 driver (SVGA server)
+-->
+<sect1> WD90C24 ¥É¥é¥¤¥Ð (SVGA ¥µ¡¼¥Ð)
+<p>
+<!--
+<itemize>
+ <item>A problem with snow at high clocks has been fixed.
+</itemize>
+-->
+<itemize>
+ <item>¹â¤¤¥¯¥í¥Ã¥¯¤Çµ¯¤³¤ëÀã¤Î¹ß¤ëÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+</itemize>
+<!--
+<sect1> Compaq AVGA driver (SVGA server)
+-->
+<sect1> Compaq AVGA ¥É¥é¥¤¥Ð (SVGA ¥µ¡¼¥Ð)
+<p>
+<!--
+<itemize>
+ <item>The Compaq AVGA driver has been disabled in this release because it
+ doesn't work, and nobody seems interested in fixing it.
+</itemize>
+-->
+<itemize>
+ <item>¤³¤ÎÈÇ¤Ç¤Ï Compaq AVGA ¥É¥é¥¤¥Ð¤Ï»ÈÍѽÐÍè¤Þ¤»¤ó¡£¤È¤¤¤¦¤Î¤Ïưºî
+ ¤·¤Ê¤¤¤Î¤È¡¢Ã¯¤â¤³¤ÎÌäÂê¤ò½¤Àµ¤·¤¿¤¬¤é¤Ê¤¤¤«¤é¤Ç¤¹¡£
+</itemize>
+<!--
+<sect1> Hercules mono driver
+-->
+<sect1> Hercules mono ¥É¥é¥¤¥Ð
+<p>
+<!--
+<itemize>
+ <item>The Hercules mono driver has been disabled in this release because
+ it has problems, and isn't likely to be fixed soon.
+</itemize>
+-->
+<itemize>
+ <item>Hercules mono ¥É¥é¥¤¥Ð ¤Ï»ÈÍѽÐÍè¤Þ¤»¤ó¡£¤È¤¤¤¦¤Î¤ÏÌäÂ꤬
+ ¤¢¤Ã¤Æ¡¢¤¹¤°¤Ë½¤Àµ½ÐÍè¤ë¸«¹þ¤ß¤¬¤Ê¤¤¤«¤é¤Ç¤¹¡£
+</itemize>
+<!--
+<sect1> Client/Library changes
+-->
+<sect1> ¥¯¥é¥¤¥¢¥ó¥È/¥é¥¤¥Ö¥é¥ê¤ÎÊѹ¹ÅÀ
+<p>
+<!--
+<itemize>
+ <item>Support for most vt220/vt320 escape sequenced has been added to xterm.
+ <item>Support for ddterm's escape sequences has been added to xterm.
+ <item>The termcap and terminfo entries for xterm have been updated in line
+ with the new features present. These entries are not completely
+ compatible with earlier versions of xterm.
+ <item>xdm's session handling on BSD OSs has been fixed.
+ <item>Some buffer overrun problems which can lead to security problems
+ have been fixed in libXt and libX11. At least one of these
+ problems has been used to exploit the setuid xterm.
+ <item>POSIX termios support has been added for xterm on most BSD systems.
+ This removes the need for the BSD kernel to built with the
+ COMPAT_43 option.
+ <item>As part of the change to X11R6.1, the shared library revisions
+ for libX11, libXaw, libXext, and libXtst have been incremented
+ to 6.1.
+ <item>The client-side library code for the XFree86 extensions and the
+ ScreenSaver extension has been moved into separate libraries.
+ The old libXExExt has been removed.
+ <item>Colour support is now included by default in xterm. I18N support
+ in xterm has been improved (as part of X11R6.1). If you've previously
+ been using one of the many "color_xterm" variants, try this and let
+ us know if you have any problems.
+ <item>xdpyinfo has been updated to provide more detailed information
+ about the XInput extension and the XFree86 extensions.
+ <item>The setting/examining of extended screen saver parameters has
+ been added to xset (was in xvidtune). xset can now also be used
+ to set the keyboard repeat parameters.
+ <item>The following new clients have been added:
+ <itemize>
+ <item>dga ** a test program for the XFree86-DGA extension.
+ <item>xsetmode, xsetpointer ** programs for use with the XInput
+ extension.
+ </itemize>
+ <item>The xdm security fix from the X Consortium's R6 fix-13 is included.
+ <item>xconsole has been updated for Unixware 2.x.
+ <item>XNLS support has been added for KOI8-R.
+ <item>xrdb dynamically allocates string space to avoid overruns.
+ <item>A memory overrun problem in xterm has been fixed.
+ <item>An "AllowNullPasswd" resource has been added to xdm.
+ <item>libXt bug fix from the X Consortium's R6 fix-13.
+</itemize>
+-->
+<itemize>
+ <item>xterm ¤Ë vt220/vt320 ¤ÎËØ¤É¤Î¥¨¥¹¥±¡¼¥×¥·¡¼¥±¥ó¥¹¤òÄɲä·¤Þ¤·¤¿¡£
+ <item>xterm ¤Ë ddterm ¤Î¥¨¥¹¥±¡¼¥×¥·¡¼¥±¥ó¥¹¤òÄɲä·¤Þ¤·¤¿¡£
+ <item>¿·µ¡Ç½¤Î¹Ô¤Î°Ù¤Ë xterm ¤Î termcap ¤È terminfo ¤Î¹àÌܤò¹¹¿·¤·¤Þ¤·¤¿¡£
+ ¤³¤ì¤é¤Î¹àÌܤϰÊÁ°¤Î xterm ¤È´°Á´¤Ê¸ß´¹À­¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+ <item>BSD OS ¤Ç¤Î xdm ¥»¥Ã¥·¥ç¥ó¤Î¼è¤ê°·¤¤¤Ë¤Ä¤¤¤Æ½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>libXt ¤È libX11 ¤ÇÊݰ¾å¤ÎÌäÂê¤ò°ú¤­µ¯¤³¤¹¥Ð¥Ã¥Õ¥¡¤Î¤¢¤Õ¤ì¤ÎÌäÂê¤ò
+ ½¤Àµ¤·¤Þ¤·¤¿¡£¤³¤ì¤é¤ÎÌäÂê¤ÎÆâ¤Î£±¤Ä¤Ï setuid xterm ¤òÍøÍѤ¹¤ë¤³¤È¤Ç¤¹¡£
+ <item>ËØ¤É¤Î BSD ¥·¥¹¥Æ¥à¤Ç xterm ¤Ë POSIX termios ¤òÄɲä·¤Þ¤·¤¿¡£
+ ¤³¤ì¤Ë¤è¤ê COMPAT_4 ¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤Æ BSD ¥«¡¼¥Í¥ë¤òÀ¸À®¤¹¤ëɬÍפ¬
+ ̵¤¯¤Ê¤ê¤Þ¤¹¡£
+ <item>X11R6.1 ¤ÎÊѹ¹ÅÀ¤Î°ìÉô¤Ç¤¢¤ë libX11, libXaw, libXext ¤È libXtst
+ ¤Î¶¦Í­¥é¥¤¥Ö¥é¥ê¤ÎÈǤò 6.1 ¤ËÁý¤ä¤·¤Þ¤·¤¿¡£
+ <item>XFree86 µ¡Ç½³ÈÄ¥¤È¥¹¥¯¥ê¡¼¥ó¥»¡¼¥Ð¡¼µ¡Ç½³ÈÄ¥¤Î¥¯¥é¥¤¥¢¥ó¥È¦¥é¥¤
+ ¥Ö¥é¥ê¤Ï³°Éô¥é¥¤¥Ö¥é¥ê¤Ë°Üư¤·¤Þ¤·¤¿¡£
+ ¸Å¤¤ libXExExt ¤Ïºï½ü¤·¤Þ¤·¤¿¡£
+ <item>º£²ó¡¢xterm ¤Ëɸ½à¤Ç¥«¥é¡¼É½¼¨¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¡£xterm ¤Ë
+ (X11R6.1 ¤ÎÉôʬ¤È¤·¤Æ) I18N µ¡Ç½¤¬¸þ¾å¤·¤Þ¤·¤¿¡£°ÊÁ°¤Î¿§¡¹¤Ê
+ "color_xterm"¤ÎÇÉÀ¸¤Î£±¤Ä¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¤³¤Î xterm ¤ò»î¤·¤Æ
+ ÌäÂ꤬¤¢¤Ã¤¿»þ¤Ë»ä¤¿¤Á¤Ë¤ªÃΤ餻¤¯¤À¤µ¤¤¡£
+ <item>xdpyinfo ¤ò Xinput µ¡Ç½³ÈÄ¥¤È XFree86 µ¡Ç½³ÈÄ¥¤Ë´Ø¤¹¤ë¤è¤ê
+ ¾ÜºÙ¤Ê¾ðÊó¤òÄ󶡤¹¤ë¤è¤¦¤Ë¹¹¿·¤·¤Þ¤·¤¿¡£
+ <item>³ÈÄ¥¤·¤¿¥¹¥¯¥ê¡¼¥ó¥»¡¼¥Ð¡¼¤Î¥Ñ¥é¥á¡¼¥¿¤ÎÀßÄê/¥Æ¥¹¥È¤ò xset ¤Ë
+ Äɲä·¤Þ¤·¤¿(xvidtune ¤Ç»È¤¤¤Þ¤·¤¿)¡£º£²ó¡¢xset ¤Ï¥­¡¼¥Ü¡¼¥É¤Î
+ ·«¤êÊÖ¤·ÆþÎϤΥѥé¥á¡¼¥¿¤ÎÀßÄê¤Ë¤â»ÈÍѽÐÍè¤Þ¤¹¡£
+ <item>¼¡¤Î¿·¤·¤¤¥¯¥é¥¤¥¢¥ó¥È¤òÄɲä·¤Þ¤·¤¿¡¢
+ <itemize>
+ <item>dga -- XFree86-DGA µ¡Ç½³ÈÄ¥¤Î¥Æ¥¹¥ÈÍÑ¥×¥í¥°¥é¥à¡£
+ <item>xsetmode, xsetpointer -- XInput µ¡Ç½³ÈÄ¥¤È¶¦¤Ë»ÈÍѤ¹¤ë
+ ¥×¥í¥°¥é¥à¡£
+ </itemize>
+ <item>X ¥³¥ó¥½¡¼¥·¥¢¥à¤Î R6 fix-13 ¤«¤é¤Î xdm ¤ÎÊݰ¾å¤Î½¤Àµ¤ò
+ ¼è¤êÆþ¤ì¤Þ¤·¤¿¡£
+ <item>Unixware 2.x Âбþ¤Ë xconsole ¤ò¹¹¿·¤·¤Þ¤·¤¿¡£
+ <item>XNLS ¤Ë KOI8-R ¤òÄɲä·¤Þ¤·¤¿¡£
+ <item>xrdb ¤Ïʸ»úÎóÎΰè¤òÎΰ褢¤Õ¤ì¤òÈò¤±¤ë¤è¤¦¤ËưŪ³ä¤êÅö¤Æ¤·¤Þ¤¹¡£
+ <item>xterm ¤Î¥á¥â¥ê¤¢¤Õ¤ì¤ÎÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>"AllowNullPasswd" ¥ê¥½¡¼¥¹¤ò xdm ¤ËÄɲä·¤Þ¤·¤¿¡£
+ <item>X ¥³¥ó¥½¡¼¥·¥¢¥à¤Î R6 fix-13 ¤«¤é¤Î libXt ¤Î¥Ð¥°¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+</itemize>
+<p>
+<!--
+<sect1> xf86config utility
+-->
+<sect1> xf86config ¥æ¡¼¥Æ¥£¥ê¥Æ¥£
+<p>
+<!--
+<itemize>
+ <item>Incorrect handling of IBM RGB Ramdacs has been fixed.
+</itemize>
+-->
+<itemize>
+ <item>IBM Ramdac ¤ÎÀµ¤·¤¯¤Ê¤¤¼è¤ê°·¤¤¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+</itemize>
+<!--
+<sect1> SuperProbe
+-->
+<sect1> SuperProbe
+<p>
+<!--
+<itemize>
+ <item>Added detection for C&amp;T 65548, Cirrus CL-GD7543/1, AT&amp;T
+ 20C409, AT&amp;T20C499, and fixed an incorrect ET4000/W32 probe
+ problem.
+ <item>Much improved detection for Mach64 cards.
+ <item>Improved detection for Trident cards.
+ <item>Added detection of SiS, ARK, S3 ViRGE cards.
+</itemize>
+-->
+<itemize>
+ <item>C&amp;T 65548, Cirrus CL-GD7543/1, AT&amp;T20C409,
+ AT&amp;T20C499 ¤ÎõÃΤòÄɲä·¡¢Àµ¤·¤¯¤Ê¤¤ ET4000/W32 ¤Îõºº¤ÎÌäÂê¤ò
+ ½¤Àµ¤·¤Þ¤·¤¿¡£
+ <item>Mach64 ¥Ó¥Ç¥ª¥«¡¼¥É¤ÎõÃΤò¿¤¤¤Ë¸þ¾å¤·¤Þ¤·¤¿¡£
+ <item>Trident ¥Ó¥Ç¥ª¥«¡¼¥É¤ÎõÃΤò¸þ¾å¤·¤Þ¤·¤¿¡£
+ <item>SiS, ARK, S3 ViRGE ¥Ó¥Ç¥ª¥«¡¼¥É¤ÎõÃΤòÄɲä·¤Þ¤·¤¿¡£
+</itemize>
+<!--
+<sect1> Fonts
+-->
+<sect1> ¥Õ¥©¥ó¥È
+<p>
+<!--
+<itemize>
+ <item>The Cyrillic fonts have been updated.
+</itemize>
+-->
+<itemize>
+ <item>¥­¥ê¥ëʸ»ú¥Õ¥©¥ó¥È¤ò¹¹¿·¤·¤Þ¤·¤¿¡£
+</itemize>
+<!--
+<sect>Installing the XFree86 3.1.2E Beta Release
+<p>
+The XFree86 3.1.2E binary beta release is distributed as a upgrade to
+3.1.2D. If you don't already have 3.1.2D installed, first install it
+(installation details for 3.1.2D are included below) except for the X
+servers.
+
+The core part of the 3.1.2E release consists of the following files:
+<quote>
+<verb>
+BetaReport Beta test report template form
+X312Eupd.tgz Files which have changed since 3.1.2D
+X312Edoc.tgz Documentation for 3.1.2E
+</verb>
+</quote>
+
+and for Linux a.out also:
+<quote>
+<verb>
+X312Eprog.tgz programming libraries and include files
+ which have changed since 3.1.2D
+</verb>
+</quote>
+
+The following X servers are for PC/AT hardware. Choose at least one which
+matches your hardware.
+<quote>
+<verb>
+X312E8514.tgz 8514/A server
+X312EAGX.tgz AGX server
+X312EI128.tgz I128 server
+X312EMa32.tgz Mach 32 server
+X312EMa64.tgz Mach 64 server
+X312EMa8.tgz Mach 8 server
+X312EMono.tgz Mono server
+X312EP9K.tgz P9000 server
+X312ES3.tgz S3 server
+X312ESVGA.tgz SVGA server
+X312EVG16.tgz 16 colour VGA server
+X312EW32.tgz ET4000/W32 server
+</verb>
+</quote>
+The following X servers are for PC98 hardware. If you have a PC98 machine,
+choose one which suits your hardware. If you don't know what a PC98 machine
+is, you don't need any of these.
+<quote>
+<verb>
+X312E9NS3.tgz PC98 NEC(S3) server
+X312E9SPW.tgz PC98 PCSKB-PowerWindow(S3) server
+X312E9LPW.tgz PC98 PowerWindowLB(S3) server
+X312E9EGC.tgz PC98 EGC(generic) server
+X312E9GAN.tgz PC98 GANB-WAP(cirrus) server
+X312E9480.tgz PC98 PEGC-480(generic) server
+X312E9NKV.tgz PC98 NKV-NEC(cirrus) server
+X312E9WBS.tgz PC98 WABS(cirrus) server
+X312E9WEP.tgz PC98 WAB-EP(cirrus) server
+X312E9WSN.tgz PC98 WSN-A2F(cirrus) server
+X312E9TGU.tgz PC98 TGUI server
+</verb>
+</quote>
+The following servers are optional:
+<quote>
+<verb>
+X312Enest.tgz Nested X server
+X312Evfb.tgz Virtual framebuffer X server
+</verb>
+</quote>
+
+The upgrade to version 3.1.2E will overwrite some files from the 3.1.2D
+installation. It is recommended that you <bf>MAKE A BACKUP OF</bf>
+<tt>/usr/X11R6</tt> <bf>BEFORE DOING ANYTHING ELSE</bf>.
+
+To upgrade from 3.1.2D to 3.1.2E, first extract the X312Eupd.tgz and
+X312Edoc.tgz files as root from the <tt>/usr/X11R6</tt> directory:
+
+<tscreen><verb>
+ cd /usr/X11R6
+ gzip -d < X312Eupd.tgz | tar vxf -
+ gzip -d < X312Edoc.tgz | tar vxf -
+</verb></tscreen>
+
+Next, extract the server(s) you need from the same directory. For example,
+to extract the S3 and SVGA and Xnest servers, run:
+
+<tscreen><verb>
+ cd /usr/X11R6
+ gzip -d < X312ES3.tgz | tar vxf -
+ gzip -d < X312ESVGA.tgz | tar vxf -
+ gzip -d < X312Enest.tgz | tar vxf -
+</verb></tscreen>
+
+Note that there is no postinst.sh script to be run for this release.
+However, if you didn't install <tt>X312Dfnon.tgz</tt> when installing
+3.1.2D (or are not sure if you installed it), you should run the following:
+
+<tscreen><verb>
+ /usr/X11R6/bin/mkfontdir /usr/X11R6/lib/X11/fonts/misc
+</verb></tscreen>
+
+An up-to-date version of the xterm termcap and terminfo entries is
+included in the 3.1.2E update. The files get installed in
+<tt>/usr/X11R6/lib/X11/etc</tt>. To make use of these, you need to
+manually update your system's termcap or terminfo database. If your
+system uses termcap, find the <tt>termcap</tt> file (it may be in
+<tt>/etc</tt> or somewhere under <tt>/usr/share</tt>), comment out the
+existing xterm entries, and add the new ones (which are in
+<tt>/usr/X11R6/lib/X11/etc/xterm.termcap</tt>). If your system uses
+terminfo, the new entries can be installed by running:
+
+<tscreen><verb>
+ tic /usr/X11R6/lib/X11/etc/xterm.terminfo
+</verb></tscreen>
+
+Note: on some systems (including Linux), you may first need to remove
+some existing terminfo entries if <tt>tic</tt> complains about duplicates.
+For example:
+
+<tscreen><verb>
+ rm /usr/lib/terminfo/x/xterms
+ rm /usr/lib/terminfo/v/vs100
+</verb></tscreen>
+-->
+
+<!--
+<sect>Installing the XFree86 3.2 Release
+-->
+<sect>XFree86 3.2 ¤ÎƳÆþ
+<p>
+<!--
+The XFree86 3.2 binary release is distributed as a full release,
+not as an upgrade.
+
+What follows is a list of the XFree86 3.2 components. There may be
+some variations in this for some OSs.
+
+The following are required for all installations:
+<quote>
+<verb>
+preinst.sh Pre-installation script
+postinst.sh Post-installation script
+X32bin.tgz Clients, run-time libs, and app-defaults files
+X32doc.tgz Documentation
+X32fnts.tgz 75dpi, misc and PEX fonts
+X32lib.tgz Data files required at run-time
+X32man.tgz Manual pages
+X32set.tgz XF86Setup utility
+X32VG16.tgz 16 colour VGA server (XF86Setup needs this server)
+</verb>
+</quote>
+-->
+XFree86 3.2 ¥Ð¥¤¥Ê¥êÈǤϲþÄûÈǤȤ·¤Æ¤Ç¤Ï¤Ê¤¯´°Á´ÈǤȤ·¤ÆÇÛÉÛ¤·¤Þ¤¹¡£
+
+XFree86 3.2 ¤Î¹½À®Í×ÁǤΰìÍ÷¤Ï¼¡¤ÎÄ̤ê¤Ç¤¹¡£¤¤¤¯¤Ä¤«¤Î OS Ëè¤ËÁê°ã¤¬
+¤¢¤ë¤Ç¤·¤ç¤¦¡£
+
+¼¡¤ÏÁ´¤Æ¤òƳÆþ¤¹¤ë¤Î¤ËɬÍפǤ¹¡£:
+<quote>
+<verb>
+preinst.sh ƳÆþÁ°¥¹¥¯¥ê¥×¥È
+postinst.sh ƳÆþ¸å¥¹¥¯¥ê¥×¥È
+X32bin.tgz ¥¯¥é¥¤¥¢¥ó¥È¡¢¥é¥ó¥¿¥¤¥à¥é¥¤¥Ö¥é¥ê¤È¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î
+ ɸ½àÃÍ¥Õ¥¡¥¤¥ë
+X32doc.tgz ʸ½ñ
+X32fnts.tgz 75dpi, ¼þÊÕ¥Õ¥¡¥¤¥ë¤È PEX ¥Õ¥©¥ó¥È
+X32lib.tgz ¼Â¹Ô»þ¤ËɬÍפʥǡ¼¥¿¥Õ¥¡¥¤¥ë
+X32man.tgz ¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë
+X32set.tgz XF86Setup ¥æ¡¼¥Æ¥£¥ê¥Æ¥£
+X32VG16.tgz 16 ¿§ VGA ¥µ¡¼¥Ð(XF86Setup ¤¬¤³¤Î¥µ¡¼¥Ð¤òɬÍפȤ·¤Æ¤¤¤Þ¤¹)
+</verb>
+</quote>
+
+<!--
+The following is required for new installations, and optional for existing
+installations:
+<quote>
+<verb>
+X32cfg.tgz sample config files for xinit, xdm
+</verb>
+</quote>
+
+NOTE: Be very careful about installing X32cfg.tgz over an existing
+installation if you have customised your xinit and/or xdm config files.
+Installing X32cfg.tgz will overwrite any existing files. If you do have
+customised files, there is no need to install X32cfg.tgz.
+
+The following X servers are for PC/AT hardware. Choose at least one which
+matches your hardware, as well as the VGA16 server. The VGA16 server is
+required by the new configuration utility (XF86Setup).
+<quote>
+<verb>
+X328514.tgz 8514/A server
+X32AGX.tgz AGX server
+X32I128.tgz I128 server
+X32Ma32.tgz Mach 32 server
+X32Ma64.tgz Mach 64 server
+X32Ma8.tgz Mach 8 server
+X32Mono.tgz Mono server
+X32P9K.tgz P9000 server
+X32S3.tgz S3 server
+X32S3V.tgz S3 ViRGE server
+X32SVGA.tgz SVGA server
+X32VG16.tgz 16 colour VGA server (XF86Setup needs this server)
+X32W32.tgz ET4000/W32, ET6000 server
+</verb>
+</quote>
+-->
+½é¤á¤Æ¤ÎƳÆþ¤Ë¤Ï¼¡¤¬É¬Íפǡ¢´û¤ËƳÆþ¤·¤Æ¤¤¤ë¾ì¹ç¤Ë¤ÏÄɲúî¶È¤¬¤¢¤ê¤Þ
+¤¹¡£:
+<quote>
+<verb>
+X32cfg.tgz xinit, xdm ¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤ÎÎãÂê
+</verb>
+</quote>
+
+Ãí°Õ¡§xinit ¤ä xdm ¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤òÊѹ¹¤·¤Æ¤¤¤ë´û¤ËƳÆþ¤·¤Æ¤¤¤ë½ê¤Ë
+X32cfg.tgz ¤ò¾å½ñ¤­¤¹¤ë¤È¤­¤Ï½½Ê¬Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£X32cfg.tgz ¤ò
+ƳÆþ¤¹¤ë¤È´û¤Ë¸ºß¤¹¤ë¥Õ¥¡¥¤¥ë¤ò½ñ¤­´¹¤¨¤Æ¤·¤Þ¤¤¤Þ¤¹¡£¥Õ¥¡¥¤¥ë¤ò
+Êѹ¹¤·¤Æ¤¤¤ë¾ì¹ç¤Ï X32cfg.tgz ¤òƳÆþ¤¹¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£
+
+¼¡¤Î X ¥µ¡¼¥Ð¤Ï PC/AT µ¡ÍѤǤ¹¡£µ¡ºà¤Ë°ìÃפ¹¤ë¤â¤Î¤ò VGA16 ¥µ¡¼¥Ð¼ã¤¯¤Ï
+¤¤¤Å¤ì¤«£±¤ÄÁªÂò¤·¤Æ¤¯¤À¤µ¤¤¡£VGA16 ¥µ¡¼¥Ð¤Ï¿·¤·¤¤¹½À®¾ðÊóÀßÄê¥æ¡¼¥Æ¥£
+¥ê¥Æ¥£(XF86Setup) ¤ËɬÍפǤ¹¡£
+<quote>
+<verb>
+X328514.tgz 8514/A ¥µ¡¼¥Ð
+X32AGX.tgz AGX ¥µ¡¼¥Ð
+X32I128.tgz I128 ¥µ¡¼¥Ð
+X32Ma32.tgz Mach 32 ¥µ¡¼¥Ð
+X32Ma64.tgz Mach 64 ¥µ¡¼¥Ð
+X32Ma8.tgz Mach 8 ¥µ¡¼¥Ð
+X32Mono.tgz Mono ¥µ¡¼¥Ð
+X32P9K.tgz P9000 ¥µ¡¼¥Ð
+X32S3.tgz S3 ¥µ¡¼¥Ð
+X32S3V.tgz S3 ViRGE ¥µ¡¼¥Ð
+X32SVGA.tgz SVGA ¥µ¡¼¥Ð
+X32VG16.tgz 16 colour VGA ¥µ¡¼¥Ð (XF86Setup ¤Ï¤³¤Î¥µ¡¼¥Ð¤¬É¬ÍפǤ¹)
+X32W32.tgz ET4000/W32, ET6000 ¥µ¡¼¥Ð
+</verb>
+</quote>
+<!--
+The following X server is for Alpha hardware.
+<quote>
+<verb>
+X32TGA.tgz DEC 21030 (TGA) server
+</verb>
+</quote>
+-->
+¼¡¤Ï Alpha µ¡ÍÑ X ¥µ¡¼¥Ð¤Ç¤¹¡£
+<quote>
+<verb>
+X32TGA.tgz DEC 21030 (TGA) ¥µ¡¼¥Ð
+</verb>
+</quote>
+<!--
+The following X servers are for PC98 hardware. If you have a PC98 machine,
+choose one which suits your hardware. If you don't know what a PC98 machine
+is, you don't need any of these.
+<quote>
+<verb>
+X329NS3.tgz PC98 NEC(S3) server
+X329SPW.tgz PC98 PCSKB-PowerWindow(S3) server
+X329LPW.tgz PC98 PowerWindowLB(S3) server
+X329EGC.tgz PC98 EGC(generic) server
+X329GA9.tgz PC98 GA-968V4/PCI(S3 968) server
+X329GAN.tgz PC98 GANB-WAP(cirrus) server
+X329480.tgz PC98 PEGC-480(generic) server
+X329NKV.tgz PC98 NKV-NEC(cirrus) server
+X329WS.tgz PC98 WABS(cirrus) server
+X329WEP.tgz PC98 WAB-EP(cirrus) server
+X329WSN.tgz PC98 WSN-A2F(cirrus) server
+X329TGU.tgz PC98 TGUI server
+</verb>
+</quote>
+-->
+¼¡¤Ï PC98 µ¡ÍѤΠX ¥µ¡¼¥Ð¤Ç¤¹¡£PC98 µ¡¤ò¤â¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï
+¤ª¼ê¸µ¤Îµ¡ºà¤Ë¹ç¤Ã¤Æ¤¤¤ë¤â¤Î¤òÁªÂò¤·¤Æ¤¯¤À¤µ¤¤¡£PC98 µ¡¤¬²¿¤«ÃΤé¤Ê¤¤¾ì¹ç
+¤Ï¡¢¤¤¤º¤ì¤âɬÍפ¢¤ê¤Þ¤»¤ó¡£
+<quote>
+<verb>
+X329NS3.tgz PC98 NEC(S3) ¥µ¡¼¥Ð
+X329SPW.tgz PC98 PCSKB-PowerWindow(S3) ¥µ¡¼¥Ð
+X329LPW.tgz PC98 PowerWindowLB(S3) ¥µ¡¼¥Ð
+X329EGC.tgz PC98 EGC(generic) ¥µ¡¼¥Ð
+X329GA9.tgz PC98 GA-968V4/PCI(S3 968) ¥µ¡¼¥Ð
+X329GAN.tgz PC98 GANB-WAP(cirrus) ¥µ¡¼¥Ð
+X329480.tgz PC98 PEGC-480(generic) ¥µ¡¼¥Ð
+X329NKV.tgz PC98 NKV-NEC(cirrus) ¥µ¡¼¥Ð
+X329WS.tgz PC98 WABS(cirrus) ¥µ¡¼¥Ð
+X329WEP.tgz PC98 WAB-EP(cirrus) ¥µ¡¼¥Ð
+X329WSN.tgz PC98 WSN-A2F(cirrus) ¥µ¡¼¥Ð
+X329TGU.tgz PC98 TGUI ¥µ¡¼¥Ð
+</verb>
+</quote>
+<!--
+The following are optional.
+-->
+¼¡¤Ï¥ª¥×¥·¥ç¥ó¤Ç¤¹¡£
+<!--
+<quote>
+<verb>
+X32f100.tgz 100dpi fonts
+X32fcyr.tgz Cyrillic fonts
+X32fnon.tgz Other fonts (Chinese, Japanese, Korean, Hebrew)
+X32fscl.tgz Scalable fonts (Speedo and Type1)
+X32fsrv.tgz Font server and config files
+X32prog.tgz X header files, config files and compile-time libs
+X32lkit.tgz X server LinkKit
+X32lk98.tgz PC98 X server LinkKit
+X32nest.tgz Nested X server
+X32vfb.tgz Virtual framebuffer X server
+X32ps.tgz PostScript version of the documentation
+X32html.tgz HTML version of the documentation
+</verb>
+</quote>
+-->
+<quote>
+<verb>
+X32f100.tgz 100dpi ¥Õ¥©¥ó¥È
+X32fcyr.tgz ¥­¥ê¥ëʸ»ú¥Õ¥©¥ó¥È
+X32fnon.tgz ¤½¤Î¾¤Î¥Õ¥©¥ó¥È (Ãæ¹ñ¸ì, ÆüËܸì, ´Ú¹ñ¸ì, ¥Ø¥Ö¥é¥¤¸ì)
+X32fscl.tgz ¥¹¥±¡¼¥é¥Ö¥ë¥Õ¥©¥ó¥È (Speedo ¤È Type1)
+X32fsrv.tgz ¥Õ¥©¥ó¥È¥µ¡¼¥Ð¤ÈÀßÄê¥Õ¥¡¥¤¥ë
+X32prog.tgz X ¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë, ÀßÄê¥Õ¥¡¥¤¥ë¤È¥³¥ó¥Ñ¥¤¥ë¤ËɬÍפʥ饤¥Ö¥é¥ê
+X32lkit.tgz X ¥µ¡¼¥Ð¥ê¥ó¥¯¥­¥Ã¥È
+X32lk98.tgz PC98 X ¥µ¡¼¥Ð¥ê¥ó¥¯¥­¥Ã¥È
+X32nest.tgz ¥Í¥¹¥È¤·¤¿ X ¥µ¡¼¥Ð
+X32vfb.tgz ²¾Áۥե졼¥à¥Ð¥Ã¥Õ¥¡¤ò»È¤¦ X ¥µ¡¼¥Ð
+X32ps.tgz ʸ½ñ¤Î¥Ý¥¹¥È¥¹¥¯¥ê¥×¥ÈÈÇ
+X32html.tgz ʸ½ñ¤Î HTML ÈÇ
+</verb>
+</quote>
+
+<!--
+If you already have a version of XFree86 installed, <bf>MAKE A BACKUP OF</bf>
+<tt>/usr/X11R6</tt> <bf>BEFORE DOING ANYTHING ELSE</bf>. The standard
+installation procedure will overwrite your existing version of XFree86.
+
+If you are installing from scratch, create a directory called
+<tt>/usr/X11R6</tt>, then extract the required <tt>.tgz</tt> files.
+If you don't have enough space in <tt>/usr</tt> for this, create a
+directory elsewhere and create a symbolic link to it.
+E.g., if you create a directory in <tt>/home</tt>:
+<tscreen><verb>
+ mkdir /home/X11R6
+ ln -s /home/X11R6 /usr
+</verb></tscreen>
+-->
+´û¤Ë XFree86 ¤Î¤¤¤º¤ì¤«¤òƳÆþºÑ¤ß¤Î¾ì¹ç¤Ï¡¢<bf>¾¤Î»ö¤ò¹Ô¤¦Á°¤Ë</bf>
+<tt>/usr/X11R6</tt> ¤Î<bf>¥Ð¥Ã¥¯¥¢¥Ã¥×¤ò¼è¤Ã¤Æ¤¯¤À¤µ¤¤</bf>¡£É¸½à¤Î
+ƳÆþ¼ê½ç¤Ç¤Ï¡¢¤½¤³¤Ë¤¢¤ë XFree86 ¤ò¾å½ñ¤­¤·¤Þ¤¹¡£
+
+¿·µ¬¤ËƳÆþ¤¹¤ë¾ì¹ç¤Ï <tt>/usr/X11R6</tt> ¤È¤¤¤¦¥Ç¥£¥ì¥¯¥È¥ê¤òºîÀ®¤·¤Æ¡¢
+¤½¤·¤Æ <tt>.tgz</tt> ¥Õ¥¡¥¤¥ë¤ò¿­Ä¥ (extract) ¤·¤Æ¤¯¤À¤µ¤¤¡£
+¿·µ¬Æ³Æþ¤ò¹Ô¤¦¤Î¤Ë <tt>/usr</tt> ¤Ë½½Ê¬¤Ê¶õ¤¬¤Ê¤¤¾ì¹ç¤Ï¡¢¤É¤³¤«Â¾¤Ë
+¥Ç¥£¥ì¥¯¥È¥ê¤òºîÀ®¤·¤Æ <tt>/usr/</tt> ¤Ë¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤òºîÀ®¤·¤Æ
+¤¯¤À¤µ¤¤¡£
+Î㤨¤Ð¡¢<tt>/home</tt> ¤Ë¥Ç¥£¥ì¥¯¥È¥ê¤òºîÀ®¤¹¤ë¾ì¹ç¤Ï¼¡¤Î¤è¤¦¤Ë¤·¤Æ
+¤¯¤À¤µ¤¤¡£:
+<tscreen><verb>
+ mkdir /home/X11R6
+ ln -s /home/X11R6 /usr
+</verb></tscreen>
+
+<!--
+The next step is to run the pre-installation script. This script makes
+some preliminary checks of your system. For some OSs, it may tell you
+to install new versions of some system components before proceeding with
+the installation. This script also removes outdated files and symbolic
+links from a previous installation that may cause problems.
+
+Copy the <tt>preinst.sh</tt> script to
+<tt>/var/tmp</tt>, then go to <tt>/usr/X11R6</tt> and run it:
+<tscreen><verb>
+ cd /usr/X11R6
+ sh /var/tmp/preinst.sh
+</verb></tscreen>
+
+The <tt>.tgz</tt> files are gzipped tar files. To extract them, go to
+<tt>/usr/X11R6</tt>, and run the following as <bf>root</bf> for each
+file you need:
+<tscreen><verb>
+ gzip -d < X32file.tgz | tar vxf -
+</verb></tscreen>
+On some OSs, you might get some "Broken Pipe" messages. Providing there
+are no other messages associated with this, they can be safely ignored.
+Note: You should not be running X while doing this installation. Doing
+so may cause the installation to fail, or cause your X session to crash.
+-->
+¼¡¤ÎÃʳ¬¤ÏƳÆþÁ°¥¹¥¯¥ê¥×¥È¤ò¼Â¹Ô¤·¤Æ¤¯¤À¤µ¤¤¡£¤³¤Î¥¹¥¯¥ê¥×¥È¤Ï¥·¥¹¥Æ¥à¤Î
+¤¤¤¯¤Ä¤«¤ÎͽÈ÷Ä´ºº¤ò¹Ô¤¤¤Þ¤¹¡£¤¤¤¯¤Ä¤«¤Î OS ¤Ç¤ÏƳÆþÁ°¥¹¥¯¥ê¥×¥È¤¬¿·¤·¤¤
+¥·¥¹¥Æ¥à¹½À®Í×ÁǤòƳÆþ¤¹¤ë¤«Æ³ÆþÁ°¤Ëʹ¤¤¤Æ¤­¤Þ¤¹¡£¤³¤Î¥¹¥¯¥ê¥×¥È¤ÏÌäÂê¤ò
+µ¯¤³¤·¤½¤¦¤Ê¡¢¸Å¤¯¤Ê¤Ã¤¿¥Õ¥¡¥¤¥ë¤È¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤ò°ÊÁ°¤ÎƳÆþ¤·¤¿¤â¤Î
+¤«¤éºï½ü¤·¤Þ¤¹¡£
+<tt>preinst.sh</tt> ¤ò <tt>/var/tmp</tt> ¤Ë¥³¥Ô¡¼¤·¤Æ¡¢¤½¤ì¤«¤é
+<tt>/usr/X11R6</tt> ¤Ë°Üư¤·¤Æ¥¹¥¯¥ê¥×¥È¤ò¼Â¹Ô¤·¤Æ¤¯¤À¤µ¤¤¡£:
+<tscreen><verb>
+ cd /usr/X11R6
+ sh /var/tmp/preinst.sh
+</verb></tscreen>
+
+<tt>.tgz</tt> ¥Õ¥¡¥¤¥ë¤Ï gzip °µ½Ì¤·¤¿ tar ¥Õ¥¡¥¤¥ë¤Ç¤¹¡£¤³¤ì¤é¤Î¥Õ¥¡¥¤¥ë
+¤ò¿­Ä¥¤·¤¿¤é <tt>/usr/X11R6</tt> ¤Ë°Üư¤·¤Æ <bf>root</bf> ¤Ë¤Ê¤Ã¤Æ¼¡¤Î
+ɬÍפʥե¡¥¤¥ë¤ò¼Â¹Ô¤·¤Æ¤¯¤À¤µ¤¤¡£
+<tscreen><verb>
+ gzip -d < X32file.tgz | tar vxf -
+</verb></tscreen>
+¤¤¤¯¤Ä¤«¤Î OS ¤Ç¤Ï¡¢¤¤¤¯¤Ä¤« "Broken Pipe" ¤È¤¤¤¦¥á¥Ã¥»¡¼¥¸¤¬½ÐÎϤµ¤ì¤Þ
+¤¹¡£¤³¤Î¥á¥Ã¥»¡¼¥¸¤Ë´ØÏ¢¤·¤¿Â¾¤Î¥á¥Ã¥»¡¼¥¸¤¬¤Ê¤¤¾ì¹ç¡¢Ìµ»ë¤·¤Æ¤â·ë¹½¤Ç
+¤¹¡£
+Ãí°Õ»ö¹à: ¤³¤ÎƳÆþºî¶ÈÃæ¤Ë X ¤òµ¯Æ°¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£Æ³Æþ¤Ë»Ù¾ã¤ò¤­¤¿¤¹
+ÍÍ¡¹¤Ê»ö¤¬µ¯¤³¤Ã¤¿¤ê¡¢X ¥»¥Ã¥·¥ç¥ó¤¬½ªÎ»¤·¤¿¤ê¤·¤Þ¤¹¡£
+
+<!--
+If you are using NetBSD or FreeBSD, a more reliable (and highly recommended)
+way of doing this is to extract the <tt>.tgz</tt> files with:
+<tscreen><verb>
+ gzip -d < X32file.tgz | tar -v -x **unlink -f -
+</verb></tscreen>
+
+If you have GNU cpio (as Linux does) or SVR4 cpio, a more reliable (and
+highly recommended) way of doing this is to extract the <tt>.tgz</tt>
+files with:
+<tscreen><verb>
+ gzip -d < X32file.tgz | cpio -i -v -d -u -H ustar
+</verb></tscreen>
+
+Once the required <tt>.tgz</tt> files have been extracted, copy the
+<tt>postinst.sh</tt> script to <tt>/var/tmp</tt>, then go to
+<tt>/usr/X11R6</tt> and run it:
+<tscreen><verb>
+ cd /usr/X11R6
+ sh /var/tmp/postinst.sh
+</verb></tscreen>
+-->
+NetBSD ¤Þ¤¿¤Ï FreeBSD ¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¤è¤ê³Î¼Â¤Ê(¤«¤Ä¶¯¤¯¤ª´«¤á¤¹¤ë)
+ƳÆþÊýË¡¤Ï <tt>.tgz</tt> ¥Õ¥¡¥¤¥ë¤ò¼¡¤Î¤è¤¦¤Ë¿­Ä¥¤¹¤ë¤³¤È¤Ç¤¹¡£:
+<tscreen><verb>
+ gzip -d < X32file.tgz | tar -v -x --unlink -f -
+</verb></tscreen>
+
+GNU cpio (Linux ¤Ï»ý¤Ã¤Æ¤¤¤Þ¤¹) ¤Þ¤¿¤Ï SVR4 cpio ¤ò»ý¤Ã¤Æ¤¤¤ë¤Ê¤é¤Ð¡¢
+¤è¤ê³Î¼Â¤Ê(¤«¤Ä¶¯¤¯¤ª´«¤á¤¹¤ë) ƳÆþÊýË¡¤Ï <tt>.tgz</tt> ¥Õ¥¡¥¤¥ë¤ò
+¼¡¤Î¤è¤¦¤Ë¿­Ä¥¤¹¤ë¤³¤È¤Ç¤¹¡£:
+<tscreen><verb>
+ gzip -d < X32file.tgz | cpio -i -v -d -u -H ustar
+</verb></tscreen>
+
+ɬÍ×¤Ê <tt>.tgz</tt> ¥Õ¥¡¥¤¥ë¤¬¿­Ä¥¤Ç¤­¤¿¤é¡¢<tt>postinst.sh</tt>
+¥¹¥¯¥ê¥×¥È¤ò <tt>/var/tmp</tt> ¤Ë¥³¥Ô¡¼¤·¤Æ¡¢¤½¤·¤Æ <tt>/usr/X11R6</tt>
+¤Ë°Üư¤·¤Æ¥¹¥¯¥ê¥×¥È¤ò¼Â¹Ô¤·¤Æ¤¯¤À¤µ¤¤¡£:
+<tscreen><verb>
+ cd /usr/X11R6
+ sh /var/tmp/postinst.sh
+</verb></tscreen>
+
+<!--
+For OSs which use ldconfig (like Linux, FreeBSD and NetBSD), you
+should either run ldconfig or reboot to complete the installation.
+On FreeBSD and NetBSD, ldconfig takes arguments. In particular, you should
+at least include <tt>/usr/lib</tt> and <tt>/usr/X11R6/lib</tt> on the
+command line. Check <tt>/etc/rc</tt> to see how ldconfig gets run at
+boot time.
+-->
+Linux, FreeBSD ¤È NetBSD ¤Î¤è¤¦¤Ê ldconfig ¤ò»ÈÍѤ¹¤ë OS ¤Ç¤Ï¡¢ldconfig ¤ò
+¼Â¹Ô¤¹¤ë¤«ºÆÎ©¤Á¾å¤²¤ò¹Ô¤¨¤ÐƳÆþ¤Ï´°Î»¤·¤Þ¤¹¡£ÆÃ¤Ë¡¢ºÇÄã <tt>/usr/lib</tt>
+¤È <tt>/usr/X11R6/lib</tt> ¤ò¥³¥Þ¥ó¥É¥é¥¤¥ó¤«¤éÄɲ䷤Ƥ¯¤À¤µ¤¤¡£
+µ¯Æ°»þ¤Ë¤É¤Î¤è¤¦¤Ë ldconfig ¤ò¼Â¹Ô¤·¤Æ¤¤¤ë¤« <tt>/etc/rc</tt> ¤òÄ´ºº¤·¤Æ
+¤¯¤À¤µ¤¤¡£
+
+<p>
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/RELNOTE.sgml,v 3.1 1997/01/26 04:34:24 dawes Exp $
+</verb>
+<hrule>
+
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ï xc/programs/Xserver/hw/xfree86/doc/sgml/RELNOTE.sgml,v 3.47 1996/10/26 09:38:54 ¤ò¡¢²¬ËÜ °ì¹¬
+( Kazuyuki Okamoto <url url="mailto:ikko-@pacific.rim.or.jp"
+name="&lt;ikko-@pacific.rim.or.jp&gt;"> ) ¤¬ XFree86 3.2 ¤ò
+ÆüËܤǥ¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¿Í¸þ¤±¤ËÏÂÌõ¤·¤¿¤â¤Î¤Ç¤¹¡£¤³¤³¤¬¤ª¤«¤·¤¤¤È¤«¡¢
+¤³¤³¤Ï¤³¤¦¤·¤¿¤Û¤¦¤¬¤¤¤¤¤È¤¤¤Ã¤¿¤´°Õ¸«¤¬¤¢¤ê¤Þ¤·¤¿¤é¡¢ÅŻҥ᡼¥ë¤Ç
+¤ªÃΤ餻²¼¤µ¤¤¡£
+¸¶Ê¸¤ÎÃøºî¸¢¤Ï XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ÎÏÂÌõ¤ÎÃøºî¸¢¤Ï
+XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤È²¬ËÜ¡¡°ì¹¬¤Ë¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤ÎÏÂÌõ¤ÎÉÔ¶ñ¹ç¤Ï»ä¤Ë¡¢
+ÅŻҥ᡼¥ë¤ÇÁ÷¤Ã¤Æ²¼¤µ¤¤¡£
+<hrule>
+&lsqb;EOF&rsqb;
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/S3.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/S3.sgml
new file mode 100644
index 000000000..4ca400a36
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/S3.sgml
@@ -0,0 +1,872 @@
+<!doctype linuxdoc system>
+
+<article>
+<title> S3 ¥Á¥Ã¥×¥»¥Ã¥È»ÈÍѼԤΤ¿¤á¤Î¾ðÊó
+<author>XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò
+<date>1996 ǯ 1 ·î 15 Æü
+<trans> ²¬ËÜ¡¡°ì¹¬ Kazuyuki Okamoto &lt;ikko-@pacific.rim.or.jp&gt;
+<toc>
+
+<sect> ¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¥Ï¡¼¥É¥¦¥§¥¢
+<p>
+¸½¹Ô¤Î S3 ¥µ¡¼¥Ð¤Ï 911, 924, 801/805, 928, 732 (Trio32), 764 (Trio64),
+864, 868, 964 ¤È 968 ¤ÎÆþ¼ê²Äǽ¤Ê S3 ¤Î¥Á¥Ã¥×¥»¥Ã¥È¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£S3
+¥µ¡¼¥Ð¤Ï 866 ¤âǧ¼±¤·¤Þ¤¹¤¬¡¢¤³¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ï̤¤À¥Æ¥¹¥È¤·¤Æ¤Þ¤»¤ó¡£¤³
+¤ì¤é¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ç²¿¤«ÌäÂ꤬¤¢¤Ã¤¿¤È¤«¡¢¤¦¤Þ¤¯Æ°ºî¤·¤¿¤È¤«¤ò¡¢²æ¡¹¤ËÊó¹ð
+¤·¤Æ²¼¤µ¤¤¡£
+
+¤·¤«¤·¡¢¤½¤ì¤é¤Î¥Á¥Ã¥×¥»¥Ã¥È¤òÅëºÜ¤·¤Æ¤¤¤ëÁ´¤Æ¤Î¥Ó¥Ç¥ª¥Ü¡¼¥É¤ò½½Ê¬¥µ¥Ý¡¼¥È
+¤·¤Æ¤¤¤Þ¤»¤ó¡£Æ°ºî³Îǧ¤ò¤·¤¿¥Ó¥Ç¥ª¥Ü¡¼¥É¤Î¤¤¤¯¤Ä¤«¤ò¼¡¤Î°ìÍ÷¤Ë¼¨¤·¤Þ¤¹¡£¼«
+ʬ¤Î¥«¡¼¥É¤Ë»÷¤¿¥«¡¼¥É¤¬°ìÍ÷¤ÎÃæ¤Ë¤¢¤ë¾ì¹ç¤Ï¡¢¤½¤Î¥«¡¼¥É¤âưºî¤¹¤ë²ÄǽÀ­¤¬
+¤¢¤ê¤Þ¤¹¡£
+[ ÌõÃí¡§bpp (bit per pixel) ¤Ï£±¥Ô¥¯¥»¥ë(²èÁÇ) ¤òɽ¸½¤¹¤ë¥Ó¥Ã¥È¿ô ]
+
+<descrip>
+<tag>S3 801/805, AT&amp;T 20C490 (¤Þ¤¿¤Ï ¤½¤Ã¤¯¤ê¤µ¤ó) RAMDAC</tag>
+ <itemize>
+ <item> Orchid Fahrenheit 1280+ VLB
+ <item> Actix GE32
+ </itemize>
+
+ 8 ¤È 15/16 bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ Ãí°Õ: ËÜʪ¤Î AT&amp;T20C490 RAMDAC ¤Ï¥µ¡¼¥Ð¤Ç¼«Æ°Ç§¼±½ÐÍè¤Þ¤¹¡£
+ ¤½¤Î¸ß´¹¥Á¥Ã¥×¥»¥Ã¥È¤Î¾ì¹ç¤Ï <tt/XF86Config/ ¤Ë
+ `<tt/Ramdac "att20c490"/'¤ÈÌÀµ­¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+ ËÜʪ¤Î AT&amp;T 20C490 ¤È 20C491 RAMDAC ¤Ï <tt/"dac_8_bit"/ ¤È¤¤¤¦
+ ¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤ÆÆ°ºî¤·¤Þ¤¹¡£¡ÊWinbond 82C490 ¤Î¤è¤¦¤Ê¡Ë¤¤¤¯¤Ä¤«¤Î
+ ¤½¤Ã¤¯¤ê¤µ¤ó¤Ë¤Ï¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£
+
+ Orchid Fahrenheit 1280+ VLB ¤Ë¤Ï `<tt/Option "nolinear"/' ¤¬É¬ÍפǤ¹¡£
+
+
+
+<tag>S3 805 VLB, S3 GENDAC (RAMDAC + ¥¯¥í¥Ã¥¯¥·¥ó¥»¥µ¥¤¥¶¡¼)</tag>
+ <itemize>
+ <item> MIRO 10SD (VLB ¤È PCI ÍѤ¬ÍøÍѲÄǽ)
+ Á´¤Æ¤Î10SD ¤¬ S3 GENDAC ¤òÅëºÜ¤·¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¤ï¤«¤ê¤Þ¤»¤ó¡£
+ </itemize>
+
+ 8 ¤È 15/16 bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ <tscreen><verb>
+ ClockChip "s3gendac"
+ RamDac "s3gendac"
+ </verb></tscreen>
+
+
+<tag>S3 801/805, AT&amp;T 20C490 RAMDAC, ICD2061A ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> STB PowerGraph X.24 S3 (ISA)
+ </itemize>
+
+ 8 ¤È 15/16 bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ Ãí°Õ: ËÜʪ¤Î AT&amp;T20C490 RAMDAC ¤Ï¥µ¡¼¥Ð¤Ç¼«Æ°Ç§¼±½ÐÍè¤Þ¤¹¡£
+ ¤½¤Î¸ß´¹¥Á¥Ã¥×¥»¥Ã¥È¤Î¾ì¹ç¤Ï <tt/XF86Config/ ¤Ë`<tt/Ramdac "att20c490"/'¤ÈÌÀµ­
+ ¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ RamDac "att20c490"
+ Option "dac_8_bit
+ </verb></tscreen>
+
+
+<tag>S3 805, Diamond SS2410 RAMDAC, ICD2061A ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> Diamond Stealth 24 VLB
+ </itemize>
+
+ 8 ¤È 15bpp(*) ¤Î¤ß¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ `<tt/Option "nolinear"/' ¤È¤¤¤¦¥ª¥×¥·¥ç¥ó¤¬É¬ÍפǤ¹¡£
+
+ (*) SS2410 RAMDAC ¤Ï AT&amp;T20C490 ¤È15 bpp ¥â¡¼¥É¤Ç¤Ï¸ß´¹À­¤¬
+ ¤¢¤ë¤³¤È¤¬Êó¹ð¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤½¤Î¥Á¥Ã¥×¤ò AT&amp;T20C490 ¤È¤ß¤Ê
+ ¤·¤Æ¥µ¡¼¥Ð¤òÀ¸À®¤·¤¿¾ì¹ç¡¢<tt/XF86Config/ ¤Ë
+ `<tt/Ramdac "att20c490"/' ¤È½ñ¤¯É¬Íפ¬¤¢¤ê¤Þ¤¹¡£
+
+<tag>S3 801/805, Chrontel 8391 ¥¯¥í¥Ã¥¯¥Á¥Ã¥×/Ramdac</tag>
+ <itemize>
+ <item> JAX 8241
+ <item> SPEA Mirage
+ </itemize>
+
+ 8 ¤È 15/16 bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ 8391 ¤Ï AT&amp;T 20C490 RAMDAC ¤È¸ß´¹À­¤¬¤¢¤ê¤Þ¤¹¡£
+
+ <tscreen><verb>
+ ClockChip "ch8391"
+ Ramdac "ch8391"
+ Option "dac_8_bit"
+ </verb></tscreen>
+
+
+<tag>S3 928, AT&amp;T 20C490 RAMDAC </tag>
+ <itemize>
+ <item> Actix Ultra
+ </itemize>
+
+ 8 ¤È 15/16 bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ Ãí°Õ: ËÜʪ¤Î AT&amp;T20C490 RAMDAC ¤Ï¥µ¡¼¥Ð¤Ç¼«Æ°Ç§¼±½ÐÍè¤Þ¤¹¡£
+ ¤½¤Î¸ß´¹¥Á¥Ã¥×¥»¥Ã¥È¤Î¾ì¹ç¤Ï <tt/XF86Config/ ¤Ë
+ `<tt/Ramdac "att20c490"/'¤ÈÌÀµ­¤·¤Æ¤¯¤À¤µ¤¤¡£
+ ¤Þ¤¿¡¢¥µ¡¼¥Ð¤Î RAMDAC õººÊó¹ð¤¬ÅÁ¤¨¤ë¤È¤³¤í¤Ë¤è¤ì¤Ð´ö¤Ä¤«¤Î
+ ¥Ü¡¼¥É¤ÇÌäÂ꤬À¸¤¸¡¢RamDac ¤ÎÀßÄ꤬õºº¤«¤é̵»ë¤µ¤ì¤Þ¤¹¡£
+
+ ËÜʪ¤Î AT&amp;T 20C490 ¤È 20C491 RAMDAC ¤Ï <tt/"dac_8_bit"/ ¤È¤¤¤¦¥ª¥×¥·¥ç¥ó
+ ¤òÉÕ¤±¤ÆÆ°ºî¤·¤Þ¤¹¡£¡ÊWinbond 82C490 ¤Î¤è¤¦¤Ê¡Ë¤¤¤¯¤Ä¤«¤Î¤½¤Ã¤¯¤ê¤µ
+ ¤ó¤Ë¤Ï¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£
+
+<tag>S3 928, Sierra SC15025 RAMDAC, ICD2061A ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> ELSA Winner 1000 ISA/EISA (``TwinBus'' ¤Ï Winner1000ISA ¤Ç¤Ï¤¢¤ê
+ ¤Þ¤»¤ó!!)
+ <item> ELSA Winner 1000 VL
+ </itemize>
+
+ 8, 15/16 ¤È 24(32) bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ 8bpp ¤Ç¤Ï 8¥Ó¥Ã¥È/¥Ô¥¯¥»¥ë RGB ¤ò¥µ¥Ý¡¼¥È¤·¡¢15/16 ¤È 24bpp ¥â¡¼¥É¤Ç¤Ï
+ ¥¬¥ó¥ÞÊäÀµ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£
+
+ ¥¯¥í¥Ã¥¯¤¬ 30 MHz ¤Î¸Â³¦¶á¤¯¤Ç¤¢¤ë¾ì¹ç¤Ë¡¢ 24 bpp ¤Ç¤Ï ``À㤬¹ß¤Ã¤¿
+ ¤è¤¦¤Ë'' ¤Ê¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£¤³¤ì¤¬´í¸±¤Ç¤¢¤ë¤È¹Í¤¨¤Æ¤Ï¤¤¤Þ¤»¤ó¤¬¡¢
+ 24bpp ¤Î»ÈÍѤǤ­¤ë¾å¸Â¤À¤È»×¤¤¤Þ¤¹¡£
+
+ D-Ãʳ¬ (Ëô¤Ï°Ê¹ß¤Î) ¥Á¥Ã¥×¤Ï 1152 ¥É¥Ã¥È¤Î²èÌÌÉý¤ò»È¤¦¤³¤È¤Ï½ÐÍè¤Ê
+ ¤¤¤Î¤Ç¡¢ 1 MB ¤Î¥Ü¡¼¥É¤Ç¤Î¤â¤Ã¤È¤âÍ­¸ú¤Ê¥â¡¼¥É¤Ï 1088x800x8 ¤Ç¤¹(¤³
+ ¤ì¤Ï 2 MB ¤Î»þ¤Î 1088x800x16 ¤ÈƱÍͤǤ¹¡Ë¡£
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ </verb></tscreen>
+
+
+<tag>S3 928, Bt9485 RAMDAC, ICD2061A ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> STB Pegasus VL
+ </itemize>
+
+ 8, 15/16 ¤È 24(32) bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ <tt/"sync_on_green"/ ¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤Æ¡¢¤«¤Ä BNC ¥³¥Í¥¯¥¿¤Ë½ÐÎϤ¹¤ë¤è¤¦
+ ¤Ë¥Ü¡¼¥É¾å¤Î¥¸¥ã¥ó¥Ñ¥¹¥¤¥Ã¥Á¤òÀßÄꤷ¤¿¾ì¹ç¤Ë¡¢Îп®¹æÆ±´ü¤ò»ÈÍѤ·¤¿
+ RBG ½ÐÎϤò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£
+
+ VLB ¥ê¥Ë¥¢ ¥¢¥É¥ì¥Ã¥·¥ó¥°¤Ï¥¢¥É¥ì¥¹ 0x7FCxxxxx ¤Ç ¥¢¥¯¥»¥¹¤·¤Þ¤¹¤Î¤Ç¡¢
+ 64MB ¤«¤½¤ì°Ê¾å¤Î¥á¥¤¥ó¥á¥â¥ê¤¬¤¢¤ì¤Ð¥ê¥Ë¥¢¥Õ¥ì¡¼¥à¥Ð¥Ã¥Õ¥¡¤ò¼º¤¦»ö
+ ¤Ê¤·¤Ë¥µ¥Ý¡¼¥È½ÐÍè¤Þ¤¹¡£
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ Option "stb_pegasus"
+ </verb></tscreen>
+
+
+<tag>S3 928, Bt485 RAMDAC, SC11412 ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> SPEA Mercury 2MB VL
+ </itemize>
+
+ 8, 15/16 ¤È 24(32) bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ <tscreen><verb>
+ ClockChip "SC11412"
+ Option "SPEA_Mercury"
+ </verb></tscreen>
+
+
+<tag>S3 928, Bt485 RAMDAC, ICD2061A ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> &num;9 GXE Level 10, 11, 12
+ </itemize>
+
+ 8, 15/16 ¤È 24(32) bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ Option "number_nine"
+ </verb></tscreen>
+
+
+<tag>S3 928, Ti3020 RAMDAC, ICD2061A ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> &num;9 GXE Level 14, 16
+ </itemize>
+
+ 8, 15/16 ¤È 24(32) bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ Îп®¹æÆ±´ü¤ò»ÈÍѤ·¤¿ RBG ½ÐÎϤò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ Option "number_nine"
+ </verb></tscreen>
+
+
+<tag>S3 864, AT&amp;T20C498, ICS2494 ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> MIRO 20SD (BIOS 1.xx)
+ </itemize>
+
+ ICS2494 ¤Ï¸ÇÄê¼þÇÈ¿ô¤Î¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤Ç¡¢¡ÊXF86Config ¥Õ¥¡¥¤¥ë¤Ë
+ Clocks ¹Ô¤ò½ñ¤«¤º¤Ë¡ËX -probeonly ¤ò¼Â¹Ô¤¹¤ë¤ÈÀµ¤·¤¤¥¯¥í¥Ã¥¯¤¬ÆÀ¤é¤ì
+ ¤Þ¤¹¡£
+
+ 8, 15/16 ¤È 24(32) bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£
+
+
+<tag>S3 864, AT&amp;T20C498 ¤Þ¤¿¤Ï STG1700 RAMDAC, ICD2061A ¤Þ¤¿¤Ï ICS9161 ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> Elsa Winner1000PRO VLB
+ <item> Elsa Winner1000PRO PCI
+ <item> MIRO 20SD (BIOS 2.xx)
+ <item> Actix GraphicsENGINE 64 VLB/2MB
+ </itemize>
+
+ 8, 15/16 ¤È 24(32) bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ </verb></tscreen>
+
+
+<tag>S3 864, 20C498 or 21C498 RAMDAC, ICS2595 ¥Á¥Ã¥×¥»¥Ã¥È</tag>
+ <itemize>
+ <item> SPEA MirageP64 2MB DRAM (BIOS 3.xx)
+ </itemize>
+
+ 8, 15/16 ¤È 24(32) bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ ¤³¤Î¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤Ï̤¤ÀÃÇÊÒŪ¤Ê¥µ¥Ý¡¼¥È¤Ç¡¢¤«¤Ä´ö¤Ä¤«¤Î¥Þ¥·¥ó¾å¤Ç¤Ï
+ XF86_S3 µ¯Æ°»þ¤Î½é´ü²èÌÌ¡¢¤Þ¤¿¤Ï²¾ÁÛüËö(VT) ¤«¤éÌá¤Ã¤¿Ä¾¸å¤Î²èÌ̤Ë
+ ÌäÂ꤬¤¢¤ê¤Þ¤¹¤¬¡¢ CTRL+ALT+``KP+'' ¤Ç¼¡¤Î¥â¡¼¥É¤ËÀÚ¤êÂØ¤¨¤¿¤ê¡¢Ìá¤Ã
+ ¤¿¤ê¤¹¤ë¾ì¹ç¤ÎÌäÂê¤Ï²ò·èºÑ¤ß¤È»×¤ï¤ì¤Þ¤¹¡£
+
+ ¥¤¥ó¥¿¡¼¥ì¡¼¥¹¥â¡¼¥É¤ÏÀµ¤·¤¯Æ°ºî¤·¤Þ¤»¤ó¡£
+
+ Mirage P64 with BIOS 4.xx ¤Ï S3 SDAC ¤ò»ÈÍѤ·¤Æ¤¤¤Þ¤¹¡£
+
+ <tscreen><verb>
+ ClockChip "ics2595"
+ </verb></tscreen>
+
+
+<tag>S3 864, S3 86C716 SDAC RAMDAC ¤È¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> Elsa Winner1000PRO
+ <item> MIRO 20SD (BIOS 3.xx)
+ <item> SPEA MirageP64 2MB DRAM (BIOS 4.xx)
+ <item> Diamond Stealth 64 DRAM
+ </itemize>
+
+ 8, 15/16 ¤È 24 bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£
+
+
+<tag>S3 864, ICS5342 RAMDAC ¤È ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> Diamond Stealth 64 DRAM (Ʊ¤¸¥«¡¼¥É¤Î¤ß)
+ </itemize>
+
+ 8, 15/16 ¤È 24 bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ <tscreen><verb>
+ ClockChip "ics5342"
+ Ramdac "ics5342"
+ </verb></tscreen>
+
+
+<tag>S3 864, AT&amp;T21C498-13 RAMDAC, ICD2061A ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> &num;9 GXE64 - PCI
+ </itemize>
+
+ 8, 15/16, 24(32) bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ Option "number_nine"
+ </verb></tscreen>
+
+
+<tag>S3 964, AT&amp;T 20C505 RAMDAC, ICD2061A ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> Miro Crystal 20SV
+ </itemize>
+
+ 8, 15/16, 24(32) bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ Ramdac "att20c505"
+ </verb></tscreen>
+
+
+<tag>S3 964, Bt485 RAMDAC, ICD2061A ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> Diamond Stealth 64
+ </itemize>
+
+ 8, 15/16, 24(32) bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ </verb></tscreen>
+
+
+<tag>S3 964, Bt9485 or AT&amp;T 20C505 RAMDAC, ICS9161a ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> SPEA Mercury 64
+ </itemize>
+
+ 8, 15/16, 24(32) bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ <tscreen><verb>
+ ClockChip "ics9161a"
+ Option "SPEA_Mercury"
+ </verb></tscreen>
+
+
+<tag>S3 964, Ti3020 RAMDAC, ICD2061A ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> Elsa Winner2000PRO PCI
+ </itemize>
+
+ 8, 15/16, 24(32) bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ </verb></tscreen>
+
+
+<tag>S3 964, Ti3025 RAMDAC, Ti3025 ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> Miro Crystal 40SV
+ <item> &num;9 GXE64 Pro VLB
+ <item> &num;9 GXE64 Pro PCI
+ </itemize>
+
+ 8 bpp, 15, 16 ¤È 24(32) bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ GXE64 Pro ¤Ç 15/16/24 bpp ¤Î¾ì¹ç¤Ë²èÁü¤¬ÊФ俤ê/²ó¤ê¹þ¤ó¤À¤ê¤¹¤ëÅù¡¢
+ ´ö¤Ä¤«¤ÎÌäÂêÅÀ¤¬¤ï¤«¤Ã¤Æ¤¤¤Þ¤¹¡£
+
+ ´û¤Ë &num;9 ¤¬ 1600x1200 ¤ò GXE64 Pro ¤Ç¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤»ö¤òÃΤäƤ¤¤Þ
+ ¤¹¡£¤±¤ì¤É¤â¾¤Î¥Ü¡¼¥É¤Ç 135MHz ¤Ç ¤¢¤ë RAMDAC ¤ò 220MHz ¤Î RAMDAC
+ ¤ËÃÖ¤­´¹¤¨¤¿ GXE64Pro-1600 ¤È¸Æ¤Ð¤ì¤ë¿·¤·¤¤¡Ê¤½¤·¤Æ¤è¤ê¹â²Á¤Ê¡Ë¥Ü¡¼
+ ¥É¤ò³«È¯¤·¤Æ¤¤¤Þ¤¹¡£
+
+
+<tag>S3 764 (Trio64)</tag>
+ <itemize>
+ <item> SPEA Mirage P64 (BIOS 5.xx)
+ <item> Diamond Stealth 64 DRAM
+ <item> &num;9 GXE64 Trio64
+ </itemize>
+
+ 8/15/16/24 bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£
+
+ Ãí°Õ: Trio64 ¤Ï RAMDAC ¤È ¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤òÆâ¢¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¥µ¡¼¥Ð
+ ¤ÏÁ´¤Æ¤Î Trio64 ¤Çưºî¤¹¤ë¤Ç¤·¤ç¤¦¡£¤À¤«¤é <tt/XF86Config/ ¥Õ¥¡¥¤¥ë¤Ë
+ RAMDAC ¤È ¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤Ï»ØÄꤹ¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£
+
+
+<tag>S3 732 (Trio32)</tag>
+ <itemize>
+ <item> Diamond Stealth 64 DRAM SE
+ </itemize>
+
+ 8/15/16/24 bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ Ãí°Õ: Trio32 ¤Ï RAMDAC ¤È ¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤òÆâ¢¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¥µ¡¼¥Ð
+ ¤ÏÁ´¤Æ¤Î Trio32 ¤Çưºî¤¹¤ë¤Ç¤·¤ç¤¦¡£¤À¤«¤é <tt/XF86Config/ ¥Õ¥¡¥¤¥ë¤Ë
+ RAMDAC ¤È ¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤Ï»ØÄꤹ¤ëɬÍפϤ¢¤ê¤Þ¤»¤ó¡£
+
+
+<tag>S3 868, S3 86C716 SDAC RAMDAC ¤È ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> ELSA Winner 1000AVI
+ <item> Diamond Stealth Video DRAM
+ </itemize>
+
+ 8/15/16/24 bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£
+
+<tag>S3 868, AT&amp;T 20C409 RAMDAC ¤È ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> ELSA Winner 1000AVI
+ </itemize>
+
+ 8/15/16/24 bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£
+
+<!--
+ Note: pixelmultiplexing is not supported yet, therefore limited
+ maximum dot clock for 8bpp (currently 67.5MHz, should be changed
+ to 100MHz if pixmux isn't fixed prior to release)
+-->
+ Ãí°Õ: ¥Ô¥¯¥»¥ë¿½Å²½¤Ï̤¤À¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó¡£½¾¤Ã¤Æ 8bpp ¤Ç¤ÎºÇÂç
+ ¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ÏÀ©¸Â¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ºÇÂç¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ï¸½ºß¡¢ 67.5MHz
+ ¤Ç¤¹¤¬¡¢pixmux ¤Î½¤Àµ¤¬¸ø³«¤è¤ê¤âÍ¥À褵¤ì¤Ê¤¤¤È¡¢Êѹ¹¤·¤¿¤È¤³¤í¤Ç
+ 100MHz Ëø¤Ç¤·¤ç¤¦¡£
+
+<tag>S3 968, Ti3026 RAMDAC, Ti3026 ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> Elsa Winner 2000PRO/X-2 ¤È /X-4 (²þÊÑ F °Ê¾å)
+ <item> Elsa Winner 2000AVI-2 ¤È -4
+ <item> Diamond Stealth 64 VIDEO VRAM
+ </itemize>
+
+ 8/15/16/24 bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£
+
+<tag>S3 968, Ti3026 RAMDAC, ICS9161A ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> Elsa Winner 2000PRO/X-2 ¤È /X-4 (²þÊÑ G)
+ </itemize>
+
+ 8/15/16/24 bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£
+
+<!--
+ Note: clock doubling doesn't work, yet, therefore the maximum
+ usable dot clock is limited to about 120MHz.
+-->
+ Ãí°Õ: ÇÜ¥¯¥í¥Ã¥¯µ¡Ç½¤Ï̤¤Àưºî¤·¤Þ¤»¤ó¤¬¡¢ºÇ¹â¥É¥Ã¥È¥¯¥í¥Ã¥¯
+ ¤Î¾å¸Â¤Ï 120MHz ÄøÅ٤ޤǻÈÍѽÐÍè¤Þ¤¹¡£
+
+<tag>S3 964, IBM RGB 514/524/525/528 RAMDAC &amp; ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> Hercules Graphics Terminator 64
+ </itemize>
+
+ 8/15/16/24 bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ <tscreen><verb>
+ s3RefClk 50
+ DACspeed 170
+ Option "slow_vram"
+ </verb></tscreen>
+
+<tag>S3 968, IBM RGB 514/524/525/528 RAMDAC &amp; ¥¯¥í¥Ã¥¯¥Á¥Ã¥×</tag>
+ <itemize>
+ <item> Genoa Genoa VideoBlitz III AV
+ <tscreen><verb>
+ s3RefClk 50
+ DACspeed 170
+ </verb></tscreen>
+ <item> Hercules Graphics Terminator Pro 64
+ <tscreen><verb>
+ s3RefClk 16
+ DACspeed 220
+ </verb></tscreen>
+ ¤³¤Î¥«¡¼¥É¤Ë¤Ï¼¡¤Î¹Ô¤òÌÀµ­¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£:
+ <tscreen><verb>
+ Invert_VCLK "*" 0
+ </verb></tscreen>
+ ¤³¤ì¤ò³Æ¡¹¤Î Display ¥µ¥Ö¥»¥¯¥·¥ç¥ó¤ËÌÀµ­¤·¤Æ¤¯¤À¤µ¤¤¡£
+ <item> STB Velocity 64
+ <tscreen><verb>
+ s3RefClk 24
+ DACspeed 220
+ </verb></tscreen>
+ <item> Number Nine FX Motion 771
+ <tscreen><verb>
+ s3RefClk 16
+ DACspeed 220
+ </verb></tscreen>
+ ¤³¤Î¥«¡¼¥É¤Ë¤Ï¼¡¤Î¹Ô¤òÌÀµ­¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£:
+ <tscreen><verb>
+ Invert_VCLK "*" 0
+ </verb></tscreen>
+ ¤³¤ì¤ò³Æ¡¹¤Î Display ¥µ¥Ö¥»¥¯¥·¥ç¥ó¤ËÌÀµ­¤·¤Æ¤¯¤À¤µ¤¤¡£
+ </itemize>
+
+ 8/15/16/24 bpp ¤¬ÍøÍѲÄǽ¤Ç¤¹¡£¼¡¤Î¤è¤¦¤ËÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+</descrip>
+
+<sect> 16bpp ¤È 32bpp
+<p>
+
+¡ÊFarenheit 1280+ VLB ¤Î¤è¤¦¤Ê¡Ë 801/805 ¤È AT&amp;T490 ¤Î¥«¡¼¥É¤Ç¤Ï 15 ¤È
+16bpp ¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£¤³¤Î·ÏÎó¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ç¤Ï 32bpp ¤ò»ÈÍѤǤ­¤Þ
+¤»¤ó¡£
+¡ÊMS Windows ¤Ç¤Ï 24 ¥Ó¥Ã¥È¥â¡¼¥É¤ò»È¤Ã¤Æ¤¤¤Þ¤¹¤¬¡¢¤³¤ì¤Ï 32bpp ¤Î¿§¿ô¤ò¾¯
+¤Ê¤¯¤·¤¿ (sparse) ¥â¡¼¥É¤Ç¤Ï¤Ê¤¯¡¢ËÜÅö¤Ë 3 ¥Ð¥¤¥È/¥Ô¥¯¥»¥ë¤òÍѤ¤¤¿¥â¡¼¥É¤Ç
+¤¹¡£¤³¤Î¥â¡¼¥É¤ò XFree86 ¤Ç¼ÂÁõ¤¹¤ë¤Î¤ÏÍÆ°×¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¡Ë
+
+<sect>¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¥Á¥Ã¥×¥»¥Ã¥È¤Î°ìÍ÷
+<p>
+
+<tscreen><verb>
+ICD2061A ==> ClockChip "icd2061a"
+ICS9161A (ICD2061A ¸ß´¹) ==> ClockChip "ics9161a"
+DCS2824-0 (Diamond, ICD2061A ¸ß´¹) ==> ClockChip "dcs2824"
+
+S3 86c708 GENDAC ==> ClockChip "s3gendac"
+ICS5300 GENDAC (86c708 ¸ß´¹) ==> ClockChip "ics5300"
+
+S3 86c716 SDAC ==> ClockChip "s3_sdac"
+ICS5342 GENDAC ==> ClockChip "ics5342"
+STG 1703 ==> ClockChip "stg1703"
+
+Sierra SC11412 ==> ClockChip "sc11412"
+ICS2595 ==> ClockChip "ics2595"
+TI3025 ==> ClockChip "ti3025"
+TI3026 ==> ClockChip "ti3026"
+IBM RGB 5xx ==> ClockChip "ibm_rgb5xx"
+
+Chrontel 8391 ==> ClockChip "ch8391"
+
+AT&amp;T 20C409 ==> ClockChip "att20c409"
+AT&amp;T 20C499 (̤¥Æ¥¹¥È) ==> ClockChip "att20c499"
+</verb></tscreen>
+
+<!--
+<sect>List of Supported RAMDAC Chips
+<p>
+If you have a RAMDAC that is not listed here, be VERY careful not to
+overdrive it using XF86_S3. Better contact the XFree86 team first to
+verify that running XF86_S3 will not damage your board.
+
+RAMDACs that are grouped together below are treated as compatible
+with each other as far as the server is concerned. For example, the
+server will report <tt>"bt485"</tt> when you actually specify
+<tt>RAMDAC "bt9485"</tt>, or <tt>"s3_gendac"</tt> when you specify
+<tt>RAMDAC "ics5300"</tt>.
+
+<tscreen><verb>
+ATT20C409 ==> RAMDAC "att20c409"
+
+ATT20C490 ==> RAMDAC "att20c490"
+ATT20C491 ==> RAMDAC "att20c491"
+CH8391 ==> RAMDAC "ch8391"
+
+ATT20C498 ==> RAMDAC "att20c498"
+ATT21C498 ==> RAMDAC "att21c498"
+
+ATT22C498 ==> RAMDAC "att22c498"
+
+ATT20C505 ==> RAMDAC "att20c505"
+
+BT485 ==> RAMDAC "bt485"
+BT9485 ==> RAMDAC "bt9485"
+
+IBMRGB514 ==> RAMDAC "ibm_rgb514"
+IBMRGB525 ==> RAMDAC "ibm_rgb525"
+
+IBMRGB524 ==> RAMDAC "ibm_rgb524"
+IBMRGB526 ==> RAMDAC "ibm_rgb526"
+
+IBMRGB528 ==> RAMDAC "ibm_rgb528"
+
+S3_GENDAC ==> RAMDAC "s3gendac"
+ICS5300 ==> RAMDAC "ics5300"
+
+S3_SDAC ==> RAMDAC "s3_sdac"
+ICS5342 ==> RAMDAC "ics5342"
+
+S3_TRIO32 ==> RAMDAC "s3_trio32"
+
+S3_TRIO64 ==> RAMDAC "s3_trio64"
+S3_TRIO64 ==> RAMDAC "s3_trio"
+
+SC11482 ==> RAMDAC "sc11482"
+SC11483 ==> RAMDAC "sc11483"
+SC11484 ==> RAMDAC "sc11484"
+
+SC11485 ==> RAMDAC "sc11485"
+SC11487 ==> RAMDAC "sc11487"
+SC11489 ==> RAMDAC "sc11489"
+
+SC15025 ==> RAMDAC "sc15025"
+
+STG1700 ==> RAMDAC "stg1700"
+
+STG1703 ==> RAMDAC "stg1703"
+
+TI3020 ==> RAMDAC "ti3020"
+
+TI3025 ==> RAMDAC "ti3025"
+
+TI3026 ==> RAMDAC "ti3026"
+
+None of the above ==> RAMDAC "normal"
+</verb></tscreen>
+
+If you feel adventurous you could also open up your computer and have
+a peek at your RAMDAC. The RAMDAC is usually one of the larger chips
+(second or third largest chip that is NOT an EPROM) on the board. The
+markings on it are usually
+
+<tscreen><verb>
+ <Company logo>
+
+ <company identifier><part number>-<speed grade>
+ <manufacturing week><manufacturing year>
+ <lot number><other funny numbers>
+</verb></tscreen>
+
+For example:
+
+<tscreen><verb>
+ @@
+ @@ AT&amp;T
+
+ ATT20C490-11
+ 9339S ES
+ 9869874
+</verb></tscreen>
+
+This is an AT&amp;T 20C490 with a speed grade of 110 MHz. This would then mean
+that you put a `<tt/DacSpeed 110/' line in your <tt/XF86Config/ file. Be
+advised that some RAMDACs have different modes that have different
+limits. The manufacturer will always mark the chip naming the higher
+limits, so you should be careful. The S3 server knows how to handle
+the limits for most of the RAMDACs it supports providing the DacSpeed
+is specified correctly.
+
+
+Chips labeled <bf/-80/ or <bf/-8/ should use `<tt/DacSpeed 80/' in
+the device section.
+<tscreen><verb>
+S3 86C716-ME SDAC ==> DacSpeed 110
+SC15025-8 ==> DacSpeed 80
+ATT20C490-80 ==> DacSpeed 80
+
+IBM 8190429 ==> DacSpeed 170
+IBM 03H5428 ==> DacSpeed 170
+IBM 03H6447 ==> DacSpeed 170
+IBM 03H6448 ==> DacSpeed 220
+IBM 03H5319 ==> DacSpeed 220
+IBM 63G9902 ==> DacSpeed 250
+
+IBM 37RGB514CF17 ==> DacSpeed 170
+IBM 37RGB524CF22 ==> DacSpeed 220
+ ^^
+</verb></tscreen>
+-->
+<sect> ÄɲÃÃí°Õ»ö¹à
+<p>
+¤³¤Î°ìÍ÷¤Ëµ­ºÜ¤µ¤ì¤Æ¤¤¤Ê¤¤ RAMDAC ¤ò»ý¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢XF86_S3 ¤ò»ÈÍѤ¹¤ëºÝ
+RAMDAC ¤Î¼þÇÈ¿ô¤ò¾å¤²²á¤®¤Ê¤¤¤è¤¦¤Ë½½Ê¬Ãí°Õ¤·¤Æ²¼¤µ¤¤¡£XF86_S3 ¤¬¥Ü¡¼¥É¤ò
+Äˤá¤Ê¤¤¤è¤¦¤Ë¡¢À褺 XFree86 ¥Á¡¼¥à¤Ë³Îǧ¤ÎÏ¢Íí¤ò¼è¤Ã¤¿¤Û¤¦¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£
+
+ËÁ¸±¤·¤è¤¦¤È»×¤¦¤Ê¤é¡¢¥³¥ó¥Ô¥å¡¼¥¿¡¼¤Î³¸¤ò³«¤±¤Æ RAMDAC ¤òÇÁ¤¤¤Æ¤ß¤Æ²¼¤µ¤¤¡£
+RAMDAC ¤ÏÉáḀ̈ӥǥª¥Ü¡¼¥É¾å¤ÇÂ礭¤¤¥Á¥Ã¥×¡Ê£²ÈÖÌܤ«£³ÈÖÌܤËÂ礭¤¤¥Á¥Ã¥×¤Ï
+EPROM ¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡Ë¤Ç¤¹¡£Ä̾¤½¤³¤Ë¤Ï¼¡¤Î¤è¤¦¤Ë½ñ¤«¤ì¤Æ¤¤¤Þ¤¹¡£
+
+<tscreen><verb>
+ <²ñ¼Ò¤Î¥í¥´>
+
+ <²ñ¼Ò¤Î¼±ÊÌ»Ò><ÉôÉÊÈÖ¹æ>-<¼þÇÈ¿ô¤Î¾Êά·Á>
+ <À½Â¤½µ><À½Â¤Ç¯>
+ <¥í¥Ã¥ÈÈÖ¹æ><¤½¤Î¾¤Î°ÕÌ£ÉÔÌÀ¤Ê¿ô»ú>
+</verb></tscreen>
+
+Î㤨¤Ð:
+
+<tscreen><verb>
+ @@
+ @@ AT&amp;T
+
+ ATT20C490-11
+ 9339S ES
+ 9869874
+</verb></tscreen>
+
+¤³¤ì¤Ïưºî¼þÇÈ¿ô 110 MHz ¤Î AT&amp;T 20C490 ¤Ç¤¹¡£¤³¤Î»ö¤Ï <tt/XF86Config/ ¥Õ¥¡¥¤¥ë
+¤Ë `<tt/DacSpeed 110/' ¤Èµ­Æþ¤¹¤ë¤³¤È¤ò»Ø¤·¤Æ¤¤¤Þ¤¹¡£´ö¤Ä¤«¤Î RAMDAC ¤Ï¤½¤ì¤¾¤ì
+¤Î¥â¡¼¥É¤Ë¤è¤Ã¤Æ°Û¤Ê¤ë¼þÇÈ¿ô¤Î¾å¸Â¤ò»ý¤Ã¤Æ¤¤¤ë»ö¤òÎɤ¯¹Í¤¨¤Æ²¼¤µ¤¤¡£À½Â¤²ñ
+¼Ò¤Ï¤¤¤Ä¤â¤½¤Î¥Á¥Ã¥×¤Î»ý¤Æ¤ëºÇ¹âÀ­Ç½¤Î¼þÇÈ¿ô¤ò̾Á°¤ËÉÕ¤±¤ë¤Î¤Ç¡¢½½Ê¬Ãí°Õ¤·
+¤Æ²¼¤µ¤¤¡£S3 ¥µ¡¼¥Ð¤ÏÀµ¤·¤¯»ØÄꤵ¤ì¤¿ DacSpeed ¤ÎÃͤòÍѤ¤¤ÆËؤɤÎ
+RAMDAC ¤Î¼þÇÈ¿ô¤Î¾å¸Â¤ò¤É¤Î¤è¤¦¤Ë°·¤¨¤ÐÎɤ¤¤«¤òÃΤäƤ¤¤Þ¤¹¡£
+
+
+chips labeled <bf/-80/ or <bf/-8/ should use `<tt/DacSpeed 80/' in
+the device section
+¥Á¥Ã¥×¤Ë <bf/-80/ ¤Þ¤¿¤Ï <bf/-8/ ¤È¤«ÉÕ¤¤¤Æ¤¤¤¿¤é¡¢¥Ç¥Ð¥¤¥¹Àá¤Ë `<tt/DacSpeed 80/' ¤È
+ÌÀµ­¤¹¤ë¤Ù¤­¤Ç¤·¤ç¤¦¡£
+<tscreen><verb>
+S3 86C716-ME SDAC ==> DacSpeed 110
+SC15025-8 ==> DacSpeed 80
+ATT20C490-80 ==> DacSpeed 80
+
+IBM 8190429 ==> DacSpeed 170
+IBM 03H5428 ==> DacSpeed 170
+IBM 03H6447 ==> DacSpeed 170
+IBM 03H6448 ==> DacSpeed 220
+IBM 03H5319 ==> DacSpeed 220
+IBM 63G9902 ==> DacSpeed 250
+
+IBM 37RGB514CF17 ==> DacSpeed 170
+IBM 37RGB524CF22 ==> DacSpeed 220
+ ^^
+</verb></tscreen>
+
+¡ÊTi3025 ¤Î¤è¤¦¤Ê¡Ë´ö¤Ä¤«¤Î RAMDAC ¤Ï¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½¥ë¤¬Àµ¤·¤¯Æ°ºî¤¹¤ë
+¤è¤¦¤Ë´ö¤Ä¤«¤Î¥â¡¼¥É¤ÎÄ´À°¤ËÇÛθ¤¬É¬ÍפǤ¹¡£Ti3025 ¤ÏºÇÄã 80 ¥Ô¥¯¥»¥ëʬ¤Î
+;͵¤¬É¬ÍפǤ¹¡£ÀßÄ꤬Îɤ¯¤Ê¤«¤Ã¤¿¤È¤­¤Î¾É¾õ¤Ï²èÌ̤α¦Ã¼¤Ë¶á¤¤¤È¤³¤í¤Ø¥Ï¡¼
+¥É¥¦¥§¥¢¥«¡¼¥½¥ë¤ò¶áÉÕ¤±¤ë¤È¾Ã¤¨¤ë¤è¤¦¤Ë¤Ê¤ë¤³¤È¤Ç¤¹¡£
+
+
+<sect> IBM RGB 5xx RAMDAC ¤Î¥¯¥í¥Ã¥¯Ãͤò»²¾È¤¹¤ë¤Ë¤Ï
+<p>
+
+IBM RGB5xx RAMDAC ¤òÅëºÜ¤·¤Æ¤¤¤ë¥«¡¼¥É¤Ï¡¢¥Æ¥­¥¹¥È¥â¡¼¥É¤Î¥¯¥í¥Ã¥¯¤Î¾ðÊó¤ò½ü
+¤¤¤ÆÃµºº¤¹¤ë¤³¤È¤¬½ÐÍè¤Ê¤¤¥¯¥í¥Ã¥¯¥·¥ó¥»¥µ¥¤¥¶¡¼¤Ë¤¤¤¯¤Ä¤«°Û¤Ê¤ë¼þÇÈ¿ô¤òÍ¿
+¤¨¤ÆÆ°ºî¤·¤Þ¤¹¡Êɸ½à¤Ç¤Ê¤¤¥Æ¥­¥¹¥È¥â¡¼¥É¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ë´Ö°ã¤Ã¤¿²¾Äê¤ò¤¹
+¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡Ë¡£¼¡¤ËÆþÎϼþÇÈ¿ô¤òõ¤¹¼ê½ç¤ò¼¨¤·¤Þ¤¹¡£:
+
+À褺¼¡¤ò¼Â¹Ô¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+<tscreen><verb>
+ X -probeonly >& outfile
+</verb></tscreen>
+
+¤½¤·¤Æ¥¯¥í¥Ã¥¯¥Á¥Ã¥×¤Îõºº·ë²Ì¤Î outfile ¤Ë¼¡¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤ë»ö¤ò³Îǧ
+¤·¤Æ¤¯¤À¤µ¤¤¡£:
+
+<tscreen><verb>
+(--) S3: Using IBM RGB52x programmable clock (MCLK 66.000 MHz)
+(--) S3: with refclock 16.000 MHz (probed 15.952 & 16.041)
+ ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
+</verb></tscreen>
+
+»ÈÍѤ¹¤ë¼þÇÈ¿ô¤È³ç¸Ì¤ÎÃæ¤ÎÆó¤Ä¤Îõºº¤·¤¿¼þÇÈ¿ô¤Ï 25MHz ¤È 28MHz ¤Î¥Æ¥­¥¹¥È
+¥â¡¼¥É¤Î¥¯¥í¥Ã¥¯¤ò´ð½à¤È¤·¤¿ "Îɤ¤Í½ÁÛ¤Î" ÃͤǤ·¤ç¤¦¡£ÉáÄ̤Π80x25 ¤Þ¤¿¤Ï
+80x28 ¤Î¥Æ¥­¥¹¥È¥â¡¼¥É¤Ç¼Â¹Ô¤·¤¿¾ì¹ç¤Î¤ß¡¢¤³¤Îõºº¤Ïưºî²Äǽ¤Ç¤¹¡ª¡£
+
+»²¾È¼þÇÈ¿ô¤ÎÃͤÏÂçÂμ¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹:
+
+<verb>
+ STB Velocity 64 24 Mhz
+ Genoa VideoBlitz II AV 50 MHz
+ Hercules S3 964 50 MHz
+ Hercules S3 968 16 MHz
+ #9 Motion 771 16 MHz
+</verb>
+
+ ¤³¤ì¤é¤ÎÃͤϥ«¡¼¥É¤Î¿å¾½È¯¿¶»Ò¤È¿ʬ Genoa ¥«¡¼¥É¤ËÅëºÜ¤µ¤ì¤Æ¤¤¤ë¡Ê14.3
+ MHz ¤Î¡ËÄɲ寥í¥Ã¥¯¥Á¥Ã¥×Åù¤ÎÍͤʾ¤Îµ¡Ç½¤Ë°Í¸¤·¤Þ¤¹¡£
+
+ 16MHz ¤Î¥«¡¼¥É¤¬ 50MHz ¤ò¼ÂºÝ¤Ë»È¤¦»ö¤Ë¤Ê¤ë¤Î¤Ï¡¢Á´¤Æ¤Î¥Ô¥¯¥»¥ë¥¯¥í¥Ã¥¯
+ ¤Ï¥«¡¼¥É¤Î¼þÇÈ¿ô¤Î»°Çܤˤʤ뤫¤é¤Ç 25MHz ¤Î 640x480 ¥â¡¼¥É¤Ç¤Ï 75MHz ¤Î¥Ô
+ ¥¯¥»¥ë¥¯¥í¥Ã¥¯¤Ë¤Ê¤ê¤Þ¤¹¤Î¤Ç½½Ê¬Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+ Àµ¤·¤¤»²¾È¼þÇÈ¿ô¤¬¸«¤Ä¤«¤Ã¤¿¤é¡¢ÀßÄê¥Õ¥¡¥¤¥ë¡Ê¤Î device Àá¤Ë¡Ë¤ËÆþ¤ì¤Þ¤·¤ç
+ ¤¦¡£Î㤨¤Ð¼¡¤Î¤è¤¦¤ËÆþ¤ì¤Æ¤¯¤À¤µ¤¤¡£
+
+ <tscreen><verb>
+ s3RefClk 16
+ </verb></tscreen>
+¤Þ¤¿¤Ï
+ <tscreen><verb>
+ s3RefClk 50
+ </verb></tscreen>
+
+¤³¤ÎÃͤˤĤ¤¤Æ¡¢Â¾¤Î¥Æ¥­¥¹¥È¥â¡¼¥É¤ò»È¤Ã¤Æ¤¤¤ÆÃµºº¤Ë¼ºÇÔ¤·¤Æ¤¤¤ë¤È¤­¤Ï¡¢¤³
+¤Î¸Â¤ê¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡ª¡£
+
+
+
+
+<sect> ¥°¥é¥Õ¥£¥Ã¥¯²èÌÌÁàºî»þ¡¢``À㤬¹ß¤ë'' ¸½¾Ý¤Î²óÈòºö
+<p>
+
+S3 Vision864 ¥Á¥Ã¥×ÅëºÜ¤Î¥«¡¼¥É¤Ç¤Ï¡¢¥Ô¥¯¥»¥ë¥¯¥í¥Ã¥¯¤È S3 ¥Á¥Ã¥×¤òÁàºî¤¹
+¤ë¥á¥â¥ê¥¯¥í¥Ã¥¯ MCLK ¤Ë°Í¸¤·¤¿¼«Æ°ÄûÀµµ¡Ç½¤¬¤¢¤ê¤Þ¤¹¡£ËؤɤΥ¯¥í¥Ã¥¯¥Á¥Ã
+¥×¤Ç¤Ï¥¯¥í¥Ã¥¯¤ÎÆÉ¤ß½Ð¤·¤Ï½ÐÍè¤Þ¤»¤ó¡ÊÀΤ«¤é S3 SDAC ¤À¤±¤Ï ¥á¥â¥ê¥¯¥í¥Ã¥¯
+¤ÎÃͤòÆÉ¤ß½Ð¤»¤Þ¤·¤¿¡Ë¤Î¤Ç¡¢¤³¤ÎÃͤϿäÄꤹ¤ë¤«¥æ¡¼¥¶¡¼¤¬»ØÄꤷ¤Æ¤¤¤Þ¤·¤¿
+¡Ê½é´üÃÍ¤Ï 60 &lsqb;MHz&rsqb;¡Ë¡£
+
+XF86Config ¥Õ¥¡¥¤¥ë¤Ø¿·¤·¤¤ `<tt/s3MCLK/' ¤ÎÀßÄê¤ò¤¹¤ë¤Ê¤é¡¢¼¡¤ÎÎã¤Î¤è¤¦¤Ë¤·¤Þ
+¤·¤ç¤¦¡£
+With the new `<tt/s3MCLK/' entry for your <tt/XF86Config/ file now you can
+specify e.g.
+
+ <tscreen><verb>
+ s3MCLK 55
+ </verb></tscreen>
+
+55 MHz ¤Ë¥á¥â¥ê¥¯¥í¥Ã¥¯¤òÀßÄꤹ¤ë¤ÈÀã¤ÎÎ̤¬¸º¤ë¤Ç¤·¤ç¤¦¡£¤è¤ê¾®¤µ¤¤¥á¥â¥ê
+¥¯¥í¥Ã¥¯¤ÏÀ­Ç½¤ò¼ã´³Íî¤È¤·¤Þ¤¹¤Î¤Ç¡¢Ä㤹¤®¤ëÃͤϻÈÍѤ·¤Ê¤¤¤Ç²¼¤µ¤¤¡ÊËØ¤É¤Î
+¾ì¹ç 55 ¤« 50 ÄøÅÙ¤ÎÃͤ¬Îɤ¤¤È»×¤¤¤Þ¤¹¡Ë¡£
+
+¼¡¤Ï¥á¥â¥ê¥¯¥í¥Ã¥¯¤Î³µ»»ÃÍ¡ÊÌó +/- 1 ¤«¤é 2 MHz ¤Î¸íº¹¤¬¤¢¤ê¤Þ¤¹¡Ë¤ò·è¤á¤ë
+¤Î¤ËÍ­¸ú¤Ê¾®¤µ¤Ê¥·¥§¥ë¥¹¥¯¥ê¥×¥È¤Ç¤¹¡£¤³¤Î¥¹¥¯¥ê¥×¥È¤ò¼Â¹Ô¤¹¤ëÁ°¤Ë¼¡¤Î¹Ô
+
+ <tscreen><verb>
+ s3MNadjust -31 255
+ </verb></tscreen>
+
+¤ò <tt/XF86Config/ ¥Õ¥¡¥¤¥ë¤Î¥Ç¥Ð¥¤¥¹Àá¤ËÄɲä· X ¥¦¥£¥ó¥É¥¦¤òºÆ»Ïư¤¹¤ëɬÍפ¬
+¤¢¤ê¤Þ¤¹¡£
+¤³¤Î¡Ê¥Æ¥¹¥È¤È¥Ç¥Ð¥Ã¥°ÀìÍѤΡ˥ª¥×¥·¥ç¥ó¤ÇÈá»´¤Êɽ¼¨¤Î¤Á¤é¤Ä¤­¤È¹ßÀã¤òÂô»³
+¸«¤ë¤Ç¤·¤ç¤¦¤¬¡¢°Ê¹ß¤Î¥Æ¥¹¥È¥¹¥¯¥ê¥×¥È¤ò¼Â¹Ô¤¹¤ì¤Ðľ¤Á¤ËºÆ¤Ó¼è¤ê½ü¤¯¤³¤È¤¬
+½ÐÍè¤Þ¤¹¡£
+
+¤³¤Î¥¹¥¯¥ê¥×¥È¤Ï xbench ¤«¤Ä/Ëô¤Ï x11perf ¤ò¼Â¹Ô¤·¤Æ¥á¥â¥ê¥¯¥í¥Ã¥¯ ¤ò MHz
+ñ°Ì¤Çɽ¼¨¤··èÄꤹ¤ë¸¡ºº¤ò¹Ô¤¤¤Þ¤¹¡£4 ¤Ä°Ê¾å¤Î¥Æ¥¹¥È¤ò¼Â¹Ô¤·¤¿¤é¡¢4 ¤Ä°Ê¾å
+¤Î¿äÄêÃ͡ʺǽé¤Î¿äÄêÃͤ¬°ìÈÖÀµ³Î¤Ç¤·¤ç¤¦¡Ë¤ò¸«¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡£
+
+<code>
+#!/bin/sh
+
+exec 2> /dev/null
+
+scale=2
+
+calc() {
+ m=`awk 'BEGIN{printf "%.'$scale'f\n",'"( $1 + $2 ) / $3; exit}" `
+ [ -z "$m" ] && m=` echo "scale=$scale; ( $1 + $2 ) / $3" | bc `
+ [ -z "$m" ] && m=` echo "$scale $1 $2 + $3 / pq" | dc `
+ echo $m
+}
+
+run_xbench() {
+ r=` ( echo 1; echo 2; echo 3; echo 4 ) | xbench -only $1 | grep rate `
+ [ -z "$r" ] && return
+ cp="$2 $3"
+ set $r
+ calc $3 $cp
+}
+
+run_x11perf() {
+ r=` x11perf $1 | grep trep | tr '(/)' ' ' `
+ [ -z "$r" ] && return
+ cp="$2 $3"
+ set $r
+ calc `calc 1000 0 $4` $cp
+}
+
+run_x11perf "-rect500 -rop GXxor" 3.86 5.53 # 0 1 # 4.11 5.52 #
+run_xbench invrects500 4.63 5.48 # 0 1 # 4.69 5.48 #
+
+run_x11perf "-rect500 -rop GXcopy" -16.42 13.90 # 0 1 # -14.99 13.88 #
+run_xbench fillrects500 -7.81 13.57 # 0 1 # -8.53 13.58 #
+
+exit
+</code>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/S3.sgml,v 3.2 1997/01/26 04:34:25 dawes Exp $
+</verb>
+<hrule>
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ï xc/programs/Xserver/hw/xfree86/
+doc/sgml/S3.sgml,v 3.26 1995/07/30 04:15:58 ¤ò¡¢²¬ËÜ °ì¹¬
+( Kazuyuki Okamoto <url url="mailto:ikko-@pacific.rim.or.jp"
+name="&lt;ikko-@pacific.rim.or.jp&gt;"> ) ¤¬ XFree86 3.1.2 ¤ò
+ÆüËܤǥ¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¿Í¸þ¤±¤ËÏÂÌõ¤·¤¿¤â¤Î¤Ç¤¹¡£¤³¤³¤¬¤ª¤«¤·¤¤¤È¤«¡¢
+¤³¤³¤Ï¤³¤¦¤·¤¿¤Û¤¦¤¬¤¤¤¤¤È¤¤¤Ã¤¿¤´°Õ¸«¤¬¤¢¤ê¤Þ¤·¤¿¤é¡¢ÅŻҥ᡼¥ë¤Ç
+¤ªÃΤ餻²¼¤µ¤¤¡£
+¸¶Ê¸¤ÎÃøºî¸¢¤Ï XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ÎÏÂÌõ¤ÎÃøºî¸¢¤Ï
+XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤È²¬ËÜ¡¡°ì¹¬¤Ë¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤ÎÏÂÌõ¤ÎÉÔ¶ñ¹ç¤Ï»ä¤Ë¡¢
+ÅŻҥ᡼¥ë¤ÇÁ÷¤Ã¤Æ²¼¤µ¤¤¡£
+
+<hrule>
+&lsqb;EOF&rsqb;
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/VGADriv.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/VGADriv.sgml
new file mode 100644
index 000000000..2e5dd7871
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/VGADriv.sgml
@@ -0,0 +1,1574 @@
+<!doctype linuxdoc system>
+
+<article>
+
+<!--<title> How to add an (S)VGA driver to XFree86-->
+<title> XFree86 ¤Ø (S)VGA ¥É¥é¥¤¥Ð¤òÄɲ乤ëÊýË¡
+<author> Copyright (c) 1993, 1994 David E. Wexelblat
+ <tt/&lt;dwex@XFree86.org&gt;/
+<date> 1.3 ¹æ - 1994 ǯ 5 ·î 29 Æü
+<trans> ²¬ËÜ¡¡°ì¹¬ Kazuyuki Okamoto &lt;ikko-@pacific.rim.or.jp&gt;
+<tdate> 1996 ǯ 01 ·î 07 Æü
+<toc>
+<!-- ....1.........2.........3.........4.........5.........6...... -->
+
+<!--<sect> Introduction <p>-->
+<sect> ½øÊ¸ <p>
+<!--Adding support for a new SVGA chipset to XFree86 is a challenging project
+for someone who wants to learn more about hardware-level programming. It
+can be fraught with hazards (in particular, crashing the machine is all too
+common). But in the end, when the server comes up and functions, it is
+immensely satisfying.-->
+XFree86 ¤Ë¿·¤·¤¤ SVGA ¥Á¥Ã¥×¥»¥Ã¥È¤Î¥µ¥Ý¡¼¥È¤òÄɲ乤뤳¤È¤Ï¥Ï¡¼¥É¥¦¥§
+¥¢¤ËÌ©Ã夷¤¿¥×¥í¥°¥é¥ß¥ó¥°¤Ë¤Ä¤¤¤Æ³Ø½¬¤·¤¿¤¤¿Í¤Ë¤È¤Ã¤Æ¼ê¤´¤¿¤¨¤Î¤¢¤ë
+ºî¶È¤Ç¤¹¡£¤³¤Î¤è¤¦¤Êºî¶È¤Ë¤Ï´í¸±¤¬°ìÇդǤ¹¡£ÆÃ¤Ë¡¢¥Þ¥·¥ó¤¬¥Ï¥ó¥°¥¢¥Ã
+¥×¤·¤Æ¤·¤Þ¤¦¤è¤¦¤Ê¤³¤È¤ÏÆü¾ïÃãÈÓ»ö¤Ç¤¹¡£¤½¤ì¤Ç¤âºÇ½ªÅª¤Ë¡¢¥µ¡¼¥Ð¡¼¤¬
+Ω¤Á¾å¤¬¤Ã¤Æ¤¦¤Þ¤¯Æ°¤¤¤Æ¤¯¤ì¤¿»þ¤Ï¡¢ÄìÃΤì¤ÌËþ­´¶¤Ë¤Ò¤¿¤ì¤Þ¤¹¡£
+
+<!--Adding support for an SVGA chipset does not change any of the basic
+functioning of the server. It is still a dumb 8-bit PseudoColor server or
+1-bit StaticGray server. Adding support for new hardware (e.g. accelerated
+chips) is a major undertaking, and is not anywhere near formalized enough yet
+that it can be documented.-->
+SVGA ¥Á¥Ã¥×¥»¥Ã¥ÈÂбþ¤Î¥É¥é¥¤¥Ð¤òÄɲ乤뤳¤È¤Ï¥µ¡¼¥Ð¡¼¤Î´ðËܵ¡Ç½¤ò
+Êѹ¹¤¹¤ë¤â¤Î¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤¿¤À¡¢256 ¿§Æ±»þȯ¿§¤Î¥«¥é¡¼¥µ¡¼¥Ð¡¼¤«
+¥â¥Î¥¯¥í¥µ¡¼¥Ð¡¼¤¬½ÐÍè¤ë¤À¤±¤Ç¤¹¡£¿·¤·¤¤¥Ï¡¼¥É¥¦¥§¥¢¡ÊÎ㤨¤Ð¥¢¥¯¥»
+¥é¥ì¡¼¥¿¥Á¥Ã¥×¡Ë¤òÄɲ乤뤳¤È¤Ï½ÅÍפʻŻö¤Ç¡¢Ê¸½ñ²½½ÐÍè¤ë¤è¤¦¤ÊÄê
+·¿Åªºî¶È¤Ë¤ÏÄø±ó¤¤¤â¤Î¤Ç¤¹¡£
+
+<!--Nonetheless, the driver-level programming here is a good introduction. And
+can well be the first step for adding support for an accelerated chipset, as
+many are SVGA-supersets. Writing an SVGA-level driver for the chipset can
+provide a stable development platform for making use of new features (in fact,
+this has been done for the S3, Cirrus, and WD accelerated chipsets, for
+internal use as the accelerated servers are developed for XFree86 2.0).-->
+¤½¤ì¤Ë¤â¤«¤«¤ï¤é¤º¡¢¤³¤³¤Ç¹Ô¤¦¥É¥é¥¤¥Ð¤ò½ñ¤¯¤è¤¦¤Ê¥×¥í¥°¥é¥ß¥ó¥°¤Ï
+Îɤ¤ÆþÌç¤È¤Ê¤ê¤Þ¤¹¡£¥¢¥¯¥»¥é¥ì¡¼¥¿¥Á¥Ã¥×¥»¥Ã¥È¤òÄɲ乤ëºÇ½é¤ÎÃʳ¬
+¤Ç¤Ï SVGA ¤Î¾å°Ì¸ß´¹¤È¤·¤Æ¤Î¥É¥é¥¤¥Ð¤òÄɲ乤ë¤Î¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£³º
+Åö¤¹¤ë¥Á¥Ã¥×Âбþ¤Î SVGA ¤Î¥É¥é¥¤¥Ð¡¼¤ò½ñ¤¯¤³¤È¤Ï¿·¤·¤¤µ¡Ç½¤òÄɲä¹
+¤ë¤È¤­¤Î°ÂÄꤷ¤¿³«È¯´Ä¶­¤ò¹½ÃÛ¤¹¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡Ê¼ÂºÝ¡¢XFree86 2.0
+Âбþ¤ËÆâÉô¤Ç³«È¯¤µ¤ì¤¿ S3, Cirrus ¤ä WD ¤Î¥¢¥¯¥»¥¿¥ì¡¼¥¿¥Á¥Ã¥×¥»¥Ã
+¥È¤Î¥É¥é¥¤¥Ð¤Ç¤Ï¤½¤¦¤Ç¤·¤¿¡Ë¡£
+
+<!--Now let's get down to it. In addition to this documentation, a stub
+driver has
+been provided. This should provide you a complete framework for your new
+driver. Don't let the size of this document persuade you that this is an
+overly difficult task. A lot of work has been put into making this document
+as close to complete as possible; hence it should, in theory, be possible to
+use this as a cookbook, and come out with a working driver when you reach the
+end. I do advise that you read it all the way through before starting.-->
+¤µ¤¢¡¢ÎãÂê¤Î¥½¡¼¥¹¤ò¼ê¤Ë¤¤¤ì¤Þ¤·¤ç¤¦¡£¤³¤Îʸ½ñ¤Ë²Ã¤¨¤Æ¡¢¥¹¥¿¥Ö¥É
+¥é¥¤¥Ð¤òÄ󶡤·¤Þ¤¹¡£¤³¤ì¤Ï¿·¤·¤¤¥É¥é¥¤¥Ð¤ÎŰÄ줷¤¿¹üÁȤߤȤ·¤ÆÄó¶¡
+¤¹¤ë¤â¤Î¤Ç¤¹¡£¤³¤Îʸ½ñ¤¬Â礭¤¤¤«¤é¤È¤¤¤Ã¤Æºî¶È¤¬²áÅÙ¤ËÆñ¤·¤¤¤È»×¤ï
+¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£Ëؤɤκî¶È¤ò½ÐÍè¤ë¸Â¤ê¤³¤Îʸ½ñ¤Ë±è¤Ã¤Æ¿Ê¤á¤ë¤Ê¤é¤Ð¡¢
+º£ÈդΤ¦¤Á¤ËÍýÏÀŪ¤Ë¤Ï¤³¤Îʸ½ñ¤òÎÁÍý¤ÎËܤΤ褦¤Ë»È¤¤¡¢ºÇ¸å¤Ë¤Ïư¤¯
+¥É¥é¥¤¥Ð¤¬½ÐÍè¤ë¤Ç¤·¤ç¤¦¡£
+
+<!--<sect> Getting Started <p>-->
+<sect> »Ï¤á¤Ë <p>
+<!--The first step in developing a new driver is to get the documentation for
+your chipset. I've included a list of vendor contact information that I have
+collected so far (it's far from complete, so if you have any that isn't on
+the list, please send it to me). You need to obtain the databook for the
+chipset. Make sure that the person you speak to is aware that you intend to
+do register-level programming (so they don't send you the EE-style datasheet).
+Ask for any example code, or developer's kits, etc. I've learned that at the
+SVGA level, in general, a databook that lists and describes the registers is
+the most you can hope to find.-->
+¿·¤·¤¤¥É¥é¥¤¥Ð¤òºî¤ëºÇ½é¤ÎÃʳ¬¤Ï¤½¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ë´Ø¤¹¤ë»ñÎÁ¤ò½¸¤á
+¤ë¤³¤È¤Ç¤¹¡£¤ï¤¿¤·¤Î½¸¤á¤¿¥Ù¥ó¥À¡¼¤ÎÏ¢ÍíÀè¾ðÊó¤Î°ìÍ÷¤ò¤³¤Îʸ½ñ¤ËÆþ
+¤ì¤Æ¤¤¤Þ¤¹¡Ê´°àú¤È¤Ï¸À¤¨¤Ê¤¤¤â¤Î¤Ç¤¹¤Î¤Ç¤³¤Î°ìÍ÷¤Ë̵¤¤¤â¤Î¤ÇÃΤäÆ
+¤¤¤ë¤â¤Î¤¬¤¢¤ê¤Þ¤·¤¿¤éÃø¼Ô¤Þ¤ÇÁ÷¤Ã¤Æ¤¯¤À¤µ¤¤¡Ë¡£¥Á¥Ã¥×¥»¥Ã¥È¤Î¥Ç¡¼
+¥¿¥Ö¥Ã¥¯¤ò¼ê¤ËÆþ¤ì¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¥ì¥¸¥¹¥¿¤òľÀÜÁàºî¤¹¤ë¥×¥í¥°¥é
+¥ß¥ó¥°¤¬¤·¤¿¤¤¤È¥Ù¥ó¥À¡¼¤Î¿Í¤ÈÏä¹µ¡²ñ¤Ë³Îǧ¤·¤Æ²¼¤µ¤¤¡£¡Ê¤½¤¦¤·¤Ê
+¤¤¤È EE ·Á¼°¤Î¥Ç¡¼¥¿¥·¡¼¥È¤òÁ÷ÉÕ¤·¤Æ¤¯¤ì¤Þ¤»¤ó¡Ë¡£²¿¤«¥µ¥ó¥×¥ë¥×¥í
+¥°¥é¥à¤«³«È¯¼ÔÍѤΥ­¥Ã¥ÈÅù¤Ë¤Ä¤¤¤ÆÌ䤤¹ç¤ï¤»¤Æ¤¯¤À¤µ¤¤¡£Ãø¼Ô¤¬°ìÈÌ
+Ū¤Ê SVGA ¤Ë¤Ä¤¤¤Æ¾Ü¤·¤¯³Ø½¬¤·¤¿¤È¤­¤Ï¡¢¥ì¥¸¥¹¥¿¤Ë¤Ä¤¤¤ÆÃΤꤿ¤¤
+ËØ¤É¤Î»ö¤¬¥Ç¡¼¥¿¥·¡¼¥È¤Ë°ìÍ÷¤äµ­»ö¤Ë¤¢¤ê¤Þ¤·¤¿¡£
+
+<!--If you are not familiar with VGA register-level programming, you should get
+(and read!) a copy of Richard Ferraro's bible (see references below). The
+best way to understand what is happening in the server is to study the
+workings of the monochrome server's ``generic'' server, and compare it with
+the documentation in Ferraro's book (be aware that there are a few errors
+in the book). You can find the generic-VGA-register handling functions in
+the file ``vgaHW.c''.-->
+VGA ¥ì¥¸¥¹¥¿¤òľÀÜÁàºî¤¹¤ë¤è¤¦¤Ê¥×¥í¥°¥é¥ß¥ó¥°¤Ë´·¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï
+Richard Ferraro ¤ÎɬÆÉ½ñ¤òÆþ¼ê¤·¤Æ¡ÊÀ§ÈóÆÉ¤ó¤Ç¡ª¡Ë²¼¤µ¤¤¡Ê°Ê¹ß¤Î
+¡Ö»²¹Íʸ¸¥¡×¤ò¸«¤Æ¤¯¤À¤µ¤¤¡Ë¡£¥µ¡¼¥Ð¡¼¤Ç²¿¤¬µ¯¤Ã¤Æ¤¤¤ë¤«¤òÍý²ò¤¹¤ë
+ºÇÎɤÎÊýË¡¤Ï¥â¥Î¥¯¥í¤Î ``generic'' ¥µ¡¼¥Ð¡¼¤Îưºî¤òÄ´¤Ù¡¢Ferraro
+¤ÎËܤ˽ñ¤«¤ì¤Æ¤¤¤ë¾ðÊó¤ÈÈæ³Ó¤·¤Æ²¼¤µ¤¤¡ÊËܤ˾¯¤·´Ö°ã¤¤¤¬¤¢¤ë¤³¤È¤Ë
+µ¤ÉÕ¤¯¤Ç¤·¤ç¤¦¡Ë¡£generic ¤Ê VGA ¥ì¥¸¥¹¥¿¤ò°·¤¦´Ø¿ô¤ò ``vgaHW.c''
+¥Õ¥¡¥¤¥ë¤Ë¸«¤Ä¤±¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡£
+
+<!--Once you understand what's happening in the generic server, you should
+study
+one or more of the existing SVGA drivers. Obtain the databook for a supported
+SVGA chipset, and study the documentation along with the code. When you have
+a good understanding of what that driver does over and above the generic VGA,
+you will know what information you need to obtain from the databook for the
+new chipset. Once you have this information, you are ready to begin work on
+your new driver.-->
+generic ¤Ê¥µ¡¼¥Ð¡¼¤Ç²¿¤¬µ¯¤Ã¤Æ¤¤¤ë¤«Íý²ò¤·¤¿¤é¡¢°ì¤Ä¤«¤½¤ì°Ê¾å¤Î´û
+¸¤Î SVGA ¥µ¡¼¥Ð¡¼¤Ë¤Ä¤¤¤ÆÄ´¤Ù¤Æ¤¯¤À¤µ¤¤¡£¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë SVGA ¥Á¥Ã
+¥×¤Î¥Ç¡¼¥¿¥Ö¥Ã¥¯¤òÆþ¼ê¤·¤Æ¥×¥í¥°¥é¥à¤òÄɤ¤¤Ê¤¬¤éʸ½ñ¤òÄ´ºº¤·¤Æ¤¯¤À
+¤µ¤¤¡£generic ¤Ê VGA ¤«¤é²¿¤¬»ÅÍͤòͤ¨¤Æ¤¤¤Æ²¿¤¬»ÅÍͤ˼ý¤Þ¤Ã¤Æ¤¤¤ë
+¤«Îɤ¯Íý²ò¤·¤¿¤é¡¢¿·¤·¤¤¥Á¥Ã¥×¤Ë¤Ä¤¤¤Æ¥Ç¡¼¥¿¥Ö¥Ã¥¯¤«¤é¤É¤ó¤Ê¾ðÊó¤òÆÀ
+¤ì¤Ð¤è¤¤¤«Ê¬¤«¤ë¤Ç¤·¤ç¤¦¡£¤³¤Î¾ðÊó¤ò¼ý½¸¤·¤¿¤é¡¢¿·¤·¤¤¥É¥é¥¤¥Ð¡¼¤Ë¼è
+¤ê¤«¤«¤ë½àÈ÷¤¬½ÐÍè¤Þ¤·¤¿¡£
+
+<!--<sect> Directory Tree Structure <p>-->
+<sect> ¥Ç¥£¥ì¥¯¥È¥ê¹½Â¤ <p>
+<!--Here is an outline of the directory tree structure for the source tree.
+Only directories/files that are relevant to writing a driver are presented.
+The structure for the Link Kit is presented below.-->
+¤³¤³¤Ç¤Ï¥½¡¼¥¹¤Î¥Ç¥£¥ì¥¯¥È¥ê¹½Â¤¤Î³µÍפòÀâÌÀ¤·¤Þ¤¹¡£½ñ¤³¤¦¤È¤·¤Æ¤¤
+¤ë¥É¥é¥¤¥Ð¤Ë´ØÏ¢¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¡¿¥Õ¥¡¥¤¥ë¤Ï´ûÃΤȤ·¤Þ¤¹¡£¥ê¥ó¥¯¥­¥Ã
+¥È¤Î¹½Â¤¤Ï°Ê¹ß¤Ç¼¨¤·¤Þ¤¹¡£
+
+<descrip>
+<tag>xc/config/cf/</tag>
+ <descrip>
+ <tag>site.def</tag>
+<!-- Local configuration customization-->
+ ¥í¡¼¥«¥ë¤Ê¹½À®¤Î¥«¥¹¥¿¥Þ¥¤¥º
+ <tag>xf86site.def</tag>
+<!-- XFree86 local configuration customization-->
+ XFree86 ¤Î¥í¡¼¥«¥ë¤Ê¹½À®¤Î¥«¥¹¥¿¥Þ¥¤¥º
+ </descrip>
+
+<tag>xc/programs/Xserver/hw/xfree86/</tag>
+<!-- The server source-->
+ ¥µ¡¼¥Ð¡¼¤Î¥½¡¼¥¹
+ <descrip>
+ <tag>common/</tag>
+<!-- Files common to all of the server (XF86Config
+ parser, I/O device handlers, etc)-->
+ Á´¥µ¡¼¥Ð¡¼¤Ë¶¦Ä̤ʥե¡¥¤¥ë (XF86Config ¤Î¥Ñ¥é¥á¡¼¥¿
+ ²òÀÏ/¥Ñ¡¼¥µ, I/O ¥Ç¥Ð¥¤¥¹¥Ï¥ó¥É¥éÅù)
+ <descrip>
+ <tag>xf86.h</tag>
+<!-- Contains the `ScrnInfoRec' data structure-->
+ `ScrnInfoRec' ¥Ç¡¼¥¿¹½Â¤¤ò´Þ¤à
+ <tag>xf86_Option.h</tag>
+<!-- Contains option flags-->
+ ¥ª¥×¥·¥ç¥ó¥Õ¥é¥°¤ò´Þ¤à
+ <tag>compiler.h</tag>
+<!-- Contains in-line assembler macros and
+ utility functions-->
+ ¥¤¥ó¥é¥¤¥ó¥¢¥»¥ó¥Ö¥é¥Þ¥¯¥í¤È
+ ¥æ¡¼¥Æ¥£¥ê¥Æ¥£´Ø¿ô¤ò´Þ¤à
+ </descrip>
+<!-- <tag>os-support/</tag> OS-support layer-->
+ <tag>os-support/</tag> OS ¥µ¥Ý¡¼¥ÈÁØ
+ <descrip>
+ <tag>assyntax.h</tag>
+<!-- Contains macro-ized assembler mnemonics-->
+ ¥Þ¥¯¥í²½¤·¤¿¥¢¥»¥ó¥Ö¥é¥Ë¥â¥Ë¥Ã¥¯¤ò´Þ¤à
+ <tag>xf86_OSlib.h</tag>
+<!-- OS-support includes, defines, and prototypes-->
+ OS ¤¬¥µ¥Ý¡¼¥È¤¹¤ë include, define ¤È ¥×¥í¥È¥¿¥¤¥×
+ </descrip>
+ <tag>LinkKit/</tag>
+ <descrip>
+ <tag>site.def.LK</tag>
+<!-- Template for Link Kit site.def-->
+ ¥ê¥ó¥¯¥­¥Ã¥È¤Î site.def ÍѤΥƥó¥×¥ì¡¼¥È
+ </descrip>
+<!-- <tag>vga256/</tag> 256-color VGA server directories-->
+ <tag>vga256/</tag> 256 ¿§ VGA ¥µ¡¼¥Ð¡¼¤Î¥Ç¥£¥ì¥¯¥È¥ê
+ <descrip>
+ <tag>vga/</tag>
+<!-- The generic VGA handling code-->
+ generic ¤Ê VGA ¤ò¼è¤ê°·¤¦¥×¥í¥°¥é¥à
+ <descrip>
+ <tag>vga.h</tag>
+<!-- Contains the `vgaVideoChipRec' and `vgaHWRec'
+ data structures-->
+ `vgaVideoChipRec' ¤È `vgaHWRec' ¥Ç¡¼¥¿¹½Â¤¤ò
+ ´Þ¤à
+ <tag>vgaHW.c</tag>
+<!-- Contains the generic-VGA-register handling
+ functions <bf>vgaHWInit()</bf>,
+ <bf>vgaHWSave()</bf> and
+ <bf>vgaHWRestore()</bf>.-->
+ generic ¤Ê VGA ¥ì¥¸¥¹¥¿¤ò¼è¤ê°·¤¦´Ø¿ô
+ <bf>vgaHWInit()</bf>,
+ <bf>vgaHWSave()</bf> ¤È
+ <bf>vgaHWRestore()</bf>¤ò´Þ¤à¡£
+ </descrip>
+<!-- <tag>drivers/</tag> Contains the SVGA driver subdirectories.-->
+ <tag>drivers/</tag> SVGA ¥É¥é¥¤¥Ð¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤ò´Þ¤à¡£
+<!-- Each contains an Imakefile, a .c file for
+ the driver, and a .s file for the bank-
+ switching functions.-->
+ ³Æ¡¹¡¢¥É¥é¥¤¥ÐÍÑ Imakefile, .c ¥Õ¥¡¥¤¥ë¤È
+ ¥Ð¥ó¥¯ÀÚ¤êÂØ¤¨´Ø¿ôÍѤΠ.s ¥Õ¥¡¥¤¥ë¤ò´Þ¤à
+ </descrip>
+ <tag>vga2/</tag>
+<!-- The monochrome vga server directories. Most of
+ the files are linked from vga256, and the
+ differences handled by conditional compilation.-->
+ ¥â¥Î¥¯¥í¤Î vga ¥µ¡¼¥Ð¡¼¤Î¥Ç¥£¥ì¥¯¥È¥ê¡£vga256 ¤Ë
+ ¥ê¥ó¥¯¤¹¤ë¥Õ¥¡¥¤¥ë¤È¾ò·ï¥³¥ó¥Ñ¥¤¥ë¤Ç»ÈÍѤ¹¤ëº¹Ê¬¡£
+ <descrip>
+ <tag>drivers/</tag>
+<!-- The SVGA driver subdirectories. The `generic'
+ VGA driver is also located here.-->
+ SVGA ¥É¥é¥¤¥Ð¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¡£`generic' ¤Ê VGA
+ ¥É¥é¥¤¥Ð¤â¤³¤³¤ËÇÛÃÖ¤¹¤ë¡£
+ </descrip>
+ <tag>vga16/</tag>
+<!-- The 16-color vga server directories. Most of
+ the files are linked from vga256, and the
+ differences handled by conditional compilation.-->
+ 16 ¿§ vga ¥µ¡¼¥Ð¡¼¤Î¥Ç¥£¥ì¥¯¥È¥ê¡£vga256
+ ¤Ë¥ê¥ó¥¯¤¹¤ëËØ¤É¤Î¥Õ¥¡¥¤¥ë¤È¾ò·ï¥³¥ó¥Ñ¥¤¥ë¤Ç
+ »ÈÍѤ¹¤ëº¹Ê¬¡£
+ <descrip>
+<!-- <tag>drivers/</tag> The SVGA driver subdirectories.-->
+ <tag>drivers/</tag> SVGA ¥É¥é¥¤¥Ð¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¡£
+ </descrip>
+<!-- <tag>VGADriverDoc/</tag> This documentation and the stub driver.-->
+ <tag>VGADriverDoc/</tag> ¤³¤Îʸ½ñ¤È¥¹¥¿¥Ö¥É¥é¥¤¥Ð¡£
+ </descrip>
+</descrip>
+<!--The Link Kit is usually installed in /usr/X11R6/lib/Server.-->
+¥ê¥ó¥¯¥­¥Ã¥È¤ÏÄ̾ï /usr/X11R6/lib/Server ¤ËƳÆþ¤·¤Þ¤¹¡£
+<!--The Link Kit
+contains everything that is needed to relink the server. It is possible
+to write a new driver and build a new server without having even the server
+source installed.-->
+¥ê¥ó¥¯¥­¥Ã¥È¤Ï¥µ¡¼¥Ð¡¼¤ÎºÆ¥ê¥ó¥¯¤ò¹Ô¤¦¤Î¤ËɬÍפÊÁ´¤Æ¤Î¤â¤Î¤¬´Þ¤Þ¤ì
+¤Æ¤¤¤Þ¤¹¡£¿·¤·¤¤¥É¥é¥¤¥Ð¤ò½ñ¤¯¤Î¤È¥µ¡¼¥Ð¡¼¤Î¥½¡¼¥¹¤ÎƳÆþ¤Ê¤·¤Ë¿·¤·
+¤¤¥µ¡¼¥Ð¡¼¤òÀ¸À®¤¹¤ë¤Î¤ËɬÍפǤ¹¡£
+<descrip>
+<tag>Server/</tag>
+ <descrip>
+ <tag>site.def</tag>
+<!-- Local configuration customization-->
+ ¥í¡¼¥«¥ë¤Ê¹½À®¤Î¥«¥¹¥¿¥Þ¥¤¥º
+ <tag>include/</tag>
+<!-- All of the include files listed under the
+ `common' directory above-->
+ ¾åµ­ `common' ¥Ç¥£¥ì¥¯¥È¥ê²¼¤Ë¤¢¤ëÁ´¤Æ¤Î include ¥Õ¥¡¥¤¥ë
+ <tag>drivers/</tag>
+<!-- All of the SVGA drivers-->
+ SVGA ¥É¥é¥¤¥Ð¤ÎÁ´¤Æ
+ <descrip>
+<!-- <tag>vga2/</tag> The SVGA driver subdirectories.-->
+ <tag>vga2/</tag> SVGA ¥É¥é¥¤¥Ð¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¡£
+<!-- <tag>vga16/</tag> The SVGA driver subdirectories.-->
+ <tag>vga16/</tag> SVGA ¥É¥é¥¤¥Ð¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¡£
+<!-- <tag>vga256/</tag> The SVGA driver subdirectories.-->
+ <tag>vga256/</tag> SVGA ¥É¥é¥¤¥Ð¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¡£
+ </descrip>
+<!-- <tag>VGADriverDoc/</tag> The directory with this documentation and
+ the stub driver. `vgaHW.c' is also copied
+ here, for reference (it is not built as
+ part of the Link Kit).-->
+ <tag>VGADriverDoc/</tag> ¤³¤Îʸ½ñ¤È¥¹¥¿¥Ö¥É¥é¥¤¥Ð¤Î
+ ¥Ç¥£¥ì¥¯¥È¥ê¡£`vgaHW.c' ¤Ï¤³¤³¤Ë¤â¥³¥Ô¡¼¤µ¤ì
+ »²¾È¤µ¤ì¤Þ¤¹¡Ê¥ê¥ó¥¯¥­¥Ã¥È¤Î°ìÉô¤È¤·¤Æ¤ÏÀ¸À®¤·
+ ¤Þ¤»¤ó¡Ë¡£
+ </descrip>
+</descrip>
+
+<!--<sect> Setting Up The Build Information <p>-->
+<sect> À¸À®¾ðÊó¤ÎÀßÄê <p>
+<!-- This section describes the peripheral configuration and build steps that
+must be performed to set up for your new driver. The steps are the same
+whether you are building from the source tree of from the Link Kit; only
+the locations of the files is different. Here are the configuration steps
+that must be followed:-->
+¤³¤ÎÀá¤Ç¤Ï¿·¤·¤¤¥É¥é¥¤¥ÐÍÑÀßÄê¤ò¹Ô¤Ê¤¦°Ù¤Î¼þÊդι½À®Êѹ¹¤ÈÀ¸À®Ãʳ¬
+¤Ë¤Ä¤¤¤ÆÀâÌÀ¤·¤Þ¤¹¡£¤³¤ÎÃʳ¬¤Ç¤Ï¥½¡¼¥¹¤«¤éÀ¸À®¤¹¤ë¤«¥ê¥ó¥¯¥­¥Ã¥È¤«
+¤éÀ¸À®¤¹¤ë¤«¤Ë¤«¤«¤ï¤é¤ºÆ±Íͤǡ¢¤¿¤À¥Õ¥¡¥¤¥ë¤ÎÇÛÃÖ¤¬°Û¤Ê¤Ã¤Æ¤¤¤ë¤À
+¤±¤Î¤³¤È¤Ç¤¹¡£°Ê²¼¤Ë¹½À®Êѹ¹¤Ë¤Ä¤¤¤ÆÀâÌÀ¤·¤Þ¤¹:
+
+<enum>
+<!--<item> Choose the name for your driver subdirectory and data structures.
+ Since the current driver scheme allows (in fact, encourages)
+ putting drivers for multiple related chipsets in a single driver,
+ it is usually best to use the vendor name, rather than a chipset
+ version. The fact that older XFree86 drivers do not follow this
+ convention should not deter you from using it now - most of that
+ code was developed before the driver interface had been made
+ flexible and extensible.-->
+<item> ¥É¥é¥¤¥Ð¤Î¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤È¥Ç¡¼¥¿¹½Â¤¤ò·èÄꤷ¤Æ²¼¤µ¤¤¡£
+ ñ°ì¤Î¥É¥é¥¤¥ÐÆâ¤Ë¤½¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ë´ØÏ¢¤¹¤ëÊ£¿ô¤Î¥É¥é¥¤¥Ð
+ ¤ò¼ÂÁõ¤¹¤ë¤³¤È¤¬¸½¾õ¤Î¥É¥é¥¤¥Ð¤Ëµö¤µ¤ì¤ë¤Ê¤é¤Ð¡Ê¼ÂºÝ¤Ë¤Ï¾©
+ Î夵¤ì¤Æ¤¤¤Þ¤¹¡Ë¡¢Ä̾ï¥Á¥Ã¥×¥»¥Ã¥È¤Î¥Ð¡¼¥¸¥ç¥ó¤è¤ê¤Ï¥Ù¥ó¥À¡¼
+ ̾¾Î¤ò»ÈÍѤ¹¤ë¤Î¤¬Îɤ¤¤Ç¤·¤ç¤¦¡£ÀΤΠXFree86 ¤Î¥É¥é¥¤¥Ð¤Ï¤³
+ ¤Î´·½¬¤òºÎÍѤ·¤Æ¤¤¤Ê¤«¤Ã¤¿¤Ç¤¹¤¬¸½ºß¤ÏËØ¤É¤Î¥É¥é¥¤¥Ð¤¬¥É¥é¥¤
+ ¥Ð¤Î¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤ò½ÀÆð³î¤Ä³ÈÄ¥²Äǽ¤Ë¤Ê¤ë¤è¤¦¤Ë¤³¤Î´·½¬
+ ¤ò»ÈÍѤ·¤Æ¤¤¤Þ¤¹¤Î¤Ç¥Ù¥ó¥À¡¼Ì¾¾Î¤ò»È¤¤¤Þ¤·¤ç¤¦¡£
+
+<!-- For this documentation, we'll use chips from the SuperDuper Chips
+ vendor. Hence, we'll use `sdc' for the name of the driver.-->
+ ¤³¤Îʸ½ñ¤Ç¤Ï SuperDuper Chips ¤È¤¤¤¦¥Ù¥ó¥À¡¼¤òÎã¤Ë¼è¤êµó¤²
+ ¤Þ¤¹¡£°Ê¹ß¡¢¥É¥é¥¤¥Ð¤Î̾¾Î¤Ë `sdc' ¤òÍѤ¤¤Þ¤¹¡£
+
+<!--<item> Decide whether your driver will support the color server, the
+ monochrome server, or both. For this documentation, we will
+ assume that both the color and monochrome servers will be
+ supported. If you intend to support only the color server, the
+ steps for the monochrome server can be ignored. If you intend
+ to support only the monochrome server, the steps for the color
+ server listed should be performed for the monochrome server,
+ and the monochrome steps ignored. Most of the existing drivers
+ support only the color or both servers; the ``generic'' driver is
+ the only driver (currently) that supports just the monochrome
+ server.-->
+<item> ¥«¥é¡¼¥µ¡¼¥Ð¡¼¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤«¥â¥Î¥¯¥í¥µ¡¼¥Ð¡¼¤ò¥µ¥Ý¡¼¥È¤¹
+ ¤ë¤«Ëô¤ÏξÊý¥µ¥Ý¡¼¥È¤¹¤ë¤Î¤«·èÄꤷ¤Æ¤¯¤À¤µ¤¤¡£¤³¤Îʸ½ñ¤Ç¤Ï¡¢
+ ¥«¥é¡¼¤È¥â¥Î¥¯¥íξÊý¤Î¥µ¡¼¥Ð¡¼¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤è¤¦¤Ë²¾Äꤷ¤Æ¤¤
+ ¤Þ¤¹¡£¥«¥é¡¼¥µ¡¼¥Ð¡¼¤À¤±¤ò¥µ¥Ý¡¼¥È¤·¤¿¤¤¤È»×¤¦¾ì¹ç¤Ï¥â¥Î¥¯¥í
+ ¤Î¥µ¡¼¥Ð¡¼¤ò¼Â¸½¤¹¤ëÃʳ¬¤ò̵»ë¤·¤Æ¤¯¤À¤µ¤¤¡£¥â¥Î¥¯¥í¥µ¡¼¥Ð¡¼
+ ¤À¤±¤ò¥µ¥Ý¡¼¥È¤·¤¿¤¤¾ì¹ç¤Ï¥«¥é¡¼¥µ¡¼¥Ð¡¼¤ÎÃʳ¬¤Ç°ìÍ÷¤Ë¤¢¤ë²Ä
+ ǽ¤Ê¥â¥Î¥¯¥í¥µ¡¼¥Ð¡¼¤ò¼Â¸½¤µ¤»¡¢¥â¥Î¥¯¥í¥µ¡¼¥Ð¡¼¤ÎÃʳ¬¤Ï̵»ë
+ ¤·¤Æ¤¯¤À¤µ¤¤¡£¸½Â¸¤¹¤ëËØ¤É¤Î¥É¥é¥¤¥Ð¡¼¤Ï¥«¥é¡¼¤Î¤ß¤«¡¢Î¾Êý¤Î
+ ¥µ¡¼¥Ð¡¼¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Æ¡¢``generic'' ¤Ê¥É¥é¥¤¥Ð¡¼¤Ï¡Ê¸½ºß
+ ¤Ï¡Ë¥â¥Î¥¯¥í¥µ¡¼¥Ð¡¼¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£
+
+<!--<item> Create your driver directories:-->
+<item> ¥É¥é¥¤¥Ð¡¼¤Î¥Ç¥£¥ì¥¯¥È¥ê¤òºîÀ®¤·¤Æ¤¯¤À¤µ¤¤:
+
+ <itemize>
+<!-- <item> If you are working in the source tree, create the
+ following directories:-->
+ <item> ¥½¡¼¥¹¤«¤éºî¶È¤¹¤ë¾ì¹ç¤Ï¡¢¼¡¤Î¥Ç¥£¥ì¥¯¥È¥ê¤òºîÀ®
+ ¤·¤Æ¤¯¤À¤µ¤¤:
+
+<verb>
+ xc/programs/Xserver/hw/xfree86/vga256/drivers/sdc
+ xc/programs/Xserver/hw/xfree86/vga16/drivers/sdc
+ xc/programs/Xserver/hw/xfree86/vga2/drivers/sdc
+</verb>
+
+<!-- <item> If you are working in the Link Kit, create the
+ following directories:-->
+ <item> ¥ê¥ó¥¯¥­¥Ã¥È¤«¤éºî¶È¤¹¤ë¾ì¹ç¤Ï¼¡¤Î¥Ç¥£¥ì¥¯¥È¥ê¤ò
+ ºîÀ®¤·¤Æ¤¯¤À¤µ¤¤:
+
+
+<verb>
+ /usr/X11R6/lib/Server/drivers/vga256/sdc
+ /usr/X11R6/lib/Server/drivers/vga16/sdc
+ /usr/X11R6/lib/Server/drivers/vga2/sdc
+</verb>
+ </itemize>
+
+<!--<item> Set up the Imakefile parameters to cause your driver to be
+ built:-->
+<item> ¥É¥é¥¤¥Ð¡¼¤òÀ¸À®¤¹¤ë°Ù¤Î Imakefiel ¥Ñ¥é¥á¥¿¤òÀßÄꤷ¤Þ¤·¤ç¤¦:
+
+ <itemize>
+<!-- <item> If you are working in the source tree:-->
+ <item> ¥½¡¼¥¹¤«¤éºî¶È¤¹¤ë¤Ê¤é:
+ <enum>
+<!-- <item> Edit the file xc/config/cf/xfree86.cf,
+ and add
+ `sdc' to the list for the definitions for
+ `XF86Vga256Drivers', `XF86Vga16Drivers' and
+ `XF86Vga2Drivers'.
+ You should put `sdc' just before `generic' in the
+ list (i.e. second last), to ensure that none of the
+ other driver's probe functions incorrectly detect
+ the `sdc' chipset .-->
+ <item> xc/config/cf/xfree86.cf ¤òÊÔ½¸¤·¤Æ `sdc' ¤ò
+ `XF86Vga256Drivers', `XF86Vga16Drivers' ¤È
+ `XF86Vga2Drivers' ¤ÎÄêµÁ¤Î°ìÍ÷¤ËÄɲ䷤Ƥ¯¤À¤µ¤¤¡£
+ °ìÍ÷¤Î `generic' ¤ÎľÁ°¡ÊÎ㤨¤ÐºÇ¸å¤«¤éÆóÈÖÌܡˤË
+ `sdc' ¤òÄɲä· `sdc' ¤ò¾¤Î¥É¥é¥¤¥Ð¡¼¤Îõºº¤¬ÉÔÀµ
+ ¤Ë `sdc' ¥Á¥Ã¥×¥»¥Ã¥È¤ò¸¡ÃΤ·¤Ê¤¤¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ
+ ¤¤¡£
+<!-- <item> Edit the file xc/config/cf/xf86site.def,
+ and add
+ the same entries in this file (this is just a
+ comment that shows the default values).-->
+ <item> xc/config/cf/xf86site.def ¤òÊÔ½¸¤·¤Æ¤³¤Î¥Õ¥¡¥¤
+ ¥ë¤Ë¤¤¤¯¤Ä¤«¤Î¹àÌܤòÄɲ䷤Ƥ¯¤À¤µ¤¤¡Ê¤³¤ì¤Ïɸ½àÃͤÎ
+ ÀßÄê¤Îºî¶È¤Ç¤¹¡Ë¡£
+<!-- <item> Edit the site.def.LK file in
+ xc/programs/Xserver/hw/xfree86/LinkKit/,
+ and add the same entries in this file. This is
+ the prototype `site.def' file that will be
+ installed in the Link Kit.-->
+ <item> xc/programs/Xserver/hw/xfree86/LinkKit/ ¤Ë¤¢¤ë
+ site.def.LK ¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Æ¤³¤Î¥Õ¥¡¥¤¥ë¤Ë¤¤¤¯¤Ä¤«
+ ¤Î¹àÌܤòÄɲ䷤Ƥ¯¤À¤µ¤¤¡£¤³¤ì¤Ï¥ê¥ó¥¯¥­¥Ã¥È¤Ë´Þ¤Þ¤ì
+ ¤ë `site.def' ¥Õ¥¡¥¤¥ë¤Î¿÷·¿¤Ç¤¹¡£
+ </enum>
+
+<!-- <item> If you are working in the Link Kit, edit the file
+ /usr/X11R6/lib/Server/site.def, and add `sdc' to
+ the `XF86Vga256Drivers', `XF86Vga16Drivers' and
+ `XF86Vga2Drivers' definitions as described in (a) above.-->
+ <item>¥ê¥ó¥¯¥­¥Ã¥È¤«¤éºî¶È¤ò¤¹¤ë¤Ê¤é¡¢/usr/X11R6/lib/Server/site.def
+ ¤òÊÔ½¸¤·¤Æ`sdc' ¤ò `XF86Vga256Drivers', `XF86Vga16Drivers' ¤È
+ `XF86Vga2Drivers' ¤ÎÄêµÁ¤ËºÇ½é¤Ë½ñ¤¤¤¿ÍͤËÄɲ䷤Ƥ¯¤À¤µ¤¤¡£
+ </itemize>
+<!--<item> Now copy the prototype files into your new directories:-->
+<item> ¤µ¤Æ¿·¤·¤¤¥Ç¥£¥ì¥¯¥È¥ê¤Ë¿÷·¿¤Î¥Õ¥¡¥¤¥ë¤ò¥³¥Ô¡¼¤·¤Þ¤·¤ç¤¦:
+ <itemize>
+<!-- <item> If you are working in the source tree, copy the `stub'
+ files as follows (directories are below xc/programs/Xserver):-->
+ <item> ¥½¡¼¥¹¤«¤éºî¶È¤¹¤ë¤Ê¤é¡¢`stub' ¥Õ¥¡¥¤¥ë¤ò¼¡¤Î¤è¤¦¤Ë¥³¥Ô¡¼
+ ¤·¤Æ¤¯¤À¤µ¤¤¡Ê¥Ç¥£¥ì¥¯¥È¥ê¤Ï xc/programs/Xserver ¤Î²¼¤Ç¤¹¡Ë:
+ <descrip>
+ <tag>Imakefile.stub =&gt;</tag>
+ hw/xfree86/vga256/drivers/sdc/Imakefile
+ <tag>stub_driver.c =&gt;</tag>
+ hw/xfree86/vga256/drivers/sdc/sdc_driver.c
+ <tag>stub_bank.s =&gt;</tag>
+ hw/xfree86/vga256/drivers/sdc/sdc_bank.s
+ <tag>Imakefile.stub =&gt;</tag>
+ hw/xfree86/vga16/drivers/sdc/Imakefile
+<!-- (then edit this Imakefile and make the changes
+ described in the comments).-->
+ ¡Ê¤½¤·¤Æ Imakefile ¤òÊÔ½¸¤·¤Æ¥³¥á¥ó¥È¤Ë½¾¤Ã¤Æ
+ Êѹ¹¤·¤Æ¤¯¤À¤µ¤¤¡Ë¡£
+ <tag>Imakefile.stub =&gt;</tag>
+<!-- hw/xfree86/vga2/drivers/sdc/Imakefile
+ (then edit this Imakefile and make the changes
+ described in the comments).-->
+ ¡Ê¤½¤·¤Æ Imakefile ¤òÊÔ½¸¤·¤Æ¥³¥á¥ó¥È¤Ë½¾¤Ã¤Æ
+ Êѹ¹¤·¤Æ¤¯¤À¤µ¤¤¡Ë¡£
+ </descrip>
+<!-- <item> If you are working in the Link Kit, copy the `stub' files
+ as follows:-->
+ <item> ¥ê¥ó¥¯¥­¥Ã¥È¤«¤éºî¶È¤¹¤ë¤Ê¤é¡¢`stub' ¥Õ¥¡¥¤¥ë¤ò¼¡¤Î¤è¤¦
+ ¤Ë¥³¥Ô¡¼¤·¤Æ¤¯¤À¤µ¤¤:
+ <descrip>
+ <tag>Imakefile.stub =&gt; </tag>
+ /usr/X11R6/lib/Server/drivers/vga256/sdc/Imakefile
+ <tag>stub_driver.c =&gt; </tag>
+ /usr/X11R6/lib/Server/drivers/vga256/sdc/sdc_driver.c
+ <tag>stub_bank.s =&gt; </tag>
+ /usr/X11R6/lib/Server/drivers/vga256/sdc/sdc_bank.s
+ <tag>Imakefile.stub =&gt; </tag>
+ /usr/X11R6/lib/Server/drivers/vga16/sdc/Imakefile
+<!-- (then edit this Imakefile and make the changes
+ described in the comments).-->
+ ¡Ê¤½¤·¤Æ Imakefile ¤òÊÔ½¸¤·¤Æ¥³¥á¥ó¥È¤Ë½¾¤Ã¤Æ
+ Êѹ¹¤·¤Æ¤¯¤À¤µ¤¤¡Ë¡£
+ <tag>Imakefile.stub =&gt; </tag>
+ /usr/X11R6/lib/Server/drivers/vga2/sdc/Imakefile
+<!-- (then edit this Imakefile and make the changes
+ described in the comments).-->
+ ¡Ê¤½¤·¤Æ Imakefile ¤òÊÔ½¸¤·¤Æ¥³¥á¥ó¥È¤Ë½¾¤Ã¤Æ
+ Êѹ¹¤·¤Æ¤¯¤À¤µ¤¤¡Ë¡£
+ </descrip>
+ </itemize>
+<!--<item> Edit each of the files you've just copied, and replace `stub'
+ with `sdc' and `STUB' with `SDC' wherever they appear.-->
+<item> ¤¿¤Ã¤¿º£¥³¥Ô¡¼¤·¤¿³Æ¡¹¤Î¥Õ¥¡¥¤¥ë¤òÊÔ½¸¤·¤Æ `stub' ¤ò `sdc'
+¤Ë¡¢`STUB' ¤ò `SDC' ¤ËÁ´¤ÆÃÖ¤­´¹¤¨¤Æ¤¯¤À¤µ¤¤¡£
+</enum>
+<!--That's all the prep work needed. Now it's time to work on the actual
+driver.-->
+ɬÍפʽàÈ÷ºî¶È¤Ï°Ê¾å¤Ç¤¹¡£¤³¤ì¤Ç¼ÂºÝ¤Î¥É¥é¥¤¥Ð¤òºîÀ®¤¹¤ëºî¶È¤¬½ÐÍè
+¤Þ¤¹¡£
+
+<!--<sect> The Bank-Switching Functions <p>-->
+<sect> ¥Ð¥ó¥¯ÀÚ¤êÂØ¤¨µ¡Ç½ <p>
+<!--The normal VGA memory map is 64k starting at address 0xA0000. To access
+more than 64k of memory, SuperVGA chipsets implement ``bank switching'' -
+the high-order address bits are used to select the bank of memory in which
+operations will take place. The size and number of these banks varies,
+and will be spelled out in the chipset documentation. A chipset will
+have zero, one or two bank registers. Likely the ONLY case of zero bank
+registers is a generic VGA, and hence is not a concern.-->
+ÉáÄ̤ΠVGA ¥á¥â¥ê¥Þ¥Ã¥×¤Ï 0xA0000 ¤«¤é»Ï¤Þ¤ë 64k ¤Ç¤¹¡£64k ¤è¤êÂ礭
+¤Ê¥á¥â¥ê¤Ë¥¢¥¯¥»¥¹¤¹¤ë¤Ë¤Ï¡¢``¥Ð¥ó¥¯ÀÚ¤êÂØ¤¨µ¡Ç½(bank switching)''
+- ¹â°Ì¤Î¥¢¥É¥ì¥¹¥Ó¥Ã¥È¤ò¥á¥â¥ê¤Î¥Ð¥ó¥¯ÁªÂò¤Ë»È¤¦¤è¤¦¤ÊÁàºî¤ËÃÖ¤­´¹
+¤¨¤ëµ¡Ç½¤ò¼Â¸½¤·¤Æ¤¤¤ëSuperVGA ¥Á¥Ã¥×¥»¥Ã¥È¤¬É¬ÍפǤ¹¡£¥µ¥¤¥º¤È¿ô¤Î
+¥Ð¥ó¥¯¤ÏÊѲ½¤·¡¢¤½¤Î̾¾Î¤Ï¥Á¥Ã¥×¥»¥Ã¥È¤Î»ñÎÁ¤Ëµ­ºÜ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¥Á¥Ã
+¥×¥»¥Ã¥È¤Ï¥Ð¥ó¥¯¥ì¥¸¥¹¥¿Ìµ¤·¤«°ì¤Ä¤«Æó¤Ä¤Î¥Ð¥ó¥¯¥ì¥¸¥¹¥¿¤ò»ý¤Ã¤Æ¤¤
+¤Þ¤¹¡£¥Ð¥ó¥¯¥ì¥¸¥¹¥¿¤Ê¤·¤Î¾ì¹ç¤Ï generic ¤Ê VGA *¤À¤±* ¤Ç¤¹¤Î¤Ç¡¢´Ø
+·¸¤¢¤ê¤Þ¤»¤ó¡£
+
+<!--Note that some of the newer chipsets (e.g. Trident 8900CL, Cirrus) allow
+for a linear mapping of the video memory. While using such a scheme would
+improve the performance of the server, it is not currently supported. Hence
+there is no way to use such features for a new chipset.-->
+¿·¤·¤¤¥Á¥Ã¥×¥»¥Ã¥È¡ÊÎ㤨¤Ð Trident 8900CL, CirrusÀ½¡Ë¤Ï¥Ó¥Ç¥ª¥á¥â¥ê
+¤ò¥ê¥Ë¥¢¤Ë³ä¤êÅö¤Æ¤ë»ö¤¬½ÐÍè¤ë»ö¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤³¤Î¤ä¤êÊý¤ò»È¤¦
+¾ì¹ç¤Ï¥µ¡¼¥Ð¡¼¤ÎÀ­Ç½¤ò¸þ¾å¤µ¤»¤Þ¤¹¤¬¡¢¸½ºß¤Ï¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó¡£¸Î
+¤Ë¿·¤·¤¤¥Á¥Ã¥×¥»¥Ã¥È¤Î¤³¤Îµ¡Ç½¤Ï»ÈÍѽÐÍè¤Þ¤»¤ó¡£
+
+<!--Most SVGA chipsets have two bank registers. This is the most desirable
+structure (if any banking structure can be called ``desirable''), because
+data can be moved from one area of the screen to another with a simple
+`mov' instruction. There are two forms of dual-banking - one where the
+two bank operations define a read-only bank and a write-only bank, and
+one with two read/write windows. With the first form, the entire SVGA
+memory window is used for both read a write operations, and the two
+bank registers determine which bank is actually used (e.g. ET3000, ET4000).
+With the second form, the SVGA memory window is split into two read/write
+banks, with each bank pointer being used to control one window. In
+this case, one window is used for read operations and the other for write
+operations (e.g. PVGA1/Western Digital, Cirrus).-->
+ËØ¤É¤Î SVGA ¥Á¥Ã¥×¥»¥Ã¥È¤ÏÆó¤Ä¤Î¥Ð¥ó¥¯¥ì¥¸¥¹¥¿¤ò»ý¤Ã¤Æ¤¤¤Þ¤¹¡£¥Ç¡¼
+¥¿¤ò²èÌ̤Τ¢¤ëÎΰ褫¤é¾¤ÎÎΰè¤Ëñ½ã¤Ë 'mov' Ì¿Îá¤Ç°Üư½ÐÍè¤ë¤Î¤Ç
+Èó¾ï¤Ë˾¤Þ¤·¤¤¹½Â¤¤Ç¤¹¡Ê¤É¤ó¤Ê¥Ð¥ó¥¯¹½Â¤¤â ``˾¤Þ¤·¤¤'' ¤È¸Æ¤ó¤Ç¤¤
+¤Þ¤¹¡Ë¡£Æó½Å²½¥Ð¥ó¥­¥ó¥°(dual-banking) ¤ÏÆó¤Ä¤ÎÊý¼°¤¬¤¢¤ê¡¢°ìÊý¤Ï
+ÆÉ¤ß¹þ¤ßÀìÍѥХ󥯤Ƚñ¤­¹þ¤ßÀìÍÑ¥Ð¥ó¥¯¤ÎÆó¤Ä¤Î¥Ð¥ó¥¯Áàºî¤Ç¡¢¤â¤¦°ì
+Êý¤ÏÆó¤Ä¤Î½ñ¤­¹þ¤ß¡¿ÆÉ¤ß¹þ¤ß·óÍÑÁë¤Ç¤¹¡£ºÇ½é¤ÎÊý¼°¤ÏÁ´¤Æ¤Î SVGA ¥á
+¥â¥êÁë¤òÆÉ¤ß¹þ¤ß¤È½ñ¤­¹þ¤ßξÊý¤Ë»È¤¤¡¢Æó¤Ä¤Î¥Ð¥ó¥¯¥ì¥¸¥¹¥¿¤Ï¤É¤Á¤é
+¤Î¥Ð¥ó¥¯¤ò¼ÂºÝ¤Ë»È¤¦¤Î¤«¡ÊÎ㤨¤ÐET3000, ET4000 ¤Ç¤Ï¡Ë·èÄꤹ¤ë¤Î¤Ë
+»ÈÍѤ·¤Æ¤¤¤Þ¤¹¡£ÆóÈÖÌܤÎÊý¼°¤Ç¤Ï SVGA ¥á¥â¥êÁë¤òÆÉ¤ß¹þ¤ß¡¿½ñ¤­¹þ¤ß
+²Äǽ¤ÊÆó¤Ä¤Î¥Ð¥ó¥¯¤Ëʬ¤±¤É¤Á¤é¤«¤Î¥Ð¥ó¥¯¥Ý¥¤¥ó¥¿¤¬°ì¤Ä¤ÎÁë¤òÀ©¸æ¤¹
+¤ë¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£¤³¤Î¾ì¹ç°ì¤Ä¤ÎÁ뤬ÆÉ¤ß¹þ¤ßÁàºî¤ò¹Ô¤¦¤È¤­¤Ï¾
+¤ÎÁ뤬½ñ¤­¹þ¤ßÁàºî¤ò¡ÊÎ㤨¤Ð PVGA1/Western Digital, Cirrus ¤Ç¤Ï¡Ë¹Ô
+¤¦¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
+
+<!--A chipset that has a single bank register uses that one bank for both
+read and write access. This is problematic, because copying information
+from one part of the screen to another requires that the data be read in,
+stored, and then written out. Fortunately, the server is able to handle
+both one-bank and two-bank chipsets; the determination of behavior is
+defined by an entry in the driver data structure described below.-->
+ñ°ì¤Î¥Ð¥ó¥¯¥ì¥¸¥¹¥¿¤ò»ý¤Ã¤Æ¤¤¤ë¥Á¥Ã¥×¥»¥Ã¥È¤Ï°ì¤Ä¤Î¥Ð¥ó¥¯¤Ø¤ÎÆÉ¤ß
+¹þ¤ß¤È½ñ¤­¹þ¤ß¤ÎξÊý¤Î¥¢¥¯¥»¥¹¤ò¹Ô¤¤¤Þ¤¹¡£²èÌ̤ΰìÉô¤Î¾ðÊó¤ò¾¤ÎÉô
+ʬ¤Ø¥³¥Ô¡¼¤¹¤ë»ö¤Ï¥Ç¡¼¥¿¤òÆÉ¤ß¹þ¤ß¡¢Ãߤ¨¡¢¤½¤ì¤«¤é½ñ¤­½Ð¤¹¤È¤¤¤¦¼ê
+½ç¤¬Í׵ᤵ¤ì¤ë¤¿¤áº¤Æñ¤Ç¤¹¡£¹¬±¿¤Ë¤â¡¢¥µ¡¼¥Ð¡¼¤Ï°ì¤Ä¤Î¥Ð¥ó¥¯¤Î¥Á¥Ã
+¥×¥»¥Ã¥È¤ÈÆó¤Ä¤Î¥Ð¥ó¥¯¤Î¥Á¥Ã¥×¥»¥Ã¥È¤ÎξÊý¤ò°·¤¨¡¢¤½¤Îµóư¤ò¼¡¤ËÀâ
+ÌÀ¤¹¤ë¥É¥é¥¤¥Ð¥Ç¡¼¥¿¹½Â¤¤Î¹àÌÜÄêµÁ¤Ç·èÄꤷ¤Þ¤¹¡£
+
+<!--A driver requires that three assembly-language functions be written, in
+the file `<tt>sdc_bank.s</tt>'.
+These functions set the read bank - <bf>SDCSetRead()</bf>,
+the write bank - <bf>SDCSetWrite()</bf>, and set both banks -
+<bf>SDCSetReadWrite()</bf>.
+For a chipset with only one bank, all three will be declared as entry points
+to the same function (see the ``tvga8900'' driver for an example).-->
+¥É¥é¥¤¥Ð¤Ë¤Ï`<tt>sdc_bank.s</tt>' ¥Õ¥¡¥¤¥ëÆâ¤Î»°¤Ä¤Î¥¢¥»¥ó¥Ö¥é¸À¸ì
+¤Ç½ñ¤¤¤Æ¤¢¤ë´Ø¿ô¤¬É¬ÍפǤ¹¡£
+¤³¤ì¤é¤Î´Ø¿ô¤Ï¥Ð¥ó¥¯ÆÉ¤ß¹þ¤ßÀßÄê - <bf>SDCSetRead()</bf>,
+¥Ð¥ó¥¯½ñ¤­¹þ¤ß - <bf>SDCSetWrite()</bf> ¤È ξ¥Ð¥ó¥¯ÀßÄê -
+<bf>SDCSetReadWrite()</bf> ¤Ç¤¹¡£
+°ì¤Ä¤Î¥Ð¥ó¥¯¤À¤±¤Î¥Á¥Ã¥×¥»¥Ã¥ÈÍѤ˻°¤ÄÁ´¤Æ¤Î´Ø¿ô¤ÎÆþ¤ê¸ýÅÀ¤òƱ¤¸´Ø
+¿ô¤ËÀë¸À¤Ç¤­¤ë¤Ç¤·¤ç¤¦(``tvga8900'' ¥É¥é¥¤¥Ð¤òÎã¤È¤·¤Æ»²¾È¤·¤Æ¤¯¤À
+¤µ¤¤)¡£
+
+<!--The functions are fairly simple - the bank number is passed to the function
+in register &percnt;al. The function will shift, bitmask, etc - whatever is
+required to put the bank number into the correct form - and then write
+it to the correct I/O port. For chipsets where the two banks are read-only
+HERE
+and write-only, the <bf>SetReadWrite()</bf> function will have to do this
+twice - once
+for each bank. For chipsets with two independent read/write windows, the
+<bf>SetReadWrite()</bf> function should use the same bank as the
+<bf>SetWrite()</bf> function.-->
+´Ø¿ô¤Ï¤«¤Ê¤êñ½ã¤Ç - ¥Ð¥ó¥¯ÈÖ¹æ¤ò´Ø¿ô¤Î &percnt;al ¥ì¥¸¥¹¥¿¤ØÅϤ·¡¢
+´Ø¿ô¤Ï¥·¥Õ¥È¤ä¥Ó¥Ã¥È¥Þ¥¹¥¯Åù¹Ô¤¤Àµ¤·¤¤·Á¼°¤Ç¥Ð¥ó¥¯ÈÖ¹æ¤ò¥ì¥¸¥¹¥¿¥Ø
+Êݸ¤·¡¢Àµ¤·¤¤ I/O ¥Ý¡¼¥È¤Ø½ñ¤­¹þ¤ß¤Þ¤¹¡£Æó¤Ä¤Î¥Ð¥ó¥¯¤¬ÆÉ¤ß¹þ¤ßÀì
+ÍѤȽñ¤­¹þ¤ßÀìÍѤˤʤäƤ¤¤ë¥Á¥Ã¥×¥»¥Ã¥È¤Î¾ì¹ç¡¢°ì²ó¤Å¤Ä³Æ¡¹¤Î¥Ð¥ó
+¥¯¤Ë¡¢·×Æó²ó <bf>SetReadWrite()</bf>´Ø¿ô¤ò¼Â¹Ô¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+Æó¤Ä¤ÎÆÈΩ¤ÊÆÉ¤ß¹þ¤ß¡¿½ñ¤­¹þ¤ßÁë¤Ë¤Ê¤Ã¤Æ¤¤¤ë¥Á¥Ã¥×¥»¥Ã¥È¤Î¾ì¹ç¡¢
+<bf>SetReadWrite()</bf> ´Ø¿ô¤ò <bf>SetWrite()</bf> ´Ø¿ô¤ÎÂå¤ï¤ê¤Ë
+Ʊ¤¸¥Ð¥ó¥¯¤Ë¼Â¹Ô¤¹¤ë¤Ù¤­¤Ç¤¹¡£
+
+<!--A special note - these functions MUST be written in the macroized assembler
+format defined in the header file ``assyntax.h''. This will ensure that
+the correct assembler code will be generated, regardless of OS. This
+macroized format currently supports USL, GNU, and Intel assembler formats.-->
+ÆÃÊ̤ÊÃí°Õ¤È¤·¤Æ¡¢¤³¤ì¤é¤Î´Ø¿ô¤Ï ``assyntax.h'' ¥Õ¥¡¥¤¥ë¤ËÄêµÁ¤·¤Æ
+¤¤¤ë¥Þ¥¯¥í¥¢¥»¥ó¥Ö¥é¤Î½ñ¼°¤Ç½ñ¤¯É¬Íפ¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤Ï OS ¤Ë´Ø·¸¤Ê
+¤¯Àµ¤·¤¤¥¢¥»¥ó¥Ö¥é¥³¡¼¥É¤òÀ¸À®¤¹¤ë¤³¤È¤òÊݾڤ¹¤ë°Ù¤Ç¤¹¡£¸½ºß¡¢¤³¤Î
+¥Þ¥¯¥í·Á¼°¤Ï USL, GNU ¤È ¥¤¥ó¥Æ¥ë¤Î¥¢¥»¥ó¥Ö¥é¤Î½ñ¼°¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤
+¤Þ¤¹¡£
+
+<!--That's all there is to the banking functions. Usually the chipset reference
+will give examples of this code; if not, it is not difficult to figure out,
+especially using the other drivers as examples.-->
+°Ê¾å¤¬¥Ð¥ó¥¯µ¡Ç½¤Ë´Ø¤¹¤ëºî¶È¤Ç¤¹¡£ÉáÄÌ¡¢¥Á¥Ã¥×¥»¥Ã¥È¤Î»²¹Í½ñ¤¬¤³¤Î
+¥×¥í¥°¥é¥à¤ÎÎãÂê¤ò·ÇºÜ¤·¤Æ¤¤¤Þ¤¹¤¬¡¢¤½¤¦¤Ç¤Ê¤¤¾ì¹ç¤Ç¤â¾¤Î¥É¥é¥¤¥Ð
+¤ÎÎã¤òÍѤ¤¤ì¤ÐÁÛÁü¤¹¤ë¤Î¤ÏÆñ¤·¤¯¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+
+<!--<sect> The Driver Itself <p>-->
+<sect> ¥É¥é¥¤¥Ð¼«¿È¤Ë¤Ä¤¤¤Æ <p>
+<!-- Now it's time to get down to the real work - writing the major driver
+functions in the files sdc_driver.c. First, an overview of what the
+responsibilities of the driver are:-->
+¤µ¤Æ¡¢ËÜÍè¤Îºî¶È¤Ç¤¢¤ëËØ¤É¤Î¥É¥é¥¤¥Ð¤Îµ¡Ç½¤ò sdc_driver.c ¥Õ¥¡¥¤¥ë
+¤Ë½ñ¤¯Ãʳ¬¤ËÍè¤Þ¤·¤¿¡£À褺¡¢¥É¥é¥¤¥Ð¤Î¼ç¤Êµ¡Ç½¤Î³µÍפϼ¡¤Î¤È¤ª¤ê:
+
+<enum>
+<!--<item> Provide a chipset-descriptor data structure to the server. This
+ data structure contains pointers to the driver functions and
+ some data-structure initialization as well.-->
+<item> ¥µ¡¼¥Ð¡¼¤Î¥Á¥Ã¥×¥»¥Ã¥Èµ­½Ò»Ò¤Î¥Ç¡¼¥¿¹½Â¤¤òÄ󶡤·¤Þ¤¹¡£
+ ¤³¤Î¥Ç¡¼¥¿¹½Â¤¤Ï¥É¥é¥¤¥Ð´Ø¿ô¤Ø¤Î¥Ý¥¤¥ó¥¿¤È¤¤¤¯¤Ä¤«¤Î¥Ç¡¼¥¿
+ ¹½Â¤¤Î½é´üÃͤâ´Þ¤ß¤Þ¤¹¡£
+<!--<item> Provide a driver-local data structure to hold the contents of
+ the chipset registers. This data structure will contain a
+ generic part and a driver-specific part. It is used to save the
+ initial chipset state, and is initialized by the driver to put
+ the chipset into different modes.-->
+<item> ¥É¥é¥¤¥Ð¸ÇÍ­¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Î¥ì¥¸¥¹¥¿¤Î¥Ç¡¼¥¿¹½Â¤¤òÄ󶡤·
+ ¤Þ¤¹¡£¤³¤Î¥Ç¡¼¥¿¹½Â¤¤Ë¤Ï°ìÈÌŪ¤ÊÉôʬ¤È¥É¥é¥¤¥Ð¸ÇÍ­¤ÎÉôʬ¤¬¤¢
+ ¤ê¤Þ¤¹¡£¥Á¥Ã¥×¥»¥Ã¥È¤Î½é´ü¾õÂÖ¤òÊݸ¤·¤¿¤ê¡¢Â¾¤Î¥â¡¼¥É¤Ë¥Á¥Ã
+ ¥×¥»¥Ã¥È¤òÊѤ¨¤ë¤È¤­¤Ë½é´ü²½¤¹¤ë¤Î¤ËÍѤ¤¤Þ¤¹¡£
+<!--<item> Provide an identification function that the server will call to
+ list the chipsets that the driver is capable of supporting.-->
+<item> ¥É¥é¥¤¥Ð¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¥Á¥Ã¥×¥»¥Ã¥È¤Î°ìÍ÷¤ò¸Æ¤Ó½Ð¤»¤ë
+ ¤è¤¦¤Ê¼±Ê̵¡Ç½¤òÄ󶡤·¤Þ¤¹¡£
+<!--<item> Provide a probe function that will identify this chipset as
+ different from all others, and return a positive response if
+ the chipset this driver supports is installed, and a negative
+ response otherwise.-->
+<item> ¾¤Î¥Á¥Ã¥×¥»¥Ã¥È¤È°Û¤Ê¤ë¤È¤¤¤¦¤³¤È¤òǧ¼±¤·¤Æ¥É¥é¥¤¥Ð¤¬
+ ¤½¤Î¥Á¥Ã¥×¥»¥Ã¥È¤ò¥µ¥Ý¡¼¥È¤·¥¤¥ó¥¹¥È¡¼¥ë¤·¤Æ¤¢¤ì¤ÐÀµ¤Î±þÅú
+ ¤ò¤·¡¢¤½¤¦¤Ç¤Ê¤±¤ì¤ÐÉé¤Î±þÅú¤ò¤¹¤ëõººµ¡Ç½¤òÄ󶡤·¤Þ¤¹¡£
+<!--<item> Provide a function to select dot-clocks available on the board.-->
+<item> ¥Ü¡¼¥É¤Ç²Äǽ¤Ê¥É¥Ã¥È¥¯¥í¥Ã¥¯¤òÁªÂò¤¹¤ëµ¡Ç½¤òÄ󶡤·¤Þ¤¹¡£
+<!--<item> Provide functions to save, restore, and initialize the driver-
+ local data structure.-->
+<item> ¥É¥é¥¤¥Ð¤Ë°Í¸¤¹¤ë¥Ç¡¼¥¿¹½Â¤¤òÊݸ¡¢²óÉü¡¢½é´ü²½¤¹¤ëµ¡Ç½¤ò
+ Ä󶡤·¤Þ¤¹¡£
+<!--<item> Provide a function to set the starting address for display in
+ the video memory. This implements the virtual-screen for the
+ server.-->
+<item> ¥Ó¥Ç¥ª¥á¥â¥êÆâ¤Ë¥Ç¥£¥¹¥×¥ì¥¤¤Î³«»Ï¥¢¥É¥ì¥¹¤òÀßÄꤹ¤ëµ¡Ç½
+ ¤òÄ󶡤·¤Þ¤¹¡£¤³¤ì¤Ï¥µ¡¼¥Ð¡¼¤Ë²¾ÁÛ¥¹¥¯¥ê¡¼¥ó¤ò¼Â¸½¤·¤Þ¤¹¡£
+<!--<item> Perhaps provide a function for use during VT-switching.-->
+<item> VT ÀÚ¤êÂØ¤¨¤ò¹Ô¤¦µ¡Ç½¤òÄ󶡤¹¤ë¤Ç¤·¤ç¤¦¡£
+<!--<item> Perhaps provide a function to check if each mode is suitable for
+ the chipset being used.-->
+<item> ¥â¡¼¥É¤¬¥Á¥Ã¥×¥»¥Ã¥È¤Î»ÈÍѤ¹¤ë³Æ¡¹¤Î¥â¡¼¥É¤Ë°ìÃפ¹¤ë¤«
+ ¥Á¥§¥Ã¥¯¤¹¤ëµ¡Ç½¤òÄ󶡤¹¤ë¤Ç¤·¤ç¤¦¡£
+</enum>
+
+<!--Before stepping through the driver file in detail, here are some important
+issues:-->
+¾ÜºÙ¤Ë¥É¥é¥¤¥Ð¡¼¤Î¥Õ¥¡¥¤¥ë¤òÄɤ¤¤«¤±¤ëÁ°¤Ë¡¢½ÅÍפʾðÊ󤬤³¤³¤Ë¤¢¤ê
+¤Þ¤¹:
+
+<enum>
+<!--<item> If your driver supports both the color and monochrome servers,
+ you should take care of both cases in the same file. Most things
+ are the same - you can differentiate between the two with the
+ MONOVGA <tt>&num;define</tt>. If the 16 color server is supported,
+ code specific to it can be enabled with the XF86VGA16
+ <tt>&num;define</tt>. In most cases it is sufficient to put
+ the following near the top of the stub_driver.c file:-->
+<item> ¥É¥é¥¤¥Ð¤¬¥«¥é¡¼¤È¥â¥Î¥¯¥í¥µ¡¼¥Ð¡¼¤ÎξÊý¤ò¥µ¥Ý¡¼¥È¤¹¤ë
+ ¾ì¹ç¡¢°ì¤Ä¤Î¥Õ¥¡¥¤¥ë¤ËξÊý¤Î»öÎ㤬´Þ¤Þ¤ì¤Æ¤¤¤ë¤³¤È¤ËÃí°Õ¤·
+ ¤Æ¤¯¤À¤µ¤¤¡£¤³¤ì¤é¤ÏËØ¤ÉƱ¤¸¤Ç¤¹¤¬¡¢MONOVGA ¤ò
+ <tt>&num;define</tt> ¤·¤Æ¤¢¤ë½ê¤Çξ¼Ô¤ò¶èÊ̤¹¤ë¤³¤È¤¬½ÐÍè¤Þ
+ ¤¹¡£16 ¿§¥µ¡¼¥Ð¡¼¤ò¥µ¥Ý¡¼¥È¤¹¤ë¾ì¹ç¡¢XF86VGA16 ¤Î
+ <tt>&num;define</tt> ¤¬Í­¸ú¤Ë¤Ê¤ë¤è¤¦¤Ë¥×¥í¥°¥é¥à¤Ë»ØÄꤷ¤Æ
+ ¤¯¤À¤µ¤¤¡£Ëؤɤξì¹ç¡¢¼¡¤ò stub_driver.c ¥Õ¥¡¥¤¥ë¤ÎÀèÆ¬¶á¤¯
+ ¤Ë»ØÄꤹ¤ë»ö¤Ç½¼Ê¬¤Ç¤¹¡£
+<verb>
+ #ifdef XF86VGA16
+ #define MONOVGA
+ #endif
+</verb>
+
+<!--<item> The color server uses the SVGA's 8-bit packed-pixel mode. Thes
+ monochrome and vga16 servers uses the VGA's 16-color mode
+ (4 bit-planes). Only one plane is enabled for the monochrome
+ server.-->
+<item> ¥«¥é¡¼¥µ¡¼¥Ð¡¼¤Ï SVGA ¤Î 8-¥Ó¥Ã¥È¥Ñ¥Ã¥¯¥È¥Ô¥¯¥»¥ë¥â¡¼¥É
+ ¤ò»ÈÍѤ·¤Þ¤¹¡£¥â¥Î¥¯¥í¤È vga16 ¥µ¡¼¥Ð¡¼¤Ï VGA ¤Î 16-¿§¥â¡¼¥É
+ ¡Ê4 ¥Ó¥Ã¥È¥×¥ì¡¼¥ó¡Ë¤ò»ÈÍѤ·¤Þ¤¹¡£¥â¥Î¥¯¥í¥µ¡¼¥Ð¡¼¤Ç¤Ï 1 ¥×
+ ¥ì¡¼¥ó¤À¤±»ÈÍѤ·¤Þ¤¹¡£
+ [ ÌõÃí : ¥Ñ¥Ã¥¯¥È¥Ô¥¯¥»¥ë¡§ 1 ¥É¥Ã¥È¤Î¥Ô¥¯¥»¥ë¡Ê²èÌ̾å¤ÎÅÀ¡Ë
+ ¤òɽ¸½¤¹¤ë¤Î¤Ë¡¢Ï¢Â³¤·¤¿ 8 ¥Ó¥Ã¥È¤ò 4 ¤Äʤ٤ÆÉ½¤ï¤¹Êý¼°¡£
+ 4 ¥Ó¥Ã¥È¥×¥ì¡¼¥ó¡§ 1 ¥É¥Ã¥È¤òɽ¤ï¤¹¤Î¤Ë¡¢¤½¤ì¤¾¤ì¤Î¿§Ëè¤Ë¥×
+ ¥ì¡¼¥ó¤ò»ý¤Á³Æ¥×¥ì¡¼¥ó¾å¤ÎϢ³¤·¤Ê¤¤ 8 ¥Ó¥Ã¥È 4 ¤Ä¤ò»È¤Ã¤Æ
+ ɽ¤ï¤¹Êý¼°¡£]
+<!--<item> It is possible for you to define your monochrome driver so that
+ no bank-switching is done. This is not particularly desirable,
+ as it yields only 64k of viewing area.-->
+<item> ¥Ð¥ó¥¯ÀÚ¤êÂØ¤¨¤ò»È¤ï¤Ê¤¤¤è¤¦¤Ë¡¢¥â¥Î¥¯¥í¥µ¡¼¥Ð¡¼¤òÀßÄê
+ ¤Ç¤­¤Þ¤¹¡£¤³¤ì¤Ïɽ¼¨Îΰè¤Î¥á¥â¥ê¤ò¤¿¤Ã¤¿ 64k ¤Ë½ÐÍè¤ë»ö°Ê³°
+ ¤ÏÆÃ¤ËÌ¥ÎÏŪ¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+</enum>
+<!--Keeping these things in mind, you need to find the registers from your
+SVGA chipset that control the desired features. In particular, registers
+that control:-->
+¤³¤ì¤é¤òƧ¤Þ¤¨¤Æ¡¢½êÄê¤Îµ¡Ç½¤òÀ©¸æ¤¹¤ë¥Á¥Ã¥×¥»¥Ã¥È¤«¤é¥ì¥¸¥¹¥¿¤òõ
+¤¹É¬Íפ¬¤¢¤ê¤Þ¤¹¡£ÆÃ¤Ë¡¢¥ì¥¸¥¹¥¿¤Ï°Ê²¼¤òÀ©¸æ¤·¤Þ¤¹:
+<enum>
+<!--<item> Clock select bits. The two low-order bits are part of the
+ standard Miscellaneous Output Register; most SVGA chipsets
+ will include 1 or 2 more bits, allowing the use of 8 or 16
+ discrete clocks.-->
+<item> ¥¯¥í¥Ã¥¯ÁªÂò¥Ó¥Ã¥È¡£Äã°Ì¤Î 2 ¥Ó¥Ã¥È¤Ïɸ½à¤Î¡ÊËØ¤É¤Î
+SVGA ¥Á¥Ã¥×¥»¥Ã¥È¤¬ 1 ¼ã¤¯¤Ï 2 ¥Ó¥Ã¥È°Ê¾å»ý¤Ã¤Æ¤¤¤ë¡Ë¼þÊÕµ¡´ï½ÐÎÏ
+¥ì¥¸¥¹¥¿(Miscellaneous Output Register) ¤Î°ìÉô¤Ç¡¢8 ¤« 16 ¤Ëʬ²ò¤·
+¤¿¥¯¥í¥Ã¥¯¤ò»È¤¦¤è¤¦¤ËÀßÄꤷ¤Þ¤¹¡£
+<!--<item> Bank selection. The SVGA chipset will have one or two registers
+ that control read/write bank selection.-->
+<item> ¥Ð¥ó¥¯ÁªÂò¡£ÆÉ¤ß½ñ¤­¤¹¤ë¥Ð¥ó¥¯ÁªÂò¤ÎÀ©¸æ¤ò¹Ô¤¦¥ì¥¸¥¹¥¿¤ò
+ SVGA ¥Á¥Ã¥×¥»¥Ã¥È¤Ï°ì¤Ä¤«Æó¤Ä»ý¤Ã¤Æ¤¤¤ë¤Ç¤·¤ç¤¦¡£
+<!--<item> CRTC extensions. The standard VGA registers don't have enough
+ bits to address large displays. So the SVGA chipsets have
+ extension bits.-->
+<item> CRTC µ¡Ç½³ÈÄ¥¡£É¸½àŪ¤Ê VGA ¥ì¥¸¥¹¥¿¤ÏÂ礭¤Êɽ¼¨¤ò¹Ô¤¦¤Î¤Ë½½Ê¬¤Ê¥Ó¥Ã
+ ¥È¿ô¤ò»ý¤Ã¤Æ¤¤¤Þ¤»¤ó¡£¸Î¤Ë SVGA ¥Á¥Ã¥×¥»¥Ã¥È¤Ï³ÈÄ¥¤·¤¿¥Ó¥Ã¥È¿ô¤ò»ý¤Ã¤Æ¤¤
+ ¤Þ¤¹¡£
+<!--<item> Interlaced mode. Standard VGA does not support interlaced
+ displays. So the SVGA chipset will have a bit somewhere to
+ control interlaced mode. Some chipsets require additional
+ registers to be set up to control interlaced mode-->
+<item> ¥¤¥ó¥¿¡¼¥ì¡¼¥¹¥â¡¼¥É¡£É¸½àŪ¤Ê VGA ¤Ï¥¤¥ó¥¿¡¼¥ì¡¼¥¹É½¼¨
+ ¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó¡£¸Î¤Ë SVGA ¥Á¥Ã¥×¥»¥Ã¥È¤Ï¥¤¥ó¥¿¡¼¥ì¡¼
+ ¥¹¥â¡¼¥É¤òÀ©¸æ¤¹¤ë¥Ó¥Ã¥È¤ò»ý¤Ã¤Æ¤¤¤Þ¤¹¡£¥¤¥ó¥¿¡¼¥ì¡¼¥¹¥â¡¼¥É
+ À©¸æÍѤÎÀßÄê¤ò¹Ô¤¦¥ì¥¸¥¹¥¿¤òÄɲ䷤Ƥ¤¤ë¤¤¤¯¤Ä¤«¤Î¥Á¥Ã¥×¥»¥Ã
+ ¥È¤¬¤¢¤ê¤Þ¤¹¡£
+<!--<item> Starting address. The standard VGA only has 16 bits in which
+ to specify the starting address for the display. This restricts
+ the screen size usable by the virtual screen feature. The SVGA
+ chipset will usually provide one or more extension bits.-->
+<item> ³«»Ï¥¢¥É¥ì¥¹¡£É¸½àŪ¤Ê VGA ¤À¤±¤Ïɽ¼¨ÍÑ¥á¥â¥ê¤Î³«»Ï¥¢¥É¥ì
+ ¥¹¤ò»ØÄꤹ¤ë¤Î¤Ë 16 ¥Ó¥Ã¥È¤Î¥¢¥É¥ì¥¹¤ò»È¤¤¤Þ¤¹¡£¤³¤ì¤Ï²¾ÁÛ¥¹
+ ¥¯¥ê¡¼¥óµ¡Ç½¤Ç»È¤¦¥¹¥¯¥ê¡¼¥ó¤Î¥µ¥¤¥º¤òÀ©¸Â¤·¤Þ¤¹¡£SVGA ¥Á¥Ã
+ ¥×¥»¥Ã¥È¤ÏÄ̾ï°ì¤Ä¤«¤½¤ì°Ê¾å¤Î³ÈÄ¥¥Ó¥Ã¥È¤ò»ý¤Ã¤Æ¤¤¤Þ¤¹¡£
+<!--<item> Lock registers. Many SVGA chipset prevent modification of
+ extended registers unless the registers are first ``unlocked''.
+ You will need to disable protection of any registers you will
+ need for other purposes.-->
+<item> ¥ì¥¸¥¹¥¿¥í¥Ã¥¯¡£ËؤɤΠSVGA ¥Á¥Ã¥×¥»¥Ã¥È¤Ï¥ì¥¸¥¹¥¿¤òºÇ½é¤Ë
+ ``unlocked'' ¤Ë¤·¤Ê¤¤¸Â¤ê³ÈÄ¥¥ì¥¸¥¹¥¿¤Î¹¹¿·¤òËɻߤ·¤Þ¤¹¡£
+ ²¿¤«°Õ¿Þ¤ò»ý¤Ã¤Æ¥ì¥¸¥¹¥¿¤ÎÊݸî¤ò̵¸ú¤Ë¤·¤¿¤¤»þ¤ËɬÍפˤʤê¤Þ¤¹¡£
+<!--<item> Any other facilities. Some chipset may, for example, require
+ that certain bits be set before you can access extended VGA
+ memory (beyond the IBM-standard 256k). Or other facilities;
+ read through all of the extended register descriptions and see
+ if anything important leaps out at you.-->
+<item> ¤½¤Î¾¤Îµ¡Ç½¡£Î㤨¤Ð¡¢¤¤¤¯¤Ä¤«¤Î¥Á¥Ã¥×¥»¥Ã¥È¤¬³ÈÄ¥ VGA
+ ¥á¥â¥ê¤ò¡ÊIBM-ɸ½à¤Î 265k ¤òͤ¨¤Æ¡Ë¥¢¥¯¥»¥¹¤·¤¿¤¤»þ¡¢Àµ¤·¤¤
+ ¥Ó¥Ã¥È¤òÀßÄꤹ¤ëɬÍפ¬¤¢¤ë¤Ç¤·¤ç¤¦¡£¤Þ¤¿¤ÏÁ´¤Æ¤Î³ÈÄ¥¥ì¥¸¥¹¥¿
+ ¤ÎÆâÍÆ¤òÆÉ¤ß¼è¤ë¤È¤«¡¢ÌܤËα¤Þ¤Ã¤¿½ÅÍפʲ¿¤«¤ò¸«¤ëÅù¤Î¾¤Îµ¡
+ ǽ¤¬¤¢¤ë¤Ç¤·¤ç¤¦¡£
+</enum>
+
+<!--If you are fortunate, the chipset vendor will include in the databook some
+tables of register settings for various BIOS modes. You can learn a lot
+about what manipulations you must do by looking at the various BIOS modes.-->
+±¿¤¬¤è¤±¤ì¤Ð¡¢¥Á¥Ã¥×¥»¥Ã¥È¤Î¥Ù¥ó¥À¡¼¤Î¥Ç¡¼¥¿¥Ö¥Ã¥¯¤ËÍÍ¡¹¤Ê BIOS ¥â¡¼
+¥ÉÍѤΥ쥸¥¹¥¿¤ÎÀßÄê¤Îɽ¤¬·ÇºÜ¤µ¤ì¤Æ¤¤¤ë¤Ç¤·¤ç¤¦¡£ÍÍ¡¹¤Ê BIOS ¥â¡¼¥É
+¤Ç¤É¤ó¤ÊÁàºî¤¬²Äǽ¤Ç¤¢¤ë¤«³Ø½¬¤¹¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡£
+
+<!--<sect1> Multiple Chipsets And Options <p>-->
+<sect1> Ê£¿ô¤Î¥Á¥Ã¥×¥»¥Ã¥È¤È¥ª¥×¥·¥ç¥ó <p>
+<!--It is possible, and in fact desirable, to have a single driver support
+multiple chipsets from the same vendor. If there are multiple supported
+chipsets, then you would have a series of &num;define's for them, and a
+variable `SDCchipset', which would be used throughout the driver when
+distinctions must be made. See the Trident and PVGA1/WD drivers for
+examples (the Tseng ET3000 and ET4000 are counter-examples - these were
+implemented before the driver interface allowed for multiple chipsets, so
+this example should NOT be followed). Note that you should only distinguish
+versions when your driver needs to do things differently for them. For
+example, suppose the SDC driver supports the SDC-1a, SDC-1b, and SDC-2
+chipsets. The -1a and -1b are essentially the same, but different from the
+-2 chipset. Your driver should support the -1 and -2 chipsets, and not
+distinguish between the -1a and -1a. This will simplify things for the
+end user.-->
+Ʊ¤¸¥Ù¥ó¥À¡¼¤«¤é½Ð²Ù¤·¤Æ¤¤¤ëÊ£¿ô¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ïñ°ì¤Î¥É¥é¥¤¥Ð¤Ç¥µ
+¥Ý¡¼¥È²Äǽ¤Ç¡¢¼ÂºÝÌ¥ÎÏŪ¤Ç¤¹¡£Ê£¿ô¤Î¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¥Á¥Ã¥×¥»¥Ã¥È¤¬
+¤¢¤ë¾ì¹ç¡¢°ìÏ¢¤ÎÂбþ¤¹¤ë &num;define ¤È¥É¥é¥¤¥Ð¤ò¼±Ê̤¹¤ë°Ù¤ÎÊÑ¿ô¤Î
+`SDCchipset' ¤òÊÝ»ý¤·¤Æ²¼¤µ¤¤¡£Trident ¤È PVGA1/WD ¤òÎãÂê¤È¤·¤Æ¸«¤Æ
+¤¯¤À¤µ¤¤¡ÊTseng ET3000 ¤È ET4000¤ÏµÕ¤Î°ÕÌ£¤Ç¤ÎÎãÂê¤Ç¤¹¡£¤Ä¤Þ¤êÊ£¿ô
+¤Î¥Á¥Ã¥×¥»¥Ã¥È¤ËÂбþ¤·¤¿¥É¥é¥¤¥Ð¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤¬³«È¯¤µ¤ì¤ëÁ°¤Ë¼Â
+¸½¤·¤Æ¤·¤Þ¤¤¤Þ¤·¤¿¡£½¾¤Ã¤Æ¤³¤Î¾ì¹ç¤Ï¤â¤¦¥Õ¥©¥í¡¼½ÐÍè¤Þ¤»¤ó¡£¡Ë¡£ÄÉ
+²Ã¤¹¤ë¥É¥é¥¤¥Ð¤Ï¤³¤ì¤é¤È°Û¤Ê¤ë¤è¤¦¤Ëºî¶È¤ò¤¹¤ë¤È¤­¤Ï¥Ð¡¼¥¸¥ç¥ó¤ò°Õ
+¼±¤¹¤ë¤À¤±¤ÇÎɤ¤¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£Î㤨¤Ð¡¢SDC ¥É¥é¥¤¥Ð¤¬
+SDC-1a,SDC-1b ¤È SDC-2 ¤Î¥Á¥Ã¥×¥»¥Ã¥È¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¤È²¾Äꤷ¤Æ²¼
+¤µ¤¤¡£¤³¤Î -1a ¤È-1b ¤ÏËܼÁŪ¤Ë¤ÏƱ°ì¤Ç¤¹¤¬¡¢-2 ¤È¤Ï°Û¤Ê¤ê¤Þ¤¹¡£ÄÉ
+²Ã¤¹¤ë¥É¥é¥¤¥Ð¤¬ -1 ¤È -2 ¤Î¥Á¥Ã¥×¥»¥Ã¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ì¤Ð¡¢-1a ¤È -1b
+¤Î°ã¤¤¤ò°Õ¼±¤·¤Ê¤¯¤Æ¤âÎɤ¤¤Ç¤·¤ç¤¦¡£¤³¤Î»ö¤Ï¥¨¥ó¥É¥æ¡¼¥¶¤Îºî¶È¤ò´Ê
+ñ¤Ë¤·¤Þ¤¹¡£
+
+<!--In cases where you want to give the user control of driver behavior, or
+there are things that cannot be determined without user intervention, you
+should use ``option'' flags. Say that board vendors that use the SDC
+chipsets have the option of providing 8 or 16 clocks. There's no way you
+can determine this from the chipset probe, so you provide an option flag to
+let the user select the behavior from the XF86Config file. The option flags
+are defined in the file ``xf86_option.h''. You should look to see if there is
+already a flag that can be reused. If so, use it in your driver. If not,
+add a new &num;define, and define the string->symbol mapping in the table in
+that file. To see how option flags are used, look at the ET4000,
+PVGA1/WD, and Trident drivers.-->
+¥æ¡¼¥¶¤Ë¥É¥é¥¤¥Ð¤Îµóư¤òÀ©¸æ¤µ¤»¤ë¤«¡¢¥æ¡¼¥¶¤Î²ðÆþ̵¤·¤Ë¥É¥é¥¤¥Ð¤ò
+·èÄê¤Ç¤­¤Ê¤¤¾ì¹ç¤Ï¡¢``option'' ¤ò»È¤¤¤Þ¤·¤ç¤¦¡£SDC ¥Á¥Ã¥×¥»¥Ã¥È¤ò
+»ÈÍѤ·¤Æ¤¤¤ë¥Ü¡¼¥É¥Ù¥ó¥À¡¼¤Ï 8 ¸Ä¤« 16 ¸Ä¤Î¥¯¥í¥Ã¥¯¥Ñ¥é¥á¡¼¥¿¤ò¥ª
+¥×¥·¥ç¥ó¤ÇÍ¿¤¨¤Æ¤Ê¤µ¤¤¤È¸À¤¦¤Ç¤·¤ç¤¦¡£¥Á¥Ã¥×¥»¥Ã¥È¤Îõºº¤Î·ë²Ì¤«¤é
+·èÄꤹ¤ë¤·¤«ÊýË¡¤Ï̵¤¤¤Î¤Ç XF86Config ¥Õ¥¡¥¤¥ë ¤«¤é¥æ¡¼¥¶¤¬¥ª¥×¥·¥ç
+¥ó¤Çµóư¤òÁªÂò¤Ç¤­¤ë¤è¤¦¤ËÄ󶡤·¤Þ¤·¤ç¤¦¡£¥ª¥×¥·¥ç¥ó¤Ï
+``xf86_option.h'' ¥Õ¥¡¥¤¥ë¤ËÄêµÁ¤·¤Þ¤¹¡£ºÆÍøÍѲÄǽ¤Ê¥ª¥×¥·¥ç¥ó¤¬´û
+¤Ë¤½¤³¤Ë¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£ºÆÍøÍѲÄǽ¤Ê¾ì¹ç¤ÏÄɲ乤ë¥É¥é¥¤¥Ð¤Ë»È
+¤¤¤Þ¤·¤ç¤¦¡£ºÆÍøÍѲÄǽ¤Ç̵¤¤¾ì¹ç¤Ï¿·¤¿¤Ë &num;define ¤òÄɲä·¡¢¤½
+¤Î¥Õ¥¡¥¤¥ë¤Ë ʸ»úÎó->¥·¥ó¥Ü¥ë¤Î³ä¤êÅö¤Æ¤òɽ·Á¼°¤ÇÄêµÁ¤·¤Þ¤¹¡£¥ª¥×
+¥·¥ç¥ó¤Î»È¤¤Êý¤òÍý²ò¤¹¤ë¤Ë¤Ï ET4000, PVGA1/WD ¤È Trident ¤Î¥É¥é¥¤
+¥Ð¤ò¸«¤Æ¤¯¤À¤µ¤¤¡£
+
+<!--<sect1> Data Structures <p>-->
+<sect1> ¥Ç¡¼¥¿¹½Â¤ <p>
+<!--Once you have an understanding of what is needed from the above description,
+it is time to fill in the driver data structures. First we will deal with
+the `vgaSDCRec' structure. This data structure is the driver-local structure
+that holds the SVGA state information. The first entry in this data structure
+is ALWAYS `vgaHWRec std'. This piece holds the generic VGA portion of the
+information. After that, you will have one `unsigned char' field for each
+register that will be manipulated by your driver. That's all there is to
+this data structure.-->
+¾åµ­¤ÎÀâÌÀ¤«¤é²¿¤¬É¬ÍפʤΤ«Íý²ò¤·¤¿¤é¡¢¥É¥é¥¤¥Ð¤Î¥Ç¡¼¥¿¹½Â¤¤òµ­Æþ
+¤¹¤ëÃʳ¬¤Ç¤¹¡£ºÇ½é¤Ë `vgaSDCRec' ¤Î¹½Â¤¤Ë¼è¤ê³Ý¤«¤ê¤Þ¤·¤ç¤¦¡£¤³¤Î¥Ç
+¡¼¥¿¹½Â¤¤Ï SVGA ¤Î¾õÂÖ¾ðÊó¤òÊÝ»ý¤¹¤ë¥É¥é¥¤¥ÐÆÃÍ­¤Î¥Ç¡¼¥¿¹½Â¤¤Ç¤¹¡£
+¤³¤Î¥Ç¡¼¥¿¹½Â¤¤ÎºÇ½é¤Î¹àÌܤϾï¤Ë `vgaHWRec std' ¤Ç¤¹¡£¤³¤Î¹àÌܤÏÈÆ
+ÍÑ VGA ¤Î°ìÉôʬ¤Î¾ðÊó¤òÊÝ»ý¤·¤Þ¤¹¡£¤½¤ì°Ê¹ß¤ËÄɲ乤ë¥É¥é¥¤¥Ð¤¬Áàºî
+¤¹¤ë¥ì¥¸¥¹¥¿Ëè¤Ë°ì¤Ä¤Î `unsigned char' ¤ÎÎΰè¤ò¼è¤Ã¤Æ¤¯¤À¤µ¤¤¡£¤³¤ì
+¤¬ºÇ½é¤Î¥Ç¡¼¥¿¹½Â¤¤ÎÁ´¤Æ¤Ç¤¹¡£
+
+<!--Next you must initialize the `SDC' structure (type `vgaVideoChipRec'). This
+is the global structure that identifies your driver to the server. Its name
+MUST be `SDC', in all caps - i.e. it must match the directory name for your
+driver. This is required so that the Link Kit reconfiguration can identify
+all of the requisite directories and global data structures.-->
+¼¡¤Ë `SDC' ¹½Â¤(`vgaVideoChipRec' ·¿) ¤Î½é´ü²½¤ò¤·¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»
+¤ó¡£¤³¤ì¤ÏÄɲ乤ë¥É¥é¥¤¥Ð¤ò¥µ¡¼¥Ð¡¼¤Ë¼±Ê̤µ¤»¤ë¥°¥í¡¼¥Ð¥ë¤Ê¹½Â¤ÂÎ
+¤Ç¤¹¡£¤½¤Î̾¾Î¤Ï¤¹¤Ù¤ÆÂçʸ»ú¤Ç `SDC' ¤È¤·¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£¤Ä¤Þ¤ê¡¢
+Äɲ乤ë¥É¥é¥¤¥Ð¤Î¤¢¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Î̾¾Î¤È°ìÃפ·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£
+¤³¤Î»ö¤Ï¥ê¥ó¥¯¥­¥Ã¥È¤ÎºÆ¹½À®¤ò¹Ô¤¦»þ¤ËɬÍפʥǥ£¥ì¥¯¥È¥ê¤È¥°¥í¡¼¥Ð
+¥ë¤Ê¥Ç¡¼¥¿¹½Â¤¤ÎÁ´¤Æ¤ò³Îǧ¤¹¤ë¤³¤È¤¬É¬¿Ü¤Ç¤¹¡£
+
+<!--The first section of this structure simply holds pointers to the driver
+functions.-->
+¤³¤Î¹½Â¤ÂΤλϤá¤ÎÉôʬ¤Ï¥É¥é¥¤¥Ð´Ø¿ô¤Ø¤Î¥Ý¥¤¥ó¥¿¤òñ¤ËÊÝ»ý¤·¤Þ¤¹¡£
+
+<!--Next, you must initialize the information about how your chipset does
+bank switching. The following fields must be filled in:-->
+¼¡¤Ï¡¢¥Á¥Ã¥×¥»¥Ã¥È¤¬¥Ð¥ó¥¯ÀÚ¤êÂØ¤¨¤ò¤É¤¦¤¹¤ë¤«¤Ë¤Ä¤¤¤Æ¤Î¾ðÊó¤ò½é´ü
+²½¤·¤Þ¤¹¡£°Ê¹ß¤ÎÎΰè¤Ï¼¡¤Î¤è¤¦¤Ëµ­Æþ¤·¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó:
+<enum>
+<!--<item> ChipMapSize - the amount of memory that must be mapped into
+ the server's address space. This is almost always 64k (from
+ 0xA0000 to 0xAFFFF). Some chipsets use a 128k map (from
+ 0xA0000 to 0xBFFFF). If your chipset gives an option, use the
+ 64k window, as a 128k window rules out using a Hercules or
+ Monochrome Display Adapter card with the SVGA.-->
+<item> ChipMapSize - ¥µ¡¼¥Ð¡¼¤Î¥¢¥É¥ì¥¹¶õ´Ö¤Ë³ä¤êÉÕ¤±¤ë¥á¥â¥êÎÌ¡£
+ ¤Û¤ÜÄ̾ï 64k (0xA0000 ¤«¤é 0xAFFFF ¤Þ¤Ç) ¤Ç¤¹¡£¤¤¤¯¤Ä¤«¤Î¥Á¥Ã
+ ¥×¥»¥Ã¥È¤Ï 128k ¤ò»È¤¤¤Þ¤¹ (0xA0000 ¤«¤é 0xBFFFF ¤Þ¤Ç)¡£ÄɲÃ
+ ¤¹¤ë¥Á¥Ã¥×¥»¥Ã¥È¤Ë¥ª¥×¥·¥ç¥ó¤òÉղ乤ë¤È¡¢64k ¤ÎÁë¤ò 128k ¤Î
+ Áë¤Ë¤·¤Æ Hercules ¤Þ¤¿¤Ï¥â¥Î¥¯¥í ¥Ç¥£¥¹¥×¥ì¥¤ ¥¢¥À¥×¥¿¥«¡¼¥É
+ ¤Ç SVGA ¤È¤·¤Æ»ÈÍѽÐÍè¤Þ¤¹¡£
+<!--<item> ChipSegmentSize - the size of each bank within the ChipMapSize
+ window. This is usually also 64k, however, some chipsets split
+ the mapped window into a read portion and a write portion (for
+ example the PVGA1/Western Digital chipsets).-->
+<item> ChipSegmentSize - ChipMapSize ¤ÎÁëÆâ¤Î¥Ð¥ó¥¯¤ÎÂ礭¤µ¡£
+ ¤³¤ì¤â¤Þ¤¿Ä̾ï 64k ¤Ç¤¹¤¬¡¢¤¤¤¯¤Ä¤«¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ï³ä¤êÉÕ¤±
+ ¤é¤ì¤¿Áë¤òÆÉ¤ß¹þ¤ßÉôʬ¤È½ñ¤­¹þ¤ßÉôʬ¤Ëʬ³ä¤·¤Þ¤¹¡ÊÎ㤨¤Ð
+ PVGA1/Western Digita ¥Á¥Ã¥×¥»¥Ã¥È¡Ë¡£
+<!--<item> ChipSegmentShift - the number of bits by which an address will
+ be shifted right to mask of the bank number. This is log-base-2
+ of ChipSegmentSize.-->
+<item> ChipSegmentShift - ¥Ð¥ó¥¯ÈÖ¹æ¤ò¥Þ¥¹¥¯¤¹¤ë¤È¤­¤Î¥¢¥É¥ì¥¹
+ ¤ò±¦¥·¥Õ¥È¤¹¤ëºÝ¤Î¥Ó¥Ã¥È¿ô¡£¤³¤ì¤Ï ChipSegmentSize ¤Î 2 ¤òÄì
+ ¤È¤·¤¿ log ¤Ë¤Ê¤ê¤Þ¤¹¡£
+<!--<item> ChipSegmentMask - a bitmask used to mask off the address within
+ a given bank. This is (ChipSegmentSize-1).-->
+<item> ChipSegmentMask - Í¿¤¨¤é¤ì¤¿¥Ð¥ó¥¯¤Î¥¢¥É¥ì¥¹¤ò¥Þ¥¹¥¯¥ª¥Õ¤¹¤ë¤È¤­
+ ¤Î¥Ó¥Ã¥È¥Þ¥¹¥¯¡£¤³¤ì¤Ï (ChipSegmentSize-1) ¤Ë¤Ê¤ê¤Þ¤¹¡£
+<!--<item> ChipReadBottom,ChipReadTop - the addresses within the mapped
+ window in which read operations can be done. Usually 0, and
+ 64k, respectively, except for those chipset that have separate
+ read and write windows.-->
+<item> ChipReadBottom,ChipReadTop - ÆÉ¤ß¹þ¤ßÁàºî¤ò¹Ô¤Ã¤¿¤È¤­¤Î
+ ³ä¤êÉÕ¤±¤é¤ì¤¿Áë¤Î¥¢¥É¥ì¥¹¡£¤¬¡¢¥Á¥Ã¥×¥»¥Ã¥È¤¬Ê¬³ä¤µ¤ì¤¿ÆÉ¤ß
+ ¹þ¤ß¤È½ñ¤­¹þ¤ß¤ÎÁë¤ò»ý¤Ã¤Æ¤¤¤ë¾ì¹ç¤ò½ü¤¤¤Æ¡¢Ä̾ï¤Ï¤ª¤Î¤ª¤Î
+ 0 ¤È 64k ¤Ç¤¹¡£
+<!--<item> ChipWriteBottom,ChipWriteTop - same as above, for write
+operations.-->
+<item> ChipWriteBottom,ChipWriteTop - ½ñ¤­¹þ¤ßÁàºî¤Ë¤ª¤¤¤Æ¾åµ­
+ ¤ÈƱÍͤǤ¹¡£
+<!--<item> ChipUse2Banks - a boolean value for whether this chipset has one
+ or two bank registers. This is used to set up the screen-to-screen
+ operations properly.-->
+<item> ChipUse2Banks - ³ºÅö¥Á¥Ã¥×¥»¥Ã¥È¤¬°ì¤ÄËô¤ÏÆó¤Ä¤Î¥Ð¥ó¥¯
+ ¥ì¥¸¥¹¥¿¤ò»ý¤Ã¤Æ¤¤¤ë¤«¡¢¤¤¤Ê¤¤¤«¤Ë´Ø¤ï¤é¤Ê¤¤¥Ö¡¼¥ê¥¢¥óÃÍ¡£
+ ¤³¤ì¤Ï¥¹¥¯¥ê¡¼¥ó¤«¤é¥¹¥¯¥ê¡¼¥ó¤Ø¤ÎÁàºî¤ÎÀßÄê¤ËŬÀµ¤ËÍѤ¤¤é
+ ¤ì¤Þ¤¹¡£
+</enum>
+<!--There are three more fields that must be filled in:-->
+¤µ¤é¤Ë 3 ¸Ä¤ÎÎΰè¤òµ­Æþ¤·¤Þ¤·¤ç¤¦:
+<enum>
+<!--<item> ChipInterlaceType - this is either VGA_NO_DIVIDE_VERT or
+ VGA_DIVIDE_VERT. Some chipsets require that the vertical timing
+ numbers be divided in half for interlaced modes. Setting this
+ flag will take care of that.-->
+<item> ChipInterlaceType - VGA_NO_DIVIDE_VERT ¤Þ¤¿¤Ï VGA_DIVIDE_VERT
+ ¤Î¤É¤Á¤é¤«¤Ë¤Ê¤ê¤Þ¤¹¡£¤¤¤¯¤Ä¤«¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ï¥¤¥ó¥¿¥ì¡¼¥¹¥â¡¼
+ ¥ÉÍѤ˿âľÊý¸þ¤ÎÄ´À°¿ôÃͤò 2 ¤Ç³ä¤Ã¤¿¤â¤Î¤òɬÍפȤ·¤Þ¤¹¡£¤½¤Î
+ ¤¿¤á¡¢¤³¤ÎÀßÄê¤Ë¤ÏÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£
+<!--<item> ChipOptionFlags - this should always be `{0,}' in the data
+ structure initialization. This is a bitfield that contains
+ the Option flags that are valid for this driver. The appropriate
+ bits are initialized at the end of the Probe function.-->
+<item> ChipOptionFlags - ¥Ç¡¼¥¿¹½Â¤¤Î½é´ü²½¤Ç¤ÏÄ̾ï `{0,}' ¤Ë
+ ¤·¤Þ¤¹¡£¤³¤ì¤Ï¤³¤Î¥É¥é¥¤¥Ð¤ÇÍ­¸ú¤Ê ¥ª¥×¥·¥ç¥ó ¤ò´Þ¤ó¤À¥Ó¥Ã
+ ¥ÈÎó¤Ç¤¹¡£Ãµºº´Ø¿ô¤Î½ªÎ»»þ¤ËŬÀµ¤Ê¥Ó¥Ã¥ÈÎó¤Ë½é´ü²½¤µ¤ì¤Þ¤¹¡£
+<!--<item> ChipRounding - this gets set to the multiple by which the
+ virtual width of the display must be rounded for the 256-color
+ server. This value is usually 8, but may be 4 or 16 for some
+ chipsets.-->
+<item> ChipRounding - 256 ¿§¥µ¡¼¥Ð¡¼ÍѤ˲¾ÁÛ¥¹¥¯¥ê¡¼¥ó¤ÎÉý¤ò¤³
+ ¤ÎÃͤÎÇÜ¿ô¤Ë¤Ê¤ë¤è¤¦¤Ë´Ý¤á¤ë¤Î¤ËÍѤ¤¤ë¤¿¤áÀßÄꤷ¤Þ¤¹¡£¤³¤ÎÃÍ
+ ¤ÏÄ̾ï¤Ï 8 ¤Ç¤¹¤¬¡¢¤¤¤¯¤Ä¤«¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ç¤Ï 4 ¤È¤« 16 ¤Ë¤Ê
+ ¤ê¤Þ¤¹¡£
+</enum>
+
+<!--<sect1> The Ident() function <p>-->
+<sect1> Ident() ´Ø¿ô <p>
+<!--The <bf>Ident()</bf> function is a very simple function. The server
+will call
+this function repeatedly, until a NULL is returned, when printing out the
+list of configured drivers. The <bf>Ident()</bf> function should return a
+chipset
+name for a supported chipset. The function is passed a number which
+increments from 0 on each iteration.-->
+<bf>Ident()</bf> ´Ø¿ô¤ÏÂçÊÑñ½ã¤Ê´Ø¿ô¤Ç¤¹¡£¥µ¡¼¥Ð¡¼¤¬¤³¤Î´Ø¿ô¤ò
+NULL ¤òµ¢¤¹¤Þ¤Ç·«¤êÊÖ¤·¸Æ¤Ó½Ð¤·¤¿¤È¤­¤Ë¡¢ÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ë¥É¥é¥¤¥Ð¤Î
+°ìÍ÷¤ò½ÐÎϤ·¤Þ¤¹¡£<bf>Ident()</bf> ´Ø¿ô¤Ï¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¥Á¥Ã¥×¥»¥Ã
+¥È¤Î̾¾Î¤òÊÖ¤·¤Þ¤¹¡£¤³¤Î´Ø¿ô¤Ï³Æ¡¹¤Î·«¤êÊÖ¤·¤Ç 0 ¤«¤éÁý²Ã¤¹¤ë¿ôÃͤò
+ÅϤ·¤Þ¤¹¡£
+
+<!--<sect1> The ClockSelect() function <p>-->
+<sect1> ClockSelect() ´Ø¿ô <p>
+<!--The <bf>ClockSelect()</bf> function is used during clock probing (i.e.
+when no
+`Clocks' line is specified in the XF86Config file) to select the dot-clock
+indicated by the number passed in the parameter. The function should
+set the chipset's clock-select bits according to the passed-in number.
+Two dummy values will be passed in as well (CLK_REG_SAVE, CLK_SAVE_RESTORE).
+When CLK_REG_SAVE is passed, the function should save away copies of
+any registers that will be modified during clock selection. When
+CLK_REG_RESTORE is passed, the function should restore these registers.
+This ensure that the clock-probing cannot corrupt registers.-->
+<bf>ClockSelect()</bf> ´Ø¿ô¤Ï¥¯¥í¥Ã¥¯¤Îõºº¤ò¤¹¤ë¤È¤­¤Ë¡ÊÎ㤨¤Ð
+`Clocks' ¹Ô¤ò XF86Config ¥Õ¥¡¥¤¥ë¤Ç»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¡ËÁªÂò¤·¤¿¥É¥Ã
+¥È¥¯¥í¥Ã¥¯¤ò¥Ñ¥é¥á¥¿¤Ç¼õ¤±¼è¤ë¤Î¤ËÍѤ¤¤Þ¤¹¡£¼õ¤±¼è¤Ã¤¿¿ôÃͤˤè¤Ã¤Æ
+´Ø¿ô¤Ï¥Á¥Ã¥×¥»¥Ã¥È¤Î clock-select ¥Ó¥Ã¥È¤òÀßÄꤷ¤Þ¤¹¡£
+(CLK_REG_SAVE, CLK_SAVE_RESTORE) ¤Î¤è¤¦¤ÊÃÍ¤ÏÆó¤Ä¤Î¥À¥ß¡¼¤È¤·¤Æ¼õ¤±
+¼è¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£CLK_REG_SAVE ¤ò¼õ¤±¼è¤Ã¤¿»þ¤Ï¡¢´Ø¿ô¤¬¥¯¥í¥Ã¥¯
+ÁªÂòÅÓÃæ¤ËÊѹ¹¤·¤¿¥ì¥¸¥¹¥¿¤Î¼Ì¤·¤¬Êݸ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£CLK_REG_RESTORE
+¤ò¼õ¤±¼è¤Ã¤¿»þ¤Ï¡¢´Ø¿ô¤¬¥ì¥¸¥¹¥¿¤ò²óÉü¤·¤Þ¤·¤¿¡£¥¯¥í¥Ã¥¯Ãµºº¤¬¥ì¥¸
+¥¹¥¿¤ÎÆâÍÆ¤òÇ˲õ¤·¤Ê¤«¤Ã¤¿¤³¤È¤òÊݾڤ·¤Þ¤¹¡£
+
+<!--This function should return FALSE if the passed-in index value is invalid
+or if the clock can't be set for some reason.-->
+¼õ¤±¼è¤Ã¤¿¥¤¥ó¥Ç¥Ã¥¯¥¹¤ÎÃͤ¬ÉÔÀµ¤«¡¢¤â¤·¤¯¤Ï¥¯¥í¥Ã¥¯¤¬ÉÔÀµ¤ÇÀßÄê½Ð
+Íè¤Ê¤«¤Ã¤¿¾ì¹ç¡¢¤³¤Î´Ø¿ô¤Ï FALSE ¤òÊÖ¤·¤Þ¤¹
+
+<!--<sect1> The Probe() function <p>-->
+<sect1> Probe() ´Ø¿ô <p>
+<!--The <bf>Probe()</bf> function is perhaps the most important, and perhaps the
+least intuitive function in the driver. The Probe function is required
+to identify the chipset independent of all other chipsets. If the user
+has specified a `<tt>Chipset</tt>' line in the XF86Config file, this is a simple
+string comparison check. Otherwise, you must use some other technique
+to figure out what chipset is installed. If you are lucky, the chipset
+will have an identification mechanism (ident/version registers, etc), and
+this will be documented in the databook. Otherwise, you will have to
+determine some scheme, using the reference materials listed below.-->
+<bf>Probe()</bf> ´Ø¿ô¤Ï¥É¥é¥¤¥Ð¤ÎÃæ¤Ç¿ʬºÇ¤â½ÅÍפǤ«¤ÄºÇ¤âľ´¶Åª¤Ç
+̵¤¤´Ø¿ô¤Ç¤·¤ç¤¦¡£Probe ´Ø¿ô¤ÏÁ´¤Æ¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ë°Í¸¤»¤º¤Ë¥Á¥Ã¥×
+¥»¥Ã¥È¤ò¼±Ê̤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£XF86Config ¥Õ¥¡¥¤¥ë¤Ë
+`<tt>Chipset</tt>' ¹Ô¤ò»ØÄꤷ¤¿»þ¤Ë¡¢Ã±½ã¤Êʸ»úÎóÈæ³Ó¤ò¹Ô¤¤¤Þ¤¹¡£±¿
+¤¬¤è¤±¤ì¤Ð¡¢¥Á¥Ã¥×¥»¥Ã¥È¤Îǧ¼±µ¡¹½(¼±ÊÌ/¥Ð¡¼¥¸¥ç¥ó ¥ì¥¸¥¹¥¿, Åù)¤¬
+¤¢¤Ã¤Æ¡¢¤½¤ì¤¬¥Ç¡¼¥¿¥Ö¥Ã¥¯¤Ë·ÇºÜ¤µ¤ì¤Æ¤¤¤ë¤Ç¤·¤ç¤¦¡£¤µ¤â¤Ê¤±¤ì¤Ð¡¢
+°Ê²¼¤Ë½Ò¤Ù¤ë¤è¤¦¤Ê²¿¤é¤«¤Î¼ê½ç¤Ë¤è¤Ã¤ÆÇ§¼±¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£
+
+<!--The identification is often done by looking for particular patterns in
+register, or for the existence of certain extended registers. Or with
+some boards/chipsets, the requisite information can be obtained by reading
+the BIOS for certain signature strings. The best advise is to study the
+existing probe functions, and use the reference documentation. You
+must be certain that your probe is non-destructive - if you modify a
+register, it must be saved before, and restored after.-->
+¤è¤¯¥ì¥¸¥¹¥¿¤ËÆÃÍ­¤Î¥Ñ¥¿¡¼¥ó¤ä¡¢°ìÄê¤Î³ÈÄ¥¥ì¥¸¥¹¥¿¤òõ¤·¤ÆÇ§¼±¤·¤Þ
+¤¹¡£Ëô¤Ï¤¤¤¯¤Ä¤«¤Î¥Ü¡¼¥É¤ä¥Á¥Ã¥×¥»¥Ã¥È¤Ç¤Ï¡¢É¬ÍפʾðÊó¤Ï°ìÄê¤Î½ð̾
+ʸ»úÎó¤ò BIOS¤«¤éÆÉ¤ß¤À¤·¤Æ³ÍÆÀ¤·¤Æ¤¤¤Þ¤¹¡£´û¸¤Îõºº´Ø¿ô¤òÊÙ¶¯¤¹¤ë
+»ö¤È»²¹Íʸ¸¥¤ò»²¾È¤¹¤ë»ö¤ò¶¯¤¯¤ªÁ¦¤á¤·¤Þ¤¹¡£Äɲ乤ëõºº¤¬ÈóÇ˲õ¤Ç
+¹Ô¤ï¤ì¤Æ¤¤¤ë¤³¤È¤ò³Îǧ¤·¤Æ¡¢¥ì¥¸¥¹¥¿¤ò¹¹¿·¤¹¤ë¤Ê¤é¤Ð¡¢¹¹¿·Á°¤ËÊݸ
+¤·¤Æ¡¢¹¹¿·¸å¤Ë²óÉü¤·¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£
+
+<!--Once the chipset is successfully identified, the <bf>Probe()</bf>
+function must
+do some other initializations:-->
+¥Á¥Ã¥×¥»¥Ã¥È¤¬Ç§¼±¤Ç¤­¤¿¤é¡¢<bf>Probe()</bf> ´Ø¿ô¤Ï¤¤¤¯¤Ä¤«¤Î¾¤Î
+½é´ü²½¤ò¹Ô¤¦É¬Íפ¬¤¢¤ê¤Þ¤¹¡£
+<enum>
+<!--<item> If the user has not specified the `<tt>VideoRam</tt>'
+parameter in the
+ XF86Config file, the amount of installed memory must be determined.-->
+<item> XF86Config ¥Õ¥¡¥¤¥ë¤Ë `<tt>VideoRam</tt>' ¥Ñ¥é¥á¥¿¤ò»ØÄê
+¤·¤Ê¤¤¾ì¹ç¤Ï¡¢ÅëºÜ¤·¤Æ¤¤¤ë¥á¥â¥êÎ̤òÆÃÄꤷ¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£
+<!--<item> If the user has not specified the `<tt>Clocks</tt>' parameter
+in the
+ XF86Config file, the values for the available dot-clocks must
+ be determined. This is done by calling the <bf>vgaGetClocks()</bf>
+ function, and passing it the number of clocks available and
+ a pointer to the <bf>ClockSelect()</bf> function.-->
+<item> XF86Config ¥Õ¥¡¥¤¥ë¤Ë `<tt>Clocks</tt>' ¥Ñ¥é¥á¥¿¤ò»ØÄꤷ
+ ¤Ê¤¤¾ì¹ç¤Ï¡¢²Äǽ¤Ê¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ÎÃͤòÆÃÄꤷ¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»
+ ¤ó¡£<bf>vgaGetClocks()</bf> ´Ø¿ô¤ò¸Æ¤Ö¤³¤È¤Ç¡¢²Äǽ¤Ê¥¯¥í¥Ã¥¯
+ ¤ÎÃͤÈ<bf>ClockSelect()</bf> ¤Ø¤Î¥Ý¥¤¥ó¥¿¤ò¼õ¤±¼è¤ì¤Þ¤¹¡£
+<!--<item> It is recommended that the `maxClock' field of the server's
+ `vga256InfoRec' structure be filled in with the maximum
+ dot-clock rate allowed for this chipset (specified in KHz).
+ If this is not filled in a probe time, a default (currently
+ 90MHz) will be used.-->
+<item> ¥µ¡¼¥Ð¡¼¤Î `vga256InfoRec' ¹½Â¤ÂΤΠ`maxClock' Îΰè¤ò¥Á¥Ã
+ ¥×¥»¥Ã¥È¤Ç¤Î²Äǽ¤ÊºÇÂç¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ò (KHz ñ°Ì¤Ç) »ØÄꤹ¤ë
+ ¤³¤È¤ò¤ªÁ¦¤á¤·¤Þ¤¹¡£Ãµºº»þ¤Ë¤³¤³¤òµ­Æþ¤·¤Ê¤¤¤È¡¢É¸½àÃÍ (¸½ºß
+ ¤Ï 99MHz ) ¤ò»ÈÍѤ·¤Þ¤¹¡£
+<!--<item> The `chipset' field of the server's `vga256InfoRec' structure
+ must be initialized to the name of the installed chipset.-->
+<item> ¥µ¡¼¥Ð¡¼¤Î `vga256InfoRec' ¹½Â¤ÂΤΠ`chipset' Îΰè¤òÅëºÜ
+ ¤·¤Æ¤¤¤ë¥Á¥Ã¥×¥»¥Ã¥È¤Î̾¾Î¤Ç½é´ü²½¤·¤Þ¤·¤ç¤¦¡£
+<!--<item> If the driver will be used with the monochrome server, the
+ `bankedMono' field of the server's `vga256InfoRec' structure
+ must be set to indicate whether the monochrome driver supports
+ banking.-->
+<item> ¥â¥Î¥¯¥í¥µ¡¼¥Ð¡¼¤Ç¥É¥é¥¤¥Ð¤¬»ÈÍѤµ¤ì¤ë¤Ê¤é¤Ð¡¢¥µ¡¼¥Ð¡¼¤Î
+ `vga256InfoRec' ¹½Â¤ÂΤΠ`bankedMono' Îΰè¤Ë¥â¥Î¥¯¥í¥É¥é¥¤¥Ð
+ ¤¬¥Ð¥ó¥¯ÀÚ¤êÂØ¤¨¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¤«¤É¤¦¤«¤ò»ØÄꤷ¤Ê¤±¤ì¤Ð¤¤
+ ¤±¤Þ¤»¤ó¡£
+<!--<item> If any option flags are used by this driver, the
+`ChipOptionFlags'
+ structure in the `vgaVideoChipRec' must be initialized with the
+ allowed option flags using the <bf>OFLG_SET()</bf> macro.-->
+<item> Äɲ乤륵¡¼¥Ð¡¼¤¬Â¾¤Î¥ª¥×¥·¥ç¥ó¤ò¥µ¥Ý¡¼¥È¤¹¤ë¾ì¹ç¡¢
+ `vgaVideoChipRec' ·¿¤Î `ChipOptionFlags'¹½Â¤ÂΤò
+ <bf>OFLG_SET()</bf> ¥Þ¥¯¥í¤òÍѤ¤¤Æ¥ª¥×¥·¥ç¥ó¤Î»ÈÍѵö²Ä¤ò½é´ü
+ ÀßÄꤷ¤Þ¤·¤ç¤¦¡£
+</enum>
+
+<!--<sect1> The EnterLeave() function <p>-->
+<sect1> EnterLeave() ´Ø¿ô <p>
+<!--The <bf>EnterLeave()</bf> function is called whenever the virtual
+console on which
+the server runs is entered or left (for OSs without virtual consoles, the
+function is called when the server starts and again when it exits). The
+purpose of this function is to enable and disable I/O permissions (for
+OSs where such is required), and to unlock and relock access to ``protected''
+registers that the driver must manipulate. It is a fairly trivial function,
+and can be implemented by following the comments in the stub driver.-->
+<bf>EnterLeave()</bf> ´Ø¿ô¤Ï¥µ¡¼¥Ð¡¼¾å¤Î²¾ÁÛ¥³¥ó¥½¡¼¥ë¤ËÆþ¤Ã¤¿¤ê½Ð
+¤¿¤ê¤¹¤ëÅ٤˸ƤФì¤Þ¤¹(²¾ÁÛ¥³¥ó¥½¡¼¥ë¤Î̵¤¤ OS ¤Ç¤Ï¡¢¤³¤Î´Ø¿ô¤Ï¥µ¡¼
+¥Ð¡¼¤Î³«»Ï»þ¤Ë¸Æ¤Ð¤ì¡¢½ªÎ»»þ¤Ë¤â¤¦°ìÅٸƤФì¤Þ¤¹)¡£¤³¤Î´Ø¿ô¤ÎÌÜŪ¤Ï
+I/O ¤Î¸¢¸Â¤ò(OS ¤¬Í׵᤹¤ë¤è¤¦¤Ë)¾ùÅϤ·¤¿¤êÇíÃ¥¤·¤¿¤ê¤¹¤ë»ö¤Ë¤¢¤ë°Ù
+ ¤È ¥É¥é¥¤¥Ð¤¬Áàºî¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤``Êݸ¤ì¤¿''¥ì¥¸¥¹¥¿¤Ø¤Î¥í¥Ã¥¯
+ ²ò½ü¤ÈºÆ¥í¥Ã¥¯¥¢¥¯¥»¥¹¤ò¤¹¤ë°Ù¤Ç¤¹¡£¤³¤ì¤Ï¡¢¤È¤Æ¤â¾®¤µ¤Ê´Ø¿ô¤Ç¤¹¤¬
+ °Ê¹ß¤Î¥¹¥¿¥Ö¥É¥é¥¤¥Ð¤Î¥³¥á¥ó¥È¤Ë¤¢¤ë¤è¤¦¤Ë¼Â¸½¤·¤Þ¤·¤¿¡£
+
+<!--<sect1> The Restore() function <p>-->
+<sect1> Restore() ´Ø¿ô <p>
+<!--The <bf>Restore()</bf> function is used for restoring a saved video
+state. Note
+that `restore' is a bit of a misnomer - this function is used to both
+restore a saved state and to install a new one created by the server. The
+<bf>Restore()</bf> function must complete the following actions:-->
+<bf>Restore()</bf> ´Ø¿ô¤ÏÊݸ¤µ¤ì¤¿¥Ó¥Ç¥ª¾õÂÖ¤ò²óÉü¤¹¤ë¤Î¤ËÍѤ¤¤Þ
+¤¹¡£restore ¤È¤¤¤¦Ì¾¾Î¤Ï¾¯¤·¸í¤Ã¤¿Ì¾¾Î¤Ç¡¢¤³¤Î´Ø¿ô¤ÏÊݸ¤µ¤ì¤¿¾õÂÖ
+¤ò²óÉü¤¹¤ë»ö¤È¥µ¡¼¥Ð¡¼¤¬¿·µ¬¤ËºîÀ®¤·¤¿¾õÂÖ¤òÊݸ¤¹¤ë»ö¤ÎξÊý¤Ë»ÈÍÑ
+¤·¤Þ¤¹¡£<bf>Restore()</bf> ´Ø¿ô¤Ï¼¡¤Î¼ê³¤­¤ò¤Õ¤àɬÍפ¬¤¢¤ê¤Þ¤¹:
+
+<enum>
+<!--<item> Ensure that Bank 0 is selected, and that any other state
+ information required prior to writing out a new state has been
+ set up.-->
+<item> ¥Ð¥ó¥¯ 0 ¤òÁªÂò¤·¡¢¿·µ¬¾õÂ֤νÐÎϤËÀè¤À¤Ã¤ÆÍ׵ᤵ¤ì¤¿¥Ð
+ ¥ó¥¯ 0 ¤Î¤½¤Î¾¤Î¾õÂÖ¾ðÊó¤¬ÀßÄêºÑ¤ß¤Ç¤¢¤ë»ö¤ò³Îǧ¤¹¤ë¡£
+<!--<item> Call <bf>vgaHWRestore()</bf> to restore the generic VGA
+portion of the
+ state information. This function is in the vgaHW.c file.-->
+<item> <bf>vgaHWRestore()</bf> ¤ò¾õÂÖ¾ðÊó¤ÎÈÆÍÑ VGA Éôʬ¤ò²óÉü
+ ¤¹¤ë°Ù¤Ë¸Æ¤Ö¡£¤³¤Î´Ø¿ô¤Ï vgaHW.c ¥Õ¥¡¥¤¥ë¤ÎÃæ¤Ë¤¢¤ê¤Þ¤¹¡£
+<!--<item> Restore the chipset-specific portion of the state information.
+ This may be done by simply writing out the register, or by
+ doing a read/modify/write cycle if only certain bits are to
+ be modified. Be sure to note the comment in the sample driver
+ about how to handle clock-select bits.-->
+<item> ¾õÂÖ¾ðÊó¤Î¥Á¥Ã¥×¥»¥Ã¥ÈÆÃÍ­Éôʬ¤ò²óÉü¤¹¤ë¡£¤³¤ì¤Ïñ½ã¤Ë
+ ¥ì¥¸¥¹¥¿¤Ë½ñ¤­¹þ¤à¤«¡¢Êѹ¹¤¹¤Ù¤­Å¬Àµ¤Ê¥Ó¥Ã¥È¤À¤±¤Ë
+ read/modify/write Áàºî¤ò¹Ô¤¦¡£¥¯¥í¥Ã¥¯ÁªÂò¥Ó¥Ã¥È¤Î°·¤¤¤òÇ¡
+ ²¿¤Ë¹Ô¤¦¤«¤Ë¤Ä¤¤¤Æ¡¢¥É¥é¥¤¥Ð¤ÎÎãÂê¤ÎÃæ¤Î¥³¥á¥ó¥È¤ËÃí°Õ»ö¹à
+ ¤ò½ñ¤¤¤¿¤Î¤Ç³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£
+</enum>
+<!--<sect1> The Save() function <p>-->
+<sect1> Save() ´Ø¿ô <p>
+<!--The <bf>Save()</bf> function is used to extract the initial video state
+information
+when the server starts. The <bf>Save()</bf> function must complete the
+following
+actions:-->
+<bf>Save()</bf> ´Ø¿ô¤Ï¥µ¡¼¥Ð¡¼³«»Ï»þ¤Ë½é´ü¥Ó¥Ç¥ª¾õÂÖ¾ðÊó¤ò¼è¤ê½Ð¤¹
+¤Î¤Ë»ÈÍѤ¹¤ë¡£<bf>Save()</bf> ´Ø¿ô¤Ï¼¡¤Î¼ê³¤­¤ò¤Õ¤àɬÍפ¬¤¢¤ê¤Þ¤¹:
+<enum>
+<!--<item> Ensure that Bank 0 is selected.-->
+<item> ¥Ð¥ó¥¯ 0 ¤òÁªÂò¤·¤¿¤³¤È¤ò³Îǧ¤¹¤ë¡£
+<!--<item> Call <bf>vgaHWSave()</bf> to extract the generic VGA portion
+of the state
+ information. This function is in the vgaHW.c file.-->
+<item> <bf>vgaHWSave()</bf> ¤ò¾õÂÖ¾ðÊó¤ÎÈÆÍÑ VGA Éôʬ¤ò¼è¤ê½Ð¤¹
+ °Ù¤Ë¸Æ¤Ö¡£¤³¤Î´Ø¿ô¤Ï vgaHW.c ¥Õ¥¡¥¤¥ë¤ÎÃæ¤Ë¤¢¤ê¤Þ¤¹¡£
+<!--<item> Extract the chipset-specific portion of the state information.-->
+<item> ¾õÂÖ¾ðÊó¤Î¥Á¥Ã¥×¥»¥Ã¥ÈÆÃÍ­Éôʬ¤ò¼è¤ê½Ð¤¹¡£
+</enum>
+<!--<sect1> The Init() function <p>-->
+<sect1> Init() ´Ø¿ô <p>
+<!-- The <bf>Init()</bf> function is the second most important function in
+the driver
+(after the <bf>Probe()</bf> function). It is used to initialize a data
+structure
+for each of the defined display modes in the server. This function is
+required to initialize the entire `vgaSDCRec' data structure with the
+information needed to put the SVGA chipset into the required state. The
+generic VGA portion of the structure is initialized with a call to
+<bf>vgaHWInit()</bf> (also located in vgaHW.c).-->
+<bf>Init()</bf> ´Ø¿ô¤Ï¥É¥é¥¤¥Ð¤ÎÃæ¤Ç (<bf>Probe()</bf> ´Ø¿ô¤Î¼¡¤Ë)
+ÆóÈÖÌܤ˽ÅÍפǤ¹¡£¥µ¡¼¥Ð¡¼¤ÎÃæ¤ËÄêµÁ¤µ¤ì¤¿É½¼¨¥â¡¼¥É³Æ¡¹¤Ë¤Ä¤¤¤Æ¥Ç¡¼
+¥¿¹½Â¤¤ò½é´ü²½¤·¤Þ¤¹¡£¤³¤Î´Ø¿ô¤Ï SVGA ¥Á¥Ã¥×¥»¥Ã¥È¤ËɬÍפʾõÂÖ¤Ë
+`vgaSDCRec' ¥Ç¡¼¥¿¹½Â¤Á´ÂΤò½é´ü²½¤¹¤ë¤Î¤Ë»È¤¤¤Þ¤¹¡£¹½Â¤ÂΤÎÈÆÍÑ
+VGA Éôʬ¤Ï (¤³¤ì¤â vgaHW.c Æâ¤Ë¤¢¤ë) <bf>vgaHWInit()</bf> ¤ò¸Æ¤Ö¤³
+¤È¤Ë¤è¤ê½é´ü²½¤·¤Þ¤¹¡£
+
+<!--Once the generic portion is initialized, the <bf>Init()</bf> function
+can override
+any of the generic register initialization, if necessary. All of the other
+fields are filled in with the correct initialization. The information
+about the particular mode being initialized is passed in the `mode'
+parameter, a pointer to a `DisplayModeRec' structure. This can be
+dereferenced to determine the needed parameters.-->
+ÈÆÍѤÎÉôʬ¤ò½é´ü²½¤·¤¿¤é¡¢É¬Íפʤé <bf>Init()</bf> ´Ø¿ô¤¬ÈÆÍѥ쥸¥¹
+¥¿¤Î¤¤¤¯¤Ä¤«¤Î½é´ü²½¤ò¹Ô¤¤¤Þ¤¹¡£Àµ¤·¤¤½é´ü²½¤Ë¤è¤Ã¤Æ¤½¤Î¾Á´¤Æ¤ÎÎÎ
+°è¤¬Ëä¤á¤é¤ì¤Þ¤¹¡£½é´ü²½¤·¤¿ÆÃÍ­¤Î¥â¡¼¥É¤Î¾ðÊó¤Ï `mode' ¥Ñ¥é¥á¥¿¤Ç
+¤¢¤ë`DisplayModeRec' ¹½Â¤ÂΤؤΥݥ¤¥ó¥¿¤Ç¼õ¤±¼è¤ê¤Þ¤¹¡£
+
+<!--If you only know how to initialize certain bits of the register, do that
+here, and make sure that the <bf>Restore()</bf> function does a
+read/modify/write
+to only manipulate those bits. Again, refer to the existing drivers
+for examples of what happens in this function.-->
+¥ì¥¸¥¹¥¿¤ÎŬÀµ¤Ê¥Ó¥Ã¥È¤Î½é´ü²½¤ÎÊýË¡¤¬Ê¬¤«¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¤³¤³¤Ç½é´ü
+²½¤·¤Þ¤·¤ç¤¦¡£<bf>Restore()</bf> ´Ø¿ô¤Ç¤·¤«¤½¤Î¥Ó¥Ã¥È¤ò
+read/modify/write ½ÐÍè¤Ê¤¤»ö¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+<!--<sect1> The Adjust() function <p>-->
+<sect1> Adjust() ´Ø¿ô <p>
+<!--The <bf>Adjust()</bf> function is another fairly basic function. It is
+called
+whenever the server needs to adjust the start of the displayed part of
+the video memory, due to scrolling of the virtual screen or when changing
+the displayed resolution. All it does is set the starting address on the
+chipset to match the specified coordinate. Follow the comments in the
+stub driver for details on how to implement it.-->
+<bf>Adjust()</bf> ´Ø¿ô¤ÏÈæ³ÓŪº¬ËÜŪ¤Ê´Ø¿ô¤Ç¤¹¡£²¾ÁÛ¥¹¥¯¥ê¡¼¥ó¤Î¥¹
+¥¯¥í¡¼¥ë¤äɽ¼¨²òÁüÅÙ¤ÎÊѹ¹¤Ë¤è¤Ã¤Æ¡¢¥µ¡¼¥Ð¡¼¤¬¥Ó¥Ç¥ª¥á¥â¥ê¤Îɽ¼¨ÍÑ
+Îΰè¤Î³«»ÏÅÀ¤òÄ´À°¤¹¤ëɬÍפΤ¢¤ë¤È¤­¤Ï¤¤¤Ä¤â¸Æ¤Ð¤ì¤Þ¤¹¡£Ëè²ó¡¢»ØÄê
+¤·¤¿ºÂɸ¤Ë¹ç¤ï¤»¤Æ¥Á¥Ã¥×¥»¥Ã¥È¤Î³«»Ï¥¢¥É¥ì¥¹¤òÀßÄꤷ¤Þ¤¹¡£¤³¤ì¤ò¼Â
+¸½¤¹¤ëÊýË¡¤Î¾ÜºÙ¤Ï¥¹¥¿¥Ö¥É¥é¥¤¥Ð¤ÎÃæ¤Î¥³¥á¥ó¥È¤Ë½¾¤Ã¤Æ¤¯¤À¤µ¤¤¡£
+
+<!--<sect1> The ValidMode() function <p>-->
+<sect1> ValidMode() ´Ø¿ô <p>
+<!--The <bf>ValidMode()</bf> function is required. It is used to check
+for any chipset-dependent reasons why a graphics mode might not be valid. It
+gets called by higher levels of the code after the Probe() stage. In
+many cases no special checking will be required and this function will
+simply return TRUE always.-->
+<bf>ValidMode()</bf> ´Ø¿ô¤Ïɬ¿Ü¤Ç¤¹¡£²¿¸Î¥°¥é¥Õ¥£¥Ã¥¯¥â¡¼¥É¤¬ÂÅÅö¤Ç
+̵¤¤¤Î¤«¡¢¥Á¥Ã¥×¥»¥Ã¥È¤Ë°Í¸¤·¤¿Íýͳ¤òÄ´ºº¤¹¤ë¤Î¤Ë»ÈÍѤ·¤Þ¤¹¡£
+Probe() ¼Â¹Ô¸å¤Î¥×¥í¥°¥é¥à¤Î¤è¤ê¾å°Ì¤Î¥×¥í¥°¥é¥à¤«¤é¸Æ¤Ð¤ì¤Þ¤¹¡£Â¿¤¯¤Î¾ì
+¹ç¡¢ÆÃÊ̤ÊÄ´ºº¤ÏɬÍפʤ¯¤³¤Î´Ø¿ô¤ÏÄ̾ñ¤Ë TRUE ¤òÊÖ¤·¤Þ¤¹¡£
+
+<!--<sect1> The SaveScreen() function <p>-->
+<sect1> SaveScreen() ´Ø¿ô <p>
+<!--The <bf>SaveScreen()</bf> function is not needed by most chipsets.
+This function
+would only be required if the extended registers that your driver needs
+will be modified when a synchronous reset is performed on the SVGA chipset
+(your databook should tell you this). If you do NOT need this function,
+simply don't define it, and put `NoopDDA' in its place in the vgaVideoChipRec
+structure initialization (NoopDDA is a generic-use empty function).-->
+<bf>SaveScreen()</bf> ´Ø¿ô¤ÏËØ¤É¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ç¤ÏɬÍפ¢¤ê¤Þ¤»¤ó¡£
+Äɲ乤ë¥É¥é¥¤¥Ð¤¬Æ±´ü¥ê¥»¥Ã¥È¤ò¥Á¥Ã¥×¥»¥Ã¥È¤Ç¼Â¹Ô¤¹¤ë¾ì¹ç¡¢³ÈÄ¥¥ì
+¥¸¥¹¥¿¤ò¹¹¿·¤¹¤ë¤Î¤Ç¤³¤Î´Ø¿ô¤¬É¬Íפˤʤê¤Þ¤¹¡Ê¥Ç¡¼¥¿¥Ö¥Ã¥¯¤Ë¾ÜºÙ¤Ë
+µ­ºÜ¤¬¤¢¤ê¤Þ¤¹¡Ë¡£¤³¤Î´Ø¿ô¤¬É¬Í×*̵¤¤*¤È¤­¡¢ÆÃ¤ËÄêµÁ¤ÏɬÍ×̵¤¯¡¢
+vgaVideoChipRec ¹½Â¤Âη¿¤Ç½é´ü²½¤·¤¿ `NoopDDA' ¤òÃÖ¤­¤Þ¤·¤ç¤¦
+¡ÊNoopDDA ¤ÏÈÆÍѤζõ¤Î´Ø¿ô¤Ç¤¹¡Ë¡£
+
+<!--If you DO need this function, it is fairly simple to do. It will be
+called twice - once before the reset, and again after. It will be passed
+a parameter of SS_START in the former case, and SS_FINISH in the latter.
+All that needs to be done is to save any registers that will be affected
+by the reset into static variables on the SS_START call, and then restore
+them on the SS_FINISH call.-->
+¤³¤Î´Ø¿ô¤¬*ɬÍ×*¤Ê¤é¤Ð¡¢Èæ³ÓŪñ½ã¤Ê¼¡¤Îºî¶È¤ò¹Ô¤Ã¤Æ¤¯¤À¤µ¤¤¡£Æó²ó
+¸Æ¤Ó½Ð¤¹¤Î¤Ç¤¹¤¬¡¢°ì²óÌܤϥꥻ¥Ã¥ÈÁ°¤ÈÆó²óÌܤϥꥻ¥Ã¥È¸å¤Ë¸Æ¤Ó½Ð¤·
+¤Þ¤¹¡£Á°¼Ô¤Î¾ì¹ç¤Ï °ú¿ô¤ËSS_START ¤òÅϤ·¡¢¸å¼Ô¤Ç¤Ï SS_FINISH ¤òÅϤ·
+¤Æ²¼¤µ¤¤¡£Ëè²ó¡¢SS_START ¤Ç¸Æ¤Ó½Ð¤·¤¿¾ì¹ç¤Ï¥ê¥»¥Ã¥È¤Ë¤è¤Ã¤Æ±Æ¶Á¤Î¤¢
+¤ë¥ì¥¸¥¹¥¿¤ò³ÊǼ¤·¡¢SS_FINISH ¤Ç¸Æ¤Ó½Ð¤·¤¿¾ì¹ç¤Ï¤½¤ì¤ò²óÉü¤¹¤ëɬÍ×
+¤¬¤¢¤ê¤Þ¤¹¡£
+
+<!--<sect1> The GetMode() function <p>-->
+<sect1> GetMode() ´Ø¿ô <p>
+<!--The <bf>GetMode()</bf> function is not used as of XFree86 1.3; its
+place in the
+vgaVideoChipRec should be initialized to `NoopDDA'.-->
+<bf>GetMode()</bf> ´Ø¿ô¤Ï XFree86 1.3 Ëø¤Ï»È¤Ã¤Æ¤¤¤Þ¤»¤ó¤·¡¢¤³¤ì¤Ï
+vgaVideoChipRec ·¿¤Ç `NoopDDA' ¤ò½é´ü²½¤·¤¿¤â¤Î¤Ç¤¹¡£
+
+<!--At some point in the future, this function will be used to enable the server
+and/or a standalone program using the server's driver libraries to do
+interactive video mode adjustments. This function will read the SVGA
+registers and fill in a DisplayModeRec structure with the current video
+mode.-->
+¾­Íè¡¢¤¤¤¯¤Ä¤«¤ÎÅÀ¤Ç¤³¤Î´Ø¿ô¤Ï¥µ¡¼¥Ð¡¼¤Î¥É¥é¥¤¥Ð¥é¥¤¥Ö¥é¥ê¤ò»È¤¦¥µ¡¼
+¥Ð¡¼³î¤Ä¡¿Ëô¤Ï¥¹¥¿¥ó¥É¥¢¥í¡¼¥ó¤Î¥×¥í¥°¥é¥à¤ÎÂÐÏ÷¿¥Ó¥Ç¥ª¥â¡¼¥ÉÄ´Àá
+¤Ë»ÈÍѲÄǽ¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£¤³¤Î´Ø¿ô¤Ï SVGA ¥ì¥¸¥¹¥¿¤òÆÉ¤ß¹þ¤ß¸½ºß¤Î
+¥Ó¥Ç¥ª¥â¡¼¥É¤Î DisplayModeRec ¹½Â¤ÂΤ˽ñ¤­¹þ¤ß¤Þ¤¹¡£
+
+<!--<sect1> The FbInit() function <p>-->
+<sect1> FbInit() ´Ø¿ô <p>
+<!--The <bf>FbInit()</bf> function is required for drivers with accelerated
+graphics
+support. It is used to replace default cfb.banked functions with
+accelerated chip-specific versions. vga256LowlevFuncs is a struct containing
+a list of functions which can be replaced. This struct defined in
+vga256.h. Examples of <bf>FbInit()</bf> functions can be found in the et4000,
+pvga1 and cirrus drivers.-->
+<bf>FbInit()</bf> ´Ø¿ô¤Ï¥¢¥¯¥»¥é¥ì¡¼¥¿¥°¥é¥Õ¥£¥Ã¥¯¥¹¤ò¥µ¥Ý¡¼¥È¤¹¤ë
+¥É¥é¥¤¥Ð¤Ëɬ¿Ü¤Ç¤¹¡£¥¢¥¯¥»¥é¥ì¡¼¥¿¥Á¥Ã¥×¸ÇÍ­¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ïɸ½à¤Ç
+cfb.banked ´Ø¿ô¤òÃÖ¤­´¹¤¨¤Æ»ÈÍѤ·¤Þ¤¹¡£vga256LowlevFuncs ¤ÏÃÖ¤­´¹¤¨
+²Äǽ¤Ê´Ø¿ô¤Î°ìÍ÷¤ò´Þ¤à¹½Â¤ÂΤǤ¹¡£¤³¤Î¹½Â¤ÂÎ¤Ï vga256.h ¤ÇÄêµÁ¤·¤Æ
+¤¤¤Þ¤¹¡£<bf>FbInit()</bf> ´Ø¿ô¤ÎÎã¤Ï et4000, pvga1 ¤Ècirrus ¤Î¥É¥é
+¥¤¥Ð¤Ë¤¢¤ê¤Þ¤¹¡£
+
+<!--If you do NOT need this function, simply don't define it, and put `NoopDDA'
+in its place in the vgaVideoChipRec structure initialization.-->
+¤³¤Î´Ø¿ô¤¬É¬Íפʤ¤¾ì¹ç¡¢Ã±¤ËÄêµÁ¤ò¤·¤Ê¤¤¤Ç¡¢vgaVideoChipRec ·¿¤Ç½é
+´ü²½¤·¤¿ `NoopDDA' ¤òÃÖ¤¤¤Æ¤¯¤À¤µ¤¤¡£
+
+<!--<sect> Building The New Server <p>-->
+<sect> ¿·¥µ¡¼¥Ð¡¼¤ÎÀ¸À® <p>
+<!--As in the setup work, the steps for building the server depend whether
+you are working in the source tree or in the Link Kit. Here are the
+steps for the initial build after installing your new driver files:-->
+¤³¤ÎÀßÄêºî¶È¤Ï¡¢¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤«¤é¤«¡¢¥ê¥ó¥¯¥­¥Ã¥È¤«¤é¤«¤Ë¤è¤é¤º¥µ¡¼
+¥Ð¡¼¤òÀ¸À®¤¹¤ëÃʳ¬¤Îºî¶È¤ò¹Ô¤¤¤Þ¤¹¡£
+<itemize>
+<!-- <item> If you are working in the source tree, follow these steps:-->
+ <item> ¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤«¤éºî¶È¤ò¤·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¼¡¤Î¼ê½ç¤Ç¹Ô¤Ã
+ ¤Æ²¼¤µ¤¤:
+
+<!-- Go to xc/programs/Xserver, and enter-->
+ xc/programs/Xserver ¤Ë°Üư¤·¤Æ¡¢
+<!-- `<tt>make Makefile</tt>', then-->
+ `<tt>make Makefile</tt>' ¤ÈÆþÎϤ·¤¿¤é
+<!-- `<tt>make Makefiles depend all</tt>'-->
+ `<tt>make Makefiles depend all</tt>' ¤ÈÆþÎϤ·¤Þ¤¹¡£
+
+<!-- <item> If you are working in the Link Kit, follow these steps:-->
+ <item> ¥ê¥ó¥¯¥­¥Ã¥È¤«¤éºî¶È¤ò¤·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¼¡¤Î¼ê½ç¤Ç¹Ô¤Ã¤Æ
+ ¤¯¤À¤µ¤¤:
+
+ <enum>
+<!-- <item> Go to /usr/X11R6/lib/Server, and enter-->
+ <item> /usr/X11R6/lib/Server ¤Ø°Üư¤·¤Æ¡¢
+<!-- `<tt>./mkmf</tt>'-->
+ `<tt>./mkmf</tt>' ¤ÈÆþÎϤ·¤¿¤é
+<!-- <item> In the same directory, enter `<tt>make</tt>'-->
+ <item> Ʊ¤¸¥Ç¥£¥ì¥¯¥È¥ê¤Ç¡¢`<tt>make</tt>' ¤ÈÆþÎϤ·¤Þ¤¹¡£
+ </enum>
+</itemize>
+<!--To rebuild the server after the initial build (e.g. after making changes
+to your driver):-->
+ºÇ½é¤ÎÀ¸À®¤Î¸å¤Ç¥µ¡¼¥Ð¡¼¤ÎºÆÀ¸À®¤ò¹Ô¤¦¤Ê¤é¤Ð¡ÊÎ㤨¤ÐÄɲ乤ë¥É¥é¥¤
+¥Ð¤ËÊѹ¹¤·¤Æ¤«¤é¡Ë:
+
+<itemize>
+<!--<item> If you are working in the source tree, follow these steps:-->
+<item> ¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤«¤éºî¶È¤ò¤·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¼¡¤Î¼ê½ç¤Ç¹Ô¤Ã¤Æ²¼¤µ¤¤:
+
+ <enum>
+<!-- <item> Go to the appropriate drivers/ directory (e.g.,
+ xc/programs/Xserver/hw/xfree86/vga256/drivers),
+ and enter `<tt>make</tt>'.-->
+ <item> ŬÀÚ¤Ê drivers/ ²¼¤Î ¥Ç¥£¥ì¥¯¥È¥ê¤Ø°Üư¤·¤Æ¡ÊÎ㤨¤Ð
+ xc/programs/Xserver/hw/xfree86/vga256/drivers¡Ë¡¢¤½¤·¤Æ
+ `<tt>make</tt>' ¤ÈÆþÎϤ·¤Æ¤¯¤À¤µ¤¤¡£
+<!-- <item> Go to xc/programs/Xserver, and enter-->
+ <item> xc/programs/Xserver ¤Ø°Üư¤·¤Æ¡¢¼¡¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤¡£
+<!-- `<tt>make loadXF86_SVGA</tt>' (to link the color server),-->
+ `<tt>make loadXF86_SVGA</tt>' (¥«¥é¡¼¥µ¡¼¥Ð¡¼¤Ø¤Î¥ê¥ó¥¯),
+<!-- `<tt>make loadXF86_VGA16</tt>' (to link the 16 color server) or-->
+ `<tt>make loadXF86_VGA16</tt>' (16 ¿§¥µ¡¼¥Ð¡¼¤Ø¤Î¥ê¥ó¥¯) Ëô¤Ï
+<!-- `<tt>make loadXF86_Mono</tt>' (to link the mono server).-->
+ `<tt>make loadXF86_Mono</tt>' (¥â¥Î¥¯¥í¥µ¡¼¥Ð¡¼¤Ø¤Î¥ê¥ó¥¯)¡£
+ </enum>
+
+<!--<item> If you are working in the Link Kit, follow these steps:-->
+<item> ¥ê¥ó¥¯¥­¥Ã¥È¤«¤éºî¶È¤ò¹Ô¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¼¡¤Î¼ê½ç¤Ç¹Ô¤Ã¤Æ²¼¤µ¤¤:
+ <enum>
+<!-- <item> Go to the appropriate driver directory, and enter
+ `<tt>make</tt>'.-->
+ <item> ŬÀڤʥɥ饤¥Ð¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ø°Üư¤·¤Æ¡¢¤½¤·¤Æ
+ `<tt>make</tt>' ¤ÈÆþÎϤ·¤Æ¤¯¤À¤µ¤¤¡£
+<!-- <item> Go to /usr/X11R6/lib/server, and enter -->
+ <item> /usr/X11R6/lib/server ¤Ë°Üư¤·¤Æ¡¢¼¡¤òÆþÎϤ·¤Æ¤¯¤À¤µ¤¤¡£
+<!-- `<tt>make loadXF86_SVGA</tt>' (to link the color server) or -->
+ `<tt>make loadXF86_SVGA</tt>' (¥«¥é¡¼¥µ¡¼¥Ð¡¼¤Ø¤Î¥ê¥ó¥¯), Ëô¤Ï
+<!-- `<tt>make loadXF86_VGA16</tt>' (to link the 16 color server) or -->
+ `<tt>make loadXF86_VGA16</tt>' (16 ¿§¥µ¡¼¥Ð¡¼¤Ø¤Î¥ê¥ó¥¯) Ëô¤Ï
+<!-- `<tt>make loadXF86_Mono</tt>' (to link the mono server).-->
+ `<tt>make loadXF86_Mono</tt>' (¥â¥Î¥¯¥í¥µ¡¼¥Ð¡¼¤Ø¤Î¥ê¥ó¥¯)¡£
+ </enum>
+</itemize>
+
+<!--<sect> Debugging <p>-->
+<sect> ¥Ç¥Ð¥Ã¥° <p>
+<!--Debugging a new driver can be a painful experience, unfortunately. It
+is likely that incorrect programming of the SVGA chipset can lock up your
+machine. More likely, however, is that the display will be lost, potentially
+requiring a reboot to correct. It is HIGHLY recommended that the server
+be run from an attached terminal or a network login. This is the only
+rational way in which a debugger can be used on the server. Attempting
+to use multiple VTs for debugging is basically a waste of time.-->
+»Äǰ¤Ê¤¬¤é¿·¤·¤¤¥É¥é¥¤¥Ð¤Î¥Ç¥Ð¥Ã¥°¤Ï¿É¤¤¤â¤Î¤Ç¤¹¡£Î㤨¤Ð SVGA ¥Á¥Ã
+¥×¥»¥Ã¥È¤Î¥×¥í¥°¥é¥à¤¬´Ö°ã¤Ã¤¿¾ì¹ç¥Þ¥·¥ó¤¬¸Ç¤Þ¤Ã¤Æ¤·¤Þ¤¦¤Ç¤·¤ç¤¦¡£
+¥Ç¥£¥¹¥×¥ì¥¤¤Îɽ¼¨¤¬¾Ã¤¨¤¿¤ê¤¹¤ë¤Î¤Ç¡¢¤â¤·¤«¤¹¤ë¤ÈÀµ¾ï¤ËÌ᤹¤¿¤á¤Ë
+ºÆÎ©¤Á¾å¤²¤ò¤¹¤ëɬÍפ¬¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£³°ÉôüËö¤ò·Ò¤°¤«¡¢¥Í¥Ã¥È
+¥ï¡¼¥¯¤«¤é¥í¥°¥¤¥ó¤¹¤ë¤³¤È¤ò*¶¯¤¯*¤ª´«¤á¤·¤Þ¤¹¡£¥µ¡¼¥Ð¡¼¤Ç¥Ç¥Ð¥Ã¥¬
+¤¬Æ°ºî¤¹¤ë¾ì¹ç¤Ë¡¢Í£°ì¹çÍýŪ¤ÊÊýË¡¤Ç¤¹¡£Ê£¿ô¤Î VT ¤ò»È¤¤¤Ê¤¬¤é¤Î¥Ç
+¥Ð¥Ã¥°¤Ï´ðËÜŪ¤Ë»þ´Ö¤Î̵Â̤Ǥ¹¡£
+
+<!--Because of the potential for locking up the machine, it is a VERY good idea
+to remember to do a `sync' or two before starting the server. In addition,
+any unnecessary filesystems should be unmounted while the debugging session
+is going on (to avoid having to run unnecessary fsck's).-->
+¥Þ¥·¥ó¤¬¸Ç¤Þ¤Ã¤Æ¤·¤Þ¤¦¾ì¹ç¤Ï¡¢¥µ¡¼¥Ð¡¼¤òµ¯Æ°¤¹¤ëÁ°¤Ë°ì¤Ä¤«Æó¤Ä¤Î
+`Ʊ´ü'¤ò¼è¤ë»ö¤ò»×¤¤½Ð¤¹¤³¤È¤Ï*¤È¤Æ¤â*Îɤ¤¤È»×¤¤¤Þ¤¹¡£²Ã¤¨¤Æ¡¢¥Ç¥Ð¥Ã
+¥°¤ò»Ï¤á¤ëÁ°¤ËɬÍפΤʤ¤¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤ò¥¢¥ó¥Þ¥¦¥ó¥È¡ÊɬÍפΤʤ¤
+fsck ¤¬¼Â¹Ô¤µ¤ì¤Ê¤¤¤è¤¦¤Ë¡Ë¤·¤Æ¤ª¤­¤Þ¤·¤ç¤¦¡£
+
+<!--By default the server is built without debugging symbols. The server can
+grow VERY large with debugging enabled. It is very simple to rebuild
+your driver for debugging, though. Do the following:-->
+ɸ½à¤Ç¤Ï¥µ¡¼¥Ð¡¼¤Ï¥Ç¥Ð¥Ã¥°ÍѤΥ·¥ó¥Ü¥ë¤¬ÉÕ°¤·¤Æ¤¤¤Þ¤»¤ó¡£¥Ç¥Ð¥Ã¥°
+¤Ç¤­¤ë¤è¤¦¤Ë¤·¤¿¥µ¡¼¥Ð¡¼¤Ï*¤È¤Æ¤â*Â礭¤Ê¤â¤Î¤Ë¤Ê¤ê¤Þ¤¹¡£¤Ç¤¹¤¬¥Ç¥Ð¥Ã
+¥°¤Î°Ù¤Î¥µ¡¼¥Ð¡¼¤òºÆ¹½ÃÛ¤¹¤ë¤³¤È¤Ï´Êñ¤Ç¤¹¡£¼¡¤Î¼ê½ç¤Ç¹Ô¤Ã¤Æ¤¯¤À¤µ¤¤:
+
+<enum>
+<!-- <item> Go to the driver directory.-->
+ <item> ¥É¥é¥¤¥Ð¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ø°Üư¤·¤Æ¤¯¤À¤µ¤¤¡£
+<!-- <item> Edit the Makefile. Look for the SECOND definition of
+ `<tt>CDEBUGFLAGS</tt>'. Change this definition to -->
+ <item> Makefile ¤òÊÔ½¸¤·¤Æ¤¯¤À¤µ¤¤¡£ `<tt>CDEBUGFLAGS</tt>' ¤Î
+ *ÆóÈÖÌÜ*¤ÎÄêµÁ¤òõ¤·¤Æ¤¯¤À¤µ¤¤¡£¼¡¤Î¤è¤¦¤Ë½¤Àµ¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+ <verb>
+ CDEBUGFLAGS = -g -DNO_INLINE
+ </verb>
+
+<!-- (this will enable debugging symbols and disable inlining of
+ functions, which can make single-stepping a nightmare).
+ <item> Remove the `sdc_driver.o' file.
+ <item> Now follow the steps above for rebuilding the server.-->
+ (¤³¤ì¤Ï¥Ç¥Ð¥Ã¥°ÍÑ¥·¥ó¥Ü¥ë¤òÍ­¸ú¤Ë¤·¡¢¥·¥ó¥°¥ë¥¹¥Æ¥Ã¥×¼Â¹Ô»þ
+ ¤Î°­Ì´¤ò°ú¤­µ¯¤³¤¹´Ø¿ô¤Î¥¤¥ó¥é¥¤¥óŸ³«¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£)
+ <item> `sdc_driver.o' ¥Õ¥¡¥¤¥ë¤ò¾Ã¤·¤Æ¤¯¤À¤µ¤¤¡£
+ <item> ¾åµ­¤Î¼ê½ç¤ËÃíÌܤ·¤Æ¥µ¡¼¥Ð¡¼¤òºÆ¹½ÃÛ¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+<!-- (Alternatively, instead of editing the Makefile, you can simply
+ do `<tt>make CDEBUGFLAGS="-g -DNO_INLINE"</tt>' after removing the
+ old .o file, then rebuild the server as described above).-->
+ (Ëô¤Ï¡¢¸Å¤¤ .o ¥Õ¥¡¥¤¥ë¤ò¾Ã¤·¤¿¸å¤Ç Makefile ¤ò½¤Àµ¤¹¤ëÂå¤ï¤ê¤Ë¡¢
+ ñ¤Ë `<tt>make CDEBUGFLAGS="-g -DNO_INLINE"</tt>' ¤ò¼Â¹Ô¤·¤Æ
+ ¾åµ­¤Î¼ê½ç¤Ç¥µ¡¼¥Ð¡¼¤òºÆ¹½ÃÛ¤·¤Æ¤¯¤À¤µ¤¤¡£)
+</enum>
+
+<!--This will give you a server with which you can set breakpoints in the driver
+functions and single-step them. If you are working in the source tree,
+and just learning about SVGA programming, it may be useful to rebuild
+vgaHW.c with debugging as well.-->
+¤³¤ì¤ò¹Ô¤¦¤³¤È¤Ë¤è¤Ã¤Æ¥É¥é¥¤¥Ð¤Î´Ø¿ô¤Ë¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È¤òÀßÄꤷ¥·¥ó
+¥°¥ë¥¹¥Æ¥Ã¥×¼Â¹Ô¤ò¥µ¡¼¥Ð¡¼¤Ç¹Ô¤¦¤³¤È¤¬½ÐÍè¤Þ¤¹¡£¥½¡¼¥¹¤«¤éºî¶È¤ò¹Ô
+¤¤¡¢SVGA ¥×¥í¥°¥é¥ß¥ó¥°¤ò³Ø½¬¤·»Ï¤á¤¿¤Ð¤«¤ê¤Ê¤é¤Ð¡¢vgaHW.c ¤òºÆ¹½ÃÛ
+¤·¥Ç¥Ð¥Ã¥°¤¹¤ë¤Î¤¬¤Á¤ç¤¦¤ÉÎɤ¤¤Ç¤·¤ç¤¦¡£
+
+<!--<sect> Advice <p>-->
+<sect> ¥¢¥É¥Ð¥¤¥¹ <p>
+<!--I cannot stress this enough - study all available references, and the
+existing code, until you understand what is happening. Do this BEFORE you
+begin writing a driver. This will save you a massive amount of headache.
+Try to find a driver for a chipset that is similar to yours, if possible.
+Use this as an example, and perhaps derive your driver from it.-->
+Á´¤Æ¤ÎÍøÍѲÄǽ¤Ê»²¹Íʸ¸¥¤È¸ºß¤¹¤ë¥×¥í¥°¥é¥à¤òÄ´¤Ù¤Æ¡¢²¿¤¬µ¯¤Ã¤Æ¤¤
+¤ë¤Î¤«Ê¬¤«¤ë¤è¤¦¤Ë¤Ê¤ë¤Þ¤Ç¤«¤Ê¤ê¥¹¥È¥ì¥¹¤ò´¶¤¸¤Þ¤¹¡£¥É¥é¥¤¥Ð¤ò½ñ¤­
+»Ï¤á¤ë*Á°¤Ë*Ä´ºº¤ò¹Ô¤Ã¤Æ²¼¤µ¤¤¡£¤«¤Ê¤êƬÄˤò¸º¤é¤¹¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡£
+²Äǽ¤Ê¤é¤Ð¡¢¤³¤ì¤«¤éÄɲ䷤褦¤È¤¹¤ë¥Á¥Ã¥×¥»¥Ã¥È¤Ë»÷¤¿¥Á¥Ã¥×¥»¥Ã¥È
+¤Î¥É¥é¥¤¥Ð¤òõ¤·¤Þ¤·¤ç¤¦¡£¤³¤ÎÎãÂ꤫¤éÇÉÀ¸¤µ¤»¤Æ¥É¥é¥¤¥Ð¤òºîÀ®
+¤Ç¤­¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£
+
+<!--Do not let the gloom-and-doom in the debugging section discourage you.
+While you will probably have problems initially (I still do), careful,
+deliberate debugging steps can bear fruit very quickly. It is likely
+that, given a good understanding of the chipset, a driver can be written
+and debugged in a day or two. For someone just learning about this kind
+of programming, a week is more reasonable.-->
+¥Ç¥Ð¥Ã¥°Ãæ¤Ï°Å¤¯»×¤¤µÍ¤á¤Æ¤Ï¤¤¤±¤Þ¤»¤ó¡£¤Ï¤¸¤á¤Î¤¦¤Á¡Ê»ä¤â¤Þ¤À¤½¤¦
+¤Ç¤¹¡Ë¡¢Â¿Ê¬ÌäÂê¤òÊú¤¨¤Æ¤¤¤ë¤È¤­¤ÏÃí°Õ¿¼¤¯¿µ½Å¤Ë¥Ç¥Ð¥Ã¥°¤¹¤ë¤Î¤Ç¿×
+®¤ËÀ®²Ì¤¬¾å¤¬¤ê¤Þ¤¹¡£¤½¤ì¤Ï¥Á¥Ã¥×¥»¥Ã¥È¤Ë¤Ä¤¤¤Æ¤ÎÍý²ò¤ò¹â¤á°ìÆü¤«
+ÆóÆü¤ÎÆâ¤Ë¥É¥é¥¤¥Ð¤¬½ñ¤­¾å¤¬¤ê¥Ç¥Ð¥Ã¥°½ÐÍè¤Þ¤¹¡£¤³¤Î¼ï¤Î¥×¥í¥°¥é¥ß
+¥ó¥°¤ò³Ø½¬¤·»Ï¤á¤¿¿Í¤Ç¤Ï°ì½µ´Ö¤â¤¢¤ì¤Ð¤è¤êÂÅÅö¤ÊÀþ¤Ç¤·¤ç¤¦¡£
+
+<!--<sect> Advanced Topics <p>-->
+<sect> ¹âÅÙ¤ÊÏÃÂê <p>
+<!--Newer chipsets are getting into two advanced areas: programmable clock
+generators, and accelerated capabilities (BitBlt, line drawing, HW cursor).
+These are new areas, and the formal interfaces to them are not yet defined.
+It is advised that you contact the XFree86 team and get involved with the
+development/beta-testing team if you need to be working in these areas.-->
+¿·¤·¤¤¥Á¥Ã¥×¥»¥Ã¥È¤ÏÆó¤Ä¤Î¹âÅ٤ʵ»½ÑÎΰè¤ò¼è¤êÁȤߤޤ·¤¿: ¤½¤ì¤Ï¥×
+¥í¥°¥é¥Þ¥Ö¥ë¥¯¥í¥Ã¥¯¥¸¥§¥Í¥ì¡¼¥¿¤È¥¢¥¯¥»¥é¥ì¡¼¥¿¤Î³Æ¼ïÆÃÀ­(BitBlt,
+line drawing, HW ¥«¡¼¥½¥ë) ¤Ç¤¹¡£¤³¤ì¤é¤Ï¿·¤·¤¤µ»½ÑÎΰè¤Ç¡¢Àµ¼°¤Ê
+¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Ï̤¤ÀÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£¤³¤ì¤é¤Î¿·¤·¤¤µ»½ÑÎΰè
+¤Ë¤Ä¤¤¤Æºî¶È¤·¤¿¤¤¾ì¹ç¤Ï¡¢XFree86 ¥Á¡¼¥à¤ÈÏ¢Íí¤ò¼è¤Ã¤Æ³«È¯/¥Ù¡¼¥¿
+¥Æ¥¹¥È¥Á¡¼¥à¤Ë»²²è¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+<!--<sect> References <p>-->
+<sect> »²¹Íʸ¸¥ <p>
+<itemize>
+<item> Programmer's Guide to the EGA and VGA Cards, 3rd ed. <newline>
+ Richard Ferraro <newline>
+ Addison-Wesley, 1990 <newline>
+ ISBN 0-201-57025-4 <newline>
+<!--
+-<item> Programmer's Guide to the EGA and VGA Cards, 2nd ed. <newline>
+- Richard Ferraro <newline>
+- Addison-Wesley, 1990 <newline>
+- ISBN 0-201-57025-4 <newline>
+- (This is the bible of SVGA programming - it has a few errors, so watch out).
+-
+-<item> vgadoc3.zip <newline>
++<item> Programmer's Guide to the EGA and VGA Cards, 3rd ed. <newline>
++ Richard Ferraro <newline>
++ Addison-Wesley, 1994 <newline>
++ ISBN 0-201-62490-7 <newline>
++ (This is the bible of SVGA programming - it has a few errors, so watch out.
++ The third edition also covers several accelerated video cards.)
++
++<item> vgadoc4.zip <newline>
+-->
+<!-- (This is the bible of SVGA programming - it has a few errors, so
+watch out).-->
+ (¤³¤ì¤Ï SVGA ¥×¥í¥°¥é¥ß¥ó¥°¤ÎɬÆÉ½ñ¤Ç¤¹¡£¤Á¤ç¤Ã¤È¥¨¥é¡¼¤¬¤¢
+ ¤ë¤Î¤ÇÃí°Õ¤·¤Þ¤·¤ç¤¦¡£Âè 3 ÈǤǤ⥢¥¯¥»¥é¥ì¡¼¥¿¥Ó¥Ç¥ª¥«¡¼¥É¤Ë¸ÀµÚ
+ ¤·¤Æ¤¤¤Þ¤¹¡£)
+
+<item> vgadoc4.zip <newline>
+ Finn Thoegersen <newline>
+<!-- (This is a collection of SVGA and other chipset documentation. It is
+ available on most MS-DOS/Windows related FTP archives, including wuarchive.
+ It is DOS/BIOS oriented, but is still extremely useful, especially for
+ developing probe functions).-->
+<!-- ....1.........2.........3.........4.........5.........6...... -->
+ (SVGA ¤È¤½¤Î¾¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Î»ñÎÁ¤ò½¸¤á¤¿¤â¤Î¤Ç¤¹¡£wuarchive ¤ò
+ ´Þ¤à FTP ¤«¤é¼è¤ê´ó¤»²Äǽ¤ÇËØ¤É¤Î MS-DOS/Windows ¤Ç¸«¤ë¤³¤È¤¬²Ä
+ ǽ¤Ç¤¹¡£DOS/BIOS ¤Ë°Í¸¤·¤¿¤â¤Î¤Ç¤¹¤¬¡¢Ãµºº´Ø¿ô¤ò³«È¯¤¹¤ë»þ¤Ë¤È
+ ¤Æ¤âÍ­ÍѤǤ¹¡£)
+</itemize>
+
+<!--<sect> Vendor Contact Information <p>-->
+<sect> ¥Ù¥ó¥À¡¼Ï¢ÍíÀè¾ðÊó <p>
+<descrip>
+<tag/ATI Technologies (VGA-Wonder, Mach8, Mach32)
+ 33 Commerce Valley Drive East/
+Thornhill, Ontario <newline>
+Canada L3T 7N6 <newline>
+(905) 882-2600 (sales) <newline>
+(905) 882-2626 (tech support) <newline>
+(905) 764-9404 (BBS) <newline>
+(905) 882-0546 (fax) <newline>
+
+<tag/Chips &amp; Technologies/
+??? <newline>
+
+<tag/Cirrus Logic (SVGA, Accelerators - CL-GD5426)/
+3100 West Warren Ave. <newline>
+Fremont, CA 94538 <newline>
+(510) 623-8300 (N. CA, USA) <newline>
+(49) 8152-40084 (Germany) <newline>
+(44) 0727-872424 (UK) <newline>
+
+<tag/Genoa Systems (GVGA)/
+75 E. Trimble Road <newline>
+San Jose, CA 95131 <newline>
+(408) 432-9090 (sales) <newline>
+(408) 432-8324 (tech support) <newline>
+
+<tag/Headland Technologies, Inc (Video-7 VGA 1024i, VRAM II)/
+46221 Landing Parkway <newline>
+Fremont, CA 94538 <newline>
+(415) 623-7857 <newline>
+
+<tag/Oak Technology, Inc (OTI-067,OTI-077)/
+139 Kifer Ct. <newline>
+Sunnyvale, CA 94086 <newline>
+(408) 737-0888 <newline>
+(408) 737-3838 (fax) <newline>
+
+<tag>S3 (911, 924, 801/805, 928, 864, 868, 964, 968, 764, 765)</tag>
+(408) 980-5400 <newline>
+
+<tag/Trident Microsystems Inc (8800, 8900, 9000)/
+205 Ravendale Dr <newline>
+Mountainside, CA 94043 <newline>
+(415) 691-9211 <newline>
+
+<tag/Tseng Labs Inc,/
+6 Terry Drive <newline>
+Newtown, PA 18940 <newline>
+(215) 968-0502 <newline>
+
+<tag/Weitek (Power9000, 5186)/
+1060 E. Arques Ave, <newline>
+Sunnyvale, CA 94086 <newline>
+(408) 738-5765 <newline>
+
+<tag/Western Digital/
+(714) 932-4900 <newline>
+</descrip>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/VGADriv.sgml,v 3.1 1997/01/26 04:34:26 dawes Exp $
+</verb>
+<hrule>
+
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ï xc/programs/Xserver/hw/xfree86/doc/sgml/VGADriv.sgml,v 3.10 1996/10/23 13:10:05 ¤ò¡¢ ²¬ËÜ °ì¹¬
+( Kazuyuki Okamoto <url url="mailto:ikko-@pacific.rim.or.jp"
+name="&lt;ikko-@pacific.rim.or.jp&gt;"> ) ¤¬ XFree86 3.2 ¤ò
+ÆüËܤǥ¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¿Í¸þ¤±¤ËÏÂÌõ¤·¤¿¤â¤Î¤Ç¤¹¡£¤³¤³¤¬¤ª¤«¤·¤¤¤È¤«¡¢
+¤³¤³¤Ï¤³¤¦¤·¤¿¤Û¤¦¤¬¤¤¤¤¤È¤¤¤Ã¤¿¤´°Õ¸«¤¬¤¢¤ê¤Þ¤·¤¿¤é¡¢ÅŻҥ᡼¥ë¤Ç
+¤ªÃΤ餻²¼¤µ¤¤¡£
+¸¶Ê¸¤ÎÃøºî¸¢¤Ï XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ÎÏÂÌõ¤ÎÃøºî¸¢¤Ï
+XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤È²¬ËÜ¡¡°ì¹¬¤Ë¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤ÎÏÂÌõ¤ÎÉÔ¶ñ¹ç¤Ï»ä¤Ë¡¢
+ÅŻҥ᡼¥ë¤ÇÁ÷¤Ã¤Æ²¼¤µ¤¤¡£
+<hrule>
+&lsqb;EOF&rsqb;
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/VidModes.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/VidModes.sgml
new file mode 100644
index 000000000..0f2021582
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/VidModes.sgml
@@ -0,0 +1,1142 @@
+<!doctype linuxdoc system>
+
+<article>
+<title>X386/XFree86 ¤Î¥Ó¥Ç¥ª¾ðÊóÄ´À°¤ò¼«Ê¬¤Ç¹Ô¤Ê¤¦¤¿¤á¤Î¼ê°ú¤­
+<subtitle>(¤Þ¤¿¤Ï¼ñÌ£¤È¼Â±×¤Î¤¿¤á¤Î¥â¥Ë¥¿¡¼Ä´À°¤Î¼ê°ú¤­)
+<author> Eric S. Raymond <em/esr@snark.thyrsus.com/
+ (¸¶Ãø¤Ï Chin Fang <em/fangchin@leland.stanford.edu/; »á¤¬½ñ¤­¤Þ¤·¤¿¡£
+ Bob Crosson <em/crosson@cam.nist.gov/,»á¤¬¥Ï¥¦¥Ä¡¼¤«¤éÇÉÀ¸Éôʬ¤ò½ñ¤­
+ ¤Þ¤·¤¿¡£)
+
+
+<date>
+¤³¤ì¤Ï¥Ð¡¼¥¸¥ç¥ó 1.0, 1993 ǯ 1 ·î 8 Æü ¤Ç¤¹¡£
+</date>
+<trans> ²¬ËÜ¡¡°ì¹¬ Kazuyuki Okamoto &lt;ikko-@pacific.rim.or.jp&gt;
+<toc>
+
+
+<sect> ½øÊ¸
+<p>
+
+²þÎɤΤ¿¤á¤ÎΨľ¤Ê¤´°Õ¸«¡¢¤´Èãɾ¤È¤´Äó°Æ¤Ï <em/esr@snark.thyrsus.com/ °¸¤Æ¤ËÁ÷
+¤Ã¤Æ¤¯¤À¤µ¤¤¡£
+&lsqb;ÌõÃí: ÌÞÏÀ¡¢Ëܽñ¤ÎÆüËܸìÈǤËÂФ¹¤ë²þÎɤΤ¿¤á¤ÎΨľ¤Ê¤´°Õ¸«¡¢¤´Èãɾ¤È¤´Äó
+°Æ¤Ï <url url="mailto:ikko-@pacific.rim.or.jp" name="&lt;ikko-@pacific.rim.or.jp&gt;"> °¸¤Æ¤ËÁ÷¤Ã¤Æ²¼¤µ¤¤¡£&rsqb;
+
+¥æ¡¼¥¶¡¼¤Ï XFree86 ¥µ¡¼¥Ð¡¼¤ò¼«Ê¬¤Î¥Ó¥Ç¥ª¤Ë¹ç¤ï¤»¤Æ¥Ï¡¼¥É¥¦¥§¥¢¤ò»È¤¤¤³¤Ê
+¤¹¤è¤¦¤Ë¹½À®½ÐÍè¤Þ¤¹¡£¤³¤Î¼ê°ú¤­½ñ¤Ï¼«Ê¬¼«¿È¤Î¥Ó¥Ç¥ª¥«¡¼¥É¤È¥â¥Ë¥¿¤ÎºÇŬ¤Ê
+»þ´ÖÄ´Àá¤Î¿ôÃͤò¡¢Ç¡²¿¤ËÀ¸À®¤¹¤ë¤«ÊÙ¶¯¤¹¤ë½õ¤±¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£
+
+¤³¤³¤Ç¤Ï¤Þ¤º XFree86 ¥µ¡¼¥Ð¡¼¤ò²¿¤È¤«Æ°¤«¤¹¤¿¤á¤ÎÊýË¡¤òÄ󼨤·¡¢¤½¤ì¤ò¥Ù¡¼
+¥¹¤Ë¼Â¸³¤ò¤·¤Ê¤¬¤é¤¤¤í¤¤¤í¤ÈÀßÄê¤òÊѹ¹¤·¤Æ¼«Ê¬¤Î¹¥¤ß¤Ë¹ç¤ï¤»¤ë¤¿¤á¤Î¤ä¤êÊý
+¤òÀâÌÀ¤·¤Þ¤¹¡£
+
+¤Û¤È¤ó¤Éưºî¤·¤Æ¤¤¤ë¥â¡¼¥É¤ò»ý¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡ÊÆÃ¤Ë¡¢Á°¤â¤Ã¤ÆÀßÄꤷ¤Æ¤¤¤ë
+VESA ¥â¡¼¥É¤Ïº¸±¦¤ËÊÒ´ó¤Ã¤¿¤ê¡¢¾®¤µ¤¹¤®¤¿¤ê¡¢Â礭¤¹¤®¤¿¤ê¤¹¤ë¤Ç¤·¤ç¤¦¤¬¡¢
+°ÂÄꤷ¤Æ¤¤¤ë¤Ç¤·¤ç¤¦¡Ë¡¢¤µ¤Ã¤½¤¯ÌäÂ꽤Àµ¤ÎÀᤫ¤é»Ï¤á¤Æ¤¯¤À¤µ¤¤¡£¤³¤ÎÀá¤ÏÄ´
+À°¿ôÃͤò¤Á¤ç¤¦¤ÉÎɤ¤¿ôÃͤ˶á¤Å¤±¤ëÊýË¡¤ò¶µ¤¨¤Æ¤¯¤ì¤ë¤Ç¤·¤ç¤¦¡£
+
+XFree86 ¤Ï¥Û¥Ã¥È¥­¡¼¤Ç XF86Config ¥Õ¥¡¥¤¥ë ¤ËÄêµÁ¤µ¤ì¤Æ¤¤¤ë°Û¤Ê¤ë¥â¡¼¥É´Ö
+¤ò°Üư¤Ç¤­¤Þ¤¹¡Ê¾ÜºÙ¤Ë¤Ä¤¤¤Æ¤Ï XF86Config.man ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡Ë¡£¤³¤ì¤Ï
+¤È¤Æ¤âÊØÍø¤Êµ¡Ç½¤Ç¤¹¡£¿·¤·¤¤¥â¡¼¥É¤ò»î¤·¤Æ¤ß¤¿¤¯¤Ê¤Ã¤¿¤é¡¢¿·¤·¤¤¥â¡¼¥É¤ò½Å
+Ê£¤·¤Ê¤¤¥â¡¼¥É¥é¥Ù¥ë¤òÉÕ¤±¤Æ¥Û¥Ã¥È¥­¡¼¥ê¥¹¥È¤Î <em/end/ ¤ËÄɲ䷤Ƥ¯¤À¤µ¤¤¡£¿·
+¤·¤¤¥â¡¼¥É¤¬Æ°¤«¤Ê¤«¤Ã¤¿¤È¤­¤ÎÊݸ±¤Ë¡¢´û¤Ëư¤¤¤Æ¤¤¤ë¥â¡¼¥É¤Ïɸ½àÃͤȤ·¤Æ»Ä
+¤·¤Æ¤ª¤¤¤Æ¤¯¤À¤µ¤¤¡£¡ÖÆó¤Ä¤ÎÎãÂê¡×¾Ï¤ÎºÇ¸å¤Î Xconfig Àá¤òÆÉ¤á¤Ð¡¢¤¹¤ß¤ä¤«
+¤ËÌäÂê¤ò²ò·è¤¹¤ë¤¿¤á¤Ë¤Ï¤É¤Î¤è¤¦¤Ë¼Â¸³¤òµ­Ï¿¤¹¤ì¤Ð¤è¤¤¤«¡¢»²¹Í¤Ë¤Ê¤ë¤Ç¤·¤ç
+¤¦¡£
+
+ºÇ½é¤Ë <tt>lib/X11/doc</tt> ¤Ë¤¢¤ë <tt/Monitors/ ¥Õ¥¡¥¤¥ë¤ò³Îǧ¤·¤Æ¼«Ê¬¤Î
+¥â¥Ë¥¿¡¼¤¬¥Ç¡¼¥¿¥Ù¡¼¥¹¤ÎÃæ¤Ë¤¢¤ì¤Ð¡¢Â¿Ê¬¤³¤Îʸ½ñ¤Î»Ä¤ê¤ÎÉôʬ¤ÏÈô¤Ð¤·¤Æ¹½¤¤
+¤Þ¤»¤ó¡ª¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¼«Ê¬¤Î¥«¡¼¥É¤¬»ÈÍѤ¹¤ë¥â¡¼¥É¤¬Ìµ¤«¤Ã¤¿¾ì¹ç¡¢¤¤¤¯¤Ä¤«
+¤Î»þ´ÖÄ´Àá¤Î¿ôÃͤò¬Äꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¤¬¡¢´Êñ¤Êºî¶È¤Ç¤¹¡£
+
+<sect> ¥Ó¥Ç¥ª¥Ç¥£¥¹¥×¥ì¥¤¤Îưºî¸¶Íý
+<p>
+
+¥Ó¥Ç¥ª¥Ç¥£¥¹¥×¥ì¥¤¤Îưºî¸¶Íý¤òÃΤ뤳¤È¤Ï Xconfig ¥Õ¥¡¥¤¥ë¤Î¿§¡¹¤Ê¾ì½ê¤Ë¤É
+¤ó¤Ê¿ô»ú¤òÆþ¤ì¤ë¤«¤òÍý²ò¤¹¤ë¾å¤Ç½ÅÍפǤ¹¡£¤³¤ì¤é¤ÎÃÍ¤Ï XFree86 ¥µ¡¼¥Ð¡¼¤¬
+¥Ç¥£¥¹¥×¥ì¥¤¤ò¥Ï¡¼¥É¥¦¥§¥¢¥ì¥Ù¥ë¤ÇÀ©¸æ¤¹¤ë¤Î¤Ë»ÈÍѤµ¤ì¤Þ¤¹¡£
+
+¥Ç¥£¥¹¥×¥ì¥¤¤Ï¥É¥Ã¥È¤Î½¸¤Þ¤ê¤«¤é²èÁü¤òɽ¼¨¤·¤Þ¤¹¡£¤³¤Î¥É¥Ã¥È¤òº¸¤«¤é±¦¤ØÊÂ
+¤Ù¤ÆÀþ¤òºî¤ê¤Þ¤¹¡£¤³¤ÎÀþ¤ò¾å¤«¤é²¼¤ØÊ¤٤ƲèÁü¤òºî¤ê¤Þ¤¹¡£¥É¥Ã¥È¤Ï¥Ç¥£¥¹¥×
+¥ì¥¤ÆâÉô¤«¤é¤ÎÅŻҥӡ¼¥à¤Çᤫ¤ì¤¿¤È¤­È¯¸÷¤·¤Þ¤¹¡£¤½¤ì¤¾¤ì¤Î¥É¥Ã¥È¤Ë¶Ñ°ì¤Ë
+ÅŻҥӡ¼¥à¤òÅö¤Æ¤ë¤¿¤á¤Ë¡¢°ìÄê¤Î¥Ñ¥¿¡¼¥ó¤Ç¥Ç¥£¥¹¥×¥ì¥¤¾å¤òÁöºº¤·¤Þ¤¹¡£
+
+
+¤½¤Î¥Ñ¥¿¡¼¥ó¤Ï¥¹¥¯¥ê¡¼¥ó¤Îº¸¾å¤«¤é»Ï¤Þ¤ê¡¢±¦¤Ø¿¿Ä¾¤°¥¹¥¯¥ê¡¼¥ó¤ò²£ÀÚ¤ë¤è¤¦
+¤ËÁö¤ê¡¢¥¹¥¯¥ê¡¼¥ó¤Î±¦Ã¼¤Ç°ìöÄä»ß¤·¤Þ¤¹¡£¤½¤·¤ÆÅŻҥӡ¼¥à¤Ï¥Ç¥£¥¹¥×¥ì¥¤¤Î
+º¸Ã¼¤Ë°Üư¤·¡¢°ìËܲ¼¤Ë°Üư¤·¤Þ¤¹¡£¿·¤·¤¤Àþ¤Ï¥Ç¥£¥¹¥×¥ì¥¤¤Îº¸¤«¤é±¦¤ØºÇ½é¤Î
+Àþ¤ò°ú¤¤¤¿¤è¤¦¤ËÁöºº¤·¤Þ¤¹¡£¤³¤Î¥Ñ¥¿¡¼¥ó¤ò¥Ç¥£¥¹¥×¥ì¥¤¤Î°ìÈÖ²¼¤Þ¤Ç·«¤êÊÖ¤·
+¤Þ¤¹¡£¤½¤ì¤«¤éÅŻҥӡ¼¥à¤¬¥Ç¥£¥¹¥×¥ì¥¤¤Îº¸¾å¤«¤é±¦²¼¤Þ¤Ç°Üư¤·¤¿¤é¡¢¤Þ¤¿ºÇ
+½é¤«¤é·«¤êÊÖ¤·¤Þ¤¹¡£
+
+¥Õ¥ì¡¼¥à¤Î»Ï¤Þ¤ê¤Ï¥Ç¥£¥¹¥×¥ì¥¤¤Îº¸¾å¤ÎÅŻҥӡ¼¥à¤Î³«»ÏÅÀ¤Ç¤¹¡£ÅŻҥӡ¼¥à¤¬
+¥Ç¥£¥¹¥×¥ì¥¤¤Î±¦²¼¶ù¤Þ¤ÇÆÏ¤¤¤Æ¤«¤éº¸¾å¶ù¤ËºÆ¤ÓÌá¤Ã¤Æ¤¯¤ë»þ¤¬¥Õ¥ì¡¼¥à¤Î½ªÎ»
+ÅÀ¤Ç¤¹¡£¥Õ¥ì¡¼¥à¤Ï¥Ç¥£¥¹¥×¥ì¥¤¤Î°ìÈ־夫¤é°ìÈÖ²¼¤Þ¤Ç¤ÎÁ´¤Æ¤ÎÅŻҥӡ¼¥à¤ÎÀþ
+¤Ç½ÐÍè¤Æ¤¤¤Þ¤¹¡£
+
+¤â¤·ÅŻҥӡ¼¥à¤¬¥Õ¥ì¡¼¥à¤ò°Üư¤·¤Æ¤¤¤ë´Ö¤º¤Ã¤È¡Ö¥ª¥ó¡×¤À¤Ã¤¿¤é¡¢¥Ç¥£¥¹¥×¥ì
+¥¤¤ÎÁ´¤Æ¤Î¥É¥Ã¥È¤ÏÅÀÅô¤·¤Æ¤·¤Þ¤¤¡¢¥Ç¥£¥¹¥×¥ì¥¤¤Î±ï¤Ë¤Ï¹õ¤¤Éôʬ¤Ï¤Ê¤¯¤Ê¤ë¤Ç
+¤·¤ç¤¦¡£¤½¤·¤Æ¥Ç¥£¥¹¥×¥ì¥¤¤Î±ï¤Ç¤Ï¡¢ÅŻҥӡ¼¥à¤ÎÀ©¸æ¤¬Æñ¤·¤¤¤Î¤Ç²èÁü¤¬ÏĶÊ
+¤·¤Æ¤·¤Þ¤¦¤Ç¤·¤ç¤¦¡£¤³¤ÎÏĤߤò¸º¤é¤¹¤¿¤á¡¢¥Ç¥£¥¹¥×¥ì¥¤¤Î±ï¤Î¥É¥Ã¥È¤Ë¤Ï¡¢ÅÅ
+»Ò¥Ó¡¼¥à¤¬ÆÏ¤¤¤Æ¤â¡¢¥É¥Ã¥È¤¬µ±¤«¤Ê¤¤¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£¥Ç¥£¥¹¥×¥ì¥¤¤Î¼ÂºÝ
+¤Ëɽ¼¨¤µ¤ì¤ëÎΰ褬¾®¤µ¤¯¤Ê¤Ã¤Æ¤¤¤ë¤Î¤Ï¡¢¤³¤¦¤¤¤¦¤ï¤±¤Ê¤Î¤Ç¤¹¡£
+
+¤â¤¦°ì¤ÄÍý²ò¤·¤Æ¤Û¤·¤¤¤Î¤Ï¡¢É½¼¨¤µ¤ì¤ëÎΰè¤òÉÁ²è¤·¤Æ¤¤¤Ê¤¤»þ¤ËÅŻҥӡ¼¥à¤¬
+¤É¤¦¤Ê¤Ã¤Æ¤¤¤ë¤«¤È¤¤¤¦¤³¤È¤Ç¤¹¡£¥Ç¥£¥¹¥×¥ì¥¤¤Î²£Ã¼¤òÉÁ²è¤¹¤ë¤¿¤á¤Ë»È¤ï¤ì¤ë
+¤Ï¤º¤À¤Ã¤¿»þ´Ö¤Ï¡¢ÅŻҥӡ¼¥à¤ò±¦¤Îü¤«¤éº¸¤Îü¤Þ¤ÇÌᤷ¡¢°ì¤Ä²¼¤Î¼¡¤Î¥é¥¤¥ó
+¤Ë°Üư¤¹¤ë¤¿¤á¤Ë»È¤ï¤ì¤Þ¤¹¡£¥Ç¥£¥¹¥×¥ì¥¤¤Î¾åü¤ª¤è¤Ó²¼Ã¼¤òÉÁ²è¤¹¤ë¤¿¤á¤Ë³Ý
+¤«¤ë¤Ï¤º¤À¤Ã¤¿»þ´Ö¤Ï¡¢ÅŻҥӡ¼¥à¤ò¥Ç¥£¥¹¥×¥ì¥¤¤Î±¦²¼¶ù¤«¤éº¸¾å¶ù¤Þ¤Ç°Üư¤¹
+¤ë¤¿¤á¤Ë»È¤ï¤ì¤Þ¤¹¡£
+
+¥¢¥À¥×¥¿¥«¡¼¥É¤Ï¥Ç¥£¥¹¥×¥ì¥¤¤ÎÅŻҽƤòÅÀÅô¤µ¤»Á´¤Æ¤Î¥É¥Ã¥È¤Ç²èÁü¤òÀ¸À®¤¹¤ë
+¤è¤¦¤Ê¿®¹æ¤òºîÀ®¤·¤Þ¤¹¡£¤Þ¤¿¡¢¥«¡¼¥É¤ÏÅŻҥӡ¼¥à¤¬±¦¤«¤éº¸¤Ë°Üư¤·¤Æ°ìËܲ¼
+¤¬¤ë¤È¤­¤Ë¿åʿƱ´ü¿®¹æ¤È¸Æ¤Ð¤ì¤ë¿®¹æ¤òºîÀ®¤·¤Þ¤¹¡£¤¹¤Ù¤Æ¤Î¥é¥¤¥ó¤ÎºÇ¸å¤Ë°ì
+¤Ä¤Î¿åʿƱ´ü¿®¹æ¤¬È¯À¸¤·¤Þ¤¹¡£¤µ¤é¤Ë¡¢¥¢¥À¥×¥¿¥«¡¼¥É¤ÏÅŻҥӡ¼¥à¤ò¥Ç¥£¥¹¥×
+¥ì¥¤¤Îº¸¾å¶ù¤Ë°Üư¤¹¤ë¤¿¤á¤Î¿âľƱ´ü¿®¹æ¤âÀ¸À®¤·¤Þ¤¹¡£¿âľƱ´ü¿®¹æ¤ÏÁ´¤Æ¤Î
+¥Õ¥ì¡¼¥à¤Î½ª¤ï¤ê¶á¤¯¤ËºîÀ®¤µ¤ì¤Þ¤¹¡£
+
+¥Ç¥£¥¹¥×¥ì¥¤¤Ë¤Ï¡¢ÅŻҥӡ¼¥à¤Î°ÌÃÖ¤ò°ÂÄꤵ¤»¤ë¤¿¤á¡¢¿åʿƱ´ü¿®¹æ¤È¿âľƱ´ü
+¿®¹æ¤ÎÁ°¸å¤Ëû»þ´Ö¤Î;͵¤¬É¬ÍפǤ¹¡£ÅŻҥӡ¼¥à¤Î°ÂÄê²½¤¬½ÐÍè¤Ê¤¤¤È¡¢²èÁü¤¬
+¤·¤Ã¤«¤ê¤·¤Þ¤»¤ó¡£
+
+°Ê¹ß¤ÎÀá¤Ç¡¢ÄêµÁ¡¢¸ø¼°¤ÈÎãÂê¤ÎÊä½õ¤Î¤¿¤á¤Ë¡¢¤³¤ì¤é¤Î´ðËܤËÌá¤ë¤Ç¤·¤ç¤¦¡£
+
+<sect> ¥Ç¥£¥¹¥×¥ì¥¤¤È¥¢¥À¥×¥¿¤Ë¤Ä¤¤¤Æ¤Î´ðÁÃÃμ±
+<p>
+
+Xconfig ¤ÎÀßÄê¹àÌܤò¤µ¤ï¤ëÁ°¤Ë¡¢°Ê²¼¤Î´ðÁÃŪ¤Ê»ö¹à¤òÃΤäƤª¤¯É¬Íפ¬¤¢¤ê¤Þ
+¤¹¡£
+<enum>
+<item> ¥â¥Ë¥¿¡¼¤Î¿åʿƱ´ü¿®¹æ¤È¿âľƱ´ü¿®¹æ¤Î¼þÇÈ¿ô
+<item> ¥Ó¥Ç¥ª¥¢¥À¥×¥¿¤Îưºî¥¯¥í¥Ã¥¯¼þÇÈ¿ô¡¢¤Þ¤¿¤Ï"¥É¥Ã¥È¥¯¥í¥Ã¥¯"
+<item> ¥â¥Ë¥¿¡¼¤Î¼þÇÈ¿ôÂÓÉý
+</enum>
+¤Ç¤¹¡£
+
+¥â¥Ë¥¿¡¼¤ÎƱ´ü¼þÇÈ¿ô :
+
+¥â¥Ë¥¿¡¼¤Î¿åʿƱ´ü¼þÇÈ¿ô¤Ï¡¢¤½¤Î¥â¥Ë¥¿¡¼¤¬£±Éô֤˽ñ¤±¤ë¿åÊ¿ÁöººÀþ¤Î¿ô¤Î¤³
+¤È¤Ç¡¢¤³¤ì¤Ï¥â¥Ë¥¿¡¼¤Ë¤Ä¤¤¤ÆºÇ¤â½ÅÍפÊÅý·×ÃͤǤ¹¡£¿âľƱ´ü¼þÇÈ¿ô¤Ï¡¢¤½¤Î¥â
+¥Ë¥¿¡¼¤¬£±Éô֤ËÅŻҥӡ¼¥à¤ò½ÄÊý¸þ¤ËÄ̲ᤵ¤»¤ë¤³¤È¤Î¤Ç¤­¤ë²ó¿ô¤Î¤³¤È¤Ç¤¹¡£
+
+Ʊ´ü¼þÇÈ¿ô¤ÏÉáÄÌ¡¢¥â¥Ë¥¿¡¼¤Î¥Þ¥Ë¥å¥¢¥ë¤Î»ÅÍͤÎÊǤ˰ìÍ÷¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£¿âľ
+Ʊ´ü¼þÇÈ¿ô¤Î¿ôÃͤϰìÈÌŪ¤Ë Hz¡ÊÉÃÅö¤¿¤ê¤Îñ°Ì¼þ´ü¡Ë¤Ç¡¢¿åʿƱ´ü¼þÇÈ¿ô¤Ï
+KHz¡ÊÉÃÅö¤¿¤ê¤ÎÀéñ°Ì¼þ´ü¡Ë¤Ç·×¬¤µ¤ì¤Æ¤¤¤Þ¤¹¡£Ä̾ï¤ÎÈϰϤϿ⾤ˤĤ¤¤Æ¤Ï
+50 ¤«¤é 80Hz¡¢¿åÊ¿¤Ë¤Ä¤¤¤Æ¤Ï 31 ¤«¤é 135KHz ÄøÅ٤Ǥ¹¡£
+
+¥Þ¥ë¥Á¥¹¥­¥ã¥ó¥â¥Ë¥¿¡¼¤Î¾ì¹ç¡¢¤½¤Î¼þÇÈ¿ô¤ÏÉý¤Î¤¢¤ëÃͤȤ·¤ÆÉ½¼¨¤µ¤ì¤Æ¤¤¤Þ¤¹¡£
+¥í¡¼¥¨¥ó¥É¤Î¤â¤Î¤Ë¿¤¤¤Î¤Ç¤¹¤¬¡¢Ê£¿ô¤Î¸ÇÄꤷ¤¿¼þÇÈ¿ô¤ò»ý¤Ã¤Æ¤¤¤ë¥â¥Ë¥¿¡¼¤â
+¤¢¤ê¤Þ¤¹¡£¤³¤Î¤è¤¦¤Ê¥â¥Ë¥¿¡¼¤âÉáÄ̤Υâ¥Ë¥¿¡¼¤ÈƱÍͤËÀßÄê¤Ï½ÐÍè¤Þ¤¹¤¬¡¢¥â¥Ë
+¥¿¡¼¤Î»ý¤ÄÆÃħ¤Ë¸·¤·¤¯À©¸Â¤µ¤ì¤Æ¤·¤Þ¤¦¤Ç¤·¤ç¤¦¡£ºÇ¹â¤Î²òÁüÅÙ¤¬ÆÀ¤é¤ì¤ë¤è¤¦
+¤ÊºÇ¤â¹â¤¤¿åʿƱ´ü¤È¿âľƱ´ü¼þÇÈ¿ô¤ÎÁȤ߹ç¤ï¤»¤òÁªÂò¤·¤Æ¤¯¤À¤µ¤¤¡£¤½¤·¤Æ¡¢
+¸ÇÄê¼þÇÈ¿ô¥â¥Ë¥¿¡¼¤Ç¤ÏÀß·×Ãͤè¤ê¹â¤¤¼þÇÈ¿ô¤òÍ¿¤¨¤ë¤È¥â¥Ë¥¿¡¼¤òÄˤá¤ë¤ª¤½¤ì
+¤¬¤¢¤ë¤Î¤ÇÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+¥«¡¼¥É¤Îưºî¼þÇÈ¿ô :
+
+¥Ó¥Ç¥ª¥¢¥À¥×¥¿¤Î»ÅÍͽñ¤Ë¥«¡¼¥É¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤¬¤¢¤ê¤Þ¤¹¡Ê¥É¥Ã¥È¥¯¥í¥Ã¥¯¤È
+¤Ï²èÌ̤أ±Éô֤ËÅÀ¤òɽ¼¨¤Ç¤­¤ëÁí¿ô¤Ç¤¹¡Ë¡£¤³¤Î¾ðÊó¤¬Ìµ¤¤¾ì¹ç¤Ï¡¢X ¥µ¡¼¥Ð¡¼
+¤¬¤½¤ì¤ò¼è¤Ã¤Æ¤­¤Þ¤¹¡£X ¤¬¥â¥Ë¥¿¡¼¤ò¸Ç¤á¤Æ¤·¤Þ¤Ã¤¿¾ì¹ç¤Ç¤â¡¢¥¯¥í¥Ã¥¯¤È¤½¤Î
+¾¤Î¾ðÊó¤òɸ½à½ÐÎϤËÅǤ­½Ð¤·¤Þ¤¹¡£¤³¤Î¾ðÊó¤ò¥Õ¥¡¥¤¥ë¤Ë¥ê¥À¥¤¥ì¥¯¥È¤·¤¿¾ì¹ç¡¢
+¥³¥ó¥½¡¼¥ë¤ØÌá¤Ã¤ÆºÆÎ©¤Á¾å¤²¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¯¤Ê¤Ã¤Æ¤â¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤Þ
+¤¹¡£
+
+SGCS X ¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¼¡¤ÎÎã¤Î¤è¤¦¤Ê¹Ô¤ò¥í¡¼¥«¥ë¥Ð¥¹Àܳ¤Î S3 ¥¢¥À¥×
+¥¿¤Î Swan ¤«¤é¼ý½¸¤·¤Þ¤¹¡£XFree86 ¤Ï¤Á¤ç¤Ã¤ÈÆñ¤·¤¤Ê£¿ô¹Ô¤Ë¤ï¤¿¤ë½ñ¼°¤ò»È¤Ã
+¤Æ¤¤¤Þ¤¹¡£
+
+<tscreen><verb>
+WGA: 86C911 (mem: 1024k clocks: 25 28 40 3 50 77 36 45 0 0 79 31 94 65 75 71)
+--- ------ ----- --------------------------------------------
+ | | | ưºî²Äǽ¤Ê¼þÇÈ¿ô¤ò MHz ¤Çɽ¤ï¤·¤Þ¤¹¡£
+ | | +-- ¥Ü¡¼¥É¾å¤Î¥Õ¥ì¡¼¥à¥Ð¥Ã¥Õ¥¡¥á¥â¥ê¤ÎÂ礭¤µ
+ | +-- ¥Á¥Ã¥×¤Î·¿¼°
+ +-- ¥µ¡¼¥Ð¡¼¤Î¼ïÎà
+</verb></tscreen>
+
+Ãí°Õ: ¤Ê¤ë¤Ù¤¯¤³¤Îºî¶È¤Ï¥Þ¥·¥ó¤ÎÉé²Ù¤¬Ä㤤»þ¤Ë¹Ô¤Ê¤Ã¤Æ²¼¤µ¤¤¡£X ¤Ï¥¢¥×¥ê¥±
+¡¼¥·¥ç¥ó¤Ç¤¹¤«¤é¡¢¥Ç¥£¥¹¥¯¤Îưºî¤È»þ´ÖÄ´Àá¤Î¥ë¡¼¥×¤¬¾×ÆÍ¤¹¤ë¤È¡¢¾åµ­¤Î¿ô»ú
+¤ÏÉÔÀµ³Î¤Ë¤Ê¤ê¤Þ¤¹¡£²¿²ó¤«·«¤êÊÖ¤·¼Â¹Ô¤·¡¢¿ô»ú¤¬Â礭¤¯ÊÑÆ°¤·¤Ê¤¤¤³¤È¤ò³Î¤«
+¤á¤Æ²¼¤µ¤¤¡£¤â¤·ÊÑÆ°¤¬Â礭¤¤¾ì¹ç¤Ë¤Ï¡¢°ÂÄꤹ¤ë¤Þ¤Ç¥×¥í¥»¥¹¤ò»¦¤·¤Æ¤ß¤Æ¤¯¤À
+¤µ¤¤¡£SVr4¡Ê¥·¥¹¥Æ¥à V ¥ê¥ê¡¼¥¹ 4¡Ë ¤ò»ÈÍѤ·¤Æ¤¤¤ë¿Í¤Ø: mousemgr¡Ê¥Þ¥¦¥¹¥Þ
+¥Í¡¼¥¸¥ã¡¼¡Ë¥×¥í¥»¥¹¤ÏÆÃ¤Ëº®Íð¤Î¸µ¤Ç¤¹¡£
+
+¤³¤Î¤è¤¦¤ÊÉÔÀµ³Î¤µ¤òÈò¤±¤ë¤¿¤á¡¢ÆÀ¤é¤ì¤¿¥¯¥í¥Ã¥¯¤Î¿ô»ú¤ò¤½¤Î¤Þ¤Þ Clocks ¥×
+¥í¥Ñ¥Æ¥£¤ÎÃͤȤ·¤Æ Xconfig ¤Ë¼è¤ê¹þ¤ó¤Ç²¼¤µ¤¤¡£¤³¤ì¤Ï»þ´ÖÄ´Àá¤Î¥ë¡¼¥×¤òÍÞ
+»ß¤·¡¢X ¤¬»î¤·¤Æ¤ß¤ë¤³¤È¤Î¤Ç¤­¤ë¥¯¥í¥Ã¥¯¤ÎÃͤÎÀµ³Î¤Ê°ìÍ÷¤òÍ¿¤¨¤ë¤¿¤á¤Ç¤¹¡£
+¾åµ­¤ÎÎã¤Î¥Ç¡¼¥¿¤ò»È¤¦¤È¡¢¼¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
+
+<tscreen><verb>
+wga
+ Clocks 25 28 40 3 50 77 36 45 0 0 79 31 94 65 75 71
+</verb></tscreen>
+
+¹â¤¯ÊѤï¤ê¤ä¤¹¤¤Éé²Ù¤¬³Ý¤«¤Ã¤¿¥·¥¹¥Æ¥à¤Ç¤Ï¡¢¤³¤ÎÊýË¡¤Ï X ¤Îµ¯Æ°»þ¤Ë´Ù¤ë¤³
+¤È¤¬¤¢¤ëÉԻ׵ĤʼºÇÔ¤ò²óÈò¤¹¤ë½õ¤±¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£X ¤¬µ¯Æ°¤·¤¿»þ¥·¥¹¥Æ¥à¤Î
+Éé²Ù¤Î¤»¤¤¤Ç´Ö°ã¤Ã¤¿ÃͤòÆÀ¤Æ¤·¤Þ¤¤¡¢config ¥Ç¡¼¥¿¥Ù¡¼¥¹¤«¤éÃúÅÙ¤¤¤¤¥É¥Ã¥È
+¥¯¥í¥Ã¥¯¤ò¸«¤Ä¤±¤ë¤³¤È¤¬½ÐÍè¤Ê¤«¤Ã¤¿¤ê¡¢´Ö°ã¤Ã¤¿¤â¤Î¤ò¸«¤Ä¤±¤Æ¤·¤Þ¤¦¤³¤È¤¬
+¤¢¤êÆÀ¤ë¤Î¤Ç¤¹¡£
+
+The monitor's video bandwidth:
+
+¥â¥Ë¥¿¡¼¤Î¥Ó¥Ç¥ª¿®¹æÂÓ°èÉý :
+
+¥â¥Ë¥¿¡¼¤Î¥Ó¥Ç¥ª¿®¹æÂÓ°èÉý¤òÃΤäƤª¤¯¤³¤È¤Ï¡¢»ÈÍѤǤ­¤ëºÇ¤â¹â¤¤¥É¥Ã¥È¥¯¥í
+¥Ã¥¯¤Î¤ª¤ª¤è¤½¤ÎÃͤòÃΤë¤Î¤ËÍ­ÍѤǤ¹¡£¤·¤«¤·¡¢¤³¤ÎÃͤϽÀÆðÀ­¤ËÉÙ¤ó¤Ç¤¤¤Þ¤¹¡£
+Î㤨¤Ð¡¢Ì¾Ìܾå¤ÎÂÓ°èÉý¤Î 30% Áý¤·¤Çưºî¤Ç¤­¤ë¥â¥Ë¥¿¡¼¤â¤¢¤ê¤Þ¤¹¡£
+
+ÂÓ°èÉý¤òÃΤ뤳¤È¤Ï²Äǽ¤Ê¹½À®ÄêµÁ¤«¤é¤è¤ê¸­¤¤ÁªÂò¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£¤¢
+¤Ê¤¿¤Î¥Ç¥£¥¹¥×¥ì¥¤¤Îɽ¼¨ÉʼÁ¡ÊÆÃ¤Ë¹âÀººÙ¤Î¤¿¤á¤Î¥·¥ã¡¼¥×¤µ¡Ë¤Ë±Æ¶Á¤òµÚ¤Ü¤·
+¤Þ¤¹¡£
+
+¥â¥Ë¥¿¡¼¤Î¥Ó¥Ç¥ª¿®¹æÂÓ°èÉý¤Ï¥Þ¥Ë¥å¥¢¥ë¤Î»ÅÍͤÎÊǤ˺ܤäƤ¤¤Þ¤¹¡£Ìµ¤«¤Ã¤¿¾ì
+¹ç¤Ï¡¢¥â¥Ë¥¿¡¼¤ÎºÇ¤â¹â¤¤²òÁüÅ٤ΤȤ³¤í¤ò¸«¤Æ¤¯¤À¤µ¤¤¡£²òÁüÅÙ¤«¤éÂÓ°èÉý¡Ê¤Ä
+¤Þ¤ê»ÈÍѤǤ­¤ë¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ÎÂç¤Þ¤«¤Ê¾å¸ÂÃ͡ˤò¿äÄꤹ¤ë¤¿¤á¤Î·Ð¸³Â§¤ò²¼¤Ë
+¼¨¤·¤Þ¤¹¡£
+
+<tscreen><verb>
+ 640x480 25
+ 800x600 36
+ 1024x768 65
+ 1024x768 interlaced 45
+ 1280x1024 110
+</verb></tscreen>
+
+¤È¤³¤í¤Ç¡¢¤³¤Îɽ¤ÏÀäÂÐŪ¤Ê¤â¤Î¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤³¤ì¤é¤Î¿ô»ú¤Ïɸ½àŪ¤Ê
+XFree86 ¥â¡¼¥É¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ç¤Î²òÁüÅÙËè¤ÎºÇ¤âÄ㤤¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ç¤¹¡£¥â¥Ë¥¿
+¡¼¤ÎÂÓ°èÉý¤Ï°ìÈÖ¾å¤Î²òÁüÅÙ¤ËÍ׵ᤵ¤ì¤ëºÇ¾®¤ÎÂÓ°èÉý¤è¤ê¹â¤¤¤Ç¤·¤ç¤¦¤«¤é¡¢¶²
+¤ì¤º¤Ë¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ò¿ô MHz ¹â¤á¤Ë»î¤·¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£
+
+¤Þ¤¿¡¢¥É¥Ã¥È¥¯¥í¥Ã¥¯¤¬ 65MHz °Ì¤è¤êÄ㤤¾ì¹ç¤Ë¤ÏÂÓ°èÉý¤Ï¤Û¤È¤ó¤ÉÌäÂê¤Ë¤Ê¤é
+¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£SVGA ¤ä¤Û¤È¤ó¤É¤Î¹â²òÁüÅ٤Υâ¥Ë¥¿¡¼¤Ç¤Ï¡¢¤³¤ì
+¤Ï¥â¥Ë¥¿¡¼¤Î¥Ó¥Ç¥ª¿®¹æÂÓ°èÉý¤Î¸Â³¦¤è¤ê¤â¤Ï¤ë¤«¤ËÄ㤤¼þÇÈ¿ô¤Ç¤¹¤«¤é¡£¼¡¤ËÎã
+¤ò¼¨¤·¤Þ¤¹¡£:
+
+<tscreen><verb>
+ ¥Ö¥é¥ó¥É̾ ¥Ó¥Ç¥ª¿®¹æÂÓ°èÉý
+ ---------- ----------------
+ NEC 4D 75Mhz
+ Nano 907a 50Mhz
+ Nano 9080i 60Mhz
+ Mitsubishi HL6615 110Mhz
+ Mitsubishi Diamond Scan 100Mhz
+ IDEK MF-5117 65Mhz
+ IOCOMM Thinksync-17 CM-7126 136Mhz
+ HP D1188A 100Mhz
+ Philips SC-17AS 110Mhz
+ Swan SW617 85Mhz
+</verb></tscreen>
+
+°ìÈÖ²¼¤Î¥¯¥é¥¹¤Î¥â¥Ë¥¿¡¼¤Ç¤â¡¢²òÁüÅ٤˴ؤ·¤ÆÈó¾ï¤Ë¥Ó¥Ç¥ª¿®¹æÂÓ°èÉý¤ËÀ©Ìó¤ò
+¼õ¤±¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£NEC ¥Þ¥ë¥Á¥·¥ó¥¯ II ¤¬Îɤ¤Îã¤Ç¤¹¡Ê»ÅÍͤˤè¤ì¤Ð
+800x600¤Ïɽ¼¨½ÐÍè¤Ê¤¤¡Ë¡£¤½¤Î¥Ç¥£¥¹¥×¥ì¥¤¤Ï 800x560 ¤Î¤ßɽ¼¨¤Ç¤­¤Þ¤¹¡£¤³¤Î
+¤è¤¦¤ÊÄã²òÁüÅ٤ξì¹ç¤Ï¡¢¹â¤¤¥É¥Ã¥È¥¯¥í¥Ã¥¯¤äÂ礭¤Ê¥Ó¥Ç¥ª¿®¹æÂÓ°èÉý¤òɬÍפÈ
+¤·¤Ê¤¯¡¢Â¿Ê¬ 32Mhz ¤« 36Mhz ¤Ç½½Ê¬¤Ç¡¢Î¾Êý¤Î¼þÇÈ¿ô¤È¤â¥â¥Ë¥¿¡¼¤Î¥Ó¥Ç¥ª¿®¹æ
+ÂÓ°èÉý¤Ç¤¢¤ë30Mhz ¤«¤é¤½¤ìÄø¤«¤±Î¥¤ì¤¿ÃͤǤϤ¢¤ê¤Þ¤»¤ó¡£
+
+¤³¤ì¤é 2 ¤Ä¤Îưºî¼þÇÈ¿ô¤Ç¤Ï¡¢¥Ç¥£¥¹¥×¥ì¥¤¤Î»ý¤Ã¤Æ¤¤¤ëÀ­Ç½¤è¤ê¤¯¤Ã¤­¤ê¤Èɽ
+¼¨¤·¤Ê¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¤¬¡¢¤Ç¤â¤«¤Ê¤ê¤ÎÉʼÁ¤À¤È¸À¤¤ÀڤäƤ⤤¤¤¤Ç¤·¤ç¤¦¡£ÌÞ
+ÏÀ¡¢NEC ¥Þ¥ë¥Á¥·¥ó¥¯ II ¤¬¤â¤Ã¤È¹â¤¤¡¢Î㤨¤Ð 36MHz ¥Ó¥Ç¥ª¿®¹æÂÓ°èÉý¤ò»ý¤Ã
+¤Æ¤¤¤ë¤Ë±Û¤·¤¿¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤·¤«¤·¡¢Â礭¤¯²èÁü¤¬ÏĤàÄø¼þÇÈ¿ô¤¬¤«¤±Î¥¤ì
+¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢Ê¸¾Ï¤òÊÔ½¸¤¹¤ëÅù¤Î°ìÈÌŪ¤Êºî¶È¤Ë¤ÏÌäÂê¤Ï¤¢¤ê¤Þ¤»¤ó¡£¡Ê¤â¤·²è
+Áü¤ÎÏĤߤ¬¤¢¤Þ¤ê¤Ë¤âÂ礭¤¤¾ì¹ç¤Ë¤Ï¡¢ÌܤǸ«¤Æ¤¹¤°¤ï¤«¤ë¤Ç¤·¤ç¤¦¡Ë¡£
+
+¤É¤¦¤ä¤Ã¤ÆÀ©¸æ¤¹¤ë¤« :
+
+¥â¥Ë¥¿¡¼¤ÎƱ´ü¿®¹æÂÓ°èÉý¤Ï¡¢¥Ó¥Ç¥ª¥¢¥À¥×¥¿¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤È¶¦¤Ë¡¢É½¼¨¤Ç¤­
+¤ëºÇ¹â¤Î²òÁüÅÙ¤ò·èÄꤷ¤Þ¤¹¡£¤·¤«¤·¥Ï¡¼¥É¥¦¥§¥¢¤ÎÀ­Ç½¤ò°ú¤­½Ð¤¹¤Î¤Ï¥É¥é¥¤¥Ð
+¡¼¤Ç¤¹¡£¤É¤ó¤Ê¤ËÍ¥¤ì¤¿¥Ó¥Ç¥ª¥¢¥À¥×¥¿¤ä¥â¥Ë¥¿¡¼¤Ç¤â¡¢Îɤ¤¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¡¼
+¤¬¤Ê¤±¤ì¤ÐÊõ¤Î»ý¤ÁÉå¤ì¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¤¤Þ¤¹¡£°ìÊý¡¢Í­Ç½¤Ç¤Ê¤¤¥Ï¡¼¥É¤Ç¤â¿ÌÜŪ
+¤Ë»ÈÍѤǤ­¤ë¥Ç¥Ð¥¤¥¹¥É¥é¥¤¥Ð¤¬¤¢¤ì¤Ð½½Ê¬Ìò¤ËΩ¤Á¤Þ¤¹¡£¤³¤ì¤¬ XFree86 ¤ÎÀß·×ů
+³Ø¤Ç¤¹¡£
+
+<sect> ´ðËÜ»ÅÍÍ¤ÎÆÉ¤ßÊý
+<p>
+
+¤³¤ÎÀá¤Ç¤Ï»ÅÍͤ¬²¿¤ò°ÕÌ£¤¹¤ë¤«¤È¡¢¤½¤Î¾ÃΤé¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤³¤È¤òÀâÌÀ¤·¤Þ
+¤¹¡£À褺ºÇ½é¤Ë¡¢ÄêµÁ¤ò¤·¤Þ¤¹¡£¼¡¤Ë·×»»¤ò¤¹¤ë»þ¤Ë»È¤¦ÊÑ¿ô̾¤ò³ç¸ÌÆâ¤Ç¼¨¤·¤Þ
+¤¹¡£
+&lsqb;ÌõÃí¡§¤³¤ÎÄêµÁ¤À¤±¤ÏÂÐÌõÉ÷¤Ë¤·¤Þ¤¹¡£&rsqb;
+
+<descrip>
+<tag/horizontal sync frequency (HSF)/
+ Horizontal scans per second (see above).
+<tag/¿åʿƱ´ü¼þÇÈ¿ô (HSF)/
+ ËèÉäοåÊ¿Áöºº¿ô¡Ê¾åµ­»²¾È¡Ë¡£
+
+<tag/vertical sync frequency (VSF)/
+ Vertical scans per second (see above). Mainly important as the upper
+limit on your refresh rate.
+<tag/¿âľƱ´ü¼þÇÈ¿ô (VSF)/
+ ËèÉäοâľÁöºº¿ô¡Ê¾åµ­»²¾È¡Ë¡£¼ç¤ËºÆÉÁ²è®Å٤ξå¸Â¤È¤·¤Æ½ÅÍס£
+
+<tag/dot clock (DCF)/
+ More formally, `driving clock frequency'; sometimes loosely called
+`bandwidth'. The frequency of the crystal or VCO on your adaptor --- the
+maximum dots-per-second it can emit.
+<tag/¥É¥Ã¥È¥¯¥í¥Ã¥¯ (DCF)/
+ ¤è¤êÀµ¼°¤Ë¤Ï¡¢`¶îư¥¯¥í¥Ã¥¯¼þÇÈ¿ô'; »þ¡¹Å¬Åö¤Ë`ÂÓ°èÉý'¤È¸Æ¤Ö¡£¥¢¥À¥×
+¥¿¤Îȯ¿®»Ò¤Þ¤¿¤Ï VCO ¤Î¼þÇÈ¿ô --- ËèÉÃÉÁ²è²Äǽ¥É¥Ã¥È¿ô¤ÎºÇÂç¡£
+
+<tag/video bandwidth (VB)/
+ The highest frequency at which your monitor's video signal can change.
+This constrains the highest dot clock you can use and the overall sharpness
+of fine details in the video image.
+<tag/¥Ó¥Ç¥ª¿®¹æÂÓ°èÉý (VB)/
+ ¥â¥Ë¥¿¡¼¤Î¥Ó¥Ç¥ª¿®¹æ¤¬ÊѲ½¤Ç¤­¤ëºÇ¹â¤Î¼þÇÈ¿ô¡£¤³¤ì¤ÏºÇÂç¤Î¥É¥Ã¥È
+¥¯¥í¥Ã¥¯¤È²èÁüÁ´ÂΤ˾ܺÙɽ¼¨¤·¤¿»þ¤Î¥·¥ã¡¼¥×¤µ¤òÀ©Ìó¤·¤Þ¤¹¡£
+
+<tag/frame length (HFL, VFL)/
+ Horizontal frame length (HFL) is the number of dot-clock ticks needed for
+your monitor's electron gun to scan one horizontal line, *including the
+inactive left and right borders*. Vertical frame length (VFL) is the number
+of scan lines in the *entire* image, including the inactive top and bottom
+borders.
+<tag/¥Õ¥ì¡¼¥àĹ (HFL, VFL)/
+ ¿åÊ¿¥Õ¥ì¡¼¥àĹ (HFL) ¤Ï¥â¥Ë¥¿¡¼¤ÎÅŻҽƤ¬£±¤Ä¤Î¡ö»È¤ï¤ì¤Æ¤¤¤Ê¤¤º¸±¦
+¤Î¶­³¦¤ò´Þ¤à¡ö¿åÊ¿Àþ¤òÁöºº¤¹¤ë¤Î¤ËɬÍפʥɥåȥ¯¥í¥Ã¥¯¤Î¿ô¡£¿âľ¥Õ¥ì
+¡¼¥àĹ (VFL)¤Ï»È¤ï¤ì¤Æ¤¤¤Ê¤¤¾å¤È²¼¤Î¶­³¦¤ò´Þ¤à¡ö´°Á´¤Ê¡ö²èÌ̤ÎÁöººÀþ
+¤Î¿ô¤Ç¤¹¡£
+
+<tag/screen refresh rate (RR)/
+ The number of times per second your screen is repainted. Higher frequencies
+are better, as they reduce flicker. 60Hz is good, VESA-standard 72Hz is
+better. Compute it as
+<tscreen><verb>
+ RR = DCF / (HFL * VFL)
+</verb></tscreen>
+<tag/²èÌ̺ÆÉÁ²è®ÅÙ (RR)/
+ ËèÉäβèÌ̺ÆÉÁ²è²ó¿ô¡£¹â¤¤¤Û¤¦¤¬¤Á¤é¤Ä¤­¤òÄ㸺¤·¤Þ¤¹¡£60Hz¤ÇÎɤ¯¡¢
+VESA ɸ½à¤Î 72Hz ¤ÎÊý¤¬¤è¤êÎɤ¤¤Ç¤·¤ç¤¦¡£·×»»¤Ï¤³¤Î¤è¤¦¤Ë¤·¤Þ¤¹¡£
+<tscreen><verb>
+ RR = DCF / (HFL * VFL)
+</verb></tscreen>
+Note that the product in the denominator is *not* the same as the monitor's
+visible resolution, but typically somewhat larger. We'll get to the details
+of this below.
+ʬÊì¤Ë¤¢¤ëÀѤϥâ¥Ë¥¿¡¼¤Ëɽ¼¨¤µ¤ì¤ë²òÁüÅ٤Ǥϡö¤Ê¤¯¡ö¡¢´ö¤é¤«Â礭¤¤¤³
+¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤³¤ì¤Ë¤Ä¤¤¤Æ¤Ï°Ê¹ß¤Ç¾ÜºÙ¤ËÀâÌÀ¤·¤Þ¤¹¡£
+</descrip>
+
+ÂÓ°èÉý¤Ë¤Ä¤¤¤Æ :
+
+¥â¥Ë¥¿¡¼À½Â¤²ñ¼Ò¤ÏÂÓ°èÉý¤¬²èÌ̤ÎÇ÷ÎϤȿ§ÊѲ½¤Î¥·¥ã¡¼¥×¤µ¤òÀ©Ì󤹤ë¤Î¤Ç¹âÂÓ
+°èÉý¤Ç¤¢¤ë¤³¤È¤òÀëÅÁ¤·¤Þ¤¹¡£ÂÓ°èÉý¤¬Â礭¤¤¤Û¤É¡¢¤è¤êºÙ¤«¤¤²èÁü¤òɽ¼¨¤¹¤ë¤³
+¤È¤¬¤Ç¤­¤Þ¤¹¡£
+
+¥â¥Ë¥¿¡¼¤ÏÅŵ¤¿®¹æ¤òÍѤ¤¤Æ²èÁü¤òɽ¼¨¤·¤Þ¤¹¡£¿®¹æ¤Ï°ìö¥Ç¥¸¥¿¥ë¤«¤é¥¢¥Ê¥í¥°
+¤Ø¤ÈÊÑ´¹¤µ¤ì¤ë¤È¡¢¤Ä¤Í¤Ë¥¢¥Ê¥í¥°ÇÈ·Á¤È¤·¤Æ¼è¤ê°·¤ï¤ì¤Þ¤¹¡£¤½¤ì¤Ï¿¤¯¤Î¡¢¸Ç
+Äꤷ¤¿¼þÇÈ¿ô¤Îñ½ã¤ÊÇÈ·Á¤ÎÁȹ礻¤Ç¤¢¤ë¤È¹Í¤¨¤é¤ì¡¢¤½¤ì¤é¤Î¿¤¯¤Ï MHz ¤ÎÈÏ
+°Ï¤ÇÎ㤨¤Ð 20MHz¡¢40MHz¡¢¤µ¤é¤Ë 70MHz ¤À¤Ã¤¿¤ê¤·¤Þ¤¹¡£¥â¥Ë¥¿¡¼¤Î¥Ó¥Ç¥ª¿®¹æ
+ÂÓ°èÉý¤Ï»ö¼Â¾åÏĤߤ¬Ìµ¤¯°·¤¨¤ë¹â¼þÇȤΥ¢¥Ê¥í¥°¿®¹æ¤Ç¤¹¡£
+
+»äã¤ÎÌÜŪ¤Î¤¿¤á¤Ë¤Ï¡¢ÂÓ°èÉý¤Ï¼ç¤Ë»ÈÍѲÄǽ¤Ê¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Î¤ª¤ª¤è¤½¤Î¾å¸Â
+¤È¤·¤Æ½ÅÍפǤ¹¡£
+
+Ʊ´ü¼þÇÈ¿ô¤ÈºÆÉÁ²è®ÅÙ :
+
+²èÌ̾å¤Î¿åÊ¿ÁöººÀþ¤Ï¥Õ¥ì¡¼¥àĹÁöºº¤ÎÃæ¤Ç¼ÂºÝ¤Ëɽ¼¨¤µ¤ì¤ëÉôʬ¤Ç¤¹¡£¤½¤ì¤¾¤ì
+¤Î½Ö´Ö¤Ë¤ÏËÜÅö¤Ï¤¿¤Ã¤¿°ì¤Ä¤ÎÅÀ¤¬²èÌ̤˵±¤¤¤Æ¤¤¤ë¤Î¤Ç¤¹¤¬¡¢ºÆÉÁ²è®ÅÙ¤¬½½Ê¬
+®¤¤¤Î¤ÇÌܤˤÏÀ䤨´Ö̵¤¯Á´¤Æ¤Î²èÁü¤¬"¸«¤¨¤ë"¤È¤¤¤¦Ìõ¤Ç¤¹¡£
+
+¤³¤³¤Ç¤¤¤¯¤Ä¤«¤Î³¨¤Ç²òÀ⤷¤Þ¤¹ :
+
+<tscreen><verb>
+ _______________________
+| | ¿åÊ¿¥Õ¥ì¡¼¥àŤÏÅŻҥӡ¼¥à
+|->->->->->->->->->->-> | ¤¬¤³¤Î¤è¤¦¤Ê¥Ñ¥¿¡¼¥ó¤òÉÁ¤¯
+| )| »þ´Ö¤ò¥É¥Ã¥È¥¯¥í¥Ã¥¯Ã±°Ì¤Ç
+|<-----<-----<-----<--- | ɽ¤·¤¿¤â¤Î¤Ç¤¹¡£
+| |
+| |
+| |
+| |
+|_______________________|
+
+ _______________________
+| ^ | ¿âľ¥Õ¥ì¡¼¥àŤÏÅŻҥӡ¼¥à
+| ^ | | ¤¬¤³¤Î¤è¤¦¤Ê¥Ñ¥¿¡¼¥ó¤òÉÁ¤¯
+| | v | »þ´Ö¤ò¥É¥Ã¥È¥¯¥í¥Ã¥¯Ã±°Ì¤Ç
+| ^ | | ɽ¤·¤¿¤â¤Î¤Ç¤¹¡£
+| | | |
+| ^ | |
+| | v |
+| ^ | |
+|_______|_v_____________|
+</verb></tscreen>
+
+¼ÂºÝ¤Î¥é¥¹¥¿¡¼Áöºº¤Ï¤È¤Æ¤âºÙ¤«¤¤¥¸¥°¥¶¥°·¿¤Î¥Ñ¥¿¡¼¥ó¤ò¤·¤Æ¤¤¤Æ¡¢º¸±¦¤ËÅÅ»Ò
+¥Ó¡¼¥à¤¬Æ°¤¤¤ÆÆ±»þ¤Ë¾å²¼¤Ë¤âư¤¤¤Æ¤¤¤Þ¤¹¡£
+
+¤µ¤Æ¡¢¥É¥Ã¥È¥¯¥í¥Ã¥¯¤È¥Õ¥ì¡¼¥à¤ÎÂ礭¤µ¤ÏºÆÉÁ²è®Å٤˴ط¸¤¬¤¢¤ë¤È¤¤¤¦¤³¤È¤¬
+ʬ¤«¤ê¤Þ¤¹¡£ÄêµÁ¾å¡¢£±¥Ø¥ë¥Ä (hz) ¤Ï£±Éäˣ±¼þ´ü¤Ç¤¹¡£¤½¤ì¤«¤é¡¢¿åÊ¿¥Õ¥ì¡¼
+¥àŤò HFL ¤È¤·¿âľ¥Õ¥ì¡¼¥àŤò VFL ¤È¤·¤¿¾ì¹ç¤ËÁ´¤Æ¤Î²èÌ̤òʤ¤¦¤Ë¤Ï (HFL
+* VFL) ²ó¥É¥Ã¥È¥¯¥í¥Ã¥¯¤¬É¬ÍפǤ¹¡£¥«¡¼¥É¤ÏÄêµÁ¤«¤éËèÉà DCF ²ó¿®¹æ¤ò½Ð¤·¤Æ
+¤¤¤Þ¤¹¤Î¤Ç¡¢ÌÀ¤é¤«¤Ë¥â¥Ë¥¿¡¼¤ÎÅŻҽƤϺ¸¤«¤é±¦¡¢Ìá¤Ã¤Æ¡¢²¼¤«¤é¾å¤Ø¡¢Ìá¤Ã¤Æ
+¤òËèÉà DCF / (HFL * VFL) ²ó¡¢²èÌ̾å¤òư¤­²ó¤ì¤ëÌõ¤Ç¤¹¡£¤³¤ì¤ÏËèÉò¿²ó²èÌÌ
+¤òÉÁ¤­Ä¾¤·¤Æ¤¤¤ë¤«¤òɽ¤ï¤·¤Æ¤¤¤ë¤Î¤Ç¡¢²èÌ̤κÆÉÁ²è®Å٤ʤΤǤ¹¡£
+
+²òÁüÅ٤ȤÁ¤é¤Ä¤­¤Î´Ø·¸¤¬¥È¥ì¡¼¥É¥ª¥Õ¤Î´Ø·¸¤Ë¤¢¤ë¤Î¤Ç¡¢¼«Ê¬¤ÎÍ×µá¤Ë±þ¤¸¤ÆÀß
+Äê¤ò¹Ô¤Ê¤¦¤¿¤á¤Ë¤³¤Î³µÇ°¤òÍý²ò¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
+
+<sect> ¥·¥¹¥Æ¥à¤Î¹½À®¤Ë¤ª¤±¤ë¥È¥ì¡¼¥É¥ª¥Õ
+<p>
+
+Á°¤Ë¼¨¤·¤¿¸ø¼°¤Ï¡¢¤³¤Î¤è¤¦¤ËÊÑ·Á¤Ç¤­¤Þ¤¹¡£
+<tscreen><verb>
+ DCF = RR * HFL * VFL
+</verb></tscreen>
+¤Ä¤Þ¤ê¡¢¥É¥Ã¥È¥¯¥í¥Ã¥¯¤¬°ìÄê¤À¤È¤¹¤ë¤È¡¢°ìÉô֤ˤ³¤ì¤À¤±¤Î¥É¥Ã¥È¿ô¤òºÆÉÁ²è
+®ÅÙ¡¢¿åÊ¿²òÁüÅÙ¤Þ¤¿¤Ï¿âľ²òÁüÅ٤˿¶¤êʬ¤±¤ë¤³¤È¤¬¤Ç¤­¤ë¤È¤¤¤¦¤³¤È¤Ç¤¹¡£¤³
+¤ì¤é¤Î¿ô»ú¤Î°ì¤Ä¤òÁý¤ä¤¹¤È¾¤Î¿ô»ú¤ò¸º¤é¤µ¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£
+
+¤·¤«¤·¡¢ºÆÉÁ²è®Å٤ϥâ¥Ë¥¿¡¼¤ÎºÇÂç¿âľƱ´ü¼þÇÈ¿ô¤òͤ¨¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¤Î
+¤Ç¡¢Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£½¾¤Ã¤ÆÍ¿¤¨¤é¤ì¤¿¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ÇÍ¿¤¨¤é¤ì¤¿¥â¥Ë¥¿¡¼¤Ç
+¤Ï¡¢¼«Ê¬¤Ç¶¯À©½ÐÍè¤Ê¤¤¥Õ¥ì¡¼¥àŤÎÀѤκǾ®°Ê²¼¤Ë¤Ê¤ê¤Þ¤¹¡£
+
+¼«Ê¬¤ÎÀßÄê¤òÁª¤Ö»þ¤Ë¡¢RR ¤¬Ä㤹¤®¤ë¾ì¹ç¡¢²èÌ̤ΤÁ¤é¤Ä¤­¤Ç´é¤ò¤·¤«¤á¤ë¤³¤È
+¤ò³Ð¤¨¤Æ¤¯¤À¤µ¤¤
+
+¿ʬ¡¢ºÆÉÁ²è®ÅÙ¤ò 60Hz °Ê²¼¤Ë²¼¤²¤¿¤¯¤Ï̵¤¤¤Ç¤·¤ç¤¦¡£·Ö¸÷Åõ¤Î¤Á¤é¤Ä¤¯Â®¤µ
+¤Ç¤¹¤Î¤Ç¡¢¤Á¤é¤Ä¤­¤ËÉÒ´¶¤Ê¾ì¹ç¤Ï VESA ¿Í´Ö¹©³ØÉ¸½à¤Î 72MHz ¤ËÊݤÄɬÍפ¬¤¢
+¤ê¤Þ¤¹¡£
+
+¤Á¤é¤Ä¤­¤ÏÂçÊÑÌܤ˿ɤ¤¤â¤Î¤Ç¤¹¤¬¡¢¤·¤«¤·¿Í´Ö¤ÎÌܤÏŬ±þ¤·¿Í¡¹¤Î¤Á¤é¤Ä¤­¤ËÂÐ
+¤¹¤ëÂÑÀ­¤Ï¤«¤Ê¤ê¹­ÈϰϤǤ¹¡£²èÌ̤Π90% ¤¬¸«¤¨¤ë³ÑÅ٤ǥâ¥Ë¥¿¡¼¤Ë¸þ¤­¹ç¤Ã¤Æ
+¤¤¤ë¾ì¹ç¤Ë¡¢°Å¤¤ÇطʤÈÎɤ¤¥³¥ó¥È¥é¥¹¥È¤Î¿§¤òÁ°·Ê¤Ë»È¤¤¡¢µ±ÅÙ¤òÄ㤫¤éÃæ¤ËÄ´
+À°¤¹¤ë¤Ê¤é¤Ð¡¢¡ö¤¿¤Ö¤ó¡ö 45Hz °Ì¤Ë¾®¤µ¤¯¤Æ¤â²÷Ŭ¤Ç¤·¤ç¤¦¡£
+
+¸·Ì©¤Ê¥Æ¥¹¥È¤Î¤ä¤êÊý¤Ï¼¡¤ÎÄ̤ê¤Ç¤¹ : xterm -bg white -fg black ¤Ç¿¿¤ÃÇò¤Ê
+ÇØ·Ê¤Ë¹õ¤ÎÁ°·Ê¤Î xterm ¤ò³«¤¤¤Æ¡¢É½¼¨²Äǽ¤ÊÎΰèÁ´¤Æ¤ò±£¤¹¤°¤é¤¤¤ÎÂ礭¤µ¤Ë
+¤·¤Æ²¼¤µ¤¤¡£¤½¤·¤Æ¥â¥Ë¥¿¡¼¤ÎÌÀ¤«¤ë¤µ¤òºÇÂç¤ÎÀßÄêÃͤΠ3/4 ¤ËÀßÄꤷ¤Æ¡¢¥â¥Ë
+¥¿¡¼¤«¤é´é¤ò¤½¤à¤±¤Æ¡¢¥â¥Ë¥¿¡¼¤ò²£ÌܤÇÇÁ¤¤¤Æ¤ß¤Æ²¼¤µ¤¤¡Ê¤³¤ì¤Ï¡¢¤è¤êÉÒ´¶¤Ê
+»ëÌî¼þÊÕÉô¤ÎºÙ˦¤òƯ¤«¤»¤ë¤¿¤á¤Ç¤¹¡Ë¡£¤Ê¤ó¤Ë¤â¤Á¤é¤Ä¤­¤ò´¶¤¸¤Ê¤¤¾ì¹ç¼ã¤·¤¯
+¤Ïµö¤»¤ëÈϰϤʤé¤Ð¡¢¤¢¤Ê¤¿¤Ë¤È¤Ã¤Æ¤½¤ÎºÆÉÁ²è®ÅÙ¤ÏÃúÅÙÎɤ¤¤Î¤Ç¤¹¡£¤â¤·¤½¤¦
+¤Ç¤Ê¤«¤Ã¤¿¤é¡¢°ì¸«Âç¾æÉפʤ褦¤Ë¸«¤¨¤Æ¤â¡¢ÌÀ¤é¤«¤Ë¤ÏȽ¤«¤é¤Ê¤¤¤è¤¦¤Ê¤Á¤é¤Ä
+¤­¤Ë¤è¤Ã¤Æ¤Ò¤É¤¯Ìܤ¬ÈèÏ«¤·Æ¬Äˤòµ¯¤³¤·¤Þ¤¹¤Î¤Ç¡¢ÉáÄ̤˸«¤¨¤ëÍͤˤʤëËø¡¢¤è
+¤ê¹â¤¤ºÆÉÁ²è®ÅÙ¤ËÄ´À°¤·¤Æ²¼¤µ¤¤¡£
+
+¤³¤Î¤è¤¦¤Ë¤·¤ÆºÇ¾®¤ÎµöÍÆ¤Ç¤­¤ëºÆÉÁ²è®ÅÙ¤òÁª¤Ö¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£HFL ¤È VFL
+¤òÁªÂò¤¹¤ë¤¿¤á¤Ë¤Ï¡¢Â¿¾¯¤ÎºîÀï¤Î;ÃϤ¬¤¢¤ë¤Ç¤·¤ç¤¦¡£
+
+<sect>Í×µá¥á¥â¥êÎÌ
+<p>
+
+¼«Ê¬¤¬¼Â¸½¤·¤è¤¦¤È¤·¤Æ¤¤¤ë¥«¥é¡¼¤ä¥°¥ì¡¼¥¹¥±¡¼¥ë¥Ç¥£¥¹¥×¥ì¥¤¤Î²òÁüÅ٤ϻÈÍÑ
+²Äǽ¤Ê¥Õ¥ì¡¼¥à¥Ð¥Ã¥Õ¥¡¥á¥â¥ê¤ÎÎ̤ÇÀ©¸Â¤µ¤ì¤Þ¤¹¡£2 ¿§¡ÊÇò¹õ¡Ë¤Ç¥°¥ì¡¼¥¹¥±¡¼
+¥ë¤Ç¤Ê¤¤Êª¤Î¾ì¹ç¤Ï¡¢À©¸Â¤ò¼õ¤±¤ë¤³¤È¤Ï¿ʬ¤¢¤ê¤Þ¤»¤ó¡£
+
+256 ¿§¤Î¥Ç¥£¥¹¥×¥ì¥¤¤Î¾ì¹ç¤Ï¡¢¥Ó¥Ç¥ª¥á¥â¥ê¤Î¥Ð¥¤¥È¿ô¤Ïɽ¼¨¤µ¤ì¤ë¥É¥Ã¥È¤Î¿ô
+¤À¤±É¬ÍפǤ¹¡£¤³¤Î¥Ð¥¤¥È¿ô¤ÏÀÖÎÐÀĤ«¤éÀ®¤ë½¸¹ç¤ÎÅÀ¤ò£±ÅÀ¤È¤·¤¿¿ô¤Ç¤¹¡£É¬Í×
+¤Ê¥á¥â¥êÎ̤òÆÀ¤ë¤Ë¤Ï¡¢Àþ£±ËÜÅö¤¿¤ê¤Ëɽ¼¨¤µ¤ì¤ëÅÀ¤Î¿ô¤Ëɽ¼¨¤µ¤ì¤ëÀþ¤Î¿ô¤ò³Ý
+¤±¤Æ²¼¤µ¤¤¡£800x600 ¤Î²òÁüÅÙ¤ò»ý¤Ä¥Ç¥£¥¹¥×¥ì¥¤¤Î¾ì¹ç¤Ï¡¢¥Ç¥£¥¹¥×¥ì¥¤¤Ëɽ¼¨
+¤¹¤ëÅÀ¤Î¿ô¤Ï 800 x 600 = 480,000 ¤Ë¤Ê¤ê¤Þ¤¹¡£¤Þ¤¿¡¢£±¥É¥Ã¥È¤¬£±¥Ð¥¤¥È¤ËÀ®
+¤ë¤Î¤Ç¡¢¥¢¥À¥×¥¿¥«¡¼¥É¤ËƱ¤¸¥Ð¥¤¥È¿ô¤Î¥Ó¥Ç¥ª¥á¥â¥ê¤¬É¬ÍפǤ¹¡£
+
+½¾¤Ã¤Æ¡¢¥á¥â¥êÎ̤ϡ¢°ìÈÌ¤Ë (HR * VR)/1024 ¤ò¥­¥í¥Ð¥¤¥Èñ°Ì¤ËÀÚ¤ê¾å¤²¤¿Êª¤¬
+ɬÍפǤ¹¡£Îã¤òµó¤²¤ì¤Ð¡¢ (936 * 702)/1024 = 642K ¥Ð¥¤¥È¤È¤Ê¤ê¤Þ¤¹¡£½¾¤Ã¤Æ
+1M ¥Ð¥¤¥È¤Î¥á¥â¥ê¤¬¤¢¤ì¤Ð¡¢Í¾¤ê¤ò²¾ÁÛ¥¹¥¯¥ê¡¼¥ó¤Ë³ä¤êÅö¤Æ¤Æ¥¹¥¯¥í¡¼¥ë½ÐÍè
+¤Þ¤¹¡£
+
+¤È¤³¤í¤¬¡¢¥Ü¡¼¥É¤Ë 512K ¤·¤«Ìµ¤¤¾ì¹ç¤Ï¤³¤Î²òÁüÅ٤ϻȤ¨¤Þ¤»¤ó¡£Îɤ¤¥â¥Ë¥¿¡¼
+¤ò»ý¤Ã¤Æ¤¤¤¿¤È¤·¤Æ¤â¡¢½½Ê¬¤Ê¥Ó¥Ç¥ª¥á¥â¥ê¤¬Ìµ¤·¤Ë¤Ï¥â¥Ë¥¿¡¼¤ÎÀ­Ç½¤ò³è¤«¤¹¤³
+¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£¤Þ¤¿°ìÊý¤Ç¡¢SVGA ¥«¡¼¥É¤¬ 1M ¥Ð¥¤¥È¤Î¥á¥â¥ê¤ò»ý¤Ã¤Æ¤¤¤¿¤È
+¤·¤Æ¤â¡¢¥â¥Ë¥¿¡¼¤¬ºÇ¹â¤Ç 800x600 ¤·¤«É½¼¨¤Ç¤­¤Ê¤¤¤Ê¤é¤Ð¡¢¤³¤ì°Ê¾å¤Î¹â²òÁü
+Å٤Ϥɤ¦¤ä¤Ã¤Æ¤â̵Íý¤È¤¤¤¦¤â¤Î¤Ç¤¹¡£
+
+Í×µáÎ̤è¤ê¿¤¤¥á¥â¥ê¤ò»ý¤Ã¤Æ¤¤¤Æ¤â¿´ÇÛ¤·¤Ê¤¤¤Ç²¼¤µ¤¤¡£XFree86 ¤Ï;¤Ã¤¿¥á¥â
+¥ê¤Çɽ¼¨Îΰè¤ò¥¹¥¯¥í¡¼¥ë¤Ç¤­¤ë¤è¤¦¤Ë¤·¤Þ¤¹¡Ê²¾ÁÛ¥¹¥¯¥ê¡¼¥ó¤ÎÂ礭¤µ¤Î¥Ñ¥é¥á
+¡¼¥¿¤Ë¤Ä¤¤¤Æ¤Î Xconfig ¥Õ¥¡¥¤¥ë¤Îʸ½ñ¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡Ë¡£¤Þ¤¿¡¢512K ¥Ð¥¤¥È
+¤Î¥á¥â¥ê¤òÅëºÜ¤·¤¿¥«¡¼¥É¤Ï 512,000 ¥Ð¥¤¥È¤Ç¤Ï¤Ê¤¯¡¢ËÜÅö¤Ï 512 x 1024 =
+524,288 ¥Ð¥¤¥È¤Î¥á¥â¥ê¤¬ÅëºÜ¤µ¤ì¤Æ¤¤¤ë¤³¤È¤ò³Ð¤¨¤Æ¤¤¤Æ²¼¤µ¤¤¡£
+
+S3 ¥«¡¼¥É¤Ç SGCS X ¤¬Æ°ºî¤·¤Æ¤¤¤Æ¡¢¤«¤Ä 16 ¿§¡Ê 1 ¥Ô¥¯¥»¥ëÅö¤¿¤ê 4 ¥Ó¥Ã¥È¡Ë
+¤Î¾ì¹ç¡¢Xconfig ¥Õ¥¡¥¤¥ë¤Ç ¿¼¤µ 4 ¤ÈÀßÄꤹ¤ì¤Ð¡¢¥«¡¼¥É¤ÏÇܤβòÁüÅÙ¤ò»È¤¨¤Þ
+¤¹¡£Î㤨¤Ð¡¢S3 ¥«¡¼¥É¤ÏÄ̾ï 1024x768x256 ¡Ê1024x768 ¤Î²òÁüÅÙ¤Ç 256 ¿§¡Ë¤Ç
+¤¹¤¬¡¢¿¼¤µ 4 ¤Ë¤¹¤ì¤Ð 1280x1024x16 ¡Ê1280x1024 ¤Î²òÁüÅÙ¤Ç 16 ¿§¡Ë¤¬»È¤¨¤ë
+¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
+&lsqb;ÌõÃí : ¿¼¤µ¤È¤Ï¿§¿ô¤ä¥°¥ì¡¼¥¹¥±¡¼¥ë¤òɽ¸½¤¹¤ë¥Ó¥Ã¥È¿ô¤Ç¤¹¡£&rsqb;
+
+<sect>¥Õ¥ì¡¼¥à¥µ¥¤¥º¤Î·×»»
+<p>
+
+·Ù¹ð : ¤³¤ÎÊýË¡¤Ï¥Þ¥ë¥Á¥·¥ó¥¯¥â¥Ë¥¿¡¼¤Î¤¿¤á¤Ë³«È¯¤·¤Þ¤·¤¿¡£Â¿Ê¬¡¢¤³¤ÎÊýË¡
+¤Ï¸ÇÄê¼þÇÈ¿ô¥â¥Ë¥¿¡¼¤Ç¤¦¤Þ¤¯¹Ô¤¯¤«¤âÃΤì¤Þ¤»¤ó¤¬¡¢ÊݾڤǤ­¤Þ¤»¤ó¡£
+
+ºÇ½é¤ËºÇÂç¤Î»ÈÍѲÄǽ¤Ê HSF ¤Ç DCF ¤ò³ä¤Ã¤Æ¡¢¿åÊ¿Áöºº²Äǽ²ó¿ô¤ò
+·×»»¤·¤Æ²¼¤µ¤¤¡£
+
+Î㤨¤Ð¡¢ 65MHz ¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Î Sigma Legend SVGA ¥«¡¼¥É¤È¡¢55KHz ¤Î¿åÊ¿
+Áöºº¼þÇÈ¿ô¤Î¥â¥Ë¥¿¡¼¤ò»È¤Ã¤Æ¤¤¤ë¤È²¾Äꤷ¤Þ¤¹¡£DCF / HSF ¤ò·×»»¤¹¤ë¤È 1181
+¤È¤¤¤¦Î̤¬ÆÀ¤é¤ì¤Þ¤¹¡£
+
+¤µ¤¢¡¢ºÇ½é¤Î¹õËâ½Ñ¤Îµ»¤ÎÊÒÎÚ¤ò»È¤¤¤Þ¤·¤ç¤¦¡£¤³¤Î¼°¤ÎÅú¤¨¤ò¤â¤Ã¤È¤â¶á¤¤ 8
+¤ÎÇÜ¿ô¤Ë´Ý¤á¤Æ²¼¤µ¤¤¡£¤³¤ì¤Ï 8 ¥Ó¥Ã¥È¥ì¥¸¥¹¥¿¤ò»ý¤Á¡¢º¸¤Ë 3 ¥Ó¥Ã¥È¤º¤é¤·¤Æ
+11 ¥Ó¥Ã¥È¤ÎÃͤòÆÀ¤ë¤è¤¦¤Ê SVGA ¤È S3 ¤Î VGA À©¸æÁõÃ֤ˤª¤¤¤ÆÍ­¸ú¤Ç¤¹¡£ ATI
+8514/A ¤Î¤è¤¦¤Ê¾¤Î¥«¡¼¥É¤Ç¤Ï¤³¤Î¤è¤¦¤ÊÍ×µá¤Ï¤Ê¤¤¤«¤âÃΤì¤Þ¤»¤ó¤¬¡¢²æ¡¹¤Ï
+Àµ³Î¤ÊÃ챤ò»ý¤Á¹ç¤ï¤»¤Æ¤Ï¤¤¤Þ¤»¤ó¤·¡¢´Ý¤á¤Ë¤è¤Ã¤ÆÉÔÅÔ¹ç¤Ê¤³¤È¤¬À¸¤¸¤ë¤³¤È
+¤Ï¤¢¤ê¤Þ¤»¤ó¡£½¾¤Ã¤Æ¿åÊ¿Áöºº²Äǽ²ó¿ô¤ò 1176 ¤Ë´Ý¤á¤Þ¤¹¡£
+
+¤³¤Î¿ô»ú¡ÊDCF / HSF ¤ò 8 ¤ÎÇÜ¿ô¤Ë´Ý¤á¤¿¤â¤Î¡Ë¤ÏºÇ¾®¤Î HFL ¤È¤·¤ÆÍѤ¤¤ë¤³¤È
+¤¬½ÐÍè¤Þ¤¹¡£¤è¤êÄ㤤 HSF ¤ÇƱ´ü¿®¹æ¤òÀßÄꤹ¤ì¤Ð¡¢¤â¤Ã¤ÈŤ¤ HFL ¡Ê¤Ä¤Þ¤ê¡¢
+¿ʬ¤è¤ê¿¤¯¤Î²èÌ̤οåÊ¿Êý¸þ¤Î¥É¥Ã¥È¿ô¡Ë¤¬ÆÀ¤é¤ì¤Þ¤¹¡£¤·¤«¤·¡¢ÃÙ¤¯¤Æ¤è¤ê¿
+¤¯¸«¤¨¤ë¤Á¤é¤Ä¤­¤Î®ÅÙ¤ËÉü½²¤µ¤ì¤ë¤Ç¤·¤ç¤¦¡£
+
+·Ð¸³Åª¤Êˡ§¤Ç¤Ï¡¢¿åÊ¿¥Õ¥ì¡¼¥àŤΠ80% ¤¬¿åÊ¿²òÁüÅ٤Ȥ·¤Æ»ÈÍѲÄǽ¤Ç¡¢¿åÊ¿
+ÁöººÀþ¤Îɽ¼¨¤µ¤ì¤ëÉôʬ¡Ê¤³¤ì¤ÏÂçÂΡ¢¶­³¦¤ÈÅŻҥӡ¼¥à¤¬²èÌ̤α¦Ã¼¤«¤é¼¡¤ÎÁö
+ººÀþ¤Îº¸Ã¼¤ØÌá¤Ã¤Æ¤¯¤ë»þ´Ö¤òº¹¤·°ú¤¤¤¿¤â¤Î¡Ë¤Ç¤¹¡£¤³¤ÎÎã¤Ç¤Ï¡¢944 ¤Ë¤Ê¤ê¤Þ
+¤¹¡£
+
+¤µ¤Æ¡¢Ä̾ï¤Î²èÌ̤Υ¢¥¹¥Ú¥¯¥ÈÈæ¡Ê²£½ÄÈæ¡Ë4:3 ¤òÆÀ¤ë¤¿¤á¡¢º£·×»»¤·¤¿¿åÊ¿²òÁü
+Å٤Π3/4 ¤Ë¤Ê¤ë¤è¤¦¤Ë¿âľ²òÁüÅÙ¤òÀßÄꤷ¤Þ¤·¤ç¤¦¡£¤³¤ÎÎã¤Ç¤Ï¡¢708 ¤Ë¤Ê¤ê¤Þ
+¤¹¡£¼ÂºÝ¤Î VFL ¤òÆÀ¤ë¤Ë¤Ï¡¢1.05 ¤ò³Ý¤±¤Æ 743 ¤Ë¤Ê¤ê¤Þ¤¹¡£
+
+¤³¤Î 4:3 ¤Ë¤Ä¤¤¤Æ --- ɽ¼¨¾å¤ÎÉý¤È¹â¤µ¤¬ 4:3 ¤ÎÈæÎ¨¤ÏÂçÂβ«¶âʬ³äÈæ¤ÎÃÍ¡¢
+(1 + sqrt(5))/2 ¤Ë¶á¤¤ÃͤǤ¹¡£¿Í´Ö¤Ï¤³¤Î¼ï¤Î¶ë·Á¤ò¸«¤Æ¹¥¤Þ¤·¤¤¤È»×¤¦¤è¤¦¤Ë
+¤Ç¤­¤Æ¤¤¤ë¤è¤¦¤Ç¤¹¡£¤½¤Î¤¿¤á¥Ö¥é¥¦¥ó´É¤ä 800x600, 640x480 ¤½¤·¤Æ 1024x768
+¤È¤¤¤¦É¸½àŪ¤Ê²òÁüÅ٤Ϥߤʤ³¤Î²«¶âʬ³äÈæ¤Î¶á»÷ÃͤˤʤäƤ¤¤Þ¤¹¡£¤·¤«¤·¤³¤ì
+¤Ï¿´Íý³ØÅª¤ÊÍ×µá¤Ç¤¢¤Ã¤Æ¡¢µ»½ÑŪ¤ÊÍ×µá¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤â¤·¤½¤ÎÊý¤¬²èÌ̤Î
+Â礭¤µ¤òÍ­¸ú¤Ë³èÍѤǤ­¤ë¤Î¤Ç¤¢¤ì¤Ð¡¢È󲫶âʬ³äÈæ¤ò»È¤¦¤³¤È¤ò¤¿¤á¤é¤¦Íýͳ¤Ï
+²¿¤â¤¢¤ê¤Þ¤»¤ó¡£
+
+·ë¶É¡¢HFL=1176 ¤È VFL=743 ¤È¤·¤Þ¤·¤¿¡£65MHz ¤ò¤³¤Î 2 ¤Ä¤Î¿ô»ú¤ÎÀѤdzä¤ë¤È¡¢
+½½Ê¬¤Ë¹â¤¯¤Æ·ò¹¯¤ËÎɤ¤ 74.4Hz ¤ÎºÆÉÁ²è®ÅÙ¤¬ÆÀ¤é¤ì¤Þ¤¹¡£ÁÇÀ²¤é¤·¤¤¡ª
+VESA ɸ½à¤è¤êΩÇɤǤ·¤ç¤¦¡ª ¤ª¤Þ¤±¤Ë¡¢¤ª¤½¤é¤¯Í½ÁÛ¤·¤Æ¤¤¤¿ 800x600 ¤è¤ê¤â
+¹â¤¤ 944x708 ¤È¤¤¤¦²òÁüÅÙ¤¬ÆÀ¤é¤ì¤¿¤Î¤Ç¤¹¡£ËÜÅö¤ËÁÇÀ²¤é¤·¤¤¡ª
+
+¤µ¤é¤Ë¡ÊÂçÂÎ 76 Hz Ëø¡ËºÆÉÁ²è®ÅÙ¤ò²þÎɤ¹¤ë¤³¤È¤â²Äǽ¤Ç¤¹¡£¤³¤ì¤Ë¤Ï¡¢Äê³Ê
+¤è¤ê¤â 2 KHz ¤¯¤é¤¤¹â¤¤¿åʿƱ´ü¼þÇÈ¿ô¤Ç¤âư¤¯¥â¥Ë¥¿¡¼¤¬Â¿¤¤¤È¤¤¤¦»ö¼Â¤È¡¢
+VFL ¤ò´ö¤é¤«²¼¤²¤ë¡Ê¤Ä¤Þ¤ê¡¢¾å¤ÎÎã¤Ç¸À¤¦¤È 944 ¤Î 75% ¤è¤ê¤â¾®¤µ¤¯¤¹¤ë¡Ë¤³
+¤È¤òÍøÍѤ·¤Þ¤¹¡£¤·¤«¤·¤³¤Î "¥ª¡¼¥Ð¡¼¥É¥é¥¤¥Ö" ºîÀï¤ò»î¤·¤Æ¤ß¤ëÁ°¤Ë¡¢¤¢¤Ê¤¿
+¤Î¥â¥Ë¥¿¡¼¤ÎÅŻҽƤ¬¿âľƱ´ü¤ò 76 Hz °Ê¾å¤Ç¤Ç¤­¤ë¤³¤È¤ò¡ö³Îǧ¡ö¤·¤Æ¤¯¤À¤µ
+¤¤¡£¡ÊÎ㤨¤Ð¡¢¿Íµ¤¤Î¤¢¤ë NEC 4D ¤Ç¤Ï¤³¤ì¤Ï½ÐÍè¤Þ¤»¤ó¡£¤³¤ì¤Ï 75 Hz Ëø¤Î
+VSF ¤Î¤ß¤¬ÍøÍѤǤ­¤Þ¤¹¡£¡Ë
+
+°Ê¾å¤¬¡¢¥é¥¹¥¿¡¼É½¼¨¤Ë¤Ä¤¤¤Æ¤Îñ½ã¤Ê·×»»¤È´ðËÜŪ¤Ê»öÊÁ¤Î¤Û¤È¤ó¤É¤Ç¤¹¡£¤Û¤È
+¤ó¤É¹õËâ½Ñ¤Ç¤â²¿¤Ç¤â̵¤¤¤Ç¤¹¤Í¡£
+
+<sect> ¹õËâ½Ñ¤ÈƱ´ü¿®¹æ
+<p>
+¤µ¤¢¡¢¼«Ê¬¤ÇÁª¤ó¤À¥É¥Ã¥È¥¯¥í¥Ã¥¯Âбþ¤Ë·×»»¤·¤¿ HFL/VFL ¤Î¿ô»ú¤¬¤¢¤ê¡¢ÌµÆñ
+¤ÊºÆÉÁ²è®ÅÙ¤¬¸«¤Ä¤«¤ê¡¢½½Ê¬¤Ê VRAM ¡Ê¥Ó¥Ç¥ª¥á¥â¥ê¡Ë¤¬¤¢¤ë¤³¤È¤ò³Îǧ¤·¤Þ¤·
+¤¿¡£¤³¤ì¤«¤é¤¬ËÜÅö¤Î¹õËâ½Ñ¤Ç¤¹ -- ¤¤¤Ä¤É¤³¤ÇƱ´ü¿®¹æ¤ò½Ð¤¹¤«¤òÃΤëɬÍפ¬¤¢
+¤ê¤Þ¤¹¡£
+
+Ʊ´ü¿®¹æ¤¬¼ÂºÝ¤Ë¥â¥Ë¥¿¡¼¤Î¿åÊ¿µÚ¤Ó¿âľ¤ÎÁöºº¼þÇÈ¿ô¤òÀ©¸æ¤·¤Æ¤¤¤Þ¤¹¡£»ÅÍÍɽ
+¤«¤é°ú¤Ã¤Ñ¤ê½Ð¤·¤Æ¤­¤¿ HSF ¤È VSF ¤ÏÄê³Ê¾å¤ÎºÇÂçÆ±´ü¼þÇÈ¿ô¤Î¿äÄêÃͤǤ¹¡£¥¢
+¥À¥×¥¿¥«¡¼¥É¤«¤é¤Î¿®¹æ¤ÎÃæ¤ÎƱ´ü¿®¹æ¤Ï¥â¥Ë¥¿¡¼¤Ë¤É¤ì¤¯¤é¤¤Â®¤¯¼ÂºÝ¤Ëưºî¤¹
+¤ë¤«ÅÁ¤¨¤Þ¤¹¡£
+
+¾åµ­¤Î 2 ¤Ä¤Î³¨¤ò»×¤¤½Ð¤·¤Æ²¼¤µ¤¤¡£Ìܤ˸«¤¨¤ë²èÁü¡Ê¤¢¤Ê¤¿¤ÎÁª¤ó¤À²òÁüÅÙ¡Ë
+¤òɽ¼¨¤¹¤ë¤¿¤á¤Ë»È¤ï¤ì¤ë¤Î¤Ï¡¢¥Õ¥ì¡¼¥à¤ò¥é¥¹¥¿¡¼Áöºº¤¹¤ë¤¿¤á¤ËɬÍפʻþ´Ö¤Î
+°ìÉô¤À¤±¤Ç¤¹¡£
+
+¿åʿƱ´ü :
+
+Á°¤ÎÄêµÁ¤Ë¤è¤ì¤Ð¡¢£±ËܤοåÊ¿ÁöººÀþ¤ò¤¿¤É¤ë¤Î¤Ë¤Ï HFL ʬ¤Î»þ´Ö³Ý¤«¤ê¤Þ¤¹¡£
+ɽ¼¨¤µ¤ì¤ëÉôʬ¤Î¥¯¥í¥Ã¥¯²ó¿ô¡Ê¿åÊ¿¥¹¥¯¥ê¡¼¥ó²òÁüÅ١ˤò HR ¤È¸Æ¤Ó¤Þ¤·¤ç¤¦¡£
+¤½¤Î»þ¤ÏÌÀ¤é¤«¤Ë¡¢ÄêµÁ¤«¤é HR < HFL ¤È¤Ê¤ê¤Þ¤¹¡£¶ñÂÎŪ¤ËξÊý¤¬Æ±»þ¤Ë³«»Ï¤·
+¤¿¤È²¾Äꤷ¤Æ¼¡¤Ë¼¨¤·¤Þ¤¹ :
+
+<tscreen><verb>
+
+|___ __ __ __ __ __ __ __ __ __ __ __ __
+|_ _ _ _ _ _ _ _ _ _ _ _ |
+|_______________________|_______________|_____
+0 ^ ^ ñ°Ì: 1¥¯¥í¥Ã¥¯
+ | ^ ^ |
+ HR | | HFL
+ | |<----->| |
+ |<->| HSP |<->|
+ HGT1 HGT2
+
+</verb></tscreen>
+
+¤³¤³¤Ç¡¢¾å¤Ë¤¢¤ë¤è¤¦¤Ëɽ¼¨¥Ç¡¼¥¿¤Î¥¯¥í¥Ã¥¯½ªÎ»¤È¥Õ¥ì¡¼¥àÁ´ÂΤΥ¯¥í¥Ã¥¯½ªÎ»
+¤Î´Ö¤Ë HSP ¤ÎƱ´ü¿®¹æÄ¹¤òÇÛÃÖ¤·¤Þ¤¹¡£²¿¸Î¤½¤¦¤¹¤ë¤Î¤«¡© ¤½¤ì¤Ï¤³¤¦¤¹¤ë¤È¡¢
+²èÌÌɽ¼¨¤¬º¸±¦¤Ë°Üư¤·¤Ê¤¯¤Ê¤ë¤«¤é¤Ç¤¹¡£É½¼¨¤ò¥¹¥¯¥ê¡¼¥ó¾å¤Çɽ¼¨¤µ¤ì¤ë¤Ù¤­
+¾ì½ê¡¢¤Ä¤Þ¤ê¥â¥Ë¥¿¡¼¤Îɽ¼¨²ÄǽÎΰèÆâ¤Ë¤­¤Ã¤Á¤ê¤È¤ª¤µ¤á¤ë¤¿¤á¤Ç¤¹¡£
+
+
+¤½¤Î¾å¡¢Æ±´ü¿®¹æ¤Îξ¦¤Ë "Ëɸæ»þ´Ö" ¤È¤·¤ÆÌó 30 ¥¯¥í¥Ã¥¯É¬ÍפǤ¹¡£HGT1 ¤È
+HGT2 ¤Çɽ¤ï¤·¤Æ¤¤¤Þ¤¹¡£°ìÈÌŪ¤Ë¤Ï HGT1 ¤Ï HGT2 ¤ÈÅù¤·¤¯¤¢¤ê¤Þ¤»¤ó¤¬¡¢¤·¤«
+¤·¿¿¤Ã¤µ¤é¤Î¾õÂÖ¤«¤éÀßÄê¤ò¹Ô¤¦¤Ê¤é¤Ð¡¢2 ¤Ä¤òÅù¤·¤¯¤·¤Æ¼Â¸³¤ò»Ï¤á¤¿¤éÎɤ¤¤Ç
+¤·¤ç¤¦¡Ê¤½¤ì¤ÏƱ´ü¿®¹æ¤òÃæ±û¤ËÃÖ¤¯¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡Ë¡£
+
+Ʊ´ü¿®¹æ¤ÎÃÖ¤­°ã¤¨¤Î¾É¾õ¤Ï¡¢1 ¤Ä¤Î¶­³¦¤¬¶Ëü¤Ë¹­¤¯¤Ê¤Ã¤Æ²èÁü¤Î¾¤Î¦¤¬²èÌÌ
+¤Îü¤«¤é²ó¤ê¹þ¤ó¤À¤ê¡¢Çò¤¤Ã¼¤ÎÀþ¤È"¤ª²½¤±²èÁü"¤ÎÂӤˤʤ俤ꡢ²èÌ̤βèÁüɽ
+¼¨¤Î¤º¤ì¤È¤·¤Æ¸½¤ï¤ì¤Þ¤¹¡£¿âľƱ´ü¿®¹æÈ´¤±¤Ï¿âľÊÝ»ý¤¬Ä´ÀáÉÔÈ÷¤Ë¤Ê¤Ã¤Æ¤¤¤ë
+TV ¤ÎÍͤ˼ºݤ˽ĥ¹¥¯¥í¡¼¥ë¤·¤Þ¤¹¡Ê»ö¼Â¡¢Æ±¤¸¸½¾Ý¤¬µ¯¤³¤ê¤Þ¤¹¡Ë¡£
+
+¹¬±¿¤Ê¤é¤Ð¡¢¥â¥Ë¥¿¡¼¤ÎƱ´ü¿®¹æ¤ÎÉý¤¬¤½¤Î»ÅÍͽñ¤Ëµ­ºÜ¤µ¤ì¤Æ¤¤¤ë¤Ç¤·¤ç¤¦¡£µ­
+ºÜ¤¬¤Ê¤¤¾ì¹ç¤Ë¤Ï¡¢¤³¤³¤«¤é¤¬ËÜÅö¤Î¹õËâ½Ñ¤Î»Ï¤Þ¤ê¡¢¡¢¡¢
+
+¤³¤³¤Ç¤Ï¾¯¤·»î¹Ôºø¸í¤ò¹Ô¤¦É¬Íפ¬¤¢¤ë¤Ç¤·¤ç¤¦¡£¤·¤«¤·¤Û¤È¤ó¤É¤Î¾ì¹ç¤Ë¤Ï¡¢Æ±
+´ü¿®¹æ¤òÌó 3.5 ¤«¤é 4.0 ¥Þ¥¤¥¯¥íÉäȲ¾Äꤹ¤ì¤Ð°ÂÁ´¤Ç¤¹¡£
+
+¶ñÂÎŪ¤Ë¤Ï¡¢HSP ¤ò 3.8 ¥Þ¥¤¥¯¥íÉäˤ·¤Þ¤·¤ç¤¦¡Ê¤³¤ÎÃͤϼ¸³¤ò»Ï¤á¤ë¤ËÅö¤¿
+¤Ã¤Æ¤Ï°­¤¤ÃͤǤϤ¢¤ê¤Þ¤»¤ó¡Ë¡£
+
+¤µ¤Æ¡¢Àè¤Û¤É 65Mhz ¤ò¥¯¥í¥Ã¥¯¤Ë»È¤¤¤Þ¤·¤¿¤«¤é¡¢HSP ¤ò 247 ¥¯¥í¥Ã¥¯Ê¬¤ÈÅù¤·
+¤¯¤¹¤ì¤Ð¤è¤¤¤³¤È¤¬¤ï¤«¤ê¤Þ¤¹¡£( 247 = 65x10**6 * 3.8 *10**(-6))
+&lsqb;¥á¥¬=10**6, ¥Þ¥¤¥¯¥í=10**(-6) ¤Ç¤¢¤ë»ö¤ò»×¤¤½Ð¤·¤Æ²¼¤µ¤¤&rsqb;
+
+¿âľƱ´ü :
+
+Á°¤Î³¨¤ËÌá¤Ã¤Æ¡¢247 ¥¯¥í¥Ã¥¯Ê¬¤ò³¨¤ÎÃæ¤Ç¤É¤Î¤è¤¦¤ËÃÖ¤¤¤¿¤é¤¤¤¤¤Ç¤·¤ç¤¦¡©
+
+¤³¤ÎÎã¤Ç¤Ï¡¢HR ¤Ï 944 ¤Ç HFL ¤Ï 1176 ¤Ç¤¹¡£¤³¤Î 2 ¤Ä¤ÎÎã¤Îº¹¤Ï
+1176-944=232 &lt; 247¤Ç¤¹! ÌÀ¤é¤«¤Ë¤³¤Î°ã¤¤¤òÄ´À°¤·¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£²¿¤¬
+¤Ç¤­¤ë¤Ç¤·¤ç¤¦¤«¡©
+
+ºÇ½é¤Ë 1176 ¤Ï 1184 ¤Ø¾å¤²¤Æ¡¢ 944 ¤Ï 936 ¤Ø²¼¤²¤Æ¤¯¤À¤µ¤¤¡£¤µ¤Æ¡¢°ã¤¤¤Ï
+1184-936= 248 ¤Ë¤Ê¤ê¤Þ¤·¤¿¡£¤¦¡Á¤ó¡¢¶á¤Å¤­¤Þ¤·¤¿¤Í¡£
+
+¼¡¤Ï HSP ¤ò·×»»¤¹¤ë¤Î¤Ë 3.8 ¤ÎÂå¤ï¤ê¤Ë¡¢3.5 ¤ò»È¤¦¤è¤¦¤Ë¤¹¤ë¤È¡¢
+65*3.5=227 ¤È¤Ê¤ê¤Þ¤¹¡£¤«¤Ê¤êÎɤ¯¤Ê¤ê¤Þ¤·¤¿¡£¤·¤«¤· 248 ¤Ï 227 ¤è¤ê¤½¤ì¤Û
+¤ÉÂ礭¤¯¤¢¤ê¤Þ¤»¤ó¡£HR ¤È SP ¤Î³«»ÏÅÀ¤Î´Ö¤È SP ¤Î½ªÎ»ÅÀ¤È HFL ¤Î´Ö¤Ë 30 ¤«
+¤½¤ì¤°¤é¤¤¤¢¤±¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤½¤·¤Æ¡¢¤½¤ì¤é¤Ï 8 ¤ÎÇÜ¿ô¤Ë¤·¤Ê¤±¤ì¤Ð¤Ê¤ê
+¤Þ¤»¤ó¡ª²æ¡¹¤Ï¤³¤³¤Ç¹Ô¤­µÍ¤Þ¤Ã¤Æ¤·¤Þ¤Ã¤¿¤Î¤Ç¤·¤ç¤¦¤«¡©
+
+¤¤¤¤¤¨¡ª ¤³¤¦¤·¤Æ¤ß¤Þ¤·¤ç¤¦¡¢936&percnt 8==0 ¤Ç¤¹¡¢¤Þ¤¿ (936+32)&percnt 8==0
+¤Ç¤¹¡£¤·¤«¤·¡¢936+32=968¡¢968+227=1195¡¢1195+32=1227 ¤È¤Ê¤ê¤Þ¤¹¡£¤Õ¤à¤Õ¤à¡¢
+¤½¤ó¤Ê¤Ë°­¤¯¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤·¤«¤·¡¢8 ¤ÎÇÜ¿ô¤Ë¤Ï¤Ê¤Ã¤Æ¤¤¤Þ¤»¤ó¤Î¤Ç¡¢1232 ¤Ë
+´Ý¤á¤Æ²¼¤µ¤¤¡£
+
+¤·¤«¤·¡¢Æ±´ü¿®¹æ¤ò HR ¤È HFL ¤Î¤Á¤ç¤¦¤É¿¿¤óÃæ¤ËÃÖ¤¯¤³¤È¤¬½ÐÍè¤Ê¤¤¤È¤¤¤¦Àø
+ºßŪ¤Êº¤Æñ¤¬¤¢¤ê¤Þ¤¹¡£¹¬¤¤¤Ë¤â¡¢1232-32=1200 ¤â 8 ¤ÎÇÜ¿ô¤Ç¤¢¤ë»ö¤È¡¢
+(1232-32)-968=232 ¤Ï 3.57 ¥Þ¥¤¥¯¥íÉà (232/65) ¤È¤¤¤¦ÂÅÅö¤ÊŤµ¤ÎƱ´ü¿®¹æ¤Ë
+Âбþ¤¹¤ë¤³¤È¤¬·×»»¤Ç¤ï¤«¤ê¤Þ¤¹¡£
+
+¤µ¤é¤Ë¡¢ 936/1232 ¤ÏÂçÂÎ 0.76 ¤Ä¤Þ¤ê 76&percnt, ¤Ç¤¹¤¬¡¢80&percnt ¤«¤é¤½¤¦
+±ó¤¯¤Ê¤¤¤Î¤Ç¤Þ¤¢Âç¾æÉפǤ·¤ç¤¦¡£
+
+¤½¤Î¾å¡¢¸½ºß¤Î¿åÊ¿¥Õ¥ì¡¼¥àŤò»È¤¦¤Ê¤é¡¢´ðËÜŪ¤Ë¤Ï¥â¥Ë¥¿¡¼¤¬¤½¤ÎǽÎÏÆâ¤Ç
+52.7KHz(=65MHz/1232) ¤Ë¤ª¤¤¤ÆÆ±´ü¤¬¼è¤ì¤ë¤«¤É¤¦¤«Ä´¤Ù¤Þ¤·¤ç¤¦¡£ÌäÂê¤Ï̵¤¤
+¤Ç¤·¤ç¤¦¡£
+
+·Ð¸³Â§¤«¤é¡¢¾åµ­¤Î 936*75%=702 ¤ò¿·¤·¤¤¿âľ²òÁüÅ٤ˤ·¤Þ¤·¤ç¤¦¡£
+702*1.05=737 ¤¬¿·¤·¤¤¿âľ¥Õ¥ì¡¼¥àĹ¤Ë¤Ê¤ê¤Þ¤¹¡£
+
+²èÌ̺ÆÉÁ²è®ÅÙ¤Ï 65Mhz/(737*1232)=71.6 Hz ¤Ë¤Ê¤ê¤Þ¤¹¡£¤½¤ì¤Ç¤âÁÇÀ²¤é¤·¤¤¤Ç
+¤¹¤Í¡£
+
+ƱÍͤ˿âľƱ´ü¿®¹æ¤ÎÇÛÃÖ¤ò¿Þ²ò¤·¤Þ¤¹ :
+<tscreen><verb>
+
+ |___ __ __ __ __ __ __ __ __ __ __ __ __
+ |_ _ _ _ _ _ _ _ _ _ _ _ |
+ |_______________________|_______________|_____
+ 0 VR VFL ñ°Ì:1 ¿âľ¥¯¥í¥Ã¥¯
+ ^ ^ ^
+ | | |
+ |<->|<----->|
+ VGT VSP
+</verb></tscreen>
+
+¿âľɽ¼¨¥Ç¡¼¥¿¤Î½ªÎ»»þ¤­¤Ã¤«¤ê¤ËƱ´ü¿®¹æ¤òȯ¿®¤·¤Þ¤¹¡£VGT ¤ÏƱ´ü¿®¹æ¤Î¿âľ
+Ëɸæ»þ´Ö¤Ç¤¹¡£¤Û¤È¤ó¤É¤Î¥â¥Ë¥¿¡¼¤Ï VGT ̵¤·¡ÊËɸæ»þ´Ö̵¤·¡Ë¤Ç²÷Ŭ¤Ëưºî¤·¡¢
+ÎãÂê¤Ç¤âËɸæ»þ´Ö̵¤·¤Ç¤¹¡£2,3 ¥¯¥í¥Ã¥¯¤ÎËɸæ»þ´Ö¤¬É¬Íפʤâ¤Î¤â¤¢¤ê¤Þ¤¹¤¬¡¢
+Ëɸæ»þ´Ö¤òÆþ¤ì¤ÆÉÔÅԹ礬À¸¤¸¤ë¤³¤È¤ÏÉáÄ̤¢¤ê¤Þ¤»¤ó¡£
+
+ÎãÂê¤ËÌá¤ê¤Þ¤·¤ç¤¦ : ¥Õ¥ì¡¼¥àŤÎÄêµÁ¤«¤é¡¢¿âľ¥¯¥í¥Ã¥¯¤ÏÁ´¡ö¿åÊ¿¡ö¥Õ¥ì¡¼
+¥à¤òé¤ë»þ´Ö¤Ç¤¹¤Î¤Ç¡¢ÎãÂê¤Ç¤Ï 1232/65Mhz=18.95 ¥Þ¥¤¥¯¥íÉäˤʤê¤Þ¤¹¡£
+
+¼Â¸³¤Ë¤è¤ì¤Ð¿âľƱ´ü¤Î¥Ñ¥ë¥¹Éý¤Ï 50 ¥Þ¥¤¥¯¥íÉ䫤é 300 ¥Þ¥¤¥¯¥íÉäÎÈϰϤË
+ÀßÄꤹ¤Ù¤­¤Ç¤¹¡£ÎãÂê¤Ç¤Ï 8 ¿âľ¥¯¥í¥Ã¥¯Ê¬¡¢150 ¥Þ¥¤¥¯¥íÉäò»ÈÍѤ·¤Þ¤¹
+(150 ¥Þ¥¤¥¯¥íÉà / 18.95 ¥Þ¥¤¥¯¥íÉà ~ 8)¡£
+
+<sect>Á´ÂΤΤޤȤá
+<p>
+
+Xconfig ¥Õ¥¡¥¤¥ë¤Î¥Ó¥Ç¥ª¥â¡¼¥É ( Video Modes ) ɽ¤Ï¿ô¹Ô¤Î¿ôÎó¤Ç½ÐÍè¤Æ¤¤¤Æ¡¢
+¤½¤ì¤¾¤ì¤Î¹Ô¤Ï X ¥µ¡¼¥Ð¡¼¤¬»ÈÍѤ¹¤ë£±¤Ä¤Î¥â¡¼¥É¤Î´°Á´¤Ê»ÅÍͤòɽ¤ï¤·¤Æ¤¤¤Þ
+¤¹¡£¤½¤Î¹àÌܤÏ̾¾ÎÀá¡¢¥É¥Ã¥È¥¯¥í¥Ã¥¯Àá¡¢¿åÊ¿Àá¡¢¿âľÀá¤Î 4 ¤Ä¤ÎÀá¤Ëʬ¤±¤é
+¤ì¤Þ¤¹¡£
+
+̾¾ÎÀá¤Ï£±¹àÌܤǡ¢¹Ô¤Î»Ä¤ê¤Ç»ØÄꤷ¤Æ¤¤¤ë¥Ó¥Ç¥ª¥â¡¼¥É¤Î̾¾Î¤Ç¤¹¡£¤³¤Î̾¾Î¤Ï¡¢
+Xconfig ¥Õ¥¡¥¤¥ë¤Î¥°¥é¥Õ¥£¥Ã¥¯¥É¥é¥¤¥ÐÀßÄêÀá¤Î "Modes" ¹Ô¤Ç»²¾È¤µ¤ì¤Þ¤¹¡£
+¸½ºß¤Î¹Ô¤¬Á°¤Î¹Ô¤ÈƱ¤¸Ì¾¾Î¤Ê¤é¤Ð̾¾Î¤Ï¾Êά½ÐÍè¤Þ¤¹¡£
+
+¥É¥Ã¥È¥¯¥í¥Ã¥¯Àá¤Ï¥Ó¥Ç¥ª¥â¡¼¥É¹Ô¤Î¹àÌÜ¤Ë DCF ¤È¸Æ¤ó¤Ç¤¤¤¿¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Î
+¤ß¤ò½ñ¤­¤Þ¤¹¡£¼¡¤ÎÀá¤ÇºîÀ®¤¹¤ë¿ô»ú¤ò¥É¥Ã¥È¥¯¥í¥Ã¥¯¤È¤·¤Æ¤³¤Î¹àÌܤ˽ñ¤­¤Þ¤¹¡£
+
+¿åÊ¿Àá¤Ï¤½¤ì¤¾¤ì¤Î¿åÊ¿Àþ¤ò²èÌ̤ξå¤Ç¤É¤Î¤è¤¦¤ËºîÀ®¤¹¤ë¤«¤ò 4 ¹àÌܤǽñ¤­¤Þ
+¤¹¡£ºÇ½é¤Î¹àÌÜ¤Ï HR ¤È¸Æ¤ó¤Ç¤¤¤¿±ÇÁü¤ò¹½À®¤¹¤ëµ±¤¯£±Ëܤ¬²¿¥É¥Ã¥È¤Ç¤¢¤ë¤«¤ò
+½ñ¤­¤Þ¤¹¡£ 2 ÈÖÌܤιàÌܤϤɤΥɥåȤ«¤é¿åʿƱ´ü¿®¹æ¤¬»Ï¤Þ¤ë¤«¤ò¼¨¤·¤Þ¤¹¡£
+3 ÈÖÌܤιàÌܤϤɤΥɥåȤǿåʿƱ´ü¿®¹æ¤¬½ª¤ï¤ë¤«¤ò¼¨¤·¤Þ¤¹¡£ 4 ÈÖÌܤιàÌÜ
+¤ÏÁ´¿åÊ¿¥Õ¥ì¡¼¥àĹ (HFL) ¤ò»ØÄꤷ¤Þ¤¹¡£
+
+¿âľÀá¤â 4 ¹àÌܤǽñ¤­¤Þ¤¹¡£ºÇ½é¤Î¹àÌܤϲèÌ̾å¤Ëɽ¼¨¤µ¤ì¤ëÁöººÀþ¤Î¿ô¤ò½ñ¤­
+¤Þ¤¹ (VR)¡£ 2 ÈÖÌܤιàÌܤϿâľƱ´ü¿®¹æ¤¬²¿ÈÖÌܤÎÀþ¤«¤é»Ï¤Þ¤ë¤«¤ò½ñ¤­¤Þ¤¹¡£
+3 ÈÖÌܤιàÌܤϿâľƱ´ü¿®¹æ¤¬²¿ÈÖÌܤÎÀþ¤Ç½ª¤ï¤ë¤«¤ò½ñ¤­¤Þ¤¹¡£4 ÈÖÌܤιàÌܤÏ
+Á´¿âľ¥Õ¥ì¡¼¥àŤò½ñ¤­¤Þ¤¹¡£
+
+Îã :
+<tscreen><verb>
+ #̾¾ÎÀá ¥â¡¼¥É¥¯¥í¥Ã¥¯Àá ¿åÊ¿Àá(1¤«¤é4) ¿âľÀá(1¤«¤é4)
+ #Modename clock horizontal timing vertical timing
+
+ "752x564" 40 752 784 944 1088 564 567 569 611
+ 44.5 752 792 976 1240 564 567 570 600
+</verb></tscreen>
+
+¡ÊÃí°Õ : ɸ½àŪ¤Ê X11R5 ¤½¤Î¤Þ¤Þ¤Ç¤Ï ¾®¿ô¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ï»È¤¨¤Þ¤»¤ó¡£¡Ë
+
+Xconfig ¤Ç¤Ï¡¢Àþ¾å¤Çµ±¤¤¤Æ¤¤¤ë¥É¥Ã¥È¤Î¿ô¡¢µ±¤¤¤Æ¤¤¤ë¥É¥Ã¥È¤«¤éƱ´ü¿®¹æ¤Î³«
+»ÏÅÀ¤Þ¤Ç¤Î¥É¥Ã¥È¿ô¡¢Æ±´ü¿®¹æ¤Î»ý³»þ´Öʬ¤Î¥É¥Ã¥È¿ô¤ÈƱ´ü¿®¹æ¤Î½ªÎ»ÅÀ¤«¤é¸å
+¤Î¥É¥Ã¥È¿ô¡¢¤³¤ì¤é¤ò­¤·¹ç¤ï¤»¤ë¤È£±ËÜÅö¤¿¤ê¤Î¥É¥Ã¥È¿ô¤¬·×»»¤Ç¤­¤Þ¤¹¡£¿åÊ¿
+Êý¸þ¤Î¥É¥Ã¥È¿ô¤Ï°ìΧ¤Ë 8 ¤Ç³ä¤êÀÚ¤ì¤ë¿ôÃͤǤʤ±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£
+
+Îã :
+
+ ¿åÊ¿Êý¸þ¤Î¿ôÃÍ : 800 864 1024 1088
+
+ ¤³¤ÎÎã¤Ïµ±¤¤¤Æ¤¤¤ë¥É¥Ã¥È¿ô (800)¡¢
+ ³¤¤¤ÆÆ±´ü³«»ÏÅÀ¤Î¥É¥Ã¥È (864)¡¢
+ ¤½¤Î¼¡¤¬Æ±´ü½ªÎ»ÅÀ¤Î¥É¥Ã¥È (1024)¡¢
+ ¼¡¤Ï¿åÊ¿Àþ¤ÎºÇ¸å¤Î¥É¥Ã¥È (1088) ¤È¤Ê¤ê¤Þ¤¹¡£
+
+Á´¤Æ¤Î¿åÊ¿Êý¸þ¤Î¿ô»ú (800¡¢864¡¢1024 ¤È 1088) ¤Ï 8 ¤Ç³ä¤êÀÚ¤ì¤ë»ö¤Ë¤â¤¦°ì
+ÅÙÃí°Õ¤ò¤·¤Æ²¼¤µ¤¤¡£¤³¤ì¤Ï¿âľÊý¸þ¤Î¿ô»ú¤Ë¤ÏÅö¤Æ¤Ï¤Þ¤ê¤Þ¤»¤ó¡£
+
+²èÌ̤ξ夫¤é²¼¤Þ¤Ç¤ÎÀþ¤Î¿ô¤¬¥Õ¥ì¡¼¥à¤ò¹½À®¤·¤Þ¤¹¡£¥Õ¥ì¡¼¥à¤Î´ðËÜŪ¤Ê»þ´ÖÄ´
+À°¤ÏÀþ¤Ç¹Ô¤Ê¤¤¤Þ¤¹¡£Àþ¤Î¿¤¯¤Ï²èÁü¤òɽ¼¨¤¹¤ë¤¿¤á¤Ë»È¤ï¤ì¤Þ¤¹¡£ºÇ¸å¤Îȯ¸÷¤¹
+¤ëÀþ¤òɽ¼¨¤·¤¿¸å¤Ç¡¢¿ôËÜʬÃٱ䤬ÁÞÆþ¤µ¤ì¡¢¤½¤Î¸å¿âľƱ´ü¿®¹æ¤¬À¸À®¤µ¤ì¤Þ¤¹¡£
+¤½¤·¤ÆÆ±´ü¿®¹æ¤Ï¿ôËÜʬ¤À¤±»ý³¤·¡¢¥Õ¥ì¡¼¥à¤ÎºÇ¸å¤ËƱ´ü¿®¹æ¤Î¸å¤ÇɬÍפÊÃÙ±ä
+¤¬À¸À®¤µ¤ì¤Þ¤¹¡£¤³¤Îưºî¥â¡¼¥É¤òµ¬Äꤹ¤ë¿ôÃͤϡ¢¼¡¤ÎÎã¤Î¤è¤¦¤ËÆþÎϤ·¤Þ¤¹¡£
+
+Îã :
+
+ ¿âľÊý¸þ¤Î¿ôÃÍ : 600 603 609 630
+
+ ¤³¤ÎÎã¤Ï¥Ç¥£¥¹¥×¥ì¥¤¤Ë 600 ËܤÎÀþ¤¬É½¼¨¤µ¤ì¡¢603 ÈÖÌܤÎÀþ
+ ¤«¤é¿âľƱ´ü¤¬»Ï¤Þ¤ê 609 ÈÖÌܤǽª¤ï¤ë»ö¡¢¤½¤·¤ÆÁ´Éô¤Ç 630 ËÜ
+ ¤ÎÀþ¤ò»ÈÍѤ¹¤ë¤³¤È¤òɽ¤ï¤·¤Æ¤¤¤Þ¤¹¡£
+
+¿âľÊý¸þ¤Î¿ôÃÍ¤Ï 8 ¤Ç³ä¤êÀÚ¤ì¤ëÃͤǤʤ¯¤Æ¤â¹½¤¤¤Þ¤»¤ó¡£
+
+ ÎãÂê¤ËÌá¤ê¤Þ¤·¤ç¤¦¡£¾åµ­¤Ë¤è¤Ã¤Æ¡¢Xconfig ¤Ø½ñ¤­¹þ¤àɬÍפÊÁ´¤Æ¤ÎÃͤϼ¡¤ÎÍÍ
+¤Ç¤¹:
+
+<tscreen><verb>
+&lt name &gt DCF HR SH1 SH2 HFL VR SV1 SV2 VFL
+</verb></tscreen>
+
+¤³¤³¤Ç SH1 ¤Ï¿åʿƱ´ü¿®¹æ¤Î³«»Ï¥¯¥í¥Ã¥¯¤Ç¡¢SH2 ¤Ï¤½¤Î½ªÎ»¥¯¥í¥Ã¥¯¤Ë¤Ê¤ê¡¢
+ƱÍÍ¤Ë SV1 ¤Ï¿âľƱ´ü¿®¹æ¤Î³«»Ï¥¯¥í¥Ã¥¯¤Ç¡¢SV2 ¤Ï¤½¤Î½ªÎ»¥¯¥í¥Ã¥¯¤Ç¤¹¡£
+
+<tscreen><verb>
+#̾¾ÎÀá ¥â¡¼¥É¥¯¥í¥Ã¥¯Àá ¿åÊ¿Àá(1¤«¤é4) ¿âľÀá(1¤«¤é4) ¥ª¥×¥·¥ç¥ó
+#name clock horizontal timing vertical timing flag
+936x702 65 936 968 1200 1232 702 702 710 737
+</verb></tscreen>
+
+ÆÃÊ̤ʥª¥×¥·¥ç¥ó¤ÏɬÍ×̵¤¯¡¢¤³¤ì¤Ï¥Î¥ó¥¤¥ó¥¿¡¼¥ì¡¼¥¹¥â¡¼¥É¤Çưºî¤·¤Þ¤¹¡£
+¤³¤ì¤Ç´°Î»¤·¤Þ¤·¤¿¡£
+
+<sect>¼Áµ¿±þÅú
+<p>
+
+ Q. ¤³¤³¤Ë¤¢¤ëÎãÂê¤Ïɸ½àŪ¤Ê²èÌÌ¥µ¥¤¥º¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¤¬¡¢»È¤Ã¤Æ¤â¤è¤¤¤Ç¤¹¤«¡©
+
+ A. ÌÞÏÀ¤Ç¤¹¡£¤Ê¤Ë¤¬¤Ê¤ó¤Ç¤â 640x480, 800x600 ¤È¤« 1024x768 ¤ò»È¤ï¤Ê¤±¤ì¤Ð
+ ¤Ê¤é¤Ê¤¤Íýͳ¤Ï¤¢¤ê¤Þ¤»¤ó¡£XFree86 ¥É¥é¥¤¥Ð¤Ï¥Ï¡¼¥É¥¦¥§¥¢¤ò¼«Í³¤ËÀßÄê¤Ç¤­¤ë
+ ¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£°ìÈ̤ËÀµ¤·¤¤ÀßÄê¤Ï 2 ¡¢3 ʬ¤Ç¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£Àµ
+ ¤·¤¤ÀßÄê¤òÅö¤Æ¤ë¤Î¤Ë½ÅÍפÊʪ¤Ï¹â¤¤ºÆÉÁ²è®ÅÙ¤ÈÂÅÅö¤Êɽ¼¨Îΰè¤Ç¤¹¡£¹â²òÁüÅÙ
+ ¤À¤±¤òÄɵᤷ¤ÆÎÞÌܤòͶ¤¦¤Á¤é¤Ä¤­¤ËÂå½þ¤òʧ¤¦¤³¤È¤Î¤Ê¤¤¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+ Q. 65Mhz ¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤È 55Khz ¤Î HSF ¤ÇÆÀ¤é¤ì¤ë²òÁüÅ٤Ϥ³¤ì¡ö¤À¤±¡ö¤Ç
+ ¤¹¤«¡©
+
+ A. ÀäÂФ½¤ó¤Ê¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡ª °ìÈÌŪ¤Ê¼ê½ç¤Ë½¾¤Ã¤Æºî¶È¤ò¹Ô¤¤¡¢ËÜÅö¤Ë¹¥¤ß
+ ¤ÎÀßÄê¤Ë¤¿¤É¤êÃ夯¤¿¤á¡¢¾¯¤·¤Î»î¹Ô¤Î·«¤êÊÖ¤·¤ò¤ª´«¤á¤·¤Þ¤¹¡£ ¼Â¸³¤Ï¤È¤Ã¤Æ
+ ¤â³Ú¤·¤¤¤â¤Î¤Ç¤¹¡£ ¤Û¤È¤ó¤É¤ÎÀßÄê¤Ï¥Ó¥Ç¥ªÉ½¼¨¤¬Íð¤ì¤Æ¤Á¤ã¤ó¤ÈÀßÄê¤Ç¤­¤Ê¤¤
+ ¤«¤â¤·¤ì¤Þ¤»¤ó¤¬¡¢¥Þ¥ë¥Á¥·¥ó¥¯¥â¥Ë¥¿¡¼¤ò¡ÊÂÓ°èÉý¤è¤ê¤â¤Ï¤ë¤«¤Ë¹â¤¤¼þÇÈ¿ô¤Î
+ ¥¯¥í¥Ã¥¯¤ò½ÐÎϤµ¤»¤è¤¦¤È¤·¤Ê¤¤¸Â¤ê¤Ï --- ¥â¥Ë¥¿¡¼¤ÎÀâÌÀ½ñ¤Ë½ñ¤«¤ì¤Æ¤¤¤ëºÇ
+ Âç²òÁüÅ٤˶ᤤÃͤò¼é¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï¡ËÄˤá¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£¸ÇÄê¼þÇÈ¿ô¤Î¥â
+ ¥Ë¥¿¡¼¤Ë¤ÏÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¼þÇÈ¿ôÄ´À°¤Ï¸ÇÄê¼þÇÈ¿ô¤Î¥â¥Ë¥¿¡¼¤òÄˤá¤ë¡ö¤«¤â
+ ¡ö¤·¤ì¤Þ¤»¤ó¡£
+
+ Q. Æó¤Ä¤Îɸ½àŪ¤Ê²òÁüÅÙ¤òµ­ºÜ¤·¤Æ¤Þ¤¹¤Í¡£ Xconfig ¤ÎÃæ¤Ç¤Ï¿§¡¹É¸½àŪ¤Ê²òÁü
+ ÅÙ¤¬¤¢¤ê¤Þ¤¹¤¬¡¢»þ´ÖÄ´Àá¤Î¿ôÃͤòÄ´À°¤¹¤ë¾ì¹ç¤Î¥Ý¥¤¥ó¥È¤ò¶µ¤¨¤Æ¤¯¤À¤µ¤¤¡£
+
+ A. ÌÞÏÀ¶µ¤¨¤Þ¤·¤ç¤¦¡ª ¸½ºß¤Î Xconfig ¤Ë¤¢¤ë "ɸ½àŪ¤Ê" 640x480 ¤òÎãÂê¤Ë¼è
+ ¤ê¾å¤²¤Þ¤¹¡£¤³¤Î¾ì¹ç¡¢Æ°ºî¼þÇÈ¿ô¤¬ 25MHz ¡¢¥Õ¥ì¡¼¥àŤ¬ 800 ¤È 525 ¤Î»þ¤Ë
+ Ìó 59.5Hz ¤Î²èÌ̺ÆÉÁ²è¼þÇÈ¿ô¤¬»È¤¨¤Þ¤¹¡£ °­¤¯Ìµ¤¤¤Ç¤·¤ç¡© ¤·¤«¤·°ìÈÌŪ¤Ë¿
+ ¤¯¤Î SVGA ¥Ü¡¼¥É¤Îưºî¼þÇÈ¿ô¤Ï 28MHz ¤ò»È¤¨¤Þ¤¹¡£28MHz ¤Ç 640x480 ¤ò»È¤¦¾ì
+ ¹ç¡¢°ÊÁ°¤ËÀâÌÀ¤·¤¿¼ê½ç¤Ë½¾¤¨¤Ð¡¢¥Õ¥ì¡¼¥àĹ¤Ï 812 ¤È 505 ¤ËÀßÄê¤Ç¤­¤Þ¤¹¡£¤³
+ ¤³¤ÇºÆÉÁ²è¼þÇÈ¿ô¤Ï 68MHz ¤Þ¤Ç°ú¤­¾å¤²¤é¤ì¡¢É¸½àÃͤè¤ê¤«¤Ê¤ê¸þ¾å¤·¤Þ¤·¤¿¡£
+
+ Q. ¤È¤³¤í¤Ç¥¤¥ó¥¿¡¼¥ì¡¼¥¹¤È¥Î¥ó¥¤¥ó¥¿¡¼¥ì¡¼¥¹¤Ë¤Ä¤¤¤Æ¤Ï¤É¤¦¤Ç¤¹¤«¡©
+
+ A. ¸ÇÄê¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ç¤Ï¡¢¥Î¥ó¥¤¥ó¥¿¡¼¥ì¡¼¥¹¤Î¤Á¤é¤Ä¤­¤è¤ê¥¤¥ó¥¿¡¼¥ì¡¼¥¹
+ ¤Î¤Á¤é¤Ä¤­¤ÎÊý¤¬¹ó¤¤¤Î¤Ç¡¢¥¤¥ó¥¿¡¼¥ì¡¼¥¹¤Ï»Ô¾ì¤«¤é¾Ã¤¨¤Ä¤Ä¤¢¤ê¤Þ¤¹¡£¥Õ¥ê¥Ã
+ ¥«¡¼¤¬Áý¤¨¤ëÂå¤ï¤ê¤Ë¡¢ÃÙ¤¤¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ç¹â²òÁüÅÙ¤ò¼Â¸½¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£
+ DCF ¤¬½½Ê¬Â®¤¤¾ì¹ç¤Ë¤Ï (Î㤨¤Ð 90MHz ¤È¤«¤½¤ì°Ê¾å) ¥¤¥ó¥¿¡¼¥ì¡¼¥¹¤Ç¤â¤Á¤é
+ ¤Ä¤­¤ÏȯÀ¸¤·¤Þ¤»¤ó¤¬¡¢¸½ºß¤Î¥¹¥Ô¡¼¥É¤Ç¤Ï¥¤¥ó¥¿¡¼¥ì¡¼¥¹¥â¥Ë¥¿¡¼¤Ï X ¤Ë¸þ¤¤
+ ¤Æ¤¤¤Þ¤»¤ó¡£
+
+
+ Q. º£¤Þ¤Ç¤ÎµÄÏÀ¤ò¤Þ¤È¤á¤Æ¤â¤é¤¨¤Þ¤¹¤«¡©
+
+ A. Í×Ì󤷤ƸÀ¤¨¤Ð :
+
+<enum>
+<item> Ǥ°Õ¤Î¸ÇÄê¤Îưºî¼þÇÈ¿ô¤Ç¤Ï¡¢ºÇ¹â¤Î²òÁüÅ٤˹â¤á¤ì¤ÐºÆÉÁ²è®ÅÙ¤ò²¼¤²¤Ê
+ ¤±¤ì¤Ð¤Ê¤é¤º¡¢¤·¤¿¤¬¤Ã¤Æ¤Á¤é¤Ä¤­¤¬Áý¤¨¤ë¤Ç¤·¤ç¤¦¡£
+
+<item> ¹â²òÁüÅÙ¤ò´õ˾¤·¥â¥Ë¥¿¡¼¤¬¤½¤ì¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤È¤­¤Ï¡¢¤½¤ì¤Ë¹ç¤¦¥É¥Ã¥È
+ ¥¯¥í¥Ã¥¯¡¢¤Ä¤Þ¤ê DCF ¤ò¶¡µë¤¹¤ë SVGA ¥«¡¼¥É¤ò¼ê¤ËÆþ¤ì¤Æ²¼¤µ¤¤¡£
+ ¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ï¹â¤¤¤Ë±Û¤·¤¿¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+</enum>
+
+<sect> Æó¤Ä¤ÎÎãÂê
+<p>
+¤³¤³¤ÇÊ̤β¾Äê¤ò¤·¤Þ¤¹¡£:
+
+¤¢¤ë¥¢¥À¥×¥¿¡¼¥«¡¼¥É¤Ï 40 MHz ¤Î¥¯¥í¥Ã¥¯¤Çưºî¤·¤Þ¤¹¡£¤¢¤ë¥Ç¥£¥¹¥×¥ì¥¤¤Ï
+30 KHz ¤«¤é37 KHz ¤ÎÈϰϤοåʿƱ´ü¿®¹æ¤Çưºî¤·¤Þ¤¹¡£¤³¤Î»þ¤Î£±¤Ä¤ÎÀþÅö¤¿¤ê
+¤Î¥É¥Ã¥È¤ÎºÇ¾®¿ô¤Ï 40,000,000/37,000 = 1,081.081 ¤è¤ê¡¢Ìó 1,081 ¥É¥Ã¥È/Àþ
+¤È¤Ê¤ê¤Þ¤¹¡£
+
+¤³¤Î£±ËÜÅö¤¿¤ê¤Î¥É¥Ã¥È¿ô¤ò¤³¤ì¤«¤é¤Î·×»»¤Ç»È¤¤¤Þ¤¹¡£¤À¤«¤é¡¢¥Ç¥£¥¹¥×¥ì¥¤¾å
+¤Î¤½¤ì¤¾¤ì¤ÎÀþ¤ÏºÇ¾®¤Ç 1081 ¥É¥Ã¥È¤¢¤ê¤Þ¤¹¡£¤³¤Î¿ôÃͤò 8 ¤Ç³ä¤êÀÚ¤ì¤ë¿ô¤Ë
+´Ý¤á¤Æ 1088 ¤ËÀÚ¤ê¾å¤²¤Þ¤¹¡£¤³¤³¤Ç¤Ï¿åʿƱ´ü¿®¹æÄ¹¤Ë 3.8 ¥Þ¥¤¥¯¥íÉäò»È¤¦
+¤³¤È¤ò²¾Äꤷ¤Æ¤¤¤Þ¤¹¡£ 3.8 ¥Þ¥¤¥¯¥íÉäο®¹æ¤òºî¤ë¤Î¤Ë²¿¥É¥Ã¥ÈɬÍפʤΤ«¤ò
+¸«¤Ä¤±¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£À褺£±¥É¥Ã¥È¤¬²¿¥Þ¥¤¥¯¥íÉäʤΤ«¤òõ¤·¤Þ¤·¤ç¤¦¡£Ëè
+Éà 40,000,000 ¥É¥Ã¥È¤Ê¤Î¤Ç¡¢1/40,000,000 ¤¬¥É¥Ã¥ÈÅö¤¿¤ê¤ÎÉÿô¤Ç¤¹¡£
+¤Ä¤Þ¤ê
+
+ 1/40,000,000 = .000000025 = ¥É¥Ã¥ÈÅö¤¿¤ê .025 ¥Þ¥¤¥¯¥íÉÃ
+
+¤È¤Ê¤ê¤Þ¤¹¡£
+
+¤³¤Î»þ 3.8 ¥Þ¥¤¥¯¥íÉÃ¤ÎÆ±´ü¿®¹æ¤ò¹½À®¤¹¤ë¥É¥Ã¥È¿ô D ¤Ï
+
+ 3.8 ¥Þ¥¤¥¯¥íÉà = D ¥É¥Ã¥È x .025 ¥Þ¥¤¥¯¥íÉÃ/¥É¥Ã¥È
+
+ ¤Ä¤Þ¤ê
+
+ D ¥É¥Ã¥È = (3.8 ¥Þ¥¤¥¯¥íÉÃ) / (.025 ¥Þ¥¤¥¯¥íÉÃ/¥É¥Ã¥È) = 152 ¥É¥Ã¥È
+¤Ç¤¹¡£
+
+ÀþÅö¤¿¤ê 1088 ¥É¥Ã¥È¤Î»þ¡¢152 ¥É¥Ã¥È¤òƱ´ü¿®¹æ¤Ë»ÈÍѤ·¤Æ¡¢800 ¥É¥Ã¥È¤¬µ±¤¤
+¤Æ¸«¤¨¤Æ¤¤¤ë¤ï¤±¤Ç¤¹¡£¡Ê152 ¤Ï 8 ¤Ç³ä¤êÀÚ¤ì¤ë¤³¤È¤ËÃí°Õ¤·¤Æ²¼¤µ¤¤¡£³ä¤êÀÚ
+¤ì¤Ê¤¤¾ì¹ç¤Ï³ä¤êÀÚ¤ì¤ë¤è¤¦¤ËÀÚ¤ê¾å¤²¤Æ²¼¤µ¤¤¡£¡Ë¤³¤³¤Ç¥Ç¥£¥¹¥×¥ì¥¤¤Î¤¿¤á¤Ë
+ɬÍ×¤ÊÆ±´ü¿®¹æ¤ÎÁ°¸å¤Î»þ´Ö¤ò·×»»¤¹¤ë»Å»ö¤¬»Ä¤Ã¤Æ¤¤¤Þ¤¹¡£
+
+·Ð¸³Â§¤Ë¤è¤ê¡¢Ëɸæ»þ´Ö¤ÎÌó 30 ñ°Ì¤¬É¬ÍפǤ¹¡£¾Ü¤·¤¯½Ò¤Ù¤ë¤È¡¢32 ¥É¥Ã¥È¤ò
+³ä¤êÅö¤Æ¤ë¤ÈÅԹ礬Îɤ¤¤Î¤Ï¡¢Â¾¤ÎÁ´¤Æ¤Î¿ôÃͤ¬ 8 ¤Ç³ä¤êÀÚ¤ì¤Æ¤¤¤ë¤«¤é¤Ç¤¹¡£
+ɽ¼¨Îΰè¤Ë 800 ¥É¥Ã¥È¡¢Æ±´ü¿®¹æ¤Ë 152 ¥É¥Ã¥È»È¤Ã¤¿·ë²Ì¡¢1088 - (800 + 152)
+= 136 ¤È¤Ê¤ê¡¢136 ¥É¥Ã¥È¤¬ 2 ¤Ä¤Î»þ´Ö¤Î´Ö¤òʬ¤±¤Æ¤¤¤Þ¤¹¡£136 ¤ÎȾʬ¤Î 68
+¥É¥Ã¥È¤¬µ±¤¤¤Æ¤¤¤ë¥É¥Ã¥È¤ÈƱ´ü¿®¹æ¤Î´Ö¤ËÃÖ¤«¤ì¤Æ¡¢68 ¥É¥Ã¥È¤¬Æ±´ü¿®¹æ¤Î¸å
+¤ËÃÖ¤«¤ì¤Æ¤¤¤Þ¤¹¡£Xconfig ¥Õ¥¡¥¤¥ë¤Î¿åÊ¿Êý¸þ¤Î¿ôÃͤϼ¡¤Î¤è¤¦¤Ë½ñ¤­¤Þ¤¹¡£
+
+ 800 (800+68) (800+68+152) (800+68+152+68)
+
+ ¤Ä¤Þ¤ê
+
+ 800 868 1020 1088
+¤È¤Ê¤ê¤Þ¤¹¡£
+
+º£Å٤ϿâľÊý¸þ¤Î¿ôÃͤò·×»»¤·¤Þ¤·¤ç¤¦¡£Åö½é¤«¤é¿âľÊý¸þ¤Î¿ôÃͤ˥ɥåȤÀ¤È¤«
+¥É¥Ã¥ÈÅö¤¿¤ê¤Î¥Þ¥¤¥¯¥íÉäȤ«¤Îñ°Ì¤ò»È¤ï¤º¤ËÀþ¤Î¿ô¤ò»È¤Ã¤Æ¤¤¤¿»ö¤ò»×¤¤½Ð¤·
+¤Æ²¼¤µ¤¤¡£¤è¤Ã¤Æ¡¢1 ËܤÎÀþ¤òɽ¼¨¤¹¤ë¤Î¤Ë¤É¤ì¤¯¤é¤¤¤Î»þ´Ö¤¬³Ý¤«¤ë¤«¤ò·×»»¤¹
+¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤³¤Î·×»»¤Ï¤½¤ì¤¾¤ì¤ÎÀþ¤¬ 1088 ¥É¥Ã¥È¤Ç¤½¤ì¤¾¤ì¤Î¥É¥Ã¥È¤Ï
+.025 ¥Þ¥¤¥¯¥íÉäʤΤǴÊñ¤Ç¤¹¡£½¾¤Ã¤Æ¡¢¤½¤ì¤¾¤ì¤ÎÀþ¤Ï
+
+(1088 ¥É¥Ã¥È/Àþ) x (.025 ¥Þ¥¤¥¯¥íÉÃ/¥É¥Ã¥È) = 27.2 ¥Þ¥¤¥¯¥íÉÃ/Àþ
+¤È·×»»¤Ç¤­¤Þ¤¹¡£
+
+ÀþÅö¤¿¤ê 800 ¥É¥Ã¥Èɽ¼¨²Äǽ¤òÁªÂò¤·¤¿¤Î¤Ç¡¢¥¢¥¹¥Ú¥¯¥ÈÈæ¤¬ 4 ÂÐ 3 ¤Ë¤Ê¤ë¤è
+¤¦¤ËÀþ¤Î¿ô¤òÁªÂò¤·¤Þ¤·¤ç¤¦¡£¤³¤Î»þ¡¢800 ¤Ï 4 x 200 ¤Ê¤Î¤Ç½ÄÊý¸þ¤ÎÀþ¤Î¿ô¤Ï
+3 x 200 = 600 ¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£ÌÜɸ²òÁüÅÙ¤Ï 800x600 ¤Ç¤¹¡£
+
+ ¿âľƱ´ü¿®¹æ¤ÎÈÏ°Ï¤Ï 50 ¤«¤é 300 ¥Þ¥¤¥¯¥íÉäǤ¢¤ë¤³¤È¤¬Ê¬¤«¤Ã¤Æ¤¤¤Þ¤¹¡£Âå
+ ɽŪ¤ÊƱ´ü¿®¹æ¤È¤·¤Æ 150 ¥Þ¥¤¥¯¥íÉäòÁªÂò¤·¤¿¾ì¹ç¤Ë¡¢150 ¥Þ¥¤¥¯¥íÉäò
+ 27.2 ¥Þ¥¤¥¯¥íÉädzä¤ì¤Ð 1 Ʊ´ü¿®¹æÅö¤¿¤ê¤ÎËÜ¿ô¤¬·×»»¤Ç¤­¤Þ¤¹¡£
+
+ (150 ¥Þ¥¤¥¯¥íÉÃ/Ʊ´ü¿®¹æ) / (27.2 ¥Þ¥¤¥¯¥íÉÃ/ËÜ) = 5.51 ËÜ/Ʊ´ü¿®¹æ
+
+ ¤³¤ì¤ò 6 ËÜ/Ʊ´ü¿®¹æ¤ËÀÚ¤ê¾å¤²¤ë¤³¤È¤Ç¡ÊÀÚ¤ê¼Î¤Æ¤Ï¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡Ë¡¢¿âľ
+ Ʊ´ü¿®¹æÉý¤¬µá¤Þ¤ê¤Þ¤·¤¿¡£
+
+ ¥Õ¥ì¡¼¥à¤ÎÀþ¤Î¡Êµ±¤¤¤Æ¤¤¤ëÀþ¤È¼þ°Ï¤Ë¤¢¤ëµ±¤¤¤Æ¤¤¤Ê¤¤Àþ¤ò²Ã¤¨¤¿¡Ë¹ç·×ËÜ¿ô¤ò
+ ¡Ê"¥Ó¥Ç¥ªÄ´À°..." ¤«¤é¡Ë¡¢É½¼¨²Äǽ¤ÊÀþ¤ÎËÜ¿ô¤è¤ê 5% Áý¤·¤Î¹ç·×ËÜ¿ô¤È¤·¤ÆÍ½
+ ¬¤Ç¤­¤Þ¤¹¡£¤è¤Ã¤Æ¡¢Àþ¤Î¹ç·×ËÜ¿ô¤Ï¼¡¤Î¤è¤¦¤Ë·×»»¤·¤Þ¤¹¡£
+
+ (600 ËÜ) x (1.05) = 630 (¥Õ¥ì¡¼¥àÅö¤¿¤ê¤Î¹ç·×ËÜ¿ô)
+
+ ¤µ¤Æ¤³¤³¤Ç¡¢µ±¤¤¤Æ¤¤¤ëÀþ (°Ê²¼¡¢µ±Àþ) ¤Î½ª¤ï¤ê¤È¥Õ¥ì¡¼¥à¤Î½ª¤ï¤ê¤Î´Ö¤ËƱ´ü
+ ¿®¹æ¤òÃÖ¤«¤Ê¤¤¤È¤¤¤±¤Þ¤»¤ó¡£¹ç·×¤Ç 630 ËÜ¡¢µ±Àþ¤¬ 600 ËÜ¡¢Æ±´ü¿®¹æ¤Ë 6 ËÜ
+ ¤¢¤ë¤Î¤Ç¡¢
+
+ 630 - 600 - 6 = 24 ËܻĤê¤Þ¤¹¡£
+
+ ´ö¤Ä¤«¤Î¥Ç¥£¥¹¥×¥ì¥¤¤Ïµ±Àþ¤Îľ¸å¤ËƱ´ü¿®¹æ¤òȯ¹Ô¤·¤Æ¤âÌäÂꤢ¤ê¤Þ¤»¤ó¤¬¡¢Â¾
+ ¤Î´ö¤Ä¤«¤Î¥Ç¥£¥¹¥×¥ì¥¤¤Ç¤Ï¡¢µ±Àþ¤ÎºÇ¸å¤ÈƱ´ü¿®¹æ¤ÎºÇ½é¤Î´Ö¤Ë 1 Ëܤ« 2 ËÜʬ
+ ´Ö³Ö¤òÃÖ¤¯¤Ù¤­¤Ç¤·¤ç¤¦¡£°ÂÁ´¤Î¤¿¤á¤Ë;͵¤ò»ý¤Ã¤Æ¡¢µ±Àþ¤ÎºÇ¸å¤ÈƱ´ü¿®¹æ¤ÎºÇ
+ ½é¤Î´Ö¤Ë 3 ËÜʬÄɲä·¤Þ¤¹¡£»Ä¤ê¤ÎËÜ¿ô¤òƱ´ü¿®¹æ¤Î¸å¤í¤ËÄɲä·¤Þ¤¹¡£¿âľƱ
+ ´üÄ´À°¤Î¿ôÃͤϼ¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
+
+ 600 (600+3) (600+3+6) (600+3+6+21)
+
+ ¤Ä¤Þ¤ê
+
+ 600 603 609 630
+
+ ¤È¤Ë¤«¤¯ºî¶È¤ò¹Ô¤Ê¤¦Á°¤Ë¡¢Àþ 1 ËÜÅö¤¿¤ê 27.2 ¥Þ¥¤¥¯¥íÉäλþ¤Ë¥Õ¥ì¡¼¥àÅö¤¿
+ ¤ê 630 Ëܤò¥Ç¥£¥¹¥×¥ì¥¤¤¬É½¼¨¤Ç¤­¤ë¤³¤È¤ò³Îǧ¤·¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£ÀßÄꤷ
+ ¤è¤¦¤È¤·¤Æ¤¤¤ë¹½À®¤ÇËèÉò¿¥Õ¥ì¡¼¥àɽ¼¨¤¹¤ë¤«·×»»¤·¡¢¥Ç¥£¥¹¥×¥ì¥¤¤Î¥Þ¥Ë¥å¥¢
+ ¥ë¤Î¿âľƱ´ü®Å٤˴ؤ¹¤ëµ­ºÜ¤È¸«Èæ¤Ù¤ë¤³¤È¤Ë¤è¤Ã¤Æ³Îǧ¤Ç¤­¤Þ¤¹¡£Àþ 1 ËÜÅö
+ ¤¿¤ê 27.2 ¥Þ¥¤¥¯¥íÉäλþ¤Ë¥Õ¥ì¡¼¥àÅö¤¿¤ê 630 ËÜɽ¼¨¤¹¤ë¤¿¤á¤Ë¤Ï¡¢630 x
+ 27.2 = 17,136 ¥Þ¥¤¥¯¥íÉÃ/¥Õ¥ì¡¼¥à ɬÍפǤ¹¡£17,136 ¥Þ¥¤¥¯¥íÉÃ/¥Õ¥ì¡¼¥à ¤Ï
+ 0.017136 ÉÃ/¥Õ¥ì¡¼¥à ¤Ä¤Þ¤ê 1/0.017136 ¥Õ¥ì¡¼¥à/Éà ¤Ç¤¹¡£
+
+ 1 / (0.017136 ÉÃ/¥Õ¥ì¡¼¥à ) = 58.4 ¥Õ¥ì¡¼¥à/ÉÃ
+
+ ¥Þ¥Ë¥å¥¢¥ë¤Ë¿âľƱ´ü®ÅÙ¤¬ 58.4 Hz ¤È½ñ¤«¤ì¤Æ¤¤¤¿¾ì¹ç¡¢¼ã¤·¤¯¤Ï 58.4 Hz ¤¬
+ ¥Ç¥£¥¹¥×¥ì¥¤¤Î¿âľƱ´ü²Äǽ¤Ê¼þÇÈ¿ôÂÓ°è¤Ë¤¢¤ë¾ì¹ç¤ÏÌäÂꤢ¤ê¤Þ¤»¤ó¡£¥Ç¥£¥¹¥×
+ ¥ì¥¤¤¬¤³¤Î®ÅÙ¤ò°·¤¨¤Ê¤¤¾ì¹ç¤Ï¡¢Á´¤Æ¤Î¿ô»ú¤òÈæÎ㤵¤»¤Æ¥Õ¥ì¡¼¥àÅö¤¿¤ê¤ÎÀþ¤Î
+ ËÜ¿ô¤òÊѹ¹¤·¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£
+
+ ¤µ¤Æ Xconfig ¤Î¥Æ¥¹¥È¹½À®¤òºîÀ®¤¹¤ë¤¿¤á¤Ë²òÁüÅ٤ȥ¯¥í¥Ã¥¯¤ò¹ç¤ï¤»¤Æ¿åÊ¿¤È
+ ¿âľ¤ÎÄ´À°¿ôÃͤòÁȹ礻¤Þ¤·¤ç¤¦¡£ÄêµÁ¤¹¤ë¹Ô¤Ï¼¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
+
+ "800x600" 40 800 868 1020 1088 600 603 609 630
+
+ ¤³¤ì¤Ç XFree86 ¤Î¹½À®¤¬½ÐÍè¾å¤¬¤ê¤Þ¤·¤¿¡£¤³¤³¤Ç¤¤¤¯¤Ä¤«²¾Äꤷ¤¿¤³¤È¤¬¤È¤Æ
+ ¤â¤Õ¤µ¤ï¤·¤¯¤Ê¤¯¤Æ¤¦¤Þ¤¯Æ°ºî¤·¤Ê¤¤¾ì¹ç¤¬¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¤¬¡¢¤Û¤È¤ó¤É¤Î¾ì
+ ¹ç¾¯¤Ê¤¯¤È¤â°ÂÄꤷ¤¿É½¼¨¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£¤µ¤¢¡¢²÷Ŭ¤Ë¤¹¤ë¤¿¤á¤Ë¤Á¤ç
+ ¤Ã¤È¤·¤¿¼Â¸³¤ò¤ä¤Ã¤Æ¤ß¤Þ¤·¤ç¤¦¡£
+
+ ¼ÂºÝ¤Î·×»»
+
+ »ä¤Î¥¢¥À¥×¥¿¡¼¥«¡¼¥É¤¬ 40 MHz ¤Î¿å¾½È¯¿®»Ò¤òÅëºÜ¤·¤Æ¤¤¤ë¤Î¤Ç¡¢¼þÇÈ¿ô¤ò 40
+ MHz ¤«¤é»Ï¤á¤Þ¤·¤ç¤¦¡£»ä¤Î¥Ç¥£¥¹¥×¥ì¥¤¤ÎºÇ¹â¿åʿƱ´ü¼þÇÈ¿ô¤¬ 37 KHz ¤Ê¤é¤Ð¡¢
+ ÀþÅö¤ê¤ÎºÇ¾®¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ï 40,000,000/37,000 = 1081 ¤Ë¤Ê¤ê¤Þ¤¹¡£»ä¤Î¥Ç¥£
+ ¥¹¥×¥ì¥¤¤Î¿âľƱ´ü¼þÇÈ¿ô¤Ï 50 Hz ¤«¤é 90 Hz ¤Þ¤Ç¤ÎÈϰϤǤ¹¡£
+
+ »ä¤Î¥Ç¥£¥¹¥×¥ì¥¤¤Î¥Þ¥Ë¥å¥¢¥ë¤Ë¤è¤ì¤ÐºÇÂç¤Î¿åʿƱ´ü¿®¹æ¤Ï 3.92 ¥Þ¥¤¥¯¥íÉäÇ
+ ¤¹¡£¥É¥Ã¥ÈÅö¤ê 0.025 ¥Þ¥¤¥¯¥íÉäξì¹ç¡¢¿®¹æ¤Ï
+
+ (3.92 ¥Þ¥¤¥¯¥íÉÃ) / (.025 ¥Þ¥¤¥¯¥íÉÃ/¥É¥Ã¥È) = 156.8 ¥É¥Ã¥È
+ ¤Ë¤Ê¤ê¤Þ¤¹¡£
+
+ ¤³¤ì¤òºÇ¤â¶á¤¤ 8 ¤ÎÇÜ¿ô¤ËÀÚ¤ê¾å¤²¤Æ¡¢160 ¥É¥Ã¥È¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+ ¤Þ¤¿¥Þ¥Ë¥å¥¢¥ë¤Ë¤è¤ì¤ÐºÇ¸å¤Ëµ±¤¤¤¿¥É¥Ã¥È¤ÈƱ´ü¿®¹æ¤Î»Ï¤Þ¤ê¤Î´Ö¤ËºÇÄã 0.67
+ ¥Þ¥¤¥¯¥íÉôֳ֤òÃÖ¤¯¤Ù¤­¤È²òÀ⤷¤Æ¤¤¤Þ¤¹¡£ 40 MHz ¤Î»þ 0.67 ¥Þ¥¤¥¯¥íÉäǽÐ
+ ¤»¤ë¥É¥Ã¥È¿ô D¡Ê 40 MHz ¤Ï .025 ¥Þ¥¤¥¯¥íÉÃ/¥É¥Ã¥È¤Ç¤¢¤ë¤³¤È¤ò³Ð¤¨¤Æ¤¤¤Æ¤¯
+ ¤À¤µ¤¤¡Ë¤Ï
+
+ D ¥É¥Ã¥È = (0.67 ¥Þ¥¤¥¯¥íÉÃ) / (.025 ¥Þ¥¤¥¯¥íÉÃ/¥É¥Ã¥È) = 26.8 ¥É¥Ã¥È
+ ¤Ë¤Ê¤ê¤Þ¤¹¡£
+
+ 26.8 ¤Ï 8 ¤ÎÇÜ¿ô¤Ç¤Ï¤Ê¤¤¤Î¤Ç¡¢32 ¥É¥Ã¥È¤ËÀÚ¤ê¾å¤²¤Æ²¼¤µ¤¤¡£
+
+ »ä¤Î¥Ç¥£¥¹¥×¥ì¥¤¤Î¥Þ¥Ë¥å¥¢¥ë¤Ë¤è¤ì¤ÐƱ´ü¿®¹æ¤Î¸å¤Î´Ö³Ö¤ò 3.56 ¥Þ¥¤¥¯¥íÉä«
+ ¤½¤ì°Ê¾åÃÖ¤¯¤Ù¤­¤Ç¤¢¤ë¤È½ñ¤¤¤Æ¤¤¤Þ¤¹¡£3.56 ¥Þ¥¤¥¯¥íÉäǤΥɥåȿô D ¤Ï
+
+ D ¥É¥Ã¥È = (3.56 ¥Þ¥¤¥¯¥íÉÃ) / (.025 ¥Þ¥¤¥¯¥íÉÃ/¥É¥Ã¥È) = 142.4 ¥É¥Ã¥È
+
+ 8 ¤ÎÇÜ¿ô¤Ë¤Ê¤ë¤è¤¦¤Ë 142.4 ¤ò 144 ¤ËÀÚ¤ê¾å¤²¤Æ²¼¤µ¤¤¡£
+
+ ¿åÊ¿Àþ¤Î¤¿¤á¤Ë 800 ¤Îµ±¤¯¥É¥Ã¥È¡¢µ±¤¯¥É¥Ã¥È¤ÈƱ´ü¿®¹æ¤Î´Ö¤Ë 32 ¥É¥Ã¥È¡¢Æ±
+ ´ü¿®¹æ¤Î¤¿¤á¤Î 152 ¥É¥Ã¥È¡¢Æ±´ü¿®¹æ¤Î¸å¤Ë 144 ¥É¥Ã¥È¤¬¤¢¤ê¤Þ¤¹¡£
+
+ 800 + 32 + 160 + 144 = 1136
+
+ 1 ËܤÎÀþ¤Ë 1136 ¥É¥Ã¥È»È¤Ã¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤ÏÁ°¤Ë·×»»¤·¤¿ 1088 ¤è¤êÂ礭¤¤¤Ç¤¹
+ ¤¬¡¢1088 ¤ÏÀþ¤òºî¤ë¥É¥Ã¥È¿ô¤Î *ºÇ¾®¤Î* ¿ô¤Ç¤¢¤ë¤³¤È¤ò»×¤¤½Ð¤·¤Æ²¼¤µ¤¤¡£¤Ç
+ ¤¹¤«¤éÀþÅö¤ê 1136 ¥É¥Ã¥È¤ÏÂè°ìÊâ¤È¤·¤Æ¤Ï¤¤¤¤¤È¤³¤í¤Ç¤·¤ç¤¦¡£
+
+ Xconfig ¤Ëµ­Æþ¤¹¤ë¿ôÃͤϡ¢¼¡¤Î¤è¤¦¤Ë
+
+ "800x?" 40 800 (800+32) (800+32+160) (800+32+160+144)...
+
+ ¤Þ¤¿¤Ï
+
+ "800x?" 40 800 832 992 1136...
+ ¤È¤·¤Þ¤·¤ç¤¦¡£
+
+
+ .025 ¥Þ¥¤¥¯¥íÉÃ/¥É¥Ã¥È¤Ç 1136 ¥É¥Ã¥È¤ÎÀþ¤ò°ú¤¯¤È¤¤¤¦¤³¤È¤Ï 1136 x .025 =
+ 28.4 ¥Þ¥¤¥¯¥íÉóݤ«¤ë¤³¤È¤òɽ¤·¤Æ¤¤¤Þ¤¹¡£
+
+ ¿åÊ¿²òÁüÅÙ¤Ë 800 ¥É¥Ã¥È/ËÜ ¤ò·è¤á¤¿¤Î¤Ç¡¢¿âľ²òÁüÅÙ¤Ë 600 ËÜ/¥Õ¥ì¡¼¥à¤ò·è
+ ¤á¤Þ¤·¤ç¤¦¡£
+
+ »ä¤Î¥Ç¥£¥¹¥×¥ì¥¤¤Î¥Þ¥Ë¥å¥¢¥ë¤Ë¤è¤ë¤È¿âľƱ´ü¿®¹æ¤ÏºÇÄã 64 ¥Þ¥¤¥¯¥íÉÃɬÍפÈ
+ ½ñ¤¤¤Æ¤¤¤Þ¤¹¡£ 64 ¥Þ¥¤¥¯¥íÉäÇÀþ¤ò°ú¤¯¤ÈËÜ¿ô¤Ï
+
+ (64 ¥Þ¥¤¥¯¥íÉÃ/Ʊ´ü¿®¹æ) / (28.4 ¥Þ¥¤¥¯¥íÉÃ/ËÜ) = 2.25 ËÜ/Ʊ´ü¿®¹æ
+ ¤È¤Ê¤ê¤Þ¤¹¡£
+
+ ¿âľƱ´ü¿®¹æ¤Î¤¿¤á¤Ë 2.25 ¤ò 3 ËܤËÀÚ¤ê¾å¤²¤Æ²¼¤µ¤¤¡£
+
+ ¥Þ¥Ë¥å¥¢¥ë¤Ë¤è¤ì¤ÐºÇ¸å¤Ëɽ¼¨¤·¤¿Àþ¤ÈƱ´ü¿®¹æ¤Î³«»ÏÅÀ¤Î´Ö¤ËºÇÄã 318 ¥Þ¥¤¥¯
+ ¥íÉá¢Æ±´ü¿®¹æ¤Î½ªÎ»¸å¤ÎÃÙ±ä¤òºÇÄã 630 ¥Þ¥¤¥¯¥íÉäδֳ֤òÃÖ¤¯¤è¤¦¤Ë½ñ¤«¤ì
+ ¤Æ¤¤¤Þ¤¹¡£¤½¤ì¤¾¤ì¤Î¶è´Ö¤Ç²¿ËÜ¡¢Àþ¤¬°ú¤±¤ë¤«¤ò¼¡¤Ë·×»»¤·¤Þ¤¹¡£
+
+ (318 ¥Þ¥¤¥¯¥íÉÃ) / (28.4 ¥Þ¥¤¥¯¥íÉÃ/ËÜ) = 11.20 ËÜ
+
+ (630 ¥Þ¥¤¥¯¥íÉÃ) / (28.4 ¥Þ¥¤¥¯¥íÉÃ/ËÜ) = 22.18 ËÜ
+
+ Ʊ´ü¿®¹æ¤ÎÁ°¤Î´Ö³Ö¤ò 12 ËÜ¡¢¸å¤Î´Ö³Ö¤ò 23 Ëܤ˴ݤá¤Þ¤¹¡£¤³¤ì¤Ç¿âľĴÀ°¤Î¿ô
+ Ãͤ¬·èÄꤷ¤Þ¤·¤¿¡£
+
+ 600 (600+12) (600+12+3) (600+12+3+23)
+
+ ¤¹¤Ê¤ï¤Á
+
+ 600 612 615 638
+ ¤È¤Ê¤ê¤Þ¤¹¡£
+
+¤³¤Î¥Õ¥ì¡¼¥à¼þÇÈ¿ô¤¬¥Ç¥£¥¹¥×¥ì¥¤¤ÎǽÎϤ˹ç¤Ã¤Æ¤¤¤ë¤³¤È¤ò³Î¤«¤á¤ë¤¿¤á¡¢¥Õ¥ì
+¡¼¥à¼þÇÈ¿ô¤¬¡¢ 28.4 ¥Þ¥¤¥¯¥íÉÃ/Ëܤλþ 638 ËÜ/¥Õ¥ì¡¼¥à¤Ï 18,119 ¥Þ¥¤¥¯¥íÉÃ/
+¥Õ¥ì¡¼¥à¤Ç¤¢¤ê¡¢55.19 ¥Õ¥ì¡¼¥à/Éäˤʤ뤳¤È¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£»ä¤Î¥Ç¥£¥¹
+¥×¥ì¥¤¤Ï 50 Hz ¤«¤é 90 Hz ¤Þ¤Ç¤ÎÁ´¤Æ¤Î¼þÇÈ¿ô¤ò°·¤¨¤ë¤Î¤ÇÌäÂꤢ¤ê¤Þ¤»¤ó¡£
+
+²òÁüÅÙ¡¢¥¯¥í¥Ã¥¯¡¢¿åÊ¿Êý¸þ¤È¿âľÊý¸þ¤ÎÄ´À°¿ôÃͤò Xconfig ¥Õ¥¡¥¤¥ë¤Î¥Ó¥Ç¥ª
+¥â¡¼¥É¤Î¹Ô¤Ë¼¡¤ÎÍͤ˵­Æþ¤·¤Æ²¼¤µ¤¤¡£
+
+ "800x600" 40 800 832 992 1136 600 612 615 638
+
+¤³¤ì¤¬»ä¤¬»î¤·¤¿ºÇ½é¤Î¥Ó¥Ç¥ª¥â¡¼¥É¤Ç¤¹¡£¤Á¤é¤Ä¤­¤¬¤Ò¤É¤¹¤®¤Æ¡¢¤È¤Æ¤âËþ­¤Ç
+¤­¤ë¤â¤Î¤Ç¤Ï¤Ê¤¤¤Î¤Ç»ß¤á¤Þ¤·¤¿¡£¤³¤ÎÀßÄê¤ÎÄ´À°¿ôÃͤò¾å¤²¤¿¤ê²¼¤²¤¿¤ê¤¹¤ëÎã
+¤ò¼¡¤«¤éÀâÌÀ¤·¤Þ¤¹¡£¤Á¤é¤Ä¤­¤È²òÁüÅ٤δ֤ÎÀÞ¤ê¹ç¤¤¤ò¤Ä¤±¤ÆºÇ½ªÅª¤Ë
+"784x614" ¤ËÀßÄꤷ¤Þ¤·¤¿¡£
+
+¤Û¤È¤ó¤ÉÁ´¤Æ¤Î¥¯¥í¥Ã¥¯¤Î¼þÇÈ¿ô¤Ï 40 MHz ¤Ç¤¢¤ë¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¼Â¸³
+¤òÄ̤·¤Æ¤è¤ê¹â¤¤¼þÇÈ¿ô¤Ï»ä¤Î¥¢¥À¥×¥¿¡¼¥«¡¼¥É¤ÎǽÎϤòͤ¨¤Æ¤ª¤ê¡¢¤è¤êÄ㤤¼þ
+ÇÈ¿ô¤Ï»ä¤Î˾¤à²òÁüÅÙ¤òÍ¿¤¨¤ë¤â¤Î¤Ç¤Ï¤Ê¤¤¤È¤¤¤¦¤³¤È¤¬Ê¬¤«¤ê¤Þ¤·¤¿¡£
+
+ Îã :
+ »ä¤¬»î¤·¤¿¿ôÃͤǤ¹ :
+
+<tscreen><verb>
+ # ¼¡¤Î¹Ô¤Ïư¤¯¤±¤ì¤ÉÃæ¿´¤«¤é±¦¤Ë´ó¤Ã¤Æ¤¤¤Þ¤¹¡£
+ "752x564" 40 752 784 944 1088 564 567 569 611
+ # 44.5 752 792 976 1240 564 567 570 600
+ #
+ # ¤³¤Î¹Ô¤ÏÁ°¤Î¹Ô¤Ç¤¢¤Ã¤¿ÌäÂê¤ò½¤Àµ¤·¤¿¤â¤Î¤Ç¤¹¡£
+ #"752x564" 40 752 816 976 1088 564 567 569 611
+ #
+ # ¿âľÊý¸þ¤Îɽ¼¨¤ÎÂ礭¤µ¤òÁý¤ä¤·¤Æ¤ß¤Þ¤·¤ç¤¦¡¢¤³¤ì¤Ïưºî¤·¤Þ¤¹¡£
+ #"752x614" 40 752 816 976 1088 614 617 619 661
+ #
+ # ¿åÊ¿Êý¸þ¤Îɽ¼¨¤ÎÂ礭¤µ¤òÁý¤ä¤·¤Æ¤ß¤Þ¤·¤ç¤¦¡¢¤³¤ì¤Ïưºî¤·¤Þ¤¹¡£
+ #"784x564" 40 784 816 976 1088 564 567 569 611
+ #
+ # ¼¡¤âư¤­¤Þ¤¹¤¬¡¢Ãæ¿´¤«¤é±¦¤Ë´ó¤Ã¤Æ¤¤¤Þ¤¹¡£
+ #"784x614" 40 784 816 976 1088 614 617 619 661
+ #
+ # ľÁ°¤ÎÎã¤ÎÃæ¿´¤Ë¤­¤Æ¤¤¤Ê¤¤ÌäÂê¤ò½¤Àµ¤·¤¿¤â¤Î¤Ç¤¹¡£
+ "784x614" 40 784 848 1008 1088 614 617 619 661
+ #
+ # ɽ¼¨¤ÎÂ礭¤µ¤òÁý¤ä¤·¤Æ¤ß¤Þ¤·¤ç¤¦
+ # ¼¡¤âư¤­¤Þ¤¹¤¬¡¢Ãæ¿´¤«¤é¤ï¤º¤«¤Ëº¸¤Ë´ó¤Ã¤Æ¤¤¤Þ¤¹¡£
+ #"800x614" 40 800 864 1024 1088 614 617 619 661
+ #
+ # ľÁ°¤ÎÀßÄê¤ÎÃæ¿´¤Ë¤­¤Æ¤¤¤Ê¤¤ÌäÂê¤ò½¤Àµ¤·¤¿¤â¤Î¤Ç¤¹¡£
+ "800x614" 40 800 864 1024 1104 614 617 619 661
+ #
+ # ɽ¼¨¤ÎÂ礭¤µ¤òÁý¤ä¤·¤Æ¤ß¤Þ¤·¤ç¤¦¡¢¤³¤ì¤Ïưºî¤·¤Þ¤¹¡£
+ "816x614" 40 816 880 1040 1120 614 617 619 661
+ #
+ # ɽ¼¨¤ÎÂ礭¤µ¤òÁý¤ä¤·¤Æ¤ß¤Þ¤·¤ç¤¦¡¢¤³¤ì¤Ïưºî¤·¤Þ¤¹¡£
+ "800x620" 40 800 864 1024 1104 620 623 625 661
+ #
+ # ɽ¼¨¤ÎÂ礭¤µ¤òÁý¤ä¤·¤Æ¤ß¤Þ¤·¤ç¤¦¡¢¤³¤ì¤Ïưºî¤·¤Þ¤¹¡£
+ "816x620" 40 816 880 1040 1120 620 623 625 661
+ #
+ # ɽ¼¨¤ÎÂ礭¤µ¤òÁý¤ä¤·¤Æ¤ß¤Þ¤·¤ç¤¦¡¢¤³¤ì¤Ïưºî¤·¤Þ¤¹¡£
+ "832x630" 40 832 896 1056 1136 630 633 635 661
+ #
+ # ɽ¼¨¤ÎÂ礭¤µ¤òÊѤ¨¤Þ¤·¤¿¡¢Æ°¤­¤Þ¤¹¤¬·ã¤·¤¯¤Á¤é¤Ä¤­¤Þ¤¹¡£
+ "848x618" 40 848 912 1072 1152 618 621 623 661
+</verb></tscreen>
+
+<sect> ɽ¼¨¤ÎÌäÂ꽤Àµ
+<p>
+
+¤µ¤¢¡¢ X ¤Î¹½À®ÄêµÁ¤Î¿ôÃͤò¼ê¤ËÆþ¤ì¤Þ¤·¤¿¡£Xconfig ¤Ë ¤½¤Î¿ôÃͤò¥Æ¥¹¥ÈÃæ¤Î
+¥³¥á¥ó¥È¤ò¤Ä¤±¤Æ½ñ¤­¤Þ¤·¤¿¡£X ¤òΩ¤Á¤¢¤²¡¢¥Û¥Ã¥È¥­¡¼¤Ç¿·¤·¤¤¥â¡¼¥É¤ËÀÚ¤êÂØ
+¤¨¤Æ¤ß¤Þ¤·¤¿ &hellip ¤·¤«¤·²èÁü¤¬ÊѤǤ¹¡£¤³¤¦¤¤¤¦¾ì¹ç¡¢¤É¤¦¤¹¤ì¤Ð¤¤¤¤¤Î¤Ç¤·¤ç¤¦¡©
+°ìÈÌŪ¤ÊÌäÂê¤È²ò·èºö¤ò¤³¤³¤Ëµó¤²¤Þ¤¹¡£
+
+Ʊ´ü¿®¹æ¤ÎÄ´À°¤òÊѤ¨¤Æ²èÁü¤ò *°Üư* ¤·¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£¥Õ¥ì¡¼¥àŤòÊѤ¨¤Æ²è
+Áü¤ò *³ÈÂç½Ì¾®* ¤·¤Æ²¼¤µ¤¤¡ÊÁêÂÐŪ¤Ê°ÌÃÖ¤ò¤½¤Î¤Þ¤Þ¤ËƱ´ü¿®¹æ¤ò°Üư¤¹¤ëɬÍ×
+¤¬¤¢¤ê¤Þ¤¹¡£¤½¤¦¤·¤Ê¤¤¤È³ÈÂç½Ì¾®¤ÈƱ»þ¤Ë²èÁü¤Î°Üư¤âµ¯¤³¤Ã¤Æ¤·¤Þ¤¤¤Þ¤¹¡Ë¡£
+¤â¤¦¾¯¤·¸ÄÊ̤ÎÂнèÊýË¡¤ò¼¡¤Ë¼¨¤·¤Þ¤¹¡£:
+
+¿åÊ¿¤È¿âľ¤Îɽ¼¨°ÌÃÖ¤ÏÆÈΩ¤·¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤Ï²èÁü¤ò¿åÊ¿¤Ë°Üư¤µ¤»¤Æ¤â¿âľ°Ì
+Ã֤ˤϱƶÁ¤¬¤Ê¤¯¡¢¤Þ¤¿µÕ¤âƱ¤¸¤È¤¤¤¦¤³¤È¤Ç¤¹¡£¤È¤³¤í¤¬³ÈÂç½Ì¾®¤Ç¤Ïɬ¤º¤·¤â
+¤½¤¦¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¿åÊ¿Êý¸þ¤ÎÂ礭¤µ¤òÊѤ¨¤Æ¤â¿âľÊý¸þ¤ÎÂ礭¤µ¤Ë¤Ï²¿¤â±Æ¶Á
+¤òÍ¿¤¨¤º¡¢µÕ¤âƱ¤¸¤Ç¤¹¤¬¡¢½Ä²£Î¾Êý¤ÎÊѹ¹Î̤ιç·×¤Ï¸ÂÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£ÆÃ¤Ë¡¢
+½Ä²£¤ËÂ礭²á¤®¤¿¾ì¹ç¤Ï¤è¤ê¹â¤¤¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ËÊѹ¹¤·¤Æ½¤Àµ¤¹¤ëɬÍפ¬¤¢¤ë¤Ç
+¤·¤ç¤¦¡£»ÈÍѲÄǽ¤Ê²òÁüÅÙ¤ò°ú¤­¾å¤²¤ë¤³¤È¤Ë¤Ê¤ë¤¿¤á¡¢¤³¤ì¤Ï¤á¤Ã¤¿¤ËÌäÂê¤È¤Ï
+¤Ê¤ê¤Þ¤»¤ó¡£
+
+²èÁü¤¬º¸¤«±¦¤Ë¤º¤ì¤Æ¤¤¤ë¾ì¹ç
+
+¤³¤ì¤ò½¤Àµ¤¹¤ë¤¿¤á¤Ë¿åʿƱ´ü¿®¹æ¤ò°Üư¤·¤Þ¤·¤ç¤¦¡£¤½¤ì¤Ï¿åʿƱ´ü¿®¹æ¤Î³«»Ï
+ü¤È½ªÎ»Ã¼¤òÄêµÁ¤·¤Æ¤¤¤ë¿åʿĴÀ°Éôʬ¤Î 2 ¤Ä¤Î¿ôÃͤο¿¤óÃæ¤Î¿ôÃͤò¡Ê 8 ¤ÎÇÜ
+¿ô¤º¤Ä¡ËÁý¸º¤µ¤»¤Æ¹Ô¤¤¤Þ¤·¤ç¤¦¡£
+
+²èÁü¤¬º¸¤Ë¤º¤ì¤Æ¤¤¤ë¡Ê±¦¤Î±ï¤ÎÉôʬ¤¬Â礭¤¹¤®¤Æ¡¢±¦¤Ø²èÁü¤ò°Üư¤·¤¿¤¤¡Ë»þ¤Ï¡¢
+¿ôÃͤòÁý¤ä¤·¤Æ¤¯¤À¤µ¤¤¡£²èÁü¤¬±¦¤Ë¤º¤ì¤Æ¤¤¤ë¡Êº¸¤Î±ï¤ÎÉôʬ¤¬Â礭¤¹¤®¤Æ¡¢º¸
+¤Ø²èÁü¤ò°Üư¤·¤¿¤¤¡Ë»þ¤Ï¡¢Æ±´ü¿®¹æ¤ò¸º¤é¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+²èÁü¤¬¾å²¼¤Ëư¤¤¤Æ¤¤¤ë¾ì¹ç
+
+¤³¤ì¤ò½¤Àµ¤¹¤ë¤¿¤á¤Ë¿âľƱ´ü¿®¹æ¤ò°Üư¤·¤Æ¤¯¤À¤µ¤¤¡£¤½¤ì¤Ï¿âľƱ´ü¿®¹æ¤Î³«
+»Ïü¤È½ªÎ»Ã¼¤òÄêµÁ¤·¤Æ¤¤¤ë¿âľĴÀ°Éôʬ¤Î 2 ¤Ä¤Î¿ôÃͤο¿¤óÃæ¤Î¿ôÃͤòÁý¸º¤µ
+¤»¤Æ¹Ô¤¤¤Þ¤·¤ç¤¦¡£
+
+²èÁü¤¬¾å¤Ë¤º¤ì¤Æ¤¤¤ë¡Ê²¼¤Î±ï¤ÎÉôʬ¤¬Â礭¤¹¤®¤Æ¡¢²¼¤Ë²èÁü¤ò°Üư¤·¤¿¤¤¡Ë»þ¤Ï¡¢
+¿ôÃͤò¸º¤é¤·¤Æ¤¯¤À¤µ¤¤¡£²èÁü¤¬²¼¤Ë¤º¤ì¤Æ¤¤¤ë¡Ê¾å¤Î±ï¤ÎÉôʬ¤¬Â礭¤¹¤®¤Æ¡¢¾å
+¤Ø²èÁü¤ò°Üư¤·¤¿¤¤¡Ë»þ¤Ï¡¢¿ôÃͤòÁý¤ä¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+²èÁü¤¬¿åÊ¿Êý¸þ¤Ë¹­¤¹¤®¤ë¡Ê¶¹¤¹¤®¤ë¡Ë¾ì¹ç
+
+¤³¤ì¤ò½¤Àµ¤¹¤ë¤¿¤á¤Ë¤Ï¿åÊ¿¥Õ¥ì¡¼¥àŤòÁý¤ä¤·¡Ê¸º¤é¤·¡Ë¤Æ¤¯¤À¤µ¤¤¡£¤½¤ì¤ÏºÇ
+½é¤ÎÄ´À°Éôʬ¤Î 4 ÈÖÌܤοôÃͤòÊѤ¨¤Æ¹Ô¤¤¤Þ¤¹¡£²èÁü¤¬°Üư¤¹¤ë¤Î¤ò²óÈò¤¹¤ë¤¿
+¤á¡¢Æ±´ü¿®¹æ¡Ê 2 ÈÖÌÜ¤È 3 ÈÖÌܤοôÃ͡ˤ⤽¤ÎȾʬ¤À¤±°Üư¤·¡¢Æ±¤¸ÁêÂаÌÃÖ¤ò
+Êݸ¤·¤Æ¤ª¤¤¤Æ¤¯¤À¤µ¤¤¡£
+
+²èÁü¤¬¿âľÊý¸þ¤ËËĤé¤ó¤Ç¤¤¤ë¡ÊÁ餻¤Æ¤¤¤ë¡Ë¾ì¹ç
+
+¤³¤ì¤ò½¤Àµ¤¹¤ë¤¿¤á¤Ë¤Ï¿âľ¥Õ¥ì¡¼¥àŤò¸º¤é¤·¡ÊÁý¤ä¤·¡Ë¤Æ¤¯¤À¤µ¤¤¡£¤½¤ì¤Ï
+2 ÈÖÌܤÎÄ´À°Éôʬ¤Î 4 ÈÖÌܤοôÃͤòÊѤ¨¤Æ¹Ô¤¤¤Þ¤¹¡£²èÁü¤¬°Üư¤¹¤ë¤Î¤ò²óÈò¤¹
+¤ë¤¿¤á¡¢Æ±´ü¿®¹æ¡Ê 2 ÈÖÌÜ¤È 3 ÈÖÌܤοôÃͤǡˤ⤽¤ÎȾʬ¤À¤±°Üư¤·¡¢Æ±¤¸ÁêÂÐ
+°ÌÃÖ¤òÊݸ¤·¤Æ¤ª¤¤¤Æ¤¯¤À¤µ¤¤¡£
+
+¤³¤ì¤é¤Îµ»½Ñ¤ÎÁȹ礻¤Ç¤â¼è¤ì¤Ê¤¤Â¾¤ÎÏĤߤÏ¿ʬ¤â¤Ã¤È´ðËÜŪ¤ÊÉôʬ¤¬°ã¤Ã¤Æ¤¤
+¤ë¡¢Î㤨¤Ð·×»»°ã¤¤¤È¤«¥â¥Ë¥¿¡¼¤Ç»È¤¨¤Ê¤¤¹â¤¤¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ò»È¤Ã¤Æ¤¤¤ë¤è¤¦
+¤Ê¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£
+
+ºÇ¸å¤Ë¡¢¥Õ¥ì¡¼¥àŤΤɤÁ¤é¤«¤Î¿ôÃͤòÁý¤ä¤»¤ÐºÆÉÁ²è®ÅÙ¤¬Äã²¼¤·¤Æ¤·¤Þ¤¦¤³¤È¡¢
+¤Þ¤¿¤½¤ÎµÕ¤â¸À¤¨¤ë¤³¤È¤ò³Ð¤¨¤Æ¤ª¤¤¤Æ²¼¤µ¤¤¡£
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/VidModes.sgml,v 3.2 1997/01/26 04:34:27 dawes Exp $
+</verb>
+<hrule>
+
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ï xc/programs/Xserver/hw/xfree86/doc/sgml/VidModes.sgml,v 3.8 1996/02/04 09:08:28 ¤ò¡¢ ²¬ËÜ °ì¹¬
+( Kazuyuki Okamoto <url url="mailto:ikko-@pacific.rim.or.jp"
+name="&lt;ikko-@pacific.rim.or.jp&gt;"> ) ¤¬ XFree86 3.2 ¤ò
+ÆüËܤǥ¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¿Í¸þ¤±¤ËÏÂÌõ¤·¤¿¤â¤Î¤Ç¤¹¡£¤³¤³¤¬¤ª¤«¤·¤¤¤È¤«¡¢
+¤³¤³¤Ï¤³¤¦¤·¤¿¤Û¤¦¤¬¤¤¤¤¤È¤¤¤Ã¤¿¤´°Õ¸«¤¬¤¢¤ê¤Þ¤·¤¿¤é¡¢ÅŻҥ᡼¥ë¤Ç
+¤ªÃΤ餻²¼¤µ¤¤¡£
+¸¶Ê¸¤ÎÃøºî¸¢¤Ï XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ÎÏÂÌõ¤ÎÃøºî¸¢¤Ï
+XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤È²¬ËÜ¡¡°ì¹¬¤Ë¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤ÎÏÂÌõ¤ÎÉÔ¶ñ¹ç¤Ï»ä¤Ë¡¢
+ÅŻҥ᡼¥ë¤ÇÁ÷¤Ã¤Æ²¼¤µ¤¤¡£
+<hrule>
+&lsqb;EOF&rsqb;
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/ati.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/ati.sgml
new file mode 100644
index 000000000..7a4f160ed
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/ati.sgml
@@ -0,0 +1,389 @@
+<!doctype linuxdoc system>
+<article>
+
+<!-- Title information -->
+<!-- ....1.........2.........3.........4.........5.........6...... -->
+<title>ATI ¥¢¥À¥×¥¿¤Î README
+<author>Marc Aurele La France
+<date>1996 ǯ 3 ·î 23 Æü
+<trans> ²¬ËÜ¡¡°ì¹¬ Kazuyuki Okamoto &lt;ikko-@pacific.rim.or.jp&gt;
+
+<abstract>
+Ëܽñ¤Ï XF86_Mono, XF86_VGA16 ¤È XF86_SVGA ¥µ¡¼¥Ð¤Ç»ÈÍѤ·¤Æ¤¤¤ë
+XFree86 ATI VGA ¥É¥é¥¤¥Ð¤Ë´Ø¤¹¤ë README ¤Ç¤¹¡£
+Mach8, Mach32 ¼ã¤¯¤Ï Mach64 ¥¢¥¯¥»¥é¥ì¡¼¥¿¤¬ÅëºÜ¤µ¤ì¤Æ¤¤¤ë ATI ¥°¥é
+¥Õ¥£¥Ã¥¯¥Ü¡¼¥É¤Î»ÈÍѼԤϥ¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð (XF86_Mach8,XF86_Mach32
+¼ã¤¯¤Ï XF86_Mach64) ¤ò»ÈÍѤ¹¤ë¤Ù¤­¤Ç¤¹¡£Èó¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼¥Ð
+(XF86_Mono, XF86_VGA16 ¤È XF86_SVGA) ¤â²ÔƯ¤·¤Þ¤¹¤¬¡¢¤½¤ÎǽÎϤòÀ¸¤«¤·
+ÀÚ¤ì¤Þ¤»¤ó¡£
+</abstract>
+
+<!-- Table of contents -->
+<toc>
+
+<!-- Begin the document -->
+
+<sect> ATI VGA ¥É¥é¥¤¥Ð¤È¤Ï²¿¤« ?<p>
+ ATI VGA ¥É¥é¥¤¥Ð¤Ï XFree86 ÍѤΠ256 ¿§, 16 ¿§¤ÈÇò¹õ¤Î¥É¥é¥¤¥Ð¤Ç¤¹¡£
+¤³¤Î¥É¥é¥¤¥Ð¤Ï SuperVGA ¤È¤·¤ÆÆ¯¤«¤Ê¤¤¤â¤Î(¤¤¤¯¤Ä¤«¤Î½é´ü¤Î Mach8 ¤È
+Mach32 ¥¢¥À¥×¥¿) ¤ò½ü¤¤¤¿Á´¤Æ¤Î ATI ¥Ó¥Ç¥ª¥¢¥À¥×¥¿¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£
+¼¡¤Î¤ª¤ª¤è¤½¤Î (x/y = (1 + sqrt(5))/2 ¤Ê¤ë²«¶âʬ³äÈæ¤ò´ð¤Ë¤·¤¿) ºÇÂç²ò
+ÁüÅ٤ϥܡ¼¥É¤ËÅëºÜ¤·¤Æ¤¤¤ë»ÈÍѲÄǽ¤Ê¥Ó¥Ç¥ª¥á¥â¥ê¡Ê¤È¥â¥Ë¥¿¡¼¤ÎǽÎϡˤË
+°Í¸¤·¤Þ¤¹¡£:
+
+<verb>
+ 256k 640x409x256 896x585x16
+ 512k 896x585x256 1280x819x16
+ 1M 1280x819x256 1824x1149x16</verb>
+Çò¹õ¥µ¡¼¥Ð¤Ï»ÈÍѲÄǽ¤Ê¥Ó¥Ç¥ª¥á¥â¥ê¤ÎºÇÂç¤Î 1/4 ¤ò»ÈÍѤ¹¤ë¤Î¤Ç¡¢Çò¹õ
+¤Ç¤ÎºÇÂç²òÁüÅÙ¤Ï 16 ¿§¥â¡¼¥É¤ÈƱ¤¸¤Ê¤Î¤Ç¤¹¡£<p>
+<sect> ATI VGA Wonder ¥É¥é¥¤¥Ð ¤Ç¤Ï *½ÐÍè¤Ê¤¤»ö* ¤Ï²¿¤«¡©<p>
+¤³¤Î¥É¥é¥¤¥Ð¤Ï¥Ô¥¯¥»¥ë¤¢¤¿¤ê 8 ¥Ó¥Ã¥È°Ê¾å¤Î¿¼¤µ¤ò̤¤À¥µ¥Ý¡¼¥È¤·¤Æ¤Þ¤»
+¤ó¡£
+¤ª¼ê¸µ¤Î¥Þ¥Ë¥å¥¢¥ë¤Ë¥°¥é¥Õ¥£¥Ã¥¯¥¢¥À¥×¥¿¤¬ 256 ¿§°Ê¾å¤Î¥â¡¼¥É¤ò¥µ¥Ý¡¼
+¥È¤·¤Æ¤¤¤ë¤Èµ­ºÜ¤¬¤¢¤Ã¤Æ¤â¡¢ATI VGA Wonder ¥É¥é¥¤¥Ð¤¬ 256 ¿§°Ê¾å¤Î¥â¡¼
+¥É¤ò»È¤Ã¤Æ¤¤¤Ê¤¤¤Î¤Ç¤¹¡£<p>
+ATI VGA ¥É¥é¥¤¥Ð¤Ï¥¢¥¯¥»¥é¥ì¡¼¥¿¥É¥é¥¤¥Ð¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤ª¼ê¸µ¤Î
+¥É¥é¥¤¥Ð¤¬ Mach8, Mach32 ¤Þ¤¿¤Ï Mach64 ¥Ó¥Ç¥ª¥³¥ó¥È¥í¡¼¥é¤òÅëºÜ¤·¤Æ¤¤¤ë
+¾ì¹ç¡¢¥É¥é¥¤¥Ð¤Ï¥°¥é¥Õ¥£¥Ã¥¯¥Ü¡¼¥É¤Î¥¢¥¯¥»¥é¥ì¡¼¥¿µ¡Ç½¤ò»ÈÍѤ·¤Þ¤»¤ó¡£
+(Mach32 ÍÑ¤È Mach64 ÍѤΥ¢¥¯¥»¥é¥ì¡¼¥¿¤ËÅý¹ç¤µ¤ì¤Æ¤¤¤ë) ¥É¥é¥¤¥Ð¤Ï VGA
+¥Ü¡¼¥É¤À¤±¤ò»ÈÍѤ·¤Þ¤¹¡£¤³¤ÎÎã¤Ïʬ¤«¤ê¤Ë¤¯¤¤¤Ç¤¹¤¬¡¢²¿¤È¤«Æ°ºî¤·¤Þ¤¹¡£<p>
+<sect> ¤É¤Î¤è¤¦¤Ê¥Ó¥Ç¥ª¥¢¥À¥×¥¿¤Ç¥É¥é¥¤¥Ð¤¬Æ°ºî¤¹¤ë¤«¡©<p>
+¼¡¤Î ATI ¥Ó¥Ç¥ª¥³¥ó¥È¥í¡¼¥é¥Á¥Ã¥×¤òÅëºÜ¤·¤Æ¤¤¤ë¤Û¤È¤ó¤É¤Î¥É¥é¥¤¥Ð¤Ç¤³
+¤Î¥É¥é¥¤¥Ð¤Ïưºî¤·¤Þ¤¹¡£
+<verb>
+VGA Wonder ·ÏÎó: 18800, 18800-1, 28800-2, 28800-4, 28800-5, 28800-6
+ Mach32 ·ÏÎó: 68800-3, 68800-6, 68800AX, 68800LX
+ Mach64 ·ÏÎó: 88800GX-C, 88800GX-D, 88800GX-E, 88800GX-F, 88800CX,
+ 264CT, 264ET, 264VT, 264VT2, 264GT</verb>
+<!--
+ Mach64 series: 88800GX-C, 88800GX-D, 88800GX-E, 88800GX-F, 88800CX,
+ 264CT, 264ET, 264VT, 264VT2, 264GT</verb>
+The 264xT series are integrated controllers, meaning that they include an
+internal RAMDAC and clock generator.
+Some early Mach32 adapters will not work with this driver because they do not
+provide VGA functionality.
+Also, early Mach8 adapters will not work for the same reason, unless the
+adapter also has a video controller from the VGA Wonder series (or is connected
+to one through the VGA passthrough connector).<p>
+These adapters are available with a variety of clock generators and RAMDACs.
+See the XF86Config section below for details.
+These adapters are available with or without a mouse.<p>
+VGA Wonder V3 adapters use a 18800 video controller and generate dot clocks
+with crystals.
+VGA Wonder V4 adapters have a 18800-1 and also use crystals.
+VGA Wonder V5 adapters also use a 18800-1, but have a 18810 clock generator.
+VGA Wonder+ adapters use a 28800-2 and a 18810.
+Other than these, ATI's adapter naming convention (if it can be said that one
+-->
+264xT ¥·¥ê¡¼¥º¤ÏÆâ¢ RAMDAC ¤È¥¯¥í¥Ã¥¯¥¸¥§¥Í¥ì¡¼¥¿¤òÅëºÜ¤·¤Æ¤¤¤ë¤Î¤ÇÅý¹ç
+¥³¥ó¥È¥í¡¼¥é¤Ç¤¹¡£
+¤¤¤¯¤Ä¤«¤Î½é´ü·¿¤Î Mach32 ¥¢¥À¥×¥¿¤¬¤³¤Î¥É¥é¥¤¥Ð¤Çưºî¤·¤Ê¤¤¤Î¤Ï¡¢VGA µ¡
+ǽ¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¤«¤é¤Ç¤¹¡£
+¤Þ¤¿Æ±ÍͤÎÍýͳ¤Ç¡¢ VGA Wonder ·ÏÎ󤫤é¥Ó¥Ç¥ª¥³¥ó¥È¥í¡¼¥é¤òÅëºÜ¤·¤Æ
+¤¤¤ë¥Ü¡¼¥É¡Ê¤Þ¤¿¤Ï VGA ¥Ñ¥¹¥¹¥ë¡¼¥³¥Í¥¯¥¿¤«¤éÀܳ¤¹¤ë¾ì¹ç¡Ë¤ò½ü¤¤¤Æ½é
+´ü·¿¤Î Mach8 ¥¢¥À¥×¥¿¤âưºî¤·¤Þ¤»¤ó¡£<p>
+¤³¤ì¤é¤Î¥¢¥À¥×¥¿¤Ç¤ÏÍÍ¡¹¤Ê¥¯¥í¥Ã¥¯¥¸¥§¥Í¥ì¡¼¥¿¤È RAMDAC ¤¬»ÈÍѲÄǽ¤Ç¤¹¡£
+¾ÜºÙ¤Ï°Ê¹ß¤Î XF86Config ¤ÎÀá¤ò¤´Í÷¤¯¤À¤µ¤¤¡£
+¤³¤ì¤é¤Î¥¢¥À¥×¥¿¤Ï¥Þ¥¦¥¹¤¬¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â»ÈÍѲÄǽ¤Ç¤¹¡£
+VGA Wonder V3 ¥¢¥À¥×¥¿¤Ï 18800 ¥Ó¥Ç¥ª¥³¥ó¥È¥í¡¼¥é¤òÅëºÜ¤·¡¢¿å¾½È¯¿¶»Ò¤Ë
+¤è¤Ã¤Æ¥É¥Ã¥È¥¯¥í¥Ã¥¯¤òÀ¸À®¤·¤Æ¤¤¤Þ¤¹¡£
+VGA Wonder V4 ¥¢¥À¥×¥¿¤Ï 18800-1 ¤È¤³¤Á¤é¤â¿å¾½È¯¿¶»Ò¤òÅëºÜ¤·¤Æ¤¤¤Þ¤¹¡£
+VGA Wonder V5 ¥¢¥À¥×¥¿¤â¤Þ¤¿ 18800-1 ¤òÅëºÜ¤·¤Æ¤¤¤Þ¤¹¤¬¡¢18810 ¥¯¥í¥Ã¥¯
+¥¸¥§¥Í¥ì¡¼¥¿¤òÅëºÜ¤·¤Æ¤¤¤Þ¤¹¡£
+VGA Wonder+ ¥¢¥À¥×¥¿¤Ï 28800-2 ¤È 18810 ¤òÅëºÜ¤·¤Æ¤¤¤Þ¤¹¡£
+¤½¤Î¾¤Î ATI ¤Î¥¢¥À¥×¥¿¤Î̾¾Î¤Î·è¤áÊý¤Î´·½¬¡ÊÀΤ«¤é¤¢¤Ã¤¿¤â¤Î¡Ë¤Ç¤Ï̾Á°
+¤Î°ìÉôʬ¤ò¾Êά¤·¤Æ¤¤¤Þ¤¹¡£<p>
+
+<!--
+ The VGA Wonder series was also available through ATI's OEM channel under the
+name VGA1024.
+Thus, the ATI VGA driver also supports VGA1024, VGA1024D, VGA1024XL,
+VGA1024DXL and VGA1024VLB boards, among others.
+-->
+VGA Wonder ·ÏÎó¤Ï¤Þ¤¿¡¢ATI ¤Î OEM À褫¤é VGA1024 ¤È¤¤¤¦Ì¾¾Î¤ÇȯÇä
+¤·¤Æ¤¤¤Þ¤¹¡£
+½¾¤Ã¤Æ¡¢ATI VGA ¥É¥é¥¤¥Ð¤Ï VGA1024, VGA1024D, VGA1024XL, VGA1024DXL ¤È
+VGA1024VLB ¥Ü¡¼¥É¤ä¤½¤ÎÎà¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£<p>
+<sect>XF86Config ¥Õ¥¡¥¤¥ë¤Ë²¿¤ò½ñ¤¤¤¿¤éÎɤ¤¤Ç¤·¤ç¤¦¡©<p>
+¥Á¥Ã¥×¥»¥Ã¥È¤¬¹½À®¤ò¼«Æ°¸¡½Ð¤¹¤ë¤Ç¤·¤ç¤¦¡£
+<!--
++The chipset name for this driver is "ati".
++The driver also recognizes "vgawonder", "mach8", "mach32" and "mach64" as
++chipset names.
++In this version of the driver, all names are equivalent.
++In some future version each name will have a different meaning to be
++documented at that time.<p>
++The clocks line to be specified in your XF86Config depends on what the adapter
++uses to generate dot clocks.<p>
++For all adapters, one of the following clocks specifications (or an initial
++subset thereof) can be used depending on what the adapter uses to generate dot
+-->
+¤³¤Î¥É¥é¥¤¥Ð¤Ç¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Î̾¾Î¤Ï "ati" ¤Ç¤¹¡£
+¤Þ¤¿¡¢¥É¥é¥¤¥Ð¤Ï "vgawonder", "mach8", "mach32" ¤È "mach64" ¤Î¤è¤¦¤Ê¥Á¥Ã¥×
+¥»¥Ã¥È¤Î̾¾Î¤Ç¤âǧ¼±¤Ç¤­¤Þ¤¹¡£¤³¤Î¥Ð¡¼¥¸¥ç¥ó¤Î¥É¥é¥¤¥Ð¤Ç¤Ï¤¹¤Ù¤Æ¤Î̾¾Î¤Ï
+ƱÅù¤Ç¤¹¡£¾­Íè¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤½¤ì¤¾¤ì¤Î̾¾Î¤Ï°Û¤Ê¤Ã¤¿°ÕÌ£¤ò»ý¤Ä¤³¤È¤ò
+¤½¤Î¤È¤­Ê¸½ñ²½¤¹¤ë¤Ç¤·¤ç¤¦¡£<p>
+Á´¤Æ¤Î¥¢¥À¥×¥¿¤Ç¡¢¼¡¤ÎÆâ¤Î°ì¤Ä¤Î¥¯¥í¥Ã¥¯¡Ê¤Þ¤¿¤Ï¤½¤ì¤é¤ÎºÇ½é¤ÎÉôʬ¡Ë¤Î
+ÀßÄê¤Ï¥¢¥À¥×¥¿¤¬À¸À®¤¹¤ë¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ë°Í¸¤·¤¿¤â¤Î¤Ë¤Ê¤ê¤Þ¤¹¡£:
+<!--
++Crystals (VGA Wonder V3 and V4 adapters only):
++
++ Clocks 50.000 56.644 0.000 44.900 44.900 50.000 0.000 36.000
++ 25.000 28.322 0.000 22.450 22.450 25.000 0.000 18.000
++ 16.667 18.881 0.000 14.967 14.967 16.667 0.000 12.000
++ 12.500 14.161 0.000 11.225 11.225 12.500 0.000 9.000</verb>
+-->
+<verb>
+¿å¾½È¯¿¶»Ò (VGA Wonder V3 ¤È V4 ¥¢¥À¥×¥¿ ¤Î¤ß):
+
+ Clocks 50.000 56.644 0.000 44.900 44.900 50.000 0.000 36.000
+ 25.000 28.322 0.000 22.450 22.450 25.000 0.000 18.000
+ 16.667 18.881 0.000 14.967 14.967 16.667 0.000 12.000
+ 12.500 14.161 0.000 11.225 11.225 12.500 0.000 9.000</verb>
+<verb>
+ATI 18810 ¥¯¥í¥Ã¥¯¥¸¥§¥Í¥ì¡¼¥¿:
+
+ Clocks 30.240 32.000 37.500 39.000 42.954 48.771 0.000 36.000
+ 40.000 56.644 75.000 65.000 50.350 56.640 0.000 44.900
+ 15.120 16.000 18.750 19.500 21.477 24.386 0.000 18.000
+ 20.000 28.322 37.500 32.500 25.175 28.320 0.000 22.450
+ 10.080 10.667 12.500 13.000 14.318 16.257 0.000 12.000
+ 13.333 18.881 25.000 21.667 16.783 18.880 0.000 14.967
+ 7.560 8.000 9.375 9.750 10.739 12.193 0.000 9.000
+ 10.000 14.161 18.750 16.250 12.586 14.160 0.000 11.225</verb>
+<verb>
+ATI 18811-0 ¤È ATI 18812-0 ¥¯¥í¥Ã¥¯¥¸¥§¥Í¥ì¡¼¥¿:
+
+ Clocks 30.240 32.000 110.000 80.000 42.954 48.771 92.400 36.000
+ 39.910 44.900 75.000 65.000 50.350 56.640 0.000 44.900
+ 15.120 16.000 55.000 40.000 21.477 24.386 46.200 18.000
+ 19.955 22.450 37.500 32.500 25.175 28.320 0.000 22.450
+ 10.080 10.667 36.667 26.667 14.318 16.257 30.800 12.000
+ 13.303 14.967 25.000 21.667 16.783 18.880 0.000 14.967
+ 7.560 8.000 27.500 20.000 10.739 12.193 23.100 9.000
+ 9.978 11.225 18.750 16.250 12.588 14.160 0.000 11.225</verb>
+<verb>
+ATI 18811-1 ¤È ATI 18811-2 ¥¯¥í¥Ã¥¯¥¸¥§¥Í¥ì¡¼¥¿:
+
+ Clocks 135.000 32.000 110.000 80.000 100.000 126.000 92.400 36.000
+ 39.910 44.900 75.000 65.000 50.350 56.640 0.000 44.900
+ 67.500 16.000 55.000 40.000 50.000 63.000 46.200 18.000
+ 19.955 22.450 37.500 32.500 25.175 28.320 0.000 22.450
+ 45.000 10.667 36.667 26.667 33.333 42.000 30.800 12.000
+ 13.303 14.967 25.000 21.667 16.783 18.880 0.000 14.967
+ 33.750 8.000 27.500 20.000 25.000 31.500 23.100 9.000
+ 9.978 11.225 18.750 16.250 12.588 14.160 0.000 11.225</verb>
+Mach32 ¤È Mach64 ¤ò»ý¤Ã¤Æ¤¤¤ë¿Í¤ÏºÇ½é¤Î 32 ¸Ä¤Î¼þÇÈ¿ô¤À¤±¤ò»ØÄꤷ¤Æ¤¯
+¤À¤µ¤¤¡£<p>
+<!--
++The oldest Mach64 adapters use one of the clock generators described above.
++The possibilities for Mach64 adapters also include programmable clock
++generators.
++At bootup, video BIOS initialization programmes an initial set of frequencies.
++Two of these are reserved to allow the setting of modes that do not use a
++frequency from this initial set.
++One of these reserved slots is used by the BIOS mode set routine, the other by
++the particular driver used (MS-Windows, AutoCAD, X, etc.).
++The clock numbers reserved in this way are dependent on the particular clock
++generator used on the adapter.<p>
++If the driver does not support the adapter's clock generator, it will try to
++match the clocks to one of the following specifications. This matching will
++occur whether or not the user specifies the clocks in XF86Config.
++<verb>
++BIOS setting 1:
++
++ Clocks 0.000 110.000 126.000 135.000 50.350 56.640 63.000 72.000
++ 0.000 80.000 75.000 65.000 40.000 44.900 49.500 50.000
++ 0.000 55.000 63.000 67.500 25.180 28.320 31.500 36.000
+-->
+ºÇ¤â¸Å¤¤ Mach64 ¥¢¥À¥×¥¿¤Ï¾åµ­¤Î¥¯¥í¥Ã¥¯¥¸¥§¥Í¥ì¡¼¥¿¤ÎÆâ¤Î°ì¤Ä¤ò»È¤Ã¤Æ¤¤
+¤Þ¤¹¡£¤Þ¤¿¡¢Mach64 ¥¢¥À¥×¥¿¤Ï¥×¥í¥°¥é¥Þ¥Ö¥ë¥¯¥í¥Ã¥¯¥¸¥§¥Í¥ì¡¼¥¿¤ò»È¤Ã¤Æ
+¤¤¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£
+¥Ö¡¼¥È»þ¤Ë¡¢¥Ó¥Ç¥ª BIOS ¤Î½é´ü²½¤Ï¼þÇÈ¿ô¤ÎºÇ½é¤ÎÀßÄêÃͤòÁȤ߹þ¤ß¤Þ¤¹¡£
+¥â¡¼¥É¤òÀßÄꤹ¤ë£²¤Ä¤Î¼þÇÈ¿ô¤Ï¤³¤ÎºÇ½é¤ÎÀßÄêÃͤǻȤï¤Ê¤¤¤è¤¦¤ËͽÌó¤·
+¤Æ¤¢¤ê¤Þ¤¹¡£Í½Ìó¤·¤¿Æâ¤Î°ì¤Ä¤Ï BIOS ¥â¡¼¥ÉÀßÄê¤Ç»ÈÍѤ·¡¢»Ä¤ê¤ÏÆÃÄê¤Î
+(MS-Windows, AutoCAD, X, Åù) ¥É¥é¥¤¥Ð¤¬»ÈÍѤ·¤Þ¤¹¡£
+¤³¤ÎÊýË¡¤ÇͽÌ󤷤Ƥ¤¤ë¥¯¥í¥Ã¥¯¤Î¿ôÃͤϥ¢¥À¥×¥¿¤Ç»È¤¦ÆÃÄê¤Î¥¯¥í¥Ã¥¯
+¥¸¥§¥Í¥ì¡¼¥¿¤Ë°Í¸¤·¤Þ¤¹¡£<p>
+¥É¥é¥¤¥Ð¤¬¥¢¥À¥×¥¿¤Î¥¯¥í¥Ã¥¯¥¸¥§¥Í¥ì¡¼¥¿¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤¾ì¹ç¡¢¼¡¤Î
+ÀßÄêÃͤÎÃæ¤«¤éŬ¹ç¤¹¤ë¥¯¥í¥Ã¥¯¤òÁª¤ó¤Ç¤¯¤À¤µ¤¤¡£¤³¤ÎŬ¹çºî¶È¤Ï
+XF86Config ¥Õ¥¡¥¤¥ë¤Ë¥¯¥í¥Ã¥¯¤òÀßÄꤷ¤Æ¤â¤·¤Ê¤¯¤Æ¤âȯÀ¸¤·¤Þ¤¹¡£
+<verb>
+BIOS ¤ÎÀßÄê 1:
+
+ Clocks 0.000 110.000 126.000 135.000 50.350 56.640 63.000 72.000
+ 0.000 80.000 75.000 65.000 40.000 44.900 49.500 50.000
+ 0.000 55.000 63.000 67.500 25.180 28.320 31.500 36.000
+ 0.000 40.000 37.500 32.500 20.000 22.450 24.750 25.000</verb>
+<!--
+<verb>
+BIOS setting 2:
+
+ Clocks 0.000 110.000 126.000 135.000 25.180 28.320 31.500 36.000
+ 0.000 80.000 75.000 65.000 40.000 44.900 49.500 50.000
+ 0.000 55.000 63.000 67.500 12.590 14.160 15.750 18.000
+ 0.000 40.000 37.500 32.500 20.000 22.450 24.750 25.000</verb>
+<verb>
+BIOS setting 3:
+
+ Clocks 0.000 0.000 0.000 0.000 25.180 28.320 0.000 0.000
+ 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
+ 0.000 0.000 0.000 0.000 12.590 14.160 0.000 0.000
+ 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000</verb>
+If the driver matches the clocks to the third setting above, functionality will
+be *extremely* limited (assuming the driver works at all).<p>
+Other clock generators that have been used on ATI adapters (which can all be
+said to be clones of one of the above) might generate non-zero frequencies for
+those that are zero above, or vice-versa.<p>
+The order of the clocks *is* very important, although the driver will reorder
+the clocks if it deems it appropriate to do so.
+-->
+<verb>
+BIOS ¤ÎÀßÄê 2:
+
+ Clocks 0.000 110.000 126.000 135.000 25.180 28.320 31.500 36.000
+ 0.000 80.000 75.000 65.000 40.000 44.900 49.500 50.000
+ 0.000 55.000 63.000 67.500 12.590 14.160 15.750 18.000
+ 0.000 40.000 37.500 32.500 20.000 22.450 24.750 25.000</verb>
+<verb>
+BIOS ¤ÎÀßÄê 3:
+
+ Clocks 0.000 0.000 0.000 0.000 25.180 28.320 0.000 0.000
+ 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
+ 0.000 0.000 0.000 0.000 12.590 14.160 0.000 0.000
+ 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000</verb>
+¥É¥é¥¤¥Ð¤¬¾å¤Î£³ÈÖÌܤÎÀßÄê¤È°ìÃפ·¤¿¾ì¹ç¤Ï(¥É¥é¥¤¥Ð¤¬´°Á´¤Ëưºî¤¹¤ë¤Ë¤Ï)
+µ¡Ç½Åª¤Ë *¤È¤Æ¤â* ¸ÂÄꤵ¤ì¤Þ¤¹¡£
+ATI ¥¢¥À¥×¥¿¡Ê¤È¤½¤Î¥½¥Ã¥¯¥ê¤µ¤óÁ´¤Æ¡Ë¤ËÅëºÜ¤·¤Æ¤¤¤ë¤½¤Î¾¤Î¥¯¥í¥Ã¥¯¥¸¥§
+¥Í¥ì¡¼¥¿¤Ï¾åµ­¤Ç¥¼¥í¤Ë¤Ê¤Ã¤Æ¤¤¤ëÉôʬ¤¬¥¼¥í¤Ç¤Ê¤¤Ãͤˤʤë¡ÊËô¤Ï¤½¤ÎµÕ¡Ë
+¤Ç¤·¤ç¤¦¡£<p>
+¤³¤Î¥¯¥í¥Ã¥¯¤Î½çÈÖ¤ÏÈó¾ï¤Ë *½ÅÍ×* ¤Ç¤¹¤¬¡¢¥É¥é¥¤¥Ð¤¬Åª³Î¤Ë¤Ê¤ë¤è¤¦¤Ë
+¥¯¥í¥Ã¥¯¤Î½ç½ø¤òÊѤ¨¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£
+Mach32 ¤È Mach64 ¤ò½êÍ­¤·¤Æ¤¤¤ë¿Í¤Ï¥¯¥í¥Ã¥¯¤Î½çÈÖ¤¬¥¢¥¯¥»¥é¥ì¡¼¥¿¥µ¡¼
+¥ÐÍѤ˻Ȥ¦¥¯¥í¥Ã¥¯¤Î½çÈ֤Ȥϰۤʤ뤳¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£<p>
+<!--
++If the driver detects a supported programmable clock generator, it will ignore
++any XF86Config clock specification and programme the generator as needed by the
++modes to be used during the X session.<p>
++A clock probe, done with the command "X -probeonly", will help you decide which
++of the above to use for your particular adapter.
+-->
+¥É¥é¥¤¥Ð¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¥×¥í¥°¥é¥Þ¥Ö¥ë¥¯¥í¥Ã¥¯¥¸¥§¥Í¥ì¡¼¥¿¤òõÃΤ·¤¿¤é¡¢
+XF86Config ¤Î¥¯¥í¥Ã¥¯ÀßÄê¤ò̵»ë¤·¤Æ X ¥»¥Ã¥·¥ç¥ó¤Ç»ÈÍѤ¹¤ë¥â¡¼¥É¤ò
+ÁȤ߹þ¤ß¤Þ¤¹¡£<p>
+"X -probeonly" ¥³¥Þ¥ó¥É¤Çõºº¤·¤¿¥¯¥í¥Ã¥¯¤Ï¤½¤Î¥¢¥À¥×¥¿¤¬¾åµ­¤Î¥¢¥À¥×¥¿¤Î
+¤¦¤Á¤Î¤É¤ì¤Ç¤¢¤ë¤«¤òȽÄꤹ¤ë½õ¤±¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£
+¥µ¡¼¥Ð¤¬°ì´Ó¤·¤ÆÃΤé¤Ê¤¤¥¯¥í¥Ã¥¯¥¸¥§¥Í¥ì¡¼¥¿¤Ç¤¢¤ë¤ÈÃΤ餻¤Æ¤¯¤ë¾ì¹ç
+¤Ï¡¢É¸½à¥¨¥é¡¼½ÐÎÏ¤ÎÆâÍÆ¤òÅŻҥ᡼¥ë¤ÇÁ÷ÉÕ¤·¤Æ¤¯¤À¤µ¤¤¡£<p>
+¥â¡¼¥É¤Ï XFree86 ¤Îʸ½ñ¥Ç¥£¥ì¥¯¥È¥ê¤ËÆþ¤Ã¤Æ¤¤¤ë¾ðÊ󤫤é°ú¤­½Ð¤·¤Æ¤­¤Þ
+¤·¤ç¤¦¡£
+XF86Config ¤Î³ºÅö¤¹¤ë¥¹¥¯¥ê¡¼¥ó (screen) ¥»¥¯¥·¥ç¥ó¤Î¥Ç¥£¥¹¥×¥ì¥¤
+(display) ¥µ¥Ö¥»¥¯¥·¥ç¥ó¤Ë "modes" ¹Ô¤ò»ØÄꤷ¤Ê¤¤¾ì¹ç¤Ë¥É¥é¥¤¥Ð¡¼¤Ïɸ
+½àÃͤΥ⡼¥É¤òÀ¸À®¤·¡¢»ÈÍѤ·¤è¤¦¤È¤·¤Þ¤¹¡£
+ɸ½à¥â¡¼¥É¤ÎÄ´À°ÍÑ¿ôÃͤϻö¼Â¾å¥µ¡¼¥Ð¤¬µ¯Æ°¤·¤¿¥â¡¼¥É¡ÊÄÌ¾ï¥Æ¥­¥¹¥È
+¥â¡¼¥É¡Ë¤ÎÃͤ«¤é°ú¤­½Ð¤·¤Æ¤­¤Þ¤¹¡£<p>
+<sect> ¥É¥é¥¤¥Ð¤ÎÍúÎò¤Ï¡©<p>
+¥É¥é¥¤¥Ð¤Î´°Á´¤ÊÍúÎò¤Ï¤¢¤Þ¤êÄ꤫¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+¼¡¤Îµ­½Ò¤ÏÉÔ´°Á´¤«¤ÄÉÔÀµ³Î¤«¤â¤·¤ì¤Þ¤»¤ó¡£<p>
+<bf>Per Lindqvist</bf> (<it>pgd@compuram.bbt.se</it>) »á¤¬ºÇ½é¤Ë ATI
+VGA Wonder XL ¥É¥é¥¤¥Ð¤ò½é´ü·¿¤Î ATI ¥«¡¼¥ÉÍÑ¤Ë X386 1.1a ¾å¤Ë°Ü¿¢¤·¤¿
+¤é¤·¤¤¤Ç¤¹¡£
+¤³¤ÎºÇ½é¤Î¥É¥é¥¤¥Ð¤Ï <bf>Roell</bf> »á¤Ë¤è¤Ã¤Æ½ñ¤«¤ì¤¿ ATI ¤Ç¤Ï
+ưºî¤·¤Ê¤¤¥É¥é¥¤¥Ð¤ò¼ÂºÝ¤Ë´ð¤Ë¤·¤Æ¤¤¤Þ¤¹¡£
+¤½¤·¤Æ <bf>Doug Evans</bf> (<it>dje@cygnus.com</it>) »á¤¬ ¤½¤Î¾¤ÎÁ´¤Æ
+¤Î ATI ¥«¡¼¥É¤Ç¥É¥é¥¤¥Ð¤¬Æ°ºî¤¹¤ë¤«¤É¤¦¤«³Îǧ¤·¤Ê¤¬¤é¡¢ATI VGA Wonder
+XL ¥É¥é¥¤¥Ð¤ò°Ü¿¢¤·¤Þ¤·¤¿¡£<p>
+<bf>Rik Faith</bf> (<it>faith@cs.unc.edu</it>) »á¤Ï Doug Evans »á¤Î
+X11R4 ÍѤΥɥ饤¥Ð¤ò 1992 ǯ¡¢²Æ¤Ë¼ê¤Ë¤¤¤ì¡¢X11R5 ¤Î°ìÉô¤Î X386 ¤Ë¥×¥í
+¥°¥é¥à¤ò°Ü¿¢¤·¤Þ¤·¤¿¡£
+¤³¤ì¤ò XFree86 ¤Î°ìÉô¤Ø°ú¤­·Ñ¤®¤Þ¤·¤¿¡£<p>
+<!--
++I (<bf>Marc Aurele La France</bf>) took the driver over in the fall of 1993
++after Rik got rid of his VGA Wonder card.<p>
++<sect> Miscellaneous notes<p>
++Dot clocks greater than 80MHz cannot be used on most adapters as a way still
++needs to be discovered to make the VGA Wonder controller do pixel
++multiplexing.<p>
++Support for more than 8bpp colour depth is pending proper RAMDAC handling and
++banked framebuffer code for >8bpp.<p>
++Video memory banking does not work in the 16-colour and monochrome servers on
++V3, V4 and V5 adapters.<p>
++Video memory corruption can still occur during mode switches on V3, V4 and V5
++adapters.
++Symptoms of this problem include garbled fonts on return to text mode, and
++various effects (snow, dashed lines, etc) on initial entry into a graphics
++mode.
++In the first case, the workaround is to use some other means of restoring the
++text font.
++On Linux, this can be done with the kbd or svgalib packages.
++In the second case, xrefresh will usually cleanup the image.<p>
++Interlaced modes do not work in the monochrome server on 28800-x adapters when
++using a virtual resolution wider than 1024 pixels.<p>
++Some (particularly low resolution) interlaced modes do not work on 264xT
++adapters.<p>
++Support for virtual resolutions using more than 1MB of video memory is still
++incomplete.
++Specifically, such support works on Mach32 adapters, and on 264xT adapters,
++but not on any other Mach64 adapters.<p>
++There is some controversy over whether or not clocks higher than 135MHz should
++be allowed on 264xT adapters.
++For now, clocks will be limited to 135MHz by default.
++This limit can only be increased (up to a driver-calculated absolute maximum)
++through the DACSpeed option in XF86Config.
++Be aware however that doing this is untested and might damage the adapter.<p>
++Future development plans include addressing the above problems and using
++accelerated functionality.<p>
+-->
+Ãø¼Ô(<bf>Marc La France</bf>) ¤Ï Rik »á¤Î VGA Wander ¥«¡¼¥ÉÍѤΥɥ饤
+¥Ð¤ò 1993 ǯ½©¤Ë°ú¤­·Ñ¤®¤Þ¤·¤¿¡£<p>
+<sect> ¼ï¡¹¤ÎÃí°Õ»ö¹à<p>
+ËØ¤É¤Î¥³¥ó¥È¥í¡¼¥é¤Ç 80MHz °Ê¾å¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ò»È¤¦¤Ë¤Ï VGA Wonder
+¥³¥ó¥È¥í¡¼¥é¤¬¥Ô¥¯¥»¥ë¿½Å¤ò¹Ô¤¦¤è¤¦¤Ë¤·¤Ê¤±¤ì¤Ð½ÐÍè¤Þ¤»¤ó¡£<p>
+8bpp ¿§°Ê¾å¤Î¿¼¤µ¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤Ë¤Ï¸½¾õ¤Î RAMDAC ¤Î»È¤¤Êý¤ò»ß¤á¤Æ¡¢¥Ð¥ó¥¯²½
+¤·¤¿¥Õ¥ì¡¼¥à¥Ð¥Ã¥Õ¥¡¥×¥í¥°¥é¥à¤¬ 8bpp °Ê¾å¤ò¥µ¥Ý¡¼¥È¤·¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£<p>
+V3, V4 ¤È V5 ¥¢¥À¥×¥¿¤Î¥Ó¥Ç¥ª¥á¥â¥ê¤Î¥Ð¥ó¥¯²½¤Ï 16 ¿§¤ÈÇò¹õ¥µ¡¼¥Ð¤Çưºî
+¤·¤Þ¤»¤ó¡£<p>
+V3, V4 ¤È V5 ¥¢¥À¥×¥¿¤Î¥â¡¼¥É´Ö¤ÎÀÚ¤êÂØ¤¨¤Ë¤è¤Ã¤Æ¥Ó¥Ç¥ª¥á¥â¥ê¤ÎÂÄÍ̤¤À
+µ¯¤­¤Þ¤¹¡£<p>
+¤³¤ÎÂÄÍ¾Ý¤Ï¥Æ¥­¥¹¥È¥â¡¼¥É¤ËÌá¤Ã¤¿¤È¤­¤Î·ç¤±¤¿¥Õ¥©¥ó¥È¤È¥°¥é¥Õ¥£¥Ã¥¯
+¥â¡¼¥É¤ËºÇ½é¤ËÆþ¤Ã¤¿¤È¤­¤ÎÍÍ¡¹¤ÊÈ¿±þ(À㤬¹ß¤Ã¤¿¤ê¡¢Ã»¤¤Àþ¤¬½Ð¤¿¤êÅù)
+¤È¤·¤Æ¸½¤ï¤ì¤Þ¤¹¡£
+ºÇ½é¤ÎÌäÂê¤Î¾ì¹ç¤Ï¡¢Âкö¤Ï¾¤ÎÊýË¡¤Ç¥Æ¥­¥¹¥È¥Õ¥©¥ó¥È¤ò²óÉü¤¹¤ë¤³¤È¤Ç¤¹¡£
+Linux ¤Ç¤Ï kbd ¤Þ¤¿¤Ï svgalib ¥Ñ¥Ã¥±¡¼¥¸¤È°ì½ï¤Ë²ò·è¤·¤Þ¤·¤¿¡£
+ÆóÈÖÌܤÎÌäÂê¤Î¾ì¹ç¤Ï¡¢°ìÈÌ¤Ë xrefresh ¤¬²èÁü¤ò¤­¤ì¤¤¤Ë¤¹¤ë¤Ç¤·¤ç¤¦¡£<p>
+1024 ¥Ô¥¯¥»¥ë¤è¤ê¹­¤¤²¾ÁÛ²èÌ̤β£Éý¤ò 28800-x ¥¢¥À¥×¥¿¾å¤ÎÇò¹õ¥µ¡¼¥Ð
+¤Ç¤Ï¥¤¥ó¥¿¡¼¥ì¡¼¥¹¥â¡¼¥É¤Ïưºî¤·¤Þ¤»¤ó¡£<p>
+264xT ¥¢¥À¥×¥¿¾å¤Ç¤Ï¤¤¤¯¤Ä¤«¤Î(ÆÃ¤ËÄã²òÁüÅÙ) ¥¤¥ó¥¿¡¼¥ì¡¼¥¹¥â¡¼¥É¤Ï
+ưºî¤·¤Þ¤»¤ó¡£<p>
+1M ¥Ð¥¤¥È°Ê¾å¤Î¥Ó¥Ç¥ª¥á¥â¥ê¤ò»ÈÍѤ·¤¿²¾ÁÛ²òÁüÅÙ¤Ï̤¤À´°àú¤Ç¤Ï¤¢¤ê¤Þ¤»
+¤ó¤¬¡¢¤Û¤«¤Î Mach64 ¥¢¥À¥×¥¿¤Ç¤Ï¤½¤¦¤Ç¤Ï¤Ê¤¤¤È¤¤¤¦¤³¤È¤Ç¤¹¡£<p>
+264xT ¥¢¥À¥×¥¿¤Ç 135MHz ¤è¤ê¹â¤¤¥¯¥í¥Ã¥¯¤¬»È¤¨¤ë¤«Èݤ«¤Ë¤Ä¤¤¤Æ
+¤¤¤¯¤Ä¤«µÄÏÀ¤¬¤¢¤ê¤Þ¤¹¡£
+¸½ºß¤Ç¤Ï¡¢É¸½à¤Ç 135MHz ¤¬¾å¸Â¤Ç¤·¤ç¤¦¡£
+¤³¤Î¾å¸Â¤Ï XF86Config ¤Ë DACSpeed ¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤ë¤³¤È¤Ë¤è¤ê(¥É¥é¥¤¥Ð
+¤¬·×»»½ÐÍè¤ëÀäÂÐŪ¤ÊºÇÂçÃͰʾå) Áý²Ã¤µ¤»¤ë¤³¤È¤À¤±¤¬½ÐÍè¤Þ¤¹¡£
+¤³¤ì¤Ï¥Æ¥¹¥È¤·¤Æ¤¤¤Ê¤¤¤³¤È¤È¥¢¥À¥×¥¿¤Ë»½ý¤òÍ¿¤¨¤ë¤«¤â¤·¤ì¤Ê¤¤¤³¤È¤ò
+°Õ¼±¤·¤Æ¤¯¤À¤µ¤¤¡£<p>
+¾­Íè¤Î³«È¯·×²è¤Ï¾åµ­¤ÎÌäÂê¤Ë¸þ¤±¤ë¤³¤È¤È¥¢¥¯¥»¥é¥ì¡¼¥¿µ¡Ç½¤ò»È¤¦¤³¤È
+¤Ç¤¹¡£<p>
+¥Ð¥°¥ì¥Ý¡¼¥È¤ä¥³¥á¥ó¥È¤Ê¤É¤ò
+<bf>Marc Aurele La France</bf>, <url url="mailto:tsi@ualberta.ca"
+name="&lt;<it>tsi@ualberta.ca</it>&gt;">¤Þ¤ÇÅŻҥ᡼¥ë¤ò²¼¤µ¤¤¡£
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/ati.sgml,v 3.2 1997/01/26 04:34:28 dawes Exp $
+</verb>
+<hrule>
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ï xc/programs/Xserver/hw/xfree86/doc/sgml/ati.sgml,v 3.12 1996/05/10 06:58:31 ¤ò¡¢²¬ËÜ °ì¹¬
+( Kazuyuki Okamoto <url url="mailto:ikko-@pacific.rim.or.jp"
+name="&lt;ikko-@pacific.rim.or.jp&gt;"> ) ¤¬ XFree86 3.2 ¤ò
+ÆüËܤǥ¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¿Í¸þ¤±¤ËÏÂÌõ¤·¤¿¤â¤Î¤Ç¤¹¡£¤³¤³¤¬¤ª¤«¤·¤¤¤È¤«¡¢
+¤³¤³¤Ï¤³¤¦¤·¤¿¤Û¤¦¤¬¤¤¤¤¤È¤¤¤Ã¤¿¤´°Õ¸«¤¬¤¢¤ê¤Þ¤·¤¿¤é¡¢ÅŻҥ᡼¥ë¤Ç
+¤ªÃΤ餻²¼¤µ¤¤¡£
+¸¶Ê¸¤ÎÃøºî¸¢¤Ï XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ÎÏÂÌõ¤ÎÃøºî¸¢¤Ï
+XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤È²¬ËÜ¡¡°ì¹¬¤Ë¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤ÎÏÂÌõ¤ÎÉÔ¶ñ¹ç¤Ï»ä
+¤Ë¡¢ÅŻҥ᡼¥ë¤ÇÁ÷¤Ã¤Æ²¼¤µ¤¤¡£
+<hrule>
+&lsqb;EOF&rsqb;
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/cirrus.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/cirrus.sgml
new file mode 100644
index 000000000..562ab08ad
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/cirrus.sgml
@@ -0,0 +1,1123 @@
+<!doctype linuxdoc system>
+
+<article>
+
+<!-- Title information -->
+<!-- ....1.........2.........3.........4.........5.........6...... -->
+<title> Cirrus ¥Á¥Ã¥×¥»¥Ã¥È¥æ¡¼¥¶¤Î¤¿¤á¤Î¾ðÊó
+<author> Harm Hanemaayer (<it>H.Hanemaayer@inter.nl.net</it>),
+ Randy Hendry (<it>randy@sgi.com</it>),
+ Corin Anderson (<it>corina@bdc.cirrus.com</it>)
+<date> 1996 ǯ 10 ·î 9 Æü
+<trans> ²¬ËÜ¡¡°ì¹¬ Kazuyuki Okamoto &lt;ikko-@pacific.rim.or.jp&gt;
+
+<!-- Table of contents -->
+<toc>
+
+<sect> ¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¥Á¥Ã¥×¥»¥Ã¥È <p>
+
+Cirrus ¤Î¥Á¥Ã¥×¥»¥Ã¥ÈÍѤˤϡ¢&dquot;cirrus&dquot;¤È&dquot;cl64xx&dquot;¤È¸Æ¤Ð¤ì¤ë£²¤Ä¤Î°Û¤Ê
+¤ë SVGA ¥µ¡¼¥Ð¤¬¤¢¤ê¤Þ¤¹¡£
+&dquot;cirrus&dquot; ¥É¥é¥¤¥Ð¤Ï 256 ¿§¤Î¡Ê¥¢¥¯¥»¥é¥ì¡¼¥¿ÉÕ¤­¡ËSVGA ¥µ¡¼¥Ð¤È
+¡Ê¥¢¥¯¥»¥é¥ì¡¼¥¿Ìµ¤·¡ËÇò¹õ¥µ¡¼¥Ð¤ÇÍѤ¤¤é¤ì¤Æ¤¤¤Þ¤¹¡£SVGA ¥µ¡¼¥Ð¤Ï
+16, 24 ¤È 32 ¥Ô¥¯¥»¥ëÅö¤ê¥Ó¥Ã¥È¿ô ¤ò¥µ¥Ý¡¼¥È¤·¡¢¤³¤Î¹½À®¤Ç
+Å·Á³¿§ (truecolor) ¥â¡¼¥É¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£
+&dquot;cl64xx&dquot; ¥É¥é¥¤¥Ð¤Ï 256 ¿§ SVGA, 16 ¿§ ¤È Çò¹õ ¥µ¡¼¥Ð¤ÇÍѤ¤¤é¤ì¤Æ¤¤
+¤Þ¤¹¡£¤É¤Á¤é¤¬°ÂÄꤷ¤Æ¤¤¤ë¤È¤«¤Ï¤³¤³¤Ç¤ÏµÄÏÀ¤·¤Þ¤»¤ó¤¬¡¢¤³¤Îʸ½ñ¤Ç¤Ï
+&dquot;cirrus&dquot; ¥É¥é¥¤¥Ð¤Ë¤Ä¤¤¤Æ¼ç¤Ë¸ÀµÚ¤·¤Þ¤¹¡£
+¼¡¤ÎCirrus Logic ¤Î¥Á¥Ã¥×¥»¥Ã¥È¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£:
+<descrip>
+<tag>CL-GD5420</tag>
+ ISA SVGA ¥Á¥Ã¥×¥»¥Ã¥È, 1M¥Ð¥¤¥È; ºÇÂç¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ï 45 MHz (256
+ ¿§¥µ¡¼¥Ð)¡£
+ ³ÈÄ¥½ñ¤­¹þ¤ß¥â¡¼¥É¤Ë¤è¤ë¥¢¥¯¥»¥é¥ì¡¼¥¿µ¡Ç½¡Ê¤³¤Î¥µ¡¼¥Ð¤Ç¤Ï¥¹¥¯
+ ¥í¡¼¥ë¤È¥Ù¥¿Åɤê¤Ä¤Ö¤·¤ËÍѤ¤¤Æ¤¤¤ë¡Ë¡£¤³¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ï 256 ¿§¤Î
+ 1024x768 ¥Î¥ó¥¤¥ó¥¿¡¼¥ì¡¼¥¹ ¤Ï¥µ¥Ý¡¼¥È<em>¤·¤Þ¤»¤ó</em>¡£
+<tag>CL-GD5422</tag>
+ 5420¤Î²þÎÉÈÇ (32 ¥Ó¥Ã¥ÈÆâ¢¥á¥â¥ê¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹)¡£
+ ºÇÂç¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ï 80 MHz¡£
+<tag>CL-GD6205/6215/6225/6235</tag>
+ 5420 ¤Ë¤Û¤Ü¸ß´¹À­¤Î¤¢¤ë¥é¥Ã¥×¥È¥Ã¥×ÍÑ¥Á¥Ã¥×¥»¥Ã¥È¡£¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ï
+ 25 MHz ¤Î¤ß¥µ¥Ý¡¼¥È¤¹¤ë¡Ê³°Éô¥Ç¥£¥¹¥×¥ì¥¤¤Ï¤½¤ì°Ê¾å²Äǽ¡Ë¡£
+ &dquot;<tt>noaccel</tt>&dquot; ¥ª¥×¥·¥ç¥ó¤¬É¬ÍפʤΤÇÃí°Õ¤Î»ö¡£
+<tag>CL-GD6420/6440</tag>
+ ¤³¤ì¤é¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ï 542x ¥·¥ê¡¼¥º¤È¤Ï¸ß´¹À­¤Ï¤¢¤ê¤Þ¤»¤ó¤¬¡¢
+ &dquot;cl64xx&dquot; ¥É¥é¥¤¥Ð¤Ç¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£¤³¤Î¥Á¥Ã¥×¥»¥Ã¥È¤ÏºÇ¶á¤Î¥é¥Ã¥×
+ ¥È¥Ã¥×¤ËÅëºÜ¤µ¤ì¤Æ¤ª¤ê¡¢ÀΤΠCirrus ¥Á¥Ã¥×¥»¥Ã¥È(5410/AVGA2)¤ÈƱÍÍ
+ ¤ËÆâ¢¤·¤Æ¤¤¤Þ¤¹¡£¤³¤Î¥É¥é¥¤¥Ð¤Ï¾¤Î 64xx ¥Á¥Ã¥×¥»¥Ã¥È¤Ç¤â²ÔƯ¤·¤Æ
+ ¤¤¤Þ¤¹¡£¹½À®¾å¤Î¼±ÊÌ»Ò¤Ï &dquot;<tt>cl6420</tt>&dquot; ¤È <tt>&dquot;cl6440&dquot;</tt> ¤Ç
+ ¤¹¡£¤³¤Î¥É¥é¥¤¥Ð¤Ë¤Ä¤¤¤Æ¤Ï <ref id="cl64xx" name="cl64xx ¥É¥é¥¤¥Ð">
+ ¤ÎÀá¤Ç¾ÜºÙ¤Ë½Ò¤Ù¤Þ¤¹¡£
+<tag>CL-GD5424</tag>
+ ´ðËÜŪ¤Ë 5422 ¤Î VLB ÈǤǤ¹¤¬¡¢¤¤¤¯¤Ä¤«¤ÎÅÀ¤Ç 5426 ¤Ë»÷¤Æ¤¤¤Þ¤¹¡£
+<tag>CL-GD5426</tag>
+ ISA ¥Ð¥¹¤È VLB ξÊý¤Î 2M ¥Ð¥¤¥È°Ê¾å¤Î¥á¥â¥ê¤òÅëºÜ¤·¤¿¤â¤Î¤ò¥µ¥Ý¡¼
+ ¥È¤·¤Þ¤¹¡£¤è¤ê¤è¤¤¥¢¥¯¥»¥é¥ì¡¼¥¿¤òµá¤á¤ë¤Ê¤é BitBLT ¥¨¥ó¥¸¥ó¤òÅë
+ ºÜ¤·¤Æ¤¯¤À¤µ¤¤(BitBLT¤Ï²èÁüžÁ÷¤È¥Æ¥­¥¹¥Èɽ¼¨¤ËÍ­¸ú)¡£¥É¥Ã¥È¥¯¥í¥Ã
+ ¥¯¤Î¾å¸Â¤Ï 85 MHz¡£
+<tag>CL-GD5428</tag>
+ 5426 ¤Î²þÎÉÈÇ¡£
+<tag>CL-GD5429</tag>
+ 5428 ¤Î²þÎÉÈǤǡ¢¤è¤ê¹â¤¤ MCLK ¤ò¸ø¼°¤Ë¥µ¥Ý¡¼¥È¤·¡¢¥á¥â¥ê¥Þ¥Ã¥×¥É
+ I/O ¤òÅëºÜ¤·¤Æ¤¤¤Þ¤¹¡£
+<tag>CL-GD5430</tag>
+ 5429 ¤Ë»÷¤Æ¤¤¤Þ¤¹¤¬¡¢´ð¤Ï 543x (32 ¥Ó¥Ã¥È¥Û¥¹¥È¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹)
+ ¤Ç¤¹¡£64 ¥Ó¥Ã¥È¥á¥â¥ê¥â¡¼¥É¤Ï»ý¤Ã¤Æ¤¤¤Þ¤»¤ó¡£
+<tag>CL-GD5434</tag>
+ 64 ¥Ó¥Ã¥ÈÆâ¢¥á¥â¥ê¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤ò»ý¤Ã¤¿ `Alpine'
+ ¤Î·ÏÎó¤Î¥Á¥Ã¥×¤Ç¤¹¡£
+<!--
+ `Alpine' family chip with 64-bit internal memory interface.
+ The chip
+-->
+ ¤³¤Î¥Á¥Ã¥×¤Ï 2M ¥Ð¥¤¥È¤Î¥á¥â¥ê¤òÅëºÜ¤·¤¿¤È¤­ 64 ¥Ó¥Ã¥È¥â¡¼¥É¤Î
+ ¤ß¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£1M ¥Ð¥¤¥È¥á¥â¥ê¤Î¤ß¤Î¤Î¥«¡¼¥É¤Ç¤Ï¸·¤·¤¤¸Â³¦
+ ¤¬¤¢¤ê¤Þ¤¹¡£110 MHz °Ê¾å¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹
+ ¡Ê¿·¤·¤¤¥Á¥Ã¥×¥»¥Ã¥È¤Ï 135 MHz ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡Ë¡£
+<tag>CL-GD5436</tag>
+<!-- ¹âÅ٤˺ÇŬ²½¤·¤¿5434¡£´ðËÜŪ¤Ë 5434 ¤È¤·¤Æ°·¤¨¤Þ¤¹¤¬¡¢¥Æ¥¹¥È¤·
+ ¤Æ¤Þ¤»¤ó¡£-->
+ ¹âÅ٤˺ÇŬ²½¤·¤¿ 5434.
+<!--
+<tag>CL-GD5440</tag>
+ Similar to the CL-GD5430, and detected as such.
+<tag>CL-GD5446</tag>
+ Another member of the Alpine family of 2D accelerators; similar
+ to the CL-GD5436.
+<tag>CL-GD546X</tag>
+ The Laguna VisualMedia family of 2D Accelerators. These chips
+ use Rambus RDRAM memory. The '62 is a 64-bit 2D
+ accelerator, including a BitBlit engine, video windows (not currently
+ used by the server), and 64x64 HW cursor. Mono modes have not been
+ tested. The CL-GD5464 is the next chip in the Laguna family, and
+ is supported and has been tested.
+<tag>CL-GD7541/7542/7543/7548</tag>
+ Laptop chipsets more or less compatible with the 5428/3x.
+ When the LCD is on, the maximum dot clock supported is 44 MHz.
+ Support for these chips seems to be broken in this release.
+ Reports are welcomed.
+-->
+<tag>CL-GD5440</tag>
+ CL-GD5430 ¤Ë»÷¤Æ¤¤¤Þ¤¹¤Î¤Ç¤½¤Î¤è¤¦¤ËõÃΤµ¤ì¤Þ¤¹¡£
+<tag>CL-GD5446</tag>
+ £²¼¡¸µ¥¢¥¯¥»¥é¥ì¡¼¥¿¤Î Alpine ·ÏÎó¤ÎÆâ¤Î°ì¤Ä¤Ç¡¢CL-GD5436
+ ¤Ë»÷¤Æ¤¤¤Þ¤¹¡£
+<tag>CL-GD546X</tag>
+ £²¼¡¸µ¥¢¥¯¥»¥é¥ì¡¼¥¿¤Î Laguna VisualMedia ·ÏÎó¤Ç¤¹¡£¤³¤ì¤é
+ £³¤Ä¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ï Rambus RDRAM ¥á¥â¥ê¤ò»È¤Ã¤Æ¤¤¤Þ¤¹¡£
+ '62 ¤Ï 64 ¥Ó¥Ã¥È£²¼¡¸µ¥¢¥¯¥»¥é¥ì¡¼¥¿¤È BitBlit ¥¨¥ó¥¸¥ó¤È
+ ¥Ó¥Ç¥ª¥¦¥£¥ó¥É¥¦(¸½ºß¤Î¥µ¡¼¥Ð¤Ç¤Ï»ÈÍѤ·¤Æ¤¤¤Þ¤»¤ó) ¤È
+ ¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½¥ë¤òÆâ¢¤·¤Æ¤¤¤Þ¤¹¡£Çò¹õ¥â¡¼¥É¤Ï¥Æ¥¹¥È¤·
+ ¤Æ¤¤¤Þ¤»¤ó¡£CL-GD5464 ¤Ï Laguna ·ÏÎó¤Î¼¡À¤Âå¤Î¥Á¥Ã¥×¤Ç¡¢
+ ¥µ¥Ý¡¼¥È¤·¤Þ¤·¤¿¤¬¥Æ¥¹¥È¤·¤Æ¤¤¤Þ¤»¤ó¡£
+<tag>CL-GD7541/7542/7543/7548</tag>
+ 5428/3x ¤ÈÂçÂθߴ¹À­¤Î¤¢¤ë¥é¥Ã¥×¥È¥Ã¥×ÍѤΥÁ¥Ã¥×¥»¥Ã¥È¤Ç
+ ¤¹¡£LCD ¤¬¥ª¥ó¤Î»þ¤ÏºÇÂç¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ï 44MHz ¤Ç¤¹¡£
+ ¤³¤ÎÈǤǤϤ³¤ì¤é¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ï¤ª¤«¤·¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£
+ Êó¹ð¤ò¤ªÂÔ¤Á¤·¤Æ¤¤¤Þ¤¹¡£
+</descrip>
+
+³Æ¡¹¤Î¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¿¼¤µËè¤ËºÇÂç¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ò°ìÍ÷¤Ë¤·¤Þ¤¹¡£:
+
+<quote><verb>
+ mono 8 bpp (256c) 16 bpp 24 bpp 32 bpp
+CL-GD62x5 45 MHz 45 MHz
+CL-GD5420 80 MHz 45 MHz (1)
+CL-GD542x/512K 80 MHz 45 MHz
+CL-GD5422/24 80 MHz 80 MHz 40 MHz 27 MHz
+CL-GD5426/28 85 MHz 85 MHz 45 MHz (2) 28 MHz
+CL-GD5429 85 MHz 85 MHz 50 MHz 28 MHz
+CL-GD5430 85 MHz 85 MHz 45 MHz (2) 28 MHz
+CL-GD5434/1Mb 85 MHz 85 MHz 42 MHz 28 MHz
+CL-GD5434/2Mb 85 MHz 110/135 MHz 85 MHz 28 MHz 45/50 MHz (2)
+CL-GD5436/1Mb 85 MHz 110 MHz (3) 60 MHz (3) 40 MHz (3)
+CL-GD5436/2Mb 85 MHz 135 MHz 85 MHz 85 MHz (3) 60 MHz (3)
+CL-GD5446/1Mb 85 MHz 110 MHz (3) 60 MHz (3) 40 MHz (3)
+CL-GD5446/2Mb 85 MHz 135 MHz 85 MHz 85 MHz (3) 60 MHz (3)
+CL-GD546X 170 MHz 170 Mhz 170 MHz 170 MHz 170 MHz
+CL-GD754x 80 MHz 80 MHz 40 MHz (4) (5)
+
+(1) 512K ¥á¥â¥ê¤Ç¤¹¡£
+(2) ¹â¤¤ MCLK ¤òÀßÄꤹ¤ë¤È 50 MHz¡£
+(3) ¥á¥â¥ê¥¯¥í¥Ã¥¯¤Ë°Í¸¤·¤Þ¤¹¡£
+(4) ¿ʬ¡¢¤¤¤¯¤Ä¤«¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Ë¤ÏÄ㤹¤®¤ë¤Ç¤·¤ç¤¦¡£
+(5) ¿ʬ¡¢Í­¸ú¤Ë¤·¤Æ¥Æ¥¹¥È¤ò¹Ô¤¨¤Ð¤³¤Î¿¼¤µ¤Ï¼ÂºÝ¤Ëưºî¤¹¤ë¤Ç¤·¤ç¤¦¡£
+</verb></quote>
+
+Âç¤Þ¤«¤Ë¸À¤Ã¤Æ ²¾ÁÛŪ/ʪÍýŪ¤Ê²èÌ̲òÁüÅ٤ϥӥǥª¥á¥â¥ê¤ÎÎ̤ΰ㤤¤ËÀ©Ìó
+¤µ¤ì¤Þ¤¹¡£
+
+<quote><verb>
+ mono 8 bpp 16 bpp 24 bpp 32 bpp
+256K 800x600 640x400
+512K 1152x900 800x600 640x400
+1024K 1600x1200 1152x900 800x600 680x510
+2048K 2304x1728 1600x1200 1152x900 960x720 800x600
+4096K 2304x1728 2272x1704 1600x1200 1360x1020 1152x900
+</verb>
+</quote>
+<!--
+For 546x chips, the virtual width may be any size. However, the
+screen <it>pitch</it> will be rounded up to the nearest value in the table
+below. Thus, each line on the screen will take more video memory than just
+what is displayed. To maximize video memory, then, choose the virtual
+desktop width from the table of pixel widths below:
+<quote><verb>
+8bpp: 640, 1024, 1280, 1664, 2048, 2560, 3328, 4096, 5120, 6656
+16bpp: 320, 512, 640, 832, 1024, 1280, 1664, 2048, 2560, 3328
+24bpp: 640, 1024, 1280, 1664, 2048, 2560, 3328, 4096, 5120, 6656
+32bpp: 160, 256, 320, 416, 512, 640, 832, 1024, 1280, 1664
+</verb></quote>
+
+For other Cirrus chips, it's advisable to have a virtual width that is a
+multiple of 32 if acceleration is used.
+-->
+546x ¥Á¥Ã¥×¤Ç¤Ï²¾ÁÛ²èÌ̤ÎÉý¤ÏǤ°Õ¤Ç¤¹¡£¤·¤«¤·¡¢²èÌ̤Î
+<it>¥Ô¥Ã¥Á(pitch)</it> ¤ò¼¡¤Îɽ¤ÎºÇ¤â¶á¤¤²Á¤ËÀÚ¤ê¾å¤²¤Þ¤·¤ç¤¦¡£
+½¾¤Ã¤Æ¡¢²èÌ̾å¤Î³Æ¡¹¤ÎÀþ¤Ï¥Ó¥Ç¥ª¥á¥â¥ê¤ò¤É¤ì¤¯¤é¤¤¾ÃÈñ¤¹¤ë¤«¤è¤ê¤âñ¤Ë
+ɽ¼¨¤·¤¿¤¤Ä¹¤µ¤Ë¤Ê¤ê¤Þ¤¹¡£¥Ó¥Ç¥ª¥á¥â¥ê¤òÌܰìÇջȤ¦¤Ë¤Ï¡¢¼¡¤Îɽ¤Î
+¥Ô¥¯¥»¥ë¿ô¤«¤é²¾Áۥǥ¹¥¯¥È¥Ã¥×¤ÎÉý¤òÁªÂò¤·¤Æ¤¯¤À¤µ¤¤¡£:
+<quote><verb>
+8bpp: 640, 1024, 1280, 1664, 2048, 2560, 3328, 4096, 5120, 6656
+16bpp: 320, 512, 640, 832, 1024, 1280, 1664, 2048, 2560, 3328
+24bpp: 640, 1024, 1280, 1664, 2048, 2560, 3328, 4096, 5120, 6656
+32bpp: 160, 256, 320, 416, 512, 640, 832, 1024, 1280, 1664
+</verb></quote>
+
+¾¤Î Cirrus ¥Á¥Ã¥×¥»¥Ã¥È¤Ç¤Ï¡¢¥¢¥¯¥»¥é¥ì¡¼¥¿µ¡Ç½¤ò»È¤Ã¤¿¾ì¹ç¡¢
+²¾ÁÛ²èÌ̤ÎÉý¤Ï 32 ¤ÎÇÜ¿ô¤Ë¤Ê¤ê¤Þ¤¹¡£
+¥â¥Ë¥¿¡¼¤Î¿åÊ¿Êý¸þ¤ÎÄ´À°¿ôÃÍ¤Ï 2048 °Ê²¼¤Ë¤·¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£
+
+<!--To run <tt>XF86_SVGA</tt> at a higher color depth, pass options to the
+X server as follows:-->
+¤è¤ê¹â¤¤¿§¤Î¿¼¤µ¤Ç <tt>XF86_SVGA</tt> ¤òưºî¤µ¤»¤ë¤Ë¤Ï¡¢¼¡¤Î¥ª¥×¥·¥ç¥ó¤ò
+X ¥µ¡¼¥Ð¤ËÉղ䷤Ʋ¼¤µ¤¤¡£
+
+<verb>
+startx -- -bpp 16 5-6-5 RGB ('64K color', XGA)
+startx -- -bpp 16 -weight 555 5-5-5 RGB ('Hicolor') (5462 ¤Ç¤Ï¤Ê¤¯)
+startx -- -bpp 24 8-8-8 RGB truecolor
+startx -- -bpp 32 8-8-8 XRGB truecolor (543X/46/6X)
+</verb>
+
+
+<sect> ´ðËܹ½À® <p>
+
+<!--
+It is recommended that you generate an XF86Config file using
+the `<tt>XF86Setup</tt>' or `<tt>xf86config</tt>' program, which should
+produce a working
+-->
+`<tt>XF86Setup</tt>' ¤ä`<tt>xf86config</tt>' ¥×¥í¥°¥é¥à¤ò»ÈÍѤ·¤Æ
+XF86Config ¥Õ¥¡¥¤¥ë¤òÀ¸À®
+¤¹¤ë¤³¤È¤ò¤ª´«¤á¤·¤Æ¤¤¤Þ¤¹¤¬¡¢¤³¤Î¥×¥í¥°¥é¥à¤Ï²ÔƯ²Äǽ¤Ê¹â²òÁüÅÙ¤Î
+8bpp ¤Î¹½À®¤òºîÀ®¤·¤Þ¤¹¡£»ÈÍѤ¹¤ë¥â¥Ë¥¿¡¼¤Ë¡¢¤è¤êŬ±þ¤·¤¿¥â¡¼¥ÉÄ´À°
+Ãͤò <tt>Monitor</tt> Àá¤Ëµ­Æþ¤·¤¿¤¯¤Ê¤ë¤Ç¤·¤ç¤¦¡£¥É¥é¥¤¥Ð¤Î¥ª¥×¥·¥ç
+¥ó¤Ë¤Ä¤¤¤Æ¤Ï¼¡¤ÎÀá¤Ç¾ÜºÙ¤Ë½Ò¤Ù¤Þ¤¹¤Î¤Ç¡¢¤³¤³¤Ç¤Ï·Ú¤¯¿¨¤ì¤ë¤À¤±¤Ë¤·¤Þ
+¤¹¡£
+
+Á´¤Æ¤Î¤Î¥Á¥Ã¥×¥»¥Ã¥ÈÍÑ¤Ë <tt>Clockchip &dquot;cirrus&dquot;</tt> ¹Ô¤ò
+<tt>Device</tt> Àá¤Ë½ñ¤­¤Þ¤·¤ç¤¦¡£¤³¤¦¤ä¤Ã¤Æ¤ª¤¯¤È¥µ¡¼¥Ð¤¬¥µ¥Ý¡¼¥È
+¤·¤Æ¤¤¤ëÂкöºÑ¤ß¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ÎÁȤ߹ç¤ï¤»¤ÎÃæ¤«¤éŬÀڤʥɥåȥ¯¥í
+¥Ã¥¯¤ò»ÈÍѲÄǽ¤Ë¤·¤Þ¤¹¡£Äã²òÁüÅ٤Υâ¥Ë¥¿¡¼Âбþ¤Ç 12.6 MHz ¤Î¥É¥Ã¥È¥¯
+¥í¥Ã¥¯¤ò»È¤¤¤¿¤¤¾ì¹ç¤ËɬÍפˤʤê¤Þ¤¹¡£¤·¤«¤·¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤ò»ÈÍѤ¹
+¤ë¤È¡¢ÊѤï¤Ã¤¿¸½¾Ý¤ò°ú¤­µ¯¤³¤¹¥¯¥í¥Ã¥¯¼þÇÈ¿ô¤¬ÉÔ°ÂÄê¤Ë¤Ê¤ë¤Î¤Ç¡¢
+ÀäÂФËɬÍפʻþ¤À¤±»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£
+<!--
+low-resolution modes. However, when this option used, clock frequencies
+be unstable leading to strange effects, so only use it if absolutely
+required.
+-->
+
+¥°¥é¥Õ¥£¥Ã¥¯²èÌ̤κÆÉÁ²è¤¬¤¦¤Þ¤¯Æ°ºî¤·¤Ê¤¤¾ì¹ç¤Ï¡¢¥Á¥Ã¥×¥»¥Ã¥È¤¬ BitBLT
+¥¨¥ó¥¸¥ó¤ò»ý¤Ã¤Æ¤¤¤ë¾ì¹ç¤ËÀ褺<tt>&dquot;no_bitblt&dquot;</tt> ¥ª¥×¥·¥ç
+¥ó¤ò»î¤·¤Æ¤¯¤À¤µ¤¤¡£¤³¤ì¤¬¤¦¤Þ¤¯Æ°ºî¤·¤Ê¤¤¤È¤­¤Ï
+<tt>&dquot;noaccel&dquot;</tt> ¥ª¥×¥·¥ç¥ó¤ò»î¤·¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£Á´¤Æ¤Î
+¥¢¥¯¥»¥é¥ì¡¼¥¿µ¡Ç½¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£<tt>&dquot;no_imageblt&dquot;</tt>
+¥ª¥×¥·¥ç¥ó¤Ç½¼Ê¬¤«¤â¤·¤ì¤Þ¤»¤ó¡£
+
+16bpp ¤« 32bpp ¤Î¿¼¤µ¤Ç¼Â¹Ô¤¹¤ë¤«¡¢8bpp ¤ÇÀ­Ç½¤ò¸þ¾å¤µ¤»¤ë¤Ë¤Ï¥ê¥Ë¥¢
+¥¢¥É¥ì¥Ã¥·¥ó¥°µ¡Ç½¤ò»È¤¨¤ë¤è¤¦¤Ë¤·¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£¥í¡¼¥«¥ë¥Ð¥¹¤Î
+543x ¥«¡¼¥É¤Þ¤¿¤Ï¡¢¥á¥â¥ê¤¬ 16M ¥Ð¥¤¥È°Ê²¼¤Î¥·¥¹¥Æ¥à¤Ç¥í¡¼¥«¥ë¥Ð¥¹¤Î
+542x ¥«¡¼¥É¤â¤·¤¯¤Ï ISA ¤Î 543x ¥«¡¼¥É¤òÅëºÜ¤·¤Æ¤¤¤ë¤È¤­¤Ë°ìÈ̤˻ÈÍѲÄ
+ǽ¤Ç¤¹¡£
+<tt>&dquot;linear&dquot;</tt> ¥ª¥×¥·¥ç¥ó¤¬É¬¿Ü¤Ç¡¢¤ª¤½¤é¤¯
+<tt>Membase</tt>¤Ç¥¢¥É¥ì¥¹¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ë¤Ç¤·¤ç¤¦¡£°Ê¹ß¤ÎÀá¤Ç¾ÜºÙ
+¤ËÀâÌÀ¤·¤Þ¤¹¡£
+
+¤Þ¤¿¡¢ 534x ¤Ç ¥Ç¥Ð¥¤¥¹Àá¤Ë <tt>&dquot;mmio&dquot;</tt> ¥ª¥×¥·¥ç¥ó¤ò½ñ
+¤¤¤Æ¤ª¤¯¤È¹¹¤ËÎɹ¥¤Ê¥¢¥¯¥»¥é¥ì¡¼¥¿¤Ë¤Ê¤ê¤Þ¤¹ < ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï 5429 ¤Ç
+¤âŬÍѲÄǽ¤È»×¤¤¤Þ¤¹¤¬¡¢Ì¤¤À¥Æ¥¹¥È¤·¤Æ¤¤¤Þ¤»¤ó >¡£
+
+<!--
+Finally, if you have 546X chip, it will be on the PCI bus. As such, there
+is no problem about memory mapped I/O or linear frame buffer address spaces
+running into system memory. The PCI spaces are mapped way up near the 4GB
+point. Because the mmio and linear frame buffer don't conflict at all on
+the system, the <tt>&dquot;linear&dquot;</tt>, <tt>Membase</tt>, and
+<tt>&dquot;mmio&dquot;</tt> options are ignored.
+-->
+ºÇ¸å¤Ë¡¢546X ¥Á¥Ã¥×¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ï PCI ¥Ð¥¹¾å¤ËÅëºÜ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤³¤Î
+¤è¤¦¤Ê¾ì¹ç¤Ï¡¢¥á¥â¥ê¥Þ¥Ã¥× I/O ¤ä ¥Õ¥ì¡¼¥à¥Ð¥Ã¥Õ¥¡¥¢¥É¥ì¥¹¶õ´Ö¤¬¥·¥¹¥Æ¥à
+¥á¥â¥ê¤ËÈô¤Ó½Ð¤·¤Æ¤¤¤Æ¤âÌäÂꤢ¤ê¤Þ¤»¤ó¡£PCI ¶õ´Ö¤Ï 4GB ¶á¤¯¤Î¥¢¥É¥ì¥¹¤ò
+³ä¤êÉÕ¤±¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤·¤¿¤¬¤Ã¤Æ mmio ¤È¥ê¥Ë¥¢¥Õ¥ì¡¼¥à¥Ð¥Ã¥Õ¥¡¤Ï
+¥·¥¹¥Æ¥à¾å¤Ç¾×ÆÍ¤¹¤ë¤³¤È¤ÏÁ´Á³¤Ê¤¤¤Î¤Ç<tt>&dquot;linear&dquot;</tt>,
+<tt>Membase</tt>¤È<tt>&dquot;mmio&dquot;</tt>¥ª¥×¥·¥ç¥ó¤Ï̵»ë¤·¤Æ¤¯¤À¤µ
+¤¤¡£
+
+<sect> XF86Config ¥ª¥×¥·¥ç¥ó <p>
+`<tt>Clocks</tt>' ¥³¥Þ¥ó¥É¤Ï»È¤ï¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£¡Ê¤Ä¤Þ¤ê¡¢Ãµºº¤·¤Ê¤¤
+¤Ç¡Ë¥¯¥í¥Ã¥¯¤ò½¤Àµ¤·¤¿¾ì¹ç¡¢¡Ê³Æ¡¹¤Î¥Á¥Ã¥×¥»¥Ã¥È¤Î¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ëºÇÂç
+¥¯¥í¥Ã¥¯°Ê³°¤Î¡Ë¥«¡¼¥ÉËè¤Î°ã¤¤¤ÏÈ¿±Ç¤Ç¤­¤Þ¤»¤ó¡£
+
+°Ê¹ß¤Î¥ª¥×¥·¥ç¥ó¤ÏÆÃ¤Ë Cirrus ¥É¥é¥¤¥Ð¤Ç¤Ï½ÅÍפǤ¹¡£³Æ¡¹¤Î¥ª¥×¥·¥ç¥ó¤Ï
+<tt>XF86Config</tt> ¤Î `<tt>svga</tt>' ¥É¥é¥¤¥ÐÀá¤Ë <tt>Screen</tt> ¹à
+¤ÎÃæ¤ËŬ±þ¤¹¤ëÁ´¤Æ¤Î¿¼¤µ¤ò»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡ÊDevice Àá¤ËÁ´¤Æ¤Î
+Screen ¤ò»ØÄꤹ¤ë¤³¤È¤¬²Äǽ¤Ç¤¹¡Ë¡£
+
+<descrip>
+<tag>&dquot;noaccel&dquot; ¥ª¥×¥·¥ç¥ó</tag>
+<!--
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥¢¥¯¥»¥¿¥ì¡¼¥¿µ¡Ç½¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£DRAM ¤Î®ÅÙ¤ä¹â¤¤
+ ¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ä¥¢¥¯¥»¥é¥ì¡¼¥¿µ¡Ç½¤ÎÉÔ¶ñ¹ç¤Ë¤è¤ëÌäÂê¤ò²ò·è¤¹¤ë»Ù±ç
+ ¤ò¸úΨÎɤ¯¡ÊVLB ¤Ç¤Ï°ìÃʤÈÂÅÅö¤Ë¡Ë¹Ô¤¤¤Þ¤¹¡£
+ of performance (which will still be reasonable on a local bus).
+<tag>Option &dquot;fast_dram&dquot; &dquot;med_dram&dquot; \
+&dquot;slow_dram&dquot; (5424/6/8/9, 543x, 5446)
+</tag>
+-->
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥¢¥¯¥»¥¿¥ì¡¼¥¿µ¡Ç½¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£DRAM ¤Î®ÅÙ¤ä¹â¤¤
+ ¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ä¥¢¥¯¥»¥é¥ì¡¼¥¿µ¡Ç½¤ÎÉÔ¶ñ¹ç¤Ë¤è¤ëÌäÂê¤ò²ò·è¤¹¤ë»Ù±ç
+ ¤ò¸úΨÎɤ¯¡Ê¥í¡¼¥«¥ë¥Ð¥¹¤Ç¤Ï°ìÃʤÈÂÅÅö¤Ë¡Ë¹Ô¤¤¤Þ¤¹¡£
+
+<tag>&dquot;fast_dram&dquot; &dquot;med_dram&dquot; \
+&dquot;slow_dram&dquot; (5424/6/8/9, 543x) ¥ª¥×¥·¥ç¥ó
+</tag>
+<!--
+ These options set the internal memory clock (MCLK) register to
+ another value. The default value programmed by the BIOS is
+ usually OK, don't mess with these options unless absolutely
+ required.
+-->
+ ¤³¤ì¤é¤Î¥ª¥×¥·¥ç¥ó¤ÏÆâ¢¥á¥â¥ê¥¯¥í¥Ã¥¯(MCLK) ¥ì¥¸¥¹¥¿¤Ë¾¤Î¿ôÃͤò
+ Êѹ¹¤¹¤ë¤â¤Î¤Ç¤¹¡£É¸½àÃÍ¤Ï BIOS ¤ËÁȤ߹þ¤Þ¤ì¤Æ¤¤¤ë¾ì¹ç¤ÏÂç¾æÉפǤ¹
+ ¤¬¡¢¶¯¤¯Í׵ᤵ¤ì¤Ê¤¤¸Â¤ê¤³¤Î¥ª¥×¥·¥ç¥ó¤Ç̵Ãã¤ò¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£
+
+ <tt>&dquot;fast_dram&dquot;</tt> ¥ª¥×¥·¥ç¥ó¤Ï¥Ó¥Ç¥ª¥Ü¡¼¥É¤ÎÆâ¢¥á¥â¥ê
+ ¥¯¥í¥Ã¥¯(MCLK) ¥ì¥¸¥¹¥¿¤Ë¤è¤ê¹â¤¤ÃͤòÀßÄꤷ¤Þ¤¹
+ (ºÇ¶á¤Î¥Á¥Ã¥×¤Ïɸ½à¤Ç½½Ê¬¤è¤ê¹â¤¤²Á¤ò»È¤Ã¤Æ¤¤¤Þ¤¹)¡£
+
+ Ä̾¤³¤Î¥ì¥¸¥¹¥¿¤Ï¤¤¤¸¤ë¤³¤È¤Ï¤Ê¤¤¤Î¤Ç¤¹¤¬¡¢É¸½à¤Î CL-GD542x BIOS
+ ¤Î½é´ü²½¤Ë¤è¤Ã¤Æ¹â¤¤¥É¥Ã¥È¥¯¥í¥Ã¥¯¥â¡¼¥É¤Ç¤ÎÀ­Ç½¤ËÎɤ¯¤Ê¤¤±Æ¶Á¤òÍ¿
+ ¤¨¤ë¤è¤¦¤Ê¡Ê¥Á¥Ã¥×¥»¥Ã¥È¤Î»ÅÍͤËÀ©¸Â¤µ¤ì¤¿¡ËÄ㤤Êý¤ÎÃͤËÀßÄꤵ¤ì¤Þ
+ ¤¹¡£¤³¤ì¤Ï³ÈÄ¥ RAS Ä´À°¤ò»È¤¦¾ì¹ç¤Ë¤ÏÆÃ¤Ë±Æ¶Á¤ò¼õ¤±¤Þ¤¹¡Ê¤³¤ì¤Ï¥µ¡¼
+ ¥Ð¡¼¤Îõºº¤Ç»ØÅ¦¤µ¤ì¤Þ¤¹¡Ë¡£
+
+
+<!--
+ DRAM ¤Î¼ÂºÝ¤Î®Å٤Ϥ³¤Î¥ª¥×¥·¥ç¥ó¤¬Å¬ÀÚ¤À¤í¤¦¤È¤Ê¤«¤í¤¦¤È¥«¡¼¥Éǧ¼±
+ ¤Ë¤ª¤¤¤Æ´í¸±¤ÊÍ×ÁǤˤϤʤê¤Þ¤»¤ó¡£80ns ¤Î DRAM ¤òÅëºÜ¤·¤Æ¤¤¤ë¤¢¤ë
+ ¥«¡¼¥É¤¬³ÈÄ¥ RAS Ä´À°¤ò»È¤Ã¤Æ DOS ¤Î ¥É¥é¥¤¥Ð¥æ¡¼¥Æ¥£¥ê¥Æ¥£¤Ç
+ MCLK ¤ò (0x22) ¤Î¤è¤¦¤ÊÃͤËÀßÄꤷ¤¿¾ì¹ç¤Ï¹â¤¤ MCLK ¤Ç°ÂÄꤷ¤ÆÆ°ºî¤·
+ ¤Æ¤¤¤ëÍͤ˸«¤¨¤ë¤Ç¤·¤ç¤¦¡£
+ whether this option is appropriate; one CL-GD5426-based card with
+ 80ns DRAM using Extended RAS timing, which came with a DOS driver
+ utility to set the MCLK to this value (0x22), seems to run stable
+ at higher MCLK.
+-->
+ DRAM ¤Î¼ÂºÝ¤Î®Å٤Ϥ³¤Î¥ª¥×¥·¥ç¥ó¤¬Å¬ÀÚ¤À¤í¤¦¤È¤Ê¤«¤í¤¦¤È¥«¡¼¥Éǧ¼±
+ ¤Ë¤ª¤¤¤Æ´í¸±¤ÊÍ×ÁǤˤϤʤê¤Þ¤»¤ó¡£80ns ¤Î DRAM ¤òÅëºÜ¤·¤Æ¤¤¤ë
+ CL-GD5426 ¤ò´ð¤Ë¤·¤¿
+ ¥«¡¼¥É¤¬³ÈÄ¥ RAS Ä´À°¤ò»È¤Ã¤Æ DOS ¤Î ¥É¥é¥¤¥Ð¥æ¡¼¥Æ¥£¥ê¥Æ¥£¤Ç
+ MCLK ¤ò (0x22) ¤Î¤è¤¦¤ÊÃͤËÀßÄꤷ¤¿¾ì¹ç¤Ï¹â¤¤ MCLK ¤Ç°ÂÄꤷ¤ÆÆ°ºî¤·
+ ¤Æ¤¤¤ëÍͤ˸«¤¨¤ë¤Ç¤·¤ç¤¦¡£
+
+ ¥«¥¹¥¿¥Þ¥¤¥º¤µ¤ì¤¿ BIOS ¤¬¤è¤ê¹â¤¤É¸½àÃͰʳ°¤ÎÃͤ˽é´ü²½¤·¤¿¡Ê¼ç¤Ë
+ ͭ̾¤É¤³¤í¤Î¡Ë¥«¡¼¥É¤¬¤¢¤ê¤Þ¤¹¡£<!--¤³¤Î¾ì¹ç¤Ï¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤ò»È¤¦¤È
+ ŬÀڤǤϤʤ¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£-->
+
+ <tt>&dquot;slow_dram&dquot;</tt> ¥ª¥×¥·¥ç¥ó¤Ï MCLK ¤òɸ½à¤Î
+ CL-GD542x BIOS ¤Î
+ ÃÍ (0x1c) ¤ËÀßÄꤷ¤Þ¤¹¡£¹â¤¹¤®¤ë MCLK ¤ÎÃͤϿâľÊý¸þ¤Î²èÌ̤ΤÁ¤é¤Ä
+ ¤¯ÂÓ¡¢¥Æ¥­¥¹¥È¤Ë¸í¤Ã¤¿²èÁÇ¡¢¥Æ¥­¥¹¥È¥â¡¼¥É¤Î²èÁǤÎÈ´¤±¤ò X ¤Îưºî¸å
+ ¤Ë°ú¤­µ¯¤³¤·¤Þ¤¹¡ÊMCLK ¤ÎÀßÄ꤬Ä㤹¤®¤ë¾ì¹ç¤âƱÍͤθ½¾Ý¤òµ¯¤³¤·¤Þ¤¹
+ ¤Î¤ÇÃí°Õ¤·¤Þ¤·¤ç¤¦¡Ë¡£
+
+ ³«»Ï»þ¤Ë¡¢¥É¥é¥¤¥Ð¡¼¤Ï MCLK ¤ÎÃͤòɽ¼¨¤¹¤ë¤Ç¤·¤ç¤¦¡ÊÀ褺¡¢¤³¤ì¤ò³Î
+ ǧ¤·¤Æ²¼¤µ¤¤¡Ë¡¢¤½¤·¤Æ¤³¤ÎÃͤϥ⡼¥É¤Ë¤è¤Ã¤ÆÊѲ½¤·¤Þ¤¹¡£
+
+ ŵ·¿Åª¤Ê MCLK ¤ÎÃÍ:
+ <descrip>
+ <tag/0x1c (50 MHz)/
+ ¤³¤ì¤Ï BIOS ¤Îɸ½àÃͤÇÍѤ¤¤é¤ì¤Þ¤¹¡£
+ <tt>&dquot;slow_dram&dquot;</tt> ¥ª¥×¥·¥ç¥ó¤Ç¶¯À©»ØÄê¤Ç¤­¤Þ¤¹¡£
+ <tag/0x1f (55 MHz)/
+ <tt>&dquot;med_dram&dquot;</tt> ¥ª¥×¥·¥ç¥ó¤Ç»ÈÍѤ¹¤ëÃͤǤ¹¡£
+ 542x ¤ò»È¤Ã¤Æ¤¤¤ë¥«¡¼¥É¤Ç¤ÎºÇ¹â¤ÎÃͤϥê¥Ë¥¢¥¢¥É¥ì¥Ã¥·¥ó¥°¤¬Í­¸ú
+ ¤Ë¤Ê¤Ã¤Æ¤¤¤Ê¤¤¤È°·¤¨¤Ê¤¤¤è¤¦¤Ç¤¹¡£
+ <tag/0x22 (60 MHz)/
+ ËØ¤É¤Î¡Ê³ÈÄ¥ RAS¡Ë 542x ¥«¡¼¥É¤Ç¤Ï <tt>&dquot;fast_dram&dquot;</tt> ¥ª¥×
+ ¥·¥ç¥ó¤ò»È¤¦¤ÈÍ­¸ú¤Ë¤Ê¤ê¤Þ¤¹¡£
+ </descrip>
+
+ ¸ø¼°¤Ê 542x ¥Á¥Ã¥×¤ÎºÇÂç¼þÇÈ¿ô¤Ï 50 MHz ¤Ç¤¹¡£
+ 5434 ¤Î¸ø¼°»ÅÍͤϤޤ¿ 50 MHz (0x1c) ¤Ç¡¢5429 ¤È 5430 ¤Î¥°¥é¥Õ¥£¥Ã¥¯
+ ¥â¡¼¥É¤Ç¤Ï 60 MHz (0x22) ¤Î MCLK ¤ò¥µ¥Ý¡¼¥È¤·¡¢¥É¥é¥¤¥Ð¤Ï¼«Æ°Åª¤Ë¤³
+ ¤ì¤òÁȤ߹þ¤ß¤Þ¤¹¡£¤³¤ì¤¬ÌäÂê¤ò°ú¤­µ¯¤³¤·¤¿¾ì¹ç¤Ï &dquot;slow_dram&dquot; ¥ª¥×
+ ¥·¥ç¥ó¤ò»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤¡£
+
+ ¥É¥é¥¤¥Ð¤Ïǧ¼±¤·¤¿ DRAM ÂÓ°èÉý¤Î¥¯¥í¥Ã¥¯¤Î¾å¸Â¤ò MCLK ¤Ë¼è¤ê¹þ¤ß¤Þ
+ ¤¹¡£
+
+ ÆÃ¤Ë¡Ê¹â¤¤¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ÇÀ­Ç½¤ä°ÂÄêÅ٤ΡËÌäÂ꤬¤Ê¤«¤Ã¤¿¤é¡¢
+ DRAM ¥ª¥×¥·¥ç¥ó¤ò»È¤¦É¬ÍפϤ¢¤ê¤Þ¤»¤ó¡£
+<tag>
+&dquot;no_bitblt&dquot; ¥ª¥×¥·¥ç¥ó
+</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤ò 5426/28/29/3x/46/6x/754x ¤Ç»ÈÍѤ¹¤ë¾ì¹ç¡¢
+ ¥¢¥¯¥»¥é¥ì¡¼¥¿µ¡Ç½
+ ¤òÊÝ»ý¤¹¤ë´Ö¡¢¡Ê5424 ¤Ç¤Ï»ý¤Ã¤Æ¤¤¤Ê¤¤¡ËBitBLT ¥¨¥ó¥¸¥ó¤ò̵¸ú¤Ë¤·¤Þ
+ ¤¹¡£BitBLT ¥¨¥ó¥¸¥ó¤ò»ÈÍѤ¹¤ë¤³¤È¤Ë´ØÏ¢¤·¤ÆÀ¸¤¸¤ëµ¡Ç½¾å¤ÎÌäÂê¤ËÂФ·
+ ¤ÆÍ­¸ú¤Ç¤¹¡£À­Ç½¤Ï¤«¤Ê¤êÃø¤·¤¯Íî¤Á¤Þ¤¹¡£
+<tag>
+&dquot;no_imageblt&dquot; ¥ª¥×¥·¥ç¥ó
+</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤ò 5426/28/29/3x/46/6x/754x ¤Ç»ÈÍѤ¹¤ë¾ì¹ç¡¢
+ ¥·¥¹¥Æ¥à¥á¥â¥ê¤«¤é
+ ¥Ó¥Ç¥ª¥á¥â¥ê¤ËžÁ÷¤¹¤ë BitBLT µ¡Ç½¤ò̵¸ú¤Ë¤·¤Þ¤¹¡£
+ ÆÃ¤Ë®¤¤ CPU ¤Ç VLB 5426 ¤È 5434 ¤ò»È¤Ã¤¿¤¤¤¯¤Ä¤«¤Î¥·¥¹¥Æ¥à¹½À®¤Ç
+ ǧ¤á¤é¤ì¤Æ¤¤¤ë¡¢²èÌ̤κ¸¾å¤¹¤ß¤Î¾®¤µ¤¤Çò¤¤Àþ¼ã¤¯¤Ï¥µ¡¼¥Ð¤ËÌá¤Ã¤¿
+ ¸å¤ÎÏĤó¤À²èÁü¤ÎÍͤʲèÁü½ñ¤­¹þ¤ß¤ÎÌäÂê¤ËÍ­¸ú¤Ç¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤ò
+ »È¤¦¤ÈÀ­Ç½¤¬Äã²¼¤·¤Þ¤¹¤Î¤ÇÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£
+<tag>
+&dquot;clgd54xx&dquot; ¥Á¥Ã¥×¥»¥Ã¥È
+</tag>
+ ÅëºÜ¤µ¤ì¤Æ¤¤¤ë¥Á¥Ã¥×¥»¥Ã¥È¤ò¶¯À©Ãµºº¤µ¤»¤Þ¤¹¡£¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¥Á¥Ã
+ ¥×¥»¥Ã¥È¤¬Àµ³Î¤Ëǧ¼±¤µ¤ì¤Ê¤¤¤È¤«¡¢¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤¥Á¥Ã¥×¥»¥Ã¥È¤ò
+ ¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¥Á¥Ã¥×¥»¥Ã¥È¸ß´¹ÉʤȤ·¤ÆÇ§¼±¤µ¤»¤¿¤¤¾ì¹ç¤ËÍ­¸ú¤Ç
+ ¤¹¡£
+<tag>
+videoram 1024 (Ëô¤Ï¾¤ÎÃÍ)
+</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥Ó¥Ç¥ª¥á¥â¥ê¤ÎõººÅëºÜÎ̤ζ¯À©»ØÄê¤È¸½¹Ô¤Î¥«¡¼¥É¤Ë
+ ¥á¥â¥ê¤òÄɲ乤ë¤Õ¤ê¤ò¤¹¤ë¾ì¹ç¤Ë»ØÄꤷ¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï 2M ¥Ð
+ ¥¤¥È¤Î¥á¥â¥ê¹½À®»þ¤Ë¥É¥é¥¤¥Ð¤ÎÍ×µá¥á¥â¥êÎ̤ȸߴ¹À­¤¬ÊݤƤʤ¤¾ì¹ç¤Ë
+ £±MB °Ê¾å¤ò¸«¤»¤¿¤¯¤Ê¤¤¡¢¤È¤«¥á¥â¥ê¤Îõºº¤¬¤¦¤Þ¤¯Æ°ºî¤·¤Ê¤¤¤È¤­¤ËÍ­
+ ¸ú¤Ç¤¹¡£¤³¤ì¤Ï Device Àá¤Ëɬ¤º»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+<tag>
+&dquot;fifo_conservative&dquot; ¥ª¥×¥·¥ç¥ó (5424/6/8/9/3x/46/6x/754x ¤Î¾ì¹ç¤Ë»ØÄê)
+</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï CRT FIFO ¤ÎÉßµïÃͤò¹â¤¤¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Î¹µ¤¨ÌܤÊÃÍ
+ (&gt;= 65 MHz) ¤Ë ÀßÄꤹ¤ë¤â¤Î¤Ç¡¢`¶Ú¡¦°ðºÊ'(`streaks')
+ , `¥¸¥Ã¥¿¡¦ÉÔ°ÂÄê'(`jitter') ¼ã¤¯¤Ï²èÌ̤οåÊ¿Îΰè¤Î·«¤êÊÖ¤·É½¼¨
+ (ÆÃ¤Ë BitBLT Áàºî¤ò¹Ô¤Ã¤¿¤È¤­,Î㤨¤Ð¥¹¥¯¥í¡¼¥ë)¤È·ÁÍÆ¤µ¤ì¤ëÌäÂê¤ò
+ À­Ç½¤¬Íî¤È¤·¤Æ¤â·Ú¸º¤·¤¿¤¤¾ì¹ç¤ËÍ­¸ú¤Ç¤¹¡£
+<tag>
+&dquot;fifo_aggressive&dquot; ¥ª¥×¥·¥ç¥ó (5424/6/8/9/3x/46/6x/754x ¤Î¾ì¹ç¤Ë»ØÄê)
+</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï CRT FIFO ¤ÎÉßµïÃͤò¹â¤¤¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ÎÀѶËŪ¤ÊÃÍ
+ ¤ËÀßÄꤹ¤ë¤â¤Î¤Ç¡¢Ä㤤Êý¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯ÍѤ˻ÈÍѤ¹¤ë¤â¤Î¤ÈƱ¤¸¤Ç
+ ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¹â¤¤¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ç¤ÎÀ­Ç½¤ò¸þ¾å¤µ¤»¤Þ¤¹¡£
+<tag>
+&dquot;no_2mb_banksel&dquot; ¥ª¥×¥·¥ç¥ó (542x ¤Î¾ì¹ç¤Ë»ØÄê)
+</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï 2M ¥Ð¥¤¥È¤Î¥á¥â¥ê¤òÅëºÜ¤·¤¿¥«¡¼¥É¤Ç 1M ¥Ð¥¤¥È°Ê¾å
+ ¤Î¥á¥â¥ê¤òÍ­¸ú¤Ë¤¹¤ë `DRAM bank select' ¥Ó¥Ã¥È¤òÀßÄꤷ¤Ê¤¤¤â¤Î¤Ç
+ ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï 512Kx8 ¤Î DRAM ¹½À®¤ÇÍ­¸ú¤Ç¡¢1M ¥Ð¥¤¥È°Ê¾å¤ò²¾
+ ÁÛ²èÌ̤˻ȤäƤ¤¤ë 256Kx4/16 ¤Î DRAM ¹½À®¤Î¾ì¹ç¤Ï̵¸ú¤Ç¤¹¡£
+<tag>
+&dquot;probe_clocks&dquot; ¥ª¥×¥·¥ç¥ó
+</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥«¡¼¥É¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ò¶¯À©Ãµºº¤·¤Þ¤¹¡£¥¯¥í¥Ã¥¯¤¬
+ ¸ÇÄê¤ÇÁ´¤Æ¤Î Cirrus ¤Î¥Á¥Ã¥×¥»¥Ã¥È¤ÇƱ¤¸¤Ê¤éɬÍפ¢¤ê¤Þ¤»¤ó¡£¤·¤«¤·
+ ¸½¾õɸ½à¤Î 14.31818 MHz ¤Î¼þÇÈ¿ô¤ò¥Ð¥¹¤Ë¶¡µë¤¹¤ë¥Þ¥¶¡¼¥Ü¡¼¥É¤Ë°Í¸
+ ¤·¤Þ¤¹¡£´Ö°ã¤Ã¤ÆÀ߷פµ¤ì¤¿ VLB ¤Î¥Þ¥¶¡¼¥Ü¡¼¥É¤ÏŬÀµ¤Ê¥Ð¥¹¼þÇÈ¿ô¤Î¤¿
+ ¤á¤Î¤³¤Î¼þÇÈ¿ô¤òÀµ¤·¤¯¶¡µë¤·¤Þ¤»¤ó¡ÊÎ㤨¤Ð 33 MHz ¤«¤é³ÈÄ¥¤·¤¿¤â
+ ¤Î¡Ë¡£
+ ¤â¤·´Ö°ã¤Ã¤Æ¤¤¤¿¤é¡¢¤³¤Î¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤Æ`<tt>X -probeonly</tt> ¤ò
+ ¼Â¹Ô¤·¤Æ¤¯¤À¤µ¤¤¡£
+ ¥¯¥í¥Ã¥¯¤¬¼¡¤Ë¼¨¤¹Àµ¤·¤¤¥¯¥í¥Ã¥¯¤«¤é¤È¤Æ¤â°Û¤Ê¤Ã¤Æ¤¤¤¿¾ì¹ç¡¢
+ <tt>XF86Config</tt> ¤Î <tt>Clocks</tt> ¹Ô¤Ë ÊФäƤ¤¤ëÊý¤Î¥¯¥í¥Ã¥¯
+ ¤òµ­Æþ¤·¤Æ¤¯¤À¤µ¤¤¡£¤³¤Î¾ì¹ç¡¢MCLK ¤âÌò¤Ë¤¿¤Á¤Þ¤»¤ó¡£
+
+ Àµ¤·¤¤¥¯¥í¥Ã¥¯:
+<verb>
+ 25.2 28.3 41.1 36.1 31.5 40.0 45.1 49.9
+ 65.0 72.2 75.0 80.0 85.2
+</verb>
+<tag>
+&dquot;cirrus&dquot; ¥¯¥í¥Ã¥¯¥Á¥Ã¥×
+</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥×¥í¥°¥é¥Þ¥Ö¥ë¥¯¥í¥Ã¥¯¤ò²Äǽ¤Ë¤·¤Þ¤¹¡£Device Àá¤Ë
+ »ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤ë¤È¡¢¥¯¥í¥Ã¥¯¥â¡¼¥É¤¬
+ ¼«Æ°¤ÇÁªÂò¤µ¤ì¤Þ¤¹¡£Clocks ¹Ô¤Ïµ­Æþ¤·¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£¤³¤Î¥ª¥×¥·¥ç¥ó
+ ¤Ï 320x200 ¤Î¥À¥Ö¥ë¥¹¥­¥ã¥ó¥â¡¼¥É¤Î¤¿¤á¤Î 12.5 MHz ¤Î¥¯¥í¥Ã¥¯¤ò²Äǽ
+ ¤Ë¤·¤Þ¤¹¡£¤¤¤¯¤Ä¤«¤Î¼þÇÈ¿ô¤ÏÉÔ°ÂÄê¤Ë¤Ê¤ë¤«¤â¤·¤ì¤Ê¤¤¡Ê`ÇÈÂǤÄ' ²èÌÌ
+ ¤¬½Ð¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡Ë¤Î¤ÇÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£»î¤·¤Æ¡¢¥Æ¥¹¥È¤·¤¿¼þÇÈ
+ ¿ô¡Êɸ½àÃͤΤ褦¤Ë¡Ë¤À¤±¤¬°ÂÄê¤Ê¤Î¤ÏÊݾڤ·¤Þ¤¹¡£
+<tag>
+&dquot;linear&dquot; ¥ª¥×¥·¥ç¥ó (542x/6/8/9/3x/46/754x ¤Î¾ì¹ç¤Ë»ØÄê)
+</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï SVGA ¥Ð¥ó¥¯ÀÚ¤êÂØ¤¨¤Ç¤ÏɬÍפΤʤ¤Á´¥Õ¥ì¡¼¥à¥Ð¥Ã
+ ¥Õ¥¡¤ò¥·¥¹¥Æ¥à¥á¥â¥ê¤ÎÈϰϤòͤ¨¤¿¹â°Ì¤Î¥¢¥É¥ì¥¹¤Þ¤Ç³ä¤êÉÕ¤±¤ë¥ê¥Ë
+ ¥¢¥¢¥É¥ì¥Ã¥·¥ó¥°¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£256 ¿§»þ¤ÎÀ­Ç½¤¬¸þ¾å¤· 16bpp ¤È
+ 32bpp ¤Ç¤Ïɬ¿Ü¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£¾ÜºÙ¤Ï
+ <ref id="16bpp/32bpp" name="¥ê¥Ë¥¢¥¢¥É¥ì¥Ã¥·¥ó¥° ¤È 16bpp/32bpp
+ ¥â¡¼¥É">¤ÎÀá¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+<tag>
+Membase 0x00e00000 (Ëô¤Ï°Û¤Ê¤ë¥¢¥É¥ì¥¹) (542x/6/8/9/3x/46/754x ¤Î¾ì¹ç¤Ë»ØÄê)
+</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤ÏʪÍýŪ¤Ê¥ê¥Ë¥¢¥Õ¥ì¡¼¥à¥Ð¥Ã¥Õ¥¡¤Î¥á¥â¥ê´ðÄ쥢¥É¥ì¥¹
+ ¤òÀßÄꤷ¤Þ¤¹¡£¤³¤ì¤Ï Device Àá¤Ë»ØÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£Èó PCI ¤Î¥ê¥Ë
+ ¥¢¥¢¥É¥ì¥Ã¥·¥ó¥°¤Î¹½À®¤ËɬÍפǤ¹¡£
+<tag>
+&dquot;favour_bitblt&dquot; ¥ª¥×¥·¥ç¥ó (5426 ¤Î¤ß)
+</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï BitBLT ¥¨¥ó¥¸¥ó ¤òÍ­¸ú¤Ë¤·¤Æ¥Õ¥ì¡¼¥à¥Ð¥Ã¥Õ¥¡¤Î¿§¿ô
+ ¤òÁý¤ä¤¹µ¡Ç½¤ò°ìÈÌŪ¤Ë®¤¯¤¹¤ë¤Î¤ËÍѤ¤¤Þ¤¹¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï
+ CPU ¤ËÉé²Ù¤Î¤«¤«¤Ã¤¿¥·¥¹¥Æ¥à¡ÊÎ㤨¤Ð¡¢gcc ¤È¾¤Î¥×¥í¥°¥é¥à¤¬Æ±»þ¤Ë
+ ¼Â¹Ô¤·¤Æ¤¤¤ë¾ì¹ç¤Ê¤É¡ËÅù¡¢°ìÄê¤Î¾ò·ï¤ÇÀ­Ç½¤Î¸þ¾å¤ò¤Ï¤«¤ê¤Þ¤¹¡£
+<tag>
+&dquot;mmio&dquot; ¥ª¥×¥·¥ç¥ó (5429/3x/46/754x)
+</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¾¯¤·Â®¤¯¤Ê¤ë¥á¥â¥ê¥Þ¥Ã¥×¥É I/O ¤ò»È¤¦ 543x/5429 ¾å
+ ¤Î BitBLT ¥¨¥ó¥¸¥ó¤È¤ÎÀܳ¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£Éտ路¤Æ¥á¥â¥ê¥Þ¥Ã¥×¥É
+ I/O ¤ò»È¤¦¥¢¥¯¥»¥é¥ì¡¼¥¿µ¡Ç½¤âÍ­¸ú¤Ë¤Ê¤ê¤Þ¤¹¡£¤³¤ÎÉղõ¡Ç½¤Ï BitBLT
+ ¥¨¥ó¥¸¥ó¤ò»È¤ï¤Ê¤¤¤È¤­¡ÊÎ㤨¤Ð¡¢&dquot;no_bitblt&dquot; ¤ò»È¤Ã¤¿¾ì¹ç¡Ë¤Ï¸ú²Ì¤¬
+ ¤¢¤ê¤Þ¤»¤ó¡£
+<tag>
+&dquot;sw_cursor&dquot; ¥ª¥×¥·¥ç¥ó (5429/3x/46/754x)
+</tag>
+ ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¥Á¥Ã¥×¤¬Ä󶡤¹¤ë¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½¥ë¤ò̵¸ú¤Ë¤·¤Þ
+ ¤¹¡£¥«¡¼¥½¥ë¤ËÌäÂ꤬¤¢¤ë¤È¤­¤Ë»î¤·¤Æ¤¯¤À¤µ¤¤¡£ÆÃ¤Ë¡¢5434/6 ¤Ç
+ 85 MHz °Ê¾å¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ò»È¤¦¤È¤­¤ËÍ­¸ú¤Ç¤¹¤¬¡¢¤³¤ì¤é¤Î¥Á¥Ã¥×¤¬¤½¤Î¥¯
+ ¥í¥Ã¥¯¤Ç¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½¥ë¤ÎÁ´¤Æ¤Îµ¡Ç½¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤¤³¤È¤Ë
+ Ãí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£
+<tag>
+&dquot;clgd6225_lcd&dquot; ¥ª¥×¥·¥ç¥ó
+</tag>
+ ¤¤¤¯¤Ä¤«¤Î 62x5 ¥é¥Ã¥×¥È¥Ã¥×ÍÑ¥Á¥Ã¥×¥»¥Ã¥È¤ÇºÇ¤âÇò¤¤¿§¤ò LCD ²èÌÌ
+ ¤Ëɽ¼¨¤¹¤ë¤È¤­¤ÎÌäÂê¤ËÂФ¹¤ëÂкö¤òÄ󶡤·¤Þ¤¹¡£
+</descrip>
+
+
+<sect> ¥â¡¼¥É ¤Ë´Ø¤¹¤ëµÄÏÀ <p>
+
+<!--
+256 ¿§¥¢¥¯¥»¥é¥ì¡¼¥¿¥É¥é¥¤¥Ð¤Ï¥Ó¥Ç¥ª¥á¥â¥êÆâ¤Î 256 ¥Ð¥¤¥È¡¢¥Ï¡¼¥É¥¦¥§¥¢
+¥«¡¼¥½¥ë¤Ï 1K ¥Ð¥¤¥È¤òºî¶ÈÎΰè¤Ë»È¤¤¤Þ¤¹¡£·ë²ÌŪ¤Ë 1M ¥Ð¥¤¥È¤Î¥«¡¼¥É¤Ç
+¤Ï 1024x1024 ¤Î²¾ÁÛ²òÁüÅ٤ϻÈÍѽÐÍè¤Þ¤»¤ó¡£
+
+ÆÃ¤Ë BitBlt ¤òÉÁ²èÍѤΠDRAM Éý¤¬¾®¤µ¤¤¾ì¹ç¤Ë»ÈÍѤ·¤¿¤È¤­¡¢¤è¤ê¹â¤¤
+¥É¥Ã¥È¥¯¥í¥Ã¥¯¼þÇÈ¿ô¤Ï¥°¥é¥Õ¥£¥Ã¥¯Áàºî¤ÎÀ­Ç½¤ËÈÝÄêŪ¤Ê¸ú²Ì¤òµÚ¤Ü¤·¤Þ¤¹
+¡Ê¤½¤ÎÎ̤ϵ¯Æ°»þ¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡Ë¡£É¸½à¤Î MCLK ¤ÎÀßÄê (0x1c) ¤È 32-¥Ó¥Ã
+¥È¥á¥â¥ê¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤ò»ÈÍѤ·¤¿¤È¤­¡¢65 MHz ¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ç¤ÎÀ­Ç½
+¤Ï 25 MHz ¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯»þ¤ÎÀ­Ç½¤ÎȾʬ¤Ë¤Ê¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£DRAM Éý¤¬
+¾¯¤Ê¤¤¤È¤­¡¢¤È¤Æ¤âÃÙ¤¯´¶¤¸¤¿¤é¥É¥Ã¥È¥¯¥í¥Ã¥¯¤òºÇ¤âÃÙ¤¤ÍÆÇ§¤Ç¤­¤ëÃͤˤ·
+¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£Î㤨¤Ð¹â¤¤ºÆÉÁ²è®ÅÙ¡Ê 50MHz ¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¡Ë¤ò»È¤Ã¤Æ
+14&dquot; Ëô¤Ï 15&dquot; ¤Î¥â¥Ë¥¿¡¼¤ËÂ礭¤Ê²¾ÁÛ²èÌÌ¤Ç 800x600 ¤Î²èÌ̤òɽ¼¨¤¹¤ë¤Î¤Ï
+¤½¤ó¤Ê¤Ë°­¤¯¤¢¤ê¤Þ¤»¤ó¡£
+-memory, and the hardware cursor also uses 1K. Consequently, a 1024x1024
+-virtual resolution should not be used with a 1Mbyte card.
+-
+-The use of a higher dot clock frequencies has a negative effect on
+-the performance of graphics operations, especially BitBlt, when little DRAM
+-bandwidth is left for drawing (the amount is displayed during start-up).
+-With default MCLK setting (0x1c) and a 32-bit memory interface, performance
+-with a 65 MHz dot clock can be half of that with a dot clock of 25 MHz.
+-So if you are short on DRAM bandwidth and experience blitting slowness,
+-try using the lowest dot clock that is acceptable; for example, on a 14" or
+-15" screen 800x600 with high refresh (50 MHz dot clock) is not so bad, with
+-a large virtual screen.
+memory, and the hardware cursor also uses 1K (2K on the '6X). Consequently,
+a 1024x1024 virtual resolution should not be used with a 1Mbyte card.
+
+
+The use of a higher dot clock frequencies has a negative effect on the
+performance of graphics operations, especially BitBlt, when little
+video memory bandwidth is left for drawing (the amount is displayed
+during start-up for 542x/3x/46 chips). For the 542x/3x/46 chips, with
+default MCLK setting (0x1c) and a 32-bit memory interface, performance
+with a 65 MHz dot clock can be half of that with a dot clock of 25
+MHz. So if you are short on memory bandwidth and experience blitting
+slowness, try using the lowest dot clock that is acceptable; for
+example, on a 14" or 15" screen 800x600 with high refresh (50 MHz dot
+clock) is not so bad, with a large virtual screen.
+-->
+256 ¿§¥¢¥¯¥»¥é¥ì¡¼¥¿¥É¥é¥¤¥Ð¤Ï¥Ó¥Ç¥ª¥á¥â¥êÆâ¤Î 256 ¥Ð¥¤¥È¡¢¥Ï¡¼¥É¥¦¥§¥¢
+¥«¡¼¥½¥ë¤Ï 1K ¥Ð¥¤¥È ('6X ¤Ç¤Ï 2K ¥Ð¥¤¥È) ¤òºî¶ÈÎΰè¤Ë»È¤¤¤Þ¤¹¡£
+
+
+ÆÃ¤Ë BitBlt ¤òÉÁ²èÍѤΥӥǥª¥á¥â¥êÉý¤¬¾®¤µ¤¤¾ì¹ç¤Ë»ÈÍѤ·¤¿¤È¤­¡¢¤è¤ê¹â¤¤
+¥É¥Ã¥È¥¯¥í¥Ã¥¯¼þÇÈ¿ô¤Ï¥°¥é¥Õ¥£¥Ã¥¯Áàºî¤ÎÀ­Ç½¤ËÈÝÄêŪ¤Ê¸ú²Ì¤òµÚ¤Ü¤·¤Þ¤¹
+¡Ê542x/3x/46 ¥Á¥Ã¥×¤Ç¤Ï¼þÇÈ¿ô¤Ïµ¯Æ°»þ¤Ëɽ¼¨¤µ¤ì¤Þ¤¹¡Ë¡£
+542x/3x/46 ¥Á¥Ã¥×¤Ç¤Ï¡¢É¸½à¤Î MCLK ¤ÎÀßÄê (0x1c) ¤È 32-¥Ó¥Ã¥È¥á¥â¥ê
+¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤ò»ÈÍѤ·¤¿¤È¤­¡¢65 MHz ¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ç¤ÎÀ­Ç½
+¤Ï 25 MHz ¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯»þ¤ÎÀ­Ç½¤ÎȾʬ¤Ë¤Ê¤ë¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£¥á¥â¥êÉý¤¬
+¾¯¤Ê¤¤¤È¤­¡¢¤È¤Æ¤âÃÙ¤¯´¶¤¸¤¿¤é¥É¥Ã¥È¥¯¥í¥Ã¥¯¤òºÇ¤âÃÙ¤¤ÍÆÇ§¤Ç¤­¤ëÃͤˤ·
+¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£Î㤨¤Ð¹â¤¤ºÆÉÁ²è®ÅÙ¡Ê 50MHz ¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¡Ë¤ò»È¤Ã¤Æ
+14" Ëô¤Ï 15" ¤Î¥â¥Ë¥¿¡¼¤ËÂ礭¤Ê²¾ÁÛ²èÌÌ¤Ç 800x600 ¤Î²èÌ̤òɽ¼¨¤¹¤ë¤Î¤Ï
+¤½¤ó¤Ê¤Ë°­¤¯¤¢¤ê¤Þ¤»¤ó¡£
+
+1024x768 ¤Ç ºÇ¤â¹â¤¤¥¯¥í¥Ã¥¯ (85 MHz) ¤ò 542x ¤Î 76 Hz ¤Ç»ÈÍѤ·¤¿¾ì¹ç¡¢
+À­Ç½¸þ¾å»Ø¸þ¤Ë¤Ï¤Ê¤ê¤Þ¤»¤ó¡£¥«¡¼¥É¤ÏÂçÄñÄä»ß¤·¤Þ¤¹¡£75 MHz ¤Î¥É¥Ã¥È¥¯
+¥í¥Ã¥¯ ¤ò 70 Hz ¤Ç»È¤Ã¤¿¾ì¹ç¤ÏËþ­¤Ç¤­¤ë¤Ç¤·¤ç¤¦¡£85 MHz ¤Î¥É¥Ã¥È¥¯
+¥í¥Ã¥¯¤Ë¤ª¤¤¤Æ 76 Hz ¤Ç 1024x768 ¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë¥â¥Ë¥¿¡¼¤ò»ý¤Ã¤Æ¤¤¤ë
+¾ì¹ç¤Ï¡¢É¸½àŪ¤Ê 5426/5428 ¤ò´ð¤Ë¤·¤¿¥«¡¼¥É¤È¤ÏÁêÀ­¤¬Îɤ¯¤Ê¤¤¤Ç¤·¤ç¤¦¡£
+
+2M ¤Î¥á¥â¥ê¤òÀѤó¤À 5434 ¤ò´ð¤Ë¤·¤¿¥«¡¼¥É¤Ï¹â¤¤¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ÈÁêÀ­¤¬ÎÉ
+¤¯¡¢542x ¥·¥ê¡¼¥º¤ËÈæ¤Ù DRAM Éý¤Ï´ðËÜŪ¤Ë 2 Çܤ¢¤ê¤Þ¤¹¡£Ëô¡¢543x ¥Á¥Ã¥×
+¤ÎÎà¤Ï»ÈÍѲÄǽ¤Ê DRAM Éý¤¬°ìÃʤȸú²ÌŪ¤Ë³ÎÊݤǤ­¤Þ¤¹¡£
+
+<sect> ¥ê¥Ë¥¢¥¢¥É¥ì¥Ã¥·¥ó¥° ¤È 16bpp/32bpp ¥â¡¼¥É <label id="16bpp/32bpp"><p>
+
+¸½ºß¡¢SVGA ¥µ¡¼¥Ð¤¬Èó¥¢¥¯¥»¥é¥ì¡¼¥¿¤Î 16-¥Ó¥Ã¥È¤È 32-¥Ó¥Ã¥È¥Ô¥¯¥»¥ë¤ò
+¥µ¥Ý¡¼¥È¤¹¤ë¤Ë¤Ï¥ê¥Ë¥¢¥¢¥É¥ì¥Ã¥·¥ó¥°¤¬É¬¿Ü¤Ç¤¹¡£¤³¤ÎÀ©Ìó¤Ï¤¦¤Þ¤¯¤¤¤±¤Ð
+¾­ÍèŪ¤Ë¤Ï¤º¤µ¤ì¤ë¤Ç¤·¤ç¤¦¡£&dquot;linear&dquot; ¥ª¥×¥·¥ç¥ó ¤Ï¿¼¤µ¤ò»ØÄꤹ¤ë screen
+Àá¤Ç»ØÄꤹ¤ë¤³¤È¤Ç¥ê¥Ë¥¢¥¢¥É¥ì¥Ã¥·¥ó¥°¤òÍ­¸ú¤Ë¤·¡¢Ëô MemBase ¤ò (device
+Àá¤Ç) ÀßÄꤹ¤ëɬÍפ¬¤¢¤ë¤Ç¤·¤ç¤¦(¤±¤ì¤É¤â 5446, 546x ¤È ¤¤¤¯¤Ä¤«¤Î 5436 ¤ò´ð¤Ë¤·¤¿
+¥Ó¥Ç¥ª¥«¡¼¥É¤Î¤è¤¦¤Ê PCI ¥«¡¼¥É¤Ç¤Ï¼«Æ°Åª¤ËÁªÂò¤µ¤ì¤Þ¤¹)¡£
+¥«¡¼¥É¤Ë¤è¤Ã¤Æ°Û¤Ê¤ë¹½À®¤¬¤¤¤¯¤Ä¤â¤¢¤ê¤Þ¤¹¡£
+
+ISA ¥Ð¥¹ÍѤΠ542x/543x ¤È 16M ¥Ð¥¤¥È¤«¤½¤ì°Ê¾å¤Î¥·¥¹¥Æ¥à¥á¥â¥ê¤Î¾ì¹ç¤Ï
+¥ê¥Ë¥¢¥¢¥É¥ì¥Ã¥·¥ó¥°¤ÏÉÔ²Äǽ¤Ç¤¹¡£16bpp ¤Ï»È¤¨¤Þ¤»¤ó¡¢¤¹¤¤¤Þ¤»¤ó¡£14M
+¥Ð¥¤¥È°Ê²¼¤Î¥á¥â¥ê¤Î¾ì¹ç¤Ï `<tt>MemBase 0x00e00000</tt>' ¤ò»È¤¦¤³¤È¤Ç¥Õ
+¥ì¡¼¥à¥Ð¥Ã¥Õ¥¡¤ò 14M ¥Ð¥¤¥È¤Ë³ä¤êÉÕ¤±¤ë¤³¤È¤¬²Äǽ¤Ç¤¹¡£`e' ¤Î¸å¤í¤Ë¥¼¥í
+¤ò£µ¤ÄÉÕ¤±¤Æ¤¯¤À¤µ¤¤¡£»Äǰ¤Ê¤¬¤é¿¤¯¤Î ISA ¥«¡¼¥É¤Ï¥ê¥Ë¥¢¥¢¥É¥ì¥Ã¥·¥ó¥°
+¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó¡£
+
+VESA ¥í¡¼¥«¥ë¥Ð¥¹ÍѤΠ5424/26/28/29 ¤Î¾ì¹ç¤Ï¡¢¾õ¶·¤Ï¤â¤Ã¤ÈÉü»¨¤Ç¤¹¡£
+¥ê¥Ë¥¢¥¢¥É¥ì¥Ã¥·¥ó¥°¤Ë¤Ä¤¤¤Æ£²¼ïÎà¤Î°Û¤Ê¤ë¥¿¥¤¥×¤Î¥«¡¼¥É¤¬¤¢¤ê¤Þ¤¹:
+<itemize>
+<item> ISA ¥Ð¥¹¾å¤Î¥«¡¼¥É¤Î¤è¤¦¤Ë 16M ¥Ð¥¤¥È°Ê²¼¤Ë³ä¤êÉÕ¤±¤ë¥«¡¼¥É¡£
+ ËØ¤É¤³¤Î¤è¤¦¤Ê¥«¡¼¥É¤Ç¤·¤ç¤¦¡£Æ±ÍͤÊÀ©Ìó¡ÊÎ㤨¤Ð 16M ¥Ð¥¤¥È¤è¤ê¾¯¤Ê¤¤
+ ¥á¥â¥ê¤Ç¤Ê¤±¤ì¤Ð¤¤¤±¤Ê¤¤¡Ë¤¬Å¬ÍѤµ¤ì¤Þ¤¹¡£
+<item> A26 ¤Î¥¢¥É¥ì¥¹¥é¥¤¥ó¤ËÀܳ¤· 64M ¥Ð¥¤¥È + 14M ¥Ð¥¤¥È¤â¤·¤¯¤Ï 64M ¥Ð¥¤¥È¤Ë¾ï¤Ë³ä¤êÉÕ¤±¤ë¥«¡¼¥É¡£
+ ¤³¤Î¾ì¹ç¡¢`<tt>MemBase 0x04e00000</tt>' ¤«Ëô¤Ï
+ `<tt>MemBase 0x04000000</tt>' ¤ò»ØÄꤷ¤Þ¤·¤ç¤¦¡£A26 ¤ò »ý¤Ã¤Æ¤¤¤ë VLB
+ ¥Þ¥¶¡¼¥Ü¡¼¥É¤ò²¾Äꤷ¤Æ¤¤¤Þ¤¹¡£¤Þ¤¿¤Ï¥«¡¼¥É¤¬ 0x2000000 ¤Ë³ä¤êÉÕ¤±¤ë¤È
+ ¤«¡¢ 5429 ¤Î¤è¤¦¤ÊºÇ¶á¤Î¥«¡¼¥É¤ÏÄ̾ï 0x03e00000 (62M ¥Ð¥¤¥È) ¤Ë³ä¤êÉÕ
+ ¤±¤Æ¤¤¤Þ¤¹¡£
+</itemize>
+¿ʬ¡¢»î¹Ôºø¸í¤ËÍê¤é¤Ê¤¤¤È¤¤¤±¤Ê¤¤¤Ç¤·¤ç¤¦¡£16M ¥Ð¥¤¥È¤è¤ê¾¯¤Ê¤¤¥á¥â¥ê¤Ê¤é¤Ð `¸í¤Ã¤¿' membase ¤òÀßÄꤹ¤ë¤È¥°¥é¥Õ¥£¥Ã¥¯²èÌ̤Ïɽ¼¨¤Ç¤­¤Þ¤»¤ó¤¬¡¢Â¿Ê¬¥³¥ó¥È¥í¡¼¥ë¡Ü¥ª¥ë¥¿¥Í¡¼¥È¡Ü¥Ð¥Ã¥¯¥¹¥Ú¡¼¥¹¤òƱ»þ¤Ë²¡¤¹¤ÈÌá¤Ã¤Æ¤³¤ì¤Þ¤¹¡£
+
+16M ¥Ð¥¤¥È°Ê¾å¤Î¥á¥â¥ê¤Î¾ì¹ç¤Ï¡¢ºÇ½é¤Î¥¿¥¤¥×¤Î¥«¡¼¥É¡Ê¤È´ÖÈ´¤±¤Ê VLB ¥Þ
+¥¶¡¼¥Ü¡¼¥É¤Î£²ÈÖÌܤΥ¿¥¤¥×¤â¡Ë¤Ç¥Ï¥ó¥°¤·¤Þ¤¹¡Ê¿ʬ¥Ï¡¼¥É¥ê¥Ö¡¼¥È¤¬¼«È¯
+Ū¤Ëµ¯¤ê¤Þ¤¹¡Ë¡£
+
+<!-- It may be possible to find out the type by visual inspection. If the card
+has a pin at A26, it is likely to map beyond 64Mb. To do this, take the card
+out. At the VESA local bus pins (this is the smaller strip of connector pins
+at the non-slot side of the card), consider the right side (this is the side
+of the board where all the chips are mounted). There are 45 pins here. They
+are numbered 1 to 45, from the inside (i.e. the one nearest to the card end
+is 45). Counting from the inside, the 17th pin is probably not present, then
+there are pins at 18-20. The 21st is A30, the 22nd is A28 and the 23rd is
+A26. So, if we have no pins at at 21-23, the card doesn't map beyond 64Mb. If
+there's only a gap of two pins at 21 and 22 (or they are both present) and
+there's a pin at 23, the card does probably map beyond 64Mb. If there's a
+little logic near that pin on the card, it's more likely. -->
+¥«¡¼¥É¤Î¥¿¥¤¥×¤ÏÌܤdzÎǧ¤·¤ÆÊ¬¤«¤ê¤Þ¤¹¡£¥«¡¼¥É¤Ë A26 ¥Ô¥ó¤¬¤¢¤ì¤Ð¡¢64M
+¥Ð¥¤¥È°Ê¾å¤Ë³ä¤êÉÕ¤±¤ë¤â¤Î¤Ç¤·¤ç¤¦¡£³Îǧ¤ò¹Ô¤¦¤Ë¤Ï¡¢¥«¡¼¥É¤òÈ´¤¤¤Æ²¼¤µ
+¤¤¡£VESA ¥í¡¼¥«¥ë¥Ð¥¹¤Î¥Ô¥ó¡Ê¥«¡¼¥É¤Î¥¹¥í¥Ã¥È¤Ç¤Ê¤¤Â¦¤«¤é¸«¤Æ¥³¥Í¥¯¥¿¥Ô
+¥ó¤Î¾®¤µ¤¤Êý¤ÎºÙŤ¤¾®Êҡˤǡ¢±¦Â¦¡ÊÁ´¤Æ¤Î¥Á¥Ã¥×¤¬¼ÂÁõ¤µ¤ì¤Æ¤¤¤ëÌ̡ˤò
+¾Ü¤·¤¯¤ß¤Æ¤¯¤À¤µ¤¤¡£¤³¤³¤Ë 45 ¸Ä¤Î¥Ô¥ó¤¬¤¢¤ê¤Þ¤¹¡£Æâ¦¤«¤é 1 ¤«¤é 45 ¤Þ
+¤ÇÈÖ¹æ¤ò¿¶¤ê¤Þ¤¹¡Ê¥«¡¼¥É¤Îü¤ÎÊý¤¬45 È֤Ǥ¹¡Ë¡£Æâ¦¤«¤é¿ô¤¨¤Æ¡¢17 ÈÖÌÜ
+¤Î¥Ô¥ó¤¬Ìµ¤¯¡¢18 ÈÖÌܤ«¤é 20 ÈÖÌܤޤǤϤ¢¤ë¤È»×¤¤¤Þ¤¹¡£21 ÈÖÌܤ¬ A30
+¤Ç¡¢22 ÈÖÌܤ¬ A28 ¡¢23 ÈÖÌܤ¬ A26 ¤Ç¤¹¡£¤½¤·¤Æ¡¢21 ÈÖÌܤ«¤é 23 ÈÖÌܤΥÔ
+¥ó¤¬Ìµ¤¤¾ì¹ç¡¢¥«¡¼¥É¤Ï 64M ¥Ð¥¤¥È°Ê¾å¤Ë³ä¤êÉÕ¤±¤ë¤³¤È¤Ï½ÐÍè¤Þ¤»¤ó¡£21
+ÈÖÌÜ¤È 22 ÈÖÌܤ¬¶õ¤¤¤Æ¤¤¤Æ¡Ê¤Þ¤¿¤ÏξÊý¤¢¤ê¡Ë³î¤Ä 23 ÈÖÌܤ¬¥Ô¥ó¤¬¤¢¤ë¾ì
+¹ç¡¢64M ¥Ð¥¤¥È°Ê¾å¤Ë¿ʬ³ä¤êÅö¤Æ¤Þ¤¹¡£¥«¡¼¥É¾å¤Î¥Ô¥ó¤Î¤½¤Ð¤Ë¾®¤µ¤Ê²óÏ©
+¤¬¤¢¤ë¾ì¹ç¡¢¤«¤Ê¤ê¸«¹þ¤ß¤¬¤¢¤ë¤È»×¤¤¤Þ¤¹¡£
+
+¥í¡¼¥«¥ë¥Ð¥¹¾å¤Î 543x ¥«¡¼¥É¤Ï¤è¤êñ½ã¡ÊCirrus Logic ¼Ò¤Î winsows ¤Î¥É¥é¥¤¥Ð¤¬¤³¤ì¤ò¤Ä¤«¤Ã¤Æ¤¤¤Þ¤¹¡Ë¤Ç¤¹¤¬¡¢ÌäÂ̵꤬¤¤¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+
+PCI ¥Ð¥¹¾å¤Î¥«¡¼¥É¤Ç¤Ï¡¢PCI ¥«¡¼¥É¤òõºº¤·¤¿¤È¤­¤Ë¼«Æ°Åª¤Ë¥É¥é¥¤¥Ð¤¬ÆÉ
+¤ß¹þ¤à¥Õ¥ì¡¼¥à¥Ð¥Ã¥Õ¥¡¤Î´ðÄ쥢¥É¥ì¥¹¤ò³ÊǼ¤·¤Æ¤¤¤ë PCI ¹½À®¥ì¥¸¥¹¥¿¤ò
+»ý¤Ã¤Æ¤¤¤Þ¤¹¡£`scanpci' ¥×¥í¥°¥é¥à¤Ï PCI ¹½À®¤òÆÉ¤ß½Ð¤·´ðÄ쥢¥É¥ì
+¥¹¤ò¸«¤Þ¤¹¡£
+
+VESA ¥í¡¼¥«¥ë¥Ð¥¹¾å¤Ç¤Ï¡¢ËؤɤΠ543x ¥«¡¼¥É¤Ï 64M ¥Ð¥¤¥È¤Îɸ½àŪ¤Ê³ä¤ê
+ÉÕ¤±¥¢¥É¥ì¥¹¤ò»ý¤Ã¤Æ¤¤¤Æ¡¢¥ª¥×¥·¥ç¥ó¤Ç 2048M ¥Ð¥¤¥È ¤È 32M ¥Ð¥¤¥È¤ò¥¸¥ã
+¥ó¥Ñ¥Ô¥ó¤ÇÀßÄꤷ¤Þ¤¹¡£¤³¤ì¤Ï¥«¡¼¥É¤ËƱº­¤Î»ñÎÁ¤Ë½ñ¤«¤ì¤Æ¤¤¤ë¤«¡¢MS-
+Windows ¤Î system.ini ¥Õ¥¡¥¤¥ë¤Ë (linearaddr = &lt;offset in megabytes
+&gt; Åù¤È) ½ñ¤«¤ì¤Æ¤¤¤ë¤Ç¤·¤ç¤¦¡£Cirrus Logic ¤¬Â¿¤¯¤Î VLB ¥Þ¥¶¡¼¥Ü¡¼¥É
+¤Î¼ÂÁõ¾õ¶·¤òÄ´ºº¤·²Ã¤¨¤¿¤â¤Î¤Ç¡¢¤³¤ì¤é¤È°Û¤Ê¤ë¥¢¥É¥ì¥¹¥Ô¥ó¤Ë¤Ï¼ÂÁõ¤·¤Ê
+¤¤¤Î¤Ç¤¹¡£¥É¥é¥¤¥Ð¤Ï MemBase ¤Î»ØÄ̵꤬¤¤¾ì¹ç¤Ïɸ½à¤Î
+64M ¥Ð¥¤¥È¤ò²¾Äꤷ¤Þ¤¹¡£MemBase ¤ÎÎã¤ò¾¯¤·¼¨¤·¤Þ¤¹:
+<tscreen><verb>
+ MemBase 0x02000000 32Mb
+ MemBase 0x04000000 64Mb
+ MemBase 0x80000000 2048Mb
+</verb></tscreen>
+<!--
++
++Finally, for 546X cards, you are in luck: there are no "issues" to worry
++about. The '6X will always use linear addressing and memory-mapped I/O,
++and will use the memory addresses up near 4GB. Yay for PCI!
++
++The 16bpp and 32bpp modes have limited acceleration (scroll, text, fill)
+ The 16bpp and 32bpp modes have limited acceleration (scroll, text)
+which means they can be slow, although a good local bus host
+interface (like the 543x has) helps a lot. Note that the standard cfb
+framebuffer code can be very slow for monochrome stipples and bitmaps.
+32bpp mode is only supported on a 5434 with 2Mb or more of memory.
+-->
+
+ºÇ¸å¤Ë¡¢546X ¥Ó¥Ç¥ª¥«¡¼¥É¤Î¾ì¹ç¤Ï¥é¥Ã¥­¡¼¤«¤â¡£¿´ÇÛ¤¹¤ë¤è¤¦¤Ê "º¤Æñ" ¤Ï
+¤Ê¤¤¤Ç¤·¤ç¤¦¡£'6X ¤Ï¾ï¤Ë¥ê¥Ë¥¢¥¢¥É¥ì¥Ã¥·¥ó¥°¤È¥á¥â¥ê¥Þ¥Ã¥×¥É I/O ¤È 4GB
+¶á¤¤¥á¥â¥ê¥¢¥É¥ì¥¹¤ò»ÈÍѽÐÍè¤Þ¤¹¡£PCI ¤ò¤É¤¦¤¾¡ª
+
+16bpp ¤È 32bpp ¥â¡¼¥É¤Ï¡Ê¥¹¥¯¥í¡¼¥ë¡¢¥Æ¥­¥¹¥È¡¢Åɤê¤Ä¤Ö¤·¡Ë¤Ë¸ÂÄꤷ¤¿
+¥¢¥¯¥»¥é¥ì¡¼¥¿µ¡Ç½¤¬¤¢¤ê¤Þ¤¹¤¬¤½¤ì¤Ç¤âÃÙ¤¤¤È´¶¤¸¤ë¤Ç¤·¤ç¤¦¡£¤Ç¤â¡¢
+¡Ê543x ¤¬»ý¤Ã¤Æ¤¤¤ë¤è¤¦¤Ê¡ËÍ¥½¨¤Ê¥í¡¼¥«¥ë¥Ð¥¹¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤¬½½Ê¬½õ¤±
+¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£É¸½à¤Î fbc ¥Õ¥ì¡¼¥à¥Ð¥Ã¥Õ¥¡¥×¥í¥°¥é¥à¤ÏÇò¹õ¤ÎÅÀÉÁ¤È
+¥Ó¥Ã¥È¥Þ¥Ã¥×¤Ç¤Ï¤È¤Æ¤âÃÙ¤¤¤Ç¤·¤ç¤¦¡£
+32bpp ¥â¡¼¥É¤ÏºÇÄã 2M ¥Ð¥¤¥È¤Î¥á¥â¥ê¤òÅëºÜ¤·¤¿°ìÉô¤Î¥Ó¥Ç¥ª¥«¡¼¥É¤Ç¤Î¤ß
+¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£
+
+<tt>XF86Config</tt> ¤Î <tt>&dquot;Screen&dquot;</tt> Àá¤Î¤Ê¤«¤Î¡¢
+<tt>&dquot;Display&dquot;</tt>
+¹à(subsection) ¤Ë Modes ¤È ²¾ÁÛ²èÌ̤ÎÂ礭¤µ¤òʬ¤±¤ÆÆ°¤«¤·¤¿¤¤¿¼¤µËè¤Ë
+ÄêµÁ¤·¤Ê¤±¤ì¤Ð¤¤¤±¤Þ¤»¤ó¡£Îã¡Ê2M ¥Ð¥¤¥È¤Î¥Ó¥Ç¥ª¥á¥â¥ê¤Î¾ì¹ç¡Ë¤Ï:
+<tscreen><verb>
+Section "screen"
+ SubSection "Display"
+ Depth 8
+ Virtual 1280 1024
+ ViewPort 0 0
+ Modes "640x480" "800x600" "1024x768"
+ Option "linear"
+ EndSubSection
+ SubSection "Display"
+ Depth 16
+ Virtual 1024 992
+ ViewPort 0 0
+ Modes "640x480" "800x600" "1024x768"
+ Option "linear"
+ EndSubSection
+ SubSection "Display"
+ Depth 32
+ Virtual 832 600
+ ViewPort 0 0
+ Modes "640x480" "800x600"
+ Option "linear"
+ EndSubSection
+EndSection
+</verb></tscreen>
+
+<sect> &dquot;cl64xx&dquot; ¥É¥é¥¤¥Ð<label id="cl64xx"><p>
+cl64xx ¥É¥é¥¤¥Ð¤Ï¿¤¯¤Î¥é¥Ã¥×¥È¥Ã¥×ÍѤΠcl-gd6440 ¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£Îã
+¤¨¤Ð¡¢Sager, ProStar Åù ¤È Texas Instruments TI4000 ¥·¥ê¡¼¥º¤Ë OEM Äó¶¡
+¤µ¤ì¤Æ¤¤¤ë Nan Tan ¥³¥ó¥Ô¥å¡¼¥¿¤Î NP9200,NP3600 Åù¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ
+¤¹¡£
+
+¥É¥é¥¤¥Ð¤Ï LCD ÀìÍѥ⡼¥É¡¢ CRT ÀìÍѥ⡼¥É¤È LCD ¤È³°Éô CRT ¥Ç¥£¥¹¥×¥ì
+¥¤¤òƱ»þ¤Ë»È¤¨¤ë¤è¤¦¤Ë¤¹¤ë¥Á¥Ã¥×¤Î»ý¤Ä SimulScan ¥â¡¼¥É¤Çưºî¤·¤Þ¤¹¡£
+LCD ¤È SimulScan ¥â¡¼¥É¤Î²òÁüÅÙ¤Ï 640x480 ¤¬¡¢CRT ÀìÍѥ⡼¥É¤Ç¤Ï
+640x480, 600x800 ¤È 1024x768 ¤Î ɸ½à VESA ¥â¡¼¥É¤¬¥Æ¥¹¥ÈºÑ¤ß¤Ç¤¹¡£
+1024x768 ¥¤¥ó¥¿¥ì¡¼¥¹¥â¡¼¥É¤Ï¥Ç¥Ð¥Ã¥°¤·¤Æ¤Þ¤»¤ó¤·¡¢¥Æ¥¹¥ÈÍѵ¡¤Ç¤âưºî¤·
+¤Æ¤Þ¤»¤ó¡£
+
+»ñÎÁ¤Ë¤Ê¤Ã¤Æ¤¤¤ë¶îưÅ۵¤Ë°Í¸¤¹¤ë¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ÎºÇÂç²ÔƯ¾å¸Â¤¬¤¢¤ê¤Þ
+¤¹¡£ÆÃ¤Ë 5.0V ¤Ç¤ÎºÇÂç¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ï 65MHz ¤Ç 3.3V ¤Ç¤ÎºÇÂç¥É¥Ã¥È¥¯
+¥í¥Ã¥¯¤Ï 40MHz ¤Ç¤¹¡£¥É¥é¥¤¥Ð¤Ï¶îưÅ۵¤ò³Îǧ¤·¤ÆÅ¬Àµ¤ÊÃͤ˺ÇÂç¥É¥Ã¥È¥¯
+¥í¥Ã¥¯¤òÀ©¸Â¤·¤Þ¤¹¡£¤³¤ì¤¬ 60Hz ¤ÎºÆÉÁ²è®ÅÙ»þ¤ÎÌó 1024x768 ¤ÎºÇÂç²òÁü
+ÅÙ¤ËÊÑ´¹¤µ¤ì¤Þ¤¹¡£Æâ¢ȯ¿¶´ï(frequency generator) ¤Ï¤³¤ì¤é¤Î¾å¸Â¤è¤ê¹â
+¤¤ÃÍ¤Ë¥×¥í¥°¥é¥à¤µ¤ì¤Æ¤¤¤Æ¡¢¥µ¡¼¥Ð¤Îµ¯Æ°»þ¤Ë½Ö´ÖŪ¤Ë¥Á¥Ã¥×¤Î²ÔƯ¾å¸Â
+¤òͤ¨¤ë¤è¤¦¤Ê¥¯¥í¥Ã¥¯¤òõºº¤µ¤»¤Þ¤¹¡£°ìöͭ¸ú¤Ê¥¯¥í¥Ã¥¯¤ÎÁȤ߹ç¤ï¤»¤¬
+ÆÀ¤é¤ì¤¿¤é¡¢<tt>XF86Config</tt> ¤Î Clocks ¹Ô¤Ë½ñ¤¤¤Æ¤ª¤¯¤³¤È¤ò¤ª´«¤á¤·
+¤Þ¤¹¡£¤³¤ì¤ò¹Ô¤¦¤Èµ¯Æ°¤Ë¤«¤«¤ë»þ´Ö¤¬Ãø¤·¤¯¸º¾¯¤·¤Þ¤¹¡£¥¯¥í¥Ã¥¯¤Ï X ¥µ¡¼
+¥Ð¡¼¤Ë -probeonly ¤òÉÕ¤±¤Æ¼Â¹Ô¤¹¤ë»ö¤Ë¤è¤Ã¤ÆÆÀ¤é¤ì¤Þ¤¹¡Ê-probeonly ¤Ë¤Ä
+¤¤¤Æ¾ðÊó¤ò¤â¤Ã¤ÈÃΤꤿ¤¤¾ì¹ç¤Ï XFree86 ¤Î¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤Î¤³
+¤È¡Ë¡£
+
+¥Ç¡¼¥¿¥Ö¥Ã¥¯¤Ë¤Ï¥Á¥Ã¥×¤¬¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤ë 1 ¥á¥¬¥Ð¥¤¥È¤Î¥Ó¥Ç¥ª¥á¥â¥ê¤Î¹½
+À®¤À¤±¤¬¼¨¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤³¤ÎÂ礭¤µ¤Ï¥É¥é¥¤¥Ð¤ÇľÀÜÀßÄꤷ¤Æ¤¤¤Þ¤¹¡£É¬Í×
+¤Ë±þ¤¸¤Æ¡¢½é´üÃͤΥá¥â¥ê¥µ¥¤¥º¤ò <tt>XF86Config</tt> ¤Ë½ñ¤¤¤Æ¤ª¤¯¤³¤È¤â
+½ÐÍè¤Þ¤¹¡£¤Þ¤¿¡¢1M ¥Ð¥¤¥È¤Î¥Ó¥Ç¥ª¥á¥â¥ê¤ÇÎ㤨¤Ð 1024x1024 ¤Î¤è¤¦¤ÊÂ礭
+¤µ¤Î²¾ÁÛ²èÌ̤ò»ý¤Ä¤³¤È¤¬¤Ç¤­¡¢¤³¤ì¤Ï CRT ÀìÍѤβèÌ̥⡼¥É¤Ç»ÈÍѲÄǽ¤Ç
+¤¹¡£¤·¤«¤·¡¢LCD (LCD ¤È SimulScan) ¤ò»È¤¦¤È¤­¤Ï¤¤¤Ä¤Ç¤â¥Á¥Ã¥×¤Ï¥Ó¥Ç¥ª¥á
+¥â¥ê¤Î¾å°Ì¤Î°ìÉô¤ò¤½¤ì¼«¿È¤ÎÆâÉô¤Î²Ã®½èÍý¤Î¤¿¤á¤Ë»ÈÍѤ·¤Þ¤¹¡£½¾¤Ã¤Æ¡¢
+LCD ¥â¡¼¥É¤Ç²¾ÁÛ²èÌ̤ò»ÈÍѤ¹¤ë¤È¤­¤ÎºÇÂç¤Î¥Ó¥Ç¥ª¥á¥â¥ê¤ÏÌó 0.75M ¥Ð¥¤¥È
+¤Ê¤Î¤ÇÎ㤨¤Ð 1024x768 ¤Î¤è¤¦¤Ê²òÁüÅ٤ˤʤë¤Î¤Ç¤¹¡£¾åµ­¤Î¤è¤¦¤Ê²¾ÁÛ²òÁü
+ÅÙ¤òÀßÄꤷ¤¿¾ì¹ç¤Ë¾®¤µ¤¯ÀÚ¤ê¼è¤é¤ì¤¿²èÌ̤˲î²½¤µ¤ì¤¿Îΰ褬ɽ¼¨¤µ¤ì¤Þ
+¤¹¡£
+
+¸½ºß¡¢LCD, CRT ¤È SimulScan ¤Î³Æ²èÌ̥⡼¥É´Ö¤ÎÀÚ¤êÂØ¤¨¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤
+¤Þ¤»¤ó¤¬¡¢¾¯¤Ê¤¯¤È¤â NP9200 ¤Ç¤Ï OS ¤Î¥Ö¡¼¥È»þ¡ÊÎ㤨¤Ð Linux ¤Î LILO
+¤Ç¡ËBIOS ¤¬Ì¤¤À»Ïư¤¹¤ëÁ°¤Ë¥â¡¼¥É¤ÎÁªÂò¤¬½ÐÍè¤ë¤è¤¦¤Ë¤Ê¤Ã¤Æ¤Þ¤¹¡£<tt>
+XF86Config</tt> ¤ËModeLine ¥ª¥×¥·¥ç¥ó¤òÄɲ乤ì¤Ð²èÌ̥⡼¥É¤ÎÁªÂò¤¬ X
+¥µ¡¼¥Ð¤ÎÆâÉô¤«¤éưŪ¤Ë²Äǽ¤Ë¤Ê¤ê¤Þ¤¹¡£ºÇ¸å¤Ë¡¢¥É¥é¥¤¥Ð¤Ï¸½¾õ¤Ç¥Á¥Ã¥×
+¤ÎÄã¾ÃÈñÅÅÎϵ¡Ç½¤È¥¹¥¯¥ê¡¼¥ó¥»¡¼¥Ð¡¼¤Ë¤è¤Ã¤Æ²èÌ̤¬¾Ã¤¨¤Æ¤¤¤ë¤È¤­¤Î LCD
+¤Î¥Ð¥Ã¥¯¥é¥¤¥È¤Î¾ÃÅô¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó¡£¾­Íè¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤³¤ì¤éÁ´
+¤Æ¤Îµ¡Ç½¤¬¼Â¸½¤¹¤ë¤³¤È¤ò´üÂÔ¤·¤Æ¤¤¤Þ¤¹¡£
+
+CL-GD6420 ¤Ë´Ø¤¹¤ëÃí°Õ»ö¹à:
+
+¥Ó¥Ç¥ª¥á¥â¥ê¤ÎÎ̤¬»þ¡¹Àµ¤·¤¯Ãµºº¤Ç¤­¤Ê¤¤¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡££²¤Ä¤Î²ò·èÊýË¡
+¤¬¥É¥é¥¤¥Ð¤Î¥½¡¼¥¹¥³¡¼¥É¤Ë¤¢¤ê¡¢£±¤Ä¤ÏÄêµÁ¤·¤Æ¤·¤Þ¤¦¤³¤È¤Ç¤¹¡£¤â¤Ã¤ÈÎÉ
+¤¤ÊýË¡¤Ï Device Àá¤Î VideoRam ¹Ô¤Ë¥Ó¥Ç¥ª¥á¥â¥ê¤ÎÎ̤ò»ØÄꤹ¤ë¤³¤È¤Ç¤¹¡£
+CRT Ëô¤Ï SIMulscan ¥â¡¼¥É¤Ç¤Ïɸ½àŪ¤Ê 640x480 60Mhz ¤Ç 25.175 MHz ¤Î
+¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ç¤Îɸ½à¥â¡¼¥ÉÄ´À°¤ò¹Ô¤Ã¤Æ²¼¤µ¤¤¡£LCD ÀìÍѤΥ⡼¥É¤Ç¤ÏƱ
+ÍͤΥ⡼¥ÉÄ´À°¤ò¹Ô¤¨¤Þ¤¹¤¬¡¢16.257 MHz ¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤òÍѤ¤¤Æ¤¯¤À¤µ
+¤¤¡£É¸½à¤Î 56 Hz 800x600 ¤â CRT ¤Ç¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤¹¡£
+
+&dquot;cl64xx&dquot; ¥É¥é¥¤¥Ð¤Ç¤Î cl6440 ¤Ë´Ø¤¹¤ëÌäÂê¤ÏRandy Hendry
+<em>&lt;randy@sgi.com&gt;</em> »á¤Þ¤ÇÀ褺ºÇ½é¤ËÏ¢Íí¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+<sect> &dquot;cirrus&dquot; ¥É¥é¥¤¥Ð¤Ç¤Î¾ã³²Âкö¤Î¤Þ¤È¤á<p>
+À褺ºÇ½é¤Ë¡¢<tt>XF86Config</tt> ¤ÇÁªÂò¤·¤¿¥â¡¼¥É¤ò¥â¥Ë¥¿¡¼¤¬¥µ¥Ý¡¼¥È¤·
+¤Æ¤¤¤ë¤³¤È¡¢¤Ä¤Þ¤ê¿åʿƱ´ü¤Î¾å¸Â¤¬Àµ¤·¤¤¤³¤È¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£25.175
+MHz ¤Î¥¯¥í¥Ã¥¯¤Çɸ½àŪ¤Ê 640x480x256 ¡Êñ°ì¤Î¿åʿƱ´ü¤ò 31.5 ¤Ë»ØÄꤷ¤¿
+¾ì¹ç¡Ë¤¬¹½À®¾å¥É¥é¥¤¥Ð¤¬Æ°ºî¤¹¤ë¤³¤È¤Î³Îǧ¤«¤é¤Ï¤¸¤á¤ë¤Î¤¬¤ª´«¤á¤Ç¤¹¡£
+timing Àá¤Ë¤³¤Î²òÁüÅÙÍѤκǹâ¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤òÃÖ¤¤¤Æ¡¢mode ¹Ô¤ÎºÇ½é¤Ë
+½ñ¤¤¤¿¥â¡¼¥É¤¬¾ï¤Ë½é´üÃͤΥ⡼¥É¤È¤·¤ÆÍѤ¤¤é¤ì¤Þ¤¹¡£
+
+¤¤¤¯¤Ä¤«¤Î VESA ɸ½à¥â¡¼¥É¤ÎÄ´À°¤¬¤¤¤¯¤Ä¤«¤Î¥â¥Ë¥¿¡¼¤ÇÌäÂê¤òµ¯¤³¤·¤Þ¤¹
+¤Î¤ÇÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡Ê¿åʿƱ´ü¿®¹æ¤òÁý¤ä¤·¤Æ¤ß¤Þ¤·¤ç¤¦¡¢¤Ä¤Þ¤ê¿¿¤óÃæ¤Î
+£²¤Ä¤Î¿ôÃͤκ¹¤ò¹­¤²¤ë¡¢¼ã¤¯¤ÏÁ´¤Æ¤Î¿åʿƱ´ü¤ÎÄ´À°¿ôÃͤò 16 Ëô¤Ï 32 ¤Î
+ÇÜ¿ô¤Ë¤Ê¤ë¤è¤¦¤ËÁý¤ä¤¹¡Ë¡£
+<descrip>
+<tag>¥Ó¥Ç¥ª¿®¹æ¤¬ÆÏ¤¤¤Æ¤¤¤ë¤¬¡¢²èÌ̤¬Æ±´ü½ÐÍè¤Ê¤¤¾ì¹ç¡£</tag>
+ ¥â¥Ë¥¿¡¼¤¬°·¤¨¤Ê¤¤¥â¡¼¥É¤ò»È¤Ã¤Æ¤¤¤ë¤Î¤Ç¤¹¡£É¸½à¤Ç¤Ê¤¤¥â¡¼¥É¤ò»È¤Ã
+ ¤Æ¤¤¤ë¾ì¹ç¡¢¾¯¤·¿ôÃͤòľ¤¹É¬Íפ¬¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£¥â¥Ë¥¿¡¼¤¬¼è¤ê
+ °·¤¨¤ëɸ½à¥â¡¼¥É¤Èɸ½à¼þÇÈ¿ô¤Î¾ì¹ç¡¢»÷¤¿¤è¤¦¤Ê¥â¡¼¥É¤È¼þÇÈ¿ô¤Ç°Û¤Ê
+ ¤ë¿ôÃͤÎÁȤ߹ç¤ï¤»¤ò¸«¤Ä¤±¤Æ¤¯¤À¤µ¤¤¡£
+<tag>¹â¤¤¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ç¤Î ¿åÊ¿¥¸¥Ã¥¿¡ÊÉÔ°ÂÄê´¶¡Ë</tag>
+ ÆÃ¤Ë¾å¤Ë¥¹¥¯¥í¡¼¥ë¤¹¤ë¤è¤¦¤ÊÉÁ²èÁàºî¤ò¹Ô¤¦»þ¤Ë¤³¤ÎÌäÂ꤬¸«¤é¤ì¤Þ
+ ¤¹¡£542x/3x/46/6x ¤ò»È¤¦¾ì¹ç¤Ï
+ <tt>&dquot;fifo_conservative&dquot;</tt> ¥ª¥×¥·¥ç¥ó¤ò»î¤·¤Æ¤¯¤À¤µ
+ ¤¤¡£¤³¤ì¤¬¼ºÇÔ¤·¤¿¤È¤­¤Ï¡¢<tt>&dquot;fast_dram&dquot;</tt> ¥ª¥×
+ ¥·¥ç¥ó¤ò»î¤¹¤«¡¢¤è¤êÄ㤤¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ò»È¤Ã¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£
+ ¤³¤ì¤Ç¤âËþ­¤¤¤«¤Ê¤¤¾ì¹ç¤Ï¡¢<tt>&dquot;noaccel&dquot;</tt> ¥ª¥×
+ ¥·¥ç¥ó¤«¡¢<tt>&dquot;no_bitblt&dquot;</tt> ¥ª¥×¥·¥ç¥ó¤¬
+ ¿ʬ½õ¤±¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£
+<tag>`ÇÈÂǤÄ'(`Wavy') ²èÌÌ¡£</tag>
+ ²èÌ̤οåÊ¿ÍɤìËô¤ÏÁ´ÂΤΥ¸¥Ã¥¿¤¬¡ÊÉÁ²èÁàºî¤Ë°Í¸¤·¤Ê¤¤¤Ç¡Ë´ÖÃǤʳ
+ ¤¯¸½¾Ý¤Ç¤¹¡£Â¿Ê¬¡¢¹â¤¹¤®¤ë¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ò»È¤Ã¤Æ¤¤¤ë¤»¤¤¤Ç¡¢¶á¤¤¼þ
+ ÇÈ¿ô¤Î MCLK ¤È´³¾Ä¤¬µ¯¤­¤Æ¤¤¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£¤â¤Ã¤ÈÄ㤤¥É¥Ã¥È¥¯
+ ¥í¥Ã¥¯¤ò»î¤·¤Æ²¼¤µ¤¤¡£¤Þ¤¿¡¢¥â¡¼¥É¤Î¿ôÃÍÄ´À°¤ò¹Ô¤Ã¤Æ¡¢£²ÈÖÌܤοåÊ¿
+ Êý¸þ¤Î¿ô»ú¤ò¤¤¤¯¤é¤«Áý¤ä¤·¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£¼¡¤Ï 65MHz ¤Î¥É¥Ã¥È¥¯¥í¥Ã
+ ¥¯¤Ç 1024x768 ¡ÊÌó 60 Hz¡Ë¤Î¥â¡¼¥É¤¬½õ¤±¤Ë¤Ê¤ë¤Ï¤º¤Ç¤¹¡£:
+<verb>
+ "1024x768" 65 1024 1116 1228 1328 768 783 789 818
+</verb>
+ Clockchip <tt>&dquot;cirrus&dquot;</tt> ¤òÍѤ¤¤Æ¥×¥í¥°¥é¥Þ¥Ö¥ë¥¯¥í¥Ã¥¯¤ò»ÈÍѤ·
+ ¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢¤³¤ì¤ò̵¸ú¤Ë¤·¤ÆÉ¸½àÃͤΥ¯¥í¥Ã¥¯¤ÎÁȤ߹ç¤ï¤»¤ò»È¤Ã¤Æ
+ ¤¯¤À¤µ¤¤¡£
+<tag>µ¯Æ°¤·¤¿¸å¤Ç²èÌ̤¬Êø¤ì¤ë¡¢»ß¤Þ¤ë¡Ê²èÌ̤¬¿¿¤Ã°Å¤Ë¤Ê¤ë¤«¤â¡Ë¡£</tag>
+<!-- Try the <tt>&dquot;noaccel&dquot;</tt> option. If that works,
+ try Option <tt>&dquot;no_bitblt&dquot;</tt> for
+ somewhat better performance. Check that the BIOS settings are OK;
+ in particular, disable caching of 0xa0000-0xaffff. Disabling hidden
+ DRAM refresh may also help. -->
+ <tt>&dquot;noaccel&dquot;</tt> ¥ª¥×¥·¥ç¥ó¤ò»î¤·¤Æ¤ß¤Þ¤·¤ç¤¦¡£¤â¤·Æ°¤«¤Ê¤«¤Ã¤¿¾ì
+ ¹ç¡¢¤¤¤¯¤é¤«À­Ç½¸þ¾å¤Î°Ù¤Ë <tt>&dquot;no_bitblt&dquot;</tt> ¤ò»î¤·¤Æ¤ß¤Æ¤¯¤À¤µ
+ ¤¤¡£ BIOS ¤ÎÀßÄ꤬Âç¾æÉפ«¤É¤¦¤«³Îǧ¤·¤Æ¡¢ÆÃ¤Ë 0xa0000-0xaffff ¤ò
+ ¥­¥ã¥Ã¥·¥ó¥°¤·¤Ê¤¤¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£Î¢ DRAM ¤Î¹¹¿·(hidden DRAM
+ refresh) ¤ò̵¸ú¤Ë¤·¤Æ¤âÎɤ¤¤Ç¤·¤ç¤¦¡£
+<tag>
+¥°¥é¥Õ¥£¥Ã¥¯Áàºî¤Î¸å¤Î²èÌ̤¬Êø¤ì¤ë¡¢»ß¤Þ¤ëËô¤Ï¤´¤ß¤¬»Ä¤ë¡£
+</tag>
+ ¥¢¥¯¥»¥é¥ì¡¼¥¿µ¡Ç½¤Î°ì¤Ä¡¢Ëô¤Ï BitBLT µ¡Ç½¤ò»È¤Ã¤¿¤È¤­¤Î¥×¥í¥°¥é¥à
+ ¤Î¥Ð¥°¤Ë´ØÏ¢¤·¤Æ¤¤¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£<tt>&dquot;noaccel&dquot;</tt> ¥ª¥×¥·¥ç¥óËô
+ ¤Ï <tt>&dquot;no_bitblt&dquot;</tt> ¥ª¥×¥·¥ç¥ó¤ò»î¤·¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£¤Þ¤¿¡¢BIOS
+ ¤ÎÀßÄê¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤¡£
+<tag>
+¥µ¡¼¥Ð¤¬ `Blitter timeout' ¤È¤¤¤¦¥á¥Ã¥»¡¼¥¸¤ò½ÐÎϤ¹¤ë¡£
+</tag>
+ Ʊ¤¸ÀßÄ꤬¥À¥Ö¤Ã¤Æ¤¤¤Þ¤¹¡£
+<tag>
+²èÌ̤¬¿âľÊý¸þ¤Ë¼þ¤ê¹þ¤ó¤Ç (`wrapped') ¤¤¤ë¡£ (542x/3x/46 ¤Î¾ì¹ç)
+</tag>
+ DRAM ¹½À®¤ËÌäÂ꤬¤¢¤ë¤³¤È¤ò¼¨¤·¤Æ¤¤¤Þ¤¹¡£¥«¡¼¥É¤Ë£²¥á¥¬¥Ð¥¤¥È¤Î¥á¥â
+ ¥ê¤òÅëºÜ¤·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢<tt>&dquot;no_2mb_banksel&dquot;</tt> ¥ª¥×¥·¥ç¥ó¤«¡¢£±
+ ¥á¥¬¥Ð¥¤¥È¤Î¥á¥â¥ê¤À¤±¤ò²¾ÁÛ²èÌ̤˻Ȥ¦¾ì¹ç¡¢
+ <tt>videoram &dquot;1024&dquot;</tt> ¤ò»î¤·¤Æ¤¯¤À¤µ¤¤¡£
+<tag>
+üËö¥¦¥£¥ó¥É¥¦¤Îʸ»ú¤¬¤Ë¤¸¤à¡£
+</tag>
+
+ ɸ½à¤Ç¤Ê¤¤¥Ó¥Ç¥ª¤Î¼ÂÁõ¤Ë¤ÆÊó¹ð¤µ¤ì¤Æ¤¤¤Þ¤¹¡£
+ <tt>&dquot;no_bitblt&dquot;</tt> ¥ª¥×¥·¥ç¥ó¤ò»È¤Ã¤Æ²¼¤µ¤¤¡£
+<tag>
+¥é¥Ã¥×¥È¥Ã¥×ÍÑ¥Á¥Ã¥×¥»¥Ã¥È¤Ç°ðºÊ¤¬Áö¤ëËô¤Ï»ß¤Þ¤ë
+</tag>
+ ¥É¥Ã¥È¥¯¥í¥Ã¥¯¤¬¹â¤¹¤®¤ë¤¿¤á¡¢ÉÁ²èÍѤÎÂÓ°èÉý¤¬¤È¤Æ¤â¾¯¤Ê¤¯¤Ê¤Ã¤Æ
+ ¡ÊÎ㤨¤Ð¡¢512K ¥Ð¥¤¥È¤Î¥«¡¼¥É¤Ç 40MHz ¤ò»È¤¦¾ì¹ç¡Ë¤¤¤ë¤«¡¢¡Ê 5422
+ ¤Î¤è¤¦¤Ê¡Ë¥¢¥¯¥»¥é¥ì¡¼¥¿µ¡Ç½¤ò»È¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ëµ¯¤³¤ê¤Þ¤¹¡£
+<tag>
+»þ¡¹Ê¸»ú¤Î¥É¥Ã¥È¤¬È´¤±¤ë¡¢ÁëÏȤòư¤«¤¹¤È¥É¥Ã¥È¤Î¤´¤ß¤¬½Ð¤ë¡£
+</tag>
+ ¿ʬ¡¢¹â¤¹¤®¤ë MCLK ¤ÎÀßÄ꤬´Ø·¸¤·¤Æ¤¤¤Þ¤¹¡Ê¥Ð¥ó¥¯¥â¡¼¥É¤¬Âç¾æÉפÇ
+ ¤â¥ê¥Ë¥¢¥¢¥É¥ì¥Ã¥·¥ó¥°¤¬°ú¤­µ¯¤³¤¹¤Ç¤·¤ç¤¦¡Ë¡£
+<tag>
+¥Á¥Ã¥×¥»¥Ã¥È¤¬Ç§¼±¤Ç¤­¤Ê¤¤¡£
+</tag>
+ »È¤ª¤¦¤È¤·¤Æ¤¤¤ë¥Á¥Ã¥×¥»¥Ã¥È¤Ë»÷¤¿¤â¤Î¤ò¶¯À©»ØÄꤹ¤ë¤³¤È¤ò»î¤·¤Þ
+ ¤·¤ç¤¦¡£
+<tag>
+»þ¡¹¡¢´Ö°ã¤Ã¤¿¾®¤µ¤¤Àþʬ¡ÊËØ¤É¤¬Çò¤¤¡Ë¤¬¸½¤ï¤ì¤ë
+</tag>
+ ¥·¥¹¥Æ¥à¤«¤é¥Ó¥Ç¥ª¥á¥â¥ê¤Ø¤Î BitBLT Áàºî¤Ë´Ø¤¹¤ëÌäÂê¤Ë´Ø·¸¤·¤Æ¤¤¤Þ
+ ¤¹¡£¤¤¤é¤¤¤é¤¹¤ë¾ì¹ç¤Ï <tt>&dquot;no_imageblt&dquot;</tt> ¥ª¥×¥·¥ç¥ó¤ò»î¤·¤Æ¤ß
+ ¤Þ¤·¤ç¤¦¡£
+<tag>
+¥Æ¥­¥¹¥È¥â¡¼¥É¤¬Å¬Àڤ˲óÉü¤·¤Ê¤¤
+</tag>
+ ¤¤¤¯¤Ä¤«¤Î¹½À®¤ÇÊó¹ð¤µ¤ì¤Æ¤¤¤Þ¤¹¡£XFree86 3.1 ¤Î SVGA ¥µ¡¼¥Ð¤Îõ
+ ºº¤¬¡¢Chipset ¹Ô¤ÇÍ׵ᤷ¤¿ 543x ¤Î¥ì¥¸¥¹¥¿¤ÎÆâÍÆ¤ò²õ¤·¤¿¤«¤â¤·¤ì¤Þ
+ ¤»¤ó¡£ÉáÄ̤ϥ桼¥Æ¥£¥ê¥Æ¥£ ( Linux ¤Î <tt>setfont</tt>,
+ <tt>runx</tt>, <tt>restorefont</tt>) ¤Ç¥Æ¥­¥¹¥È¥â¡¼¥É¤Ï²óÉü²Äǽ¤Ç
+ ¤·¤ç¤¦¡£
+<tag>
+Èó¾ï¤Ë¹â¤¤¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ç»¶Ì¡¤Ê¥·¥¹¥Æ¥àµóư¤òµ¯¤¹
+</tag>
+ ¥«¡¼¥É³î¤Ä¡¿Ëô¤Ï¥Þ¥¶¡¼¥Ü¡¼¥É¤ÎÀ߷פËÉÔÎɤΤ¢¤ë¾ì¹ç¡¢¥Ó¥Ç¥ª¥«¡¼¥É¾å
+ ¤Î¹â¤¤¥É¥Ã¥È¥¯¥í¥Ã¥¯¤È¥·¥¹¥Æ¥àÆâ¤Î¾¤ÎÉôʬ¡ÊÎ㤨¤Ð ¥Ç¥£¥¹¥¯ I/O¡Ë¤È
+ ¤Î¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤¬¤¦¤Þ¤¯¤¤¤«¤Ê¤¤»þ¤ËȯÀ¸¤¹¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£
+ ¡Ê¤´¤¯¤Þ¤ì¤Ë¡¢ 5428 ¥Á¥Ã¥×¤¬ PCI ¤ò¥µ¥Ý¡¼¥È¤·¤Ê¤¤»þ¤Ë¡Ë¤¤¤¯¤Ä¤«¤Î
+ PCI¤Î 5428 ¤ò´ð¤Ë¤·¤¿¥«¡¼¥É¤Ç´Ñ¬¤µ¤ì¤Þ¤¹¡£
+</descrip>
+¤½¤Î¾¤Î²èÌÌÉÁ²è¤Ë´Ø¤¹¤ëÌäÂ꤬À¸¤¸¤¿¾ì¹ç¤Ï¡¢ ( <tt>&dquot;no_bitblt&dquot;</tt> ¤¬
+½õ¤±¤Ë¤Ê¤é¤Ê¤¤¾ì¹ç¤Ë) <tt>&dquot;noaccel&dquot;</tt> ¥ª¥×¥·¥ç¥ó¤ò»î¤·¤Æ¤ß¤Þ¤·¤ç¤¦¡£
+
+¤³¤Îʸ½ñ¤Ëµ­½Ò¤Î̵¤¤¥É¥é¥¤¥Ð¤Ë´Ø¤¹¤ëÌäÂê¡¢Ëô¤Ï¥¢¥¯¥»¥é¥ì¡¼¥¿µ¡Ç½¤Ë¤Ä¤¤
+¤Æ¥Ð¥°¤òȯ¸«¤·¤¿¾ì¹ç¤Ï XFree86 ¥Á¡¼¥à¡Ê¸½ºß¡¢¥É¥é¥¤¥Ð¤ÎÊݼé¤Ï
+<it>H.Hanemaayer@inter.nl.net</it> ¤Ç¹Ô¤Ã¤Æ¤¤¤Þ¤¹¡Ë¤ËÏ¢Íí¤ò²¼¤µ¤ë¤«¡¢
+&dquot;<it>comp.windows.x.i386unix</it>&dquot; ¤È¤¤¤¦¥Ë¥å¡¼¥¹¥°¥ë¡¼¥×¤ËÅê¹Æ¤·¤Æ²¼¤µ
+¤¤¡£
+
+<!--
+In fact, reports (success or failure) are very welcome, especially
+on configurations that have not been tested. You can do this
+via the BetaReport form (mail to report@XFree86.org). You may want to
+keep an eye on forthcoming beta releases at <it>www.xfree86.org</it>.
+-->
+¼ÂºÝ¡¢ÆÃ¤Ë¥Æ¥¹¥È¤·¤Æ¤¤¤Ê¤¤¹½À®¤Ç¤Î (À®¸ù¤ä¼ºÇÔ¤Î) Êó¹ð¤ò´¿·Þ¤·¤Æ¤¤¤Þ
+¤¹¡£¥Ù¡¼¥¿¥ì¥Ý¡¼¥È (BetaReport) ÍÑ»æ¤ò»È¤Ã¤Æ (report@XFree86.org ¤Ë
+¥á¡¼¥ë¤Ç) Êó¹ð¤·¤Æ¤¯¤À¤µ¤¤¡£<it>www.xfree86.org</it> ¤«¤é¤Î¿·´©Í½Äê¤Î
+¥Ù¡¼¥¿ÈǤˤ´´üÂÔ¤¯¤À¤µ¤¤¡£
+
+<!--
+<sect> Tested Configurations <p>
+
+This is a list of configurations that has received testing with one or
+more of the changes introduced in the current version XFree86 3.2. The
+amount of testing is very small for some of the configurations, and the
+summaries may be incomplete. If you can contribute, please do so. For
+the latest information check the latest version of this document on
+<it>www.xfree86.org</it>.
+-->
+<sect> ¥Æ¥¹¥È¤·¤¿µ¡´ï¹½À® <p>
+
+¸½¹Ô¤Î XFree86 3.2 ¤Ç¾Ò²ð¤·¤¿¤Ò¤È¤ÄËô¤Ï¤½¤ì°Ê¾å¤ÎÊѹ¹¤Î¥Æ¥¹¥È·ë²Ì¤ò¼õ¤±
+¼è¤Ã¤¿µ¡´ï¹½À®¤Î°ìÍ÷¤ò¼¨¤·¤Þ¤¹¡£¤¤¤¯¤Ä¤«¤Îµ¡´ï¹½À®¤Ç¤Î¥Æ¥¹¥È·ë²Ì¤ÎÎ̤Ï
+¤È¤Æ¤â¾¯¤Ê¤¯¡¢¤Þ¤È¤á¤ÏÉÔ´°Á´¤Ç¤¹¡£¹×¸¥½ÐÍè¤ë»þ¤Ï¡¢¤ª´ê¤¤¤·¤Þ¤¹¡£
+ºÇ¿·¾ðÊó¤Ï <it>www.xfree86.org</it> ¤Ë¤¢¤ë¤³¤Îʸ½ñ¤ÎºÇ¿·ÈǤòÄ´¤Ù¤Æ
+¤¯¤À¤µ¤¤¡£
+
+<descrip>
+<!--
+<tag>CL-GD5426 on VL-bus</tag>
+
+<tag>CL-GD5429 on VL-bus</tag>
+ BitBLT operation should be fixed. MMIO does not work.
+
+<tag>CL-GD5434 with 2MB memory on VL-bus</tag>
+ MMIO operation is supported.
+
+<tag>CL-GD5434 with 1MB memory on PCI bus</tag>
+ 8bpp, 16pp and 24bpp work OK. 16bpp no longer has "static"
+ problems. MMIO operation is supported.
+
+<tag>CL-GD5446 with 2MB memory on PCI bus</tag>
+ 32bpp probably doesn't work. 8bpp and 16bpp should work without
+ any FIFO-related problems, and without requiring "fifo_conservative".
+
+<tag>CL-GD5462 with 2MB memory on PCI bus</tag>
+
+<tag>CL-GD5462 with 4MB memory on PCI bus</tag>
+
+<tag>CL-GD5464 with 4MB memory on PCI bus</tag>
+ Works OK at 8bpp, 16bpp, 24bpp and 32bpp.
+
+<tag>CL-GD6440 on ISA bus</tag>
+
+<tag>CL-GD7543 on PCI bus</tag>
+ Apparently broken in this release. On 800x600 displays, the
+ recommended dot clock is 40 MHz for TFT and 33.7 MHz for a DSTN
+ panel, with corresponding horizontal syncs of 33.7 kHz for TFT and
+ 38.6 kHz for DSTN.
+-->
+<tag>VL ¥Ð¥¹¾å¤Î CL-GD5426</tag>
+
+<tag>VL ¥Ð¥¹¾å¤Î CL-GD5429</tag>
+ BitBLT Áàºî¤ò½¤Àµ¤·¤Þ¤·¤¿¡£ MMIO ¤Ë¤Ä¤¤¤Æ¤Ïºî¶È¤·¤Æ¤Þ¤»¤ó¡£
+
+<tag>VL ¥Ð¥¹¾å¤Î 2M ¥Ð¥¤¥È¤Î¥á¥â¥ê¤òÅëºÜ¤·¤¿ CL-GD5434</tag>
+ MMIO operation is supported.
+
+<tag>PCI ¥Ð¥¹¾å¤Î 1M ¥Ð¥¤¥È¤Î¥á¥â¥ê¤òÅëºÜ¤·¤¿ CL-GD5434</tag>
+ 8bpp, 16pp ¤È 24bpp ¤Ïưºî¤·¤Þ¤¹¡£ 16bpp ¤ÏºÇÁá "ÀÅŪ¤Ê"
+ ÌäÂê¤Ï¤¢¤ê¤Þ¤»¤ó¡£ MMIO Áàºî¤Ï¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó¡£
+
+<tag>PCI ¥Ð¥¹¾å¤Î 2M ¥Ð¥¤¥È¤Î¥á¥â¥ê¤òÅëºÜ¤·¤¿ CL-GD5446</tag>
+ 32bpp ¤Ï¿ʬưºî¤·¤Þ¤»¤ó¡£ 8bpp ¤È 16bpp ¤Ï FIFO ¤Ë´ØÏ¢¤·¤¿
+ ÌäÂê¤È "fifo_conservative" ¤¬É¬Íפʤ³¤È¤ò½ü¤¤¤ÆÆ°ºî¤·¤Þ¤¹¡£
+
+<tag>PCI ¥Ð¥¹¾å¤Î 2M ¥Ð¥¤¥È¤Î¥á¥â¥ê¤òÅëºÜ¤·¤¿ CL-GD5462</tag>
+
+<tag>PCI ¥Ð¥¹¾å¤Î 4M ¥Ð¥¤¥È¤Î¥á¥â¥ê¤òÅëºÜ¤·¤¿ CL-GD5462</tag>
+
+<tag>PCI ¥Ð¥¹¾å¤Î 4M ¥Ð¥¤¥È¤Î¥á¥â¥ê¤òÅëºÜ¤·¤¿ CL-GD5464</tag>
+ 8bpp, 16bpp, 24bpp ¤È 32bpp¤Çưºî¤·¤Þ¤¹¡£
+
+<tag>ISA ¥Ð¥¹¾å¤Î CL-GD6440</tag>
+
+<tag>PCI ¥Ð¥¹¾å¤Î CL-GD7543</tag>
+ ¤³¤ÎÈǤǤϸ«¤¿¤È¤³¤íưºî¤·¤Þ¤»¤ó¡£800x600 ɽ¼¨¤Ç¡¢¿ä¾©
+ ¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ï TFT ¤Ç¤Ï 40 MHz¡¢DSTN ¤Ç¤Ï 33.7 MHz ¤Ç
+ Ŭ¹ç¤¹¤ë¿åʿƱ´ü¼þÇÈ¿ô¤Ï TFT ¤Ç¤Ï 33.7 khz ¤Ç DSTN ¤Ç¤Ï
+ 38.6 khz ¤Ç¤¹¡£
+
+</descrip>
+
+<!--
+Some configurations for which no up-to-date testing data is available:
+
+<descrip>
+<tag>CL-GD5430, and CL-GD5436 and CL-GD5446 with 1MB memory</tag>
+ It would be nice to know whether these chips needs the same
+ treatment at 16bpp as the CL-GD5434 with 1MB memory does.
+ This also applies to the CL-GD754x series.
+
+<tag>CL-GD5436 and CL-GD5446 with 1MB memory</tag>
+ In particular the FIFO settings for this configuration are uncertain.
+
+<tag>CL-GD754x</tag>
+ Support for these chips was reported broken in 3.1.2G, although the
+ 7548 was reported to work in some cases.
+-->
+ºÇ¿·¤Ç¤Ï¤Ê¤¤¥Æ¥¹¥È¤·¤¿¤¤¤¯¤Ä¤«¤Îµ¡´ï¹½À®¤¬¤¢¤ê¤Þ¤¹:
+<descrip>
+<tag>1M ¥Ð¥¤¥È¤Î¥á¥â¥ê¤òÅëºÜ¤·¤¿ CL-GD5430, CL-GD5436 ¤È CL-GD5446</tag>
+ ¤³¤ì¤é¤Î¥Á¥Ã¥×¤ò 1M ¥Ð¥¤¥È¤Î¥á¥â¥ê¤¬¤¢¤ë CL-GD5434 ¤È¤·¤Æ 16bpp ¤Ç
+ ¤É¤¦¼è¤ê°·¤¦¤«¤É¤¦¤«¤òÃΤë¤Î¤ËÁÇÀ²¤·¤¤¤Ç¤¹¡£
+ CL-GD754x ·ÏÎó¤Ë¤âŬ±þ½ÐÍè¤Þ¤¹¡£
+
+<tag>1M ¥Ð¥¤¥È¤Î¥á¥â¥ê¤òÅëºÜ¤·¤¿ CL-GD5436 ¤È CL-GD5446</tag>
+ ÆÃ¤Ë¤³¤Î¹½À®¤Ç¤Î FIFO ¤ÎÀßÄê¤ÏÉÔ°ÂÄê¤Ç¤¹¡£
+
+<tag>CL-GD754x</tag>
+ 3.1.2G ¤Ç¤Ï¤³¤ì¤é¤Î¥Á¥Ã¥×¤Ç¤Ïưºî¤·¤Þ¤»¤ó¤¬¡¢¤¤¤¯¤Ä¤«¤Î¾ì¹ç¤Ç 7548
+ ¤Ïưºî¤·¤¿¤ÈÊó¹ð¤¬¤¢¤ê¤Þ¤·¤¿¡£
+</descrip>
+
+<!--
+<sect> ¥É¥é¥¤¥Ð¤ÎÊѹ¹ÅÀ <p>
+
+XFree86 3.1 ¤«¤é¼¡¤Î¥Ð¥°¤ò½¤Àµ¤·¤Þ¤·¤¿:
+<itemize>
+<item> ¥¢¥¯¥»¥é¥ì¡¼¥¿µ¡Ç½¤Î 14 ¥Ô¥¯¥»¥ë¤ÎÉý¤Î¥Õ¥©¥ó¥È¤Îɽ¼¨¤Î¥Ð¥°
+<item> 8bpp ¤Ç¥ê¥Ë¥¢¥¢¥É¥ì¥Ã¥·¥ó¥°µ¡Ç½¤ò»È¤Ã¤¿¤È¤­¤Ë¾¤Î VC ¤«¤é
+ ÀÚ¤êÂØ¤¨¤¿¤È¤­¥µ¡¼¥Ð¤¬²õ¤ì¤ë¡£
+<item> 542x ¾å¤Ç 16bpp ¤Î»þ VC ÀÚ¤êÂØ¤¨¤ò¹Ô¤Ã¤¿¤È¤­ DAC ¥×¥í¥°¥é¥à¤¬
+ ¸Ç¤Þ¤Ã¤Æ¤·¤Þ¤¦¡£
+<item> ¥É¥é¥¤¥Ð¤¬¥µ¡¼¥Ð¤Îõºº¤·¤¿¾ðÊó¤ò¸µ¤ËÌᤷ¤Æ 543x ¤Î¥ì¥¸¥¹¥¿
+ ¤ÎÆâÍÆ¤òÇ˲õ¤¹¤ë¡£
+<item> 543x ¤Ç 8bpp ¤Î»þ¤Î¥ê¥Ë¥¢¥¢¥É¥ì¥Ã¥·¥ó¥°¡Ê16/32bpp ¤ò¹½À®¤·¤è
+ ¤¦¤È¤¹¤ë¤È¼ºÇÔ¤¹¤ë¡Ë
+<item> 16/32bpp ¤Ç¤Î¥Ï¡¼¥É¥¦¥§¥¢¥«¡¼¥½¥ë¤Î¿§ÉÕ¤±
+
+<sect> Driver Changes <p>
+
+Changes since XFree86 3.1.2:
+<itemize>
+<item> Display-refresh problems for CL-GD5434 with 1MB memory at 16bpp
+ are fixed.
+<item> Some problems with Memory-Mapped I/O operation have been fixed.
+<item> A problem with unaligned bitmaps has been fixed.
+<item> The CRT FIFO setting for the 5436/46 has been fixed.
+<item> Opaque window moves are now accelerated at 16/24/32bpp.
+-->
+<sect> ¥É¥é¥¤¥Ð¤ÎÊѹ¹ÅÀ <p>
+
+XFree86 3.1.2 ¤«¤é¼¡¤Î¥Ð¥°¤ò½¤Àµ¤·¤Þ¤·¤¿:
+<itemize>
+<item> 16bpp ¤Ç 1M ¥Ð¥¤¥È¤òÅëºÜ¤·¤¿ CL-GD5434 ¤Çµ¯¤³¤ëºÆÉ½¼¨¤ÎÌäÂê¤ò
+ ½¤Àµ¤·¤Þ¤·¤¿¡£
+<item> ¥á¥â¥ê¥Þ¥Ã¥×¥É I/O Áàºî¤Çµ¯¤³¤ëÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+<item> ¥Ó¥Ã¥È¥Þ¥Ã¥×¤¬À°Îó¤Ç¤­¤Ê¤¤ÌäÂê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+<item> 5436/46 ¤Ç¤Î CRT FIFO ¤ÎÀßÄê¤ò½¤Àµ¤·¤Þ¤·¤¿¡£
+<item> 16/24/32bpp ¤Ç¤ÎÉÔÆ©ÌÀ¤Ê¥¦¥£¥ó¥É¥¦¤Î°Üư¤ò¹â®²½¤·¤Þ¤·¤¿¡£
+</itemize>
+
+<!--
+XFree 3.1.1 ¤Ç¤Î¿·µ¡Ç½:
+<itemize>
+<item> ¤¤¤¯¤é¤«¤Îɽ¼¨Â®ÅÙ¤ÎÀ­Ç½¸þ¾å¡£
+<item> 16/32bpp ¤Ç¤Î¥¹¥¯¥í¡¼¥ë¡¿¥Æ¥­¥¹¥È¡¿Åɤê¤Ä¤Ö¤·¤Î²Ã®²½¡£
+<item> ¥×¥í¥°¥é¥Þ¥Ö¥ë¥¯¥í¥Ã¥¯¤Î¥µ¥Ý¡¼¥È¡£
+<item> 543x ¤Ç¤Î¥á¥â¥ê¥Þ¥Ã¥×¥É I/O ¤Î¥µ¥Ý¡¼¥È¡£
+<item> 5434 ¤Ç¤Î 110 MHz ¤Ø¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¸þ¾å¤Î¥µ¥Ý¡¼¥È¡£
+<item> &dquot;cl64xx&dquot; ¥É¥é¥¤¥Ð¤Ç CL6440 ¤Î¥µ¥Ý¡¼¥È¡£
+</itemize>
+
+XFree86 3.1.1 ¤«¤é¤ÎÊѹ¹ÅÀ:
+<itemize>
+<item> ʸ»úɽ¼¨µ¡Ç½¤Ç¤Î¥á¥â¥êÇ˲õ¤Î½¤Àµ¡£
+<item> CL-GD5434 ¥ì¥Ó¥¸¥ç¥ó E °Ê¹ß¤Ç¤Î¥É¥Ã¥È¥¯¥í¥Ã¥¯¤ò 135 MHz ¤Ë¸þ
+ ¾å¡£
+<item> ¹â¥É¥Ã¥È¥¯¥í¥Ã¥¯¤Ç¤Î²èÌ̺ÆÉ½¼¨¥¨¥é¡¼¡Ê¥¸¥Ã¥¿¡Ë¤ò²ò·è¤¹¤ë¤¿¤á¤Î
+ ¤è¤ê¥Ð¥é¥ó¥¹¤Î¤È¤ì¤¿ FIFO ¤ÎÀßÄê¡£
+<item> ¥á¥â¥ê¥Þ¥Ã¥×¥É I/O (&dquot;mmio&dquot; ¥ª¥×¥·¥ç¥ó) ¤ÎÁàºîÀ­¸þ¾å (5429 Âбþ
+ ¤ÎÉûºîÍѤÎÇÓ½ü)¡£
+<item> Éé¤ÎÂ礭¤µ¤Î¶ë·¿Åɤê¤Ä¤Ö¤·¤ò¹Ô¤Ã¤¿¤È¤­¤ÎÀøºßŪ¤Ê¥µ¡¼¥ÐÇ˲õ¤ò
+ ²óÈò¤¹¤ëÀµÅöÀ­¥Á¥§¥Ã¥¯¤òÄɲá£
+<item> BitBLT ¥¨¥ó¥¸¥ó¤ò»È¤ï¤Ê¤¤¤Ç¥¹¥¯¥í¡¼¥ë¤ò¤·¤¿»þȯÀ¸¤¹¤ëɽ¼¨¥¨
+ ¥é¡¼¤ò½¤Àµ¡£
+<item> 543x PCI ¤Î´ðÄ쥢¥É¥ì¥¹¤Îǧ¼±¡£
+<item> CL-GD5436 ¤Î¸ÂÄꥵ¥Ý¡¼¥È¡£
+<item> 5429 Âбþ¤Î VLB ¤Î½é´üÃͤδðÄ쥢¥É¥ì¥¹¤ò 0x03e00000 ¤È¤·¤¿¡£
+</itemize>
+
+New features in XFree86 3.2:
+<itemize>
+<item> Largely untested accelerated support for the CL-GD754x series of
+ laptop chips.
+<item> Support for 5446 chip.
+<item> Support and accelerated features for 546x chips.
+<item> Support for packed 24bpp mode on most chips (including devices
+ with 1MB memory).
+</itemize>
+-->
+XFree86 3.2 ¤Ç¤Î¿·µ¡Ç½:
+<itemize>
+<item> ¼ç¤Ê¤â¤Î¤Ï¥é¥Ã¥×¥È¥Ã¥×ÍÑ¥Á¥Ã¥×¤Î CL-GD754x ·ÏÎóÂбþ¤Î̤¥Æ¥¹¥È¤Î
+ ¥¢¥¯¥»¥é¥ì¡¼¥¿¤Î¥µ¥Ý¡¼¥È
+<item> 5446 ¥Á¥Ã¥×¤Î¥µ¥Ý¡¼¥È
+<item> 546x ¥Á¥Ã¥×¤Î¥¢¥¯¥»¥é¥ì¡¼¥¿¤Î¥µ¥Ý¡¼¥È
+<item> 1M ¥Ð¥¤¥È¤Î¥á¥â¥ê¤òÅëºÜ¤·¤¿ËؤɤΥÁ¥Ã¥×¤Ç¥Ñ¥Ã¥¯¥È 24 bpp ¤Î
+ ¥µ¥Ý¡¼¥È
+</itemize>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/cirrus.sgml,v 3.2 1997/01/26 04:34:29 dawes Exp $
+</verb>
+<hrule>
+¤³¤Î¥Õ¥¡¥¤¥ë¤Ï xc/programs/Xserver/hw/xfree86/doc/sgml/cirrus.sgml,v 3.17 1996/10/26 09:38:57 ¤ò¡¢²¬ËÜ °ì¹¬
+( Kazuyuki Okamoto <url url="mailto:ikko-@pacific.rim.or.jp"
+name="&lt;ikko-@pacific.rim.or.jp&gt;"> ) ¤¬ XFree86 3.2 ¤ò
+ÆüËܤǥ¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¿Í¸þ¤±¤ËÏÂÌõ¤·¤¿¤â¤Î¤Ç¤¹¡£¤³¤³¤¬¤ª¤«¤·¤¤¤È¤«¡¢
+¤³¤³¤Ï¤³¤¦¤·¤¿¤Û¤¦¤¬¤¤¤¤¤È¤¤¤Ã¤¿¤´°Õ¸«¤¬¤¢¤ê¤Þ¤·¤¿¤é¡¢ÅŻҥ᡼¥ë¤Ç
+¤ªÃΤ餻²¼¤µ¤¤¡£
+¸¶Ê¸¤ÎÃøºî¸¢¤Ï XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤Ë¤¢¤ê¤Þ¤¹¡£¤³¤ÎÏÂÌõ¤ÎÃøºî¸¢¤Ï
+XFree86 ¥×¥í¥¸¥§¥¯¥È¼Ò¤È²¬ËÜ¡¡°ì¹¬¤Ë¤¢¤ê¤Þ¤¹¤¬¡¢¤³¤ÎÏÂÌõ¤ÎÉÔ¶ñ¹ç¤Ï»ä
+¤Ë¡¢ÅŻҥ᡼¥ë¤ÇÁ÷¤Ã¤Æ²¼¤µ¤¤¡£
+<hrule>
+&lsqb;EOF&rsqb;
+
+</article>
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/read98.sgml b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/read98.sgml
new file mode 100644
index 000000000..42f89c501
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/Japanese/sgml/read98.sgml
@@ -0,0 +1,169 @@
+<!doctype linuxdoc system>
+
+<article>
+
+<!-- Title information -->
+<title> XFree86 PC98 Dependent Information
+<author> The XFree86 Project Inc. and X98 CORE TEAM
+<date> 1999ǯ 7·î 19Æü
+<abstract>
+¤³¤Î¥É¥­¥å¥á¥ó¥È¤Ç¤Ï¡¢PC98¸ÇÍ­¤Î»ö¹à¤Ë¤Ä¤¤¤Æ²òÀ⤷¤Þ¤¹¡£
+PC/AT¸ß´¹µ¡¤È¶¦Ä̤λö¹à¤Ë¤Ä¤¤¤Æ¤Ï¡¢¶¦Ä̤Υɥ­¥å¥á¥ó¥È¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡£
+</abstract>
+
+<sect>ËÜ¥ê¥ê¡¼¥¹¤Ë¤Ä¤¤¤Æ
+<p>ËÜ¥ê¥ê¡¼¥¹¤Ç¤Ï¡¢PC98ÍÑX¥µ¡¼¥Ð¤ÏPC/AT¸ß´¹µ¡ÍÑX¥µ¡¼¥Ð¤ÈÅý¹ç(¥Õ¥¡¥¤¥ë̾:
+XFree86)¤µ¤ì¤Æ¤ª¤ê¡¢½¾Íè¤Î¥Ü¡¼¥É/¥Á¥Ã¥×¥»¥Ã¥ÈËè¤Î¥µ¡¼¥Ð¤â¤Ê¤¯¤Ê¤ê¤Þ¤·¤¿¡£
+¤Þ¤¿¡¢³Æ¥É¥é¥¤¥Ð¤Ï¤¹¤Ù¤ÆSVGA¥Ù¡¼¥¹¤Ç¡¢XF86_S3¥Ù¡¼¥¹¤Î¥É¥é¥¤¥Ð¤Ï¤¢¤ê¤Þ¤»¤ó¡£
+¸½ºß¤Î¤È¤³¤í¡¢PC98¤Çưºî¤·¤Æ¤¤¤ë¤Î¤Ï¡¢mga¥É¥é¥¤¥Ð¤Î¤ß¤Ç¤¹¡£Millennium¡¢
+Mystique¤Î¥Ü¡¼¥É¤ò¤ª»ý¤Á¤ÎÊý°Ê³°¤Ï¡¢3.3¥Ù¡¼¥¹(ex. 3.3.3.1, 3.3.4)¤Î´Ä¶­¤ò
+¸æÍøÍѲ¼¤µ¤¤¡£EGC¤äPEGC¤¹¤éÍøÍѤǤ­¤Þ¤»¤ó¡£³«È¯¥á¥ó¥Ð¤¬Èó¾ï¤Ë¾¯¤Ê¤¯¤Ê¤Ã¤Æ
+¤¤¤ë¤Î¤Ç¡¢³«È¯¤Ë¶½Ì£¤¬¤ª¤¢¤ê¤ÎÊý¤ÏX98 Core Team¤Þ¤Ç¡¢¸æÏ¢Íí²¼¤µ¤¤¡£</p>
+
+<p>XF86Config¤äµ¯Æ°»þ¤Î¥ª¥×¥·¥ç¥óÅù¤ÎÊѹ¹¤Ë¤Ä¤¤¤Æ¤Ï¡¢RELNOTES¤Ë¾Ü¤·¤¯½ñ¤¤¤Æ
+¤¢¤ê¤Þ¤¹¤Î¤Ç¡¢»²¾È¤·¤Æ²¼¤µ¤¤¡£/usr/X11R6/lib/X11/XF86Config.98¤¬¡¢PC98ÍÑ
+¤ÎXF86Config¤Î¿÷·¿¤Ç¤¹¡£</p>
+
+<sect>¥µ¥Ý¡¼¥È¾õ¶·<p>
+Åý¹çX¥µ¡¼¥Ð(XFree86)¤Ï¡¢°Ê²¼¤Î³ÈÄ¥¥Ó¥Ç¥ª¥Ü¡¼¥É¡¢Æâ¢¥Ó¥Ç¥ª¥·¥¹¥Æ¥à¤ËÂбþ
+¤·¤Æ¤¤¤Þ¤¹¡£¸Ä¡¹¤ÎÂбþ¡¢Æ°ºî¾õ¶·¤Ë¤Ä¤¤¤Æ¤ÏVideoBoard98¤ò»²¾È¤·¤Æ²¼¤µ¤¤¡£
+</p>
+
+<sect1>¥µ¥Ý¡¼¥È¥«¡¼¥É°ìÍ÷ <p>
+<verb>
+ ¥Ù¥ó¥À¡¼ ¥«¡¼¥É̾¾Î ¥µ¡¼¥Ð
+ ------------- ----------------------------------------------- -------
+ NEC ¥Õ¥ë¥«¥é¡¼¥¦¥£¥ó¥É¥¦¥¢¥¯¥»¥é¥ì¡¼¥¿¥Ü¡¼¥É X2 XFree86
+ Matrox MGA Millennium(PC/AT ¸ß´¹µ¡ÍÑ) XFree86
+</verb></p></sect1>
+
+<sect1>¥µ¥Ý¡¼¥ÈÆâ¢¥Ó¥Ç¥ª¥·¥¹¥Æ¥à°ìÍ÷<p>
+<verb>
+ ¥Ù¥ó¥À¡¼ ¥Á¥Ã¥×¥»¥Ã¥È ¥µ¡¼¥Ð
+ ------------- ----------------------------------------------- -------
+ NEC MGA Millennium/Mystique XFree86
+</verb></p>
+
+<sect>¶¦ÄÌ»ö¹à<p>
+<descrip>
+<tag>PC98¤Î»ØÄê</tag>
+ Åý¹çX¥µ¡¼¥Ð¤Ç¤Ï¡¢ÊªÍý¥¢¥É¥ì¥¹0xf8e80¤«¤é¤Î2¥Ð¥¤¥È¤ò»²¾È¤·¡¢0x98¡¢
+ 0x21¤Î¥Ç¡¼¥¿¤¬¤¢¤ì¤ÐPC98¤È¼«Æ°Ç§¼±¤·¡¢µ¯Æ°»þ¤Î¥í¥°¤Ë
+
+ (--) Japanese PC98 architecture
+
+ ¤È½ÐÎϤ·¤Þ¤¹¡£Âç¿¿ô¤ÎPC98(Millennium,Mystique¤òÍøÍѤǤ­¤ëµ¡¼ï¤Ç¤Ï
+ 100%)¤¬¤³¤ì¤Çǧ¼±¤µ¤ì¤ëȦ¤Ç¤¹¤¬¡¢Ëü°ì¾åµ­¤Îɽ¼¨¤¬¤µ¤ì¤Ê¤«¤Ã¤¿¾ì¹ç
+ ¤Ï¡¢XF86Config¤ÎSection "ServerFlags"¤Ë¡¢
+
+ Option "PC98"
+
+ ¤Î»ØÄê¤òÆþ¤ì¤Æ²¼¤µ¤¤¡£¤³¤ì¤ÇPC98¤Èǧ¼±¤µ¤ì¡¢¥í¥°¤Ë
+
+ (**) Japanese PC98 architecture
+
+ ¤È½ÐÎϤµ¤ì¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
+<tag>xf86config</tag>
+ PC98ÍѤ˰ܿ¢¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£/usr/X11R6/lib/X11/XF86Config.98¤ò
+ XF86Config¤È¥ê¥Í¡¼¥à¤·¤Æ»ÈÍѤ·¤Æ²¼¤µ¤¤¡£
+<tag>xvidtune</tag>
+ ¸·³Ê¤Êưºî³Îǧ¤ò¹Ô¤Ã¤Æ¤¤¤Þ¤»¤ó¤¬¡¢Æ°ºî¤¹¤ë¤è¤¦¤Ç¤¹¡£
+<tag>SuperProbe</tag>
+ °Ü¿¢¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£¥Ï¥ó¥°¥¢¥Ã¥×¤ä¥Ó¥Ç¥ª¥Ü¡¼¥É¤ò²õ¤¹¶²¤ì¤¬¤¢¤ë
+ ¤Î¤ÇÀäÂФ˻ÈÍѤ·¤Ê¤¤¤Ç²¼¤µ¤¤¡£
+<tag>XF86Setup</tag>
+ PC/AT¸ß´¹µ¡¤ò´Þ¤á¡¢ËÜ¥ê¥ê¡¼¥¹¤Ç¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£
+ /usr/X11R6/lib/X11/XF86Config.98¤òXF86Config¤È¥ê¥Í¡¼¥à¤·¤Æ»ÈÍÑ
+ ¤·¤Æ²¼¤µ¤¤¡£
+<tag>scanpci</tag>
+ ¸·³Ê¤Êưºî³Îǧ¤ò¹Ô¤Ã¤Æ¤¤¤Þ¤»¤ó¤¬¡¢Æ°ºî¤¹¤ë¤è¤¦¤Ç¤¹¡£
+<tag>¥Ç¥Õ¥©¥ë¥È¤Î¥³¥ó¥Ñ¥¤¥ë»þ¤ÎÀßÄê</tag>
+ ÀΤÎPC98ÍÑ¥µ¡¼¥Ð¤È°Û¤Ê¤ê¡¢XFree86¤Ï¡¢GetValuesBC NO,BuildPexExt
+ YES,BuildXIE YES¤ÈÄêµÁ¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤´Ãí°Õ²¼¤µ¤¤¡£xengineÅù¤Ç
+ ¤ÏGetValues¤Ë¤Ä¤¤¤Æ¥½¡¼¥¹¤Î½¤Àµ¤¬É¬ÍפǤ¹¡£
+<tag>16MB¥·¥¹¥Æ¥à¶õ´Ö¤ÎÀßÄê</tag>
+ ¥Ü¡¼¥É/¥Á¥Ã¥×¥»¥Ã¥È¤Ë¤è¤Ã¤Æ¤Ï¡¢15M-16M¤ÎÎΰè¤ò»ÈÍѤ¹¤ëʪ¤¬¤¢¤ê¤Þ¤¹¡£
+ ¤½¤ÎÍͤʥܡ¼¥É¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç¡¢¥·¥¹¥Æ¥à¥»¥Ã¥È¥¢¥Ã¥×¥á¥Ë¥å¡¼¤Ç¡¢
+ 16MB¥·¥¹¥Æ¥à¶õ´Ö¤ò¡ÖÀÚ¤êÎ¥¤¹¡×¤Ë¤·¤Æ¥µ¡¼¥Ð¤òµ¯Æ°¤¹¤ë¤È¡¢¥Ï¥ó¥°¥¢¥Ã¥×
+ Åù¤ò°ú¤­µ¯¤³¤¹²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡£Millennium¤äMystique¤Ë´Ø¤·¤Æ¤Ï¤³¤Î
+ ¶õ´Ö¤ò»ÈÍѤ·¤Þ¤»¤ó¤¬¡¢¤³¤Î¶õ´Ö¤ò»ÈÍѤ·¤Ê¤¤¤È¤Ï¤Ã¤­¤êʬ¤«¤ë¤â¤Î°Ê³°
+ ¤ò»È¤¦¾ì¹ç¤Ï¡¢¤«¤Ê¤é¤º¡Ö»ÈÍѤ¹¤ë¡×¤Ë¤·¤Æ²¼¤µ¤¤¡£
+<tag>XKB</tag>
+ XF86Config¤ÎSection "InputDevice"¤Ç¡¢
+<verb>
+ XkbRules "xfree86"
+ XkbModel "pc98"
+ XkbLayout "nec/jp"
+</verb>
+ ¤Î»ØÄê¤ò¤·¤Æ²¼¤µ¤¤¡£
+<tag>BusID</tag>
+ XF86Config¤ÎSection "Device"¤Ç¡¢É¬¤º
+<verb>
+ BusID "0:10:0"
+</verb>
+ ¤Î¤è¤¦¤Ê»ØÄê¤ò¤·¤Æ²¼¤µ¤¤¡£¥í¥°¤Ë
+<verb>
+ (--) PCI: (0:7:0) NEC unknown chipset (0x0009) rev 2
+ (--) PCI: (0:12:0) S3 968 rev 0, Mem @ 0x24000000/25
+ (--) PCI: (0:14:0) Matrox MGA 2064W rev 1, Mem @ 0x20004000/14, 0x21000000/23
+</verb>
+ ¤Î¤è¤¦¤Ë½Ð¤Æ¤¤¤Æ¡¢Millennium¤ò»ÈÍѤ¹¤ë¾ì¹ç¤Ï¡¢"0:14:0"¤ò»ØÄꤷ¤Þ¤¹¡£
+ S3 968¤Ï»ÈÍѤǤ­¤Þ¤»¤ó¡£Ç°¤Î°Ù¡£
+<tag>VT switch</tag>
+ FreeBSD(98)¤Ç¤Ï¤Ç¤­¤Ê¤¯¤Ê¤Ã¤Æ¤¤¤ë¤è¤¦¤Ç¤¹¡£PANIX for 98¤Ç¤â¤Ç¤­¤Þ¤»¤ó¡£
+<tag>CTRL,GRPH,+/- ¤Ë¤è¤ë²òÁüÅÙÀÚÂØ¤¨</tag>
+ ¤Ç¤­¤Ê¤¯¤Ê¤Ã¤Æ¤¤¤ë¤è¤¦¤Ç¤¹¡£
+</descrip>
+
+<sect>¥É¥é¥¤¥Ð¤Ë¤Ä¤¤¤Æ
+<sect1>mga¥É¥é¥¤¥Ð<p>
+ NEC¤ÎÆâ¢¥¢¥¯¥»¥é¥ì¡¼¥¿(Matrox Millennium/Mystique), PC/AT¸ß´¹µ¡ÍÑ
+ Millennium ¤Çưºî¤¹¤ë¥É¥é¥¤¥Ð¤Ç¤¹¡£</p>
+<sect2>XF86Config¤ÎÀßÄê<p>
+ README.MGAÆâ¤Ë²òÀ⤵¤ì¤Æ¤¤¤ë¥ª¥×¥·¥ç¥ó¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£Ä̾ï¤ÏÆÃ¤Ë
+ ²¿¤â»ØÄꤹ¤ëɬÍ×̵¤¤È¦¤Ç¤¹¡£
+<sect2>Êó¹ð¤µ¤ì¤Æ¤¤¤ëÌäÂê<p>
+<itemize>
+ <ITEM>Millennium¤Ç¤Ï¡¢Modeline¤ÎÀßÄê¤Ë¤è¤Ã¤Æ¤Ï24bpp¤Ç½Ä¤ËÀþ
+ ¤¢¤ë¤¤¤Ï¼ÊÌÏÍͤΥΥ¤¥º¤¬½Ð¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£
+ <ITEM>Millennium¤Ç¤Ï¡¢½é´ü²½¤¬ÉÔ´°Á´¤Ê¤¿¤á¡¢»ÈÍÑÁ°¤Ë3.3¥Ù¡¼¥¹¤Î
+ ¥µ¡¼¥Ð¤òµ¯Æ°¤·¤Æ¤ª¤«¤Ê¤¤¤È¥Ï¥ó¥°¥¢¥Ã¥×¤¹¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£°ìöµ¯Æ°
+ ¤¹¤ì¤ÐÅŸ»¤òOFF¤Ë¤¹¤ë¤Þ¤Ç¤ÏÀµ¾ï¤Ëưºî¤·¤Þ¤¹¡£
+ <ITEM>Linux/98¤Ç¤Ï¡¢beta 14°Ê¹ß¤Î¥«¡¼¥Í¥ë¤Ç¤Ê¤¤¤È»ÈÍÑÃæ¤Ë¥Ï¥ó¥°
+ ¥¢¥Ã¥×¤¹¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¡£¤³¤ì¤òÈò¤±¤ë¤Ë¤Ï¡¢root¸¢¸Â¤Ë¤Ædmesg
+ -n 1 ¤ò¼Â¹Ô¤¹¤ë¤È¤¤¤¤¤è¤¦¤Ç¤¹¡£
+</itemize>
+<sect2>¤½¤Î¾<p>
+<itemize>
+ <ITEM>PC/AT¸ß´¹µ¡ÍѤÎMillennium¤ò»ÈÍѤ¹¤ë¾ì¹ç¤Ï¡¢VGA¤òdisable
+ ¤·¤Æ²¼¤µ¤¤¡£
+ <ITEM>PC/AT¸ß´¹µ¡ÍѤÎMillennium II, Mystique, G100, G200Åù¤Ï¡¢VGA¤ò
+ disable¤Ç¤­¤Ê¤¤¤Î¤Ç¡¢»ÈÍѤǤ­¤Þ¤»¤ó¡£
+ <ITEM>3.3¥Ù¡¼¥¹¤ÎX¥µ¡¼¥Ð¤Ç¸ºß¤·¤Æ¤¤¤¿¡¢Mystique¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç¤Ï
+ Windows¤ò»öÁ°¤Ëµ¯Æ°¤·¤Æ¤ª¤«¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤È¤¤¤¦ÌäÂê¤ä8bpp¤Ç¤Îɽ¼¨
+ ¤¬¤ª¤«¤·¤¤¤È¤¤¤¦ÌäÂê¤Ï²ò¾Ã¤µ¤ì¤Æ¤¤¤Þ¤¹¡£
+ <ITEM>¤Þ¤À½½Ê¬¤Ê¥Æ¥¹¥È¤¬¹Ô¤ï¤ì¤Æ¤¤¤Ê¤¤¤Î¤Çưºî¥ì¥Ý¡¼¥È¤ò¤ª´ê¤¤
+ ¤·¤Þ¤¹¡£
+</itemize>
+<sect2>´ØÏ¢<p>
+ README.MGA¡¢XF86_SVGA man page</p>
+
+<sect1>apm¥É¥é¥¤¥Ð<p>
+ (¾­ÍèŪ¤Ë¤Ï)IO-DATA¤ÎGA-RUSH6/PCI¤Ç¤âưºî¤¹¤ë(ͽÄê¤Î)¥É¥é¥¤¥Ð¤Ç¤¹¡£</p>
+<sect2>XF86Config¤ÎÀßÄê<p>
+ README.MGAÆâ¤Ë²òÀ⤵¤ì¤Æ¤¤¤ë¥ª¥×¥·¥ç¥ó¤ò»ØÄê¤Ç¤­¤Þ¤¹¡£Ä̾ï¤ÏÆÃ¤Ë
+ ²¿¤â»ØÄꤹ¤ëɬÍ×̵¤¤È¦¤Ç¤¹¡£
+<sect2>Êó¹ð¤µ¤ì¤Æ¤¤¤ëÌäÂê<p>
+<itemize>
+ <ITEM>8bpp°Ê³°¤Ç¤Ï¤Þ¤Ã¤¿¤¯Æ±´ü¤¬¼è¤ì¤Þ¤»¤ó¡£8bpp¤Î¾ì¹ç¤Ç¤âƱ´ü¤¬
+ ¤ª¤«¤·¤¯¤ÆÆ±¤¸Êª¤¬3¤Äɽ¼¨¤µ¤ì¤¿¤ê¤·¤Þ¤¹¡£
+ <ITEM>XF86Config¤Ç¤Î¥ª¥×¥·¥ç¥ó»ØÄê¤Ë¤è¤Ã¤Æ¤Ï¥Ï¥ó¥°¥¢¥Ã¥×¤·¤¿¤ê¤¹¤ë
+ ¤³¤È¤â¤¢¤ê¤Þ¤¹¡£
+</itemize>
+<sect2>¤½¤Î¾<p>
+<itemize>
+ <ITEM>¤Þ¤ÀPC-98Âбþºî¶È¤¬ËؤɽÐÍè¤Æ¤¤¤Þ¤»¤ó¡£¼ÂÍѤˤÏÂѤ¨¤Ê¤¤¤Ç¤·¤ç¤¦¡£
+</itemize>
+<sect2>´ØÏ¢<p>
+ XF86_SVGA man page</p>
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/VideoModes.doc b/xc/programs/Xserver/hw/xfree86/doc/VideoModes.doc
index 25690d4fc..896fd93f5 100644
--- a/xc/programs/Xserver/hw/xfree86/doc/VideoModes.doc
+++ b/xc/programs/Xserver/hw/xfree86/doc/VideoModes.doc
@@ -1123,7 +1123,7 @@ Here is a copy of modeplot:
#
# Do `modeplot -?' to see the control options.
#
- # ($Id: VideoModes.doc,v 1.1 1999/12/05 01:16:52 daryll Exp $)
+ # ($Id: VideoModes.doc,v 1.1.1.1 1999/12/05 01:16:52 daryll Exp $)
# Monitor description. Bandwidth in MHz, horizontal frequencies in kHz
# and vertical frequencies in Hz.
@@ -1162,7 +1162,7 @@ Here is a copy of modeplot:
The modeplot tool was created by Eric S. Raymond <esr@thyrsus.com> based on
analysis and scratch code by Martin Lottermoser <Martin.Lottermoser@mch.sni.de>
- This is modeplot $Revision: 1.1 $
+ This is modeplot $Revision: 1.1.1.1 $
EOF
exit;;
esac
diff --git a/xc/programs/Xserver/hw/xfree86/doc/man/Imakefile b/xc/programs/Xserver/hw/xfree86/doc/man/Imakefile
new file mode 100644
index 000000000..c0c19a6bc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/man/Imakefile
@@ -0,0 +1,15 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/doc/man/Imakefile,v 3.4 1999/08/01 07:57:14 dawes Exp $
+
+MANDIR = $(LIBMANDIR)
+MANSUFFIX = $(LIBMANSUFFIX)
+
+all::
+
+InstallManPage(XF86DGA,$(MANDIR))
+InstallManPage(XF86Misc,$(MANDIR))
+InstallManPageLong(XF86VM,$(MANDIR),XF86VidMode)
+#if ExpandManNames
+InstallManPageAliases(XF86DGA,$(MANDIR),XF86DGAQueryExtension XF86DGAQueryVersion XF86DGAQueryDirectVideo XF86DGAGetVideo XF86DGADirectVideo XF86DGASetVidPage XF86DGASetViewPort XF86DGAViewPortChanged XF86DGAGetViewPortSize XF86DGAInstallColormap XF86DGAForkApp)
+InstallManPageAliases(XF86Misc,$(MANDIR),XF86MiscQueryExtension XF86MiscQueryVersion XF86MiscGetSaver XF86MiscSetSaver XF86MiscGetMouseSettings XF86MiscSetMouseSettings XF86MiscGetKbdSettings XF86MiscSetKbdSettings)
+InstallManPageAliases(XF86VidMode,$(MANDIR),XF86VidModeQueryExtension XF86VidModeQueryVersion XF86VidModeGetModeLine XF86VidModeGetAllModeLines XF86VidModeDeleteModeLine XF86VidModeModModeLine XF86VidModeSwitchMode XF86VidModeSwitchToMode XF86VidModeLockModeSwitch XF86VidModeGetMonitor XF86VidModeGetViewPort XF86VidModeSetViewPort)
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/doc/man/XF86DGA.man b/xc/programs/Xserver/hw/xfree86/doc/man/XF86DGA.man
new file mode 100644
index 000000000..f4f08714b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/man/XF86DGA.man
@@ -0,0 +1,201 @@
+.\" Copyright (c) 1996 The XFree86 Project
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/doc/man/XF86DGA.man,v 3.6 1997/11/16 06:42:12 dawes Exp $
+.\" $TOG: XF86DGA.man /main/9 1997/11/11 12:08:52 kaleb $
+.\"
+.de ZN
+.ie t \fB\^\\$1\^\fR\\$2
+.el \fI\^\\$1\^\fP\\$2
+..
+.TH XF86DGA 3X11 "3.3.1+ (X11R6.4)" "XFree86" "X FUNCTIONS"
+.SH NAME
+XF86DGAQueryExtension, XF86DGAQueryVersion, XF86DGAQueryDirectVideo, XF86DGAGetVideo, XF86DGADirectVideo, XF86DGASetVidPage, XF86DGASetViewPort, XF86DGAViewPortChanged, XF86DGAGetViewPortSize, XF86DGAInstallColormap, XF86DGAForkApp \- XFree86-DGA extension interface functions
+.SH SYNTAX
+.nf
+.LP
+#include <X11/extensions/xf86dga.h>
+.LP
+Bool XF86DGAQueryExtension(
+ Display *\fIdisplay\fP\^,
+ int *\fIevent_base_return\fP\^,
+ int *\fIerror_base_return\fP\^);
+.LP
+Bool XF86DGAQueryVersion(
+ Display *\fIdisplay\fP\^,
+ int *\fImajor_version_return\fP\^,
+ int *\fIminor_version_return\fP\^);
+.LP
+Bool XF86DGAQueryDirectVideo(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ int *\fIflags_return\fP\^);
+.LP
+Bool XF86DGAGetVideo(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ char **\fIaddr_return\fP\^,
+ int *\fIwidth_return\fP\^,
+ int *\fIbanksize_return\fP\^,
+ int *\fImemsize_return\fP\^);
+.LP
+Bool XF86DGADirectVideo(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ int \fIflags\fP\^);
+.LP
+Bool XF86DGASetVidPage(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ int \fIpage\fP\^);
+.LP
+Bool XF86DGASetViewPort(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ int \fIx\fP\^,
+ int \fIy\fP\^);
+.LP
+Bool XF86DGAViewPortChanged(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ int \fInum_pages\fP\^);
+.LP
+Bool XF86DGAGetViewPortSize(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ int *\fIviewport_width_return\fP\^,
+ int *\fIviewport_height_return\fP\^);
+.LP
+Bool XF86DGAInstallColormap(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ Colormap \fIcmap\fP\^);
+.LP
+int XF86DGAForkApp(
+ int \fIscreen\fP\^);
+.fi
+.SH ARGUMENTS
+.IP \fIdisplay\fP 2i
+Specifies the connection to the X server.
+.IP \fIscreen\fP 2i
+Specifies which screen number the setting apply to.
+.IP \fIevent_base_return\fP 2i
+Returns the base event number for the extension.
+.IP \fIerror_base_return\fP 2i
+Returns the base error number for the extension.
+.IP \fImajor_version_return\fP 2i
+Returns the major version number of the extension.
+.IP \fIminor_version_return\fP 2i
+Returns the minor version number of the extension.
+.IP \fIaddr_return\fP 2i
+Returns a pointer to the start of the video framebuffer.
+.IP \fIwidth_return\fP 2i
+Returns the framebuffer line width.
+.IP \fIbanksize_return\fP 2i
+Returns the framebuffer bank size.
+.IP \fImemsize_return\fP 2i
+Returns the size of the framebuffer memory.
+.IP \fIflags\fP 2i
+Sets the DirectVideo access features. When zero, DirectVideo mode is
+disabled. \fIflags\fP may be a a bit-wise combination of the following
+values:
+.nf
+XF86DGADirectGraphics enable Direct Video mode
+XF86DGADirectMouse enable reporting of pointer movement
+ as relative motion
+XF86DGADirectKeyb enable direct reporting of keyboard events
+.fi
+.IP \fIflags_return\fP 2i
+Reports the DirectVideo features supported by the hardware. When zero,
+the hardware does not support direct video at all.
+\fIflags\fP may be a a bit-wise combination of the following
+values:
+.nf
+XF86DGADirectPresent DirectVideo support is present
+.fi
+.IP \fIpage\fP 2i
+Indicates the framebuffer page (bank) to activate for read/write access.
+.IP \fIx\fP 2i
+Incidates the x coordinate for the upper-left corner of the view port.
+.IP \fIy\fP 2i
+Incidates the y coordinate for the upper-left corner of the view port.
+.IP \fIviewport_width_return\fP 2i
+Reports the width of the view port.
+.IP \fIviewport_width_return\fP 2i
+Reports the height of the view port.
+.IP \fInum_pages\fP 2i
+Indicates the number of pages when doing hardware multi-buffering.
+.IP \fIcmap\fP 2i
+Indicates the colormap to install.
+.SH DESCRIPTION
+These functions provide an interface to the server extension
+\fIXFree86-DGA\fP
+which allows a local client direct access to the video framebuffer.
+Applications that use these functions must be linked with
+.ZN -lXxf86dga
+.SS "DGA FUNCTIONS"
+The function
+.ZN XF86DGAQueryDirectVideo
+returns the DirectVideo capabilities supported by the graphics device.
+.PP
+The
+.ZN XF86DGAGetVideo
+function is used to get the parameters for the framebuffer. The parameters
+returned are a pointer to the start of the framebuffer, the framebuffer line
+width, framebuffer bank size, and framebuffer memory size.
+.PP
+.ZN XF86DGADirectVideo
+is used to enable or disable DirectVideo mode.
+.PP
+The
+.ZN XF86DGASetVidPage
+function sets the currently active framebuffer page (bank). This is only
+required for hardware which has a banked memory layout (banksize < memsize).
+.PP
+The
+.ZN XF86DGASetViewPort
+function sets the framebuffer coordinates to use for the upper-left corner
+of the view port.
+.PP
+The
+.ZN XF86DGAViewPortChanged
+function checks whether a previous XF86DGASetViewPort command has been
+completed by the hardware, that is, whether a vertical retrace has
+occurred since a previous XF86DGASetViewPort. This can (must, in fact)
+be used with page-flipping; you can start writing to the next page only
+when this function returns TRUE. For some devices this will be the case
+immediately after XF86DGASetViewPort, however this may be changed in the
+future. The number of pages used is specified with \fInum_pages\fP; it
+should be 2 for simple page flipping (double buffering). If n is greater
+than two (triple or multi-buffering), the function checks whether the
+(n \- 2)-before-last SetViewPort has been completed.
+.PP
+The
+.ZN XF86DGAGetViewPortSize
+function returns the size of the view port, which is the part of the
+framebuffer that is visible on the screen.
+.PP
+The
+.ZN XF86DGAInstallColormap
+function is used to install a colormap. This must be called after DirectVideo
+mode has been enabled.
+.PP
+The
+.ZN XF86DGAForkApp
+function causes the client application to fork, leaving the parent process
+to hang around and return to non-DGA mode should the client exit for any
+reason. This function returns 0 for success, or the error condition
+returned by fork().
+.SS "OTHER FUNCTIONS"
+The
+.ZN XF86DGAQueryVersion
+function can be used to determine the version of the extension
+built into the server.
+.PP
+The function
+.ZN XF86DGAQueryExtension
+returns the lowest numbered error and event values
+assigned to the extension.
+.SH SEE ALSO
+XFree86(1), XF86Config(4/5)
+.SH AUTHORS
+Jon Tombs, Harm Hanemaayer, Mark Vojkovich.
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/man/XF86Misc.man b/xc/programs/Xserver/hw/xfree86/doc/man/XF86Misc.man
new file mode 100644
index 000000000..24520e6a0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/man/XF86Misc.man
@@ -0,0 +1,216 @@
+.\" $TOG: XF86Misc.man /main/7 1997/07/19 10:30:32 kaleb $
+.\"
+.\"
+.\"
+.\" Copyright (c) 1996 Joe Moss, The XFree86 Project
+.\"
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/doc/man/XF86Misc.man,v 3.9 1998/04/05 02:28:41 dawes Exp $
+.de ZN
+.ie t \fB\^\\$1\^\fR\\$2
+.el \fI\^\\$1\^\fP\\$2
+..
+.TH XF86MISC 3X11 "3.3.1+ (X11R6.4)" "XFree86" "X FUNCTIONS"
+.SH NAME
+XF86MiscQueryExtension, XF86MiscQueryVersion, XF86MiscGetMouseSettings, XF86MiscSetMouseSettings, XF86MiscGetKbdSettings, XF86MiscSetKbdSettings \- XFree86-Misc extension interface functions
+.SH SYNTAX
+.nf
+.LP
+#include <X11/extensions/xf86misc.h>
+.LP
+Bool XF86MiscQueryExtension(
+ Display *\fIdisplay\fP\^,
+ int *\fIevent_base_return\fP\^,
+ int *\fIerror_base_return\fP\^);
+.LP
+Bool XF86MiscQueryVersion(
+ Display *\fIdisplay\fP\^,
+ int *\fImajor_version_return\fP\^,
+ int *\fIminor_version_return\fP\^);
+.ig
+.LP
+Status XF86MiscGetSaver(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ int *\fIsuspend_time_return\fP\^,
+ int *\fIoff_time_return\fP\^);
+.LP
+Status XF86MiscSetSaver(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ int \fIsuspend_time\fP\^,
+ int \fIoff_time\fP\^);
+..
+.LP
+Status XF86MiscGetMouseSettings(
+ Display *\fIdisplay\fP\^,
+ XF86MiscMouseSettings *\fImseinfo\fP\^);
+.LP
+Status XF86MiscSetMouseSettings(
+ Display *\fIdisplay\fP\^,
+ XF86MiscMouseSettings *\fImseinfo\fP\^);
+.LP
+Status XF86MiscGetKbdSettings(
+ Display *\fIdisplay\fP\^,
+ XF86MiscKbdSettings *\fIkbdinfo\fP\^);
+.LP
+Status XF86MiscSetKbdSettings(
+ Display *\fIdisplay\fP\^,
+ XF86MiscKbdSettings *\fIkbdinfo\fP\^);
+.fi
+.SH ARGUMENTS
+.IP \fIdisplay\fP 2i
+Specifies the connection to the X server.
+.IP \fIscreen\fP 2i
+Specifies which screen number the setting apply to.
+.IP \fIevent_base_return\fP 2i
+Returns the base event number for the extension.
+.IP \fIerror_base_return\fP 2i
+Returns the base error number for the extension.
+.IP \fImajor_version_return\fP 2i
+Returns the major version number of the extension.
+.IP \fIminor_version_return\fP 2i
+Returns the minor version number of the extension.
+.ig
+.IP \fIsuspend_time_return\fP 2i
+Returns the number of seconds of idle time the server
+will wait before activating the monitor's suspend mode.
+.IP \fIoff_time_return\fP 2i
+Returns the number of seconds of idle time the server
+will wait before causing the monitor to powerdown.
+.IP \fIsuspend_time\fP 2i
+Specifies the number of seconds of idle time the server
+should wait before activating the monitor's suspend mode.
+.IP \fIoff_time\fP 2i
+Specifies the number of seconds of idle time the server
+should wait before causing the monitor to powerdown.
+..
+.IP \fImseinfo\fP 2i
+Specifies a structure which contains the mouse parameters.
+.IP \fIkbdinfo\fP 2i
+Specifies a structure which contains the keyboard parameters.
+.SH STRUCTURES
+.nf
+.ta 3i
+\fIMouse:\fP
+typedef struct {
+ char *device; /* returned path to device */
+ int type; /* mouse protocol */
+ int baudrate; /* 1200, 2400, 4800, or 9600 */
+ int samplerate; /* samples per second */
+ int resolution; /* resolution, count per inch */
+ int buttons; /* number of buttons */
+ Bool emulate3buttons; /* Button1+Button3 -> Button2 ? */
+ int emulate3timeout; /* in milliseconds */
+ Bool chordmiddle; /* Button1+Button3 == Button2 ? */
+ int flags; /* Device open flags */
+} XF86MiscMouseSettings;
+.LP
+\fIKeyboard:\fP
+typedef struct {
+ int type; /* of keyboard: 84-key, 101-key, Xqueue */
+ int rate; /* repeat rate */
+ int delay; /* delay until repeat starts */
+ Bool servnumlock; /* Server handles NumLock ? */
+} XF86MiscKbdSettings;
+.fi
+.SH DESCRIPTION
+These functions provide an interface to the
+\fIXFree86-Misc\fP extension
+which allows various server settings to be
+queried and changed dynamically.
+Applications that use these functions must be linked with
+.ZN -lXxf86misc
+.SS "POWER-SAVER FUNCTIONS"
+The
+.ZN XF86MiscGetSaver
+and
+.ZN XF86MiscSetSaver
+functions have been removed. This functionality is now provided by
+the DPMS extension.
+.SS "MOUSE FUNCTIONS"
+Mouse parameters can be queried using the function
+.ZN XF86MiscGetMouseSettings .
+The structure pointed to by its second argument is filled in
+with the current mouse settings.
+.PP
+Not all fields are valid in all cases.
+For example, when the protocol indicates a bus mouse (i.e. the
+type field has value
+.ZN MTYPE_BUSMOUSE
+as defined in
+.ZN xf86misc.h ),
+then the value in the
+.ZN baudrate
+field should be ignored as it does not apply to bus mice.
+.PP
+The
+.ZN samplerate
+field contains the resolution in lines per inch when
+using the Hitachi tablet protocol.
+.PP
+The device field of the structure points to dynamically
+allocated storage which should be freed by the caller.
+.PP
+Any of the fields of the structure can be altered and then passed
+to the
+.ZN XF86MiscSetMouseSettings
+function to change their value in the server,
+with the following restrictions:
+.RS 5
+.IP 1) 3
+The device can not be changed
+.IP 2) 3
+The protocol can not be changed to or from Xqueue or OsMouse
+.IP 3) 3
+The buttons field can not be changed
+.IP 4) 3
+Invalid combinations of parameters are not allowed
+.RE
+.PP
+The server will generate an error if any of the above is attempted,
+except the first \- the contents of the device field are simply ignored.
+.PP
+A change of the protocol causes the device to be closed and reopened.
+Changes to the baud rate, sample rate, resolution or flags,
+when applicable to the
+selected protocol, also cause a reopen of the device.
+A reopen can be forced by using the MF_REOPEN flag, except in the
+case of the OsMouse and Xqueue protocols which ignore all attempts
+to reopen the device.
+.SS "KEYBOARD FUNCTIONS"
+The
+.ZN XF86MiscGetKbdSettings
+function allows you to retrieve the current keyboard-related
+settings from the server.
+.PP
+Using the
+.ZN XF86MiscSetKbdSettings
+function, the keyboard autorepeat delay and rate can be set.
+Requests to change the
+.ZN type
+and
+.ZN servnumlock
+fields are ignored (except for checking for an invalid keyboard type).
+This is expected to change in a future release.
+.SS "OTHER FUNCTIONS"
+Two functions,
+.ZN XF86MiscQueryExtension
+and
+.ZN XF86MiscQueryVersion ,
+are provided which allow the client to query some information
+regarding the extension itself.
+.SH PREDEFINED VALUES
+The header file
+.ZN X11/extensions/xf86misc.h
+contains definitions for
+.IP \fBMTYPE_\fP* 1i
+Mouse protocols
+.IP \fBKTYPE_\fP* 1i
+Keyboard types
+.IP \fBMF_\fP* 1i
+Mouse flags
+.SH "SEE ALSO"
+xset(1)
+.SH AUTHORS
+Joe Moss and David Dawes, The XFree86 Project, Inc.
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/man/XF86VM.man b/xc/programs/Xserver/hw/xfree86/doc/man/XF86VM.man
new file mode 100644
index 000000000..82047bc81
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/man/XF86VM.man
@@ -0,0 +1,343 @@
+.\" $TOG: XF86VM.man /main/6 1997/07/19 10:30:39 kaleb $
+.\"
+.\"
+.\"
+.\"
+.\" Copyright (c) 1996 Joe Moss, The XFree86 Project
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/doc/man/XF86VM.man,v 3.8 1998/04/05 02:28:41 dawes Exp $
+.\"
+.de ZN
+.ie t \fB\^\\$1\^\fR\\$2
+.el \fI\^\\$1\^\fP\\$2
+..
+.TH XF86VIDMODE 3X11 "3.3.1+ (X11R6.4)" "XFree86" "X FUNCTIONS"
+.SH NAME
+XF86VidModeQueryExtension, XF86VidModeQueryVersion, XF86VidModeGetModeLine, XF86VidModeGetAllModeLines, XF86VidModeDeleteModeLine, XF86VidModeModModeLine, XF86VidModeValidateModeLine, XF86VidModeSwitchMode, XF86VidModeSwitchToMode, XF86VidModeLockModeSwitch, XF86VidModeGetMonitor, XF86VidModeGetViewPort, XF86VidModeSetViewPort \- XFree86-VidMode extension interface functions
+.SH SYNTAX
+.nf
+.LP
+#include <X11/extensions/xf86vmode.h>
+.LP
+Bool XF86VidModeQueryExtension(
+ Display *\fIdisplay\fP\^,
+ int *\fIevent_base_return\fP\^,
+ int *\fIerror_base_return\fP\^);
+.LP
+Bool XF86VidModeQueryVersion(
+ Display *\fIdisplay\fP\^,
+ int *\fImajor_version_return\fP\^,
+ int *\fIminor_version_return\fP\^);
+.LP
+Bool XF86VidModeGetModeLine(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ int *\fIdotclock_return\fP\^,
+ XF86VidModeModeLine *\fImodeline\fP\^);
+.LP
+Bool XF86VidModeGetAllModeLines(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ int *\fImodecount_return\fP\^,
+ XF86VidModeModeInfo **\fImodesinfo\fP\^);
+.ig
+.LP
+Bool XF86VidModeAddModeLine(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ XF86VidModeModeInfo *\fImodeline\fP\,
+ XF86VidModeModeInfo *\fIaftermode\fP\^);
+..
+.LP
+Bool XF86VidModeDeleteModeLine(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ XF86VidModeModeInfo *\fImodeline\fP\^);
+.LP
+Bool XF86VidModeModModeLine(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ XF86VidModeModeLine *\fImodeline\fP\^);
+.LP
+Status XF86VidModeValidateModeLine(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ XF86VidModeModeLine *\fImodeline\fP\^);
+.LP
+Bool XF86VidModeSwitchMode(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ int \fIzoom\fP\^);
+.LP
+Bool XF86VidModeSwitchToMode(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ XF86VidModeModeInfo *\fImodeline\fP\^);
+.LP
+Bool XF86VidModeLockModeSwitch(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ int \fIlock\fP\^);
+.LP
+Bool XF86VidModeGetMonitor(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ XF86VidModeMonitor *\fImonitor\fP\^);
+.LP
+Bool XF86VidModeGetViewPort(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ int *\fIx_return\fP\^,
+ int *\fIy_return\fP\^);
+.LP
+Bool XF86VidModeSetViewPort(
+ Display *\fIdisplay\fP\^,
+ int \fIscreen\fP\^,
+ int \fIx\fP\^,
+ int \fIy\fP\^);
+.fi
+.SH ARGUMENTS
+.IP \fIdisplay\fP 2i
+Specifies the connection to the X server.
+.IP \fIscreen\fP 2i
+Specifies which screen number the setting apply to.
+.IP \fIevent_base_return\fP 2i
+Returns the base event number for the extension.
+.IP \fIerror_base_return\fP 2i
+Returns the base error number for the extension.
+.IP \fImajor_version_return\fP 2i
+Returns the major version number of the extension.
+.IP \fIminor_version_return\fP 2i
+Returns the minor version number of the extension.
+.IP \fIdotclock_return\fP 2i
+Returns the clock for the mode line.
+.IP \fImodecount_return\fP 2i
+Returns the number of video modes available in the server.
+.IP \fIzoom\fP 2i
+If greater than zero, indicates that the server should switch to
+the next mode, otherwise switch to the previous mode.
+.IP \fIlock\fP 2i
+Indicates that mode switching should be locked, if non-zero.
+.IP \fImodeline\fP 2i
+Specifies or returns the timing values for a video mode.
+.ig
+.IP \fIaftermode\fP 2i
+Specifies the timing values for the video mode after which the
+new mode will added.
+..
+.IP \fImodesinfo\fP 2i
+Returns the timing values and dotclocks for all of the available
+video modes.
+.IP \fImonitor\fP 2i
+Returns information about the monitor.
+.IP \fIx\fP 2i
+Specifies the desired X location for the viewport.
+.IP \fIx_return\fP 2i
+Returns the current X location of the viewport.
+.IP \fIy\fP 2i
+Specifies the desired Y location for the viewport.
+.IP \fIy_return\fP 2i
+Returns the current Y location of the viewport.
+.SH STRUCTURES
+.nf
+.ta 2.25i 3.5i
+\fIVideo Mode Settings:\fP
+typedef struct {
+ unsigned short hdisplay; /* Number of display pixels horizontally */
+ unsigned short hsyncstart; /* Horizontal sync start */
+ unsigned short hsyncend; /* Horizontal sync end */
+ unsigned short htotal; /* Total horizontal pixels */
+ unsigned short vdisplay; /* Number of display pixels vertically */
+ unsigned short vsyncstart; /* Vertical sync start */
+ unsigned short vsyncend; /* Vertical sync start */
+ unsigned short vtotal; /* Total vertical pixels */
+ unsigned int flags; /* Mode flags */
+ int privsize; /* Size of private */
+ INT32 *private; /* Server privates */
+} XF86VidModeModeLine;
+.sp
+typedef struct {
+ unsigned int dotclock; /* Pixel clock */
+ unsigned short hdisplay; /* Number of display pixels horizontally */
+ unsigned short hsyncstart; /* Horizontal sync start */
+ unsigned short hsyncend; /* Horizontal sync end */
+ unsigned short htotal; /* Total horizontal pixels */
+ unsigned short vdisplay; /* Number of display pixels vertically */
+ unsigned short vsyncstart; /* Vertical sync start */
+ unsigned short vsyncend; /* Vertical sync start */
+ unsigned short vtotal; /* Total vertical pixels */
+ unsigned int flags; /* Mode flags */
+ int privsize; /* Size of private */
+ INT32 *private; /* Server privates */
+} XF86VidModeModeInfo;
+.LP
+\fIMonitor information:\fP
+typedef struct {
+ char* vendor; /* Name of manufacturer */
+ char* model; /* Model name */
+ float bandwidth; /* Monitor bandwidth */
+ unsigned char nhsync; /* Number of horiz sync ranges */
+ XF86VidModeSyncRange* hsync; /* Horizontal sync ranges */
+ unsigned char nvsync; /* Number of vert sync ranges */
+ XF86VidModeSyncRange* vsync; /* Vertical sync ranges */
+} XF86VidModeMonitor;
+.sp
+typedef struct {
+ float hi; /* Top of range */
+ float lo; /* Bottom of range */
+} XF86VidModeSyncRange;
+.fi
+.SH DESCRIPTION
+These functions provide an interface to the server extension
+\fIXFree86-VidModeExtension\fP
+which allows the video modes to be
+queried and adjusted dynamically and mode switching to be controlled.
+Applications that use these functions must be linked with
+.ZN -lXxf86vm
+.SS "MODELINE FUNCTIONS"
+The
+.ZN XF86VidModeGetModeLine
+function is used to query the settings for the currently selected
+video mode. The calling program should pass a pointer to a
+.ZN XF86VidModeModeLine
+structure that it has already allocated. The function fills in
+the fields of the structure.
+.PP
+If there are any server private values (currently only applicable to
+the S3 server) the function will allocate storage for them.
+Therefore, if the
+.ZN privsize
+field is non-zero, the calling program should call
+.ZN Xfree(private)
+to free the storage.
+.PP
+.ZN XF86VidModeGetAllModeLines
+returns the settings for all video modes.
+The calling program supplies the address of a pointer which will be
+set by the function to point to an array of
+.ZN XF86VidModeModeInfo
+structures. The memory occupied by the array is dynamically allocated
+by the
+.ZN XF86VidModeGetAllModeLines
+function and should be freed by the caller.
+The first element of the array corresponds to the current video mode.
+.PP
+The
+.ZN XF86VidModeModModeLine
+function can be used to change the settings of the current video mode
+provided the requested settings are valid (e.g. they don't exceed the
+capabilities of the monitor).
+.PP
+.ig
+To add a mode to the list of available modes, the
+.ZN XF86VidModeAddModeLine
+function can be used.
+Assuming the settings are valid, the video mode will be added after
+the existing mode which matches the timings specified by the
+.ZN aftermode
+parameter.
+To be considered a match, all of the fields of the given
+.ZN XF86VidModeModeInfo
+structure must match, except the
+.ZN privsize
+and
+.ZN private
+fields.
+If the
+.ZN aftermode
+parameter is zero, the mode will be added
+after the current mode.
+.PP
+..
+Modes can be deleted with the
+.ZN XF86VidModeDeleteModeLine
+function. The specified mode must match an existing mode.
+To be considered a match, all of the fields of the given
+.ZN XF86VidModeModeInfo
+structure must match, except the
+.ZN privsize
+and
+.ZN private
+fields.
+If the mode to be deleted is the current mode, a mode switch
+to the next mode will occur first. The last remaining mode can not
+be deleted.
+.PP
+The validity of a mode can be checked with the
+.ZN XF86VidModeValidateModeLine
+function.
+If the specified mode can be used by the server (i.e. meets all the
+constraints placed upon a mode by the combination of the server, card,
+and monitor) the function returns
+.ZN MODE_OK ,
+otherwise it returns a value indicating the reason why the mode is
+invalid (as defined in \fIxf86.h\fP)
+.SS "MODE SWITCH FUNCTIONS"
+When the function
+.ZN XF86VidModeSwitchMode
+is called, the server will change the video mode to next (or previous)
+video mode. The
+.ZN XF86VidModeSwitchToMode
+function can be used to switch directly to the specified mode.
+Matching is as specified in the description of the
+.ZN XF86VidModeAddModeLine
+function above.
+The
+.ZN XF86VidModeLockModeSwitch
+function can be used to allow or disallow mode switching whether
+the request to switch modes comes from a call to the
+.ZN XF86VidModeSwitchMode
+or
+.ZN XF86VidModeSwitchToMode
+functions or from one of the mode switch key sequences.
+.SS "MONITOR FUNCTIONS"
+Information known to the server about the monitor is returned by the
+.ZN XF86VidModeGetMonitor
+function. The
+.ZN hsync
+and
+.ZN vsync
+fields each point to an array of
+.ZN XF86VidModeSyncRange
+structures. The arrays contain
+.ZN nhsync
+and
+.ZN nvsync
+elements, respectively.
+The
+.ZN hi
+and
+.ZN low
+values will be equal if a discreate value was given in the
+.ZN XF86Config
+file.
+.PP
+The
+.ZN vendor ,
+.ZN model ,
+.ZN hsync ,
+and
+.ZN vsync
+fields point to dynamically allocated storage that should be freed
+by the caller.
+.SS "VIEWPORT FUNCTIONS"
+The
+.ZN XF86VidModeGetViewPort
+and
+.ZN XF86VidModeSetViewPort
+functions can be used to, respectively, query and change the location
+of the upper left corner of the viewport into the virtual screen.
+.SS "OTHER FUNCTIONS"
+The
+.ZN XF86VidModeQueryVersion
+function can be used to determine the version of the extension
+built into the server.
+.PP
+The function
+.ZN XF86VidModeQueryExtension
+returns the lowest numbered error and event values
+assigned to the extension.
+.SH SEE ALSO
+XFree86(1), XF86Config(4/5), xvidtune(1)
+.SH AUTHORS
+Kaleb Keithley, Jon Tombs, David Dawes, and Joe Moss
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/3Dlabs.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/3Dlabs.sgml
new file mode 100644
index 000000000..7c365b514
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/3Dlabs.sgml
@@ -0,0 +1,84 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+<title>Information for 3DLabs Chipset Users
+<author>The XFree86 Project Inc.
+<date>25 June 1999
+<toc>
+
+<sect>Supported hardware <p>
+
+This server supports the following 3DLabs chipsets:
+<itemize>
+<item>GLINT 500TX with IBM RGB526 RAMDAC
+<item>GLINT MX plus Delta with IBM RGB526 and IBM RGB640 RAMDAC
+<item>GLINT MX plus Gamma with IBM RGB526 and IBM RGB640 RAMDAC
+<item>Permedia with IBM RGB526 RAMDAC
+<item>Permedia 2 (classic, 2a, 2v)
+</itemize>
+
+<sect>Features <p>
+<itemize>
+<item>accelerated
+<item>hardware cursor
+<item>DPMS support
+<item>supported color depths
+<itemize>
+<item>GLINT MX/500TX: 8/16/32 bpp
+<item>Permedia: 8/16/32 bpp
+<item>Permedia 2: 8/16/24/32 bpp
+</itemize>
+</itemize>
+
+<sect>XF86Config Option <p>
+<descrip>
+<tag>Option "sw_cursor"</tag>
+disable the hardware cursor.
+<tag>Option "no_pixmap_cache"</tag>
+disables use of the pixmap cache. Might be useful if drawing errors occur.
+<tag>Option "no_accel"</tag>
+completely disables acceleration. Usually not recommended.
+<tag>Option "pci_retry"</tag>
+stall the PCI bus while the graphics engine is busy. While this might
+give slightly higher performance, you run the risk of disturbing other
+devices that are waiting to be serviced by the processor. This option may
+cause problems with SCSI cards, serial connections, sound cards, etc.
+<tag>Option "firegl_3000"</tag>
+needed for the Diamond Fire GL 3000 in order to use the primary output
+on that card. The second screen is currently not supported.
+<tag>Option "overclock_mem"</tag>
+Run the memory at a higher clock. Useful on some cards with display glitches
+at higher resolutions. But adds the risk to damage the hardware. Use with
+caution.
+</descrip>
+
+<sect>Bugs and Limitations<p>
+<itemize>
+<item>The 500TX and MX chipsets cannot switch modes, therefore only the first
+mode on the modes line is available.
+<item>In some color depths without acceleration there are color problems.
+<item>While the server is accelerated, there is room for improvement. As our
+development is focusing on XFree86-4.0 we are not planning to change that in
+the 3.3.x branch. XFree86-4.0 will include a significantly faster server.
+</itemize>
+
+<sect>Authors<p>
+<itemize>
+<item>Alan Hourihane <it>&lt;alanh@fairlite.demon.co.uk&gt;</it>
+<item>Dirk Hohndel <it>&lt;hohndel@XFree86.org&gt;</it>
+<item>Stefan Dirsch <it>&lt;sndirsch@suse.de&gt;</it>
+<item>Helmut Fahrion <it>&lt;hf@suse.de&gt;</it>
+<item>Special thanks to Elsa AG, Aachen for making it possible for us to
+develop this server and furnishing us with plenty of boards and information
+to help us on the way
+<item>Very special thanks to SuSE GmbH, Nuernberg for allowing some of us to
+work on this server on paid time, thereby financing development of this
+server.
+</itemize>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/3Dlabs.sgml,v 1.2 1999/08/24 02:01:07 dawes Exp $
+</verb>
+
+</article>
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/BUILD.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/BUILD.sgml
new file mode 100644
index 000000000..6bd6ddbb8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/BUILD.sgml
@@ -0,0 +1,224 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+<title>Building XFree86
+<author>David Dawes
+<Date>24 May 1997
+
+<abstract>
+This document describes how to build XFree86 from the <bf>source</bf>
+distribution. It covers building from the full source distribution as
+well as from the cut-down source distribution available for building
+only the X servers. It is designed to
+be used in conjunction with the OS-specific README files.
+</abstract>
+
+<toc>
+
+
+<sect>Building XFree86 From a Source Distribution
+
+<p>
+<quote>
+<bf/NOTE:/ Refer to the appropriate OS-specific README file before attempting
+ to build XFree86. These files contain additional information that
+ you may need to successfully build under your OS.
+</quote>
+
+
+We highly recommend using GCC-2 to build XFree86. Do not use version
+2.6.0 or 2.4.x versions prior to 2.4.5 due to bugs that cause either
+build or execution failures. (gcc-2 is available from prep.ai.mit.edu
+and other sites archiving GNU source.)
+
+<sect1>How to get the XFree86 3.3 source
+<p>
+There are a few starting points for getting the XFree86 source. One option
+is to start directly with the XFree86 3.3 source distribution. In this
+case, the procedure is as follows:
+<itemize>
+ <item>The XFree86 3.3 source is contained in files <tt>X33src-1.tgz</tt>,
+ <tt>X33src-2.tgz</tt> and <tt>X33src-3.tgz</tt>. These can be found
+ at <htmlurl name="ftp://ftp.xfree86.org/pub/XFree86/3.3/source/"
+ url="ftp://ftp.xfree86.org/pub/XFree86/3.3/source/"> and similar
+ locations on XFree86 mirror sites. <tt>X33src-2.tgz</tt> contains
+ the fonts and documentation source. <tt>X33src-3.tgz</tt> contains
+ the hardcopy documentation. <tt>X33src-1.tgz</tt> contains
+ everything else. If you don't need the docs or fonts you can get
+ by with only <tt>X33src-1.tgz</tt>.
+ <item>Extract each of these files by running the following from a directory
+ on a filesystem containing enough space (the full source requires
+ around 130MB, and a similar amount is required in addition to this
+ for the compiled binaries):
+ <quote><verb>
+ gzip -d < X33src-1.tgz | tar vxf -
+ gzip -d < X33src-2.tgz | tar vxf -
+ gzip -d < X33src-3.tgz | tar vxf -
+ </verb></quote>
+</itemize>
+
+Another option is to start with the X11R6.3 source distribution and patch
+it up to XFree86 3.3. In this case you need to do the following:
+<itemize>
+ <item>Start with the X Consortium's X11R6.3 distribution with public
+ patch 1 applied. This can be obtained by following the links
+ from the <url name="X homepage" url="http://www.x.org">.
+ <item>Get the files <tt>R6.3pl1-3.3.diff.gz</tt> and <tt>cfont33.tgz</tt>
+ from <htmlurl name="ftp://ftp.xfree86.org/pub/XFree86/3.3/patches/"
+ url="ftp://ftp.xfree86.org/pub/XFree86/3.3/patches/"> (or a similar
+ location on mirror sites). To upgrade the source to XFree86 3.3,
+ run the following from directory containing the <tt>xc</tt>
+ directory of the X11R6.3 pl1 source tree:
+ <quote><verb>
+ gzip -d < R6.3pl1-3.3.diff.gz | patch -p0 -E
+ gzip -d < cfont33.tgz | tar vxf -
+ </verb></quote>
+ Be sure to do this with a clean unmodified source tree. If you
+ don't some patches may fail.
+</itemize>
+
+If you only want to build the XFree86 X servers, you can use a cut-down
+version of the XFree86 source tree called the ``servers only'' distribution.
+If you choose this option, do the following:
+<itemize>
+ <item>Get the <tt>X33servonly.tgz</tt> file from
+ <htmlurl name="ftp://ftp.xfree86.org/pub/XFree86/3.3/source/"
+ url="ftp://ftp.xfree86.org/pub/XFree86/3.3/source/"> (or a similar
+ locations on mirror sites.
+ <item>Extract this by running the following:
+ <quote><verb>
+ gzip -d < X33servonly.tgz | tar vxf -
+ </verb></quote>
+</itemize>
+
+There is no patch to upgrade from the XFree86 3.2 source to 3.3. The
+reason for this is the large number of changes associated with the
+move from X11R6.1 to X11R6.3.
+
+XFree86 supports a small subset of the X Consortium X11R6.1 contrib
+distribution. If you wish to build this, you will need at least the
+following files/directories from that distribution:
+<tscreen><verb>
+ contrib/Imakefile
+ contrib/programs/Imakefile
+ contrib/programs/ico
+ contrib/programs/listres
+ contrib/programs/showfont
+ contrib/programs/viewres
+ contrib/programs/xbiff
+ contrib/programs/xcalc
+ contrib/programs/xditview
+ contrib/programs/xedit
+ contrib/programs/xev
+ contrib/programs/xeyes
+ contrib/programs/xfontsel
+ contrib/programs/xgc
+ contrib/programs/xload
+ contrib/programs/xman
+ contrib/programs/xmessage
+</verb></tscreen>
+You will also need the XFree86 patch <tt>contrib-3.3.diff.gz</tt>. To
+apply the patch, run the following from the directory containing the
+<tt>contrib</tt> directory:
+<tscreen><verb>
+ gzip -d < contrib-3.3.diff.gz | patch -p0 -E
+</verb></tscreen>
+
+If you wish to build the xtest distribution, get the source distribution
+<tt>X33test.tgz</tt> from the XFree86 source directory, and extract it
+by running:
+<tscreen><verb>
+ gzip -d < X33test.tgz | tar vxf -
+</verb></tscreen>
+Note, xtest is no longer part of the core X11 distribution (since X11R6.3).
+
+<sect1>Configuring the source before building
+<p>
+It is recommended that you start the configuration process by going to the
+<tt>xc/config/cf</tt> directory, and copying the file <tt>xf86site.def</tt>
+to <tt>host.def</tt>. Then read through the <tt>host.def</tt> file
+(which is heavily commented), and set any parameters that you want for
+your configuration. You can usually find out what the default settings
+are by checking the <tt>.cf</tt> file(s) relevant to your OS.
+
+Unlike previous versions, imake can now automatically detect and set
+the various <bf>OS*Version</bf> parameters, so you shouldn't need to
+enter those settings explicitly.
+
+If you are using just the <tt>X33src-1.tgz</tt> part of the source dist,
+you will need to define <bf>BuildFonts</bf> to <bf>NO</bf>.
+
+If you are using the ``servers only'' distribution, you will need to
+define <bf>BuildServersOnly</bf> to <bf>YES</bf>.
+
+<sect1>Building and installing the distribution
+<p>
+Before building the distribution, read through the OS-specific <tt/README/
+file in <tt>xc/programs/Xserver/hw/xfree86/doc</tt> that is relevant to
+you. Once those OS-specific details have been taken care of, go the
+<tt/xc/ directory and run ``<tt/make World/'' with the <bf/BOOTSTRAPCFLAGS/
+set as described in the OS-specific README (if necessary). It is
+advisable to redirect stdout and stderr to <tt/World.Log/ so that you
+can track down problems that might occur during the build.
+
+When the build is finished, you should check <tt/World.Log/ to see
+if there were any problems. If there weren't any then you can install
+the binaries. When using the full source distribution, the installation
+should be done from the <tt/xc/ directory. When using the ``servers only''
+distribution, the install should be done from the
+<tt>xc/programs/Xserver</tt> directory.
+To do
+the install, run ``<tt/make
+install/'' and ``<tt/make install.man/''. Make sure you have enough
+space in <tt>/usr/X11R6</tt> for the install to succeed. If you want
+to install on a filesystem other than <tt>/usr</tt>, make a symbolic
+link to <tt>/usr/X11R6</tt> before installing.
+
+To install the binary LinkKit (in <tt>/usr/X11R6/lib/Server</tt>),
+run ``<tt>make install.linkkit</tt>'' from the <tt/xc/ directory.
+
+To build the subset of the contrib release supported by
+XFree86, make sure that you have first built and installed the core
+distribution. Then go to the <tt/contrib/ directory and run
+``<tt/xmkmf -a; make/''. When that is completed, run
+``<tt/make install/'' and ``<tt/make install.man/'' to install it.
+
+To build/run the xtest distribution, refer to the instructions in
+the file <tt>test/xsuite/NOTES.xf86</tt>.
+
+<sect>Reconfiguring the server (source distribution)
+<p>
+To build a different set of servers or servers with a different set of
+drivers installed:
+<enum>
+<item>Make sure the source for any new drivers is in the correct place (e.g.,
+driver source for the SVGA server should be in a subdirectory of
+<tt>xc/programs/Xserver/hw/xfree86/vga256/drivers</tt>).
+
+<item>Change the settings of the server defines
+in <tt/host.def/ to specify which servers you
+wish to build. Also, change the driver lists to suit your needs.
+
+<item>From <tt>xc/programs/Xserver</tt>, run:
+<tscreen><verb>
+ make Makefile
+ make Makefiles
+ make depend
+ make
+</verb></tscreen>
+</enum>
+
+<sect>Reconfiguring the server (binary distribution)
+<p>
+
+If you have installed the server Binary LinkKit, it is possible to
+reconfigure the drivers and some of the extensions in the servers. For
+details of how to do this, please refer to the <htmlurl url="LinkKit.html"
+name="README.LinkKit"> file.
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/BUILD.sgml,v 3.3 1999/07/19 14:38:41 dawes Exp $
+</verb>
+
+</article>
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/Bsdi.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/Bsdi.sgml
new file mode 100644
index 000000000..163653b7d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/Bsdi.sgml
@@ -0,0 +1,327 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+
+<title>README for XFree86 3.1.2 on BSD/OS 2.0
+<author>Hans Nasten
+<date>24 July 1995
+<toc>
+
+<p>
+<bf>THIS DOCUMENT IS OUT OF DATE</bf>
+
+<sect> What and Where is XFree86? <p>
+XFree86 3.1.2 is a port of X11R6 that supports several versions of
+Intel-based Unix. It is derived from X386 1.2, which was the X server
+distributed with X11R5. This release consists of many new features
+and performance improvements as well as many bug fixes. The release
+is available as source patches against the X Consortium X11R6 code, as
+well as binary distributions for many architectures.
+
+The sources for XFree86 are available by anonymous ftp from:
+<p>
+<htmlurl
+ name="ftp://ftp.XFree86.org/pub/XFree86/current"
+ url="ftp://ftp.XFree86.org/pub/XFree86/current">
+<p>
+Binaries for BSD/OS 2.0 will be available from:
+<p>
+<htmlurl
+ name="ftp://ftp.XFree86.org/pub/XFree86/current/binaries/Bsdi"
+ url="ftp://ftp.XFree86.org/pub/XFree86/current/binaries/Bsdi">
+<p>
+If you're running a earlier version of BSD/OS, you'll have to build the
+distribution from source.
+Building the distribution on BSD/386 1.1 and 1.0 is untested, but believed to
+work correctly. If you run into trouble building on a earlier release, please
+let us know so that we can correct any incompatibilities.
+If you've done it and want to share your binaries, please let the Bsdi
+mailing list know.
+The binaries are built using gcc 2.6.3 as distributed with BSD/OS 2.0.
+If you build the distribution from source using a gcc compiler built using
+the generic gcc source code, you may run into problems using the binaries
+on a 386/486 not equipped with a math coprocessor.
+
+<sect>Bug Reports for This Document <p>
+Send email to <it>nasten@Everyware.SE</it> (Hans Nasten)
+or <it>XFree86@XFree86.org</it>
+if you have comments or suggestions about this file and we'll revise it.
+
+<sect>Installing the Binaries <p>
+The binary distribution is composed of a number of gzipped tar archives
+which contains the executables, servers, fonts, libraries, include files,
+man pages, config files, and the server link kit. All tar archives should
+be extracted as root with <tt>/</tt> as the default directory. The full
+distribution takes over 40MB of disk space.
+The file names are converted to be compatible with CD-rom conventions.
+
+Note that many clients were moved from the X11R6 distribution to the
+`contrib' area. However, they are still distributed with the
+XFree86 binary distribution.
+
+The contents of the archives are:
+<descrip>
+<tag>REQUIRED:</tag>
+ <descrip>
+ <tag/X312doc.tgz/ READMEs and XFree86 specific man pages.
+ <tag/X312bin.tgz/ all of the executable X client applications.
+ <tag/X312fnts.tgz/ all fonts except the cyrillic fonts
+ <tag/X312lib.tgz/ data files needed at runtime
+ </descrip>
+<tag>Choose at least one of the following to match your hardware:</tag>
+ <descrip>
+ <tag/X312SVGA.tgz/ the 8-bit pseudo-color X server for Super VGA cards
+ <tag/X312VG16.tgz/ the 4-bit pseudo-color X server for VGA &amp;
+ SVGA cards.
+ <tag/X312Mono.tgz/ the Monochrome X Server
+ <tag/X3128514.tgz/ the X server for IBM 8514/A and compatible boards
+ <tag/X312AGX.tgz/ the X server for AGX boards
+ <tag/X312Ma8.tgz/ the X server for ATI Mach8 boards
+ <tag/X312Ma32.tgz/ the X server for ATI Mach32 boards
+ <tag/X312Ma64.tgz/ the X server for ATI Mach64 boards
+ <tag/X312P9K.tgz/ the X server for P9000 based boards
+ <tag/X312S3.tgz/ the X server for S3 based boards
+ </descrip>
+<tag/OPTIONAL:</tag>
+ <descrip>
+ <tag/X312fsrv.tgz/ the font server with man pages.
+ <tag/X312cfnt.tgz/ cyrillic fonts
+ <tag/X312prog.tgz/ the <tt>include/X11</tt> header files and
+ static libraries needed only for compiling other X applications
+ <tag/X312man.tgz/ all man pages
+ <tag/X312link.tgz/ the server reconfiguration kit.
+ </descrip>
+</descrip>
+If this is your first time, then you should be able to safely
+install all of the packages. As a minimal install, you'll need doc,
+bin, fonts lib and one X server.
+
+To unpack and install the archives:
+<enum>
+ <item>create some destination directory in which you'd like the
+ X distribution to live. <tt>/usr/X11R6</tt> is recommended,
+ but if that partition is full (as it is on my machine), then just
+ create an alternate directory, and sym-link <tt>/usr/X11R6</tt>
+ to this place.
+
+ ie, on my machine, I do the following:
+
+<verb>
+ % cd /usr/local
+ % mkdir X11R6
+ % ln -s /usr/local/X11R6 /usr/X11R6
+</verb>
+
+ <item>You must be logged in as root to unpack the archives and use a
+ `<tt>umask</tt>' value of 022. Typing `<tt>umask 022</tt>' sets it.
+ Caution:
+ If you do not extract the files as user `<tt>root</tt>' with the
+ correct umask you may not be able to run XFree86 3.1.2. The X
+ server needs special permissions that are only granted to the
+ root user. You must also cd to <tt>/</tt> before extracting the
+ archives.
+
+ <item>Create a symbolic link in <tt>/usr/X11R6/bin</tt> named `X' that
+ points to
+ the server that matches your video card: See the XF86_* man pages
+ for hardware details. For example, if you have an ET4000 based SVGA
+ card:
+<verb>
+ cd /usr/X11R6/bin
+ rm -f X
+ ln -s XF86_SVGA X
+</verb>
+</enum>
+<bf>Note:</bf> you don't need to uncompress the fonts files in
+<tt>lib/X11/fonts</tt>.
+If you want to uncompress them anyway, don't forget to run
+`<tt>mkfontdir</tt>' in each directory after that.
+
+
+<sect>Installing Xdm, the display manager <p>
+The display manager makes your PC look like an X terminal. That is, it
+presents you with a login screen that runs under X.
+To start the display manager, log in as root on the console and type
+`<tt>xdm -nodaemon</tt>'.
+
+You can start xdm automatically on bootup by disabling the console getty
+and adding the following code to <tt>/etc/rc.local</tt>:
+
+<verb>
+ if [ -x /usr/X11R6/bin/xdm ]; then
+ echo -n ' xdm'; /usr/X11R6/bin/xdm
+ fi
+</verb>
+
+To disable the console getty, change `<tt>on</tt>' to `<tt>off</tt>'
+in the console entry in <tt>/etc/ttys</tt>:
+<verb>
+console "/usr/libexec/getty std.9600" ibmpc3 off secure
+</verb>
+
+<sect>Configuring X for Your Hardware <p>
+The <tt>XF86Config</tt> file tells the X server what kind of monitor, video
+card and mouse you have.
+You <em>must</em> create it to tell the server what specific hardware you have.
+
+XFree86 3.1 and later releases uses a new configuration file format.
+Consult the
+<tt>XF86Config</tt> man
+page and the general <tt>INSTALL</tt> file for instructions.
+
+If you have a <tt>Xconfig</tt> file for XFree86 2.x, use reconfig to
+translate part of
+it into the new format:
+<verb>
+ # reconfig <Xconfig >XF86Config
+</verb>
+and complete the rest according to the <tt>XF86Config</tt> man page and the
+<tt>XF86Config.sample</tt> file as a template.
+
+In order to protect your hardware from damage, the server will no longer read
+<tt>XF86Config</tt> files from a user's home directory, but requires that it
+be in <tt>/etc/XF86Config</tt>, <tt>/usr/X11R6/lib/X11/XF86Config.hostname</tt>
+or <tt>/usr/X11R6/lib/X11/XF86Config</tt>.
+
+You'll need info on your hardware:
+<itemize>
+ <item>Your mouse type, baud rate and its /dev entry.
+ <item>The video card's chipset (e.g. ET4000, S3, etc).
+ <item>Your monitor's sync frequencies.
+</itemize>
+The easiest way to find which device your mouse is plugged into is to use
+`<tt>cat</tt>' or `<tt>kermit</tt>' to look at the output of the mouse.
+Connect to it and just
+make sure that it generates output when the mouse is moved or clicked:
+<verb>
+ % cat < /dev/tty00
+</verb>
+If you can't find the right mouse device then use `<tt>dmesg|grep com</tt>'
+to get a list of devices that were detected upon booting:
+<verb>
+ % dmesg|grep com
+ com0 at isa0 iobase 0x3f8 irq 4
+</verb>
+<tt>com0</tt> is the hardware port used for <tt>/dev/tty00</tt> and
+<tt>com1</tt> is <tt>/dev/tty01</tt>.
+If you plan to fine tune the screen size or position on your monitor you'll
+need the specs for sync frequencies from your monitor's manual.
+
+<sect>Running X <p>
+8mb of memory is a recommended minimum for running X. The server,
+window manager and an xterm take about 4 Mb of memory themselves. On
+a 4Mb system that would leave nothing left over for the kernel and
+other applications like <tt>gcc</tt> that expect a few meg free.
+
+The easiest way for new users to start X windows is to type
+`<tt>xinit &gt;&amp; xinit.log</tt>'.
+Error messages are lost unless you redirect them because
+the server takes over the screen.
+
+To get out of X windows, type `<tt>exit</tt>' in the console xterm. You can
+customize your X by creating <tt>.xinitrc</tt>, <tt>.xserverrc</tt>,
+and <tt>.twmrc</tt> files in your home directory as described in the xinit and
+startx man pages.
+
+<sect>Rebuilding the XFree86 Distribution <p>
+The server link kit allows you to rebuild just the X server with a
+minimum amount of disk space. Just unpack it, make the appropriate
+changes to the site.def, type `<tt>./mkmf</tt>' and `<tt>make</tt>' to link
+the server.
+See <tt>/usr/X11R6/lib/Server/README</tt> for more info.
+
+See <tt>/usr/X11R6/lib/X11/etc/INSTALL</tt> for instructions on unbundling and
+building the source distribution. You will need about 250Mb free for the
+sources, objects and binaries during the build.
+
+You should configure the distribution by editing
+<tt>xc/config/cf/xf86site.def</tt>
+before compiling. To compile the sources, invoke
+<verb>
+ make World
+</verb>
+in the xc directory.
+
+<sect>Building New X Clients <p>
+The easiest way to build a new client (X application) is to use
+<tt>xmkmf</tt> if an Imakefile is included in the sources.
+Type `<tt>xmkmf</tt>' to create the Makefiles,
+check the configuration if necessary and type
+`<tt>make</tt>'. Whenever you install additional man pages you should update
+<tt>whatis.db</tt> by running `<tt>makewhatis /usr/X11R6/man</tt>'.
+To avoid the `<tt>Virtual memory exhausted</tt>' message from <tt>cc</tt>
+while compiling, increase the data and stack size limits
+(in <tt>csh</tt> type `<tt>limit datasize 32M</tt>' and
+`<tt>limit stacksize 16M</tt>').
+
+Note: Starting with XFree86 2.1, the symbol ``<tt>__386BSD__</tt>'' no
+longer gets defined or via the X config files for *BSD systems.
+When porting clients to *BSD systems,
+make use of the symbol ``<tt>BSD</tt>'' for code which is truly
+BSD-specific. The value of the symbol can be used to distinguish
+different BSD releases. For example, code specific to the Net-2 and
+later releases can use:
+<verb>
+#if (BSD >= 199103)
+</verb>
+To ensure that this symbol is correctly defined, include
+<tt>&lt;sys/param.h&gt;</tt> in the source that requires it. Note that
+the symbol <bf/CSRG_BASED/ is defined for *BSD systems in XFree86 3.1.1
+and later. This should be used to protect the inclusion of
+<tt>&lt;sys/param.h&gt;</tt>.
+
+For code that really is specific to a particular i386 BSD port, use
+<tt>__FreeBSD__</tt> for FreeBSD, <tt>__NetBSD__</tt> for NetBSD,
+<tt>__OpenBSD__</tt> for OpenBSD,
+<tt>__386BSD__</tt> for 386BSD, and <tt>__bsdi__</tt> for BSD/OS.
+
+
+<sect>Linear access to the frame buffer using BSD/386 1.1<p>
+The stock BSD/386 1.1 kernel has problems when trying to mmap the frame
+buffer as a linear ( unbanked ) memory area in high memory. This patch
+removes the check in <tt>/sys/i386/isa/vga.c</tt> that disables mmapping the
+frame buffer in linear mode. Please consult the BSD/386 1.1 release notes for
+instructions on how to build a new kernel. This patch is not needed on
+BSD/OS 2.0.
+<itemize>
+<item> save the patch below in a separate file.
+<item> cd to <tt>/sys/i386/isa</tt>.
+<item> apply the patch with
+ ``<tt>patch -p &lt;</tt><it>the_separate_patch_file</it>''
+<item> rebuild and install the new kernel.
+<item> reboot.
+</itemize>
+<tt>vga.c</tt> patch:
+<verb>
+*** vga.c.orig Sun Dec 19 09:35:01 1993
+--- vga.c Mon Oct 24 01:38:44 1994
+***************
+*** 159,165 ****
+ #if 0
+ if (off + NBPG > vgap->vga_mem_size)
+ return (-1);
+! #else
+ if (off + NBPG > IOM_END)
+ return (-1);
+ #endif
+--- 159,165 ----
+ #if 0
+ if (off + NBPG > vgap->vga_mem_size)
+ return (-1);
+! /*#else*/
+ if (off + NBPG > IOM_END)
+ return (-1);
+ #endif
+</verb>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/Bsdi.sgml,v 3.22 1997/12/05 22:01:35 hohndel Exp $
+
+
+
+
+
+$XConsortium: Bsdi.sgml /main/8 1996/10/27 11:05:51 kaleb $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/Config.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/Config.sgml
new file mode 100644
index 000000000..cb91d998b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/Config.sgml
@@ -0,0 +1,527 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<!-- Id: README.Config.sgml,v 1.1 1994/10/05 23:31:42 klemme Exp -->
+
+<article>
+
+<title>Configuring XFree86: A Step-By-Step Guide
+<author>David Wexelblat and The XFree86 Project, Inc
+<date>5 October 1994
+
+<abstract>
+ This document describes how to set up your XFree86 server and
+the corresponding <tt>XF86Config</tt> configuration file. If you follow the
+procedures in this document, you should have no problems getting your
+server up and running quickly.
+
+ This document is designed to be generic. Be certain to refer
+to the operating system specific <tt>README</tt> file for your OS (e.g.
+<tt>README.SVR4</tt>) and the card/chipset specific <tt>README</tt>
+file for you video card (e.g. <tt>README.trident</tt>).
+Where these specific files contradict this generic file, you should
+follow the specific instructions (there shouldn't be much of that, though).
+</abstract>
+
+
+
+<toc>
+
+
+<sect>Procedure Overview
+<p>
+ There are two steps to getting things up and running. The first
+is to select the appropriate server that you will be using and set it up
+as the default server. The second step is to set up the <tt>XF86Config</tt>
+file. This file is used to configure the server for your pointer device
+(e.g. mouse, trackball), video card, and monitor, as well as a few other
+things.
+
+ The <tt>XF86Config</tt> file contains several sections; these
+procedures will lead you through filling out each part.
+There is a default/sample <tt>XF86Config</tt> file in
+<tt>/usr/X11R6/lib/X11/XF86Config.sample</tt>; you should copy
+this to <tt>/usr/X11R6/lib/X11/XF86Config</tt>, and edit that file to your
+specific configuration.
+The <it>XF86Config(4/5)</it> manual page describes the
+<tt>XF86Config</tt> file contents and options in detail.
+Be sure to read through that manual page as you fill in your
+<tt>XF86Config</tt> file.
+
+The sections of the <tt>XF86Config</tt> file are:
+ <descrip>
+ <tag> Files </tag>
+ Sets the default font and RGB paths.
+ <tag> Server Flags</tag>
+ Sets a few general server options. Refer to the
+ manual page to learn about these.
+ <tag> Keyboard</tag>
+ Sets up keyboard devices, and sets a few optional
+ parameters.
+ <tag> Pointer</tag>
+ Sets up the pointer devices, and sets a few optional
+ parameters.
+ <tag> Monitor</tag>
+ Describes your monitor(s) to the server.
+ <tag> Graphics Device</tag>
+ Describes your video hardware to the server.
+ <tag> Screen.</tag>
+ Describes how the monitor and video hardware should
+ be used.
+ </descrip>
+
+
+<sect>Setting Up The Correct Default Server
+<p>
+
+The default server name is <tt>/usr/X11R6/bin/X</tt>.
+This is a link to a specific server binary <tt>XF86_xxxx</tt>, located
+in <tt>/usr/X11R6/bin/</tt>.
+You should check which server the X link is connected to.
+If it is not correct, remove it and make a new link to the correct
+binary.
+The server binaries are:
+ <descrip>
+ <tag>XF86_SVGA:</tag>
+ Super-VGA server. Contains accelerated support for
+ Cirrus 542{0,2,4,6,8,9}, 543{0,4} and Western
+ Digital 90C3{1,3} and Oak Technologies Inc. OTI087 chipsets,
+ unaccelerated for the rest of the supported chipsets.
+ <tag>XF86_Mono:</tag> (S)VGA monochrome, optionally Hercules
+ or other monochrome hardware support is linked in.
+ <tag>XF86_VGA16:</tag> Generic VGA 16-color server.
+ <tag>XF86_S3:</tag> S3 accelerated server.
+ <tag>XF86_Mach32:</tag> ATI Mach32 accelerated server.
+ <tag>XF86_Mach64:</tag> ATI Mach64 accelerated server.
+ <tag>XF86_Mach8:</tag> ATI Mach8 accelerated server.
+ <tag>XF86_8514:</tag> 8514/A accelerated server.
+ <tag>XF86_P9000:</tag> P9000 accelerated server.
+ <tag>XF86_AGX:</tag> AGX accelerated server.
+ </descrip>
+
+There is a manual page for each of these servers; refer to the manual
+page for specific details on supported chipsets and server-specific
+configuration options.
+
+ Note that it is possible to modify the drivers configured into
+a server via the LinkKit; the server binary may not contain all of
+the possible drivers, depending on how the distribution was assembled.
+You can run <tt>/usr/X11R6/bin/X -showconfig</tt> to get a printout of the
+configured drivers. If you need to relink your server, refer to the
+<tt>README</tt> file in the LinkKit for specific information.
+
+<sect>The Easy Parts of XF86Config
+<p>
+
+
+The "Files" section of the <tt>XF86Config</tt> file contains the path to
+the RGB database file (which should, in general, never need to be
+changed), and the default font path. You can have multiple FontPath
+lines in your <tt>XF86Config</tt>; they are concatenated. Ensure that each
+directory listed exists and is a valid font directory. If the server
+complains about "Can't open default font 'fixed'", it is because there
+is an invalid entry in your font path. Try running the 'mkfontdir'
+command in each directory if you are certain that each one is correct.
+The <it>XF86Config(4/5)</it> manual page describes other parameters that may be
+in this section of the file.
+
+ Next comes the "Keyboard" section. In this section, you can
+specify the keyboard protocol (Xqueue or Normal), the repeat rate, and
+the default mapping of some of the modifier keys. In general, nothing
+will need to be modified here. Users of non-English keyboards might want
+to change the definitions of the modifier keys. See the
+<it>XF86Config(4/5)</it> man page for details.
+
+ After this comes the "Pointer" section. In this section you can
+specify the pointer protocol and device. Note that the protocol name
+does not always match the manufacturer's name. For example, some
+Logitech mice (especially newer ones) require either the MouseMan or
+Microsoft protocols, not the Logitech protocol. Some other mouse
+parameters can be adjusted here. If you are using a two-button mouse,
+uncomment the Emulate3Buttons keyword - in this mode, pressing both
+mouse buttons simultaneously causes the server to report a middle button
+press.
+
+ Note that if the server complains about being unable to open
+your mouse device, this is NOT a server problem. It has been a very
+common misconfiguration error on several of the OSs, and 99.999&percnt; of the
+time it is because the device is not correctly configured in the OS.
+Hence don't bug us until after you prove that your OS level support
+is correct.
+
+<sect>Configuring the Video Hardware
+<p>
+
+The video hardware is described in the "Device" sections.
+Multiple device sections are permitted, and each section describes a
+single graphics board.
+
+ Be sure to read the server manual pages and the chipset-specific
+<tt>README</tt> files for any non-generic information that may apply to your
+setup.
+
+To create a Device section you need to collect the data for your
+hardware, and make some configuration decisions. The hardware data you
+need is:
+<itemize>
+ <item>Chipset
+ <item>Amount of video memory
+ <item>Dot-clocks available or clock chip used (if programmable)
+ <item>Ramdac type (for some servers)
+</itemize>
+The server, in general, is capable of filling these on its own, but it
+is best to fully specify things in the <tt>XF86Config</tt> file, so that no
+mistakes are made. The 'Chipset' is one of the keyword strings for a
+configured driver (which can be displayed by running 'X -showconfig').
+Of the accelerated servers, only some have chipset drivers currently.
+The amount of memory is specified in KBytes, so 1M of memory would be
+specified as 1024.
+
+ The dot-clocks are the trickiest part of card configuration.
+Fortunately a large database of collected dot-clocks is available. A
+list of Device entries for some graphics boards can be found in the
+`Devices' file. If you find one for your card, you can start with that.
+Also, the first part of the <tt>modeDB.txt</tt> file lists information for a
+myriad of SVGA cards. For accelerated cards, you can also look in the
+`AccelCards' file. If you are fortunate, your card is listed in one
+place or the other. If you find your card, copy the numbers from the
+database to the Clocks line in your <tt>XF86Config</tt> file, exactly as they
+appear in the database, without sorting, and leaving any duplicates.
+Note that some of the newer accelerated cards use a programmable clock
+generator, in which case a ClockChip line is used in your <tt>XF86Config</tt>
+file to identify the type of clock generator. (e.g. 'ClockChip
+"icd2061a"', which would be used for a &num;9 GXe board).
+
+ If you can't find a listing for your board, you can attempt to
+have the server detect them. Run the command 'X -probeonly >/tmp/out 2>&amp;1'
+(for sh or ksh) or 'X -probeonly >&amp;/tmp/out' (for csh). Be sure that the
+<tt>XF86Config</tt> file does <bf>not</bf> contain a Clocks line at
+this point. Running this
+will cause your monitor to freak out for a couple of seconds, as the
+server cycles through the clocks rapidly. It should not damage your
+monitor, but some newer monitors may shut themselves off because
+things may go out of spec. Anyhow, when this gets done, look in the
+file /tmp/out for the detected dot-clocks. Copy these to the Clocks
+line in your <tt>XF86Config</tt> file, exactly as they appear in
+/tmp/out.
+Don't sort them or rearrange them in any way.
+
+ It is possible that your board has a programmable clock
+generator. A symptom of this will be a printout of only 2 or 3 clock
+values, with the rest all zeros. If you run into this, and your board
+is not listed in the databases, contact the XFree86 team for help, or
+post a message to comp.windows.x.i386unix. Note that most current
+Diamond hardware falls into this category, and Diamond will not
+release the programming details, so we can't help you. There are some
+ethically questionable solutions available that you can inquire about
+on netnews; we do not advocate these methods, so do not contact us
+about them.
+
+ Some servers (S3 and AGX) require you to identify the type and
+speed of the RAMDAC your board uses in order to get the most out of the
+hardware. This is done by adding 'Ramdac' and 'DacSpeec' entries. For
+details of the supported RAMDACs, refer to the appropriate server manual
+page. Note, in previous versions of XFree86 the RAMDAC type was
+specified with an Option flag.
+
+ You may need to specify some Option flags for your hardware The
+server manual pages will describe these options, and the
+chipset-specific <tt>README</tt> files will tell you if any are required for your
+board.
+
+<sect>Configuring the Monitor and its Modes
+<p>
+
+ Configuring monitor modes can be a trying experience,
+unfortunately, because of the lack of standardization in monitor
+hardware. We have attempted to simplify this by collecting databases
+of specific monitor information, and assembling a set of "generic"
+modes that should get pretty much any monitor up and functional.
+For all the gory details of mode generation and tuning, refer to the
+`VideoModes.doc' document by Eric Raymond.
+
+ The monitor specs and video modes are described in the "Monitor"
+sections in the <tt>XF86Config</tt> file. To create a Monitor section, you need
+to know your monitor's specifications. In particular, you need to know
+what range of horizontal sync and vertical sync (refresh) rates it supports and
+what its video bandwidth is. This information should be available in
+the monitor's user manual. Also check the 'Monitors' file to see if it
+has an entry for your monitor. See the <it>XF86Config(4/5)</it>
+manual page for details of how this information is entered into the
+Monitor section.
+
+ Next, you need to provide a set of video modes that are suitable
+for the monitor. The first step is to check in the 'Monitors' and
+<tt>modeDB.txt</tt> files to see if there is a listing of modes for your
+specific monitor. If there is, copy those modes to the Monitor section
+of your <tt>XF86Config</tt> file. Verify that there is a clock listed on the
+Clocks line in your <tt>XF86Config</tt> that matches the dot-clock in the 2nd
+parameter of each mode line; delete any mode line that does not have a
+matching clock on your card. If you still have modes left, you are in
+good shape.
+
+ If you don't find any specific modes, or need more modes for the
+resolutions you want to use, refer to the Generic Video Modes listing
+below. Match the mode specification against your monitor's
+specifications; pick the highest-refresh mode that is within specs, and
+make sure you have a matching dot-clock on your Clocks line. Try the
+VESA modes before any corresponding alternate mode setting. Copy the
+mode specification to the Monitor section of your <tt>XF86Config</tt>
+file.
+Note that these modes are likely not optimal; they may not be sized
+perfectly, or may not be correctly centered. But they should get you up
+and running. If you want to tune the mode to your monitor, you can read
+the 'Fixing Problems with the Image' section of the VideoModes.doc file.
+
+ A note before you are done. If the same mode name occurs more
+than once in the Monitor section of the <tt>XF86Config</tt> file, the
+server will use the first mode with a matching clock.
+It is generally considered a bad idea to have more than one mode with
+the same name in your <tt>XF86Config</tt> file.
+
+<sect>Combining the Video Hardware and Monitor Data
+<p>
+
+ Once you have given a description of your monitor and graphics
+hardware you need to specify how they are to be used by the servers.
+This is done with the "Screen" sections in the <tt>XF86Config</tt>
+file. You need to supply a Screen section for each of the server
+driver types you will be using.
+The driver types are "SVGA" (XF86_SVGA), "VGA16" (XF86_VGA16), "VGA2"
+(XF86_Mono), "MONO" (XF86_Mono, XF86_VGA16), and "ACCEL" (XF86_S3,
+XF86_Mach32, XF86_Mach8, XF86_Mach64, XF86_8514, XF86_P9000, XF86_AGX).
+Each Screen section specifies which Monitor description and Device
+description are to be used.
+
+ The Screen sections include one or more "Display" subsections.
+One Display subsection may be provided for each depth that the server
+supports. In the Display subsection you can specify the size of the
+virtual screen the server will use. The virtual screen allows you to
+have a "root window" larger than can be displayed on your monitor (e.g.
+you can have an 800x600 display, but a 1280x1024 virtual size). The
+Virtual keyword is used to specify this size. Note that many of the new
+accelerated server use non-displayed memory for caching. It is not
+desirable to use all of your memory for virtual display, as this leaves
+none for caching, and this can cost as much as 30-40&percnt; of your server
+performance.
+
+ The last thing you specify in Display subsection is the display
+modes. These are the physical display resolutions that the server will
+use. The name is arbitrary, but must match something in the appropriate
+Monitor section. In general, these names are the display resolution
+(e.g. "1024x768"), but need not be. You can list as many as desired;
+the first is the default/starting display, and you can cycle through the
+list with Ctrl-Alt-Keypad+ or Ctrl-Alt-Keypad- hotkey sequences.
+
+ That's it. Now you're ready to test out your new XFree86
+installation.
+
+<sect>Generic Video Modes
+<p>
+<code>
+#
+# Mode Refresh Hor. Sync Dot-clock Interlaced? VESA?
+# ------------------------------------------------------------
+# 640x480 60Hz 31.5k 25.175M No No
+# 640x480 60Hz 31.5k 25.175M No No
+# 640x480 63Hz 32.8k 28.322M No No
+# 640x480 70Hz 36.5k 31.5M No No
+# 640x480 72Hz 37.9k 31.5M No Yes
+# 800x600 56Hz 35.1k 36.0M No Yes
+# 800x600 56Hz 35.4k 36.0M No No
+# 800x600 60Hz 37.9k 40.0M No Yes
+# 800x600 60Hz 37.9k 40.0M No No
+# 800x600 72Hz 48.0k 50.0M No Yes
+# 1024x768i 43.5Hz 35.5k 44.9M Yes No
+# 1024x768 60Hz 48.4k 65.0M No Yes
+# 1024x768 60Hz 48.4k 62.0M No No
+# 1024x768 70Hz 56.5k 75.0M No Yes
+# 1024x768 70Hz 56.25k 72.0M No No
+# 1024x768 76Hz 62.5k 85.0M No No
+# 1280x1024i 44Hz 51kHz 80.0M Yes No
+# 1280x1024i 44Hz 47.6k 75.0M Yes No
+# 1280x1024 59Hz 63.6k 110.0M No No
+# 1280x1024 61Hz 64.24k 110.0M No No
+# 1280x1024 74Hz 78.85k 135.0M No No
+
+#
+# 640x480@60Hz Non-Interlaced mode
+# Horizontal Sync = 31.5kHz
+# Timing: H=(0.95us, 3.81us, 1.59us), V=(0.35ms, 0.064ms, 1.02ms)
+#
+# name clock horizontal timing vertical timing flags
+ "640x480" 25.175 640 664 760 800 480 491 493 525
+
+#
+# Alternate 640x480@60Hz Non-Interlaced mode
+# Horizontal Sync = 31.5kHz
+# Timing: H=(1.27us, 3.81us, 1.27us) V=(0.32ms, 0.06ms, 1.05ms)
+#
+# name clock horizontal timing vertical timing flags
+ "640x480" 25.175 640 672 768 800 480 490 492 525
+
+#
+# 640x480@63Hz Non-Interlaced mode (non-standard)
+# Horizontal Sync = 32.8kHz
+# Timing: H=(1.41us, 1.41us, 5.08us) V=(0.24ms, 0.092ms, 0.92ms)
+#
+# name clock horizontal timing vertical timing flags
+ "640x480" 28.322 640 680 720 864 480 488 491 521
+
+#
+# 640x480@70Hz Non-Interlaced mode (non-standard)
+# Horizontal Sync = 36.5kHz
+# Timing: H=(1.27us, 1.27us, 4.57us) V=(0.22ms, 0.082ms, 0.82ms)
+#
+# name clock horizontal timing vertical timing flags
+ "640x480" 31.5 640 680 720 864 480 488 491 521
+
+#
+# VESA 640x480@72Hz Non-Interlaced mode
+# Horizontal Sync = 37.9kHz
+# Timing: H=(0.76us, 1.27us, 4.06us) V=(0.24ms, 0.079ms, 0.74ms)
+#
+# name clock horizontal timing vertical timing flags
+ "640x480" 31.5 640 664 704 832 480 489 492 520
+
+#
+# VESA 800x600@56Hz Non-Interlaced mode
+# Horizontal Sync = 35.1kHz
+# Timing: H=(0.67us, 2.00us, 3.56us) V=(0.03ms, 0.063ms, 0.70ms)
+#
+# name clock horizontal timing vertical timing flags
+ "800x600" 36 800 824 896 1024 600 601 603 625
+
+#
+# Alternate 800x600@56Hz Non-Interlaced mode
+# Horizontal Sync = 35.4kHz
+# Timing: H=(0.89us, 4.00us, 1.11us) V=(0.11ms, 0.057ms, 0.79ms)
+#
+# name clock horizontal timing vertical timing flags
+ "800x600" 36 800 832 976 1016 600 604 606 634
+
+#
+# VESA 800x600@60Hz Non-Interlaced mode
+# Horizontal Sync = 37.9kHz
+# Timing: H=(1.00us, 3.20us, 2.20us) V=(0.03ms, 0.106ms, 0.61ms)
+#
+# name clock horizontal timing vertical timing flags
+ "800x600" 40 800 840 968 1056 600 601 605 628 +hsync +vsync
+
+#
+# Alternate 800x600@60Hz Non-Interlaced mode
+# Horizontal Sync = 37.9kHz
+# Timing: H=(1.20us, 3.80us, 1.40us) V=(0.13ms, 0.053ms, 0.69ms)
+#
+# name clock horizontal timing vertical timing flags
+ "800x600" 40 800 848 1000 1056 600 605 607 633
+
+#
+# VESA 800x600@72Hz Non-Interlaced mode
+# Horizontal Sync = 48kHz
+# Timing: H=(1.12us, 2.40us, 1.28us) V=(0.77ms, 0.13ms, 0.48ms)
+#
+# name clock horizontal timing vertical timing flags
+ "800x600" 50 800 856 976 1040 600 637 643 666 +hsync +vsync
+
+#
+# 1024x768@43.5Hz, Interlaced mode (8514/A standard)
+# Horizontal Sync = 35.5kHz
+# Timing: H=(0.54us, 1.34us, 1.25us) V=(0.23ms, 0.23ms, 0.93ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1024x768i" 44.9 1024 1048 1208 1264 768 776 784 817 Interlace
+
+#
+# VESA 1024x768@60Hz Non-Interlaced mode
+# Horizontal Sync = 48.4kHz
+# Timing: H=(0.12us, 2.22us, 2.58us) V=(0.06ms, 0.12ms, 0.60ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1024x768" 65 1024 1032 1176 1344 768 771 777 806 -hsync -vsync
+
+#
+# 1024x768@60Hz Non-Interlaced mode (non-standard dot-clock)
+# Horizontal Sync = 48.4kHz
+# Timing: H=(0.65us, 2.84us, 0.65us) V=(0.12ms, 0.041ms, 0.66ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1024x768" 62 1024 1064 1240 1280 768 774 776 808
+
+#
+# VESA 1024x768@70Hz Non-Interlaced mode
+# Horizontal Sync=56.5kHz
+# Timing: H=(0.32us, 1.81us, 1.92us) V=(0.05ms, 0.14ms, 0.51ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1024x768" 75 1024 1048 1184 1328 768 771 777 806 -hsync -vsync
+
+#
+# 1024x768@70Hz Non-Interlaced mode (non-standard dot-clock)
+# Horizontal Sync=56.25kHz
+# Timing: H=(0.44us, 1.89us, 1.22us) V=(0.036ms, 0.11ms, 0.53ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1024x768" 72 1024 1056 1192 1280 768 770 776 806 -hsync -vsync
+
+#
+# 1024x768@76Hz Non-Interlaced mode
+# Horizontal Sync=62.5kHz
+# Timing: H=(0.09us, 1.41us, 2.45us) V=(0.09ms, 0.048ms, 0.62ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1024x768" 85 1024 1032 1152 1360 768 784 787 823
+
+#
+# 1280x1024@44Hz, Interlaced mode
+# Horizontal Sync=51kHz
+# Timing: H=(0.02us, 2.7us, 0.70us) V=(0.02ms, 0.24ms, 2.51ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1280x1024i" 80 1280 1296 1512 1568 1024 1025 1037 1165 Interlace
+
+#
+# Alternate 1280x1024@44Hz, Interlaced mode (non-standard dot-clock)
+# Horizontal Sync=47.6kHz
+# Timing: H=(0.42us, 2.88us, 0.64us) V=(0.08ms, 0.12ms, 0.96ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1280x1024i" 75 1280 1312 1528 1576 1024 1028 1034 1080 Interlace
+
+#
+# 1280x1024@59Hz Non-Interlaced mode (non-standard)
+# Horizontal Sync=63.6kHz
+# Timing: H=(0.36us, 1.45us, 2.25us) V=(0.08ms, 0.11ms, 0.65ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1280x1024" 110 1280 1320 1480 1728 1024 1029 1036 1077
+
+#
+# 1280x1024@61Hz, Non-Interlaced mode
+# Horizontal Sync=64.25kHz
+# Timing: H=(0.44us, 1.67us, 1.82us) V=(0.02ms, 0.05ms, 0.41ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1280x1024" 110 1280 1328 1512 1712 1024 1025 1028 1054
+
+#
+# 1280x1024@74Hz, Non-Interlaced mode
+# Horizontal Sync=78.85kHz
+# Timing: H=(0.24us, 1.07us, 1.90us) V=(0.04ms, 0.04ms, 0.43ms)
+#
+# name clock horizontal timing vertical timing flags
+ "1280x1024" 135 1280 1312 1456 1712 1024 1027 1030 1064
+
+
+</code>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/Config.sgml,v 3.13 1998/04/12 12:43:41 dawes Exp $
+
+
+
+
+
+$XConsortium: Config.sgml /main/7 1996/10/19 18:03:03 kaleb $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/DECtga.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/DECtga.sgml
new file mode 100644
index 000000000..5e891379a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/DECtga.sgml
@@ -0,0 +1,71 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN" [
+<!ENTITY % defs SYSTEM "defs.ent"> %defs;
+]>
+<article>
+
+<title>Information for DEC 21030 Users (aka TGA)
+<author>The XFree86 Project, Inc.
+<date>April 29th, 1999
+
+<ident>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/DECtga.sgml,v 3.8 1999/07/19 13:36:20 dawes Exp $
+</ident>
+
+<toc>
+
+<p>
+<sect>DEC 21030
+<p>
+<itemize>
+<item>The DEC 21030 is supported by XFree86 &relvers;. The driver is now
+partially accelerated. The built-in graphics on the Multia is
+supported in 8-plane mode, and PCI cards with 8 or 16 MB framebuffers
+are supported in 24-plane mode.
+
+<item>Current Known Problems
+
+<enum>
+
+<item>Virtual desktops and multiple modelines do not work. You should
+specify only one modeline.
+
+<item>Hardware cursor is only supported on systems with the BT485
+ramdac, ie the Multia.
+
+<item>After the server has been run using the hardware cursor, the
+Linux TGA console cursor (which also uses the hardware cursor) is
+shifted down by one pixel.
+
+</enum>
+
+<item>The following options may be specified for the 21030 driver:
+<descrip>
+<tag>BusID "PCI:?:??:?"</tag> Currently it is necessary to
+ specify the BusID so that the server will find the card.
+ Check /proc/pci and look for the bus, device, and function
+ numbers in the 21030 section. On a Multia, this should be
+ &dquot;PCI:0:11:0&dquot;.
+
+<tag>MemBase "0x???????"</tag> If the server does not
+ detect the base address of the 21030, then check /proc/pci for
+ the 21030 and look for the "Prefetchable 32 bit memory
+ at 0x???????" and enter this as your MemBase setting.
+
+<tag>Option "NoAccel"</tag>
+ Disables acceleration.
+
+<tag>Option "swcursor"</tag>
+ Disables the hardware cursor.
+
+</descrip>
+</itemize>
+
+<sect>Authors
+<p>
+<itemize>
+<item>Matthew Grossman, <email>mattg@oz.net</email>
+<item>Alan Hourihane, <email>alanh@fairlite.demon.co.uk</email>
+<item>Tim Rowley, <email>tor@cs.brown.edu</email>
+</itemize>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/DESIGN.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/DESIGN.sgml
new file mode 100644
index 000000000..67f2cbb7d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/DESIGN.sgml
@@ -0,0 +1,6903 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN" [
+ <!-- config file keyword markup -->
+ <!ENTITY s.key STARTTAG "bf">
+ <!ENTITY e.key ENDTAG "bf">
+ <!-- specific config file keywords -->
+ <!ENTITY k.device "&s.key;Device&e.key;">
+ <!ENTITY k.monitor "&s.key;Monitor&e.key;">
+ <!ENTITY k.display "&s.key;Display&e.key;">
+ <!ENTITY k.inputdevice "&s.key;InputDevice&e.key;">
+ <!ENTITY k.screen "&s.key;Screen&e.key;">
+ <!ENTITY k.serverlayout "&s.key;ServerLayout&e.key;">
+ <!ENTITY k.driver "&s.key;Driver&e.key;">
+ <!ENTITY k.module "&s.key;Module&e.key;">
+ <!ENTITY k.identifier "&s.key;Identifier&e.key;">
+ <!ENTITY k.serverflags "&s.key;ServerFlags&e.key;">
+ <!-- command line markup -->
+ <!ENTITY s.cmd STARTTAG "tt">
+ <!ENTITY e.cmd ENDTAG "tt">
+ <!-- inline code markup -->
+ <!ENTITY s.code STARTTAG "tt">
+ <!ENTITY e.code ENDTAG "tt">
+ <!-- function indent -->
+ <!ENTITY f.indent "&nl&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp">
+] >
+
+<article>
+
+<title>XFree86 X server ``New Design'' (DRAFT)
+<author>The XFree86 Project, Inc
+<date>Last modified 17 July 1999
+
+<ident>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/DESIGN.sgml,v 1.9 1999/07/18 03:26:51 dawes Exp $
+</ident>
+
+
+<p>
+<bf>NOTE</bf>: This is a DRAFT document, and the interfaces described here
+are subject to change without notice.
+
+
+<sect>Preface
+<p>
+
+The broad design principles are:
+<itemize>
+ <item>keep it reasonable
+ <itemize>
+ <item>We cannot rewrite the complete server
+ <item>We don't want to re-invent the wheel
+ </itemize>
+ <item>keep it modular
+ <itemize>
+ <item>As many things as possible should go into modules
+ <item>The basic loader binary should be minimal
+ <item>A clean design with well defined layering is important
+ <item>DDX specific global variables are a nono
+ <item>The structure should be flexible enough to allow
+ future extensions
+ <item> The structure should minimize duplication of common code
+ </itemize>
+ <item>keep important features in mind
+ <itemize>
+ <item>multiple screens, including multiple instances of drivers
+ <item>mixing different color depths and visuals on different
+ and ideally even on the same screen
+ <item>better control of the PCI device used
+ <item>better config file parser
+ <item>get rid of all VGA compatibility assumptions
+ </itemize>
+</itemize>
+
+Unless we find major deficiencies in the DIX layer, we should avoid
+making changes there.
+
+<sect>The XF86Config File
+<p>
+
+The XF86Config file format is similar to the old format, with the following
+changes:
+
+<sect1>&k.device; section
+<p>
+
+ The &k.device; sections are similar to what they used to be, and
+ describe hardware-specific information for a single video card.
+ &k.device;
+ Some new keywords are added:
+
+
+ <descrip>
+ <tag>Driver "drivername"</tag>
+ Specifies the name of the driver to be used for the card. This
+ is mandatory.
+ <tag>BusID "busslot"</tag>
+ Specifies uniquely the location of the card on the bus. The
+ purpose is to identify particular cards in a multi-headed
+ configuration. The format of the argument is intentionally
+ vague, and may be architecture dependent. For a PCI bus, it
+ is something like "bus:slot:func".
+ </descrip>
+
+ A &k.device; section is considered ``active'' if there is a reference
+ to it in an active &k.screen; section.
+
+<sect1>&k.screen; section
+<p>
+
+ The &k.screen; sections are similar to what they used to be. They
+ no longer have a &k.driver; keyword, but an &k.identifier; keyword
+ is added. (The &k.driver; keyword may be accepted in place of the
+ &k.identifier; keyword for compatibility purposes.) The identifier
+ can be used to identify which screen is to be active when multiple
+ &k.screen sections are present. It is possible to specify the active
+ screen from the command line. A default is chosen in the absence
+ of one being specified. A &k.screen; section is considered ``active''
+ if there is a reference to it either from the command line, or from
+ an active &k.serverlayout; section.
+
+<sect1>&k.inputdevice; section
+<p>
+
+ The &k.inputdevice; section is a new section that describes
+ configuration information for input devices. It replaces the old
+ &s.key;Keyboard&e.key;, &s.key;Pointer&e.key; and &s.key;XInput&e.key;
+ sections. Like the &k.device; section, it has two mandatory keywords:
+ &k.identifier; and &k.driver;. For compatibility purposes the old
+ &s.key;Keyboard&e.key; and &s.key;Pointer&e.key; sections are
+ converted by the parser into &k.inputdevice; sections as follows:
+
+ <descrip>
+ <tag>&s.key;Keyboard&e.key;</tag>
+ &k.identifier; "Implicit Core Keyboard"<newline>
+ &k.driver; "keyboard"
+ <tag>&s.key;Pointer&e.key;</tag>
+ &k.identifier; "Implicit Core Pointer"<newline>
+ &k.driver; "mouse"
+ </descrip>
+
+ An &k.inputdevice; section is considered active if there is a
+ reference to it in an active &k.serverlayout; section. An
+ &k.inputdevice; section may also be referenced implicitly if there
+ is no &k.serverlayout; section, if the &s.cmd;-screen&e.cmd; command
+ line options is used, or if the &k.serverlayout; section doesn't
+ reference any &k.inputdevice; sections. In this case, the first
+ sections with drivers "keyboard" and "mouse" are used as the core
+ keyboard and pointer respectively.
+
+<sect1>&k.serverlayout; section
+<p>
+
+ The &k.serverlayout; section is a new section that is used to identify
+ which &k.screen; sections are to be used in a multi-headed configuration,
+ and the relative layout of those screens. It also identifies which
+ &k.inputdevice; sections are to be used. Each &k.serverlayout section
+ has an identifier, a list of &k.screen; section identifiers, and a list of
+ &k.inputdevice; section identifiers. &k.serverflags; options may also be
+ included in a &k.serverlayout; section, making it possible to override
+ the global values in the &k.serverflags; section.
+
+ A &k.serverlayout; section can be made active by being referenced on
+ the command line. In the absence of this, a default will be chosen
+ (the first one found). The screen names may optionally be followed
+ by a number specifying the preferred screen number, and optionally
+ by the names of the four screens adjacent to it. The order of these
+ is top, bottom, left, right. When no screen number is specified,
+ they are numbered according to the order in which they are listed.
+ Here is an example of a &k.serverlayout; section for two screens, with
+ the second located to the right of the first:
+
+ <code>
+ Section "ServerLayout"
+ Identifier "Main Layout"
+ Screen "Screen 1" 0 "" "" "" "Screen 2"
+ Screen "Screen 2" 1
+ Screen "Screen 3"
+ EndSection
+ </code>
+
+<sect1>Options
+<p>
+
+ Options are used more extensively. They may appear in most sections
+ now. Options related to drivers can be present in the &k.screen;,
+ &k.device; and &k.monitor; sections and the &k.display; subsections.
+ The order of precedence is &k.display;, &k.screen;, &k.monitor;,
+ &k.device;. Options have been extended to allow an optional value
+ to be specified in addition to the option name. For more details
+ about options, see the <ref id="options" name="Options"> section
+ for details.
+
+<sect>Driver Interface
+<p>
+
+The driver interface consists of a minimal set of entry points that are
+required based on the external events that the driver must react to.
+No non-essential structure is imposed on the way they are used beyond
+that. This is a significant difference compared with the old design.
+
+The entry points for drawing operations are already taken care of by
+the framebuffer code (including, XAA). Extensions and enhancements to
+framebuffer code are outside the scope of this document.
+
+This approach to the driver interface provides good flexibility, but does
+increase the complexity of drivers. To help address this, the XFree86
+common layer provides a set of ``helper'' functions to take care of things
+that most drivers need. These helpers help minimise the amount of code
+duplication between drivers. The use of helper functions by drivers is
+however optional, though encouraged. The basic philosophy behind the
+helper functions is that they should be useful to many drivers, that
+they should balance this against the complexity of their interface. It
+is inevitable that some drivers may find some helpers unsuitable and
+need to provide their own code.
+
+Events that a driver needs to react to are:
+
+ <descrip>
+ <tag>ScreenInit</tag>
+
+ An initialisation function is called from the DIX layer for each
+ screen at the start of each server generation.
+
+ <tag>Enter VT</tag>
+
+ The server takes control of the console.
+
+ <tag>Leave VT</tag>
+
+ The server releases control of the console.
+
+ <tag>Mode Switch</tag>
+
+ Change video mode.
+
+ <tag>ViewPort change</tag>
+
+ Change the origin of the physical view port.
+
+ <tag>ScreenSaver state change</tag>
+
+ Screen saver activation/deactivation.
+
+ <tag>CloseScreen</tag>
+
+ A close screen function is called from the DIX layer for each screen
+ at the end of each server generation.
+ </descrip>
+
+
+In addition to these events, the following functions are required by
+the XFree86 common layer:
+
+ <descrip>
+ <tag>Identify</tag>
+
+ Print a driver identifying message.
+
+ <tag>Probe</tag>
+
+ This is how a driver identifies if there is any hardware present that
+ it knows how to drive.
+
+ <tag>PreInit</tag>
+
+ Process information from the XF86Config file, determine the
+ full characteristics of the hardware, and determine if a valid
+ configuration is present.
+ </descrip>
+
+The VidMode extension also requires:
+
+ <descrip>
+ <tag>ValidMode</tag>
+
+ Identify if a new mode is usable with the current configuration.
+ The PreInit function (and/or helpers it calls) may also make use
+ of the ValidMode function or something similar.
+ </descrip>
+
+
+Other extensions may require other entry points. The drivers will
+inform the common layer of these in such cases.
+
+<sect>Resource Access Control Introduction
+<p>
+
+Graphics devices are accessed through ranges in I/O or memory space.
+While most modern graphics devices allow relocation of such ranges many
+of them still require the use of well established interfaces such as
+VGA memory and IO ranges or 8514/A IO ranges. With modern buses (like
+PCI) it is possible for multiple video devices to share access to these
+resources. The RAC (Resource Access Control) subsystem provides a
+mechanism for this.
+
+<sect1>Terms and Definitions
+<p>
+
+<sect2>Bus
+<p>
+
+ ``Bus'' is ambiguous as it is used for different things: it may refer
+ to physical incompatible extension connectors in a computer system.
+ The RAC system knows two such systems: The ISA bus and the PCI bus.
+ (On the software level EISA, MCA and VL buses are currently treated
+ like ISA buses). ``Bus'' may also refer to logically different
+ entities on a single bus system which are connected via bridges. A
+ PCI system may have several distinct PCI buses connecting each other
+ by PCI-PCI bridges or to the host CPU by HOST-PCI bridges.
+
+ Systems that host more than one bus system link these together using
+ bridges. Bridges are a concern to RAC as they might block or pass
+ specific resources. PCI-PCI bridges may be set up to pass VGA
+ resources to the secondary bus. PCI-ISA buses pass any resources not
+ decoded on the primary PCI bus to the ISA bus. This way VGA resources
+ (although exclusive on the ISA bus) can be shared by ISA and PCI
+ cards. Currently HOST-PCI bridges are not yet handled by RAC as they
+ require specific drivers.
+
+<sect2>Entity
+<p>
+
+ The smallest independently addressable unit on a system bus is
+ referred to as an entity. So far we know ISA and PCI entities. PCI
+ entities can be located on the PCI bus by an unique ID consisting of
+ the bus, card and function number.
+
+<sect2>Resource
+<p>
+
+ ``Resource'' refers to a range of memory or I/O addresses an entity
+ can decode.
+
+ If a device is capable of disabling this decoding the resource is
+ called sharable. For PCI devices a generic method is provided to
+ control resource decoding. Other devices will have to provide a
+ device specific function to control decoding.
+
+ If the entity is capable of decoding this range at a different
+ location this resource is considered relocatable.
+
+ Resources which start at a specific address and occupy a single
+ continuous range are called block resources.
+
+ Alternatively resource addresses can be decoded in a way that they
+ satisfy the conditions:
+ <quote><verb>
+ address & mask == base
+ </verb></quote>
+ and
+ <quote><verb>
+ base & mask == base
+ </verb></quote>
+ Resources addressed in such a way are called sparse resources.
+
+<sect2>Server States
+<p>
+
+ The resource access control system knows two server states: the
+ SETUP and the OPERATING state. The SETUP state is entered whenever
+ a mode change takes place or the server exits or does VT switching.
+ During this state all entity resources are under resource access
+ control. During OPERATING state only those entities are controlled
+ which actually have shared resources that conflict with others.
+
+<sect>Control Flow in the Server and Mandatory Driver Functions
+<p>
+
+At the start of each server generation, &s.code;main()&e.code;
+(&s.code;dix/main.c&e.code;) calls the DDX function
+&s.code;InitOutput()&e.code;. This is the first place that the DDX gets
+control. &s.code;InitOutput()&e.code; is expected to fill in the global
+&s.code;screenInfo&e.code; struct, and one
+&s.code;screenInfo.screen[]&e.code; entry for each screen present. Here
+is what &s.code;InitOutput()&e.code; does:
+
+<sect1>Parse the XF86Config file
+<p>
+
+ This is done at the start of the first server generation only.
+
+ The XF86Config file is read in full, and the resulting information
+ stored in data structures. None of the parsed information is
+ processed at this point. The parser data structures are opaque to
+ the video drivers and to most of the common layer code.
+
+ The entire file is parsed first to remove any section ordering
+ requirements.
+
+
+<sect1>Initial processing of parsed information and command line options
+<p>
+
+ This is done at the start of the first server generation only.
+
+ The initial processing is to determine paths like the
+ &s.key;ModulePath&e.key;, etc, and to determine which &k.serverlayout;,
+ &k.screen; and &k.device; sections are active.
+
+
+<sect1>Enable port I/O access
+<p>
+
+ Port I/O access is controlled from the XFree86 common layer, and is
+ ``all or nothing''. It is enabled prior to calling driver probes, at
+ the start of subsequent server generations, and when VT switching
+ back to the Xserver. It is disabled at the end of server generations,
+ and when VT switching away from the Xserver.
+
+ The implementation details of this may vary on different platforms.
+
+
+<sect1>General bus probe
+<p>
+
+ This is done at the start of the first server generation only.
+
+ In the case of ix86 machines, this will be a general PCI probe.
+ The full information obtained here will be available to the drivers.
+ This information persists for the life of the Xserver. In the PCI
+ case, the PCI information for all video cards found is available by
+ calling &s.code;xf86GetPciVideoInfo()&e.code;.
+
+ <quote>
+ &s.code;pciVideoPtr *xf86GetPciVideoInfo(void)&e.code;
+ <quote><p>
+ returns a pointer to a list of pointers to
+ &s.code;pciVideoRec&e.code; entries, of which there is one for
+ each detected PCI video card. The list is terminated with a
+ &s.code;NULL&e.code; pointer. If no PCI video cards were
+ detected, the return value is &s.code;NULL&e.code;.
+
+ </quote>
+ </quote>
+
+ After the bus probe, the resource broker is initialised.
+
+
+<sect1>Load initial set of modules
+<p>
+
+ This is done at the start of the first server generation only.
+
+ The core server contains a list of mandatory modules. These are loaded
+ first. Currently the only module on this list is the bitmap font module.
+
+ The next set of modules loaded are those specified explicitly in the
+ &k.module; section of the config file.
+
+ The final set of initial modules are the driver modules referenced
+ by the active &k.device; and &k.inputdevice; sections in the config
+ file. Each of these modules is loaded exactly once.
+
+
+<sect1>Register Video and Input Drivers
+<p>
+
+ This is done at the start of the first server generation only.
+
+ When a driver module is loaded, the loader calls its
+ &s.code;Setup&e.code; function. For video drivers, this function
+ calls &s.code;xf86AddDriver()&e.code; to register the driver's
+ &s.code;DriverRec&e.code;, which contains a small set of essential
+ details and driver entry points required during the early phase of
+ &s.code;InitOutput()&e.code;. &s.code;xf86AddDriver()&e.code; adds
+ it to the global &s.code;xf86DriverList[]&e.code; array.
+
+ The &s.code;DriverRec&e.code; contains the driver's version, a short
+ descriptive message, the &s.code;Identify()&e.code; and
+ &s.code;Probe()&e.code; function entry points as well as a pointer
+ to the driver's module (as returned from the loader when the driver
+ was loaded) and a reference count which keeps track of how many
+ screens are using the driver. The entry driver entry points are
+ those required prior to the driver allocating and filling in its
+ &s.code;ScrnInfoRec&e.code;.
+
+ For a static server, the &s.code;xf86DriverList[]&e.code; array is
+ initialised at build time, and the loading of modules is not done.
+
+ A similar procedure is used for input drivers. The input driver's
+ &s.code;Setup&e.code; function calls
+ &s.code;xf86AddInputDriver()&e.code; to register the driver's
+ &s.code;InputDriverRec&e.code;, which contains a small set of
+ essential details and driver entry points required during the early
+ phase of &s.code;InitInput()&e.code;.
+ &s.code;xf86AddInputDriver()&e.code; adds it to the global
+ &s.code;xf86InputDriverList[]&e.code; array. For a static server,
+ the &s.code;xf86InputDriverList[]&e.code; array is initialised at
+ build time.
+
+ Both the &s.code;xf86DriverList[]&e.code; and
+ &s.code;xf86InputDriverList[]&e.code; arrays have been initialised
+ by the end of this stage.
+
+ Once all the drivers are registered, their
+ &s.code;ChipIdentify()&e.code; functions are called.
+
+ <quote>
+ &s.code;void ChipIdentify(int flags)&e.code;
+ <quote>
+ This is expected to print a message indicating the driver name,
+ a short summary of what it supports, and a list of the chipset
+ names that it supports. It may use the xf86PrintChipsets() helper
+ to do this.
+ </quote>
+ </quote>
+
+ <quote>
+ &s.code;void xf86PrintChipsets(const char *drvname, const char *drvmsg,
+ &f.indent;SymTabPtr chips)&e.code;
+ <quote>
+ This function provides an easy way for a driver's ChipIdentify
+ function to format the identification message.
+ </quote>
+ </quote>
+
+<sect1>Initialise Access Control
+<p>
+
+ This is done at the start of the first server generation only.
+
+ The Resource Access Control (RAC) subsystem is initialised before
+ calling any driver functions that may access hardware. All generic
+ bus information is probed and saved (for restoration later). All
+ (shared resource) video devices are disabled at the generic bus
+ level, and a probe is done to find the ``primary'' video device. These
+ devices remain disabled for the next step.
+
+
+<sect1>Video Driver Probe<label id="probe">
+<p>
+ This is done at the start of the first server generation only. The
+ &s.code;ChipProbe()&e.code; function of each registered video driver
+ is called.
+
+ <quote><p>
+ &s.code;Bool ChipProbe(DriverPtr drv, int flags)&e.code;
+ <quote><p>
+ The purpose of this is to identify all instances of hardware
+ supported by the driver. The flags value is currently not used,
+ and should be ignored by the driver.
+
+ The probe must find the active device sections that match the
+ driver by calling &s.code;xf86MatchDevice()&e.code;. The number
+ of matches found limits the maximum number of instances for this
+ driver. If no matches are found, the problem should return
+ &s.code;FALSE&e.code; immediately.
+
+ Devices that cannot be identified by using device-independent
+ methods should be probed at this stage (keeping in mind that access
+ to all resources that can be disabled in a device-independent way
+ are disabled during this phase). The probe must be a minimal
+ probe. It should just determine if there is a card present that
+ the driver can drive. It should use the least intrusive probe
+ methods possible. It must not do anything that is not essential,
+ like probing for other details such as the amount of memory
+ installed, etc. It is recommended that the
+ &s.code;xf86MatchPciInstances()&e.code; helper function be used
+ for identifying matching PCI devices, and similarly the
+ &s.code;xf86MatchIsaInstances()&e.code; for ISA (non-PCI) devices
+ (see the <ref id="rac" name="RAC"> section). These helpers also
+ checks and claims the appropriate entity. When not using the
+ helper, that should be done with &s.code;xf86CheckPciSlot()&e.code;
+ and &s.code;xf86ClaimPciSlot()&e.code; for PCI devices and
+ &s.code;xf86ClaimIsaSlot()&e.code; for ISA devices (see the
+ <ref id="rac" name="RAC"> section).
+
+ The probe must register all non-relocatable resources at this
+ stage. If a resource conflict is found between exclusive resources
+ the driver will fail immediately. This is usually best done with
+ the &s.code;xf86ConfigActivePciEntity()&e.code; helper function
+ for PCI and &s.code;xf86ConfigActiveIsaEntity()&e.code; for ISA
+ (see the <ref id="rac" name="RAC"> section). It is possible to
+ register some entity specific functions with those helpers. When
+ not using the helpers, the &s.code;xf86AddEntityToScreen()&e.code;
+ &s.code;xf86ClaimFixedResources()&e.code; and
+ &s.code;xf86SetEntityFuncs()&e.code; should be used instead (see
+ the <ref id="rac" name="RAC"> section).
+
+ If a chipset is specified in an active device section which the
+ driver considers relevant (ie it has no driver specified, or the
+ driver specified matches the driver doing the probe), the Probe
+ must return &s.code;FALSE&e.code; if the chipset doesn't match
+ one supported by the driver.
+
+ If there are no active device sections that the driver considers
+ relevant, it must return &s.code;FALSE&e.code;.
+
+ Allocate a &s.code;ScrnInfoRec&e.code; for each instance of the
+ hardware found, and fill in the basic information, including the
+ other driver entry points. The &s.code;xf86AllocateScreen()&e.code;
+ function must be used to allocate the &s.code;ScrnInfoRec&e.code;,
+ and it takes care of initialising fields to defined ``unused''
+ values.
+
+ Claim the entities for each instance of the hardware found. This
+ prevents other drivers from claiming the same hardware.
+
+ Must leave hardware in the same state it found it in, and must not
+ do any hardware initialisation.
+
+ All detection can be overridden via the config file, and that
+ parsed information is available to the driver at this stage.
+
+ Returns &s.code;TRUE&e.code; if one or more instances are found,
+ and &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+
+ &s.code;int xf86MatchDevice(const char *drivername,
+ &f.indent;GDevPtr **driversectlist)&e.code;
+ <quote><p>
+
+ This function takes the name of the driver and returns via
+ &s.code;driversectlist&e.code; a list of device sections that
+ match the driver name. The function return value is the number
+ of matches found. If a fatal error is encountered the return
+ value is &s.code;-1&e.code;.
+
+ The caller should use &s.code;xfree()&e.code; to free
+ &s.code;*driversectlist&e.code; when it is no longer needed.
+
+ </quote>
+
+ &s.code;ScrnInfoPtr xf86AllocateScreen(DriverPtr drv, int flags)&e.code;
+ <quote><p>
+ This function allocates a new &s.code;ScrnInfoRec&e.code; in the
+ &s.code;xf86Screens[]&e.code; array. This function is normally
+ called by the video driver &s.code;ChipProbe()&e.code; functions.
+ The return value is a pointer to the newly allocated
+ &s.code;ScrnInfoRec&e.code;. The &s.code;scrnIndex&e.code;,
+ &s.code;origIndex&e.code;, &s.code;module&e.code; and
+ &s.code;drv&e.code; fields are initialised. The reference count
+ in &s.code;drv&e.code; is incremented. The storage for any
+ currently allocated ``privates'' pointers is also allocated and
+ the &s.code;privates&e.code; field initialised (the privates data
+ is of course not allocated or initialised). This function never
+ returns on failure. If the allocation fails, the server exits
+ with a fatal error. The flags value is not currently used, and
+ should be set to zero.
+ </quote>
+ </quote>
+
+ At the completion of this, a list of &s.code;ScrnInfoRecs&e.code;
+ have been allocated in the &s.code;xf86Screens[]&e.code; array, and
+ the associated entities and fixed resources have been claimed. The
+ following &s.code;ScrnInfoRec&e.code; fields must be initialised at
+ this point:
+
+ <quote><verb>
+ driverVersion
+ driverName
+ scrnIndex(*)
+ origIndex(*)
+ drv(*)
+ module(*)
+ name
+ Probe
+ PreInit
+ ScreenInit
+ EnterVT
+ LeaveVT
+ numEntities
+ entityList
+ access
+ </verb></quote>
+
+ <tt>(*)</tt> These are initialised when the &s.code;ScrnInfoRec&e.code;
+ is allocated, and not explicitly by the driver.
+
+ The following &s.code;ScrnInfoRec&e.code; fields must be initialised
+ if the driver is going to use them:
+
+ <quote><verb>
+ SwitchMode
+ AdjustFrame
+ FreeScreen
+ ValidMode
+ </verb></quote>
+
+<sect1>Matching Screens
+<p>
+
+ This is done at the start of the first server generation only.
+
+ After the Probe phase is finished, there will be some number of
+ &s.code;ScrnInfoRecs&e.code;. These are then matched with the active
+ &k.screen; sections in the XF86Config, and those not having an active
+ &k.screen; section are deleted. If the number of remaining screens
+ is 0, &s.code;InitOutput()&e.code; sets
+ &s.code;screenInfo.numScreens&e.code; to &s.code;0&e.code; and
+ returns.
+
+ At this point the following fields of the &s.code;ScrnInfoRecs&e.code;
+ must be initialised:
+
+ <quote><verb>
+ confScreen
+ </verb></quote>
+
+
+<sect1>Allocate non-conflicting resources
+<p>
+
+ This is done at the start of the first server generation only.
+
+ Before calling the drivers again, the resource information collected
+ from the Probe phase is processed. This includes checking the extent
+ of PCI resources for the probed devices, and resolving any conflicts
+ in the relocatable PCI resources. It also reports conflicts, checks
+ bus routing issues, and anything else that is needed to enable the
+ entities for the next phase.
+
+ If any drivers registered an &s.code;EntityInit()&e.code; function
+ during the Probe phase, then they are called here.
+
+
+<sect1>Sort the Screens and pre-check Monitor Information
+<p>
+
+ This is done at the start of the first server generation only.
+
+ The list of screens is sorted to match the ordering requested in the
+ config file.
+
+ The list of modes for each active monitor is checked against the
+ monitor's parameters. Invalid modes are pruned.
+
+
+<sect1>PreInit
+<p>
+
+ This is done at the start of the first server generation only.
+
+ For each &s.code;ScrnInfoRec&e.code;, enable access to the screens entities and call
+ the &s.code;ChipPreInit()&e.code; function.
+
+ <quote><p>
+ &s.code;Bool ChipPreInit(ScrnInfoRec screen, int flags)&e.code;
+ <quote><p>
+ The purpose of this function is to find out all the information
+ required to determine if the configuration is usable, and to
+ initialise those parts of the &s.code;ScrnInfoRec&e.code; that
+ can be set once at the beginning of the first server generation.
+
+ The number of entities registered for the screen should be checked
+ against the expected number (most drivers expect only one). The
+ entity information for each of them should be retrieved (with
+ &s.code;xf86GetEntityInfo()&e.code;) and checked for the correct
+ bus type and that none of the sharable resources registered during
+ the Probe phase was rejected.
+
+ Access to resources for the entities that can be controlled in a
+ device-independent way are enabled before this function is called.
+ If the driver needs to access any resources that it has disabled
+ in an &s.code;EntityInit()&e.code; function that it registered,
+ then it may enable them here providing that it disables them before
+ this function returns.
+
+ This includes probing for video memory, clocks, ramdac, and all
+ other HW info that is needed. It includes determining the
+ depth/bpp/visual and related info. It includes validating and
+ determining the set of video modes that will be used (and anything
+ that is required to determine that).
+
+ This information should be determined in the least intrusive way
+ possible. The state of the HW must remain unchanged by this
+ function. Although video memory (including MMIO) may be mapped
+ within this function, it must be unmapped before returning. Driver
+ specific information should be stored in a structure hooked into
+ the &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code;
+ field. Any other modules which require persistent data (ie data
+ that persists across server generations) should be initialised in
+ this function, and they should allocate a ``privates'' index to
+ hook their data into by calling
+ &s.code;xf86AllocateScrnInfoPrivateIndex().&e.code; The ``privates''
+ data is persistent.
+
+ Helper functions for some of these things are provided at the
+ XFree86 common level, and the driver can choose to make use of
+ them.
+
+ All additional resources that the screen needs must be registered
+ here. This should be done with
+ &s.code;xf86RegisterResources()&e.code;. If some of the fixed
+ resources registered in the Probe phase are not needed or not
+ decoded by the hardware when in the OPERATING server state, their
+ status should be updated with
+ &s.code;xf86SetOperatingState()&e.code;.
+
+ Modules may be loaded at any point in this function, and all
+ modules that the driver will need must be loaded before the end
+ of this function. The &s.code;xf86LoadSubModule()&e.code; function
+ should be used to load modules. A driver may unload a module
+ within this function if it was only needed temporarily, and the
+ &s.code;UnloadSubModule()&e.code; function should be used to do
+ that. Otherwise there is no need to explicitly unload modules
+ because the loader takes care of module dependencies and will
+ unload submodules automatically if/when the driver module is
+ unloaded.
+
+ The bulk of the &s.code;ScrnInfoRec&e.code; fields should be filled
+ out in this function.
+
+ &s.code;ChipPreInit()&e.code; returns &s.code;FALSE&e.code; when
+ the configuration is unusable in some way (unsupported depth, no
+ valid modes, not enough video memory, etc), and &s.code;TRUE&e.code;
+ if it is usable.
+
+ It is expected that if the &s.code;ChipPreInit()&e.code; function
+ returns &s.code;TRUE&e.code;, then the only reasons that subsequent
+ stages in the driver might fail are lack or resources (like xalloc
+ failures). All other possible reasons for failure should be
+ determined by the &s.code;ChipPreInit()&e.code; function.
+
+ </quote>
+ </quote>
+
+ The &s.code;ScrnInfoRecs&e.code; for screens where the &s.code;ChipPreInit()&e.code; fails are removed.
+ If none remain, &s.code;InitOutput()&e.code; sets &s.code;screenInfo.numScreens&e.code; to &s.code;0&e.code; and returns.
+
+ At this point, further fields of the &s.code;ScrnInfoRecs&e.code; would normally be
+ filled in. Most are not strictly mandatory, but many are required
+ by other layers and/or helper functions that the driver may choose
+ to use. The documentation for those layers and helper functions
+ indicates which they require.
+
+ The following fields of the &s.code;ScrnInfoRecs&e.code; should be filled in if the
+ driver is going to use them:
+
+ <quote><verb>
+ monitor
+ display
+ depth
+ pixmapBPP
+ bitsPerPixel
+ weight (>8bpp only)
+ mask (>8bpp only)
+ offset (>8bpp only)
+ rgbBits (8bpp only)
+ gamma
+ defaultVisual
+ maxHValue
+ maxVValue
+ virtualX
+ virtualY
+ displayWidth
+ frameX0
+ frameY0
+ frameX1
+ frameY1
+ zoomLocked
+ modePool
+ modes
+ currentMode
+ progClock (TRUE if clock is programmable)
+ chipset
+ ramdac
+ clockchip
+ numClocks (if not programmable)
+ clock[] (if not programmable)
+ videoRam
+ biosBase
+ memBase
+ memClk
+ driverPrivate
+ chipID
+ chipRev
+ </verb></quote>
+
+ <quote><p>
+ &s.code;pointer xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)&e.code:
+ <quote><p>
+ Load a module that a driver depends on. This function loads the
+ module &s.code;name&e.code; as a sub module of the driver. The
+ return value is a handle identifying the new module. If the load
+ fails, the return value will be &s.code;NULL&e.code;. If a driver
+ needs to explicitly unload a module it has loaded in this way,
+ the return value must be saved and passed to
+ &s.code;UnloadSubModule()&e.code; when unloading.
+
+ </quote>
+
+ &s.code;void UnloadSubModule(pointer module)&e.code;
+ <quote><p>
+ Unloads the module referenced by &s.code;module&e.code;.
+ &s.code;module&e.code; should be a pointer returned previously
+ by &s.code;xf86LoadSubModule()&e.code;.
+
+ </quote>
+ </quote>
+
+<sect1>Cleaning up Unused Drivers
+<p>
+
+ At this point it is known which screens will be in use, and which
+ drivers are being used. Unreferenced drivers (and modules they
+ may have loaded) are unloaded here.
+
+
+<sect1>Consistency Checks
+<p>
+
+ The parameters that must be global to the server, like pixmap formats,
+ bitmap bit order, bitmap scanline unit and image byte order are
+ compared for each of the screens. If a mismatch is found, the server
+ exits with an appropriate message.
+
+
+<sect1>Check of Resource Control is Needed
+<p>
+
+ Determine if resource access control is needed. This is the case
+ if more than one screen is used. If necessary the RAC wrapper module
+ is loaded.
+
+<sect1>AddScreen (ScreenInit)
+<p>
+
+ At this point, the valid screens are known.
+ &s.code;AddScreen()&e.code; is called for each of them, passing
+ &s.code;ChipScreenInit()&e.code; as the argument.
+ &s.code;AddScreen()&e.code; is a DIX function that allocates a new
+ &s.code;screenInfo.screen[]&e.code; entry (aka
+ &s.code;pScreen&e.code;), and does some basic initialisation of it.
+ It then calls the &s.code;ChipScreenInit()&e.code; function, with
+ &s.code;pScreen&e.code; as one of its arguments. If
+ &s.code;ChipScreenInit()&e.code; returns &s.code;FALSE&e.code;,
+ &s.code;AddScreen()&e.code; returns &s.code;-1&e.code;. Otherwise
+ it returns the index of the screen. &s.code;AddScreen()&e.code;
+ should only fail because of programming errors or failure to allocate
+ resources (like memory). All configuration problems should be
+ detected BEFORE this point.
+
+ <quote><p>
+ &s.code;Bool ChipScreenInit(int index, ScreenPtr pScreen,
+ &f.indent;int argc, char **argv)&e.code;
+ <quote><p>
+ This is called at the start of each server generation.
+
+ Fill in all of &s.code;pScreen&e.code;, possibly doing some of
+ this by calling ScreenInit functions from other layers like mi,
+ framebuffers (cfb, etc), and extensions.
+
+ Decide which operations need to be placed under resource access
+ control. The classes of operations are the frame buffer operations
+ (&s.code;RAC_FB&e.code;), the pointer operations
+ (&s.code;RAC_CURSOR&e.code;), the viewport change operations
+ (&s.code;RAC_VIEWPORT&e.code;) and the colormap operations
+ (&s.code;RAC_COLORMAP&e.code;). Any operation that requires
+ resources which might be disabled during OPERATING state should
+ be set to use RAC. This can be specified separately for memory
+ and IO resources (the &s.code;racMemFlags&e.code; and
+ &s.code;racIoFlags&e.code; fields of the &s.code;ScrnInfoRec&e.code;
+ respectively).
+
+ Map any video memory or other memory regions.
+
+ Save the video card state. Enough state must be saved so that
+ the original state can later be restored.
+
+ Initialise the initial video mode. The &s.code;ScrnInfoRec&e.code;'s
+ &s.code;vtSema&e.code; field should be set to &s.code;TRUE&e.code;
+ just prior to changing the video hardware's state.
+
+ </quote>
+ </quote>
+
+
+ The &s.code;ChipScreenInit()&e.code; function (or functions from other
+ layers that it calls) should allocate entries in the
+ &s.code;ScreenRec&e.code;'s &s.code;devPrivates&e.code; area by
+ calling &s.code;AllocateScreenPrivateIndex()&e.code; if it needs
+ per-generation storage. Since the &s.code;ScreenRec&e.code;'s
+ &s.code;devPrivates&e.code; information is cleared for each server
+ generation, this is the correct place to initialise it.
+
+ After &s.code;AddScreen()&e.code; has successfully returned, the
+ following &s.code;ScrnInfoRec&e.code; fields are initialised:
+
+ <quote><verb>
+ pScreen
+ racMemFlags
+ racIoFlags
+ </verb></quote>
+
+ The &s.code;ChipScreenInit()&e.code; function should initialise the
+ &s.code;CloseScreen&e.code; and &s.code;SaveScreen&e.code; fields
+ of &s.code;pScreen&e.code;. The old value of
+ &s.code;pScreen-&gt;CloseScreen&e.code; should be saved as part of
+ the driver's per-screen private data, allowing it to be called from
+ &s.code;ChipCloseScreen()&e.code;. This means that the existing
+ &s.code;CloseScreen()&e.code; function is wrapped.
+
+<sect1>Finalising RAC Initialisation
+<p>
+
+ After all the &s.code;ChipScreenInit()&e.code; functions have been
+ called, each screen has registered its RAC requirements. This
+ information is used to determine which shared resources are requested
+ by more than one driver and set the access functions accordingly.
+ This is done following these rules:
+
+ <enum>
+ <item>The sharable resources registered by each entity are compared.
+ If a resource is registered by more than one entity the entity
+ will be marked to indicate that it needs to share this resources
+ type (IO or MEM).
+
+ <item>A resource marked ``disabled'' during OPERATING state will be
+ ignored entirely.
+
+ <item>A resource marked ``unused'' will only conflict with an overlapping
+ resource of an other entity if the second is actually in use
+ during OPERATING state.
+
+ <item>If an ``unused'' resource was found to conflict but the entity
+ does not use any other resource of this type the entire resource
+ type will be disabled for that entity.
+ </enum>
+
+
+<sect1>Finishing InitOutput()
+<p>
+
+ At this point &s.code;InitOutput()&e.code; is finished, and all the
+ screens have been setup in their initial video mode.
+
+
+<sect1>Mode Switching
+<p>
+
+ When a SwitchMode event is received, &s.code;ChipSwitchMode()&e.code;
+ is called (when it exists):
+
+ <quote><p>
+ &s.code;Bool ChipSwitchMode(int index, DisplayModePtr mode, int flags)&e.code;
+ <quote><p>
+ Initialises the new mode for the screen identified by
+ &s.code;index;&e.code;. The viewport may need to be adjusted
+ also.
+
+ </quote>
+ </quote>
+
+
+<sect1>Changing Viewport
+<p>
+
+ When a Change Viewport event is received,
+ &s.code;ChipAdjustFrame()&e.code; is called (when it exists):
+
+ <quote><p>
+ &s.code;void ChipAdjustFrame(int index, int x, int y, int flags)&e.code;
+ <quote><p>
+ Changes the viewport for the screen identified by
+ &s.code;index;&e.code;.
+
+ </quote>
+ </quote>
+
+
+<sect1>VT Switching
+<p>
+
+ When a VT switch event is received, &s.code;xf86VTSwitch()&e.code;
+ is called. &s.code;xf86VTSwitch()&e.code; does the following:
+
+ <descrip>
+ <tag>On ENTER:</tag>
+ <itemize>
+ <item>enable port I/O access
+
+ <item>save and initialise the bus/resource state
+
+ <item>enter the SETUP server state
+
+ <item>calls &s.code;ChipEnterVT()&e.code; for each screen
+
+ <item>enter the OPERATING server state
+
+ <item>validate GCs
+
+ <item>Restore fb from saved pixmap for each screen
+
+ <item>Enable all input devices
+ </itemize>
+ <tag>On LEAVE:</tag>
+ <itemize>
+ <item>Save fb to pixmap for each screen
+
+ <item>validate GCs
+
+ <item>enter the SETUP server state
+
+ <item>calls &s.code;ChipLeaveVT()&e.code; for each screen
+
+ <item>disable all input devices
+
+ <item>restore bus/resource state
+
+ <item>disables port I/O access
+ </itemize>
+ </descrip>
+
+ <quote><p>
+ &s.code;Bool ChipEnterVT(int index, int flags)&e.code;
+ <quote><p>
+ This function should map memory regions, initialise the current
+ video mode and initialise the viewport, turn on the HW cursor if
+ appropriate, etc.
+
+ Should it re-save the video state before initialising the video
+ mode?
+
+ </quote>
+
+ &s.code;void ChipLeaveVT(int index, int flags)&e.code;
+ <quote><p>
+ This function should restore the saved video state and unmap the
+ memory regions. If appropriate it should also turn off the HW
+ cursor, and invalidate any pixmap/font caches.
+
+ </quote>
+ </quote>
+
+ Other layers may wrap the &s.code;ChipEnterVT()&e.code; and
+ &s.code;ChipLeaveVT()&e.code; functions if they need to take some
+ action when these events are received.
+
+<sect1>End of server generation
+<p>
+
+ At the end of each server generation, the DIX layer calls
+ &s.code;ChipCloseScreen()&e.code; for each screen:
+
+ <quote><p>
+ &s.code;Bool ChipCloseScreen(int index, ScreenPtr pScreen)&e.code;
+ <quote><p>
+ This function should restore the saved video state and unmap the
+ memory regions.
+
+ It should also free per-screen data structures allocated by the
+ driver. Note that the persistent data held in the
+ &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; field
+ should not be freed here because it is needed by subsequent server
+ generations.
+
+ The &s.code;ScrnInfoRec&e.code;'s &s.code;vtSema&e.code; field
+ should be set to &s.code;FALSE&e.code; once the video HW state
+ has been restored.
+
+ Before freeing the per-screen driver data the saved
+ &s.code;CloseScreen&e.code; value should be restored to
+ &s.code;pScreen-&gt;CloseScreen&e.code;, and that function should
+ be called after freeing the data.
+
+ </quote>
+ </quote>
+
+<sect>Optional Driver Functions
+<p>
+
+The functions outlined here can be called from the XFree86 common layer,
+but their presence is optional.
+
+<sect1>Mode Validation
+<p>
+
+ When a mode validation helper supplied by the XFree86-common layer is
+ being used, it can be useful to provide a function to check for hw
+ specific mode constraints:
+
+ <quote><p>
+ &s.code;ModeStatus ChipValidMode(int index, DisplayModePtr mode,
+ &f.indent;Bool verbose, int flags)&e.code;
+ <quote><p>
+ Check the passed mode for hw-specific constraints, and return the
+ appropriate status value.
+
+ </quote>
+ </quote>
+
+<sect1>Free screen data
+<p>
+
+ When a screen is deleted prior to the completion of the ScreenInit
+ phase the &s.code;ChipFreeScreen()&e.code; function is called when defined.
+
+ <quote><p>
+ &s.code;void ChipFreeScreen(int scrnindex, int flags)&e.code;
+ <quote><p>
+ Free any driver-allocated data that may have been allocated up to
+ and including an unsuccessful &s.code;ChipScreenInit()&e.code;
+ call. This would predominantly be data allocated by
+ &s.code;ChipPreInit()&e.code; that persists across server
+ generations. It would include the &s.code;driverPrivate&e.code;,
+ and any ``privates'' entries that modules may have allocated.
+
+ </quote>
+ </quote>
+
+
+<sect>Recommended driver functions
+<p>
+
+The functions outlined here are for internal use by the driver only.
+They are entirely optional, and are never accessed directly from higher
+layers. The sample function declarations shown here are just examples.
+The interface (if any) used is up to the driver.
+
+<sect1>Save
+<p>
+
+ Save the video state. This could be called from &s.code;ChipScreenInit()&e.code; and
+ (possibly) &s.code;ChipEnterVT()&e.code;.
+
+ <quote><p>
+ &s.code;void ChipSave(ScrnInfoPtr pScrn)&e.code;
+ <quote><p>
+ Saves the current state. This will only be saving pre-server
+ states or states before returning to the server. There is only
+ one current saved state per screen and it is stored in private
+ storage in the screen.
+
+ </quote>
+ </quote>
+
+<sect1>Restore
+<p>
+
+ Restore the original video state. This could be called from the
+ &s.code;ChipLeaveVT()&e.code; and &s.code;ChipCloseScreen()&e.code;
+ functions.
+
+ <quote><p>
+ &s.code;void ChipRestore(ScrnInfoPtr pScrn)&e.code;
+ <quote><p>
+ Restores the saved state from the private storage. Usually only
+ used for restoring text modes.
+
+ </quote>
+ </quote>
+
+
+<sect1>Initialise Mode
+<p>
+
+ Initialise a video mode. This could be called from the
+ &s.code;ChipScreenInit()&e.code;, &s.code;ChipSwitchMode()&e.code;
+ and &s.code;ChipEnterVT()&e.code; functions.
+
+ <quote><p>
+ &s.code;Bool ChipModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)&e.code;
+ <quote><p>
+ Programs the hardware for the given video mode.
+
+ </quote>
+ </quote>
+
+
+<sect>Data and Data Structures
+<p>
+
+<sect1>Command line data
+<p>
+
+Command line options are typically global, and are stored in global
+variables. These variables are read-only and are available to drivers
+via a function call interface. Most of these command line values are
+processed via helper functions to ensure that they are treated consistently
+by all drivers. The other means of access is provided for cases where
+the supplied helper functions might not be appropriate.
+
+Some of them are:
+
+<quote><verb>
+ xf86Verbose verbosity level
+ xf86Bpp -bpp from the command line
+ xf86Depth -depth from the command line
+ xf86Weight -weight from the command line
+ xf86Gamma -{r,g,b,}gamma from the command line
+ xf86FlipPixels -flippixels from the command line
+ xf86ProbeOnly -probeonly from the command line
+ defaultColorVisualClass -cc from the command line
+</verb></quote>
+
+If we ever do allow for screen-specific command line options, we may
+need to rethink this.
+
+These can be accessed in a read-only manner by drivers with the following
+functions:
+
+ <quote><p>
+ &s.code;int xf86GetVerbosity()&e.code;
+ <quote><p>
+ Returns the value of &s.code;xf86Verbose&e.code;.
+
+ </quote>
+
+ &s.code;int xf86GetDepth()&e.code;
+ <quote><p>
+ Returns the &s.cmd;-depth&e.cmd; command line setting. If not
+ set on the command line, &s.code;-1&e.code; is returned.
+
+ </quote>
+
+ &s.code;rgb xf86GetWeight()&e.code;
+ <quote><p>
+ Returns the &s.cmd;-weight&e.cmd; command line setting. If not
+ set on the command line, &s.code;{0, 0, 0}&e.code; is returned.
+
+ </quote>
+
+ &s.code;Gamma xf86GetGamma()&e.code;
+ <quote><p>
+ Returns the &s.cmd;-gamma&e.cmd; or &s.cmd;-rgamma&e.cmd;,
+ &s.cmd;-ggamma&e.cmd;, &s.cmd;-bgamma&e.cmd; command line settings.
+ If not set on the command line, &s.code;{0.0, 0.0, 0.0}&e.code;
+ is returned.
+
+ </quote>
+
+ &s.code;Bool xf86GetFlipPixels()&e.code;
+ <quote><p>
+ Returns &s.code;TRUE&e.code; if &s.cmd;-flippixels&e.cmd; is
+ present on the command line, and &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+
+ &s.code;const char *xf86GetServerName()&e.code;
+ <quote><p>
+ Returns the name of the X server from the command line.
+
+ </quote>
+ </quote>
+
+<sect1>Data handling
+<p>
+
+Config file data contains parts that are global, and parts that are
+Screen specific. All of it is parsed into data structures that neither
+the drivers or most other parts of the server need to know about.
+
+The global data is typically not required by drivers, and as such, most
+of it is stored in the private &s.code;xf86InfoRec&e.code;.
+
+The screen-specific data collected from the config file is stored in
+screen, device, display, monitor-specific data structures that are separate
+from the &s.code;ScrnInfoRecs&e.code;, with the appropriate elements/fields
+hooked into the &s.code;ScrnInfoRecs&e.code; as required. The screen
+config data is held in &s.code;confScreenRec&e.code;, device data in
+the &s.code;GDevRec&e.code;, monitor data in the &s.code;MonRec&e.code;,
+and display data in the &s.code;DispRec&e.code;.
+
+The XFree86 common layer's screen specific data (the actual data in use
+for each screen) is held in the &s.code;ScrnInfoRecs&e.code;. As has
+been outlined above, the &s.code;ScrnInfoRecs&e.code; are allocated at probe
+time, and it is the responsibility of the Drivers' &s.code;Probe()&e.code;
+and &s.code;PreInit()&e.code; functions to finish filling them in based
+on both data provided on the command line and data provided from the
+Config file. The precedence for this is:
+
+ <quote>
+ command line -&gt; config file -&gt; probed/default data
+ </quote>
+
+For most things in this category there are helper functions that the
+drivers can use to ensure that the above precedence is consistently
+used.
+
+As well as containing screen-specific data that the XFree86 common layer
+(including essential parts of the server infrastructure as well as helper
+functions) needs to access, it also contains some data that drivers use
+internally. When considering whether to add a new field to the
+&s.code;ScrnInfoRec&e.code;, consider the balance between the convenience
+of things that lots of drivers need and the size/obscurity of the
+&s.code;ScrnInfoRec&e.code;.
+
+Per-screen driver specific data that cannot be accommodated with the
+static &s.code;ScrnInfoRec&e.code; fields is held in a driver-defined
+data structure, a pointer to which is assigned to the
+&s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; field. This
+is per-screen data that persists across server generations (as does the
+bulk of the static &s.code;ScrnInfoRec&e.code; data). It would typically
+also include the video card's saved state.
+
+Per-screen data for other modules that the driver uses (for example,
+the XAA module) that is reset for each server generation is hooked into
+the &s.code;ScrnInfoRec&e.code; through it's &s.code;privates&e.code;
+field.
+
+Once it has stabilised, the data structures and variables accessible to
+video drivers will be documented here. In the meantime, those things
+defined in the &s.code;xf86.h&e.code; and &s.code;xf86str.h&e.code;
+files are visible to video drivers. Things defined in
+&s.code;xf86Priv.h&e.code; and &s.code;xf86Privstr.h&e.code; are NOT
+intended to be visible to video drivers, and it is an error for a driver
+to include those files.
+
+
+<sect1>Accessing global data
+<p>
+
+Some other global state information that the drivers may access via
+functions is as follows:
+
+ <quote><p>
+ &s.code;Bool xf86ServerIsExiting()&e.code;
+ <quote><p>
+ Returns &s.code;TRUE&e.code; if the server is at the end of a
+ generation and is in the process of exiting, and
+ &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+
+ &s.code;Bool xf86ServerIsResetting()&e.code;
+ <quote><p>
+ Returns &s.code;TRUE&e.code; if the server is at the end of a
+ generation and is in the process of resetting, and
+ &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+
+ &s.code;Bool xf86ServerIsInitialising()&e.code;
+ <quote><p>
+ Returns &s.code;TRUE&e.code; if the server is at the beginning of
+ a generation and is in the process of initialising, and
+ &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+
+ &s.code;Bool xf86ServerIsOnlyProbing()&e.code;
+ <quote><p>
+ Returns &s.code;TRUE&e.code; if the -probeonly command line flag
+ was specified, and &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+
+ &s.code;Bool xf86CaughtSignal()&e.code;
+ <quote><p>
+ Returns &s.code;TRUE&e.code; if the server has caught a signal,
+ and &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+ </quote>
+
+<sect1>Allocating private data
+<p>
+
+A driver and any module it uses may allocate per-screen private storage
+in either the &s.code;ScreenRec&e.code; (DIX level) or
+&s.code;ScrnInfoRec&e.code; (XFree86 common layer level).
+&s.code;ScreenRec&e.code; storage persists only for a single server
+generation, and &s.code;ScrnInfoRec&e.code; storage persists across
+generations for the lifetime of the server.
+
+The &s.code;ScreenRec&e.code; &s.code;devPrivates&e.code; data must be
+reallocated/initialised at the start of each new generation. This is
+normally done from the &s.code;ChipScreenInit()&e.code; function, and
+Init functions for other modules that it calls. Data allocated in this
+way should be freed by the driver's &s.code;ChipCloseScreen()&e.code;
+functions, and Close functions for other modules that it calls. A new
+&s.code;devPrivates&e.code; entry is allocated by calling the
+&s.code;AllocateScreenPrivateIndex()&e.code; function.
+
+ <quote><p>
+ &s.code;int AllocateScreenPrivateIndex()&e.code;
+ <quote><p>
+ This function allocates a new element in the
+ &s.code;devPrivates&e.code; field of all currently existing
+ &s.code;ScreenRecs&e.code;. The return value is the index of this
+ new element in the &s.code;devPrivates&e.code; array. The
+ &s.code;devPrivates&e.code; field is of type
+ &s.code;DevUnion&e.code;:
+
+ <verb>
+ typedef union _DevUnion {
+ pointer ptr;
+ long val;
+ unsigned long uval;
+ pointer (*fptr)(void);
+ } DevUnion;
+ </verb>
+
+ which allows the element to be used for any of the above types.
+ It is commonly used as a pointer to data that the caller allocates
+ after the new index has been allocated.
+
+ This function will return &s.code;-1&e.code; when there is an
+ error allocating the new index.
+
+ </quote>
+ </quote>
+
+The &s.code;ScrnInfoRec&e.code; &s.code;privates&e.code; data persists
+for the life of the server, so only needs to be allocated once. This
+should be done from the &s.code;ChipPreInit()&e.code; function, and Init
+functions for other modules that it calls. Data allocated in this way
+should be freed by the driver's &s.code;ChipFreeScreen()&e.code; functions,
+and Free functions for other modules that it calls. A new
+&s.code;privates&e.code; entry is allocated by calling the
+&s.code;xf86AllocateScrnInfoPrivateIndex()&e.code; function.
+
+
+ <quote><p>
+ &s.code;int xf86AllocateScrnInfoPrivateIndex()&e.code;
+ <quote><p>
+ This function allocates a new element in the &s.code;privates&e.code;
+ field of all currently existing &s.code;ScrnInfoRecs&e.code;.
+ The return value is the index of this new element in the
+ &s.code;privates&e.code; array. The &s.code;privates&e.code;
+ field is of type &s.code;DevUnion&e.code;:
+
+ <verb>
+ typedef union _DevUnion {
+ pointer ptr;
+ long val;
+ unsigned long uval;
+ pointer (*fptr)(void);
+ } DevUnion;
+ </verb>
+
+ which allows the element to be used for any of the above types.
+ It is commonly used as a pointer to data that the caller allocates
+ after the new index has been allocated.
+
+ This function will not return when there is an error allocating
+ the new index. When there is an error it will cause the server
+ to exit with a fatal error. The similar function for allocation
+ privates in the &s.code;ScreenRec&e.code;
+ (&s.code;AllocateScreenPrivateIndex()&e.code;) differs in this
+ respect by returning &s.code;-1&e.code; when the allocation fails.
+
+ </quote>
+ </quote>
+
+<sect>Keeping Track of Bus Resources<label id="rac">
+<p>
+
+<sect1>Theory of Operation
+<p>
+
+The XFree86 common layer has knowledge of generic access control mechanisms
+for devices on certain bus systems (currently the PCI bus) as well as
+of methods to enable or disable access to the buses itself. Furthermore
+it can access information on resources decoded by these devices and if
+necessary modify it.
+
+When first starting the Xserver collects all this information, saves it
+for restoration, checks it for consistency, and if necessary, corrects
+it. Finally it disables all resources on a generic level prior to
+calling any driver function.
+
+When the &s.code;Probe()&e.code; function of each driver is called the
+device sections are matched against the devices found in the system.
+The driver may probe devices at this stage that cannot be identified by
+using device independent methods. Access to all resources that can be
+controlled in a device independent way is disabled. The
+&s.code;Probe()&e.code; function should register all non-relocatable
+resources at this stage. If a resource conflict is found between
+exclusive resources the driver will fail immediately. Optionally the
+driver might specify an &s.code;EntityInit()&e.code;,
+&s.code;EntityLeave()&e.code; and &s.code;EntityEnter()&e.code; function.
+
+&s.code;EntityInit()&e.code; can be used to disable any shared resources
+that are not controlled by the generic access control functions. It is
+called prior to the PreInit phase regardless if an entity is active or
+not. When calling the &s.code;EntityInit()&e.code;,
+&s.code;EntityEnter()&e.code; and &s.code;EntityLeave()&e.code; functions
+the common level will disable access to all other entities on a generic
+level. Since the common level has no knowledge of device specific
+methods to disable access to resources it cannot be guaranteed that
+certain resources are not decoded by any other entity until the
+&s.code;EntityInit()&e.code; or &s.code;EntityEnter()&e.code; phase is
+finished. Device drivers should therefore register all those resources
+which they are going to disable. If these resources are never to be
+used by any driver function they may be flagged &s.code;ResInit&e.code;
+so that they can be removed from the resource list after processing all
+&s.code;EntityInit()&e.code; functions. &s.code;EntityEnter()&e.code;
+should disable decoding of all resources which are not registered as
+exclusive and which are not handled by the generic access control in
+the common level. The difference to &s.code;EntityInit()&e.code; is
+that the latter one is only called once during lifetime of the server.
+It can therefore be used to set up variables prior to disabling resources.
+&s.code;EntityLeave()&e.code; should restore the original state when
+exiting the server or switching to a different VT. It also needs to
+disable device specific access functions if they need to be disabled on
+server exit or VT switch. The default state is to enable them before
+giving up the VT.
+
+In &s.code;PreInit()&e.code; phase each driver should check if any
+sharable resources it has registered during &s.code;Probe()&e.code; has
+been denied and take appropriate action which could simply be to fail.
+If it needs to access resources it has disabled during
+&s.code;EntitySetup()&e.code; it can do so provided it has registered
+these and will disable them before returning from
+&s.code;PreInit()&e.code;. This also applies to all other driver
+functions. Several functions are provided to request resource ranges,
+register these, correct PCI config space and add replacements for the
+generic access functions. Resources may be marked ``disabled'' or
+``unused'' during OPERATING stage. Although these steps could also be
+performed in &s.code;ScreenInit()&e.code;, this is not desirable.
+
+Following &s.code;PreInit()&e.code; phase the common level determines
+if resource access control is needed. This is the case if more than
+one screen is used. If necessary the RAC wrapper module is loaded. In
+&s.code;ScreenInit()&e.code; the drivers can decide which operations
+need to be placed under RAC. Available are the frame buffer operations,
+the pointer operations and the colormap operations. Any operation that
+requires resources which might be disabled during OPERATING state should
+be set to use RAC. This can be specified separately for memory and IO
+resources.
+
+When &s.code;ScreenInit()&e.code; phase is done the common level will
+determine which shared resources are requested by more than one driver
+and set the access functions accordingly. This is done following these
+rules:
+
+<enum>
+<item>The sharable resources registered by each entity are compared. If
+ a resource is registered by more than one entity the entity will be
+ marked to need to share this resources type (&s.code;IO&e.code; or
+ &s.code;MEM&e.code;).
+
+<item>A resource marked ``disabled'' during OPERATING state will be ignored
+ entirely.
+
+<item>A resource marked ``unused'' will only conflicts with an overlapping
+ resource of an other entity if the second is actually in use during
+ OPERATING state.
+
+<item>If an ``unused'' resource was found to conflict however the entity
+ does not use any other resource of this type the entire resource type
+ will be disabled for that entity.
+</enum>
+
+The driver has the choice among different ways to control access to
+certain resources:
+
+<enum>
+<item>It can rely on the generic access functions. This is probably the
+ most common case. Here the driver only needs to register any resource
+ it is going to use.
+
+<item>It can replace the generic access functions by driver specific
+ ones. This will mostly be used in cases where no generic access
+ functions are available. In this case the driver has to make sure
+ these resources are disabled when entering the &s.code;PreInit()&e.code;
+ stage. Since the replacement functions are registered in
+ &s.code;PreInit()&e.code; the driver will have to enable these
+ resources itself if it needs to access them during this state. The
+ driver can specify if the replacement functions can control memory
+ and/or I/O resources separately.
+
+<item>The driver can enable resources itself when it needs them. Each
+ driver function enabling them needs to disable them before it will
+ return. This should be used if a resource which can be controlled
+ in a device dependent way is only required during SETUP state. This
+ way it can be marked ``unused'' during OPERATING state.
+</enum>
+
+A resource which is decoded during OPERATING state however never accessed
+by the driver should be marked unused.
+
+Since access switching latencies are an issue during Xserver operation,
+the common level attempts to minimize the number of entities that need
+to be placed under RAC control. When a wrapped operation is called,
+the &s.code;EnableAccess()&e.code; function is called before control is
+passed on. &s.code;EnableAccess()&e.code; checks if a screen is under
+access control. If not it just establishes bus routing and returns.
+If the screen needs to be under access control,
+&s.code;EnableAccess()&e.code; determines which resource types
+(&s.code;MEM&e.code;, &s.code;IO&e.code;) are required. Then it tests
+if this access is already established. If so it simply returns. If
+not it disables the currently established access, fixes bus routing and
+enables access to all entities registered for this screen.
+
+Whenever a mode switch or a VT-switch is performed the common level will
+return to SETUP state.
+
+<sect1>Resource Types
+<p>
+
+Resource have certain properties. When registering resources each range
+is accompanied by a flag consisting of the ORed flags of the different
+properties the resource has. Each resource range may be classified
+according to
+
+<itemize>
+ <item>its physical properties i.e., if it addresses
+ memory (&s.code;ResMem&e.code;) or
+ I/O space (&s.code;ResIo&e.code;),
+ <item>if it addresses a
+ block (&s.code;ResBlock&e.code;) or
+ sparse (&s.code;ResSparse&e.code;)
+ range,
+ <item>its access properties.
+</itemize>
+
+There are two known access properties:
+
+<itemize>
+ <item>&s.code;ResExclusive&e.code;
+ for resources which may not be shared with any other device and
+ <item>&s.code;ResShared&e.code;
+ for resources which can be disabled and therefore can be shared.
+</itemize>
+
+If it is necessary to test a resource against any type a generic access
+type &s.code;ResAny&e.code; is provided. If this is set the resource
+will conflict with any resource of a different entity intersecting its
+range. Further it can be specified that a resource is decoded however
+never used during any stage (&s.code;ResUnused&e.code;) or during
+OPERATING state (&s.code;ResUnusedOpr&e.code;). A resource only visible
+during the init functions (ie. &s.code;EntityInit()&e.code;,
+&s.code;EntityEnter()&e.code; and &s.code;EntityLeave()&e.code; should
+be registered with the flag &s.code;ResInit&e.code;. A resource that
+might conflict with background resource ranges may be flagged with
+&s.code;ResBios&e.code;. This might be useful when registering resources
+ranges that were assigned by the system Bios.
+
+Several predefined resource lists are available for VGA and 8514/A
+resources in &s.code;common/xf86Resources.h&e.code;.
+
+<sect1>Available Functions<label id="avail">
+<p>
+
+The functions provided for resource management are listed in their order
+of use in the driver.
+
+
+<sect2>Probe Phase
+<p>
+
+In this phase each driver detects those resources it is able to drive,
+creates an entity record for each of them, registers non-relocatable
+resources and allocates screens and adds the resources to screens.
+
+Two helper functions are provided for matching device sections in the
+XF86Config file to the devices:
+
+ <quote><p>
+ &s.code;int xf86MatchPciInstances(const char *driverName, int vendorID,
+ &f.indent;SymTabPtr chipsets, PciChipsets *PCIchipsets,
+ &f.indent;GDevPtr *devList, int numDevs,
+ &f.indent;GDevPtr *devList, int numDevs, DriverPtr drvp,
+ &f.indent;int **foundEntities)&e.code;
+ <quote><p>
+ This function finds matches between PCI cards that a driver supports
+ and config file device sections. It is intended for use in the
+ &s.code;ChipProbe()&e.code; function of drivers for PCI cards.
+ Only probed PCI devices with a vendor ID matching
+ &s.code;vendorID&e.code; are considered. &s.code;devList&e.code;
+ and &s.code;numDevs&e.code; are typically those found from
+ calling &s.code;xf86MatchDevice()&e.code;, and represent the active
+ config file device sections relevant to the driver.
+ &s.code;PCIchipsets&e.code; is a table that provides a mapping
+ between the PCI device IDs, the driver's internal chipset tokens
+ and a list of fixed resources.
+
+ When a device section doesn't have a &s.key;BusID&e.key; entry it
+ can only match the primary video device. Secondary devices are
+ only matched with device sections that have a matching
+ &s.key;BusID&e.key; entry.
+
+ Once the preliminary matches have been found, a final match is
+ confirmed by checking if the chipset override, ChipID override or
+ probed PCI chipset type match one of those given in the
+ &s.code;chipsets&e.code; and &s.code;PCIchipsets&e.code; lists.
+ The &s.code;PCIchipsets&e.code; list includes a list of the PCI
+ device IDs supported by the driver. The list should be terminated
+ with an entry with PCI ID &s.code;-1&e.code;". The
+ &s.code;chipsets&e.code; list is a table mapping the driver's
+ internal chipset tokens to names, and should be terminated with
+ a &s.code;NULL&e.code; entry. Only those entries with a
+ corresponding entry in the &s.code;PCIchipsets&e.code; list are
+ considered. The order of precedence is: config file chipset,
+ config file ChipID, probed PCI device ID.
+
+ In cases where a driver handles PCI chipsets with more than one
+ vendor ID, it may set &s.code;vendorID&e.code; to
+ &s.code;0&e.code;, and OR each devID in the list with (the
+ vendor&nbsp;ID&nbsp;&lt;&lt;&nbsp;16).
+
+ Entity index numbers for confirmed matches are returned as an
+ array via &s.code;foundEntities&e.code;. The PCI information,
+ chipset token and device section for each match are found in the
+ &s.code;EntityInfoRec&e.code; referenced by the indices.
+
+ The function return value is the number of confirmed matches. A
+ return value of &s.code;-1&e.code; indicates an internal error.
+ The returned &s.code;foundEntities&e.code; array should be freed
+ by the driver with &s.code;xfree()&e.code; when it is no longer
+ needed in cases where the return value is greater than zero.
+
+ </quote>
+
+ &s.code;int xf86MatchIsaInstances(const char *driverName,
+ &f.indent;SymTabPtr chipsets, IsaChipsets *ISAchipsets,
+ &f.indent;DriverPtr drvp, FindIsaDevProc FindIsaDevice,
+ &f.indent;GDevPtr *devList, int numDevs,
+ int **foundEntities)&e.code;
+ <quote><p>
+ This function finds matches between ISA cards that a driver supports
+ and config file device sections. It is intended for use in the
+ &s.code;ChipProbe()&e.code; function of drivers for ISA cards.
+ &s.code;devList&e.code; and &s.code;numDevs&e.code; are
+ typically those found from calling &s.code;xf86MatchDevice()&e.code;,
+ and represent the active config file device sections relevant to
+ the driver. &s.code;ISAchipsets&e.code; is a table that provides
+ a mapping between the driver's internal chipset tokens and the
+ resource classes. &s.code;FindIsaDevice&e.code; is a
+ driver-provided function that probes the hardware and returns the
+ chipset token corresponding to what was detected, and
+ &s.code;-1&e.code; if nothing was detected.
+
+ If the config file device section contains a chipset entry, then
+ it is checked against the &s.code;chipsets&e.code; list. When
+ no chipset entry is present, the &s.code;FindIsaDevice&e.code;
+ function is called instead.
+
+ Entity index numbers for confirmed matches are returned as an
+ array via &s.code;foundEntities&e.code;. The chipset token and
+ device section for each match are found in the
+ &s.code;EntityInfoRec&e.code; referenced by the indices.
+
+ The function return value is the number of confirmed matches. A
+ return value of &s.code;-1&e.code; indicates an internal error.
+ The returned &s.code;foundEntities&e.code; array should be freed
+ by the driver with &s.code;xfree()&e.code; when it is no longer
+ needed in cases where the return value is greater than zero.
+
+ </quote>
+ </quote>
+
+These two helper functions make use of several core functions that are
+available at the driver level:
+
+ <quote><p>
+ &s.code;Bool xf86ParsePciBusString(const char *busID, int *bus,
+ &f.indent;int *device, int *func)&e.code;
+ <quote><p>
+ Takes a &s.code;BusID&e.code; string, and if it is in the correct
+ format, returns the PCI &s.code;bus&e.code;, &s.code;device&e.code;,
+ &s.code;func&e.code; values that it indicates. The format of the
+ string is expected to be "PCI:bus:device:func" where each of `bus',
+ `device' and `func' are decimal integers. The ":func" part may
+ be omitted, and the func value assumed to be zero, but this isn't
+ encouraged. The "PCI" prefix may also be omitted. The prefix
+ "AGP" is currently equivalent to the "PCI" prefix. If the string
+ isn't a valid PCI BusID, the return value is &s.code;FALSE&e.code;.
+
+ </quote>
+
+
+ &s.code;Bool xf86ComparePciBusString(const char *busID, int bus,
+ &f.indent;int device, int func)&e.code;
+ <quote><p>
+ Compares a &s.code;BusID&e.code; string with PCI &s.code;bus&e.code;,
+ &s.code;device&e.code;, &s.code;func&e.code; values. If they
+ match &s.code;TRUE&e.code; is returned, and &s.code;FALSE&e.code;
+ if they don't.
+
+ </quote>
+
+ &s.code;Bool xf86ParseIsaBusString(const char *busID)&e.code;
+ <quote><p>
+ Compares a &s.code;BusID&e.code; string with the ISA bus ID string
+ ("ISA" or "ISA:"). If they match &s.code;TRUE&e.code; is returned,
+ and &s.code;FALSE&e.code; if they don't.
+
+ </quote>
+
+ &s.code;Bool xf86CheckPciSlot(int bus, int device, int func)&e.code;
+ <quote><p>
+ Checks if the PCI slot &s.code;bus:device:func&e.code; has been
+ claimed. If so, it returns &s.code;FALSE&e.code;, and otherwise
+ &s.code;TRUE&e.code;.
+
+ </quote>
+
+ &s.code;int xf86ClaimPciSlot(int bus, int device, int func, DriverPtr drvp,
+ &f.indent;int chipset, GDevPtr dev, Bool active)&e.code;
+ <quote><p>
+ This function is used to claim a PCI slot, allocate the associated
+ entity record and initialise their data structures. The return
+ value is the index of the newly allocated entity record, or
+ &s.code;-1&e.code; if the claim fails. This function should always
+ succeed if &s.code;xf86CheckPciSlot()&e.code; returned
+ &s.code;TRUE&e.code; for the same PCI slot.
+
+ </quote>
+
+ &s.code;Bool xf86IsPrimaryPci(void)&e.code;
+ <quote><p>
+ This function returns &s.code;TRUE&e.code; if the primary card is
+ a PCI device, and &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+
+ &s.code;int xf86ClaimIsaSlot(DriverPtr drvp, int chipset,
+ &f.indent;GDevPtr dev, Bool active)&e.code;
+ <quote><p>
+ This allocates an entity record entity and initialise the data
+ structures. The return value is the index of the newly allocated
+ entity record.
+
+ </quote>
+
+ &s.code;Bool xf86IsPrimaryIsa(void)&e.code;
+ <quote><p>
+ This function returns &s.code;TRUE&e.code; if the primary card is
+ an ISA (non-PCI) device, and &s.code;FALSE&e.code; otherwise.
+
+ </quote>
+ </quote>
+
+Two helper functions are provided to aid configuring entities:
+ <quote><p>
+ &s.code;Bool xf86ConfigActivePciEntity(ScrnInfoPtr pScrn, int entityIndex,
+ &f.indent;PciChipsets *p_chip, resList res,
+ &f.indent;EntityProc init, EntityProc enter,
+ &f.indent;EntityProc leave, pointer private)&e.code;
+ <p>
+ &s.code;Bool xf86ConfigActiveIsaEntity(ScrnInfoPtr pScrn, int entityIndex,
+ &f.indent;IsaChipsets *i_chip, resList res,
+ &f.indent;EntityProc init, EntityProc enter,
+ &f.indent;EntityProc leave, pointer private)&e.code;
+ <quote><p>
+ These functions are used to register the non-relocatable resources
+ for an entity, and the optional entity-specific &s.code;Init&e.code;, &s.code;Enter&e.code; and
+ &s.code;Leave&e.code; functions. Usually the list of fixed resources is obtained
+ from the Isa/PciChipsets lists. However an additional list of
+ resources may be passed. Generally this is not required. The
+ return value is &s.code;TRUE&e.code; when successful. The init, enter, leave
+ functions are defined as follows:
+
+ <quote>
+ &s.code;typedef void (*EntityProc)(int entityIndex,
+ &f.indent;pointer private)&e.code;
+ </quote>
+
+ They are passed the entity index and a pointer to a private scratch
+ area. This are can be set up during &s.code;Probe()&e.code; and
+ its address can be passed to
+ &s.code;xf86ConfigActiveIsaEntity()&e.code;
+ &s.code;xf86ConfigActivePciEntity()&e.code; as the last argument.
+
+ </quote>
+ </quote>
+
+These two helper functions make use of several core functions that are
+available at the driver level:
+ <quote><p>
+ &s.code;void xf86ClaimFixedResources(resList list, int entityIndex)&e.code;
+ <quote><p>
+ This function registers the non-relocatable resources which cannot
+ be disabled and which therefore would cause the server to fail
+ immediately if they were found to conflict. It also records
+ non-relocatable but sharable resources for processing after the
+ &s.code;Probe()&e.code; phase.
+
+ </quote>
+
+ &s.code;Bool xf86SetEntityFuncs(int entityIndex, EntityProc init,
+ &f.indent;EntityProc enter, EntityProc leave, pointer)&e.code;
+ <quote><p>
+ This function registers with an entity the &s.code;init&e.code;,
+ &s.code;enter&e.code;, &s.code;leave&e.code; functions along
+ with the pointer to their private area.
+
+ </quote>
+
+ &s.code;void xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex)&e.code;
+ <quote><p>
+ This function associates the entity referenced by
+ &s.code;entityIndex&e.code; with the screen.
+
+ </quote>
+ </quote>
+
+<sect2>PreInit Phase
+<p>
+
+During this phase the remaining resource should be registered.
+&s.code;PreInit()&e.code; should call &s.code;xf86GetEntityInfo()&e.code;
+To obtain a pointer to an &s.code;EntityInfoRec&e.code; for each entity
+it is able to drive and check if any resource are listed in its
+&s.code;resources&e.code; field. If resources registered in the Probe
+phase have been rejected in the post-Probe phase
+(&s.code;resources&nbsp;==&nbsp;NULL&e.code;), then the driver should
+decide if it can continue without using these or if it should fail.
+
+ <quote><p>
+ &s.code;EntityInfoPtr xf86GetEntityInfo(int entityIndex)&e.code;
+ <quote><p>
+ This function returns a pointer to the &s.code;EntityInfoRec&e.code;
+ referenced by &s.code;entityIndex&e.code;. The returned
+ &s.code;EntityInfoRec&e.code; should be freed with
+ &s.code;xfree()&e.code; when no longer needed.
+
+ </quote>
+ </quote>
+Several functions are provided to simplify resource registration:
+ <quote><p>
+ &s.code;Bool xf86IsEntityPrimary(int entityIndex)&e.code;
+ <quote><p>
+ This function returns &s.code;TRUE&e.code; if the entity referenced
+ by &s.code;entityIndex&e.code; is the display device that primary
+ display device (i.e., the one initialised at boot time and used
+ in text mode).
+
+ </quote>
+
+ &s.code;Bool xf86IsScreenPrimary(int scrnIndex)&e.code;
+ <quote><p>
+ This function returns &s.code;TRUE&e.code; if the primary entity
+ is registered with the screen referenced by
+ &s.code;scrnIndex&e.code;.
+
+ </quote>
+
+ &s.code;pciVideoPtr xf86GetPciInfoForEntity(int entityIndex)&e.code;
+ <quote><p>
+ This function returns a pointer to the &s.code;pciVideoRec&e.code;
+ for the specified entity. If the entity is not a PCI device,
+ &s.code;NULL&e.code; is returned.
+
+ </quote>
+ </quote>
+
+The primary function for registration of resources is:
+ <quote><p>
+ &s.code;resPtr xf86RegisterResources(int entityIndex, resList list,
+ &f.indent;int access)&e.code;
+ <quote><p>
+ This function tries to register the resources in
+ &s.code;list&e.code;. If list is &s.code;NULL&e.code; it tries
+ to determine the resources automatically. This only works for
+ entities that provide a generic way to read out the resource ranges
+ they decode. So far this is only the case for PCI devices. By
+ default the PCI resources are registered as shared
+ (&s.code;ResShared&e.code;) if the driver wants to set a different
+ access type it can do so by specifying the access flags in the
+ third argument. A value of &s.code;0&e.code; means to use the
+ default settings. If for any reason the resource broker is not
+ able to register some of the requested resources the function will
+ return a pointer to a list of the failed ones. In this case the
+ driver may be able to move the resource to different locations.
+ In case of PCI bus entities this is done by passing the list of
+ failed resources to &s.code;xf86ReallocatePciResources()&e.code;.
+ When the registration succeeds, the return value is
+ &s.code;NULL&e.code;.
+
+ </quote>
+
+ &s.code;resPtr xf86ReallocatePciResources(int entityIndex, resPtr pRes)&e.code;
+ <quote><p>
+ This function takes a list of PCI resources that need to be
+ reallocated and returns a list of the reallocated resource. This
+ list needs to be passed to &s.code;xf86RegisterResources()&e.code; again to be
+ registered with the broker. If the reallocation fails, &s.code;NULL&e.code; is
+ returned.
+
+ </quote>
+ </quote>
+
+Two functions are provided to obtain a resource range of a given type:
+ <quote><p>
+ &s.code;resRange xf86GetBlock(long type, memType size,
+ &f.indent;memType window_start, memType window_end,
+ &f.indent;memType align_mask, resPtr avoid)&e.code;
+ <quote><p>
+ This function tries to find a block range of size
+ &s.code;size&e.code; and type &s.code;type&e.code; in a window
+ bound by &s.code;window_start&e.code; and &s.code;window_end&e.code;
+ with the alignment specified in &s.code;align_mask&e.code;.
+ Optionally a list of resource ranges which should be avoided within
+ the window can be supplied. On failure a zero-length range of
+ type &s.code;ResEnd&e.code; will be returned.
+
+ </quote>
+ &s.code;resRange xf86GetSparse(long type, memType fixed_bits,
+ &f.indent;memType decode_mask, memType address_mask,
+ &f.indent;resPtr avoid)&e.code;
+ <quote><p>
+ This function is like the previous one, but attempts to find a
+ sparse range instead of a block range. Here three values have to
+ be specified: the &s.code;address_mask&e.code; which marks all
+ bits of the mask part of the address, the &s.code;decode_mask&e.code;
+ which masks out the bits which are hardcoded and are therefore
+ not available for relocation and the values of the fixed bits.
+ The function tries to find a base that satisfies the given condition.
+ If the function fails it will return a zero range of type
+ &s.code;ResEnd&e.code;. Optionally it might be passed a list of
+ resource ranges to avoid.
+
+ </quote>
+ </quote>
+
+Some PCI devices are broken in the sense that they return invalid size
+information for a certain resource. In this case the driver can supply
+the correct size and make sure that the resource range allocated for
+the card is large enough to hold the address range decoded by the card.
+The function &s.code;xf86FixPciResource()&e.code; can be used to do this:
+ <quote><p>
+ &s.code;Bool xf86FixPciResource(int entityIndex, unsigned int prt,
+ &f.indent;CARD32 alignment, long type)&e.code;
+ <quote><p>
+ This function fixes a PCI resource allocation. The
+ &s.code;prt&e.code; parameter contains the number of the PCI base
+ register that needs to be fixed (&s.code;0-5&e.code;, and
+ &s.code;6&e.code; for the BIOS base register). The size is
+ specified by the alignment. Since PCI resources need to span an
+ integral range of the size &s.code;2^n&e.code; the alignment also
+ specifies the number of addresses that will be decoded. If the
+ driver specifies a type mask it can override the default type for
+ PCI resources which is &s.code;ResShared&e.code;. The resource
+ broker needs to know that to find a matching resource range. This
+ function should be called before calling
+ &s.code;xf86RegisterResources()&e.code;. The return value is
+ &s.code;TRUE&e.code; when the function succeeds.
+
+ </quote>
+
+ &s.code;Bool xf86CheckPciMemBase(pciVideoPtr pPci, memType base)&e.code;
+ <quote><p>
+ This function checks that the memory base address specified matches
+ one of the PCI base address register values for the given PCI
+ device. This is mostly used to check that an externally provided
+ base address (e.g., from a config file) matches an actual value
+ allocated to a device.
+
+ </quote>
+ </quote>
+
+The driver may replace the generic access control functions for an entity
+by it's own ones. This is done with the &s.code;xf86SetAccessFuncs()&e.code;:
+ <quote><p>
+ &s.code;void xf86SetAccessFuncs(EntityInfoPtr pEnt, xf86AccessPtr p_io,
+ &f.indent;xf86AccessPtr p_mem, xf86AccessPtr p_io_mem,
+ &f.indent;xf86AccessPtr *ppAccessOld)&e.code;
+ <quote><p>
+ The driver can pass three functions: one for I/O access, one for
+ memory access and one for combined memory and I/O access. If the
+ memory access and combined access functions are identical the
+ common level assumes that the memory access cannot be controlled
+ independently of I/O access, if the I/O access function and the
+ combined access functions are the same it is assumed that I/O can
+ not be controlled independently. If memory and I/O have to be
+ controlled together all three values should be the same. If a
+ non &s.code;NULL&e.code; value is passed as fifth argument it is
+ interpreted as an address where to store the old access record.
+ If the fifth argument is &s.code;NULL&e.code; it will be assumed
+ that the generic access should be enabled before replacing the
+ access functions. Otherwise it will be disabled. The driver may
+ enable them itself using the returned values. It should do this
+ from his replacement access functions as the generic access may
+ be disabled by the common level on certain occasions. If replacement
+ functions are specified they must control all resources of the
+ specific type registered for the entity.
+
+ </quote>
+ </quote>
+
+To find out if specific resource range is conflicting with another
+resource the &s.code;xf86ChkConflict()&e.code; function may be used:
+ <quote><p>
+ &s.code;memType xf86ChkConflict(resRange *rgp, int entityIndex)&e.code;
+ <quote><p>
+ This function checks if the resource range &s.code;rgp&e.code; of
+ for the specified entity conflicts with with another resource.
+ If it a conflict is found, the address of the start of the conflict
+ is returned. The return value is zero when there is no conflict.
+
+ </quote>
+ </quote>
+
+The OPERATING state properties of previously registered fixed resources
+can be set with the &s.code;xf86SetOperatingState()&e.code; function:
+ <quote><p>
+ &s.code;resPtr xf86SetOperatingState(resList list, int entityIndex,
+ &f.indent;int mask)&e.code;
+ <quote><p>
+ This function is used to set the status of a resource during
+ OPERATING state. &s.code;list&e.code; holds a list to which
+ &s.code;mask&e.code; is to be applied. The parameter
+ &s.code;mask&e.code; may have the value &s.code;ResUnusedOpr&e.code;
+ and &s.code;ResDisableOpr&e.code;. The first one should be used
+ if a resource isn't used by the driver during OPERATING state
+ although it is decoded by the device, while the latter one indicates
+ that the resource is not decoded during OPERATING state. Note
+ that the resource ranges have to match those specified during
+ registration. If a range has been specified starting at
+ &s.code;A&e.code; and ending at &s.code;B&e.code; and suppose
+ &s.code;C&e.code; us a value satisfying
+ &s.code;A&nbsp;&lt;&nbsp;C&nbsp;&lt;&nbsp;B&e.code; one may not
+ specify the resource range &s.code;(A,B)&e.code; by splitting it
+ into two ranges &s.code;(A,C)&e.code; and &s.code;(C,B)&e.code;.
+
+ </quote>
+ </quote>
+
+The following two functions are provided for special cases:
+ <quote><p>
+ &s.code;void xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex)&e.code;
+ <quote><p>
+ This function may be used to remove an entity from a screen. This
+ only makes sense if a screen has more than one entity assigned or
+ the screen is to be deleted. No test is made if the screen has
+ any entities left.
+
+ </quote>
+
+ &s.code;void xf86DeallocateResourcesForEntity(int entityIndex, long type)&e.code;
+ <quote><p>
+ This function deallocates all resources of a given type registered
+ for a certain entity from the resource broker list.
+
+ </quote>
+ </quote>
+
+<sect2>ScreenInit Phase
+<p>
+
+All that is required in this phase is to setup the RAC flags. Note that
+it is also permissible to set these flags up in the PreInit phase. The
+RAC flags are held in the &s.code;racIoFlags&e.code; and &s.code;racMemFlags&e.code; fields of the
+&s.code;ScrnInfoRec&e.code; for each screen. They specify which graphics operations
+might require the use of shared resources. This can be specified
+separately for memory and I/O resources. The available flags are defined
+in &s.code;rac/xf86RAC.h&e.code;. They are:
+
+ &s.code;RAC_FB&e.code;
+ <quote>
+ for framebuffer operations (including hw acceleration)
+ </quote>
+ &s.code;RAC_CURSOR&e.code;
+ <quote>
+ for Cursor operations
+ (??? I'm not sure if we need this for SW cursor it depends
+ on which level the sw cursor is drawn)
+ </quote>
+ &s.code;RAC_COLORMAP&e.code;
+ <quote>
+ for colormap operations
+ </quote>
+ &s.code;RAC_VIEWPORT&e.code;
+ <quote>
+ for the call to &s.code;ChipAdjustFrame()&e.code; </quote>
+
+
+The flags are ORed together.
+
+<sect>Config file ``Option'' entries<label id="options">
+<p>
+
+Option entries are permitted in most sections and subsections of the
+config file. There are two forms of option entries:
+
+<descrip>
+<tag>Option "option-name"</tag>
+ A boolean option.
+<tag>Option "option-name" "option-value"</tag>
+ An option with an arbitrary value.
+</descrip>
+
+The option entries are handled by the parser, and a list of the parsed
+options is included with each of the appropriate data structures that
+the drivers have access to. The data structures used to hold the option
+information are opaque to the driver, and a driver must not access the
+option data directly. Instead, the common layer provides a set of
+functions that may be used to access, check and manipulate the option
+data.
+
+First, the low level option handling functions. In most cases drivers
+would not need to use these directly.
+
+ <quote><p>
+ &s.code;pointer xf86FindOption(pointer options, const char *name)&e.code;
+ <quote><p>
+ Takes a list of options and an option name, and returns a handle
+ for the first option entry in the list matching the name. Returns
+ &s.code;NULL&e.code; if no match is found.
+
+ </quote>
+
+ &s.code;char *xf86FindOptionValue(pointer options, const char *name)&e.code;
+ <quote><p>
+ Takes a list of options and an option name, and returns the value
+ associated with the first option entry in the list matching the
+ name. If the matching option has no value, an empty string
+ (&s.code;""&e.code;) is returned. Returns &s.code;NULL&e.code;
+ if no match is found.
+
+ </quote>
+
+ &s.code;void xf86MarkOptionUsed(pointer option)&e.code;
+ <quote><p>
+ Takes a handle for an option, and marks that option as used.
+
+ </quote>
+
+ &s.code;void xf86MarkOptionUsedByName(pointer options, const char *name)&e.code;
+ <quote><p>
+ Takes a list of options and an option name and marks the first
+ option entry in the list matching the name as used.
+
+ </quote>
+ </quote>
+
+
+Next, the higher level functions that most drivers would use.
+ <quote><p>
+ &s.code;void xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts)&e.code;
+ <quote><p>
+ Collect the options from each of the config file sections used by
+ the screen (&s.code;pScrn&e.code;) and return the merged list as
+ &s.code;pScrn-&gt;options&e.code;. This function requires that
+ &s.code;pScrn-&gt;confScreen&e.code;, &s.code;pScrn-&gt;display&e.code;,
+ &s.code;pScrn-&gt;monitor&e.code;,
+ &s.code;pScrn-&gt;numEntities&e.code;, and
+ &s.code;pScrn-&gt;entityList&e.code; are initialised.
+ &s.code;extraOpts&e.code; may optionally be set to an additional
+ list of options to be combined with the others. The order of
+ precedence for options is &s.code;extraOpts&e.code;, display,
+ confScreen, monitor, device.
+
+ </quote>
+
+ &s.code;void xf86ProcessOptions(int scrnIndex, pointer options,
+ &f.indent;OptionInfoPtr optinfo)&e.code;
+ <quote><p>
+ Processes a list of options according to the information in the
+ array of &s.code;OptionInfoRecs&e.code; (&s.code;optinfo&e.code;).
+ The resulting information is stored in the &s.code;value&e.code;
+ fields of the appropriate &s.code;optinfo&e.code; entries. The
+ &s.code;found&e.code; fields are set to &s.code;TRUE&e.code;
+ when an option with a value of the correct type if found, and
+ &s.code;FALSE&e.code; otherwise. The &s.code;type&e.code; field
+ is used to determine the expected value type for each option.
+ Each option in the list of options for which there is a name match
+ (but not necessarily a value type match) is marked as used.
+ Warning messages are printed when option values don't match the
+ types specified in the optinfo data.
+
+ NOTE: If this function is called before a driver's screen number
+ is known (e.g., from the &s.code;ChipProbe()&e.code; function) a
+ &s.code;scrnIndex&e.code; value of &s.code;-1&e.code; should be
+ used.
+
+ The &s.code;OptionInfoRec&e.code; is defined as follows:
+
+ <verb>
+ typedef struct {
+ double freq;
+ int units;
+ } OptFrequency;
+
+ typedef union {
+ unsigned long num;
+ char * str;
+ double realnum;
+ Bool bool;
+ OptFrequency freq;
+ } ValueUnion;
+
+ typedef enum {
+ OPTV_NONE = 0,
+ OPTV_INTEGER,
+ OPTV_STRING, /* a non-empty string */
+ OPTV_ANYSTR, /* Any string, including an empty one */
+ OPTV_REAL,
+ OPTV_BOOLEAN,
+ OPTV_FREQ
+ } OptionValueType;
+
+ typedef enum {
+ OPTUNITS_HZ = 1,
+ OPTUNITS_KHZ,
+ OPTUNITS_MHZ
+ } OptFreqUnits;
+
+ typedef struct {
+ int token;
+ const char* name;
+ OptionValueType type;
+ ValueUnion value;
+ Bool found;
+ } OptionInfoRec, *OptionInfoPtr;
+ </verb>
+
+ &s.code;OPTV_FREQ&e.code; can be used for options values that are
+ frequencies. These values are a floating point number with an
+ optional unit name appended. The unit name can be one of "Hz",
+ "kHz", "k", "MHz", "M". The multiplier associated with the unit
+ is stored in &s.code;freq.units&e.code;, and the scaled frequency
+ is stored in &s.code;freq.freq&e.code;. When no unit is specified,
+ &s.code;freq.units&e.code; is set to &s.code;0&e.code;, and
+ &s.code;freq.freq&e.code; is unscaled.
+
+ Typical usage is to setup a static array of
+ &s.code;OptionInfoRecs&e.code; with the &s.code;token&e.code;,
+ &s.code;name&e.code;, and &s.code;type&e.code; fields initialised.
+ The &s.code;value&e.code; and &s.code;found&e.code; fields get
+ set by &s.code;xf86ProcessOptions()&e.code;. For cases where the
+ value parsing is more complex, the driver should specify
+ &s.code;OPTV_STRING&e.code;, and parse the string itself. An
+ example of using this option handling is included in the
+ <ref id="sample" name="Sample Driver"> section.
+
+ </quote>
+
+ &s.code;void xf86ShowUnusedOptions(int scrnIndex, pointer options)&e.code;
+ <quote><p>
+ Prints out warning messages for each option in the list of options
+ that isn't marked as used. This is intended to show options that
+ the driver hasn't recognised. It would normally be called near
+ the end of the &s.code;ChipScreenInit()&e.code; function, but only
+ when &s.code;serverGeneration&nbsp;==&nbsp;1&e.code;.
+
+ </quote>
+
+ &s.code;OptionInfoPtr xf86TokenToOptinfo(OptionInfoPtr table, int token)&e.code;
+ <quote><p>
+ Returns a pointer to the &s.code;OptionInfoRec&e.code; in
+ &s.code;table&e.code; with a token field matching
+ &s.code;token&e.code;. Returns &s.code;NULL&e.code; if no match
+ is found.
+
+ </quote>
+
+ &s.code;Bool xf86IsOptionSet(OptionInfoPtr table, int token)&e.code;
+ <quote><p>
+ Returns the &s.code;found&e.code; field of the
+ &s.code;OptionInfoRec&e.code; in &s.code;table&e.code; with a
+ &s.code;token&e.code; field matching &s.code;token&e.code;. This
+ can be used for options of all types. Note that for options of
+ type &s.code;OPTV_BOOLEAN&e.code;, it isn't sufficient to check
+ this to determine the value of the option. Returns
+ &s.code;FALSE&e.code; if no match is found.
+
+ </quote>
+
+ &s.code;char *xf86GetOptValString(OptionInfoPtr table, int token)&e.code;
+ <quote><p>
+ Returns the &s.code;value.str&e.code; field of the
+ &s.code;OptionInfoRec&e.code; in &s.code;table&e.code; with a
+ token field matching &s.code;token&e.code;. Returns
+ &s.code;NULL&e.code; if no match is found.
+
+ </quote>
+
+ &s.code;Bool xf86GetOptValInteger(OptionInfoPtr table, int token,
+ &f.indent;int *value)&e.code;
+ <quote><p>
+ Returns via &s.code;*value&e.code; the &s.code;value.num&e.code;
+ field of the &s.code;OptionInfoRec&e.code; in &s.code;table&e.code;
+ with a &s.code;token&e.code; field matching &s.code;token&e.code;.
+ &s.code;*value&e.code; is only changed when a match is found so
+ it can be safely initialised with a default prior to calling this
+ function. The function return value is as for
+ &s.code;xf86IsOptionSet()&e.code;.
+
+ </quote>
+
+ &s.code;Bool xf86GetOptValULong(OptionInfoPtr table, int token,
+ &f.indent;unsigned long *value)&e.code;
+ <quote><p>
+ Like &s.code;xf86GetOptValInteger()&e.code;, except the value is
+ treated as an &s.code;unsigned long&e.code;.
+
+ </quote>
+
+ &s.code;Bool xf86GetOptValReal(OptionInfoPtr table, int token,
+ &f.indent;double *value)&e.code;
+ <quote><p>
+ Like &s.code;xf86GetOptValInteger()&e.code;, except that
+ &s.code;value.realnum&e.code; is used.
+
+ </quote>
+
+ &s.code;Bool xf86GetOptValFreq(OptionInfoPtr table, int token,
+ &f.indent;OptFreqUnits expectedUnits, double *value)&e.code;
+ <quote><p>
+ Like &s.code;xf86GetOptValInteger()&e.code;, except that the
+ &s.code;value.freq&e.code; data is returned. The frequency value
+ is scaled to the units indicated by &s.code;expectedUnits&e.code;.
+ The scaling is exact when the units were specified explicitly in
+ the option's value. Otherwise, the &s.code;expectedUnits&e.code;
+ field is used as a hint when doing the scaling. In this case,
+ values larger than &s.code;1000&e.code; are assumed to have be
+ specified in the next smallest units. For example, if the Option
+ value is "10000" and expectedUnits is &s.code;OPTUNITS_MHZ&e.code;,
+ the value returned is &s.code;10&e.code;.
+
+ </quote>
+
+ &s.code;Bool xf86GetOptValBool(OptionInfoPtr table, int token, Bool *value)&e.code;
+ <quote><p>
+ This function is used to check boolean options
+ (&s.code;OPTV_BOOLEAN&e.code;). If the function return value is
+ &s.code;FALSE&e.code;, it means the option wasn't set. Otherwise
+ &s.code;*value&e.code; is set to the boolean value indicated by
+ the option's value. No option &s.code;value&e.code; is interpreted
+ as &s.code;TRUE&e.code;. Option values meaning &s.code;TRUE&e.code;
+ are "1", "yes", "on", "true", and option values meaning
+ &s.code;FALSE&e.code; are "0", "no", "off", "false". Option names
+ both with the "no" prefix in their names, and with that prefix
+ removed are also checked and handled in the obvious way.
+ &s.code;*value&e.code; is not changed when the option isn't present.
+ It should normally be set to a default value before calling this
+ function.
+
+ </quote>
+
+ &s.code;Bool xf86ReturnOptValBool(OptionInfoPtr table, int token, Bool def)&e.code;
+ <quote><p>
+ This function is used to check boolean options
+ (&s.code;OPTV_BOOLEAN&e.code;). If the option is set, its value
+ is returned. If the options is not set, the default value specified
+ by &s.code;def&e.code; is returned. The option interpretation is
+ the same as for &s.code;xf86GetOptValBool()&e.code;.
+
+ </quote>
+
+ &s.code;int xf86NameCmp(const char *s1, const char *s2)&e.code;
+ <quote><p>
+ This function should be used when comparing strings from the config
+ file with expected values. It works like &s.code;strcmp()&e.code;,
+ but is not case sensitive and space, tab, and `<tt>_</tt>' characters
+ are ignored in the comparison. The use of this function isn't
+ restricted to parsing option values. It may be used anywhere
+ where this functionality required.
+
+ </quote>
+ </quote>
+
+<sect>Modules, Drivers, Include Files and Interface Issues
+<p>
+
+NOTE: this section is incomplete.
+
+
+<sect1>Include files
+<p>
+
+The following include files are typically required by video drivers:
+
+ <quote><p>
+ All drivers should include these:
+ <quote>
+ &s.code;"xf86.h"&nl;
+ "xf86_OSproc.h"&nl;
+ "xf86_ansic.h"&nl;
+ "xf86Resources.h"&e.code;
+ </quote>
+ Wherever inb/outb (and related things) are used the following should be
+ included:
+ <quote>
+ &s.code;"compiler.h"&e.code;
+ </quote>
+
+ Drivers that need to access PCI vendor/device definitions need this:
+ <quote>
+ &s.code;"xf86PciInfo.h"&e.code;
+ </quote>
+
+ Drivers that need to access the PCI config space need this:
+ <quote>
+ &s.code;"xf86Pci.h"&e.code;
+ </quote>
+
+ Drivers that initialise a SW cursor need this:
+ <quote>
+ &s.code;"mipointer.h"&e.code;
+ </quote>
+
+ All drivers implementing backing store need this:
+ <quote>
+ &s.code;"mibstore.h"&e.code;
+ </quote>
+
+ All drivers using the mi colourmap code need this:
+ <quote>
+ &s.code;"micmap.h"&e.code;
+ </quote>
+
+ If a driver uses the vgahw module, it needs this:
+ <quote>
+ &s.code;"vgaHW.h"&e.code;
+ </quote>
+
+ Drivers supporting VGA or Hercules monochrome screens need:
+ <quote>
+ &s.code;"xf1bpp.h"&e.code;
+ </quote>
+
+ Drivers supporting VGA or EGC 16-colour screens need:
+ <quote>
+ &s.code;"xf4bpp.h"&e.code;
+ </quote>
+
+ Drivers using cfb need:
+ <quote>
+ &s.code;#define PSZ 8&nl;
+ #include "cfb.h"&nl;
+ #undef PSZ&e.code;
+ </quote>
+
+ Drivers supporting bpp 16, 24 or 32 with cfb need one or more of:
+ <quote>
+ &s.code;"cfb16.h"&nl;
+ "cfb24.h"&nl;
+ "cfb32.h"&e.code;
+ </quote>
+
+ If a driver uses XAA, it needs these:
+ <quote>
+ &s.code;"xaa.h"&nl;
+ "xaalocal.h"&e.code;
+ </quote>
+
+ If a driver uses the fb manager, it needs this:
+ <quote>
+ &s.code;"xf86fbman.h"&e.code;
+ </quote>
+ </quote>
+
+Non-driver modules should include &s.code;"xf86_ansic.h"&e.code; to get the correct
+wrapping of ANSI C/libc functions.
+
+All modules must NOT include any system include files, or the following:
+
+ <quote>
+ &s.code;"xf86Priv.h"&nl;
+ "xf86Privstr.h"&nl;
+ "xf86_libc.h"&nl;
+ "xf86_OSlib.h"&nl;
+ "Xos.h"&e.code;
+ </quote>
+
+or any other include files with ``priv'' in their name.
+
+<sect>Offscreen Memory Manager
+<p>
+
+Management of offscreen video memory may be handled by the XFree86
+framebuffer manager. Once the offscreen memory manager is running,
+drivers or extensions may allocate, free or resize areas of offscreen
+video memory using the following functions (definitions taken from
+&s.code;xf86fbman.h&e.code;):
+
+<code>
+ typedef struct _FBArea {
+ ScreenPtr pScreen;
+ BoxRec box;
+ int granularity;
+ void (*MoveAreaCallback)(struct _FBArea*, struct _FBArea*)
+ void (*RemoveAreaCallback)(struct _FBArea*)
+ DevUnion devPrivate;
+ } FBArea, *FBAreaPtr;
+
+ typedef void (*MoveAreaCallbackProcPtr)(FBAreaPtr from, FBAreaPtr to)
+ typedef void (*RemoveAreaCallbackProcPtr)(FBAreaPtr)
+
+ FBAreaPtr xf86AllocateOffscreenArea (
+ ScreenPtr pScreen,
+ int width, int height,
+ int granularity,
+ MoveAreaCallbackProcPtr MoveAreaCallback,
+ RemoveAreaCallbackProcPtr RemoveAreaCallback,
+ pointer privData
+ )
+
+ void xf86FreeOffscreenArea (FBAreaPtr area)
+
+ Bool xf86ResizeOffscreenArea (
+ FBAreaPtr area
+ int w, int h
+ )
+</code>
+
+The function:
+<quote>
+ &s.code;Bool xf86FBManagerRunning(ScreenPtr pScreen)&e.code;
+</quote>
+
+can be used by an extension to check if the driver has initialized
+the memory manager. The manager is not available if this returns
+&s.code;FALSE&e.code; and the functions above will all fail.
+
+
+&s.code;xf86AllocateOffscreenArea()&e.code; can be used to request a
+rectangle of dimensions &s.code;width&e.code; x &s.code;height&e.code;
+(in pixels) from unused offscreen memory. &s.code;granularity&e.code;
+specifies that the leftmost edge of the rectangle must lie on some
+multiple of &s.code;granularity&e.code; pixels. A granularity of zero
+means the same thing as a granularity of one - no alignment preference.
+A &s.code;MoveAreaCallback&e.code; can be provided to notify the requester
+when the offscreen area is moved. If no &s.code;MoveAreaCallback&e.code;
+is supplied then the area is considered to be immovable. The
+&s.code;privData&e.code; field will be stored in the manager's internal
+structure for that allocated area and will be returned to the requester
+in the &s.code;FBArea&e.code; passed via the
+&s.code;MoveAreaCallback&e.code;. An optional
+&s.code;RemoveAreaCallback&e.code; is provided. If the driver provides
+this it indicates that the area should be allocated with a lower priority.
+Such an area may be removed when a higher priority request (one that
+doesn't have a &s.code;RemoveAreaCallback&e.code;) is made. When this
+function is called, the driver will have an opportunity to do whatever
+cleanup it needs to do to deal with the loss of the area, but it must
+finish its cleanup before the function exits since the offscreen memory
+manager will free the area immediately after.
+
+&s.code;xf86AllocateOffscreenArea()&e.code; returns &s.code;NULL&e.code;
+if it was unable to allocate the requested area. When no longer needed,
+areas should be freed with &s.code;xf86FreeOffscreenArea()&e.code;.
+
+&s.code;xf86ResizeOffscreenArea()&e.code; resizes an existing
+&s.code;FBArea&e.code;. &s.code;xf86ResizeOffscreenArea()&e.code;
+returns &s.code;TRUE&e.code; if the resize was successful. If
+&s.code;xf86ResizeOffscreenArea()&e.code; returns &s.code;FALSE&e.code;,
+the original &s.code;FBArea&e.code; is left unmodified. Resizing an
+area maintains the area's original &s.code;granularity&e.code;,
+&s.code;devPrivate&e.code;, and &s.code;MoveAreaCallback&e.code;.
+&s.code;xf86ResizeOffscreenArea()&e.code; has considerably less overhead
+than freeing the old area then reallocating the new size, so it should
+be used whenever possible.
+
+The function:
+ <quote>
+ &s.code;Bool xf86QueryLargestOffscreenArea(
+ &f.indent;ScreenPtr pScreen,
+ &f.indent;int *width, int *height,
+ &f.indent;int granularity,
+ &f.indent;int preferences,
+ &f.indent;int priority
+ &nl)&e.code;
+ </quote>
+
+is provided to query the width and height of the largest single
+&s.code;FBArea&e.code; allocatable given a particular priority.
+&s.code;preferences&e.code; can be one of the following to indicate
+whether width, height or area should be considered when determining
+which is the largest single &s.code;FBArea&e.code; available.
+
+ <quote>
+ &s.code;FAVOR_AREA_THEN_WIDTH&nl;
+ FAVOR_AREA_THEN_HEIGHT&nl;
+ FAVOR_WIDTH_THEN_AREA&nl;
+ FAVOR_HEIGHT_THEN_AREA&e.code;
+ </quote>
+
+&s.code;priority&e.code; is one of the following:
+
+ <quote><p>
+ &s.code;PRIORITY_LOW&e.code;
+ <quote><p>
+ Return the largest block available without stealing anyone else's
+ space. This corresponds to the priority of allocating a
+ &s.code;FBArea&e.code; when a &s.code;RemoveAreaCallback&e.code;
+ is provided.
+
+ </quote>
+ &s.code;PRIORITY_NORMAL&e.code;
+ <quote><p>
+ Return the largest block available if it is acceptable to steal a
+ lower priority area from someone. This corresponds to the priority
+ of allocating a &s.code;FBArea&e.code; without providing a
+ &s.code;RemoveAreaCallback&e.code;.
+
+ </quote>
+ &s.code;PRIORITY_EXTREME&e.code;
+ <quote><p>
+ Return the largest block available if all &s.code;FBAreas&e.code;
+ that aren't locked down were expunged from memory first. This
+ corresponds to any allocation made directly after a call to
+ &s.code;xf86PurgeUnlockedOffscreenAreas()&e.code;.
+
+ </quote>
+ </quote>
+
+
+The function:
+
+ <quote>
+ &s.code;Bool xf86PurgeUnlockedOffscreenAreas(ScreenPtr pScreen)&e.code;
+ </quote>
+
+is provided as an extreme method to free up offscreen memory. This
+will remove all removable &s.code;FBArea&e.code; allocations.
+
+
+Initialization of the XFree86 framebuffer manager is done via
+
+ <quote>
+ &s.code;Bool xf86InitFBManager(ScreenPtr pScreen, BoxPtr FullBox)&e.code;
+ </quote>
+
+&s.code;FullBox&e.code; represents the area of the framebuffer that the
+manager is allowed to manage. This is typically a box with a width of
+&s.code;pScrn-&gt;displayWidth&e.code; and a height of as many lines as
+can be fit within the total video memory, however, the driver can reserve
+areas at the extremities by passing a smaller area to the manager.
+
+&s.code;xf86InitFBManager()&e.code; must be called before XAA is
+initialized since XAA uses the manager for it's pixmap cache.
+
+An alternative function is provided to allow the driver to initialize
+the framebuffer manager with a Region rather than a box.
+
+ <quote>
+ &s.code;Bool xf86InitFBManagerRegion(ScreenPtr pScreen,
+ &f.indent;RegionPtr FullRegion)&e.code;
+ </quote>
+
+&s.code;xf86InitFBManagerRegion()&e.code;, unlike
+&s.code;xf86InitFBManager()&e.code;, does not remove the area used for
+the visible screen so that area should not be included in the region
+passed to the function. &s.code;xf86InitFBManagerRegion()&e.code; is
+useful when non-contiguous areas are available to be managed, and is
+required when multiple framebuffers are stored in video memory (as in
+the case where an overlay of a different depth is stored as a second
+framebuffer in offscreen memory).
+
+
+<sect>Colormap Handling<label id="cmap">
+<p>
+
+A generic colormap handling layer is provided within the XFree86 common
+layer. This layer takes care of most of the details, and only requires
+a function from the driver that loads the hardware palette when required.
+To use the colormap layer, a driver calls the
+&s.code;xf86HandleColormaps()&e.code; function.
+
+ <quote><p>
+ &s.code;Bool xf86HandleColormaps(ScreenPtr pScreen, int maxColors,
+ &f.indent;int sigRGBbits, LoadPaletteFuncPtr loadPalette,
+ &f.indent;SetOverscanFuncPtr setOverscan,
+ unsigned int flags)&e.code;
+ <quote><p>
+ This function must be called after the default colormap has been
+ initialised. The &s.code;pScrn-&gt;gamma&e.code; field must also
+ be initialised, preferably by calling &s.code;xf86SetGamma()&e.code;.
+ &s.code;maxColors&e.code; is the number of entries in the palette.
+ &s.code;sigRGBbits&e.code; is the number of significant bits in
+ each colour component. This would normally be the same as
+ &s.code;pScrn-&gt;rgbBits&e.code;. &s.code;loadPalette&e.code;
+ is a driver-provided function for loading a colormap into the
+ hardware, and is described below. &s.code;setOverscan&e.code; is
+ an optional function that may be provided when the overscan color
+ is an index from the standard LUT and when it needs to be adjusted
+ to keep it as close to black as possible. The
+ &s.code;setOverscan&e.code; function programs the overscan index.
+ It shouldn't normally be used for depths other than 8.
+ &s.code;setOverscan&e.code; should be set to &s.code;NULL&e.code;
+ when it isn't needed. &s.code;flags&e.code; may be set to the
+ following (which may be ORed together):
+
+ &s.code;CMAP_PALETTED_TRUECOLOR&e.code;
+ <quote><p>
+ the TrueColor visual is paletted and is
+ just a special case of DirectColor.
+ This flag is only valid for
+ &s.code;bpp&nbsp;&gt;&nbsp;8&e.code;.
+
+ </quote>
+
+ &s.code;CMAP_RELOAD_ON_MODE_SWITCH&e.code;
+ <quote><p>
+ reload the colormap automatically
+ after mode switches. This is useful
+ for when the driver is resetting the
+ hardware during mode switches and
+ corrupting or erasing the hardware
+ palette.
+
+ </quote>
+
+ The colormap layer always reloads the palette after VT enters so it
+ is not necessary for the driver to save and restore the palette
+ when switching VTs. The driver must, however, still save the
+ initial palette during server start up and restore it during
+ server exit.
+
+ </quote>
+
+ &s.code;void LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ &f.indent;LOCO *colors, VisualPtr pVisual)&e.code;
+ <quote><p>
+ &s.code;LoadPalette()&e.code; is a driver-provide function for
+ loading a colormap into hardware. &s.code;colors&e.code; is the
+ array of RGB values that represent the full colormap.
+ &s.code;indices&e.code; is a list of index values into the colors
+ array. These indices indicate the entries that need to be updated.
+ &s.code;numColors&e.code; is the number of the indices to be
+ updated.
+
+ </quote>
+
+ &s.code;void SetOverscan(ScrnInfoPtr pScrn, int overscan)&e.code;
+ <quote><p>
+ &s.code;SetOverscan()&e.code; is a driver-provided function for
+ programming the &s.code;overscan&e.code; index. As described
+ above, it is normally only appropriate for LUT modes where all
+ colormap entries are available for the display, but where one of
+ them is also used for the overscan (typically 8bpp for VGA compatible
+ LUTs). It isn't required in cases where the overscan area is
+ never visible.
+
+ </quote>
+ </quote>
+
+
+<sect>DPMS Extension
+<p>
+
+Support code for the DPMS extension is included in the XFree86 common layer.
+This code provides an interface between the main extension code, and a means
+for drivers to initialise DPMS when they support it. One function is
+available to drivers to do this initialisation, and it is always available,
+even when the DPMS extension is not supported by the core server (in
+which case it returns a failure result).
+
+
+ <quote><p>
+ &s.code;Bool xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set, int flags)&e.code;
+ <quote><p>
+ This function registers a driver's DPMS level programming function
+ &s.code;set&e.code;. It also checks
+ &s.code;pScrn-&gt;options&e.code; for the "dpms" option, and when
+ present marks DPMS as being enabled for that screen. The
+ &s.code;set&e.code; function is called whenever the DPMS level
+ changes, and is used to program the requested level.
+ &s.code;flags&e.code; is currently not used, and should be
+ &s.code;0&e.code;. If the initialisation fails for any reason,
+ including when there is no DPMS support in the core server, the
+ function returns &s.code;FALSE&e.code;.
+
+ </quote>
+ </quote>
+
+
+Drivers that implement DPMS support must provide the following function,
+that gets called when the DPMS level is changed:
+
+
+ <quote><p>
+ &s.code;void ChipDPMSSet(ScrnInfoPtr pScrn, int level, int flags)&e.code;
+ <quote><p>
+ Program the DPMS level specified by &s.code;level&e.code;. Valid
+ values of &s.code;level&e.code; are &s.code;DPMSModeOn&e.code;,
+ &s.code;DPMSModeStandby&e.code;, &s.code;DPMSModeSuspend&e.code;,
+ &s.code;DPMSModeOff&e.code;. These values are defined in
+ &s.code;"extensions/dpms.h"&e.code;.
+
+ </quote>
+ </quote>
+
+
+<sect>DGA Extension
+<p>
+
+Drivers can support the XFree86 Direct Graphics Architecture (DGA) by
+filling out a structure of function pointers and a list of modes and
+passing them to DGAInit.
+
+ <quote><p>
+ &s.code;Bool DGAInit(ScreenPtr pScreen, DGAFunctionPtr funcs,
+ &f.indent;DGAModePtr modes, int num)&e.code;
+ <quote><p>
+ <verb>
+/** The DGAModeRec **/
+
+typedef struct {
+ int num;
+ DisplayModePtr mode;
+ int flags;
+ int imageWidth;
+ int imageHeight;
+ int pixmapWidth;
+ int pixmapHeight;
+ int bytesPerScanline;
+ int byteOrder;
+ int depth;
+ int bitsPerPixel;
+ unsigned long red_mask;
+ unsigned long green_mask;
+ unsigned long blue_mask;
+ int viewportWidth;
+ int viewportHeight;
+ int xViewportStep;
+ int yViewportStep;
+ int maxViewportX;
+ int maxViewportY;
+ int viewportFlags;
+ int offset;
+ unsigned char *address;
+ int reserved1;
+ int reserved2;
+} DGAModeRec, *DGAModePtr;
+</verb>
+
+ &s.code;num&e.code;
+ <quote>
+ Can be ignored. The DGA DDX will assign these numbers.
+ </quote>
+
+ &s.code;mode&e.code;
+ <quote>
+ A pointer to the &s.code;DisplayModeRec&e.code; for this mode.
+ </quote>
+
+ &s.code;flags&e.code;
+ <quote><p>
+ The following flags are defined and may be OR'd together:
+
+ &s.code;DGA_CONCURRENT_ACCESS&e.code;
+ <quote><p>
+ Indicates that the driver supports concurrent graphics
+ accelerator and linear framebuffer access.
+
+ </quote>
+
+ &s.code;DGA_FILL_RECT&nl;
+ DGA_BLIT_RECT&nl;
+ DGA_BLIT_RECT_TRANS&e.code;
+ <quote><p>
+ Indicates that the driver supports the FillRect, BlitRect
+ or BlitTransRect functions in this mode.
+
+ </quote>
+
+ &s.code;DGA_PIXMAP_AVAILABLE&e.code;
+ <quote><p>
+ Indicates that Xlib may be used on the framebuffer.
+ This flag will usually be set unless the driver wishes
+ to prohibit this for some reason.
+
+ </quote>
+
+ &s.code;DGA_INTERLACED&nl;
+ DGA_DOUBLESCAN&e.code;
+ <quote><p>
+ Indicates that these are interlaced or double scan modes.
+
+ </quote>
+ </quote>
+
+
+ &s.code;imageWidth&nl;
+ imageHeight&e.code;
+ <quote><p>
+ These are the dimensions of the linear framebuffer
+ accessible by the client.
+
+ </quote>
+
+ &s.code;pixmapWidth&nl;
+ pixmapHeight&e.code;
+ <quote><p>
+ These are the dimensions of the area of the
+ framebuffer accessible by the graphics accelerator.
+
+ </quote>
+
+ &s.code;bytesPerScanline&e.code;
+ <quote><p>
+ Pitch of the framebuffer in bytes.
+
+ </quote>
+
+ &s.code;byteOrder&e.code;
+ <quote><p>
+ Usually the same as
+ &s.code;pScrn-&gt;imageByteOrder&e.code;.
+
+ </quote>
+
+ &s.code;depth&e.code;
+ <quote><p>
+ The depth of the framebuffer in this mode.
+
+ </quote>
+
+ &s.code;bitsPerPixel&e.code;
+ <quote><p>
+ The number of bits per pixel in this mode.
+
+ </quote>
+
+ &s.code;red_mask&nl;
+ green_mask&nl;
+ blue_mask&e.code;
+ <quote><p>
+ The RGB masks for this mode, if applicable.
+
+ </quote>
+
+ &s.code;viewportWidth&nl;
+ viewportHeight&e.code;
+ <quote><p>
+ Dimensions of the visible part of the framebuffer.
+ Usually &s.code;mode-&gt;HDisplay&e.code; and
+ &s.code;mode-&gt;VDisplay&e.code;.
+
+ </quote>
+
+ &s.code;xViewportStep&nl;
+ yViewportStep&e.code;
+ <quote><p>
+ The granularity of x and y viewport positions that
+ the driver supports in this mode.
+
+ </quote>
+
+ &s.code;maxViewportX&nl;
+ maxViewportY&e.code;
+ <quote><p>
+ The maximum viewport position supported by the
+ driver in this mode.
+
+ </quote>
+
+ &s.code;viewportFlags&e.code;
+ <quote><p>
+ The following may be OR'd together:
+
+ &s.code;DGA_FLIP_IMMEDIATE&e.code;
+ <quote><p>
+ The driver supports immediate viewport changes.
+
+ </quote>
+ &s.code;DGA_FLIP_RETRACE&e.code;
+ <quote<p>
+ The driver supports viewport changes at retrace.
+
+ </quote>
+ </quote>
+
+ &s.code;offset&e.code;
+ <quote><p>
+ The offset into the linear framebuffer that corresponds to
+ pixel (0,0) for this mode.
+
+ </quote>
+
+ <verb>
+/** The DGAFunctionRec **/
+
+typedef struct {
+ Bool (*OpenFramebuffer)(
+ ScrnInfoPtr pScrn,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *extra
+ );
+ void (*CloseFramebuffer)(ScrnInfoPtr pScrn);
+ Bool (*SetMode)(ScrnInfoPtr pScrn, DGAModePtr pMode);
+ void (*SetViewport)(ScrnInfoPtr pScrn, int x, int y, int flags);
+ int (*GetViewport)(ScrnInfoPtr pScrn);
+ void (*Flush)(ScrnInfoPtr);
+ void (*FillRect)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned long color
+ );
+ void (*BlitRect)(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty
+ );
+ void (*BlitTransRect)(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty,
+ unsigned long color
+ );
+} DGAFunctionRec, *DGAFunctionPtr;
+</verb>
+
+ </quote>
+
+ &s.code;Bool OpenFramebuffer (pScrn, name, mem, size, offset, extra)&e.code;
+ <quote><p>
+ &s.code;OpenFramebuffer()&e.code; should pass the client everything
+ it needs to know to be able to open the framebuffer. These
+ parameters are OS specific and their meanings are to be interpreted
+ by an OS specific client library.
+
+ &s.code;name&e.code;
+ <quote><p>
+ The name of the device to open or &s.code;NULL&e.code; if
+ there is no special device to open. A &s.code;NULL&e.code;
+ name tells the client that it should open whatever device
+ one would usually open to access physical memory.
+
+ </quote>
+ &s.code;mem&e.code;
+ <quote><p>
+ The physical address of the start of the framebuffer.
+
+ </quote>
+ &s.code;size&e.code;
+ <quote><p>
+ The size of the framebuffer in bytes.
+
+ </quote>
+ &s.code;offset&e.code;
+ <quote><p>
+ Any offset into the device, if applicable.
+
+ </quote>
+ &s.code;flags&e.code;
+ <quote><p>
+ Any additional information that the client may need.
+ Currently, only the &s.code;DGA_NEED_ROOT&e.code; flag is
+ defined.
+
+ </quote>
+ </quote>
+
+ &s.code;void CloseFramebuffer (pScrn)&e.code;
+ <quote><p>
+ &s.code;CloseFramebuffer()&e.code; merely informs the driver (if it
+ even cares) that client no longer needs to access the framebuffer
+ directly. This function is optional.
+
+ </quote>
+
+ &s.code;Bool SetMode (pScrn, pMode)&e.code;
+ <quote><p>
+ &s.code;SetMode()&e.code; tells the driver to initialize the mode
+ passed to it. If &s.code;pMode&e.code; is &s.code;NULL&e.code;,
+ then the driver should restore the original pre-DGA mode.
+
+ </quote>
+
+ &s.code;void SetViewport (pScrn, x, y, flags)&e.code;
+ <quote><p>
+ &s.code;SetViewport()&e.code; tells the driver to make the upper
+ left-hand corner of the visible screen correspond to coordinate
+ &s.code;(x,y)&e.code; on the framebuffer. &s.code;Flags&e.code;
+ currently defined are:
+
+ &s.code;DGA_FLIP_IMMEDIATE&e.code;
+ <quote><p>
+ The viewport change should occur immediately.
+
+ </quote>
+ &s.code;DGA_FLIP_RETRACE&e.code;
+ <quote><p>
+ The viewport change should occur at the
+ vertical retrace, but this function should
+ return sooner if possible.
+
+ </quote>
+ The &s.code;(x,y)&e.code; locations will be passed as the client
+ specified them, however, the driver is expected to round these
+ locations down to the next supported location as specified by the
+ &s.code;xViewportStep&e.code; and &s.code;yViewportStep&e.code;
+ for the current mode.
+
+ </quote>
+
+ &s.code;int GetViewport (pScrn)&e.code;
+ <quote><p>
+ &s.code;GetViewport()&e.code; gets the current page flip status.
+ Set bits in the returned int correspond to viewport change requests
+ still pending. For instance, set bit zero if the last SetViewport
+ request is still pending, bit one if the one before that is still
+ pending, etc.
+
+ </quote>
+
+ &s.code;void Flush (pScrn)&e.code;
+ <quote><p>
+ This function should ensure that any graphics accelerator operations
+ have finished. This function should not return until the graphics
+ accelerator is idle.
+
+ </quote>
+
+ &s.code;void FillRect (pScrn, x, y, w, h, color)&e.code;
+ <quote><p>
+ This optional function should fill a rectangle
+ &s.code;w&nbsp;&times;&nbsp;h&e.code; located at
+ &s.code;(x,y)&e.code; in the given color.
+
+ </quote>
+
+ &s.code;void BlitRect (pScrn, srcx, srcy, w, h, dstx, dsty)&e.code;
+ <quote><p>
+ This optional function should copy an area
+ &s.code;w&nbsp;&times;&nbsp;h&e.code; located at
+ &s.code;(srcx,srcy)&e.code; to location &s.code;(dstx,dsty)&e.code;.
+ This function will need to handle copy directions as appropriate.
+
+ </quote>
+
+ &s.code;void BlitTransRect (pScrn, srcx, srcy, w, h, dstx, dsty, color)&e.code;
+ <quote><p>
+ This optional function is the same as BlitRect except that pixels
+ in the source corresponding to the color key &s.code;color&e.code;
+ should be skipped.
+
+ </quote>
+ </quote>
+
+<sect>The XFree86 X Video Extension (Xv) Device Dependent Layer
+<p>
+
+XFree86 offers the X Video Extension which allows clients to treat video
+as any another primitive and ``Put'' video into drawables. By default,
+the extension reports no video adaptors as being available since the
+DDX layer has not been initialized. The driver can initialize the DDX
+layer by filling out one or more &s.code;XF86VideoAdaptorRecs&e.code;
+as described later in this document and passing a list of
+&s.code;XF86VideoAdaptorPtr&e.code; pointers to the following function:
+
+ <quote>
+ &s.code;Bool xf86XVScreenInit(
+ &f.indent;ScreenPtr pScreen,
+ &f.indent;XF86VideoAdaptorPtr *adaptPtrs,
+ &f.indent;int num)&e.code;
+ </quote>
+
+
+After doing this, the extension will report video adaptors as being
+available, providing the data in their respective
+&s.code;XF86VideoAdaptorRecs&e.code; was valid.
+&s.code;xf86XVScreenInit()&e.code; <em>copies</em> data from the structure
+passed to it so the driver may free it after the initialization. At
+the moment, the DDX only supports rendering into Window drawables.
+Pixmap rendering will be supported after a sufficient survey of suitable
+hardware is completed.
+
+The &s.code;XF86VideoAdaptorRec&e.code;:
+
+<quote><p>
+<verb>
+typedef struct {
+ unsigned char type;
+ int flags;
+ char *name;
+ int nEncodings;
+ XF86VideoEncodingPtr pEncodings;
+ int nFormats;
+ XF86VideoFormatPtr pFormats;
+ int nPorts;
+ XF86AttributeListPtr pAttributes;
+ DevUnion *pPortPrivates;
+ PutVideoFuncPtr PutVideo;
+ PutStillFuncPtr PutStill;
+ GetVideoFuncPtr GetVideo;
+ GetStillFuncPtr GetStill;
+ StopVideoFuncPtr StopVideo;
+ SetPortAttributeFuncPtr SetPortAttribute;
+ GetPortAttributeFuncPtr GetPortAttribute;
+ QueryBestSizeFuncPtr QueryBestSize;
+} XF86VideoAdaptorRec, *XF86VideoAdaptorPtr;
+</verb>
+
+ Each adaptor will have its own XF86VideoAdaptorRec. The fields are
+ as follows:
+
+ &s.code;type&e.code;
+ <quote><p>
+ This can be &s.code;XvInputMask&e.code;,
+ &s.code;XvOutputMask&e.code; or both OR'd together. This refers
+ to the target drawable and is similar to a Window's
+ &s.code;class&e.code;. &s.code;XvInputMask&e.code; indicates
+ that the adaptor can put video into a drawable.
+ &s.code;XvOutputMask&e.code; indicates that the adaptor can get
+ video from a drawable.
+
+ </quote>
+
+ &s.code;flags&e.code;
+ <quote><p>
+ Currently, the following flags are defined:
+
+ &s.code;VIDEO_NO_CLIPPING&e.code;
+ <quote><p>
+ This indicates that the video adaptor does not support
+ clipping. The driver will never receive Get/Put requests
+ where less than the entire area determined by
+ &s.code;drw_x&e.code;, &s.code;drw_y&e.code;,
+ &s.code;drw_w&e.code; and &s.code;drw_h&e.code; is visible.
+
+ </quote>
+
+ &s.code;VIDEO_INVERT_CLIPLIST&e.code;
+ <quote><p>
+ This indicates that the video driver requires the clip
+ list to contain the regions which are obscured rather
+ than the regions which are are visible.
+
+ </quote>
+
+ &s.code;VIDEO_EXPOSE&e.code;
+ <quote><p>
+ This flag applies to &s.code;GetStill&e.code; and
+ &s.code;GetVideo&e.code; only, it indicates the clip list
+ shall contain obscured regions. Note the source region will
+ still be clipped against the screen bounds. This flag is
+ meant for showing all the contents of the [root] window, if
+ the administrator has no hesitations regarding security.
+
+ </quote>
+
+ </quote>
+
+ &s.code;name&e.code;
+ <quote><p>
+ The name of the adaptor.
+
+ </quote>
+
+ &s.code;nEncodings&nl;
+ pEncodings&e.code;
+ <quote><p>
+ The number of encodings the adaptor is capable of and pointer
+ to the &s.code;XF86VideoEncodingRec&e.code; array. The
+ &s.code;XF86VideoEncodingRec&e.code; is described later on.
+
+ </quote>
+
+ &s.code;nFormats&nl;
+ pFormats&e.code;
+ <quote><p>
+ The number of formats the adaptor is capable of and pointer to
+ the &s.code;XF86VideoFormatRec&e.code; array. The
+ &s.code;XF86VideoFormatRec&e.code; is described later on.
+
+ </quote>
+
+ &s.code;nPorts&nl;
+ pPortPrivates&e.code;
+ <quote><p>
+ The number of ports is the number of separate data streams which
+ the adaptor can handle simultaneously. If you have more than
+ one port, the adaptor is expected to be able to render into more
+ than one window at a time. &s.code;pPortPrivates&e.code; is
+ an array of pointers or ints - one for each port. A port's
+ private data will be passed to the driver any time the port is
+ requested to do something like put the video or stop the video.
+ In the case where there may be many ports, this enables the
+ driver to know which port the request is intended for. Most
+ commonly, this will contain a pointer to the data structure
+ containing information about the port.
+
+ </quote>
+
+ &s.code;pAttributes&e.code;
+ <quote><p>
+ There is an array of &s.code;XF86AttributeListRecs&e.code; with
+ an entry for each port.
+
+ </quote>
+
+ &s.code;PutVideo PutStill GetVideo GetStill StopVideo
+ SetPortAttribute GetPortAttribute QueryBestSize&e.code;
+ <quote><p>
+ These functions define the DDX-&gt;driver interface. In each
+ case, the pointer &s.code;data&e.code; is passed to the driver.
+ This is the port private for that port as described above. All
+ fields are required except under the following conditions:
+
+ <enum>
+ <item>&s.code;PutVideo&e.code; and &s.code;PutStill&e.code;
+ are not required when the adaptor type does not contain
+ &s.code;XvInputMask&e.code;.
+
+ <item>&s.code;GetVideo&e.code; and &s.code;GetStill&e.code;
+ are not required when the adaptor type does not contain
+ &s.code;XvOutputMask&e.code;.
+
+ </enum>
+
+ These functions should return Success if the operation was
+ completed successfully. They can return &s.code;XvBadAlloc&e.code;
+ otherwise. Xv DDX will not call a Get/Put function while video
+ is active, rather issue a &s.code;StopVideo&e.code; call first.
+
+ Earlier versions of Xv DDX had a &s.code;ReclipVideo&e.code;
+ function, obsolete now. The clip region will be passed directly
+ by the functions below. If the &s.code;VIDEO_NO_CLIPPING&e.code;
+ flag is set, the &s.code;RegionPtr&e.code; should be ignored by
+ the driver. &s.code;ClipBoxes&e.code; is an &s.code;X-Y&e.code;
+ banded region identical to those used throughout the server.
+ The clipBoxes represent the visible portions of area determined
+ by &s.code;drw_x&e.code;, &s.code;drw_y&e.code;,
+ &s.code;drw_w&e.code; and &s.code;drw_h&e.code; in the Get/Put
+ function. The boxes are in screen coordinates, are guaranteed
+ not to overlap and an empty region will be passed only to
+ &s.code;GetVideo&e.code;, once. This to notify the driver the
+ primitive is totally obscured now. A &s.code;StopVideo&e.code;
+ call will immediately follow nevertheless. In the case where
+ the &s.code;VIDEO_INVERT_CLIPLIST&e.code; flag is set,
+ &s.code;clipBoxes&e.code; will indicate the areas of the primitive
+ which are obscured rather than the areas visible. The Region
+ must not be altered by the driver and will be deleted when the
+ function returns.
+
+ </quote>
+
+ &s.code;typedef int (* PutVideoFuncPtr)( ScrnInfoPtr pScrn,
+ &f.indent;short vid_x, short vid_y, short drw_x, short drw_y,
+ &f.indent;short vid_w, short vid_h, short drw_w, short drw_h,
+ &f.indent;RegionPtr clipBoxes, pointer data )&e.code;
+ <quote><p>
+ This indicates that the driver should take a subsection
+ &s.code;vid_w&nbsp;&times;&nbsp;vid_h&e.code; at location
+ &s.code;(vid_x,vid_y)&e.code; from the video stream and direct
+ it into the rectangle
+ &s.code;rw_w&nbsp;&times;&nbsp;drw_h&e.code; at location
+ &s.code;(drw_x,drw_y)&e.code; on the screen, scaling as
+ necessary. Due to the large variations in capabilities of
+ the various hardware expected to be used with this extension,
+ it is not expected that all hardware will be able to do this
+ exactly as described. In that case the driver should just do
+ ``the best it can,'' scaling as closely to the target rectangle
+ as it can without rendering outside of it. In the worst case,
+ the driver can opt to just not turn on the video.
+
+ </quote>
+
+ &s.code;typedef int (* PutStillFuncPtr)( ScrnInfoPtr pScrn,
+ &f.indent;short vid_x, short vid_y, short drw_x, short drw_y,
+ &f.indent;short vid_w, short vid_h, short drw_w, short drw_h,
+ &f.indent;RegionPtr clipBoxes, pointer data )&e.code;
+ <quote><p>
+ This is same as &s.code;PutVideo&e.code; except that the driver
+ should place only one frame from the stream on the screen.
+
+ </quote>
+
+ &s.code;typedef int (* GetVideoFuncPtr)( ScrnInfoPtr pScrn,
+ &f.indent;short vid_x, short vid_y, short drw_x, short drw_y,
+ &f.indent;short vid_w, short vid_h, short drw_w, short drw_h,
+ &f.indent;RegionPtr clipBoxes, pointer data )&e.code;
+ <quote><p>
+ This is same as &s.code;PutVideo&e.code; except that the driver
+ gets video from the screen and outputs it. The driver should
+ do the best it can to get the requested dimensions correct
+ without reading from an area larger than requested.
+
+ </quote>
+
+ &s.code;typedef int (* GetStillFuncPtr)( ScrnInfoPtr pScrn,
+ &f.indent;short vid_x, short vid_y, short drw_x, short drw_y,
+ &f.indent;short vid_w, short vid_h, short drw_w, short drw_h,
+ &f.indent;RegionPtr clipBoxes, pointer data )&e.code;
+ <quote><p>
+ This is the same as &s.code;GetVideo&e.code; except that the
+ driver should place only one frame from the screen into the
+ output stream.
+
+ </quote>
+
+ &s.code;typedef void (* StopVideoFuncPtr)(ScrnInfoPtr pScrn,
+ &f.indent;pointer data, Bool cleanup)&e.code;
+ <quote><p>
+ This indicates the the driver should stop displaying the video.
+ This is used to stop both input and output video. The
+ &s.code;cleanup&e.code; field indicates that the video is
+ being stopped because the client requested it to stop or
+ because the server is exiting the current VT. In that case
+ the driver should deallocate any offscreen memory areas (if
+ there are any) being used to put the video to the screen. If
+ &s.code;cleanup&e.code; is not set, the video is being stopped
+ temporarily due to clipping or moving of the window, etc...
+ and video will likely be restarted soon so the driver should
+ not deallocate any offscreen areas associated with that port.
+
+ </quote>
+ &s.code;typedef int (* SetPortAttributeFuncPtr)(ScrnInfoPtr pScrn,
+ &f.indent;Atom attribute,INT32 value, pointer data)&e.code;
+
+ &s.code;typedef int (* GetPortAttributeFuncPtr)(ScrnInfoPtr pScrn,
+ &f.indent;Atom attribute,INT32 *value, pointer data)&e.code;
+
+ <quote><p>
+ A port may have particular attributes such as hue,
+ saturation, brightness or contrast. Xv clients set and
+ get these attribute values by sending attribute strings
+ (Atoms) to the server. Such requests end up at these
+ driver functions. It is recommended that the driver provide
+ at least the following attributes mentioned in the Xv client
+ library docs:
+ <quote>
+ &s.code;XV_ENCODING&nl;
+ XV_HUE&nl;
+ XV_SATURATION&nl;
+ XV_BRIGHTNESS&nl;
+ XV_CONTRAST&e.code;
+ </quote>
+ but the driver may recognize as many atoms as it wishes. If
+ a requested attribute is unknown by the driver it should return
+ &s.code;BadMatch&e.code;. &s.code;XV_ENCODING&e.code; is the
+ attribute intended to let the client specify which video
+ encoding the particular port should be using (see the description
+ of &s.code;XF86VideoEncodingRec&e.code; below). If the
+ requested encoding is unsupported, the driver should return
+ &s.code;XvBadEncoding&e.code;. &s.code;Success&e.code; should
+ be returned otherwise.
+
+ </quote>
+
+ &s.code;typedef void (* QueryBestSizeFuncPtr)(ScrnInfoPtr pScrn,
+ &f.indent;Bool motion, short vid_w, short vid_h,
+ &f.indent;short drw_w, short drw_h,
+ &f.indent;unsigned int *p_w, unsigned int *p_h, pointer data)&e.code;
+ <quote><p>
+ &s.code;QueryBestSize&e.code; provides the client with a way
+ to query what the destination dimensions would end up being
+ if they were to request that an area
+ &s.code;vid_w&nbsp;&times;&nbsp;vid_h&e.code; from the video
+ stream be scaled to rectangle of
+ &s.code;drw_w&nbsp;&times;&nbsp;drw_h&e.code; on the screen.
+ Since it is not expected that all hardware will be able to
+ get the target dimensions exactly, it is important that the
+ driver provide this function. The returned dimensions must
+ be less than or equal to the requested dimension.
+
+ </quote>
+ </quote>
+
+The XF86VideoEncodingRec:
+<quote><p>
+<verb>
+typedef struct {
+ int id;
+ char *name;
+ unsigned short width, height;
+ XvRationalRec rate;
+} XF86VideoEncodingRec, *XF86VideoEncodingPtr;
+</verb>
+
+ The &s.code;XF86VideoEncodingRec&e.code; specifies what encodings
+ the adaptor can support. Most of this data is just informational
+ and for the client's benefit, and is what will be reported by
+ &s.code;XvQueryEncodings&e.code;. The &s.code;id&e.code; field is
+ expected to be a unique identifier to allow the client to request a
+ certain encoding via the &s.code;XV_ENCODING&e.code; attribute string.
+
+</quote>
+
+The XF86VideoFormatRec:
+
+<quote><p>
+<verb>
+typedef struct {
+ char depth;
+ short class;
+} XF86VideoFormatRec, *XF86VideoFormatPtr;
+</verb>
+
+ This specifies what visuals the video is viewable in.
+ &s.code;depth&e.code; is the depth of the visual (not bpp).
+ &s.code;class&e.code; is the visual class such as
+ &s.code;TrueColor&e.code;, &s.code;DirectColor&e.code; or
+ &s.code;PseudoColor&e.code;. Initialization of an adaptor will fail
+ if none of the visuals on that screen are supported.
+
+</quote>
+
+The XF86AttributeListRec:
+
+<quote><p>
+<verb>
+typedef struct {
+ int number;
+ int *flags;
+ char **names;
+} XF86AttributeListRec, *XF86AttributeListPtr;
+</verb>
+
+ Each port will have one of these indicating the &s.code;number&e.code;
+ of attributes for that port, an array of names of the attributes and
+ an array of flags associated with each attribute. Both arrays are
+ &s.code;number&e.code; in size. Currently defined flags are
+ &s.code;XvGettable&e.code; and &s.code;XvSettable&e.code; which may
+ be OR'd together indicating that attribute is ``gettable'' or ``settable''
+ by the client. Both arrays can be nulled if number is zero. While
+ the Xv DDX copies most data from these structures and stores it
+ internally, including adaptor and encoding names, the attribute names
+ are not copied, but only their pointers. Because of this, the strings
+ pointed to by &s.code;names[]&e.code; must exist as long as Xv is
+ initialized.
+
+</quote>
+
+
+<sect>The Loader
+<p>
+
+This section describes the interfaces to the module loader. The loader
+interfaces can be divided into two groups: those that are only available to
+the XFree86 common layer, and those that are also available to modules.
+
+<sect1>Loader Overview
+<p>
+
+The loader is capable of loading modules in a range of object formats,
+and knowledge of these formats is built in to the loader. Knowledge of
+new object formats can be added to the loader in a straightforward
+manner. This makes it possible to provide OS-independent modules (for
+a given CPU architecture type). In addition to this, the loader can
+load modules via the OS-provided &s.code;dlopen(3)&e.code; service where
+available. Such modules are not platform independent, and the semantics
+of &s.code;dlopen()&e.code; on most systems results in significant
+limitations in the use of modules of this type. Support for
+&s.code;dlopen()&e.code; modules in the loader is primarily for
+experimental and development purposes.
+
+Symbols exported by the loader (on behalf of the core X server) to
+modules are determined at compile time. Only those symbols explicitly
+exported are available to modules. All external symbols of loaded
+modules are exported to other modules, and to the core X server. The
+loader can be requested to check for unresolved symbols at any time,
+and the action to be taken for unresolved symbols can be controlled by
+the caller of the loader. Typically the caller identifies which symbols
+can safely remain unresolved and which cannot.
+
+<sect1>Semi-private Loader Interface
+<p>
+
+The following is the semi-private loader interface that is available to the
+XFree86 common layer.
+
+ <quote><p>
+ &s.code;void LoaderInit(void)&e.code;
+ <quote><p>
+ The &s.code;LoaderInit()&e.code; function initialises the loader,
+ and it must be called once before calling any other loader functions.
+ This function initialises the tables of exported symbols, and anything
+ else that might need to be initialised.
+
+ </quote>
+
+ &s.code;void LoaderSetPath(const char *path)&e.code;
+ <quote><p>
+ The &s.code;LoaderSetPath()&e.code; function initialises a default
+ module search path. This must be called if calls to other functions
+ are to be made without explicitly specifying a module search path.
+ The search path &s.code;path&e.code; must be a string of one or more
+ comma separated absolute paths. Modules are expected to be located
+ below these paths, possibly in subdirectories of these paths.
+
+ </quote>
+
+ &s.code;pointer LoadModule(const char *module, const char *path,
+ &f.indent;const char **subdirlist, const char **patternlist,
+ &f.indent;pointer options, const XF86ModReqInfo * modreq,
+ &f.indent;int *errmaj, int *errmin)&e.code;
+ <quote><p>
+ The &s.code;LoadModule()&e.code; function loads the module called
+ &s.code;module&e.code;. The return value is a module handle, and
+ may be used in future calls to the loader that require a reference
+ to a loaded module. The module name &s.code;module&e.code; is
+ normally the module's canonical name, which doesn't contain any
+ directory path information, or any object/library file prefixes of
+ suffixes. Currently a full pathname and/or filename is also accepted.
+ This might change. The other parameters are:
+
+ &s.code;path&e.code;
+ <quote><p>
+ An optional comma-separated list of module search paths.
+ When &s.code;NULL&e.code;, the default search path is used.
+
+ </quote>
+
+ &s.code;subdirlist&e.code;
+ <quote><p>
+ An optional &s.code;NULL&e.code; terminated list of
+ subdirectories to search. When &s.code;NULL&e.code;,
+ the default built-in list is used (refer to
+ &s.code;stdSubdirs&e.code; in &s.code;loadmod.c&e.code;).
+ The default list is also substituted for entries in
+ &s.code;subdirlist&e.code; with the value
+ &s.code;DEFAULT_LIST&e.code;. This makes is possible
+ to augment the default list instead of replacing it.
+ Subdir elements must be relative, and must not contain
+ &s.code;".."&e.code;. If any violate this requirement,
+ the load fails.
+
+ </quote>
+
+ &s.code;patternlist&e.code;
+ <quote><p>
+ An optional &s.code;NULL&e.code; terminated list of
+ POSIX regular expressions used to connect module
+ filenames with canonical module names. Each regex
+ should contain exactly one subexpression that corresponds
+ to the canonical module name. When &s.code;NULL&e.code;,
+ the default built-in list is used (refer to
+ &s.code;stdPatterns&e.code; in
+ &s.code;loadmod.c&e.code;). The default list is also
+ substituted for entries in &s.code;patternlist&e.code;
+ with the value &s.code;DEFAULT_LIST&e.code;. This
+ makes it possible to augment the default list instead
+ of replacing it.
+
+ </quote>
+
+ &s.code;options&e.code;
+ <quote><p>
+ An optional parameter that is passed to the newly
+ loaded module's &s.code;SetupProc&e.code; function
+ (if it has one). This argument is normally a
+ &s.code;NULL&e.code; terminated list of
+ &s.code;Options&e.code;, and must be interpreted that
+ way by modules loaded directly by the XFree86 common
+ layer. However, it may be used for application-specific
+ parameter passing in other situations.
+
+ When loading ``external'' modules (modules that don't
+ have the the standard entry point, for example a
+ special shared library) the options parameter can be
+ set to &s.code;EXTERN_MODULE&e.code; to tell the
+ loader not to reject the module when it doesn't find
+ the standard entry point.
+
+ </quote>
+
+ &s.code;modreq&e.code;
+ <quote><p>
+ An optional &s.code;XF86ModReqInfo*&e.code; containing
+ version/ABI/vendor information to requirements to
+ check the newly loaded module against. The main
+ purpose of this is to allow the loader to verify that
+ a module of the correct type/version before running
+ its &s.code;SetupProc&e.code; function.
+
+ The &s.code;XF86ModReqInfo&e.code; struct is defined
+ as follows:
+<verb>
+typedef struct {
+ CARD8 majorversion; /* MAJOR_UNSPEC */
+ CARD8 minorversion; /* MINOR_UNSPEC */
+ CARD16 patchlevel; /* PATCH_UNSPEC */
+ const char * abiclass; /* ABI_CLASS_NONE */
+ CARD32 abiversion; /* ABI_VERS_UNSPEC */
+ const char * moduleclass; /* MOD_CLASS_NONE */
+} XF86ModReqInfo;
+</verb>
+
+ The information here is compared against the equivalent
+ information in the module's
+ &s.code;XF86ModuleVersionInfo&e.code; record (which
+ is described below). The values in comments above
+ indicate ``don't care'' settings for each of the fields.
+ The comparisons made are as follows:
+
+ &s.code;majorversion&e.code;
+ <quote><p>
+ Must match the module's majorversion
+ exactly.
+
+ </quote>
+ &s.code;minorversion&e.code;
+ <quote><p>
+ The module's minor version must be
+ no less than this value. This
+ comparison is only made if
+ &s.code;majorversion&e.code; is
+ specified and matches.
+
+ </quote>
+ &s.code;patchlevel&e.code;
+ <quote><p>
+ The module's patchlevel must be no
+ less than this value. This comparison
+ is only made if
+ &s.code;minorversion&e.code; is
+ specified and matches.
+
+ </quote>
+ &s.code;abiclass&e.code;
+ <quote><p>
+ String must match the module's abiclass
+ string.
+
+ </quote>
+ &s.code;abiversion&e.code;
+ <quote><p>
+ Must be consistent with the module's
+ abiversion (major equal, minor no
+ older).
+
+ </quote>
+ &s.code;moduleclass&e.code;
+ <quote><p>
+ String must match the module's
+ moduleclass string.
+
+ </quote>
+
+ </quote>
+
+ &s.code;errmaj&e.code;
+ <quote><p>
+ An optional pointer to a variable holding the major
+ part or the error code. When provided, it
+ &s.code;*errmaj&e.code; is filled in when
+ &s.code;LoadModule()&e.code; fails.
+
+ </quote>
+
+ &s.code;errmin&e.code;
+ <quote><p>
+ Like &s.code;errmaj&e.code;, but for the minor part
+ of the error code.
+
+ </quote>
+
+ </quote>
+
+ &s.code;void UnloadModule(pointer mod)&e.code;
+ <quote><p>
+ This function unloads the module referred to by the handle mod.
+ All child modules are also unloaded recursively. This function must
+ not be used to directly unload modules that are child modules (i.e.,
+ those that have been loaded with &s.code;LoadSubModule()&e.code;).
+
+ </quote>
+ </quote>
+
+<sect1>Module Requirements
+<p>
+
+Modules must provide information about themselves to the loader, and
+may optionally provide entry points for "setup" and "teardown" functions
+(those two functions are referred to here as &s.code;SetupProc&e.code;
+and &s.code;TearDownProc&e.code;).
+
+The module information is contained in the
+&s.code;XF86ModuleVersionInfo&e.code; struct, which is defined as follows:
+
+<quote><p><verb>
+typedef struct {
+ const char * modname; /* name of module, e.g. "foo" */
+ const char * vendor; /* vendor specific string */
+ CARD32 _modinfo1_; /* constant MODINFOSTRING1/2 to find */
+ CARD32 _modinfo2_; /* infoarea with a binary editor/sign tool */
+ CARD32 xf86version; /* contains XF86_VERSION_CURRENT */
+ CARD8 majorversion; /* module-specific major version */
+ CARD8 minorversion; /* module-specific minor version */
+ CARD16 patchlevel; /* module-specific patch level */
+ const char * abiclass; /* ABI class that the module uses */
+ CARD32 abiversion; /* ABI version */
+ const char * moduleclass; /* module class */
+ CARD32 checksum[4]; /* contains a digital signature of the */
+ /* version info structure */
+} XF86ModuleVersionInfo;
+</verb>
+
+The fields are used as follows:
+
+ &s.code;modname&e.code;
+ <quote><p>
+ The module's name. This field is currently only for
+ informational purposes, but the loader may be modified
+ in future to require it to match the module's canonical
+ name.
+
+ </quote>
+
+ &s.code;vendor&e.code;
+ <quote><p>
+ The module vendor. This field is for informational purposes
+ only.
+
+ </quote>
+
+ &s.code;_modinfo1_&e.code;
+ <quote><p>
+ This field holds the first part of a signature that can
+ be used to locate this structure in the binary. It should
+ always be initialised to &s.code;MODINFOSTRING1&e.code;.
+
+ </quote>
+
+ &s.code;_modinfo2_&e.code;
+ <quote><p>
+ This field holds the second part of a signature that can
+ be used to locate this structure in the binary. It should
+ always be initialised to &s.code;MODINFOSTRING2&e.code;.
+
+ </quote>
+
+ &s.code;xf86version&e.code;
+ <quote><p>
+ The XFree86 version against which the module was compiled.
+ This is mostly for informational/diagnostic purposes. It
+ should be initialised to &s.code;XF86_VERSION_CURRENT&e.code;, which is
+ defined in &s.code;xf86Version.h&e.code;.
+
+ </quote>
+
+ &s.code;majorversion&e.code;
+ <quote><p>
+ The module-specific major version. For modules where this
+ version is used for more than simply informational
+ purposes, the major version should only change (be
+ incremented) when ABI incompatibilities are introduced,
+ or ABI components are removed.
+
+ </quote>
+
+ &s.code;minorversion&e.code;
+ <quote><p>
+ The module-specific minor version. For modules where this
+ version is used for more than simply informational
+ purposes, the minor version should only change (be
+ incremented) when ABI additions are made in a backward
+ compatible way. It should be reset to zero when the major
+ version is increased.
+
+ </quote>
+
+ &s.code;patchlevel&e.code;
+ <quote><p>
+ The module-specific patch level. The patch level should
+ increase with new revisions of the module where there
+ are no ABI changes, and it should be reset to zero when
+ the minor version is increased.
+
+ </quote>
+
+ &s.code;abiclass&e.code;
+ <quote><p>
+ The ABI class that the module requires. The class is
+ specified as a string for easy extensibility. It should
+ indicate which (if any) of the X server's built-in ABI
+ classes that the module relies on, or a third-party ABI
+ if appropriate. Built-in ABI classes currently defined are:
+
+ <quote>
+ &s.code;ABI_CLASS_NONE&e.code;
+ <quote>no class</quote>
+ &s.code;ABI_CLASS_ANSIC&e.code;
+ <quote>only requires the ANSI C interfaces</quote>
+ &s.code;ABI_CLASS_VIDEODRV&e.code;
+ <quote>requires the video driver ABI</quote>
+ &s.code;ABI_CLASS_XINPUT&e.code;
+ <quote>requires the XInput driver ABI</quote>
+ &s.code;ABI_CLASS_EXTENSION&e.code;
+ <quote>requires the extension module ABI</quote>
+ &s.code;ABI_CLASS_FONT&e.code;
+ <quote>requires the font module ABI</quote>
+ </quote>
+
+ </quote>
+
+ &s.code;abiversion&e.code;
+ <quote><p>
+ The version of abiclass that the module requires. The
+ version consists of major and minor components. The
+ major version must match and the minor version must be
+ no newer than that provided by the server or parent
+ module. Version identifiers for the built-in classes
+ currently defined are:
+
+ <quote>
+ &s.code;ABI_ANSIC_VERSION&nl;
+ ABI_VIDEODRV_VERSION&nl;
+ ABI_XINPUT_VERSION&nl;
+ ABI_EXTENSION_VERSION&nl;
+ ABI_FONT_VERSION&e.code;
+ </quote>
+
+ </quote>
+
+ &s.code;moduleclass&e.code;
+ <quote><p>
+ This is similar to the abiclass field, except that it
+ defines the type of module rather than the ABI it
+ requires. For example, although all video drivers require
+ the video driver ABI, not all modules that require the
+ video driver ABI are video drivers. This distinction
+ can be made with the moduleclass. Currently pre-defined
+ module classes are:
+
+ <quote>
+ &s.code;MOD_CLASS_NONE&nl;
+ MOD_CLASS_VIDEODRV&nl;
+ MOD_CLASS_XINPUT&nl;
+ MOD_CLASS_FONT&nl;
+ MOD_CLASS_EXTENSION&e.code;
+ </quote>
+
+ </quote>
+
+ &s.code;checksum&e.code;
+ <quote><p>
+ Not currently used.
+
+ </quote>
+
+</quote>
+
+The module version information, and the optional &s.code;SetupProc&e.code;
+and &s.code;TearDownProc&e.code; entry points are found by the loader
+by locating a data object in the module called "modnameModuleData",
+where "modname" is the canonical name of the module. Modules must
+contain such a data object, and it must be declared with global scope,
+be compile-time initialised, and is of the following type:
+
+<quote>
+<verb>
+typedef struct {
+ XF86ModuleVersionInfo * vers;
+ ModuleSetupProc setup;
+ ModuleTearDownProc teardown;
+} XF86ModuleData;
+</verb>
+</quote>
+
+The vers parameter must be initialised to a pointer to a correctly
+initialised &s.code;XF86ModuleVersionInfo&e.code; struct. The other
+two parameter are optional, and should be initialised to
+&s.code;NULL&e.code; when not required. The other parameters are defined
+as
+
+ <quote><p>
+ &s.code;typedef pointer (*ModuleSetupProc)(pointer, pointer, int *, int *)&e.code;
+
+ &s.code;typedef void (*ModuleTearDownProc)(pointer)&e.code;
+
+
+ &s.code;pointer SetupProc(pointer module, pointer options,
+ &f.indent;int *errmaj, int *errmin)&e.code;
+ <quote><p>
+ When defined, this function is called by the loader after successfully
+ loading a module. module is a handle for the newly loaded module,
+ and maybe used by the &s.code;SetupProc&e.code; if it calls other
+ loader functions that require a reference to it. The remaining
+ arguments are those that were passed to the
+ &s.code;LoadModule()&e.code; (or &s.code;LoadSubModule()&e.code;),
+ and are described above. When the &s.code;SetupProc&e.code; is
+ successful it must return a non-&s.code;NULL&e.code; value. The
+ loader checks this, and if it is &s.code;NULL&e.code; it unloads
+ the module and reports the failure to the caller of
+ &s.code;LoadModule()&e.code;. If the &s.code;SetupProc&e.code; does
+ things that need to be undone when the module is unloaded, it should
+ define a &s.code;TearDownProc&e.code;, and return a pointer that
+ the &s.code;TearDownProc&e.code; can use to undo what has been done.
+
+ When a module is loaded multiple times, the &s.code;SetupProc&e.code;
+ is called once for each time it is loaded.
+
+ </quote>
+
+ &s.code;void TearDownProc(pointer tearDownData)&e.code;
+ <quote><p>
+ When defined, this function is called when the loader unloads a
+ module. The &s.code;tearDownData&e.code; parameter is the return
+ value of the &s.code;SetupProc()&e.code; that was called when the
+ module was loaded. The purpose of this function is to clean up
+ before the module is unloaded (for example, by freeing allocated
+ resources).
+
+ </quote>
+ </quote>
+
+<sect1>Public Loader Interface
+<p>
+
+The following is the Loader interface that is available to any part of
+the server, and may also be used from within modules.
+
+ <quote><p>
+ &s.code;pointer LoadSubModule(pointer parent, const char *module,
+ &f.indent;const char **subdirlist, const char **patternlist,
+ &f.indent;pointer options, const XF86ModReqInfo * modreq,
+ &f.indent;int *errmaj, int *errmin)&e.code;
+ <quote><p>
+ This function is like the &s.code;LoadModule()&e.code; function
+ described above, except that the module loaded is registered as a
+ child of the calling module. The &s.code;parent&e.code; parameter
+ is the calling module's handle. Modules loaded with this function
+ are automatically unloaded when the parent module is unloaded. The
+ other difference is that the path parameter may not be specified.
+ The module search path used for modules loaded with this function
+ is the default search path as initialised with
+ &s.code;LoaderSetPath()&e.code;.
+
+ </quote>
+
+ &s.code;void UnloadSubModule(pointer module)&e.code;
+ <quote><p>
+ This function unloads the module with handle &s.code;module&e.code;.
+ If that module itself has children, they are also unloaded. It is
+ like &s.code;LoadModule()&e.code;, except that it is safe to use
+ for unloading child modules.
+
+ </quote>
+
+ &s.code;pointer LoaderSymbol(const char *symbol)&e.code;
+ <quote><p>
+ This function returns the address of the symbol with name
+ &s.code;symbol&e.code;. This may be used to locate a module entry
+ point with a known name.
+
+ </quote>
+
+ &s.code;char **LoaderlistDirs(const char **subdirlist,
+ &f.indent;const char **patternlist)&e.code;
+ <quote><p>
+ This function returns a &s.code;NULL&e.code; terminated list of
+ canonical modules names for modules found in the default module
+ search path. The &s.code;subdirlist&e.code; and
+ &s.code;patternlist&e.code; parameters are as described above, and
+ can be used to control the locations and names that are searched.
+ If no modules are found, the return value is &s.code;NULL&e.code;.
+ The returned list should be freed by calling
+ &s.code;LoaderFreeDirList()&e.code; when it is no longer needed.
+
+ </quote>
+
+ &s.code;void LoaderFreeDirList(char **list)&e.code;
+ <quote><p>
+ This function frees a module list created by
+ &s.code;LoaderlistDirs()&e.code;.
+
+ </quote>
+
+ &s.code;void LoaderReqSymLists(const char **list0, ...)&e.code;
+ <quote><p>
+ This function allows the registration of required symbols with the
+ loader. It is normally used by a caller of
+ &s.code;LoadSubModule()&e.code;. If any symbols registered in this
+ way are found to be unresolved when
+ &s.code;LoaderCheckUnresolved()&e.code; is called then
+ &s.code;LoaderCheckUnresolved()&e.code; will report a failure. The
+ function takes one or more &s.code;NULL&e.code; terminated lists of
+ symbols. The end of the argument list is indicated by a
+ &s.code;NULL&e.code; argument.
+
+ </quote>
+
+ &s.code;void LoaderReqSymbols(const char *sym0, ...)&e.code;
+ <quote><p>
+ This function is like &s.code;LoaderReqSymLists()&e.code; except
+ that its arguments are symbols rather than lists of symbols. This
+ function is more convenient when single functions are to be registered,
+ especially when the single function might depend on runtime factors.
+ The end of the argument list is indicated by a &s.code;NULL&e.code;
+ argument.
+
+ </quote>
+
+ &s.code;void LoaderRefSymLists(const char **list0, ...)&e.code;
+ <quote><p>
+ This function allows the registration of possibly unresolved symbols
+ with the loader. When &s.code;LoaderCheckUnresolved()&e.code; is
+ run it won't generate warnings for symbols registered in this way
+ unless they were also registered as required symbols.
+
+ </quote>
+
+ &s.code;void LoaderRefSymbols(const char *sym0, ...)&e.code;
+ <quote><p>
+ This function is like &s.code;LoaderRefSymLists()&e.code; except
+ that its arguments are symbols rather than lists of symbols. This
+ function is more convenient when single functions are to be registered,
+ especially when the single function might depend on runtime factors.
+ The end of the argument list is indicated by a &s.code;NULL&e.code;
+ argument.
+
+ </quote>
+
+ &s.code;int LoaderCheckUnresolved(int delayflag)&e.code;
+ <quote><p>
+ This function checks for unresolved symbols. It generates warnings
+ for unresolved symbols that have not been registered with
+ &s.code;LoaderRefSymLists()&e.code;, and maps them to a dummy
+ function. This behaviour may change in future. If unresolved
+ symbols are found that have been registered with
+ &s.code;LoaderReqSymLists()&e.code; or
+ &s.code;LoaderReqSymbols()&e.code; then this function returns a
+ non-zero value. If none of these symbols are unresolved the return
+ value is zero, indicating success.
+
+ The &s.code;delayflag&e.code; parameter should normally be set to
+ &s.code;LD_RESOLV_IFDONE&e.code;.
+
+ </quote>
+
+ &s.code;LoaderErrorMsg(const char *name, const char *modname,
+ &f.indent;int errmaj, int errmin)&e.code;
+ <quote><p>
+ This function prints an error message that includes the text ``Failed
+ to load module'', the module name &s.code;modname&e.code;, a message
+ specific to the &s.code;errmaj&e.code; value, and the value if
+ &s.code;errmin&e.code;. If &s.code;name&e.code; is
+ non-&s.code;NULL&e.code;, it is printed as an identifying prefix
+ to the message (followed by a `:').
+
+ </quote>
+ </quote>
+
+<sect1>Special Registration Functions
+<p>
+
+The loader contains some functions for registering some classes of modules.
+These may be moved out of the loader at some point.
+
+ <quote><p>
+ &s.code;void LoadExtension(ExtensionModule *ext)&e.code;
+ <quote><p>
+ This registers the entry points for the extension identified by
+ &s.code;ext&e.code;. The &s.code;ExtensionModule&e.code; struct is
+ defined as:
+
+<quote>
+<verb>
+typedef struct {
+ InitExtension initFunc;
+ char * name;
+ Bool *disablePtr;
+ InitExtension setupFunc;
+} ExtensionModule;
+</verb>
+</quote>
+
+ </quote>
+
+ &s.code;void LoadFont(FontModule *font)&e.code;
+ <quote><p>
+ This registers the entry points for the font rasteriser module
+ identified by &s.code;font&e.code;. The &s.code;FontModule&e.code;
+ struct is defined as:
+
+<quote>
+<verb>
+typedef struct {
+ InitFont initFunc;
+ char * name;
+ pointer module;
+} FontModule;
+</verb>
+</quote>
+
+ </quote>
+ </quote>
+
+</sect>
+
+
+<sect>Helper Functions
+<p>
+
+This section describe ``helper'' functions that video driver
+might find useful. While video drivers are not required to use any of
+these to be considered ``compliant'', the use of appropriate helpers is
+strongly encouraged to improve the consistency of driver behaviour.
+
+<sect1>Functions for printing messages
+<p>
+
+ <quote><p>
+ &s.code;ErrorF(const char *format, ...)&e.code;
+ <quote><p>
+ This is the basic function for writing to the error log (typically
+ stderr and/or a log file). Video drivers should usually avoid
+ using this directly in favour of the more specialised functions
+ described below. This function is useful for printing messages
+ while debugging a driver.
+
+ </quote>
+
+ &s.code;FatalError(const char *format, ...)&e.code;
+ <quote><p>
+ This prints a message and causes the Xserver to abort. It should
+ rarely be used within a video driver, as most error conditions
+ should be flagged by the return values of the driver functions.
+ This allows the higher layers to decide how to proceed. In rare
+ cases, this can be used within a driver if a fatal unexpected
+ condition is found.
+
+ </quote>
+
+ &s.code;xf86ErrorF(const char *format, ...)&e.code;
+ <quote><p>
+ This is like &s.code;ErrorF()&e.code;, except that the message is
+ only printed when the Xserver's verbosity level is set to the
+ default (&s.code;1&e.code;) or higher. It means that the messages
+ are not printed when the server is started with the
+ &s.cmd;-quiet&e.cmd; flag. Typically this function would only be
+ used for continuing messages started with one of the more specialised
+ functions described below.
+
+ </quote>
+
+ &s.code;xf86ErrorFVerb(int verb, const char *format, ...)&e.code;
+ <quote><p>
+ Like &s.code;xf86ErrorF()&e.code;, except the minimum verbosity
+ level for which the message is to be printed is given explicitly.
+ Passing a &s.code;verb&e.code; value of zero means the message
+ is always printed. A value higher than &s.code;1&e.code; can be
+ used for information would normally not be needed, but which might
+ be useful when diagnosing problems.
+
+ </quote>
+
+ &s.code;xf86Msg(MessageType type, const char *format, ...)&e.code;
+ <quote><p>
+ This is like &s.code;xf86ErrorF()&e.code;, except that the message
+ is prefixed with a marker determined by the value of
+ &s.code;type&e.code;. The marker is used to indicate the type of
+ message (warning, error, probed value, config value, etc). Note
+ the &s.code;xf86Verbose&e.code; value is ignored for messages of
+ type &s.code;X_ERROR&e.code;.
+
+ The marker values are:
+
+ <quote>
+ &s.code;X_PROBED&e.code;
+ <quote>Value was probed.</quote>
+ &s.code;X_CONFIG&e.code;
+ <quote>Value was given in the config file.</quote>
+ &s.code;X_DEFAULT&e.code;
+ <quote>Value is a default.</quote>
+ &s.code;X_CMDLINE&e.code;
+ <quote>Value was given on the command line.</quote>
+ &s.code;X_NOTICE&e.code;
+ <quote>Notice.</quote>
+ &s.code;X_ERROR&e.code;
+ <quote>Error message.</quote>
+ &s.code;X_WARNING&e.code;
+ <quote>Warning message.</quote>
+ &s.code;X_INFO&e.code;
+ <quote>Informational message.</quote>
+ &s.code;X_NONE&e.code;
+ <quote>No prefix.</quote>
+ </quote>
+
+
+ </quote>
+
+ &s.code;xf86MsgVerb(MessageType type, int verb, const char *format, ...)&e.code;
+ <quote><p>
+ Like &s.code;xf86Msg()&e.code;, but with the verbosity level given
+ explicitly.
+
+ </quote>
+
+ &s.code;xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)&e.code;
+ <quote><p>
+ This is like &s.code;xf86Msg()&e.code; except that the driver's
+ name (the &s.code;name&e.code; field of the
+ &s.code;ScrnInfoRec&e.code;) followed by the
+ &s.code;scrnIndex&e.code; in parentheses is printed following the
+ prefix. This should be used by video drivers in most cases as it
+ clearly indicates which driver/screen the message is for. If
+ &s.code;scrnIndex&e.code; is negative, this function behaves
+ exactly like &s.code;xf86Msg()&e.code;.
+
+ NOTE: This function can only be used after the
+ &s.code;ScrnInfoRec&e.code; and its &s.code;name&e.code; field
+ have been allocated. That means that it can not be used before
+ the END of the &s.code;ChipProbe()&e.code; function. Prior to
+ that, use &s.code;xf86Msg()&e.code;, providing the driver's name
+ explicitly. No screen number can be supplied at that point.
+
+ </quote>
+
+ &s.code;xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb,
+ &f.indent;const char *format, ...)&e.code;
+ <quote><p>
+ Like &s.code;xf86DrvMsg()&e.code;, but with the verbosity level
+ given explicitly.
+
+ </quote>
+ </quote>
+
+
+<sect1>Functions for setting values based on command line and config file
+<p>
+
+ <quote><p>
+ &s.code;Bool xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int bpp, int fbbpp,
+ &f.indent;int depth24flags)&e.code;
+ <quote><p>
+ This function sets the &s.code;depth&e.code;, &s.code;pixmapBPP&e.code; and &s.code;bitsPerPixel&e.code; fields
+ of the &s.code;ScrnInfoRec&e.code;. It also determines the defaults for display-wide
+ attributes and pixmap formats the screen will support, and finds
+ the Display subsection that matches the depth/bpp. This function
+ should normally be called very early from the
+ &s.code;ChipPreInit()&e.code; function.
+
+ It requires that the &s.code;confScreen&e.code; field of the &s.code;ScrnInfoRec&e.code; be
+ initialised prior to calling it. This is done by the XFree86
+ common layer prior to calling &s.code;ChipPreInit()&e.code;.
+
+ The parameters passed are:
+
+ &s.code;depth&e.code;
+ <quote><p>
+ driver's preferred default depth if no other is given.
+ If zero, use the overall server default.
+
+ </quote>
+ &s.code;bpp&e.code;
+ <quote><p>
+ Same, but for the pixmap bpp.
+
+ </quote>
+ &s.code;fbbpp&e.code;
+ <quote><p>
+ Same, but for the framebuffer bpp.
+
+ </quote>
+ &s.code;depth24flags&e.code;
+ <quote><p>
+ Flags that indicate the level of 24/32bpp support
+ and whether conversion between different framebuffer
+ and pixmap formats is supported. The flags for this
+ argument are defined as follows, and multiple flags
+ may be ORed together:
+
+ &s.code;NoDepth24Support&e.code;
+ <quote>No depth 24 formats supported</quote>
+ &s.code;Support24bppFb&e.code;
+ <quote>24bpp framebuffer supported</quote>
+ &s.code;Support32bppFb&e.code;
+ <quote>32bpp framebuffer supported</quote>
+ &s.code;SupportConvert24to32&e.code;
+ <quote>Can convert 24bpp pixmap to 32bpp fb</quote>
+ &s.code;SupportConvert32to24&e.code;
+ <quote>Can convert 32bpp pixmap to 24bpp fb</quote>
+ &s.code;ForceConvert24to32&e.code;
+ <quote>Force 24bpp pixmap to 32bpp fb conversion</quote>
+ &s.code;ForceConvert32to24&e.code;
+ <quote>Force 32bpp pixmap to 24bpp fb conversion</quote>
+
+ </quote>
+
+ It uses the command line, config file, and default values in the
+ correct order of precedence to determine the depth and bpp values.
+ It is up to the driver to check the results to see that it supports
+ them. If not the &s.code;ChipPreInit()&e.code; function should
+ return &s.code;FALSE&e.code;.
+
+ If only one of depth/bpp is given, the other is set to a reasonable
+ (and consistent) default.
+
+ If a driver finds that the initial &s.code;depth24flags&e.code;
+ it uses later results in a fb format that requires more video
+ memory than is available it may call this function a second time
+ with a different &s.code;depth24flags&e.code; setting.
+
+ On success, the return value is &s.code;TRUE&e.code;. On failure
+ it prints an error message and returns &s.code;FALSE&e.code;.
+
+ The following fields of the &s.code;ScrnInfoRec&e.code; are
+ initialised by this function:
+
+ <quote>
+ &s.code;depth&e.code;, &s.code;bitsPerPixel&e.code;,
+ &s.code;display&e.code;, &s.code;imageByteOrder&e.code;,
+ &s.code;bitmapScanlinePad&e.code;,
+ &s.code;bitmapScanlineUnit&e.code;, &s.code;bitmapBitOrder&e.code;,
+ &s.code;numFormats&e.code;, &s.code;formats&e.code;,
+ &s.code;fbFormat&e.code;.
+ </quote>
+
+ </quote>
+
+ &s.code;void xf86PrintDepthBpp(scrnInfoPtr scrp)&e.code;
+ <quote><p>
+ This function can be used to print out the depth and bpp settings.
+ It should be called after the final call to
+ &s.code;xf86SetDepthBpp()&e.code;.
+
+ </quote>
+
+ &s.code;Bool xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)&e.code;
+ <quote><p>
+ This function sets the &s.code;weight&e.code;, &s.code;mask&e.code;,
+ &s.code;offset&e.code; and &s.code;rgbBits&e.code; fields of the
+ &s.code;ScrnInfoRec&e.code;. It would normally be called fairly
+ early in the &s.code;ChipPreInit()&e.code; function for
+ depths&nbsp;>&nbsp;8bpp.
+
+ It requires that the &s.code;depth&e.code; and
+ &s.code;display&e.code; fields of the &s.code;ScrnInfoRec&e.code;
+ be initialised prior to calling it.
+
+ The parameters passed are:
+
+ &s.code;weight&e.code;
+ <quote><p>
+ driver's preferred default weight if no other is given.
+ If zero, use the overall server default.
+
+ </quote>
+
+ &s.code;mask&e.code;
+ <quote><p>
+ Same, but for mask.
+
+ </quote>
+
+ It uses the command line, config file, and default values in the
+ correct order of precedence to determine the weight value. It
+ derives the mask and offset values from the weight and the defaults.
+ It is up to the driver to check the results to see that it supports
+ them. If not the &s.code;ChipPreInit()&e.code; function should
+ return &s.code;FALSE&e.code;.
+
+ On success, this function prints a message showing the weight
+ values selected, and returns &s.code;TRUE&e.code;.
+
+ On failure it prints an error message and returns &s.code;FALSE&e.code;.
+
+ The following fields of the &s.code;ScrnInfoRec&e.code; are
+ initialised by this function:
+
+ <quote>
+ &s.code;weight&e.code;, &s.code;mask&e.code;, &s.code;offset&e.code;.
+ </quote>
+
+ </quote>
+
+ &s.code;Bool xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual)&e.code;
+ <quote><p>
+ This function sets the &s.code;defaultVisual&e.code; field of the
+ &s.code;ScrnInfoRec&e.code;. It would normally be called fairly
+ early from the &s.code;ChipPreInit()&e.code; function.
+
+ It requires that the &s.code;depth&e.code; and
+ &s.code;display&e.code; fields of the &s.code;ScrnInfoRec&e.code;
+ be initialised prior to calling it.
+
+ The parameters passed are:
+
+ &s.code;visual&e.code;
+ <quote><p>
+ driver's preferred default visual if no other is given.
+ If &s.code;-1&e.code;, use the overall server default.
+
+ </quote>
+
+ It uses the command line, config file, and default values in the
+ correct order of precedence to determine the default visual value.
+ It is up to the driver to check the result to see that it supports
+ it. If not the &s.code;ChipPreInit()&e.code; function should
+ return &s.code;FALSE&e.code;.
+
+ On success, this function prints a message showing the default visual
+ selected, and returns &s.code;TRUE&e.code;.
+
+ On failure it prints an error message and returns &s.code;FALSE&e.code;.
+
+ </quote>
+
+ &s.code;Bool xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)&e.code;
+ <quote><p>
+ This function sets the &s.code;gamma&e.code; field of the
+ &s.code;ScrnInfoRec&e.code;. It would normally be called fairly
+ early from the &s.code;ChipPreInit()&e.code; function in cases
+ where the driver supports gamma correction.
+
+ It requires that the &s.code;monitor&e.code; field of the
+ &s.code;ScrnInfoRec&e.code; be initialised prior to calling it.
+
+ The parameters passed are:
+
+ &s.code;gamma&e.code;
+ <quote><p>
+ driver's preferred default gamma if no other is given.
+ If zero (&s.code;< 0.01&e.code;), use the overall server
+ default.
+
+ </quote>
+
+ It uses the command line, config file, and default values in the
+ correct order of precedence to determine the gamma value. It is
+ up to the driver to check the results to see that it supports
+ them. If not the &s.code;ChipPreInit()&e.code; function should
+ return &s.code;FALSE&e.code;.
+
+ On success, this function prints a message showing the gamma
+ value selected, and returns &s.code;TRUE&e.code;.
+
+ On failure it prints an error message and returns &s.code;FALSE&e.code;.
+
+ </quote>
+
+ &s.code;void xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)&e.code;
+ <quote><p>
+ This function sets the &s.code;xDpi&e.code; and &s.code;yDpi&e.code;
+ fields of the &s.code;ScrnInfoRec&e.code;. The driver can specify
+ preferred defaults by setting &s.code;x&e.code; and &s.code;y&e.code;
+ to non-zero values. The &s.cmd;-dpi&e.cmd; command line option
+ overrides all other settings. Otherwise, if the
+ &s.key;DisplaySize&e.key; entry is present in the screen's &k.monitor;
+ config file section, it is used together with the virtual size to
+ calculate the dpi values. This function should be called after
+ all the mode resolution has been done.
+
+ </quote>
+
+ &s.code;void xf86SetBlackWhitePixels(ScrnInfoPtr pScrn)&e.code;
+ <quote><p>
+ This functions sets the &s.code;blackPixel&e.code; and
+ &s.code;whitePixel&e.code; fields of the &s.code;ScrnInfoRec&e.code;
+ according to whether or not the &s.cmd;-flipPixels&e.cmd; command
+ line options is present.
+
+ </quote>
+
+ &s.code;const char *xf86GetVisualName(int visual)&e.code;
+ <quote><p>
+ Returns a printable string with the visual name matching the
+ numerical visual class provided. If the value is outside the
+ range of valid visual classes, &s.code;NULL&e.code; is returned.
+
+ </quote>
+ </quote>
+
+
+<sect1>Primary Mode functions
+<p>
+
+The primary mode helper functions are those which would normally be
+used by a driver, unless it has unusual requirements which cannot
+be catered for the by the helpers.
+
+ <quote><p>
+ &s.code;int xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
+ &f.indent;char **modeNames, ClockRangePtr clockRanges,
+ &f.indent;int *linePitches, int minPitch, int maxPitch,
+ &f.indent;int pitchInc, int minHeight, int maxHeight,
+ &f.indent;int virtualX, int virtualY,
+ &f.indent;unsigned long apertureSize,
+ &f.indent;LookupModeFlags strategy)&e.code;
+ <quote><p>
+ This function basically selects the set of modes to use based on
+ those available and the various constraints. It also sets some
+ other related parameters. It is normally called near the end of
+ the &s.code;ChipPreInit()&e.code; function.
+
+ The parameters passed to the function are:
+
+ &s.code;availModes&e.code;
+ <quote><p>
+ List of modes available for the monitor.
+
+ </quote>
+ &s.code;modeNames&e.code;
+ <quote><p>
+ List of mode names that the screen is requesting.
+
+ </quote>
+ &s.code;clockRanges&e.code;
+ <quote><p>
+ A list of clock ranges allowed by the driver. Each
+ range includes whether interlaced or multiscan modes
+ are supported for that range. See below for more on
+ &s.code;clockRanges&e.code;.
+
+ </quote>
+ &s.code;linePitches&e.code;
+ <quote><p>
+ List of supported line pitches supported by the driver.
+ This is optional and should be &s.code;NULL&e.code; when
+ not used.
+
+ </quote>
+ &s.code;minPitch&e.code;
+ <quote><p>
+ Minimum line pitch supported by the driver. This must
+ be supplied when &s.code;linePitches&e.code; is
+ &s.code;NULL&e.code;, and is ignored otherwise.
+
+ </quote>
+ &s.code;maxPitch&e.code;
+ <quote><p>
+ Maximum line pitch supported by the driver. This is
+ required when &s.code;minPitch&e.code; is required.
+
+ </quote>
+ &s.code;pitchInc&e.code;
+ <quote><p>
+ Granularity of horizontal pitch values as supported by
+ the chipset. This is expressed in bits. This must be
+ supplied.
+
+ </quote>
+ &s.code;minHeight&e.code;
+ <quote><p>
+ minimum virtual height allowed. If zero, no limit is
+ imposed.
+
+ </quote>
+ &s.code;maxHeight&e.code;
+ <quote><p>
+ maximum virtual height allowed. If zero, no limit is
+ imposed.
+
+ </quote>
+ &s.code;virtualX&e.code;
+ <quote><p>
+ If greater than zero, this is the virtual width value
+ that will be used. Otherwise, the virtual width is
+ chosen to be the smallest that can accommodate the modes
+ selected.
+
+ </quote>
+ &s.code;virtualY&e.code;
+ <quote><p>
+ If greater than zero, this is the virtual height value
+ that will be used. Otherwise, the virtual height is
+ chosen to be the smallest that can accommodate the modes
+ selected.
+
+ </quote>
+ &s.code;apertureSize&e.code;
+ <quote><p>
+ The size (in bytes) of the aperture used to access video
+ memory.
+
+ </quote>
+ &s.code;strategy&e.code;
+ <quote><p>
+ The strategy to use when choosing from multiple modes
+ with the same name. The options are:
+
+ &s.code;LOOKUP_DEFAULT&e.code;
+ <quote>???</quote>
+ &s.code;LOOKUP_BEST_REFRESH&e.code;
+ <quote>mode with best refresh rate</quote>
+ &s.code;LOOKUP_CLOSEST_CLOCK&e.code;
+ <quote>mode with closest matching clock</quote>
+ &s.code;LOOKUP_LIST_ORDER&e.code;
+ <quote>first usable mode in list</quote>
+ &s.code;LOOKUP_CLKDIV2&e.code;
+ <quote>Allow halved clocks</quote>
+
+ &s.code;LOOKUP_CLKDIV2&e.code; can be combined (OR'ed)
+ with one of the others.
+
+ </quote>
+
+ This function requires that the following fields of the
+ &s.code;ScrnInfoRec&e.code; are initialised prior to calling it:
+
+ &s.code;clock[]&e.code;
+ <quote>List of discrete clocks (when non-programmable).</quote>
+ &s.code;numClocks&e.code;
+ <quote>Number of discrete clocks (when non-programmable).</quote>
+ &s.code;progClock&e.code;
+ <quote>Whether the clock is programmable or not.</quote>
+ &s.code;formats&e.code;
+ <quote>pixmap formats for screen</quote>
+ &s.code;numFormats&e.code;
+ <quote>number of pixmap formats for screen</quote>
+ &s.code;videoRam&e.code;
+ <quote>total video memory size (in bytes)</quote>
+ &s.code;maxHValue&e.code;
+ <quote>Maximum horizontal timing value allowed</quote>
+ &s.code;maxVValue&e.code;
+ <quote>Maximum vertical timing value allowed</quote>
+
+ This function fills in the following &s.code;ScrnInfoRec&e.code;
+ fields:
+
+ &s.code;modePool&e.code;
+ <quote><p>
+ A subset of the modes available to the monitor which
+ are compatible with the driver.
+
+ </quote>
+ &s.code;modes&e.code;
+ <quote><p>
+ One mode entry for each of the requested modes, with
+ the status field of each filled in to indicate if
+ the mode has been accepted or not. This list of
+ modes is a circular list.
+
+ </quote>
+ &s.code;virtualX&e.code;
+ <quote><p>
+ The resulting virtual width.
+
+ </quote>
+ &s.code;virtualY&e.code;
+ <quote><p>
+ The resulting virtual height.
+
+ </quote>
+ &s.code;displayWidth&e.code;
+ <quote><p>
+ The resulting line pitch.
+
+ </quote>
+ &s.code;virtualFrom&e.code;
+ <quote><p>
+ Where the virtual size was determined from.
+
+ </quote>
+
+ The first stage of this function checks that the
+ &s.code;virtualX&e.code; and &s.code;virtualY&e.code; values
+ supplied (if greater than zero) are consistent with the line pitch
+ and &s.code;maxHeight&e.code; limitations. If not, an error
+ message is printed, and the return value is &s.code;-1&e.code;.
+
+ The second stage sets up the mode pool, eliminating immediately
+ any modes that exceed the driver's line pitch limits, and also
+ the virtual width and height limits (if greater than zero). For
+ each mode removed an informational message is printed at verbosity
+ level &s.code;2&e.code;. If the mode pool ends up being empty,
+ an error message is printed, and the return value is
+ &s.code;-1&e.code;.
+
+ The final stage is to lookup each mode, and fill in the remaining
+ parameters. If an error condition is encountered, a message is
+ printed, and the return value is &s.code;-1&e.code;. Otherwise,
+ the return value is the number of valid modes found
+ (&s.code;0&e.code; if none are found).
+
+ A message is only printed by this function when a fundamental
+ problem is found. It is intended that this function may be called
+ more than once if there is more than one set of constraints that
+ the driver can work within.
+
+ If this function returns &s.code;-1&e.code;, the
+ &s.code;ChipPreInit()&e.code; function should return
+ &s.code;FALSE&e.code;.
+
+ &s.code;clockRanges&e.code; is a linked list of clock ranges
+ allowed by the driver. If a mode doesn't fit in any of the defined
+ &s.code;clockRanges&e.code;, it is rejected. The first
+ &s.code;clockRange&e.code; that matches all requirements is used.
+
+ &s.code;clockRanges&e.code; contains the following fields:
+
+ &s.code;minClock&nl;
+ maxClock&e.code;
+ <quote><p>
+ The lower and upper mode clock bounds for which the rest
+ of the &s.code;clockRange&e.code; parameters apply.
+ Since these are the mode clocks, they are not scaled
+ with the &s.code;ClockMulFactor&e.code; and
+ &s.code;ClockDivFactor&e.code;. It is up to the driver
+ to adjust these values if they depend on the clock
+ scaling factors.
+
+ </quote>
+ &s.code;clockIndex&e.code;
+ <quote><p>
+ (not used yet) &s.code;-1&e.code; for programmable clocks
+
+ </quote>
+ &s.code;interlaceAllowed&e.code;
+ <quote><p>
+ &s.code;TRUE&e.code; if interlacing is allowed for this
+ range
+
+ </quote>
+ &s.code;doubleScanAllowed&e.code;
+ <quote><p>
+ &s.code;TRUE&e.code; if doublescan is allowed for this
+ range
+
+ </quote>
+ &s.code;ClockMulFactor&nl;
+ ClockDivFactor&e.code;
+ <quote><p>
+ Scaling factors that are applied to the mode clocks ONLY
+ before selecting a clock index (when there is no
+ programmable clock) or a &s.code;SynthClock&e.code;
+ value. This is useful for drivers that support pixel
+ multiplexing or that need to scale the clocks because
+ of hardware restrictions (like sending 24bpp data to an
+ 8 bit RAMDAC using a tripled clock).
+
+ Note that these parameters describe what must be done
+ to the mode clock to achieve the data transport clock
+ between graphics controller and RAMDAC. For example
+ for &s.code;2:1&e.code; pixel multiplexing, two pixels
+ are sent to the RAMDAC on each clock. This allows the
+ RAMDAC clock to be half of the actual pixel clock.
+ Hence, &s.code;ClockMulFactor=1&e.code; and
+ &s.code;ClockDivFactor=2&e.code;. This means that the
+ clock used for clock selection (ie, determining the
+ correct clock index from the list of discrete clocks)
+ or for the &s.code;SynthClock&e.code; field in case of
+ a programmable clock is: (&s.code;mode-&gt;Clock *
+ ClockMulFactor) / ClockDivFactor&e.code;.
+
+ </quote>
+ &s.code;PrivFlags&e.code;
+ <quote><p>
+ This field is copied into the
+ &s.code;mode-&gt;PrivFlags&e.code; field when this
+ &s.code;clockRange&e.code; is selected by
+ &s.code;xf86ValidateModes()&e.code;. It allows the
+ driver to find out what clock range was selected, so it
+ knows it needs to set up pixel multiplexing or any other
+ range-dependent feature. This field is purely
+ driver-defined: it may contain flag bits, an index or
+ anything else (as long as it is an &s.code;INT&e.code;).
+ </quote>
+
+ Note that the &s.code;mode-&gt;SynthClock&e.code; field is always
+ filled in by &s.code;xf86ValidateModes()&e.code;: it will contain
+ the ``data transport clock'', which is the clock that will have
+ to be programmed in the chip when it has a programmable clock, or
+ the clock that will be picked from the clocks list when it is not
+ a programmable one. Thus:
+
+ &s.code;mode-&gt;SynthClock =
+ &f.indent;(mode-&gt;Clock * ClockMulFactor) / ClockDivFactor&e.code;
+
+ </quote>
+
+ &s.code;void xf86PruneDriverModes(ScrnInfoPtr scrp)&e.code;
+ <quote><p>
+ This function deletes modes in the modes field of the
+ &s.code;ScrnInfoRec&e.code; that have been marked as invalid.
+ This is normally run after having run
+ &s.code;xf86ValidateModes()&e.code; for the last time. For each
+ mode that is deleted, a warning message is printed out indicating
+ the reason for it being deleted.
+
+ </quote>
+
+ &s.code;void xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags)&e.code;
+ <quote><p>
+ This function fills in the &s.code;Crtc*&e.code; fields for all
+ the modes in the &s.code;modes&e.code; field of the
+ &s.code;ScrnInfoRec&e.code;. The &s.code;adjustFlags&e.code;
+ parameter determines how the vertical CRTC values are scaled for
+ interlaced modes. They are halved if it is
+ &s.code;INTERLACE_HALVE_V&e.code;. The vertical CRTC values are
+ doubled for doublescan modes, and are further multiplied by the
+ &s.code;VScan&e.code; value.
+
+ This function is normally called after calling
+ &s.code;xf86PruneDriverModes()&e.code;.
+
+ NOTE: The &s.code;Crtc*&e.code; fields are not initialised anywhere
+ else, so the driver must either call this function or initialise
+ them itself.
+
+ </quote>
+
+ &s.code;void xf86PrintModes(ScrnInfoPtr scrp)&e.code;
+ <quote><p>
+ This function prints out the virtual size setting, and the line
+ pitch being used. It also prints out one line for each mode being
+ used, including its pixel clock, horizontal sync rate, refresh
+ rate, and whether it is interlaced or multiscan.
+
+ This function is normally called after calling
+ &s.code;xf86SetCrtcForModes()&e.code;.
+
+ </quote>
+ </quote>
+
+
+<sect1>Secondary Mode functions
+<p>
+
+The secondary mode helper functions are functions which are normally
+used by the primary mode helper functions, and which are not normally
+called directly by a driver. If a driver has unusual requirements
+and needs to do its own mode validation, it might be able to make
+use of some of these secondary mode helper functions.
+
+ <quote><p>
+ &s.code;int xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2,
+ &f.indent;int *divider)&e.code;
+ <quote><p>
+ This function returns the index of the closest clock to the
+ frequency &s.code;freq&e.code; given (in kHz). It assumes that
+ the number of clocks is greater than zero. It requires that the
+ &s.code;numClocks&e.code; and &s.code;clock&e.code; fields of the
+ &s.code;ScrnInfoRec&e.code; are initialised. The
+ &s.code;allowDiv2&e.code; field determines if the clocks can be
+ halved. The &s.code;*divider&e.code; return value indicates
+ whether clock division is used when determining the clock returned.
+
+ This function is only for non-programmable clocks.
+
+ </quote>
+
+ &s.code;const char *xf86ModeStatusToString(ModeStatus status)&e.code;
+ <quote><p>
+ This function converts the &s.code;status&e.code; value to a
+ descriptive printable string.
+
+ </quote>
+
+ &s.code;ModeStatus xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
+ &f.indent;ClockRangePtr clockRanges, LookupModeFlags strategy)&e.code;
+ <quote><p>
+ This function takes a pointer to a mode with the name filled in,
+ and looks for a mode in the &s.code;modePool&e.code; list which
+ matches. The parameters of the matching mode are filled in to
+ &s.code;*modep&e.code;. The &s.code;clockRanges&e.code; and
+ &s.code;strategy&e.code; parameters are as for the
+ &s.code;xf86ValidateModes()&e.code; function above.
+
+ This function requires the &s.code;modePool&e.code;,
+ &s.code;clock[]&e.code;, &s.code;numClocks&e.code; and
+ &s.code;progClock&e.code; fields of the &s.code;ScrnInfoRec&e.code;
+ to be initialised before being called.
+
+ The return value is &s.code;MODE_OK&e.code; if a mode was found.
+ Otherwise it indicates why a matching mode could not be found.
+
+ </quote>
+
+ &s.code;ModeStatus xf86InitialCheckModeForDriver(ScrnInfoPtr scrp,
+ &f.indent;DisplayModePtr mode, int maxPitch,
+ &f.indent;int virtualX, int virtualY)&e.code;
+ <quote><p>
+ This function checks the passed mode against some basic driver
+ constraints. Apart from the ones passed explicitly, the
+ &s.code;maxHValue&e.code; and &s.code;maxVValue&e.code; fields of
+ the &s.code;ScrnInfoRec&e.code; are also used. If the
+ &s.code;ValidMode&e.code; field of the &s.code;ScrnInfoRec&e.code;
+ is set, that function is also called to check the mode.
+
+ If the mode is consistent with the constraints, the return value
+ is &s.code;MODE_OK&e.code;. Otherwise the return value indicates
+ which constraint wasn't met.
+
+ </quote>
+
+ &s.code;void xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode)&e.code;
+ <quote><p>
+ This function deletes the &s.code;mode&e.code; given from the
+ &s.code;modeList&e.code;. It never prints any messages, so it is
+ up to the caller to print a message if required.
+
+ </quote>
+ </quote>
+
+<sect1>Functions for handling strings and tokens
+<p>
+
+ Tables associating strings and numerical tokens combined with the
+ following functions provide a compact way of handling strings from
+ the config file, and for converting tokens into printable strings.
+ The table data structure is:
+
+<quote><verb>
+typedef struct {
+ int token;
+ const char * name;
+} SymTabRec, *SymTabPtr;
+</verb></quote>
+
+ A table is an initialised array of &s.code;SymTabRec&e.code;. The
+ tokens must be non-negative integers. Multiple names may be mapped
+ to a single token. The table is terminated with an element with a
+ &s.code;token&e.code; value of &s.code;-1&e.code; and
+ &s.code;NULL&e.code; for the &s.code;name&e.code;.
+
+
+ <quote><p>
+ &s.code;const char *xf86TokenToString(SymTabPtr table, int token)&e.code;
+ <quote><p>
+ This function returns the first string in &s.code;table&e.code;
+ that matches &s.code;token&e.code;. If no match is found,
+ &s.code;NULL&e.code; is returned (NOTE, older versions of this
+ function would return the string "unknown" when no match is found).
+
+ </quote>
+
+ &s.code;int xf86StringToToken(SymTabPtr table, const char *string)&e.code;
+ <quote><p>
+ This function returns the first token in &s.code;table&e.code;
+ that matches &s.code;string&e.code;. The
+ &s.code;xf86NameCmp()&e.code; function is used to determine the
+ match. If no match is found, &s.code;-1&e.code; is returned.
+
+ </quote>
+ </quote>
+
+
+<sect1>Functions for finding which config file entries to use
+<p>
+
+ These functions can be used to select the appropriate config file
+ entries that match the detected hardware. They are described above
+ in the <ref id="probe" name="Probe"> and
+ <ref id="avail" name="Available Functions"> sections.
+
+
+<sect1>Probing discrete clocks on old hardware
+<p>
+
+ The &s.code;xf86GetClocks()&e.code; function may be used to assist
+ in finding the discrete pixel clock values on older hardware.
+
+
+ <quote><p>
+ &s.code;void xf86GetClocks(ScrnInfoPtr pScrn, int num,
+ &f.indent;Bool (*ClockFunc)(ScrnInfoPtr, int),
+ &f.indent;void (*ProtectRegs)(ScrnInfoPtr, Bool),
+ &f.indent;void (*BlankScreen)(ScrnInfoPtr, Bool),
+ &f.indent;int vertsyncreg, int maskval, int knownclkindex,
+ &f.indent;int knownclkvalue)&e.code;
+ <quote><p>
+ This function uses a comparative sampling method to measure the
+ discrete pixel clock values. The number of discrete clocks to
+ measure is given by &s.code;num&e.code;. &s.code;clockFunc&e.code;
+ is a function that selects the &s.code;n&e.code;'th clock. It
+ should also save or restore any state affected by programming the
+ clocks when the index passed is &s.code;CLK_REG_SAVE&e.code; or
+ &s.code;CLK_REG_RESTORE&e.code;. &s.code;ProtectRegs&e.code; is
+ a function that does whatever is required to protect the hardware
+ state while selecting a new clock. &s.code;BlankScreen&e.code;
+ is a function that blanks the screen. &s.code;vertsyncreg&e.code;
+ and &s.code;maskval&e.code; are the register and bitmask to
+ check for the presence of vertical sync pulses.
+ &s.code;knownclkindex&e.code; and &s.code;knownclkvalue&e.code;
+ are the index and value of a known clock. These are the known
+ references on which the comparative measurements are based. The
+ number of clocks probed is set in &s.code;pScrn-&gt;numClocks&e.code;,
+ and the probed clocks are set in the &s.code;pScrn-&gt;clock[]&e.code;
+ array. All of the clock values are in units of kHz.
+
+ </quote>
+
+ &s.code;void xf86ShowClocks(ScrnInfoPtr scrp, MessageType from)&e.code;
+ <quote><p>
+ Print out the pixel clocks &s.code;scrp-&gt;clock[]&e.code;.
+ &s.code;from&e.code; indicates whether the clocks were probed
+ or from the config file.
+
+ </quote>
+ </quote>
+
+<sect>The vgahw module
+<p>
+
+The vgahw modules provides an interface for saving, restoring and
+programming the standard VGA registers, and for handling VGA colourmaps.
+
+<sect1>Data Structures
+<p>
+
+ The public data structures used by the vgahw module are
+ &s.code;vgaRegRec&e.code; and &s.code;vgaHWRec&e.code;. They are
+ defined in &s.code;vgaHW.h.&e.code;
+
+
+<sect1>General vgahw Functions
+<p>
+
+ <quote><p>
+ &s.code;Bool vgaHWGetHWRec(ScrnInfoPtr pScrn)&e.code;
+ <quote><p>
+ This function allocates a &s.code;vgaHWRec&e.code; structure, and
+ hooks it into the &s.code;ScrnInfoRec&e.code;'s
+ &s.code;privates&e.code;. Like all information hooked into the
+ &s.code;privates&e.code;, it is persistent, and only needs to be
+ allocated once per screen. This function should normally be called
+ from the driver's &s.code;ChipPreInit()&e.code; function. The
+ &s.code;vgaHWRec&e.code; is zero-allocated, and the following
+ fields are explicitly initialised:
+
+ &s.code;ModeReg.DAC[]&e.code;
+ <quote>initialised with a default colourmap</quote>
+ &s.code;ModeReg.Attribute[0x11]&e.code;
+ <quote>initialised with the default overscan index</quote>
+ &s.code;ShowOverscan&e.code;
+ <quote>initialised according to the "ShowOverscan" option</quote>
+ &s.code;paletteEnabled&e.code;
+ <quote>initialised to FALSE</quote>
+ &s.code;cmapSaved&e.code;
+ <quote>initialised to FALSE</quote>
+ &s.code;pScrn&e.code;
+ <quote>initialised to pScrn</quote>
+
+ In addition to the above, &s.code;vgaHWSetStdFuncs()&e.code; is
+ called to initialise the register access function fields with the
+ standard VGA set of functions.
+
+ Once allocated, a pointer to the &s.code;vgaHWRec&e.code; can be
+ obtained from the &s.code;ScrnInfoPtr&e.code; with the
+ &s.code;VGAHWPTR(pScrn)&e.code; macro.
+
+ </quote>
+
+ &s.code;void vgaHWFreeHWRec(ScrnInfoPtr pScrn)&e.code;
+ <quote><p>
+ This function frees a &s.code;vgaHWRec&e.code; structure. It
+ should be called from a driver's &s.code;ChipFreeScreen()&e.code;
+ function.
+
+ </quote>
+
+ &s.code;Bool vgaHWSetRegCounts(ScrnInfoPtr pScrn, int numCRTC,
+ &f.indent;int numSequencer, int numGraphics, int numAttribute)&e.code;
+ <quote><p>
+ This function allows the number of CRTC, Sequencer, Graphics and
+ Attribute registers to be changed. This makes it possible for
+ extended registers to be saved and restored with
+ &s.code;vgaHWSave()&e.code; and &s.code;vgaHWRestore()&e.code;.
+ This function should be called after a &s.code;vgaHWRec&e.code;
+ has been allocated with &s.code;vgaHWGetHWRec()&e.code;. The
+ default values are defined in &s.code;vgaHW.h&e.code; as follows:
+
+ <quote><verb>
+#define VGA_NUM_CRTC 25
+#define VGA_NUM_SEQ 5
+#define VGA_NUM_GFX 9
+#define VGA_NUM_ATTR 21
+ </verb></quote>
+
+ </quote>
+
+ &s.code;Bool vgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src)&e.code;
+ <quote><p>
+ This function copies the contents of the VGA saved registers in
+ &s.code;src&e.code; to &s.code;dst&e.code;. Note that it isn't
+ possible to simply do this with &s.code;memcpy()&e.code; (or
+ similar). This function returns &s.code;TRUE&e.code; unless there
+ is a problem allocating space for the &s.code;CRTC&e.code and
+ related fields in &s.code;dst&e.code;.
+
+ </quote>
+
+ &s.code;void vgaHWSetStdFuncs(vgaHWPtr hwp)&e.code;
+ <quote><p>
+ This function initialises the register access function fields of
+ &s.code;hwp&e.code; with the standard VGA set of functions. This
+ is called by &s.code;vgaHWGetHWRec()&e.code;, so there is usually
+ no need to call this explicitly. The register access functions
+ are described below.
+
+ </quote>
+
+ &s.code;void vgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset)&e.code;
+ <quote><p>
+ This function initialised the register access function fields of
+ hwp with a generic MMIO set of functions.
+ &s.code;hwp-&gt;MMIOBase&e.code; is initialised with
+ &s.code;base&e.code;, which must be the virtual address that the
+ start of MMIO area is mapped to. &s.code;hwp-&gt;MMIOOffset&e.code;
+ is initialised with &s.code;offset&e.code;, which must be calculated
+ in such a way that when the standard VGA I/O port value is added
+ to it the correct offset into the MMIO area results. That means
+ that these functions are only suitable when the VGA I/O ports are
+ made available in a direct mapping to the MMIO space. If that is
+ not the case, the driver will need to provide its own register
+ access functions. The register access functions are described
+ below.
+
+ </quote>
+
+ &s.code;Bool vgaHWMapMem(ScrnInfoPtr pScrn)&e.code;
+ <quote><p>
+ This function maps the VGA memory window. It requires that the
+ &s.code;vgaHWRec&e.code; be allocated. If a driver requires
+ non-default &s.code;MapPhys&e.code; or &s.code;MapSize&e.code;
+ settings (the physical location and size of the VGA memory window)
+ then those fields of the &s.code;vgaHWRec&e.code; must be initialised
+ before calling this function. Otherwise, this function initialiases
+ the default values of &s.code;0xA0000&e.code; for
+ &s.code;MapPhys&e.code; and &s.code;(64&nbsp;*&nbsp;1024)&e.code; for
+ &s.code;MapSize&e.code;. This function must be called before
+ attempting to save or restore the VGA state. If the driver doesn't
+ call it explicitly, the &s.code;vgaHWSave()&e.code; and
+ &s.code;vgaHWRestore()&e.code; functions may call it if they need
+ to access the VGA memory (in which case they will also call
+ &s.code;vgaHWUnmapMem()&e.code; to unmap the VGA memory before
+ exiting).
+
+ </quote>
+
+ &s.code;void vgaHWUnmapMem(ScrnInfoPtr pScrn)&e.code;
+ <quote><p>
+ This function unmaps the VGA memory window. It must only be called
+ after the memory has been mapped. The &s.code;Base&e.code; field
+ of the &s.code;vgaHWRec&e.code; field is set to &s.code;NULL&e.code;
+ to indicate that the memory is no longer mapped.
+
+ </quote>
+
+ &s.code;void vgaHWGetIOBase(vgaHWPtr hwp)&e.code;
+ <quote><p>
+ This function initialises the &s.code;IOBase&e.code; field of the
+ &s.code;vgaHWRec&e.code;. This function must be called before
+ using any other functions that access the video hardware.
+
+ A macro &s.code;VGAHW_GET_IOBASE()&e.code; is also available in
+ &s.code;vgaHW.h&e.code; that returns the I/O base, and this may
+ be used when the vgahw module is not loaded (for example, in the
+ &s.code;ChipProbe()&e.code; function).
+
+ </quote>
+
+ &s.code;void vgaHWUnlock(vgaHWPtr hwp)&e.code;
+ <quote><p>
+ This function unlocks the VGA &s.code;CRTC[0-7]&e.code; registers,
+ and must be called before attempting to write to those registers.
+
+ A macro &s.code;VGAHW_UNLOCK(base)&e.code; is also available in
+ &s.code;vgaHW.h&e.code; that does the same thing, and this may be
+ used when the vgahw module is not loaded (for example, in the
+ &s.code;ChipProbe()&e.code; function).
+
+ </quote>
+
+ &s.code;void vgaHWLock(vgaHWPtr hwp)&e.code;
+ <quote><p>
+ This function locks the VGA &s.code;CRTC[0-7]&e.code; registers.
+
+ A macro &s.code;VGAHW_LOCK(base)&e.code; is also available in
+ &s.code;vgaHW.h&e.code; that does the same thing, and this may be
+ used when the vgahw module is not loaded (for example, in the
+ &s.code;ChipProbe()&e.code; function).
+
+ </quote>
+
+ &s.code;void vgaHWSave(ScrnInfoPtr pScrn, vgaRegPtr save, int flags)&e.code;
+ <quote><p>
+ This function saves the VGA state. The state is written to the
+ &s.code;vgaRegRec&e.code; pointed to by &s.code;save&e.code;.
+ &s.code;flags&e.code; is set to one or more of the following flags
+ ORed together:
+
+ &s.code;VGA_SR_MODE&e.code;
+ <quote>the mode setting registers are saved</quote>
+ &s.code;VGA_SR_FONTS&e.code;
+ <quote>the text mode font/text data is saved</quote>
+ &s.code;VGA_SR_CMAP&e.code;
+ <quote>the colourmap (LUT) is saved</quote>
+ &s.code;VGA_SR_ALL&e.code;
+ <quote>all of the above are saved</quote>
+
+ The &s.code;vgaHWRec&e.code; and its &s.code;IOBase&e.code; fields
+ must be initialised before this function is called. If
+ &s.code;VGA_SR_FONTS&e.code; is set in &s.code;flags&e.code;, the
+ VGA memory window must be mapped. If it isn't then
+ &s.code;vgaHWMapMem()&e.code; will be called to map it, and
+ &s.code;vgaHWUnmapMem()&e.code; will be called to unmap it
+ afterwards. &s.code;vgaHWSave()&e.code; uses the three functions
+ below in the order &s.code;vgaHWSaveColormap()&e.code;,
+ &s.code;vgaHWSaveMode()&e.code;, &s.code;vgaHWSaveFonts()&e.code; to
+ carry out the different save phases. It is undecided at this
+ stage whether they will be part of the vgahw module's public
+ interface or not.
+
+ </quote>
+
+ &s.code;void vgaHWSaveMode(ScrnInfoPtr pScrn, vgaRegPtr save)&e.code;
+ <quote><p>
+ This functions saves the VGA mode registers. They are saved to
+ the &s.code;vgaRegRec&e.code; pointed to by &s.code;save&e.code;.
+ The registers saved are:
+
+ <quote>
+ &s.code;MiscOut&nl;
+ CRTC[0-0x18]&nl;
+ Attribute[0-0x14]&nl;
+ Graphics[0-8]&nl;
+ Sequencer[0-4]&e.code;
+ </quote>
+
+ </quote>
+
+ &s.code;void vgaHWSaveFonts(ScrnInfoPtr pScrn, vgaRegPtr save)&e.code;
+ <quote><p>
+ This functions saves the text mode font and text data held in the
+ video memory. If called while in a graphics mode, no save is
+ done. The VGA memory window must be mapped with
+ &s.code;vgaHWMapMem()&e.code; before to calling this function.
+
+ On some platforms, one or more of the font/text plane saves may be
+ no-ops. This is the case when the platform's VC driver already
+ takes care of this.
+
+ </quote>
+
+ &s.code;void vgaHWSaveColormap(ScrnInfoPtr pScrn, vgaRegPtr save)&e.code;
+ <quote><p>
+ This function saves the VGA colourmap (LUT). Before saving it, it
+ attempts to verify that the colourmap is readable. In rare cases
+ where it isn't readable, a default colourmap is saved instead.
+
+ </quote>
+
+ &s.code;void vgaHWRestore(ScrnInfoPtr pScrn, vgaRegPtr restore, int flags)&e.code;
+ <quote><p>
+ This function programs the VGA state. The state programmed is
+ that contained in the &s.code;vgaRegRec&e.code; pointed to by
+ &s.code;restore&e.code;. &s.code;flags&e.code; is the same
+ as described above for the &s.code;vgaHWSave()&e.code; function.
+
+ The &s.code;vgaHWRec&e.code; and its &s.code;IOBase&e.code; fields
+ must be initialised before this function is called. If
+ &s.code;VGA_SR_FONTS&e.code; is set in &s.code;flags&e.code;, the
+ VGA memory window must be mapped. If it isn't then
+ &s.code;vgaHWMapMem()&e.code; will be called to map it, and
+ &s.code;vgaHWUnmapMem()&e.code; will be called to unmap it
+ afterwards. &s.code;vgaHWRestore()&e.code; uses the three functions
+ below in the order &s.code;vgaHWRestoreFonts()&e.code;,
+ &s.code;vgaHWRestoreMode()&e.code;,
+ &s.code;vgaHWRestoreColormap()&e.code; to carry out the different
+ restore phases. It is undecided at this stage whether they will
+ be part of the vgahw module's public interface or not.
+
+ </quote>
+
+ &s.code;void vgaHWRestoreMode(ScrnInfoPtr pScrn, vgaRegPtr restore)&e.code;
+ <quote><p>
+ This functions restores the VGA mode registers. They are restore
+ from the data in the &s.code;vgaRegRec&e.code; pointed to by
+ &s.code;restore&e.code;. The registers restored are:
+
+ <quote>
+ &s.code;MiscOut&nl;
+ CRTC[0-0x18]&nl;
+ Attribute[0-0x14]&nl;
+ Graphics[0-8]&nl;
+ Sequencer[0-4]&e.code;
+ </quote>
+
+ </quote>
+
+ &s.code;void vgaHWRestoreFonts(ScrnInfoPtr pScrn, vgaRegPtr restore)&e.code;
+ <quote><p>
+ This functions restores the text mode font and text data to the
+ video memory. The VGA memory window must be mapped with
+ &s.code;vgaHWMapMem()&e.code; before to calling this function.
+
+ On some platforms, one or more of the font/text plane restores
+ may be no-ops. This is the case when the platform's VC driver
+ already takes care of this.
+
+ </quote>
+
+ &s.code;void vgaHWRestoreColormap(ScrnInfoPtr pScrn, vgaRegPtr restore)&e.code;
+ <quote><p>
+ This function restores the VGA colourmap (LUT).
+
+ </quote>
+
+ &s.code;void vgaHWInit(ScrnInfoPtr pScrn, DisplayModePtr mode)&e.code;
+ <quote><p>
+ This function fills in the &s.code;vgaHWRec&e.code;'s
+ &s.code;ModeReg&e.code; field with the values appropriate for
+ programming the given video mode. It requires that the
+ &s.code;ScrnInfoRec&e.code;'s &s.code;depth&e.code; field is
+ initialised, which determines how the registers are programmed.
+
+ </quote>
+
+ &s.code;void vgaHWSeqReset(vgaHWPtr hwp, Bool start)&e.code;
+ <quote><p>
+ Do a VGA sequencer reset. If start is &s.code;TRUE&e.code;, the
+ reset is started. If start is &s.code;FALSE&e.code;, the reset
+ is ended.
+
+ </quote>
+
+ &s.code;void vgaHWProtect(ScrnInfoPtr pScrn, Bool on)&e.code;
+ <quote><p>
+ This function protects VGA registers and memory from corruption
+ during loads. It is typically called with on set to
+ &s.code;TRUE&e.code; before programming, and with on set to
+ &s.code;FALSE&e.code; after programming.
+
+ </quote>
+
+ &s.code;Bool vgaHWSaveScreen(ScreenPtr pScreen, Bool on)&e.code;
+ <quote><p>
+ This function blanks and unblanks the screen. It is blanked when
+ &s.code;on&e.code; is &s.code;FALSE&e.code;, and unblanked when
+ &s.code;on&e.code; is &s.code;TRUE&e.code;.
+
+ </quote>
+
+ &s.code;void vgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on)&e.code;
+ <quote><p>
+ This function blanks and unblanks the screen. It is blanked when
+ &s.code;on&e.code; is &s.code;FALSE&e.code;, and unblanked when
+ &s.code;on&e.code; is &s.code;TRUE&e.code;. This function is
+ provided for use in cases where the &s.code;ScrnInfoRec&e.code;
+ can't be derived from the &s.code;ScreenRec&e.code;, like probing
+ for clocks.
+
+ </quote>
+ </quote>
+
+<sect1>VGA Colormap Functions
+<p>
+
+ The vgahw modules uses the standard colormap support (see the
+ <ref id="cmap" name="Colormap Handling"> section. This is initialised
+ with the following function:
+
+ <quote>
+ &s.code;Bool vgaHWHandleColormaps(ScreenPtr pScreen)&e.code;
+ </quote>
+
+
+<sect1>VGA Register Access Functions
+<p>
+
+ The vgahw module abstracts access to the standard VGA registers by
+ using a set of functions held in the &s.code;vgaHWRec&e.code;. When
+ the &s.code;vgaHWRec&e.code; is created these function pointers are
+ initialised with the set of standard VGA I/O register access functions.
+ In addition to these, the vgahw module includes a basic set of MMIO
+ register access functions, and the &s.code;vgaHWRec&e.code; function
+ pointers can be initialised to these by calling the
+ &s.code;vgaHWSetMmioFuncs()&e.code; function described above. Some
+ drivers/platforms may require a different set of functions for VGA
+ access. The access functions are described here.
+
+
+ <quote><p>
+ &s.code;void writeCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)&e.code;
+ <quote><p>
+ Write &s.code;value&e.code; to CRTC register &s.code;index&e.code;.
+
+ </quote>
+
+ &s.code;CARD8 readCrtc(vgaHWPtr hwp, CARD8 index)&e.code;
+ <quote><p>
+ Return the value read from CRTC register &s.code;index&e.code;.
+
+ </quote>
+
+ &s.code;void writeGr(vgaHWPtr hwp, CARD8 index, CARD8 value)&e.code;
+ <quote><p>
+ Write &s.code;value&e.code; to Graphics Controller register
+ &s.code;index&e.code;.
+
+ </quote>
+
+ &s.code;CARD8 readGR(vgaHWPtr hwp, CARD8 index)&e.code;
+ <quote><p>
+ Return the value read from Graphics Controller register
+ &s.code;index&e.code;.
+
+ </quote>
+
+ &s.code;void writeSeq(vgaHWPtr hwp, CARD8 index, CARD8, value)&e.code;
+ <quote><p>
+ Write &s.code;value&e.code; to Sequencer register
+ &s.code;index&e.code;.
+
+ </quote>
+
+ &s.code;CARD8 readSeq(vgaHWPtr hwp, CARD8 index)&e.code;
+ <quote><p>
+ Return the value read from Sequencer register &s.code;index&e.code;.
+
+ </quote>
+
+ &s.code;void writeAttr(vgaHWPtr hwp, CARD8 index, CARD8, value)&e.code;
+ <quote><p>
+ Write &s.code;value&e.code; to Attribute Controller register
+ &s.code;index&e.code;. When writing out the index value this
+ function should set bit 5 (&s.code;0x20&e.code;) according to the
+ setting of &s.code;hwp-&gt;paletteEnabled&e.code; in order to
+ preserve the palette access state. It should be cleared when
+ &s.code;hwp-&gt;paletteEnabled&e.code; is &s.code;TRUE&e.code;
+ and set when it is &s.code;FALSE&e.code;.
+
+ </quote>
+
+ &s.code;CARD8 readAttr(vgaHWPtr hwp, CARD8 index)&e.code;
+ <quote><p>
+ Return the value read from Attribute Controller register
+ &s.code;index&e.code;. When writing out the index value this
+ function should set bit 5 (&s.code;0x20&e.code;) according to the
+ setting of &s.code;hwp-&gt;paletteEnabled&e.code; in order to
+ preserve the palette access state. It should be cleared when
+ &s.code;hwp-&gt;paletteEnabled&e.code; is &s.code;TRUE&e.code;
+ and set when it is &s.code;FALSE&e.code;.
+
+ </quote>
+
+ &s.code;void writeMiscOut(vgaHWPtr hwp, CARD8 value)&e.code;
+ <quote><p>
+ Write `&s.code;value&e.code;' to the Miscellaneous Output register.
+
+ </quote>
+
+ &s.code;CARD8 readMiscOut(vgwHWPtr hwp)&e.code;
+ <quote><p>
+ Return the value read from the Miscellaneous Output register.
+
+ </quote>
+
+ &s.code;void enablePalette(vgaHWPtr hwp)&e.code;
+ <quote><p>
+ Clear the palette address source bit in the Attribute Controller
+ index register and set &s.code;hwp-&gt;paletteEnabled&e.code; to
+ &s.code;TRUE&e.code;.
+
+ </quote>
+
+ &s.code;void disablePalette(vgaHWPtr hwp)&e.code;
+ <quote><p>
+ Set the palette address source bit in the Attribute Controller
+ index register and set &s.code;hwp-&gt;paletteEnabled&e.code; to
+ &s.code;FALSE&e.code;.
+
+ </quote>
+
+ &s.code;void writeDacMask(vgaHWPtr hwp, CARD8 value)&e.code;
+ <quote><p>
+ Write &s.code;value&e.code; to the DAC Mask register.
+
+ </quote>
+
+ &s.code;CARD8 readDacMask(vgaHWptr hwp)&e.code;
+ <quote><p>
+ Return the value read from the DAC Mask register.
+
+ </quote>
+
+ &s.code;void writeDacReadAddress(vgaHWPtr hwp, CARD8 value)&e.code;
+ <quote><p>
+ Write &s.code;value&e.code; to the DAC Read Address register.
+
+ </quote>
+
+ &s.code;void writeDacWriteAddress(vgaHWPtr hwp, CARD8 value)&e.code;
+ <quote><p>
+ Write &s.code;value&e.code; to the DAC Write Address register.
+
+ </quote>
+
+ &s.code;void writeDacData(vgaHWPtr hwp, CARD8 value)&e.code;
+ <quote><p>
+ Write &s.code;value&e.code; to the DAC Data register.
+
+ </quote>
+
+ &s.code;CARD8 readDacData(vgaHWptr hwp)&e.code;
+ <quote><p>
+ Return the value read from the DAC Data register.
+
+ </quote>
+ </quote>
+
+<sect>Some notes about writing a driver<label id="sample">
+<p>
+
+<em>NOTE: some parts of this are not up to date</em>
+
+The following is an outline for writing a basic unaccelerated driver
+for a PCI video card with a linear mapped framebuffer, and which has a
+VGA core. It is includes some general information that is relevant to
+most drivers (even those which don't fit that basic description).
+
+The information here is based on the initial conversion of the Matrox
+Millennium driver to the ``new design''. For a fleshing out and sample
+implementation of some of the bits outlined here, refer to that driver.
+Note that this is an example only. The approach used here will not be
+appropriate for all drivers.
+
+Each driver must reserve a unique driver name, and a string that is used
+to prefix all of its externally visible symbols. This is to avoid name
+space clashes when loading multiple drivers. The examples here are for
+the ``ZZZ'' driver, which uses the ``ZZZ'' or ``zzz'' prefix for its externally
+visible symbols.
+
+
+<sect1>Include files
+<p>
+
+ All drivers normally include the following headers:
+ <quote>
+ &s.code;"xf86.h"&nl;
+ "xf86_OSproc.h"&nl;
+ "xf86_ansic.h"&nl;
+ "xf86Resources.h"&e.code;
+ </quote>
+ Wherever inb/outb (and related things) are used the following should be
+ included:
+ <quote>
+ &s.code;"compiler.h"&e.code;
+ </quote>
+
+ Drivers that need to access PCI vendor/device definitions need this:
+ <quote>
+ &s.code;"xf86PciInfo.h"&e.code;
+ </quote>
+
+ Drivers that need to access the PCI config space need this:
+ <quote>
+ &s.code;"xf86Pci.h"&e.code;
+ </quote>
+
+ Drivers using the mi banking wrapper need:
+
+ <quote>
+ &s.code;"mibank.h"&e.code;
+ </quote>
+
+ Drivers that initialise a SW cursor need this:
+ <quote>
+ &s.code;"mipointer.h"&e.code;
+ </quote>
+
+ All drivers implementing backing store need this:
+ <quote>
+ &s.code;"mibstore.h"&e.code;
+ </quote>
+
+ All drivers using the mi colourmap code need this:
+ <quote>
+ &s.code;"micmap.h"&e.code;
+ </quote>
+
+ If a driver uses the vgahw module, it needs this:
+ <quote>
+ &s.code;"vgaHW.h"&e.code;
+ </quote>
+
+ Drivers supporting VGA or Hercules monochrome screens need:
+ <quote>
+ &s.code;"xf1bpp.h"&e.code;
+ </quote>
+
+ Drivers supporting VGA or EGC 16-colour screens need:
+ <quote>
+ &s.code;"xf4bpp.h"&e.code;
+ </quote>
+
+ Drivers using cfb need:
+ <quote>
+ &s.code;#define PSZ 8&nl;
+ #include "cfb.h"&nl;
+ #undef PSZ&e.code;
+ </quote>
+
+ Drivers supporting bpp 16, 24 or 32 with cfb need one or more of:
+ <quote>
+ &s.code;"cfb16.h"&nl;
+ "cfb24.h"&nl;
+ "cfb32.h"&e.code;
+ </quote>
+
+ The driver's own header file:
+ <quote>
+ &s.code;"zzz.h"&e.code;
+ </quote>
+
+ Drivers must NOT include the following:
+
+ <quote>
+ &s.code;"xf86Priv.h"&nl;
+ "xf86Privstr.h"&nl;
+ "xf86_libc.h"&nl;
+ "xf86_OSlib.h"&nl;
+ "Xos.h"&e.code;&nl;
+ any OS header
+ </quote>
+
+
+<sect1>Data structures and initialisation
+<p>
+
+<itemize>
+ <item>The following macros should be defined:
+ <code>
+#define VERSION <version-as-an-int>
+#define ZZZ_NAME "ZZZ" /* the name used to prefix messages */
+#define ZZZ_DRIVER_NAME "zzz" /* the driver name as used in config file */
+#define ZZZ_MAJOR_VERSION <int>
+#define ZZZ_MINOR_VERSION <int>
+#define ZZZ_PATCHLEVEL <int>
+ </code>
+<p>
+ XXX Probably want to remove one of these version.
+<p>
+ NOTE: &s.code;ZZZ_DRIVER_NAME&e.code; should match the name of the
+ driver module without things like the "lib" prefix, the "_drv" suffix
+ or filename extensions.
+<p>
+
+ <item>A DriverRec must be defined, which includes the functions required
+ at the pre-probe phase. The name of this DriverRec must be an
+ upper-case version of ZZZ_DRIVER_NAME (for the purposes of static
+ linking).
+<p>
+ <code>
+DriverRec ZZZ = {
+ VERSION,
+ "unaccelerated driver for ZZZ Zzzzzy cards",
+ ZZZIdentify,
+ ZZZProbe,
+ NULL,
+ 0
+};
+ </code>
+
+ <item>Define list of supported chips and their matching ID:
+<p>
+ <code>
+static SymTabRec ZZZChipsets[] = {
+ { PCI_CHIP_ZZZ1234, "zzz1234a" },
+ { PCI_CHIP_ZZZ5678, "zzz5678a" },
+ { -1, NULL }
+};
+ </code>
+<p>
+ The token field may be any integer value that the driver may use to
+ uniquely identify the supported chipsets. For drivers that support
+ only PCI devices using the PCI device IDs might be a natural choice,
+ but this isn't mandatory. For drivers that support both PCI and other
+ devices (like ISA), some other ID should probably used. When other
+ IDs are used as the tokens it is recommended that the names be
+ defined as an &s.code;enum&e.code; type.
+<p>
+ <item>If the driver uses the &s.code;xf86MatchPciInstances(&e.code;)
+ helper (recommended for drivers that support PCI cards) a list that
+ maps PCI IDs to chip IDs and fixed resources must be defined:
+<p>
+ <code>
+static PciChipsets ZZZPciChipsets[] = {
+ { PCI_CHIP_ZZZ1234, PCI_CHIP_ZZZ1234, RES_SHARED_VGA },
+ { PCI_CHIP_ZZZ5678, PCI_CHIP_ZZZ5678, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED }
+}
+ </code>
+<p>
+ <item>Define the &s.code;XF86ModuleVersionInfo&e.code; struct for the
+ driver. This is required for the dynamically loaded version:
+<p>
+ <code>
+#ifdef XFree86LOADER
+static XF86ModuleVersionInfo zzzVersRec =
+{
+ "zzz",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ ZZZ_MAJOR_VERSION, ZZZ_MINOR_VERSION, ZZZ_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+#endif
+ </code>
+<p>
+ <item>Define a data structure to hold the driver's screen-specific data.
+ This must be used instead of global variables. This would be defined
+ in the &s.code;"zzz.h"&e.code; file, something like:
+<p>
+ <code>
+typedef struct {
+ type1 field1;
+ type2 field2;
+ int fooHack;
+ Bool pciRetry;
+ Bool noAccel;
+ Bool hwCursor;
+ CloseScreenProcPtr CloseScreen;
+ ...
+} ZZZRec, *ZZZPtr;
+ </code>
+<p>
+ <item>Define the list of config file Options that the driver accepts. For
+ consistency between drivers those in the list of ``standard'' options
+ should be used where appropriate before inventing new options.
+<p>
+ <code>
+typedef enum {
+ OPTION_FOO_HACK,
+ OPTION_PCI_RETRY,
+ OPTION_HW_CURSOR,
+ OPTION_NOACCEL
+} ZZZOpts;
+
+static OptionInfoRec ZZZOptions[] = {
+ { OPTION_FOO_HACK, "FooHack", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+ </code>
+<p>
+</itemize>
+
+<sect1>Functions
+<p>
+
+
+<sect2>SetupProc
+<p>
+
+ For dynamically loaded modules, a &s.code;ModuleData&e.code;
+ variable is required. It is should be the name of the driver
+ prepended to "ModuleData". A &s.code;Setup()&e.code; function is
+ also required, which calls &s.code;xf86AddDriver()&e.code; to add
+ the driver to the main list of drivers.
+
+ <code>
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(mgaSetup);
+
+XF86ModuleData zzzModuleData = { &amp;zzzVersRec, zzzSetup, NULL };
+
+static pointer
+zzzSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ /* This module should be loaded only once, but check to be sure. */
+
+ if (!setupDone) {
+ /*
+ * Modules that this driver always requires may be loaded
+ * here by calling LoadSubModule().
+ */
+
+ setupDone = TRUE;
+ xf86AddDriver(&amp;MGA, module, 0);
+
+ /*
+ * The return value must be non-NULL on success even though
+ * there is no TearDownProc.
+ */
+ return (pointer)1;
+ } else {
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+#endif
+ </code>
+
+<sect2>GetRec, FreeRec
+<p>
+
+ A function is usually required to allocate the driver's
+ screen-specific data structure and hook it into the
+ &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; field.
+ The &s.code;ScrnInfoRec&e.code;'s &s.code;driverPrivate&e.code; is
+ initialised to &s.code;NULL&e.code;, so it is easy to check if the
+ initialisation has already been done. After allocating it, initialise
+ the fields. By using &s.code;xnfcalloc()&e.code; to do the allocation
+ it is zeroed, and if the allocation fails the server exits.
+
+ <code>
+static Bool
+ZZZGetRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+ pScrn->driverPrivate = xnfcalloc(sizeof(ZZZRec), 1);
+ /* Initialise as required */
+ ...
+ return TRUE;
+}
+ </code>
+
+ Define a macro in &s.code;"zzz.h"&e.code; which gets a pointer to
+ the &s.code;ZZZRec&e.code; when given &s.code;pScrn&e.code;:
+
+ <code>
+#define ZZZPTR(p) ((ZZZPtr)((p)->driverPrivate))
+ </code>
+
+ Define a function to free the above, setting it to &s.code;NULL&e.code;
+ once it has been freed:
+
+ <code>
+static void
+ZZZFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+ </code>
+
+<sect2>Identify
+<p>
+
+ Define the &s.code;Identify()&e.code; function. It is run before
+ the Probe, and typically prints out an identifying message, which
+ might include the chipsets it supports. This function is mandatory:
+
+ <code>
+static void
+ZZZIdentify(int flags)
+{
+ xf86PrintChipsets(ZZZ_NAME, "driver for ZZZ Tech chipsets",
+ ZZZChipsets);
+}
+ </code>
+
+<sect2>Probe
+<p>
+
+ Define the &s.code;Probe()&e.code; function. The purpose of this
+ is to find all instances of the hardware that the driver supports,
+ and for the ones not already claimed by another driver, claim the
+ slot, and allocate a &s.code;ScrnInfoRec&e.code;. This should be
+ a minimal probe, and it should under no circumstances leave the
+ state of the hardware changed. Because a device is found, don't
+ assume that it will be used. Don't do any initialisations other
+ than the required &s.code;ScrnInfoRec&e.code; initialisations.
+ Don't allocate any new data structures.
+
+ This function is mandatory.
+
+ NOTE: The &s.code;xf86DrvMsg()&e.code; functions cannot be used from
+ the Probe.
+
+ <code>
+static Bool
+ZZZProbe(DriverPtr drv, int flags)
+{
+ Bool foundScreen = FALSE;
+ int numDevSections, numUsed;
+ GDevPtr *devSections;
+ int *usedChips;
+ int i;
+
+ /*
+ * Find the config file Device sections that match this
+ * driver, and return if there are none.
+ */
+ if ((numDevSections = xf86MatchDevice(ZZZ_DRIVER_NAME,
+ &amp;devSections)) <= 0) {
+ return FALSE;
+ }
+
+ /*
+ * Since this is a PCI card, "probing" just amounts to checking
+ * the PCI data that the server has already collected. If there
+ * is none, return.
+ *
+ * Although the config file is allowed to override things, it
+ * is reasonable to not allow it to override the detection
+ * of no PCI video cards.
+ *
+ * The provided xf86MatchPciInstances() helper takes care of
+ * the details.
+ */
+ /* test if PCI bus present */
+ if (xf86GetPciVideoInfo()) {
+
+ numUsed = xf86MatchPciInstances(ZZZ_NAME, PCI_VENDOR_ZZZ,
+ ZZZChipsets, ZZZPciChipsets, devSections,
+ numDevSections, drv, &amp;usedChips);
+
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn;
+
+ /* Allocate a ScrnInfoRec */
+ pScrn = xf86AllocateScreen(drv, 0);
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = ZZZ_DRIVER_NAME;
+ pScrn->name = ZZZ_NAME;
+ pScrn->Probe = ZZZProbe;
+ pScrn->PreInit = ZZZPreInit;
+ pScrn->ScreenInit = ZZZScreenInit;
+ pScrn->SwitchMode = ZZZSwitchMode;
+ pScrn->AdjustFrame = ZZZAdjustFrame;
+ pScrn->EnterVT = ZZZEnterVT;
+ pScrn->LeaveVT = ZZZLeaveVT;
+ pScrn->FreeScreen = ZZZFreeScreen;
+ pScrn->ValidMode = ZZZValidMode;
+ foundScreen = TRUE;
+ /* add screen to entity */
+ xf86ConfigActivePciEntity(pScrn, usedChips[i],
+ ZZZPciChipsets, NULL, NULL, NULL, NULL, NULL);
+
+ }
+ if (numUsed > 0)
+ xfree(usedChips);
+ }
+
+#ifdef HAS_ISA_DEVS
+ /*
+ * If the driver supports ISA hardware, the following block
+ * can be included too.
+ */
+ numUsed = xf86MatchIsaInstances(ZZZ_NAME, ZZZChipsets,
+ ZZZIsaChipsets, drv, ZZZFindIsaDevice,
+ devSections, numDevSections, &amp;usedChips);
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = xf86AllocateScreen(drv,0);
+
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = ZZZ_DRIVER_NAME;
+ pScrn->name = ZZZ_NAME;
+ pScrn->Probe = ZZZProbe;
+ pScrn->PreInit = ZZZPreInit;
+ pScrn->ScreenInit = ZZZScreenInit;
+ pScrn->SwitchMode = ZZZSwitchMode;
+ pScrn->AdjustFrame = ZZZAdjustFrame;
+ pScrn->EnterVT = ZZZEnterVT;
+ pScrn->LeaveVT = ZZZLeaveVT;
+ pScrn->FreeScreen = ZZZFreeScreen;
+ pScrn->ValidMode = ZZZValidMode;
+ foundScreen = TRUE;
+ xf86ConfigActiveIsaEntity(pScrn, usedChips[i], ZZZIsaChipsets,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+ if (numUsed > 0)
+ xfree(usedChips);
+#endif /* HAS_ISA_DEVS */
+
+ xfree(devSections);
+ return foundScreen;
+ </code>
+
+<sect2>PreInit
+<p>
+
+ Define the &s.code;PreInit()&e.code; function. The purpose of
+ this is to find all the information required to determine if the
+ configuration is usable, and to initialise those parts of the
+ &s.code;ScrnInfoRec&e.code; that can be set once at the beginning
+ of the first server generation. The information should be found in
+ the least intrusive way possible.
+
+ This function is mandatory.
+
+ NOTES:
+ <enum>
+ <item>The &s.code;PreInit()&e.code; function is only called once
+ during the life of the X server (at the start of the first
+ generation).
+
+ <item>Data allocated here must be of the type that persists for
+ the life of the X server. This means that data that hooks into
+ the &s.code;ScrnInfoRec&e.code;'s &s.code;privates&e.code;
+ field should be allocated here, but data that hooks into the
+ &s.code;ScreenRec&e.code;'s &s.code;devPrivates&e.code; field
+ should not be allocated here. The &s.code;driverPrivate&e.code;
+ field should also be allocated here.
+
+ <item>Although the &s.code;ScrnInfoRec&e.code; has been allocated
+ before this function is called, the &s.code;ScreenRec&e.code;
+ has not been allocated. That means that things requiring it
+ cannot be used in this function.
+
+ <item>Very little of the &s.code;ScrnInfoRec&e.code; has been
+ initialised when this function is called. It is important to
+ get the order of doing things right in this function.
+
+ </enum>
+
+ <code>
+static Bool
+ZZZPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ /* Fill in the monitor field */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*
+ * If using the vgahw module, it will typically be loaded
+ * here by calling xf86LoadSubModule(pScrn, "vgahw");
+ */
+
+ /*
+ * Set the depth/bpp. Our preferred default depth/bpp is 8, and
+ * we support both 24bpp and 32bpp framebuffer layouts.
+ * This sets pScrn->display also.
+ */
+ if (!xf86SetDepthBpp(pScrn, 8, 8, 8,
+ Support24bppFb | Support32bppFb)) {
+ return FALSE;
+ } else {
+ if (depth/bpp isn't one we support) {
+ print error message;
+ return FALSE;
+ }
+ }
+ /* Print out the depth/bpp that was set */
+ xf86PrintDepthBpp(pScrn);
+
+ /* Set bits per RGB for 8bpp */
+ if (pScrn->depth <= 8) {
+ /* Take into account a dac_6_bit option here */
+ pScrn->rgbBits = 6 or 8;
+ }
+
+ /*
+ * xf86SetWeight() and xf86SetDefaultVisual() must be called
+ * after pScrn->display is initialised.
+ */
+
+ /* Set weight/mask/offset for depth > 8 */
+ if (pScrn->depth > 8) {
+ if (!xf86SetWeight(pScrn, defaultWeight, defaultMask)) {
+ return FALSE;
+ } else {
+ if (weight isn't one we support) {
+ print error message;
+ return FALSE;
+ }
+ }
+ }
+
+ /* Set the default visual. */
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ if (visual isn't one we support) {
+ print error message;
+ return FALSE;
+ }
+ }
+
+ /* If the driver supports gamma correction, set the gamma. */
+ if (!xf86SetGamma(pScrn, default_gamma)) {
+ return FALSE;
+ }
+
+ /* This driver uses a programmable clock */
+ pScrn->progClock = TRUE;
+
+ /* Allocate the ZZZRec driverPrivate */
+ if (!ZZZGetRec(pScrn)) {
+ return FALSE;
+ }
+
+ pZzz = ZZZPTR(pScrn);
+
+ /* Collect all of the option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /*
+ * Process the options based on the information in ZZZOptions.
+ * The results are written to ZZZOptions.
+ */
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ZZZOptions);
+
+ /*
+ * Set various fields of ScrnInfoRec and/or ZZZRec based on
+ * the options found.
+ */
+ from = X_DEFAULT;
+ pZzz->hwCursor = FALSE;
+ if (xf86IsOptionSet(ZZZOptions, OPTION_HW_CURSOR)) {
+ from = X_CONFIG;
+ pZzz->hwCursor = TRUE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pZzz->hwCursor ? "HW" : "SW");
+ if (xf86IsOptionSet(ZZZOptions, OPTION_NOACCEL)) {
+ pZzz->noAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Acceleration disabled\n");
+ } else {
+ pZzz->noAccel = FALSE;
+ }
+ if (xf86IsOptionSet(ZZZOptions, OPTION_PCI_RETRY)) {
+ pZzz->UsePCIRetry = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
+ }
+ pZzz->fooHack = 0;
+ if (xf86GetOptValInteger(ZZZOptions, OPTION_FOO_HACK,
+ &amp;pZzz->fooHack)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Foo Hack set to %d\n",
+ pZzz->fooHack);
+ }
+
+ /*
+ * Find the PCI slot(s) that this screen claimed in the probe.
+ * In this case, exactly one is expected, so complain otherwise.
+ * Note in this case we're not interested in the card types so
+ * that parameter is set to NULL.
+ */
+ if ((i = xf86GetPciInfoForScreen(pScrn->scrnIndex, &amp;pciList, NULL))
+ != 1) {
+ print error message;
+ ZZZFreeRec(pScrn);
+ if (i > 0)
+ xfree(pciList);
+ return FALSE;
+ }
+ /* Note that pciList should be freed below when no longer needed */
+
+ /*
+ * Determine the chipset, allowing config file chipset and
+ * chipid values to override the probed information. The config
+ * chipset value has precedence over its chipid value if both
+ * are present.
+ *
+ * It isn't necessary to fill in pScrn->chipset if the driver
+ * keeps track of the chipset in its ZZZRec.
+ */
+
+ ...
+
+ /*
+ * Determine video memory, fb base address, I/O addresses, etc,
+ * allowing the config file to override probed values.
+ *
+ * Set the appropriate pScrn fields (videoRam is probably the
+ * most important one that other code might require), and
+ * print out the settings.
+ */
+
+ ...
+
+ /* Initialise a clockRanges list. */
+
+ ...
+
+ /* Set any other chipset specific things in the ZZZRec */
+
+ ...
+
+ /* Select valid modes from those available */
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, minPitch, maxPitch, rounding,
+ minHeight, maxHeight,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pScrn->videoRam * 1024,
+ LOOKUP_BEST_REFRESH);
+ if (i == -1) {
+ ZZZFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Prune the modes marked as invalid */
+
+ xf86PruneDriverModes(pScrn);
+
+ /* If no valid modes, return */
+
+ if (i == 0 || pScrn->modes == NULL) {
+ print error message;
+ ZZZFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /*
+ * Initialise the CRTC fields for the modes. This driver expects
+ * vertical values to be halved for interlaced modes.
+ */
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list. */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used. */
+ xf86PrintModes(pScrn);
+
+ /* Set the DPI */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ mod = "xf1bpp";
+ break;
+ case 4:
+ mod = "xf4bpp";
+ break;
+ case 8:
+ mod = "cfb";
+ break;
+ case 16:
+ mod = "cfb16";
+ break;
+ case 24:
+ mod = "cfb24";
+ break;
+ case 32:
+ mod = "cfb32";
+ break;
+ }
+ if (mod && !xf86LoadSubModule(pScrn, mod))
+ ZZZFreeRec(pScrn);
+ return FALSE;
+
+ /* Load XAA if needed */
+ if (!pZzz->noAccel || pZzz->hwCursor)
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ ZZZFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Done */
+ return TRUE;
+}
+ </code>
+
+<sect2>MapMem, UnmapMem
+<p>
+
+ Define functions to map and unmap the video memory and any other
+ memory apertures required. These functions are not mandatory, but
+ it is often useful to have such functions.
+
+ <code>
+static Bool
+ZZZMapMem(ScrnInfoPtr pScrn)
+{
+ /* Call xf86MapPciMem() to map each PCI memory area */
+ ...
+ return TRUE or FALSE;
+}
+
+static Bool
+ZZZUnmapMem(ScrnInfoPtr pScrn)
+{
+ /* Call xf86UnMapVidMem() to unmap each memory area */
+ ...
+ return TRUE or FALSE;
+}
+ </code>
+
+<sect2>Save, Restore
+<p>
+
+ Define functions to save and restore the original video state. These
+ functions are not mandatory, but are often useful.
+
+ <code>
+static void
+ZZZSave(ScrnInfoPtr pScrn)
+{
+ /*
+ * Save state into per-screen data structures.
+ * If using the vgahw module, vgaHWSave will typically be
+ * called here.
+ */
+ ...
+}
+
+static void
+ZZZRestore(ScrnInfoPtr pScrn)
+{
+ /*
+ * Restore state from per-screen data structures.
+ * If using the vgahw module, vgaHWRestore will typically be
+ * called here.
+ */
+ ...
+}
+ </code>
+
+<sect2>ModeInit
+<p>
+
+ Define a function to initialise a new video mode. This function isn't
+ mandatory, but is often useful.
+
+ <code>
+static Bool
+ZZZModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ /*
+ * Program a video mode. If using the vgahw module,
+ * vgaHWInit and vgaRestore will typically be called here.
+ * Once up to the point where there can't be a failure
+ * set pScrn->vtSema to TRUE.
+ */
+ ...
+}
+ </code>
+
+<sect2>ScreenInit
+<p>
+
+ Define the &s.code;ScreenInit()&e.code; function. This is called
+ at the start of each server generation, and should fill in as much
+ of the &s.code;ScreenRec&e.code; as possible as well as any other
+ data that is initialised once per generation. It should initialise
+ the framebuffer layers it is using, and initialise the initial video
+ mode.
+
+ This function is mandatory.
+
+ NOTE: The &s.code;ScreenRec&e.code; (&s.code;pScreen&e.code;) is
+ passed to this driver, but it and the
+ &s.code;ScrnInfoRecs&e.code; are not yet hooked into each
+ other. This means that in this function, and functions it
+ calls, one cannot be found from the other.
+
+ <code>
+static Bool
+ZZZScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ /* Get the ScrnInfoRec */
+ pScrn = xf86Screens[pScreen->myNum];
+
+ /*
+ * If using the vgahw module, its data structures and related
+ * things are typically initialised/mapped here.
+ */
+
+ /* Save the current video state */
+ ZZZSave(pScrn);
+
+ /* Initialise the first mode */
+ ZZZModeInit(pScrn, pScrn->currentMode);
+
+ /* Set the viewport if supported */
+
+ ZZZAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /*
+ * Setup the screen's visuals, and initialise the framebuffer
+ * code.
+ */
+
+ /* Reset the visual list */
+ miClearVisualTypes();
+
+ /*
+ * Setup the visuals supported. This driver only supports
+ * TrueColor for bpp > 8, so the default set of visuals isn't
+ * acceptable. To deal with this, call miSetVisualTypes with
+ * the appropriate visual mask.
+ */
+
+ if (pScrn->bitsPerPixel > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+ /*
+ * Initialise the framebuffer.
+ */
+
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ ret = xf1bppScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 4:
+ ret = xf4bppScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 8:
+ ret = cfbScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 16:
+ ret = cfb16ScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 24:
+ ret = cfb24ScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 32:
+ ret = cfb32ScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ default:
+ print a message about an internal error;
+ ret = FALSE;
+ break;
+ }
+
+ if (!ret)
+ return FALSE;
+
+ /* Override the default mask/offset settings */
+ if (pScrn->bitsPerPixel > 8) {
+ for (i = 0, visual = pScreen->visuals;
+ i < pScreen->numVisuals; i++, visual++) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ /*
+ * If banking is needed, initialise an miBankInfoRec (defined in
+ * "mibank.h"), and call miInitializeBanking().
+ */
+ if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
+ pScrn->displayWidth, pBankInfo))
+ return FALSE;
+
+ /*
+ * If backing store is to be supported (as is usually the case),
+ * initialise it.
+ */
+ miInitializeBackingStore(pScreen);
+
+ /*
+ * Set initial black & white colourmap indices.
+ */
+ xf86SetBlackWhitePixels(pScreen);
+
+ /*
+ * Install colourmap functions. If using the vgahw module,
+ * vgaHandleColormaps would usually be called here.
+ */
+
+ ...
+
+ /*
+ * Initialise cursor functions. This example is for the mi
+ * software cursor.
+ */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ /* Initialise the default colourmap */
+ switch (pScrn->depth) {
+ case 1:
+ if (!xf1bppCreateDefColormap(pScreen))
+ return FALSE;
+ break;
+ case 4:
+ if (!xf4bppCreateDefColormap(pScreen))
+ return FALSE;
+ break;
+ default:
+ if (!cfbCreateDefColormap(pScreen))
+ return FALSE;
+ break;
+ }
+
+ /*
+ * Wrap the CloseScreen vector and set SaveScreen.
+ */
+ ZZZPTR(pScrn)->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = ZZZCloseScreen;
+ pScreen->SaveScreen = ZZZSaveScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ /* Done */
+ return TRUE;
+}
+ </code>
+
+
+<sect2>SwitchMode
+<p>
+
+ Define the &s.code;SwitchMode()&e.code; function if mode switching
+ is supported by the driver.
+
+ <code>
+static Bool
+ZZZSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return ZZZModeInit(xf86Screens[scrnIndex], mode);
+}
+ </code>
+
+
+<sect2>AdjustFrame
+<p>
+
+ Define the &s.code;AdjustFrame()&e.code; function if the driver
+ supports this.
+
+ <code>
+static void
+ZZZAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ /* Adjust the viewport */
+}
+ </code>
+
+
+<sect2>EnterVT, LeaveVT
+<p>
+
+ Define the &s.code;EnterVT()&e.code; and &s.code;LeaveVT()&e.code;
+ functions.
+
+ These functions are mandatory.
+
+ <code>
+static Bool
+ZZZEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ return ZZZModeInit(pScrn, pScrn->currentMode);
+}
+
+static void
+ZZZLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ ZZZRestore(pScrn);
+}
+ </code>
+
+<sect2>CloseScreen
+<p>
+
+ Define the &s.code;CloseScreen()&e.code; function:
+
+ This function is mandatory. Note that it unwraps the previously
+ wrapped &s.code;pScreen-&gt;CloseScreen&e.code;, and finishes by
+ calling it.
+
+ <code>
+static Bool
+ZZZCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ ZZZRestore(pScrn);
+ ZZZUnmapMem(pScrn);
+ pScrn->vtSema = FALSE;
+ pScreen->CloseScreen = ZZZPTR(pScrn)->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+ </code>
+
+<sect2>SaveScreen
+<p>
+
+ Define the &s.code;SaveScreen()&e.code; function (the screen
+ blanking function). When using the vgahw module, this will typically
+ be:
+
+This function is mandatory.
+
+ <code>
+static Bool
+ZZZSaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+ return vgaHWSaveScreen(pScreen, unblank);
+}
+ </code>
+
+<sect2>FreeScreen
+<p>
+
+ Define the &s.code;FreeScreen()&e.code; function. This function
+ is optional. It should be defined if the &s.code;ScrnInfoRec&e.code;
+ &s.code;driverPrivate&e.code; field is used so that it can be freed
+ when a screen is deleted by the common layer for reasons possibly
+ beyond the driver's control. This function is not used in during
+ normal (error free) operation. The per-generation data is freed by
+ the &s.code;CloseScreen()&e.code; function.
+
+ <code>
+static void
+ZZZFreeScreen(int scrnIndex, int flags)
+{
+ /*
+ * If the vgahw module is used vgaHWFreeHWRec() would be called
+ * here.
+ */
+ ZZZFreeRec(xf86Screens[scrnIndex]);
+}
+ </code>
+
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/DGux.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/DGux.sgml
new file mode 100644
index 000000000..355fc87aa
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/DGux.sgml
@@ -0,0 +1,789 @@
+
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+
+<title>Instructions for Building XFree86 on an Intel Pentium Aviion machine with DG/ux R4.20MU04
+<author>Takis Psarogiannakopoulos
+<date>July 27, 1999
+<toc>
+
+<sect>Whats new <p>
+
+July 27, 1999<p>
+ DG has fix the streams bug in /usr/lib/tcpip.so . (Read below)
+ The workaround in the July 25 source code has been removed.
+ I've been told from DG that BSD sockets perform better in DGUX
+ than SVR4 native STREAMS. From R4.20MU06 DG/ux will have the correct
+ tcpip.so lib (no bug in STREAMS). If you have MU05,MU04 and you
+ want for some reason STREAMS definitely contact DG for an updated
+ /usr/lib/tcpip.so in /usr/lib (patch for your MU04,5).
+<p>
+ DG/ux at the moment lacks the sysi86 syscall and the definition
+ of SYSI86IOPL (that is in &lt;sys/sysi86.h&gt; but guarded by a
+ UNIXWARE defintion that of course cannot be applicable to DG/ux).
+ Until this header is accessible by a simple -DDGUX , and _sysi86,
+ sysi86 subroutines added to libc (or some other extra library)
+ we need to define the DG_NO_SYSI86 to be 1. If DG makes the above
+ modifications , you will need to manually edit the files (before
+ building!)
+ xc/programs/Xserver/hw/xfree86/SuperProbe/OS_DGUX.c
+ xc/programs/Xserver/hw/xfree86/etc/scanpci.c
+ xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_video.c
+ and eliminate DG_NO_SYSI86 flag by changing DG_NO_SYSI86 1-->0.
+<p>
+July 25, 1999<p>
+ A major bug has now been corrected in this release. According to this
+ since the STREAMS interface of DG/ux were broken the server was
+ listening not to port 6000 (= 0x1770) but to 0x7017.
+ All binaries that you have from 3.3.3.1, 3.3.3 they will work
+ locally (if you run them in the same machine) but NOT remotely
+ because they use an Xlib that tries to connect to port 28365.
+ If you want to run them remotely YOU MUST recompile them!
+ Steve thank you for bringing this to my attention initially but
+ was too busy then to look at it in detail... Perhaps I should
+ have...
+<p>
+ We now use sockets instead of ioctls.
+ But I've fix and tested the STREAMS also.
+<p>
+ David thanks for making me realize that this was indeed a problem
+ in DG/ux.
+<p>
+ I 've also take the trouble to port gdb-4.17/8 and ddd (X inter)
+ in pub/XFree86/3.3.5/binaries/DGUX-ix86/GDB_BETA (both binaries
+ and source code) in order to be able to send me traces of core
+ files produced by Xservers. Try
+<verb>
+ gdb /usr/X11R6/bin/X location of core/core
+ gdb: where
+</verb>
+ and send me what you see.
+ (I suppose that the Xserver executable is in /usr/X11R6.3/bin)
+<p>
+ From 3.3.3.1:
+ Several bugs are now fixed. DG/ux support is on this official
+ patch. All configuration is in xc/config/cf/DGUX.cf and in
+ xf86site.def. Also Imake autodetects (thanks to David Dawes)
+ the DGUX OS (including Release version). So only a simple
+ "make World" is needed anymore to build in ix86 DG/ux.
+ Usually the process to build is (after unpacking and patching
+ the source "xc" tree) to go to xc/config/cf copy the file
+ xf86site.def to site.def and edit the files DGUX.cf ,site.def
+ for whatever changes you need to do.
+<p>
+ Default ProjectRoot in 3.3.5 is /usr/X11R6 (except if you
+ set this specifically in DGUX.cf either as /usr/X11R6.3--
+ --my choice, or in whatever you like).
+<p>
+ From:
+ December 1, 1998
+ IMPORTANT: PLEASE READ THE FILE README-GCC-2.8.1
+ GCC VERSION 2.8.1 is recommended for the DGUX build of X11R6.3
+ You can ignore below the _old_ conversation about gcc compiler
+ if you already run a gcc-2.8.1 in your machine.
+
+<sect> GENERAL: <p>
+
+ Get from ftp.xfree86.org the XFree 3.3.x source code:
+<verb>
+ ftp ftp.xfree86.org
+ login: ftp
+ passwd: your e-mail address
+ cd pub/XFree86/3.3.5/source
+ You need the files:
+ X335src-1.tgz
+ X335src-2.tgz
+ X335src-3.tgz
+</verb>
+<p>
+ Get also the contributed X software
+<verb>
+ cd /pub/XFree86/3.3.5/source
+ X335contrib.tgz
+</verb>
+<p>
+ If you have the source tarballs of 3.3.3 go to
+ /pub/XFree86/3.3.5/binaries/DGUX-ix86/SOURCE get the DGUX source
+ patch
+<p>
+<verb>
+ 3.3.3-3.3.5-DGUX.diff.gz
+ X335contrib-DGUX.diff.gz (patch for the contrib software).
+</verb>
+<p>
+ to avoid downloading all the source code again.
+<p>
+ Sorry some DGUX changes they didn't make in time for the official
+ release date of 3.3.4...
+ I do this for free, so some times I may be excused for something
+ like this...
+<p>
+ To build X11R6.3 you need also the tools for DG/ux (see discussion
+ below). They will be in
+ ftp dpmms.cam.ac.uk
+ (University of Cambridge,Department of Pure Mathematics)
+ in /pub/takis/DGUX-Tools/BuildXtools.tar.gz (anonymous ftp)
+ or in the ftp.xfree86.org ...
+ (pub/XFree86/3.3.5/binaries/DGUX-ix86/SOURCE/BUILD-TOOLS/
+ BuildXtools.tar.gz).
+<p>
+ Using a big filesystem (I use a virtual disk "xf86work" mounted on
+ /xf86work of size 1400000 blocks) copy the source as:
+<p>
+<verb>
+ cp X335src-1.tgz /xf86work/X335src-1.tar.gz
+ cp X335src-2.tgz /xf86work/X335src-2.tar.gz
+ cp X335src-3.tgz /xf86work/X335src-3.tar.gz
+</verb>
+<p>
+ (or X333src-1,2,3.tar.gz as above plus the DG/ux patch to 3.3.5
+ i.e. the file 3.3.3-3.3.5-DGUX.diff.gz)
+<p>
+ And maybe the contributed software:
+<verb>
+ cp X335contrib.tgz /xf86work
+
+ (cp X335contrib-DGUX.diff.gz /xf86work).
+</verb>
+<p>
+ If you get the patches from DGUX-ix86, to build from source 3.3.3
+ your first problem is that in order to apply the source patch you
+ need "patch" a very common GNU program that DG/ux doesn't have!?
+ This program is in BuildXtools.tar.gz
+ (or ftp prep.ai.mit.edu cd/pub/gnu get patch-2.5.tar.gz)
+ So lets speak about these tools before anything else:
+ Using "sysadm" mount a filesystem usr_local under /usr/local with
+ size 200000 blocks. Then copy the BuildXtools file in /usr and give:
+<verb>
+ gzip -d < BuildXtools.tar.gz | tar xvf -
+</verb>
+<p>
+ It will unfold in the new filesystem /usr/local.
+ Then go to your ".profile" (in your Home dir , mine eg is /admin)
+ and add the /usr/local/bin in your path and the /usr/local/lib in
+ your lib-path.
+<p>
+ What you need is like that:
+ (vi .profile)
+<p>
+<verb>
+ PATH=/usr/local/bin:/sbin:/usr/sbin:/usr/bin
+ if [ -d /usr/opt/X11/bin ]
+ then
+ PATH=$PATH:/usr/opt/X11/bin
+ fi
+ export PATH
+ (/usr/local/bin is before any other path!)
+
+ LD_LIBRARY_PATH=/usr/local/lib:/usr/lib:/usr/ccs/lib
+ export LD_LIBRARY_PATH
+</verb>
+<p>
+ then exit and re-login so that your new modified .profile will take effect.
+<p>
+ Now do the following:
+<verb>
+ cd /usr/sbin
+ cp install install_dg
+ rm install
+ cp /usr/local/bin
+ cp install /usr/bin *(make the GNU install the default install)*
+ (DG/ux install is useless)
+ (Look also the file xc/config/cf/DGUX.cf , below).
+
+ (Or get GNU make-3.77 and copy install.sh (or -sh) to a /usr/bin/install)
+
+ cd /usr/bin
+ cp true /usr/local/bin
+ cd /usr/local/bin
+ ln -s true ranlib (Install true as ranlib in the DG/ux system)
+</verb>
+ Usually giving -v,-V or --version will give you build info on all
+ the tools in /usr/local/bin (try it).
+<p>
+ **Look the discussion for gcc before you build (below)**
+<p>
+ Now untar the source tree:
+ In /xf86work (or whatever name you gave to the big filesystem for the build)
+<verb>
+ gzip -d < X335src-1.tar.gz | tar xvf -
+ gzip -d < X335src-2.tar.gz | tar xvf -
+ gzip -d < X335src-3.tar.gz | tar xvf -
+</verb>
+
+ (If you have X-3.3.3 do the same for the 3.3.3 sources and
+ then apply the 3.3.5-DGUX source patch
+
+<verb>
+ gzip -d < 3.3.3-3.3.5-DGUX.diff.gz | patch -p0 -E).
+</verb>
+
+ The directory xc in now present in your build filesystem.
+
+
+<sect> Configuration for the build:<p>
+ Almost all you need is in "DGUX.cf" located in xc/config/cf.
+ Edit the file DGUX.cf and site.def and change what ever you need.
+ Remember DGUX.cf overwrites site.def.
+ The default ProjectRoot for XFree86-3.3.5 is now /usr/X11R6
+ (located in site.def). If you want to change this to whatever
+ you like (I prefer /usr/X11R6.3 and a link in /usr X11R6->X11R6.3)
+ edit DGUX.cf and locate the entry:
+<p>
+<verb>
+ #if 0
+ #define ProjectRoot /usr/X11R6.3
+ #endif
+</verb>
+ Eliminate the #if 0 , #endif.
+ Then change this to whatever you prefer.
+ (I prefer the above for the precompiled binaries)
+<p>
+ The DG/ux malloc is crap and keeps bringing problems with some
+ X software so I don't use it. Instead there is a port of GNU
+ malloc in /usr/local (it came with the BuildXtools file).
+ Don't try to build with the /lib/libmalloc.a of DG/ux and then
+ send me e-mails that some programs they don't work properly.
+ In my build I use tcl8.0 and tk8.0 since the xconfig of R4.20MU03
+ is reporting incorrect values for the monitors and XF86Setup
+ need to be build in order to manage to adjust the display.
+ If you don't have this (or don't want this) comment out the lines
+ about tcl,tk, (in DGUX.cf)
+<p>
+<verb>
+ /*******TCL TK DEFINITIONS ***********/
+ #define HasTk YES-->NO
+ ...
+ #define HasTcl YES-->NO
+</verb>
+ Also 'GNU make' is required for the correct X11R6.3 build.
+ (it is in Buildxtools file).
+ If you decide yes to tcl,tk obtain the files
+<verb>
+ tcl8.0.3.tar.gz
+ tk8.0.3.tar.gz (from some ftp)
+</verb>
+ (or newer versions) and compile them before the building
+ of X11R6.3 (Build first tcl8.0.3 then tk8.0.3).
+<p>
+<sect> DISCUSSION ABOUT GCC<p>
+ There are so much things that I can say for the system gcc of
+ DG/ux. If I was keeping track for the programs that fail using
+ this compiler I will certainly have fill a book (conveniently
+ for the DG of course).
+ But my work is not to correct bugs for the DG/ux compiler or
+ anything else) , and in particular to collect reports for
+ the genius of DG.
+ (DG:Sorry guys nothing personal. I am a pure Mathematician ,
+ I am doing all this work for pleasure, I don't want any money
+ from DG or anybody else , I am not looking to become a employer
+ of DG,and I am NOT a trouble shooter of the DG/ux in general.
+ But maybe some times if you help I may be able to help you also).
+<p>
+ What I wanted to do is to build X11. Thats why you will find
+ in BuildXtools a new gcc. This gcc is build for DG/ux R4.20MU02.
+ so you have to upgrade your DG/ux OS version to the above.
+ But it is solid to build not only X11 but whatever else you want.
+ DO NOT use gcc of DG/ux. If you do I cannot tell you anything
+ about any problems that you have.
+ To complete the installation of this new gcc do the following:
+<p>
+<verb>
+ cp -r /usr/local/gcc-dgux /usr/opt/sdk/sde/ix86dgux/usr/lib
+ cd /usr/opt/sdk/sde/ix86dgux/usr/lib
+ rm gcc
+ ln -s gcc-dgux gcc (set link gcc--->gcc-dgux)
+
+ cd /usr/local
+ cp -r /usr/local/gcc-dgux /usr/sde/ix86dgux/usr/lib
+ cd /usr/sde/ix86dgux/usr/lib
+ rm gcc
+ ln -s gcc-dgux gcc (set link gcc-->gcc-dgux)
+</verb>
+
+ To come back to your old DG/ux gcc just change the above two
+ links gcc-->gcc-dgux
+ to gcc-->gcc-2
+ with the command: (in both the above two dirs)
+<verb>
+ rm gcc
+ ln -s gcc-2 gcc
+</verb>
+
+ /usr/bin/gcc -v should report the version that you have.
+ To build successfully this version of X11 gcc is a *MUST*.
+<p>
+ Dynamic loading Servers:
+ Edit xc/config/cf/DGUX.cf and change the entry
+<p>
+ #ifndef BuildDynamicLoading
+ #define BuildDynamicLoading NO --->YES.
+ #endif
+<p>
+ Remember when you build you will see lots of errors and the servers
+ will NOT build! This is because the dynamic linker doesn't know
+ the locations of the newly created R6 libX's.
+ So after the (seem faulty) building do a
+<p>
+ make DESTDIR=ProjectRoot/lib install
+<p>
+ (look below for install, ProjectRoot the location that you choose
+ in the file xc/config/cf/DGUX.cf above)
+<p>
+ So that all your new libXR6 libraries will go there.
+ (do a cd ProjectRoot/lib to make sure).
+<p>
+ Then go to your home dir and declare the path ProjectRoot/lib dir
+ in you LD_LIBRARY_PATH (your profile) as:
+<p>
+ LD_LIBRARY_PATH=ProjectRoot/lib:$LD_LIBRARY_PATH
+ export LD_LIBRARY_PATH
+<p>
+ Then relogin!
+<p>
+ Now just _rebuild_ A FULL XFree86-3.3.5 with the entry
+<p>
+ #define BuildDynamicLoading YES in your DGUX.cf.
+<p>
+ This time you will build _all_ XFree86-3.3.5 correctly.
+<p>
+
+<sect> BUILD <p>
+ In the usual X11R5 of DG (mwm) open an xterm and give:
+ (/bin/sh = Bourne shell)
+<p>
+<verb>
+ cd xc
+ make World > Build-dg.log
+</verb>
+
+ In that way you will get all the error messages in your
+ screen.
+ Don't worry with messages about -znodefs.
+<p>
+ Note: the old command
+<verb>
+ make World BOOTSTRAPCFLAGS="-DDGUX" > Build-dg.log
+</verb>
+ is no longer needed since imake will detect the DGUX OS
+ (in Version => 3.3.3.1) and set up things. However this
+ command will also work.
+<p>
+ And in another xterm give cd xc
+ tail -f Build-dg.log to watch the building progress.
+<p>
+ To install X11R6.3 XFree version 3.3.5 after the build
+ you must have a filesystem say usr_X11R6.3 mounted to
+ the directory /usr/X11R6 size 350000 blocks.
+ (or whatever you choose to be your ProjectRoot, if you
+ modify DGUX.cf for another ProjectRoot than the default
+ /usr/X11R6 in site.def).
+ Then give
+<verb>
+ make install
+ make install.man (install the man pages)
+</verb>
+ The installation will not put an XF86Config in your
+ /usr/X11R6.3/lib/X11/ and so if you give startx the new
+ X11 will not start. Read the file README-X3331.DGUX in
+ this ftp site (located in the binaries) about the whole
+ installation procedure of X11R6.3.
+ Or quickly you can do:
+ (I remind: DG/ux mouse device "/dev/mouse")
+ cd /usr/X11R6.3/bin
+ ln -s XF86_VGA16 X
+ Then put in your .profile the path /usr/X11R6.3/bin and
+ run the XF86Setup program. Adjust first the mouse device
+ then everything else.
+ (You need to read really the file README-DGUX.INSTALL-> look
+ in the end of this file).
+<p>
+ To build the contributed software with XFree86-3.3.5 get
+ the X335contrib.tgz and do
+<verb>
+ gzip -d < X335contrib.tgz | tar xvf -
+</verb>
+
+ (Or for 3.3.3 sources unpack X333contrib.tgz and apply the DGUX
+ patch as
+<verb>
+ gzip -d < X335contrib-DGUX.diff.gz | patch -p0 -E ).
+</verb>
+ Please note:
+ You must have already install and active the X11R6.3 that you
+ build so that the imake is working properly for your system.
+ Read below for how to install this X window system.
+ After that you could do:
+
+<verb>
+ cd contrib
+ xmkmf -a
+ make
+ make install
+ make install.man (for installing the man pages)
+</verb>
+
+
+<sect> INSTALLATION OF THE BINARY:<p>
+
+ NOTE:This executable has been compiled with the macro -DPENTIUM_CHANGE
+ (that all the new Aviion machines support). If you have an old i486
+ (rather unlikely) the executable will NOT RUN correctly.
+ But we haven't use -mcpu=pentiumpro, so the executable will work on
+ ALL PENTIUM machines.
+
+<itemize>
+<item> About Project Root: I choose as ProjectRoot for ix86 DG/ux the location
+ /usr/X11R6.3. The default (in 3.3.5 sources) is the /usr/X11R6. To
+ cover this we make a link in /usr as X11R6->X11R6.3 (read below);
+ so don't forget to do this link. I don't like the location /usr/opt/X11
+ (default location of DG X11) that some of you have suggested to me, I
+ believe it is a good idea to keep the original X11 as is for several
+ reasons.
+
+<item> Make a filesystem,using sysadm, mounted under "/usr/X11R6.3".
+ This is the default location of X11R6.3 , you cannot change this
+ except if you recompile the whole source of X.
+ (Please don't send e-mails about this).
+ The size of this filesystem should be around 175 MB(350000 blocks).
+
+ The list of files is:
+
+<verb>
+ X3353DL.tgz 3D_Labs XServer ... etc
+ X3358514.tgz
+ X335AGX.tgz
+ X335I128.tgz
+ X335Ma32.tgz Mach32 Xserver
+ X335Ma64.tgz Mach64 Xserver
+ X335Ma8.tgz
+ X335Mono.tgz
+ X335P9K.tgz
+ X335S3.tgz
+ X335S3V.tgz
+ X335SVGA.tgz SuperVGA Xserver (Supports AV3700 Cirrus)
+ X335VG16.tgz VGA16 Xserver (needed by XF86Setup)
+ X335W32.tgz
+ X335bin.tgz BIN (you must have this)
+ X335cfg.tgz
+ X335doc.tgz
+ X335f100.tgz
+ X335fcyr.tgz
+ X335fnon.tgz
+ X335fnts.tgz
+ X335fscl.tgz
+ X335fsrv.tgz
+ X335lib.tgz LIB (you must have this)
+ X335lkit.tgz Linkkit (X development)
+ X335man.tgz Man pages
+ X335nest.tgz
+ X335prog.tgz
+ X335prt.tgz
+ X335set.tgz
+ X335vfb.tgz
+ preinst.sh Install script
+ extract The XFree86 extract program (for ix86 DG/ux)
+
+ SUMS.md5 Checksums for the integrity of the files
+</verb>
+ (Try compile the GNU textutils-1.22.tar.gz from
+ prep.ai.mit.edu /pub/gnu. md5sum is there).
+<p>
+ You need at least:
+<verb>
+ X335bin.tgz
+ X335lib.tgz
+</verb>
+ And the correct Xserver for your machine/Graphics card.
+ In my opinion take all files , in the future you may need to
+ switch to another graphics device etc ... (mget *).
+ Generally it is good to have the full distribution of the
+ X11R6.3 window system ,it should make life easier in DG/ux.
+<p>
+ (Trivial:you must have root privilege).
+<p>
+<item> Unpack the *.tgz files in your / so that it will go directly inside to
+ the new filesystem /usr/X11R6.3. After you do that cd /usr and do a link :
+ ln -s X11R6.3 X11R6. (Use the install script).
+ This link will indicate in XF86 programs like XF86Setup where the new X11
+ window system is.
+
+<item> cd your home dir and backup your .profile as "cp .profile myprofile". Then
+ cd /usr/X11R6.3. Copy the file HOME.profile-X11R6.3 to your home dir as
+ "cp HOME.profile-X11R6.3 your home dir/.profile" ,then cd your home dir and
+ "chmod 644 .profile" to make sure that the new profile is active. This is
+ because you need to tell to the system to look for the X software in a
+ different location than the usual /usr/bin/X11 of DG/ux. Also you need
+ to tell to the system that the new X libraries are in /usr/X11R6.3/lib.
+<p>
+ **You NEED to re-login in order to make the new .profile active !**
+ ** DO NOT GIVE "startx" AFTER THAT, READ Configuration below !**
+
+<item> About Configuration:
+ DG/ux has a program (actually a script) called xconfig that makes the
+ configuration for you. Usually when you run xconfig in the DG/ux-X11R5
+ it creates a file XdgConfig in /var/X11/Xserver which is the corresponding
+ of the XF86-configuration file located in /usr/X11R6.3/lib/X11/XF86Config.
+ This file ,in the section monitor, has all values for your monitor.
+ Please Note:
+ Unfortunately in DG/ux R4.20MU02 things change. Instead of going forwards we
+ going backwards... xconfig reports crazy values for my DG-DA1765VA monitor.
+ So if you have a CDROM of DG/ux R4.11MU02,or MU03 use it to find an xconfig
+ that will give you reliable values for your monitor.
+<p>
+ Your best bet is to use XF86Setup for correct adjustments.
+<p>
+ Thats the reason that in this binary there is a minimum tcl,tk(version 8.0).
+ Before you run XF86Setup read the relevant documents found in www.xfree86.org.
+ (Or read below for a hand-made configuration).
+<p>
+ Notice about XF86Setup: You will will see the message
+ "The program is running on a different virtual"
+ "Please switch to the correct virtual terminal"
+<p>
+ DG/ux does NOT have any virtual terminals. But XF86Setup uses a script
+ that doesn't checks for this. So it is printing this message anyway.
+ Ignore it and don't send e-mails asking how to set the virtual terminal!
+ XF86Setup WORKS for SURE (if you use it correctly) to set your configuration.
+ Just remember:
+ <enum>
+ <item> make a link in /usr/X11R6.3/bin: ln -s XF86_VGA16 X
+ <item> set mouse device in your XF86Config to /dev/mouse (this the mouse in DGUX)
+ <item> set the correct mouse protocol. (usually for a typical AViiON PS/2).
+ </enum>
+ Or just cd /usr/X11R6.3/lib/X11 and copy XF86Config.eg.dgux to XF86Config
+ (it is for a PS/2 protocol mouse that almost all AViiON's have) , then
+ run XF86Setup and choose to use this XF86Config file as default (so mouse
+ works).
+<p>
+ Alternatively, you can run xf86config, a non-graphical configuration utility
+ but you will need to enter manually the values for your monitor.
+ If you have the small booklet that came with the monitor they are inside.
+<p>
+ Hand made configuration:
+ I have an DG/ux Medium resolution (1280x1024) 17 inch DG-26059,DA1765VA.
+<bf>
+ ONLY IF YOU HAVE THE
+ ***EXACT SAME***
+ MONITOR USE THE FILE XF86Config_SVGA_DGUX that you will find in /usr/X11R6.3/.
+ IT IS IN YOUR OWN RISK IF YOU DECIDE TO USE THIS FILE WHEN YOU DON'T HAVE THE
+ SAME MONITOR AS MINE. YOU CAN DAMAGE YOUR VIDEO MONITOR OR YOUR GRAPHICS CARD.
+</bf>
+<p>
+ An example of how to use the Accel Servers (eg ATI=XF86_Mach64) is in the file
+ XF86Config_ATI_DGUX.
+ Again remember:
+ I have an DG/ux Medium resolution (1280x1024) 17 inch DG-26059,DA1765VA.
+<bf>
+ ONLY IF YOU HAVE THE
+ ***EXACT SAME***
+ MONITOR USE THE FILE XF86Config_ATI_DGUX that you will find in /usr/X11R6.3/.
+ IT IS IN YOUR OWN RISK IF YOU DECIDE TO USE THIS FILE WHEN YOU DON'T HAVE THE
+ SAME MONITOR AS MINE. YOU CAN DAMAGE YOUR VIDEO MONITOR.
+</bf>
+<p>
+ Start with the file XF86Config.eg as a prototype. READ the README.Config .
+ In Cirrus chips you need to read the file README.cirrus located in /usr/X11R6.3
+ There is a problem with the accelerated XAA code ,so you need to try to put
+ the following option in your XF86Config:
+<verb>
+ Option "no_mmio" (in Section Screen ,subsection display).
+</verb>
+ Look in the XF86Config_SVGA_DGUX to see how this can be done .
+ If this doesn't work (it will probably) try Option "noaccel" or "no_bitblt".Again
+ READ the file README.cirrus (and README.Config).
+ I suggest to print (in paper) the file XdgConfig and have a look in it. Then it
+ should be quite trivial to figure out what you have to do with the XF86 file
+ ie XF86Config in the sections mouse, keyboard, screen ...
+ After you have a correct XF86Config in /usr/X11R6.3/lib/X11 give
+<verb>
+ chmod 444 XF86Config.
+</verb>
+<p>
+ Supposing that you have already re-login so that the new .profile is active
+ and you have the correct XF86Config file (as your XdgConfig suggest) (DO not
+ forget for a cirrus to put the Option "no_mmio" in section screen !), give
+ startx and the new X11 will start .
+ Remember: You can shut down at any point the Xserver by pressing
+ CONTROL+ALT+BACKSPACE (if something goes wrong).
+ Also Xservers don't produce messages unless to want them to do so. This is
+ because the DG/ux console driver some times causes corruption of the screen
+ if you print text during the startup of the Xserver.
+ If you require messages try in bash shell to give: (bash# )
+<verb>
+ X -verbose >& info1 or even
+ X -verbose -verbose >& info2 for more messages.
+</verb>
+ Then when the server is up press CONTROL+ALT+BACKSPACE to shutdown the
+ Xserver. File info1 (or info2) have all relevant info about your graphics
+ card , display memory etc ...
+ I suggest you do that at least one time before start using the new X11R6.3.
+ Read this info file to see if all ok. If not try change settings in your
+ XF86Config to make thinks correct.
+<p>
+ If you have an ATI Rage II (or RageII+) use the server XF86_Mach64 (make
+ a link link X--->XF86_MACH64, or run xf86config, or use XF86Setup above).
+
+<item> If you want to compile programs with the X11R6.3 the headers in /usr/include
+ /X11 pointing to /usr/opt/X11 of DG/ux is a problem .
+ Do:
+<p>
+ a): unmounting the /usr/opt/X11 will prevent the sysadm to use the X
+ graphical interface. But this will be the only thing that you loose.
+ The correct thing to do for X11R6.3 is to delete the filesystem /usr/opt/X11
+ and make a link /usr/opt/X11--->/usr/X11R6.3 , so that the libraries
+ from dglib and /usr/lib point correctly to the new ones in /usr/X11r6.3/lib.
+ Before you unmount this filesystem you need to do this:
+<verb>
+ cd /usr/opt/X11/include
+ cp -r Mrm /usr/X11R6.3/include
+ cp -r uil /usr/X11R6.3/include
+ cp -r Xm /usr/X11R6.3/include
+ cd /usr/X11R6.3/include
+ ln -s uil Uil
+</verb>
+
+ LIBRARIES:
+<verb>
+ and cd /usr/opt/X11/lib
+ cp libXm.a /usr/X11R6.3/lib
+</verb>
+
+ and similarly copy the following libraries:
+
+<verb>
+ libX11.so.2, libX11.so.5, libXIM.so.1, libXaw.so.1, libXaw.so.2,
+ libXext.so.2, libXi.so.2, libXimp.so.1, libXm.so.2, libXmu.so.2,
+ libXsess.so.1, libXsi.so.1, libXt.so.2, libXt.so.5.0, libMrm.a,
+ libUil.a, libX11_s, libXR4sco_s
+</verb>
+
+ into /usr/X11R6.3/lib.
+<p>
+ Then cd /usr/X11R6.3/lib and make links:
+
+<verb>
+ ln -s libXm.so.2 libXm.so
+ ln -s libXm.so.2 libXm.so.1
+ ln -s libXm.so.2 libXm.so.5.0
+
+ ln -s libX11.so.5.0 libX11.so.1
+
+ ln -s libXIM.so.1 libXIM.so.5.0
+
+ ln -s libXaw.so.2 libXaw.so.5.0
+
+ ln -s libXext.so.2 libXext.so.5.0
+ ln -s libXext.so.2 libXext.so.1
+
+ ln -s libXi.so.2 libXi.so.1
+ ln -s libXi.so.2 libXi.so.5.0
+
+ ln -s libXimp.so.1 libXimp.so.5.0
+
+ ln -s libXmu.so.2 libXmu.so.5.0
+
+ ln -s libXt.so.2 libXt.so.5.0
+
+ ln -s libXsi.so.1 libXi.so.5.0
+
+ cd /usr/X11R6.3/lib
+ rm libXmu.so (to avoid undefs when building X software)
+</verb>
+
+ Also you need to correct the links in /usr/dglib at least!
+ (the correct thing to do is modify also /usr/lib links to
+ /usr/opt/X11 libs).
+ Try
+<verb>
+ cd /usr/
+ tar -cvf dglib-orig.tar dglib
+ gzip dglib-orig.tar
+</verb>
+ (to minimize the space dglib-backup takes) then
+<verb>
+ cd /usr/dglib
+</verb>
+ and delete ALL links to libraries in
+ /usr/opt/X11. Then copy the script create_new_links_in_dglib (found
+ in /usr/X11R6.3 to /usr/dglib and cd /usr/dglib execute script.
+ This will create all new links with the X11R6.3 X window system.
+<p>
+ But remember to do in the end :
+<p>
+<verb>
+ cd /usr/dglib
+ rm *.a (no static libs links in dglib)
+</verb>
+
+ Then unmount (delete) the old X11 by giving "umount /usr/opt/X11".
+<p>
+ NOTE: If you compile programs in the X11R6 make sure that you
+ unmount /usr/opt/X11 or you eliminate the links in /usr/lib
+ to the OLD libX's in /usr/opt/X11/lib.
+ Otherwise gcc will link these old libraries! and the binary will
+ not run correctly.
+ Always after an R6 compilation do "ldd prog" to make sure that the
+ binary loads only R6 version libraries (except maybe the motif
+ library libXm.so.2), --if you don't use the static libXm.a
+<p>
+ b:)
+<verb>
+ cd /usr/include
+ tar -cvf old-X11headers.tar X11
+ gzip old-X11headers.tar
+</verb>
+ so that you store your old headers in /usr/include.
+
+ Then cd /usr/include/ and delete
+<verb>
+ rm -r X11
+ rm Xm
+ rm Mrm
+ rm Uil
+ rm uil
+ Make new links as:
+ cd /usr/include
+ ln -s ../X11R6.3/include/X11 X11
+ ln -s ../X11R6.3/include/uil Uil
+ ln -s ../X11R6.3/include/uil uil
+ ln -s ../X11R6.3/include/Xm Xm
+ ln -s ../X11R6.3/include/Mrm Mrm
+</verb>
+</itemize>
+
+<sect> What is about:<p>
+ This new X11R6 are not simply an upgrade of the servers to the latest ones.
+ It is a new programming platform in your DG/ux system to allow you to import
+ all this *FREE* or not software for the X window system.
+ This software will not compile in the old (and ugly) X11 of Data General.
+ The imake command that is implemented in almost all the (source) software
+ for X11 (free or not) will not work with the totally broken "imake" command
+ of /usr/opt/X11 of DG/ux.
+<p>
+ The imake of DG/ux X11R5 is badly broken:
+ I have seen DG/ux releases R4.11,MU01, ...MU04, R420, R4.20MU02 ,R4.20MU03
+ and nobody bother to look in all these releases the imake command...
+<p>
+ While until now DG was rather hostile to the prospect of a new X11 in DG/ux
+ some new folks there they have turn their interest in X11R6 (XFree86) these
+ days. That is good of course because the ultimate target is to make XFree86
+ (3.3.5 or whatever version) to run in _their_ DG/ux Unix! I will be able to
+ make a much better X11 in DG/ux if I could had some access to DG/ux sources
+ (i.e. the original R5 sources , but not only --eg kernel driver sources as
+ for example the DG/ux kernel console driver sources).
+<p>
+ I have compile almost anything that runs for Linux in DG/ux using this X11.
+ In doing this work in XFree86 I would like to express my thanks to David Dawes
+ that he help me all the time with several technical questions. Also D.T. is one
+ of the people that offer valuable help.
+ Finally I want to express my thanks to John H. for enlightening me in some syscall
+ issues.
+
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/DGux.sgml,v 1.3 1999/08/28 10:43:32 dawes Exp $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/DocIndex.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/DocIndex.sgml
new file mode 100644
index 000000000..6327a190c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/DocIndex.sgml
@@ -0,0 +1,132 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN"[
+<!ENTITY % defs SYSTEM "defs.ent"> %defs;
+]>
+
+<article>
+
+<!-- Title information -->
+<title>Documentation for XFree86&trade; version &relvers;
+<author>The XFree86 Project, Inc
+<date>19 July 1999
+
+<ident>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/DocIndex.sgml,v 3.34 1999/08/23 09:06:03 dawes Exp $
+</ident>
+
+<p>
+<itemize>
+<item><htmlurl name="README for XFree86&tm; &relvers;"
+ url="README.html">
+<item><htmlurl name="Release Notes for XFree86&trade; &relvers;"
+ url="RELNOTES.html">
+<item><htmlurl name="Licenses"
+ url="LICENSE.html">
+<!--
+<item><htmlurl name="Quick Start Guide for XFree86"
+ url="QuickStart.html">
+<item><htmlurl name="The XInput extension in XFree86"
+ url="xinput.html">
+-->
+<item><htmlurl name="XFree86 X server ``New Design'' (DRAFT)"
+ url="DESIGN.html">
+<item><htmlurl name="Mouse Support in XFree86"
+ url="mouse.html">
+<item><htmlurl name="Fonts in XFree86"
+ url="fonts.html">
+<!--
+<item><htmlurl name="README for XFree86 3.1.2 on BSD/OS 2.0"
+ url="Bsdi.html">
+-->
+<!--
+<item><htmlurl name="README for XFree86 on FreeBSD"
+ url="FreeBSD.html">
+-->
+<item><htmlurl name="Information for ISC Users"
+ url="isc.html">
+<!--
+<item><htmlurl name="Information for Linux Users"
+ url="Linux.html">
+<item><htmlurl name="README for XFree86 3.2A on LynxOS"
+ url="LynxOS.html">
+-->
+<!--
+<item><htmlurl name="README for XFree86 3.1 on Mach"
+ url="Mach.html">
+-->
+<!--
+<item><htmlurl name="README for XFree86 3.2 on NetBSD and OpenBSD"
+ url="NetBSD.html">
+<item><htmlurl name="README for XFree86 3.2 on OS/2"
+ url="OS2.html">
+<item><htmlurl name="Notes on Rebuilding XFree86/OS2 from Scratch"
+ url="OS2Notes.html">
+<item><htmlurl name="Information for SCO Users"
+ url="SCO.html">
+<item><htmlurl name="Information for Solaris for x86 Users"
+ url="SOLX86.html">
+<item><htmlurl name="Information for SVR4 Users"
+ url="SVR4.html">
+<item><htmlurl name="Configuring XFree86"
+ url="Config.html">
+<item><htmlurl name="Building XFre86"
+ url="BUILD.html">
+-->
+<!--
+<item><htmlurl name="The Hitchhiker's Guide to X386/XFree86 Video Timing"
+ url="VideoModes.html">
+<item><htmlurl name="Readme for the XFree86 3.1.2 LinkKit"
+ url="LinkKit.html">
+-->
+<!--
+<item><htmlurl name="How to add an (S)VGA driver to XFree86"
+ url="VGADriver.html">
+<item><htmlurl name="Notes on the AGX Server"
+ url="agx.html">
+<item><htmlurl name="Information for ARK Logic Chipset Users"
+ url="ark.html">
+-->
+<item><htmlurl name="ATI Adapters README file"
+ url="ati.html">
+<item><htmlurl name="Information for Chips and Technologies Users"
+ url="chips.html">
+<!--
+<item><htmlurl name="Information for Cirrus Chipset Users"
+ url="cirrus.html">
+-->
+<item><htmlurl name="Information for DEC 21030 Users (aka TGA)"
+ url="DECtga.html">
+<!--
+<item><htmlurl name="Notes for Mach32 X Server"
+ url="Mach32.html">
+<item><htmlurl name="Notes for Mach64 X Server"
+ url="Mach64.html">
+<item><htmlurl name="Information for Matrox Millennium Users"
+ url="MGA.html">
+<item><htmlurl name="Information for NVidia NV1 / SGS-Thomson Users"
+ url="NV1.html">
+<item><htmlurl name="Information for Oak Technologies Inc. Chipset Users"
+ url="Oak.html">
+<item><htmlurl name="XFree86 3.2 P9000 Server Release Notes"
+ url="P9000.html">
+<item><htmlurl name="Information for S3 Chipset Users"
+ url="S3.html">
+-->
+<item><htmlurl name="Information for S3 ViRGE Users"
+ url="s3virge.html">
+<item><htmlurl name="Information for SiS Users"
+ url="SiS.html">
+<!--
+<item><htmlurl name="Information for Trident Chipset Users"
+ url="trident.html">
+<item><htmlurl name="Information for Tseng Chipset Users"
+ url="tseng.html">
+<item><htmlurl name="README.VIDEO7"
+ url="Video7.html">
+<item><htmlurl name="Information for Western Digital Chipset Users"
+ url="WstDig.html">
+<item><htmlurl name="The Linux/m68k Frame Buffer Device"
+ url="fbdev.html">
+-->
+</itemize>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/FreeBSD.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/FreeBSD.sgml
new file mode 100644
index 000000000..a13cfc0d0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/FreeBSD.sgml
@@ -0,0 +1,354 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+<title> README for XFree86 on FreeBSD
+<author>Rich Murphey, David Dawes
+<date>8 November 1998
+
+<toc>
+
+<sect>What and Where is XFree86?
+
+<p>
+XFree86 is a port of X11R6.3 that supports several versions of
+Intel-based Unix. It is derived from X386 1.2, which was the X server
+distributed with X11R5. This release consists of many new features
+and performance improvements as well as many bug fixes.
+
+For further details about this release, including installation instructions,
+please refer to the <htmlurl name="Release Notes" url="RELNOTES.html">.
+
+See the <htmlurl url="COPYRIGHT.html" name="Copyright Notice">.
+
+Binaries for XFree86 on FreeBSD 2.2.x and 3.0 are available from:
+
+<htmlurl name="ftp://ftp.XFree86.org/pub/XFree86/current/binaries/"
+url="ftp://ftp.XFree86.org/pub/XFree86/current/binaries/">
+<p>
+
+Send email to <em/Rich-Murphey@Rice.edu/ or <em/XFree86@XFree86.org/
+if you have comments or suggestions about this file and we'll revise
+it.
+
+
+<sect>FreeBSD 3.0 and ELF<p>
+
+The FreeBSD-3.0 binary distribution is ELF only. The Xbin.tgz tarball
+contains a.out libraries for compatibility purposes.
+
+
+<sect>Installing The Display Manager (xdm)
+<p>
+The display manager makes your PC look like an X terminal. That is, it
+presents you with a login screen that runs under X.
+
+The easiest way to automatically start the display manager on boot is to
+add a line in <tt>/etc/ttys</tt> to start it on one of the unoccupied
+virtual terminals:
+
+<tscreen><verb>
+ ttyv4 "/usr/X11R6/bin/xdm -nodaemon" xterm on secure
+</verb></tscreen>
+
+You should also make sure that <tt>/usr/X11R6/bin/X</tt> is a symbolic
+link to the Xserver that matches your video card or edit the file
+Xservers in <tt>/usr/X11R6/lib/X11/xdm</tt> to specify the pathname of
+the X server.
+
+The change to <tt>/etc/ttys</tt> won't take effect until you either
+reboot or ``<tt/kill -HUP 1/'' to force initd to reread
+<tt>/etc/ttys</tt>. You can also test the display manager manually by
+loging in as root on the console and typing ``<tt/xdm -nodaemon/''.
+
+
+<sect>Configuring X for Your Hardware
+<p>
+The <tt/XF86Config/ file tells the X server what kind of monitor, video card
+and mouse you have. You <em/must/ create it to tell the server what
+specific hardware you have.
+
+It is strongly recommended that you read through the <htmlurl
+name="QuickStart guide" url="QuickStart.html">, and use either
+the `XF86Setup' utility (which requires the VGA16 server to be installed),
+or the `xf86config' utility to generate an XF86Config file.
+
+When you run the `XF86Setup' utility, do NOT touch the mouse until
+you are finished with mouse set up.
+Otherwise, the VGA16 server and the mouse device driver may get
+confused and you may experience mouse and/or keyboard input problems.
+
+If you are running ``<tt/moused/'' (see the man page for <tt/moused(8)/)
+in FreeBSD versions 2.2.1 or later,
+you MUST specify <tt>SysMouse</tt> as the mouse protocol type
+and <tt>/dev/sysmouse</tt> as the mouse device name,
+regardless of the brand and model of your mouse.
+
+If you are NOT running ``<tt/moused/'', you need to know the interface
+type of your mouse, <tt>/dev</tt> entry and the protocol type to use.
+
+The interface type can be determined by looking at the connector
+of the mouse.
+The serial mouse has a D-Sub female 9- or 25-pin connector.
+The bus mouse has either a D-Sub male 9-pin connector
+or a round DIN 9-pin connector.
+The PS/2 mouse is equipped with a small, round DIN 6-pin connector.
+Some mice come with adapters with which the connector can
+be converted to another. If you are to use such an adapter,
+remember the connector at the very end of the mouse/adapter pair is
+what matters.
+
+The next thing to decide is a <tt>/dev</tt> entry for the given interface.
+For the bus and PS/2 mice, there is little choice:
+the bus mouse always use <tt>/dev/mse0</tt>,
+and the PS/2 mouse is always at <tt>/dev/psm0</tt>.
+There may be more than one serial port to which the serial
+mouse can be attached. Many people often assign the first, built-in
+serial port <tt>/dev/cuaa0</tt> to the mouse.
+
+If you are not sure which serial device your mouse is plugged into,
+the easiest way to find out the device is to
+use ``<tt/cat/'' or ``<tt/kermit/'' to look at the output of the
+mouse. Connect to it and just make sure that it generates output when
+the mouse is moved or clicked:
+
+<tscreen><verb>
+ % cat < /dev/tty00
+</verb></tscreen>
+
+If you can't find the right mouse device then use ``<tt/dmesg|grep
+sio/'' to get a list of serial devices that were detected upon booting:
+
+<tscreen><verb>
+ % dmesg|grep sio
+ sio0 at 0x3f8-0x3ff irq 4 on isa
+</verb></tscreen>
+
+Then double check the <tt>/dev</tt> entries corresponding to these
+devices. Use the script <tt>/dev/MAKEDEV</tt> to create entries if
+they don't already exist:
+
+<tscreen><verb>
+ % cd /dev
+ % sh MAKEDEV tty00
+</verb></tscreen>
+
+You may want to create a symbolic link <tt>/dev/mouse</tt>
+pointing to the real port to which the mouse is connected, so that you
+can easily distinguish which is your ``mouse'' port later.
+
+The next step is to guess the appropriate protocol type for the mouse.
+In FreeBSD 2.2.6 or later, the X server may be able to automatically
+determine the appropriate protocol type, unless your mouse is of a
+relatively old model.
+Use the ``<tt/Auto/'' protocol in these versions.
+
+In other versions of FreeBSD or if the ``<tt/Auto/'' protocol
+doesn't work in 2.2.6, you have to guess a protocol type and try.
+
+There is rule of thumb:
+
+<enum>
+<item>The bus mice always use the ``<tt>BusMouse</tt>''
+protocol regardless of the brand of the mouse.
+<item>The ``<tt>PS/2</tt>'' protocol should always be specified for
+the PS/2 mouse regardless of the brand of the mouse.
+<quote>
+<bf/NOTE:/ There are quite a few PS/2 mouse protocols listed in the man page
+for <tt>XF86Config</tt>. But, ``<tt>PS/2</tt>'' is the only PS/2 mouse
+protocol type useful in <tt>XF86Config</tt> for FreeBSD.
+The other PS/2 mouse protocol types are not supported in FreeBSD.
+FreeBSD version 2.2.6 and later directly support
+these protocol types in the PS/2 mouse driver <tt/psm/ and it is not
+necessary to tell the X server which PS/2 mouse protocol type is to
+be used; ``<tt/Auto/'' should work, otherwise use ``<tt>PS/2</tt>''.
+</quote>
+<item>The ``<tt>Logitech</tt>'' protocol is for old mouse models
+from Logitech.
+Modern Logitech mice use either the ``<tt>MouseMan</tt>''
+or ``<tt>Microsoft</tt>'' protocol.
+<item>Most 2-button serial mice support the ``<tt>Microsoft</tt>'' protocol.
+<item>3-button serial mice may work with the ``<tt>MouseSystems</tt>''
+protocol. If it doesn't, it may work with the ``<tt>Microsoft</tt>''
+protocol although the third (middle) button won't function.
+3-button serial mice may also work with the ``<tt>MouseMan</tt>''
+protocol under which the third button may function as expected.
+<item>3-button serial mice may have a small switch to choose between ``MS''
+and ``PC'', or ``2'' and ``3''.
+``MS'' or ``2'' usually mean the ``<tt>Microsoft</tt>'' protocol.
+``PC'' or ``3'' will choose the ``<tt>MouseSystems</tt>'' protocol.
+<item>If the serial mouse has a roller or a wheel, it may be compatible
+with the ``<tt>IntelliMouse</tt>'' protocol.
+</enum>
+
+<sect>Running X
+<p>
+8mb of memory is a recommended minimum for running X. The server,
+window manager, display manager and an xterm take about 8Mb of virtual
+memory themselves. Even if their resident set size is smaller, on a
+8Mb system that leaves very space for other applications such as gcc
+that expect a few meg free. The R6 X servers may work with 4Mb of
+memory, but in practice compilation while running X can take 5 or 10
+times as long due to constant paging.
+
+The easiest way for new users to start X windows is to type
+``<tt>startx >&amp; startx.log</tt>''. Error messages are lost unless
+you redirect them because the server takes over the screen.
+
+To get out of X windows, type: ``<tt/exit/'' in the console xterm.
+You can customize your X by creating <tt/.xinitrc/, <tt/.xserverrc/,
+and <tt/.twmrc/ files in your home directory as described in the <em/xinit/
+and <em/startx/ man pages.
+
+
+
+<sect>Rebuilding Kernels for X
+<p>
+
+The GENERIC FreeBSD kernels support XFree86
+without any modifications required. You do not need to make any changes
+to the GENERIC kernel or any kernel configuration which is a superset.
+
+For a general description of BSD kernel configuration get <url
+name="smm.02.config.ps.Z"
+url="ftp://gatekeeper.dec.com/pub/BSD/manuals/smm.02.config.ps.Z">.
+It is a ready-to-print postscript copy of the kernel configuration
+chapter from the system maintainers manual.
+
+If you do decide to reduce your kernel configuration file, do not
+remove the line below (in <tt>/sys/arch/i386/conf</tt>). It
+is required for X support:
+
+<tscreen><verb>
+ options UCONSOLE #X Console support
+</verb></tscreen>
+
+The generic FreeBSD kernels are configured
+by default with the syscons driver. To configure your kernel similarly
+it should have a line like this in <tt>/usr/src/sys/i386/conf/GENERIC</tt>:
+
+<tscreen><verb>
+ device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+</verb></tscreen>
+
+The number of virtual consoles can be set using the MAXCONS option:
+
+<tscreen><verb>
+ options "MAXCONS=4" #4 virtual consoles
+</verb></tscreen>
+
+Otherwise, the default without a line like this is 16. You must have more
+VTs than gettys as described in the end of section 3, and 4 is a reasonable
+minimum.
+
+The server supports two console drivers: syscons and pcvt.
+The syscons driver is the default in FreeBSD 1.1.5 and higher. They are
+detected at runtime and no configuration of the server itself is required.
+
+If you intend to use pcvt as the console driver, be sure to include the
+following option in your kernel configuration file.
+
+<tscreen><verb>
+ options XSERVER #Xserver
+</verb></tscreen>
+
+The number of virtual consoles in pcvt can be set using the following
+option:
+
+<tscreen><verb>
+ options "PCVT_NSCREENS=10" #10 virtual consoles
+</verb></tscreen>
+
+The bus mouse driver and the PS/2 mouse driver may not be included, or
+may be included but disabled in your kernel. If you intend to use
+these mice, verify the following lines in the kernel configuration file:
+
+
+<tscreen><verb>
+ device mse0 at isa? port 0x23c tty irq 5 vector mseintr
+ device psm0 at isa? port "IO_KBD" conflicts tty irq 12 vector psmintr
+</verb></tscreen>
+
+The <tt/mse0/ device is for the bus mouse and the <tt/psm/ device is
+for the PS/2 mouse. Your bus mouse interface card may allow you to
+change IRQ and the port address. Please refer to the manual of
+the bus mouse and the manual page for <tt/mse(4)/ for details.
+There is no provision to change IRQ and the port address of the
+PS/2 mouse.
+
+The XFree86 servers include support for the MIT-SHM extension. The
+GENERIC kernel does not support this, so if you want to make use of
+this, you will need a kernel configured with SYSV shared memory
+support. To do this, add the following line to your kernel config
+file:
+
+<tscreen><verb>
+ options SYSVSHM # System V shared memory
+ options SYSVSEM # System V semaphores
+ options SYSVMSG # System V message queues
+</verb></tscreen>
+
+If you are using a SoundBlaster 16 on IRQ 2 (9), then you need a patch for
+sb16_dsp.c. Otherwise a kernel configured with the SoundBlaster driver will
+claim interrupt 9 doesn't exist and X server will lock up.
+
+S3 cards and serial port COM 4 cannot be installed together on a
+system because the I/O port addresses overlap.
+
+
+<sect>Building X Clients
+<p>
+
+The easiest way to build a new client (X application) is to use
+<tt/xmkmf/ if an <tt/Imakefile/ is included with it. Type ``<tt/xmkmf -a/''
+to create the Makefiles, then type ``<tt/make/''. Whenever you install
+additional man pages you should update <tt/whatis.db/ by running
+``<tt>makewhatis /usr/X11R6/man</tt>''.
+
+<bf/Note:/ Starting with XFree86 2.1 and FreeBSD 1.1, the symbol
+<bf/__386BSD__/ no longer gets defined either by the compiler or via the
+X config files for FreeBSD systems. When porting clients to BSD
+systems, make use of the symbol <bf/BSD/ for code which is truly
+BSD-specific. The value of the symbol can be used to distinguish
+different BSD releases. For example, code specific to the Net-2 and
+later releases can use:
+
+<tscreen>
+#if (BSD >= 199103)
+</tscreen>
+
+To ensure that this symbol is correctly defined, include
+<tt>&lt;sys/param.h&gt;</tt> in the source that requires it. Note that
+the symbol <bf/CSRG_BASED/ is defined for *BSD systems in XFree86 3.1.1
+and later. This should be used to protect the inclusion of
+<tt>&lt;sys/param.h&gt;</tt>.
+
+For code that really is specific to a particular i386 BSD port, use
+<bf/__FreeBSD__/ for FreeBSD, <bf/__NetBSD__/ for NetBSD,
+<bf/__OpenBSD__/ for OpenBSD,
+<bf/__386BSD__/ for 386BSD, and <bf/__bsdi__/ for BSD/386.
+
+
+<sect> Thanks
+<p>
+Many thanks to:
+ <itemize>
+<item><bf/Pace Willison/ for providing initial *BSD support.
+<item><bf/Amancio Hasty/ for 386BSD kernel and S3 chipset support.
+<item><bf/David Greenman, Nate Williams, Jordan Hubbard/ for FreeBSD
+ kernel support.
+<item><bf/Rod Grimes/, <bf/Jordan Hubbard/ and <bf/Jack Velte/ for
+ the use of Walnut Creek Cdrom's hardware.
+<item><bf/Orest Zborowski/, <bf/Simon Cooper/ and <bf/Dirk Hohndel/ for ideas from the Linux distribution.
+</itemize>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/FreeBSD.sgml,v 3.29 1999/08/23 06:38:46 dawes Exp $
+
+
+
+
+
+$XConsortium: FreeBSD.sgml /main/12 1996/10/28 05:43:08 kaleb $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/I128.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/I128.sgml
new file mode 100644
index 000000000..3381a243b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/I128.sgml
@@ -0,0 +1,90 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+<title>Information for Number Nine I128 Users
+<author>The XFree86 Project Inc.
+<date>24 October 1998
+<toc>
+
+<sect>Supported hardware
+<p>
+The current accelerated I128 server supports
+<p>
+<itemize>
+<item>Imagine 128
+(I128 with Texas Instruments TVP3025 or IBM528 RAMDAC). It has been tested with
+with 4MB of VRAM.
+<item>Imagine 128 Ticket 2 Ride
+(I128-T2R with IBM526 or 528 RAMDAC). It has been tested with 4 MB and 8 MB of
+VRAM and DRAM.
+<item>Imagine 128 Revolution 3D
+(I128-R3D with IBM526 RAMDAC). It has been tested with 4 MB, 8 MB, and 16 MB
+of WRAM or SGRAM.
+<item>Imagine 128 Revolution IV
+(I128-R4 with SILVERHAMMER RAMDAC). It has been tested with 32 MB.
+</itemize>
+
+<sect>Features:
+<p>
+<itemize>
+<item>uses linear frame buffer
+<item>Resolutions up to the maximum supported by the card should be possible.
+<item>8 bpp, 16 bpp (depth 15 and 16), and 32 bpp (depth 24, sparse) are
+supported.
+<item>supports RGB Sync-on-Green
+<item>Makes use of the graphics accelerator.
+</itemize>
+
+<sect>Configuration:
+<p>
+The I128 driver should auto-detect all supported hardware so you needn't
+have anything other than the Identifier in the Section "Device" of the
+XF86Config file. When running the XF86Setup or xf86config programs one
+merely needs to select an I128 card so that the correct server will be
+used. One need not and should not specify a RAMDAC, clockchip or allow
+the setup program to probe for clocks. The driver will auto-detect the
+amount of video ram present.
+
+The following Section "Device" options are supported by the MGA driver:
+<itemize>
+<item>Option "dac_8_bit"
+<p>
+Will enable 8-bit DAC support.
+<item>Option "no_accel"
+<p>
+Will disable all hardware acceleration.
+<item>Option "sync_on_green"
+<p>
+Will enable syncing on green for sync-on-green monitors (these are typically
+fixed frequency workstation monitors).
+</itemize>
+
+<sect>Mode lines for the Silicon Graphics flat panel display:
+<p>
+<itemize>
+<item>These mode lines are required for use with the T2R4 (Rev 4) and the
+Silicon Graphics Flat Panel display.
+<item>Modeline "1600x1024d32" 103.125 1600 1600 1656 1664 1024 1024 1029 1030 HSkew 7 +Hsync +Vsync
+<item>Modeline "1600x1024d16" 103.125 1600 1600 1656 1664 1024 1024 1029 1030 HSkew 5 +Hsync +Vsync
+<item>Modeline "1600x1024d08" 103.125 1600 1600 1656 1664 1024 1024 1029 1030 HSkew 1 +Hsync +Vsync
+<item>Modeline "800x512d32" 54.375 800 800 840 848 512 512 514 515 HSkew 7 DoubleScan +Hsync +Vsync
+<item>Modeline "800x512d16" 54.375 800 800 840 848 512 512 514 515 HSkew 5 DoubleScan +Hsync +Vsync
+<item>Modeline "800x512d08" 54.375 800 800 840 848 512 512 514 515 HSkew 1 DoubleScan +Hsync +Vsync
+</itemize>
+
+<sect>Author(s)
+<p>
+
+Robin Cutshaw, <it>robin@XFree86.Org</it>
+
+and special help from:
+
+<itemize>
+<item>Galen Brooks, <it>galen@nine.com</it>
+</itemize>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/I128.sgml,v 1.3 1999/08/28 10:43:32 dawes Exp $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/Imakefile b/xc/programs/Xserver/hw/xfree86/doc/sgml/Imakefile
new file mode 100644
index 000000000..c515a9007
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/Imakefile
@@ -0,0 +1,95 @@
+XCOMM $XConsortium: Imakefile /main/16 1996/10/28 05:13:04 kaleb $
+
+
+
+
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/Imakefile,v 3.45 1999/08/24 11:24:09 dawes Exp $
+
+#include <Server.tmpl>
+#include <lnxdoc.rules>
+
+SGMLDEPENDS = defs.ent
+ INDEXLIST = README.sgml RELNOTES.sgml LICENSE.sgml DESIGN.sgml \
+ mouse.sgml fonts.sgml isc.sgml \
+ ati.sgml chips.sgml DECtga.sgml s3virge.sgml SiS.sgml
+
+#if 0
+LinuxDocReadmeTarget(Bsdi)
+#endif
+LinuxDocReadmeTarget(DGux)
+LinuxDocReadmeTarget(FreeBSD)
+LinuxDocReadmeTarget(NetBSD)
+LinuxDocReadmeTarget(OpenBSD)
+LinuxDocReadmeTarget(Linux)
+LinuxDocReadmeTarget(LynxOS)
+LinuxDocReadmeTarget(SCO)
+LinuxDocReadmeTarget(isc)
+LinuxDocReadmeTarget(OS2)
+LinuxDocTargetLong(OS2note.sgml,OS2.Notes,OS2Notes)
+LinuxDocReadmeTarget(SOLX86)
+LinuxDocReadmeTarget(SVR4)
+
+/* Hardware docs */
+LinuxDocReadmeTarget(3Dlabs)
+LinuxDocReadmeTarget(DECtga)
+LinuxDocReadmeTarget(I128)
+LinuxDocReadmeTarget(Mach32)
+LinuxDocReadmeTarget(Mach64)
+LinuxDocReadmeTarget(MGA)
+LinuxDocReadmeTarget(NVIDIA)
+LinuxDocReadmeTarget(Oak)
+LinuxDocReadmeTarget(P9000)
+LinuxDocReadmeTarget(Video7)
+LinuxDocReadmeTarget(S3)
+LinuxDocReadmeTarget(SiS)
+LinuxDocReadmeTarget(WstDig)
+LinuxDocReadmeTarget(apm)
+LinuxDocReadmeTarget(ark)
+LinuxDocReadmeTarget(agx)
+LinuxDocReadmeTarget(ati)
+LinuxDocReadmeTarget(chips)
+LinuxDocReadmeTarget(cirrus)
+LinuxDocReadmeTarget(cyrix)
+LinuxDocReadmeTarget(epson)
+LinuxDocReadmeTarget(fbdev)
+LinuxDocReadmeTarget(i740)
+LinuxDocReadmeTarget(neomagic)
+LinuxDocReadmeTarget(rendition)
+LinuxDocReadmeTarget(s3virge)
+LinuxDocReadmeTarget(trident)
+LinuxDocReadmeTarget(tseng)
+
+/* Main docs */
+LinuxDocTarget(LICENSE)
+LinuxDocTarget(RELNOTES)
+#ifdef UPTODATE
+LinuxDocReadmeTarget(Config)
+LinuxDocTarget(BUILD)
+#endif
+LinuxDocTarget(README)
+LinuxDocTarget(DESIGN)
+#ifdef UPTODATE
+LinuxDocTargetLong(QStart.sgml,QuickStart.doc,QuickStart)
+#endif
+LinuxDocTarget(DocIndex)
+
+/* Other docs */
+LinuxDocTarget(xinput)
+LinuxDocReadmeTarget(mouse)
+LinuxDocReadmeTarget(fonts)
+LinuxDocTargetLong(VidModes.sgml,VideoModes.doc,VideoModes)
+#ifdef UPTODATE
+LinuxDocTargetLong(VGADriv.sgml,VGADriver.Doc,VGADriver)
+#endif
+
+index.sgml: $(INDEXLIST) index.pre index.post add.sh Imakefile $(SGMLDEPENDS)
+ RemoveFile(index.sgml)
+ cat index.pre > index.sgml
+ echo "<!-- This file is auto-generated. Do not edit! -->" >> index.sgml
+ for i in $(INDEXLIST); do \
+ $(SHELL) add.sh $$i; \
+ done
+ cat index.post >> index.sgml
+
+LinuxDocTarget(index)
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/LICENSE.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/LICENSE.sgml
new file mode 100644
index 000000000..8b500ca30
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/LICENSE.sgml
@@ -0,0 +1,615 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN"[
+<!ENTITY % defs SYSTEM "defs.ent"> %defs;
+]>
+
+<article>
+<title>Licenses</title>
+<author>The XFree86 Project</author>
+<date>1999</date>
+
+<ident>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/LICENSE.sgml,v 1.5 1999/07/19 13:36:21 dawes Exp $
+</ident>
+
+<sect>XFree86 License
+<p>
+XFree86 code without an explicit copyright is covered by the following
+copyright/license:
+
+<p>
+Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE XFREE86 PROJECT 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 XFree86 Project 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
+XFree86 Project.
+
+<sect>Other Licenses
+<p>
+Portions of code are covered by the following licenses/copyrights:
+
+<sect1>X Consortium
+<p>
+Copyright (C) 1996 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without
+limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense, and/or sell copies of the Software, and to permit persons to
+whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization from
+the X Consortium.
+
+X Window System is a trademark of X Consortium, Inc.
+
+<sect1>Berkeley-based copyrights:
+<p>
+<sect2>General
+<p>
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+<enum>
+<item>Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+<item>Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+<item>The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+</enum>
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+<sect2>UCB/LBL
+<p>
+ Copyright (c) 1993
+ The Regents of the University of California. All rights reserved.
+
+ This software was developed by the Computer Systems Engineering group
+ at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ contributed to Berkeley.
+
+ All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ This product includes software developed by the University of
+ California, Lawrence Berkeley Laboratory.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+<enum>
+<item>Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+<item>Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+<item>All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ This product includes software developed by the University of
+ California, Berkeley and its contributors.
+<item>Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+</enum>
+
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+<sect1>NVIDIA Corp
+<p>
+ Copyright (c) 1996 NVIDIA, Corp. All rights reserved.
+
+ NOTICE TO USER: The source code is copyrighted under U.S. and
+ international laws. NVIDIA, Corp. of Sunnyvale, California owns
+ the copyright and as design patents pending on the design and
+ interface of the NV chips. Users and possessors of this source
+ code are hereby granted a nonexclusive, royalty-free copyright
+ and design patent license to use this code in individual and
+ commercial software.
+
+ Any use of this source code must include, in the user documentation
+ and internal comments to the code, notices to the end user
+ as follows:
+
+ Copyright (c) 1996 NVIDIA, Corp. NVIDIA design patents pending
+ in the U.S. and foreign countries.
+
+ NVIDIA, CORP. MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF
+ THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT
+ EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORP. DISCLAIMS
+ ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, INCLUDING ALL
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA, CORP. BE LIABLE
+ FOR ANY SPECIAL, INDIRECT, INCIDENTAL, 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 SOURCE CODE.
+
+<sect1>GLX Public License
+<p>
+GLX PUBLIC LICENSE (Version 1.0 (2/11/99)) ("License")
+
+Subject to any third party claims, Silicon Graphics, Inc. ("SGI") hereby
+grants permission to Recipient (defined below), under Recipient's
+copyrights in the Original Software (defined below), to use, copy,
+modify, merge, publish, distribute, sublicense and/or sell copies of
+Subject Software (defined below), and to permit persons to whom the
+Subject Software is furnished in accordance with this License to do the
+same, subject to all of the following terms and conditions, which
+Recipient accepts by engaging in any such use, copying, modifying,
+merging, publishing, distributing, sublicensing or selling:
+
+1. Definitions.
+
+<quote>
+ (a) "Original Software" means source code of computer software code
+ which is described in Exhibit A as Original Software.
+</quote>
+
+<quote>
+ (b) "Modifications" means any addition to or deletion from the
+ substance or structure of either the Original Software or any
+ previous Modifications. When Subject Software is released as a
+ series of files, a Modification means (i) any addition to or
+ deletion from the contents of a file containing Original Software or
+ previous Modifications and (ii) any new file that contains any part
+ of the Original Code or previous Modifications.
+</quote>
+
+<quote>
+ (c) "Subject Software" means the Original Software or Modifications
+ or the combination of the Original Software and Modifications, or
+ portions of any of the foregoing.
+</quote>
+
+<quote>
+ (d) "Recipient" means an individual or a legal entity exercising
+ rights under, and complying with all of the terms of, this License.
+ For legal entities, "Recipient" includes any entity which controls,
+ is controlled by, or is under common control with Recipient. For
+ purposes of this definition, "control" of an entity means (a) the
+ power, direct or indirect, to direct or manage such entity, or (b)
+ ownership of fifty percent (50%) or more of the outstanding shares
+ or beneficial ownership of such entity.
+</quote>
+
+2. Redistribution of Source Code Subject to These Terms. Redistributions
+of Subject Software in source code form must retain the notice set forth
+in Exhibit A, below, in every file. A copy of this License must be
+included in any documentation for such Subject Software where the
+recipients' rights relating to Subject Software are described. Recipient
+may distribute the source code version of Subject Software under a
+license of Recipient's choice, which may contain terms different from
+this License, provided that (i) Recipient is in compliance with the
+terms of this License, and (ii) the license terms include this Section 2
+and Sections 3, 4, 7, 8, 10, 12 and 13 of this License, which terms may
+not be modified or superseded by any other terms of such license. If
+Recipient distributes the source code version under a different license
+Recipient must make it absolutely clear that any terms which differ from
+this License are offered by Recipient alone, not by SGI. Recipient
+hereby agrees to indemnify SGI for any liability incurred by SGI as a
+result of any such terms Recipient offers.
+
+3. Redistribution in Executable Form. The notice set forth in Exhibit A
+must be conspicuously included in any notice in an executable version of
+Subject Software, related documentation or collateral in which Recipient
+describes the user's rights relating to the Subject Software. Recipient
+may distribute the executable version of Subject Software under a
+license of Recipient's choice, which may contain terms different from
+this License, provided that (i) Recipient is in compliance with the
+terms of this License, and (ii) the license terms include this Section 3
+and Sections 4, 7, 8, 10, 12 and 13 of this License, which terms may not
+be modified or superseded by any other terms of such license. If
+Recipient distributes the executable version under a different license
+Recipient must make it absolutely clear that any terms which differ from
+this License are offered by Recipient alone, not by SGI. Recipient
+hereby agrees to indemnify SGI for any liability incurred by SGI as a
+result of any such terms Recipient offers.
+
+4. Termination. This License and the rights granted hereunder will
+terminate automatically if Recipient fails to comply with terms herein
+and fails to cure such breach within 30 days of the breach. Any
+sublicense to the Subject Software which is properly granted shall
+survive any termination of this License absent termination by the terms
+of such sublicense. Provisions which, by their nature, must remain in
+effect beyond the termination of this License shall survive.
+
+5. No Trademark Rights. This License does not grant any rights to use
+any trade name, trademark or service mark whatsoever. No trade name,
+trademark or service mark of SGI may be used to endorse or promote
+products derived from the Subject Software without prior written
+permission of SGI.
+
+6. No Other Rights. This License does not grant any rights with respect
+to the OpenGL API or to any software or hardware implementation thereof
+or to any other software whatsoever, nor shall any other rights or
+licenses not expressly granted hereunder arise by implication, estoppel
+or otherwise with respect to the Subject Software. Title to and
+ownership of the Original Software at all times remains with SGI. All
+rights in the Original Software not expressly granted under this License
+are reserved.
+
+7. Compliance with Laws; Non-Infringement. Recipient shall comply with
+all applicable laws and regulations in connection with use and
+distribution of the Subject Software, including but not limited to, all
+export and import control laws and regulations of the U.S. government
+and other countries. Recipient may not distribute Subject Software that
+(i) in any way infringes (directly or contributorily) the rights
+(including patent, copyright, trade secret, trademark or other
+intellectual property rights of any kind) of any other person or entity
+or (ii) breaches any representation or warranty, express, implied or
+statutory, which under any applicable law it might be deemed to have
+been distributed.
+
+8. Claims of Infringement. If Recipient at any time has knowledge of any
+one or more third party claims that reproduction, modification, use,
+distribution, import or sale of Subject Software (including particular
+functionality or code incorporated in Subject Software) infringes the
+third party's intellectual property rights, Recipient must place in a
+well-identified web page bearing the title "LEGAL" a description of each
+such claim and a description of the party making each such claim in
+sufficient detail that a user of the Subject Software will know whom to
+contact regarding the claim. Also, upon gaining such knowledge of any
+such claim, Recipient must conspicuously include the URL for such web
+page in the Exhibit A notice required under Sections 2 and 3, above, and
+in the text of any related documentation, license agreement or
+collateral in which Recipient describes end user's rights relating to
+the Subject Software. If Recipient obtains such knowledge after it makes
+Subject Software available to any other person or entity, Recipient
+shall take other steps (such as notifying appropriate mailing lists or
+newsgroups) reasonably calculated to inform those who received the
+Subject Software that new knowledge has been obtained.
+
+9. DISCLAIMER OF WARRANTY. SUBJECT SOFTWARE IS PROVIDED ON AN "AS IS"
+BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE SUBJECT SOFTWARE IS
+FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-
+INFRINGING. SGI ASSUMES NO RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+SOFTWARE. SHOULD ANY SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, SGI
+ASSUMES NO COST OR LIABILITY FOR ANY SERVICING, REPAIR OR CORRECTION.
+THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
+LICENSE. NO USE OF ANY SUBJECT SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT
+UNDER THIS DISCLAIMER.
+
+10. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL
+THEORY, WHETHER TORT (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE OR
+STRICT LIABILITY), CONTRACT, OR OTHERWISE, SHALL SGI OR ANY SGI LICENSOR
+BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
+CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION,
+DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, LOSS OF DATA, COMPUTER
+FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR
+LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY
+OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO
+LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SGI's NEGLIGENCE
+TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME
+JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR
+CONSEQUENTIAL DAMAGES, SO THAT EXCLUSION AND LIMITATION MAY NOT APPLY TO
+RECIPIENT.
+
+11. Indemnity. Recipient shall be solely responsible for damages
+arising, directly or indirectly, out of its utilization of rights under
+this License. Recipient will defend, indemnify and hold harmless Silicon
+Graphics, Inc. from and against any loss, liability, damages, costs or
+expenses (including the payment of reasonable attorneys fees) arising
+out of Recipient's use, modification, reproduction and distribution of
+the Subject Software or out of any representation or warranty made by
+Recipient.
+
+12. U.S. Government End Users. The Subject Software is a "commercial
+item" consisting of "commercial computer software" as such terms are
+defined in title 48 of the Code of Federal Regulations and all U.S.
+Government End Users acquire only the rights set forth in this License
+and are subject to the terms of this License.
+
+13. Miscellaneous. This License represents the complete agreement
+concerning subject matter hereof. If any provision of this License is
+held to be unenforceable, such provision shall be reformed so as to
+achieve as nearly as possible the same economic effect as the original
+provision and the remainder of this License will remain in effect. This
+License shall be governed by and construed in accordance with the laws
+of the United States and the State of California as applied to
+agreements entered into and to be performed entirely within California
+between California residents. Any litigation relating to this License
+shall be subject to the exclusive jurisdiction of the Federal Courts of
+the Northern District of California (or, absent subject matter
+jurisdiction in such courts, the courts of the State of California),
+with venue lying exclusively in Santa Clara County, California, with the
+losing party responsible for costs, including without limitation, court
+costs and reasonable attorneys fees and expenses. The application of the
+United Nations Convention on Contracts for the International Sale of
+Goods is expressly excluded. Any law or regulation which provides that
+the language of a contract shall be construed against the drafter shall
+not apply to this License.
+
+Exhibit A
+
+The contents of this file are subject to Sections 2, 3, 4, 7, 8, 10, 12
+and 13 of the GLX Public License Version 1.0 (the "License"). You may
+not use this file except in compliance with those sections of the
+License. You may obtain a copy of the License at Silicon Graphics, Inc.,
+attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
+or at http://www.sgi.com/software/opensource/glx/license.html.
+
+Software distributed under the License is distributed on an "AS IS"
+basis. ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY
+IMPLIED WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
+PURPOSE OR OF NON- INFRINGEMENT. See the License for the specific
+language governing rights and limitations under the License.
+
+The Original Software is GLX version 1.2 source code, released February,
+1999. The developer of the Original Software is Silicon Graphics, Inc.
+Those portions of the Subject Software created by Silicon Graphics, Inc.
+are Copyright (c) 1991-9 Silicon Graphics, Inc. All Rights Reserved.
+
+<sect1>CID Font Code Public License
+<p>
+CID FONT CODE PUBLIC LICENSE (Version 1.0 (3/31/99))("License")
+
+Subject to any applicable third party claims, Silicon Graphics, Inc. ("SGI")
+hereby grants permission to Recipient (defined below), under SGI's copyrights
+in the Original Software (defined below), to use, copy, modify, merge, publish,
+distribute, sublicense and/or sell copies of Subject Software (defined below)
+in both source code and executable form, and to permit persons to whom the
+Subject Software is furnished in accordance with this License to do the same,
+subject to all of the following terms and conditions, which Recipient accepts
+by engaging in any such use, copying, modifying, merging, publication,
+distributing, sublicensing or selling:
+
+1. Definitions.
+<quote>
+ a. "Original Software" means source code of computer software code
+ that is described in Exhibit A as Original Software.
+</quote>
+
+<quote>
+ b. "Modifications" means any addition to or deletion from the
+ substance or structure of either the Original Software or any
+ previous Modifications. When Subject Software is released as a
+ series of files, a Modification means (i) any addition to or
+ deletion from the contents of a file containing Original Software
+ or previous Modifications and (ii) any new file that contains any
+ part of the Original Code or previous Modifications.
+</quote>
+
+<quote>
+ c. "Subject Software" means the Original Software or Modifications
+ or the combination of the Original Software and Modifications, or
+ portions of any of the foregoing.
+</quote>
+
+<quote>
+ d. "Recipient" means an individual or a legal entity exercising
+ rights under the terms of this License. For legal entities,
+ "Recipient" includes any entity that controls, is controlled by,
+ or is under common control with Recipient. For purposes of this
+ definition, "control" of an entity means (i) the power, direct or
+ indirect, to direct or manage such entity, or (ii) ownership of
+ fifty percent (50%) or more of the outstanding shares or
+ beneficial ownership of such entity.
+</quote>
+
+<quote>
+ e. "Required Notice" means the notice set forth in Exhibit A to this
+ License.
+</quote>
+
+<quote>
+ f. "Accompanying Technology" means any software or other technology
+ that is not a Modification and that is distributed or made
+ publicly available by Recipient with the Subject Software.
+ Separate software files that do not contain any Original Software
+ or any previous Modification shall not be deemed a Modification,
+ even if such software files are aggregated as part of a product,
+ or in any medium of storage, with any file that does contain
+ Original Software or any previous Modification.
+</quote>
+
+ 2. License Terms. All distribution of the Subject Software must be made
+ subject to the terms of this License. A copy of this License and the
+ Required Notice must be included in any documentation for Subject
+ Software where Recipient's rights relating to Subject Software and/or
+ any Accompanying Technology are described. Distributions of Subject
+ Software in source code form must also include the Required Notice in
+ every file distributed. In addition, a ReadMe file entitled "Important
+ Legal Notice" must be distributed with each distribution of one or more
+ files that incorporate Subject Software. That file must be included with
+ distributions made in both source code and executable form. A copy of
+ the License and the Required Notice must be included in that file.
+ Recipient may distribute Accompanying Technology under a license of
+ Recipient's choice, which may contain terms different from this License,
+ provided that (i) Recipient is in compliance with the terms of this
+ License, (ii) such other license terms do not modify or supersede the
+ terms of this License as applicable to the Subject Software, (iii)
+ Recipient hereby indemnifies SGI for any liability incurred by SGI as a
+ result of the distribution of Accompanying Technology or the use of
+ other license terms.
+
+ 3. Termination. This License and the rights granted hereunder will
+ terminate automatically if Recipient fails to comply with terms herein
+ and fails to cure such breach within 30 days of the breach. Any
+ sublicense to the Subject Software that is properly granted shall
+ survive any termination of this License absent termination by the terms
+ of such sublicense. Provisions which, by their nature, must remain in
+ effect beyond the termination of this License shall survive.
+
+ 4. Trademark Rights. This License does not grant any rights to use any
+ trade name, trademark or service mark whatsoever. No trade name,
+ trademark or service mark of SGI may be used to endorse or promote
+ products derived from or incorporating any Subject Software without
+ prior written permission of SGI.
+
+ 5. No Other Rights. No rights or licenses not expressly granted hereunder
+ shall arise by implication, estoppel or otherwise. Title to and
+ ownership of the Original Software at all times remains with SGI. All
+ rights in the Original Software not expressly granted under this
+ License are reserved.
+
+ 6. Compliance with Laws; Non-Infringement. Recipient shall comply with all
+ applicable laws and regulations in connection with use and distribution
+ of the Subject Software, including but not limited to, all export and
+ import control laws and regulations of the U.S. government and other
+ countries. Recipient may not distribute Subject Software that (i) in any
+ way infringes (directly or contributorily) the rights (including patent,
+ copyright, trade secret, trademark or other intellectual property rights
+ of any kind) of any other person or entity, or (ii) breaches any
+ representation or warranty, express, implied or statutory, which under
+ any applicable law it might be deemed to have been distributed.
+
+ 7. Claims of Infringement. If Recipient at any time has knowledge of any
+ one or more third party claims that reproduction, modification, use,
+ distribution, import or sale of Subject Software (including particular
+ functionality or code incorporated in Subject Software) infringes the
+ third party's intellectual property rights, Recipient must place in a
+ well-identified web page bearing the title "LEGAL" a description of
+ each such claim and a description of the party making each such claim in
+ sufficient detail that a user of the Subject Software will know whom to
+ contact regarding the claim. Also, upon gaining such knowledge of any
+ such claim, Recipient must conspicuously include the URL for such web
+ page in the Required Notice, and in the text of any related
+ documentation, license agreement or collateral in which Recipient
+ describes end user's rights relating to the Subject Software. If
+ Recipient obtains such knowledge after it makes Subject Software
+ available to any other person or entity, Recipient shall take other
+ steps (such as notifying appropriate mailing lists or newsgroups)
+ reasonably calculated to provide such knowledge to those who received
+ the Subject Software.
+
+ 8. DISCLAIMER OF WARRANTY. SUBJECT SOFTWARE IS PROVIDED ON AN "AS IS"
+ BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+ INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE SUBJECT SOFTWARE IS
+ FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR
+ NON-INFRINGING. SGI ASSUMES NO RISK AS TO THE QUALITY AND PERFORMANCE
+ OF THE SOFTWARE. SHOULD ANY SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, SGI
+ ASSUMES NO COST OR LIABILITY FOR ANY SERVICING, REPAIR OR CORRECTION.
+ THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
+ LICENSE. NO USE OF ANY SUBJECT SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT
+ UNDER THIS DISCLAIMER.
+
+ 9. LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL
+ THEORY, WHETHER TORT (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE OR
+ STRICT LIABILITY), CONTRACT, OR OTHERWISE, SHALL SGI OR ANY SGI LICENSOR
+ 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 SUBJECT SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SUBJECT SOFTWARE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR
+ LIMITATION OF CERTAIN DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT
+ APPLY TO RECIPIENT TO THE EXTENT SO DISALLOWED.
+
+ 10. Indemnity. Recipient shall be solely responsible for damages arising,
+ directly or indirectly, out of its utilization of rights under this
+ License. Recipient will defend, indemnify and hold SGI and its
+ successors and assigns harmless from and against any loss, liability,
+ damages, costs or expenses (including the payment of reasonable
+ attorneys fees) arising out of (Recipient's use, modification,
+ reproduction and distribution of the Subject Software or out of any
+ representation or warranty made by Recipient.
+
+ 11. U.S. Government End Users. The Subject Software is a "commercial item"
+ consisting of "commercial computer software" as such terms are defined
+ in title 48 of the Code of Federal Regulations and all U.S. Government
+ End Users acquire only the rights set forth in this License and are
+ subject to the terms of this License.
+
+ 12. Miscellaneous. This License represents the complete agreement concerning
+ subject matter hereof. If any provision of this License is held to be
+ unenforceable by any judicial or administrative authority having proper
+ jurisdiction with respect thereto, such provision shall be reformed so
+ as to achieve as nearly as possible the same economic effect as the
+ original provision and the remainder of this License will remain in
+ effect. This License shall be governed by and construed in accordance
+ with the laws of the United States and the State of California as
+ applied to agreements entered into and to be performed entirely within
+ California between California residents. Any litigation relating to
+ this License shall be subject to the exclusive jurisdiction of the
+ Federal Courts of the Northern District of California (or, absent
+ subject matter jurisdiction in such courts, the courts of the State of
+ California), with venue lying exclusively in Santa Clara County,
+ California, with the losing party responsible for costs, including
+ without limitation, court costs and reasonable attorneys fees and
+ expenses. The application of the United Nations Convention on Contracts
+ for the International Sale of Goods is expressly excluded. Any law or
+ regulation that provides that the language of a contract shall be
+ construed against the drafter shall not apply to this License.
+
+Exhibit A
+
+Copyright (c) 1994-1999 Silicon Graphics, Inc.
+
+The contents of this file are subject to the CID Font Code Public License
+Version 1.0 (the "License"). You may not use this file except in compliance
+with the License. You may obtain a copy of the License at Silicon Graphics,
+Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA 94043
+or at http://www.sgi.com/software/opensource/cid/license.html
+
+Software distributed under the License is distributed on an "AS IS" basis.
+ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED
+WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF
+NON-INFRINGEMENT. See the License for the specific language governing rights
+and limitations under the License.
+
+The Original Software (as defined in the License) is CID font code that was
+developed by Silicon Graphics, Inc. Those portions of the Subject Software
+(as defined in the License) that were created by Silicon Graphics, Inc. are
+Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved.
+
+[NOTE: When using this text in connection with Subject Software delivered
+solely in object code form, Recipient may replace the words "this file" with
+"this software" in both the first and second sentences.]
+
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/Linux.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/Linux.sgml
new file mode 100644
index 000000000..6d8c0f074
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/Linux.sgml
@@ -0,0 +1,149 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+
+<title>Information for Linux Users
+<author>Orest Zborowski, Dirk Hohndel
+<date>June 25, 1999
+<toc>
+
+<sect>Linux versions on which XFree86 has been tested <p>
+XFree86 has been tested with Linux version 2.0.36, 2.2.7 and several
+2.3.x kernels.
+It should work with any version since 1.0 without change.
+Binaries both against libc5 and libc6 are available.
+
+<sect>Backwards Compatibility <p>
+X11R6 is considered a major update from X11R5, so the shared
+libraries in XFree86 3.1 and later are not compatible with XFree86 2.1.1
+and older libraries. To continue to run X11R5 applications, you must keep
+the old libraries somewhere on your machine. They can be moved from
+<tt>/usr/X386/lib</tt> elsewhere, but <tt>/etc/ld.so.conf</tt> must be updated.
+All X11R5 applications should work with the X11R6 servers without problems.
+
+X11R6.1 is yet another update to X11R6. While the minor number for some
+libraries has been increased to '1' it is believed to be fully
+compatible with X11R6 based applications.
+
+X11R6.3 is yet another update to X11R6.1. While the minor number for some
+libraries has been increased to '3' it is believed to be fully
+compatible with X11R6 based applications.
+
+Very old binaries (linked to XFree86-1.2, XFree86-1.3 or
+XFree86-2.0 libraries) will continue to work, but may need an explicit
+symlink from <tt>/lib/libX{11,t,aw}.so.3</tt> to
+<tt>/usr/X386/lib/libX{11,t,aw}.so.3</tt>.
+
+<sect>Installing XFree86 <p>
+Starting with version 3.0, XFree86 is installed in <tt>/usr/X11R6</tt>.
+The installation details are provided in the <htmlurl name="RELNOTES"
+url="RELNOTES.html">.
+
+<sect>Running XFree86 <p>
+XFree86 requires about 4mb of virtual memory to run, although
+having 16mb of RAM is probably the minimum comfortable configuration. A 387
+coprocessor is helpful for 386 machines, although greater gains in
+interactive performance are obtained with an increase in physical memory.
+Also, a faster graphics card, bus or RAM, will improve server performance.
+
+After unpacking the tar files, you need to include <tt>/usr/X11R6/lib</tt>
+in <tt>/etc/ld.so.conf</tt> (where it should already be by default) or in your
+<tt>LD_LIBRARY_PATH</tt> environment variable. Also, the configuration file
+<tt>/etc/XF86Config</tt> or <tt>/usr/X11R6/lib/X11/XF86Config</tt>
+<em>must</em> be properly filled out
+based on the host setup. Ideally this is done using <tt>XF86Setup</tt> or (if
+for some reason this doesn't work) using <tt>xf86config</tt>. If you really
+insist in hand-creating your config file use <tt>XF86Config.eg</tt> as a
+starting point and <tt>README.Config</tt> as
+guideline. You may damage your hardware if you use a wrong
+<tt>XF86Config</tt> file, so <em>read the docs</em>,
+especially the man pages and the other <tt>README</tt> files in
+<tt>/usr/X11R6/lib/X11/doc</tt>.
+
+XFree86 has the ability to perform VT switching to and from the X
+server. When first started, XFree86 will automatically locate the first
+available VT (one that hasn't been opened by any process), and run on that
+VT. If there isn't one available, XFree86 will terminate with an error
+message. The server can be run on a specific VT by using the
+``vt&lt;nn&gt;'' option, where
+ &lt;nn&gt; is the number of an available VT (starting from 1). If
+you don't have a free VT XFree86 cannot run. Normally you can simply disable
+one of the <tt>getty</tt> programs in <tt>/etc/inittab</tt>, but if this is
+not an option, you can increase the number of
+available VTs by increasing the value of <tt>NR_CONSOLES</tt> in
+<tt>include/linux/tty.h</tt> and recompiling the kernel.
+
+Once running inside X, switching to another VT is accomplished by
+pressing Ctrl-Alt-&lt;Fnn&gt; where nn is the number of the VT to switch to.
+To return to the server, press the proper key-combination that moves you back
+to the VT that XFree86 is using: by default, this is Alt-&lt;Fmm&gt;, where
+mm is the number of the VT the server is running on (this number is printed
+when the server is started). Note that this is NOT the VT from which the
+server was started.
+
+NOTE: you can redefine the text-mode keybindings with the
+`<tt>loadkeys</tt>' command found in the <tt>kbd-0.81.tar.gz</tt>
+archive (or a later version thereof).
+With this, you can (for example) make Ctrl-Alt-&lt;Fmm&gt; work from text mode
+the same way it works under the XFree86 server.
+
+When the server is exited, it will return to the original VT it was
+started from, unless it dies unexpectedly, when the switch must be done
+manually. There still seem to be weird combinations of graphic cards and
+motherboards that have problems to restore the textfont when returning from
+XFree86 to the text mode. In these cases using the <tt>runx</tt> script from
+the <bf>svgalib</bf> distribution might help.
+
+The XFree86 server now queries the kernel to obtain the key binding
+in effect at startup. These bindings are either the default map in place
+when the kernel was compiled, or reloaded using the
+`<tt>loadkeys</tt>' utility. Not
+all keys are bound: kernel-specific, multiple keysym, and dead keys are not
+handled by the server. All others are translated to their X equivalents.
+Note that the XFree86 server only allows for four modifier maps: unshifted,
+shifted, modeswitch unshifted and modeswitch shifted. Depending on what
+the modeswitch key is (it is configurable in your <tt>XF86Config</tt> and defaults
+to Alt),
+XFree86 will read those tables into its keymaps. This means if you use
+certain keys, like left-Control, for Linux modeswitch, that will not be
+mappable to X.
+
+<sect>Installing Xdm, the display manager
+<p>
+
+Since xdm is dynamically linked, there's no issue on
+export restriction outside US for this binary distribution of xdm: it
+does not contain the DES encryption code. So it's now included in the
+bin package.
+
+However the file <tt>xc/lib/Xdmcp/WrapHelp.c</tt> is not included in the
+XFree86-3.3 source, so support for
+XDM-AUTHORIZATION-1 is not included here. You'll have to get
+WrapHelp.c and rebuild xdm after having set <tt/HasXdmAuth/ in
+<tt/xf86site.def/.
+
+The file is available within the US; for
+details see <htmlurl name="ftp.x.org:/pub/R6/xdm-auth/README"
+url="ftp://ftp.x.org/pub/R6/xdm-auth/README">.
+
+To start the display manager, log in as root on the console and type:
+``<tt/xdm -nodaemon/''.
+
+You can start xdm automatically on bootup by disabling the console getty
+and modifying <tt>/etc/inittab</tt>. Details about this setup depend on the
+Linux distribution that you use, so check the documentation provided there.
+
+The xdm binary provided should run with both shadow- and non-shadow password
+systems.
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/Linux.sgml,v 3.14 1999/08/23 06:38:46 dawes Exp $
+
+
+
+
+
+$XConsortium: Linux.sgml /main/6 1996/10/28 04:47:37 kaleb $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/LynxOS.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/LynxOS.sgml
new file mode 100644
index 000000000..992c14123
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/LynxOS.sgml
@@ -0,0 +1,552 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+
+<title>README for XFree86 on LynxOS
+<author>Thomas Mueller
+<date>Last modified on: 30 May 1999
+<toc>
+
+<sect>What and Where is XFree86?<p>
+XFree86 is a port of X11R6.3 that supports several versions of
+Intel-based Unix. It is derived from X386 1.2, which was the X server
+distributed with X11R5. This release consists of many new features
+and performance improvements as well as many bug fixes. The release
+is available as source patches against the X Consortium X11R6.3 code, as
+well as binary distributions for many architectures.
+
+See the Copyright Notice in <htmlurl url="COPYRIGHT.html"
+name="Copyright Notice">.
+
+The sources for XFree86 are available by anonymous ftp from:
+
+<htmlurl name="ftp://ftp.XFree86.org/pub/XFree86/current"
+url="ftp://ftp.XFree86.org/pub/XFree86/current">
+
+Binaries of XFree86 for LynxOS AT are available from:
+
+<htmlurl name="ftp://ftp.XFree86.org/pub/XFree86/current/binaries/LynxOS"
+url="ftp://ftp.XFree86.org/pub/XFree86/current/binaries/LynxOS">
+
+The binaries were built on `LynxOS x86 3.0.1'. Because of changes
+made to the object format they don't run on LynxOS versions earlier
+than 3.0.0.
+
+Building of this XFree86 version has never been tested on LynxOS versions
+earlier than 2.4.0. Binaries built on LynxOS 2.4.0 are expected to run
+on 2.3.0 as well.
+
+XFree86 supports LynxOS on the AT, on the microSPARC and
+on the PowerPC platform. X servers are currently available on
+the AT and microSPARC platform. Refer to section <ref id="others"
+name="Building on microSPARC and PowerPC"> for details on XFree86
+on the non-AT platforms.
+
+If you need binaries for other platforms than the one on the
+XFree86 FTP server contact me (<htmlurl name="tmueller@sysgo.de"
+url="mailto:tmueller@sysgo.de">).
+
+Send email to <it>tmueller@sysgo.de</it> (Thomas Mueller) or
+<it>XFree86@XFree86.org</it> if you have comments or suggestions about
+this file and we'll revise it.
+
+<sect>Installing the Binaries
+<p>
+Please refer to section "Installing the XFree86 3.3.4 Release" of the
+<htmlurl url="RELNOTES.html" name="Release Notes"> for detailed
+installation instructions.
+
+If you plan to install XF86Setup you'll have to install
+<tt/X333prog/ as well since XF86Setup checks for the existence of
+a certain file name pattern which is satisfied only if you install
+the library files from <tt/X333prog/.
+
+It may be necessary to increase the process stack limit in order to
+run XFree86 on your system. Edit <tt>/etc/startab</tt> and reboot your
+system to make the changes active before you begin the installation.
+
+Also, be sure to include <tt>/usr/X11R6/bin</tt> in your PATH
+environment variable.
+
+Refer to the next section <ref id="running" name="Running XFree86"> for
+further information on necessary configuration steps before running
+XFree86 on LynxOS.
+
+<sect>Running XFree86<p><label id="running">
+
+This section describes the changes to the LynxOS environment
+which may be necessary to successfully run XFree86.
+
+Read <htmlurl url="QuickStart.html" name="Quick-Start Guide
+to XFree86 Setup"> to learn more about how to configure XFree86 for
+your hardware.
+
+<sect1>System requirements<p>
+ A minimum of 16MB of memory is required to run X. If you want to run
+ real-world applications you should think of upgrading to 32MB (or more).
+
+<sect1>System tuning<p>
+<sect2>Tunable parameters<p>
+ To reasonably run XFree86 you may have to adjust a few system parameters.
+
+ On LynxOS 2.5.x and 3.0.x include a line
+<verb>
+ #define X_WINDOWS
+</verb>
+
+ in <tt>/sys/lynx.os/uparam.h</tt>.
+
+ For earlier versions you'll have to edit <tt>/usr/include/param.h</tt>:
+<verb>
+ Tunable Old New
+ USR_NFDS number of open files per process 20 64
+ NPROC number of tasks 50 150
+ NFILES number of open files in system 100 250
+ NINODES number of incore inodes (same value as NFILES)
+ QUANTUM clock ticks until preemption 64 20
+ CACHEBLKS number of cache memory blocks 202 >= 4096
+</verb>
+
+ The new values are those suggested by the LynxOS documentation for
+ their X Window package.
+
+<sect2>Adjustment for Riva 128 and Riva TNT driver>
+
+If you're using the nVidia driver (Riva 128, TNT, TNT2) of the SVGA
+server, you will have to increase the value of the SMEMS parameter in
+<tt>/sys/lynx.os/uparam.h</tt> from 10 to 20.
+
+<sect2>Increase number of ptys<p>
+
+ You should also increase the number of ptys to be able run a couple
+ more xterms. You may replace <tt>/sys/lynx.os/pty.cfg</tt> with
+ <tt>/usr/X11R6/lib/X11/etc/pty.cfg</tt>.
+
+<sect2>Kernel build<p>
+
+ If you plan to use PS/2 or Bus mice refer to the following section
+ before rebuilding the kernel, if not, you should rebuild the kernel
+ now:
+
+ <tscreen><verb>
+ # cd /sys/lynx.os
+ # make install
+ # reboot -N
+ </verb></tscreen>
+
+<sect1>Mouse support in XFree86<p>
+
+ XFree86 includes support for PnP mice (see also
+ <htmlurl url="mouse.html" name="Mouse Support in XFree86">). The
+ current LynxOS TTY device driver doesn't allow the necessary
+ manipulation of the RTS line and therefore the support for
+ PnP mice has been disabled for LynxOS.
+
+<sect1>Bus mouse drivers<p>
+
+ Starting with LynxOS AT 2.4.0 LynxOS includes a PS/2 mouse driver.
+ Currently this driver is not fully supported by XFree86 (you'll
+ probably have to specify the mouse type as <em>Microsoft</em>
+ regardless of real mouse type and in some cases you won't have
+ all mouse buttons supported).
+ <tt>/usr/X11R6/lib/X11/etc/BM-Lynx.shar</tt> contains a LynxOS port
+ of the Linux bus mouse drivers. To install the drivers
+ unpack the shar archive
+
+ <tscreen><verb>
+ # cd /
+ # bash /usr/X11R6/lib/X11/etc/BM-Lynx.shar
+ </verb></tscreen>
+
+ and follow the notes in <tt>/BMOUSE.Readme</tt> for further installation and
+ configuration notes.
+
+ The XFree86 PS/2 mouse driver works also with MetroLink X 2.3.3.1 as
+ shipped with LynxOS AT 2.4.0 unless you have the LynxOS patch
+ 000055-00 installed.
+
+<sect1> ATC console driver and VT switching<p>
+
+ The XFree86 servers will only run with the default LynxOS console
+ driver, sorry for those of you who use the alternative vdt console
+ driver. Currently there is no support for virtual terminal switching
+ once the server has started.
+
+ You will need a free console which the X server will use for
+ keyboard input. You must disable login on at least one of the four
+ virtual terminals in <tt>/etc/ttys</tt>, e.g. <tt>/dev/atc3</tt>:
+
+ <tscreen>
+ change
+ <verb>
+ /dev/atc3:1:default:vt100at:/bin/login
+ </verb>
+ to
+ <verb>
+ /dev/atc3:0:default:vt100at:/bin/login
+ ^
+ </verb></tscreen>
+
+<sect1>X Server debug diagnostics output and other VT peculiarities<p>
+
+ The XFree86 X servers will produce a lot of diagnostics output on
+ stderr during startup. This output will be lost after the server
+ reached a certain point in its console initialization process. You
+ should redirect stdout and stderr if you want to analyze the
+ diagnostics produced by the server.
+
+ When the X server is running output made to other consoles will be
+ lost. After server shutdown the screen contents of other consoles
+ may be inconsistent with what one would expect (i.e. random).
+
+<sect>Installing XFree86 manual pages<p><label id="installman">
+
+ LynxOS uses cat-able manual pages, and because a doc preparation
+ system is definitely not a vital component of a real-time operating
+ system you must first install groff-1.09 (or newer). Starting with
+ LynxOS 2.3.0 it should compile right out of the box (or better tar archive).
+
+ XFree86 manual pages may be installed using
+
+ <tscreen><verb>
+ make install.man
+ </verb></tscreen>
+
+ The index and whatis database for the XFree86 manual pages will be
+ created automatically. If you already have a whatis database or
+ index file in the destination directories you should perform a
+ sort/uniq operation to remove duplicate entries:
+
+ <tscreen><verb>
+ for i in 1 3 5
+ do
+ rm -f /tmp/tmpfile
+ sort /usr/X11R6/man/cat$i/LIST$i | uniq > /tmp/tmpfile
+ mv /tmp/tmpfile /usr/X11R6/man/cat$i/LIST$i
+ done
+ sort /usr/X11R6/man/whatis | uniq > /tmp/tmpfile
+ mv /tmp/tmpfile /usr/X11R6/man/whatis
+ </verb></tscreen>
+
+ With LynxOS 2.3.0 you should include <tt>/usr/X11R6/man</tt> in the MANPATH
+ environment variable.
+
+ <tscreen>
+ bash: <tt>MANPATH=&dollar;MANPATH:/usr/X11R6/man</tt>
+ </tscreen>
+
+ The man command of LynxOS 2.2.1 does not support the MANPATH
+ environment variable properly. The XFree86 manual pages must be
+ copied (or linked) to the standard manual page locations
+ (<tt>/usr/man/catx</tt>) in order to be read the man command:
+
+ <tscreen><verb>
+ for i in 1 3 5
+ do
+ ln -s /usr/X11R6/man/cat$i/*.* /usr/man/cat$i
+ cat /usr/X11R6/man/cat$i/LIST$i >> /usr/man/cat$i/LIST$i
+ sort -o /usr/man/cat$i/LIST$i /usr/man/cat$i/LIST$i
+ cat /usr/X11R6/man/cat$i/whatis$i >> /usr/man/whatis
+ done
+ </verb></tscreen>
+
+<sect>Using XFree86 with Motif<p>
+
+ The Motif libraries shipped with LynxOS AT 2.3.0 and 2.4.0 can be
+ used with the XFree86 libraries. Follow the steps outlined below after
+ you have installed XFree86 and LynxOS Motif on your system.
+
+<sect1>Copy Motif files<p>
+
+ You must create symbolic links for the Motif libraries and
+ utilities in the <tt>/usr/X11R6</tt> directory tree.
+ <tscreen><verb>
+ ln -s /usr/bin/X11/uil /usr/X11R6/bin
+ ln -s /usr/lib/libUil.a /usr/X11R6/lib
+ ln -s /usr/lib/libMrm.a /usr/X11R6/lib
+ ln -s /usr/lib/libXm.a /usr/X11R6/lib
+ ln -s /usr/lib/X11/uid /usr/X11R6/lib/X11
+ ln -s /usr/include/Xm /usr/X11R6/include
+ ln -s /usr/include/Mrm /usr/X11R6/include
+ ln -s /usr/include/uil /usr/X11R6/include
+ </verb></tscreen>
+
+ The Motif imake-configuration files are part of the LynxOS X Window
+ package. They must be copied to the <tt>/usr/X11R6</tt> directory tree.
+ <tscreen><verb>
+ cp /usr/lib/X11/config/Motif.* /usr/X11R6/lib/X11/config
+ </verb></tscreen>
+
+<sect1>Motif library patch for LynxOS AT 2.3.0<p>
+
+ The XFree86 libraries are compiled with the -mposix compiler option
+ while the Motif libraries shipped with LynxOS AT 2.3.0 are not. This
+ incompatibility will cause Motif <tt>XmFileSelection</tt> widgets to be linked
+ with the wrong (i.e. POSIX) directory routines. To circumvent this
+ problem apply the following patch to the library:
+ <tscreen><verb>
+ cp /usr/lib/libXm.a /usr/X11R6/lib
+ ar x /usr/X11R6/lib/libXm.a Xmos.o
+ ar x /lib/libc.a directory.s.o
+ ld -r -o x.o Xmos.o directory.s.o
+ mv x.o Xmos.o
+ ar r /usr/X11R6/lib/libXm.a Xmos.o
+ </verb></tscreen>
+
+ This patch is not necessary for LynxOS revisions after 2.3.0.
+
+<sect1>X11R6 config file patch<p>
+
+ Edit <tt>/usr/X11R6/lib/X11/config/lynx.cf</tt> and change the definition
+ of <tt>HasMotif</tt>
+ <tscreen>
+ from
+ <verb>
+ #define HasMotif NO
+ </verb>
+ to
+ <verb>
+ #define HasMotif YES
+ </verb></tscreen>
+
+<sect1>Motif config file patch<p>
+
+ The file <tt>Motif.tmpl</tt> shipped with LynxOS Motif must be modified
+ to work with XFree86. In every reference to <tt>UnsharedLibReferences</tt>
+ the first argument must be changed
+ <tscreen>
+ from
+ <verb>
+ UnsharedLibReferences(<Something>LIB, Arg2, Arg3)
+ </verb>
+ to
+ <verb>
+ UnsharedLibReferences(<Something>, Arg2, Arg3)
+ </verb></tscreen>
+ Be sure to apply the change to the file copied to
+ <tt>/usr/X11R6/lib/X11/config</tt>.
+
+<sect>Compiling the XFree86 Distribution<p>
+
+Before trying to rebuild XFree86 from source read <htmlurl url="BUILD.html"
+name="Building XFree86"> for a detailed description of the build
+process. The next sections contain LynxOS specific notes with
+respect to the build process.
+
+
+<sect1>Disk space requirements<p>
+Currently there is no support for shared libraries in the LynxOS
+XFree86 port. A complete binary installation along with manual pages
+will require approximately 90-100 MBytes of disk space. To compile
+the system you will need at least 230 MBytes of free disk space.
+
+<sect1>Changes to system environment (LynxOS AT)<p>
+Before compiling the XFree86 distribution you will have to make a
+few little adjustments to your system:
+
+ <descrip>
+ <tag>LynxOS AT 2.5</tag>
+ <itemize>
+ <item>Create a shell script named <tt>/lib/cpp</tt> as follows:
+ <tscreen><verb>
+ #!/bin/sh
+ /usr/lib/gcc-lib/i386-unknown-lynxos2.5/2.7-96q1/cpp \
+ -traditional "$@"
+ </verb></tscreen>
+ On other platforms than the AT the paths for the compiler support
+ programs are different. You may use
+ <tscreen><verb>
+ gcc -v
+ </verb></tscreen>
+ to find out the correct path. Set the file mode of <tt>/lib/cpp</tt> with
+ <tscreen><verb>
+ # chown root /lib/cpp
+ # chmod 755 /lib/cpp
+ </verb></tscreen>
+ <item>Modify <tt>/lib/liblynx.a</tt>. The X servers need the
+ <tt>smem_create()</tt> system call to map the frame buffer into their
+ address space. The system call is in <tt>liblynx</tt> library along
+ with other Lynx proprietary calls which (unfortunately) overlap
+ with calls in <tt>libc</tt>. To reduce confusion you should modify
+ <tt>liblynx</tt> as follows:
+ <tscreen><verb>
+ # mv /lib/liblynx.a /lib/liblynx.a.ORG
+ # mkdir /tmp/xx; cd /tmp/xx
+ # ar xv /lib/liblynx.a.ORG
+ # ar rv /lib/liblynx.a *smem*
+ # ranlib /lib/liblynx.a
+ </verb></tscreen>
+
+ </itemize>
+ <tag>LynxOS AT 2.4</tag>
+ <itemize>
+ <item>Use the CYGNUS GNU-C Compiler to build XFree86. With LynxOS
+ 2.4.0 you must execute the shell script <tt>/CYGNUS.bash</tt> to
+ apply the necessary changes to your environment.
+ <item>Create a shell script named <tt>/lib/cpp</tt> as follows:
+ <tscreen><verb>
+ #!/bin/sh
+ /cygnus/94q4-lynxos-x86/lib/gcc-lib/i386-lynx/2.6-94q4/cpp \
+ -traditional "$@"
+ </verb></tscreen>
+ It is possible that future releases use a different path for
+ the CYGNUS compiler support programs. You may use
+ <tscreen><verb>
+ gcc -v
+ </verb></tscreen>
+ to find out the correct path. Set the file mode of <tt>/lib/cpp</tt> with
+ <tscreen><verb>
+ # chown root /lib/cpp
+ # chmod 755 /lib/cpp
+ </verb></tscreen>
+ </itemize>
+ <tag>LynxOS AT 2.3</tag>
+ This has actually not been tested, but the steps for described
+ for 2.4 should apply to 2.3 as well.
+ <tag>LynxOS AT 2.2.1</tag>
+ This has actually never been tested, be prepared that the build will
+ fail somewhere!
+ <itemize>
+ <item>Create a shell script named <tt>/lib/cpp</tt> as follows:
+ <tscreen><verb>
+ #!/bin/sh
+ /usr/local/lib/gcc-cpp -traditional "$@"
+ </verb></tscreen>
+ <item>The loader /bin/ld of LynxOS 2.2.1 does not support the -L option
+ which is heavily used by X11R6 makefiles. To work around this
+ problem you must install a small wrapper program which replaces
+ the original /bin/ld program. Use the following steps to install
+ it:
+ <tscreen><verb>
+ # cd xc/programs/Xserver/hw/xfree/etc
+ # cc -o ld ld-wrapper.c
+ # mv /bin/ld /bin/ld.org
+ # mv ld /bin/ld
+ # chmod 511 /bin/ld
+ # chown root /bin/ld
+ </verb></tscreen>
+ <item>Modify system header files as follows:
+ <descrip>
+ <tag><tt>/usr/include/uio.h</tt></tag> surrounded by
+ <tscreen><verb>
+ #ifndef _UIO_H
+ #define _UIO_H
+ ...
+ #endif
+ </verb></tscreen>
+ <tag><tt>/usr/include/utmp.h</tt></tag> surrounded by
+ <tscreen><verb>
+ #ifndef _UTMP_H
+ #define _UTMP_H
+ ...
+ #endif
+ </verb></tscreen>
+ <tag><tt>/usr/include/unistd.h</tt></tag> add
+ <tscreen><verb>
+ extern int read();
+ </verb></tscreen>
+ </descrip>
+ </itemize>
+ </descrip>
+
+<sect1> make World<p>
+
+ Read <htmlurl url="BUILD.html" name="Building XFree86"> before
+ trying to rebuild XFree86 from the source distribution.
+
+ You may then issue a
+
+ <tscreen><verb>
+ make World
+ </verb></tscreen>
+
+ to compile XFree86. After a few hours (and hopefully a successful
+ build of the XFree86 system) you can install the software using
+
+ <tscreen><verb>
+ make install
+ </verb></tscreen>
+
+ You must be logged in as super-user (root) when you invoke `make
+ install'. Be sure to set your environment to use the same compiler
+ (LynxOS 2.3.0/2.4.0, CYGNUS GNU-C) as you did during the `make World'. To
+ install the LinkKit use
+
+ <tscreen><verb>
+ make install.linkkit
+ </verb></tscreen>
+
+ With LynxOS 2.2.1 programs will not be stripped during
+ installation. This is due to a problem with the strip program which
+ shows up when installing across file system boundaries.
+
+ Refer to section <ref id="installman" name="Installing XFree86 manual pages">
+ for manual page installation.
+
+ On LynxOS AT 2.5.0 you may encounter problems with <tt>make</tt> in
+ deeply nested subdirectories (eg core dumps, hangups). In this case
+ update to GNU make version 3.75 or higher.
+
+<sect>Building on microSPARC and PowerPC<label id="others"><p>
+
+ XFree86 3.3 compiles on LynxOS microSPARC and on LynxOS PPC as well. On the
+ microSPARC there is X server support for the colour frame buffers CG3 and CG6
+ while on the PPC there is no X server available at this time. Before you
+ start the build (on versions earlier than 2.5.0) you must create a symbolic
+ link from the CYGNUS gcc to a file named <tt>cc</tt> somewhere in a
+ directory included in your PATH environment variable.
+
+<sect1>Console driver patch for microSPARC<p>
+
+ Before building on the microSPARC you should install the patch for the console
+ driver supplied in <tt>xc/programs/Xserver/hw/sunLynx/patch.Console</tt>.
+ (<tt>xc/programs/Xserver/hw/sunLynx/patch.Console-2.4.0</tt> for LynxOS
+ revisions earlier than 2.5.0).
+ The patch fixes minor problems in the original LynxOS driver and adds
+ functionalities to detect the keyboard type and control the key click.
+ To create a backup of the original driver and install the patch issue
+ the commands
+<tscreen><verb>
+ # cd /
+ # tar cf /sys/drivers/console.tar /sys/drivers/console
+ # patch -p -E < xc/programs/Xserver/hw/sunLynx/patch.Console
+ # cd /sys/drivers/console
+ # make install
+ # cd /sys/lynx.os
+ # make install
+ # reboot -a
+</verb></tscreen>
+
+ If you opt not to install the patch you must edit <tt>xc/config/cf/lynx.cf</tt>
+ and change the definition of <tt>SparcConsoleDefines</tt>
+ <tscreen>
+ from
+ <verb>
+ #define SparcConsoleDefines -DPATCHED_CONSOLE
+ </verb>
+ to
+ <verb>
+ #define SparcConsoleDefines /* -DPATCHED_CONSOLE */
+ </verb></tscreen>
+
+<sect1>Known Bug of the microSPARC server<p>
+
+ On the first start of the X server on the microSPARC you will notice that
+ the pointer follows mouse movements with a certain delay (especially if
+ you're moving the mouse real fast). You will also notice that moving
+ windows with certain window managers (eg mwm) is not working correctly.
+ These effects should go away on the next server start.
+
+ The server for monochrome cards builds properly if you enable it in
+ <tt>lynx.cf</tt> but it has never been tested (reports are welcome).
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/LynxOS.sgml,v 3.17 1999/08/23 06:38:47 dawes Exp $
+
+
+
+
+
+$XConsortium: LynxOS.sgml /main/10 1996/10/28 05:13:07 kaleb $
+</verb>
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/MGA.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/MGA.sgml
new file mode 100644
index 000000000..155e41b02
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/MGA.sgml
@@ -0,0 +1,185 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+<title>Information for Matrox Users
+<author>The XFree86 Project Inc.
+<date>30 December 1998
+<toc>
+
+<sect>Supported hardware
+<p>
+The current MGA driver in the SVGA server supports
+<p>
+<itemize>
+<item>Matrox Millennium
+(MGA2064W with Texas Instruments TVP3026 RAMDAC). It has been tested with
+175, 220MHz, and 250MHz cards with 2MB, 4MB and 8MB WRAM.
+<item>Millennium II both PCI and AGP (MGA2164W with Texas Instruments
+TVP3026 RAMDAC). It has been tested with 4 MB, 8 MB and 16 MB WRAM.
+<item>Matrox Mystique (Both MGA1064SG and MGA1164SG with integrated RAMDACs)
+170 MHz and 220 MHz (Mystique 220) versions should work.
+<item>Millennium G200 with SGRAM and SDRAM (Millennium G200-SD), with 8MB RAM.
+<item>Mystique G200 (but no TVout support)
+<item>Productiva G100 with SGRAM and SDRAM. 4MB and 8MB versions have been
+tested.
+<item>Matrox G400 (only the first head and no TVout support).
+</itemize>
+
+<sect1>What's not supported
+<p>
+<itemize>
+<item> Chipsets other than those listed above. We are still interested in
+providing support for the other Matrox chipsets including the Impression,
+Atlas, Genesis etc... but at this time have not been able to obtain
+documentation for them.
+<item> MGA2064W and MGA2164W based cards with ramdacs other than the TVP3026
+RAMDAC (like the Matrox Corona) are not supported.
+</itemize>
+
+<sect>Features:
+<p>
+<itemize>
+<item>uses linear frame buffer
+<item>Resolutions up to the maximum supported by the card should be possible.
+<item>8 bpp, 16 bpp (depth 15 and 16), 24 bpp (depth 24, packed) and 32 bpp
+(depth 24, sparse) are all supported.
+<item>supports VESA Display Power Management Signaling (DPMS)
+<item>supports RGB Sync-on-Green
+<item>supports the XF86_DGA extension
+<item>Makes extensive use of the graphics accelerator. This server is very
+well accelerated, and is one of the fastest XFree86 X servers.
+</itemize>
+
+<sect>Configuration:
+<p>
+The MGA driver should auto-detect all supported hardware so you needn't
+have anything other than the Identifier in the Section "Device" of the
+XF86Config file. When running the XF86Setup or xf86config programs one
+merely needs to select a Matrox card so that the correct server will be
+used. One need not and should not specify a RAMDAC, clockchip or allow
+the setup program to probe for clocks. The driver will auto-detect the
+amount of video ram present, however, due to some hardware problems
+this is not detected for the MGA2164W (Millennium II) or G100/G200.
+In this case users should specify the amount of video ram in the Section
+"Device" of the XF86Config file. eg:
+
+<verb>
+ VideoRam 4096
+ or
+ VideoRam 8192
+ or
+ VideoRam 16384
+</verb>
+
+as appropriate so that the server doesn't have to probe for it.
+
+The following Section "Device" options are supported by the MGA driver:
+<itemize>
+<item>Option "sw_cursor"
+<p>
+Will disable the hardware cursor on the Millennium and Millennium II.
+<item>Option "no_accel"
+<p>
+Will disable all hardware acceleration (oh my!).
+<item>Option "no_pixmap_cache"
+<p>
+Will disable caching of pixmaps in offscreen video memory.
+<item>Option "sync_on_green"
+<p>
+Will enable syncing on green for sync-on-green monitors (these are typically
+fixed frequency workstation monitors).
+<item>Option "pci_retry"
+<p>
+This will allow the MGA hardware to generate a pci_disconnect based on
+accelerator FIFO status. This can yield large performance boosts for
+some graphics operations but has a tendency to hog the PCI bus so
+it is turned off by default.
+<item>Option "mga_sdram"
+<p>
+This will force the server to disable sgram features such as block
+mode fills and hardware planemasks.
+</itemize>
+
+<sect>Known solutions for some problems:
+<p>
+
+<itemize>
+<item>Temporary loss of monitor sync when the cursor shape changes on
+Millennium and Millennium II. The hardware cursor has been enabled by
+default in 3.3.3.1. This seems to cause some problems on a minority of
+systems. If you experience problems with this on your system,
+please put:
+<verb>
+ Option "sw_cursor"
+</verb>
+in the Section "Device" of the XF86Config file to disable the hardware
+cursor.
+<item>Garbage in the cursor instead of the normal cursor image. A bug
+in the driver will cause this when less than 1K of video memory is left
+unused and the hardware cursor is enabled for some cards.
+If you experience this problem, please put:
+<verb>
+ Option "sw_cursor"
+</verb>
+in the Section "Device" of the XF86Config file to disable the hardware
+cursor. This should be fixed in XFree86 3.3.3.1 as in cases like this the
+software cursor should be used automatically.
+<item>the driver doesn't support some values of HTotal parameter in
+Modelines in the XF86Config file. If you get flickering vertical stripes on
+the screen, try to change this parameter +/- 8.
+<item>On some Millennium II cards the driver shows severe distortions with
+24bpp in modes above about 1024x768. We hope to have automated the detection
+and fix of this problem. If it still occurs, putting
+<verb>
+ Option "mga_24bpp_fix"
+</verb>
+in the Device Section may fix the problem.
+<item>On some MGA cards the amount of memory is mis-detected, on others
+probing for the amount of memory can cause a lockup in the system so memory
+probing is not done on those hardware (Millennium II, G100/G200).
+If the default of 4MB RAM (Millennium II) or 8MB RAM (G100/G200) is not
+correct, specify the amount of video ram in
+the Section "Device" of the XF86Config file as described in section 3 above.
+<item>If you Millennium II card that worked fine with XFree86-3.3.2.3 and
+earlier now shows pixel errors and strange effects when returning to the
+text console, make sure that the amount of memory that the server reports
+is correct.
+See item above for details.
+<item>With virtual screens that use 8MB of memory or more (e.g.,
+2048x2048 at 16bpp) there can be cursor distortions when panning the screen
+vertically. If that occurs, please put
+<verb>
+ Option "sw_cursor"
+</verb>
+in the Section "Device" of the XF86Config file to disable the hardware
+cursor.
+</itemize>
+
+<sect>Authors
+<p>
+
+Radoslaw Kapitan, <it>kapitan@student.uci.agh.edu.pl</it>
+
+Mark Vojkovich, <it>mvojkovi@sdcc10.ucsd.edu</it>
+
+and:
+
+<itemize>
+<item>Andrew Vanderstock, <it>vanderaj@mail2.svhm.org.au</it>
+<item>Angsar Hockmann, <it>Ansgar.Hockmann@hrz.uni-dortmund.de</it>
+<item>Michael Will, <it>Michael.Will@student.uni-tuebingen.de</it>
+<item>Andrew Mileski, <it>aem@ott.hookup.net</it>
+<item>Stephen Pitts, <it>pitts2@memphisonline.com</it>
+<item>Dirk Hohndel, <it>hohndel@XFree86.Org</it>
+<item>Leonard N. Zubkoff, <it>lnz@dandelion.com</it>
+<item>Harm Hanemaayer, <it>H.Hanemaayer@inter.nl.net</it>
+<item>Guy Desbief, <it>g.desbief@aix.pacwan.net</it>
+<item>Takaaki Nomura, <it>tnomura@sfc.keio.ac.jp</it>
+<item>Doug Merritt, <it>doug@netcom.com</it>
+</itemize>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/MGA.sgml,v 3.8 1999/08/23 06:38:47 dawes Exp $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/Mach32.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/Mach32.sgml
new file mode 100644
index 000000000..34a829c0d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/Mach32.sgml
@@ -0,0 +1,157 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+<article>
+
+<!-- Title information -->
+
+<title>Notes for Mach32 X Server
+<author>Bryan Feir (jenora@istar.ca)
+<date>2 July 1997
+
+<!-- Table of contents -->
+<toc>
+
+<!-- Begin the document -->
+
+
+<sect>Supported Cards, RAMDACs, and Bits Per Pixel<p>
+The base support in the Mach32 X server is for 8 bpp, with a dot clock
+of up to 80 MHz. At present 15/16 bpp is supported on only three of the
+many RAMDACs; however those three cover the most commonly sold cards.
+<p>
+<verb>
+ RAMDAC Max Dot Clock BPP Max Resolution Video RAM Required
+-------- ------------- --- -------------- ------------------
+Default 80MHz 8 1280x1024i 2Mb
+Default 80MHz 8 1024x768 1Mb
+
+ATI68875 135MHz 8 1280x1024 2Mb
+ATI68875 80MHz 16 1024x768 2Mb
+
+AT&amp;T20C49x 80MHz 8 1024x768 1Mb
+AT&amp;T20C49x 40MHz 16 800x600 2Mb
+
+BT481 80MHz 8 1024x768 1Mb
+BT481 40MHz 16 800x600 2Mb
+
+</verb>
+
+The RAMDAC is reported when you run the Mach32 X server with the
+"<tt>-probeonly</tt>" command line option, or can be specified in the
+XF86Config file.
+
+The ATI68875 (or the TLC34075) is used on the Graphics Ultra + and
+the Graphics Ultra Pro. The Brooktree 481 is used on most Graphics
+Wonder cards. The AT&amp;T20C491 is used on many of the OEM cards
+that are built into component systems.
+
+The BIOS detection unfortunately lumps the BT481 and the AT&amp;T20C49x
+together, while they require different configuration controls in 16 bit
+mode. SuperProbe can tell the difference, and will report which it finds.
+In the server itself, the BT481 is considered the default value. If you
+have an AT&amp;TC49x RAMDAC on your card you will have to include the Ramdac
+entry in the XF86Config file as below.
+
+<sect>XF86Config options<p>
+Several options are supported in the "Device" section for the Mach32 X
+server. Most of them should be auto-detected if needed, but a few may
+need to be deliberately set. For example, the "Clocks" entry should
+almost certainly be set after first running the server with the
+<tt>-probeonly</tt> option, so as to avoid the probe in later runs.
+
+<descrip>
+<tag>Option &dquot;composite&dquot;</tag>
+ This option will set the composite sync for
+ monitors that require this.
+<tag>Option &dquot;dac_8_bit&dquot;</tag>
+ This option enables 8 bits per RGB value. Note
+ this option does not work with all RAMDACs, and
+ is not considered supported by the Mach32 itself.
+<tag>Option &dquot;ast_mach32&dquot;</tag>
+ This option sets some special handling for the AST
+ version of the Mach32 card that comes soldered in to
+ some of their motherboards. This card will lock up
+ without this option.
+<tag>Option &dquot;intel_gx&dquot;</tag>
+ This option sets the memory aperture address to
+ the hardwired value for the Intel GX Pro. It is
+ equivalent to setting Membase to 0x78000000.
+<tag>Option &dquot;no_linear&dquot;</tag>
+ This option disables the use of the linear mapped
+ framebuffer. This should be auto-detected.
+<tag>Option &dquot;sw_cursor&dquot;</tag>
+ This option allows you to use the software cursor
+ instead of the hardware cursor.
+<tag>MemBase baseaddress</tag>
+ This entry specifies the video memory aperture
+ address. Normally the aperture address is
+ automatically determined, but on some VESA Local
+ Bus systems the address chosen will not work. If
+ the Mach32 X server is dying with a seg. fault,
+ then try setting the aperture address to another
+ location.
+<tag>Clocks <it>clock</it> ...</tag>
+ This entry gives the clock rates for the server to use.
+<tag>Ramdac &dquot;<it>type</it>&dquot;</tag>
+ This entry specifies the RAMDAC type. The following
+ values are valid for <it>type</it>:
+ <itemize>
+ <item>ati68830
+ <item>sc11483
+ <item>sc11486
+ <item>sc11488
+ <item>ims_g173
+ <item>mu9c4870
+ <item>ati68875*
+ <item>bt885
+ <item>tlc34075*
+ <item>bt476
+ <item>bt478
+ <item>inmos176
+ <item>inmos178
+ <item>bt481*
+ <item>bt482
+ <item>ims_g174
+ <item>mu9c1880
+ <item>mu9c4910
+ <item>sc15025
+ <item>sc15026
+ <item>att20c490*
+ <item>ati68860
+ <item>stg1700
+ <item>sc15021
+ <item>stg1702
+ <item>att21c498
+ </itemize>
+ Only the ones marked with &lsqb*&rsqb have an effect yet.
+</descrip>
+
+<sect>Known Problems and Bug Reports<p>
+There are several known problems with the current version of the
+Mach32 X server. They include:
+<itemize>
+<item>Not all RAMDACs are supported at higher colour ranges, and not all
+ that are can be detected properly. In fact most of the RAMDAC values
+ above have no effect except to block higher bit modes.
+<item>Sixteen bit character support (e.g., Chinese and Japanese character
+ sets) has been known to lose parts of characters. While this should
+ be fixed, if it occurs try running the server with Option
+ &dquot;no_linear&dquot;.
+</itemize>
+
+Bug reports should be sent to XFree86@XFree86.org or posted to the
+comp.windows.x.i386unix newsgroup.
+
+<p>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/Mach32.sgml,v 3.7 1997/07/10 08:17:25 hohndel Exp $
+
+
+
+
+$XConsortium: Mach32.sgml /main/4 1996/10/28 04:47:43 kaleb $
+</verb>
+
+</article>
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/Mach64.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/Mach64.sgml
new file mode 100644
index 000000000..017efd97c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/Mach64.sgml
@@ -0,0 +1,393 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+<article>
+
+<!-- Title information -->
+
+<title>Mach64 X Server Release Notes
+<author>Kevin E. Martin (martin@cs.unc.edu)
+<date>1999 June 28
+
+<!-- Table of contents -->
+<toc>
+
+<!-- Begin the document -->
+
+
+<sect>Supported Cards, RAMDACs, and Bits Per Pixel<p>
+The Mach64 X server supports 8bpp with a dot clock up to 80MHz on all
+Mach64 based cards. On most cards, higher dot clocks and additional
+depths are available (see the table below). What determines this
+support is the RAMDAC on your card.
+<p>
+<verb>
+ RAMDAC Max Dot Clock BPP Max Resolution Video RAM Required
+-------- ------------- --- -------------- ------------------
+ATI68860 135MHz 8 1280x1024 2Mb
+ATI68860 135MHz 16 1280x1024 4Mb
+ATI68860 80MHz 32 1024x768 4Mb
+
+ATI68875 80MHz 32 1024x768 4Mb
+
+CH8398 135MHz 8 1280x1024 2Mb
+CH8398 80MHz 16 1024x768 2Mb
+CH8398 40MHz 32 800x600 2Mb
+
+STG1702 135MHz 8 1280x1024 2Mb
+STG1702 80MHz 16 1024x768 2Mb
+STG1702 50MHz 32 800x600 2Mb
+
+STG1703 135MHz 8 1280x1024 2Mb
+STG1703 80MHz 16 1024x768 2Mb
+STG1703 50MHz 32 800x600 2Mb
+
+AT&amp;T20C408 135MHz 8 1280x1024 2Mb
+AT&amp;T20C408 80MHz 16 1024x768 2Mb
+AT&amp;T20C408 40MHz 32 800x600 2Mb
+
+3D Rage II 170MHz 8 1600x1200 4Mb
+3D Rage II 170MHz 16 1600x1200 4Mb
+3D Rage II 170MHz 32 1024x768 4Mb
+
+3D Rage II+DVD 200MHz 8 1600x1200 4Mb
+3D Rage II+DVD 200MHz 16 1600x1200 4Mb
+3D Rage II+DVD 200MHz 32 1024x768 4Mb
+
+Rage Pro 230MHz 8 1600x1200 8Mb
+Rage Pro 230MHz 16 1600x1200 8Mb
+Rage Pro 230MHz 32 1600x1200 8Mb
+
+Internal 135MHz 8 1280x1024 2Mb
+Internal 80MHz 16 1024x768 2Mb
+Internal 40MHz 32 800x600 2Mb
+
+IBM RGB514 220MHz 8 1600x1200 2Mb
+IBM RGB514 220MHz 16 1600x1200 4Mb
+IBM RGB514 135MHz 32 1024x768 4Mb
+
+All Others[*] 80MHz 8 1280x1024 2Mb
+
+</verb>
+&lsqb*&rsqb - The dot clocks are limited to 80MHz and the bpp is limited to 8.
+
+The table above specifies the maximum resolution and the video memory
+required to run this maximum resolution. Smaller resolutions will
+require less video memory.
+
+The RAMDAC is reported when you run the Mach64 X server with the
+"<tt>-probeonly</tt>" command line option. The RAMDAC reported should
+be correct for all Mach64 cards. It can also be specified in the
+XF86Config file, but this is not recommended unless the RAMDAC
+reported in the probeonly output is incorrect. Before specifying the
+RAMDAC in your XF86Config file visually verify which RAMDAC is on your
+Mach64 card. If the RAMDAC reported in the probeonly output is
+definitely different than what you see on the card, then check to see
+if you have a RAMDAC specified in your XF86Config file. If you do,
+comment this line out and re-run the Mach64 X server with the
+"<tt>-probeonly</tt>". If it still reports the incorrect RAMDAC,
+please send in a bug report to XFree86@XFree86.Org.
+
+The ATI68860 RAMDACs are usually found on ATI Graphics Pro Turbo and
+ATI WinTurbo cards. The IBM RGB514 RAMDAC is found on the ATI
+Graphics Pro Turbo 1600 card. The other RAMDACs are usually found on
+ATI Graphics Xpression, ATI Video Xpression and ATI 3d Xpression
+cards. Mach64 CT, ET, VT, VT3, VT4, LT, GT (3D Rage), 3D Rage II, 3D
+Rage IIC, 3D Rage II+DVD, Rage Pro, and Rage LT Pro chips have an
+"Internal" RAMDAC (i.e., it is built into the Mach64 chip).
+
+As advertised, Mach64 graphics cards can use a special 24bpp mode
+(packed pixel mode), but this is not currently supported in the Mach64
+X server. This will be added in the next major release.
+
+The Mach64 X server requires the video memory aperture to function
+properly. This means that ISA Mach64 cards in systems with more than
+12Mb of main memory will not work. If you have a PCI based Mach64
+card or a VLB based Mach64 card, then the Mach64 X server will work
+with any amount of main memory.
+
+Accelerated doublescan modes are supported on VT, VT3, VT4, LT, GT,
+Rage II, Rage IIC, Rage II+DVD, Rage Pro and Rage LT Pro based Mach64
+cards. Mach64 cards with other chips cannot handle accelerated double
+scan modes due to a hardware limitation. Non-accelerated doublescan
+modes should work with the ATI driver in the SVGA X server for all
+Mach64 cards.
+
+<sect>Optimizing the speed of the Mach64 X server<p>
+To maximize the speed of the Mach64 X server, I suggest that you use
+the following maximum resolutions. This will allow room for the font
+and pixmap caches and a hardware cursor.
+
+<verb>
+Max Resolution BPP Video RAM
+-------------- --- ---------
+ 1600x1200 8 8Mb
+ 1600x1200 16 8Mb
+ 1280x1024 32 8Mb
+
+ 1280x1024 8 4Mb
+ 1280x1024 16 4Mb
+ 1024x767 32 4Mb
+
+ 1280x1024 8 2Mb
+ 1024x767 16 2Mb
+ 800x600[*] 32 2Mb
+
+ 1024x767 8 1Mb
+ 800x600[*] 16 1Mb
+</verb>
+
+&lsqb;*&rsqb; - With a 2MB video card, the only way to use the font
+and pixmap caches is to have a virtual resolution of 1024x480 with a
+640x480 mode. I suggest using 800x600 to maximize your screen size at
+the cost of the speed gained from the caches. The same argument can
+be made for 1MB video cards running in 16bpp mode. Note that it is
+not possible to run in 32bpp mode with 1MB of video memory.
+
+Technical explanation for the above suggestions: The Mach64 X server
+uses a font and pixmap cache that is only available at a screen width
+of 1024 or greater. This restriction will be removed in a future
+version of the X server. To obtain the best performance from your
+video card, you need to make sure that there is enough room off-screen
+for the caches (at least 1024x256). In addition to the cache, the
+Mach64 uses memory mapped registers which are mapped to the last 1024
+bytes of the memory aperture. This takes away another line from video
+memory. Thus, you need at least a video memory area of 1024x257.
+
+<sect>XF86Config options<p>
+Several options are supported in the "Device" section for the Mach64 X
+server. By default, the Mach64 X server will determine the RAMDAC
+type from the BIOS. If you wish to override the default RAMDAC type
+(not recommended unless the BIOS incorrectly reports your RAMDAC
+type), you can specify the RAMDAC type in the XF86Config file with the
+"Ramdac" entry. The Mach64 X server will also program the clocks
+based on the clock chip read from the BIOS. If you wish to override
+the default clock chip type (not recommended unless the BIOS
+incorrectly reports your clock chip type), you may specify the clock
+chip in the XF86Config file with the "ClockChip" entry. If, however,
+you wish to use the preprogrammed clocks, you can turn off the clock
+programming with the "no_program_clocks" option. In this case, the
+Mach64 X server reads the Clocks from the BIOS. The "Clocks" lines in
+the XF86Config file are normally ignored by the Mach64 X server unless
+the "no_bios_clocks" option is given. Note on newer Mach64 cards (CT,
+ET, VT, GT, 3D Rage II, 3D Rage II+DVD and Rage Pro) the "Ramdac",
+"ClockChip" and "Clocks" lines have no meaning and should not be
+included in your XF86Config file.
+
+<descrip>
+<tag>Option "sw_cursor"</tag>
+ This option allows you to use the software cursor
+ instead of the hardware cursor.
+<tag>Option "hw_cursor"</tag>
+ This option turns on the hardware cursor. This
+ should not be necessary since the hardware cursor
+ is used by default unless the "sw_cursor" option is
+ specified.
+<tag>Option "composite"</tag>
+ This option will set the composite sync for
+ monitors that require this.
+<tag>Option "dac_8_bit"</tag>
+ This option enables 8 bits per RGB value. Note that
+ this does not work with the Chrontel 8398 RAMDAC.
+ This options is not necessary since 8 bits per RGB
+ value is the default for the Mach64 X server for all
+ Mach64 cards except those with the Chrontel 8398
+ RAMDAC.
+<tag>Option "dac_6_bit"</tag>
+ This option enables 6 bits per RGB value.
+<tag>Option "override_bios"</tag>
+ This option allows you to specify a video
+ mode that the video card's BIOS believes to be
+ illegal. Some BIOSs have incorrect maximum
+ resolution and/or dot clock limitations. Use
+ this option with extreme care. It is possible to
+ specify a video mode that can damage your card or
+ monitor.
+<tag>Option "no_block_write"</tag>
+ This option allows you to turn off block write mode.
+ Block write mode only works on certain types of VRAM
+ cards. This option has no effect on DRAM based cards.
+ If you see noise on the screen that can be captured
+ via xmag, then it is probably a problem with block
+ write mode being turned on when it should not. This
+ ``noise'' usually looks like bits of windows/menus
+ repeated on the screen.
+<tag>Option "block_write"</tag>
+ This option allows you to turn on block
+ write mode. Block write mode only works on
+ certain types of VRAM cards, and this option has
+ no effect on DRAM based cards. If you want to
+ override the probed default, you can use this option.
+ Note that this may result in ``noise'' appearing on
+ the screen.
+<tag>Option "power_saver"</tag>
+ This option allows the server to use the power
+ saving features of certain "green" monitors
+ instead of blanking when the screen saver is
+ activated. This option is still experimental.
+<tag>Option "no_program_clocks"</tag>
+ This option allows you to disable the clock
+ programming. Normally the Mach64 server will program
+ the clocks based on the clock chip type unless this
+ option is given. With this option, the clocks are
+ either read from the BIOS or, if the "no_bios_clocks"
+ option is set, set from the Clocks line.
+<tag>Option "no_bios_clocks"</tag>
+ This option allows you to override the clocks read
+ from the video card's BIOS and use the clocks
+ specified in the Clocks line in your XF86Config file.
+ Normally the Mach64 server will ignore both the BIOS
+ clocks and the clocks specified in the Clocks line
+ unless the "no_program_clocks" options is set (see
+ above).
+<tag>Option "no_font_cache"</tag>
+ This option allows you to disable the font cache. By
+ default the font cache is turned on if the horizontal
+ resolution is 1024 pixels or greater and there is
+ enough off-screen video memory to hold the cache.
+<tag>Option "no_pixmap_cache"</tag>
+ This option allows you to disable the pixmap cache.
+ By default the pixmap cache is turned on if the
+ horizontal resolution is 1024 pixels or greater and
+ there is enough off-screen video memory to hold the
+ cache.
+<tag>Option "fifo_conservative"</tag>
+ This option allows you to use a more conservative
+ display fifo value. If you are experiencing snow or
+ vertical banding on the screen, try adding this option
+ to see if it fixes the problem.
+<tag>MemBase baseaddress</tag>
+ This entry specifies the video memory aperture
+ address. By default the aperture address is
+ automatically determined and this option should
+ not be necessary. If the Mach64 X server is dying
+ with a seg. fault, then the memory aperture might
+ not be correctly determined. To fix this try setting
+ the aperture address to another location.
+<tag>ClockChip "<it>type</it>"</tag>
+ This entry specifies the clock chip type. The
+ following values are valid for <it>type</it>:
+ <itemize>
+ <item>ati18818
+ <item>att20c408
+ <item>ch8398
+ <item>ibm_rgb514
+ <item>ics2595
+ <item>stg1703
+ </itemize>
+<tag>Ramdac "<it>type</it>"</tag>
+ This entry specifies the RAMDAC type. The following
+ values are valid for <it>type</it>:
+ <itemize>
+ <item>ati68860
+ <item>ati68860b
+ <item>ati68860c
+ <item>ati68875
+ <item>att20c408
+ <item>ch8398
+ <item>ibm_rgb514
+ <item>internal
+ <item>stg1702
+ <item>stg1703
+ <item>tlc34075
+ </itemize>
+<tag>DacSpeed "<it>MHz</it>"</tag>
+ This entry allows you to override the default maximum
+ dot clock. Use this option with extreme caution. If
+ you specify a <it>MHz</it> value too large for your
+ card, you can damage it.
+</descrip>
+
+<sect>Enhancements for this release<p>
+With this release, the following enhancements have been made:
+<itemize>
+<item>Proper identification of all current Mach64 chips
+<item>Support for VT4 and Rage IIC based cards
+<item>Improved timing calculation for video FIFOs
+<item>Fixed timing bug in font code
+<item>Fixed VGA font restoration bug when exiting the X server
+</itemize>
+
+<sect>Cards known to work with this release<p>
+The following is a list of cards that have been tested with this
+release. Many other cards should work including All-In-Wonder and
+All-In-Wonder Pro cards as well as motherboards with Mach64, 3D Rage
+II and Rage Pro included on them. If you have a new card that does
+not appear to work, see the Known Problems and Bug Reports section
+below.
+
+<verb>
+ATI Xpert@Play 98 4MB 3D Rage Pro (AGP)
+ATI Xpert 98 4MB 3D Rage Pro (PCI)
+ATI Xpert XL 4MB 3D Rage Pro (AGP)
+ATI Rage IIC 4MB 3D Rage IIC (AGP)
+ATI Xpert@Play 8MB 3D Rage Pro (AGP/PCI)
+ATI Xpert@Work 2MB 3D Rage Pro (PCI)
+ATI Pro Turbo+PC2TV 4MB 3D Rage II+DVD (rev 154)
+ATI 3D Xpression+ 4MB 3D Rage II (GT-B, SGRAM, rev 65)
+ATI 3D Xpression+ 2MB 3D Rage II (GT-B, SDRAM, rev 65)
+ATI 3D Xpression 2MB 3D Rage (GT-A, rev 72)
+ATI Video Xpression+ 2MB Mach64 VT-A3 (rev 8)
+ATI Video Xpression 2MB Mach64 VT-A4 (rev 72)
+ATI Graphics Xpression 2MB Mach64 CT (rev 9)
+ATI Graphics Xpression 2MB Mach64 CT-C (rev 65)
+ATI Graphics Xpression 2MB Mach64 CT-D (rev 10)
+ATI Graphics Xpression 2MB Mach64 GX (rev 1) with Chrontel8398 RAMDAC
+ATI Graphics Pro Turbo 2MB Mach64 GX (rev 0) with 68860-B RAMDAC
+ATI Graphics Pro Turbo 2MB Mach64 CX (rev 1) with AT&amp;T20C408 RAMDAC
+ATI WinTurbo 2MB Mach64 GX (rev 1) with 68860-C RAMDAC
+</verb>
+
+<sect>Known Problems and Bug Reports<p>
+There are several known problems with the current version of the
+Mach64 X server. They include:
+<itemize>
+<item>Gamma correction is not currently supported. It will be
+ supported in a future release.
+<item>Screen blanking in 16bpp and 32bpp modes on certain Mach64 CT
+ cards does not work.
+<item>In doublescan modes, only the top half of the hardware cursor
+ is displayed. The hardware cursor works fine in all other
+ modes.
+<item>With high refresh rates on certain cards (VT-A3 and CT-D) noise
+ can become a problem in 32bpp mode. This usually only happens
+ with refresh rates of 85Hz or greater and can be fixed by using
+ a lower refresh rate (e.g., 72Hz or 75Hz).
+<item>ISA cards with more than 12Mb of main memory cannot use the
+ server due to the requirement of a video memory aperture. This
+ a major project.
+</itemize>
+
+If you are experiencing problems, first check to make sure that you
+have the very latest available release (including beta releases). ATI
+releases new cards throughout the year. Each of these new cards
+require additional programming to support the new Mach64 chips,
+RAMDACs and clock chips that appear on them. The most recent release
+is most likely to support your video card.
+
+Second, please check the RELNOTES and README files (as well as the
+other documentation available with the release). Third, make sure you
+do not have any Ramdac, ClockChip or Clocks lines in your XF86Config
+file (all of these are automatically detected by the Mach64 X server).
+The "Device" section should only contain the Identifier, VendorName
+and BoardName. All other options should be automatically detected.
+
+If you are still experiencing problems, please send e-mail to
+XFree86@XFree86.org or post to the comp.windows.x.i386unix newsgroup.
+
+Please do NOT send e-mail to me since the developers who answer e-mail
+sent to XFree86@XFree86.org are better able to answer most questions
+and I would like to spend my minimal free time working on new
+enhancements to the X server. Thanks!
+
+<p>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/Mach64.sgml,v 3.16 1999/08/23 06:38:48 dawes Exp $
+
+
+
+
+
+$XConsortium: Mach64.sgml /main/8 1996/10/28 05:23:52 kaleb $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/NVIDIA.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/NVIDIA.sgml
new file mode 100644
index 000000000..c9932ee29
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/NVIDIA.sgml
@@ -0,0 +1,63 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+
+<!-- Title information -->
+<title>Information for NVidia NV1 / SGS-Thomson STG2000, Riva 128 and Riva TNT and TNT2 Users
+<author>David McKay, Dirk Hohndel
+<date>June 25 1999
+
+<!-- Table of contents -->
+<toc>
+
+<sect>Supported hardware
+<p>
+This driver supports good acceleration for the NV1/STG2000 as well as
+the Riva128, Riva TNT and Riva TNT2.
+
+<sect>Notes
+<p>
+<itemize>
+ <item>On the NV1/STG2000, the driver does not support the virtual desktop
+ features of xfree86.
+ This is because the NV1 does not have the necessary hardware to
+ support this
+ feature. If you want to change resolutions, you will have
+ to modify your config file. Comment out all but the mode you wish
+ to use.
+ <item>The generic VGA16 server will not work with the NV1. For this reason
+ <tt>XF86Setup</tt> cannot be used to configure the server for NV1
+ based cards. Use
+ <tt>xf86config</tt> instead. Select `Diamond Edge 3D' as your board,
+ and select only <bf>ONE</bf> mode for each of 8bpp and 16bpp. Do
+ not select a virtual desktop. Also, make sure you don't select
+ a RAMDAC or clock chip. This does not apply if you own a Riva128
+ or RIVA TNT card, as the VGA16 server works just fine on that.
+ <item>Both the NV1 and the Riva128 only support a 555 RGB Weight in 16 bpp,
+ the hardware does
+ not do 565. If you run into problems with some window managers in
+ 16bpp, try putting a Weight 555 in the Display section.
+ <item>24 bpp is not supported.
+ <item>In some modes the hardware cursor gets out of sync with the display.
+ Use Option "sw_cursor" to work around this problem.
+ <item>There are modelines that confuse the Riva128 chip. This results in
+ a greenish display. Slightly modifying the modeline usually fixes
+ the problem. In most cases all that is needed is to reduce the
+ HTotal. You can use xvidtune to do that.
+ <item>The low maximum dot clocks for the Riva 128 have been fixed. The
+ driver should now utilize the Riva 128 to its full capabilities.
+</itemize>
+
+<sect>Authors
+<p>
+<itemize>
+<item>David McKay
+<item>David Schmenk <it>&lt;dschmenk@nvidia.com&gt;</it>
+<item>Dirk Hohndel <it>&lt;hohndel@XFree86.org&gt;</it>
+</itemize>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/NVIDIA.sgml,v 1.2 1999/08/23 06:18:33 dawes Exp $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/NetBSD.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/NetBSD.sgml
new file mode 100644
index 000000000..b2438032d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/NetBSD.sgml
@@ -0,0 +1,600 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+<title>README for XFree86 on NetBSD
+<author>Rich Murphey,
+David Dawes,
+Marc Wandschneider,
+Mark Weaver,
+Matthieu Herrb
+<Date>Last modified on: 25 June 1999
+
+<toc>
+
+
+<sect>What and Where is XFree86?
+
+<p>
+XFree86 is a port of X11R6.3 that supports several versions of
+Intel-based Unix. It is derived from X386 1.2, which was the X server
+distributed with X11R5. This release consists of many new features
+and performance improvements as well as many bug fixes. The release
+is available as source patches against the X Consortium X11R6.3 code, as
+well as binary distributions for many architectures.
+
+See the <htmlurl url="COPYRIGHT.html" name="Copyright Notice">.
+
+The sources for XFree86 are available by anonymous ftp from:
+
+<htmlurl name="ftp://ftp.XFree86.org/pub/XFree86/current"
+url="ftp://ftp.XFree86.org/pub/XFree86/current">
+
+Binaries for NetBSD 1.2 are available from:
+<htmlurl name="ftp://ftp.XFree86.org/pub/XFree86/current/binaries/NetBSD-1.2"
+url="ftp://ftp.XFree86.org/pub/XFree86/current/binaries/NetBSD-1.2">
+
+Binaries for NetBSD 1.4 and later are available from:
+<htmlurl name="ftp://ftp.XFree86.org/pub/XFree86/current/binaries/NetBSD-1.4"
+url="ftp://ftp.XFree86.org/pub/XFree86/current/binaries/NetBSD-1.4">
+
+A list of mirror sites is provided by
+<htmlurl name="ftp://ftp.XFree86.org/pub/XFree86/MIRRORS"
+url="ftp://ftp.XFree86.org/pub/XFree86/MIRRORS">
+
+<p>
+Other NetBSD versions:
+
+These binaries are not compatible with earlier NetBSD versions. If
+you're still running NetBSD 0.9, 1.0 or 1.1, you should think about
+upgrading to a newer version of NetBSD first.
+
+If you don't upgrade, you'll have to build XFree86 from the sources.
+XFree86 should compile cleanly under earlier versions of
+NetBSD, although this has not been tested.
+
+XFree86 also builds on NetBSD/sparc. See section
+<ref id="sparc" name="Building on other architectures"> for details.
+
+The client side of XFree86 also builds on NetBSD/alpha and many other
+architecture supported by NetBSD.
+
+XFree86 also supports NetBSD on PC98 machines.
+
+
+<sect>Bug Reports for This Document
+
+<p>
+Send email to <em/matthieu@laas.fr/ (Matthieu Herrb) or
+<em/XFree86@XFree86.org/ if you have comments or suggestions about
+this file and we'll revise it.
+
+<sect>New features in this release
+
+<p>
+<itemize>
+<item>The maximum number of open connections in the server has been
+raised to 128,
+<item>support for the <bf/wsmouse/ mouse protocol included in NetBSD 1.4 has
+been added.
+</itemize>
+
+<p>
+See the <htmlurl url="RELNOTES.html" name="Release Notes"> for
+non-OS dependent new features in XFree86 3.3.4.
+
+<sect>Installing the Binaries
+
+<p>
+Refer to section 5 of the <htmlurl url="RELNOTES.html" name="Release
+Notes"> for detailed installation instructions.
+
+
+<sect>Configuring X for Your Hardware
+
+<p>
+The <tt>/etc/XF86Config</tt> file tells the X server what kind of
+monitor,
+video card and mouse you have. You <em/must/ create it to tell the
+server what specific hardware you have.
+<p>
+The easiest way to create this file is to run the <bf/XF86Setup/
+utility as root. Refer to <htmlurl url="QuickStart.html"
+name="QuickStart.doc"> for details about its use.
+<p>
+You'll need info on your hardware:
+<itemize>
+<item>Your mouse type, baud rate and its /dev entry.
+<item>The video card's chipset (e.g. ET4000, S3, etc).
+<item>Your monitor's sync frequencies.
+</itemize>
+
+The recommended way to generate an <tt/XF86Config/ file is to use the
+<tt/XF86Setup/ utility. The xf86config text utility is still there
+for the (few) cases where XF86Setup can't be used. Also, there is a
+sample file installed as <tt>/usr/X11R6/lib/X11/XF86Config.eg</tt>,
+which can be used as a starting point.
+
+For details about the <tt/XF86Config/ file format, refer to the
+<em>XF86Config(5)</em> manual page.
+
+Once you've set up a XF86Config file, you can fine tune the video
+modes with the <tt>xvidtune</tt> utility.
+
+<sect1>About mouse configuration
+
+<p>
+If your serial mouse does not work try using <tt>kermit</tt> or
+<tt>tip</tt> to connect to the mouse serial port and verify that it
+does indeed generate characters.
+<p>
+The NetBSD pms mouse driver handles PS/2 style mice as
+Busmouse. Specify the protocol as ``<bf/busmouse/'' in the mouse
+section of your
+<tt/XF86Config/ file if you're using a PS/2 mouse.
+<p>
+Only standard PS/2 mice are supported by this driver. Newest PS/2
+mice that send more than three bytes at a time (especially
+Intellimouse, or MouseMan+ with a ``3D'' roller) are not supported yet.
+<p>
+XFree86 3.3.4 also has support for the mouse driver included in
+the new <bf/wscons/ console driver introduced by NetBSD 1.4. Specify
+``<tt/wsmouse/'' as the protocol and ``<tt>/dev/wsmouse0</tt>'' as the
+device in <tt>/etc/XF86Config</tt> if you're using NetBSD 1.4 with
+wscons.
+<p>
+See <htmlurl url="mouse.html" name="README.mouse"> for general
+instruction on mouse configuration in XFree86.
+
+<sect1>Other input devices
+<p>
+XFree86 supports the dynamic loading of drivers for external
+input devices using the <tt/XInput/ extension. Currently supported
+devices are:
+<itemize>
+<item>Joystick (<tt/xf86Jstk.so/)
+<item>Wacom tablets (Wacom IV protocol only, <tt/xf86Wacom.so/)
+<item>SummaSketch tablets (<tt/xf86Summa.so/)
+<item>Elographics touchscreen (<tt/xf86Elo.so/)
+</itemize>
+
+To use a specific device, add the line
+<tscreen>
+<tt/load/ <tt/"/<em/module/<tt/"/
+</tscreen>
+in the <bf/Module/ section of <tt/XF86Config/, where <em/module/ is
+the name of the <tt/.so/ file corresponding to your device.
+You also need to set up a <bf/XInput/ section in <tt/XF86Config/.
+Refer to the <em>XF86Config(5)</em> man page for detailed
+configuration instructions.
+<p>
+You can then change the device used to drive the X pointer with the
+<em/xsetpointer(1)/ command.
+<p>
+For joystick support, you'll need to install the joystick device
+driver in the kernel. It is included in NetBSD 1.2. See
+<em/joy(4)/ for details.
+
+<sect1>Configuring PEX and XIE extensions
+<p>
+The PEX and XIE extensions are supported as external modules.
+If you want to have access to these extensions, add the following
+lines to the <bf/Module/ section of <tt/XF86Config/:
+<tscreen><verb>
+ load "pex5.so"
+ load "xie.so"
+</verb></tscreen>
+
+
+<sect>Running X
+
+<p>
+8mb of memory is a recommended minimum for running X. The server,
+window manager and an xterm take about 4 Mb of memory themselves. On
+a 4Mb system that would leave nothing left over for other applications
+like gcc that expect a few meg free. X will work with 4Mb of memory,
+but in practice compilation while running X can take 5 or 10 times as
+long due to constant paging.
+
+The easiest way for new users to start X windows is to type:
+<tscreen><verb>
+startx >& startx.log
+</verb></tscreen>
+Error messages are lost unless you redirect them
+because the server takes over the screen.
+
+To get out of X windows, type: ``<tt/exit/'' in the console xterm.
+You can customize your X by creating <tt/.xinitrc/, <tt/.xserverrc/,
+and <tt/.twmrc/ files in your home directory as described in the xinit
+and startx man pages.
+
+<sect1>Starting Xdm, the display manager
+
+<p>
+To start the display manager, log in as root on the console and type:
+``<tt/xdm -nodaemon/''.
+
+You can start xdm automatically on bootup by disabling the console getty
+and adding the following code to <tt>/etc/rc.local</tt>:
+
+<tscreen><verb>
+ if [ -x /usr/X11R6/bin/xdm ]; then
+ echo -n ' xdm'; /usr/X11R6/bin/xdm
+ fi
+</verb></tscreen>
+
+To disable the console getty, change ``<bf/on/'' to ``<bf/off/'' in
+the console entry in <tt>/etc/ttys</tt>:
+
+<tscreen><verb>
+ ttyv0 "/usr/libexec/getty Pc" pc off secure
+</verb></tscreen>
+
+<p>
+Under NetBSD 1.4 with the wscons console driver, you must enable a
+virtual console for the X server first. To do this follow these steps:
+<itemize>
+<item>Make sure the device file exists. If not, ``<tt>cd /dev ;
+./MAKEDEV wscons</tt>''.
+<item>Next, make sure your kernel wants to do wscons. (see <ref
+id="wscons" name="below">).
+<item>Next, make sure ``<tt>wscons=YES</tt>'' in
+<tt>/etc/rc.conf</tt>.
+<item>Next, make sure <tt>/etc/wscons.conf</tt> exists. The relevant
+bits:
+<tscreen><verb>
+#screen 0 - vt100
+screen 1 - vt100
+screen 2 - vt100
+screen 3 - vt100
+screen 4 - -
+screen 5 - vt100
+</verb></tscreen>
+</itemize>
+(Thanks to Mason Loring Bliss <tt>&lt;mason@acheron.middleboro.ma.us&gt;</tt> for
+this explanation)
+<p>
+Note that the binary distributions of XFree86 for NetBSD don't include
+support for the XDM-AUTHORIZATION-1 protocol.
+
+<sect>Kernel Support for X
+
+<p>
+To make sure X support is enabled under NetBSD, the following
+line must be in your config file in <tt>/sys/arch/i386/conf</tt>:
+
+<tscreen>
+ options XSERVER, UCONSOLE
+</tscreen>
+
+<sect1>Console drivers
+
+<p>
+The server supports the standard NetBSD/i386
+console drivers: pccons, pcvt and wscons (in pcvt compatibility
+mode). They are detected at runtime and no
+configuration of the server itself is required.
+
+<p>
+The pccons driver is the most widely tested and is the console driver
+contained in the NetBSD binary distribution's kernels.
+
+<p>
+The pcvt console driver is bundled with NetBSD. The pcvt X
+mode is compatible with the pccons driver X mode. It offers several
+virtual consoles and international keyboard support. In order to use
+this driver, change the line:
+
+<tscreen>
+ device pc0 at isa? port "IO_KBD" irq 1
+</tscreen>
+
+to
+
+<tscreen>
+ device vt0 at isa? port "IO_KBD" irq 1
+</tscreen>
+
+in your kernel config file, and rebuild and install your kernel.
+
+<p>
+<label id="wscons">
+XFree86 will also run with the wscons console driver in
+NetBSD 1.4. For now, it uses the pcvt compatibility mode, so be
+sure to have the lines:
+<tscreen><verb>
+options WSDISPLAY_COMPAT_PCVT # emulate some ioctls
+options WSDISPLAY_COMPAT_SYSCONS # emulate some ioctls
+options WSDISPLAY_COMPAT_USL # VT handling
+options WSDISPLAY_COMPAT_RAWKBD # can get raw scancodes
+</verb></tscreen>
+in your kernel configuration file if you're using wscons. Refer to the
+<em>wscons(4)</em> and <em>wsmouse(4)</em> manual pages for
+informations on how to configure wscons into the kernel.
+
+<sect1>Aperture Driver
+<p>
+By default NetBSD 0.9C and higher include the BSD 4.4 kernel security
+feature that disable access to the <tt>/dev/mem</tt> device when in
+multi-users mode. But XFree86 servers can take advantage (or require)
+linear access to the display memory.
+
+Moset recent accelerated servers require linear memory access, some
+other can take advantage of it, but do not require it.
+
+There are two ways to allow XFree86 to access linear memory:
+
+The first way is to disable the kernel security feature by adding
+`option INSECURE' in the kernel configuration file and build a new
+kernel.
+
+
+The second way is to install the aperture driver:
+You can get the aperture driver sources from
+<htmlurl url="ftp://ftp.netbsd.org/pub/NetBSD/arch/i386/apNetBSD.shar"
+name="ftp://ftp.netbsd.org/pub/NetBSD/arch/i386/apNetBSD.shar">.
+
+How to activate it is highly dependent from your exact operating
+system version:
+<itemize>
+<item> NetBSD 1.0, 1.1, 1.2, 1.2.1:
+<p>
+Add the following lines to the end of <tt>/etc/rc.local</tt>:
+<tscreen><verb>
+ KERNDIR=/usr/X11R6/lib/X11/kernel
+ if [ -f ${KERNDIR}/ap.o ]; then
+ modload -o ${KERNDIR}/ap -e ap -p ${KERNDIR}/apinstall ${KERNDIR}/ap.o
+ fi
+</verb></tscreen>
+
+<item> NetBSD 1.2D and later
+<p>
+Add the following line to <tt>/etc/lkm.conf</tt>:
+<tscreen><verb>
+/usr/X11R6/lib/X11/kernel/ap.o - ap /usr/X11R6/lib/X11/kernel/apinstall -
+</verb></tscreen>
+
+<item> NetBSD 1.2G, 1.3 and later
+<p>
+The <tt>lkm.conf</tt> format changed in 1.2G.
+Add the following line to <tt>/etc/lkm.conf</tt>:
+<tscreen><verb>
+/usr/X11R6/lib/X11/kernel/ap.o - ap /usr/X11R6/lib/X11/kernel/apinstall - -AFTERMOUNT
+</verb></tscreen>
+</itemize>
+
+Reboot your system. XFree86 will auto-detect the aperture
+driver if available.
+
+<bf/Warning:/ if you boot another kernel than <tt>/netbsd</tt> or
+<tt>/bsd</tt>,
+loadable kernel modules can crash your system. Always boot in
+single user mode when you want to run another kernel.
+
+<p>
+<quote>
+<bf/Caveat:/ the aperture driver only allows one access at a time
+(so that the system is in the same security state once X is
+launched). This means that if you run multiple servers on multiples
+VT, only the first one will have linear memory access.
+Use 'option INSECURE' if you need more that one X server at a time.
+</quote>
+
+
+<sect1>MIT-SHM
+<p>
+NetBSD 1.0 and later supports System V shared memory. If XFree86
+detects this support in your kernel, it will support the MIT-SHM
+extension.
+
+ To add support for system V shared memory to your kernel add the
+ lines:
+
+<tscreen><verb>
+ # System V-like IPC
+ options SYSVMSG
+ options SYSVSEM
+ options SYSVSHM
+</verb></tscreen>
+
+ to your kernel config file.
+
+<sect> Rebuilding the XFree86 Distribution
+
+<p>
+The server link kit allow you to rebuild just the X server with a
+minimum amount of disk space. Just unpack it, make the appropriate
+changes to the <tt/xf86site.def/, type ``<tt>./mkmf</tt>'' and
+``<tt/make/'' to link the server. See <tt>/usr/X11R6/lib/Server/README</tt>
+for more info.
+
+See <htmlurl url="INSTALL.html" name="INSTALL"> for instructions on
+unbundling and building the source distribution.
+
+You should configure the distribution by editing
+<tt>xc/config/cf/host.def</tt> before compiling. To compile the
+sources, invoke ``<tt/make World/'' in the xc directory.
+
+<sect1>Console drivers<label id="console-drivers">
+
+
+<p>
+XFree86 has a configuration option to select the console
+drivers to use in <tt/xf86site.def/:
+<itemize>
+<item> if you're using pccons put:
+<tscreen><verb>
+ #define XFree86ConsoleDefines -DPCCONS_SUPPORT
+</verb></tscreen>
+<item>if you're using pcvt put:
+<tscreen><verb>
+ #define XFree86ConsoleDefines -DPCVT_SUPPORT
+</verb></tscreen>
+<item>if you're using syscons put:
+<tscreen><verb>
+ #define XFree86ConsoleDefines -DSYSCONS_SUPPORT
+</verb></tscreen>
+<item>if you're running codrv put:
+<tscreen><verb>
+ #define XFree86ConsoleDefines -DCODRV_SUPPORT
+</verb></tscreen>
+</itemize>
+If you don't define <bf/XFree86ConsoleDefines/ in <tt/xf86site.def/ the
+pccons and pcvt drivers will be supported by default.
+
+<p>
+Syscons and codrv are not bundled with NetBSD. They are
+available by anonymous FTP from a number of sites. They are not
+supported by the XFree86 binary distribution anymore.
+
+<sect1>pcvt_ioctl.h file:
+
+<p>
+XFree86's default configuration includes support for the PCVT console
+driver. Unfortunately, NetBSD versions before 19980413 don't install
+the <tt/pcvt_ioctl.h/
+file in <tt>/usr/include/machine</tt>. If you want to build XFree86
+with PCVT support, execute the following command as root before
+starting <tt/make World/:
+<tscreen><verb>
+cp /usr/src/sys/arch/i386/isa/pcvt/pcvt_ioctl.h /usr/include/machine
+</verb></tscreen>
+
+If you don't have kernel sources, you can grab this file from
+ftp.netbsd.org or one of its mirrors. If you're not running PCVT, you
+can remove -DPCVT_SUPPORT from <bf/XFree86ConsoleDefines/ in
+<tt/xf86site.def/ too.
+
+
+<sect1>console.h and ioctl_pc.h files:
+
+<p>
+If you want to build a server supporting codrv and you
+don't already have the corresponding header file
+<tt/ioctl_pc.h/ installed in <tt>/usr/include/machine</tt>, then
+install the copy that is supplied in
+<tt>xc/programs/Xserver/hw/xfree86/etc</tt>. If you run
+NetBSD-current you probably want to install it in
+<tt>/usr/src/sys/arch/i386/include</tt> too, so that it get
+reinstalled each time you run <tt/make includes/.
+
+If you have installed the codrv console driver, this
+file should be taken from your installed version of the driver.
+
+The <tt/console.h/ file for syscons isn't distributed with XFree86
+anymore. You should get it from the syscons distribution.
+
+<sect1>Support for shared libs under NetBSD 1.0 and later
+
+<p>
+By default XFree86 builds for NetBSD with shared libraries
+support. If you're building on 0.9 or don't want shared libraries
+add the following line to <tt/host.def/:
+
+<tscreen>
+ #define BuildBsdSharedLibs NO
+</tscreen>
+
+<sect1>Building on other architectures<label id="sparc">
+
+<p>
+XFree86 also compiles on NetBSD/sparc. The Sun server
+patches from Dennis Ferguson and Matthew Green have been integrated in
+<tt>xc/programs/Xserver/hw/sun</tt>. Small
+modifications to <tt/xf86site.def/ are needed:
+<itemize>
+<item>Set all variables defining the servers to build to
+<bf/NO/. (The variables controlling the Sun servers to build
+<bf/Xsun24Server/, <bf/XsunServer/ and <bf/XsunMonoServer/ are
+defined at the end of <tt/NetBSD.cf/.)
+<item>Set <bf/ServerToInstall/ to the sun server of your
+choice. (Xsun or XsunMono).
+<item>Look at other applicable options in the <htmlurl name="INSTALL document"
+url="INSTALL.html">.
+</itemize>
+
+Problems with this port should be reported to the
+<em/port-sparc@NetBSD.Org/ mailing list or directly to me
+<em/matthieu@laas.fr/ rather than to the xfree86 mailing list.
+
+<p>
+Note that the NetBSD project has now its own source tree, based on the
+XFree86 source tree, with some local modifications. You may want to
+start with this tree to rebuild from sources.
+The NetBSD xsrc source tree is available at:
+<htmlurl url="ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-current/xsrc/"
+name="ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-current/xsrc/">
+
+<sect>Building New X Clients
+
+<p>
+The easiest way to build a new client (X application) is to use
+<tt/xmkmf/ if an <tt/Imakefile/ is included in the sources. Type
+``<tt/xmkmf -a/'' to create the Makefiles, check the configuration if
+necessary and type ``<tt/make/''. Whenever you install additional man
+pages you should update <tt/whatis.db/ by running ``<tt>makewhatis
+/usr/X11R6/man</tt>''.
+
+To avoid the ``Virtual memory exhausted'' message from cc while
+compiling, increase the data and stack size limits (in csh type ``<tt/limit
+datasize 32M/'' and ``<tt/limit stacksize 16M/'').
+
+Note: Starting with XFree86 2.1 and NetBSD 0.9A, the symbol
+<bf/__386BSD__/ no longer gets defined either by the compiler or via the
+X config files for *BSD systems. When porting clients to *BSD
+systems, make use of the symbol <bf/BSD/ for code which is truly
+BSD-specific. The value of the symbol can be used to distinguish
+different BSD releases. For example, code specific to the Net-2 and
+later releases can use:
+
+<tscreen>
+#if (BSD >= 199103)
+</tscreen>
+
+To ensure that this symbol is correctly defined, include
+<tt>&lt;sys/param.h&gt;</tt> in the source that requires it. Note that
+the symbol <bf/CSRG_BASED/ is defined for *BSD systems in XFree86 3.1.1
+and later. This should be used to protect the inclusion of
+<tt>&lt;sys/param.h&gt;</tt>.
+
+For code that really is specific to a particular i386 BSD port, use
+<bf/__FreeBSD__/ for FreeBSD, <bf/__NetBSD__/ for NetBSD,
+<bf/__OpenBSD__/ for OpenBSD,
+<bf/__386BSD__/ for 386BSD, and <bf/__bsdi__/ for BSD/386.
+
+Another note: If you get the message:
+
+<tscreen>
+ ld.so: undefined symbol _XtCvtStringToFont
+</tscreen>
+
+at run-time, you've stumbled on a semantic weakness of the NetBSD
+dynamic linker. Applications that use libXmu also need libXt. If the
+client uses a standard <tt/Imakefile/, this dependency will probably by
+included in the Makefile automagically -- you'll not see the
+problem. Otherwise, just add ``<tt/-lXt/'' to your library list in the
+Imakefile or Makefile and relink.
+
+<sect> Thanks
+<p>
+Many thanks to:
+<itemize>
+<item><bf/Pace Willison/ for providing the initial port to 386BSD.
+<item><bf/Amancio Hasty/ for fixing cursor restoration, mouse bugs
+and many others.
+<item><bf/Christoph Robitschko/ for fixing <tt/com.c/ and thus select().
+<item><bf/Nate Williams/ for the patchkit support for X.
+<item><bf/Rod Grimes/ and <bf/Jack Velte/ of Walnut Creek Cdrom for use
+ of their machines in preparing the FreeBSD binary release.
+</itemize>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/NetBSD.sgml,v 3.49 1999/08/23 06:38:48 dawes Exp $
+
+
+
+
+
+$XConsortium: NetBSD.sgml /main/26 1996/10/28 05:43:20 kaleb $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/OS2.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/OS2.sgml
new file mode 100644
index 000000000..9d4ea2fd9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/OS2.sgml
@@ -0,0 +1,656 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+<title>README for XFree86 on OS/2
+<author>Holger Veit
+<Date>Last modified on: August 1st, 1999
+
+<toc>
+
+<sect>Introductory Note about the release 3.3.5
+<p>
+
+Before looking into this file, please check for any LATEST.OS2 files
+that may come with the binary distribution. Please also check out the
+following XFree86/OS2 WWW pages:
+<itemize>
+<item><htmlurl name="http://set.gmd.de/~veit/os2/xf86os2.html" url="http://set.gmd.de/~veit/os2/xf86os2.html">
+<item><htmlurl name="http://set.gmd.de/~veit/os2/xf86bugs.html" url="http://set.gmd.de/~veit/os2/xf86bugs.html">
+<item><htmlurl name="http://set.gmd.de/~veit/os2/x11os2faq.html" url="http://set.gmd.de/~veit/os2/x11os2faq.html">
+</itemize>
+before you claim to have found any problems.
+
+This version of the code is called XFree86/OS2 3.3.5. This is a
+bugfix release for 3.3.3.1 (3.3.4 was never released for XFree86/OS2)
+which also adds hardware support for some newer cards, including AGP
+boards. XFree86-3.3.5 contains all security fixes that were released
+for earlier versions. See the RELNOTES document for details.
+
+XFree86/OS2-3.3.5 is a full, unrestricted version which does not
+expire, and for which the complete source code is available. In
+contrast to beta versions, we consider this code as sufficiently
+stable for use by an end user. Since there have been numerous
+bugfixes, we recommend this version, even if you had XFree86/OS2 3.3.x
+before and it worked satisfyingly with your hardware. By the time
+3.3.5 is released, the older version 3.3 will be withdrawn, and
+archives will be updated to this version. There may still be
+references to 3.3 or 3.3.x still in documents; these apply
+to 3.3.5 as well, unless otherwise noted.
+
+Previous versions have been tested in a large number of configurations
+and have been found to be working, with some bugs left, rather flawlessly.
+
+This release is almost complete (with a few exceptions) regarding
+the X11R6.3 ``core'' distribution. A subset of the ``contrib'' distribution
+is available from the ported software page
+<htmlurl name="http://set.gmd.de/~veit/os2/xf86ported.html" url="http://set.gmd.de/~veit/os2/xf86ported.html">
+
+In the past beta testing, it has been found that the software itself
+is rather stable and does not damage hardware - provided the user
+does not try to push the builtin limits and change certain
+configuration parameters which could operate the video hardware out
+of specs.
+
+However,
+<itemize>
+<item>even with a code we consider stable there is no explicit or implicit
+ warranty that certain code works correctly or works at all
+<item>although no damage reports are known, it does not mean that it is
+ impossible to damage hardware with this code; some deeply hidden
+ bugs may still be present in the software.
+</itemize>
+
+It is recommended that you backup essential data of your system before
+installing this software, but this should be your general precautions
+before ANY installation. No reports exist that a crashing X server itself
+actively destroys or modifies data, but it is possible in rare cases
+that the system is left in an unusable state (video display mode garbled
+or system unresponsive, not reacting to mouse or keyboard actions).
+If you then hard reset or switch off the system, file caches of the operating
+system might not be written correctly back to disk, thus causing data loss.
+
+<sect>What and Where is XFree86?
+
+<p>
+XFree86 is a port of X11R6.3 that supports several versions of
+Intel-based Unix. It is derived from X386 1.2, which was the X server
+distributed with X11R5. This release consists of many new features
+and performance improvements as well as many bug fixes. The release
+is available as source patches against the X Consortium X11R6 code, as
+well as binary distributions for many architectures.
+<p>XFree86/OS2 is the name of the implementation of XFree86
+on OS/2 based systems.
+
+See the <htmlurl url="COPYRIGHT.html" name="Copyright Notice">.
+
+<!--
+The sources for XFree86/OS2 are available by anonymous ftp from:
+
+<htmlurl name="ftp.XFree86.org:/pub/XFree86/3.3.5/source"
+url="ftp://ftp.XFree86.org/pub/XFree86/3.3.5/source">
+-->
+
+Binaries for OS/2 Warp and Merlin are available from:
+<htmlurl name="ftp.XFree86.org:/pub/XFree86/3.3.5/OS2"
+url="ftp://ftp.XFree86.org/pub/XFree86/3.3.5/OS2">
+<p>
+The WWW page
+<htmlurl name="http://borneo.gmd.de/~veit/os2/xf86os2.html"
+url="http://borneo.gmd.de/~veit/os2/xf86os2.html"> will
+usually show more references to FTP or WWW sites to retrieve
+sources or binaries.
+<p>
+
+Other versions:
+
+XFree86/OS2 will run on all dialects of Warp 3, including Warp "red spine box",
+Warp "blue spine box", Warp Connect, Warp Server, and Warp 4.
+
+For Warp 3 installing fixpack level 17 or later is strongly recommended.
+There have been a few reports that the installation of FP26 causes XFree86
+no longer to work, but I am not sure about a real reason. Current fixpacks
+for Warp 3, like FP36, seem to work well also.
+
+Warp 4 may be used with or without the recent public fixpack.
+
+Please check in all cases a LATEST.OS2 file.
+
+OS/2 2.11 is not supported any longer with this release, due to lack
+of a working test environment. Consequently, OS/2 SMP 2.11 is not supported
+either. Warp Server SMP is supported, but SMP does not give significant
+advantage, other than the general speedup because of multiple processors
+working. OS/2 versions 1.X are definitely not supported and will never be.
+
+It is possible to build XFree86/OS2 from the sources. Read about this
+in the document OS2.NOTES.
+
+<sect>Bug Reports for This Document
+
+<p>
+Send email to <em/Holger.Veit@gmd.de/ (Holger Veit) or
+<em/XFree86@XFree86.org/ if you have comments or suggestions about
+this file and we'll revise it.
+
+<sect>Hardware and Software Requirements
+
+<p>
+<sect1>Supported, Required, and Recommended Hardware
+
+<p>
+<itemize>
+<item>At least a 486DX33 with 16MB RAM is required. A Pentium or Pentium Pro
+ and more main memory is recommended. A 386 or a system with 8MB or less
+ memory is an insufficient configuration.
+<item>There are no specific requirements concerning network cards, disk types,
+ or CD ROM equipment; of course the more powerful, the better.
+<item>Depending on the packages installed, a disk space of 20-55MB on a
+ HPFS formatted partition (or a NFS or ext2fs partition natively
+ allowing long filenames) is required. XFree86/OS2 will not run on FAT partitions.
+<item>You need a video card that is supported by XFree86. Refer to the general
+ README document for a list of supported cards. Note that the sets
+ of video cards supported by XFree86 on one hand and OS/2 on the other
+ hand overlap, but do not match exactly, i.e. the fact that your card
+ is supported by OS/2 does not mean it works with XFree86 as well, and
+ vice versa. XFree86 does not use the video services of the OS/2
+ operating system.
+</itemize>
+
+<sect1>Required Software
+
+<p>
+<itemize>
+<item>Any version of Warp 3 with at least fixpack 17, or Warp 4 is required
+<item>XFree86/OS2-3.3.5 may use a local named-pipe connection or a TCP/IP
+ based network connection.
+ <enum>
+ <item>Warp comes with the Internet Access Kit (IAK), which is
+ sufficient. Warp Connect and Warp Server come with a full
+ version of TCP/IP (3.0). Use of this software is preferred over
+ IAK then.
+ <item>Warp 4 comes with TCP/IP 4.0 which should also work.
+ <item>There are reports that with EMX 0.9 fix 4, you can also use
+ the new 32 bit IBM TCP/IP 4.1 product.
+ <item>The old IBM TCP/IP 2.0, that comes with the IBM PMX product
+ may be used with Warp as well, although it is no longer supported
+ by IBM. Please ensure that you have the latest CSDs installed.
+ </enum>
+ Other versions of TCP/IP, such as FTP's, DEC's, or Hummingbird's
+ TCP/IP versions, as well as IBM TCP/IP 1.X are not supported. Nor does
+ any networking support from DOS (packet drivers, winsock), Netware,
+ or NetBIOS work, and I won't to provide support for that in the future.
+<item>If you want to write or port applications for XFree86, you are
+ encouraged to do so. You will need a complete installation of
+ EMX/gcc 0.9C fix4 or later for doing so. Neither the second (obsolete)
+ implementation of gcc, nor any commercial package, including
+ Cset/2, VAC++, Borland C++/OS2, Watcom C++, Metaware C, and others,
+ is suitable for porting, because various parts of the X DLLs rely
+ on certain features only present with EMX.
+</itemize>
+
+<sect>Installing the System
+
+<p>
+The binary distribution is composed of a number of zip archives
+which are the executables, servers, fonts, libraries, include files,
+man pages, and config files. The full distribution requires about
+40-55MB of disk space.
+
+All archives of this alpha version are packed with the <tt/info-zip/ utility,
+which is available under the name <tt/UNZ512X2.EXE/ (or a later version)
+from many OS/2 archives. Please obtain a native OS/2 version of this unpacker.
+DOS <tt/PKUNZIP/ does not work, because it cannot unpack long file names and
+extended attributes.
+
+At this moment, the distribution covers only the ``core'' distribution
+which somewhat reduces the usability. Refer to WWW sites and archives listed
+in the XFree86/OS2 FAQ and elsewhere to obtain pre-built X clients which
+were ported to XFree86.
+
+ The contents of the packages are:
+
+<descrip>
+<tag/REQUIRED:/
+ <descrip>
+ <tag/Xbase/ A special device driver and the SuperProbe program
+ <tag/Xdoc/ READMEs and XFree86 specific man pages.
+ <tag/Xbin/ all of the executable X client applications and shared libs
+ <tag/Xfnts/ the misc and 75dpi fonts
+ <tag/emxrt/ Runtime libraries of EMX
+ </descrip>
+
+ Choose at least one of the following to match your hardware:
+
+ <descrip>
+ <tag/X8514/ the X server for IBM 8514/A and compatible boards
+ <tag/XAGX/ the X server for AGX boards
+ <tag/XGlnt/ the X server for Permedia / GLINT boards
+ <tag/XI128/ the X server for &num;9 Imagination 128 boards
+ <tag/XMa32/ the X server for ATI Mach32 graphics boards
+ <tag/XMa64/ the X server for ATI Mach64 graphics boards
+ <tag/XMa8/ the X server for ATI Mach8 graphics boards
+ <tag/XMono/ the Monochrome X Server
+ <tag/XP9K/ the X server for P9000 based boards
+ <tag/XS3/ the X server for S3 based boards (excluding S3 ViRGE)
+ <tag/XS3V/ the X server for S3 ViRGE based boards
+ <tag/XSVGA/ the 8-bit pseudo-color X server for Super VGA cards
+ <tag/XVG16/ the 4-bit pseudo-color X server for VGA &amp; SVGA cards.
+ <tag/XW32/ the X server for et4000w32 based boards
+ </descrip>
+
+<tag/OPTIONAL:/
+
+ <descrip>
+ <tag/Xman/ pre-formatted man pages for the X11 interface and clients
+ <tag/Xf100/ 100dpi fonts
+ <tag/Xfscl/ Speedo and Type1 fonts
+ <tag/Xfnon/ Japanese, Chinese and other fonts
+ <tag/Xfcyr/ Cyrillic fonts
+ <tag/Xfsrv/ the font server with man pages.
+ <tag/Xprog/ the X11 header files and programmer's utilities
+ for compiling other X applications
+ <tag/Xpex/ PEX fonts and libraries required for PEX applications
+ </descrip>
+</descrip>
+
+In order to save space on your disk and reduce net bandwidth, choose the
+software to obtain carefully. Each X server is an archive of about 1.2MB
+and occupies 3.0MB on the disk. You won't normally need more than the
+single Xserver tailored to your video card.
+
+If it is your first time install, get the <tt/Xbase/ archive before any
+of the other packages. This package contains a driver and a test program,
+which analyzes your video hardware. If this program fails or reports an
+incompatible hardware, it makes no sense to obtain the other packages in
+the hope that they would magically work.
+
+<sect>Troubleshooting
+
+<p>
+Surprised to see this section directly in the beginning? We have put it here
+because chances are best here not to overlook it. This does not mean that
+you will necessarily encounter trouble when installing XFree86, but be warned:
+the following sections are <bf/IMPORTANT/ and neglecting one or more things
+out of impatience or sloppiness will leave you with a non-working X11
+system and us with unnecessary problems.
+
+Still, due to the incredibly large number of hardware configurations, there
+may be some special situations and configurations where the below description
+is not successful. If this happens, read - I repeat <bf/READ/ - the list
+of ``frequently asked questions'' (FAQ) which has meanwhile evolved to
+a troubleshooting guide. The latest version is always at
+<htmlurl name="http://set.gmd.de/~veit/os2/x11os2faq.html" url="http://set.gmd.de/~veit/os2/x11os2faq.html"> .
+
+Maybe - but we found you must be very creative - you find a bug. Consult the
+page <htmlurl name="http://set.gmd.de/~veit/os2/xf86bugs.html" url="http://set.gmd.de/~veit/os2/xf86bugs.html">
+whether it is already known. If not, you have a case and should report it
+to XFree86 (<em/xfree86@xfree86.org/). Please refer to the FAQ about the
+information to be provided for a complete problem report.
+
+The recommended newsgroup for setup questions is <em/comp.os.os2.setup.misc/.
+I read this group, so it won't speed up the process or enforce anything if
+you post to other groups, or forward the report to my mail address as well
+or to xfree86@xfree86.org.
+
+So, not to discourage you completely, the setup section begins:
+
+
+<sect>Checking Compatibility of Video Hardware
+
+<p>
+In the following, we assume that you want to install XFree86/OS2 on a disk
+drive with the letter Y: (which you probably don't have). Change the letter
+in all commands accordingly.
+
+<enum>
+<item>Obtain the package <tt/Xbase/ and install it from the root directory
+ of the Y: drive, by entering the following commands:
+<tscreen><verb>
+[C:\] Y:
+[Y:\] cd \
+[Y:\] unzip \path_of_package\Xbase.zip
+</verb></tscreen>
+
+<item>Edit your CONFIG.SYS file to contain the following line somewhere:
+<tscreen><verb>
+DEVICE=Y:\XFree86\lib\xf86sup.sys
+</verb></tscreen>
+ Of course replace ``Y:'' with the correct drive letter.
+
+<item>At this point, you may consider to add the variables required for
+ XFree86/OS2 as well, which will save you from one additional reboot.
+ Refer to section <ref id="envvar" name="Adding Variables to CONFIG.SYS">
+ below.
+
+<item>After adding the device driver entry to the CONFIG.SYS file, you must
+ reboot to install the driver. XFree86/OS2 will not work without this
+ driver.
+
+<item>Start a full screen OS/2 CMD session and enter the following
+ command:
+<tscreen><verb>
+[C:\] Y:\XFree86\bin\SuperProbe
+</verb></tscreen>
+
+<item>This command will (normally) report important information about your
+ video configuration, i.e. the type of chipset, the available video
+ memory and the RAMDAC circuit available. Please write this down or
+ redirect the output of ``SuperProbe'' into a file by entering:
+<tscreen><verb>
+[C:\] Y:\XFree86\bin\SuperProbe >filename
+</verb></tscreen>
+
+<item>SuperProbe can identify many more video cards than are supported by
+ XFree86. In some cases, SuperProbe unfortunately detects a wrong
+ card, often it claims to have seen a MCGA card which is some sort of
+ a fallback. Generally, if it is approximately right, there are only
+ few reasons for doubts; if it is totally off (e.g. saying it has
+ seen a ET4000, and you have a Cirrus card), you should report a
+ mis-detection as a bug to the given address. In all cases, please
+ take the few minutes and check the accompanying README.* files to
+ check for special precautions, options, or features of the card.
+
+<item>If the README files tell you that your hardware is supported, please
+ obtain the rest of the software.
+
+</enum>
+
+<sect>Installing the packages
+
+<p>
+XFree86/OS2 assumes a directory hierarchy starting from <tt>drive:&bsol;XFree86</tt>.
+This can be changed, but is strictly discouraged.
+
+<enum>
+<item>Choose a HPFS partition with sufficient free space.
+<item>For each package to install, go to the root directory of this
+ drive, and type:
+<tscreen><verb>
+drive:> cd \
+drive:> unzip \path_of_packages\Xxxxx.zip
+</verb></tscreen>
+<item>You might encounter that some packages report duplicate files, e.g.
+the X server packages install corresponding README files, which are also
+in the Xdoc package. This is okay, the files are the same. Let unzip
+replace the files.
+<item>No special sequence to unpack the files is required.
+</enum>
+
+<sect>Adding Variables to CONFIG.SYS <label id="envvar">
+
+<p>
+XFree86/OS2 requires a number of settings in the CONFIG.SYS file to work
+correctly. Please add the following settings, and in particular take
+care to set forward versus backward slashes correctly:
+
+<descrip>
+<tag/TERM/
+ Set the preferred terminal type for the xterm or editor to be used.
+ Some programs need this setting. I have my type set to
+<tscreen><verb>SET TERM=ansi</verb></tscreen>
+ <tt>&bsol;XFree86&bsol;lib&bsol;X11&bsol;etc&bsol;termcap.x11</tt>
+ contains a suitable termcap which
+ can be used in place of termcap files that come with EMX, EMACS, or
+ other ported software.
+<tag/TERMCAP/
+ This variable must be set to the location where the termcap file
+ used for the above <tt/TERM/ variable is searched. My setting, for
+ instance, is:
+<tscreen><verb>SET TERMCAP=D:/EMX/ETC/TERMCAP.X11</verb></tscreen>
+ Note that forward ``/'' is used as a directory separator.
+<tag/ETC/
+ Set to an ETC directory. Normally, this is already set to the ETC
+ directory of the TCP/IP code, such as
+<tscreen><verb>SET ETC=C:&bsol;TCPIP&bsol;ETC</verb></tscreen>
+<tag/TMP/
+ Set to an TMP directory. Normally, this is already set to the TMP
+ directory of the TCP/IP code, such as
+<tscreen><verb>SET TMP=C:&bsol;TCPIP&bsol;TMP</verb></tscreen>
+<tag/HOSTNAME/
+ Set to the internet hostname. Normally, this is already set by the
+ TCP/IP installation program, such as
+<tscreen><verb>SET HOSTNAME=myhost</verb></tscreen>
+ With IAK, you would normally run a loopback configuration
+ <ref id="loopback" name="Network configuration"> and would then
+ set this to
+<tscreen><verb>SET HOSTNAME=localhost</verb></tscreen>
+<tag/USER/
+
+<tag/LOGNAME/
+ Set both to a username. Currently, they are there just to make some
+ programs happy; in the future, this variable might be set by a
+ login shell of a multiuser configuration. My variable, for instance,
+ is set to
+<tscreen><verb>
+ SET USER=holger
+ SET LOGNAME=holger
+</verb></tscreen>
+<tag/HOME/
+ Set this to an existing directory that is supposed to be a home directory
+ of a user. Some utilities place temporary and init files here. This
+ is also future investment for a multiuser configuration, but must still
+ be there. For instance, this variable might be set to
+<tscreen><verb>SET HOME=H:&bsol;user&bsol;holger</verb></tscreen>
+<tag/X11ROOT/
+ This is one of the most important settings, it determines the root
+ of the XFree86 directory tree. Normally, you will set this to the
+ drive letter of the partition where the &bsol;XFree86 tree resides,
+ such as in
+<tscreen><verb>SET X11ROOT=Y:</verb></tscreen>
+ You may try to move the tree to another subdirectory, e.g. to
+ <tt>K:&bsol;OS2&bsol;X11&bsol;XFree86...</tt> and would then have
+ to change this to
+<tscreen><verb>SET X11ROOT=K:/OS2/X11</verb></tscreen>,
+ but this is discouraged, since some utilities might not accept this.
+ Note the forward ``/'' as a directory separator here.
+<tag/DISPLAY/
+ This variable may be set to the display to be used for displaying
+ clients. Normally you will set this variable to the same value as
+ the <tt/HOSTNAME/ variable and simply add a <tt/:0.0/ after it, such as
+<tscreen><verb>SET DISPLAY=myhost:0.0</verb></tscreen>
+ Read the X11 man page on the exact meaning of these postfixes and
+ other options.
+<tag/XSERVER/
+ Set this to the executable name of the X server to be used. This
+ must be a complete path. My setting is as follows:
+<tscreen><verb>SET XSERVER=D:/XFree86/bin/XF86_Mach64.exe</verb></tscreen>
+<tag/PATH/
+ Add the binary directory for the X11 utilities to your search PATH.
+ This is normally the directory (adjust the letter)
+<tscreen><verb>Y:&bsol;XFree86&bsol;bin</verb></tscreen>
+ It is possible to move the binaries to another directory in the
+ search path; for maintenance reasons and clarity of the structure, this
+ is not recommended, though.
+<tag/LIBPATH/
+ Add the DLL directory for the X11 utilities to the LIBPATH.
+ This is normally the directory (adjust the letter)
+<tscreen><verb>Y:&bsol;XFree86&bsol;lib</verb></tscreen>
+ It is possible to move the DLLs to another directory in the
+ library path; for maintenance reasons and clarity of the structure,
+ this is not recommended, though. Note that
+ <tt>Y:&bsol;XFree86&bsol;lib</tt>
+ has several other subdirectories; these may not be moved elsewhere,
+ rather they must stay there, because most utilities form a path to
+ these directories by using <tt>%X11ROOT%&bsol;XFree86&bsol;lib</tt>
+ as a base.
+</descrip>
+
+The recent version of XFree86/OS2 has a REXX script named <tt/checkinstall.cmd/
+which you can (and should) use to check whether you have entered most things
+correctly. This is not bullet-proof, but prevents the most obvious
+setup problems. Also, the X server itself will do some checking and will
+refuse to start if something is wrong.
+
+<sect>Remarks on the Network Configuration
+
+<p>
+It is beyond the scope of this document to even give an introduction about
+the correct installation of the TCP/IP networking system. You must do this
+yourself or seek assistance elsewhere. It is only possible to say here that
+a PC working well in a TCP/IP based LAN network will also work with
+XFree86/OS2 (when all other prerequisites are matched as well).
+
+<label id="loopback">With IAK, there is a special configuration necessary,
+unless you want to use XFree86/OS2 only during a hot link to your Internet
+provider, the so called ``localhost'' or ``loopback'' configuration. This is
+a local network interface which ``loops'' back to the same host. The following
+settings are necessary for this:
+
+<enum>
+<item>Create a file <tt>&bsol;tcpip&bsol;etc&bsol;hosts</tt> with the
+ following content:
+<tscreen><verb>127.0.0.1 localhost</verb></tscreen>
+<item>Add the following line to your
+ <tt>&bsol;tcpip&bsol;bin&bsol;tcpstart.cmd</tt>:
+<tscreen><verb>ifconfig lo 127.0.0.1 up</verb></tscreen>
+ If you don't have such a tcpstart.cmd file (Warp 4 calls this file
+<tt>&bsol;MPTN&bsol;BIN&bsol;MPTSTART.CMD</tt>), create one, and add a line
+like the following to your config.sys file:
+ <tt>CALL=C:&bsol;OS2&bsol;CMD.EXE /Q /C C:&bsol;tcpip&bsol;bin&bsol;tcpstart.cmd &gt;NUL</tt>:
+(implying that your bootdrive is C:).
+<item>Set the HOSTNAME environment variable to <tt/localhost/ as described
+ in the last section.
+<item>Add the following line to CONFIG.SYS:
+<tscreen><verb>SET USE_HOSTS_FIRST=1</verb></tscreen>
+<item>After rebooting, verify that the following command works:
+<tscreen><verb>[C:&bsol;] ping localhost</verb></tscreen>
+</enum>
+
+You don't need this ``loopback'' interface if your PC is connected to a LAN
+(either directly or through SLIP/PPP).
+
+In case of a SLIP/PPP line, you have to establish this connection BEFORE
+you start XFree86.
+
+The <tt/checkinstall.cmd/ script coming with XFree86/OS2 gives some advice
+on the configuration as well.
+
+If you have problems to get this or other basic networking things running,
+seek assistance elsewhere.
+
+<sect>Configuring X for Your Hardware
+
+<p>
+After you have added the required settings and setup a working network,
+run the <tt/xf86config/ program to create a standard configuration file
+in <tt>Y:&bsol;XFree86&bsol;lib&bsol;X11&bsol;XF86Config</tt> from a windowed
+or full screen OS/2 text session:
+<tscreen><verb>[C:&bsol;] xf86config</verb></tscreen>
+
+The <tt/xf86config/ program will ask a number of questions. You will need
+the information obtained from the SuperProbe program here. The program should
+be self explanatory; if you have problems to understand something though, seek
+assistance in the newsgroups.
+
+It is possible, but strongly discouraged for the non-expert, to edit the
+<tt/XF86Config/ file with a text editor. In a few situations as described in
+the FAQ, however, this might even be mandatory. This file is not a hacker's area,
+such as the Win95 registry, but it has in common with it that you can
+easily cause damage.
+
+For details about the <tt/XF86Config/ file format, refer to the
+<em>XF86Config(4/5)</em> manual page.
+
+If you know the configuration process from Linux or other XFree86 platform,
+you will encounter a few differences:
+<itemize>
+<item>There is no configuration for the mouse type or device. The mouse
+ device name is fixed to OSMOUSE, and this cannot be changed.
+ If you have a three-button-mouse, install the correct OS/2 driver
+ for it, such as
+<tscreen><verb>
+DEVICE=D:&bsol;OS2&bsol;BOOT&bsol;PCLOGIC.SYS SERIAL=COM1
+DEVICE=D:&bsol;OS2&bsol;BOOT&bsol;MOUSE.SYS TYPE=PCLOGIC$
+</verb></tscreen>
+ for a MouseSystems compatible mouse, for instance.
+<item>The X server does not read the native OS/2 keyboard map, but the new XKB
+ server extension might already give you a correct keyboard layout,
+ provided your language was selectable in the <tt/xf86config/ program. If you
+ encounter incorrect settings, please send a mail to <tt/XFree86@XFree86.org/
+ describing in detail what is wrong. Even with XKB, you have the option
+ to replace some key settings with a xmodmap file. See the man page
+ for xmodmap for details (or use some available xmodmap file from Linux -
+ they are the same).
+<item>There is no support for the Wacom and Elographics input devices yet.
+</itemize>
+
+In most cases, an existing <tt/XF86Config/ file for the same XFree86 version
+from Linux or another platform may be used without changes. There is one
+prominent exception: some S3 805 based VLB cards put their video memory
+in odd locations. The X server can search for this memory by experimentally
+mapping and unmapping possible memory regions. In XFree86/OS2, the OS may
+run out of memory tiles during this process. If this happens, you must
+find out the location of the memory yourself and add it as an option
+<tscreen><verb>
+ MemBase 0x12345678
+</verb></tscreen>
+to the XF86Config file.
+
+Once you've set up a XF86Config file, you can fine tune the video
+modes with the <tt>xvidtune</tt> utility.
+
+<sect>Running X
+
+<p>
+16mb of memory is a recommended minimum for running the network software,
+X and the presentation manager in parallel. The server, window manager and
+an xterm take about 4-6 Mb of memory themselves. X will start up on a
+system with 8MB or less, but the performance will severely suffer from
+heavy disk swapping. Your mileage may vary, though, so some people might
+consider this still tolerable.
+
+The easiest way for new users to start X windows is to type:
+<tscreen><verb>[C:&bsol;] startx</verb></tscreen>.
+
+To get out of X windows, type: ``<tt/exit/'' in the console xterm.
+You can customize your X by creating <tt/.xinitrc/, <tt/.xserverrc/,
+and <tt/.twmrc/ files in the directory that the <tt/HOME/ environment
+variable points to. These files are described in the xinit and startx
+man pages.
+
+By default, the systemwide <tt/xinitrc/ file (in <tt>Y:/XFree86/lib/X11/xinit/xinitrc.cmd</tt>)
+installs the rather simplistic <tt/twm/ window manager. You can find better
+window managers on the ported software page at
+<htmlurl name="http://set.gmd.de/~veit/os2/xf86ported.html" url="http://set.gmd.de/~veit/os2/xf86ported.html"> .
+
+
+<sect>Rebuilding the XFree86 Distribution
+
+<p>
+Do you really want to rebuild XFree86/OS2 from source? Read the file
+<htmlurl name=OS2.Notes url=OS2Notes.html>
+on details to recompile XFree86/OS2 from scratch.
+
+<sect>Building New X Clients
+
+<p>
+The easiest way to build a new client (X application) is to use
+<tt/xmkmf/ if an <tt/Imakefile/ is included in the sources. Type
+``<tt/xmkmf -a/'' to create the Makefiles, check the configuration if
+necessary and type ``<tt/xmake/''. ``<tt/xmake/'' is a wrapper for the
+GNU make program which defeats the improper SHELL setting typically found
+in a Makefile generated from an Imakefile. Also see the XFree86/OS2 FAQ
+for more hints about porting X clients.
+
+<sect>Acknowledgements
+
+<p>
+Many thanks to:
+<itemize>
+<item><bf/Sebastien Marineau/ for his great work on getting the server code
+debugged
+<item><bf/Eberhard Mattes/ for the wonderful base platform EMX which this
+port heavily relies on
+<item><bf/ME/ - no, no, forget this: I won't praise myself :-)
+</itemize>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/OS2.sgml,v 3.13 1999/08/23 06:38:49 dawes Exp $
+
+
+
+
+
+$XConsortium: OS2.sgml /main/4 1996/03/11 10:46:06 kaleb $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/OS2note.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/OS2note.sgml
new file mode 100644
index 000000000..daf7d7a76
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/OS2note.sgml
@@ -0,0 +1,213 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+<article>
+
+<title>Notes on Rebuilding XFree86/OS2 from Scratch
+<author>Holger Veit
+<date>Last modified August 1st, 1999
+
+<toc>
+
+<sect>Preface
+<p>
+X11 and XFree86 were initially developed on Unix-based systems. Usually
+Unix systems provide a rich number of tools and utilities to get certain
+things done. Under OS/2, these tools are not installed, but ports are
+available which are sometimes functionally equivalent to Unix utilities
+with the same name, but also differ sometimes in a subtle way.
+This guide will give you hints if you intend to rebuild the system
+from scratch under OS/2.
+<p>
+Please also read <htmlurl name=README.OS2 url=OS2.html> for end-user
+information, and set at least the environment variables described there.
+<p>
+At the current time, the most recent version available is XFree86-3.3.5.
+This is a full and unrestricted version which comes with complete source
+code. 3.3.5 is not only a bugfix release, but also supports new hardware,
+some of which might not even supported by OS/2 itself. See the RELEASE NOTES
+document for details.
+
+If you want to join the XFree86 developer team, e.g. to add support for
+certain hardware, please send a request to BOD@XFree86.org. Please
+think about such a step carefully before, though, since much work is
+involved. Please use the XFree86-3.3.5 source code as a test example how
+to compile the system. The ability to manage that is a basic requirement
+for becoming a developer.
+
+
+<sect>Tools required
+<p>
+
+I have tried to reduce the number of external tools, but when looking back
+it seems I were not very successful. At least I managed to get everything
+working with the native CMD.EXE shell only. However, there is still plenty
+of software required.
+Most of this software is available from <tt/hobbes.nmsu.edu/ or <tt/ftp.leo.org/
+via anonymous FTP. The following shopping list shows what you will need:
+
+<itemize>
+<item>gcc EMX/gcc emx 0.9C patch4 or later (0.9d preferred!)
+<item>gzip GNU zip/unzip
+<item>tar GNU tar
+<item>patch Larry Wall's patch utility (attention: incompatible tool with same name in OS/2)
+<item>install BSD/GNU install
+<item>rm,mv,cp GNU file utilities
+<item>tee,.. GNU shell utilities
+<item>groff GNU nroff/troff
+<item>sed GNU sed stream editor
+<item>grep GNU grep
+<item>gawk GNU awk
+<item>make GNU make 3.71/3.72 (use the one from Xprog.zip!)
+<item>flex GNU flex
+<item>bison GNU bison
+<item>find GNU find (attention: incompatible tool with the same name in OS/2)
+</itemize>
+
+If there is no version number given, any new version will do. Particularly
+critical is only EMX/gcc and GNU make. Note that the second GCC implementation
+which might still be available from some archives is NOT compatible.
+
+Furthermore, you need the XFree86 sources. These are available from
+the common XFree86 repositories. Look into a directory which is
+often named /pub/XFree86/3.3.5/source.
+
+<sect>Compiling and Installing
+<p>
+
+You need about 300MB of free HPFS space for the whole system. This does not
+include space for the postscript and troff documentation files. I have never
+installed them. Nor did I install the test subtree.
+
+<enum>
+<item>Install all the above utilities. Refer to the corresponding documentation.
+ Verify that everything works well, particularly EMX.
+<item>It is a good idea to use the same or a similar structure I have.
+ I have made a directory <tt>&bsol;x11</tt> on the partition for compiling and have
+ put everything below this tree. I found that a clean tree occupies
+ less than the half space of the disk, this gives me the opportunity to
+ rename this tree to <tt>&bsol;x11old</tt> and copy a new version to the
+ same disk to produce diffs. Last time the complete tree was
+ arranged under the root directory <tt>xc</tt>, this would become
+ <tt>&bsol;x11&bsol;xc</tt> then.
+<item>To unpack the files you would usually execute the command
+ <verb>gzip -dc file.tar.gz | tar xvf -</verb>
+ in the <tt>&bsol;x11</tt> directory. At the end you will usually see the
+ irritating, but non-fatal message "gzip: stdout Broken pipe". Ignore it.
+<item>After that, is is likely necessary to apply some patches, either from
+ the XConsortium or from the XFree86 project. Before you do this, enter
+ <verb>
+ chmod -R a+rw &bsol;x11&bsol;xc
+ </verb>
+ to make certain files in the tree writable.
+<item>There should be a file <tt>added-XXX</tt> accompanying the patch file
+ which lists the files that are newly created. The patch program has
+ a problem with creating new directories, so we need to create them
+ on advance. For each <tt/added-XXX/ file you find, execute from
+ <tt>&bsol;x11</tt> <verb>xc&bsol;config&bsol;util&bsol;added added-XXX</verb>
+ If there is no <tt>added-XXX</tt> file available, you can make one with
+ the following instructions:
+ <verb>
+ grep "&bsol;*&bsol;*&bsol;* xc/" patchfile >added-file
+ </verb>
+ Edit <tt/added-file/ with a text editor and remove the <tt/*** / at
+ the beginning and the time stamp at the end (search for a TAB and
+ erase to the end of the line). You get a list of file paths, one in a
+ line, which is the input to the added utility.
+<item>After that you can apply the patches in the right order. Usually this
+ is done by a command
+ <verb>
+ patch -p -E <patchfile 2>&1 | tee patchlog
+ </verb>
+ from the <tt>&bsol;x11</tt> directory. Be aware to use the right
+ patch - OS/2 has a utility with the same name and different functionality.
+ Don't use the recommended <tt/-s/ option, this makes <tt/patch/ quiet,
+ and you won't see problems in the patchlog file. Use
+ <verb>
+ find &bsol;x11 -name *.rej -print
+ find &bsol;x11 -name *# -print
+ </verb>
+ to find any rejects and unapplied patches (attention: yet another OS/2
+ program with wrong functionality). Normally there shouldn't
+ be any problems of this kind, else you have made a mistake. Finally
+ remove the original files with
+ <verb>
+ find &bsol;x11 -name *.orig -print -exec rm {} ;
+ </verb>
+<item>Go to the <tt>xc/config/cf</tt> directory and edit the <tt>xf86site.def</tt>
+ file to match your requirements (you probably don't want to compile
+ all X servers). Certain changes must be set to the following values:
+ <itemize>
+ <item>Disable if not already done any PC98 server; PC98 (Japanese XFree86)
+ does not work yet. Porters from Japan are welcome!
+ <item><tt>&num;define WacomSupport NO
+ &num;define ElographicsSupport NO</tt>
+ Both options are not yet supported.
+ <item>Tcl* and Tk* don't need to be set explicitly. Reasonable defaults
+ are in the other config files, provided you have a complete
+ XFree86/OS2 binary tree with the tcl/tk runtime support installed.
+ <item><tt>&num;define BuildDynamicLoading NO</tt>
+ This does not work.
+ </itemize>
+<item>Go to the directory <tt>xc&bsol;util&bsol;compress</tt> and
+ <tt>make compress.exe</tt> there. Install the program produced
+ there in your path. I stumbled more than once on half-ported
+ compress programs on OS/2 ftp servers that are defective w.r.t.
+ reading and writing stdin/stdout. In some stage (font compression)
+ otherwise you will get a core dump of mkfontdir, because all
+ compressed fonts are corrupt.
+<item>Set the environment variable <tt/X11ROOT/ to something different than
+ it is; otherwise the installation process will overwrite your
+ original XFree86/OS2 installation. If you have not set this variable,
+ go back to the prefix section of this document: you have forgotten
+ something.
+<item>Copy the file <tt>xc/programs/Xserver/hw/xfree86/etc/bindist/OS2/host.def.os2</tt>
+ to the location <tt>xc/config/cf/host.def</tt>. Use this file to do
+ any specific modifications to imake variables, rather than editing
+ the file xfree86.cf, imake.tmpl, or os2.cf directly.
+<item>Copy the file <tt>xc/config/util/buildos2.cmd</tt> into the <tt/xc/
+ directory. If this is a second or later attempt, you might need to
+ copy the saved toplevel Makefile.os2 back to Makefile.
+<item>Execute this <tt/buildos2.cmd/ command in the <tt/xc/ directory;
+ it will produce a logfile <tt>buildxc.log</tt> in this directory.
+<item>Go have a bucket of coffee, or better, buy new coffee - in Colombia!
+ The compile will need between 2 and 20 hours, depending on your
+ selections, and the horse power of your hardware.
+<item>When finished, view the logfile for errors, and fix the problems if
+ there are some. I have managed to compile the whole system
+ flawlessly, so there is at least one configuration that works.
+<item>Finally, from the <tt/xc/ dir, execute
+ <verb>
+ xmake install
+ xmake install.man
+ </verb>
+<item>There are a few minor glitches in the installation:
+<enum>
+<item>The xdm and linkkit directories will fail in compile and installation.
+ This is no problem and has no effect on the rest of the system.
+<item>The imake.exe which is installed in <tt/&bsol;XFree86&bsol;bin/ is usually defective.
+ The one which was built initially and installed in the root directory
+ of the drive where you have the source tree is okay. So simply copy
+ this <tt/&bsol;imake.exe/ to the <tt/&bsol;XFree86&bsol;bin/ directory
+ manually. Some day this might be fixed.
+<item><tt/XF86Setup/ is not ported yet and won't work with the tcl/tk port
+ available for XFree86/OS2. My idea was to replace this by some native
+ installation tool, which I didn't find the time to do yet. Feel free
+ to spend a bit of time to play with XF86Setup if you like.
+</enum>
+</enum>
+
+Well, you see, this was quite easy :-)
+
+
+
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/OS2note.sgml,v 3.6 1999/08/23 06:38:50 dawes Exp $
+
+
+
+
+
+$XConsortium: OS2note.sgml /main/1 1996/02/24 10:08:59 kaleb $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/Oak.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/Oak.sgml
new file mode 100644
index 000000000..be1ede736
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/Oak.sgml
@@ -0,0 +1,213 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+
+<!-- Title information -->
+<title>Information for Oak Technologies Inc. Chipset Users
+<author>Jorge F. Delgado Mendoza (<it>delgadomendoza.j@pg.com</it>)
+<date>17 August 1999
+
+<!-- Table of contents -->
+<toc>
+
+<sect>Supported chipsets <p>
+
+The driver is used in the 8-bit / 256-color SVGA server and the mono
+server. The following chipsets for Oak Tech. Inc. are supported:
+<descrip>
+<tag>OTI037C</tag>
+ 8-bit VGA chipset, with up to 256Kbytes of DRAM. All the
+ boards I have seen are only able to do standard VGA modes.
+ (ie. up to 320x200x256 and up to 640x480x16). Currently the
+ probe for this chip is disabled, so use the generic VGA
+ driver instead.
+<tag>OTI067</tag>
+ ISA SVGA chipset, up to 512Kbytes of DRAM (usually 70/80 ns).
+<tag>OTI077</tag>
+ Enhanced version of the 067, with support for 1Mbyte and
+ up to 65 Mhz dot-clock. This chipset is capable of resolutions
+up to
+ 1024x768x256 colors in Non-Interlaced mode, and up to
+ 1280x1024x16 colors Interlaced.
+<tag>OTI087</tag>
+ One of the first VLB chipsets available, it has a 16-bit
+ external data path, and a 32-bit internal memory-controller
+ data path. It features some acceleration hardware:
+ register-based color expansion, hardware cursor,
+ a primitive BitBlt engine, a 64 bit graphic latch and some
+ other new (on its time) features.
+ Maximum BIOS resolutions are 1024x768x256
+ Non-Interlaced and 1280x1024x256 interlaced. Maximum
+ Dot-Clock is 80Mhz, but is usually coupled with the OTI068
+ clock generator capable of frequencies up to 78Mhz.
+ This chipset supports up to 2MBytes of 70/70R ns DRAM.
+
+<tag>OTI107 and OTI111</tag>
+ These are new, PCI chipsets by Oak Tech. Inc. Support is not
+ included for them, as they are very rare and I haven't had
+ the chance to look at one of these boards.
+ We have been unable to locate 107's. If anybody has such a board and
+ can donate it to XFree86, we would be more than glad to add
+ support for them.
+ <p>
+ An OTI111 is now available and we are working on support for it.
+</descrip>
+
+All the chipsets up to the OTI087 are "Backwards compatible",
+in fact some early drivers for the OTI087 based chipsets were
+those made for the 077.
+
+Accelerated support is included only for OTI087 chipsets, also Mono
+server is only included for 067/077 chipsets.
+
+<sect>XF86Config options <p>
+
+The following options are of particular interest to the Oak driver. Each
+of them must be specified in the 'svga' driver section of the
+<tt>XF86Config</tt> file, within the Screen subsections to which they
+are
+applicable (you can enable options for all depths by specifying them in
+the
+Device section).
+
+<descrip>
+<tag>
+Option "linear" (OTI087)
+</tag>
+ This option enables a linear framebuffer at 0xE00000 (14Mb) for
+ cards recognized as ISA by the probe. Cards that are VLB will
+ map the framebuffer at 0x4E00000. The aperture depends
+ on the VideoRam parameter in the <tt>XF86Config</tt> file or on
+ the probed value for the board. It will speed up performance by
+ about 15&percnt; on a VLB-based boards for a DX2-66 486.
+
+
+ Sometimes a motherboard will not be able to map at 0x4E00000,
+ and then linear mode will not work with more than 14 Mbytes of
+ main RAM. I know this because mine doesn't.
+<tag>
+Option "fifo_aggressive" (OTI087)
+</tag>
+ This option will cause the command FIFO threshold of the
+ chipset to be set at 0 instructions, which should be optimal
+ for 16-bit data transfers, as empirical use of different
+ thresholds, with xbench, show. Expect a 5-10&percnt; of
+performance
+ boost on a DX2-66 486.
+<tag>
+Option "fifo_conservative" (OTI087)
+</tag>
+ This option will set the FIFO to a safe value of 14, slowing
+ the board by a 50&percnt;, use this only if you experience
+streaks or
+ anomalies on the screen.
+<tag>
+Option "enable_bitblt" (OTI087)
+</tag>
+ This option will enable an internal cache on the board that
+ will be used as a rudimentary bitblt engine. Performance boost
+ is more or less 100&percnt;, (double BlitStones on xbench). Most
+ OTI087 boards seem to have this feature broken, corrupting text
+ from xterms and leaving mouse droppings throughout the
+ screen. As a rule of thumb, enable it, if it works badly,
+ disable it.
+<tag>
+Option "clock_50" (OTI087)
+</tag>
+ This one will force the internal speed to 50 Mhz.
+<tag>
+Option "clock_66" (OTI087)
+</tag>
+ This one will force the internal speed to 66 Mhz, speeding up
+ performance of the chipset.
+
+<tag>
+Option "no_wait" (OTI087)
+</tag>
+ Sets the VLB interface to no wait states. On a medium VLB
+ board (mine is VLB/PCI, so its not a very fast one) in VLB
+ transparent mode, it manages up to 16 Mbytes/second transfer
+ rate through the bus.
+<tag>
+Option "first_wait" (OTI087)
+</tag>
+ Makes the VLB interface to add one wait state to the first
+ read or write of a given burst.
+<tag>
+Option "first_wwait" (OTI087)
+</tag>
+ Similar to the previous one, this only inserts a wait state in
+ the first 'write' of a given burst. reads are not
+ affected. This is the default behaviour of the server.
+<tag>
+Option "write_wait" (OTI087)
+</tag>
+ This configures the VLB interface to add one wait state to
+ each write cycle.
+<tag>
+Option "read_wait" (OTI087)
+</tag>
+ This configures the VLB interface to add one wait state to
+ each read cycle.
+<tag>
+Option "all_wait" (OTI087)
+</tag>
+ Enables the slowest VLB transfer adding wait states in all
+ cases. Hopefully, no board will need this enabled.
+<tag>
+Option "one_wait" (OTI087)
+</tag>
+ Sets the VLB interface to at least one wait state.
+<tag>
+Option "noaccel" (OTI087)
+</tag>
+ One accelerated routine has been lately added to the driver,
+ allowing it to draw solid fills quite faster. This routine
+ only works (up to date) on segmented addressing, and only if
+ the virtual width is 1024. This option is automatically enabled
+ by the driver. Use this option if you want to disable it.
+</descrip>
+
+As a rule of thumb, use the option "no_wait", and if it doesn't
+result in corrupting text, lucky you. If not, try "first_wwait", and
+downwards. ISA card owners should not use these options.
+
+<sect>Mode issues <p>
+
+ The use of very high dot-clocks has a REAL negative effect on the
+ performance of the boards, due to its limited 80Mbit/sec, higher
+ dot clocks limit its ability to draw data into the
+ framebuffer. Thus expect better performance of a 72Mhz based mode
+ than on a 78Mhz based one (for example) where more bandwidth is
+ required for screen refresh.
+
+ It does not make much sense to use the highest clock (78 MHz) for
+ 1024x768 at 76 Hz on a OTI087; the card will almost come to a
+ standstill. A 72 MHz dot clock results in 70 Hz which should be
+ acceptable. If you have a monitor that supports 1024x768 at 76 Hz
+ with a 78 MHz dot clock, a standard OTI087 based card is a poor
+ match anyway.
+
+<sect>Linear addressing<p>
+
+ Linear addressing is hardwired to 14 Mbytes for ISA boards
+ and 78 Mbytes for VLB boards, thus if you have more
+ than that on your board you shouldn't enable it.
+ The aperture is selected from the VideoRam
+ parameter of the XF86Config or from the amount of memory that is
+ detected if VideoRam is not found.
+
+ I hope (because I have not tested it very thoroughly) that linear
+ addressing will work on all ISA boards, VLB ones work flawlessly.
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/Oak.sgml,v 3.13 1999/08/23 06:38:50 dawes Exp $
+
+
+
+
+
+$XConsortium: Oak.sgml /main/8 1996/05/12 20:58:00 kaleb $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/OpenBSD.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/OpenBSD.sgml
new file mode 100644
index 000000000..b7aba4214
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/OpenBSD.sgml
@@ -0,0 +1,411 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+<title>README for XFree86 on OpenBSD
+<author>
+Matthieu Herrb
+<Date>Last modified on: 25 June 1999
+
+<toc>
+
+
+<sect>What and Where is XFree86?
+
+<p>
+XFree86 is a port of X11R6.3 that supports several versions of
+Intel-based Unix. It is derived from X386 1.2, which was the X server
+distributed with X11R5. This release consists of many new features
+and performance improvements as well as many bug fixes. The release
+is available as source patches against the X Consortium X11R6.3 code, as
+well as binary distributions for many architectures.
+
+See the <htmlurl url="COPYRIGHT.html" name="Copyright Notice">.
+
+The sources for XFree86 are available by anonymous ftp from:
+
+<htmlurl name="ftp://ftp.XFree86.org/pub/XFree86/current"
+url="ftp://ftp.XFree86.org/pub/XFree86/current">
+
+Binaries for OpenBSD 2.5 and later are available from:
+
+<htmlurl name="ftp://ftp.XFree86.org/pub/XFree86/current/binaries/OpenBSD"
+url="ftp://ftp.XFree86.org/pub/XFree86/current/binaries/OpenBSD">
+
+A list of mirror sites is provided by
+<htmlurl name="ftp://ftp.XFree86.org/pub/XFree86/MIRRORS"
+url="ftp://ftp.XFree86.org/pub/XFree86/MIRRORS">
+
+<p>
+
+XFree86 also builds on other OpenBSD architectures. See section
+<ref id="otherarch" name="Building on other architectures"> for details.
+
+
+<sect>Bug Reports for This Document
+
+<p>
+Send email to <em/matthieu@laas.fr/ (Matthieu Herrb) or
+<em/XFree86@XFree86.org/ if you have comments or suggestions about
+this file and we'll revise it.
+
+<sect>New features in this release
+<p>
+<itemize>
+<item>The maximum number of open connections in the server has been
+raised to 128,
+<item>the <tt>resize</tt> utility was fixed.
+</itemize>
+<p>
+See the <htmlurl url="RELNOTES.html" name="Release Notes"> for
+non-OS dependent new features in XFree86 3.3.4.
+
+<sect>Installing the Binaries
+
+<p>
+Refer to section 5 of the <htmlurl url="RELNOTES.html" name="Release
+Notes"> for detailed installation instructions.
+
+<sect>Configuring X for Your Hardware
+
+<p>
+The <tt>/etc/XF86Config</tt> file tells the X server what kind of
+monitor,
+video card and mouse you have. You <em/must/ create it to tell the
+server what specific hardware you have.
+<p>
+The easiest way to create this file is to run the <bf/XF86Setup/
+utility as root. Refer to <htmlurl url="QuickStart.html"
+name="QuickStart.doc"> for details about its use.
+<p>
+You'll need info on your hardware:
+<itemize>
+<item>Your mouse type, baud rate and its /dev entry.
+<item>The video card's chipset (e.g. ET4000, S3, etc).
+<item>Your monitor's sync frequencies.
+</itemize>
+
+The recommended way to generate an <tt/XF86Config/ file is to use the
+<tt/XF86Setup/ utility. The xf86config text utility is still there
+for the (few) cases where XF86Setup can't be used. Also, there is a
+sample file installed as <tt>/usr/X11R6/lib/X11/XF86Config.eg</tt>,
+which can be used as a starting point.
+
+For details about the <tt/XF86Config/ file format, refer to the
+<em>XF86Config(5)</em> manual page.
+
+Once you've set up a XF86Config file, you can fine tune the video
+modes with the <tt>xvidtune</tt> utility.
+
+
+<sect1>About mouse configuration
+
+<p>
+If your serial mouse does not work try using <tt>kermit</tt> or
+<tt>tip</tt> to connect to the mouse serial port and verify that it
+does indeed generate characters.
+<p>
+The OpenBSD pms driver provides both ``raw'' and ``cooked''
+(translated) modes. ``raw'' mode does not do protocol translation, so
+XFree86 would use the <bf>PS/2</bf> protocol for talking to the device
+in that mode. ``Cooked'' mode is the old BusMouse translation.
+The driver runs in ``raw'' mode when using the <tt>/dev/psm0</tt>
+device name.
+<p>
+On OpenBSD 2.2, only standard PS/2 mice are supported by this
+driver.
+<p>
+On OpenBSD 2.3 and later include there is support for recent PS/2
+mice that send more than three bytes at a time (especially
+intellimouse, or mouseman+ with a "3D" roller).
+<p>
+See <htmlurl url="mouse.html" name="README.mouse"> for general
+instruction on mouse configuration in XFree86.
+
+<sect1>Other input devices
+<p>
+XFree86 supports the dynamic loading of drivers for external
+input devices using the <tt/XInput/ extension. Currently supported
+devices are:
+<itemize>
+<item>Joystick (<tt/xf86Jstk.so/)
+<item>Wacom tablets (Wacom IV protocol only, <tt/xf86Wacom.so/)
+<item>SummaSketch tablets (<tt/xf86Summa.so/)
+<item>Elographics touchscreen (<tt/xf86Elo.so/)
+</itemize>
+
+To use a specific device, add the line
+<tscreen>
+<tt/load/ <tt/"/<em/module/<tt/"/
+</tscreen>
+in the <bf/Module/ section of <tt/XF86Config/, where <em/module/ is
+the name of the <tt/.so/ file corresponding to your device.
+You also need to set up a <bf/XInput/ section in <tt/XF86Config/.
+Refer to the <em>XF86Config(5)</em> man page for detailed
+configuration instructions.
+<p>
+You can then change the device used to drive the X pointer with the
+<em/xsetpointer(1)/ command.
+<p>
+For joystick support, you'll need to enable the joystick device
+driver in the kernel. See <em/joy(4)/ for details.
+
+<sect1>Configuring PEX and XIE extensions
+<p>
+The PEX and XIE extensions are supported as external modules.
+If you want to have access to these extensions, add the following
+lines to the <bf/Module/ section of <tt/XF86Config/:
+<tscreen><verb>
+ load "pex5.so"
+ load "xie.so"
+</verb></tscreen>
+
+<sect>Running X
+
+<p>
+8mb of memory is a recommended minimum for running X. The server,
+window manager and an xterm take about 4 Mb of memory themselves. On
+a 4Mb system that would leave nothing left over for other applications
+like gcc that expect a few meg free. X will work with 4Mb of memory,
+but in practice compilation while running X can take 5 or 10 times as
+long due to constant paging.
+
+
+<sect1>Starting xdm, the display manager
+
+<p>
+To start the display manager, log in as root on the console and type:
+``<tt/xdm -nodaemon/''.
+
+You can start xdm automatically on bootup un-commenting the following
+code in <tt>/etc/rc.local</tt>:
+
+<tscreen><verb>
+ if [ -x /usr/X11R6/bin/xdm ]; then
+ echo -n ' xdm'; /usr/X11R6/bin/xdm
+ fi
+</verb></tscreen>
+
+On the default OpenBSD 2.2 installation, you will need to create
+the virtual console device for the X server:
+<tscreen><verb>
+cd /dev
+ ./MAKEDEV ttyC5
+</verb></tscreen>
+
+<p>
+Note that the binary distributions of XFree86 for OpenBSD don't include
+support for the XDM-AUTHORIZATION-1 protocol.
+
+<sect1>Running X without the display manager
+<p>
+The easiest way for new users to start X windows is to type: ``<tt/startx
+>&amp; startx.log/''. Error messages are lost unless you redirect them
+because the server takes over the screen.
+
+To get out of X windows, type: ``<tt/exit/'' in the console xterm.
+You can customize your X by creating <tt/.xinitrc/, <tt/.xserverrc/,
+and <tt/.twmrc/ files in your home directory as described in the xinit
+and startx man pages.
+
+<sect>Kernel Support for X
+
+<p>
+To make sure X support is enabled under OpenBSD, the following
+line must be in your config file in <tt>/sys/arch/i386/conf</tt>:
+
+<tscreen>
+ options XSERVER
+</tscreen>
+
+<sect1>Console drivers
+<p>
+The server supports the two standard OpenBSD/i386
+console drivers: pccons and pcvt. They are detected at runtime and no
+configuration of the server itself is required.
+
+<p>
+The pcvt console driver is the default in OpenBSD. It offers
+several virtual consoles and international keyboard support.
+
+
+<sect1>Aperture Driver
+<p>
+By default OpenBSD includes the BSD 4.4 kernel security
+feature that disable access to the <tt>/dev/mem</tt> device when in
+multi-users mode. But XFree86 servers can take advantage (or require)
+linear access to the display memory.
+
+The P9000, Mach64 and AGX servers require linear memory access, other
+accelerated servers can take advantage of it, but do not require it.
+Some drivers in the SVGA server require linear memory access too,
+notably the Matrox driver.
+
+The preferred way to allow XFree86 to access linear memory is to use
+the aperture driver
+
+Ths step is highly dependent from your exact operating
+system version:
+<itemize>
+<item> OpenBSD 2.0
+
+Use the aperture driver from /usr/lkm:
+
+add the following lines to the end of <tt>/etc/rc.local</tt>:
+<tscreen><verb>
+ KERNDIR=/usr/lkm
+ if [ -f ${KERNDIR}/ap.o ]; then
+ modload -o ${KERNDIR}/ap -e ap -p \
+ ${KERNDIR}/apinstall ${KERNDIR}/ap.o
+ fi
+</verb></tscreen>
+
+<item> OpenBSD 2.1, 2.2
+
+Uncomment the lines loading the aperture driver from
+<tt>/etc/rc.securelevel</tt>
+
+<item> OpenBSD 2.3
+
+The aperture driver is part of the kernel. Add 'option APERTURE' to
+your kernel configuration file, build and install the new kernel and
+run <tt>./MAKEDEV std</tt> in <tt>/dev</tt>. Edit
+<tt>/etc/sysctl.conf</tt> to set the variable
+<bf>machdep.allowaperture</bf> to 1.
+
+<item> OpenBSD 2.4 and later
+
+OpenBSD now requires the aperture driver to be enabled for all X
+servers, because the aperture driver also controls access to the
+I/O ports of the video boards.
+
+</itemize>
+
+After doing that, reboot your system. XFree86 will auto-detect the
+aperture driver if available.
+
+<p>
+<bf/Warning:/ if you boot another kernel than <tt>/bsd</tt>,
+loadable kernel modules can crash your system. Always boot in
+single user mode when you want to run another kernel.
+
+<p>
+<quote>
+<bf/Caveat:/ the aperture driver only allows one access at a time
+(so that the system is in the same security state once X is
+launched). This means that if you run multiple servers on multiples
+VT, only the first one will have linear memory access. Use 'option
+INSECURE' if you need more that one X server at a time.
+</quote>
+
+
+Another (less recommended) way to enable linear memory access is to
+disable the kernel security feature by adding ``option INSECURE'' in
+your kernel configuration file and build a new kernel. In OpenBSD 2.2
+and later, you will also need to comment out the line initializing
+<tt/securelevel/ to 1 in <tt>/etc/rc.securelevel</tt>.
+
+<sect1>MIT-SHM
+<p>
+OpenBSD supports System V shared memory. If XFree86
+detects this support in your kernel, it will support the MIT-SHM
+extension.
+
+To add support for system V shared memory to your kernel add the
+lines:
+
+<tscreen><verb>
+ # System V-like IPC
+ options SYSVMSG
+ options SYSVSEM
+ options SYSVSHM
+</verb></tscreen>
+
+to your kernel config file.
+
+<sect> Rebuilding the XFree86 Distribution
+
+<p>
+The server link kit allow you to rebuild just the X server with a
+minimum amount of disk space. Just unpack it, make the appropriate
+changes to the <tt/xf86site.def/, type ``<tt>./mkmf</tt>'' and
+``<tt/make/'' to link the server. See <tt>/usr/X11R6/lib/Server/README</tt>
+for more info.
+
+See <htmlurl url="INSTALL.html" name="INSTALL"> for instructions on
+unbundling and building the source distribution.
+
+You should configure the distribution by editing
+<tt>xc/config/cf/host.def</tt> before compiling. To compile the
+sources, invoke ``<tt/make World/'' in the xc directory.
+
+<sect1>Console drivers<label id="console-drivers">
+
+<p>
+XFree86 has a configuration option to select the console
+drivers to use in <tt/xf86site.def/:
+<itemize>
+<item> if you're using pccons only put:
+<tscreen><verb>
+ #define XFree86ConsoleDefines -DPCCONS_SUPPORT
+</verb></tscreen>
+<item>if you're using pcvt only put:
+<tscreen><verb>
+ #define XFree86ConsoleDefines -DPCVT_SUPPORT
+</verb></tscreen>
+</itemize>
+If you don't define <bf/XFree86ConsoleDefines/ in <tt/xf86site.def/ the
+pccons and pcvt drivers will be supported.
+
+
+
+<sect1>Building on other architectures<label id="otherarch">
+
+<p>
+XFree86 also compiles on other OpenBSD architectures.
+
+The XFree86 servers can also been built on OpenBSD/mips. The S3 server
+has been tested on an Acer Mips system with a S3/928 board. Contact
+Per Fogelstrom (pefo@OpenBSD.org) for details.
+
+The Xsun server patches from Dennis Ferguson and Matthew Green for
+NetBSD have been integrated in
+<tt>xc/programs/Xserver/hw/sun</tt>. The Xsun server can be built on
+the sparc and the sun3.
+
+The client side of XFree86 also builds on the alpha, pmax, amiga,
+mac68k and mvme68k architectures.
+
+Problems with this port should be reported directly to the OpenBSD
+mailing lists rather than to the xfree86 mailing list.
+
+<p>
+Note that OpenBSD project has now its own source tree, based on
+the XFree86 source tree, with some local modifications. You may want
+to start with this tree to rebuild from sources. The OpenBSD X11
+source tree is available by anoncvs from all OpenBSD anoncvs
+servers. See <htmlurl url="http://www.openbsd.org/anoncvs.html"
+name="http://www.openbsd.org/anoncvs.html"> for details on anoncvs.
+
+
+<sect>Building New X Clients
+
+<p>
+The easiest way to build a new client (X application) is to use
+<tt/xmkmf/ if an <tt/Imakefile/ is included in the sources. Type
+``<tt/xmkmf -a/'' to create the Makefiles, check the configuration if
+necessary and type ``<tt/make/''. Whenever you install additional man
+pages you should update <tt/whatis.db/ by running ``<tt>makewhatis
+/usr/X11R6/man</tt>''.
+
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/OpenBSD.sgml,v 1.3 1999/08/23 06:38:50 dawes Exp $
+
+
+
+
+
+$XConsortium$
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/P9000.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/P9000.sgml
new file mode 100644
index 000000000..4430f11b1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/P9000.sgml
@@ -0,0 +1,471 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+
+<title>XFree86 P9000 Server Release Notes
+<author>Erik Nygren (<it>nygren@mit.edu</it>)
+<date>1998 December 29
+<toc>
+
+<sect>Change Log <p>
+<descrip>
+<tag/1998.10.13:/
+ <itemize>
+ <item>
+ Fixed a bug that would cause the server to crash when it tried
+ to enable or disable the screen saver while at a VT (Erik Nygren)
+ </itemize>
+<tag/1997.01.30:/
+ <itemize>
+ <item>
+ Added probing for MemBase and IOBase on Diamond Viper PCI cards
+ (Karl Anders Øygard)
+ <item>
+ Added support for DPMI screen saving (Karl Anders Øygard)
+ </itemize>
+<tag/1996.03.31:/
+ <itemize>
+ <item>
+ Added support for the XFree86-DGA extension (Erik Nygren)
+ </itemize>
+<tag/1995.05.24:/
+ <itemize>
+ <item>
+ Added p9000frect.c: Accelerated solid rectangle fills at 8/16bpp
+ (Henrik Harmsen)
+ <item>
+ Added stipple fills to p9000frect.c, and a stub for tile fills when
+ p9000ImageFill is fixed (Chris Mason)
+ <item>
+ Added p9000pntwin.c: Accelerated paint window at 8/16/32bpp
+ (Henrik Harmsen)
+ <item>
+ Added p9000gc16.c and p9000gc32.c for the higher bpp drawing functions
+ (Henrik Harmsen)
+ <item>
+ Additions to p9000im.c: p9000Image&lsqb;Op&rsqb;Stipple.
+ And p9000ImageFill.
+ Currently, there are small problems with ImageFill, and it is not
+ being used. (Chris Mason)
+ <item>
+ Added p9000PixAlu and p9000PixOpAlu. miniterm->alu translation for
+ pixel1 opaque and transparent operations. (Chris Mason)
+ <item>
+ Added p9000text.c: Non-cached poly text and image text functions.
+ Image text functions are not used because they are too slow :(
+ (Chris Mason)
+ </itemize>
+<tag/1995.05.21:/
+ <itemize>
+ <item>
+ Fixed p9000init.c to properly deal with the <tt>vram_128</tt>
+ option. This should allow the driver to work properly with all
+ Viper's with 1 MB of memory. (Erik Nygren)
+ </itemize>
+<tag/1995.01.29:/
+ <itemize>
+ <item>
+ Updated P9000.sgml to mention using Robin's scanpci rather
+ than PCIDUMP.EXE.
+ </itemize>
+<tag/1995.01.15:/
+ <itemize>
+ <item>
+ Fixed problem with line capping in accelerated line
+ drawing. (Chris Mason)
+ <item>
+ Fixed p9000QuadAlu&lsqb;GXset&rsqb; to be ~0 rather than 1.
+ (Erik Nygren)
+ </itemize>
+<tag/1995.01.14:/
+ <itemize>
+ <item>
+ <tt>Clocks</tt> line is no longer used in <tt>XF86Config</tt> file.
+ Operation should now be consistent with the operation of the
+ other servers which use programmable clocks. (Erik Nygren)
+ <item>
+ Users with 1MB cards can now explicitly specify <tt>videoRam</tt>
+ in the <tt>XF86Config</tt> file when autoprobing fails.
+ The new <tt>vram_128</tt> option may also be used to force
+ the detection of 128Kx8 SIMM's. (Erik Nygren)
+ <item>
+ Added p9000line.c and p9000seg.c for accelerated line drawing code
+ using the p9000 quad/clipping engine. Blazingly fast for 1 clipping
+ rectangle, could be made faster for multiple clipping regions by
+ using software clipping. There is still a bug which causes
+ xtest to report <tt>Cap style incorrect for thin line and
+ CapNotLast</tt> for the <tt>XDrawLines</tt> tests but not
+ for the <tt>XDrawLine</tt> or <tt>XDrawSegments</tt> tests
+ &lsqb;fixed in 1995.01.15 patch&rsqb;. (Chris Mason)
+ <item>
+ Changed p9000blt.c, and p9000win.c to wait for the quad/blit engine
+ to be free. Before a quad/blit, check SR_ISSUE_QBN, then blit, then
+ when all blits are done, do a p9000QBNotBusy. (Chris Mason)
+ <item>
+ Changed p9000init.c to clear the screen using the quad meta coord
+ drawing mode. Appears the rect mode does not update the CINDEX
+ register correctly. Changed the color to 1 (black) from 0. (Chris)
+ <item>
+ Added p9000QuadAlu. When drawing a quad, the p9000 equivalent to X's
+ source is the foreground mask. When bliting/pixel8ing/pixel1ing,
+ it is the p9000 source mask and the p9000alu lookup table should be
+ used. (Chris Mason)
+ <item>
+ Added some more registers to p9000reg.h. (Chris Mason)
+ </itemize>
+<tag/1994.09.20:/
+ <itemize>
+ <item>
+ Fixed problem which prevented 16 bpp modes from working (Erik Nygren)
+ </itemize>
+<tag/1994.09.16:/
+ <itemize>
+ <item>
+ Added screen blanking support for 16 bpp and 32 bpp modes.
+ Screen blanking now powers down the RAMDAC rather than
+ just changing the planemask. (Chris Mason, Erik Nygren)
+ <item>
+ Fixed more problems caused by switch to <tt>XF86Config</tt>
+ (Erik Nygren)
+ <item>
+ Possible fix to maxclock for Orchid P9000 (Harry Langenbacher,
+ Erik Nygren)
+ </itemize>
+<tag/1994.09.15:/
+ <itemize>
+ <item>
+ Now almost always works with <tt>XF86Config</tt> changes
+ (Erik Nygren)
+ <item>
+ Cursor code looks at VTSema before writing to RAMDAC.
+ This had been causing the x11perf server crash (Erik Nygren)
+ </itemize>
+<tag/1994.09.08:/
+ <itemize>
+ <item>
+ Fixed problem with xdm and restarting the server (Erik Nygren)
+ <item>
+ Fixed and enabled ImageRead in CopyArea (Chris Mason)
+ <item>
+ Made informational comments conform to standard :-) (Erik Nygren)
+ </itemize>
+<tag/1994.09.05:/
+ <itemize>
+ <item>
+ Fixed BIOS probe for Viper PCI (Bob Hollinger)
+ <item>
+ Fixes to Orchid P9000 support (Harry Langenbacher)
+ <item>
+ Changing of datatypes in clock code (Harry Langenbacher)
+ <item>
+ Fixed clock and misc reg restoration so now works fine with svgalib
+ (Chris Mason, Harry, Erik)
+ </itemize>
+<tag/1994.08.29:/
+ <itemize>
+ <item>
+ Increased number of memory regions in xf86_OSlib.h from 2 to 3
+ as needed by the Viper PCI (Erik Nygren)
+ <item>
+ Changed method of short pauses in p9000vga.c to outb(0x80,0) (Erik)
+ <item>
+ Rewrote routines to determine sysconfig from horizontal resolution.
+ Also added check for valid hres to probe. (Erik Nygren)
+ <item>
+ Added MoveWindow acceleration for all depths. Opaque move even
+ looks nice at 32bpp now! (Chris Mason)
+ <item>
+ Minor fixes to acceleration. Acceleration is now enabled
+ by default (Chris Mason)
+ <item>
+ Added <tt>"noaccel"</tt> option (Erik Nygren)
+ <item>
+ Added some fixes for Viper PCI (Matt Thomas)
+ </itemize>
+<tag/1994.07.21:/
+ <itemize>
+ <item>
+ Preliminary Viper PCI support - totally untested so disabled
+ (Erik Nygren)
+ <item>
+ Preliminary Orchid P9000 support - incomplete and totally
+ untested so disabled (Erik Nygren)
+ <item>
+ Preliminary accelerated support - incomplete and not fully tested
+ so disabled (Erik Nygren and Chris Mason)
+ </itemize>
+<tag/1994.07.08:/
+ <itemize>
+ <item>
+ 16 and 32 bpp TrueColor support (Erik Nygren)
+ <item>
+ Color restoration hopefully fixed (Erik Nygren)
+ <item>
+ Changes to how <tt>"Modes"</tt> line in Xconfig is processed
+ <item>
+ Removed banking support :-(
+ </itemize>
+</descrip>
+
+<sect>Supported Cards <p>
+
+<sect1>Diamond Viper VLB <p>
+ All Viper VLB's should work with this server, hopefully&hellip; :-) Due
+to Diamond's putting the same BIOS in some Viper VLB's as are used in
+Viper PCI's, the probe may detect you have a Viper PCI when you really
+have a Viper VLB. If this happens, put <tt>chipset "vipervlb"</tt>
+into your <tt>XF86Config</tt> file.
+
+<sect1>Diamond Viper PCI <p>
+
+You may need to specify the chipset <tt>"viperpci"</tt> in your
+<tt>XF86Config</tt> file.
+
+Previously you had to find out the values for <tt>MemBase</tt> and
+<tt>IOBase</tt> by yourself. These are now autodetected.
+
+<sect>Orchid P9000 and random clones <p>
+The Orchid P9000 and other cards based on the Weitek board design
+(such as the STAR 2000) should now work. Talk to
+<it>harry@brain.jpl.nasa.gov</it>
+if you have problems with this. Specify the chipset <tt>"orchid_p9000"</tt> in
+the <tt>Device</tt> section of <tt>XF86Config</tt>
+
+<sect>Viper Pro and other P9100 and P9130 cards (UNSUPPORTED!!!) <p>
+These are NOT supported yet by this server, but are supported in the
+p9x00 driver of the SVGA server.
+
+
+<sect>Acceleration <p>
+Some of the acceleration code is working, but
+there are probably still bugs. Only a very small number of
+accelerated features have been implemented. Before working on any
+acceleration, please contact <it>nygren@mit.edu</it> so we don't duplicate
+efforts. Acceleration may be turned off with the <tt>"noaccel"</tt> option.
+The following things are now accelerated:
+<itemize>
+ <item> Hardware cursor (8/16/32bpp)
+ <item> MoveWindow (8/16/32bpp)
+ <item> CopyArea (8bpp)
+</itemize>
+
+
+<sect>XFree86-DGA Extension Support <p>
+
+The XFree86-DGA extension is now supported. Note that
+XF86DGASetViewPort command is not fully implemented due to hardware
+limitations of the P9000. The SetViewPort and SetVidPage commands
+have been hacked to allow double buffering under certain conditions. <p>
+
+For cards with 1MB or modes where xres*yres*Bpp > 1024K,
+no double buffering is supported. In this case, the bank size
+returned is equal to the amount of video memory. Using
+the XF86DGASetViewPort and XF86DGASetVidPage commands have
+no results. <p>
+
+For cards with 2MB and for modes where virtualX*virtualY*Bpp < 1024K,
+the behaviors of SetViewPort and SetVidPage are modified to allow
+double buffering. The bank size returned by XF86DGAGetVideo is
+equal to xres*yres*Bpp. In this mode, there are two buffers
+which can be written to, read from, and displayed. The
+XF86DGASetVidPage command can be used to switch between
+buffers 0 and 1 for I/O. Whichever buffer is selected will
+be available through the linear aperture with no offset.
+If XF86DGASetViewPort is called with ypos < yres, it
+will cause buffer 0 to be displayed. If ypos >= yres,
+buffer 1 will be displayed. The result of this behavior
+is that programs which switch banks as necessary
+and which use two vertically adjacent banks should
+work with no P9000-specific changes.
+
+
+<sect>High Color and TrueColor <p>
+Support for 16 and 24 bit truecolor is now supported. Note that 24
+bit color is really 32 bits per pixel. Use the <tt>-bpp</tt> option when
+starting the server. Examples:
+<verb>
+ startx -- -bpp 32
+ startx -- -bpp 16
+ startx -- -bpp 16 -weight 555
+ startx -- -bpp 16 -weight 565
+</verb>
+Note that many programs do not yet work properly with these modes.
+Don't tell me. Tell the authors unless they've already fixed it.
+It's their fault&hellip :-)
+
+Example problems:
+<descrip>
+ <tag/xv 3.00/ Works fine in 32 bpp and in 16 bpp with 24 bit images.
+ Has problems with colors in 8 bit images in 8 bpp mode.
+ <tag/Mosaic 2.1/ Has problems with colormap in both 16 bpp and 32 bpp.
+ Newer versions of Mosaic such as 2.4 do work.
+ <tag/mpeg_play/ Doesn't work at all in 16 bpp mode. Works fine
+ 24 bpp mode when compiled with -DRS6000 and when
+ run with ``<tt>-dither color</tt>''
+ <tag/xpaint 2.1/ Works great in both modes but has a bug in the
+ color requester for the selection tool.
+ I think later versions may have fixed this.
+</descrip>
+
+<sect>Random Notes <p>
+Text restoration should now be fixed. Color restoration should
+also be fixed. You can now even run the server at the same time as svgalib
+programs!!!
+
+Diamond has actually been fairly open and helpful. No NDA's were
+signed by anyone who wrote code and Diamond claims that none of the
+information they provided is proprietary.
+
+One unresolved issue is the maximum clock speed. It is currently set
+to 135 MHz with a warning printed over 110 MHz. Diamond claims that
+this is the max in their docs, but examination has shown some Viper's
+to contain 110 MHz bt485's. Without 135 MHz, it is not possible for
+people to with large monitors to run at 1280x1024. Diamond claims
+that all Vipers have 135MHz bt485's or compatibles. If you have
+something slower, call their tech support and they will send you
+a RMA to get the board replaced.
+
+<sect>Operating System Notes <p>
+Any operating system that can memory map linear regions in really
+high memory should work. This should include Linux, FreeBSD, SVR4,
+and more.
+
+<sect1>NetBSD <p>
+If you have NetBSD, you will need to install the aperture driver.
+Extract the file <tt>apNetBSD.shar</tt>
+(in <tt>xc/programs/Xserver/hw/xfree86/etc/apNetBSD.shar</tt>) and read
+the <tt>README</tt> contained therein.
+
+<sect>XF86Config <p>
+The <tt>modes</tt> line in the <tt>XF86Config</tt> file is now handled
+differently.
+The virtual line is now ignored entirely. Each mode on the mode
+line is looked at and the first usable mode is selected (ie the first
+one which works with available memory, etc). Any other modes which
+are valid and have the same dimensions are also used. And other modes
+are ignored.
+
+The current supported keywords in the <tt>Device</tt> section
+of the <tt>XF86Config</tt> file are:
+<descrip>
+ <tag/VideoRAM/ 1024 or 2048 (use 2048 for ``3MB'' Orchid P9000's)
+ <tag/ChipSet/ <tt>"vipervlb"</tt> or <tt>"viperpci"</tt> or
+ <tt>"orchid_p9000"</tt>
+ <tag/MemBase/
+ <descrip>
+ <tag/Viper VLB:/ 0xA0000000 or 0x20000000 or 0x80000000
+<!-- Converted square brackets to parentheses -->
+ (0x80000000 is default if none spec'd)
+ <tag/Orchid P9000:/ 0xC0000000 or 0xD0000000 or
+ 0xE0000000
+ (this MUST be set to correspond to the jumpers)
+ <tag/Viper PCI:/ any value corresponding to the output
+ of <tt>PCIDUMP.EXE</tt>
+ </descrip>
+ <tag/IOBase/
+ <descrip>
+ <tag/Viper PCI:/ any value corresponding to the output
+ of <tt>PCIDUMP.EXE</tt>
+ <tag/Others:/ unused
+ </descrip>
+ <tag/Clocks/ any values between 25 and 135 corresponding to the
+ clocks for the mode entries being used.
+ This line may now be omitted and clocks will
+ be matched automatically.
+ <tag/Option/ <descrip>
+ <tag/"sw_cursor"/
+ use software cursor
+ <tag/"vram_128"/
+ use if you have 1024K VRAM in 128Kx8 SIMMS
+ <tag/"sync_on_green"/
+ generate sync pulses on the green signal. Most
+ (all?) P9000 based boards don't support this.
+ <tag/"noaccel"/
+ do not do hardware acceleration if
+ it's causing problems for you
+ </descrip>
+ <tag/Modes/ almost any valid mode (there are constraints on
+ the horiz res so not all values are possible)
+
+</descrip>
+The current supported keywords in the Display section
+of the <tt>XF86Config</tt> file are:
+<descrip>
+ <tag/Depth/
+ <descrip>
+ <tag/8:/ use 8 bits per pixel for 256 colors (default)
+ <tag/15 or 16:/ use 16 bits per pixel for up to 65K colors
+ <tag/24 or 32:/ use 32 bits per pixel (sparse 24 bpp)
+ for up to 16 million colors
+ </descrip>
+ <tag/Weight/ 555 or 565 if Depth is 15 or 16. Otherwise this
+ is ignored. These are the Red, Green,
+ and Blue bits per pixel (default=565)
+</descrip>
+Here's a portion of a sample <tt>XF86Config</tt> file for the Viper VLB:
+<verb>
+Section "Device"
+ Identifier "ViperVLB"
+ VendorName "Diamond"
+ BoardName "Viper VLB"
+ Videoram 2048 # This is mandatory
+ Membase 0x80000000 # This is mandatory on non-ViperVLB's
+ IOBase 0xe000 # Use this ONLY on ViperPCI's
+EndSection
+
+Section "Screen"
+ Driver "accel"
+ Device "ViperVLB"
+ Monitor "NEC4FGe"
+ Subsection "Display"
+ Depth 8 # This line is optional
+ Modes "1024x768" "800x600"
+ EndSubsection
+EndSection
+</verb>
+
+<sect>Known Bugs <p>
+There are currently problems with the server when used in conjunction
+with xdm, olvwm, and VT switching under Linux.
+
+If the cursor changes while you're in a VT, the cursor won't look
+right when you return from the VT until it is moved between windows
+(and changes color and shape).
+
+Memory probing does not work. You will need to explicitly specify the
+amount of memory you have. If you have a 1 MB card, try put
+<tt>VideoRAM 1024</tt> into the <tt>Device</tt> section of your
+<tt>XF86Config</tt> file. If this doesn't work, try adding
+<tt>Option "vram_128"</tt> to the <tt>Device</tt> section.
+
+<sect>Credits <p>
+Major contributors to P9000 code:
+<itemize>
+<item>Erik Nygren (<it>nygren@mit.edu</it>)
+<item>Harry Langenbacher (<it>harry@brain.jpl.nasa.gov</it>)
+<item>Chris Mason (<it>clmtch@osfmail.isc.rit.edu</it>)
+<item>Henrik Harmsen (<it>harmsen@eritel.se</it>)
+</itemize>
+Thanks to Matt Thomas (<it>thomas@lkg.dec.com</it>) and Bob Hollinger
+(<it>bob@interaccess.com</it>) for helping to get the Viper PCI server working.
+
+Special thanks to David Moews (<it>dmoews@xraysgi.ims.uconn.edu</it>)
+whose banking patch could unfortunately not be included.
+
+Thanks to Andy, David, Dave, Jon, Michael, Bob, all the XFree86 core team
+people, and everyone else!
+
+During the course of the next few months, people will be working on
+acceleration, etc. Please send any patches to me (<it>nygren@mit.edu</it>).
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/P9000.sgml,v 3.22 1999/08/23 06:38:51 dawes Exp $
+
+
+
+
+
+$XConsortium: P9000.sgml /main/9 1996/05/12 20:58:05 kaleb $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/QStart.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/QStart.sgml
new file mode 100644
index 000000000..85e6e2f39
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/QStart.sgml
@@ -0,0 +1,677 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+
+<title>Quick-Start Guide to XFree86 Setup
+
+<author>Joe Moss
+<date>27 February 1998
+
+<abstract>
+ Current releases of XFree86 include several tools that can help
+to automate the process of server configuration. Much of the existing
+documentation, however, describes how to do the job manually, including
+many technical details.
+
+ For those users with esoteric hardware or with the desire to
+get their hands dirty under the hood, this is great, but many users are
+using common hardware and just want to get X up and running quickly.
+This guide is for them.
+
+</abstract>
+
+<toc>
+
+<sect> Before You Start
+<p>
+ There are a few bits of information that you will need to have
+ before you can setup the server:
+ <descrip>
+ <tag> The model name of your video card </tag>
+ Make sure you know the exact model name of the card. It
+ may help to also know the graphics chipset, RAMDAC, and
+ clock chip used on your card.
+ <tag> The amount of memory on your video card </tag>
+ Find out how many megabytes of RAM are on your video card.
+ <tag> Whether or not your card is VGA compatible </tag>
+ Most cards these days are VGA compatible, but for example,
+ if you have and older monochrome card, it might not be.
+ <tag> Your monitor's specifications </tag>
+ Specifically, you need to know the horizontal sync rate(s),
+ and vertical refresh rate(s). These are <bf>important</bf>!
+ Consult your monitor's manual.
+ <tag> The protocol used by your mouse </tag>
+ It will help speed up the process, if you know which protocol
+ is used by your mouse to communicate. Some mice are capable
+ of using two different protocols, although the method of
+ switching between them varies. In some cases, with new
+ Plug-n-Play mice, the protocol can be determined
+ automatically.
+ </descrip>
+
+<sect> What to Do - An Overview
+<p>
+ There are three tools that can be used to set up XFree86:
+ <itemize>
+ <item>XF86Setup
+ <item>xf86config
+ <item>xvidtune
+ </itemize>
+<p>
+ XF86Setup primarily uses a graphical user interface and
+ is the preferred tool for initial setup, but there
+ are a few cases where it can't be used. If you are using a
+ card that is not VGA compatible, have a fixed-frequency
+ monitor, or are running OS/2, you'll not be able to use
+ XF86Setup, read about xf86config instead.
+ If you have limited RAM or a slow system, you might be better
+ off using xf86config as well.
+<p>
+ The xf86config program is text based only, but works for almost
+ any hardware combination. If you have a fixed frequency
+ monitor that won't work with standard text modes, you
+ will have to read the necessary documentation and
+ do the configuration manually.
+<p>
+ To get things looking just right, you may need to use
+ <tt>xvidtune</tt>, a program that allows you to make adjustments
+ to the displayed image (e.g. make it wider, move it a little
+ to the left, etc.). XF86Setup will allow you to run xvidtune
+ at the appropriate time; if you use xf86config, you can use
+ xvidtune afterwards.
+<p>
+ All of these are explained in detail in the following
+ sections. If you're the type that doesn't like to read
+ the documentation, but would rather just try and figure
+ your way through things, you can just type <tt/XF86Setup/
+ now.
+ If you have problems, the documentation will still be here.
+<p>
+ Although it is possible to use XF86Setup from within X to
+ make changes to your existing configuration, such use is
+ not specifically documented here. These instructions are
+ primarily for those initially setting up XFree86 on their
+ system.
+
+<sect> Using <tt>XF86Setup</tt>
+<p>
+ XF86Setup will first check around to make sure certain files
+ are installed and that you are running as root. If a problem
+ is found, it will display a message and exit. Correct the
+ problem (e.g. install the missing files) and run it again.
+
+ XF86Setup is internationalized. If you are Japanese and set
+ the LANG environment variable to ja, japan, japanese, etc.,
+ XF86Setup's screen can be Japanized. But it is necessary that
+ XF86Setup is built with Japanized Tcl/Tk. Other language can
+ be added, if you prepare its own directory under the directory
+ XF86Setup/texts. Please see under the directory
+ XF86Setup/texts/generic.
+
+<sect1> Initial questions
+<p>
+ If you have an existing XF86Config file, you will be asked if
+ you would like to use it to set the default values of various
+ configuration settings. If you've already got an (at least
+ somewhat) working configuration you will want to do this.
+
+ If you are running on an OS which has a mouse driver in the
+ kernel (e.g. SCO or SVR4), you may be asked if you'd like to
+ use it.
+
+ Once the questions (if any) are completed, you will see a message
+ indicating that the program is ready to switch into graphics mode.
+ Just press Enter. If you don't get a graphics screen saying
+ <it/Welcome to XFree86 Setup/ within a minute, something has
+ probably hung, you can try pressing Ctrl-Alt-Backspace to
+ switch back to text mode and you'll probably have to use
+ xf86config instead of XF86Setup.
+
+<sect1> Configuration areas
+<p>
+ Once the VGA16 server is started, and once the program has
+ finished loading, you will see a screen with six
+ buttons along the top and three along the bottom.
+ The buttons along the top correspond to the general categories
+ of configuration settings. They can be done in any order.
+ Each of these areas is explained in detail below.
+ The bottom row consists of the <bf/Abort/,
+ <bf/Done/, and <bf/Help/ buttons.
+<p>
+ <bf/Abort/ does as it name implies. It exits the program
+ without saving any changes that have been made. The one
+ possible exception is the link to the mouse device. Any
+ change to that is made as soon as <bf/Apply/ is selected.
+<p>
+ <bf/Done/ should be selected when you've finished
+ configuration in each of the various categories.
+<p>
+ The <bf/Help/ can be pressed at any time to get on-line
+ help regarding the current configuration screen.
+<p>
+ You should start with configuring your mouse as it will make
+ things a lot easier to perform the configuration of other
+ categories.
+
+<sect2> Mouse
+<p>
+ The mouse configuration screen is used to get the mouse working
+ properly. There are key bindings for everything so that you
+ can easily configure the mouse, if it's not already working.
+<p>
+ The screen includes a representation of a white mouse with
+ three buttons. As you move your mouse it should show the
+ pointer coordinates on the mouse and the buttons should turn
+ black as you press the corresponding button on your mouse.
+ If that is not happening, then your mouse is not correctly
+ configured.
+<p>
+ Along the top are some rows of buttons corresponding to
+ the various possible protocols. There will also be
+ several buttons and a couple of sliders
+ for other settings, a visual representation of the mouse,
+ and a button to apply any changes.
+ There may also be an entry box in which the
+ device can be set along with a list of possible devices.
+<p>
+ First try moving your mouse around and see if the pointer moves
+ correctly. If so, try testing that the buttons are working
+ properly. If those are working as desired, go ahead and go on
+ to another configuration area.
+<p>
+ If the mouse pointer doesn't move at all, you need to fix
+ either the mouse device or the protocol (or both).
+ You can press 'n' followed by a Tab, to move to the list
+ of mouse devices and select a different one.
+ Pressing 'p' will pick the next available protocol on the list
+ (protocols that are not available on your OS will be
+ greyed-out). If you have a PnP mouse, it may be easiest to
+ just select "Auto" as the protocol.
+ After changing these, press 'a' to apply the changes and try
+ again. Repeat the process until you are getting some response
+ from your mouse.
+<p>
+ If the mouse pointer or button indicators do something when you
+ move the mouse, but the pointer is not moving properly, you
+ probably have the wrong protocol selected. Try with a different
+ one.
+<p>
+ Most mice these days use the <bf/Microsoft/ protocol, the second
+ most common is <bf/MouseSystems/. Some mice do both.
+ These <it/dual-protocol/ mice have various methods of switching
+ between the two protocols.
+ Some have a switch on the mouse itself.
+ Some are switched by sending a certain signal to the mouse
+ when opening a connection to the mouse.
+ These signals can be controlled by using different
+ combinations of the 'ClearDTR' and 'ClearRTS' settings.
+ Other mice require a button to be depressed when the mouse
+ is opened (when the mouse driver first tries to talk to it).
+ If your mouse uses this method, hold down the appropriate
+ button while selecting apply (pressing 'a').
+<p>
+ Once the mouse pointer is moving correctly, test that all
+ three buttons are working properly. If your mouse only has
+ two buttons, select 'Emulate3Buttons' and you should be able
+ to press both buttons simultaneously to emulate the missing
+ middle button. If not all of the buttons are working, try
+ changing the 'ChordMiddle' setting or you may be using a
+ protocol that is similar to that of your mouse,
+ but not quite right.
+
+<sect2> Keyboard
+<p>
+ You need to specify the model and layout of your keyboard (and
+ press apply) if they are not already correct.
+ The graphical representation of the keyboard will be
+ updated when you choose a different model.
+<p>
+ For non-U.S. keyboards you may wish to choose a variant from
+ the list (at this time there is only one available variant:
+ <tt/nodeadkeys/>).
+<p>
+ You can also pick from the options to the right, if you wish.
+
+<sect2> Card
+<p>
+ Pick your card from the list.
+<p>
+ If there are README files that may pertain to your card
+ the 'Read README file' button will then be usable (i.e. not
+ greyed out).
+ Please read them.
+<p>
+ If your card is not in the list, or if there are any
+ special settings listed in the README file as required
+ by your card, you can press the 'Detailed Setup'
+ button to make sure that the required settings are selected.
+ Otherwise, you're finished with configuring your card.
+<p>
+ To use 'Detailed Setup':
+ First select the appropriate server for your card.
+ Then read the README file corresponding to the selected
+ server by pressing the 'Read README file' button
+ (it won't do anything, if there is no README).
+<p>
+ Next, pick the chipset, and Ramdac of your card, if
+ directed by the README file.
+ In most cases, you don't need to select these,
+ as the server will detect (probe) them automatically.
+<p>
+ The clockchip should generally be picked, if your card
+ has one, as these are often impossible to probe
+ (the exception is when the clockchip is built
+ into one of the other chips).
+<p>
+ Choose whatever options are appropriate (again,
+ according to the README).
+<p>
+ You can also set the maximum speed of your Ramdac.
+ Some Ramdacs are available with various speed ratings.
+ The max speed cannot be detected by the server
+ so it will use the speed rating of the slowest version
+ of the specified Ramdac, if you don't specify one.
+<p>
+ Additionally, you can also specify the amount of RAM on your
+ card, though the server will usually be able to detect this.
+
+
+<sect2> Modeselect
+<p>
+ Use this one to pick which depth you prefer to use (this
+ determines how many colors can be displayed at a time)
+ and to select all of the modes you are interested in
+ possibly using.
+<p>
+ Your hardware may not be able to support all
+ of depth and mode combinations that can be selected.
+ Any unsupported combinations will automatically be
+ rejected by the server when it tries to startup.
+ Note also that if you select multiple modes, you will
+ get a virtual screen as large as the largest of the
+ usable modes.
+
+<sect2> Monitor
+<p>
+ Enter the horizontal and vertical frequency ranges that your
+ monitor supports in the corresponding entry boxes near the
+ top of the screen.
+ You can enter specific frequencies or ranges of frequencies
+ (separated by hyphens).
+ If the monitor supports several different frequencies or
+ ranges, list them all, separated by commas.
+<p>
+ If you can not find this information in you monitor's manual,
+ pick one of the choices from the list of common monitor
+ capabilities. The program will use conservative values
+ for each of these, so you'll get better performance if you
+ type in the correct values from your monitor manual.
+
+<sect2> Other
+<p>
+ You can probably just skip this one.
+
+<sect2> Completing the configuration
+<p>
+ Once you've finished with the above, press the 'Done' button
+ and then the 'Okay' button which will appear. You will then
+ be switched back to text mode.
+
+<sect1> Back to text mode
+<p>
+ The program will now attempt to start the appropriate server
+ for your card, with all of the
+ configuration settings you selected.
+ If for some reason it is unable to start the server, you have
+ likely selected an improper setting and will be asked if you
+ would like to return to the graphical configuration screen
+ and try again.
+
+<sect1> The second server
+<p>
+ This is unlikely to happen, but
+ if when the server starts, the display is unreadable, try
+ pressing Ctrl-Alt-+ (using the plus on the numeric keypad)
+ to switch to a different video mode.
+<p>
+ The display will show an entry box and three buttons.
+<p>
+ The first button allows you to run xvidtune to adjust your
+ video modes. One important point to keep in mind when using
+ xvidtune is that switching video modes with Ctrl-Alt-+ is
+ disabled while xvidtune is running.
+ You must use the 'Next' and 'Prev' buttons to switch modes.
+ Because of this, you should be careful not to move the mouse
+ when pressing either of these. If by some chance the mode
+ you switch to doesn't produce a readable display on your
+ monitor, you can then just press the mouse button again to
+ move to the next (hopefully readable) mode.
+<p>
+ The second button causes the settings you've made to be
+ written to the filename given in the entry box.
+ After saving the settings a message will appear indicating
+ that it has finished. Just press the 'Okay' button and
+ you're done.
+<p>
+ And the third button causes the program to exit without
+ saving any of the configuration settings.
+
+<sect1> Ending text
+<p>
+ You are returned to text mode and the program will print a
+ `Configuration complete.' message. You should now have a
+ usable configuration file and can start the X server by
+ whichever method you wish (usually either the 'startx'
+ command or via 'xdm').
+
+<sect> Running <tt>xf86config</tt>
+<p>
+ From a text screen, run the <tt/xf86config/ program. This
+ program should be run as <it/root/ (although not absolutely
+ necessary, it will allow xf86config to do more of the work
+ for you). You can press your interrupt character (usually
+ Control-C or perhaps Delete), at any time to stop the program,
+ if you need to. You can just start it over again.
+
+ The <tt/xf86config/ program provides instructions on screen
+ as to what you need to do. Following are some notes that
+ document the various stages in the process. They should help
+ you get through the process quickly and provide some
+ documentation for those people who like to know what they're
+ getting themselves into, before running a program.
+
+<sect1> The intro screen
+<p>
+ First, <tt/xf86config/ begins by telling you a few things like
+ the fact that it can help you setup an XF86Config file or that
+ you can do the job yourself with an editor. Just read what
+ it says and press <sf/Enter/ when done.
+
+<sect1> Getting your <tt>PATH</tt> right
+<p>
+ The program will next check that you have the directory
+ <tt>/usr/X11R6</tt> (the standard installation directory)
+ on your system and tell you that it needs to be in your
+ <tt/PATH/ environment variable.
+
+ It will also check if you have the
+ <tt>/usr/X386</tt> directory as used by older (pre 3.0)
+ versions of XFree86. If by chance you do, it will warn you
+ that <tt>/usr/X11R6</tt> must be before <tt>/usr/X386</tt>
+ in your <tt/PATH/.
+
+ If everything is okay, just press Enter and go on, otherwise
+ press Control-C to exit and make any necessary changes and
+ restart <tt/xf86config/.
+
+<sect1> Mouse setup
+<p>
+ Pick the mouse type from the menu and enter the name of the
+ device to which mouse is connected, as directed.
+
+ If you are using an OS (e.g. SVR4, SCO) that has a built in
+ mouse driver that the Xserver could use, you'll need to edit
+ the XF86Config file to setup your mouse, so just pick any
+ mouse from the list and press enter when asked for the device.
+
+ If you don't know which protocol your mouse uses, you'll just
+ have to guess (the xf86config program will give you some hints
+ as to which might be most likely) and then see the
+ troubleshooting section if it doesn't work when you run the
+ server.
+
+ The xf86config program has not been updated to allow you to
+ select the latest mouse protocols, so you may have to edit
+ the config file by hand after xf86config has finished.
+
+<sect1> Keyboard setup
+<p>
+ Simply answer yes to the question regarding keyboard setup.
+
+ If there is some reason you need to use the right-alt and
+ control keys for something else, you can enter no.
+
+<sect1> Monitor setup
+<p>
+ Setting up a monitor consists of entering the specifications
+ of your monitor and a description of the model and manufacturer.
+
+ You are first asked for the horizontal sync rate. It is
+ <bf/VERY/ important to enter the correct value(s) from the
+ manual. If one of the ranges given matches the rate of your
+ monitor, then pick it, otherwise pick <tt/custom/ and enter
+ the values from your manual.
+
+ Next is the vertical refresh rate. Again, it is <bf/VERY/
+ important that this parameter be specified correctly.
+ Enter it in a manner similar to the horizontal sync rate.
+
+ <it>If either rate is mis-specified, it can result in damage
+ to your monitor.</it>
+
+ Finally, you are asked for an "identifier", your monitor
+ manufacturer, and model. You can just press enter to
+ get through these quickly.
+
+<sect1> Selecting your card
+<p>
+ You are next asked if you would like to view the database of
+ cards. Picking your card from the list will cause the answers
+ to the questions in the next two sections to be filled in for
+ you and so can save a little time.
+
+ If your card does not appear in the list, just press <tt/q/
+ and enter to skip on to the next step - where you'll have to
+ answer the questions yourself.
+
+<sect1> Server selection
+<p>
+ If you selected your card in the previous step, then server
+ selection is easy - just use the recommendation from the
+ database.
+
+ If you have a card which uses one of the chipsets for which a
+ specific server exists (Mach8, Mach32, Mach64, AGX/XGA,
+ 8514/A, S3, I128, P9000) you'll want to pick the
+ <tt/accel/ option.
+
+ Otherwise you'll probably want to use the SVGA server.
+
+ Next, answer yes when the program asks if you want it to
+ set the symbolic link for you. If you picked the <tt/accel/
+ option, you'll also need to indicate which particular
+ accelerated server to link to.
+
+<sect1> Screen/Video configuration
+<p>
+ Pick the appropriate option from the list to indicate the
+ amount of memory on your video card.
+
+ Then you are asked to provide and identifier, the manufacturer,
+ and the model of your card. You can just press enter to skip
+ through these, if you wish.
+
+ Next, the program will ask for the type of RAMDAC and Clockchip
+ on your card. If your card was in the database, you should
+ just to tell it to use the values from the database.
+
+ If you don't have one of the listed RAMDACs or Clockchips
+ on your card, just press enter when asked what type you have.
+ If you do not have a programmable clock chip, the program will
+ next attempt to probe to find out what clock rates are
+ supported by your clock chip.
+
+<sect1> Mode Selection
+<p>
+ Now you get to tell the program which video modes you would
+ like to be able to run.
+
+ The program will show you the common modes that should work
+ with your card (some might not work with your monitor, but
+ if you've correctly specified the monitor's sync rates, the
+ X server will just ignore them when it runs).
+
+ You could just accept the settings as they are given, but
+ you'll probably wish to reverse the order. For example, if
+ you have a card with 1 Meg RAM, it will list the modes
+ <tscreen><verb>
+ "640x480" "800x600" "1024x768" for 8bpp
+ </verb></tscreen>
+
+ Select <tt/1/ to change the settings for 8bpp and the type
+ <tt/432/ to select the reverse order.
+
+ When you've select the modes, in the order you wish, select
+ option <tt/4/ to continue.
+
+<sect1> Creating the <tt>XF86Config</tt> file
+<p>
+ The program will now ask if you would like to write the
+ configuration settings you've selected to the file
+ <tt/XF86Config/. Answer yes.
+
+<sect1> Some final notes
+<p>
+ Lastly, the program tells you that it's finished its part
+ of this process and counsels you to check the file before
+ using it. The next section covers the changes that are most
+ likely to be needed.
+
+<sect> Fixing the XF86Config file
+<p>
+ Use an editor to look at the <tt/XF86Config/ file. Here are
+ some things that may need to be changed:
+ <itemize>
+ <item>If you are running an operating system which has
+ built-in mouse support, you'll want to change the
+ <tt/Pointer/ section. Specifically, you should set
+ the <tt/Protocol/ to <tt/OSMouse/ (SCO) or <tt/Xqueue/
+ (SVR4, some SVR3) and you should remove the <tt/Device/
+ line.
+ <item>If you are running a system with the Xqueue event driver
+ and would like to use it, change the <tt/Protocol/
+ setting in the <tt/Keyboard/ section to <tt/Xqueue/.
+<!-- What else should be added here? -->
+ </itemize>
+
+ Once you are satisfied that the configuration is correct, copy
+ the XF86Config file to <tt>/usr/X11R6/lib/X11</tt> and run
+ the 'startx' command.
+
+ You should now have a running X server. If it's running but
+ the display doesn't look as good as you think it should (i.e.
+ it doesn't fill the whole screen, it's off-center, it's wrapping
+ around on one side, etc.) see the section on <tt/xvidtune/.
+ If there is some other problem, see the troubleshooting section.
+
+<sect> Running <tt>xvidtune</tt>
+<p>
+ If you need to make adjustments to the video display,
+ <tt/xvidtune/ is the tool to use.
+
+ Simply enter the command <tt/xvidtune/ from a shell prompt
+ within an xterm. Read the warning and click on <tt/OK/.
+ Next click on the <tt/Auto/ button.
+
+ Now click on whatever combination of <tt>Up/Down/Left/Right</tt>
+ <tt>Shorter/Taller/Wider/Narrower</tt> is need to adjust
+ the display to your liking.
+
+ If you are using a recent S3-based card there will be some
+ extra buttons and entries at the bottom (InvertVCLK, EarlySC,
+ and Blank Delays). These can help solve problems of the
+ display wrapping around a few pixels.
+
+ Once the display has been adjusted properly, press the <tt/show/
+ button to printout the correct <tt/ModeLine/ to put in the
+ <tt/XF86Config/ to make the server always use the current
+ display settings. To aid in copying this information to your
+ XF86Config file, the modeline is also made the current
+ selection allowing you to just paste it into your editor.
+
+ If you would like to adjust your other modes, you can click
+ on the <tt/Next/ and <tt/Prev/ buttons to switch modes.
+
+ When you are through using <tt/xvidtune/ simply press on the
+ <tt/Quit/ button.
+
+<sect> Troubleshooting
+<p>
+ Since you're reading this, something must not have gone
+ the way you had hoped (or else you just really enjoy reading).
+
+ Below are listed some common problems that may occur
+ during configuration and some hints for solving them.
+ However, there are just too many different combinations
+ of hardware and software configurations, and, well, just
+ too many things that can go wrong, for this document
+ and the tools it documents, to cover every case.
+
+ If after trying the steps in the previous sections and
+ checking the hints in this section, you still are unable
+ to get your system working, you'll have to read the full
+ documentation. Read the README file for your card and
+ OS (if they exist), the XFree86 Configuration Guide
+ (README.Config), and the XF86Config man page.
+
+ You should also look at
+ <url name="the XFree86 FAQ" url="http://www.XFree86.org/FAQ">
+ for more up-to-date information,
+ especially if you are trying to configure a fairly new card.
+
+ If all else fails, you can try posting a message to
+ comp.windows.x.i386unix or comp.os.linux.x or send email
+ to XFree86@XFree86.org.
+
+<sect1> The mouse doesn't move correctly, it stays in one area of the screen
+<p>
+ You've selected the wrong protocol for your mouse. Try a
+ different one.
+
+<sect1> The server doesn't start, it says the mouse is busy.
+<p>
+ Well, it's probably right. This most often happens on
+ Linux systems that have <tt/gpm/ running. Kill the <tt/gpm/
+ process and try <tt/startx/ again.
+
+<sect1> The middle button doesn't work.
+<p>
+ There's no easy answer to this one. It's a lot of trial
+ and error. You need to make sure you're running the right
+ protocol for your mouse.
+
+ Many three button mice are "dual protocol" which means that
+ they have both a 2-button and 3-button mode. The way to get
+ the mouse to switch into 3-button mode (which usually then
+ uses MouseSystems protocol) varies between different models.
+
+ You may need to slide a switch on the mouse or hold down the
+ middle button when starting the server. Other methods of
+ switching modes can be done by the server, you just have to
+ find the right combination of settings for your mouse. See
+ the Pointer section of the XF86Config man page for a complete
+ list of settings.
+
+<sect1> The display is shifted to the left/right/top/bottom
+<p>
+ See the section on xvidtune.
+
+<sect1> I don't appear to have xf86config or xvidtune on my system
+<p>
+ Hmmm. A couple of possibilities:
+ <enum>
+ <item>Your <tt/PATH/ is not set correctly. Make sure it includes
+ the bin directory for the XFree86 binaries (usually,
+ <tt>/usr/X11R6/bin</tt>
+ <item>You don't have a complete installation of XFree86.
+ Go back to wherever you got XFree86 and get the missing
+ pieces.
+ </enum>
+
+<!-- Lots of things still need to be added -->
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/QStart.sgml,v 3.7 1999/08/23 06:38:51 dawes Exp $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/README.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/README.sgml
new file mode 100644
index 000000000..6127166fc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/README.sgml
@@ -0,0 +1,134 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN" [
+<!ENTITY % defs SYSTEM "defs.ent"> %defs;
+<!ENTITY % onediff 'IGNORE'> <!-- patch is a single diff file -->
+<!ENTITY % twodiffs 'INCLUDE'> <!-- patch is split into two diff files -->
+]>
+
+
+<article>
+
+<title>README for XFree86&tm; &relvers;
+<author>The XFree86 Project, Inc
+<date>31 August 1999
+
+<ident>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/README.sgml,v 3.98 1999/08/31 09:09:56 dawes Exp $
+</ident>
+
+<abstract>
+
+XFree86 is a port of X11R6.4 that supports several UNIX(R) and UNIX-like
+operating systems on Intel and other platforms.
+
+</abstract>
+
+<toc>
+
+<sect>What is XFree86 &relvers;?
+<p>
+
+XFree86 &relvers; is a ``work in progress'' snapshot of the XFree86 4.0
+development code. It is <![ %latersnap; [one of]]>
+<![ %firstsnap; [the first]]>
+in a series of snapshot releases leading up the the 4.0 release. The
+plan is to release a new snapshot every four to six weeks. The target
+audience for this release is developers and others who are comfortable
+on the bleeding edge. This release is not targeted at beginners.
+Also, most end users will find life easier using our latest 3.3.x release.
+While we welcome bug reports and feedback about this release, we don't
+have the resources to provide user-level support for it. If you're not
+comfortable dealing with those sorts of things yourself, then the snapshot
+releases are probably not for you.
+
+This code is very much work in progress. Many of the interfaces may
+change without notice between now and the 4.0 release. The
+<htmlurl name="driver design" url="DESIGN.html"> has changed significantly
+compared with the 3.3.x versions, and only a small number of drivers have
+been converted so far. That means that this release does not support a
+wide range of video hardware. Some of the drivers and new features are
+well developed and reasonably stable, while others are not.
+
+Information on this release's features and their status can be found in
+the <htmlurl name="Release Notes" url="RELNOTES.html">.
+
+<sect>Redistribution of the Snapshots
+<p>
+
+While the XFree86 <htmlurl name="License" url="LICENSE.html"> doesn't
+prohibit vendors and others redistributing binaries of this release, we
+don't recommend it. We ask that if you do distribute such binaries,
+you make it clear that people using then should contact you for support
+and not XFree86.
+
+<sect>Developers
+<p>
+
+If you would like to work on the development on XFree86 4.0, then it is
+recommended that you <url name="join the XFree86 development team"
+url="http://www.xfree86.org:/developer.html">. That way you will have access
+to the latest source and to other developers.
+
+<sect>How to get XFree86 &relvers;
+<p>
+
+XFree86 &relvers; can be found at the <url name="XFree86 ftp server"
+url="ftp://ftp.xfree86.org/pub/XFree86/snapshots/&relvers;/">, and at
+mirrors of this server. This snapshot is available primarily in source
+form. Binaries for some platforms may be made available at a later time.
+
+The source for version &relvers; is split into three tarballs:
+<tt>X&srcvers;src-1.tgz</tt>, <tt>X&srcvers;src-2.tgz</tt>,
+<tt>X&srcvers;src-3.tgz</tt>. The first contains everything except the
+fonts and general X11 documentation. It is sufficient for building
+XFree86 is you already have a set of fonts. The second contains the
+fonts and the source for the general X11 documentation. The third
+contains the general X11 documentation in hardcopy format.
+
+<![ %onediff; [
+A source patch relative to version &prevrelvers; is also available.
+The patch file is <tt>&prevrelvers;-&relvers;.diff.gz</tt>. This patch should
+be applied to a clean &prevrelvers; source tree, working from the directory
+containing the <tt>xc/</tt> directory. The patch should be applied by
+running:
+
+<tscreen><verb>
+gunzip &lt; &prevrelvers;-&relvers;.diff.gz | patch -p0 -E
+</verb></tscreen>
+]]>
+
+<![ %twodiffs; [
+A source patch relative to version &prevrelvers; is also available.
+Because of its size, it is split into two parts.
+The patch files are <tt>&prevrelvers;-&relvers;.diff1.gz</tt> and
+<tt>&prevrelvers;-&relvers;.diff2.gz</tt>. These patches should
+be applied to a clean &prevrelvers; source tree, working from the directory
+containing the <tt>xc/</tt> directory. The patches should be applied by
+running:
+
+<tscreen><verb>
+gunzip &lt; &prevrelvers;-&relvers;.diff1.gz | patch -p0 -E
+gunzip &lt; &prevrelvers;-&relvers;.diff2.gz | patch -p0 -E
+rm -fr xc/fonts/scaled/Type1/latin2
+</verb></tscreen>
+]]>
+
+The contrib part of the distribution can be found in the following tarball:
+<tt>X&srcvers;contrib.tgz</tt>.
+
+To format the XFree86 documentation, the latest version of our doctools
+package. That is available as <tt>doctools-1.1.tgz</tt>.
+
+<sect>Reporting Bugs
+<p>
+
+Bugs should be reported to <email>XFree86@XFree86.org</email>. Before
+reporting bugs, please check the X server log file, which can be found
+at <tt>/var/log/XFree86.0.log</tt> on most platforms. If you can't resolve
+the problem yourself, send the entire log file with your bug report. Please
+don't edit out what you think might not be important. The information
+contained in the log file is there to make it easier for the developers
+to determine what is going wrong when there are problems.
+
+
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/RELNOTES.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/RELNOTES.sgml
new file mode 100644
index 000000000..0c40d9fcf
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/RELNOTES.sgml
@@ -0,0 +1,1037 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN" [
+<!ENTITY % defs SYSTEM "defs.ent"> %defs;
+]>
+
+<article>
+
+<title>Release Notes for XFree86&trade; &relvers;
+<author>The XFree86 Project, Inc
+<date>31 August 1999
+
+<ident>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/RELNOTES.sgml,v 1.18 1999/08/31 08:39:09 dawes Exp $
+</ident>
+
+<abstract>
+
+This document contains some information about the features present
+in XFree86 &relvers; and their status.
+
+</abstract>
+
+<toc>
+
+<sect>Summary of new features in &relvers; compared with &prevrelvers;.
+<p>
+This section contains a brief summary of what has changed since the
+previous snapshot. Unfortunately, only a small number of changes are
+listed here. For detailed information, refer to the <tt>CHANGELOG</tt>
+file in the <tt>xc/programs/Xserver/hw/xfree86</tt> directory in the
+source tree. The sections that follow this one have details of features
+that are new to the pre-4.0 snapshot series.
+
+<itemize>
+ <item>The "apm" driver has been updated.
+ See the <ref id="apm" name="APM section"> below.
+ <item>A driver for NVIDIA chipsets is now included. The driver is called
+ "nv". Some very basic information can be found in the nv(4) man
+ page.
+ <item>The default xdm config file now has a line to disable listening for
+ XDMCP requests. This is fine when xdm is only managing a local
+ X server. The line must be commented out when xdm is used to manage
+ external X servers (e.g., X terminals).
+ <item>New driver for Intel i740. The driver is called "i740".
+ <item>New driver for 3Dfx Banshee and Voodoo 3. The driver is called "tdfx".
+ <item>Some work on adding WYSIWYG capabilities to the Xaw text widget.
+ <item>Some preliminary support for programming modes has been added to xedit.
+</itemize>
+
+<sect>X server
+<p>
+Unlike XFree86 3.3.x where there are multiple X server binaries, each
+of which drive different hardware, XFree86 &relvers; has a single X server
+binary (called <tt>XFree86</tt>). This binary can either have one or
+more video drivers linked in statically, or, more usually, dynamically
+load the video drivers and other modules that are needed.
+
+XFree86 &relvers; has X server support for most UNIX(R) and UNIX-like
+operating systems on Intel/x86 platforms, plus support for Linux on
+Alpha and PowerPC platforms. Support for additional architectures and
+operating systems is planned for future releases.
+
+<sect1>Loader and Modules
+<p>
+The XFree86 X server has a built-in run-time loader, donated by <url
+name="Metro Link" url="http://www.metrolink.com">. This loader can load
+normal object files and libraries in most of the commonly used formats.
+Since the loader doesn't rely on an operating system's native dynamic
+loader support, it works on platforms that don't provide this feature,
+and makes it possible for the modules to be operating system independent
+(although not, of course, independent of CPU architecture). This means
+that, for example, a module compiled on Linux/x86 can be loaded by an
+X server running on Solaris/x86, or FreeBSD, or even OS/2. One of the
+main benefits of this is that when modules are updated, they don't need
+to be recompiled for each different operating system.
+
+The loader in version &relvers; has support for Intel (x86), Alpha and
+PowerPC platforms. It also has preliminary support for Sparc platforms.
+
+The X server makes use of modules for video drivers, X server extensions,
+font rasterisers, input device drivers, framebuffer layers (like mfb,
+cfb, etc), and internal components used by some drivers (like XAA),
+
+The module interfaces (API and ABI) used in the snapshot releases are
+subject to change without notice. This means that there is no guarantee
+that modules built for one snapshot release will function with another
+snapshot release. As of the 4.0 release we plan to make every effort
+to provide backward compatibility for the module interfaces (that means
+older modules working with newer core X server binaries).
+
+<bf>Note about module security</bf>
+<quote><p>
+ The XFree86 X server runs with root privileges, which means that the
+ X server loadable modules also run with these privileges. For this
+ reason we recommend that all users be careful to only use loadable
+ modules from reliable sources. By the time that XFree86 4.0 is
+ released, we hope to have implemented a method for signing/verifying
+ modules that we provide.
+
+</quote>
+
+<sect1>Configuration File <label id="config">
+<p>
+
+The X server configuration file format has been extended to handle some
+of the new functionality. The <tt>xf86config</tt> utility can be used
+to generate a basic config file, that may require some manual editing.
+Alternatively, the sample config file <tt>XF86Config.eg</tt> that is
+installed in <tt>/usr/X11R6/lib/X11</tt> may be used as a starting point.
+The <tt>XF86Setup</tt> utility is currently not usable, but work is
+continuing in this area.
+
+The main changes are:
+
+<itemize>
+ <item>The Module section is used to load server extension modules and
+ font modules, but not XInput drivers. The <tt>.so</tt> suffix
+ should no longer be specified with module names. Options may
+ be supplied for modules by loading the module via a SubSection
+ instead of the usual Load keyword. The <tt>bitmap</tt> module
+ is the only font module that is loaded by default. No server
+ extensions are loaded by default, but some are built-in to the
+ server. The following example shows how to load all the server
+ extensions plus the Type1 and TrueType fonts support, and a
+ commented example that shows how to pass options to an extension
+ (this one is for loading the misc extensions (<tt>extmod</tt>)
+ with the XFree86-VidModeExtension disabled):
+
+<quote><verb>
+Section "Module"
+
+ Load "dbe"
+ Load "record"
+ Load "glx"
+ Load "pex5"
+ Load "xie"
+ Load "extmod"
+
+ Load "type1"
+ Load "freetype"
+
+ # SubSection "extmod"
+ # Option "Omit XFree86-VidModeExtension"
+ # EndSubSection
+
+EndSection
+</verb></quote>
+
+ <item>Option flags have been extended and are now used more widely in the
+ config file. Options flags come in two main types. The first type
+ is exactly like the old form:
+
+<quote><verb>
+ Option "name"
+</verb></quote>
+
+ where the option just has a name specified. The name is case
+ insensitive, and white space and underscore characters are ignored.
+ The second type consists of a name and a value:
+
+<quote><verb>
+ Option "name" "value"
+</verb></quote>
+
+ The value is passed transparently as a string to the code that
+ uses the option. Common value formats are integer, boolean,
+ real, string and frequency. The following boolean option values
+ are recognised as meaning TRUE: <tt>"true"</tt>, <tt>"yes"</tt>,
+ <tt>"on"</tt>, <tt>"1"</tt>, and no value. The values recognised
+ as FALSE are <tt>"false"</tt>, <tt>"no"</tt>, <tt>"off"</tt>,
+ <tt>"0"</tt>. In addition to this, <tt>"no"</tt> may be prepended
+ to the <em>name</em> of a boolean option to indicate that it is
+ false. Frequency options can have the strings <tt>Hz</tt>,
+ <tt>kHz</tt>, or <tt>MHz</tt> appended to the numerical value
+ specified.
+
+ Note: the value must always be enclosed in double quotes
+ (<tt>"</tt>).
+
+ <item>The ServerFlags section now accepts its parameters as Options
+ instead of as special keywords. The older keyword format is
+ still recognised for compatibility purposes, but is deprecated
+ and support for it will likely be dropped in a future release.
+ The DPMS and screen save timeout values are now specified in the
+ ServerFlags section rather than elsewhere (because they are global
+ parameters, not screen-specific). This example shows the defaults
+ for these:
+
+<quote><verb>
+ Option "blank time" "10"
+ Option "standby time" "20"
+ Option "suspend time" "30"
+ Option "off time" "60"
+</verb></quote>
+
+ <item>The Keyboard, Pointer and XInput sections have been replaced by a
+ more general InputDevice section. The old Keyboard and Pointer
+ sections are still recognised for compatibility purposes, but
+ they are deprecated and support for them may be dropped in future
+ releases. The keywords from the old sections are expressed as
+ Options in the InputDevice sections. The following example shows
+ typical InputDevice sections for the core mouse and keyboard.
+
+<quote><verb>
+Section "InputDevice"
+ Identifier "Keyboard 1"
+ Driver "keyboard"
+ Option "AutoRepeat" "500 5"
+ Option "XkbModel" "pc104"
+ Option "XkbLayout" "us"
+EndSection
+
+Section "InputDevice"
+ Identifier "Mouse 1"
+ Driver "mouse"
+ Option "Protocol" "PS/2"
+ Option "Device" "/dev/mouse"
+EndSection
+</verb></quote>
+
+ <item>The Monitor section is mostly unchanged. The main difference is
+ that a set of VESA modes is defined internally in the server,
+ and so for most monitors, it isn't necessary to specify any modes
+ explicitly in the Monitor section. The Monitor section may also
+ include Options. Options that are monitor-specific, like the
+ <tt>"DPMS"</tt> and <tt>"Sync on Green"</tt> options are best
+ specified in the Monitor sections.
+
+ <item>The Device sections are mostly unchanged. The main difference
+ is the new (and mandatory) Driver keyword, that specifies which
+ video driver should be loaded to drive the video card. Another
+ difference is the BusID keyword that is used to specify which of
+ possibly multiple video cards the Device section is for. The
+ following is an example for a Matrox card:
+
+<quote><verb>
+Section "Device"
+ Identifier "MGA 1"
+ Driver "mga"
+ BusID "PCI:1:0:0"
+ Option "PCI Retry"
+EndSection
+</verb></quote>
+
+ <item>The Screen sections are mostly unchanged. The old Driver keyword
+ is no longer used, and a mandatory Identifier keyword has been
+ added. The DefaultColorDepth keyword has been renamed to
+ DefaultDepth.
+
+ <item>A new section called ServerLayout has been added to allow the
+ layout of the screens and the selection of input devices to be
+ specified. The ServerLayout sections may also include options
+ that are normally found in the ServerFlags section. Multiple
+ ServerLayout sections may be present, and selected from the command
+ line. The following example shows a ServerLayout section for a
+ dual-headed configuration with two Matrox cards, and two mice:
+
+<quote><verb>
+Section "ServerLayout"
+ Identifier "Layout 1"
+ Screen "MGA 1"
+ Screen "MGA 2"
+ InputDevice "Keyboard 1" "CoreKeyboard"
+ InputDevice "Mouse 1" "CorePointer"
+ InputDevice "Mouse 2" "SendCoreEvents"
+ Option "BlankTime" "5"
+EndSection
+</verb></quote>
+
+</itemize>
+
+The config file search patch has been extended, with the directories
+<tt>/etc/X11</tt> and <tt>/usr/X11R6/etc</tt> being added.
+
+
+<sect1>Command Line Options
+<p>
+
+The following new X server command line options have been added:
+
+<quote><p>
+
+<tt>-depth</tt> <it>n</it>
+<quote><p>
+ This specifies the colour depth that the server is running at.
+ The default is 8 for most drivers. Most drivers support the
+ values 8, 15, 16 and 24. Some drivers also support the values
+ 1 and 4. Some drivers may also support other depths. Note that
+ the depth is different from the ``bpp'' that was specified with
+ previous versions. The depth is the number of bits in each
+ pixel that are significant in determining the pixel's value.
+ The bpp is the total size occupied by each pixel, including bits
+ that are not used. The old <tt>-bpp</tt> option is no longer
+ recognised because it isn't a good way of specifying the server
+ behaviour.
+
+</quote>
+
+<tt>-fbbpp</tt> <it>n</it>
+<quote><p>
+ This specifies the bpp format to use for the framebuffer. This
+ may be used in 24-bit mode to force a framebuffer format that is
+ different from what the driver chooses by default. In most cases
+ there should be no need to use this option.
+
+</quote>
+
+<tt>-pixmap24</tt>
+<quote><p>
+ This specifies that the client-side pixmap format should be the
+ packed 24-bit format that was often used by the 3.3.x servers.
+ The default is the more common 32-bit format. There should normally
+ be no need to use this option.
+
+</quote>
+
+<tt>-pixmap32</tt>
+<quote><p>
+ This specifies that the client-side pixmap format should be the
+ sparse 32-bit format. This is the default, so there should
+ normally be no need to use this option.
+
+</quote>
+
+<tt>-layout</tt> <it>name</it>
+<quote><p>
+ This specifies which ServerLayout section in the config file to
+ use. When this option is not specified, the first ServerLayout
+ section is used. When there is no ServerLayout section, the
+ first Screen section is used.
+
+</quote>
+
+<tt>-screen</tt> <it>name</it>
+<quote><p>
+ This specifies which Screen section in the config file to
+ use. When this option is not specified, the first ServerLayout
+ section is used. When there is no ServerLayout section, the
+ first Screen section is used.
+
+</quote>
+
+<tt>-keyboard</tt> <it>name</it>
+<quote><p>
+ This specifies which InputDevice section in the config file to
+ use for the core keyboard. This option may be used in conjunction
+ with the <tt>-screen</tt> option.
+
+</quote>
+
+<tt>-pointer</tt> <it>name</it>
+<quote><p>
+ This specifies which InputDevice section in the config file to
+ use for the core pointer. This option may be used in conjunction
+ with the <tt>-screen</tt> option.
+
+</quote>
+
+<tt>-modulepath</tt> <it>path</it>
+<quote><p>
+ This specifies the module search path. The path should be a
+ comma-separated list of absolute directory paths to search for
+ server modules. When specified here, it overrides the value
+ specified in the config file. This option is only available
+ when the server is started by the <tt>root</tt> user.
+
+</quote>
+
+<tt>-logfile</tt> <it>file</it>
+<quote><p>
+ This specifies the log file name. When specified here, it
+ overrides the value specified in the config file. This option
+ is only available when the server is started by the <tt>root</tt>
+ user.
+
+</quote>
+
+<tt>-scanpci</tt>
+<quote><p>
+ This specifies that the <tt>scanpci</tt> module should be loaded and
+ executed. This does a scan of the PCI bus. This option is only
+ available when the server is started by the <tt>root</tt> user.
+
+</quote>
+
+<tt>-logverbose</tt> [<it>n</it>]
+<quote><p>
+ This options specifies the verbosity level to use for the log file.
+ The default is 3.
+
+</quote>
+
+</quote>
+
+The following X server command line options have been changed since 3.3.x:
+
+<quote><p>
+
+<tt>-verbose</tt> [<it>n</it>]
+<quote><p>
+ This option specifies the verbosity level to use for the server
+ messages that get written to stderr. It may be specified multiple
+ times to increase the verbosity level (as with 3.3.x), or the
+ verbosity level may be specified explicitly as a number. The
+ default verbosity level is 1.
+
+</quote>
+
+<tt>-xf86config</tt> <it>filename</it>
+<quote><p>
+ This option has been extended to allow non-root users to specify
+ a relative config file name. The config file search path will be
+ used to locate the file in this case. This makes it possible for
+ users to choose from multiple config files that the the sysadmin
+ has provided.
+
+</quote>
+
+
+</quote>
+
+
+<sect1>XAA
+<p>
+
+The XFree86 Acceleration Architecture (XAA) has been completely rewritten
+from scratch. Most drivers implement acceleration by making use of the
+XAA module.
+
+<sect1>Multi-head
+<p>
+Some multi-head configurations are supported in this release, primarily
+with multiple PCI/AGP cards. However, this is an area that is still
+being worked on, and we expect that the range of configurations for which
+it works well will increase in future snapshots. A configuration that
+is known to work well in most cases is multiple (supported) Matrox cards.
+
+One of the main problems is with drivers not sufficiently initialising
+cards that were not initialised at boot time. Normally only the primary
+video card gets initialised at boot time. Some combinations can be made
+to work better by changing which card is the primary card (either by
+using a different PCI slot, or by changing the system BIOS's preference for
+the primary card). We are investigating options for ``soft-booting''
+secondary video cards to deal with this problem, and we've had some very
+encouraging results.
+
+<sect1>Xinerama
+<p>
+Xinerama is an X server extension that allows multiple physical screens
+to behave as a single screen. With traditional multi-head in X11,
+windows cannot span or cross physical screens. Xinerama removes this
+limitation. Xinerama does, however, require that the physical screens
+all have the same root depth, so it isn't possible, for example, to use
+an 8-bit screen together with a 16-bit screen in Xinerama mode.
+
+Xinerama is not enabled by default, and can be enabled with the
+<tt>+xinerama</tt> command line option for the X server.
+
+Xinerama was included with X11R6.4. The version included in this snapshot
+contains many bug fixes. This is an area that we are still working on, and
+we expect it to be improved further in future snapshots.
+
+Known problems:
+<itemize>
+ <item>The Xinerama layout doesn't match the layout specified in the
+ config file's ServerLayout section.
+
+ <item>It appears that there are still some bugs that cause unexpected
+ behaviour from time to time.
+
+ <item>Most (all?) window managers are not Xinerama-aware, and so some
+ operations like window placement and resizing might not behave
+ in an ideal way. This is an issue that needs to be dealt with
+ in the individual window managers, and isn't specifically an
+ XFree86 problem.
+
+</itemize>
+
+<!--
+<sect1>XVideo extension
+<p>
+-->
+
+<sect1>DGA version 2
+<p>
+
+The DGA extension has been reworked. The version present in this snapshot
+is preliminary, not documented, not implemented by many drivers, and
+subject to further change without notice. Compatibility with version 1.0
+is provided.
+
+<sect1>DDC
+<p>
+The VESA(R) Display Data Channel (DDC&trade;) standard (related to, but
+separate from, the VESA(R) Plug and Display standard) allows the
+monitor to tell the video card (or on some cases the computer
+directly) about itself; particularly the supported screen resolutions
+and refresh rates.
+
+Partial or complete DDC support is available in the following hardware modules
+(this list needs to be verified):
+<itemize>
+ <item>APM
+ <item>Chips
+ <item>Cirrus
+ <item>Glint
+ <item>MGA
+ <item>Neomagic
+ <item>S3 ViRGE
+ <item>SIS
+ <item>Trident
+</itemize>
+
+DDC is enabled by default, but can be disabled
+with a "Device" section entry:
+<tt>Option "NoDDC"</tt>.
+We have support for DDC versions 1 and 2; these can be disabled independently
+with <tt>Option "NoDDC1"</tt> and <tt>Option "NoDDC2"</tt>.
+
+At startup the server prints out DDC information from the display,
+but it does not yet use it the determine modelines.
+
+Changed behavior caused by DDC. Several drivers uses DDC information to
+set the monitor gamma (brightness) curve, and the screen size and
+pitch.
+<itemize>
+ <item>The gamma is particularly noticeable; every monitor I have tried has
+ a gamma setting >&nbsp;2, which means that the picture is much
+ lighter than under 3.3.x or without DDC. To revert to the previous
+ behavior put
+
+ <tscreen>
+Gamma 1.0 1.0 1.0
+ </tscreen>
+
+ in the appropriate "Monitor" section of the config file.
+
+ <item>Similarly, you can override the DDC probed "dpi" value by explicitly
+ resetting it to the 3.3.x and non-DDC default value 75 with the
+ <tt>-dpi 75</tt> command line option for the X server, or by
+ specifying appropriate screen dimensions with the "DisplaySize"
+ keyword in the "Monitor" section of the config file.
+
+</itemize>
+
+<sect1>GLX and the Direct Rendering Infrastructure (DRI)
+<p>
+
+<url name="Precision Insight" url="http://www.precisioninsight.com">
+has been provided with funding and support from <url name="Red Hat"
+url="http://www.redhat.com"> and <url name="SGI" url="http://www.sgi.com">
+to integrate the GLX extension for 3D rendering in an X11 window. The
+3D core rendering component is the <url name="Mesa"
+url="http://www.mesa3d.org"> library. SGI has released the sources to
+the extension framework under an open license, which essentially provides
+the glue between the 3D library and this windowing system. Precision
+Insight has integrated these components into this XFree86 X Server and
+added a Direct Rendering Infrastructure. Direct Rendering provides a
+highly optimized path for sending 3D data directly to the graphics
+hardware. This release <url name="demonstrates a sample implementation
+of direct rendering" url="http://www.precisioninsight.com/demo.html">
+by providing a single path of 3D hardware accelerated rendering for
+the GMX2000 graphics card. Future releases will support much broader
+implementations of hardware accelerated direct rendering on a wide
+range of 3D capable graphics devices.
+
+
+<sect1>Other extensions
+<p>
+
+The XFree86-Misc extension has not been fully ported to the new server
+architecture yet. This should be completed in a future snapshot.
+
+The XFree86-VidModeExtension extension has been updated, and mostly
+ported to the new server architecture. The area of mode validation
+needs further work, and the extension should be used with care. This
+extension has support for changing the gamma setting at run-time, for
+modes where this is possible. The new <tt>xgamma</tt> utility makes
+use of this feature. Compatibility with the 3.3.x version of the
+extension is provided. The missing parts of this extension and some
+new features should be completed in a future snapshot.
+
+
+<sect1>Drivers
+<p>
+
+XFree86 &relvers; includes the following drivers:
+
+<table border=1 align="center">
+<tabular ca="|l|l|">
+ <tabrow>Driver Name<colsep>Description</tabrow>
+ <hline>
+ <tabrow><tt>apm</tt><colsep>Alliance Pro Motion</tabrow>
+ <tabrow><tt>ati</tt><colsep>ATI</tabrow>
+ <tabrow><tt>chips</tt><colsep>Chips &amp; Technologies</tabrow>
+ <tabrow><tt>cirrus</tt><colsep>Cirrus Logic</tabrow>
+ <tabrow><tt>fbdev</tt><colsep>Linux fbdev</tabrow>
+ <tabrow><tt>glide</tt><colsep>Glide2x (3Dfx)</tabrow>
+ <tabrow><tt>glint</tt><colsep>3Dlabs</tabrow>
+ <tabrow><tt>i740</tt><colsep>Intel i740</tabrow>
+ <tabrow><tt>mga</tt><colsep>Matrox</tabrow>
+ <tabrow><tt>neomagic</tt><colsep>NeoMagic</tabrow>
+ <tabrow><tt>nv</tt><colsep>NVIDIA</tabrow>
+ <tabrow><tt>rendition</tt><colsep>Rendition</tabrow>
+ <tabrow><tt>s3virge</tt><colsep>S3 ViRGE</tabrow>
+ <tabrow><tt>sis</tt><colsep>SiS</tabrow>
+ <tabrow><tt>tdfx</tt><colsep>3Dfx</tabrow>
+ <tabrow><tt>tga</tt><colsep>DEC TGA</tabrow>
+ <tabrow><tt>trident</tt><colsep>Trident</tabrow>
+ <tabrow><tt>tseng</tt><colsep>Tseng Labs</tabrow>
+ <tabrow><tt>vga</tt><colsep>Generic VGA</tabrow>
+</tabular>
+</table>
+
+<sect2>APM <label id="apm">
+<p>
+
+The driver apm is for Alliance AT3D/AT25 based boards. The driver is
+still in development. I hope to be able to correct the errors I find.
+The Rush extension should be ready for the next snapshot; I can do better
+memory management, but I'll need time. If someone can help me, feel free
+to drop an email to <email>grenie@lami.univ-evry.fr</email>
+
+<sect2>Chips &amp; Technologies
+<p>
+
+Information about the C&amp;T driver can be found in <htmlurl
+name="README.chips" url="chips.html">.
+
+<sect2>s3virge
+<p>
+
+The s3virge driver is a port of the 3.3.3.1 SVGA S3 ViRGE driver. As
+such it should be as stable and functional as previous XFree86
+releases. There are a couple additional benefits included primarily due
+to common enhancements:
+
+<itemize>
+ <item>Depth 24 problems resolved with clients using 24/32 bpp pixmaps.
+ <item>Our common acceleration architecture (XAA) has been re-written,
+ as has the ViRGE acceleration code. You should find this version
+ has better performance than prior releases.
+
+ <item>Multi-head is reported to work.
+ <item>The <tt>s3virge</tt> man page lists options and has configuration
+ notes for this release of the driver.
+
+</itemize>
+
+Outstanding items not implemented or fully tested:
+
+<itemize>
+ <item>DGA support is implemented, but preliminary and untested.
+ <item>ViRGE MX Melco BIOS support has not been ported yet.
+</itemize>
+
+<sect2>TGA
+<p>
+
+The TGA driver is now accelerated and supports both 8 and 32 plane
+framebuffers. It is known to work under Linux/Alpha. Please see the
+<htmlurl name="README.DECtga" url="DECtga.html"> file for further
+information.
+
+<sect2>Matrox
+<p>
+
+The MGA driver supports the same range or hardware as XFree86 3.3.4,
+but has a number of enhancements including multi-head support and
+support for overlays (8-bit + 24-bit).
+
+Option <tt>"overlay"</tt> when the server is started in 32bpp
+(<tt>-fbbpp&nbsp;32</tt>) will enable the 8+24 mode. The current
+implementation doesn't optimize away unnecessary exposures yet so the
+performance of this option will be better in future snapshots. The
+option is not supported on the G100 due to a missing hardware feature.
+By default, the color key for the overlays is 255, but this can be
+changed with the <tt>"ColorKey"</tt> option to work around problems in
+specific programs. Valid values for the key are 2-255.
+
+Option <tt>"OverclockMem"</tt> will raise the memory clock on the G200.
+Matrox doesn't recommend deviating from the BIOS defaults but we find
+that some hardware shows static during graphics operations in high
+resolutions/depths when run at the regular clocks so this option is
+needed for some cards (it also improves performance). Beware, some
+hardware experiences difficultly restoring the console when this option
+is used.
+
+Further information can be found in the <tt>mga</tt> man page.
+
+<sect2>ATI
+<p>
+
+Information about the ATI driver can be found in <url name="README.ati"
+url="ati.html">. The current version is not accelerated. Acceleration
+support is planned for a future snapshot.
+
+
+<sect>X libraries and clients
+<p>
+
+<sect1>Xaw
+<p>
+
+Two versions of the Xaw library are provided in this release. A version with
+bug fixes and a few binary compatible improvements and a new version with
+several new features.
+
+New features:
+
+<itemize>
+
+ <item>A <tt>displayList</tt> resource is available to all Xaw widgets. It
+ basically consists of a list of drawing commands, fully described in
+ the <tt>Xaw(3)</tt> manual page, that enables a integration of Xaw
+ programs with the new window/desktop managers that allows for
+ configurable themes.
+
+ <item>Some new actions were added to all Xaw widgets, to allow more
+ configurable control of the widgets, and to allow setting resources
+ at run time.
+
+ <item>Since Xpm was integrated into XFree86, programs linked with the
+ new Xaw library will also link with Xpm. This allows for color
+ background pixmaps, and also for shaped widgets.
+
+ <item>The text widget is the widget that will present more changes. These
+ include:
+
+ <itemize>
+
+ <item>Block cursor.
+
+ <item>Compile time limit of 16384 undo/redo levels (that will
+ automatically grow if the text is not saved when this mark is
+ reached).
+
+ <item>Overwrite mode.
+
+ <item>Text killed is inserted in a kill ring list, this text is not
+ forgotten, pressing <tt>M-y</tt> allows traversing the kill
+ ring list.
+
+ <item>International support for latin languages is available even
+ if the <tt>international</tt> resource is not set. Users will
+ need to properly set the <it>locale</it> environment to make
+ complete use of this feature.
+
+ <item>A better <tt>multiply</tt> interface is provided. Pressing
+ <tt>C-u,&lt;number&gt;</tt> (where number can be negative)
+ allows passing parameters for text actions.
+
+ <item>Text can be formatted to have left, right, center or full
+ justification.
+
+ <item>Text indentation support is also available.
+
+ </itemize>
+
+ <item>This snapshot shows the current state of the work to add to the Xaw
+ text widget WYSIWYG capabilities. The state is very initial, and
+ can be seen as a candidate to a candidate to a very early alpha
+ snapshot. There is no public interface for programming yet, because
+ the current one is very likely to change before ready to use.
+
+</itemize>
+
+Bug fixes:
+
+<itemize>
+
+ <item>The simple menu widget geometry management code was improved to solve
+ problems with menu entries not visible in the screen.
+
+ <item>The form widget geometry code was changed to solve problems with integer
+ round problems in the child widgets geometry when resizing the parent
+ form widget.
+
+ <item>Several bugs were fixed in the text code, while some code was rewritten
+ from scratch.
+
+</itemize>
+
+<p>
+
+<sect1>Xpm
+<p>
+
+Version 3.4k of the Xpm (X pixmap) library is now integrated into XFree86.
+
+<sect1>xterm
+<p>
+
+New Features:
+
+<itemize>
+ <item>Support Unix98 PTY's.
+
+ <item>Support Unicode using UTF-8 input and output. There are a few
+ limitations, this work is still in progress:
+
+ <itemize>
+ <item>You must use the <tt>-u8</tt> command line option to
+ use this feature, as well as compile with the
+ <tt>OPT_WIDE_CHARS</tt> definition. (The feature is
+ compiled when using imake).
+
+ <item>Input (from keyboard) and output (select/paste) are in
+ UTF-8 form. There is no support in Xlib for UTF-8;
+ xterm uses a lookup table to map keysym codes.
+ Select/paste is done either via <tt>STRING</tt> or using
+ the new atom <tt>UTF8_STRING</tt>.
+
+ </itemize>
+
+ <item>Add optional feature (resource and command-line options) to make
+ xterm use the PTY's sense of erase character on startup, rather
+ than requiring it to be <tt>\177</tt>, or set the PTY's erase
+ character to match xterm's configuration. Note that while
+ <tt>$TERMCAP</tt> is modified to reflect the actual configuration,
+ the terminfo <tt>kdch1</tt> string is not. (This feature is
+ also in XFree86 3.3.4).
+
+ <item>Revised keyboard handling, making two modes (VT220 and Sun/PC) which
+ are switched by popup menu. This makes the numeric keypad work as
+ expected. Codes sent by the backarrow and delete keys also are
+ affected.
+
+ <item>Add parameters to function key escape sequences to indicate if
+ shift, control or alt are set. This works for Sun/PC keyboard
+ mode.
+
+ <item>Separated command-line and menu settings for reverse video from that
+ done under program control. This is a problem which was introduced
+ by X11R6. Though correct, most users are confused by allowing
+ the reset command to undo the effect of the command-line
+ <tt>-rv</tt> option.
+
+ <item>Blinking cursor can be specified by resource or popup menu.
+
+ <item>New control sequences for switching between normal and alternate
+ screens maintain separate cursor-save locations for the two screens,
+ avoiding incorrect cursor placement on exit from vi.
+
+ <item>Support line-drawing characters when the font does not include them
+ by drawing them.
+
+ <item>Add support for switching font sizes, by stepping through the font
+ menu using shifted keypad plus and minus.
+
+ <item>New resource <tt>trimSelection</tt> allows xterm to trim trailing
+ blanks from selected lines.
+
+ <item>Provide user applications a means of determining the version of xterm
+ for feature comparison by returning the patch number (e.g., 111) in
+ the secondary DA response.
+
+</itemize>
+
+Bug fixes/improvements:
+
+<itemize>
+ <item>If <tt>colorMode</tt> is enabled by default, compile-in default
+ resources to match the colors listed in <tt>XTerm-col.ad</tt>.
+
+ <item>Deprecate DA answerback string, making it settable via a resource
+ value for applications which may need this.
+
+ <item>Input characters which are mapped when in vt220 National Replacement
+ Character mode.
+
+ <item>Completed support for double size characters.
+
+ <item>Remove <tt>kfnd</tt>/<tt>kll</tt>/<tt>kslt</tt> strings from
+ terminfo, because curses applications do not necessarily return
+ <tt>khome</tt>/<tt>kend</tt> pairs.
+
+ <item>Corrected ifdef's for menus, which did not allow tek4014 to be
+ suppressed properly.
+
+ <item>Improved tests for determining if xterm should use overstriking to
+ simulate bold fonts.
+
+ <item>Add test/demo scripts for double size characters, font switching,
+ screen resizing and colors.
+
+</itemize>
+
+<sect1>xedit
+<p>
+
+Xedit have been changed to use most of the new features added to the new
+version of the Xaw library, and some xedit only features were added. Emacs
+users will find that several of the emacs key bindings work with the new
+version of xedit. These include:
+
+<itemize>
+
+ <item>File name tab completion. Including a <it>Emacs dired</it> like window,
+ that will be shown when there are more than one match, when
+ <tt>C-x,d</tt> is pressed, or when a directory name is specified.
+
+ <item>An unlimited number of files can be edited at the same time. Including
+ multiple views of the same or different files.
+
+ <item>The line number of the cursor position is always visible. It can also
+ be customized to show the column number, the position offset and the
+ current size of the file.
+
+ <item>There is an <tt>autoReplace</tt> resource, that enables automatic text
+ replacement at the time text is typed. This feature is useful to create
+ simple macros, or to correct common spelling errors.
+
+ <item>A fully featured ispell interface is also available. This interface
+ is expected to provide most of the features of the terminal interface
+ of the ispell program, with some extra features that include:
+
+ <itemize>
+
+ <item>A compile time limit of 16 undo levels.
+
+ <item>Terse mode switch.
+
+ <item>Dictionary change.
+
+ <item>The interface also checks for repeated words.
+
+ </itemize>
+
+ <item>A first tentative to add programming modes was done. Currently, there
+ are two modes:
+ <itemize>
+
+ <item><bf>C-mode:</bf> this mode is expected to be stable, and fully
+ usable.
+
+ <item><bf>Html-mode:</bf> a lot of work needs to be done yet. It is
+ included in this snapshot only to show what the new text widget
+ capabilities can do.
+ </itemize>
+
+</itemize>
+
+<p>
+
+
+<sect>Fonts and Internationalisation
+<p>
+
+Details about the font support in this version of XFree86 can be found
+in the <htmlurl name="README.fonts" url="fonts.html"> document.
+
+<sect1>TrueType support
+<p>
+
+This version of XFree86 comes with two TrueType backends, known as
+`xfsft' (the <tt>"freetype"</tt> module) and `X-TrueType' (the
+<tt>"xtt"</tt> module). Both of these backends are based on the FreeType
+library.
+
+<sect1>CID font support
+<p>
+
+Support for CID-keyed fonts is included in this version of XFree86.
+The CID-keyed font format was designed by <url name="Adobe Systems"
+url="http://www.adobe.com"> for fonts with large character sets. The
+CID-keyed font support in XFree86 was donated by <url name="SGI"
+url="http://www.sgi.com">. See the <htmlurl name="LICENSE"
+url="LICENSE.html"> document for a copy of the CID Font Code Public
+License.
+
+<sect1>Internationalisation of the scalable font backends
+<p>
+
+A new ``fontenc'' layer has been added to allow the scalable font backends
+to use a common method of font re-encoding. This re-encoding makes it
+possible to uses fonts in encodings other than their their native
+encoding. This layer is used by the Type1 and Speedo backends and the
+`xfsft' version of the TrueType backend. The `X-TrueType' version of
+the TrueType backend uses a different re-encoding method based on loadable
+encoding modules.
+
+<sect1>Unicode support
+<p>
+What is included:
+
+<itemize>
+ <item>ISO 10646-1 extension of ``fixed'' BDF fonts added that cover
+ over 2000 characters including all Latin, Greek, Cyrillic,
+ Armenian, and Gregorian characters, plus numerous scientific
+ and technical symbols (further fonts are under preparation).
+
+ <item>Mark Leisher's ClearlyU proportional font (similar to Computer
+ Modern).
+
+ <item>ISO 10646/Unicode UTF-8 Level 1 support added to xterm
+ (enabled with the <tt>-u8</tt> option).
+
+ <item>Both the xfsft (the <tt>"freetype"</tt> module) and the X-TrueType
+ (the <tt>"xtt"</tt> module) TrueType font backends support
+ Unicode-encoded fonts.
+
+</itemize>
+
+Known problems:
+
+<itemize>
+ <item>Xlib does not yet support UTF-8 as a locale, which means that
+ xterm UTF-8 keyboard support is at the moment a temporary hack.
+
+ <item>ISO 10646-1 cell-spaced fonts such as ``fixed'' work nicely, but
+ mono-spaced and proportional fonts are handled inefficiently
+ by the X protocol, resulting in metrics for 64k glyphs even if
+ only 2000 glyphs are used.
+
+ <item>ISO 10646 Level 2 combining characters not yet supported by
+ xterm (will be needed for instance for the Thai script).
+
+</itemize>
+
+
+<sect>Miscellaneous
+<p>
+
+<sect1>Directory rearrangements
+<p>
+
+Some changes to the installed XFree86 directory structure have been
+planned for 4.0. Not all of these changes have been implemented in this
+snapshot, and they will appear in a future snapshot. One important
+change that has been implemented is a modified search path for the X
+server's <tt>XF86Config</tt> file. The details of this can be found
+above in the <ref id="config" name="Configuration File"> section.
+
+
+
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/S3.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/S3.sgml
new file mode 100644
index 000000000..4ae0cace4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/S3.sgml
@@ -0,0 +1,933 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+<title> Information for S3 Chipset Users
+<author>The XFree86 Project Inc.
+<date>27 February 1998
+<toc>
+
+<sect> Supported hardware
+<p>
+The current S3 Server supports the following S3 chipsets: 911, 924,
+801/805, 928, 732 (Trio32), 764, 765, 775, 785 (Trio64*),
+864, 868, 964, 968 and M65 (Aurora64V+). The
+S3 server will also recognise the 866, but it has not been tested with
+this chipset. If you have any problems or success with these, please
+report it to us.
+
+Nevertheless, this is not enough to support every board using one of these
+chipsets. The following list contains some data points on boards that are
+known to work. If your card is similar to one of the described ones,
+chances are good it might work for you, too.
+
+<descrip>
+<tag>S3 801/805, AT&amp;T 20C490 (or similar) RAMDAC</tag>
+ <itemize>
+ <item>Orchid Fahrenheit 1280+ VLB
+ <item>Actix GE32
+ </itemize>
+
+ 8 and 15/16 bpp
+
+ Note: Real AT&amp;T20C490 RAMDACs should be automatically detected by
+ the server. For others which are compatible, you need to provide
+ a `<tt/Ramdac "att20c490"/'
+ entry in your <tt/XF86Config/.
+
+ Real AT&amp;T 20C490 or 20C491 RAMDACs work with the
+ <tt/"dac_8_bit"/ option. Some clones (like the Winbond
+ 82C490) do not.
+
+ The Orchid Fahrenheit 1280+ VLB may require `<tt/Option "nolinear"/'.
+
+
+
+<tag>S3 805 VLB, S3 GENDAC (RAMDAC + clock synthesizer)</tag>
+ <itemize>
+ <item>MIRO 10SD (available for VLB and PCI)
+ It is not known whether all 10SDs use the S3 GENDAC.
+ </itemize>
+
+ 8 and 15/16 bpp
+
+ <tscreen><verb>
+ ClockChip "s3gendac"
+ RamDac "s3gendac"
+ </verb></tscreen>
+
+
+<tag>S3 801/805, AT&amp;T 20C490 RAMDAC, ICD2061A Clockchip</tag>
+ <itemize>
+ <item>STB PowerGraph X.24 S3 (ISA)
+ </itemize>
+
+ 8 and 15/16 bpp
+
+ Note: Real AT&amp;T20C490 RAMDACs should be automatically detected by
+ the server. For others which are compatible, you need to provide
+ a `<tt/Ramdac "att20c490"/'
+ entry in your <tt/XF86Config/.
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ RamDac "att20c490"
+ Option "dac_8_bit
+ </verb></tscreen>
+
+
+<tag>S3 805, Diamond SS2410 RAMDAC, ICD2061A Clockchip</tag>
+ <itemize>
+ <item>Diamond Stealth 24 VLB
+ </itemize>
+
+ 8 and 15bpp(*) only.
+
+ requires `<tt/Option "nolinear"/'
+
+ (*) The SS2410 RAMDAC is reportedly compatible with the AT&amp;T20C490
+ in 15bpp mode. To make the server treat it as an AT&amp;T20C490,
+ you need to provide a `<tt/Ramdac "att20c490"/' entry in your
+ <tt/XF86Config/.
+
+
+<tag>S3 801/805, Chrontel 8391 Clockchip/Ramdac</tag>
+ <itemize>
+ <item>JAX 8241
+ <item>SPEA Mirage
+ </itemize>
+
+ 8 and 15/16 bpp.
+
+ The 8391 is compatible with the AT&amp;T 20C490 RAMDAC
+
+ <tscreen><verb>
+ ClockChip "ch8391"
+ Ramdac "ch8391"
+ Option "dac_8_bit"
+ </verb></tscreen>
+
+
+<tag>S3 928, AT&amp;T 20C490 RAMDAC </tag>
+ <itemize>
+ <item>Actix Ultra
+ </itemize>
+
+ 8 and 15/16 bpp
+
+ Note: Real AT&amp;T20C490 RAMDACs should be automatically detected by
+ the server. For others which are compatible, you need to provide
+ a `<tt/Ramdac "att20c490"/'
+ entry in your <tt/XF86Config/. Also, the server's RAMDAC probe
+ reportedly causes problems with some of these boards, and a
+ RamDac entry should be used to avoid the probe.
+
+ Real AT&amp;T 20C490 or 20C491 RAMDACs work with the
+ <tt/"dac_8_bit"/ option. Some clones (like the Winbond
+ 82C490) do not.
+
+
+<tag>S3 928, Sierra SC15025 RAMDAC, ICD2061A Clockchip</tag>
+ <itemize>
+ <item>ELSA Winner 1000 ISA/EISA (``TwinBus'', not Winner1000ISA!!)
+ <item>ELSA Winner 1000 VL
+ </itemize>
+
+ 8, 15/16 and 24(32) bpp
+
+ Supports 8bit/pixel RGB in 8bpp and gamma correction for 15/16
+ and 24bpp modes
+
+ 24 bpp might get ``snowy'' if the clock is near the limit of
+ 30MHz. This is not considered dangerous, but limits the
+ usability of 24 bpp.
+
+ D-step (or below) chips cannot be used with a line width of
+ 1152; hence the most effective mode for a 1 MB board is about
+ 1088x800x8 (similar to 2 MB, 1088x800x16).
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ </verb></tscreen>
+
+
+<tag>S3 928, Bt9485 RAMDAC, ICD2061A Clockchip</tag>
+ <itemize>
+ <item>STB Pegasus VL
+ </itemize>
+
+ 8, 15/16 and 24(32) bpp
+
+ Supports RGB with sync-on-green if <tt/"sync_on_green"/
+ option is provided and board jumper is set for BNC outputs.
+
+ VLB linear addressing now occurs at 0x7FCxxxxx so that 64MB
+ or more main memory can be supported without losing linear
+ frame buffer access.
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ Option "stb_pegasus"
+ </verb></tscreen>
+
+
+<tag>S3 928, Bt485 RAMDAC, SC11412 Clockchip</tag>
+ <itemize>
+ <item>SPEA Mercury 2MB VL
+ </itemize>
+
+ 8, 15/16 and 24(32) bpp
+
+ <tscreen><verb>
+ ClockChip "SC11412"
+ Option "SPEA_Mercury"
+ </verb></tscreen>
+
+
+<tag>S3 928, Bt485 RAMDAC, ICD2061A Clockchip</tag>
+ <itemize>
+ <item>&num;9 GXE Level 10, 11, 12
+ </itemize>
+
+ 8, 15/16 and 24(32) bpp
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ Option "number_nine"
+ </verb></tscreen>
+
+
+<tag>S3 928, Ti3020 RAMDAC, ICD2061A Clockchip</tag>
+ <itemize>
+ <item>&num;9 GXE Level 14, 16
+ </itemize>
+
+ 8, 15/16 and 24(32) bpp
+
+ Supports RGB with sync-on-green
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ Option "number_nine"
+ </verb></tscreen>
+
+
+<tag>S3 864, AT&amp;T20C498, ICS2494 Clockchip</tag>
+ <itemize>
+ <item>MIRO 20SD (BIOS 1.xx)
+ </itemize>
+
+ The ICS2494 is a fixed frequency clockchip, you have to use
+ X -probeonly (without a Clocks line in XF86Config) to get the
+ correct clock values.
+
+ 8, 15/16 and 24(32) bpp
+
+
+<tag>S3 864, AT&amp;T20C498 or STG1700 RAMDAC, ICD2061A or ICS9161 Clockchip</tag>
+ <itemize>
+ <item>Elsa Winner1000PRO VLB
+ <item>Elsa Winner1000PRO PCI
+ <item>MIRO 20SD (BIOS 2.xx)
+ <item>Actix GraphicsENGINE 64 VLB/2MB
+ </itemize>
+
+ 8, 15/16 and 24(32) bpp
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ </verb></tscreen>
+
+
+<tag>S3 864, 20C498 or 21C498 RAMDAC, ICS2595 Clockchip</tag>
+ <itemize>
+ <item>SPEA MirageP64 2MB DRAM (BIOS 3.xx)
+ </itemize>
+
+ 8, 15/16 and 24(32) bpp
+
+ Clockchip support is still sometimes flaky and on some machines
+ problems with the first mode after startup of XF86_S3 or after
+ switching back from VT have been seen; switching to next mode
+ with CTRL+ALT+``KP+'' and back seems to solve this problem.
+
+ Interlaced modes don't work correctly.
+
+ Mirage P64 with BIOS 4.xx uses the S3 SDAC.
+
+ <tscreen><verb>
+ ClockChip "ics2595"
+ </verb></tscreen>
+
+
+<tag>S3 864, S3 86C716 SDAC RAMDAC and Clockchip</tag>
+ <itemize>
+ <item>Elsa Winner1000PRO
+ <item>MIRO 20SD (BIOS 3.xx)
+ <item>SPEA MirageP64 2MB DRAM (BIOS 4.xx)
+ <item>Diamond Stealth 64 DRAM
+ </itemize>
+
+ 8, 15/16 and 24 bpp
+
+
+<tag>S3 864, ICS5342 RAMDAC and Clockchip</tag>
+ <itemize>
+ <item>Diamond Stealth 64 DRAM (only some cards)
+ </itemize>
+
+ 8, 15/16 and 24 bpp
+
+ <tscreen><verb>
+ ClockChip "ics5342"
+ Ramdac "ics5342"
+ </verb></tscreen>
+
+
+<tag>S3 864, AT&amp;T21C498-13 RAMDAC, ICD2061A Clockchip</tag>
+ <itemize>
+ <item>&num;9 GXE64 - PCI
+ </itemize>
+
+ 8, 15/16, 24(32) bpp
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ Option "number_nine"
+ </verb></tscreen>
+
+
+<tag>S3 964, AT&amp;T 20C505 RAMDAC, ICD2061A Clockchip</tag>
+ <itemize>
+ <item>Miro Crystal 20SV
+ </itemize>
+
+ 8, 15/16, 24(32) bpp
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ Ramdac "att20c505"
+ </verb></tscreen>
+
+
+<tag>S3 964, Bt485 RAMDAC, ICD2061A Clockchip</tag>
+ <itemize>
+ <item>Diamond Stealth 64
+ </itemize>
+
+ 8, 15/16, 24(32) bpp
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ </verb></tscreen>
+
+
+<tag>S3 964, Bt9485 or AT&amp;T 20C505 RAMDAC, ICS9161a Clockchip</tag>
+ <itemize>
+ <item>SPEA Mercury 64
+ </itemize>
+
+ 8, 15/16, 24(32) bpp
+
+ <tscreen><verb>
+ ClockChip "ics9161a"
+ Option "SPEA_Mercury"
+ </verb></tscreen>
+
+
+<tag>S3 964, Ti3020 RAMDAC, ICD2061A Clockchip</tag>
+ <itemize>
+ <item>Elsa Winner2000PRO PCI
+ </itemize>
+
+ 8, 15/16, 24(32) bpp
+
+ <tscreen><verb>
+ ClockChip "icd2061a"
+ </verb></tscreen>
+
+
+<tag>S3 964, Ti3025 RAMDAC, Ti3025 Clockchip</tag>
+ <itemize>
+ <item>Miro Crystal 40SV
+ <item>&num;9 GXE64 Pro VLB
+ <item>&num;9 GXE64 Pro PCI
+ </itemize>
+
+ 8 bpp, 15, 16 and 24(32) bpp
+
+ There are some known problems with the GXE64 Pro support,
+ including some image shifting/wrapping at 15/16/24 bpp.
+
+ We have found that &num;9 no longer support the GXE64 Pro
+ at 1600x1200. They do however have a new (and more expensive)
+ board called the GXE64Pro-1600 which uses a 220MHz RAMDAC
+ instead of 135MHz part used on the other boards.
+
+
+<tag>S3 764 (Trio64)</tag>
+ <itemize>
+ <item>SPEA Mirage P64 (BIOS 5.xx)
+ <item>Diamond Stealth 64 DRAM
+ <item>&num;9 GXE64 Trio64
+ </itemize>
+
+ 8/15/16/24 bpp
+
+ Note: The Trio64 has a builtin RAMDAC and clockchip, so the server
+ should work with all Trio64 cards, and there is no need to specify
+ the RAMDAC or clockchip in the <tt/XF86Config/ file.
+
+
+<tag>S3 732 (Trio32)</tag>
+ <itemize>
+ <item>Diamond Stealth 64 DRAM SE
+ </itemize>
+
+ 8/15/16/24 bpp
+
+ Note: The Trio32 has a builtin RAMDAC and clockchip, so the server
+ should work with all Trio32 cards, and there is no need to specify
+ the RAMDAC or clockchip in the <tt/XF86Config/ file.
+
+
+<tag>S3 868, S3 86C716 SDAC RAMDAC and Clockchip</tag>
+ <itemize>
+ <item>ELSA Winner 1000AVI
+ <item>Diamond Stealth Video DRAM
+ </itemize>
+
+ 8/15/16/24 bpp
+
+<tag>S3 868, AT&amp;T 20C409 RAMDAC and Clockchip</tag>
+ <itemize>
+ <item>ELSA Winner 1000AVI
+ </itemize>
+
+ 8/15/16/24 bpp
+
+ Note: pixelmultiplexing is not supported yet, therefore limited
+ maximum dot clock for 8bpp (currently 67.5MHz, should be changed
+ to 100MHz if pixmux isn't fixed prior to release)
+
+<tag>S3 968, Ti3026 RAMDAC, Ti3026 Clockchip</tag>
+ <itemize>
+ <item>Elsa Winner 2000PRO/X-2 and /X-4 (Revsions <= F)
+ <item>Elsa Winner 2000AVI-2 and -4
+ <item>Diamond Stealth 64 VIDEO VRAM
+ </itemize>
+
+ 8/15/16/24 bpp
+
+<tag>S3 968, Ti3026 RAMDAC, ICS9161A Clockchip</tag>
+ <itemize>
+ <item>Elsa Winner 2000PRO/X-2 and /X-4 (Revision G)
+ </itemize>
+
+ 8/15/16/24 bpp
+
+ Note: clock doubling doesn't work, yet, therefore the maximum
+ usable dot clock is limited to about 120MHz.
+
+<tag>S3 964, IBM RGB 514/524/525/528 RAMDAC &amp; Clockchip</tag>
+ <itemize>
+ <item>Hercules Graphics Terminator 64
+ </itemize>
+
+ 8/15/16/24 bpp
+
+ <tscreen><verb>
+ s3RefClk 50
+ DACspeed 170
+ Option "slow_vram"
+ </verb></tscreen>
+
+<tag>S3 968, IBM RGB 514/524/525/528 RAMDAC &amp; Clockchip</tag>
+ <itemize>
+ <item>Genoa Genoa VideoBlitz III AV
+ <tscreen><verb>
+ s3RefClk 50
+ DACspeed 170
+ </verb></tscreen>
+ <item>Hercules Graphics Terminator Pro 64
+ <tscreen><verb>
+ s3RefClk 16
+ DACspeed 220
+ </verb></tscreen>
+ This card may require the line:
+ <tscreen><verb>
+ Invert_VCLK "*" 0
+ </verb></tscreen>
+ in each Display subsection.
+ <item>STB Velocity 64
+ <tscreen><verb>
+ s3RefClk 24
+ DACspeed 220
+ </verb></tscreen>
+ <item>Number Nine FX Motion 771
+ <tscreen><verb>
+ s3RefClk 16
+ DACspeed 220
+ </verb></tscreen>
+ This card may require the line:
+ <tscreen><verb>
+ Invert_VCLK "*" 0
+ </verb></tscreen>
+ in each Display subsection.
+ <item>MIRO 80SV
+ <tscreen><verb>
+ s3RefClk 16
+ DACspeed 250
+ </verb></tscreen>
+ </itemize>
+
+ 8/15/16/24 bpp
+
+<tag>ELSA Winner 2000PRO/X-8 (S3 968, 8MB VRAM, 220MHz for 32bpp)</tag>
+
+ The server has only been tested for "revision C" of this card
+ (guess the serial number should start with C, but not sure since
+ mine says Ser.No. A-0000.000.000;) which have an IBM RGB528A
+ note the A; can't be probed though)
+
+ depending on the mode line etc there may be some display distortions like:
+ <enum>
+ <item>many long horizontal lines/stripes
+ <item>pixel jitter or short horizontal stripes like snow all over the
+ screen
+ <item>Like 2., but only when doing graphics ops (like opaque move of
+ windows).
+ <item>additional pixel at the left display edge and some missing pixels
+ at the right edge.
+ </enum>
+ All of these problems can be fixed by small adjustments to the mode line
+ (best to run `xvidtune' and make these adjustments interactively). E.g.,
+ for the first three problems, shift the display left or right a few steps.
+ For the last problem, increasing HSyncEnd (making the hsync pulse longer)
+ solves the problem. In some cases, a significant increase in the sync
+ pulse width is needed, and rarely, it needs to be shortened (by decreasing
+ HSyncEnd).
+
+ In rare cases, InvertVCLK and/or EarlySC may need to be adjusted, followed
+ by an adjustment of BlankDelay (see the bottom line of xvidtune).
+
+ If you see any of these problems, please contact
+ <htmlurl url="mailto:koenig@XFree86.org" name="koenig@XFree86.org">, and
+ send details of:
+ <itemize>
+ <item>Original mode showing the problem,
+ <item>Tuned/fixed mode, including all flags from the bottom line of
+ xvidtune,
+ <item>Colour depth used for this tuned mode line,
+ <item>Full server startup output.
+ </itemize>
+
+
+</descrip>
+
+<sect> 16bpp and 32bpp
+<p>
+
+On 801/805 + AT&amp;T490 Cards (like the Fahrenheit 1280+ VLB) only 15 and
+16bpp are supported. 32bpp isn't available on this type of
+card. (There is a 24 bit mode under MS Windows, but it's not a 32bpp
+sparse mode but a real 3 bytes/pixel mode).
+
+<sect>List of Supported Clock Chips
+<p>
+
+<tscreen><verb>
+ICD2061A ==> ClockChip "icd2061a"
+ICS9161A (ICD2061A compatible) ==> ClockChip "ics9161a"
+DCS2824-0 (Diamond, ICD2061A comp.) ==> ClockChip "dcs2824"
+
+S3 86c708 GENDAC ==> ClockChip "s3gendac"
+ICS5300 GENDAC (86c708 compatible) ==> ClockChip "ics5300"
+
+S3 86c716 SDAC ==> ClockChip "s3_sdac"
+ICS5342 GENDAC ==> ClockChip "ics5342"
+STG 1703 ==> ClockChip "stg1703"
+
+Sierra SC11412 ==> ClockChip "sc11412"
+ICS2595 ==> ClockChip "ics2595"
+TI3025 ==> ClockChip "ti3025"
+TI3026 ==> ClockChip "ti3026"
+IBM RGB 5xx ==> ClockChip "ibm_rgb5xx"
+
+Chrontel 8391 ==> ClockChip "ch8391"
+
+AT&amp;T 20C409 ==> ClockChip "att20c409"
+AT&amp;T 20C499 (untested) ==> ClockChip "att20c499"
+</verb></tscreen>
+
+<sect>List of Supported RAMDAC Chips
+<p>
+If you have a RAMDAC that is not listed here, be VERY careful not to
+overdrive it using XF86_S3. Better contact the XFree86 team first to
+verify that running XF86_S3 will not damage your board.
+
+RAMDACs that are grouped together below are treated as compatible
+with each other as far as the server is concerned. For example, the
+server will report <tt>"bt485"</tt> when you actually specify
+<tt>RAMDAC "bt9485"</tt>, or <tt>"s3_gendac"</tt> when you specify
+<tt>RAMDAC "ics5300"</tt>.
+
+<tscreen><verb>
+ATT20C409 ==> RAMDAC "att20c409"
+
+ATT20C490 ==> RAMDAC "att20c490"
+ATT20C491 ==> RAMDAC "att20c491"
+CH8391 ==> RAMDAC "ch8391"
+
+ATT20C498 ==> RAMDAC "att20c498"
+ATT21C498 ==> RAMDAC "att21c498"
+
+ATT22C498 ==> RAMDAC "att22c498"
+
+ATT20C505 ==> RAMDAC "att20c505"
+
+BT485 ==> RAMDAC "bt485"
+BT9485 ==> RAMDAC "bt9485"
+
+IBMRGB514 ==> RAMDAC "ibm_rgb514"
+IBMRGB525 ==> RAMDAC "ibm_rgb525"
+
+IBMRGB524 ==> RAMDAC "ibm_rgb524"
+IBMRGB526 ==> RAMDAC "ibm_rgb526"
+
+IBMRGB528 ==> RAMDAC "ibm_rgb528"
+
+S3_GENDAC ==> RAMDAC "s3gendac"
+ICS5300 ==> RAMDAC "ics5300"
+
+S3_SDAC ==> RAMDAC "s3_sdac"
+ICS5342 ==> RAMDAC "ics5342"
+
+S3_TRIO32 ==> RAMDAC "s3_trio32"
+
+S3_TRIO64 ==> RAMDAC "s3_trio64"
+S3_TRIO64 ==> RAMDAC "s3_trio"
+
+SC11482 ==> RAMDAC "sc11482"
+SC11483 ==> RAMDAC "sc11483"
+SC11484 ==> RAMDAC "sc11484"
+
+SC11485 ==> RAMDAC "sc11485"
+SC11487 ==> RAMDAC "sc11487"
+SC11489 ==> RAMDAC "sc11489"
+
+SC15025 ==> RAMDAC "sc15025"
+
+STG1700 ==> RAMDAC "stg1700"
+
+STG1703 ==> RAMDAC "stg1703"
+
+TI3020 ==> RAMDAC "ti3020"
+
+TI3025 ==> RAMDAC "ti3025"
+
+TI3026 ==> RAMDAC "ti3026"
+
+None of the above ==> RAMDAC "normal"
+</verb></tscreen>
+
+If you feel adventurous you could also open up your computer and have
+a peek at your RAMDAC. The RAMDAC is usually one of the larger chips
+(second or third largest chip that is NOT an EPROM) on the board. The
+markings on it are usually
+
+<tscreen><verb>
+ <Company logo>
+
+ <company identifier><part number>-<speed grade>
+ <manufacturing week><manufacturing year>
+ <lot number><other funny numbers>
+</verb></tscreen>
+
+For example:
+
+<tscreen><verb>
+ @@
+ @@ AT&amp;T
+
+ ATT20C490-11
+ 9339S ES
+ 9869874
+</verb></tscreen>
+
+This is an AT&amp;T 20C490 with a speed grade of 110 MHz. This would then mean
+that you put a `<tt/DacSpeed 110/' line in your <tt/XF86Config/ file. Be
+advised that some RAMDACs have different modes that have different
+limits. The manufacturer will always mark the chip naming the higher
+limits, so you should be careful. The S3 server knows how to handle
+the limits for most of the RAMDACs it supports providing the DacSpeed
+is specified correctly.
+
+
+Chips labeled <bf/-80/ or <bf/-8/ should use `<tt/DacSpeed 80/' in
+the device section.
+<tscreen><verb>
+S3 86C716-ME SDAC ==> DacSpeed 110
+SC15025-8 ==> DacSpeed 80
+ATT20C490-80 ==> DacSpeed 80
+
+IBM 8190429 ==> DacSpeed 170
+IBM 03H5428 ==> DacSpeed 170
+IBM 03H6447 ==> DacSpeed 170
+IBM 03H6448 ==> DacSpeed 220
+IBM 03H5319 ==> DacSpeed 220
+IBM 63G9902 ==> DacSpeed 250
+
+IBM 37RGB514CF17 ==> DacSpeed 170
+IBM 37RGB524CF22 ==> DacSpeed 220
+ ^^
+</verb></tscreen>
+
+<sect> Additional Notes
+<p>
+Note that the Sierra SC1148{5,7,9} will not be distinguished from the
+Sierra SC1148{2,3,4} by the probe. The only difference between the
+two series as far as the server is concerned is that the {2,3,4} is
+capable of 15bpp, while the {5,7,9} is capable of 16bpp. So if you
+have a SC1148{5,7,9} and want to use 16bpp instead of 15bpp, you will
+have to specify a <tt>RAMDAC "sc11485"</tt> line as shown above.
+
+Some RAMDACs (like the Ti3025) require some mode timing consideration
+for their hardware cursor to work correctly. The Ti3025 requires that
+the mode have a back porch of at least 80 pixel-clock cycles. A
+symptom of this not being correct is the HW cursor being chopped off
+when positioned close to the right edge of the screen.
+
+
+<sect> Reference clock value for IBM RGB 5xx RAMDACs
+<p>
+
+Cards with IBM RGB5xx RAMDACs use several different input frequencies
+for the clock synthesizer which can't be probed without some knowledge
+of the text mode clocks (which may be a wrong assumption if you're using
+non-standard text modes). Here is the procedure you should use to
+find out the input frequency:
+
+First run
+
+<tscreen><verb>
+ X -probeonly >& outfile
+</verb></tscreen>
+
+and check the output for the probed clock chip which might look like this:
+
+<tscreen><verb>
+(--) S3: Using IBM RGB52x programmable clock (MCLK 66.000 MHz)
+(--) S3: with refclock 16.000 MHz (probed 15.952 & 16.041)
+ ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
+</verb></tscreen>
+
+there will be a "good guessed" value which will be used
+and two probed values in brackets based on the 25MHz and 28MHz
+text clocks. This probing can only work if you run a normal 80x25
+or 80x28 text mode!
+
+The refclock values known so far are:
+
+<verb>
+ STB Velocity 64 24 Mhz
+ Genoa VideoBlitz II AV 50 MHz
+ Hercules S3 964 50 MHz
+ Hercules S3 968 16 MHz
+ #9 Motion 771 16 MHz
+</verb>
+
+depending on the quartz on your card and maybe other features like
+an additional clock chip on the Genoa card (which as a 14.3MHz quartz).
+
+If you claim that your card has a 16MHz clock, but it really uses 50MHz,
+all pixel clocks will be tripled and a 640x480 mode with 25MHz will
+use a 75MHz pixel clock, so be very careful.
+
+If you found the right refclock, you should set it in the config file
+(device section) e.g. with
+
+ <tscreen><verb>
+ s3RefClk 16
+ </verb></tscreen>
+or
+ <tscreen><verb>
+ s3RefClk 50
+ </verb></tscreen>
+
+so that that this value will be used even if you use another text
+mode and probing fails!
+
+
+<sect>Hints for LCD configuration (S3 Aurora64V+)
+<p>
+If LCD is active the CRT will always output 1024x768 (or whatever is
+the _physical_ LCD size) and smaller modes are zoomed to fit on the LCD
+unless you specify Option "lcd_center" in the device section.
+
+The pixel clock for this physical size (e.g. 1024x768) mode...
+<itemize>
+<item>...can explicitly set in the config file (device section) with e.g. `Set_LCDClk 70'
+(resulting 70 MHz pixel clock being used for all modes when LCD is on)
+<item>...is taken from the _first_ mode in the modes line iff this mode's display size
+is the same as the physical LCD size
+<item>...the default LCD pixel clock of BIOS initialisation setup is used.
+This value is output at server startup in the line `LCD size ...'
+unless you're specifying a value using `Set_LCDClk ...'
+</itemize>
+
+If LCD is _not_ active, the normal mode lines and pixel clocks
+are used for the VGA output.
+
+Whenever you switch output sources with Fn-F5,
+the Xserver won't get informed and pixel clock and other settings are wrong.
+Because of this you have to switch modes _after_ switch output sources!
+Then the server will check which outputs are active and select the correct
+clocks etc.
+So the recommended key sequence to switch output is
+
+ Fn-F5 Ctrl-Alt-Plus Ctrl-Alt-Minus
+
+and everything should be ok..
+
+on the Toshiba keypad you can first hold down Ctrl-Alt, then press `Fn' additionally
+before pressing Plus/Minus too to avoid to explicitly enable/disable
+the numeric keypad for mode switching.
+
+
+<sect> How to avoid ``snowing'' display while performing graphics operations
+<p>
+
+For cards with the S3 Vision864 chip, there is an automatic correction which
+depends on the pixel clock and the memory clock MCLK at which the S3 chip
+operates. For most clock chips this value can't be read (only the S3 SDAC
+allows reading the MCLK value so far), so this value has to be estimated
+and specified by the user (the default is 60 &lsqb;MHz&rsqb;).
+
+With the new `<tt/s3MCLK/' entry for your <tt/XF86Config/ file, now you can
+specify e.g.
+
+ <tscreen><verb>
+ s3MCLK 55
+ </verb></tscreen>
+
+for a 55 MHz MCLK which will reduce snowing. Smaller MCLK values will reduce
+performance a bit so you shouldn't use a too low value (55 or 50 should be a
+good guess in most cases).
+
+Below is a small shell script which might be useful to determine the
+approximate value for MCLK (about +/- 1-2 MHz error). Before running
+this script you have to add the line
+
+ <tscreen><verb>
+ s3MNadjust -31 255
+ </verb></tscreen>
+
+to the device section in your <tt/XF86Config/ file and restart X Windows.
+With this option (which is for testing and debugging only) you'll get
+lots of disastrous display flickering and snowing, so it should be removed
+again immediately after running the test script below.
+
+Running this script will use xbench and/or x11perf to run a test to determine
+the MLCK value, which is printed in MHz. Up to 4 tests are run, so you'll
+get up to 4 estimates (where the first might be the most accurate one).
+
+<code>
+#!/bin/sh
+
+exec 2> /dev/null
+
+scale=2
+
+calc() {
+ m=`awk 'BEGIN{printf "%.'$scale'f\n",'"( $1 + $2 ) / $3; exit}" `
+ [ -z "$m" ] && m=` echo "scale=$scale; ( $1 + $2 ) / $3" | bc `
+ [ -z "$m" ] && m=` echo "$scale $1 $2 + $3 / pq" | dc `
+ echo $m
+}
+
+run_xbench() {
+ r=` ( echo 1; echo 2; echo 3; echo 4 ) | xbench -only $1 | grep rate `
+ [ -z "$r" ] && return
+ cp="$2 $3"
+ set $r
+ calc $3 $cp
+}
+
+run_x11perf() {
+ r=` x11perf $1 | grep trep | tr '(/)' ' ' `
+ [ -z "$r" ] && return
+ cp="$2 $3"
+ set $r
+ calc `calc 1000 0 $4` $cp
+}
+
+run_x11perf "-rect500 -rop GXxor" 3.86 5.53 # 0 1 # 4.11 5.52 #
+run_xbench invrects500 4.63 5.48 # 0 1 # 4.69 5.48 #
+
+run_x11perf "-rect500 -rop GXcopy" -16.42 13.90 # 0 1 # -14.99 13.88 #
+run_xbench fillrects500 -7.81 13.57 # 0 1 # -8.53 13.58 #
+
+exit
+</code>
+
+<sect>New S3 SVGA driver<p>
+ There is a new experimental S3 driver for
+non-ViRGE S3 chipsets in the XF86_SVGA server. This is definitely
+an ALPHA quality driver and hasn't been well tested, and has some known
+problems.
+Because of this, the configuration programs will install XF86_S3 by
+default rather than this one. But if you're adventurous or had some
+problems with XF86_S3, you might want to give it a try.
+
+ The driver includes generic S3 support which should work on
+all non-ViRGE S3 chips (in theory, that is). It also has improved
+support for chips that support S3's new style memory mapped I/O.
+These chips include the 868, 968 and recent Trio64 variants (not
+the plain old Trio64s). Chips that are capable of using the new
+style MMIO will use it automatically. The option "NO_MMIO" can
+be used to turn this off.
+
+ Performance for chips using the new style MMIO is expected
+to be better than XF86_S3, especially on a PCI bus. Performance
+without MMIO, however, is expected to be roughly comparable
+to XF86_S3 (faster in some areas, slower in others).
+
+ All color depths achievable with XF86_S3 should be possible
+with these drivers. Additionally, packed 24 bpp "sort of" works
+for the 868 and 968. Your results may vary.
+
+ Nearly all the options and features supported by XF86_S3
+are supported by this driver. Additionally, the standard XAA/SVGA
+server options such as NO_ACCEL, SW_CURSOR, and NO_PIXMAP_CACHE are
+also supported. XF86_S3 features which are NOT supported in this
+driver are DPMS support and gamma correction.
+
+ The driver supports the PCI_RETRY option when using MMIO and
+a PCI card. This option can give large performance boosts for
+some operations, but has a tendency to hog the bus. Because
+of this, the option is not set by default. Most hardware
+combinations may not have any problems using this option, but
+sound card glitches during intensive graphics operations have
+been reported on some.
+
+ One shortcoming worth noting is that this driver does not yet
+contain the work-around for some S3 PCI BIOSs that report
+their memory usage incorrectly. This can result in conflicting
+address spaces. If this is the case on your hardware you should
+run XF86_S3 once and write down the address that your card is
+relocated to (as printed out in the server output). Then you can
+force the server to use this address with the MemBase field in the
+XF86Config (see the man page on XF86Config).
+
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/S3.sgml,v 3.38 1999/08/23 06:38:52 dawes Exp $
+
+
+
+
+
+$XConsortium: S3.sgml /main/14 1996/02/21 17:45:58 kaleb $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/SCO.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/SCO.sgml
new file mode 100644
index 000000000..2d14972ba
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/SCO.sgml
@@ -0,0 +1,535 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+<article>
+
+<!-- TitleS information -->
+
+<title>Information for SCO Users
+<author>J. Kean Johnston (hug@netcom.com)
+<date>30 November 1996
+
+
+<!-- Table of contents -->
+<toc>
+
+<!-- Begin the document -->
+
+<sect>Binary Distribution<p>
+
+The following files are provided in the binary distribution:
+<quote>
+<descrip>
+<tag/README.SCO/ This file.
+<tag/gunzip.Z/ The GNU <tt>uncompress</tt> utility.
+
+<tag/*X312Xdoc.tgz/ The XFree86 specific documentation.
+
+<tag/X312Mono.tgz/ The Mono server
+<tag/X312VG16.tgz/ The 16 colour VGA server
+<tag/X312SVGA.tgz/ The Super VGA server
+<tag/X312S3.tgz/ The S3 server
+<tag/X3128514.tgz/ The 8514 server
+<tag/X312AGX.tgz/ The AGX server
+<tag/X312Mc32.tgz/ The Mach 32 server
+<tag/X312Mc64.tgz/ The Mach 64 server
+<tag/X312Mc8.tgz/ The Mach 8 server
+<tag/X312P9k.tgz/ The P9000 server
+<tag/*X312cfg.tgz/ The local configuration files for
+<tt>xdm/fs/xinit</tt>.
+<tag/*X312bin.tgz/ The <tt>bin</tt> directory, contains most executables.
+<tag/*X312lib.tgz/ The shared and unshared libraries.
+<tag/*X312fnt1.tgz/ <tt>75dpi</tt> and <tt>misc</tt> fonts.
+<tag/X312fnt2.tgz/ <tt>100dpi</tt> and <tt>Speedo</tt> fonts.
+<tag/*X312inc.tgz/ The X11 include files.
+<tag/X312man.tgz/ The formatted man pages.
+<tag/X312lkit.tgz/ The server link kit (all drivers + PEX).
+<tag/X312util.tgz/ Lots of PD utilities provided as is.
+<tag/X312pex.tgz/ All files relating to PEX including libraries
+ and header files. The LinkKit is required to
+ obtain servers capable of running PEX.
+</descrip></quote>
+
+To obtain a minimum XFree86 installation you will require the archives
+marked with a `*' above, the server binary best suited to your machine
+and optionally "<tt>gunzip.Z</tt>". All the files are compressed
+with "<tt>gzip</tt>" except
+of course "<tt>gunzip.Z</tt>" which is compressed using the
+conventional <tt>compress</tt>
+program.<p>
+
+To install the XFree86 binaries just follow these steps.
+<enum>
+<item>Obtain the files you require.<p>
+ The rest of this procedure must be done as root. If you do not run
+ the extraction as root the permissions on the files will not be
+ correct. For example, the `X' server is s-bit root and will not
+ function correctly if extracted as an ordinary user. <p>
+<item>create a directory <tt>/usr/X11R6</tt>, permissions <tt>755</tt>
+ should do nicely.
+<item>cd <tt>/usr/X11R6</tt>
+<item>extract the archives, for example:
+<verb>
+ gunzip < X312bin.tgz | tar xvpf -
+</verb>
+<item>if you have installed man pages see the later section on
+ setting up man pages.
+<item>Look through <tt>/usr/X11R6/lib/X11/doc/INSTALL</tt>,
+ especially section 2
+ on configuring and using XFree86. This should allow you to get
+ a server up and running. Before starting the server check in
+ the later section <ref id="sec-runxf86" name="Before Running XFree86">,
+ in this document, to
+ see if there are any system requirements you have to make for the
+ server to operate correctly.
+</enum>
+
+<sect>Source Distribution<p>
+
+The SCO port comes as part of the standard XFree86 distribution. Consult
+the XFree86 <tt>README</tt> for more information on the location of sources.
+
+Please note that as of XFree86 3.2, Only SCO Open Server Release 5 and
+onwards are supported. If you are using a previous version of SCO UNIX
+and you want to use XFree86, use the 3.1 series, or be prepared for build
+failures.
+
+For people who want and need to look around the source, there
+are now two files in ``<tt>xc/config/cf</tt>''. Firstly, ``<tt>sco.cf</tt>'' is
+the old original SCO configuration file, and ``<tt>sco5.cf</tt>'', which is
+the currently used configuration file.
+
+<sect>Before Running XFree86<p><label id="sec-runxf86">
+
+The SCO <tt/xterm/ terminfo description is not compatible with the <tt/xterm/
+in the R5 distribution.<p>
+
+To use a Bus/Keyboard or PS2 mouse you should configure the mouse drivers
+under SCO as above using '<tt>mkdev mouse</tt>'. You may then use the
+<tt>OsMouse</tt> option
+in your XF86Config to specify that XFree86 should use the SCO mouse drivers.
+To do this, set the <tt>Protocol</tt> to "<tt>OsMouse</tt>" in the
+Pointer section of your
+XF86Config file. You can also use "<tt>OsMouse</tt>" for your
+serial mouse,
+especially if you are having trouble getting your mouse to work using the
+XFree86 mouse drivers.<p>
+
+If you do not have the SCO TCP/IP package installed do not panic.
+XFree86 will work fine without TCP/IP but you will most likely have to do
+some or all of these things:
+<itemize>
+ <item>Do not worry about errors from the X server complaining about
+ ``/dev/socksys''. The X server is configured to run on systems with
+ and without TCP/IP. This error is just pointing out that you do
+ not have TCP/IP and that this method of connecting to the server
+ has been disabled.
+
+ <item>Do worry about errors involving ``/dev/spx'' or the ``sco''
+ connection
+ type. This means something is wrong with the streams pipes that
+ are used for connections on the local machine. First be sure that
+ your server has the ``s-bit'' set. You can do this by running this
+ command for the X server you are using:
+
+ ls -al /usr/X11R6/bin/XF86_XXXXXX
+
+ The output should contain the `s' character instead of the `x'
+ character. For example:
+ <quote><verb>
+-rwsr-xr-x 1 root bin 1074060 Jul 24 11:54 XF86_S3
+ </verb></quote>
+ is correct while:
+ <quote><verb>
+-rwxr-xr-x 1 root bin 1074060 Jul 24 11:54 XF86_S3
+ </verb></quote>
+ is not.
+
+ <item>you may have to install streams into the kernel with
+ ``mkdev streams''
+ Check the SCO Manuals for more information on this.
+
+ <item>you may have to configure some devices in /dev, check in the
+ "Trouble Shooting" section of this document for the entry which
+ comments on ``/dev/spx'' and ``Xsco''.
+
+ <item>Your streams resources may be configured too low. You should check
+ your streams parameters against the following values, if the are
+ higher then you do not need to changes them. To check these
+ values, login as root, change directory to ``/etc/conf/cf.d'' and
+ then run ``./configure''.
+
+ Once you are running configure, choose the ``Streams Data'' option
+ and step through the entries. Just press &lt;ENTER&gt; at each prompt
+ unless you want to change a value. The values to look for, and
+ their minimum values, are:
+
+ <quote><verb>
+ NSTREAM 128
+ NQUEUE 512
+ NBLK4096 4
+ NBLK2048 32
+ NBLK1024 32
+ NBLK512 32
+ NBLK256 64
+ NBLK128 256
+ NBLK64 256
+ NBLK16 256
+ NBLK4 128
+ NUMSP 128
+ </verb></quote>
+
+ You will not normally need to change any of these, if however you
+ do have to change some, configure will confirm that you want to
+ save the changes before exiting, and will give you further
+ instructions on rebuilding the unix kernel.
+</itemize>
+
+<sect>Switching Consoles<p>
+
+XFree86 uses similar console switching keys as the SCO R4 and R5
+servers. That is, <tt>Ctrl-PrntScr</tt> takes you to the next console along
+from the one X is running on. If this is the last console it will take
+you to console 1. <tt>Ctrl-Alt-FXX</tt>, where <tt>XX</tt> is a function
+key between <tt>F1</tt> and <tt>F12</tt> will switch you to the console
+number assigned to that function key. <tt>F1</tt> corresponds to
+<tt>tty01</tt> (or console 1), <tt>F2</tt> corresponds to <tt>tty02</tt>
+(or console 2) etc. Those interested in modifying the console switching
+should look in <tt>xc/programs/Xserver/hw/xfree86/common/xf86Events.c</tt>.
+
+<sect>Setting up Man Pages<p>
+
+After compiling the tree, or after installing the binary distribution you
+can get man to recognise the XFree86 man pages by adding
+<tt>/usr/X11R6/man</tt> to
+the <tt>MANPATH</tt> in <tt>/etc/default/man</tt>, the line should
+look similar to:
+<tscreen><verb>
+ MANPATH=/usr/man:/usr/X11R6/man
+</verb></tscreen>
+This allows all users to view the X man pages. You may change your own
+<tt>MANPATH</tt> environment variable if you do not want everyone to access the
+man pages.<p>
+
+By default the man pages are compressed using ``<tt>compress</tt>'' to
+conserve space. If you do not want to compress the man pages change
+<tt>CompressManPages</tt> to <tt>NO</tt> in your ``<tt>xf86site.def</tt>''
+file. Those using the binary distribution can use ``<tt>uncompress</tt>''
+to uncompress the man pages.
+
+<sect>Using SCO binaries/servers.<p>
+
+XFree86 will accept connections from SCO binaries (R3 upwards) and the
+SCO R5 server will also accept connections from XFree86 binaries. This
+means you may mix and match the two if you have ODT. For example you may
+still use the Motif window manager (mwm) if you prefer.
+
+<sect>Compiling XFree86 under Open Server 5<p>
+
+As of GCC version 2.8.0, Open Server is supported. Configure it by
+using the following:
+<tscreen><verb>
+ ./configure i486-sco3.2v5.0
+</verb></tscreen><p>
+
+There is no reason to modify gcc in any way. It compiles cleanly on
+Open Server 5.<p>
+
+SCO Open Server 5.0 is recognised automatically by XFree86. You do not
+need to specify any <tt>BOOTSTRAPCFLAGS</tt> parameters when doing a
+<tt>make World</tt>. You can ignore the warning message about
+<tt>BOOTSTRAPCFLAGS</tt> at the very beginning of a <tt>make World</tt>.
+
+<enum>
+<item>Fine tune ``<tt>site.def/xf86site.def</tt>''<p>
+Use GCC if you can. XFree should compile with the DevSys cc, but GCC has
+better optimizations, and is guaranteed to work.
+
+<item>SCO Open Server comes with Visual
+TCL, which is an old (and incompatible) version of TCL. If you want to
+use XF86Setup you will have to compile Tcl and Tk yourself. Both are
+supported well on SCO Open Server 5. Tcl 7.6 and Tk 4.2 are available
+from <tt>ftp://ftp.smli.com/pub/tcl</tt>.
+
+<item>You may want to disable dynamic loading support. Several users have
+reported trouble with this. XIE and PEX5 definitely do not work. If
+you want to experiment, try enabling this. Please report successes or
+failures to me.
+
+<item>Do <bf>not</bf> enable the <tt>HasSVR3mmapDrv</tt> as you may have done
+in older versions of SCO. Open Server 5 has full mmap() support, and
+this is used for direct frame buffer access.
+
+<item>If you know you will not ever be using COFF binaries, and you are
+short of space, set <tt>ForceNormalLib</tt> to <tt>NO</tt>. Doing this
+will cause only the ELF versions of the libraries to be built.
+``<tt>sco5.cf</tt>'' sets this to <tt>YES</tt> by default, so you must
+explicitly set it to <tt>NO</tt> in ``<tt>xf86site.def</tt>''.
+All binaries are compiled in ELF mode to reduce space.
+
+</enum>
+
+<sect>Relevant Documentation<p>
+
+Some relevant documentation for SCO Users and Developers can be found in
+the following files.
+<descrip>
+<tag/README/
+the standard XFree86 <tt>README</tt> (<tt>/usr/X11R6/lib/X11/doc</tt>)
+<tag/README.SVR3/ Although a lot of this readme is based on Interactive
+ a substantial proportion is still relevant.
+<tag>All of the VGA/Config documentation.</tag>
+ <tt>/usr/X11R6/lib/X11/doc/VideoModes.doc</tt> and the <tt>README</tt>
+ files for particular video cards.
+</descrip>
+
+<sect>Known Problems<p>
+<itemize>
+<item>After running the server you may see some strange characters in your
+input to the shell. This is due to some unprocessed scancodes and is
+of no concern. This will be fixed in a future release.<p>
+<item>Not all of the applications in <tt>/usr/X11R6/bin</tt> have
+been debugged.<p>
+</itemize>
+
+<sect>Trouble Shooting<p>
+<descrip>
+<tag/Problem:/
+<quote>
+ The server does not start up, and I cannot tell what is going
+ wrong as it did not print any error messages.
+</quote>
+<tag/Causes:/
+<quote>
+ There can be any number of causes why the server doesn't start.
+ The first step is to find out what the server has to say. To do
+ this we have to catch the error output of the server into a file.
+ This output contains a log of what the server is finding/doing as
+ it starts up. To get this output run:
+ <verb>
+ startx 2> /tmp/errs
+ </verb>
+ The output of the server will now be in "/tmp/errs". You should
+ look through this output for possible problems, and then check
+ here in this document for any references to the problems you are
+ seeing.
+</quote>
+<tag/Problem:/
+<quote>
+ The server starts up, the screen goes blank, and I never see
+ anything else. It appears that my machine has hung.
+</quote>
+<tag/Causes:/
+<quote>
+ Again this can have many causes. Most likely your XF86Config is
+ wrong. You should be able to kill the server by typing
+ Ctrl-Alt-BackSpace, if it is still running. If this does not
+ restore your display then you may have to drive your system blind.
+ Always keep another login running at the shell prompt so that you
+ may switch to that screen and run commands even if you cannot see
+ anything on the screen. Try these things, usually in the order
+ given:
+ <itemize>
+ <item>log out of the login where you started ``X'' and then
+ change consoles. This will cause the SCO screen
+ switching code to try to reset the card.
+ <item>run ``vidi v80x25'', this command will also try to set
+ your card into a viewable mode.
+ <item>shutdown the machine cleanly with ``shutdown'' and try
+ again.
+ </itemize>
+ When first trying to get XFree86 to run, be sure to use a simple
+ setup. Get 640x480 working first then move on to higher
+ resolutions. Always trap the output of the server as shown earlier.
+ Once you have the valid clocks for your video card (as provided
+ in the server output), hard code them into your XF86Config as
+ this will take some strain off your monitor during XFree86
+ startup where it usually probes the various clock frequencies.
+ Getting the ``X'' screen to appear can be a painfully slow task.
+ Be patient and read as much of the doco as you can handle. You
+ will get it to work.
+</quote>
+<tag/Problem:/
+<quote>
+<verb>
+ Fatal server error:
+ xf86MapVidMem:No class map defined for (XXXXX,XXXXX)
+</verb>
+</quote>
+<tag/Causes:/
+<quote>
+<enum>
+ <item>Your system does not have the correct
+ /etc/conf/pack.d/cn/class.h, You can confirm this by
+ editing the file and looking for the string "SVGA", if it
+ is not there then you should re-install this file from
+ the "Extended Utilities" diskettes provided with your OS.
+ If this is not possible then installing the "dmmap"
+ driver from the distribution may allow the server to
+ operate correctly.
+
+</enum>
+</quote>
+<tag/Problem:/
+<quote>
+ <tt>xf86install</tt> does not work.
+</quote>
+<tag/Causes:/
+<quote>
+ You should not be running <tt>xf86install</tt> when using the
+ XFree86 server
+ under SCO. It is used for Interactive (ISC) installations.
+</quote>
+<tag/Problem:/
+<quote>
+ The server starts but the screen is not aligned correctly or is shaky
+ and impossible to view.
+</quote>
+<tag/Causes:/
+<quote>
+ This is most likely due to an incorrect <tt>XF86Config</tt> setup.
+ Look for the
+ files <tt>README.Config</tt> <tt>VideoModes.doc</tt> (in
+ <tt>/usr/X11R6/lib/X11/doc</tt> with
+ the binary distribution). These files explains how to fix up your
+ video modes.
+</quote>
+<tag/Problem:/
+<enum>
+<item>Can only run a limited number of xterms.
+<item><tt>xterm</tt> does not work but other programs like
+<tt>xclock</tt> do work.
+</enum>
+
+<tag/Causes:/
+<quote>
+ Not enough or no pseudo ttys devices are present on your system.
+ Run "<tt>mkdev ptty</tt>" and increase the number of ptty's.
+</quote>
+<tag/Problem:/
+<quote>
+ When running curses/termcap applications in an <tt>xterm</tt>
+ the output gets
+ corrupted especially when scrolling.
+</quote>
+<tag/Causes:/
+<enum>
+<item>You are running an original 1.3 distribution of XFree86. Update
+ to the latest version (3.2 or greater).
+<item>You have resized the window and not ran "<tt>eval `resize`</tt>"
+ before using
+ your application. The SCO operating system does not support dynamic
+ resizing of xterms fully so this command must be run after resizing
+ an <tt>xterm</tt> in order for curses/termcap applications to operate
+ correctly.
+</enum>
+<tag/Problem:/
+<enum>
+<item>When starting X it dies with an error "Cannot access a needed shared
+ library".
+<item>When starting an X application is dies with the above error.
+</enum>
+<tag/Causes:/
+<enum>
+<item>You do not have the binaries installed in the correct directory.
+ Check that they are in <tt>/usr/X11R6</tt>
+<item>You have upgraded to a new binary distribution which has a new
+ version of the shared libraries which are not compatible with your
+ old binaries. To fix this you will need to re-install the old
+ shared libraries or recompile your application against the new
+ libraries.
+</enum>
+<tag/Problem:/
+<quote>
+ When linking against the SCO motif library I get an unresolved external
+ for "<tt>XtDisplayStringConversionWarning</tt>" when using gcc.
+</quote>
+<tag/Causes:/
+<quote>
+ The SCO library is compiled with limited length identifiers. To work
+ around this add the following code to your application when compiling
+ under XFree86 with gcc and SCO motif.
+<verb>
+ #ifdef SCO
+ void XtDisplayStringConversionWarnin(dpy, from, toType)
+ Display* dpy;
+ String from;
+ String toType;
+ { XtDisplayStringConversionWarning(dpy, from, toType); }
+ #endif
+</verb></quote>
+<tag/Problem:/
+<quote>
+ The server fails to run and prints out a line similar to:<p>
+<tt>XFree86: Cannot open /dev/spx for ???? listener: No such file or directory
+</tt></quote>
+<tag/Causes:/
+<quote>
+ All SCO unix installations appear to have the Streams pseudo tty driver
+ installed, but not all the devices are present.<p>
+<enum>
+<item>there should be a <tt>/etc/conf/pack.d/sp</tt> directory,
+<item><tt>/etc/conf/sdevice.d/sp</tt> should have a '<tt>Y</tt>' in it.
+<item>You need a file in <tt>/etc/conf/node.d</tt>
+ which contains something like:
+<verb>
+ clone spx c sp
+ sp X0S c 127
+ sp X0R c 126
+ sp X1S c 125
+ sp X1R c 124
+ sp X2S c 123
+ sp X2R c 122
+ sp X3S c 121
+ sp X3R c 120
+ sp X4S c 119
+ sp X4R c 118
+ sp X5S c 117
+ sp X5R c 116
+ sp X6S c 115
+ sp X6R c 114
+ sp X7S c 113
+ sp X7R c 112
+</verb>
+</enum>
+ if you don't have something like this (maybe called "Xsco") then create
+ one and that should fix your problem. As far as I can tell the streams
+ pseudo tty driver should be there.<p>
+ The simplest way to get the devices if you had to create this file is
+ to rebuild the kernel and the environment. If you don't want to do this
+ then:
+<verb>
+ touch /etc/.new_unix
+ cd /etc/conf/bin
+ ./idmkenv
+ </verb>
+ and try it out.
+</quote>
+</descrip>
+<sect>Acknowledgements<p>
+
+Thanks to the Core team for their previous and continuing help with the SCO
+work. Many thanks to <bf/Stacey Campbell/ at SCO for all the advice and
+insights provided. Thanks to SCO in general for making information available
+for XFree86 development.
+
+Thanks also to <bf/Peter Eubert/ (<em/peter.eubert@iwb.mw.tu-muenchen.dbp.de/)
+and <bf/Kent Hamilton/ (<em/kenth@stl.scscom.COM/) for
+input on compiling under 3.2.4
+systems. <bf/Larry Plona/ (<em/faxi@world.std.com/) and
+<bf/Didier Poirot/ (<em/dp@chorus.fr/)
+for their input on xdm and 3.2.4 compilation under 3.1. And of course the
+beta list for its input on everything.
+
+Special thanks to <bf/Jerry Whelan/ (<em/guru@stasi.bradley.edu/)
+for providing an
+ftp site for the binary distribution.
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/SCO.sgml,v 3.17 1997/12/05 22:01:38 hohndel Exp $
+
+
+
+
+
+$XConsortium: SCO.sgml /main/11 1996/10/23 11:45:55 kaleb $
+</verb>
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/SOLX86.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/SOLX86.sgml
new file mode 100644
index 000000000..270c3030e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/SOLX86.sgml
@@ -0,0 +1,327 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+<article>
+
+<!-- Title information -->
+
+<title>Information for Solaris for x86 Users
+<author>David Holland
+<date>25 Feb 1998
+
+<!-- Table of contents -->
+<toc>
+
+<!-- Begin the document -->
+
+
+<!--Contents
+--------
+
+ 1) What is XFree86
+ 2) Solaris versions on which XFree86 has been tested.
+ 3) The VT-switching sub-system in Solaris x86
+ 4) Various notes for building XFree86 on Solaris x86
+ 5) Known bugs, and work arounds.
+ -->
+
+
+<sect>What is XFree86<p>
+
+ XFree86 is a port of X11R6.3 that supports several versions of
+ Intel-based Unix. It is derived from X386 1.2 which was the X server
+ distributed with X11R5. This release consists of many new features
+ and
+ performance improvements as well as many bug fixes. The release is
+ available as source patches against the X Consortium code, as well as
+ binary distributions for many architectures.
+<p>
+The sources for XFree86 are available by anonymous ftp from:
+<quote>
+ <htmlurl name="ftp://ftp.XFree86.org/pub/XFree86/current"
+ url="ftp://ftp.XFree86.org/pub/XFree86/current">
+</quote>
+Solaris binaries for XFree86 are available for anonymous ftp from:
+<quote>
+ <htmlurl name="ftp://ftp.XFree86.org/pub/XFree86/current/binaries/Solaris"
+ url="ftp://ftp.XFree86.org/pub/XFree86/current/binaries/Solaris"><p>
+</quote>
+
+<sect> Solaris for x86, versions on which XFree86 3.3.3 has been tested<p>
+
+XFree86 3.3.2 has been actively tested on:
+<itemize>
+<item>Solaris 2.5.1 for x86
+<item>Solaris 2.6 for x86
+</itemize>
+
+<sect>The VT-switching sub-system in Solaris x86<p>
+
+ The virtual terminal sub-system is a undocumented, and unsupported
+ feature of Solaris x86. Therefore if you use Virtual Terminals, you
+ do so at <bf>YOUR OWN RISK</bf>.<p>
+
+ The virtual terminals of Solaris work basically the same way as
+ most other Intel based SVR4 VT sub-systems. However, there are a
+ number of limitations documented below.<p>
+
+ First, if you are running a Solaris 2.4 x86 system, and you want VT's,
+ you will have to create the necessary devices first, so become root.<p>
+
+ First verify the chanmux device driver's major number is 100:<p>
+<tscreen><verb>
+ # grep -i chanmux /etc/name_to_major
+ chanmux 100
+ #
+</verb></tscreen>
+ If the number after 'chanmux' is anything but 100, I would suggest
+ you immediately abort your attempt to create virtual terminals, and
+ learn to live without them.<p>
+
+ However, if it is 100, then as root type the following commands to
+ create the maximum allowable number of virtual terminals.<p>
+<tscreen><verb>
+ # cd /dev
+ # mknod vt01 c 100 1
+ # mknod vt02 c 100 2
+ # mknod vt03 c 100 3
+ # mknod vt04 c 100 4
+ # mknod vt05 c 100 5
+ # mknod vt06 c 100 6
+ # mknod vt07 c 100 7
+</verb></tscreen>
+ There is no need for a reconfiguration boot.<p>
+
+ Secondly, for both 2.1, and 2.4 x86 systems, add a few lines to the
+ <tt/inittab/ to enable logins on them.<p>
+
+(<bf>Note</bf>, do <bf>NOT</bf> make a mistake here, you could
+lock yourself out of the system)<p>
+<verb>
+--------------------->Snip Snip<-----------------------------------------------
+v1:234:respawn:/usr/lib/saf/ttymon -g -h -p "`uname -n` VT01 login: " -T AT386 -d /dev/vt01 -l console
+v2:234:respawn:/usr/lib/saf/ttymon -g -h -p "`uname -n` VT02 login: " -T AT386 -d /dev/vt02 -l console
+v3:234:respawn:/usr/lib/saf/ttymon -g -h -p "`uname -n` VT03 login: " -T AT386 -d /dev/vt03 -l console
+v4:234:respawn:/usr/lib/saf/ttymon -g -h -p "`uname -n` VT04 login: " -T AT386 -d /dev/vt04 -l console
+---------------------->End Here<-----------------------------------------------
+</verb>
+ These four lines enable four VT's on Alt-SysReq-F1 through
+ Alt-SysReq-F4.<p>
+
+ Then execute the command '<tt>init q</tt>' to immediately
+ enable the virtual
+ terminals.<p>
+
+The keys used for VT switching are as follows:<p>
+
+<quote>
+ <tt>Alt-SysReq-F1</tt> through <tt>Alt-SysReq-F7</tt>
+ enable VT screens 1-7 respectively
+ (if the VT is active).<p>
+ <tt>Alt-SysReq-n</tt> enables the next active VT screen.<p>
+ <tt>Alt-SysReq-p</tt> enables the previous active VT screen.<p>
+ <tt>Alt-SysReq-h</tt> returns to the console.<p>
+</quote>
+ If you are using virtual terminals, you must leave at least one free
+ for use by the Xserver.<p>
+
+
+Limitations of the virtual terminal sub-system under Solaris x86:<p>
+
+ There are only a total of 8 available VT's (7 normal VT's + 1 console)
+ not the usual 15. If you have all 8 allocated, and you attempt to
+ allocate a additional VT you will panic the system. (This bug is
+ worked around in the Solaris XFree86 Xserver.)<p>
+
+ From a programming stand point, they work pretty much as documented in
+ the AT&amp;T Unix System V/386 Release 4 Integrated Software
+ Development
+ Guide, however a number of <tt>ioctl()</tt> calls are broken.<p>
+
+
+<sect>Notes for building XFree86 on Solaris x86<p>
+
+<enum>
+<item>The majority of all modifications you will need to make are now in
+ <tt>~xc/config/cf/xf86site.def</tt>.
+
+<!--
+ except one. You will need to set OSName,
+ and OSMinorVersion correctly in <tt>~xc/config/cf/sun.cf</tt>.
+
+Under Solaris 2.1 for x86, <tt>sun.cf</tt> needs to read
+(near the top of the file)
+
+<verb> #ifdef SVR4Architecture
+ #ifdef i386Architecture
+ #define OSName SunOS 5.1 x86
+ XCOMM operating system: OSName
+ #define OSMajorVersion 5
+ #define OSMinorVersion 1
+</verb>
+
+Under Solaris 2.4 for x86, <tt>sun.cf</tt> needs to read
+(near the top of the file)
+
+<verb> #ifdef SVR4Architecture
+ #ifdef i386Architecture
+ #define OSName SunOS 5.4 x86
+ XCOMM operating system: OSName
+ #define OSMajorVersion 5
+ #define OSMinorVersion 4
+</verb>
+-->
+
+<item>Both Gcc, and ProWorks are supported by XFree86. Gcc-2.5.8 or
+ gcc-2.7.2.3 are
+ suggested, Gcc-2.6.0 is known not to work. You also need to set
+ HasGcc2 correctly in <tt>~xc/config/cf/xf86site.def</tt>.
+
+ You should also make certain your version of GCC predefines `sun'.
+ 2.4.5 is known NOT to by default. If needed edit
+ <tt>/usr/local/lib/gcc-lib/*/*/specs</tt>, and modify the
+ <tt>*predefines:</tt> line.<p>
+
+ Note: A Threaded Xlib compiled with GCC has subtle problems.
+ It'll work 98&percnt; of the time, however clients will occasionally
+ exhibit strange hangs. Most notably image viewers such as
+ xv-3.10 exhibit this problem.<p>
+
+ It is recommended that you set ThreadedX in
+ <tt>~xc/config/cf/sun.cf</tt> to NO, if you are using GCC.
+ ProWorks does not have this problem.
+
+<item> To build XFree86 with gcc you need gcc and (optionally)
+ c++filt from GNU binutils. Don't install gas or ld from GNU
+ binutils, use the one provided by Sun.
+ <p>
+ With XFree86 3.3.2, you will need to setup a /opt/SUNWspro/bin
+ directory containing symbolic links named <tt/cc/, <tt/CC/, and
+ <tt/c++filt/ pointing respectively to the actual <tt/gcc/,
+ <tt/g++/ and <tt/c++filt/ commands.
+
+<item>If you don't have c++filt or if you have troubles in making
+ World with c++filt, you need to set UseExportLists to NO in
+ <tt>~xc/config/cf/host.def</tt>.<p>
+
+<!--
+ If you use c++filt, you need to check the definition of PATH in
+ <tt>~xc/config/util/elistgen.sun</tt>.<p>
+-->
+
+<item>If you are using ProWorks to compile the XFree86 distribution, you
+ need to modify your PATH appropriately so the ProWorks tools are
+ available. Normally, they should be in <tt>/opt/SUNWspro/bin</tt><p>
+
+
+<item>You <bf>MUST</bf> put <tt>/usr/ccs/bin</tt>
+ at the front of your PATH. There are known
+ problems with some GNU replacements for the utilities found there. So
+ the <tt>/usr/ccs/bin</tt> versions of these programs
+must be found before any
+ other possible GNU versions. (Most notably GNU '<tt/ar/' does not work
+ during the build).<p>
+
+<item>If you wish to use the "memory aperture" feature of the S3, and Mach32
+ servers, you need to compile, and install the Solaris x86 aperture
+ driver for memory mapped I/O support. This driver is <bf>REQUIRED</bf>
+ for the I128, P9000 and Mach 64 servers.<p>
+
+ You need to set HasSolx86apertureDrv to YES in
+ <tt>~xc/config/cf/xf86site.def</tt>.<p> to enable the aperture
+ driver.
+
+ Under Solaris 2.5 and later, there's a system driver
+ (<tt>/dev/xsvc</tt> that provides this functionality. It will
+ be detected automatically by the server, so you don't need to
+ install the driver.
+
+ For Solaris 2.1 and 2.4, the source for this driver is included in
+ <tt>~xc/programs/Xserver/hw/xfree86/etc/apSolx86.shar</tt>.
+ Building, and
+ installing the driver is relatively straight forward. Please read
+ its accompanying README file.<p>
+
+
+
+</enum>
+<sect> Notes for running XFree86 on Solaris x86<p>
+
+<enum>
+<item>If you have not made the Virtual Terminal devices, you will need to
+ specify the terminal device to run the Xserver on. The correct
+ device is vt00 so your <tt>xinit</tt> command would look like so:<p>
+<tscreen><verb>
+ xinit -- vt00
+</verb></tscreen>
+ If you have made the virtual terminal devices you do not need to
+ specify the VT to run the Xserver on.<p>
+
+ To be able to run XF86Setup, you must at least create
+ /dev/vt01. Otherwise XF86Setup won't start.
+
+<item>For Solaris you will probably want to set your LD_LIBRARY_PATH to
+ <tt>/usr/X11R6/lib:/usr/openwin/lib:/usr/dt/lib</tt>.
+ Including <tt>/usr/X11R6/lib</tt> in your
+ LD_LIBRARY_PATH is probably not necessary, however it doesn't hurt. :)
+<p>
+ Including <tt>/usr/openwin/lib</tt> in the LD_LIBRARY_PATH is
+ recommended
+ because some Sun supplied binaries were not compiled with LD_RUN_PATH
+ set properly at compile time.<p>
+<p>
+ Motif and CDE applications may require <tt>/usr/dt/lib</tt> in your
+ LD_LIBRARY_PATH too.
+
+<item>Xqueue is <bf>NOT</bf> supported under Solaris.
+ The includes necessary for
+ Xqueue are available, however the driver does not seem to be in the
+ kernel. (Go figure)<p>
+
+
+<item>If you want to use xdm with Solaris, extract the files from the shar
+ file in <tt>/usr/X11R6/lib/X11/etc/XdmConf.svr4</tt> into a temporary
+ directory. The <tt>README</tt> file tells where
+ the individual files need to
+ be installed. Be sure to read through each file and make any
+ site-specific changes that you need.<p>
+
+</enum>
+
+<sect> Known bugs, and work arounds with Solaris x86<p>
+
+<enum>
+
+<item>The Solaris 2.1 for x86 OpenWindows filemgr does not work against a
+ X11R5 Xserver, it probably will also not work against a X11R6
+Xserver.
+ Attempting to 'Drag and Drop' a file causes the filemgr to abort
+ with a 'X error'<p>
+
+ Solaris 2.4 does not have this problem.<p>
+
+ There is no known work around.<p>
+
+<!--
+<item>It has been reported that the aperture driver doesn't work
+ under Solaris 2.5.1. It probably doesn't work either under
+ 2.5.
+-->
+
+</enum>
+<sect> Bug Notification<p>
+
+ Bug reports need to be sent to <bf/XFree86@XFree86.org/, or posted to
+ the comp.windows.x.i386unix newsgroup. Questions or comments about
+ the Solaris support, or the Solaris distribution need to be made to
+ <it/davidh@use.com/, or <it/danson@lgc.com./<p>
+
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/SOLX86.sgml,v 3.15 1999/08/23 06:38:52 dawes Exp $
+
+
+
+
+
+$XConsortium: SOLX86.sgml /main/7 1996/10/28 05:43:28 kaleb $
+</verb>
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/SVR4.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/SVR4.sgml
new file mode 100644
index 000000000..42721c574
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/SVR4.sgml
@@ -0,0 +1,451 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+<article>
+
+<!-- Titles information -->
+
+<title>Information for SVR4 Users
+<author>The XFree86 Project, Inc
+<date>27 Feb 1998
+
+<abstract>
+<bf>NOTE:</bf> If you intend to use any of the accelerated servers, read section
+10 and follow the instructions. Otherwise the X server will crash
+when exiting, restarting, or switching VTs.
+</abstract>
+
+<!-- Table of contents -->
+<toc>
+
+<!-- Begin the document -->
+
+<sect>SVR4 versions on which XFree86 has been tested<p>
+ XFree86 has been tested on the following versions of <bf>SVR4.0</bf>:
+<itemize>
+<item>Microport: 2.2, 3.1, 4.1, 4.2
+<item>Esix: 4.0.3A, 4.0.4, 4.0.4.1
+<item>Dell: 2.1, 2.2, 2.2.1
+<item>UHC: 2.0, 3.6
+<item>Consensys: 1.2
+<item>MST: 4.0.3
+<item>AT&amp;T: 2.1, 4.0
+<item>ISC: 4.0.3
+<item>NCR: MP-RAS
+<item>PANIX: 5.0
+</itemize>
+and the following versions of <bf>SVR4.2</bf>:
+<itemize>
+<item>Consensys
+<item>Novell/SCO UnixWare 1.x and 2.0
+</itemize>
+Basically, we believe that XFree86 binaries will run unmodified on any
+ISA, EISA, or MCA platform version version of SVR4.0 (Solaris 2.x is an
+exception), or SVR4.2. If you run XFree86 on another version of SVR4
+that's not in this list, please let us know about it.
+
+<sect>How to cope with VT-switching hotkeys<p>
+ Some versions of SVR4 (Esix and Microport) have mechanisms for enabling
+two-key sequences for VT switching (<tt>Alt-Fn</tt>).
+The standard SVR4 mechanism
+is <tt>Alt-SysReq-Fn</tt>, which all versions we know use.
+Running under X, the
+<tt>Alt-Fn</tt> sequences are stolen by the driver before the
+server can see them,
+so you can't use them for X applications. So you want to switch back to
+the standard 3-key sequences while you are running X. Here's how to do
+it:
+<descrip>
+<tag/Microport/
+ Microport makes this very simple. The 2-key mode is called
+ "Microport Mode", and the 3-key mode is called "Compatible Mode".
+ You enter Microport Mode by pressing <tt>Alt-SysReq-m</tt>. You enter
+ Compatible Mode by pressing <tt>Alt-SysReq-c</tt>. So all you
+ need to do is press <tt>Alt-SysReq-c</tt> after starting the
+ X server to allow X clients access to the
+ <tt>Alt-Fn</tt> sequences.
+<tag/Esix/
+ Esix has no keyboard-driven way to switch modes. There are two
+ levels at which this can be handled:<p>
+<enum>
+ <item>There is a kernel tunable that determines which mode is the
+ default. The tunable is the initialisation of kd_2keysw in
+ <tt>/etc/conf/pack.d/kd/space.c</tt>. When set to 1 (the default),
+ 2-key
+ mode is enabled. When set to 0 it is disabled.<p>
+ <item>The mode can be changed for individual VTs programatically by
+ an ioctl(). To make life easier for XFree86 users, a program
+ called `2key' is provided (in
+ <tt>xc/programs/Xserver/hw/xfree86/etc/</tt>
+ in the source tree, and in
+ <tt>/usr/X11R6/lib/X11/etc/</tt> in the binary
+ kit). You can compile and install this program. Then to make use
+ of it, add the line `<tt>VTInit "2key off"</tt>'
+ to the Keyboard section of
+ your <tt>XF86Config</tt> file to cause the program to be run
+ automatically
+ when the server starts up. Doing this means that 2-key switching
+ will be turned off while in the server's VT, but will still be on
+ for the other VTs.<p>
+</enum>
+ For further details, refer to the keyboard(7) man page included
+ with the release notes (the on-line man page doesn't have this
+ information).
+</descrip>
+
+<sect>Running SVR3 binaries on SVR4.0.4 and SVR4.2<p>
+ SVR4.0.4 added the `Advanced Compatibility Package', which provides
+iBCS-2 compliance for running SVR3 binaries. These facilities are also
+present in SVR4.2. XFree86 makes use of this to accept local connections
+from SVR3 clients. The XFree86 binary distribution is built to use these
+capabilities. You need to install the `Advanced Compatibility Package', if
+you have not done so already.<p>
+We have found that SVR4.0.4 is not able to run all SCO, and perhaps not
+many ISC SVR3 binaries. This is not a failing of XFree86, but of SVR4
+itself. One particular example is that many SVR3 programs are ignorant of
+the UFS filesystem, and attempt to read directories as files, rather than
+using the system call that is defined for the purpose. This will fail for
+obvious reasons. The SVR4.0.4 release notes from USL (which you should
+have gotten from your vendor) have lots of suggestions for how to improve
+compatibility.<p>
+That said, we have had luck with several SCO binaries right out of the
+box. No changes are needed - just go to an xterm window and run the
+program.<p>
+ISC users will need a binary editor before they can attempt to run their
+binaries. ISC, for whatever reason, put the pipe for local connections in
+<tt>/tmp/.X11-unix/Xn</tt>. This unfortunately is the same place as the X
+Consortium X server puts the Unix-domain socket normally used for local
+connections. The XFree86 server was modified to use
+<tt>/dev/X/ISCCONN/Xn</tt> for
+local connections to ISC clients. So what you must do is use a binary
+editor to edit your client program. Search for <tt>/tmp/.X11-unix</tt>,
+and change
+it to <tt>/dev/X/ISCCONN</tt>. Now you just have to worry about base-OS
+compatibility.<p>
+<sect>Notes for building XFree86 on SVR4<p>
+<enum>
+<item>If you are using gcc with SVR4, we highly recommend that you use
+ gcc-2.4.5 (or a later stable release). Version 2.6.0 has some problems
+ on i386 platforms and is not recommended.<p>
+<item>It is recommended that you increase the <tt>UFSNINODE</tt>
+ (for a UFS filesystem)
+ and/or the <tt>S5NINODE</tt> (for an S5 filesystem) kernel parameter
+ to about 650
+ before attempting to build the distribution. See the "Notes for running
+ XFree86 on SVR4" section for some other parameters you may want to
+ change.<p>
+<item>The <tt>BOOTSTRAPCFLAGS</tt> required are:
+<quote>
+ For Unixware: "<tt>-DUSL</tt>"
+
+ For NCR: "<tt>-DNCR</tt>"
+
+ For other SVR4: "<tt>-DSVR4 -Di386</tt>"
+</quote>
+</enum>
+<sect>Notes for running XFree86 on SVR4<p>
+<bf>NOTE:</bf> If you intend to use any of the accelerated servers,
+ read section 10
+ and follow the instructions. Otherwise the X server will crash when
+ exiting, restarting, or switching VTs.
+<enum>
+<item>For SVR4, you may also need to add <tt>/usr/X11R6/lib</tt> to your
+ <tt>LD_LIBRARY_PATH</tt>, but this is not required for running properly
+ built clients.<p>
+<item>You may want to increase some kernel parameters (either by running
+ <tt>idtune</tt>, or editing <tt>/etc/conf/cf.d/stune</tt>, and
+ rebuilding the kernel with <tt>idbuild</tt>):
+<quote>
+ <tt>[HS]FNOLIM </tt>hard/soft limit for number of open files<p>
+ <tt>MAXUP </tt>max number of processes per user<p>
+ <tt>ARG_MAX </tt>max length of an arg list<p>
+ <tt>SHMMAX </tt>max size of shared memory segment(in bytes)<p>
+</quote>
+<item>Choose which mouse driver you will use. For SVR4 the best choice
+ depends on which version you are using. If you have a bus mouse then
+ Xqueue is probably the only option. For a serial mouse the
+ options are as follows:<p>
+<descrip>
+<tag/Esix 4.0.3/ Xqueue works. It is also possible to
+ use the standard asy driver directly,
+ but the mouse operation is "jerky".
+
+<tag/Microport SVR4 &lsqb;34&rsqb;.1/ Xqueue works fine, and the asy driver
+ can also be used directly giving smooth
+ mouse operation.
+</descrip>
+ To use Xqueue, set the <tt>Protocol</tt> to <tt>Xqueue</tt> in both the
+ <tt>Keyboard</tt> and
+ <tt>Pointer</tt> sections of your <tt>XF86Config</tt> file, and You
+ must have the mouse
+ driver package installed, and must run mouseadmin to set it up for your
+ mouse. If mouseadmin won't work try doing `<tt>touch /dev/gmse</tt>'
+ before
+ running it. (Note that mouseadmin will need to be rerun after
+ rebuilding a kernel unless you add an appropriate entry to
+ <tt>/etc/conf/node.d/gmse.</tt>)<p>
+
+ <bf>NOTE</bf>: Many of the accelerated server/drivers have problems
+ when using a HW cursor and Xqueue together. If you have a serial mouse,
+ you can work around this by not using Xqueue. Otherwise the only
+ workaround is to disable the HW cursor. This is done by adding the line:
+<tscreen><verb>
+ Option "sw_cursor"
+</verb></tscreen>
+ to the Device section of your XF86Config file. The S3 server is the
+ only one known to not have this problem.
+ <p>
+ If you have problems with both Xqueue and your standard asy driver with
+ SVR4, then you should install SAS. When using SAS, set up <tt>XF86Config</tt> as
+ you would for the standard driver.<p>
+ SAS is available from ftp.physics.su.oz.au. When using SAS for a
+ serial mouse, you will get smoother operation if you change
+<tt>EVENT_TIME</tt>
+ from 80 to 30 in <tt>sas.h</tt>. A couple of details which aren't
+spelled out
+ in the SAS README are:<p>
+
+ - An example of the line you should add to <tt>/etc/ap/chan.ap</tt> is:
+<verb>
+ MAJOR 0 255 ldterm ttcompat
+</verb>
+ where <tt>MAJOR</tt> is replaced by the major number used for SAS
+ devices. To
+ determine what that is, check <tt>/etc/conf/cf.d/mdevice</tt> after
+ rebuilding
+ the kernel. The major number is the sixth field in the line starting
+ with `sas'. This file must be updated before rebooting with the new
+ kernel.<p>
+ - The installation instructions omit the following:<p>
+<quote>
+ 3a) Disable the asy driver by either running `<tt>kconfig</tt>' or editing
+ <tt>/etc/conf/sdevice.d/asy</tt>.<p>
+ 3b) Rebuild the kernel by running <tt>/etc/conf/bin/idbuild</tt><p>
+</quote>
+<item>If you want to use xdm with SVR4, extract the files from the shar file
+ in <tt>/usr/X11R6/lib/X11/etc/XdmConf.svr4</tt> into a temporary
+ directory. The
+ <tt>README</tt> file tells where the individual files should be
+ installed. Be
+ sure to read through each file and make any site-specific changes that
+ you need.<p>
+
+ <bf>NOTE:</bf> Some SVR4 versions (one example is Esix 4.0.3) have a default
+ inittab which runs `vtgetty' on the console. This does not work well
+ when starting xdm at boot time. The problem is that when you logout
+ from a vtgetty session it wants to close all the VTs -- including the
+ one xdm is using for the server. It is recommended that you use
+ `getty'. If you change <tt>/etc/inittab</tt>, remember to also change
+ <tt>/etc/conf/cf.d/init.base</tt> or you will lose the changes when you next
+ rebuild the kernel.<p>
+
+<item>If you want to change the number of VTs available on SVR4, just edit the
+ file <tt>/etc/default/workstations</tt> and change the number there.
+ The device
+ nodes will be created/deleted next time you reboot.<p>
+<item>The default local connection types have changed in X11R6. Unix domain
+ sockets are no longer treated as a "local" connection type. This means
+ that a client connecting to :0 will use not use a Unix socket for the
+ connection. To use the Unix socket connection, the client must connect
+ to unix:0.<p>
+
+ The local connection types available are "<tt>NAMED</tt>" (named streams pipe),
+ "<tt>PTS</tt>" (old-stype USL streams pipe), "<tt>SCO</tt>"
+ (SCO Xsight streams pipe), and
+ "<tt>ISC</tt>" (ISC streams pipe). The <tt>XLOCAL</tt>
+ environment variable can be used
+ to set which types of local connection should be used in order of
+ preference. The default setting is <tt>PTS:NAMED:ISC:SCO</tt>. It is
+ recommended that <tt>NAMED</tt> be used in most cases because it is
+ faster than
+ the default <tt>PTS</tt>, and because using PTS can cause you to run out of
+ <tt>/dev/pts/</tt> devices (each client using PTS requires a
+ <tt>/dev/pts</tt> device).
+ To set up the default local connection type, make sure that
+ <tt>XLOCAL</tt> is
+ set and exported in your <tt>.xinitrc</tt> file
+ (when using xinit or startx) or
+ your <tt>/usr/X11R6/lib/xdm/Xsession</tt> script (when using xdm).<p>
+
+</enum>
+<!--
+<sect>Notes for running XFree86 on SVR4.2<p>
+ In addition to the notes for SVR4.0, you need to be aware of a few
+problems with SVR4.2. Basically, the base SVR4.2 code has broken
+Unix-domain sockets in such a way that making local connections via
+<tt>UNIXCONN</tt> does not work properly (this bug is known to exist
+on Consensys
+SVR4.2 and Novell/SCO UnixWare). The manifestation of this bug is that
+windows remain on the screen after the client program exits, until you
+move the mouse into the window, or otherwise cause the server to try to
+write to the client.<p>
+If you run XFree86 and see the manifestation of the Unix-domain socket bug
+described above, you can work around this problem quickly and effectively
+by changing the default local connection mode to <tt>NAMED</tt> rather
+than <tt>UNIX</tt>.
+The mechanisms for doing this are described above. This is not a problem
+for clients using the X11R6 X libraries because <tt>UNIX</tt> is no longer
+considered a local connection type.<p>
+-->
+
+<sect>Building non-core clients with SVR4<p>
+<enum>
+<item>A lot of clients (even some which have explicit SVR4 support) require
+ <tt>-DSYSV</tt> when building under SVR4. This will not be set when
+ using the
+ default configuration. A quick fix is to add something like the
+ following to the client's Imakefile:
+<verb>
+ #if SystemV4
+ DEFINES = -DSYSV OTHER_CLIENT_DEPENDENT_DEFINES
+ #endif
+</verb>
+ The best solution is to modify the code so it compiles correctly
+ without <tt>-DSYSV</tt>.<p>
+</enum>
+<sect>Using DOS/Merge 2.2 with XFree86<p>
+ It is possible to use the Locus DOS/Merge 2.2 X clients with XFree86.
+You need to do a couple of things for this to work, though. One change is
+a generic problem with the X client and X11R5/6; the others are to work
+with some things that are specific to the XFree86 servers. Here are the
+things you need to do:
+<enum>
+<item>Set and export <tt>&dollar;XMERGE</tt> in your <tt>.xinitrc</tt>
+ and/or <tt>.xsession</tt> files.
+ In general, you should set <tt>XMERGE=vga</tt>.<p>
+<item>You MUST use the "xqueue" driver instead of the server's native
+ keyboard and mouse driver, if you intend to use the "zoom"
+ feature of the `dos' client. Otherwise the mouse will cease to
+ function after the first time you "zoom" (because the `dos'
+ client uses the native driver, and the server will not be able
+ to access the mouse after the zoom ends). The only other
+ alternative is to use separate mice on separate devices.<p>
+<item>You need to install the `dos' client fonts in the XFree86 font
+ directories. Locate the BDF files (search for files with names
+ matching the pattern `*pc???.bdf'). These will likely be
+ <tt>/usr/lib/X11/fonts/misc</tt>.
+ Go to the directory where these files
+ are located, and execute the following (using `sh' or `ksh'):
+<verb>
+ for i in *pc???.bdf
+ do
+ /usr/X11R6/bin/bdftopcf $i > \
+ /usr/X11R6/lib/X11/fonts/misc/`basename $i .bdf`.pcf
+ done
+ cd /usr/X11R6/lib/X11/fonts/misc
+ /usr/X11R6/bin/mkfontdir
+ # Do this only if the server is already running.
+ /usr/X11R6/bin/xset fp rehash
+</verb>
+<item>The `dos' client program uses a translation table to map from
+ an internal key representation to the X keymap. It is likely
+ that the table supplied with Merge 2.2 use the mapping for
+ SCO's server. A correct mapping table is available in
+ <tt>/usr/X11R6/lib/X11/etc/xcode.xfree86</tt>. This file should be
+ installed in <tt>/usr/lib/merge/xc</tt>. In addition, you must
+ add the
+ following resource to the `dos' client's application-defaults
+ file (usually in <tt>/usr/lib/X11/app-defaults/DOS</tt>):
+<verb>
+ dos*xcodetable: /usr/lib/merge/xc/xcode.xfree86
+</verb>
+ It will be obvious if this new code table is needed, as the
+ arrow keys on the keypad will fail to function in the `dos'
+ client if the wrong table is installed.<p>
+<item>For the "zoom" feature to work correctly, you must run `dos'
+ with &dollar;DISPLAY set to "unix:N" or "host_name:N". If you use
+ just ":0", the client will not function properly. `dos' does
+ not accept a `-display' parameter. Hence it is probably a good
+ idea to replace the `dos' program with something like this:
+<verb>
+ #!/usr/bin/ksh
+ if [ "X${DISPLAY}" != "X" ]
+ then
+ case ${DISPLAY} in
+ :*)
+ DISPLAY=unix${DISPLAY}
+ ;;
+ esac
+ fi
+ /usr/bin/dos.real "$@"
+</verb>
+</enum>
+<sect>Keyboard mapping problems with some Esix systems<p>
+ One of the console driver patches for Esix 4.0.3A causes the XFree86
+server's default keymap to be corrupted. If you are being affected by
+this problem it will be obvious because few (if any) of the keys will be
+mapped correctly. There are two solutions to this. One is to remove the
+console driver patch which introduced the problem. The second is to use
+xmodmap(1) to reset the default mapping after server startup. The default
+mapping is provided in the file
+<tt>/usr/X11R6/lib/X11/etc/xmodmap.std</tt>, and can
+be installed automatically by adding the line:
+<tscreen><verb>
+ xmodmap /usr/X11R6/lib/X11/etc/xmodmap.std
+</verb></tscreen>
+to your <tt>.xinitrc</tt> file (or your <tt>Xsetup</tt> file if using xdm).
+
+<sect>106 Japanese keyboard problem on PANIX<p>
+ PANIX for PC-AT uses Japanese keycodes standardized by DICOP(Desktop
+UNIX for Intel Cooperative Promotion Group) in Japan. Therefore keycode
+confliction occurs with 106 Japanese keyboard in XFree86. To avoid it,
+specify the keyword "panix106" in XF86Config like this:
+<verb>
+ Section "Keyboard"
+ Protocol "Standard"
+ Autorepeat 500 5
+ XkbModel "jp106"
+ XkbLayout "jp"
+ panix106
+ EndSection
+</verb>
+
+<sect>A kernel patch that is required for accelerated servers<p>
+ SVR4.0 has a bug handling programs that access extended I/O registers
+(above 0x3FF). Boards like S3 and 8514/A use these extended I/O
+registers. XFree86 supports boards that tickle this bug. In
+preparation for using these servers, we have produced a kernel patch
+that works around the problem, and provided scripts for you that will
+both install and back out the patch. You must install this if you
+intend to use the S3, 8514, Mach8, Mach32, P9000, AGX or W32 servers.<p>
+
+Dell 2.2 is known to not need the patch, because Thomas Roell found and
+fixed the bug while he was working for Dell. Microport has fixed this in
+their 4.0 v4.2 release. Also, SVR4.2 does not need this patch, as the
+problem has been fixed by USL.<p>
+
+The patch scripts are located in <tt>xc/programs/Xserver/hw/xfree86/etc</tt>
+in the
+source tree, and <tt>/usr/X11R6/lib/X11/etc</tt> in the binary distribution.
+The
+files are `svr4_patch' to install the patch, and `svr4_patch_rem' to back
+it out. The file that is being patched is
+<tt>/etc/conf/pack.d/kernel/os.o.</tt>
+The patch script verifies the presence of the bug before patching, and will
+tell you whether or not it succeeded in patching. You need to run the
+`svr4_patch' script as root, obviously. The original <tt>os.o</tt> file,
+as well as
+the patching program, and a copy of the removal script are stored in the
+directory <tt>/etc/conf/pack.d/kernel/.xfree86</tt><p>
+
+Thanks to John M. Sully of Microport for helping us find a simple
+workaround for this problem, and giving us permission to release the
+information.<p>
+
+<sect>Other problems<p>
+Some accelerated drivers may cause the machine to lockup when starting
+up the server on some versions of SVR4.0. The problem seems to be
+related to the kernel checking for the presence of physical memory
+when mmaping /dev/pmem. This can cause problems when mapping memory
+mapped registers. This was known to be a problem with the MGA driver in
+the SVGA server. Some other drivers may be affected too. The problem with
+the MGA driver is now fixed.
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/SVR4.sgml,v 3.16 1999/08/23 06:38:52 dawes Exp $
+
+
+
+
+
+$XConsortium: SVR4.sgml /main/8 1996/10/27 11:06:06 kaleb $
+</verb>
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/SiS.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/SiS.sgml
new file mode 100644
index 000000000..7c7be3479
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/SiS.sgml
@@ -0,0 +1,116 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN" [
+<!ENTITY % defs SYSTEM "defs.ent"> %defs;
+]>
+
+<article>
+
+<!-- Title information -->
+<title>Information for SiS Users
+<author>Juanjo Santamarta (<it>santamarta@ctv.es</it>)
+<date>17 April 1999
+
+<ident>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/SiS.sgml,v 3.5 1999/07/19 13:36:21 dawes Exp $
+</ident>
+
+<!-- Table of contents -->
+<toc>
+
+<sect> Introduction <p>
+
+This driver was primarily written for the SiS6326 and SiS530 by Alan Hourihane.
+It also works on 5597/5598 chips, and probably on older SiS862XX family.
+
+The driver supports :
+<itemize>
+ <item>Linear Addressing
+ <item>8/15/16/24 bits per pixel
+ <item>Fully programmable clocks are supported
+ <item>H/W acceleration and cursor support
+ <item>XAA support (XFree86 Acceleration Architecture)
+</itemize>
+
+<sect> Supported chips <p>
+
+<quote>
+SiS 530, SiS 86c201, SiS 86c202, SiS 86c2x5, SiS 5597/5598, SiS 6326
+</quote>
+
+Color expansion is not supported by the engine in 16M-color graphic mode.
+
+<sect> XF86Config Options <p>
+
+The following options are of particular interest for the SiS driver. Each of
+them must be specified in the `svga' driver section of the XF86Config file,
+within the Screen subsections of the depths to which they are applicable
+(you can enable options for all depths by specifying them in the Device
+section).
+
+<descrip>
+<tag>Option "SetMclk"</tag>
+ This option lets you to modify the memory clocking of your card.
+ (only for 5597 and 6326) Modifying the memory timings can destroy the
+ device, but usually the only ill effects of overclocking is to
+ have some noise an drawing errors, but BE CAREFUL. Usually a little
+ increment can improve the drawing speed, and allows also higher dotclocks.
+ The server reports default memclock on starting messages, so take it
+ as a base. Units are in KHZ.
+<tag>Option "DacSpeed"</tag>
+ This option lets you to modify the maximum allowed dotclock).
+<tag>Option "sw_cursor", "hw_cursor"</tag>
+ The default is for using the hardware cursor.
+<tag>Option "Turboqueue"</tag>
+ 5597/8 and 6326 have the option to extend the engine command queue on
+ VRAM. With extended queue length, the driver only checks queue status
+ on some color-expansion commands. This gives some performance improvement,
+ but is possible to lose some commands, corrupting screen output. As the
+ size of extended command queue is 16-32K, the probability is very low, but
+ exists. The performance gain observed is around 8-10%. Currently, using
+ this option will occasionally freeze the acceleration engine, causing
+ weird image display.
+<tag>Option "FastVram"</tag>
+ Enables 1 cycle memory access. Try it. Increased memory bandwidth reduces
+ the possibility of glitches and noise on high resolution modes.
+
+
+</descrip>
+
+
+<sect> Modelines <p>
+
+When constructing a modeline for use with the Sis
+driver you'll need to consider several points:
+<itemize>
+ <item>H/W Acceleration. The H/W cursor, and fill operations
+ currently allocate memory of the video ram for there own use.
+ If this is not available these functions will automatically be
+ disabled. Also, Turboqueue allocate 32k of Vram.
+ <item>Dot Clock. SiS documents the following video modes to work with
+ 6326. The max dot clock allowable for your 6326 based board depends
+ also on the memory installed on it. Option FastVram can be needed
+ for high dot clocks to work. Of course, the memory installed must
+ allow 1 cycle R/W.
+ <p>
+ SiS recommended video modes for 6326:
+ <descrip>
+ <tag>640x480 :</tag>4, 8, 15, 16, 24 bpp at 85Hz Non-interlaced
+ <tag>800x600 :</tag>4, 8, 15, 16, 24 bpp at 85Hz Non-interlaced
+ <tag>1024x768 :</tag>4, 8, 15, 16, 24 bpp at 85Hz Non-interlaced
+ <tag>1280x1024 :</tag>4, 8, 15, 16, 24 bpp at 75Hz Non-interlaced
+ <tag>1600x1200 :</tag>4, 8 bpp at 65Hz Non-interlaced
+ </descrip>
+</itemize>
+
+<sect> Troubleshooting <p>
+
+6326 based cards with more than 4Mb of RAM probably don't work.
+
+The generic VGA driver don't work with 6326, so XF86Setup can't be used
+for this card. Please use xf86config instead.
+
+Some video modes with high dot-clocks don't work at all, resulting on black
+screen. Lowering dotclock in that case could solve the problem.
+
+Document based on 3.3 version written by Xavier Ducoin.
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/VGADriv.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/VGADriv.sgml
new file mode 100644
index 000000000..555551310
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/VGADriv.sgml
@@ -0,0 +1,916 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+
+<title> How to add an (S)VGA driver to XFree86
+<author> Copyright (c) 1993, 1994 David E. Wexelblat
+ <tt/&lt;dwex@XFree86.org&gt;/
+<date> Issue 1.3 - May 29, 1994
+
+<toc>
+
+<sect> Introduction <p>
+Adding support for a new SVGA chipset to XFree86 is a challenging project
+for someone who wants to learn more about hardware-level programming. It
+can be fraught with hazards (in particular, crashing the machine is all too
+common). But in the end, when the server comes up and functions, it is
+immensely satisfying.
+
+Adding support for an SVGA chipset does not change any of the basic
+functioning of the server. It is still a dumb 8-bit PseudoColor server or
+1-bit StaticGray server. Adding support for new hardware (e.g. accelerated
+chips) is a major undertaking, and is not anywhere near formalized enough yet
+that it can be documented.
+
+Nonetheless, the driver-level programming here is a good introduction. And
+can well be the first step for adding support for an accelerated chipset, as
+many are SVGA-supersets. Writing an SVGA-level driver for the chipset can
+provide a stable development platform for making use of new features (in fact,
+this has been done for the S3, Cirrus, and WD accelerated chipsets, for
+internal use as the accelerated servers are developed for XFree86 2.0).
+
+Now let's get down to it. In addition to this documentation, a stub driver has
+been provided. This should provide you a complete framework for your new
+driver. Don't let the size of this document persuade you that this is an
+overly difficult task. A lot of work has been put into making this document
+as close to complete as possible; hence it should, in theory, be possible to
+use this as a cookbook, and come out with a working driver when you reach the
+end. I do advise that you read it all the way through before starting.
+
+<sect> Getting Started <p>
+The first step in developing a new driver is to get the documentation for
+your chipset. I've included a list of vendor contact information that I have
+collected so far (it's far from complete, so if you have any that isn't on
+the list, please send it to me). You need to obtain the databook for the
+chipset. Make sure that the person you speak to is aware that you intend to
+do register-level programming (so they don't send you the EE-style datasheet).
+Ask for any example code, or developer's kits, etc. I've learned that at the
+SVGA level, in general, a databook that lists and describes the registers is
+the most you can hope to find.
+
+If you are not familiar with VGA register-level programming, you should get
+(and read!) a copy of Richard Ferraro's bible (see references below). The
+best way to understand what is happening in the server is to study the
+workings of the monochrome server's ``generic'' server, and compare it with
+the documentation in Ferraro's book (be aware that there are a few errors
+in the book). You can find the generic-VGA-register handling functions in
+the file ``vgaHW.c''.
+
+Once you understand what's happening in the generic server, you should study
+one or more of the existing SVGA drivers. Obtain the databook for a supported
+SVGA chipset, and study the documentation along with the code. When you have
+a good understanding of what that driver does over and above the generic VGA,
+you will know what information you need to obtain from the databook for the
+new chipset. Once you have this information, you are ready to begin work on
+your new driver.
+
+<sect> Directory Tree Structure <p>
+Here is an outline of the directory tree structure for the source tree.
+Only directories/files that are relevant to writing a driver are presented.
+The structure for the Link Kit is presented below.
+
+<descrip>
+<tag>xc/config/cf/</tag>
+ <descrip>
+ <tag>site.def</tag>
+ Local configuration customization
+ <tag>xf86site.def</tag>
+ XFree86 local configuration customization
+ </descrip>
+
+<tag>xc/programs/Xserver/hw/xfree86/</tag>
+ The server source
+ <descrip>
+ <tag>common/</tag>
+ Files common to all of the server (XF86Config
+ parser, I/O device handlers, etc)
+ <descrip>
+ <tag>xf86.h</tag>
+ Contains the `ScrnInfoRec' data structure
+ <tag>xf86_Option.h</tag>
+ Contains option flags
+ <tag>compiler.h</tag>
+ Contains in-line assembler macros and
+ utility functions
+ </descrip>
+ <tag>os-support/</tag> OS-support layer
+ <descrip>
+ <tag>assyntax.h</tag>
+ Contains macro-ized assembler mnemonics
+ <tag>xf86_OSlib.h</tag>
+ OS-support includes, defines, and prototypes
+ </descrip>
+ <tag>LinkKit/</tag>
+ <descrip>
+ <tag>site.def.LK</tag>
+ Template for Link Kit site.def
+ </descrip>
+ <tag>vga256/</tag> 256-color VGA server directories
+ <descrip>
+ <tag>vga/</tag>
+ The generic VGA handling code
+ <descrip>
+ <tag>vga.h</tag>
+ Contains the `vgaVideoChipRec' and `vgaHWRec'
+ data structures
+ <tag>vgaHW.c</tag>
+ Contains the generic-VGA-register handling
+ functions <bf>vgaHWInit()</bf>,
+ <bf>vgaHWSave()</bf> and
+ <bf>vgaHWRestore()</bf>.
+ </descrip>
+ <tag>drivers/</tag> Contains the SVGA driver subdirectories.
+ Each contains an Imakefile, a .c file for
+ the driver, and a .s file for the bank-
+ switching functions.
+ </descrip>
+ <tag>vga2/</tag>
+ The monochrome vga server directories. Most of
+ the files are linked from vga256, and the
+ differences handled by conditional compilation.
+ <descrip>
+ <tag>drivers/</tag>
+ The SVGA driver subdirectories. The `generic'
+ VGA driver is also located here.
+ </descrip>
+ <tag>vga16/</tag>
+ The 16-color vga server directories. Most of
+ the files are linked from vga256, and the
+ differences handled by conditional compilation.
+ <descrip>
+ <tag>drivers/</tag> The SVGA driver subdirectories.
+ </descrip>
+ <tag>VGADriverDoc/</tag> This documentation and the stub driver.
+ </descrip>
+</descrip>
+The Link Kit is usually installed in /usr/X11R6/lib/Server.
+The Link Kit
+contains everything that is needed to relink the server. It is possible
+to write a new driver and build a new server without having even the server
+source installed.
+<descrip>
+<tag>Server/</tag>
+ <descrip>
+ <tag>site.def</tag>
+ Local configuration customization
+ <tag>include/</tag>
+ All of the include files listed under the
+ `common' directory above
+ <tag>drivers/</tag>
+ All of the SVGA drivers
+ <descrip>
+ <tag>vga2/</tag> The SVGA driver subdirectories.
+ <tag>vga16/</tag> The SVGA driver subdirectories.
+ <tag>vga256/</tag> The SVGA driver subdirectories.
+ </descrip>
+ <tag>VGADriverDoc/</tag> The directory with this documentation and
+ the stub driver. `vgaHW.c' is also copied
+ here, for reference (it is not built as
+ part of the Link Kit).
+ </descrip>
+</descrip>
+
+<sect> Setting Up The Build Information <p>
+ This section describes the peripheral configuration and build steps that
+must be performed to set up for your new driver. The steps are the same
+whether you are building from the source tree of from the Link Kit; only
+the locations of the files is different. Here are the configuration steps
+that must be followed:
+
+<enum>
+<item> Choose the name for your driver subdirectory and data structures.
+ Since the current driver scheme allows (in fact, encourages)
+ putting drivers for multiple related chipsets in a single driver,
+ it is usually best to use the vendor name, rather than a chipset
+ version. The fact that older XFree86 drivers do not follow this
+ convention should not deter you from using it now - most of that
+ code was developed before the driver interface had been made
+ flexible and extensible.
+
+ For this documentation, we'll use chips from the SuperDuper Chips
+ vendor. Hence, we'll use `sdc' for the name of the driver.
+
+<item> Decide whether your driver will support the color server, the
+ monochrome server, or both. For this documentation, we will
+ assume that both the color and monochrome servers will be
+ supported. If you intend to support only the color server, the
+ steps for the monochrome server can be ignored. If you intend
+ to support only the monochrome server, the steps for the color
+ server listed should be performed for the monochrome server,
+ and the monochrome steps ignored. Most of the existing drivers
+ support only the color or both servers; the ``generic'' driver is
+ the only driver (currently) that supports just the monochrome
+ server.
+
+<item> Create your driver directories:
+
+ <itemize>
+ <item>If you are working in the source tree, create the
+ following directories:
+
+<verb>
+ xc/programs/Xserver/hw/xfree86/vga256/drivers/sdc
+ xc/programs/Xserver/hw/xfree86/vga16/drivers/sdc
+ xc/programs/Xserver/hw/xfree86/vga2/drivers/sdc
+</verb>
+
+ <item>If you are working in the Link Kit, create the
+ following directories:
+
+<verb>
+ /usr/X11R6/lib/Server/drivers/vga256/sdc
+ /usr/X11R6/lib/Server/drivers/vga16/sdc
+ /usr/X11R6/lib/Server/drivers/vga2/sdc
+</verb>
+ </itemize>
+
+<item> Set up the Imakefile parameters to cause your driver to be
+ built:
+
+ <itemize>
+ <item>If you are working in the source tree:
+ <enum>
+ <item>Edit the file xc/config/cf/xfree86.cf,
+ and add
+ `sdc' to the list for the definitions for
+ `XF86Vga256Drivers', `XF86Vga16Drivers' and
+ `XF86Vga2Drivers'.
+ You should put `sdc' just before `generic' in the
+ list (i.e. second last), to ensure that none of the
+ other driver's probe functions incorrectly detect
+ the `sdc' chipset .
+ <item>Edit the file xc/config/cf/xf86site.def,
+ and add
+ the same entries in this file (this is just a
+ comment that shows the default values).
+ <item>Edit the site.def.LK file in
+ xc/programs/Xserver/hw/xfree86/LinkKit/,
+ and add the same entries in this file. This is
+ the prototype `site.def' file that will be
+ installed in the Link Kit.
+ </enum>
+
+ <item>If you are working in the Link Kit, edit the file
+ /usr/X11R6/lib/Server/site.def, and add `sdc' to
+ the `XF86Vga256Drivers', `XF86Vga16Drivers' and
+ `XF86Vga2Drivers' definitions as described in (a) above.
+ </itemize>
+<item> Now copy the prototype files into your new directories:
+ <itemize>
+ <item>If you are working in the source tree, copy the `stub'
+ files as follows (directories are below xc/programs/Xserver):
+ <descrip>
+ <tag>Imakefile.stub =&gt;</tag>
+ hw/xfree86/vga256/drivers/sdc/Imakefile
+ <tag>stub_driver.c =&gt;</tag>
+ hw/xfree86/vga256/drivers/sdc/sdc_driver.c
+ <tag>stub_bank.s =&gt;</tag>
+ hw/xfree86/vga256/drivers/sdc/sdc_bank.s
+ <tag>Imakefile.stub =&gt;</tag>
+ hw/xfree86/vga16/drivers/sdc/Imakefile
+ (then edit this Imakefile and make the changes
+ described in the comments).
+ <tag>Imakefile.stub =&gt;</tag>
+ hw/xfree86/vga2/drivers/sdc/Imakefile
+ (then edit this Imakefile and make the changes
+ described in the comments).
+ </descrip>
+ <item>If you are working in the Link Kit, copy the `stub' files
+ as follows:
+ <descrip>
+ <tag>Imakefile.stub =&gt; </tag>
+ /usr/X11R6/lib/Server/drivers/vga256/sdc/Imakefile
+ <tag>stub_driver.c =&gt; </tag>
+ /usr/X11R6/lib/Server/drivers/vga256/sdc/sdc_driver.c
+ <tag>stub_bank.s =&gt; </tag>
+ /usr/X11R6/lib/Server/drivers/vga256/sdc/sdc_bank.s
+ <tag>Imakefile.stub =&gt; </tag>
+ /usr/X11R6/lib/Server/drivers/vga16/sdc/Imakefile
+ (then edit this Imakefile and make the changes
+ described in the comments).
+ <tag>Imakefile.stub =&gt; </tag>
+ /usr/X11R6/lib/Server/drivers/vga2/sdc/Imakefile
+ (then edit this Imakefile and make the changes
+ described in the comments).
+ </descrip>
+ </itemize>
+<item> Edit each of the files you've just copied, and replace `stub'
+ with `sdc' and `STUB' with `SDC' wherever they appear.
+</enum>
+That's all the prep work needed. Now it's time to work on the actual driver.
+
+<sect> The Bank-Switching Functions <p>
+The normal VGA memory map is 64k starting at address 0xA0000. To access
+more than 64k of memory, SuperVGA chipsets implement ``bank switching'' -
+the high-order address bits are used to select the bank of memory in which
+operations will take place. The size and number of these banks varies,
+and will be spelled out in the chipset documentation. A chipset will
+have zero, one or two bank registers. Likely the ONLY case of zero bank
+registers is a generic VGA, and hence is not a concern.
+
+Note that some of the newer chipsets (e.g. Trident 8900CL, Cirrus) allow
+for a linear mapping of the video memory. While using such a scheme would
+improve the performance of the server, it is not currently supported. Hence
+there is no way to use such features for a new chipset.
+
+Most SVGA chipsets have two bank registers. This is the most desirable
+structure (if any banking structure can be called ``desirable''), because
+data can be moved from one area of the screen to another with a simple
+`mov' instruction. There are two forms of dual-banking - one where the
+two bank operations define a read-only bank and a write-only bank, and
+one with two read/write windows. With the first form, the entire SVGA
+memory window is used for both read a write operations, and the two
+bank registers determine which bank is actually used (e.g. ET3000, ET4000).
+With the second form, the SVGA memory window is split into two read/write
+banks, with each bank pointer being used to control one window. In
+this case, one window is used for read operations and the other for write
+operations (e.g. PVGA1/Western Digital, Cirrus).
+
+A chipset that has a single bank register uses that one bank for both
+read and write access. This is problematic, because copying information
+from one part of the screen to another requires that the data be read in,
+stored, and then written out. Fortunately, the server is able to handle
+both one-bank and two-bank chipsets; the determination of behavior is
+defined by an entry in the driver data structure described below.
+
+A driver requires that three assembly-language functions be written, in
+the file `<tt>sdc_bank.s</tt>'.
+These functions set the read bank - <bf>SDCSetRead()</bf>,
+the write bank - <bf>SDCSetWrite()</bf>, and set both banks -
+<bf>SDCSetReadWrite()</bf>.
+For a chipset with only one bank, all three will be declared as entry points
+to the same function (see the ``tvga8900'' driver for an example).
+
+The functions are fairly simple - the bank number is passed to the function
+in register &percnt;al. The function will shift, bitmask, etc - whatever is
+required to put the bank number into the correct form - and then write
+it to the correct I/O port. For chipsets where the two banks are read-only
+HERE
+and write-only, the <bf>SetReadWrite()</bf> function will have to do this twice - once
+for each bank. For chipsets with two independent read/write windows, the
+<bf>SetReadWrite()</bf> function should use the same bank as the <bf>SetWrite()</bf> function.
+
+A special note - these functions MUST be written in the macroized assembler
+format defined in the header file ``assyntax.h''. This will ensure that
+the correct assembler code will be generated, regardless of OS. This
+macroized format currently supports USL, GNU, and Intel assembler formats.
+
+That's all there is to the banking functions. Usually the chipset reference
+will give examples of this code; if not, it is not difficult to figure out,
+especially using the other drivers as examples.
+
+<sect> The Driver Itself <p>
+ Now it's time to get down to the real work - writing the major driver
+functions in the files sdc_driver.c. First, an overview of what the
+responsibilities of the driver are:
+
+<enum>
+<item> Provide a chipset-descriptor data structure to the server. This
+ data structure contains pointers to the driver functions and
+ some data-structure initialization as well.
+<item> Provide a driver-local data structure to hold the contents of
+ the chipset registers. This data structure will contain a
+ generic part and a driver-specific part. It is used to save the
+ initial chipset state, and is initialized by the driver to put
+ the chipset into different modes.
+<item> Provide an identification function that the server will call to
+ list the chipsets that the driver is capable of supporting.
+<item> Provide a probe function that will identify this chipset as
+ different from all others, and return a positive response if
+ the chipset this driver supports is installed, and a negative
+ response otherwise.
+<item> Provide a function to select dot-clocks available on the board.
+<item> Provide functions to save, restore, and initialize the driver-
+ local data structure.
+<item> Provide a function to set the starting address for display in
+ the video memory. This implements the virtual-screen for the
+ server.
+<item> Perhaps provide a function for use during VT-switching.
+<item> Perhaps provide a function to check if each mode is suitable for
+ the chipset being used.
+</enum>
+
+Before stepping through the driver file in detail, here are some important
+issues:
+
+<enum>
+<item> If your driver supports both the color and monochrome servers,
+ you should take care of both cases in the same file. Most things
+ are the same - you can differentiate between the two with the
+ MONOVGA <tt>&num;define</tt>. If the 16 color server is supported,
+ code specific to it can be enabled with the XF86VGA16
+ <tt>&num;define</tt>. In most cases it is sufficient to put
+ the following near the top of the stub_driver.c file:
+
+<verb>
+ #ifdef XF86VGA16
+ #define MONOVGA
+ #endif
+</verb>
+
+<item> The color server uses the SVGA's 8-bit packed-pixel mode. The
+ monochrome and vga16 servers uses the VGA's 16-color mode
+ (4 bit-planes). Only one plane is enabled for the monochrome
+ server.
+<item> It is possible for you to define your monochrome driver so that
+ no bank-switching is done. This is not particularly desirable,
+ as it yields only 64k of viewing area.
+</enum>
+Keeping these things in mind, you need to find the registers from your
+SVGA chipset that control the desired features. In particular, registers
+that control:
+<enum>
+<item> Clock select bits. The two low-order bits are part of the
+ standard Miscellaneous Output Register; most SVGA chipsets
+ will include 1 or 2 more bits, allowing the use of 8 or 16
+ discrete clocks.
+<item> Bank selection. The SVGA chipset will have one or two registers
+ that control read/write bank selection.
+<item> CRTC extensions. The standard VGA registers don't have enough
+ bits to address large displays. So the SVGA chipsets have
+ extension bits.
+<item> Interlaced mode. Standard VGA does not support interlaced
+ displays. So the SVGA chipset will have a bit somewhere to
+ control interlaced mode. Some chipsets require additional
+ registers to be set up to control interlaced mode
+<item> Starting address. The standard VGA only has 16 bits in which
+ to specify the starting address for the display. This restricts
+ the screen size usable by the virtual screen feature. The SVGA
+ chipset will usually provide one or more extension bits.
+<item> Lock registers. Many SVGA chipset prevent modification of
+ extended registers unless the registers are first ``unlocked''.
+ You will need to disable protection of any registers you will
+ need for other purposes.
+<item> Any other facilities. Some chipset may, for example, require
+ that certain bits be set before you can access extended VGA
+ memory (beyond the IBM-standard 256k). Or other facilities;
+ read through all of the extended register descriptions and see
+ if anything important leaps out at you.
+</enum>
+
+If you are fortunate, the chipset vendor will include in the databook some
+tables of register settings for various BIOS modes. You can learn a lot
+about what manipulations you must do by looking at the various BIOS modes.
+
+<sect1> Multiple Chipsets And Options <p>
+It is possible, and in fact desirable, to have a single driver support
+multiple chipsets from the same vendor. If there are multiple supported
+chipsets, then you would have a series of &num;define's for them, and a
+variable `SDCchipset', which would be used throughout the driver when
+distinctions must be made. See the Trident and PVGA1/WD drivers for
+examples (the Tseng ET3000 and ET4000 are counter-examples - these were
+implemented before the driver interface allowed for multiple chipsets, so
+this example should NOT be followed). Note that you should only distinguish
+versions when your driver needs to do things differently for them. For
+example, suppose the SDC driver supports the SDC-1a, SDC-1b, and SDC-2
+chipsets. The -1a and -1b are essentially the same, but different from the
+-2 chipset. Your driver should support the -1 and -2 chipsets, and not
+distinguish between the -1a and -1b. This will simplify things for the
+end user.
+
+In cases where you want to give the user control of driver behavior, or
+there are things that cannot be determined without user intervention, you
+should use ``option'' flags. Say that board vendors that use the SDC
+chipsets have the option of providing 8 or 16 clocks. There's no way you
+can determine this from the chipset probe, so you provide an option flag to
+let the user select the behavior from the XF86Config file. The option flags
+are defined in the file ``xf86_option.h''. You should look to see if there is
+already a flag that can be reused. If so, use it in your driver. If not,
+add a new &num;define, and define the string->symbol mapping in the table in
+that file. To see how option flags are used, look at the ET4000,
+PVGA1/WD, and Trident drivers.
+
+<sect1> Data Structures <p>
+Once you have an understanding of what is needed from the above description,
+it is time to fill in the driver data structures. First we will deal with
+the `vgaSDCRec' structure. This data structure is the driver-local structure
+that holds the SVGA state information. The first entry in this data structure
+is ALWAYS `vgaHWRec std'. This piece holds the generic VGA portion of the
+information. After that, you will have one `unsigned char' field for each
+register that will be manipulated by your driver. That's all there is to
+this data structure.
+
+Next you must initialize the `SDC' structure (type `vgaVideoChipRec'). This
+is the global structure that identifies your driver to the server. Its name
+MUST be `SDC', in all caps - i.e. it must match the directory name for your
+driver. This is required so that the Link Kit reconfiguration can identify
+all of the requisite directories and global data structures.
+
+The first section of this structure simply holds pointers to the driver
+functions.
+
+Next, you must initialize the information about how your chipset does
+bank switching. The following fields must be filled in:
+<enum>
+<item> ChipMapSize - the amount of memory that must be mapped into
+ the server's address space. This is almost always 64k (from
+ 0xA0000 to 0xAFFFF). Some chipsets use a 128k map (from
+ 0xA0000 to 0xBFFFF). If your chipset gives an option, use the
+ 64k window, as a 128k window rules out using a Hercules or
+ Monochrome Display Adapter card with the SVGA.
+<item> ChipSegmentSize - the size of each bank within the ChipMapSize
+ window. This is usually also 64k, however, some chipsets split
+ the mapped window into a read portion and a write portion (for
+ example the PVGA1/Western Digital chipsets).
+<item> ChipSegmentShift - the number of bits by which an address will
+ be shifted right to mask of the bank number. This is log-base-2
+ of ChipSegmentSize.
+<item> ChipSegmentMask - a bitmask used to mask off the address within
+ a given bank. This is (ChipSegmentSize-1).
+<item> ChipReadBottom,ChipReadTop - the addresses within the mapped
+ window in which read operations can be done. Usually 0, and
+ 64k, respectively, except for those chipset that have separate
+ read and write windows.
+<item> ChipWriteBottom,ChipWriteTop - same as above, for write operations.
+<item> ChipUse2Banks - a boolean value for whether this chipset has one
+ or two bank registers. This is used to set up the screen-to-screen
+ operations properly.
+</enum>
+There are three more fields that must be filled in:
+<enum>
+<item> ChipInterlaceType - this is either VGA_NO_DIVIDE_VERT or
+ VGA_DIVIDE_VERT. Some chipsets require that the vertical timing
+ numbers be divided in half for interlaced modes. Setting this
+ flag will take care of that.
+<item> ChipOptionFlags - this should always be `{0,}' in the data
+ structure initialization. This is a bitfield that contains
+ the Option flags that are valid for this driver. The appropriate
+ bits are initialized at the end of the Probe function.
+<item> ChipRounding - this gets set to the multiple by which the
+ virtual width of the display must be rounded for the 256-color
+ server. This value is usually 8, but may be 4 or 16 for some
+ chipsets.
+</enum>
+
+<sect1> The Ident() function <p>
+The <bf>Ident()</bf> function is a very simple function. The server will call
+this function repeatedly, until a NULL is returned, when printing out the
+list of configured drivers. The <bf>Ident()</bf> function should return a chipset
+name for a supported chipset. The function is passed a number which
+increments from 0 on each iteration.
+
+<sect1> The ClockSelect() function <p>
+The <bf>ClockSelect()</bf> function is used during clock probing (i.e. when no
+`Clocks' line is specified in the XF86Config file) to select the dot-clock
+indicated by the number passed in the parameter. The function should
+set the chipset's clock-select bits according to the passed-in number.
+Two dummy values will be passed in as well (CLK_REG_SAVE, CLK_SAVE_RESTORE).
+When CLK_REG_SAVE is passed, the function should save away copies of
+any registers that will be modified during clock selection. When
+CLK_REG_RESTORE is passed, the function should restore these registers.
+This ensure that the clock-probing cannot corrupt registers.
+
+This function should return FALSE if the passed-in index value is invalid
+or if the clock can't be set for some reason.
+
+<sect1> The Probe() function <p>
+The <bf>Probe()</bf> function is perhaps the most important, and perhaps the
+least intuitive function in the driver. The Probe function is required
+to identify the chipset independent of all other chipsets. If the user
+has specified a `<tt>Chipset</tt>' line in the XF86Config file, this is a simple
+string comparison check. Otherwise, you must use some other technique
+to figure out what chipset is installed. If you are lucky, the chipset
+will have an identification mechanism (ident/version registers, etc), and
+this will be documented in the databook. Otherwise, you will have to
+determine some scheme, using the reference materials listed below.
+
+The identification is often done by looking for particular patterns in
+register, or for the existence of certain extended registers. Or with
+some boards/chipsets, the requisite information can be obtained by reading
+the BIOS for certain signature strings. The best advise is to study the
+existing probe functions, and use the reference documentation. You
+must be certain that your probe is non-destructive - if you modify a
+register, it must be saved before, and restored after.
+
+Once the chipset is successfully identified, the <bf>Probe()</bf> function must
+do some other initializations:
+<enum>
+<item> If the user has not specified the `<tt>VideoRam</tt>' parameter in the
+ XF86Config file, the amount of installed memory must be determined.
+<item> If the user has not specified the `<tt>Clocks</tt>' parameter in the
+ XF86Config file, the values for the available dot-clocks must
+ be determined. This is done by calling the <bf>vgaGetClocks()</bf>
+ function, and passing it the number of clocks available and
+ a pointer to the <bf>ClockSelect()</bf> function.
+<item> It is recommended that the `maxClock' field of the server's
+ `vga256InfoRec' structure be filled in with the maximum
+ dot-clock rate allowed for this chipset (specified in KHz).
+ If this is not filled in a probe time, a default (currently
+ 90MHz) will be used.
+<item> The `chipset' field of the server's `vga256InfoRec' structure
+ must be initialized to the name of the installed chipset.
+<item> If the driver will be used with the monochrome server, the
+ `bankedMono' field of the server's `vga256InfoRec' structure
+ must be set to indicate whether the monochrome driver supports
+ banking.
+<item> If any option flags are used by this driver, the `ChipOptionFlags'
+ structure in the `vgaVideoChipRec' must be initialized with the
+ allowed option flags using the <bf>OFLG_SET()</bf> macro.
+</enum>
+
+<sect1> The EnterLeave() function <p>
+The <bf>EnterLeave()</bf> function is called whenever the virtual console on which
+the server runs is entered or left (for OSs without virtual consoles, the
+function is called when the server starts and again when it exits). The
+purpose of this function is to enable and disable I/O permissions (for
+OSs where such is required), and to unlock and relock access to ``protected''
+registers that the driver must manipulate. It is a fairly trivial function,
+and can be implemented by following the comments in the stub driver.
+
+<sect1> The Restore() function <p>
+The <bf>Restore()</bf> function is used for restoring a saved video state. Note
+that `restore' is a bit of a misnomer - this function is used to both
+restore a saved state and to install a new one created by the server. The
+<bf>Restore()</bf> function must complete the following actions:
+<enum>
+<item> Ensure that Bank 0 is selected, and that any other state
+ information required prior to writing out a new state has been
+ set up.
+<item> Call <bf>vgaHWRestore()</bf> to restore the generic VGA portion of the
+ state information. This function is in the vgaHW.c file.
+<item> Restore the chipset-specific portion of the state information.
+ This may be done by simply writing out the register, or by
+ doing a read/modify/write cycle if only certain bits are to
+ be modified. Be sure to note the comment in the sample driver
+ about how to handle clock-select bits.
+</enum>
+<sect1> The Save() function <p>
+The <bf>Save()</bf> function is used to extract the initial video state information
+when the server starts. The <bf>Save()</bf> function must complete the following
+actions:
+<enum>
+<item> Ensure that Bank 0 is selected.
+<item> Call <bf>vgaHWSave()</bf> to extract the generic VGA portion of the state
+ information. This function is in the vgaHW.c file.
+<item> Extract the chipset-specific portion of the state information.
+</enum>
+<sect1> The Init() function <p>
+ The <bf>Init()</bf> function is the second most important function in the driver
+(after the <bf>Probe()</bf> function). It is used to initialize a data structure
+for each of the defined display modes in the server. This function is
+required to initialize the entire `vgaSDCRec' data structure with the
+information needed to put the SVGA chipset into the required state. The
+generic VGA portion of the structure is initialized with a call to
+<bf>vgaHWInit()</bf> (also located in vgaHW.c).
+
+Once the generic portion is initialized, the <bf>Init()</bf> function can override
+any of the generic register initialization, if necessary. All of the other
+fields are filled in with the correct initialization. The information
+about the particular mode being initialized is passed in the `mode'
+parameter, a pointer to a `DisplayModeRec' structure. This can be
+dereferenced to determine the needed parameters.
+
+If you only know how to initialize certain bits of the register, do that
+here, and make sure that the <bf>Restore()</bf> function does a read/modify/write
+to only manipulate those bits. Again, refer to the existing drivers
+for examples of what happens in this function.
+
+<sect1> The Adjust() function <p>
+The <bf>Adjust()</bf> function is another fairly basic function. It is called
+whenever the server needs to adjust the start of the displayed part of
+the video memory, due to scrolling of the virtual screen or when changing
+the displayed resolution. All it does is set the starting address on the
+chipset to match the specified coordinate. Follow the comments in the
+stub driver for details on how to implement it.
+
+<sect1> The ValidMode() function <p>
+The <bf>ValidMode()</bf> function is required. It is used to check
+for any chipset-dependent reasons why a graphics mode might not be valid. It
+gets called by higher levels of the code after the Probe() stage. In
+many cases no special checking will be required and this function will
+simply return TRUE always.
+
+<sect1> The SaveScreen() function <p>
+The <bf>SaveScreen()</bf> function is not needed by most chipsets. This function
+would only be required if the extended registers that your driver needs
+will be modified when a synchronous reset is performed on the SVGA chipset
+(your databook should tell you this). If you do NOT need this function,
+simply don't define it, and put `NoopDDA' in its place in the vgaVideoChipRec
+structure initialization (NoopDDA is a generic-use empty function).
+
+If you DO need this function, it is fairly simple to do. It will be
+called twice - once before the reset, and again after. It will be passed
+a parameter of SS_START in the former case, and SS_FINISH in the latter.
+All that needs to be done is to save any registers that will be affected
+by the reset into static variables on the SS_START call, and then restore
+them on the SS_FINISH call.
+
+<sect1> The GetMode() function <p>
+The <bf>GetMode()</bf> function is not used as of XFree86 1.3; its place in the
+vgaVideoChipRec should be initialized to `NoopDDA'.
+
+At some point in the future, this function will be used to enable the server
+and/or a standalone program using the server's driver libraries to do
+interactive video mode adjustments. This function will read the SVGA
+registers and fill in a DisplayModeRec structure with the current video
+mode.
+
+<sect1> The FbInit() function <p>
+The <bf>FbInit()</bf> function is required for drivers with accelerated graphics
+support. It is used to replace default cfb.banked functions with
+accelerated chip-specific versions. vga256LowlevFuncs is a struct containing
+a list of functions which can be replaced. This struct defined in
+vga256.h. Examples of <bf>FbInit()</bf> functions can be found in the et4000,
+pvga1 and cirrus drivers.
+
+If you do NOT need this function, simply don't define it, and put `NoopDDA'
+in its place in the vgaVideoChipRec structure initialization.
+
+<sect> Building The New Server <p>
+As in the setup work, the steps for building the server depend whether
+you are working in the source tree or in the Link Kit. Here are the
+steps for the initial build after installing your new driver files:
+<itemize>
+ <item>If you are working in the source tree, follow these steps:
+
+ Go to xc/programs/Xserver, and enter
+ `<tt>make Makefile</tt>', then
+ `<tt>make Makefiles depend all</tt>'
+
+ <item>If you are working in the Link Kit, follow these steps:
+
+ <enum>
+ <item>Go to /usr/X11R6/lib/Server, and enter
+ `<tt>./mkmf</tt>'
+ <item>In the same directory, enter `<tt>make</tt>'
+ </enum>
+</itemize>
+To rebuild the server after the initial build (e.g. after making changes
+to your driver):
+
+<itemize>
+<item> If you are working in the source tree, follow these steps:
+
+ <enum>
+ <item> Go to the appropriate drivers/ directory (e.g.,
+ xc/programs/Xserver/hw/xfree86/vga256/drivers),
+ and enter `<tt>make</tt>'.
+ <item> Go to xc/programs/Xserver, and enter
+ `<tt>make loadXF86_SVGA</tt>' (to link the color server),
+ `<tt>make loadXF86_VGA16</tt>' (to link the 16 color server) or
+ `<tt>make loadXF86_Mono</tt>' (to link the mono server).
+ </enum>
+
+<item> If you are working in the Link Kit, follow these steps:
+
+ <enum>
+ <item> Go to the appropriate driver directory, and enter
+ `<tt>make</tt>'.
+ <item> Go to /usr/X11R6/lib/server, and enter
+ `<tt>make loadXF86_SVGA</tt>' (to link the color server) or
+ `<tt>make loadXF86_VGA16</tt>' (to link the 16 color server) or
+ `<tt>make loadXF86_Mono</tt>' (to link the mono server).
+ </enum>
+</itemize>
+
+<sect> Debugging <p>
+Debugging a new driver can be a painful experience, unfortunately. It
+is likely that incorrect programming of the SVGA chipset can lock up your
+machine. More likely, however, is that the display will be lost, potentially
+requiring a reboot to correct. It is HIGHLY recommended that the server
+be run from an attached terminal or a network login. This is the only
+rational way in which a debugger can be used on the server. Attempting
+to use multiple VTs for debugging is basically a waste of time.
+
+Because of the potential for locking up the machine, it is a VERY good idea
+to remember to do a `sync' or two before starting the server. In addition,
+any unnecessary filesystems should be unmounted while the debugging session
+is going on (to avoid having to run unnecessary fsck's).
+
+By default the server is built without debugging symbols. The server can
+grow VERY large with debugging enabled. It is very simple to rebuild
+your driver for debugging, though. Do the following:
+
+<enum>
+ <item>Go to the driver directory.
+ <item>Edit the Makefile. Look for the SECOND definition of
+ `<tt>CDEBUGFLAGS</tt>'. Change this definition to
+
+ <verb>
+ CDEBUGFLAGS = -g -DNO_INLINE
+ </verb>
+
+ (this will enable debugging symbols and disable inlining of
+ functions, which can make single-stepping a nightmare).
+ <item>Remove the `sdc_driver.o' file.
+ <item>Now follow the steps above for rebuilding the server.
+
+ (Alternatively, instead of editing the Makefile, you can simply
+ do `<tt>make CDEBUGFLAGS="-g -DNO_INLINE"</tt>' after removing the
+ old .o file, then rebuild the server as described above).
+</enum>
+
+This will give you a server with which you can set breakpoints in the driver
+functions and single-step them. If you are working in the source tree,
+and just learning about SVGA programming, it may be useful to rebuild
+vgaHW.c with debugging as well.
+
+<sect> Advice <p>
+I cannot stress this enough - study all available references, and the
+existing code, until you understand what is happening. Do this BEFORE you
+begin writing a driver. This will save you a massive amount of headache.
+Try to find a driver for a chipset that is similar to yours, if possible.
+Use this as an example, and perhaps derive your driver from it.
+
+Do not let the gloom-and-doom in the debugging section discourage you.
+While you will probably have problems initially (I still do), careful,
+deliberate debugging steps can bear fruit very quickly. It is likely
+that, given a good understanding of the chipset, a driver can be written
+and debugged in a day or two. For someone just learning about this kind
+of programming, a week is more reasonable.
+
+<sect> Advanced Topics <p>
+Newer chipsets are getting into two advanced areas: programmable clock
+generators, and accelerated capabilities (BitBlt, line drawing, HW cursor).
+These are new areas, and the formal interfaces to them are not yet defined.
+It is advised that you contact the XFree86 team and get involved with the
+development/beta-testing team if you need to be working in these areas.
+
+<sect> References <p>
+<itemize>
+<item>Programmer's Guide to the EGA and VGA Cards, 3rd ed. <newline>
+ Richard Ferraro <newline>
+ Addison-Wesley, 1994 <newline>
+ ISBN 0-201-62490-7 <newline>
+ (This is the bible of SVGA programming - it has a few errors, so watch out.
+ The third edition also covers several accelerated video cards.)
+
+<item>vgadoc4.zip <newline>
+ Finn Thoegersen <newline>
+ (This is a collection of SVGA and other chipset documentation. It is
+ available on most MS-DOS/Windows related FTP archives, including wuarchive.
+ It is DOS/BIOS oriented, but is still extremely useful, especially for
+ developing probe functions.)
+</itemize>
+
+<sect> Vendor Contact Information <p>
+<descrip>
+<tag/ATI Technologies (VGA-Wonder, Mach8, Mach32, Mach64)
+ 33 Commerce Valley Drive East/
+Thornhill, Ontario <newline>
+Canada L3T 7N6 <newline>
+(905) 882-2600 (sales) <newline>
+(905) 882-2626 (tech support) <newline>
+(905) 764-9404 (BBS) <newline>
+(905) 882-0546 (fax) <newline>
+
+<tag/Chips &amp; Technologies/
+???
+
+<tag/Cirrus Logic (SVGA, Accelerators - CL-GD5426)/
+3100 West Warren Ave. <newline>
+Fremont, CA 94538 <newline>
+(510) 623-8300 (N. CA, USA) <newline>
+(49) 8152-40084 (Germany) <newline>
+(44) 0727-872424 (UK) <newline>
+
+<tag/Genoa Systems (GVGA)/
+75 E. Trimble Road <newline>
+San Jose, CA 95131 <newline>
+(408) 432-9090 (sales) <newline>
+(408) 432-8324 (tech support) <newline>
+
+<tag/Headland Technologies, Inc (Video-7 VGA 1024i, VRAM II)/
+46221 Landing Parkway <newline>
+Fremont, CA 94538 <newline>
+(415) 623-7857 <newline>
+
+<tag/Oak Technology, Inc (OTI-067,OTI-077)/
+139 Kifer Ct. <newline>
+Sunnyvale, CA 94086 <newline>
+(408) 737-0888 <newline>
+(408) 737-3838 (fax)
+
+<tag>S3 (911, 924, 801/805, 928, 864, 868, 964, 968, 764, 765)</tag>
+(408) 980-5400
+
+<tag/Trident Microsystems Inc (8800, 8900, 9000)/
+205 Ravendale Dr <newline>
+Mountainside, CA 94043 <newline>
+(415) 691-9211
+
+<tag/Tseng Labs Inc,/
+6 Terry Drive <newline>
+Newtown, PA 18940 <newline>
+(215) 968-0502
+
+<tag/Weitek (Power9000, 5186)/
+1060 E. Arques Ave, <newline>
+Sunnyvale, CA 94086 <newline>
+(408) 738-5765
+
+<tag/Western Digital/
+(714) 932-4900
+</descrip>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/VGADriv.sgml,v 3.14 1998/03/20 21:06:26 hohndel Exp $
+
+
+
+
+
+$XConsortium: VGADriv.sgml /main/9 1996/10/28 05:13:22 kaleb $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/VidModes.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/VidModes.sgml
new file mode 100644
index 000000000..bf0d63c5a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/VidModes.sgml
@@ -0,0 +1,1428 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<!-- This is the Linux Distribution HOWTO, SGML source -- >
+<!-- Eric S. Raymond, esr@snark.thyrsus.com -- >
+<!-- The submission address is gregh@sunsite.unc.edu -- >
+
+<article>
+
+<title>XFree86 Video Timings HOWTO
+<author>Eric S. Raymond &lt;esr@thyrsus.com&gt;
+<date>Version 3.0, 8 Aug 1997
+
+<abstract>
+How to compose a mode line for your card/monitor combination under XFree86.
+The XFree86 distribution now includes good facilities for configuring most
+standard combinations; this document is mainly useful if you are tuning a
+custom mode line for a high-performance monitor or very unusual hardware.
+It may also help you in using xvidtune to tweak a standard mode that is
+not quite right for your monitor.
+</abstract>
+
+<toc>
+
+<sect>Disclaimer
+<p>
+
+You use the material herein SOLELY AT YOUR OWN RISK. It is possible
+to harm both your monitor and yourself when driving it outside the
+manufacturer's specs. Read <ref id="overd" name="Overdriving Your
+Monitor"> for detailed cautions. Any damages to you or your monitor
+caused by overdriving it are your problem.
+
+The most up-to-date version of this HOWTO can be found at the <url
+url="http://sunsite.unc.edu/LDP"
+name="Linux Documentation Project"> web page.
+
+Please direct comments, criticism, and suggestions for improvement to
+<htmlurl url="mailto:esr@thyrsus.com" name="esr@snark.thyrsus.com">. Please do
+<em>not</em> send email pleading for a magic solution to your
+special monitor problem, as doing so will only burn up my time and
+frustrate you -- everything I know about the subject is already in
+here.
+
+<sect>Introduction<label id="intro">
+<p>
+
+The XFree86 server allows users to configure their video subsystem and thus
+encourages best use of existing hardware. This tutorial is intended to help
+you learn how to generate your own timing numbers to make optimum use of your
+video card and monitor.
+
+We'll present a method for getting something that works, and then show you how
+you can experiment starting from that base to develop settings that optimize
+for your taste.
+
+Starting with XFree86 3.2, XFree86 provides an <bf>XF86Setup</bf>(1)
+program that makes it easy to generate a working monitor mode
+interactively, without messing with video timing number directly. So
+you shouldn't actually need to calculate a base monitor mode in most
+cases. Unfortunately, <bf>XF86Setup</bf>(1) has some limitations; it
+only knows about standard video modes up to 1280x1024. If you have a
+very high-performance monitor capable of 1600x1200 or more you will
+still have to compute your base monitor mode yourself.
+
+Recent versions of XFree86 provide a tool called <bf>xvidtune</bf>(1)
+which you will probably find quite useful for testing and tuning
+monitor modes. It begins with a gruesome warning about the possible
+consequences of mistakes with it. If you pay careful attention to
+this document and learn what is behind the pretty numbers in
+xvidtune's boxes, you will become able to use xvidtune effectively and
+with confidence.
+
+If you already have a mode that almost works (in particular, if one of
+predefined VESA modes gives you a stable display but one that's
+displaced right or left, or too small, or too large) you can go
+straight to the section on <ref id="fixes" name="Fixing Problems with the
+Image">. This will enlighten you on ways to tweak the timing
+numbers to achieve particular effects.
+
+If you have <bf>xvidtune</bf>(1), you'll be able to test new modes on the fly,
+without modifying your X configuration files or even rebooting your X server.
+Otherwise, XFree86 allows you to hot-key between different modes defined in
+Xconfig (see XFree86.man for details). Use this capabilty to save
+yourself hassles! When you want to test a new mode, give it a unique
+mode label and add it to the <EM>end</EM> of your hot-key list. Leave a
+known-good mode as the default to fall back on if the test mode
+doesn't work.
+
+<sect>How Video Displays Work<label id="video">
+<p>
+
+Knowing how the display works is essential to understanding what numbers to put
+in the various fields in the file Xconfig. Those values are used in the lowest
+levels of controlling the display by the XFree86 server.
+
+The display generates a picture from a series of dots. The dots are arranged
+from left to right to form lines. The lines are arranged from top to bottom to
+form the picture. The dots emit light when they are struck by the electron
+beam inside the display. To make the beam strike each dot for an equal amount
+of time, the beam is swept across the display in a constant pattern.
+
+The pattern starts at the top left of the screen, goes across the screen to the
+right in a straight line, and stops temporarily on the right side of the
+screen. Then the beam is swept back to the left side of the display, but down
+one line. The new line is swept from left to right just as the first line was.
+This pattern is repeated until the bottom line on the display has been swept.
+Then the beam is moved from the bottom right corner of the display to the top
+left corner, and the pattern is started over again.
+
+There is one variation of this scheme known as interlacing: here only
+every second line is swept during one half-frame and the others are filled in
+in during a second half-frame.
+
+Starting the beam at the top left of the display is called the beginning of a
+frame. The frame ends when the beam reaches the the top left corner again as
+it comes from the bottom right corner of the display. A frame is made up of
+all of the lines the beam traced from the top of the display to the bottom.
+
+If the electron beam were on all of the time it was sweeping through the frame,
+all of the dots on the display would be illuminated. There would be no black
+border around the edges of the display. At the edges of the display the
+picture would become distorted because the beam is hard to control there. To
+reduce the distortion, the dots around the edges of the display are not
+illuminated by the beam even though the beam may be pointing at them. The
+viewable area of the display is reduced this way.
+
+Another important thing to understand is what becomes of the beam when no spot
+is being painted on the visible area. The time the beam would have been
+illuminating the side borders of the display is used for sweeping the beam back
+from the right edge to the left and moving the beam down to the next line. The
+time the beam would have been illuminating the top and bottom borders of the
+display is used for moving the beam from the bottom-right corner of the display
+to the top-left corner.
+
+The adapter card generates the signals which cause the display to turn on the
+electron beam at each dot to generate a picture. The card also controls when
+the display moves the beam from the right side to the left and down a line by
+generating a signal called the horizontal sync (for synchronization) pulse.
+One horizontal sync pulse occurs at the end of every line. The adapter also
+generates a vertical sync pulse which signals the display to move the beam to
+the top-left corner of the display. A vertical sync pulse is generated near
+the end of every frame.
+
+The display requires that there be short time periods both before and after the
+horizontal and vertical sync pulses so that the position of the electron beam
+can stabilize. If the beam can't stabilize, the picture will not be steady.
+
+In a later section, we'll come back to these basics with definitions,
+formulas and examples to help you use them.
+
+<sect>Basic Things to Know about your Display and Adapter<label id="basic">
+<p>
+
+There are some fundamental things you need to know before hacking an Xconfig
+entry. These are:
+
+<itemize>
+<item>your monitor's horizontal and vertical sync frequency options
+<item>your video adapter's driving clock frequency, or "dot clock"
+<item>your monitor's bandwidth
+</itemize>
+The monitor sync frequencies:
+
+The horizontal sync frequency is just the number of times per second the
+monitor can write a horizontal scan line; it is the single most important
+statistic about your monitor. The vertical sync frequency is the number of
+times per second the monitor can traverse its beam vertically.
+
+Sync frequencies are usually listed on the specifications page of your monitor
+manual. The vertical sync frequency number is typically calibrated in Hz
+(cycles per second), the horizontal one in KHz (kilocycles per second). The
+usual ranges are between 50 and 150Hz vertical, and between 31 and 135KHz
+horizontal.
+
+If you have a multisync monitor, these frequencies will be given as ranges.
+Some monitors, especially lower-end ones, have multiple fixed frequencies.
+These can be configured too, but your options will be severely limited by the
+built-in monitor characteristics. Choose the highest frequency pair for best
+resolution. And be careful --- trying to clock a fixed-frequency monitor at a
+higher speed than it's designed for can easily damage it.
+
+Earlier versions of this guide were pretty cavalier about overdriving
+multisync monitors, pushing them past their nominal highest vertical
+sync frequency in order to get better performance. We have since had more
+reasons pointed out to us for caution on this score; we'll cover those under
+<ref id="overd" name="Overdriving Your Monitor"> below.
+
+The card driving clock frequency:
+
+Your video adapter manual's spec page will usually give you the card's dot
+clock (that is, the total number of pixels per second it can write to the
+screen). If you don't have this information, the X server will get it for
+you. Even if your X locks up your monitor, it will emit a line of clock and
+other info to standard output. If you redirect this to a file, it should be
+saved even if you have to reboot to get your console back. (Recent versions
+of the X servers allsupport a --probeonly option that prints out this
+information and exits without actually starting up X or changing the
+video mode.)
+
+Your X startup message should look something like one of the following
+examples:
+
+If you're using XFree86:
+
+<tscreen><verb>
+Xconfig: /usr/X11R6/lib/X11/Xconfig
+(**) stands for supplied, (--) stands for probed/default values
+(**) Mouse: type: MouseMan, device: /dev/ttyS1, baudrate: 9600
+Warning: The directory "/usr/andrew/X11fonts" does not exist.
+ Entry deleted from font path.
+(**) FontPath set to "/usr/lib/X11/fonts/misc/,/usr/lib/X11/fonts/75dpi/"
+(--) S3: card type: 386/486 localbus
+(--) S3: chipset: 924
+ ---
+ Chipset -- this is the exact chip type; an early mask of the 86C911
+
+(--) S3: chipset driver: s3_generic
+(--) S3: videoram: 1024k
+ -----
+ Size of on-board frame-buffer RAM
+
+(**) S3: clocks: 25.00 28.00 40.00 3.00 50.00 77.00 36.00 45.00
+(**) S3: clocks: 0.00 0.00 79.00 31.00 94.00 65.00 75.00 71.00
+ ------------------------------------------------------
+ Possible driving frequencies in MHz
+
+(--) S3: Maximum allowed dot-clock: 110MHz
+ ------
+ Bandwidth
+(**) S3: Mode "1024x768": mode clock = 79.000, clock used = 79.000
+(--) S3: Virtual resolution set to 1024x768
+(--) S3: Using a banksize of 64k, line width of 1024
+(--) S3: Pixmap cache:
+(--) S3: Using 2 128-pixel 4 64-pixel and 8 32-pixel slots
+(--) S3: Using 8 pages of 768x255 for font caching
+</verb></tscreen>
+
+If you're using SGCS or X/Inside X:
+
+<tscreen><verb>
+WGA: 86C911 (mem: 1024k clocks: 25 28 40 3 50 77 36 45 0 0 79 31 94 65 75 71)
+--- ------ ----- --------------------------------------------
+ | | | Possible driving frequencies in MHz
+ | | +-- Size of on-board frame-buffer RAM
+ | +-- Chip type
+ +-- Server type
+</verb></tscreen>
+
+Note: do this with your machine unloaded (if at all possible). Because X is
+an application, its timing loops can collide with disk activity, rendering the
+numbers above inaccurate. Do it several times and watch for the numbers to
+stabilize; if they don't, start killing processes until they do. SVr4 users:
+the mousemgr process is particularly likely to mess you up.
+
+In order to avoid the clock-probe inaccuracy, you should clip out the clock
+timings and put them in your Xconfig as the value of the Clocks property ---
+this suppresses the timing loop and gives X an exact list of the clock values
+it can try. Using the data from the example above:
+
+<tscreen><verb>
+wga
+ Clocks 25 28 40 3 50 77 36 45 0 0 79 31 94 65 75 71
+</verb></tscreen>
+On systems with a highly variable load, this may help you avoid mysterious X
+startup failures. It's possible for X to come up, get its timings wrong due
+to system load, and then not be able to find a matching dot clock in its
+config database --- or find the wrong one!
+
+<sect1>The monitor's video bandwidth:
+<p>
+
+If you're running XFree86, your server will probe your card and tell you
+what your highest-available dot clock is.
+
+Otherwise, your highest available dot clock is approximately the monitor's
+video bandwidth. There's a lot of give here, though --- some monitors
+can run as much as 30% over their nominal bandwidth. The risks here have
+to do with exceeding the monitor's rated vertical-sync frequency; we'll
+discuss them in detail below.
+
+Knowing the bandwidth will enable you to make more intelligent choices
+between possible configurations. It may affect your display's visual
+quality (especially sharpness for fine details).
+
+Your monitor's video bandwidth should be included on the manual's spec page.
+If it's not, look at the monitor's higest rated resolution. As a rule of
+thumb, here's how to translate these into bandwidth estimates (and thus into
+rough upper bounds for the dot clock you can use):
+
+<tscreen><verb>
+ 640x480 25
+ 800x600 36
+ 1024x768 65
+ 1024x768 interlaced 45
+ 1280x1024 110
+ 1600x1200 185
+</verb></tscreen>
+
+BTW, there's nothing magic about this table; these numbers are just
+the lowest dot clocks per resolution in the standard XFree86 Modes
+database (except for the last, which I interpolated). The bandwidth
+of your monitor may actually be higher than the minimum needed for its
+top resolution, so don't be afraid to try a dot clock a few MHz
+higher.
+
+Also note that bandwidth is seldom an issue for dot clocks under 65MHz
+or so. With an SVGA card and most hi-res monitors, you can't get
+anywhere near the limit of your monitor's video bandwidth. The
+following are examples:
+
+<tscreen><verb>
+ Brand Video Bandwidth
+ ---------- ---------------
+ NEC 4D 75Mhz
+ Nano 907a 50Mhz
+ Nano 9080i 60Mhz
+ Mitsubishi HL6615 110Mhz
+ Mitsubishi Diamond Scan 100Mhz
+ IDEK MF-5117 65Mhz
+ IOCOMM Thinksync-17 CM-7126 136Mhz
+ HP D1188A 100Mhz
+ Philips SC-17AS 110Mhz
+ Swan SW617 85Mhz
+ Viewsonic 21PS 185Mhz
+</verb></tscreen>
+Even low-end monitors usually aren't terribly bandwidth-constrained for their
+rated resolutions. The NEC Multisync II makes a good example --- it can't
+even display 800x600 per its spec. It can only display 800x560. For such low
+resolutions you don't need high dot clocks or a lot of bandwidth; probably the
+best you can do is 32Mhz or 36Mhz, both of them are still not too far from the
+monitor's rated video bandwidth of 30Mhz.
+
+At these two driving frequencies, your screen image may not be as sharp as it
+should be, but definitely of tolerable quality. Of course it would be nicer if
+NEC Multisync II had a video bandwidth higher than, say, 36Mhz. But this is
+not critical for common tasks like text editing, as long as the difference is
+not so significant as to cause severe image distortion (your eyes would tell
+you right away if this were so).
+
+<sect1>What these control:
+<p>
+
+The sync frequency ranges of your monitor, together with your video adapter's
+dot clock, determine the ultimate resolution that you can use. But it's up to
+the driver to tap the potential of your hardware. A superior hardware
+combination without an equally competent device driver is a waste of money.
+On the other hand, with a versatile device driver but less capable hardware,
+you can push the hardware's envelope a little. This is the design philosophy
+of XFree86.
+
+<sect>Interpreting the Basic Specifications<label id="specs">
+<p>
+
+This section explains what the specifications above mean, and some other
+things you'll need to know. First, some definitions. Next to each in parens
+is the variable name we'll use for it when doing calculations
+
+<descrip>
+<tag/horizontal sync frequency (HSF)/
+ Horizontal scans per second (see above).
+
+<tag/vertical sync frequency (VSF) /
+ Vertical scans per second (see above). Mainly important as the upper
+ limit on your refresh rate.
+
+<tag/dot clock (DCF)/
+ More formally, `driving clock frequency'; The frequency of the
+ crystal or VCO on your adaptor --- the maximum dots-per-second it can
+ emit.
+
+<tag/video bandwidth (VB)/
+ The highest frequency you can feed into your monitor's video
+ input and still expect to see anything discernible. If your adaptor
+ produces an alternating on/off pattern, its lowest frequency is half
+ the DCF, so in theory bandwidth starts making sense at DCF/2. For
+ tolerately crisp display of fine details in the video image, however,
+ you don't want it much below your highest DCF, and preferably higher.
+
+<tag/frame length (HFL, VFL)/
+ Horizontal frame length (HFL) is the number of dot-clock ticks
+ needed for your monitor's electron gun to scan one horizontal line,
+ <em>including the inactive left and right borders</em>. Vertical
+ frame length (VFL) is the number of scan lines in the
+ <em>entire</em> image, including the inactive top and bottom
+ borders.
+
+<tag/screen refresh rate (RR)/
+ The number of times per second your screen is repainted (this is
+ also called "frame rate"). Higher frequencies are better, as they
+ reduce flicker. 60Hz is good, VESA-standard 72Hz is better.
+ Compute it as
+<tscreen><verb>
+ RR = DCF / (HFL * VFL)
+</verb></tscreen>
+
+ Note that the product in the denominator is <em>not</em> the same
+ as the monitor's visible resolution, but typically somewhat larger.
+ We'll get to the details of this below.
+
+The rates for which interlaced modes are usually specified (like 87Hz
+interlaced) are actually the half-frame rates: an entire screen seems
+to have about that flicker frequency for typical displays, but every
+single line is refreshed only half as often.
+
+For calculation purposes we reckon an interlaced display at its
+full-frame (refresh) rate, i.e. 43.5Hz. The quality of an interlaced
+mode is better than that of a non-interlaced mode with the same
+full-frame rate, but definitely worse then the non-interlaced one
+corresponding to the half-frame rate.
+</descrip>
+
+<sect1>About Bandwidth:
+<p>
+
+Monitor makers like to advertise high bandwidth because it constrains the
+sharpness of intensity and color changes on the screen. A high bandwidth
+means smaller visible details.
+
+Your monitor uses electronic signals to present an image to
+your eyes. Such signals always come in in wave form once they are converted
+into analog form from digitized form. They can be considered as combinations
+of many simpler wave forms each one of which has a fixed frequency, many of
+them are in the Mhz range, eg, 20Mhz, 40Mhz, or even 70Mhz. Your monitor
+video bandwidth is, effectively, the highest-frequency analog signal it can
+handle without distortion.
+
+For our purposes, bandwidth is mainly important as an approximate cutoff point
+for the highest dot clock you can use.
+
+<sect1>Sync Frequencies and the Refresh Rate:
+<p>
+
+Each horizontal scan line on the display is just the visible portion of a
+frame-length scan. At any instant there is actually only one dot active on
+the screen, but with a fast enough refresh rate your eye's persistence of
+vision enables you to "see" the whole image.
+
+Here are some pictures to help:
+
+<code>
+ _______________________
+ | | The horizontal sync frequency
+ |-&gt;-&gt;-&gt;-&gt;-&gt;-&gt;-&gt;-&gt;-&gt;-&gt;-&gt; | is the number of times per
+ | )| second that the monitor's
+ |&lt;-----&lt;-----&lt;-----&lt;--- | electron beam can trace
+ | | a pattern like this
+ | |
+ | |
+ | |
+ |_______________________|
+ _______________________
+ | ^ | The vertical sync frequency
+ | ^ | | is the number of times per
+ | | v | second that the monitor's
+ | ^ | | electron beam can trace
+ | | | | a pattern like this
+ | ^ | |
+ | | v |
+ | ^ | |
+ |_______|_v_____________|
+</code>
+
+Remember that the actual raster scan is a very tight zigzag pattern; that is,
+the beam moves left-right and at the same time up-down.
+
+Now we can see how the dot clock and frame size relates to refresh rate. By
+definition, one hertz (hz) is one cycle per second. So, if your horizontal
+frame length is HFL and your vertical frame length is VFL, then to cover the
+entire screen takes (HFL * VFL) ticks. Since your card emits DCF ticks per
+second by definition, then obviously your monitor's electron gun(s) can sweep
+the screen from left to right and back and from bottom to top and back DCF /
+(HFL * VFL) times/sec. This is your screen's refresh rate, because it's how
+many times your screen can be updated (thus <em>refreshed</em>) per second!
+
+You need to understand this concept to design a configuration which trades off
+resolution against flicker in whatever way suits your needs.
+
+For those of you who handle visuals better than text, here is one:
+
+<code>
+ RR VB
+ | min HSF max HSF |
+ | | R1 R2 | |
+max VSF -+----|------------/----------/---|------+----- max VSF
+ | |:::::::::::/::::::::::/:::::\ |
+ | \::::::::::/::::::::::/:::::::\ |
+ | |::::::::/::::::::::/:::::::::| |
+ | |:::::::/::::::::::/::::::::::\ |
+ | \::::::/::::::::::/::::::::::::\ |
+ | \::::/::::::::::/::::::::::::::| |
+ | |::/::::::::::/:::::::::::::::| |
+ | \/::::::::::/:::::::::::::::::\|
+ | /\:::::::::/:::::::::::::::::::|
+ | / \:::::::/::::::::::::::::::::|\
+ | / |:::::/:::::::::::::::::::::| |
+ | / \::::/::::::::::::::::::::::| \
+min VSF -+----/-------\--/-----------------------|--\--- min VSF
+ | / \/ | \
+ +--/----------/\------------------------+----\- DCF
+ R1 R2 \ | \
+ min HSF | max HSF
+ VB
+</code>
+
+This is a generic monitor mode diagram. The x axis of the diagram
+shows the clock rate (DCF), the y axis represents the refresh rate
+(RR). The filled region of the diagram describes the monitor's
+capabilities: every point within this region is a possible video
+mode.
+
+The lines labeled `R1' and `R2' represent a fixed resolutions (such as
+640x480); they are meant to illustrate how one resolution can be realized
+by many different combinations of dot clock and refresh rate. The R2
+line would represent a higher resolution than R1.
+
+The top and bottom boundaries of the permitted region are simply
+horizontal lines representing the limiting values for the vertical sync
+frequency. The video bandwidth is an upper limit to the clock rate and
+hence is represented by a vertical line bounding the capability region on
+the right.
+
+Under <ref id="cplot" name="Plotting Monitor Capabilities">) you'll
+find a program that will help you plot a diagram like
+this (but much nicer, with X graphics) for your individual monitor.
+That section also discusses the interesting part; the derivation of
+the boundaries resulting from the limits on the horizontal sync
+frequency.
+
+<sect>Tradeoffs in Configuring your System<label id="trade">
+<p>
+
+Another way to look at the formula we derived above is
+
+<tscreen><verb>
+ DCF = RR * HFL * VFL
+</verb></tscreen>
+That is, your dot clock is fixed. You can use those dots per second to buy
+either refresh rate, horizontal resolution, or vertical resolution. If one
+of those increases, one or both of the others must decrease.
+
+Note, though, that your refresh rate cannot be greater than the maximum
+vertical sync frequency of your monitor. Thus, for any given monitor at a
+given dot clock, there is a minimum product of frame lengths below which you
+can't force it.
+
+In choosing your settings, remember: if you set RR too low, you will get
+mugged by screen flicker.
+
+You probably do not want to pull your refresh rate below 60Hz. This is the
+flicker rate of fluorescent lights; if you're sensitive to those, you need
+to hang with 72Hz, the VESA ergonomic standard.
+
+Flicker is very eye-fatiguing, though human eyes are adaptable and peoples'
+tolerance for it varies widely. If you face your monitor at a 90% viewing
+angle, are using a dark background and a good contrasting color for
+foreground, and stick with low to medium intensity, you *may* be comfortable
+at as little as 45Hz.
+
+The acid test is this: open a xterm with pure white back-ground and black
+foreground using <TT>xterm -bg white -fg black</TT> and make it so large as
+to cover the entire viewable area. Now turn your monitor's intensity to 3/4 of
+its maximum setting, and turn your face away from the monitor. Try peeking at
+your monitor sideways (bringing the more sensitive peripheral-vision cells into
+play). If you don't sense any flicker or if you feel the flickering is
+tolerable, then that refresh rate is fine with you. Otherwise you better
+configure a higher refresh rate, because that semi-invisible flicker is going
+to fatigue your eyes like crazy and give you headaches, even if the screen
+looks OK to normal vision.
+
+For interlaced modes, the amount of flicker depends on more factors
+such as the current vertical resolution and the actual screen
+contents. So just experiment. You won't want to go much below about
+85Hz half frame rate, though.
+
+So let's say you've picked a minimum acceptable refresh rate. In choosing
+your HFL and VFL, you'll have some room for maneuver.
+
+<sect>Memory Requirements<label id="sizes">
+<p>
+
+Available frame-buffer RAM may limit the resolution you can achieve on color or
+gray-scale displays. It probably isn't a factor on displays that have only two
+colors, white and black with no shades of gray in between.
+
+For 256-color displays, a byte of video memory is required for each visible
+dot to be shown. This byte contains the information that determines what mix
+of red, green, and blue is generated for its dot. To get the amount of memory
+required, multiply the number of visible dots per line by the number of
+visible lines. For a display with a resolution of 800x600, this would be 800
+x 600 = 480,000, which is the number of visible dots on the display. This is
+also, at one byte per dot, the number of bytes of video memory that are
+necessary on your adapter card.
+
+Thus, your memory requirement will typically be (HR * VR)/1024 Kbytes of VRAM,
+rounded up. If you have more memory than strictly required, you'll have extra
+for virtual-screen panning.
+
+However, if you only have 512K on board, then you can't use this
+resolution. Even if you have a good monitor, without enough video
+RAM, you can't take advantage of your monitor's potential. On the
+other hand, if your SVGA has one meg, but your monitor can display at
+most 800x600, then high resolution is beyond your reach anyway (see
+<ref id="inter" name="Using Interlaced Modes"> for a possible
+remedy).
+
+Don't worry if you have more memory than required; XFree86 will make
+use of it by allowing you to scroll your viewable area (see the
+Xconfig file documentation on the virtual screen size parameter).
+Remember also that a card with 512K bytes of memory really doesn't
+have 512,000 bytes installed, it has 512 x 1024 = 524,288 bytes.
+
+If you're running SGCS X (now called X/Inside) using an S3 card, and
+are willing to live with 16 colors (4 bits per pixel), you can set
+depth 4 in Xconfig and effectively double the resolution your card can
+handle. S3 cards, for example, normally do 1024x768x256. You can
+make them do 1280x1024x16 with depth 4.
+
+<sect>Computing Frame Sizes<label id="frame">
+<p>
+
+Warning: this method was developed for multisync monitors. It will probably
+work with fixed-frequency monitors as well, but no guarantees!
+
+Start by dividing DCF by your highest available HSF to get a horizontal
+frame length.
+
+For example; suppose you have a Sigma Legend SVGA with a 65MHz dot clock, and
+your monitor has a 55KHz horizontal scan frequency. The quantity (DCF / HSF)
+is then 1181 (65MHz = 65000KHz; 65000/55 = 1181).
+
+Now for our first bit of black magic. You need to round this figure to the
+nearest multiple of 8. This has to do with the VGA hardware controller used by
+SVGA and S3 cards; it uses an 8-bit register, left-shifted 3 bits, for what's
+really an 11-bit quantity. Other card types such as ATI 8514/A may not have
+this requirement, but we don't know and the correction can't hurt. So round
+the usable horizontal frame length figure down to 1176.
+
+This figure (DCF / HSF rounded to a multiple of 8) is the minimum HFL you can
+use. You can get longer HFLs (and thus, possibly, more horizontal dots on the
+screen) by setting the sync pulse to produce a lower HSF. But you'll pay with
+a slower and more visible flicker rate.
+
+As a rule of thumb, 80% of the horizontal frame length is available for
+horizontal resolution, the visible part of the horizontal scan line (this
+allows, roughly, for borders and sweepback time -- that is, the time required
+for the beam to move from the right screen edge to the left edge of the next
+raster line). In this example, that's 944 ticks.
+
+Now, to get the normal 4:3 screen aspect ratio, set your vertical resolution
+to 3/4ths of the horizontal resolution you just calculated. For this
+example, that's 708 ticks. To get your actual VFL, multiply that by 1.05
+to get 743 ticks.
+
+The 4:3 is not technically magic; nothing prevents you from using a
+non-Golden-Section ratio if that will get the best use out of your
+screen real estate. It does make figuring frame height and frame
+width from the diagonal size convenient, you just multiply the
+diagonal by by 0.8 to get width and 0.6 to get height.
+
+So, HFL=1176 and VFL=743. Dividing 65MHz by the product of the two gives
+us a nice, healthy 74.4Hz refresh rate. Excellent! Better than VESA standard!
+And you got 944x708 to boot, more than the 800 by 600 you were probably
+expecting. Not bad at all!
+
+You can even improve the refresh rate further, to almost 76 Hz, by using the
+fact that monitors can often sync horizontally at 2khz or so higher than rated,
+and by lowering VFL somewhat (that is, taking less than 75% of 944 in the
+example above). But before you try this "overdriving" maneuver, if you do,
+make <em>sure</em> that your monitor electron guns can sync up to 76 Hz
+vertical. (the popular NEC 4D, for instance, cannot. It goes only up to 75 Hz
+VSF). (See <ref id="overd" name="Overdriving Your Monitor"> for more general
+discussion of this issue. )
+
+So far, most of this is simple arithmetic and basic facts about raster
+displays. Hardly any black magic at all!
+
+<sect>Black Magic and Sync Pulses<label id="magic">
+<p>
+
+OK, now you've computed HFL/VFL numbers for your chosen dot clock, found the
+refresh rate acceptable, and checked that you have enough VRAM. Now for the
+real black magic -- you need to know when and where to place synchronization
+pulses.
+
+The sync pulses actually control the horizontal and vertical scan frequebcies
+of the monitor. The HSF and VSF you've pulled off the spec sheet are nominal,
+approximate maximum sync frequencies. The sync pulse in the signal from the
+adapter card tells the monitor how fast to actually run.
+
+Recall the two pictures above? Only part of the time required for
+raster-scanning a frame is used for displaying viewable image (ie. your
+resolution).
+
+<sect1>Horizontal Sync:
+<p>
+
+By previous definition, it takes HFL ticks to trace the a horizontal scan line.
+Let's call the visible tick count (your horizontal screen resolution) HR. Then
+Obviously, HR < HFL by definition. For concreteness, let's assume both start
+at the same instant as shown below:
+<code>
+ |___ __ __ __ __ __ __ __ __ __ __ __ __
+ |_ _ _ _ _ _ _ _ _ _ _ _ |
+ |_______________________|_______________|_____
+ 0 ^ ^ unit: ticks
+ | ^ ^ |
+ HR | | HFL
+ | |&lt;-----&gt;| |
+ |&lt;-&gt;| HSP |&lt;-&gt;|
+ HGT1 HGT2
+</code>
+
+Now, we would like to place a sync pulse of length HSP as shown above, ie,
+between the end of clock ticks for display data and the end of clock ticks for
+the entire frame. Why so? because if we can achieve this, then your screen
+image won't shift to the right or to the left. It will be where it supposed to
+be on the screen, covering squarely the monitor's viewable area.
+
+Furthermore, we want about 30 ticks of "guard time" on either side of the sync
+pulse. This is represented by HGT1 and HGT2. In a typical configuration HGT1
+!= HGT2, but if you're building a configuration from scratch, you want to start
+your experimentation with them equal (that is, with the sync pulse centered).
+
+The symptom of a misplaced sync pulse is that the image is displaced on the
+screen, with one border excessively wide and the other side of the image
+wrapped around the screen edge, producing a white edge line and a band of
+"ghost image" on that side. A way-out-of-place vertical sync pulse can
+actually cause the image to roll like a TV with a mis-adjusted vertical hold
+(in fact, it's the same phenomenon at work).
+
+If you're lucky, your monitor's sync pulse widths will be documented on its
+specification page. If not, here's where the real black magic starts...
+
+You'll have to do a little trial and error for this part. But most of the
+time, we can safely assume that a sync pulse is about 3.5 to 4.0 microsecond
+in length.
+
+For concretness again, let's take HSP to be 3.8 microseconds (which btw, is not
+a bad value to start with when experimenting).
+
+Now, using the 65Mhz clock timing above, we know HSP is equivalent to 247 clock
+ticks (= 65 * 10**6 * 3.8 * 10^-6) [recall M=10^6, micro=10^-6]
+
+Some makers like to quote their horizontal framing parameters as timings rather
+than dot widths. You may see the following terms:
+<descrip>
+<tag/active time (HAT)/
+ Corresponds to HR, but in milliseconds. HAT * DCF = HR.
+<tag/blanking time (HBT)/
+ Corresponds to (HFL - HR), but in milliseconds. HBT * DCF = (HFL -
+ HR).
+<tag/front porch (HFP)/
+ This is just HGT1.
+<tag/sync time/
+ This is just HSP.
+<tag/back porch (HBP)/
+ This is just HGT2.
+</descrip>
+
+<sect1>Vertical Sync:
+<p>
+
+Going back to the picture above, how do we place the 247 clock ticks as shown
+in the picture?
+
+Using our example, HR is 944 and HFL is 1176. The difference between the two
+is 1176 - 944=232 < 247! Obviously we have to do some adjustment here. What
+can we do?
+
+The first thing is to raise 1176 to 1184, and lower 944 to 936. Now the
+difference = 1184-936= 248. Hmm, closer.
+
+Next, instead using 3.8, we use 3.5 for calculating HSP; then, we have
+65*3.5=227. Looks better. But 248 is not much higher than 227. It's normally
+necessary to have 30 or so clock ticks between HR and the start of SP, and the
+same for the end of SP and HFL. AND they have to be multiple of eight! Are we
+stuck?
+
+No. Let's do this, 936 % 8 = 0, (936 + 32) % 8 = 0 too. But 936 + 32 = 968,
+968 + 227 = 1195, 1195 + 32 = 1227. Hmm.. this looks not too bad. But it's
+not a multiple of 8, so let's round it up to 1232.
+
+But now we have potential trouble, the sync pulse is no longer placed right in
+the middle between h and H any more. Happily, using our calculator we find
+1232 - 32 = 1200 is also a multiple of 8 and (1232 - 32) - 968 = 232
+corresponding using a sync pulse of 3.57 micro second long, still
+reasonable.
+
+In addition, 936/1232 ~ 0.76 or 76%, still not far from 80%, so it should be
+all right.
+
+Furthermore, using the current horizontal frame length, we basically ask our
+monitor to sync at 52.7khz (= 65Mhz/1232) which is within its capability. No
+problems.
+
+Using rules of thumb we mentioned before, 936*75%=702, This is our new vertical
+resolution. 702 * 1.05 = 737, our new vertical frame length.
+
+Screen refresh rate = 65Mhz/(737*1232)=71.6 Hz. This is still excellent.
+
+Figuring the vertical sync pulse layout is similar:
+<code>
+ |___ __ __ __ __ __ __ __ __ __ __ __ __
+ |_ _ _ _ _ _ _ _ _ _ _ _ |
+ |_______________________|_______________|_____
+ 0 VR VFL unit: ticks
+ ^ ^ ^
+ | | |
+ |&lt;-&gt;|&lt;-----&gt;|
+ VGT VSP
+</code>
+
+We start the sync pulse just past the end of the vertical display data ticks.
+VGT is the vertical guard time required for the sync pulse. Most monitors are
+comfortable with a VGT of 0 (no guard time) and we'll use that in this
+example. A few need two or three ticks of guard time, and it usually doesn't
+hurt to add that.
+
+Returning to the example: since by the defintion of frame length, a vertical
+tick is the time for tracing a complete HORIZONTAL frame, therefore in our
+example, it is 1232/65Mhz=18.95us.
+
+Experience shows that a vertical sync pulse should be in the range of 50us and
+300us. As an example let's use 150us, which translates into 8 vertical clock
+ticks (150us/18.95us~8).
+
+Some makers like to quote their vertical framing parameters as timings rather
+than dot widths. You may see the following terms:
+
+<descrip>
+<tag/active time (VAT)/
+ Corresponds to VR, but in milliseconds. VAT * VSF = VR.
+<tag/blanking time (VBT)/
+ Corresponds to (VFL - VR), but in milliseconds. VBT * VSF = (VFL - VR).
+<tag/front porch (VFP)/
+ This is just VGT.
+<tag/sync time/
+ This is just VSP.
+<tag/back porch (VBP)/
+ This is like a second guard time after the vertical sync pulse. It
+ is often zero.
+</descrip>
+
+<sect>Putting it All Together<label id="synth">
+<p>
+
+The Xconfig file Table of Video Modes contains lines of numbers, with each line
+being a complete specification for one mode of X-server operation. The fields
+are grouped into four sections, the name section, the clock frequency section,
+the horizontal section, and the vertical section.
+
+The name section contains one field, the name of the video mode specified by
+the rest of the line. This name is referred to on the "Modes" line of the
+Graphics Driver Setup section of the Xconfig file. The name field may be
+omitted if the name of a previous line is the same as the current line.
+
+The dot clock section contains only the dot clock (what we've called DCF) field
+of the video mode line. The number in this field specifies what dot clock was
+used to generate the numbers in the following sections.
+
+The horizontal section consists of four fields which specify how each
+horizontal line on the display is to be generated. The first field of the
+section contains the number of dots per line which will be illuminated to form
+the picture (what we've called HR). The second field of the section indicates
+at which dot the horizontal sync pulse will begin. The third field indicates
+at which dot the horizontal sync pulse will end. The fourth field specifies
+the toal horzontal frame length (HFL).
+
+The vertical section also contains four fields. The first field contains the
+number of visible lines which will appear on the display (VR). The second
+field indicates the line number at which the vertical sync pulse will begin.
+The third field specifies the line number at which the vertical sync pulse will
+end. The fourth field contains the total vertical frame length (VFL).
+
+Example:
+<tscreen><verb>
+ #Modename clock horizontal timing vertical timing
+
+ "752x564" 40 752 784 944 1088 564 567 569 611
+ 44.5 752 792 976 1240 564 567 570 600
+</verb></tscreen>
+(Note: stock X11R5 doesn't support fractional dot clocks.)
+
+For Xconfig, all of the numbers just mentioned - the number of illuminated dots
+on the line, the number of dots separating the illuminated dots from the
+beginning of the sync pulse, the number of dots representing the duration of
+the pulse, and the number of dots after the end of the sync pulse - are added
+to produce the number of dots per line. The number of horizontal dots must be
+evenly divisible by eight.
+
+Example horizontal numbers: 800 864 1024 1088
+
+This sample line has the number of illuminated dots (800) followed by the
+number of the dot when the sync pulse starts (864), followed by the number of
+the dot when the sync pulse ends (1024), followed by the number of the last dot
+on the horizontal line (1088).
+
+Note again that all of the horizontal numbers (800, 864, 1024, and 1088) are
+divisible by eight! This is not required of the vertical numbers.
+
+The number of lines from the top of the display to the bottom form the frame.
+The basic timing signal for a frame is the line. A number of lines will
+contain the picture. After the last illuminated line has been displayed, a
+delay of a number of lines will occur before the vertical sync pulse is
+generated. Then the sync pulse will last for a few lines, and finally the last
+lines in the frame, the delay required after the pulse, will be generated. The
+numbers that specify this mode of operation are entered in a manner similar to
+the following example.
+
+Example vertical numbers: 600 603 609 630
+
+This example indicates that there are 600 visible lines on the display, that
+the vertical sync pulse starts with the 603rd line and ends with the 609th, and
+that there are 630 total lines being used.
+
+Note that the vertical numbers don't have to be divisible by eight!
+
+Let's return to the example we've been working. According to the above, all
+we need to do from now on is to write our result into Xconfig as follows:
+<tscreen><verb>
+<name> DCF HR SH1 SH2 HFL VR SV1 SV2 VFL
+</verb></tscreen>
+where SH1 is the start tick of the horizontal sync pulse and SH2 is its end
+tick; similarly, SV1 is the start tick of the vertical sync pulse and SV2 is
+its end tick.
+<tscreen><verb>
+#name clock horizontal timing vertical timing flag
+936x702 65 936 968 1200 1232 702 702 710 737
+</verb></tscreen>
+No special flag necessary; this is a non-interlaced mode. Now we are really
+done.
+
+<sect>Overdriving Your Monitor<label id="overd">
+<p>
+
+You should absolutely <EM>not</EM> try exceeding your monitor's scan
+rates if it's a fixed-frequency type. You can smoke your hardware
+doing this! There are potentially subtler problems with overdriving a
+multisync monitor which you should be aware of.
+
+Having a pixel clock higher than the monitor's maximum bandwidth is
+rather harmless, in contrast. (Note: the theoretical limit of
+discernable features is reached when the pixel clock reaches double
+the monitor's bandwidth. This is a straightforward application of
+Nyquist's Theorem: consider the pixels as a spatially distributed
+series of samples of the drive signals and you'll see why.)
+
+It's exceeding the rated maximum sync frequencies that's problematic.
+Some modern monitors might have protection circuitry that shuts the
+monitor down at dangerous scan rates, but don't rely on it. In
+particular there are older multisync monitors (like the Multisync II)
+which use just one horizontal transformer. These monitors will not
+have much protection against overdriving them. While you necessarily
+have high voltage regulation circuitry (which can be absent in fixed
+frequency monitors), it will not necessarily cover every conceivable
+frequency range, especially in cheaper models. This not only implies
+more wear on the circuitry, it can also cause the screen phosphors to
+age faster, and cause more than the specified radiation (including X-rays)
+to be emitted from the monitor.
+
+Another importance of the bandwidth is that the monitor's input
+impedance is specified only for that range, and using higher
+frequencies can cause reflections probably causing minor screen
+interferences, and radio disturbance.
+
+However, the basic problematic magnitude in question here is the slew
+rate (the steepness of the video signals) of the video output drivers,
+and that is usually independent of the actual pixel frequency, but
+(if your board manufacturer cares about such problems) related
+to the maximum pixel frequency of the board.
+
+So be careful out there...
+
+<sect>Using Interlaced Modes<label id="inter">
+<p>
+
+(This section is largely due to David Kastrup
+&lt;dak@pool.informatik.rwth-aachen.de&gt)
+
+At a fixed dot clock, an interlaced display is going to have
+considerably less noticable flicker than a non-interlaced display, if
+the vertical circuitry of your monitor is able to support it stably.
+It is because of this that interlaced modes were invented in the first
+place.
+
+Interlaced modes got their bad repute because they are inferior to
+their non-interlaced companions at the same vertical scan frequency,
+VSF (which is what is usually given in advertisements). But they are
+definitely superior at the same horizontal scan rate, and that's where
+the decisive limits of your monitor/graphics card usually lie.
+
+At a fixed <EM>refresh rate</EM> (or half frame rate, or VSF) the
+interlaced display will flicker more: a 90Hz interlaced display will
+be inferior to a 90Hz non-interlaced display. It will, however, need
+only half the video bandwidth and half the horizontal scan rate. If
+you compared it to a non-interlaced mode with the same dot clock and
+the same scan rates, it would be vastly superior: 45Hz non-interlaced
+is intolerable. With 90Hz interlaced, I have worked for years with my
+Multisync 3D (at 1024x768) and am very satisfied. I'd guess you'd need
+at least a 70Hz non-interlaced display for similar comfort.
+
+You have to watch a few points, though: use interlaced modes only at
+high resolutions, so that the alternately lighted lines are close
+together. You might want to play with sync pulse widths and positions
+to get the most stable line positions. If alternating lines are bright
+and dark, interlace will <EM>jump</EM> at you. I have one application that
+chooses such a dot pattern for a menu background (XCept, no other
+application I know does that, fortunately). I switch to 800x600 for
+using XCept because it really hurts my eyes otherwise.
+
+For the same reason, use at least 100dpi fonts, or other fonts where
+horizontal beams are at least two lines thick (for high resolutions,
+nothing else will make sense anyhow).
+
+And of course, never use an interlaced mode when your hardware would
+support a non-interlaced one with similar refresh rate.
+
+If, however, you find that for some resolution you are pushing either
+monitor or graphics card to their upper limits, and getting
+dissatisfactorily flickery or outwashed (bandwidth exceeded) display,
+you might want to try tackling the same resolution using an
+interlaced mode. Of course this is useless if the VSF
+of your monitor is already close to its limits.
+
+Design of interlaced modes is easy: do it like a non-interlaced
+mode. Just two more considerations are necessary: you need an odd
+total number of vertical lines (the last number in your mode line), and
+when you specify the "interlace" flag, the actual vertical frame rate
+for your monitor doubles. Your monitor needs to support a 90Hz frame
+rate if the mode you specified looks like a 45Hz mode apart from the
+"Interlace" flag.
+
+As an example, here is my modeline for 1024x768 interlaced: my
+Multisync 3D will support up to 90Hz vertical and 38kHz horizontal.
+
+<tscreen><verb>
+ModeLine "1024x768" 45 1024 1048 1208 1248 768 768 776 807 Interlace
+</verb></tscreen>
+
+Both limits are pretty much exhausted with this mode. Specifying the
+same mode, just without the "Interlace" flag, still is almost at the
+limit of the monitor's horizontal capacity (and strictly speaking, a
+bit under the lower limit of vertical scan rate), but produces an
+intolerably flickery display.
+
+Basic design rules: if you have designed a mode at less than half of
+your monitor's vertical capacity, make the vertical total of lines odd
+and add the "Interlace" flag. The display's quality should vastly
+improve in most cases.
+
+If you have a non-interlaced mode otherwise exhausting your monitor's
+specs where the vertical scan rate lies about 30% or more under the
+maximum of your monitor, hand-designing an interlaced mode (probably
+with somewhat higher resolution) could deliver superior results, but I
+won't promise it.
+
+<sect>Questions and Answers<label id="answe">
+<p>
+
+ Q. The example you gave is not a standard screen size, can I use it?
+
+ A. Why not? There is NO reason whatsover why you have to use 640x480,
+800x600, or even 1024x768. The XFree86 servers let you configure your hardware
+with a lot of freedom. It usually takes two to three tries to come up the
+right one. The important thing to shoot for is high refresh rate with
+reasonable viewing area. not high resolution at the price of eye-tearing
+flicker!
+
+ Q. It this the only resolution given the 65Mhz dot clock and 55Khz HSF?
+
+ A. Absolutely not! You are encouraged to follow the general procedure and
+do some trial-and-error to come up a setting that's really to your liking.
+Experimenting with this can be lots of fun. Most settings may just give you
+nasty video hash, but in practice a modern multi-sync monitor is usually not
+damaged easily. Be sure though, that your monitor can support the frame
+rates of your mode before using it for longer times.
+
+ Beware fixed-frequency monitors! This kind of hacking around can damage
+them rather quickly. Be sure you use valid refresh rates for <EM>every</EM>
+experiment on them.
+
+ Q. You just mentioned two standard resolutions. In Xconfig, there are many
+standard resolutions available, can you tell me whether there's any point in
+tinkering with timings?
+
+ A. Absolutely! Take, for example, the "standard" 640x480 listed in the
+current Xconfig. It employes 25Mhz driving frequency, frame lengths are 800
+and 525 => refresh rate ~ 59.5Hz. Not too bad. But 28Mhz is a commonly
+available driving frequency from many SVGA boards. If we use it to drive
+640x480, following the procedure we discussed above, you would get frame
+lengths like 812 and 505. Now the refresh rate is raised to 68Hz, a
+quite significant improvement over the standard one.
+
+ Q. Can you summarize what we have discussed so far?
+
+ A. In a nutshell:
+
+<enum>
+<item>
+for any fixed driving frequency, raising max resolution incurs the penalty
+of lowering refresh rate and thus introducing more flicker.
+<item>
+if high resolution is desirable and your monitor supports it, try to
+get a SVGA card that provides a matching dot clock or DCF. The higher,
+the better!
+</enum>
+
+<sect>Fixing Problems with the Image.<label id="fixes">
+<p>
+
+OK, so you've got your X configuration numbers. You put them in Xconfig with
+a test mode label. You fire up X, hot-key to the new mode, ... and the image
+doesn't look right. What do you do? Here's a list of common problems and how
+to fix them.
+
+(Fixing these minor distortions is where <bf>xvidtune</bf>(1) really shines.)
+
+You <em>move</em> the image by changing the sync pulse timing. You
+<em>scale</em> it by changing the frame length (you need to move the
+sync pulse to keep it in the same relative position, otherwise scaling will
+move the image as well). Here are some more specific recipes:
+
+The horizontal and vertical positions are independent. That is, moving the
+image horizontally doesn't affect placement vertically, or vice-versa.
+However, the same is not quite true of scaling. While changing the horizontal
+size does nothing to the vertical size or vice versa, the total change in both
+may be limited. In particular, if your image is too large in both dimensions
+you will probably have to go to a higher dot clock to fix it. Since this
+raises the usable resolution, it is seldom a problem!
+
+<sect1>The image is displaced to the left or right
+<p>
+
+To fix this, move the horizontal sync pulse. That is, increment or decrement
+(by a multiple of 8) the middle two numbers of the horizontal timing section
+that define the leading and trailing edge of the horizontal sync pulse.
+
+If the image is shifted left (right border too large, you want to move
+the image to the right) decrement the numbers. If the image is shifted right
+(left border too large, you want it to move left) increment the sync pulse.
+
+<sect1>The image is displaced up or down
+<p>
+
+To fix this, move the vertical sync pulse. That is, increment or decrement the
+middle two numbers of the vertical timing section that define the leading and
+trailing edge of the vertical sync pulse.
+
+If the image is shifted up (lower border too large, you want to move the image
+down) decrement the numbers. If the image is shifted down (top border too
+large, you want it to move up) increment the numbers.
+
+<sect1>The image is too large both horizontally and vertically
+<p>
+
+Switch to a higher card clock speed. If you have multiple modes in your
+clock file, possibly a lower-speed one is being activated by mistake.
+
+<sect1>The image is too wide (too narrow) horizontally
+<p>
+
+To fix this, increase (decrease) the horizontal frame length. That is, change
+the fourth number in the first timing section. To avoid moving the image, also
+move the sync pulse (second and third numbers) half as far, to keep it in the
+same relative position.
+
+<sect1>The image is too deep (too shallow) vertically
+<p>
+
+To fix this, increase (decrease) the vertical frame length. That is, change
+the fourth number in the second timing section. To avoid moving the image,
+also move the sync pulse (second and third numbers) half as far, to keep it in
+the same relative position.
+
+Any distortion that can't be handled by combining these techniques is probably
+evidence of something more basically wrong, like a calculation mistake or a
+faster dot clock than the monitor can handle.
+
+Finally, remember that increasing either frame length will decrease your
+refresh rate, and vice-versa.
+
+<sect>Plotting Monitor Capabilities<label id="cplot">
+<p>
+
+To plot a monitor mode diagram, you'll need the gnuplot package (a
+freeware plotting language for UNIX-like operating systems) and the
+tool <TT>modeplot</TT>, a shell/gnuplot script to plot the diagram from your
+monitor characteristics, entered as command-line options.
+
+Here is a copy of modeplot:
+
+<code>
+#!/bin/sh
+#
+# modeplot -- generate X mode plot of available monitor modes
+#
+# Do `modeplot -?' to see the control options.
+#
+# ($Id: VidModes.sgml,v 1.1.1.1 1999/12/05 01:17:39 daryll Exp $)
+
+# Monitor description. Bandwidth in MHz, horizontal frequencies in kHz
+# and vertical frequencies in Hz.
+TITLE="Viewsonic 21PS"
+BANDWIDTH=185
+MINHSF=31
+MAXHSF=85
+MINVSF=50
+MAXVSF=160
+ASPECT="4/3"
+vesa=72.5 # VESA-recommended minimum refresh rate
+
+while [ "$1" != "" ]
+do
+ case $1 in
+ -t) TITLE="$2"; shift;;
+ -b) BANDWIDTH="$2"; shift;;
+ -h) MINHSF="$2" MAXHSF="$3"; shift; shift;;
+ -v) MINVSF="$2" MAXVSF="$3"; shift; shift;;
+ -a) ASPECT="$2"; shift;;
+ -g) GNUOPTS="$2"; shift;;
+ -?) cat <<EOF
+modeplot control switches:
+
+-t "<description>" name of monitor defaults to "Viewsonic 21PS"
+-b <nn> bandwidth in MHz defaults to 185
+-h <min> <max> min & max HSF (kHz) defaults to 31 85
+-v <min> <max> min & max VSF (Hz) defaults to 50 160
+-a <aspect ratio> aspect ratio defaults to 4/3
+-g "<options>" pass options to gnuplot
+
+The -b, -h and -v options are required, -a, -t, -g optional. You can
+use -g to pass a device type to gnuplot so that (for example) modeplot's
+output can be redirected to a printer. See gnuplot(1) for details.
+
+The modeplot tool was created by Eric S. Raymond <esr@thyrsus.com> based on
+analysis and scratch code by Martin Lottermoser <Martin.Lottermoser@mch.sni.de>
+
+This is modeplot $Revision: 1.1.1.1 $
+EOF
+ exit;;
+ esac
+ shift
+done
+
+gnuplot $GNUOPTS <<EOF
+set title "$TITLE Mode Plot"
+
+# Magic numbers. Unfortunately, the plot is quite sensitive to changes in
+# these, and they may fail to represent reality on some monitors. We need
+# to fix values to get even an approximation of the mode diagram. These come
+# from looking at lots of values in the ModeDB database.
+F1 = 1.30 # multiplier to convert horizontal resolution to frame width
+F2 = 1.05 # multiplier to convert vertical resolution to frame height
+
+# Function definitions (multiplication by 1.0 forces real-number arithmetic)
+ac = (1.0*$ASPECT)*F1/F2
+refresh(hsync, dcf) = ac * (hsync**2)/(1.0*dcf)
+dotclock(hsync, rr) = ac * (hsync**2)/(1.0*rr)
+resolution(hv, dcf) = dcf * (10**6)/(hv * F1 * F2)
+
+# Put labels on the axes
+set xlabel 'DCF (MHz)'
+set ylabel 'RR (Hz)' 6 # Put it right over the Y axis
+
+# Generate diagram
+set grid
+set label "VB" at $BANDWIDTH+1, ($MAXVSF + $MINVSF) / 2 left
+set arrow from $BANDWIDTH, $MINVSF to $BANDWIDTH, $MAXVSF nohead
+set label "max VSF" at 1, $MAXVSF-1.5
+set arrow from 0, $MAXVSF to $BANDWIDTH, $MAXVSF nohead
+set label "min VSF" at 1, $MINVSF-1.5
+set arrow from 0, $MINVSF to $BANDWIDTH, $MINVSF nohead
+set label "min HSF" at dotclock($MINHSF, $MAXVSF+17), $MAXVSF + 17 right
+set label "max HSF" at dotclock($MAXHSF, $MAXVSF+17), $MAXVSF + 17 right
+set label "VESA $vesa" at 1, $vesa-1.5
+set arrow from 0, $vesa to $BANDWIDTH, $vesa nohead # style -1
+plot [dcf=0:1.1*$BANDWIDTH] [$MINVSF-10:$MAXVSF+20] \
+ refresh($MINHSF, dcf) notitle with lines 1, \
+ refresh($MAXHSF, dcf) notitle with lines 1, \
+ resolution(640*480, dcf) title "640x480 " with points 2, \
+ resolution(800*600, dcf) title "800x600 " with points 3, \
+ resolution(1024*768, dcf) title "1024x768 " with points 4, \
+ resolution(1280*1024, dcf) title "1280x1024" with points 5, \
+ resolution(1600*1280, dcf) title "1600x1200" with points 6
+
+pause 9999
+EOF
+</code>
+
+Once you know you have <TT>modeplot</TT> and the gnuplot package in
+place, you'll need the following monitor characteristics:
+
+<itemize>
+<item> video bandwidth (VB)
+<item> range of horizontal sync frequency (HSF)
+<item> range of vertical sync frequency (VSF)
+</itemize>
+
+The plot program needs to make some simplifying assumptions which are
+not necessarily correct. This is the reason why the resulting diagram is
+only a rough description. These assumptions are:
+
+<enum>
+<item> All resolutions have a single fixed aspect ratio AR = HR/VR.
+Standard resolutions have AR = 4/3 or AR = 5/4. The <TT>modeplot</TT>
+programs assumes 4/3 by default, but you can override this.
+<item> For the modes considered, horizontal and vertical frame lengths are
+fixed multiples of horizontal and vertical resolutions, respectively:
+
+<tscreen><verb>
+ HFL = F1 * HR
+ VFL = F2 * VR
+</verb></tscreen>
+</enum>
+
+As a rough guide, take F1 = 1.30 and F2 = 1.05 (see <ref id=frame>
+"Computing Frame Sizes").
+
+Now take a particular sync frequency, HSF. Given the assumptions just
+presented, every value for the clock rate DCF already determines the
+refresh rate RR, i.e. for every value of HSF there is a function RR(DCF).
+This can be derived as follows.
+
+The refresh rate is equal to the clock rate divided by the product of the
+frame sizes:
+
+<tscreen><verb>
+ RR = DCF / (HFL * VFL) (*)
+</verb></tscreen>
+
+On the other hand, the horizontal frame length is equal to the clock rate
+divided by the horizontal sync frequency:
+
+<tscreen><verb>
+ HFL = DCF / HSF (**)
+</verb></tscreen>
+
+VFL can be reduced to HFL be means of the two assumptions above:
+
+<tscreen><verb>
+ VFL = F2 * VR
+ = F2 * (HR / AR)
+ = (F2/F1) * HFL / AR (***)
+</verb></tscreen>
+
+Inserting (**) and (***) into (*) we obtain:
+
+<tscreen><verb>
+ RR = DCF / ((F2/F1) * HFL**2 / AR)
+ = (F1/F2) * AR * DCF * (HSF/DCF)**2
+ = (F1/F2) * AR * HSF**2 / DCF
+</verb></tscreen>
+
+For fixed HSF, F1, F2 and AR, this is a hyperbola in our diagram. Drawing
+two such curves for minimum and maximum horizontal sync frequencies we
+have obtained the two remaining boundaries of the permitted region.
+
+The straight lines crossing the capability region represent particular
+resolutions. This is based on (*) and the second assumption:
+
+<tscreen><verb>
+ RR = DCF / (HFL * VFL) = DCF / (F1 * HR * F2 * VR)
+</verb></tscreen>
+
+By drawing such lines for all resolutions one is interested in, one
+can immediately read off the possible relations between resolution,
+clock rate and refresh rate of which the monitor is capable. Note that
+these lines do not depend on monitor properties, but they do depend on
+the second assumption.
+
+The <TT>modeplot</TT> tool provides you with an easy way to do this. Do
+<TT>modeplot -?</TT> to see its control options. A typical invocation
+looks like this:
+
+<tscreen><verb>
+ modeplot -t "Swan SW617" -b 85 -v 50 90 -h 31 58
+</verb></tscreen>
+
+The -b option specifies video bandwidth; -v and -h set horizontal and
+vertical sync frequency ranges.
+
+When reading the output of <TT>modeplot</TT>, always bear in mind that
+it gives only an approximate description. For example, it disregards
+limitations on HFL resulting from a minimum required sync pulse width,
+and it can only be accurate as far as the assumptions are. It is
+therefore no substitute for a detailed calculation (involving some
+black magic) as presented in <ref id="synth" name="Putting it All
+Together">. However, it should give you a better feeling for what
+is possible and which tradeoffs are involved.
+
+<sect>Credits<label id="credi">
+<p>
+
+The original ancestor of this document was by Chin Fang
+&lt;fangchin@leland.stanford.edu&gt;.
+
+Eric S. Raymond &lt;esr@snark.thyrsus.com&gt; reworked, reorganized, and
+massively rewrote Chin Fang's original in an attempt to understand it. In
+the process, he merged in most of a different how-to by Bob Crosson
+&lt;crosson@cam.nist.gov&gt;.
+
+The material on interlaced modes is largely by David Kastrup
+&lt;dak@pool.informatik.rwth-aachen.de&gt;
+
+Martin Lottermoser &lt;Martin.Lottermoser@mch.sni.de&gt; contributed
+the idea of using gnuplot to make mode diagrams and did the
+mathematical analysis behind <TT>modeplot</TT>. The distributed
+<TT>modeplot</TT> was redesigned and generalized by ESR from
+Martin's original gnuplot code for one case.
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/VidModes.sgml,v 3.14 1997/11/16 10:52:47 dawes Exp $
+
+
+
+
+
+$XConsortium: VidModes.sgml /main/7 1996/02/21 17:46:17 kaleb $
+</verb>
+
+</article>
+
+<!--
+The following sets edit modes for GNU EMACS
+Local Variables:
+fill-prefix:"\t"
+fill-column:75
+End:
+-- >
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/Video7.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/Video7.sgml
new file mode 100644
index 000000000..ddddd968c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/Video7.sgml
@@ -0,0 +1,107 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+<article>
+
+<!-- TitleS information -->
+
+<title>README.VIDEO7
+<author>Craig Struble
+<date>17 May 1994
+
+<!-- Table of contents -->
+<toc>
+
+<!-- Begin the document -->
+
+<sect>The Driver:<p>
+The Video7 driver has only been tested on a Headland Technologies HT216-32
+chip, but should work on other Video 7/Headland Technologies chips as
+well.<p>
+
+Currently this implementation of the video7 driver only supports single bank
+mode, which can cause performance degradation, and makes no attempt to
+distinguish between the different video7 chips.<p>
+
+It also does not probe for memory, so in your <tt>XF86Config</tt> file,
+make sure that you use the following line:<p>
+<verb>
+ Videoram XXX
+</verb>
+Where XXX is the amount of RAM in your card. Most of them have at least
+512k, so this is a good value to start with.<p>
+Also, the clock probing function of XFree86 doesn't seem to correctly
+get the clocks. The documentation I used (vgadoc3) suggests using the
+following values for the <tt>Clocks line</tt> in your
+<tt>XF86Config</tt> file:
+<verb>
+ Clocks 25.175 28.322 30.000 32.514 34.000 36.000 38.000 40.000
+</verb>
+For 800x600 mode, use a dot clock of 38 instead of 36 or 40 as suggested in
+most of the sample <tt>XF86Config</tt> files and <tt>modeDB.txt.</tt>
+This seems to be what is
+used in the BIOS mode (0x69) which is the 800x600 in 256 colors.
+
+<sect>Known bugs and What's been tested:<p>
+<sect1>Known bugs:<p>
+<enum>
+<item>No video ram probing. Only known way to get this info is through
+an INT 10 call, but you can't do this in a user process.<p>
+<item>Clock probing. I'm not sure the docs in vgadoc3 are correct.<p>
+<item>Random lockups with the SVGA server<p>
+</enum>
+<sect1>What's been tested:<p>
+<enum>
+<item>An HT216-32 chip.<p>
+<item>800x600 mode and 640x480 mode<p>
+<item>Mode switching and switching to text mode through <tt>CTRL-ALT-F1</tt><p>
+<item>Only been tested on Linux.<p>
+</enum>
+
+<sect>Who to contact:<p>
+ <bf>Craig Struble</bf> (<em/cstruble@acm.vt.edu/) Video 7 driver<p>
+<sect>Acknowledgments<p>
+<sect1>Thanks to:<p>
+<itemize>
+<item><bf/Cara Cocking/ for loving me and supporting me. Without her I'd
+ be a bowl of jello.<p>
+<item><bf/XFree86 team/ for the great stub code that allowed me to get this
+ going.<p>
+<item><bf/Finn Thoegersen/ for compiling vgadoc3. Without this I would not
+ have had a clue.<p>
+<item><bf/Harm Hanemaayer/ for the vga.c program in svgalib. Without this I
+ would not have had the breakthroughs I needed to get the thing
+ up and running.<p>
+</itemize>
+<sect1>Other things I've already done:<p>
+<quote>
+ For Linux, I have a small patch to get the extended text modes to
+ work on the Video 7 card.<p>
+</quote>
+
+<sect1>Things to do:<p>
+<itemize>
+<item> Try dual banking mode.<p>
+<item> Write an svgalib driver.<p>
+<item> Go back to graduate school. (I'm a glutton for punishment.)<p>
+</itemize>
+
+<sect1>Disclaimer:<p>
+<quote>
+ CRAIG STRUBLE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ NO EVENT SHALL CRAIG STRUBLE 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.<p>
+</quote>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/Video7.sgml,v 3.5 1997/01/24 09:32:34 dawes Exp $
+
+
+
+
+
+$XConsortium: Video7.sgml /main/3 1996/02/21 17:46:22 kaleb $
+</verb>
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/WstDig.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/WstDig.sgml
new file mode 100644
index 000000000..f7bc28f25
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/WstDig.sgml
@@ -0,0 +1,217 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+<article>
+
+<title> Information for Western Digital Chipset Users
+<author> The XFree86 Project, Inc.
+<date> 14 July 1995
+<toc>
+
+<sect> Supported chipsets <p>
+XFree86 supports the following Western Digital SVGA chipsets: PVGA1,
+WD90C00, WD90C10, WD90C11, WD90C24, WD90C30, WD90C31, WD90C33. Note that
+the rest of the WD90C2x series of LCD-controller chipsets are still not
+supported. The WD90C24 family is now supported including acceleration,
+adjustable clocks and a full 1MB video ram even on dual scan systems (in
+CRT mode). If you have trouble with the new WD90C24 support (not that we
+expect you will), try specifying "wd90c30" or "wd90c31" on the `Chipset'
+line in your <tt>XF86Config</tt> file. The WD90C24, WD90C31 and WD90C33
+are supported as an accelerated chipset in the SVGA server; the
+accelerated features are automatically activated when a WD90C24, WD90C31
+or WD90C33 is detected, or specified in the <tt>XF86Config</tt> file.
+
+<sect> Special considerations <p>
+All of the Western Digital chipsets after the PVGA1 support the ability
+to use the memory-refresh clock as an alternate dot-clock for video
+timing. Hence for all of these chipsets, the server will detect one more
+clocks than ``normal''. What this means is that if you have an old
+`<tt>Clocks</tt>'
+line in your <tt>XF86Config</tt> file, you should comment it out, and rerun
+the server with the `<tt>-probeonly</tt>' option to find all of the clock
+values. All but the
+last should be the same as what you had before; the last will be new.
+
+For the WD90C00 chipset, the chipset will only support 640x480 in 256-color
+mode. Even though 512k of memory should allow better than 800x600, the
+chipset itself cannot do this. This is stated in the databook (which lists
+1024x768x16 and 640x480x256 for specifications). We have also witnessed
+this behavior.
+
+The server will detect 17 clocks for the WD90C24, WD90C30 and WD90C31
+chipsets. If you have one of these chipsets, you should let the server
+re-probe the clocks and update your <tt>XF86Config</tt>.
+
+There is an `<tt>Option</tt>' flag available for the <tt>XF86Config</tt>
+file that is specific to the Western Digital chipsets (except the
+WD90C24). This option is <tt>"swap_hibit"</tt>. We have determined via
+experimentation that the WD90C1x and WD90C3x chipsets need the high-order
+clock-select bit inverted, and the PVGA1 and WD90C00 need it
+non-inverted. This is hardcoded into the driver. Since our sample-set
+was rather small, we have provided the <tt>"swap_hibit"</tt> option to
+invert this behavior. If the clocks detected by the server show a very
+low last clock (under 28Mhz), then this option is likely needed.
+
+<sect> WD90C24 features <p>
+These next three sections apply only if you have a WD90C24, WD90C24a,
+or WD90C24a2 and don't specify some other chipset in your XF86Config
+file. The SVGA pvga1 driver now recognizes the wd90c24 family as
+different from the WD90C30 and seems to resolve most of the problems
+people encountered when these chips were treated as WD90C3X. The
+new code has the following features:
+<p>
+<itemize>
+<item>Locks the shadow registers at appropriate times; This should
+ prevent scrambled displays after exiting X with dual scan screens
+ when simultaneous or LCD display mode is selected. The code does
+ depend somewhat on the behavior of the BIOS regarding when it
+ locks the shadow registers, etc.
+<item>Allows (forces) the use of a full 1 Meg VRAM for dual scan systems
+ when the server is started while external CRT only display is in
+ operation. This allows 1024x768x8 resolution.
+<item>If the <tt/XF86Config/ file specifies a virtual screen size which
+ requires more than 512 K VRAM when the server is started on a Dual
+ Scan LCD, the driver will force the virtual size to 640x480. This
+ eliminates the need to edit the <tt/XF86Config/ file when you switch
+ from 1024x resolution on the CRT, to or from the LCD screen. If
+ no virtual size is specified, the result will be 800x600 virtual
+ in LCD modes and 1024x768 in CRT only mode (so you have a choice).
+<item>Note that on dual scan systems, you must still exit X, switch
+ displays, and restart X to change to/from CRT only with 1 Meg
+ videoram. This is because once the server starts, you can't change
+ the virtual screen size. There is no way around this with the
+ current server and the WD90C24 with dual scan displays. The
+ WD90C24 requires half the videoram be used for a ``Frame buffer'' when
+ the dual scan LCD is in use.
+<item>The new server uses the accelerated features of the WD90C24a. It
+ is not clear from the data book if the WD90C24 also supports ALL
+ the required features. Several people have stated that the
+ WD90C24 is not accelerated, but the differences section of the
+ WD90c24a data book implies that they ARE all three accelerated.
+ The differences documented with regard to acceleration are with
+ the type of line drawing the hardware does; Only the newer chips
+ support the type of line drawing that MS windows wants. This may
+ be what has caused the confusion since the accelerated windows
+ drivers may only support the WD90c24a chips. If this turns out to be
+ a problem with the WD90C24, acceleration can be disabled by adding
+ the line:
+ <verb>
+ Option "noaccel"
+ </verb>
+ to the Device section of the <tt/XF86Config/ file.
+<item>Although the new server does not support programmable clocks in the
+ same way as some of the other servers, 8 of the 17 clocks may be
+ set to (almost) any value via the Clocks line. It also supports
+ options for adjusting the VRAM clock.
+</itemize>
+
+<sect>WD90C24 clocks <p>
+Here are some more details on the adjustable clocks:
+
+The VRAM clock (Mclk) is adjusted by adding ONE of the following
+option lines to the Device section of the <tt/XF86Config/:
+<tscreen><verb>
+ Option "slow_dram" # Set Mclk to 47.429 MHz
+ Option "med_dram" # Set Mclk to 49.219 MHz
+ Option "fast_dram" # Set Mclk to 55.035 MHz
+</verb></tscreen>
+The default is to leave Mclk as the BIOS sets it. This is 44.297 on
+many systems. Some systems may not work properly with any of these
+options. If you experience ``bit errors'' on your display, reduce the
+Mclk speed, or don't use any of these options. The Mclk is not reset
+on server exit.
+
+The data book says that the maximum pixel clock is 1.6 times Mclk so
+you may want to experiment with higher Mclk rates if you have a fast
+monitor. It also says a 44.297MHz Mclk and 65MHz pixel clock is the
+fastest the WD90C24A2 is designed to go. However, some success has
+been reported with faster clocks. Don't expect all the clocks the
+chip can provide to work properly.
+
+The second and fourth group of 4 clocks are adjustable. That is,
+clocks 5, 6, 7, 8 and 13, 14, 15, 16 (counting from 1). These clocks are
+set by the Clocks line. Be sure to adjust the 17th (last) clock to
+match your Mclk. Here is a sample set of clocks lines with some
+clocks defined which are not directly provided by the chip. The
+NON-programmable clocks (1-4 and 9-12) MUST be set as indicated
+here.
+
+<verb>
+ Clocks 25.175 28.322 65 36 # These are *not* programmable
+
+ Clocks 29.979 77.408 62.195 59.957 # these are programmable
+ Clocks 31.5 35.501 75.166 50.114 # these are *not* programmable
+ Clocks 39.822 72.038 44.744 80.092 # these are programmable
+ Clocks 44.297 # Change this if you change
+ # Mclk above.
+</verb>
+
+You can program the clocks in increments of .447443 MHz. The server
+will warn you and adjust to the nearest increment if you specify a
+clock which does not fit this formula. Clocks 1-4 and 9-12 (the
+fixed clocks) are not constrained to this multiple, but instead are
+used to provide standard clocks which are not a multiple by .447443 MHz.
+
+If you probe for clocks (for example to find your Mclk), do it in
+CRT only mode and then add clocks lines in your <tt/XF86Config/ file.
+Clocks will not probe correctly in LCD mode on most systems.
+
+The BIOS on some systems may not allow switching from CRT to LCD
+unless the correct clock and/or mode is used. Try the following
+mode line for 640x480 LCD displays.
+<verb>
+ ModeLine "640x480" 25.175 640 664 760 800 480 491 493 525 #CRT/LCD
+</verb>
+
+The following modelines have been tested with the above Clocks lines
+on some systems, and are provided here as examples. Some testers
+have experienced minor problems (snow) with the fixed 65 and 75.166
+MHz dot clocks. The modelines below have been reported to circumvent
+these problems. Do not assume your monitor will not be damaged by
+any of these.
+
+<verb>
+ # VESA 800x600@72Hz Non-Interlaced mode
+ ModeLine "800x600.50" 50 800 856 976 1040 600 637 643 666 +hsync +vsync
+
+
+ # 1024x768 Interlaced mode
+ ModeLine "1024x768i" 45 1024 1048 1208 1264 768 776 784 817 +hsync +vsync Interlace
+
+ # 1024x768@60Hz Non-interlaced Mode
+ # One of the dram options may be necessary
+ ModeLine "1024x768.65" 65 1024 1032 1176 1344 768 771 777 806 -hsync -vsync
+
+
+ # 1024x768@60Hz Non-Interlaced mode (non-standard dot-clock)
+ # Seems to work without dram options
+ ModeLine "1024x768.62" 62 1024 1064 1240 1280 768 774 776 808
+
+ # 1024x768@70Hz Non-Interlaced mode (non-standard dot-clock)
+ # May need fast_dram option
+ ModeLine "1024x768.72" 72 1024 1056 1192 1280 768 770 776 806 -hsync -vsync
+
+</verb>
+
+<sect> Additional WD90C24 information <p>
+Standard disclaimers apply. Use this driver at your own risk. If you
+need additional information on using XFree86 with the WD90C24 family
+however, you might try <url url="http://www.castle.net/&tilde;darin"
+name="Darin Ernst's home page">. Darin maintains a mini-HOWTO on ``X and
+the WD90C24''. He was the first tester of the WD90C24 code and provided
+many good ideas and encouragement. You can reach Darin at
+<it>darin@castle.net</it> or <it>dernst@pppl.gov</it>. I only provided
+the WD90C24 specific code. You can reach me (Brad Bosch) at
+<it>brad@Lachman.com</it>.
+
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/WstDig.sgml,v 3.6 1997/01/24 09:32:38 dawes Exp $
+
+
+
+
+
+$XConsortium: WstDig.sgml /main/5 1996/02/21 17:46:29 kaleb $
+</verb>
+
+</article>
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/add.sh b/xc/programs/Xserver/hw/xfree86/doc/sgml/add.sh
new file mode 100644
index 000000000..f3d167100
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/add.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+#
+# $XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/add.sh,v 1.1 1999/08/23 09:06:04 dawes Exp $
+#
+name=`basename $1 .sgml`
+sgmlfmt -f index $name.sgml | \
+ sed -e 's,<title>,<item><htmlurl name=",' \
+ -e 's,</title>," url="'$name.html'">,' \
+ -e 's,<author>,<!-- ,' \
+ -e 's,</author>, -->,' \
+ -e 's,<date>,<!-- ,' \
+ -e 's,</date>, -->,' >> index.sgml
+exit 0
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/agx.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/agx.sgml
new file mode 100644
index 000000000..3faee3acb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/agx.sgml
@@ -0,0 +1,615 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+<article>
+
+<!-- Title information -->
+
+<title>Notes on the AGX Server
+<author>Henry Worth
+<date>24 June 1995
+
+<!-- Table of contents -->
+<toc>
+
+<!-- Begin the document -->
+
+
+<sect>General Notes<p>
+
+ This server currently supports the IIT AGX-016, AGX-015, AGX-014
+ and XGA-2 chipsets. The AGX chipset is based on XGA architecture,
+ but is missing several features and differs on others. There's
+ also untested support for the XGA-1 and AGX-010 chipsets.
+ Pixel depths of 8bpp, 15bpp, 16bpp are generally supported.
+ Unpacked 24bpp (RGBX 32bpp) is not yet stable enough to release.
+<p>
+ RAMDACs currently supported are the Brooktree (BT481, BT482,
+ and BT485) and AT&amp;T (20C505) RAMDACs used by the Hercules
+ Graphite series, and Sierra RAMDACs (15025 and 15021), and
+ Generic VGA RAMDAC. Untested support has been added for the
+ AT&amp;T 20C490 series.
+<p>
+ The current driver has a number of acceleration routines:
+ solid and dashed zero-width lines (except AGX-014), bitblt
+ fills, tiles, and stipples, solid arc and polygon fills,
+ character glyphs and font cache for 8-bit characters.
+<p>
+ Boards that have had some testing include ISA and VLB
+ versions of most of the Hercules Graphite series, Spider
+ Black Widow VLB and Black Widow Plus VLB, Boca Vortek VL,
+ CatsEye/X XGA-2, and the PS/2-57 planar XGA-2. The Orchid
+ Celsius is very similar to the Spider and Boca boards, except
+ some batches may use one of the AT&amp;T 20C490 series RAMDACs,
+ instead of the Sierra 15025. There has also been a report of
+ a generic board that uses a UMC RAMDAC that may be an AT&amp;T
+ 20C490 Clone.
+
+<sect> Acknowledgments
+<p>
+ First, to Hercules Customer Support for providing a loaner
+ board to get things started.
+<p>
+ Second, to the XFree86 team, and those who who have contributed
+ to their efforts to the project, for the foundation of work that
+ provided a basis for bootstrapping this server.
+
+<sect> Known Problems
+<p>
+<itemize>
+<item>The accelerated line routines don't match lines written
+ by the mi/cfb routines. This is noticeable when switching
+ between virtual consoles while running routines that draw
+ and erase lines. Seems to have been reduced/fixed in previous
+ releases but need more testing.<p>
+
+<item>Some special-case speedup added to cached font rendering
+ in 3.1.1 has been disabled as is over-aggressive in some
+ cases. This cuts the performance on terminal-fonts in half,
+ and font performance is already low for the AGX chips compared
+ to their contemporaries.<p>
+
+<item>As in all software, needs more testing.<p>
+
+</itemize>
+<sect> ToDo
+<p>
+ <itemize>
+<item>Address the above known problems.<p>
+
+<item>Additional acceleration routines and general performance
+ improvements. Many existing acceleration routines are Q&amp;D
+ adaptations of existing routines from other servers that support
+ graphics chips that differ significantly, architecturally, from
+ that XGA and are undoubtedly less than optimal. In particular
+ some of the general per-operation overhead to set-up the
+ graphics context should be moved to the ValidateGC() routines.<p>
+
+<item>Complete HW cursor support, most of the code is done (or
+ borrowed from other servers). There just remains a little
+ setup code and then finding a lot of time to debug and test
+ the numerous permutations.<p>
+
+<item>Complete support for the Graphite Pro's 84-pin RAMDAC.
+ (the 2MB version of the Graphite Pro has both RAMDACs,
+ the 1Mb only the 44-pin RAMDAC). Currently, the 84-pin RAMDAC
+ is only supported in clock-doubled pixmux mode, the server
+ will switch between RAMDACs as required by the video mode
+ In >8bpp modes this switching does not occur. <p>
+
+<item>Implement more HW probing, this will be difficult as it
+ appears some (all?) AGX-based vendors don't implement
+ the VESA VXE POS registers, although the AGX chip does
+ support it (and some vendors claim VXE compliance&hellip).
+ There are a few rev/vendor registers in the AGX chip but
+ they are not documented. Note: SuperProbe also does not
+ support probing for AGX/XGA chips. ISA POS probing is
+ supported for the XGA chips and some code for EISA POS
+ is also included but not tested.<p>
+
+<item>Micro-optimizations, in particularly reducing processing overhead
+ for common special cases that don't require full generality. <p>
+</itemize>
+<sect> XF86Config
+<p>
+Device Section Entries and Options Currently Supported:
+
+<p>
+ The minimum that must be specified in the XF86Config device
+ section for the AGX-014, AGX-015, AGX-016, and ISA-based XGA-1
+ and XGA-2 is the Chipset. However to get full capability out
+ of the AGX-01&lsqb;456&rsqb; chips, the RAMDAC should be specified.
+ Other parms may select additional capabilities, or may used to
+ override the defaults or reduce start-up time be suppressing
+ probing. XGA specific configuration is covered at the end of
+ this document. The XGA entries can generally be used to override
+ defaults for the AGX-01&lsqb;456&rsqb; as well.
+
+<descrip>
+<tag/Ramdac/
+
+ Be sure to check the clock rating of the RAMDAC(s) on
+ your video board and don't exceed that rating even
+ if the server allows it, overclocking RAMDACs will
+ damage them.
+<p>
+ The clock rating generally appears as a suffix to the part
+ number, may only have the most significant digit(s),
+ and may be mixed with other codes (e.g. package
+ type). For example, an 85MHz Bt481 in a plastic J-lead
+ package has a part number of Bt481KPJ85 and a 135MHz
+ AT&amp;T20C505 has a part number of ATT20C505-13. Sierra
+ stamps the rated speed below the part numbers in a
+ dark ink.
+
+<descrip>
+<tag/&dquot;normal&dquot;/
+ normal VGA style RAMDAC (6-bit DAC),
+ default if none specified. Most
+ boards should work with this parm,
+ but some capabilities will be
+ unavailable. Only 8bpp is available.
+
+<tag/&dquot;bt481&dquot;/
+ bt481 RAMDAC (supports 8-bit DAC)
+<tag/&dquot;bt482&dquot;/
+ bt482 RAMDAC (supports 8-bit DAC)
+ The Hercules Graphite HG210 uses
+ the BT481 or BT482, the only
+ difference between these two is the
+ BT482's HW cursor (not yet supported).
+ The BT481/2 are limited to 85Mhz.
+ 8bpp, 15bpp, 16bpp are supported.
+
+<tag/&dquot;ATT20c490&dquot;/
+ AT&amp;T490 RAMDAC (includes
+ 49&lsqb;123&rsqb;
+ - supports 8-bit DAC). Limited
+ to 110Mhz at 8bpp. 8bpp, 15bpp,
+ and 16bpp are supported.
+
+<tag/&dquot;SC15025&dquot;/
+ Sierra SC15025 and SC15021 RAMDAC
+ (support 8-bit DAC). The SC15025 is
+ limited to 125Mhz, and the SC15021
+ 135Mhz. Check the RAMDAC's actual rating,
+ some SC15025's used in AGX based boards
+ are only rated to 110Mhz. 8bpp, 15bpp,
+ and 16bpp are supported.
+
+<tag/&dquot;herc_dual_dac&dquot;/
+ Hercules Graphite Pro RAMDAC probe.
+ If the 84-pin Big-RAMDAC is installed
+ (2MB models), will use the Big RAMDAC,
+ but only clocks-doubled, pixel-
+ multiplexed modes (higher clock values
+ only!). Lower clocks and resolutions
+ in 8bpp mode are supported by switching
+ to the Small 44-pin RAMDAC. 15bpp and
+ 16bpp are supported.
+<p>
+ There has been one report of the
+ "dac-8-bit" option not working with a
+ Graphite Pro equipped with a BT485 RAMDAC,
+ puzzling since it should be identical to the
+ AT&amp;T20C505 in this regard. No startup
+ messages or XF86Config were submitted to
+ aid problem isolation.
+<p>
+ Not supported by the HG210 Graphite.
+
+<tag/&dquot;herc_small_dac&dquot;/
+ Hercules Graphite Pro RAMDAC probe.
+ Forces use of only the BT481/482
+ RAMDAC. 8bpp, 15bpp, 16bpp, and unpacked
+ 24/32bpp are supported.
+
+ Not supported by the HG210 Graphite.
+
+<tag/&dquot;xga&dquot;/
+ To allow overriding the default
+ VGA style RAMDAC control for the AGX-010.
+</descrip>
+
+<tag/Ramdac related Option Flags:/
+
+<descrip>
+<tag/&dquot;dac_6_bit&dquot;/
+ Sets RAMDAC to VGA default 6-bit DAC mode
+ (default for "normal").
+
+<tag/&dquot;dac_8_bit&dquot;/
+ Sets supported RAMDAC's to 8-bit DAC mode
+ (default for all but "normal").
+
+<tag/&dquot;sync_on_green&dquot;/
+ Composite sync on green for RAMDAC's that
+ support this feature (BT481/481 and
+ AT&amp;T20c490). However, whether any
+ boards have necessary traces and glue
+ logic is doubtful.
+</descrip>
+
+<tag/Chipset:/
+
+ Must be specified, possible values: "AGX-016", "AGX-015",
+ "AGX-014", "AGX-010", "XGA-2", or "XGA-1". Some AGX
+ vendors place stickers over the chip, in general, if it's
+ a VLB board it's probably an AGX-015 and if it's an ISA
+ board it may be an AGX-014. The Hercules Graphite Power Pro
+ and Spider Black Widow Plus use the AGX-016 chipset. In general,
+ specifying a lower revision in the AGX-0{14,15,16} series
+ does not seem to causes problems (except lower performance
+ from the AGX-014's non-accelerated line drawing).
+<p>
+ <bf>Note:</bf> Only the AGX-016, AGX-015, AGX-014 and XGA-2
+ have had any testing. Most of the development has been with
+ an AGX-015 based 2MB Hercules Graphite VL PRO (HG720) and
+ most of testers for previous releases had AGX-014 based 1MB
+ Hercules Graphite (HG210).
+<p>
+ The limited documentation I have for the AGX-010 is that
+ is is a clone of the XGA architecture with a few additional
+ configuration registers. What is not clear is whether to
+ use XGA or extended-VGA RAMDAC control registers.
+ The post-3.1.1 default is now VGA control registers, but
+ XGA control registers can be forced with the XGA RAMDAC parm.
+ Likewise the configuration parms described in the XGA
+ section can be used to override the AGX defaults for I/O
+ and memory addresses.
+
+<tag/VideoRam:/
+
+ Will be probed if not specified. The startup will be a
+ little faster if specified.
+
+<tag/Tuning Option flags:/
+
+<descrip>
+<tag>Bus I/O interface:</tag>
+
+<descrip>
+<tag/&dquot;8_bit_bus&dquot;/ Force 8-bit I/O bus.
+<tag/&dquot;wait_state&dquot;, &dquot;no_wait_state&dquot;/
+Set or clear CPU access wait state, default is the POST setting.
+<tag/&dquot;fifo_conserv&dquot;/ Disable Memory I/O Buffer, AGX-015 and AGX-016.
+ MS-Windows driver default. Required by some
+ VLB systems with `aggressive timing'.
+ The default for this server is to disable
+ the buffer.
+
+<tag/&dquot;fifo_moderate&dquot;/ Enable the AGX-015/016's Memory I/O buffer.
+<tag/&dquot;fifo_aggressive&dquot;/ Enable the AGX-016's extra-large buffer.
+ Either option may result in garbage being left
+ about the screen, disabled by default.
+ A good test is the xbench or x11perf dashed
+ lines tests, if random dots are drawn,
+ fifo_conserv is required. So far, no boards
+ have been reported that worked correctly
+ with the buffers enabled.
+</descrip>
+<tag/Memory Timing:/
+
+ POST defaults should be ok.
+
+<descrip>
+<tag/&dquot;vram_delay_latch&dquot;,
+ &dquot;vram delay_ras&dquot;,
+ &dquot;vram_extend_ras&dquot;/ Vram timing options.
+
+<tag/&dquot;slow_vram&dquot;,
+ &dquot;slow_dram&dquot;/ Set all of the vram timing options.
+<tag/&dquot;med_dram&dquot;/ Set vram latch delay, clear others.
+<tag/&dquot;fast_vram&dquot;,
+ &dquot;fast_dram&dquot;/ All of the vram timing options are cleared.
+ Should be specified if directly specifying
+ VRAM options in order to clear POST settings.
+</descrip>
+
+<tag/Debugging:/
+
+ These shouldn't generally be required:
+
+<descrip>
+<tag/&dquot;noaccel&dquot;/ (AGX,XGA) Disable Font Cache.
+
+<tag/&dquot;crtc_delay&dquot;/ (AGX) Force XGA mode CRTC delay.
+
+<tag/&dquot;engine_delay&dquot;/ AGX-015 only? adds additional VLB wait state.
+<tag/&dquot;vram_128&dquot;, &dquot;vram_256&dquot;/ Sets VRAM shift frequency, vram_128 is for
+ 128Kx8 VRAM. Default is to leave this bit
+ unchanged from POST setting.
+<tag/&dquot;refresh_20&dquot;, &dquot;refresh_25&dquot;/ Number of clock cycles between screen
+ refreshes. Default is to leave this bit
+ unchanged from POST setting.
+<tag/&dquot;screen_refresh&dquot;/ Disable screen refresh during non-blanked
+ intervals, AGX-016. Default is leave them
+ enabled.
+<tag/&dquot;vlb_a&dquot;, &dquot;vlb_b&dquot;/ VLB transaction type, default is to leave
+ this bit unchanged from POST value.
+
+</descrip>
+</descrip>
+</descrip>
+<descrip>
+<tag/Virtual resolution:/
+
+ The server now accepts any virtual width, however the
+ actual usable CRTC line width is restricted when using the
+ graphics engine and depends upon the chip revision. The
+ CRTC line width and not the virtual width determine the
+ amount of memory used. The server currently does not make
+ use of any of the unused CRTC line's memory. CRTC line
+ width is restricted by the following rules:
+<p><quote>
+ <bf>AGX-014 :</bf> 512, 1024 and 2048. (also AGX-010)
+</quote><quote>
+ <bf>AGX-015 :</bf> 512, 1024, 1280, and 2048.
+</quote><quote>
+ <bf>AGX-016 :</bf> 512, 640, 800, 1024, 1280, and 2048.
+</quote><quote>
+ <bf>XGA,AGX-010 :</bf> 512, 640, 800, 1024, 1280, 1152, and 2048.
+</quote>
+
+<p>
+ When panning I occasionally get streaks if the virtual
+ resolution is much greater than the physical resolution.
+ Moving the mouse a little makes it disappear. The Hercules
+ manual indicates this also happens with the MS-Windows drivers.
+<p>
+ The server requires at least a 64KB scratchpad (16KB for XGA's).
+ Additional memory is useful for font cache and a larger scratchpad.
+
+
+
+<tag/AGX Clocks:/
+
+ Probing is supported, but of course the usual warnings and
+ disclaimers apply. Probing may momentarily subject your
+ monitor to sweep frequencies in excess of its rating.
+ The cautious may wish to turn off the monitor while the
+ probe is running.
+<p>
+ Once clocks are known, they can be entered into XF86Config,
+ then subsequent runs won't probe clocks and will be quicker
+ to startup. For the clock probe it is recommended that the
+ X server be run with the -probeonly option. The values
+ in the clocks statement are the hardware input clocks and
+ correspond to the pixel clock only at 8bpp in direct-clocking
+ RAMDAC modes. The server will divide/multiply those values
+ as appropriate for the RAMDAC modes available at the current
+ pixel depth. The available pixel clocks will be displayed
+ in the startup messages.
+<p>
+ For the 2MB Hercules Graphites, with the "herc-dual-dac"
+ RAMDAC specified, earlier versions of the server generated
+ an additional 16 clocks with values doubled and some zeroed.
+ Those are no longer needed and you should re-probe and re-enter
+ the clock values to ensure all clocks are available to you.
+
+ The AGX-015 2MB Hercules Graphite VL Pro with an
+ ICS1494M 9251-516 clock chip has probed clock values of:
+<verb>
+ 25.18 28.80 32.70 36.00 40.00 45.00 50.40 64.70
+ 70.10 76.10 80.60 86.30 90.40 95.90 100.70 109.40
+</verb>
+ Actual values according to Hercules are:
+<verb>
+ 25.175 28.322 32.512 36.000 40.00 44.90 50.35 65.00
+ 70.00 75.00 80.00 85.00 90.00 95.00 100.0 108.0
+</verb>
+ These are the values to be used in the clock statement
+ if specifying the "normal", "bt481", or "herc_small_dac"
+ RAMDAC in your XF86Config and your clockchip matches
+ that above.
+<p>
+ Clock probing assumes that the first clock is 25.175Mhz and
+ uses that to derive the rest. A warning is displayed if the
+ second is not near 28.322Mhz. If this warning appears, you
+ should not use the probed clock values without additional
+ verification from other sources.
+<p>
+ In the case of the AGX-014 and later AGX's, only the external
+ clock select lines are used, this means the clock values
+ correspond to the values of the video board's clock chip.
+<p>
+ For the AGX-010, the first 8 clocks use the standard XGA
+ internal clock selects and the second 8 are based on
+ AGX extensions. For the XGA-1 only 8 clocks are available.
+ The XGA-2 uses a programmable clock and no clocks or
+ clockchip line is required.
+<p>
+ The maximum pixel clock generally allowed is 85MHz, but
+ some RAMDACs support higher values. In any case you, should
+ check your RAMDAC, some RAMDACs used on AGX based boards are
+ produced in versions rated to lesser values than the server
+ assumes. You should check the rating and limit yourself to
+ that value.
+
+<tag/Modes:/
+
+ One difference I've noted from the Mach8, is that the AGX's
+ CRTC doesn't like the start of the horizontal sync to be
+ equal to horiz blank start (vert sync may have the same problem,
+ I need to test some more). Interlaced and +/-sync flags are
+ supported but have had very little testing. For interlaced
+ modes make sure the number of lines is an odd number.
+<p>
+ The doublescan flag is now supported, however the minimum
+ clock supported is generally 25MHz, so resolutions of less
+ than 400x300 are not likely to be supported by most monitors.
+ In creating doublescan mode timings, the vertical timings
+ will match the apparent resolutions, e.g. for 400x300
+ the timings should describe 300 lines, not 600.
+
+<tag/Examples:/
+
+<p> For the Hercules HG720 (2MB VLB AGX-015, with BT481 and
+ AT&amp;T20C5050 RAMDACs), I use the following XF86Config
+ "Device" section:
+<verb>
+ Section "Device"
+ Identifier "HG720"
+ VendorName "Hercules"
+ BoardName "Graphite VL Pro"
+ Chipset "AGX-015"
+ Clocks 25.2 28.3 32.5 36.0 40.0 45.0 50.4 65.0
+ 70.00 75.00 80.00 85.00 90.00 95.00 100.0 108.0
+ Videoram 2048
+ RamDac "herc_dual_dac"
+ Option "dac_8_bit"
+ Option "no_wait_state"
+ EndSection
+</verb>
+ For the Spider Black Widow Plus (2MB VLB AGX-016, with
+ Sierra SC15021 RAMDAC):
+<verb>
+ Section "Device"
+ Identifier "SBWP"
+ VendorName "Spider"
+ BoardName "Black Widow Plus"
+ Chipset "AGX-016"
+ Clocks 25.2 28.3 39.9 72.2 50.0 76.9 36.1 44.8
+ 89.0 119.8 79.9 31.5 110.0 64.9 74.9 94.9
+ Videoram 2048
+ RamDac "SC15025"
+ Option "dac_8_bit"
+ Option "no_wait_state"
+ EndSection
+</verb>
+</descrip>
+<sect> Xga configuration<p>
+
+
+<p> This server now has tested support for XGA-2 compatible
+ boards (aka. XGA-NI). The main issue for XGA-1 support is
+ whether clock probing works. At this time probing for board
+ configuration is limited and detailed configuration may need to be
+ done manually.
+
+<p> By default the ISA POS register will be performed. If the
+ XGA Instance number is specified the scope of probing will
+ be narrowed a bit. To override or disable probing, a minimum
+ of the Instance, COPbase, and MEMbase must be specified
+ in the XF86Config device section for the XGA card. MCA
+ probing is not supported.
+
+<p>
+<descrip>
+<tag/Instance nn/ XGA instance number (0-7).
+
+<tag/IObase nnnn/ The I/O address of the the XGA
+ general control registers. The
+ standard, and default, is 0x21i0,
+ where i is the instance number.
+
+<tag/MEMbase nnnn/ The XGA display memory address (the
+ address the XGA coprocessor uses
+ for video memory). This is also
+ the system memory address of the
+ linear aperture on boards that
+ support it.
+
+ POS register 4 bits 7-1 contains
+ bits 31-25 of the XGA's display
+ memory address. Bits 24-22 of
+ of the display memory address
+ contains the XGA instance number.
+ Bit 0 of POS register 4 is not
+ used by this server as the XGA's
+ linear aperture is not used.
+ However, the coprocessor must
+ still be configured with this.
+
+ The AGX-01&lsqb;456&rsqb;
+ chips have a fixed
+ display memory address.
+
+<tag/COPbase nnnnnn/ Address of the graphics engine's
+ memory mapped control registers.
+
+ Typically:
+
+ 0xC1C00 + (ext_mem_addr * 0x2000)
+ + (instance * 0x80)
+
+ where ext_mem_addr is the high
+ order 4-bits of POS register 2
+ (0-16 the server assumes zero).
+
+ The AGX-01&lsqb;456&rsqb; chips support
+ 0xB1F00 (default) and 0xD1F00.
+
+<tag/BIOSbase nnnnnn/ Address of the XGA BIOS (not VGA BIOS).
+ Can be specified as an alternate to COPbase.
+
+ Typically:
+
+ 0xC0000 + (ext_mem_addr * 0x2000)
+
+ where ext_mem_addr is the high
+ order 4-bits of POS register 2
+ (0-16 -- the server assumes zero).
+
+<tag/VGAbase nnnn/ Can be used to override the default 0xA0000
+ address for the 64KB video memory
+ address used by the server. The
+ only values acceptable are 0xA0000
+ and 0xB0000. VGA text mode restore
+ does not work under Linux if 0xB0000
+ is specified.
+
+ AGX-01&lsqb;456&rsqb;
+ also default to 0xA0000.
+
+<tag/POSbase nnnn/ Can be used to specify an alternate POS register
+ probe address base from the ISA
+ default of 0x100. The VESA VXE
+ standard for EISA is 0xzC80, where
+ z is the slot number).
+
+ A value of zero will disable POS
+ register probing (required for MCA).
+
+<tag/DACspeed nnnn/ Can be used to override the servers default
+ maximum Pixel Clock for XGA-2 of 80Mhz.
+ The limit can be raised as high as 90Mhz,
+ or set to lower values.
+
+</descrip>
+<p> An alternate way to determine the POS register values is
+ with the setup/diag programs that should have been included
+ with your video board, or possibly from jumper values.
+<p>
+ The XGA-2 has programmable clocks up to 90MHz, however
+ at 1024x768, 72MHz is generally the max that will produce
+ a stable display with the CatsEye/XGA-2 used for testing
+ (IBM coprocessor and INMOS RAMDAC/serializer). Higher clocks
+ will often generate artifacts at the top and left edges of
+ the screen. Such artifacts can sometimes be tuned out by
+ increasing the vertical and horizontal blanking intervals
+ or slightly changing the clock. At pixel clock rates above
+ 80Mhz I have seen the chip lose sync after running for several
+ minutes, so 80Mhz has been set as the default limit for XGA-2
+ pixel clocks. I don't have specs on actual limits, and as
+ there are a number of different XGA chipsets, you should use
+ the modes documented in your owner's manual as a guide to
+ max refresh rates. No clocks or clockchip parm are required
+ to specify use of programmable clocks for the XGA-2.
+<p>
+ 8bpp and 16bpp are supported for the XGA-2.
+<p>
+ For XGA-1 cards the clocks must be specified as for
+ the AGX chips, it is not known whether the clockprobing
+ will work. Some XGA-1 chips may support 16bpp.
+<p>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/agx.sgml,v 3.19 1997/01/25 03:22:19 dawes Exp $
+
+
+
+
+
+$XConsortium: agx.sgml /main/9 1996/10/19 18:03:50 kaleb $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/apm.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/apm.sgml
new file mode 100644
index 000000000..06aa60f9a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/apm.sgml
@@ -0,0 +1,73 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+<title> Information for Alliance Promotion chipset users
+<author> Henrik Harmsen (Henrik.Harmsen@erv.ericsson.se)
+<date> 23 February 1998
+<toc>
+
+<sect> Support chipsets
+<p>
+The apm driver in the SVGA server is for Alliance Promotion
+(www.alsc.com) graphics chipsets. The following chipsets are supported:
+
+<itemize>
+<item> 6422
+
+ Old chipset without color expansion hardware (text accel).
+
+<item> AT24
+
+ As found in Diamond Stealth Video 2500. Quite similar to AT3D.
+
+<item> AT25, AT3D
+
+ AT3D is found in Hercules Stingray 128/3D. Most other Voodoo
+ Rush based cards use the AT25 which is identical except it
+ doesn't have the 3D stuff in it.
+</itemize>
+
+<sect> Acceleration
+<p>
+The apm driver uses the XAA (XFree86 Acceleration Architecture) in the
+SVGA server. It has support for the following acceleration:
+
+<itemize>
+<item> Bitblts (rectangle copy operation)
+<item> Lines (solid, single pixel)
+<item> Filled rectangles
+<item> CPU->Screen colour expansion (text accel). Not for 6422.
+<item> Hardware cursor
+</itemize>
+
+All in 8, 16 and 32 bpp modes. No 24bpp mode is supported.
+Also VESA DPMS power save mode is fully supported with "standby",
+"suspend" and "off" modes (set with with the "xset dpms" command).
+
+<sect> Configuration
+<p>
+First: Please run the XF86Setup program to create a correct
+configuration.
+
+You can turn off hardware cursor by inserting the following line in the
+Device section of the XF86Config file:
+
+ Option "sw_cursor"
+
+Or turn off hardware acceleration:
+
+ Option "noaccel"
+
+Please don't specify the amount of video RAM you have or which chipset
+you have in the config file, let the driver probe for this. Also please
+don't put any "clocks" line in the device section since these chips have
+a fully programmable clock that can take (almost) any modeline you throw
+at it. It might fail at some specific clock values but you should just
+try a slightly different clock and it should work.
+
+
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/apm.sgml,v 1.2 1999/08/23 06:18:33 dawes Exp $
+</verb>
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/ark.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/ark.sgml
new file mode 100644
index 000000000..08e689b28
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/ark.sgml
@@ -0,0 +1,239 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+
+<!-- Title information -->
+<title> Information for ARK Logic Chipset Users
+<author> Harm Hanemaayer (<it>H.Hanemaayer@inter.nl.net</it>)
+<date> 17 January 1997
+
+<!-- Table of contents -->
+<toc>
+
+<sect> Supported chipsets <p>
+
+The "ark" driver in the SVGA server is for ARK Logic graphics chipsets.
+The following chipsets are supported:
+<descrip>
+<tag>ARK1000PV (ark1000pv)</tag>
+ Chipset with 32-bit DRAM interface, supports fast DRAM timing,
+ for VESA and PCI bus. Has powerful "coprocessor" for graphics
+ acceleration.
+ The max supported resolution/refresh depends on the RAMDAC
+ used on the card; expect 256 colors up to 80 or 110 MHz dot clock;
+ 16bpp is also supported, as is 24bpp (packed).
+<tag>ARK1000VL (ark1000vl)</tag>
+ Older chip, VLB only. More or less compatible with ARK1000PV.
+ It has is not been tested. You may have to disable acceleration
+ and linear addressing.
+<tag>ARK2000PV (ark2000pv)</tag>
+ 64-bit version of the ARK1000PV. Note that an ARK2000PV equipped
+ with 1Mb of DRAM is about equivalent to the same card with an
+ ARK1000PV chip; 2Mb is required for 64-bit operation. Again
+ the RAMDAC used on the card determines the max supported dot
+ clocks. At 8bpp, multiplexing over a 16-bit RAMDAC path is not
+ yet supported so expect dot clocks up to 110 MHz; 16bpp and 32bpp
+ are supported, as well as experimental packed 24bpp, depending
+ on the RAMDAC.
+<tag>ARK2000MT (ark2000mt)</tag>
+ This is a newer chip, compatible with the AR2000PV.
+
+</descrip>
+
+The ARK2000MI is not yet supported.
+
+The chipset may not be detected automatically. In this case use a line
+like <tt>Chipset "ark1000pv"</tt> in the <tt>Device</tt> section of
+the XF86Config file. Any options must also be specified in this section.
+
+
+<sect> Supported RAMDACs <p>
+
+If no RAMDAC is specified, a standard RAMDAC supporting 256 colors up
+to 80 MHz dot clock frequency is assumed. The following RAMDAC types
+can be specified in the Device section of the XF86Config file (e.g.
+<tt>Ramdac "att20c490"</tt>):
+<descrip>
+<tag>att20c490</tag>
+ Industry-standard 8-bit RAMDAC. The RAMDAC used
+ on the basic Hercules Stingray Pro is compatible. 16bpp color
+ depth is supported up to 40 or 55 MHz, depending on the DAC
+ speed rating. Packed 24bpp is supported up to about 36 MHz.
+<tag>att20c498</tag>
+ Industry-standard 16-bit RAMDAC. The RAMDAC used
+ on the Hercules Stingray Pro/V and the Stingray 64/V is
+ compatible. 16bpp is supported up to 80 MHz or 110 MHz dot clock
+ frequency, 32bpp is supported up to 40 or 55 MHz.
+<tag>zoomdac</tag>
+ This is the actual DAC used by the Hercules Stingray Pro/V and 64/V.
+ It is treated mostly as an ATT20C498, but with dot clock limits
+ set correctly (16bpp up to 55 MHz with ARK1000PV, up to at least
+ 110 MHz with ARK2000PV). In addition, packed 24bpp is supported
+ (up to 36 MHz with ARK1000PV, not yet on the ARK2000PV),
+ and 32bpp is also supported on the ARK2000PV (up to 55 MHz)
+ This RAMDAC should be auto-detected.
+<tag>stg1700</tag>
+ Completely untested.
+<tag>ics5342</tag>
+ This is a clockchip/RAMDAC combination and is used on the Diamond
+ Stealth 64 Graphics 2001 and newer Hercules cards that use the
+ ARK2000MT. It is supported at 16bpp and 32bpp in addition to 256
+ color mode. 32bpp mode may not work.
+</descrip>
+The Dacspeed keyword can be used to indicate the speed rating of the RAMDAC,
+but it must be used with care. The raw clock frequency may exceed 80 MHz.
+Both the ARK chips and some of the RAMDACs are specified for raw speeds up
+to 120 MHz, but this might violate FCC regulations or otherwise be unstable.
+High dot clock 8bpp modes (e.g. 135 MHz) are normally achieved by
+sending 2 pixels at at time over a 16-bit DAC path (the raw clock would be
+67.5 MHz for 135 MHz dot clock), a mode of operation that is not yet
+supported by this driver. No high-dot clock configurations
+have been tested.
+
+The driver now limits the maximum dot clocks according to the DRAM speed
+(bandwidth). Because it is not possible to determine the memory clock
+speed (except on the ICS5342), the driver assumes a default of 60 MHz.
+On an ARK1000PV, that allows 8bpp up to 109 MHz, 16bpp up to 55 MHz,
+24bpp up to 36 MHz, and 32bpp up to 27 MHz. On an ARK2000PV with 2MB
+memory, it allows 16bpp up to 110 MHz, 24bpp up to 72 MHz, and 32bpp up
+to 55 MHz. If you know what your real memory clock is, you can specify
+it with the <tt>MCLK</tt> keyword, for example <tt>MCLK 70</tt>.
+
+To run <tt>XF86_SVGA</tt> at 16 bpp, pass options to the X server as
+follows:
+<verb>
+startx -- -bpp 16 5-6-5 RGB ('64K color', XGA)
+startx -- -bpp 16 -weight 555 5-5-5 RGB ('Hicolor')
+startx -- -bpp 24 8-8-8 RGB (packed 24-bit truecolor)
+startx -- -bpp 32 8-8-8 RGB (32-bit pixel truecolor)
+</verb>
+
+<sect> Acceleration <p>
+
+The driver takes full advantage of the new XAA (XFree86 Acceleration
+Architecture) in the SVGA server. In fact the ARK driver was the
+initial XAA development platform. Most common graphics operations are
+accelerated, including most types of rectangular and non-rectangular
+filling, screen-to-screen BitBLTs, line drawing, and text and bitmap
+expansion. Expect over 300k xstones on a 2MB ARK2000PV/MT.
+
+At 24bpp, acceleration is less complete, but curiously, greyscale colors
+permit faster drawing. If you suspect a problem with acceleration, use
+the "noaccel" option. If text or bitmaps do not seem to be rendered
+correctly, you could try the "xaa_no_col_exp" option. To disable the
+pixmap cache, use "no_pixmap_cache".
+
+The hardware cursor is disabled by default. With unmodified mode timings,
+there used to be two horizontal lines and a band following the mouse
+pointer over the screen. The driver now automatically modifies the
+mode timing to eliminate this effect; this has not been tested on
+all possible configurations. Use the "hw_cursor" option to enable the
+hardware cursor.
+
+Linear addressing is the default mode of operation. If the server
+does not start correctly, you may want to try the "no_linear" option.
+
+The older ARK1000VL is probably not compatible with acceleration. Use
+the "noaccel" and "no_linear" options.
+
+<sect> Basic configuration <p>
+
+It is recommended that you generate an XF86Config file using the
+`<tt>XF86Setup</tt>' or `<tt>xf86config</tt>' programs, which should
+produce a working
+high-resolution 8bpp configuration, although the modelines might need
+reshuffling for optimal screen refresh. You may want to include mode
+timings in the <tt>Monitor</tt> section that better fit your monitor
+(e.g. 1152x864 modes).
+
+In order to prevent stress on your monitor, it is recommended that you
+turn off your monitor during clock probing (X -probeonly), which also
+happens if you start the server with no Clocks line present in the
+Device section of the XF86Config. The following Clocks line can be used
+for the Hercules Stingray Pro, Pro/V and older 64/V using an ARK Logic
+clock generator (so there's no need to probe clocks for this card, just
+insert the following line in the Device section of the XF86Config
+file):
+
+<verb>
+ Clocks 25.175 28.3 40 72 50 77 36 44.9
+ Clocks 128.43 118.8 80 31.5 110 63.96 74.19 95
+</verb>
+ The higher frequencies have not been tested, there might be a
+ mismatch in the 60-80 MHz range.
+
+<sect> Features that may be expected in upcoming beta releases <p>
+
+<itemize>
+<item>
+ Support for high dot clocks (>80 MHz, up to 135 MHz) at 8bpp by
+ sending two pixels at a time over a 16-bit RAMDAC path on an
+ ARK2000PV/MT with supported RAMDAC.
+<item>
+ Support for packed-24bpp mode up to 72 MHz on an ARK2000PV
+ with ZoomDAC.
+<item>
+ The acceleration may be further optimized and stabilized.
+<item>
+ Existing problems may be fixed.
+<item>
+ Support for the ARK2000MI, if it materializes.
+</itemize>
+
+<sect> Tested configurations. <p>
+
+<descrip>
+<tag>Hercules Stringray Pro (ARK1000PV + ATT20C490-compatible RAMDAC)</tag>
+ Supported at 8bpp, 16bpp and 24bpp. Fixed set of clocks.
+ There seems to be a restriction to the mode timings at 24bpp;
+ the last horizontal number (HTotal) must be divisible by 4 but
+ not by 8. If the modeline is wrong, the colors would
+ be incorrect. The driver automatically corrects the mode timing.
+
+<tag>Hercules Stingray Pro/V (ARK1000PV + IC Works ZoomDAC)</tag>
+ Supported at 8bpp, 16bpp and 24bpp. Fixed set of clocks.
+ The same restrictions above exist for the 24bpp mode. Problems
+ with textmode restoration have been reported on some OS's.
+
+<tag>Hercules Stingray 64/V (ARK2000PV + IC Works ZoomDAC)</tag>
+ Supported at 8bpp, 16bpp and 32bpp. Fixed set of clocks.
+ Problems with textmode restoration have been reported on
+ some OS's.
+
+<tag>Hercules Stingray 64 with ARK2000MT + ICS5342 Clockchip/RAMDAC</tag>
+ This may also apply to other cards with the ICS5342, such as
+ the Diamond Stealth 64 Graphics 2001. Use RAMDAC "ics5342".
+ Programmable clockchip (don't specify any Clocks lines).
+ Supported at 8bpp, 16bpp and 32bpp. 32bpp has been reported not
+ to work. This configuration has not been tested with a post-3.2
+ server.
+
+</descrip>
+
+If are having driver-related problems that are not addressed by this document,
+you can try contacting the XFree86 team (the current driver maintainer
+can be reached at <htmlurl name="H.Hanemaayer@inter.nl.net"
+url="mailto:H.Hanemaayer@inter.nl.net">), or post in the Usenet
+newsgroup <htmlurl name="comp.windows.x.i386unix"
+url="news:comp.windows.x.i386unix">.
+
+In fact, reports (success or failure) are very welcome, especially
+on configurations that have not been tested. You can do this via the
+<url name="bug report form" url="http://www.xfree86.org/cgi-bin/bugform.cgi">
+(or send mail to <htmlurl name="XFree86@XFree86.org"
+url="mailto:XFree86@XFree86.org">). You may want to
+keep an eye on forthcoming beta releases at the <url name="XFree86 web site"
+url="http://www.xfree86.org">.
+
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/ark.sgml,v 3.9 1997/01/25 03:22:20 dawes Exp $
+
+
+
+
+
+$XConsortium: ark.sgml /main/6 1996/10/28 05:24:04 kaleb $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/ati.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/ati.sgml
new file mode 100644
index 000000000..2966f3388
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/ati.sgml
@@ -0,0 +1,491 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN"[
+<!ENTITY % defs SYSTEM "defs.ent"> %defs;
+]>
+
+<article>
+
+<!-- Title information -->
+
+<title>ATI Adapters README file
+<author>Marc Aurele La France
+<date>1999 July 8
+
+<ident>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/ati.sgml,v 3.25 1999/08/21 13:48:29 dawes Exp $
+</ident>
+
+<abstract>
+This is the README for the XFree86 ATI driver included in this release.
+</abstract>
+
+<!-- Table of contents -->
+<toc>
+
+<!-- Begin the document -->
+
+<sect>Statement of intent<p>
+Generally speaking, the driver is intended for all ATI video adapters,
+providing maximum video function within hardware limitations.
+The driver is also intended to optionally provide the same level of support for
+generic VGA or 8514/A adapters.
+This driver is still being actively developed, meaning that it currently does
+not yet fully meet these goals.<p>
+The driver will provide
+<itemize>
+<item>accelerated support if an ATI accelerator is detected <it>and</it> the
+user has not requested that this support be disabled; otherwise
+<item>accelerated support if a non-ATI 8514/A-capable adapter is detected
+<it>and</it> the user has requested such support; otherwise
+<item>unaccelerated SuperVGA support if an ATI VGA-capable adapter is detected;
+otherwise
+<item>generic VGA support if a non-ATI VGA-capable adapter is detected
+<it>and</it> the user has requested such support.
+</itemize>
+Thus, the support provided not only depends on what the driver detects in the
+system, but also, on what the user specifies in the XF86Config file.
+See the <bf>``XF86Config specifications''</bf> section below for details.<p>
+If none of the above conditions are met, the ATI driver will essentially
+disable itself to allow other drivers to examine the system.<p>
+<sect>A note on acceleration<p>
+The meaning of ``acceleration'', as used in this document, needs to be
+clarified.
+Two of the many components in an accelerator are the CRT controller (CRTC) and
+the Draw Engine.
+This is in addition to another CRTC that, generally, is also present in the
+system (often in the same chip) and typically provides EGA, VGA or SuperVGA
+functionality.<p>
+A CRTC is the component of a graphics controller that is responsible for
+reading video memory for output to the screen.
+A Draw Engine is an accelerator component that can be programmed to manipulate
+video memory contents, thus freeing the CPU for other tasks.<p>
+When the VGA CRTC is used, all drawing operations into video memory are the
+responsibility of the system's CPU, i.e. no Draw Engine can be used.
+On the other hand, if the accelerator's CRTC is chosen to drive the screen,
+the Draw Engine can also be used for drawing operations, although the CPU can
+still be used for this purpose if it can access the accelerator's video
+memory.<p>
+Video acceleration refers to the programming of an accelerator's Draw Engine to
+offload drawing operations from the CPU, and thus also implies the use of the
+accelerator's CRTC.<p>
+<sect>Current implementation for ATI adapters<p>
+The driver currently supports the SuperVGA capabilities of all ATI adapters
+except some early Mach8 and Mach32 adapters that do not provide the required
+functionality.
+This support works for monochrome, 16-colour and 256-colour video modes, if one
+of the following ATI graphics controller chips is present:
+<verb>
+VGAWonder series: 18800, 18800-1, 28800-2, 28800-4, 28800-5, 28800-6
+ Mach32 series: 68800-3, 68800-6, 68800AX, 68800LX
+ Mach64 series: 88800GX-C, 88800GX-D, 88800GX-E, 88800GX-F, 88800CX,
+ 264CT, 264ET, 264VT, 264GT (3D Rage), 264VT-B, 264VT3,
+ 264VT4, 264GT-B (3D Rage II), 3D Rage IIc, 3D Rage Pro,
+ 3D Rage LT, 3D Rage LT Pro, 3D Rage XL, 3D Rage XC</verb>
+The driver also supports 32K, 64K and 16M-colour modes on the 264xT and 3D Rage
+series of adapters using the accelerator CRTC (but not the VGA CRTC).
+This support is as yet unaccelerated.<p>
+The newer Rage 128 chips are not yet supported.<p>
+Adapters based on the above chips have been marketed under a rather large
+number of names over the years.
+Among them are:
+<verb>
+VGAWonder series: VGAWonder V3, VGAWonder V4, VGAWonder V5, VGAWonder+,
+ VGAWonder XL, VGAWonder XL24, VGAWonder VLB, VGA Basic,
+ VGA Basic 16, VGA Edge, VGA Edge 16, VGA Integra,
+ VGA Charger, VGAStereo F/X, VGA 640, VGA 800, VGA 1024,
+ VGA 1024D, VGA 1024 XL, VGA 1024 DXL, VGA 1024 VLB
+ Mach8 series: Graphics Ultra, Graphics Vantage, VGAWonder GT
+ (None of the 8514/Ultra and 8514 Vantage series is
+ supported at this time)
+ Mach32 series: Graphics Ultra+, Graphics Ultra Pro, Graphics Wonder,
+ Graphics Ultra XLR, Graphics Ultra AXO, VLB mach32-D,
+ PCI mach32-D, ISA mach32
+ Mach64 series: Graphics Xpression, Graphics Pro Turbo, WinBoost,
+ WinTurbo, Graphics Pro Turbo 1600, Video Xpression,
+ 3D Xpression, Video Xpression+, 3D Xpression+,
+ 3D Charger, Video Charger, WinCharger, All-In-Wonder,
+ All-In-Wonder PRO, 3D Pro Turbo, XPERT@Play,
+ XPERT@Play 98, XPERT@Work, XPERT 98, XPERT LCD,
+ XPERT XL</verb>
+VGAWonder, Mach8 and Mach32 ISA adapters are available with or without a
+mouse.<p>
+These adapters are available with a variety of clock generators and RAMDACs.
+The 264xT and 3D Rage series of chips are integrated controllers, meaning that
+they include a programmable clock generator and a RAMDAC.<p>
+This driver still does not provide support for accelerated drawing to the
+screen.
+This means that all drawing is done by the CPU, rather than by any accelerator
+present in the system.
+This can make opaque moves, for example, quite ``jerky''.
+Also, given that IBM 8514/A and ATI Mach8 do not allow CPU access to their
+frame buffer, the driver will currently ignore these accelerators.
+Most Mach32 adapters provide both accelerated function and VGA functionality,
+but the driver currently only uses the VGA.<p>
+The driver <it>does</it> however support the accelerator CRTC present in all
+ATI Mach64 adapters.
+For 256-colour, and higher depth modes, this support will be used by default,
+although an XF86Config option can be specified to use the SuperVGA CRTC
+instead.
+A linear video memory aperture is also available in 256-colour and higher depth
+modes and enabled by default if a 264xT or 3D Rage controller is detected or,
+on 88800 controllers, if the accelerator CRTC is used.
+An XF86Config option is available to disable this aperture, or (on non-PCI
+adapters) enable it or move it to some other address.<p>
+<sect>Current implementation of generic VGA support for non-ATI adapters<p>
+Support for generic VGA with non-ATI adapters is also implemented, but has
+undergone only limited testing.
+The driver will intentionally disallow the use of this support with ATI
+adapters.
+This support must be explicitly requested through an XF86Config ChipSet
+specification.
+This prevents the current generic driver from being disabled.<p>
+This driver's generic VGA support is intended as an extension of that provided
+by the current generic driver.
+Specifically, within the architectural bounds defined by IBM's VGA standard,
+this driver will allow the use of any 256-colour mode, and any dot clock
+frequencies both of which allow for many more mode possibilities.<p>
+The driver will enforce the following limitations derived from IBM's original
+VGA implementation:
+<itemize>
+<item>There can only be a set of four (non-programmable) clocks to choose from.
+<item>Video memory is limited to 256kB in monochrome and 16-colour modes.
+<item>Video memory is limited to 64kB in 256-colour modes.
+<item>Interlaced modes are not available.
+</itemize>
+<sect>XF86Config specifications<p>
+The driver recognizes a number of XF86Config options.
+In general, all such options should be specified in a ``Device'' section, and
+affect only that ``Device'' section.<p>
+Those options that affect how the driver associates adapters with ``Device''
+sections are described first.
+The driver will ignore (with a message) a ``Device'' section if the section
+cannot be associated with exactly one adapter in the system.
+Similarly, the driver will ignore, or disable, (with a message) any adapter
+that cannot be associated with exactly one ``Device'' section.
+Thus, these options will be required in those uncommon cases where such unique
+associations cannot automatically be made by the driver.<p>
+Other options affect the driver's operation once an adapter has been assigned
+to the ``Device'' section which contains them.<p>
+<sect1>Driver ``ati''<p>
+The use of this specification is highly recommended if the ``Device'' section
+is to be recognized by the driver.
+In fact, it is almost (but not quite) mandatory, particularly when using the
+loader server as it indicates what driver is to be loaded and associated with
+the ``Device'' section.<p>
+<sect1>ChipSet ``name''<p>
+The default ChipSet name for this driver is ``<it>ati</it>''.
+In this case, any ATI adapter can be associated with the ``Device'' section.
+If an ATI accelerator is detected and the driver supports it, the accelerator's
+CRTC will be used to drive the screen.
+Otherwise, the driver will programme the adapter's SuperVGA CRTC.<p>
+If ``<it>ativga</it>'' is specified instead, the driver will ignore any ATI
+accelerator it detects, but otherwise operate as if ``<it>ati</it>'' had been
+specified.<p>
+A ChipSet name of ``<it>ibmvga</it>'' causes any VGA-capable adapter in the
+system to be associated with the ``Device'' section.
+It enables the driver's generic VGA support, but only for non-ATI adapters.
+If an ATI adapter is associated with the ``Device'' section, the driver will
+operate as if ``<it>ativga</it>'' had been specified instead.<p>
+A ChipSet name of ``<it>vgawonder</it>'' is equivalent to ``<it>ativga</it>'',
+except that only VGAWonder-capable adapters can be assigned to the ``Device''
+section.
+This specifically excludes newer Mach64's with integrated controllers.<p>
+In some PCI or AGP systems, the driver will not, by default, probe for non-PCI
+Mach32's or Mach64's.
+This is because, before doing any such probe, the driver attempts to determine
+if the probe can cause a lockup.
+If the driver has enough information to determine that a lockup would occur, it
+will skip the probe.
+In some situations, this determination cannot be accurate, and the driver will
+err on the side of caution, skipping the probe.
+Specifying a ChipSet name of ``<it>mach32</it>'' or ``<it>mach64</it>'', as
+appropriate, will force the driver to probe for the non-PCI adapter.
+These ChipSet names should, therefore, only be used when there is in fact such
+an adapter in the system.
+They are otherwise equivalent to ``<it>ati</it>''.<p>
+<sect1>ChipID & ChipRev specifications<p>
+These specifications will cause the driver to associate the ``Device'' section
+only with an adapter having the same attributes, or an adapter whose PCI device
+ID the driver does not recognize.
+In the second case, these options cause the driver to treat the adapter as if
+it was one with the specified PCI device ID or revision.
+ChipID can only be used with Mach32 or Mach64 adapters.
+ChipRev is meaningful only with Mach64 adapters.<p>
+<sect1>IOBase<p>
+This option limits the adapters that can be associated with the ``Device''
+section to those with the specified I/O base.
+This option only applies to Mach64 adapters.<p>
+<sect1>BusID<p>
+This option limits the adapters that can be associated with the ``Device''
+section to those with the specified PCI Bus ID.<p>
+<sect1>Clocks<p>
+For the purpose of specifying a clock line in your XF86Config, one of four
+different situations can occur, as follows.<p>
+Those configuring the driver's generic VGA support for a non-ATI adapter,
+can skip ahead to the <bf>``Clocks for non-ATI adapters''</bf> section below.
+Those <it>not</it> trying to configure the driver for a Mach64 adapter, can
+skip ahead to the <bf>``Clocks for fixed clock generators on ATI
+adapters''</bf> section below.<p>
+The very earliest Mach64 adapters use fixed (i.e. non-programmable) clock
+generators.
+Very few of these (mostly prototypes) are known to exist, but if you have one
+of these, you can also skip ahead to the <bf>``Clocks for fixed clock
+generators on ATI adapters''</bf> section below.<p>
+The two cases that are left deal with programmable clock generators, which are
+used on the great majority of Mach64 adapters.<p>
+If you are uncertain which situation applies to your adapter, you can run a
+clock probe with the command ``<tt>X -probeonly</tt>''.<p>
+<sect2>Clocks for supported programmable clock generators<p>
+At bootup, video BIOS initialization programmes an initial set of frequencies.
+Two of these are reserved to allow the setting of modes that do not use a
+frequency from this initial set.
+One of these reserved slots is used by the BIOS mode set routine, the other by
+the particular driver used (e.g. MS-Windows, AutoCAD, X, etc.).
+The clock numbers reserved in this way are dependent on the particular clock
+generator used by the adapter.<p>
+The driver currently supports all programmable clock generators known to exist
+on Mach64 adapters.
+In this case, the driver will completely ignore any XF86Config clock
+specification, and programme the clock generator as needed by the modes used
+during the X session.<p>
+<sect2>Clocks for unsupported programmable clock generators<p>
+This case is unlikely to occur, but is documented for the sake of
+completeness.<p>
+In this situation, the driver will probe the adapter for clock frequencies
+unless XF86Config clocks are already specified.
+In either case, the driver will then attempt to normalize the clocks to one of
+the following specifications:
+<verb>
+BIOS setting 1:
+
+ Clocks 0.000 110.000 126.000 135.000 50.350 56.640 63.000 72.000
+ 0.000 80.000 75.000 65.000 40.000 44.900 49.500 50.000
+ 0.000 55.000 63.000 67.500 25.180 28.320 31.500 36.000
+ 0.000 40.000 37.500 32.500 20.000 22.450 24.750 25.000</verb>
+<verb>
+BIOS setting 2:
+
+ Clocks 0.000 110.000 126.000 135.000 25.180 28.320 31.500 36.000
+ 0.000 80.000 75.000 65.000 40.000 44.900 49.500 50.000
+ 0.000 55.000 63.000 67.500 12.590 14.160 15.750 18.000
+ 0.000 40.000 37.500 32.500 20.000 22.450 24.750 25.000</verb>
+<verb>
+BIOS setting 3:
+
+ Clocks 0.000 0.000 0.000 0.000 25.180 28.320 0.000 0.000
+ 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
+ 0.000 0.000 0.000 0.000 12.590 14.160 0.000 0.000
+ 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000</verb>
+If the driver matches the clocks to the third setting above, functionality will
+be <it>extremely</it> limited (assuming the driver works at all).<p>
+<sect2>Clocks for fixed clock generators on ATI adapters<p>
+This section applies to all VGAWonder and Mach32 adapters, and to early Mach64
+prototypes.<p>
+One of the following clocks specifications (or an initial subset thereof) can
+be used depending on what the adapter uses to generate dot clocks:
+<verb>
+Crystals (VGA Wonder V3 and V4 adapters only):
+
+ Clocks 50.000 56.644 0.000 44.900 44.900 50.000 0.000 36.000
+ 25.000 28.322 0.000 22.450 22.450 25.000 0.000 18.000
+ 16.667 18.881 0.000 14.967 14.967 16.667 0.000 12.000
+ 12.500 14.161 0.000 11.225 11.225 12.500 0.000 9.000</verb>
+<verb>
+ATI 18810 clock generator:
+
+ Clocks 30.240 32.000 37.500 39.000 42.954 48.771 0.000 36.000
+ 40.000 0.000 75.000 65.000 50.350 56.640 0.000 44.900
+ 15.120 16.000 18.750 19.500 21.477 24.386 0.000 18.000
+ 20.000 0.000 37.500 32.500 25.175 28.320 0.000 22.450
+ 10.080 10.667 12.500 13.000 14.318 16.257 0.000 12.000
+ 13.333 0.000 25.000 21.667 16.783 18.880 0.000 14.967
+ 7.560 8.000 9.375 9.750 10.739 12.193 0.000 9.000
+ 10.000 0.000 18.750 16.250 12.586 14.160 0.000 11.225</verb>
+<verb>
+ATI 18811-0 and ATI 18812-0 clock generators:
+
+ Clocks 30.240 32.000 110.000 80.000 42.954 48.771 92.400 36.000
+ 39.910 44.900 75.000 65.000 50.350 56.640 0.000 44.900
+ 15.120 16.000 55.000 40.000 21.477 24.386 46.200 18.000
+ 19.955 22.450 37.500 32.500 25.175 28.320 0.000 22.450
+ 10.080 10.667 36.667 26.667 14.318 16.257 30.800 12.000
+ 13.303 14.967 25.000 21.667 16.783 18.880 0.000 14.967
+ 7.560 8.000 27.500 20.000 10.739 12.193 23.100 9.000
+ 9.978 11.225 18.750 16.250 12.588 14.160 0.000 11.225</verb>
+<verb>
+ATI 18811-1 and ATI 18811-2 clock generators:
+
+ Clocks 135.000 32.000 110.000 80.000 100.000 126.000 92.400 36.000
+ 39.910 44.900 75.000 65.000 50.350 56.640 0.000 44.900
+ 67.500 16.000 55.000 40.000 50.000 63.000 46.200 18.000
+ 19.955 22.450 37.500 32.500 25.175 28.320 0.000 22.450
+ 45.000 10.667 36.667 26.667 33.333 42.000 30.800 12.000
+ 13.303 14.967 25.000 21.667 16.783 18.880 0.000 14.967
+ 33.750 8.000 27.500 20.000 25.000 31.500 23.100 9.000
+ 9.978 11.225 18.750 16.250 12.588 14.160 0.000 11.225</verb>
+VGAWonder VLB, VGA 1024 VLB, Mach32 and Mach64 owners should only specify up to
+the first 32 frequencies.<p>
+Other clock generators that have been used on ATI adapters (which can all be
+said to be clones of one of the above) might generate non-zero frequencies for
+those that are zero above, or vice-versa.<p>
+The order of the clocks <it>is</it> very important, although the driver will
+reorder the clocks if it deems it appropriate to do so.
+Mach32 and Mach64 owners should note that this order is different than what
+they would use for previous XFree86 accelerated servers.<p>
+<sect2>Clocks for non-ATI adapters<p>
+If no clocks are specified in the XF86Config, the driver will probe for four
+clocks, the second of which will be assumed to be 28.322MHz.
+You can include up to four clock frequencies in your XF86Config to specify the
+actual values used by the adapter.
+Any more will be ignored.<p>
+<sect1>Option <it>``nolinear''</it><p>
+By default, the driver will enable a linear video memory aperture for
+256-colour and higher depth modes if it is also using a Mach64 accelerator CRTC
+or an integrated Mach64 graphics chip.
+This option disables this linear aperture.<p>
+<sect1>MemBase <it>address</it><p>
+This specification is only effective for non-PCI Mach64 adapters, and is used
+to override the CPU address at which the adapter will map its video memory.
+Normally, for non-PCI adapters, this address is set by a DOS install utility
+provided with the adapter.
+The MemBase option can also be used to enable the linear aperture in those
+cases where ATI's utility was not, or can not be, used.<p>
+For PCI adapters, this address is determined at system bootup according to the
+PCI Plug'n'Play specification which arbitrates the resource requirements of
+most devices in the system.
+This means the driver can not easily change the linear aperture address.<p>
+<sect>Known problems and limitations<p>
+There are several known problems or limitations related to the XFree86 ATI
+driver.
+They include:<p>
+<itemize>
+<item>A number of system lockups and blank screens have been reported when
+using PCI Mach64 adapters.
+The great majority of these problems have been found to be due to system
+aspects that are unrelated to this driver.
+As of this writing, these problems can be divided into three general areas:<p>
+Improper mouse protocol specification with some recent mice.
+Try different protocol specifications or another mouse.<p>
+A system conflict with APM.
+This problem is Linux-specific.
+There is a bug in kernels 2.0.31 or earlier that prevents proper APM operation.
+Upgrade to a more recent kernel or disable APM support.<p>
+The TV port on some Mach64 adapters needs to be disabled using an ATI utility
+that might or might not be supplied with the adapter.
+This problem is still under investigation.
+The only known workaround is to ensure no cable is connected to the adapter's
+TV connector on bootup.
+<item>When using a Mach64's accelerator CRTC, the virtual resolution must be
+less than 8192 pixels wide.
+The VGA CRTC further limits the virtual resolution width to less than 4096
+pixels, or to less than 2048 pixels for adapters based on 18800-x's (with 256kB
+of memory) and on Mach64 integrated controllers.
+These are hardware limits that cannot be circumvented.
+<item>Virtual resolutions requiring more than 1MB of video memory (256kB in the
+monochrome case) are not supported by the VGA CRTC on 88800GX and 88800CX
+adapters.
+This is a hardware limit that cannot be circumvented.
+<item>Due to hardware limitations, doublescanned modes are not supported by the
+accelerator CRTC in 88800GX, 88800CX, 264CT and 264ET adapters.
+<item>The ``VScan'' modeline parameter is only supported when using the VGA
+CRTC.
+<item>Interlaced modes are not supported on 18800-x and 28800-x adapters when
+using a virtual resolution that is 2048 pixels or wider.
+This is yet another hardware limitation that cannot be circumvented.
+For now, the driver prevents the occurrence of this problem by restricting
+virtual resolutions to be less than 2048 pixels wide, even when no interlaced
+modes are specified.
+<item>Video memory banking does not work in monochrome and 16-colour modes on
+18800-x adapters.
+This appears to be another hardware limit, but this conclusion cannot be
+confirmed at this time.
+The driver's default behaviour in this case is to limit video memory to 256kB.
+<item>Video memory corruption can still occur during mode switches on 18800-x
+adapters.
+Symptoms of this problem include garbled fonts on return to text mode, and
+various effects (snow, dashed lines, etc) on initial entry into a graphics
+mode.
+In the first case, the workaround is to use some other means of restoring the
+text font.
+On Linux, this can be accomplished with the kbd or svgalib packages.
+In the second case, xrefresh(1) will usually clean up the image.
+No complete solution to this problem is currently known.
+It appears this corruption occurs due to either video memory bandwidth or
+RAMDAC limitations, and so the driver will limit mode clocks to 40MHz.
+<item>There is some controversy over what the maximum allowed clock frequency
+should be on 264xT and 3D Rage adapters.
+For now, clocks will, by default, be limited to 80MHz, 135MHz, 170MHz, 200MHz
+or 230MHz, depending on the specific controller.
+This limit can only be increased (up to a driver-calculated absolute maximum)
+through the DACSpeed specification in XF86Config.
+Be aware however that doing so is untested and might damage the adapter.
+<item>Except as in the previous items, clocks are limited to 80MHz on most
+adapters, although many are capable of higher frequencies.
+This will be fixed in a future release.
+</itemize>
+Support for the following will be added in a future release:
+<itemize>
+<item>Mach32 accelerator's CRTC.
+This support is the first step towards accelerated support for Mach32's,
+Mach8's, 8514/A's and other clones.
+<item>Colour depth greater than 8, where permitted by the hardware.
+<item>Mach64, Mach32, Mach8 and 8514/A Draw Engines.
+<item>Hardware cursors.
+</itemize>
+<sect>Reporting problems<p>
+If you are experiencing problems that are not already recorded in this
+document, first ensure that you have the latest current release of this driver
+and XFree86.
+Check the server's stderr output and <htmlurl
+name="ftp://ftp.xfree86.org/pub/XFree86"
+url="ftp://ftp.xfree86.org/pub/XFree86"> if you are uncertain.<p>
+Secondly, please check XFree86's doc directory for additional information.<p>
+Thirdly, do not forget to read <htmlurl name="http://www.xfree86.org/FAQ"
+url="http://www.xfree86.org/FAQ">.<p>
+Fourth, a scan through the comp.windows.x.i386unix and comp.os.linux.x
+newsgroups using your favourite archiving service can also prove useful in
+resolving problems.<p>
+If you are still experiencing problems, you can send me e-mail at
+<email>tsi@ualberta.ca</email>.
+Please be as specific as possible when describing the problem(s), and include
+an unedited copy of the server's stderr and the XF86Config file used.<p>
+<sect>Driver history<p>
+The complete history of the driver is rather cloudy.
+The following is more than likely to be incomplete and inaccurate.<p>
+Apparently, Per Lindqvist first got a driver working with an early ATI adapter
+under X386 1.1a.
+This original driver might have actually been based on a non-functional ATI
+driver written by Thomas Roell (currently of Xi Graphics).<p>
+Then Doug Evans (<it>dje@cygnus.com</it>) added support for the ATI VGA Wonder
+XL, trying in the process to make the driver work with all other ATI adapters
+available at the time.<p>
+Rik Faith (<it>faith@cs.unc.edu</it>) obtained the X11R4 driver from Doug Evans
+in the summer of 1992 and ported the code to the X386 part of X11R5.
+This subsequently became part of XFree86.<p>
+I (Marc Aurele La France) took over development and maintenance of the driver
+in the fall of 1993 after Rik got rid of his VGA Wonder adapter.<p>
+<sect>Driver versions<p>
+Due to the introduction of loadable drivers in XFree86 4.0, it has become
+necessary to track driver versions separately.
+With this release of the driver, I am introducing the following version
+numbering scheme.<p>
+Version 1 of this driver is the one I inherited from Rik Faith.
+This is the version found in XFree86 2.0 and 2.1.<p>
+Version 2 is my first rewrite of this code which only ended up being a
+partially unsuccessful attempt at generalizing the driver for all VGA Wonder,
+Mach32, and early Mach64 adapters.
+Various releases of this version of the driver can be found in XFree86 2.1.1,
+3.1, 3.1.1 and 3.1.2.<p>
+Version 3 represents my second rewrite (although a rather lame one as rewrites
+go).
+Into version 3, I introduced clock programming for Mach64 adapters and merged
+in the old ati_test debugging tool.
+This is the version found in XFree86 3.2, 3.3 and 3.3.1.<p>
+Version 4 is a rather major restructuring of version 3, which became larger
+than I could comfortably handle in one source file.
+This version will make it quite a bit easier to introduce new function such as
+acceleration, additional colour depths, and so on.
+This is the version found in XFree86 3.3.2, 3.3.3, 3.3.3.1, 3.3.3.2 and
+3.3.4.<p>
+Version 5 is an almost complete restructuring of version 4 to fit in the new
+driver API of XFree86 4.0.<p>
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/chips.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/chips.sgml
new file mode 100644
index 000000000..170a1003a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/chips.sgml
@@ -0,0 +1,903 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN"[
+<!ENTITY % defs SYSTEM "defs.ent"> %defs;
+]>
+
+<article>
+
+<!-- Title information -->
+<title> Information for Chips and Technologies Users
+<author> David Bateman (<it>dbateman@eng.uts.edu.au</it>),
+ Egbert Eich (<it>Egbert.Eich@Physik.TH-Darmstadt.DE</it>)
+<date> 19th July 1999
+
+<ident>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/chips.sgml,v 3.29 1999/08/28 11:18:16 dawes Exp $
+</ident>
+
+<!-- Table of contents -->
+<toc>
+
+<sect> Introduction <p>
+
+With the release of XFree86 version &relvers;, the Chips and Technologies
+driver has been extensively rewritten and contains many new features.
+This driver must be considered work in progress, and those users
+wanting stability are encouraged to use the older XFree86 3.3.x
+versions. However this version of the Chips and Technologies driver
+has many new features and bug fixes that might make users prefer
+to use this version. These features include
+
+<itemize>
+<item>The long standing black/blue screen problem that some people have
+ had should be fixed.
+<item>Hardware/Software cursor switching on the fly, that should fix
+ many of the known hardware cursor problems.
+<item>Gamma correction at all depths and DirectColor visuals for depths of
+ 15 or greater with the HiQV series of chipsets.
+<item>Supports PsuedoColor overlays on 16bpp TrueColor screens for HiQV.
+<item>32bpp pixmaps while using a framebuffer in 24bpp packed pixel mode.
+<item>Heaps more acceleration.
+<item>1/4bpp support.
+<item>Multihead
+<item>Much more...
+</itemize>
+
+This document attempts to discuss the features of this driver, the
+options useful in configuring it and the known problems. Most of the
+Chips and Technologies chipsets are supported by this driver to some
+degree.
+
+<sect> Supported Chips <p>
+
+The Chips and Technologies chipsets supported by this driver have one
+of three basic architectures. A basic architecture, the WinGine architecture
+which is a modification on this basic architecture and a completely new
+HiQV architecture.
+
+<sect1>Basic architecture<p>
+<descrip>
+<tag>ct65520</tag>
+ (Max Ram: 1Mb, Max Dclk: 68MHz@5V)
+<tag>ct65525</tag>
+ This chip is basically identical to the 65530. It has the same
+ ID and is identified as a 65530 when probed. See ct65530 for
+ details.
+<tag>ct65530</tag>
+ This is a very similar chip to the 65520. However it additionally
+ has the ability for mixed 5V and 3.3V operation and linear addressing
+ of the video memory.
+ (Max Ram: 1Mb, Max Dclk: 56MHz@3.3V, 68MHz@5V)
+<tag>ct65535</tag>
+ This is the first chip of the ct655xx series to support fully
+ programmable clocks. Otherwise it has the the same properties
+ as the 65530.
+<tag>ct65540</tag>
+ This is the first version of the of the ct655xx that was capable
+ of supporting Hi-Color and True-Color. It also includes a fully
+ programmable dot clock and supports all types of flat panels.
+ (Max Ram: 1Mb, Max Dclk: 56MHz@3.3V, 68MHz@5V)
+<tag>ct65545</tag>
+ The chip is very similar to the 65540, with the addition of H/W
+ cursor, pop-menu acceleration, BitBLT and support of PCI Buses.
+ PCI version also allow all the BitBLT and H/W cursor registers
+ to be memory mapped 2Mb above the Base Address.
+ (Max Ram: 1Mb, Max Dclk: 56MHz@3.3V,68MHz@5V)
+<tag>ct65546</tag>
+ This chip is specially manufactured for Toshiba, and so documentation
+ is not widely available. It is believed that this is really just a
+ 65545 with a higher maximum dot-clock of 80MHz.
+ (Max Ram: 1Mb?, Max Dclk: 80MHz?)
+<tag>ct65548</tag>
+ This chip is similar to the 65545, but it also includes XRAM support
+ and supports the higher dot clocks of the 65546.
+ (Max Ram: 1Mb, Max Dclk: 80MHz)
+</descrip>
+
+<sect1>WinGine architecture<p>
+<descrip>
+<tag>ct64200</tag>
+ This chip, also known as the WinGine, is used in video cards
+ for desktop systems. It often uses external DAC's and programmable
+ clock chips to supply additional functionally. None of these are
+ currently supported within the driver itself, so many cards will only
+ have limited support. Linear addressing is not supported for this
+ card in the driver.
+ (Max Ram: 2Mb, Max Dclk: 80MHz)
+<tag>ct64300</tag>
+ This is a more advanced version of the WinGine chip, with specification
+ very similar to the 6554x series of chips. However there are many
+ differences at a register level. A similar level of acceleration to
+ the 65545 is included for this driver.
+ (Max Ram: 2Mb, Max Dclk: 80MHz)
+</descrip>
+
+<sect1>HiQV Architecture<p>
+<descrip>
+<tag>ct65550</tag>
+ This chip includes many new features, including improved BitBLT
+ support (24bpp color expansion, wider maximum pitch, etc), Multimedia
+ unit (video capture, zoom video port, etc) and 24bpp uncompressed true
+ color (i.e 32bpp mode). Also memory mapped I/O is possible on all bus
+ configurations.
+ (Max Ram: 2Mb, Max Dclk: 80MHz@3.3V,100MHz@5V)
+<tag>ct65554</tag>
+ This chip is similar to the 65550 but has a 64bit memory bus as
+ opposed to a 32bit bus. It also has higher limits on the maximum
+ memory and pixel clocks
+ (Max Ram: 4Mb, Max Dclk: 100MHz@3.3V)
+<tag>ct65555</tag>
+ Similar to the 65554 but has yet higher maximum memory and pixel
+ clocks. It also includes a new DSTN dithering scheme that improves
+ the performance of DSTN screens.
+ (Max Ram: 4Mb, Max Dclk: 110MHz@3.3V)
+<tag>ct68554</tag>
+ Similar to the 65555 but also incorporates "PanelLink" drivers. This
+ serial link allows an LCD screens to be located up to 100m from the
+ video processor. Expect to see this chip soon in LCD desktop machines
+ (Max Ram: 4Mb, Max Dclk: 110MHz@3.3V)
+<tag>ct69000</tag>
+ Similar to the 65555 but incorporates 2Mbytes of SGRAM on chip. It is
+ the first Chips and Technologies chipset where all of the registers
+ are accessible through MMIO, rather than just the BitBlt registers.
+ (Max Ram: 2Mb Only, Max Dclk: 130MHz@3.3V)
+<tag>ct69030</tag>
+ Similar to the 69000 but incorporates 4Mbytes of SGRAM on chip and has
+ faster memory and pixel clock limits. Also includes a second display
+ channel so that the CRT can display independently of the LCD.
+ (Max Ram: 4Mb Only, Max Dclk: 170MHz@3.3V)
+</descrip>
+
+
+<sect> XF86Config Options <p>
+
+The following options are of particular interest to the Chips and
+Technologies driver. It should be noted that the options are case
+insensitive, and that white space and "_" characters are ignored.
+There are therefore a wide variety of possible forms for all options.
+The forms given below are the preferred forms.
+
+Options related to drivers can be present in the Screen, Device and
+Monitor sections and the Display subsections. The order of precedence
+is Display, Screen, Monitor, Device.
+
+<descrip>
+<tag>
+Option "NoAccel"
+</tag>
+ This option will disable the use of any accelerated functions.
+ This is likely to help with some problems related to DRAM
+ timing, high dot clocks, and bugs in accelerated functions, at
+ the cost of performance (which will still be reasonable on VLB/PCI).
+<tag>
+VideoRam 1024 (or another value)
+</tag>
+ This option will override the detected amount of video memory,
+ and pretend the given amount of memory is present on the card.
+<tag>
+Option "NoLinear"
+</tag>
+ By default linear addressing is used on all chips where it
+ can be set up automatically. The exception is for depths of
+ 1 or 4bpp where linear addressing is turned off by default.
+ It is possible to turn the linear addressing off with this
+ option. Note that H/W acceleration is only supported with
+ linear addressing.
+<tag>
+Option "Linear"
+</tag>
+ When the chipset is capable of linear addressing and it has
+ been turned off by default, this option can be used to turn it
+ back on. This is useful for the 65530 chipset where the base
+ address of the linear framebuffer must be supplied by the user,
+ or at depths 1 and 4bpp. Note that linear addressing at 1 and 4bpp
+ is not guaranteed to work correctly.
+<tag>
+MemBase 0x03b00000 (or a different address)
+</tag>
+ This sets the physical memory base address of the linear
+ framebuffer. Typically this is probed correctly, but if
+ you believe it to be mis-probed, this option might help.
+ Also for non PCI machines specifying this force the linear base
+ address to be this value, reprogramming the video processor
+ to suit. Note that for the 65530 this is required as the
+ base address can't be correctly probed.
+<tag>
+Option "HWcursor"
+</tag>
+ For chipsets that support hardware cursors, this option enforces
+ their use, even for cases that are known to cause problems on some
+ machines. Note that it is overridden by the "<tt>SWcursor</tt>"
+ option. Hardware cursors effectively speeds all graphics operations
+ as the job of ensuring that the cursor remains on top is now given
+ to the hardware. It also reduces the effect of cursor flashing during
+ graphics operations.
+<tag>
+Option "SWcursor"
+</tag>
+ This disables use of the hardware cursor provided by the chip.
+ Try this if the cursor seems to have problems.
+<tag>
+Option "STN"
+</tag>
+ The server is unable to differentiate between SS STN
+ and TFT displays. This forces it to identify the display
+ as a SS STN rather than a TFT.
+<tag>
+Option "UseModeline"
+</tag>
+ The flat panel timings are related to the panel size and not the
+ size of the mode specified in XF86Config. For this reason the
+ default behaviour of the server is to use the panel timings already
+ installed in the chip. The user can force the panel timings to be
+ recalculated from the modeline with this option. However the panel
+ size will still be probed.
+<tag>
+Option "FixPanelSize"
+</tag>
+ For some machines the LCD panel size is incorrectly probed from
+ the registers. This option forces the LCD panel size to be
+ overridden by the modeline display sizes. This will prevent the
+ use of a mode that is a different size than the panel. Before
+ using this check that the server reports an incorrect panel
+ size. This option can be used in conjunction with the option
+ "UseModeline" to program all the panel timings using
+ the modeline values.
+<tag>
+Option "NoStretch"
+</tag>
+ When the size of the mode used is less than the panel size, the
+ default behaviour of the server is to stretch the mode in an attempt
+ to fill the screen. A "<tt>letterbox</tt>" effect with no stretching
+ can be achieved using this option.
+<tag>
+Option "LcdCenter"
+</tag>
+ When the size of the mode used is less than the panel size, the
+ default behaviour of the server is to align the left hand edge of
+ the display with the left hand edge of the screen. Using this option
+ the mode can be centered in the screen. This option is reported to
+ have problems with some machines at 16/24/32bpp, the effect of which
+ is that the right-hand edge of the mode will be pushed off the screen.
+<tag>
+Option "HWclocks"
+</tag>
+ For the chips either using the WinGine or basic architectures, the
+ chips generates a number of fixed clocks internally. With the chips
+ 65535 and later or the 64300, the default is to use the programmable
+ clock for all clocks. It is possible to use the fixed clocks
+ supported by the chip instead by using this option. Typically
+ this will give you some or all of the clocks 25.175, 28.322,
+ 31.000 and 36.000MHz. The current programmable clock will be
+ given as the last clock in the list. On a cold-booted system this
+ might be the appropriate value to use at the text console (see the
+ "<tt>TextClockFreq</tt>" option), as many flat panels will need a
+ dot clock different than the default to synchronise. The
+ programmable clock makes this option obsolete and so it's use
+ isn't recommended. It is completely ignored for HiQV chipsets.
+<tag>
+Option "UseVclk1"
+</tag>
+ The HiQV series of chips have three programmable clocks. The
+ first two are usually loaded with 25.175 and 28.322MHz for
+ VGA backward compatibility, and the third is used as a fully
+ programmable clock. On at least one system (the Inside 686 LCD/S
+ single board computer) the third clock is unusable. This option
+ forces the use of VClk1 as the programmable clock.
+<tag>
+TextClockFreq 25.175
+</tag>
+ Except for the HiQV chipsets, it is impossible for the server to read
+ the value of the currently used frequency for the text console when
+ using programmable clocks. Therefore the server uses a default value of
+ 25.175MHz as the text console clock. For some LCDs, in particular
+ DSTN screens, this clock will be wrong. This allows the user to
+ select a different clock for the server to use when returning to
+ the text console.
+<tag>
+Option "FPClock8" "65.0"
+Option "FPClock16" "65.0"
+Option "FPClock24" "65.0"
+Option "FPClock32" "65.0"
+</tag>
+ In general the LCD panel clock should be set independently of the
+ modelines supplied. Normally the chips BIOS set the flat panel
+ clock correctly and so the default behaviour with HiQV chipset is
+ to leave the flat panel clock alone, or force it to be 90% of the
+ maximum allowable clock if the current panel clock exceeds the
+ dotclock limitation due to a depth change. This option allows the user
+ to force the server the reprogram the flat panel clock independently
+ of the modeline with HiQV chipset. The four options are for 8bpp or
+ less, 16, 24 or 32bpp LCD panel clocks, where the options above set
+ the clocks to 65MHz.
+<tag>
+Option "MMIO"
+</tag>
+ This has a different effect depending on the hardware on which it
+ is used. For the 6554x machines MMIO is only used to talk to the
+ BitBLT engine and is only usable with PCI buses. It is enabled
+ by default for 65545 machines since the blitter can not be used
+ otherwise. The HiQV series of chipsets must use MMIO with their
+ BitBLT engines, and so this is enabled by default. However the
+ 690xx chipsets can use MMIO for all communications with the video
+ processor. So using this option on a 690xx chipset forces them
+ to use MMIO for all communications. This only makes sense when
+ the 690xx is on a PCI bus so that normal PIO can be disabled.
+ (WARNING!! 690xx MMIO is untested)
+<tag>
+Option "SuspendHack"
+</tag>
+ This option sets the centering and stretching to the BIOS
+ default values. This can fix suspend/resume problems on some
+ machines. It overrides the options "LcdCenter"
+ and "NoStretch".
+<tag>
+Option "18bitBus" (Chips 65540/45/46/48)
+</tag>
+ For 24bpp on TFT screens, the server assumes that a 24bit bus
+ is being used. This can result in a reddish tint to 24bpp mode.
+ This option, selects an 18 bit TFT bus. For other depths this
+ option has no effect.
+<tag>
+Chipset "ct65546" (or some other chip)
+</tag>
+ It is possible that the chip could be misidentified, particular
+ due to interactions with other drivers in the server. It is
+ possible to force the server to identify a particular chip with
+ this option.
+<tag>
+Option "SyncOnGreen"
+</tag>
+ Composite sync on green. Possibly useful if you wish to use an
+ old workstation monitor. The HiQV internal RAMDAC's supports
+ this mode of operation, but whether a particular machine does
+ depends on the manufacturer.
+<tag>
+DacSpeed 80.000
+</tag>
+ The server will limit the maximum dotclock to a value as specified
+ by the manufacturer. This might make certain modes impossible
+ to obtain with a reasonable refresh rate. Using this option the
+ user can override the maximum dot-clock and specify any value they
+ prefer. Use caution with this option, as driving the video processor
+ beyond its specifications might cause damage.
+<tag>
+Option "SetMClk" "38.000MHz"
+Option "SetMClk" "38000kHz"
+</tag>
+ This option sets the internal memory clock (MCLK) registers of HiQV
+ chipsets to 38MHz or some other value. Use caution as excess heat
+ generated by the video processor if its specifications are exceeded
+ might cause damage. However careful use of this option might boost
+ performance. This option might also be used to reduce the speed of
+ the memory clock to preserve power in modes that don't need the full
+ speed of the memory to work correctly. This option might also be
+ needed to reduce the speed of the memory clock with the
+ "<tt>Overlay</tt>" option.
+<tag>
+Option "RGBbits" "8"
+</tag>
+ By default it is assumed that there are 6 significant bits in the
+ RGB representation of the colours in 4bpp and above. If the colours
+ seem darker than they should be, perhaps your ramdac is has 8
+ significant bits. This option forces the server to assume that there
+ are 8 significant bits.
+<tag>
+Option "ShowCache"
+</tag>
+ This is a debugging option and general users have no need of it.
+ Using this option, when the virtual desktop is scrolled away from
+ the zero position, the pixmap cache becomes visible. This is useful
+ to see that pixmaps, tiles, etc have been properly cached.
+<tag>
+Option "ShadowFB"
+</tag>
+ This option is only useful when acceleration can't be used and linear
+ addressing can be used. With this option all of the graphics are
+ rendered into a copy of the framebuffer that is keep in the main memory
+ of the computer, and the screen is updated from this copy. In this
+ way the expensive operation of reading back to contents of the screen
+ is never performed and the performance is improved. Because the
+ rendering is all done into a virtual framebuffer acceleration can not
+ be used.
+<tag>
+Option "Overlay"
+</tag>
+ The HiQV chipsets contain a multimedia engine that allow a 16bpp
+ window to be overlayed on the screen. This driver uses this capability
+ to include a 16bpp framebuffer on top of an 8bpp framebuffer. In this
+ way PseudoColor and TrueColor visuals can be used on the same screen.
+ XFree86 believes that the 8bpp framebuffer is overlayed on the 16bpp
+ framebuffer. Therefore to use this option the server must be started
+ in either 15 or 16bpp depth. Also the maximum size of the desktop
+ with this option is 1024x1024, as this is the largest window that the
+ HiQV multimedia engine can display. Note that this option using the
+ multimedia engine to its limit, and some manufacturers have set a
+ default memory clock that will cause pixel errors with this option.
+ If you get pixel error with this option try using the
+ "<tt>SetMClk</tt>" option to slow the memory clock.
+<tag>
+Option "ColorKey" "255"
+</tag>
+ Normally the color transparency key for the overlay is the 8bpp lookup
+ table entry 255. This might cause troubles with some applications, and
+ so this option allows the color transparency key to be set to some
+ other value. Legal values are 2 to 255 inclusive.
+<tag>
+Option "XaaNoScreenToScreenCopy",
+Option "XaaNoSolidFillRect",
+Option "XaaNoSolidHorVertLine",
+Option "XaaNoMono8x8PatternFillRect",
+Option "XaaNoColor8x8PatternFillRect",
+Option "XaaNoCPUToScreenColorExpandFill",
+Option "XaaNoScreenToScreenColorExpandFill",
+Option "XaaNoImageWriteRect",
+Option "XaaNoImageReadRect",
+Option "XaaNoPixmapCache",
+Option "XaaNoOffscreenPixmaps"
+</tag>
+ These option individually disable the features of the XAA acceleration
+ code that the Chips and Technologies driver uses. If you have a problem
+ with the acceleration and these options will allow you to isolation
+ the problem. This information will be invaluable in debugging any
+ problems.
+</descrip>
+
+<sect> Modelines <p>
+
+When constructing a modeline for use with the Chips and Technologies
+driver you'll needed to considered several points
+
+<descrip>
+<tag> * Virtual Screen Size </tag>
+ It is the virtual screen size that determines the amount
+ of memory used by a mode. So if you have a virtual screen size
+ set to 1024x768 using a 800x600 at 8bpp, you use 768kB for the
+ mode. Further to this some of the XAA acceleration requires that
+ the display pitch is a multiple of 64 pixels. So the driver will
+ attempt to round-up the virtual X dimension to a multiple of 64,
+ but leave the virtual resolution untouched. This might further
+ reduce the available memory.
+<tag> * 16/24/32 Bits Per Pixel </tag>
+ Hi-Color and True-Color modes are implemented in the
+ server. The clocks in the 6554x series of chips are internally
+ divided by 2 for 16bpp and 3 for 24bpp, allowing one modeline to
+ be used at all depths. The effect of this is that the maximum
+ dot clock visible to the user is a half or a third of the value
+ at 8bpp. The HiQV series of chips doesn't need to use additional
+ clock cycles to display higher depths, and so the same modeline
+ can be used at all depths, without needing to divide the clocks.
+ Also 16/24/32 bpp modes will need 2 , 3 or 4 times respectively more
+ video ram.
+<tag> * Frame Acceleration</tag>
+ Many DSTN screens use frame acceleration to improve the
+ performance of the screen. This can be done by using an external
+ frame buffer, or incorporating the framebuffer at the top of video
+ ram depending on the particular implementation. The Xserver assumes
+ that the framebuffer, if used, will be at the top of video ram.
+ The amount of ram required for the framebuffer will vary depending
+ on the size of the screen, and will reduce the amount of video
+ ram available to the modes. Typical values for the size of the
+ framebuffer will be 61440 bytes (640x480 panel), 96000 bytes
+ (800x600 panel) and 157287 bytes (1024x768 panel).
+<tag> * H/W Acceleration </tag>
+ The H/W cursor will need 1kB for the 6554x and 4kb for the
+ 65550. On the 64300 chips the H/W cursor is stored in registers and
+ so no allowance is needed for the H/W cursor. In addition to this
+ many graphics operations are speeded up using a
+ "<tt>pixmap cache</tt>". Leaving too little memory available for
+ the cache will only have a detrimental effect on the graphics
+ performance.
+<tag> * PseudoColor Overlay </tag>
+ If you use the "<tt>overlay</tt>" option, then there are
+ actually two framebuffers in the video memory. An 8bpp one and a
+ 16bpp one. The total memory requirements in this mode of operation
+ is therefore similar to a 24bpp mode. The overlay consumes memory
+ bandwidth, so that the maximum dotclock will be similar to a 24bpp
+ mode.
+<tag> * VESA like modes </tag>
+ We recommend that you try and pick a mode that is similar
+ to a standard VESA mode. If you don't a suspend/resume or LCD/CRT
+ switch might mess up the screen. This is a problem with the video
+ BIOS not knowing about all the funny modes that might be selected.
+<tag> * Dot Clock </tag>
+ For LCD screens, the lowest clock that gives acceptable
+ contrast and flicker is usually the best one. This also gives
+ more memory bandwidth for use in the drawing operations. Some
+ users prefer to use clocks that are defined by their BIOS. This
+ has the advantage that the BIOS will probably restore the clock
+ they specified after a suspend/resume or LCD/CRT switch. For a
+ complete discussion on the dot clock limitations, see the next
+ section.
+</descrip>
+
+The driver is capable of driving both a CRT and a flat panel
+display. In fact the timing for the flat panel are dependent on the
+specification of the panel itself and are independent of the particular
+mode chosen. For this reason it is recommended to use one of the programs
+that automatically generate XF86Config files, such as "<tt>xf86config</tt>"
+or "<tt>XF86Setup</tt>".
+
+However there are many older machines, particularly those with 800x600
+screen or larger, that need to reprogram the panel timings. The reason
+for this is that the manufacturer has used the panel timings to get a
+standard EGA mode to work on flat panel, and these same timings don't
+work for an SVGA mode. For these machines the "<tt>UseModeline</tt>"
+and/or possibly the "<tt>FixPanelSize</tt>" option might be needed. Some
+machines that are known to need these options include.
+
+<quote><verb>
+Modeline "640x480@8bpp" 25.175 640 672 728 816 480 489 501 526
+Modeline "640x480@16bpp" 25.175 640 672 728 816 480 489 501 526
+Options: "UseModeline"
+Tested on a Prostar 8200, (640x480, 65548, 1Mbyte)
+</verb></quote>
+
+<quote><verb>
+Modeline "800x600@8bpp" 28.322 800 808 848 936 600 600 604 628
+Options: "FixPanelSize", "UseModeline"
+Tested on a HP OmniBook 5000CTS (800x600 TFT, 65548, 1Mbyte)
+</verb></quote>
+
+<quote><verb>
+Modeline "800x600@8bpp" 30.150 800 896 960 1056 600 600 604 628
+Options: "FixPanelSize", "UseModeline"
+Test on a Zeos Meridan 850c (800x600 DSTN, 65545, 1Mbyte)
+</verb></quote>
+
+The NEC Versa 4080 just needs the "FixPanelSize" option. To the best of my
+knowledge no machine with a HiQV needs the "UseModeline" or "FixPanelSize"
+options.
+
+<sect> The Full Story on Clock Limitations <p>
+
+There has been much confusion about exactly what the clock limitations
+of the Chips and Technologies chipsets are. Hence I hope that this
+section will clear up the misunderstandings.
+
+In general there are two factors determining the maximum dotclock.
+There is the limit of the maximum dotclock the video processor can handle,
+and there is another limitation of the available memory bandwidth. The
+memory bandwidth is determined by the clock used for the video memory.
+For chipsets incapable of colour depths greater that 8bpp like the 65535,
+the dotclock limit is solely determined by the highest dotclock the video
+processor is capable of handling. So this limit will be either 56MHz or
+68MHz for the 655xx chipsets, depending on what voltage they are driven
+with, or 80MHz for the 64200 WinGine machines.
+
+The 6554x and 64300 WinGine chipsets are capable of colour depths of 16
+or 24bpp. However there is no reliable way of probing the memory clock
+used in these chipsets, and so a conservative limit must be taken for
+the dotclock limit. In this case the driver divides the video processors
+dotclock limitation by the number of bytes per pixel, so that the
+limitations for the various colour depths are
+
+<verb>
+ 8bpp 16bpp 24bpp
+64300 85 42.5 28.33
+65540/65545 3.3v 56 28 18.67
+65540/65545 5v 68 34 22.67
+65546/65548 80 40 26.67
+</verb>
+
+For a CRT or TFT screen these limitations are conservative and the user
+might safely override them with the "<tt>DacSpeed</tt>" option to some
+extent. However these numbers take no account of the extra bandwidth
+needed for DSTN screens.
+
+For the HiQV series of chips, the memory clock can be successfully probed.
+Hence you will see a line like
+
+<verb>
+(--) CHIPS(0): Probed memory clock of 40.090 MHz
+</verb>
+
+in your startx log file. Note that many chips are capable of higher
+memory clocks than actually set by BIOS. You can use the "<tt>SetMClk</tt>"
+option in your XF86Config file to get a higher MClk. However some
+video ram, particularly EDO, might not be fast enough to handle this,
+resulting in drawing errors on the screen. The formula to determine the
+maximum usable dotclock on the HiQV series of chips is
+
+<verb>
+Max dotclock = min(MaxDClk, 0.70 * 4 * MemoryClk / (BytesPerPixel +
+ (isDSTN == TRUE ? 1 : 0)))
+</verb>
+
+which says that there are two limits on the dotclock. One the overall
+maximum, and another due to the available memory bandwidth of the chip.
+For the memory bandwidth 4 bytes are transfered every clock cycle (Hence
+the 4), but after accounting for the RAS/CAS signaling only about 70%
+of the bandwidth is available. The whole thing is divided by the bytes
+per pixel, plus an extra byte if you are using a DSTN. The extra byte
+with DSTN screens is used for the frame buffering/acceleration in these
+screens. So for the various Chips and Technologies chips the maximum
+specifications are
+
+<verb>
+ Max DClk MHz Max Mem Clk MHz
+65550 rev A 3.3v 80 38
+65550 rev A 5v 110 38
+65550 rev B 95 50
+65554 94.5 55
+65555 110 55
+68554 110 55
+69000 135 83
+69030 170 100
+</verb>
+
+Note that all of the chips except the 65550 rev A are 3.3v only. Which
+is the reason for the drop in the dot clock. Now the maximum memory clock
+is just the maximum supported by the video processor, not the maximum
+supported by the video memory. So the value actually used for the memory
+clock might be significantly less than this maximum value. But assuming your
+memory clock is programmed to these maximum values the various maximum dot
+clocks for the chips are
+
+<verb>
+ ------CRT/TFT------- --------DSTN--------
+ 8bpp 16bpp 24bpp 8bpp 16bpp 24bpp
+65550 rev A 3.3v 80 53.2 35.47 53.2 35.47 26.6
+65550 rev A 5v 106.2 53.2 35.47 53.2 35.47 26.6
+65550 rev B 95 70 46.67 70 46.67 35.0
+65554 94.5 77 51.33 77 51.33 38.5
+65555 110 77 51.33 77 51.33 38.5
+68554 110 77 51.33 77 51.33 38.5
+69000 135 116.2 77.47 116.2 77.47 58.1
+69030 170 140 93.33 140 93.33 70
+</verb>
+
+If you exceed the maximum set by the memory clock, you'll get corruption
+on the screen during graphics operations, as you will be starving the
+HW BitBlt engine of clock cycles. If you are driving the video memory
+too fast (too high a MemClk) you'll get pixel corruption as the data
+actually written to the video memory is corrupted by driving the memory
+too fast. You can probably get away with exceeding the Max DClk at 8bpp
+on TFT's or CRT's by up to 10% or so without problems, it will just generate
+more heat, since the 8bpp clocks aren't limited by the available memory
+bandwidth.
+
+If you find you truly can't achieve the mode you are after with the default
+clock limitations, look at the options "<tt>DacSpeed</tt>" and
+"<tt>SetMClk</tt>". Using these should give you all the capabilities
+you'll need in the server to get a particular mode to work. However use
+caution with these options, because there is no guarantee that driving the
+video processor beyond it capabilities won't cause damage.
+
+<sect> Troubleshooting <p>
+
+<descrip>
+<tag> The cursor appears as a white box, after switching modes</tag>
+ There is a known bug in the H/W cursor, that sometimes causes
+ the cursor to be redrawn as a white box, when the mode is changed.
+ This can be fixed by moving the cursor to a different region,
+ switching to the console and back again, or if it is too annoying
+ the H/W cursor can be disabled by removing the "<tt>HWcursor</tt>"
+ option.
+<tag> The cursor hot-spot isn't at the same point as the cursor</tag>
+ With modes on the 6555x machines that are stretched to fill the
+ flat panel, the H/W cursor is not correspondingly stretched. This
+ is a small and long-standing bug in the current server. You can
+ avoid this by either using the "<tt>NoStretch</tt>" option or
+ removing the <tt>HWcursor</tt>" option.
+<tag> The lower part of the screen is corrupted</tag>
+ Many DSTN screens use the top of video ram to implement a frame
+ accelerator. This reduces the amount of video ram available to
+ the modes. The server doesn't prevent the user from specifying
+ a mode that will use this memory, it prints a warning on the console.
+ The effect of this problem will be that the lower part of the screen
+ will reside in the same memory as the frame accelerator and will
+ therefore be corrupt. Try reducing the amount of memory consumed
+ by the mode.
+<tag> There is a video signal, but the screen doesn't sync.</tag>
+ You are using a mode that your screen cannot handle. If it is a
+ non-standard mode, maybe you need to tweak the timings a bit. If
+ it is a standard mode and frequency that your screen should be
+ able to handle, try to find different timings for a similar mode
+ and frequency combination. For LCD modes, it is possible that your
+ LCD panel requires different panel timings at the text console than
+ with a graphics mode. In this case you will need the
+ "<tt>UseModeline</tt>" and perhaps also the "<tt>FixPanelSize</tt>"
+ options to reprogram the LCD panel timings to sensible values.
+<tag> `Wavy' screen.</tag>
+ Horizontal waving or jittering of the whole screen, continuously
+ (independent from drawing operations). You are probably using a
+ dot clock that is too high (or too low); it is also possible that
+ there is interference with a close MCLK. Try a lower dot clock.
+ For CRT's you can also try to tweak the mode timings; try increasing
+ the second horizontal value somewhat.
+<tag> Crash or hang after start-up (probably with a black screen).</tag>
+ Try the "<tt>NoAccel</tt>" or one of the XAA acceleration options
+ discussed above. Check that the BIOS settings are OK; in particular,
+ disable caching of 0xa0000-0xaffff. Disabling hidden DRAM refresh
+ may also help.
+<tag> Hang as the first text is appearing on the screen on SVR4 machines.</tag>
+ This problem has been reported under UnixWare 1.x, but not tracked
+ down. It doesn't occur under UnixWare 2.x and only occurs on the
+ HiQV series of chips. It might affect some other SVR4 operating
+ systems as well. The workaround is to turn off the use of CPU to
+ screen acceleration with the
+ "<tt>XaaNoCPUToScreenColorExapndFill</tt>" option.
+<tag> Crash, hang, or trash on the screen after a graphics operation.</tag>
+ This may be related to a bug in one of the accelerated
+ functions, or a problem with the BitBLT engine. Try the
+ "<tt>NoAccel</tt>" or one of the XAA acceleration options
+ discussed above. Also check the BIOS settings. It is also possible
+ that with a high dot clock and depth on a large screen there is
+ very little bandwidth left for using the BitBLT engine. Try
+ reducing the clock.
+<tag> Chipset is not detected.</tag>
+ Try forcing the chipset to a type that is most similar to what
+ you have.
+<tag>The screen is blank when starting X</tag>
+ One possible cause of this problem with older linux kernels is that
+ the "APM_DISPLAY_BLANK" option didn't work correct. Either upgrade
+ your kernel or rebuild it with the "APM_DISPLAY_BLANK" option
+ disabled. If the problem remains, or you aren't using linux, a
+ CRT/LCD or switch to and from the virtual console will often fix it.
+<tag> Textmode is not properly restored</tag>
+ This has been reported on some configurations. Many laptops
+ use the programmable clock of the 6554x chips at the console.
+ It is not always possible to find out the setting that is
+ used for this clock if BIOS has written the MClk after the
+ VClk. Hence the server assumes a 25.175MHz clock at the
+ console. This is correct for most modes, but can cause some
+ problems. Usually this is fixed by switching between the LCD
+ and CRT. Alternatively the user can use the "<tt>TextClockFreq</tt>"
+ option described above to select a different clock for the
+ text console. Another possible cause of this problem is if
+ linux kernels are compiled with the "APM_DISPLAY_BLANK" option.
+ As mentioned before, try disabling this option.
+<tag> I can't display 640x480 on my 800x600 LCD</tag>
+ The problem here is that the flat panel needs timings that
+ are related to the panel size, and not the mode size. There is
+ no facility in the current Xservers to specify these values,
+ and so the server attempts to read the panel size from the
+ chip. If the user has used the "<tt>UseModeline</tt>" or
+ "<tt>FixPanelSize</tt>" options the panel timings are derived
+ from the mode, which can be different than the panel size. Try
+ deleting theses options from XF86Config or using an LCD/CRT switch.
+<tag> I can't get a 320x240 mode to occupy the whole 640x480 LCD</tag>
+ There is a bug in the 6554x's H/W cursor for modes that are
+ doubled vertically. The lower half of the screen is not accessible.
+ The servers solution to this problem is not to do doubling vertically.
+ Which results in the 320x240 mode only expanded to 640x360. If this
+ is a problem, a work around is to remove the "<tt>HWcursor</tt>"
+ option. The server will then allow the mode to occupy the whole
+ 640x480 LCD.
+<tag> After a suspend/resume my screen is messed up</tag>
+ During a suspend/resume, the BIOS controls what is read and
+ written back to the registers. If the screen is using a mode
+ that BIOS doesn't know about, then there is no guarantee that
+ it will be resumed correctly. For this reason a mode that is
+ as close to VESA like as possible should be selected. It is also
+ possible that the VGA palette can be affected by a suspend/resume.
+ Using an 8bpp, the colour will then be displayed incorrectly. This
+ shouldn't affect higher depths, and is fixable with a switch to
+ the virtual console and back.
+<tag> The right hand edge of the mode isn't visible on the LCD</tag>
+ This is usually due to a problem with the "<tt>LcdCenter</tt>"
+ option. If this option is removed form XF86Config, then the problem
+ might go away. Alternatively the manufacturer could have incorrectly
+ programmed the panel size in the EGA console mode. The
+ "<tt>FixPanelSize</tt>" can be used to force the modeline values into
+ the panel size registers. Two machines that are known to have this
+ problem are the "<tt>HP OmniBook 5000</tt>" and the "<tt>NEC Versa
+ 4080</tt>".
+<tag> My TFT screen has a reddish tint in 24bpp mode</tag>
+ For 6554x chipsets the server assumes that the TFT bus width is
+ 24bits. If this is not true then the screen will appear to have a
+ reddish tint. This can be fixed by using the "<tt>18BitBus</tt>"
+ option. Note that the reverse is also true. If the "<tt>18BitBus</tt>"
+ is used and the TFT bus width is 24bpp, then the screen will appear
+ reddish. Note that this option only has an effect on TFT screens.
+<tag> SuperProbe won't work with my chipset</tag>
+ At least one non-PCI bus system with a HiQV chipset has been found to
+ require the "<tt>-no_bios</tt>" option for SuperProbe to correctly
+ detect the chipset with the factory default BIOS settings. The server
+ itself can correctly detect the chip in the same situation.
+<tag> My 690xx machine lockups when using the "<tt>MMIO</tt>" option</tag>
+ The 690xx MMIO mode has been implemented entirely from the manual
+ as I don't have the hardware to test it on. At this point no testing
+ has been done and it is entirely possible that the "<tt>MMIO</tt>
+ option will lockup your machine. You have been warned! However if
+ you do try this option and are willing to debug it, I'd like to hear
+ from you.
+<tag> My TrueColor windows are corrupted when using the "<tt>Overlay</tt>" option </tag>
+ Chips and Technologies specify that the memory clock used with the
+ multimedia engine running should be lower than that used without. As
+ use of the HiQV chipsets multimedia engine was supposed to be for
+ things like zoomed video overlays, its use was supposed to be
+ occasional and so most machines have their memory clock set to a value
+ that is too high for use with the "<tt>Overlay</tt>" option. So with
+ the "<tt>Overlay</tt>" option, using the "<tt>SetMClk</tt>" option to
+ reduce the speed of the memory clock is recommended.
+<tag> I can't start X-windows with 16, 24 or 32bpp</tag>
+ Firstly, is your machine capable of 16/24/32bpp with the mode
+ specified. Many LCD displays are incapable of using a 24bpp
+ mode. Also you need at least a 65540 to use 16/24bpp and at least a
+ 65550 for 32bpp. The amount of memory used by the mode will be
+ doubled/tripled/quadrupled. The correct options to start the server
+ with these modes are
+
+<verb>
+ startx -- -depth 16 5-6-5 RGB ('64K color', XGA)
+ startx -- -depth 15 5-5-5 RGB ('Hicolor')
+ startx -- -depth 24 8-8-8 RGB truecolor
+</verb>
+ or with the HiQV series of chips you might try
+<verb>
+ startx -- -depth 24 -fbbpp 32 8-8-8 RGB truecolor
+</verb>
+ however as XFree86 version &relvers; allows 32bpp pixmaps to be
+ used with framebuffers operating in 24bpp, this mode of operating
+ will cost performance for no gain in functionality.
+
+ Note that the "<tt>-bpp</tt>" option has been removed
+ and replaced with a "<tt>-depth</tt>" and "<tt>-fbbpp</tt>"
+ option because of the confusion between the depth and number of
+ bits per pixel used to represent to framebuffer and the pixmaps
+ in the screens memory.
+</descrip>
+
+ A general problem with the server that can manifested in many way such
+ as drawing errors, wavy screens, etc is related to the programmable
+ clock. Many potential programmable clock register setting are unstable.
+ However luckily there are many different clock register setting that
+ can give the same or very similar clocks. The clock code can be fooled
+ into giving a different and perhaps more stable clock by simply changing
+ the clock value slightly. For example 65.00MHz might be unstable while
+ 65.10MHz is not. So for unexplained problems not addressed above, please
+ try to alter the clock you are using slightly, say in steps of 0.05MHz
+ and see if the problem goes away. Alternatively, using the
+ "<tt>UseVClk1</tt>" option with HiQV chips might also help.
+
+
+ For other screen drawing related problems, try the "<tt>NoAccel</tt>" or
+ one of the XAA acceleration options discussed above. A useful trick for
+ all laptop computers is to switch between LCD/CRT (usually with something
+ like Fn-F5), if the screen is having problems.
+
+ If you are having driver-related problems that are not addressed by this
+ document, or if you have found bugs in accelerated functions, you can
+ try contacting the XFree86 team (the current driver maintainer can be
+ reached at <it>dbateman@eng.uts.edu.au</it> or
+ <it>Egbert.Eich@Physik.TH-Darmstadt.DE)</it>,
+ or post in the Usenet newsgroup "<it>comp.windows.x.i386unix</it>".
+
+<sect> Disclaimer <p>
+
+XFree86, allows the user to do damage to their hardware with software.
+Although the authors of this software have tried to prevent this, they
+disclaim all responsibility for any damage caused by the software. Use
+caution, if you think the Xserver is frying your screen, TURN THE COMPUTER
+OFF!!
+
+<sect> Acknowledgement <p>
+
+The authors of this software wish to acknowledge the support
+supplied by Chips and Technologies during the development of this
+software.
+
+<sect> Authors <p>
+
+<tt>Major Contributors</tt> (In no particular order)
+<itemize>
+<item>Nozomi Ytow
+<item>Egbert Eich
+<item>David Bateman
+<item>Xavier Ducoin
+</itemize>
+
+<tt>Contributors</tt> (In no particular order)
+<itemize>
+<item>Ken Raeburn
+<item>Shigehiro Nomura
+<item>Marc de Courville
+<item>Adam Sulmicki
+<item>Jens Maurer
+</itemize>
+
+We also thank the many people on the net who have contributed by reporting
+bugs and extensively testing this server.
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/cirrus.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/cirrus.sgml
new file mode 100644
index 000000000..300e8c0bb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/cirrus.sgml
@@ -0,0 +1,977 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+
+<!-- Title information -->
+<title> Information for Cirrus Chipset Users
+<author> Harm Hanemaayer (<it>H.Hanemaayer@inter.nl.net</it>),
+Randy Hendry (<it>randy@sgi.com</it>) (64xx),
+Corin Anderson (<it>corina@the4cs.com</it>)
+<date> 5 November 1998
+
+<!-- Table of contents -->
+<toc>
+
+<sect> Supported chipsets <p>
+
+There are two different SVGA drivers for Cirrus chipsets, one called
+``cirrus'' and one called ``cl64xx''.
+The ``cirrus'' driver is used in the 256-color SVGA server (with
+acceleration) and the mono server (without acceleration). The SVGA server
+supports 16, 24, and 32 bits-per-pixel truecolor modes on some configurations.
+The ``cl64xx'' driver is used in the 256-color SVGA, 16-color and mono
+servers. Note that except where stated otherwise, this document is
+referring to the ``cirrus'' driver.
+The following chipsets by Cirrus Logic are supported:
+<descrip>
+<tag>CL-GD5420</tag>
+ ISA SVGA chipset, 1Mbyte; maximum dot clock is 45 MHz (256
+ color server). Acceleration with extended write modes (used
+ for scrolling and solid filling in this driver). This chipset
+ can <em>not</em> support 1024x768 non-interlaced in 256 colors.
+<tag>CL-GD5422</tag>
+ Enhanced version of the 5420 (32-bit internal memory
+ interface). Maximum dot clock is 80 MHz.
+<tag>CL-GD6205/6215/6225/6235</tag>
+ Laptop chipsets more or less compatible with the 5420. The
+ only dot clock supported is 25 MHz (more on an external
+ display). Some problems have been reported with these
+ chipsets (especially on external displays). Take note of
+ the "<tt>noaccel</tt>" option.
+<tag>CL-GD6420/6440</tag>
+ These chipsets are not compatible with the 542x series, but are
+ supported by the ``cl64xx'' driver. It is used in
+ recent laptops, and bears some similarity to old Cirrus
+ chipsets (5410/AVGA2). The driver may also work for other
+ 64xx chips. The configuration identifiers for this driver are
+ "<tt>cl6420</tt>" and <tt>"cl6440"</tt>. This driver is discussed
+ in detail in section <ref id="cl64xx" name="The cl64xx Driver">.
+<tag>CL-GD5424</tag>
+ Basically VLB version of the 5422, but resembles the
+ 5426 in some respects.
+<tag>CL-GD5426</tag>
+ Supports both ISA bus and VLB, and up to 2Mbyte of memory.
+ Has BitBLT engine for improved acceleration (BitBlt, image
+ transfer, text). Dot clock limit is 85 MHz.
+<tag>CL-GD5428</tag>
+ Enhanced version of the 5426.
+<tag>CL-GD5429</tag>
+ Enhanced version of the 5428; officially supports higher
+ MCLK and has memory-mapped I/O.
+<tag>CL-GD5430</tag>
+ Similar to 5429, but with 543x core (32-bit host interface).
+ Does not have 64-bit memory mode.
+<tag>CL-GD5434</tag>
+ `Alpine' family chip with 64-bit internal memory interface.
+ The chip
+ can only support 64-bit mode if equipped with 2 Mbytes of
+ memory; cards with only 1 Mbyte are severely limited.
+ Supports dot clocks up to 110 MHz (later chips support
+ 135 MHz).
+<tag>CL-GD5436</tag>
+ Highly optimized 5434.
+<tag>CL-GD5440</tag>
+ Similar to the CL-GD5430, and detected as such.
+<tag>CL-GD5446</tag>
+ Another member of the Alpine family of 2D accelerators; similar
+ to the CL-GD5436.
+<tag>CL-GD5480</tag>
+ Newer Alpine family chip that support synchronous graphics RAM
+ (SGRAM).
+<tag>CL-GD5462, CL-GD5464 and CL-GD5465</tag>
+ The Laguna VisualMedia family of 2D Accelerators. These chips
+ use Rambus RDRAM memory. The '62 is a 64-bit 2D
+ accelerator, including a BitBlit engine, video windows (not currently
+ used by the server), and 64x64 HW cursor. Mono modes have not been
+ tested. The CL-GD5464 is the next chip in the Laguna family, and the
+ CL-GD5465 is the latest member, both have been tested.
+<tag>CL-GD7541/7542/7543/7548</tag>
+ Laptop chipsets more or less compatible with the 5428/3x.
+ While has it been tested on some configurations, not all
+ configuration may work correctly.
+<tag>CL-GD7555</tag>
+ Limited untested support, without auto-detection, has been
+ provided for this chip which is a 64-bit extension of the 754x
+ family. Use a Chipset "clgd7555" line.
+</descrip>
+
+Here's a list of maximum dot clocks for each supported depth:
+
+<quote><verb>
+ mono 8 bpp (256c) 16 bpp 24 bpp 32 bpp
+CL-GD62x5 45 MHz 45 MHz
+CL-GD5420 80 MHz 45 MHz (1)
+CL-GD542x/512K 80 MHz 45 MHz
+CL-GD5422/24 80 MHz 80 MHz 40 MHz 27 MHz
+CL-GD5426/28 85 MHz 85 MHz 45 MHz (2) 28 MHz
+CL-GD5429 85 MHz 85 MHz 50 MHz 28 MHz
+CL-GD5430 85 MHz 85 MHz 45 MHz (2) 28 MHz
+CL-GD5434/1Mb 85 MHz 85 MHz 42 MHz 28 MHz
+CL-GD5434/2Mb 85 MHz 110/135 MHz 85 MHz 28 MHz 45/50 MHz (2)
+CL-GD5436/1Mb 85 MHz 110 MHz (3) 60 MHz (3) 40 MHz (3)
+CL-GD5436/2Mb 85 MHz 135 MHz 85 MHz 85 MHz (3) 60 MHz (3)
+CL-GD5446/1Mb 85 MHz 110 MHz (3) 60 MHz (3) 40 MHz (3)
+CL-GD5446/2Mb 85 MHz 135 MHz 85 MHz 85 MHz (3) 60 MHz (3)
+CL-GD5462 170 MHz 170 Mhz 170 MHz 170 MHz 135 MHz
+CL-GD5464/65 170 MHz 230 Mhz 170 MHz 170 MHz 135 MHz
+CL-GD5480 85 MHz 200 MHz 100 MHz 100 MHz 50 MHz
+CL-GD754x 80 MHz 80 MHz 40 MHz (4) (5)
+
+(1) with 512K memory.
+(2) 50 MHz with high MCLK setting.
+(3) Depends on memory clock.
+(4) This may be too low for some chips.
+(5) This depth may actually work if it is enabled and tested.
+</verb></quote>
+
+Rough virtual/physical screen resolution limits for different amounts of
+video memory:
+<quote><verb>
+ mono 8 bpp 16 bpp 24 bpp 32 bpp
+256K 800x600 640x400
+512K 1152x900 800x600 640x400
+1024K 1600x1200 1152x900 800x600 680x510
+2048K 2304x1728 1600x1200 1152x900 960x720 800x600
+4096K 2304x1728 2272x1704 1600x1200 1360x1020 1152x900
+</verb>
+</quote>
+For 546x chips, the above table isn't quite accurate. While the virtual
+width may be any size, the screen <it>pitch</it> will be rounded up to the
+nearest value in the table
+below. Thus, each line on the screen will take more video memory than just
+what is displayed. To maximize video memory, then, choose the virtual
+desktop width from the table of pixel widths below:
+<quote><verb>
+8bpp: 640, 1024, 1280, 1664, 2048, 2560, 3328, 4096, 5120, 6656
+16bpp: 320, 512, 640, 832, 1024, 1280, 1664, 2048, 2560, 3328
+24bpp: 640, 1024, 1280, 1664, 2048, 2560, 3328, 4096, 5120, 6656
+32bpp: 160, 256, 320, 416, 512, 640, 832, 1024, 1280, 1664
+</verb></quote>
+
+For other Cirrus chips, it's advisable to have a virtual width that is a
+multiple of 32 if acceleration is used.
+The horizontal monitor timings must be below 2048.
+
+To run <tt>XF86_SVGA</tt> at a higher color depth, pass options to the
+X server as follows:
+<verb>
+startx -- -bpp 16 5-6-5 RGB ('64K color', XGA)
+startx -- -bpp 16 -weight 555 5-5-5 RGB ('Hicolor') (not on 5462)
+startx -- -bpp 24 8-8-8 RGB truecolor
+startx -- -bpp 32 8-8-8 XRGB truecolor (543X/46/6X only)
+</verb>
+
+
+<sect> Basic configuration <p>
+
+It is recommended that you generate an XF86Config file using
+the `<tt>XF86Setup</tt>' or `<tt>xf86config</tt>' program, which should
+produce a working
+high-resolution 8bpp configuration. You may want to include mode
+timings in the <tt>Monitor</tt> section that better fit your monitor
+(e.g 1152x900 modes). The driver options are described in detail in
+the next section; here the basic options are hinted at.
+
+For all chipsets, a <tt>Clockchip "cirrus"</tt> line in the
+<tt>Device</tt> section can be useful. This allows the use of any dot
+clocks, instead of one out of the fixed set of dot clocks supported
+by the driver. This is required if you want a 12.6 MHz dot clock for
+low-resolution modes. However, when this option used, clock frequencies
+be unstable leading to strange effects, so only use it if absolutely
+required.
+
+For any chip with a BitBLT engine, the new XAA (XFree86 Acceleration
+Architecture) is used. This code is new and still in a beta stage.
+If graphics redrawing goes wrong, try the
+<tt>"noaccel"</tt> option; if it is using memory-mapped I/O,
+<tt>"no_mmio"</tt> might be sufficient.
+
+In order to be able to run at a depth of 16bpp, 24bpp, or 32bpp, and to improve
+performance at 8bpp, linear addressing must be enabled. This is generally
+
+In order to be able to run at a depth of 16bpp, 24bpp or 32bpp, and to improve
+performance at 8bpp, linear addressing must be enabled. Linear addressing
+is the default mode of operation on any PCI-bus configuration; use
+<tt>"nolinear"</tt> to disable it.
+For other bus types, it is generally
+possible on 543x local bus cards, and if you have less than 16Mb of system
+memory, on local bus 542x cards and ISA 543x cards. You must specify
+the <tt>"linear"</tt> option and possibly a <tt>Membase</tt>
+address. See the following sections for a detailed description.
+
+Memory-mapped I/O is the default mode of operation for any Alpine family
+chip. For the 5429, the <tt>"mmio"</tt> option may be used
+to enable it, but it has not been tested.
+
+Finally, if you have 546X chip, it will be on either a PCI or AGP bus.
+As such, there
+is no problem about memory mapped I/O or linear frame buffer address spaces
+running into system memory. The PCI spaces are mapped way up near the 4GB
+point. Because the mmio and linear frame buffer don't conflict at all on
+the system, the <tt>"linear"</tt>, <tt>Membase</tt>, and
+<tt>"mmio"</tt> options are ignored (memory mapped I/O and linear
+addressing are always used).
+
+<sect> XF86Config options <p>
+Don't use the `<tt>Clocks</tt>' command. The clocks are fixed
+(i.e. not probed), and
+there should be no variation between cards (other than the maximum supported
+clock for each chipset).
+
+The following options are of particular interest to the Cirrus driver. Each
+of them must be specified in the `<tt>svga</tt>' driver section of the
+<tt>XF86Config</tt>
+file, within the <tt>Screen</tt> subsections of the depths to which they are
+applicable (you can enable options for all depths by specifying them in the
+Device section).
+<descrip>
+<tag>Option "noaccel"</tag>
+ This option will disable the use of any accelerated functions. This
+ is likely to help with problems related to bugs in acceleration
+ functions, and perhaps high dot clocks and DRAM timing, at the cost
+ of performance (which will still be reasonable on a local bus).
+<tag>Option "fast_dram" "med_dram"
+"slow_dram" (5424/6/8/9, 543x, 5446, 546x)
+</tag>
+ These options set the internal memory clock (MCLK, or BCLK for
+ the 546x) register to
+ another value. The default value programmed by the BIOS is
+ usually OK, don't mess with these options unless absolutely
+ required.
+
+ The <tt>"fast_dram"</tt> option will cause the driver to set the
+ internal
+ memory clock (MCLK) register of the video card to a higher value
+ (recent chips use an even higher value by default).
+ Normally, this register is not touched but it appears that the
+ standard CL-GD542x BIOS initializes it to a value that is somewhat
+ on the low side (limited by the chip specification), which has a
+ negative influence on performance of high dot clock modes. This
+ is especially true if extended RAS timing is being used (this is
+ indicated in the server probe).
+ The actual speed of DRAM is not a critical factor in the determining
+ whether this option is appropriate; one CL-GD5426-based card with
+ 80ns DRAM using Extended RAS timing, which came with a DOS driver
+ utility to set the MCLK to this value (0x22), seems to run stable
+ at higher MCLK.
+
+ There are also (mainly brand name) cards whose customized BIOS does
+ initialize to a higher non-standard value.
+
+ The <tt>"slow_dram"</tt>
+ option will set the MCLK to the value used by the
+ standard CL-GD542x BIOS (0x1c). Symptoms of a MCLK that is too high
+ can be vertical bands of flickering pixels on the screen, erroneous
+ pixels appearing in text, and loosing pixels in the textmode font
+ after running X (note that very similar effects can be caused by an
+ MCLK setting that is too low).
+
+ Upon start-up, the driver will report the value of the MCLK
+ register (check this first), and also any changes that are made.
+
+ Typical MCLK values:
+ <descrip>
+ <tag/0x1c (50 MHz)/
+ This is usually the BIOS default.
+ It is forced by the <tt>"slow_dram"</tt> option.
+ <tag/0x1f (55 MHz)/
+ Value used by the <tt>"med_dram"</tt> option.
+ Highest value that
+ 542x based cards seem to be able to handle with linear
+ addressing enabled.
+ <tag/0x22 (60 MHz)/
+ Value that most (Extended RAS) 542x cards seem to be able to
+ handle, used by the <tt>"fast_dram"</tt> option.
+ </descrip>
+
+ The official maximum of the 542x chips is 50 MHz.
+ The official spec. for the 5434 is also 50 MHz (0x1c)
+ and that for
+ the 5429 and 5430 is probably 60 MHz (0x22). Current revisions
+ of the 5434 (E and greater) support 60 MHz MCLK in graphics modes,
+ and the driver will program this automatically. If it causes
+ problems, use the <tt>"slow_dram"</tt> option.
+
+ The driver takes the MCLK into account for clock limits that
+ are determined by DRAM bandwidth.
+
+ For the 546x chips, the BCLK is the Rambus access clock.
+ Typical values live in the range of 258 MHz to 300 MHz. If you
+ have troubles, such as a black checkerboard pattern on the
+ screen, try using the <tt>"med_dram"</tt> or
+ <tt>"slow_dram"</tt> options.
+
+ In all cases, if you are not having any problems (performance
+ or stability at high dot clocks), it is best not to use any of
+ the DRAM options.
+<tag>
+Option "no_bitblt"
+</tag>
+ This option, when used with a 5426/28/29/3x/46/6x/754x, will have the
+ effect of
+ disabling the use of the BitBLT engine (which the 5424 does not
+ have), while retaining some acceleration. This will be useful for
+ problems related to functions that use the BitBLT engine.
+ Performance is significantly decreased.
+<tag>
+Option "no_imageblt"
+</tag>
+ This option is now obsolete. The "xaa_no_color_exp" option has a
+ somewhat similar effect.
+<tag>
+chipset "clgd54xx"
+</tag>
+ Force detection of the given chipset. Useful if you have a supported
+ chipset that is not properly detected, or if you have an unsupported
+ chip that might be compatible with a supported one.
+<tag>
+videoram 1024 (or another value)
+</tag>
+ This option will override the detected amount of video memory, and
+ pretend the given amount of memory is present on the card. This is
+ useful on cards with 2Mbyte of memory whose DRAM configuration is
+ not compatible with the way the driver enables the upper megabyte of
+ memory, or if the memory detection goes wrong. It must be specified
+ in the Device section.
+<tag>
+Option "fifo_conservative" (5424/6/8/9/3x/46/6x/754x)
+</tag>
+ This option will set the CRT FIFO threshold to a conservative value
+ for high dot clocks (&gt;= 65 MHz), reducing performance but hopefully
+ alleviating problems with what can be described as flashing
+ `streaks', `jitter' or horizontally repeated display areas on the
+ screen (especially when a BitBLT operation is in progress, e.g.
+ scrolling).
+<tag>
+Option "fifo_aggressive" (5424/6/8/9/3x/46/6x/754x)
+</tag>
+ This option will set the CRT FIFO threshold to an aggressive value;
+ it will be the same as that used for lower dot clocks.
+ Theoretically it improves performance at high dot clocks, but
+ it does not help in the vast majority of cases. In some
+ cases with 546x chips, however, this option can help
+ reduce horizontal streaks or otherwise fix abnormal
+ display problems (display shifted to the left, etc.).
+<tag>
+Option "no_2mb_banksel" (542x)
+</tag>
+ This option will cause the driver not to set the `DRAM bank select'
+ bit to enable the upper megabyte of memory on a 2Mbyte card. This
+ should be helpful with cards equipped with 512Kx8 DRAMs, as opposed
+ to 256Kx4/16 DRAMs, when using a virtual screen configuration that
+ uses more than 1Mbyte of memory.
+<tag>
+Option "probe_clocks"
+</tag>
+ This option will force probing of dot clocks on the card. This
+ should not be necessary, since the clocks are fixed and the same for
+ all Cirrus chipsets.
+<tag>
+Clockchip "cirrus"
+</tag>
+ This enables programmable clocks. It must be specified in the
+ Device section. With this option, the clocks the modes use will
+ be automatically selected. Do not specify any Clocks line. This
+ option makes a 12.5 MHz clock possible for a 320x200 Doublescan
+ mode. Note that some frequencies may be unstable (resulting in
+ a `wavy' screen). Only tried
+ and tested frequencies (like the default clocks) are guaranteed
+ to be stable.
+<tag>
+Option "linear" (542x/6/8/9/3x/754x on VL-bus)
+</tag>
+ This enables linear addressing, which is the mapping of the entire
+ framebuffer to a high address beyond system memory, so that SVGA
+ bank switching is not necessary. It enhances performance at 256
+ colors, and is currently required for 16bpp, 24bpp, and 32bpp. See
+ section 4 for details.
+ <tag>
+Option "nolinear" (542x/6/8/9/3x/754x on PCI bus)
+</tag>
+ Linear addressing is the default mode of operation on any
+ PCI-bus chip. For these configurations, this option disables
+ linear addressing.
+<tag>
+Membase 0x00e00000 (or a different address) (542x/6/8/9/3x/46/754x)
+</tag>
+ This sets the physical memory base address of the linear
+ framebuffer. It must be specified in the Device section. It is
+ required for non-PCI linear addressing configurations.
+<tag>
+Option "favour_bitblt" (5426 only)
+</tag>
+ This option is now obsolete.
+<tag>
+Option "mmio" (5429, 7548)
+</tag>
+ This enables the use of memory-mapped I/O to talk to the BitBLT
+ engine on the 543x/5429, which is a bit faster. This is option
+ has no effect when not using the BitBLT engine (e.g. when using
+ "no_bitblt").
+<tag>
+Option "no_mmio" (543x/4x)
+</tag>
+ This disables the use of memory-mapped I/O to talk to the BitBLT
+ engine on any chip for which it is the default mode of
+ operation.
+<tag>
+Option "sw_cursor" (542x/3x/46/6x)
+</tag>
+ This disables use of the hardware cursor provided by the chip. Try
+ this if the cursor seems to have problems. In particular, use this
+ when using dot clocks greater than 85 MHz on the 5434/6 since those
+ chips don't fully support the hardware cursor at those clocks.
+<tag>
+Option "clgd6225_lcd"
+</tag>
+ Provides a work-around for problems on the LCD screen of some
+ 62x5 laptop chipsets with maximum white colors.
+<tag>
+Option "no_pixmap_cache"
+</tag>
+ When XAA is used (on any BitBLT chip), this option disables
+ the use of a pixmap cache in XAA. It could help with certain
+ drawing bugs.
+<tag>
+Option "xaa_no_color_exp"
+</tag>
+ When XAA is used, this option disables the use of hardware color
+ expansion features by XAA. Again, this might help with certain
+ drawing bugs.
+<tag>
+Option "no_stretch" (754x)
+</tag>
+ Disable automatic stretching (horizontal and vertical expansion)
+ of 640x480 on a 800x600 LCD.
+<tag>
+Option "pci_retry" (546x)
+</tag>
+ Enables a performance feature for PCI based cards. When this
+ feature is enabled, the driver code will attempt to transmit
+ data on the PCI bus as fast as possible. For the most part,
+ this option is safe, but may cause trouble with other PCI
+ devices such as PCI network cards, sound cards, SCSI
+ controllers, etc. When this option is not selected, a safer
+ approach (polling the VGA's command queue) is taken.
+</descrip>
+
+
+<sect> Mode issues <p>
+
+The accelerated 256-color driver uses 16K bytes of scratch space in video
+memory, and the hardware cursor also uses 1K (2K on the '6X). Consequently,
+a 1024x1024 virtual resolution should not be used with a 1Mbyte card.
+
+On older chips,
+the use of a higher dot clock frequencies has a negative effect on the
+performance of graphics operations, especially BitBlt, when little
+video memory bandwidth is left for drawing (the amount is displayed
+during start-up for 542x/3x/46/6x chips). For the 542x/3x chips, with
+default MCLK setting (0x1c) and a 32-bit memory interface, performance
+with a 65 MHz dot clock can be half of that with a dot clock of 25
+MHz. So if you are short on memory bandwidth and experience blitting
+slowness, try using the lowest dot clock that is acceptable; for
+example, on a 14" or 15" screen 800x600 with high refresh (50 MHz dot
+clock) is not so bad, with a large virtual screen.
+
+5434-based cards with 2Mbyte of memory do much better at high dot clocks;
+the DRAM bandwidth is basically double that of the 542x series. The 543x
+chips also make more efficient use of the available DRAM bandwidth. The
+same goes for the 544x.
+
+<sect> Linear addressing and 16bpp/24bpp/32bpp modes <p>
+
+Currently the framebuffer code 16-bit, 24-bit, and 32-bit pixels in
+the SVGA
+server requires linear addressing. Option
+"linear" can be specified in a
+depth-specific screen section to enable linear addressing; a MemBase
+setting (in the device section) is probably also required (although they
+are both automatically selected with PCI cards, like 5446, 546x, and some
+543x based cards). There
+are a number of different card configurations.
+
+If you have a 542x/543x on the ISA bus, and you have 16Mb or more of
+system memory, linear addressing is impossible. 16bpp is out, sorry.
+If you have less than 14Mb of memory, you may be able to map the
+framebuffer at 14Mb, using `<tt>MemBase 0x00e00000</tt>'. That's five zeros
+after the `e'. Unfortunately many ISA cards don't support linear
+addressing.
+
+If you have a 5424/26/28/29 on VESA local bus, the situation is more
+complicated. There are two different types of cards w.r.t. linear
+addressing:
+<itemize>
+<item>Cards that can only map in the lower 16Mb, like cards on the ISA bus.
+ This is the case with most cards. The same
+ restrictions apply (i.e. you must have less than 16Mb of memory).
+<item>Cards that connect address line A26 and always map at 64Mb + 14Mb or
+ 64Mb. In
+ this case specify `<tt>MemBase 0x04e00000</tt>' or `<tt>MemBase
+ 0x04000000</tt>'. This assumes you have a VLB motherboard implementation
+ that implements A26. Alternatively the card may map to 0x2000000, and
+ recent cards like the 5429 usually map to 0x03e00000 (62Mb).
+</itemize>
+You will probably have to rely on trial and error. If you have less
+than 16Mb memory, the `wrong' membase setting will result in no graphics
+being displayed, but you can probably exit with ctrl-alt-backspace.
+
+If you have &gt;= 16Mb memory, the first type of card (and even the second
+type with a stupid VLB motherboard) will result in a crash (probably a
+spontaneous hard reboot).
+
+It may be possible to find out the type by visual inspection. If the card
+has a pin at A26, it is likely to map beyond 64Mb. To do this, take the card
+out. At the VESA local bus pins (this is the smaller strip of connector pins
+at the non-slot side of the card), consider the right side (this is the side
+of the board where all the chips are mounted). There are 45 pins here. They
+are numbered 1 to 45, from the inside (i.e. the one nearest to the card end
+is 45). Counting from the inside, the 17th pin is probably not present, then
+there are pins at 18-20. The 21st is A30, the 22nd is A28 and the 23rd is
+A26. So, if we have no pins at at 21-23, the card doesn't map beyond 64Mb. If
+there's only a gap of two pins at 21 and 22 (or they are both present) and
+there's a pin at 23, the card does probably map beyond 64Mb. If there's a
+little logic near that pin on the card, it's more likely.
+
+With a 543x on the local bus things are simpler (the Cirrus Logic windows
+drivers use it), but it is not quite without problems.
+
+With a card on the PCI bus, there is a PCI configuration register that holds
+the framebuffer base address, which is read automatically by the driver
+if a PCI card is detected. The `scanpci' program
+can read out the PCI configuration and show the base address.
+
+On the VESA local bus, most 543x cards have a default mapping address of
+64Mb, with jumper options for 2048Mb and 32Mb. This is probably described in
+the documentation that came with the card, or look in the MS-Windows system.ini
+file (something with linearaddr = &lt;offset in megabytes&gt;). These different
+settings were added by Cirrus Logic after finding that many VLB motherboard
+implementations don't implement different address pins. The driver assumes
+a default of 64Mb if MemBase isn't specified. A few examples for MemBase:
+<tscreen><verb>
+ MemBase 0x02000000 32Mb
+ MemBase 0x04000000 64Mb
+ MemBase 0x80000000 2048Mb
+</verb></tscreen>
+
+Finally, for 546X cards, you are in luck: there are no "issues" to worry
+about. The '6X will always use linear addressing and memory-mapped I/O,
+and will use the memory addresses up near 4GB. Yay for PCI!
+
+
+The 16bpp and 32bpp modes are now fully accelerated, thanks to XAA. On
+more recent chips like the 5436/46 and the 546X, 24bpp is also fully
+accelerated.
+So although
+there are now up to 4 times as many bits to display, the X server shouldn't
+feel overly sluggish. Note also that the 24bpp and 32bpp modes are only
+supported on a limited set of cards, and with at least 2Mb of memory.
+
+In the <tt>XF86Config</tt> <tt>"Screen"</tt> section, a
+<tt>"Display"</tt> subsection must be
+defined for each depth that you want to run, with separate Modes
+and virtual screen size. Example (2Mb of video memory):
+<tscreen><verb>
+Section "screen"
+ SubSection "Display"
+ Depth 8
+ Virtual 1280 1024
+ ViewPort 0 0
+ Modes "640x480" "800x600" "1024x768"
+ Option "linear"
+ EndSubSection
+ SubSection "Display"
+ Depth 16
+ Virtual 1024 992
+ ViewPort 0 0
+ Modes "640x480" "800x600" "1024x768"
+ Option "linear"
+ EndSubSection
+ SubSection "Display"
+ Depth 32
+ Virtual 832 600
+ ViewPort 0 0
+ Modes "640x480" "800x600"
+ Option "linear"
+ EndSubSection
+EndSection
+</verb></tscreen>
+
+<sect> The ``cl64xx'' Driver<label id="cl64xx"><p>
+The cl64xx driver supports the cl-gd6440 found in many laptops. For
+example, Nan Tan Computer's NP9200, NP3600, etc., which are OEM-ed by
+Sager, ProStar, etc. and Texas Instruments TI4000 series are supported.
+
+The driver works in LCD-only, CRT-only, and the chip's SimulScan mode
+which allows one to use both the LCD and external CRT displays
+simultaneously. The LCD and Simulscan modes' resolution is 640x480
+while, for CRT-only, the standard VESA modes of 640x480, 600x800, and
+1024x768 have been tested. Interlaced 1024x768 mode has never been
+debugged and does not work on the machines tested.
+
+The chip has a documented maximum operating limit for its dot clock
+that is related to its core voltage. Specifically, for 5.0V the
+maximum dot clock is 65MHz and for 3.3V the maximum dot clock is
+40MHz. The driver checks the core voltage and limits the maximum dot
+clock to the corresponding value. This translates to a maximum
+resolution of about 1024x768 at a 60Hz refresh rate. The internal
+frequency generator can be programmed higher than these limits and is
+done so during server startup when the clocks are probed which
+momentarily exceeding the chip's operating limit. Once a set of valid
+clocks is obtained, I would recommend using Clocks lines in
+<tt>XF86Config</tt>. Doing so will also decrease startup time significantly.
+The clocks may be obtained by running the X server -probeonly (see the
+XFree86 man page for more information about -probeonly).
+
+The data book indicates that only a configuration of one megabyte of
+video memory is supported by the chip. This size has been directly set
+in the driver. If one finds a need, one should be able to override the
+default size in <tt>XF86Config</tt>. Also, with 1MB of video memory, one should
+be able to have a virtual screen size of e.g. 1024x1024 and this is
+possible in CRT-only screen mode. However, whenever the LCD is in use
+(LCD and SimulScan), the chip uses a portion of upper video ram for
+its own internal acceleration purposes. Thus, the maximum video memory
+available for virtual resolution in LCD modes is about 0.75MB e.g.
+1024x768. If you set the virtual resolution above this, you will see
+what might be described as a compressed aliased band when the
+accelerated area is displayed.
+
+Currently, the driver does not support switching of screen modes among
+LCD, CRT, and SimulScan, and, at least on the NP9200, the mode must be
+chosen at OS boot time (e.g. Linux's LILO) while the BIOS is still
+active. It should be possible to add screen mode type selection as a
+ModeLine flag option in <tt>XF86Config</tt> to allow for dynamic screen mode
+selection from within the X server. Finally, the driver does not currently
+support any of the powerdown saving features of the chip nor does it
+shut off the LCD's backlight on screen blank. I hope to implement all
+these features in future releases.
+
+Some notes regarding the CL-GD6420:
+
+The amount of video memory may not always be detected correctly. The driver
+source code includes two methods, one defined out. Better specify the amount
+of video memory with a VideoRam line in the Device section. Use the standard
+640x480 60 Hz standard mode timing with 25.175 MHz dot clock for CRT or
+SIMulscan mode; for LCD-only operation, use the same mode timing but with
+a dot clock of 16.257 MHz. Standard 56 Hz 800x600 is also supported on
+the CRT.
+
+The primary contact for the cl6440 problems with ``cl64xx'' driver is
+Randy Hendry <em>&lt;randy@sgi.com&gt;</em>.
+
+<sect> Trouble shooting with the ``cirrus'' driver<p>
+First of all, make sure that the default modes selected from your
+<tt>XF86Config</tt>
+is supported by your monitor, i.e. make sure the horizontal sync limit is
+correct. It is best to start with standard 640x480x256 with a 25.175 MHz
+clock (by specifying a single horizontal sync of 31.5) to make sure the
+driver works on your configuration. The default mode used will always be
+the first mode listed in the modes line, with the highest dot clock listed
+for that resolution in the timing section.
+
+Note that some VESA standard mode timings may give problems on some monitors
+(try increasing the horizontal sync pulse, i.e. the difference between
+the middle two horizontal timing values, or try multiples of 16 or 32 for
+all of the horizontal timing parameters).
+<descrip>
+<tag>There is a video signal, but the screen doesn't sync.</tag>
+ You are using a mode that your monitor cannot handle. If it is
+ a non-standard mode, maybe you need to tweak the timings a bit. If
+ it is a standard mode and frequency that your monitor should be able
+ to handle, try to find different timings for a similar mode and
+ frequency combination.
+<tag>Horizontal jitter at high dot clocks.</tag>
+ This problem shows especially when drawing operations such as
+ scrolling are in progress.
+ If you're using a 542x/3x/46/6x/754x, try the
+ <tt>"fifo_conservative"</tt>
+ option. Failing that, you can try the <tt>"fast_dram"</tt> option,
+ or use a lower dot clock. If that is not sufficient, the
+ <tt>"noaccel"</tt> option or <tt>"no_bitblt"</tt> will
+ probably help. When using a 546x, option
+ <tt>"fifo_aggressive"</tt> can also be tried.
+<tag>`Wavy' screen.</tag>
+ Horizontal waving or jittering of the whole screen, continuously
+ (independent from drawing operations).
+ You are probably using a dot clock that is too high; it is also
+ possible that there is interference with a close MCLK. Try a
+ lower dot clock. You can also try to tweak the mode timings; try
+ increasing the second horizontal value somewhat. Here's a 65 MHz
+ dot clock 1024x768 mode (about 60 Hz) that might help:
+<verb>
+ "1024x768" 65 1024 1116 1228 1328 768 783 789 818
+</verb>
+ If you are using programmable clocks with Clockchip <tt>"cirrus"</tt>,
+ try disabling it and using the default set of clocks.
+<tag>Crash or hang after start-up (probably with a black screen).</tag>
+ Try the <tt>"noaccel"</tt> option. If that works,
+ try Option <tt>"no_bitblt"</tt> for
+ somewhat better performance. Check that the BIOS settings are OK;
+ in particular, disable caching of 0xa0000-0xaffff. Disabling hidden
+ DRAM refresh may also help.
+<tag>
+Crash, hang, or trash on the screen after a graphics operation.
+</tag>
+ This may be related to a bug in one of the accelerated functions, or
+ a problem with the BitBLT engine. Try the <tt>"noaccel"</tt> option,
+ or the <tt>"no_bitblt"</tt> option. Also check the BIOS settings.
+<tag>
+`Blitter timeout' messages from the server.
+</tag>
+ Same as for the above entry.
+<tag>
+Screen is `wrapped' vertically. (542x/3x/46)
+</tag>
+ This indicates a DRAM configuration problem. If your card has two
+ megabytes of memory, try the <tt>"no_2mb_banksel"</tt> option, or use
+ <tt>videoram "1024"</tt> if you only use 1 Mbyte for the virtual
+ screen.
+<tag>
+Corrupted text in terminal window.
+</tag>
+
+ This has been reported on non-standard video implementations.
+ Use the <tt>"no_bitblt"</tt> option.
+<tag>
+Streaks or hangs with laptop chipset
+</tag>
+ This can happen if the dot clock is high enough to leave very
+ little bandwidth for drawing (e.g. 40 MHz on a 512K card), and
+ (5422-style) acceleration is used.
+<tag>
+Occasional erroneous pixels in text, pixel dust when moving window-frame
+</tag>
+ Probably related to MCLK setting that is too high (can happen
+ with linear addressing even though banked mode runs OK).
+<tag>
+Chipset is not detected.
+</tag>
+ Try forcing the chipset to a type that is most similar to what
+ you have.
+<tag>
+Incorrect little lines (mostly white) appear occasionally
+</tag>
+ This may be related to a problem with system-to-video-memory BitBLT
+ operations. Try the <tt>"no_imageblt"</tt> option if it annoys you.
+<tag>
+Textmode is not properly restored
+</tag>
+ This has been reported on some configurations. In XFree86 3.1
+ the SVGA server probe would corrupt a register on the 543x,
+ requiring a Chipset line. Normally you should be able to restore
+ the textmode font using a utility that sets it (<tt>setfont</tt>,
+ <tt>runx</tt>, <tt>restorefont</tt> on Linux).
+<tag>
+Erratic system behaviour at very high dot clocks
+</tag>
+ It is possible that high dot clocks on the video card interfere with
+ other components in the system (e.g. disk I/O), because of a bad
+ card and/or motherboard design. It has been observed on some PCI
+ 5428-based cards (which are very rare, since the 5428 chip doesn't
+ support PCI).
+<tag>
+No mouse cursor, or cursor appears twice on screen
+</tag>
+ With high dot clocks, the graphics card's hardware cursor
+ doesn't operate correctly. Try option <tt>"sw_cursor"</tt> or
+ use a lower screen refresh.
+
+<tag>
+Random/garbage pixels on far right or bottom of screen (546x)
+</tag>
+ This problem is usually associated with using a virtual
+ screen size larger than the screen display size. The
+ garbage pixels are unused portions of the frame buffer
+ that result from padding each scanline to an integral
+ number of memory tiles. To eliminate the extra pixels,
+ use a screen display mode whose pixel width is evenly
+ divisible by 128 / bits per pixel.
+
+<tag>
+Screen is wrapped horizontally on right side (546x)
+</tag>
+ Same as above entry.
+
+<tag>
+The screen is initially displayed correctly, but then turns all
+white. (546x)
+</tag>
+ This problem usually happens at high bit depths and while
+ the screen is changing rapidly (catting a long file or
+ dragging a large window around). The RamBus memory is
+ being overdriven. Use Option <tt>"med_dram"</tt>, or, if
+ the problem persists, Option <tt>"slow_dram"</tt>.
+
+</descrip>
+For other screen drawing related problems, try the <tt>"noaccel"</tt>
+option (if <tt>"no_bitblt"</tt> doesn't help).
+
+If are having driver-related problems that are not addressed by this document,
+or if you have found bugs in accelerated functions, you can try contacting
+the XFree86 team (the current driver maintainer, Corin Anderson,
+can be reached at <it>corina@the4cs.com</it>), or post in the
+Usenet newsgroup "<it>comp.windows.x.i386unix</it>".
+
+In fact, reports (success or failure) are very welcome, especially
+on configurations that have not been tested. You can do this
+via the BetaReport form (mail to report@XFree86.org). You may want to
+keep an eye on forthcoming beta releases at <it>www.xfree86.org</it>.
+
+<sect> Tested Configurations <p>
+
+Version 3.3.3 has had the following configurations tested:
+
+<descrip>
+<tag>CL-GD5446 with 2MB memory on PCI bus</tag>
+
+<tag>CL-GD5464 with 2MB memory on PCI bus</tag>
+
+<tag>CL-GD5465 with 4MB memory on PCI bus</tag>
+
+<tag>CL-GD5480 with 4MB memory on PCI bus</tag>
+
+<tag>CL-GD5465 with 4MB memory on AGP bus</tag>
+
+</descrip>
+
+For version 3.3, the following configurations have received a
+certain amount of testing:
+
+<descrip>
+<tag>CL-GD5446 with 2MB memory on PCI bus</tag>
+ Support for dot clocks > 85 MHz has been fixed. At 16bpp, it
+ has been reported that some stippled edges of window frames
+ may be corrupted or show the wrong colors. The option
+ "xaa_no_pixmap_cache" eliminates the problem.
+
+<tag>CL-GD5464 with 4MB memory on PCI bus</tag>
+
+<tag>CL-GD7543 on PCI bus</tag>
+
+</descrip>
+
+
+This is a list of configurations that has received testing with one or
+more of the changes introduced in version XFree86 3.2A. The amount of
+testing is very small for some of the configurations, and the summaries
+may be incomplete. If you can contribute, please do so. For the latest
+information check the latest version of this document on
+<it>www.xfree86.org</it>.
+
+<descrip>
+<tag>CL-GD5426 on VL-bus</tag>
+ This configuration was only tested with an early version of
+ the XAA code.
+
+<tag>CL-GD5434 with 2MB memory on VL-bus</tag>
+ MMIO operation is supported. This configuration was only tested
+ with an early version of the XAA code.
+
+<tag>CL-GD5436 with 2MB memory on PCI-bus</tag>
+ Works OK. Non-MMIO operation might have problems.
+
+<tag>CL-GD5446 with 2MB memory on PCI bus</tag>
+ Works OK in MMIO mode. 32bpp probably doesn't work. The support
+ for dot clocks > 85 MHz at 8bpp may or may not work.
+
+<tag>CL-GD5462 with 2MB memory on PCI bus</tag>
+
+<tag>CL-GD5462 with 4MB memory on PCI bus</tag>
+
+<tag>CL-GD5464 with 4MB memory on PCI bus</tag>
+ Works OK at 8bpp, 16bpp, 24bpp and 32bpp. CL-GD5464 works OK at
+ 16bpp, -weight 555.
+
+<tag>CL-GD7543 on PCI bus</tag> Works for 8bpp, 16bpp on TFT display
+ (TI TravelMate 5000). Although the previous version, 3.2, was
+ reported to broken, on some configurations it worked, while
+ others were reported not to work correctly. On 800x600
+ displays, the recommended dot clock is 40 MHz for TFT and 33.7
+ MHz for a DSTN panel, with corresponding horizontal syncs of
+ 33.7 kHz for TFT and 38.6 kHz for DSTN. However, reports
+ indicate that the VESA standard 40 MHz 800x600 timing may cause
+ problems. The solution is decrease the fourth horizontal timing
+ number or use a dot clock of 36 MHz.
+
+</descrip>
+
+Some configurations for which no up-to-date testing data is available:
+
+<descrip>
+<tag>CL-GD5429 on VL-bus</tag>
+ BitBLT operation should be fixed in 3.2. MMIO does not work,
+ but not tested with with 3.2 or 3.2A.
+
+<tag>CL-GD5430 on PCI-bus</tag>
+ Works OK. 24bpp was broken, but should be fixed in later
+ versions (3.2A).
+
+<tag>CL-GD5430, and CL-GD5436 and CL-GD5446 with 1MB memory</tag>
+ It would be nice to know whether these chips needs the same
+ treatment at 16bpp as the CL-GD5434 with 1MB memory does.
+
+<tag>CL-GD5434 with 1MB memory on PCI bus</tag>
+ 8bpp, 16pp and 24bpp work OK. 16bpp no longer has "static"
+ problems. MMIO operation is supported.
+
+<tag>CL-GD5436 and CL-GD5446 with 1MB memory</tag>
+ In particular the FIFO settings for this configuration are uncertain.
+
+<tag>CL-GD7541</tag>
+
+<tag>CL-GD7548</tag>
+ Should be compatible with 7543, but untested. Reports indicate
+ that it worked with 3.2, and there's no reason why it shouldn't
+ work with 3.2A.
+
+</descrip>
+
+<sect> Driver Changes <p>
+
+Changes since XFree86 3.3.2:
+<itemize>
+<item>Fix transparent screen-to-screen copies on 546x.
+<item>The built-in screen saver now correctly blanks the screen
+on 546x chips.
+<item>Driver prevents the use of the HW cursor on the 546x when
+the screen height is greater than 1023 scanlines (fix to double
+pointer problem).
+<item>CPU-to-screen BitBLT transfers disabled on the 5465. This
+fix should prevent 5465 AGP lockups.
+<item>Fixed mode display problem with 5480 at high resolutions.
+</itemize>
+
+Changes since XFree86 3.2A:
+<itemize>
+<item>A bug that caused a server crash with memory-mapped I/O operation
+ on some chips has been fixed.
+<item>Correct handling of dot clocks > 85 MHz on the 5436 and 5446.
+<item>Preliminary support for the CL-GD7555 (no detection yet).
+<item>Support has been added for the CL-GD5480 and CL-GD5465.
+<item>32bpp mode has been fixed on some Alpine family chips.
+<item>Support for dot clocks up to 230 MHz has been added for Laguna
+ family chips.
+</itemize>
+
+Changes since XFree86 3.2:
+<itemize>
+<item>Enhanced acceleration using XAA on all chips with a BitBLT
+ engine.
+<item>Enhanced acceleration using XAA for the Laguna series (546x).
+<item>24bpp mode on 5430 is fixed.
+<item>Improved support for 754x, including support for LCD
+ stretching/centering.
+</itemize>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/cirrus.sgml,v 3.25 1999/08/23 06:38:53 dawes Exp $
+
+
+
+
+
+$XConsortium: cirrus.sgml /main/12 1996/10/28 05:43:32 kaleb $
+</verb>
+
+</article>
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/cyrix.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/cyrix.sgml
new file mode 100644
index 000000000..4da998ea0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/cyrix.sgml
@@ -0,0 +1,81 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+<title>Information for Cyrix Chipset Users
+<author>The XFree86 Project Inc.
+<date>22 June 1999
+<toc>
+
+<sect>Supported hardware <p>
+
+This driver (as used in the SVGA (VGA256), VGA16 and VGA_Mono servers)
+supports a single chipset `mediagx' that should work on the following Cyrix
+CPUs with integrated graphics:
+
+<itemize>
+<item>MediaGX
+<item>MediaGXi
+<item>MediaGXm
+</itemize>
+
+<sect>Features <p>
+<itemize>
+<item>accelerated
+<item>hardware cursor
+<item>support color depths 1, 4, 8 and 16
+</itemize>
+
+<sect>XF86Config Option <p>
+<descrip>
+<tag>Option "sw_cursor"</tag>
+disable the hardware cursor.
+<tag>Option "no_accel"</tag>
+completely disables acceleration. Usually not recommended.
+</descrip>
+
+<sect>Bugs and Limitations<p>
+<itemize>
+<item>On some older chipsets, the driver may trigger an illegal instruction
+just after probing for the ``scratchpad size''. If this is the case,
+email to hecker@cat.dfrc.nasa.gov with the output of
+<verb>
+XF86_SVGA -probeonly -verbose
+</verb>
+and this will be fixed.
+<item>There are limitations to the modeline values that can be specified.
+Particularly, the difference between the first two horizontal
+timings (e.g. 640 656, 1024 1048) must be at least 16 and at most 24.
+The modeline values are not used in the 3.3.4 server since there is a
+static array used to load the registers. The modeline only identifies
+that a particular resolution is desired. The standard VESA modes up
+to 1280x768 are supported. For more specific information, consult
+the source code.
+<item>The 4 colour server is slow due to the VGA banking mode used.
+Moreover,
+it does not work the way it is run by XF86Setup, which is probably
+due to the timing limitations.
+<item>The 3.3.4 server MAY totally hang the machine at times. It is
+reported to be stable on a BSD platform using twm. It has crashed
+when using resolutions greater than 800x600 on a Linux (Debian
+based) system using wm as the window manager. The safest course is
+to use the 3.3.3.1 server instead. Efforts are under way to resolve
+this issue and provide a more robust server under the 4.x release.
+
+</itemize>
+
+<sect>Authors<p>
+<itemize>
+<item>Annius Groenink <it>&lt;Annius.Groenink@cwi.nl&gt;</it>
+<item>Dirk Hohndel <it>&lt;hohndel@XFree86.org&gt;</it>
+<item>Brian Falardeau
+<item>Special thanks to Cyrix and Wyse for helping us with the development of
+this server. Brian, a Cyrix employee, made the 3.3.4 update possible since
+the new 4.0 server has been our top priority.
+</itemize>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/cyrix.sgml,v 1.2 1999/08/23 06:18:33 dawes Exp $
+</verb>
+
+</article>
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/defs.ent b/xc/programs/Xserver/hw/xfree86/doc/sgml/defs.ent
new file mode 100644
index 000000000..7975e307b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/defs.ent
@@ -0,0 +1,15 @@
+<!-- $XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/defs.ent,v 1.4 1999/08/21 14:08:30 dawes Exp $ -->
+
+<!-- shared entity definitions for the XFree86 documentation -->
+
+<!-- XFree86 version string -->
+<!ENTITY relvers CDATA "3.9.16">
+<!ENTITY prevrelvers CDATA "3.9.15">
+<!ENTITY srcvers CDATA "3916">
+<!ENTITY prevsrcvers CDATA "3915">
+
+<!-- Swap these for the next snapshot -->
+<!ENTITY % firstsnap 'IGNORE'>
+<!ENTITY % latersnap 'INCLUDE'>
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/epson.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/epson.sgml
new file mode 100644
index 000000000..cff4c200d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/epson.sgml
@@ -0,0 +1,155 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+
+<title> Information for EPSON SPC8110 Users
+<author> Thomas Mueller (tmueller@sysgo.de)
+<date> October 15, 1998
+<toc>
+
+<sect> General Notes <p>
+
+This server provides support for the Seiko/EPSON SPC8110F0A LCD VGA
+controller chip.
+
+The driver was developed and tested using an EPSON 486D4 CardPC
+using CRT display mode. LCD operation was successfully tested
+using an earlier release of this driver.
+
+The current driver has support for linear mapping of the frame buffer,
+supports the hardware cursor and uses the Bitblt engine for basic
+operations such as CopyArea and solid fills.
+
+<sect> <tt>XF86Config</tt> options <p>
+
+The driver should be able to probe the presence of a SPC8110 chip. If
+the driver fails to probe the chip correctly define the chip
+explicitly in the screen section.
+
+Device Section Entries and Options Currently Supported:
+
+<descrip>
+<tag/Chipset "spc8110"/
+
+May be specified if probing fails or to accelerate server
+startup. The value must be "spc8110".
+
+<tag/VideoRam kilobytes/
+
+If specified the value (in kilobytes) will be used, otherwise the
+amount of memory will be probed on startup.
+
+<tag/Option "sw_cursor"/
+
+Disables the use of the hardware cursor. The hardware cursor
+requires one Kbyte of video memory as pattern storage area. If
+you need the full amount of video memory you may want to disable the
+hardware cursor using this option. Also the hardware cursor code was
+not tested with cursor images larger than 64 pixels (high or wide), so
+if you use large images you may have to disable the hardware cursor.
+
+<tag/Option "no_linear"/
+
+Disables the use of the linear aperture. If this option is set the
+driver will use the standard VGA memory window at 0xa0000 otherwise it
+will map the whole video memory.
+
+<tag/Membase baseaddress/
+
+In VLB/486LB configuration the linear aperture address will
+be set to 0x03E0.0000, in PCI configuration the address will be
+read from the PCI configuration space. The base address in VLB/486LB
+systems may be set to any value using the "Membase" definition.
+
+<tag/Option "noaccel"/
+
+Disables the use of the Bitblt engine. Normally the driver
+accelerates screen-to-screen copy operations and solid fills.
+
+Since the SPC8110 puts certain restrictions on the use of the
+Bitblt engine you will notice different performance between certain
+operations (eg window movement). If this is a problem for your
+application you may want to disable the accelerator.
+
+<tag/Option "fifo_moderate"/
+
+<tag/Option "fifo_conservative"/
+
+Usually the driver computes the FIFO threshold values for the
+SPC8110's write buffer correctly. However for certain modes (eg the
+832x624 mode shown below) the FIFO is programmed too aggressively which
+leads to streaks in the display during screen updates. With option
+"fifo_moderate" the computed FIFO low request level is incremented by
+one with "fifo_conservative" it is incremented by two.
+</descrip>
+
+<sect> Video modes <p>
+
+The driver probes whether the chip is configured for CRT only or
+LCD/simultaneous mode of operation. In the former case it will
+enable clock programming and will support any mode which is
+within the limits of the hardware. If the chip is configured for
+LCD/simultaneous operation mode the driver will respect the
+settings of the BIOS and allow only one video mode conforming
+with the panel size.
+
+The driver does not support interlaced or double scan modes.
+
+<sect1> Clocks <p>
+
+Probing is supported, but of course the usual warnings and
+disclaimers apply. Probing may momentarily subject your
+monitor/panel to sweep frequencies in excess of its rating. The
+cautious may wish to turn off the monitor while the probe is
+running. In CRT mode the driver may produce video timings
+inadequate for your monitor, handle with care!
+
+As with many integrated designs the speed of the graphics operations
+depend very much of the refresh rate you use. Higher refresh rates
+yield lower performance.
+
+<sect1> Example Modes <p>
+
+The following XF86Config "Device" section should work for all
+configurations:
+
+<verb>
+ Section "Device"
+ Identifier "CardPC"
+ VendorName "EPSON"
+ BoardName "CardPC"
+ Chipset "spc8110"
+ Option "sw_cursor"
+ Membase 0x03e00000
+ Option "no_linear"
+ Option "noaccel"
+ Option "fifo_moderate"
+ EndSection
+</verb>
+
+This Modeline was tested in a 640x480 panel configuration:
+<verb>
+ Modeline "640x480" 28.36 640 672 768 800 480 490 492 525
+</verb>
+
+
+These Modelines were tested in a CRT configuration:
+<verb>
+ Modeline "640x480" 25.175 640 664 760 800 480 491 493 525
+ Modeline "800x600" 36 800 824 896 1024 600 601 603 625
+ ModeLine "832x624" 40 832 873 1001 1090 624 625 627 651
+ Modeline "640x400" 25.175 640 664 760 800 400 409 411 450
+</verb>
+
+
+
+<sect> Acknowledgments <p>
+
+Thanks to Epson Europe Electronics and ProBIT GmbH, Berlin for providing a
+loaner system and documentation to get things started.
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/epson.sgml,v 1.3 1999/08/28 10:43:33 dawes Exp $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/fbdev.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/fbdev.sgml
new file mode 100644
index 000000000..435eb91c4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/fbdev.sgml
@@ -0,0 +1,369 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+<title>The Linux/m68k Frame Buffer Device
+<author>Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+<date>7 November 1998
+<toc>
+
+<sect>Introduction
+<p>
+The frame buffer device provides an abstraction for the graphics hardware. It
+represents the frame buffer of some video hardware and allows application
+software to access the graphics hardware through a well-defined interface, so
+the software doesn't need to know anything about the low-level (hardware
+register) stuff.
+
+The device is accessed through special device nodes, usually located in the
+/dev directory, i.e. <tt>/dev/fb*</tt>.
+
+
+<sect>User's View of <tt>/dev/fb*</tt>
+<p>
+From the user's point of view, the frame buffer device looks just like any
+other device in <tt>/dev</tt>. It's a character device using major 29, the
+minor specifies the frame buffer number.
+
+By convention, the following device nodes are used (numbers indicate the device
+minor numbers):
+
+<descrip>
+<tag> 0 = <tt>/dev/fb0</tt></tag>First frame buffer
+<tag> 32 = <tt>/dev/fb1</tt></tag>Second frame buffer
+<tag>...</tag><p>
+<tag>224 = <tt>/dev/fb7</tt></tag>8th frame buffer
+</descrip>
+
+For backwards compatibility, you may want to create a symbolic link from
+<tt>/dev/fb0current</tt> to <tt>fb0</tt>.
+
+The frame buffer devices are also `normal' memory devices, this means, you can
+read and write their contents. You can, for example, make a screen snapshot by
+
+ <tscreen><verb>
+ cp /dev/fb0 myfile
+ </verb></tscreen>
+
+There also can be more than one frame buffer at a time, e.g. if you have a
+graphics card in addition to the built-in hardware. The corresponding frame
+buffer devices (<tt>/dev/fb0</tt> and <tt>/dev/fb1</tt> etc.) work
+independently.
+
+Application software that uses the frame buffer device (e.g. the X server) will
+use <tt>/dev/fb0</tt> by default (older software uses
+<tt>/dev/fb0current</tt>). You can specify an alternative frame buffer device
+by setting the environment variable <tt>&dollar;FRAMEBUFFER</tt> to the path
+name of a frame buffer device, e.g. (for sh/bash users):
+
+ <tscreen><verb>
+ export FRAMEBUFFER=/dev/fb1
+ </verb></tscreen>
+
+or (for csh users):
+
+ <tscreen><verb>
+ setenv FRAMEBUFFER /dev/fb1
+ </verb></tscreen>
+
+After this the X server will use the second frame buffer.
+
+
+<sect>Programmer's View of <tt>/dev/fb*</tt>
+<p>
+As you already know, a frame buffer device is a memory device like
+<tt>/dev/mem</tt> and it has the same features. You can read it, write it, seek
+to some location in it and <tt>mmap()</tt> it (the main usage). The difference
+is just that the memory that appears in the special file is not the whole
+memory, but the frame buffer of some video hardware.
+
+<tt>/dev/fb*</tt> also allows several ioctls on it, by which lots of
+information about the hardware can be queried and set. The color map handling
+works via ioctls, too. Look into <tt>&lt;linux/fb.h&gt;</tt> for more
+information on what ioctls exist and on which data structures they work. Here's
+just a brief overview:
+
+ <itemize>
+ <item>You can request unchangeable information about the hardware, like
+ name, organization of the screen memory (planes, packed pixels, ...) and
+ address and length of the screen memory.
+
+ <item>You can request and change variable information about the hardware,
+ like visible and virtual geometry, depth, color map format, timing, and so
+ on. If you try to change that informations, the driver maybe will round up
+ some values to meet the hardware's capabilities (or return <tt>EINVAL</tt>
+ if that isn't possible).
+
+ <item>You can get and set parts of the color map. Communication is done
+ with 16 bit per color part (red, green, blue, transparency) to support all
+ existing hardware. The driver does all the computations needed to bring it
+ into the hardware (round it down to less bits, maybe throw away
+ transparency).
+ </itemize>
+
+All this hardware abstraction makes the implementation of application programs
+easier and more portable. E.g. the X server works completely on /dev/fb* and
+thus doesn't need to know, for example, how the color registers of the concrete
+hardware are organized. <em/XF68_FBDev/ is a general X server for bitmapped,
+unaccelerated video hardware. The only thing that has to be built into
+application programs is the screen organization (bitplanes or chunky pixels
+etc.), because it works on the frame buffer image data directly.
+
+For the future it is planned that frame buffer drivers for graphics cards and
+the like can be implemented as kernel modules that are loaded at runtime. Such
+a driver just has to call register_framebuffer() and supply some functions.
+Writing and distributing such drivers independently from the kernel will save
+much trouble...
+
+
+<sect>Frame Buffer Resolution Maintenance
+<p>
+Frame buffer resolutions are maintained using the utility <em/fbset/. It can
+change the video mode properties of a frame buffer device. Its main usage is
+to change the current video mode, e.g. during boot up in one of your
+<tt>/etc/rc.*</tt> or <tt>/etc/init.d/*</tt> files.
+
+Fbset uses a video mode database stored in a configuration file, so you can
+easily add your own modes and refer to them with a simple identifier.
+
+
+<sect>The X Server
+<p>
+The X server (XF68_FBDev) is the most notable application program for the frame
+buffer device. Starting with XFree86 release 3.2, the X server is part of
+XFree86 and has 2 modes:
+
+ <itemize>
+ <item>If the <tt/Display/ subsection for the <tt/fbdev/ driver in the
+ <tt>/etc/XF86Config</tt> file contains a
+
+ <tscreen><verb>
+ Modes "default"
+ </verb></tscreen>
+
+ line, the X server will use the scheme discussed above, i.e. it will start
+ up in the resolution determined by <tt>/dev/fb0</tt> (or
+ <tt>&dollar;FRAMEBUFFER</tt>, if set). You still have to specify the color
+ depth (using the <tt>Depth</tt> keyword) and virtual resolution (using the
+ <tt>Virtual</tt> keyword) though. This is the default for the configuration
+ file supplied with XFree86. It's the most simple configuration, but it has
+ some limitations.
+
+ <item>Therefore it's also possible to specify resolutions in the
+ <tt>/etc/XF86Config</tt> file. This allows for on-the-fly resolution
+ switching while retaining the same virtual desktop size. The frame buffer
+ device that's used is still <tt>/dev/fb0</tt> (or
+ <tt>&dollar;FRAMEBUFFER</tt>), but the available resolutions are defined by
+ <tt>/etc/XF86Config</tt> now. The disadvantage is that you have to specify
+ the timings in a different format (but <tt>fbset -x</tt> may help).
+ </itemize>
+
+To tune a video mode, you can use fbset or xvidtune. Note that xvidtune doesn't
+work 100% with XF68_FBDev: the reported clock values are always incorrect.
+
+
+<sect>Video Mode Timings
+<p>
+A monitor draws an image on the screen by using an electron beam (3 electron
+beams for color models, 1 electron beam for monochrome monitors). The front of
+the screen is covered by a pattern of colored phosphors (pixels). If a phosphor
+is hit by an electron, it emits a photon and thus becomes visible.
+
+The electron beam draws horizontal lines (scanlines) from left to right, and
+from the top to the bottom of the screen. By modifying the intensity of the
+electron beam, pixels with various colors and intensities can be shown.
+
+After each scanline the electron beam has to move back to the left side of the
+screen and to the next line: this is called the horizontal retrace. After the
+whole screen (frame) was painted, the beam moves back to the upper left corner:
+this is called the vertical retrace. During both the horizontal and vertical
+retrace, the electron beam is turned off (blanked).
+
+The speed at which the electron beam paints the pixels is determined by the
+dotclock in the graphics board. For a dotclock of e.g. 28.37516 MHz (millions
+of cycles per second), each pixel is 35242 ps (picoseconds) long:
+
+ <tscreen><verb>
+ </verb></tscreen>
+ 1/(28.37516E6 Hz) = 35.242E-9 s
+
+If the screen resolution is 640x480, it will take
+
+ <tscreen><verb>
+ 640*35.242E-9 s = 22.555E-6 s
+ </verb></tscreen>
+
+to paint the 640 (xres) pixels on one scanline. But the horizontal retrace
+also takes time (e.g. 272 `pixels'), so a full scanline takes
+
+ <tscreen><verb>
+ (640+272)*35.242E-9 s = 32.141E-6 s
+ </verb></tscreen>
+
+We'll say that the horizontal scanrate is about 31 kHz:
+
+ <tscreen><verb>
+ 1/(32.141E-6 s) = 31.113E3 Hz
+ </verb></tscreen>
+
+A full screen counts 480 (yres) lines, but we have to consider the vertical
+retrace too (e.g. 49 `pixels'). So a full screen will take
+
+ <tscreen><verb>
+ (480+49)*32.141E-6 s = 17.002E-3 s
+ </verb></tscreen>
+
+The vertical scanrate is about 59 Hz:
+
+ <tscreen><verb>
+ 1/(17.002E-3 s) = 58.815 Hz
+ </verb></tscreen>
+
+This means the screen data is refreshed about 59 times per second. To have a
+stable picture without visible flicker, VESA recommends a vertical scanrate of
+at least 72 Hz. But the perceived flicker is very human dependent: some people
+can use 50 Hz without any trouble, while I'll notice if it's less than 80 Hz.
+
+Since the monitor doesn't know when a new scanline starts, the graphics board
+will supply a synchronization pulse (horizontal sync or hsync) for each
+scanline. Similarly it supplies a synchronization pulse (vertical sync or
+vsync) for each new frame. The position of the image on the screen is
+influenced by the moments at which the synchronization pulses occur.
+
+The following picture summarizes all timings. The horizontal retrace time is
+the sum of the left margin, the right margin and the hsync length, while the
+vertical retrace time is the sum of the upper margin, the lower margin and the
+vsync length.
+
+<tscreen><verb>
+ +----------+---------------------------------------------+----------+-------+
+ | | x | | |
+ | | |upper_margin | | |
+ | | x | | |
+ +----------###############################################----------+-------+
+ | # x # | |
+ | # | # | |
+ | # | # | |
+ | # | # | |
+ | left # | # right | hsync |
+ | margin # | xres # margin | len |
+ |<-------->#<---------------+--------------------------->#<-------->|<----->|
+ | # | # | |
+ | # | # | |
+ | # | # | |
+ | # |yres # | |
+ | # | # | |
+ | # | # | |
+ | # | # | |
+ | # | # | |
+ | # | # | |
+ | # | # | |
+ | # | # | |
+ | # | # | |
+ | # x # | |
+ +----------###############################################----------+-------+
+ | | x | | |
+ | | |lower_margin | | |
+ | | x | | |
+ +----------+---------------------------------------------+----------+-------+
+ | | x | | |
+ | | |vsync_len | | |
+ | | x | | |
+ +----------+---------------------------------------------+----------+-------+
+</verb></tscreen>
+
+The frame buffer device expects all horizontal timings in number of dotclocks
+(in picoseconds, 1E-12 s), and vertical timings in number of scanlines.
+
+
+<sect>Converting XFree86 timing values into frame buffer device timings
+<p>
+An XFree86 mode line consists of the following fields:
+
+ <tscreen><verb>
+ "800x600" 50 800 856 976 1040 600 637 643 666
+ < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL
+ </verb></tscreen>
+
+The frame buffer device uses the following fields:
+
+ <descrip>
+ <tag>pixclock</tag> pixel clock in ps (pico seconds)
+ <tag>left_margin</tag> time from sync to picture
+ <tag>right_margin</tag> time from picture to sync
+ <tag>upper_margin</tag> time from sync to picture
+ <tag>lower_margin</tag> time from picture to sync
+ <tag>hsync_len</tag> length of horizontal sync
+ <tag>vsync_len</tag> length of vertical sync
+ </descrip>
+
+ <descrip>
+ <tag>Pixelclock</tag>
+ <itemize>
+ <item>xfree: in MHz
+ <item>fb: In Picoseconds (ps)
+ <item>pixclock = 1000000 / DCF
+ </itemize>
+
+ <tag>Horizontal timings</tag>
+ <itemize>
+ <item>left_margin = HFL - SH2
+ <item>right_margin = SH1 - HR
+ <item>hsync_len = SH2 - SH1
+ </itemize>
+
+ <tag>Vertical timings</tag>
+ <itemize>
+ <item>upper_margin = VFL - SV2
+ <item>lower_margin = SV1 - VR
+ <item>vsync_len = SV2 - SV1
+ </itemize>
+ </descrip>
+
+Good examples for VESA timings can be found in the XFree86 source tree,
+under <tt>xc/programs/Xserver/hw/xfree86/doc/modeDB.txt</tt>.
+
+
+<sect>References
+<p>
+For more specific information about the frame buffer device and its
+applications, please refer to the following documentation:
+
+ <itemize>
+ <item>The manual pages for fbset: fbset(8), fb.modes(5)
+ <item>The manual pages for XFree86: XF68_FBDev(1), XF86Config(4/5)
+ <item>The mighty kernel sources:
+ <itemize>
+ <item>linux/drivers/video/
+ <item>linux/include/linux/fb.h
+ <item>linux/include/video/
+ </itemize>
+ </itemize>
+
+
+<sect>Downloading
+<p>
+All necessary files can be found at
+
+ <tscreen><verb>
+ ftp://ftp.uni-erlangen.de/pub/Linux/LOCAL/680x0/
+ </verb></tscreen>
+
+and on its mirrors.
+
+
+<sect>Credits
+<p>
+This readme was written by Geert Uytterhoeven, partly based on the original
+<tt>X-framebuffer.README</tt> by Roman Hodek and Martin Schaller. Section
+`Converting XFree86 timing values into frame buffer device timings' was
+provided by Frank Neumann.
+
+The frame buffer device abstraction was designed by Martin Schaller.
+
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/fbdev.sgml,v 1.2 1999/08/23 06:38:53 dawes Exp $
+
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/fonts.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/fonts.sgml
new file mode 100644
index 000000000..2566f45a7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/fonts.sgml
@@ -0,0 +1,749 @@
+<!doctype LINUXDOC PUBLIC "-//XFree86//DTD linuxdoc//EN"[
+<!ENTITY % defs SYSTEM "defs.ent"> %defs;
+]>
+
+<!--
+Time-stamp: <99/05/26 23:10:24 jec>
+-->
+<article>
+
+<title>Fonts in XFree86
+<author>Juliusz Chroboczek, <tt/jec@dcs.ed.ac.uk/
+<date>26 May 1999</date>
+
+<ident>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/fonts.sgml,v 1.4 1999/08/28 10:43:33 dawes Exp $
+</ident>
+
+<toc>
+
+<p>This version of XFree86 includes a number of improvements to the
+handling of fonts, including
+<itemize>
+<item> new Unicode-encoded bitmap fonts;
+<item> internationalisation of the scalable font backends (Type 1, Speedo,
+ and TrueType);
+<item> support for TrueType fonts;
+<item> support for CID-keyed fonts.
+</itemize>
+This document describes these improvements. It does not attempt to
+describe the standard support for fonts in X11; the reader is referred
+to the <tt/X/(1), <tt/Xserver/(1), and <tt/mkfontdir/(1) manpages.
+
+<sect>Background and terminology
+
+<sect1>Characters and glyphs
+
+<p>A <it/character/ is an abstract unit of a writing system. Examples
+of characters include the Latin capital letter <it/A/, the Arabic
+letter <it/jim/, and the <it/dingbat black scissors/.
+
+A <it/glyph/ is a shape that may represent one or many characters when
+displayed by a window system or printed by a printer.
+
+While glyphs roughly correspond to characters in most cases, this
+correspondence is not, in general, one to one. For example, a font may
+have many variant forms of the capital letter <it/A/; a single <it/fi/
+ligature may correspond to the letters <it/f/ and <it/i/.
+
+A <it/coded character set/ is a set of characters together with a
+mapping from integer codes -- known as <it/codepoints/ -- to
+characters. Examples of coded character sets include US-ASCII,
+ISO&nbsp;8859-1, KOI8-R, and JIS&nbsp;X&nbsp;0208(1990).
+
+A coded character set need not use 8-bit integers to index
+characters. Many early mainframes used 6-bit character sets, while
+16-bit (or more) character sets are necessary for ideographic writing
+systems.
+
+<sect1>Font files, fonts, and XLFD
+
+<p>Traditionally, typographers speak about <it/typefaces/ and
+<it/founts/ (we use the traditional British spelling to distinguish
+founts from digital fonts). A typeface is a particular style or
+design, such as Times Italic, while a fount is a molten-lead
+incarnation of a given typeface at a given size.
+
+Digital fonts come in <it/font files/. A font file contains all the
+information necessary for generating glyphs of a given typeface, and
+applications using font files may access glyph information in
+arbitrary order.
+
+Digital fonts may consist of bitmap data, in which case they are said
+to be <it/bitmap fonts/. They may also consist of a mathematical
+description of glyph shapes, in which case they are said to be
+<it/scalable fonts/. Common formats for scalable font files are
+<it/Type&nbsp;1/ (sometimes incorrectly called <it/ATM fonts/ or
+<it/PostScript fonts/), and <it/TrueType/.
+
+The glyph data in a digital font needs to be indexed somehow. How
+this is done depends on the font file format. In the case of
+Type&nbsp;1 fonts, glyphs are identified by <it/glyph names/. In the
+case of TrueType fonts, glyphs are indexed by integers corresponding
+to one of a number of indexing schemes (usually Unicode --- see below).
+
+The X11 system uses the data in font file to generate <it/font
+instances/, which are collections of glyphs at a given size indexed
+according to a given encoding. X11 font instances are specified using
+a notation known as the <it/X Logical Font Description/ (XLFD). An
+XLFD starts with a dash `<tt/-/', and consists of fourteen fields
+separated by dashes, for example
+<tscreen>
+-adobe-courier-medium-r-normal--0-0-0-0-m-0-iso8859-1
+</tscreen>
+Or particular interest are the last two fields `<tt/iso8859-1/', which
+specify the font instance's encoding.
+
+<sect1>Unicode
+
+<p>Unicode (<url url="http://www.unicode.org">) is a coded character
+set with the goal of uniquely identifying all characters for all
+scripts, current and historical. While Unicode was explicitly not
+designed as a glyph encoding scheme, it can often be used as such for
+a large number of scripts.
+
+Unicode is an <it/open/ character set, in that codepoint assignments
+may be added to Unicode at any time (once specified, though, an
+assignment can never be changed). For this reason, a Unicode font
+will be <it/sparse/, and only define glyphs for a subset of the
+character registry of Unicode.
+
+The Unicode standard is defined in parallel with ISO&nbsp;10646.
+Assignments in the two standards are always equivalent, and this
+document uses the terms ``Unicode'' and ``ISO 10646'' interchangeably.
+
+When used in X11, Unicode-encoded fonts should have the last two
+fields of their XLFD set to `<tt/iso10646-1/'.
+
+
+<sect>Unicode-encoded bitmap fonts
+
+<p>XFree86 includes two new Unicode-encoded fonts with a large
+collection of non-ideographic glyphs. While it is possible to use
+these fonts as main fonts, applications are expected to use them as
+fallbacks when a given glyph is not available in the current font.
+
+
+<sect1>The Unicode `fixed' font
+
+<p>The font file
+<tscreen>
+/usr/X11/lib/X11/fonts/misc/6x13.pcf.gz
+</tscreen>
+with XLFD
+<tscreen>
+-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1
+</tscreen>
+is a Unicode-encoded version of the standard `<tt/fixed/' font with
+added support for the Latin, Greek, Cyrillic, Georgian, Armenian, IPA
+and other scripts plus numerous technical symbols. It contains over
+2800 characters, covering all characters of ISO&nbsp;8859 parts 1-5,
+7-10, 13-15, as well as all European IBM and Microsoft code pages,
+KOI8, WGL4, and the repertoires of many other character sets. This
+font is compatible with the standard 8-bit <tt/fixed/ font and
+therefore also includes the DEC line-drawing glyphs in the range 0x00
+to 0x1F, which are not part of Unicode or ISO&nbsp;10646-1.
+
+XFree86 changes the standard aliases `<tt/fixed/' and `<tt/6x13/' to
+stand for this new Unicode-encoded font. The old ISO&nbsp;8859-1
+encoded `<tt/fixed/' font is still available under its full XLFD name
+<tscreen>
+-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1
+</tscreen>
+in the file
+<tscreen>
+/usr/X11/lib/X11/fonts/misc/6x13-L1.pcf.gz
+</tscreen>
+
+<sect1>The ClearlyU Unicode font
+
+<p>The ClearlyU font set of fonts provides a set of 12pt, 100dpi
+proportional fonts with many of the glyphs needed for Unicode text.
+Together, the fonts contain over 4000 glyphs.
+
+The main ClearlyU font has XLFD name
+<tscreen>
+-mutt-ClearlyU-medium-r-normal--17-120-100-100-p-101-iso10646-1
+</tscreen>
+and resides in the font file
+<tscreen>
+/usr/X11/lib/X11/fonts/misc/cu12.pcf.gz
+</tscreen>
+Additional ClearlyU fonts include
+<tscreen>
+-mutt-ClearlyU&nbsp;Alternate&nbsp;Glyphs-medium-r-normal--17-120-100-100-p-91-iso10646-1
+-mutt-ClearlyU&nbsp;Arabic&nbsp;Extra-medium-r-normal--17-120-100-100-p-103-fontspecific-0
+-mutt-ClearlyU&nbsp;Ligature-medium-r-normal--17-120-100-100-p-141-fontspecific-0
+-mutt-ClearlyU&nbsp;PUA-medium-r-normal--17-120-100-100-p-111-iso10646-1
+</tscreen>
+
+
+<sect>Internationalisation of scalable font backends.
+
+<p>The scalable font backends (Type&nbsp;1, Speedo, TrueType) can now
+automatically re-encode fonts to the encoding specified in the XLFD in
+`<tt/fonts.dir/'. For example, a `<tt/fonts.dir/' file can now
+contain entries for the Type&nbsp;1 Courier font such as
+<tscreen>
+cour.pfa -adobe-courier-medium-r-normal--0-0-0-0-m-0-iso8859-1
+cour.pfa -adobe-courier-medium-r-normal--0-0-0-0-m-0-iso8859-2
+</tscreen>
+which will lead to the font being recoded to ISO&nbsp;8859-1 and
+ISO&nbsp;8859-2 respectively.
+
+<sect1>The `fontenc' layer<label id="sec-fontenc">
+
+<p>Three of the scalable backends (Type&nbsp;1, Speedo, and the
+`xfsft' TrueType backend) use a common `fontenc' layer for font
+re-encoding. This allows those backends to share their encoding data,
+and allows simple configuration of new locales independently of font
+type.
+
+<it/Please note:/ the X-TrueType (X-TT) backend does not use the
+`fontenc' layer, but instead uses its own method for font reencoding.
+Readers only interested in X-TT may want to skip to <ref
+id="sec-symbol-fonts" name="Using Symbol Fonts">, as the intervening
+information does not apply to X-TT. X-TT itself is described in more
+detail in <ref id="sec-X-TT" name="X-TrueType">.
+
+In the `fontenc' layer, an encoding is defined by a name (such as
+`<tt/iso8859-1/'), eventually a number of aliases (alternate names),
+and an ordered collection of mappings. A mapping defines the way the
+encoding can be mapped into one of the ``target'' encodings known to
+the `fontenc' layer; currently, those consist of Unicode, Adobe glyph
+names, and arbitrary TrueType `cmap's.
+
+A number of encodings are hardwired into `fontenc', and are therefore
+always available; the hardcoded encodings cannot easily be redefined.
+These include:
+<itemize>
+<item> `<tt/iso10646-1/': Unicode;
+<item> `<tt/iso8859-1/': ISO&nbsp;Latin-1 (Western Europe);
+<item> `<tt/iso8859-2/': ISO&nbsp;Latin-2 (Eastern Europe);
+<item> `<tt/iso8859-3/': ISO&nbsp;Latin-3 (Southern Europe);
+<item> `<tt/iso8859-4/': ISO&nbsp;Latin-4 (Northern Europe);
+<item> `<tt/iso8859-5/': ISO&nbsp;Cyrillic;
+<item> `<tt/iso8859-6/': ISO&nbsp;Arabic;
+<item> `<tt/iso8859-7/': ISO&nbsp;Greek;
+<item> `<tt/iso8859-8/': ISO&nbsp;Hebrew;
+<item> `<tt/iso8859-9/': ISO&nbsp;Latin-5 (Turkish);
+<item> `<tt/iso8859-10/': ISO&nbsp;Latin-6 (Nordic);
+<item> `<tt/iso8859-15/': ISO&nbsp;Latin-9, or Latin-0 (Revised
+ Western-European);
+<item> `<tt/koi8-r/': KOI8 Russian;
+<item> `<tt/koi8-u/': KOI8 Ukrainian (see RFC 2319);
+<item> `<tt/koi8-ru/': KOI8 Russian/Ukrainian
+<item> `<tt/koi8-uni/': KOI8 ``Unified'' (Russian, Ukrainian, and
+ Byelorussian);
+<item> `<tt/koi8-e/': KOI8 `European', ISO-IR-111, or ECMA-Cyrillic;
+<item> `<tt/microsoft-symbol/' and `<tt/apple-roman/': these are only
+ likely to be useful with TrueType symbol fonts.
+</itemize>
+
+New encodings can be added by defining <it/encoding files/. When a
+font encoding is requested that the `fontenc' layer doesn't know
+about, the backend checks the directory in which the font file resides
+(not the directory with `<tt/fonts.dir/'!) for a file named
+`<tt/encodings.dir/'. If found, this file is scanned for the unknown
+encoding, and the requested encoding definition file is read in. The
+mkfontdir(1) utility, when invoked with the `<tt/-e/' option followed
+by the name of a directory containing encoding files, can be used to
+automatically build `<tt/encodings.dir/' files. See the <tt/mkfontdir/(1)
+manpage for more details.
+
+A number of predefined encoding files have been included with the
+distribution. Information on writing new encoding files can be found
+in <ref id="sec-format-encoding-directory-files" name="Format of
+encodings directory files"> and <ref id="sec-format-encoding-files"
+name="Format of encodings files">.
+
+<sect1>Backend-specific notes about fontenc
+
+<sect2>Type&nbsp;1
+
+<p>The Type&nbsp;1 backend first searches for a mapping with a target
+of PostScript. If one is found, it is used. If none is found, the
+backend searches for a mapping with target Unicode, which is then
+composed with a built-in table mapping codes to glyph names. Note
+that this table only covers part of the Unicode code points that have
+been assigned names by Adobe.
+
+If neither a PostScript or Unicode mapping is found, the backend
+defaults to ISO&nbsp;8859-1.
+
+Specifying an encoding value of `<tt/adobe-fontspecific/' disables
+the encoding mechanism. This is useful with symbol and wrongly
+encoded fonts (see below).
+
+The Type&nbsp;1 backend currently limits all encodings to 8-bit codes.
+
+<sect2>Speedo
+
+<p>The Speedo backend searches for a mapping with a target of Unicode,
+and uses it if found. If none is found, the backend defaults to
+ISO&nbsp;8859-1.
+
+The Speedo backend limits all encodings to 8-bit codes.
+
+<sect2>The `xfsft' TrueType backend
+
+<p>The TrueType backend scans the mappings in order. Mappings with
+a target of PostScript are ignored; mappings with a TrueType or
+Unicode target are checked against all the cmaps in the file. The
+first applicable mapping is used.
+
+Authors of encoding files to be used with the TrueType backend should
+ensure that mappings are mentioned in decreasing order of preference.
+
+
+<sect1>Format of encodings directory files<label
+ id="sec-format-encoding-directory-files">
+
+<p>In order to use a font in an encoding that the font backend does
+not know about, you need to have a `<tt/encodings.dir/' file in the
+same directory as the font file used. `<tt/encodings.dir/' has the
+same format as `<tt/fonts.dir/'. Its first line specifies the number
+of encodings, while every successive line has two columns, the name of
+the encoding, and the name of the encoding file; this can be relative
+to the current directory, or absolute. Every encoding name should
+agree with the encoding name defined in the encoding file. For
+example,
+
+<tscreen>
+3
+mulearabic-0 encodings/mulearabic-0.enc
+mulearabic-1 encodings/mulearabic-1.enc
+mulearabic-2 encodings/mulearabic-2.enc
+</tscreen>
+
+Note that the name of an encoding must be specified in the encoding
+file's STARTENCODING or ALIAS line. It is not enough to create an
+`<tt/encodings.dir/' entry.
+
+If your platform supports it (it probably does), encoding files may be
+compressed or gzipped.
+
+`<tt/encoding.dir/' files are best maintained by the <tt/mkfontdir/(1)
+utility. Please see the <tt/mkfontdir/(1) manpage for more
+information.
+
+
+<sect1>Format of encoding files<label id="sec-format-encoding-files">
+
+<p>The encoding files are ``free form,'' <it/i.e./ any string of
+whitespace is equivalent to a single space. Keywords are parsed in a
+non-case-sensitive manner, meaning that `<tt/size/', `<tt/SIZE/', and
+`<tt/SiZE/' all parse as the same keyword; on the other hand, case is
+significant in glyph names.
+
+Numbers can be written in decimal, as in `<tt/256/', in hexadecimal,
+as in `<tt/0x100/', or in octal, as in `<tt/0400/'.
+
+Comments are introduced by a hash sign `<tt/#/'. A `<tt/#/' may
+appear at any point in a line, and all characters following the
+`<tt/#/' are ignored, up to the end of the line.
+
+The encoding file starts with the definition of the name of the
+encoding, and eventually its alternate names (aliases):
+<tscreen>
+STARTENCODING mulearabic-0
+ALIAS arabic-0
+ALIAS something-else
+</tscreen>
+The names of the encoding should be suitable for use in an XLFD font
+name, and therefore contain exactly one dash `<tt/-/'.
+
+The encoding file may then optionally declare the size of the
+encoding. For a linear encoding (such as Mule Arabic, or
+ISO&nbsp;8859-1), the SIZE line specifies the maximum code plus one:
+<tscreen>
+SIZE 0x2B
+</tscreen>
+For a matrix encoding, it should specify two numbers. The first is
+the number of the last row plus one, the other, the highest column
+number plus one. For example, in the case of `<tt/jisx0208.1990-0/'
+(JIS&nbsp;X&nbsp;0208(1990), double-byte encoding, high bit clear), it
+should be
+<tscreen>
+SIZE 0x75 0x80
+</tscreen>
+Codes outside the region defined by the size line are supposed to be
+undefined. Encodings default to linear encoding with a size of 256
+(0x100). This means that you must declare the size of all 16 bit
+encodings.
+
+What follows is one or more mapping sections. A mapping section
+starts with a `<tt/STARTMAPPING/' line stating the target of the mapping.
+The target may be one of:
+<itemize>
+<item>Unicode (ISO&nbsp;10646):
+<tscreen>
+STARTMAPPING unicode
+</tscreen>
+<item>a given TrueType `<tt/cmap/':
+<tscreen>
+STARTMAPPING cmap 3 1
+</tscreen>
+<item>PostScript glyph names
+<tscreen>
+STARTMAPPING postscript
+</tscreen>
+</itemize>
+Every line in a mapping section maps one from the encoding being
+defined to the target of the mapping. In mappings with a Unicode or
+TrueType mapping, codes are mapped to codes:
+<tscreen>
+0x21 0x0660
+0x22 0x0661
+...
+</tscreen>
+As an abbreviation, it is possible to map a contiguous range of codes
+in a single line. A line consisting of three integers
+<tscreen>
+<it/start/ <it/end/ <it/target/
+</tscreen>
+is an abbreviation for the range of lines
+<tscreen>
+<it/start/ <it/target/
+<it/start/+1 <it/target/+1
+...
+<it/end/ <it/target/+<it/end/-<it/start/
+</tscreen>
+For example, the line
+<tscreen>
+0x2121 0x215F 0x8140
+</tscreen>
+is an abbreviation for
+<tscreen>
+0x2121 0x8140
+0x2122 0x8141
+...
+0x215F 0x817E
+</tscreen>
+Codes not listed are assumed to map through the identity (<it/i.e./ to
+the same numerical value). In order to override this default mapping,
+you may specify a range of codes to be undefined by using an
+`<tt/UNDEFINE/' line:
+<tscreen>
+UNDEFINE 0x00 0x2A
+</tscreen>
+or, for a single code
+<tscreen>
+UNDEFINE 0x1234
+</tscreen>
+This works because later values override earlier one.
+
+PostScript mappings are different. Every line in a PostScript mapping
+maps a code to a glyph name
+<tscreen>
+0x41 A
+0x42 B
+...
+</tscreen>
+and codes not explicitly listed are undefined.
+
+A mapping section ends with an <tt/ENDMAPPING/ line
+<tscreen>
+ENDMAPPING
+</tscreen>
+After all the mappings have been defined, the file ends with an
+<tt/ENDENCODING/ line
+<tscreen>
+ENDENCODING
+</tscreen>
+Lines of the form
+<tscreen>
+UNASSIGNED 0x00 0x1F
+</tscreen>
+or
+<tscreen>
+UNASSIGNED 0x1234
+</tscreen>
+are ignored by the server, but may be used by supporting utilities.
+
+In order to make future extensions to the format possible, lines
+starting with an unknown keyword are ignored, as are mapping sections
+with an unknown target.
+
+
+<sect1>Using symbol fonts<label id="sec-symbol-fonts">
+
+<p>Type&nbsp;1 symbol fonts should be installed using the
+`<tt/adobe-fontspecific/' encoding.
+
+In an ideal world, all TrueType symbol fonts would be installed using
+one of the `<tt/microsoft-symbol/' and `<tt/apple-roman/' encodings. A
+number of symbol fonts, however, are not marked as such; such fonts
+should be installed using `<tt/microsoft-cp1252/', or, for older
+fonts, `<tt/microsoft-win3.1/'.
+
+In order to guarantee consistent results (especially between
+Type&nbsp;1 and TrueType versions of the same font), it is possible to
+define a special encoding for a given font. This has already been done
+for the `<tt/ZapfDingbats/' font; see the file
+`<tt>encodings/adobe-dingbats.enc</tt>'.
+
+
+<sect1>Using badly encoded font files<label id="sec-badly-encoded">
+
+<p>A number of text fonts are incorrectly encoded. Incorrect encoding is
+sometimes done by design, in order to make a font for an exotic script
+appear like an ordinary Western text font. It is often due to the font
+designer's laziness or incompetence; in particular, most people seem
+to find it easier to invent idiosyncratic glyph names rather than
+follow the Adobe glyph list.
+
+There are two ways of dealing with such fonts: using them with the
+encoding they were designed for, and creating an <it/ad hoc/ encoding
+file.
+
+Of course, most of the time the proper fix would be to hit the font
+designer very hard on the head with the PLRM (preferably the first
+edition, as it was published in hardcover).
+
+<sect2>Using fonts with the designer's encoding
+
+<p>In the case of Type&nbsp;1 fonts, the font designer can specify a
+default encoding; this encoding is requested by using the
+`<tt/adobe-fontspecific/' encoding in the XLFD name. Sometimes, the
+font designer omitted to specify a reasonable default encoding; in
+this case, you should experiment with `<tt/adobe-standard/',
+`<tt/iso8859-1/', `<tt/microsoft-cp1252/', and
+`<tt/microsoft-win3.1/', (`<tt/microsoft-symbol/' doesn't make sense
+for Type&nbsp;1 fonts).
+
+TrueType fonts do not have a default encoding, and use of the
+Microsoft Symbol encoding yields strange results with text fonts on
+some (non-X11) platforms. However, most TrueType fonts are designed
+with either Microsoft or Apple platforms in mind, so one of
+`<tt/microsoft-cp1252/', `<tt/microsoft-win3.1/', or
+`<tt/apple-roman/' should yield reasonable results.
+
+<sect2>Specifying an ad hoc encoding file
+
+<p>It is always possible to define an encoding file to put the glyphs
+in a font in any desired order. Again, see the
+`<tt/encodings/adobe-dingbats.enc/' file to see how this is done.
+
+
+<sect2>Specifying font aliases
+
+<p>By following the directions above, you will find yourself with a
+number of fonts with unusual names -- specifying encodings such as
+`<tt/adobe-fontspecific/', `<tt/microsoft-win3.1/' <it/etc/. In order
+to use these fonts with standard applications, it may be useful to
+remap them to their proper names.
+
+This is done by writing a `<tt/fonts.alias/' file. The format of this file
+is similar to the format of the `<tt/fonts.dir/' file, except that it maps
+XLFD names to XLFD names. A `<tt/fonts.alias/' file might look as follows:
+<tscreen>
+1
+"-ogonki-alamakota-medium-r-normal--0-0-0-0-p-0-iso8859-2" \
+ "-ogonki-alamakota-medium-r-normal--0-0-0-0-p-0-adobe-fontspecific"
+</tscreen>
+(both XLFD names on a single line). The syntax of the
+`<tt/fonts.alias/' file is described in the mkfontdir(1) manual page.
+
+
+<sect>New font backends
+
+<sect1>New TrueType backends
+
+<p>This version of XFree86 comes with two TrueType backends, known
+as `xfsft' and `X-TrueType' (`X-TT' for short). Those two backends
+are incompatible, in that only one can be used at any one time. Users
+are invited to chose whichever backend they find more useful and stick
+to it.
+
+Both TrueType backends delay glyph rasterisation to the time at which
+a glyph is first used. For this reason, they only provide an
+approximate value for the `average width' font property. Users are
+warned not to rely on the average width of a font having an accurate
+value.
+
+Both backends also support an optimisation for character-cell fonts
+(fonts with all glyph metrics equal, or terminal fonts). A font with
+an XLFD specifying a character-cell spacing `<tt/c/', as in
+<tscreen>
+-misc-mincho-medium-r-normal--0-0-0-0-c-0-jisx0208.1990-0
+</tscreen>
+will not rasterise glyphs at metrics computation time, but instead
+trust the font really to be a character-cell font. Users are
+encouraged to make use of this optimisation when useful, but be warned
+that not all monospaced fonts are character-cell fonts.
+
+
+<sect2>The `xfsft' TrueType backend
+
+<p>The `xfsft' backend is a backend based on the FreeType library (see
+www.freetype.org) with support for the `fontenc' style of
+internationalisation (see <ref id="sec-fontenc" name="The fontenc
+layer">). This backend supports TrueType Font files (<tt/*.ttf/) and
+TrueType Collections (<tt/*.ttc/).
+
+In order to access the faces in a TrueType Collection file, the face
+number must be specified in the fonts.dir file before the filename
+within colons. For example,
+<tscreen>
+:2:mincho.ttc -misc-mincho-medium-r-normal--0-0-0-0-c-0-jisx0208.1990-0
+</tscreen>
+refers to face 2 in the `<tt/mincho.ttc/' TrueType Collection file.
+
+<sect2>The `X-TrueType' TrueType backend<label id="sec-X-TT">
+
+<p>The `X-TrueType' backend is another backend based on the FreeType
+library. X-TrueType doesn't use the `fontenc' layer for managing font
+encodings, but instead uses its own database of encodings. However,
+X-TrueType includes a large number of encodings, and any encoding you
+need is likely to be present in X-TrueType.
+
+X-TrueType extends the `<tt/fonts.dir/' syntax with a number of options,
+known as `TTCap'. A `TTCap' entry follows the general syntax
+<tscreen>
+:option=value:
+</tscreen>
+and should be specified before the filename.
+
+The most useful TTCap option is used to specify the face number to use
+with TTCs; it carries the name `<tt/fn/'. This means that face 2 of font
+file `<tt/mincho.ttc/' is specified using:
+<tscreen>
+:fn=2:mincho.ttc -misc-mincho-medium-r-normal--0-0-0-0-c-0-jisx0208.1990-0
+</tscreen>
+More information on the TTCap syntax, and on X-TrueType in general,
+may be found on
+<tscreen>
+<url url="http://hawk.ise.chuo-u.ac.jp/student/person/tshiozak/x-tt/index-eng.html">
+</tscreen>
+
+<sect1>Support for CID-keyed fonts
+
+<p>The CID-keyed font format was designed by Adobe Systems for fonts with
+large character sets. It is described in the Adobe Technical Notes
+nr.&nbsp;5092, "Overview of the CID-Keyed Font Technology,"
+nr.&nbsp;5014, "CMap and CIDFont File Format Specification," and
+others, available from
+<tscreen>
+<url url="http://partners.adobe.com/supportservice/devrelations/typeforum/cidfonts.html">
+</tscreen>
+
+Sample CID-keyed fonts can be found at:
+<tscreen>
+<url url="ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/adobe/">
+</tscreen>
+Support for CID-keyed fonts in XFree86 is controlled by the two
+switches `<tt/BuildCID/' and <tt/BuildCIDFonts/. Make sure that those
+switches are turned on (in the directory <tt>xc/config/cf</tt>) when
+XFree86 is built. By default, they should be set to <tt/YES/, unless
+you are building XFree86 for a small memory footprint, in which case
+they should be set to <tt/NO/.
+
+The CID-keyed font backend does not use the `fontenc' layer, but
+instead uses the standard `CMap' method of recoding CID-keyed fonts.
+
+<sect2>Using CID-keyed fonts
+
+<p>As shown in the sample install file
+<tt>/usr/X11R6/lib/X11/XF86Config.eg</tt>, the font directory CID
+should be specified as part of the XFree86 font path:
+<tscreen>
+FontPath "/usr/X11R6/lib/X11/fonts/CID/"
+</tscreen>
+in the `<tt/XF86Config/' file. When the CID font directory is on the
+font path it must contain at least the empty files fonts.dir and
+fonts.scale. Sample `<tt/fonts.dir/' and `<tt/fonts.scale/' files,
+with 0 entries, are installed by default.
+
+A sample CID-keyed font is provided in the file:
+<tscreen>
+test/xsuite/xtest/CID
+</tscreen>
+The test directory was given the same name as the CID font directory,
+because it shows how a CID-keyed font should be installed. It
+contains a number of subdirectories, and any CID font directory should
+have the same directory structure.
+
+When installing CID-keyed fonts, the empty fonts.scale and fonts.dir
+files in the directory:
+<tscreen>
+xc/fonts/scaled/CID
+</tscreen>
+should be replaced by <tt/fonts.scale/ and <tt/fonts.dir/ files with a
+number of entries of the form:
+<tscreen>
+1
+Adobe-Korea1/Munhwa-Regular--Adobe-Korea1-0.cid \
+ -adobe-munhwa-medium-r-normal--0-0-0-0-p-0-adobe.korea1-0
+</tscreen>
+(the font file name and the XLFD name should be on the same line).
+Note that the first column does not specify an actual filename;
+instead, it specifies the PostScript name of the CID-keyed font,
+followed by the extension `<tt/.cid/'. The actual names of the files
+used will be derived from this PostScript name.
+
+CID-keyed fonts are divided in groups by character collection. For
+example, the Korean font:
+<tscreen>
+Munhwa-Regular--Adobe-Korea1-0
+</tscreen>
+is in a subdirectory `<tt/Adobe-Korea1/'.
+
+The PostScript name of a CID-keyed font consists of two parts, the
+<it/CIDFontName/ and the <it/CMapName/, separated by two dashes.
+For instance, in the case of the font name
+<tscreen>
+Munhwa-Regular--Adobe-Korea1-0
+</tscreen>
+the <it/CIDFontName/ is `<tt/Munhwa-Regular/' while the <it/CMapName/
+is `<tt/Adobe-Korea1/'.
+
+Each CID-keyed font consist of a CIDFont file and one or more CMap files.
+The CIDFont file contains the description of each character in a font. It is
+stored in the subdirectory CIDFont of the Adobe-Korea1 directory. The
+directory structure looks as following:
+<tscreen>
+CID/Adobe-Korea1/CIDFont/Munhwa-Regular
+CID/Adobe-Korea1/CMap/Adobe-Korea1-0
+CID/Adobe-Korea1/AFM/Munhwa-Regular.afm
+CID/Adobe-Korea1/CFM
+CID/fonts.dir
+CID/fonts.scale
+</tscreen>
+The file `<tt/Munhwa-Regular.afm/' is an Adobe Font Metric File (AFM).
+The directory `<tt/CFM/' will be used for summaries of that font
+metric file, which will be computed later.
+
+When the CID-keyed files are installed you can run the utility
+<tscreen>
+/usr/X11R6/bin/mkcfm
+</tscreen>
+to create the summaries of font metric file (<tt/*.cfm/), and to put them
+in appropriate subdirectories. By default, the program works on the
+directory:
+<tscreen>
+/usr/X11R6/lib/X11/fonts/CID
+</tscreen>
+A different directory can be specified on the command line of
+`<tt/mkcfm/.'
+
+`<tt/mkcfm/' should be run as root, as it needs to write its output to
+a system directory. If the program determines that it cannot write in
+the designated `<tt/CFM/' subdirectories, it will display a message,
+and switch to current directory.
+
+Unless `<tt/mkcfm/' is run, opening large CID-keyed fonts will take a
+significant amount of time. `<tt/mkcfm/' should be run again whenever a
+change is made to any of the CID-keyed fonts, or when the CID-keyed
+fonts are copied to a machine with a different architecture.
+
+<sect2>Limitations
+
+<p>The current version of the CID-keyed fonts backend only supports
+the CMaps used for horizontal text (<it/e.g./ the CMap
+`<tt/KSC-EUC-H/' will be used, but not `<tt/KSC-EUC-V/'). This
+limitation is due to the fact that the core X11 protocol only provides
+support for horizontal writing.
+
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/i740.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/i740.sgml
new file mode 100644
index 000000000..8bb8fe369
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/i740.sgml
@@ -0,0 +1,147 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+<title>Information for i740 Users
+<author>Precision Insight, Inc.
+<date>18 February 1999
+<toc>
+
+<sect>Supported Hardware
+<p>
+<itemize>
+ <item>Intel 740 based cards
+</itemize>
+
+
+<sect>Features
+<p>
+<itemize>
+ <item>Full support for 8, 15, 16, 24 and 32 bit per pixel depths.
+ <item>Hardware cursor support to reduce sprite flicker.
+ <item>Hardware accelerated 2D drawing engine support for 8, 15, 16 and
+ 24 bit per pixel depths.
+ <item>Support for high resolution video modes up to 1600x1200.
+ <item>Support for doublescan video modes (e.g., 320x200 and 320x240).
+ <item>Support for gamma correction at all pixel depths.
+ <item>Fully programmable clock supported.
+ <item>Robust text mode restore for VT switching.
+</itemize>
+
+
+<sect>Technical Notes
+<p>
+<itemize>
+ <item>Hardware acceleration is not possible in 32 bit per pixel depth.
+ <item>Interlace modes cannot be supported.
+</itemize>
+
+
+<sect>Reported Working Video Cards
+<p>
+<itemize>
+ <item>Real3D Starfighter AGP
+ <item>Real3D Starfighter PCI
+ <item>Diamond Stealth II/G460 AGP
+ <item>3DVision-i740 AGP
+ <item>ABIT G740 8MB SDRAM
+ <item>Acorp AGP i740
+ <item>AGP 2D/3D V. 1N, AGP-740D
+ <item>AOpen AGP 2X 3D Navigator PA740
+ <item>ARISTO i740 AGP (ART-i740-G)
+ <item>ASUS AGP-V2740
+ <item>Atrend (Speedy) 3DIO740 AGP (ATC-2740)
+ <item>Chaintech AGP-740D
+ <item>EliteGroup(ECS) 3DVision-i740 AGP
+ <item>EONtronics Picasso 740
+ <item>EONtronics Van Gogh
+ <item>Everex MVGA i740/AG
+ <item>Flagpoint Shocker i740 8MB
+ <item>Gainward CardExpert 740 8MB
+ <item>Genoa Systems Phantom 740
+ <item>Gigabyte Predator i740 8MB AGP
+ <item>Hercules Terminator 128 2X/i AGP
+ <item>HOT-158 (Shuttle)
+ <item>Intel Express 3D AGP
+ <item>Jaton Video-740 AGP 3D
+ <item>Jetway J-740-3D 8MB AGP, i740 AGP 3D
+ <item>Joymedia Apollo 7400
+ <item>Leadtek Winfast S900
+ <item>Machspeed Raptor i740 AGP 4600
+ <item>Magic-Pro MP-740DVD
+ <item>MAXI Gamer AGP 8 MB
+ <item>Palit Daytona AGP740
+ <item>PowerColor C740 (SG/SD) AGP
+ <item>QDI Amazing I
+ <item>Soyo AGP (SY-740 AGP)
+ <item>Spacewalker Hot-158
+ <item>VideoExcel AGP 740
+ <item>ViewTop ZeusL 8MB
+ <item>Winfast S900 i740 AGP 8MB
+</itemize>
+
+
+<sect>Configuration
+<p>
+The driver auto-detects all device information necessary to
+initialize the card. The only lines you need in the "Device"
+section of your XF86Config file are:
+<verb>
+ Section "Device"
+ Identifier "i740"
+ EndSection
+</verb>
+or let xf86config or XF86Setup do this for you.
+
+However, if you have problems with auto-detection, you can specify:
+<itemize>
+ <item>VideoRam - in kilobytes
+ <item>DacSpeed - in MHz
+ <item>MemBase - physical address of the linear framebuffer
+ <item>IOBase - physical address of the memory mapped IO registers
+</itemize>
+
+
+<sect>Driver Options
+<p>
+<itemize>
+ <item>"hw_cursor" - request hardware cursor (default)
+ <item>"sw_cursor" - software cursor only
+ <item>"no_accel" - software rendering only
+ <item>"sgram" - force the use of SGRAM timing info
+ <item>"sdram" - force the use of SDRAM timing info
+</itemize>
+
+Note: the i740 X server should automatically detect whether your
+card has SGRAM or SDRAM. Use the "sgram" and "sdram" options
+if it is incorrectly detected.
+
+
+<sect>Known Limitations
+<p>
+<itemize>
+ <item>Certain drawing operations are very slow when using 24 bit per
+ pixel depth mode. We hope to fix this in a future release.
+</itemize>
+
+
+<sect>Author
+<p>
+<itemize>
+ <item>Kevin E. Martin <it>&lt;kevin@precisioninsight.com&gt;</it>
+</itemize>
+
+This driver was donated to The XFree86 Project by:
+<verb>
+ Precision Insight, Inc.
+ Cedar Park, TX
+ USA
+</verb>
+
+<htmlurl name="http://www.precisioninsight.com"
+ url="http://www.precisioninsight.com">
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/i740.sgml,v 1.2 1999/08/23 06:18:34 dawes Exp $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/index.post b/xc/programs/Xserver/hw/xfree86/doc/sgml/index.post
new file mode 100644
index 000000000..f349b8099
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/index.post
@@ -0,0 +1,8 @@
+
+</itemize>
+
+</article>
+
+<!--
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/index.post,v 1.1 1999/08/24 11:24:09 dawes Exp $
+-->
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/index.pre b/xc/programs/Xserver/hw/xfree86/doc/sgml/index.pre
new file mode 100644
index 000000000..b798df3c1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/index.pre
@@ -0,0 +1,18 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN"[
+<!ENTITY % defs SYSTEM "defs.ent"> %defs;
+]>
+
+<article>
+
+<!-- Title information -->
+<title>Documentation for XFree86&trade; version &relvers;
+<author>The XFree86 Project, Inc
+<date>31 August 1999
+
+<!--
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/index.pre,v 1.3 1999/08/31 08:39:09 dawes Exp $
+-->
+
+<p>
+<itemize>
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/isc.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/isc.sgml
new file mode 100644
index 000000000..8eaadcd72
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/isc.sgml
@@ -0,0 +1,607 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN" [
+<!ENTITY % defs SYSTEM "defs.ent"> %defs;
+]>
+
+<article>
+
+<!-- made up title -->
+<title> Information for ISC Users
+<author> Michael Rohleder
+<date> 06 March 1999
+
+<ident>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/isc.sgml,v 3.22 1999/08/28 10:43:33 dawes Exp $
+</ident>
+
+<toc>
+
+<sect> X11R6/XFree86 on Interactive Unix <p>
+
+This document provides some additional information about
+compiling and using X11R6 and XFree86 on your
+Interactive Unix, also referred to as ISC.
+
+If you have any suggestions, comments, fixes or ideas regarding
+X11R6/XFree86 on Interactive Unix, send e-mail to
+
+<email>michael.rohleder@stadt-frankfurt.de</email><p>
+Bug Reports should be sent to<p>
+<email>XFree86@XFree86.Org</email><p>
+Questions or anything else should be posted to the NewsGroup<p>
+<htmlurl name="comp.windows.x.i386unix" url="news:comp.windows.x.i386unix"<p>
+
+There is currently no support for shared Libraries so it will be filespace
+consuming if you want to build X11-clients with X11R6. Best you mix X11R6
+Server with X11R5 and X11R4 clients. And only compile clients who need the
+new facilities provided in the X11R6 Libraries against them.
+
+<sect> Things needed for compiling the sources<p>
+
+<descrip>
+ <tag> gcc </tag>
+ Use the highest number for x you found.
+ Fresco will only build 2.6.3 and later.
+ I'd tried gcc Version 2.5.8, 2.6.0, 2.6.2, 2.6.3 and 2.7.2.
+ Current: 2.8.1
+ <p>
+ Since 2.6.3 the current source tree should be able to compile
+ with a little bit more Optimization:
+ <tt> &num;define DefaultCDebugFlags -O3 -fomit-frame-pointer</tt>
+ inside xf86site.def to overwrite the default -O2.
+ <p>
+ With 2.7.x you must specify
+ <tt>&num;define UsePosix YES</tt> inside xf86site.def.
+ This is necessary to build the sources successfully.
+ Versions prior to 2.7.0 could define it, but don't need it for a
+ clean build.
+ <p>
+ With 2.8.1 on Pentium CPU we can use special 586 Optimization.
+ Try the following define inside your host.def.
+ <verb>
+ #define DefaultGcc2i386Opt \
+ -O2 -march=pentium -mpentium -Wall -Wno-implicit-int \
+ -fno-strength-reduce
+ /* default with 2.8.1, so not really needed
+ -malign-loops=2 -malign-jumps=2 -malign-functions=2
+ */
+ </verb>
+ <tag> libg++-2.x.x </tag>
+ The needed g++ Libraries for use with g++ 2.x.x. As this is only
+ necessary for Fresco, it isn't needed anymore since X11R6.1.
+ <tag> binutils </tag>
+ You could use the assembler and linker
+ the assembler is most preferred,and the linker is needed
+ at least if you want to link libFresco.a within a Program.
+ Don't use strip and ar/ranlib, the first generates buggy binaries
+ when stripping (at least on my machines) and the last requires
+ the use of ranlib after creating an archive, this is not configured.
+ Current: 2.8.1.0.15 (Used: as, ld, ar, strip)
+ <tag> gnu-malloc </tag>
+ Due to better memory usage we should use GNU's malloc library
+ on systems where possible.
+
+ Enable <tt>&num;define UseGnuMalloc YES</tt>
+ inside xf86site.def or within the Linkkit site.def.
+
+ Enable and set <tt>&num;define GnuMallocLibrary</tt>
+ to your needs, if it isn't like the default
+ <tt>-L/usr/local/lib -lgmalloc</tt>.
+
+ <tag> inline-math (optional)</tag>
+ This is the "original" inline-math package available at your
+ favorite Linux Mirror.
+
+ Use <tt>&num;define UseInlineMath YES</tt>
+ inside host.def to enable it. Please note the changes section
+ what else to do, to use this package.
+
+</descrip>
+
+<sect> Changes to the System Header Files<p>
+
+You have to change some of the standard header files supplied with
+your version of Interactive. You also need to change some of the include
+files in the gcc-lib/include directory.
+
+Let us say the gcc-files are in directory
+
+<tt>/usr/local/lib/gcc-lib/i[345]86-isc[34].[0-9]/2.6.x</tt>
+
+referred to as <tt>"gcc-lib"</tt>
+
+ <sect1><tt>/usr/include/sys/limits.h</tt><p>
+ and <tt>gcc-lib/include/sys/limits.h</tt>
+
+ <verb>
+ #ifndef OPEN_MAX
+ #ifdef ISC
+ #define OPEN_MAX 256
+ #else
+ #define OPEN_MAX 20
+ #endif
+ #endif
+ </verb>
+ <tt>OPEN_MAX</tt> had to be increased to prevent
+ Xlib Errors (max no. of clients reached).
+<p>
+ <sect1><tt>/usr/include/sys/ioctl.h</tt><p>
+ surrounded by
+ <verb>
+ #ifndef _IOCTL_H
+ #define _IOCTL_H
+ ...
+ #endif
+ </verb>
+ to prevent multiple includes.
+<p>
+ <sect1><tt>/usr/include/errno.h</tt><p>
+ (and the corresponding gcc-include-file)
+ add <verb>
+ #include <net/errno.h>
+ </verb>
+ because of <bf>EWOULDBLOCK</bf> undefined in several places
+ regarding lbx.
+ Surround <tt>/usr/include/net/errno.h</tt> with
+
+ <verb>
+ #ifndef _NET_ERRNO_H
+ #define _NET_ERRNO_H
+ ...
+ #endif
+ </verb>
+
+ to prevent multiple includes were <tt>&lt;net/errno.h&gt;</tt>
+ is explicit included from the sources.
+<p>
+ <sect1><tt>/usr/include/rpc/types.h</tt><p>
+ copy this file to <tt>gcc-lib/include/rpc/types.h</tt>
+ and change the declaration of <bf>malloc()</bf> to
+
+ <verb>
+ #if !defined(__cplusplus)
+ extern char *malloc();
+ #endif
+ </verb>
+
+ Note that this is only necessary if you want to build Fresco
+<p>
+ <sect1><tt>/usr/include/sys/un.h</tt><p>
+ such a file does not exist on Interactive. You may like to generate
+ it, if you don't like a warning from depend. It isn't needed to compile
+ the sources successfully.
+
+ You could use the following to produce it:
+ <verb>
+ #ifndef X_NO_SYS_UN
+ struct sockaddr_un {
+ short sun_family; /* AF_UNIX */
+ char sun_path[108]; /* path name (gag) */
+ };
+ #endif
+ </verb>
+<p>
+ <sect1><tt>/usr/include/math.h</tt><p>
+ To use the Inline Math package you have to change your existing
+ math.h. Please note, the way I include the new Header file, is
+ different than suggested in inline-math's README.
+
+ Please add the following at the bottom of math.h, before the last
+ #endif
+ <verb>
+#if defined(UseInlineMath)
+
+/* Needed on ISC __CONCAT, PI */
+#ifndef __CONCAT
+/*
+ * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
+ * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
+ * The __CONCAT macro is a bit tricky -- make sure you don't put spaces
+ * in between its arguments. __CONCAT can also concatenate double-quoted
+ * strings produced by the __STRING macro, but this only works with ANSI C.
+ */
+#if defined(__STDC__) || defined(__cplusplus)
+#define __CONCAT(x,y) x ## y
+#define __STRING(x) #x
+#else /* !(__STDC__ || __cplusplus) */
+#define __CONCAT(x,y) x/**/y
+#define __STRING(x) "x"
+#endif /* !(__STDC__ || __cplusplus) */
+#endif
+
+#ifndef PI
+#define PI M_PI
+#endif
+
+#include "/usr/local/include/i386/__math.h"
+#endif
+ </verb>
+
+
+
+<sect> make World <p>
+<code>
+BOOTSTRAPCFLAGS="-DISC [-DISC30 | -DISC40] -DSYSV [-Di386]"
+</code>
+
+<descrip>
+<tag>-DISC -DISC30</tag>
+ these two defines are necessary to build the release
+ I don't know if the build will succeed for ISC versions
+ prior than 3.x
+
+<tag>-DISC40</tag>
+ are only for getting the ISC version and therefore
+ set the HasSymLinks to Yes ('cause symbolic linking
+ were only supported from Version 4.x using the S5L Filesystem)<p>
+ If you could use long filenames, you could enable
+ the installation of expanded Manual Pages by including
+ <tt> &num;define ExpandManNames YES </tt>
+ inside xf86site.def.<p>
+ A build on ISC 4.x only needs -DISC40 defined in the BOOTSTRAPCFLAGS
+ ( -DISC30 will be included automatically ).<p>
+ Note: due to some incompatibilities between ISC 4.0 and 4.1, the default
+ is to build for ISC4.0, even if you build on 4.1.
+ If you want to build only for 4.1 you should
+ set <tt> &num;define IscCompileVersion 410 </tt> inside your
+ host.def.<p>
+ (the fchmod function isn't available on 4.0, so it won't compile,
+ and binaries from 4.1 won't run cause of the unsupported System call
+ The libraries build for 4.1 couldn't be used with 4.0 Systems, due
+ to some functions not available on 4.0)
+
+<tag>-DSYSV &lsqb;-Di386&rsqb;</tag>
+ standard defines for SystemV Release3 on x86 platform.
+ You don't need to explicitly define -Di386 because
+ this is pre-defined in /lib/cpp.
+
+</descrip>
+
+<sect> linear Addressing <p>
+
+<itemize>
+<item>Compiling &hellip; <p>
+You need the mmap-2.2.3 driver installed on your system.
+If you don't have the mmap-2.2.3 driver installed, you could use the driver
+source in the file
+<verb>
+xc/programs/Xserver/hw/xfree86/etc/mmapSVR3.shar
+</verb>
+or
+<verb>
+/usr/X11R6/lib/X11/etc/mmapSVR3.shar
+</verb>
+Build and install the driver as instructed. You'll need the file
+/usr/include/sys/mmap.h for compiling the X11R6/XFree86 source tree,
+with linear addressing enabled.
+
+<code>
+The new loadable X Server is not tested to work without linear addressing.
+</code>
+
+
+<item>Using &hellip; <p>
+
+To use the linear address-mapping of the framebuffer you need the mmap Driver
+by Thomas Wolfram (Version 2.2.3) installed in your Kernel.
+If you have installed it, most servers will use linear addressing by default.
+Others may require
+setting the
+<verb>
+Option "linear"
+</verb>
+in your XF86Config. Check the appropriate manual pages for details.
+Maybe you need also the MemBase specified in XF86Config. Please refer to the
+appropriate README of your Card/Server, for
+<bf>How to use..</bf>.
+
+I could only test these cards on Interactive UNIX
+<itemize>
+ <item>Spea/V7 Vega - clgd5428 - VLB - (old)<p>
+ with 32MB MainMemory installed I couldn't use it.
+ My tests with different mappings into the address space
+ results in no Graphics displayed or a spontaneous reboot.<p>
+ <item>ATI GUP - mach32 - VLB - (old)<p>
+ with 32MB MainMemory installed I could map the CardMemory
+ at MemBase 0x07c00000. I could work with all clients
+ until I try to activate a Motif 1.1.1 InputField inside a
+ Motif Client like Mosaic-2.4 or xplan. This results in a
+ crash of the XServer. <p>
+ <verb>
+ !!! You could work around this !!!
+ </verb>
+ Expand your .Xdefaults with
+ <verb>
+ *blinkRate: 0
+ *cursorPositionVisible: false
+ </verb>
+
+ This bug seems to be fixed since 3.1.2, and therefore the
+ workaround is not needed anymore.
+ <item>ELSA Winner 2000PRO/X Revision G<p>
+ if you experience a Problem with this Card you could try to
+ use the older Chipset Driver instead "newmmio".
+ <p>If you declare
+ <verb>
+ Chipset "mmio_928"
+ </verb>
+ inside your XF86Config, it may be alright again.<p>
+ With the current XF86_S3 I don't encounter any problem.
+ <item>Diamond FireGL 1000<p>
+ <verb>
+ 3Dlabs GLINT Permedia rev 1
+ 3Dlabs GLINT Delta rev 1
+ </verb>
+
+</itemize>
+
+</itemize>
+
+<sect>XKeyboard Extension<p>
+
+<itemize>
+<item>Sample Setup &hellip; <p>
+Here is a sample XKeyboard Definition to include inside the Keyboard Section
+of your XF86Config File.
+<verb>
+ Xkbkeycodes "xfree86"
+/* XkbSymbols "us(pc101)+de_nodead" */
+/* This has changed between 3.1.2E and 3.1.2F */
+/* it is now: */
+ XkbSymbols "us(pc102)+de(nodeadkeys)"
+ XkbTypes "default"
+ XkbCompat "default"
+ XkbGeometry "pc"
+</verb>
+
+or you could use this one with the new Options:
+<verb>
+ XkbRules "xfree86"
+ XkbModel "pc102"
+ XkbLayout "de"
+ XkbVariant "nodeadkeys"
+</verb>
+
+</itemize>
+
+<sect> Multibuffer Extension <p>
+
+This is an obsolete Extension. Anyway, if you want to include this Extension
+inside your build, you have to add:
+ <tt>&num;define BuildMultibuffer YES</tt> inside xf86site.def
+Please note, this Extension should be disabled when building the Loader Server.
+
+<sect> Default Definitions <p>
+
+These are default options defined inside isc.cf.
+You can redefine them inside host.def.
+
+<verb>
+/* Disable the use of /var/X11 */
+#ifndef HasVarDirectory
+#define HasVarDirectory NO
+#endif
+
+/* Use mmap Driver */
+#ifndef HasSVR3mmapDrv
+# define HasSVR3mmapDrv YES
+#endif
+
+/* Use inline Math from linux ;-) package inline-math-2.6.tar.gz */
+/* should be available on your favorite linux ftp */
+#ifndef UseInlineMath
+# define UseInlineMath YES
+#endif
+
+/* Use cbrt from liboptm.a (Interactive icc Compiler) */
+#ifndef HasCbrt
+# define HasCbrt YES
+#endif
+
+/* Use GNUs MallocLibrary (and the Location for the Lib) */
+#ifndef UseGnuMalloc
+# define UseGnuMalloc YES
+#endif
+
+/* Install Zlib Headers - used in lib/zlib/Imakefile */
+#ifndef OsNeedZlibHeaders
+# define OsNeedZlibHeaders YES
+#endif
+
+/* Expand Manual Pages (needs S5L) */
+#ifndef ExpandManNames
+# define ExpandManNames YES
+#endif
+
+/* if you have groff or the TextProcessingWorkbench - don't preformat*/
+#ifndef FormattedManPages
+# define FormattedManPages NO
+#endif
+
+#ifndef HasSgmlFmt /* HasLinuxDoc */
+# define HasSgmlFmt YES
+#endif
+
+/* XF86Setup Util */
+#ifndef HasTk
+#define HasTk YES
+#define HasTcl YES
+#endif
+
+#ifndef HasPosixRegex /* Need extra/regex since 3.9Ns */
+#define HasPosixRegex NO
+#endif
+
+#ifndef DoLoadableServer
+#define DoLoadableServer YES
+#endif
+
+#ifndef CpuOption
+#define CpuOption -mpentium
+#endif
+
+</verb>
+
+
+<sect> Installation <p>
+
+After your <bf>make World BOOTSTRAPCFLAGS="&hellip;</bf> succeed,
+<verb>
+make install
+</verb>
+to install in /usr/X11R6. Make sure you have enough space, and /usr/X11R6
+exists either as a directory or a symlink to another directory maybe in another
+filesystem.
+<verb>
+make install.man
+</verb>
+to install the compressed nroff versions of the manual pages into
+/usr/X11R6/man. This directory will be generated if it doesn't exist.
+<verb>
+make install.linkkit
+</verb>
+to install the server binary LinkKit into /usr/X11R6/lib/Server.
+
+<code>
+ You should tune the Kernel using the command-file
+
+ /usr/X11R6/lib/X11/etc/xf86install
+
+ This will increase the available pseudo devices,
+ some Tunable Parameters and install some files
+ to use inside sysadm. You could also install
+ some additional Fonts and Terminal files.
+
+</code>
+
+This is now a menu driven config tool for XFree86 on IUS
+For the first setup you should go from 1 to x step by step.
+Here is its main screen
+<code>
+
+X11R6 XFree86 Version (version)
+-------------------------------------------------------------------------------
+
+
+
+ Check dependencies: 1
+ Make XFree86 Label 2
+ Install Remove script 3
+ Setup node.d + sdevice.d Files 4
+ Tune Kernel Variables 5
+ Tune PseudoTerminals 6
+ Install xterm terminal entries 7
+ Install VGA font 8
+ Save current KernelConfig 9
+
+ Exit X
+
+
+Your Choice [1-9]?<enter>:
+
+</code>
+
+You also should increase MAXUMEM to its maximum, else programs may die with:
+<code>
+X Error of failed request: BadAlloc (insufficient resources for operation)
+ Major opcode of failed request: 53 (X_CreatePixmap)
+ Serial number of failed request: 37791
+ Current serial number in output stream: 37822
+ Widget hierarchy of resource: unknown
+</code>
+You could do this automatically with menu entry no. 5.
+
+<sect>Using &hellip; <p>
+
+<itemize>
+<item>Xprt:<p>
+ The new Xprint Server is configured to use lpr as its print helper
+ so you have to install and configure lpr to use Xprt.<p>
+
+<item>Keyboard:<p>
+ You don't need any modmap-File to get your keyboard
+ working with any iso-8859-1 Font. Simply enable
+
+ <itemize>
+ <item>LeftAlt Meta
+
+ <item>RightAlt ModeShift
+
+ <item>RightCtl Compose
+ </itemize>
+
+ in your XF86Config - Section "Keyboard"
+
+<item>xpcterm: <p>
+ if you want to get the German 'Umlaut' inside your ISC X11R4 client
+ xpcterm when you are using the ega/vga font. Set up the
+ user's .Xdefaults to contain:
+ <verb>
+ XEga*AT386.Translations: #override \
+ Shift<Key>odiaeresis: string(0x99) \n\
+ <Key>odiaeresis: string(0x94) \n\
+ Shift<Key>adiaeresis: string(0x8e) \n\
+ <Key>adiaeresis: string(0x84) \n\
+ Shift<Key>udiaeresis: string(0x9a) \n\
+ <Key>udiaeresis: string(0x81) \n\
+ Shift<Key>ssharp: string(0x3f) \n\
+ Meta<Key>ssharp: string(0x5c) \n\
+ <Key>ssharp: string(0xe1)
+ </verb>
+
+ The only disadvantage is that you have to use <tt>Alt</tt> instead of
+ <tt>AltGr</tt> to get the <tt>&bsol;</tt> Backslash (on a German
+ Keyboard)
+
+ You have to call your xpcterm with the option
+ <tt>-name XEga -fn ega</tt>
+
+<item>Switching between X11R5 and X11R6 configuration<p>
+ to compile X11-Clients as either R6 or R5 clients,
+ should be as easy as you only switch the PATH components
+ so that either <tt>/usr/X11R6/bin/xmkmf</tt> or
+ <tt>/usr/X386/bin/xmkmf</tt> would make the new Makefile.
+
+<item>ISC Streams Pipes <p>
+ The old path to the pipes on ISC's R4 <tt>/tmp/.X11-unix</tt>
+ has changed to <tt>/dev/X/ISCCONN</tt>. For compatibility
+ reasons on ISC, the pipes in the new directory will be
+ linked to a file inside the old.
+ This will normally be a hard link, so it can't go across
+ filesystems. On ISC Version 4.x this is now allowed. But
+ you should use the new S5L on both filesystems.
+ ISC30 systems should take care that the two directories
+ are on the same FS. Else if you are using a ISC40 compiled
+ binary, the Server could maybe abort due to a SIGSYS.
+ We tried to catch this signal, so if it dumps please send
+ me a note.
+
+<item>Warnings you may see: <p>
+ <itemize>
+ <item>
+ Since 3.2A, you could see a warning from pre X11R6.3 clients.<p>
+ <verb>
+ Warning: Unable to load any usable fontset
+ </verb>
+ The case are the new gzipped fonts, but the Warning isn't serious.<p>
+ <item>
+ If you start a server you may see the following message:<p>
+ <verb>
+ _XSERVTransOpen: transport open failed for named/enigma:0
+ _XSERVTransMakeAllCOTSServerListeners: failed to open listener for named
+ </verb>
+ This message either isn't critical. Interactive doesn't support this
+ kind of connection.<p>
+ </itemize>
+
+</itemize>
+
+
+<sect> Acknowledgements <p>
+
+All thanks should go to the members of the
+<bf>XFree86 Team</bf> for their great work
+and the <bf>X Consortium</bf> for their Public Release of X11R6,
+as to all who contribute to this excellent piece of free software.
+
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/mouse.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/mouse.sgml
new file mode 100644
index 000000000..87832a251
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/mouse.sgml
@@ -0,0 +1,671 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN" [
+<!ENTITY % defs SYSTEM "defs.ent"> %defs;
+]>
+
+<article>
+<title>Mouse Support in XFree86
+<author>Kazutaka Yokota
+<date>4 July 1999
+
+<ident>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/mouse.sgml,v 1.7 1999/08/28 10:43:34 dawes Exp $
+</ident>
+
+<toc>
+
+<sect>Introduction <p>
+
+This document describes mouse support in XFree86 &relvers;.
+
+Mouse configuration has often been mysterious task for
+novice users.
+However, once you learn several basics, it is straightforward
+to write the mouse <tt>"InputDevice"</tt>
+section in the <tt>XF86Config</tt> file by hand.
+
+<sect>Supported Hardware <p>
+
+The XFree86 X server supports three classes of mice:
+serial, bus and PS/2 mice.
+
+<descrip>
+<tag>Serial mouse</tag>
+The serial mouse has been the most popular pointing device for
+PCs.
+There have been numerous serial mouse models from a number of
+manufactures.
+Despite the wide range of variations, there have been relatively
+few protocols (data format) with which the serial mouse talks
+to the host computer.
+
+The modern serial mouse conforms to the PnP COM device specification
+so that the host computer can automatically detect the mouse
+and load an appropriate driver.
+The XFree86 X server supports this specification and can detect
+popular PnP serial mouse models on most platforms.
+
+<tag>Bus mouse</tag>
+The bus mouse connects to a dedicated interface card in an expansion
+slot.
+Some video cards, notably those from ATI, and integrated I/O
+cards may also have a bus mouse connector.
+Some bus mice are known as `InPort mouse'.
+
+Note that some mouse manufactures have sold a package including a serial mouse
+and a serial interface card.
+Don't confuse this type of products with the genuine bus mouse.
+
+<tag>PS/2 mouse</tag>
+They are sometimes called `Mouse-port mouse'.
+The PS/2 mouse is becoming increasingly common and popular.
+
+The PS/2 mouse is an intelligent device and may have more than
+three buttons and a wheel or a roller.
+The PS/2 mouse is usually compatible with the original PS/2 mouse from IBM
+immediately after power up.
+The PS/2 mouse with additional features requires a specialized
+initialization procedure to enable these features.
+Without proper initialization, it behaves as though it were an ordinary
+two or three button mouse.
+</descrip>
+
+Many mice nowadays can be used both as a serial mouse and as a PS/2 mouse.
+They has a logic to distinguish which interface it is connected to.
+However, the mouse which is not marketed as compatible with both
+serial and PS/2 mouse interface lacks this logic and cannot be
+used in such a way, even if you can find an appropriate
+adapter with which you can connect the PS/2 mouse to a serial port
+or visa versa.
+
+XFree86 supports the mouse with a wheel, a roller or a knob.
+Its action is detected as the Z (third) axis motion of the mouse.
+As the X server or clients normally do not use the Z axis movement of the
+pointing device, a configuration option, <tt>"ZAxisMapping"</tt>,
+is provided to assign the Z axis movement to another axis or a pair
+of buttons (see below).
+
+<sect>OS Support for Mice <p>
+
+<sect1>Summary of Supported Mouse Protocol Types <p>
+<verb>
+ Protocol Types
+ serial PnP BusMouse PS/2 Extended PS/2
+OS platforms protocols serial protocol protocol protocols
+ "Auto" "BusMouse" "PS/2" "xxxPS/2"
+--------------------------------------------------------------------
+BSD/OS Ok ? ? ? ?
+FreeBSD Ok Ok Ok Ok SP*1
+FreeBSD(98) Ok ? Ok NA NA
+Interactive Unix Ok NA ?*1 ?*1 NA
+Linux Ok Ok Ok Ok Ok
+Linux/98 Ok ? Ok NA NA
+LynxOS Ok NA Ok Ok NA
+NetBSD Ok Ok Ok SP*1 SP*1
+NetBSD/pc98 Ok ? Ok NA NA
+OpenBSD Ok Ok Ok Ok*1 OK*1
+OS/2 SP*2 SP*2 SP*2 SP*2 SP*2
+SCO Ok ? SP*1 SP*1 NA
+Solaris 2.x Ok NA*1 ?*1 Ok Ok
+SVR4 Ok NA*1 SP*1 SP*1 NA
+PANIX Ok ? SP*1 SP*1 NA
+
+Ok: support is available, NA: not available, ?: untested or unknown.
+SP: support is available in a different form
+
+*1 Refer to the following sections for details.
+*2 XFree86/OS2 will support any type of mouse that the OS supports,
+ whether it is serial, bus mouse, or PnP type.
+
+</verb>
+
+<sect1>BSD/OS <p>
+No testing has been done with BSD/OS.
+
+<sect1>FreeBSD <p>
+FreeBSD supports the <tt>"SysMouse"</tt> protocol which must be
+specified when the <tt>moused</tt> daemon is running in versions 2.2.1
+or later.
+
+FreeBSD versions 2.2.6 or later include the kernel-level
+support for extended PS/2 mouse protocols and there is no need to specify
+the exact protocol name to the X server.
+Instead specify the <tt>"PS/2"</tt> or <tt>"Auto"</tt> protocol and
+the X server will automatically make use of the kernel-level support.
+
+In fact, <tt>"Auto"</tt> protocol support is really efficient in these
+versions.
+You may always specify <tt>"Auto"</tt> to any mouse, serial,
+bus or PS/2, unless the mouse is an old serial model which doesn't
+support PnP.
+
+FreeBSD versions 2.2.5 or earlier do not support extended PS/2
+mouse protocols (<tt>"xxxPS/2"</tt>).
+Always specify the <tt>"PS/2"</tt> protocol for any PS/2 mouse
+in these versions regardless of the brand of the mouse.
+
+<sect1>FreeBSD(98) <p>
+The PS/2 mouse is not supported.
+
+<sect1>Interactive Unix <p>
+The PnP serial mouse support (the <tt>"Auto"</tt> protocol) is not
+supported for the moment.
+
+The bus mouse and PS/2 mouse should be supported by using the
+appropriate device drivers.
+Use <tt>/dev/mouse</tt> for the <tt>"BusMouse"</tt> protocol
+and <tt>/dev/kdmouse</tt> for the <tt>"PS/2"</tt> protocol.
+These protocols are untested but may work.
+Please send success/failure reports to
+<email>michael.rohleder@stadt-frankfurt.de</email>.
+
+<sect1>Linux <p>
+All protocol types should work.
+
+<sect1>Linux/98 <p>
+The PS/2 mouse is not supported.
+
+<sect1>LynxOS <p>
+The PnP serial mouse support (the <tt>"Auto"</tt> protocol) is disabled in
+LynxOS, because of limited TTY device driver functionality.
+
+<sect1>NetBSD <p>
+NetBSD 1.3.x and former does not support extended PS/2 mouse protocols
+(<tt>"xxxPS/2"</tt>).
+The PS/2 mouse device driver <tt>/dev/pms</tt> emulates the bus mouse.
+Therefore, you should always specify the <tt>"BusMouse"</tt> protocol for
+any PS/2 mouse regardless of the brand of the mouse.
+<p>
+The <tt>"wsmouse"</tt> protocol introduced in NetBSD
+1.4 along with the wscons console driver is supported. You need to run binaries
+compiled on NetBSD 1.4 to have support
+for it though. Use <tt>"/dev/wsmouse0"</tt> for the device. Refer to the
+<em>wsmouse(4)</em> manual page for kernel configuration informations.
+
+<sect1>NetBSD/pc98 <p>
+The PS/2 mouse is not supported.
+
+<sect1>OpenBSD <p>
+The raw PS/2 mouse device driver <tt>/dev/psm0</tt> uses the raw PS/2
+mouse protocol.
+
+OpenBSD 2.2 and earlier does not support extended PS/2 mouse protocols
+(<tt>"xxxPS/2"</tt>) . Therefore, you should specify the
+<tt>"PS/2"</tt> protocol for any PS/2 mouse regardless of the brand of
+the mouse.
+
+OpenBSD 2.3 and later support all extended PS/2 mouse protocols.
+You can select the <tt>"Auto"</tt> protocol for PnP PS/2
+mice or any specific extended (<tt>"xxxPS/2"</tt>) protocol
+for non PnP mice.
+
+There is also a cooked PS/2 mouse device driver <tt>/dev/pms0</tt>
+which emulates the bus mouse. Specify the <tt>"BusMouse"</tt>
+protocol for any PS/2 mouse regardless of the brand of the mouse when
+using this device.
+
+<sect1>OS/2 <p>
+XFree86/OS2 always uses the native mouse driver of the operating system
+and will support any type of pointer that the OS supports, whether it is
+serial, bus mouse, or PnP type.
+If the mouse works under Presentation Manager,
+it will also work under XFree86/OS2.
+
+Always specify <tt>"OSMouse"</tt> as the protocol type.
+
+<sect1>SCO <p>
+The bus and PS/2 mouse are supported with the <tt>"OSMouse"</tt>
+protocol type.
+
+The <tt>"OSMouse"</tt> may also be used with the serial mouse.
+
+<sect1>Solaris <p>
+Testing has been done with Solaris 2.5.1 and 2.6. Logitech and
+Microsoft bus mice
+have not been tested, but might work with the <tt>/dev/logi</tt> and
+<tt>/dev/msm</tt> devices.
+Standard 2 and 3 button PS/2 mice work with the <tt>"PS/2"</tt> protocol
+type and the <tt>/dev/kdmouse</tt> device.
+The PnP serial mouse support (the <tt>"Auto"</tt> protocol) has been tested
+and does not work.
+
+<sect1>SVR4 <p>
+The bus and PS/2 mouse may be supported with the <tt>"Xqueue"</tt>
+protocol type.
+
+The <tt>"Xqueue"</tt> may also be used with the serial mouse.
+
+The PnP serial mouse support (the <tt>"Auto"</tt> protocol) is not
+tested.
+
+<sect1>PANIX <p>
+The PC/AT version of PANIX supports the bus and PS/2 mouse with the
+<tt>"Xqueue"</tt> protocol type.
+The PC-98 version of PANIX supports the bus mouse with the
+<tt>"Xqueue"</tt> protocol type.
+
+<sect>Configuring Your Mouse <p>
+
+Before using the <tt>xf86config</tt> program
+to set up mouse configuration, you must identify the interface type,
+the device name and the protocol type of your mouse.
+Blindly trying every possible combination of mouse settings
+will lead you nowhere.
+
+The first thing you need to know is the interface type
+of the mouse you are going to use.
+It can be determined by looking at the connector of the mouse.
+The serial mouse has a D-Sub female 9- or 25-pin connector.
+The bus mice have either a D-Sub male 9-pin connector
+or a round DIN 9-pin connector.
+The PS/2 mouse is equipped with a small, round DIN 6-pin connector.
+Some mice come with adapters with which the connector can
+be converted to another. If you are to use such an adapter,
+remember that the connector at the very end of the mouse/adapter pair is
+what matters.
+
+The next thing to decide is a device node to use for the given interface.
+For the bus and PS/2 mice, there is little choice;
+your OS most possibly offers just one device node each
+for the bus mouse and PS/2 mouse.
+There may be more than one serial port to which the serial
+mouse can be attached.
+
+The next step is to guess the appropriate protocol type for the mouse.
+The X server may be able to select a protocol type for the given mouse
+automatically in some cases.
+Otherwise, the user has to choose one manually.
+Follow the guidelines below.
+
+<descrip>
+<tag>Bus mouse</tag>
+The bus and InPort mice always use <tt>"BusMouse"</tt>
+protocol regardless of the brand of the mouse.
+
+Some OSs may allow you to specify <tt>"Auto"</tt> as the
+protocol type for the bus mouse.
+
+<tag>PS/2 mouse</tag>
+The <tt>"PS/2"</tt> protocol should always be tried first for the PS/2 mouse
+regardless of the brand of the mouse.
+Any PS/2 mouse should work with this protocol type, although
+wheels and other additional features are unavailable in the
+X server.
+
+After verifying the mouse works with this protocol,
+you may choose to specify one of <tt>"xxxPS/2"</tt> protocols so that
+extra features are made available in the X server.
+However, support for these PS/2 mice assumes certain behavior of
+the underlying OS and may not always work as expected.
+Support for some PS/2 mouse models may be disabled all together
+for some OS platforms for this reason.
+
+Some OSs may allow you to specify <tt>"Auto"</tt> as the
+protocol type for the PS/2 mouse and the X server will automatically
+adjust itself.
+
+<tag>Serial mouse</tag>
+The XFree86 server supports a wide range of mice, both old and new.
+If your mouse is of a relatively new model, it may conform to the
+PnP COM device specification and the X server may be able to
+detect an appropriate protocol type for the mouse automatically.
+
+Specify <tt>"Auto"</tt> as the protocol type and start the X server.
+If the mouse is not a PnP mouse, or the X server cannot determine
+a suitable protocol type, the server will print the following
+error message and abort.
+
+<verb>
+<mousename>: cannot determine the mouse protocol
+</verb>
+
+If the X server generates the above error message, you need to
+manually specify a protocol type for your mouse.
+Choose one from the following list:
+
+<itemize>
+ <item><tt>GlidePoint</tt>
+ <item><tt>IntelliMouse</tt>
+ <item><tt>Logictech</tt>
+ <item><tt>Microsoft</tt>
+ <item><tt>MMHittab</tt>
+ <item><tt>MMSeries</tt>
+ <item><tt>MouseMan</tt>
+ <item><tt>MouseSystems</tt>
+ <item><tt>ThinkingMouse</tt>
+</itemize>
+
+When you choose, keep in mind the following rule of thumb:
+
+<enum>
+<item><tt>"Logitech"</tt> protocol is for old serial mouse models
+from Logitech.
+Modern Logitech mice use either <tt>"MouseMan"</tt> or <tt>"Microsoft"</tt>
+protocol.
+<item>Most 2-button serial mice support the <tt>"Microsoft"</tt> protocol.
+<item>3-button serial mice may work with the <tt>"Mousesystems"</tt>
+protocol. If it doesn't, it may work instead with the
+<tt>"Microsoft"</tt> protocol although the third (middle) button won't
+function.
+3-button serial mice may also work with the <tt>"Mouseman"</tt>
+protocol under which the third button may function as expected.
+<item>3-button serial mice may have a small switch at the bottom
+of the mouse to choose between ``MS'' and ``PC'', or ``2'' and ``3''.
+``MS'' or ``2'' usually mean the <tt>"Microsoft"</tt> protocol.
+``PC'' or ``3'' will choose the <tt>"MouseSystems"</tt> protocol.
+<item>If the serial mouse has a roller or a wheel, it may be compatible
+with the <tt>"IntelliMouse"</tt> protocol.
+<item>If the serial mouse has a roller or a wheel and it doesn't work
+with the <tt>"IntelliMouse"</tt> protocol, you have to use it
+as a regular 2- or 3-button serial mouse.
+</enum>
+
+If the <tt>"Auto"</tt> protocol is specified and the mouse seems working,
+but you find that not all features of the mouse is available, that is
+because the X server does not have native support for that model of mouse
+and is using a ``compatible'' protocol according to PnP information.
+
+If you suspect this is the case with your mouse, please send a report to
+<email>XFree86@XFree86.Org</email>.
+
+<tag>Standardized protocols</tag>
+Mouse device drivers in your OS may use the standardized protocol
+regardless of the model or the class of the mouse.
+For example, SVR4 systems may support <tt>"Xqueue"</tt> protocol.
+In FreeBSD the system mouse device <tt>/dev/sysmouse</tt>
+uses the <tt>"SysMouse"</tt> protocol.
+Please refer to the OS support section of this file for more information.
+
+</descrip>
+
+<sect>XF86Config Options <p>
+
+The old <tt>Pointer</tt> section has been replaced by a more general
+<tt>InputDevice</tt> section. The following is a minimal example
+of an <tt>InputDevice</tt> section for a mouse:
+
+<code>
+Section "InputDevice"
+ Identifier "Mouse 1"
+ Driver "mouse"
+ Option "Device" "/dev/mouse"
+ Option "Protocol" "Auto"
+EndSection
+</code>
+
+The <tt>mouse</tt> driver supports the following config file options:
+
+<sect1>Buttons <p>
+This option tells the X server the number of buttons on the mouse.
+Currently there is no reliable way to automatically detect the correct
+number.
+This option is the only means for the X server to obtain it.
+The default value is three.
+
+<verb>
+ Option "Buttons" "N"
+</verb>
+
+<sect1>ZAxisMappping <p>
+This option maps the Z axis (wheel) motion to a pair of buttons or to
+another axis.
+
+<verb>
+ Option "ZAxisMapping" "X"
+ Option "ZAxisMapping" "Y"
+ Option "ZAxisMapping" "N M"
+</verb>
+
+The first example will map the Z axis motion to the X axis motion.
+Whenever the user moves the wheel/roller, its movement is reported as
+the X axis motion. When the wheel/roller stays still, the real X axis
+motion is reported as is. The last example will map negative Z axis
+motion to the button <tt>N</tt> and positive Z axis motion to
+the button <tt>M</tt>. If this option is used and the buttons <tt>N</tt>
+or <tt>M</tt> actually exists in the mouse,
+their actions won't be detected by the X server.
+
+<sect1>Resolution <p>
+The following option will set the mouse device resolution to <tt>N</tt>
+counts per inch, if possible:
+
+<verb>
+ Option "Resolution" "N"
+</verb>
+
+Not all mice and OSs can support this option.
+
+<sect>Mouse Gallery <p>
+
+In all of the examples below, it is assumed that <tt>/dev/mouse</tt> is
+a link to the appropriate serial port or PS/2 mouse device.
+
+<sect1>MS IntelliMouse (serial, PS/2) <p>
+The wheel movement is recognized as the Z axis motion.
+This behavior is not compatible with XFree86 versions prior to 3.3.2,
+but is more consistent with the support for other mice with
+wheels or rollers.
+If you want to make the wheel behave like before,
+you can use the <tt>"ZAxisMapping"</tt> option as described above.
+<p>
+IntelliMouse supports the PnP COM device specification.
+<p>
+To use this mouse as a serial device:
+<verb>
+ Option "Protocol" "Auto"
+</verb>
+or:
+<verb>
+ Option "Protocol" "IntelliMouse"
+</verb>
+
+To use this mouse as the PS/2 device and the OS supports PS/2 mouse
+initialization:
+<verb>
+ Option "Protocol" "IMPS/2"
+</verb>
+
+To use this mouse as the PS/2 device but the OS does not support PS/2 mouse
+initialization (the wheel won't work in this case):
+<verb>
+ Option "Protocol" "PS/2"
+</verb>
+
+To use this mouse as the PS/2 device and the OS supports automatic
+PS/2 mouse detection:
+<verb>
+ Option "Protocol" "Auto"
+</verb>
+
+<sect1>Kensington Thinking Mouse (serial, PS/2) <p>
+This mouse has four buttons.
+Thinking Mouse supports the PnP COM device specification.
+<p>
+To use this mouse as a serial device:
+<verb>
+ Option "Protocol" "Auto"
+</verb>
+or:
+<verb>
+ Option "Protocol" "ThinkingMouse"
+</verb>
+
+To use this mouse as the PS/2 device and the OS supports PS/2 mouse
+initialization:
+<verb>
+ Option "Protocol" "ThinkingMousePS/2"
+</verb>
+
+To use this mouse as the PS/2 device but the OS does not support PS/2 mouse
+initialization (the third and the fourth buttons act as though they
+were the first and the second buttons):
+<verb>
+ Option "Protocol" "PS/2"
+</verb>
+
+To use this mouse as the PS/2 device and the OS supports automatic
+PS/2 mouse detection:
+<verb>
+ Option "Protocol" "Auto"
+</verb>
+
+<sect1>Genius NetScroll (PS/2) <p>
+This mouse has four buttons and a roller. The roller movement is
+recognized as the Z axis motion.
+<p>
+To use this mouse as the PS/2 device and the OS supports PS/2 mouse
+initialization:
+<verb>
+ Option "Protocol" "NetScrollPS/2"
+</verb>
+
+To use this mouse as the PS/2 device but the OS does not support PS/2 mouse
+initialization (the roller and the fourth button won't work):
+<verb>
+ Option "Protocol" "PS/2"
+</verb>
+
+To use this mouse as the PS/2 device and the OS supports automatic
+PS/2 mouse detection:
+<verb>
+ Option "Protocol" "Auto"
+</verb>
+
+<sect1>Genius NetMouse and NetMouse Pro (serial, PS/2) <p>
+These mice have a "magic button" which is used like a wheel or a
+roller. The "magic button" action is recognized as the Z axis motion.
+NetMouse Pro is identical to NetMouse except that it has the third
+button on the left hand side.
+<p>
+NetMouse and NetMouse Pro support the PnP COM device specification.
+When used as a serial mouse, they are compatible with MS IntelliMouse.
+<p>
+To use these mice as a serial device:
+<verb>
+ Option "Protocol" "Auto"
+</verb>
+or:
+<verb>
+ Option "Protocol" "IntelliMouse"
+</verb>
+
+To use this mouse as the PS/2 device and the OS supports PS/2 mouse
+initialization:
+<verb>
+ Option "Protocol" "NetMousePS/2"
+</verb>
+
+To use this mouse as the PS/2 device but the OS does not support PS/2 mouse
+initialization (the "magic button" and the third button won't work):
+<verb>
+ Option "Protocol" "PS/2"
+</verb>
+
+To use this mouse as the PS/2 device and the OS supports automatic
+PS/2 mouse detection:
+<verb>
+ Option "Protocol" "Auto"
+</verb>
+
+<sect1>ALPS GlidePoint (serial, PS/2) <p>
+The serial version of this pad device has been supported since XFree86
+3.2. `Tapping' action is interpreted as the fourth button press.
+(IMHO, the fourth button of GlidePoint should always be mapped to the first
+button in order to make this pad behave like the other pad products.)
+<p>
+To use this pad as a serial device:
+<verb>
+ Option "Protocol" "GlidePoint"
+</verb>
+
+To use this mouse as the PS/2 device and the OS supports PS/2 mouse
+initialization:
+<verb>
+ Option "Protocol" "GlidePointPS/2"
+</verb>
+
+To use this mouse as the PS/2 device but the OS does not support PS/2 mouse
+initialization:
+<verb>
+ Option "Protocol" "PS/2"
+</verb>
+
+To use this mouse as the PS/2 device and the OS supports automatic
+PS/2 mouse detection:
+<verb>
+ Option "Protocol" "Auto"
+</verb>
+
+<sect1>ASCII MieMouse (serial, PS/2) <p>
+This mouse appears to be OEM from Genius. Although its shape is
+quite different, it works like Genius NetMouse Pro. This mouse has a
+"knob" which is used like a wheel or a roller. The "knob" action is
+recognized as the Z axis motion.
+<p>
+MieMouse supports the PnP COM device specification. When used as a
+serial mouse, it is compatible with MS IntelliMouse.
+<p>
+To use this mouse as a serial device:
+<verb>
+ Option "Protocol" "Auto"
+</verb>
+or:
+<verb>
+ Option "Protocol" "IntelliMouse"
+</verb>
+
+To use this mouse as the PS/2 device and the OS supports PS/2 mouse
+initialization:
+<verb>
+ Option "Protocol" "NetMousePS/2"
+</verb>
+
+To use this mouse as the PS/2 device but the OS does not support PS/2 mouse
+initialization (the knob and the third button won't work):
+<verb>
+ Option "Protocol" "PS/2"
+</verb>
+
+To use this mouse as the PS/2 device and the OS supports automatic
+PS/2 mouse detection:
+<verb>
+ Option "Protocol" "Auto"
+</verb>
+
+<sect1>Logitech MouseMan+ and FirstMouse+ (serial, PS/2) <p>
+MouseMan+ has two buttons on top, one side button and a roller.
+FirstMouse+ has two buttons and a roller. The roller movement is
+recognized as the Z axis motion. The roller also acts as the third
+button. The side button is recognized as the fourth button.
+<p>
+MouseMan+ and FirstMouse+ support the PnP COM device specification.
+They have MS IntelliMouse compatible mode when used as a serial mouse.
+<p>
+To use these mice as a serial device:
+<verb>
+ Option "Protocol" "Auto"
+</verb>
+or:
+<verb>
+ Option "Protocol" "IntelliMouse"
+</verb>
+
+To use this mouse as the PS/2 device and the OS supports PS/2 mouse
+initialization:
+<verb>
+ Option "Protocol" "MouseManPlusPS/2"
+</verb>
+
+To use this mouse as the PS/2 device but the OS does not support PS/2 mouse
+initialization (the wheel and the fourth button won't work):
+<verb>
+ Option "Protocol" "PS/2"
+</verb>
+
+To use this mouse as the PS/2 device and the OS supports automatic
+PS/2 mouse detection:
+<verb>
+ Option "Protocol" "Auto"
+</verb>
+
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/neomagic.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/neomagic.sgml
new file mode 100644
index 000000000..6d3698e4e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/neomagic.sgml
@@ -0,0 +1,170 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+<title> Information for NeoMagic Users
+ NeoMagic Driver Version 2.0.0
+<author>The XFree86 Project Inc.
+<date>4 November 1998
+<toc>
+
+
+<sect> Supported hardware
+
+<p>
+<itemize>
+<item> NeoMagic 2200 (MagicMedia256AV)
+<item> NeoMagic 2160 (MagicGraph128XD)
+<item> NeoMagic 2097 (MagicGraph128ZV+)
+<item> NeoMagic 2093 (MagicGraph128ZV)
+<item> NeoMagic 2090 (MagicGraph128V)
+<item> NeoMagic 2070 (MagicGraph128)
+</itemize>
+
+<sect> Features
+<p>
+<itemize>
+<item> Full support for internal flat panels, external monitors, and
+ simultaneous internal/external displays.
+
+<item> Complete set of Panel Resolutions supported including stretch and
+ centering modes for running lower resolutions on fixed resolution
+ panels.
+
+<item> Support for depths of 8, 15, 16 and 24 bits per pixel.
+
+<item> Hardware Cursor support to reduce sprite flicker.
+
+<item> Hardware accelerated drawing engine for 8, 15 and 16 bit per
+ pixel modes.
+
+<item> Fully programmable clocks supported in external monitor only
+ mode.
+
+<item> Robust text mode restore for VT switching.
+</itemize>
+
+<sect> Technical Notes
+
+<p>
+<itemize>
+<item> Enable both internal "intern_disp" and external "extern_disp"
+ options to get simultaneous panel/CRT support.
+</itemize>
+
+<sect> Reported Working Laptops
+
+<p>
+<itemize>
+ <item> Acer Travelmate 7120T
+ <item> Acer Extensa 367, 367D & 710TE
+ <item> Actebis TN559Pro
+ <item> Asus P6300
+ <item> CTX EzBook 700 & 77X series
+ <item> Compaq Presario 1080, 1210, 1215, 1220, 1610, 1611, 1620, 1621 & 1640
+ <item> Dell Inspiron 3000 & 3200
+ <item> Dell Latitude CP, CPi, LM & XPi
+ <item> Digital VP HiNote 575, 703, 717 & 720
+ <item> FIC DESIGNote 5550
+ <item> Fujitsu LifeBook 420D & 656Tx
+ <item> Gateway 2000 Solo 2300XL, 2500LS & 5150
+ <item> Highscreen XD Advance II 21,1" TFT
+ <item> Hi-Grade Notino AS6000 pII/266Mhz
+ <item> Hitachi VisionBook Plus 5000
+ <item> HP Omnibook 800, 3000, 3100, 4100 & Sojourn
+ <item> IBM ThinkPad 380D, 380E, 380ED, 380XD, 385XD, 560X & 600
+ <item> LEO DESIGNote 5550
+ <item> Micron Transport XKE
+ <item> NEC Ready 330T
+ <item> NEC Versa 2780 MT, 5060X, 5080X, 6060 & 6230
+ <item> NEC MB12C/UV (mobio NX)
+ <item> OPTI Phoenix
+ <item> Panasonic CF_S21, CF-25 MKIII & CF-35
+ <item> Quantex H-1330
+ <item> Sceptre 4500
+ <item> SEH DESIGNote 5550
+ <item> Siemens Nixdorf Scenic 510
+ <item> Sony PCG-505, PCG-705, PCG-717, PCG-719 & PCG-731
+ <item> TI Extensa 660 CDT
+ <item> Toshiba Libretto 100CT
+ <item> Toshiba Protege SS3000
+ <item> UMAX 520T
+</itemize>
+
+<sect> Configuration
+
+<p>
+ The driver auto-detects all device info included memory size, so
+ use the following device section in your XF86Config file:
+<verb>
+ Section "Device"
+ Identifier "NeoMagic"
+ EndSection
+</verb>
+ or let xf86config or XF86Setup do this for you.
+
+ But if you have problems with auto-detection, you can specify:
+<verb>
+ VideoRam - in kilobytes
+ DacSpeed - in MHz
+ MemBase - physical address of the linear framebuffer
+ MMIOBase - physical address of the memory mapped IO registers
+</verb>
+
+<sect> Driver Options
+<p>
+<itemize>
+ <item>"linear" - linear framebuffer mode (default)
+ <item>"no_linear" - banked framebuffer mode
+ <item>"no_accel" - software rendering only
+ <item>"hw_cursor" - hardware cursor requested (default)
+ <item>"sw_cursor" - software cursor only
+ <item>"mmio" - use I/O space via memory map (default)
+ <item>"no_mmio" - use I/O space directly
+ <item>"intern_disp" - enable internal display (default)
+ <item>"extern_disp" - enable external display
+ <item>"no_stretch" - disable stretching of lower resolution modes on panel
+ <item>"lcd_center" - center lower resolution modes on panel
+</itemize>
+ NOTE: Stretching of panel image is on by default for lower panel
+ resolutions.
+
+ Options useful for special lcd mode setting (should not be needed):
+<itemize>
+ <item>"prog_lcd_mode_regs" - set special lcd mode registers (2070 default)
+ <item>"no_prog_lcd_mode_regs" - don't set lcd mode registers (non-2070 default)
+ <item>"prog_lcd_mode_stretch" - force lcd mode regs if stretching is enabled
+ <item>"no_prog_lcd_mode_stretch" - no lcd mode regs if stretching (default)
+</itemize>
+ Option for subnotebooks and other laptops with uncommon size panels:
+<itemize>
+ <item>"override_validate_mode" - disable LCD mode checking
+</itemize>
+
+ <bf>WARNING:</bf> Disabling mode checking will allow for invalid modes that
+ could damage your LCD.
+
+<sect> Known Limitations
+<p>
+<itemize>
+ <item> External monitor support on the NM2070.
+ <item> Banked, or no_linear mode on the NM2070.
+ <item> Horizontal centering for lower than panel resolution on NM2070.
+</itemize>
+
+<sect> Authors
+
+<p>
+ Jens Owen <it>jens@precisioninsight.com</it>
+ Kevin E. Martin <it>kevin@precisioninsight.com</it>
+
+ This driver was donated to The XFree86 Project by
+ Precision Insight, Inc.
+ Cedar Park, TX USA
+
+ <htmlurl name="http://www.precisioninsight.com"
+ url="http://www.precisioninsight.com">
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/neomagic.sgml,v 1.1 1999/08/23 06:59:39 dawes Exp $
+</verb>
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/rendition.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/rendition.sgml
new file mode 100644
index 000000000..230c010ac
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/rendition.sgml
@@ -0,0 +1,75 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+<title>Information for Rendition Users
+<author>The XFree86 Project Inc.
+<date>1 August 1999
+<toc>
+
+<sect>Supported hardware <p>
+All cards based on the V1000 or the V2x00 should be supported. The server
+was tested on a miroCRYSTAL VRX (V1000), Intergraph Intense-100 3D (V1000), Diamond Stealth II S220 (V2100), Hercules Thriller3D (V2200) and Innovision Warrior3D (V2200).
+
+<sect>Important notices <p>
+V1000 cards can only work as primary display card due to hardware limitations. <p>
+Some V1000-based video cards are known to lock up the computer if you have write-combine activated. Disabling it removes the problem. Look for settings in the motherboards BIOS and disable ALL settings that has to do with write-combine (usually called USWC or just WC for short). <p>
+The "chipset" option is now implemented and honored when used. Unfortunately some legacy-code in the driver is preventing it from working with any cards but the primary display card. <p>
+If you have problems with hardware cursor use the "sw_cursor" option to revert back to software cursor.
+
+<sect>Features <p>
+<itemize>
+<item>Unaccelerated
+<item>Hardware cursor
+<item>Supported color depths
+<itemize>
+<item>8 bits per pixel (256 pseudo colour)
+<item>15 bits per pixel (actually 16-bits with RGB-weight 555, 32768 colors)
+<item>16 bits per pixel (high colour, RGB-weight 565, 65536 colors)
+<item>32 bits per pixel (true colour, sparse 24bit, 16M colors)
+</itemize>
+</itemize>
+
+<sect>XF86Config Option <p>
+<descrip>
+<tag>Option "sw_cursor"</tag>
+Disables use of the hardware cursor.
+<tag>Option "overclock_mem"</tag>
+Run the memory at a higher clock. Useful on some cards with display glitches
+at higher resolutions. But adds the risk to damage the hardware. Use with
+caution.
+<tag>DacSpeed "MHz"</tag>
+Set custom ramdac limit. We have currently no way of knowing if the v2x00 chip is a v2100 (170MHz) or v2200 (203MHz and 230MHz) so we assume the lowest. Use this option to manually override the value.
+</descrip>
+
+<sect>News in this release <p>
+<itemize>
+<item>Hardware-cursor on V2x00 cards.
+</itemize>
+
+<sect>Major fixes in this release <p>
+<itemize>
+<item>Depth 15 works on V1000 cards.
+<item>Bandwidth limits are now included. Can be overridden with DacSpeed option.
+</itemize>
+
+<sect>Known problems in current driver<p>
+<itemize>
+<item>Displays with depth 15 ("-bpp 15" or "-bpp 16 -weight 555") has problems on V2x00 cards.
+<item>Switching from display to VC and back to display can lock up V2x00 cards.
+<item>When scrolling the virtual display on a V1000 card parts of the screen will become distorted. Problem disappears when you continue moving around. V2x00 does not exhibit this problem. Probably a bug in the driver rather than a limitation of the chip.
+<item>Option "chipset" is honored. Unfortunately the driver still has problems and will only work if the rendition card is the primary display card in the system.
+<item>If an incorrect mode was given, the server does not restore console to correct state.
+</itemize>
+
+<sect>Work in progress (not finished in time for release) <p>
+<itemize>
+<item>Acceleration for V1000 chipset. Some bugs to clear out.
+<item>Acceleration for V2100 and V2200 chipset. Not ready for general use.
+</itemize>
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/rendition.sgml,v 1.3 1999/08/28 10:43:34 dawes Exp $
+</verb>
+
+</article>
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/s3virge.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/s3virge.sgml
new file mode 100644
index 000000000..1687a31be
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/s3virge.sgml
@@ -0,0 +1,62 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN" [
+<!ENTITY % defs SYSTEM "defs.ent"> %defs;
+]>
+
+<article>
+<title> Information for S3 ViRGE Users
+<author>The XFree86 Project Inc.
+<date>10 Jul 1999
+
+<ident>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/s3virge.sgml,v 1.2 1999/07/10 12:17:25 dawes Exp $
+</ident>
+
+<toc>
+
+<sect> Supported hardware
+<p>
+The s3virge driver in XFree86 &relvers; supports the S3 ViRGE, ViRGE DX, GX, MX, MX+, and VX chipsets. A majority of testing is done on ViRGE DX chips, making them the most stable to date. This release has improved support for 24 bit color depths and resolves all the known issues with Netscape and other applications supporting 24 bit color.
+
+This driver is moderately stable, however please use caution with any new install. Please report any problems to
+<email>XFree86@Xfree86.org</email>
+using the appropriate bug report sheet.
+
+<sect>Features:
+<p>
+
+<itemize>
+<item>Fully accelerated support for S3 ViRGE family video adapters
+<item>uses linear frame buffer
+<item>supports resolutions up to 2048x2048
+<item>supports color depths of 8, 15, 16, 24.
+<item>full use of video card memory for acceleration caching when visible framebuffer leaves extra memory
+</itemize>
+
+<sect>Configuration:
+<p>
+
+The driver auto-detects RAM size, RAMDAC and ClockChip. Do not bother putting
+these in your "Device" section.
+
+<sect>Documentation:
+<p>
+
+The driver has several supported options which are documented in the s3virge man
+page. Please refer to it for additional details about XF86Config options.
+
+<sect>Support:
+<p>
+For support with XFree86 video drivers please refer to our web site at <url name="XFree86" url="http://www.XFree86.org">. The web page has a FAQ and bug reporting form available. For problems not addressed in the web page please contact our support email address <email>XFree86@Xfree86.org</email>
+
+<sect>Authors
+<p>
+
+<itemize>
+<item>Mark Vojkovich <email>mvojkovi@ucsd.edu</email>
+<item>Sebastien Marineau
+<item>Harald Koenig <email>koenig@tat.physik.uni-tuebingen.de</email>
+<item>Matt Grossman <email>mattg@oz.net</email>
+<item>Kevin Brosius <email>Cobra@compuserve.com</email>
+</itemize>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/trident.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/trident.sgml
new file mode 100644
index 000000000..32afbcc51
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/trident.sgml
@@ -0,0 +1,171 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+<article>
+
+<title> Information for Trident Chipset Users
+<author> The XFree86 Project, Inc.
+<date> June 25 1999
+<toc>
+
+<sect> Supported chipsets <p>
+The Trident driver has undergone some slight work for XFree86 3.3.3.
+Because of this work, all of the Trident SVGA chipsets, except
+the very first one, are supported by both the color and monochrome servers.
+<quote><bf>
+8800CS 8200LX
+8900B 8900C 8900CL/D 9000 9000i 9100B
+9200CXr 9320LCD 9400CXi 9420 9420DGi 9430DGi 9440AGi 9660XGi 9680
+ProVidia9682 ProVidia9685 Cyber9382 Cyber9385 Cyber9385-1 Cyber9388
+Cyber9397 Cyber9520 Cyber9525 3DImage975(PCI) 3DImage975(AGP)
+3DImage985(AGP) Blade3D CyberBlade
+</bf></quote>
+It must be noted that the 9000i chipset is treated as a 9000 by the server.
+Additionally the 9100B is treated
+as a Trident 8900CL. Therefore it is equivalent to putting
+`<tt>Chipset "tvga8900cl"</tt>' or
+`<tt>Chipset "tvga9000"</tt>' in the <tt>XF86Config</tt> file. Also,
+note that the 9000i, 9100B have not been tested with the server,
+but should work in this way according to the chipset documentation.
+
+<bf> NOTES: </bf>
+<itemize>
+<item> The chipset keyword changed in XFree86 v3.3.2 and now you
+no longer specify 'tgui96xx' as the generic keyword, but you actually
+specify your chip. i.e. Chipset 'tgui9685' will set a ProVidia9685 chip.
+<item> The Cyber9388/9397, 3DImage975 and 3DImage985 cards are fixed in
+XFree86 v3.3.3, these chipsets have some acceleration now too. This
+acceleration has been disabled by default for the Cyber9388/9397
+because there have been problems, but it can be re-enabled with the
+<tt>"accel"</tt> option (see below).
+<item> 24bpp is all drivers remains unaccelerated, this will change in
+a future version, although 32bpp acceleration is supported for all TGUI
+based chipset except the 9440 which doesn't have the capability.
+<item> 16bpp is now supported for the Cyber9320 chipset.
+<descrip>
+<tag>Option "nolinear"</tag>
+ Turn off linear mapping
+<tag>Option "linear"</tag>
+ Force linear mapping. Use this if you have a non-PCI card and
+ require 16bpp support. Note: ISA cards can only access up to
+ 16MB of memory, so be sure you have less than this or it could
+ cause a system hang.
+<tag>MemBase 0x???????</tag>
+ This option may be used to specify the start address of the linear
+ frame buffer. By default for VLBus/EISA cards it is at 60MB.
+ For the 8900CL/D, it is at 15MB.
+<tag>Option "no_mmio"</tag>
+ This option turns off Memory Mapped IO support. MMIO is enabled
+ by default when acceleration is enabled. Acceleration doesn't work
+ well when MMIO is disabled.
+<tag>Option "tgui_pci_read_on"</tag>
+ Turn on PCI burst read mode.
+<tag>Option "tgui_pci_write_on"</tag>
+ Turn on PCI burst write mode.
+<tag>Option "pci_burst_on"</tag>
+ Turn on PCI burst (read and write)
+<tag>Option "pci_burst_off"</tag>
+ Turn off PCI burst (read and write)
+ <p>NOTE: PCI burst modes are now OFF by default for TGUI9440 cards
+ because it often upsets its Graphics Accelerator. It can be
+ turned it back on as may improve performance.
+ PCI burst modes are ON by default for all other PCI/AGP cards.
+<tag>ClockChip "tgui"</tag>
+ Turn on programmable clocks. This is the default for TGUIs.
+<tag>Option "no_program_clocks"</tag>
+ Turn off programmable clock. Use fixed VGA clocks only.
+ Useful for fixed frequency monitors - usually used for VGA
+ monitors - not SVGA.
+<tag>Option "noaccel"</tag>
+ Turn off XAA acceleration.
+<tag>Option "accel"</tag>
+ Enable acceleration for the Cyber9388/9397.
+<tag>Option "xaa_no_color_exp"</tag>
+ Disable color expansion.
+<tag>Option "no_stretch"</tag>
+ Disable LCD stretching on Cyber 938x based chips.
+<tag>Option "lcd_center"</tag>
+ Enable LCD centering on Cyber 938x based chips.
+<tag>Option "cyber_shadow"</tag>
+ Enable Shadow registers, might be needed for some
+ Cyber chipsets. (laptop machines)
+<tag>Option "tgui_mclk_66"</tag>
+ Pushes the Memory Clock from its default value to 66MHz.
+ Increases graphics speed dramatically, but use entirely
+ at your own risk, as it may damage the video card.
+ If snow appears, disable. Only tested on the 9440.
+</descrip>
+</itemize>
+
+The original Trident chipset, 8800BR, cannot be supported as an SVGA chipset
+by either the color or monochrome servers. The chip is supported, however,
+by the ``generic'' driver for the monochrome server.
+
+<sect> Special considerations for 512k boards <p>
+There are no longer any special considerations for 512k Trident boards.
+The driver is now configured so that they can use modes with normal
+timings. The available pixel clocks are halved compared with those
+specified on the Clocks line
+
+Be aware that older Trident chipsets support a maximum clock of 65Mhz. Hence
+the best actual clock available to the color server is 32.5Mhz. This means,
+in broad terms, that the color server will require an interlaced mode to be
+defined for resolutions above 640x480. Newer chipsets (8900CL, 9000, 9000i,
+9100B, 9200CX and 9420) support up to 16 clocks, and can support much higher
+clocks, which will allow 800x600 modes, non-interlaced.
+
+<sect> Additional Notes <p>
+We have had reports of the server failing to detect the amount of installed
+memory and the correct dot-clocks on older TVGA8900 boards. If the server
+fails to detect the correct amount of memory, use the <tt>"Videoram"</tt>
+keyword in your <tt>XF86Config</tt> file to specify it.
+(e.g. <tt>Videoram 512</tt> or <tt>Videoram 1024</tt>). If
+the server has problems detecting the dot-clocks, try adding the following
+line to your <tt>XF86Config</tt> file:
+<verb>
+ Clocks 25 28 45 36 57 65 50 40
+</verb>
+This line gives the clock values provided by older Trident clock synthesizer
+chipsets. This also appears to be the standard first 8 clocks for the newer
+clock synthesizers, but you should have no problems on newer boards.
+
+Some newer Trident 8900B/C boards are apparently being built with the clock
+synthesizers used on the 9000 and 8900CL boards. If your board has a chip
+labeled "Trident TCK900x" ("x" has been seen as 2 or 4; there may be others),
+your board may actually have a 4th clock select bit. The 9002 has twelve
+distinct clocks (the other 4 are duplicates); the 9004 has 16 clocks (the
+same 12 as the 9002 + 4 others). If you see such a chip on a board with
+an 8900B or 8900C, put the following line in the Device section of your
+<tt>XF86Config</tt> file:
+<verb>
+ Option "16clocks"
+</verb>
+This will cause the same clock selection code as is used for the 8900CL to
+be used for the board.
+
+While developing the Trident driver, an interesting and perturbing hardware
+phenomenon was discovered. When using the default board jumper configuration,
+dot-clocks above 57Mhz would frequently lock up the machine. There appear
+to be jumpers on all of the Trident boards that determine whether the
+board will operate in zero-wait-state mode on the ISA bus. Disabling the
+zero-wait-state mode via jumpers cured the lockups, but at the expense
+of performance. Whether or not a given system will experience this problem
+is likely a combination of (a) bus speed, (b) video memory speed, and (c) dot
+clock speed. So be prepared for this phenomenon to occur, and have the board
+documentation handy.
+
+NOTE: VLBus cards are also subject to the above. By specifying the Clocks
+in the <tt>XF86Config</tt> file, these lockups are overcome. But it may
+be worth checking wait states etc. on the card and in the BIOS setup.
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/trident.sgml,v 3.24 1999/08/23 06:38:54 dawes Exp $
+
+
+
+
+
+
+$XConsortium: trident.sgml /main/11 1996/10/28 04:24:08 kaleb $
+</verb>
+
+</article>
+
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/tseng.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/tseng.sgml
new file mode 100644
index 000000000..9816cfbbb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/tseng.sgml
@@ -0,0 +1,1053 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+
+<article>
+
+<title> Information for Tseng Chipset Users
+<author> The XFree86 Project, Inc.
+Dirk H. Hohndel, Koen Gadeyne and others.
+<date> 03 Nov 1998
+<toc>
+
+<sect> Supported chipsets <p>
+
+The Tseng chipsets supported by XFree86 are ET3000, ET4000, ET4000/W32 and
+ET6000. Accelerated features of the ET4000/W32, W32i, W32p and ET6000 are
+supported by the SVGA driver. For details about the separate accelerated
+8bpp (=256 color) ET4000/W32 and ET6000 server, refer to
+<htmlurl name="README.W32" url="W32.html">.
+
+Note that you should NOT be using XF86_W32 unless XF86_SVGA doesn't work on
+your hardware. No further development is being done on the W32 server; all
+new efforts go into the SVGA server.
+
+Some ET4000W32 ISA cards are known NOT to work with the SVGA server in this
+version (XFree86 3.3.1): they hang the machine... Use the W32 server
+<tt>XF86_W32</tt> for these cards!
+
+<sect> Terminology <p>
+
+In the rest of this document, "8bpp" is short for "8 bits per pixel", which
+means a 256-color mode. Similarly, 15bpp refers to 32768 colors, 16bpp to
+65536 colors , 24bpp to a "packed" 16 million color mode, and 32bpp to a
+"sparse" 16 million color mode (at 32bpp, only 24 of the 32 bits are
+actually used, hence the "sparse").
+
+15bpp is only used here to differentiate it from 16bpp, but they are both
+normally referred to as 16bpp. 15bpp is actually 16bpp with a 5-5-5 color
+weight (wasting one bit per pixel), while 16bpp is, well, 16bpp, with 5-6-5
+color weight.
+
+<sect> ET4000 driver features <p>
+
+The SVGA driver for ET4000 chipsets supports all color depths (8, 15, 16, 24
+and 24 bpp) on most ET4000 chips starting with the ET4000W32i. The ET4000W32
+only supports 8bpp. Depending on the RAMDAC and the support code in the SVGA
+server, some cards may only support a few of these color depths, or even
+only 8bpp.
+
+On W32i and W32p chips all color depths are supported on the supported
+RAMDACs (currently ICS5341, STG170x and Chrontel CH8398). These modes are
+also accelerated.
+
+
+Some W32p board implementations are limited to 1 MB of video memory in
+linear memory modes. This is a hardware limitation that cannot be solved in
+the driver. Since XFree86 requires linear memory for 16/24/32 bpp modes, the
+usefulness of these cards for highcolor and truecolor applications is
+severely limited (those modes mostly use a lot of video memory).
+
+In addition, those cards also don't support acceleration in linear mode.
+This is a design choice in the driver code: if acceleration were to be
+supported in linear mode, you'd only be able to use 768 kb of video memory,
+and the driver code would be twice as complex.
+
+
+Cards with a RAMDAC that is not yet supported will be limited in a similar
+manner as the older cards, i.e. to a maximum pixel clock of 86 MHz, whilst
+they actually might be able to go up to 135 MHz. As a result, 1280x1024
+modes will only be possible when using interlacing, and non-interlaced modes
+are limited to about 1024x768 at 75 Hz refresh.
+
+For a non-interlaced 1280x1024x(256 colors) at say 135-MHz on a W32-type
+card, you need a w32p (with its 16-bit RAMDAC bus) with a multiplexing
+RAMDAC so that the w32p sees only (135/2 = 67.5) MHz, not 135 MHz. This
+requires special code only provided for cards using the ICS5341 GENDAC, the
+STG170x or the CH8398. This code seems to work fine for most people, except,
+with the ICS5341, for a small band of frequencies around 90MHz.
+
+
+Linear memory mode (especially important for some DGA clients, like
+xf86quake) is supported on all ET4000W32i and ET4000W32p cards, but not on
+the ET4000W32. See the section on linear memory for more information. There
+are some important issues related to linear memory.
+
+For the higher color depths (16, 24 and 32 bpp), linear memory mode is
+REQUIRED. It is enabled by default in these modes. There is no need to
+specify that in the <tt>XF86Config</tt> file. Please read the section on
+linear memory below: it contains some vital information on how to avoid
+serious problems.
+
+To force "banked" mode in 8bpp modes (where linear memory mode is the
+default), put the following in the Device section of your
+<tt>XF86Config</tt>:
+<verb>
+ Option "no_linear"
+</verb>
+
+Acceleration support is present, and enabled by default, for all W32 and
+ET6000 family chips. This is based on the new XFree86 acceleration interface
+(XAA).
+
+If you have problems with acceleration, acceleration can be disabled by
+putting the following in the Device section of your
+<tt>XF86Config</tt>:
+<verb>
+ Option "noaccel"
+</verb>
+
+On some PCI systems (i.e. only on the ET6000 and the ET4000W32p),
+acceleration may cause occasional font corruption. This is probably caused
+by a badly written system BIOS that ignores the fact that the Tseng PCI
+devices have their "non-prefetchable" attribute set. On such a BIOS, a PCI
+feature called "write combining" (or "byte merging") is enabled for the
+Tseng video card, although it is not permitted. Some systems allow you to
+manually enable or disable the Write Combining feature in the BIOS setup
+(sometimes abbreviated to WC). Make sure WC is disabled for the VGA memory
+aperture.
+
+If you experience font corruption on your system and are unable to manually
+disable WC in your BIOS, font acceleration may be disabled using the following
+in the Device section of your
+<tt>XF86Config</tt>:
+<verb>
+ Option "xaa_no_color_exp"
+</verb>
+
+Note that this will reduce the performance of the X server.
+
+<sect> ET6000 driver features <p>
+In addition to the features in the ET4000 driver, the SVGA ET6000 server
+supports all possible color depths in the SVGA server: 8bpp, 16bpp (both at
+5-5-5 and 5-6-5 color resolutions), 24bpp and 32 bpp.
+
+Linear memory mode (as opposed to the VGA default, banked memory layout) is
+supported. It is required and enabled by default for the 16/24/32 bpp modes.
+For 8bpp, the default is linear mode for PCI cards and banked mode for
+ISA/VLB cards.
+
+To force linear memory at 8bpp, put the following in the SVGA section of your
+<tt>XF86Config</tt>:
+<verb>
+ Option "linear"
+</verb>
+
+Acceleration is supported and is enabled by default, and accelerates all
+color depths on the ET6000. Acceleration can be disabled by adding the
+following in the Device section of your
+<tt>XF86Config</tt>:
+<verb>
+ Option "noaccel"
+</verb>
+
+The hardware cursor is supported in all color depths. Due to a hardware
+limitation in the ET6000, only a limited set of colors is supported (2
+significant bits per color component). This may cause some (small) cursor
+color errors. If absolute cursor color accuracy is required, the hardware
+cursor should not be enabled. However, in most applications, this will not
+be a problem. The hardware cursor can be enabled using
+<verb>
+ Option "hw_cursor"
+</verb>
+
+There is a problem with the hardware cursor at high dotclocks (above
+approx. 110MHz) at which point the cursor does strange things when partly off
+the left-hand side of the screen.
+
+On older ET6000 chip revisions, DoubleScan modes currently don't work with
+the hardware cursor: only the top half of the cursor is visible. If you want
+to use DoubleScan modes (320x200 is a popular one), then do not enable the
+hardware cursor. Most recent ET6000 cards and the ET6100 do not exhibit this
+problem.
+
+
+On some PCI systems, acceleration may cause occasional font corruption. As
+described above, this is caused by a bug in your system BIOS or a wrong
+setting of the write combining feature in that BIOS. If you are unable to
+fix the BIOS or force the option off, font acceleration may be disabled
+using the following in the Device section of your
+<tt>XF86Config</tt>:
+<verb>
+ Option "xaa_no_color_exp"
+</verb>
+
+When using accelerated high color-depths (24bpp and 32bpp), high-resolution
+modes (starting somewhere around 800x600) may cause temporary "garbage"
+lines to the right of the screen while the accelerator is busy. The garbage
+should not be persistent: it should go away as soon as the server is left
+alone. This is a memory bandwidth problem, and thus cannot be resolved
+(except by not allowing such modes at all, which is what is done in the
+current driver).
+
+Ignoring it is one option (it isn't destructive). Disabling acceleration in
+the Device section of the <tt>XF86Config</tt> file is another option: since
+the accelerator is not being used, there is ample bandwidth to avoid such
+problems.
+
+
+<sect> Clock selection problems with some ET4000 boards <p>
+XFree86 has some problems getting the clock selection right with some
+ET4000 boards when the server is started from a high-resolution text mode.
+The clock selection is always correct when the server is started from a
+standard 80x25 text mode.
+
+This problem is indicated when the reported clocks are different when the
+server is started from the high-resolution text mode from what they are
+when it is started from the 80x25 text mode. To allow the server to work
+correctly from the high-resolution text mode, there are some Option flags
+that may be set in <tt>XF86Config</tt>.
+To find out which flags to set, start the
+server with the -probeonly flag from an 80x25 text mode and look at the
+information printed by the server. If the line:
+<verb>
+ VGAXXX: ET4000: Initial hibit state: low
+</verb>
+is printed, put the following in the SVGA, VGA16 and VGA2 sections of your
+<tt>XF86Config</tt>:
+<verb>
+ Option "hibit_low"
+</verb>
+If the line:
+<verb>
+ VGAXXX: ET4000: Initial hibit state: high
+</verb>
+is printed, put the following in the SVGA, VGA16 and VGA2 sections of your
+<tt>XF86Config</tt>:
+<verb>
+ Option "hibit_high"
+</verb>
+
+<sect> Text mode restore problems <p>
+In XFree86 1.3, an option flag ``force_bits'' was provided as an experiment
+to attempt to alleviate text-restoration problems that some people experienced.
+We have now made the behavior of this option the default, hence the flag
+has been removed. Hopefully the past text-restoration problems are alleviated
+in XFree86 2.0.
+
+
+<sect> Basic configuration <p>
+
+It is recommended that you generate an XF86Config file using
+the <tt>XF86Setup</tt>' or <tt>xf86config</tt>' program, which should
+produce a working
+high-resolution 8bpp configuration. You may want to include mode
+timings in the <tt>Monitor</tt> section that better fit your monitor
+(e.g 1152x864 modes). The driver options are described in detail in
+the next section; here the basic options are hinted at.
+
+If graphics redrawing goes wrong on accelerated chips (ET4000W32 and
+ET6000), first try the <tt>"noaccel"</tt> option, which disables
+all accelerated functions.
+
+
+<sect> general options in the <tt>XF86Config</tt> file <p>
+
+The following options are of particular interest to the Tseng driver. Each
+of them must be specified in the <tt>svga</tt>' driver section of the
+<tt>XF86Config</tt>
+file, within the <tt>Screen</tt> subsections of the depths to which they are
+applicable (you can enable options for all depths by specifying them in the
+Device section).
+<descrip>
+<tag>Option "noaccel"</tag> (ET4000W32p, et6000)
+ This option will disable the use of any accelerated functions. This
+ is likely to help with some problems related to DRAM timing, high
+ dot clocks, and bugs in accelerated functions, at the cost of
+ performance (which will still be reasonable on a local or PCI bus).
+ This option applies only to those chips where acceleration is
+ supported.
+<tag>Option "fast_dram" "slow_dram" </tag>
+ These options set the DRAM speed of certain cards where it applies.
+
+ The <tt>"slow_dram"</tt> option is always enabled on ET4000, and
+ ET4000W32. If enabled, it slows down DRAM timing, which may avoid
+ some memory-related problems. If your card starts up with a black
+ screen (and possibly a system hang), this option might be needed.
+
+ The <tt>"fast_dram"</tt> option will cause the driver to speed up
+ DRAM timings, which may also avoid screen-related problems
+ (streaking, stripes, garbage, ...). It may also increase those very
+ same effects.
+
+ All in all, these are potentially dangerous options: they could
+ crash your machine as soon as you start the server. Use them with
+ caution.
+<tag>
+option "w32_interleave_off" "w32_interleave_on" (W32i, W32p)
+</tag>
+ Force memory interleaving off or on. W32i and W32p chips can
+ increase memory bandwidth when they have 2MB or more video memory.
+ Normally the VGA BIOS sets the W32i or W32p chip to the correct
+ mode. If you suspect problems with memory sizing or interleaving,
+ fooling around with these options may improve the situation. It may
+ also make things worse. These options are not normally needed: the
+ server will use the correct value automatically. Setting this option
+ the wrong way will result in a completely distorted display.
+<tag>
+option "pci_burst_off" "pci_burst_on" (W32p)
+</tag>
+ This option disables or enables PCI bursts on the W32p chip if it's
+ a PCI card. Normally, a good BIOS will set the motherboard and the
+ VGA card to the same setting, but if both don't match, you may
+ experience garbage on the screen (e.g. mouse droppings). These
+ options allow you to match the W32p burst setting to the motherboard
+ setting.
+<tag>
+videoram 1024 (or another value) (all chips)
+</tag>
+ This option will override the detected amount of video memory, and
+ pretend the given amount of memory is present on the card. This is
+ useful on cards with 2Mbyte of memory whose DRAM configuration is
+ not compatible with the way the driver enables the upper megabyte of
+ memory, or if the memory detection goes wrong. It must be specified
+ in the Device section.
+<tag>
+Clockchip "et6000" (et6000)
+</tag>
+ This enables programmable clocks, but obviously only on the et6000.
+ It must be specified in the Device section. Normally the server will
+ automatically use this feature when it detects an ET6000. Use it
+ only when you suspect auto-detection is not working. Note that some
+ frequencies may be unstable (resulting in a `Wavy' screen). Only
+ tried and tested frequencies (like the default clocks) are
+ guaranteed to be stable. If this happens, try a slightly different
+ frequency in the modeline (like 0.5 MHz more or less). The monitor
+ should still be capable of syncing to this frequency, but the
+ clockchip may already be outside an unstable region.
+<tag>
+Option "linear" (ET4000W32i, ET4000W32p, ET6000)
+</tag>
+ This enables linear addressing, which is the mapping of the entire
+ framebuffer to a high address beyond system memory, making the full
+ length of the framebuffer directly accessible. In this way, slow
+ SVGA bank switching (where only a small fraction of the framebuffer
+ is visible at one time) is not necessary. It enhances performance at
+ 256 colors, and is currently required for 16bpp, 24bpp, and 32bpp.
+<tag>
+MemBase 0xE0000000. (or a different address) (ET4000W32, ET6000)
+</tag>
+ This sets the physical memory base address of the linear
+ framebuffer. It must be specified in the Device section. It may be
+ required for non-PCI linear addressing configurations, and might be
+ useful for PCI-based systems where auto-detection fails. However,
+ almost all PCI systems will not need this.
+
+ Read the section on linear memory base address issues below!
+
+ Read the section on linear memory base address issues below!
+ (Message repeated for a very good reason)
+
+ Use this option ONLY if you have trouble with the default MemBase
+ used by the server, or if the server explicitly states that you must
+ provide one.
+<tag>
+Option "pci_retry" (ET4000W32p on PCI bus, ET6000)
+</tag>
+ This enables the PCI bus retry function, which is a performance
+ enhancing mode for local bus or PCI bus-based systems, where the VGA
+ controller will put the bus in a hold state (sort of like
+ wait-states) when the server tries to start a new accelerated
+ operation but the accelerator is still busy with the previous
+ operation.
+
+ This is the fastest way to drive a VGA card (no busy-waiting loops
+ needed), but it also stresses some hardware that is timing-dependent
+ (tape drives, sound cards, etc). See also the trouble shooting
+ section.
+</descrip>
+
+<sect> linear memory base address (MemBase) issues <p>
+
+First a WARNING: defining a bad MemBase may cause serious injury or death
+(to your operating system, of course). Especially defining the MemBase to be
+inside the range of system memory is a ticket to hell.
+
+<sect1>What you should know BEFORE trying another MemBase<p>
+Rule &num;1: first, let the server find a memory base by itself, without
+specifying it. Make sure you "sync" all files to disk and close all critical
+applications. Make sure nothing bad will happen to your filesystems if you
+have to jump for the power switch soon.
+
+The most critical cards are the ET4000W32p rev a and rev b on VESA local bus
+(VLB). The server will autodetect a linear base address that doesn't work on
+all systems.
+
+The least critical cards are PCI-bus cards. The PCI BIOS normally takes care
+of assigning a good MemBase, and you should never have to deal with all the
+mumbo-jumbo below.
+
+If the server gets it wrong, you may end up with a severe system crash (e.g.
+if it maps the video memory right on top of your system memory). If this
+happens, RESET IMMEDIATELY. Do not try to shut down cleanly, because the
+X-server, thinking it writes to the VGA memory, will write to system memory
+instead, and you'll be writing corrupted data to disk. If you did a sync
+prior to starting the server, there will be no harm done (only a filesystem
+check which should end up clean). DO NOT attempt to redirect the server
+output to a file on the system you're testing on (that will write data after
+you synced).
+
+These are worst-case scenarios, and it is very unlikely this will happen to
+you. The text above is to make sure you are properly prepared, so that
+nothing serious happens.
+
+When the server can't find a working linear memory base, it's time to
+experiment. The rest of this section deals with that.
+
+<sect1>Choosing a MemBase<p>
+Choosing a suitable MemBase can be quite tricky. If you have no way of
+determining the MemBase your card uses, trying to put it a few Mb above the
+system memory is a good first guess. E.g. if you have 16 Mb of RAM, defining
+MemBase 0x01000000 (=16M) or 0x01400000 (=20M) may work.
+
+However, this may only work on non-PCI systems, as PCI systems mostly map all
+hardware above the 2GB mark. But then again, on PCI systems the server is
+almost always able to detect the correct linear memory base address. The
+only exception are those systems with more than one PCI VGA card.
+
+On most VESA local bus (VLB) boards, there is an additional problem with
+address decoding. Most motherboards only decode the first 32, 64 or 128 MB
+of address space (a good pointer is to check the amount of DRAM that can be
+installed on the board: it will at least decode as much address space as it
+supports DRAM).
+
+On such boards, you MUST specify a MemBase inside that range, or the actual
+address may wrap back onto system memory: if your system only decodes 128MB
+of addresses, and you set the MemBase to 128 MB, it will actually be decoded
+as being on address 0, which is probably exactly where your kernel memory is
+located. That is why the general guideline of putting the MemBase just above
+the system memory is a sound one: it stands most chance of actually being
+inside the decoded address range of the board. Unless your motherboard's
+entire memory space is filled with RAM.
+
+<sect1>An alternative approach<p>
+If you don't know how much memory address space your motherboard decodes
+(and who does?), try using a "non-trivial" address, like 0x1FC00000, which
+has enough bits set to "1" to work on any motherboard, even if a few are not
+decoded. Keep in mind that using for example 0x10000000 may end up right on
+top of your system memory if the motherboard doesn't decode all upper
+address bits. You will only do that once.
+
+<sect1>When all else fails...<p>
+Some other VLB boards can only map the linear framebuffer above the 1GB mark
+(0x80000000 and up), so you must use a MemBase that is higher or equal to
+0x80000000.
+
+Some other VLB boards can only map the linear framebuffer BELOW the 16 MB
+mark. So you may want to try booting your system with up to 12 MB of memory
+(some operating systems allow you to supply a boot-time parameter that
+limits the memory to a certain amount, so you don't have to open your
+computer to try this), and set the MemBase to 0x00C00000 (=12M).
+
+Unfortunately, there is no easy way to tell what system you have (these
+details are mostly not in the motherboard manuals). Trial and error is the
+only road to success here. The server code will provide a default that works
+on most boards... but yours won't be one of those, of course.
+
+<sect1>Restrictions<p>
+There are some limits as to where the linear memory base may be put. On any
+ET4000W32, it must have a 4MB granularity (i.e. it can be put at 16M or at
+20M, but not at 18M). On ET6000, it needs a 16M granularity (note: the
+ET6000 driver should be able to determine the linear memory base
+automatically, so you should never need to define MemBase in the first
+place).
+
+On ET4000W32i, things are worse: the linear address base is hardwired on the
+card, and there is no reliable way to read it back from the card. You need
+to know the address in some way, and specify it. The current code does an
+intelligent guess at it, but this is no guarantee.
+
+On ISA cards, things are much more simple: ISA only uses 24 address lines,
+and hence the linear memory MUST lie within the 16 MB boundary. Together
+with the 4MB granularity of the linear memory base address on ET4000 cards,
+this means that you cannot have more than 12 MB of system memory in the
+machine if you want to use linear memory. Hence, the only realistic MemBase
+for ISA cards is 0x00C00000. This is also what the server will automatically
+choose if it detects an ISA W32 card.
+
+WARNING: you must not have over 12 MB of system memory in this case. Or if
+you have it, you must disable access to all memory above the 12 MB mark.
+Some operating systems allow you to specify at startup how much memory it is
+allowed to use, so you don't have to unplug some memory each time you want
+to use linear memory.
+
+<sect1>Some boards simply cannot work in linear mode<p>
+Yes, and in that case, you're out of luck.
+
+There can be at least two reasons for this.
+
+The first is the most common: the board manufacturer has left out the
+necessary connections and hardware to be able to use linear addressing. This
+means that no coding effort on this planet can help you with your problem:
+it is physically impossible to use linear addressing.
+
+The second reason is that the current XFree86 Tseng linear addressing code is
+incompatible with the way your board is designed. The XFree86 Tseng code
+assumes a 1:1 mapping of the address lines from the bus (either ISA, VLB or
+PCI) to the address lines on the Tseng VGA chip. As unlikely as it may
+sound, this may NOT be the case!
+
+Some very rare boards do not have such a 1:1 mapping (e.g. two address lines
+swapped). It is possible to support this type of hardware, but at this
+moment, this has not been implemented yet.
+
+Other boards use external address decoding hardware that combines a number
+of address lines on the bus to a (smaller) number of address lines to the
+VGA chip. One such board for example uses three NOR gates (one 74F02 chip)
+to combine the 6 upper address lines to three address pins on the W32i chip.
+Obviously, this represents a 2:1 mapping, and not a 1:1 mapping. Therefor,
+this board is not "compatible" with the way XFree86 implements linear mode.
+
+<sect1>How can I see if the linear address is wrong?<p>
+Simple: nothing works, or your machine locks solid, or it crashes, or a
+zillion of other things.
+
+However, sometimes it is not always as obvious. Sometimes nothing bad
+happens: you just get a black screen, or a screen with rubbish on it, but
+nothing is drawn on it. Sometimes you get a core dump when the first
+application starts.
+
+If acceleration is enabled in those cases, you will almost always see
+multiple "WAIT_ACL: timeout" messages in the server output. That is because
+the accelerator registers are also mapped in the linear memory, and if
+linear memory doesn't work, then also the accelerator doesn't work.
+
+NOTE however that a WAIT_ACL message doesn't necessarily mean the linear
+memory address is bad. There are a number of other reasons for this message
+as well. But if you never saw these messages at 8bpp banked, then there's a
+good chance you have a linear memory problem ("banked" is the opposite of
+"linear", and is the default mode when "option linear" is not in the
+XF86Config file).
+
+<sect> Mode issues <p>
+
+The accelerated driver on ET4000W32/W32i/W32p and ET6000 needs at least 1K
+bytes of scratch space in video memory. Consequently, if you want
+acceleration, a 1024x1024 virtual resolution should not be used with a
+1Mbyte card. This also means that a 1024x768 mode at 24bpp on a 2.25 MB
+ET6000 card cannot be accelerated, since you've used up all the memory for
+the display.
+
+The same thing goes for the ET6000 hardware cursor: it also requires 1kb of
+free video memory. If that memory is not available, the hardware cursor
+cannot be used.
+
+The use of a higher dot clock frequencies has a negative effect on the
+performance of graphics operations on non-et6000 cards (the effect is much
+less, or even non-existing, on ET6000 cards), especially BitBlt, when little
+video memory bandwidth is left for drawing. Memory bandwidth is the speed at
+which data can be pumped into the memory while the RAMDAC is pulling it out
+to display it on the screen.
+
+Higher dot-clocks (mostly related to higher resolutions) consume more
+bandwidth, so that less of it is left for drawing into the framebuffer. With
+a working accelerator, things become increasingly crammed, because modern
+accelerators can consume huge amounts of bandwidth (but they also give you
+high speeds in return). High color depths also need extra bandwidth.
+
+If you are short on memory bandwidth (see the separate section on this) and
+experience blitting slowness or screen "glitches", try using the lowest dot
+clock that is acceptable; for example, on a 14" or 15" screen 800x600 with
+high refresh (50 MHz dot clock) is not so bad, with a large virtual screen.
+
+Tseng chips are mostly known for their (very) good memory bandwidth, so you
+should only start to see problems in the higher regions.
+
+It does not make much sense performance-wise to use the highest clock (85
+MHz) for 1024x768 at 76 Hz on a 1 MB ET4000W32; the card will very slow,
+because there is almost no bandwidth left for drawing. A 75 MHz dot clock
+results in 70 Hz which should be acceptable. If you have a monitor that
+supports 1024x768 at 76 Hz with a 85 MHz dot clock, an 1MB card is a poor
+match anyway.
+
+The ET4000W32i and ET4000W32p have a special feature that almost doubles
+memory bandwidth (+70%) using "interleaving" between the two banks.
+Upgrading to 2MB is a real bonus on these cards. This is not true for W32
+cards or for ET6000 cards.
+
+<sect> Acceleration issues <p>
+
+The XFree Acceleration Architecture makes extensive use of the unused video
+memory on the VGA card. If there is not enough free video memory, some
+acceleration features will be disabled or crippled, resulting in less
+performance.
+
+To avoid this from happening, try to keep an absolute minimum of 16 kb of
+free memory, in addition to the 1kb already reserved by the accelerator.
+
+In practice, this small amount of memory should not be a problem. Most cards
+nowadays have 2 MB of video memory, and running 1280x1024 still leaves
+plenty of memory unused. Even a 1600x1200 desktop will leave over 170kb
+unused, which will then be used by the accelerator to enhance performance.
+
+Most 1MB cards cannot display modes larger than 1024x768 with a decent
+refresh rate, leaving 256kb unused.
+
+The order in which free memory is used to accelerate certain features is as
+follows.
+
+If no video memory is unused (i.e. all of it is used for display memory),
+no acceleration can be used at all -- not even a hardware cursor on the
+ET6000.
+
+If the hardware cursor is enabled (ET6000 only) and there's at least 1kb of
+free video memory, 1kb is used for that.
+
+If there is at least 1kb of free memory remaining after this, most
+acceleration features are enabled as well, reserving an extra 1kb of video
+memory.
+
+If there's still some free memory, some extra acceleration features are
+enabled. These require more free video memory, depending on the virtual
+screen width and the color depth (bpp). The server will print out how much
+memory it used if it could.
+
+If there's still some free video memory, it is used as a pixmap cache. This
+way, small patterns and images can be kept in the video memory so that they
+don't need to be transferred into the video memory each time they're needed.
+This is beneficial because transferring an image over the bus to the video
+memory takes a lot more time than letting the accelerator blit it from the
+pixmap cache to the display memory.
+
+<sect> ET6000 memory size facts and fiction <p>
+
+The ET6000 uses a special kind of video memory called MDRAM (multi-bank
+DRAM). It may have a non-power-of-two amount of MDRAM: 2.25 or even 4.50 MB.
+Especially 2.25 MB MDRAM is popular, since this can support 1024x768 at
+24bpp without needing 4MB of RAM.
+
+There are a few less intuitive problems with this.
+
+First of all, All memory above the 4 MB limit is a waste of money, because
+the ET6000 cannot use this memory for anything at all. There are boards with
+4.5 MB around, but that extra 0.5 MB is a waste. The ET6000 can only refresh
+4 MB of (M)DRAM (refresh register). It can only access 64 banks of 64KB in
+VGA mode (bank select register). All accelerated commands use a 22-bit
+address (=4MB) inside the video memory. You get the idea... There is no way
+for the ET6000 to use anything above the 4Mb limit.
+
+And Secondly (more importantly): you may not have 2.25 MB at all! There have
+been several reports about ET6000 cards that were sold with (supposedly)
+2.25 MB of MDRAM, but which turned out to be standard 2MB MDRAM cards.
+People have been having trouble with these all along, since sometimes the
+X-server used to detect this as 2.25 MB (or even 2.5 MB) due to internal
+chip design and also due to faulty BIOSs. This memory detection problem
+has been fixed now, and the server should detect the correct amount of memory.
+
+Do NOT define the amount of memory in the XF86Config yourself, unless you
+are absolutely sure about the amount.
+
+There is a simple way to determine the amount of MDRAM on your card beyond
+doubt.
+
+Look at the video card. There is one large chip with 204 pins on it, which
+is the ET6000. One socketed rectangular chip, mostly with a sticker on it,is
+the BIOS. The remaining big chips are (mostly) 2 or 4 other large square
+chips on it with the following markings:
+
+ MDRAM
+ MD9xy ("xy" is a two-digit number)
+ SJ-5-100 (this may differ, but it will have the same layout)
+
+and a nice logo next to all that with 4 diamonds and the name "MoSys"
+underneath.
+
+The "xy" number tells you how much MEGABITS there are in that one chip.
+
+The amount of RAM on the card is then:
+
+ ("xy" * number_of_MDRAM_chips) / 8 Mbytes
+
+On my board, there are two MD908 chips, which means I have
+
+ (08 * 2) / 8 = 2 MB of MDRAM.
+
+Boards with two MD909 chips have 2.25 MB, etc.
+
+Current MDRAM chips are MD904, MD906, MD908, MD909, MD910, MD916, MD918 and
+MD920.
+
+<sect> ET6000 memory bandwidth hype and the impact on video modes <p>
+
+Tseng has always had wet dreams about memory bandwidth, and their press
+announcements about the ET6000 memory bandwidth are no exception.
+
+They claim the ET6000 using MDRAM is capable of reaching an incredible 1.2
+Gbytes/sec of bandwidth. That would surpass just about everything on the
+market (even SGI).
+
+And that would be true, _if_ they actually used the fastest available MDRAMs
+on their boards, which they don't. The stunning 1.2 GByte mark is only
+reached when using 4 MDRAM chips at their max clock rate of 166 MHz. But due
+to design limitations, the first-generation ET6000 can only drive the
+memories at 92 MHz (that will change when the ET6100 and ET6300 hit the
+streets).
+
+This means the max. theoretical bandwidth available on current ET6000 boards is "only"
+360 MB/sec on boards with 2 MDRAM chips, and 720 MB/sec on boards with 4
+MDRAM chips. And this assumes a best-case situation (=extremely long bursts
+-- the MDRAMs use a shared address/data bus, much like the PCI bus does). In
+the real world, unaligned accesses both from the PCI bus and the accelerator
+will reduce the effective available bandwidth. The current ET6000 boards
+peak out at about 225 MB/sec, with 2 or 4 MDRAMs.
+
+Whatever you may have read in press releases, the ET6000 has a 32-bit memory
+bus (not 128 bits; that's only the accelerator data path within the chip, if
+anything). That means that, with their 16-bit busses, 2 MDRAM chips already
+use the full bus capacity. Having 4 memory chips on an ET6000 board will not
+give you extra memory bandwidth.
+
+Memory bandwidth limits the maximum resolution you can use at a given color
+depth. The ET6000 RAMDAC can cope with 135 MHz in any situation. But the RAM
+cannot. At 32bpp (sparse 16M color mode), using a 135 MHz pixel clock would
+require a memory bandwidth of 135*4 = 540 MB/sec, which the current ET6000
+boards simply cannot cope with. And then you still need some spare bandwidth
+for the PCI bus and the accelerator.
+
+That is why some modes will be refused, depending on your MDRAM memory
+layout, even if the amount of memory would permit such a mode. See also the
+trouble shooting section to see what can happen if too little memory
+bandwidth is available.
+
+<sect> Linear addressing and 16bpp/24bpp/32bpp modes <p>
+
+Currently the 16-bit (32768 or 65536 colors), 24-bit (16M colors, packed
+pixel), and 32-bit (16M colors, sparse) pixel support in the SVGA server
+requires linear addressing. This restriction may be removed in a future
+version, but with nearly all new cards using the PCI bus (where linear
+addressing poses no problem), removing the linear addressing requirement
+presently has a lower priority than other features. Option "linear" can be
+specified in a depth-specific screen section to enable linear addressing; a
+MemBase setting (in the device section) is probably also required on non-PCI
+based systems, and optionally on PCI systems that have trouble finding out
+for themselves where the MemBase is.
+
+Non-PCI cards are not (or not well) supported in linear memory mode at this
+moment. Some of them don't support it at all, and some of the ones that do
+have so many address decoding bugs that it isn't feasible to provide a
+working solution.
+
+For the most part, many of the accelerated features in the 8bpp server have
+been implemented to support 16, 24, and 32 bpp modes for the W32 and the
+ET6000. So although there are now up to 4 times as many bits to display, the
+X server shouldn't feel overly sluggish. Note also that the 24bpp and 32bpp
+modes are only supported on a limited set of cards, and with at least 2Mb of
+memory.
+
+An ET6000 with 2.25 MB MDRAM is cheap-and-sound, since it can support exactly
+1024x768 at 24bpp (using all available video memory). On all other video
+cards, you need at least 4MB of video memory to do this. With only 2MB of
+(M)DRAM, 960x720 is the best you can hope for.
+
+In the <tt>XF86Config</tt> <tt>"Screen"</tt> section, a
+<tt>"Display"</tt> subsection must be
+defined for each depth that you want to run, with separate Modes
+and virtual screen size. Example (2Mb of video memory):
+<tscreen><verb>
+Section "screen"
+ SubSection "Display"
+ Depth 8
+ Virtual 1280 1024
+ ViewPort 0 0
+ Modes "640x480" "800x600" "1024x768"
+ EndSubSection
+ SubSection "Display"
+ Depth 16
+ Virtual 1024 992
+ ViewPort 0 0
+ Modes "640x480" "800x600" "1024x768"
+ EndSubSection
+ SubSection "Display"
+ Depth 24
+ Virtual 960 720
+ ViewPort 0 0
+ Modes "640x480" "800x600"
+ EndSubSection
+ SubSection "Display"
+ Depth 32
+ Virtual 832 600
+ ViewPort 0 0
+ Modes "640x480" "800x600"
+ EndSubSection
+EndSection
+</verb></tscreen>
+
+<sect> Trouble shooting with the SVGA Tseng driver<p>
+First of all, make sure that the default modes selected from your
+<tt>XF86Config</tt>
+are supported by your monitor, i.e. make sure the horizontal sync limit is
+correct. It is best to start with standard 640x480x256 with a 25.175 MHz
+clock (by specifying a single horizontal sync of 31.5) to make sure the
+driver works on your configuration. The default mode used will always be
+the first mode listed in the modes line, with the highest dot clock listed
+for that resolution in the timing section.
+
+Some general hints:
+<itemize>
+<item>Put Option "slow_dram" in the Device Section.
+<item>Put Option "pci_burst_off" in the Device Section.
+<item>Put Option "w32_interleave_off" in the Device Section.
+<item>Take out the Hercules monochrome adapter, if you have one. Many
+ configurations of the ET4000/W32 series do not allow one in the
+ system.
+<item>Get a motherboard with its local bus running at 33 MHz. Many, if not
+ all, ET4000/W32 boards will surely behave in a funny way on a 50-MHz
+ bus. You may have to use a wait state or two, but first try without
+ any.
+<item>Cold-boot your machine. Do not run anything that messes with the
+ video hardware, including other X servers, before running
+ <tt>XF86_SVGA</tt>.
+<item>In case of an ET6000 card, try specifying chipset "et6000"
+ in the Device Section. The card normally auto-probes from the PCI bus,
+ but on some systems, another on-board VGA card, although disabled, may
+ cause the ET6000 server to want to use the other card.
+</itemize>
+
+
+Note that some VESA standard mode timings may give problems on some monitors
+(try increasing the horizontal sync pulse, i.e. the difference between
+the middle two horizontal timing values, or try multiples of 16 or 32 for
+all of the horizontal timing parameters).
+<descrip>
+<tag>There is a video signal, but the screen doesn't sync.</tag>
+ You are using a mode that your monitor cannot handle. If it is
+ a non-standard mode, maybe you need to tweak the timings a bit. If
+ it is a standard mode and frequency that your monitor should be able
+ to handle, try to find different timings for a similar mode and
+ frequency combination.
+
+<tag>Horizontal jitter at high dot clocks.</tag>
+ This problem shows up especially when drawing operations such as
+ scrolling or blitting are in progress. There is currently no easy
+ fix for this, You can try the <tt>"fast_dram"</tt> option, or use a
+ lower dot clock. If that is not sufficient, the <tt>"noaccel"</tt>
+ option will almost always help (it leaves more bandwidth for the
+ RAMDAC). In most cases, this is caused by the video memory not being
+ able to provide pixel data to the RAMDAC fast enough, so it gets fed
+ with garbage.
+
+<tag>`Wavy' screen.</tag>
+ Horizontal waving or jittering of the whole screen, continuously
+ (independent from drawing operations). You are probably using a dot
+ clock that is too high; it is also possible that there is
+ interference with a close MCLK. Try a lower dot clock (sometimes
+ even dropping it by 0.5 MHz may work). You can also try to tweak the
+ mode timings; try increasing the second horizontal value somewhat.
+ Here's a 65 MHz dot clock 1024x768 mode (about 60 Hz) that might
+ help:
+<verb>
+ "1024x768" 65 1024 1116 1228 1328 768 783 789 818
+</verb>
+<tag>Crash or hang after start-up (probably with a black screen).</tag>
+ Try the <tt>"noaccel"</tt> option. Check that the BIOS settings are
+ OK; in particular, disable caching of 0xa0000-0xaffff. Disabling
+ hidden DRAM refresh may also help.
+
+ On Linux systems, if "APM" (power management) support is enabled in
+ the kernel, the server may start up in power-save mode or with a
+ black screen. Rebuild your kernel with APM support disabled.
+<tag>
+Crash, hang, or trash on the screen after a graphics operation.
+</tag>
+ This may be related to a bug in one of the accelerated functions, or
+ a problem with the BitBLT engine. Try the <tt>"noaccel"</tt> option.
+ Also check the BIOS settings.
+<tag>
+`ACL: TIMEOUT' messages from the server.
+</tag>
+ Same as for the above entry. However, on some systems, the problem
+ will not go away no matter what you do. It may be related to the
+ operating system you use (it has only been seen on Linux systems,
+ and even then it depends on the kernel versions). Sometimes,
+ choosing another MemBase may help.
+<tag>
+Occasional erroneous pixels in text, pixel dust when moving window-frame
+</tag>
+ Probably related to MCLK setting that is too high (can happen with
+ linear addressing even though banked mode runs OK). Most (if not
+ all) ET6000 cards are sold with the MCLK slightly over clocked for
+ performance (the current norm is 90 or 92 MHz), which may cause
+ these problems. There is currently no fix for this. If the pixel
+ dust is only temporary (it disappears as soon as nothing moves on
+ the screen anymore), then memory bandwidth is probably the cause.
+ The only solution is to disable acceleration, or, if that doesn't
+ help, using a lower pixel clock.
+<tag>
+Textmode is not properly restored
+</tag>
+ This has been reported on some configurations. Sometimes a Chipset
+ line will fix this. Normally you should be able to restore the
+ textmode font using a utility that sets it (<tt>setfont</tt>,
+ <tt>runx</tt>, <tt>restorefont</tt> on Linux).
+<tag>
+Mostly black or blue screen when using accelerated driver features
+</tag>
+ If you are seeing a mostly black or blue screen, with only a few
+ icons (pixmaps) displayed, this section applies to you.
+
+ There can be several causes for this.
+
+ One is if the amount of memory is not detected (or specified) correctly. If the
+ server's autodetection mechanism detects too much memory,
+ accelerated features will not work. Define the amount of memory in
+ the <tt>XF86Config</tt> file. This seems to happen sometimes on some
+ 2.25 MB ET6000 cards, where the server detects 2.5 MB instead (add
+ <tt>videoram "2304"</tt> in this particular case).
+
+ If that doesn't help, disabling acceleration (option
+ <tt>"noaccel"</tt>) is the only solution.
+<tag>
+Problems with DMA hardware (floppy, tape)
+</tag>
+ On some systems, the accelerated server will interfere with other
+ hardware that uses ISA DMA. Most notably is the PC floppy controller
+ and sound cards. The floppy interface cannot cope with inordinately
+ long bus-holds, which may occur during large accelerated operations.
+ The Linux-ftape module for example (a floppy-tape driver) will
+ generate lots of "write error" messages when running a backup or
+ restore operation while the X-server is in use. These errors should
+ not be fatal, but that all depends on how well the operating system
+ handles these conditions. Linux seems to cope.
+
+ There are two possible solutions: disable acceleration using the
+ <tt>"noaccel"</tt> option, or disable PCI-retry (which is causing
+ the large bus delays) by removing the <tt>"pci_retry"</tt> option.
+ This will cause a very small slowdown of accelerated operations.
+
+ The <tt>"pci_retry"</tt> option applies not only to the PCI bus
+ systems, but has a similar effect on other busses.
+<tag>
+"Cannot read colourmap from VGA. Will restore with default"
+</tag>
+ If this error occurs, the server was unable to properly initialize
+ the RAMDAC, and tries to restore a default color map. On some
+ unsupported RAMDACs, this will have the adverse effect of removing
+ all color altogether, leaving you with a bunch of weird colors, or
+ with a completely black screen. If that happens, add the <tt>ramdac
+ "normal"</tt> statement to the Device section in your
+ <tt>XF86Config</tt> file. In most cases, this will solve the color
+ problem.
+<tag>
+Why does the server report my ModeLine with only half the pixel clock?
+</tag>
+ For ET4000W32p cards at 8bpp, some modes using a clock over 75 MHz
+ (e.g. a 1152x910 mode with 95 MHz pixel clock) will produce the
+ following message in the Xserver output:
+
+ (--) SVGA: Mode "1152x910" will use pixel multiplexing
+
+ And later, when the accepted modelines are reported:
+
+ (**) SVGA: Mode "1152x910": mode clock = 47.500
+
+ This is normal, because with pixel multiplexing, only half the clock
+ is needed as two pixels are sent to the RAMDAC per clock pulse.
+
+</descrip>
+For other screen drawing related problems, try the <tt>"noaccel"</tt>
+option.
+
+
+If you are having driver-related problems that are not addressed by this
+document, or if you have found bugs in accelerated functions, you can try
+contacting the XFree86 team.
+
+In fact, reports (success or failure) are very welcome, especially
+on configurations that have not been tested. You can do this
+via the BetaReport form (mail it to report@XFree86.org). You may want to
+keep an eye on forthcoming beta releases at <it>www.xfree86.org</it>.
+
+
+<sect> Acknowledgments <p>
+Most of these stem from the old XF86_W32 server. That code was used
+extensively for getting the SVGA server to work on all the Tseng cards, so
+they are still somewhat valid.
+
+Glenn G. Lai wrote the original XF86_W32 server. It was modified by
+Dirk Hohndel and Koen Gadeyne to support some more hardware.
+
+Jerry J. Shekhel (<it>jerry@msi.com</it>) gave me (GGL) the 1-M Mirage
+ET4000/W32 VLB board on which the initial development (X_W32) was done.
+
+X11R6 and The XFree86 Project provide the base code for XF86_W32.
+
+Hercules Computer Technology Inc. lent me (GGL) a 2-M Hercules Dynamite Pro VLB
+board for the development that led to <tt>XF86_W32</tt>. They donated a
+Dynamite Power PCI to The XFree86 Project, that was used by DHH to extend
+the server.
+
+Tseng Labs kindly donated (KMG) an ET6000-based board (a Jazz Multimedia
+G-Force 128), which spurred the development of the ET6000 code. They also
+provided an ET6100 evaluation board.
+
+Heiko Eissfeldt provided an ET4000W32p_rev_b board which allowed us to get
+better support for those rev_a and rev_b boards.
+
+Gyorgy Krajcsovits donated an ET4000W32p + CH8398 board. A Really Good Move!
+
+Numerous testers have given me feedback for <tt>X_W32</tt> and later
+<tt>XF86_W32</tt>. I
+apologize for my failure to keep track of the people who tested
+<tt>X_W32</tt>, but
+the names of the people involved with the <tt>XF86_W32</tt> testing are
+listed below:
+<descrip>
+<tag>Linux:</tag>
+<it>bf11620@coewl.cen.uiuc.edu</it> (Byron Thomas Faber) <newline>
+<it>dlj0@chern.math.lehigh.edu</it> (David Johnson) <newline>
+<it>peterc@a3.ph.man.ac.uk</it> (Peter Chang) <newline>
+<it>dmm0t@rincewind.mech.virginia.edu</it> (David Meyer) <newline>
+<it>nrh@philabs.Philips.COM</it> (Nikolaus R. Haus) <newline>
+<it>jdooley@dbp.caltech.edu</it> (James Dooley) <newline>
+<it>thumper@hitchcock.eng.uiowa.edu</it> (Timothy Paul Schlie) <newline>
+<it>klatta@pkdla5.syntex.com</it> (Ken Latta) <newline>
+<it>robinson@cnj.digex.net</it> (Andrew Robinson) <newline>
+<it>reggie@phys.washington.edu</it> (Reginald S. Perry) <newline>
+<it>sjm@cs.tut.fi</it> (M{kinen Sami J) <newline>
+<it>engel@yacc.central.de</it> (C. Engelmann) <bf>use</bf>
+ <it>cengelm@gwdg.de</it> <newline>
+<it>postgate@cafe.net</it> (Richard Postgate) <newline>
+<it>are1@cec.wustl.edu</it> (Andy Ellsworth) <newline>
+<it>bill@celtech.com</it> (Bill Foster)
+<tag> FreeBSD: </tag>
+<it>ljo@ljo-slip.DIALIN.CWRU.Edu</it> (L Jonas Olsson)
+</descrip>
+
+Several people have developed code for the SVGA Tseng driver (this list is
+incomplete):
+<itemize>
+<item>Glenn G. Lai
+<item>Dirk H. Hohndel
+<item>Koen Gadeyne
+<item>OEyvind Aabling
+<item>Dejan Ilic
+<item>Mark Vojkovich
+<item>Harald Nordgard Hansen
+<item>David Bateman
+<item>Gyorgy Krajcsovits
+<item>Kurt Olsen
+</itemize>
+
+
+
+
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/tseng.sgml,v 3.32 1999/08/23 06:38:54 dawes Exp $
+
+
+
+
+
+$XConsortium: tseng.sgml /main/6 1996/10/27 11:06:09 kaleb $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/xinput.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/xinput.sgml
new file mode 100644
index 000000000..60805f930
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/xinput.sgml
@@ -0,0 +1,209 @@
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+<article>
+
+<!-- made up title -->
+<title> Information about the XInput extension in XFree86&tm;
+<author> Fr&eacute;d&eacute;ric Lepied
+<date> 2 November 1998
+<toc>
+
+<sect> Introduction <p>
+
+This document provides some information about the XInput extension
+implemented in XFree86&tm;.
+
+If you have any suggestions, comments, fixes or ideas regarding the
+XInput extension in XFree86&tm; or about this document, send e-mail to
+
+<htmlurl url="mailto:lepied@XFree86.Org"
+ name="lepied@XFree86.Org"><p>
+Bug Reports should be sent to<p>
+<em>XFree86@XFree86.Org</em><p>
+Questions or anything else should be posted to the NewsGroup<p>
+<em>comp.windows.x.i386unix</em><p>
+
+<sect> Description <p>
+
+The XInput extension is a standard X Consortium extension. The goal of
+this extension is to allow additional input devices management to the
+X Window System. The documentation could be found in the X Consortium
+distribution under <em>xc/doc/hardcopy/Xi</em>.
+
+<sect> XFree86 implementation <p>
+
+The XFree86 implementation contains 2 parts : the server part and two
+clients (<em>xsetpointer</em> and <em>xsetmode</em>).
+
+<sect1> Server side <p>
+
+The server supports the following extended devices :
+<itemize>
+ <item>Joystick (only on supported systems ie. Linux, FreeBSD
+ and NetBSD). Features :
+ <itemize>
+ <item>Relative mode.
+ <item>2 valuators (x and y axis).
+ <item>2 buttons.
+ </itemize>
+
+ <item>Elographics touchscreen. Features :
+ <itemize>
+ <item>Absolute mode.
+ <item>2 valuators (x and y axis).
+ <item>1 button.
+ </itemize>
+
+ <item>Stylus on MicroTouch touchscreen. Features :
+ <itemize>
+ <item>Absolute mode.
+ <item>2 valuators (x and y axis).
+ <item>1 button.
+ </itemize>
+
+ <item>Finger on MicroTouch touchscreen. Features :
+ <itemize>
+ <item>Absolute mode.
+ <item>2 valuators (x and y axis).
+ <item>1 button.
+ </itemize>
+
+ <item>Mouse. Features :
+ <itemize>
+ <item>Relative mode.
+ <item>2 valuators (x and y axis).
+ <item>up to 4 buttons.
+ </itemize>
+
+ <item>Wacom stylus. Features :
+ <itemize>
+ <item>Absolute or relative modes.
+ <item>6 valuators :
+ <enum>
+ <item>X axis.
+ <item>Y axis.
+ <item>pressure.
+ <item>X tilt.
+ <item>Y tilt.
+ <item>wheel.
+ </enum>
+ <item>3 buttons.
+ <item>Proximity report.
+ <item>Motion history capability.
+ <item>Macro/function buttons are reported as keys.
+ </itemize>
+
+ <item>Wacom eraser. Features :
+ <itemize>
+ <item>Absolute or relative modes.
+ <item>6 valuators :
+ <enum>
+ <item>X axis.
+ <item>Y axis.
+ <item>pressure.
+ <item>X tilt.
+ <item>Y tilt.
+ <item>wheel.
+ </enum>
+ <item>1 button.
+ <item>Proximity report.
+ <item>Motion history capability.
+ <item>Macro/function buttons are reported as keys.
+ </itemize>
+
+ <item>Wacom cursor. Features :
+ <itemize>
+ <item>Absolute or relative modes.
+ <item>6 valuators :
+ <enum>
+ <item>X axis.
+ <item>Y axis.
+ <item>pressure.
+ <item>X tilt.
+ <item>Y tilt.
+ <item>wheel.
+ </enum>
+ <item>16 buttons.
+ <item>Proximity report.
+ <item>Motion history capability.
+ <item>Macro/function buttons are reported as keys.
+ </itemize>
+
+ <item>SummaSketch tablet. Features :
+ <itemize>
+ <item>Absolute or relative modes.
+ <item>2 valuators (x and y axis).
+ <item>2 buttons stylus or 4 buttons puck.
+ <item>Proximity report.
+ <item>Motion history capability.
+ </itemize>
+
+ <item>AceCad tablet. Features :
+ <itemize>
+ <item>Absolute or relative modes.
+ <item>2 valuators (x and y axis).
+ <item>2 buttons stylus or 4 buttons puck.
+ <item>Proximity report.
+ <item>Motion history capability.
+ </itemize>
+
+ <item>Calcomp DrawingBoard tablet. Features :
+ <itemize>
+ <item>Absolute or relative modes.
+ <item>2 valuators (x and y axis).
+ <item>4 buttons stylus or 16 buttons puck.
+ <item>Proximity report.
+ <item>Motion history capability.
+ </itemize>
+
+ <item>SWITCH virtual device. Features :
+ <itemize>
+ <item>Absolute mode.
+ <item>1 valuator (device id) which reports the id of the device controlling
+ the core pointer (works with the AlwaysCore feature see bellow).
+ </itemize>
+
+ <item>SGI button box. Features :
+ <itemize>
+ <item>Absolute or relative modes.
+ <item>8 valuators.
+ <item>32 buttons.
+ <item>Motion history capability.
+ </itemize>
+
+</itemize>
+
+To enable an extended device, you must add en entry in the
+<em>XF86Config</em> file. Consult to the <em>XF86Config</em> man
+pages to see the details. <p>
+
+The XFree86 implementation supports a non standard feature called
+<em>AlwaysCore</em> which enables an XInput device to send both core
+and extended events at the same time. To enable it you have to add the
+<em>AlwaysCore</em> keyword to the subsection describing your device
+in the <em>XF86Config</em> file. The <em>SWITCH</em> virtual device
+reports a Motion event when another device takes over the control of
+the core pointer. The id of the new device is reported in the first
+valuator of the event.
+
+<sect1> Clients <p>
+
+<em>xsetpointer</em> is used to change the device controlling the core
+pointer and to list available extended devices. <p>
+
+<em>xsetmode</em> is used to change the mode (absolute or relative) of
+an extended device. The device has to support relative and absolute
+modes and the device must not control the core pointer. <p>
+
+Consult the man pages for details.
+
+
+<verb>
+$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/xinput.sgml,v 3.7 1999/08/23 06:38:55 dawes Exp $
+
+
+
+
+$XConsortium: xinput.sgml /main/3 1996/10/27 11:06:13 kaleb $
+</verb>
+
+</article>
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/Imakefile
new file mode 100644
index 000000000..e15b1a895
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/Imakefile
@@ -0,0 +1,54 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/Imakefile,v 1.13 1999/08/29 12:20:57 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+#define IHaveSubdirs
+
+SUBDIRS = XF86CardDrivers
+DRIVERS = XF86CardDrivers
+
+#ifndef OS2Architecture
+OBJS = `cat driver.list`
+#else
+OBJS = al2101/?*.o mx/?*.o oak/?*.o realtek/?*.o sis/?*.o trident/?*.o \
+ ali/?*.o apm/?*.o apollo/?*.o ark/?*.o ati/?*.o chips/?*.o \
+ cirrus/?*.o cl64xx/?*.o compaq/?*.o et3000/?*.o glint/?*.o \
+ gvga/?*.o hercules/?*.o hgc1280/?*.o mga/?*.o ncr/?*.o \
+ nv/?*.o s3_pio/?*.o s3_newmmio/?*.o sigma/?*.o tseng/?*.o \
+ vga/?*.o video7/?*.o wd/?*.o i740/?*.o
+
+#endif
+
+#if DoLoadableServer
+MakeSubdirs($(SUBDIRS))
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+DONES = $(SUBDIRS:%=%/DONE)
+#if HasGnuMake || HasBsdMake
+$(DONES): $(SUBDIRS)
+#endif
+#if !DoLoadableServer
+NormalDepLibraryTarget(driver,$(SUBDIRS) $(DONES) driver.list,$(OBJS))
+#endif
+#else
+#if !DoLoadableServer
+NormalDepLibraryTarget(driver,$(SUBDIRS) driver.list,$(OBJS))
+#endif
+#endif
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC)
+#if !DoLoadableServer
+ConfigTargetNoDepend(drvConf,$(ICONFIGFILES),confdrv.SHsuf,$(DRIVERS))
+DriverObjectList($(DRIVERS),driver.list)
+#endif
+
+NormalLibraryObjectRule()
+
+ForceSubdirs($(SUBDIRS))
+
+DependSubdirs($(SUBDIRS))
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers)
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/apm/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/apm/Imakefile
new file mode 100644
index 000000000..835ef4c03
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/apm/Imakefile
@@ -0,0 +1,46 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/apm/Imakefile,v 1.12 1999/08/28 09:00:56 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = apm_accel.c apm_cursor.c apm_dga.c apm_driver.c apm_i2c.c apm_rush.c
+
+OBJS = apm_accel.o apm_cursor.o apm_dga.o apm_driver.o apm_i2c.o apm_rush.o
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \
+ -I$(XF86SRC)/xf1bpp -I$(XF86SRC)/xf4bpp \
+ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \
+ -I$(XF86SRC)/i2c -I$(XF86SRC)/ddc \
+ -I$(SERVERSRC)/Xext -I$(EXTINCSRC) \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(FONTINCSRC)
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget(apm,$(OBJS))
+
+InstallObjectModule(apm,$(MODULEDIR),drivers)
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/apm)
+InstallDriverSDKNonExecFile(apm.h,$(DRIVERSDKDIR)/drivers/apm)
+InstallDriverSDKNonExecFile(apm_regs.h,$(DRIVERSDKDIR)/drivers/apm)
+InstallDriverSDKNonExecFile(apm_accel.c,$(DRIVERSDKDIR)/drivers/apm)
+InstallDriverSDKNonExecFile(apm_cursor.c,$(DRIVERSDKDIR)/drivers/apm)
+InstallDriverSDKNonExecFile(apm_dga.c,$(DRIVERSDKDIR)/drivers/apm)
+InstallDriverSDKNonExecFile(apm_driver.c,$(DRIVERSDKDIR)/drivers/apm)
+InstallDriverSDKNonExecFile(apm_i2c.c,$(DRIVERSDKDIR)/drivers/apm)
+InstallDriverSDKNonExecFile(apm_funcs.c,$(DRIVERSDKDIR)/drivers/apm)
+InstallDriverSDKNonExecFile(apm_rush.c,$(DRIVERSDKDIR)/drivers/apm)
+
+InstallDriverSDKObjectModule(apm,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/apm/README b/xc/programs/Xserver/hw/xfree86/drivers/apm/README
new file mode 100644
index 000000000..f9fc9d019
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/apm/README
@@ -0,0 +1,109 @@
+$XFree86: xc/programs/Xserver/hw/xfree86/drivers/apm/README,v 1.3 1999/08/28 09:00:57 dawes Exp $
+
+Note 1: This driver is work in progress. It might not work at all.
+Want to help? Docs are at
+ftp://beta.xfree86.org/pub/xf86/devel/Documentation/apm
+
+Note 2: The driver has preliminary, completely untested support for
+dynamic loading. Use static loading to build a useable (?) server.
+
+
+This is the Alliance Promotion driver for XFree86 4.0+. It currently
+only supports the AT3D and AT25 chipsets (found on various Voodoo-
+Rush cards). There is preliminary, uncomplete and untested support for the
+6422 and AT24. The 6422 and AT24 chips are supported in the XFree86
+3.3.x series.
+
+What has worked on my computer :
+ - XAA for 8/16/32 bpp
+ - unaccelerated 24bpp
+ - DGA (DGA2 untested)
+ - DPMS
+ - glide2x
+
+What has not worked :
+ - I2C (I'm not sure my card, Hercules 128/3D, has proper cabling)
+ - 8x8 mono expand fill rectangles. Maybe a bug in the chip, I don't
+ understand
+
+What is untested :
+ - module
+ - shadow framebuffer
+
+What should be done :
+ - acceleration for 24bpp
+ - overlays (with the video engine, everything should be overlayable
+ with everything)
+ - AP6422, AT24 (and why not 3210) support
+
+
+ Loïc Grenié
+
+Authors:
+-----------------------------------------------------------------------
+Kent Hamilton Initial creation.
+Henrik Harmsen Lots of additions and fixes. <hch@cd.chalmers.se>
+Loic Grenie Conversion to 4.0. <grenie@lami.univ-evry.fr>
+
+
+History:
+-----------------------------------------------------------------------
+Created by Kent Hamilton for Xfree86 from source from Alliance
+
+Modified 1997-06 by Henrik Harmsen
+ - Added support for AT3D
+ - Acceleration added for 8,16,32bpp: (for AT3D and AT24)
+ - Filled rectangles
+ - Screen-screen bitblts
+ - Host-screen color expansion bitblts for text
+ - DPMS support
+ - Enabled hardware cursor code (also in 8bpp)
+ - Set to programmable VCLK clock
+ - Set MCLK to 57.3 MHz on AT3D.
+ - Various bugfixes and cleanups
+
+Modified 1997-07-06 by Henrik Harmsen
+ - Fixed bug that made the HW cursor screw up on VT switches
+ - Probably fixed bug that screwed up the screen when using
+ screen-screen bitblts. This forced me to put an ApmSync() at
+ the end of ApmSubsequentScreenToScreenCopy() which makes
+ me unhappy... But: Better it works than not...
+
+Modified 1997-10-19 by Henrik Harmsen
+ - HW line drawing.
+ - HW clipping.
+ - Added support for ROP's.
+ - Text acceleration now lots faster and support for accelerated
+ proportional text. (Uses SCANLINE_PAD_DWORD + clipping).
+ - Combined write for many register writes gives good
+ general speedup. (write x+y as a single 32 bit entity, rather
+ obvious, really...:-)
+ - Now waits for correct number of free slots in FIFO before
+ issuing writes to the card.
+ This seems to have eliminated the last instances of dropped
+ interrupts from serial IO and no more lost packets in PPP :-)
+ - Converted cursor support to use XAA interface.
+ - Fixed ApmSync(). Finally removed call to ApmSync at end of
+ ApmSubsequentScreenToScreenCopy() :-)
+
+Modified 1998-03-29 by Henrik Harmsen
+ - Added DGA support.
+ - Added accel support for AP6422. Fixed AT24 accel support.
+ - Fixed clock register calculation for AP6422 and AT24.
+ - DPMS support for AT24 & AP6422.
+ - 2% faster text accel for AT24/AT3D :-)
+
+Modified 1998-12-18 by Loic Grenie
+ - Converted to Xfree86 4.0 driver interface. (Only support for
+ AT25/AT3D chips).
+
+Modified 1999-03-14 by Henrik Harmsen
+ - Various fixes to bring it up to 3.9Pd.
+ - Added preliminary (completely untested) support for dynamic
+ loading.
+
+Modified 1999-07-07 by Loïc Grenié
+ - Converted to new RAC. Support for DGA and DGA2, I2C, Rush extension.
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/apm/apm.h b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm.h
new file mode 100644
index 000000000..213fd9da1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm.h
@@ -0,0 +1,210 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/apm/apm.h,v 1.7 1999/08/28 09:00:57 dawes Exp $ */
+
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.h"
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+/* All drivers need this */
+#include "xf86_ansic.h"
+
+/* This is used for module versioning */
+#include "xf86Version.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* All drivers using the vgahw module need this */
+#include "vgaHW.h"
+
+/* Drivers using the mi banking wrapper need this */
+#include "mibank.h"
+
+/* All drivers using the mi colormap manipulation need this */
+#include "micmap.h"
+
+/* Needed for the 1 and 4 bpp framebuffers */
+#include "xf1bpp.h"
+#include "xf4bpp.h"
+
+/* Drivers using cfb need this */
+
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+
+/* Drivers supporting bpp 16, 24 or 32 with cfb need these */
+
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+
+/* Drivers using the XAA interface ... */
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xf86Cursor.h"
+#include "xf86fbman.h"
+
+/* All drivers initialising the SW cursor need this */
+#include "mipointer.h"
+
+/* All drivers implementing backing store need this */
+#include "mibstore.h"
+
+/* I2C support */
+#include "xf86i2c.h"
+
+/* DDC support */
+#include "xf86DDC.h"
+
+#ifdef TRUE
+#undef TRUE
+#endif
+#define TRUE (1)
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned long u32;
+
+#define NoSEQRegs 0x20
+#define NoCRTRegs 0x1F
+#define NoGRCRegs 0x09
+#define NoATCRegs 0x15
+
+enum {
+ XR80, XRC0, XRD0, XRE0, XRE8, XREC, XR140, XR144, XR148, XR14C, NoEXRegs
+};
+
+#if 0
+static unsigned short XR_addr[NoEXRegs] = {
+ 0x80, 0xC0, 0xD0, 0xE0, 0xE8, 0xEC, 0x140, 0x144, 0x148, 0x14C
+};
+#endif
+
+typedef struct {
+ unsigned char MISC;
+ unsigned char FCTRL;
+ unsigned char SEQ[NoSEQRegs];
+ unsigned char CRT[NoCRTRegs];
+ unsigned char GRC[NoGRCRegs];
+ unsigned char ATC[NoATCRegs];
+ unsigned int EX[NoEXRegs];
+} ApmRegStr, *ApmRegPtr;
+
+#define APM_CACHE_NUMBER 32
+
+typedef struct {
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ int scrnIndex;
+ int Chipset;
+ int ChipRev;
+ CARD32 LinAddress;
+ unsigned long LinMapSize;
+ CARD32 FbMapSize;
+ pointer LinMap;
+ pointer FbBase;
+ char *VGAMap;
+ char *MemMap;
+ pointer BltMap;
+ Bool UnlockCalled;
+ int xbase;
+ unsigned char savedSR10;
+ unsigned char d9, db;
+ unsigned long saveCmd;
+ pointer FontInfo;
+ Bool hwCursor;
+ Bool noLinear;
+ ApmRegStr ModeReg, SavedReg;
+ CloseScreenProcPtr CloseScreen;
+ Bool UsePCIRetry; /* Do we use PCI-retry or busy-waiting */
+ Bool NoAccel; /* Do we use XAA acceleration architecture */
+ int MinClock; /* Min ramdac clock */
+ int MaxClock; /* Max ramdac clock */
+ int apmMMIO_Init;
+ EntityInfoPtr pEnt;
+ XAAInfoRecPtr AccelInfoRec;
+ xf86CursorInfoPtr CursorInfoRec;
+ int DGAactive, numDGAModes;
+ DGAModePtr DGAModes;
+ int BaseCursorAddress,CursorAddress,DisplayedCursorAddress;
+ int OffscreenReserved;
+ unsigned int Setup_DEC;
+ int blitxdir, blitydir;
+ Bool apmTransparency, apmClip, ShadowFB, I2C;
+ I2CBusPtr I2CPtr;
+ struct ApmStippleCacheRec {
+ XAACacheInfoRec apmStippleCache;
+ FBAreaPtr area;
+ int apmStippleCached:1;
+ } apmCache[APM_CACHE_NUMBER];
+ int apmCachePtr;
+ unsigned char regcurr[0x54];
+ ScreenPtr pScreen;
+ int displayWidth, displayHeight;
+ int bitsPerPixel, bytesPerScanline;
+ int Scanlines;
+ int Generation;
+ int apmLock;
+ RegionRec apmLockedRegion;
+ int MemClk;
+ unsigned char *ShadowPtr;
+ int ShadowPitch;
+ int ScratchMem, ScratchMemSize, ScratchMemOffset;
+ int ScratchMemWidth;
+} ApmRec, *ApmPtr;
+
+#define curr ((unsigned char *)pApm->regcurr)
+
+typedef struct {
+ u16 ca;
+ u8 font;
+ u8 pad;
+} ApmFontBuf;
+
+typedef struct {
+ u16 ca;
+ u8 font;
+ u8 pad;
+ u16 ca2;
+ u8 font2;
+ u8 pad2;
+} ApmTextBuf;
+
+enum ApmChipId {
+ AP6422 = 0x6422,
+ AT24 = 0x6424,
+ AT3D = 0x643D
+};
+
+typedef struct {
+ BoxRec box;
+ MoveAreaCallbackProcPtr MoveAreaCallback;
+ RemoveAreaCallbackProcPtr RemoveAreaCallback;
+ void *devPriv;
+} ApmPixmapRec, *ApmPixmapPtr;
+
+#define APMDECL(p) ApmPtr pApm = ((ApmPtr)(((ScrnInfoPtr)(p))->driverPrivate))
+#define APMPTR(p) ((ApmPtr)(((ScrnInfoPtr)(p))->driverPrivate))
+
+extern int ApmHWCursorInit(ScreenPtr pScreen);
+extern int ApmDGAInit(ScreenPtr pScreen);
+extern int ApmAccelInit(ScreenPtr pScreen);
+extern Bool ApmI2CInit(ScreenPtr pScreen);
+extern void XFree86RushExtensionInit(void);
+extern void ApmCheckMMIO_Init(ScrnInfoPtr pScrn);
+extern void ApmCheckMMIO_Init_IOP(ScrnInfoPtr pScrn);
+extern void ApmCheckMMIO_Init24(ScrnInfoPtr pScrn);
+extern void ApmCheckMMIO_Init24_IOP(ScrnInfoPtr pScrn);
+
+extern int ApmPixmapIndex;
+#define APM_GET_PIXMAP_PRIVATE(pix)\
+ (ApmPixmapPtr)((pix)->devPrivates[ApmPixmapIndex].ptr)
+
+#include "apm_regs.h"
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_accel.c
new file mode 100644
index 000000000..b45ed873d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_accel.c
@@ -0,0 +1,587 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/apm/apm_accel.c,v 1.9 1999/08/28 14:32:45 dawes Exp $ */
+
+
+#include "apm.h"
+#include "miline.h"
+
+extern int xf86Exiting;
+
+/* Defines */
+#define MAXLOOP 1000000
+
+/* Translation from X ROP's to APM ROP's. */
+static unsigned char apmROP[] = {
+ 0,
+ 0x88,
+ 0x44,
+ 0xCC,
+ 0x22,
+ 0xAA,
+ 0x66,
+ 0xEE,
+ 0x11,
+ 0x99,
+ 0x55,
+ 0xDD,
+ 0x33,
+ 0xBB,
+ 0x77,
+ 0xFF
+};
+
+extern void apm_stopit(void);
+
+static void Dump(void* start, u32 len);
+
+#include "apm_funcs.c"
+
+#define IOP_ACCESS
+#include "apm_funcs.c"
+
+#undef IOP_ACCESS
+#undef PSZ
+#define PSZ 24
+#include "apm_funcs.c"
+
+#define IOP_ACCESS
+#include "apm_funcs.c"
+
+static void
+ApmRemoveStipple(FBAreaPtr area)
+{
+ ((struct ApmStippleCacheRec *)area->devPrivate.ptr)->apmStippleCached = FALSE;
+}
+
+static void
+ApmMoveStipple(FBAreaPtr from, FBAreaPtr to)
+{
+ struct ApmStippleCacheRec *pApm = (struct ApmStippleCacheRec *)to->devPrivate.ptr;
+
+ pApm->apmStippleCache.x = to->box.x1;
+ pApm->apmStippleCache.y += to->box.y1 - from->box.y1;
+ /* TODO : move data */
+}
+
+/*
+ * ApmCacheMonoStipple
+ * because my poor AT3D needs stipples stored linearly in memory.
+ */
+static XAACacheInfoPtr
+ApmCacheMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ APMDECL(pScrn);
+ int w = pPix->drawable.width, W = (w + 31) & ~31;
+ int h = pPix->drawable.height;
+ int i, j, dwords, mem, width, funcNo;
+ FBAreaPtr draw;
+ struct ApmStippleCacheRec *pCache;
+ unsigned char *srcPtr;
+ CARD32 *dstPtr;
+
+ for (i = 0; i < APM_CACHE_NUMBER; i++)
+ if ((pApm->apmCache[i].apmStippleCache.serialNumber == pPix->drawable.serialNumber)
+ && pApm->apmCache[i].apmStippleCached &&
+ (pApm->apmCache[i].apmStippleCache.fg == -1) &&
+ (pApm->apmCache[i].apmStippleCache.bg == -1)) {
+ pApm->apmCache[i].apmStippleCache.trans_color = -1;
+ return &pApm->apmCache[i].apmStippleCache;
+ }
+ if ((i = ++pApm->apmCachePtr) >= APM_CACHE_NUMBER)
+ i = pApm->apmCachePtr = 0;
+ pCache = &pApm->apmCache[i];
+ if (pCache->apmStippleCached) {
+ pCache->apmStippleCached = FALSE;
+ xf86FreeOffscreenArea(pCache->area);
+ }
+
+ draw = xf86AllocateLinearOffscreenArea(pApm->pScreen, (W * h + 7) / 8, 8,
+ ApmMoveStipple, ApmRemoveStipple, pCache);
+ if (!draw)
+ return NULL; /* Let's hope this will never happen... */
+
+ pCache->area = draw;
+ pCache->apmStippleCache.serialNumber = pPix->drawable.serialNumber;
+ pCache->apmStippleCache.trans_color =
+ pCache->apmStippleCache.bg =
+ pCache->apmStippleCache.fg = -1;
+ pCache->apmStippleCache.orig_w = w;
+ pCache->apmStippleCache.orig_h = h;
+ pCache->apmStippleCache.x = draw->box.x1;
+ pCache->apmStippleCache.y = draw->box.y1 + ((pCache - pApm->apmCache) + 1) * pApm->Scanlines;
+ mem = ((draw->box.x2 - draw->box.x1) * (draw->box.y2 - draw->box.y1) *
+ pApm->bitsPerPixel) / (W * h);
+ width = 2;
+ while (width * width <= mem)
+ width++;
+ width--;
+ pCache->apmStippleCache.w = (width * W + pApm->bitsPerPixel - 1) /
+ pApm->bitsPerPixel;
+ pCache->apmStippleCache.h = ((draw->box.x2 - draw->box.x1) *
+ (draw->box.y2 - draw->box.y1)) /
+ pCache->apmStippleCache.w;
+ pCache->apmStippleCached = TRUE;
+
+ if (w < 32) {
+ if (w & (w - 1)) funcNo = 1;
+ else funcNo = 0;
+ } else funcNo = 2;
+
+ dstPtr = ((CARD32 *)pApm->FbBase) + (draw->box.x1 +
+ draw->box.y1 * pApm->bytesPerScanline) / 4;
+ j = 0;
+ dwords = (pCache->apmStippleCache.w * pApm->bitsPerPixel) / 32;
+ while (j + h <= pCache->apmStippleCache.h) {
+ srcPtr = (unsigned char *)pPix->devPrivate.ptr;
+ for (i = h; --i >= 0; ) {
+ (*XAAStippleScanlineFuncMSBFirst[funcNo])(dstPtr, (CARD32 *)srcPtr, 0, w, dwords);
+ srcPtr += pPix->devKind;
+ dstPtr += dwords;
+ }
+ j += h;
+ }
+ srcPtr = (unsigned char *)pPix->devPrivate.ptr;
+ for (i = pCache->apmStippleCache.h - j ; --i >= 0; ) {
+ (*XAAStippleScanlineFuncMSBFirst[funcNo])(dstPtr, (CARD32 *)srcPtr, 0, w, dwords);
+ srcPtr += pPix->devKind;
+ dstPtr += dwords;
+ }
+
+ return &pCache->apmStippleCache;
+}
+
+/*********************************************************************************************/
+
+int
+ApmAccelInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ APMDECL(pScrn);
+ XAAInfoRecPtr pXAAinfo;
+ BoxRec AvailFBArea;
+ int mem, ScratchMemOffset, i, stat;
+
+ pApm->AccelInfoRec = pXAAinfo = XAACreateInfoRec();
+ if (!pXAAinfo)
+ return FALSE;
+
+ pApm->pScreen = pScreen;
+ pApm->displayWidth = pScrn->display->virtualX;
+ pApm->displayHeight = pScrn->display->virtualY;
+ pApm->bitsPerPixel = pScrn->bitsPerPixel;
+ pApm->bytesPerScanline= (pApm->displayWidth * pApm->bitsPerPixel) >> 3;
+ mem = pScrn->videoRam << 10;
+ pApm->Scanlines = mem / pApm->bytesPerScanline + 1;
+ /*
+ * Reserve at list one line for transparent 8x8 mono2color expansion
+ */
+ ScratchMemOffset = ((mem - pApm->OffscreenReserved) /
+ pApm->bytesPerScanline - 1) * pApm->bytesPerScanline;
+ pApm->ScratchMemSize= mem - ScratchMemOffset - pApm->OffscreenReserved;
+ pApm->ScratchMemOffset = ScratchMemOffset;
+ switch (pApm->bitsPerPixel) {
+ case 8:
+ case 24:
+ pApm->ScratchMemWidth =
+ (mem - ScratchMemOffset - pApm->OffscreenReserved) / 1;
+ pApm->ScratchMem =
+ ((ScratchMemOffset & 0xFFF000) << 4) |
+ (ScratchMemOffset & 0xFFF);
+ break;
+
+ case 16:
+ pApm->ScratchMemWidth =
+ (mem - ScratchMemOffset - pApm->OffscreenReserved) / 2;
+ pApm->ScratchMem =
+ ((ScratchMemOffset & 0xFFE000) << 3) |
+ ((ScratchMemOffset & 0x1FFE) >> 1);
+ break;
+
+ case 32:
+ pApm->ScratchMemWidth =
+ (mem - ScratchMemOffset - pApm->OffscreenReserved) / 4;
+ pApm->ScratchMem =
+ ((ScratchMemOffset & 0xFFC000U) << 2) |
+ ((ScratchMemOffset & 0x3FFC) >> 2);
+ break;
+ }
+ pApm->OffscreenReserved = mem - ScratchMemOffset;
+
+ pApm->apmMMIO_Init = TRUE;
+
+ /*
+ * Abort
+ */
+ if (pApm->noLinear) {
+ stat = RDXL_IOP(0x1FC);
+ while ((stat & (STATUS_HOSTBLTBUSY | STATUS_ENGINEBUSY)) ||
+ ((stat & STATUS_FIFO) < 8)) {
+ WRXB_IOP(0x1FC, 0);
+ stat = RDXL_IOP(0x1FC);
+ }
+ }
+ else {
+ stat = RDXL_M(0x1FC);
+ while ((stat & (STATUS_HOSTBLTBUSY | STATUS_ENGINEBUSY)) ||
+ ((stat & STATUS_FIFO) < 8)) {
+ WRXB_M(0x1FC, 0);
+ stat = RDXL_M(0x1FC);
+ }
+ }
+
+ pApm->Setup_DEC = 0;
+ switch(pApm->bitsPerPixel)
+ {
+ case 8:
+ pApm->Setup_DEC |= DEC_BITDEPTH_8;
+ break;
+ case 16:
+ pApm->Setup_DEC |= DEC_BITDEPTH_16;
+ break;
+ case 24:
+ pApm->Setup_DEC |= DEC_BITDEPTH_24;
+ break;
+ case 32:
+ pApm->Setup_DEC |= DEC_BITDEPTH_32;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Cannot set up drawing engine control for bpp = %d\n",
+ pScrn->bitsPerPixel);
+ break;
+ }
+
+ switch(pApm->displayWidth)
+ {
+ case 640:
+ pApm->Setup_DEC |= DEC_WIDTH_640;
+ break;
+ case 800:
+ pApm->Setup_DEC |= DEC_WIDTH_800;
+ break;
+ case 1024:
+ pApm->Setup_DEC |= DEC_WIDTH_1024;
+ break;
+ case 1152:
+ pApm->Setup_DEC |= DEC_WIDTH_1152;
+ break;
+ case 1280:
+ pApm->Setup_DEC |= DEC_WIDTH_1280;
+ break;
+ case 1600:
+ pApm->Setup_DEC |= DEC_WIDTH_1600;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Cannot set up drawing engine control "
+ "for screen width = %d\n", pApm->displayWidth);
+ break;
+ }
+
+ /* Setup current register values */
+ for (i = 0; i < sizeof(pApm->regcurr) / 4; i++)
+ ((CARD32 *)curr)[i] = RDXL(0x30 + 4*i);
+
+ SETCLIP_CTRL(1);
+ SETCLIP_CTRL(0);
+ SETBYTEMASK(0x00);
+ SETBYTEMASK(0xFF);
+ SETROP(ROP_S_xor_D);
+ SETROP(ROP_S);
+ pApm->apmMMIO_Init = TRUE;
+
+ /*
+ * Set up the main acceleration flags.
+ */
+ pXAAinfo->Flags = PIXMAP_CACHE | LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
+ pXAAinfo->CacheMonoStipple = ApmCacheMonoStipple;
+
+ if (pApm->bitsPerPixel != 24) {
+ if (!pApm->noLinear) {
+#define XAA(s) pXAAinfo->s = Apm##s
+ XAA(Sync);
+
+ /* Accelerated filled rectangles */
+ pXAAinfo->SolidFillFlags = NO_PLANEMASK;
+ XAA(SetupForSolidFill);
+ XAA(SubsequentSolidFillRect);
+
+ /* Accelerated screen to screen color expansion */
+ pXAAinfo->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK;
+ XAA(SetupForScreenToScreenColorExpandFill);
+ XAA(SubsequentScreenToScreenColorExpandFill);
+
+ /* Accelerated CPU to screen color expansion */
+ if (pApm->Chipset == AT3D && pApm->ChipRev >= 4) {
+ pXAAinfo->CPUToScreenColorExpandFillFlags =
+ NO_PLANEMASK | SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD
+ | BIT_ORDER_IN_BYTE_MSBFIRST | LEFT_EDGE_CLIPPING |
+ LEFT_EDGE_CLIPPING_NEGATIVE_X | SYNC_AFTER_COLOR_EXPAND;
+ XAA(SetupForCPUToScreenColorExpandFill);
+ XAA(SubsequentCPUToScreenColorExpandFill);
+ pXAAinfo->ColorExpandBase = pApm->BltMap;
+ pXAAinfo->ColorExpandRange = 32*1024;
+ }
+
+ /* Accelerated image transfers */
+ pXAAinfo->ImageWriteFlags =
+ LEFT_EDGE_CLIPPING | NO_PLANEMASK |
+ SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD |
+ SYNC_AFTER_IMAGE_WRITE;
+ pXAAinfo->ImageWriteBase = pApm->BltMap;
+ pXAAinfo->ImageWriteRange = 32*1024;
+ XAA(SetupForImageWrite);
+ XAA(SubsequentImageWriteRect);
+ XAA(WritePixmap);
+
+ /* Accelerated screen-screen bitblts */
+ pXAAinfo->ScreenToScreenCopyFlags = NO_PLANEMASK;
+ XAA(SetupForScreenToScreenCopy);
+ XAA(SubsequentScreenToScreenCopy);
+
+ /* Accelerated Line drawing */
+ pXAAinfo->SolidLineFlags = NO_PLANEMASK | HARDWARE_CLIP_LINE;
+ XAA(SubsequentSolidBresenhamLine);
+ XAA(SetClippingRectangle);
+ pXAAinfo->SolidBresenhamLineErrorTermBits = 15;
+
+ /* Pattern fill */
+ pXAAinfo->Mono8x8PatternFillFlags = NO_PLANEMASK | NO_TRANSPARENCY |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ HARDWARE_PATTERN_SCREEN_ORIGIN;
+ XAA(SetupForMono8x8PatternFill);
+ XAA(SubsequentMono8x8PatternFillRect);
+ if (pApm->bitsPerPixel == 8) {
+ pXAAinfo->Color8x8PatternFillFlags = NO_PLANEMASK |
+ HARDWARE_PATTERN_SCREEN_ORIGIN;
+ XAA(SetupForColor8x8PatternFill);
+ XAA(SubsequentColor8x8PatternFillRect);
+ }
+#undef XAA
+ }
+ else {
+#define XAA(s) pXAAinfo->s = Apm##s##_IOP
+ XAA(Sync);
+
+ /* Accelerated filled rectangles */
+ pXAAinfo->SolidFillFlags = NO_PLANEMASK;
+ XAA(SetupForSolidFill);
+ XAA(SubsequentSolidFillRect);
+
+ /* Accelerated screen to screen color expansion */
+ pXAAinfo->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK;
+ XAA(SetupForScreenToScreenColorExpandFill);
+ XAA(SubsequentScreenToScreenColorExpandFill);
+
+ /* Accelerated CPU to screen color expansion */
+ if (pApm->Chipset == AT3D && pApm->ChipRev >= 4) {
+ pXAAinfo->CPUToScreenColorExpandFillFlags =
+ NO_PLANEMASK | SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD
+ | BIT_ORDER_IN_BYTE_MSBFIRST | LEFT_EDGE_CLIPPING |
+ LEFT_EDGE_CLIPPING_NEGATIVE_X | SYNC_AFTER_COLOR_EXPAND;
+ XAA(SetupForCPUToScreenColorExpandFill);
+ XAA(SubsequentCPUToScreenColorExpandFill);
+ pXAAinfo->ColorExpandBase = pApm->BltMap;
+ pXAAinfo->ColorExpandRange = 32*1024;
+ }
+
+ /* Accelerated image transfers */
+ pXAAinfo->ImageWriteFlags =
+ LEFT_EDGE_CLIPPING | NO_PLANEMASK |
+ SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD;
+ pXAAinfo->ImageWriteBase = pApm->BltMap;
+ pXAAinfo->ImageWriteRange = 32*1024;
+ XAA(SetupForImageWrite);
+ XAA(SubsequentImageWriteRect);
+ XAA(WritePixmap);
+
+ /* Accelerated screen-screen bitblts */
+ pXAAinfo->ScreenToScreenCopyFlags = NO_PLANEMASK;
+ XAA(SetupForScreenToScreenCopy);
+ XAA(SubsequentScreenToScreenCopy);
+
+ /* Accelerated Line drawing */
+ pXAAinfo->SolidLineFlags = NO_PLANEMASK | HARDWARE_CLIP_LINE;
+ XAA(SubsequentSolidBresenhamLine);
+ XAA(SetClippingRectangle);
+ pXAAinfo->SolidBresenhamLineErrorTermBits = 15;
+
+ /* Pattern fill */
+ pXAAinfo->Mono8x8PatternFillFlags = NO_PLANEMASK | NO_TRANSPARENCY |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ HARDWARE_PATTERN_SCREEN_ORIGIN;
+ XAA(SetupForMono8x8PatternFill);
+ XAA(SubsequentMono8x8PatternFillRect);
+ if (pApm->bitsPerPixel == 8) {
+ pXAAinfo->Color8x8PatternFillFlags = NO_PLANEMASK |
+ HARDWARE_PATTERN_SCREEN_ORIGIN;
+ XAA(SetupForColor8x8PatternFill);
+ XAA(SubsequentColor8x8PatternFillRect);
+ }
+#undef XAA
+ }
+ }
+ else {
+ if (!pApm->noLinear) {
+#define XAA(s) pXAAinfo->s = Apm##s##24
+ XAA(Sync);
+
+ /* Accelerated filled rectangles */
+ pXAAinfo->SolidFillFlags = NO_PLANEMASK;
+ XAA(SetupForSolidFill);
+ XAA(SubsequentSolidFillRect);
+
+#if 0
+ /* Accelerated screen to screen color expansion */
+ pXAAinfo->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK;
+ XAA(SetupForScreenToScreenColorExpandFill);
+ XAA(SubsequentScreenToScreenColorExpandFill);
+
+ /* Accelerated CPU to screen color expansion */
+ if (pApm->Chipset == AT3D && pApm->ChipRev >= 4) {
+ pXAAinfo->CPUToScreenColorExpandFillFlags =
+ NO_PLANEMASK | SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD
+ | BIT_ORDER_IN_BYTE_MSBFIRST | LEFT_EDGE_CLIPPING |
+ LEFT_EDGE_CLIPPING_NEGATIVE_X | SYNC_AFTER_COLOR_EXPAND;
+ XAA(SetupForCPUToScreenColorExpandFill);
+ XAA(SubsequentCPUToScreenColorExpandFill);
+ pXAAinfo->ColorExpandBase = pApm->BltMap;
+ pXAAinfo->ColorExpandRange = 32*1024;
+ }
+
+ /* Accelerated image transfers */
+ pXAAinfo->ImageWriteFlags =
+ LEFT_EDGE_CLIPPING | NO_PLANEMASK |
+ SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD |
+ SYNC_AFTER_IMAGE_WRITE;
+ pXAAinfo->ImageWriteBase = pApm->BltMap;
+ pXAAinfo->ImageWriteRange = 32*1024;
+ XAA(SetupForImageWrite);
+ XAA(SubsequentImageWriteRect);
+ XAA(WritePixmap);
+#endif
+
+ /* Accelerated screen-screen bitblts */
+ pXAAinfo->ScreenToScreenCopyFlags = NO_PLANEMASK;
+ XAA(SetupForScreenToScreenCopy);
+ XAA(SubsequentScreenToScreenCopy);
+
+#if 0
+ /* Accelerated Line drawing */
+ pXAAinfo->SolidLineFlags = NO_PLANEMASK | HARDWARE_CLIP_LINE;
+ XAA(SubsequentSolidBresenhamLine);
+ XAA(SetClippingRectangle);
+ pXAAinfo->SolidBresenhamLineErrorTermBits = 15;
+
+ /* Pattern fill */
+ pXAAinfo->Mono8x8PatternFillFlags = NO_PLANEMASK | NO_TRANSPARENCY |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ HARDWARE_PATTERN_SCREEN_ORIGIN;
+ XAA(SetupForMono8x8PatternFill);
+ XAA(SubsequentMono8x8PatternFillRect);
+#endif
+#undef XAA
+ }
+ else {
+#define XAA(s) pXAAinfo->s = Apm##s##24##_IOP
+ XAA(Sync);
+
+ /* Accelerated filled rectangles */
+ pXAAinfo->SolidFillFlags = NO_PLANEMASK;
+ XAA(SetupForSolidFill);
+ XAA(SubsequentSolidFillRect);
+
+#if 0
+ /* Accelerated screen to screen color expansion */
+ pXAAinfo->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK;
+ XAA(SetupForScreenToScreenColorExpandFill);
+ XAA(SubsequentScreenToScreenColorExpandFill);
+
+ /* Accelerated CPU to screen color expansion */
+ if (pApm->Chipset == AT3D && pApm->ChipRev >= 4) {
+ pXAAinfo->CPUToScreenColorExpandFillFlags =
+ NO_PLANEMASK | SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD
+ | BIT_ORDER_IN_BYTE_MSBFIRST | LEFT_EDGE_CLIPPING |
+ LEFT_EDGE_CLIPPING_NEGATIVE_X | SYNC_AFTER_COLOR_EXPAND;
+ XAA(SetupForCPUToScreenColorExpandFill);
+ XAA(SubsequentCPUToScreenColorExpandFill);
+ pXAAinfo->ColorExpandBase = pApm->BltMap;
+ pXAAinfo->ColorExpandRange = 32*1024;
+ }
+
+ /* Accelerated image transfers */
+ pXAAinfo->ImageWriteFlags =
+ LEFT_EDGE_CLIPPING | NO_PLANEMASK |
+ SCANLINE_PAD_DWORD | CPU_TRANSFER_PAD_QWORD;
+ pXAAinfo->ImageWriteBase = pApm->BltMap;
+ pXAAinfo->ImageWriteRange = 32*1024;
+ XAA(SetupForImageWrite);
+ XAA(SubsequentImageWriteRect);
+ XAA(WritePixmap);
+#endif
+
+ /* Accelerated screen-screen bitblts */
+ pXAAinfo->ScreenToScreenCopyFlags = NO_PLANEMASK;
+ XAA(SetupForScreenToScreenCopy);
+ XAA(SubsequentScreenToScreenCopy);
+
+#if 0
+ /* Accelerated Line drawing */
+ pXAAinfo->SolidLineFlags = NO_PLANEMASK | HARDWARE_CLIP_LINE;
+ XAA(SubsequentSolidBresenhamLine);
+ XAA(SetClippingRectangle);
+ pXAAinfo->SolidBresenhamLineErrorTermBits = 15;
+
+ /* Pattern fill */
+ pXAAinfo->Mono8x8PatternFillFlags = NO_PLANEMASK | NO_TRANSPARENCY |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ HARDWARE_PATTERN_SCREEN_ORIGIN;
+ XAA(SetupForMono8x8PatternFill);
+ XAA(SubsequentMono8x8PatternFillRect);
+#endif
+#undef XAA
+ }
+ }
+
+ /*
+ * Init Rush extension
+ */
+ REGION_INIT(pApm->pScreen, &pApm->apmLockedRegion, (BoxRec *)0, 1);
+#ifdef XF86RUSH_EXT
+ /* XXX Should this be called once per screen? */
+ XFree86RushExtensionInit();
+#endif
+
+ /* Pixmap cache setup */
+ pXAAinfo->CachePixelGranularity = 64 / pApm->bitsPerPixel;
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pApm->displayWidth;
+ AvailFBArea.y2 = (pScrn->videoRam * 1024 - pApm->OffscreenReserved) /
+ (pApm->displayWidth * ((pApm->bitsPerPixel + 7) >> 3));
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ return XAAInit(pScreen, pXAAinfo);
+}
+
+
+static void
+Dump(void* start, u32 len)
+{
+ u8* i;
+ int c = 0;
+ ErrorF("Memory Dump. Start 0x%x length %d\n", (u32)start, len);
+ for (i = (u8*)start; i < ((u8*)start+len); i++)
+ {
+ ErrorF("%02x ", *i);
+ if (c++ % 25 == 24)
+ ErrorF("\n");
+ }
+ ErrorF("\n");
+}
+
+#ifdef __GNUC__
+void apm_stopit(void){__asm__ __volatile__("": : : "memory");}
+#else
+void apm_stopit(void){}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_cursor.c
new file mode 100644
index 000000000..6c2ff1915
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_cursor.c
@@ -0,0 +1,211 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/apm/apm_cursor.c,v 1.9 1999/08/28 09:00:57 dawes Exp $ */
+
+
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "input.h"
+#include "cursorstr.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#include "windowstr.h"
+#include "mfb.h"
+#include "compiler.h"
+#include "xf86.h"
+#include "mipointer.h"
+#include "xf86Priv.h"
+#include "xf86_ansic.h"
+
+#include "apm.h"
+
+#define CURSORWIDTH 64
+#define CURSORHEIGHT 64
+#define CURSORSIZE (CURSORWIDTH * CURSORHEIGHT / 8)
+#define CURSORALIGN ((CURSORSIZE + 1023) & ~1023l)
+
+static void ApmShowCursor(ScrnInfoPtr pScrn);
+static void ApmHideCursor(ScrnInfoPtr pScrn);
+static void ApmSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
+static void ApmSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
+static void ApmLoadCursorImage(ScrnInfoPtr pScrn, u8* data);
+static Bool ApmUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs);
+
+static u8 ConvertTable[256];
+
+/* Inline functions */
+static __inline__ void
+WaitForFifo(ApmPtr pApm, int slots)
+{
+ if (!pApm->UsePCIRetry) {
+ volatile int i;
+#define MAXLOOP 1000000
+
+ for(i = 0; i < MAXLOOP; i++) {
+ if ((STATUS() & STATUS_FIFO) >= slots)
+ break;
+ }
+ if (i == MAXLOOP && !xf86Exiting) {
+ FatalError("Hung in WaitForFifo() (Status = 0x%08X)\n", STATUS());
+ }
+ }
+}
+
+static __inline__ void
+ApmCheckMMIO_InitFast(ScrnInfoPtr pScrn)
+{
+ if (!APMPTR(pScrn)->apmMMIO_Init)
+ ApmCheckMMIO_Init(pScrn);
+}
+
+int ApmHWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ APMDECL(pScrn);
+ xf86CursorInfoPtr infoPtr;
+ u32 i;
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if (!infoPtr)
+ return FALSE;
+
+ pApm->CursorInfoRec = infoPtr;
+ pApm->OffscreenReserved += 2 * CURSORALIGN;
+ pApm->DisplayedCursorAddress = pApm->BaseCursorAddress =
+ pApm->CursorAddress = 1024 * pScrn->videoRam - pApm->OffscreenReserved;
+
+ infoPtr->MaxWidth = CURSORWIDTH;
+ infoPtr->MaxHeight = CURSORHEIGHT;
+
+ infoPtr->Flags = HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1;
+ infoPtr->SetCursorColors = ApmSetCursorColors;
+ infoPtr->SetCursorPosition = ApmSetCursorPosition;
+ infoPtr->LoadCursorImage = ApmLoadCursorImage;
+ infoPtr->HideCursor = ApmHideCursor;
+ infoPtr->ShowCursor = ApmShowCursor;
+ infoPtr->UseHWCursor = ApmUseHWCursor;
+
+ /*ErrorF("%s %s: %s: Using hardware cursor (XAA).\n",
+ XCONFIG_PROBED, vga256InfoRec.name, vga256InfoRec.chipset);
+
+ if(XAACursorInfoRec.Flags & USE_HARDWARE_CURSOR) {
+ vgaHWCursor.Init = XAACursorInit;
+ vgaHWCursor.Initialized = TRUE;
+ vgaHWCursor.Restore = XAARestoreCursor;
+ vgaHWCursor.Warp = XAAWarpCursor;
+ vgaHWCursor.QueryBestSize = XAAQueryBestSize;
+ }*/
+
+ /* Set up the convert table for the input cursor data */
+ for (i = 0; i < 256; i++)
+ ConvertTable[i] = ((~i) & 0xAA) | (i & (i >> 1) & 0x55);
+
+ return xf86InitCursor(pScreen, infoPtr);
+}
+
+
+static void
+ApmShowCursor(ScrnInfoPtr pScrn)
+{
+ APMDECL(pScrn);
+
+ ApmCheckMMIO_InitFast(pScrn);
+ WaitForFifo(pApm, 2);
+ WRXW(0x144, pApm->CursorAddress >> 10);
+ WRXB(0x140, 1);
+ pApm->DisplayedCursorAddress = pApm->CursorAddress;
+}
+
+
+static void
+ApmHideCursor(ScrnInfoPtr pScrn)
+{
+ APMDECL(pScrn);
+
+ ApmCheckMMIO_InitFast(pScrn);
+ WaitForFifo(pApm, 1);
+ WRXB(0x140, 0);
+}
+
+static Bool ApmUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ return xf86Screens[pScreen->myNum]->bitsPerPixel >= 8;
+}
+
+static void
+ApmSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ APMDECL(pScrn);
+ int xoff, yoff;
+
+ if (x < -CURSORWIDTH || y < -CURSORHEIGHT) {
+ WaitForFifo(pApm, 1);
+ WRXB(0x140, 0);
+ return;
+ }
+
+ if (x < 0) {
+ xoff = -x;
+ x = 0;
+ }
+ else
+ xoff = 0;
+ if (y < 0) {
+ yoff = -y;
+ y = 0;
+ }
+ else
+ yoff = 0;
+
+ WaitForFifo(pApm, 2);
+ WRXW(0x14c, (yoff << 8) | (xoff & 0xff));
+ WRXL(0x148, (y << 16) | (x & 0xffff));
+}
+
+
+static void
+ApmSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ APMDECL(pScrn);
+ u16 packedcolfg, packedcolbg;
+
+ if (pScrn->bitsPerPixel == 8)
+ {
+ WaitForFifo(pApm, 2);
+ WRXB(0x141, fg);
+ WRXB(0x142, bg);
+ }
+ else
+ {
+ packedcolfg =
+ ((fg & 0xe00000) >> 16) |
+ ((fg & 0x00e000) >> 11) |
+ ((fg & 0x0000c0) >> 6);
+ packedcolbg =
+ ((bg & 0xe00000) >> 16) |
+ ((bg & 0x00e000) >> 11) |
+ ((bg & 0x0000c0) >> 6);
+ WaitForFifo(pApm, 2);
+ WRXB(0x141, packedcolfg);
+ WRXB(0x142, packedcolbg);
+ }
+}
+
+
+static void
+ApmLoadCursorImage(ScrnInfoPtr pScrn, u8* data)
+{
+ APMDECL(pScrn);
+ u32 i;
+ u8 tmp[2 * CURSORSIZE];
+
+ /* Correct input data */
+ for (i = 0; i < sizeof tmp; i++)
+ tmp[i] = ConvertTable[data[i]];
+ /*
+ * To avoid flicker.
+ * Note: 2*pApm->BaseCursorAddress + CURSORALIGN (=1024) < 2^31 all the time.
+ */
+ pApm->CursorAddress = 2*pApm->BaseCursorAddress + CURSORALIGN - pApm->DisplayedCursorAddress;
+ memcpy((u8*)pApm->FbBase + pApm->CursorAddress, tmp, sizeof tmp);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_dga.c
new file mode 100644
index 000000000..6b0c65d82
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_dga.c
@@ -0,0 +1,406 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/apm/apm_dga.c,v 1.4 1999/08/28 14:32:46 dawes Exp $ */
+/*
+ * file: apm_dga.c
+ * ported from s3virge, ported from mga
+ *
+ */
+
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "apm.h"
+#include "dgaproc.h"
+
+
+static Bool ApmOpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
+ int *, int *, int *);
+static Bool ApmSetMode(ScrnInfoPtr, DGAModePtr);
+static int ApmGetViewport(ScrnInfoPtr);
+static void ApmSetViewport(ScrnInfoPtr, int, int, int);
+static void ApmFillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
+static void ApmBlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+static void ApmBlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
+ unsigned long);
+static void ApmSync(ScrnInfoPtr);
+
+static
+DGAFunctionRec ApmDGAFuncs = {
+ ApmOpenFramebuffer,
+ NULL,
+ ApmSetMode,
+ ApmSetViewport,
+ ApmGetViewport,
+ ApmSync,
+ ApmFillRect,
+ ApmBlitRect,
+ ApmBlitTransRect
+};
+
+/*
+ * Placeholder
+ */
+void
+ApmSync(ScrnInfoPtr pScrn)
+{
+}
+
+
+Bool
+ApmDGAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ APMDECL(pScrn);
+ DGAModePtr modes = NULL, newmodes = NULL, currentMode;
+ DisplayModePtr pMode, firstMode;
+ int Bpp = pScrn->bitsPerPixel >> 3;
+ int num = 0;
+ Bool oneMore;
+
+
+
+ pMode = firstMode = pScrn->modes;
+
+ while(pMode) {
+ if(pScrn->displayWidth != pMode->HDisplay) {
+ newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec));
+ oneMore = TRUE;
+ } else {
+ newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec));
+ oneMore = FALSE;
+ }
+
+ if(!newmodes) {
+ xfree(modes);
+ return FALSE;
+ }
+ modes = newmodes;
+
+SECOND_PASS:
+
+ currentMode = modes + num;
+ num++;
+
+ currentMode->mode = pMode;
+ currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
+ if(pMode->Flags & V_DBLSCAN)
+ currentMode->flags |= DGA_DOUBLESCAN;
+ if(pMode->Flags & V_INTERLACE)
+ currentMode->flags |= DGA_INTERLACED;
+ currentMode->byteOrder = pScrn->imageByteOrder;
+ currentMode->depth = pScrn->depth;
+ currentMode->bitsPerPixel = pScrn->bitsPerPixel;
+ currentMode->red_mask = pScrn->mask.red;
+ currentMode->green_mask = pScrn->mask.green;
+ currentMode->blue_mask = pScrn->mask.blue;
+ currentMode->viewportWidth = pMode->HDisplay;
+ currentMode->viewportHeight = pMode->VDisplay;
+ currentMode->xViewportStep = 3;
+ currentMode->yViewportStep = 1;
+ currentMode->viewportFlags = DGA_FLIP_RETRACE;
+ currentMode->offset = 0;
+ currentMode->address = (pointer)(pApm->LinAddress +
+ 0*((char *)pApm->FbBase - (char *)pApm->LinMap));
+/*cep*/
+ xf86ErrorFVerb(4,
+ " ApmDGAInit firstone vpWid=%d, vpHgt=%d, Bpp=%d, mdbitsPP=%d\n",
+ currentMode->viewportWidth,
+ currentMode->viewportHeight,
+ Bpp,
+ currentMode->bitsPerPixel
+ );
+
+
+ if(oneMore) { /* first one is narrow width */
+ currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L;
+ currentMode->imageWidth = pMode->HDisplay;
+ currentMode->imageHeight = (pScrn->videoRam * 1024 - pApm->OffscreenReserved) /
+ currentMode->bytesPerScanline;
+ currentMode->imageHeight = pMode->VDisplay;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+ oneMore = FALSE;
+ if(!pApm->NoAccel && Bpp * 8 == currentMode->bitsPerPixel &&
+ (currentMode->imageWidth == 640 ||
+ currentMode->imageWidth == 800 ||
+ currentMode->imageWidth == 1024 ||
+ currentMode->imageWidth == 1152 ||
+ currentMode->imageWidth == 1280 ||
+ currentMode->imageWidth == 1600))
+ currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT |
+ DGA_BLIT_RECT_TRANS;
+
+/*cep*/
+ xf86ErrorFVerb(4,
+ " ApmDGAInit imgHgt=%d, ram=%d, bytesPerScanl=%d\n",
+ currentMode->imageHeight,
+ pScrn->videoRam << 10,
+ currentMode->bytesPerScanline );
+
+ goto SECOND_PASS;
+ } else {
+ currentMode->bytesPerScanline =
+ ((pScrn->displayWidth * Bpp) + 3) & ~3L;
+ currentMode->imageWidth = pScrn->displayWidth;
+ currentMode->imageHeight = (pScrn->videoRam * 1024 - pApm->OffscreenReserved) /
+ currentMode->bytesPerScanline;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+ if(!pApm->NoAccel && Bpp * 8 == currentMode->bitsPerPixel &&
+ (currentMode->imageWidth == 640 ||
+ currentMode->imageWidth == 800 ||
+ currentMode->imageWidth == 1024 ||
+ currentMode->imageWidth == 1152 ||
+ currentMode->imageWidth == 1280 ||
+ currentMode->imageWidth == 1600))
+ currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT |
+ DGA_BLIT_RECT_TRANS;
+ }
+
+ pMode = pMode->next;
+ if(pMode == firstMode)
+ break;
+ }
+
+ pApm->numDGAModes = num;
+ pApm->DGAModes = modes;
+
+ if (pApm->AccelInfoRec)
+ ApmDGAFuncs.Sync = pApm->AccelInfoRec->Sync;
+ return DGAInit(pScreen, &ApmDGAFuncs, modes, num);
+}
+
+
+static Bool
+ApmSetMode(
+ ScrnInfoPtr pScrn,
+ DGAModePtr pMode
+)
+{
+ static int OldDisplayWidth[MAXSCREENS];
+ int index = pScrn->pScreen->myNum, c;
+ APMDECL(pScrn);
+
+ if(!pMode) { /* restore the original mode */
+ /* put the ScreenParameters back */
+
+ pScrn->displayWidth = OldDisplayWidth[index];
+
+ pScrn->SwitchMode(index, pScrn->currentMode, 0);
+ pApm->DGAactive = FALSE;
+ } else {
+ if(!pApm->DGAactive) { /* save the old parameters */
+ OldDisplayWidth[index] = pScrn->displayWidth;
+
+ pApm->DGAactive = TRUE;
+ }
+
+ pScrn->displayWidth = (8 * pMode->bytesPerScanline) /
+ pMode->bitsPerPixel;
+
+ pScrn->SwitchMode(index, pMode->mode, 0);
+ }
+
+ switch(pScrn->bitsPerPixel) {
+ case 8:
+ c = DEC_BITDEPTH_8;
+ break;
+
+ case 16:
+ c = DEC_BITDEPTH_16;
+ break;
+
+ case 24:
+ c = DEC_BITDEPTH_24;
+ break;
+
+ case 32:
+ c = DEC_BITDEPTH_32;
+ break;
+
+ default:
+ c = 0;
+ break;
+ }
+
+ switch(pScrn->displayWidth) {
+ case 640:
+ c |= DEC_WIDTH_640;
+ break;
+
+ case 800:
+ c |= DEC_WIDTH_800;
+ break;
+
+ case 1024:
+ c |= DEC_WIDTH_1024;
+ break;
+
+ case 1152:
+ c |= DEC_WIDTH_1152;
+ break;
+
+ case 1280:
+ c |= DEC_WIDTH_1280;
+ break;
+
+ case 1600:
+ c |= DEC_WIDTH_1600;
+ break;
+ }
+
+ pApm->Setup_DEC = (pApm->Setup_DEC & ~(DEC_BITDEPTH_MASK|DEC_WIDTH_MASK)) | c;
+ pApm->displayWidth = pScrn->display->virtualX;
+ pApm->displayHeight = pScrn->display->virtualY;
+ pApm->bitsPerPixel = pScrn->bitsPerPixel;
+ pApm->bytesPerScanline= (pApm->displayWidth * pApm->bitsPerPixel) >> 3;
+
+ return TRUE;
+}
+
+
+
+static int
+ApmGetViewport(
+ ScrnInfoPtr pScrn
+)
+{
+ return 0;
+}
+
+static void
+ApmSetViewport(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int flags
+)
+{
+ APMDECL(pScrn);
+
+ if (pApm->apmLock) {
+ /*
+ * This is just an attempt, because Daryll is tampering with MY
+ * registers.
+ */
+ if (!pApm->noLinear) {
+ WRXB(0xDB, (RDXB(0xDB) & 0xF4) | 0x0A);
+ ApmWriteSeq(0x1B, 0x20);
+ ApmWriteSeq(0x1C, 0x2F);
+ }
+ else {
+ unsigned char tmp = RDXB_IOP(0xDB);
+ WRXB_IOP(0xDB, (tmp & 0xF4) | 0x0A);
+ wrinx(0x3C4, 0x1B, 0x20);
+ wrinx(0x3C4, 0x1C, 0x2F);
+ }
+ pApm->apmLock = FALSE;
+ }
+ pScrn->AdjustFrame(pScrn->pScreen->myNum, x, y, flags);
+ if (pApm->VGAMap) {
+ /* Wait until vertical retrace is in progress. */
+ while (APMVGAB(0x3DA) & 0x08);
+ while (!(APMVGAB(0x3DA) & 0x08));
+ }
+ else {
+ /* Wait until vertical retrace is in progress. */
+ while (inb(0x3DA) & 0x08);
+ while (!(inb(0x3DA) & 0x08));
+ }
+}
+
+static void
+ApmFillRect (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned long color
+)
+{
+ APMDECL(pScrn);
+
+ if(pApm->AccelInfoRec) {
+ (*pApm->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
+ (*pApm->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ SET_SYNC_FLAG(pApm->AccelInfoRec);
+ }
+}
+
+static void
+ApmBlitRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty
+)
+{
+ APMDECL(pScrn);
+
+ if(pApm->AccelInfoRec) {
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ (*pApm->AccelInfoRec->SetupForScreenToScreenCopy)(
+ pScrn, xdir, ydir, GXcopy, ~0, -1);
+ (*pApm->AccelInfoRec->SubsequentScreenToScreenCopy)(
+ pScrn, srcx, srcy, dstx, dsty, w, h);
+ SET_SYNC_FLAG(pApm->AccelInfoRec);
+ }
+}
+
+static void
+ApmBlitTransRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty,
+ unsigned long color
+)
+{
+ APMDECL(pScrn);
+
+ if(pApm->AccelInfoRec) {
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ (*pApm->AccelInfoRec->SetupForScreenToScreenCopy)(
+ pScrn, xdir, ydir, GXcopy, ~0, (int)color);
+ (*pApm->AccelInfoRec->SubsequentScreenToScreenCopy)(
+ pScrn, srcx, srcy, dstx, dsty, w, h);
+ SET_SYNC_FLAG(pApm->AccelInfoRec);
+ }
+}
+
+static Bool
+ApmOpenFramebuffer(
+ ScrnInfoPtr pScrn,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *flags
+)
+{
+ APMDECL(pScrn);
+
+ *name = NULL; /* no special device */
+ *mem = (unsigned char*)(pApm->LinAddress +
+ 0*((char *)pApm->FbBase - (char *)pApm->LinMap));
+ *size = pScrn->videoRam << 10;
+ *offset = 0;
+ *flags = DGA_NEED_ROOT;
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_driver.c
new file mode 100644
index 000000000..f1c1422eb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_driver.c
@@ -0,0 +1,2068 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/apm/apm_driver.c,v 1.20 1999/08/28 09:00:58 dawes Exp $ */
+
+
+#include "apm.h"
+#include "xf86cmap.h"
+#include "xf86Resources.h"
+
+#include "compiler.h"
+
+#ifdef DPMSExtension
+#include "opaque.h"
+#include "extensions/dpms.h"
+#endif
+
+#define VERSION 4000
+#define APM_NAME "APM"
+#define APM_DRIVER_NAME "apm"
+#define APM_MAJOR_VERSION 1
+#define APM_MINOR_VERSION 0
+#define APM_PATCHLEVEL 0
+#ifndef PCI_CHIP_AT3D
+#define PCI_CHIP_AT3D 0x643D
+#endif
+
+/* bytes to save for text/font data */
+#define TEXT_AMOUNT 32768
+
+/* Mandatory functions */
+static void ApmIdentify(int flags);
+static Bool ApmProbe(DriverPtr drv, int flags);
+static Bool ApmPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool ApmScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool ApmSwitchMode(int scrnIndex, DisplayModePtr mode,
+ int flags);
+static void ApmAdjustFrame(int scrnIndex, int x, int y, int flags);
+static Bool ApmEnterVT(int scrnIndex, int flags);
+static void ApmLeaveVT(int scrnIndex, int flags);
+static Bool ApmCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static void ApmFreeScreen(int scrnIndex, int flags);
+static int ApmValidMode(int scrnIndex, DisplayModePtr mode,
+ Bool verbose, int flags);
+static Bool ApmSaveScreen(ScreenPtr pScreen, Bool unblank);
+static void ApmUnlock(ApmPtr pApm);
+static void ApmLock(ApmPtr pApm);
+static void ApmRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg,
+ ApmRegPtr ApmReg);
+static void ApmLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual);
+#ifdef DPMSExtension
+static void ApmDisplayPowerManagementSet(ScrnInfoPtr pScrn,
+ int PowerManagementMode,
+ int flags);
+#endif
+
+
+int ApmPixmapIndex = -1;
+
+DriverRec APM = {
+ VERSION,
+ "Driver for the Alliance chipsets",
+ ApmIdentify,
+ ApmProbe,
+ NULL,
+ 0
+};
+
+static SymTabRec ApmChipsets[] = {
+ { AP6422, "AP6422" },
+ { AT24, "AT24" },
+ { AT3D, "AT3D" },
+ { -1, NULL }
+};
+
+static PciChipsets ApmPciChipsets[] = {
+ { PCI_CHIP_AP6422, PCI_CHIP_AP6422, RES_SHARED_VGA },
+ { PCI_CHIP_AT24, PCI_CHIP_AT24, RES_SHARED_VGA },
+ { PCI_CHIP_AT3D, PCI_CHIP_AT3D, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED }
+};
+
+static IsaChipsets ApmIsaChipsets[] = {
+ { PCI_CHIP_AP6422, RES_EXCLUSIVE_VGA},
+ {-1, RES_UNDEFINED}
+};
+
+#ifdef XFree86LOADER
+#endif
+
+typedef enum {
+ OPTION_SET_MCLK,
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+ OPTION_NOLINEAR,
+ OPTION_NOACCEL,
+ OPTION_SHADOW_FB,
+ OPTION_PCI_BURST,
+ OPTION_PCI_RETRY
+} ApmOpts;
+
+static OptionInfoRec ApmOptions[] =
+{
+ {OPTION_SET_MCLK, "SetMclk", OPTV_FREQ,
+ {0}, FALSE},
+ {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_NOLINEAR, "NoLinear", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_PCI_BURST, "pci_burst", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {-1, NULL, OPTV_NONE,
+ {0}, FALSE}
+};
+
+/*
+ * List of symbols from other modules that this module references. This
+ * list is used to tell the loader that it is OK for symbols here to be
+ * unresolved providing that it hasn't been told that they haven't been
+ * told that they are essential via a call to xf86LoaderReqSymbols() or
+ * xf86LoaderReqSymLists(). The purpose is this is to avoid warnings about
+ * unresolved symbols that are not required.
+ */
+
+static const char *vgahwSymbols[] = {
+ "vgaHWBlankScreen",
+ "vgaHWCursor",
+ "vgaHWFreeHWRec",
+ "vgaHWGetHWRec",
+ "vgaHWGetIOBase",
+ "vgaHWInit",
+ "vgaHWLock",
+ "vgaHWMapMem",
+ "vgaHWProtect",
+ "vgaHWRestore",
+ "vgaHWSave",
+ "vgaHWSaveScreen",
+ "vgaHWSetMmioFuncs",
+ "vgaHWUnlock",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAACreateInfoRec",
+ "XAACursorInfoRec",
+ "XAACursorInit",
+ "XAADestroyInfoRec",
+ "XAAInit",
+ "XAAQueryBestSize",
+ "XAARestoreCursor",
+ "XAAScreenIndex",
+ "XAAStippleScanlineFuncMSBFirst",
+ "XAAWarpCursor",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86InitCursor",
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ NULL
+};
+
+static const char *ddcSymbols[] = {
+ "xf86PrintEDID",
+ "xf86DoEDID_DDC2",
+ NULL
+};
+
+static const char *i2cSymbols[] = {
+ "xf86CreateI2CBusRec",
+ "xf86I2CBusInit",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+
+#ifdef XFree86LOADER
+
+static const char *cfbSymbols[] = {
+ "xf1bppScreenInit",
+ "xf4bppScreenInit",
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb24ScreenInit",
+ "cfb32ScreenInit",
+ NULL
+};
+
+static XF86ModuleVersionInfo apmVersRec = {
+ "Alliance Promotion",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ APM_MAJOR_VERSION, APM_MINOR_VERSION, APM_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+static MODULESETUPPROTO(apmSetup);
+
+/*
+ * This is the module init data.
+ * Its name has to be the driver name followed by ModuleData.
+ */
+XF86ModuleData apmModuleData = { &apmVersRec, apmSetup, NULL };
+
+static pointer
+apmSetup(pointer module, pointer opts, int *errmaj, int *errmain)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&APM, module, 0);
+
+ LoaderRefSymLists(vgahwSymbols, cfbSymbols, xaaSymbols,
+ /*xf8_32bppSymbols,*/ ramdacSymbols,
+ ddcSymbols, i2cSymbols, shadowSymbols, NULL);
+
+ return (pointer)1;
+ }
+ else {
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+#endif
+
+static Bool
+ApmGetRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate)
+ return TRUE;
+ pScrn->driverPrivate = xnfcalloc(sizeof(ApmRec), 1);
+ /* pScrn->driverPrivate != NULL at this point */
+
+ return TRUE;
+}
+
+static void
+ApmFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate) {
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+ }
+}
+
+
+/* unlock Alliance registers */
+static void
+ApmUnlock(ApmPtr pApm)
+{
+ if (!pApm->UnlockCalled) {
+ if (!pApm->noLinear) {
+ pApm->savedSR10 = ApmReadSeq(0x10);
+ pApm->xbase = (ApmReadSeq(0x1F) << 8) | ApmReadSeq(0x1E);
+ pApm->UnlockCalled = TRUE;
+ }
+ else {
+ pApm->savedSR10 = rdinx(0x3C4, 0x10);
+ pApm->xbase = (rdinx(0x3C4, 0x1F) << 8) | rdinx(0x3C4, 0x1E);
+ pApm->UnlockCalled = TRUE;
+ }
+ }
+ if (!pApm->noLinear) {
+ ApmWriteSeq(0x10, 0x12);
+ }
+ else {
+ wrinx(0x3C4, 0x10, 0x12);
+ }
+}
+
+/* lock Alliance registers */
+static void
+ApmLock(ApmPtr pApm)
+{
+ if (pApm->UnlockCalled) {
+ if (!pApm->noLinear) {
+ ApmWriteSeq(0x10, pApm->savedSR10 ? 0 : 0x12);
+ }
+ else {
+ wrinx(0x3C4, 0x10, pApm->savedSR10 ? 0 : 0x12);
+ }
+ }
+}
+
+static void
+ApmIdentify(int flags)
+{
+ xf86PrintChipsets(APM_NAME, "driver for the Alliance chipsets",
+ ApmChipsets);
+}
+
+static int
+ApmFindIsaDevice(GDevPtr dev)
+{
+ char save = rdinx(0x3C4, 0x10);
+ int i;
+ int apmChip = -1;
+
+ /*
+ * Start by probing the VGA chipset.
+ */
+ outw(0x3C4, 0x1210);
+ if (rdinx(0x3C4, 0x11) == 'P' && rdinx(0x3C4, 0x12) == 'r' &&
+ rdinx(0x3C4, 0x13) == 'o') {
+ char id_ap6420[] = "6420";
+ char id_ap6422[] = "6422";
+ char id_at24[] = "6424";
+ char id_at3d[] = "AT3D";
+ char idstring[] = " ";
+
+ /*
+ * Must be an Alliance !!!
+ */
+ for (i = 0; i < 4; i++)
+ idstring[i] = rdinx(0x3C4, 0x14 + i);
+ if (!memcmp(id_ap6420, idstring, 4) ||
+ !memcmp(id_ap6422, idstring, 4))
+ apmChip = AP6422;
+ else if (!memcmp(id_at24, idstring, 4))
+ apmChip = AT24;
+ else if (!memcmp(id_at3d, idstring, 4))
+ apmChip = AT3D;
+ if (apmChip >= 0) {
+ int apm_xbase;
+
+ apm_xbase = (rdinx(0x3C4, 0x1F) << 8) | rdinx(0x3C4, 0x1E);
+
+ if (!(wrinx(0x3C4, 0x1D, 0xCA >> 2), inb(apm_xbase + 2))) {
+ /*
+ * TODO Not PCI
+ */
+ }
+
+ }
+ }
+ wrinx(0x3C4, 0x10, save);
+
+ return apmChip;
+}
+
+static void
+ApmAssignFPtr(ScrnInfoPtr pScrn)
+{
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = APM_DRIVER_NAME;
+ pScrn->name = APM_NAME;
+ pScrn->Probe = ApmProbe;
+ pScrn->PreInit = ApmPreInit;
+ pScrn->ScreenInit = ApmScreenInit;
+ pScrn->SwitchMode = ApmSwitchMode;
+ pScrn->AdjustFrame = ApmAdjustFrame;
+ pScrn->EnterVT = ApmEnterVT;
+ pScrn->LeaveVT = ApmLeaveVT;
+ pScrn->FreeScreen = ApmFreeScreen;
+ pScrn->ValidMode = ApmValidMode;
+}
+
+static Bool
+ApmProbe(DriverPtr drv, int flags)
+{
+ int numDevSections, numUsed, i;
+ GDevPtr *DevSections;
+ int *usedChips;
+ EntityInfoPtr pEnt;
+ int foundScreen = FALSE;
+
+ /*
+ * Check if there is a chipset override in the config file
+ */
+ if ((numDevSections = xf86MatchDevice(APM_DRIVER_NAME,
+ &DevSections)) <= 0)
+ return FALSE;
+
+ /*
+ * We need to probe the hardware first. We then need to see how this
+ * fits in with what is given in the config file, and allow the config
+ * file info to override any contradictions.
+ */
+
+ if (xf86GetPciVideoInfo() == NULL) {
+ return FALSE;
+ }
+ numUsed = xf86MatchPciInstances(APM_NAME, PCI_VENDOR_ALLIANCE,
+ ApmChipsets, ApmPciChipsets, DevSections, numDevSections,
+ drv, &usedChips);
+
+ if (numUsed > 0) {
+ for (i = 0; i < numUsed; i++) {
+ pEnt = xf86GetEntityInfo(usedChips[i]);
+
+ if (pEnt && pEnt->active) {
+ ScrnInfoPtr pScrn;
+
+ /*
+ * Allocate a ScrnInfoRec and claim the slot
+ */
+ pScrn = xf86AllocateScreen(drv, 0);
+
+ /*
+ * Fill in what we can of the ScrnInfoRec
+ */
+ ApmAssignFPtr(pScrn);
+ xf86ConfigActivePciEntity(pScrn, usedChips[i], ApmPciChipsets,
+ NULL, NULL, NULL, NULL, NULL);
+ foundScreen = TRUE;
+ }
+ xfree(pEnt);
+ }
+ }
+
+ /* Check for non-PCI cards */
+ numUsed = xf86MatchIsaInstances(APM_NAME, ApmChipsets,
+ ApmIsaChipsets, drv, ApmFindIsaDevice, DevSections,
+ numDevSections, &usedChips);
+ if (numUsed > 0)
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = xf86AllocateScreen(drv,0);
+
+ /*
+ * Fill in what we can of the ScrnInfoRec
+ */
+ ApmAssignFPtr(pScrn);
+ foundScreen = TRUE;
+ xf86ConfigActiveIsaEntity(pScrn, usedChips[i], ApmIsaChipsets,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+ xfree(DevSections);
+ DevSections = NULL;
+ return foundScreen;
+}
+
+/*
+ * GetAccelPitchValues -
+ *
+ * This function returns a list of display width (pitch) values that can
+ * be used in accelerated mode.
+ */
+static int *
+GetAccelPitchValues(ScrnInfoPtr pScrn)
+{
+ int *linePitches = NULL;
+ int linep[] = {640, 800, 1024, 1152, 1280, 1600, 0};
+
+ if (sizeof linep > 0) {
+ linePitches = (int *)xnfalloc(sizeof linep);
+ memcpy(linePitches, linep, sizeof linep);
+ }
+
+ return linePitches;
+}
+
+static Bool
+ApmPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ APMDECL(pScrn);
+ EntityInfoPtr pEnt;
+ MessageType from;
+ char *mod = NULL, *req = NULL;
+ ClockRangePtr clockRanges;
+ int i;
+ double real;
+
+ /*
+ * Note: This function is only called once at server startup, and
+ * not at the start of each server generation. This means that
+ * only things that are persistent across server generations can
+ * be initialised here. xf86Screens[] is (pScrn is a pointer to one
+ * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex()
+ * are too, and should be used for data that must persist across
+ * server generations.
+ *
+ * Per-generation data should be allocated with
+ * AllocateScreenPrivateIndex() from the ScreenInit() function.
+ */
+
+ /* The vgahw module should be allocated here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /*
+ * Allocate a vgaHWRec
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*
+ * The first thing we should figure out is the depth, bpp, etc.
+ */
+ if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb)) {
+ return FALSE;
+ } else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 4:
+ case 8:
+ case 15:
+ case 16:
+ case 24:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /* The gamma fields must be initialised when using the new cmap code */
+ if (pScrn->depth > 1) {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+
+ /* We use a programamble clock */
+ pScrn->progClock = TRUE;
+
+ /* Allocate the ApmRec driverPrivate */
+ if (!ApmGetRec(pScrn)) {
+ return FALSE;
+ }
+ pApm = APMPTR(pScrn);
+
+ /* Get the entity */
+ pEnt = pApm->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pApm->pEnt->location.type == BUS_PCI) {
+ pApm->PciInfo = xf86GetPciInfoForEntity(pApm->pEnt->index);
+ pApm->PciTag = pciTag(pApm->PciInfo->bus, pApm->PciInfo->device,
+ pApm->PciInfo->func);
+ }
+ else {
+ pApm->PciInfo = NULL;
+ pApm->PciTag = 0;
+ }
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ApmOptions);
+
+ pApm->scrnIndex = pScrn->scrnIndex;
+ /* Set the bits per RGB for 8bpp mode */
+ if (pScrn->depth > 1 && pScrn->depth <= 8) {
+ /* Default to 8 */
+ pScrn->rgbBits = 8;
+ }
+ if (xf86ReturnOptValBool(ApmOptions, OPTION_NOLINEAR, FALSE)) {
+ pApm->noLinear = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "No linear framebuffer\n");
+ }
+ from = X_DEFAULT;
+ pApm->hwCursor = FALSE;
+ if (xf86GetOptValBool(ApmOptions, OPTION_HW_CURSOR, &pApm->hwCursor))
+ from = X_CONFIG;
+ if (pApm->noLinear ||
+ xf86ReturnOptValBool(ApmOptions, OPTION_SW_CURSOR, FALSE)) {
+ from = X_CONFIG;
+ pApm->hwCursor = FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pApm->hwCursor ? "HW" : "SW");
+ from = X_DEFAULT;
+ if (pScrn->bitsPerPixel < 8)
+ pApm->NoAccel = TRUE;
+ if (xf86ReturnOptValBool(ApmOptions, OPTION_NOACCEL, FALSE)) {
+ from = X_CONFIG;
+ pApm->NoAccel = TRUE;
+ }
+ if (pApm->NoAccel)
+ xf86DrvMsg(pScrn->scrnIndex, from, "Acceleration disabled\n");
+ if (xf86GetOptValFreq(ApmOptions, OPTION_SET_MCLK, OPTUNITS_MHZ, &real)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MCLK used is %.1f MHz\n", real);
+ pApm->MemClk = (int)(real * 1000.0);
+ }
+ if (xf86ReturnOptValBool(ApmOptions, OPTION_SHADOW_FB, FALSE)) {
+ pApm->ShadowFB = TRUE;
+ pApm->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using \"Shadow Framebuffer\" - acceleration disabled\n");
+ }
+ if (xf86ReturnOptValBool(ApmOptions, OPTION_PCI_RETRY, FALSE)) {
+ if (xf86ReturnOptValBool(ApmOptions, OPTION_PCI_BURST, FALSE)) {
+ pApm->UsePCIRetry = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
+ }
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"pci_retry\" option requires pci_burst \"on\".\n");
+ }
+
+ /*
+ * Set the Chipset and ChipRev, allowing config file entries to
+ * override.
+ */
+ if (pEnt->device->chipset && *pEnt->device->chipset) {
+ pScrn->chipset = pEnt->device->chipset;
+ pApm->Chipset = xf86StringToToken(ApmChipsets, pScrn->chipset);
+ from = X_CONFIG;
+ } else if (pEnt->device->chipID >= 0) {
+ pApm->Chipset = pEnt->device->chipID;
+ pScrn->chipset = (char *)xf86TokenToString(ApmChipsets, pApm->Chipset);
+
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pApm->Chipset);
+ } else {
+ from = X_PROBED;
+ if (pApm->PciInfo)
+ pApm->Chipset = pApm->PciInfo->chipType;
+ else
+ pApm->Chipset = pApm->pEnt->chipset;
+ pScrn->chipset = (char *)xf86TokenToString(ApmChipsets, pApm->Chipset);
+ }
+ if (pEnt->device->chipRev >= 0) {
+ pApm->ChipRev = pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pApm->ChipRev);
+ } else if (pApm->PciInfo) {
+ pApm->ChipRev = pApm->PciInfo->chipRev;
+ }
+
+ /*
+ * This shouldn't happen because such problems should be caught in
+ * ApmProbe(), but check it just in case.
+ */
+ if (pScrn->chipset == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ChipID 0x%04X is not recognised\n", pApm->Chipset);
+ return FALSE;
+ }
+ if (pApm->Chipset < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Chipset \"%s\" is not recognised\n", pScrn->chipset);
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
+
+ if (pEnt->device->MemBase != 0) {
+ pApm->LinAddress = pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else if (pApm->PciInfo) {
+ pApm->LinAddress = pApm->PciInfo->memBase[0] & 0xFF800000;
+ from = X_PROBED;
+ } else {
+ /*
+ * VESA local bus.
+ * Pray that 2048MB works.
+ */
+ pApm->LinAddress = 0x80000000;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pApm->LinAddress);
+
+ if (xf86LoadSubModule(pScrn, "ddc")) {
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+ if (xf86LoadSubModule(pScrn, "i2c")) {
+ xf86LoaderReqSymLists(i2cSymbols, NULL);
+ pApm->I2C = TRUE;
+ }
+ }
+
+ if (pApm->noLinear) {
+ /*
+ * TODO not AT3D.
+ * XXX ICI XXX
+ */
+ pApm->LinMapSize = 4 * 1024 * 1024 /* 0x10000 */;
+ pApm->FbMapSize = 4 * 1024 * 1024 /* 0x10000 */;
+ pApm->LinAddress += 8 * 1024 * 1024 /* 0xA0000 */;
+ }
+ else {
+ pApm->LinMapSize = 16 * 1024 * 1024;
+ pApm->FbMapSize = 4 * 1024 * 1024;
+ }
+
+ if (pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else if (!pApm->noLinear) {
+ unsigned char d9, db, uc;
+ unsigned long save;
+ volatile unsigned char *LinMap;
+
+ LinMap = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pApm->PciTag, pApm->LinAddress,
+ pApm->LinMapSize);
+ save = pciReadLong(pApm->PciTag, PCI_CMD_STAT_REG);
+ pciWriteLong(pApm->PciTag, PCI_CMD_STAT_REG, save | PCI_CMD_MEM_ENABLE);
+ d9 = LinMap[0xFFECD9];
+ db = LinMap[0xFFECDB];
+ LinMap[0xFFECDB] = (db & 0xF4) | 0x0A;
+ LinMap[0xFFECD9] = (d9 & 0xCF) | 0x20;
+ LinMap[0xFFF3C4] = 0x1C;
+ uc = LinMap[0xFFF3C5];
+ LinMap[0xFFF3C5] = 0x3F;
+ LinMap[0xFFF3C4] = 0x20;
+ pScrn->videoRam = LinMap[0xFFF3C5] * 64;
+ LinMap[0xFFF3C4] = 0x1C;
+ LinMap[0xFFF3C5] = uc;
+ LinMap[0xFFECDB] = db;
+ LinMap[0xFFECD9] = d9;
+ pciWriteLong(pApm->PciTag, PCI_CMD_STAT_REG, save);
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)LinMap, pApm->LinMapSize);
+ from = X_PROBED;
+ }
+ else {
+ unsigned long save;
+
+ save = pciReadLong(pApm->PciTag, PCI_CMD_STAT_REG);
+ pciWriteLong(pApm->PciTag, PCI_CMD_STAT_REG, save | PCI_CMD_IO_ENABLE);
+ pScrn->videoRam = rdinx(0x3C4, 0x20) * 64;
+ pciWriteLong(pApm->PciTag, PCI_CMD_STAT_REG, save);
+ from = X_PROBED;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+
+ pApm->MinClock = 23125;
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock set to %d MHz\n",
+ pApm->MinClock / 1000);
+
+ /*
+ * If the user has specified ramdac speed in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+
+ switch (pScrn->bitsPerPixel) {
+ case 4:
+ case 8:
+ speed = pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ speed = pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ speed = pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ case 32:
+ speed = pEnt->device->dacSpeeds[DAC_BPP32];
+ break;
+ }
+ if (speed == 0)
+ pApm->MaxClock = pEnt->device->dacSpeeds[0];
+ else
+ pApm->MaxClock = speed;
+ from = X_CONFIG;
+ } else {
+ switch(pApm->Chipset)
+ {
+ /* These values come from the Manual for AT24 and AT3D
+ in the overview of various modes. I've taken the largest
+ number for the different modes. Alliance wouldn't
+ tell me what the maximum frequency was, so...
+ */
+ case AT24:
+ switch(pScrn->bitsPerPixel)
+ {
+ case 4:
+ case 8:
+ pApm->MaxClock = 160000;
+ break;
+ case 16:
+ pApm->MaxClock = 144000;
+ break;
+ case 24:
+ pApm->MaxClock = 75000; /* Hmm. */
+ break;
+ case 32:
+ pApm->MaxClock = 94500;
+ break;
+ default:
+ return FALSE;
+ }
+ break;
+ case AT3D:
+ switch(pScrn->bitsPerPixel)
+ {
+ case 4:
+ case 8:
+ pApm->MaxClock = 175500;
+ break;
+ case 16:
+ pApm->MaxClock = 144000;
+ break;
+ case 24:
+ pApm->MaxClock = 94000;
+ break;
+ case 32:
+ pApm->MaxClock = 94500;
+ break;
+ default:
+ return FALSE;
+ }
+ break;
+ default:
+ pApm->MaxClock = 135000;
+ break;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
+ pApm->MaxClock / 1000);
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+ clockRanges = (ClockRangePtr)xnfalloc(sizeof(ClockRange));
+ clockRanges->next = NULL;
+ clockRanges->minClock = pApm->MinClock;
+ clockRanges->maxClock = pApm->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = FALSE; /* XXX change this */
+ clockRanges->doubleScanAllowed = FALSE; /* XXX check this */
+
+ /* Select valid modes from those available */
+ if (pApm->NoAccel) {
+ /*
+ * XXX Assuming min pitch 256, max 2048
+ * XXX Assuming min height 128, max 2048
+ */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, 256, 2048,
+ pScrn->bitsPerPixel, 128, 2048,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pApm->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+ } else {
+ /*
+ * XXX Assuming min height 128, max 2048
+ */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ GetAccelPitchValues(pScrn), 0, 0,
+ pScrn->bitsPerPixel, 128, 2048,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pApm->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+ }
+
+ if (i == -1) {
+ ApmFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ ApmFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ mod = "xf1bpp";
+ req = "xf1bppScreenInit";
+ break;
+ case 4:
+ mod = "xf4bpp";
+ req = "xf4bppScreenInit";
+ break;
+ case 8:
+ mod = "cfb";
+ req = "cfbScreenInit";
+ break;
+ case 16:
+ mod = "cfb16";
+ req = "cfb16ScreenInit";
+ break;
+ case 24:
+ mod = "cfb24";
+ req = "cfb24ScreenInit";
+ break;
+ case 32:
+ mod = "cfb32";
+ req = "cfb32ScreenInit";
+ break;
+ }
+
+ if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ ApmFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymbols(req, NULL);
+
+ /* Load XAA if needed */
+ if (!pApm->NoAccel) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ ApmFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ /* Load ramdac if needed */
+ if (pApm->hwCursor) {
+ if (!xf86LoadSubModule(pScrn, "ramdac")) {
+ ApmFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+ }
+
+ /* Load shadowfb if needed */
+ if (pApm->ShadowFB) {
+ if (!xf86LoadSubModule(pScrn, "shadowfb")) {
+ ApmFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+ }
+
+ return TRUE;
+}
+
+/*
+ * Map the framebuffer and MMIO memory.
+ */
+
+static Bool
+ApmMapMem(ScrnInfoPtr pScrn)
+{
+ APMDECL(pScrn);
+
+ pApm->LinMap = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pApm->PciTag,
+ (unsigned long)pApm->LinAddress,
+ pApm->LinMapSize);
+ if (pApm->LinMap == NULL)
+ return FALSE;
+
+ if (!pApm->noLinear) {
+ pApm->FbBase = (void *)(((char *)pApm->LinMap) + 0x800000);
+ pApm->VGAMap = ((char *)pApm->LinMap) + 0xFFF000;
+ pApm->MemMap = ((char *)pApm->LinMap) + 0xFFEC00;
+ pApm->BltMap = (void *)(((char *)pApm->LinMap) + 0x3F8000);
+
+ /*
+ * Initialize chipset
+ */
+ pApm->d9 = RDXB(0xD9);
+ pApm->db = RDXB(0xDB);
+
+ /* If you change it, change it also in apm_funcs.c */
+ WRXB(0xDB, (pApm->db & 0xF4) | 0x0A);
+ WRXB(0xD9, (pApm->d9 & 0xCF) | 0x20);
+ vgaHWSetMmioFuncs(VGAHWPTR(pScrn), (CARD8 *)pApm->LinMap, 0xFFF000);
+ }
+ else {
+ pApm->FbBase = pApm->LinMap;
+
+ /*
+ * Initialize chipset
+ */
+ pApm->d9 = RDXB_IOP(0xD9);
+ pApm->db = RDXB_IOP(0xDB);
+ WRXB_IOP(0xDB, pApm->db & 0xF4);
+ }
+
+ return TRUE;
+}
+
+/*
+ * Unmap the framebuffer and MMIO memory
+ */
+
+static Bool
+ApmUnmapMem(ScrnInfoPtr pScrn)
+{
+ APMDECL(pScrn);
+
+ if (pApm->LinMap) {
+ if (!pApm->noLinear) {
+ WRXB(0xD9, pApm->d9);
+ WRXB(0xDB, pApm->db);
+ }
+ else {
+ WRXB_IOP(0xD9, pApm->d9);
+ WRXB_IOP(0xDB, pApm->db);
+ }
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pApm->LinMap, pApm->LinMapSize);
+ pApm->LinMap = NULL;
+ }
+ else if (pApm->FbBase)
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pApm->LinMap, 0x10000);
+
+ return TRUE;
+}
+
+/*
+ * This function saves the video state.
+ */
+static void
+ApmSave(ScrnInfoPtr pScrn)
+{
+ APMDECL(pScrn);
+ ApmRegPtr ApmReg = &pApm->SavedReg;
+ vgaHWPtr vgaHWP = VGAHWPTR(pScrn);
+
+ if (!pApm->noLinear) {
+ ApmReg->SEQ[0x1B] = ApmReadSeq(0x1B);
+ ApmReg->SEQ[0x1C] = ApmReadSeq(0x1C);
+
+ /*
+ * Save fonts
+ */
+ if (!(vgaHWP->SavedReg.Attribute[0x10] & 1)) {
+ if (pApm->FontInfo || (pApm->FontInfo = (pointer)xalloc(TEXT_AMOUNT))) {
+ int locked;
+
+ locked = ApmReadSeq(0x10);
+ if (locked)
+ ApmWriteSeq(0x10, 0x12);
+ ApmWriteSeq(0x1C, 0x3F);
+ memcpy(pApm->FontInfo, pApm->FbBase, TEXT_AMOUNT);
+ ApmWriteSeq(0x1C, ApmReg->SEQ[0x1C]);
+ if (locked)
+ ApmWriteSeq(0x10, 0);
+ }
+ }
+ /*
+ * This function will handle creating the data structure and filling
+ * in the generic VGA portion.
+ */
+ vgaHWSave(pScrn, &vgaHWP->SavedReg, VGA_SR_MODE | VGA_SR_CMAP);
+
+ /* Hardware cursor registers. */
+ ApmReg->EX[XR140] = RDXL(0x140);
+ ApmReg->EX[XR144] = RDXW(0x144);
+ ApmReg->EX[XR148] = RDXL(0x148);
+ ApmReg->EX[XR14C] = RDXW(0x14C);
+
+ ApmReg->CRT[0x19] = ApmReadCrtc(0x19);
+ ApmReg->CRT[0x1A] = ApmReadCrtc(0x1A);
+ ApmReg->CRT[0x1B] = ApmReadCrtc(0x1B);
+ ApmReg->CRT[0x1C] = ApmReadCrtc(0x1C);
+ ApmReg->CRT[0x1D] = ApmReadCrtc(0x1D);
+ ApmReg->CRT[0x1E] = ApmReadCrtc(0x1E);
+
+ /* RAMDAC registers. */
+ ApmReg->EX[XRE8] = RDXL(0xE8);
+ ApmReg->EX[XREC] = RDXL(0xEC);
+
+ /* Color correction */
+ ApmReg->EX[XRE0] = RDXL(0xE0);
+
+ ApmReg->EX[XR80] = RDXB(0x80);
+ }
+ else {
+ /*
+ * This function will handle creating the data structure and filling
+ * in the generic VGA portion.
+ */
+ vgaHWSave(pScrn, &vgaHWP->SavedReg, VGA_SR_ALL);
+
+ ApmReg->SEQ[0x1B] = rdinx(0x3C4, 0x1B);
+ ApmReg->SEQ[0x1C] = rdinx(0x3C4, 0x1C);
+
+ /* Hardware cursor registers. */
+ ApmReg->EX[XR140] = RDXL_IOP(0x140);
+ ApmReg->EX[XR144] = RDXW_IOP(0x144);
+ ApmReg->EX[XR148] = RDXL_IOP(0x148);
+ ApmReg->EX[XR14C] = RDXW_IOP(0x14C);
+
+ ApmReg->CRT[0x19] = rdinx(0x3D4, 0x19);
+ ApmReg->CRT[0x1A] = rdinx(0x3D4, 0x1A);
+ ApmReg->CRT[0x1B] = rdinx(0x3D4, 0x1B);
+ ApmReg->CRT[0x1C] = rdinx(0x3D4, 0x1C);
+ ApmReg->CRT[0x1D] = rdinx(0x3D4, 0x1D);
+ ApmReg->CRT[0x1E] = rdinx(0x3D4, 0x1E);
+
+ /* RAMDAC registers. */
+ ApmReg->EX[XRE8] = RDXL_IOP(0xE8);
+ ApmReg->EX[XREC] = RDXL_IOP(0xEC);
+
+ /* Color correction */
+ ApmReg->EX[XRE0] = RDXL_IOP(0xE0);
+
+ ApmReg->EX[XR80] = RDXB_IOP(0x80);
+ }
+}
+
+#define WITHIN(v,c1,c2) (((v) >= (c1)) && ((v) <= (c2)))
+
+static unsigned
+comp_lmn(ApmPtr pApm, long clock)
+{
+ int n, m, l, f;
+ double fvco;
+ double fout;
+ double fmax;
+ double fref;
+ double fvco_goal;
+ double k, c;
+
+ if (pApm->Chipset >= AT3D)
+ fmax = 400000.0;
+ else
+ fmax = 250000.0;
+
+ fref = 14318.0;
+
+ for (m = 1; m <= 5; m++)
+ {
+ for (l = 3; l >= 0; l--)
+ {
+ for (n = 8; n <= 127; n++)
+ {
+ fout = ((double)(n + 1) * fref)/((double)(m + 1) * (1 << l));
+ fvco_goal = (double)clock * (double)(1 << l);
+ fvco = fout * (double)(1 << l);
+ if (!WITHIN(fvco, 0.995*fvco_goal, 1.005*fvco_goal))
+ continue;
+ if (!WITHIN(fvco, 125000.0, fmax))
+ continue;
+ if (!WITHIN(fvco / (double)(n+1), 300.0, 300000.0))
+ continue;
+ if (!WITHIN(fref / (double)(m+1), 300.0, 300000.0))
+ continue;
+
+ /* The following formula was empirically derived by
+ matching a number of fvco values with acceptable
+ values of f.
+
+ (fvco can be 125MHz - 400MHz on AT3D)
+ (fvco can be 125MHz - 250MHz on AT24/AP6422)
+
+ The table that was measured up follows:
+
+ AT3D
+
+ fvco f
+ (125) (x-7) guess
+ 200 5-7
+ 219 4-7
+ 253 3-6
+ 289 2-5
+ 320 0-4
+ (400) (0-x) guess
+
+ AT24
+
+ fvco f
+ 126 7
+ 200 5-7
+ 211 4-7
+
+ AP6422
+
+ fvco f
+ 126 7
+ 169 5-7
+ 200 4-5
+ 211 4-5
+
+ From this, a function "f = k * fvco + c" was derived.
+
+ For AT3D, this table was measured with MCLK == 50MHz.
+ The driver has since been set to use MCLK == 57.3MHz for,
+ but I don't think that makes a difference here.
+ */
+
+ if (pApm->Chipset >= AT24)
+ {
+ k = 7.0 / (175.0 - 380.0);
+ c = -k * 380.0;
+ f = (int)(k * fvco/1000.0 + c + 0.5);
+ if (f > 7) f = 7;
+ if (f < 0) f = 0;
+ }
+
+ if (pApm->Chipset < AT24) /* i.e AP6422 */
+ {
+ c = (211.0*6.0-169.0*4.5)/(211.0-169.0);
+ k = (4.5-c)/211.0;
+ f = (int)(k * fvco/1000.0 + c + 0.5);
+ if (f > 7) f = 7;
+ if (f < 0) f = 0;
+ }
+
+ return (n << 16) | (m << 8) | (l << 2) | (f << 4);
+ }
+ }
+ }
+ xf86DrvMsg(pApm->scrnIndex, X_PROBED,
+ "Cannot find register values for clock %6.2f MHz. "
+ "Please use a (slightly) different clock.\n",
+ (double)clock / 1000.0);
+ return 0;
+}
+
+/*
+ * Initialise a new mode. This is currently still using the old
+ * "initialise struct, restore/write struct to HW" model. That could
+ * be changed.
+ */
+
+static Bool
+ApmModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ APMDECL(pScrn);
+ ApmRegPtr ApmReg = &pApm->ModeReg;
+ vgaHWPtr hwp;
+
+ /* set clockIndex to "2" for programmable clocks */
+ if (pScrn->progClock)
+ mode->ClockIndex = 2;
+
+ /* prepare standard VGA register contents */
+ if (!vgaHWInit(pScrn, mode))
+ return FALSE;
+ pScrn->vtSema = TRUE;
+ hwp = VGAHWPTR(pScrn);
+
+ memcpy(ApmReg, &pApm->SavedReg, sizeof pApm->SavedReg);
+
+ /*
+ * The APM chips have a scale factor of 8 for the
+ * scanline offset. There are four extended bit in addition
+ * to the 8 VGA bits.
+ */
+ {
+ int offset;
+
+ offset = (pScrn->displayWidth *
+ pScrn->bitsPerPixel / 8) >> 3;
+ hwp->ModeReg.CRTC[0x13] = offset;
+ /* Bit 8 resides at CR1C bits 7:4. */
+ ApmReg->CRT[0x1C] = (offset & 0xf00) >> 4;
+ }
+
+ /* Set pixel depth. */
+ switch(pScrn->bitsPerPixel)
+ {
+ case 4:
+ ApmReg->EX[XR80] = 0x01;
+ break;
+ case 8:
+ ApmReg->EX[XR80] = 0x02;
+ break;
+ case 15:
+ ApmReg->EX[XR80] = 0x0C;
+ break;
+ case 16:
+ ApmReg->EX[XR80] = 0x0D;
+ break;
+ case 24:
+ ApmReg->EX[XR80] = 0x0E;
+ break;
+ case 32:
+ ApmReg->EX[XR80] = 0x0F;
+ break;
+ default:
+ FatalError("Unsupported bit depth %d\n", pScrn->bitsPerPixel);
+ break;
+ }
+
+ /* Set banking register to zero. */
+ ApmReg->EX[XRC0] = 0;
+
+ /* Handle the CRTC overflow bits. */
+ {
+ unsigned char val;
+ /* Vertical Overflow. */
+ val = 0;
+ if ((mode->CrtcVTotal - 2) & 0x400)
+ val |= 0x01;
+ if ((mode->CrtcVDisplay - 1) & 0x400)
+ val |= 0x02;
+ /* VBlankStart is equal to VSyncStart + 1. */
+ if (mode->CrtcVSyncStart & 0x400)
+ val |= 0x04;
+ /* VRetraceStart is equal to VSyncStart + 1. */
+ if (mode->CrtcVSyncStart & 0x400)
+ val |= 0x08;
+ ApmReg->CRT[0x1A] = val;
+
+ /* Horizontal Overflow. */
+ val = 0;
+ if ((mode->CrtcHTotal / 8 - 5) & 0x100)
+ val |= 1;
+ if ((mode->CrtcHDisplay / 8 - 1) & 0x100)
+ val |= 2;
+ /* HBlankStart is equal to HSyncStart - 1. */
+ if ((mode->CrtcHSyncStart / 8 - 1) & 0x100)
+ val |= 4;
+ /* HRetraceStart is equal to HSyncStart. */
+ if ((mode->CrtcHSyncStart / 8) & 0x100)
+ val |= 8;
+ ApmReg->CRT[0x1B] = val;
+
+ /* Assume the CRTC is not KGA (see vgaHWInit) */
+ hwp->ModeReg.CRTC[3] = (hwp->ModeReg.CRTC[3] & 0xE0) |
+ (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F);
+ hwp->ModeReg.CRTC[5] = ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2)
+ | (hwp->ModeReg.CRTC[5] & 0x7F);
+ hwp->ModeReg.CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF;
+ }
+ ApmReg->CRT[0x1E] = 1; /* disable autoreset feature */
+
+ /* Program clock select. */
+ ApmReg->EX[XREC] = comp_lmn(pApm, mode->Clock);
+ if (!ApmReg->EX[XREC])
+ return FALSE;
+ hwp->ModeReg.MiscOutReg |= 0x0C;
+
+ /* Set up the RAMDAC registers. */
+
+ if (pScrn->bitsPerPixel > 8)
+ /* Get rid of white border. */
+ hwp->ModeReg.Attribute[0x11] = 0x00;
+ else
+ hwp->ModeReg.Attribute[0x11] = 0xFF;
+ if (pApm->MemClk)
+ ApmReg->EX[XRE8] = comp_lmn(pApm, pApm->MemClk);
+ else if (pApm->Chipset >= AT3D)
+ ApmReg->EX[XRE8] = 0x071F01E8; /* Enable 58MHz MCLK (actually 57.3 MHz)
+ This is what is used in the Windows
+ drivers. The BIOS sets it to 50MHz. */
+ else if (!pApm->noLinear)
+ ApmReg->EX[XRE8] = RDXL(0xE8); /* No change */
+ else
+ ApmReg->EX[XRE8] = RDXL_IOP(0xE8); /* No change */
+
+ ApmReg->EX[XRE0] = 0x10;
+
+ /* If you change it, change in apm_funcs.c as well */
+ ApmReg->SEQ[0x1B] = 0x20;
+ ApmReg->SEQ[0x1C] = 0x2F;
+
+ /* ICICICICI */
+ ApmRestore(pScrn, &hwp->ModeReg, ApmReg);
+
+ if (xf86IsPc98())
+ outb(0xfac, 0xff);
+
+ return TRUE;
+}
+
+/*
+ * Restore the initial mode.
+ */
+static void
+ApmRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, ApmRegPtr ApmReg)
+{
+ APMDECL(pScrn);
+
+ vgaHWProtect(pScrn, TRUE);
+ ApmUnlock(pApm);
+
+ if (pApm->LinMap) {
+ /*
+ * Restore fonts
+ */
+ if (!(vgaReg->Attribute[0x10] & 1) && pApm->FontInfo) {
+ ApmWriteSeq(0x1C, 0x3F);
+ memcpy(pApm->FbBase, pApm->FontInfo, TEXT_AMOUNT);
+ }
+
+ /* Set aperture index to 0. */
+ WRXW(0xC0, 0);
+
+ /*
+ * Write the extended registers first
+ */
+ ApmWriteSeq(0x1B, ApmReg->SEQ[0x1B]);
+ ApmWriteSeq(0x1C, ApmReg->SEQ[0x1C]);
+
+ /* Hardware cursor registers. */
+ WRXL(0x140, ApmReg->EX[XR140]);
+ WRXW(0x144, ApmReg->EX[XR144]);
+ WRXL(0x148, ApmReg->EX[XR148]);
+ WRXW(0x14C, ApmReg->EX[XR14C]);
+
+ ApmWriteCrtc(0x19, ApmReg->CRT[0x19]);
+ ApmWriteCrtc(0x1A, ApmReg->CRT[0x1A]);
+ ApmWriteCrtc(0x1B, ApmReg->CRT[0x1B]);
+ ApmWriteCrtc(0x1C, ApmReg->CRT[0x1C]);
+ ApmWriteCrtc(0x1D, ApmReg->CRT[0x1D]);
+ ApmWriteCrtc(0x1E, ApmReg->CRT[0x1E]);
+
+ /* RAMDAC registers. */
+ WRXL(0xE8, ApmReg->EX[XRE8]);
+ WRXL(0xEC, ApmReg->EX[XREC] & ~(1 << 7));
+ WRXL(0xEC, ApmReg->EX[XREC] | (1 << 7)); /* Do a PLL resync */
+
+ /* Color correction */
+ WRXL(0xE0, ApmReg->EX[XRE0]);
+
+ WRXB(0x80, ApmReg->EX[XR80]);
+
+ /*
+ * This function handles restoring the generic VGA registers.
+ */
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_CMAP);
+ }
+ else {
+ /* Set aperture index to 0. */
+ WRXW_IOP(0xC0, 0);
+
+ /*
+ * Write the extended registers first
+ */
+ wrinx(0x3C4, 0x1B, ApmReg->SEQ[0x1B]);
+ wrinx(0x3C4, 0x1C, ApmReg->SEQ[0x1C]);
+
+ /* Hardware cursor registers. */
+ WRXL_IOP(0x140, ApmReg->EX[XR140]);
+ WRXW_IOP(0x144, ApmReg->EX[XR144]);
+ WRXL_IOP(0x148, ApmReg->EX[XR148]);
+ WRXW_IOP(0x14C, ApmReg->EX[XR14C]);
+
+ wrinx(0x3D4, 0x19, ApmReg->CRT[0x19]);
+ wrinx(0x3D4, 0x1A, ApmReg->CRT[0x1A]);
+ wrinx(0x3D4, 0x1B, ApmReg->CRT[0x1B]);
+ wrinx(0x3D4, 0x1C, ApmReg->CRT[0x1C]);
+ wrinx(0x3D4, 0x1D, ApmReg->CRT[0x1D]);
+ wrinx(0x3D4, 0x1E, ApmReg->CRT[0x1E]);
+
+ /* RAMDAC registers. */
+ WRXL_IOP(0xE8, ApmReg->EX[XRE8]);
+ WRXL_IOP(0xEC, ApmReg->EX[XREC] & ~(1 << 7));
+ WRXL_IOP(0xEC, ApmReg->EX[XREC] | (1 << 7)); /* Do a PLL resync */
+
+ /* Color correction */
+ WRXL_IOP(0xE0, ApmReg->EX[XRE0]);
+
+ WRXB_IOP(0x80, ApmReg->EX[XR80]);
+
+ /*
+ * This function handles restoring the generic VGA registers.
+ */
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+ }
+
+ vgaHWProtect(pScrn, FALSE);
+}
+
+
+/* Refresh a region of the shadow framebuffer to the screen */
+static void
+ApmRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ APMDECL(pScrn);
+ int width, height, Bpp, FBPitch;
+ unsigned char *src, *dst;
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ FBPitch = pScrn->displayWidth * Bpp;
+
+ while(num--) {
+ width = (pbox->x2 - pbox->x1) * Bpp;
+ height = pbox->y2 - pbox->y1;
+ src = pApm->ShadowPtr + (pbox->y1 * pApm->ShadowPitch) +
+ (pbox->x1 * Bpp);
+ dst = (unsigned char *)pApm->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
+
+ while(height--) {
+ memcpy(dst, src, width);
+ dst += FBPitch;
+ src += pApm->ShadowPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+/* Mandatory */
+
+/* This gets called at the start of each server generation */
+
+static unsigned int
+ddc1Read(ScrnInfoPtr pScrn)
+{
+ APMDECL(pScrn);
+
+ WRXB(0xD0, RDXB(0xD0) & 0x07);
+ while (APMVGAB(0x3DA) & 0x08);
+ while (!(APMVGAB(0x3DA) & 0x08));
+ return (STATUS() & STATUS_SDA) != 0;
+}
+
+static Bool
+ApmScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ APMDECL(pScrn);
+ int ret;
+ unsigned char *FbBase;
+
+ /* Map the chip memory and MMIO areas */
+ if (pApm->noLinear) {
+ pApm->saveCmd = pciReadLong(pApm->PciTag, PCI_CMD_STAT_REG);
+ pciWriteLong(pApm->PciTag, PCI_CMD_STAT_REG, pApm->saveCmd | (PCI_CMD_IO_ENABLE|PCI_CMD_MEM_ENABLE));
+ pApm->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pApm->PciTag, 0xA0000, 0x10000);
+ }
+ else
+ if (!ApmMapMem(pScrn))
+ return FALSE;
+
+ /* No memory reserved yet */
+ pApm->OffscreenReserved = 0;
+
+ /* Save the current state */
+ ApmSave(pScrn);
+
+ /* Initialise the first mode */
+ ApmModeInit(pScrn, pScrn->currentMode);
+
+ /* Darken the screen for aesthetic reasons and set the viewport */
+ ApmSaveScreen(pScreen, FALSE);
+ ApmAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * XXX NOTE: cfbScreenInit() will not result in the default visual
+ * being set correctly when there is a screen-specific value given
+ * in the config file as opposed to a global value given on the
+ * command line. Saving and restoring 'defaultColorVisualClass'
+ * around the fb's ScreenInit() solves this problem.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset cfb's visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ /*
+ * For bpp > 8, the default visuals are not acceptable because we only
+ * support TrueColor and not DirectColor. To deal with this, call
+ * miSetVisualTypes for each visual supported.
+ */
+
+ if (pScrn->bitsPerPixel > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
+ pScrn->defaultVisual))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+
+ if(pApm->ShadowFB) {
+ pApm->ShadowPitch =
+ ((pScrn->virtualX * pScrn->bitsPerPixel >> 3) + 3) & ~3L;
+ pApm->ShadowPtr = xalloc(pApm->ShadowPitch * pScrn->virtualY);
+ FbBase = pApm->ShadowPtr;
+ } else {
+ pApm->ShadowPtr = NULL;
+ FbBase = pApm->FbBase;
+ }
+
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ ret = xf1bppScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 4:
+ ret = xf4bppScreenInit(pScreen, FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 8:
+ ret = cfbScreenInit(pScreen, FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 16:
+ ret = cfb16ScreenInit(pScreen, FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 24:
+ ret = cfb24ScreenInit(pScreen, FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 32:
+ ret = cfb32ScreenInit(pScreen, FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in ApmScrnInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ if (!ret)
+ return FALSE;
+
+ miInitializeBackingStore(pScreen);
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ if (pScrn->bitsPerPixel > 8) {
+ VisualPtr visual;
+
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ /* Initialise cursor functions */
+ miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
+
+ if (pApm->hwCursor) { /* Initialize HW cursor layer */
+ if (!ApmHWCursorInit(pScreen))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ }
+
+ if (!pApm->ShadowFB) { /* hardware cursor needs to wrap this layer */
+ if(!ApmDGAInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"DGA initialization failed\n");
+ }
+ }
+
+ vgaHWSetMmioFuncs(VGAHWPTR(pScrn), (CARD8 *)pApm->LinMap, 0xFFF000);
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ VGAHWPTR(pScrn)->MapSize = 0x10000;
+ vgaHWMapMem(pScrn);
+ xf86PrintEDID(xf86DoEDID_DDC1(pScrn->scrnIndex,vgaHWddc1SetSpeed,ddc1Read));
+ if (pApm->I2C) {
+ if (!ApmI2CInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"I2C initialization failed\n");
+ }
+ else {
+ xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,pApm->I2CPtr));
+ }
+ }
+
+ /*
+ * Initialize the acceleration interface.
+ */
+ if (!pApm->NoAccel) {
+ if (!ApmAccelInit(pScreen)) { /* set up XAA interface */
+ return FALSE;
+ }
+ }
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ /*
+ * Initialize colormap layer.
+ * Must follow initialization of the default colormap.
+ */
+ if (!xf86HandleColormaps(pScreen, 256, 8, ApmLoadPalette, NULL,
+ CMAP_RELOAD_ON_MODE_SWITCH)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Colormap initialization failed\n");
+ return FALSE;
+ }
+
+ if (pApm->ShadowFB)
+ ShadowFBInit(pScreen, ApmRefreshArea);
+
+#ifdef DPMSExtension
+ xf86DPMSInit(pScreen, ApmDisplayPowerManagementSet, 0);
+#endif
+
+ pScreen->SaveScreen = ApmSaveScreen;
+
+ pApm->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = ApmCloseScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ if (pApm->Generation != serverGeneration) {
+ if ((ApmPixmapIndex = AllocatePixmapPrivateIndex()) < 0)
+ return FALSE;
+ }
+
+ if (!AllocatePixmapPrivate(pScreen, ApmPixmapIndex, sizeof(ApmPixmapRec)))
+ return FALSE;
+
+ /* Done */
+ return TRUE;
+}
+
+/* mandatory */
+static void
+ApmLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
+ VisualPtr pVisual)
+{
+ APMDECL(pScrn);
+ int i, index, last = -1;
+
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ if (index != last)
+ ApmWriteDacWriteAddr(index);
+ last = index + 1;
+ ApmWriteDacData(colors[index].red);
+ ApmWriteDacData(colors[index].green);
+ ApmWriteDacData(colors[index].blue);
+ }
+}
+
+/* Usually mandatory */
+static Bool
+ApmSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return ApmModeInit(xf86Screens[scrnIndex], mode);
+}
+
+/*
+ * This function is used to initialize the Start Address - the first
+ * displayed location in the video memory.
+ */
+/* Usually mandatory */
+static void
+ApmAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ APMDECL(pScrn);
+ int Base;
+
+ if (pScrn->bitsPerPixel == 24)
+ x = (x + 3) & ~3;
+ Base = ((y * pScrn->displayWidth + x) * (pScrn->bitsPerPixel / 8)) >> 2;
+ /*
+ * These are the generic starting address registers.
+ */
+ if (pApm->VGAMap) {
+ ApmWriteCrtc(0x0C, Base >> 8);
+ ApmWriteCrtc(0x0D, Base);
+
+ /*
+ * Here the high-order bits are masked and shifted, and put into
+ * the appropriate extended registers.
+ */
+ ApmWriteCrtc(0x1C, (ApmReadCrtc(0x1C) & 0xF0) | ((Base & 0x0F0000) >> 16));
+ }
+ else {
+ outw(0x3D4, (Base & 0x00FF00) | 0x0C);
+ outw(0x3D4, ((Base & 0x00FF) << 8) | 0x0D);
+
+ /*
+ * Here the high-order bits are masked and shifted, and put into
+ * the appropriate extended registers.
+ */
+ modinx(0x3D4, 0x1C, 0x0F, (Base & 0x0F0000) >> 16);
+ }
+}
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ *
+ * We may wish to unmap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static Bool
+ApmEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ APMDECL(pScrn);
+
+ if (!pApm->noLinear) {
+ /* If you change it, change it also in apm_funcs.c */
+ WRXB(0xDB, (pApm->db & 0xF4) | 0x0A);
+ WRXB(0xD9, (pApm->d9 & 0xCF) | 0x20);
+ }
+ else
+ WRXB_IOP(0xDB, pApm->db & 0xF4);
+ ApmUnlock(APMPTR(pScrn));
+ vgaHWUnlock(VGAHWPTR(pScrn));
+ /* Should we re-save the text mode on each VT enter? */
+ if (!ApmModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Mandatory */
+static void
+ApmLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ APMDECL(pScrn);
+
+ ApmRestore(pScrn, &VGAHWPTR(pScrn)->SavedReg, &pApm->SavedReg);
+ vgaHWLock(VGAHWPTR(pScrn));
+ ApmLock(pApm);
+ if (!pApm->noLinear) {
+ WRXB(0xD9, pApm->d9);
+ WRXB(0xDB, pApm->db);
+ }
+ else {
+ WRXB_IOP(0xD9, pApm->d9);
+ WRXB_IOP(0xDB, pApm->db);
+ }
+
+ if (xf86IsPc98())
+ outb(0xfac, 0xfe);
+}
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode. It should really also unmap the video memory too.
+ */
+
+/* Mandatory */
+static Bool
+ApmCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ APMDECL(pScrn);
+
+ if (pScrn->vtSema) {
+ ApmRestore(pScrn, &VGAHWPTR(pScrn)->SavedReg, &pApm->SavedReg);
+ vgaHWLock(hwp);
+ ApmUnmapMem(pScrn);
+ }
+ if(pApm->AccelInfoRec)
+ XAADestroyInfoRec(pApm->AccelInfoRec);
+ pApm->AccelInfoRec = NULL;
+ if(pApm->CursorInfoRec)
+ xf86DestroyCursorInfoRec(pApm->CursorInfoRec);
+ pApm->CursorInfoRec = NULL;
+ if (pApm->DGAModes)
+ xfree(pApm->DGAModes);
+ if (pApm->I2CPtr)
+ xf86DestroyI2CBusRec(pApm->I2CPtr, TRUE, TRUE);
+ pApm->I2CPtr = NULL;
+
+ pScrn->vtSema = FALSE;
+
+ if (xf86IsPc98())
+ outb(0xfac, 0xfe);
+
+ pScreen->CloseScreen = pApm->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+/* Free up any per-generation data structures */
+
+/* Optional */
+static void
+ApmFreeScreen(int scrnIndex, int flags)
+{
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ ApmFreeRec(xf86Screens[scrnIndex]);
+}
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+/* Optional */
+static int
+ApmValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ if (mode->Flags & V_INTERLACE)
+ return(MODE_BAD);
+
+ return(MODE_OK);
+}
+
+
+/*
+ * ApmDisplayPowerManagementSet --
+ *
+ * Sets VESA Display Power Management Signaling (DPMS) Mode.
+ */
+#ifdef DPMSExtension
+static void
+ApmDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
+ int flags)
+{
+ APMDECL(pScrn);
+ unsigned char dpmsreg, tmp;
+
+ switch (PowerManagementMode)
+ {
+ case DPMSModeOn:
+ /* Screen: On; HSync: On, VSync: On */
+ dpmsreg = 0x00;
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off; HSync: Off, VSync: On */
+ dpmsreg = 0x01;
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off; HSync: On, VSync: Off */
+ dpmsreg = 0x02;
+ break;
+ case DPMSModeOff:
+ /* Screen: Off; HSync: Off, VSync: Off */
+ dpmsreg = 0x03;
+ break;
+ default:
+ dpmsreg = 0;
+ }
+ if (pApm->noLinear) {
+ tmp = RDXB_IOP(0xD0);
+ WRXB_IOP(0xD0, (tmp & 0xFC) | dpmsreg);
+ } else {
+ tmp = RDXB(0xD0);
+ WRXB(0xD0, (tmp & 0xFC) | dpmsreg);
+ }
+}
+#endif
+
+static Bool
+ApmSaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if (unblank)
+ SetTimeSinceLastInputEvent();
+
+ if (pScrn->vtSema)
+ vgaHWBlankScreen(pScrn, unblank);
+ return TRUE;
+}
+
+
+unsigned char _L_ACR(unsigned char *x);
+unsigned char _L_ACR(unsigned char *x)
+{
+ return *x;
+}
+
+unsigned short _L_ASR(unsigned short *x);
+unsigned short _L_ASR(unsigned short *x)
+{
+ return *x;
+}
+
+unsigned int _L_AIR(unsigned int *x);
+unsigned int _L_AIR(unsigned int *x)
+{
+ return *x;
+}
+
+void _L_ACW(char *x, char y);
+void _L_ACW(char *x, char y)
+{
+ *x = y;
+}
+
+void _L_ASW(short *x, short y);
+void _L_ASW(short *x, short y)
+{
+ *x = y;
+}
+
+void _L_AIW(int *x, int y);
+void _L_AIW(int *x, int y)
+{
+ *x = y;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_funcs.c b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_funcs.c
new file mode 100644
index 000000000..b384a547a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_funcs.c
@@ -0,0 +1,1062 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/apm/apm_funcs.c,v 1.6 1999/08/29 13:29:55 dawes Exp $ */
+
+#undef DEBUG
+#define FASTER
+#ifdef IOP_ACCESS
+# if defined(PSZ) && (PSZ == 24)
+# define A(s) Apm##s##24##_IOP
+# else
+# define A(s) Apm##s##_IOP
+# endif
+# undef RDXB
+# undef RDXW
+# undef RDXL
+# undef WRXB
+# undef WRXW
+# undef WRXL
+# undef ApmWriteSeq
+# define RDXB RDXB_IOP
+# define RDXW RDXW_IOP
+# define RDXL RDXL_IOP
+# define WRXB WRXB_IOP
+# define WRXW WRXW_IOP
+# define WRXL WRXL_IOP
+# define ApmWriteSeq(i, v) wrinx(0x3C4, i, v)
+# ifdef DEBUG
+# if defined(PSZ) && (PSZ == 24)
+# define DPRINTNAME(s) do { ErrorF("Apm" #s "24_IOP\n"); fflush(stderr); sync(); } while (0)
+# else
+# define DPRINTNAME(s) do { ErrorF("Apm" #s "_IOP\n"); fflush(stderr); sync(); } while (0)
+# endif
+# endif
+#else
+# if defined(PSZ) && (PSZ == 24)
+# define A(s) Apm##s##24
+# else
+# define A(s) Apm##s
+# endif
+# ifdef DEBUG
+# if defined(PSZ) && (PSZ == 24)
+# define DPRINTNAME(s) do { ErrorF("Apm" #s "24\n"); fflush(stderr); sync(); } while (0)
+# else
+# define DPRINTNAME(s) do { ErrorF("Apm" #s "\n"); fflush(stderr); sync(); usleep(100000); } while (0)
+# endif
+# endif
+#endif
+#ifndef DEBUG
+# define DPRINTNAME(s) /**/
+#endif
+
+/* Defines */
+#define MAXLOOP 1000000
+
+
+/* Local functions */
+static void A(Sync)(ScrnInfoPtr pScrn);
+static void A(SetupForSolidFill)(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+static void A(SubsequentSolidFillRect)(ScrnInfoPtr pScrn, int x, int y, int w, int h);
+static void A(SetupForScreenToScreenCopy)(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, unsigned int planemask,
+ int transparency_color);
+static void A(SubsequentScreenToScreenCopy)(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w, int h);
+#if !defined(PSZ) || PSZ != 24
+static void A(SetupForCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int bg, int fg, int rop, unsigned int planemask);
+static void A(SubsequentCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft);
+static void A(SetupForScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void A(SetupForImageWrite)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int trans_color,
+ int bpp, int depth);
+static void A(SubsequentImageWriteRect)(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h, int skipleft);
+static void A(SubsequentScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h,
+ int srcx, int srcy,
+ int offset);
+static void A(SubsequentSolidBresenhamLine)(ScrnInfoPtr pScrn, int x1, int y1, int octant, int err, int e1, int e2, int length);
+static void A(SetClippingRectangle)(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2);
+static void A(WritePixmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int rop,
+ unsigned int planemask, int trans, int bpp,
+ int depth);
+static void A(SetupForMono8x8PatternFill)(ScrnInfoPtr pScrn, int patx, int paty,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void A(SubsequentMono8x8PatternFillRect)(ScrnInfoPtr pScrn, int patx,
+ int paty, int x, int y,
+ int w, int h);
+static void A(SetupForColor8x8PatternFill)(ScrnInfoPtr pScrn,int patx,int paty,
+ int rop, unsigned int planemask,
+ int transparency_color);
+static void A(SubsequentColor8x8PatternFillRect)(ScrnInfoPtr pScrn, int patx,
+ int paty, int x, int y,
+ int w, int h);
+#endif
+
+/* Inline functions */
+static __inline__ void
+A(WaitForFifo)(ApmPtr pApm, int slots)
+{
+ if (!pApm->UsePCIRetry) {
+ volatile int i;
+
+ for(i = 0; i < MAXLOOP; i++) {
+ if ((STATUS() & STATUS_FIFO) >= slots)
+ break;
+ }
+ if (i == MAXLOOP) {
+ apm_stopit();
+ FatalError("Hung in WaitForFifo() (Status = 0x%08X)\n", STATUS());
+ }
+ }
+}
+
+static __inline__ void
+A(CheckMMIO_InitFast)(ScrnInfoPtr pScrn)
+{
+ if (!APMPTR(pScrn)->apmMMIO_Init)
+ A(CheckMMIO_Init)(pScrn);
+}
+
+
+static void
+A(SetupForSolidFill)(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ APMDECL(pScrn);
+
+ DPRINTNAME(SetupForSolidFill);
+ A(CheckMMIO_InitFast)(pScrn);
+#ifdef FASTER
+ A(WaitForFifo)(pApm, 3 + pApm->apmClip);
+ SETDEC(DEC_QUICKSTART_ONDIMX | DEC_OP_RECT | DEC_DEST_UPD_TRCORNER |
+ pApm->Setup_DEC);
+#else
+ A(WaitForFifo)(pApm, 2 + pApm->apmClip);
+#endif
+ SETFOREGROUNDCOLOR(color);
+
+ if (pApm->apmClip) {
+ SETCLIP_CTRL(0);
+ pApm->apmClip = FALSE;
+ }
+
+ SETROP(apmROP[rop]);
+}
+
+static void
+A(SubsequentSolidFillRect)(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ APMDECL(pScrn);
+
+ DPRINTNAME(SubsequentSolidFillRect);
+#if defined(PSZ) && (PSZ == 24)
+# ifndef FASTER
+ A(WaitForFifo)(pApm, 4);
+# else
+ A(WaitForFifo)(pApm, 3);
+# endif
+ /* COLOR */
+ SETOFFSET(3*(pApm->displayWidth - w));
+#else
+# ifndef FASTER
+ A(WaitForFifo)(pApm, 3);
+# else
+ A(WaitForFifo)(pApm, 2);
+# endif
+#endif
+ SETDESTXY(x, y);
+ SETWIDTHHEIGHT(w, h);
+ UPDATEDEST(x + w + 1, y);
+#ifndef FASTER
+ SETDEC(DEC_START | DEC_OP_RECT | DEC_DEST_UPD_TRCORNER | pApm->Setup_DEC);
+#endif
+}
+
+static void
+A(SetupForScreenToScreenCopy)(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
+ unsigned int planemask, int transparency_color)
+{
+ APMDECL(pScrn);
+
+ DPRINTNAME(SetupForScreenToScreenCopy);
+ A(CheckMMIO_InitFast)(pScrn);
+
+ if (pApm->apmLock) {
+ /*
+ * This is just an attempt, because Daryll is tampering with MY registers.
+ */
+ unsigned char tmp = RDXB(0xDB);
+ WRXB(0xDB, (tmp & 0xF4) | 0x0A);
+ ApmWriteSeq(0x1B, 0x20);
+ ApmWriteSeq(0x1C, 0x2F);
+ pApm->apmLock = FALSE;
+ }
+
+ pApm->blitxdir = xdir;
+ pApm->blitydir = ydir;
+
+ pApm->apmTransparency = (transparency_color != -1);
+
+/* cc on SVR4.0 can't handle this */
+#if defined(FASTER) && !(defined(SVR4) && !defined(__GNUC__))
+ A(WaitForFifo)(pApm, 2 + pApm->apmClip + pApm->apmTransparency);
+ SETDEC(DEC_QUICKSTART_ONDIMX | DEC_OP_BLT | DEC_DEST_UPD_TRCORNER |
+ (pApm->apmTransparency ? DEC_SOURCE_TRANSPARENCY : 0) | pApm->Setup_DEC |
+ ((xdir < 0) ? DEC_DIR_X_NEG : DEC_DIR_X_POS) |
+ ((ydir < 0) ? DEC_DIR_Y_NEG : DEC_DIR_Y_POS));
+#else
+ A(WaitForFifo)(pApm, 1 + pApm->apmClip + (transparency_color != -1));
+#endif
+
+ if (pApm->apmClip) {
+ SETCLIP_CTRL(0);
+ pApm->apmClip = FALSE;
+ }
+ if (transparency_color != -1)
+ SETBACKGROUNDCOLOR(transparency_color);
+
+ SETROP(apmROP[rop]);
+}
+
+static void
+A(SubsequentScreenToScreenCopy)(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h)
+{
+ APMDECL(pScrn);
+ BoxRec box;
+#ifndef FASTER
+ u32 c = pApm->apmTransparency ? DEC_SOURCE_TRANSPARENCY : 0;
+#endif
+#if defined(PSZ) && (PSZ == 24)
+ u16 offset;
+#endif
+ u32 sx, dx, sy, dy;
+
+ DPRINTNAME(SubsequentScreenToScreenCopy);
+ if (pApm->blitxdir < 0)
+ {
+#ifndef FASTER
+ c |= DEC_DIR_X_NEG;
+#endif
+#if defined(PSZ) && (PSZ == 24)
+ offset = 3*(pApm->displayWidth + w);
+#endif
+ sx = x1+w-1;
+ dx = x2+w-1;
+ }
+ else
+ {
+#ifndef FASTER
+ c |= DEC_DIR_X_POS;
+#endif
+#if defined(PSZ) && (PSZ == 24)
+ offset = 3*(pApm->displayWidth - w);
+#endif
+ sx = x1;
+ dx = x2;
+ }
+
+ if (pApm->blitydir < 0)
+ {
+#ifndef FASTER
+ c |= DEC_DIR_Y_NEG | DEC_START | DEC_OP_BLT | DEC_DEST_UPD_TRCORNER |
+ pApm->Setup_DEC;
+#endif
+ sy = y1+h-1;
+ dy = y2+h-1;
+ }
+ else
+ {
+#ifndef FASTER
+ c |= DEC_DIR_Y_POS | DEC_START | DEC_OP_BLT | DEC_DEST_UPD_TRCORNER |
+ pApm->Setup_DEC;
+#endif
+ sy = y1;
+ dy = y2;
+ }
+
+#if defined(PSZ) && (PSZ == 24)
+# ifndef FASTER
+ A(WaitForFifo)(pApm, 5);
+# else
+ A(WaitForFifo)(pApm, 4);
+# endif
+ SETOFFSET(offset);
+#else
+# ifndef FASTER
+ A(WaitForFifo)(pApm, 4);
+# else
+ A(WaitForFifo)(pApm, 3);
+# endif
+#endif
+
+ SETSOURCEXY(sx,sy);
+ SETDESTXY(dx,dy);
+ SETWIDTHHEIGHT(w,h);
+ UPDATEDEST(sx + (w + 1)*pApm->blitxdir, sy);
+
+#ifndef FASTER
+ SETDEC(c);
+#endif
+ if (POINT_IN_REGION(pApm->pScreen, &pApm->apmLockedRegion, sx, sy, &box))
+ A(Sync)(pScrn);
+}
+
+#if !defined(PSZ) || PSZ != 24
+static void
+A(SetupForCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop, unsigned int planemask)
+{
+ APMDECL(pScrn);
+
+ DPRINTNAME(SetupForCPUToScreenColorExpandFill);
+ A(CheckMMIO_InitFast)(pScrn);
+ if (bg == -1)
+ {
+#ifndef FASTER
+ pApm->apmTransparency = TRUE;
+ A(WaitForFifo)(pApm, 3);
+#else
+ A(WaitForFifo)(pApm, 4);
+ SETDEC(DEC_OP_HOSTBLT_HOST2SCREEN | DEC_SOURCE_LINEAR | DEC_SOURCE_CONTIG |
+ DEC_SOURCE_TRANSPARENCY | DEC_SOURCE_MONOCHROME | DEC_QUICKSTART_ONDIMX |
+ DEC_DEST_UPD_TRCORNER | pApm->Setup_DEC);
+#endif
+ SETFOREGROUNDCOLOR(fg);
+ SETBACKGROUNDCOLOR(fg+1);
+ }
+ else
+ {
+#ifndef FASTER
+ pApm->apmTransparency = FALSE;
+ A(WaitForFifo)(pApm, 3);
+#else
+ A(WaitForFifo)(pApm, 4);
+ SETDEC(DEC_OP_HOSTBLT_HOST2SCREEN | DEC_SOURCE_LINEAR | DEC_SOURCE_CONTIG |
+ DEC_DEST_UPD_TRCORNER | DEC_SOURCE_MONOCHROME |
+ DEC_QUICKSTART_ONDIMX | pApm->Setup_DEC);
+#endif
+ SETFOREGROUNDCOLOR(fg);
+ SETBACKGROUNDCOLOR(bg);
+ }
+ SETROP(apmROP[rop]);
+}
+
+static void
+A(SubsequentCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h, int skipleft)
+{
+ APMDECL(pScrn);
+#ifndef FASTER
+ u32 c;
+#endif
+
+ DPRINTNAME(SubsequentCPUToScreenColorExpandFill);
+#ifndef FASTER
+ c = DEC_OP_HOSTBLT_HOST2SCREEN | DEC_SOURCE_LINEAR | DEC_SOURCE_CONTIG |
+ DEC_SOURCE_MONOCHROME | DEC_START | DEC_DEST_UPD_TRCORNER |
+ pApm->Setup_DEC;
+
+ if (pApm->apmTransparency)
+ c |= DEC_SOURCE_TRANSPARENCY;
+
+ A(WaitForFifo)(pApm, 7);
+#else
+ A(WaitForFifo)(pApm, 6);
+#endif
+
+ SETCLIP_LEFTTOP(x+skipleft, y);
+ SETCLIP_RIGHTBOT(x+w-1, y+h-1);
+ SETCLIP_CTRL(0x01);
+ pApm->apmClip = TRUE;
+ SETSOURCEX(0); /* According to manual, it just has to be zero */
+ SETDESTXY(x, y);
+ SETWIDTHHEIGHT((w + 31) & ~31, h);
+ UPDATEDEST(x + ((w + 31) & ~31), y);
+
+#ifndef FASTER
+ SETDEC(c);
+#endif
+}
+
+static void
+A(SetupForImageWrite)(ScrnInfoPtr pScrn, int rop, unsigned int planemask,
+ int trans_color, int bpp, int depth)
+{
+ APMDECL(pScrn);
+
+ DPRINTNAME(SetupForImageWriteRect);
+ A(CheckMMIO_InitFast)(pScrn);
+ if (trans_color != -1)
+ {
+#ifndef FASTER
+ pApm->apmTransparency = TRUE;
+ A(WaitForFifo)(pApm, 3);
+#else
+ A(WaitForFifo)(pApm, 4);
+ SETDEC(DEC_OP_HOSTBLT_HOST2SCREEN | DEC_SOURCE_LINEAR | DEC_SOURCE_CONTIG |
+ DEC_SOURCE_TRANSPARENCY | DEC_QUICKSTART_ONDIMX | pApm->Setup_DEC);
+#endif
+ SETBACKGROUNDCOLOR(trans_color);
+ }
+ else {
+#ifndef FASTER
+ pApm->apmTransparency = FALSE;
+ A(WaitForFifo)(pApm, 2);
+#else
+ A(WaitForFifo)(pApm, 3);
+ SETDEC(DEC_OP_HOSTBLT_HOST2SCREEN | DEC_SOURCE_LINEAR | DEC_SOURCE_CONTIG |
+ DEC_QUICKSTART_ONDIMX | pApm->Setup_DEC);
+#endif
+ }
+
+ SETROP(apmROP[rop]);
+}
+
+static void
+A(SubsequentImageWriteRect)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ int skipleft)
+{
+ APMDECL(pScrn);
+#ifndef FASTER
+ u32 c;
+#endif
+
+ DPRINTNAME(SubsequentImageWriteRect);
+#ifndef FASTER
+ c = DEC_OP_HOSTBLT_HOST2SCREEN | DEC_SOURCE_LINEAR | DEC_SOURCE_CONTIG |
+ DEC_START | pApm->Setup_DEC;
+
+ if (pApm->apmTransparency)
+ c |= DEC_SOURCE_TRANSPARENCY;
+
+ A(WaitForFifo)(pApm, 7);
+#else
+ A(WaitForFifo)(pApm, 6);
+#endif
+
+ SETCLIP_LEFTTOP(x+skipleft, y);
+ SETCLIP_RIGHTBOT(x+w-1, y+h-1);
+ SETCLIP_CTRL(0x01);
+ pApm->apmClip = TRUE;
+ SETSOURCEX(0); /* According to manual, it just has to be zero */
+ SETDESTXY(x, y);
+ SETWIDTHHEIGHT((w + 3) & ~3, h);
+
+#ifndef FASTER
+ SETDEC(c);
+#endif
+}
+
+
+static void
+A(SetupForScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop, unsigned int planemask)
+{
+ APMDECL(pScrn);
+
+ DPRINTNAME(SetupForScreenToScreenColorExpandFill);
+ A(CheckMMIO_InitFast)(pScrn);
+ A(WaitForFifo)(pApm, 3 + pApm->apmClip);
+ if (bg == -1)
+ {
+ SETFOREGROUNDCOLOR(fg);
+ SETBACKGROUNDCOLOR(fg+1);
+ pApm->apmTransparency = TRUE;
+ }
+ else
+ {
+ SETFOREGROUNDCOLOR(fg);
+ SETBACKGROUNDCOLOR(bg);
+ pApm->apmTransparency = FALSE;
+ }
+
+ SETROP(apmROP[rop]);
+}
+
+static void
+A(SubsequentScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h, int srcx, int srcy,
+ int offset)
+{
+ APMDECL(pScrn);
+ u32 c;
+
+ DPRINTNAME(SubsequentScreenToScreenColorExpandFill);
+#ifdef FASTER
+ c = DEC_OP_BLT | DEC_DIR_X_POS | DEC_DIR_Y_POS | DEC_SOURCE_MONOCHROME |
+ DEC_QUICKSTART_ONDIMX | DEC_DEST_UPD_TRCORNER | pApm->Setup_DEC;
+#else
+ c = DEC_OP_BLT | DEC_DIR_X_POS | DEC_DIR_Y_POS | DEC_SOURCE_MONOCHROME |
+ DEC_START | DEC_DEST_UPD_TRCORNER | pApm->Setup_DEC;
+#endif
+
+ if (pApm->apmTransparency)
+ c |= DEC_SOURCE_TRANSPARENCY;
+
+ if (srcy >= pApm->Scanlines) {
+ struct ApmStippleCacheRec *pCache;
+ CARD32 dist;
+
+ /*
+ * Offscreen linear stipple
+ */
+ pCache = &pApm->apmCache[srcy / pApm->Scanlines - 1];
+ if (w != pCache->apmStippleCache.w * pApm->bitsPerPixel) {
+ A(WaitForFifo)(pApm, 3);
+ SETCLIP_LEFTTOP(x, y);
+ SETCLIP_RIGHTBOT(x + w - 1, y + h - 1);
+ SETCLIP_CTRL(0x01);
+ pApm->apmClip = TRUE;
+ w = pCache->apmStippleCache.w * pApm->bitsPerPixel;
+ x -= srcx - pCache->apmStippleCache.x;
+ srcx = pCache->apmStippleCache.x;
+ }
+ else if (pApm->apmClip) {
+ A(WaitForFifo)(pApm, 1);
+ SETCLIP_CTRL(0x00);
+ pApm->apmClip = FALSE;
+ }
+ srcx += (srcy - pCache->apmStippleCache.y) * pCache->apmStippleCache.w;
+ srcy = pCache->apmStippleCache.y % pApm->Scanlines;
+ dist = srcx + srcy * pApm->displayWidth;
+ srcx = dist & 0xFFF;
+ srcy = dist >> 12;
+ c |= DEC_SOURCE_CONTIG | DEC_SOURCE_LINEAR;
+ }
+ else if (offset) {
+ A(WaitForFifo)(pApm, 3);
+ SETCLIP_LEFTTOP(x, y);
+ SETCLIP_RIGHTBOT(x + w, y + h);
+ SETCLIP_CTRL(0x01);
+ pApm->apmClip = TRUE;
+ w += offset;
+ x -= offset;
+ }
+ else if (pApm->apmClip) {
+ A(WaitForFifo)(pApm, 1);
+ SETCLIP_CTRL(0x00);
+ pApm->apmClip = FALSE;
+ }
+
+ A(WaitForFifo)(pApm, 4);
+
+ SETSOURCEXY(srcx, srcy);
+ SETDESTXY(x, y);
+
+#ifdef FASTER
+ SETDEC(c);
+ SETWIDTHHEIGHT(w, h);
+#else
+ SETWIDTHHEIGHT(w, h);
+ SETDEC(c);
+#endif
+ UPDATEDEST(x + w + 1, h);
+}
+
+static void
+A(SubsequentSolidBresenhamLine)(ScrnInfoPtr pScrn, int x1, int y1, int e1,
+ int e2, int err, int length, int octant)
+{
+ APMDECL(pScrn);
+#ifdef FASTER
+ u32 c = DEC_QUICKSTART_ONDIMX | DEC_OP_VECT_ENDP | DEC_DEST_UPD_LASTPIX |
+ pApm->Setup_DEC;
+#else
+ u32 c = DEC_START | DEC_OP_VECT_ENDP | DEC_DEST_UPD_LASTPIX | pApm->Setup_DEC;
+#endif
+ int tmp;
+
+ DPRINTNAME(SubsequentSolidBresenhamLine);
+
+ A(WaitForFifo)(pApm, 5);
+ SETDESTXY(x1,y1);
+ SETDDA_ERRORTERM(err);
+ SETDDA_ADSTEP(e1, e2);
+
+ if (octant & YMAJOR) {
+ c |= DEC_MAJORAXIS_Y;
+ tmp = e1; e1 = e2; e2 = tmp;
+ }
+ else
+ c |= DEC_MAJORAXIS_X;
+
+ if (octant & XDECREASING) {
+ c |= DEC_DIR_X_NEG;
+ e1 = -e1;
+ }
+ else
+ c |= DEC_DIR_X_POS;
+
+ if (octant & YDECREASING) {
+ c |= DEC_DIR_Y_NEG;
+ e2 = -e2;
+ }
+ else
+ c |= DEC_DIR_Y_POS;
+
+#ifdef FASTER
+ SETDEC(c);
+ SETWIDTH(length);
+#else
+ SETWIDTH(length);
+ SETDEC(c);
+#endif
+
+ if (octant & YMAJOR)
+ UPDATEDEST(x1 + e1 / 2, y1 + e2 / 2);
+ else
+ UPDATEDEST(x1 + e2 / 2, y1 + e1 / 2);
+ if (pApm->apmClip)
+ {
+ pApm->apmClip = FALSE;
+ A(WaitForFifo)(pApm, 1);
+ SETCLIP_CTRL(0);
+ }
+}
+
+static void
+A(SetClippingRectangle)(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
+{
+ APMDECL(pScrn);
+
+ DPRINTNAME(SetClippingRectangle);
+ A(WaitForFifo)(pApm, 3);
+ SETCLIP_LEFTTOP(x1,y1);
+ SETCLIP_RIGHTBOT(x2,y2);
+ SETCLIP_CTRL(0x01);
+ pApm->apmClip = TRUE;
+}
+
+static void
+A(WritePixmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int rop,
+ unsigned int planemask, int trans, int bpp, int depth)
+{
+ APMDECL(pScrn);
+ int dwords, skipleft, Bpp = bpp >> 3;
+ Bool beCareful = FALSE;
+ unsigned char *dst = ((unsigned char *)pApm->FbBase) + x * Bpp + y * pApm->bytesPerScanline;
+ int PlusOne = 0, mask, count;
+
+ DPRINTNAME(WritePixmap);
+ /*
+ * First the fast case : source and dest have same alignment. Doc says
+ * it's faster to do it here, which may be true since one has to read
+ * the chip when CPU to screen-ing.
+ */
+ if ((skipleft = (long)src & 3L) == ((long)dst & 3L)) {
+ int skipright;
+
+ if (skipleft)
+ skipleft = 4 - skipleft;
+ dwords = (skipright = (w - skipleft) * Bpp) >> 2;
+ skipright %= 4;
+ if (!skipleft && !skipright)
+ while (h-- > 0) {
+ CARD32 *src2 = (CARD32 *)src;
+ CARD32 *dst2 = (CARD32 *)dst;
+
+ for (count = dwords; count-- > 0; )
+ *dst2++ = *src2++;
+ src += srcwidth;
+ dst += pApm->bytesPerScanline;
+ }
+ else if (!skipleft)
+ while (h-- > 0) {
+ CARD32 *src2 = (CARD32 *)src;
+ CARD32 *dst2 = (CARD32 *)dst;
+
+ for (count = dwords; count-- > 0; )
+ *dst2++ = *src2++;
+ for (count = skipright; count-- > 0; )
+ ((char *)dst2)[count] = ((char *)src2)[count];
+ src += srcwidth;
+ dst += pApm->bytesPerScanline;
+ }
+ else if (!skipright)
+ while (h-- > 0) {
+ CARD32 *src2 = (CARD32 *)(src + skipleft);
+ CARD32 *dst2 = (CARD32 *)(dst + skipleft);
+
+ for (count = skipleft; count-- > 0; )
+ dst[count] = src[count];
+ for (count = dwords; count-- > 0; )
+ *dst2++ = *src2++;
+ src += srcwidth;
+ dst += pApm->bytesPerScanline;
+ }
+ else
+ while (h-- > 0) {
+ CARD32 *src2 = (CARD32 *)(src + skipleft);
+ CARD32 *dst2 = (CARD32 *)(dst + skipleft);
+
+ for (count = skipleft; count-- > 0; )
+ dst[count] = src[count];
+ for (count = dwords; count-- > 0; )
+ *dst2++ = *src2++;
+ for (count = skipright; count-- > 0; )
+ ((char *)dst2)[count] = ((char *)src2)[count];
+ src += srcwidth;
+ dst += pApm->bytesPerScanline;
+ }
+
+ return;
+ }
+
+ if ((skipleft = (long)src & 0x03L)) {
+ if (Bpp == 3)
+ skipleft = 4 - skipleft;
+ else
+ skipleft /= Bpp;
+
+ if (x < skipleft) {
+ skipleft = 0;
+ beCareful = TRUE;
+ goto BAD_ALIGNMENT;
+ }
+
+ x -= skipleft;
+ w += skipleft;
+
+ if (Bpp == 3)
+ src -= 3 * skipleft;
+ else /* is this Alpha friendly ? */
+ src = (unsigned char*)((long)src & ~0x03L);
+ }
+
+BAD_ALIGNMENT:
+
+ dwords = ((w * Bpp) + 3) >> 2;
+ mask = (pApm->bitsPerPixel / 8) - 1;
+
+ if (dwords & mask) {
+ /*
+ * Experimental...
+ * It seems the AT3D needs a padding of scanline to a multiple of
+ * 4 pixels, not only bytes.
+ */
+ PlusOne = mask - (dwords & mask) + 1;
+ }
+
+ A(SetupForImageWrite)(pScrn, rop, planemask, trans, bpp, depth);
+ A(SubsequentImageWriteRect)(pScrn, x, y, w, h, skipleft);
+
+ if (beCareful) {
+ /* in cases with bad alignment we have to be careful not
+ to read beyond the end of the source */
+ if (((x * Bpp) + (dwords << 2)) > srcwidth) h--;
+ else beCareful = FALSE;
+ }
+
+ srcwidth -= (dwords << 2);
+
+ while (h--) {
+ for (count = dwords; count-- > 0; ) {
+ while (!(STATUS() & STATUS_HOSTBLTBUSY))
+ ;
+ *(CARD32*)pApm->BltMap = *(CARD32*)src;
+ src += 4;
+ }
+ src += srcwidth;
+ for (count = PlusOne; count-- > 0; ) {
+ int status;
+
+ while (!((status = STATUS()) & STATUS_HOSTBLTBUSY))
+ if (!(status & STATUS_ENGINEBUSY))
+ break;
+ if (status & STATUS_ENGINEBUSY)
+ *(CARD32*)pApm->BltMap = 0x00000000;
+ }
+ }
+ if (beCareful) {
+ int shift = ((long)src & 0x03L) << 3;
+
+ if (--dwords) {
+ int count;
+
+ for (count = dwords >> 2; count-- > 0; ) {
+ while (!(STATUS() & STATUS_HOSTBLTBUSY))
+ ;
+ *(CARD32*)pApm->BltMap = *(CARD32*)src;
+ src += 4;
+ }
+ }
+ while (!(STATUS() & STATUS_HOSTBLTBUSY))
+ ;
+ *((CARD32*)pApm->BltMap) = *((CARD32*)src) >> shift;
+ }
+
+ pApm->apmClip = FALSE;
+ A(WaitForFifo)(pApm, 1);
+ SETCLIP_CTRL(0);
+}
+
+static void A(SetupForMono8x8PatternFill)(ScrnInfoPtr pScrn, int patx, int paty,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ APMDECL(pScrn);
+
+ DPRINTNAME(SetupForMono8x8PatternFill);
+ if (bg != -1) {
+ pApm->apmTransparency = FALSE;
+ A(WaitForFifo)(pApm, 3 + pApm->apmClip);
+ SETBACKGROUNDCOLOR(bg);
+ SETFOREGROUNDCOLOR(fg);
+ SETROP(apmROP[rop] & 0xF0);
+ }
+ else {
+ pApm->apmTransparency = TRUE;
+ A(WaitForFifo)(pApm, 3);
+ SETROP(0xCC);
+ SETFOREGROUNDCOLOR(fg);
+ SETDESTOFF(pApm->ScratchMem);
+ A(WaitForFifo)(pApm, 4 + pApm->apmClip);
+#ifdef FASTER
+ SETDEC(pApm->Setup_DEC | DEC_OP_STRIP | DEC_DEST_LINEAR |
+ DEC_DEST_CONTIG | DEC_QUICKSTART_ONDIMX);
+ SETWIDTH(pApm->ScratchMemWidth);
+ SETDEC(pApm->Setup_DEC | DEC_OP_BLT | DEC_DEST_XY | DEC_SOURCE_CONTIG |
+ DEC_PATTERN_88_1bMONO | DEC_DEST_UPD_BLCORNER | DEC_SOURCE_TRANSPARENCY |
+ DEC_QUICKSTART_ONDIMX);
+#else
+ SETWIDTH(pApm->ScratchMemWidth);
+ SETDEC(pApm->Setup_DEC | DEC_OP_STRIP | DEC_DEST_LINEAR |
+ DEC_DEST_CONTIG | DEC_START);
+#endif
+ SETROP((apmROP[rop] & 0xF0) | 0x0A);
+ }
+ if (pApm->apmClip) {
+ SETCLIP_CTRL(0);
+ pApm->apmClip = FALSE;
+ }
+}
+
+static void A(SubsequentMono8x8PatternFillRect)(ScrnInfoPtr pScrn, int patx,
+ int paty, int x, int y,
+ int w, int h)
+{
+ APMDECL(pScrn);
+
+ DPRINTNAME(SubsequentMono8x8PatternFillRect);
+ A(WaitForFifo)(pApm, 6);
+ SETPATTERN(patx, paty);
+ SETDESTXY(x, y);
+ UPDATEDEST(x, y + h + 1);
+ if (pApm->apmTransparency) {
+ int hoff = pApm->ScratchMemWidth / w;
+
+ SETSOURCEOFF(pApm->ScratchMem);
+#ifndef FASTER
+ if (h > hoff)
+ SETWIDTHHEIGHT(w, hoff);
+#endif
+ while (h > hoff) {
+#ifdef FASTER
+ A(WaitForFifo)(pApm, 4);
+ SETWIDTHHEIGHT(w, hoff);
+ SETPATTERN(patx, paty);
+#else
+ A(WaitForFifo)(pApm, 5);
+ SETDEC(pApm->Setup_DEC | DEC_OP_BLT | DEC_SOURCE_LINEAR |
+ DEC_SOURCE_CONTIG | DEC_DEST_XY | DEC_PATTERN_88_1bMONO |
+ DEC_DEST_UPD_BLCORNER | DEC_START);
+ SETPATTERN(patx, paty);
+#endif
+ h -= hoff;
+ }
+#ifdef FASTER
+ SETWIDTHHEIGHT(w, h);
+#else
+ SETWIDTHHEIGHT(w, h);
+ SETDEC(pApm->Setup_DEC | DEC_OP_BLT | DEC_DEST_XY |
+ DEC_SOURCE_CONTIG | DEC_PATTERN_88_1bMONO |
+ DEC_DEST_UPD_BLCORNER | DEC_START);
+#endif
+ }
+ else {
+#ifdef FASTER
+ SETDEC(pApm->Setup_DEC | ((h == 1) ? DEC_OP_STRIP : DEC_OP_RECT) |
+ DEC_DEST_XY | DEC_PATTERN_88_1bMONO | DEC_DEST_UPD_TRCORNER |
+ DEC_QUICKSTART_ONDIMX);
+ SETWIDTHHEIGHT(w, h);
+#else
+ SETWIDTHHEIGHT(w, h);
+ SETDEC(pApm->Setup_DEC | ((h == 1) ? DEC_OP_STRIP : DEC_OP_RECT) |
+ DEC_DEST_XY | DEC_PATTERN_88_1bMONO | DEC_DEST_UPD_TRCORNER |
+ DEC_START);
+#endif
+ }
+}
+
+static void A(SetupForColor8x8PatternFill)(ScrnInfoPtr pScrn,int patx,int paty,
+ int rop, unsigned int planemask,
+ int transparency_color)
+{
+ APMDECL(pScrn);
+
+ DPRINTNAME(SetupForColor8x8PatternFillRect);
+ if (transparency_color != -1) {
+#ifndef FASTER
+ pApm->apmTransparency = TRUE;
+ A(WaitForFifo)(pApm, 2 + pApm->apmClip);
+#else
+ A(WaitForFifo)(pApm, 3 + pApm->apmClip);
+ SETDEC(pApm->Setup_DEC | DEC_OP_BLT |
+ DEC_DEST_XY | DEC_PATTERN_88_8bCOLOR | DEC_SOURCE_TRANSPARENCY |
+ DEC_QUICKSTART_ONDIMX);
+#endif
+ SETBACKGROUNDCOLOR(transparency_color);
+ }
+ else {
+#ifndef FASTER
+ pApm->apmTransparency = FALSE;
+ A(WaitForFifo)(pApm, 1 + pApm->apmClip);
+#else
+ A(WaitForFifo)(pApm, 2 + pApm->apmClip);
+ SETDEC(pApm->Setup_DEC | DEC_OP_BLT |
+ DEC_DEST_XY | DEC_PATTERN_88_8bCOLOR | DEC_QUICKSTART_ONDIMX);
+#endif
+ }
+ if (pApm->apmClip) {
+ SETCLIP_CTRL(0);
+ pApm->apmClip = FALSE;
+ }
+ SETROP(apmROP[rop]);
+}
+
+static void A(SubsequentColor8x8PatternFillRect)(ScrnInfoPtr pScrn, int patx,
+ int paty, int x, int y,
+ int w, int h)
+{
+ APMDECL(pScrn);
+
+ DPRINTNAME(SubsequentColor8x8PatternFillRect);
+#ifndef FASTER
+ A(WaitForFifo)(pApm, 5);
+#else
+ A(WaitForFifo)(pApm, 4);
+#endif
+ SETSOURCEXY(patx, paty);
+ SETDESTXY(x, y);
+ SETWIDTHHEIGHT(w, h);
+ UPDATEDEST(x + w + 1, y);
+#ifndef FASTER
+ SETDEC(pApm->Setup_DEC | DEC_OP_BLT |
+ DEC_DEST_XY | (pApm->apmTransparency * DEC_SOURCE_TRANSPARENCY) |
+ DEC_PATTERN_88_8bCOLOR | DEC_START);
+#endif
+}
+#endif
+
+
+/* This function is a f*cking kludge since I could not get MMIO to
+ work if I initialized in one of the functions in apm_driver.c (like
+ preferrably ApmFbInit()... */
+void
+A(CheckMMIO_Init)(ScrnInfoPtr pScrn)
+{
+ APMDECL(pScrn);
+ volatile int i;
+
+ if (!pApm->apmMMIO_Init)
+ {
+ pApm->apmMMIO_Init = TRUE;
+
+ A(Sync)(pScrn);
+
+ pApm->Setup_DEC = 0;
+ switch(pApm->bitsPerPixel)
+ {
+ case 8:
+ pApm->Setup_DEC |= DEC_BITDEPTH_8;
+ break;
+ case 16:
+ pApm->Setup_DEC |= DEC_BITDEPTH_16;
+ break;
+ case 24:
+ pApm->Setup_DEC |= DEC_BITDEPTH_24;
+ break;
+ case 32:
+ pApm->Setup_DEC |= DEC_BITDEPTH_32;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Cannot set up drawing engine control for bpp = %d\n",
+ pScrn->bitsPerPixel);
+ break;
+ }
+
+ switch(pApm->displayWidth)
+ {
+ case 640:
+ pApm->Setup_DEC |= DEC_WIDTH_640;
+ break;
+ case 800:
+ pApm->Setup_DEC |= DEC_WIDTH_800;
+ break;
+ case 1024:
+ pApm->Setup_DEC |= DEC_WIDTH_1024;
+ break;
+ case 1152:
+ pApm->Setup_DEC |= DEC_WIDTH_1152;
+ break;
+ case 1280:
+ pApm->Setup_DEC |= DEC_WIDTH_1280;
+ break;
+ case 1600:
+ pApm->Setup_DEC |= DEC_WIDTH_1600;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Cannot set up drawing engine control "
+ "for screen width = %d\n", pApm->displayWidth);
+ break;
+ }
+
+ /* Setup current register values */
+ for (i = 0; i < sizeof(pApm->regcurr) / 4; i++)
+ ((CARD32 *)curr)[i] = RDXL(0x30 + 4*i);
+
+ SETCLIP_CTRL(1);
+ SETCLIP_CTRL(0);
+ SETBYTEMASK(0x00);
+ SETBYTEMASK(0xFF);
+ SETROP(ROP_S_xor_D);
+ SETROP(ROP_S);
+
+ }
+}
+
+static void
+A(Sync)(ScrnInfoPtr pScrn)
+{
+ APMDECL(pScrn);
+ volatile u32 i, stat;
+
+ for(i = 0; i < MAXLOOP; i++) {
+ stat = STATUS();
+ if ((!(stat & (STATUS_HOSTBLTBUSY | STATUS_ENGINEBUSY))) &&
+ ((stat & STATUS_FIFO) >= 8))
+ break;
+ }
+ if (i == MAXLOOP) {
+ apm_stopit();
+ if (!xf86Exiting)
+ FatalError("Hung in ApmSync() (Status = 0x%08X)\n", STATUS());
+ }
+ if (pApm->apmClip) {
+ SETCLIP_CTRL(0);
+ pApm->apmClip = FALSE;
+ }
+}
+
+
+#undef DPRINTNAME
+#undef A
+#undef DEBUG
+#undef DEPTH
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_i2c.c b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_i2c.c
new file mode 100644
index 000000000..8a6fd68b5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_i2c.c
@@ -0,0 +1,78 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/apm/apm_i2c.c,v 1.2 1999/08/28 09:00:59 dawes Exp $ */
+
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+#include "apm.h"
+#include "apm_regs.h"
+
+/* Inline functions */
+static __inline__ void
+WaitForFifo(ApmPtr pApm, int slots)
+{
+ if (!pApm->UsePCIRetry) {
+ volatile int i;
+#define MAXLOOP 1000000
+
+ for(i = 0; i < MAXLOOP; i++) {
+ if ((STATUS() & STATUS_FIFO) >= slots)
+ break;
+ }
+ if (i == MAXLOOP) {
+ FatalError("Hung in WaitForFifo() (Status = 0x%08X)\n", STATUS());
+ }
+ }
+}
+
+static void
+ApmI2CPutBits(I2CBusPtr b, int clock, int data)
+{
+ unsigned int reg;
+ ApmPtr pApm = ((ApmPtr)b->DriverPrivate.ptr);
+
+ WaitForFifo(pApm, 2);
+ reg = (RDXB(0xD0) & 0x07) | 0x60;
+ if(clock) reg |= 0x08;
+ if(data) reg |= 0x10;
+ WRXB(0xD0, reg);
+}
+
+static void
+ApmI2CGetBits(I2CBusPtr b, int *clock, int *data)
+{
+ unsigned int reg;
+ ApmPtr pApm = ((ApmPtr)b->DriverPrivate.ptr);
+
+ WaitForFifo(pApm, 2);
+ WRXB(0xD0, RDXB(0xD0) & 0x07);
+ reg = STATUS();
+ *clock = (reg & STATUS_SCL) != 0;
+ *data = (reg & STATUS_SDA) != 0;
+}
+
+Bool
+ApmI2CInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ APMDECL(pScrn);
+ I2CBusPtr I2CPtr;
+
+ I2CPtr = xf86CreateI2CBusRec();
+ if(!I2CPtr) return FALSE;
+
+ pApm->I2CPtr = I2CPtr;
+
+ I2CPtr->BusName = "Alliance bus";
+ I2CPtr->scrnIndex = pScrn->scrnIndex;
+ I2CPtr->I2CPutBits = ApmI2CPutBits;
+ I2CPtr->I2CGetBits = ApmI2CGetBits;
+ I2CPtr->DriverPrivate.ptr = pApm;
+
+ if(!xf86I2CBusInit(I2CPtr))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_regs.h b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_regs.h
new file mode 100644
index 000000000..39e37e84c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_regs.h
@@ -0,0 +1,206 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/apm/apm_regs.h,v 1.3 1999/08/28 09:00:59 dawes Exp $ */
+
+
+
+#define curr08 (curr - 0x30)
+#define curr16 ((CARD16 *)(curr - 0x30))
+#define curr32 ((CARD32 *)(curr - 0x30))
+#define check08(addr, val) \
+ ((addr) >= 0x80 || (((addr)&0xF8) == 0x48) || curr08[addr] != (val))
+#define check16(addr, val) \
+ ((addr) >= 0x80 || (((addr)&0xF8) == 0x48) || curr16[(addr) / 2] != (val)||\
+ ((addr) == 0x50 && curr32[0x40 / 4] & DEC_QUICKSTART_ONSOURCE)||\
+ ((addr) == 0x52 && curr32[0x40 / 4] & DEC_QUICKSTART_ONSOURCE)||\
+ ((addr) == 0x54 && curr32[0x40 / 4] & DEC_QUICKSTART_ONDEST) || \
+ ((addr) == 0x56 && curr32[0x40 / 4] & DEC_QUICKSTART_ONDEST) || \
+ ((addr) == 0x58 && curr32[0x40 / 4] & DEC_QUICKSTART_ONDIMX))
+#define check32(addr, val) \
+ ((addr) >= 0x80 || (((addr)&0xF8) == 0x48) || curr32[(addr) / 4] != (val)||\
+ ((addr) == 0x50 && curr32[0x40 / 4] & DEC_QUICKSTART_ONSOURCE)||\
+ ((addr) == 0x54 && curr32[0x40 / 4] & DEC_QUICKSTART_ONDEST) || \
+ ((addr) == 0x58 && curr32[0x40 / 4] & DEC_QUICKSTART_ONDIMX) || \
+ ((addr) == 0x40 && (val) & DEC_START))
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+/* Memory mapped access to extended registers */
+#define RDXB_M(addr) (*(volatile unsigned char *)(pApm->MemMap+(addr)))
+#define RDXW_M(addr) (*(volatile unsigned short *)(pApm->MemMap+(addr)))
+#define RDXL_M(addr) (*(volatile unsigned int *)(pApm->MemMap+(addr)))
+#define WRXB_M(addr,val) (void) (check08((addr), (val)) && \
+ (*(volatile unsigned char *)(pApm->MemMap+(addr)) = (val), \
+ curr08[MIN((addr), 0x80)] = (val)))
+#define WRXW_M(addr,val) (void) (check16((addr), (val)) && \
+ (*(volatile unsigned short *)(pApm->MemMap+(addr)) = (val), \
+ curr16[MIN(((addr) / 2), 0x40)] = (val)))
+#define WRXL_M(addr,val) (void) (check32((addr), (val)) && \
+ (*(volatile unsigned int *)(pApm->MemMap+(addr)) = (val), \
+ curr32[MIN(((addr) / 4), 0x20)] = (val)))
+
+/* IO port access to extended registers */
+#define RDXB_IOP(addr) (wrinx(0x3c4, 0x1d, (addr) >> 2),inb(pApm->xbase + ((addr) & 3)))
+#define RDXW_IOP(addr) (wrinx(0x3c4, 0x1d, (addr) >> 2),inw(pApm->xbase + ((addr) & 2)))
+#define RDXL_IOP(addr) (wrinx(0x3c4, 0x1d, (addr) >> 2),inl(pApm->xbase))
+#define WRXB_IOP(addr,val) do { if (check08((addr), (val))) { \
+ wrinx(0x3c4, 0x1d, (addr) >> 2); \
+ outb(pApm->xbase + ((addr) & 3), (val)); \
+ curr08[MIN((addr), 0x80)] = (val); \
+ break; \
+ }} while (1)
+#define WRXW_IOP(addr,val) do { if (check16((addr), (val))) { \
+ wrinx(0x3c4, 0x1d, (addr) >> 2); \
+ outw(pApm->xbase + ((addr) & 2), (val)); \
+ curr16[MIN(((addr) / 2), 0x40)] = (val); \
+ break; \
+ }} while (1)
+#define WRXL_IOP(addr,val) do { if (check32((addr), (val))) { \
+ wrinx(0x3c4, 0x1d, (addr) >> 2); \
+ outl(pApm->xbase, (val)); \
+ curr32[MIN(((addr) / 4), 0x20)] = (val); \
+ break; \
+ }} while (1)
+
+#define WRXL WRXL_M
+#define WRXW WRXW_M
+#define WRXB WRXB_M
+#define RDXL RDXL_M
+#define RDXW RDXW_M
+#define RDXB RDXB_M
+#define UPDATEDEST(x,y) (void)(curr32[0x54 / 4] = ((y) << 16) | ((x) & 0xFFFF))
+
+/* Memory mapped access to VGA registers */
+#define APMVGAB(idx) (((volatile unsigned char *)pApm->VGAMap)[idx])
+#define APMVGAS(idx) (((volatile unsigned short *)pApm->VGAMap)[(idx) >> 1])
+#define APMVGAW(idx) (((volatile unsigned int *)pApm->VGAMap)[(idx) >> 2])
+#define ApmWriteCrtc(idx, val) do { APMVGAS(0x3D4) = ((val) << 8) | ((idx) & 0xFF); break; } while(1)
+#define ApmReadCrtc(idx) ((APMVGAB(0x3D4) = (idx)), APMVGAB(0x3D5))
+#define ApmWriteGr(idx, val) do { APMVGAS(0x3CE) = ((val) << 8) | ((idx) & 0xFF); break; } while(1)
+#define ApmReadGr(idx) ((APMVGAB(0x3CE) = (idx)), APMVGAB(0x3CF))
+#define ApmWriteSeq(idx, val) do { APMVGAB(0x3C4) = (idx); APMVGAB(0x3C5) = (val); break; } while(1)
+#define ApmReadSeq(idx) ((APMVGAB(0x3C4) = (idx)), APMVGAB(0x3C5))
+#define ApmWriteAttr(idx, val) do { int tmp = APMVGAB(0x3DA); APMVGAB(0x3C0) = (idx); APMVGAB(0x3C0) = (val); break; } while(1)
+#define ApmReadAttr(idx) (APMVGAB(0x3DA), (APMVGAB(0x3C0) = (idx)), APMVGAB(0x3C1))
+#define ApmWriteMiscOut(val) do { APMVGAB(0x3C2) = (val); break; } while(1)
+#define ApmReadMiscOut() APMVGAB(0x3CC)
+#define ApmWriteDacMask(val) do { APMVGAB(0x3C6) = (val); break; } while(1)
+#define ApmReadDacMask() APMVGAB(0x3C6)
+#define ApmWriteDacReadAddr(val)do { APMVGAB(0x3C7) = (val); break; } while(1)
+#define ApmWriteDacWriteAddr(val)do{ APMVGAB(0x3C8) = (val); break; } while(1)
+#define ApmWriteDacData(val) do { APMVGAB(0x3C9) = (val); break; } while(1)
+#define ApmReadDacData() APMVGAB(0x3C9)
+
+#define STATUS() (RDXL(0x1fc))
+#define STATUS_FIFO (0x0f)
+#define STATUS_HOSTBLTBUSY (1 << 8)
+#define STATUS_ENGINEBUSY (1 << 10)
+#define STATUS_SDA (1 << 16)
+#define STATUS_SCL (1 << 17)
+
+#define SETFOREGROUNDCOLOR(c) WRXL(0x60,c)
+#define SETBACKGROUNDCOLOR(c) WRXL(0x64,c)
+
+#define SETSOURCEX(x) WRXW(0x50, x)
+#define SETSOURCEY(y) WRXW(0x52, y)
+#define SETSOURCEXY(x,y) WRXL(0x50, ((y) << 16) | ((x) & 0xFFFF))
+#define SETSOURCEOFF(o) WRXL(0x50, (o))
+
+#define SETDESTX(x) WRXW(0x54, x)
+#define SETDESTY(y) WRXW(0x56, y)
+#define SETDESTXY(x,y) WRXL(0x54, ((y) << 16) | ((x) & 0xFFFF))
+#define SETDESTOFF(o) WRXL(0x54, (o))
+
+#define SETWIDTH(w) WRXW(0x58, w)
+#define SETHEIGHT(h) WRXW(0x5A, h)
+#define SETWIDTHHEIGHT(w,h) WRXL(0x58, ((h) << 16) | ((w) & 0xFFFF))
+
+#define SETOFFSET(o) WRXW(0x5C, (o))
+#define SETSOURCEOFFSET(o) WRXW(0x5E, (o))
+
+#define SETBYTEMASK(mask) WRXB(0x47, (mask))
+
+#define SETPATTERN(p1, p2) do {WRXL(0x48, p1); WRXL(0x4C, p2);} while(0)
+
+#define SETDDA_AXIALSTEP(step) WRXW(0x70, (step))
+#define SETDDA_DIAGONALSTEP(step) WRXW(0x72, (step))
+#define SETDDA_ERRORTERM(eterm) WRXW(0x74, (eterm))
+#define SETDDA_ADSTEP(s1,s2) WRXL(0x70, ((s2) << 16)|((s1) & 0xFFFF))
+
+#define SETCLIP_CTRL(ctrl) WRXB(0x30, ctrl)
+#define SETCLIP_LEFT(x) WRXW(0x38, x)
+#define SETCLIP_TOP(y) WRXW(0x3A, y)
+#define SETCLIP_LEFTTOP(x,y) WRXL(0x38, ((y) << 16) | ((x) & 0xFFFF))
+#define SETCLIP_RIGHT(x) WRXW(0x3C, x)
+#define SETCLIP_BOT(y) WRXW(0x3E, y)
+#define SETCLIP_RIGHTBOT(x,y) WRXL(0x3C, ((y) << 16) | ((x) & 0xFFFF))
+
+/* RASTER OPERATION REGISTER */
+/* P = pattern S = source D = destination */
+#define SETROP(rop) WRXB(0x46, rop)
+#define ROP_P_and_S_and_D 0x80
+#define ROP_S_xor_D 0x66
+#define ROP_S 0xCC
+#define ROP_P 0xF0
+/* Then there are about 252 more operations ... */
+
+
+/* DRAWING ENGINE CONTROL REGISTER */
+#define SETDEC(control) WRXL(0x40, (control))
+#define DEC_OP_VECT_NOENDP 0x0000000D
+#define DEC_OP_VECT_ENDP 0x0000000C
+#define DEC_OP_HOSTBLT_SCREEN2HOST 0x00000009
+#define DEC_OP_HOSTBLT_HOST2SCREEN 0x00000008
+#define DEC_OP_STRIP 0x00000004
+#define DEC_OP_BLT_STRETCH 0x00000003
+#define DEC_OP_RECT 0x00000002
+#define DEC_OP_BLT 0x00000001
+#define DEC_OP_NOOP 0x00000000
+#define DEC_DIR_X_NEG (1 << 6)
+#define DEC_DIR_X_POS (0 << 6)
+#define DEC_DIR_Y_NEG (1 << 7)
+#define DEC_DIR_Y_POS (0 << 7)
+#define DEC_MAJORAXIS_X (0 << 8) /* Looks like an error in the docs ...*/
+#define DEC_MAJORAXIS_Y (1 << 8)
+#define DEC_SOURCE_LINEAR (1 << 9)
+#define DEC_SOURCE_XY (0 << 9)
+#define DEC_SOURCE_CONTIG (1 << 11)
+#define DEC_SOURCE_RECTANGULAR (0 << 11)
+#define DEC_SOURCE_MONOCHROME (1 << 12)
+#define DEC_SOURCE_COLOR (0 << 12)
+#define DEC_SOURCE_TRANSPARENCY (1 << 13)
+#define DEC_SOURCE_NO_TRANSPARENCY (0 << 13)
+#define DEC_BITDEPTH_MASK (7 << 14)
+#define DEC_BITDEPTH_24 (4 << 14)
+#define DEC_BITDEPTH_32 (3 << 14)
+#define DEC_BITDEPTH_16 (2 << 14)
+#define DEC_BITDEPTH_8 (1 << 14)
+#define DEC_DEST_LINEAR (1 << 18)
+#define DEC_DEST_XY (0 << 18)
+#define DEC_DEST_CONTIG (1 << 19)
+#define DEC_DEST_RECTANGULAR (0 << 19)
+#define DEC_DEST_TRANSPARENCY (1 << 20)
+#define DEC_DEST_NO_TRANSPARENCY (0 << 20)
+#define DEC_DEST_TRANSP_POLARITY (1 << 21)
+#define DEC_DEST_TRANSP_POLARITYINV (0 << 21)
+#define DEC_PATTERN_88_8bCOLOR (3 << 22)
+#define DEC_PATTERN_88_1bMONO (2 << 22)
+#define DEC_PATTERN_44_4bDITHER (1 << 22)
+#define DEC_PATTERN_NONE (0 << 22)
+#define DEC_WIDTH_MASK (7 << 24)
+#define DEC_WIDTH_1600 (7 << 24)
+#define DEC_WIDTH_1280 (6 << 24)
+#define DEC_WIDTH_1152 (5 << 24)
+#define DEC_WIDTH_1024 (4 << 24)
+#define DEC_WIDTH_800 (2 << 24)
+#define DEC_WIDTH_640 (1 << 24)
+#define DEC_WIDTH_LINEAR (0 << 24)
+#define DEC_DEST_UPD_LASTPIX (3 << 27)
+#define DEC_DEST_UPD_BLCORNER (2 << 27)
+#define DEC_DEST_UPD_TRCORNER (1 << 27)
+#define DEC_DEST_UPD_NONE (0 << 27)
+#define DEC_QUICKSTART_ONDEST (3 << 29)
+#define DEC_QUICKSTART_ONSOURCE (2 << 29)
+#define DEC_QUICKSTART_ONDIMX (1 << 29)
+#define DEC_QUICKSTART_NONE (0 << 29)
+#define DEC_START (1 << 31)
+#define DEC_START_NO (0 << 31)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_rush.c b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_rush.c
new file mode 100644
index 000000000..f2f6a5459
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/apm/apm_rush.c
@@ -0,0 +1,328 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/apm/apm_rush.c,v 1.3 1999/08/28 14:32:46 dawes Exp $ */
+/*
+ * Copyright Loïc Grenié 1999
+ */
+
+#include "apm.h"
+#include "xaalocal.h"
+
+static __inline__ void __xf86UnlockPixmap(ApmPtr, PixmapLinkPtr pLink);
+static int xf86RushLockPixmap(int scrnIndex, PixmapPtr pix);
+static void xf86RushUnlockPixmap(int scrnIndex, PixmapPtr pix);
+static void xf86RushUnlockAllPixmaps(void);
+
+int
+xf86RushLockPixmap(int scrnIndex, PixmapPtr pix)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ APMDECL(pScrn);
+ ApmPixmapPtr pApmPriv = APM_GET_PIXMAP_PRIVATE(pix);
+ FBAreaPtr area = ((XAAPixmapPtr)XAA_GET_PIXMAP_PRIVATE(pix))->offscreenArea;
+ int p2, width = pApm->bytesPerScanline;
+
+ pApm->apmLock = TRUE;
+ if (area) {
+ RegionRec NewReg;
+
+ /*
+ * 1) Make it unmovable so that XAA won't know we're playing
+ * with the cache.
+ * 2) Play musical chairs if needed.
+ */
+ pApmPriv->MoveAreaCallback = area->MoveAreaCallback;
+ area->MoveAreaCallback = NULL;
+ pApmPriv->RemoveAreaCallback = area->RemoveAreaCallback;
+ area->RemoveAreaCallback = NULL;
+ pApmPriv->devPriv = area->devPrivate.ptr;
+ if (((pix->drawable.x + pApm->displayWidth * pix->drawable.y) * pApm->bitsPerPixel) & 32767) {
+ int p1;
+
+ /*
+ * Not aligned on a 4KB boundary, need to move it around.
+ */
+ xf86FreeOffscreenArea(area);
+ p2 = 1;
+ while (!(p2 & width))
+ p2 *= 2;
+ p1 = 4096 / p2 - 1;
+ switch(pApm->bitsPerPixel) {
+ case 16:
+ p2 /= 2;
+ break;
+ case 32:
+ p2 /= 4;
+ break;
+ }
+ ((XAAPixmapPtr)XAA_GET_PIXMAP_PRIVATE(pix))->offscreenArea = area =
+ xf86AllocateOffscreenArea(pScrn->pScreen,
+ pix->drawable.width, pix->drawable.height + p1,
+ p2, NULL, NULL, pApmPriv->devPriv);
+ if (area) {
+ int devKind = pApm->bytesPerScanline, off = devKind * p1;
+ int h, goal = (-area->box.x1 * (pApm->bitsPerPixel >> 3) - area->box.y1 * devKind) & 4095;
+
+ pix->drawable.x = area->box.x1;
+ for (h = p1; h >= 0; h--, off -= devKind)
+ if ((off & 4095) == goal)
+ break;
+ pix->drawable.y = area->box.y1 + h;
+ }
+ else {
+ /*
+ * Failed, return the old one
+ */
+ switch(pApm->bitsPerPixel) {
+ case 24:
+ case 8: p2 = 4; break;
+ case 16: p2 = 2; break;
+ case 32: p2 = 1; break;
+ default: p2 = 0; break;
+ }
+ ((XAAPixmapPtr)XAA_GET_PIXMAP_PRIVATE(pix))->offscreenArea = area =
+ xf86AllocateOffscreenArea(pScrn->pScreen,
+ pix->drawable.width, pix->drawable.height,
+ p2,
+ pApmPriv->MoveAreaCallback,
+ pApmPriv->RemoveAreaCallback,
+ pApmPriv->devPriv);
+ /* The allocate can not fail: we just removed the old one. */
+ pix->drawable.x = area->box.x1;
+ pix->drawable.y = area->box.y1;
+ return 0;
+ }
+ }
+ REGION_INIT(pApm->pScreen, &NewReg, &area->box, 1)
+ REGION_UNION(pApm->pScreen, &pApm->apmLockedRegion, &pApm->apmLockedRegion, &NewReg);
+ REGION_UNINIT(pApm->pScreen, &NewReg);
+ return pApm->LinAddress +
+ ((pix->drawable.x + pApm->displayWidth * pix->drawable.y) * pApm->bitsPerPixel) / 8;
+ }
+
+ return 0;
+}
+
+static __inline__ void
+__xf86UnlockPixmap(ApmPtr pApm, PixmapLinkPtr pLink)
+{
+ PixmapPtr pix = pLink->pPix;
+ ApmPixmapPtr pApmPriv = APM_GET_PIXMAP_PRIVATE(pix);
+ XAAPixmapPtr pXAAPriv = XAA_GET_PIXMAP_PRIVATE(pix);
+ FBAreaPtr area = pXAAPriv->offscreenArea;
+
+ if (!area)
+ area = pLink->area;
+ if ((pXAAPriv->flags & OFFSCREEN) && !area->MoveAreaCallback && !area->RemoveAreaCallback) {
+ RegionRec NewReg;
+
+ area->MoveAreaCallback = pApmPriv->MoveAreaCallback;
+ area->RemoveAreaCallback = pApmPriv->RemoveAreaCallback;
+ area->devPrivate.ptr = pApmPriv->devPriv;
+ REGION_INIT(pApm->pScreen, &NewReg, &area->box, 1)
+ REGION_SUBTRACT(pApm->pScreen, &pApm->apmLockedRegion, &pApm->apmLockedRegion, &NewReg);
+ REGION_UNINIT(pApm->pScreen, &NewReg);
+ }
+}
+
+void
+xf86RushUnlockPixmap(int scrnIndex, PixmapPtr pix)
+{
+ APMDECL(xf86Screens[scrnIndex]);
+ PixmapLinkPtr pLink = GET_XAAINFORECPTR_FROM_SCREEN(xf86Screens[scrnIndex]->pScreen)->OffscreenPixmaps;
+
+ if (pApm->apmLock) {
+ /*
+ * This is just an attempt, because Daryll is tampering with MY
+ * registers.
+ */
+ if (!pApm->noLinear) {
+ WRXB(0xDB, (RDXB(0xDB) & 0xF4) | 0x0A);
+ ApmWriteSeq(0x1B, 0x20);
+ ApmWriteSeq(0x1C, 0x2F);
+ }
+ else {
+ unsigned char tmp = RDXB_IOP(0xDB);
+ WRXB_IOP(0xDB, (tmp & 0xF4) | 0x0A);
+ wrinx(0x3C4, 0x1B, 0x20);
+ wrinx(0x3C4, 0x1C, 0x2F);
+ }
+ pApm->apmLock = FALSE;
+ }
+ while (pLink && pLink->pPix != pix)
+ pLink = pLink->next;
+ __xf86UnlockPixmap(pApm, pLink);
+}
+
+void
+xf86RushUnlockAllPixmaps()
+{
+ int scrnIndex;
+
+ for (scrnIndex = 0; scrnIndex < screenInfo.numScreens; scrnIndex++) {
+ PixmapLinkPtr pLink = GET_XAAINFORECPTR_FROM_SCREEN(xf86Screens[scrnIndex]->pScreen)->OffscreenPixmaps;
+
+ while(pLink) {
+ __xf86UnlockPixmap(APMPTR(xf86Screens[scrnIndex]), pLink);
+ pLink = pLink->next;
+ }
+ }
+}
+
+#ifdef XF86RUSH_EXT
+/*
+
+Copyright (c) 1998 Daryll Strauss
+
+*/
+
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "scrnintstr.h"
+#define _XF86RUSH_SERVER_
+#include "xf86rushstr.h"
+
+static unsigned char RushReqCode = 0;
+static int RushErrorBase;
+
+static DISPATCH_PROC(ProcXF86RushDispatch);
+static DISPATCH_PROC(ProcXF86RushQueryVersion);
+static DISPATCH_PROC(ProcXF86RushLockPixmap);
+static DISPATCH_PROC(ProcXF86RushUnlockPixmap);
+static DISPATCH_PROC(ProcXF86RushUnlockAllPixmaps);
+
+static DISPATCH_PROC(SProcXF86RushDispatch);
+
+static void XF86RushResetProc(ExtensionEntry* extEntry);
+
+void
+XFree86RushExtensionInit()
+{
+ ExtensionEntry* extEntry;
+
+ if ((extEntry = AddExtension(XF86RUSHNAME,
+ XF86RushNumberEvents,
+ XF86RushNumberErrors,
+ ProcXF86RushDispatch,
+ SProcXF86RushDispatch,
+ XF86RushResetProc,
+ StandardMinorOpcode))) {
+ RushReqCode = (unsigned char)extEntry->base;
+ RushErrorBase = extEntry->errorBase;
+ }
+}
+
+/*ARGSUSED*/
+static void
+XF86RushResetProc (extEntry)
+ ExtensionEntry* extEntry;
+{
+}
+
+static int
+ProcXF86RushQueryVersion(client)
+ register ClientPtr client;
+{
+ xXF86RushQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xXF86RushQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = XF86RUSH_MAJOR_VERSION;
+ rep.minorVersion = XF86RUSH_MINOR_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+ WriteToClient(client, sizeof(xXF86RushQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+static int
+ProcXF86RushLockPixmap(client)
+ register ClientPtr client;
+{
+ REQUEST(xXF86RushLockPixmapReq);
+ xXF86RushLockPixmapReply rep;
+ PixmapPtr pix;
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ REQUEST_SIZE_MATCH(xXF86RushLockPixmapReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ pix = (PixmapPtr)SecurityLookupIDByType(client,
+ stuff->pixmap, RT_PIXMAP,
+ SecurityReadAccess);
+ rep.addr = xf86RushLockPixmap(stuff->screen, pix);
+
+ WriteToClient(client, SIZEOF(xXF86RushLockPixmapReply), (char*)&rep);
+ return client->noClientException;
+}
+
+static int
+ProcXF86RushUnlockPixmap(client)
+ register ClientPtr client;
+{
+ REQUEST(xXF86RushUnlockPixmapReq);
+ PixmapPtr pix;
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ REQUEST_SIZE_MATCH(xXF86RushUnlockPixmapReq);
+ pix = (PixmapPtr)SecurityLookupIDByType(client,
+ stuff->pixmap, RT_PIXMAP,
+ SecurityReadAccess);
+ xf86RushUnlockPixmap(stuff->screen, pix);
+ return client->noClientException;
+}
+
+static int
+ProcXF86RushUnlockAllPixmaps(client)
+ register ClientPtr client;
+{
+
+ REQUEST_SIZE_MATCH(xXF86RushUnlockAllPixmapsReq);
+ xf86RushUnlockAllPixmaps();
+ return client->noClientException;
+}
+
+int
+ProcXF86RushDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+
+ if (!LocalClient(client))
+ return RushErrorBase + XF86RushClientNotLocal;
+
+ switch (stuff->data)
+ {
+ case X_XF86RushQueryVersion:
+ return ProcXF86RushQueryVersion(client);
+ case X_XF86RushLockPixmap:
+ return ProcXF86RushLockPixmap(client);
+ case X_XF86RushUnlockPixmap:
+ return ProcXF86RushUnlockPixmap(client);
+ case X_XF86RushUnlockAllPixmaps:
+ return ProcXF86RushUnlockAllPixmaps(client);
+ default:
+ return BadRequest;
+ }
+}
+
+int
+SProcXF86RushDispatch (client)
+ register ClientPtr client;
+{
+ return RushErrorBase + XF86RushClientNotLocal;
+}
+#endif /* XF86RUSH_EXT */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile
new file mode 100644
index 000000000..8e41284a4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile
@@ -0,0 +1,134 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile,v 1.10 1999/08/14 10:49:38 dawes Exp $
+XCOMM
+XCOMM Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+XCOMM
+XCOMM Permission to use, copy, modify, distribute, and sell this software and
+XCOMM its documentation for any purpose is hereby granted without fee, provided
+XCOMM that the above copyright notice appear in all copies and that both that
+XCOMM copyright notice and this permission notice appear in supporting
+XCOMM documentation, and that the name of Marc Aurele La France not be used in
+XCOMM advertising or publicity pertaining to distribution of the software
+XCOMM without specific, written prior permission. Marc Aurele La France makes
+XCOMM no representations about the suitability of this software for any
+XCOMM purpose. It is provided "as-is" without express or implied warranty.
+XCOMM
+XCOMM MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+XCOMM SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+XCOMM FITNESS. IN NO EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY
+XCOMM SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+XCOMM RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+XCOMM CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+XCOMM CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+XCOMM
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#ifdef ATIDriverCCOptions
+CCOPTIONS = ATIDriverCCOptions
+#endif
+
+#if DoLoadableServer
+ATIMODSRC = atimodule.c
+ATIMODOBJ = atimodule.o
+#endif
+
+SRCS = ati.c atiadapter.c atiadjust.c atibank.c atibios.c atibus.c atichip.c \
+ aticlock.c aticonsole.c aticrtc.c atidac.c atidsp.c atiident.c atiio.c \
+ atilock.c atimach64.c $(ATIMODSRC) atioption.c atipreinit.c atiprint.c \
+ atiprobe.c atiscreen.c atiutil.c ativalid.c ativga.c atividmem.c \
+ atiwonder.c
+
+OBJS = ati.o atiadapter.o atiadjust.o atibank.o atibios.o atibus.o atichip.o \
+ aticlock.o aticonsole.o aticrtc.o atidac.o atidsp.o atiident.o atiio.o \
+ atilock.o atimach64.o $(ATIMODOBJ) atioption.o atipreinit.o atiprint.o \
+ atiprobe.o atiscreen.o atiutil.o ativalid.o ativga.o atividmem.o \
+ atiwonder.o
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(XF86SRC)/rac -I$(XF86SRC) \
+ -I$(XF86SRC)/xf4bpp -I$(XF86SRC)/xf1bpp \
+ -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mfb \
+ -I$(SERVERSRC)/mi -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC) -I$(FONTINCSRC)
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget(ati,$(OBJS))
+
+InstallObjectModule(ati,$(MODULEDIR),drivers)
+
+#ifndef OS2Architecture
+DependTarget()
+#endif
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(ati.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(ati.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiadapter.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiadapter.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiadjust.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiadjust.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atibank.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atibank.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atibios.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atibios.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atibus.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atibus.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atichip.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atichip.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(aticlock.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(aticlock.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(aticonsole.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(aticonsole.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(aticrtc.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(aticrtc.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atidac.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atidac.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atidsp.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atidsp.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiident.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiident.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiio.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiio.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atilock.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atilock.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atimach64.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atimach64.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atimodule.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atimodule.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atimono.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atioption.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atioption.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atipreinit.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atipreinit.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiprint.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiprint.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atipriv.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiprobe.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiprobe.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiproto.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiregs.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiscreen.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiscreen.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atistruct.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiutil.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiutil.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(ativalid.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(ativalid.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(ativersion.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(ativga.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(ativga.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atividmem.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atividmem.h,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiwonder.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(atiwonder.h,$(DRIVERSDKDIR)/drivers/ati)
+
+InstallDriverSDKObjectModule(ati,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/ati.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/ati.c
new file mode 100644
index 000000000..efd4fe25e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/ati.c
@@ -0,0 +1,82 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ati.c,v 1.4 1999/08/01 07:57:17 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*************************************************************************/
+
+/*
+ * Author: Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * This is the ATI driver for XFree86.
+ *
+ * John Donne once said "No man is an island", and I am most certainly not an
+ * exception. Contributions, intentional or not, to this and previous versions
+ * of this driver by the following are hereby acknowledged:
+ *
+ * Thomas Roell, roell@informatik.tu-muenchen.de
+ * Per Lindqvist, pgd@compuram.bbt.se
+ * Doug Evans, dje@cygnus.com
+ * Rik Faith, faith@cs.unc.edu
+ * Arthur Tateishi, ruhtra@turing.toronto.edu
+ * Alain Hebert, aal@broue.rot.qc.ca
+ * Ton van Rosmalen, ton@stack.urc.tue.nl
+ * David Chambers, davidc@netcom.com
+ * William Shubert, wms@ssd.intel.com
+ * ATI Technologies Incorporated
+ * Robert Wolff
+ * David Dawes, dawes@xfree86.org
+ * Mark Weaver, Mark_Weaver@brown.edu
+ * Hans Nasten, nasten@everyware.se
+ * Kevin Martin, martin@cs.unc.edu
+ * Frederic Rienthaler, root@mojo.synapse.com
+ * Marc Bolduc, bolduc@cim.mcgill.ca
+ * Reuben Sumner, rasumner@undergrad.math.uwaterloo.ca
+ * Benjamin T. Yang, risk@uclink.berkeley.edu
+ * James Fast Kane, jfk2@engr.uark.edu
+ * Randall Hopper, rhh@ct.picker.com
+ * W. Marcus Miller, marcus@llnl.gov
+ *
+ * ... and, many, many others from around the world.
+ *
+ * In addition, this work would not have been possible without the active
+ * support, both moral and otherwise, of the staff and management of Computing
+ * and Network Services at the University of Alberta, in Edmonton, Alberta,
+ * Canada.
+ *
+ * The driver is intended to support all ATI adapters since their VGA Wonder
+ * V3, including OEM counterparts.
+ */
+
+#include "atiident.h"
+#include "atiprobe.h"
+#include "ativersion.h"
+
+/* The root of all evil... */
+DriverRec ATI =
+{
+ ATI_VERSION_CURRENT,
+ "ATI driver",
+ ATIIdentify,
+ ATIProbe,
+ NULL,
+ 0
+};
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/ati.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/ati.h
new file mode 100644
index 000000000..975ec43cc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/ati.h
@@ -0,0 +1,39 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ati.h,v 1.4 1999/08/01 07:57:17 dawes Exp $ */
+/*
+ * Copyright 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATI_H___
+#define ___ATI_H___ 1
+
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+#include "xf86.h"
+
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#define ATI_README "\n See README.ati for details.\n"
+
+extern DriverRec ATI;
+
+#endif /* ___ATI_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiadapter.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiadapter.c
new file mode 100644
index 000000000..d312bfe05
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiadapter.c
@@ -0,0 +1,46 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiadapter.c,v 1.3 1999/07/06 11:38:23 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "atiadapter.h"
+
+/*
+ * Adapter-related definitions.
+ */
+const char *ATIAdapterNames[] =
+{
+ "Unknown",
+ "ATI EGA Wonder800",
+ "ATI EGA Wonder800+",
+ "IBM VGA or compatible",
+ "ATI VGA Basic16",
+ "ATI VGA Wonder V3",
+ "ATI VGA Wonder V4",
+ "ATI VGA Wonder V5",
+ "ATI VGA Wonder+",
+ "ATI VGA Wonder XL or XL24",
+ "ATI VGA Wonder VLB or PCI",
+ "IBM 8514/A or compatible",
+ "ATI Mach8",
+ "ATI Mach32",
+ "ATI Mach64"
+};
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiadapter.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiadapter.h
new file mode 100644
index 000000000..558384416
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiadapter.h
@@ -0,0 +1,51 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiadapter.h,v 1.3 1999/07/06 11:38:23 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIADAPTER_H___
+#define ___ATIADAPTER_H___ 1
+
+/*
+ * Adapter-related definitions.
+ */
+typedef enum
+{
+ ATI_ADAPTER_NONE = 0,
+ ATI_ADAPTER_EGA,
+ ATI_ADAPTER_EGA_PLUS,
+ ATI_ADAPTER_VGA,
+ ATI_ADAPTER_BASIC,
+ ATI_ADAPTER_V3,
+ ATI_ADAPTER_V4,
+ ATI_ADAPTER_V5,
+ ATI_ADAPTER_PLUS,
+ ATI_ADAPTER_XL,
+ ATI_ADAPTER_NONISA,
+ ATI_ADAPTER_8514A,
+ ATI_ADAPTER_MACH8,
+ ATI_ADAPTER_MACH32,
+ ATI_ADAPTER_MACH64
+} ATIAdapterType;
+
+extern const char *ATIAdapterNames[];
+
+#endif /* ___ATIADAPTER_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiadjust.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiadjust.c
new file mode 100644
index 000000000..bf419c186
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiadjust.c
@@ -0,0 +1,211 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiadjust.c,v 1.4 1999/08/01 07:57:18 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "atiadjust.h"
+#include "atichip.h"
+#include "aticrtc.h"
+#include "atiio.h"
+#include "atilock.h"
+#include "xf86.h"
+
+/*
+ * The display start address is expressed in units of 32-bit (VGA) or 64-bit
+ * (accelerator) words where all planar modes are considered as 4bpp modes.
+ * These functions ensure the start address does not exceed architectural
+ * limits. Also, to avoid colour changes while panning, these 32-bit or 64-bit
+ * boundaries may not fall within a pixel.
+ */
+
+/*
+ * ATIAjustPreInit --
+ *
+ * This function calculates values needed to speed up the setting of the
+ * display start address.
+ */
+void
+ATIAdjustPreInit
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI
+)
+{
+ DisplayModePtr pMode;
+ unsigned long MaxBase = 0;
+ int MinX, MinY;
+
+ if ((pATI->CPIO_VGAWonder) &&
+ (pATI->Chip <= ATI_CHIP_18800_1) &&
+ (pATI->VideoRAM == 256) &&
+ (pScreenInfo->depth >= 8))
+ {
+ /* Strange, to say the least ... */
+ pATI->AdjustDepth = (pScreenInfo->bitsPerPixel + 3) >> 2;
+ pATI->AdjustMask = (unsigned long)(-32);
+ }
+ else
+ {
+ pATI->AdjustDepth = (pScreenInfo->bitsPerPixel + 7) >> 3;
+
+ pATI->AdjustMask = 64;
+ while (pATI->AdjustMask % (unsigned long)(pATI->AdjustDepth))
+ pATI->AdjustMask += 64;
+ pATI->AdjustMask =
+ ~(((pATI->AdjustMask / (unsigned long)(pATI->AdjustDepth)) >> 3) -
+ 1);
+ }
+
+ switch (pATI->NewHW.crtc)
+ {
+ case ATI_CRTC_VGA:
+ if (pATI->Chip >= ATI_CHIP_264CT)
+ {
+ MaxBase = MaxBits(CRTC_OFFSET_VGA) << 2;
+ if (pScreenInfo->depth <= 4)
+ MaxBase <<= 1;
+ }
+ else if (!pATI->CPIO_VGAWonder)
+ MaxBase = 0xFFFFU << 3;
+ else if (pATI->Chip <= ATI_CHIP_28800_6)
+ MaxBase = 0x03FFFFU << 3;
+ else /* Mach32 & Mach64 */
+ MaxBase = 0x0FFFFFU << 3;
+ break;
+
+ case ATI_CRTC_MACH64:
+ MaxBase = MaxBits(CRTC_OFFSET) << 3;
+ break;
+ }
+
+ MaxBase = (MaxBase / (unsigned long)pATI->AdjustDepth) | ~pATI->AdjustMask;
+
+ pATI->AdjustMaxX = MaxBase % pScreenInfo->displayWidth;
+ pATI->AdjustMaxY = MaxBase / pScreenInfo->displayWidth;
+
+ /*
+ * Warn about modes that are too small, or not aligned, to scroll to the
+ * bottom right corner of the virtual screen.
+ */
+ MinX = pScreenInfo->virtualX - pATI->AdjustMaxX;
+ MinY = pScreenInfo->virtualY - pATI->AdjustMaxY;
+
+ pMode = pScreenInfo->modes;
+ do
+ {
+ if ((pMode->VDisplay <= MinY) &&
+ ((pMode->VDisplay < MinY) || (pMode->HDisplay < MinX)))
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Mode \"%s\" too small to scroll to bottom right corner of"
+ " virtual resolution.\n", pMode->name);
+ else if ((pMode->HDisplay & ~pATI->AdjustMask) / pScreenInfo->xInc)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Mode \"%s\" cannot scroll to bottom right corner of virtual"
+ " resolution.\n Horizontal dimension not a multiple of %d.\n",
+ pMode->name, ~pATI->AdjustMask + 1);
+ } while ((pMode = pMode->next) != pScreenInfo->modes);
+}
+
+/*
+ * ATIAdjustFrame --
+ *
+ * This function is used to initialize the SVGA Start Address - the first
+ * displayed location in video memory. This is used to implement the virtual
+ * window.
+ */
+void
+ATIAdjustFrame
+(
+ int scrnIndex,
+ int x,
+ int y,
+ int flags
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ int Base;
+
+ /*
+ * Assume the caller has already done its homework in ensuring the physical
+ * screen is still contained in the virtual resolution.
+ */
+ if (y >= pATI->AdjustMaxY)
+ {
+ y = pATI->AdjustMaxY;
+ if (x > pATI->AdjustMaxX)
+ y--;
+ }
+
+ Base = ((((y * pScreenInfo->displayWidth) + x) & pATI->AdjustMask) *
+ pATI->AdjustDepth) >> 3;
+
+ /* Unlock registers */
+ ATIUnlock(pATI);
+
+ if ((pATI->NewHW.crtc == ATI_CRTC_VGA) && (pATI->Chip < ATI_CHIP_264CT))
+ {
+ PutReg(CRTX(pATI->CPIO_VGABase), 0x0CU, GetByte(Base, 1));
+ PutReg(CRTX(pATI->CPIO_VGABase), 0x0DU, GetByte(Base, 0));
+
+ if (pATI->CPIO_VGAWonder)
+ {
+ if (pATI->Chip <= ATI_CHIP_18800_1)
+ ATIModifyExtReg(pATI, 0xB0U, -1, 0x3FU, Base >> 10);
+ else
+ {
+ ATIModifyExtReg(pATI, 0xB0U, -1, 0xBFU, Base >> 10);
+ ATIModifyExtReg(pATI, 0xA3U, -1, 0xEFU, Base >> 13);
+
+ /*
+ * I don't know if this also applies to Mach64's, but give it a
+ * shot...
+ */
+ if (pATI->Chip >= ATI_CHIP_68800)
+ ATIModifyExtReg(pATI, 0xADU, -1, 0xF3U, Base >> 16);
+ }
+ }
+ }
+ else
+ {
+ /*
+ * On integrated controllers, there is only one set of CRTC control
+ * bits, many of which are simultaneously accessible through both VGA
+ * and accelerator I/O ports. Given VGA's architectural limitations,
+ * setting the CRTC's offset register to more than 256k needs to be
+ * done through the accelerator port.
+ */
+ if (pScreenInfo->depth <= 4)
+ {
+ outl(pATI->CPIO_CRTC_OFF_PITCH,
+ SetBits(pScreenInfo->displayWidth >> 4, CRTC_PITCH) |
+ SetBits(Base, CRTC_OFFSET));
+ }
+ else
+ {
+ if (pATI->NewHW.crtc == ATI_CRTC_VGA)
+ Base <<= 1; /* LSBit must be zero */
+ outl(pATI->CPIO_CRTC_OFF_PITCH,
+ SetBits(pScreenInfo->displayWidth >> 3, CRTC_PITCH) |
+ SetBits(Base, CRTC_OFFSET));
+ }
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiadjust.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiadjust.h
new file mode 100644
index 000000000..2685eb887
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiadjust.h
@@ -0,0 +1,34 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiadjust.h,v 1.3 1999/07/06 11:38:23 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIADJUST_H___
+#define ___ATIADJUST_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+#include "xf86str.h"
+
+extern void ATIAdjustPreInit FunctionPrototype((ScrnInfoPtr, ATIPtr));
+extern void ATIAdjustFrame FunctionPrototype((int, int, int, int));
+
+#endif /* ___ATIADJUST_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atibank.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atibank.c
new file mode 100644
index 000000000..b420cf802
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atibank.c
@@ -0,0 +1,398 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atibank.c,v 1.4 1999/08/01 07:57:18 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "atibank.h"
+#include "atiio.h"
+#include "xf86.h"
+
+/*
+ * ATI VGA Wonder V3 adapters use an ATI 18800 chip and are single-banked.
+ * Bank selection is done with bits 0x1E of ATI extended VGA register index
+ * 0xB2.
+ */
+
+/*
+ * ATIV3SetBank --
+ *
+ * Set an ATI 18800's bank number.
+ */
+void
+ATIV3SetBank
+(
+ ATIPtr pATI,
+ unsigned int iBank
+)
+{
+ ATIModifyExtReg(pATI, 0xB2U, -1, (CARD8)(~0x1EU), SetBits(iBank, 0x1EU));
+}
+
+/*
+ * ATIV3SetReadWrite --
+ *
+ * Set an ATI 18800's bank number.
+ */
+int
+ATIV3SetReadWrite
+(
+ ScreenPtr pScreen,
+ unsigned int iBank
+)
+{
+ ATIPtr pATI = ATIPTR(XF86SCRNINFO(pScreen));
+
+ ATIModifyExtReg(pATI, 0xB2U, -1, (CARD8)(~0x1EU), SetBits(iBank, 0x1EU));
+ return 0;
+}
+
+/*
+ * ATI VGA Wonder V4 and V5 adapters use an ATI 18800-1 chip. Bank selection
+ * is done with ATI extended VGA register index 0xB2. The format is:
+ *
+ * 0xE0 - Read bank select bits 0x07
+ * 0x1E - Write bank select bits 0x0F
+ * 0x01 - Read bank select bit 0x08.
+ */
+
+/*
+ * ATIV4V5SetBank --
+ *
+ * Set an ATI 18800-1's read and write bank numbers.
+ */
+void
+ATIV4V5SetBank
+(
+ ATIPtr pATI,
+ unsigned int iBank
+)
+{
+ pATI->B2Reg = SetBits(iBank, 0x1EU) | SetBits(iBank, 0xE0U) |
+ SetBits(GetBits(iBank, 0x08U), 0x01U);
+ ATIPutExtReg(0xB2U, pATI->B2Reg);
+}
+
+/*
+ * ATIV4V5SetRead --
+ *
+ * Set an ATI 18800-1's read bank number.
+ */
+int
+ATIV4V5SetRead
+(
+ ScreenPtr pScreen,
+ unsigned int iBank
+)
+{
+ ATIPtr pATI = ATIPTR(XF86SCRNINFO(pScreen));
+ CARD8 B2Reg = (pATI->B2Reg & 0x1EU) | SetBits(iBank, 0xE0U) |
+ SetBits(GetBits(iBank, 0x08U), 0x01U);
+
+ if (B2Reg != pATI->B2Reg)
+ {
+ ATIPutExtReg(0xB2U, B2Reg);
+ pATI->B2Reg = B2Reg;
+ }
+
+ return 0;
+}
+
+/*
+ * ATIV4V5SetWrite --
+ *
+ * Set an ATI 18800-1's write bank number.
+ */
+int
+ATIV4V5SetWrite
+(
+ ScreenPtr pScreen,
+ unsigned int iBank
+)
+{
+ ATIPtr pATI = ATIPTR(XF86SCRNINFO(pScreen));
+ CARD8 B2Reg = (pATI->B2Reg & 0xE1U) | SetBits(iBank, 0x1EU);
+
+ if (B2Reg != pATI->B2Reg)
+ {
+ ATIPutExtReg(0xB2U, B2Reg);
+ pATI->B2Reg = B2Reg;
+ }
+ return 0;
+}
+
+/*
+ * ATIV4V5SetReadWrite --
+ *
+ * Set an ATI 18800-1's read and write bank numbers.
+ */
+int
+ATIV4V5SetReadWrite
+(
+ ScreenPtr pScreen,
+ unsigned int iBank
+)
+{
+ ATIV4V5SetBank(ATIPTR(XF86SCRNINFO(pScreen)), iBank);
+ return 0;
+}
+
+/*
+ * In addition to ATI extended register index 0xB2, 28800's, 68800's and
+ * 88800's define banking bits in bits 0x0F of ATI extended VGA register index
+ * 0xAE. These are only needed for adapters with more than 1MB of video
+ * memory, and it is questionable whether or not they are actually implemented
+ * by 28800's and 88800's. ATI extended VGA register index 0xAE is defined as
+ * follows:
+ *
+ * 0xF0 - reserved
+ * 0x0C - read bank select bits 0x30
+ * 0x03 - write bank select bits 0x30
+ */
+
+/*
+ * ATIx8800SetBank --
+ *
+ * Set an ATI 28800's, 68800's or 88800's read and write bank numbers.
+ */
+void
+ATIx8800SetBank
+(
+ ATIPtr pATI,
+ unsigned int iBank
+)
+{
+ ATIV4V5SetBank(pATI, iBank);
+ iBank = GetBits(iBank, 0x30U);
+ ATIModifyExtReg(pATI, 0xAEU, -1, (CARD8)(~0x0FU),
+ SetBits(iBank, 0x03U) | SetBits(iBank, 0x0CU));
+}
+
+/*
+ * ATIx8800SetRead --
+ *
+ * Set an ATI 28800's, 68800's or 88800's read bank numbers.
+ */
+int
+ATIx8800SetRead
+(
+ ScreenPtr pScreen,
+ unsigned int iBank
+)
+{
+ (void) ATIV4V5SetRead(pScreen, iBank);
+ ATIModifyExtReg(ATIPTR(XF86SCRNINFO(pScreen)), 0xAEU, -1, (CARD8)(~0x0CU),
+ SetBits(GetBits(iBank, 0x30U), 0x0CU));
+ return 0;
+}
+
+/*
+ * ATIx8800SetWrite --
+ *
+ * Set an ATI 28800's, 68800's or 88800's write bank numbers.
+ */
+int
+ATIx8800SetWrite
+(
+ ScreenPtr pScreen,
+ unsigned int iBank
+)
+{
+ (void) ATIV4V5SetWrite(pScreen, iBank);
+ ATIModifyExtReg(ATIPTR(XF86SCRNINFO(pScreen)), 0xAEU, -1, (CARD8)(~0x03U),
+ SetBits(GetBits(iBank, 0x30U), 0x03U));
+ return 0;
+}
+
+/*
+ * ATIx8800SetReadWrite --
+ *
+ * Set an ATI 28800's, 68800's or 88800's read and write bank numbers.
+ */
+int
+ATIx8800SetReadWrite
+(
+ ScreenPtr pScreen,
+ unsigned int iBank
+)
+{
+ ATIx8800SetBank(ATIPTR(XF86SCRNINFO(pScreen)), iBank);
+ return 0;
+}
+
+/*
+ * Functions to simulate a banked VGA aperture using a Mach64's small dual
+ * paged apertures. There are two sets of these: one for packed modes, the
+ * other for planar modes.
+ */
+
+static CARD32
+ATIMach64MassagePackedBankNumber
+(
+ CARD8 iBank
+)
+{
+ iBank <<= 1;
+ return ((iBank + 1) << 16) | iBank;
+}
+
+/*
+ * ATIMach64SetBankPacked --
+ *
+ * Set read and write bank numbers for small dual paged apertures.
+ */
+void
+ATIMach64SetBankPacked
+(
+ ATIPtr pATI,
+ unsigned int iBank
+)
+{
+ CARD32 tmp = ATIMach64MassagePackedBankNumber(iBank);
+ outl(pATI->CPIO_MEM_VGA_RP_SEL, tmp);
+ outl(pATI->CPIO_MEM_VGA_WP_SEL, tmp);
+}
+
+/*
+ * ATIMach64SetReadPacked --
+ *
+ * Set read bank number for small dual paged apertures.
+ */
+int
+ATIMach64SetReadPacked
+(
+ ScreenPtr pScreen,
+ unsigned int iBank
+)
+{
+ outl(ATIPTR(XF86SCRNINFO(pScreen))->CPIO_MEM_VGA_RP_SEL,
+ ATIMach64MassagePackedBankNumber(iBank));
+ return 0;
+}
+
+/*
+ * ATIMach64SetWritePacked --
+ *
+ * Set write bank number for small dual paged apertures.
+ */
+int
+ATIMach64SetWritePacked
+(
+ ScreenPtr pScreen,
+ unsigned int iBank
+)
+{
+ outl(ATIPTR(XF86SCRNINFO(pScreen))->CPIO_MEM_VGA_WP_SEL,
+ ATIMach64MassagePackedBankNumber(iBank));
+ return 0;
+}
+
+/*
+ * ATIMach64SetReadWritePacked --
+ *
+ * Set read and write bank numbers for small dual paged apertures.
+ */
+int
+ATIMach64SetReadWritePacked
+(
+ ScreenPtr pScreen,
+ unsigned int iBank
+)
+{
+ ATIMach64SetBankPacked(ATIPTR(XF86SCRNINFO(pScreen)), iBank);
+ return 0;
+}
+
+static CARD32
+ATIMach64MassagePlanarBankNumber
+(
+ CARD8 iBank
+)
+{
+ iBank <<= 3;
+ return ((iBank + 4) << 16) | iBank;
+}
+
+/*
+ * ATIMach64SetBankPlanar --
+ *
+ * Set read and write bank numbers for small dual paged apertures.
+ */
+void
+ATIMach64SetBankPlanar
+(
+ ATIPtr pATI,
+ unsigned int iBank
+)
+{
+ CARD32 tmp = ATIMach64MassagePlanarBankNumber(iBank);
+ outl(pATI->CPIO_MEM_VGA_RP_SEL, tmp);
+ outl(pATI->CPIO_MEM_VGA_WP_SEL, tmp);
+}
+
+/*
+ * ATIMach64SetReadPlanar --
+ *
+ * Set read bank number for small dual paged apertures.
+ */
+int
+ATIMach64SetReadPlanar
+(
+ ScreenPtr pScreen,
+ unsigned int iBank
+)
+{
+ outl(ATIPTR(XF86SCRNINFO(pScreen))->CPIO_MEM_VGA_RP_SEL,
+ ATIMach64MassagePlanarBankNumber(iBank));
+ return 0;
+}
+
+/*
+ * ATIMach64SetWritePlanar --
+ *
+ * Set write bank number for small dual paged apertures.
+ */
+int
+ATIMach64SetWritePlanar
+(
+ ScreenPtr pScreen,
+ unsigned int iBank
+)
+{
+ outl(ATIPTR(XF86SCRNINFO(pScreen))->CPIO_MEM_VGA_WP_SEL,
+ ATIMach64MassagePlanarBankNumber(iBank));
+ return 0;
+}
+
+/*
+ * ATIMach64SetReadWritePlanar --
+ *
+ * Set read and write bank numbers for small dual paged apertures.
+ */
+int
+ATIMach64SetReadWritePlanar
+(
+ ScreenPtr pScreen,
+ unsigned int iBank
+)
+{
+ ATIMach64SetBankPlanar(ATIPTR(XF86SCRNINFO(pScreen)), iBank);
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atibank.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atibank.h
new file mode 100644
index 000000000..fbf6ce7e4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atibank.h
@@ -0,0 +1,83 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atibank.h,v 1.3 1999/07/06 11:38:24 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIBANK_H___
+#define ___ATIBANK_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+#include "mibank.h"
+
+/*
+ * Banking definitions.
+ */
+
+/*
+ * Bank selection function for VGA Wonder V3 adapters (which are
+ * single-banked).
+ */
+#define ATIV3SetRead ATIV3SetReadWrite
+#define ATIV3SetWrite ATIV3SetReadWrite
+extern miBankProc ATIV3SetReadWrite;
+
+/*
+ * Bank selection functions for VGA Wonder V4 and V5 adapters.
+ */
+extern miBankProc ATIV4V5SetRead,
+ ATIV4V5SetWrite,
+ ATIV4V5SetReadWrite;
+
+/*
+ * Bank selection functions for 28800-x, 68800-x and 88800 based adapters.
+ */
+extern miBankProc ATIx8800SetRead,
+ ATIx8800SetWrite,
+ ATIx8800SetReadWrite;
+
+/*
+ * Bank selection functions used to simulate a banked VGA aperture with a
+ * Mach64's small dual paged apertures. There are two sets of these: one for
+ * packed modes, and one for planar modes.
+ */
+extern miBankProc ATIMach64SetReadPacked,
+ ATIMach64SetWritePacked,
+ ATIMach64SetReadWritePacked;
+extern miBankProc ATIMach64SetReadPlanar,
+ ATIMach64SetWritePlanar,
+ ATIMach64SetReadWritePlanar;
+
+/*
+ * The CRT save/restore code also needs a separate banking interface that can
+ * used before ATIScreenInit() is called.
+ */
+
+typedef void ATIBankProc FunctionPrototype((ATIPtr, unsigned int));
+typedef ATIBankProc *ATIBankProcPtr;
+
+extern ATIBankProc ATIV3SetBank,
+ ATIV4V5SetBank,
+ ATIx8800SetBank,
+ ATIMach64SetBankPacked,
+ ATIMach64SetBankPlanar;
+
+#endif /* ___ATIBANK_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atibios.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atibios.c
new file mode 100644
index 000000000..57bf3f517
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atibios.c
@@ -0,0 +1,57 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atibios.c,v 1.2 1999/08/21 13:48:30 dawes Exp $ */
+/*
+ * Copyright 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "ati.h"
+#include "atibios.h"
+#include "atistruct.h"
+
+/*
+ * ATIReadBIOS --
+ *
+ * This function is called to read in an adapter's BIOS, or parts thereof.
+ */
+int
+ATIReadBIOS
+(
+ ATIPtr pATI,
+ pointer Buffer,
+ unsigned long Offset,
+ int Length
+)
+{
+ pciVideoPtr pVideo;
+ pciConfigPtr pPCI;
+
+ /* Read PCI adapter expansion ROM */
+ if ((pVideo = pATI->PCIInfo))
+ {
+ pPCI = (pciConfigPtr)(pVideo->thisCard);
+ pATI->BIOSBase = PCIGETROM(pciReadLong(pPCI->tag, PCI_MAP_ROM_REG));
+ return xf86ReadPciBIOS(Offset, pPCI->tag, 0, Buffer, Length);
+ }
+
+ /* Read legacy ROM */
+ if (!pATI->BIOSBase)
+ pATI->BIOSBase = 0x000C0000U;
+ return xf86ReadBIOS(pATI->BIOSBase, Offset, Buffer, Length);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atibios.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atibios.h
new file mode 100644
index 000000000..3c3878e03
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atibios.h
@@ -0,0 +1,34 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atibios.h,v 1.1 1999/08/01 07:57:18 dawes Exp $ */
+/*
+ * Copyright 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIBIOS_H___
+#define ___ATIBIOS_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+#include "Xmd.h"
+
+extern int ATIReadBIOS FunctionPrototype((ATIPtr, pointer, unsigned long,
+ int));
+
+#endif /* ___ATIBIOS_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atibus.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atibus.c
new file mode 100644
index 000000000..f841511e6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atibus.c
@@ -0,0 +1,167 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atibus.c,v 1.5 1999/08/21 13:48:30 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "atiadapter.h"
+#include "atibus.h"
+#include "atichip.h"
+#include "atiio.h"
+#include "ativersion.h"
+#include "xf86Resources.h"
+#include "xf86.h"
+
+/*
+ * Definitions related to an adapter's system bus interface.
+ */
+
+const char *ATIBusNames[] =
+{
+ "16-Bit ISA",
+ "EISA",
+ "16-Bit MicroChannel",
+ "32-Bit MicroChannel",
+ "386SX Local Bus",
+ "386DX Local Bus",
+ "VESA Local Bus",
+ "PCI",
+ "AGP"
+};
+
+/*
+ * ATIClaimResources --
+ *
+ * This function registers most of the bus resources used by an adapter. The
+ * exceptions are PCI-configured resources and non-PCI non-AGP linear
+ * apertures, both of which are registered by ATIPreInit(). This function also
+ * attempts to register unshareable resources for inactive PCI adapters,
+ * whether or not they are relocatable.
+ */
+static void
+ATIClaimResources
+(
+ ATIPtr pATI,
+ Bool Active
+)
+{
+ resPtr pResources;
+ resRange Resources[2] = {{0, 0, 0}, _END};
+
+ /* Claim VGA and VGAWonder resources */
+ if ((pATI->VGAAdapter != ATI_ADAPTER_NONE) && (Active || !pATI->SharedVGA))
+ {
+ /*
+ * 18800-x's are the only ATI controllers that decode all ISA aliases
+ * of VGA and VGA Wonder I/O ports. Other x8800's do not decode >any<
+ * VGA aliases, but do decode VGA Wonder aliases whose most significant
+ * nibble is zero.
+ */
+ xf86ClaimFixedResources(
+ (pATI->Chip <= ATI_CHIP_18800_1) ?
+ (pATI->SharedVGA ? resVgaSparseShared : resVgaSparseExclusive) :
+ (pATI->SharedVGA ? resVgaShared : resVgaExclusive),
+ pATI->iEntity);
+
+ if (pATI->CPIO_VGAWonder)
+ {
+ if (pATI->SharedVGA)
+ Resources[0].type = ResShrIoSparse;
+ else
+ Resources[0].type = ResExcIoSparse;
+ Resources[0].rBase = pATI->CPIO_VGAWonder;
+ if (pATI->Chip <= ATI_CHIP_18800_1)
+ Resources[0].rMask = 0x03FEU;
+ else
+ Resources[0].rMask = 0xF3FEU;
+
+ xf86ClaimFixedResources(Resources, pATI->iEntity);
+ }
+ }
+
+ if (Active || !pATI->SharedAccelerator)
+ {
+ /* Claim 8514/A resources */
+ if (pATI->ChipHasSUBSYS_CNTL)
+ xf86ClaimFixedResources(
+ pATI->SharedAccelerator ? res8514Shared : res8514Exclusive,
+ pATI->iEntity);
+
+ /* Claim Mach64 sparse I/O resources */
+ if ((pATI->Adapter == ATI_ADAPTER_MACH64) &&
+ (pATI->CPIODecoding == SPARSE_IO))
+ {
+ if (pATI->SharedAccelerator)
+ Resources[0].type = ResShrIoSparse;
+ else
+ Resources[0].type = ResExcIoSparse;
+ Resources[0].rBase = pATI->CPIOBase;
+ Resources[0].rMask = 0x03FCU;
+
+ xf86ClaimFixedResources(Resources, pATI->iEntity);
+ }
+
+ /* Register relocatable resources for inactive adapters */
+ if (!Active)
+ {
+ pResources =
+ xf86RegisterResources(pATI->iEntity, NULL, ResExclusive);
+ pResources =
+ xf86ReallocatePciResources(pATI->iEntity, pResources);
+ if (pResources)
+ {
+ xf86Msg(X_WARNING,
+ ATI_NAME ": Unable to register the following resources"
+ " for inactive adapter:\n");
+ xf86PrintResList(1, pResources);
+ }
+ }
+ }
+}
+
+/*
+ * ATIClaimBusSlot --
+ *
+ * Claim an adapter and register its resources.
+ */
+int
+ATIClaimBusSlot
+(
+ DriverPtr pDriver,
+ int Chipset,
+ GDevPtr pGDev,
+ Bool Active,
+ ATIPtr pATI
+)
+{
+ pciVideoPtr pVideo = pATI->PCIInfo;
+
+ if (pVideo)
+ pATI->iEntity =
+ xf86ClaimPciSlot(pVideo->bus, pVideo->device, pVideo->func,
+ pDriver, Chipset, pGDev, Active);
+ else
+ pATI->iEntity = xf86ClaimIsaSlot(pDriver, Chipset, pGDev, Active);
+
+ if (pATI->iEntity >= 0)
+ ATIClaimResources(pATI, Active);
+
+ return pATI->iEntity;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atibus.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atibus.h
new file mode 100644
index 000000000..98ad93326
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atibus.h
@@ -0,0 +1,52 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atibus.h,v 1.4 1999/08/01 07:57:19 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIBUS_H___
+#define ___ATIBUS_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+#include "xf86str.h"
+
+/*
+ * Definitions related to an adapter's system bus interface.
+ */
+typedef enum
+{
+ ATI_BUS_ISA = 0,
+ ATI_BUS_EISA,
+ ATI_BUS_MCA16,
+ ATI_BUS_MCA32,
+ ATI_BUS_SXLB,
+ ATI_BUS_DXLB,
+ ATI_BUS_VLB,
+ ATI_BUS_PCI,
+ ATI_BUS_AGP
+} ATIBusType;
+
+extern const char *ATIBusNames[];
+
+extern int ATIClaimBusSlot FunctionPrototype((DriverPtr, int, GDevPtr, Bool,
+ ATIPtr));
+
+#endif /* ___ATIBUS_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.c
new file mode 100644
index 000000000..91a60f955
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.c
@@ -0,0 +1,436 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.c,v 1.6 1999/08/21 13:48:31 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "ati.h"
+#include "atibus.h"
+#include "atichip.h"
+#include "atiio.h"
+#include "ativersion.h"
+
+/*
+ * Chip-related definitions.
+ */
+const char *ATIChipNames[] =
+{
+ "Unknown",
+ "IBM VGA or compatible",
+ "ATI 18800",
+ "ATI 18800-1",
+ "ATI 28800-2",
+ "ATI 28800-4",
+ "ATI 28800-5",
+ "ATI 28800-6",
+ "IBM 8514/A",
+ "Chips & Technologies 82C480",
+ "ATI 38800-1",
+ "ATI 68800",
+ "ATI 68800-3",
+ "ATI 68800-6",
+ "ATI 68800LX",
+ "ATI 68800AX",
+ "ATI 88800GX-C",
+ "ATI 88800GX-D",
+ "ATI 88800GX-E",
+ "ATI 88800GX-F",
+ "ATI 88800GX",
+ "ATI 88800CX",
+ "ATI 264CT",
+ "ATI 264ET",
+ "ATI 264VT",
+ "ATI 3D Rage",
+ "ATI 264VT-B",
+ "ATI 3D Rage II",
+ "ATI 264VT3",
+ "ATI 3D Rage II+DVD",
+ "ATI 3D Rage LT",
+ "ATI 264VT4",
+ "ATI 3D Rage IIc",
+ "ATI 3D Rage Pro",
+ "ATI 3D Rage LT Pro",
+ "ATI 3D Rage XL or XC",
+ "ATI unknown Mach64",
+};
+
+const char *ATIFoundryNames[] =
+ { "SGS", "NEC", "KCS", "UMC", "4", "5", "6", "UMC" };
+
+/*
+ * ATIMach32ChipID --
+ *
+ * Set variables whose value is dependent upon an 68800's CHIP_ID register.
+ */
+void
+ATIMach32ChipID
+(
+ ATIPtr pATI
+)
+{
+ CARD16 IOValue = inw(CHIP_ID);
+ pATI->ChipType = GetBits(IOValue, CHIP_CODE_0 | CHIP_CODE_1);
+ pATI->ChipClass = GetBits(IOValue, CHIP_CLASS);
+ pATI->ChipRevision = GetBits(IOValue, CHIP_REV);
+ pATI->ChipRev = pATI->ChipRevision;
+ if (IOValue == 0xFFFFU)
+ IOValue = 0;
+ switch (GetBits(IOValue, CHIP_CODE_0 | CHIP_CODE_1))
+ {
+ case OldChipID('A', 'A'):
+ pATI->Chip = ATI_CHIP_68800_3;
+ break;
+
+ case OldChipID('X', 'X'):
+ pATI->Chip = ATI_CHIP_68800_6;
+ break;
+
+ case OldChipID('L', 'X'):
+ pATI->Chip = ATI_CHIP_68800LX;
+ break;
+
+ case OldChipID('A', 'X'):
+ pATI->Chip = ATI_CHIP_68800AX;
+ break;
+
+ default:
+ pATI->Chip = ATI_CHIP_68800;
+ break;
+ }
+}
+
+/*
+ * ATIMach64ChipID --
+ *
+ * Set variables whose value is dependent upon a Mach64's CONFIG_CHIP_ID
+ * register.
+ */
+void
+ATIMach64ChipID
+(
+ ATIPtr pATI,
+ const CARD16 ExpectedChipType
+)
+{
+ CARD32 IOValue = inl(ATIIOPort(CONFIG_CHIP_ID));
+ pATI->ChipType = GetBits(IOValue, 0xFFFFU);
+ pATI->ChipClass = GetBits(IOValue, CFG_CHIP_CLASS);
+ pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REV);
+ pATI->ChipVersion = GetBits(IOValue, CFG_CHIP_VERSION);
+ pATI->ChipFoundry = GetBits(IOValue, CFG_CHIP_FOUNDRY);
+ pATI->ChipRev = pATI->ChipRevision;
+ switch (pATI->ChipType)
+ {
+ case OldChipID('G', 'X'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('G', 'X'):
+ switch (pATI->ChipRevision)
+ {
+ case 0x00U:
+ pATI->Chip = ATI_CHIP_88800GXC;
+ break;
+
+ case 0x01U:
+ pATI->Chip = ATI_CHIP_88800GXD;
+ break;
+
+ case 0x02U:
+ pATI->Chip = ATI_CHIP_88800GXE;
+ break;
+
+ case 0x03U:
+ pATI->Chip = ATI_CHIP_88800GXF;
+ break;
+
+ default:
+ pATI->Chip = ATI_CHIP_88800GX;
+ break;
+ }
+ break;
+
+ case OldChipID('C', 'X'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('C', 'X'):
+ pATI->Chip = ATI_CHIP_88800CX;
+ break;
+
+ case OldChipID('C', 'T'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('C', 'T'):
+ pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION);
+ pATI->Chip = ATI_CHIP_264CT;
+ pATI->BusType = ATI_BUS_PCI;
+ break;
+
+ case OldChipID('E', 'T'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('E', 'T'):
+ pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION);
+ pATI->Chip = ATI_CHIP_264ET;
+ pATI->BusType = ATI_BUS_PCI;
+ break;
+
+ case OldChipID('V', 'T'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('V', 'T'):
+ pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION);
+ pATI->Chip = ATI_CHIP_264VT;
+ pATI->BusType = ATI_BUS_PCI;
+ /* Some early GT's are detected as VT's */
+ if (ExpectedChipType && (pATI->ChipType != ExpectedChipType))
+ {
+ if (ExpectedChipType == NewChipID('G', 'T'))
+ pATI->Chip = ATI_CHIP_264GT;
+ else
+ xf86Msg(X_WARNING,
+ ATI_NAME ": Mach64 chip type probe discrepancy"
+ " detected: PCI=0x%04X; CHIP_ID=0x%04X.\n",
+ ExpectedChipType, pATI->ChipType);
+ }
+ else if (pATI->ChipVersion)
+ pATI->Chip = ATI_CHIP_264VTB;
+ break;
+
+ case OldChipID('G', 'T'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('G', 'T'):
+ pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION);
+ pATI->BusType = ATI_BUS_PCI;
+ if (!pATI->ChipVersion)
+ pATI->Chip = ATI_CHIP_264GT;
+ else
+ pATI->Chip = ATI_CHIP_264GTB;
+ break;
+
+ case OldChipID('V', 'U'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('V', 'U'):
+ pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION);
+ pATI->Chip = ATI_CHIP_264VT3;
+ pATI->BusType = ATI_BUS_PCI;
+ break;
+
+ case OldChipID('G', 'U'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('G', 'U'):
+ pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION);
+ pATI->Chip = ATI_CHIP_264GTDVD;
+ pATI->BusType = ATI_BUS_PCI;
+ break;
+
+ case OldChipID('L', 'G'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('L', 'G'):
+ pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION);
+ pATI->Chip = ATI_CHIP_264LT;
+ pATI->BusType = ATI_BUS_PCI;
+ break;
+
+ case OldChipID('V', 'V'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('V', 'V'):
+ pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION);
+ pATI->Chip = ATI_CHIP_264VT4;
+ pATI->BusType = ATI_BUS_PCI;
+ break;
+
+ case OldChipID('G', 'V'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('G', 'V'):
+ pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION);
+ pATI->Chip = ATI_CHIP_264GT2C;
+ pATI->BusType = ATI_BUS_PCI;
+ break;
+
+ case OldChipID('G', 'W'):
+ case OldChipID('G', 'Z'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('G', 'W'):
+ case NewChipID('G', 'Z'):
+ pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION);
+ pATI->Chip = ATI_CHIP_264GT2C;
+ pATI->BusType = ATI_BUS_AGP;
+ break;
+
+ case OldChipID('G', 'I'):
+ case OldChipID('G', 'P'):
+ case OldChipID('G', 'Q'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('G', 'I'):
+ case NewChipID('G', 'P'):
+ case NewChipID('G', 'Q'):
+ pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION);
+ pATI->Chip = ATI_CHIP_264GTPRO;
+ pATI->BusType = ATI_BUS_PCI;
+ break;
+
+ case OldChipID('G', 'B'):
+ case OldChipID('G', 'D'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('G', 'B'):
+ case NewChipID('G', 'D'):
+ pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION);
+ pATI->Chip = ATI_CHIP_264GTPRO;
+ pATI->BusType = ATI_BUS_AGP;
+ break;
+
+ case OldChipID('L', 'I'):
+ case OldChipID('L', 'P'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('L', 'I'):
+ case NewChipID('L', 'P'):
+ pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION);
+ pATI->Chip = ATI_CHIP_264LTPRO;
+ pATI->BusType = ATI_BUS_PCI;
+ pATI->LCDVBlendFIFOSize = 800;
+ break;
+
+ case OldChipID('L', 'B'):
+ case OldChipID('L', 'D'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('L', 'B'):
+ case NewChipID('L', 'D'):
+ pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION);
+ pATI->Chip = ATI_CHIP_264LTPRO;
+ pATI->BusType = ATI_BUS_AGP;
+ pATI->LCDVBlendFIFOSize = 800;
+ break;
+
+ case OldChipID('G', 'O'):
+ case OldChipID('G', 'R'):
+ case OldChipID('G', 'S'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('G', 'O'):
+ case NewChipID('G', 'R'):
+ case NewChipID('G', 'S'):
+ pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION);
+ pATI->Chip = ATI_CHIP_264XL;
+ pATI->BusType = ATI_BUS_PCI;
+ pATI->LCDVBlendFIFOSize = 1024;
+ break;
+
+ case OldChipID('G', 'M'):
+ case OldChipID('G', 'N'):
+ pATI->ChipType = OldToNewChipID(pATI->ChipType);
+ case NewChipID('G', 'M'):
+ case NewChipID('G', 'N'):
+ pATI->ChipRevision = GetBits(IOValue, CFG_CHIP_REVISION);
+ pATI->Chip = ATI_CHIP_264XL;
+ pATI->BusType = ATI_BUS_AGP;
+ pATI->LCDVBlendFIFOSize = 1024;
+ break;
+
+ default:
+ pATI->Chip = ATI_CHIP_Mach64;
+ break;
+ }
+}
+
+/*
+ * ATIPCIChip --
+ *
+ * This returns the ATI_CHIP_* value (generally) associated with a particular
+ * ChipID/ChipRev combination.
+ */
+ATIChipType
+ATIChipID
+(
+ const CARD16 ChipID,
+ const CARD8 ChipRev
+)
+{
+ switch (ChipID)
+ {
+ case OldChipID('A', 'A'): case NewChipID('A', 'A'):
+ return ATI_CHIP_68800_3;
+
+ case OldChipID('X', 'X'): case NewChipID('X', 'X'):
+ return ATI_CHIP_68800_6;
+
+ case OldChipID('L', 'X'): case NewChipID('L', 'X'):
+ return ATI_CHIP_68800LX;
+
+ case OldChipID('A', 'X'): case NewChipID('A', 'X'):
+ return ATI_CHIP_68800AX;
+
+ case OldChipID('G', 'X'): case NewChipID('G', 'X'):
+ return ATI_CHIP_88800GX;
+
+ case OldChipID('C', 'X'): case NewChipID('C', 'X'):
+ return ATI_CHIP_88800CX;
+
+ case OldChipID('C', 'T'): case NewChipID('C', 'T'):
+ return ATI_CHIP_264CT;
+
+ case OldChipID('E', 'T'): case NewChipID('E', 'T'):
+ return ATI_CHIP_264ET;
+
+ case OldChipID('V', 'T'): case NewChipID('V', 'T'):
+ /* For simplicity, ignore ChipID discrepancy that can occur here */
+ if (!(ChipRev & GetBits(CFG_CHIP_VERSION, CFG_CHIP_REV)))
+ return ATI_CHIP_264VT;
+ return ATI_CHIP_264VTB;
+
+ case OldChipID('G', 'T'): case NewChipID('G', 'T'):
+ if (!(ChipRev & GetBits(CFG_CHIP_VERSION, CFG_CHIP_REV)))
+ return ATI_CHIP_264GT;
+ return ATI_CHIP_264GTB;
+
+ case OldChipID('V', 'U'): case NewChipID('V', 'U'):
+ return ATI_CHIP_264VT3;
+
+ case OldChipID('G', 'U'): case NewChipID('G', 'U'):
+ return ATI_CHIP_264GTDVD;
+
+ case OldChipID('L', 'G'): case NewChipID('L', 'G'):
+ return ATI_CHIP_264LT;
+
+ case OldChipID('V', 'V'): case NewChipID('V', 'V'):
+ return ATI_CHIP_264VT4;
+
+ case OldChipID('G', 'V'): case NewChipID('G', 'V'):
+ case OldChipID('G', 'W'): case NewChipID('G', 'W'):
+ case OldChipID('G', 'Z'): case NewChipID('G', 'Z'):
+ return ATI_CHIP_264GT2C;
+
+ case OldChipID('G', 'B'): case NewChipID('G', 'B'):
+ case OldChipID('G', 'D'): case NewChipID('G', 'D'):
+ case OldChipID('G', 'I'): case NewChipID('G', 'I'):
+ case OldChipID('G', 'P'): case NewChipID('G', 'P'):
+ case OldChipID('G', 'Q'): case NewChipID('G', 'Q'):
+ return ATI_CHIP_264GTPRO;
+
+ case OldChipID('L', 'B'): case NewChipID('L', 'B'):
+ case OldChipID('L', 'D'): case NewChipID('L', 'D'):
+ case OldChipID('L', 'I'): case NewChipID('L', 'I'):
+ case OldChipID('L', 'P'): case NewChipID('L', 'P'):
+ return ATI_CHIP_264LTPRO;
+
+ case OldChipID('G', 'M'): case NewChipID('G', 'M'):
+ case OldChipID('G', 'N'): case NewChipID('G', 'N'):
+ case OldChipID('G', 'O'): case NewChipID('G', 'O'):
+ case OldChipID('G', 'R'): case NewChipID('G', 'R'):
+ case OldChipID('G', 'S'): case NewChipID('G', 'S'):
+ return ATI_CHIP_264XL;
+
+ default:
+ return ATI_CHIP_Mach64;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.h
new file mode 100644
index 000000000..8bcf4d448
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.h
@@ -0,0 +1,112 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atichip.h,v 1.5 1999/07/06 11:38:25 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATICHIP_H___
+#define ___ATICHIP_H___ 1
+
+#include "atipriv.h"
+#include "atiregs.h"
+
+/*
+ * Chip-related definitions.
+ */
+typedef enum
+{
+ ATI_CHIP_NONE = 0,
+ ATI_CHIP_VGA, /* Generic VGA */
+ ATI_CHIP_18800,
+ ATI_CHIP_18800_1,
+ ATI_CHIP_28800_2,
+ ATI_CHIP_28800_4,
+ ATI_CHIP_28800_5,
+ ATI_CHIP_28800_6,
+ ATI_CHIP_8514A, /* 8514/A */
+ ATI_CHIP_CT480, /* 8514/A clone */
+ ATI_CHIP_38800_1, /* Mach8 */
+ ATI_CHIP_68800, /* Mach32 */
+ ATI_CHIP_68800_3, /* Mach32 */
+ ATI_CHIP_68800_6, /* Mach32 */
+ ATI_CHIP_68800LX, /* Mach32 */
+ ATI_CHIP_68800AX, /* Mach32 */
+ ATI_CHIP_88800GXC, /* Mach64 */
+ ATI_CHIP_88800GXD, /* Mach64 */
+ ATI_CHIP_88800GXE, /* Mach64 */
+ ATI_CHIP_88800GXF, /* Mach64 */
+ ATI_CHIP_88800GX, /* Mach64 */
+ ATI_CHIP_88800CX, /* Mach64 */
+ ATI_CHIP_264CT, /* Mach64 */
+ ATI_CHIP_264ET, /* Mach64 */
+ ATI_CHIP_264VT, /* Mach64 */
+ ATI_CHIP_264GT, /* Mach64 */
+ ATI_CHIP_264VTB, /* Mach64 */
+ ATI_CHIP_264GTB, /* Mach64 */
+ ATI_CHIP_264VT3, /* Mach64 */
+ ATI_CHIP_264GTDVD, /* Mach64 */
+ ATI_CHIP_264LT, /* Mach64 */
+ ATI_CHIP_264VT4, /* Mach64 */
+ ATI_CHIP_264GT2C, /* Mach64 */
+ ATI_CHIP_264GTPRO, /* Mach64 */
+ ATI_CHIP_264LTPRO, /* Mach64 */
+ ATI_CHIP_264XL, /* Mach64 */
+ ATI_CHIP_Mach64 /* Mach64 */
+} ATIChipType;
+
+extern const char *ATIChipNames[];
+
+/*
+ * Foundry codes for 264xT's.
+ */
+typedef enum
+{
+ ATI_FOUNDRY_SGS, /* SGS-Thompson */
+ ATI_FOUNDRY_NEC, /* NEC */
+ ATI_FOUNDRY_KSC, /* KSC (?) */
+ ATI_FOUNDRY_UMC, /* United Microelectronics Corporation */
+ ATI_FOUNDRY_4,
+ ATI_FOUNDRY_5,
+ ATI_FOUNDRY_6,
+ ATI_FOUNDRY_UMCA /* UMC alternate */
+} ATIFoundryType;
+
+extern const char *ATIFoundryNames[];
+
+extern void ATIMach32ChipID FunctionPrototype((ATIPtr));
+extern void ATIMach64ChipID FunctionPrototype((ATIPtr, const CARD16));
+extern ATIChipType ATIChipID FunctionPrototype((const CARD16,
+ const CARD8));
+
+#define OldChipID(_1, _0) \
+ (SetBits(_0 - 'A', CHIP_CODE_0) | SetBits(_1 - 'A', CHIP_CODE_1))
+
+#define NewChipID(_1, _0) \
+ (SetBits(_0, CFG_CHIP_TYPE0) | SetBits(_1, CFG_CHIP_TYPE1))
+
+#define OldToNewChipID(_ChipID) \
+ (SetBits(GetBits(_ChipID, CHIP_CODE_0) + 'A', CFG_CHIP_TYPE0) | \
+ SetBits(GetBits(_ChipID, CHIP_CODE_1) + 'A', CFG_CHIP_TYPE1))
+
+#define NewToOldChipID(_ChipID) \
+ (SetBits(GetBits(_ChipID, CFG_CHIP_TYPE0) - 'A', CHIP_CODE_0) | \
+ (SetBits(GetBits(_ChipID, CFG_CHIP_TYPE1) - 'A', CHIP_CODE_1))
+
+#endif /* ___ATICHIP_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/aticlock.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/aticlock.c
new file mode 100644
index 000000000..076b636a8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/aticlock.c
@@ -0,0 +1,1356 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/aticlock.c,v 1.5 1999/08/01 07:57:19 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ */
+
+/*
+ * Adapters prior to V5 use 4 crystals. Adapters V5 and later use a clock
+ * generator chip. V3 and V4 adapters differ when it comes to choosing clock
+ * frequencies.
+ *
+ * VGA Wonder V3/V4 Adapter Clock Frequencies
+ * R E G I S T E R S
+ * 1CE(*) 3C2 3C2 Frequency
+ * B2h/BEh
+ * Bit 6/4 Bit 3 Bit 2 (MHz)
+ * ------- ------- ------- -------
+ * 0 0 0 50.000
+ * 0 0 1 56.644
+ * 0 1 0 Spare 1
+ * 0 1 1 44.900
+ * 1 0 0 44.900
+ * 1 0 1 50.000
+ * 1 1 0 Spare 2
+ * 1 1 1 36.000
+ *
+ * (*): V3 uses index B2h, bit 6; V4 uses index BEh, bit 4
+ *
+ * V5, PLUS, XL and XL24 usually have an ATI 18810 clock generator chip, but
+ * some have an ATI 18811-0, and it's quite conceivable that some exist with
+ * ATI 18811-1's or ATI 18811-2's. Mach32 adapters are known to use any one of
+ * these clock generators. Mach32 adapters also use a different dot clock
+ * ordering. ATI says there is no reliable way for the driver to determine
+ * which clock generator is on the adapter, but this driver will do its best to
+ * do so anyway.
+ *
+ * VGA Wonder V5/PLUS/XL/XL24 Clock Frequencies
+ * R E G I S T E R S
+ * 1CE 1CE 3C2 3C2 Frequency
+ * B9h BEh (MHz) 18811-0 18811-1
+ * Bit 1 Bit 4 Bit 3 Bit 2 18810 18812-0 18811-2
+ * ------- ------- ------- ------- ------- ------- -------
+ * 0 0 0 0 30.240 30.240 135.000
+ * 0 0 0 1 32.000 32.000 32.000
+ * 0 0 1 0 37.500 110.000 110.000
+ * 0 0 1 1 39.000 80.000 80.000
+ * 0 1 0 0 42.954 42.954 100.000
+ * 0 1 0 1 48.771 48.771 126.000
+ * 0 1 1 0 (*1) 92.400 92.400
+ * 0 1 1 1 36.000 36.000 36.000
+ * 1 0 0 0 40.000 39.910 39.910
+ * 1 0 0 1 (*4) 44.900 44.900
+ * 1 0 1 0 75.000 75.000 75.000
+ * 1 0 1 1 65.000 65.000 65.000
+ * 1 1 0 0 50.350 50.350 50.350
+ * 1 1 0 1 56.640 56.640 56.640
+ * 1 1 1 0 (*2) (*3) (*3)
+ * 1 1 1 1 44.900 44.900 44.900
+ *
+ * (*1) External 0 (supposedly 16.657 Mhz)
+ * (*2) External 1 (supposedly 28.322 MHz)
+ * (*3) This setting doesn't seem to generate anything
+ * (*4) This setting is documented to be 56.644 MHz, but something close to 82
+ * MHz has also been encountered.
+ *
+ * Mach32 Clock Frequencies
+ * R E G I S T E R S
+ * 1CE 1CE 3C2 3C2 Frequency
+ * B9h BEh (MHz) 18811-0 18811-1
+ * Bit 1 Bit 4 Bit 3 Bit 2 18810 18812-0 18811-2
+ * ------- ------- ------- ------- ------- ------- -------
+ * 0 0 0 0 42.954 42.954 100.000
+ * 0 0 0 1 48.771 48.771 126.000
+ * 0 0 1 0 (*1) 92.400 92.400
+ * 0 0 1 1 36.000 36.000 36.000
+ * 0 1 0 0 30.240 30.240 135.000
+ * 0 1 0 1 32.000 32.000 32.000
+ * 0 1 1 0 37.500 110.000 110.000
+ * 0 1 1 1 39.000 80.000 80.000
+ * 1 0 0 0 50.350 50.350 50.350
+ * 1 0 0 1 56.640 56.640 56.640
+ * 1 0 1 0 (*2) (*3) (*3)
+ * 1 0 1 1 44.900 44.900 44.900
+ * 1 1 0 0 40.000 39.910 39.910
+ * 1 1 0 1 (*4) 44.900 44.900
+ * 1 1 1 0 75.000 75.000 75.000
+ * 1 1 1 1 65.000 65.000 65.000
+ *
+ * (*1) External 0 (supposedly 16.657 Mhz)
+ * (*2) External 1 (supposedly 28.322 MHz)
+ * (*3) This setting doesn't seem to generate anything
+ * (*4) This setting is documented to be 56.644 MHz, but something close to 82
+ * MHz has also been encountered.
+ *
+ * Note that, to reduce confusion, this driver masks out the different clock
+ * ordering.
+ *
+ * For all adapters, these frequencies can be divided by 1 or 2. For all
+ * adapters, except Mach32's and Mach64's, frequencies can also be divided by 3
+ * or 4.
+ *
+ * Register 1CE, index B8h
+ * Bit 7 Bit 6
+ * ------- -------
+ * 0 0 Divide by 1
+ * 0 1 Divide by 2
+ * 1 0 Divide by 3
+ * 1 1 Divide by 4
+ *
+ * With respect to clocks, Mach64's are entirely different animals.
+ *
+ * The oldest Mach64's use one of the non-programmable clock generators
+ * described above. In this case, the driver will handle clocks in much the
+ * same way as it would for a Mach32.
+ *
+ * All other Mach64 adapters use a programmable clock generator. BIOS
+ * initialization programmes an initial set of frequencies. Two of these are
+ * reserved to allow for the setting of modes that do not use a frequency from
+ * this initial set. One of these reserved slots is used by the BIOS mode set
+ * routine, the other by the particular accelerated driver used (MS-Windows,
+ * AutoCAD, etc.). The slots reserved in this way are dependent on the
+ * particular clock generator used by the adapter.
+ *
+ * If the driver does not support the adapter's clock generator, it will try to
+ * match the (probed or specified) clocks to one of the following sets.
+ *
+ * Mach64 Clock Frequencies for unsupported programmable clock generators
+ * R E G I S T E R S
+ * 1CE 1CE 3C2 3C2 Frequency
+ * B9h BEh (MHz)
+ * Bit 1 Bit 4 Bit 3 Bit 2 Set 1 Set 2 Set 3
+ * ------- ------- ------- ------- ------- ------- -------
+ * 0 0 0 0 50.350 25.180 25.180
+ * 0 0 0 1 56.640 28.320 28.320
+ * 0 0 1 0 63.000 31.500 0.000
+ * 0 0 1 1 72.000 36.000 0.000
+ * 0 1 0 0 0.000 0.000 0.000
+ * 0 1 0 1 110.000 110.000 0.000
+ * 0 1 1 0 126.000 126.000 0.000
+ * 0 1 1 1 135.000 135.000 0.000
+ * 1 0 0 0 40.000 40.000 0.000
+ * 1 0 0 1 44.900 44.900 0.000
+ * 1 0 1 0 49.500 49.500 0.000
+ * 1 0 1 1 50.000 50.000 0.000
+ * 1 1 0 0 0.000 0.000 0.000
+ * 1 1 0 1 80.000 80.000 0.000
+ * 1 1 1 0 75.000 75.000 0.000
+ * 1 1 1 1 65.000 65.000 0.000
+ *
+ * The driver will never select a setting of 0.000 MHz. The above comments on
+ * clock ordering and clock divider apply here also.
+ *
+ * For all supported programmable clock generators, the driver will ignore any
+ * XF86Config clock line and programme, as needed, the clock number reserved by
+ * the BIOS for accelerated drivers. The driver's mode initialization routine
+ * finds integers N, M and D such that
+ *
+ * N
+ * R * ------- MHz
+ * M * D
+ *
+ * best approximates the mode's clock frequency, where R is the crystal-
+ * generated reference frequency (usually 14.318 MHz). D is a power of 2
+ * except for those integrated controllers that also offer odd dividers.
+ * Different clock generators have different restrictions on the value N, M and
+ * D can assume. The driver contains an internal table to record these
+ * restrictions (among other things). The resulting values of N, M and D are
+ * then encoded in a generator-specific way and used to programme the clock.
+ * The Mach64's clock divider is not used in this case.
+ */
+
+#include "ati.h"
+#include "atiadapter.h"
+#include "atichip.h"
+#include "atidac.h"
+#include "atidsp.h"
+#include "atividmem.h"
+
+/*
+ * Definitions related to non-programmable clock generators.
+ */
+const char *ATIClockNames[] =
+{
+ "unknown",
+ "IBM VGA compatible",
+ "crystals",
+ "ATI 18810 or similar",
+ "ATI 18811-0 or similar",
+ "ATI 18811-1 or similar",
+ "Programmable (BIOS setting 1)",
+ "Programmable (BIOS setting 2)",
+ "Programmable (BIOS setting 3)"
+};
+
+/*
+ * Definitions related to programmable clock generators.
+ */
+static CARD16 ATIPostDividers[] = {1, 2, 4, 8, 16, 32, 64, 128},
+ ATI264xTPostDividers[] = {1, 2, 4, 8, 3, 0, 6, 12};
+ClockRec ATIClockDescriptors[] =
+{
+ {
+ 0, 0, 0, 1, 1,
+ 1, 1, 0,
+ 0, NULL,
+ "Non-programmable"
+ },
+ {
+ 257, 512, 257, 1, 1,
+ 46, 46, 0,
+ 4, ATIPostDividers,
+ "ATI 18818 or ICS 2595 or similar"
+ },
+ {
+ 2, 129, 2, 1, 1,
+ 8, 14, 2,
+ 8, ATIPostDividers,
+ "SGS-Thompson 1703 or similar"
+ },
+ {
+ 8, 263, 8, 8, 9,
+ 4, 12, 2,
+ 4, ATIPostDividers,
+ "Chrontel 8398 or similar"
+ },
+ {
+ 2, 255, 0, 1, 1,
+ 45, 45, 0,
+ 4, ATI264xTPostDividers,
+ "Internal"
+ },
+ {
+ 2, 257, 2, 1, 1,
+ 2, 32, 2,
+ 4, ATIPostDividers,
+ "AT&T 20C408 or similar"
+ },
+ {
+ 65, 128, 65, 1, 1,
+ 2, 31, 0,
+ 4, ATIPostDividers,
+ "IBM RGB 514 or similar"
+ }
+};
+
+/*
+ * XF86Config clocks line that start with the following will either be rejected
+ * for ATI boards, or accepted for non-ATI boards.
+ */
+static const int
+ATIVGAClocks[] =
+{
+ 25175, 28322,
+ -1
+};
+
+/*
+ * The driver will attempt to match fixed clocks to one of the following
+ * specifications.
+ */
+static const int
+ATICrystalFrequencies[] =
+{
+ 50000, 56644, 0, 44900, 44900, 50000, 0, 36000,
+ -1
+},
+ATI18810Frequencies[] =
+{
+ 30240, 32000, 37500, 39000, 42954, 48771, 0, 36000,
+ 40000, 0, 75000, 65000, 50350, 56640, 0, 44900
+},
+ATI188110Frequencies[] =
+{
+ 30240, 32000, 110000, 80000, 42954, 48771, 92400, 36000,
+ 39910, 44900, 75000, 65000, 50350, 56640, 0, 44900
+},
+ATI188111Frequencies[] =
+{
+ 135000, 32000, 110000, 80000, 100000, 126000, 92400, 36000,
+ 39910, 44900, 75000, 65000, 50350, 56640, 0, 44900
+},
+ATIMach64AFrequencies[] =
+{
+ 0, 110000, 126000, 135000, 50350, 56640, 63000, 72000,
+ 0, 80000, 75000, 65000, 40000, 44900, 49500, 50000
+},
+ATIMach64BFrequencies[] =
+{
+ 0, 110000, 126000, 135000, 25180, 28320, 31500, 36000,
+ 0, 80000, 75000, 65000, 40000, 44900, 49500, 50000
+},
+ATIMach64CFrequencies[] =
+{
+ 0, 0, 0, 0, 25180, 28320, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+},
+*SpecificationClockLine[] =
+{
+ NULL,
+ ATIVGAClocks,
+ ATICrystalFrequencies,
+ ATI18810Frequencies,
+ ATI188110Frequencies,
+ ATI188111Frequencies,
+ ATIMach64AFrequencies,
+ ATIMach64BFrequencies,
+ ATIMach64CFrequencies,
+ NULL
+};
+
+/*
+ * The driver will reject XF86Config clocks lines that start with, or are an
+ * initial subset of, one of the following.
+ */
+static const int
+ATIPre_2_1_1_Clocks_A[] = /* Based on 18810 */
+{
+ 18000, 22450, 25175, 28320, 36000, 44900, 50350, 56640,
+ 30240, 32000, 37500, 39000, 40000, 0, 75000, 65000,
+ -1
+},
+ATIPre_2_1_1_Clocks_B[] = /* Based on 18811-0 */
+{
+ 18000, 22450, 25175, 28320, 36000, 44900, 50350, 56640,
+ 30240, 32000, 110000, 80000, 39910, 44900, 75000, 65000,
+ -1
+},
+ATIPre_2_1_1_Clocks_C[] = /* Based on 18811-1 (or -2) */
+{
+ 18000, 22450, 25175, 28320, 36000, 44900, 50350, 56640,
+ 135000, 32000, 110000, 80000, 39910, 44900, 75000, 65000,
+ -1
+},
+ATIPre_2_1_1_Clocks_D[] = /* Based on programmable setting 1 */
+{
+ 36000, 25000, 20000, 22450, 72000, 50000, 40000, 44900,
+ 0, 110000, 126000, 135000, 0, 80000, 75000, 65000,
+ -1
+},
+ATIPre_2_1_1_Clocks_E[] = /* Based on programmable setting 2 */
+{
+ 18000, 25000, 20000, 22450, 36000, 50000, 40000, 44900,
+ 0, 110000, 126000, 135000, 0, 80000, 75000, 65000,
+ -1
+},
+*InvalidClockLine[] =
+{
+ NULL,
+ ATIVGAClocks,
+ ATIPre_2_1_1_Clocks_A,
+ ATIPre_2_1_1_Clocks_B,
+ ATIPre_2_1_1_Clocks_C,
+ ATIPre_2_1_1_Clocks_D,
+ ATIPre_2_1_1_Clocks_E,
+ NULL
+};
+
+/*
+ * Clock maps.
+ */
+static const CARD8 ClockMaps[][4] =
+{
+ /* Null map */
+ { 0, 1, 2, 3},
+ /* VGA Wonder map <-> Mach{8,32,64} */
+ { 1, 0, 3, 2},
+ /* VGA Wonder map <-> Accelerator */
+ { 0, 2, 1, 3},
+ /* VGA -> Accelerator map */
+ { 2, 0, 3, 1},
+ /* Accelerator -> VGA map */
+ { 1, 3, 0, 2}
+};
+#define ATIVGAWonderClockMap ClockMaps[0]
+#define ATIVGAWonderClockUnmap ATIVGAWonderClockMap
+#define ATIMachVGAClockMap ClockMaps[1]
+#define ATIMachVGAClockUnmap ATIMachVGAClockMap
+#define ATIVGAProgrammableClockMap ClockMaps[2]
+#define ATIVGAProgrammableClockUnmap ATIVGAProgrammableClockMap
+#define ATIAcceleratorClockMap ClockMaps[3]
+#define ATIAcceleratorClockUnmap ClockMaps[4]
+#define ATIProgrammableClockMap ClockMaps[0]
+#define ATIProgrammableClockUnmap ATIProgrammableClockMap
+#define MapClockIndex(_ClockMap, _Index) \
+ (SetBits((_ClockMap)[GetBits((_Index), 0x0CU)], 0x0CU) | \
+ ((_Index) & ~0x0CU))
+
+/*
+ * ATIClockSelect --
+ *
+ * This function sets clock select bits in various registers to a specified
+ * value.
+ */
+static Bool
+ATIClockSelect
+(
+ ScrnInfoPtr pScreenInfo,
+ int Index
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ CARD8 genmo;
+
+ switch (Index)
+ {
+ case CLK_REG_SAVE:
+ if (pATI->CPIO_VGAWonder && (pATI->OldHW.crtc == ATI_CRTC_VGA))
+ ATIModifyExtReg(pATI, 0xB5U, pATI->OldHW.b5, 0x7FU, 0x00U);
+ break;
+
+ case CLK_REG_RESTORE:
+ break;
+
+ default:
+ /* Remap clock number */
+ Index = MapClockIndex(pATI->OldHW.ClockMap, Index);
+
+ switch (pATI->OldHW.crtc)
+ {
+ case ATI_CRTC_VGA:
+ /* Get generic two low-order bits */
+ genmo = (inb(R_GENMO) & 0xF3U) | ((Index << 2) & 0x0CU);
+
+ if (pATI->CPIO_VGAWonder)
+ {
+ /*
+ * On adapters with crystals, switching to one of the
+ * spare assignments doesn't do anything (i.e. the
+ * previous setting remains in effect). So, disable
+ * their selection.
+ */
+ if (((Index & 0x03U) == 0x02U) &&
+ ((pATI->Chip <= ATI_CHIP_18800) ||
+ (pATI->Adapter == ATI_ADAPTER_V4)))
+ return FALSE;
+
+ /* Start sequencer reset */
+ PutReg(SEQX, 0x00U, 0x00U);
+
+ /* Set high-order bits */
+ if (pATI->Chip <= ATI_CHIP_18800)
+ ATIModifyExtReg(pATI, 0xB2U, -1, 0xBFU,
+ Index << 4);
+ else
+ {
+ ATIModifyExtReg(pATI, 0xBEU, -1, 0xEFU,
+ Index << 2);
+ if (pATI->Adapter != ATI_ADAPTER_V4)
+ {
+ Index >>= 1;
+ ATIModifyExtReg(pATI, 0xB9U, -1, 0xFDU,
+ Index >> 1);
+ }
+ }
+
+ /* Set clock divider bits */
+ ATIModifyExtReg(pATI, 0xB8U, -1, 0x00U,
+ (Index << 3) & 0xC0U);
+ }
+ else
+ {
+ /*
+ * Reject clocks that cannot be selected.
+ */
+ if (Index & ~0x03U)
+ return FALSE;
+
+ /* Start sequencer reset */
+ PutReg(SEQX, 0x00U, 0x00U);
+ }
+
+ /* Must set miscellaneous output register last */
+ outb(GENMO, genmo);
+
+ /* End sequencer reset */
+ PutReg(SEQX, 0x00U, 0x03U);
+
+ break;
+
+ case ATI_CRTC_MACH64:
+ outl(pATI->CPIO_CLOCK_CNTL, CLOCK_STROBE |
+ SetBits(Index, CLOCK_SELECT | CLOCK_DIVIDER));
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ break;
+ }
+
+ return TRUE;
+}
+
+/*
+ * ATIMatchClockLine --
+ *
+ * This function tries to match the XF86Config clocks to one of an array of
+ * clock lines. It returns a clock line number or 0.
+ */
+static const int
+ATIMatchClockLine
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ const int **ClockLine,
+ const unsigned short int NumberOfClocks,
+ const int CalibrationClockNumber,
+ const int ClockMap
+)
+{
+ int ClockChip = 0, ClockChipIndex = 0;
+ int NumberOfMatchingClocks = 0;
+ int MinimumGap = CLOCK_TOLERANCE + 1;
+
+ /* For ATI adapters, reject generic VGA clocks */
+ if ((pATI->Adapter != ATI_ADAPTER_VGA) &&
+ (ClockLine == SpecificationClockLine))
+ ClockChipIndex++;
+ /* If checking for XF86Config clock order, skip crystals */
+ if (ClockMap)
+ ClockChipIndex++;
+
+ for (; ClockLine[++ClockChipIndex]; )
+ {
+ int MaximumGap = 0, ClockCount = 0, ClockIndex = 0;
+
+ for (; ClockIndex < NumberOfClocks; ClockIndex++)
+ {
+ int Gap, XF86ConfigClock, SpecificationClock;
+
+ SpecificationClock = ClockLine[ClockChipIndex]
+ [MapClockIndex(ClockMaps[ClockMap], ClockIndex)];
+ if (SpecificationClock < 0)
+ break;
+ if (!SpecificationClock)
+ continue;
+
+ XF86ConfigClock = pScreenInfo->clock[ClockIndex];
+ if (!XF86ConfigClock)
+ continue;
+
+ Gap = abs(XF86ConfigClock - SpecificationClock);
+ if (Gap >= MinimumGap)
+ goto SkipThisClockGenerator;
+ if (!Gap)
+ {
+ if (ClockIndex == CalibrationClockNumber)
+ continue;
+ }
+ else if (Gap > MaximumGap)
+ MaximumGap = Gap;
+ ClockCount++;
+ }
+
+ if (ClockCount <= NumberOfMatchingClocks)
+ continue;
+ NumberOfMatchingClocks = ClockCount;
+ ClockChip = ClockChipIndex;
+ if (!(MinimumGap = MaximumGap))
+ break;
+
+SkipThisClockGenerator:
+ /* For non-ATI adapters, only normalize standard VGA clocks */
+ if (pATI->Adapter == ATI_ADAPTER_VGA)
+ break;
+ }
+
+ return ClockChip;
+}
+
+/*
+ * ATIClockPreInit --
+ *
+ * This function is called by ATIPreInit() and handles the XF86Config clocks
+ * line (or lack thereof).
+ */
+void
+ATIClockPreInit
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ GDevPtr pGDev,
+ ClockRangePtr pRange
+)
+{
+ unsigned short int NumberOfUndividedClocks;
+ unsigned short int NumberOfDividers, NumberOfClocks;
+ int CalibrationClockNumber, CalibrationClockValue;
+ int ClockIndex, SpecificationClock, ClockMap = 0;
+ CARD16 VSyncRegister = GENS1(pATI->CPIO_VGABase);
+ CARD8 VSyncBit = 0x08U;
+
+ /*
+ * Decide what to do about the XF86Config clocks for programmable clock
+ * generators.
+ */
+ if (pATI->ProgrammableClock != ATI_CLOCK_FIXED)
+ {
+ /* Check for those that are not (yet) handled */
+ if (pATI->ProgrammableClock > NumberOf(ATIClockDescriptors))
+ xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 0,
+ "Unknown programmable clock generator type (0x%02X)"
+ " detected.\n", pATI->ProgrammableClock);
+ else if (pATI->ClockDescriptor.MaxN <= 0)
+ xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 0,
+ "Unsupported programmable clock generator detected: %s.\n",
+ pATI->ClockDescriptor.ClockName);
+ else
+ {
+ /*
+ * Recognize supported clock generators. This involves telling the
+ * rest of the server about it and (re-)initializing the XF86Config
+ * clocks line.
+ */
+ pRange->clockIndex = -1;
+ pScreenInfo->progClock = TRUE;
+
+ /* Set internal clock ordering */
+ if (pATI->NewHW.crtc == ATI_CRTC_VGA)
+ {
+ pATI->NewHW.ClockMap = ATIVGAProgrammableClockMap;
+ pATI->NewHW.ClockUnmap = ATIVGAProgrammableClockUnmap;
+ }
+ else
+ {
+ pATI->NewHW.ClockMap = ATIProgrammableClockMap;
+ pATI->NewHW.ClockUnmap = ATIProgrammableClockUnmap;
+ }
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "%s programmable clock generator detected.\n",
+ pATI->ClockDescriptor.ClockName);
+ if (pATI->ReferenceDenominator == 1)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "Reference clock %.3f MHz.\n",
+ (double)pATI->ReferenceNumerator / 1000.0);
+ else
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "Reference clock %.6g/%d (%.3f) MHz.\n",
+ (double)pATI->ReferenceNumerator / 1000.0,
+ pATI->ReferenceDenominator,
+ (double)pATI->ReferenceNumerator /
+ ((double)pATI->ReferenceDenominator * 1000.0));
+
+ /* Clobber XF86Config clocks line */
+ if (pGDev->numclocks)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE,
+ "XF86Config clocks specification ignored.\n");
+
+ if (pATI->ProgrammableClock == ATI_CLOCK_CH8398)
+ { /* First two are fixed */
+ pScreenInfo->numClocks = 2;
+ pScreenInfo->clock[0] = 25175;
+ pScreenInfo->clock[1] = 28322;
+ }
+ else if (pATI->ProgrammableClock == ATI_CLOCK_INTERNAL)
+ /*
+ * The integrated PLL generates clocks as if the reference
+ * frequency were doubled.
+ */
+ pATI->ReferenceNumerator <<= 1;
+
+ return; /* ... to ATIPreInit() */
+ }
+ }
+
+ /* Set default clock maps */
+ pATI->NewHW.ClockMap = ATIVGAWonderClockMap;
+ pATI->NewHW.ClockUnmap = ATIVGAWonderClockUnmap;
+
+ /*
+ * Determine the number of clock values the adapter should be able to
+ * generate and the dot clock to use for probe calibration.
+ */
+ProbeClocks:
+ if (pATI->Adapter == ATI_ADAPTER_VGA)
+ {
+ NumberOfDividers = 1;
+ NumberOfUndividedClocks = 4;
+ CalibrationClockNumber = 1;
+ CalibrationClockValue = 28322;
+ }
+ else
+ {
+ NumberOfDividers = 4;
+ if ((pATI->Chip <= ATI_CHIP_18800) ||
+ (pATI->Adapter == ATI_ADAPTER_V4))
+ {
+ NumberOfUndividedClocks = 8;
+ /* Actually, any undivided clock will do */
+ CalibrationClockNumber = 1;
+ CalibrationClockValue = 56644;
+ }
+ else
+ {
+ NumberOfUndividedClocks = 16;
+ CalibrationClockNumber = 10 /* or 11 */;
+ CalibrationClockValue = 75000 /* or 65000 */;
+ if (pATI->Chip >= ATI_CHIP_68800)
+ {
+ NumberOfDividers = 2;
+ if (pATI->Chip >= ATI_CHIP_264CT)
+ {
+ NumberOfDividers = 1;
+ NumberOfUndividedClocks = 4;
+ CalibrationClockNumber = 1;
+ CalibrationClockValue = 28322;
+ }
+
+ /*
+ * When selecting clocks, all ATI accelerators use a different
+ * clock ordering.
+ */
+ if (pATI->NewHW.crtc == ATI_CRTC_VGA)
+ {
+ pATI->NewHW.ClockMap = ATIMachVGAClockMap;
+ pATI->NewHW.ClockUnmap = ATIMachVGAClockUnmap;
+ }
+ else
+ {
+ pATI->NewHW.ClockMap = ATIAcceleratorClockMap;
+ pATI->NewHW.ClockUnmap = ATIAcceleratorClockUnmap;
+ }
+ }
+ }
+ }
+
+ pATI->OldHW.ClockMap = pATI->NewHW.ClockMap;
+ pATI->OldHW.ClockUnmap = pATI->NewHW.ClockUnmap;
+
+ NumberOfClocks = NumberOfUndividedClocks * NumberOfDividers;
+
+ /*
+ * Respect any XF86Config clocks line. Well, that's the theory, anyway.
+ * In practice, however, the regular use of probed values is widespread, at
+ * times causing otherwise inexplicable results. So, attempt to normalize
+ * the clocks to known (i.e. specification) values.
+ */
+ if (!pGDev->numclocks || pATI->OptionProbeClocks ||
+ xf86ServerIsOnlyProbing())
+ {
+ if (pATI->ProgrammableClock != ATI_CLOCK_FIXED)
+ {
+ /*
+ * For unsupported programmable clock generators, pick the highest
+ * frequency set by BIOS initialization for clock calibration.
+ */
+ CalibrationClockNumber = CalibrationClockValue = 0;
+ for (ClockIndex = 0;
+ ClockIndex < NumberOfUndividedClocks;
+ ClockIndex++)
+ if (CalibrationClockValue < pATI->BIOSClocks[ClockIndex])
+ {
+ CalibrationClockNumber = ClockIndex;
+ CalibrationClockValue = pATI->BIOSClocks[ClockIndex];
+ }
+ CalibrationClockNumber =
+ MapClockIndex(pATI->NewHW.ClockUnmap, CalibrationClockNumber);
+ CalibrationClockValue *= 10;
+ }
+
+ if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
+ {
+ /*
+ * The current video state needs to be saved before the clock
+ * probe, and restored after. Video memory corruption and other
+ * effects occur because, at this early stage, the clock probe
+ * cannot reliably be prevented from enabling frequencies that are
+ * greater than what the adapter can handle.
+ */
+ ATIMapApertures(pScreenInfo, pATI);
+ ATICRTCSave(pScreenInfo, pATI, &pATI->OldHW);
+ }
+
+ switch (pATI->OldHW.crtc)
+ {
+ case ATI_CRTC_VGA:
+ /* Already set */
+ break;
+
+ case ATI_CRTC_MACH64:
+ VSyncRegister = pATI->CPIO_CRTC_INT_CNTL;
+ VSyncBit = GetByte(CRTC_VBLANK, 0);
+ break;
+
+ default:
+ break;
+ }
+
+ /* Probe the adapter for clock values */
+ xf86GetClocks(pScreenInfo, NumberOfClocks, ATIClockSelect,
+ NULL, NULL, VSyncRegister, VSyncBit,
+ CalibrationClockNumber, CalibrationClockValue);
+
+ if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
+ {
+ /* Restore video state */
+ ATICRTCSet(pScreenInfo, pATI, &pATI->OldHW);
+ ATIUnmapApertures(pScreenInfo, pATI);
+ xfree(pATI->OldHW.frame_buffer);
+ pATI->OldHW.frame_buffer = NULL;
+ }
+
+ /* Tell user clocks were probed, instead of supplied */
+ pATI->OptionProbeClocks = TRUE;
+
+ /* Attempt to match probed clocks to a known specification */
+ pATI->Clock = ATIMatchClockLine(pScreenInfo, pATI,
+ SpecificationClockLine, NumberOfUndividedClocks,
+ CalibrationClockNumber, 0);
+
+ if ((pATI->Chip <= ATI_CHIP_18800) ||
+ (pATI->Adapter == ATI_ADAPTER_V4))
+ {
+ /* V3 and V4 adapters don't have clock chips */
+ if (pATI->Clock > ATI_CLOCK_CRYSTALS)
+ pATI->Clock = ATI_CLOCK_NONE;
+ }
+ else
+ {
+ /* All others don't have crystals */
+ if (pATI->Clock == ATI_CLOCK_CRYSTALS)
+ pATI->Clock = ATI_CLOCK_NONE;
+ }
+ }
+ else
+ {
+ /*
+ * Allow for an initial subset of specification clocks. Can't allow
+ * for any more than that though...
+ */
+ if (NumberOfClocks > pGDev->numclocks)
+ {
+ NumberOfClocks = pGDev->numclocks;
+ if (NumberOfUndividedClocks > NumberOfClocks)
+ NumberOfUndividedClocks = NumberOfClocks;
+ }
+
+ /* Move XF86Config clocks into the ScrnInfoRec */
+ for (ClockIndex = 0; ClockIndex < NumberOfClocks; ClockIndex++)
+ pScreenInfo->clock[ClockIndex] = pGDev->clock[ClockIndex];
+ pScreenInfo->numClocks = NumberOfClocks;
+
+ /* Attempt to match clocks to a known specification */
+ pATI->Clock = ATIMatchClockLine(pScreenInfo, pATI,
+ SpecificationClockLine, NumberOfUndividedClocks, -1, 0);
+
+ if (pATI->Adapter != ATI_ADAPTER_VGA)
+ {
+ if (pATI->Clock == ATI_CLOCK_NONE)
+ {
+ /*
+ * Reject certain clock lines that are obviously wrong. This
+ * includes the standard VGA clocks for non-ATI adapters, and
+ * clock lines that could have been used with the pre-2.1.1
+ * driver.
+ */
+ if (ATIMatchClockLine(pScreenInfo, pATI, InvalidClockLine,
+ NumberOfClocks, -1, 0))
+ pATI->OptionProbeClocks = TRUE;
+ else if ((pATI->Chip >= ATI_CHIP_18800) &&
+ (pATI->Adapter != ATI_ADAPTER_V4))
+ {
+ /*
+ * Check for clocks that are specified in the wrong order.
+ * This is meant to catch those who are trying to use the
+ * clock order intended for the old accelerated servers.
+ */
+ while ((++ClockMap, ClockMap %= NumberOf(ClockMaps)))
+ {
+ pATI->Clock = ATIMatchClockLine(pScreenInfo, pATI,
+ SpecificationClockLine, NumberOfUndividedClocks,
+ -1, ClockMap);
+ if (pATI->Clock != ATI_CLOCK_NONE)
+ {
+ xf86DrvMsgVerb(pScreenInfo->scrnIndex,
+ X_WARNING, 0,
+ "XF86Config clock ordering incorrect. Clocks"
+ " will be reordered." ATI_README);
+ break;
+ }
+ }
+ }
+ }
+ else
+ /* Ensure crystals are not matched to clock chips, and vice versa */
+ if ((pATI->Chip <= ATI_CHIP_18800) ||
+ (pATI->Adapter == ATI_ADAPTER_V4))
+ {
+ if (pATI->Clock > ATI_CLOCK_CRYSTALS)
+ pATI->OptionProbeClocks = TRUE;
+ }
+ else
+ {
+ if (pATI->Clock == ATI_CLOCK_CRYSTALS)
+ pATI->OptionProbeClocks = TRUE;
+ }
+
+ if (pATI->OptionProbeClocks)
+ {
+ xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 0,
+ "Invalid or obsolete XF86Config clocks line rejected.\n"
+ " Clocks will be probed." ATI_README);
+ goto ProbeClocks;
+ }
+ }
+ }
+
+ if (pATI->ProgrammableClock != ATI_CLOCK_FIXED)
+ pATI->ProgrammableClock = ATI_CLOCK_FIXED;
+ else if (pATI->Clock == ATI_CLOCK_NONE)
+ xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 0,
+ "Unknown clock generator detected.\n");
+ else if (pATI->Clock == ATI_CLOCK_CRYSTALS)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "This adapter uses crystals to generate clock frequencies.\n");
+ else if (pATI->Clock != ATI_CLOCK_VGA)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "%s clock chip detected.\n", ATIClockNames[pATI->Clock]);
+
+ if (pATI->Clock != ATI_CLOCK_NONE)
+ {
+ /* Replace undivided clocks with specification values */
+ for (ClockIndex = 0;
+ ClockIndex < NumberOfUndividedClocks;
+ ClockIndex++)
+ {
+ /*
+ * Don't replace clocks that are probed, documented, or set by the
+ * user to zero. One exception is that we need to override the
+ * user's value for the spare settings on a crystal-based adapter.
+ * Another exception is when the user specifies the clock ordering
+ * intended for the old accelerated servers.
+ */
+ SpecificationClock =
+ SpecificationClockLine[pATI->Clock][ClockIndex];
+ if (SpecificationClock < 0)
+ break;
+ if (!ClockMap)
+ {
+ if (!pScreenInfo->clock[ClockIndex])
+ continue;
+ if (!SpecificationClock)
+ {
+ if (pATI->Clock != ATI_CLOCK_CRYSTALS)
+ continue;
+ }
+ else
+ {
+ /*
+ * Due to the way clock lines are matched, the following
+ * can prevent the override if the clock is probed,
+ * documented or set by the user to a value greater than
+ * MaximumClock.
+ */
+ if (abs(SpecificationClock -
+ pScreenInfo->clock[ClockIndex]) > CLOCK_TOLERANCE)
+ continue;
+ }
+ }
+ pScreenInfo->clock[ClockIndex] = SpecificationClock;
+ }
+
+ /* Adjust divided clocks */
+ for (ClockIndex = NumberOfUndividedClocks;
+ ClockIndex < NumberOfClocks;
+ ClockIndex++)
+ pScreenInfo->clock[ClockIndex] = ATIDivide(
+ pScreenInfo->clock[ClockIndex % NumberOfUndividedClocks],
+ (ClockIndex / NumberOfUndividedClocks) + 1, 0, 0);
+ }
+
+ /* Tell user about fixed clocks */
+ xf86ShowClocks(pScreenInfo, pATI->OptionProbeClocks ? X_PROBED : X_CONFIG);
+
+ /* Prevent selection of high clocks, even by V_CLKDIV2 modes */
+ for (ClockIndex = 0; ClockIndex < NumberOfClocks; ClockIndex++)
+ if (pScreenInfo->clock[ClockIndex] > pRange->maxClock)
+ pScreenInfo->clock[ClockIndex] = 0;
+}
+
+/*
+ * ATIClockSave --
+ *
+ * This function saves that part of an ATIHWRec that relates to clocks.
+ */
+void
+ATIClockSave
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ if (pScreenInfo->vtSema && (pATI->ProgrammableClock != ATI_CLOCK_FIXED))
+ {
+ if (pATIHW->crtc == ATI_CRTC_VGA)
+ {
+ pATIHW->ClockMap = ATIVGAProgrammableClockMap;
+ pATIHW->ClockUnmap = ATIVGAProgrammableClockUnmap;
+ }
+ else
+ {
+ pATIHW->ClockMap = ATIProgrammableClockMap;
+ pATIHW->ClockUnmap = ATIProgrammableClockUnmap;
+ }
+ }
+ else
+ {
+ if (pATIHW->crtc != ATI_CRTC_VGA)
+ {
+ pATIHW->ClockMap = ATIAcceleratorClockMap;
+ pATIHW->ClockUnmap = ATIAcceleratorClockUnmap;
+ }
+ else if (pATI->Chip < ATI_CHIP_68800)
+ {
+ pATIHW->ClockMap = ATIVGAWonderClockMap;
+ pATIHW->ClockUnmap = ATIVGAWonderClockUnmap;
+ }
+ else
+ {
+ pATIHW->ClockMap = ATIMachVGAClockMap;
+ pATIHW->ClockUnmap = ATIMachVGAClockUnmap;
+ }
+ }
+}
+
+/*
+ * ATIClockCalculate --
+ *
+ * This function is called to generate, if necessary, the data needed for clock
+ * programming, and set clock select bits in various register values.
+ */
+Bool
+ATIClockCalculate
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW,
+ DisplayModePtr pMode
+)
+{
+ int N, M, D;
+ int ClockSelect, N1, MinimumGap;
+ int Frequency, Multiple; /* Used as temporaries */
+
+ /* Set default values */
+ pATIHW->FeedbackDivider = pATIHW->ReferenceDivider = pATIHW->PostDivider = 0;
+
+ if ((pATI->ProgrammableClock == ATI_CLOCK_FIXED) ||
+ ((pATI->ProgrammableClock == ATI_CLOCK_CH8398) &&
+ (pMode->ClockIndex < 2)))
+ {
+ /* Use a fixed clock */
+ ClockSelect = pMode->ClockIndex;
+ }
+ else
+ {
+ if (pATI->LCDPanelID >= 0)
+ pMode->Clock = pATI->LCDClock;
+
+ /* Generate clock programme word, using units of kHz */
+ MinimumGap = ((unsigned int)(-1)) >> 1;
+
+ /* Loop through reference dividers */
+ for (M = pATI->ClockDescriptor.MinM;
+ M <= pATI->ClockDescriptor.MaxM;
+ M++)
+ {
+ /* Loop through post-dividers */
+ for (D = 0; D < pATI->ClockDescriptor.NumD; D++)
+ {
+ if (!pATI->ClockDescriptor.PostDividers[D])
+ continue;
+
+ /*
+ * Calculate closest feedback divider and apply its
+ * restrictions.
+ */
+ Multiple = M * pATI->ReferenceDenominator *
+ pATI->ClockDescriptor.PostDividers[D];
+ N = ATIDivide(pMode->Clock * Multiple,
+ pATI->ReferenceNumerator, 0, 0);
+ if (N < pATI->ClockDescriptor.MinN)
+ N = pATI->ClockDescriptor.MinN;
+ else if (N > pATI->ClockDescriptor.MaxN)
+ N = pATI->ClockDescriptor.MaxN;
+ N -= pATI->ClockDescriptor.NAdjust;
+ N1 = (N / pATI->ClockDescriptor.N1) * pATI->ClockDescriptor.N2;
+ if (N > N1)
+ N = ATIDivide(N1 + 1, pATI->ClockDescriptor.N1, 0, 1);
+ N += pATI->ClockDescriptor.NAdjust;
+ N1 += pATI->ClockDescriptor.NAdjust;
+
+ for (; ; N = N1)
+ {
+ /* Pick the closest setting */
+ Frequency = abs(ATIDivide(N * pATI->ReferenceNumerator,
+ Multiple, 0, 0) - pMode->Clock);
+ if ((Frequency < MinimumGap) ||
+ ((Frequency == MinimumGap) &&
+ (pATIHW->FeedbackDivider < N)))
+ {
+ /* Save settings */
+ pATIHW->FeedbackDivider = N;
+ pATIHW->ReferenceDivider = M;
+ pATIHW->PostDivider = D;
+ MinimumGap = Frequency;
+ }
+
+ if (N <= N1)
+ break;
+ }
+ }
+ }
+
+ Multiple = pATIHW->ReferenceDivider * pATI->ReferenceDenominator *
+ pATI->ClockDescriptor.PostDividers[pATIHW->PostDivider];
+ Frequency = pATIHW->FeedbackDivider * pATI->ReferenceNumerator;
+ Frequency = ATIDivide(Frequency, Multiple, 0, 0);
+ if (abs(Frequency - pMode->Clock) > CLOCK_TOLERANCE)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Unable to programme clock %.3fMHz for mode %s.\n",
+ (double)(pMode->Clock) / 1000.0, pMode->name);
+ return FALSE;
+ }
+ pMode->SynthClock = Frequency;
+ ClockSelect = pATI->ClockNumberToProgramme;
+
+ xf86ErrorFVerb(4,
+ "\n Programming clock %d to %.3fMHz for mode %s."
+ " N=%d, M=%d, D=%d.\n",
+ ClockSelect, (double)Frequency / 1000.0, pMode->name,
+ pATIHW->FeedbackDivider, pATIHW->ReferenceDivider,
+ pATIHW->PostDivider);
+
+ if ((pATI->Chip >= ATI_CHIP_264VTB) &&
+ (pATI->CPIODecoding == BLOCK_IO))
+ ATIDSPCalculate(pScreenInfo, pATI, pATIHW, pMode);
+ }
+
+ /* Set clock select bits, after remapping them */
+ pATIHW->clock = ClockSelect; /* Save pre-map clock number */
+ ClockSelect = MapClockIndex(pATIHW->ClockMap, ClockSelect);
+
+ switch (pATIHW->crtc)
+ {
+ case ATI_CRTC_VGA:
+ pATIHW->genmo = (pATIHW->genmo & 0xF3U) |
+ ((ClockSelect << 2) & 0x0CU);
+
+ if (pATI->CPIO_VGAWonder)
+ {
+ /* Set ATI clock select bits */
+ if (pATI->Chip <= ATI_CHIP_18800)
+ pATIHW->b2 = (pATIHW->b2 & 0xBFU) |
+ ((ClockSelect << 4) & 0x40U);
+ else
+ {
+ pATIHW->be = (pATIHW->be & 0xEFU) |
+ ((ClockSelect << 2) & 0x10U);
+ if (pATI->Adapter != ATI_ADAPTER_V4)
+ {
+ ClockSelect >>= 1;
+ pATIHW->b9 = (pATIHW->b9 & 0xFDU) |
+ ((ClockSelect >> 1) & 0x02U);
+ }
+ }
+
+ /* Set clock divider bits */
+ pATIHW->b8 = (pATIHW->b8 & 0x3FU) |
+ ((ClockSelect << 3) & 0xC0U);
+ }
+ break;
+
+ case ATI_CRTC_MACH64:
+ pATIHW->clock_cntl = CLOCK_STROBE |
+ SetBits(ClockSelect, CLOCK_SELECT | CLOCK_DIVIDER);
+ break;
+
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+/*
+ * ATIClockSet --
+ *
+ * This function is called to programme a clock for the mode being set.
+ */
+void
+ATIClockSet
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ CARD8 clock_cntl0, crtc_gen_cntl3;
+ CARD8 tmp, tmp2, tmp3;
+ unsigned int Programme;
+ int N = pATIHW->FeedbackDivider - pATI->ClockDescriptor.NAdjust;
+ int M = pATIHW->ReferenceDivider - pATI->ClockDescriptor.MAdjust;
+ int D = pATIHW->PostDivider;
+
+ /* Temporarily switch to accelerator mode */
+ crtc_gen_cntl3 = inb(pATI->CPIO_CRTC_GEN_CNTL + 3);
+ outb(pATI->CPIO_CRTC_GEN_CNTL + 3,
+ crtc_gen_cntl3 | GetByte(CRTC_EXT_DISP_EN, 3));
+
+ ATISetDACIOPorts(pATI, ATI_CRTC_MACH64);
+
+ switch (pATI->ProgrammableClock)
+ {
+ case ATI_CLOCK_ICS2595:
+ clock_cntl0 = inb(pATI->CPIO_CLOCK_CNTL);
+
+ Programme = (SetBits(pATIHW->clock, ICS2595_CLOCK) |
+ SetBits(N, ICS2595_FB_DIV) | SetBits(D, ICS2595_POST_DIV)) ^
+ ICS2595_TOGGLE;
+
+ ATIDelay(50000); /* 50 milliseconds */
+
+ (void)xf86DisableInterrupts();
+
+ /* Send all 20 bits of programme word */
+ while (Programme >= CLOCK_BIT)
+ {
+ tmp = (Programme & CLOCK_BIT) | CLOCK_STROBE;
+ outb(pATI->CPIO_CLOCK_CNTL, tmp);
+ ATIDelay(26); /* 26 microseconds */
+ outb(pATI->CPIO_CLOCK_CNTL, tmp | CLOCK_PULSE);
+ ATIDelay(26); /* 26 microseconds */
+ Programme >>= 1;
+ }
+
+ xf86EnableInterrupts();
+
+ /* Restore register */
+ outb(pATI->CPIO_CLOCK_CNTL, clock_cntl0 | CLOCK_STROBE);
+ break;
+
+ case ATI_CLOCK_STG1703:
+ (void)ATIGetDACCmdReg(pATI);
+ (void)inb(pATI->CPIO_DAC_MASK);
+ outb(pATI->CPIO_DAC_MASK, (pATIHW->clock << 1) + 0x20U);
+ outb(pATI->CPIO_DAC_MASK, 0);
+ outb(pATI->CPIO_DAC_MASK, SetBits(N, 0xFFU));
+ outb(pATI->CPIO_DAC_MASK, SetBits(M, 0x1FU) | SetBits(D, 0xE0U));
+ break;
+
+ case ATI_CLOCK_CH8398:
+ tmp = inb(pATI->CPIO_DAC_CNTL);
+ outb(pATI->CPIO_DAC_CNTL,
+ tmp | (DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3));
+ outb(pATI->CPIO_DAC_WRITE, pATIHW->clock);
+ outb(pATI->CPIO_DAC_DATA, SetBits(N, 0xFFU));
+ outb(pATI->CPIO_DAC_DATA, SetBits(M, 0x3FU) | SetBits(D, 0xC0U));
+ outb(pATI->CPIO_DAC_CNTL, tmp);
+ break;
+
+ case ATI_CLOCK_INTERNAL:
+ /* Reset VCLK generator */
+ tmp3 = ATIGetMach64PLLReg(PLL_VCLK_CNTL) |
+ (/* PLL_VCLK_SRC_SEL | */ PLL_VCLK_RESET);
+ ATIPutMach64PLLReg(PLL_VCLK_CNTL, tmp3);
+
+ /* Set post-divider */
+ tmp2 = pATIHW->clock << 1;
+ tmp = ATIGetMach64PLLReg(PLL_VCLK_POST_DIV);
+ tmp &= ~(0x03U << tmp2);
+ tmp |= SetBits(D, 0x03U) << tmp2;
+ ATIPutMach64PLLReg(PLL_VCLK_POST_DIV, tmp);
+
+ /* Set extended post-divider */
+ tmp = ATIGetMach64PLLReg(PLL_XCLK_CNTL);
+ tmp &= ~(SetBits(1, PLL_VCLK0_XDIV) << pATIHW->clock);
+ tmp |= SetBits(D >> 2, PLL_VCLK0_XDIV) << pATIHW->clock;
+ ATIPutMach64PLLReg(PLL_XCLK_CNTL, tmp);
+
+ /* Set feedback divider */
+ tmp = PLL_VCLK0_FB_DIV + pATIHW->clock;
+ ATIPutMach64PLLReg(tmp, SetBits(N, 0xFFU));
+
+ /* End VCLK generator reset */
+ tmp3 &= ~PLL_VCLK_RESET;
+ ATIPutMach64PLLReg(PLL_VCLK_CNTL, tmp3);
+
+ /* Reset write bit */
+ ATIAccessMach64PLLReg(pATI, 0, FALSE);
+ break;
+
+ case ATI_CLOCK_ATT20C408:
+ (void)ATIGetDACCmdReg(pATI);
+ tmp = inb(pATI->CPIO_DAC_MASK);
+ (void)ATIGetDACCmdReg(pATI);
+ outb(pATI->CPIO_DAC_MASK, tmp | 1);
+ outb(pATI->CPIO_DAC_WRITE, 1);
+ outb(pATI->CPIO_DAC_MASK, tmp | 9);
+ ATIDelay(400); /* 400 microseconds */
+ tmp2 = (pATIHW->clock << 2) + 0x40U;
+ outb(pATI->CPIO_DAC_WRITE, tmp2);
+ outb(pATI->CPIO_DAC_MASK, SetBits(N, 0xFFU));
+ outb(pATI->CPIO_DAC_WRITE, ++tmp2);
+ outb(pATI->CPIO_DAC_MASK, SetBits(M, 0x3FU) | SetBits(D, 0xC0U));
+ outb(pATI->CPIO_DAC_WRITE, ++tmp2);
+ outb(pATI->CPIO_DAC_MASK, 0x77U);
+ ATIDelay(400); /* 400 microseconds */
+ outb(pATI->CPIO_DAC_WRITE, 1);
+ outb(pATI->CPIO_DAC_MASK, tmp);
+ break;
+
+ case ATI_CLOCK_IBMRGB514:
+ tmp = inb(pATI->CPIO_DAC_CNTL);
+ outb(pATI->CPIO_DAC_CNTL,
+ (tmp & ~DAC_EXT_SEL_RS3) | DAC_EXT_SEL_RS2);
+ tmp2 = (pATIHW->clock << 1) + 0x20U;
+ outb(pATI->CPIO_DAC_WRITE, tmp2);
+ outb(pATI->CPIO_DAC_DATA, 0);
+ outb(pATI->CPIO_DAC_MASK,
+ (SetBits(N, 0x3FU) | SetBits(D, 0xC0U)) ^ 0xC0U);
+ outb(pATI->CPIO_DAC_WRITE, tmp2 + 1);
+ outb(pATI->CPIO_DAC_DATA, 0);
+ outb(pATI->CPIO_DAC_MASK, SetBits(M, 0x3FU));
+ outb(pATI->CPIO_DAC_CNTL, tmp);
+ break;
+
+ default:
+ break;
+ }
+
+ (void)inb(pATI->CPIO_DAC_WRITE); /* Clear DAC counter */
+
+ /* Restore register */
+ outb(pATI->CPIO_CRTC_GEN_CNTL + 3, crtc_gen_cntl3);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/aticlock.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/aticlock.h
new file mode 100644
index 000000000..4ca2d613b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/aticlock.h
@@ -0,0 +1,83 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/aticlock.h,v 1.3 1999/07/06 11:38:26 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATICLOCK_H___
+#define ___ATICLOCK_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+#include "xf86str.h"
+
+/*
+ * Definitions related to non-programmable clock generators.
+ */
+typedef enum
+{
+ ATI_CLOCK_NONE = 0,
+ ATI_CLOCK_VGA = 1,
+ ATI_CLOCK_CRYSTALS = 2,
+ ATI_CLOCK_18810,
+ ATI_CLOCK_18811_0,
+ ATI_CLOCK_18811_1,
+ ATI_CLOCK_MACH64A,
+ ATI_CLOCK_MACH64B,
+ ATI_CLOCK_MACH64C
+} ATIClockType;
+extern const char *ATIClockNames[];
+
+/*
+ * Definitions related to programmable clock generators.
+ */
+typedef enum
+{
+ ATI_CLOCK_FIXED = 0, /* Further described by ATIClockType */
+ ATI_CLOCK_ICS2595,
+ ATI_CLOCK_STG1703,
+ ATI_CLOCK_CH8398,
+ ATI_CLOCK_INTERNAL,
+ ATI_CLOCK_ATT20C408,
+ ATI_CLOCK_IBMRGB514,
+ ATI_CLOCK_MAX /* Must be last */
+} ATIProgrammableClockType;
+
+typedef struct
+{
+ CARD16 MinN, MaxN; /* Feedback divider and ... */
+ CARD16 NAdjust; /* ... its adjustment and ... */
+ CARD16 N1, N2; /* ... its restrictions */
+ CARD16 MinM, MaxM; /* Reference divider and ... */
+ CARD16 MAdjust; /* ... its adjustment */
+ CARD16 NumD, *PostDividers; /* Post-dividers */
+ const char *ClockName;
+} ClockRec, *ClockPtr;
+extern ClockRec ATIClockDescriptors[];
+
+extern void ATIClockPreInit FunctionPrototype((ScrnInfoPtr, ATIPtr, GDevPtr,
+ ClockRangePtr));
+extern void ATIClockSave FunctionPrototype((ScrnInfoPtr, ATIPtr,
+ ATIHWPtr));
+extern Bool ATIClockCalculate FunctionPrototype((ScrnInfoPtr, ATIPtr,
+ ATIHWPtr, DisplayModePtr));
+extern void ATIClockSet FunctionPrototype((ATIPtr, ATIHWPtr));
+
+#endif /* ___ATICLOCK_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/aticonsole.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/aticonsole.c
new file mode 100644
index 000000000..dce247f2a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/aticonsole.c
@@ -0,0 +1,250 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/aticonsole.c,v 1.3 1999/07/06 11:38:27 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "aticonsole.h"
+#include "aticrtc.h"
+#include "atilock.h"
+#include "atimach64.h"
+#include "atistruct.h"
+#include "ativga.h"
+#include "atividmem.h"
+#include "xf86.h"
+
+/*
+ * ATISaveScreen --
+ *
+ * DIX calls this function to blank (On == FALSE) or unblank (On == TRUE) the
+ * screen.
+ */
+Bool
+ATISaveScreen
+(
+ ScreenPtr pScreen,
+ int On
+)
+{
+ ScrnInfoPtr pScreenInfo;
+ ATIPtr pATI;
+
+ if (On)
+ SetTimeSinceLastInputEvent();
+
+ if (!pScreen)
+ return TRUE;
+
+ pScreenInfo = xf86Screens[pScreen->myNum];
+ if (!pScreenInfo->vtSema)
+ return TRUE;
+
+ pATI = ATIPTR(pScreenInfo);
+ switch (pATI->NewHW.crtc)
+ {
+ case ATI_CRTC_VGA:
+ ATIVGASaveScreen(pATI, On);
+ break;
+
+ case ATI_CRTC_MACH64:
+ ATIMach64SaveScreen(pATI, On);
+ break;
+
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+/*
+ * ATIEnterGraphics --
+ *
+ * This function sets the hardware to a graphics video state.
+ */
+Bool
+ATIEnterGraphics
+(
+ ScreenPtr pScreen,
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI
+)
+{
+ /* Map apertures */
+ if (!ATIMapApertures(pScreenInfo, pATI))
+ return FALSE;
+
+ /* Unlock device */
+ ATIUnlock(pATI);
+
+ /* Calculate hardware data */
+ if (pScreen &&
+ !ATICRTCCalculate(pScreenInfo, pATI, &pATI->NewHW,
+ pScreenInfo->currentMode))
+ return FALSE;
+
+ pScreenInfo->vtSema = TRUE;
+
+ /* Save current state */
+ ATICRTCSave(pScreenInfo, pATI, &pATI->OldHW);
+
+ /* Set graphics state */
+ ATICRTCSet(pScreenInfo, pATI, &pATI->NewHW);
+
+ /* Possibly blank the screen */
+ if (pScreen)
+ (void)ATISaveScreen(pScreen, FALSE);
+
+ /* Position the screen */
+ (*pScreenInfo->AdjustFrame)(pScreenInfo->scrnIndex,
+ pScreenInfo->frameX0, pScreenInfo->frameY0, 0);
+
+ SetTimeSinceLastInputEvent();
+
+ return TRUE;
+}
+
+/*
+ * ATILeaveGraphics --
+ *
+ * This function restores the hardware to its previous state.
+ */
+void
+ATILeaveGraphics
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI
+)
+{
+ Bool Exiting = xf86ServerIsExiting();
+
+ if (pScreenInfo->vtSema)
+ {
+ /* If not exiting, save graphics video state */
+ if (!Exiting)
+ ATICRTCSave(pScreenInfo, pATI, &pATI->NewHW);
+
+ /* Restore mode in effect on server entry */
+ ATICRTCSet(pScreenInfo, pATI, &pATI->OldHW);
+
+ pScreenInfo->vtSema = FALSE;
+ }
+
+ /* Lock device */
+ ATILock(pATI);
+
+ /* Unmap apertures */
+ if (Exiting)
+ ATIUnmapApertures(pScreenInfo, pATI);
+
+ SetTimeSinceLastInputEvent();
+}
+
+/*
+ * ATISwitchMode --
+ *
+ * This function switches to another graphics video state.
+ */
+Bool
+ATISwitchMode
+(
+ int iScreen,
+ DisplayModePtr pMode,
+ int flags
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[iScreen];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ /* Calculate new hardware data */
+ if (!ATICRTCCalculate(pScreenInfo, pATI, &pATI->NewHW, pMode))
+ return FALSE;
+
+ /* Set new hardware state */
+ if (pScreenInfo->vtSema)
+ ATICRTCSet(pScreenInfo, pATI, &pATI->NewHW);
+
+ SetTimeSinceLastInputEvent();
+
+ return TRUE;
+}
+
+/*
+ * ATIEnterVT --
+ *
+ * This function sets the server's virtual console to a graphics video state.
+ */
+Bool
+ATIEnterVT
+(
+ int iScreen,
+ int flags
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[iScreen];
+
+ return ATIEnterGraphics(NULL, pScreenInfo, ATIPTR(pScreenInfo));
+}
+
+/*
+ * ATILeaveVT --
+ *
+ * This function restores the server's virtual console to its state on server
+ * entry.
+ */
+void
+ATILeaveVT
+(
+ int iScreen,
+ int flags
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[iScreen];
+
+ ATILeaveGraphics(pScreenInfo, ATIPTR(pScreenInfo));
+}
+
+/*
+ * ATIFreeScreen --
+ *
+ * This function frees all driver data related to a screen.
+ */
+void
+ATIFreeScreen
+(
+ int iScreen,
+ int flags
+)
+{
+ ScreenPtr pScreen = screenInfo.screens[iScreen];
+ ScrnInfoPtr pScreenInfo = xf86Screens[iScreen];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ if (pATI->Closeable)
+ (void)(*pScreen->CloseScreen)(iScreen, pScreen);
+
+ ATILeaveGraphics(pScreenInfo, pATI);
+
+ xfree(pATI->OldHW.frame_buffer);
+ xfree(pATI->NewHW.frame_buffer);
+
+ xfree(pATI);
+ pScreenInfo->driverPrivate = NULL;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/aticonsole.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/aticonsole.h
new file mode 100644
index 000000000..51cbbdaea
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/aticonsole.h
@@ -0,0 +1,44 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/aticonsole.h,v 1.3 1999/07/06 11:38:27 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATICONSOLE_H___
+#define ___ATICONSOLE_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+#include "xf86str.h"
+
+extern Bool ATISaveScreen FunctionPrototype((ScreenPtr, int));
+
+extern Bool ATIEnterGraphics FunctionPrototype((ScreenPtr, ScrnInfoPtr,
+ ATIPtr));
+extern void ATILeaveGraphics FunctionPrototype((ScrnInfoPtr, ATIPtr));
+
+extern Bool ATISwitchMode FunctionPrototype((int, DisplayModePtr, int));
+
+extern Bool ATIEnterVT FunctionPrototype((int, int));
+extern void ATILeaveVT FunctionPrototype((int, int));
+
+extern void ATIFreeScreen FunctionPrototype((int, int));
+
+#endif /* ___ATICONSOLE_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/aticrtc.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/aticrtc.c
new file mode 100644
index 000000000..869596e0d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/aticrtc.c
@@ -0,0 +1,864 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/aticrtc.c,v 1.7 1999/08/21 13:48:31 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "ati.h"
+#include "atiadapter.h"
+#include "atichip.h"
+#include "atidac.h"
+#include "atidsp.h"
+#include "atimach64.h"
+#include "atiprint.h"
+#include "ativga.h"
+#include "atiwonder.h"
+
+/*
+ * ATICopyVGAMemory --
+ *
+ * This function is called to copy one or all banks of a VGA plane.
+ */
+static void
+ATICopyVGAMemory
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW,
+ pointer *saveptr,
+ pointer *from,
+ pointer *to
+)
+{
+ unsigned int iBank;
+
+ for (iBank = 0; iBank < pATIHW->nBank; iBank++)
+ {
+ (*pATIHW->SetBank)(pATI, iBank);
+ (void) memcpy(*to, *from, 0x00010000U);
+ *saveptr = (char *)(*saveptr) + 0x00010000U;
+ }
+}
+
+/*
+ * ATISwap --
+ *
+ * This function saves/restores video memory contents during video mode
+ * switches.
+ */
+static void
+ATISwap
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW,
+ Bool ToFB
+)
+{
+ pointer save, *from, *to;
+ unsigned int iPlane = 0, PlaneMask = 1;
+ CARD8 seq2, seq4, gra1, gra3, gra4, gra5, gra6, gra8;
+
+ /*
+ * This is only done for non-accelerator modes. If the video state on
+ * server entry was an accelerator mode, the application that relinquished
+ * the console had better do the Right Thing (tm) anyway by saving and
+ * restoring its own video memory contents.
+ */
+ if (pATIHW->crtc != ATI_CRTC_VGA)
+ return;
+
+ if (ToFB)
+ {
+ if (!pATIHW->frame_buffer)
+ return;
+
+ from = &save;
+ to = &pATI->pBank;
+ }
+ else
+ {
+ /* Allocate the memory */
+ if (!pATIHW->frame_buffer)
+ {
+ pATIHW->frame_buffer =
+ (pointer)xalloc(pATIHW->nBank * pATIHW->nPlane * 0x00010000U);
+ if (!pATIHW->frame_buffer)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Temporary frame buffer could not be allocated.\n");
+ return;
+ }
+ }
+
+ from = &pATI->pBank;
+ to = &save;
+ }
+
+ /* Turn off screen */
+ ATIVGASaveScreen(pATI, FALSE);
+
+ /* Save register values to be modified */
+ seq2 = GetReg(SEQX, 0x02U);
+ seq4 = GetReg(SEQX, 0x04U);
+ gra1 = GetReg(GRAX, 0x01U);
+ gra3 = GetReg(GRAX, 0x03U);
+ gra4 = GetReg(GRAX, 0x04U);
+ gra5 = GetReg(GRAX, 0x05U);
+ gra6 = GetReg(GRAX, 0x06U);
+ gra8 = GetReg(GRAX, 0x08U);
+
+ save = pATIHW->frame_buffer;
+
+ /* Temporarily normalize the mode */
+ if (gra1 != 0x00U)
+ PutReg(GRAX, 0x01U, 0x00U);
+ if (gra3 != 0x00U)
+ PutReg(GRAX, 0x03U, 0x00U);
+ if (gra6 != 0x05U)
+ PutReg(GRAX, 0x06U, 0x05U);
+ if (gra8 != 0xFFU)
+ PutReg(GRAX, 0x08U, 0xFFU);
+
+ if (seq4 & 0x08U)
+ {
+ /* Setup packed mode memory */
+ if (seq2 != 0x0FU)
+ PutReg(SEQX, 0x02U, 0x0FU);
+ if (seq4 != 0x0AU)
+ PutReg(SEQX, 0x04U, 0x0AU);
+ if (pATI->Chip < ATI_CHIP_264CT)
+ {
+ if (gra5 != 0x00U)
+ PutReg(GRAX, 0x05U, 0x00U);
+ }
+ else
+ {
+ if (gra5 != 0x40U)
+ PutReg(GRAX, 0x05U, 0x40U);
+ }
+
+ ATICopyVGAMemory(pATI, pATIHW, &save, from, to);
+
+ if (seq2 != 0x0FU)
+ PutReg(SEQX, 0x02U, seq2);
+ if (seq4 != 0x0AU)
+ PutReg(SEQX, 0x04U, seq4);
+ if (pATI->Chip < ATI_CHIP_264CT)
+ {
+ if (gra5 != 0x00U)
+ PutReg(GRAX, 0x05U, gra5);
+ }
+ else
+ {
+ if (gra5 != 0x40U)
+ PutReg(GRAX, 0x05U, gra5);
+ }
+ }
+ else
+ {
+ gra4 = GetReg(GRAX, 0x04U);
+
+ /* Setup planar mode memory */
+ if (seq4 != 0x06U)
+ PutReg(SEQX, 0x04U, 0x06U);
+ if (gra5 != 0x00U)
+ PutReg(GRAX, 0x05U, 0x00U);
+
+ for (; iPlane < pATIHW->nPlane; iPlane++)
+ {
+ PutReg(SEQX, 0x02U, PlaneMask);
+ PutReg(GRAX, 0x04U, iPlane);
+ ATICopyVGAMemory(pATI, pATIHW, &save, from, to);
+ PlaneMask <<= 1;
+ }
+
+ PutReg(SEQX, 0x02U, seq2);
+ if (seq4 != 0x06U)
+ PutReg(SEQX, 0x04U, seq4);
+ PutReg(GRAX, 0x04U, gra4);
+ if (gra5 != 0x00U)
+ PutReg(GRAX, 0x05U, gra5);
+ }
+
+ /* Restore registers */
+ if (gra1 != 0x00U)
+ PutReg(GRAX, 0x01U, gra1);
+ if (gra3 != 0x00U)
+ PutReg(GRAX, 0x03U, gra3);
+ if (gra6 != 0x05U)
+ PutReg(GRAX, 0x06U, gra6);
+ if (gra8 != 0xFFU)
+ PutReg(GRAX, 0x08U, gra8);
+
+ /* Back to bank 0 */
+ (*pATIHW->SetBank)(pATI, 0);
+
+ /*
+ * If restoring video memory for a server video mode, free the frame buffer
+ * save area.
+ */
+ if (ToFB && (pATIHW == &pATI->NewHW))
+ {
+ xfree(pATIHW->frame_buffer);
+ pATIHW->frame_buffer = NULL;
+ }
+}
+
+/*
+ * ATICRTCPreInit --
+ *
+ * This function initializes an ATIHWRec with information common to all video
+ * states generated by the driver.
+ */
+void
+ATICRTCPreInit
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ CARD32 lcd_index;
+
+ if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
+ {
+ /* Fill in VGA data */
+ ATIVGAPreInit(pScreenInfo, pATI, pATIHW);
+
+ /* Fill in VGA Wonder data */
+ if (pATI->CPIO_VGAWonder)
+ ATIVGAWonderPreInit(pScreenInfo, pATI, pATIHW);
+ }
+
+ /* Fill in Mach64 data */
+ if (pATI->Chip >= ATI_CHIP_88800GXC)
+ ATIMach64PreInit(pScreenInfo, pATI, pATIHW);
+
+ /* For now disable extended reference and feedback dividers */
+ if (pATI->Chip >= ATI_CHIP_264LT)
+ pATIHW->pll_ext_vpll_cntl = ATIGetMach64PLLReg(PLL_EXT_VPLL_CNTL) &
+ ~(PLL_EXT_VPLL_EN | PLL_EXT_VPLL_VGA_EN | PLL_EXT_VPLL_INSYNC);
+
+ /* Initialize CRTC data for LCD panels */
+ if (pATI->LCDPanelID >= 0)
+ {
+ int HDisplay, VDisplay;
+
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ pATIHW->lcd_gen_ctrl = inl(pATI->CPIO_LCD_GEN_CTRL);
+ pATIHW->power_management = inl(pATI->CPIO_POWER_MANAGEMENT);
+ }
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL)) */
+ {
+ lcd_index = inl(pATI->CPIO_LCD_INDEX);
+ pATIHW->lcd_index = (lcd_index &
+ ~(LCD_REG_INDEX | LCD_DISPLAY_DIS | LCD_SRC_SEL)) |
+ (LCD_SRC_SEL_CRTC1 | LCD_CRTC2_DISPLAY_DIS);
+ pATIHW->config_panel =
+ ATIGetLTProLCDReg(LCD_CONFIG_PANEL) | DONT_SHADOW_HEND;
+ pATIHW->lcd_gen_ctrl = ATIGetLTProLCDReg(LCD_GEN_CNTL);
+ pATIHW->power_management =
+ ATIGetLTProLCDReg(LCD_POWER_MANAGEMENT);
+ outl(pATI->CPIO_LCD_INDEX, lcd_index);
+ }
+
+ /*
+ * Use primary CRTC to drive the panel. Turn off CRT interface.
+ */
+ pATIHW->lcd_gen_ctrl &=
+ ~(CRT_ON | CRTC_RW_SELECT | HORZ_DIVBY2_EN | DIS_HOR_CRT_DIVBY2 |
+ USE_SHADOWED_VEND | USE_SHADOWED_ROWCUR | SHADOW_EN |
+ SHADOW_RW_EN);
+ pATIHW->lcd_gen_ctrl |= DONT_SHADOW_VPAR | LOCK_8DOT;
+
+ /* Disable power management */
+ pATIHW->power_management &= ~PWR_MGT_ON;
+
+ /*
+ * XXX
+ *
+ * Determine porch data. This is ugly and will be removed when the
+ * common layer's mode validation is changed to better deal with
+ * panels. The intent here is to produce stretched modes that
+ * approximate the horizontal sync and vertical refresh rates of the
+ * mode on server entry (which, BTW, hasn't been saved yet). The
+ * following is inaccurate (but still good enough) when BIOS
+ * initialization has set things up so that the registers read here are
+ * not the ones actually in use by the panel.
+ */
+ if (inl(pATI->CPIO_CRTC_GEN_CNTL) & CRTC_EXT_DISP_EN)
+ {
+ pATIHW->crtc_h_total_disp = inl(pATI->CPIO_CRTC_H_TOTAL_DISP);
+ pATIHW->crtc_h_sync_strt_wid =
+ inl(pATI->CPIO_CRTC_H_SYNC_STRT_WID);
+ pATIHW->crtc_v_total_disp = inl(pATI->CPIO_CRTC_V_TOTAL_DISP);
+ pATIHW->crtc_v_sync_strt_wid =
+ inl(pATI->CPIO_CRTC_V_SYNC_STRT_WID);
+
+ HDisplay = GetBits(pATIHW->crtc_h_total_disp, CRTC_H_DISP);
+ VDisplay = GetBits(pATIHW->crtc_v_total_disp, CRTC_V_DISP);
+
+ pATI->LCDHSyncStart =
+ (GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_STRT_HI) *
+ (MaxBits(CRTC_H_SYNC_STRT) + 1)) +
+ GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_STRT) -
+ HDisplay;
+ pATI->LCDHSyncWidth =
+ GetBits(pATIHW->crtc_h_sync_strt_wid, CRTC_H_SYNC_WID);
+ pATI->LCDHBlankWidth =
+ GetBits(pATIHW->crtc_h_total_disp, CRTC_H_TOTAL) - HDisplay;
+ pATI->LCDVSyncStart =
+ GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_STRT) -
+ VDisplay;
+ pATI->LCDVSyncWidth =
+ GetBits(pATIHW->crtc_v_sync_strt_wid, CRTC_V_SYNC_WID);
+ pATI->LCDVBlankWidth =
+ GetBits(pATIHW->crtc_v_total_disp, CRTC_V_TOTAL) - VDisplay;
+ }
+ else
+ {
+ pATIHW->crt[0] = GetReg(CRTX(pATI->CPIO_VGABase), 0x00U);
+ pATIHW->crt[1] = GetReg(CRTX(pATI->CPIO_VGABase), 0x01U);
+ pATIHW->crt[4] = GetReg(CRTX(pATI->CPIO_VGABase), 0x04U);
+ pATIHW->crt[5] = GetReg(CRTX(pATI->CPIO_VGABase), 0x05U);
+ pATIHW->crt[6] = GetReg(CRTX(pATI->CPIO_VGABase), 0x06U);
+ pATIHW->crt[7] = GetReg(CRTX(pATI->CPIO_VGABase), 0x07U);
+ pATIHW->crt[16] = GetReg(CRTX(pATI->CPIO_VGABase), 0x10U);
+ pATIHW->crt[17] = GetReg(CRTX(pATI->CPIO_VGABase), 0x11U);
+ pATIHW->crt[18] = GetReg(CRTX(pATI->CPIO_VGABase), 0x12U);
+
+ HDisplay = pATIHW->crt[1] + 1;
+ VDisplay = (((pATIHW->crt[7] << 3) & 0x0200U) |
+ ((pATIHW->crt[7] << 7) & 0x0100U) |
+ pATIHW->crt[18]) + 1;
+
+ pATI->LCDHSyncStart = pATIHW->crt[4] - HDisplay;
+ pATI->LCDHSyncWidth = (pATIHW->crt[5] - pATIHW->crt[4]) & 0x1FU;
+ pATI->LCDHBlankWidth = pATIHW->crt[0] + 5 - HDisplay;
+ pATI->LCDVSyncStart = (((pATIHW->crt[7] << 2) & 0x0200U) |
+ ((pATIHW->crt[7] << 6) & 0x0100U) |
+ pATIHW->crt[16]) - VDisplay;
+ pATI->LCDVSyncWidth = (pATIHW->crt[17] - pATIHW->crt[16]) & 0x0FU;
+ pATI->LCDVBlankWidth = (((pATIHW->crt[7] << 4) & 0x0200U) |
+ ((pATIHW->crt[7] << 8) & 0x0100U) |
+ pATIHW->crt[6]) + 2 - VDisplay;
+ }
+
+ pATI->LCDHSyncStart <<= 3;
+ pATI->LCDHSyncWidth <<= 3;
+ pATI->LCDHBlankWidth <<= 3;
+ }
+
+ /* Set RAMDAC data */
+ ATIDACPreInit(pScreenInfo, pATIHW);
+}
+
+/*
+ * ATICRTCSave --
+ *
+ * This function saves the curent video state.
+ */
+void
+ATICRTCSave
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ int Index;
+
+ /* Get bank to bank 0 */
+ (*pATIHW->SetBank)(pATI, 0);
+
+ /* Save clock data */
+ ATIClockSave(pScreenInfo, pATI, pATIHW);
+ if (pATI->Chip >= ATI_CHIP_264LT)
+ pATIHW->pll_ext_vpll_cntl = ATIGetMach64PLLReg(PLL_EXT_VPLL_CNTL);
+
+ /* Save LCD registers */
+ if (pATI->LCDPanelID >= 0)
+ {
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ pATIHW->horz_stretching = inl(pATI->CPIO_HORZ_STRETCHING);
+ pATIHW->vert_stretching = inl(pATI->CPIO_VERT_STRETCHING);
+ pATIHW->lcd_gen_ctrl = inl(pATI->CPIO_LCD_GEN_CTRL);
+ pATIHW->power_management = inl(pATI->CPIO_POWER_MANAGEMENT);
+
+ /* Set up to save non-shadow registers */
+ outl(pATI->CPIO_LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl &
+ ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN));
+ }
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL)) */
+ {
+ pATIHW->lcd_index = inl(pATI->CPIO_LCD_INDEX);
+ pATIHW->config_panel = ATIGetLTProLCDReg(LCD_CONFIG_PANEL);
+ pATIHW->lcd_gen_ctrl = ATIGetLTProLCDReg(LCD_GEN_CNTL);
+ pATIHW->horz_stretching = ATIGetLTProLCDReg(LCD_HORZ_STRETCHING);
+ pATIHW->vert_stretching = ATIGetLTProLCDReg(LCD_VERT_STRETCHING);
+ pATIHW->ext_vert_stretch = ATIGetLTProLCDReg(LCD_EXT_VERT_STRETCH);
+ pATIHW->power_management = ATIGetLTProLCDReg(LCD_POWER_MANAGEMENT);
+
+ /* Set up to save non-shadow registers */
+ ATIPutLTProLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl &
+ ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN));
+ }
+ }
+
+ if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
+ {
+ /* Save VGA data */
+ ATIVGASave(pATI, pATIHW);
+
+ /* Save VGA Wonder data */
+ if (pATI->CPIO_VGAWonder)
+ ATIVGAWonderSave(pATI, pATIHW);
+ }
+
+ /* Save Mach64 data */
+ if (pATI->Chip >= ATI_CHIP_88800GXC)
+ ATIMach64Save(pATI, pATIHW);
+
+ /* Save DSP data */
+ if ((pATI->Chip >= ATI_CHIP_264VTB) && (pATI->CPIODecoding == BLOCK_IO))
+ ATIDSPSave(pATI, pATIHW);
+
+ if (pATI->LCDPanelID >= 0)
+ {
+ /* Switch to shadow registers */
+ if (pATI->Chip == ATI_CHIP_264LT)
+ outl(pATI->CPIO_LCD_GEN_CTRL,
+ (pATIHW->lcd_gen_ctrl & ~CRTC_RW_SELECT) |
+ (SHADOW_EN | SHADOW_RW_EN));
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL)) */
+ ATIPutLTProLCDReg(LCD_GEN_CNTL,
+ (pATIHW->lcd_gen_ctrl & ~CRTC_RW_SELECT) |
+ (SHADOW_EN | SHADOW_RW_EN));
+
+ /* Save shadow VGA CRTC registers */
+ for (Index = 0; Index < NumberOf(pATIHW->shadow_vga); Index++)
+ pATIHW->shadow_vga[Index] =
+ GetReg(CRTX(pATI->CPIO_VGABase), Index);
+
+ /* Save shadow Mach64 CRTC registers */
+ pATIHW->shadow_h_total_disp = inl (pATI->CPIO_CRTC_H_TOTAL_DISP);
+ pATIHW->shadow_h_sync_strt_wid = inl(pATI->CPIO_CRTC_H_SYNC_STRT_WID);
+ pATIHW->shadow_v_total_disp = inl (pATI->CPIO_CRTC_V_TOTAL_DISP);
+ pATIHW->shadow_v_sync_strt_wid = inl(pATI->CPIO_CRTC_V_SYNC_STRT_WID);
+
+ /* Restore CRTC selection and shadow state */
+ if (pATI->Chip == ATI_CHIP_264LT)
+ outl(pATI->CPIO_LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl);
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL)) */
+ {
+ ATIPutLTProLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl);
+ outl(pATI->CPIO_LCD_INDEX, pATIHW->lcd_index);
+ }
+ }
+
+ /*
+ * For some unknown reason, CLKDIV2 needs to be turned off to save the
+ * DAC's LUT reliably on VGA Wonder VLB adapters.
+ */
+ if ((pATI->Adapter == ATI_ADAPTER_NONISA) && (pATIHW->seq[1] & 0x08U))
+ PutReg(SEQX, 0x01U, pATIHW->seq[1] & ~0x08U);
+
+ /* Save RAMDAC state */
+ ATIDACSave(pATI, pATIHW);
+
+ if ((pATI->Adapter == ATI_ADAPTER_NONISA) && (pATIHW->seq[1] & 0x08U))
+ PutReg(SEQX, 0x01U, pATIHW->seq[1]);
+
+ /*
+ * The server has already saved video memory contents when switching out of
+ * its virtual console, so don't do it again.
+ */
+ if (pATIHW != &pATI->NewHW)
+ {
+ pATIHW->FeedbackDivider = 0; /* Don't programme clock */
+
+ ATISwap(pScreenInfo, pATI, pATIHW, FALSE); /* Save video memory */
+ }
+
+ if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
+ ATIVGASaveScreen(pATI, TRUE); /* Turn on screen */
+}
+
+/*
+ * ATICRTCCalculate --
+ *
+ * This function fills in the an ATIHWRec with all register values needed to
+ * enable a video state. It's important that this be done without modifying
+ * the current video state.
+ */
+Bool
+ATICRTCCalculate
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW,
+ DisplayModePtr pMode
+)
+{
+ CARD32 lcd_index;
+ int Index;
+
+ /* XXX Clobber mode timings */
+ if ((pATI->LCDPanelID >= 0) &&
+ !(pMode->CrtcHAdjusted) &&
+ !(pMode->CrtcVAdjusted))
+ {
+ pMode->Flags &= ~(V_DBLSCAN | V_INTERLACE | V_CLKDIV2);
+
+ pMode->HSyncStart = pMode->HDisplay + pATI->LCDHSyncStart;
+ pMode->HSyncEnd = pMode->HSyncStart + pATI->LCDHSyncWidth;
+ pMode->HTotal = pMode->HDisplay + pATI->LCDHBlankWidth;
+
+ pMode->VSyncStart = pMode->VDisplay + pATI->LCDVSyncStart;
+ pMode->VSyncEnd = pMode->VSyncStart + pATI->LCDVSyncWidth;
+ pMode->VTotal = pMode->VDisplay + pATI->LCDVBlankWidth;
+
+ pMode->VScan = 0;
+ }
+
+ switch (pATIHW->crtc)
+ {
+ case ATI_CRTC_VGA:
+ /* Fill in VGA data */
+ ATIVGACalculate(pATI, pATIHW, pMode);
+
+ /* Fill in VGA Wonder data */
+ if (pATI->CPIO_VGAWonder)
+ ATIVGAWonderCalculate(pScreenInfo, pATI, pATIHW, pMode);
+
+ if (pATI->Chip >= ATI_CHIP_88800GXC)
+ {
+ pATIHW->crtc_gen_cntl = inl(pATI->CPIO_CRTC_GEN_CNTL) &
+ ~(CRTC_DBL_SCAN_EN | CRTC_INTERLACE_EN |
+ CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_CSYNC_EN |
+ CRTC_PIX_BY_2_EN | CRTC_DISPLAY_DIS |
+ CRTC_VGA_XOVERSCAN | CRTC_VGA_128KAP_PAGING |
+ CRTC_VFC_SYNC_TRISTATE |
+ CRTC_LOCK_REGS | /* Already off, but ... */
+ CRTC_SYNC_TRISTATE | CRTC_EXT_DISP_EN |
+ CRTC_DISP_REQ_EN | CRTC_VGA_LINEAR | CRTC_VGA_TEXT_132 |
+ CRTC_CUR_B_TEST);
+#if 0 /* This isn't needed, but is kept for reference */
+ if (pMode->Flags & V_DBLSCAN)
+ pATIHW->crtc_gen_cntl |= CRTC_DBL_SCAN_EN;
+#endif
+ if (pMode->Flags & V_INTERLACE)
+ pATIHW->crtc_gen_cntl |= CRTC_INTERLACE_EN;
+ if ((pMode->Flags & (V_CSYNC | V_PCSYNC)) || pATI->OptionCSync)
+ pATIHW->crtc_gen_cntl |= CRTC_CSYNC_EN;
+ if (pScreenInfo->depth <= 4)
+ pATIHW->crtc_gen_cntl |= CRTC_EN | CRTC_CNT_EN;
+ else
+ pATIHW->crtc_gen_cntl |=
+ CRTC_EN | CRTC_VGA_LINEAR | CRTC_CNT_EN;
+ }
+ break;
+
+ case ATI_CRTC_MACH64:
+ /*
+ * Fill in Mach64 data.
+ */
+ ATIMach64Calculate(pScreenInfo, pATI, pATIHW, pMode);
+ break;
+
+ default:
+ break;
+ }
+
+ /* Set up LCD register values */
+ if (pATI->LCDPanelID >= 0)
+ {
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ pATIHW->horz_stretching = inl(pATI->CPIO_HORZ_STRETCHING);
+ pATIHW->vert_stretching = inl(pATI->CPIO_VERT_STRETCHING);
+ }
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL)) */
+ {
+ lcd_index = inl(pATI->CPIO_LCD_INDEX);
+ pATIHW->horz_stretching = ATIGetLTProLCDReg(LCD_HORZ_STRETCHING);
+ pATIHW->vert_stretching = ATIGetLTProLCDReg(LCD_VERT_STRETCHING);
+ pATIHW->ext_vert_stretch =
+ ATIGetLTProLCDReg(LCD_EXT_VERT_STRETCH) &
+ ~(AUTO_VERT_RATIO | VERT_STRETCH_MODE);
+
+ /*
+ * Don't use vertical blending if the mode is too wide, too short,
+ * or not vertically stretched.
+ */
+ if ((pMode->HDisplay <= pATI->LCDVBlendFIFOSize) &&
+ (pMode->VDisplay < pATI->LCDVertical) &&
+ (pMode->VDisplay >= (pATI->LCDVertical / 2)))
+ pATIHW->ext_vert_stretch |= VERT_STRETCH_MODE;
+
+ outl(pATI->CPIO_LCD_INDEX, lcd_index);
+ }
+
+ pATIHW->horz_stretching &=
+ ~(HORZ_STRETCH_RATIO | HORZ_STRETCH_LOOP | HORZ_STRETCH_MODE |
+ HORZ_STRETCH_EN);
+ if (pMode->HDisplay < pATI->LCDHorizontal)
+ pATIHW->horz_stretching |= (HORZ_STRETCH_MODE | HORZ_STRETCH_EN) |
+ SetBits(((pMode->HDisplay & ~7) *
+ (MaxBits(HORZ_STRETCH_BLEND) + 1)) /
+ pATI->LCDHorizontal, HORZ_STRETCH_BLEND);
+
+ if (pMode->VDisplay >= pATI->LCDVertical)
+ pATIHW->vert_stretching &= ~VERT_STRETCH_EN;
+ else
+ {
+ pATIHW->vert_stretching &= ~VERT_STRETCH_RATIO0;
+ pATIHW->vert_stretching |= (VERT_STRETCH_USE0 | VERT_STRETCH_EN) |
+ SetBits((pMode->VDisplay *
+ (MaxBits(VERT_STRETCH_RATIO0) + 1)) /
+ pATI->LCDVertical, VERT_STRETCH_RATIO0);
+ }
+
+ /* Copy non-shadow CRTC register values to the shadow set */
+ for (Index = 0; Index < NumberOf(pATIHW->shadow_vga); Index++)
+ pATIHW->shadow_vga[Index] = pATIHW->crt[Index];
+
+ pATIHW->shadow_h_total_disp = pATIHW->crtc_h_total_disp;
+ pATIHW->shadow_h_sync_strt_wid = pATIHW->crtc_h_sync_strt_wid;
+ pATIHW->shadow_v_total_disp = pATIHW->crtc_v_total_disp;
+ pATIHW->shadow_v_sync_strt_wid = pATIHW->crtc_v_sync_strt_wid;
+ }
+
+ /* Fill in clock data */
+ return ATIClockCalculate(pScreenInfo, pATI, pATIHW, pMode);
+}
+
+/*
+ * ATICRTCSet --
+ *
+ * This function sets a video mode. It writes out all video state data that
+ * has been previously calculated or saved.
+ */
+void
+ATICRTCSet
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ int Index;
+
+ /* Get back to bank 0 */
+ (*pATIHW->SetBank)(pATI, 0);
+
+ if (pATI->Chip >= ATI_CHIP_264LT)
+ ATIPutMach64PLLReg(PLL_EXT_VPLL_CNTL, pATIHW->pll_ext_vpll_cntl);
+
+ /* Load LCD registers */
+ if (pATI->LCDPanelID >= 0)
+ {
+ /* Stop CRTC */
+ outl(pATI->CPIO_CRTC_GEN_CNTL, pATIHW->crtc_gen_cntl &
+ ~(CRTC_EXT_DISP_EN | CRTC_EN));
+
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ /* Update non-shadow registers first */
+ outl(pATI->CPIO_LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl &
+ ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN));
+
+ /* Temporarily disable stretching */
+ outl(pATI->CPIO_HORZ_STRETCHING, pATIHW->horz_stretching &
+ ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN));
+ outl(pATI->CPIO_VERT_STRETCHING, pATIHW->vert_stretching &
+ ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 |
+ VERT_STRETCH_USE0 | VERT_STRETCH_EN));
+ }
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL)) */
+ {
+ /* Update non-shadow registers first */
+ ATIPutLTProLCDReg(LCD_CONFIG_PANEL, pATIHW->config_panel);
+ ATIPutLTProLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl &
+ ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN));
+
+ /* Temporarily disable stretching */
+ ATIPutLTProLCDReg(LCD_HORZ_STRETCHING, pATIHW->horz_stretching &
+ ~(HORZ_STRETCH_MODE | HORZ_STRETCH_EN));
+ ATIPutLTProLCDReg(LCD_VERT_STRETCHING, pATIHW->vert_stretching &
+ ~(VERT_STRETCH_RATIO1 | VERT_STRETCH_RATIO2 |
+ VERT_STRETCH_USE0 | VERT_STRETCH_EN));
+ }
+ }
+
+ switch (pATIHW->crtc)
+ {
+ case ATI_CRTC_VGA:
+ /* Stop CRTC */
+ if (pATI->Chip >= ATI_CHIP_88800GXC)
+ outl(pATI->CPIO_CRTC_GEN_CNTL,
+ pATIHW->crtc_gen_cntl & ~CRTC_EN);
+
+ /* Start sequencer reset */
+ PutReg(SEQX, 0x00U, 0x00U);
+
+ /* Set pixel clock */
+ if ((pATIHW->FeedbackDivider > 0) &&
+ (pATI->ProgrammableClock != ATI_CLOCK_FIXED))
+ ATIClockSet(pATI, pATIHW);
+
+ /* Load VGA Wonder */
+ if (pATI->CPIO_VGAWonder)
+ ATIVGAWonderSet(pATI, pATIHW);
+
+ /* Load VGA device */
+ ATIVGASet(pATI, pATIHW);
+
+ /* Load Mach64 registers */
+ if (pATI->Chip >= ATI_CHIP_88800GXC)
+ {
+ outl(pATI->CPIO_CRTC_GEN_CNTL, pATIHW->crtc_gen_cntl);
+ outl(pATI->CPIO_MEM_VGA_WP_SEL, pATIHW->mem_vga_wp_sel);
+ outl(pATI->CPIO_MEM_VGA_RP_SEL, pATIHW->mem_vga_rp_sel);
+ if (pATI->Chip >= ATI_CHIP_264CT)
+ {
+ outl(pATI->CPIO_CRTC_OFF_PITCH, pATIHW->crtc_off_pitch);
+ outl(pATI->CPIO_BUS_CNTL, pATIHW->bus_cntl);
+ outl(pATI->CPIO_DAC_CNTL, pATIHW->dac_cntl);
+ outl(pATI->CPIO_CONFIG_CNTL, pATIHW->config_cntl);
+ }
+ }
+
+ break;
+
+ case ATI_CRTC_MACH64:
+ /* Load Mach64 CRTC registers */
+ ATIMach64Set(pATI, pATIHW);
+
+ if (pATI->UseSmallApertures)
+ {
+ /* Oddly enough, these need to be set also, maybe others */
+ PutReg(SEQX, 0x02U, pATIHW->seq[2]);
+ PutReg(SEQX, 0x04U, pATIHW->seq[4]);
+ PutReg(GRAX, 0x06U, pATIHW->gra[6]);
+ if (pATI->CPIO_VGAWonder)
+ ATIModifyExtReg(pATI, 0xB6U, -1, 0x00U, pATIHW->b6);
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ if (pATI->LCDPanelID >= 0)
+ {
+ if (!pATI->OptionDevel || (pATIHW == &pATI->OldHW))
+ {
+ /* Switch to shadow registers */
+ if (pATI->Chip == ATI_CHIP_264LT)
+ outl(pATI->CPIO_LCD_GEN_CTRL,
+ (pATIHW->lcd_gen_ctrl & ~CRTC_RW_SELECT) |
+ (SHADOW_EN | SHADOW_RW_EN));
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL)) */
+ ATIPutLTProLCDReg(LCD_GEN_CNTL,
+ (pATIHW->lcd_gen_ctrl & ~CRTC_RW_SELECT) |
+ (SHADOW_EN | SHADOW_RW_EN));
+
+ /* Restore shadow registers */
+ switch (pATIHW->crtc)
+ {
+ case ATI_CRTC_VGA:
+ for (Index = 0;
+ Index < NumberOf(pATIHW->shadow_vga);
+ Index++)
+ PutReg(CRTX(pATI->CPIO_VGABase), Index,
+ pATIHW->shadow_vga[Index]);
+ break;
+
+ case ATI_CRTC_MACH64:
+ outl(pATI->CPIO_CRTC_H_TOTAL_DISP,
+ pATIHW->shadow_h_total_disp);
+ outl(pATI->CPIO_CRTC_H_SYNC_STRT_WID,
+ pATIHW->shadow_h_sync_strt_wid);
+ outl(pATI->CPIO_CRTC_V_TOTAL_DISP,
+ pATIHW->shadow_v_total_disp);
+ outl(pATI->CPIO_CRTC_V_SYNC_STRT_WID,
+ pATIHW->shadow_v_sync_strt_wid);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* Restore CRTC selection & shadow state and enable stretching */
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ outl(pATI->CPIO_LCD_GEN_CTRL, pATIHW->lcd_gen_ctrl);
+ outl(pATI->CPIO_HORZ_STRETCHING, pATIHW->horz_stretching);
+ outl(pATI->CPIO_VERT_STRETCHING, pATIHW->vert_stretching);
+ outl(pATI->CPIO_POWER_MANAGEMENT, pATIHW->power_management);
+ }
+ else /* if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL)) */
+ {
+ ATIPutLTProLCDReg(LCD_GEN_CNTL, pATIHW->lcd_gen_ctrl);
+ ATIPutLTProLCDReg(LCD_HORZ_STRETCHING, pATIHW->horz_stretching);
+ ATIPutLTProLCDReg(LCD_VERT_STRETCHING, pATIHW->vert_stretching);
+ ATIPutLTProLCDReg(LCD_EXT_VERT_STRETCH, pATIHW->ext_vert_stretch);
+ ATIPutLTProLCDReg(LCD_POWER_MANAGEMENT, pATIHW->power_management);
+ outl(pATI->CPIO_LCD_INDEX, pATIHW->lcd_index);
+ }
+ }
+
+ /*
+ * Set DSP registers. Note that sequencer resets clear the DSP_CONFIG
+ * register, for some reason.
+ */
+ if ((pATI->Chip >= ATI_CHIP_264VTB) && (pATI->CPIODecoding == BLOCK_IO))
+ ATIDSPSet(pATI, pATIHW);
+
+ /* Load RAMDAC */
+ ATIDACSet(pATI, pATIHW);
+
+ /* Restore video memory */
+ ATISwap(pScreenInfo, pATI, pATIHW, TRUE);
+
+ if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
+ ATIVGASaveScreen(pATI, TRUE); /* Turn screen back on */
+
+ if ((xf86GetVerbosity() > 3) && (pATIHW == &pATI->NewHW))
+ {
+ xf86ErrorFVerb(4, "\n After setting mode \"%s\":\n\n",
+ pScreenInfo->currentMode->name);
+ ATIPrintMode(pScreenInfo->currentMode);
+ ATIPrintRegisters(pATI);
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/aticrtc.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/aticrtc.h
new file mode 100644
index 000000000..09e8095cc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/aticrtc.h
@@ -0,0 +1,50 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/aticrtc.h,v 1.3 1999/07/06 11:38:27 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATICRTC_H___
+#define ___ATICRTC_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+#include "xf86str.h"
+
+/*
+ * CRTC related definitions.
+ */
+typedef enum
+{
+ ATI_CRTC_VGA, /* Use VGA CRTC */
+ ATI_CRTC_8514, /* Use 8514/Mach8/Mach32 accelerator CRTC */
+ ATI_CRTC_MACH64 /* Use Mach64 accelerator CRTC */
+} ATICRTCType;
+
+extern void ATICRTCPreInit FunctionPrototype((ScrnInfoPtr, ATIPtr,
+ ATIHWPtr));
+extern void ATICRTCSave FunctionPrototype((ScrnInfoPtr, ATIPtr,
+ ATIHWPtr));
+extern Bool ATICRTCCalculate FunctionPrototype((ScrnInfoPtr, ATIPtr,
+ ATIHWPtr, DisplayModePtr));
+extern void ATICRTCSet FunctionPrototype((ScrnInfoPtr, ATIPtr,
+ ATIHWPtr));
+
+#endif /* ___ATICRTC_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atidac.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atidac.c
new file mode 100644
index 000000000..177a71797
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atidac.c
@@ -0,0 +1,310 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidac.c,v 1.4 1999/07/18 03:26:53 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "atidac.h"
+#include "atimono.h"
+
+/*
+ * RAMDAC-related definitions.
+ */
+const DACRec ATIDACDescriptors[] =
+{ /* Keep this table in ascending DACType order */
+ {ATI_DAC_ATI68830, "ATI 68830 or similar"},
+ {ATI_DAC_SC11483, "Sierra 11483 or similar"},
+ {ATI_DAC_ATI68875, "ATI 68875 or similar"},
+ {ATI_DAC_TVP3026_A, "TI ViewPoint3026 or similar"},
+ {ATI_DAC_GENERIC, "Brooktree 476 or similar"},
+ {ATI_DAC_BT481, "Brooktree 481 or similar"},
+ {ATI_DAC_ATT20C491, "AT&T 20C491 or similar"},
+ {ATI_DAC_SC15026, "Sierra 15026 or similar"},
+ {ATI_DAC_MU9C1880, "Music 9C1880 or similar"},
+ {ATI_DAC_IMSG174, "Inmos G174 or similar"},
+ {ATI_DAC_ATI68860_B, "ATI 68860 (Revision B) or similar"},
+ {ATI_DAC_ATI68860_C, "ATI 68860 (Revision C) or similar"},
+ {ATI_DAC_TVP3026_B, "TI ViewPoint3026 or similar"},
+ {ATI_DAC_STG1700, "SGS-Thompson 1700 or similar"},
+ {ATI_DAC_ATT20C498, "AT&T 20C498 or similar"},
+ {ATI_DAC_STG1702, "SGS-Thompson 1702 or similar"},
+ {ATI_DAC_SC15021, "Sierra 15021 or similar"},
+ {ATI_DAC_ATT21C498, "AT&T 21C498 or similar"},
+ {ATI_DAC_STG1703, "SGS-Thompson 1703 or similar"},
+ {ATI_DAC_CH8398, "Chrontel 8398 or similar"},
+ {ATI_DAC_ATT20C408, "AT&T 20C408 or similar"},
+ {ATI_DAC_INTERNAL, "Internal"},
+ {ATI_DAC_IBMRGB514, "IBM RGB 514 or similar"},
+ {ATI_DAC_UNKNOWN, "Unknown"} /* Must be last */
+};
+
+/*
+ * ATISetDACIOPorts --
+ *
+ * This function sets up DAC access I/O port numbers.
+ */
+void
+ATISetDACIOPorts
+(
+ ATIPtr pATI,
+ ATICRTCType crtc
+)
+{
+ switch (crtc)
+ {
+ case ATI_CRTC_VGA:
+ pATI->CPIO_DAC_DATA = VGA_DAC_DATA;
+ pATI->CPIO_DAC_MASK = VGA_DAC_MASK;
+ pATI->CPIO_DAC_READ = VGA_DAC_READ;
+ pATI->CPIO_DAC_WRITE = VGA_DAC_WRITE;
+ break;
+
+ case ATI_CRTC_8514:
+ pATI->CPIO_DAC_DATA = DAC_DATA;
+ pATI->CPIO_DAC_MASK = DAC_MASK;
+ pATI->CPIO_DAC_READ = DAC_R_INDEX;
+ pATI->CPIO_DAC_WRITE = DAC_W_INDEX;
+ break;
+
+ case ATI_CRTC_MACH64:
+ pATI->CPIO_DAC_DATA = pATI->CPIO_DAC_REGS + 1;
+ pATI->CPIO_DAC_MASK = pATI->CPIO_DAC_REGS + 2;
+ pATI->CPIO_DAC_READ = pATI->CPIO_DAC_REGS + 3;
+ pATI->CPIO_DAC_WRITE = pATI->CPIO_DAC_REGS + 0;
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*
+ * ATIGetDACCmdReg --
+ *
+ * Setup to access a RAMDAC's command register.
+ */
+CARD8
+ATIGetDACCmdReg
+(
+ ATIPtr pATI
+)
+{
+ (void) inb(pATI->CPIO_DAC_WRITE); /* Reset to PEL mode */
+ (void) inb(pATI->CPIO_DAC_MASK);
+ (void) inb(pATI->CPIO_DAC_MASK);
+ (void) inb(pATI->CPIO_DAC_MASK);
+ return inb(pATI->CPIO_DAC_MASK);
+}
+
+/*
+ * ATIDACPreInit --
+ *
+ * This function initializes the fields in an ATIHWRec that relate to DACs.
+ */
+void
+ATIDACPreInit
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIHWPtr pATIHW
+)
+{
+ int Index, Index2;
+ CARD8 maxColour = (1 << pScreenInfo->rgbBits) - 1;
+
+ pATIHW->dac_read = pATIHW->dac_write = 0x00U;
+ pATIHW->dac_mask = 0xFFU;
+
+ /*
+ * Set colour lookup table. The first entry has already been zeroed out.
+ */
+ if (pScreenInfo->depth > 8)
+ for (Index = 1; Index < (NumberOf(pATIHW->lut) / 3); Index++)
+ {
+ Index2 = Index * 3;
+ pATIHW->lut[Index2 + 0] =
+ pATIHW->lut[Index2 + 1] =
+ pATIHW->lut[Index2 + 2] = Index;
+ }
+ else
+ {
+ /*
+ * Initialize hardware colour map so that use of uninitialized
+ * software colour map entries can easily be seen. For 256-colour
+ * modes, this doesn't remain effective for very long...
+ */
+ pATIHW->lut[3] = pATIHW->lut[4] = pATIHW->lut[5] = 0xFFU;
+ for (Index = 2; Index < (NumberOf(pATIHW->lut) / 3); Index++)
+ {
+ Index2 = Index * 3;
+ pATIHW->lut[Index2 + 0] = maxColour;
+ pATIHW->lut[Index2 + 1] = 0x00U;
+ pATIHW->lut[Index2 + 2] = maxColour;
+ }
+
+ if (pScreenInfo->depth == 1)
+ {
+ rgb blackColour = pScreenInfo->display->whiteColour,
+ whiteColour = pScreenInfo->display->whiteColour;
+
+ /* Check for defaults */
+ if (!blackColour.red && !blackColour.green && !blackColour.blue &&
+ !whiteColour.red && !whiteColour.green && !whiteColour.blue)
+ whiteColour.red = whiteColour.green = whiteColour.blue =
+ maxColour;
+
+ pATIHW->lut[(MONO_BLACK * 3) + 0] = blackColour.red;
+ pATIHW->lut[(MONO_BLACK * 3) + 1] = blackColour.green;
+ pATIHW->lut[(MONO_BLACK * 3) + 2] = blackColour.blue;
+ pATIHW->lut[(MONO_WHITE * 3) + 0] = whiteColour.red;
+ pATIHW->lut[(MONO_WHITE * 3) + 1] = whiteColour.green;
+ pATIHW->lut[(MONO_WHITE * 3) + 2] = whiteColour.blue;
+ }
+
+ if (pATIHW->crtc == ATI_CRTC_VGA)
+ {
+ /* Initialize overscan to black */
+ Index = pATIHW->attr[17] * 3;
+ pATIHW->lut[Index + 0] =
+ pATIHW->lut[Index + 1] =
+ pATIHW->lut[Index + 2] = 0x00U;
+ }
+ }
+}
+
+/*
+ * ATIDACSave --
+ *
+ * This function is called to save the current RAMDAC state into an ATIHWRec
+ * structure occurrence.
+ */
+void
+ATIDACSave
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ int Index;
+
+ ATISetDACIOPorts(pATI, pATIHW->crtc);
+
+ pATIHW->dac_read = inb(pATI->CPIO_DAC_READ);
+ DACDelay;
+ pATIHW->dac_write = inb(pATI->CPIO_DAC_WRITE);
+ DACDelay;
+ pATIHW->dac_mask = inb(pATI->CPIO_DAC_MASK);
+ DACDelay;
+
+ /* Save DAC's colour lookup table */
+ outb(pATI->CPIO_DAC_MASK, 0xFFU);
+ DACDelay;
+ outb(pATI->CPIO_DAC_READ, 0x00U);
+ DACDelay;
+ for (Index = 0; Index < NumberOf(pATIHW->lut); Index++)
+ {
+ pATIHW->lut[Index] = inb(pATI->CPIO_DAC_DATA);
+ DACDelay;
+ }
+
+ outb(pATI->CPIO_DAC_MASK, pATIHW->dac_mask);
+ DACDelay;
+ outb(pATI->CPIO_DAC_READ, pATIHW->dac_read);
+ DACDelay;
+}
+
+/*
+ * ATIDACSet --
+ *
+ * This function loads RAMDAC data from an ATIHWRec structure occurrence.
+ */
+void
+ATIDACSet
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ int Index;
+
+ ATISetDACIOPorts(pATI, pATIHW->crtc);
+
+ /* Load DAC's colour lookup table */
+ outb(pATI->CPIO_DAC_MASK, 0xFFU);
+ DACDelay;
+ outb(pATI->CPIO_DAC_WRITE, 0x00U);
+ DACDelay;
+ for (Index = 0; Index < NumberOf(pATIHW->lut); Index++)
+ {
+ outb(pATI->CPIO_DAC_DATA, pATIHW->lut[Index]);
+ DACDelay;
+ }
+
+ outb(pATI->CPIO_DAC_MASK, pATIHW->dac_mask);
+ DACDelay;
+ outb(pATI->CPIO_DAC_READ, pATIHW->dac_read);
+ DACDelay;
+ outb(pATI->CPIO_DAC_WRITE, pATIHW->dac_write);
+ DACDelay;
+}
+
+/*
+ * ATILoadPalette --
+ *
+ * This function updates the RAMDAC's LUT and the in-memory copy of it in
+ * NewHW.
+ */
+void
+ATILoadPalette
+(
+ ScrnInfoPtr pScreenInfo,
+ int nColours,
+ int *Indices,
+ LOCO *Colours,
+ VisualPtr pVisual
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ CARD8 *LUTEntry;
+ int i, Index;
+
+ for (i = 0; i < nColours; i++)
+ {
+ Index = Indices[i];
+ if ((Index < 0) || (Index > 255))
+ continue;
+
+ LUTEntry = &pATI->NewHW.lut[Index * 3];
+ LUTEntry[0] = Colours[Index].red;
+ LUTEntry[1] = Colours[Index].green;
+ LUTEntry[2] = Colours[Index].blue;
+
+ if (pScreenInfo->vtSema)
+ {
+ outb(pATI->CPIO_DAC_WRITE, Index);
+ DACDelay;
+ outb(pATI->CPIO_DAC_DATA, LUTEntry[0]);
+ DACDelay;
+ outb(pATI->CPIO_DAC_DATA, LUTEntry[1]);
+ DACDelay;
+ outb(pATI->CPIO_DAC_DATA, LUTEntry[2]);
+ DACDelay;
+ }
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atidac.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atidac.h
new file mode 100644
index 000000000..983aa0c55
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atidac.h
@@ -0,0 +1,88 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidac.h,v 1.4 1999/07/18 03:26:53 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIDAC_H___
+#define ___ATIDAC_H___ 1
+
+#include "aticrtc.h"
+#include "atiio.h"
+#include "colormapst.h"
+
+/*
+ * RAMDAC-related definitions.
+ */
+#define ATI_DAC_MAX_TYPE MaxBits(DACTYPE)
+#define ATI_DAC_MAX_SUBTYPE MaxBits(BIOS_INIT_DAC_SUBTYPE)
+
+#define ATI_DAC(_Type, _Subtype) (((_Type) << 4) | (_Subtype))
+
+#define ATI_DAC_ATI68830 ATI_DAC(0x0U, 0x0U)
+#define ATI_DAC_SC11483 ATI_DAC(0x1U, 0x0U)
+#define ATI_DAC_ATI68875 ATI_DAC(0x2U, 0x0U)
+#define ATI_DAC_TVP3026_A ATI_DAC(0x2U, 0x7U)
+#define ATI_DAC_GENERIC ATI_DAC(0x3U, 0x0U)
+#define ATI_DAC_BT481 ATI_DAC(0x4U, 0x0U)
+#define ATI_DAC_ATT20C491 ATI_DAC(0x4U, 0x1U)
+#define ATI_DAC_SC15026 ATI_DAC(0x4U, 0x2U)
+#define ATI_DAC_MU9C1880 ATI_DAC(0x4U, 0x3U)
+#define ATI_DAC_IMSG174 ATI_DAC(0x4U, 0x4U)
+#define ATI_DAC_ATI68860_B ATI_DAC(0x5U, 0x0U)
+#define ATI_DAC_ATI68860_C ATI_DAC(0x5U, 0x1U)
+#define ATI_DAC_TVP3026_B ATI_DAC(0x5U, 0x7U)
+#define ATI_DAC_STG1700 ATI_DAC(0x6U, 0x0U)
+#define ATI_DAC_ATT20C498 ATI_DAC(0x6U, 0x1U)
+#define ATI_DAC_STG1702 ATI_DAC(0x7U, 0x0U)
+#define ATI_DAC_SC15021 ATI_DAC(0x7U, 0x1U)
+#define ATI_DAC_ATT21C498 ATI_DAC(0x7U, 0x2U)
+#define ATI_DAC_STG1703 ATI_DAC(0x7U, 0x3U)
+#define ATI_DAC_CH8398 ATI_DAC(0x7U, 0x4U)
+#define ATI_DAC_ATT20C408 ATI_DAC(0x7U, 0x5U)
+#define ATI_DAC_INTERNAL ATI_DAC(0x8U, 0x0U)
+#define ATI_DAC_IBMRGB514 ATI_DAC(0x9U, 0x0U)
+#define ATI_DAC_UNKNOWN ATI_DAC((ATI_DAC_MAX_TYPE << 2) + 3, \
+ ATI_DAC_MAX_SUBTYPE)
+typedef struct
+{
+ const int DACType;
+ const char *DACName;
+} DACRec;
+extern const DACRec ATIDACDescriptors[];
+
+#define DACDelay \
+ do \
+ { \
+ (void)inb(GENS1(pATI->CPIO_VGABase)); \
+ (void)inb(GENS1(pATI->CPIO_VGABase)); \
+ } while(0)
+
+extern void ATISetDACIOPorts FunctionPrototype((ATIPtr, ATICRTCType));
+extern CARD8 ATIGetDACCmdReg FunctionPrototype((ATIPtr));
+
+extern void ATIDACPreInit FunctionPrototype((ScrnInfoPtr, ATIHWPtr));
+extern void ATIDACSave FunctionPrototype((ATIPtr, ATIHWPtr));
+extern void ATIDACSet FunctionPrototype((ATIPtr, ATIHWPtr));
+
+extern void ATILoadPalette FunctionPrototype((ScrnInfoPtr, int, int *, LOCO *,
+ VisualPtr));
+
+#endif /* ___ATIDAC_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atidsp.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atidsp.c
new file mode 100644
index 000000000..0edf91b28
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atidsp.c
@@ -0,0 +1,270 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidsp.c,v 1.5 1999/08/01 07:57:20 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "atichip.h"
+#include "aticrtc.h"
+#include "atidsp.h"
+#include "atiio.h"
+#include "atividmem.h"
+#include "xf86.h"
+
+/*
+ * ATIDSPPreInit --
+ *
+ * This function initializes global variables used to set DSP registers on a
+ * VT-B or later.
+ */
+Bool
+ATIDSPPreInit
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI
+)
+{
+ CARD32 IOValue;
+ int trp;
+
+ /* Set DSP register port numbers */
+ pATI->CPIO_DSP_CONFIG = ATIIOPort(DSP_CONFIG);
+ pATI->CPIO_DSP_ON_OFF = ATIIOPort(DSP_ON_OFF);
+
+ /*
+ * VT-B's and later have additional post-dividers that are not powers of
+ * two.
+ */
+ pATI->ClockDescriptor.NumD = 8;
+
+ /* Retrieve XCLK settings */
+ IOValue = ATIGetMach64PLLReg(PLL_XCLK_CNTL);
+ pATI->XCLKPostDivider = GetBits(IOValue, PLL_XCLK_SRC_SEL);
+ pATI->XCLKReferenceDivider = 1;
+ switch (pATI->XCLKPostDivider)
+ {
+ case 0: case 1: case 2: case 3:
+ break;
+
+ case 4:
+ pATI->XCLKReferenceDivider = 3;
+ pATI->XCLKPostDivider = 0;
+ break;
+
+ default:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Unsupported XCLK source: %d.\n", pATI->XCLKPostDivider);
+ return FALSE;
+ }
+
+ pATI->XCLKPostDivider -= GetBits(IOValue, PLL_MFB_TIMES_4_2B);
+ pATI->XCLKFeedbackDivider = ATIGetMach64PLLReg(PLL_MCLK_FB_DIV);
+
+ /* Compute maximum RAS delay and friends */
+ IOValue = inl(pATI->CPIO_MEM_INFO);
+ trp = GetBits(IOValue, CTL_MEM_TRP);
+ pATI->XCLKPageFaultDelay = GetBits(IOValue, CTL_MEM_TRCD) +
+ GetBits(IOValue, CTL_MEM_TCRD) + trp + 2;
+ pATI->XCLKMaxRASDelay = GetBits(IOValue, CTL_MEM_TRAS) + trp + 2;
+ pATI->DisplayFIFODepth = 32;
+
+ if (pATI->Chip < ATI_CHIP_264VT4)
+ {
+ pATI->XCLKPageFaultDelay += 2;
+ pATI->XCLKMaxRASDelay += 3;
+ pATI->DisplayFIFODepth = 24;
+ }
+
+ switch (pATI->MemoryType)
+ {
+ case MEM_264_DRAM:
+ if (pATI->VideoRAM <= 1024)
+ pATI->DisplayLoopLatency = 10;
+ else
+ {
+ pATI->DisplayLoopLatency = 8;
+ pATI->XCLKPageFaultDelay += 2;
+ }
+ break;
+
+ case MEM_264_EDO:
+ case MEM_264_PSEUDO_EDO:
+ if (pATI->VideoRAM <= 1024)
+ pATI->DisplayLoopLatency = 9;
+ else
+ {
+ pATI->DisplayLoopLatency = 8;
+ pATI->XCLKPageFaultDelay++;
+ }
+ break;
+
+ case MEM_264_SDRAM:
+ if (pATI->VideoRAM <= 1024)
+ pATI->DisplayLoopLatency = 11;
+ else
+ {
+ pATI->DisplayLoopLatency = 10;
+ pATI->XCLKPageFaultDelay++;
+ }
+ break;
+
+ case MEM_264_SGRAM:
+ pATI->DisplayLoopLatency = 8;
+ pATI->XCLKPageFaultDelay += 3;
+ break;
+
+ default: /* Set maximums */
+ pATI->DisplayLoopLatency = 11;
+ pATI->XCLKPageFaultDelay += 3;
+ break;
+ }
+
+ if (pATI->XCLKMaxRASDelay <= pATI->XCLKPageFaultDelay)
+ pATI->XCLKMaxRASDelay = pATI->XCLKPageFaultDelay + 1;
+
+ return TRUE;
+}
+
+/*
+ * ATIDSPSave --
+ *
+ * This function is called to remember DSP register values on VT-B and later
+ * controllers.
+ */
+void
+ATIDSPSave
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ pATIHW->dsp_on_off = inl(pATI->CPIO_DSP_ON_OFF);
+ pATIHW->dsp_config = inl(pATI->CPIO_DSP_CONFIG);
+}
+
+
+/*
+ * ATIDSPCalculate --
+ *
+ * This function sets up DSP register values for a VTB or later. Note that
+ * this would be slightly different if VCLK 0 or 1 were used for the mode
+ * instead. In that case, this function would set VGA_DSP_CONFIG and
+ * VGA_DSP_ON_OFF, would have to zero out DSP_CONFIG and DSP_ON_OFF, and would
+ * have to consider that VGA_DSP_CONFIG is partitioned slightly differently
+ * than DSP_CONFIG.
+ */
+void
+ATIDSPCalculate
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW,
+ DisplayModePtr pMode
+)
+{
+ int Multiplier, Divider;
+ int RASMultiplier = pATI->XCLKMaxRASDelay, RASDivider = 1;
+ int dsp_precision, dsp_on, dsp_off, dsp_xclks;
+ int tmp, vshift, xshift;
+
+# define Maximum_DSP_PRECISION ((int)MaxBits(DSP_PRECISION))
+
+ /* Compute a memory-to-screen bandwidth ratio */
+ Multiplier = pATI->XCLKFeedbackDivider *
+ pATI->ClockDescriptor.PostDividers[pATIHW->PostDivider];
+ Divider = pATIHW->FeedbackDivider * pATI->XCLKReferenceDivider;
+ if (pScreenInfo->depth >= 8)
+ Divider *= pScreenInfo->bitsPerPixel / 4;
+ /* Start by assuming a display FIFO width of 32 bits */
+ vshift = (5 - 2) - pATI->XCLKPostDivider;
+ if (pATIHW->crtc != ATI_CRTC_VGA)
+ vshift++; /* Nope, it's 64 bits wide */
+
+ if (pATI->LCDPanelID >= 0)
+ {
+ /* Compensate for horizontal stretching */
+ Multiplier *= pATI->LCDHorizontal;
+ Divider *= pMode->HDisplay;
+
+ RASMultiplier *= pATI->LCDHorizontal;
+ RASDivider *= pMode->HTotal;
+ }
+
+ /* Determine dsp_precision first */
+ tmp = ATIDivide(Multiplier * pATI->DisplayFIFODepth, Divider, vshift, 1);
+ for (dsp_precision = -5; tmp; dsp_precision++)
+ tmp >>= 1;
+ if (dsp_precision < 0)
+ dsp_precision = 0;
+ else if (dsp_precision > Maximum_DSP_PRECISION)
+ dsp_precision = Maximum_DSP_PRECISION;
+
+ xshift = 6 - dsp_precision;
+ vshift += xshift;
+
+ /* Move on to dsp_off */
+ dsp_off = ATIDivide(Multiplier * (pATI->DisplayFIFODepth - 1), Divider,
+ vshift, -1) - ATIDivide(1, 1, vshift - xshift, 1);
+
+ /* Next is dsp_on */
+ if ((pATIHW->crtc == ATI_CRTC_VGA) && (dsp_precision < 3))
+ {
+ /*
+ * TODO: I don't yet know why something like this appears necessary.
+ * But I don't have time to explore this right now.
+ */
+ dsp_on = ATIDivide(Multiplier * 5, Divider, vshift + 2, 1);
+ }
+ else
+ {
+ dsp_on = ATIDivide(Multiplier, Divider, vshift, 1);
+ tmp = ATIDivide(RASMultiplier, RASDivider, xshift, 1);
+ if (dsp_on < tmp)
+ dsp_on = tmp;
+ dsp_on += (tmp * 2) +
+ ATIDivide(pATI->XCLKPageFaultDelay, 1, xshift, 1);
+ }
+
+ /* Last but not least: dsp_xclks */
+ dsp_xclks = ATIDivide(Multiplier, Divider, vshift + 5, 1);
+
+ /* Build DSP register contents */
+ pATIHW->dsp_on_off = SetBits(dsp_on, DSP_ON) |
+ SetBits(dsp_off, DSP_OFF);
+ pATIHW->dsp_config = SetBits(dsp_precision, DSP_PRECISION) |
+ SetBits(dsp_xclks, DSP_XCLKS_PER_QW) |
+ SetBits(pATI->DisplayLoopLatency, DSP_LOOP_LATENCY);
+}
+
+/*
+ * ATIDSPSet --
+ *
+ * This function is called to set DSP registers on VT-B and later controllers.
+ */
+void
+ATIDSPSet
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ outl(pATI->CPIO_DSP_ON_OFF, pATIHW->dsp_on_off);
+ outl(pATI->CPIO_DSP_CONFIG, pATIHW->dsp_config);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atidsp.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atidsp.h
new file mode 100644
index 000000000..6c167ea96
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atidsp.h
@@ -0,0 +1,37 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atidsp.h,v 1.4 1999/08/01 07:57:20 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIDSP_H___
+#define ___ATIDSP_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+#include "xf86str.h"
+
+extern Bool ATIDSPPreInit FunctionPrototype((ScrnInfoPtr, ATIPtr));
+extern void ATIDSPSave FunctionPrototype((ATIPtr, ATIHWPtr));
+extern void ATIDSPCalculate FunctionPrototype((ScrnInfoPtr, ATIPtr, ATIHWPtr,
+ DisplayModePtr));
+extern void ATIDSPSet FunctionPrototype((ATIPtr, ATIHWPtr));
+
+#endif /* ___ATIDSP_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.c
new file mode 100644
index 000000000..2b13d7194
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.c
@@ -0,0 +1,104 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.c,v 1.3 1999/07/06 11:38:30 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "ati.h"
+#include "atiident.h"
+#include "ativersion.h"
+
+const char *ATIChipsetNames[] =
+{
+ "ati",
+ "ativga",
+ "ibmvga",
+ "ibm8514",
+ "vgawonder",
+ "mach8",
+ "mach32",
+ "mach64"
+};
+
+static SymTabRec ATIPublicChipsetNames[] =
+{
+ {ATI_CHIPSET_ATI, "ati"},
+ {ATI_CHIPSET_ATIVGA, "ativga"},
+#ifdef __MAYBE_NOT__
+ {ATI_CHIPSET_IBMVGA, "ibmvga"},
+#endif
+#ifdef __NOT_YET__
+ {ATI_CHIPSET_IBM8514, "ibm8514"},
+#endif
+ {-1, NULL}
+};
+
+/*
+ * ATIIdentify --
+ *
+ * Print the driver's list of chipset names.
+ */
+void
+ATIIdentify
+(
+ int flags
+)
+{
+ xf86PrintChipsets(ATI_NAME,
+ "ATI driver (version " ATI_VERSION_NAME ") for chipsets",
+ ATIPublicChipsetNames);
+}
+
+/*
+ * ATIIdentProbe --
+ *
+ * This function determines if the user specified a chipset name acceptable to
+ * the driver. It returns an ATIChipsetType or -1.
+ */
+int
+ATIIdentProbe
+(
+ const char *ChipsetName
+)
+{
+ int Chipset;
+
+ static SymTabRec SpecificNames[] =
+ {
+ {ATI_CHIPSET_VGAWONDER, "vgawonder"},
+#ifdef __NOT_YET__
+ {ATI_CHIPSET_MACH8, "mach8"},
+#endif
+ {ATI_CHIPSET_MACH32, "mach32"},
+ {ATI_CHIPSET_MACH64, "mach64"},
+ {-1, NULL}
+ };
+
+ /* If no Chipset specification, default to "ati" */
+ if (!ChipsetName || !*ChipsetName)
+ return ATI_CHIPSET_ATI;
+
+ Chipset = xf86StringToToken(ATIPublicChipsetNames, ChipsetName);
+ if (Chipset != -1)
+ return Chipset;
+
+ /* Check for some other chipset names */
+ return xf86StringToToken(SpecificNames, ChipsetName);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.h
new file mode 100644
index 000000000..0e37eb0d6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.h
@@ -0,0 +1,47 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiident.h,v 1.3 1999/07/06 11:38:30 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIIDENT_H___
+#define ___ATIIDENT_H___ 1
+
+#include "atiproto.h"
+
+typedef enum
+{
+ ATI_CHIPSET_ATI,
+ ATI_CHIPSET_ATIVGA,
+ ATI_CHIPSET_IBMVGA,
+ ATI_CHIPSET_IBM8514,
+ ATI_CHIPSET_VGAWONDER,
+ ATI_CHIPSET_MACH8,
+ ATI_CHIPSET_MACH32,
+ ATI_CHIPSET_MACH64,
+ ATI_CHIPSET_MAX /* Must be last */
+} ATIChipsetType;
+
+extern const char *ATIChipsetNames[];
+
+extern void ATIIdentify FunctionPrototype((int));
+extern int ATIIdentProbe FunctionPrototype((const char *));
+
+#endif /* ___ATIIDENT_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiio.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiio.c
new file mode 100644
index 000000000..f055f2029
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiio.c
@@ -0,0 +1,119 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiio.c,v 1.3 1999/07/06 11:38:31 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "atichip.h"
+#include "atiio.h"
+
+/*
+ * ATISetVGAIOBase --
+ *
+ * This sets vgaIOBase according to the value of the passed value of the
+ * miscellaneous output register.
+ */
+void
+ATISetVGAIOBase
+(
+ ATIPtr pATI,
+ const CARD8 misc
+)
+{
+ pATI->CPIO_VGABase = (misc & 0x01U) ? ColourIOBase : MonochromeIOBase;
+}
+
+/*
+ * ATIModifyExtReg --
+ *
+ * This function is called to modify certain bits in an ATI extended VGA
+ * register while preserving its other bits. The function will not write the
+ * register if it turns out its value would not change. This helps prevent
+ * server hangs on older adapters.
+ */
+void
+ATIModifyExtReg
+(
+ ATIPtr pATI,
+ const CARD8 Index,
+ int CurrentValue,
+ const CARD8 CurrentMask,
+ CARD8 NewValue
+)
+{
+ /* Possibly retrieve the current value */
+ if (CurrentValue < 0)
+ CurrentValue = ATIGetExtReg(Index);
+
+ /* Compute new value */
+ NewValue &= (CARD8)(~CurrentMask);
+ NewValue |= CurrentValue & CurrentMask;
+
+ /* Check if value will be changed */
+ if (CurrentValue == NewValue)
+ return;
+
+ /*
+ * The following is taken from ATI's VGA Wonder programmer's reference
+ * manual which says that this is needed to "ensure the proper state of the
+ * 8/16 bit ROM toggle". I suspect a timing glitch appeared in the 18800
+ * after its die was cast. 18800-1 and later chips do not exhibit this
+ * problem.
+ */
+ if ((pATI->Chip <= ATI_CHIP_18800) && (Index == 0xB2U) &&
+ ((NewValue ^ 0x40U) & CurrentValue & 0x40U))
+ {
+ CARD8 misc = inb(R_GENMO);
+ CARD8 bb = ATIGetExtReg(0xBBU);
+
+ outb(GENMO, (misc & 0xF3U) | 0x04U | ((bb & 0x10U) >> 1));
+ CurrentValue &= (CARD8)(~0x40U);
+ ATIPutExtReg(0xB2U, CurrentValue);
+ ATIDelay(5);
+ outb(GENMO, misc);
+ ATIDelay(5);
+ if (CurrentValue != NewValue)
+ ATIPutExtReg(0xB2U, NewValue);
+ }
+ else
+ ATIPutExtReg(Index, NewValue);
+}
+
+/*
+ * ATIAccessMach64PLLReg --
+ *
+ * This function sets up the addressing required to access, for read or write,
+ * a 264xT's PLL registers.
+ */
+void
+ATIAccessMach64PLLReg
+(
+ ATIPtr pATI,
+ const CARD8 Index,
+ const Bool Write
+)
+{
+ CARD8 clock_cntl1 = inb(pATI->CPIO_CLOCK_CNTL + 1) &
+ ~GetByte(PLL_WR_EN | PLL_ADDR, 1);
+
+ /* Set PLL register to be read or written */
+ outb(pATI->CPIO_CLOCK_CNTL + 1, clock_cntl1 |
+ GetByte(SetBits(Index, PLL_ADDR) | SetBits(Write, PLL_WR_EN), 1));
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiio.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiio.h
new file mode 100644
index 000000000..9ac13e1c5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiio.h
@@ -0,0 +1,134 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiio.h,v 1.4 1999/08/01 07:57:20 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIIO_H___
+#define ___ATIIO_H___ 1
+
+#ifndef NO_COMPILER_H_EXTRAS
+#define NO_COMPILER_H_EXTRAS
+#endif
+
+#include "atiregs.h"
+#include "atistruct.h"
+#include "compiler.h"
+
+/* I/O decoding definitions */
+typedef enum
+{
+ SPARSE_IO,
+ BLOCK_IO
+} ATIIODecodingType;
+
+#define ATIIOPort(_PortTag) \
+ (((pATI->CPIODecoding == SPARSE_IO) ? \
+ (((_PortTag) & SPARSE_IO_SELECT) | ((_PortTag) & IO_BYTE_SELECT)) : \
+ (((_PortTag) & BLOCK_IO_SELECT) | ((_PortTag) & IO_BYTE_SELECT))) | \
+ pATI->CPIOBase)
+
+extern void ATISetVGAIOBase FunctionPrototype((ATIPtr, const CARD8));
+extern void ATIModifyExtReg FunctionPrototype((ATIPtr, const CARD8, int,
+ const CARD8, CARD8));
+
+/* Odds and ends to ease reading and writting of registers */
+#define GetReg(_Register, _Index) \
+ ( \
+ outb(_Register, _Index), \
+ inb((_Register) + 1) \
+ )
+#define PutReg(_Register, _Index, _Value) \
+ ( \
+ outb(_Register, _Index), \
+ outb((_Register) + 1, _Value) \
+ )
+
+#define ATIGetExtReg(_Index) \
+ GetReg(pATI->CPIO_VGAWonder, _Index)
+#define ATIPutExtReg(_Index, _Value) \
+ PutReg(pATI->CPIO_VGAWonder, _Index, _Value)
+
+extern void ATIAccessMach64PLLReg FunctionPrototype((ATIPtr, const CARD8,
+ const Bool));
+
+#define ATIGetMach64PLLReg(_Index) \
+ ( \
+ ATIAccessMach64PLLReg(pATI, _Index, FALSE), \
+ inb(pATI->CPIO_CLOCK_CNTL + 2) \
+ )
+#define ATIPutMach64PLLReg(_Index, _Value) \
+ ( \
+ ATIAccessMach64PLLReg(pATI, _Index, TRUE), \
+ outb(pATI->CPIO_CLOCK_CNTL + 2, _Value) \
+ )
+
+#define ATIGetLTProLCDReg(_Index) \
+ ( \
+ outb(pATI->CPIO_LCD_INDEX, SetBits((_Index), LCD_REG_INDEX)), \
+ inl(pATI->CPIO_LCD_DATA) \
+ )
+#define ATIPutLTProLCDReg(_Index, _Value) \
+ ( \
+ outb(pATI->CPIO_LCD_INDEX, SetBits((_Index), LCD_REG_INDEX)), \
+ outl(pATI->CPIO_LCD_DATA, (_Value)) \
+ )
+
+#define ATIGetLTProTVReg(_Index) \
+ ( \
+ outb(pATI->CPIO_TV_OUT_INDEX, SetBits((_Index), TV_REG_INDEX)), \
+ inl(pATI->CPIO_TV_OUT_DATA) \
+ )
+#define ATIPutLTProTVReg(_Index, _Value) \
+ ( \
+ outb(pATI->CPIO_TV_OUT_INDEX, SetBits((_Index), TV_REG_INDEX)), \
+ outl(pATI->CPIO_TV_OUT_DATA, (_Value)) \
+ )
+
+/* Wait until "n" queue entries are free */
+#define ibm8514WaitQueue(_n) \
+ { \
+ while (inw(GP_STAT) & (0x0100U >> (_n))); \
+ }
+#define ATIWaitQueue(_n) \
+ { \
+ while (inw(EXT_FIFO_STATUS) & (0x010000U >> (_n))); \
+ }
+
+/* Wait until GP is idle and queue is empty */
+#define WaitIdleEmpty() \
+ { \
+ while (inw(GP_STAT) & (GPBUSY | 1)); \
+ }
+#define ProbeWaitIdleEmpty() \
+ { \
+ int _i; \
+ for (_i = 0; _i < 100000; _i++) \
+ if (!(inw(GP_STAT) & (GPBUSY | 1))) \
+ break; \
+ }
+
+/* Wait until GP has data available */
+#define WaitDataReady() \
+ { \
+ while (!(inw(GP_STAT) & DATARDY)); \
+ }
+
+#endif /* ___ATIIO_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atilock.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atilock.c
new file mode 100644
index 000000000..b8aaea017
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atilock.c
@@ -0,0 +1,316 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atilock.c,v 1.2 1999/08/01 07:57:20 dawes Exp $ */
+/*
+ * Copyright 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "ati.h"
+#include "atiadapter.h"
+#include "atichip.h"
+#include "atiio.h"
+#include "atilock.h"
+
+/*
+ * ATIUnlock --
+ *
+ * This function is entered to unlock registers and disable unwanted
+ * emulations. It saves the current state for later restoration by ATILock().
+ */
+void
+ATIUnlock
+(
+ ATIPtr pATI
+)
+{
+ CARD32 tmp;
+
+ if (pATI->Unlocked)
+ return;
+ pATI->Unlocked = TRUE;
+
+ if (pATI->ChipHasSUBSYS_CNTL)
+ {
+ /* Save register values to be modified */
+ pATI->LockData.clock_sel = inw(CLOCK_SEL);
+ if (pATI->Chip >= ATI_CHIP_68800)
+ {
+ pATI->LockData.misc_options = inw(MISC_OPTIONS);
+ pATI->LockData.mem_bndry = inw(MEM_BNDRY);
+ pATI->LockData.mem_cfg = inw(MEM_CFG);
+ }
+
+ tmp = inw(SUBSYS_STAT) & _8PLANE;
+
+ /* Reset the 8514/A and disable all interrupts */
+ outw(SUBSYS_CNTL, tmp | (GPCTRL_RESET | CHPTEST_NORMAL));
+ outw(SUBSYS_CNTL, tmp | (GPCTRL_ENAB | CHPTEST_NORMAL | RVBLNKFLG |
+ RPICKFLAG | RINVALIDIO | RGPIDLE));
+
+ /* Ensure VGA is enabled */
+ outw(CLOCK_SEL, pATI->LockData.clock_sel &~DISABPASSTHRU);
+ if (pATI->Chip >= ATI_CHIP_68800)
+ {
+ outw(MISC_OPTIONS, pATI->LockData.misc_options &
+ ~(DISABLE_VGA | DISABLE_DAC));
+
+ /* Disable any video memory boundary */
+ outw(MEM_BNDRY, pATI->LockData.mem_bndry &
+ ~(MEM_PAGE_BNDRY | MEM_BNDRY_ENA));
+
+ /* Disable direct video memory aperture */
+ outw(MEM_CFG, pATI->LockData.mem_cfg &
+ ~(MEM_APERT_SEL | MEM_APERT_PAGE | MEM_APERT_LOC));
+ }
+
+ /* Wait for all activity to die down */
+ ProbeWaitIdleEmpty();
+ }
+ else if (pATI->Chip >= ATI_CHIP_88800GXC)
+ {
+ /* Save register values to be modified */
+ pATI->LockData.config_cntl = inl(pATI->CPIO_CONFIG_CNTL);
+ pATI->LockData.dac_cntl = inl(pATI->CPIO_DAC_CNTL);
+
+ /* Reset everything */
+ pATI->LockData.bus_cntl =
+ (inl(pATI->CPIO_BUS_CNTL) & ~BUS_HOST_ERR_INT_EN) |
+ BUS_HOST_ERR_INT;
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ pATI->LockData.bus_cntl =
+ (pATI->LockData.bus_cntl & ~BUS_FIFO_ERR_INT_EN) |
+ BUS_FIFO_ERR_INT;
+ outl(pATI->CPIO_BUS_CNTL, (pATI->LockData.bus_cntl & ~BUS_ROM_DIS) |
+ SetBits(15, BUS_FIFO_WS));
+ pATI->LockData.crtc_int_cntl = inl(pATI->CPIO_CRTC_INT_CNTL);
+ outl(pATI->CPIO_CRTC_INT_CNTL,
+ (pATI->LockData.crtc_int_cntl & ~CRTC_INT_ENS) | CRTC_INT_ACKS);
+ pATI->LockData.gen_test_cntl = inl(pATI->CPIO_GEN_TEST_CNTL) &
+ (GEN_OVR_OUTPUT_EN | GEN_OVR_POLARITY | GEN_CUR_EN |
+ GEN_BLOCK_WR_EN);
+ tmp = pATI->LockData.gen_test_cntl & ~GEN_CUR_EN;
+ outl(pATI->CPIO_GEN_TEST_CNTL, tmp | GEN_GUI_EN);
+ outl(pATI->CPIO_GEN_TEST_CNTL, tmp);
+ outl(pATI->CPIO_GEN_TEST_CNTL, tmp | GEN_GUI_EN);
+ pATI->LockData.crtc_gen_cntl = inl(pATI->CPIO_CRTC_GEN_CNTL) &
+ ~(CRTC_EN | CRTC_LOCK_REGS);
+ tmp = pATI->LockData.crtc_gen_cntl & ~CRTC_EXT_DISP_EN;
+ outl(pATI->CPIO_CRTC_GEN_CNTL, tmp | CRTC_EN);
+ outl(pATI->CPIO_CRTC_GEN_CNTL, tmp);
+ outl(pATI->CPIO_CRTC_GEN_CNTL, tmp | CRTC_EN);
+
+ /* Ensure VGA aperture is enabled */
+ outl(pATI->CPIO_DAC_CNTL, pATI->LockData.dac_cntl | DAC_VGA_ADR_EN);
+ outl(pATI->CPIO_CONFIG_CNTL,
+ pATI->LockData.config_cntl & ~CFG_VGA_DIS);
+ if (pATI->Chip < ATI_CHIP_264CT)
+ {
+ pATI->LockData.mem_info = inl(pATI->CPIO_MEM_INFO);
+ outl(pATI->CPIO_MEM_INFO, pATI->LockData.mem_info &
+ ~(CTL_MEM_BNDRY | CTL_MEM_BNDRY_EN));
+ }
+ }
+
+ if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
+ {
+ if (pATI->CPIO_VGAWonder)
+ {
+ /*
+ * Ensure all registers are read/write and disable all non-VGA
+ * emulations.
+ */
+ pATI->LockData.b1 = ATIGetExtReg(0xB1U);
+ ATIModifyExtReg(pATI, 0xB1U, pATI->LockData.b1, 0xFCU, 0x00U);
+ pATI->LockData.b4 = ATIGetExtReg(0xB4U);
+ ATIModifyExtReg(pATI, 0xB4U, pATI->LockData.b4, 0x00U, 0x00U);
+ pATI->LockData.b5 = ATIGetExtReg(0xB5U);
+ ATIModifyExtReg(pATI, 0xB5U, pATI->LockData.b5, 0xBFU, 0x00U);
+ pATI->LockData.b6 = ATIGetExtReg(0xB6U);
+ ATIModifyExtReg(pATI, 0xB6U, pATI->LockData.b6, 0xDDU, 0x00U);
+ pATI->LockData.b8 = ATIGetExtReg(0xB8U);
+ ATIModifyExtReg(pATI, 0xB8U, pATI->LockData.b8, 0xC0U, 0x00U);
+ pATI->LockData.b9 = ATIGetExtReg(0xB9U);
+ ATIModifyExtReg(pATI, 0xB9U, pATI->LockData.b9, 0x7FU, 0x00U);
+ if (pATI->Chip > ATI_CHIP_18800)
+ {
+ pATI->LockData.be = ATIGetExtReg(0xBEU);
+ ATIModifyExtReg(pATI, 0xBEU, pATI->LockData.be, 0xFAU, 0x01U);
+ if (pATI->Chip >= ATI_CHIP_28800_2)
+ {
+ pATI->LockData.a6 = ATIGetExtReg(0xA6U);
+ ATIModifyExtReg(pATI, 0xA6U, pATI->LockData.a6,
+ 0x7FU, 0x00U);
+ pATI->LockData.ab = ATIGetExtReg(0xABU);
+ ATIModifyExtReg(pATI, 0xABU, pATI->LockData.ab,
+ 0xE7U, 0x00U);
+ }
+ }
+ }
+
+ ATISetVGAIOBase(pATI, inb(R_GENMO));
+
+ /*
+ * There's a bizarre interaction here. If bit 0x80 of CRTC[17] is on,
+ * then CRTC[3] is read-only. If bit 0x80 of CRTC[3] is off, then
+ * CRTC[17] is write-only (or a read attempt actually returns bits from
+ * C/EGA's light pen position). This means that if both conditions are
+ * met, CRTC[17]'s value on server entry cannot be retrieved.
+ */
+
+ pATI->LockData.crt03 = tmp = GetReg(CRTX(pATI->CPIO_VGABase), 0x03U);
+ if ((tmp & 0x80U) ||
+ ((outb(CRTD(pATI->CPIO_VGABase), tmp | 0x80U),
+ tmp = inb(CRTD(pATI->CPIO_VGABase))) & 0x80U))
+ {
+ /* CRTC[16-17] should be readable */
+ pATI->LockData.crt11 = tmp =
+ GetReg(CRTX(pATI->CPIO_VGABase), 0x11U);
+ if (tmp & 0x80U) /* Unprotect CRTC[0-7] */
+ outb(CRTD(pATI->CPIO_VGABase), tmp & 0x7FU);
+ }
+ else
+ {
+ /*
+ * Could not make CRTC[17] readable, so unprotect CRTC[0-7]
+ * replacing VSyncEnd with zero. This zero will be replaced after
+ * acquiring the needed access.
+ */
+ unsigned int VSyncEnd, VBlankStart, VBlankEnd;
+ CARD8 crt07, crt09;
+
+ PutReg(CRTX(pATI->CPIO_VGABase), 0x11U, 0x20U);
+ /* Make CRTC[16-17] readable */
+ PutReg(CRTX(pATI->CPIO_VGABase), 0x03U, tmp | 0x80U);
+ /* Make vertical synch pulse as wide as possible */
+ crt07 = GetReg(CRTX(pATI->CPIO_VGABase), 0x07U);
+ crt09 = GetReg(CRTX(pATI->CPIO_VGABase), 0x09U);
+ VBlankStart = (((crt09 & 0x20U) << 4) | ((crt07 & 0x08U) << 5) |
+ GetReg(CRTX(pATI->CPIO_VGABase), 0x15U)) + 1;
+ VBlankEnd = (VBlankStart & 0x0300U) |
+ GetReg(CRTX(pATI->CPIO_VGABase), 0x16U);
+ if (VBlankEnd <= VBlankStart)
+ VBlankEnd += 0x0100U;
+ VSyncEnd = (((crt07 & 0x80U) << 2) | ((crt07 & 0x04U) << 6) |
+ GetReg(CRTX(pATI->CPIO_VGABase), 0x10U)) + 0x0FU;
+ if (VSyncEnd >= VBlankEnd)
+ VSyncEnd = VBlankEnd - 1;
+ pATI->LockData.crt11 = (VSyncEnd & 0x0FU) | 0x20U;
+ PutReg(CRTX(pATI->CPIO_VGABase), 0x11U, pATI->LockData.crt11);
+ pATI->LockData.crt11 |= 0x80U;
+ }
+ }
+}
+
+/*
+ * ATILock --
+ *
+ * This function restores the state saved by ATIUnlock() above.
+ */
+void
+ATILock
+(
+ ATIPtr pATI
+)
+{
+ CARD32 tmp;
+
+ if (!pATI->Unlocked)
+ return;
+ pATI->Unlocked = FALSE;
+
+ if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
+ {
+ ATISetVGAIOBase(pATI, inb(R_GENMO));
+
+ /* Restore VGA locks */
+ PutReg(CRTX(pATI->CPIO_VGABase), 0x03U, pATI->LockData.crt03);
+ PutReg(CRTX(pATI->CPIO_VGABase), 0x11U, pATI->LockData.crt11);
+
+ if (pATI->CPIO_VGAWonder)
+ {
+ /*
+ * Restore emulation and protection bits in ATI extended VGA
+ * registers.
+ */
+ ATIModifyExtReg(pATI, 0xB1U, -1, 0xFCU, pATI->LockData.b1);
+ ATIModifyExtReg(pATI, 0xB4U, -1, 0x00U, pATI->LockData.b4);
+ ATIModifyExtReg(pATI, 0xB5U, -1, 0xBFU, pATI->LockData.b5);
+ ATIModifyExtReg(pATI, 0xB6U, -1, 0xDDU, pATI->LockData.b6);
+ ATIModifyExtReg(pATI, 0xB8U, -1, 0xC0U, pATI->LockData.b8 & 0x03U);
+ ATIModifyExtReg(pATI, 0xB9U, -1, 0x7FU, pATI->LockData.b9);
+ if (pATI->Chip > ATI_CHIP_18800)
+ {
+ ATIModifyExtReg(pATI, 0xBEU, -1, 0xFAU, pATI->LockData.be);
+ if (pATI->Chip >= ATI_CHIP_28800_2)
+ {
+ ATIModifyExtReg(pATI, 0xA6U, -1, 0x7FU, pATI->LockData.a6);
+ ATIModifyExtReg(pATI, 0xABU, -1, 0xE7U, pATI->LockData.ab);
+ }
+ }
+ ATIModifyExtReg(pATI, 0xB8U, -1, 0xC0U, pATI->LockData.b8);
+ }
+ }
+
+ if (pATI->ChipHasSUBSYS_CNTL)
+ {
+ tmp = inw(SUBSYS_STAT) & _8PLANE;
+
+ /* Reset the 8514/A and disable all interrupts */
+ outw(SUBSYS_CNTL, tmp | (GPCTRL_RESET | CHPTEST_NORMAL));
+ outw(SUBSYS_CNTL, tmp | (GPCTRL_ENAB | CHPTEST_NORMAL | RVBLNKFLG |
+ RPICKFLAG | RINVALIDIO | RGPIDLE));
+
+ /* Restore modified accelerator registers */
+ outw(CLOCK_SEL, pATI->LockData.clock_sel);
+ if (pATI->Chip >= ATI_CHIP_68800)
+ {
+ outw(MISC_OPTIONS, pATI->LockData.misc_options);
+ outw(MEM_BNDRY, pATI->LockData.mem_bndry);
+ outw(MEM_CFG, pATI->LockData.mem_cfg);
+ }
+
+ /* Wait for all activity to die down */
+ ProbeWaitIdleEmpty();
+ }
+ else if (pATI->Chip >= ATI_CHIP_88800GXC)
+ {
+ /* Reset everything */
+ outl(pATI->CPIO_BUS_CNTL, pATI->LockData.bus_cntl);
+
+ outl(pATI->CPIO_CRTC_INT_CNTL, pATI->LockData.crtc_int_cntl);
+
+ outl(pATI->CPIO_GEN_TEST_CNTL,
+ pATI->LockData.gen_test_cntl | GEN_GUI_EN);
+ outl(pATI->CPIO_GEN_TEST_CNTL, pATI->LockData.gen_test_cntl);
+ outl(pATI->CPIO_GEN_TEST_CNTL,
+ pATI->LockData.gen_test_cntl | GEN_GUI_EN);
+
+ outl(pATI->CPIO_CRTC_GEN_CNTL,
+ pATI->LockData.crtc_gen_cntl | CRTC_EN);
+ outl(pATI->CPIO_CRTC_GEN_CNTL, pATI->LockData.crtc_gen_cntl);
+ outl(pATI->CPIO_CRTC_GEN_CNTL,
+ pATI->LockData.crtc_gen_cntl | CRTC_EN);
+
+ /* Restore registers */
+ outl(pATI->CPIO_CONFIG_CNTL, pATI->LockData.config_cntl);
+ outl(pATI->CPIO_DAC_CNTL, pATI->LockData.dac_cntl);
+ if (pATI->Chip < ATI_CHIP_264CT)
+ outl(pATI->CPIO_MEM_INFO, pATI->LockData.mem_info);
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atilock.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atilock.h
new file mode 100644
index 000000000..e5ce88e0f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atilock.h
@@ -0,0 +1,33 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atilock.h,v 1.1 1999/07/06 11:38:31 dawes Exp $ */
+/*
+ * Copyright 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATILOCK_H___
+#define ___ATILOCK_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+
+extern void ATIUnlock FunctionPrototype((ATIPtr));
+extern void ATILock FunctionPrototype((ATIPtr));
+
+#endif /* ___ATILOCK_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.c
new file mode 100644
index 000000000..4ae1e55e3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.c
@@ -0,0 +1,356 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.c,v 1.5 1999/08/01 07:57:21 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "atibus.h"
+#include "atichip.h"
+#include "atiio.h"
+#include "atimach64.h"
+
+/*
+ * ATIMach64PreInit --
+ *
+ * This function fills in the Mach64 portion of an ATIHWRec that is common to
+ * all video modes generated by the driver.
+ */
+void
+ATIMach64PreInit
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ if (pScreenInfo->depth <= 4)
+ pATIHW->crtc_off_pitch =
+ SetBits(pScreenInfo->displayWidth >> 4, CRTC_PITCH);
+ else
+ pATIHW->crtc_off_pitch =
+ SetBits(pScreenInfo->displayWidth >> 3, CRTC_PITCH);
+
+ pATIHW->bus_cntl = (inl(pATI->CPIO_BUS_CNTL) & ~BUS_HOST_ERR_INT_EN) |
+ BUS_HOST_ERR_INT;
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ {
+ pATIHW->bus_cntl &= ~(BUS_FIFO_ERR_INT_EN | BUS_ROM_DIS);
+ pATIHW->bus_cntl |= SetBits(15, BUS_FIFO_WS) | BUS_FIFO_ERR_INT;
+ }
+ else
+ pATIHW->bus_cntl |= BUS_APER_REG_DIS;
+
+ pATIHW->mem_vga_wp_sel =
+ /* SetBits(0, MEM_VGA_WPS0) | */
+ SetBits(pATIHW->nPlane, MEM_VGA_WPS1);
+ pATIHW->mem_vga_rp_sel =
+ /* SetBits(0, MEM_VGA_RPS0) | */
+ SetBits(pATIHW->nPlane, MEM_VGA_RPS1);
+
+ pATIHW->dac_cntl = inl(pATI->CPIO_DAC_CNTL);
+ if ((pScreenInfo->depth > 8) || (pScreenInfo->rgbBits == 8))
+ pATIHW->dac_cntl |= DAC_8BIT_EN;
+ else
+ pATIHW->dac_cntl &= ~DAC_8BIT_EN;
+
+ pATIHW->config_cntl = inl(pATI->CPIO_CONFIG_CNTL);
+ if (pATI->UseSmallApertures)
+ pATIHW->config_cntl |= CFG_MEM_VGA_AP_EN;
+ else
+ pATIHW->config_cntl &= ~CFG_MEM_VGA_AP_EN;
+ if (pATI->LinearBase &&
+ (pATI->BusType != ATI_BUS_PCI) && (pATI->BusType != ATI_BUS_AGP))
+ {
+ /* Replace linear aperture size and address */
+ pATIHW->config_cntl &= ~(CFG_MEM_AP_LOC | CFG_MEM_AP_SIZE);
+ pATIHW->config_cntl |= SetBits(pATI->LinearBase >> 22, CFG_MEM_AP_LOC);
+ if ((pATI->Chip < ATI_CHIP_264CT) && (pATI->VideoRAM < 4096))
+ pATIHW->config_cntl |= SetBits(1, CFG_MEM_AP_SIZE);
+ else
+ pATIHW->config_cntl |= SetBits(2, CFG_MEM_AP_SIZE);
+ }
+}
+
+/*
+ * ATIMach64Save --
+ *
+ * This function is called to save the Mach64 portion of the current video
+ * state.
+ */
+void
+ATIMach64Save
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ pATIHW->crtc_h_total_disp = inl(pATI->CPIO_CRTC_H_TOTAL_DISP);
+ pATIHW->crtc_h_sync_strt_wid = inl(pATI->CPIO_CRTC_H_SYNC_STRT_WID);
+ pATIHW->crtc_v_total_disp = inl(pATI->CPIO_CRTC_V_TOTAL_DISP);
+ pATIHW->crtc_v_sync_strt_wid = inl(pATI->CPIO_CRTC_V_SYNC_STRT_WID);
+
+ pATIHW->crtc_off_pitch = inl(pATI->CPIO_CRTC_OFF_PITCH);
+
+ pATIHW->crtc_gen_cntl = inl(pATI->CPIO_CRTC_GEN_CNTL);
+
+ pATIHW->ovr_clr = inl(pATI->CPIO_OVR_CLR);
+ pATIHW->ovr_wid_left_right = inl(pATI->CPIO_OVR_WID_LEFT_RIGHT);
+ pATIHW->ovr_wid_top_bottom = inl(pATI->CPIO_OVR_WID_TOP_BOTTOM);
+
+ pATIHW->clock_cntl = inl(pATI->CPIO_CLOCK_CNTL);
+
+ pATIHW->bus_cntl = inl(pATI->CPIO_BUS_CNTL);
+
+ pATIHW->mem_vga_wp_sel = inl(pATI->CPIO_MEM_VGA_WP_SEL);
+ pATIHW->mem_vga_rp_sel = inl(pATI->CPIO_MEM_VGA_RP_SEL);
+
+ pATIHW->dac_cntl = inl(pATI->CPIO_DAC_CNTL);
+
+ pATIHW->config_cntl = inl(pATI->CPIO_CONFIG_CNTL);
+}
+
+/*
+ * ATIMach64Calculate --
+ *
+ * This function is called to fill in the Mach64 portion of an ATIHWRec.
+ */
+void
+ATIMach64Calculate
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW,
+ DisplayModePtr pMode
+)
+{
+ int VDisplay;
+
+ /* If not already done adjust horizontal timings */
+ if (!pMode->CrtcHAdjusted)
+ {
+ pMode->CrtcHAdjusted = TRUE;
+ /* XXX Deal with Blank Start/End and overscan later */
+ pMode->CrtcHDisplay = (pMode->HDisplay >> 3) - 1;
+ pMode->CrtcHSyncStart = (pMode->HSyncStart >> 3) - 1;
+ pMode->CrtcHSyncEnd = (pMode->HSyncEnd >> 3) - 1;
+ pMode->CrtcHTotal = (pMode->HTotal >> 3) - 1;
+
+ /* Make adjustments if sync pulse width is out-of-bounds */
+ if ((pMode->CrtcHSyncEnd - pMode->CrtcHSyncStart) >
+ (int)MaxBits(CRTC_H_SYNC_WID))
+ pMode->CrtcHSyncEnd =
+ pMode->CrtcHSyncStart + MaxBits(CRTC_H_SYNC_WID);
+ else if (pMode->CrtcHSyncStart == pMode->CrtcHSyncEnd)
+ if (pMode->CrtcHDisplay < pMode->CrtcHSyncStart)
+ pMode->CrtcHSyncStart--;
+ else if (pMode->CrtcHSyncEnd < pMode->CrtcHTotal)
+ pMode->CrtcHSyncEnd++;
+ }
+
+ /*
+ * Always re-do vertical adjustments.
+ */
+ pMode->CrtcVDisplay = pMode->VDisplay;
+ pMode->CrtcVSyncStart = pMode->VSyncStart;
+ pMode->CrtcVSyncEnd = pMode->VSyncEnd;
+ pMode->CrtcVTotal = pMode->VTotal;
+
+ if ((pMode->Flags & V_DBLSCAN) && (pATI->Chip >= ATI_CHIP_264CT))
+ {
+ pMode->CrtcVDisplay <<= 1;
+ pMode->CrtcVSyncStart <<= 1;
+ pMode->CrtcVSyncEnd <<= 1;
+ pMode->CrtcVTotal <<= 1;
+ }
+ pMode->CrtcVDisplay--;
+ pMode->CrtcVSyncStart--;
+ pMode->CrtcVSyncEnd--;
+ pMode->CrtcVTotal--;
+ /* Make sure sync pulse is not too wide */
+ if ((pMode->CrtcVSyncEnd - pMode->CrtcVSyncStart) >
+ (int)MaxBits(CRTC_V_SYNC_WID))
+ pMode->CrtcVSyncEnd = pMode->CrtcVSyncStart + MaxBits(CRTC_V_SYNC_WID);
+ pMode->CrtcVAdjusted = TRUE; /* Redundant */
+
+ /*
+ * Might as well default to the same as VGA with respect to sync
+ * polarities.
+ */
+ if ((!(pMode->Flags & (V_PHSYNC | V_NHSYNC))) ||
+ (!(pMode->Flags & (V_PVSYNC | V_NVSYNC))))
+ {
+ pMode->Flags &= ~(V_PHSYNC | V_NHSYNC | V_PVSYNC | V_NVSYNC);
+
+ if (pATI->LCDPanelID >= 0)
+ VDisplay = pATI->LCDVertical;
+ else
+ VDisplay = pMode->CrtcVDisplay;
+
+ if (VDisplay < 400)
+ pMode->Flags |= V_PHSYNC | V_NVSYNC;
+ else if (VDisplay < 480)
+ pMode->Flags |= V_NHSYNC | V_PVSYNC;
+ else if (VDisplay < 768)
+ pMode->Flags |= V_NHSYNC | V_NVSYNC;
+ else
+ pMode->Flags |= V_PHSYNC | V_PVSYNC;
+ }
+
+ /* Build register contents */
+ pATIHW->crtc_h_total_disp =
+ SetBits(pMode->CrtcHTotal, CRTC_H_TOTAL) |
+ SetBits(pMode->CrtcHDisplay, CRTC_H_DISP);
+ pATIHW->crtc_h_sync_strt_wid =
+ SetBits(pMode->CrtcHSyncStart, CRTC_H_SYNC_STRT) |
+ SetBits(pMode->CrtcHSkew, CRTC_H_SYNC_DLY) | /* ? */
+ SetBits(GetBits(pMode->CrtcHSyncStart, 0x0100U),
+ CRTC_H_SYNC_STRT_HI) |
+ SetBits(pMode->CrtcHSyncEnd - pMode->CrtcHSyncStart,
+ CRTC_H_SYNC_WID);
+ if (pMode->Flags & V_NHSYNC)
+ pATIHW->crtc_h_sync_strt_wid |= CRTC_H_SYNC_POL;
+
+ pATIHW->crtc_v_total_disp =
+ SetBits(pMode->CrtcVTotal, CRTC_V_TOTAL) |
+ SetBits(pMode->CrtcVDisplay, CRTC_V_DISP);
+ pATIHW->crtc_v_sync_strt_wid =
+ SetBits(pMode->CrtcVSyncStart, CRTC_V_SYNC_STRT) |
+ SetBits(pMode->CrtcVSyncEnd - pMode->CrtcVSyncStart,
+ CRTC_V_SYNC_WID);
+ if (pMode->Flags & V_NVSYNC)
+ pATIHW->crtc_v_sync_strt_wid |= CRTC_V_SYNC_POL;
+
+ pATIHW->crtc_gen_cntl = inl(pATI->CPIO_CRTC_GEN_CNTL) &
+ ~(CRTC_DBL_SCAN_EN | CRTC_INTERLACE_EN |
+ CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_CSYNC_EN |
+ CRTC_PIX_BY_2_EN | CRTC_DISPLAY_DIS | CRTC_VGA_XOVERSCAN |
+ CRTC_PIX_WIDTH | CRTC_BYTE_PIX_ORDER | CRTC_FIFO_LWM |
+ CRTC_VGA_128KAP_PAGING | CRTC_VFC_SYNC_TRISTATE |
+ CRTC_LOCK_REGS | /* Already off, but ... */
+ CRTC_SYNC_TRISTATE | CRTC_DISP_REQ_EN |
+ CRTC_VGA_TEXT_132 | CRTC_CUR_B_TEST);
+ pATIHW->crtc_gen_cntl |=
+ CRTC_EXT_DISP_EN | CRTC_EN | CRTC_VGA_LINEAR | CRTC_CNT_EN;
+ switch (pScreenInfo->depth)
+ {
+ case 1:
+ pATIHW->crtc_gen_cntl |= CRTC_PIX_WIDTH_1BPP;
+ break;
+ case 4:
+ pATIHW->crtc_gen_cntl |= CRTC_PIX_WIDTH_4BPP;
+ break;
+ case 8:
+ pATIHW->crtc_gen_cntl |= CRTC_PIX_WIDTH_8BPP;
+ break;
+ case 15:
+ pATIHW->crtc_gen_cntl |= CRTC_PIX_WIDTH_15BPP;
+ break;
+ case 16:
+ pATIHW->crtc_gen_cntl |= CRTC_PIX_WIDTH_16BPP;
+ break;
+ case 24:
+ if (pScreenInfo->bitsPerPixel == 24)
+ pATIHW->crtc_gen_cntl |= CRTC_PIX_WIDTH_24BPP;
+ else if (pScreenInfo->bitsPerPixel == 32)
+ pATIHW->crtc_gen_cntl |= CRTC_PIX_WIDTH_32BPP;
+ break;
+ case 32:
+ pATIHW->crtc_gen_cntl |= CRTC_PIX_WIDTH_32BPP;
+ break;
+ default:
+ break;
+ }
+ if (pMode->Flags & V_DBLSCAN)
+ pATIHW->crtc_gen_cntl |= CRTC_DBL_SCAN_EN;
+ if (pMode->Flags & V_INTERLACE)
+ pATIHW->crtc_gen_cntl |= CRTC_INTERLACE_EN;
+ if (pATI->OptionCSync || (pMode->Flags & (V_CSYNC | V_PCSYNC)))
+ pATIHW->crtc_gen_cntl |= CRTC_CSYNC_EN;
+ /* For now, set display FIFO low water mark as high as possible */
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ pATIHW->crtc_gen_cntl |= CRTC_FIFO_LWM;
+}
+
+/*
+ * ATIMach64Set --
+ *
+ * This function is called to load a Mach64's accelerator CRTC.
+ */
+void
+ATIMach64Set
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ /* First, turn off the display */
+ outl(pATI->CPIO_CRTC_GEN_CNTL, pATIHW->crtc_gen_cntl & ~CRTC_EN);
+
+ if ((pATIHW->FeedbackDivider > 0) &&
+ (pATI->ProgrammableClock != ATI_CLOCK_NONE))
+ ATIClockSet(pATI, pATIHW); /* Programme clock */
+
+ /* Load Mach64 CRTC registers */
+ outl(pATI->CPIO_CRTC_H_TOTAL_DISP, pATIHW->crtc_h_total_disp);
+ outl(pATI->CPIO_CRTC_H_SYNC_STRT_WID, pATIHW->crtc_h_sync_strt_wid);
+ outl(pATI->CPIO_CRTC_V_TOTAL_DISP, pATIHW->crtc_v_total_disp);
+ outl(pATI->CPIO_CRTC_V_SYNC_STRT_WID, pATIHW->crtc_v_sync_strt_wid);
+
+ outl(pATI->CPIO_CRTC_OFF_PITCH, pATIHW->crtc_off_pitch);
+
+ /* Set pixel clock */
+ outl(pATI->CPIO_CLOCK_CNTL, pATIHW->clock_cntl | CLOCK_STROBE);
+
+ /* Load overscan registers */
+ outl(pATI->CPIO_OVR_CLR, pATIHW->ovr_clr);
+ outl(pATI->CPIO_OVR_WID_LEFT_RIGHT, pATIHW->ovr_wid_left_right);
+ outl(pATI->CPIO_OVR_WID_TOP_BOTTOM, pATIHW->ovr_wid_top_bottom);
+
+ /* Finalize CRTC setup and turn on the screen */
+ outl(pATI->CPIO_CRTC_GEN_CNTL, pATIHW->crtc_gen_cntl);
+
+ /* Aperture setup */
+ outl(pATI->CPIO_BUS_CNTL, pATIHW->bus_cntl);
+
+ outl(pATI->CPIO_MEM_VGA_WP_SEL, pATIHW->mem_vga_wp_sel);
+ outl(pATI->CPIO_MEM_VGA_RP_SEL, pATIHW->mem_vga_rp_sel);
+
+ outl(pATI->CPIO_DAC_CNTL, pATIHW->dac_cntl);
+
+ outl(pATI->CPIO_CONFIG_CNTL, pATIHW->config_cntl);
+}
+
+/*
+ * ATIMach64SaveScreen --
+ *
+ * This function blanks or unblanks a Mach64 screen.
+ */
+void
+ATIMach64SaveScreen
+(
+ ATIPtr pATI,
+ int On
+)
+{
+ CARD32 crtc_gen_cntl = inl(pATI->CPIO_CRTC_GEN_CNTL);
+
+ outl(pATI->CPIO_CRTC_GEN_CNTL,
+ On ? (crtc_gen_cntl | CRTC_EN) : (crtc_gen_cntl & ~CRTC_EN));
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.h
new file mode 100644
index 000000000..b0a5cecd3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.h
@@ -0,0 +1,40 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64.h,v 1.3 1999/07/06 11:38:32 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIMACH64_H___
+#define ___ATIMACH64_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+#include "xf86str.h"
+
+extern void ATIMach64PreInit FunctionPrototype((ScrnInfoPtr, ATIPtr,
+ ATIHWPtr));
+extern void ATIMach64Save FunctionPrototype((ATIPtr, ATIHWPtr));
+extern void ATIMach64Calculate FunctionPrototype((ScrnInfoPtr, ATIPtr,
+ ATIHWPtr, DisplayModePtr));
+extern void ATIMach64Set FunctionPrototype((ATIPtr, ATIHWPtr));
+
+extern void ATIMach64SaveScreen FunctionPrototype((ATIPtr, int));
+
+#endif /* ___ATIMACH64_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.c
new file mode 100644
index 000000000..8bab150dd
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.c
@@ -0,0 +1,154 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.c,v 1.3 1999/07/06 11:38:32 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef XFree86LOADER
+
+#include "ati.h"
+#include "atimodule.h"
+#include "ativersion.h"
+
+/* Module loader interface */
+
+static XF86ModuleVersionInfo ATIVersionRec =
+{
+ ATI_DRIVER_NAME,
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ ATI_VERSION_MAJOR, ATI_VERSION_MINOR, ATI_VERSION_PATCH,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0, 0, 0, 0}
+};
+
+/*
+ * ATISetup --
+ *
+ * This function is called every time the module is loaded.
+ */
+static pointer
+ATISetup
+(
+ pointer Module,
+ pointer Options,
+ int *ErrorMajor,
+ int *ErrorMinor
+)
+{
+ static Bool Inited = FALSE;
+
+ if (!Inited)
+ {
+ Inited = TRUE;
+ xf86AddDriver(&ATI, Module, 0);
+
+ /*
+ * Tell loader about symbols from other modules that this module might
+ * refer to.
+ */
+ LoaderRefSymbols(
+ "xf1bppScreenInit",
+ "xf4bppScreenInit",
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb24ScreenInit",
+ "cfb32ScreenInit",
+ NULL);
+
+ return (pointer)TRUE;
+ }
+
+ if (ErrorMajor)
+ *ErrorMajor = LDR_ONCEONLY;
+ return NULL;
+}
+
+/* The following record must be called atiModuleData */
+XF86ModuleData atiModuleData =
+{
+ &ATIVersionRec,
+ ATISetup,
+ NULL
+};
+
+/*
+ * ATILoadModule --
+ *
+ * Load a specific module and register its main entry with the loader.
+ */
+static Bool
+ATILoadModule
+(
+ ScrnInfoPtr pScreenInfo,
+ const char *Module,
+ const char *Symbol
+)
+{
+ if (!xf86LoadSubModule(pScreenInfo, Module))
+ return FALSE;
+
+ xf86LoaderReqSymbols(Symbol, NULL);
+
+ return TRUE;
+}
+
+/*
+ * ATILoadModules --
+ *
+ * This function loads other modules required for a screen.
+ */
+Bool
+ATILoadModules
+(
+ ScrnInfoPtr pScreenInfo
+)
+{
+ /* Load depth-specific entry points */
+ switch (pScreenInfo->bitsPerPixel)
+ {
+ case 1:
+ return ATILoadModule(pScreenInfo, "xf1bpp", "xf1bppScreenInit");
+
+ case 4:
+ return ATILoadModule(pScreenInfo, "xf4bpp", "xf4bppScreenInit");
+
+ case 8:
+ return ATILoadModule(pScreenInfo, "cfb", "cfbScreenInit");
+
+ case 16:
+ return ATILoadModule(pScreenInfo, "cfb16", "cfb16ScreenInit");
+
+ case 24:
+ return ATILoadModule(pScreenInfo, "cfb24", "cfb24ScreenInit");
+
+ case 32:
+ return ATILoadModule(pScreenInfo, "cfb32", "cfb32ScreenInit");
+
+ default:
+ return FALSE;
+ }
+}
+
+#endif /* XFree86LOADER */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h
new file mode 100644
index 000000000..0aea97208
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h
@@ -0,0 +1,32 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimodule.h,v 1.1 1999/07/06 11:38:32 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ */
+
+#if defined(XFree86LOADER) && !defined(___ATI_MODULE_H___)
+#define ___ATI_MODULE_H___ 1
+
+#include "atiproto.h"
+#include "xf86str.h"
+
+extern Bool ATILoadModules FunctionPrototype((ScrnInfoPtr));
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atimono.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimono.h
new file mode 100644
index 000000000..7271386ba
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atimono.h
@@ -0,0 +1,43 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimono.h,v 1.3 1999/07/06 11:38:33 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIMONO_H___
+#define ___ATIMONO_H___ 1
+
+#ifndef BIT_PLANE
+# define BIT_PLANE 3
+#endif
+
+#ifndef MONO_BLACK
+# define MONO_BLACK 0x00U
+#endif
+
+#ifndef MONO_WHITE
+# define MONO_WHITE 0x3FU
+#endif
+
+#ifndef MONO_OVERSCAN
+# define MONO_OVERSCAN 0x01U
+#endif
+
+#endif /* ___ATIMONO_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.c
new file mode 100644
index 000000000..aabd758af
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.c
@@ -0,0 +1,89 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.c,v 1.1 1999/07/06 11:38:33 dawes Exp $ */
+/*
+ * Copyright 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "ati.h"
+#include "atioption.h"
+#include "atistruct.h"
+
+/*
+ * Recognized XF86Config options.
+ */
+typedef enum
+{
+ ATI_OPTION_CSYNC,
+ ATI_OPTION_DEVEL, /* Intentionally undocumented */
+ ATI_OPTION_LINEAR,
+ ATI_OPTION_PROBE_CLOCKS,
+ ATI_OPTION_MAX /* Must be last */
+} ATIOptionType;
+
+/*
+ * ATIProcessOptions --
+ *
+ * This function extracts options from what was parsed out of the XF86Config
+ * file.
+ */
+void
+ATIProcessOptions
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI
+)
+{
+ OptionInfoRec Option[] =
+ {
+ {ATI_OPTION_CSYNC, "composite_sync", OPTV_BOOLEAN, {0, }, FALSE},
+ {ATI_OPTION_DEVEL, "tsi", OPTV_BOOLEAN, {0, }, FALSE},
+ {ATI_OPTION_LINEAR, "linear", OPTV_BOOLEAN, {0, }, FALSE},
+ {ATI_OPTION_PROBE_CLOCKS, "probe_clocks", OPTV_BOOLEAN, {0, }, FALSE},
+ {-1, NULL, OPTV_NONE , {0, }, FALSE}
+ };
+
+# define CSync Option[ATI_OPTION_CSYNC].value.bool
+# define Devel Option[ATI_OPTION_DEVEL].value.bool
+# define Linear Option[ATI_OPTION_LINEAR].value.bool
+# define ProbeClocks Option[ATI_OPTION_PROBE_CLOCKS].value.bool
+
+ /* Pick up XF86Config options */
+ xf86CollectOptions(pScreenInfo, NULL);
+
+ /* Set non-zero defaults */
+ Linear = TRUE;
+
+ xf86ProcessOptions(pScreenInfo->scrnIndex, pScreenInfo->options, Option);
+
+ /* Disable linear apertures if the OS doesn't support them */
+ if (!xf86LinearVidMem() && Linear)
+ {
+ if (Option[ATI_OPTION_LINEAR].found)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "OS does not support linear apertures.\n");
+ Linear = FALSE;
+ }
+
+ /* Move option values into driver private structure */
+ pATI->OptionCSync = CSync;
+ pATI->OptionDevel = Devel;
+ pATI->OptionLinear = Linear;
+ pATI->OptionProbeClocks = ProbeClocks;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.h
new file mode 100644
index 000000000..87fc3e071
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.h
@@ -0,0 +1,33 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atioption.h,v 1.1 1999/07/06 11:38:33 dawes Exp $ */
+/*
+ * Copyright 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIOPTION_H___
+#define ___ATIOPTION_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+#include "xf86str.h"
+
+extern void ATIProcessOptions FunctionPrototype((ScrnInfoPtr, ATIPtr));
+
+#endif /* ___ATIOPTION_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atipreinit.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atipreinit.c
new file mode 100644
index 000000000..db0a5a649
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atipreinit.c
@@ -0,0 +1,1645 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atipreinit.c,v 1.3 1999/08/21 13:48:31 dawes Exp $ */
+/*
+ * Copyright 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "ati.h"
+#include "atiadapter.h"
+#include "atiadjust.h"
+#include "atibios.h"
+#include "atibus.h"
+#include "atichip.h"
+#include "atidac.h"
+#include "atidsp.h"
+#include "atiident.h"
+#include "atilock.h"
+#include "atimodule.h"
+#include "atioption.h"
+#include "atipreinit.h"
+#include "atiprint.h"
+#include "atividmem.h"
+#include "xf86RAC.h"
+#include "xf86Resources.h"
+
+typedef CARD16 Colour; /* The correct spelling should be OK :-) */
+
+/*
+ * Bit patterns which are extremely unlikely to show up when reading from
+ * nonexistant memory (which normally shows up as either all bits set or all
+ * bits clear).
+ */
+static const Colour Test_Pixel[] = {0x5AA5U, 0x55AAU, 0xA55AU, 0xCA53U};
+
+static const struct
+{
+ int videoRamSize;
+ int Miscellaneous_Options_Setting;
+ struct
+ {
+ short int x, y;
+ }
+ Coordinates[NumberOf(Test_Pixel) + 1];
+}
+Test_Case[] =
+{
+ /*
+ * Given the engine settings used, only a 4M card will have enough memory
+ * to back up the 1025th line of the display. Since the pixel coordinates
+ * are zero-based, line 1024 will be the first one which is only backed on
+ * 4M cards.
+ *
+ * <Mark_Weaver@brown.edu>:
+ * In case memory is being wrapped, (0,0) and (0,1024) to make sure they
+ * can each hold a unique value.
+ */
+ {4096, MEM_SIZE_4M, {{0,0}, {0,1024}, {-1,-1}}},
+
+ /*
+ * This card has 2M or less. On a 1M card, the first 2M of the card's
+ * memory will have even doublewords backed by physical memory and odd
+ * doublewords unbacked.
+ *
+ * Pixels 0 and 1 of a row will be in the zeroth doubleword, while pixels 2
+ * and 3 will be in the first. Check both pixels 2 and 3 in case this is a
+ * pseudo-1M card (one chip pulled to turn a 2M card into a 1M card).
+ *
+ * <Mark_Weaver@brown.edu>:
+ * I don't have a 1M card, so I'm taking a stab in the dark. Maybe memory
+ * wraps every 512 lines, or maybe odd doublewords are aliases of their
+ * even doubleword counterparts. I try everything here.
+ */
+ {2048, MEM_SIZE_2M, {{0,0}, {0,512}, {2,0}, {3,0}, {-1,-1}}},
+
+ /*
+ * This is a either a 1M card or a 512k card. Test pixel 1, since it is an
+ * odd word in an even doubleword.
+ *
+ * <Mark_Weaver@brown.edu>:
+ * This is the same idea as the test above.
+ */
+ {1024, MEM_SIZE_1M, {{0,0}, {0,256}, {1,0}, {-1,-1}}},
+
+ /*
+ * Assume it is a 512k card by default, since that is the minimum
+ * configuration.
+ */
+ {512, MEM_SIZE_512K, {{-1,-1}}}
+};
+
+/*
+ * ATIMach32ReadPixel --
+ *
+ * Return the colour of the specified screen location. Called from
+ * ATIMach32videoRam function below.
+ */
+static Colour
+ATIMach32ReadPixel
+(
+ const short int X,
+ const short int Y
+)
+{
+ Colour Pixel_Colour;
+
+ /* Wait for idle engine */
+ ProbeWaitIdleEmpty();
+
+ /* Set up engine for pixel read */
+ ATIWaitQueue(7);
+ outw(RD_MASK, (CARD16)(~0));
+ outw(DP_CONFIG, FG_COLOR_SRC_BLIT | DATA_WIDTH | DRAW | DATA_ORDER);
+ outw(CUR_X, X);
+ outw(CUR_Y, Y);
+ outw(DEST_X_START, X);
+ outw(DEST_X_END, X + 1);
+ outw(DEST_Y_END, Y + 1);
+
+ /* Wait for data to become ready */
+ ATIWaitQueue(16);
+ WaitDataReady();
+
+ /* Read pixel colour */
+ Pixel_Colour = inw(PIX_TRANS);
+ ProbeWaitIdleEmpty();
+ return Pixel_Colour;
+}
+
+/*
+ * ATIMach32WritePixel --
+ *
+ * Set the colour of the specified screen location. Called from
+ * ATIMach32videoRam function below.
+ */
+static void
+ATIMach32WritePixel
+(
+ const short int X,
+ const short int Y,
+ const Colour Pixel_Colour
+)
+{
+ /* Set up engine for pixel write */
+ ATIWaitQueue(9);
+ outw(WRT_MASK, (CARD16)(~0));
+ outw(DP_CONFIG, FG_COLOR_SRC_FG | DRAW | READ_WRITE);
+ outw(ALU_FG_FN, MIX_FN_PAINT);
+ outw(FRGD_COLOR, Pixel_Colour);
+ outw(CUR_X, X);
+ outw(CUR_Y, Y);
+ outw(DEST_X_START, X);
+ outw(DEST_X_END, X + 1);
+ outw(DEST_Y_END, Y + 1);
+}
+
+/*
+ * ATIMach32videoRam --
+ *
+ * Determine the amount of video memory installed on an 68800-6 based adapter.
+ * This is done because these chips exhibit a bug that causes their
+ * MISC_OPTIONS register to report 1M rather than the true amount of memory.
+ *
+ * This function is adapted from a similar function in mach32mem.c written by
+ * Robert Wolff, David Dawes and Mark Weaver.
+ */
+static int
+ATIMach32videoRam
+(
+ void
+)
+{
+ CARD16 clock_sel, mem_bndry, misc_options, ext_ge_config;
+ Colour saved_Pixel[NumberOf(Test_Pixel)];
+ unsigned int Case_Number, Pixel_Number;
+ Bool AllPixelsOK;
+
+ /* Save register values to be modified */
+ clock_sel = inw(CLOCK_SEL);
+ mem_bndry = inw(MEM_BNDRY);
+ misc_options = inw(MISC_OPTIONS) & ~MEM_SIZE_ALIAS;
+ ext_ge_config = inw(R_EXT_GE_CONFIG);
+
+ /* Wait for enough FIFO entries */
+ ATIWaitQueue(7);
+
+ /* Enable accelerator */
+ outw(CLOCK_SEL, clock_sel | DISABPASSTHRU);
+
+ /* Make accelerator and VGA share video memory */
+ outw(MEM_BNDRY, mem_bndry & ~(MEM_PAGE_BNDRY | MEM_BNDRY_ENA));
+
+ /* Prevent video memory wrap */
+ outw(MISC_OPTIONS, misc_options | MEM_SIZE_4M);
+
+ /*
+ * Set up the drawing engine for a pitch of 1024 at 16 bits per pixel. No
+ * need to mess with the CRT because the results of this test are not
+ * intended to be seen.
+ */
+ outw(EXT_GE_CONFIG, PIX_WIDTH_16BPP | ORDER_16BPP_565 | MONITOR_8514 |
+ ALIAS_ENA);
+ outw(GE_PITCH, 1024 >> 3);
+ outw(GE_OFFSET_HI, 0);
+ outw(GE_OFFSET_LO, 0);
+
+ for (Case_Number = 0;
+ Case_Number < (NumberOf(Test_Case) - 1);
+ Case_Number++)
+ {
+ /* Reduce redundancy as per Mark_Weaver@brown.edu */
+# define TestPixel Test_Case[Case_Number].Coordinates[Pixel_Number]
+# define ForEachTestPixel \
+ for (Pixel_Number = 0; TestPixel.x >= 0; Pixel_Number++)
+
+ /* Save pixel colours that will be clobbered */
+ ForEachTestPixel
+ saved_Pixel[Pixel_Number] =
+ ATIMach32ReadPixel(TestPixel.x, TestPixel.y);
+
+ /* Write test patterns */
+ ForEachTestPixel
+ ATIMach32WritePixel(TestPixel.x, TestPixel.y,
+ Test_Pixel[Pixel_Number]);
+
+ /* Test for lost pixels */
+ AllPixelsOK = TRUE;
+ ForEachTestPixel
+ if (ATIMach32ReadPixel(TestPixel.x, TestPixel.y) !=
+ Test_Pixel[Pixel_Number])
+ {
+ AllPixelsOK = FALSE;
+ break;
+ }
+
+ /* Restore clobbered pixels */
+ ForEachTestPixel
+ ATIMach32WritePixel(TestPixel.x, TestPixel.y,
+ saved_Pixel[Pixel_Number]);
+
+ /* End test on success */
+ if (AllPixelsOK)
+ break;
+
+ /* Completeness */
+# undef ForEachTestPixel
+# undef TestPixel
+ }
+
+ /* Restore what was changed and correct MISC_OPTIONS register */
+ ATIWaitQueue(4);
+ outw(EXT_GE_CONFIG, ext_ge_config);
+ misc_options |= Test_Case[Case_Number].Miscellaneous_Options_Setting;
+ outw(MISC_OPTIONS, misc_options);
+ outw(MEM_BNDRY, mem_bndry);
+ outw(CLOCK_SEL, clock_sel);
+
+ /* Wait for activity to die down */
+ ProbeWaitIdleEmpty();
+
+ /* Tell ATIPreInit the REAL story */
+ return Test_Case[Case_Number].videoRamSize;
+}
+
+/*
+ * ATIReportMemory --
+ *
+ * This function reports on the amount and type of video memory found.
+ */
+static void
+ATIReportMemory
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ const char *MemoryTypeName
+)
+{
+ char Buffer[128], *Message;
+
+ Message = Buffer +
+ snprintf(Buffer, SizeOf(Buffer), "%d kB of %s detected",
+ pATI->VideoRAM, MemoryTypeName);
+ if (pScreenInfo->depth == 1)
+ {
+ /* 1bpp only uses one plane of four */
+ pScreenInfo->videoRam /= 4;
+ Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message,
+ " (using %d kB)", pScreenInfo->videoRam);
+ }
+ else if (pATI->VideoRAM > pScreenInfo->videoRam)
+ Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message,
+ " (using %d kB)", pScreenInfo->videoRam);
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, "%s.\n", Buffer);
+}
+
+static const int videoRamSizes[] =
+ {0, 256, 512, 1024, 2*1024, 4*1024, 6*1024, 8*1024, 12*1024, 16*1024, 0};
+static const rgb defaultWeight = {0, 0, 0};
+static const Gamma defaultGamma = {0.0, 0.0, 0.0};
+
+/*
+ * ATIPreInit --
+ *
+ * This function is only called once per screen at the start of the first
+ * server generation.
+ */
+Bool
+ATIPreInit
+(
+ ScrnInfoPtr pScreenInfo,
+ int flags
+)
+{
+# define BIOS_SIZE 0x00010000U /* 64kB */
+ CARD8 BIOS[BIOS_SIZE];
+# define BIOSByte(_n) (*((CARD8 *)(BIOS + (_n))))
+# define BIOSWord(_n) (*((CARD16 *)(BIOS + (_n))))
+ unsigned int BIOSSize = BIOS_SIZE;
+ unsigned int ROMTable = 0, ClockTable = 0, FrequencyTable = 0;
+ unsigned int LCDTable = 0, LCDPanelInfo = 0;
+
+ char Buffer[128], *Message;
+ ATIPtr pATI;
+ GDevPtr pGDev;
+ EntityInfoPtr pEntity;
+ resPtr pResources;
+ CARD32 IOValue1, IOValue2;
+ int i, j, AcceleratorVideoRAM = 0, VGAVideoRAM = 0;
+ int Numerator, Denominator;
+ resRange Resources[2] = {{0, 0, 0}, _END};
+ ClockRange ATIClockRange = {NULL, 0, 80000, 0, TRUE, TRUE, 1, 1, 0};
+ int minPitch, maxPitch = 0xFFU, pitchInc;
+ LookupModeFlags Strategy = LOOKUP_CLOSEST_CLOCK;
+
+ if (pScreenInfo->numEntities != 1)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Logic error: Number of attached entities not 1.\n");
+ return FALSE;
+ }
+
+ pATI = ATIPTR(pScreenInfo);
+
+ if (pATI->iEntity != pScreenInfo->entityList[0])
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Logic error: Entity mismatch.\n");
+ return FALSE;
+ }
+
+ /* Register resources */
+ pEntity = xf86GetEntityInfo(pScreenInfo->entityList[0]);
+ pGDev = pEntity->device;
+ pResources = pEntity->resources;
+ xfree(pEntity);
+ if (!pResources)
+ pResources = xf86RegisterResources(pATI->iEntity, NULL,
+ pATI->SharedAccelerator ? ResShared : ResExclusive);
+ if (pResources)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Unable to register the following bus resources:\n");
+ xf86PrintResList(0, pResources);
+ return FALSE;
+ }
+
+ pScreenInfo->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT;
+ pScreenInfo->racMemFlags = RAC_FB;
+
+ /* Set monitor */
+ pScreenInfo->monitor = pScreenInfo->confScreen->monitor;
+
+ /* Deal with ChipID & ChipRev overrides */
+ if (pGDev->chipID >= 0)
+ {
+ ATIChipType Chip;
+
+ Chip = ATIChipID(pGDev->chipID,
+ (pGDev->chipRev < 0) ? pATI->ChipRev : pGDev->chipRev);
+ if (Chip != pATI->Chip)
+ {
+ pATI->Chip = Chip;
+ pATI->ChipType = pGDev->chipID;
+ if (pGDev->chipRev < 0)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,
+ "Driver messages reflect ChipID 0x%04X override.\n",
+ pATI->ChipType);
+ }
+ else
+ {
+ pATI->ChipRev = pGDev->chipRev;
+ pATI->ChipVersion = GetBits(pATI->ChipRev,
+ GetBits(CFG_CHIP_VERSION, CFG_CHIP_REV));
+ pATI->ChipFoundry = GetBits(pATI->ChipRev,
+ GetBits(CFG_CHIP_FOUNDRY, CFG_CHIP_REV));
+ pATI->ChipRevision = GetBits(pATI->ChipRev,
+ GetBits(CFG_CHIP_REVISION, CFG_CHIP_REV));
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,
+ "Driver messages reflect ChipID 0x%04X and ChipRev 0x%02X"
+ " overrides.\n", pATI->ChipType, pATI->ChipRev);
+ }
+ }
+ }
+
+ /* Finish private area initialization */
+ pATI->DAC = ATI_DAC_GENERIC;
+ pATI->NewHW.SetBank = ATIx8800SetBank;
+ pATI->BankInfo.SetSourceBank = ATIx8800SetRead;
+ pATI->BankInfo.SetDestinationBank = ATIx8800SetWrite;
+ pATI->BankInfo.SetSourceAndDestinationBanks = ATIx8800SetReadWrite;
+ pATI->BankInfo.BankSize = 0x00010000U; /* 64kB */
+ pATI->ApertureBase = 0x000A0000U;
+ pATI->ApertureSize = 0x00010000U;
+ pATI->LCDPanelID = -1;
+
+ /* Finish probing the adapter */
+ switch (pATI->Adapter)
+ {
+ case ATI_ADAPTER_NONE:
+ case ATI_ADAPTER_EGA:
+ case ATI_ADAPTER_EGA_PLUS:
+ case ATI_ADAPTER_VGA:
+ case ATI_ADAPTER_BASIC:
+ pATI->NewHW.SetBank = (ATIBankProcPtr)NoopDDA;
+ pATI->BankInfo.SetSourceBank =
+ pATI->BankInfo.SetDestinationBank =
+ pATI->BankInfo.SetSourceAndDestinationBanks =
+ (miBankProcPtr)NoopDDA;
+ case ATI_ADAPTER_V3:
+ pATI->NewHW.SetBank = ATIV3SetBank;
+ pATI->BankInfo.SetSourceBank = ATIV3SetRead;
+ pATI->BankInfo.SetDestinationBank = ATIV3SetWrite;
+ pATI->BankInfo.SetSourceAndDestinationBanks = ATIV3SetReadWrite;
+ break;
+
+ case ATI_ADAPTER_V4:
+ case ATI_ADAPTER_V5:
+ pATI->NewHW.SetBank = ATIV4V5SetBank;
+ pATI->BankInfo.SetSourceBank = ATIV4V5SetRead;
+ pATI->BankInfo.SetDestinationBank = ATIV4V5SetWrite;
+ pATI->BankInfo.SetSourceAndDestinationBanks = ATIV4V5SetReadWrite;
+ break;
+
+ case ATI_ADAPTER_XL:
+ pATI->DAC = ATI_DAC_SC11483;
+ break;
+
+ case ATI_ADAPTER_8514A:
+ pATI->VideoRAM =
+ videoRamSizes[GetBits(inw(SUBSYS_STAT), _8PLANE) + 2];
+ break;
+
+ case ATI_ADAPTER_MACH8:
+ pATI->VideoRAM =
+ videoRamSizes[GetBits(inw(CONFIG_STATUS_1), MEM_INSTALLED) + 2];
+ break;
+
+ case ATI_ADAPTER_MACH32:
+ IOValue1 = inw(CONFIG_STATUS_1);
+ pATI->DAC = ATI_DAC(GetBits(IOValue1, DACTYPE), 0);
+ pATI->MemoryType = GetBits(IOValue1, MEM_TYPE);
+
+ IOValue1 = inw(MISC_OPTIONS);
+ pATI->VideoRAM =
+ videoRamSizes[GetBits(IOValue1, MEM_SIZE_ALIAS) + 2];
+
+ /*
+ * The 68800-6 doesn't necessarily report the correct video memory
+ * size.
+ */
+ if ((pATI->Chip == ATI_CHIP_68800_6) && (pATI->VideoRAM == 1024))
+ pATI->VideoRAM = ATIMach32videoRam();
+
+ break;
+
+ case ATI_ADAPTER_MACH64:
+ /* Set I/O port addresses */
+ pATI->CPIO_CRTC_H_TOTAL_DISP = ATIIOPort(CRTC_H_TOTAL_DISP);
+ pATI->CPIO_CRTC_H_SYNC_STRT_WID = ATIIOPort(CRTC_H_SYNC_STRT_WID);
+ pATI->CPIO_CRTC_V_TOTAL_DISP = ATIIOPort(CRTC_V_TOTAL_DISP);
+ pATI->CPIO_CRTC_V_SYNC_STRT_WID = ATIIOPort(CRTC_V_SYNC_STRT_WID);
+ pATI->CPIO_CRTC_OFF_PITCH = ATIIOPort(CRTC_OFF_PITCH);
+ pATI->CPIO_CRTC_INT_CNTL = ATIIOPort(CRTC_INT_CNTL);
+ pATI->CPIO_CRTC_GEN_CNTL = ATIIOPort(CRTC_GEN_CNTL);
+ pATI->CPIO_OVR_CLR = ATIIOPort(OVR_CLR);
+ pATI->CPIO_OVR_WID_LEFT_RIGHT = ATIIOPort(OVR_WID_LEFT_RIGHT);
+ pATI->CPIO_OVR_WID_TOP_BOTTOM = ATIIOPort(OVR_WID_TOP_BOTTOM);
+ pATI->CPIO_CLOCK_CNTL = ATIIOPort(CLOCK_CNTL);
+ pATI->CPIO_MEM_INFO = ATIIOPort(MEM_INFO);
+ pATI->CPIO_DAC_REGS = ATIIOPort(DAC_REGS);
+ pATI->CPIO_DAC_CNTL = ATIIOPort(DAC_CNTL);
+ pATI->CPIO_CONFIG_CNTL = ATIIOPort(CONFIG_CNTL);
+
+ IOValue1 = inl(pATI->CPIO_MEM_INFO);
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ pATI->VideoRAM =
+ videoRamSizes[GetBits(IOValue1, CTL_MEM_SIZE) + 2];
+ else
+ {
+ IOValue1 = GetBits(IOValue1, CTL_MEM_SIZEB);
+ if (IOValue1 < 8)
+ pATI->VideoRAM = (IOValue1 + 1) * 512;
+ else if (IOValue1 < 12)
+ pATI->VideoRAM = (IOValue1 - 3) * 1024;
+ else
+ pATI->VideoRAM = (IOValue1 - 7) * 2048;
+ }
+
+ IOValue1 = inl(pATI->CPIO_DAC_CNTL);
+ pATI->DAC = GetBits(IOValue1, DAC_TYPE);
+
+ IOValue1 = inl(ATIIOPort(CONFIG_STATUS64_0));
+ IOValue2 = inl(ATIIOPort(SCRATCH_REG1));
+ if (pATI->Chip >= ATI_CHIP_264CT)
+ {
+ pATI->MemoryType = GetBits(IOValue1, CFG_MEM_TYPE_T);
+
+ /* Get LCD panel id and set LCD & TV I/O port numbers */
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ pATI->LCDPanelID = GetBits(IOValue1, CFG_PANEL_ID);
+
+ pATI->CPIO_HORZ_STRETCHING = ATIIOPort(HORZ_STRETCHING);
+ pATI->CPIO_VERT_STRETCHING = ATIIOPort(VERT_STRETCHING);
+ pATI->CPIO_LCD_GEN_CTRL = ATIIOPort(LCD_GEN_CTRL);
+ pATI->CPIO_POWER_MANAGEMENT = ATIIOPort(POWER_MANAGEMENT);
+
+ /*
+ * Don't bother with panel support if it's not enabled by
+ * BIOS initialization.
+ */
+ if (!(inl(pATI->CPIO_LCD_GEN_CTRL) & LCD_ON))
+ pATI->LCDPanelID = -1;
+ }
+ else if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL))
+ {
+ pATI->LCDPanelID = GetBits(IOValue1, CFG_PANEL_ID);
+
+ pATI->CPIO_TV_OUT_INDEX = ATIIOPort(TV_OUT_INDEX);
+ pATI->CPIO_TV_OUT_DATA = ATIIOPort(TV_OUT_DATA);
+ pATI->CPIO_LCD_INDEX = ATIIOPort(LCD_INDEX);
+ pATI->CPIO_LCD_DATA = ATIIOPort(LCD_DATA);
+
+ /*
+ * Don't bother with panel support if it's not enabled by
+ * BIOS initialization.
+ */
+ IOValue1 = inl(pATI->CPIO_LCD_INDEX);
+ IOValue2 = ATIGetLTProLCDReg(LCD_GEN_CNTL);
+ outl(pATI->CPIO_LCD_INDEX, IOValue1);
+ if (!(IOValue2 & LCD_ON))
+ pATI->LCDPanelID = -1;
+ }
+ }
+ else
+ {
+ pATI->MemoryType = GetBits(IOValue1, CFG_MEM_TYPE);
+
+ /* Factor in what the BIOS says the DAC is */
+ pATI->DAC = ATI_DAC(pATI->DAC,
+ GetBits(IOValue2, BIOS_INIT_DAC_SUBTYPE));
+ }
+
+ /*
+ * RAMDAC types 0 & 1 for Mach64's are different than those for
+ * Mach32's.
+ */
+ if (pATI->DAC < ATI_DAC_ATI68875)
+ pATI->DAC += ATI_DAC_INTERNAL;
+
+ break;
+
+ default:
+ break;
+ }
+
+ /* Get PCI or legacy video BIOS, >all< of it */
+ i = ATIReadBIOS(pATI, BIOS, 0, SizeOf(BIOS));
+
+ /* Clear off what could not be read */
+ if (i < 0)
+ i = 0;
+ if (i < SizeOf(BIOS))
+ memset(BIOS + i, 0, SizeOf(BIOS) - i);
+ if ((BIOSByte(0) == 0x55U) && (BIOSByte(1) == 0xAAU) && BIOSByte(2))
+ BIOSSize = BIOSByte(2) << 9;
+ else
+ i = 0;
+ if ((unsigned int)i < BIOSSize)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Unable to correctly read adapter BIOS.\n");
+ return FALSE;
+ }
+
+ /*
+ * For Mach64 adapters, pick up, from the BIOS, the type of programmable
+ * clock generator (if any), and various information about it.
+ */
+ if (pATI->Chip >= ATI_CHIP_88800GXC)
+ {
+ CARD16 ClockDac;
+
+ /* Set up non-zero defaults */
+ pATI->ClockDescriptor = ATIClockDescriptors[ATI_CLOCK_FIXED];
+ pATI->ClockNumberToProgramme = -1;
+
+ ROMTable = BIOSWord(0x48U);
+ if ((ROMTable + 0x12U) > BIOSSize)
+ ROMTable = 0;
+
+ if (ROMTable > 0)
+ {
+ ClockTable = BIOSWord(ROMTable + 0x10U);
+ if ((ClockTable + 0x20U) > BIOSSize)
+ ClockTable = 0;
+ }
+
+ if (ClockTable > 0)
+ {
+ FrequencyTable = BIOSWord(ClockTable - 0x02U);
+ if ((FrequencyTable > 0) &&
+ ((FrequencyTable + 0x20U) <= BIOSSize))
+ for (i = 0; i < 16; i++)
+ pATI->BIOSClocks[i] = (&BIOSWord(FrequencyTable))[i];
+ pATI->ProgrammableClock = BIOSByte(ClockTable);
+ pATI->ClockNumberToProgramme = BIOSByte(ClockTable + 0x06U);
+ if (pATI->ProgrammableClock < ATI_CLOCK_MAX)
+ pATI->ClockDescriptor =
+ ATIClockDescriptors[pATI->ProgrammableClock];
+ switch (BIOSWord(ClockTable + 0x08U) / 10)
+ {
+ case 143:
+ pATI->ReferenceNumerator = 157500;
+ pATI->ReferenceDenominator = 11;
+ break;
+
+ case 286:
+ pATI->ReferenceNumerator = 315000;
+ pATI->ReferenceDenominator = 11;
+ break;
+
+ default:
+ pATI->ReferenceNumerator =
+ BIOSWord(ClockTable + 0x08U) * 10;
+ pATI->ReferenceDenominator = 1;
+ break;
+ }
+ }
+
+ ClockDac = pATI->DAC;
+ switch (pATI->ProgrammableClock)
+ {
+ case ATI_CLOCK_ICS2595:
+ /*
+ * Pick up reference divider (43 or 46) appropriate to the chip
+ * revision level.
+ */
+ if (ClockTable > 0)
+ pATI->ClockDescriptor.MinM = pATI->ClockDescriptor.MaxM =
+ BIOSWord(ClockTable + 0x0AU);
+ break;
+
+ case ATI_CLOCK_STG1703:
+ /* This one's also a RAMDAC */
+ ClockDac = ATI_DAC_STG1703;
+ break;
+
+ case ATI_CLOCK_CH8398:
+ /* This one's also a RAMDAC */
+ ClockDac = ATI_DAC_CH8398;
+ break;
+
+ case ATI_CLOCK_INTERNAL:
+ /*
+ * The reference divider has already been programmed by BIOS
+ * initialization. Because, there is only one reference
+ * divider for all generated frequencies (including MCLK), it
+ * cannot be changed without reprogramming all clocks every
+ * time one of them needs a different reference divider.
+ *
+ * Besides, it's not a good idea to change the reference
+ * divider. BIOS initialization sets it to a value that
+ * effectively prevents generating frequencies beyond the
+ * graphics controller's tolerance.
+ */
+ pATI->ClockDescriptor.MinM = pATI->ClockDescriptor.MaxM =
+ ATIGetMach64PLLReg(PLL_REF_DIV);
+
+ /* The DAC is also integrated */
+ if ((pATI->DAC & ~0x0FU) != ATI_DAC_INTERNAL)
+ ClockDac = ATI_DAC_INTERNAL;
+
+ break;
+
+ case ATI_CLOCK_ATT20C408:
+ /* This one's also a RAMDAC */
+ ClockDac = ATI_DAC_ATT20C408;
+ break;
+
+ case ATI_CLOCK_IBMRGB514:
+ /* This one's also a RAMDAC */
+ ClockDac = ATI_DAC_IBMRGB514;
+ pATI->ClockNumberToProgramme = 7;
+ break;
+
+ default:
+ break;
+ }
+
+ /*
+ * We now have up to two indications of what RAMDAC the adapter uses.
+ * They should be the same. The following test and corresponding
+ * action are under construction.
+ */
+ if (pATI->DAC != ClockDac)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Mach64 RAMDAC probe discrepancy detected:\n"
+ " DAC=0x%02X; ClockDac=0x%02X.\n",
+ pATI->DAC, ClockDac);
+
+ if (pATI->DAC == ATI_DAC_IBMRGB514)
+ {
+ pATI->ProgrammableClock = ATI_CLOCK_IBMRGB514;
+ pATI->ClockDescriptor =
+ ATIClockDescriptors[ATI_CLOCK_IBMRGB514];
+ pATI->ClockNumberToProgramme = 7;
+ }
+ else
+ pATI->DAC = ClockDac; /* For now */
+ }
+
+ /* Determine panel dimensions and driving clock */
+ if (pATI->LCDPanelID >= 0)
+ {
+ LCDTable = BIOSWord(0x78U);
+ if (((LCDTable + 0x1AU) > BIOSSize) ||
+ (BIOSByte(LCDTable + 5) != 0x1AU))
+ LCDTable = 0;
+
+ if (LCDTable > 0)
+ {
+ LCDPanelInfo = BIOSWord(LCDTable + 0x0AU);
+ if (((LCDPanelInfo + 0x1DU) > BIOSSize) ||
+ (BIOSByte(LCDPanelInfo) != pATI->LCDPanelID))
+ LCDPanelInfo = 0;
+ }
+
+ if (LCDPanelInfo > 0)
+ {
+ pATI->LCDHorizontal = BIOSWord(LCDPanelInfo + 0x19U);
+ pATI->LCDVertical = BIOSWord(LCDPanelInfo + 0x1BU);
+
+ /* Get clock number */
+ if (inl(pATI->CPIO_CRTC_GEN_CNTL) & CRTC_EXT_DISP_EN)
+ i = inl(pATI->CPIO_CLOCK_CNTL) & 0x03U;
+ else
+ i = (inb(R_GENMO) & 0x0CU) >> 2;
+
+ /* Get post divider */
+ j = (GetBits(ATIGetMach64PLLReg(PLL_XCLK_CNTL),
+ PLL_VCLK0_XDIV << i) *
+ (MaxBits(PLL_VCLK0_POST_DIV) + 1)) |
+ GetBits(ATIGetMach64PLLReg(PLL_VCLK_POST_DIV),
+ PLL_VCLK0_POST_DIV << (i * 2));
+
+ /* Calculate clock of mode on entry */
+ Numerator = ATIGetMach64PLLReg(PLL_VCLK0_FB_DIV + i) *
+ pATI->ReferenceNumerator;
+ Denominator = pATI->ClockDescriptor.MinM *
+ pATI->ReferenceDenominator *
+ pATI->ClockDescriptor.PostDividers[j];
+ pATI->LCDClock = ATIDivide(Numerator, Denominator, 1, 0);
+ }
+ }
+ }
+
+ ATIUnlock(pATI); /* Unlock registers */
+
+ /* Sometimes, the BIOS lies about the chip */
+ if ((pATI->Chip >= ATI_CHIP_28800_4) && (pATI->Chip <= ATI_CHIP_28800_6))
+ {
+ IOValue1 = GetBits(ATIGetExtReg(0xAAU), 0x0FU) +
+ (ATI_CHIP_28800_4 - 4);
+ if ((IOValue1 <= ATI_CHIP_28800_6) && (IOValue1 > pATI->Chip))
+ pATI->Chip = IOValue1;
+ }
+
+ /* Report what was found */
+ xf86DrvMsg(pScreenInfo->scrnIndex, pATI->Chipset ? X_CONFIG : X_DEFAULT,
+ "Chipset: \"%s\".\n", ATIChipsetNames[pATI->Chipset]);
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "%s graphics controller detected.\n", ATIChipNames[pATI->Chip]);
+
+ if ((pATI->Chip >= ATI_CHIP_68800) && (pATI->Chip != ATI_CHIP_68800_3))
+ {
+ Message = Buffer + snprintf(Buffer, SizeOf(Buffer), "Chip type %04X",
+ pATI->ChipType);
+ if (!(pATI->ChipType & ~(CHIP_CODE_0 | CHIP_CODE_1)))
+ Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message,
+ " (%c%c)",
+ GetBits(pATI->ChipType, CHIP_CODE_1) + 0x41U,
+ GetBits(pATI->ChipType, CHIP_CODE_0) + 0x41U);
+ else if ((pATI->ChipType & 0x4040U) == 0x4040U)
+ Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message,
+ " \"%c%c\"",
+ GetByte(pATI->ChipType, 1), GetByte(pATI->ChipType, 0));
+ if ((pATI->Chip >= ATI_CHIP_264CT) && (pATI->Chip != ATI_CHIP_Mach64))
+ Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message,
+ ", version %d, foundry %s",
+ pATI->ChipVersion, ATIFoundryNames[pATI->ChipFoundry]);
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "%s, class %d, revision 0x%02X.\n",
+ Buffer, pATI->ChipClass, pATI->ChipRevision);
+ }
+
+ if (pATI->Adapter >= ATI_ADAPTER_MACH8)
+ {
+ Message = Buffer + snprintf(Buffer, SizeOf(Buffer),
+ "%s bus interface detected", ATIBusNames[pATI->BusType]);
+ if (pATI->Adapter >= ATI_ADAPTER_MACH64)
+ Message += snprintf(Message, Buffer + SizeOf(Buffer) - Message,
+ "; %s I/O base is 0x%04X",
+ (pATI->CPIODecoding == SPARSE_IO) ? "sparse" : "block",
+ pATI->CPIOBase);
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, "%s.\n", Buffer);
+ }
+
+ if (pATI->CPIO_VGAWonder)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "VGA Wonder registers at I/O port 0x%04X.\n",
+ pATI->CPIO_VGAWonder);
+
+ if (pATI->Coprocessor != ATI_CHIP_NONE)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "%s graphics accelerator detected,\n with %d kB of coprocessor"
+ " memory.\n",
+ ATIChipNames[pATI->Coprocessor], pATI->VideoRAM);
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "%s adapter detected.\n", ATIAdapterNames[pATI->Adapter]);
+
+ if ((pATI->DAC & ~0x0FU) == ATI_DAC_INTERNAL)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "Internal RAMDAC (subtype %d) detected.\n", pATI->DAC & 0x0FU);
+ else
+ {
+ const DACRec *DAC;
+
+ for (DAC = ATIDACDescriptors; ; DAC++)
+ {
+ if (pATI->DAC == DAC->DACType)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "%s RAMDAC detected.\n", DAC->DACName);
+ break;
+ }
+
+ if (pATI->DAC < DAC->DACType)
+ {
+ xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 0,
+ "Unknown RAMDAC type 0x%02X detected.\n", pATI->DAC);
+ break;
+ }
+ }
+ }
+
+ if (pATI->LCDPanelID >= 0)
+ {
+ if (LCDPanelInfo <= 0)
+ {
+ xf86DrvMsgVerb(pScreenInfo->scrnIndex, X_WARNING, 0,
+ "Unable to determine dimensions of panel (ID %d).\n",
+ pATI->LCDPanelID);
+ pATI->LCDPanelID = -1; /* Revert to unsupported status */
+ }
+ else
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "%dx%d panel (ID %d) detected.\n",
+ pATI->LCDHorizontal, pATI->LCDVertical, pATI->LCDPanelID);
+ for (i = 0; i < 24; i++)
+ Buffer[i] = BIOSByte(LCDPanelInfo + 1 + i);
+ for (i = 24; --i >= 0; )
+ if (Buffer[i] != ' ')
+ {
+ Buffer[i + 1] = '\0';
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "Panel model %s.\n", Buffer);
+ break;
+ }
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
+ "Panel clock is %.3f MHz.\n",
+ (double)(pATI->LCDClock) / 1000.0);
+ }
+ }
+
+ /* Report BIOS address */
+ if (pATI->BIOSBase)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "BIOS bus address: 0x%08X.\n", pATI->BIOSBase);
+ else
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "BIOS not mapped by BIOS initialization.\n");
+
+ /* Promote chipset specification */
+ switch (pATI->Chipset)
+ {
+ case ATI_CHIPSET_IBMVGA:
+ if (pATI->Adapter == ATI_ADAPTER_VGA)
+ break; /* XXX */
+ /* Fall through */
+
+ case ATI_CHIPSET_VGAWONDER:
+ pATI->Chipset = ATI_CHIPSET_ATIVGA;
+ break;
+
+ case ATI_CHIPSET_IBM8514:
+ if (pATI->Adapter == ATI_ADAPTER_8514A)
+ break; /* XXX */
+ /* Fall through */
+
+ case ATI_CHIPSET_MACH8:
+ case ATI_CHIPSET_MACH32:
+ case ATI_CHIPSET_MACH64:
+ pATI->Chipset = ATI_CHIPSET_ATI;
+ break;
+
+ default:
+ break;
+ }
+
+ /*
+ * Set depth, bpp, etc.
+ */
+
+ if ((pATI->Chipset != ATI_CHIPSET_ATI) || (pATI->Chip < ATI_CHIP_264CT))
+ i = NoDepth24Support; /* No support for >8bpp either */
+ else
+ i = Support24bppFb | Support32bppFb;
+ if (!xf86SetDepthBpp(pScreenInfo, 8, 8, 8, i))
+ return FALSE;
+
+ switch (pScreenInfo->depth)
+ {
+ case 1: case 4: case 8: case 15: case 16: case 24:
+ break;
+
+ default:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Driver does not support depth %d.\n",
+ pScreenInfo->depth);
+ return FALSE;
+ }
+
+ xf86PrintDepthBpp(pScreenInfo);
+
+ if ((i == NoDepth24Support) && (pScreenInfo->depth > 8))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Depth %d is not supported through this adapter.\n",
+ pScreenInfo->depth);
+ return FALSE;
+ }
+
+ /*
+ * Pick up XF86Config options.
+ */
+
+ ATIProcessOptions(pScreenInfo, pATI);
+
+ /*
+ * Set colour weights.
+ */
+
+ if (pATI->Chip < ATI_CHIP_264CT)
+ pScreenInfo->rgbBits = 6;
+ else
+ pScreenInfo->rgbBits = 8;
+ if (!xf86SetWeight(pScreenInfo, defaultWeight, defaultWeight))
+ return FALSE;
+
+ if ((pScreenInfo->depth > 8) &&
+ ((pScreenInfo->weight.red != pScreenInfo->weight.blue) ||
+ (pScreenInfo->weight.red != (CARD32)(pScreenInfo->depth / 3)) ||
+ ((CARD32)pScreenInfo->depth != (pScreenInfo->weight.red +
+ pScreenInfo->weight.green +
+ pScreenInfo->weight.blue))))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Driver does not support weight %d%d%d for depth %d.\n",
+ pScreenInfo->weight.red, pScreenInfo->weight.green,
+ pScreenInfo->weight.blue, pScreenInfo->depth);
+ return FALSE;
+ }
+
+ /*
+ * Set default visual.
+ */
+
+ if (!xf86SetDefaultVisual(pScreenInfo, -1))
+ return FALSE;
+
+ if ((pScreenInfo->depth > 8) && (pScreenInfo->defaultVisual != TrueColor))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Driver does not support default visual %s for depth %d.\n",
+ xf86GetVisualName(pScreenInfo->defaultVisual),
+ pScreenInfo->depth);
+ return FALSE;
+ }
+
+ /*
+ * Set colour gamma.
+ */
+
+ if ((pScreenInfo->depth > 1) && !xf86SetGamma(pScreenInfo, defaultGamma))
+ return FALSE;
+
+ /*
+ * Determine which CRT controller to use for video modes.
+ */
+
+ if ((pATI->Chip >= ATI_CHIP_88800GXC) &&
+ (pScreenInfo->depth >= 8) &&
+ (pATI->Chipset == ATI_CHIPSET_ATI))
+ pATI->NewHW.crtc = ATI_CRTC_MACH64;
+ else
+ pATI->NewHW.crtc = ATI_CRTC_VGA;
+
+ /* Complain if VGA is needed but not there */
+ if ((pATI->NewHW.crtc == ATI_CRTC_VGA) || !pATI->OptionLinear)
+ {
+ /* VGA is required at this point */
+ if (pATI->VGAAdapter == ATI_ADAPTER_NONE)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "VGA is not available through this adapter.\n");
+ return FALSE;
+ }
+
+ if (pATI->Coprocessor != ATI_CHIP_NONE)
+ {
+ /* Ignore any 8514/A or Mach8 accelerator from this point on */
+ pATI->Adapter = pATI->VGAAdapter;
+
+ /* Accelerator and VGA cannot share memory */
+ pATI->VideoRAM = 0;
+ }
+ }
+
+ /*
+ * Finish detecting video RAM size.
+ */
+
+ AcceleratorVideoRAM = pScreenInfo->videoRam = pATI->VideoRAM;
+ if (pATI->Chip == ATI_CHIP_VGA)
+ {
+ if (pScreenInfo->depth <= 4)
+ VGAVideoRAM = 256;
+ else
+ VGAVideoRAM = 64;
+
+ /* For VGA, allow a lower override */
+ if ((pGDev->videoRam > 0) && (pGDev->videoRam < VGAVideoRAM))
+ VGAVideoRAM = pGDev->videoRam;
+ }
+ else if (pATI->CPIO_VGAWonder)
+ {
+ /*
+ * XXX There's an assumption here that the values retrieved are those
+ * set by BIOS initialization.
+ */
+ if (pATI->Chip <= ATI_CHIP_18800_1)
+ {
+ VGAVideoRAM =
+ videoRamSizes[GetBits(ATIGetExtReg(0xBBU), 0x20U) + 1];
+ if (AcceleratorVideoRAM > 512)
+ AcceleratorVideoRAM = 512;
+ }
+ else
+ {
+ IOValue1 = ATIGetExtReg(0xB0U);
+ if (IOValue1 & 0x08U)
+ VGAVideoRAM = 1024;
+ else if (IOValue1 & 0x10U)
+ VGAVideoRAM = 512;
+ else
+ VGAVideoRAM = 256;
+ if (AcceleratorVideoRAM > 1024)
+ AcceleratorVideoRAM = 1024;
+ }
+ }
+
+ /* Check for hardware limitations */
+ if (!AcceleratorVideoRAM)
+ {
+ pScreenInfo->videoRam = pATI->VideoRAM = VGAVideoRAM;
+
+ /*
+ * VGA Wonder V3's, V4's and V5's don't appear to support banking in
+ * planar modes.
+ */
+ if ((pScreenInfo->depth <= 4) &&
+ (pATI->Chip <= ATI_CHIP_18800_1) &&
+ (VGAVideoRAM > 256))
+ {
+ if (pATI->OptionDevel)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE,
+ "Virtual resolutions requiring more than %s kB\n of video"
+ " memory might not function properly." ATI_README,
+ (pScreenInfo->depth == 1) ? "64" : "256");
+ }
+ else
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE,
+ "VideoRAM reduced to 256 kB due to hardware limitations."
+ ATI_README);
+ pScreenInfo->videoRam = 256;
+ }
+ }
+ }
+ else if ((pATI->NewHW.crtc == ATI_CRTC_MACH64) ||
+ (pATI->Chip >= ATI_CHIP_264CT))
+ {
+ /* Possibly set up for linear aperture */
+ if ((pScreenInfo->depth >= 8) && pATI->OptionLinear)
+ {
+ /* Get adapter's linear aperture configuration */
+ IOValue1 = inl(pATI->CPIO_CONFIG_CNTL);
+ pATI->LinearBase = GetBits(IOValue1, CFG_MEM_AP_LOC) << 22;
+ if ((IOValue1 & CFG_MEM_AP_SIZE) != CFG_MEM_AP_SIZE)
+ pATI->LinearSize = GetBits(IOValue1, CFG_MEM_AP_SIZE) << 22;
+
+ /* Except for PCI & AGP, allow for user override */
+ if ((pATI->BusType != ATI_BUS_PCI) &&
+ (pATI->BusType != ATI_BUS_AGP))
+ {
+ if (pATI->Chip >= ATI_CHIP_88800GXE)
+ IOValue2 = ~((unsigned long)((1 << 24) - 1));
+ else if (pATI->VideoRAM >= 4096)
+ IOValue2 = ~((unsigned long)((1 << 23) - 1));
+ else
+ IOValue2 = ~((unsigned long)((1 << 22) - 1));
+ if ((IOValue2 &= pGDev->MemBase) &&
+ (IOValue2 <= (MaxBits(CFG_MEM_AP_LOC) << 22)))
+ pATI->LinearBase = IOValue2;
+
+ if (pATI->LinearBase)
+ {
+ if (pATI->VideoRAM < 4096)
+ pATI->LinearSize = 4 * 1024 * 1024;
+ else
+ pATI->LinearSize = 8 * 1024 * 1024;
+
+ Resources[0].type = ResExcMemBlock;
+ Resources[0].rBegin = pATI->LinearBase;
+ Resources[0].rEnd = pATI->LinearBase +
+ pATI->LinearSize - 1;
+ if (xf86RegisterResources(pATI->iEntity, Resources,
+ ResNone))
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING,
+ "Unable to register %d MB linear aperture at"
+ " 0x%08X.\n", pATI->LinearSize >> 10,
+ pATI->LinearBase);
+
+ pATI->LinearSize = 0;
+ }
+ }
+ }
+
+ if (!pATI->LinearBase || !pATI->LinearSize)
+ {
+ if (pATI->VGAAdapter == ATI_ADAPTER_NONE)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "A linear aperture is not available through this"
+ " adapter.\n");
+ return FALSE;
+ }
+
+ /* Insurance */
+ pATI->LinearBase = pATI->LinearSize = 0;
+ }
+ else
+ {
+ AcceleratorVideoRAM = (pATI->LinearSize >> 10) - 2; /* 4? */
+ if (AcceleratorVideoRAM < pATI->VideoRAM)
+ {
+ if (pATI->Chip < ATI_CHIP_264CT)
+ {
+ /*
+ * Don't allow virtual resolution to overlay register
+ * aperture(s).
+ */
+ pScreenInfo->videoRam = AcceleratorVideoRAM;
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE,
+ "Virtual resolutions will be limited to %d kB to"
+ " account for\n accelerator register aperture.\n",
+ AcceleratorVideoRAM);
+ }
+ else
+ {
+ /*
+ * On VTB's and later, ATIInit disables the primary
+ * register aperture. This is done so the driver can
+ * get at the frame buffer memory behind it. For MMIO
+ * purposes, the auxillary register aperture will be
+ * used instead. Also, ignore the CONFIG_CNTL
+ * register's indication of linear aperture size, as it
+ * is insufficient for adapters with more than 8MB of
+ * video memory.
+ */
+ if (pATI->VideoRAM > (8 * 1024))
+ pATI->LinearSize = 16 * 1024 * 1024;
+ }
+ }
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Using %d MB linear aperture at 0x%08X.\n",
+ pATI->LinearSize >> 20, pATI->LinearBase);
+
+ /* Only mmap what is needed */
+ pATI->ApertureSize = pATI->LinearSize = pATI->VideoRAM * 1024;
+ }
+ }
+
+ /* Set up for a banked aperture */
+ if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
+ {
+ pATI->UseSmallApertures = TRUE;
+
+ /* Set banking port numbers */
+ pATI->CPIO_MEM_VGA_RP_SEL = ATIIOPort(MEM_VGA_RP_SEL);
+ pATI->CPIO_MEM_VGA_WP_SEL = ATIIOPort(MEM_VGA_WP_SEL);
+
+ /* Set banking functions */
+ if (pScreenInfo->depth <= 4)
+ {
+ pATI->NewHW.SetBank = ATIMach64SetBankPlanar;
+ pATI->BankInfo.SetSourceBank = ATIMach64SetReadPlanar;
+ pATI->BankInfo.SetDestinationBank = ATIMach64SetWritePlanar;
+ pATI->BankInfo.SetSourceAndDestinationBanks =
+ ATIMach64SetReadWritePlanar;
+ }
+ else
+ {
+ pATI->NewHW.SetBank = ATIMach64SetBankPacked;
+ pATI->BankInfo.SetSourceBank = ATIMach64SetReadPacked;
+ pATI->BankInfo.SetDestinationBank = ATIMach64SetWritePacked;
+ pATI->BankInfo.SetSourceAndDestinationBanks =
+ ATIMach64SetReadWritePacked;
+ }
+ }
+ }
+ else
+ /*
+ * After BIOS initialization, the accelerator (if any) and the VGA won't
+ * necessarily agree on the amount of video memory, depending on whether or
+ * where the memory boundary is configured. Any discrepancy will be
+ * resolved by ATIInit.
+ *
+ * However, it's possible that there is more video memory than VGA Wonder
+ * can architecturally handle.
+ */
+ if (((pATI->Chip < ATI_CHIP_68800) || (pATI->Chip > ATI_CHIP_68800AX)) &&
+ (AcceleratorVideoRAM < pScreenInfo->videoRam))
+ {
+ if (pATI->OptionDevel)
+ {
+ if (pScreenInfo->depth == 1)
+ AcceleratorVideoRAM /= 4;
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE,
+ "Virtual resolutions requiring more than %d kB\n of video"
+ " memory might not function correctly.\n",
+ AcceleratorVideoRAM);
+ }
+ else
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_NOTICE,
+ "VideoRAM reduced to %d kB due to hardware limitations."
+ ATI_README, AcceleratorVideoRAM);
+
+ pScreenInfo->videoRam = AcceleratorVideoRAM;
+ }
+ }
+
+ if (pATI->Adapter >= ATI_ADAPTER_MACH32)
+ {
+ if (pATI->Chip >= ATI_CHIP_264CT)
+ ATIReportMemory(pScreenInfo, pATI,
+ ATIMemoryTypeNames_264xT[pATI->MemoryType]);
+ else if (pATI->Chip == ATI_CHIP_88800CX)
+ ATIReportMemory(pScreenInfo, pATI,
+ ATIMemoryTypeNames_88800CX[pATI->MemoryType]);
+ else
+ ATIReportMemory(pScreenInfo, pATI,
+ ATIMemoryTypeNames_Mach[pATI->MemoryType]);
+ }
+ else if (pATI->Adapter >= ATI_ADAPTER_V3)
+ ATIReportMemory(pScreenInfo, pATI,
+ (ATIGetExtReg(0xB7U) & 0x04U) ? "DRAM" : "VRAM");
+ else
+ ATIReportMemory(pScreenInfo, pATI, "video memory");
+
+ /*
+ * Finish banking setup. This needs to be fixed to not assume the mode on
+ * entry is a VGA mode. XXX
+ */
+ if (pATI->VGAAdapter == ATI_ADAPTER_NONE)
+ {
+ pATI->OldHW.crtc = pATI->NewHW.crtc;
+ pATI->OldHW.SetBank = (ATIBankProcPtr)NoopDDA;
+ }
+ else
+ {
+ pATI->OldHW.crtc = ATI_CRTC_VGA;
+#if 0 /* ___NOT_YET___ */
+ if (pATI->ChipHasSUBSYS_CNTL)
+ {
+ }
+ else
+#endif
+ if ((pATI->Chip >= ATI_CHIP_88800GXC) &&
+ (inl(pATI->CPIO_CRTC_GEN_CNTL) & CRTC_EXT_DISP_EN))
+ pATI->OldHW.crtc = ATI_CRTC_MACH64;
+
+ if (pScreenInfo->depth <= 4)
+ {
+ pATI->BankInfo.nBankDepth = 1;
+ pATI->NewHW.nPlane = 4;
+ }
+ else
+ {
+ pATI->BankInfo.nBankDepth = pScreenInfo->depth;
+ pATI->NewHW.nPlane = 1;
+ }
+
+ if ((pATI->OldHW.crtc != ATI_CRTC_VGA) ||
+ (GetReg(SEQX, 0x04U) & 0x08U))
+ pATI->OldHW.nPlane = 1;
+ else
+ pATI->OldHW.nPlane = 4;
+
+ pATI->OldHW.nBank = ATIDivide(pATI->VideoRAM,
+ pATI->OldHW.nPlane * pATI->BankInfo.BankSize, 10, 1);
+ pATI->NewHW.nBank = ATIDivide(pATI->VideoRAM,
+ pATI->NewHW.nPlane * pATI->BankInfo.BankSize, 10, 1);
+
+ if (pATI->VGAAdapter == ATI_ADAPTER_VGA)
+ {
+ pATI->OldHW.SetBank = pATI->NewHW.SetBank =
+ (ATIBankProcPtr)NoopDDA;
+ pATI->OldHW.nBank = pATI->NewHW.nBank = 1;
+ }
+ else if (!pATI->UseSmallApertures)
+ pATI->OldHW.SetBank = pATI->NewHW.SetBank;
+ else if (!(inl(pATI->CPIO_CONFIG_CNTL) & CFG_MEM_VGA_AP_EN))
+ {
+ pATI->OldHW.SetBank = (ATIBankProcPtr)NoopDDA;
+ pATI->OldHW.nBank = 1;
+ }
+ else if (pATI->OldHW.nPlane == 1)
+ pATI->OldHW.SetBank = ATIMach64SetBankPacked;
+ else
+ pATI->OldHW.SetBank = ATIMach64SetBankPlanar;
+ }
+
+ /* 264VT-B's and later have DSP registers */
+ if ((pATI->Chip >= ATI_CHIP_264VTB) && (pATI->CPIODecoding == BLOCK_IO) &&
+ !ATIDSPPreInit(pScreenInfo, pATI))
+ return FALSE;
+
+ /*
+ * Determine maxClock. For adapters with supported programmable clock
+ * generators, start with an absolute maximum.
+ */
+ if (pATI->ClockDescriptor.MaxN > 0)
+ {
+ Numerator = pATI->ClockDescriptor.MaxN * pATI->ReferenceNumerator;
+ Denominator = pATI->ClockDescriptor.MinM * pATI->ReferenceDenominator *
+ pATI->ClockDescriptor.PostDividers[0];
+
+ /*
+ * An integrated PLL behaves as though the reference frequency were
+ * doubled. It also does not appear to care about the colour depth.
+ */
+ if (pATI->ProgrammableClock == ATI_CLOCK_INTERNAL)
+ Numerator <<= 1;
+ else if (pScreenInfo->depth > 8)
+ Denominator *= (pScreenInfo->bitsPerPixel / 8);
+
+ ATIClockRange.maxClock = (Numerator / (Denominator * 1000)) * 1000;
+ }
+
+ /*
+ * Assume an internal DAC can handle whatever frequency the internal PLL
+ * can produce (with the reference divider set by BIOS initialization), but
+ * default maxClock to a lower chip-specific default.
+ */
+ if ((pATI->DAC & ~0x0FU) == ATI_DAC_INTERNAL)
+ {
+ int DacSpeed;
+ switch (pScreenInfo->bitsPerPixel)
+ {
+ case 15:
+ case 16:
+ DacSpeed = pGDev->dacSpeeds[DAC_BPP16];
+ break;
+
+ case 24:
+ DacSpeed = pGDev->dacSpeeds[DAC_BPP24];
+ break;
+
+ case 32:
+ DacSpeed = pGDev->dacSpeeds[DAC_BPP32];
+ break;
+
+ default:
+ DacSpeed = 0;
+ break;
+ }
+ if (!DacSpeed)
+ DacSpeed = pGDev->dacSpeeds[DAC_BPP8];
+ if (DacSpeed < ATIClockRange.maxClock)
+ {
+ int DefaultmaxClock = 135000;
+
+ if (pScreenInfo->depth > 8)
+ DefaultmaxClock = 80000;
+
+ if ((pATI->Chip >= ATI_CHIP_264VTB) &&
+ (pATI->Chip != ATI_CHIP_Mach64))
+ {
+ if (pATI->Chip >= ATI_CHIP_264VT4)
+ DefaultmaxClock = 230000;
+ else if (pATI->Chip >= ATI_CHIP_264VT3)
+ DefaultmaxClock = 200000;
+ else
+ DefaultmaxClock = 170000;
+ }
+ if (DacSpeed > DefaultmaxClock)
+ ATIClockRange.maxClock = DacSpeed;
+ else if (DefaultmaxClock < ATIClockRange.maxClock)
+ ATIClockRange.maxClock = DefaultmaxClock;
+ }
+ }
+ else switch(pATI->DAC)
+ {
+ case ATI_DAC_STG1700:
+ case ATI_DAC_STG1702:
+ case ATI_DAC_STG1703:
+ ATIClockRange.maxClock = 110000;
+ break;
+
+ default:
+ /*
+ * 80 MHz is too high in some cases. Limit 18800-x's to 40 MHz.
+ * Don't exceed the memory clock on VGA Wonder capables with less
+ * than 1 MB, if using a packed mode.
+ */
+ if ((pATI->Chip == ATI_CHIP_18800) ||
+ (pATI->Chip == ATI_CHIP_18800_1))
+ ATIClockRange.maxClock = 40000;
+ else if (pATI->CPIO_VGAWonder &&
+ (pATI->VideoRAM < 1024) &&
+ (pScreenInfo->depth >= 8))
+ ATIClockRange.maxClock =
+ (GetBits(BIOSByte(0x44U), 0x04U) * 5000) + 40000;
+ else
+ ATIClockRange.maxClock = 80000;
+ break;
+ }
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Maximum pixel clock: %.3f MHz.\n",
+ (double)ATIClockRange.maxClock / 1000.0);
+
+ /*
+ * Determine available pixel clock frequencies.
+ */
+
+ ATIClockPreInit(pScreenInfo, pATI, pGDev, &ATIClockRange);
+
+ /*
+ * Mode validation.
+ */
+
+ if ((pScreenInfo->depth >= 8) && (pATI->Chip >= ATI_CHIP_264CT))
+ minPitch = 8;
+ else if (pATI->CPIO_VGAWonder &&
+ (pATI->Chip <= ATI_CHIP_18800_1) &&
+ (pATI->VideoRAM == 256) &&
+ (pScreenInfo->depth >= 8))
+ minPitch = 32; /* Very strange, but true */
+ else
+ minPitch = 16;
+
+ pitchInc = minPitch;
+ if (pScreenInfo->depth >= 8)
+ pitchInc *= pScreenInfo->bitsPerPixel;
+
+ switch (pATI->NewHW.crtc)
+ {
+ case ATI_CRTC_VGA:
+ /*
+ * IBM's VGA doesn't allow for interlaced modes. Neither do ATI
+ * VGA Wonder adapters when the virtual width is too high. Here,
+ * only the requested virtual width can be factored in. The actual
+ * virtual width will be factored in later.
+ */
+ if ((pATI->Adapter <= ATI_ADAPTER_VGA) /* XXX ||
+ ((pATI->Chip <= ATI_CHIP_28800_6) &&
+ (pScreenInfo->display->virtualX > 2032)) */ )
+ ATIClockRange.interlaceAllowed = FALSE;
+
+ pScreenInfo->maxHValue = (0xFFU + 5) << 3; /* max HTotal */
+
+ /*
+ * The maximum VTotal value set here applies to all modes,
+ * including interlaced, doublescanned or multiscanned modes.
+ * Finer-grained checks are done in ATIValidateMode().
+ */
+ pScreenInfo->maxVValue = 0x03FFU + 2;
+ if (pATI->Adapter > ATI_ADAPTER_VGA)
+ {
+ pScreenInfo->maxVValue <<= 1;
+ if (ATIClockRange.interlaceAllowed &&
+ (pATI->Chip < ATI_CHIP_264CT))
+ pScreenInfo->maxVValue <<= 1;
+ }
+
+ /*
+ * 18800-x and 28800-x do not support interlaced modes when the
+ * scanline pitch is 2048 pixels or more.
+ */
+ if (pATI->Chip > ATI_CHIP_28800_6)
+ maxPitch = 0xFFU;
+ else if (minPitch == 32)
+ maxPitch = 0x3FU;
+ else
+ maxPitch = 0x7FU;
+
+ Strategy |= LOOKUP_CLKDIV2;
+
+ break;
+
+ case ATI_CRTC_MACH64:
+ pScreenInfo->maxHValue = (MaxBits(CRTC_H_TOTAL) + 1) << 3;
+
+ if (pATI->Chip < ATI_CHIP_264VT)
+ {
+ /*
+ * ATI finally fixed accelerated doublescanning in the 264VT
+ * and later. On 88800's, the bit is documented to exist, but
+ * only doubles the vertical timings. On the 264CT and 264ET,
+ * the bit is ignored.
+ */
+ ATIClockRange.doubleScanAllowed = FALSE;
+
+ /* CRTC_H_TOTAL is one bit narrower */
+ pScreenInfo->maxHValue >>= 1;
+ }
+
+ pScreenInfo->maxVValue = MaxBits(CRTC_V_TOTAL) + 1;
+
+ maxPitch = MaxBits(CRTC_PITCH);
+
+ break;
+
+ default:
+ break;
+ }
+
+ maxPitch *= minPitch;
+
+ i = xf86ValidateModes(pScreenInfo,
+ pScreenInfo->monitor->Modes, pScreenInfo->display->modes,
+ &ATIClockRange, NULL, minPitch, maxPitch, pitchInc, 0, 0,
+ pScreenInfo->display->virtualX, pScreenInfo->display->virtualY,
+ pATI->ApertureSize, Strategy);
+ if (i <= 0)
+ return FALSE;
+
+ /* Remove invalid modes */
+ xf86PruneDriverModes(pScreenInfo);
+
+ /* Set current mode to the first in the list */
+ pScreenInfo->currentMode = pScreenInfo->modes;
+
+ /* Print mode list */
+ xf86PrintModes(pScreenInfo);
+
+ /* Set display resolution */
+ xf86SetDpi(pScreenInfo, 0, 0);
+
+#ifdef XFree86LOADER
+ /* Load required modules */
+ if (!ATILoadModules(pScreenInfo))
+ return FALSE;
+#endif
+
+ /* Initialize for panning */
+ ATIAdjustPreInit(pScreenInfo, pATI);
+
+ /* Initialize CRTC code */
+ ATICRTCPreInit(pScreenInfo, pATI, &pATI->NewHW);
+
+ /* Relock registers */
+ ATILock(pATI);
+
+ if (!pScreenInfo->chipset || !*pScreenInfo->chipset)
+ pScreenInfo->chipset = (char *)ATIChipsetNames[0];
+
+ /* Generate noise if requested */
+ if (xf86GetVerbosity() > 3)
+ {
+ ATIPrintBIOS(pATI, BIOS, 0, BIOSSize);
+ xf86ErrorFVerb(4, "\n On server entry:\n");
+ ATIPrintRegisters(pATI);
+ }
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atipreinit.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atipreinit.h
new file mode 100644
index 000000000..507e3d268
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atipreinit.h
@@ -0,0 +1,32 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atipreinit.h,v 1.1 1999/07/06 11:38:34 dawes Exp $ */
+/*
+ * Copyright 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIPREINIT_H___
+#define ___ATIPREINIT_H___ 1
+
+#include "atiproto.h"
+#include "xf86str.h"
+
+extern Bool ATIPreInit FunctionPrototype((ScrnInfoPtr, int));
+
+#endif /* ___ATIPREINIT_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprint.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprint.c
new file mode 100644
index 000000000..2a82e450c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprint.c
@@ -0,0 +1,536 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiprint.c,v 1.5 1999/07/06 11:38:34 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "ati.h"
+#include "atiadapter.h"
+#include "atichip.h"
+#include "atidac.h"
+#include "atiprint.h"
+
+/*
+ * ATIPrintBIOS --
+ *
+ * Display various parts of the BIOS when the server is invoked with -verbose.
+ */
+void
+ATIPrintBIOS
+(
+ ATIPtr pATI,
+ const CARD8 *BIOS,
+ const unsigned int Start,
+ const unsigned int End
+)
+{
+ unsigned int Index = Start & ~(16U - 1U);
+
+ xf86ErrorFVerb(4, "\n BIOS data at 0x%08X:", Start + pATI->BIOSBase);
+
+ for (; Index < End; Index++)
+ {
+ if (!(Index & (4U - 1U)))
+ {
+ if (!(Index & (16U - 1U)))
+ xf86ErrorFVerb(4, "\n 0x%08X: ", Index + pATI->BIOSBase);
+ xf86ErrorFVerb(4, " ");
+ }
+ if (Index < Start)
+ xf86ErrorFVerb(4, " ");
+ else
+ xf86ErrorFVerb(4, "%02X", BIOS[Index]);
+ }
+
+ xf86ErrorFVerb(4, "\n");
+}
+
+/*
+ * ATIPrintIndexedRegisters --
+ *
+ * Display a set of indexed byte-size registers when the server is invoked with
+ * -verbose.
+ */
+static void
+ATIPrintIndexedRegisters
+(
+ const CARD16 Port,
+ const CARD8 StartIndex,
+ const CARD8 EndIndex,
+ const char *Name,
+ const CARD16 GenS1
+)
+{
+ int Index;
+
+ xf86ErrorFVerb(4, "\n\n %s register values:", Name);
+ for (Index = StartIndex; Index < EndIndex; Index++)
+ {
+ if (!(Index & (4U - 1U)))
+ {
+ if (!(Index & (16U - 1U)))
+ xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
+ xf86ErrorFVerb(4, " ");
+ }
+ if (Port == ATTRX)
+ (void)inb(GenS1); /* Reset flip-flop */
+ xf86ErrorFVerb(4, "%02X", GetReg(Port, Index));
+ }
+
+ if (Port == ATTRX)
+ {
+ (void)inb(GenS1); /* Reset flip-flop */
+ outb(ATTRX, 0x20U); /* Turn on PAS bit */
+ }
+}
+
+/*
+ * ATIPrintMach64Registers --
+ *
+ * Display a Mach64's main register bank when the server is invoked with
+ * -verbose.
+ */
+static void
+ATIPrintMach64Registers
+(
+ ATIPtr pATI,
+ CARD8 *crtc,
+ const char *Description
+)
+{
+ int Index, Step, Limit;
+ CARD32 IOValue;
+ CARD8 dac_read, dac_mask, dac_data, dac_write;
+
+ xf86ErrorFVerb(4, "\n\n Mach64 %s registers:", Description);
+ Limit = ATIIOPort(IOPortTag(0x1FU, 0x3FU));
+ Step = ATIIOPort(IOPortTag(0x01U, 0x01U)) - pATI->CPIOBase;
+ for (Index = pATI->CPIOBase; Index <= Limit; Index += Step)
+ {
+ if (!(((Index - pATI->CPIOBase) / Step) & 0x03U))
+ xf86ErrorFVerb(4, "\n 0x%04X: ", Index);
+ if (Index == pATI->CPIO_DAC_REGS)
+ {
+ dac_read = inb(pATI->CPIO_DAC_REGS + 3);
+ DACDelay;
+ dac_mask = inb(pATI->CPIO_DAC_REGS + 2);
+ DACDelay;
+ dac_data = inb(pATI->CPIO_DAC_REGS + 1);
+ DACDelay;
+ dac_write = inb(pATI->CPIO_DAC_REGS);
+ DACDelay;
+
+ xf86ErrorFVerb(4, " %02X%02X%02X%02X",
+ dac_read, dac_mask, dac_data, dac_write);
+
+ outb(pATI->CPIO_DAC_REGS + 2, dac_mask);
+ DACDelay;
+ outb(pATI->CPIO_DAC_REGS + 3, dac_read);
+ DACDelay;
+ }
+ else
+ {
+ IOValue = inl(Index);
+
+ if ((Index == pATI->CPIO_CRTC_GEN_CNTL) &&
+ (IOValue & CRTC_EXT_DISP_EN))
+ *crtc = ATI_CRTC_MACH64;
+
+ xf86ErrorFVerb(4, " %08X", IOValue);
+ }
+ }
+}
+
+/*
+ * ATIPrintMach64PLLRegisters --
+ *
+ * Display an integrated Mach64's PLL registers when the server is invoked with
+ * -verbose.
+ */
+static void
+ATIPrintMach64PLLRegisters
+(
+ ATIPtr pATI
+)
+{
+ int Index;
+
+ xf86ErrorFVerb(4, "\n\n Mach64 PLL registers:");
+ for (Index = 0; Index < 64; Index++)
+ {
+ if (!(Index & 3))
+ {
+ if (!(Index & 15))
+ xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
+ xf86ErrorFVerb(4, " ");
+ }
+ xf86ErrorFVerb(4, "%02X", ATIGetMach64PLLReg(Index));
+ }
+}
+
+/*
+ * ATIPrintRegisters --
+ *
+ * Display various registers when the server is invoked with -verbose.
+ */
+void
+ATIPrintRegisters
+(
+ ATIPtr pATI
+)
+{
+ pciVideoPtr pVideo;
+ pciConfigPtr pPCI;
+ int Index;
+ CARD32 lcd_index, tv_out_index, lcd_gen_ctrl;
+ CARD8 genmo, seq1 = 0;
+ CARD8 dac_read, dac_mask, dac_write;
+ CARD8 crtc = ATI_CRTC_VGA;
+
+ if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
+ {
+ xf86ErrorFVerb(4, "\n Miscellaneous output register value: 0x%02X.",
+ genmo = inb(R_GENMO));
+
+ if (genmo & 0x01U)
+ {
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ lcd_gen_ctrl = inl(pATI->CPIO_LCD_GEN_CTRL);
+
+ outl(pATI->CPIO_LCD_GEN_CTRL,
+ lcd_gen_ctrl & ~(SHADOW_EN | SHADOW_RW_EN));
+ ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
+ "Non-shadow colour CRT controller", 0);
+
+ outl(pATI->CPIO_LCD_GEN_CTRL,
+ lcd_gen_ctrl | (SHADOW_EN | SHADOW_RW_EN));
+ ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
+ "Shadow colour CRT controller", 0);
+
+ outl(pATI->CPIO_LCD_GEN_CTRL, lcd_gen_ctrl);
+ }
+ else if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL))
+ {
+ lcd_index = inl(pATI->CPIO_LCD_INDEX);
+ lcd_gen_ctrl = ATIGetLTProLCDReg(LCD_GEN_CNTL);
+
+ ATIPutLTProLCDReg(LCD_GEN_CNTL,
+ lcd_gen_ctrl & ~(SHADOW_EN | SHADOW_RW_EN));
+ ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
+ "Non-shadow colour CRT controller", 0);
+
+ ATIPutLTProLCDReg(LCD_GEN_CNTL,
+ lcd_gen_ctrl | (SHADOW_EN | SHADOW_RW_EN));
+ ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
+ "Shadow colour CRT controller", 0);
+
+ ATIPutLTProLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
+ outl(pATI->CPIO_LCD_INDEX, lcd_index);
+ }
+ else
+ ATIPrintIndexedRegisters(CRTX(ColourIOBase), 0, 64,
+ "Colour CRT controller", 0);
+ ATIPrintIndexedRegisters(ATTRX, 0, 32, "Attribute controller",
+ GENS1(ColourIOBase));
+ }
+ else
+ {
+ if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ lcd_gen_ctrl = inl(pATI->CPIO_LCD_GEN_CTRL);
+
+ outl(pATI->CPIO_LCD_GEN_CTRL,
+ lcd_gen_ctrl & ~(SHADOW_EN | SHADOW_RW_EN));
+ ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
+ "Non-shadow monochrome CRT controller", 0);
+
+ outl(pATI->CPIO_LCD_GEN_CTRL,
+ lcd_gen_ctrl | (SHADOW_EN | SHADOW_RW_EN));
+ ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
+ "Shadow monochrome CRT controller", 0);
+
+ outl(pATI->CPIO_LCD_GEN_CTRL, lcd_gen_ctrl);
+ }
+ else if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL))
+ {
+ lcd_index = inl(pATI->CPIO_LCD_INDEX);
+ lcd_gen_ctrl = ATIGetLTProLCDReg(LCD_GEN_CNTL);
+
+ ATIPutLTProLCDReg(LCD_GEN_CNTL,
+ lcd_gen_ctrl & ~(SHADOW_EN | SHADOW_RW_EN));
+ ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
+ "Non-shadow monochrome CRT controller", 0);
+
+ ATIPutLTProLCDReg(LCD_GEN_CNTL,
+ lcd_gen_ctrl | (SHADOW_EN | SHADOW_RW_EN));
+ ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
+ "Shadow monochrome CRT controller", 0);
+
+ ATIPutLTProLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
+ outl(pATI->CPIO_LCD_INDEX, lcd_index);
+ }
+ else
+ ATIPrintIndexedRegisters(CRTX(MonochromeIOBase), 0, 64,
+ "Monochrome CRT controller", 0);
+ ATIPrintIndexedRegisters(ATTRX, 0, 32, "Attribute controller",
+ GENS1(MonochromeIOBase));
+ }
+
+ ATIPrintIndexedRegisters(GRAX, 0, 16, "Graphics controller", 0);
+ ATIPrintIndexedRegisters(SEQX, 0, 8, "Sequencer", 0);
+
+ if (pATI->CPIO_VGAWonder)
+ ATIPrintIndexedRegisters(pATI->CPIO_VGAWonder,
+ xf86ServerIsOnlyProbing() ? 0x80U : pATI->VGAOffset, 0xC0U,
+ "ATI extended VGA", 0);
+ }
+
+ if (pATI->ChipHasSUBSYS_CNTL)
+ {
+ xf86ErrorFVerb(4, "\n\n 8514/A registers:");
+ for (Index = 0x02E8U; Index <= 0x0FEE8; Index += 0x0400U)
+ {
+ if (!((Index - 0x02E8U) & 0x0C00U))
+ xf86ErrorFVerb(4, "\n 0x%04X: ", Index);
+ xf86ErrorFVerb(4, " %04X", inw(Index));
+ }
+
+ if (pATI->Adapter >= ATI_ADAPTER_MACH8)
+ {
+ xf86ErrorFVerb(4, "\n\n Mach8/Mach32 registers:");
+ for (Index = 0x02EEU; Index <= 0x0FEEE; Index += 0x0400U)
+ {
+ if (!((Index - 0x02EEU) & 0x0C00U))
+ xf86ErrorFVerb(4, "\n 0x%04X: ", Index);
+ xf86ErrorFVerb(4, " %04X", inw(Index));
+ }
+ }
+ }
+ else if (pATI->Chip == ATI_CHIP_264LT)
+ {
+ lcd_gen_ctrl = inl(pATI->CPIO_LCD_GEN_CTRL);
+
+ outl(pATI->CPIO_LCD_GEN_CTRL,
+ lcd_gen_ctrl & ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN));
+ ATIPrintMach64Registers(pATI, &crtc, "non-shadow");
+
+ outl(pATI->CPIO_LCD_GEN_CTRL,
+ (lcd_gen_ctrl & ~CRTC_RW_SELECT) | (SHADOW_EN | SHADOW_RW_EN));
+ ATIPrintMach64Registers(pATI, &crtc, "shadow");
+
+ outl(pATI->CPIO_LCD_GEN_CTRL, lcd_gen_ctrl);
+
+ ATIPrintMach64PLLRegisters(pATI);
+ }
+ else if ((pATI->Chip == ATI_CHIP_264LTPRO) ||
+ (pATI->Chip == ATI_CHIP_264XL))
+ {
+ lcd_index = inl(pATI->CPIO_LCD_INDEX);
+ lcd_gen_ctrl = ATIGetLTProLCDReg(LCD_GEN_CNTL);
+
+ ATIPutLTProLCDReg(LCD_GEN_CNTL,
+ lcd_gen_ctrl & ~(CRTC_RW_SELECT | SHADOW_EN | SHADOW_RW_EN));
+ ATIPrintMach64Registers(pATI, &crtc, "non-shadow");
+
+ ATIPutLTProLCDReg(LCD_GEN_CNTL,
+ (lcd_gen_ctrl & ~CRTC_RW_SELECT) | (SHADOW_EN | SHADOW_RW_EN));
+ ATIPrintMach64Registers(pATI, &crtc, "shadow");
+
+ ATIPutLTProLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl | CRTC_RW_SELECT);
+ ATIPrintMach64Registers(pATI, &crtc, "secondary");
+
+ ATIPutLTProLCDReg(LCD_GEN_CNTL, lcd_gen_ctrl);
+
+ ATIPrintMach64PLLRegisters(pATI);
+
+ xf86ErrorFVerb(4, "\n\n LCD registers:");
+ for (Index = 0; Index < 16; Index++)
+ {
+ if (!(Index & 3))
+ xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
+ xf86ErrorFVerb(4, " %08X", ATIGetLTProLCDReg(Index));
+ }
+
+ outl(pATI->CPIO_LCD_INDEX, lcd_index);
+
+ tv_out_index = inl(pATI->CPIO_TV_OUT_INDEX);
+
+ xf86ErrorFVerb(4, "\n\n TV_OUT registers:");
+ for (Index = 0; Index < 256; Index++)
+ {
+ if (!(Index & 3))
+ xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
+ xf86ErrorFVerb(4, " %08X", ATIGetLTProTVReg(Index));
+ }
+
+ outl(pATI->CPIO_TV_OUT_INDEX, tv_out_index);
+ }
+ else if (pATI->Chip >= ATI_CHIP_88800GXC)
+ {
+ ATIPrintMach64Registers(pATI, &crtc,
+ (pATI->CPIODecoding == SPARSE_IO) ? "sparse" : "block");
+
+ if (pATI->Chip >= ATI_CHIP_264CT)
+ ATIPrintMach64PLLRegisters(pATI);
+ }
+
+ ATISetDACIOPorts(pATI, crtc);
+
+ /* Temporarily turn off CLKDIV2 while reading DAC's LUT */
+ if (pATI->Adapter == ATI_ADAPTER_NONISA)
+ {
+ seq1 = GetReg(SEQX, 0x01U);
+ if (seq1 & 0x08U)
+ PutReg(SEQX, 0x01U, seq1 & ~0x08U);
+ }
+
+ dac_read = inb(pATI->CPIO_DAC_READ);
+ DACDelay;
+ dac_write = inb(pATI->CPIO_DAC_WRITE);
+ DACDelay;
+ dac_mask = inb(pATI->CPIO_DAC_MASK);
+ DACDelay;
+
+ xf86ErrorFVerb(4, "\n\n"
+ " DAC read index: 0x%02X\n"
+ " DAC write index: 0x%02X\n"
+ " DAC mask: 0x%02X\n\n"
+ " DAC colour lookup table:",
+ dac_read, dac_write, dac_mask);
+
+ outb(pATI->CPIO_DAC_MASK, 0xFFU);
+ DACDelay;
+ outb(pATI->CPIO_DAC_READ, 0x00U);
+ DACDelay;
+
+ for (Index = 0; Index < 256; Index++)
+ {
+ if (!(Index & 3))
+ xf86ErrorFVerb(4, "\n 0x%02X:", Index);
+ xf86ErrorFVerb(4, " %02X", inb(pATI->CPIO_DAC_DATA));
+ DACDelay;
+ xf86ErrorFVerb(4, " %02X", inb(pATI->CPIO_DAC_DATA));
+ DACDelay;
+ xf86ErrorFVerb(4, " %02X", inb(pATI->CPIO_DAC_DATA));
+ DACDelay;
+ }
+
+ outb(pATI->CPIO_DAC_MASK, dac_mask);
+ DACDelay;
+ outb(pATI->CPIO_DAC_READ, dac_read);
+ DACDelay;
+
+ if ((pATI->Adapter == ATI_ADAPTER_NONISA) && (seq1 & 0x08U))
+ PutReg(SEQX, 0x01U, seq1);
+
+ if ((pVideo = pATI->PCIInfo))
+ {
+ pPCI = (pciConfigPtr)(pVideo->thisCard);
+ xf86ErrorFVerb(4, "\n\n PCI configuration registers:");
+ for (Index = 0; Index < 256; Index+= 4)
+ {
+ if (!(Index & 15))
+ xf86ErrorFVerb(4, "\n 0x%02X: ", Index);
+ xf86ErrorFVerb(4, " 0x%08X", pciReadLong(pPCI->tag, Index));
+ }
+ }
+
+ xf86ErrorFVerb(4, "\n\n");
+}
+
+/*
+ * A table to associate mode attributes with character strings.
+ */
+static const SymTabRec ModeAttributeNames[] =
+{
+ {V_PHSYNC, "+hsync"},
+ {V_NHSYNC, "-hsync"},
+ {V_PVSYNC, "+vsync"},
+ {V_NVSYNC, "-vsync"},
+ {V_PCSYNC, "+csync"},
+ {V_NCSYNC, "-csync"},
+ {V_INTERLACE, "interlace"},
+ {V_DBLSCAN, "doublescan"},
+ {V_CSYNC, "composite"},
+ {V_DBLCLK, "dblclk"},
+ {V_CLKDIV2, "clkdiv2"},
+ {0, NULL}
+};
+
+/*
+ * ATIPrintMode --
+ *
+ * This function displays a mode's timing information.
+ */
+void
+ATIPrintMode
+(
+ DisplayModePtr pMode
+)
+{
+ const SymTabRec *pSymbol = ModeAttributeNames;
+ int flags = pMode->Flags;
+ double mClock, hSync, vRefresh;
+
+ mClock = (double)pMode->SynthClock;
+ hSync = mClock / pMode->HTotal;
+ vRefresh = (hSync * 1000.0) / pMode->VTotal;
+ if (flags & V_INTERLACE)
+ vRefresh *= 2.0;
+ if (flags & V_DBLSCAN)
+ vRefresh /= 2.0;
+ if (pMode->VScan > 1)
+ vRefresh /= pMode->VScan;
+
+ xf86ErrorFVerb(4, " Dot clock: %7.3f MHz\n", mClock / 1000.0);
+ xf86ErrorFVerb(4, " Horizontal sync: %7.3f kHz\n", hSync);
+ xf86ErrorFVerb(4, " Vertical refresh: %7.3f Hz (%s)\n", vRefresh,
+ (flags & V_INTERLACE) ? "I" : "NI");
+ if ((pMode->ClockIndex >= 0) && (pMode->ClockIndex < MAXCLOCKS))
+ xf86ErrorFVerb(4, " Clock index: %d\n", pMode->ClockIndex);
+ xf86ErrorFVerb(4, " Horizontal timings: %4d %4d %4d %4d\n"
+ " Vertical timings: %4d %4d %4d %4d\n",
+ pMode->HDisplay, pMode->HSyncStart, pMode->HSyncEnd, pMode->HTotal,
+ pMode->VDisplay, pMode->VSyncStart, pMode->VSyncEnd, pMode->VTotal);
+
+ if (flags & V_HSKEW)
+ {
+ flags &= ~V_HSKEW;
+ xf86ErrorFVerb(4, " Horizontal skew: %4d\n", pMode->HSkew);
+ }
+
+ if (pMode->VScan >= 1)
+ xf86ErrorFVerb(4, " Vertical scan: %4d\n", pMode->VScan);
+
+ xf86ErrorFVerb(4, " Flags: ");
+ for (; pSymbol->token; pSymbol++)
+ {
+ if (flags & pSymbol->token)
+ {
+ xf86ErrorFVerb(4, " %s", pSymbol->name);
+ if (!(flags &= ~pSymbol->token))
+ break;
+ }
+ }
+ xf86ErrorFVerb(4, "\n");
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprint.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprint.h
new file mode 100644
index 000000000..44958e896
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprint.h
@@ -0,0 +1,37 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiprint.h,v 1.3 1999/07/06 11:38:34 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIPRINT_H___
+#define ___ATIPRINT_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+#include "xf86str.h"
+
+extern void ATIPrintBIOS FunctionPrototype((ATIPtr, const CARD8 *,
+ const unsigned int,
+ const unsigned int));
+extern void ATIPrintRegisters FunctionPrototype((ATIPtr));
+extern void ATIPrintMode FunctionPrototype((DisplayModePtr));
+
+#endif /* ___ATIPRINT_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atipriv.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atipriv.h
new file mode 100644
index 000000000..43720c5cb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atipriv.h
@@ -0,0 +1,31 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atipriv.h,v 1.1 1999/07/06 11:38:34 dawes Exp $ */
+/*
+ * Copyright 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIPRIV_H___
+#define ___ATIPRIV_H___ 1
+
+/* Forward pointer definitions */
+typedef struct _ATIHWRec *ATIHWPtr;
+typedef struct _ATIRec *ATIPtr;
+
+#endif /* ___ATIPRIV_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c
new file mode 100644
index 000000000..4ff6dad1e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c
@@ -0,0 +1,1703 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.c,v 1.10 1999/08/21 13:48:32 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "ati.h"
+#include "atiadapter.h"
+#include "atiadjust.h"
+#include "atibios.h"
+#include "atibus.h"
+#include "atichip.h"
+#include "aticonsole.h"
+#include "atiident.h"
+#include "atiio.h"
+#include "atipreinit.h"
+#include "atiprobe.h"
+#include "atiscreen.h"
+#include "ativalid.h"
+#include "ativersion.h"
+
+/*
+ * NOTES:
+ *
+ * - The driver private structures (ATIRec's) are allocated here, rather than
+ * in ATIPreInit(). This allows ATIProbe() to pass information to later
+ * stages.
+ * - A minor point, perhaps, is that XF86Config Chipset names denote functional
+ * levels, rather than specific graphics controller chips.
+ * - ATIProbe() does not call xf86MatchPciInstances(), because ATIProbe()
+ * should be able to match a mix of PCI and non-PCI devices to XF86Config
+ * Device sections. Also, PCI configuration space for Mach32's is to be
+ * largely ignored.
+ */
+
+/*
+ * Definitions for I/O conflict avoidance.
+ */
+#define LongPort(_Port) GetBits((_Port), PCIGETIO(SPARSE_IO_BASE))
+#define DetectedVGA (1 << 0)
+#define Detected8514A (1 << 1)
+#define DetectedMach64 (1 << 2)
+#define Allowed (1 << 3)
+#define DoProbe (1 << 4)
+typedef struct
+{
+ CARD16 Base;
+ CARD8 Size;
+ CARD8 Flag;
+} PortRec, *PortPtr;
+
+/*
+ * An internal structure definition to facilitate the matching of detected
+ * adapters to XF86Config Device sections.
+ */
+typedef struct _ATIGDev
+{
+ GDevPtr pGDev;
+ int iATIPtr;
+ CARD8 Chipset;
+} ATIGDev, *ATIGDevPtr;
+
+/*
+ * ATIScanPCIBases --
+ *
+ * This function loops though a device's PCI registered bases and accumulates
+ * a list of block I/O bases in use in the system.
+ */
+static void
+ATIScanPCIBases
+(
+ PortPtr *PCIPorts,
+ int *nPCIPort,
+ const CARD32 *pBase,
+ const int *pSize,
+ const CARD8 ProbeFlag
+)
+{
+ int i, j;
+ CARD16 Base;
+
+ for (i = 6; --i >= 0; pBase++, pSize++)
+ {
+ if (*pBase & PCI_MAP_IO)
+ {
+ Base = *pBase & ~IO_BYTE_SELECT;
+ for (j = 0; ; j++)
+ {
+ if (j >= *nPCIPort)
+ {
+ (*nPCIPort)++;
+ *PCIPorts = (PortPtr)xnfrealloc(*PCIPorts,
+ *nPCIPort * SizeOf(PortRec));
+ (*PCIPorts)[j].Base = Base;
+ (*PCIPorts)[j].Size = (CARD8)*pSize;
+ (*PCIPorts)[j].Flag = ProbeFlag;
+ break;
+ }
+
+ if (Base == (*PCIPorts)[j].Base)
+ break;
+ }
+
+ continue;
+ }
+
+ /* Allow for 64-bit addresses */
+ if (!PCI_MAP_IS64BITMEM(*pBase))
+ continue;
+
+ i--;
+ pBase++;
+ pSize++;
+ }
+}
+
+/*
+ * ATICheckSparseIOBases --
+ *
+ * This function checks whether a sparse I/O base can safely be probed.
+ */
+static CARD8
+ATICheckSparseIOBases
+(
+ CARD8 *ProbeFlags,
+ const CARD16 IOBase,
+ const int Count,
+ const Bool Override
+)
+{
+ CARD32 FirstPort = LongPort(IOBase),
+ LastPort = LongPort(IOBase + Count - 1);
+
+ for (; FirstPort <= LastPort; FirstPort++)
+ {
+ CARD8 ProbeFlag = ProbeFlags[FirstPort];
+
+ if (ProbeFlag & DoProbe)
+ continue;
+
+ if (!(ProbeFlag & Allowed))
+ return ProbeFlag;
+
+ if (Override)
+ continue;
+
+ /* User might wish to override this decision */
+ xf86Msg(X_WARNING,
+ ATI_NAME ": Sparse I/O base 0x%04X not probed." ATI_README,
+ IOBase);
+ return Allowed;
+ }
+
+ return DoProbe;
+}
+
+/*
+ * ATIClaimSparseIOBases --
+ *
+ * This function updates the sparse I/O base table with information from the
+ * hardware probes.
+ */
+static void
+ATIClaimSparseIOBases
+(
+ CARD8 *ProbeFlags,
+ const CARD16 IOBase,
+ const int Count,
+ const CARD8 ProbeFlag
+)
+{
+ CARD32 FirstPort = LongPort(IOBase),
+ LastPort = LongPort(IOBase + Count - 1);
+
+ for (; FirstPort <= LastPort; FirstPort++)
+ ProbeFlags[FirstPort] = ProbeFlag;
+}
+
+/*
+ * ATIVGAProbe --
+ *
+ * This function looks for an IBM standard VGA, or clone, and sets
+ * pATI->VGAAdapter if one is found.
+ */
+static ATIPtr
+ATIVGAProbe
+(
+ ATIPtr pVGA
+)
+{
+ CARD8 IOValue1, IOValue2, IOValue3;
+
+ if (!pVGA)
+ pVGA = (ATIPtr)xnfcalloc(1, SizeOf(ATIRec));
+
+ /*
+ * VGA has one more attribute register than EGA. See if it can be read and
+ * written. Note that the CRTC registers are not used here, so there's no
+ * need to unlock them.
+ */
+ ATISetVGAIOBase(pVGA, inb(R_GENMO));
+ (void) inb(GENS1(pVGA->CPIO_VGABase));
+ IOValue1 = inb(ATTRX);
+ (void) inb(GENS1(pVGA->CPIO_VGABase));
+ IOValue2 = GetReg(ATTRX, 0x14U | 0x20U);
+ outb(ATTRX, IOValue2 ^ 0x0FU);
+ IOValue3 = GetReg(ATTRX, 0x14U | 0x20U);
+ outb(ATTRX, IOValue2);
+ outb(ATTRX, IOValue1);
+ (void) inb(GENS1(pVGA->CPIO_VGABase));
+ if (IOValue3 == (IOValue2 ^ 0x0FU))
+ {
+ /* VGA device detected */
+ if (pVGA->Chip == ATI_CHIP_NONE)
+ pVGA->Chip = ATI_CHIP_VGA;
+ if (pVGA->VGAAdapter == ATI_ADAPTER_NONE)
+ pVGA->VGAAdapter = ATI_ADAPTER_VGA;
+ if (pVGA->Adapter == ATI_ADAPTER_NONE)
+ pVGA->Adapter = ATI_ADAPTER_VGA;
+ }
+ else
+ pVGA->VGAAdapter = ATI_ADAPTER_NONE;
+
+ return pVGA;
+}
+
+/*
+ * ATIVGAWonderProbe --
+ *
+ * This function determines if ATI extended VGA registers can be accessed
+ * through the I/O port specified by pATI->CPIO_VGAWonder. If not, the
+ * function resets pATI->CPIO_VGAWonder to zero.
+ */
+static void
+ATIVGAWonderProbe
+(
+ ATIPtr pATI,
+ ATIPtr p8514,
+ CARD8 *ProbeFlags
+)
+{
+ CARD8 IOValue1, IOValue2, IOValue3, IOValue4, IOValue5, IOValue6;
+
+ switch (ATICheckSparseIOBases(ProbeFlags, pATI->CPIO_VGAWonder, 2, TRUE))
+ {
+ case 0:
+ xf86Msg(X_WARNING,
+ ATI_NAME ": Expected VGA Wonder capability could not be"
+ " detected at I/O port 0x%04X because it would conflict with"
+ " a non-video PCI device." ATI_README, pATI->CPIO_VGAWonder);
+ pATI->CPIO_VGAWonder = 0;
+ break;
+
+ case Detected8514A:
+ xf86Msg(X_WARNING,
+ ATI_NAME ": Expected VGA Wonder capability could not be"
+ " detected at I/O port 0x%04X because it would conflict with"
+ " a %s %s." ATI_README, pATI->CPIO_VGAWonder,
+ ATIBusNames[p8514->BusType], ATIAdapterNames[p8514->Adapter]);
+ pATI->CPIO_VGAWonder = 0;
+ break;
+
+ case DetectedMach64:
+ xf86Msg(X_WARNING,
+ ATI_NAME ": Expected VGA Wonder capability could not be"
+ " detected at I/O port 0x%04X because it would conflict with"
+ " a Mach64." ATI_README, pATI->CPIO_VGAWonder);
+ pATI->CPIO_VGAWonder = 0;
+ break;
+
+ case DetectedVGA:
+ default: /* Must be DoProbe */
+ /*
+ * Register 0xBB is used by the BIOS to keep track of various
+ * things (monitor type, etc.). Except for 18800-x's, register
+ * 0xBC must be zero and causes the adapter to enter a test mode
+ * when written to with a non-zero value.
+ */
+ IOValue1 = inb(pATI->CPIO_VGAWonder);
+ IOValue2 = ATIGetExtReg(IOValue1);
+ IOValue3 = ATIGetExtReg(0xBBU);
+ ATIPutExtReg(0xBBU, IOValue3 ^ 0xAAU);
+ IOValue4 = ATIGetExtReg(0xBBU);
+ ATIPutExtReg(0xBBU, IOValue3 ^ 0x55U);
+ IOValue5 = ATIGetExtReg(0xBBU);
+ ATIPutExtReg(0xBBU, IOValue3);
+ if (pATI->Chip <= ATI_CHIP_18800_1)
+ IOValue6 = 0;
+ else
+ IOValue6 = ATIGetExtReg(0xBCU);
+ ATIPutExtReg(IOValue1, IOValue2);
+ if ((IOValue4 == (IOValue3 ^ 0xAAU)) &&
+ (IOValue5 == (IOValue3 ^ 0x55U)) &&
+ (IOValue6 == 0))
+ break;
+
+ xf86Msg(X_WARNING,
+ ATI_NAME ": Expected VGA Wonder capability at I/O port 0x%04X"
+ " was not detected." ATI_README);
+ pATI->CPIO_VGAWonder = 0;
+ break;
+ }
+}
+
+/*
+ * ATI8514Probe --
+ *
+ * This function looks for an 8514/A compatible and returns an ATIRec if one is
+ * found. The function also determines whether or not the detected 8514/A
+ * compatible device is actually a Mach8 or Mach32, and sets pATI->Adapter
+ * accordingly.
+ */
+static ATIPtr
+ATI8514Probe
+(
+ pciVideoPtr pVideo
+)
+{
+ ATIPtr pATI = NULL;
+ CARD16 IOValue1, IOValue2;
+
+ /*
+ * Save register value to be modified, just in case there is no 8514/A
+ * compatible accelerator. Note that, in more ways than one,
+ * SUBSYS_STAT == SUBSYS_CNTL.
+ */
+ IOValue1 = inw(SUBSYS_STAT);
+ IOValue2 = IOValue1 & _8PLANE;
+
+ /* Reset any 8514/A compatible adapter that might be present */
+ outw(SUBSYS_CNTL, IOValue2 | (GPCTRL_RESET | CHPTEST_NORMAL));
+ outw(SUBSYS_CNTL, IOValue2 | (GPCTRL_ENAB | CHPTEST_NORMAL |
+ RVBLNKFLG | RPICKFLAG | RINVALIDIO | RGPIDLE));
+
+ /* Probe for an 8514/A compatible */
+ IOValue2 = inw(ERR_TERM);
+ outw(ERR_TERM, 0x5A5AU);
+ ProbeWaitIdleEmpty();
+ if (inw(ERR_TERM) == 0x5A5AU)
+ {
+ outw(ERR_TERM, 0x2525U);
+ if (inw(ERR_TERM) == 0x2525U)
+ {
+ pATI = (ATIPtr)xnfcalloc(1, SizeOf(ATIRec));
+ pATI->Adapter = ATI_ADAPTER_8514A;
+ pATI->ChipHasSUBSYS_CNTL = TRUE;
+ pATI->PCIInfo = pVideo;
+ }
+ }
+ outw(ERR_TERM, IOValue2);
+
+ /* Restore register value clobbered by 8514/A reset attempt */
+ if (!pATI)
+ {
+ outw(SUBSYS_CNTL, IOValue1);
+ return NULL;
+ }
+
+ /* Ensure and Mach8 or Mach32 is not in 8514/A emulation mode */
+ IOValue1 = inw(CLOCK_SEL);
+ outw(CLOCK_SEL, IOValue1);
+ ProbeWaitIdleEmpty();
+
+ IOValue1 = IOValue2 = inw(ROM_ADDR_1);
+ outw(ROM_ADDR_1, 0x5555U);
+ ProbeWaitIdleEmpty();
+ if (inw(ROM_ADDR_1) == 0x5555U)
+ {
+ outw(ROM_ADDR_1, 0x2A2AU);
+ ProbeWaitIdleEmpty();
+ if (inw(ROM_ADDR_1) == 0x2A2AU)
+ pATI->Adapter = ATI_ADAPTER_MACH8;
+ }
+ outw(ROM_ADDR_1, IOValue1);
+
+ if (pATI->Adapter == ATI_ADAPTER_MACH8)
+ {
+ /* A Mach8 or Mach32 has been detected */
+ IOValue1 = inw(READ_SRC_X);
+ outw(DESTX_DIASTP, 0xAAAAU);
+ ProbeWaitIdleEmpty();
+ if (inw(READ_SRC_X) == 0x02AAU)
+ pATI->Adapter = ATI_ADAPTER_MACH32;
+
+ outw(DESTX_DIASTP, 0x5555U);
+ ProbeWaitIdleEmpty();
+ if (inw(READ_SRC_X) == 0x0555U)
+ {
+ if (pATI->Adapter != ATI_ADAPTER_MACH32)
+ pATI->Adapter = ATI_ADAPTER_8514A;
+ }
+ else
+ {
+ if (pATI->Adapter != ATI_ADAPTER_MACH8)
+ pATI->Adapter = ATI_ADAPTER_8514A;
+ }
+ outw(DESTX_DIASTP, IOValue1);
+ }
+
+ switch (pATI->Adapter)
+ {
+ case ATI_ADAPTER_8514A:
+ pATI->Coprocessor = ATI_CHIP_8514A;
+ IOValue1 = inb(EXT_CONFIG_3);
+ outb(EXT_CONFIG_3, IOValue1 & 0x0FU);
+ if (!(inb(EXT_CONFIG_3) & 0xF0U))
+ {
+ outb(EXT_CONFIG_3, IOValue1 | 0xF0U);
+ if ((inb(EXT_CONFIG_3) & 0xF0U) == 0xF0U)
+ pATI->Coprocessor = ATI_CHIP_CT480;
+ }
+ outb(EXT_CONFIG_3, IOValue1);
+ break;
+
+ case ATI_ADAPTER_MACH8:
+ pATI->Coprocessor = ATI_CHIP_38800_1;
+ if (inw(CONFIG_STATUS_1) & MC_BUS)
+ pATI->BusType = ATI_BUS_MCA16;
+ break;
+
+ case ATI_ADAPTER_MACH32:
+ IOValue1 = inw(CONFIG_STATUS_1);
+ pATI->BusType = GetBits(IOValue1, BUS_TYPE);
+ pATI->BIOSBase = 0x000C0000U +
+ (GetBits(IOValue2, BIOS_BASE_SEGMENT) << 11);
+ if (!(IOValue1 & (_8514_ONLY | CHIP_DIS)))
+ {
+ pATI->VGAAdapter = ATI_ADAPTER_MACH32;
+ if ((ATIReadBIOS(pATI, &pATI->CPIO_VGAWonder, 0x10U,
+ SizeOf(pATI->CPIO_VGAWonder)) <
+ SizeOf(pATI->CPIO_VGAWonder)) ||
+ !(pATI->CPIO_VGAWonder &= SPARSE_IO_PORT))
+ pATI->CPIO_VGAWonder = 0x01CEU;
+ pATI->VGAOffset = 0x80U;
+ }
+
+ ATIMach32ChipID(pATI);
+ break;
+
+ default:
+ break;
+ }
+
+ return pATI;
+}
+
+/*
+ * ATIMach64Probe --
+ *
+ * This function looks for a Mach64 at a particular I/O base address and
+ * returns an ATIRec if one is found.
+ */
+static ATIPtr
+ATIMach64Probe
+(
+ const CARD16 IOBase,
+ const CARD8 IODecoding,
+ const CARD16 ChipType,
+ const ATIChipType Chip
+)
+{
+ ATIPtr pATI;
+ CARD32 IOValue, bus_cntl, gen_test_cntl;
+ CARD16 IOPort;
+
+ pATI = (ATIPtr)xnfcalloc(1, SizeOf(ATIRec));
+ pATI->CPIOBase = IOBase;
+ pATI->CPIODecoding = IODecoding;
+
+ /* Make sure any Mach64 is not in some weird state */
+ pATI->CPIO_BUS_CNTL = ATIIOPort(BUS_CNTL);
+ bus_cntl = inl(pATI->CPIO_BUS_CNTL);
+ if (Chip < ATI_CHIP_264VTB)
+ outl(pATI->CPIO_BUS_CNTL,
+ (bus_cntl & ~(BUS_HOST_ERR_INT_EN | BUS_FIFO_ERR_INT_EN)) |
+ (BUS_HOST_ERR_INT | BUS_FIFO_ERR_INT));
+ else
+ outl(pATI->CPIO_BUS_CNTL, (bus_cntl & ~BUS_HOST_ERR_INT_EN) |
+ BUS_HOST_ERR_INT);
+
+ pATI->CPIO_GEN_TEST_CNTL = ATIIOPort(GEN_TEST_CNTL);
+ gen_test_cntl = inl(pATI->CPIO_GEN_TEST_CNTL);
+ IOValue = gen_test_cntl &
+ (GEN_OVR_OUTPUT_EN | GEN_OVR_POLARITY | GEN_CUR_EN | GEN_BLOCK_WR_EN);
+ outl(pATI->CPIO_GEN_TEST_CNTL, IOValue | GEN_GUI_EN);
+ outl(pATI->CPIO_GEN_TEST_CNTL, IOValue);
+ outl(pATI->CPIO_GEN_TEST_CNTL, IOValue | GEN_GUI_EN);
+
+ /* See if a Mach64 answers */
+ IOPort = ATIIOPort(SCRATCH_REG0);
+ IOValue = inl(IOPort);
+
+ /* Test odd bits */
+ outl(IOPort, 0x55555555U);
+ if (inl(IOPort) == 0x55555555U)
+ {
+ /* Test even bits */
+ outl(IOPort, 0xAAAAAAAAU);
+ if (inl(IOPort) == 0xAAAAAAAAU)
+ {
+ /*
+ * *Something* has a R/W 32-bit register at this I/O address. Try
+ * to make sure it's a Mach64. The following assumes that ATI will
+ * not be producing any more adapters that do not register
+ * themselves in PCI configuration space.
+ */
+ ATIMach64ChipID(pATI, ChipType);
+ if ((pATI->Chip != ATI_CHIP_Mach64) || (IODecoding == BLOCK_IO))
+ pATI->Adapter = ATI_ADAPTER_MACH64;
+ }
+ }
+
+ /* Restore clobbered register value */
+ outl(IOPort, IOValue);
+
+ /* If no Mach64 was detected, return now */
+ if (pATI->Adapter != ATI_ADAPTER_MACH64)
+ {
+ outl(pATI->CPIO_GEN_TEST_CNTL, gen_test_cntl);
+ outl(pATI->CPIO_BUS_CNTL, bus_cntl);
+ xfree(pATI);
+ return NULL;
+ }
+
+ /* Determine legacy BIOS address */
+ pATI->BIOSBase = 0x000C0000U +
+ (GetBits(inl(ATIIOPort(SCRATCH_REG1)), BIOS_BASE_SEGMENT) << 11);
+
+ /* Determine VGA capability */
+ IOValue = inl(ATIIOPort(CONFIG_STATUS64_0));
+ if (pATI->Chip < ATI_CHIP_264CT)
+ {
+ pATI->BusType = GetBits(IOValue, CFG_BUS_TYPE);
+ IOValue &= (CFG_VGA_EN | CFG_CHIP_EN);
+ if (pATI->Chip == ATI_CHIP_88800CX)
+ IOValue |= CFG_VGA_EN;
+ if (IOValue == (CFG_VGA_EN | CFG_CHIP_EN))
+ {
+ pATI->VGAAdapter = ATI_ADAPTER_MACH64;
+ pATI->CPIO_VGAWonder = 0x01CEU;
+ pATI->VGAOffset = 0x80U;
+ }
+ }
+ else
+ {
+ if ((pATI->Chip < ATI_CHIP_264VT) || (IOValue & CFG_VGA_EN_T))
+ pATI->VGAAdapter = ATI_ADAPTER_MACH64;
+ }
+
+ return pATI;
+}
+
+/*
+ * ATIAssignVGA --
+ *
+ * This function is called to associate a VGA interface with an accelerator.
+ * This is done by temporarily configuring the accelerator to route VGA RAMDAC
+ * I/O through the accelerator's RAMDAC. A value is then written through the
+ * VGA DAC ports and a check is made to see if the same value shows up on the
+ * accelerator side.
+ */
+static void
+ATIAssignVGA
+(
+ ATIPtr *ppVGA,
+ ATIPtr pATI,
+ ATIPtr p8514,
+ CARD8 *ProbeFlags
+)
+{
+ ATIPtr pVGA = *ppVGA;
+ CARD8 OldDACMask;
+
+ /* Assume unassignable VGA */
+ pATI->VGAAdapter = ATI_ADAPTER_NONE;
+
+ /* If no assignable VGA, return now */
+ if ((pATI != pVGA) && (!pVGA || (pVGA->Adapter > ATI_ADAPTER_VGA)))
+ return;
+
+ switch (pATI->Adapter)
+ {
+ case ATI_ADAPTER_8514A:
+ {
+ /*
+ * Assumption: Bit DISABPASSTHRU in ADVFUNC_CNTL is already
+ * off.
+ */
+ OldDACMask = inb(VGA_DAC_MASK);
+
+ if (inb(DAC_MASK) == OldDACMask)
+ {
+ outb(VGA_DAC_MASK, 0xA5U);
+ if (inb(DAC_MASK) == 0xA5U)
+ pATI->VGAAdapter = ATI_ADAPTER_VGA;
+ }
+
+ outb(VGA_DAC_MASK, OldDACMask);
+ }
+ break;
+
+ case ATI_ADAPTER_MACH8:
+ {
+ CARD16 ClockSel = inw(CLOCK_SEL);
+
+ if (ClockSel & DISABPASSTHRU)
+ outw(CLOCK_SEL, ClockSel & ~DISABPASSTHRU);
+
+ ProbeWaitIdleEmpty();
+
+ OldDACMask = inb(VGA_DAC_MASK);
+
+ if (inb(DAC_MASK) == OldDACMask)
+ {
+ outb(VGA_DAC_MASK, 0xA5U);
+ if (inb(DAC_MASK) == 0xA5U)
+ pATI->VGAAdapter = ATI_ADAPTER_VGA;
+ }
+
+ outb(VGA_DAC_MASK, OldDACMask);
+
+ if (ClockSel & DISABPASSTHRU)
+ outw(CLOCK_SEL, ClockSel);
+ }
+ break;
+
+ case ATI_ADAPTER_MACH32:
+ {
+ CARD16 ClockSel = inw(CLOCK_SEL),
+ MiscOptions = inw(MISC_OPTIONS);
+
+ if (ClockSel & DISABPASSTHRU)
+ outw(CLOCK_SEL, ClockSel & ~DISABPASSTHRU);
+ if (MiscOptions & (DISABLE_VGA | DISABLE_DAC))
+ outw(MISC_OPTIONS,
+ MiscOptions & ~(DISABLE_VGA | DISABLE_DAC));
+
+ ProbeWaitIdleEmpty();
+
+ OldDACMask = inb(VGA_DAC_MASK);
+
+ if (inb(DAC_MASK) == OldDACMask)
+ {
+ outb(VGA_DAC_MASK, 0xA5U);
+ if (inb(DAC_MASK) == 0xA5U)
+ pATI->VGAAdapter = ATI_ADAPTER_MACH32;
+ }
+
+ outb(VGA_DAC_MASK, OldDACMask);
+
+ if (ClockSel & DISABPASSTHRU)
+ outw(CLOCK_SEL, ClockSel);
+ if (MiscOptions & (DISABLE_VGA | DISABLE_DAC))
+ outw(MISC_OPTIONS, MiscOptions);
+ }
+ break;
+
+ case ATI_ADAPTER_MACH64:
+ {
+ CARD16 DACMaskPort = ATIIOPort(DAC_REGS) + 2,
+ DACCntlPort = ATIIOPort(DAC_CNTL);
+ CARD32 DACCntl = inl(DACCntlPort);
+
+ if (!(DACCntl & DAC_VGA_ADR_EN))
+ outl(DACCntlPort, DACCntl | DAC_VGA_ADR_EN);
+
+ OldDACMask = inb(VGA_DAC_MASK);
+
+ if (inb(DACMaskPort) == OldDACMask)
+ {
+ outb(VGA_DAC_MASK, 0xA5U);
+ if (inb(DACMaskPort) == 0xA5U)
+ pATI->VGAAdapter = ATI_ADAPTER_MACH64;
+ }
+
+ outb(VGA_DAC_MASK, OldDACMask);
+
+ if (!(DACCntl & DAC_VGA_ADR_EN))
+ outl(DACCntlPort, DACCntl);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (pATI->VGAAdapter == ATI_ADAPTER_NONE)
+ {
+ pATI->CPIO_VGAWonder = 0;
+ return;
+ }
+
+ if (pATI->CPIO_VGAWonder)
+ {
+ ATIVGAWonderProbe(pATI, p8514, ProbeFlags);
+ if (!pATI->CPIO_VGAWonder)
+ {
+ /*
+ * Some adapters are reputed to append ATI extended VGA registers
+ * to the VGA Graphics controller registers.
+ */
+ pATI->CPIO_VGAWonder = GRAX;
+ ATIVGAWonderProbe(pATI, p8514, ProbeFlags);
+ }
+ }
+
+ if (pATI == pVGA)
+ {
+ pATI->SharedVGA = TRUE;
+ return;
+ }
+
+ /* Assign the VGA to this adapter */
+ xfree(pVGA);
+ *ppVGA = pATI;
+}
+
+/*
+ * ATIClaimVGA --
+ *
+ * Attempt to assign a non-shareable VGA to an accelerator. If successful,
+ * update ProbeFlags array.
+ */
+static void
+ATIClaimVGA
+(
+ ATIPtr *ppVGA,
+ ATIPtr pATI,
+ ATIPtr p8514,
+ CARD8 *ProbeFlags,
+ int Detected
+)
+{
+ ATIAssignVGA(ppVGA, pATI, p8514, ProbeFlags);
+ if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
+ {
+ ATIClaimSparseIOBases(ProbeFlags, MonochromeIOBase, 48, Detected);
+ if (pATI->CPIO_VGAWonder)
+ ATIClaimSparseIOBases(ProbeFlags, pATI->CPIO_VGAWonder, 2,
+ Detected);
+ }
+}
+
+/*
+ * ATIFindVGA --
+ *
+ * This function determines if a VGA associated with an ATI PCI adapter is
+ * shareable.
+ */
+static void
+ATIFindVGA
+(
+ ATIPtr *ppVGA,
+ ATIPtr *ppATI,
+ ATIPtr p8514,
+ CARD8 *ProbeFlags
+)
+{
+ ATIPtr pATI = *ppATI;
+
+ if (*ppVGA)
+ ATIAssignVGA(ppVGA, pATI, p8514, ProbeFlags);
+ else
+ {
+ pATI = ATIVGAProbe(pATI);
+ if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
+ ATIAssignVGA(ppATI, pATI, p8514, ProbeFlags);
+ }
+}
+
+/*
+ * ATIProbe --
+ *
+ * This function is called once, at the start of the first server generation to
+ * do a minimal probe for supported hardware.
+ */
+Bool
+ATIProbe
+(
+ DriverPtr pDriver,
+ int flags
+)
+{
+ ATIPtr pATI, *ATIPtrs = NULL, pVGA, p8514 = NULL;
+ ATIPtr pMach64[3] = {NULL, NULL, NULL};
+ GDevPtr *GDevs, pGDev;
+ pciVideoPtr pVideo, *xf86PciVideoInfo = xf86GetPciVideoInfo();
+ pciConfigPtr pPCI, *xf86PciInfo = xf86GetPciConfigInfo();
+ ATIGDev *ATIGDevs, *pATIGDev;
+ ScrnInfoPtr pScreenInfo;
+ PortPtr PCIPorts = NULL;
+ CARD32 PciReg;
+ int i, j, k;
+ int nGDev, nATIGDev = 0, nATIPtr = 0, nPCIPort = 0;
+ int nScreen = 0;
+ int Chipset;
+ CARD8 fChipsets[ATI_CHIPSET_MAX];
+ ATIChipType Chip;
+ static const CARD16 Mach64SparseIOBases[] = {0x02ECU, 0x01CCU, 0x01C8U};
+ CARD8 ProbeFlags[LongPort(SPARSE_IO_BASE) + 1];
+
+ unsigned long BIOSBase;
+ static const CARD8 ATISignature[] = " 761295520";
+# define SignatureSize 10
+# define PrefixSize 0x50U
+# define BIOSSignature 0x30U
+ CARD8 BIOS[PrefixSize];
+# define BIOSWord(_n) (*((CARD16 *)(BIOS + (_n))))
+
+# define AddAdapter(_p) \
+ do \
+ { \
+ nATIPtr++; \
+ ATIPtrs = (ATIPtr *)xnfrealloc(ATIPtrs, SizeOf(ATIPtr) * nATIPtr); \
+ ATIPtrs[nATIPtr - 1] = (_p); \
+ (_p)->iEntity = -2; \
+ } while(0)
+
+ /*
+ * Get a list of XF86Config device sections whose "Driver" is either not
+ * specified, or specified as this driver. From this list, eliminate those
+ * device sections that specify a "Chipset" or a "ChipID" not recognized by
+ * the driver. Those device sections that specify a "ChipRev" without a
+ * "ChipID" are also weeded out.
+ */
+ if ((nGDev = xf86MatchDevice(ATI_NAME, &GDevs)) <= 0)
+ return FALSE;
+
+ ATIGDevs = (ATIGDevPtr)xnfcalloc(nGDev, SizeOf(ATIGDev));
+ memset(fChipsets, FALSE, SizeOf(fChipsets));
+
+ for (i = 0, pATIGDev = ATIGDevs; i < nGDev; i++)
+ {
+ pGDev = GDevs[i];
+ Chipset = ATIIdentProbe(pGDev->chipset);
+ if (Chipset == -1)
+ continue;
+
+ if ((pGDev->chipID > (int)((CARD16)(-1))) ||
+ (pGDev->chipRev > (int)((CARD8)(-1))))
+ continue;
+
+ if (pGDev->chipID >= 0)
+ {
+ if (ATIChipID(pGDev->chipID, 0) == ATI_CHIP_Mach64)
+ continue;
+ }
+ else
+ {
+ if (pGDev->chipRev >= 0)
+ continue;
+ }
+
+ pATIGDev->pGDev = pGDev;
+ pATIGDev->Chipset = Chipset;
+ nATIGDev++;
+ pATIGDev++;
+ fChipsets[Chipset] = TRUE;
+ }
+
+ xfree(GDevs);
+
+ /* If no device sections remain, return now */
+ if (!nATIGDev)
+ {
+ xfree(ATIGDevs);
+ return FALSE;
+ }
+
+ /*
+ * Collect hardware information. This must be done with care to avoid
+ * lockups due to overlapping I/O port assignments.
+ *
+ * First, scan PCI configuration space for registered I/O ports (which will
+ * be block I/O bases). Each such port is used to generate a list of
+ * sparse I/O bases it precludes. This list is then used to decide whether
+ * or not certain sparse I/O probes are done. Unfortunately, this assumes
+ * that any registered I/O base actually reserves upto the full 256 ports
+ * allowed by the PCI specification. This assumption holds true for PCI
+ * Mach64, but probably doesn't for other device types. For some things,
+ * such as video devices, the number of ports a base represents is
+ * determined by the server's PCI probe, but, for other devices, this
+ * cannot be done by a user-level process without jeopardizing system
+ * integrity. This information should ideally be retrieved from the OS's
+ * own PCI probe (if any), but there's currently no portable way of doing
+ * so. The following allows sparse I/O probes to be forced in certain
+ * circumstances when an appropriate chipset specification is used in any
+ * XF86Config Device section.
+ *
+ * Note that this is not bullet-proof. Lockups can still occur, but they
+ * will usually be due to devices that are misconfigured to respond to the
+ * same I/O ports as 8514/A's or ATI sparse I/O devices without registering
+ * them in PCI configuration space.
+ */
+ if (xf86PciVideoInfo)
+ for (i = 0; (pVideo = xf86PciVideoInfo[i++]); )
+ {
+ pPCI = (pciConfigPtr)(pVideo->thisCard);
+
+ if (pVideo->vendor == PCI_VENDOR_ATI)
+ {
+ if (pVideo->chipType == PCI_CHIP_MACH32)
+ continue;
+
+ /*
+ * Some PCI Mach64's are not properly configured for sparse or
+ * block I/O. Correct PCI's USERCONFIG register, if necessary.
+ */
+ PciReg = pciReadLong(pPCI->tag, PCI_REG_USERCONFIG);
+ if (IsATIBlockIOBase(pVideo->ioBase[1]))
+ {
+ /* This is block I/O */
+ if (!(PciReg & 0x00000004U))
+ pciWriteLong(pPCI->tag, PCI_REG_USERCONFIG,
+ PciReg | 0x00000004U);
+ }
+ else
+ {
+ /* This is sparse I/O */
+ if (PciReg & 0x00000004U)
+ pciWriteLong(pPCI->tag, PCI_REG_USERCONFIG,
+ PciReg & ~0x00000004U);
+ }
+ continue;
+ }
+
+ ATIScanPCIBases(&PCIPorts, &nPCIPort,
+ &pPCI->pci_base0, pVideo->size,
+ (pciReadLong(pPCI->tag, PCI_CMD_STAT_REG) &
+ PCI_CMD_IO_ENABLE) ? 0 : Allowed);
+ }
+
+ /* Check non-video PCI devices for I/O bases */
+ if (xf86PciInfo)
+ for (i = 0; (pPCI = xf86PciInfo[i++]); )
+ if ((pPCI->pci_vendor != PCI_VENDOR_ATI) &&
+ (pPCI->pci_base_class != PCI_CLASS_BRIDGE) &&
+ !(pPCI->pci_header_type &
+ ~GetByte(PCI_HEADER_MULTIFUNCTION, 2)))
+ ATIScanPCIBases(&PCIPorts, &nPCIPort,
+ &pPCI->pci_base0, pPCI->basesize,
+ (pciReadLong(pPCI->tag, PCI_CMD_STAT_REG) &
+ PCI_CMD_IO_ENABLE) ? 0 : Allowed);
+
+ /* Generate ProbeFlags array from list of registered PCI I/O bases */
+ memset(ProbeFlags, Allowed | DoProbe, SizeOf(ProbeFlags));
+ for (i = 0; i < nPCIPort; i++)
+ {
+ CARD32 Base = PCIPorts[i].Base;
+ CARD16 Count = (1 << PCIPorts[i].Size) - 1;
+ CARD8 ProbeFlag = PCIPorts[i].Flag;
+
+ /*
+ * The following reduction of Count is based on the assumption that
+ * PCI-registered I/O port ranges do not overlap.
+ */
+ for (j = 0; j < nPCIPort; j++)
+ {
+ CARD32 Base2 = PCIPorts[j].Base;
+
+ if (Base < Base2)
+ while ((Base + Count) >= Base2)
+ Count >>= 1;
+ }
+
+ Base = LongPort(Base);
+ Count = LongPort((Count | IO_BYTE_SELECT) + 1);
+ while (Count--)
+ ProbeFlags[Base++] &= ProbeFlag;
+ }
+
+ xfree(PCIPorts);
+
+ /*
+ * A note on probe strategy. I/O and memory response by certain PCI
+ * devices has been disabled by the common layer at this point, including
+ * any devices this driver might be interested in. The following does
+ * sparse I/O probes, followed by block I/O probes. Block I/O probes are
+ * dictated by what is found to be of interest in PCI configuration space.
+ * All this will detect ATI adapters that do not implement this
+ * disablement, pre-PCI or not.
+ *
+ * PCI configuration space is then scanned again for ATI devices that
+ * failed to be detected the first time around. Each such device is probed
+ * for again, this time with I/O temporarily enabled through PCI.
+ */
+ if (ATICheckSparseIOBases(ProbeFlags, ATTRX, 16, TRUE) == DoProbe)
+ {
+ pVGA = ATIVGAProbe(NULL);
+ if (pVGA->Adapter == ATI_ADAPTER_NONE)
+ {
+ xfree(pVGA);
+ pVGA = NULL;
+ }
+ else
+ {
+ /*
+ * Claim all MDA/HGA/CGA/EGA/VGA I/O ports. This might need to be
+ * more selective.
+ */
+ ATIClaimSparseIOBases(ProbeFlags, MonochromeIOBase, 48,
+ DetectedVGA);
+ }
+ }
+
+ if ((ATICheckSparseIOBases(ProbeFlags, 0x02E8U, 8,
+ fChipsets[ATI_CHIPSET_IBM8514] ||
+ fChipsets[ATI_CHIPSET_MACH8] ||
+ fChipsets[ATI_CHIPSET_MACH32]) == DoProbe) &&
+ (pATI = ATI8514Probe(NULL)))
+ {
+ AddAdapter(p8514 = pATI);
+
+ if ((pATI->VGAAdapter != ATI_ADAPTER_NONE) ||
+ (pATI->Coprocessor != ATI_CHIP_NONE))
+ ATIClaimVGA(&pVGA, pATI, p8514, ProbeFlags, Detected8514A);
+
+ ATIClaimSparseIOBases(ProbeFlags, 0x02E8U, 8, Detected8514A);
+ }
+
+ for (i = 0; i < NumberOf(Mach64SparseIOBases); i++)
+ {
+ if (ATICheckSparseIOBases(ProbeFlags, Mach64SparseIOBases[i], 4,
+ fChipsets[ATI_CHIPSET_MACH64]) != DoProbe)
+ continue;
+
+ if (!(pATI = ATIMach64Probe(Mach64SparseIOBases[i], SPARSE_IO, 0, 0)))
+ continue;
+
+ AddAdapter(pMach64[i] = pATI);
+
+ if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
+ ATIClaimVGA(&pVGA, pATI, p8514, ProbeFlags, DetectedMach64);
+
+ ATIClaimSparseIOBases(ProbeFlags, Mach64SparseIOBases[i], 4,
+ DetectedMach64);
+ }
+
+ if (xf86PciVideoInfo)
+ {
+ for (i = 0; (pVideo = xf86PciVideoInfo[i++]); )
+ {
+ if ((pVideo->vendor != PCI_VENDOR_ATI) ||
+ (pVideo->chipType == PCI_CHIP_MACH32) ||
+ !IsATIBlockIOBase(pVideo->ioBase[1]))
+ continue;
+
+ pATI = ATIMach64Probe(pVideo->ioBase[1], BLOCK_IO,
+ pVideo->chipType,
+ ATIChipID(pVideo->chipType, pVideo->chipRev));
+ if (!pATI)
+ continue;
+
+ AddAdapter(pATI);
+
+ /* This is probably not necessary */
+ if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
+ ATIClaimVGA(&pVGA, pATI, p8514, ProbeFlags, DetectedMach64);
+ }
+
+ /*
+ * This is the second pass through PCI configuration space. Much of
+ * this is verbiage to deal with potential situations that are very
+ * unlikely to occur in practice.
+ *
+ * First, look for non-ATI shareable VGA's. For now, these must have
+ * been previously initialized by their BIOS.
+ */
+ if (ATICheckSparseIOBases(ProbeFlags, ATTRX, 16, TRUE) == DoProbe)
+ {
+ for (i = 0; (pVideo = xf86PciVideoInfo[i++]); )
+ {
+ if ((pVideo->vendor == PCI_VENDOR_ATI) ||
+ !(((pciConfigPtr)(pVideo->thisCard))->pci_command &
+ PCI_CMD_IO_ENABLE) ||
+ (pVideo->interface != 0) ||
+ (((pVideo->class != PCI_CLASS_PREHISTORIC) ||
+ (pVideo->subclass != PCI_SUBCLASS_PREHISTORIC_VGA)) &&
+ ((pVideo->class != PCI_CLASS_DISPLAY) ||
+ (pVideo->subclass != PCI_SUBCLASS_DISPLAY_VGA))))
+ continue;
+
+ xf86SetPciVideo(pVideo, IO);
+
+ pATI = ATIVGAProbe(NULL);
+ if (pATI->Adapter == ATI_ADAPTER_NONE)
+ {
+ xfree(pATI);
+ xf86Msg(X_WARNING,
+ ATI_NAME ": PCI VGA-compatible in slot %d:%d:%d"
+ " could not be detected!" ATI_README,
+ pVideo->bus, pVideo->device, pVideo->func);
+ }
+ else
+ {
+ AddAdapter(pATI);
+ pATI->SharedVGA = TRUE;
+ pATI->BusType = ATI_BUS_PCI;
+ pATI->PCIInfo = pVideo;
+ }
+
+ xf86SetPciVideo(NULL, NONE);
+ }
+ }
+
+ /* Next, look for PCI Mach32's */
+ for (i = 0; (pVideo = xf86PciVideoInfo[i++]); )
+ {
+ if ((pVideo->vendor != PCI_VENDOR_ATI) ||
+ (pVideo->chipType != PCI_CHIP_MACH32))
+ continue;
+
+ switch (ATICheckSparseIOBases(ProbeFlags, 0x02E8U, 8, TRUE))
+ {
+ case 0:
+ xf86Msg(X_WARNING,
+ ATI_NAME ": PCI Mach32 in slot %d:%d:%d will not"
+ " be enabled\n because it conflicts with a"
+ " non-video PCI device." ATI_README,
+ pVideo->bus, pVideo->device, pVideo->func);
+ break;
+
+ case Detected8514A:
+ if ((p8514->BusType >= ATI_BUS_PCI) && !p8514->PCIInfo)
+ p8514->PCIInfo = pVideo;
+ else
+ xf86Msg(X_WARNING,
+ ATI_NAME ": PCI Mach32 in slot %d:%d:%d will"
+ " not be enabled\n because it conflicts with"
+ " another %s %s." ATI_README,
+ pVideo->bus, pVideo->device, pVideo->func,
+ ATIBusNames[p8514->BusType],
+ ATIAdapterNames[p8514->Adapter]);
+ break;
+
+ case DetectedMach64:
+ xf86Msg(X_WARNING,
+ ATI_NAME ": PCI Mach32 in slot %d:%d:%d will not"
+ " be enabled\n because it conflicts with a"
+ " Mach64 at I/O base 0x02EC."
+ ATI_README,
+ pVideo->bus, pVideo->device, pVideo->func);
+ break;
+
+ default: /* Must be DoProbe */
+ xf86SetPciVideo(pVideo, IO);
+
+ if (!(pATI = ATI8514Probe(pVideo)))
+ xf86Msg(X_WARNING,
+ ATI_NAME ": PCI Mach32 in slot %d:%d:%d could"
+ " not be detected!" ATI_README,
+ pVideo->bus, pVideo->device, pVideo->func);
+ else
+ {
+ if (pATI->Adapter != ATI_ADAPTER_MACH32)
+ xf86Msg(X_WARNING,
+ ATI_NAME ": PCI Mach32 in slot %d:%d:%d"
+ " could only be detected as an %s!"
+ ATI_README,
+ pVideo->bus, pVideo->device, pVideo->func,
+ ATIAdapterNames[pATI->Adapter]);
+
+ AddAdapter(pATI);
+ pATI->SharedAccelerator = TRUE;
+
+ if ((pATI->VGAAdapter != ATI_ADAPTER_NONE) ||
+ (pATI->Coprocessor != ATI_CHIP_NONE))
+ ATIFindVGA(&pVGA, &pATI, p8514, ProbeFlags);
+ }
+
+ xf86SetPciVideo(NULL, NONE);
+ break;
+ }
+ }
+
+ /* Next, look for sparse I/O Mach64's */
+ for (i = 0; (pVideo = xf86PciVideoInfo[i++]); )
+ {
+ if ((pVideo->vendor != PCI_VENDOR_ATI) ||
+ (pVideo->chipType == PCI_CHIP_MACH32) ||
+ IsATIBlockIOBase(pVideo->ioBase[1]))
+ continue;
+
+ pPCI = (pciConfigPtr)(pVideo->thisCard);
+ PciReg = pciReadLong(pPCI->tag, PCI_REG_USERCONFIG);
+ j = PciReg & 0x03U;
+ if (j == 0x03U)
+ xf86Msg(X_WARNING,
+ ATI_NAME ": PCI Mach64 in slot %d:%d:%d cannot be"
+ " enabled\n because it has neither a block, nor a"
+ " sparse, I/O base." ATI_README,
+ pVideo->bus, pVideo->device, pVideo->func);
+ else switch(ATICheckSparseIOBases(ProbeFlags,
+ Mach64SparseIOBases[j], 4, TRUE))
+ {
+ case 0:
+ xf86Msg(X_WARNING,
+ ATI_NAME ": PCI Mach64 in slot %d:%d:%d will not"
+ " be enabled\n because it conflicts with another"
+ " non-video PCI device." ATI_README,
+ pVideo->bus, pVideo->device, pVideo->func);
+ break;
+
+ case Detected8514A:
+ xf86Msg(X_WARNING,
+ ATI_NAME ": PCI Mach64 in slot %d:%d:%d will not"
+ " be enabled\n because it conflicts with an %s."
+ ATI_README,
+ pVideo->bus, pVideo->device, pVideo->func,
+ ATIAdapterNames[p8514->Adapter]);
+ break;
+
+ case DetectedMach64:
+ pATI = pMach64[j];
+ if ((pATI->BusType >= ATI_BUS_PCI) && !pATI->PCIInfo)
+ pATI->PCIInfo = pVideo;
+ else
+ xf86Msg(X_WARNING,
+ ATI_NAME ": PCI Mach64 in slot %d:%d:%d will"
+ " not be enabled\n because it conflicts with"
+ " another %s Mach64 at sparse I/O base 0x%04X."
+ ATI_README,
+ pVideo->bus, pVideo->device, pVideo->func,
+ ATIBusNames[pATI->BusType],
+ Mach64SparseIOBases[j]);
+ break;
+
+ default: /* Must be DoProbe */
+ xf86SetPciVideo(pVideo, IO);
+
+ pATI = ATIMach64Probe(Mach64SparseIOBases[j], SPARSE_IO,
+ pVideo->chipType,
+ ATIChipID(pVideo->chipType, pVideo->chipRev));
+ if (!pATI)
+ xf86Msg(X_WARNING,
+ ATI_NAME ": PCI Mach64 in slot %d:%d:%d could"
+ " not be detected!" ATI_README,
+ pVideo->bus, pVideo->device, pVideo->func);
+ else
+ {
+ AddAdapter(pATI);
+ pATI->SharedAccelerator = TRUE;
+ pATI->PCIInfo = pVideo;
+
+ if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
+ ATIFindVGA(&pVGA, &pATI, p8514, ProbeFlags);
+ }
+
+ xf86SetPciVideo(NULL, NONE);
+ break;
+ }
+ }
+
+ /* Lastly, look for block I/O devices */
+ for (i = 0; (pVideo = xf86PciVideoInfo[i++]); )
+ {
+ if ((pVideo->vendor != PCI_VENDOR_ATI) ||
+ (pVideo->chipType == PCI_CHIP_MACH32) ||
+ !IsATIBlockIOBase(pVideo->ioBase[1]))
+ continue;
+
+ /* Check if this one has already been detected */
+ for (j = 0; j < nATIPtr; j++)
+ {
+ pATI = ATIPtrs[j];
+ if (pATI->CPIOBase == pVideo->ioBase[1])
+ goto SetPCIInfo;
+ }
+
+ /* Probe for it */
+ xf86SetPciVideo(pVideo, IO);
+
+ pATI = ATIMach64Probe(pVideo->ioBase[1], BLOCK_IO,
+ pVideo->chipType,
+ ATIChipID(pVideo->chipType, pVideo->chipRev));
+ if (pATI)
+ {
+ AddAdapter(pATI);
+ pATI->SharedAccelerator = TRUE;
+
+ if (pATI->VGAAdapter != ATI_ADAPTER_NONE)
+ ATIFindVGA(&pVGA, &pATI, p8514, ProbeFlags);
+ }
+
+ xf86SetPciVideo(NULL, NONE);
+
+ if (!pATI)
+ {
+ xf86Msg(X_WARNING,
+ ATI_NAME ": PCI Mach64 in slot %d:%d:%d could not be"
+ " detected!" ATI_README,
+ pVideo->bus, pVideo->device, pVideo->func);
+ continue;
+ }
+
+ SetPCIInfo:
+ pATI->PCIInfo = pVideo;
+ }
+ }
+
+ /*
+ * At this point, if there's a non-shareable VGA with its own framebuffer,
+ * find out if it's an ATI VGA Wonder.
+ */
+ do
+ {
+ if (!pVGA || (pVGA->VGAAdapter > ATI_ADAPTER_VGA))
+ break;
+
+ /* If it has not been assigned to a coprocessor, keep track of it */
+ if (pVGA->Coprocessor == ATI_CHIP_NONE)
+ AddAdapter(pVGA);
+
+ /* Look for its BIOS */
+ for (BIOSBase = 0x000C0000U; ; BIOSBase += 0x00000200U)
+ {
+ if (BIOSBase >= 0x000F0000U)
+ goto NoVGAWonder;
+
+ /* Skip over those that are already known */
+ for (i = 0; i < nATIPtr; i++)
+ if (ATIPtrs[i]->BIOSBase == BIOSBase)
+ goto SkipBiosSegment;
+
+ /* Get first 80 bytes of video BIOS */
+ if (xf86ReadBIOS(BIOSBase, 0, BIOS, SizeOf(BIOS)) !=
+ SizeOf(BIOS))
+ goto NoVGAWonder;
+
+ if ((BIOS[0x00U] != 0x55U) || (BIOS[0x01U] != 0xAAU))
+ continue;
+
+ if ((BIOS[0x1EU] == 'I') &&
+ (BIOS[0x1FU] == 'B') &&
+ (BIOS[0x20U] == 'M'))
+ break;
+
+ /* XXX Should PCI BIOS signature be checked for here ? */
+ if ((BIOS[0x20U] == 'P') &&
+ (BIOS[0x21U] == 'C') &&
+ (BIOS[0x22U] == 'I'))
+ break;
+
+ SkipBiosSegment: ;
+ }
+
+ pVGA->BIOSBase = BIOSBase;
+
+ /* Look for the ATI signature string */
+ if (memcmp(BIOS + BIOSSignature, ATISignature, SignatureSize))
+ break;
+
+ if (BIOS[0x40U] != '3')
+ break;
+
+ switch (BIOS[0x41U])
+ {
+ case '1':
+ /* This is a Mach8 or VGA Wonder adapter of some kind */
+ if ((BIOS[0x43U] >= '1') && (BIOS[0x43U] <= '6'))
+ pVGA->Chip = BIOS[0x43U] - ('1' - ATI_CHIP_18800);
+
+ switch (BIOS[0x43U])
+ {
+ case '1': /* ATI_CHIP_18800 */
+ pVGA->VGAOffset = 0xB0U;
+ pVGA->VGAAdapter = ATI_ADAPTER_V3;
+ break;
+
+ case '2': /* ATI_CHIP_18800_1 */
+ pVGA->VGAOffset = 0xB0U;
+ if (BIOS[0x42U] & 0x10U)
+ pVGA->VGAAdapter = ATI_ADAPTER_V5;
+ else
+ pVGA->VGAAdapter = ATI_ADAPTER_V4;
+ break;
+
+ case '3': /* ATI_CHIP_28800_2 */
+ case '4': /* ATI_CHIP_28800_4 */
+ case '5': /* ATI_CHIP_28800_5 */
+ case '6': /* ATI_CHIP_28800_6 */
+ pVGA->VGAOffset = 0xA0U;
+ if (BIOS[0x44U] & 0x80U)
+ pVGA->VGAAdapter = ATI_ADAPTER_XL;
+ else
+ pVGA->VGAAdapter = ATI_ADAPTER_PLUS;
+ break;
+
+ case 'a': /* A crippled Mach32 */
+ case 'b':
+ case 'c':
+ pVGA->VGAOffset = 0x80U;
+ pVGA->VGAAdapter = ATI_ADAPTER_NONISA;
+ ATIMach32ChipID(pVGA);
+ ProbeWaitIdleEmpty();
+ if (inw(SUBSYS_STAT) != (CARD16)(-1))
+ pVGA->ChipHasSUBSYS_CNTL = TRUE;
+ break;
+#if 0
+ case ' ': /* A crippled Mach64 */
+ pVGA->VGAOffset = 0x80U;
+ pVGA->VGAAdapter = ATI_ADAPTER_NONISA;
+ ATIMach64ChipID(pVGA, 0);
+ break;
+#endif
+ default:
+ break;
+ }
+
+ if (pVGA->VGAAdapter == ATI_ADAPTER_NONE)
+ break;
+
+ /* Set VGA Wonder I/O port */
+ pVGA->CPIO_VGAWonder = BIOSWord(0x10U) & SPARSE_IO_PORT;
+ if (!pVGA->CPIO_VGAWonder)
+ pVGA->CPIO_VGAWonder = 0x01CEU;
+
+ ATIVGAWonderProbe(pVGA, p8514, ProbeFlags);
+ break;
+#if 0
+ case '2':
+ pVGA->VGAOffset = 0xB0U; /* Presumably */
+ pVGA->VGAAdapter = ATI_ADAPTER_EGA_PLUS;
+ break;
+
+ case '3':
+ pVGA->VGAOffset = 0xB0U; /* Presumably */
+ pVGA->VGAAdapter = ATI_ADAPTER_BASIC;
+ break;
+
+ case '?': /* A crippled Mach64 */
+ pVGA->VGAAdapter = ATI_ADAPTER_NONISA;
+ ATIMach64ChipID(pVGA, 0);
+ break;
+#endif
+ default:
+ break;
+ }
+
+ if (pVGA->Adapter <= ATI_ADAPTER_VGA)
+ pVGA->Adapter = pVGA->VGAAdapter;
+
+NoVGAWonder:;
+ } while (0);
+
+ /* If no appropriate adapters have been detected, return now */
+ if (!nATIPtr)
+ {
+ xfree(ATIGDevs);
+ return FALSE;
+ }
+
+ /*
+ * Assign detected devices to XF86Config Device sections. This is done by
+ * comparing certain Device section specifications against the
+ * corresponding adapter information. Begin with those specifications that
+ * are independent of the adapter's bus location.
+ */
+ for (i = 0, pATIGDev = ATIGDevs; i < nATIGDev; i++, pATIGDev++)
+ {
+ pGDev = pATIGDev->pGDev;
+
+ for (j = 0; j < nATIPtr; j++)
+ {
+ pATI = ATIPtrs[j];
+
+ /*
+ * First check the Chipset specification. The placement of "break"
+ * and "continue" statements here is carefully chosen to produce
+ * the intended behaviour for each Chipset value.
+ */
+ switch (pATIGDev->Chipset)
+ {
+ case ATI_CHIPSET_ATI:
+ if (pATI->Adapter == ATI_ADAPTER_VGA)
+ continue;
+ if (pATI->Adapter != ATI_ADAPTER_8514A)
+ break;
+ /* Fall through */
+
+ case ATI_CHIPSET_ATIVGA:
+ if (pATI->VGAAdapter == ATI_ADAPTER_VGA)
+ continue;
+ /* Fall through */
+
+ case ATI_CHIPSET_IBMVGA:
+ if (pATI->VGAAdapter == ATI_ADAPTER_NONE)
+ continue;
+ break;
+
+ case ATI_CHIPSET_VGAWONDER:
+ if (!pATI->CPIO_VGAWonder)
+ continue;
+ break;
+
+ case ATI_CHIPSET_IBM8514:
+ if (pATI->Adapter == ATI_ADAPTER_8514A)
+ break;
+ /* Fall through */
+
+ case ATI_CHIPSET_MACH8:
+ if (pATI->Adapter == ATI_ADAPTER_MACH8)
+ break;
+ /* Fall through */
+
+ case ATI_CHIPSET_MACH32:
+ if (pATI->Adapter == ATI_ADAPTER_MACH32)
+ break;
+ continue;
+
+ case ATI_CHIPSET_MACH64:
+ if (pATI->Adapter == ATI_ADAPTER_MACH64)
+ break;
+ continue;
+
+ default:
+ continue;
+ }
+
+ /*
+ * The ChipID and ChipRev specifications are compared next. First,
+ * require these to be unspecified for anything other than Mach32
+ * or Mach64 adapters. ChipRev is also required to be unspecified
+ * for Mach32's. ChipID is optional for for Mach32's, and both
+ * specifications are optional for Mach64's. Lastly, allow both
+ * specifications to override their detected value in the case of
+ * Mach64 adapters whose ChipID is unrecognized.
+ */
+ if (pGDev->chipID >= 0)
+ {
+ if (pATI->ChipType != pGDev->chipID)
+ {
+ if ((pATI->Adapter != ATI_ADAPTER_MACH64) ||
+ (pATI->Chip != ATI_CHIP_Mach64))
+ continue;
+
+ Chip = ATIChipID(pGDev->chipID, 0);
+ if ((Chip <= ATI_CHIP_264GTB) || (Chip == ATI_CHIP_Mach64))
+ continue;
+ }
+ if ((pGDev->chipRev >= 0) && (pATI->ChipRev != pGDev->chipRev))
+ {
+ if (pATI->Adapter != ATI_ADAPTER_MACH64)
+ continue;
+ if ((pGDev->chipRev >= 0) &&
+ (pATI->Chip != ATI_CHIP_Mach64))
+ continue;
+ }
+ }
+
+ /*
+ * IOBase is next. This is the first specification that is
+ * potentially dependent on bus location. It is only allowed for
+ * Mach64 adapters, and is optional.
+ */
+ if (pGDev->IOBase && (pATI->CPIOBase != pGDev->IOBase))
+ continue;
+
+ /*
+ * Compare BusID's. This specification is only allowed for PCI
+ * Mach32's or Mach64's and is optional.
+ */
+ if (pGDev->busID && pGDev->busID[0])
+ {
+ if (!(pVideo = pATI->PCIInfo))
+ continue;
+ if (!xf86ComparePciBusString(pGDev->busID,
+ pVideo->bus, pVideo->device, pVideo->func))
+ continue;
+ }
+
+ /*
+ * Ensure no two adapters are assigned to the same XF86Config
+ * Device section.
+ */
+ if (pATIGDev->iATIPtr)
+ {
+ if (pATIGDev->iATIPtr < 0)
+ break;
+
+ xf86Msg(X_ERROR,
+ ATI_NAME ": XF86Config Device section \"%s\" may not"
+ " be assigned to more than one adapter." ATI_README,
+ pGDev->identifier);
+ pATIGDev->iATIPtr = -1;
+ break;
+ }
+
+ /* Assign adapter */
+ pATIGDev->iATIPtr = j + 1;
+
+ /*
+ * For compatibility with previous releases, assign the first
+ * applicable adapter if there is only one Device section.
+ */
+ if (nATIGDev == 1)
+ break;
+ }
+ }
+
+ /*
+ * Ensure no two XF86Config Device sections are assigned to the same
+ * adapter. Then, generate screens for any that are left.
+ */
+ for (i = 0, pATIGDev = ATIGDevs; i < nATIGDev; i++, pATIGDev++)
+ {
+ pGDev = pATIGDev->pGDev;
+
+ j = pATIGDev->iATIPtr;
+ if (j <= 0)
+ continue;
+
+ for (k = i; ++k < nATIGDev; )
+ {
+ if (j == ATIGDevs[k].iATIPtr)
+ {
+ xf86Msg(X_ERROR,
+ ATI_NAME ": XF86Config Device sections \"%s\" and"
+ " \"%s\" may not be assigned to the same adapter."
+ ATI_README, pGDev->identifier,
+ ATIGDevs[k].pGDev->identifier);
+ pATIGDev->iATIPtr = ATIGDevs[k].iATIPtr = -1;
+ }
+ }
+
+ j = ATIGDevs[i].iATIPtr;
+ if (j <= 0)
+ continue;
+
+ pATI = ATIPtrs[j - 1];
+
+ /*
+ * Attach adapter to XF86Config Device section and register its
+ * resources.
+ */
+ if (ATIClaimBusSlot(pDriver, pATIGDev->Chipset,
+ pGDev, pGDev->active, pATI) < 0)
+ continue;
+
+ if (!pGDev->active)
+ continue;
+
+ /* Allocate screen */
+ pScreenInfo = xf86AllocateScreen(pDriver, 0);
+
+ /* Attach device to screen */
+ xf86AddEntityToScreen(pScreenInfo, pATI->iEntity);
+
+ ATIPtrs[j - 1] = NULL;
+
+ /* Fill in probe data */
+ pScreenInfo->driverVersion = ATI_VERSION_CURRENT;
+ pScreenInfo->driverName = ATI_DRIVER_NAME;
+ pScreenInfo->name = ATI_NAME;
+ pScreenInfo->Probe = ATIProbe;
+ pScreenInfo->PreInit = ATIPreInit;
+ pScreenInfo->ScreenInit = ATIScreenInit;
+ pScreenInfo->SwitchMode = ATISwitchMode;
+ pScreenInfo->AdjustFrame = ATIAdjustFrame;
+ pScreenInfo->EnterVT = ATIEnterVT;
+ pScreenInfo->LeaveVT = ATILeaveVT;
+ pScreenInfo->FreeScreen = ATIFreeScreen;
+ pScreenInfo->ValidMode = ATIValidMode;
+
+ pScreenInfo->driverPrivate = pATI;
+
+ pATI->Chipset = pATIGDev->Chipset;
+
+ nScreen++;
+ }
+
+ /* Deal with unassigned adapters */
+ for (i = 0; i < nATIPtr; i++)
+ {
+ if (!(pATI = ATIPtrs[i]))
+ continue;
+
+ if ((pATI->Adapter > ATI_ADAPTER_VGA) && (pATI->iEntity < 0))
+ (void)ATIClaimBusSlot(pDriver, 0, NULL, FALSE, pATI);
+ xfree(pATI);
+ }
+ xfree(ATIPtrs);
+ xfree(ATIGDevs);
+
+ return (nScreen != 0);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.h
new file mode 100644
index 000000000..b7c27b7dc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.h
@@ -0,0 +1,32 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiprobe.h,v 1.3 1999/07/06 11:38:35 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIPROBE_H___
+#define ___ATIPROBE_H___ 1
+
+#include "atiproto.h"
+#include "xf86str.h"
+
+extern Bool ATIProbe FunctionPrototype((DriverPtr, int));
+
+#endif /* ___ATIPROBE_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiproto.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiproto.h
new file mode 100644
index 000000000..cb9a1ea78
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiproto.h
@@ -0,0 +1,41 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiproto.h,v 1.3 1999/07/06 11:38:36 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIPROTO_H___
+#define ___ATIPROTO_H___ 1
+
+#include "Xfuncproto.h"
+
+/*
+ * This isn't quite ready for Xfuncproto.h yet.
+ */
+
+#ifndef FunctionPrototype
+# if NeedFunctionPrototypes
+# define FunctionPrototype(FunctionArgumentTypes) FunctionArgumentTypes
+# else
+# define FunctionPrototype(FunctionArgumentTypes) ()
+# endif
+#endif
+
+#endif /* ___ATIPROTO_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiregs.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiregs.h
new file mode 100644
index 000000000..3e50d4bb5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiregs.h
@@ -0,0 +1,1624 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiregs.h,v 1.5 1999/08/01 07:57:22 dawes Exp $ */
+/*
+ * Copyright 1994 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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.
+ *
+ * Acknowledgements:
+ * Jake Richter, Panacea Inc., Londonderry, New Hampshire, U.S.A.
+ * Kevin E. Martin, martin@cs.unc.edu
+ * Tiago Gons, tiago@comosjn.hobby.nl
+ * Rickard E. Faith, faith@cs.unc.edu
+ * Scott Laird, lair@kimbark.uchicago.edu
+ *
+ * The intent here is to list all I/O ports for VGA (and its predecessors),
+ * ATI VGA Wonder, 8514/A, ATI Mach8, ATI Mach32 and ATI Mach64 video adapters,
+ * not just the ones in use by the ATI driver.
+ */
+
+#ifndef ___ATIREGS_H___
+#define ___ATIREGS_H___ 1
+
+#include "atiutil.h"
+
+/* I/O decoding definitions */
+#define SPARSE_IO_BASE 0x03fcu
+#define SPARSE_IO_SELECT 0xfc00u
+
+#define BLOCK_IO_BASE 0xff00u
+#define BLOCK_IO_SELECT 0x00fcu
+
+#define IO_BYTE_SELECT 0x0003u
+
+#define SPARSE_IO_PORT (SPARSE_IO_BASE | IO_BYTE_SELECT)
+#define BLOCK_IO_PORT (BLOCK_IO_BASE | IO_BYTE_SELECT)
+
+#define IsATIBlockIOBase(_Base) \
+ (((_Base) & BLOCK_IO_BASE) && !((_Base) & BLOCK_IO_SELECT))
+
+#define IOPortTag(_SparseIOSelect, _BlockIOSelect) \
+ (SetBits(_SparseIOSelect, SPARSE_IO_SELECT) | \
+ SetBits(_BlockIOSelect, BLOCK_IO_SELECT))
+#define SparseIOTag(_IOSelect) IOPortTag(_IOSelect, (unsigned)(-1))
+#define BlockIOTag(_IOSelect) IOPortTag((unsigned)(-1), _IOSelect)
+
+/* MDA/CGA/EGA/VGA I/O ports */
+#define GENVS 0x0102u /* Write (and Read on uC only) */
+
+#define R_GENLPS 0x03b9u /* Read */
+
+#define GENHP 0x03bfu
+
+#define ATTRX 0x03c0u
+#define ATTRD 0x03c1u
+#define GENS0 0x03c2u /* Read */
+#define GENMO 0x03c2u /* Write */
+#define GENENB 0x03c3u /* Read */
+#define SEQX 0x03c4u
+#define SEQD 0x03c5u
+#define VGA_DAC_MASK 0x03c6u
+#define VGA_DAC_READ 0x03c7u
+#define VGA_DAC_WRITE 0x03c8u
+#define VGA_DAC_DATA 0x03c9u
+#define R_GENFC 0x03cau /* Read */
+/* ? 0x03cbu */
+#define R_GENMO 0x03ccu /* Read */
+/* ? 0x03cdu */
+#define GRAX 0x03ceu
+#define GRAD 0x03cfu
+
+#define GENB 0x03d9u
+
+#define GENLPS 0x03dcu /* Write */
+#define KCX 0x03ddu
+#define KCD 0x03deu
+
+#define GENENA 0x46e8u /* Write */
+
+/* I/O port base numbers */
+#define MonochromeIOBase 0x03b0u
+#define ColourIOBase 0x03d0u
+
+/* Other EGA/CGA/VGA I/O ports */
+/* ?(_IOBase) (_IOBase + 0x00u) */
+/* ?(_IOBase) (_IOBase + 0x01u) */
+/* ?(_IOBase) (_IOBase + 0x02u) */
+/* ?(_IOBase) (_IOBase + 0x03u) */
+#define CRTX(_IOBase) (_IOBase + 0x04u)
+#define CRTD(_IOBase) (_IOBase + 0x05u)
+/* ?(_IOBase) (_IOBase + 0x06u) */
+/* ?(_IOBase) (_IOBase + 0x07u) */
+#define GENMC(_IOBase) (_IOBase + 0x08u)
+/* ?(_IOBase) (_IOBase + 0x09u) */ /* R_GENLPS/GENB */
+#define GENS1(_IOBase) (_IOBase + 0x0au) /* Read */
+#define GENFC(_IOBase) (_IOBase + 0x0au) /* Write */
+#define GENLPC(_IOBase) (_IOBase + 0x0bu)
+/* ?(_IOBase) (_IOBase + 0x0cu) */ /* /GENLPS */
+/* ?(_IOBase) (_IOBase + 0x0du) */ /* /KCX */
+/* ?(_IOBase) (_IOBase + 0x0eu) */ /* /KCD */
+/* ?(_IOBase) (_IOBase + 0x0fu) */ /* GENHP/ */
+
+/* 8514/A VESA approved register definitions */
+#define DISP_STAT 0x02e8u /* Read */
+#define SENSE 0x0001u /* Presumably belong here */
+#define VBLANK 0x0002u
+#define HORTOG 0x0004u
+#define H_TOTAL 0x02e8u /* Write */
+#define DAC_MASK 0x02eau
+#define DAC_R_INDEX 0x02ebu
+#define DAC_W_INDEX 0x02ecu
+#define DAC_DATA 0x02edu
+#define H_DISP 0x06e8u /* Write */
+#define H_SYNC_STRT 0x0ae8u /* Write */
+#define H_SYNC_WID 0x0ee8u /* Write */
+#define HSYNCPOL_POS 0x0000u
+#define HSYNCPOL_NEG 0x0020u
+#define H_POLARITY_POS HSYNCPOL_POS /* Sigh */
+#define H_POLARITY_NEG HSYNCPOL_NEG /* Sigh */
+#define V_TOTAL 0x12e8u /* Write */
+#define V_DISP 0x16e8u /* Write */
+#define V_SYNC_STRT 0x1ae8u /* Write */
+#define V_SYNC_WID 0x1ee8u /* Write */
+#define VSYNCPOL_POS 0x0000u
+#define VSYNCPOL_NEG 0x0020u
+#define V_POLARITY_POS VSYNCPOL_POS /* Sigh */
+#define V_POLARITY_NEG VSYNCPOL_NEG /* Sigh */
+#define DISP_CNTL 0x22e8u /* Write */
+#define ODDBNKENAB 0x0001u
+#define MEMCFG_2 0x0000u
+#define MEMCFG_4 0x0002u
+#define MEMCFG_6 0x0004u
+#define MEMCFG_8 0x0006u
+#define DBLSCAN 0x0008u
+#define INTERLACE 0x0010u
+#define DISPEN_NC 0x0000u
+#define DISPEN_ENAB 0x0020u
+#define DISPEN_DISAB 0x0040u
+#define R_H_TOTAL 0x26e8u /* Read */
+/* ? 0x2ae8u */
+/* ? 0x2ee8u */
+/* ? 0x32e8u */
+/* ? 0x36e8u */
+/* ? 0x3ae8u */
+/* ? 0x3ee8u */
+#define SUBSYS_STAT 0x42e8u /* Read */
+#define VBLNKFLG 0x0001u
+#define PICKFLAG 0x0002u
+#define INVALIDIO 0x0004u
+#define GPIDLE 0x0008u
+#define MONITORID_MASK 0x0070u
+/* MONITORID_? 0x0000u */
+#define MONITORID_8507 0x0010u
+#define MONITORID_8514 0x0020u
+/* MONITORID_? 0x0030u */
+/* MONITORID_? 0x0040u */
+#define MONITORID_8503 0x0050u
+#define MONITORID_8512 0x0060u
+#define MONITORID_8513 0x0060u
+#define MONITORID_NONE 0x0070u
+#define _8PLANE 0x0080u
+#define SUBSYS_CNTL 0x42e8u /* Write */
+#define RVBLNKFLG 0x0001u
+#define RPICKFLAG 0x0002u
+#define RINVALIDIO 0x0004u
+#define RGPIDLE 0x0008u
+#define IVBLNKFLG 0x0100u
+#define IPICKFLAG 0x0200u
+#define IINVALIDIO 0x0400u
+#define IGPIDLE 0x0800u
+#define CHPTEST_NC 0x0000u
+#define CHPTEST_NORMAL 0x1000u
+#define CHPTEST_ENAB 0x2000u
+#define GPCTRL_NC 0x0000u
+#define GPCTRL_ENAB 0x4000u
+#define GPCTRL_RESET 0x8000u
+#define ROM_PAGE_SEL 0x46e8u /* Write */
+#define ADVFUNC_CNTL 0x4ae8u /* Write */
+#define DISABPASSTHRU 0x0001u
+#define CLOKSEL 0x0004u
+/* ? 0x4ee8u */
+#define EXT_CONFIG_0 0x52e8u /* C & T 82C480 */
+#define EXT_CONFIG_1 0x56e8u /* C & T 82C480 */
+#define EXT_CONFIG_2 0x5ae8u /* C & T 82C480 */
+#define EXT_CONFIG_3 0x5ee8u /* C & T 82C480 */
+/* ? 0x62e8u */
+/* ? 0x66e8u */
+/* ? 0x6ae8u */
+/* ? 0x6ee8u */
+/* ? 0x72e8u */
+/* ? 0x76e8u */
+/* ? 0x7ae8u */
+/* ? 0x7ee8u */
+#define CUR_Y 0x82e8u
+#define CUR_X 0x86e8u
+#define DESTY_AXSTP 0x8ae8u /* Write */
+#define DESTX_DIASTP 0x8ee8u /* Write */
+#define ERR_TERM 0x92e8u
+#define MAJ_AXIS_PCNT 0x96e8u /* Write */
+#define GP_STAT 0x9ae8u /* Read */
+#define GE_STAT 0x9ae8u /* Alias */
+#define DATARDY 0x0100u
+#define DATA_READY DATARDY /* Alias */
+#define GPBUSY 0x0200u
+#define CMD 0x9ae8u /* Write */
+#define WRTDATA 0x0001u
+#define PLANAR 0x0002u
+#define LASTPIX 0x0004u
+#define LINETYPE 0x0008u
+#define DRAW 0x0010u
+#define INC_X 0x0020u
+#define YMAJAXIS 0x0040u
+#define INC_Y 0x0080u
+#define PCDATA 0x0100u
+#define _16BIT 0x0200u
+#define CMD_NOP 0x0000u
+#define CMD_OP_MSK 0xf000u
+#define BYTSEQ 0x1000u
+#define CMD_LINE 0x2000u
+#define CMD_RECT 0x4000u
+#define CMD_RECTV1 0x6000u
+#define CMD_RECTV2 0x8000u
+#define CMD_LINEAF 0xa000u
+#define CMD_BITBLT 0xc000u
+#define SHORT_STROKE 0x9ee8u /* Write */
+#define SSVDRAW 0x0010u
+#define VECDIR_000 0x0000u
+#define VECDIR_045 0x0020u
+#define VECDIR_090 0x0040u
+#define VECDIR_135 0x0060u
+#define VECDIR_180 0x0080u
+#define VECDIR_225 0x00a0u
+#define VECDIR_270 0x00c0u
+#define VECDIR_315 0x00e0u
+#define BKGD_COLOR 0xa2e8u /* Write */
+#define FRGD_COLOR 0xa6e8u /* Write */
+#define WRT_MASK 0xaae8u /* Write */
+#define RD_MASK 0xaee8u /* Write */
+#define COLOR_CMP 0xb2e8u /* Write */
+#define BKGD_MIX 0xb6e8u /* Write */
+/* 0x001fu See MIX_* definitions below */
+#define BSS_BKGDCOL 0x0000u
+#define BSS_FRGDCOL 0x0020u
+#define BSS_PCDATA 0x0040u
+#define BSS_BITBLT 0x0060u
+#define FRGD_MIX 0xbae8u /* Write */
+/* 0x001fu See MIX_* definitions below */
+#define FSS_BKGDCOL 0x0000u
+#define FSS_FRGDCOL 0x0020u
+#define FSS_PCDATA 0x0040u
+#define FSS_BITBLT 0x0060u
+#define MULTIFUNC_CNTL 0xbee8u /* Write */
+#define MIN_AXIS_PCNT 0x0000u
+#define SCISSORS_T 0x1000u
+#define SCISSORS_L 0x2000u
+#define SCISSORS_B 0x3000u
+#define SCISSORS_R 0x4000u
+#define MEM_CNTL 0x5000u
+#define HORCFG_4 0x0000u
+#define HORCFG_5 0x0001u
+#define HORCFG_8 0x0002u
+#define HORCFG_10 0x0003u
+#define VRTCFG_2 0x0000u
+#define VRTCFG_4 0x0004u
+#define VRTCFG_6 0x0008u
+#define VRTCFG_8 0x000cu
+#define BUFSWP 0x0010u
+#define PATTERN_L 0x8000u
+#define PATTERN_H 0x9000u
+#define PIX_CNTL 0xa000u
+#define PLANEMODE 0x0004u
+#define COLCMPOP_F 0x0000u
+#define COLCMPOP_T 0x0008u
+#define COLCMPOP_GE 0x0010u
+#define COLCMPOP_LT 0x0018u
+#define COLCMPOP_NE 0x0020u
+#define COLCMPOP_EQ 0x0028u
+#define COLCMPOP_LE 0x0030u
+#define COLCMPOP_GT 0x0038u
+#define MIXSEL_FRGDMIX 0x0000u
+#define MIXSEL_PATT 0x0040u
+#define MIXSEL_EXPPC 0x0080u
+#define MIXSEL_EXPBLT 0x00c0u
+/* ? 0xc2e8u */
+/* ? 0xc6e8u */
+/* ? 0xcae8u */
+/* ? 0xcee8u */
+/* ? 0xd2e8u */
+/* ? 0xd6e8u */
+/* ? 0xdae8u */
+/* ? 0xdee8u */
+#define PIX_TRANS 0xe2e8u
+/* ? 0xe6e8u */
+/* ? 0xeae8u */
+/* ? 0xeee8u */
+/* ? 0xf2e8u */
+/* ? 0xf6e8u */
+/* ? 0xfae8u */
+/* ? 0xfee8u */
+
+/* ATI Mach8 & Mach32 register definitions */
+#define OVERSCAN_COLOR_8 0x02eeu /* Write */ /* Mach32 */
+#define OVERSCAN_BLUE_24 0x02efu /* Write */ /* Mach32 */
+#define OVERSCAN_GREEN_24 0x06eeu /* Write */ /* Mach32 */
+#define OVERSCAN_RED_24 0x06efu /* Write */ /* Mach32 */
+#define CURSOR_OFFSET_LO 0x0aeeu /* Write */ /* Mach32 */
+#define CURSOR_OFFSET_HI 0x0eeeu /* Write */ /* Mach32 */
+#define CONFIG_STATUS_1 0x12eeu /* Read */
+#define CLK_MODE 0x0001u /* Mach8 */
+#define BUS_16 0x0002u /* Mach8 */
+#define MC_BUS 0x0004u /* Mach8 */
+#define EEPROM_ENA 0x0008u /* Mach8 */
+#define DRAM_ENA 0x0010u /* Mach8 */
+#define MEM_INSTALLED 0x0060u /* Mach8 */
+#define ROM_ENA 0x0080u /* Mach8 */
+#define ROM_PAGE_ENA 0x0100u /* Mach8 */
+#define ROM_LOCATION 0xfe00u /* Mach8 */
+#define _8514_ONLY 0x0001u /* Mach32 */
+#define BUS_TYPE 0x000eu /* Mach32 */
+#define ISA_16_BIT 0x0000u /* Mach32 */
+#define EISA 0x0002u /* Mach32 */
+#define MICRO_C_16_BIT 0x0004u /* Mach32 */
+#define MICRO_C_8_BIT 0x0006u /* Mach32 */
+#define LOCAL_386SX 0x0008u /* Mach32 */
+#define LOCAL_386DX 0x000au /* Mach32 */
+#define LOCAL_486 0x000cu /* Mach32 */
+#define PCI 0x000eu /* Mach32 */
+#define MEM_TYPE 0x0070u /* Mach32 */
+#define CHIP_DIS 0x0080u /* Mach32 */
+#define TST_VCTR_ENA 0x0100u /* Mach32 */
+#define DACTYPE 0x0e00u /* Mach32 */
+#define MC_ADR_DECODE 0x1000u /* Mach32 */
+#define CARD_ID 0xe000u /* Mach32 */
+#define HORZ_CURSOR_POSN 0x12eeu /* Write */ /* Mach32 */
+#define CONFIG_STATUS_2 0x16eeu /* Read */
+#define SHARE_CLOCK 0x0001u /* Mach8 */
+#define HIRES_BOOT 0x0002u /* Mach8 */
+#define EPROM_16_ENA 0x0004u /* Mach8 */
+#define WRITE_PER_BIT 0x0008u /* Mach8 */
+#define FLASH_ENA 0x0010u /* Mach8 */
+#define SLOW_SEQ_EN 0x0001u /* Mach32 */
+#define MEM_ADDR_DIS 0x0002u /* Mach32 */
+#define ISA_16_ENA 0x0004u /* Mach32 */
+#define KOR_TXT_MODE_ENA 0x0008u /* Mach32 */
+#define LOCAL_BUS_SUPPORT 0x0030u /* Mach32 */
+#define LOCAL_BUS_CONFIG_2 0x0040u /* Mach32 */
+#define LOCAL_BUS_RD_DLY_ENA 0x0080u /* Mach32 */
+#define LOCAL_DAC_EN 0x0100u /* Mach32 */
+#define LOCAL_RDY_EN 0x0200u /* Mach32 */
+#define EEPROM_ADR_SEL 0x0400u /* Mach32 */
+#define GE_STRAP_SEL 0x0800u /* Mach32 */
+#define VESA_RDY 0x1000u /* Mach32 */
+#define Z4GB 0x2000u /* Mach32 */
+#define LOC2_MDRAM 0x4000u /* Mach32 */
+#define VERT_CURSOR_POSN 0x16eeu /* Write */ /* Mach32 */
+#define FIFO_TEST_DATA 0x1aeeu /* Read */ /* Mach32 */
+#define CURSOR_COLOR_0 0x1aeeu /* Write */ /* Mach32 */
+#define CURSOR_COLOR_1 0x1aefu /* Write */ /* Mach32 */
+#define HORZ_CURSOR_OFFSET 0x1eeeu /* Write */ /* Mach32 */
+#define VERT_CURSOR_OFFSET 0x1eefu /* Write */ /* Mach32 */
+#define PCI_CNTL 0x22eeu /* Mach32-PCI */
+#define CRT_PITCH 0x26eeu /* Write */
+#define CRT_OFFSET_LO 0x2aeeu /* Write */
+#define CRT_OFFSET_HI 0x2eeeu /* Write */
+#define LOCAL_CNTL 0x32eeu /* Mach32 */
+#define FIFO_OPT 0x36eeu /* Write */ /* Mach8 */
+#define MISC_OPTIONS 0x36eeu /* Mach32 */
+#define W_STATE_ENA 0x0000u /* Mach32 */
+#define HOST_8_ENA 0x0001u /* Mach32 */
+#define MEM_SIZE_ALIAS 0x000cu /* Mach32 */
+#define MEM_SIZE_512K 0x0000u /* Mach32 */
+#define MEM_SIZE_1M 0x0004u /* Mach32 */
+#define MEM_SIZE_2M 0x0008u /* Mach32 */
+#define MEM_SIZE_4M 0x000cu /* Mach32 */
+#define DISABLE_VGA 0x0010u /* Mach32 */
+#define _16_BIT_IO 0x0020u /* Mach32 */
+#define DISABLE_DAC 0x0040u /* Mach32 */
+#define DLY_LATCH_ENA 0x0080u /* Mach32 */
+#define TEST_MODE 0x0100u /* Mach32 */
+#define BLK_WR_ENA 0x0400u /* Mach32 */
+#define _64_DRAW_ENA 0x0800u /* Mach32 */
+#define FIFO_TEST_TAG 0x3aeeu /* Read */ /* Mach32 */
+#define EXT_CURSOR_COLOR_0 0x3aeeu /* Write */ /* Mach32 */
+#define EXT_CURSOR_COLOR_1 0x3eeeu /* Write */ /* Mach32 */
+#define MEM_BNDRY 0x42eeu /* Mach32 */
+#define MEM_PAGE_BNDRY 0x000fu /* Mach32 */
+#define MEM_BNDRY_ENA 0x0010u /* Mach32 */
+#define SHADOW_CTL 0x46eeu /* Write */
+#define CLOCK_SEL 0x4aeeu
+/* DISABPASSTHRU 0x0001u See ADVFUNC_CNTL */
+#define VFIFO_DEPTH_1 0x0100u /* Mach32 */
+#define VFIFO_DEPTH_2 0x0200u /* Mach32 */
+#define VFIFO_DEPTH_3 0x0300u /* Mach32 */
+#define VFIFO_DEPTH_4 0x0400u /* Mach32 */
+#define VFIFO_DEPTH_5 0x0500u /* Mach32 */
+#define VFIFO_DEPTH_6 0x0600u /* Mach32 */
+#define VFIFO_DEPTH_7 0x0700u /* Mach32 */
+#define VFIFO_DEPTH_8 0x0800u /* Mach32 */
+#define VFIFO_DEPTH_9 0x0900u /* Mach32 */
+#define VFIFO_DEPTH_A 0x0a00u /* Mach32 */
+#define VFIFO_DEPTH_B 0x0b00u /* Mach32 */
+#define VFIFO_DEPTH_C 0x0c00u /* Mach32 */
+#define VFIFO_DEPTH_D 0x0d00u /* Mach32 */
+#define VFIFO_DEPTH_E 0x0e00u /* Mach32 */
+#define VFIFO_DEPTH_F 0x0f00u /* Mach32 */
+#define COMPOSITE_SYNC 0x1000u
+/* ? 0x4eeeu */
+#define ROM_ADDR_1 0x52eeu
+#define BIOS_BASE_SEGMENT 0x007fu /* Mach32 */
+/* ? 0xff80u */ /* Mach32 */
+#define ROM_ADDR_2 0x56eeu /* Sick ... */
+#define SHADOW_SET 0x5aeeu /* Write */
+#define MEM_CFG 0x5eeeu /* Mach32 */
+#define MEM_APERT_SEL 0x0003u /* Mach32 */
+#define MEM_APERT_PAGE 0x000cu /* Mach32 */
+#define MEM_APERT_LOC 0xfff0u /* Mach32 */
+#define EXT_GE_STATUS 0x62eeu /* Read */ /* Mach32 */
+#define HORZ_OVERSCAN 0x62eeu /* Write */ /* Mach32 */
+#define VERT_OVERSCAN 0x66eeu /* Write */ /* Mach32 */
+#define MAX_WAITSTATES 0x6aeeu
+#define GE_OFFSET_LO 0x6eeeu /* Write */
+#define BOUNDS_LEFT 0x72eeu /* Read */
+#define GE_OFFSET_HI 0x72eeu /* Write */
+#define BOUNDS_TOP 0x76eeu /* Read */
+#define GE_PITCH 0x76eeu /* Write */
+#define BOUNDS_RIGHT 0x7aeeu /* Read */
+#define EXT_GE_CONFIG 0x7aeeu /* Write */ /* Mach32 */
+#define MONITOR_ALIAS 0x0007u /* Mach32 */
+/* MONITOR_? 0x0000u */ /* Mach32 */
+#define MONITOR_8507 0x0001u /* Mach32 */
+#define MONITOR_8514 0x0002u /* Mach32 */
+/* MONITOR_? 0x0003u */ /* Mach32 */
+/* MONITOR_? 0x0004u */ /* Mach32 */
+#define MONITOR_8503 0x0005u /* Mach32 */
+#define MONITOR_8512 0x0006u /* Mach32 */
+#define MONITOR_8513 0x0006u /* Mach32 */
+#define MONITOR_NONE 0x0007u /* Mach32 */
+#define ALIAS_ENA 0x0008u /* Mach32 */
+#define PIXEL_WIDTH_4 0x0000u /* Mach32 */
+#define PIXEL_WIDTH_8 0x0010u /* Mach32 */
+#define PIXEL_WIDTH_16 0x0020u /* Mach32 */
+#define PIXEL_WIDTH_24 0x0030u /* Mach32 */
+#define RGB16_555 0x0000u /* Mach32 */
+#define RGB16_565 0x0040u /* Mach32 */
+#define RGB16_655 0x0080u /* Mach32 */
+#define RGB16_664 0x00c0u /* Mach32 */
+#define MULTIPLEX_PIXELS 0x0100u /* Mach32 */
+#define RGB24 0x0000u /* Mach32 */
+#define RGBx24 0x0200u /* Mach32 */
+#define BGR24 0x0400u /* Mach32 */
+#define xBGR24 0x0600u /* Mach32 */
+#define DAC_8_BIT_EN 0x4000u /* Mach32 */
+#define PIX_WIDTH_16BPP PIXEL_WIDTH_16 /* Mach32 */
+#define ORDER_16BPP_565 RGB16_565 /* Mach32 */
+#define BOUNDS_BOTTOM 0x7eeeu /* Read */
+#define MISC_CNTL 0x7eeeu /* Write */ /* Mach32 */
+#define PATT_DATA_INDEX 0x82eeu
+/* ? 0x86eeu */
+/* ? 0x8aeeu */
+#define R_EXT_GE_CONFIG 0x8eeeu /* Read */ /* Mach32 */
+#define PATT_DATA 0x8eeeu /* Write */
+#define R_MISC_CNTL 0x92eeu /* Read */ /* Mach32 */
+#define BRES_COUNT 0x96eeu
+#define EXT_FIFO_STATUS 0x9aeeu /* Read */
+#define LINEDRAW_INDEX 0x9aeeu /* Write */
+/* ? 0x9eeeu */
+#define LINEDRAW_OPT 0xa2eeu
+#define BOUNDS_RESET 0x0100u
+#define CLIP_MODE_0 0x0000u /* Clip exception disabled */
+#define CLIP_MODE_1 0x0200u /* Line segments */
+#define CLIP_MODE_2 0x0400u /* Polygon boundary lines */
+#define CLIP_MODE_3 0x0600u /* Patterned lines */
+#define DEST_X_START 0xa6eeu /* Write */
+#define DEST_X_END 0xaaeeu /* Write */
+#define DEST_Y_END 0xaeeeu /* Write */
+#define R_H_TOTAL_DISP 0xb2eeu /* Read */ /* Mach32 */
+#define SRC_X_START 0xb2eeu /* Write */
+#define R_H_SYNC_STRT 0xb6eeu /* Read */ /* Mach32 */
+#define ALU_BG_FN 0xb6eeu /* Write */
+#define R_H_SYNC_WID 0xbaeeu /* Read */ /* Mach32 */
+#define ALU_FG_FN 0xbaeeu /* Write */
+#define SRC_X_END 0xbeeeu /* Write */
+#define R_V_TOTAL 0xc2eeu /* Read */
+#define SRC_Y_DIR 0xc2eeu /* Write */
+#define R_V_DISP 0xc6eeu /* Read */ /* Mach32 */
+#define EXT_SHORT_STROKE 0xc6eeu /* Write */
+#define R_V_SYNC_STRT 0xcaeeu /* Read */ /* Mach32 */
+#define SCAN_X 0xcaeeu /* Write */
+#define VERT_LINE_CNTR 0xceeeu /* Read */ /* Mach32 */
+#define DP_CONFIG 0xceeeu /* Write */
+#define READ_WRITE 0x0001u
+#define DATA_WIDTH 0x0200u
+#define DATA_ORDER 0x1000u
+#define FG_COLOR_SRC_FG 0x2000u
+#define FG_COLOR_SRC_BLIT 0x6000u
+#define R_V_SYNC_WID 0xd2eeu /* Read */
+#define PATT_LENGTH 0xd2eeu /* Write */
+#define PATT_INDEX 0xd6eeu /* Write */
+#define READ_SRC_X 0xdaeeu /* Read */ /* Mach32 */
+#define EXT_SCISSOR_L 0xdaeeu /* Write */
+#define READ_SRC_Y 0xdeeeu /* Read */ /* Mach32 */
+#define EXT_SCISSOR_T 0xdeeeu /* Write */
+#define EXT_SCISSOR_R 0xe2eeu /* Write */
+#define EXT_SCISSOR_B 0xe6eeu /* Write */
+/* ? 0xeaeeu */
+#define DEST_COMP_FN 0xeeeeu /* Write */
+#define DEST_COLOR_CMP_MASK 0xf2eeu /* Write */ /* Mach32 */
+/* ? 0xf6eeu */
+#define CHIP_ID 0xfaeeu /* Read */ /* Mach32 */
+#define CHIP_CODE_0 0x001fu /* Mach32 */
+#define CHIP_CODE_1 0x03e0u /* Mach32 */
+#define CHIP_CLASS 0x0c00u /* Mach32 */
+#define CHIP_REV 0xf000u /* Mach32 */
+#define LINEDRAW 0xfeeeu /* Write */
+
+/* ATI Mach64 register definitions */
+#define CRTC_H_TOTAL_DISP IOPortTag(0x00u, 0x00u)
+#define CRTC_H_TOTAL 0x000001fful
+/* ? 0x0000fe00ul */
+#define CRTC_H_DISP 0x01ff0000ul
+/* ? 0xfe000000ul */
+#define CRTC_H_SYNC_STRT_WID IOPortTag(0x01u, 0x01u)
+#define CRTC_H_SYNC_STRT 0x000000fful
+#define CRTC_H_SYNC_DLY 0x00000700ul
+/* ? 0x00000800ul */
+#define CRTC_H_SYNC_STRT_HI 0x00001000ul
+/* ? 0x0000e000ul */
+#define CRTC_H_SYNC_WID 0x001f0000ul
+#define CRTC_H_SYNC_POL 0x00200000ul
+/* ? 0xffc00000ul */
+#define CRTC_V_TOTAL_DISP IOPortTag(0x02u, 0x02u)
+#define CRTC_V_TOTAL 0x000007fful
+/* ? 0x0000f800ul */
+#define CRTC_V_DISP 0x07ff0000ul
+/* ? 0xf8000000ul */
+#define CRTC_V_SYNC_STRT_WID IOPortTag(0x03u, 0x03u)
+#define CRTC_V_SYNC_STRT 0x000007fful
+/* ? 0x0000f800ul */
+#define CRTC_V_SYNC_WID 0x001f0000ul
+#define CRTC_V_SYNC_POL 0x00200000ul
+/* ? 0xffc00000ul */
+#define CRTC_VLINE_CRNT_VLINE IOPortTag(0x04u, 0x04u)
+#define CRTC_VLINE 0x000007fful
+/* ? 0x0000f800ul */
+#define CRTC_CRNT_VLINE 0x07ff0000ul
+/* ? 0xf8000000ul */
+#define CRTC_OFF_PITCH IOPortTag(0x05u, 0x05u)
+#define CRTC_OFFSET 0x000ffffful
+#define CRTC_OFFSET_VGA 0x0003fffful
+/* ? 0x00300000ul */
+#define CRTC_PITCH 0xffc00000ul
+#define CRTC_INT_CNTL IOPortTag(0x06u, 0x06u)
+#define CRTC_VBLANK 0x00000001ul
+#define CRTC_VBLANK_INT_EN 0x00000002ul
+#define CRTC_VBLANK_INT 0x00000004ul
+#define CRTC_VLINE_INT_EN 0x00000008ul
+#define CRTC_VLINE_INT 0x00000010ul
+#define CRTC_VLINE_SYNC 0x00000020ul
+#define CRTC_FRAME 0x00000040ul
+#define CRTC_SNAPSHOT_INT_EN 0x00000080ul /* GT3 */
+#define CRTC_SNAPSHOT_INT 0x00000100ul /* GT3 */
+#define CRTC_I2C_INT_EN 0x00000200ul /* GT3 */
+#define CRTC_I2C_INT 0x00000400ul /* GT3 */
+#define CRTC2_VBLANK 0x00000800ul /* LTPro */
+#define CRTC2_VBLANK_INT_EN 0x00001000ul /* LTPro */
+#define CRTC2_VBLANK_INT 0x00002000ul /* LTPro */
+#define CRTC2_VLINE_INT_EN 0x00004000ul /* LTPro */
+#define CRTC2_VLINE_INT 0x00008000ul /* LTPro */
+#define CRTC_CAPBUF0_INT_EN 0x00010000ul /* VT/GT */
+#define CRTC_CAPBUF0_INT 0x00020000ul /* VT/GT */
+#define CRTC_CAPBUF1_INT_EN 0x00040000ul /* VT/GT */
+#define CRTC_CAPBUF1_INT 0x00080000ul /* VT/GT */
+#define CRTC_OVERLAY_EOF_INT_EN 0x00100000ul /* VT/GT */
+#define CRTC_OVERLAY_EOF_INT 0x00200000ul /* VT/GT */
+#define CRTC_ONESHOT_CAP_INT_EN 0x00400000ul /* VT/GT */
+#define CRTC_ONESHOT_CAP_INT 0x00800000ul /* VT/GT */
+#define CRTC_BUSMASTER_EOL_INT_EN 0x01000000ul /* VTB/GTB/LT */
+#define CRTC_BUSMASTER_EOL_INT 0x02000000ul /* VTB/GTB/LT */
+#define CRTC_GP_INT_EN 0x04000000ul /* VTB/GTB/LT */
+#define CRTC_GP_INT 0x08000000ul /* VTB/GTB/LT */
+#define CRTC2_VLINE_SYNC 0x10000000ul /* LTPro */
+#define CRTC_SNAPSHOT2_INT_EN 0x20000000ul /* LTPro */
+#define CRTC_SNAPSHOT2_INT 0x40000000ul /* LTPro */
+#define CRTC_VBLANK_BIT2_INT 0x80000000ul /* GT3/LTPro */
+#define CRTC_INT_ENS /* *** UPDATE ME *** */ \
+ ( \
+ CRTC_VBLANK_INT_EN | \
+ CRTC_VLINE_INT_EN | \
+ CRTC_SNAPSHOT_INT_EN | \
+ CRTC_I2C_INT_EN | \
+ CRTC2_VBLANK_INT_EN | \
+ CRTC2_VLINE_INT_EN | \
+ CRTC_CAPBUF0_INT_EN | \
+ CRTC_CAPBUF1_INT_EN | \
+ CRTC_OVERLAY_EOF_INT_EN | \
+ CRTC_ONESHOT_CAP_INT_EN | \
+ CRTC_BUSMASTER_EOL_INT_EN | \
+ CRTC_GP_INT_EN | \
+ CRTC_SNAPSHOT2_INT_EN | \
+ 0 \
+ )
+#define CRTC_INT_ACKS /* *** UPDATE ME *** */ \
+ ( \
+ CRTC_VBLANK_INT | \
+ CRTC_VLINE_INT | \
+ CRTC_SNAPSHOT_INT | \
+ CRTC_I2C_INT | \
+ CRTC2_VBLANK_INT | \
+ CRTC2_VLINE_INT | \
+ CRTC_CAPBUF0_INT | \
+ CRTC_CAPBUF1_INT | \
+ CRTC_OVERLAY_EOF_INT | \
+ CRTC_ONESHOT_CAP_INT | \
+ CRTC_BUSMASTER_EOL_INT | \
+ CRTC_GP_INT | \
+ CRTC_SNAPSHOT2_INT | \
+ CRTC_VBLANK_BIT2_INT | \
+ 0 \
+ )
+#define CRTC_GEN_CNTL IOPortTag(0x07u, 0x07u)
+#define CRTC_DBL_SCAN_EN 0x00000001ul
+#define CRTC_INTERLACE_EN 0x00000002ul
+#define CRTC_HSYNC_DIS 0x00000004ul
+#define CRTC_VSYNC_DIS 0x00000008ul
+#define CRTC_CSYNC_EN 0x00000010ul
+#define CRTC_PIX_BY_2_EN 0x00000020ul
+#define CRTC2_DBL_SCAN_EN 0x00000020ul /* LTPro */
+#define CRTC_DISPLAY_DIS 0x00000040ul
+#define CRTC_VGA_XOVERSCAN 0x00000080ul
+#define CRTC_PIX_WIDTH 0x00000700ul
+#define CRTC_PIX_WIDTH_1BPP 0x00000000ul
+#define CRTC_PIX_WIDTH_4BPP 0x00000100ul
+#define CRTC_PIX_WIDTH_8BPP 0x00000200ul
+#define CRTC_PIX_WIDTH_15BPP 0x00000300ul
+#define CRTC_PIX_WIDTH_16BPP 0x00000400ul
+#define CRTC_PIX_WIDTH_24BPP 0x00000500ul
+#define CRTC_PIX_WIDTH_32BPP 0x00000600ul
+/* ? 0x00000700ul */
+#define CRTC_BYTE_PIX_ORDER 0x00000800ul
+/* ? 0x00003000ul */
+#define CRTC_FIFO_OVERFILL 0x0000c000ul /* VT/GT */
+#define CRTC_FIFO_LWM 0x000f0000ul
+/* ? 0x00010000ul */ /* LTPro */
+#define CRTC2_PIX_WIDTH 0x000e0000ul /* LTPro */
+#define CRTC2_PIX_WIDTH_NONE 0x00000000ul
+#define CRTC2_PIX_WIDTH_8BPP 0x00020000ul
+/* ? 0x00040000ul */
+#define CRTC2_PIX_WIDTH_15BPP 0x00060000ul
+#define CRTC2_PIX_WIDTH_16BPP 0x00080000ul
+#define CRTC2_PIX_WIDTH_24BPP 0x000a0000ul
+#define CRTC2_PIX_WIDTH_32BPP 0x000c0000ul
+#define CRTC2_PIX_WIDTH_YUV422 0x000e0000ul
+#define CRTC_VGA_128KAP_PAGING 0x00100000ul /* VT/GT */
+#define CRTC_DISPREQ_ONLY 0x00200000ul /* VT/GT */
+#define CRTC_VFC_SYNC_TRISTATE 0x00200000ul /* VTB/GTB/LT */
+#define CRTC2_EN 0x00200000ul /* LTPro */
+#define CRTC_LOCK_REGS 0x00400000ul /* VT/GT */
+#define CRTC_SYNC_TRISTATE 0x00800000ul /* VT/GT */
+#define CRTC_EXT_DISP_EN 0x01000000ul
+#define CRTC_EN 0x02000000ul
+#define CRTC_DISP_REQ_EN 0x04000000ul
+#define CRTC_VGA_LINEAR 0x08000000ul
+#define CRTC_VSYNC_FALL_EDGE 0x10000000ul
+#define CRTC_VGA_TEXT_132 0x20000000ul
+#define CRTC_CNT_EN 0x40000000ul
+#define CRTC_CUR_B_TEST 0x80000000ul
+#define DSP_CONFIG BlockIOTag(0x08u) /* VTB/GTB/LT */
+#define DSP_XCLKS_PER_QW 0x00003ffful
+/* ? 0x00004000ul */
+#define DSP_FLUSH_WB 0x00008000ul
+#define DSP_LOOP_LATENCY 0x000f0000ul
+#define DSP_PRECISION 0x00700000ul
+/* ? 0xff800000ul */
+#define DSP_ON_OFF BlockIOTag(0x09u) /* VTB/GTB/LT */
+#define DSP_OFF 0x000007fful
+/* ? 0x0000f800ul */
+#define DSP_ON 0x07ff0000ul
+/* ? 0xf8000000ul */
+#define TIMER_CONFIG BlockIOTag(0x0au) /* VTB/GTB/LT */
+#define MEM_BUF_CNTL BlockIOTag(0x0bu) /* VTB/GTB/LT */
+#define SHARED_CNTL BlockIOTag(0x0cu) /* VTB/GTB/LT */
+#define SHARED_MEM_CONFIG BlockIOTag(0x0du) /* VTB/GTB/LT */
+#define MEM_ADDR_CONFIG BlockIOTag(0x0du) /* GT3/LTPro */
+#define SHARED_CNTL_CTD BlockIOTag(0x0eu) /* CTD */
+/* ? 0x00fffffful */
+#define CTD_FIFO5 0x01000000ul
+/* ? 0xfe000000ul */
+#define CRT_TRAP BlockIOTag(0x0eu) /* VTB/GTB/LT */
+#define DSTN_CONTROL BlockIOTag(0x0fu) /* LT */
+#define I2C_CNTL_0 BlockIOTag(0x0fu) /* GT3/LTPro */
+#define OVR_CLR IOPortTag(0x08u, 0x10u)
+#define OVR_CLR_8 0x000000fful
+#define OVR_CLR_B 0x0000ff00ul
+#define OVR_CLR_G 0x00ff0000ul
+#define OVR_CLR_R 0xff000000ul
+#define OVR_WID_LEFT_RIGHT IOPortTag(0x09u, 0x11u)
+#define OVR_WID_LEFT 0x0000003ful /* 0x0f on <LT */
+/* ? 0x0000ffc0ul */
+#define OVR_WID_RIGHT 0x003f0000ul /* 0x0f0000 on <LT */
+/* ? 0xffc00000ul */
+#define OVR_WID_TOP_BOTTOM IOPortTag(0x0au, 0x12u)
+#define OVR_WID_TOP 0x000001fful /* 0x00ff on <LT */
+/* ? 0x0000fe00ul */
+#define OVR_WID_BOTTOM 0x01ff0000ul /* 0x00ff0000 on <LT */
+/* ? 0xfe000000ul */
+#define VGA_DSP_CONFIG BlockIOTag(0x13u) /* VTB/GTB/LT */
+#define VGA_DSP_XCLKS_PER_QW DSP_XCLKS_PER_QW
+/* ? 0x000fc000ul */
+#define VGA_DSP_PREC_PCLKBY2 0x00700000ul
+/* ? 0x00800000ul */
+#define VGA_DSP_PREC_PCLK 0x07000000ul
+/* ? 0xf8000000ul */
+#define VGA_DSP_ON_OFF BlockIOTag(0x14u) /* VTB/GTB/LT */
+#define VGA_DSP_OFF DSP_OFF
+/* ? 0x0000f800ul */
+#define VGA_DSP_ON DSP_ON
+/* ? 0xf8000000ul */
+#define DSP2_CONFIG BlockIOTag(0x15u) /* LTPro */
+#define DSP2_ON_OFF BlockIOTag(0x16u) /* LTPro */
+#define EXT_CRTC_GEN_CNTL BlockIOTag(0x17u) /* VT-A4 */
+#define CRTC2_OFF_PITCH BlockIOTag(0x17u) /* LTPro */
+#define CUR_CLR0 IOPortTag(0x0bu, 0x18u)
+#define CUR_CLR1 IOPortTag(0x0cu, 0x19u)
+#define CUR_OFFSET IOPortTag(0x0du, 0x1au)
+#define CUR_HORZ_VERT_POSN IOPortTag(0x0eu, 0x1bu)
+#define CUR_HORZ_VERT_OFF IOPortTag(0x0fu, 0x1cu)
+#define CONFIG_PANEL BlockIOTag(0x1du) /* LT */
+#define PANEL_FORMAT 0x00000007ul
+/* ? 0x00000008ul */
+#define PANEL_TYPE 0x000000f0ul
+#define NO_OF_GREY 0x00000700ul
+#define MOD_GEN 0x00001800ul
+#define EXT_LVDS_CLK 0x00001800ul /* LTPro */
+#define BLINK_RATE 0x00006000ul
+#define BLINK_RATE_PRO 0x00002000ul /* LTPro */
+#define DONT_SHADOW_HEND 0x00004000ul /* LTPro */
+#define DONT_USE_F32KHZ 0x00008000ul
+#define FP_POL 0x00010000ul
+#define LP_POL 0x00020000ul
+#define DTMG_POL 0x00040000ul
+#define SCK_POL 0x00080000ul
+#define DITHER_SEL 0x00300000ul
+#define INVERSE_VIDEO_EN 0x00400000ul
+#define BL_CLK_SEL 0x01800000ul
+#define BL_LEVEL 0x0e000000ul
+#define BL_CLK_SEL_PRO 0x00800000ul /* LTPro */
+#define BL_LEVEL_PRO 0x03000000ul /* LTPro */
+#define BIAS_LEVEL_PRO 0x0c000000ul /* LTPro */
+#define HSYNC_DELAY 0xf0000000ul
+#define TV_OUT_INDEX BlockIOTag(0x1du) /* LTPro */
+#define TV_REG_INDEX 0x000000fful
+#define TV_ON 0x00000100ul
+/* ? 0xfffffe00ul */
+#define GP_IO IOPortTag(0x1eu, 0x1eu) /* VT/GT */
+#define GP_IO_CNTL BlockIOTag(0x1fu) /* VT/GT */
+#define HW_DEBUG BlockIOTag(0x1fu) /* VTB/GTB/LT */
+#define SCRATCH_REG0 IOPortTag(0x10u, 0x20u)
+#define SCRATCH_REG1 IOPortTag(0x11u, 0x21u)
+/* BIOS_BASE_SEGMENT 0x0000007ful */ /* As above */
+/* ? 0x00000f80ul */
+#define BIOS_INIT_DAC_SUBTYPE 0x0000f000ul
+/* ? 0xffff0000ul */
+#define SCRATCH_REG2 BlockIOTag(0x22u) /* LT */
+#define SCRATCH_REG3 BlockIOTag(0x23u) /* GT3/LTPro */
+#define CLOCK_CNTL IOPortTag(0x12u, 0x24u)
+#define CLOCK_BIT 0x00000004ul /* For ICS2595 */
+#define CLOCK_PULSE 0x00000008ul /* For ICS2595 */
+#define CLOCK_SELECT 0x0000000ful
+#define CLOCK_DIVIDER 0x00000030ul
+#define CLOCK_STROBE 0x00000040ul
+#define CLOCK_DATA 0x00000080ul
+/* ? 0x00000100ul */
+#define PLL_WR_EN 0x00000200ul /* For internal PLL */
+#define PLL_ADDR 0x0000fc00ul /* For internal PLL */
+#define PLL_DATA 0x00ff0000ul /* For internal PLL */
+/* ? 0xff000000ul */
+#define CONFIG_STAT64_1 BlockIOTag(0x25u) /* GT3/LTPro */
+#define CFG_SUBSYS_DEV_ID 0x000000fful
+#define CFG_SUBSYS_VEN_ID 0x00ffff00ul
+/* ? 0x1f000000ul */
+#define CFG_DIMM_TYPE 0xe0000000ul
+#define CONFIG_STAT64_2 BlockIOTag(0x26u) /* GT3/LTPro */
+#define CFG_DIMM_TYPE_3 0x00000001ul
+/* ? 0x0000001eul */
+#define CFG_ROMWRTEN 0x00000020ul
+#define CFG_AGPVCOGAIN 0x000000c0ul
+#define CFG_PCI_TYPE 0x00000100ul
+#define CFG_AGPSKEW 0x00000e00ul
+#define CFG_X1CLKSKEW 0x00007000ul
+#define CFG_PANEL_ID_P 0x000f8000ul /* LTPro */
+/* ? 0x00100000ul */
+#define CFG_PREFETCH_EN 0x00200000ul
+#define CFG_ID_DISABLE 0x00400000ul
+#define CFG_PRE_TESTEN 0x00800000ul
+/* ? 0x01000000ul */
+#define CFG_PCI5VEN 0x02000000ul /* LTPro */
+#define CFG_VGA_DISABLE 0x04000000ul
+#define CFG_ENINTB 0x08000000ul
+/* ? 0x10000000ul */
+#define CFG_ROM_REMAP_2 0x20000000ul
+#define CFG_IDSEL 0x40000000ul
+/* ? 0x80000000ul */
+#define TV_OUT_DATA BlockIOTag(0x27u) /* LTPro */
+#define BUS_CNTL IOPortTag(0x13u, 0x28u)
+#define BUS_WS 0x0000000ful
+#define BUS_DBL_RESYNC 0x00000001ul /* VTB/GTB/LT */
+#define BUS_MSTR_RESET 0x00000002ul /* VTB/GTB/LT */
+#define BUS_FLUSH_BUF 0x00000004ul /* VTB/GTB/LT */
+#define BUS_STOP_REQ_DIS 0x00000008ul /* VTB/GTB/LT */
+#define BUS_ROM_WS 0x000000f0ul
+#define BUS_APER_REG_DIS 0x00000010ul /* VTB/GTB/LT */
+#define BUS_EXTRA_PIPE_DIS 0x00000020ul /* VTB/GTB/LT */
+#define BUS_MASTER_DIS 0x00000040ul /* VTB/GTB/LT */
+#define BUS_ROM_WRT_EN 0x00000080ul /* GT3/LTPro */
+#define BUS_ROM_PAGE 0x00000f00ul
+#define BUS_MINOR_REV_ID 0x00000700ul /* LTPro */
+/* First silicom - Prototype (A11) 0x00000000ul */
+/* Metal mask spin (A12 & A13) 0x00000100ul */
+/* All layer spin (A21) 0x00000200ul */
+/* Fast metal spin (A22) - Prod. 0x00000300ul */
+/* All layer spin (A31) 0x00000700ul */
+/* ? 0x00000800ul */ /* LTPro */
+#define BUS_ROM_DIS 0x00001000ul
+#define BUS_IO_16_EN 0x00002000ul /* GX */
+#define BUS_PCI_READ_RETRY_EN 0x00002000ul /* VTB/GTB/LT */
+#define BUS_DAC_SNOOP_EN 0x00004000ul
+#define BUS_PCI_RETRY_EN 0x00008000ul /* VT/GT */
+#define BUS_PCI_WRT_RETRY_EN 0x00008000ul /* VTB/GTB/LT */
+#define BUS_FIFO_WS 0x000f0000ul
+#define BUS_RETRY_WS 0x000f0000ul /* VTB/GTB/LT */
+#define BUS_FIFO_ERR_INT_EN 0x00100000ul
+#define BUS_MSTR_RD_MULT 0x00100000ul /* VTB/GTB/LT */
+#define BUS_FIFO_ERR_INT 0x00200000ul
+#define BUS_MSTR_RD_LINE 0x00200000ul /* VTB/GTB/LT */
+#define BUS_HOST_ERR_INT_EN 0x00400000ul
+#define BUS_SUSPEND 0x00400000ul /* GT3/LTPro */
+#define BUS_HOST_ERR_INT 0x00800000ul
+#define BUS_LAT16X 0x00800000ul /* GT3/LTPro */
+#define BUS_PCI_DAC_WS 0x07000000ul
+#define BUS_RD_DISCARD_EN 0x01000000ul /* VTB/GTB/LT */
+#define BUS_RD_ABORT_EN 0x02000000ul /* VTB/GTB/LT */
+#define BUS_MSTR_WS 0x04000000ul /* VTB/GTB/LT */
+#define BUS_PCI_DAC_DLY 0x08000000ul
+#define BUS_EXT_REG_EN 0x08000000ul /* VT/GT */
+#define BUS_PCI_MEMW_WS 0x10000000ul
+#define BUS_MSTR_DISCONNECT_EN 0x10000000ul /* VTB/GTB/LT */
+#define BUS_PCI_BURST_DEC 0x20000000ul /* GX/CX */
+#define BUS_BURST 0x20000000ul /* 264xT */
+#define BUS_WRT_BURST 0x20000000ul /* VTB/GTB/LT */
+#define BUS_RDY_READ_DLY 0xc0000000ul
+#define BUS_READ_BURST 0x40000000ul /* VTB/GTB/LT */
+#define BUS_RDY_READ_DLY_B 0x80000000ul /* VTB/GTB/LT */
+#define LCD_INDEX BlockIOTag(0x29u) /* LTPro */
+#define LCD_REG_INDEX 0x0000000ful
+/* ? 0x000000f0ul */
+#define LCD_DISPLAY_DIS 0x00000100ul
+#define LCD_SRC_SEL 0x00000200ul
+#define LCD_SRC_SEL_CRTC1 0x00000000ul
+#define LCD_SRC_SEL_CRTC2 0x00000200ul
+#define LCD_CRTC2_DISPLAY_DIS 0x00000400ul
+/* ? 0xfffff800ul */
+#define HFB_PITCH_ADDR BlockIOTag(0x2au) /* LT */
+#define LCD_DATA BlockIOTag(0x2au) /* LTPro */
+#define EXT_MEM_CNTL BlockIOTag(0x2bu) /* VTB/GTB/LT */
+#define MEM_INFO IOPortTag(0x14u, 0x2cu) /* Renamed MEM_CNTL */
+#define CTL_MEM_SIZE 0x00000007ul
+/* ? 0x00000008ul */
+#define CTL_MEM_REFRESH 0x00000078ul /* VT/GT */
+#define CTL_MEM_SIZEB 0x0000000ful /* VTB/GTB/LT */
+#define CTL_MEM_RD_LATCH_EN 0x00000010ul
+#define CTL_MEM_RD_LATCH_DLY 0x00000020ul
+#define CTL_MEM_LATENCY 0x00000030ul /* VTB/GTB/LT */
+#define CTL_MEM_SD_LATCH_EN 0x00000040ul
+#define CTL_MEM_SD_LATCH_DLY 0x00000080ul
+#define CTL_MEM_LATCH 0x000000c0ul /* VTB/GTB/LT */
+#define CTL_MEM_FULL_PLS 0x00000100ul
+#define CTL_MEM_CYC_LNTH_AUX 0x00000180ul /* VT/GT */
+#define CTL_MEM_TRP 0x00000300ul /* VTB/GTB/LT */
+#define CTL_MEM_CYC_LNTH 0x00000600ul
+#define CTL_MEM_REFRESH_RATE 0x00001800ul /* 264xT */
+#define CTL_MEM_TRCD 0x00000c00ul /* VTB/GTB/LT */
+#define CTL_MEM_WR_RDY_SEL 0x00000800ul /* GX/CX */
+#define CTL_MEM_EXT_RMW_CYC_EN 0x00001000ul /* GX/CX */
+#define CTL_MEM_TCRD 0x00001000ul /* VTB/GTB/LT */
+#define CTL_MEM_DLL_RESET 0x00002000ul /* VT/GT */
+#define CTL_MEM_TR2W 0x00002000ul /* GT3/LTPro */
+#define CTL_MEM_ACTV_PRE 0x0000c000ul /* VT/GT */
+#define CTL_MEM_CAS_PHASE 0x00004000ul /* GT3/LTPro */
+#define CTL_MEM_OE_PULLBACK 0x00008000ul /* GT3/LTPro */
+#define CTL_MEM_BNDRY 0x00030000ul
+#define CTL_MEM_BNDRY_0K 0x00000000ul
+#define CTL_MEM_BNDRY_256K 0x00010000ul
+#define CTL_MEM_BNDRY_512K 0x00020000ul
+#define CTL_MEM_BNDRY_1024K 0x00030000ul
+#define CTL_MEM_DLL_GAIN_CNTL 0x00030000ul /* VT/GT */
+#define CTL_MEM_BNDRY_EN 0x00040000ul
+#define CTL_MEM_SDRAM_RESET 0x00040000ul /* VT/GT */
+#define CTL_MEM_TRAS 0x00070000ul /* VTB/GTB/LT */
+#define CTL_MEM_TILE_SELECT 0x00180000ul /* VT/GT */
+#define CTL_MEM_REFRESH_DIS 0x00080000ul /* VTB/GTB/LT */
+#define CTL_MEM_LOW_LATENCY_MODE 0x00200000ul /* VT/GT */
+#define CTL_MEM_CDE_PULLBACK 0x00400000ul /* VT/GT */
+#define CTL_MEM_REFRESH_RATE_B 0x00700000ul /* VTB/GTB/LT */
+/* ? 0x00800000ul */
+#define CTL_MEM_PIX_WIDTH 0x07000000ul
+#define CTL_MEM_LOWER_APER_ENDIAN 0x03000000ul /* VTB/GTB/LT */
+#define CTL_MEM_OE_SELECT 0x18000000ul /* VT/GT */
+#define CTL_MEM_UPPER_APER_ENDIAN 0c0c000000ul /* VTB/GTB/LT */
+/* ? 0xe0000000ul */
+#define CTL_MEM_PAGE_SIZE 0x30000000ul /* VTB/GTB/LT */
+#define MEM_VGA_WP_SEL IOPortTag(0x15u, 0x2du)
+#define MEM_VGA_WPS0 0x0000fffful
+#define MEM_VGA_WPS1 0xffff0000ul
+#define MEM_VGA_RP_SEL IOPortTag(0x16u, 0x2eu)
+#define MEM_VGA_RPS0 0x0000fffful
+#define MEM_VGA_RPS1 0xffff0000ul
+#define LT_GIO BlockIOTag(0x2fu) /* LT */
+#define I2C_CNTL_1 BlockIOTag(0x2fu) /* GT3/LTPro */
+#define DAC_REGS IOPortTag(0x17u, 0x30u) /* 4 separate bytes */
+#define DAC_CNTL IOPortTag(0x18u, 0x31u)
+#define DAC_EXT_SEL 0x00000003ul
+#define DAC_EXT_SEL_RS2 0x000000001ul
+#define DAC_EXT_SEL_RS3 0x000000002ul
+#define DAC_RANGE_CTL 0x00000003ul /* VTB/GTB/LT */
+#define DAC_BLANKING 0x00000004ul /* 264xT */
+#define DAC_CMP_DIS 0x00000008ul /* 264xT */
+#define DAC1_CLK_SEL 0x00000010ul /* LTPro */
+#define DAC_PALETTE_ACCESS_CNTL 0x00000020ul /* LTPro */
+#define DAC_PALETTE2_SNOOP_EN 0x00000040ul /* LTPro */
+#define DAC_CMP_OUTPUT 0x00000080ul /* 264xT */
+#define DAC_8BIT_EN 0x00000100ul
+#define DAC_PIX_DLY 0x00000600ul
+#define DAC_DIRECT 0x00000400ul /* VTB/GTB/LT */
+#define DAC_BLANK_ADJ 0x00001800ul
+#define DAC_PAL_CLK_SEL 0x00000800ul /* VTB/GTB/LT */
+#define DAC_VGA_ADR_EN 0x00002000ul
+#define DAC_FEA_CON_EN 0x00004000ul /* 264xT */
+#define DAC_PDMN 0x00008000ul /* 264xT */
+#define DAC_TYPE 0x00070000ul
+/* ? 0x00f80000ul */
+#define DAC_MON_ID_STATE0 0x01000000ul /* GX-E+/CX */
+#define DAC_GIO_STATE_1 0x01000000ul /* 264xT */
+#define DAC_MON_ID_STATE1 0x02000000ul /* GX-E+/CX */
+#define DAC_GIO_STATE_0 0x02000000ul /* 264xT */
+#define DAC_MON_ID_STATE2 0x04000000ul /* GX-E+/CX */
+#define DAC_GIO_STATE_4 0x04000000ul /* 264xT */
+#define DAC_MON_ID_DIR0 0x08000000ul /* GX-E+/CX */
+#define DAC_GIO_DIR_1 0x08000000ul /* 264xT */
+#define DAC_MON_ID_DIR1 0x10000000ul /* GX-E+/CX */
+#define DAC_GIO_DIR_0 0x10000000ul /* 264xT */
+#define DAC_MON_ID_DIR2 0x20000000ul /* GX-E+/CX */
+#define DAC_GIO_DIR_4 0x20000000ul /* 264xT */
+#define DAC_MAN_CMP_STATE 0x40000000ul /* GX-E+ */
+#define DAC_RW_WS 0x80000000ul /* VT/GT */
+#define HORZ_STRETCHING BlockIOTag(0x32u) /* LT */
+#define HORZ_STRETCH_BLEND 0x00000ffful
+#define HORZ_STRETCH_RATIO 0x0000fffful
+#define HORZ_STRETCH_LOOP 0x00070000ul
+#define HORZ_STRETCH_LOOP09 0x00000000ul
+#define HORZ_STRETCH_LOOP11 0x00010000ul
+#define HORZ_STRETCH_LOOP12 0x00020000ul
+#define HORZ_STRETCH_LOOP14 0x00030000ul
+#define HORZ_STRETCH_LOOP15 0x00040000ul
+/* ? 0x00050000ul */
+/* ? 0x00060000ul */
+/* ? 0x00070000ul */
+/* ? 0x3ff80000ul */
+#define HORZ_STRETCH_MODE 0x40000000ul
+#define HORZ_STRETCH_EN 0x80000000ul
+#define EXT_DAC_REGS BlockIOTag(0x32u) /* GT3 */
+#define VERT_STRETCHING BlockIOTag(0x33u) /* LT */
+#define VERT_STRETCH_RATIO0 0x000003fful
+#define VERT_STRETCH_RATIO1 0x000ffc00ul
+#define VERT_STRETCH_RATIO2 0x3ff00000ul
+#define VERT_STRETCH_USE0 0x40000000ul
+#define VERT_STRETCH_EN 0x80000000ul
+#define GEN_TEST_CNTL IOPortTag(0x19u, 0x34u)
+#define GEN_EE_DATA_OUT 0x00000001ul /* GX/CX */
+#define GEN_GIO2_DATA_OUT 0x00000001ul /* 264xT */
+#define GEN_EE_CLOCK 0x00000002ul /* GX/CX */
+/* ? 0x00000002ul */ /* 264xT */
+#define GEN_EE_CHIP_SEL 0x00000004ul /* GX/CX */
+#define GEN_GIO3_DATA_OUT 0x00000004ul /* 264xT */
+#define GEN_EE_DATA_IN 0x00000008ul /* GX/CX */
+#define GEN_GIO2_DATA_IN 0x00000008ul /* 264xT */
+#define GEN_EE_EN 0x00000010ul /* GX/CX */
+#define GEN_GIO2_ENABLE 0x00000010ul /* 264xT */
+#define GEN_OVR_OUTPUT_EN 0x00000020ul /* GX/CX */
+#define GEN_GIO2_WRITE 0x00000020ul /* 264xT */
+#define GEN_OVR_POLARITY 0x00000040ul /* GX/CX */
+/* ? 0x00000040ul */ /* 264xT */
+#define GEN_CUR_EN 0x00000080ul
+#define GEN_GUI_EN 0x00000100ul /* GX/CX */
+#define GEN_GUI_RESETB 0x00000100ul /* 264xT */
+#define GEN_BLOCK_WR_EN 0x00000200ul /* GX */
+/* ? 0x00000200ul */ /* CX/264xT */
+#define GEN_SOFT_RESET 0x00000200ul /* VTB/GTB/LT */
+#define GEN_MEM_TRISTATE 0x00000400ul /* GT3/LTPro */
+/* ? 0x00000800ul */
+#define GEN_TEST_VECT_MODE 0x00003000ul /* VT/GT */
+/* ? 0x0000c000ul */
+#define GEN_TEST_FIFO_EN 0x00010000ul /* GX/CX */
+#define GEN_TEST_GUI_REGS_EN 0x00020000ul /* GX/CX */
+#define GEN_TEST_VECT_EN 0x00040000ul /* GX/CX */
+#define GEN_TEST_CRC_STR 0x00080000ul /* GX-C/-D */
+/* ? 0x00080000ul */ /* GX-E+/CX */
+#define GEN_TEST_MODE_T 0x000f0000ul /* 264xT */
+#define GEN_TEST_MODE 0x00700000ul /* GX/CX */
+#define GEN_TEST_CNT_EN 0x00100000ul /* 264xT */
+#define GEN_TEST_CRC_EN 0x00200000ul /* 264xT */
+/* ? 0x00400000ul */ /* 264xT */
+/* ? 0x00800000ul */
+#define GEN_TEST_MEM_WR 0x01000000ul /* GX-C/-D */
+#define GEN_TEST_MEM_STROBE 0x02000000ul /* GX-C/-D */
+#define GEN_TEST_DST_SS_EN 0x04000000ul /* GX/CX */
+#define GEN_TEST_DST_SS_STROBE 0x08000000ul /* GX/CX */
+#define GEN_TEST_SRC_SS_EN 0x10000000ul /* GX/CX */
+#define GEN_TEST_SRC_SS_STROBE 0x20000000ul /* GX/CX */
+#define GEN_TEST_CNT_VALUE 0x3f000000ul /* 264xT */
+#define GEN_TEST_CC_EN 0x40000000ul /* GX/CX */
+#define GEN_TEST_CC_STROBE 0x80000000ul /* GX/CX */
+/* ? 0xc0000000ul */ /* 264xT */
+#define GEN_DEBUG_MODE 0xff000000ul /* VTB/GTB/LT */
+#define LCD_GEN_CTRL BlockIOTag(0x35u) /* LT */
+#define CRT_ON 0x00000001ul
+#define LCD_ON 0x00000002ul
+#define HORZ_DIVBY2_EN 0x00000004ul
+#define DONT_DS_ICON 0x00000008ul
+#define LOCK_8DOT 0x00000010ul
+#define ICON_ENABLE 0x00000020ul
+#define DONT_SHADOW_VPAR 0x00000040ul
+#define V2CLK_ALWAYS_ONb 0x00000080ul
+#define RST_FM 0x00000100ul
+/* ? 0x00000200ul */
+#define DIS_HOR_CRT_DIVBY2 0x00000400ul
+#define SCLK_SEL 0x00000800ul
+#define SCLK_DELAY 0x0000f000ul
+#define TVCLK_ALWAYS_ONb 0x00010000ul
+#define VCLK_DAC_ALWAYS_ONb 0x00020000ul
+#define VCLK_LCD_OFF 0x00040000ul
+#define SELECT_WAIT_4MS 0x00080000ul
+#define V2CLK_DAC_ALWAYS_ONb 0x00100000ul
+#define LVDS_EN 0x00200000ul
+#define LVDS_PLL_EN 0x00400000ul
+#define LVDS_PLL_RESET 0x00800000ul
+#define LVDS_RESERVED_BITS 0x07000000ul
+#define CRTC_RW_SELECT 0x08000000ul /* LTPro */
+#define USE_SHADOWED_VEND 0x10000000ul
+#define USE_SHADOWED_ROWCUR 0x20000000ul
+#define SHADOW_EN 0x40000000ul
+#define SHADOW_RW_EN 0x80000000ul
+#define CUSTOM_MACRO_CNTL BlockIOTag(0x35u) /* GT3/LTPro */
+#define POWER_MANAGEMENT BlockIOTag(0x36u) /* LT */
+#define PWR_MGT_ON 0x00000001ul
+#define PWR_MGT_MODE 0x00000006ul
+#define AUTO_PWRUP_EN 0x00000008ul
+#define ACTIVITY_PIN_ON 0x00000010ul
+#define STANDBY_POL 0x00000020ul
+#define SUSPEND_POL 0x00000040ul
+#define SELF_REFRESH 0x00000080ul
+#define ACTIVITY_PIN_EN 0x00000100ul
+#define KEYBD_SNOOP 0x00000200ul
+#define USE_F32KHZ 0x00000400ul /* LTPro */
+#define TRISTATE_MEM_EN 0x00000800ul /* LTPro */
+#define LCDENG_TEST_MODE 0x0000f000ul
+#define STANDBY_COUNT 0x000f0000ul
+#define SUSPEND_COUNT 0x00f00000ul
+#define BAISON 0x01000000ul
+#define BLON 0x02000000ul
+#define DIGON 0x04000000ul
+/* ? 0x08000000ul */
+#define STANDBY_NOW 0x10000000ul
+#define SUSPEND_NOW 0x20000000ul
+#define PWR_MGT_STATUS 0xc0000000ul
+#define CONFIG_CNTL IOPortTag(0x1au, 0x37u)
+#define CFG_MEM_AP_SIZE 0x00000003ul
+#define CFG_MEM_VGA_AP_EN 0x00000004ul
+/* ? 0x00000008ul */
+#define CFG_MEM_AP_LOC 0x00003ff0ul
+/* ? 0x0000c000ul */
+#define CFG_CARD_ID 0x00070000ul
+#define CFG_VGA_DIS 0x00080000ul
+/* ? 0x00f00000ul */
+#define CFG_CDE_WINDOW 0x3f000000ul /* VT/GT */
+/* ? 0xc0000000ul */
+#define CONFIG_CHIP_ID IOPortTag(0x1bu, 0x38u) /* Read */
+#define CFG_CHIP_TYPE0 0x000000fful
+#define CFG_CHIP_TYPE1 0x0000ff00ul
+#define CFG_CHIP_TYPE 0x0000fffful
+#define CFG_CHIP_CLASS 0x00ff0000ul
+#define CFG_CHIP_REV 0xff000000ul
+#define CFG_CHIP_VERSION 0x07000000ul /* 264xT */
+#define CFG_CHIP_FOUNDRY 0x38000000ul /* 264xT */
+#define CFG_CHIP_REVISION 0xc0000000ul /* 264xT */
+#define CONFIG_STATUS64_0 IOPortTag(0x1cu, 0x39u) /* Read (R/W (264xT)) */
+#define CFG_BUS_TYPE 0x00000007ul /* GX/CX */
+#define CFG_MEM_TYPE_T 0x00000007ul /* 264xT */
+#define CFG_MEM_TYPE 0x00000038ul /* GX/CX */
+#define CFG_DUAL_CAS_EN_T 0x00000008ul /* 264xT */
+#define CFG_ROM_128K_EN 0x00000008ul /* VTB/GTB/LT */
+#define CFG_ROM_REMAP 0x00000008ul /* GT3/LTPro */
+#define CFG_VGA_EN_T 0x00000010ul /* VT/GT */
+#define CFG_CLOCK_EN 0x00000020ul /* 264xT */
+#define CFG_DUAL_CAS_EN 0x00000040ul /* GX/CX */
+#define CFG_VMC_SENSE 0x00000040ul /* VT/GT */
+#define CFG_SHARED_MEM_EN 0x00000040ul /* VTB/GTB/LT */
+#define CFG_LOCAL_BUS_OPTION 0x00000180ul /* GX/CX */
+#define CFG_VFC_SENSE 0x00000080ul /* VT/GT */
+#define CFG_INIT_DAC_TYPE 0x00000e00ul /* GX/CX */
+#define CFG_INIT_CARD_ID 0x00007000ul /* GX-C/-D */
+#define CFG_BLK_WR_SIZE 0x00001000ul /* GX-E+ */
+#define CFG_INT_QSF_EN 0x00002000ul /* GX-E+ */
+/* ? 0x00004000ul */ /* GX-E+ */
+/* ? 0x00007000ul */ /* CX */
+#define CFG_TRI_BUF_DIS 0x00008000ul /* GX/CX */
+#define CFG_BOARD_ID 0x0000ff00ul /* VT/GT */
+#define CFG_EXT_RAM_ADDR 0x003f0000ul /* GX/CX */
+#define CFG_PANEL_ID 0x001f0000ul /* LT */
+#define CFG_MACROVISION_EN 0x00200000ul /* GT3/LTPro */
+#define CFG_ROM_DIS 0x00400000ul /* GX/CX */
+#define CFG_PCI33EN 0x00400000ul /* GT3/LTPro */
+#define CFG_VGA_EN 0x00800000ul /* GX/CX */
+#define CFG_FULLAGP 0x00800000ul /* GT3/LTPro */
+#define CFG_LOCAL_BUS_CFG 0x01000000ul /* GX/CX */
+#define CFG_CHIP_EN 0x02000000ul /* GX/CX */
+#define CFG_LOCAL_READ_DLY_DIS 0x04000000ul /* GX/CX */
+#define CFG_ROM_OPTION 0x08000000ul /* GX/CX */
+#define CFG_BUS_OPTION 0x10000000ul /* GX/CX */
+#define CFG_LOCAL_DAC_WR_EN 0x20000000ul /* GX/CX */
+#define CFG_VLB_RDY_DIS 0x40000000ul /* GX/CX */
+#define CFG_AP_4GBYTE_DIS 0x80000000ul /* GX/CX */
+#define CONFIG_STATUS64_1 IOPortTag(0x1du, 0x3au) /* Read */
+#define CFG_PCI_DAC_CFG 0x00000001ul /* GX/CX */
+/* ? 0x0000001eul */ /* GX/CX */
+#define CFG_1C8_IO_SEL 0x00000020ul /* GX/CX */
+/* ? 0xffffffc0ul */ /* GX/CX */
+#define CRC_SIG 0xfffffffful /* 264xT */
+#define MPP_CONFIG BlockIOTag(0x3bu) /* VTB/GTB/LT */
+#define MPP_STROBE_CONFIG BlockIOTag(0x3cu) /* VTB/GTB/LT */
+#define MPP_ADDR BlockIOTag(0x3du) /* VTB/GTB/LT */
+#define MPP_DATA BlockIOTag(0x3eu) /* VTB/GTB/LT */
+#define TVO_CNTL BlockIOTag(0x3fu) /* VTB/GTB/LT */
+/* GP_IO IOPortTag(0x1eu, 0x1eu) */ /* See above */
+/* CRTC_H_TOTAL_DISP IOPortTag(0x1fu, 0x00u) */ /* Duplicate */
+
+/* Definitions for an ICS2595's programme word */
+#define ICS2595_CLOCK 0x000001f0ul
+#define ICS2595_FB_DIV 0x0001fe00ul /* Feedback divider */
+#define ICS2595_POST_DIV 0x000c0000ul /* Post-divider */
+#define ICS2595_STOP 0x00300000ul /* Stop bits */
+#define ICS2595_TOGGLE (ICS2595_POST_DIV | ICS2595_STOP)
+
+/* Definitions for internal PLL registers on a 264xT */
+#define PLL_MPLL_CNTL 0x00u
+#define MPLL_PC_GAIN 0x07u
+#define MPLL_VC_GAIN 0x18u
+#define MPLL_D_CYC 0x60u
+#define MPLL_RANGE 0x80u
+#define VPLL_CNTL 0x01u
+#define VPLL_PC_GAIN 0x07u
+#define VPLL_VC_GAIN 0x18u
+#define VPLL_D_CYC 0x60u
+#define VPLL_RANGE 0x80u
+#define PLL_REF_DIV 0x02u
+#define PLL_GEN_CNTL 0x03u
+#define PLL_OVERRIDE 0x01u
+#define PLL_SLEEP 0x01u /* GT3/LTPro */
+#define PLL_MCLK_RESET 0x02u
+#define PLL_OSC_EN 0x04u
+#define PLL_EXT_CLK_EN 0x08u
+#define PLL_MCLK_SRC_SEL 0x70u
+#define PLL_EXT_CLK_CNTL 0x80u /* CT/ET */
+#define PLL_DLL_PWDN 0x80u /* VTB/GTB/LT */
+#define PLL_MCLK_FB_DIV 0x04u
+#define PLL_VCLK_CNTL 0x05u
+#define PLL_VCLK_SRC_SEL 0x03u
+#define PLL_VCLK_RESET 0x04u
+#define PLL_VCLK_INVERT 0x08u
+#define PLL_ECP_DIV 0x30u /* VT/GT */
+#define PLL_ERATE_GT_XRATE 0x40u /* VT/GT */
+#define PLL_SCALER_LOCK_EN 0x80u /* VT/GT */
+#define PLL_VCLK_POST_DIV 0x06u
+#define PLL_VCLK0_POST_DIV 0x03u
+#define PLL_VCLK1_POST_DIV 0x0cu
+#define PLL_VCLK2_POST_DIV 0x30u
+#define PLL_VCLK3_POST_DIV 0xc0u
+#define PLL_VCLK0_FB_DIV 0x07u
+#define PLL_VCLK1_FB_DIV 0x08u
+#define PLL_VCLK2_FB_DIV 0x09u
+#define PLL_VCLK3_FB_DIV 0x0au
+#define PLL_XCLK_CNTL 0x0bu /* VT/GT */
+#define PLL_XCLK_MCLK_RATIO 0x03u
+#define PLL_XCLK_SRC_SEL 0x07u /* VTB/GTB/LT */
+#define PLL_MFB_TIMES_4_2B 0x08u
+#define PLL_VCLK0_XDIV 0x10u
+#define PLL_VCLK1_XDIV 0x20u
+#define PLL_VCLK2_XDIV 0x40u
+#define PLL_VCLK3_XDIV 0x80u
+#define PLL_FCP_CNTL 0x0cu /* VT/GT */
+#define PLL_FCP_POST_DIV 0x0fu
+#define PLL_FCP_SRC_SEL 0x70u
+#define PLL_DCLK_BY2_EN 0x80u
+#define PLL_DLL_CNTL 0x0cu /* VTB/GTB/LT */
+#define PLL_DLL_REF_SRC 0x03u
+#define PLL_DLL_FB_SRC 0x0cu
+#define PLL_DLL_GAIN 0x30u
+#define PLL_DLL_RESET 0x40u
+#define PLL_DLL_HCLK_OUT_EN 0x80u
+#define PLL_VFC_CNTL 0x0du /* VT/GT */
+#define PLL_DCLK_INVB 0x01u
+#define PLL_DCLKBY2_EN 0x02u
+#define PLL_VFC_2PHASE 0x04u
+#define PLL_VFC_DELAY 0x18u
+#define PLL_VFC_DCLKBY2_SHIFT 0x20u
+/* ? 0x40u */
+#define PLL_TST_SRC_SEL_BIT5 0x80u /* VTB/GTB/LT */
+#define PLL_TEST_CNTL 0x0eu
+#define PLL_TST_SRC_SEL 0x1fu
+#define PLL_TST_DIVIDERS 0x20u
+#define PLL_TST_MASK_READ 0x40u
+#define PLL_TST_ANALOG_MON_EN 0x80u
+#define PLL_TEST_COUNT 0x0fu
+#define PLL_LVDSPLL_CNTL0 0x10u /* LT */
+#define PLL_FPDI_NS_TIMING 0x01u
+#define PLL_CURR_LEVEL 0x0eu
+#define PLL_LVDS_TEST_MODE 0xf0u
+#define PLL_LVDSPLL_CNTL1 0x11u /* LT */
+#define PLL_LPPL_RANGE 0x01u
+#define PLL_LPLL_DUTY 0x06u
+#define PLL_LPLL_VC_GAIN 0x18u
+#define PLL_LPLL_CP_GAIN 0xe0u
+#define PLL_AGP1_CNTL 0x12u /* GT3/LTPro */
+#define PLL_AGP2_CNTL 0x13u /* GT3/LTPro */
+#define PLL_DLL2_CNTL 0x14u /* GT3/LTPro */
+#define PLL_SCLK_FB_DIV 0x15u /* GT3/LTPro */
+#define PLL_SPLL_CNTL1 0x16u /* GT3/LTPro */
+#define PLL_SPLL_CNTL2 0x17u /* GT3/LTPro */
+#define PLL_APLL_STRAPS 0x18u /* GT3/LTPro */
+#define PLL_EXT_VPLL_CNTL 0x19u /* GT3/LTPro */
+#define PLL_EXT_VPLL_REF_SRC 0x03u
+#define PLL_EXT_VPLL_EN 0x04u
+#define PLL_EXT_VPLL_VGA_EN 0x08u
+#define PLL_EXT_VPLL_INSYNC 0x10u
+/* ? 0x60u */
+#define PLL_EXT_V2PLL_EN 0x80u
+#define PLL_EXT_VPLL_REF_DIV 0x1au /* GT3/LTPro */
+#define PLL_EXT_VPLL_FB_DIV 0x1bu /* GT3/LTPro */
+#define PLL_EXT_VPLL_MSB 0x1cu /* GT3/LTPro */
+#define PLL_HTOTAL_CNTL 0x1du /* GT3/LTPro */
+#define PLL_BYTE_CLK_CNTL 0x1eu /* GT3/LTPro */
+#define PLL_TV_REF_DIV 0x1fu /* LTPro */
+#define PLL_TV_FB_DIV 0x20u /* LTPro */
+#define PLL_TV_CNTL 0x21u /* LTPro */
+#define PLL_TV_GEN_CNTL 0x22u /* LTPro */
+#define PLL_V2_CNTL 0x23u /* LTPro */
+#define PLL_V2_GEN_CNTL 0x24u /* LTPro */
+#define PLL_V2_REF_DIV 0x25u /* LTPro */
+#define PLL_V2_FB_DIV 0x26u /* LTPro */
+#define PLL_V2_MSB 0x27u /* LTPro */
+#define PLL_HTOTAL2_CNTL 0x28u /* LTPro */
+/* ? 0x29u */
+/* ? 0x2au */
+/* ? 0x2bu */
+/* ? 0x2cu */
+/* ? 0x2du */
+/* ? 0x2eu */
+/* ? 0x2fu */
+/* ? 0x30u */
+/* ? 0x31u */
+/* ? 0x32u */
+/* ? 0x33u */
+/* ? 0x34u */
+/* ? 0x35u */
+/* ? 0x36u */
+/* ? 0x37u */
+/* ? 0x38u */
+/* ? 0x39u */
+/* ? 0x3au */
+/* ? 0x3bu */
+/* ? 0x3cu */
+/* ? 0x3du */
+/* ? 0x3eu */
+/* ? 0x3fu */
+
+/* Definitions for an LTPro's 32-bit LCD registers */
+#define LCD_CONFIG_PANEL 0x00u /* See LT's CONFIG_PANEL (0x1d) */
+#define LCD_GEN_CNTL 0x01u /* See LT's LCD_GEN_CTRL (0x35) */
+#define LCD_DSTN_CONTROL 0x02u /* See LT's DSTN_CONTROL (0x1f) */
+#define LCD_HFB_PITCH_ADDR 0x03u /* See LT's HFB_PITCH_ADDR (0x2a) */
+#define LCD_HORZ_STRETCHING 0x04u /* See LT's HORZ_STRETCHING (0x32) */
+#define LCD_VERT_STRETCHING 0x05u /* See LT's VERT_STRETCHING (0x33) */
+#define LCD_EXT_VERT_STRETCH 0x06u
+#define VERT_STRETCH_RATIO3 0x000003fful
+#define FORCE_DAC_DATA 0x000000fful
+#define FORCE_DAC_DATA_SEL 0x00000300ul
+#define VERT_STRETCH_MODE 0x00000400ul
+#define VERT_PANEL_SIZE 0x003ff800ul
+#define AUTO_VERT_RATIO 0x00400000ul
+#define USE_AUTO_FP_POS 0x00800000ul
+#define USE_AUTO_LCD_VSYNC 0x01000000ul
+/* ? 0xfe000000ul */
+#define LCD_LT_GIO 0x07u /* See LT's LT_GIO (0x2f) */
+#define LCD_POWER_MANAGEMENT 0x08u /* See LT's POWER_MANAGEMENT (0x36) */
+#define LCD_ZVGPIO 0x09u
+/* ? 0x0au */
+/* ? 0x0bu */
+/* ? 0x0cu */
+/* ? 0x0du */
+/* ? 0x0eu */
+/* ? 0x0fu */
+
+/* Definitions for an LTPro's TV registers */
+/* ? 0x00u */
+/* ? 0x01u */
+/* ? 0x02u */
+/* ? 0x03u */
+/* ? 0x04u */
+/* ? 0x05u */
+/* ? 0x06u */
+/* ? 0x07u */
+/* ? 0x08u */
+/* ? 0x09u */
+/* ? 0x0au */
+/* ? 0x0bu */
+/* ? 0x0cu */
+/* ? 0x0du */
+/* ? 0x0eu */
+/* ? 0x0fu */
+#define TV_MASTER_CNTL 0x10u
+/* ? 0x11u */
+#define TV_RGB_CNTL 0x12u
+/* ? 0x13u */
+#define TV_SYNC_CNTL 0x14u
+/* ? 0x15u */
+/* ? 0x16u */
+/* ? 0x17u */
+/* ? 0x18u */
+/* ? 0x19u */
+/* ? 0x1au */
+/* ? 0x1bu */
+/* ? 0x1cu */
+/* ? 0x1du */
+/* ? 0x1eu */
+/* ? 0x1fu */
+#define TV_HTOTAL 0x20u
+#define TV_HDISP 0x21u
+#define TV_HSIZE 0x22u
+#define TV_HSTART 0x23u
+#define TV_HCOUNT 0x24u
+#define TV_VTOTAL 0x25u
+#define TV_VDISP 0x26u
+#define TV_VCOUNT 0x27u
+#define TV_FTOTAL 0x28u
+#define TV_FCOUNT 0x29u
+#define TV_FRESTART 0x2au
+#define TV_HRESTART 0x2bu
+#define TV_VRESTART 0x2cu
+/* ? 0x2du */
+/* ? 0x2eu */
+/* ? 0x2fu */
+/* ? 0x30u */
+/* ? 0x31u */
+/* ? 0x32u */
+/* ? 0x33u */
+/* ? 0x34u */
+/* ? 0x35u */
+/* ? 0x36u */
+/* ? 0x37u */
+/* ? 0x38u */
+/* ? 0x39u */
+/* ? 0x3au */
+/* ? 0x3bu */
+/* ? 0x3cu */
+/* ? 0x3du */
+/* ? 0x3eu */
+/* ? 0x3fu */
+/* ? 0x40u */
+/* ? 0x41u */
+/* ? 0x42u */
+/* ? 0x43u */
+/* ? 0x44u */
+/* ? 0x45u */
+/* ? 0x46u */
+/* ? 0x47u */
+/* ? 0x48u */
+/* ? 0x49u */
+/* ? 0x4au */
+/* ? 0x4bu */
+/* ? 0x4cu */
+/* ? 0x4du */
+/* ? 0x4eu */
+/* ? 0x4fu */
+/* ? 0x50u */
+/* ? 0x51u */
+/* ? 0x52u */
+/* ? 0x53u */
+/* ? 0x54u */
+/* ? 0x55u */
+/* ? 0x56u */
+/* ? 0x57u */
+/* ? 0x58u */
+/* ? 0x59u */
+/* ? 0x5au */
+/* ? 0x5bu */
+/* ? 0x5cu */
+/* ? 0x5du */
+/* ? 0x5eu */
+/* ? 0x5fu */
+#define TV_HOST_READ_DATA 0x60u
+#define TV_HOST_WRITE_DATA 0x61u
+#define TV_HOST_RD_WT_CNTL 0x62u
+/* ? 0x63u */
+/* ? 0x64u */
+/* ? 0x65u */
+/* ? 0x66u */
+/* ? 0x67u */
+/* ? 0x68u */
+/* ? 0x69u */
+/* ? 0x6au */
+/* ? 0x6bu */
+/* ? 0x6cu */
+/* ? 0x6du */
+/* ? 0x6eu */
+/* ? 0x6fu */
+#define TV_VSCALER_CNTL 0x70u
+#define TV_TIMING_CNTL 0x71u
+#define TV_GAMMA_CNTL 0x72u
+#define TV_Y_FALL_CNTL 0x73u
+#define TV_Y_RISE_CNTL 0x74u
+#define TV_Y_SAW_TOOTH_CNTL 0x75u
+/* ? 0x76u */
+/* ? 0x77u */
+/* ? 0x78u */
+/* ? 0x79u */
+/* ? 0x7au */
+/* ? 0x7bu */
+/* ? 0x7cu */
+/* ? 0x7du */
+/* ? 0x7eu */
+/* ? 0x7fu */
+#define TV_MODULATOR_CNTL1 0x80u
+#define TV_MODULATOR_CNTL2 0x81u
+/* ? 0x82u */
+/* ? 0x83u */
+/* ? 0x84u */
+/* ? 0x85u */
+/* ? 0x86u */
+/* ? 0x87u */
+/* ? 0x88u */
+/* ? 0x89u */
+/* ? 0x8au */
+/* ? 0x8bu */
+/* ? 0x8cu */
+/* ? 0x8du */
+/* ? 0x8eu */
+/* ? 0x8fu */
+#define TV_PRE_DAC_MUX_CNTL 0x90u
+/* ? 0x91u */
+/* ? 0x92u */
+/* ? 0x93u */
+/* ? 0x94u */
+/* ? 0x95u */
+/* ? 0x96u */
+/* ? 0x97u */
+/* ? 0x98u */
+/* ? 0x99u */
+/* ? 0x9au */
+/* ? 0x9bu */
+/* ? 0x9cu */
+/* ? 0x9du */
+/* ? 0x9eu */
+/* ? 0x9fu */
+#define TV_DAC_CNTL 0xa0u
+/* ? 0xa1u */
+/* ? 0xa2u */
+/* ? 0xa3u */
+/* ? 0xa4u */
+/* ? 0xa5u */
+/* ? 0xa6u */
+/* ? 0xa7u */
+/* ? 0xa8u */
+/* ? 0xa9u */
+/* ? 0xaau */
+/* ? 0xabu */
+/* ? 0xacu */
+/* ? 0xadu */
+/* ? 0xaeu */
+/* ? 0xafu */
+#define TV_CRC_CNTL 0xb0u
+#define TV_VIDEO_PORT_SIG 0xb1u
+/* ? 0xb2u */
+/* ? 0xb3u */
+/* ? 0xb4u */
+/* ? 0xb5u */
+/* ? 0xb6u */
+/* ? 0xb7u */
+#define TV_VBI_CC_CNTL 0xb8u
+#define TV_VBI_EDS_CNTL 0xb9u
+#define TV_VBI_20BIT_CNTL 0xbau
+/* ? 0xbbu */
+/* ? 0xbcu */
+#define TV_VBI_DTO_CNTL 0xbdu
+#define TV_VBI_LEVEL_CNTL 0xbeu
+/* ? 0xbfu */
+#define TV_UV_ADR 0xc0u
+#define TV_FIFO_TEST_CNTL 0xc1u
+/* ? 0xc2u */
+/* ? 0xc3u */
+/* ? 0xc4u */
+/* ? 0xc5u */
+/* ? 0xc6u */
+/* ? 0xc7u */
+/* ? 0xc8u */
+/* ? 0xc9u */
+/* ? 0xcau */
+/* ? 0xcbu */
+/* ? 0xccu */
+/* ? 0xcdu */
+/* ? 0xceu */
+/* ? 0xcfu */
+/* ? 0xd0u */
+/* ? 0xd1u */
+/* ? 0xd2u */
+/* ? 0xd3u */
+/* ? 0xd4u */
+/* ? 0xd5u */
+/* ? 0xd6u */
+/* ? 0xd7u */
+/* ? 0xd8u */
+/* ? 0xd9u */
+/* ? 0xdau */
+/* ? 0xdbu */
+/* ? 0xdcu */
+/* ? 0xddu */
+/* ? 0xdeu */
+/* ? 0xdfu */
+/* ? 0xe0u */
+/* ? 0xe1u */
+/* ? 0xe2u */
+/* ? 0xe3u */
+/* ? 0xe4u */
+/* ? 0xe5u */
+/* ? 0xe6u */
+/* ? 0xe7u */
+/* ? 0xe8u */
+/* ? 0xe9u */
+/* ? 0xeau */
+/* ? 0xebu */
+/* ? 0xecu */
+/* ? 0xedu */
+/* ? 0xeeu */
+/* ? 0xefu */
+/* ? 0xf0u */
+/* ? 0xf1u */
+/* ? 0xf2u */
+/* ? 0xf3u */
+/* ? 0xf4u */
+/* ? 0xf5u */
+/* ? 0xf6u */
+/* ? 0xf7u */
+/* ? 0xf8u */
+/* ? 0xf9u */
+/* ? 0xfau */
+/* ? 0xfbu */
+/* ? 0xfcu */
+/* ? 0xfdu */
+/* ? 0xfeu */
+/* ? 0xffu */
+
+/* Miscellaneous */
+
+/* Current X, Y & Dest X, Y mask */
+#define COORD_MASK 0x07ffu
+
+/* The Mixes */
+#define MIX_MASK 0x001fu
+
+#define MIX_NOT_DST 0x0000u
+#define MIX_0 0x0001u
+#define MIX_1 0x0002u
+#define MIX_DST 0x0003u
+#define MIX_NOT_SRC 0x0004u
+#define MIX_XOR 0x0005u
+#define MIX_XNOR 0x0006u
+#define MIX_SRC 0x0007u
+#define MIX_NAND 0x0008u
+#define MIX_NOT_SRC_OR_DST 0x0009u
+#define MIX_SRC_OR_NOT_DST 0x000au
+#define MIX_OR 0x000bu
+#define MIX_AND 0x000cu
+#define MIX_SRC_AND_NOT_DST 0x000du
+#define MIX_NOT_SRC_AND_DST 0x000eu
+#define MIX_NOR 0x000fu
+
+#define MIX_MIN 0x0010u
+#define MIX_DST_MINUS_SRC 0x0011u
+#define MIX_SRC_MINUS_DST 0x0012u
+#define MIX_PLUS 0x0013u
+#define MIX_MAX 0x0014u
+#define MIX_HALF__DST_MINUS_SRC 0x0015u
+#define MIX_HALF__SRC_MINUS_DST 0x0016u
+#define MIX_AVERAGE 0x0017u
+#define MIX_DST_MINUS_SRC_SAT 0x0018u
+#define MIX_SRC_MINUS_DST_SAT 0x001au
+#define MIX_HALF__DST_MINUS_SRC_SAT 0x001cu
+#define MIX_HALF__SRC_MINUS_DST_SAT 0x001eu
+#define MIX_AVERAGE_SAT 0x001fu
+#define MIX_FN_PAINT MIX_SRC
+
+#endif /* ___ATIREGS_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiscreen.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiscreen.c
new file mode 100644
index 000000000..9f234f36d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiscreen.c
@@ -0,0 +1,216 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiscreen.c,v 1.2 1999/08/01 07:57:22 dawes Exp $ */
+/*
+ * Copyright 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "ati.h"
+#include "aticonsole.h"
+#include "atidac.h"
+#include "atiscreen.h"
+
+#include "xf86cmap.h"
+
+#include "xf1bpp.h"
+#include "xf4bpp.h"
+#undef PSZ
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+
+#include "mibank.h"
+#include "micmap.h"
+#include "mipointer.h"
+
+/*
+ * ATIScreenInit --
+ *
+ * This function is called by DIX to initialize the screen.
+ */
+Bool
+ATIScreenInit
+(
+ int iScreen,
+ ScreenPtr pScreen,
+ int argc,
+ char **argv
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[iScreen];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ int VisualMask;
+
+ /* Set video hardware state */
+ if (!ATIEnterGraphics(pScreen, pScreenInfo, pATI))
+ return FALSE;
+
+ /* Re-initialize mi's visual list */
+ miClearVisualTypes();
+
+ if (pScreenInfo->depth > 8)
+ VisualMask = TrueColorMask;
+ else
+ VisualMask = miGetDefaultVisualMask(pScreenInfo->depth);
+
+ if (!miSetVisualTypes(pScreenInfo->depth, VisualMask,
+ pScreenInfo->rgbBits, pScreenInfo->defaultVisual))
+ return FALSE;
+
+ /* Initialize framebuffer layer */
+ switch (pScreenInfo->bitsPerPixel)
+ {
+ case 1:
+ pATI->Closeable = xf1bppScreenInit(pScreen, pATI->pMemory,
+ pScreenInfo->virtualX, pScreenInfo->virtualY,
+ pScreenInfo->xDpi, pScreenInfo->yDpi,
+ pScreenInfo->displayWidth);
+ break;
+
+ case 4:
+ pATI->Closeable = xf4bppScreenInit(pScreen, pATI->pMemory,
+ pScreenInfo->virtualX, pScreenInfo->virtualY,
+ pScreenInfo->xDpi, pScreenInfo->yDpi,
+ pScreenInfo->displayWidth);
+ break;
+
+ case 8:
+ pATI->Closeable = cfbScreenInit(pScreen, pATI->pMemory,
+ pScreenInfo->virtualX, pScreenInfo->virtualY,
+ pScreenInfo->xDpi, pScreenInfo->yDpi,
+ pScreenInfo->displayWidth);
+ break;
+
+ case 16:
+ pATI->Closeable = cfb16ScreenInit(pScreen, pATI->pMemory,
+ pScreenInfo->virtualX, pScreenInfo->virtualY,
+ pScreenInfo->xDpi, pScreenInfo->yDpi,
+ pScreenInfo->displayWidth);
+ break;
+
+ case 24:
+ pATI->Closeable = cfb24ScreenInit(pScreen, pATI->pMemory,
+ pScreenInfo->virtualX, pScreenInfo->virtualY,
+ pScreenInfo->xDpi, pScreenInfo->yDpi,
+ pScreenInfo->displayWidth);
+ break;
+
+ case 32:
+ pATI->Closeable = cfb32ScreenInit(pScreen, pATI->pMemory,
+ pScreenInfo->virtualX, pScreenInfo->virtualY,
+ pScreenInfo->xDpi, pScreenInfo->yDpi,
+ pScreenInfo->displayWidth);
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ if (!pATI->Closeable)
+ return FALSE;
+
+ /* Fixup RGB ordering */
+ if (pScreenInfo->depth > 8)
+ {
+ VisualPtr pVisual = pScreen->visuals + pScreen->numVisuals;
+
+ while (--pVisual >= pScreen->visuals)
+ {
+ if ((pVisual->class | DynamicClass) != DirectColor)
+ continue;
+
+ pVisual->offsetRed = pScreenInfo->offset.red;
+ pVisual->offsetGreen = pScreenInfo->offset.green;
+ pVisual->offsetBlue = pScreenInfo->offset.blue;
+
+ pVisual->redMask = pScreenInfo->mask.red;
+ pVisual->greenMask = pScreenInfo->mask.green;
+ pVisual->blueMask = pScreenInfo->mask.blue;
+ }
+ }
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ /* Initialize banking */
+ if ((pATI->ApertureSize < (pATI->VideoRAM * 1024)) &&
+ !miInitializeBanking(pScreen,
+ pScreenInfo->virtualX, pScreenInfo->virtualY,
+ pScreenInfo->displayWidth, &pATI->BankInfo))
+ return FALSE;
+
+ /* Initialize backing store */
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ /* Initialize software cursor */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ /* Create default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ if (pScreenInfo->depth > 1)
+ if (!xf86HandleColormaps(pScreen, (pScreenInfo->depth == 4) ? 16 : 256,
+ pScreenInfo->rgbBits, ATILoadPalette, NULL,
+ CMAP_PALETTED_TRUECOLOR |
+ CMAP_LOAD_EVEN_IF_OFFSCREEN))
+ return FALSE;
+
+ /* Set pScreen->SaveScreen and wrap CloseScreen vector */
+ pScreen->SaveScreen = ATISaveScreen;
+ pATI->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = ATICloseScreen;
+
+ if (serverGeneration == 1)
+ xf86ShowUnusedOptions(pScreenInfo->scrnIndex, pScreenInfo->options);
+
+ return TRUE;
+}
+
+/*
+ * ATICloseScreen --
+ *
+ * This function is called by DIX to close the screen.
+ */
+Bool
+ATICloseScreen
+(
+ int iScreen,
+ ScreenPtr pScreen
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[iScreen];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ Bool Closed = TRUE;
+
+ if ((pScreen->CloseScreen = pATI->CloseScreen))
+ {
+ pATI->CloseScreen = NULL;
+ Closed = (*pScreen->CloseScreen)(iScreen, pScreen);
+ }
+
+ pATI->Closeable = FALSE;
+
+ ATILeaveGraphics(pScreenInfo, pATI);
+
+ return Closed;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiscreen.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiscreen.h
new file mode 100644
index 000000000..0b8d4364b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiscreen.h
@@ -0,0 +1,33 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiscreen.h,v 1.1 1999/07/06 11:38:37 dawes Exp $ */
+/*
+ * Copyright 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATISCREEN_H___
+#define ___ATISCREEN_H___ 1
+
+#include "atiproto.h"
+#include "screenint.h"
+
+extern Bool ATIScreenInit FunctionPrototype((int, ScreenPtr, int, char **));
+extern Bool ATICloseScreen FunctionPrototype((int, ScreenPtr));
+
+#endif /* ___ATISCREEN_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atistruct.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atistruct.h
new file mode 100644
index 000000000..426dfd912
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atistruct.h
@@ -0,0 +1,261 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atistruct.h,v 1.3 1999/08/21 13:48:32 dawes Exp $ */
+/*
+ * Copyright 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATISTRUCT_H___
+#define ___ATISTRUCT_H___ 1
+
+#include "atibank.h"
+#include "aticlock.h"
+
+/*
+ * This is probably as good a place as any to put this note, as it applies to
+ * the entire driver, but especially here. CARD8's are used rather than the
+ * appropriate enum types because the latter would nearly quadruple storage
+ * requirements (they are stored as int's). This reduces the usefulness of
+ * enum types to their ability to declare index values. I've also elected to
+ * forgo the strong typing capabilities of enum types. C is not terribly adept
+ * at strong typing anyway.
+ */
+
+/* A structure for local data related to video modes */
+typedef struct _ATIHWRec
+{
+ /* Clock number for mode */
+ CARD8 clock;
+
+ /* The CRTC used to drive the screen (VGA, 8514, Mach64) */
+ CARD8 crtc;
+
+ /* VGA registers */
+ CARD8 genmo, crt[25], seq[5], gra[9], attr[21], lut[256 * 3];
+
+ /* Generic DAC registers */
+ CARD8 dac_read, dac_write, dac_mask;
+
+ /* VGA Wonder registers */
+ CARD8 a3, a6, a7, ab, ac, ad, ae,
+ b0, b1, b2, b3, b5, b6, b8, b9, ba, bd, be, bf;
+
+ /* Mach64 PLL register */
+ CARD8 pll_ext_vpll_cntl;
+
+ /* Mach64 registers */
+ CARD32 crtc_h_total_disp, crtc_h_sync_strt_wid,
+ crtc_v_total_disp, crtc_v_sync_strt_wid,
+ crtc_off_pitch, crtc_gen_cntl, dsp_config, dsp_on_off,
+ ovr_clr, ovr_wid_left_right, ovr_wid_top_bottom,
+ clock_cntl, bus_cntl, mem_vga_wp_sel, mem_vga_rp_sel,
+ dac_cntl, config_cntl;
+
+ /* LCD registers */
+ CARD32 lcd_index, config_panel, lcd_gen_ctrl, power_management,
+ horz_stretching, vert_stretching, ext_vert_stretch;
+
+ /* Shadow VGA CRTC registers */
+ CARD8 shadow_vga[25];
+
+ /* Shadow Mach64 CRTC registers */
+ CARD32 shadow_h_total_disp, shadow_h_sync_strt_wid,
+ shadow_v_total_disp, shadow_v_sync_strt_wid;
+
+ /* Clock map pointers */
+ const CARD8 *ClockMap, *ClockUnmap;
+
+ /* Clock programming data */
+ int FeedbackDivider, ReferenceDivider, PostDivider;
+
+ /* This is used by ATISwap() */
+ pointer frame_buffer;
+ ATIBankProcPtr SetBank;
+ unsigned int nBank, nPlane;
+} ATIHWRec;
+
+/*
+ * This structure defines the driver's private area.
+ */
+typedef struct _ATIRec
+{
+ /*
+ * Definitions related to XF86Config "Chipset" specifications.
+ */
+ CARD8 Chipset;
+
+ /*
+ * Adapter-related definitions.
+ */
+ CARD8 Adapter, VGAAdapter;
+
+ /*
+ * Chip-related definitions.
+ */
+ CARD8 Chip, Coprocessor;
+ CARD16 ChipType, ChipClass, ChipRevision, ChipRev;
+ CARD16 ChipVersion, ChipFoundry;
+ CARD8 ChipHasSUBSYS_CNTL;
+
+ /*
+ * Processor I/O decoding definitions.
+ */
+ CARD8 CPIODecoding;
+ CARD16 CPIOBase;
+
+ /*
+ * Processor I/O port definition for VGA.
+ */
+ CARD16 CPIO_VGABase;
+
+ /*
+ * Processor I/O port definitions for VGA Wonder.
+ */
+ CARD16 CPIO_VGAWonder;
+ CARD8 B2Reg; /* The B2 mirror */
+ CARD8 VGAOffset; /* Low index for CPIO_VGAWonder */
+
+ /*
+ * Processor I/O port definitions for Mach64.
+ */
+ CARD16 CPIO_CRTC_H_TOTAL_DISP, CPIO_CRTC_H_SYNC_STRT_WID,
+ CPIO_CRTC_V_TOTAL_DISP, CPIO_CRTC_V_SYNC_STRT_WID,
+ CPIO_CRTC_OFF_PITCH,CPIO_CRTC_INT_CNTL, CPIO_CRTC_GEN_CNTL,
+ CPIO_DSP_CONFIG, CPIO_DSP_ON_OFF, CPIO_OVR_CLR,
+ CPIO_OVR_WID_LEFT_RIGHT, CPIO_OVR_WID_TOP_BOTTOM,
+ CPIO_TV_OUT_INDEX, CPIO_CLOCK_CNTL, CPIO_TV_OUT_DATA,
+ CPIO_BUS_CNTL, CPIO_LCD_INDEX, CPIO_LCD_DATA, CPIO_MEM_INFO,
+ CPIO_MEM_VGA_WP_SEL, CPIO_MEM_VGA_RP_SEL,
+ CPIO_DAC_REGS, CPIO_DAC_CNTL,
+ CPIO_HORZ_STRETCHING, CPIO_VERT_STRETCHING,
+ CPIO_GEN_TEST_CNTL, CPIO_LCD_GEN_CTRL,
+ CPIO_POWER_MANAGEMENT, CPIO_CONFIG_CNTL;
+
+ /*
+ * DAC-related definitions.
+ */
+ CARD16 DAC;
+ CARD16 CPIO_DAC_MASK, CPIO_DAC_DATA, CPIO_DAC_READ, CPIO_DAC_WRITE;
+
+ /*
+ * Definitions related to system bus interface.
+ */
+ pciVideoPtr PCIInfo;
+ CARD8 BusType;
+ CARD8 SharedVGA, SharedAccelerator;
+
+ /*
+ * Definitions related to video memory.
+ */
+ CARD8 MemoryType;
+ int VideoRAM;
+
+ /*
+ * BIOS-related definitions.
+ */
+ unsigned long BIOSBase;
+
+ /*
+ * Definitions related to video memory apertures.
+ */
+ pointer pBank, pMemory;
+ unsigned long LinearBase, ApertureBase;
+ int LinearSize, ApertureSize;
+ CARD8 UseSmallApertures;
+
+ /*
+ * Banking interface.
+ */
+ miBankInfoRec BankInfo;
+
+ /*
+ * Clock-related definitions.
+ */
+ int ClockNumberToProgramme, ReferenceNumerator, ReferenceDenominator;
+ ClockRec ClockDescriptor;
+ CARD16 BIOSClocks[16];
+ CARD8 Clock, ProgrammableClock;
+
+ /*
+ * DSP register data.
+ */
+ int XCLKFeedbackDivider, XCLKReferenceDivider, XCLKPostDivider;
+ CARD16 XCLKMaxRASDelay, XCLKPageFaultDelay,
+ DisplayLoopLatency, DisplayFIFODepth;
+
+ /*
+ * LCD panel data.
+ */
+ int LCDPanelID, LCDClock, LCDHorizontal, LCDVertical;
+ int LCDHSyncStart, LCDHSyncWidth, LCDHBlankWidth;
+ int LCDVSyncStart, LCDVSyncWidth, LCDVBlankWidth;
+ int LCDVBlendFIFOSize;
+
+ /*
+ * Data used by ATIAdjustFrame().
+ */
+ int AdjustDepth, AdjustMaxX, AdjustMaxY;
+ unsigned long AdjustMask;
+
+ /*
+ * Data saved by ATIUnlock() and restored by ATILock().
+ */
+ struct
+ {
+ /* VGA registers */
+ CARD8 crt03, crt11;
+
+ /* VGA Wonder registers */
+ CARD8 a6, ab, b1, b4, b5, b6, b8, b9, be;
+
+ /* Mach8/Mach32 registers */
+ CARD16 clock_sel, misc_options, mem_bndry, mem_cfg;
+
+ /* Mach64 registers */
+ CARD32 bus_cntl, config_cntl, crtc_gen_cntl, mem_info, gen_test_cntl,
+ dac_cntl, crtc_int_cntl;
+ } LockData;
+
+ /* Mode data */
+ ATIHWRec OldHW, NewHW;
+
+ /*
+ * Resource Access Control entity index.
+ */
+ int iEntity;
+
+ /*
+ * Driver options.
+ */
+ CARD8 OptionCSync, OptionDevel, OptionLinear, OptionProbeClocks;
+
+ /*
+ * State flags.
+ */
+ CARD8 Unlocked, Mapped, Closeable;
+
+ /*
+ * Wrapped functions.
+ */
+ CloseScreenProcPtr CloseScreen;
+} ATIRec;
+
+#define ATIPTR(_p) ((ATIPtr)((_p)->driverPrivate))
+
+#endif /* ___ATISTRUCT_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiutil.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiutil.c
new file mode 100644
index 000000000..ed6f284b2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiutil.c
@@ -0,0 +1,96 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiutil.c,v 1.3 1999/07/06 11:38:38 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "atiutil.h"
+
+/*
+ * ATIDivide --
+ *
+ * Using integer arithmetic and avoiding overflows, this function finds the
+ * rounded integer that best approximates
+ *
+ * Numerator Shift
+ * ----------- * 2
+ * Denominator
+ *
+ * using the specified rounding (floor, nearest or ceiling).
+ */
+int
+ATIDivide
+(
+ int Numerator,
+ int Denominator,
+ int Shift,
+ const int RoundingKind
+)
+{
+ int Multiplier, Divider, Remainder;
+ int Rounding = 0; /* Default to floor */
+
+#define MaxInt ((int)((unsigned int)(-1) >> 2))
+
+ /* Filter out largest common divider */
+ Multiplier = Numerator;
+ Divider = Denominator;
+ while ((Remainder = Multiplier % Divider))
+ {
+ Multiplier = Divider;
+ Divider = Remainder;
+ }
+ Numerator /= Divider;
+ Denominator /= Divider;
+
+ /* Deal with left shifts but try to keep the denominator even */
+ if (Denominator & 1)
+ {
+ if (Denominator <= MaxInt)
+ {
+ Denominator <<= 1;
+ Shift++;
+ }
+ }
+ else while ((Shift > 0) && !(Denominator & 3))
+ {
+ Denominator >>= 1;
+ Shift--;
+ }
+
+ /* Deal with right shifts */
+ while (Shift < 0)
+ {
+ if ((Numerator & 1) && (Denominator <= MaxInt))
+ Denominator <<= 1;
+ else
+ Numerator >>= 1;
+
+ Shift++;
+ }
+
+ if (!RoundingKind) /* Nearest */
+ Rounding = Denominator >> 1;
+ else if (RoundingKind > 0) /* Ceiling */
+ Rounding = Denominator - 1;
+
+ return ((Numerator / Denominator) << Shift) +
+ ((((Numerator % Denominator) << Shift) + Rounding) / Denominator);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiutil.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiutil.h
new file mode 100644
index 000000000..37b8a76c1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiutil.h
@@ -0,0 +1,62 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiutil.h,v 1.3 1999/07/06 11:38:38 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIUTIL_H___
+#define ___ATIUTIL_H___ 1
+
+#include "atiproto.h"
+
+/*
+ * Prevent the C standard's insistence on unsigned long sizeof's from causing
+ * counter-intuitive results.
+ */
+#define SizeOf(_object) ((int)sizeof(_object))
+#define NumberOf(_what) (SizeOf(_what) / SizeOf(_what[0]))
+
+#define __ONE_MICROSECOND__ 100 /* This'll need calibration */
+
+#define ATIDelay(_microseconds) \
+ { \
+ unsigned int _i, _j; \
+ for (_i = 0; _i < _microseconds; _i++) \
+ for (_j = 0; _j < __ONE_MICROSECOND__; _j++) \
+ /* Nothing */; \
+ }
+
+/*
+ * Macros to get/set a contiguous bit field. '_Mask' should not be
+ * self-modifying.
+ */
+#define UnitOf(___Value) ((((___Value) ^ ((___Value) - 1)) + 1) >> 1)
+#define GetBits(__Value, _Mask) (((__Value) & (_Mask)) / UnitOf(_Mask))
+#define SetBits(__Value, _Mask) (((__Value) * UnitOf(_Mask)) & (_Mask))
+
+#define MaxBits(__Mask) GetBits(__Mask, __Mask)
+
+#define _ByteMask(__Byte) ((CARD8)(-1) << (8 * (__Byte)))
+#define GetByte(_Value, _Byte) GetBits(_Value, _ByteMask(_Byte))
+#define SetByte(_Value, _Byte) SetBits(_Value, _ByteMask(_Byte))
+
+extern int ATIDivide FunctionPrototype((int, int, int, const int));
+
+#endif /* ___ATIUTIL_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/ativalid.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/ativalid.c
new file mode 100644
index 000000000..20393bd51
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/ativalid.c
@@ -0,0 +1,117 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ativalid.c,v 1.4 1999/08/01 07:57:23 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "atiadapter.h"
+#include "atichip.h"
+#include "aticrtc.h"
+#include "atistruct.h"
+#include "ativalid.h"
+#include "xf86.h"
+
+/*
+ * ATIValidMode --
+ *
+ * This checks for hardware-related limits on mode timings. This assumes
+ * xf86CheckMode has already done some basic consistency checks.
+ */
+int
+ATIValidMode
+(
+ int iScreen,
+ DisplayModePtr pMode,
+ Bool Verbose,
+ int flags
+)
+{
+ ATIPtr pATI = ATIPTR(xf86Screens[iScreen]);
+ int VDisplay, VTotal, HBlankWidth;
+
+ if (pATI->LCDPanelID >= 0)
+ {
+ if ((pMode->HDisplay > pATI->LCDHorizontal) ||
+ (pMode->VDisplay > pATI->LCDVertical))
+ return MODE_PANEL;
+ return MODE_OK;
+ }
+
+ HBlankWidth = (pMode->HTotal >> 3) - (pMode->HDisplay >> 3);
+ if (!HBlankWidth)
+ return MODE_HBLANK_NARROW;
+
+ switch (pATI->NewHW.crtc)
+ {
+ case ATI_CRTC_VGA:
+ /* Prevent overscans */
+ if (HBlankWidth > 63)
+ return MODE_HBLANK_WIDE;
+
+ if (pMode->HDisplay > 2048)
+ return MODE_BAD_HVALUE;
+
+ VDisplay = pMode->VDisplay;
+ VTotal = pMode->VTotal;
+
+ if (pMode->VScan > 1)
+ {
+ if (pMode->VScan > 32)
+ return MODE_BAD_VSCAN;
+
+ VDisplay *= pMode->VScan;
+ VTotal *= pMode->VScan;
+ }
+
+ if (pMode->Flags & V_DBLSCAN)
+ {
+ VDisplay <<= 1;
+ VTotal <<= 1;
+ }
+
+ if ((pMode->Flags & V_INTERLACE) && (pATI->Chip < ATI_CHIP_264CT))
+ {
+ VDisplay >>= 1;
+ VTotal >>= 1;
+ }
+
+ if ((VDisplay > 2048) || (VTotal > 2050))
+ return MODE_BAD_VVALUE;
+
+ if (pATI->Adapter != ATI_ADAPTER_VGA)
+ break;
+
+ if ((VDisplay > 1024) || (VTotal > 1025))
+ return MODE_BAD_VVALUE;
+
+ break;
+
+ case ATI_CRTC_MACH64:
+ if (pMode->VScan > 1)
+ return MODE_NO_VSCAN;
+
+ break;
+
+ default:
+ break;
+ }
+
+ return MODE_OK;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/ativalid.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/ativalid.h
new file mode 100644
index 000000000..9e2e035c3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/ativalid.h
@@ -0,0 +1,32 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ativalid.h,v 1.3 1999/07/06 11:38:39 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIVALID_H___
+#define ___ATIVALID_H___ 1
+
+#include "atiproto.h"
+#include "xf86str.h"
+
+extern int ATIValidMode FunctionPrototype((int, DisplayModePtr, Bool, int));
+
+#endif /* ___ATIVALID_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/ativersion.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/ativersion.h
new file mode 100644
index 000000000..5419ac1ce
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/ativersion.h
@@ -0,0 +1,38 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ativersion.h,v 1.8 1999/08/21 13:48:33 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIVERSION_H___
+#define ___ATIVERSION_H___ 1
+
+#define ATI_NAME "ATI"
+#define ATI_DRIVER_NAME "ati"
+
+#define ATI_VERSION_NAME "5.1.1"
+
+#define ATI_VERSION_MAJOR 5
+#define ATI_VERSION_MINOR 1
+#define ATI_VERSION_PATCH 1
+
+#define ATI_VERSION_CURRENT ((ATI_VERSION_MAJOR << 16) | ATI_VERSION_MINOR)
+
+#endif /* ___ATIVERSION_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/ativga.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/ativga.c
new file mode 100644
index 000000000..474c8505f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/ativga.c
@@ -0,0 +1,428 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ativga.c,v 1.5 1999/08/01 07:57:23 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "atiadapter.h"
+#include "atichip.h"
+#include "atiio.h"
+#include "atimono.h"
+#include "ativga.h"
+#include "xf86.h"
+
+/*
+ * ATIVGAPreInit --
+ *
+ * This function is called to set up VGA-related data that is common to all
+ * video modes generated by the driver.
+ */
+void
+ATIVGAPreInit
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ int Index;
+
+ /* Initialize sequencer register values */
+ pATIHW->seq[0] = 0x03U;
+ if (pScreenInfo->depth == 1)
+ pATIHW->seq[2] = 0x01U << BIT_PLANE;
+ else
+ pATIHW->seq[2] = 0x0FU;
+ if (pScreenInfo->depth <= 4)
+ pATIHW->seq[4] = 0x06U;
+ else if (pATI->Adapter == ATI_ADAPTER_VGA)
+ pATIHW->seq[4] = 0x0EU;
+ else
+ pATIHW->seq[4] = 0x0AU;
+
+ /* Initialize CRTC register values */
+ if ((pScreenInfo->depth >= 8) &&
+ ((pATI->Chip >= ATI_CHIP_264CT) ||
+ (pATI->CPIO_VGAWonder &&
+ (pATI->Chip <= ATI_CHIP_18800_1) &&
+ (pATI->VideoRAM == 256))))
+ pATIHW->crt[19] = pScreenInfo->displayWidth >> 3;
+ else
+ pATIHW->crt[19] = pScreenInfo->displayWidth >> 4;
+ if ((pScreenInfo->depth >= 8) && (pATI->Adapter == ATI_ADAPTER_VGA))
+ pATIHW->crt[23] = 0xC3U;
+ else
+ pATIHW->crt[23] = 0xE3U;
+ pATIHW->crt[24] = 0xFFU;
+
+ /* Initialize attribute controller register values */
+ if (pScreenInfo->depth == 1)
+ {
+ Bool FlipPixels = xf86GetFlipPixels();
+
+ for (Index = 0; Index < 16; Index++)
+ if (((Index & (0x01U << BIT_PLANE)) != 0) != FlipPixels)
+ pATIHW->attr[Index] = MONO_WHITE;
+ else
+ pATIHW->attr[Index] = MONO_BLACK;
+ pATIHW->attr[16] = 0x01U;
+ pATIHW->attr[17] = MONO_OVERSCAN;
+ }
+ else
+ {
+ for (Index = 0; Index < 16; Index++)
+ pATIHW->attr[Index] = Index;
+ if (pScreenInfo->depth <= 4)
+ pATIHW->attr[16] = 0x81U;
+ else if (pATI->Adapter == ATI_ADAPTER_VGA)
+ pATIHW->attr[16] = 0x41U;
+ else
+ pATIHW->attr[16] = 0x01U;
+ pATIHW->attr[17] = 0xFFU;
+ }
+ pATIHW->attr[18] = 0x0FU;
+
+ /* Initialize graphics controller register values */
+ if (pScreenInfo->depth == 1)
+ pATIHW->gra[4] = BIT_PLANE;
+ else if (pScreenInfo->depth <= 4)
+ pATIHW->gra[5] = 0x02U;
+ else if (pATI->Chip >= ATI_CHIP_264CT)
+ pATIHW->gra[5] = 0x40U;
+ if (pATI->UseSmallApertures && (pATI->Chip >= ATI_CHIP_264VTB))
+ pATIHW->gra[6] = 0x01U; /* 128kB aperture */
+ else
+ pATIHW->gra[6] = 0x05U; /* 64kB aperture */
+ pATIHW->gra[7] = 0x0FU;
+ pATIHW->gra[8] = 0xFFU;
+}
+
+/*
+ * ATIVGASave --
+ *
+ * This function is called to save the VGA portion of the current video state.
+ */
+void
+ATIVGASave
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ int Index;
+
+ /* Save miscellaneous output register */
+ pATIHW->genmo = inb(R_GENMO);
+ ATISetVGAIOBase(pATI, pATIHW->genmo);
+
+ /* Save sequencer registers */
+ for (Index = 0; Index < NumberOf(pATIHW->seq); Index++)
+ pATIHW->seq[Index] = GetReg(SEQX, Index);
+
+ /* Save CRTC registers */
+ for (Index = 0; Index < NumberOf(pATIHW->crt); Index++)
+ pATIHW->crt[Index] = GetReg(CRTX(pATI->CPIO_VGABase), Index);
+
+ /* Save attribute controller registers */
+ for (Index = 0; Index < NumberOf(pATIHW->attr); Index++)
+ {
+ (void)inb(GENS1(pATI->CPIO_VGABase)); /* Reset flip-flop */
+ pATIHW->attr[Index] = GetReg(ATTRX, Index);
+ }
+
+ /* Save graphics controller registers */
+ for (Index = 0; Index < NumberOf(pATIHW->gra); Index++)
+ pATIHW->gra[Index] = GetReg(GRAX, Index);
+}
+
+/*
+ * ATIVGACalculate --
+ *
+ * This function fills in the VGA portion of an ATIHWRec.
+ */
+void
+ATIVGACalculate
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW,
+ DisplayModePtr pMode
+)
+{
+ int Index, VDisplay;
+
+ /* If not already done, adjust horizontal timings */
+ if (!pMode->CrtcHAdjusted)
+ {
+ pMode->CrtcHAdjusted = TRUE;
+ pMode->CrtcHDisplay = (pMode->HDisplay >> 3) - 1;
+ pMode->CrtcHBlankStart = (pMode->HDisplay >> 3);
+ if ((pATI->Chip == ATI_CHIP_18800_1) ||
+ (pATI->Chip >= ATI_CHIP_264CT))
+ pMode->CrtcHBlankStart--;
+ pMode->CrtcHSyncStart = pMode->HSyncStart >> 3;
+ pMode->CrtcHSyncEnd = pMode->HSyncEnd >> 3;
+ pMode->CrtcHBlankEnd = (pMode->HTotal >> 3) - 1;
+ pMode->CrtcHTotal = (pMode->HTotal >> 3) - 5;
+ pMode->CrtcHSkew = pMode->HSkew;
+
+ /* Check sync pulse width */
+ Index = pMode->CrtcHSyncEnd - pMode->CrtcHSyncStart - 0x1F;
+ if (Index > 0)
+ {
+ pMode->CrtcHSyncStart += Index / 2;
+ pMode->CrtcHSyncEnd = pMode->CrtcHSyncStart + 0x1F;
+ }
+
+ /* Check blank pulse width */
+ Index = pMode->CrtcHBlankEnd - pMode->CrtcHBlankStart - 0x3F;
+ if (Index > 0)
+ {
+ pMode->CrtcHBlankStart += Index / 2;
+ if (pMode->CrtcHBlankStart >= pMode->CrtcHSyncStart)
+ pMode->CrtcHBlankStart = pMode->CrtcHSyncStart - 1;
+ pMode->CrtcHBlankEnd = pMode->CrtcHBlankStart + 0x3F;
+ }
+ }
+
+ /*
+ * Because of the use of CRTC[23] bit 0x04's for vertical doubling, it is
+ * necessary to always re-adjust vertical timings here.
+ */
+ pMode->CrtcVDisplay = pMode->VDisplay;
+ pMode->CrtcVBlankStart = pMode->VDisplay;
+ pMode->CrtcVSyncStart = pMode->VSyncStart;
+ pMode->CrtcVSyncEnd = pMode->VSyncEnd;
+ pMode->CrtcVBlankEnd = pMode->VTotal;
+ pMode->CrtcVTotal = pMode->VTotal;
+
+ /* Adjust for doublescanned modes */
+ if (pMode->Flags & V_DBLSCAN)
+ {
+ pMode->CrtcVDisplay <<= 1;
+ pMode->CrtcVBlankStart <<= 1;
+ pMode->CrtcVSyncStart <<= 1;
+ pMode->CrtcVSyncEnd <<= 1;
+ pMode->CrtcVBlankEnd <<= 1;
+ pMode->CrtcVTotal <<= 1;
+ }
+
+ /* Adjust for multiscanned modes */
+ if (pMode->VScan > 1)
+ {
+ pMode->CrtcVDisplay *= pMode->VScan;
+ pMode->CrtcVBlankStart *= pMode->VScan;
+ pMode->CrtcVSyncStart *= pMode->VScan;
+ pMode->CrtcVSyncEnd *= pMode->VScan;
+ pMode->CrtcVBlankEnd *= pMode->VScan;
+ pMode->CrtcVTotal *= pMode->VScan;
+ }
+
+ /* Set up miscellaneous output register value */
+ pATIHW->genmo = 0x23U;
+ if ((pMode->Flags & (V_PHSYNC | V_NHSYNC)) &&
+ (pMode->Flags & (V_PVSYNC | V_NVSYNC)))
+ {
+ if (pMode->Flags & V_NHSYNC)
+ pATIHW->genmo |= 0x40U;
+ if (pMode->Flags & V_NVSYNC)
+ pATIHW->genmo |= 0x80U;
+ }
+ else
+ {
+ if (pATI->LCDPanelID >= 0)
+ VDisplay = pATI->LCDVertical;
+ else
+ VDisplay = pMode->CrtcVDisplay;
+
+ if (VDisplay < 400)
+ {
+ pMode->Flags |= V_PHSYNC | V_NVSYNC;
+ pATIHW->genmo |= 0x80U;
+ }
+ else if (VDisplay < 480)
+ {
+ pMode->Flags |= V_NHSYNC | V_PVSYNC;
+ pATIHW->genmo |= 0x40U;
+ }
+ else if (VDisplay < 768)
+ {
+ pMode->Flags |= V_NHSYNC | V_NVSYNC;
+ pATIHW->genmo |= 0xC0U;
+ }
+ else
+ {
+ pMode->Flags |= V_PHSYNC | V_PVSYNC;
+ }
+ }
+
+ /* Adjust for interlaced modes */
+ if ((pMode->Flags & V_INTERLACE) && (pATI->Chip < ATI_CHIP_264CT))
+ {
+ pMode->CrtcVDisplay >>= 1;
+ pMode->CrtcVBlankStart >>= 1;
+ pMode->CrtcVSyncStart >>= 1;
+ pMode->CrtcVSyncEnd >>= 1;
+ pMode->CrtcVBlankEnd >>= 1;
+ pMode->CrtcVTotal >>= 1;
+ }
+
+ if (pMode->CrtcVTotal > 1024)
+ {
+ pATIHW->crt[23] |= 0x04U;
+ pMode->CrtcVDisplay >>= 1;
+ pMode->CrtcVBlankStart >>= 1;
+ pMode->CrtcVSyncStart >>= 1;
+ pMode->CrtcVSyncEnd >>= 1;
+ pMode->CrtcVBlankEnd >>= 1;
+ pMode->CrtcVTotal >>= 1;
+ }
+ else
+ pATIHW->crt[23] &= ~0x04U;
+
+ pMode->CrtcVDisplay--;
+ if (pATI->Chip == ATI_CHIP_18800)
+ pMode->CrtcVBlankStart++;
+ else
+ pMode->CrtcVBlankStart--;
+ pMode->CrtcVBlankEnd--;
+ if (pATI->Chip < ATI_CHIP_264CT)
+ pMode->CrtcVBlankEnd--;
+ pMode->CrtcVTotal -= 2;
+ pMode->CrtcVAdjusted = TRUE; /* Redundant */
+
+ /* Check sync pulse width */
+ Index = pMode->CrtcVSyncEnd - pMode->CrtcVSyncStart - 0x0F;
+ if (Index > 0)
+ {
+ pMode->CrtcVSyncStart += Index / 2;
+ pMode->CrtcVSyncEnd = pMode->CrtcVSyncStart + 0x0F;
+ }
+
+ /* Check blank pulse width */
+ Index = pMode->CrtcVBlankEnd - pMode->CrtcVBlankStart - 0x0FF;
+ if (Index > 0)
+ {
+ pMode->CrtcVBlankStart += Index / 2;
+ if (pMode->CrtcVBlankStart >= pMode->CrtcVSyncStart)
+ pMode->CrtcVBlankStart = pMode->CrtcVSyncStart - 1;
+ pMode->CrtcVBlankEnd = pMode->CrtcVBlankStart + 0x0FF;
+ }
+
+ /* Set up sequencer register values */
+ if (pMode->Flags & V_CLKDIV2)
+ pATIHW->seq[1] = 0x09U;
+ else
+ pATIHW->seq[1] = 0x01U;
+
+ /* Set up CRTC register values */
+ pATIHW->crt[0] = pMode->CrtcHTotal;
+ pATIHW->crt[1] = pMode->CrtcHDisplay;
+ pATIHW->crt[2] = pMode->CrtcHBlankStart;
+ pATIHW->crt[3] = (pMode->CrtcHBlankEnd & 0x1FU) | 0x80U;
+ Index = ((pMode->CrtcHSkew << 2) + 0x10U) & ~0x1FU;
+ if (Index < 0x0080)
+ pATIHW->crt[3] |= Index;
+ pATIHW->crt[4] = pMode->CrtcHSyncStart;
+ pATIHW->crt[5] = ((pMode->CrtcHBlankEnd & 0x20U) << 2) |
+ ((pMode->CrtcHSyncEnd & 0x1FU) );
+ pATIHW->crt[6] = pMode->CrtcVTotal & 0xFFU;
+ pATIHW->crt[7] = ((pMode->CrtcVTotal & 0x0100U) >> 8) |
+ ((pMode->CrtcVDisplay & 0x0100U) >> 7) |
+ ((pMode->CrtcVSyncStart & 0x0100U) >> 6) |
+ ((pMode->CrtcVBlankStart & 0x0100U) >> 5) |
+ 0x10U |
+ ((pMode->CrtcVTotal & 0x0200U) >> 4) |
+ ((pMode->CrtcVDisplay & 0x0200U) >> 3) |
+ ((pMode->CrtcVSyncStart & 0x0200U) >> 2);
+ pATIHW->crt[9] = ((pMode->CrtcVBlankStart & 0x0200U) >> 4) | 0x40U;
+ /*
+ * Doublescanned modes are missing the top scanline. Convert
+ * doublescanning to multiscanning, using the doublescan bit only as a last
+ * resort.
+ */
+ if ((Index = pMode->VScan) <= 0)
+ Index = 1;
+ if (pMode->Flags & V_DBLSCAN)
+ Index <<= 1;
+ Index--;
+ pATIHW->crt[9] |= (Index & 0x1FU) | ((Index & 0x20U) << 2);
+ pATIHW->crt[16] = pMode->CrtcVSyncStart & 0xFFU;
+ pATIHW->crt[17] = (pMode->CrtcVSyncEnd & 0x0FU) | 0x20U;
+ pATIHW->crt[18] = pMode->CrtcVDisplay & 0xFFU;
+ pATIHW->crt[21] = pMode->CrtcVBlankStart & 0xFFU;
+ pATIHW->crt[22] = pMode->CrtcVBlankEnd & 0xFFU;
+}
+
+/*
+ * ATIVGASet --
+ *
+ * This function is called to load the VGA portion of a video state.
+ */
+void
+ATIVGASet
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ int Index;
+
+ /* Set VGA I/O base */
+ ATISetVGAIOBase(pATI, pATIHW->genmo);
+
+ /* Load miscellaneous output register */
+ outb(GENMO, pATIHW->genmo);
+
+ /* Load sequencer in reverse index order; this also ends its reset */
+ for (Index = NumberOf(pATIHW->seq); --Index >= 0; )
+ PutReg(SEQX, Index, pATIHW->seq[Index]);
+
+ /* Load CRTC registers */
+ for (Index = 0; Index < NumberOf(pATIHW->crt); Index++)
+ PutReg(CRTX(pATI->CPIO_VGABase), Index, pATIHW->crt[Index]);
+
+ /* Load attribute controller registers */
+ for (Index = 0; Index < NumberOf(pATIHW->attr); Index++)
+ {
+ (void)inb(GENS1(pATI->CPIO_VGABase)); /* Reset flip-flop & delay */
+ outb(ATTRX, Index);
+ outb(ATTRX, pATIHW->attr[Index]);
+ }
+
+ /* Load graphics controller registers */
+ for (Index = 0; Index < NumberOf(pATIHW->gra); Index++)
+ PutReg(GRAX, Index, pATIHW->gra[Index]);
+}
+
+/*
+ * ATIVGASaveScreen --
+ *
+ * This function blanks or unblanks a VGA screen.
+ */
+void
+ATIVGASaveScreen
+(
+ ATIPtr pATI,
+ int On
+)
+{
+ (void)inb(GENS1(pATI->CPIO_VGABase)); /* Reset flip-flop */
+ outb(ATTRX, On ? 0x20U : 0x00U); /* Turn PAS on or off */
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/ativga.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/ativga.h
new file mode 100644
index 000000000..23eeefe71
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/ativga.h
@@ -0,0 +1,40 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/ativga.h,v 1.3 1999/07/06 11:38:39 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIVGA_H___
+#define ___ATIVGA_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+#include "xf86str.h"
+
+extern void ATIVGAPreInit FunctionPrototype((ScrnInfoPtr, ATIPtr,
+ ATIHWPtr));
+extern void ATIVGASave FunctionPrototype((ATIPtr, ATIHWPtr));
+extern void ATIVGACalculate FunctionPrototype((ATIPtr, ATIHWPtr,
+ DisplayModePtr));
+extern void ATIVGASet FunctionPrototype((ATIPtr, ATIHWPtr));
+
+extern void ATIVGASaveScreen FunctionPrototype((ATIPtr, int));
+
+#endif /* ___ATIVGA_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atividmem.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atividmem.c
new file mode 100644
index 000000000..45d22a7f0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atividmem.c
@@ -0,0 +1,149 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atividmem.c,v 1.4 1999/08/01 07:57:24 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 "ati.h"
+#include "atiadapter.h"
+#include "atistruct.h"
+#include "atividmem.h"
+
+/* Memory types for 68800's and 88800GX's */
+const char *ATIMemoryTypeNames_Mach[] =
+{
+ "DRAM (256Kx4)",
+ "VRAM (256Kx4, x8, x16)",
+ "VRAM (256Kx16 with short shift register)",
+ "DRAM (256Kx16)",
+ "Graphics DRAM (256Kx16)",
+ "Enhanced VRAM (256Kx4, x8, x16)",
+ "Enhanced VRAM (256Kx16 with short shift register)",
+ "Unknown video memory type"
+};
+
+/* Memory types for 88800CX's */
+const char *ATIMemoryTypeNames_88800CX[] =
+{
+ "DRAM (256Kx4, x8, x16)",
+ "EDO DRAM (256Kx4, x8, x16)",
+ "Unknown video memory type",
+ "DRAM (256Kx16 with assymetric RAS/CAS)",
+ "Unknown video memory type",
+ "Unknown video memory type",
+ "Unknown video memory type",
+ "Unknown video memory type"
+};
+
+/* Memory types for 264xT's */
+const char *ATIMemoryTypeNames_264xT[] =
+{
+ "Disabled video memory",
+ "DRAM",
+ "EDO DRAM",
+ "Pseudo-EDO DRAM",
+ "SDRAM",
+ "SGRAM",
+ "Unknown video memory type",
+ "Unknown video memory type"
+};
+
+/*
+ * ATIMapApertures --
+ *
+ * This function maps all apertures used by the driver.
+ */
+Bool
+ATIMapApertures
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI
+)
+{
+ if (pATI->Mapped)
+ return TRUE;
+
+ /* Map VGA aperture */
+ if (pATI->VGAAdapter != ATI_ADAPTER_VGA)
+ {
+ pATI->pBank = xf86MapVidMem(pScreenInfo->scrnIndex, VIDMEM_MMIO,
+ 0x000A0000U, 0x00010000U);
+ if (!pATI->pBank)
+ return FALSE;
+ pATI->pMemory =
+ pATI->BankInfo.pBankA =
+ pATI->BankInfo.pBankB = pATI->pBank;
+ }
+
+ /* Map linear aperture */
+ if (pATI->LinearBase)
+ {
+ if (pATI->PCIInfo)
+ pATI->pMemory = xf86MapPciMem(pScreenInfo->scrnIndex,
+ VIDMEM_FRAMEBUFFER,
+ ((pciConfigPtr)(pATI->PCIInfo->thisCard))->tag,
+ pATI->LinearBase, pATI->LinearSize);
+ else
+ pATI->pMemory = xf86MapVidMem(pScreenInfo->scrnIndex,
+ VIDMEM_FRAMEBUFFER, pATI->LinearBase, pATI->LinearSize);
+ if (!pATI->pMemory)
+ {
+ if (pATI->pBank)
+ {
+ xf86UnMapVidMem(pScreenInfo->scrnIndex, pATI->pBank,
+ 0x00010000U);
+ pATI->pBank = NULL;
+ }
+ return FALSE;
+ }
+ }
+
+ pATI->Mapped = TRUE;
+ return TRUE;
+}
+
+/*
+ * ATIUnmapApertures --
+ *
+ * This function unmaps all apertures used by the driver.
+ */
+void
+ATIUnmapApertures
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI
+)
+{
+ if (!pATI->Mapped)
+ return;
+ pATI->Mapped = FALSE;
+
+ /* Unmap linear aperture */
+ if (pATI->pMemory != pATI->pBank)
+ xf86UnMapVidMem(pScreenInfo->scrnIndex, pATI->pMemory,
+ pATI->LinearSize);
+
+ /* Unmap VGA aperture */
+ if (pATI->pBank)
+ xf86UnMapVidMem(pScreenInfo->scrnIndex, pATI->pBank, 0x00010000U);
+
+ pATI->pMemory = pATI->pBank = NULL;
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atividmem.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atividmem.h
new file mode 100644
index 000000000..f3b0bcb8f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atividmem.h
@@ -0,0 +1,76 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atividmem.h,v 1.3 1999/07/06 11:38:40 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIVIDMEM_H___
+#define ___ATIVIDMEM_H___ 1
+
+#include "atiproto.h"
+#include "atipriv.h"
+#include "xf86str.h"
+
+/* Memory types for 68800's and 88800GX's */
+typedef enum
+{
+ MEM_MACH_DRAMx4,
+ MEM_MACH_VRAM,
+ MEM_MACH_VRAMssr,
+ MEM_MACH_DRAMx16,
+ MEM_MACH_GDRAM,
+ MEM_MACH_EVRAM,
+ MEM_MACH_EVRAMssr,
+ MEM_MACH_TYPE_7
+} ATIMachMemoryType;
+extern const char *ATIMemoryTypeNames_Mach[];
+
+/* Memory types for 88800CX's */
+typedef enum
+{
+ MEM_CX_DRAM,
+ MEM_CX_EDO,
+ MEM_CX_TYPE_2,
+ MEM_CX_DRAM_A,
+ MEM_CX_TYPE_4,
+ MEM_CX_TYPE_5,
+ MEM_CX_TYPE_6,
+ MEM_CX_TYPE_7
+} ATICXMemoryType;
+extern const char *ATIMemoryTypeNames_88800CX[];
+
+/* Memory types for 264xT's */
+typedef enum
+{
+ MEM_264_NONE,
+ MEM_264_DRAM,
+ MEM_264_EDO,
+ MEM_264_PSEUDO_EDO,
+ MEM_264_SDRAM,
+ MEM_264_SGRAM,
+ MEM_264_TYPE_6,
+ MEM_264_TYPE_7
+} ATI264MemoryType;
+extern const char *ATIMemoryTypeNames_264xT[];
+
+extern Bool ATIMapApertures FunctionPrototype((ScrnInfoPtr, ATIPtr));
+extern void ATIUnmapApertures FunctionPrototype((ScrnInfoPtr, ATIPtr));
+
+#endif /* ___ATIVIDMEM_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiwonder.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiwonder.c
new file mode 100644
index 000000000..f0c1ab4b5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiwonder.c
@@ -0,0 +1,296 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiwonder.c,v 1.5 1999/08/01 07:57:24 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * The ATI x8800 chips use special registers for their extended VGA features.
+ * These registers are accessible through an index I/O port and a data I/O
+ * port. BIOS initialization stores the index port number in the Graphics
+ * register bank (0x03CE), indices 0x50 and 0x51. Unfortunately, for all but
+ * the 18800-x series of adapters, these registers are write-only (a.k.a. black
+ * holes). On all but 88800's, the index port number can be found in the short
+ * integer at offset 0x10 in the BIOS. For 88800's, this driver will use
+ * 0x01CE or 0x03CE as the index port number, depending on the I/O port
+ * decoding used. The data port number is one more than the index port number
+ * (i.e. 0x01CF). These ports differ slightly in their I/O behaviour from the
+ * normal VGA ones:
+ *
+ * write: outw(0x01CE, (data << 8) | index); (16-bit, not used)
+ * outb(0x01CE, index); outb(0x01CF, data); (8-bit)
+ * read: outb(0x01CE, index); data = inb(0x01CF);
+ *
+ * Two consecutive byte-writes to the data port will not work. Furthermore an
+ * index written to 0x01CE is usable only once. Note also that the setting of
+ * ATI extended registers (especially those with clock selection bits) should
+ * be bracketed by a sequencer reset.
+ *
+ * The number of these extended VGA registers varies by chipset. The 18800
+ * series have 16, the 28800 series have 32, while 68800's and 88800's have 64.
+ * The last 16 on each have almost identical definitions. Thus, the BIOS sets
+ * up an indexing scheme whereby the last 16 extended VGA registers are
+ * accessed at indices 0xB0 through 0xBF on all chipsets.
+ */
+
+#include "atichip.h"
+#include "atiio.h"
+#include "atiwonder.h"
+
+/*
+ * ATIVGAWonderPreInit --
+ *
+ * This function is called to initialize the VGA Wonder part of an ATIHWRec
+ * that is common to all modes generated by the driver.
+ */
+void
+ATIVGAWonderPreInit
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ pATIHW->b3 = ATIGetExtReg(0xB3U) & 0x20U;
+ if (pScreenInfo->depth <= 4)
+ pATIHW->b6 = 0x40U;
+ else
+ pATIHW->b6 = 0x04U;
+ if (pATI->Chip <= ATI_CHIP_18800)
+ pATIHW->ba = 0x08U;
+ else if (pATI->Chip >= ATI_CHIP_28800_2)
+ {
+ if (pATI->VideoRAM > 256)
+ pATIHW->b6 |= 0x01U;
+ pATIHW->bf = ATIGetExtReg(0xBFU) & 0x5FU;
+ pATIHW->a3 = ATIGetExtReg(0xA3U) & 0x67U;
+ pATIHW->ab = ATIGetExtReg(0xABU) & 0xE7U;
+ pATIHW->ae = ATIGetExtReg(0xAEU) & 0xE0U;
+ }
+}
+
+/*
+ * ATIVGAWonderSave --
+ *
+ * This function is called to save the VGA Wonder portion of the current video
+ * state.
+ */
+void
+ATIVGAWonderSave
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ pATIHW->b0 = ATIGetExtReg(0xB0U);
+ pATIHW->b1 = ATIGetExtReg(0xB1U);
+ pATIHW->b2 = ATIGetExtReg(0xB2U);
+ pATIHW->b3 = ATIGetExtReg(0xB3U);
+ pATIHW->b5 = ATIGetExtReg(0xB5U);
+ pATIHW->b6 = ATIGetExtReg(0xB6U);
+ pATIHW->b8 = ATIGetExtReg(0xB8U);
+ pATIHW->b9 = ATIGetExtReg(0xB9U);
+ pATIHW->ba = ATIGetExtReg(0xBAU);
+ pATIHW->bd = ATIGetExtReg(0xBDU);
+ if (pATI->Chip > ATI_CHIP_18800)
+ {
+ pATIHW->be = ATIGetExtReg(0xBEU);
+ if (pATI->Chip >= ATI_CHIP_28800_2)
+ {
+ pATIHW->bf = ATIGetExtReg(0xBFU);
+ pATIHW->a3 = ATIGetExtReg(0xA3U);
+ pATIHW->a6 = ATIGetExtReg(0xA6U);
+ pATIHW->a7 = ATIGetExtReg(0xA7U);
+ pATIHW->ab = ATIGetExtReg(0xABU);
+ pATIHW->ac = ATIGetExtReg(0xACU);
+ pATIHW->ad = ATIGetExtReg(0xADU);
+ pATIHW->ae = ATIGetExtReg(0xAEU);
+ }
+ }
+}
+
+/*
+ * ATIVGAWonderCalculate --
+ *
+ * This function fills in the VGA Wonder portion of an ATIHWRec structure
+ * occurrence.
+ */
+void
+ATIVGAWonderCalculate
+(
+ ScrnInfoPtr pScreenInfo,
+ ATIPtr pATI,
+ ATIHWPtr pATIHW,
+ DisplayModePtr pMode
+)
+{
+ /* Set up the default horizontal display enable skew */
+ if ((pATI->Chip >= ATI_CHIP_28800_2) && (pATI->Chip <= ATI_CHIP_28800_6) &&
+ !(pMode->Flags & V_HSKEW))
+ {
+ /*
+ * Modes using the higher clock frequencies need a non-zero Display
+ * Enable Skew. The following number has been empirically determined
+ * to be somewhere between 4.2 and 4.7 MHz.
+ */
+# define DisplayEnableSkewThreshold 4500
+
+ /* Set a reasonable default Display Enable Skew */
+ pMode->HSkew = pMode->CrtcHSkew =
+ ATIDivide(pMode->SynthClock, DisplayEnableSkewThreshold, 0, 0);
+ }
+ pMode->Flags |= V_HSKEW;
+
+ /*
+ * Fill in mode-specific VGA Wonder data.
+ */
+ pATIHW->b0 = 0x00U;
+ if (pScreenInfo->depth >= 8)
+ pATIHW->b0 = 0x20U;
+ if (pATI->Chip >= ATI_CHIP_28800_2)
+ {
+ if (pATI->VideoRAM > 512)
+ pATIHW->b0 |= 0x08U;
+ else if (pATI->VideoRAM > 256)
+ pATIHW->b0 |= 0x10U;
+ }
+ else if (pScreenInfo->depth <= 4)
+ {
+ if (pATI->VideoRAM > 256)
+ pATIHW->b0 |= 0x08U;
+ }
+ else
+ {
+ if (pATI->VideoRAM > 256)
+ pATIHW->b0 |= 0x18U;
+ else
+ pATIHW->b0 |= 0x06U;
+ }
+ pATIHW->b1 = ATIGetExtReg(0xB1U) & 0x04U;
+ /*
+ * Setting the following bit causes hangs on return to text mode from
+ * packed modes on 18800-1's. The hang occurs because the adapter's I/O
+ * response is completely disabled when the register is rewritten. The
+ * adapter can then only be re-enabled with a powerdown. The bit, when on,
+ * blanks out the overscan.
+ */
+ if ((pATI->Chip == ATI_CHIP_18800_1) && (pScreenInfo->depth >= 8))
+ pATIHW->b5 = 0x00U;
+ else
+ pATIHW->b5 = 0x01U;
+ pATIHW->b8 = ATIGetExtReg(0xB8U) & 0xC0U;
+ pATIHW->b9 = ATIGetExtReg(0xB9U) & 0x7FU;
+ pATIHW->bd = ATIGetExtReg(0xBDU) & 0x02U;
+ if (pATI->Chip <= ATI_CHIP_18800)
+ pATIHW->b2 = ATIGetExtReg(0xB2U) & 0xC0U;
+ else
+ {
+ pATIHW->b2 = 0x00U;
+ pATIHW->be = (ATIGetExtReg(0xBEU) & 0x30U) | 0x09U;
+ if (pATI->Chip >= ATI_CHIP_28800_2)
+ {
+ pATIHW->a6 = (ATIGetExtReg(0xA6U) & 0x38U) | 0x04U;
+ pATIHW->a7 = (ATIGetExtReg(0xA7U) & 0xBEU) ;
+ pATIHW->ac = (ATIGetExtReg(0xACU) & 0x8EU) ;
+ }
+ }
+ if (pMode->Flags & V_INTERLACE) /* Enable interlace */
+ if (pATI->Chip <= ATI_CHIP_18800)
+ pATIHW->b2 |= 0x01U;
+ else
+ pATIHW->be |= 0x02U;
+#if 0 /* This is no longer needed but is left in for reference */
+ if (pMode->Flags & V_DBLSCAN) /* Enable doublescan */
+ pATIHW->b1 |= 0x08U;
+#endif
+ if (pATI->OptionCSync || (pMode->Flags & (V_CSYNC | V_PCSYNC)))
+ pATIHW->bd |= 0x08U; /* Enable composite sync */
+ if (pMode->Flags & V_NCSYNC)
+ pATIHW->bd |= 0x09U; /* Invert composite sync */
+ if (pMode->HSkew > 0)
+ if (pMode->HSkew <= 3)
+ pATIHW->b5 |= 0x04U;
+ else if (pATI->Chip >= ATI_CHIP_28800_2)
+ switch ((pMode->HSkew + 4) >> 3)
+ {
+ case 1: /* Use ATI override */
+ pATIHW->crt[3] &= ~0x60U;
+ pATIHW->b0 |= 0x01U;
+ break;
+ case 2: /* Use ATI override */
+ pATIHW->crt[3] &= ~0x60U;
+ pATIHW->a6 |= 0x01U;
+ break;
+ case 3:
+ pATIHW->crt[3] |= 0x60U;
+ break;
+ case 4:
+ pATIHW->a7 |= 0x40U;
+ break;
+ case 5:
+ pATIHW->ac |= 0x10U;
+ break;
+ case 6:
+ pATIHW->ac |= 0x20U;
+ break;
+ default:
+ break;
+ }
+}
+
+/*
+ * ATIVGAWonderSet --
+ *
+ * This function loads the VGA Wonder portion of a video state.
+ */
+void
+ATIVGAWonderSet
+(
+ ATIPtr pATI,
+ ATIHWPtr pATIHW
+)
+{
+ if (pATI->Chip <= ATI_CHIP_18800)
+ ATIModifyExtReg(pATI, 0xB2U, -1, 0x00U, pATIHW->b2);
+ else
+ {
+ ATIModifyExtReg(pATI, 0xBEU, -1, 0x00U, pATIHW->be);
+ if (pATI->Chip >= ATI_CHIP_28800_2)
+ {
+ ATIModifyExtReg(pATI, 0xBFU, -1, 0x00U, pATIHW->bf);
+ ATIModifyExtReg(pATI, 0xA3U, -1, 0x00U, pATIHW->a3);
+ ATIModifyExtReg(pATI, 0xA6U, -1, 0x00U, pATIHW->a6);
+ ATIModifyExtReg(pATI, 0xA7U, -1, 0x00U, pATIHW->a7);
+ ATIModifyExtReg(pATI, 0xABU, -1, 0x00U, pATIHW->ab);
+ ATIModifyExtReg(pATI, 0xACU, -1, 0x00U, pATIHW->ac);
+ ATIModifyExtReg(pATI, 0xADU, -1, 0x00U, pATIHW->ad);
+ ATIModifyExtReg(pATI, 0xAEU, -1, 0x00U, pATIHW->ae);
+ }
+ }
+ ATIModifyExtReg(pATI, 0xB0U, -1, 0x00U, pATIHW->b0);
+ ATIModifyExtReg(pATI, 0xB1U, -1, 0x00U, pATIHW->b1);
+ ATIModifyExtReg(pATI, 0xB3U, -1, 0x00U, pATIHW->b3);
+ ATIModifyExtReg(pATI, 0xB5U, -1, 0x00U, pATIHW->b5);
+ ATIModifyExtReg(pATI, 0xB6U, -1, 0x00U, pATIHW->b6);
+ ATIModifyExtReg(pATI, 0xB8U, -1, 0x00U, pATIHW->b8);
+ ATIModifyExtReg(pATI, 0xB9U, -1, 0x00U, pATIHW->b9);
+ ATIModifyExtReg(pATI, 0xBAU, -1, 0x00U, pATIHW->ba);
+ ATIModifyExtReg(pATI, 0xBDU, -1, 0x00U, pATIHW->bd);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/atiwonder.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiwonder.h
new file mode 100644
index 000000000..382c62dc6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/atiwonder.h
@@ -0,0 +1,39 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atiwonder.h,v 1.3 1999/07/06 11:38:40 dawes Exp $ */
+/*
+ * Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE 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 ___ATIWONDER_H___
+#define ___ATIWONDER_H___ 1
+
+#include "atipriv.h"
+#include "atiproto.h"
+#include "xf86str.h"
+
+extern void ATIVGAWonderPreInit FunctionPrototype((ScrnInfoPtr, ATIPtr,
+ ATIHWPtr));
+extern void ATIVGAWonderSave FunctionPrototype((ATIPtr, ATIHWPtr));
+extern void ATIVGAWonderCalculate FunctionPrototype((ScrnInfoPtr, ATIPtr,
+ ATIHWPtr,
+ DisplayModePtr));
+extern void ATIVGAWonderSet FunctionPrototype((ATIPtr, ATIHWPtr));
+
+#endif /* ___ATIWONDER_H___ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/chips/Imakefile
new file mode 100644
index 000000000..dfd23d836
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/Imakefile
@@ -0,0 +1,63 @@
+XCOMM $XConsortium: Imakefile /main/13 1996/10/27 11:49:09 kaleb $
+
+
+
+
+
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/Imakefile,v 1.18 1999/08/14 10:49:38 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = ct_driver.c ct_bank.c ct_accel.c ct_accelmm.c ct_accelhi.c ct_cursor.c\
+ ct_ddc.c ct_regs.c ct_dga.c
+
+OBJS = ct_driver.o ct_bank.o ct_accel.o ct_accelmm.o ct_accelhi.o ct_cursor.o\
+ ct_ddc.o ct_regs.o ct_dga.o
+
+DEFINES = -DPSZ=8
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(XF86SRC)/vgafb -I$(XF86SRC)/vgahw -I$(SERVERSRC)/include \
+ -I$(SERVERSRC)/mi -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mfb \
+ -I$(XF86SRC)/xf1bpp -I$(XF86SRC)/xf4bpp -I$(SERVERSRC)/Xext \
+ -I$(XINCLUDESRC) -I$(XF86SRC)/xaa -I$(FONTINCSRC) \
+ -I$(XF86SRC)/ramdac -I$(XF86SRC)/rac -I$(XF86SRC)/ddc \
+ -I$(XF86SRC)/i2c -I$(XF86SRC)/xf24_32bpp -I$(XF86SRC)/shadowfb \
+ -I$(XF86SRC)/xf8_16bpp
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget(chips,$(OBJS))
+
+ObjectFromSpecialSource(ct_accelmm, ct_accel, -DCHIPS_MMIO)
+ObjectFromSpecialSource(ct_accelhi, ct_accel, -DCHIPS_MMIO -DCHIPS_HIQV)
+
+InstallObjectModule(chips,$(MODULEDIR),drivers)
+
+#ifndef OS2Architecture
+DependTarget()
+#endif
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/chips)
+InstallDriverSDKNonExecFile(ct_BlitMM.h,$(DRIVERSDKDIR)/drivers/chips)
+InstallDriverSDKNonExecFile(ct_Blitter.h,$(DRIVERSDKDIR)/drivers/chips)
+InstallDriverSDKNonExecFile(ct_BltHiQV.h,$(DRIVERSDKDIR)/drivers/chips)
+InstallDriverSDKNonExecFile(ct_accel.c,$(DRIVERSDKDIR)/drivers/chips)
+InstallDriverSDKNonExecFile(ct_bank.c,$(DRIVERSDKDIR)/drivers/chips)
+InstallDriverSDKNonExecFile(ct_cursor.c,$(DRIVERSDKDIR)/drivers/chips)
+InstallDriverSDKNonExecFile(ct_ddc.c,$(DRIVERSDKDIR)/drivers/chips)
+InstallDriverSDKNonExecFile(ct_dga.c,$(DRIVERSDKDIR)/drivers/chips)
+InstallDriverSDKNonExecFile(ct_driver.c,$(DRIVERSDKDIR)/drivers/chips)
+InstallDriverSDKNonExecFile(ct_driver.h,$(DRIVERSDKDIR)/drivers/chips)
+InstallDriverSDKNonExecFile(ct_regs.c,$(DRIVERSDKDIR)/drivers/chips)
+
+InstallDriverSDKObjectModule(chips,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_BlitMM.h b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_BlitMM.h
new file mode 100644
index 000000000..424eb2175
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_BlitMM.h
@@ -0,0 +1,141 @@
+/* $XConsortium: ct_BlitMM.h /main/2 1996/10/25 10:28:31 kaleb $ */
+
+
+
+
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_BlitMM.h,v 1.4 1998/08/29 05:43:05 dawes Exp $ */
+
+/* Definitions for the Chips and Technology BitBLT engine communication. */
+/* These are done using Memory Mapped IO, of the registers */
+/* BitBLT modes for register 93D0. */
+
+#define ctPATCOPY 0xF0
+#define ctTOP2BOTTOM 0x100
+#define ctBOTTOM2TOP 0x000
+#define ctLEFT2RIGHT 0x200
+#define ctRIGHT2LEFT 0x000
+#define ctSRCFG 0x400
+#define ctSRCMONO 0x800
+#define ctPATMONO 0x1000
+#define ctBGTRANSPARENT 0x2000
+#define ctSRCSYSTEM 0x4000
+#define ctPATSOLID 0x80000L
+#define ctPATSTART0 0x00000L
+#define ctPATSTART1 0x10000L
+#define ctPATSTART2 0x20000L
+#define ctPATSTART3 0x30000L
+#define ctPATSTART4 0x40000L
+#define ctPATSTART5 0x50000L
+#define ctPATSTART6 0x60000L
+#define ctPATSTART7 0x70000L
+
+/* Macros to do useful things with the C&T BitBLT engine */
+#define ctBLTWAIT \
+ {HW_DEBUG(0x4); \
+ while(*(volatile unsigned int *)(cPtr->MMIOBase + MR(0x4)) & \
+ 0x00100000){};}
+
+#define ctSETROP(op) \
+ {HW_DEBUG(0x4); *(unsigned int *)(cPtr->MMIOBase + MR(0x4)) = (op);}
+
+#define ctSETSRCADDR(srcAddr) \
+ {HW_DEBUG(0x5); \
+ *(unsigned int *)(cPtr->MMIOBase + MR(0x5)) = (srcAddr)&0x7FFFFFL;}
+
+#define ctSETDSTADDR(dstAddr) \
+{HW_DEBUG(0x6); \
+ *(unsigned int *)(cPtr->MMIOBase + MR(0x6)) = (dstAddr)&0x7FFFFFL;}
+
+#define ctSETPITCH(srcPitch,dstPitch) \
+{HW_DEBUG(0x0); \
+ *(unsigned int *)(cPtr->MMIOBase + MR(0x0)) = (((dstPitch)&0xFFFF)<<16)| \
+ ((srcPitch)&0xFFFF);}
+
+#define ctSETHEIGHTWIDTHGO(Height,Width)\
+{HW_DEBUG(0x7); \
+ *(unsigned int *)(cPtr->MMIOBase + MR(0x7)) = (((Height)&0xFFFF)<<16)| \
+ ((Width)&0xFFFF);}
+
+#define ctSETPATSRCADDR(srcAddr)\
+{HW_DEBUG(0x1); \
+ *(unsigned int *)(cPtr->MMIOBase + MR(0x1)) = (srcAddr)&0x1FFFFFL;}
+
+#define ctSETBGCOLOR8(c) {\
+ HW_DEBUG(0x2); \
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ *(unsigned int *)(cPtr->MMIOBase + MR(0x2)) = \
+ ((((((c)&0xFF)<<8)|((c)&0xFF))<<16) | \
+ ((((c)&0xFF)<<8)|((c)&0xFF))); \
+ } \
+}
+
+#define ctSETBGCOLOR16(c) {\
+ HW_DEBUG(0x2); \
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ *(unsigned int *)(cPtr->MMIOBase + MR(0x2)) = \
+ ((((c)&0xFFFF)<<16)|((c)&0xFFFF)); \
+ } \
+}
+
+/* As the 6554x doesn't support 24bpp colour expansion this doesn't work,
+ * It is here only for later use with the 65550 */
+#define ctSETBGCOLOR24(c) {\
+ HW_DEBUG(0x2); \
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ *(unsigned int *)(cPtr->MMIOBase + MR(0x2)) = ((c)&0xFFFFFF); \
+ } \
+}
+
+#define ctSETFGCOLOR8(c) {\
+ HW_DEBUG(0x3); \
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ *(unsigned int *)(cPtr->MMIOBase + MR(0x3)) = \
+ ((((((c)&0xFF)<<8)|((c)&0xFF))<<16) | \
+ ((((c)&0xFF)<<8)|((c)&0xFF))); \
+ } \
+}
+
+#define ctSETFGCOLOR16(c) {\
+ HW_DEBUG(0x3); \
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ *(unsigned int *)(cPtr->MMIOBase + MR(0x3)) = \
+ ((((c)&0xFFFF)<<16)|((c)&0xFFFF)); \
+ } \
+}
+
+/* As the 6554x doesn't support 24bpp colour expansion this doesn't work,
+ * It is here only for later use with the 65550 */
+#define ctSETFGCOLOR24(c) {\
+ HW_DEBUG(0x3); \
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ *(unsigned int *)(cPtr->MMIOBase + MR(0x3)) = ((c)&0xFFFFFF); \
+ } \
+}
+
+/* Define a Macro to replicate a planemask 64 times and write to address
+ * allocated for planemask pattern */
+#define ctWRITEPLANEMASK8(mask,addr) { \
+ if (cAcl->planemask != (mask&0xFF)) { \
+ cAcl->planemask = (mask&0xFF); \
+ memset((unsigned char *)cPtr->FbBase + addr, (mask&0xFF), 64); \
+ } \
+}
+
+#define ctWRITEPLANEMASK16(mask,addr) { \
+ if (cAcl->planemask != (mask&0xFFFF)) { \
+ cAcl->planemask = (mask&0xFFFF); \
+ { int i; \
+ for (i = 0; i < 64; i++) { \
+ memcpy((unsigned char *)cPtr->FbBase + addr \
+ + i * 2, &mask, 2); \
+ } \
+ } \
+ } \
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_Blitter.h b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_Blitter.h
new file mode 100644
index 000000000..6d05a0139
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_Blitter.h
@@ -0,0 +1,168 @@
+/* $XConsortium: ct_Blitter.h /main/2 1996/10/25 10:28:37 kaleb $ */
+
+
+
+
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_Blitter.h,v 1.3 1998/08/29 05:43:06 dawes Exp $ */
+
+/* Definitions for the Chips and Technology BitBLT engine communication. */
+/* registers */
+/* Do not read 87D0 while BitBLT is active */
+/* 83D0: 11-0 source offset, width of 'screen' */
+/* 15-12 reserved (0) */
+/* 27-16 destination offset, width of screen */
+/* 31-28 reserved (0) */
+/* 87D0: 20-0 pattern (alinged 8 pixel x 8 line) pointer */
+/* 31-21 reserved (0) */
+/* 8BD0: 15-0 backgroud colour */
+/* 31-6 duplicate of 15-0 */
+/* 8FD0: 15-0 foregroud/solid colour */
+/* 31-6 duplicate of 15-0 */
+/* 93D0: 7-0 ROP, same as MS-Windows */
+/* 8 BitBLT Y direction, if 0 bottom to top, 1 top to bottom */
+/* 9 BitBLT X direction, if 0 right to left, 1 left to right */
+/* 10 source data, if 0 source is selected bit 14, 1 foregourd colour */
+/* 11 source depth, if 0 source is colour, */
+/* 1 source is monochrome(Font expansion) */
+/* 12 pattern depth, if 0 colour, else monochrome */
+/* 13 background, if 0 opaque (8BD0), else transparent */
+/* 14 BitBLT source, if 0 screen, else system memory */
+/* 15 reserved (0, destination?) */
+/* 18-16 starting row of 8x8 pattern */
+/* 19 if 1 solid pattern (Brush), else bitmap */
+/* 20(R) BitBLT status, if 1 active */
+/* 23-21 reserved (0) */
+/* 27-24 vacancy in buffer */
+/* 31-25 reserved (0) */
+/* 97D0: 20-0 source address (byte aligned) */
+/* 31-21 reserved (0) */
+/* 9BD0: 20-0 destination address (byte aligned) */
+/* 31-21 reserved (0) */
+/* 9FD0: 11-0 number of bytes to be transferred per line */
+/* 15-12 reserved (0) */
+/* 27-16 height in lines of the block to be transferred */
+/* 31-28 reserved (0) */
+
+/* BitBLT modes for register 93D0. */
+
+#define ctPATCOPY 0xF0
+#define ctTOP2BOTTOM 0x100
+#define ctBOTTOM2TOP 0x000
+#define ctLEFT2RIGHT 0x200
+#define ctRIGHT2LEFT 0x000
+#define ctSRCFG 0x400
+#define ctSRCMONO 0x800
+#define ctPATMONO 0x1000
+#define ctBGTRANSPARENT 0x2000
+#define ctSRCSYSTEM 0x4000
+#define ctPATSOLID 0x80000L
+#define ctPATSTART0 0x00000L
+#define ctPATSTART1 0x10000L
+#define ctPATSTART2 0x20000L
+#define ctPATSTART3 0x30000L
+#define ctPATSTART4 0x40000L
+#define ctPATSTART5 0x50000L
+#define ctPATSTART6 0x60000L
+#define ctPATSTART7 0x70000L
+
+/* Macros to do useful things with the C&T BitBLT engine */
+
+#define ctBLTWAIT \
+ {HW_DEBUG(0x4+2); while(inw(DR(0x4)+2)&0x10){};}
+
+#define ctSETROP(op) \
+ {HW_DEBUG(0x4); outl(DR(0x4),(op));}
+
+#define ctSETSRCADDR(srcAddr) \
+ {HW_DEBUG(0x5); outl(DR(0x5),((srcAddr)&0x1FFFFFL));}
+
+#define ctSETDSTADDR(dstAddr) \
+ {HW_DEBUG(0x6); outl(DR(0x6),((dstAddr)&0x1FFFFFL));}
+
+#define ctSETPITCH(srcPitch,dstPitch) \
+ {HW_DEBUG(0x0); outl(DR(0x0),(((dstPitch)<<16)|(srcPitch)));}
+
+/* Note that this command signal a blit to commence */
+#define ctSETHEIGHTWIDTHGO(Height,Width)\
+ {HW_DEBUG(0x7); outl(DR(0x7),(((Height)<<16)|(Width)));}
+
+#define ctSETPATSRCADDR(srcAddr)\
+ {HW_DEBUG(0x1); outl(DR(0x1),((srcAddr)&0x1FFFFFL));}
+
+/* I can't help pointing out at this point that I'm not complaining
+ * about the american spelling of Colour!! [DGB] */
+
+#define ctSETBGCOLOR8(c) {\
+ HW_DEBUG(0x2); \
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ outl(DR(0x2),((((((c)&0xFF)<<8)|((c)&0xFF))<<16) | \
+ ((((c)&0xFF)<<8)|((c)&0xFF)))); \
+ } \
+}
+
+#define ctSETBGCOLOR16(c) {\
+ HW_DEBUG(0x2); \
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ outl(DR(0x2),((((c)&0xFFFF)<<16)|((c)&0xFFFF))); \
+ } \
+}
+
+/* As the 6554x doesn't support 24bpp colour expansion this doesn't work */
+#define ctSETBGCOLOR24(c) {\
+ HW_DEBUG(0x2); \
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ outl(DR(0x2),(c)&0xFFFFFF); \
+ } \
+}
+
+#define ctSETFGCOLOR8(c) {\
+ HW_DEBUG(0x3); \
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ outl(DR(0x3),((((((c)&0xFF)<<8)|((c)&0xFF))<<16) | \
+ ((((c)&0xFF)<<8)|((c)&0xFF)))); \
+ } \
+}
+
+#define ctSETFGCOLOR16(c) {\
+ HW_DEBUG(0x3); \
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ outl(DR(0x3),((((c)&0xFFFF)<<16)|((c)&0xFFFF))); \
+ } \
+}
+
+/* As the 6554x doesn't support 24bpp colour expansion this doesn't work */
+#define ctSETFGCOLOR24(c) {\
+ HW_DEBUG(0x3); \
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ outl(DR(0x3),(c)&0xFFFFFF); \
+ } \
+}
+
+/* Define a Macro to replicate a planemask 64 times and write to address
+ * allocated for planemask pattern */
+#define ctWRITEPLANEMASK8(mask,addr) { \
+ if (cAcl->planemask != (mask&0xFF)) { \
+ cAcl->planemask = (mask&0xFF); \
+ memset((unsigned char *)cPtr->FbBase + addr, (mask&0xFF), 64); \
+ } \
+}
+
+#define ctWRITEPLANEMASK16(mask,addr) { \
+ if (cAcl->planemask != (mask&0xFFFF)) { \
+ cAcl->planemask = (mask&0xFFFF); \
+ { int i; \
+ for (i = 0; i < 64; i++) { \
+ memcpy((unsigned char *)cPtr->FbBase + addr \
+ + i * 2, &mask, 2); \
+ } \
+ } \
+ } \
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_BltHiQV.h b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_BltHiQV.h
new file mode 100644
index 000000000..0580c003c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_BltHiQV.h
@@ -0,0 +1,170 @@
+/* $XConsortium: ct_BltHiQV.h /main/2 1996/10/25 10:28:43 kaleb $ */
+
+
+
+
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_BltHiQV.h,v 1.8 1998/12/20 11:57:40 dawes Exp $ */
+
+/* Definitions for the Chips and Technology BitBLT engine communication. */
+/* These are done using Memory Mapped IO, of the registers */
+/* BitBLT modes for register 93D0. */
+
+#define ctPATCOPY 0xF0
+#define ctLEFT2RIGHT 0x000
+#define ctRIGHT2LEFT 0x100
+#define ctTOP2BOTTOM 0x000
+#define ctBOTTOM2TOP 0x200
+#define ctSRCSYSTEM 0x400
+#define ctDSTSYSTEM 0x800
+#define ctSRCMONO 0x1000
+#define ctBGTRANSPARENT 0x22000
+#define ctCOLORTRANSENABLE 0x4000
+#define ctCOLORTRANSDISABLE 0x0
+#define ctCOLORTRANSDST 0x8000
+#define ctCOLORTRANSROP 0x0
+#define ctCOLORTRANSEQUAL 0x10000L
+#define ctCOLORTRANSNEQUAL 0x0
+#define ctPATMONO 0x40000L
+#define ctPATSOLID 0x80000L
+#define ctPATSTART0 0x000000L
+#define ctPATSTART1 0x100000L
+#define ctPATSTART2 0x200000L
+#define ctPATSTART3 0x300000L
+#define ctPATSTART4 0x400000L
+#define ctPATSTART5 0x500000L
+#define ctPATSTART6 0x600000L
+#define ctPATSTART7 0x700000L
+#define ctSRCFG 0x000000L /* Where is this for the 65550?? */
+
+/* The Monochrome expansion register setup */
+#define ctCLIPLEFT(clip) ((clip)&0x3F)
+#define ctCLIPRIGHT(clip) (((clip)&0x3F) << 8)
+#define ctSRCDISCARD(clip) (((clip)&0x3F) << 16)
+#define ctBITALIGN 0x1000000L
+#define ctBYTEALIGN 0x2000000L
+#define ctWORDALIGN 0x3000000L
+#define ctDWORDALIGN 0x4000000L
+#define ctQWORDALIGN 0x5000000L
+/* This shouldn't be used because not all chip rev's
+ * have BR09 and BR0A, and I haven't even defined
+ * macros to write to these registers
+ */
+#define ctEXPCOLSEL 0x8000000L
+
+/* Macros to do useful things with the C&T BitBLT engine */
+
+/* For some odd reason the blitter busy bit occasionly "locks up" when
+ * it gets polled to fast. However I have observed this behavior only
+ * when doing ScreenToScreenColorExpandFill on a 65550. This operation
+ * was broken anyway (the source offest register is not observed) therefore
+ * no action was taken.
+ *
+ * This function uses indirect access to XR20 to test whether the blitter
+ * is busy. If the cost of doing this is too high then other options will
+ * need to be considered.
+ *
+ * Note that BR04[31] can't be used as some C&T chipsets lockup when reading
+ * the BRxx registers.
+ */
+#define ctBLTWAIT \
+ {int timeout; \
+ timeout = 0; \
+ for (;;) { \
+ if (!((cPtr->readXR(cPtr, 0x20)) & 0x1)) break; \
+ timeout++; \
+ if (timeout == 100000) { \
+ unsigned char tmp; \
+ tmp = cPtr->readXR(cPtr, 0x20); \
+ cPtr->writeXR(cPtr, 0x20, ((tmp & 0xFD) | 0x2)); \
+ cPtr->writeXR(cPtr, 0x20, (tmp & 0xFD)); \
+ break; \
+ } \
+ } \
+ }
+
+#define ctSETROP(op) \
+ *(unsigned int *)(cPtr->MMIOBase + BR(0x4)) = (op)
+
+#define ctSETMONOCTL(op) \
+ *(unsigned int *)(cPtr->MMIOBase + BR(0x3)) = (op)
+
+#define ctSETSRCADDR(srcAddr) \
+ *(unsigned int *)(cPtr->MMIOBase + BR(0x6)) = (srcAddr)&0x7FFFFFL
+
+#define ctSETDSTADDR(dstAddr) \
+ *(unsigned int *)(cPtr->MMIOBase + BR(0x7)) = (dstAddr)&0x7FFFFFL
+
+#define ctSETPITCH(srcPitch,dstPitch) \
+ *(unsigned int *)(cPtr->MMIOBase + BR(0x0)) = (((dstPitch)&0xFFFF)<<16)| \
+ ((srcPitch)&0xFFFF)
+
+#define ctSETHEIGHTWIDTHGO(Height,Width)\
+ *(unsigned int *)(cPtr->MMIOBase + BR(0x8)) = (((Height)&0xFFFF)<<16)| \
+ ((Width)&0xFFFF)
+
+#define ctSETPATSRCADDR(srcAddr)\
+ *(unsigned int *)(cPtr->MMIOBase + BR(0x5)) = (srcAddr)&0x7FFFFFL
+
+#define ctSETBGCOLOR8(c) {\
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ *(unsigned int *)(cPtr->MMIOBase + BR(0x1)) = ((c)&0xFF); \
+ } \
+}
+
+#define ctSETBGCOLOR16(c) {\
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ *(unsigned int *)(cPtr->MMIOBase + BR(0x1)) = ((c)&0xFFFF); \
+ } \
+}
+
+#define ctSETBGCOLOR24(c) {\
+ if ((cAcl->bgColor != (c)) || (cAcl->bgColor == -1)) { \
+ cAcl->bgColor = (c); \
+ *(unsigned int *)(cPtr->MMIOBase + BR(0x1)) = ((c)&0xFFFFFF); \
+ } \
+}
+
+#define ctSETFGCOLOR8(c) {\
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ *(unsigned int *)(cPtr->MMIOBase + BR(0x2)) = ((c)&0xFF); \
+ } \
+}
+
+#define ctSETFGCOLOR16(c) {\
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ *(unsigned int *)(cPtr->MMIOBase + BR(0x2)) = ((c)&0xFFFF); \
+ } \
+}
+
+#define ctSETFGCOLOR24(c) {\
+ if ((cAcl->fgColor != (c)) || (cAcl->fgColor == -1)) { \
+ cAcl->fgColor = (c); \
+ *(unsigned int *)(cPtr->MMIOBase + BR(0x2)) = ((c)&0xFFFFFF); \
+ } \
+}
+
+/* Define a Macro to replicate a planemask 64 times and write to address
+ * allocated for planemask pattern */
+#define ctWRITEPLANEMASK8(mask,addr) { \
+ if (cAcl->planemask != (mask&0xFF)) { \
+ cAcl->planemask = (mask&0xFF); \
+ memset((unsigned char *)cPtr->FbBase + addr, (mask&0xFF), 64); \
+ } \
+}
+
+#define ctWRITEPLANEMASK16(mask,addr) { \
+ if (cAcl->planemask != (mask&0xFFFF)) { \
+ cAcl->planemask = (mask&0xFFFF); \
+ { int i; \
+ for (i = 0; i < 64; i++) { \
+ memcpy((unsigned char *)cPtr->FbBase + addr \
+ + i * 2, &mask, 2); \
+ } \
+ } \
+ } \
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_accel.c
new file mode 100644
index 000000000..a83e5f4c1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_accel.c
@@ -0,0 +1,1733 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_accel.c,v 1.32 1999/05/03 12:16:04 dawes Exp $ */
+/*
+ * Copyright 1996, 1997, 1998 by David Bateman <dbateman@ee.uts.edu.au>
+ * Modified 1997, 1998 by Nozomi Ytow
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS 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.
+ */
+
+/*
+ * When monochrome tiles/stipples are cached on the HiQV chipsets the
+ * pitch of the monochrome data is the displayWidth. The HiQV manuals
+ * state that the source pitch is ignored with monochrome data, and so
+ * "offically" there the XAA cached monochrome data can't be used. But
+ * it appears that by not setting the monochrome source alignment in
+ * BR03, the monochrome source pitch is forced to the displayWidth!!
+ *
+ * To enable the use of this undocumented feature, uncomment the define
+ * below.
+ */
+#define UNDOCUMENTED_FEATURE
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that use XAA need this */
+#include "xf86fbman.h"
+
+/* The vga HW register stuff. Do we need this? */
+#include "vgaHW.h"
+
+/* Our driver specific include file */
+#include "ct_driver.h"
+
+#ifdef DEBUG
+# define DEBUG_P(x) ErrorF(x"\n");
+#else
+# define DEBUG_P(x) /**/
+#endif
+
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define CATNAME(prefix,subname) prefix##subname
+#else
+#define CATNAME(prefix,subname) prefix/**/subname
+#endif
+
+#ifdef CHIPS_MMIO
+#ifdef CHIPS_HIQV
+#include "ct_BltHiQV.h"
+#define CTNAME(subname) CATNAME(CHIPSHiQV,subname)
+#else
+#include "ct_BlitMM.h"
+#define CTNAME(subname) CATNAME(CHIPSMMIO,subname)
+#endif
+#else
+#include "ct_Blitter.h"
+#define CTNAME(subname) CATNAME(CHIPS,subname)
+#endif
+
+
+#ifdef CHIPS_HIQV
+static void CTNAME(DepthChange)(ScrnInfoPtr pScrn, int depth);
+#endif
+static void CTNAME(8SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void CTNAME(16SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void CTNAME(24SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void CTNAME(SubsequentSolidFillRect)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h);
+#ifndef CHIPS_HIQV
+static void CTNAME(24SubsequentSolidFillRect)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h);
+#else
+static void CTNAME(32SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void CTNAME(32SubsequentSolidFillRect)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h);
+#endif
+static void CTNAME(SetupForScreenToScreenCopy)(ScrnInfoPtr pScrn, int xdir,
+ int ydir, int rop, unsigned int planemask,
+ int trans);
+static void CTNAME(SubsequentScreenToScreenCopy)(ScrnInfoPtr pScrn,
+ int srcX, int srcY, int dstX, int dstY,
+ int w, int h);
+static void CTNAME(SetupForCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int fg,
+ int bg, int rop, unsigned int planemask);
+static void CTNAME(SubsequentCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft);
+#ifndef CHIPS_HIQV
+static XAACacheInfoPtr CTNAME(CacheMonoStipple)(ScrnInfoPtr pScrn,
+ PixmapPtr pPix);
+#endif
+#if !defined(CHIPS_HIQV) || defined(UNDOCUMENTED_FEATURE)
+static void CTNAME(SetupForScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void CTNAME(SubsequentScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int skipleft);
+#endif
+static void CTNAME(SetupForMono8x8PatternFill)(ScrnInfoPtr pScrn,
+ int patx, int paty, int fg, int bg,
+ int rop, unsigned int planemask);
+static void CTNAME(SubsequentMono8x8PatternFillRect)(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h );
+static void CTNAME(SetupForColor8x8PatternFill)(ScrnInfoPtr pScrn,
+ int patx, int paty, int rop,
+ unsigned int planemask, int trans);
+static void CTNAME(SubsequentColor8x8PatternFillRect)(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h );
+#ifndef CHIPS_HIQV
+static void CTNAME(SetupForImageWrite)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask,
+ int transparency_color, int bpp, int depth);
+static void CTNAME(SubsequentImageWriteRect)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft);
+#else
+static void CTNAME(WritePixmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int rop,
+ unsigned int planemask, int trans, int bpp, int depth);
+static void CTNAME(ReadPixmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *dst, int dstwidth, int bpp, int depth);
+#endif
+
+
+Bool
+CTNAME(AccelInit)(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ BoxRec AvailFBArea;
+
+ DEBUG_P("AccelInit");
+ cPtr->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if(!infoPtr) return FALSE;
+
+ /*
+ * Setup some global variables
+ */
+ cAcl->BytesPerPixel = pScrn->bitsPerPixel >> 3;
+ cAcl->BitsPerPixel = pScrn->bitsPerPixel;
+ cAcl->PitchInBytes = pScrn->displayWidth * cAcl->BytesPerPixel;
+ cAcl->planemask = -1;
+ cAcl->bgColor = -1;
+ cAcl->fgColor = -1;
+ cAcl->FbOffset = 0;
+
+ /*
+ * Set up the main acceleration flags.
+ */
+ if (cAcl->CacheEnd > cAcl->CacheStart) infoPtr->Flags = PIXMAP_CACHE;
+
+ if (cPtr->Flags & ChipsLinearSupport)
+ infoPtr->Flags |= OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER;
+
+ infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES;
+
+ /*
+ * The following line installs a "Sync" function, that waits for
+ * all coprocessor operations to complete.
+ */
+ infoPtr->Sync = CTNAME(Sync);
+
+ /*
+ * Setup a Screen to Screen copy (BitBLT) primitive
+ */
+#ifndef CHIPS_HIQV
+ infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
+ if (cAcl->BitsPerPixel == 24)
+ infoPtr->ScreenToScreenCopyFlags |= NO_PLANEMASK;
+#else
+ infoPtr->ScreenToScreenCopyFlags = 0;
+ if ((cAcl->BitsPerPixel == 24) || (cAcl->BitsPerPixel == 32))
+ infoPtr->ScreenToScreenCopyFlags |= NO_PLANEMASK;
+
+ /* A Chips and Technologies application notes says that some
+ * 65550 have a bug that prevents 16bpp transparency. It probably
+ * applies to 24 bpp as well (Someone with a 65550 care to check?).
+ * Selection of this controlled in Probe.
+ */
+ if (!(cPtr->Flags & ChipsColorTransparency))
+ infoPtr->ScreenToScreenCopyFlags |= NO_TRANSPARENCY;
+#endif
+
+ infoPtr->SetupForScreenToScreenCopy = CTNAME(SetupForScreenToScreenCopy);
+ infoPtr->SubsequentScreenToScreenCopy =
+ CTNAME(SubsequentScreenToScreenCopy);
+
+ /*
+ * Install the low-level functions for drawing solid filled rectangles.
+ */
+ infoPtr->SolidFillFlags |= NO_PLANEMASK;
+ switch (cAcl->BitsPerPixel) {
+ case 8 :
+ infoPtr->SetupForSolidFill = CTNAME(8SetupForSolidFill);
+ infoPtr->SubsequentSolidFillRect = CTNAME(SubsequentSolidFillRect);
+ break;
+ case 16 :
+ infoPtr->SetupForSolidFill = CTNAME(16SetupForSolidFill);
+ infoPtr->SubsequentSolidFillRect = CTNAME(SubsequentSolidFillRect);
+ break;
+ case 24 :
+ infoPtr->SetupForSolidFill = CTNAME(24SetupForSolidFill);
+#ifdef CHIPS_HIQV
+ infoPtr->SubsequentSolidFillRect = CTNAME(SubsequentSolidFillRect);
+#else
+ /*
+ * The version of this function here uses three different
+ * algorithms in an attempt to maximise performance. One
+ * for RGB_EQUAL, another for !RGB_EQUAL && GXCOPY_ONLY
+ * and yet another for !RGB_EQUAL && !GXCOPY_ONLY. The
+ * first two versions use the 8bpp engine for the fill,
+ * whilst the second uses a framebuffer routine to create
+ * one scanline of the fill in off screen memory which is
+ * then used by a CopyArea function with a complex ROP.
+ */
+ infoPtr->SubsequentSolidFillRect = CTNAME(24SubsequentSolidFillRect);
+ if (cAcl->ScratchAddress < 0)
+ infoPtr->ScreenToScreenCopyFlags |= GXCOPY_ONLY;
+#endif
+ break;
+#ifdef CHIPS_HIQV
+ case 32:
+ if (cAcl->ScratchAddress > 0) {
+ infoPtr->SetupForSolidFill = CTNAME(32SetupForSolidFill);
+ infoPtr->SubsequentSolidFillRect =
+ CTNAME(32SubsequentSolidFillRect);
+ }
+ break;
+#endif
+ }
+
+#ifdef CHIPS_HIQV
+ /* At 32bpp we can't use the other acceleration */
+ if (cAcl->BitsPerPixel == 32) goto chips_imagewrite;
+#endif
+
+ /*
+ * Setup the functions that perform monochrome colour expansion
+ */
+
+#ifdef CHIPS_HIQV
+ infoPtr->CPUToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_MSBFIRST | CPU_TRANSFER_PAD_QWORD |
+ LEFT_EDGE_CLIPPING | LEFT_EDGE_CLIPPING_NEGATIVE_X |
+ ROP_NEEDS_SOURCE;
+#ifdef UNDOCUMENTED_FEATURE
+ infoPtr->ScreenToScreenColorExpandFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST |
+ LEFT_EDGE_CLIPPING;
+#endif
+ if (cAcl->BitsPerPixel == 24) {
+ infoPtr->CPUToScreenColorExpandFillFlags |= NO_PLANEMASK;
+#ifdef UNDOCUMENTED_FEATURE
+ infoPtr->ScreenToScreenColorExpandFillFlags |= NO_PLANEMASK;
+#endif
+ }
+#else
+ infoPtr->CPUToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_MSBFIRST | CPU_TRANSFER_PAD_DWORD |
+ ROP_NEEDS_SOURCE;
+ infoPtr->ScreenToScreenColorExpandFillFlags = BIT_ORDER_IN_BYTE_MSBFIRST;
+ infoPtr->CacheColorExpandDensity = 8;
+
+ if (cAcl->BitsPerPixel == 24)
+ infoPtr->CPUToScreenColorExpandFillFlags |= TRIPLE_BITS_24BPP |
+ RGB_EQUAL | NO_PLANEMASK;
+#endif
+
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ CTNAME(SetupForCPUToScreenColorExpandFill);
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ CTNAME(SubsequentCPUToScreenColorExpandFill);
+
+#ifndef CHIPS_HIQV
+ if (cAcl->BitsPerPixel != 24) {
+#endif
+#if !defined(CHIPS_HIQV) || defined(UNDOCUMENTED_FEATURE)
+ infoPtr->SetupForScreenToScreenColorExpandFill =
+ CTNAME(SetupForScreenToScreenColorExpandFill);
+ infoPtr->SubsequentScreenToScreenColorExpandFill =
+ CTNAME(SubsequentScreenToScreenColorExpandFill);
+#endif
+#ifndef CHIPS_HIQV
+ infoPtr->CacheMonoStipple = CTNAME(CacheMonoStipple);
+ }
+#endif
+
+ infoPtr->ColorExpandBase = (unsigned char *)cAcl->BltDataWindow;
+ infoPtr->ColorExpandRange = 64 * 1024;
+
+ /* Mono 8x8 pattern fills */
+ infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
+ BIT_ORDER_IN_BYTE_MSBFIRST | HARDWARE_PATTERN_SCREEN_ORIGIN;
+
+#ifdef CHIPS_HIQV
+ infoPtr->SetupForMono8x8PatternFill =
+ CTNAME(SetupForMono8x8PatternFill);
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ CTNAME(SubsequentMono8x8PatternFillRect);
+ if (cAcl->BitsPerPixel == 24)
+ infoPtr->MonoPatternPitch = 8; /* Need 8 byte alignment */
+#else
+ if (cAcl->BitsPerPixel != 24) {
+ infoPtr->SetupForMono8x8PatternFill =
+ CTNAME(SetupForMono8x8PatternFill);
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ CTNAME(SubsequentMono8x8PatternFillRect);
+ }
+#endif
+
+ /* Color 8x8 pattern fills, must have a displayWidth divisible by 64 */
+ if (!(pScrn->displayWidth % 64)) {
+#ifdef CHIPS_HIQV
+ infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK |
+ HARDWARE_PATTERN_SCREEN_ORIGIN;
+ if (!(cPtr->Flags & ChipsColorTransparency))
+ infoPtr->Color8x8PatternFillFlags |= NO_TRANSPARENCY;
+#else
+ infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK |
+ HARDWARE_PATTERN_SCREEN_ORIGIN | NO_TRANSPARENCY;
+#endif
+
+ if (cAcl->BitsPerPixel != 24) {
+ infoPtr->SetupForColor8x8PatternFill =
+ CTNAME(SetupForColor8x8PatternFill);
+ infoPtr->SubsequentColor8x8PatternFillRect =
+ CTNAME(SubsequentColor8x8PatternFillRect);
+ }
+ }
+
+#ifdef CHIPS_HIQV
+chips_imagewrite:
+#endif
+
+ /* Setup for the Image Write functions */
+#ifdef CHIPS_HIQV
+ infoPtr->WritePixmapFlags = CPU_TRANSFER_PAD_QWORD | LEFT_EDGE_CLIPPING
+ | LEFT_EDGE_CLIPPING_NEGATIVE_X | ROP_NEEDS_SOURCE;
+
+ if (!(cPtr->Flags & ChipsColorTransparency))
+ infoPtr->WritePixmapFlags |= NO_TRANSPARENCY;
+ if ((cAcl->BitsPerPixel == 24) || (cAcl->BitsPerPixel == 32))
+ infoPtr->WritePixmapFlags |= NO_PLANEMASK;
+
+ infoPtr->WritePixmap = CTNAME(WritePixmap);
+
+#if 0 /* Not used by XAA as yet, but coming soon */
+ if (cPtr->Flags & ChipsImageReadSupport) {
+ infoPtr->ReadPixmapFlags = CPU_TRANSFER_PAD_QWORD | ROP_NEEDS_SOURCE;
+ infoPtr->ReadPixmap = CTNAME(ReadPixmap);
+ }
+#endif
+
+#else
+ infoPtr->SetupForImageWrite = CTNAME(SetupForImageWrite);
+ infoPtr->SubsequentImageWriteRect = CTNAME(SubsequentImageWriteRect);
+ infoPtr->ImageWriteBase = (unsigned char *)cAcl->BltDataWindow;
+ infoPtr->ImageWriteRange = 64 * 1024;
+ infoPtr->ImageWriteFlags = NO_TRANSPARENCY | CPU_TRANSFER_PAD_DWORD
+ | ROP_NEEDS_SOURCE;
+ if ((cAcl->BitsPerPixel == 24) || (cAcl->BitsPerPixel == 32))
+ infoPtr->ImageWriteFlags |= NO_PLANEMASK;
+#endif
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = cAcl->CacheEnd /
+ (pScrn->displayWidth * cAcl->BytesPerPixel);
+
+#ifdef CHIPS_HIQV
+ if (!(cPtr->Flags & ChipsOverlay8plus16))
+#endif
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+#ifdef CHIPS_HIQV
+ if (XAAInit(pScreen, infoPtr)) {
+ if (cPtr->Flags & ChipsOverlay8plus16)
+ return(XAAInitDualFramebufferOverlay(pScreen,
+ CTNAME(DepthChange)));
+ else
+ return TRUE;
+ } else
+ return FALSE;
+#else
+ return(XAAInit(pScreen, infoPtr));
+#endif
+}
+
+#ifdef CHIPS_HIQV
+void
+CTNAME(DepthChange)(ScrnInfoPtr pScrn, int depth)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ unsigned char mode;
+
+ DEBUG_P("DepthChange");
+ switch (depth) {
+ case 8 :
+ cPtr->AccelInfoRec->SetupForSolidFill = CTNAME(8SetupForSolidFill);
+ mode = 0x00; /* BitBLT engine to 8bpp */
+ cAcl->BytesPerPixel = 1;
+ cAcl->FbOffset = 0;
+ cAcl->BitsPerPixel = 8;
+ break;
+ default :
+ cPtr->AccelInfoRec->SetupForSolidFill = CTNAME(16SetupForSolidFill);
+ mode = 0x10; /* BitBLT engine to 16bpp */
+ cAcl->BytesPerPixel = 2;
+ cAcl->FbOffset = cPtr->FbOffset16;
+ cAcl->BitsPerPixel = 16;
+ break;
+ }
+ cAcl->PitchInBytes = pScrn->displayWidth * cAcl->BytesPerPixel;
+ ctBLTWAIT;
+ cPtr->writeXR(cPtr, 0x20, mode); /* Change BitBLT engine mode */
+}
+#endif
+
+void
+CTNAME(Sync)(ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ DEBUG_P("sync");
+ ctBLTWAIT;
+}
+
+static void
+CTNAME(8SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("8SetupForSolidFill");
+ ctBLTWAIT;
+ ctSETBGCOLOR8(color);
+ ctSETFGCOLOR8(color);
+ ctSETROP(ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ctPATSOLID | ctPATMONO);
+ ctSETPITCH(0, cAcl->PitchInBytes);
+}
+
+static void
+CTNAME(16SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("16SetupForSolidFill");
+ ctBLTWAIT;
+ ctSETBGCOLOR16(color);
+ ctSETFGCOLOR16(color);
+ ctSETROP(ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ctPATSOLID | ctPATMONO);
+ ctSETPITCH(0, cAcl->PitchInBytes);
+}
+
+#ifdef CHIPS_HIQV
+static void
+CTNAME(24SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("24SetupForSolidFill");
+ ctBLTWAIT;
+ ctSETBGCOLOR24(color);
+ ctSETFGCOLOR24(color);
+ ctSETROP(ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ctPATSOLID | ctPATMONO);
+ ctSETPITCH(0, cAcl->PitchInBytes);
+}
+
+static void
+CTNAME(32SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("32SetupForSolidFill");
+ ctBLTWAIT;
+ memset((unsigned char *)cPtr->FbBase + cAcl->ScratchAddress, 0xAA, 8);
+ ctSETFGCOLOR16((color & 0xFFFF));
+ ctSETBGCOLOR16(((color >> 16) & 0xFFFF));
+ ctSETROP(ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ctPATMONO);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctSETPITCH(1, cAcl->PitchInBytes);
+}
+
+static void
+CTNAME(32SubsequentSolidFillRect)(ScrnInfoPtr pScrn, int x, int y, int w,
+ int h)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ unsigned int destaddr;
+ destaddr = (y * pScrn->displayWidth + x) << 2;
+ w <<= 2;
+ DEBUG_P("32SubsequentSolidFillRect");
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(h, w);
+}
+#else
+
+static void
+CTNAME(24SetupForSolidFill)(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ unsigned char pixel1, pixel2, pixel3;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("24SetupForSolidFill");
+ cAcl->rgb24equal = (((((color & 0xFF) == ((color & 0xFF00) >> 8)) &&
+ ((color & 0xFF) == ((color & 0xFF0000) >> 16)))) ||
+ /* Check the rop for paranoid reasons */
+ (rop == GXclear) || (rop == GXnoop) ||
+ (rop == GXinvert) || (rop == GXset));
+ if (cAcl->rgb24equal) {
+ cAcl->CommandFlags = ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM |
+ ctLEFT2RIGHT | ctPATSOLID | ctPATMONO;
+ ctBLTWAIT;
+ ctSETFGCOLOR8(color&0xFF);
+ ctSETBGCOLOR8(color&0xFF);
+ ctSETPITCH(0, cAcl->PitchInBytes);
+ } else {
+ cAcl->rop24bpp = rop;
+ if (rop == GXcopy) {
+ pixel3 = color & 0xFF;
+ pixel2 = (color >> 8) & 0xFF;
+ pixel1 = (color >> 16) & 0xFF;
+ cAcl->fgpixel = pixel1;
+ cAcl->bgpixel = pixel2;
+ cAcl->fillindex = 0;
+ cAcl->fastfill = FALSE;
+
+ /* Test for the special case where two of the byte of the
+ * 24bpp colour are the same. This can double the speed
+ */
+ if (pixel1 == pixel2) {
+ cAcl->fgpixel = pixel3;
+ cAcl->bgpixel = pixel1;
+ cAcl->fastfill = TRUE;
+ cAcl->fillindex = 1;
+ } else if (pixel1 == pixel3) {
+ cAcl->fgpixel = pixel2;
+ cAcl->bgpixel = pixel1;
+ cAcl->fastfill = TRUE;
+ cAcl->fillindex = 2;
+ } else if (pixel2 == pixel3) {
+ cAcl->fastfill = TRUE;
+ } else {
+ cAcl->xorpixel = pixel2 ^ pixel3;
+ }
+
+ cAcl->CommandFlags = ctSRCMONO | ctSRCSYSTEM | ctTOP2BOTTOM |
+ ctLEFT2RIGHT;
+ ctBLTWAIT;
+ if (cAcl->fastfill) {
+ ctSETFGCOLOR8(cAcl->fgpixel);
+ }
+ ctSETBGCOLOR8(cAcl->bgpixel);
+ ctSETSRCADDR(0);
+ ctSETPITCH(0, cAcl->PitchInBytes);
+ } else {
+ if (cAcl->color24bpp != color) {
+ cAcl->color24bpp = color;
+ cAcl->width24bpp = 0;
+ }
+ cAcl->rop24bpp = rop;
+ ctBLTWAIT;
+ ctSETROP(ctTOP2BOTTOM | ctLEFT2RIGHT | ChipsAluConv[rop & 0xF]);
+ ctSETPITCH(cAcl->PitchInBytes, cAcl->PitchInBytes);
+ }
+ }
+}
+
+static void
+CTNAME(24SubsequentSolidFillRect)(ScrnInfoPtr pScrn, int x, int y, int w,
+ int h)
+{
+ static unsigned int dwords[3] = { 0x24499224, 0x92244992, 0x49922449};
+ int srcaddr, destaddr, line, i;
+ register int width;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("24SubsequentSolidFillRect");
+ if (cAcl->rgb24equal) {
+ destaddr = y * pScrn->displayWidth + x;
+ destaddr += destaddr << 1;
+ ctBLTWAIT;
+ ctSETROP(cAcl->CommandFlags);
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(h, (w + (w << 1)));
+ } else {
+ if (cAcl->rop24bpp == GXcopy ) {
+ unsigned int *base = (unsigned int *)cAcl->BltDataWindow;
+ destaddr = y * cAcl->PitchInBytes + x * 3;
+ w *= 3;
+ width = ((w + 31) & ~31) >> 5;
+
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+
+ if (!cAcl->fastfill) ctSETFGCOLOR8(cAcl->fgpixel);
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[GXcopy & 0xF]);
+ ctSETDSTADDR(destaddr);
+ if (cAcl->fastfill) {
+ ctSETHEIGHTWIDTHGO(h, w);
+ line = 0;
+ while (line < h) {
+ base = (unsigned int *)cAcl->BltDataWindow;
+ for (i = 0; i < width; i++) {
+ *base++ = dwords[((cAcl->fillindex + i) % 3)];
+ }
+ line++;
+ }
+ } else {
+ ctSETHEIGHTWIDTHGO(1, w);
+ i = 0;
+ while(i < width){
+ *base++ = dwords[(i++ % 3)];
+ }
+ for(line = 0; (h >> line ) > 1; line++){;}
+ i = 0;
+ ctBLTWAIT;
+ ctSETFGCOLOR8(cAcl->xorpixel);
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[GXxor & 0xF] |
+ ctBGTRANSPARENT);
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(1, w);
+ base = (unsigned int *)cAcl->BltDataWindow;
+ while(i < width) {
+ *base++ = dwords[((++i) % 3)];
+ }
+ srcaddr = destaddr;
+ if(line){
+ i = 0;
+ ctBLTWAIT;
+ ctSETROP(ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv[GXcopy & 0xF]);
+ ctSETPITCH(cAcl->PitchInBytes, cAcl->PitchInBytes);
+ ctSETSRCADDR(srcaddr);
+
+ while(i < line){
+ destaddr = srcaddr + (cAcl->PitchInBytes << i);
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO((1 << i), w);
+ i++;
+ }
+
+ if((1 << line) < h){
+ destaddr = srcaddr + (cAcl->PitchInBytes << line);
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(h-(1 << line), w);
+ }
+
+ ctBLTWAIT;
+ ctSETROP(ctSRCMONO | ctSRCSYSTEM | ctTOP2BOTTOM |
+ ctLEFT2RIGHT | ChipsAluConv[GXcopy & 0xF]);
+ ctSETSRCADDR(0);
+ ctSETPITCH(0, cAcl->PitchInBytes);
+ }
+ }
+ } else {
+ register unsigned char *base;
+ if (cAcl->width24bpp < w) {
+ base = (unsigned char *)cPtr->FbBase + cAcl->ScratchAddress +
+ ((3 * cAcl->width24bpp + 3) & ~0x3);
+ width = w - cAcl->width24bpp;
+ ctBLTWAIT;
+ /* Load of a single scanline into framebuffer */
+ while (width > 0) {
+ *(unsigned int *)base = cAcl->color24bpp |
+ (cAcl->color24bpp << 24);
+ *(unsigned int *)(base + 4) = (cAcl->color24bpp >> 8) |
+ (cAcl->color24bpp << 16);
+ *(unsigned int *)(base + 8) = (cAcl->color24bpp >> 16) |
+ (cAcl->color24bpp << 8);
+ base += 12;
+ width -= 4;
+ }
+ cAcl->width24bpp = w - width;
+ }
+ line = 0;
+ destaddr = 3 * (y * pScrn->displayWidth + x);
+ w *= cAcl->BytesPerPixel;
+ while (line < h) {
+ ctBLTWAIT;
+ ctSETSRCADDR(cAcl->ScratchAddress);
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(1, w);
+ destaddr += (3 * pScrn->displayWidth);
+ line++;
+ }
+ }
+ }
+}
+#endif
+
+static void
+CTNAME(SubsequentSolidFillRect)(ScrnInfoPtr pScrn, int x, int y, int w,
+ int h)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ int destaddr;
+
+ DEBUG_P("SubsequentSolidFillRect");
+ destaddr = (y * pScrn->displayWidth + x) * cAcl->BytesPerPixel;
+#ifdef CHIPS_HIQV
+ destaddr += cAcl->FbOffset;
+#endif
+ w *= cAcl->BytesPerPixel;
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(h, w);
+}
+
+/*
+ * Screen-to-screen BitBLT.
+ *
+ */
+
+static void
+CTNAME(SetupForScreenToScreenCopy)(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned int planemask, int trans)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("SetupForScreenToScreenCopy");
+ cAcl->CommandFlags = 0;
+
+ /* Set up the blit direction. */
+ if (ydir < 0)
+ cAcl->CommandFlags |= ctBOTTOM2TOP;
+ else
+ cAcl->CommandFlags |= ctTOP2BOTTOM;
+ if (xdir < 0)
+ cAcl->CommandFlags |= ctRIGHT2LEFT;
+ else
+ cAcl->CommandFlags |= ctLEFT2RIGHT;
+#ifdef CHIPS_HIQV
+ if (trans != -1) {
+ cAcl->CommandFlags |= ctCOLORTRANSENABLE | ctCOLORTRANSROP |
+ ctCOLORTRANSNEQUAL;
+ ctBLTWAIT;
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETBGCOLOR8(trans);
+ break;
+ case 16:
+ ctSETBGCOLOR16(trans);
+ break;
+ case 24:
+ ctSETBGCOLOR24(trans);
+ break;
+ }
+ } else
+#endif
+ ctBLTWAIT;
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ if ((planemask & 0xFF) == 0xFF) {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ } else {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK8(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ case 16:
+ if ((planemask & 0xFFFF) == 0xFFFF) {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ } else {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK16(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ default:
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ break;
+ }
+ ctSETPITCH(cAcl->PitchInBytes, cAcl->PitchInBytes);
+}
+
+static void
+CTNAME(SubsequentScreenToScreenCopy)(ScrnInfoPtr pScrn, int srcX, int srcY,
+ int dstX, int dstY, int w, int h)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ unsigned int srcaddr, destaddr;
+
+ DEBUG_P("SubsequentScreenToScreenCopy");
+#ifdef CHIPS_HIQV
+ if (cAcl->CommandFlags & ctBOTTOM2TOP) {
+ srcaddr = (srcY + h - 1) * pScrn->displayWidth;
+ destaddr = (dstY + h - 1) * pScrn->displayWidth;
+ } else {
+ srcaddr = srcY * pScrn->displayWidth;
+ destaddr = dstY * pScrn->displayWidth;
+ }
+ if (cAcl->CommandFlags & ctRIGHT2LEFT) {
+ srcaddr = ( srcaddr + srcX + w ) * cAcl->BytesPerPixel - 1 ;
+ destaddr = ( destaddr + dstX + w ) * cAcl->BytesPerPixel - 1;
+ } else {
+ srcaddr = (srcaddr + srcX) * cAcl->BytesPerPixel;
+ destaddr = (destaddr + dstX) * cAcl->BytesPerPixel;
+ }
+ srcaddr += cAcl->FbOffset;
+ destaddr += cAcl->FbOffset;
+#else
+ if (cAcl->CommandFlags & ctTOP2BOTTOM) {
+ srcaddr = srcY * pScrn->displayWidth;
+ destaddr = dstY * pScrn->displayWidth;
+ } else {
+ srcaddr = (srcY + h - 1) * pScrn->displayWidth;
+ destaddr = (dstY + h - 1) * pScrn->displayWidth;
+ }
+ if (cAcl->CommandFlags & ctLEFT2RIGHT) {
+ srcaddr = (srcaddr + srcX) * cAcl->BytesPerPixel;
+ destaddr = (destaddr + dstX) * cAcl->BytesPerPixel;
+ } else {
+ srcaddr = ( srcaddr + srcX + w ) * cAcl->BytesPerPixel - 1 ;
+ destaddr = ( destaddr + dstX + w ) * cAcl->BytesPerPixel - 1;
+ }
+#endif
+ w *= cAcl->BytesPerPixel;
+ ctBLTWAIT;
+ ctSETSRCADDR(srcaddr);
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(h, w);
+}
+
+
+static void
+CTNAME(SetupForCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int fg,
+ int bg, int rop, unsigned int planemask)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("SetupForCPUToScreenColorExpandFill");
+ ctBLTWAIT;
+ cAcl->CommandFlags = 0;
+ if (bg == -1) {
+ cAcl->CommandFlags |= ctBGTRANSPARENT; /* Background = Destination */
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETFGCOLOR8(fg);
+ break;
+ case 16:
+ ctSETFGCOLOR16(fg);
+ break;
+ case 24:
+#ifdef CHIPS_HIQV
+ ctSETFGCOLOR24(fg);
+#else
+ ctSETFGCOLOR8(fg);
+#endif
+ break;
+ }
+ }
+ else {
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETBGCOLOR8(bg);
+ ctSETFGCOLOR8(fg);
+ break;
+ case 16:
+ ctSETBGCOLOR16(bg);
+ ctSETFGCOLOR16(fg);
+ break;
+ case 24:
+#ifdef CHIPS_HIQV
+ ctSETBGCOLOR24(bg);
+ ctSETFGCOLOR24(fg);
+#else
+ ctSETBGCOLOR8(bg);
+ ctSETFGCOLOR8(fg);
+#endif
+ break;
+ }
+ }
+
+#ifdef CHIPS_HIQV
+ ctSETMONOCTL(ctDWORDALIGN);
+#endif
+
+ ctSETSRCADDR(0);
+
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ if ((planemask & 0xFF) == 0xFF) {
+ ctSETROP(ctSRCSYSTEM | ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
+ } else {
+ ctSETROP(ctSRCSYSTEM | ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv3[rop & 0xF] | cAcl->CommandFlags);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK8(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ case 16:
+ if ((planemask & 0xFFFF) == 0xFFFF) {
+ ctSETROP(ctSRCSYSTEM | ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
+ } else {
+ ctSETROP(ctSRCSYSTEM | ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv3[rop & 0xF] | cAcl->CommandFlags);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK16(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ default:
+ ctSETROP(ctSRCSYSTEM | ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
+ break;
+ }
+ ctSETPITCH(0, cAcl->PitchInBytes);
+}
+
+static void
+CTNAME(SubsequentCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ int destaddr;
+
+ DEBUG_P("SubsequentCPUToScreenColorExpandFill");
+ destaddr = (y * pScrn->displayWidth + x + skipleft) *
+ cAcl->BytesPerPixel;
+#ifdef CHIPS_HIQV
+ destaddr += cAcl->FbOffset;
+#endif
+ w = (w - skipleft) * cAcl->BytesPerPixel;
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+#ifdef CHIPS_HIQV
+ ctSETMONOCTL(ctDWORDALIGN | ctCLIPLEFT(skipleft));
+#endif
+ ctSETHEIGHTWIDTHGO(h, w);
+}
+
+#if !defined(CHIPS_HIQV) || defined(UNDOCUMENTED_FEATURE)
+static void
+CTNAME(SetupForScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("SetupForScreenToScreenColorExpandFill");
+ cAcl->CommandFlags = 0;
+ ctBLTWAIT;
+ if (bg == -1) {
+ cAcl->CommandFlags |= ctBGTRANSPARENT; /* Background = Destination */
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETFGCOLOR8(fg);
+ break;
+ case 16:
+ ctSETFGCOLOR16(fg);
+ break;
+ case 24:
+#ifdef CHIPS_HIQV
+ ctSETFGCOLOR24(fg);
+#else
+ ctSETFGCOLOR8(fg);
+#endif
+ break;
+ }
+ }
+ else {
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETBGCOLOR8(bg);
+ ctSETFGCOLOR8(fg);
+ break;
+ case 16:
+ ctSETBGCOLOR16(bg);
+ ctSETFGCOLOR16(fg);
+ break;
+ case 24:
+#ifdef CHIPS_HIQV
+ ctSETBGCOLOR24(bg);
+ ctSETFGCOLOR24(fg);
+#else
+ ctSETBGCOLOR8(bg);
+ ctSETFGCOLOR8(fg);
+#endif
+ break;
+ }
+ }
+
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ if ((planemask & 0xFF) == 0xFF) {
+ ctSETROP(ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
+ } else {
+ ctSETROP(ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv3[rop & 0xF] | cAcl->CommandFlags);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK8(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ case 16:
+ if ((planemask & 0xFFFF) == 0xFFFF) {
+ ctSETROP(ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
+ } else {
+ ctSETROP(ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv3[rop & 0xF] | cAcl->CommandFlags);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK16(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ default:
+ ctSETROP(ctSRCMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv[rop & 0xF] | cAcl->CommandFlags);
+ break;
+ }
+ ctSETPITCH(cAcl->PitchInBytes, cAcl->PitchInBytes);
+}
+#endif
+#ifndef CHIPS_HIQV
+/*
+ * The non-HiQV chips don't have left-edge clippling of monochrome sources.
+ * However you can have the monochrome source starting on a byte boundary.
+ * Hence have 8 rotated copies of the monochrome source to simulate left
+ * edge clipping with these chips. This requires the XAACacheMonoStipple
+ * function to be replaced, if we are to use ScreenToScreenColorExpand.
+ */
+
+static XAACacheInfoPtr
+CTNAME(CacheMonoStipple)(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ XAAInfoRecPtr infoRec = (CHIPSPTR(pScrn))->AccelInfoRec;
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ int i, j, max = 0, funcNo, pad, dwords, bpp = cAcl->BitsPerPixel;
+ int *current;
+ StippleScanlineProcPtr StippleFunc;
+ unsigned char *data, *srcPtr, *dstPtr;
+
+ DEBUG_P("CacheMonoStipple");
+ if((h <= 128) && (w <= 128 * bpp / 8)) {
+ if(pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ } else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ } else if((h <= 256) && (w <= 256 * bpp / 8)){
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ } else if((h <= 512) && (w <= 512 * bpp / 8)){
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ } else { /* something's wrong */
+ ErrorF("Something's wrong in XAACacheMonoStipple()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+
+ /* lets look for it */
+ for(i = 0; i < max; i++, pCache++) {
+ if((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (pCache->fg == -1) && (pCache->bg == -1)) {
+ pCache->trans_color = -1;
+ dwords =
+ cAcl->SlotWidth = ((pCache->w * bpp) >> 5) >> 1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if(*current >= max) *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->bg = pCache->fg = -1;
+ pCache->orig_w = w; pCache->orig_h = h;
+
+ if(w <= 32) {
+ if(w & (w - 1)) funcNo = 1;
+ else funcNo = 0;
+ } else funcNo = 2;
+
+ pad = (((pCache->w * bpp) + 31) >> 5) << 2;
+ dstPtr = data = (unsigned char*)ALLOCATE_LOCAL(pad * pCache->h);
+ srcPtr = (unsigned char*)pPix->devPrivate.ptr;
+ StippleFunc = XAAStippleScanlineFuncMSBFirst[funcNo];
+
+ dwords = ((pCache->w * bpp) >> 5) >> 3;
+ cAcl->SlotWidth = dwords << 2;
+
+ for(i = 0; i < h; i++) {
+ for(j = 0; j < 8; j++) {
+ (*StippleFunc)((CARD32*)dstPtr + j * dwords,
+ (CARD32*)srcPtr, j, w, dwords);
+ }
+ srcPtr += pPix->devKind;
+ dstPtr += pad;
+ }
+
+ while((h<<1) <= pCache->h) {
+ memcpy(data + (pad * h), data, pad * h);
+ h <<= 1;
+ }
+
+ if(h < pCache->h)
+ memcpy(data + (pad * h), data, pad * (pCache->h - h));
+
+ (*infoRec->WritePixmapToCache)(
+ pScrn, pCache->x, pCache->y, pCache->w, pCache->h, data,
+ pad, bpp, pScrn->depth);
+
+ DEALLOCATE_LOCAL(data);
+
+ return pCache;
+}
+#endif
+#if !defined(CHIPS_HIQV) || defined(UNDOCUMENTED_FEATURE)
+static void
+CTNAME(SubsequentScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int skipleft)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ int srcaddr, destaddr;
+
+ DEBUG_P("SubsequentScreenToScreenColorExpandFill");
+#ifdef CHIPS_HIQV
+ srcaddr = (srcy * pScrn->displayWidth + srcx) * cAcl->BytesPerPixel
+ + ((skipleft & ~0x3F) >> 3);
+ if ( y < pScrn->virtualY)
+ srcaddr += cAcl->FbOffset;
+ else
+ srcaddr += cPtr->FbOffset16;
+#else
+ srcaddr = (srcy * pScrn->displayWidth + srcx) * cAcl->BytesPerPixel
+ + ((skipleft & 0x07) * cAcl->SlotWidth)
+ + ((skipleft & ~0x07) >> 3);
+#endif
+ destaddr = (y * pScrn->displayWidth + x) * cAcl->BytesPerPixel;
+#ifdef CHIPS_HIQV
+ destaddr += cAcl->FbOffset;
+#endif
+ w *= cAcl->BytesPerPixel;
+ ctBLTWAIT;
+#ifdef CHIPS_HIQV
+ if ((y >= pScrn->virtualY) && (cPtr->Flags & ChipsOverlay8plus16) &&
+ (pScrn->depth == 8))
+ ctSETPITCH(cAcl->PitchInBytes << 1, cAcl->PitchInBytes);
+#endif
+ ctSETSRCADDR(srcaddr);
+ ctSETDSTADDR(destaddr);
+#ifdef CHIPS_HIQV
+ ctSETMONOCTL(ctCLIPLEFT(skipleft & 0x3F));
+#endif
+ ctSETHEIGHTWIDTHGO(h, w);
+}
+#endif
+static void
+CTNAME(SetupForColor8x8PatternFill)(ScrnInfoPtr pScrn, int patx, int paty,
+ int rop, unsigned int planemask,
+ int trans)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ unsigned int patternaddr;
+
+ DEBUG_P("SetupForColor8x8PatternFill");
+ cAcl->CommandFlags = ChipsAluConv2[rop & 0xF] | ctTOP2BOTTOM |
+ ctLEFT2RIGHT;
+ patternaddr = (paty * pScrn->displayWidth +
+ (patx & ~0x3F)) * cAcl->BytesPerPixel;
+ cAcl->patternyrot = (patx & 0x3F) >> 3;
+#ifdef CHIPS_HIQV
+ if (cPtr->Flags & ChipsOverlay8plus16)
+ patternaddr += cPtr->FbOffset16;
+#endif
+
+ ctBLTWAIT;
+ ctSETPATSRCADDR(patternaddr);
+#ifdef CHIPS_HIQV
+ if (trans != -1) {
+ cAcl->CommandFlags |= ctCOLORTRANSENABLE | ctCOLORTRANSROP |
+ ctCOLORTRANSNEQUAL;
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETBGCOLOR8(trans);
+ break;
+ case 16:
+ ctSETBGCOLOR16(trans);
+ break;
+ case 24:
+ ctSETBGCOLOR24(trans);
+ break;
+ }
+ } else
+#endif
+ ctSETPITCH(8 * cAcl->BytesPerPixel, cAcl->PitchInBytes);
+}
+
+static void
+CTNAME(SubsequentColor8x8PatternFillRect)(ScrnInfoPtr pScrn, int patx, int paty,
+ int x, int y, int w, int h)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ unsigned int destaddr;
+
+ DEBUG_P("SubsequentColor8x8PatternFillRect");
+ destaddr = (y * pScrn->displayWidth + x) * cAcl->BytesPerPixel;
+#ifdef CHIPS_HIQV
+ destaddr += cAcl->FbOffset;
+#endif
+ w *= cAcl->BytesPerPixel;
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+#ifdef CHIPS_HIQV
+ ctSETROP(cAcl->CommandFlags | (((y + cAcl->patternyrot) & 0x7) << 20));
+#else
+ ctSETROP(cAcl->CommandFlags | (((y + cAcl->patternyrot) & 0x7) << 16));
+#endif
+ ctSETHEIGHTWIDTHGO(h, w);
+}
+
+static void
+CTNAME(SetupForMono8x8PatternFill)(ScrnInfoPtr pScrn, int patx, int paty,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ unsigned int patternaddr;
+
+ DEBUG_P("SetupForMono8x8PatternFill");
+ cAcl->CommandFlags = ctPATMONO | ctTOP2BOTTOM | ctLEFT2RIGHT |
+ ChipsAluConv2[rop & 0xF];
+
+#ifdef CHIPS_HIQV
+ patternaddr = paty * pScrn->displayWidth + patx;
+ if (cPtr->Flags & ChipsOverlay8plus16)
+ patternaddr = patternaddr * 2 + cPtr->FbOffset16;
+ else
+ patternaddr *= cAcl->BytesPerPixel;
+#else
+ patternaddr = (paty * pScrn->displayWidth + patx) * cAcl->BytesPerPixel;
+#endif
+ ctBLTWAIT;
+ ctSETPATSRCADDR(patternaddr);
+ if (bg == -1) {
+ cAcl->CommandFlags |= ctBGTRANSPARENT; /* Background = Destination */
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETFGCOLOR8(fg);
+ break;
+ case 16:
+ ctSETFGCOLOR16(fg);
+ break;
+ case 24:
+ ctSETFGCOLOR24(fg);
+ break;
+ }
+ }
+ else {
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETBGCOLOR8(bg);
+ ctSETFGCOLOR8(fg);
+ break;
+ case 16:
+ ctSETBGCOLOR16(bg);
+ ctSETFGCOLOR16(fg);
+ break;
+ case 24:
+ ctSETBGCOLOR24(bg);
+ ctSETFGCOLOR24(fg);
+ break;
+ }
+ }
+#ifdef CHIPS_HIQV
+ ctSETMONOCTL(ctDWORDALIGN);
+#endif
+ ctSETPITCH(1,cAcl->PitchInBytes);
+}
+
+static void
+CTNAME(SubsequentMono8x8PatternFillRect)(ScrnInfoPtr pScrn, int patx,
+ int paty, int x, int y, int w, int h )
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ int destaddr;
+ DEBUG_P("SubsequentMono8x8PatternFillRect");
+ destaddr = (y * pScrn->displayWidth + x) * cAcl->BytesPerPixel;
+#ifdef CHIPS_HIQV
+ destaddr += cAcl->FbOffset;
+#endif
+ w *= cAcl->BytesPerPixel;
+
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+#ifdef CHIPS_HIQV
+ ctSETROP(cAcl->CommandFlags | ((y & 0x7) << 20));
+#else
+ ctSETROP(cAcl->CommandFlags | ((y & 0x7) << 16));
+#endif
+ ctSETHEIGHTWIDTHGO(h, w);
+}
+
+#ifndef CHIPS_HIQV
+static void
+CTNAME(SetupForImageWrite)(ScrnInfoPtr pScrn, int rop, unsigned int planemask,
+ int transparency_color, int bpp, int depth)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ DEBUG_P("SetupForImageWrite");
+ cAcl->CommandFlags = ctSRCSYSTEM | ctTOP2BOTTOM | ctLEFT2RIGHT;
+ ctBLTWAIT;
+
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ if ((planemask & 0xFF) == 0xFF) {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ } else {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK8(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ case 16:
+ if ((planemask & 0xFFFF) == 0xFFFF) {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ } else {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK16(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ default:
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ break;
+ }
+ ctSETSRCADDR(0);
+}
+
+static void
+CTNAME(SubsequentImageWriteRect)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ int skipleft)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ int destaddr = (y * pScrn->displayWidth + x) * cAcl->BytesPerPixel;
+ DEBUG_P("SubsequentImageWriteRect");
+ w *= cAcl->BytesPerPixel;
+ ctBLTWAIT;
+ ctSETPITCH(((w + 3) & ~0x3), cAcl->PitchInBytes);
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(h, w);
+}
+
+#else
+/*
+ * Copyright 1997
+ * Digital Equipment Corporation. All rights reserved.
+ * This software is furnished under license and may be used and copied only in
+ * accordance with the following terms and conditions. Subject to these
+ * conditions, you may download, copy, install, use, modify and distribute
+ * this software in source and/or binary form. No title or ownership is
+ * transferred hereby.
+ * 1) Any source code used, modified or distributed must reproduce and retain
+ * this copyright notice and list of conditions as they appear in the
+ * source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or logo of Digital
+ * Equipment Corporation. Neither the "Digital Equipment Corporation" name
+ * nor any trademark or logo of Digital Equipment Corporation may be used
+ * to endorse or promote products derived from this software without the
+ * prior written permission of Digital Equipment Corporation.
+ *
+ * 3) This software is provided "AS-IS" and any express or implied warranties,
+ * including but not limited to, any implied warranties of merchantability,
+ * fitness for a particular purpose, or non-infringement are disclaimed. In
+ * no event shall DIGITAL be liable for any damages whatsoever, and in
+ * particular, DIGITAL shall not be liable for special, indirect,
+ * consequential, or incidental damages or damages for lost profits, loss
+ * of revenue or loss of use, whether such damages arise in contract,
+ * negligence, tort, under statute, in equity, at law or otherwise, even if
+ * advised of the possibility of such damage.
+ */
+
+/* The code below comes from the idea supplied by the people at DEC, like
+ * the copyright above says. But its had to go through a large evolution
+ * to fit it into the new design for XFree86 4.0
+ */
+
+static void
+MoveDWORDS(register CARD32* dest, register CARD32* src, register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ *(dest + 2) = *(src + 2);
+ *(dest + 3) = *(src + 3);
+ src += 4;
+ dest += 4;
+ dwords -= 4;
+ }
+ switch(dwords){
+ case 1:
+ *dest = *src;
+ break;
+ case 2:
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ break;
+ case 3:
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ *(dest + 2) = *(src + 2);
+ break;
+ }
+}
+
+#ifndef __GNUC__
+#define __inline__ /**/
+#endif
+
+static __inline__ void
+MoveDataFromCPU(unsigned char *src, unsigned char *dest, int srcwidth,
+ int window, int h, int dwords)
+{
+ if(srcwidth == (dwords << 2)) {
+ int decrement = window / dwords;
+ while(h > decrement) {
+ MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords * decrement);
+ src += (srcwidth * decrement);
+ h -= decrement;
+ }
+ if(h) {
+ MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords * h);
+ }
+ } else {
+ while(h--) {
+ MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords);
+ src += srcwidth;
+ }
+ }
+}
+
+static __inline__ void
+MoveDataToCPU(unsigned char *src, unsigned char *dest, int dstwidth,
+ int window, int h, int dwords)
+{
+ if(dstwidth == (dwords << 2)) {
+ int decrement = window / dwords;
+ while(h > decrement) {
+ MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords * decrement);
+ dest += (dstwidth * decrement);
+ h -= decrement;
+ }
+ if(h) {
+ MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords * h);
+ }
+ } else {
+ while(h--) {
+ MoveDWORDS((CARD32*)dest, (CARD32*)src, dwords);
+ dest += dstwidth;
+ }
+ }
+}
+
+static void
+CTNAME(WritePixmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int rop,
+ unsigned int planemask, int trans, int bpp, int depth)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ unsigned int bytesPerLine;
+ unsigned int byteWidthSrc;
+ unsigned int destpitch;
+ int dwords;
+ int skipleft;
+ int destaddr;
+ int olddepth = -1;
+
+ DEBUG_P("WritePixmap");
+#ifdef DEBUG
+ ErrorF("WritePixmap x %d, y %d, w %d, h %d, src 0x%X, srcwidth %d, rop 0x%X, planemask 0x%X, trans 0x%X, bpp %d, depth %d\n", x, y, w, h, src, srcwidth, rop, planemask, trans, bpp, depth);
+#endif
+
+ bytesPerLine = w * (bpp >> 3);
+ byteWidthSrc = ((srcwidth * (bpp >> 3) + 3L) & ~0x3L);
+ cAcl->CommandFlags = ctSRCSYSTEM | ctLEFT2RIGHT | ctTOP2BOTTOM;
+ skipleft = (unsigned int)src & 0x7;
+ src = (unsigned char *)((unsigned int)src & ~0x7L);
+ dwords = (((skipleft + bytesPerLine + 0x7) & ~0x7)) >> 2;
+ destaddr = (y * pScrn->displayWidth + x) * (bpp >> 3);
+ destpitch = pScrn->displayWidth * (bpp >> 3);
+ if ((y >= pScrn->virtualY) && (cPtr->Flags & ChipsOverlay8plus16))
+ destaddr += cPtr->FbOffset16;
+ else
+ destaddr += cAcl->FbOffset;
+
+ ctBLTWAIT;
+
+ if (trans != -1) {
+ cAcl->CommandFlags |= ctCOLORTRANSENABLE | ctCOLORTRANSROP |
+ ctCOLORTRANSNEQUAL;
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ ctSETBGCOLOR8(trans);
+ break;
+ case 16:
+ ctSETBGCOLOR16(trans);
+ break;
+ case 24:
+ ctSETBGCOLOR24(trans);
+ break;
+ }
+ }
+
+ switch (cAcl->BitsPerPixel) {
+ case 8:
+ if ((planemask & 0xFF) == 0xFF) {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ } else {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK8(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ case 16:
+ if ((planemask & 0xFFFF) == 0xFFFF) {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ } else {
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv3[rop & 0xF]);
+ ctSETPATSRCADDR(cAcl->ScratchAddress);
+ ctWRITEPLANEMASK16(planemask, cAcl->ScratchAddress);
+ }
+ break;
+ default:
+ ctSETROP(cAcl->CommandFlags | ChipsAluConv[rop & 0xF]);
+ break;
+ }
+
+ /*
+ *
+ * CT6555X requires quad-word padding, but XAA provides double-word
+ * padding. If the width of a region to be transferred happens to be
+ * quad-word aligned, the transfer is straightforward. If the
+ * region is double-word aligned, a pair of contiguous scanlines
+ * is quad-word aligned. In latter case, we can use interleaved
+ * transfer twice. It is faster than transfer line by line.
+ *
+ */
+
+ ctSETSRCADDR(skipleft);
+ ctSETDSTADDR(destaddr);
+
+ if ((byteWidthSrc & 0x7) == 0) { /* quad-word aligned */
+
+ ctSETPITCH(byteWidthSrc, destpitch);
+ ctSETHEIGHTWIDTHGO(h, bytesPerLine);
+
+ MoveDataFromCPU((unsigned char *)src,
+ (unsigned char *)cAcl->BltDataWindow,
+ srcwidth, 16384, h, dwords);
+
+ } else {
+ unsigned int vert = h;
+
+ h = (vert + 1) >> 1;
+
+ ctSETPITCH(byteWidthSrc << 1, destpitch << 1);
+ ctSETHEIGHTWIDTHGO(h, bytesPerLine);
+
+ MoveDataFromCPU((unsigned char *)src,
+ (unsigned char *)cAcl->BltDataWindow,
+ srcwidth<<1, 16384, h, dwords);
+
+ h = vert >> 1;
+ src += srcwidth;
+ y++;
+
+ destaddr = (y * pScrn->displayWidth + x) * (bpp >> 3);
+ if ((y >= pScrn->virtualY) && (cPtr->Flags & ChipsOverlay8plus16))
+ destaddr += cPtr->FbOffset16;
+ else
+ destaddr += cAcl->FbOffset;
+
+ ctBLTWAIT;
+ ctSETDSTADDR(destaddr);
+ ctSETHEIGHTWIDTHGO(h, bytesPerLine);
+
+ MoveDataFromCPU((unsigned char *)src,
+ (unsigned char *)cAcl->BltDataWindow,
+ srcwidth<<1, 16384, h, dwords);
+ }
+
+ cPtr->AccelInfoRec->NeedToSync = TRUE;
+}
+
+static void
+CTNAME(ReadPixmap)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *dst, int dstwidth, int bpp, int depth)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+ unsigned int bytesPerLine;
+ unsigned int byteWidthDst;
+ unsigned int srcpitch;
+ int dwords;
+ int srcaddr;
+
+ DEBUG_P("ReadPixmap");
+ bytesPerLine = w * (bpp >> 3);
+ byteWidthDst = ((dstwidth * (bpp >> 3) + 3L) & ~0x3L);
+ dwords = (((bytesPerLine + 0x7) & ~0x7)) >> 2;
+ srcaddr = (y * pScrn->displayWidth + x) * (bpp >> 3);
+ srcpitch = pScrn->displayWidth * (bpp >> 3);
+ if ((y >= pScrn->virtualY) && (cPtr->Flags & ChipsOverlay8plus16))
+ srcaddr += cPtr->FbOffset16;
+ else
+ srcaddr += cAcl->FbOffset;
+
+ ctBLTWAIT;
+ ctSETROP( ctDSTSYSTEM | ctLEFT2RIGHT | ctTOP2BOTTOM |
+ ChipsAluConv[GXcopy & 0xF]);
+ ctSETDSTADDR(0);
+ ctSETSRCADDR(srcaddr);
+
+ if ((byteWidthDst & 0x7) == 0) { /* quad-word aligned */
+
+ ctSETPITCH(srcpitch, byteWidthDst);
+ ctSETHEIGHTWIDTHGO(h, bytesPerLine);
+
+ MoveDataToCPU((unsigned char *)cAcl->BltDataWindow,
+ (unsigned char *)dst, dstwidth, 16384, h, dwords);
+
+ } else {
+ unsigned int vert = h;
+
+ h = (vert + 1) >> 1;
+
+ ctSETPITCH(srcpitch << 1, byteWidthDst << 1);
+ ctSETHEIGHTWIDTHGO(h, bytesPerLine);
+
+ MoveDataToCPU((unsigned char *)cAcl->BltDataWindow,
+ (unsigned char *)dst, dstwidth<<1, 16384, h, dwords);
+
+ h = vert >> 1;
+ dst += dstwidth;
+ y++;
+ srcaddr = (y * pScrn->displayWidth + x) * (bpp >> 3);
+ if ((y >= pScrn->virtualY) && (cPtr->Flags & ChipsOverlay8plus16))
+ srcaddr += cPtr->FbOffset16;
+ else
+ srcaddr += cAcl->FbOffset;
+ ctBLTWAIT;
+ ctSETSRCADDR(srcaddr);
+ ctSETHEIGHTWIDTHGO(h, bytesPerLine);
+
+ MoveDataToCPU((unsigned char *)cAcl->BltDataWindow,
+ (unsigned char *)dst, dstwidth<<1, 16384, h, dwords);
+ }
+
+ cPtr->AccelInfoRec->NeedToSync = TRUE;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_bank.c b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_bank.c
new file mode 100644
index 000000000..5b31a258a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_bank.c
@@ -0,0 +1,602 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_bank.c,v 1.4 1998/12/20 11:57:42 dawes Exp $ */
+
+/*
+ * Copyright 1997
+ * Digital Equipment Corporation. All rights reserved.
+ * This software is furnished under license and may be used and copied only in
+ * accordance with the following terms and conditions. Subject to these
+ * conditions, you may download, copy, install, use, modify and distribute
+ * this software in source and/or binary form. No title or ownership is
+ * transferred hereby.
+ * 1) Any source code used, modified or distributed must reproduce and retain
+ * this copyright notice and list of conditions as they appear in the
+ * source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or logo of Digital
+ * Equipment Corporation. Neither the "Digital Equipment Corporation" name
+ * nor any trademark or logo of Digital Equipment Corporation may be used
+ * to endorse or promote products derived from this software without the
+ * prior written permission of Digital Equipment Corporation.
+ *
+ * 3) This software is provided "AS-IS" and any express or implied warranties,
+ * including but not limited to, any implied warranties of merchantability,
+ * fitness for a particular purpose, or non-infringement are disclaimed. In
+ * no event shall DIGITAL be liable for any damages whatsoever, and in
+ * particular, DIGITAL shall not be liable for special, indirect,
+ * consequential, or incidental damages or damages for lost profits, loss
+ * of revenue or loss of use, whether such damages arise in contract,
+ * negligence, tort, under statute, in equity, at law or otherwise, even if
+ * advised of the possibility of such damage.
+ */
+#define PSZ 8
+
+/*
+ * Define DIRECT_REGISTER_ACCESS if you want to bypass the wrapped register
+ * access functions
+ */
+/* #define DIRECT_REGISTER_ACCESS */
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.h"
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* Driver specific headers */
+#include "ct_driver.h"
+
+#ifdef __arm32__
+/*#include <machine/sysarch.h>*/
+#define arm32_drain_writebuf() sysarch(1, 0)
+#define ChipsBank(pScreen) CHIPSPTR(xf86Screens[pScreen->myNum])->Bank
+#endif
+
+#ifdef DIRECT_REGISTER_ACCESS
+int
+CHIPSSetRead(ScreenPtr pScreen, int bank)
+{
+ outw(0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x10));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+
+int
+CHIPSSetWrite(ScreenPtr pScreen, int bank)
+{
+ outw(0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x11));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+
+int
+CHIPSSetReadWrite(ScreenPtr pScreen, int bank)
+{
+ outw(0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x10));
+ outw(0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x11));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSSetReadPlanar(ScreenPtr pScreen, int bank)
+{
+ outw(0x3D6, ((((bank << 5) & 0xFF) << 8) | 0x10));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSSetWritePlanar(ScreenPtr pScreen, int bank)
+{
+ outw(0x3D6, ((((bank << 5) & 0xFF) << 8) | 0x11));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSSetReadWritePlanar(ScreenPtr pScreen, int bank)
+{
+ outw(0x3D6, ((((bank << 5) & 0xFF) << 8) | 0x10));
+ outw(0x3D6, ((((bank << 5) & 0xFF) << 8) | 0x11));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetRead(ScreenPtr pScreen, int bank)
+{
+ register unsigned char tmp;
+
+ outw(0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x10));
+ outb(0x3D6, 0x0C);
+ tmp = inb(0x3D7) & 0xEF;
+ outw(0x3D6, (((((bank >> 1) & 0x10) | tmp) << 8) | 0x0C));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+
+int
+CHIPSWINSetWrite(ScreenPtr pScreen, int bank)
+{
+ register unsigned char tmp;
+
+ outw(0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x11));
+ outb(0x3D6, 0x0C);
+ tmp = inb(0x3D7) & 0xBF;
+ outw(0x3D6, (((((bank << 1) & 0x40) | tmp) << 8) | 0x0C));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetReadWrite(ScreenPtr pScreen, int bank)
+{
+ register unsigned char tmp;
+
+ outw(0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x10));
+ outw(0x3D6, ((((bank << 3) & 0xFF) << 8) | 0x11));
+ outb(0x3D6, 0x0C);
+ tmp = inb(0x3D7) & 0xAF;
+ outw(0x3D6, (((((bank << 1) & 0x40) | ((bank >> 1) & 0x10) | tmp) << 8) | 0x0C));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetReadPlanar(ScreenPtr pScreen, int bank)
+{
+ register unsigned char tmp;
+
+ outw(0x3D6, ((((bank << 5) & 0xFF) << 8) | 0x10));
+ outb(0x3D6, 0x0C);
+ tmp = inb(0x3D7) & 0xEF;
+ outw(0x3D6, (((((bank << 1) & 0x10) | tmp) << 8) | 0x0C));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetWritePlanar(ScreenPtr pScreen, int bank)
+{
+ register unsigned char tmp;
+
+ outw(0x3D6, ((((bank << 5) & 0xFF) << 8) | 0x11));
+ outb(0x3D6, 0x0C);
+ tmp = inb(0x3D7) & 0xBF;
+ outw(0x3D6, (((((bank << 3) & 0x40) | tmp) << 8) | 0x0C));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetReadWritePlanar(ScreenPtr pScreen, int bank)
+{
+ register unsigned char tmp;
+
+ outw(0x3D6, ((((bank << 5) & 0xFF) << 8) | 0x10));
+ outw(0x3D6, ((((bank << 5) & 0xFF) << 8) | 0x11));
+ outb(0x3D6, 0x0C);
+ tmp = inb(0x3D7) & 0xAF;
+ outw(0x3D6, (((((bank << 3) & 0x40) | ((bank << 1) & 0x10) | tmp) << 8) | 0x0C));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSHiQVSetReadWrite(ScreenPtr pScreen, int bank)
+{
+ outw(0x3D6, (((bank & 0x7F) << 8) | 0x0E));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSHiQVSetReadWritePlanar(ScreenPtr pScreen, int bank)
+{
+ outw(0x3D6, ((((bank << 2) & 0x7F) << 8) | 0x0E));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != ChipsBank(pScreen)) {
+ arm32_drain_writebuf();
+ ChipsBank(pScreen) = bank;
+ }
+#endif
+
+ return 0;
+}
+
+#else /* DIRECT_REGISTER_ACCESS */
+
+int
+CHIPSSetRead(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ cPtr->writeXR(cPtr, 0x10, ((bank << 3) & 0xFF));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+
+int
+CHIPSSetWrite(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ cPtr->writeXR(cPtr, 0x11, ((bank << 3) & 0xFF));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+
+int
+CHIPSSetReadWrite(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ cPtr->writeXR(cPtr, 0x10, ((bank << 3) & 0xFF));
+ cPtr->writeXR(cPtr, 0x11, ((bank << 3) & 0xFF));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSSetReadPlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ cPtr->writeXR(cPtr, 0x10, ((bank << 5) & 0xFF));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSSetWritePlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ cPtr->writeXR(cPtr, 0x11, ((bank << 5) & 0xFF));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSSetReadWritePlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ cPtr->writeXR(cPtr, 0x10, ((bank << 5) & 0xFF));
+ cPtr->writeXR(cPtr, 0x11, ((bank << 5) & 0xFF));
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetRead(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ cPtr->writeXR(cPtr, 0x10, ((bank << 3) & 0xFF));
+ tmp = cPtr->readXR(cPtr, 0x0C) & 0xEF;
+ cPtr->writeXR(cPtr, 0x0C, ((bank >> 1) & 0x10) | tmp);
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+
+int
+CHIPSWINSetWrite(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ cPtr->writeXR(cPtr, 0x11, ((bank << 3) & 0xFF));
+ tmp = cPtr->readXR(cPtr, 0x0C) & 0xBF;
+ cPtr->writeXR(cPtr, 0x0C, ((bank << 1) & 0x40) | tmp);
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetReadWrite(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ cPtr->writeXR(cPtr, 0x10, ((bank << 3) & 0xFF));
+ cPtr->writeXR(cPtr, 0x11, ((bank << 3) & 0xFF));
+ tmp = cPtr->readXR(cPtr, 0x0C) & 0xAF;
+ cPtr->writeXR(cPtr, 0x0C, ((bank << 1) & 0x40) | ((bank >> 1) & 0x10) | tmp);
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetReadPlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ cPtr->writeXR(cPtr, 0x10, ((bank << 5) & 0xFF));
+ tmp = cPtr->readXR(cPtr, 0x0C) & 0xEF;
+ cPtr->writeXR(cPtr, 0x0C, ((bank << 1) & 0x10) | tmp);
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetWritePlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ cPtr->writeXR(cPtr, 0x11, ((bank << 5) & 0xFF));
+ tmp = cPtr->readXR(cPtr, 0x0C) & 0xBF;
+ cPtr->writeXR(cPtr, 0x0C, ((bank << 3) & 0x40) | tmp);
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSWINSetReadWritePlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+ register unsigned char tmp;
+
+ cPtr->writeXR(cPtr, 0x10, ((bank << 5) & 0xFF));
+ cPtr->writeXR(cPtr, 0x11, ((bank << 5) & 0xFF));
+ tmp = cPtr->readXR(cPtr, 0x0C) & 0xAF;
+ cPtr->writeXR(cPtr, 0x0C, ((bank << 3) & 0x40) | ((bank << 1) & 0x10) | tmp);
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSHiQVSetReadWrite(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ cPtr->writeXR(cPtr, 0x0E, bank & 0x7F);
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+
+int
+CHIPSHiQVSetReadWritePlanar(ScreenPtr pScreen, int bank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(xf86Screens[pScreen->myNum]);
+
+ cPtr->writeXR(cPtr, 0x0E, (bank << 2) & 0x7F);
+
+#ifdef __arm32__
+ /* Must drain StrongARM write buffer on bank switch! */
+ if (bank != cPtr->Bank) {
+ arm32_drain_writebuf();
+ cPtr->Bank = bank;
+ }
+#endif
+
+ return 0;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_cursor.c
new file mode 100644
index 000000000..6375a15c6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_cursor.c
@@ -0,0 +1,318 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_cursor.c,v 1.17 1998/12/20 11:57:42 dawes Exp $ */
+
+/*
+ * Copyright 1994 The XFree86 Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * DAVID WEXELBLAT 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.
+ *
+ * Hardware Cursor for Trident utilizing XAA Cursor code.
+ * Written by Alan Hourihane <alanh@fairlite.demon.co.uk>
+ * Modified for Chips and Technologies by David Bateman <dbateman@eng.uts.edu.au>
+ */
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.h"
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* All drivers using the vgahw module need this */
+/* This driver needs to be modified to not use vgaHW for multihead operation */
+#include "vgaHW.h"
+
+#include "xf86Cursor.h"
+
+/* Driver specific headers */
+#include "ct_driver.h"
+
+/* Sync function, maybe this should check infoRec->NeedToSync before syncing */
+#define CURSOR_SYNC(pScrn) \
+ if (IS_HiQV(cPtr)) { \
+ CHIPSHiQVSync(pScrn); \
+ } else { \
+ if(!cPtr->UseMMIO) { \
+ CHIPSSync(pScrn); \
+ } else { \
+ CHIPSMMIOSync(pScrn); \
+ } \
+ }
+
+
+static void
+CHIPSShowCursor(ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char tmp;
+
+ CURSOR_SYNC(pScrn);
+
+ /* turn the cursor on */
+ if (IS_HiQV(cPtr)) {
+ tmp = cPtr->readXR(cPtr, 0xA0);
+ cPtr->writeXR(cPtr, 0xA0, (tmp & 0xF8) | 5);
+ } else {
+ if(!cPtr->UseMMIO) {
+ HW_DEBUG(0x8);
+ outw(DR(0x8), 0x21);
+ } else {
+ HW_DEBUG(DR(8));
+ MMIOmemw(MR(8)) = 0x21;
+ }
+ }
+ cPtr->HWCursorShown = TRUE;
+}
+
+static void
+CHIPSHideCursor(ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char tmp;
+
+ CURSOR_SYNC(pScrn);
+
+ /* turn the cursor off */
+ if (IS_HiQV(cPtr)) {
+ tmp = cPtr->readXR(cPtr, 0xA0);
+ cPtr->writeXR(cPtr, 0xA0, tmp & 0xF8);
+ } else {
+ if(!cPtr->UseMMIO) {
+ HW_DEBUG(0x8);
+ outw(DR(0x8), 0x20);
+ } else {
+ HW_DEBUG(DR(0x8));
+ MMIOmemw(DR(0x8)) = 0x20;
+ }
+ }
+ cPtr->HWCursorShown = FALSE;
+}
+
+static void
+CHIPSSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ CURSOR_SYNC(pScrn);
+
+ if (pScrn->currentMode->Flags & V_DBLSCAN)
+ y *= 2;
+
+ if (x < 0)
+ x = ~(x-1) | 0x8000;
+ if (y < 0)
+ y = ~(y-1) | 0x8000;
+
+ /* Program the cursor origin (offset into the cursor bitmap). */
+ if (IS_HiQV(cPtr)) {
+ cPtr->writeXR(cPtr, 0xA4, x & 0xFF);
+ cPtr->writeXR(cPtr, 0xA5, (x >> 8) & 0x87);
+ cPtr->writeXR(cPtr, 0xA6, y & 0xFF);
+ cPtr->writeXR(cPtr, 0xA7, (y >> 8) & 0x87);
+ } else {
+ unsigned long xy;
+
+ xy = y;
+ xy = (xy << 16) | x;
+ if(!cPtr->UseMMIO) {
+ HW_DEBUG(0xB);
+ outl(DR(0xB), xy);
+ } else {
+ HW_DEBUG(MR(0xB));
+ MMIOmeml(MR(0xB)) = xy;
+ }
+ }
+}
+
+static void
+CHIPSSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ unsigned long packedcolfg, packedcolbg;
+
+ CURSOR_SYNC(pScrn);
+
+ if (IS_HiQV(cPtr)) {
+ unsigned char xr80;
+
+ /* Enable extended palette addressing */
+ xr80 = cPtr->readXR(cPtr, 0x80);
+ cPtr->writeXR(cPtr, 0x80, xr80 | 0x1);
+
+ /* Write the new colours to the extended VGA palette. Palette
+ * index is incremented after each write, so only write index
+ * once
+ */
+ hwp->writeDacWriteAddr(hwp, 0x04);
+ if (xr80 & 0x80) {
+ /* 8bit DAC */
+ hwp->writeDacData(hwp, (bg >> 16) & 0xFF);
+ hwp->writeDacData(hwp, (bg >> 8) & 0xFF);
+ hwp->writeDacData(hwp, bg & 0xFF);
+ hwp->writeDacData(hwp, (fg >> 16) & 0xFF);
+ hwp->writeDacData(hwp, (fg >> 8) & 0xFF);
+ hwp->writeDacData(hwp, fg & 0xFF);
+ } else {
+ /* 6bit DAC */
+ hwp->writeDacData(hwp, (bg >> 18) & 0xFF);
+ hwp->writeDacData(hwp, (bg >> 10) & 0xFF);
+ hwp->writeDacData(hwp, (bg >> 2) & 0xFF);
+ hwp->writeDacData(hwp, (fg >> 18) & 0xFF);
+ hwp->writeDacData(hwp, (fg >> 10) & 0xFF);
+ hwp->writeDacData(hwp, (fg >> 2) & 0xFF);
+ }
+ /* Enable normal palette addressing */
+ cPtr->writeXR(cPtr, 0x80, xr80);
+ } else if (IS_Wingine(cPtr)) {
+ outl(DR(0xA), (bg & 0xFFFFFF));
+ outl(DR(0x9), (fg & 0xFFFFFF));
+ } else {
+ packedcolfg = ((fg & 0xF80000) >> 8) | ((fg & 0xFC00) >> 5)
+ | ((fg & 0xF8) >> 3);
+ packedcolbg = ((bg & 0xF80000) >> 8) | ((bg & 0xFC00) >> 5)
+ | ((bg & 0xF8) >> 3);
+ packedcolfg = (packedcolfg << 16) | packedcolbg;
+ if(!cPtr->UseMMIO) {
+ HW_DEBUG(0x9);
+ outl(DR(0x9), packedcolfg);
+ } else {
+ MMIOmeml(MR(0x9)) = packedcolfg;
+ HW_DEBUG(MR(0x9));
+ }
+ }
+}
+
+static void
+CHIPSLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ CURSOR_SYNC(pScrn);
+
+ if (IS_Wingine(cPtr)) {
+ int i;
+ unsigned long *tmp = (unsigned long *)src;
+
+ outl(DR(0x8),0x20);
+ for (i=0; i<64; i++) {
+ outl(DR(0xC),*(unsigned long *)tmp);
+ tmp++;
+ }
+ } else {
+ if (cPtr->Flags & ChipsLinearSupport) {
+ memcpy((unsigned char *)cPtr->FbBase + cAcl->CursorAddress,
+ src, cPtr->CursorInfoRec->MaxWidth *
+ cPtr->CursorInfoRec->MaxHeight / 4);
+ } else {
+ /*
+ * The cursor can only be in the last 16K of video memory,
+ * which fits in the last banking window.
+ */
+ if (IS_HiQV(cPtr))
+ if (pScrn->bitsPerPixel < 8)
+ CHIPSHiQVSetReadWritePlanar(pScrn->pScreen,
+ (int)(cAcl->CursorAddress >> 16));
+ else
+ CHIPSHiQVSetReadWrite(pScrn->pScreen,
+ (int)(cAcl->CursorAddress >> 16));
+ else
+ if (pScrn->bitsPerPixel < 8)
+ CHIPSSetWritePlanar(pScrn->pScreen,
+ (int)(cAcl->CursorAddress >> 16));
+ else
+ CHIPSSetWrite(pScrn->pScreen,
+ (int)(cAcl->CursorAddress >> 16));
+ memcpy((unsigned char *)cPtr->FbBase + (cAcl->CursorAddress &
+ 0xFFFF), src, cPtr->CursorInfoRec->MaxWidth *
+ cPtr->CursorInfoRec->MaxHeight / 4);
+ }
+ }
+
+ /* set cursor address here or we loose the cursor on video mode change */
+ if (IS_HiQV(cPtr)) {
+ cPtr->writeXR(cPtr, 0xA2, (cAcl->CursorAddress >> 8) & 0xFF);
+ cPtr->writeXR(cPtr, 0xA3, (cAcl->CursorAddress >> 16) & 0x3F);
+ } else if (!IS_Wingine(cPtr)) {
+ if (!cPtr->UseMMIO) {
+ HW_DEBUG(0xC);
+ outl(DR(0xC), cAcl->CursorAddress);
+ } else {
+ HW_DEBUG(MR(0xC));
+ MMIOmeml(MR(0xC)) = cAcl->CursorAddress;
+ }
+ }
+}
+
+static Bool
+CHIPSUseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
+{
+ CHIPSACLPtr cAcl = CHIPSACLPTR(xf86Screens[pScr->myNum]);
+
+ return cAcl->UseHWCursor;
+}
+
+Bool
+CHIPSCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ cPtr->CursorInfoRec = infoPtr;
+
+ infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_INVERT_MASK |
+ HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
+
+ if (IS_HiQV(cPtr)) {
+ infoPtr->Flags |= HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->MaxWidth = 64;
+ } else if (IS_Wingine(cPtr)) {
+ infoPtr->Flags |= HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
+ infoPtr->MaxHeight = 32;
+ infoPtr->MaxWidth = 32;
+ } else {
+ infoPtr->Flags |= HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8;
+ infoPtr->MaxHeight = 32;
+ infoPtr->MaxWidth = 32;
+ }
+
+ infoPtr->SetCursorColors = CHIPSSetCursorColors;
+ infoPtr->SetCursorPosition = CHIPSSetCursorPosition;
+ infoPtr->LoadCursorImage = CHIPSLoadCursorImage;
+ infoPtr->HideCursor = CHIPSHideCursor;
+ infoPtr->ShowCursor = CHIPSShowCursor;
+ infoPtr->UseHWCursor = CHIPSUseHWCursor;
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_ddc.c b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_ddc.c
new file mode 100644
index 000000000..232ad5765
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_ddc.c
@@ -0,0 +1,283 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_ddc.c,v 1.5 1999/08/21 13:48:34 dawes Exp $ */
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.h"
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* All drivers using the vgahw module need this */
+#include "vgaHW.h"
+
+#include "ct_driver.h"
+
+static Bool chips_TestI2C(int scrnIndex);
+static Bool chips_setI2CBits(I2CBusPtr I2CPtr, ScrnInfoPtr pScrn);
+
+static unsigned int
+chips_ddc1Read(ScrnInfoPtr pScrn)
+{
+ unsigned char ddc_mask = ((CHIPSPtr)pScrn->driverPrivate)->ddc_mask;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ register unsigned int tmp;
+
+ while ((cPtr->readST01(cPtr)) & 0x08){};
+ while (!(cPtr->readST01(cPtr)) & 0x08){};
+ tmp = cPtr->readXR(cPtr, 0x63);
+ return (tmp & ddc_mask);
+}
+
+void
+chips_ddc1(ScrnInfoPtr pScrn)
+{
+ unsigned char FR0B, FR0C, XR62;
+ unsigned char mask_c = 0x00;
+ unsigned char val, tmp_val;
+ int i;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Probing for DDC1\n");
+
+ FR0C = cPtr->readFR(cPtr, 0x0C);
+ XR62 = cPtr->readXR(cPtr, 0x62);
+ switch (cPtr->Chipset) {
+ case CHIPS_CT65550:
+ cPtr->ddc_mask = 0x1F; /* GPIO 0-4 */
+ FR0B = cPtr->readFR(cPtr, 0x0B);
+ if (!(FR0B & 0x10)) /* GPIO 2 is used as 32 kHz input */
+ cPtr->ddc_mask &= 0xFB;
+ if (cPtr->Bus == ChipsVLB) /* GPIO 3-7 are used as address bits */
+ cPtr->ddc_mask &= 0x07;
+ break;
+ case CHIPS_CT65554:
+ case CHIPS_CT65555:
+ case CHIPS_CT68554:
+ cPtr->ddc_mask = 0x0F; /* GPIO 0-3 */
+ break;
+ case CHIPS_CT69000:
+ case CHIPS_CT69030:
+ cPtr->ddc_mask = 0x9F; /* GPIO 0-4,7? */
+ break;
+ default:
+ cPtr->ddc_mask = 0x0C; /* GPIO 2,3 */
+ break;
+ }
+ if (!(FR0C & 0x80)) { /* GPIO 1 is not available */
+ mask_c |= 0xC0;
+ cPtr->ddc_mask &= 0xFE;
+ }
+ if (!(FR0C & 0x10)) { /* GPIO 0 is not available */
+ mask_c |= 0x18;
+ cPtr->ddc_mask &= 0xFD;
+ }
+
+ /* set GPIO 0,1 to read if available */
+ cPtr->writeFR(cPtr, 0x0C, (FR0C & mask_c) | (~mask_c & 0x90));
+ /* set remaining GPIO to read */
+ cPtr->writeXR(cPtr, 0x62, 0x00);
+
+ val = chips_ddc1Read(pScrn);
+ for (i = 0; i < 70; i++) {
+ tmp_val = chips_ddc1Read(pScrn);
+ if (tmp_val != val)
+ break;
+ }
+ cPtr->ddc_mask = val ^ tmp_val;
+ if (cPtr->ddc_mask)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DDC1 found\n");
+ else return;
+
+ xf86PrintEDID(xf86DoEDID_DDC1(pScrn->scrnIndex,vgaHWddc1SetSpeed,
+ chips_ddc1Read));
+
+ /* restore */
+ cPtr->writeFR(cPtr, 0x0C, FR0C);
+ cPtr->writeXR(cPtr, 0x62, XR62);
+}
+
+static void
+chips_I2CGetBits(I2CBusPtr b, int *clock, int *data)
+{
+ CHIPSI2CPtr pI2C_c = (CHIPSI2CPtr) (b->DriverPrivate.ptr);
+ unsigned char FR0C, XR62, val;
+
+ FR0C = pI2C_c->cPtr->readFR(pI2C_c->cPtr, 0x0C);
+ if (pI2C_c->i2cDataBit & 0x01 || pI2C_c->i2cClockBit & 0x01)
+ FR0C = (FR0C & 0xE7) | 0x10;
+ if (pI2C_c->i2cDataBit & 0x02 || pI2C_c->i2cClockBit & 0x02)
+ FR0C = (FR0C & 0x3F) | 0x80;
+ XR62 = pI2C_c->cPtr->readXR(pI2C_c->cPtr, 0x62);
+ XR62 &= (~pI2C_c->i2cDataBit) & (~pI2C_c->i2cClockBit);
+ pI2C_c->cPtr->writeFR(pI2C_c->cPtr, 0x0C, FR0C);
+ pI2C_c->cPtr->writeXR(pI2C_c->cPtr, 0x62, XR62);
+ val = pI2C_c->cPtr->readXR(pI2C_c->cPtr, 0x63);
+ *clock = (val & pI2C_c->i2cClockBit) != 0;
+ *data = (val & pI2C_c->i2cDataBit) != 0;
+}
+
+static void
+chips_I2CPutBits(I2CBusPtr b, int clock, int data)
+{
+ CHIPSI2CPtr pI2C_c = (CHIPSI2CPtr) (b->DriverPrivate.ptr);
+ unsigned char FR0C, XR62, val;
+
+ FR0C = pI2C_c->cPtr->readFR(pI2C_c->cPtr, 0x0C);
+ if (((pI2C_c->i2cDataBit & 0x01) && data)
+ || ((pI2C_c->i2cClockBit & 0x01) && clock))
+ FR0C |= 0x18;
+ else if ((pI2C_c->i2cDataBit & 0x01)
+ || (pI2C_c->i2cClockBit & 0x01))
+ FR0C |= 0x10;
+ if (((pI2C_c->i2cDataBit & 0x02) && data)
+ || ((pI2C_c->i2cClockBit & 0x02) && clock))
+ FR0C |= 0xC0;
+ else if ((pI2C_c->i2cDataBit & 0x02)
+ || (pI2C_c->i2cClockBit & 0x02))
+ FR0C |= 0x80;
+ XR62 = pI2C_c->cPtr->readXR(pI2C_c->cPtr, 0x62);
+ XR62 = (XR62 & ~pI2C_c->i2cClockBit) | (clock ? pI2C_c->i2cClockBit : 0);
+ XR62 = (XR62 & ~pI2C_c->i2cDataBit) | (data ? pI2C_c->i2cDataBit : 0);
+ pI2C_c->cPtr->writeFR(pI2C_c->cPtr, 0x0C, FR0C);
+ pI2C_c->cPtr->writeXR(pI2C_c->cPtr, 0x62, XR62);
+ val = pI2C_c->cPtr->readXR(pI2C_c->cPtr, 0x63);
+ val = (val & ~pI2C_c->i2cClockBit) | (clock ? pI2C_c->i2cClockBit : 0);
+ val = (val & ~pI2C_c->i2cDataBit) | (data ? pI2C_c->i2cDataBit : 0);
+ pI2C_c->cPtr->writeXR(pI2C_c->cPtr, 0x63, val);
+}
+
+
+Bool
+chips_i2cInit(ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ I2CBusPtr I2CPtr;
+
+ I2CPtr = xf86CreateI2CBusRec();
+ if(!I2CPtr) return FALSE;
+
+ cPtr->I2C = I2CPtr;
+
+ I2CPtr->BusName = "DDC";
+ I2CPtr->scrnIndex = pScrn->scrnIndex;
+ I2CPtr->I2CPutBits = chips_I2CPutBits;
+ I2CPtr->I2CGetBits = chips_I2CGetBits;
+ I2CPtr->DriverPrivate.ptr = xalloc(sizeof(CHIPSI2CRec));
+ ((CHIPSI2CPtr)(I2CPtr->DriverPrivate.ptr))->cPtr = cPtr;
+
+ if (!xf86I2CBusInit(I2CPtr))
+ return FALSE;
+
+ if (!chips_setI2CBits(I2CPtr, pScrn))
+ return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+chips_setI2CBits(I2CBusPtr b, ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSI2CPtr pI2C_c = (CHIPSI2CPtr) (b->DriverPrivate.ptr);
+ unsigned char FR0B, FR0C;
+ unsigned char bits, data_bits, clock_bits;
+ int i,j;
+
+ FR0C = cPtr->readFR(cPtr, 0x0C);
+ switch (cPtr->Chipset) {
+ case CHIPS_CT65550:
+ bits = 0x1F; /* GPIO 0-4 */
+ FR0B = cPtr->readFR(cPtr, 0x0B);
+ if (!(FR0B & 0x10)) /* GPIO 2 is used as 32 kHz input */
+ bits &= 0xFB;
+ pI2C_c->i2cDataBit = 0x01;
+ pI2C_c->i2cClockBit = 0x02;
+ if (cPtr->Bus == ChipsVLB) /* GPIO 3-7 are used as address bits */
+ bits &= 0x07;
+ break;
+ case CHIPS_CT65554:
+ case CHIPS_CT65555:
+ case CHIPS_CT68554:
+ bits = 0x0F; /* GPIO 0-3 */
+ pI2C_c->i2cDataBit = 0x04;
+ pI2C_c->i2cClockBit = 0x08;
+ break;
+ case CHIPS_CT69000:
+ case CHIPS_CT69030:
+ bits = 0x9F; /* GPIO 0-4,7? */
+ pI2C_c->i2cDataBit = 0x04;
+ pI2C_c->i2cClockBit = 0x08;
+ break;
+ default:
+ bits = 0x0C; /* GPIO 2,3 */
+ pI2C_c->i2cDataBit = 0x04;
+ pI2C_c->i2cClockBit = 0x08;
+ break;
+ }
+ if (!(FR0C & 0x80)) { /* GPIO 1 is not available */
+ bits &= 0xFE;
+ }
+ if (!(FR0C & 0x10)) { /* GPIO 0 is not available */
+ bits &= 0xFD;
+ }
+ pI2C_c->i2cClockBit &= bits;
+ pI2C_c->i2cDataBit &= bits;
+ /*
+ * first we test out the "favorite" GPIO bits ie. the ones suggested
+ * by the data book; if we don't succeed test all other combinations
+ * of possible GPIO pins as data/clock lines as the manufacturer might
+ * have its own ideas.
+ */
+ if (chips_TestI2C(pScrn->scrnIndex)) return TRUE;
+
+ data_bits = bits;
+ pI2C_c->i2cDataBit = 0x01;
+ for (i = 0; i<8; i++) {
+ if (data_bits & 0x01) {
+ clock_bits = bits;
+ pI2C_c->i2cClockBit = 0x01;
+ for (j = 0; j<8; j++) {
+ if (clock_bits & 0x01)
+ if (chips_TestI2C(pScrn->scrnIndex)) return TRUE;
+ clock_bits >>= 1;
+ pI2C_c->i2cClockBit <<= 1;
+ }
+ }
+ data_bits >>= 1;
+ pI2C_c->i2cDataBit <<= 1;
+ }
+ /*
+ * We haven't found a valid clock/data line combination - that
+ * doesn't mean there aren't any. We just haven't received an
+ * answer from the relevant DDC I2C addresses. We'll have to wait
+ * and see, if this is too restrictive (eg one wants to use I2C
+ * for something else than DDC we might have to probe more addresses
+ * or just fall back to the "favorite" GPIO lines.
+ */
+ return FALSE;
+}
+
+static Bool
+chips_TestI2C(int scrnIndex)
+{
+ int i;
+ I2CBusPtr b;
+
+ b = xf86I2CFindBus(scrnIndex, "DDC");
+ if (b == NULL) return FALSE;
+ else {
+ for(i = 0xA0; i < 0xA8; i += 2)
+ if(xf86I2CProbeAddress(b, i))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_dga.c
new file mode 100644
index 000000000..942b78251
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_dga.c
@@ -0,0 +1,304 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_dga.c,v 1.1 1999/08/14 10:49:38 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "ct_driver.h"
+#include "dgaproc.h"
+
+
+static Bool CHIPS_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
+ int *, int *, int *);
+static Bool CHIPS_SetMode(ScrnInfoPtr, DGAModePtr);
+static int CHIPS_GetViewport(ScrnInfoPtr);
+static void CHIPS_SetViewport(ScrnInfoPtr, int, int, int);
+static void CHIPS_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
+static void CHIPS_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+static void CHIPS_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
+ unsigned long);
+
+static
+DGAFunctionRec CHIPS_DGAFuncs = {
+ CHIPS_OpenFramebuffer,
+ NULL,
+ CHIPS_SetMode,
+ CHIPS_SetViewport,
+ CHIPS_GetViewport,
+ CHIPSSync,
+ CHIPS_FillRect,
+ CHIPS_BlitRect,
+#if 0
+ CHIPS_BlitTransRect
+#else
+ NULL
+#endif
+};
+
+static
+DGAFunctionRec CHIPS_MMIODGAFuncs = {
+ CHIPS_OpenFramebuffer,
+ NULL,
+ CHIPS_SetMode,
+ CHIPS_SetViewport,
+ CHIPS_GetViewport,
+ CHIPSMMIOSync,
+ CHIPS_FillRect,
+ CHIPS_BlitRect,
+#if 0
+ CHIPS_BlitTransRect
+#else
+ NULL
+#endif
+};
+
+static
+DGAFunctionRec CHIPS_HiQVDGAFuncs = {
+ CHIPS_OpenFramebuffer,
+ NULL,
+ CHIPS_SetMode,
+ CHIPS_SetViewport,
+ CHIPS_GetViewport,
+ CHIPSHiQVSync,
+ CHIPS_FillRect,
+ CHIPS_BlitRect,
+#if 0
+ CHIPS_BlitTransRect
+#else
+ NULL
+#endif
+};
+
+
+Bool
+CHIPSDGAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ DGAModePtr modes = NULL, newmodes = NULL, currentMode;
+ DisplayModePtr pMode, firstMode;
+ int Bpp = pScrn->bitsPerPixel >> 3;
+ int num = 0;
+ Bool oneMore;
+
+ pMode = firstMode = pScrn->modes;
+
+ while(pMode) {
+
+ if(0 /*pScrn->displayWidth != pMode->HDisplay*/) {
+ newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec));
+ oneMore = TRUE;
+ } else {
+ newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec));
+ oneMore = FALSE;
+ }
+
+ if(!newmodes) {
+ xfree(modes);
+ return FALSE;
+ }
+ modes = newmodes;
+
+SECOND_PASS:
+
+ currentMode = modes + num;
+ num++;
+
+ currentMode->mode = pMode;
+ currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
+ if(cPtr->Flags & ChipsAccelSupport)
+ currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
+ if(pMode->Flags & V_DBLSCAN)
+ currentMode->flags |= DGA_DOUBLESCAN;
+ if(pMode->Flags & V_INTERLACE)
+ currentMode->flags |= DGA_INTERLACED;
+ currentMode->byteOrder = pScrn->imageByteOrder;
+ currentMode->depth = pScrn->depth;
+ currentMode->bitsPerPixel = pScrn->bitsPerPixel;
+ currentMode->red_mask = pScrn->mask.red;
+ currentMode->green_mask = pScrn->mask.green;
+ currentMode->blue_mask = pScrn->mask.blue;
+ currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor;
+ currentMode->viewportWidth = pMode->HDisplay;
+ currentMode->viewportHeight = pMode->VDisplay;
+ currentMode->xViewportStep = 1;
+ currentMode->yViewportStep = 1;
+ currentMode->viewportFlags = DGA_FLIP_RETRACE;
+ currentMode->offset = 0;
+ currentMode->address = cPtr->FbBase;
+
+ if(oneMore) { /* first one is narrow width */
+ currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L;
+ currentMode->imageWidth = pMode->HDisplay;
+ currentMode->imageHeight = pMode->VDisplay;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+ oneMore = FALSE;
+ goto SECOND_PASS;
+ } else {
+ currentMode->bytesPerScanline =
+ ((pScrn->displayWidth * Bpp) + 3) & ~3L;
+ currentMode->imageWidth = pScrn->displayWidth;
+ currentMode->imageHeight = pMode->VDisplay;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+ }
+
+ pMode = pMode->next;
+ if(pMode == firstMode)
+ break;
+ }
+
+ cPtr->numDGAModes = num;
+ cPtr->DGAModes = modes;
+
+ if (IS_HiQV(cPtr)) {
+ return DGAInit(pScreen, &CHIPS_HiQVDGAFuncs, modes, num);
+ } else {
+ if(!cPtr->UseMMIO) {
+ return DGAInit(pScreen, &CHIPS_DGAFuncs, modes, num);
+ } else {
+ return DGAInit(pScreen, &CHIPS_MMIODGAFuncs, modes, num);
+ }
+ }
+}
+
+
+static Bool
+CHIPS_SetMode(
+ ScrnInfoPtr pScrn,
+ DGAModePtr pMode
+){
+ static int OldDisplayWidth[MAXSCREENS];
+ int index = pScrn->pScreen->myNum;
+
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ if(!pMode) { /* restore the original mode */
+ /* put the ScreenParameters back */
+
+ pScrn->displayWidth = OldDisplayWidth[index];
+
+ CHIPSSwitchMode(index, pScrn->currentMode, 0);
+ cPtr->DGAactive = FALSE;
+ } else {
+ if(!cPtr->DGAactive) { /* save the old parameters */
+ OldDisplayWidth[index] = pScrn->displayWidth;
+
+ cPtr->DGAactive = TRUE;
+ }
+
+ pScrn->displayWidth = pMode->bytesPerScanline /
+ (pMode->bitsPerPixel >> 3);
+
+ CHIPSSwitchMode(index, pMode->mode, 0);
+ }
+
+ return TRUE;
+}
+
+
+
+static int
+CHIPS_GetViewport(
+ ScrnInfoPtr pScrn
+){
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ return cPtr->DGAViewportStatus;
+}
+
+static void
+CHIPS_SetViewport(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int flags
+){
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ CHIPSAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
+ cPtr->DGAViewportStatus = 0; /* CHIPSAdjustFrame loops until finished */
+}
+
+static void
+CHIPS_FillRect (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned long color
+){
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ if(cPtr->AccelInfoRec) {
+ (*cPtr->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
+ (*cPtr->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ SET_SYNC_FLAG(cPtr->AccelInfoRec);
+ }
+}
+
+static void
+CHIPS_BlitRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty
+){
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ if(cPtr->AccelInfoRec) {
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ (*cPtr->AccelInfoRec->SetupForScreenToScreenCopy)(
+ pScrn, xdir, ydir, GXcopy, ~0, -1);
+ (*cPtr->AccelInfoRec->SubsequentScreenToScreenCopy)(
+ pScrn, srcx, srcy, dstx, dsty, w, h);
+ SET_SYNC_FLAG(cPtr->AccelInfoRec);
+ }
+}
+
+
+static void
+CHIPS_BlitTransRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty,
+ unsigned long color
+){
+ /* this one should be separate since the XAA function would
+ prohibit usage of ~0 as the key */
+}
+
+
+static Bool
+CHIPS_OpenFramebuffer(
+ ScrnInfoPtr pScrn,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *flags
+){
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ *name = NULL; /* no special device */
+ *mem = (unsigned char*)cPtr->FbAddress;
+ *size = cPtr->FbMapSize;
+ *offset = 0;
+ *flags = DGA_NEED_ROOT;
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.c
new file mode 100644
index 000000000..8964317b1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.c
@@ -0,0 +1,6229 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.c,v 1.66 1999/08/30 14:36:22 dawes Exp $ */
+
+/*
+ * Copyright 1993 by Jon Block <block@frc.com>
+ * Modified by Mike Hollick <hollick@graphics.cis.upenn.edu>
+ * Modified 1994 by Régis Cridlig <cridlig@dmi.ens.fr>
+ *
+ * Major Contributors to XFree86 3.2
+ * Modified 1995/6 by Nozomi Ytow
+ * Modified 1996 by Egbert Eich <Egbert.Eich@Physik.TH-Darmstadt.DE>
+ * Modified 1996 by David Bateman <dbateman@ee.uts.edu.au>
+ * Modified 1996 by Xavier Ducoin <xavier@rd.lectra.fr>
+ *
+ * Contributors to XFree86 3.2
+ * Modified 1995/6 by Ken Raeburn <raeburn@raeburn.org>
+ * Modified 1996 by Shigehiro Nomura <nomura@sm.sony.co.jp>
+ * Modified 1996 by Marc de Courville <courvill@sig.enst.fr>
+ * Modified 1996 by Adam Sulmicki <adam@cfar.umd.edu>
+ * Modified 1996 by Jens Maurer <jmaurer@cck.uni-kl.de>
+ *
+ * Large parts rewritten for XFree86 4.0
+ * Modified 1998 by David Bateman <dbateman@eng.uts.edu.au>
+ * Modified 1998 by Egbert Eich <Egbert.Eich@Physik.TH-Darmstadt.DE>
+ * Modified 1998 by Nozomi Ytow
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Copyright 1997
+ * Digital Equipment Corporation. All rights reserved.
+ * This software is furnished under license and may be used and copied only in
+ * accordance with the following terms and conditions. Subject to these
+ * conditions, you may download, copy, install, use, modify and distribute
+ * this software in source and/or binary form. No title or ownership is
+ * transferred hereby.
+ * 1) Any source code used, modified or distributed must reproduce and retain
+ * this copyright notice and list of conditions as they appear in the
+ * source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or logo of Digital
+ * Equipment Corporation. Neither the "Digital Equipment Corporation" name
+ * nor any trademark or logo of Digital Equipment Corporation may be used
+ * to endorse or promote products derived from this software without the
+ * prior written permission of Digital Equipment Corporation.
+ *
+ * 3) This software is provided "AS-IS" and any express or implied warranties,
+ * including but not limited to, any implied warranties of merchantability,
+ * fitness for a particular purpose, or non-infringement are disclaimed. In
+ * no event shall DIGITAL be liable for any damages whatsoever, and in
+ * particular, DIGITAL shall not be liable for special, indirect,
+ * consequential, or incidental damages or damages for lost profits, loss
+ * of revenue or loss of use, whether such damages arise in contract,
+ * negligence, tort, under statute, in equity, at law or otherwise, even if
+ * advised of the possibility of such damage.
+ */
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.h"
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* This is used for module versioning */
+#include "xf86Version.h"
+
+/* Standard resources are defined here */
+#include "xf86Resources.h"
+
+/* All drivers using the vgahw module need this */
+#include "vgaHW.h"
+
+/* All drivers initialising the SW cursor need this */
+#include "mipointer.h"
+
+/* All drivers implementing backing store need this */
+#include "mibstore.h"
+
+/* All drivers using the mi banking wrapper need this */
+#include "mibank.h"
+
+/* All drivers using the mi colormap manipulation need this */
+#include "micmap.h"
+
+/* If using cfb, cfb.h is required. */
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+#include "cfb24_32.h"
+#include "cfb8_16.h"
+
+/* Needed for the 1 and 4 bpp framebuffers */
+#include "xf1bpp.h"
+#include "xf4bpp.h"
+
+/* Needed by Resources Access Control (RAC) */
+#include "xf86RAC.h"
+
+/* Needed by the Shadow Framebuffer */
+#include "shadowfb.h"
+
+/* Needed for replacement LoadPalette function for Gamma Correction */
+#include "xf86cmap.h"
+
+/* Driver specific headers */
+#include "ct_driver.h"
+
+/* Mandatory functions */
+static void CHIPSIdentify(int flags);
+static Bool CHIPSProbe(DriverPtr drv, int flags);
+static Bool CHIPSPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool CHIPSScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool CHIPSEnterVT(int scrnIndex, int flags);
+static void CHIPSLeaveVT(int scrnIndex, int flags);
+static Bool CHIPSCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static void CHIPSFreeScreen(int scrnIndex, int flags);
+static int CHIPSValidMode(int scrnIndex, DisplayModePtr mode,
+ Bool verbose, int flags);
+static Bool CHIPSSaveScreen(ScreenPtr pScreen, Bool unblank);
+
+/* Internally used functions */
+static int chipsFindIsaDevice(GDevPtr dev);
+static Bool chipsClockSelect(ScrnInfoPtr pScrn, int no);
+static Bool chipsModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static void chipsSave(ScrnInfoPtr pScrn);
+static void chipsRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg,
+ CHIPSRegPtr ChipsReg, Bool restoreFonts);
+static void chipsLock(ScrnInfoPtr pScrn);
+static void chipsUnlock(ScrnInfoPtr pScrn);
+static void chipsClockSave(ScrnInfoPtr pScrn, CHIPSClockPtr Clock);
+static void chipsClockLoad(ScrnInfoPtr pScrn, CHIPSClockPtr Clock);
+static Bool chipsClockFind(ScrnInfoPtr pScrn, int no, CHIPSClockPtr Clock);
+static void chipsCalcClock(ScrnInfoPtr pScrn, int Clock,
+ unsigned char *vclk);
+static int chipsGetHWClock(ScrnInfoPtr pScrn);
+static Bool chipsPreInit655xx(ScrnInfoPtr pScrn, int flags);
+static Bool chipsPreInitHiQV(ScrnInfoPtr pScrn, int flags);
+static Bool chipsPreInitWingine(ScrnInfoPtr pScrn, int flags);
+static int chipsSetMonitor(ScrnInfoPtr pScrn);
+static Bool chipsMapMem(ScrnInfoPtr pScrn);
+static Bool chipsUnmapMem(ScrnInfoPtr pScrn);
+static void chipsProtect(ScrnInfoPtr pScrn, Bool on);
+static void chipsBlankScreen(ScrnInfoPtr pScrn, Bool unblank);
+static void chipsRestoreExtendedRegs(ScrnInfoPtr pScrn, CHIPSRegPtr Regs);
+static void chipsRestoreStretching(ScrnInfoPtr pScrn,
+ unsigned char ctHorizontalStretch,
+ unsigned char ctVerticalStretch);
+static Bool chipsModeInitHiQV(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static Bool chipsModeInitWingine(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static Bool chipsModeInit655xx(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static int chipsVideoMode(int vgaBitsPerPixel, int weightGreen,
+ int displayHSize, int displayVSize);
+static void chipsDisplayPowerManagementSet(ScrnInfoPtr pScrn,
+ int PowerManagementMode, int flags);
+static void chipsHWCursorOn(CHIPSPtr cPtr);
+static void chipsHWCursorOff(CHIPSPtr cPtr);
+static void chipsFixResume(ScrnInfoPtr pScrn);
+static void chipsRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+static void chipsLoadPalette(ScrnInfoPtr pScrn, int numColors,
+ int *indices, LOCO *colors, VisualPtr pVisual);
+static void chipsLoadPalette16(ScrnInfoPtr pScrn, int numColors,
+ int *indices, LOCO *colors, VisualPtr pVisual);
+
+/*
+ * This is intentionally screen-independent. It indicates the binding
+ * choice made in the first PreInit.
+ */
+static int pix24bpp = 0;
+
+/*
+ * Initialise some arrays that are used in multiple instances of the
+ * acceleration code. Set them up here as its a convenient place to do it.
+ */
+/* alu to C&T conversion for use with source data */
+int ChipsAluConv[] =
+{
+ 0x00, /* dest = 0; GXclear, 0 */
+ 0x88, /* dest &= src; GXand, 0x1 */
+ 0x44, /* dest = src & ~dest; GXandReverse, 0x2 */
+ 0xCC, /* dest = src; GXcopy, 0x3 */
+ 0x22, /* dest &= ~src; GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; GXnoop, 0x5 */
+ 0x66, /* dest = ^src; GXxor, 0x6 */
+ 0xEE, /* dest |= src; GXor, 0x7 */
+ 0x11, /* dest = ~src & ~dest;GXnor, 0x8 */
+ 0x99, /* dest ^= ~src ;GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; GXInvert, 0xA */
+ 0xDD, /* dest = src|~dest ;GXorReverse, 0xB */
+ 0x33, /* dest = ~src; GXcopyInverted, 0xC */
+ 0xBB, /* dest |= ~src; GXorInverted, 0xD */
+ 0x77, /* dest = ~src|~dest ;GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; GXset, 0xF */
+};
+
+/* alu to C&T conversion for use with pattern data */
+int ChipsAluConv2[] =
+{
+ 0x00, /* dest = 0; GXclear, 0 */
+ 0xA0, /* dest &= src; GXand, 0x1 */
+ 0x50, /* dest = src & ~dest; GXandReverse, 0x2 */
+ 0xF0, /* dest = src; GXcopy, 0x3 */
+ 0x0A, /* dest &= ~src; GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; GXnoop, 0x5 */
+ 0x5A, /* dest = ^src; GXxor, 0x6 */
+ 0xFA, /* dest |= src; GXor, 0x7 */
+ 0x05, /* dest = ~src & ~dest;GXnor, 0x8 */
+ 0xA5, /* dest ^= ~src ;GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; GXInvert, 0xA */
+ 0xF5, /* dest = src|~dest ;GXorReverse, 0xB */
+ 0x0F, /* dest = ~src; GXcopyInverted, 0xC */
+ 0xAF, /* dest |= ~src; GXorInverted, 0xD */
+ 0x5F, /* dest = ~src|~dest ;GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; GXset, 0xF */
+};
+
+/* alu to C&T conversion for use with pattern data as a planemask */
+int ChipsAluConv3[] =
+{
+ 0x0A, /* dest = 0; GXclear, 0 */
+ 0x8A, /* dest &= src; GXand, 0x1 */
+ 0x4A, /* dest = src & ~dest; GXandReverse, 0x2 */
+ 0xCA, /* dest = src; GXcopy, 0x3 */
+ 0x2A, /* dest &= ~src; GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; GXnoop, 0x5 */
+ 0x6A, /* dest = ^src; GXxor, 0x6 */
+ 0xEA, /* dest |= src; GXor, 0x7 */
+ 0x1A, /* dest = ~src & ~dest;GXnor, 0x8 */
+ 0x9A, /* dest ^= ~src ;GXequiv, 0x9 */
+ 0x5A, /* dest = ~dest; GXInvert, 0xA */
+ 0xDA, /* dest = src|~dest ;GXorReverse, 0xB */
+ 0x3A, /* dest = ~src; GXcopyInverted, 0xC */
+ 0xBA, /* dest |= ~src; GXorInverted, 0xD */
+ 0x7A, /* dest = ~src|~dest ;GXnand, 0xE */
+ 0xFA, /* dest = 0xFF; GXset, 0xF */
+};
+
+/* The addresses of the acceleration registers */
+unsigned int ChipsReg32HiQV[] =
+{
+ 0x00, /* BR00 Source and Destination offset register */
+ 0x04, /* BR01 Color expansion background color */
+ 0x08, /* BR02 Color expansion foreground color */
+ 0x0C, /* BR03 Monochrome source control register */
+ 0x10, /* BR04 BitBLT control register */
+ 0x14, /* BR05 Pattern address register */
+ 0x18, /* BR06 Source address register */
+ 0x1C, /* BR07 Destination address register */
+ 0x20 /* BR08 Destination width and height register */
+};
+
+unsigned int ChipsReg32[] =
+{
+ /*BitBLT */
+ 0x83D0, /*DR0 src/dest offset */
+ 0x87D0, /*DR1 BitBlt. address of freeVram? */
+ 0x8BD0, /*DR2 BitBlt. paintBrush, or tile pat.*/
+ 0x8FD0, /*DR3 */
+ 0x93D0, /*DR4 BitBlt. */
+ 0x97D0, /*DR5 BitBlt. srcAddr, or 0 in VRAM */
+ 0x9BD0, /*DR6 BitBlt. dest? */
+ 0x9FD0, /*DR7 BitBlt. width << 16 | height */
+ /*H/W cursor */
+ 0xA3D0, /*DR8 write/erase cursor */
+ /*bit 0-1 if 0 cursor is not shown
+ * if 1 32x32 cursor
+ * if 2 64x64 cursor
+ * if 3 128x128 cursor
+ */
+ /* bit 7 if 1 cursor is not shown */
+ /* bit 9 cursor expansion in X */
+ /* bit 10 cursor expansion in Y */
+ 0xA7D0, /* DR9 foreGroundCursorColor */
+ 0xABD0, /* DR0xA backGroundCursorColor */
+ 0xAFD0, /* DR0xB cursorPosition */
+ /* bit 0-7 x coordinate */
+ /* bit 8-14 0 */
+ /* bit 15 x signum */
+ /* bit 16-23 y coordinate */
+ /* bit 24-30 0 */
+ /* bit 31 y signum */
+ 0xB3D0, /* DR0xC address of cursor pattern */
+};
+
+#if defined(__arm32__) && defined(__NetBSD__)
+/*
+ * Built in TV output modes: These modes have been tested on NetBSD with
+ * CT65550 and StrongARM. They give what seems to be the best output for
+ * a roughly 640x480 display. To enable one of the built in modes, add
+ * the identifier "NTSC" or "PAL" to the list of modes in the appropriate
+ * "Display" subsection of the "Screen" section in the XF86Config file.
+ * Note that the call to xf86SetTVOut(), which tells the kernel to enable
+ * TV output results in hardware specific actions. There must be code to
+ * support this in the kernel or TV output won't work.
+ */
+static DisplayModeRec ChipsPALMode = {
+ NULL, NULL, /* prev, next */
+ "PAL", /* identifier of this mode */
+ MODE_OK, /* mode status */
+ M_T_BUILTIN, /* mode type */
+ 15000, /* Clock frequency */
+ 776, /* HDisplay */
+ 800, /* HSyncStart */
+ 872, /* HSyncEnd */
+ 960, /* HTotal */
+ 0, /* HSkew */
+ 585, /* VDisplay */
+ 590, /* VSyncStart */
+ 595, /* VSyncEnd */
+ 625, /* VTotal */
+ 0, /* VScan */
+ V_INTERLACE, /* Flags */
+ -1, /* ClockIndex */
+ 15000, /* SynthClock */
+ 776, /* CRTC HDisplay */
+ 800, /* CRTC HBlankStart */
+ 800, /* CRTC HSyncStart */
+ 872, /* CRTC HSyncEnd */
+ 872, /* CRTC HBlankEnd */
+ 960, /* CRTC HTotal */
+ 0, /* CRTC HSkew */
+ 585, /* CRTC VDisplay */
+ 590, /* CRTC VBlankStart */
+ 590, /* CRTC VSyncStart */
+ 595, /* CRTC VSyncEnd */
+ 595, /* CRTC VBlankEnd */
+ 625, /* CRTC VTotal */
+ FALSE, /* CrtcHAdjusted */
+ FALSE, /* CrtcVAdjusted */
+ 0, /* PrivSize */
+ NULL /* Private */
+};
+
+/*
+** So far, it looks like SECAM uses the same values as PAL
+*/
+static DisplayModeRec ChipsSECAMMode = {
+ NULL, /* prev */
+ &ChipsPALMode, /* next */
+ "SECAM", /* identifier of this mode */
+ MODE_OK, /* mode status */
+ M_T_BUILTIN, /* mode type */
+ 15000, /* Clock frequency */
+ 776, /* HDisplay */
+ 800, /* HSyncStart */
+ 872, /* HSyncEnd */
+ 960, /* HTotal */
+ 0, /* HSkew */
+ 585, /* VDisplay */
+ 590, /* VSyncStart */
+ 595, /* VSyncEnd */
+ 625, /* VTotal */
+ 0, /* VScan */
+ V_INTERLACE, /* Flags */
+ -1, /* ClockIndex */
+ 15000, /* SynthClock */
+ 776, /* CRTC HDisplay */
+ 800, /* CRTC HBlankStart */
+ 800, /* CRTC HSyncStart */
+ 872, /* CRTC HSyncEnd */
+ 872, /* CRTC HBlankEnd */
+ 960, /* CRTC HTotal */
+ 0, /* CRTC HSkew */
+ 585, /* CRTC VDisplay */
+ 590, /* CRTC VBlankStart */
+ 590, /* CRTC VSyncStart */
+ 595, /* CRTC VSyncEnd */
+ 595, /* CRTC VBlankEnd */
+ 625, /* CRTC VTotal */
+ FALSE, /* CrtcHAdjusted */
+ FALSE, /* CrtcVAdjusted */
+ 0, /* PrivSize */
+ NULL /* Private */
+};
+
+
+static DisplayModeRec ChipsNTSCMode = {
+ NULL, /* prev */
+ &ChipsSECAMMode,/* next */
+ "NTSC", /* identifier of this mode */
+ MODE_OK, /* mode status */
+ M_T_BUILTIN, /* mode type */
+ 11970, /* Clock frequency */
+ 584, /* HDisplay */
+ 640, /* HSyncStart */
+ 696, /* HSyncEnd */
+ 760, /* HTotal */
+ 0, /* HSkew */
+ 450, /* VDisplay */
+ 479, /* VSyncStart */
+ 485, /* VSyncEnd */
+ 525, /* VTotal */
+ 0, /* VScan */
+ V_INTERLACE | V_NVSYNC | V_NHSYNC , /* Flags */
+ -1, /* ClockIndex */
+ 11970, /* SynthClock */
+ 584, /* CRTC HDisplay */
+ 640, /* CRTC HBlankStart */
+ 640, /* CRTC HSyncStart */
+ 696, /* CRTC HSyncEnd */
+ 696, /* CRTC HBlankEnd */
+ 760, /* CRTC HTotal */
+ 0, /* CRTC HSkew */
+ 450, /* CRTC VDisplay */
+ 479, /* CRTC VBlankStart */
+ 479, /* CRTC VSyncStart */
+ 485, /* CRTC VSyncEnd */
+ 485, /* CRTC VBlankEnd */
+ 525, /* CRTC VTotal */
+ FALSE, /* CrtcHAdjusted */
+ FALSE, /* CrtcVAdjusted */
+ 0, /* PrivSize */
+ NULL /* Private */
+};
+#endif
+
+#define VERSION 4000
+#define CHIPS_NAME "CHIPS"
+#define CHIPS_DRIVER_NAME "chips"
+#define CHIPS_MAJOR_VERSION 1
+#define CHIPS_MINOR_VERSION 0
+#define CHIPS_PATCHLEVEL 0
+
+/*
+ * This contains the functions needed by the server after loading the driver
+ * module. It must be supplied, and gets passed back by the SetupProc
+ * function in the dynamic case. In the static case, a reference to this
+ * is compiled in, and this requires that the name of this DriverRec be
+ * an upper-case version of the driver name.
+ */
+
+DriverRec CHIPS = {
+ VERSION,
+ "Driver for the Chips and Technologies chipsets",
+ CHIPSIdentify,
+ CHIPSProbe,
+ NULL,
+ 0
+};
+
+static SymTabRec CHIPSChipsets[] = {
+ { CHIPS_CT65520, "ct65520" },
+ { CHIPS_CT65525, "ct65525" },
+ { CHIPS_CT65530, "ct65530" },
+ { CHIPS_CT65535, "ct65535" },
+ { CHIPS_CT65540, "ct65540" },
+ { CHIPS_CT65545, "ct65545" },
+ { CHIPS_CT65546, "ct65546" },
+ { CHIPS_CT65548, "ct65548" },
+ { CHIPS_CT65550, "ct65550" },
+ { CHIPS_CT65554, "ct65554" },
+ { CHIPS_CT65555, "ct65555" },
+ { CHIPS_CT68554, "ct68554" },
+ { CHIPS_CT69000, "ct69000" },
+ { CHIPS_CT69030, "ct69030" },
+ { CHIPS_CT64200, "ct64200" },
+ { CHIPS_CT64300, "ct64300" },
+ { -1, NULL }
+};
+
+/* Conversion PCI ID to chipset name */
+static PciChipsets CHIPSPCIchipsets[] = {
+ { CHIPS_CT65545, PCI_CHIP_65545, RES_SHARED_VGA },
+ { CHIPS_CT65548, PCI_CHIP_65548, RES_SHARED_VGA },
+ { CHIPS_CT65550, PCI_CHIP_65550, RES_SHARED_VGA },
+ { CHIPS_CT65554, PCI_CHIP_65554, RES_SHARED_VGA },
+ { CHIPS_CT65555, PCI_CHIP_65555, RES_SHARED_VGA },
+ { CHIPS_CT68554, PCI_CHIP_68554, RES_SHARED_VGA },
+ { CHIPS_CT69000, PCI_CHIP_69000, RES_SHARED_VGA },
+ { CHIPS_CT69030, PCI_CHIP_69030, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED}
+};
+
+static IsaChipsets CHIPSISAchipsets[] = {
+ { CHIPS_CT65520, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65525, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65530, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65535, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65540, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65545, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65546, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65548, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65550, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65554, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT65555, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT68554, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT69000, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT69030, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT64200, RES_EXCLUSIVE_VGA },
+ { CHIPS_CT64300, RES_EXCLUSIVE_VGA },
+ { -1, RES_UNDEFINED }
+};
+
+/* The options supported by the Chips and Technologies Driver */
+typedef enum {
+ OPTION_LINEAR,
+ OPTION_NOACCEL,
+ OPTION_HW_CLKS,
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+ OPTION_STN,
+ OPTION_USE_MODELINE,
+ OPTION_LCD_STRETCH,
+ OPTION_LCD_CENTER,
+ OPTION_MMIO,
+ OPTION_SUSPEND_HACK,
+ OPTION_RGB_BITS,
+ OPTION_SYNC_ON_GREEN,
+ OPTION_PANEL_SIZE,
+ OPTION_18_BIT_BUS,
+ OPTION_SHOWCACHE,
+ OPTION_SHADOW_FB,
+ OPTION_OVERLAY,
+ OPTION_COLOR_KEY,
+ OPTION_FP_CLOCK_8,
+ OPTION_FP_CLOCK_16,
+ OPTION_FP_CLOCK_24,
+ OPTION_FP_CLOCK_32,
+ OPTION_SET_MCLK
+} CHIPSOpts;
+
+static OptionInfoRec Chips655xxOptions[] = {
+ { OPTION_LINEAR, "Linear", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CLKS, "HWclocks", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_STN, "STN", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_USE_MODELINE, "UseModeline", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_LCD_STRETCH, "NoStretch", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_LCD_CENTER, "LcdCenter", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_MMIO, "MMIO", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SUSPEND_HACK, "SuspendHack", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PANEL_SIZE, "FixPanelSize", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_RGB_BITS, "RGBbits", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_18_BIT_BUS, "18BitBus", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+static OptionInfoRec ChipsWingineOptions[] = {
+ { OPTION_LINEAR, "Linear", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CLKS, "HWclocks", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_RGB_BITS, "RGBbits", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+static OptionInfoRec ChipsHiQVOptions[] = {
+ { OPTION_LINEAR, "Linear", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_STN, "STN", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_USE_MODELINE, "UseModeline", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_LCD_STRETCH, "NoStretch", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_LCD_CENTER, "LcdCenter", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_MMIO, "MMIO", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SUSPEND_HACK, "SuspendHack", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PANEL_SIZE, "FixPanelSize", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_RGB_BITS, "RGBbits", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_SYNC_ON_GREEN, "SyncOnGreen", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_OVERLAY, "Overlay", OPTV_ANYSTR, {0}, FALSE },
+ { OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_FP_CLOCK_8, "FPClock8", OPTV_FREQ, {0}, FALSE },
+ { OPTION_FP_CLOCK_16, "FPClock16", OPTV_FREQ, {0}, FALSE },
+ { OPTION_FP_CLOCK_24, "FPClock24", OPTV_FREQ, {0}, FALSE },
+ { OPTION_FP_CLOCK_32, "FPClock32", OPTV_FREQ, {0}, FALSE },
+ { OPTION_SET_MCLK, "SetMclk", OPTV_FREQ, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+/*
+ * List of symbols from other modules that this module references. This
+ * list is used to tell the loader that it is OK for symbols here to be
+ * unresolved providing that it hasn't been told that they haven't been
+ * told that they are essential via a call to xf86LoaderReqSymbols() or
+ * xf86LoaderReqSymLists(). The purpose is this is to avoid warnings about
+ * unresolved symbols that are not required.
+ */
+
+static const char *vgahwSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWUnlock",
+ "vgaHWInit",
+ "vgaHWProtect",
+ "vgaHWGetIOBase",
+ "vgaHWMapMem",
+ "vgaHWLock",
+ "vgaHWFreeHWRec",
+ "vgaHWSaveScreen",
+ NULL
+};
+
+static const char *cfbSymbols[] = {
+ "xf1bppScreenInit",
+ "xf4bppScreenInit",
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb8_16ScreenInit",
+ "cfb24ScreenInit",
+ "cfb24_32ScreenInit",
+ "cfb32ScreenInit",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAADestroyInfoRec",
+ "XAACreateInfoRec",
+ "XAAInit",
+ "XAAStippleScanlineFuncMSBFirst",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86InitCursor",
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ NULL
+};
+
+static const char *ddcSymbols[] = {
+ "xf86PrintEDID",
+ "xf86DoEDID_DDC1",
+ "xf86DoEDID_DDC2",
+ NULL
+};
+
+static const char *i2cSymbols[] = {
+ "xf86CreateI2CBusRec",
+ "xf86I2CBusInit",
+ "xf86I2CProbeAddress",
+ "xf86I2CFindBus",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(chipsSetup);
+
+static XF86ModuleVersionInfo chipsVersRec =
+{
+ "chips",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ CHIPS_MAJOR_VERSION, CHIPS_MINOR_VERSION, CHIPS_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+/*
+ * This is the module init data.
+ * Its name has to be the driver name followed by ModuleData
+ */
+XF86ModuleData chipsModuleData = { &chipsVersRec, chipsSetup, NULL };
+
+static pointer
+chipsSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&CHIPS, module, 0);
+
+ /*
+ * Modules that this driver always requires can be loaded here
+ * by calling LoadSubModule().
+ */
+
+ /*
+ * Tell the loader about symbols from other modules that this module
+ * might refer to.
+ */
+ LoaderRefSymLists(vgahwSymbols, cfbSymbols, xaaSymbols,
+ ramdacSymbols, ddcSymbols, i2cSymbols,
+ shadowSymbols, NULL);
+
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer)1;
+ } else {
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+#endif /* XFree86LOADER */
+
+static Bool
+CHIPSGetRec(ScrnInfoPtr pScrn)
+{
+ /*
+ * Allocate a CHIPSRec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(CHIPSRec), 1);
+
+ if (pScrn->driverPrivate == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+CHIPSFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+/* Mandatory */
+static void
+CHIPSIdentify(int flags)
+{
+ xf86PrintChipsets(CHIPS_NAME, "Driver for Chips and Technologies chipsets",
+ CHIPSChipsets);
+}
+
+/* Mandatory */
+static Bool
+CHIPSProbe(DriverPtr drv, int flags)
+{
+ Bool foundScreen = FALSE;
+ int numDevSections, numUsed;
+ GDevPtr *devSections;
+ int *usedChips;
+ int i;
+
+ /*
+ * Find the config file Device sections that match this
+ * driver, and return if there are none.
+ */
+ if ((numDevSections = xf86MatchDevice(CHIPS_DRIVER_NAME,
+ &devSections)) <= 0) {
+ return FALSE;
+ }
+ /* PCI BUS */
+ if (xf86GetPciVideoInfo() ) {
+ numUsed = xf86MatchPciInstances(CHIPS_NAME, PCI_VENDOR_CHIPSTECH,
+ CHIPSChipsets, CHIPSPCIchipsets,
+ devSections,numDevSections, drv,
+ &usedChips);
+ if (numUsed > 0) {
+ for (i = 0; i < numUsed; i++) {
+ /* Allocate a ScrnInfoRec */
+ ScrnInfoPtr pScrn = xf86AllocateScreen(drv,0);
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = CHIPS_DRIVER_NAME;
+ pScrn->name = CHIPS_NAME;
+ pScrn->Probe = CHIPSProbe;
+ pScrn->PreInit = CHIPSPreInit;
+ pScrn->ScreenInit = CHIPSScreenInit;
+ pScrn->SwitchMode = CHIPSSwitchMode;
+ pScrn->AdjustFrame = CHIPSAdjustFrame;
+ pScrn->EnterVT = CHIPSEnterVT;
+ pScrn->LeaveVT = CHIPSLeaveVT;
+ pScrn->FreeScreen = CHIPSFreeScreen;
+ pScrn->ValidMode = CHIPSValidMode;
+ foundScreen = TRUE;
+ xf86ConfigActivePciEntity(pScrn,usedChips[i],CHIPSPCIchipsets,
+ NULL,NULL,NULL,NULL,NULL);
+ }
+ }
+ }
+
+ /* Isa Bus */
+ numUsed = xf86MatchIsaInstances(CHIPS_NAME,CHIPSChipsets,CHIPSISAchipsets,
+ drv,chipsFindIsaDevice,devSections,
+ numDevSections,&usedChips);
+ if(numUsed >= 0)
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = xf86AllocateScreen(drv,0);
+
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = CHIPS_DRIVER_NAME;
+ pScrn->name = CHIPS_NAME;
+ pScrn->Probe = CHIPSProbe;
+ pScrn->PreInit = CHIPSPreInit;
+ pScrn->ScreenInit = CHIPSScreenInit;
+ pScrn->SwitchMode = CHIPSSwitchMode;
+ pScrn->AdjustFrame = CHIPSAdjustFrame;
+ pScrn->EnterVT = CHIPSEnterVT;
+ pScrn->LeaveVT = CHIPSLeaveVT;
+ pScrn->FreeScreen = CHIPSFreeScreen;
+ pScrn->ValidMode = CHIPSValidMode;
+ foundScreen = TRUE;
+ xf86ConfigActiveIsaEntity(pScrn,usedChips[i],CHIPSISAchipsets,
+ NULL,NULL,NULL,NULL,NULL);
+ }
+ xfree(devSections);
+ return foundScreen;
+}
+
+static int
+chipsFindIsaDevice(GDevPtr dev)
+{
+ int found = -1;
+ unsigned char tmp;
+
+ /*
+ * This function has the only direct register access in the C&T driver.
+ * All other register access through functions to allow for full MMIO.
+ */
+ outb(0x3D6, 0x00);
+ tmp = inb(0x3D7);
+
+ switch (tmp & 0xF0) {
+ case 0x70: /* CT65520 */
+ found = CHIPS_CT65520; break;
+ case 0x80: /* CT65525 or CT65530 */
+ found = CHIPS_CT65530; break;
+ case 0xA0: /* CT64200 */
+ found = CHIPS_CT64200; break;
+ case 0xB0: /* CT64300 */
+ found = CHIPS_CT64300; break;
+ case 0xC0: /* CT65535 */
+ found = CHIPS_CT65535; break;
+ default:
+ switch (tmp & 0xF8) {
+ case 0xD0: /* CT65540 */
+ found = CHIPS_CT65540; break;
+ case 0xD8: /* CT65545 or CT65546 or CT65548 */
+ switch (tmp & 7) {
+ case 3:
+ found = CHIPS_CT65546; break;
+ case 4:
+ found = CHIPS_CT65548; break;
+ default:
+ found = CHIPS_CT65545; break;
+
+ }
+ break;
+ default:
+ if (tmp == 0x2C) {
+ outb(0x3D6, 0x01);
+ tmp = inb(0x3D7);
+ if (tmp != 0x10) break;
+ outb(0x3D6, 0x02);
+ tmp = inb(0x3D7);
+ switch (tmp) {
+ case 0xE0: /* CT65550 */
+ found = CHIPS_CT65550; break;
+ case 0xE4: /* CT65554 */
+ found = CHIPS_CT65554; break;
+ case 0xE5: /* CT65555 */
+ found = CHIPS_CT65555; break;
+ case 0xF4: /* CT68554 */
+ found = CHIPS_CT68554; break;
+ case 0xC0: /* CT69000 */
+ found = CHIPS_CT69000; break;
+ case 0x30: /* CT69030 */
+ outb(0x3D6, 0x03);
+ tmp = inb(0x3D7);
+ if (tmp == 0xC)
+ found = CHIPS_CT69030;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ }
+ break;
+ }
+ /* We only want ISA/VL Bus - so check for PCI Bus */
+ if(found > CHIPS_CT65548) {
+ outb(0x3D6, 0x08);
+ tmp = inb(0x3D7);
+ if(tmp & 0x01) found = -1;
+ } else if(found > CHIPS_CT65535) {
+ outb(0x3D6, 0x01);
+ tmp = inb(0x3D7);
+ if ((tmp & 0x07) == 0x06) found = -1;
+ }
+ return found;
+}
+
+/* Mandatory */
+Bool
+CHIPSPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ pciVideoPtr pciPtr;
+ ClockRangePtr clockRanges;
+ char *mod = NULL;
+ int i;
+ CHIPSPtr cPtr;
+ const char *reqSym = NULL;
+
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ return FALSE;
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /* Allocate the ChipsRec driverPrivate */
+ if (!CHIPSGetRec(pScrn)) {
+ return FALSE;
+ }
+ cPtr = CHIPSPTR(pScrn);
+
+ /* Since the capabilities are determined by the chipset the very
+ * first thing to do is, figure out the chipset and its capabilities
+ */
+ /* This driver doesn't expect more than one entity per screen */
+ if (pScrn->numEntities > 1)
+ return FALSE;
+ /* This is the general case */
+ for (i = 0; i<pScrn->numEntities; i++) {
+ cPtr->pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
+ if (cPtr->pEnt->resources) return FALSE;
+ cPtr->Chipset = cPtr->pEnt->chipset;
+ pScrn->chipset = (char *)xf86TokenToString(CHIPSChipsets,
+ cPtr->pEnt->chipset);
+ if ((cPtr->Chipset == CHIPS_CT64200) ||
+ (cPtr->Chipset == CHIPS_CT64300)) cPtr->Flags |= ChipsWingine;
+ if ((cPtr->Chipset >= CHIPS_CT65550) &&
+ (cPtr->Chipset <= CHIPS_CT69030)) cPtr->Flags |= ChipsHiQV;
+
+ /* This driver can handle ISA and PCI buses */
+ if (cPtr->pEnt->location.type == BUS_PCI) {
+ pciPtr = xf86GetPciInfoForEntity(cPtr->pEnt->index);
+ cPtr->PciInfo = pciPtr;
+ cPtr->PciTag = pciTag(cPtr->PciInfo->bus,
+ cPtr->PciInfo->device,
+ cPtr->PciInfo->func);
+ }
+ }
+ /* Now that we've identified the chipset, setup the capabilities flags */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT69030:
+ case CHIPS_CT69000:
+ cPtr->Flags |= ChipsFullMMIOSupport;
+ /* Fall through */
+ case CHIPS_CT65555:
+ cPtr->Flags |= ChipsImageReadSupport; /* Does the 69000 support it? */
+ /* Fall through */
+ case CHIPS_CT68554:
+ cPtr->Flags |= ChipsTMEDSupport;
+ /* Fall through */
+ case CHIPS_CT65554:
+ case CHIPS_CT65550:
+ cPtr->Flags |= ChipsGammaSupport;
+ /* Fall through */
+ case CHIPS_CT65548:
+ case CHIPS_CT65546:
+ case CHIPS_CT65545:
+ cPtr->Flags |= ChipsMMIOSupport;
+ /* Fall through */
+ case CHIPS_CT64300:
+ cPtr->Flags |= ChipsAccelSupport;
+ /* Fall through */
+ case CHIPS_CT65540:
+ cPtr->Flags |= ChipsHDepthSupport;
+ cPtr->Flags |= ChipsDPMSSupport;
+ /* Fall through */
+ case CHIPS_CT65535:
+ case CHIPS_CT65530:
+ case CHIPS_CT65525:
+ cPtr->Flags |= ChipsLinearSupport;
+ /* Fall through */
+ case CHIPS_CT64200:
+ case CHIPS_CT65520:
+ break;
+ }
+ CHIPSSetStdExtFuncs(cPtr);
+ /* Call the device specific PreInit */
+ if (IS_HiQV(cPtr)) {
+ if (!chipsPreInitHiQV(pScrn, flags)) {
+ if (cPtr->UseFullMMIO)
+ chipsUnmapMem(pScrn);
+ return FALSE;
+ }
+ } else if (IS_Wingine(cPtr)) {
+ if (!chipsPreInitWingine(pScrn, flags)) {
+ if (cPtr->UseFullMMIO)
+ chipsUnmapMem(pScrn);
+ return FALSE;
+ }
+ } else {
+ if (!chipsPreInit655xx(pScrn, flags)) {
+ if (cPtr->UseFullMMIO)
+ chipsUnmapMem(pScrn);
+ return FALSE;
+ }
+ }
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+ clockRanges = xnfalloc(sizeof(ClockRange));
+ clockRanges->next = NULL;
+ clockRanges->ClockMulFactor = cPtr->ClockMulFactor;
+ clockRanges->minClock = cPtr->MinClock;
+ clockRanges->maxClock = cPtr->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ if (cPtr->PanelType & ChipsLCD)
+ clockRanges->interlaceAllowed = FALSE;
+ else
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = FALSE;
+
+ /*
+ * Reduce the amount of video ram for the modes, so that they
+ * don't overlap with the DSTN framebuffer
+ */
+ pScrn->videoRam -= (cPtr->FrameBufferSize + 1023) / 1024;
+
+ if (cPtr->Flags & ChipsAccelSupport) {
+ /*
+ * If we are using acceleration then we want a display pitch that is
+ * a multiple of 64 pixels. This allows for alignment issues for the
+ * 8x8 pattern fills. Try to widen the display pitch to 64 if necessary
+ */
+ cPtr->Rounding = 64 * (pScrn->bitsPerPixel <= 8 ? 8
+ : pScrn->bitsPerPixel);
+ /* 16 Kb cache for each bpp */
+ pScrn->videoRam -= 16 * (pScrn->bitsPerPixel >> 3);
+ } else {
+ cPtr->Rounding = 8;
+ if (pScrn->bitsPerPixel >= 8)
+ cPtr->Rounding *= (pScrn->bitsPerPixel >> 3);
+ }
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, 256, 2048, cPtr->Rounding,
+ 128, 2048, pScrn->display->virtualX,
+ pScrn->display->virtualY, cPtr->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+ /*
+ * If we are using accel and don't find any valid modes
+ * we might not have enough memory for a 64 bit rounding
+ * and 16 Kb per bpp cache. Let's try without it.
+ */
+ if (i < 1 && (cPtr->Flags & ChipsAccelSupport)) {
+ cPtr->Rounding = 8;
+ if (pScrn->bitsPerPixel >= 8)
+ cPtr->Rounding *= pScrn->bitsPerPixel;
+ pScrn->videoRam += 16 * (pScrn->bitsPerPixel >> 3);
+
+ /*
+ * If the modepool isn't empty, we'll need to delete it
+ * before revalidating the mode list
+ */
+ {
+ DisplayModePtr first, p, n;
+ p = pScrn->modes;
+ if ( p != NULL) {
+ do {
+ if (!(first = pScrn->modes))
+ break;
+ n = p->next;
+ xf86DeleteMode(&(pScrn->modes), p);
+ p = n;
+ } while (p != NULL && p != first);
+ }
+ pScrn->modePool = NULL;
+ }
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, 256, 2048, cPtr->Rounding,
+ 128, 2048, pScrn->display->virtualX,
+ pScrn->display->virtualY, cPtr->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+
+ if (i >= 1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "not enough free memory to adjust display pitch.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "some acceleration may be disabled.\n");
+ }
+ }
+ if (i == -1) {
+ if (cPtr->UseFullMMIO)
+ chipsUnmapMem(pScrn);
+ CHIPSFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /*
+ * Put the DSTN framebuffer back into the video ram
+ */
+ pScrn->videoRam += (cPtr->FrameBufferSize + 1023) / 1024;
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ if (cPtr->UseFullMMIO)
+ chipsUnmapMem(pScrn);
+ CHIPSFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /*
+ * Set the CRTC parameters for all of the modes based on the type
+ * of mode, and the chipset's interlace requirements.
+ *
+ * Calling this is required if the mode->Crtc* values are used by the
+ * driver and if the driver doesn't provide code to set them. They
+ * are not pre-initialised at all.
+ */
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* If monitor resolution is set on the command line, use it */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ mod = "xf1bpp";
+ reqSym = "xf1bppScreenInit";
+ break;
+ case 4:
+ mod = "xf4bpp";
+ reqSym = "xf4bppScreenInit";
+ break;
+ case 8:
+ mod = "cfb";
+ reqSym = "cfbScreenInit";
+ break;
+ case 16:
+ if (cPtr->Flags & ChipsOverlay8plus16) {
+ mod = "xf8_16bpp";
+ reqSym = "cfb8_16ScreenInit";
+ } else {
+ mod = "cfb16";
+ reqSym = "cfb16ScreenInit";
+ }
+ break;
+ case 24:
+ if (pix24bpp == 24) {
+ mod = "cfb24";
+ reqSym = "cfb24ScreenInit";
+ } else {
+ mod = "xf24_32bpp";
+ reqSym = "cfb24_32ScreenInit";
+ }
+ break;
+ case 32:
+ mod = "cfb32";
+ reqSym = "cfb32ScreenInit";
+ break;
+ }
+ if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ CHIPSFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymbols(reqSym, NULL);
+
+ if (cPtr->Flags & ChipsAccelSupport) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ if (cPtr->UseFullMMIO)
+ chipsUnmapMem(pScrn);
+ CHIPSFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ if (cPtr->Flags & ChipsShadowFB) {
+ if (!xf86LoadSubModule(pScrn, "shadowfb")) {
+ if (cPtr->UseFullMMIO)
+ chipsUnmapMem(pScrn);
+ CHIPSFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+ }
+
+ if (cPtr->Flags & ChipsHWCursor) {
+ if (!xf86LoadSubModule(pScrn, "ramdac")) {
+ if (cPtr->UseFullMMIO)
+ chipsUnmapMem(pScrn);
+ CHIPSFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+ }
+
+ if (cPtr->UseFullMMIO)
+ chipsUnmapMem(pScrn);
+
+ if (cPtr->Flags & ChipsLinearSupport) {
+ resRange vgamem[] = { {ResShrMemBlock,0xA0000,0xAFFFF},
+ {ResShrMemBlock,0xB0000,0xB7FFF},
+ {ResShrMemBlock,0xB8000,0xBFFFF},
+ _END };
+ xf86SetOperatingState(vgamem, cPtr->pEnt->index, ResDisableOpr);
+ }
+ if (cPtr->Flags & ChipsFullMMIOSupport)
+ xf86SetOperatingState(RES_SHARED_VGA, cPtr->pEnt->index, ResDisableOpr);
+
+ return TRUE;
+}
+
+static Bool
+chipsPreInitHiQV(ScrnInfoPtr pScrn, int flags)
+{
+ int bytesPerPixel;
+ unsigned char tmp;
+ MessageType from;
+ int i;
+ unsigned int Probed[3], FPclkI, CRTclkI;
+ double real;
+ int val;
+ const char *s;
+
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSPanelSizePtr Size = &cPtr->PanelSize;
+ CHIPSMemClockPtr MemClk = &cPtr->MemClock;
+ CHIPSClockPtr SaveClk = &(cPtr->SavedReg.Clock);
+ resRange linearRes[] = { {ResExcMemBlock|ResBios,0,0},_END };
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /* All HiQV chips support 16/24/32 bpp */
+ if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb | Support32bppFb |
+ SupportConvert32to24 | PreferConvert32to24))
+ return FALSE;
+ else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 1:
+ case 4:
+ case 8:
+ case 15:
+ case 16:
+ case 24:
+ case 32:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+ xf86PrintDepthBpp(pScrn);
+
+ /* Get the depth24 pixmap format */
+ if (pScrn->depth == 24 && pix24bpp == 0)
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+
+ /*
+ * Allocate a vgaHWRec, this must happen after xf86SetDepthBpp for 1bpp
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ hwp = VGAHWPTR(pScrn);
+ vgaHWGetIOBase(hwp);
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /* The gamma fields must be initialised when using the new cmap code */
+ if (pScrn->depth > 1) {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros))
+ return FALSE;
+ }
+
+ bytesPerPixel = max(1, pScrn->bitsPerPixel >> 3);
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+ /* Process the options */
+ cPtr->Options = (OptionInfoPtr)ChipsHiQVOptions;
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, cPtr->Options);
+
+ /* Set the bits per RGB */
+ if (pScrn->depth > 1) {
+ /* Default to 6, is this right for HiQV?? */
+ pScrn->rgbBits = 6;
+ if (xf86GetOptValInteger(cPtr->Options, OPTION_RGB_BITS,
+ &pScrn->rgbBits)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
+ pScrn->rgbBits);
+ }
+ }
+
+ if ((cPtr->Flags & ChipsAccelSupport) &&
+ (xf86ReturnOptValBool(cPtr->Options, OPTION_NOACCEL, FALSE))) {
+ cPtr->Flags &= ~ChipsAccelSupport;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+
+ from = X_DEFAULT;
+ if (pScrn->bitsPerPixel < 8) {
+ /* Default to SW cursor for 1/4 bpp */
+ cPtr->Accel.UseHWCursor = FALSE;
+ cPtr->Flags &= ~ChipsHWCursor;
+ } else {
+ cPtr->Accel.UseHWCursor = TRUE;
+ cPtr->Flags |= ChipsHWCursor;
+ }
+ if (xf86GetOptValBool(cPtr->Options, OPTION_HW_CURSOR,
+ &cPtr->Accel.UseHWCursor))
+ from = X_CONFIG;
+ if (xf86GetOptValBool(cPtr->Options, OPTION_SW_CURSOR,
+ &cPtr->Accel.UseHWCursor)) {
+ from = X_CONFIG;
+ cPtr->Accel.UseHWCursor = !cPtr->Accel.UseHWCursor;
+ }
+ if (cPtr->Accel.UseHWCursor)
+ cPtr->Flags |= ChipsHWCursor;
+ else
+ cPtr->Flags &= ~ChipsHWCursor;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ (cPtr->Flags & ChipsHWCursor) ? "HW" : "SW");
+
+ /* Default to nonlinear for < 8bpp and linear for >= 8bpp. */
+ if (pScrn->bitsPerPixel < 8) {
+ if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, FALSE)) {
+ cPtr->Flags &= ~ChipsLinearSupport;
+ from = X_CONFIG;
+ }
+ } else if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, TRUE)) {
+ cPtr->Flags &= ~ChipsLinearSupport;
+ from = X_CONFIG;
+ }
+
+ /* linear base */
+ if (cPtr->Flags & ChipsLinearSupport) {
+ if (cPtr->pEnt->location.type == BUS_PCI) {
+ cPtr->FbAddress = cPtr->PciInfo->memBase[0] & 0xff800000;
+ from = X_PROBED;
+ if (xf86RegisterResources(cPtr->pEnt->index,NULL,ResNone))
+ cPtr->Flags &= ~ChipsLinearSupport;
+ } else {
+ if (cPtr->pEnt->device->MemBase) {
+ cPtr->FbAddress = cPtr->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ cPtr->FbAddress = ((unsigned int)
+ (cPtr->readXR(cPtr, 0x06))) << 24;
+ cPtr->FbAddress |= ((unsigned int)
+ (0x80 & (cPtr->readXR(cPtr, 0x05)))) << 16;
+ from = X_PROBED;
+ }
+ linearRes[0].rBegin = cPtr->FbAddress;
+ linearRes[0].rEnd = cPtr->FbAddress + 0x800000;
+ if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) {
+ cPtr->Flags &= ~ChipsLinearSupport;
+ from = X_PROBED;
+ }
+ }
+ }
+ if (cPtr->Flags & ChipsLinearSupport) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Enabling linear addressing\n");
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "base address is set at 0x%X.\n", cPtr->FbAddress);
+ cPtr->UseMMIO = TRUE;
+ cPtr->IOAddress = cPtr->FbAddress + 0x400000L;
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Disabling linear addressing\n");
+
+
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_SHADOW_FB, FALSE)) {
+ if (!(cPtr->Flags & ChipsLinearSupport)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Option \"ShadowFB\" ignored. Not supported without linear addressing\n");
+ } else if (pScrn->depth < 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Option \"ShadowFB\" ignored. Not supported at this depth.\n");
+ } else {
+ cPtr->Flags |= ChipsShadowFB;
+ cPtr->Flags &= ~ChipsAccelSupport;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using \"Shadow Framebuffer\" - acceleration disabled\n");
+ }
+ }
+
+ if ((s = xf86GetOptValString(cPtr->Options, OPTION_OVERLAY))) {
+ if (!*s || !xf86NameCmp(s, "8,16") || !xf86NameCmp(s, "16,8")) {
+ if (pScrn->bitsPerPixel == 16) {
+ if (cPtr->Flags & ChipsLinearSupport) {
+ cPtr->Flags |= ChipsOverlay8plus16;
+ if(!xf86GetOptValInteger(
+ cPtr->Options, OPTION_COLOR_KEY, &(pScrn->colorKey)))
+ pScrn->colorKey = TRANSPARENCY_KEY;
+ pScrn->overlayFlags = OVERLAY_8_16_DUALFB;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "PseudoColor overlay enabled.\n");
+ if (!xf86IsOptionSet(cPtr->Options, OPTION_LCD_STRETCH))
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ " - Forcing option \"NoStretch\".\n");
+ if (cPtr->Flags & ChipsShadowFB) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ " - Disabling \"Shadow Framebuffer\".\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ " Not support with option \"8Plus16\".\n");
+ cPtr->Flags &= ~ChipsShadowFB;
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Option \"Overlay\" ignored. Not supported without linear addressing\n");
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Option \"Overlay\" is not supported in this configuration\n");
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "\"%s\" is not a valid value for Option \"Overlay\"\n", s);
+ }
+ }
+
+ /* memory size */
+ if (cPtr->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = cPtr->pEnt->device->videoRam;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+ } else {
+ /* not given, probe it */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT69030:
+ /* The ct69000 has 4Mb of SGRAM integrated */
+ pScrn->videoRam = 4096;
+ break;
+ case CHIPS_CT69000:
+ /* The ct69000 has 2Mb of SGRAM integrated */
+ pScrn->videoRam = 2048;
+ break;
+ case CHIPS_CT65550:
+ /* XR43: DRAM interface */
+ /* bit 2-1: memory size */
+ /* 0: 1024 kB */
+ /* 1: 2048 kB */
+ /* 2: reserved */
+ /* 3: reserved */
+ switch (((cPtr->readXR(cPtr, 0x43)) & 0x06) >> 1) {
+ case 0:
+ pScrn->videoRam = 1024;
+ break;
+ case 1:
+ case 2:
+ case 3:
+ pScrn->videoRam = 2048;
+ break;
+ }
+ default:
+ /* XRE0: Software reg */
+ /* bit 3-0: memory size */
+ /* 0: 512k */
+ /* 1: 1024k */
+ /* 2: 1536k(1.5M)*/
+ /* 3: 2048k */
+ /* 7: 4096k */
+ tmp = (cPtr->readXR(cPtr, 0xE0)) & 0xF;
+ switch (tmp) {
+ case 0:
+ pScrn->videoRam = 512;
+ break;
+ case 1:
+ pScrn->videoRam = 1024;
+ break;
+ case 2:
+ pScrn->videoRam = 1536;
+ break;
+ case 3:
+ pScrn->videoRam = 2048;
+ break;
+ case 7:
+ pScrn->videoRam = 4096;
+ break;
+ default:
+ pScrn->videoRam = 1024;
+ break;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+ }
+ cPtr->FbMapSize = pScrn->videoRam * 1024;
+
+ /* Are we using MMIO mapping of VGA registers */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_MMIO, FALSE)) {
+ if ((cPtr->Flags & ChipsLinearSupport) && cPtr->UseMMIO &&
+ (cPtr->Flags & ChipsFullMMIOSupport) &&
+ cPtr->pEnt->location.type == BUS_PCI) {
+
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Enabling MMIO\n");
+ cPtr->UseFullMMIO = TRUE;
+
+ /* Map the linear framebuffer */
+ if (!chipsMapMem(pScrn))
+ return FALSE;
+
+ /* Setup the MMIO register funstions */
+ CHIPSSetMmioExtFuncs(cPtr);
+ CHIPSHWSetMmioFuncs(pScrn, cPtr->MMIOBase, 0x0);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MMIO option ignored\n");
+ }
+ }
+
+ /* Store register values that might be messed up by a suspend resume */
+ /* Do this early as some of the other code in PreInit relies on it */
+ cPtr->SuspendHack.vgaIOBaseFlag = ((hwp->readMiscOut(hwp)) & 0x01);
+ cPtr->IOBase = (unsigned int)(cPtr->SuspendHack.vgaIOBaseFlag ?
+ 0x3D0 : 0x3B0);
+
+ /* monitor info */
+ cPtr->Monitor = chipsSetMonitor(pScrn);
+
+ /*test STN / TFT */
+ tmp = cPtr->readFR(cPtr, 0x10);
+
+ /* XR51 or FR10: DISPLAY TYPE REGISTER */
+ /* XR51[1-0] or FR10[1:0] for ct65550 : PanelType, */
+ /* 0 = Single Panel Single Drive, 3 = Dual Panel Dual Drive */
+ switch (tmp & 0x3) {
+ case 0:
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_STN, FALSE)) {
+ cPtr->PanelType |= ChipsSS;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "SS-STN probed\n");
+ } else {
+ cPtr->PanelType |= ChipsTFT;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "TFT probed\n");
+ }
+ break;
+ case 2:
+ cPtr->PanelType |= ChipsDS;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DS-STN probed\n");
+ case 3:
+ cPtr->PanelType |= ChipsDD;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DD-STN probed\n");
+ break;
+ default:
+ break;
+ }
+
+ /* test LCD */
+ /* FR01: DISPLAY TYPE REGISTER */
+ /* FR01[1:0]: Display Type, 01 = CRT, 10 = FlatPanel */
+ /* LCD */
+ tmp = cPtr->readFR(cPtr, 0x01);
+ if ((tmp & 0x03) == 0x02) {
+ cPtr->PanelType |= ChipsLCD;
+ }
+ tmp = cPtr->readXR(cPtr,0xD0);
+ if (tmp & 0x01) {
+ cPtr->PanelType |= ChipsCRT;
+ }
+ if ((cPtr->PanelType & ChipsLCD) && (cPtr->PanelType & ChipsCRT))
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "LCD/CRT\n");
+ else if (cPtr->PanelType & ChipsLCD)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "LCD\n");
+ else if (cPtr->PanelType & ChipsCRT)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT\n");
+
+
+ /* screen size */
+ /*
+ * In LCD mode / dual mode we want to derive the timing values from
+ * the ones preset by bios
+ */
+ if (cPtr->PanelType & ChipsLCD) {
+
+ /* for 65550 we only need H/VDisplay values for screen size */
+ unsigned char fr25, tmp1;
+#ifdef DEBUG
+ unsigned char fr26;
+ char tmp2;
+#endif
+ fr25 = cPtr->readFR(cPtr, 0x25);
+ tmp = cPtr->readFR(cPtr, 0x20);
+ Size->HDisplay = ((tmp + ((fr25 & 0x0F) << 8)) + 1) << 3;
+ tmp = cPtr->readFR(cPtr, 0x30);
+ tmp1 = cPtr->readFR(cPtr, 0x35);
+ Size->VDisplay = ((tmp1 & 0x0F) << 8) + tmp + 1;
+#ifdef DEBUG
+ tmp = cPtr->readFR(cPtr, 0x21);
+ Size->HRetraceStart = ((tmp + ((fr25 & 0xF0) << 4)) + 1) << 3;
+ tmp1 = cPtr->readFR(cPtr, 0x22);
+ tmp2 = (tmp1 & 0x1F) - (tmp & 0x3F);
+ Size->HRetraceEnd = ((((tmp2 < 0) ? (tmp2 + 0x40) : tmp2) << 3)
+ + Size->HRetraceStart);
+ tmp = cPtr->readFR(cPtr, 0x23);
+ fr26 = cPtr->readFR(cPtr, 0x26);
+ Size->HTotal = ((tmp + ((fr26 & 0x0F) << 8)) + 5) << 3;
+ ErrorF("x=%i, y=%i; xSync=%i, xSyncEnd=%i, xTotal=%i\n",
+ Size->HDisplay, Size->VDisplay,
+ Size->HRetraceStart,Size->HRetraceEnd,
+ Size->HTotal);
+#endif
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Display Size: x=%i; y=%i\n",
+ Size->HDisplay, Size->VDisplay);
+ /* Warn the user if the panel size has been overridden by
+ * the modeline values
+ */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Display size overridden by modelines.\n");
+ }
+ }
+
+ /* Frame Buffer */ /* for LCDs */
+ if (IS_STN(cPtr->PanelType)) {
+ tmp = cPtr->readFR(cPtr, 0x1A); /*Frame Buffer Ctrl. */
+ if (tmp & 1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Frame Buffer used\n");
+ if (!(tmp & 0x80)) {
+ /* Formula for calculating the size of the framebuffer. 3
+ * bits per pixel 10 pixels per 32 bit dword. If frame
+ * acceleration is enabled the size can be halved.
+ */
+ cPtr->FrameBufferSize = ( Size->HDisplay *
+ Size->VDisplay / 5 ) * ((tmp & 2) ? 1 : 2);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Using embedded Frame Buffer, size %d bytes\n",
+ cPtr->FrameBufferSize);
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Using external Frame Buffer used\n");
+ }
+ if (tmp & 2)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Frame accelerator enabled\n");
+ }
+
+ /* bus type */
+ tmp = (cPtr->readXR(cPtr, 0x08)) & 1;
+ if (tmp == 1) { /*PCI */
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PCI Bus\n");
+ cPtr->Bus = ChipsPCI;
+ } else { /* XR08: Linear addressing base, not for PCI */
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VL Bus\n");
+ cPtr->Bus = ChipsVLB;
+ }
+
+ /* disable acceleration for 1 and 4 bpp */
+ if (pScrn->bitsPerPixel < 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Disabling acceleration for %d bpp\n", pScrn->bitsPerPixel);
+ cPtr->Flags &= ~ChipsAccelSupport;
+ }
+
+ /* Set the flags for Colour transparency. This is dependent
+ * on the revision on the chip. Until exactly which chips
+ * have this bug are found, only allow 8bpp Colour transparency */
+ if ((pScrn->bitsPerPixel == 8) || ((cPtr->Chipset >= CHIPS_CT65555) &&
+ (pScrn->bitsPerPixel >= 8) && (pScrn->bitsPerPixel <= 24)))
+ cPtr->Flags |= ChipsColorTransparency;
+ else
+ cPtr->Flags &= ~ChipsColorTransparency;
+
+ /* DAC info */
+ if (!((cPtr->readXR(cPtr, 0xD0)) & 0x01))
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Internal DAC disabled\n");
+
+ /* MMIO address offset */
+ cPtr->Regs32 = ChipsReg32HiQV;
+
+ /* sync reset ignored on this chipset */
+ cPtr->SyncResetIgn = TRUE; /* !! */
+
+ /* We use a programamble clock */
+ pScrn->numClocks = 26; /* Some number */
+ pScrn->progClock = TRUE;
+ cPtr->ClockType = HiQV_STYLE | TYPE_PROGRAMMABLE;
+
+ if (cPtr->pEnt->device->textClockFreq > 0) {
+ SaveClk->Clock = cPtr->pEnt->device->textClockFreq;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using textclock freq: %7.3f.\n",
+ SaveClk->Clock/1000.0);
+ } else
+ SaveClk->Clock = 0;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Using programmable clocks\n");
+
+ /* Set the maximum memory clock. */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT65550:
+ if (((cPtr->readXR(cPtr, 0x04)) & 0xF) < 6)
+ MemClk->Max = 38000; /* Revision A chips */
+ else
+ MemClk->Max = 50000; /* Revision B chips */
+ break;
+ case CHIPS_CT65554:
+ case CHIPS_CT65555:
+ case CHIPS_CT68554:
+ MemClk->Max = 55000;
+ break;
+ case CHIPS_CT69000:
+ MemClk->Max = 83000;
+ break;
+ case CHIPS_CT69030:
+ MemClk->Max = 100000;
+ break;
+ }
+
+ /* Probe the dot clocks */
+ for (i = 0; i < 3; i++) {
+ unsigned int N,M,PSN,P,VCO_D;
+ unsigned char tmp;
+ int offset = i * 4;
+
+ tmp = cPtr->readXR(cPtr,0xC2 + offset);
+ M = (cPtr->readXR(cPtr, 0xC0 + offset)
+ | (tmp & 0x03)) + 2;
+ N = (cPtr->readXR(cPtr, 0xC1 + offset)
+ | (( tmp >> 4) & 0x03)) + 2;
+ tmp = cPtr->readXR(cPtr, 0xC3 + offset);
+ PSN = ((tmp & 0x1) ? 1 : 4) * ((tmp & 0x02) ? 5 : 1);
+ VCO_D = ((tmp & 0x04) ? 16 : 4);
+ P = ((tmp & 0x70) >> 4);
+ Probed[i] = VCO_D * Fref / N;
+ Probed[i] = Probed[i] * M / (PSN * (1 << P));
+ Probed[i] = Probed[i] / 1000;
+ }
+ CRTclkI = (hwp->readMiscOut(hwp) >> 2) & 0x03;
+ if (CRTclkI == 3) CRTclkI = 2;
+ FPclkI = (cPtr->readFR(cPtr, 0x03) >> 2) & 0x3;
+ if (FPclkI == 3) FPclkI = 2;
+ for (i = 0; i < 3; i++) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Dot clock %i: %7.3f MHz",i,
+ (float)(Probed[i])/1000.);
+ if (FPclkI == i) ErrorF(" FPclk");
+ if (CRTclkI == i) ErrorF(" CRTclk");
+ ErrorF("\n");
+ }
+ cPtr->FPclock = Probed[FPclkI];
+ cPtr->FPclkInx = FPclkI;
+ if (CRTclkI == FPclkI) {
+ if (FPclkI == 2)
+ CRTclkI = 1;
+ else
+ CRTclkI = 2;
+ }
+ cPtr->CRTclkInx = CRTclkI;
+
+ /* Probe the memory clock currently in use */
+ MemClk->xrCC = cPtr->readXR(cPtr, 0xCC);
+ MemClk->M = (MemClk->xrCC & 0x7F) + 2;
+ MemClk->xrCD = cPtr->readXR(cPtr, 0xCD);
+ MemClk->N = (MemClk->xrCD & 0x7F) + 2;
+ MemClk->xrCE = cPtr->readXR(cPtr, 0xCE);
+ MemClk->PSN = (MemClk->xrCE & 0x1) ? 1 : 4;
+ MemClk->P = ((MemClk->xrCE & 0x70) >> 4);
+ /* Be careful with the calculation of ProbeClk as it can overflow */
+ MemClk->ProbedClk = 4 * Fref / MemClk->N;
+ MemClk->ProbedClk = MemClk->ProbedClk * MemClk->M / (MemClk->PSN *
+ (1 << MemClk->P));
+ MemClk->ProbedClk = MemClk->ProbedClk / 1000;
+ MemClk->Clk = MemClk->ProbedClk;
+
+ if (xf86GetOptValFreq(cPtr->Options, OPTION_SET_MCLK, OPTUNITS_MHZ, &real)) {
+ int mclk = (int)(real * 1000.0);
+ if (mclk <= MemClk->Max) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using memory clock of %7.3f MHz\n",
+ (float)(mclk/1000.));
+
+ /* Only alter the memory clock if the desired memory clock differs
+ * by 50kHz from the one currently being used.
+ */
+ if (abs(mclk - MemClk->ProbedClk) > 50) {
+ unsigned char vclk[3];
+
+ MemClk->Clk = mclk;
+ chipsCalcClock(pScrn, MemClk->Clk, vclk);
+ MemClk->M = vclk[1] + 2;
+ MemClk->N = vclk[2] + 2;
+ MemClk->P = (vclk[0] & 0x70) >> 4;
+ MemClk->PSN = (vclk[0] & 0x1) ? 1 : 4;
+ MemClk->xrCC = vclk[1];
+ MemClk->xrCD = vclk[2];
+ MemClk->xrCE = 0x80 || vclk[0];
+ }
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Memory clock of %7.3f MHz exceeds limit of %7.3 MHz\n",
+ (float)(mclk/1000.),
+ (float)(MemClk->Max/1000.));
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Probed memory clock of %7.3f MHz\n",
+ (float)(MemClk->ProbedClk/1000.));
+
+ cPtr->ClockMulFactor = 1;
+
+ /* Set the min pixel clock */
+ cPtr->MinClock = 11000; /* XXX Guess, need to check this */
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %7.3f MHz\n",
+ (float)(cPtr->MinClock / 1000.));
+ /* Set the max pixel clock */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT69030:
+ cPtr->MaxClock = 170000;
+ break;
+ case CHIPS_CT69000:
+ cPtr->MaxClock = 135000;
+ break;
+ case CHIPS_CT68554:
+ case CHIPS_CT65555:
+ cPtr->MaxClock = 110000;
+ break;
+ case CHIPS_CT65554:
+ cPtr->MaxClock = 95000;
+ break;
+ case CHIPS_CT65550:
+ if (((cPtr->readXR(cPtr, 0x04)) & 0xF) < 6) {
+ if ((cPtr->readFR(cPtr, 0x0A)) & 2) {
+ /*5V Vcc */
+ cPtr->MaxClock = 100000;
+ } else {
+ /*3.3V Vcc */
+ cPtr->MaxClock = 80000;
+ }
+ } else
+ cPtr->MaxClock = 95000; /* Revision B */
+ break;
+ }
+
+ /* Check if maxClock is limited by the MemClk. Only 70% to allow for */
+ /* RAS/CAS. Extra byte per memory clock needed if framebuffer used */
+ /* Extra byte if the overlay plane is avtivated */
+ if (cPtr->FrameBufferSize)
+ if (cPtr->Flags & ChipsOverlay8plus16)
+ cPtr->MaxClock = min(cPtr->MaxClock, MemClk->Clk * 4 * 0.7 / 4);
+ else
+ cPtr->MaxClock = min(cPtr->MaxClock,
+ MemClk->Clk * 4 * 0.7 / (bytesPerPixel + 1));
+ else
+ if (cPtr->Flags & ChipsOverlay8plus16)
+ cPtr->MaxClock = min(cPtr->MaxClock, MemClk->Clk * 4 * 0.7 / 3);
+ else
+ cPtr->MaxClock = min(cPtr->MaxClock,
+ MemClk->Clk * 4 * 0.7 / bytesPerPixel);
+
+ if (cPtr->pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ case 4:
+ case 8:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ case 32:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP32];
+ break;
+ }
+
+ if (speed == 0)
+ cPtr->MaxClock = cPtr->pEnt->device->dacSpeeds[0];
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "User max pixel clock of %7.3f MHz overrides %7.3f MHz limit\n",
+ (float)(cPtr->MaxClock / 1000.), (float)(speed / 1000.));
+ cPtr->MaxClock = speed;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Max pixel clock is %7.3f MHz\n",
+ (float)(cPtr->MaxClock / 1000.));
+ }
+ /*
+ * Prepare the FPclock:
+ * if FPclock >= MaxClock : don't modify the FP clock.
+ * else set FPclock to 90% of MaxClock.
+ */
+ real = 0.;
+ switch(bytesPerPixel) {
+ case 1:
+ if (xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_8, OPTUNITS_MHZ, &real))
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "FP clock %7.3f MHz requested\n",real);
+ break;
+ case 2:
+ if (xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_16, OPTUNITS_MHZ, &real))
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "FP clock %7.3f MHz requested\n",real);
+ break;
+ case 3:
+ if (xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_24, OPTUNITS_MHZ, &real))
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "FP clock %7.3f MHz requested\n",real);
+ break;
+ case 4:
+ if (xf86GetOptValFreq(cPtr->Options, OPTION_FP_CLOCK_32, OPTUNITS_MHZ, &real))
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "FP clock %7.3f MHz requested\n",real);
+ break;
+ }
+ val = (int) (real * 1000.);
+ if (val && val >= cPtr->MinClock && val <= cPtr->MaxClock)
+ cPtr->FPclock = val;
+ else if (cPtr->FPclock > cPtr->MaxClock)
+ cPtr->FPclock = (int)((float)cPtr->MaxClock * 0.9);
+ else
+ cPtr->FPclock = 0; /* special value */
+ cPtr->FPClkModified = FALSE;
+ if (cPtr->FPclock)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "FP clock set to %7.3f MHz\n",
+ (float)(cPtr->FPclock / 1000.));
+
+#if defined(__arm32__) && defined(__NetBSD__)
+ ChipsPALMode.next = pScrn->monitor->Modes;
+ pScrn->monitor->Modes = &ChipsNTSCMode;
+#endif
+
+ if (!xf86LoadSubModule(pScrn, "ddc"))
+ return FALSE;
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+
+ if (!xf86LoadSubModule(pScrn, "i2c"))
+ return FALSE;
+ xf86LoaderReqSymLists(i2cSymbols,NULL);
+ if (chips_i2cInit(pScrn))
+ xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,cPtr->I2C));
+ else
+ chips_ddc1(pScrn);
+
+ return TRUE;
+}
+
+static Bool
+chipsPreInitWingine(ScrnInfoPtr pScrn, int flags)
+{
+ int i, bytesPerPixel, NoClocks = 0;
+ unsigned char tmp;
+ MessageType from;
+ vgaHWPtr hwp;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSClockPtr SaveClk = &(cPtr->SavedReg.Clock);
+ Bool useLinear;
+ resRange linearRes[] = { {ResExcMemBlock|ResBios,0,0},_END };
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ if (cPtr->Flags & ChipsHDepthSupport)
+ i = xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb |
+ SupportConvert32to24 | PreferConvert32to24);
+ else
+ i = xf86SetDepthBpp(pScrn, 8, 8, 8, NoDepth24Support);
+
+ if (!i)
+ return FALSE;
+ else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 1:
+ case 4:
+ case 8:
+ /* OK */
+ break;
+ case 15:
+ case 16:
+ case 24:
+ if (cPtr->Flags & ChipsHDepthSupport)
+ break; /* OK */
+ /* fall through */
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ xf86PrintDepthBpp(pScrn);
+
+ /* Get the depth24 pixmap format */
+ if (pScrn->depth == 24 && pix24bpp == 0)
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+
+ /*
+ * Allocate a vgaHWRec, this must happen after xf86SetDepthBpp for 1bpp
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ hwp = VGAHWPTR(pScrn);
+ vgaHWGetIOBase(hwp);
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /* The gamma fields must be initialised when using the new cmap code */
+ if (pScrn->depth > 1) {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros))
+ return FALSE;
+ }
+
+ /* Store register values that might be messed up by a suspend resume */
+ /* Do this early as some of the other code in PreInit relies on it */
+ cPtr->SuspendHack.xr02 = (cPtr->readXR(cPtr, 0x02)) & 0x18;
+ cPtr->SuspendHack.xr03 = (cPtr->readXR(cPtr, 0x03)) & 0x0A;
+ cPtr->SuspendHack.xr14 = (cPtr->readXR(cPtr, 0x14)) & 0x20;
+ cPtr->SuspendHack.xr15 = cPtr->readXR(cPtr, 0x15);
+
+ cPtr->SuspendHack.vgaIOBaseFlag = ((hwp->readMiscOut(hwp)) & 0x01);
+ cPtr->IOBase = (unsigned int)(cPtr->SuspendHack.vgaIOBaseFlag ?
+ 0x3D0 : 0x3B0);
+
+ bytesPerPixel = max(1, pScrn->bitsPerPixel >> 3);
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ cPtr->Options = (OptionInfoPtr)ChipsWingineOptions;
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, cPtr->Options);
+
+ /* Set the bits per RGB */
+ if (pScrn->depth > 1) {
+ /* Default to 6, is this right?? */
+ pScrn->rgbBits = 6;
+ if (xf86GetOptValInteger(cPtr->Options, OPTION_RGB_BITS,
+ &pScrn->rgbBits)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
+ pScrn->rgbBits);
+ }
+ }
+
+ if ((cPtr->Flags & ChipsAccelSupport) &&
+ (xf86ReturnOptValBool(cPtr->Options, OPTION_NOACCEL, FALSE))) {
+ cPtr->Flags &= ~ChipsAccelSupport;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+
+ from = X_DEFAULT;
+ if (pScrn->bitsPerPixel < 8) {
+ /* Default to SW cursor for 1/4 bpp */
+ cPtr->Accel.UseHWCursor = FALSE;
+ cPtr->Flags &= ~ChipsHWCursor;
+ } else {
+ cPtr->Accel.UseHWCursor = TRUE;
+ cPtr->Flags |= ChipsHWCursor;
+ }
+ if (xf86GetOptValBool(cPtr->Options, OPTION_HW_CURSOR,
+ &cPtr->Accel.UseHWCursor))
+ from = X_CONFIG;
+ if (xf86GetOptValBool(cPtr->Options, OPTION_SW_CURSOR,
+ &cPtr->Accel.UseHWCursor)) {
+ from = X_CONFIG;
+ cPtr->Accel.UseHWCursor = !cPtr->Accel.UseHWCursor;
+ }
+ if (cPtr->Accel.UseHWCursor)
+ cPtr->Flags |= ChipsHWCursor;
+ else
+ cPtr->Flags &= ~ChipsHWCursor;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ (cPtr->Flags & ChipsHWCursor) ? "HW" : "SW");
+
+ /* memory size */
+ if (cPtr->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = cPtr->pEnt->device->videoRam;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+ } else {
+ /* not given, probe it */
+ /* XR0F: Software flags 0 */
+ /* bit 1-0: memory size */
+ /* 0: 256 kB */
+ /* 1: 512 kB */
+ /* 2: 1024 kB */
+ /* 3: 1024 kB */
+
+ switch ((cPtr->readXR(cPtr, 0x0F)) & 3) {
+ case 0:
+ pScrn->videoRam = 256;
+ break;
+ case 1:
+ pScrn->videoRam = 512;
+ break;
+ case 2:
+ pScrn->videoRam = 1024;
+ break;
+ case 3:
+ pScrn->videoRam = 2048;
+ break;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+ }
+ cPtr->FbMapSize = pScrn->videoRam * 1024;
+
+ /* Default to nonlinear for < 8bpp and linear for >= 8bpp. */
+ if (cPtr->Flags & ChipsLinearSupport) useLinear = TRUE;
+ if (pScrn->bitsPerPixel < 8) {
+ if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, FALSE)) {
+ useLinear = FALSE;
+ from = X_CONFIG;
+ }
+ } else if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, TRUE)) {
+ useLinear = FALSE;
+ from = X_CONFIG;
+ }
+
+ /* linear base */
+ if (useLinear) {
+ unsigned char mask = 0xF8;
+ if (pScrn->videoRam == 1024)
+ mask = 0xF0;
+ else if (pScrn->videoRam == 2048)
+ mask = 0xE0;
+ if (cPtr->pEnt->device->MemBase) {
+ cPtr->FbAddress = cPtr->pEnt->device->MemBase
+ & ((0xFF << 24) | (mask << 16));
+ from = X_CONFIG;
+ } else {
+ cPtr->FbAddress = ((0xFF & (cPtr->readXR(cPtr, 0x09))) << 24);
+ cPtr->FbAddress |= ((mask & (cPtr->readXR(cPtr, 0x08))) << 16);
+ from = X_PROBED;
+ }
+ linearRes[0].rBegin = cPtr->FbAddress;
+ linearRes[0].rEnd = cPtr->FbAddress + 0x800000;
+ if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) {
+ useLinear = FALSE;
+ from = X_PROBED;
+ }
+ }
+
+ if (useLinear) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Enabling linear addressing\n");
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "base address is set at 0x%X.\n", cPtr->FbAddress);
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_MMIO, FALSE) &&
+ (cPtr->Flags & ChipsMMIOSupport)) {
+ cPtr->UseMMIO = TRUE;
+ cPtr->IOAddress = cPtr->FbAddress + 0x200000L;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Enabling MMIO\n");
+ }
+ } else {
+ if (cPtr->Flags & ChipsLinearSupport)
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Disabling linear addressing\n");
+ cPtr->Flags &= ~ChipsLinearSupport;
+ }
+
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_SHADOW_FB, FALSE)) {
+ if (!(cPtr->Flags & ChipsLinearSupport)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Option \"ShadowFB\" ignored. Not supported without linear addressing\n");
+ } else if (pScrn->depth < 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Option \"ShadowFB\" ignored. Not supported at this depth.\n");
+ } else {
+ cPtr->Flags |= ChipsShadowFB;
+ cPtr->Flags &= ~ChipsAccelSupport;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using \"Shadow Framebuffer\" - acceleration disabled\n");
+ }
+ }
+
+ /* monitor info */
+ cPtr->Monitor = chipsSetMonitor(pScrn);
+
+ cPtr->PanelType |= ChipsCRT;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT\n");
+
+ /* bus type */
+ tmp = cPtr->readXR(cPtr, 0x01) & 3;
+ switch (tmp) {
+ case 0:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ISA Bus\n");
+ cPtr->Bus = ChipsISA;
+ break;
+ case 3:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VL Bus\n");
+ cPtr->Bus = ChipsVLB;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Unknown Bus\n");
+ cPtr->Bus = ChipsUnknown;
+ break;
+ }
+
+ /* disable acceleration for 1 and 4 bpp */
+ if (pScrn->bitsPerPixel < 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Disabling acceleration for %d bpp\n", pScrn->bitsPerPixel);
+ cPtr->Flags &= ~ChipsAccelSupport;
+ }
+
+ /* 32bit register address offsets */
+ if ((cPtr->Flags & ChipsAccelSupport) ||
+ (cPtr->Flags & ChipsHWCursor)) {
+ cPtr->Regs32 = xnfalloc(sizeof(ChipsReg32));
+ tmp = cPtr->readXR(cPtr, 0x07);
+ for( i = 0; i < (sizeof(ChipsReg32) / sizeof(ChipsReg32[0])); i++) {
+ cPtr->Regs32[i] = ((ChipsReg32[i] & 0x7E03)) | ((tmp & 0x80)
+ << 8)| ((tmp & 0x7F) << 2);
+#ifdef DEBUG
+ ErrorF("DR[%X] = %X\n",i,cPtr->Regs32[i]);
+#endif
+ }
+ linearRes[0].type = ResExcIoSparse | ResBios;
+ linearRes[0].rBase = cPtr->Regs32[0];
+ linearRes[0].rMask = 0x83FC;
+ if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) {
+ if (cPtr->Flags & ChipsAccelSupport) {
+ cPtr->Flags &= ~ChipsAccelSupport;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Cannot allocate IO registers: "
+ "Disabling acceleration\n");
+ }
+ if (cPtr->Flags & ChipsHWCursor) {
+ cPtr->Flags &= ~ChipsHWCursor;
+ cPtr->Accel.UseHWCursor = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Cannot allocate IO registers: "
+ "Disabling HWCursor\n");
+ }
+ }
+ }
+
+ cPtr->ClockMulFactor = ((pScrn->bitsPerPixel >= 8) ? bytesPerPixel : 1);
+ if (cPtr->ClockMulFactor != 1)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Clocks scaled by %d\n", cPtr->ClockMulFactor);
+
+ /* Clock type */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT64200:
+ NoClocks = 4;
+ cPtr->ClockType = WINGINE_1_STYLE | TYPE_HW;
+ break;
+ default:
+ if (!((cPtr->readXR(cPtr, 0x01)) & 0x10)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Using external clock generator\n");
+ NoClocks = 4;
+ cPtr->ClockType = WINGINE_1_STYLE | TYPE_HW;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Using internal clock generator\n");
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_HW_CLKS, FALSE)) {
+ NoClocks = 3;
+ cPtr->ClockType = WINGINE_2_STYLE | TYPE_HW;
+ } else {
+ NoClocks = 26; /* some number */
+ cPtr->ClockType = WINGINE_2_STYLE | TYPE_PROGRAMMABLE;
+ pScrn->progClock = TRUE;
+ }
+ }
+ }
+
+ if (cPtr->ClockType & TYPE_PROGRAMMABLE) {
+ pScrn->numClocks = NoClocks;
+ if(cPtr->pEnt->device->textClockFreq > 0) {
+ SaveClk->Clock = cPtr->pEnt->device->textClockFreq;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using textclock freq: %7.3f.\n",
+ SaveClk->Clock/1000.0);
+ } else
+ SaveClk->Clock = CRT_TEXT_CLK_FREQ;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Using programmable clocks\n");
+ } else { /* TYPE_PROGRAMMABLE */
+ SaveClk->Clock = chipsGetHWClock(pScrn);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using textclock clock %i.\n",
+ SaveClk->Clock);
+ if (!cPtr->pEnt->device->numclocks) {
+ pScrn->numClocks = NoClocks;
+ xf86GetClocks(pScrn, NoClocks, chipsClockSelect,
+ chipsProtect, chipsBlankScreen,
+ cPtr->IOBase + 0x0A, 0x08, 1, 28322);
+ from = X_PROBED;
+ } else {
+ pScrn->numClocks = cPtr->pEnt->device->numclocks;
+ if (pScrn->numClocks > NoClocks) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Too many Clocks specified in configuration file.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "\t\tAt most %d clocks may be specified\n", NoClocks);
+ pScrn->numClocks= NoClocks;
+ }
+ for (i = 0; i < pScrn->numClocks; i++)
+ pScrn->clock[i] = cPtr->pEnt->device->clock[i];
+ from = X_CONFIG;
+ }
+ xf86ShowClocks(pScrn, from);
+ }
+
+ /* Set the min pixel clock */
+ /* XXX Guess, need to check this */
+ cPtr->MinClock = 11000 / cPtr->ClockMulFactor;
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %7.3f MHz\n",
+ (float)(cPtr->MinClock / 1000.));
+ /* maximal clock */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT64200:
+ cPtr->MaxClock = 80000 / cPtr->ClockMulFactor;
+ break;
+ case CHIPS_CT64300:
+ cPtr->MaxClock = 85000 / cPtr->ClockMulFactor;
+ break;
+ }
+
+ if (cPtr->pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ case 4:
+ case 8:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ }
+ if (speed == 0)
+ cPtr->MaxClock = cPtr->pEnt->device->dacSpeeds[0];
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "User max pixel clock of %7.3f MHz overrides %7.3f MHz limit\n",
+ (float)(cPtr->MaxClock / 1000.), (float)(speed / 1000.));
+ cPtr->MaxClock = speed;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Max pixel clock is %7.3f MHz\n",
+ (float)(cPtr->MaxClock / 1000.));
+ }
+
+ return TRUE;
+}
+
+static Bool
+chipsPreInit655xx(ScrnInfoPtr pScrn, int flags)
+{
+ int i, bytesPerPixel, NoClocks = 0;
+ unsigned char tmp;
+ MessageType from;
+ vgaHWPtr hwp;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSPanelSizePtr Size = &cPtr->PanelSize;
+ CHIPSClockPtr SaveClk = &(cPtr->SavedReg.Clock);
+ Bool useLinear;
+ resRange linearRes[] = { {ResExcMemBlock|ResBios,0,0},_END };
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ if (cPtr->Flags & ChipsHDepthSupport)
+ i = xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb |
+ SupportConvert32to24 | PreferConvert32to24);
+ else
+ i = xf86SetDepthBpp(pScrn, 8, 8, 8, NoDepth24Support);
+
+ if (!i)
+ return FALSE;
+ else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 1:
+ case 4:
+ case 8:
+ /* OK */
+ break;
+ case 15:
+ case 16:
+ case 24:
+ if (cPtr->Flags & ChipsHDepthSupport)
+ break; /* OK */
+ /* fall through */
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+ xf86PrintDepthBpp(pScrn);
+
+ /* Get the depth24 pixmap format */
+ if (pScrn->depth == 24 && pix24bpp == 0)
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+
+ /*
+ * Allocate a vgaHWRec, this must happen after xf86SetDepthBpp for 1bpp
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ hwp = VGAHWPTR(pScrn);
+ vgaHWGetIOBase(hwp);
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /* The gamma fields must be initialised when using the new cmap code */
+ if (pScrn->depth > 1) {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros))
+ return FALSE;
+ }
+
+ /* Store register values that might be messed up by a suspend resume */
+ /* Do this early as some of the other code in PreInit relies on it */
+ cPtr->SuspendHack.xr02 = (cPtr->readXR(cPtr, 0x02)) & 0x18;
+ cPtr->SuspendHack.xr03 = (cPtr->readXR(cPtr, 0x03)) & 0x0A;
+ cPtr->SuspendHack.xr14 = (cPtr->readXR(cPtr, 0x14)) & 0x20;
+ cPtr->SuspendHack.xr15 = cPtr->readXR(cPtr, 0x15);
+
+ cPtr->SuspendHack.vgaIOBaseFlag = ((hwp->readMiscOut(hwp)) & 0x01);
+ cPtr->IOBase = cPtr->SuspendHack.vgaIOBaseFlag ? 0x3D0 : 0x3B0;
+
+ bytesPerPixel = max(1, pScrn->bitsPerPixel >> 3);
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ cPtr->Options = (OptionInfoPtr)Chips655xxOptions;
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, cPtr->Options);
+
+ /* Set the bits per RGB */
+ if (pScrn->depth > 1) {
+ /* Default to 6, is this right */
+ pScrn->rgbBits = 6;
+ if (xf86GetOptValInteger(cPtr->Options, OPTION_RGB_BITS,
+ &pScrn->rgbBits)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
+ pScrn->rgbBits);
+ }
+ }
+
+ if ((cPtr->Flags & ChipsAccelSupport) &&
+ (xf86ReturnOptValBool(cPtr->Options, OPTION_NOACCEL, FALSE))) {
+ cPtr->Flags &= ~ChipsAccelSupport;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+
+ from = X_DEFAULT;
+ if (pScrn->bitsPerPixel < 8) {
+ /* Default to SW cursor for 1/4 bpp */
+ cPtr->Accel.UseHWCursor = FALSE;
+ cPtr->Flags &= ~ChipsHWCursor;
+ } else {
+ cPtr->Accel.UseHWCursor = TRUE;
+ cPtr->Flags |= ChipsHWCursor;
+ }
+ if (xf86GetOptValBool(cPtr->Options, OPTION_HW_CURSOR,
+ &cPtr->Accel.UseHWCursor))
+ from = X_CONFIG;
+ if (xf86GetOptValBool(cPtr->Options, OPTION_SW_CURSOR,
+ &cPtr->Accel.UseHWCursor)) {
+ from = X_CONFIG;
+ cPtr->Accel.UseHWCursor = !cPtr->Accel.UseHWCursor;
+ }
+ if (cPtr->Accel.UseHWCursor)
+ cPtr->Flags |= ChipsHWCursor;
+ else
+ cPtr->Flags &= ~ChipsHWCursor;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ (cPtr->Flags & ChipsHWCursor) ? "HW" : "SW");
+
+ /* memory size */
+ if (cPtr->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = cPtr->pEnt->device->videoRam;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+ } else {
+ /* not given, probe it */
+ /* XR0F: Software flags 0 */
+ /* bit 1-0: memory size */
+ /* 0: 256 kB */
+ /* 1: 512 kB */
+ /* 2: 1024 kB */
+ /* 3: 1024 kB */
+ switch ((cPtr->readXR(cPtr, 0x0F)) & 3) {
+ case 0:
+ pScrn->videoRam = 256;
+ break;
+ case 1:
+ pScrn->videoRam = 512;
+ break;
+ case 2:
+ case 3:
+ pScrn->videoRam = 1024;
+ break;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+ }
+ cPtr->FbMapSize = pScrn->videoRam * 1024;
+
+ /* Default to nonlinear for < 8bpp and linear for >= 8bpp. */
+ if (cPtr->Flags & ChipsLinearSupport) useLinear = TRUE;
+ if (pScrn->bitsPerPixel < 8) {
+ if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, FALSE)) {
+ useLinear = FALSE;
+ from = X_CONFIG;
+ }
+ } else if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, TRUE)) {
+ useLinear = FALSE;
+ from = X_CONFIG;
+ }
+
+ /* linear base */
+ if (useLinear) {
+ unsigned char mask;
+ if (cPtr->Chipset == CHIPS_CT65535) {
+ mask = (pScrn->videoRam > 512) ? 0xF8 :0xFC;
+ if (cPtr->Bus == ChipsISA)
+ mask &= 0x7F;
+ } else if (cPtr->Bus == ChipsISA) {
+ mask = 0x0F;
+ } else {
+ mask = 0xFF;
+ tmp = cPtr->readXR(cPtr, 0x01);
+ if(tmp & 0x40)
+ mask &= 0x3F;
+ if(!(tmp & 0x80))
+ mask &= 0xCF;
+ }
+ if (cPtr->pEnt->location.type == BUS_PCI) {
+ cPtr->FbAddress = cPtr->PciInfo->memBase[0] & 0xff800000;
+ if (xf86RegisterResources(cPtr->pEnt->index,NULL,ResNone))
+ useLinear = FALSE;
+ from = X_PROBED;
+ } else {
+ if (cPtr->pEnt->device->MemBase) {
+ cPtr->FbAddress = cPtr->pEnt->device->MemBase;
+ if (cPtr->Chipset == CHIPS_CT65535)
+ cPtr->FbAddress &= (mask << 17);
+ else if (cPtr->Chipset > CHIPS_CT65535)
+ cPtr->FbAddress &= (mask << 20);
+ from = X_CONFIG;
+ } else {
+ if (cPtr->Chipset <= CHIPS_CT65530) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "base address assumed at 0xC00000!\n");
+ cPtr->FbAddress = 0xC00000;
+ from = X_CONFIG;
+ } else if (cPtr->Chipset == CHIPS_CT65535) {
+ cPtr->FbAddress =
+ ((mask & (cPtr->readXR(cPtr, 0x08))) << 17);
+ } else {
+ cPtr->FbAddress =
+ ((mask & (cPtr->readXR(cPtr, 0x08))) << 20);
+ }
+ from = X_PROBED;
+ }
+ linearRes[0].rBegin = cPtr->FbAddress;
+ linearRes[0].rEnd = cPtr->FbAddress + 0x800000;
+ if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) {
+ useLinear = FALSE;
+ from = X_PROBED;
+ }
+ }
+ }
+
+ if (useLinear) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Enabling linear addressing\n");
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "base address is set at 0x%X.\n", cPtr->FbAddress);
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_MMIO, FALSE) &&
+ (cPtr->Flags & ChipsMMIOSupport)) {
+ cPtr->UseMMIO = TRUE;
+ cPtr->IOAddress = cPtr->FbAddress + 0x200000L;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Enabling MMIO\n");
+ }
+ } else {
+ if (cPtr->Flags & ChipsLinearSupport)
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Disabling linear addressing\n");
+ cPtr->Flags &= ~ChipsLinearSupport;
+ }
+
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_SHADOW_FB, FALSE)) {
+ if (!(cPtr->Flags & ChipsLinearSupport)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Option \"ShadowFB\" ignored. Not supported without linear addressing\n");
+ } else if (pScrn->depth < 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Option \"ShadowFB\" ignored. Not supported at this depth.\n");
+ } else {
+ cPtr->Flags |= ChipsShadowFB;
+ cPtr->Flags &= ~ChipsAccelSupport;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using \"Shadow Framebuffer\" - acceleration disabled\n");
+ }
+ }
+
+ /* monitor info */
+ cPtr->Monitor = chipsSetMonitor(pScrn);
+
+ /*test STN / TFT */
+ tmp = cPtr->readXR(cPtr, 0x51);
+
+ /* XR51 or FR10: DISPLAY TYPE REGISTER */
+ /* XR51[1-0] or FR10[1:0] for ct65550 : PanelType, */
+ /* 0 = Single Panel Single Drive, 3 = Dual Panel Dual Drive */
+ switch (tmp & 0x3) {
+ case 0:
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_STN, FALSE)) {
+ cPtr->PanelType |= ChipsSS;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "SS-STN probed\n");
+ } else {
+ cPtr->PanelType |= ChipsTFT;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "TFT probed\n");
+ }
+ break;
+ case 2:
+ cPtr->PanelType |= ChipsDS;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DS-STN probed\n");
+ case 3:
+ cPtr->PanelType |= ChipsDD;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DD-STN probed\n");
+ break;
+ default:
+ break;
+ }
+
+ /* test LCD */
+ /* XR51: DISPLAY TYPE REGISTER */
+ /* XR51[2]: Display Type, 0 = CRT, 1 = FlatPanel */
+ if (tmp & 0x04) {
+ cPtr->PanelType |= ChipsLCD;
+ }
+ if ((cPtr->readXR(cPtr, 0x06)) & 0x02) {
+ cPtr->PanelType |= ChipsCRT;
+ }
+ if ((cPtr->PanelType & ChipsLCD) && (cPtr->PanelType & ChipsCRT))
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "LCD/CRT\n");
+ else if (cPtr->PanelType & ChipsLCD)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "LCD\n");
+ else if (cPtr->PanelType & ChipsCRT)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT\n");
+
+
+ /* screen size */
+ /*
+ * In LCD mode / dual mode we want to derive the timing values from
+ * the ones preset by bios
+ */
+ if (cPtr->PanelType & ChipsLCD) {
+ unsigned char xr17, tmp1;
+ char tmp2;
+
+ xr17 = cPtr->readXR(cPtr, 0x17);
+ tmp = cPtr->readXR(cPtr, 0x1B);
+ Size->HTotal =((tmp + ((xr17 & 0x01) << 8)) + 5) << 3;
+ tmp = cPtr->readXR(cPtr, 0x1C);
+ Size->HDisplay = ((tmp + ((xr17 & 0x02) << 7)) + 1) << 3;
+ tmp = cPtr->readXR(cPtr, 0x19);
+ Size->HRetraceStart = ((tmp + ((xr17 & 0x04) << 9)) + 1) << 3;
+ tmp1 = cPtr->readXR(cPtr, 0x1A);
+ tmp2 = (tmp1 & 0x1F) + ((xr17 & 0x08) << 2) - (tmp & 0x3F);
+ Size->HRetraceEnd = ((((tmp2 < 0) ? (tmp2 + 0x40) : tmp2) << 3)
+ + Size->HRetraceStart);
+ tmp1 = cPtr->readXR(cPtr, 0x65);
+ tmp = cPtr->readXR(cPtr, 0x68);
+ Size->VDisplay = ((tmp1 & 0x02) << 7)
+ + ((tmp1 & 0x40) << 3) + tmp + 1;
+ tmp = cPtr->readXR(cPtr, 0x66);
+ Size->VRetraceStart = ((tmp1 & 0x04) << 6)
+ + ((tmp1 & 0x80) << 2) + tmp + 1;
+ tmp = cPtr->readXR(cPtr, 0x64);
+ Size->VTotal = ((tmp1 & 0x01) << 8)
+ + ((tmp1 & 0x20) << 4) + tmp + 2;
+#ifdef DEBUG
+ ErrorF("x=%i, y=%i; xSync=%i, xSyncEnd=%i, xTotal=%i\n",
+ Size->HDisplay, Size->VDisplay,
+ Size->HRetraceStart, Size->HRetraceEnd,
+ Size->HTotal);
+#endif
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Display Size: x=%i; y=%i\n",
+ Size->HDisplay, Size->VDisplay);
+ /* Warn the user if the panel size has been overridden by
+ * the modeline values
+ */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Display size overridden by modelines.\n");
+ }
+ }
+
+ /* Frame Buffer */ /* for LCDs */
+ if (IS_STN(cPtr->PanelType)) {
+ tmp = cPtr->readXR(cPtr, 0x6F); /*Frame Buffer Ctrl. */
+ if (tmp & 1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Frame Buffer used\n");
+ if ((cPtr->Chipset > CHIPS_CT65530) && !(tmp & 0x80)) {
+ /* Formula for calculating the size of the framebuffer. 3
+ * bits per pixel 10 pixels per 32 bit dword. If frame
+ * acceleration is enabled the size can be halved.
+ */
+ cPtr->FrameBufferSize = ( Size->HDisplay *
+ Size->VDisplay / 5 ) * ((tmp & 2) ? 1 : 2);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Using embedded Frame Buffer, size %d bytes\n",
+ cPtr->FrameBufferSize);
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Using external Frame Buffer used\n");
+ }
+ if (tmp & 2)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Frame accelerator enabled\n");
+ }
+
+ /* bus type */
+ if (cPtr->Chipset > CHIPS_CT65535) {
+ tmp = (cPtr->readXR(cPtr, 0x01)) & 7;
+ if (tmp == 6) { /*PCI */
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PCI Bus\n");
+ cPtr->Bus = ChipsPCI;
+ if ((cPtr->Chipset == CHIPS_CT65545) ||
+ (cPtr->Chipset == CHIPS_CT65546)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "32Bit IO not supported on 65545 PCI\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "\tenabling MMIO\n");
+ cPtr->UseMMIO = TRUE;
+ }
+
+ } else { /* XR08: Linear addressing base, not for PCI */
+ switch (tmp) {
+ case 3:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CPU Direct\n");
+ cPtr->Bus = ChipsCPUDirect;
+ break;
+ case 5:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ISA Bus\n");
+ cPtr->Bus = ChipsISA;
+ break;
+ case 7:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VL Bus\n");
+ cPtr->Bus = ChipsVLB;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Unknown Bus\n");
+ }
+ }
+ } else {
+ tmp = (cPtr->readXR(cPtr, 0x01)) & 3;
+ switch (tmp) {
+ case 0:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PI Bus\n");
+ cPtr->Bus = ChipsPIB;
+ break;
+ case 1:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MC Bus\n");
+ cPtr->Bus = ChipsMCB;
+ break;
+ case 2:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VL Bus\n");
+ cPtr->Bus = ChipsVLB;
+ break;
+ case 3:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "ISA Bus\n");
+ cPtr->Bus = ChipsISA;
+ break;
+ }
+ }
+
+ if (!(cPtr->Bus == ChipsPCI) && (cPtr->UseMMIO)) {
+ cPtr->UseMMIO = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "MMIO only supported on PCI Bus. Disabling MMIO\n");
+ }
+
+ /* disable acceleration for 1 and 4 bpp */
+ if (pScrn->bitsPerPixel < 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Disabling acceleration for %d bpp\n", pScrn->bitsPerPixel);
+ cPtr->Flags &= ~ChipsAccelSupport;
+ }
+
+ if ((cPtr->Chipset == CHIPS_CT65530) &&
+ (cPtr->Flags & ChipsLinearSupport)) {
+ /* linear mode is no longer default on ct65530 since it */
+ /* requires additional hardware which some manufacturers*/
+ /* might not provide. */
+ if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LINEAR, FALSE))
+ cPtr->Flags &= ~ChipsLinearSupport;
+
+ /* Test wether linear addressing is possible on 65530 */
+ /* on the 65530 only the A19 select scheme can be used*/
+ /* for linear addressing since MEMW is used on ISA bus*/
+ /* systems. */
+ /* A19 however is used if video memory is > 512 Mb */
+ if ((cPtr->Bus == ChipsISA) && (pScrn->videoRam > 512)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "User selected linear fb not supported by HW!\n");
+ cPtr->Flags &= ~ChipsLinearSupport;
+ }
+ }
+
+ /* DAC info */
+ if ((cPtr->readXR(cPtr, 0x06)) & 0x02)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Internal DAC disabled\n");
+
+ /* MMIO address offset */
+ if (cPtr->UseMMIO)
+ cPtr->Regs32 = ChipsReg32;
+ else if ((cPtr->Flags & ChipsAccelSupport) ||
+ (cPtr->Flags & ChipsHWCursor)) {
+ cPtr->Regs32 = xnfalloc(sizeof(ChipsReg32));
+ tmp = cPtr->readXR(cPtr, 0x07);
+ for (i = 0; i < (sizeof(ChipsReg32)/sizeof(ChipsReg32[0])); i++) {
+ cPtr->Regs32[i] =
+ ((ChipsReg32[i] & 0x7E03)) | ((tmp & 0x80)<< 8)
+ | ((tmp & 0x7F) << 2);
+#ifdef DEBUG
+ ErrorF("DR[%X] = %X\n",i,cPtr->Regs32[i]);
+#endif
+ }
+ linearRes[0].type = ResExcIoSparse;
+ linearRes[0].rBase = cPtr->Regs32[0];
+ linearRes[0].rMask = 0x83FC;
+ if (xf86RegisterResources(cPtr->pEnt->index,linearRes,ResNone)) {
+ if (cPtr->Flags & ChipsAccelSupport) {
+ cPtr->Flags &= ~ChipsAccelSupport;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Cannot allocate IO registers: "
+ "Disabling acceleration\n");
+ }
+ if (cPtr->Flags & ChipsHWCursor) {
+ cPtr->Flags &= ~ChipsHWCursor;
+ cPtr->Accel.UseHWCursor = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Cannot allocate IO registers: "
+ "Disabling HWCursor\n");
+ }
+ }
+ }
+
+ /* sync reset ignored on this chipset */
+ if (cPtr->Chipset > CHIPS_CT65530) {
+ tmp = cPtr->readXR(cPtr, 0x0E);
+ if (tmp & 0x80)
+ cPtr->SyncResetIgn = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Synchronous reset %signored.\n",
+ (cPtr->SyncResetIgn ? "" : "not "));
+ }
+
+ cPtr->ClockMulFactor = ((pScrn->bitsPerPixel >= 8) ? bytesPerPixel : 1);
+ if (cPtr->ClockMulFactor != 1)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Clocks scaled by %d\n", cPtr->ClockMulFactor);
+ /* We use a programamble clock */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT65520:
+ case CHIPS_CT65525:
+ case CHIPS_CT65530:
+ NoClocks = 4; /* Some number */
+ cPtr->ClockType = OLD_STYLE | TYPE_HW;
+ break;
+ default:
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_HW_CLKS, FALSE)) {
+ NoClocks = 5; /* Some number */
+ cPtr->ClockType = NEW_STYLE | TYPE_HW;
+ } else {
+ NoClocks = 26; /* Some number */
+ cPtr->ClockType = NEW_STYLE | TYPE_PROGRAMMABLE;
+ pScrn->progClock = TRUE;
+ }
+ }
+
+ if (cPtr->ClockType & TYPE_PROGRAMMABLE) {
+ pScrn->numClocks = NoClocks;
+ if (cPtr->pEnt->device->textClockFreq > 0) {
+ SaveClk->Clock = cPtr->pEnt->device->textClockFreq;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using textclock freq: %7.3f.\n",
+ SaveClk->Clock/1000.0);
+ } else
+ SaveClk->Clock = ((cPtr->PanelType & ChipsLCD) ?
+ LCD_TEXT_CLK_FREQ : CRT_TEXT_CLK_FREQ);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Using programmable clocks\n");
+ } else { /* TYPE_PROGRAMMABLE */
+ SaveClk->Clock = chipsGetHWClock(pScrn);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using textclock clock %i.\n",
+ SaveClk->Clock);
+ if (!cPtr->pEnt->device->numclocks) {
+ pScrn->numClocks = NoClocks;
+ xf86GetClocks(pScrn, NoClocks, chipsClockSelect,
+ chipsProtect, chipsBlankScreen,
+ cPtr->IOBase + 0x0A, 0x08, 1, 28322);
+ from = X_PROBED;
+ } else {
+ pScrn->numClocks = cPtr->pEnt->device->numclocks;
+ if (pScrn->numClocks > NoClocks) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Too many Clocks specified in configuration file.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "\t\tAt most %d clocks may be specified\n", NoClocks);
+ pScrn->numClocks = NoClocks;
+ }
+ for (i = 0; i < pScrn->numClocks; i++)
+ pScrn->clock[i] = cPtr->pEnt->device->clock[i];
+ from = X_CONFIG;
+ }
+ xf86ShowClocks(pScrn, from);
+ }
+ /* Set the min pixel clock */
+ /* XXX Guess, need to check this */
+ cPtr->MinClock = 11000 / cPtr->ClockMulFactor;
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %7.3f MHz\n",
+ (float)(cPtr->MinClock / 1000.));
+ /* Set the max pixel clock */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT65546:
+ case CHIPS_CT65548:
+ /* max VCLK is 80 MHz, max MCLK is 75 MHz for CT65548 */
+ /* It is not sure for CT65546, but it works with 60 nsec EDODRAM */
+ cPtr->MaxClock = 80000 / cPtr->ClockMulFactor;
+ break;
+ default:
+ if ((cPtr->readXR(cPtr, 0x6C)) & 2) {
+ /*5V Vcc */
+ cPtr->MaxClock = 68000 / cPtr->ClockMulFactor;
+ } else {
+ /*3.3V Vcc */
+ cPtr->MaxClock = 56000 / cPtr->ClockMulFactor;
+ }
+ }
+
+ if (cPtr->pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ case 4:
+ case 8:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ speed = cPtr->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ }
+ if (speed == 0)
+ cPtr->MaxClock = cPtr->pEnt->device->dacSpeeds[0];
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "User max pixel clock of %7.3f MHz overrides %7.3f MHz limit\n",
+ (float)(cPtr->MaxClock / 1000.), (float)(speed / 1000.));
+ cPtr->MaxClock = speed;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Max pixel clock is %7.3f MHz\n",
+ (float)(cPtr->MaxClock / 1000.));
+ }
+
+ return TRUE;
+}
+
+
+/* Mandatory */
+static Bool
+CHIPSEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ chipsHWCursorOn(cPtr);
+ /* Should we re-save the text mode on each VT enter? */
+ if(!chipsModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ /*
+ * we need to wait until the chip frame accellerator has
+ * settled or the HW cursor might be messed up (seen on 65550)
+ */
+ usleep(50000);
+ CHIPSAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ return TRUE;
+}
+
+/* Mandatory */
+static void
+CHIPSLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSACLPtr cAcl = CHIPSACLPTR(pScrn);
+
+ /*xf86EnableAccess(pScrn);*/
+
+ /* Invalidate the cached acceleration registers */
+ cAcl->planemask = -1;
+ cAcl->fgColor = -1;
+ cAcl->bgColor = -1;
+ chipsHWCursorOff(cPtr);
+ chipsRestore(pScrn, &(VGAHWPTR(pScrn))->SavedReg, &cPtr->SavedReg, TRUE);
+ chipsLock(pScrn);
+}
+
+static void
+chipsRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ int width, height, Bpp, FBPitch;
+ unsigned char *src, *dst;
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ FBPitch = pScrn->displayWidth * Bpp;
+
+ while(num--) {
+ width = (pbox->x2 - pbox->x1) * Bpp;
+ height = pbox->y2 - pbox->y1;
+ src = cPtr->ShadowPtr + (pbox->y1 * cPtr->ShadowPitch) +
+ (pbox->x1 * Bpp);
+ dst = cPtr->FbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
+
+ while(height--) {
+ memcpy(dst, src, width);
+ dst += FBPitch;
+ src += cPtr->ShadowPitch;
+ }
+
+ pbox++;
+ }
+}
+
+static void
+chipsLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
+ VisualPtr pVisual)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ int i, index, shift ;
+
+ shift = ((pScrn->depth == 15) &&
+ (!(cPtr->Flags & ChipsOverlay8plus16))) ? 3 : 0;
+
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ hwp->writeDacWriteAddr(hwp,index << shift);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].red);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].green);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].blue);
+ DACDelay(hwp);
+ }
+
+ /* This shouldn't be necessary, but we'll play safe. */
+ hwp->disablePalette(hwp);
+}
+
+static void
+chipsLoadPalette16(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ int i, index;
+
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ hwp->writeDacWriteAddr(hwp, index << 2);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index >> 1].red);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].green);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index >> 1].blue);
+ DACDelay(hwp);
+ }
+
+ /* This shouldn't be necessary, but we'll play safe. */
+ hwp->disablePalette(hwp);
+}
+
+/* Mandatory */
+static Bool
+CHIPSScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ CHIPSPtr cPtr;
+ CHIPSACLPtr cAcl;
+ int ret;
+ VisualPtr visual;
+ int allocatebase, freespace, currentaddr;
+ unsigned int racflag = 0;
+ unsigned char *FBStart;
+
+ /*
+ * we need to get the ScrnInfoRec for this screen, so let's allocate
+ * one first thing
+ */
+ pScrn = xf86Screens[pScreen->myNum];
+ cPtr = CHIPSPTR(pScrn);
+ cAcl = CHIPSACLPTR(pScrn);
+ hwp = VGAHWPTR(pScrn);
+ hwp->MapSize = 0x10000; /* Standard 64k VGA window */
+
+ /* Map the VGA memory */
+ if (!vgaHWMapMem(pScrn))
+ return FALSE;
+
+ /* Map the Chips memory and possible MMIO areas */
+ if (!chipsMapMem(pScrn))
+ return FALSE;
+
+ /* Setup a pointer to the overlay if needed */
+ if (cPtr->Flags & ChipsOverlay8plus16) {
+ cPtr->FbOffset16 = pScrn->displayWidth * pScrn->virtualY;
+ cPtr->FbSize16 = (pScrn->displayWidth << 1) * pScrn->virtualY;
+ if (cPtr->FbSize16 > (cPtr->FbMapSize - cPtr->FrameBufferSize)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Too little memory for overlay. Disabling.\n");
+ cPtr->Flags &= ~ChipsOverlay8plus16;
+ }
+ if ((pScrn->displayWidth > 1024) || (pScrn->virtualY > 1024)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Max overlay Width/Height 1024 pixels. Disabling.\n");
+ cPtr->Flags &= ~ChipsOverlay8plus16;
+ }
+ }
+
+ /* Setup the MMIO register access functions if need */
+ if (cPtr->UseFullMMIO) {
+ CHIPSSetMmioExtFuncs(cPtr);
+ CHIPSHWSetMmioFuncs(pScrn, cPtr->MMIOBase, 0x0);
+ }
+
+#if defined(__arm32__) && defined(__NetBSD__)
+ if (strcmp(pScrn->currentMode->name,"PAL") == 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using built-in PAL TV mode\n");
+ cPtr->TVMode = XMODE_PAL;
+ } else if (strcmp(pScrn->currentMode->name,"SECAM") == 0){
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using built-in SECAM TV mode\n");
+ cPtr->TVMode = XMODE_SECAM;
+ } else if (strcmp(pScrn->currentMode->name,"NTSC") == 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using built-in NTSC TV mode\n");
+ cPtr->TVMode = XMODE_NTSC;
+ } else
+ cPtr->TVMode = XMODE_RGB;
+#endif
+
+ /*xf86EnableAccess(pScrn);*/
+
+ /*
+ * next we save the current state and setup the first mode
+ */
+ chipsSave(pScrn);
+ if (!chipsModeInit(pScrn,pScrn->currentMode))
+ return FALSE;
+ CHIPSSaveScreen(pScreen,FALSE);
+ CHIPSAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+ if ((pScrn->bitsPerPixel == 16) && (cPtr->Flags & ChipsOverlay8plus16)){
+ if (!miSetVisualTypes(8, PseudoColorMask | GrayScaleMask,
+ pScrn->rgbBits, PseudoColor))
+ return FALSE;
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
+ TrueColor))
+ return FALSE;
+ } else if ((pScrn->depth > 8) && (!(cPtr->Flags & ChipsGammaSupport))) {
+ /*
+ * For bpp > 8, the default visuals are not acceptable because we only
+ * support TrueColor and not DirectColor. To deal with this, call
+ * miSetVisualTypes for each visual supported.
+ */
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
+ pScrn->defaultVisual))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+ if(cPtr->Flags & ChipsShadowFB) {
+ cPtr->ShadowPitch =
+ ((pScrn->virtualX * pScrn->bitsPerPixel >> 3) + 3) & ~3L;
+ cPtr->ShadowPtr = xalloc(cPtr->ShadowPitch * pScrn->virtualY);
+ FBStart = cPtr->ShadowPtr;
+ } else {
+ cPtr->ShadowPtr = NULL;
+ FBStart = cPtr->FbBase;
+ }
+
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ ret = xf1bppScreenInit(pScreen, FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 4:
+ ret = xf4bppScreenInit(pScreen, FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 8:
+ ret = cfbScreenInit(pScreen, FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 16:
+ if (cPtr->Flags & ChipsOverlay8plus16)
+ ret = cfb8_16ScreenInit(pScreen, (unsigned char *)FBStart +
+ cPtr->FbOffset16, FBStart, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth, pScrn->displayWidth);
+ else
+ ret = cfb16ScreenInit(pScreen, FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 24:
+ if (pix24bpp == 24)
+ ret = cfb24ScreenInit(pScreen, FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ else
+ ret = cfb24_32ScreenInit(pScreen, FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 32:
+ ret = cfb32ScreenInit(pScreen, FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in CHIPSScreenInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ if (!ret)
+ return FALSE;
+
+ if (pScrn->depth > 8) {
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ if ((cPtr->Flags & ChipsAccelSupport) && (pScrn->depth >= 8))
+ CHIPSDGAInit(pScreen);
+
+ cPtr->HWCursorShown = FALSE;
+
+ if (!(cPtr->Flags & ChipsLinearSupport)) {
+ miBankInfoPtr pBankInfo;
+
+ /* Setup the vga banking variables */
+ pBankInfo = (miBankInfoPtr)xnfcalloc(sizeof(miBankInfoRec),1);
+ if (pBankInfo == NULL)
+ return FALSE;
+
+#if defined(__arm32__)
+ cPtr->Bank = -1;
+#endif
+ pBankInfo->pBankA = hwp->Base;
+ pBankInfo->pBankB = (unsigned char *)hwp->Base + 0x08000;
+ pBankInfo->BankSize = 0x08000;
+ pBankInfo->nBankDepth = (pScrn->depth == 4) ? 1 : pScrn->depth;
+ xf86EnableAccess(pScrn);
+
+ if (IS_HiQV(cPtr)) {
+ pBankInfo->pBankB = hwp->Base;
+ pBankInfo->BankSize = 0x10000;
+ if (pScrn->bitsPerPixel < 8) {
+ pBankInfo->SetSourceBank =
+ (miBankProcPtr)CHIPSHiQVSetReadWritePlanar;
+ pBankInfo->SetDestinationBank =
+ (miBankProcPtr)CHIPSHiQVSetReadWritePlanar;
+ pBankInfo->SetSourceAndDestinationBanks =
+ (miBankProcPtr)CHIPSHiQVSetReadWritePlanar;
+ } else {
+ pBankInfo->SetSourceBank =
+ (miBankProcPtr)CHIPSHiQVSetReadWrite;
+ pBankInfo->SetDestinationBank =
+ (miBankProcPtr)CHIPSHiQVSetReadWrite;
+ pBankInfo->SetSourceAndDestinationBanks =
+ (miBankProcPtr)CHIPSHiQVSetReadWrite;
+ }
+ } else {
+ if (IS_Wingine(cPtr)) {
+ if (pScrn->bitsPerPixel < 8) {
+ pBankInfo->SetSourceBank =
+ (miBankProcPtr)CHIPSWINSetReadPlanar;
+ pBankInfo->SetDestinationBank =
+ (miBankProcPtr)CHIPSWINSetWritePlanar;
+ pBankInfo->SetSourceAndDestinationBanks =
+ (miBankProcPtr)CHIPSWINSetReadWritePlanar;
+ } else {
+ pBankInfo->SetSourceBank = (miBankProcPtr)CHIPSWINSetRead;
+ pBankInfo->SetDestinationBank =
+ (miBankProcPtr)CHIPSWINSetWrite;
+ pBankInfo->SetSourceAndDestinationBanks =
+ (miBankProcPtr)CHIPSWINSetReadWrite;
+ }
+ } else {
+ if (pScrn->bitsPerPixel < 8) {
+ pBankInfo->SetSourceBank =
+ (miBankProcPtr)CHIPSSetReadPlanar;
+ pBankInfo->SetDestinationBank =
+ (miBankProcPtr)CHIPSSetWritePlanar;
+ pBankInfo->SetSourceAndDestinationBanks =
+ (miBankProcPtr)CHIPSSetReadWritePlanar;
+ } else {
+ pBankInfo->SetSourceBank = (miBankProcPtr)CHIPSSetRead;
+ pBankInfo->SetDestinationBank =
+ (miBankProcPtr)CHIPSSetWrite;
+ pBankInfo->SetSourceAndDestinationBanks =
+ (miBankProcPtr)CHIPSSetReadWrite;
+ }
+ }
+ }
+ if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
+ pScrn->displayWidth, pBankInfo)) {
+ xfree(pBankInfo);
+ pBankInfo = NULL;
+ return FALSE;
+ }
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ /* Initialise cursor functions */
+ miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
+
+ } else {
+ /* !!! Only support linear addressing for now. This might change */
+ /* Setup pointers to free space in video ram */
+#define CHIPSALIGN(size, align) (currentaddr - ((currentaddr - size) & ~align))
+ allocatebase = (pScrn->videoRam<<10) - cPtr->FrameBufferSize;
+ if (pScrn->bitsPerPixel < 8)
+ freespace = allocatebase - pScrn->displayWidth *
+ pScrn->virtualY / 2;
+ else if ((pScrn->bitsPerPixel == 16) && (cPtr->Flags & ChipsOverlay8plus16))
+ freespace = allocatebase - pScrn->displayWidth *
+ pScrn->virtualY - cPtr->FbSize16;
+ else
+ freespace = allocatebase - pScrn->displayWidth *
+ pScrn->virtualY * (pScrn->bitsPerPixel >> 3);
+
+ currentaddr = allocatebase;
+ if (serverGeneration == 1)
+ xf86DrvMsg(scrnIndex, X_PROBED,
+ "%d bytes off-screen memory available\n", freespace);
+
+ /*
+ * Allocate video memory to store the hardware cursor. Allocate 1kB
+ * vram to the cursor, with 1kB alignment for 6554x's and 4kb alignment
+ * for 65550's. Wingine cursor is stored in registers and so no memory
+ * is needed.
+ */
+ if (cPtr->Flags & ChipsHWCursor) {
+ cAcl->CursorAddress = -1;
+ if (IS_HiQV(cPtr)) {
+ if (CHIPSALIGN(1024, 0xFFF) <= freespace) {
+ currentaddr -= CHIPSALIGN(1024, 0xFFF);
+ freespace -= CHIPSALIGN(1024, 0xFFF);
+ cAcl->CursorAddress = currentaddr;
+ }
+ } else if (IS_Wingine(cPtr)) {
+ cAcl->CursorAddress = 0;
+ } else if (CHIPSALIGN(1024, 0x3FF) <= freespace) {
+ currentaddr -= CHIPSALIGN(1024, 0x3FF);
+ freespace -= CHIPSALIGN(1024, 0x3FF);
+ cAcl->CursorAddress = currentaddr;
+ }
+ if (cAcl->CursorAddress == -1)
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Too little space for H/W cursor.\n");
+ }
+
+ /* Setup the acceleration primitives */
+ if (cPtr->Flags & ChipsAccelSupport) {
+ /*
+ * A scratch area is now allocated in the video ram. This is used
+ * at 8 and 16 bpp to simulate a planemask with a complex ROP, and
+ * at 24 and 32 bpp to aid in accelerating solid fills
+ */
+ cAcl->ScratchAddress = -1;
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ if (CHIPSALIGN(64, 0x3F) <= freespace) {
+ currentaddr -= CHIPSALIGN(64, 0x3F);
+ freespace -= CHIPSALIGN(64, 0x3F);
+ cAcl->ScratchAddress = currentaddr;
+ }
+ break;
+ case 16:
+ if (CHIPSALIGN(128, 0x7F) <= freespace) {
+ currentaddr -= CHIPSALIGN(128, 0x7F);
+ freespace -= CHIPSALIGN(128, 0x7F);
+ cAcl->ScratchAddress = currentaddr;
+ }
+ break;
+ case 24:
+ /* One scanline of data used for solid fill */
+ if (!IS_HiQV(cPtr)) {
+ if (CHIPSALIGN(3 * (pScrn->displayWidth + 4), 0x3)
+ <= freespace) {
+ currentaddr -= CHIPSALIGN(3 * (pScrn->displayWidth
+ + 4), 0x3);
+ freespace -= CHIPSALIGN(3 * (pScrn->displayWidth + 4),
+ 0x3);
+ cAcl->ScratchAddress = currentaddr;
+ }
+ }
+ break;
+ case 32:
+ /* 16bpp 8x8 mono pattern fill for solid fill. QWORD aligned */
+ if (IS_HiQV(cPtr)) {
+ if (CHIPSALIGN(8, 0x7) <= freespace) {
+ currentaddr -= CHIPSALIGN(8, 0x7);
+ freespace -= CHIPSALIGN(8, 0x7);
+ cAcl->ScratchAddress = currentaddr;
+ }
+ }
+ break;
+ }
+
+ /* Setup the boundaries of the pixmap cache */
+ cAcl->CacheStart = currentaddr - freespace;
+ cAcl->CacheEnd = currentaddr;
+
+ if (cAcl->CacheStart >= cAcl->CacheEnd) {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Too little space for pixmap cache.\n");
+ cAcl->CacheStart = 0;
+ cAcl->CacheEnd = 0;
+ }
+
+ if (IS_HiQV(cPtr)) {
+ cAcl->BltDataWindow = (unsigned char *)cPtr->MMIOBase +
+ 0x10000L;
+ } else {
+ cAcl->BltDataWindow = cPtr->FbBase;
+ }
+
+ if (IS_HiQV(cPtr)) {
+ CHIPSHiQVAccelInit(pScreen);
+ } else if (cPtr->UseMMIO) {
+ CHIPSMMIOAccelInit(pScreen);
+ } else {
+ CHIPSAccelInit(pScreen);
+ }
+ }
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ /* Initialise cursor functions */
+ miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
+
+ if ((cPtr->Flags & ChipsHWCursor) && (cAcl->CursorAddress != -1)) {
+ /* HW cursor functions */
+ if (!CHIPSCursorInit(pScreen)) {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ return FALSE;
+ }
+ }
+ }
+
+ if (cPtr->Flags & ChipsShadowFB)
+ ShadowFBInit(pScreen, chipsRefreshArea);
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ if ((cPtr->Flags & ChipsOverlay8plus16) && (pScrn->bitsPerPixel == 16)) {
+ if(!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, chipsLoadPalette,
+ NULL, CMAP_RELOAD_ON_MODE_SWITCH))
+ return FALSE;
+ } else if ((cPtr->Flags & ChipsGammaSupport) && (pScrn->depth > 8)) {
+ if(!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits,
+ (pScrn->depth == 16 ? chipsLoadPalette16 : chipsLoadPalette),
+ NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR))
+ return FALSE;
+ } else {
+ if (!vgaHWHandleColormaps(pScreen))
+ return FALSE;
+ }
+
+ if (pScrn->bitsPerPixel <= 8)
+ racflag = RAC_COLORMAP;
+ if (cPtr->Flags & ChipsHWCursor)
+ racflag |= RAC_CURSOR;
+ racflag |= (RAC_FB | RAC_VIEWPORT);
+ /* XXX Check if I/O and Mem flags need to be the same. */
+ pScrn->racIoFlags = pScrn->racMemFlags = racflag;
+
+ pScreen->SaveScreen = CHIPSSaveScreen;
+
+#ifdef DPMSExtension
+ /* Setup DPMS mode */
+ if (cPtr->Flags & ChipsDPMSSupport)
+ xf86DPMSInit(pScreen, (DPMSSetProcPtr)chipsDisplayPowerManagementSet,
+ 0);
+#endif
+
+ /* Wrap the current CloseScreen function */
+ cPtr->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = CHIPSCloseScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ return TRUE;
+}
+
+/* Mandatory */
+Bool
+CHIPSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ xf86EnableAccess(xf86Screens[scrnIndex]);
+ return chipsModeInit(xf86Screens[scrnIndex], mode);
+}
+
+/* Mandatory */
+void
+CHIPSAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn;
+ int Base;
+ CHIPSPtr cPtr;
+ vgaHWPtr hwp;
+ unsigned char tmp;
+
+ pScrn = xf86Screens[scrnIndex];
+ hwp = VGAHWPTR(pScrn);
+ cPtr = CHIPSPTR(pScrn);
+
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_SHOWCACHE, FALSE) && y) {
+ int lastline = cPtr->FbMapSize /
+ ((pScrn->displayWidth * pScrn->bitsPerPixel) / 8);
+ lastline -= pScrn->currentMode->VDisplay;
+ y += pScrn->virtualY - 1;
+ if (y > lastline) y = lastline;
+ }
+
+ Base = y * pScrn->displayWidth + x;
+
+ /* calculate base bpp dep. */
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ case 4:
+ Base >>= 3;
+ break;
+ case 16:
+ if (!(cPtr->Flags & ChipsOverlay8plus16))
+ Base >>= 1;
+ else
+ Base >>= 2;
+ break;
+ case 24:
+ if (!IS_HiQV(cPtr))
+ Base = (Base >> 2) * 3;
+ else
+ Base = (Base >> 3) * 6; /* 65550 seems to need 64bit alignment */
+ break;
+ case 32:
+ break;
+ default: /* 8bpp */
+ Base >>= 2;
+ break;
+ }
+
+ /* write base to chip */
+ /*
+ * These are the generic starting address registers.
+ */
+ xf86EnableAccess(pScrn);
+ chipsFixResume(pScrn);
+ hwp->writeCrtc(hwp, 0x0C, (Base & 0xFF00) >> 8);
+ hwp->writeCrtc(hwp, 0x0D, Base & 0xFF);
+ if (IS_HiQV(cPtr)) {
+ if (((cPtr->readXR(cPtr, 0x09)) & 0x1) == 0x1)
+ hwp->writeCrtc(hwp, 0x40, ((Base & 0x0F0000) >> 16) | 0x80);
+ } else {
+ tmp = cPtr->readXR(cPtr, 0x0C);
+ cPtr->writeXR(cPtr, 0x0C, ((Base & (IS_Wingine(cPtr) ? 0x0F0000 :
+ 0x030000)) >> 16) | (tmp & 0xF8));
+ }
+
+ if (cPtr->Flags & ChipsOverlay8plus16) {
+ Base = (Base << 3) & ~(unsigned long)0xF;
+
+ cPtr->writeMR(cPtr, 0x22, (cPtr->FbOffset16 + Base) & 0xF8);
+ cPtr->writeMR(cPtr, 0x23, ((cPtr->FbOffset16 + Base) >> 8) & 0xFF);
+ cPtr->writeMR(cPtr, 0x24, ((cPtr->FbOffset16 + Base) >> 16) & 0xFF);
+ }
+
+}
+
+/* Mandatory */
+static Bool
+CHIPSCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ if(pScrn->vtSema){ /*§§§*/
+ chipsHWCursorOff(cPtr);
+ chipsRestore(pScrn, &(VGAHWPTR(pScrn))->SavedReg, &cPtr->SavedReg, TRUE);
+ chipsLock(pScrn);
+ chipsUnmapMem(pScrn);
+ }
+ if (cPtr->AccelInfoRec)
+ XAADestroyInfoRec(cPtr->AccelInfoRec);
+ if (cPtr->CursorInfoRec)
+ xf86DestroyCursorInfoRec(cPtr->CursorInfoRec);
+ if (cPtr->ShadowPtr)
+ xfree(cPtr->ShadowPtr);
+ if (cPtr->DGAModes)
+ xfree(cPtr->DGAModes);
+ pScrn->vtSema = FALSE;
+ pScreen->CloseScreen = cPtr->CloseScreen; /*§§§*/
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);/*§§§*/
+}
+
+/* Optional */
+static void
+CHIPSFreeScreen(int scrnIndex, int flags)
+{
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ CHIPSFreeRec(xf86Screens[scrnIndex]);
+}
+
+/* Optional */
+static int
+CHIPSValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ /* The tests here need to be expanded */
+ if ((mode->Flags & V_INTERLACE) && (cPtr->Flags & ChipsLCD))
+ return MODE_BAD;
+
+ return MODE_OK;
+}
+
+#ifdef DPMSExtension
+/*
+ * DPMS Control registers
+ *
+ * XR73 6554x and 64300 (what about 65535?)
+ * XR61 6555x
+ * 0 HSync Powerdown data
+ * 1 HSync Select 1=Powerdown
+ * 2 VSync Powerdown data
+ * 3 VSync Select 1=Powerdown
+ */
+
+static void
+chipsDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
+ int flags)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char dpmsreg, seqreg, lcdoff, tmp;
+
+ xf86EnableAccess(pScrn);
+ switch (PowerManagementMode) {
+ case DPMSModeOn:
+ /* Screen: On; HSync: On, VSync: On */
+ dpmsreg = 0x00;
+ seqreg = 0x00;
+ lcdoff = 0x0;
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off; HSync: Off, VSync: On */
+ dpmsreg = 0x02;
+ seqreg = 0x20;
+ lcdoff = 0x0;
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off; HSync: On, VSync: Off */
+ dpmsreg = 0x08;
+ seqreg = 0x20;
+ lcdoff = 0x1;
+ break;
+ case DPMSModeOff:
+ /* Screen: Off; HSync: Off, VSync: Off */
+ dpmsreg = 0x0A;
+ seqreg = 0x20;
+ lcdoff = 0x1;
+ break;
+ default:
+ return;
+ }
+
+ seqreg |= hwp->readSeq(hwp, 0x01) & ~0x20;
+ hwp->writeSeq(hwp, 0x01, seqreg);
+ if (IS_HiQV(cPtr)) {
+ tmp = cPtr->readXR(cPtr, 0x61);
+ cPtr->writeXR(cPtr, 0x61, (tmp & 0xF0) | dpmsreg);
+ } else {
+ tmp = cPtr->readXR(cPtr, 0x73);
+ cPtr->writeXR(cPtr, 0x73, (tmp & 0xF0) | dpmsreg);
+ }
+
+ /* Turn off the flat panel */
+ if (cPtr->PanelType & ChipsLCD) {
+ if (IS_HiQV(cPtr)) {
+ tmp = cPtr->readFR(cPtr, 0x05);
+ if (lcdoff)
+ cPtr->writeFR(cPtr, 0x05, tmp | 0x08);
+ else
+ cPtr->writeFR(cPtr, 0x05, tmp & 0xF7);
+ } else {
+ tmp = cPtr->readXR(cPtr, 0x52);
+ if (lcdoff)
+ cPtr->writeXR(cPtr, 0x52, tmp | 0x08);
+ else
+ cPtr->writeXR(cPtr, 0x52, tmp & 0xF7);
+ }
+ }
+}
+#endif
+
+static Bool
+CHIPSSaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+ ScrnInfoPtr pScrn = NULL; /* §§§ */
+
+ if (pScreen != NULL)
+ pScrn = xf86Screens[pScreen->myNum];
+
+ if (unblank)
+ SetTimeSinceLastInputEvent();
+
+ if ((pScrn != NULL) && pScrn->vtSema) { /* §§§ */
+ xf86EnableAccess(pScrn);
+ chipsBlankScreen(pScrn, unblank);
+ }
+ return (TRUE);
+}
+
+static Bool
+chipsClockSelect(ScrnInfoPtr pScrn, int no)
+{
+ CHIPSClockReg TmpClock;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ switch (no) {
+ case CLK_REG_SAVE:
+ chipsClockSave(pScrn, &cPtr->SaveClock);
+ break;
+
+ case CLK_REG_RESTORE:
+ chipsClockLoad(pScrn, &cPtr->SaveClock);
+ break;
+
+ default:
+ if (!chipsClockFind(pScrn, no, &TmpClock))
+ return (FALSE);
+ chipsClockLoad(pScrn, &TmpClock);
+ }
+ return (TRUE);
+}
+
+/*
+ *
+ * Fout = (Fref * 4 * M) / (PSN * N * (1 << P) )
+ * Fvco = (Fref * 4 * M) / (PSN * N)
+ * where
+ * M = XR31+2
+ * N = XR32+2
+ * P = XR30[3:1]
+ * PSN = XR30[0]? 1:4
+ *
+ * constraints:
+ * 4 MHz <= Fref <= 20 MHz (typ. 14.31818 MHz)
+ * 150 kHz <= Fref/(PSN * N) <= 2 MHz
+ * 48 MHz <= Fvco <= 220 MHz
+ * 2 < M < 128
+ * 2 < N < 128
+ */
+
+static void
+chipsClockSave(ScrnInfoPtr pScrn, CHIPSClockPtr Clock)
+{
+ unsigned char tmp;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char Type = cPtr->ClockType;
+
+ Clock->msr = hwp->readMiscOut(hwp)&0xFE; /* save standard VGA clock reg */
+ switch (Type & GET_STYLE) {
+ case HiQV_STYLE:
+ Clock->fr03 = cPtr->readFR(cPtr, 0x03); /* save alternate clock select reg.*/
+ if (!Clock->Clock) { /* save HiQV console clock */
+ tmp = cPtr->CRTclkInx << 2;
+ cPtr->CRTClk[0] = cPtr->readXR(cPtr, 0xC0 + tmp);
+ cPtr->CRTClk[1] = cPtr->readXR(cPtr, 0xC1 + tmp);
+ cPtr->CRTClk[2] = cPtr->readXR(cPtr, 0xC2 + tmp);
+ cPtr->CRTClk[3] = cPtr->readXR(cPtr, 0xC3 + tmp);
+ tmp = cPtr->FPclkInx << 2;
+ cPtr->FPClk[0] = cPtr->readXR(cPtr, 0xC0 + tmp);
+ cPtr->FPClk[1] = cPtr->readXR(cPtr, 0xC1 + tmp);
+ cPtr->FPClk[2] = cPtr->readXR(cPtr, 0xC2 + tmp);
+ cPtr->FPClk[3] = cPtr->readXR(cPtr, 0xC3 + tmp);
+ }
+ break;
+ case OLD_STYLE:
+ Clock->fcr = cPtr->readFCR(cPtr);
+ Clock->xr02 = cPtr->readXR(cPtr, 0x02);
+ Clock->xr54 = cPtr->readXR(cPtr, 0x54); /* save alternate clock select reg.*/
+ break;
+ case WINGINE_1_STYLE:
+ case WINGINE_2_STYLE:
+ break;
+ case NEW_STYLE:
+ Clock->xr54 = cPtr->readXR(cPtr, 0x54); /* save alternate clock select reg.*/
+ Clock->xr33 = cPtr->readXR(cPtr, 0x33); /* get status of MCLK/VCLK sel reg.*/
+ break;
+ }
+#ifdef DEBUG
+ ErrorF("saved \n");
+#endif
+}
+
+static Bool
+chipsClockFind(ScrnInfoPtr pScrn, int no, CHIPSClockPtr Clock)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char Type = cPtr->ClockType;
+
+ if (no > (pScrn->numClocks - 1))
+ return (FALSE);
+
+ switch (Type & GET_STYLE) {
+ case HiQV_STYLE:
+ Clock->msr = cPtr->CRTclkInx << 2;
+ Clock->fr03 = cPtr->FPclkInx << 2;
+ Clock->Clock = pScrn->currentMode->Clock;
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_USE_MODELINE, FALSE)) {
+ Clock->FPClock = pScrn->currentMode->Clock;
+ } else
+ Clock->FPClock = cPtr->FPclock;
+ break;
+ case NEW_STYLE:
+ if (Type & TYPE_HW) {
+ Clock->msr = (no == 4 ? 3 << 2: (no & 0x01) << 2);
+ Clock->xr54 = Clock->msr;
+ Clock->xr33 = no > 1 ? 0x80 : 0;
+ } else {
+ Clock->msr = 3 << 2;
+ Clock->xr33 = 0;
+ Clock->xr54 = Clock->msr;
+ Clock->Clock = pScrn->currentMode->SynthClock;
+ }
+ break;
+ case OLD_STYLE:
+ if (no > 3) {
+ Clock->msr = 3 << 2;
+ Clock->fcr = no & 0x03;
+ Clock->xr02 = 0;
+ Clock->xr54 = Clock->msr & (Clock->fcr << 4);
+ } else {
+ Clock->msr = (no << 2) & 0x4;
+ Clock->fcr = 0;
+ Clock->xr02 = no & 0x02;
+ Clock->xr54 = Clock->msr;
+ }
+ break;
+ case WINGINE_1_STYLE:
+ Clock->msr = no << 2;
+ case WINGINE_2_STYLE:
+ if (Type & TYPE_HW) {
+ Clock->msr = (no == 2 ? 3 << 2: (no & 0x01) << 2);
+ Clock->xr33 = 0;
+ } else {
+ Clock->msr = 3 << 2;
+ Clock->xr33 = 0;
+ Clock->Clock = pScrn->currentMode->SynthClock;
+ }
+ break;
+ }
+ Clock->msr |= (hwp->readMiscOut(hwp) & 0xF2);
+
+#ifdef DEBUG
+ ErrorF("found\n");
+#endif
+ return (TRUE);
+}
+
+static int
+chipsGetHWClock(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char Type = cPtr->ClockType;
+ unsigned char tmp, tmp1;
+
+ if (!(Type & TYPE_HW))
+ return 0; /* shouldn't happen */
+
+ switch (Type & GET_STYLE) {
+ case WINGINE_1_STYLE:
+ return ((hwp->readMiscOut(hwp) & 0x0C) >> 2);
+ case WINGINE_2_STYLE:
+ tmp = ((hwp->readMiscOut(hwp) & 0x04) >> 2);
+ return (tmp > 2) ? 2 : tmp;
+ case OLD_STYLE:
+ if (!(cPtr->PanelType & ChipsLCD))
+ tmp = hwp->readMiscOut(hwp);
+ else
+ tmp = cPtr->readXR(cPtr, 0x54);
+ if (tmp & 0x08) {
+ if (!(cPtr->PanelType & ChipsLCD))
+ tmp = cPtr->readFCR(cPtr) & 0x03;
+ else
+ tmp = (tmp >> 4) & 0x03;
+ return (tmp + 4);
+ } else {
+ tmp = (tmp >> 2) & 0x01;
+ tmp1 = cPtr->readXR(cPtr, 0x02);
+ return (tmp + (tmp1 & 0x02));
+ }
+ case NEW_STYLE:
+ if (cPtr->PanelType & ChipsLCD) {
+ tmp = cPtr->readXR(cPtr, 0x54);
+ } else
+ tmp = hwp->readMiscOut(hwp);
+ tmp = (tmp & 0x0C) >> 2;
+ if (tmp > 1) return 4;
+ tmp1 = cPtr->readXR(cPtr, 0x33);
+ tmp1 = (tmp1 & 0x80) >> 6; /* iso mode 25.175/28.322 or 32/36 MHz */
+ return (tmp + tmp1); /* ^=0 ^=1 ^=4 ^=5 */
+ default: /* we should never get here */
+ return (0);
+ }
+}
+
+static void
+chipsClockLoad(ScrnInfoPtr pScrn, CHIPSClockPtr Clock)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char Type = cPtr->ClockType;
+ volatile unsigned char tmp, tmpmsr, tmpfcr, tmp02;
+ volatile unsigned char tmp33, tmp54, tmpf03;
+ unsigned char vclk[3];
+
+ tmpmsr = hwp->readMiscOut(hwp); /* read msr, needed for all styles */
+
+ switch (Type & GET_STYLE) {
+ case HiQV_STYLE:
+ tmpf03 = cPtr->readFR(cPtr, 0x03); /* save alternate clock select reg. */
+ /* select fixed clock 0 before tampering with VCLK select */
+ hwp->writeMiscOut(hwp, (tmpmsr & ~0x0D) |
+ cPtr->SuspendHack.vgaIOBaseFlag);
+ cPtr->writeFR(cPtr, 0x03, (tmpf03 & ~0x0C) | 0x04);
+ if (!Clock->Clock) { /* Hack to load saved console clock */
+ tmp = cPtr->CRTclkInx << 2;
+ cPtr->writeXR(cPtr, 0xC0 + tmp, (cPtr->CRTClk[0] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC1 + tmp, (cPtr->CRTClk[1] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC2 + tmp, (cPtr->CRTClk[2] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC3 + tmp, (cPtr->CRTClk[3] & 0xFF));
+
+ if (cPtr->FPClkModified) {
+ usleep(10000); /* let VCO stabilize */
+ tmp = cPtr->FPclkInx << 2;
+ cPtr->writeXR(cPtr, 0xC0 + tmp, (cPtr->FPClk[0] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC1 + tmp, (cPtr->FPClk[1] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC2 + tmp, (cPtr->FPClk[2] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC3 + tmp, (cPtr->FPClk[3] & 0xFF));
+ }
+ } else {
+ /*
+ * Don't use the extra 2 bits in the M, N registers available
+ * on the HiQV, so write zero to 0xCA
+ */
+ chipsCalcClock(pScrn, Clock->Clock, vclk);
+ tmp = cPtr->CRTclkInx << 2;
+ cPtr->writeXR(cPtr, 0xC0 + tmp, (vclk[1] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC1 + tmp, (vclk[2] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC2 + tmp, 0x0);
+ cPtr->writeXR(cPtr, 0xC3 + tmp, (vclk[0] & 0xFF));
+ if (Clock->FPClock) {
+ usleep(10000); /* let VCO stabilize */
+ chipsCalcClock(pScrn, Clock->FPClock, vclk);
+ tmp = cPtr->FPclkInx << 2;
+ cPtr->writeXR(cPtr, 0xC0 + tmp, (vclk[1] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC1 + tmp, (vclk[2] & 0xFF));
+ cPtr->writeXR(cPtr, 0xC2 + tmp, 0x0);
+ cPtr->writeXR(cPtr, 0xC3 + tmp, (vclk[0] & 0xFF));
+ cPtr->FPClkModified = TRUE;
+ }
+ }
+ usleep(10000); /* Let VCO stabilise */
+ cPtr->writeFR(cPtr, 0x03, ((tmpf03 & ~0x0C) | (Clock->fr03 & 0x0C)));
+ break;
+ case WINGINE_1_STYLE:
+ break;
+ case WINGINE_2_STYLE:
+ /* Only write to soft clock registers if we really need to */
+ if ((Type & GET_TYPE) == TYPE_PROGRAMMABLE) {
+ /* select fixed clock 0 before tampering with VCLK select */
+ hwp->writeMiscOut(hwp, (tmpmsr & ~0x0D) |
+ cPtr->SuspendHack.vgaIOBaseFlag);
+ chipsCalcClock(pScrn, Clock->Clock, vclk);
+ tmp33 = cPtr->readXR(cPtr, 0x33); /* get status of MCLK/VCLK select reg */
+ cPtr->writeXR(cPtr, 0x33, tmp33 & ~0x20);
+ cPtr->writeXR(cPtr, 0x30, vclk[0]);
+ cPtr->writeXR(cPtr, 0x31, vclk[1]); /* restore VCLK regs. */
+ cPtr->writeXR(cPtr, 0x32, vclk[2]);
+ /* cPtr->writeXR(cPtr, 0x33, tmp33 & ~0x20);*/
+ usleep(10000); /* Let VCO stabilise */
+ }
+ break;
+ case OLD_STYLE:
+ tmp02 = cPtr->readXR(cPtr, 0x02);
+ tmp54 = cPtr->readXR(cPtr, 0x54);
+ tmpfcr = cPtr->readFCR(cPtr);
+ cPtr->writeXR(cPtr, 0x02, ((tmp02 & ~0x02) | (Clock->xr02 & 0x02)));
+ cPtr->writeXR(cPtr, 0x54, ((tmp54 & 0xF0) | (Clock->xr54 & ~0xF0)));
+ cPtr->writeFCR(cPtr, (tmpfcr & ~0x03) & Clock->fcr);
+ break;
+ case NEW_STYLE:
+ tmp33 = cPtr->readXR(cPtr, 0x33); /* get status of MCLK/VCLK select reg */
+ tmp54 = cPtr->readXR(cPtr, 0x54);
+ /* Only write to soft clock registers if we really need to */
+ if ((Type & GET_TYPE) == TYPE_PROGRAMMABLE) {
+ /* select fixed clock 0 before tampering with VCLK select */
+ hwp->writeMiscOut(hwp, (tmpmsr & ~0x0D) |
+ cPtr->SuspendHack.vgaIOBaseFlag);
+ cPtr->writeXR(cPtr, 0x54, (tmp54 & 0xF3));
+ chipsCalcClock(pScrn, Clock->Clock, vclk);
+ cPtr->writeXR(cPtr, 0x33, tmp33 & ~0x20);
+ cPtr->writeXR(cPtr, 0x30, vclk[0]);
+ cPtr->writeXR(cPtr, 0x31, vclk[1]); /* restore VCLK regs. */
+ cPtr->writeXR(cPtr, 0x32, vclk[2]);
+ /* cPtr->writeXR(cPtr, 0x33, tmp33 & ~0x20);*/
+ usleep(10000); /* Let VCO stabilise */
+ }
+ cPtr->writeXR(cPtr, 0x33, ((tmp33 & ~0x80) | (Clock->xr33 & 0x80)));
+ cPtr->writeXR(cPtr, 0x54, ((tmp54 & 0xF3) | (Clock->xr54 & ~0xF3)));
+ break;
+ }
+ hwp->writeMiscOut(hwp, (Clock->msr & 0xFE) |
+ cPtr->SuspendHack.vgaIOBaseFlag);
+#ifdef DEBUG
+ ErrorF("restored\n");
+#endif
+}
+
+/*
+ * This is Ken Raeburn's <raeburn@raeburn.org> clock
+ * calculation code just modified a little bit to fit in here.
+ */
+
+static void
+chipsCalcClock(ScrnInfoPtr pScrn, int Clock, unsigned char *vclk)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ int M, N, P, PSN, PSNx;
+
+ int bestM = 0, bestN = 0, bestP = 0, bestPSN = 0;
+ double bestError, abest = 42, bestFout = 0;
+ double target;
+
+ double Fvco, Fout;
+ double error, aerror;
+
+ int M_min = 3;
+
+ /* Hack to deal with problem of Toshiba 720CDT clock */
+ int M_max = IS_HiQV(cPtr) ? 63 : 127;
+
+
+ /* Other parameters available on the 65548 but not the 65545, and
+ * not documented in the Clock Synthesizer doc in rev 1.0 of the
+ * 65548 datasheet:
+ *
+ * + XR30[4] = 0, VCO divider loop uses divide by 4 (same as 65545)
+ * 1, VCO divider loop uses divide by 16
+ *
+ * + XR30[5] = 1, reference clock is divided by 5
+ *
+ * Other parameters available on the 65550 and not on the 65545
+ *
+ * + XRCB[2] = 0, VCO divider loop uses divide by 4 (same as 65545)
+ * 1, VCO divider loop uses divide by 16
+ *
+ * + XRCB[1] = 1, reference clock is divided by 5
+ *
+ * + XRCB[7] = Vclk = Mclk
+ *
+ * + XRCA[0:1] = 2 MSB of a 10 bit M-Divisor
+ *
+ * + XRCA[4:5] = 2 MSB of a 10 bit N-Divisor
+ *
+ * I haven't put in any support for those here. For simplicity,
+ * they should be set to 0 on the 65548, and left untouched on
+ * earlier chips. */
+
+ target = Clock * 1000;
+
+ for (PSNx = 0; PSNx <= 1; PSNx++) {
+ int low_N, high_N;
+ double Fref4PSN;
+
+ PSN = PSNx ? 1 : 4;
+
+ low_N = 3;
+ high_N = 127;
+
+ while (Fref / (PSN * low_N) > 2.0e6)
+ low_N++;
+ while (Fref / (PSN * high_N) < 150.0e3)
+ high_N--;
+
+ Fref4PSN = Fref * 4 / PSN;
+ for (N = low_N; N <= high_N; N++) {
+ double tmp = Fref4PSN / N;
+
+ for (P = IS_HiQV(cPtr) ? 1 : 0; P <= 5; P++) {
+ /* to force post divisor on Toshiba 720CDT */
+ double Fvco_desired = target * (1 << P);
+ double M_desired = Fvco_desired / tmp;
+
+ /* Which way will M_desired be rounded? Do all three just to
+ * be safe. */
+ int M_low = M_desired - 1;
+ int M_hi = M_desired + 1;
+
+ if (M_hi < M_min || M_low > M_max)
+ continue;
+
+ if (M_low < M_min)
+ M_low = M_min;
+ if (M_hi > M_max)
+ M_hi = M_max;
+
+ for (M = M_low; M <= M_hi; M++) {
+ Fvco = tmp * M;
+ if (Fvco <= 48.0e6)
+ continue;
+ if (Fvco > 220.0e6)
+ break;
+
+ Fout = Fvco / (1 << P);
+
+ error = (target - Fout) / target;
+
+ aerror = (error < 0) ? -error : error;
+ if (aerror < abest) {
+ abest = aerror;
+ bestError = error;
+ bestM = M;
+ bestN = N;
+ bestP = P;
+ bestPSN = PSN;
+ bestFout = Fout;
+ }
+ }
+ }
+ }
+ }
+ vclk[0] = (bestP << (IS_HiQV(cPtr) ? 4 : 1)) + (bestPSN == 1);
+ vclk[1] = bestM - 2;
+ vclk[2] = bestN - 2;
+#ifdef DEBUG
+ ErrorF("Freq. selected: %.2f MHz, vclk[0]=%X, vclk[1]=%X, vclk[2]=%X\n",
+ (float)(Clock / 1000.), vclk[0], vclk[1], vclk[2]);
+ ErrorF("Freq. set: %.2f MHz\n", bestFout / 1.0e6);
+#endif
+}
+
+static void
+chipsSave(ScrnInfoPtr pScrn)
+{
+ vgaRegPtr VgaSave = &VGAHWPTR(pScrn)->SavedReg;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSRegPtr ChipsSave;
+ int i;
+ unsigned char tmp;
+
+ ChipsSave = &cPtr->SavedReg;
+
+ /* set registers that we can program the controller */
+ /* bank 0 */
+ if (IS_HiQV(cPtr)) {
+ cPtr->writeXR(cPtr, 0x0E, 0x00);
+ } else {
+ cPtr->writeXR(cPtr, 0x10, 0x00);
+ cPtr->writeXR(cPtr, 0x11, 0x00);
+ tmp = cPtr->readXR(cPtr, 0x0C) & ~0x50; /* WINgine stores MSB here */
+ cPtr->writeXR(cPtr, 0x0C, tmp);
+ }
+ chipsFixResume(pScrn);
+ tmp = cPtr->readXR(cPtr, 0x02);
+ cPtr->writeXR(cPtr, 0x02, tmp & ~0x18);
+
+ /* get generic registers */
+ vgaHWSave(pScrn, VgaSave, VGA_SR_ALL);
+
+ /* save clock */
+ chipsClockSave(pScrn, &ChipsSave->Clock);
+
+ /* save extended registers */
+ if (IS_HiQV(cPtr)) {
+ for (i = 0; i < 0xFF; i++) {
+ ChipsSave->XR[i] = cPtr->readXR(cPtr, i);
+#ifdef DEBUG
+ ErrorF("XS%X - %X\n", i, ChipsSave->XR[i]);
+#endif
+ }
+ for (i = 0; i < 0x80; i++) {
+ ChipsSave->FR[i] = cPtr->readFR(cPtr, i);
+#ifdef DEBUG
+ ErrorF("FS%X - %X\n", i, ChipsSave->FR[i]);
+#endif
+ }
+ for (i = 0; i < 0x80; i++) {
+ /* Save SAR04 multimedia register correctly */
+ if (i == 0x4F) {
+ cPtr->writeXR(cPtr, 0x4E, 0x04);
+ ChipsSave->MR[i] = cPtr->readMR(cPtr, i);
+ } else
+ ChipsSave->MR[i] = cPtr->readMR(cPtr, i);
+#ifdef DEBUG
+ ErrorF("MS%X - %X\n", i, ChipsSave->FR[i]);
+#endif
+ }
+ /* Save CR0-CR40 even though we don't use them, so they can be
+ * printed */
+ for (i = 0x0; i < 0x80; i++) {
+ ChipsSave->CR[i] = hwp->readCrtc(hwp, i);
+#ifdef DEBUG
+ ErrorF("CS%X - %X\n", i, ChipsSave->CR[i]);
+#endif
+ }
+ } else {
+ for (i = 0; i < 0x7D; i++) { /* don't touch XR7D and XR7F on WINGINE */
+ ChipsSave->XR[i] = cPtr->readXR(cPtr, i);
+#ifdef DEBUG
+ ErrorF("XS%X - %X\n", i, ChipsSave->XR[i]);
+#endif
+ }
+ }
+}
+
+static Bool
+chipsModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ chipsUnlock(pScrn);
+ chipsFixResume(pScrn);
+
+ if (IS_HiQV(cPtr))
+ return chipsModeInitHiQV(pScrn, mode);
+ else if (IS_Wingine(cPtr))
+ return chipsModeInitWingine(pScrn, mode);
+ else
+ return chipsModeInit655xx(pScrn, mode);
+}
+
+/*
+ * The timing register of the C&T FP chipsets are organized
+ * as follows:
+ * The chipsets have two sets of timing registers:
+ * the standard horizontal and vertical timing registers for
+ * display size, blank start, sync start, sync end, blank end
+ * and total size at their default VGA locations and extensions
+ * and the alternate horizontal and vertical timing registers for
+ * display size, sync start, sync end and total size.
+ * In LCD and mixed (LCD+CRT) mode the alternate timing registers
+ * control the timing. The alternate horizontal and vertical display
+ * size registers are set to the physical pixel size of the display.
+ * Normally the alternalte registers are set by the BIOS to optimized
+ * values.
+ * While the horizontal an vertical refresh rates are fixed independent
+ * of the visible display size to enshure optimal performace of both
+ * displays they can be adapted to the screen resolution and CRT
+ * requirements in CRT mode by programming the standard timing registers
+ * in the VGA fashion.
+ * In LCD and mixed mode the _standard_ horizontal and vertical display
+ * size registers control the size of the _visible_ part of the display
+ * in contast to the _physical_ size of the display which is specified
+ * by the _alternate_ horizontal and vertical display size registers.
+ * The size of the visible should always be equal or less than the
+ * physical size.
+ */
+static Bool
+chipsModeInitHiQV(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ int i;
+ int lcdHTotal, lcdHDisplay;
+ int lcdVTotal, lcdVDisplay;
+ int lcdHRetraceStart, lcdHRetraceEnd;
+ int lcdVRetraceStart, lcdVRetraceEnd;
+ int lcdHSyncStart;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSRegPtr ChipsNew;
+ vgaRegPtr ChipsStd;
+ unsigned int tmp;
+ int OverlaySkewX, OverlaySkewY;
+
+ ChipsNew = &cPtr->ModeReg;
+ ChipsStd = &hwp->ModeReg;
+
+ /*
+ * Possibly fix up the panel size, if the manufacture is stupid
+ * enough to set it incorrectly in text modes
+ */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE)) {
+ cPtr->PanelSize.HDisplay = mode->CrtcHDisplay;
+ cPtr->PanelSize.VDisplay = mode->CrtcVDisplay;
+ }
+
+ /* generic init */
+ if (!vgaHWInit(pScrn, mode)) {
+ ErrorF("bomb 1\n");
+ return (FALSE);
+ }
+ pScrn->vtSema = TRUE;
+
+ /* init clock */
+ if (!chipsClockFind(pScrn, mode->ClockIndex, &ChipsNew->Clock)) {
+ ErrorF("bomb 2\n");
+ return (FALSE);
+ }
+
+ /* get C&T Specific Registers */
+ for (i = 0; i < 0xFF; i++) {
+ ChipsNew->XR[i] = cPtr->readXR(cPtr, i);
+ }
+ for (i = 0; i < 0x80; i++) {
+ ChipsNew->FR[i] = cPtr->readFR(cPtr, i);
+ }
+ for (i = 0; i < 0x80; i++) {
+ /* Save SAR04 multimedia register correctly */
+ if (i == 0x4F) {
+ cPtr->writeXR(cPtr, 0x4E, 0x04);
+ ChipsNew->MR[i] = cPtr->readMR(cPtr, i);
+ } else
+ ChipsNew->MR[i] = cPtr->readMR(cPtr, i);
+ }
+ for (i = 0x30; i < 0x80; i++) { /* These are the CT extended CRT regs */
+ ChipsNew->CR[i] = hwp->readCrtc(hwp, i);
+ }
+
+ /*
+ * Here all of the other fields of 'ChipsNew' get filled in, to
+ * handle the SVGA extended registers. It is also allowable
+ * to override generic registers whenever necessary.
+ */
+
+ /* some generic settings */
+ if (pScrn->depth == 1) {
+ ChipsStd->Attribute[0x10] = 0x03; /* mode */
+ } else {
+ ChipsStd->Attribute[0x10] = 0x01; /* mode */
+ }
+ if ((pScrn->bitsPerPixel == 16) && (cPtr->Flags & ChipsOverlay8plus16)) {
+ /* Make sure that the overlay isn't visible in the overscan region */
+ if (ChipsStd->Attribute[0x11] == pScrn->colorKey)
+ ChipsStd->Attribute[0x11] = pScrn->colorKey - 1;
+ } else
+ ChipsStd->Attribute[0x11] = 0x00; /* overscan (border) color */
+ ChipsStd->Attribute[0x12] = 0x0F; /* enable all color planes */
+ ChipsStd->Attribute[0x13] = 0x00; /* horiz pixel panning 0 */
+
+ ChipsStd->Graphics[0x05] = 0x00; /* normal read/write mode */
+
+ /* set virtual screen width */
+ tmp = pScrn->displayWidth >> 3;
+ if (pScrn->bitsPerPixel == 16) {
+ if (!(cPtr->Flags & ChipsOverlay8plus16))
+ tmp <<= 1; /* double the width of the buffer */
+ } else if (pScrn->bitsPerPixel == 24) {
+ tmp += tmp << 1;
+ } else if (pScrn->bitsPerPixel == 32) {
+ tmp <<= 2;
+ } else if (pScrn->bitsPerPixel < 8) {
+ tmp >>= 1;
+ }
+ ChipsStd->CRTC[0x13] = tmp & 0xFF;
+ ChipsNew->CR[0x41] = (tmp >> 8) & 0x0F;
+
+ /* Set paging mode on the HiQV32 architecture, if required */
+ if (!(cPtr->Flags & ChipsLinearSupport) || (pScrn->bitsPerPixel < 8))
+ ChipsNew->XR[0x0A] |= 0x1;
+
+ ChipsNew->XR[0x09] |= 0x1; /* Enable extended CRT registers */
+ ChipsNew->XR[0x0E] = 0; /* Single map */
+ ChipsNew->XR[0x40] |= 0x2; /* Don't wrap at 256kb */
+ ChipsNew->XR[0x81] &= 0xF8;
+ if (pScrn->bitsPerPixel >= 8) {
+ ChipsNew->XR[0x40] |= 0x1; /* High Resolution. XR40[1] reserved? */
+ ChipsNew->XR[0x81] |= 0x2; /* 256 Color Video */
+ }
+ ChipsNew->XR[0x80] |= 0x10; /* Enable cursor output on P0 and P1 */
+
+ if (abs(cPtr->MemClock.Clk - cPtr->MemClock.ProbedClk) > 50) {
+ /* set mem clk */
+ ChipsNew->XR[0xCC] = cPtr->MemClock.xrCC;
+ ChipsNew->XR[0xCD] = cPtr->MemClock.xrCD;
+ ChipsNew->XR[0xCE] = cPtr->MemClock.xrCE;
+ }
+
+ /* linear specific */
+ if (cPtr->Flags & ChipsLinearSupport) {
+ ChipsNew->XR[0x0A] |= 0x02; /* Linear Addressing Mode */
+ ChipsNew->XR[0x20] = 0x0; /*BitBLT Draw Mode for 8 */
+ ChipsNew->XR[0x05] =
+ (unsigned char)((cPtr->FbAddress >> 16) & 0xFF);
+ ChipsNew->XR[0x06] =
+ (unsigned char)((cPtr->FbAddress >> 24) & 0xFF);
+ }
+
+ /* panel timing */
+ /* By default don't set panel timings, but allow it as an option */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_USE_MODELINE, FALSE)) {
+ lcdHTotal = (mode->CrtcHTotal >> 3) - 5;
+ lcdHDisplay = (cPtr->PanelSize.HDisplay >> 3) - 1;
+ lcdHRetraceStart = (mode->CrtcHSyncStart >> 3);
+ lcdHRetraceEnd = (mode->CrtcHSyncEnd >> 3);
+ lcdHSyncStart = lcdHRetraceStart - 2;
+
+ lcdVTotal = mode->CrtcVTotal - 2;
+ lcdVDisplay = cPtr->PanelSize.VDisplay - 1;
+ lcdVRetraceStart = mode->CrtcVSyncStart;
+ lcdVRetraceEnd = mode->CrtcVSyncEnd;
+
+ ChipsNew->FR[0x20] = lcdHDisplay & 0xFF;
+ ChipsNew->FR[0x21] = lcdHRetraceStart & 0xFF;
+ ChipsNew->FR[0x25] = ((lcdHRetraceStart & 0xF00) >> 4) |
+ ((lcdHDisplay & 0xF00) >> 8);
+ ChipsNew->FR[0x22] = lcdHRetraceEnd & 0x1F;
+ ChipsNew->FR[0x23] = lcdHTotal & 0xFF;
+ ChipsNew->FR[0x24] = (lcdHSyncStart >> 3) & 0xFF;
+ ChipsNew->FR[0x26] = (ChipsNew->FR[0x26] & ~0x1F)
+ | ((lcdHTotal & 0xF00) >> 8)
+ | (((lcdHSyncStart >> 3) & 0x100) >> 4);
+ ChipsNew->FR[0x27] &= 0x7F;
+
+ ChipsNew->FR[0x30] = lcdVDisplay & 0xFF;
+ ChipsNew->FR[0x31] = lcdVRetraceStart & 0xFF;
+ ChipsNew->FR[0x35] = ((lcdVRetraceStart & 0xF00) >> 4)
+ | ((lcdVDisplay & 0xF00) >> 8);
+ ChipsNew->FR[0x32] = lcdVRetraceEnd & 0x0F;
+ ChipsNew->FR[0x33] = lcdVTotal & 0xFF;
+ ChipsNew->FR[0x34] = (lcdVTotal - lcdVRetraceStart) & 0xFF;
+ ChipsNew->FR[0x36] = ((lcdVTotal & 0xF00) >> 8) |
+ (((lcdVTotal - lcdVRetraceStart) & 0x700) >> 4);
+ ChipsNew->FR[0x37] |= 0x80;
+ }
+
+ /* Set up the extended CRT registers of the HiQV32 chips */
+ ChipsNew->CR[0x30] = ((mode->CrtcVTotal - 2) & 0xF00) >> 8;
+ ChipsNew->CR[0x31] = ((mode->CrtcVDisplay - 1) & 0xF00) >> 8;
+ ChipsNew->CR[0x32] = (mode->CrtcVSyncStart & 0xF00) >> 8;
+ ChipsNew->CR[0x33] = (mode->CrtcVBlankStart & 0xF00) >> 8;
+ if ((cPtr->Chipset == CHIPS_CT69000) || (cPtr->Chipset == CHIPS_CT69030)) {
+ /* The 690xx has overflow bits for the horizontal values as well */
+ ChipsNew->CR[0x38] = (((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8;
+ ChipsNew->CR[0x3C] = ((mode->CrtcHSyncEnd >> 3) & 0xC0);
+ }
+ ChipsNew->CR[0x40] |= 0x80;
+
+ /* centering/stretching */
+ if (!xf86ReturnOptValBool(cPtr->Options, OPTION_SUSPEND_HACK, FALSE)) {
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_STRETCH, FALSE) ||
+ (cPtr->Flags & ChipsOverlay8plus16)) {
+ ChipsNew->FR[0x40] &= 0xDF; /* Disable Horizontal stretching */
+ ChipsNew->FR[0x48] &= 0xFB; /* Disable vertical stretching */
+ ChipsNew->XR[0xA0] = 0x10; /* Disable cursor stretching */
+ cPtr->Accel.UseHWCursor = TRUE;
+ } else {
+ ChipsNew->FR[0x40] |= 0x21; /* Enable Horizontal stretching */
+ ChipsNew->FR[0x48] |= 0x05; /* Enable vertical stretching */
+ ChipsNew->XR[0xA0] = 0x70; /* Enable cursor stretching */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_HW_CURSOR, FALSE))
+ cPtr->Accel.UseHWCursor = TRUE; /* H/W cursor forced */
+ else {
+ if ((cPtr->PanelSize.HDisplay != mode->CrtcHDisplay) &&
+ (cPtr->PanelSize.VDisplay != mode->CrtcVDisplay)) {
+ if(cPtr->Accel.UseHWCursor)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling HW Cursor on stretched LCD\n");
+ cPtr->Accel.UseHWCursor = FALSE; /* Possible H/W bug? */
+ }
+ }
+ }
+ }
+
+ if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_CENTER, FALSE)) {
+ ChipsNew->FR[0x40] &= 0xFD; /* Disable Horizontal centering */
+ ChipsNew->FR[0x48] &= 0xFD; /* Disable Vertical centering */
+ } else {
+ ChipsNew->FR[0x40] |= 0x3; /* Enable Horizontal centering */
+ ChipsNew->FR[0x48] |= 0x3; /* Enable Vertical centering */
+ }
+
+ /* sync on green */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_SYNC_ON_GREEN, FALSE))
+ ChipsNew->XR[0x82] |=0x02;
+
+ /* software mode flag */
+ ChipsNew->XR[0xE2] = chipsVideoMode(((cPtr->Flags & ChipsOverlay8plus16) ?
+ 8 : pScrn->bitsPerPixel),
+ pScrn->weight.green, (cPtr->PanelType & ChipsLCD) ?
+ min(mode->CrtcHDisplay, cPtr->PanelSize.HDisplay) :
+ mode->CrtcHDisplay, mode->CrtcVDisplay);
+#ifdef DEBUG
+ ErrorF("VESA Mode: %Xh\n", ChipsNew->XR[0xE2]);
+#endif
+
+ /* sync. polarities */
+ if ((mode->Flags & (V_PHSYNC | V_NHSYNC))
+ && (mode->Flags & (V_PVSYNC | V_NVSYNC))) {
+ if (mode->Flags & (V_PHSYNC | V_NHSYNC)) {
+ if (mode->Flags & V_PHSYNC)
+ ChipsNew->FR[0x08] &= 0xBF; /* Alt. CRT Hsync positive */
+ else
+ ChipsNew->FR[0x08] |= 0x40; /* Alt. CRT Hsync negative */
+ }
+ if (mode->Flags & (V_PVSYNC | V_NVSYNC)) {
+ if (mode->Flags & V_PVSYNC)
+ ChipsNew->FR[0x08] &= 0x7F; /* Alt. CRT Vsync positive */
+ else
+ ChipsNew->FR[0x08] |= 0x80; /* Alt. CRT Vsync negative */
+ }
+ }
+
+ /* bpp depend */
+ if ((pScrn->bitsPerPixel == 16) && (!(cPtr->Flags & ChipsOverlay8plus16))) {
+ ChipsNew->XR[0x81] = (ChipsNew->XR[0x81] & 0xF0) | 0x4;
+ if (cPtr->Flags & ChipsGammaSupport)
+ ChipsNew->XR[0x82] |= 0x0C;
+ /* 16bpp = 5-5-5 */
+ ChipsNew->FR[0x10] |= 0x0C; /*Colour Panel */
+ ChipsNew->XR[0x20] = 0x10; /*BitBLT Draw Mode for 16 bpp */
+ if (pScrn->weight.green != 5)
+ ChipsNew->XR[0x81] |= 0x01; /*16bpp */
+ } else if (pScrn->bitsPerPixel == 24) {
+ ChipsNew->XR[0x81] = (ChipsNew->XR[0x81] & 0xF0) | 0x6;
+ if (cPtr->Flags & ChipsGammaSupport)
+ ChipsNew->XR[0x82] |= 0x0C;
+ /* 24bpp colour */
+ ChipsNew->XR[0x20] = 0x20; /*BitBLT Draw Mode for 24 bpp */
+ } else if (pScrn->bitsPerPixel == 32) {
+ ChipsNew->XR[0x81] = (ChipsNew->XR[0x81] & 0xF0) | 0x7;
+ if (cPtr->Flags & ChipsGammaSupport)
+ ChipsNew->XR[0x82] |= 0x0C;
+ /* 32bpp colour */
+ ChipsNew->XR[0x20] = 0x10; /*BitBLT Mode for 16bpp used at 32bpp */
+ }
+
+ /*CRT only */
+ if (!(cPtr->PanelType & ChipsLCD)) {
+ if (mode->Flags & V_INTERLACE) {
+ ChipsNew->CR[0x70] = 0x80 /* set interlace */
+ | (((((mode->CrtcHDisplay >> 3) - 1) >> 1) - 6) & 0x7F);
+ /*
+ ** Double VDisplay to get back the full screen value, otherwise
+ ** you only see half the picture.
+ */
+ mode->CrtcVDisplay = mode->VDisplay;
+ tmp = ChipsStd->CRTC[7] & ~0x42;
+ ChipsStd->CRTC[7] = (tmp |
+ ((((mode->CrtcVDisplay -1) & 0x100) >> 7 ) |
+ (((mode->CrtcVDisplay -1) & 0x200) >> 3 )));
+ ChipsStd->CRTC[0x12] = (mode->CrtcVDisplay -1) & 0xFF;
+ ChipsNew->CR[0x31] = ((mode->CrtcVDisplay - 1) & 0xF00) >> 8;
+ } else {
+ ChipsNew->CR[0x70] &= ~0x80; /* unset interlace */
+ }
+ }
+
+#if defined(__arm32__) && defined(__NetBSD__)
+ if (cPtr->TVMode != XMODE_RGB) {
+ /*
+ * Put the console into TV Out mode.
+ */
+ xf86SetTVOut(cPtr->TVMode);
+
+ ChipsNew->CR[0x72] = (mode->CrtcHTotal >> 1) >> 3;/* First horizontal
+ * serration pulse */
+ ChipsNew->CR[0x73] = mode->CrtcHTotal >> 3; /* Second pulse */
+ ChipsNew->CR[0x74] = (((mode->HSyncEnd - mode->HSyncStart) >> 3) - 1)
+ & 0x1F; /* equalization pulse */
+
+ if (cPtr->TVMode == XMODE_PAL || cPtr->TVMode == XMODE_SECAM) {
+ ChipsNew->CR[0x71] = 0xA0; /* PAL support with blanking delay */
+ } else {
+ ChipsNew->CR[0x71] = 0x20; /* NTSC support with blanking delay */
+ }
+ } else { /* XMODE_RGB */
+ /*
+ * Put the console into RGB Out mode.
+ */
+ xf86SetRGBOut();
+ }
+#endif
+
+ /* STN specific */
+ if (IS_STN(cPtr->PanelType)) {
+ ChipsNew->FR[0x11] &= ~0x03; /* FRC clear */
+ ChipsNew->FR[0x11] &= ~0x8C; /* Dither clear */
+ ChipsNew->FR[0x11] |= 0x01; /* 16 frame FRC */
+ ChipsNew->FR[0x11] |= 0x84; /* Dither */
+ if (cPtr->Flags & ChipsTMEDSupport) {
+ ChipsNew->FR[0x73] &= 0x4F; /* Clear TMED */
+ ChipsNew->FR[0x73] |= 0x80; /* Enable TMED */
+ ChipsNew->FR[0x73] |= 0x30; /* TMED 256 Shades of RGB */
+ }
+ if (cPtr->PanelType & ChipsDD) /* Shift Clock Mask. Use to get */
+ ChipsNew->FR[0x12] |= 0x4; /* rid of line in DSTN screens */
+ }
+
+ /* Setup the overlay */
+ if (cPtr->Flags & ChipsOverlay8plus16) {
+ ChipsNew->XR[0xD0] |= 0x10; /* Force the Multimedia engine on */
+ ChipsNew->XR[0x4F] = 0x2A; /* SAR04 >352 pixel overlay width */
+ ChipsNew->MR[0x1E] &= 0xE0; /* Set Zoom and Direction */
+ if ((!(cPtr->PanelType & ChipsLCD)) && (mode->Flags & V_INTERLACE))
+ ChipsNew->MR[0x1E] |= 0x10; /* Interlace */
+ ChipsNew->MR[0x1F] &= 0x14; /* Mask reserved bits */
+ ChipsNew->MR[0x1F] |= 0x08; /* RGB 16bpp */
+ if (pScrn->weight.green == 5)
+ ChipsNew->MR[0x1F] |= 0x01; /* RGB 15bpp */
+
+ ChipsNew->MR[0x20] &= 0x03; /* Mask reserved bits */
+ ChipsNew->MR[0x20] |= 0x80; /* Auto Centre, Use mem ptr1 */
+ ChipsNew->MR[0x22] = cPtr->FbOffset16 & 0xF8; /* Setup Pointer 1 */
+ ChipsNew->MR[0x23] = (cPtr->FbOffset16 >> 8) & 0xFF;
+ ChipsNew->MR[0x24] = (cPtr->FbOffset16 >> 16) & 0xFF;
+ ChipsNew->MR[0x25] = cPtr->FbOffset16 & 0xF8; /* Setup Pointer 2 */
+ ChipsNew->MR[0x26] = (cPtr->FbOffset16 >> 8) & 0xFF;
+ ChipsNew->MR[0x27] = (cPtr->FbOffset16 >> 16) & 0xFF;
+ ChipsNew->MR[0x28] = (pScrn->displayWidth >> 2) - 1; /* Width */
+ ChipsNew->MR[0x34] = (pScrn->displayWidth >> 2) - 1;
+
+ /*
+ * The zero position of the overlay does not align with the zero
+ * position of the display. The skew is dependent on the depth,
+ * display type and refresh rate. Calculate the skew before setting
+ * the X and Y dimensions of the overlay
+ */
+ if (cPtr->PanelType & ChipsLCD) {
+ OverlaySkewX = (((ChipsNew->FR[0x23] & 0xFF)
+ - (ChipsNew->FR[0x20] & 0xFF) + 3) << 3)
+ - 1;
+ OverlaySkewY = (ChipsNew->FR[0x33]
+ + ((ChipsNew->FR[0x36] & 0xF) << 8)
+ - (ChipsNew->FR[0x31] & 0xF0)
+ - (ChipsNew->FR[0x32] & 0x0F)
+ - ((ChipsNew->FR[0x35] & 0xF0) << 4));
+ if (cPtr->PanelSize.HDisplay > mode->CrtcHDisplay)
+ OverlaySkewX += (cPtr->PanelSize.HDisplay - mode->CrtcHDisplay)
+ / 2;
+ if (cPtr->PanelSize.VDisplay > mode->CrtcVDisplay)
+ OverlaySkewY += (cPtr->PanelSize.VDisplay - mode->CrtcVDisplay)
+ / 2;
+ } else {
+ OverlaySkewX = mode->CrtcHTotal - mode->CrtcHBlankStart - 1;
+ OverlaySkewY = mode->CrtcVTotal - mode->CrtcVSyncEnd;
+
+ if (mode->Flags & V_INTERLACE) {
+ /*
+ * This handles 1024 and 1280 interlaced modes only. Its
+ * pretty arbitrary, but its what C&T recommends
+ */
+ if (mode->CrtcHDisplay == 1024)
+ OverlaySkewY += 5;
+ if (mode->CrtcHDisplay == 1280)
+ OverlaySkewY *= 2;
+
+ }
+ }
+
+ /* Left Edge of Overlay */
+ ChipsNew->MR[0x2A] = OverlaySkewX;
+ ChipsNew->MR[0x2B] &= 0xF8;
+ /* Right Edge of Overlay */
+ ChipsNew->MR[0x2C] = (OverlaySkewX + pScrn->displayWidth - 1) & 0xFF;
+ ChipsNew->MR[0x2D] &= 0xF8; /* Mask reserved bits */
+ ChipsNew->MR[0x2D] = ((OverlaySkewX + pScrn->displayWidth - 1) >> 8) & 0x07;
+ /* Top Edge of Overlay */
+ ChipsNew->MR[0x2E] = OverlaySkewY;
+ ChipsNew->MR[0x2F] &= 0xF8;
+ /* Bottom Edge of Overlay*/
+ ChipsNew->MR[0x30] = (OverlaySkewY + pScrn->virtualY - 1 )& 0xFF;
+ ChipsNew->MR[0x31] &= 0xF8; /* Mask reserved bits */
+ ChipsNew->MR[0x31] = ((OverlaySkewY + pScrn->virtualY - 1 ) >> 8) & 0x07;
+
+ ChipsNew->MR[0x3C] &= 0x18; /* Mask reserved bits */
+ ChipsNew->MR[0x3C] |= 0x07; /* Enable keyed overlay window */
+ ChipsNew->MR[0x3D] = 0x00;
+ ChipsNew->MR[0x3E] = 0x00;
+ ChipsNew->MR[0x3F] = pScrn->colorKey; /* 8bpp transparency key */
+ ChipsNew->MR[0x40] = 0xFF;
+ ChipsNew->MR[0x41] = 0xFF;
+ ChipsNew->MR[0x42] = 0x00;
+ }
+
+ /* Program the registers */
+ /*vgaHWProtect(pScrn, TRUE);*/
+ chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE);
+ /*vgaHWProtect(pScrn, FALSE);*/
+ usleep(100000); /* prevents cursor corruption seen on a TECRA 510 */
+
+ return(TRUE);
+}
+
+static Bool
+chipsModeInitWingine(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ int i, bytesPerPixel;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSRegPtr ChipsNew;
+ vgaRegPtr ChipsStd;
+ unsigned int tmp;
+
+ ChipsNew = &cPtr->ModeReg;
+ ChipsStd = &hwp->ModeReg;
+
+ bytesPerPixel = pScrn->bitsPerPixel >> 3;
+
+ /*
+ * This chipset seems to have problems if
+ * HBlankEnd is choosen equals HTotal
+ */
+ if (!mode->CrtcHAdjusted)
+ mode->CrtcHBlankEnd = min(mode->CrtcHSyncEnd, mode->CrtcHTotal - 2);
+
+ /* correct the timings for 16/24 bpp */
+ if (pScrn->bitsPerPixel == 16) {
+ if (!mode->CrtcHAdjusted) {
+ mode->CrtcHDisplay++;
+ mode->CrtcHDisplay <<= 1;
+ mode->CrtcHDisplay--;
+ mode->CrtcHSyncStart <<= 1;
+ mode->CrtcHSyncEnd <<= 1;
+ mode->CrtcHBlankStart <<= 1;
+ mode->CrtcHBlankEnd <<= 1;
+ mode->CrtcHTotal <<= 1;
+ mode->CrtcHAdjusted = TRUE;
+ }
+ } else if (pScrn->bitsPerPixel == 24) {
+ if (!mode->CrtcHAdjusted) {
+ mode->CrtcHDisplay++;
+ mode->CrtcHDisplay += ((mode->CrtcHDisplay) << 1);
+ mode->CrtcHDisplay--;
+ mode->CrtcHSyncStart += ((mode->CrtcHSyncStart) << 1);
+ mode->CrtcHSyncEnd += ((mode->CrtcHSyncEnd) << 1);
+ mode->CrtcHBlankStart += ((mode->CrtcHBlankStart) << 1);
+ mode->CrtcHBlankEnd += ((mode->CrtcHBlankEnd) << 1);
+ mode->CrtcHTotal += ((mode->CrtcHTotal) << 1);
+ mode->CrtcHAdjusted = TRUE;
+ }
+ }
+
+ /* generic init */
+ if (!vgaHWInit(pScrn, mode)) {
+ ErrorF("bomb 3\n");
+ return (FALSE);
+ }
+ pScrn->vtSema = TRUE;
+
+ /* init clock */
+ if (!chipsClockFind(pScrn, mode->ClockIndex, &ChipsNew->Clock)) {
+ ErrorF("bomb 4\n");
+ return (FALSE);
+ }
+
+ /* get C&T Specific Registers */
+ for (i = 0; i < 0x7D; i++) { /* don't touch XR7D and XR7F on WINGINE */
+ ChipsNew->XR[i] = cPtr->readXR(cPtr, i);
+ }
+
+ /* some generic settings */
+ if (pScrn->bitsPerPixel == 1) {
+ ChipsStd->Attribute[0x10] = 0x03; /* mode */
+ } else {
+ ChipsStd->Attribute[0x10] = 0x01; /* mode */
+ }
+ ChipsStd->Attribute[0x11] = 0x00; /* overscan (border) color */
+ ChipsStd->Attribute[0x12] = 0x0F; /* enable all color planes */
+ ChipsStd->Attribute[0x13] = 0x00; /* horiz pixel panning 0 */
+
+ ChipsStd->Graphics[0x05] = 0x00; /* normal read/write mode */
+
+
+ /* set virtual screen width */
+ if (pScrn->bitsPerPixel >= 8)
+ ChipsStd->CRTC[0x13] = (pScrn->displayWidth * bytesPerPixel) >> 3;
+ else
+ ChipsStd->CRTC[0x13] = pScrn->displayWidth >> 4;
+
+
+ /* set C&T Specific Registers */
+ /* set virtual screen width */
+ if (pScrn->bitsPerPixel >= 8)
+ tmp = (pScrn->displayWidth >> 4) * bytesPerPixel;
+ else
+ tmp = (pScrn->displayWidth >> 5);
+ ChipsNew->XR[0x0D] = (tmp & 0x80) >> 5;
+
+ ChipsNew->XR[0x04] |= 4; /* enable addr counter bits 16-17 */
+ /* XR04: Memory control 1 */
+ /* bit 2: Memory Wraparound */
+ /* Enable CRTC addr counter bits 16-17 if set */
+
+ ChipsNew->XR[0x0B] |= 0x07; /* extended mode, dual pages enabled */
+ ChipsNew->XR[0x0B] &= ~0x10; /* linear mode off */
+ /* XR0B: CPU paging */
+ /* bit 0: Memory mapping mode */
+ /* VGA compatible if 0 (default) */
+ /* Extended mode (mapping for > 256 kB mem) if 1 */
+ /* bit 1: CPU single/dual mapping */
+ /* 0, CPU uses only a single map to access (default) */
+ /* 1, CPU uses two maps to access */
+ /* bit 2: CPU address divide by 4 */
+
+ ChipsNew->XR[0x10] = 0; /* XR10: Single/low map */
+ ChipsNew->XR[0x11] = 0; /* XR11: High map */
+ ChipsNew->XR[0x0C] &= ~0x50; /* MSB for XR10 & XR11 */
+ if (pScrn->bitsPerPixel >= 8) {
+ ChipsNew->XR[0x28] |= 0x10; /* 256-color video */
+ } else {
+ ChipsNew->XR[0x28] &= 0xEF; /* 16-color video */
+ }
+ /* set up extended display timings */
+ /* in CRTonly mode this is simple: only set overflow for CR00-CR06 */
+ ChipsNew->XR[0x17] = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8)
+ | ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7)
+ | ((((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6)
+ | ((((mode->CrtcHSyncEnd >> 3)) & 0x20) >> 2)
+ | ((((mode->CrtcHBlankStart >> 3) - 1) & 0x100) >> 4)
+ | ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x40) >> 1);
+
+
+ ChipsNew->XR[0x16] = (((mode->CrtcVTotal -2) & 0x400) >> 10 )
+ | (((mode->CrtcVDisplay -1) & 0x400) >> 9 )
+ | ((mode->CrtcVSyncStart & 0x400) >> 8 )
+ | (((mode->CrtcVBlankStart) & 0x400) >> 6 );
+
+ /* set video mode */
+ ChipsNew->XR[0x2B] = chipsVideoMode(pScrn->bitsPerPixel,
+ pScrn->weight.green, mode->CrtcHDisplay, mode->CrtcVDisplay);
+#ifdef DEBUG
+ ErrorF("VESA Mode: %Xh\n", ChipsNew->XR[0x2B]);
+#endif
+
+ /* set some linear specific registers */
+ if (cPtr->Flags & ChipsLinearSupport) {
+ /* enable linear addressing */
+ ChipsNew->XR[0x0B] &= 0xFD; /* dual page clear */
+ ChipsNew->XR[0x0B] |= 0x10; /* linear mode on */
+
+ ChipsNew->XR[0x08] =
+ (unsigned char)((cPtr->FbAddress >> 16) & 0xFF);
+ ChipsNew->XR[0x09] =
+ (unsigned char)((cPtr->FbAddress >> 24) & 0xFF);
+
+ /* general setup */
+ ChipsNew->XR[0x40] = 0x01; /*BitBLT Draw Mode for 8 and 24 bpp */
+ }
+
+ /* common general setup */
+ ChipsNew->XR[0x52] |= 0x01; /* Refresh count */
+ ChipsNew->XR[0x0F] &= 0xEF; /* not Hi-/True-Colour */
+ ChipsNew->XR[0x02] &= 0xE7; /* Attr. Cont. default access */
+ /* use ext. regs. for hor. in dual */
+ ChipsNew->XR[0x06] &= 0xF3; /* bpp clear */
+
+ /* bpp depend */
+ /*XR06: Palette control */
+ /* bit 0: Pixel Data Pin Diag, 0 for flat panel pix. data (def) */
+ /* bit 1: Internal DAC disable */
+ /* bit 3-2: Colour depth, 0 for 4 or 8 bpp, 1 for 16(5-5-5) bpp, */
+ /* 2 for 24 bpp, 3 for 16(5-6-5)bpp */
+ /* bit 4: Enable PC Video Overlay on colour key */
+ /* bit 5: Bypass Internal VGA palette */
+ /* bit 7-6: Colour reduction select, 0 for NTSC (default), */
+ /* 1 for Equivalent weighting, 2 for green only, */
+ /* 3 for Colour w/o reduction */
+ /* XR50 Panel Format Register 1 */
+ /* bit 1-0: Frame Rate Control; 00, No FRC; */
+ /* 01, 16-frame FRC for colour STN and monochrome */
+ /* 10, 2-frame FRC for colour TFT or monochrome; */
+ /* 11, reserved */
+ /* bit 3-2: Dither Enable */
+ /* 00, disable dithering; 01, enable dithering */
+ /* for 256 mode */
+ /* 10, enable dithering for all modes; 11, reserved */
+ /* bit6-4: Clock Divide (CD) */
+ /* 000, Shift Clock Freq = Dot Clock Freq; */
+ /* 001, SClk = DClk/2; 010 SClk = DClk/4; */
+ /* 011, SClk = DClk/8; 100 SClk = DClk/16; */
+ /* bit 7: TFT data width */
+ /* 0, 16 bit(565RGB); 1, 24bit (888RGB) */
+ if (pScrn->bitsPerPixel == 16) {
+ ChipsNew->XR[0x06] |= 0xC4; /*15 or 16 bpp colour */
+ ChipsNew->XR[0x0F] |= 0x10; /*Hi-/True-Colour */
+ ChipsNew->XR[0x40] = 0x02; /*BitBLT Draw Mode for 16 bpp */
+ if (pScrn->weight.green != 5)
+ ChipsNew->XR[0x06] |= 0x08; /*16bpp */
+ } else if (pScrn->bitsPerPixel == 24) {
+ ChipsNew->XR[0x06] |= 0xC8; /*24 bpp colour */
+ ChipsNew->XR[0x0F] |= 0x10; /*Hi-/True-Colour */
+ }
+
+ /*CRT only: interlaced mode */
+ if (mode->Flags & V_INTERLACE) {
+ ChipsNew->XR[0x28] |= 0x20; /* set interlace */
+ /* empirical value */
+ tmp = ((((mode->CrtcHDisplay >> 3) - 1) >> 1)
+ - 6 * (pScrn->bitsPerPixel >= 8 ? bytesPerPixel : 1 ));
+ ChipsNew->XR[0x19] = tmp & 0xFF;
+ ChipsNew->XR[0x17] |= ((tmp & 0x100) >> 1); /* overflow */
+ ChipsNew->XR[0x0F] &= ~0x40; /* set SW-Flag */
+ } else {
+ ChipsNew->XR[0x28] &= ~0x20; /* unset interlace */
+ ChipsNew->XR[0x0F] |= 0x40; /* set SW-Flag */
+ }
+
+ /* Program the registers */
+ /*vgaHWProtect(pScrn, TRUE);*/
+ chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE);
+ /*vgaHWProtect(pScrn, FALSE);*/
+
+ return (TRUE);
+}
+
+static Bool
+chipsModeInit655xx(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ int i, bytesPerPixel;
+ int lcdHTotal, lcdHDisplay;
+ int lcdVTotal, lcdVDisplay;
+ int lcdHRetraceStart, lcdHRetraceEnd;
+ int lcdVRetraceStart, lcdVRetraceEnd;
+ int HSyncStart, HDisplay;
+ int CrtcHDisplay;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ CHIPSRegPtr ChipsNew;
+ vgaRegPtr ChipsStd;
+ unsigned int tmp;
+
+ ChipsNew = &cPtr->ModeReg;
+ ChipsStd = &hwp->ModeReg;
+
+ bytesPerPixel = pScrn->bitsPerPixel >> 3;
+
+ /*
+ * Possibly fix up the panel size, if the manufacture is stupid
+ * enough to set it incorrectly in text modes
+ */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_PANEL_SIZE, FALSE)) {
+ cPtr->PanelSize.HDisplay = mode->CrtcHDisplay;
+ cPtr->PanelSize.VDisplay = mode->CrtcVDisplay;
+ }
+
+ /*
+ * This chipset seems to have problems if
+ * HBlankEnd is choosen equals HTotal
+ */
+ if (!mode->CrtcHAdjusted)
+ mode->CrtcHBlankEnd = min(mode->CrtcHSyncEnd, mode->CrtcHTotal - 2);
+
+ /* correct the timings for 16/24 bpp */
+ if (pScrn->bitsPerPixel == 16) {
+ if (!mode->CrtcHAdjusted) {
+ mode->CrtcHDisplay++;
+ mode->CrtcHDisplay <<= 1;
+ mode->CrtcHDisplay--;
+ mode->CrtcHSyncStart <<= 1;
+ mode->CrtcHSyncEnd <<= 1;
+ mode->CrtcHBlankStart <<= 1;
+ mode->CrtcHBlankEnd <<= 1;
+ mode->CrtcHTotal <<= 1;
+ mode->CrtcHAdjusted = TRUE;
+ }
+ } else if (pScrn->bitsPerPixel == 24) {
+ if (!mode->CrtcHAdjusted) {
+ mode->CrtcHDisplay++;
+ mode->CrtcHDisplay += ((mode->CrtcHDisplay) << 1);
+ mode->CrtcHDisplay--;
+ mode->CrtcHSyncStart += ((mode->CrtcHSyncStart) << 1);
+ mode->CrtcHSyncEnd += ((mode->CrtcHSyncEnd) << 1);
+ mode->CrtcHBlankStart += ((mode->CrtcHBlankStart) << 1);
+ mode->CrtcHBlankEnd += ((mode->CrtcHBlankEnd) << 1);
+ mode->CrtcHTotal += ((mode->CrtcHTotal) << 1);
+ mode->CrtcHAdjusted = TRUE;
+ }
+ }
+
+ /* store orig. HSyncStart needed for flat panel mode */
+ HSyncStart = mode->CrtcHSyncStart / (pScrn->bitsPerPixel >= 8 ?
+ bytesPerPixel : 1 ) - 16;
+ HDisplay = (mode->CrtcHDisplay + 1) / (pScrn->bitsPerPixel >= 8 ?
+ bytesPerPixel : 1 );
+
+ /* generic init */
+ if (!vgaHWInit(pScrn, mode)) {
+ ErrorF("bomb 5\n");
+ return (FALSE);
+ }
+ pScrn->vtSema = TRUE;
+
+ /* init clock */
+ if (!chipsClockFind(pScrn, mode->ClockIndex, &ChipsNew->Clock)) {
+ ErrorF("bomb 6\n");
+ return (FALSE);
+ }
+
+ /* get C&T Specific Registers */
+ for (i = 0; i < 0x80; i++) {
+ ChipsNew->XR[i] = cPtr->readXR(cPtr, i);
+ }
+
+ /* some generic settings */
+ if (pScrn->bitsPerPixel == 1) {
+ ChipsStd->Attribute[0x10] = 0x03; /* mode */
+ } else {
+ ChipsStd->Attribute[0x10] = 0x01; /* mode */
+ }
+ ChipsStd->Attribute[0x11] = 0x00; /* overscan (border) color */
+ ChipsStd->Attribute[0x12] = 0x0F; /* enable all color planes */
+ ChipsStd->Attribute[0x13] = 0x00; /* horiz pixel panning 0 */
+
+ ChipsStd->Graphics[0x05] = 0x00; /* normal read/write mode */
+
+ /* set virtual screen width */
+ if (pScrn->bitsPerPixel >= 8)
+ ChipsStd->CRTC[0x13] = (pScrn->displayWidth * bytesPerPixel) >> 3;
+ else
+ ChipsStd->CRTC[0x13] = pScrn->displayWidth >> 4;
+
+
+ /* set C&T Specific Registers */
+ /* set virtual screen width */
+ ChipsNew->XR[0x1E] = ChipsStd->CRTC[0x13]; /* alternate offset */
+ /*databook is not clear about 0x1E might be needed for 65520/30 */
+ if (pScrn->bitsPerPixel >= 8)
+ tmp = (pScrn->displayWidth * bytesPerPixel) >> 2;
+ else
+ tmp = pScrn->displayWidth >> 3;
+ ChipsNew->XR[0x0D] = (tmp & 0x01) | ((tmp << 1) & 0x02) ;
+
+ ChipsNew->XR[0x04] |= 4; /* enable addr counter bits 16-17 */
+ /* XR04: Memory control 1 */
+ /* bit 2: Memory Wraparound */
+ /* Enable CRTC addr counter bits 16-17 if set */
+
+ ChipsNew->XR[0x0B] |= 0x07; /* extended mode, dual pages enabled */
+ ChipsNew->XR[0x0B] &= ~0x10; /* linear mode off */
+ /* XR0B: CPU paging */
+ /* bit 0: Memory mapping mode */
+ /* VGA compatible if 0 (default) */
+ /* Extended mode (mapping for > 256 kB mem) if 1 */
+ /* bit 1: CPU single/dual mapping */
+ /* 0, CPU uses only a single map to access (default) */
+ /* 1, CPU uses two maps to access */
+ /* bit 2: CPU address divide by 4 */
+
+ ChipsNew->XR[0x10] = 0; /* XR10: Single/low map */
+ ChipsNew->XR[0x11] = 0; /* XR11: High map */
+ if (pScrn->bitsPerPixel >= 8) {
+ ChipsNew->XR[0x28] |= 0x10; /* 256-color video */
+ } else {
+ ChipsNew->XR[0x28] &= 0xEF; /* 16-color video */
+ }
+ /* set up extended display timings */
+ if (!(cPtr->PanelType & ChipsLCD)) {
+ /* in CRTonly mode this is simple: only set overflow for CR00-CR06 */
+ ChipsNew->XR[0x17] = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8)
+ | ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7)
+ | ((((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6)
+ | ((((mode->CrtcHSyncEnd >> 3)) & 0x20) >> 2)
+ | ((((mode->CrtcHBlankStart >> 3) - 1) & 0x100) >> 4)
+ | ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x40) >> 1);
+
+ ChipsNew->XR[0x16] = (((mode->CrtcVTotal -2) & 0x400) >> 10 )
+ | (((mode->CrtcVDisplay -1) & 0x400) >> 9 )
+ | ((mode->CrtcVSyncStart & 0x400) >> 8 )
+ | (((mode->CrtcVBlankStart) & 0x400) >> 6 );
+ } else {
+ /* horizontal timing registers */
+ /* in LCD/dual mode use saved bios values to derive timing values if
+ * not told otherwise */
+ if (!xf86ReturnOptValBool(cPtr->Options, OPTION_USE_MODELINE, FALSE)) {
+ lcdHTotal = cPtr->PanelSize.HTotal;
+ lcdHRetraceStart = cPtr->PanelSize.HRetraceStart;
+ lcdHRetraceEnd = cPtr->PanelSize.HRetraceEnd;
+ if (pScrn->bitsPerPixel == 16) {
+ lcdHRetraceStart <<= 1;
+ lcdHRetraceEnd <<= 1;
+ lcdHTotal <<= 1;
+ } else if (pScrn->bitsPerPixel == 24) {
+ lcdHRetraceStart += (lcdHRetraceStart << 1);
+ lcdHRetraceEnd += (lcdHRetraceEnd << 1);
+ lcdHTotal += (lcdHTotal << 1);
+ }
+ lcdHRetraceStart -=8; /* HBlank = HRetrace - 1: for */
+ lcdHRetraceEnd -=8; /* compatibility with vgaHW.c */
+ } else {
+ /* use modeline values if bios values don't work */
+ lcdHTotal = mode->CrtcHTotal;
+ lcdHRetraceStart = mode->CrtcHSyncStart;
+ lcdHRetraceEnd = mode->CrtcHSyncEnd;
+ }
+ /* The chip takes the size of the visible display area from the
+ * CRTC values. We use bios screensize for LCD in LCD/dual mode
+ * wether or not we use modeline for LCD. This way we can specify
+ * always specify a smaller than default display size on LCD
+ * by writing it to the CRTC registers. */
+ lcdHDisplay = cPtr->PanelSize.HDisplay;
+ if (pScrn->bitsPerPixel == 16) {
+ lcdHDisplay++;
+ lcdHDisplay <<= 1;
+ lcdHDisplay--;
+ } else if (pScrn->bitsPerPixel == 24) {
+ lcdHDisplay++;
+ lcdHDisplay += (lcdHDisplay << 1);
+ lcdHDisplay--;
+ }
+ lcdHTotal = (lcdHTotal >> 3) - 5;
+ lcdHDisplay = (lcdHDisplay >> 3) - 1;
+ lcdHRetraceStart = (lcdHRetraceStart >> 3);
+ lcdHRetraceEnd = (lcdHRetraceEnd >> 3);
+ /* This ugly hack is needed because CR01 and XR1C share the 8th bit!*/
+ CrtcHDisplay = ((mode->CrtcHDisplay >> 3) - 1);
+ if ((lcdHDisplay & 0x100) != (CrtcHDisplay & 0x100)) {
+ ErrorF("This display configuration might cause problems !\n");
+ lcdHDisplay = 255;
+ }
+
+ /* now init register values */
+ ChipsNew->XR[0x17] = (((lcdHTotal) & 0x100) >> 8)
+ | ((lcdHDisplay & 0x100) >> 7)
+ | ((lcdHRetraceStart & 0x100) >> 6)
+ | (((lcdHRetraceEnd) & 0x20) >> 2);
+
+ ChipsNew->XR[0x19] = lcdHRetraceStart & 0xFF;
+ ChipsNew->XR[0x1A] = lcdHRetraceEnd & 0x1F;
+
+ /* XR1B: Alternate horizontal total */
+ /* used in all flat panel mode with horiz. compression disabled, */
+ /* CRT CGA text and graphic modes and Hercules graphics mode */
+ /* similar to CR00, actual value - 5 */
+ ChipsNew->XR[0x1B] = lcdHTotal & 0xFF;
+
+ /*XR1C: Alternate horizontal blank start (CRT mode) */
+ /* /horizontal panel size (FP mode) */
+ /* FP horizontal panel size (FP mode), */
+ /* actual value - 1 (in characters unit) */
+ /* CRT horizontal blank start (CRT mode) */
+ /* similar to CR02, actual value - 1 */
+ ChipsNew->XR[0x1C] = lcdHDisplay & 0xFF;
+
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_USE_MODELINE, FALSE)) {
+ /* for ext. packed pixel mode on 64520/64530 */
+ /* no need to rescale: used only in 65530 */
+ ChipsNew->XR[0x21] = lcdHRetraceStart & 0xFF;
+ ChipsNew->XR[0x22] = lcdHRetraceEnd & 0x1F;
+ ChipsNew->XR[0x23] = lcdHTotal & 0xFF;
+
+ /* vertical timing registers */
+ lcdVTotal = mode->CrtcVTotal - 2;
+ lcdVDisplay = cPtr->PanelSize.VDisplay - 1;
+ lcdVRetraceStart = mode->CrtcVSyncStart;
+ lcdVRetraceEnd = mode->CrtcVSyncEnd;
+
+ ChipsNew->XR[0x64] = lcdVTotal & 0xFF;
+ ChipsNew->XR[0x66] = lcdVRetraceStart & 0xFF;
+ ChipsNew->XR[0x67] = lcdVRetraceEnd & 0x0F;
+ ChipsNew->XR[0x68] = lcdVDisplay & 0xFF;
+ ChipsNew->XR[0x65] = ((lcdVTotal & 0x100) >> 8)
+ | ((lcdVDisplay & 0x100) >> 7)
+ | ((lcdVRetraceStart & 0x100) >> 6)
+ | ((lcdVRetraceStart & 0x400) >> 7)
+ | ((lcdVTotal & 0x400) >> 6)
+ | ((lcdVTotal & 0x200) >> 4)
+ | ((lcdVDisplay & 0x200) >> 3)
+ | ((lcdVRetraceStart & 0x200) >> 2);
+
+ /*
+ * These are important: 0x2C specifies the numbers of lines
+ * (hsync pulses) between vertical blank start and vertical
+ * line total, 0x2D specifies the number of clock ticks? to
+ * horiz. blank start ( caution ! 16bpp/24bpp modes: that's
+ * why we need HSyncStart - can't use mode->CrtcHSyncStart)
+ */
+ tmp = ((cPtr->PanelType & ChipsDD) && !(ChipsNew->XR[0x6F] & 0x02))
+ ? 1 : 0; /* double LP delay, FLM: 2 lines iff DD+no acc*/
+ /* Currently we support 2 FLM schemes: #1: FLM coincides with
+ * VTotal ie. the delay is programmed to the difference bet-
+ * ween lctVTotal and lcdVRetraceStart. #2: FLM coincides
+ * lcdVRetraceStart - in this case FLM delay will be turned
+ * off. To decide which scheme to use we compare the value of
+ * XR2C set by the bios to the two schemes. The one that fits
+ * better will be used.
+ */
+
+ if (ChipsNew->XR[0x2C] < abs((cPtr->PanelSize.VTotal -
+ cPtr->PanelSize.VRetraceStart - tmp - 1) -
+ ChipsNew->XR[0x2C]))
+ ChipsNew->XR[0x2F] |= 0x80; /* turn FLM delay off */
+ ChipsNew->XR[0x2C] = lcdVTotal - lcdVRetraceStart - tmp;
+ /*ChipsNew->XR[0x2D] = (HSyncStart >> (3 - tmp)) & 0xFF;*/
+ ChipsNew->XR[0x2D] = (HDisplay >> (3 - tmp)) & 0xFF;
+ ChipsNew->XR[0x2F] = (ChipsNew->XR[0x2F] & 0xDF)
+ | (((HSyncStart >> (3 - tmp)) & 0x100) >> 3);
+ }
+
+ /* set stretching/centering */
+ if (!xf86ReturnOptValBool(cPtr->Options, OPTION_SUSPEND_HACK, FALSE)) {
+ ChipsNew->XR[0x51] |= 0x40; /* enable FP compensation */
+ ChipsNew->XR[0x55] |= 0x01; /* enable horiz. compensation */
+ ChipsNew->XR[0x57] |= 0x01; /* enable horiz. compensation */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_STRETCH,
+ FALSE)) {
+ if (mode->CrtcHDisplay < 1489) /* HWBug */
+ ChipsNew->XR[0x55] |= 0x02; /* enable h-centering */
+ else if (pScrn->bitsPerPixel == 24)
+ ChipsNew->XR[0x56] = (lcdHDisplay - CrtcHDisplay) >> 1;
+ } else {
+ ChipsNew->XR[0x55] &= 0xFD; /* disable h-centering */
+ ChipsNew->XR[0x56] = 0;
+ }
+ ChipsNew->XR[0x57] = 0x03; /* enable v-comp disable v-stretch */
+ if (!xf86ReturnOptValBool(cPtr->Options, OPTION_LCD_STRETCH,
+ FALSE)) {
+ ChipsNew->XR[0x55] |= 0x20; /* enable h-comp disable h-double*/
+ ChipsNew->XR[0x57] |= 0x60; /* Enable vertical stretching */
+ tmp = (mode->CrtcVDisplay / (cPtr->PanelSize.VDisplay -
+ mode->CrtcVDisplay + 1));
+ if (tmp == 0)
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_HW_CURSOR,
+ FALSE))
+ cPtr->Accel.UseHWCursor = TRUE; /* H/W cursor forced */
+ else {
+ if ((cPtr->PanelSize.HDisplay != mode->CrtcHDisplay)
+ && (cPtr->PanelSize.VDisplay != mode->CrtcVDisplay)) {
+ /* Possible H/W bug? */
+ if(cPtr->Accel.UseHWCursor)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling HW Cursor on stretched LCD\n");
+ cPtr->Accel.UseHWCursor = FALSE;
+ }
+ }
+ else
+ cPtr->Accel.UseHWCursor = TRUE;
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_HW_CURSOR,
+ FALSE) &&
+ !xf86ReturnOptValBool(cPtr->Options, OPTION_SW_CURSOR,
+ FALSE))
+ tmp = (tmp == 0 ? 1 : tmp); /* Bug when doubling */
+ ChipsNew->XR[0x5A] = tmp > 0x0F ? 0 : (unsigned char)tmp;
+ } else {
+ ChipsNew->XR[0x55] &= 0xDF; /* disable h-comp, h-double */
+ ChipsNew->XR[0x57] &= 0x9F; /* disable vertical stretching */
+ }
+ }
+ }
+
+ /* set video mode */
+ ChipsNew->XR[0x2B] = chipsVideoMode(pScrn->bitsPerPixel,
+ pScrn->weight.green, (cPtr->PanelType & ChipsLCD) ?
+ min(HDisplay, cPtr->PanelSize.HDisplay) : HDisplay,
+ cPtr->PanelSize.VDisplay);
+#ifdef DEBUG
+ ErrorF("VESA Mode: %Xh\n", ChipsNew->XR[0x2B]);
+#endif
+
+ /* set some linear specific registers */
+ if (cPtr->Flags & ChipsLinearSupport) {
+ /* enable linear addressing */
+ ChipsNew->XR[0x0B] &= 0xFD; /* dual page clear */
+ ChipsNew->XR[0x0B] |= 0x10; /* linear mode on */
+ if (cPtr->Chipset == CHIPS_CT65535)
+ ChipsNew->XR[0x08] = (unsigned char)(cPtr->FbAddress >> 17);
+ else if (cPtr->Chipset > CHIPS_CT65535)
+ ChipsNew->XR[0x08] = (unsigned char)(cPtr->FbAddress >> 20);
+ else {
+ /* Its probably set correctly by BIOS anyway. Leave it alone */
+ /* 65525 - 65530 require XR04[6] set for greater than 512k of */
+ /* ram. We only correct obvious bugs; VL probably uses MEMR/MEMW*/
+ if (cPtr->Bus == ChipsISA)
+ ChipsNew->XR[0x04] &= ~0x40; /* A19 sceme */
+ if (pScrn->videoRam > 512)
+ ChipsNew->XR[0x04] |= 0x40; /* MEMR/MEMW sceme */
+ }
+
+ /* general setup */
+ ChipsNew->XR[0x03] |= 0x08; /* High bandwidth on 65548 */
+ ChipsNew->XR[0x40] = 0x01; /*BitBLT Draw Mode for 8 and 24 bpp */
+ }
+
+ /* common general setup */
+ ChipsNew->XR[0x52] |= 0x01; /* Refresh count */
+ ChipsNew->XR[0x0F] &= 0xEF; /* not Hi-/True-Colour */
+ ChipsNew->XR[0x02] |= 0x01; /* 16bit CPU Memory Access */
+ ChipsNew->XR[0x02] &= 0xE3; /* Attr. Cont. default access */
+ /* use ext. regs. for hor. in dual */
+ ChipsNew->XR[0x06] &= 0xF3; /* bpp clear */
+
+ /* PCI */
+ if (cPtr->Bus == ChipsPCI)
+ ChipsNew->XR[0x03] |= 0x40; /*PCI burst */
+
+ /* sync. polarities */
+ if ((mode->Flags & (V_PHSYNC | V_NHSYNC))
+ && (mode->Flags & (V_PVSYNC | V_NVSYNC))) {
+ if (mode->Flags & (V_PHSYNC | V_NHSYNC)) {
+ if (mode->Flags & V_PHSYNC) {
+ ChipsNew->XR[0x55] &= 0xBF; /* CRT Hsync positive */
+ } else {
+ ChipsNew->XR[0x55] |= 0x40; /* CRT Hsync negative */
+ }
+ }
+ if (mode->Flags & (V_PVSYNC | V_NVSYNC)) {
+ if (mode->Flags & V_PVSYNC) {
+ ChipsNew->XR[0x55] &= 0x7F; /* CRT Vsync positive */
+ } else {
+ ChipsNew->XR[0x55] |= 0x80; /* CRT Vsync negative */
+ }
+ }
+ }
+
+ /* bpp depend */
+ /*XR06: Palette control */
+ /* bit 0: Pixel Data Pin Diag, 0 for flat panel pix. data (def) */
+ /* bit 1: Internal DAC disable */
+ /* bit 3-2: Colour depth, 0 for 4 or 8 bpp, 1 for 16(5-5-5) bpp, */
+ /* 2 for 24 bpp, 3 for 16(5-6-5)bpp */
+ /* bit 4: Enable PC Video Overlay on colour key */
+ /* bit 5: Bypass Internal VGA palette */
+ /* bit 7-6: Colour reduction select, 0 for NTSC (default), */
+ /* 1 for Equivalent weighting, 2 for green only, */
+ /* 3 for Colour w/o reduction */
+ /* XR50 Panel Format Register 1 */
+ /* bit 1-0: Frame Rate Control; 00, No FRC; */
+ /* 01, 16-frame FRC for colour STN and monochrome */
+ /* 10, 2-frame FRC for colour TFT or monochrome; */
+ /* 11, reserved */
+ /* bit 3-2: Dither Enable */
+ /* 00, disable dithering; 01, enable dithering */
+ /* for 256 mode */
+ /* 10, enable dithering for all modes; 11, reserved */
+ /* bit6-4: Clock Divide (CD) */
+ /* 000, Shift Clock Freq = Dot Clock Freq; */
+ /* 001, SClk = DClk/2; 010 SClk = DClk/4; */
+ /* 011, SClk = DClk/8; 100 SClk = DClk/16; */
+ /* bit 7: TFT data width */
+ /* 0, 16 bit(565RGB); 1, 24bit (888RGB) */
+ if (pScrn->bitsPerPixel == 16) {
+ ChipsNew->XR[0x06] |= 0xC4; /*15 or 16 bpp colour */
+ ChipsNew->XR[0x0F] |= 0x10; /*Hi-/True-Colour */
+ ChipsNew->XR[0x40] = 0x02; /*BitBLT Draw Mode for 16 bpp */
+ if (pScrn->weight.green != 5)
+ ChipsNew->XR[0x06] |= 0x08; /*16bpp */
+ } else if (pScrn->bitsPerPixel == 24) {
+ ChipsNew->XR[0x06] |= 0xC8; /*24 bpp colour */
+ ChipsNew->XR[0x0F] |= 0x10; /*Hi-/True-Colour */
+ if (xf86ReturnOptValBool(cPtr->Options, OPTION_18_BIT_BUS, FALSE)) {
+ ChipsNew->XR[0x50] &= 0x7F; /*18 bit TFT data width */
+ } else {
+ ChipsNew->XR[0x50] |= 0x80; /*24 bit TFT data width */
+ }
+ }
+
+ /*CRT only: interlaced mode */
+ if (!(cPtr->PanelType & ChipsLCD)) {
+ if (mode->Flags & V_INTERLACE){
+ ChipsNew->XR[0x28] |= 0x20; /* set interlace */
+ /* empirical value */
+ tmp = ((((mode->CrtcHDisplay >> 3) - 1) >> 1)
+ - 6 * (pScrn->bitsPerPixel >= 8 ? bytesPerPixel : 1 ));
+ if(cPtr->Chipset < CHIPS_CT65535)
+ ChipsNew->XR[0x19] = tmp & 0xFF;
+ else
+ ChipsNew->XR[0x29] = tmp & 0xFF;
+ ChipsNew->XR[0x0F] &= ~0x40; /* set SW-Flag */
+ } else {
+ ChipsNew->XR[0x28] &= ~0x20; /* unset interlace */
+ ChipsNew->XR[0x0F] |= 0x40; /* set SW-Flag */
+ }
+ }
+
+ /* STN specific */
+ if (IS_STN(cPtr->PanelType)) {
+ ChipsNew->XR[0x50] &= ~0x03; /* FRC clear */
+ ChipsNew->XR[0x50] |= 0x01; /* 16 frame FRC */
+ ChipsNew->XR[0x50] &= ~0x0C; /* Dither clear */
+ ChipsNew->XR[0x50] |= 0x08; /* Dither all modes */
+ if (cPtr->Chipset == CHIPS_CT65548) {
+ ChipsNew->XR[0x03] |= 0x20; /* CRT I/F priority */
+ ChipsNew->XR[0x04] |= 0x10; /* RAS precharge 65548 */
+ }
+ }
+
+ /* This stuff was emprically derived several years ago. Not sure its
+ * still needed, and I'd love to get rid of it as its ugly
+ */
+ switch (cPtr->Chipset) {
+ case CHIPS_CT65545: /*jet mini *//*DEC HighNote Ultra DSTN */
+ ChipsNew->XR[0x03] |= 0x10; /* do not hold off CPU for palette acc*/
+ break;
+ case CHIPS_CT65546: /*CT 65546, only for Toshiba */
+ ChipsNew->XR[0x05] |= 0x80; /* EDO RAM enable */
+ break;
+ }
+
+ /* Program the registers */
+ /*vgaHWProtect(pScrn, TRUE);*/
+ chipsRestore(pScrn, ChipsStd, ChipsNew, FALSE);
+ /*vgaHWProtect(pScrn, FALSE);*/
+
+ return (TRUE);
+}
+
+static void
+chipsRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, CHIPSRegPtr ChipsReg,
+ Bool restoreFonts)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char tmp = 0;
+
+ /*vgaHWProtect(pScrn, TRUE);*/
+
+ /* set registers so that we can program the controller */
+ if (IS_HiQV(cPtr)) {
+ cPtr->writeXR(cPtr, 0x0E, 0x00);
+ } else {
+ cPtr->writeXR(cPtr, 0x10, 0x00);
+ cPtr->writeXR(cPtr, 0x11, 0x00);
+ tmp = cPtr->readXR(cPtr, 0x0C) & ~0x50; /* WINgine stores MSB here */
+ cPtr->writeXR(cPtr, 0x0C, tmp);
+ cPtr->writeXR(cPtr, 0x15, 0x00); /* unprotect all registers */
+ tmp = cPtr->readXR(cPtr, 0x14);
+ cPtr->writeXR(cPtr, 0x14, tmp & ~0x20); /* enable vsync on ST01 */
+ }
+
+ chipsFixResume(pScrn);
+
+ /* wait for vsync if sequencer is running - stop sequencer */
+ if (cPtr->SyncResetIgn) { /* only do if sync reset is ignored */
+ while (((cPtr->readST01(cPtr)) & 0x08) == 0x08); /* VSync off */
+ while (((cPtr->readST01(cPtr)) & 0x08) == 0x00); /* VSync on */
+ hwp->writeSeq(hwp, 0x07, 0x00); /* reset hsync - just in case... */
+ }
+
+ /* set the clock */
+ chipsClockLoad(pScrn, &ChipsReg->Clock);
+
+ /* set extended regs */
+ chipsRestoreExtendedRegs(pScrn, ChipsReg);
+#if 0
+ /* if people complain about lock ups or blank screens -- reenable */
+ /* set CRTC registers - do it before sequencer restarts */
+ for (i=0; i<25; i++)
+ hwp->writeCrtc(hwp, i, VgaReg->CRTC[i]);
+#endif
+ /* set generic registers */
+ vgaHWRestore(pScrn, VgaReg,
+ VGA_SR_MODE | VGA_SR_CMAP | (restoreFonts ? VGA_SR_FONTS : 0));
+
+ /* set stretching registers */
+ if (IS_HiQV(cPtr)) {
+ chipsRestoreStretching(pScrn, (unsigned char)ChipsReg->FR[0x40],
+ (unsigned char)ChipsReg->FR[0x48]);
+#if 0
+ /* if people report about stretching not working -- reenable */
+ /* why twice ? :
+ * sometimes the console is not well restored even if these registers
+ * are good, re-write the registers works around it
+ */
+ chipsRestoreStretching(pScrn, (unsigned char)ChipsReg->FR[0x40],
+ (unsigned char)ChipsReg->FR[0x48]);
+#endif
+ } else if (!IS_Wingine(cPtr))
+ chipsRestoreStretching(pScrn, (unsigned char)ChipsReg->XR[0x55],
+ (unsigned char)ChipsReg->XR[0x57]);
+
+ /* perform a synchronous reset */
+ if (!cPtr->SyncResetIgn) {
+ if (!IS_HiQV(cPtr)) {
+ /* enable syncronous reset on 655xx */
+ tmp = cPtr->readXR(cPtr, 0x0E);
+ cPtr->writeXR(cPtr, 0x0E, tmp & 0x7F);
+ }
+ hwp->writeSeq(hwp, 0x00, 0x01);
+ usleep(10000);
+ hwp->writeSeq(hwp, 0x00, 0x03);
+ if (!IS_HiQV(cPtr))
+ cPtr->writeXR(cPtr, 0x0E, tmp);
+ }
+ /* Flag valid start address, if using CRT extensions */
+ if (IS_HiQV(cPtr) && (ChipsReg->XR[0x09] & 0x1) == 0x1) {
+ tmp = hwp->readCrtc(hwp, 0x40);
+ hwp->writeCrtc(hwp, 0x40, tmp | 0x80);
+ }
+
+ /* Fix resume again here, as Nozomi seems to need it */
+ chipsFixResume(pScrn);
+ /*vgaHWProtect(pScrn, FALSE);*/
+}
+
+static void
+chipsRestoreExtendedRegs(ScrnInfoPtr pScrn, CHIPSRegPtr Regs)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ int i;
+ unsigned char tmp;
+
+ if (IS_HiQV(cPtr)) {
+ /* set extended regs */
+ for (i = 0; i < 0x43; i++) {
+ if ((cPtr->readXR(cPtr, i)) != Regs->XR[i])
+ cPtr->writeXR(cPtr, i, Regs->XR[i]);
+ }
+
+ /* Set SAR04 multimedia register correctly */
+ if (cPtr->Flags & ChipsOverlay8plus16) {
+ cPtr->writeXR(cPtr, 0x4E, 0x04);
+ if (cPtr->readXR(cPtr, 0x4F) != Regs->XR[0x4F])
+ cPtr->writeXR(cPtr, 0x4F, Regs->XR[0x4F]);
+ }
+
+ /* Don't touch reserved memory control registers */
+ for (i = 0x50; i < 0xBF; i++) {
+ if ((cPtr->readXR(cPtr, i)) != Regs->XR[i])
+ cPtr->writeXR(cPtr, i, Regs->XR[i]);
+ }
+ /* Don't touch VCLK regs, but fix up MClk */
+
+ /* set mem clock */
+ tmp = cPtr->readXR(cPtr, 0xCE); /* Select Fixed MClk before */
+ cPtr->writeXR(cPtr, 0xCE, tmp & 0x7F);
+ if ((cPtr->readXR(cPtr, 0xCC)) != Regs->XR[0xCC])
+ cPtr->writeXR(cPtr, 0xCC, Regs->XR[0xCC]);
+ if ((cPtr->readXR(cPtr, 0xCD)) != Regs->XR[0xCD])
+ cPtr->writeXR(cPtr, 0xCD, Regs->XR[0xCD]);
+ if ((cPtr->readXR(cPtr, 0xCE)) != Regs->XR[0xCE])
+ cPtr->writeXR(cPtr, 0xCE, Regs->XR[0xCE]);
+
+ /* set flat panel regs. */
+ for (i = 0xD0; i < 0xFF; i++) {
+ if ((cPtr->readXR(cPtr, i)) != Regs->XR[i])
+ cPtr->writeXR(cPtr, i, Regs->XR[i]);
+ }
+ for (i = 0; i < 0x2; i++) {
+ if ((cPtr->readFR(cPtr, i)) != Regs->FR[i])
+ cPtr->writeFR(cPtr, i, Regs->FR[i]);
+ }
+ tmp = cPtr->readFR(cPtr, 0x03); /* restore the non clock bits */
+ cPtr->writeFR(cPtr, 0x03, ((Regs->FR[0x03] & 0xC3) | (tmp & ~0xC3)));
+ i++;
+ /* Don't touch alternate clock select reg. */
+ for (; i < 0x80; i++) {
+ if ( (i == 0x40) || (i==0x48)) {
+ /* !! set stretching but disable compensation */
+ cPtr->writeFR(cPtr, i, Regs->FR[i] & 0xFE);
+ continue ; /* some registers must be set before FR40/FR48 */
+ }
+ if ((cPtr->readFR(cPtr, i)) != Regs->FR[i])
+ cPtr->writeFR(cPtr, i, Regs->FR[i]);
+ }
+
+ /* set the multimedia regs */
+ for (i = 0x02; i < 0x80; i++) {
+ if ( (i == 0x43) || (i == 0x44))
+ continue;
+ if ((cPtr->readMR(cPtr, i)) != Regs->MR[i])
+ cPtr->writeMR(cPtr, i, Regs->MR[i]);
+ }
+
+ /* set extended crtc regs. */
+ for (i = 0x30; i < 0x80; i++) {
+ if ((hwp->readCrtc(hwp, i)) != Regs->CR[i])
+ hwp->writeCrtc(hwp, i, Regs->CR[i]);
+ }
+ } else {
+ /* set extended regs. */
+ for (i = 0; i < 0x30; i++) {
+ if ((cPtr->readXR(cPtr, i)) != Regs->XR[i])
+ cPtr->writeXR(cPtr, i, Regs->XR[i]);
+ }
+ cPtr->writeXR(cPtr, 0x15, 0x00); /* unprotect just in case ... */
+ /* Don't touch MCLK/VCLK regs. */
+ for (i = 0x34; i < 0x54; i++) {
+ if ((cPtr->readXR(cPtr, i)) != Regs->XR[i])
+ cPtr->writeXR(cPtr, i, Regs->XR[i]);
+ }
+ tmp = cPtr->readXR(cPtr, 0x54); /* restore the non clock bits */
+ cPtr->writeXR(cPtr, 0x54, ((Regs->XR[0x54] & 0xF3) | (tmp & ~0xF3)));
+ cPtr->writeXR(cPtr, 0x55, Regs->XR[0x55] & 0xFE); /* h-comp off */
+ cPtr->writeXR(cPtr, 0x56, Regs->XR[0x56]);
+ cPtr->writeXR(cPtr, 0x57, Regs->XR[0x57] & 0xFE); /* v-comp off */
+ for (i=0x58; i < 0x7D; i++) {/* don't touch XR7D and XR7F on WINGINE */
+ if ((cPtr->readXR(cPtr, i)) != Regs->XR[i])
+ cPtr->writeXR(cPtr, i, Regs->XR[i]);
+ }
+ }
+#ifdef DEBUG
+ /* debug - dump out all the extended registers... */
+ if (IS_HiQV(cPtr)) {
+ for (i = 0; i < 0xFF; i++) {
+ ErrorF("XR%X - %X : %X\n", i, ChipsReg->XR[i],
+ cPtr->readXR(cPtr, i));
+ }
+ for (i = 0; i < 0x80; i++) {
+ ErrorF("FR%X - %X : %X\n", i, ChipsReg->FR[i],
+ cPtr->readFR(cPtr, i));
+ }
+ } else {
+ for (i = 0; i < 0x80; i++) {
+ ErrorF("XR%X - %X : %X\n", i, ChipsReg->XR[i],
+ cPtr->readXR(cPtr, i));
+ }
+ }
+#endif
+}
+
+static void
+chipsRestoreStretching(ScrnInfoPtr pScrn, unsigned char ctHorizontalStretch,
+ unsigned char ctVerticalStretch)
+{
+ unsigned char tmp;
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ /* write to regs. */
+ if (IS_HiQV(cPtr)) {
+ tmp = cPtr->readFR(cPtr, 0x48);
+ cPtr->writeFR(cPtr, 0x48, (tmp & 0xFE) | (ctVerticalStretch & 0x01));
+ tmp = cPtr->readFR(cPtr, 0x40);
+ cPtr->writeFR(cPtr, 0x40, (tmp & 0xFE) | (ctHorizontalStretch & 0x01));
+ } else {
+ tmp = cPtr->readXR(cPtr, 0x55);
+ cPtr->writeXR(cPtr, 0x55, (tmp & 0xFE) | (ctHorizontalStretch & 0x01));
+ tmp = cPtr->readXR(cPtr, 0x57);
+ cPtr->writeXR(cPtr, 0x57, (tmp & 0xFE) | (ctVerticalStretch & 0x01));
+ }
+
+ usleep(20000); /* to be active */
+}
+
+static int
+chipsVideoMode(int vgaBitsPerPixel, int weightGreen, int displayHSize,
+ int displayVSize)
+{
+ /* 4 bpp 8 bpp 16 bpp 18 bpp 24 bpp 32 bpp */
+ /* 640 0x20 0x30 0x40 - 0x50 - */
+ /* 800 0x22 0x32 0x42 - 0x52 - */
+ /*1024 0x24 0x34 0x44 - 0x54 - for 1024x768 */
+ /*1024 - 0x36 0x47 - 0x56 - for 1024x600 */
+ /*1152 0x27 0x37 0x47 - 0x57 - */
+ /*1280 0x28 0x38 0x49 - - - */
+ /*1600 0x2C 0x3C 0x4C 0x5D - - */
+ /*This value is only for BIOS.... */
+
+ int videoMode = 0;
+
+ switch (vgaBitsPerPixel) {
+ case 1:
+ case 4:
+ videoMode = 0x20;
+ break;
+ case 8:
+ videoMode = 0x30;
+ break;
+ case 16:
+ videoMode = 0x40;
+ if (weightGreen != 5)
+ videoMode |= 0x01;
+ break;
+ default:
+ videoMode = 0x50;
+ break;
+ }
+
+ switch (displayHSize) {
+ case 800:
+ videoMode |= 0x02;
+ break;
+ case 1024:
+ videoMode |= 0x04;
+ if(displayVSize < 768)
+ videoMode |= 0x02;
+ break;
+ case 1152:
+ videoMode |= 0x07;
+ break;
+ case 1280:
+ videoMode |= 0x08;
+ if (vgaBitsPerPixel == 16)
+ videoMode |= 0x01;
+ break;
+ case 1600:
+ videoMode |= 0x0C;
+ if (vgaBitsPerPixel == 16)
+ videoMode |= 0x01;
+ break;
+ }
+
+ return videoMode;
+}
+
+
+/*
+ * Map the framebuffer and MMIO memory.
+ */
+
+static Bool
+chipsMapMem(ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ if (cPtr->Flags & ChipsLinearSupport) {
+ if (cPtr->UseMMIO) {
+ if (IS_HiQV(cPtr)) {
+ if (cPtr->Bus == ChipsPCI)
+ cPtr->MMIOBase = xf86MapPciMem(pScrn->scrnIndex,
+ VIDMEM_MMIO,cPtr->PciTag, cPtr->IOAddress,
+ 0x20000L);
+ else
+ cPtr->MMIOBase = xf86MapVidMem(pScrn->scrnIndex,
+ VIDMEM_MMIO, cPtr->IOAddress, 0x20000L);
+ } else {
+ if (cPtr->Bus == ChipsPCI)
+ cPtr->MMIOBase = xf86MapPciMem(pScrn->scrnIndex,
+ VIDMEM_MMIO, cPtr->PciTag, cPtr->IOAddress,
+ 0x10000L);
+ else
+ cPtr->MMIOBase = xf86MapVidMem(pScrn->scrnIndex,
+ VIDMEM_MMIO, cPtr->IOAddress, 0x10000L);
+ }
+
+ if (cPtr->MMIOBase == NULL)
+ return FALSE;
+ }
+
+ if (cPtr->Bus == ChipsPCI)
+ cPtr->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ cPtr->PciTag, (unsigned long)cPtr->FbAddress,
+ cPtr->FbMapSize);
+ else
+ cPtr->FbBase = xf86MapVidMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ (unsigned long)cPtr->FbAddress, cPtr->FbMapSize);
+
+ if (cPtr->FbBase == NULL)
+ return FALSE;
+ } else {
+ /* In paged mode Base is the VGA window at 0xA0000 */
+ cPtr->FbBase = hwp->Base;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+chipsUnmapMem(ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+
+ if (cPtr->Flags & ChipsLinearSupport) {
+ if (IS_HiQV(cPtr)) {
+ if (cPtr->MMIOBase)
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)cPtr->MMIOBase,
+ 0x20000);
+ } else {
+ if (cPtr->MMIOBase)
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)cPtr->MMIOBase,
+ 0x10000);
+ }
+ cPtr->MMIOBase = NULL;
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)cPtr->FbBase,
+ cPtr->FbMapSize);
+ }
+ cPtr->FbBase = NULL;
+
+ return TRUE;
+}
+
+static void
+chipsProtect(ScrnInfoPtr pScrn, Bool on)
+{
+ vgaHWProtect(pScrn, on);
+}
+
+static void
+chipsBlankScreen(ScrnInfoPtr pScrn, Bool unblank)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ unsigned char scrn;
+
+ /* fix things that could be messed up by suspend/resume */
+ if (!IS_HiQV(cPtr))
+ cPtr->writeXR(cPtr, 0x15, 0x00);
+
+ scrn = hwp->readSeq(hwp, 0x01);
+
+ if (unblank) {
+ scrn &= 0xDF; /* enable screen */
+ } else {
+ scrn |= 0x20; /* blank screen */
+ }
+
+ /* synchronous reset - stop counters */
+ if (!cPtr->SyncResetIgn) {
+ hwp->writeSeq(hwp, 0x00, 0x01);
+ }
+
+ hwp->writeSeq(hwp, 0x01, scrn); /* change mode */
+
+ /* end reset - start counters */
+ if (!cPtr->SyncResetIgn) {
+ hwp->writeSeq(hwp, 0x00, 0x03);
+ }
+}
+
+static void
+chipsLock(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char tmp;
+
+ vgaHWLock(hwp);
+
+ if (!IS_HiQV(cPtr)) {
+ /* group protection attribute controller access */
+ cPtr->writeXR(cPtr, 0x15, cPtr->SuspendHack.xr15);
+ tmp = cPtr->readXR(cPtr, 0x02);
+ cPtr->writeXR(cPtr, 0x02, (tmp & ~0x18) | cPtr->SuspendHack.xr02);
+ tmp = cPtr->readXR(cPtr, 0x14);
+ cPtr->writeXR(cPtr, 0x14, (tmp & ~0x20) | cPtr->SuspendHack.xr14);
+
+ /* reset 32 bit register access */
+ if (cPtr->Chipset > CHIPS_CT65540) {
+ tmp = cPtr->readXR(cPtr, 0x03);
+ cPtr->writeXR(cPtr, 0x03, (tmp & ~0x0A) | cPtr->SuspendHack.xr03);
+ }
+ }
+}
+
+static void
+chipsUnlock(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ unsigned char tmp;
+
+ if (!IS_HiQV(cPtr)) {
+ /* group protection attribute controller access */
+ cPtr->writeXR(cPtr, 0x15, 0x00);
+ tmp = cPtr->readXR(cPtr, 0x02);
+ cPtr->writeXR(cPtr, 0x02, (tmp & ~0x18));
+ tmp = cPtr->readXR(cPtr, 0x14);
+ cPtr->writeXR(cPtr, 0x14, (tmp & ~0x20));
+ /* enable 32 bit register access */
+ if (cPtr->Chipset > CHIPS_CT65540) {
+ cPtr->writeXR(cPtr, 0x03, cPtr->SuspendHack.xr03 | 0x0A);
+ }
+ }
+ vgaHWUnlock(hwp);
+}
+
+static void
+chipsHWCursorOn(CHIPSPtr cPtr)
+{
+ /* enable HW cursor */
+ if (cPtr->HWCursorShown) {
+ if (IS_HiQV(cPtr)) {
+ cPtr->writeXR(cPtr, 0xA0, cPtr->HWCursorContents & 0xFF);
+ } else {
+ HW_DEBUG(0x8);
+ if (cPtr->UseMMIO) {
+ MMIOmeml(DR(0x8)) = cPtr->HWCursorContents;
+ } else {
+ outl(DR(0x8), cPtr->HWCursorContents);
+ }
+ }
+ }
+}
+
+static void
+chipsHWCursorOff(CHIPSPtr cPtr)
+{
+ /* disable HW cursor */
+ if (cPtr->HWCursorShown) {
+ if (IS_HiQV(cPtr)) {
+ cPtr->HWCursorContents = cPtr->readXR(cPtr, 0xA0);
+ cPtr->writeXR(cPtr, 0xA0, cPtr->HWCursorContents & 0xF8);
+ } else {
+ HW_DEBUG(0x8);
+ if (cPtr->UseMMIO) {
+ cPtr->HWCursorContents = MMIOmeml(DR(0x8));
+ MMIOmemw(DR(0x8)) = cPtr->HWCursorContents & 0xFFFE;
+ } else {
+ cPtr->HWCursorContents = inl(DR(0x8));
+ outw(DR(0x8), cPtr->HWCursorContents & 0xFFFE);
+ }
+ }
+ }
+}
+
+void
+chipsFixResume(ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ unsigned char tmp;
+
+ /* fix things that could be messed up by suspend/resume */
+ if (!IS_HiQV(cPtr))
+ cPtr->writeXR(cPtr, 0x15, 0x00);
+ tmp = hwp->readMiscOut(hwp);
+ hwp->writeMiscOut(hwp, (tmp & 0xFE) | cPtr->SuspendHack.vgaIOBaseFlag);
+ tmp = hwp->readCrtc(hwp, 0x11);
+ hwp->writeCrtc(hwp, 0x11, (tmp & 0x7F));
+}
+
+static char
+chipsTestDACComp(ScrnInfoPtr pScrn, unsigned char a, unsigned char b,
+ unsigned char c)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ unsigned char type;
+
+ hwp->writeDacWriteAddr(hwp, 0x00);
+ while ((cPtr->readST01(cPtr)) & 0x08){}; /* wait for vsync to end */
+ while (!(cPtr->readST01(cPtr)) & 0x08){}; /* wait for new vsync */
+ hwp->writeDacData(hwp, a); /* set pattern */
+ hwp->writeDacData(hwp, b);
+ hwp->writeDacData(hwp, c);
+ while (!(cPtr->readST01(cPtr)) & 0x01){}; /* wait for hsync to end */
+ while ((cPtr->readST01(cPtr)) & 0x01){}; /* wait for hsync to end */
+ type = cPtr->readST00(cPtr); /* read comparator */
+ return (type & 0x10);
+}
+
+static int
+chipsProbeMonitor(ScrnInfoPtr pScrn)
+{
+ CHIPSPtr cPtr = CHIPSPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ unsigned char dacmask;
+ unsigned char dacdata[3];
+ unsigned char xr1, xr2;
+ int type = 2; /* no monitor */
+
+ dacmask = hwp->readDacMask(hwp); /* save registers */
+ hwp->writeDacMask(hwp, 0x00);
+ hwp->writeDacReadAddr(hwp, 0x00);
+
+ dacdata[0]=hwp->readDacData(hwp);
+ dacdata[1]=hwp->readDacData(hwp);
+ dacdata[2]=hwp->readDacData(hwp);
+
+ if (!IS_HiQV(cPtr)) {
+ xr1 = cPtr->readXR(cPtr, 0x06);
+ xr2 = cPtr->readXR(cPtr, 0x1F);
+ cPtr->writeXR(cPtr, 0x06, xr1 & 0xF1); /* turn on dac */
+ cPtr->writeXR(cPtr, 0x1F, xr2 & 0x7F); /* enable comp */
+ } else {
+ xr1 = cPtr->readXR(cPtr, 0x81);
+ xr2 = cPtr->readXR(cPtr, 0xD0);
+ cPtr->writeXR(cPtr, 0x81,(xr1 & 0xF0));
+ cPtr->writeXR(cPtr, 0xD0,(xr2 | 0x03));
+ }
+ if (chipsTestDACComp(pScrn, 0x12,0x12,0x12)) { /* test patterns */
+ if (chipsTestDACComp(pScrn,0x14,0x14,0x14)) /* taken from */
+ if (!chipsTestDACComp(pScrn,0x2D,0x14,0x14)) /* BIOS */
+ if (!chipsTestDACComp(pScrn,0x14,0x2D,0x14))
+ if (!chipsTestDACComp(pScrn,0x14,0x14,0x2D))
+ if (!chipsTestDACComp(pScrn,0x2D,0x2D,0x2D))
+ type = 0; /* color monitor */
+ } else {
+ if (chipsTestDACComp(pScrn,0x04,0x12,0x04))
+ if (!chipsTestDACComp(pScrn,0x1E,0x12,0x04))
+ if (!chipsTestDACComp(pScrn,0x04,0x2D,0x04))
+ if (!chipsTestDACComp(pScrn,0x1E,0x16,0x15))
+ if (chipsTestDACComp(pScrn,0x00,0x00,0x00))
+ type = 1; /* monochrome */
+ }
+
+ hwp->writeDacWriteAddr(hwp, 0x00); /* restore registers */
+ hwp->writeDacData(hwp, dacdata[0]);
+ hwp->writeDacData(hwp, dacdata[1]);
+ hwp->writeDacData(hwp, dacdata[2]);
+ hwp->writeDacMask(hwp, dacmask);
+ if (!IS_HiQV(cPtr)) {
+ cPtr->writeXR(cPtr,0x06,xr1);
+ cPtr->writeXR(cPtr,0x1F,xr2);
+ } else {
+ cPtr->writeXR(cPtr,0x81,xr1);
+ cPtr->writeXR(cPtr,0xD0,xr2);
+ }
+ return type;
+}
+
+static int
+chipsSetMonitor(ScrnInfoPtr pScrn)
+{
+ int tmp= chipsProbeMonitor(pScrn);
+
+ switch (tmp) {
+ case 0:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Color monitor detected\n");
+ break;
+ case 1:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Monochrome monitor detected\n");
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No monitor detected\n");
+ }
+ return (tmp);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.h b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.h
new file mode 100644
index 000000000..c43225257
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.h
@@ -0,0 +1,374 @@
+/* $XConsortium: ct_driver.h /main/3 1996/10/27 11:49:29 kaleb $ */
+/*
+ * Modified 1996 by Egbert Eich <Egbert.Eich@Physik.TH-Darmstadt.DE>
+ * Modified 1996 by David Bateman <dbateman@ee.uts.edu.au>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_driver.h,v 1.23 1999/08/14 10:49:42 dawes Exp $ */
+
+
+#ifndef _CT_DRIVER_H_
+#define _CT_DRIVER_H_
+
+#include "xaa.h"
+#include "xaalocal.h" /* XAA internals as we replace some of XAA */
+#include "xf86Cursor.h"
+#include "xf86i2c.h"
+#include "xf86DDC.h"
+
+/* Supported chipsets */
+typedef enum {
+ CHIPS_CT65520,
+ CHIPS_CT65525,
+ CHIPS_CT65530,
+ CHIPS_CT65535,
+ CHIPS_CT65540,
+ CHIPS_CT65545,
+ CHIPS_CT65546,
+ CHIPS_CT65548,
+ CHIPS_CT65550,
+ CHIPS_CT65554,
+ CHIPS_CT65555,
+ CHIPS_CT68554,
+ CHIPS_CT69000,
+ CHIPS_CT69030,
+ CHIPS_CT64200,
+ CHIPS_CT64300
+} CHIPSType;
+
+/* Clock related */
+typedef struct {
+ unsigned char msr; /* Dot Clock Related */
+ unsigned char fcr;
+ unsigned char xr02;
+ unsigned char xr03;
+ unsigned char xr33;
+ unsigned char xr54;
+ unsigned char fr03;
+ int Clock;
+ int FPClock;
+} CHIPSClockReg, *CHIPSClockPtr;
+
+typedef struct {
+ unsigned int ProbedClk;
+ unsigned int Max; /* Memory Clock Related */
+ unsigned int Clk;
+ unsigned char M;
+ unsigned char N;
+ unsigned char P;
+ unsigned char PSN;
+ unsigned char xrCC;
+ unsigned char xrCD;
+ unsigned char xrCE;
+} CHIPSMemClockReg, *CHIPSMemClockPtr;
+
+#define TYPE_HW 0x01
+#define TYPE_PROGRAMMABLE 0x02
+#define GET_TYPE 0x0F
+#define OLD_STYLE 0x10
+#define NEW_STYLE 0x20
+#define HiQV_STYLE 0x30
+#define WINGINE_1_STYLE 0x40 /* 64300: external clock; 4 clocks */
+#define WINGINE_2_STYLE 0x50 /* 64300: internal clock; 2 hw-clocks */
+#define GET_STYLE 0xF0
+#define LCD_TEXT_CLK_FREQ 25000 /* lcd textclock if TYPE_PROGRAMMABLE */
+#define CRT_TEXT_CLK_FREQ 28322 /* crt textclock if TYPE_PROGRAMMABLE */
+#define Fref 14318180 /* The reference clock in Hertz */
+
+/* The capability flags for the C&T chipsets */
+#define ChipsLinearSupport 0x00000001
+#define ChipsAccelSupport 0x00000002
+#define ChipsFullMMIOSupport 0x00000004
+#define ChipsMMIOSupport 0x00000008
+#define ChipsHDepthSupport 0x00000010
+#define ChipsDPMSSupport 0x00000020
+#define ChipsTMEDSupport 0x00000040
+#define ChipsGammaSupport 0x00000080
+
+/* Options flags for the C&T chipsets */
+#define ChipsHWCursor 0x00000100
+#define ChipsShadowFB 0x00000200
+#define ChipsOverlay8plus16 0x00000400
+
+/* Architecture type flags */
+#define ChipsHiQV 0x00001000
+#define ChipsWingine 0x00002000
+#define IS_Wingine(x) ((x->Flags) & ChipsWingine)
+#define IS_HiQV(x) ((x->Flags) & ChipsHiQV)
+
+/* Acceleration flags for the C&T chipsets */
+#define ChipsColorTransparency 0x0100000
+#define ChipsImageReadSupport 0x0200000
+
+/* Overlay Transparency Key */
+#define TRANSPARENCY_KEY 255
+
+/* Flag Bus Types */
+#define ChipsUnknown 0
+#define ChipsISA 1
+#define ChipsVLB 2
+#define ChipsPCI 3
+#define ChipsCPUDirect 4
+#define ChipsPIB 5
+#define ChipsMCB 6
+
+/* Macro's to select the 32 bit acceleration registers */
+#define DR(x) cPtr->Regs32[x] /* For CT655xx naming scheme */
+#define MR(x) cPtr->Regs32[x] /* CT655xx MMIO naming scheme */
+#define BR(x) cPtr->Regs32[x] /* For HiQV naming scheme */
+#define MMIOmeml(x) *(unsigned int *)(cPtr->MMIOBase + (x))
+#define MMIOmemw(x) *(unsigned short *)(cPtr->MMIOBase + (x))
+
+/* Monitor or flat panel type flags */
+#define ChipsCRT 0x0010
+#define ChipsLCD 0x1000
+#define ChipsTFT 0x0100
+#define ChipsDS 0x0200
+#define ChipsDD 0x0400
+#define ChipsSS 0x0800
+#define IS_STN(x) ((x) & 0xE00)
+
+/* Storage for the registers of the C&T chipsets */
+typedef struct {
+ unsigned char XR[0xFF];
+ unsigned char CR[0x80];
+ unsigned char FR[0x80];
+ unsigned char MR[0x80];
+ CHIPSClockReg Clock;
+} CHIPSRegRec, *CHIPSRegPtr;
+
+/* Storage for the flat panel size */
+typedef struct {
+ int HDisplay;
+ int HRetraceStart;
+ int HRetraceEnd;
+ int HTotal;
+ int VDisplay;
+ int VRetraceStart;
+ int VTotal;
+} CHIPSPanelSizeRec, *CHIPSPanelSizePtr;
+
+/* Some variables needed in the XAA acceleration */
+typedef struct {
+ /* General variable */
+ unsigned int CommandFlags;
+ unsigned int BytesPerPixel;
+ unsigned int BitsPerPixel;
+ unsigned int FbOffset;
+ unsigned int PitchInBytes;
+ unsigned int ScratchAddress;
+ /* 64k for color expansion and imagewrites */
+ unsigned char * BltDataWindow;
+ /* Hardware cursor address */
+ unsigned int CursorAddress;
+ Bool UseHWCursor;
+ /* Boundaries of the pixmap cache */
+ unsigned int CacheStart;
+ unsigned int CacheEnd;
+ /* Storage for pattern mask */
+ int planemask;
+ /* Storage for foreground and background color */
+ int fgColor;
+ int bgColor;
+ /* For the 8x8 pattern fills */
+ int patternyrot;
+ /* For cached stipple fills */
+ int SlotWidth;
+ /* Variables for the 24bpp fill */
+ unsigned char fgpixel;
+ unsigned char bgpixel;
+ unsigned char xorpixel;
+ Bool fastfill;
+ Bool rgb24equal;
+ int fillindex;
+ unsigned int width24bpp;
+ unsigned int color24bpp;
+ unsigned int rop24bpp;
+} CHIPSACLRec, *CHIPSACLPtr;
+#define CHIPSACLPTR(p) &((CHIPSPtr)((p)->driverPrivate))->Accel
+
+/* Storage for some register values that are messed up by suspend/resumes */
+typedef struct {
+ unsigned char xr02;
+ unsigned char xr03;
+ unsigned char xr14;
+ unsigned char xr15;
+ unsigned char vgaIOBaseFlag;
+} CHIPSSuspendHackRec, *CHIPSSuspendHackPtr;
+
+/* The functions to access the C&T extended registers */
+typedef struct _CHIPSRec *CHIPSPtr;
+typedef CARD8 (*chipsReadXRPtr)(CHIPSPtr cPtr, CARD8 index);
+typedef void (*chipsWriteXRPtr)(CHIPSPtr cPtr, CARD8 index, CARD8 value);
+typedef CARD8 (*chipsReadFRPtr)(CHIPSPtr cPtr, CARD8 index);
+typedef void (*chipsWriteFRPtr)(CHIPSPtr cPtr, CARD8 index, CARD8 value);
+typedef CARD8 (*chipsReadMRPtr)(CHIPSPtr cPtr, CARD8 index);
+typedef void (*chipsWriteMRPtr)(CHIPSPtr cPtr, CARD8 index, CARD8 value);
+
+/* C&T functions to access VGA Input status registers 0 and 1 */
+typedef CARD8 (*chipsReadST00Ptr)(CHIPSPtr cPtr);
+typedef CARD8 (*chipsReadST01Ptr)(CHIPSPtr cPtr);
+
+/* C&T functions to access the VGA feature control register */
+typedef CARD8 (*chipsReadFCRPtr)(CHIPSPtr cPtr);
+typedef void (*chipsWriteFCRPtr)(CHIPSPtr cPtr, CARD8 value);
+
+/* The privates of the C&T driver */
+#define CHIPSPTR(p) ((CHIPSPtr)((p)->driverPrivate))
+
+typedef struct _CHIPSRec {
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ int Chipset;
+ EntityInfoPtr pEnt;
+ CARD32 IOAddress;
+ CARD32 FbAddress;
+ unsigned int IOBase;
+ unsigned char * FbBase;
+ unsigned char * MMIOBase;
+ long FbMapSize;
+ unsigned char * ShadowPtr;
+ int ShadowPitch;
+ int FbOffset16;
+ int FbSize16;
+ OptionInfoPtr Options;
+ CHIPSPanelSizeRec PanelSize;
+ int FrameBufferSize;
+ Bool SyncResetIgn;
+ Bool UseMMIO;
+ Bool UseFullMMIO;
+ int Monitor;
+ int MinClock;
+ int MaxClock;
+ CHIPSClockReg SaveClock; /* Storage for ClockSelect */
+ CHIPSMemClockReg MemClock;
+ unsigned char ClockType;
+ unsigned char CRTClk[4];
+ unsigned char FPClk[4];
+ int FPclock;
+ int FPclkInx;
+ int CRTclkInx;
+ Bool FPClkModified;
+ int ClockMulFactor;
+ int Rounding;
+ CHIPSSuspendHackRec SuspendHack;
+ CARD32 PanelType;
+ CHIPSRegRec ModeReg;
+ CHIPSRegRec SavedReg;
+ unsigned int * Regs32;
+ unsigned int Flags;
+ CARD32 Bus;
+ XAAInfoRecPtr AccelInfoRec;
+ xf86CursorInfoPtr CursorInfoRec;
+ CHIPSACLRec Accel;
+ unsigned int HWCursorContents;
+ Bool HWCursorShown;
+ DGAModePtr DGAModes;
+ int numDGAModes;
+ Bool DGAactive;
+ int DGAViewportStatus;
+ CloseScreenProcPtr CloseScreen;
+#ifdef __arm32__
+#ifdef __NetBSD__
+ int TVMode;
+#endif
+ int Bank;
+#endif
+ unsigned char ddc_mask;
+ I2CBusPtr I2C;
+ chipsReadXRPtr readXR;
+ chipsWriteXRPtr writeXR;
+ chipsReadFRPtr readFR;
+ chipsWriteFRPtr writeFR;
+ chipsReadMRPtr readMR;
+ chipsWriteMRPtr writeMR;
+ chipsReadFCRPtr readFCR;
+ chipsWriteFCRPtr writeFCR;
+ chipsReadST00Ptr readST00;
+ chipsReadST01Ptr readST01;
+} CHIPSRec;
+
+typedef struct _CHIPSi2c {
+ unsigned char i2cClockBit;
+ unsigned char i2cDataBit;
+ CHIPSPtr cPtr;
+} CHIPSI2CRec, *CHIPSI2CPtr;
+
+/* External variables */
+extern int ChipsAluConv[];
+extern int ChipsAluConv2[];
+extern int ChipsAluConv3[];
+extern unsigned int ChipsReg32[];
+extern unsigned int ChipsReg32HiQV[];
+
+/* Prototypes */
+
+void CHIPSAdjustFrame(int scrnIndex, int x, int y, int flags);
+Bool CHIPSSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+
+/* banking */
+int CHIPSSetRead(ScreenPtr pScreen, int bank);
+int CHIPSSetWrite(ScreenPtr pScreen, int bank);
+int CHIPSSetReadWrite(ScreenPtr pScreen, int bank);
+int CHIPSSetReadPlanar(ScreenPtr pScreen, int bank);
+int CHIPSSetWritePlanar(ScreenPtr pScreen, int bank);
+int CHIPSSetReadWritePlanar(ScreenPtr pScreen, int bank);
+int CHIPSWINSetRead(ScreenPtr pScreen, int bank);
+int CHIPSWINSetWrite(ScreenPtr pScreen, int bank);
+int CHIPSWINSetReadWrite(ScreenPtr pScreen, int bank);
+int CHIPSWINSetReadPlanar(ScreenPtr pScreen, int bank);
+int CHIPSWINSetWritePlanar(ScreenPtr pScreen, int bank);
+int CHIPSWINSetReadWritePlanar(ScreenPtr pScreen, int bank);
+int CHIPSHiQVSetReadWrite(ScreenPtr pScreen, int bank);
+int CHIPSHiQVSetReadWritePlanar(ScreenPtr pScreen, int bank);
+
+/* acceleration */
+Bool CHIPSAccelInit(ScreenPtr pScreen);
+void CHIPSSync(ScrnInfoPtr pScrn);
+Bool CHIPSMMIOAccelInit(ScreenPtr pScreen);
+void CHIPSMMIOSync(ScrnInfoPtr pScrn);
+Bool CHIPSHiQVAccelInit(ScreenPtr pScreen);
+void CHIPSHiQVSync(ScrnInfoPtr pScrn);
+Bool CHIPSCursorInit(ScreenPtr pScreen);
+
+/* register access functions */
+void CHIPSSetStdExtFuncs(CHIPSPtr cPtr);
+void CHIPSSetMmioExtFuncs(CHIPSPtr cPtr);
+void CHIPSHWSetMmioFuncs(ScrnInfoPtr pScrn, CARD8 *base, int offset);
+
+/* ddc */
+extern void chips_ddc1(ScrnInfoPtr pScrn);
+extern Bool chips_i2cInit(ScrnInfoPtr pScrn);
+
+/* dga */
+Bool CHIPSDGAInit(ScreenPtr pScreen);
+
+/* To aid debugging of 32 bit register access we make the following defines */
+/*
+#define DEBUG
+#define CT_HW_DEBUG
+*/
+#if defined(DEBUG) & defined(CT_HW_DEBUG)
+#define HW_DEBUG(x) {usleep(500000); ErrorF("Register/Address: 0x%X\n",x);}
+#else
+#define HW_DEBUG(x)
+#endif
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_regs.c b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_regs.c
new file mode 100644
index 000000000..4064cc045
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/ct_regs.c
@@ -0,0 +1,502 @@
+/*
+ * Created 1998 by David Bateman <dbateman@eng.uts.edu.au>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/ct_regs.c,v 1.1 1998/12/20 11:57:44 dawes Exp $ */
+
+/*
+ * The functions in this file are used to read/write the C&T extension register
+ * and supply MMIO replacements of the VGA register access functions in
+ * vgaHW.c for chips that support MMIO access (eg 69000). Unlike the MGA
+ * chips, for instance, the C&T chipsets don't have a direct mapping between
+ * the MMIO mapped vga registers and the PIO versions.
+ *
+ * In General, these are the ONLY supported way of access the video processors
+ * registers. Exception are
+ *
+ * 1) chipsFindIsaDevice, where we don't know the chipset and so we don't know
+ * if the chipset supports MMIO access to its VGA registers, and we don't
+ * know the chips MemBase address and so can't map the VGA registers even
+ * if the chip did support MMIO. This effectively limits the use of non-PCI
+ * MMIO and multihead to a single card accessing 0x3D6/0x3D7. I.E. You can
+ * only have a single C&T card in a non-PCI multihead arrangement. Also as
+ * ISA has no method to disable I/O access to a card ISA multihead will
+ * never be supported.
+ *
+ * 2) ct_Blitter.h, ct_BlitMM.h and ct_BltHiQV.h, where speed is crucial and
+ * we know exactly whether we are using MMIO or PIO.
+ *
+ * 3) The 6554x 32bit DRxx in ct_cursor.c where the choice between MMIO and
+ * PIO is made explicitly
+ */
+
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.h"
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* This is used for module versioning */
+#include "xf86Version.h"
+
+/* All drivers using the vgahw module need this */
+#include "vgaHW.h"
+
+/* Driver specific headers */
+#include "ct_driver.h"
+
+#define CHIPS_MONO_STAT_1 0x3BA
+#define CHIPS_STAT_0 0x3BA
+#define CHIPS_FR_INDEX 0x3D0
+#define CHIPS_FR_DATA 0x3D1
+#define CHIPS_MR_INDEX 0x3D2
+#define CHIPS_MR_DATA 0x3D3
+#define CHIPS_XR_INDEX 0x3D6
+#define CHIPS_XR_DATA 0x3D7
+#define CHIPS_COLOR_STAT_1 0x3DA
+
+#define CHIPS_MMIO_MONO_CRTC_INDEX 0x768
+#define CHIPS_MMIO_MONO_CRTC_DATA 0x769
+#define CHIPS_MMIO_MONO_STAT_1 0x774
+#define CHIPS_MMIO_ATTR_INDEX 0x780
+#define CHIPS_MMIO_ATTR_DATA_W 0x780
+#define CHIPS_MMIO_ATTR_DATA_R 0x781
+#define CHIPS_MMIO_STAT_0 0x784
+#define CHIPS_MMIO_MISC_OUT_W 0x784
+#define CHIPS_MMIO_SEQ_INDEX 0x788
+#define CHIPS_MMIO_SEQ_DATA 0x789
+#define CHIPS_MMIO_DAC_MASK 0x78C
+#define CHIPS_MMIO_DAC_READ_ADDR 0x78D
+#define CHIPS_MMIO_DAC_WRITE_ADDR 0x790
+#define CHIPS_MMIO_DAC_DATA 0x791
+#define CHIPS_MMIO_FEATURE_R 0x794
+#define CHIPS_MMIO_MISC_OUT_R 0x798
+#define CHIPS_MMIO_GRAPH_INDEX 0x79C
+#define CHIPS_MMIO_GRAPH_DATA 0x79D
+#define CHIPS_MMIO_FR_INDEX 0x7A0
+#define CHIPS_MMIO_FR_DATA 0x7A1
+#define CHIPS_MMIO_MR_INDEX 0x7A4
+#define CHIPS_MMIO_MR_DATA 0x7A5
+#define CHIPS_MMIO_COLOR_CRTC_INDEX 0x7A8
+#define CHIPS_MMIO_COLOR_CRTC_DATA 0x7A9
+#define CHIPS_MMIO_XR_INDEX 0x7AC
+#define CHIPS_MMIO_XR_DATA 0x7AD
+#define CHIPS_MMIO_COLOR_STAT_1 0x7B4
+
+/*
+ * PIO Access to the C&T extension registers
+ */
+static void
+chipsStdWriteXR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
+{
+ outb(CHIPS_XR_INDEX, index);
+ outb(CHIPS_XR_DATA, value);
+}
+
+static CARD8
+chipsStdReadXR(CHIPSPtr cPtr, CARD8 index)
+{
+ outb(CHIPS_XR_INDEX, index);
+ return inb(CHIPS_XR_DATA);
+}
+
+static void
+chipsStdWriteFR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
+{
+ outb(CHIPS_FR_INDEX, index);
+ outb(CHIPS_FR_DATA, value);
+}
+
+static CARD8
+chipsStdReadFR(CHIPSPtr cPtr, CARD8 index)
+{
+ outb(CHIPS_FR_INDEX, index);
+ return inb(CHIPS_FR_DATA);
+}
+
+static void
+chipsStdWriteMR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
+{
+ outb(CHIPS_MR_INDEX, index);
+ outb(CHIPS_MR_DATA, value);
+}
+
+static CARD8
+chipsStdReadMR(CHIPSPtr cPtr, CARD8 index)
+{
+ outb(CHIPS_MR_INDEX, index);
+ return inb(CHIPS_MR_DATA);
+}
+
+static CARD8
+chipsStdReadFCR(CHIPSPtr cPtr)
+{
+ return inb(VGA_FEATURE_R);
+}
+
+static void
+chipsStdWriteFCR(CHIPSPtr cPtr, CARD8 value)
+{
+ if (cPtr->IOBase == VGA_IOBASE_MONO) {
+ outb(CHIPS_MONO_STAT_1, value);
+ } else {
+ outb(CHIPS_COLOR_STAT_1, value);
+ }
+}
+
+static CARD8
+chipsStdReadST00(CHIPSPtr cPtr)
+{
+ return inb(CHIPS_STAT_0);
+}
+
+static CARD8
+chipsStdReadST01(CHIPSPtr cPtr)
+{
+ if (cPtr->IOBase == VGA_IOBASE_MONO)
+ return inb(CHIPS_MONO_STAT_1);
+ else
+ return inb(CHIPS_COLOR_STAT_1);
+}
+
+void
+CHIPSSetStdExtFuncs(CHIPSPtr cPtr)
+{
+ cPtr->writeFR = chipsStdWriteFR;
+ cPtr->readFR = chipsStdReadFR;
+ cPtr->writeMR = chipsStdWriteMR;
+ cPtr->readMR = chipsStdReadMR;
+ cPtr->writeXR = chipsStdWriteXR;
+ cPtr->readXR = chipsStdReadXR;
+ cPtr->writeFCR = chipsStdWriteFCR;
+ cPtr->readFCR = chipsStdReadFCR;
+ cPtr->readST00 = chipsStdReadST00;
+ cPtr->readST01 = chipsStdReadST01;
+}
+
+/*
+ * MMIO Access to the C&T extension registers
+ */
+
+#ifndef __alpha__
+#define chipsminb(p) *(volatile CARD8 *)(cPtr->MMIOBase + (p))
+#define chipsmoutb(p,v) *(volatile CARD8 *)(cPtr->MMIOBase + (p)) = (v)
+#else
+#define chipsminb(p) xf86ReadSparse8(cPtr->MMIOBase, (p))
+#define chipsmoutb(p,v) xf86WriteSparse8((v), cPtr->MMIOBase, (p))
+#endif
+
+static void
+chipsMmioWriteXR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
+{
+ chipsmoutb(CHIPS_MMIO_XR_INDEX, index);
+ chipsmoutb(CHIPS_MMIO_XR_DATA, value);
+}
+
+static CARD8
+chipsMmioReadXR(CHIPSPtr cPtr, CARD8 index)
+{
+ chipsmoutb(CHIPS_MMIO_XR_INDEX, index);
+ return chipsminb(CHIPS_MMIO_XR_DATA);
+}
+
+static void
+chipsMmioWriteFR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
+{
+ chipsmoutb(CHIPS_MMIO_FR_INDEX, index);
+ chipsmoutb(CHIPS_MMIO_FR_DATA, value);
+}
+
+static CARD8
+chipsMmioReadFR(CHIPSPtr cPtr, CARD8 index)
+{
+ chipsmoutb(CHIPS_MMIO_FR_INDEX, index);
+ return chipsminb(CHIPS_MMIO_FR_DATA);
+}
+
+static void
+chipsMmioWriteMR(CHIPSPtr cPtr, CARD8 index, CARD8 value)
+{
+ chipsmoutb(CHIPS_MMIO_MR_INDEX, index);
+ chipsmoutb(CHIPS_MMIO_MR_DATA, value);
+}
+
+static CARD8
+chipsMmioReadMR(CHIPSPtr cPtr, CARD8 index)
+{
+ chipsmoutb(CHIPS_MMIO_MR_INDEX, index);
+ return chipsminb(CHIPS_MMIO_MR_DATA);
+}
+
+static CARD8
+chipsMmioReadFCR(CHIPSPtr cPtr)
+{
+ return chipsminb(CHIPS_MMIO_FEATURE_R);
+}
+
+static void
+chipsMmioWriteFCR(CHIPSPtr cPtr, CARD8 value)
+{
+ if (cPtr->IOBase == VGA_IOBASE_MONO) {
+ chipsmoutb(CHIPS_MMIO_MONO_STAT_1, value);
+ } else {
+ chipsmoutb(CHIPS_MMIO_COLOR_STAT_1, value);
+ }
+}
+
+static CARD8
+chipsMmioReadST00(CHIPSPtr cPtr)
+{
+ return chipsminb(CHIPS_MMIO_STAT_0);
+}
+
+static CARD8
+chipsMmioReadST01(CHIPSPtr cPtr)
+{
+ if (cPtr->IOBase == VGA_IOBASE_MONO)
+ return chipsminb(CHIPS_MMIO_MONO_STAT_1);
+ else
+ return chipsminb(CHIPS_MMIO_COLOR_STAT_1);
+}
+
+void
+CHIPSSetMmioExtFuncs(CHIPSPtr cPtr)
+{
+ cPtr->writeFR = chipsMmioWriteFR;
+ cPtr->readFR = chipsMmioReadFR;
+ cPtr->writeMR = chipsMmioWriteMR;
+ cPtr->readMR = chipsMmioReadMR;
+ cPtr->writeXR = chipsMmioWriteXR;
+ cPtr->readXR = chipsMmioReadXR;
+ cPtr->writeFCR = chipsMmioWriteFCR;
+ cPtr->readFCR = chipsMmioReadFCR;
+ cPtr->readST00 = chipsMmioReadST00;
+ cPtr->readST01 = chipsMmioReadST01;
+}
+
+/*
+ * MMIO versions of the VGA register access functions.
+ */
+
+#ifndef __alpha__
+#define minb(p) *(volatile CARD8 *)(hwp->MMIOBase + (p))
+#define moutb(p,v) *(volatile CARD8 *)(hwp->MMIOBase + (p)) = (v)
+#else
+#define minb(p) xf86ReadSparse8(hwp->MMIOBase, (p))
+#define moutb(p,v) xf86WriteSparse8((v), hwp->MMIOBase, (p))
+#endif
+
+static void
+chipsMmioWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ if (hwp->IOBase == VGA_IOBASE_MONO) {
+ moutb(CHIPS_MMIO_MONO_CRTC_INDEX, index);
+ moutb(CHIPS_MMIO_MONO_CRTC_DATA, value);
+ } else {
+ moutb(CHIPS_MMIO_COLOR_CRTC_INDEX, index);
+ moutb(CHIPS_MMIO_COLOR_CRTC_DATA, value);
+ }
+}
+
+static CARD8
+chipsMmioReadCrtc(vgaHWPtr hwp, CARD8 index)
+{
+ if (hwp->IOBase == VGA_IOBASE_MONO) {
+ moutb(CHIPS_MMIO_MONO_CRTC_INDEX, index);
+ return minb(CHIPS_MMIO_MONO_CRTC_DATA);
+ } else {
+ moutb(CHIPS_MMIO_COLOR_CRTC_INDEX, index);
+ return minb(CHIPS_MMIO_COLOR_CRTC_DATA);
+ }
+}
+
+static void
+chipsMmioWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ moutb(CHIPS_MMIO_GRAPH_INDEX, index);
+ moutb(CHIPS_MMIO_GRAPH_DATA, value);
+}
+
+static CARD8
+chipsMmioReadGr(vgaHWPtr hwp, CARD8 index)
+{
+ moutb(CHIPS_MMIO_GRAPH_INDEX, index);
+ return minb(CHIPS_MMIO_GRAPH_DATA);
+}
+
+static void
+chipsMmioWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ moutb(CHIPS_MMIO_SEQ_INDEX, index);
+ moutb(CHIPS_MMIO_SEQ_DATA, value);
+}
+
+static CARD8
+chipsMmioReadSeq(vgaHWPtr hwp, CARD8 index)
+{
+ moutb(CHIPS_MMIO_SEQ_INDEX, index);
+ return minb(CHIPS_MMIO_SEQ_DATA);
+}
+
+static void
+chipsMmioWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ CARD8 tmp;
+
+ if (hwp->paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+
+ if (hwp->IOBase == VGA_IOBASE_MONO)
+ tmp = minb(CHIPS_MMIO_MONO_STAT_1);
+ else
+ tmp = minb(CHIPS_MMIO_COLOR_STAT_1);
+ moutb(CHIPS_MMIO_ATTR_INDEX, index);
+ moutb(CHIPS_MMIO_ATTR_DATA_W, value);
+}
+
+static CARD8
+chipsMmioReadAttr(vgaHWPtr hwp, CARD8 index)
+{
+ CARD8 tmp;
+
+ if (hwp->paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+
+ if (hwp->IOBase == VGA_IOBASE_MONO)
+ tmp = minb(CHIPS_MMIO_MONO_STAT_1);
+ else
+ tmp = minb(CHIPS_MMIO_COLOR_STAT_1);
+ moutb(CHIPS_MMIO_ATTR_INDEX, index);
+ return minb(CHIPS_MMIO_ATTR_DATA_R);
+}
+
+static void
+chipsMmioWriteMiscOut(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(CHIPS_MMIO_MISC_OUT_W, value);
+}
+
+static CARD8
+chipsMmioReadMiscOut(vgaHWPtr hwp)
+{
+ return minb(CHIPS_MMIO_MISC_OUT_R);
+}
+
+static void
+chipsMmioEnablePalette(vgaHWPtr hwp)
+{
+ CARD8 tmp;
+
+ if (hwp->IOBase == VGA_IOBASE_MONO)
+ tmp = minb(CHIPS_MMIO_MONO_STAT_1);
+ else
+ tmp = minb(CHIPS_MMIO_COLOR_STAT_1);
+ moutb(CHIPS_MMIO_ATTR_INDEX, 0x00);
+ hwp->paletteEnabled = TRUE;
+}
+
+static void
+chipsMmioDisablePalette(vgaHWPtr hwp)
+{
+ CARD8 tmp;
+
+ if (hwp->IOBase == VGA_IOBASE_MONO)
+ tmp = minb(CHIPS_MMIO_MONO_STAT_1);
+ else
+ tmp = minb(CHIPS_MMIO_COLOR_STAT_1);
+ moutb(CHIPS_MMIO_ATTR_INDEX, 0x20);
+ hwp->paletteEnabled = FALSE;
+}
+
+static void
+chipsMmioWriteDacMask(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(CHIPS_MMIO_DAC_MASK, value);
+}
+
+static CARD8
+chipsMmioReadDacMask(vgaHWPtr hwp)
+{
+ return minb(CHIPS_MMIO_DAC_MASK);
+}
+
+static void
+chipsMmioWriteDacReadAddr(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(CHIPS_MMIO_DAC_READ_ADDR, value);
+}
+
+static void
+chipsMmioWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(CHIPS_MMIO_DAC_WRITE_ADDR, value);
+}
+
+static void
+chipsMmioWriteDacData(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(CHIPS_MMIO_DAC_DATA, value);
+}
+
+static CARD8
+chipsMmioReadDacData(vgaHWPtr hwp)
+{
+ return minb(CHIPS_MMIO_DAC_DATA);
+}
+
+void
+CHIPSHWSetMmioFuncs(ScrnInfoPtr pScrn, CARD8 *base, int offset)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ hwp->writeCrtc = chipsMmioWriteCrtc;
+ hwp->readCrtc = chipsMmioReadCrtc;
+ hwp->writeGr = chipsMmioWriteGr;
+ hwp->readGr = chipsMmioReadGr;
+ hwp->writeAttr = chipsMmioWriteAttr;
+ hwp->readAttr = chipsMmioReadAttr;
+ hwp->writeSeq = chipsMmioWriteSeq;
+ hwp->readSeq = chipsMmioReadSeq;
+ hwp->writeMiscOut = chipsMmioWriteMiscOut;
+ hwp->readMiscOut = chipsMmioReadMiscOut;
+ hwp->enablePalette = chipsMmioEnablePalette;
+ hwp->disablePalette = chipsMmioDisablePalette;
+ hwp->writeDacMask = chipsMmioWriteDacMask;
+ hwp->readDacMask = chipsMmioReadDacMask;
+ hwp->writeDacWriteAddr = chipsMmioWriteDacWriteAddr;
+ hwp->writeDacReadAddr = chipsMmioWriteDacReadAddr;
+ hwp->writeDacData = chipsMmioWriteDacData;
+ hwp->readDacData = chipsMmioReadDacData;
+ hwp->MMIOBase = base;
+ hwp->MMIOOffset = offset;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/util/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/chips/util/Imakefile
new file mode 100644
index 000000000..3f064a7f3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/util/Imakefile
@@ -0,0 +1,13 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/Imakefile,v 1.2 1998/07/25 16:55:43 dawes Exp $
+
+INCLUDES = -I../../../SuperProbe
+
+PROGS = dRegs mRegs modClock memClock
+
+AllTarget(ProgramTargetName($(PROGS)))
+NormalProgramTarget(dRegs,dRegs.o,NullParameter,NullParameter,NullParameter)
+NormalProgramTarget(mRegs,mRegs.o,NullParameter,NullParameter,NullParameter)
+NormalProgramTarget(modClock,modClock.o,NullParameter,NullParameter,NullParameter)
+LinkFile(memClock,modClock)
+
+DependTarget()
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/util/dRegs.c b/xc/programs/Xserver/hw/xfree86/drivers/chips/util/dRegs.c
new file mode 100644
index 000000000..fc9c0c804
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/util/dRegs.c
@@ -0,0 +1,277 @@
+/* $XConsortium: dRegs.c /main/2 1996/10/27 11:49:40 kaleb $ */
+
+
+
+
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/dRegs.c,v 1.4 1999/04/04 08:46:14 dawes Exp $ */
+
+#ifdef __NetBSD__
+# include <sys/types.h>
+# include <machine/pio.h>
+# include <machine/sysarch.h>
+#else
+# ifdef SVR4
+# include <sys/types.h>
+# ifdef NCR
+ /* broken NCR <sys/sysi86.h> */
+# define __STDC
+# include <sys/sysi86.h>
+# undef __STDC
+# else
+# include <sys/sysi86.h>
+# endif
+# ifdef SVR4
+# if !defined(sun)
+# include <sys/seg.h>
+# endif
+# endif
+# include <sys/v86.h>
+# if defined(sun)
+# include <sys/psw.h>
+# endif
+# endif
+# include "AsmMacros.h"
+#endif /* NetBSD */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef __NetBSD__
+# define SET_IOPL() i386_iopl(3)
+# define RESET_IOPL() i386_iopl(0)
+#else
+# ifdef SVR4
+# ifndef SI86IOPL
+# define SET_IOPL() sysi86(SI86V86,V86SC_IOPL,PS_IOPL)
+# define RESET_IOPL() sysi86(SI86V86,V86SC_IOPL,0)
+# else
+# define SET_IOPL() sysi86(SI86IOPL,3)
+# define RESET_IOPL() sysi86(SI86IOPL,0)
+# endif
+# else
+# ifndef Lynx
+# define SET_IOPL() iopl(3)
+# define RESET_IOPL() iopl(0)
+# else
+# define SET_IOPL() 0
+# define RESET_IOPL() 0
+# endif
+# endif
+#endif
+
+void main(void)
+{
+ int i, HTotal, HDisplay, HSyncStart, HSyncEnd,
+ VTotal, VDisplay, VSyncStart, VSyncEnd, Clock;
+ unsigned char storeReg, bpp, shift;
+ unsigned short port;
+ int isHiQV = 0;
+
+ SET_IOPL();
+
+ printf("0x3C6\t0x%X\n",inw(0x3C6));
+
+/* Check to see if the Chip is HiQV */
+ outb(0x3D6,0x02);
+ storeReg = inb(0x3D7);
+ if (storeReg == 0xE0 /* CT65550 */
+ || storeReg == 0xE4 /* CT65554 */
+ || storeReg == 0xE5 /* CT65555 */
+ || storeReg == 0xF4 /* CT68554 */
+ || storeReg == 0xC0) /* CT69000 */
+ {
+ isHiQV = 1;
+ }
+
+ printf("port 0x3D6 (C&T)\n");
+ storeReg = inb(0x3D6);
+ shift = 3;
+ if (isHiQV==1) {
+ outw(0x102,1); /*global enable, VGA awake*/
+ printf("0x%2X\n",inb(0x3C3)&0xFF);
+ outb(0x3C3,0); /*disable VGA*/
+ outb(0x3C3,1); /*enable VGA*/
+ for(i = 0;i < 0xFF;i++){
+ outb(0x3D6,i);
+ printf("XR 0x%2X\t0x%X\n",i,inb(0x3D7)&0xFF);
+ }
+ outb(0x3D6,0xE2);
+ bpp = inb(0x3D7)&0xF0;
+ } else {
+ outb(0x3D6, 0x70);
+ outw(0x3D6, (inw(0x3D6) | 0x8070));
+ outw(0x46E8,0x0016); /*setup mode*/
+ outw(0x102,1); /*global enable, VGA awake*/
+ outw(0x46E8,0x000E); /*exit from setup mode*/
+ printf("0x%2X\n",inb(0x3C3)&0xFF);
+ outb(0x3C3,0); /*disable VGA*/
+ outw(0x46E8,0x0000); /*exit from setup mode*/
+ outw(0x46E8,0x000E); /*exit from setup mode*/
+ outb(0x3C3,1); /*enable VGA*/
+ outw(0x46E8,0x0000); /*exit from setup mode*/
+ for(i = 0;i < 0x80;i++){
+ outb(0x3D6,i);
+ printf("XR 0x%2X\t0x%X\n",i,inb(0x3D7)&0xFF);
+ }
+ outb(0x3D6,0x2B);
+ bpp = inb(0x3D7)&0xF0;
+ }
+
+ switch(bpp){
+ case 0x20:
+ bpp = 4;
+ break;
+ case 0x30:
+ bpp = 8;
+ break;
+ case 0x40:
+ bpp = 16;
+ shift = 2;
+ break;
+ case 0x50:
+ bpp = 24;
+ break;
+ default:
+ bpp = 0;
+ }
+ outb(0x3D6,storeReg);
+
+ printf("\nport 0x3D4 (CRTC)\n");
+ storeReg = inb(0x3D4);
+ if (isHiQV==1) {
+ for(i = 0;i < 0x7F;i++){
+ outb(0x3D4,i);
+ printf("CR 0x%2X\t0x%X\n",i,inb(0x3D5)&0xFF);
+ }
+ outb(0x3D4,storeReg);
+ printf("\nport 0x3D0 (Flat Panel)\n");
+ storeReg = inb(0x3D0);
+ for(i = 0;i < 0x7F;i++){
+ outb(0x3D0,i);
+ printf("FR 0x%2X\t0x%X\n",i,inb(0x3D1)&0xFF);
+ }
+ outb(0x3D1,storeReg);
+ printf("\nport 0x3D2 (Multimedia)\n");
+ storeReg = inb(0x3D2);
+ for(i = 0;i < 0x7F;i++){
+ outb(0x3D2,i);
+ printf("MR 0x%2X\t0x%X\n",i,inb(0x3D3)&0xFF);
+ }
+ outb(0x3D3,storeReg);
+ } else {
+ for(i = 0;i < 0x40;i++){
+ outb(0x3D4,i);
+ printf("CR 0x%2X\t0x%X\n",i,inb(0x3D5)&0xFF);
+ }
+ outb(0x3D4,storeReg);
+ }
+
+
+ printf("port 0x3CE (GC)\n");
+ storeReg = inb(0x3CE);
+ for(i = 0;i < 0x10;i++){
+ outb(0x3CE,i);
+ printf("GC 0x%2X\t0x%X\n",i,inb(0x3CF)&0xFF);
+ }
+ outb(0x3CE,storeReg);
+ printf("port 0x3C4 (Sequencer)\n");
+ storeReg = inb(0x3C4);
+ for(i = 0;i < 0x10;i++){
+ outb(0x3C4,i);
+ printf("SQ 0x%2X\t0x%X\n",i,inb(0x3C5)&0xFF);
+ }
+ outb(0x3C4,storeReg);
+
+
+ printf("port 0x3C0 (Attribute)\n");
+ inb(0x3DA);
+ storeReg = inb(0x3C0);
+ for(i = 0;i < 0xFF;i++){
+ inb(0x3DA);
+ outb(0x3C0,i);
+ printf("AT 0x%2X\t0x%X\n",i,inb(0x3C1)&0xFF);
+ }
+ inb(0x3DA);
+ outb(0x3C0,storeReg);
+
+ printf("0x3CC\t0x%X\n",inb(0x3CC)&0xFF);
+ printf("0x3C2\t0x%X\n",inb(0x3C2)&0xFF);
+ printf("0x3C3\t0x%X\n",inb(0x3C2)&0xFF);
+ printf("0x3CA\t0x%X\n",inb(0x3CA)&0xFF);
+ printf("0x3DA\t0x%X\n",inb(0x3DA)&0xFF);
+
+ printf("\nRAMDAC\nport\tvalue\n");
+ for(port = 0x83C6; port < 0x83CA;port++){
+ printf("0x%4X\t0x%4X\n",port,inw(port));
+ }
+
+ if (isHiQV!=1) {
+ printf("\nBitBLT\nport\tvalue\n");
+ for(port = 0x83D0; port <= 0x9FD0;port+=0x400){
+ printf("0x%4X\t0x%4X\n",port,inw(port));
+ }
+
+ printf("\nH/W cursor\nport\tvalue\n");
+ for(port = 0xA3D0; port <= 0xB3D0;port+=0x400){
+ printf("0x%4X\t0x%4X\n",port,inw(port));
+ }
+
+
+ outb(0x3D6, 0x70);
+ outw(0x3D6, (inw(0x3D6) | 0x8070));
+
+ printf("0x46E8\t0x%8X\n",inl(0x46E8));
+ printf("0x4AE8\t0x%8X\n",inl(0x4AE8));
+ printf("0x102\t0x%8X\n",inl(0x102));
+ printf("0x103\t0x%8X\n",inl(0x103));
+
+ }
+
+ storeReg = inb(0x3D4);
+ {
+ outb(0x3D4,0);
+ HTotal = ((inb(0x3D5)&0xFF) + 5) << shift;
+ outb(0x3D4,1);
+ HDisplay = ((inb(0x3D5)&0xFF) + 1) << shift;
+ outb(0x3D4,2);
+ HSyncStart = ((inb(0x3D5)&0xFF) + 1) << shift;
+ outb(0x3D4,3);
+ HSyncEnd = inb(0x3D5)&0x1F;
+ outb(0x3D4,5);
+ HSyncEnd |= (inb(0x3D5)&0x80) >> 2;
+ HSyncEnd += HSyncStart >> shift;
+ HSyncEnd <<= shift;
+
+ outb(0x3D4,6);
+ VTotal = inb(0x3D5)&0xFF;
+ outb(0x3D4,7);
+ VTotal |= (inb(0x3D5)&0x1) << 8;
+ VTotal |= (inb(0x3D5)&0x20) << 4;
+ VTotal += 2;
+ VDisplay = (inb(0x3D5)&0x2) << 7;
+ VDisplay |= (inb(0x3D5)&0x40) << 3;
+ VSyncStart = (inb(0x3D5)&0x4) << 6;
+ VSyncStart |= (inb(0x3D5)&0x80) << 2;
+ outb(0x3D4,0x12);
+ VDisplay |= inb(0x3D5)&0xFF;
+ outb(0x3D4,0x10);
+ VSyncStart |= inb(0x3D5)&0xFF;
+
+ outb(0x3D4,0x11);
+ VSyncEnd = inb(0x3D5)&0xF;
+ VSyncEnd += VSyncStart;
+
+ }
+ outb(0x3D4,storeReg);
+
+ printf("\nModeLine with port 0x3D4 (CRTC) %d %d %d %d %d %d %d %d\n",
+ HDisplay, HSyncStart, HSyncEnd, HTotal,
+ VDisplay, VSyncStart, VSyncEnd, VTotal);
+
+ RESET_IOPL();
+}
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/util/mRegs.c b/xc/programs/Xserver/hw/xfree86/drivers/chips/util/mRegs.c
new file mode 100644
index 000000000..ebc13775d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/util/mRegs.c
@@ -0,0 +1,149 @@
+/* $XConsortium: mRegs.c /main/2 1996/10/27 11:49:43 kaleb $ */
+
+
+
+
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/mRegs.c,v 1.3 1999/04/04 08:46:14 dawes Exp $ */
+
+#ifdef __NetBSD__
+# include <sys/types.h>
+# include <machine/pio.h>
+# include <machine/sysarch.h>
+#else
+# ifdef SVR4
+# include <sys/types.h>
+# ifdef NCR
+ /* broken NCR <sys/sysi86.h> */
+# define __STDC
+# include <sys/sysi86.h>
+# undef __STDC
+# else
+# include <sys/sysi86.h>
+# endif
+# ifdef SVR4
+# if !defined(sun)
+# include <sys/seg.h>
+# endif
+# endif
+# include <sys/v86.h>
+# if defined(sun)
+# include <sys/psw.h>
+# endif
+# endif
+# include "AsmMacros.h"
+#endif /* NetBSD */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef __NetBSD__
+# define SET_IOPL() i386_iopl(3)
+# define RESET_IOPL() i386_iopl(0)
+#else
+# ifdef SVR4
+# ifndef SI86IOPL
+# define SET_IOPL() sysi86(SI86V86,V86SC_IOPL,PS_IOPL)
+# define RESET_IOPL() sysi86(SI86V86,V86SC_IOPL,0)
+# else
+# define SET_IOPL() sysi86(SI86IOPL,3)
+# define RESET_IOPL() sysi86(SI86IOPL,0)
+# endif
+# else
+# ifndef Lynx
+# define SET_IOPL() iopl(3)
+# define RESET_IOPL() iopl(0)
+# else
+# define SET_IOPL() 0
+# define RESET_IOPL() 0
+# endif
+# endif
+#endif
+
+int hex2int(char* str);
+
+int main(int argc, char** argv)
+{
+ int i, value, index;
+ char c, cport;
+ char* str;
+ unsigned int port;
+
+ if(argc < 2) {
+ printf("usage: %s Cvvxx [Cvvxx]\n",argv[0]);
+ printf(" where C = A|a write vv to ARxx\n");
+ printf(" = C|c write vv to CRxx\n");
+ printf(" = F|f write vv to FRxx (6555x only)\n");
+ printf(" = G|g write vv to GRxx\n");
+ printf(" = M|m write vv to MRxx (6555x only)\n");
+ printf(" = S|s write vv to SRxx\n");
+ printf(" = X|x write vv to XRxx\n");
+ printf(" Both vv and xx are in hexadecimal\n");
+ }
+
+ if(SET_IOPL())
+ return -1;
+
+ for(i = 1; i < argc; i++){
+ value = 0;
+ str = argv[i];
+ c = *str++;
+ switch (c) {
+ case 'f':
+ case 'F':
+ cport = 'F';
+ port = 0x3D0;
+ break;
+ case 'c':
+ case 'C':
+ cport = 'C';
+ port = 0x3D4;
+ break;
+ case 'x':
+ case 'X':
+ cport = 'X';
+ port = 0x3D6;
+ break;
+ case 'g':
+ case 'G':
+ cport = 'G';
+ port = 0x3CE;
+ break;
+ case 'a':
+ case 'A':
+ cport = 'A';
+ port = 0x3C0;
+ break;
+ case 's':
+ case 'S':
+ cport = 'S';
+ port = 0x3C4;
+ break;
+ case 'm':
+ case 'M':
+ cport = 'M';
+ port = 0x3D2;
+ break;
+ default:
+ continue;
+ break;
+ }
+ index = inb(port);
+ while (c = *str++){
+ if(c >= '0' && c <= '9')
+ value = (value << 4) | (c - '0'); /*ASCII assumed*/
+ else if(c >= 'A' && c < 'G')
+ value = (value << 4) | (c - 'A'+10); /*ASCII assumed*/
+ else if(c >= 'a' && c < 'g')
+ value = (value << 4) | (c - 'a'+10); /*ASCII assumed*/
+ }
+ outb(port,value&0xFF);
+ printf("%cR%X: 0x%X -> 0x%X\n", cport, value & 0xFF,
+ inb(port+1)&0xFF, (value&0xFF00)>>8);
+ outw(port, value);
+ outb(port, index &0xFF);
+ }
+ RESET_IOPL();
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/chips/util/modClock.c b/xc/programs/Xserver/hw/xfree86/drivers/chips/util/modClock.c
new file mode 100644
index 000000000..c4954d8fd
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/chips/util/modClock.c
@@ -0,0 +1,393 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/modClock.c,v 1.3 1999/04/04 08:46:14 dawes Exp $ */
+
+#ifdef __NetBSD__
+# include <sys/types.h>
+# include <machine/pio.h>
+# include <machine/sysarch.h>
+#else
+# ifdef SVR4
+# include <sys/types.h>
+# ifdef NCR
+ /* broken NCR <sys/sysi86.h> */
+# define __STDC
+# include <sys/sysi86.h>
+# undef __STDC
+# else
+# include <sys/sysi86.h>
+# endif
+# ifdef SVR4
+# if !defined(sun)
+# include <sys/seg.h>
+# endif
+# endif
+# include <sys/v86.h>
+# if defined(sun)
+# include <sys/psw.h>
+# endif
+# endif
+# include "AsmMacros.h"
+#endif /* NetBSD */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef Lynx
+#include <fnmatch.h>
+#endif
+
+#ifdef __NetBSD__
+# define SET_IOPL() i386_iopl(3)
+# define RESET_IOPL() i386_iopl(0)
+#else
+# ifdef SVR4
+# ifndef SI86IOPL
+# define SET_IOPL() sysi86(SI86V86,V86SC_IOPL,PS_IOPL)
+# define RESET_IOPL() sysi86(SI86V86,V86SC_IOPL,0)
+# else
+# define SET_IOPL() sysi86(SI86IOPL,3)
+# define RESET_IOPL() sysi86(SI86IOPL,0)
+# endif
+# else
+# ifndef Lynx
+# define SET_IOPL() iopl(3)
+# define RESET_IOPL() iopl(0)
+# else
+# define SET_IOPL() 0
+# define RESET_IOPL() 0
+# endif
+# endif
+#endif
+
+#define tolerance 0.01 /* +/- 1% */
+
+int compute_clock (
+ double target,
+ double Fref,
+ unsigned int ClkMaxN,
+ unsigned int ClkMaxM,
+ unsigned int PStart,
+ unsigned int *bestM,
+ unsigned int *bestN,
+ unsigned int *bestP,
+ unsigned int *bestPSN) {
+
+ unsigned int M, N, P, PSN, PSNx;
+
+ double bestError, abest = 42, bestFout;
+
+ double Fvco, Fout;
+ double error, aerror;
+
+ unsigned int M_min = 3;
+ unsigned int M_max = ClkMaxM;
+
+ if (target < 1e6){
+ fprintf (stderr, "MHz assumed, changed to %g MHz\n", target);
+ target *= 1e6;
+ }
+
+ if (target > 220.0e6) {
+ fprintf (stderr, "too large\n");
+ return 1;
+ }
+
+ /* Other parameters available onthe 65548 but not the 65545, and
+ not documented in the Clock Synthesizer doc in rev 1.0 of the
+ 65548 datasheet:
+
+ + XR30[4] = 0, VCO divider loop uses divide by 4 (same as 65545)
+ 1, VCO divider loop uses divide by 16
+
+ + XR30[5] = 1, reference clock is divided by 5
+
+ I haven't put in any support for those here. For simplicity,
+ they should be set to 0 on the 65548, and left untouched on
+ earlier chips. */
+
+ for (PSNx = 0; PSNx <= 1; PSNx++) {
+ unsigned int low_N, high_N;
+ double Fref4PSN;
+
+ PSN = PSNx ? 1 : 4;
+
+ low_N = 3;
+ high_N = ClkMaxN;
+
+ while (Fref / (PSN * low_N) > 2.0e6)
+ low_N++;
+ while (Fref / (PSN * high_N) < 150.0e3)
+ high_N--;
+
+ Fref4PSN = Fref * 4 / PSN;
+ for (N = low_N; N <= high_N; N++) {
+ double tmp = Fref4PSN / N;
+ for (P = PStart; P <= 5; P++) {
+ double Fvco_desired = target * (1 << P);
+ double M_desired = Fvco_desired / tmp;
+ /* Which way will M_desired be rounded? Do all three just to
+ be safe. */
+ unsigned int M_low = M_desired - 1;
+ unsigned int M_hi = M_desired + 1;
+
+ if (M_hi < M_min || M_low > M_max)
+ continue;
+
+ if (M_low < M_min)
+ M_low = M_min;
+ if (M_hi > M_max)
+ M_hi = M_max;
+
+ for (M = M_low; M <= M_hi; M++) {
+ Fvco = tmp * M;
+ if (Fvco <= 48.0e6)
+ continue;
+ if (Fvco > 220.0e6)
+ break;
+
+ Fout = Fvco / (1 << P);
+
+ error = (target - Fout) / target;
+
+ aerror = (error < 0) ? -error : error;
+ if (aerror < abest) {
+ abest = aerror;
+ bestError = error;
+ *bestM = M;
+ *bestN = N;
+ *bestP = P;
+ *bestPSN = PSN;
+ bestFout = Fout;
+ }
+ }
+ }
+ }
+ }
+
+ if (abest < tolerance) {
+ unsigned char tmp, idx;
+ printf ("best: M=%d N=%d P=%d PSN=%d\n", *bestM, *bestN, *bestP, *bestPSN);
+
+ if (bestFout > 1.0e6)
+ printf ("Fout = %g MHz", bestFout / 1.0e6);
+ else if (bestFout > 1.0e3)
+ printf ("Fout = %g kHz", bestFout / 1.0e3);
+ else
+ printf ("Fout = %g Hz", bestFout);
+ printf (", error = %g\n", bestError);
+ return 0;
+ }
+ printf ("can't do it with less than %g error\n", bestError);
+ return 1;
+}
+
+#define CT65520 0x1
+#define CT65525 0x2
+#define CT65530 0x3
+#define CT64200 0x4
+
+#define CT65535 0x11
+#define CT65540 0x12
+#define CT65545 0x13
+#define CT65546 0x14
+#define CT65548 0x15
+#define CT64300 0x16
+
+#define CT65550 0x31
+#define CT65554 0x32
+#define CT65555 0x33
+#define CT68554 0x34
+#define CT69000 0x35
+
+#define IS_Programmable(X) X&0x10
+#define IS_HiQV(X) X&0x20
+
+#define DotClk 0
+#define MemClk 1
+#define IS_MemClk(X) X&0x1
+
+int set_clock(
+ unsigned int ChipType,
+ unsigned int ClockType,
+ unsigned int M,
+ unsigned int N,
+ unsigned int P,
+ unsigned int PSN) {
+
+ unsigned int tmp, idx;
+
+ SET_IOPL();
+
+ idx = inb(0x3D6);
+ if (IS_HiQV(ChipType)) {
+ if (IS_MemClk(ClockType)) {
+ printf ("XRCC = 0x%02X\n", M - 2);
+ printf ("XRCD = 0x%02X\n", N - 2);
+ printf ("XRCE = 0x%02X\n", (0x80 | P * 16 + (PSN == 1)));
+
+ outb(0x3D6, 0xCE); /* Select Fix MClk before */
+ tmp = inb(0x3D7);
+ outb(0x3D7, tmp & 0x7F);
+ outb(0x3D6, 0xCC);
+ outb(0x3D7, (M - 2));
+ outb(0x3D6, 0xCD);
+ outb(0x3D7, (N - 2));
+ outb(0x3D6, 0xCE);
+ outb(0x3D7, (0x80 | (P * 16 + (PSN == 1))));
+ } else {
+ printf ("XRC8 = 0x%02X\n", M - 2);
+ printf ("XRC9 = 0x%02X\n", N - 2);
+ printf ("XRCA = 0x%02X\n", 0);
+ printf ("XRCB = 0x%02X\n", P * 16 + (PSN == 1));
+
+ outb(0x3D6, 0xC8);
+ outb(0x3D7, (M - 2));
+ outb(0x3D6, 0xC9);
+ outb(0x3D7, (N - 2));
+ outb(0x3D6, 0xCA);
+ outb(0x3D7, 0x0);
+ outb(0x3D6, 0xCB);
+ outb(0x3D7, (P * 16 + (PSN == 1)));
+ }
+ } else {
+ printf ("XR30 = 0x%02X\n", P * 2 + (PSN == 1));
+ printf ("XR31 = 0x%02X\n", M - 2);
+ printf ("XR32 = 0x%02X\n", N - 2);
+ outb(0x3D6, 0x33);
+ tmp = inb(0x3D7);
+ if (IS_MemClk(ClockType)) {
+ outb(0x3D7, tmp | 0x20);
+ } else {
+ outb(0x3D7, tmp & ~0x20);
+ }
+ outb(0x3D6, 0x30);
+ outb(0x3D7, (P * 2 + (PSN == 1)));
+ outb(0x3D6, 0x31);
+ outb(0x3D7, (M - 2));
+ outb(0x3D6, 0x32);
+ outb(0x3D7, (N - 2));
+ outb(0x3D6, 0x33);
+ outb(0x3D7, tmp);
+ }
+ outb(0x3D6, idx);
+ RESET_IOPL();
+ return 0;
+}
+
+unsigned int probe_chip(void) {
+
+ unsigned int ChipType, temp;
+
+ SET_IOPL();
+
+ outb(0x3D6, 0x00);
+ temp = inb(0x3D7);
+ ChipType = 0;
+ if (temp != 0xA5) {
+ if ((temp & 0xF0) == 0x70) {
+ ChipType = CT65520;
+ }
+ if ((temp & 0xF0) == 0x80) { /* could also be a 65525 */
+ ChipType = CT65530;
+ }
+ if ((temp & 0xF0) == 0xA0) {
+ ChipType = CT64200;
+ }
+ if ((temp & 0xF0) == 0xB0) {
+ ChipType = CT64300;
+ }
+ if ((temp & 0xF0) == 0xC0) {
+ ChipType = CT65535;
+ }
+ if ((temp & 0xF8) == 0xD0) {
+ ChipType = CT65540;
+ }
+ if ((temp & 0xF8) == 0xD8) {
+ switch (temp & 0x07) {
+ case 3:
+ ChipType = CT65546;
+ break;
+ case 4:
+ ChipType = CT65548;
+ break;
+ default:
+ ChipType = CT65545;
+ }
+ }
+ }
+ /* At this point the chip could still be a HiQV, so check for
+ * that. This test needs some looking at */
+ if ((temp != 0) && (ChipType == 0)) {
+ outb(0x3D6, 0x02);
+ temp = inb(0x03D7);
+ if (temp == 0xE0) {
+ ChipType = CT65550;
+ }
+ if (temp == 0xE4) {
+ ChipType = CT65554;
+ }
+ if (temp == 0xE5) {
+ ChipType = CT65555;
+ }
+ if (temp == 0xF4) {
+ ChipType = CT68554;
+ }
+ if (temp == 0xC0) {
+ ChipType = CT69000;
+ }
+ }
+
+ RESET_IOPL();
+
+ if (ChipType == 0) { /* failure */
+ fprintf(stderr, "Not a Chips and Technologies Chipset\n");
+ }
+
+ return ChipType;
+}
+
+
+int main (int argc, char *argv[]) {
+ double target;
+ double Fref = 14318180;
+ unsigned int M, N, P, PSN, ChipType, ClockType;
+
+ if (argc != 2) {
+ fprintf (stderr, "usage: %s freq\n", argv[0]);
+ return 1;
+ }
+
+ ClockType = DotClk;
+#ifndef Lynx
+ if (! fnmatch("*memClock",argv[0],FNM_PATHNAME)) {
+#else
+ if (strstr("memClock",argv[0]) != NULL) {
+#endif
+ ClockType = MemClk;
+ }
+
+ target = atof (argv[1]);
+
+ ChipType = probe_chip();
+ if (!ChipType) {
+ return 1;
+ }
+
+ if (! IS_Programmable(ChipType)) {
+ fprintf(stderr, "No programmable Clock!\n");
+ return 1;
+ }
+
+ if (IS_HiQV(ChipType)) {
+ if (! compute_clock(target, Fref, 63, 127, 1, &M, &N, &P, &PSN)) {
+ return set_clock(ChipType, ClockType, M, N, P, PSN);
+ } else {
+ return 1;
+ }
+ } else {
+ if (! compute_clock(target, Fref, 127, 127, 0, &M, &N, &P, &PSN)) {
+ return set_clock(ChipType, ClockType, M, N, P, PSN);
+ } else {
+ return 1;
+ }
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cirrus/CirrusClk.c b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/CirrusClk.c
new file mode 100644
index 000000000..46fd6acee
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/CirrusClk.c
@@ -0,0 +1,209 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/CirrusClk.c,v 1.8 1998/12/06 06:08:28 dawes Exp $ */
+
+/*
+ * Programming of the built-in Cirrus clock generator.
+ * Harm Hanemaayer <hhanemaa@cs.ruu.nl>
+ *
+ * VCO stability criterion code added by Koen Gadeyne (koen.gadeyne@barco.com)
+ * Max clock specification added by Harm Hanemaayer (H.Hanemaayer@inter.nl.net)
+ *
+ * Minor changes and cleanup Itai Nahshon.
+ */
+
+#include "compiler.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "vgaHW.h"
+
+#include "cir.h"
+
+/* CLOCK_FACTOR is double the osc freq in kHz (osc = 14.31818 MHz) */
+#define CLOCK_FACTOR 28636
+
+/* stability constraints for internal VCO -- MAX_VCO also determines the maximum Video pixel clock */
+#define MIN_VCO CLOCK_FACTOR
+#define MAX_VCO 111000
+
+/* clock in kHz is (numer * CLOCK_FACTOR / (denom & 0x3E)) >> (denom & 1) */
+#define VCOVAL(n, d) \
+ ((((n) & 0x7F) * CLOCK_FACTOR / ((d) & 0x3E)) )
+
+#define CLOCKVAL(n, d) \
+ (VCOVAL(n, d) >> ((d) & 1))
+
+typedef struct {
+ unsigned char numer;
+ unsigned char denom;
+} cirrusClockRec;
+
+static cirrusClockRec cirrusClockTab[] = {
+ { 0x2C, 0x33 }, /* 12.599 */
+ { 0x4A, 0x2B }, /* 25.227 */
+ { 0x5B, 0x2F }, /* 28.325 */
+ { 0x45, 0x30 }, /* 41.164 */
+ { 0x7E, 0x33 }, /* 36.082 */
+ { 0x42, 0x1F }, /* 31.500 */
+ { 0x51, 0x3A }, /* 39.992 */
+ { 0x55, 0x36 }, /* 45.076 */
+ { 0x65, 0x3A }, /* 49.867 */
+ { 0x76, 0x34 }, /* 64.983 */
+ { 0x7E, 0x32 }, /* 72.163 */
+ { 0x6E, 0x2A }, /* 75.000 */
+ { 0x5F, 0x22 }, /* 80.013 */
+ { 0x7D, 0x2A }, /* 85.226 */
+ { 0x58, 0x1C }, /* 89.998 */
+ { 0x49, 0x16 }, /* 95.019 */
+ { 0x46, 0x14 }, /* 100.226 */
+ { 0x53, 0x16 }, /* 108.035 */
+ { 0x5C, 0x18 }, /* 110.248 */
+
+ { 0x6D, 0x1A }, /* 120.050 */
+ { 0x58, 0x14 }, /* 125.998 */
+ { 0x6D, 0x18 }, /* 130.055 */
+ { 0x42, 0x0E }, /* 134.998 */
+
+ { 0x69, 0x14 }, /* 150.341 */
+ { 0x5E, 0x10 }, /* 168.239 */
+ { 0x5C, 0x0E }, /* 188.182 */
+ { 0x67, 0x0E }, /* 210.682 */
+ { 0x60, 0x0C }, /* 229.091 */
+};
+
+#define NU_FIXED_CLOCKS (sizeof(cirrusClockTab)/sizeof(cirrusClockTab[0]))
+
+#define IS_546x(c) (PCI_CHIP_GD5462 == c || \
+ PCI_CHIP_GD5464 == c || \
+ PCI_CHIP_GD5464BD == c || \
+ PCI_CHIP_GD5465 == c)
+
+
+/*
+ * This function returns the 7-bit numerator and 6-bit denominator/post-scalar
+ * value that corresponds to the closest clock found. If the MCLK is very close
+ * to the requested frequency, it sets a flag so that the MCLK can be used
+ * as VCLK on chips that support it.
+ * If a frequency close to one of the tested clock values is found,
+ * use the tested clock since others can be unstable.
+ */
+
+static Bool
+CirrusFindClock(vgaHWPtr hwp, CIRPtr pCir, int freq, int max_clock,
+ int *num_out, int *den_out,
+ Bool *usemclk_out) {
+ int n, i;
+ int num = 0, den = 0;
+ int ffreq, mindiff = 0;
+ int mclk;
+
+ /* Prefer a tested value if it matches within 0.1%. */
+ for (i = 0; i < NU_FIXED_CLOCKS; i++) {
+ int diff;
+ diff = abs(CLOCKVAL(cirrusClockTab[i].numer,
+ cirrusClockTab[i].denom) - freq);
+ if (diff < freq / 1000) {
+ num = cirrusClockTab[i].numer;
+ den = cirrusClockTab[i].denom;
+ goto foundclock;
+ }
+ }
+
+ /*
+ * If max_clock is greater than the MAX_VCO default, ignore
+ * MAX_VCO. On the other hand, if MAX_VCO is higher than max_clock,
+ * make use of the higher MAX_VCO value.
+ */
+ if (MAX_VCO > max_clock)
+ max_clock = MAX_VCO;
+
+ mindiff = freq;
+ for (n = 0x10; n < 0x7f; n++) {
+ int d;
+ for (d = 0x14; d < 0x3f; d++) {
+ int c, diff;
+
+ /* Avoid combinations that can be unstable. */
+ if ((VCOVAL(n, d) < MIN_VCO) || (VCOVAL(n, d) > max_clock))
+ continue;
+ c = CLOCKVAL(n, d);
+ diff = abs(c - freq);
+ if (diff < mindiff) {
+ mindiff = diff;
+ num = n;
+ den = d;
+ ffreq = c;
+ }
+ }
+ }
+
+ if (0 == num || 0 == den)
+ return FALSE;
+
+foundclock:
+ *num_out = num;
+ *den_out = den;
+
+ if (!IS_546x(pCir->Chipset)) {
+ /* Calculate the MCLK. */
+#if 1
+ mclk = 14318 * (hwp->readSeq(hwp, 0x1F) & 0x3F) / 8; /* XXX */
+#else
+ outb(0x3c4, 0x0f); /* XXX */
+ mclk = 14318 * (inb(0x3c5) & 0x3f) / 8; /* XXX */
+#endif
+ /*
+ * Favour MCLK as VLCK if it matches as good as the found clock,
+ * or if it is within 0.2 MHz of the request clock. A VCLK close
+ * to MCLK can cause instability.
+ */
+ if (abs(mclk - freq) <= mindiff + 10 || abs(mclk - freq) <= 200)
+ *usemclk_out = TRUE;
+ else
+ *usemclk_out = FALSE;
+ }
+
+ return TRUE;
+}
+
+CARD16
+CirrusSetClock(ScrnInfoPtr pScrn, int freq)
+{
+ int num, den, usemclk;
+ CARD8 tmp;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CIRPtr pCir = CIRPTR(pScrn);
+
+ ErrorF("CirrusSetClock\n");
+
+ if(!CirrusFindClock(hwp, pCir, freq, pCir->MaxClock,
+ &num, &den, &usemclk))
+ return 0;
+
+ if (IS_546x(pCir->Chipset)) {
+ /* The numerator and denominator registers are switched
+ around in the Laguna chips. */
+ int t = den;
+ den = num;
+ num = t;
+ }
+
+ ErrorF("CirrusSetClock: nom=%x den=%x usemclk=%x\n",
+ num, den, usemclk);
+
+ /* Set VCLK3. */
+#if 1
+ tmp = hwp->readSeq(hwp, 0x0E);
+ hwp->writeSeq(hwp, 0x0E, (tmp & 0x80) | num);
+ hwp->writeSeq(hwp, 0x1E, den);
+#else
+ outb(0x3c4, 0x0e);
+ tmp = inb(0x3c5);
+ outb(0x3c5, (tmp & 0x80) | num);
+ outb(0x3c4, 0x1e);
+ outb(0x3c5, den);
+#endif
+
+ return (num << 8) | den;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cirrus/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/Imakefile
new file mode 100644
index 000000000..8e324be71
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/Imakefile
@@ -0,0 +1,57 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/Imakefile,v 1.21 1999/08/14 10:49:44 dawes Exp $
+XCOMM
+XCOMM This is an Imakefile for the Cirrus Logic driver.
+XCOMM
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = cir_driver.c CirrusClk.c cir_xaa.c cir_hwcurs.c \
+ cir_i2c.c lg_driver.c cir_xaam.c lg_i2c.c lg_xaa.c lg_hwcurs.c
+OBJS = cir_driver.o CirrusClk.o cir_xaa.o cir_hwcurs.o \
+ cir_i2c.o lg_driver.o cir_xaam.o lg_i2c.o lg_xaa.o lg_hwcurs.o
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(XF86SRC)/xf4bpp -I$(XF86SRC)/xf1bpp \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \
+ -I$(XF86SRC)/ramdac -I$(XF86SRC)/i2c \
+ -I$(XF86SRC)/rac \
+ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ddc \
+ -I$(SERVERSRC)/Xext -I$(XF86SRC)/xf24_32bpp \
+ -I$(FONTINCSRC) -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC) -I$(EXTINCSRC)
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget(cirrus,$(OBJS))
+
+InstallObjectModule(cirrus,$(MODULEDIR),drivers)
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(CirrusClk.c,$(DRIVERSDKDIR)/drivers/cirrus)
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/cirrus)
+InstallDriverSDKNonExecFile(cir.h,$(DRIVERSDKDIR)/drivers/cirrus)
+InstallDriverSDKNonExecFile(cir_dga.c,$(DRIVERSDKDIR)/drivers/cirrus)
+InstallDriverSDKNonExecFile(cir_driver.c,$(DRIVERSDKDIR)/drivers/cirrus)
+InstallDriverSDKNonExecFile(cir_hwcurs.c,$(DRIVERSDKDIR)/drivers/cirrus)
+InstallDriverSDKNonExecFile(cir_i2c.c,$(DRIVERSDKDIR)/drivers/cirrus)
+InstallDriverSDKNonExecFile(cir_xaa.c,$(DRIVERSDKDIR)/drivers/cirrus)
+InstallDriverSDKNonExecFile(cir_xaam.c,$(DRIVERSDKDIR)/drivers/cirrus)
+InstallDriverSDKNonExecFile(lg.h,$(DRIVERSDKDIR)/drivers/cirrus)
+InstallDriverSDKNonExecFile(lg_driver.c,$(DRIVERSDKDIR)/drivers/cirrus)
+InstallDriverSDKNonExecFile(lg_hwcurs.c,$(DRIVERSDKDIR)/drivers/cirrus)
+InstallDriverSDKNonExecFile(lg_i2c.c,$(DRIVERSDKDIR)/drivers/cirrus)
+InstallDriverSDKNonExecFile(lg_xaa.c,$(DRIVERSDKDIR)/drivers/cirrus)
+InstallDriverSDKNonExecFile(lg_xaa.h,$(DRIVERSDKDIR)/drivers/cirrus)
+
+InstallDriverSDKObjectModule(cirrus,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cirrus/README.multihead b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/README.multihead
new file mode 100644
index 000000000..efe62d4f4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/README.multihead
@@ -0,0 +1,70 @@
+WARNING:
+On exit XFree86 restores the old mode but it
+does not disable the secondary card. As a result
+the second card (which has some randonm CRTC timing)
+may produce synch pulses which are wrong for your
+monitor.
+
+If your monitor does not tolerate bad timing I would
+recommend that you don't try Multi-head yet, or at
+least, turn it off *before* leaving X.
+
+
+3.9Nl notice: There is a problem with releasing
+of LBX colormap privates which may cause a seg.
+fault when the server exits. I got a patch from
+Mark Vojkovich which fixes it.
+
+If you have a CL-GD5480 or CL-GD5446 ver. B you
+should be able to try Multi-Head with that
+card as a secondary. The primary card should not
+have any special feature. Some MainBoards may
+not do it right too. I tried it with a 5465 (AGP)
+as a primary and 5446B (PCI) secondary on an
+ABIT LX6 upgraded to the latest bios.
+
+Version A of the 5446 cannot be pure MMIO (The driver
+requires that it is the primary display adapter).
+You can distinguish between the rel A and rel B by
+running "scanpci -v". Version 1 does not report a
+valid BASE1 address.
+
+The bios upgrade lets me chose if the primary
+display adapter is on PCI on AGP (I chose
+the AGP card as primary). Warning - this setup
+will *NOT* work with XFree86 3.3.2.
+
+The only problem that I found so far is with
+memory configuration initialization. My bios
+does not initialize the secondary display adapter.
+This results in a currupted display.
+
+Here are the options:
+1. warm booting from Windows 98 may work. I have
+not tried that.
+
+2. Take out the other card and leave the 5446
+(or 5480) as the primary card. Start the server
+and watch it's output. Look for lines like:
+ (--) CIRRUS(0): Memory Config reg 1 is 0x1B
+ (--) CIRRUS(0): Memory Config reg 2 is 0x21
+Remember these values. Now edit XF86Config
+and add to the proper device section the lines:
+ Option "MemCFG1" "0x1B"
+ Option "MemCFG2" "0x21"
+These values are the contents of registers SR0F
+and SR17. (notice: the 5480 driver does not use
+and will not print MemCFG2).
+
+Now you can reinstall the other card (which
+must me set as the the primary display adaptor).
+
+A note about configuring multi-head:
+There should be a separate section for each
+adapter (device), Monitor and Screen. A "ServerLayout"
+section is optional (and recommended). To make it
+easier for XFree86 to relate device sections to
+actual cards, use a BusId line in each device
+section. XFree86 3.9N works properly if the config
+file is for Multi-head but it finds only one
+display adapter.
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir.h b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir.h
new file mode 100644
index 000000000..61a4d4d0a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir.h
@@ -0,0 +1,105 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir.h,v 1.11 1999/06/13 15:49:02 dawes Exp $ */
+
+/* (c) Itai Nahshon */
+
+#ifndef CIR_H
+#define CIR_H
+
+#include "xf86Cursor.h"
+#include "xaa.h"
+#include "xf86i2c.h"
+
+#define CIR_DEBUG
+
+/* Saved registers that are not part of the core VGA */
+/* CRTC >= 0x19; Sequencer >= 0x05; Graphics >= 0x09; Attribute >= 0x15 */
+enum {
+ /* CR regs */
+ CR1A,
+ CR1B,
+ CR1D,
+ /* SR regs */
+ SR07,
+ SR0E,
+ SR12,
+ SR13,
+ SR1E,
+ /* GR regs */
+ GR17,
+ GR18,
+ /* HDR */
+ HDR,
+ /* Must be last! */
+ CIR_NSAVED
+};
+
+typedef struct {
+ unsigned char ExtVga[CIR_NSAVED];
+} CIRRegRec, *CIRRegPtr;
+
+/* Card-specific driver information */
+#define CIRPTR(p) ((CIRPtr)((p)->driverPrivate))
+
+typedef struct {
+ ScrnInfoPtr pScrn;
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ EntityInfoPtr pEnt;
+ int Chipset;
+ int ChipRev;
+ int Rounding;
+ int BppShift;
+ Bool HasFBitBlt;
+ CARD32 IOAddress;
+ CARD32 FbAddress;
+ unsigned char * IOBase;
+#ifdef __alpha__
+ unsigned char * IOBaseDense;
+#endif
+ unsigned char * FbBase;
+ long FbMapSize;
+ int MinClock;
+ int MaxClock;
+ Bool NoAccel;
+ Bool HWCursor;
+ Bool UseMMIO;
+ XAAInfoRecPtr AccelInfoRec;
+ xf86CursorInfoPtr CursorInfoRec;
+#if 0
+ DGAInfoPtr DGAInfo;
+#endif
+ I2CBusPtr I2CPtr1;
+ I2CBusPtr I2CPtr2;
+ CloseScreenProcPtr CloseScreen;
+
+/* Difference from Laguna start here */
+ unsigned char * HWCursorBits;
+ Bool CursorIsSkewed;
+ unsigned char * CursorBits;
+
+ CIRRegRec SavedReg;
+ CIRRegRec ModeReg;
+
+/* XXX For XF86Config based mem configuration */
+ CARD32 SR0F, SR17;
+
+#if 0
+ CARD32 BltScanDirection;
+ CARD32 FilledRectCMD;
+ CARD32 SolidLineCMD;
+ CARD32 PatternRectCMD;
+ CARD32 AccelFlags;
+#endif
+} CIRRec, *CIRPtr;
+
+
+extern Bool CIRHWCursorInit(ScreenPtr pScreen);
+extern Bool CIRXAAInit(ScreenPtr pScreen);
+extern Bool CIRXAAInitMMIO(ScreenPtr pScreen);
+extern Bool CIRDGAInit(ScreenPtr pScreen);
+extern Bool CIRI2CInit(ScreenPtr pScreen);
+
+/* CirrusClk.c */
+extern CARD16 CirrusSetClock(ScrnInfoPtr pScrn, int freq);
+
+#endif /* CIR_H */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_dga.c
new file mode 100644
index 000000000..3d7ef4c16
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_dga.c
@@ -0,0 +1,75 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_dga.c,v 1.3 1998/09/05 06:36:44 dawes Exp $ */
+
+/* (c) Itai Nahshon */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+#include "vgaHW.h"
+
+#include "cir.h"
+
+static Bool
+CIRDGAGetParams(int scrnIndex, unsigned long *offset,
+ int *banksize, int *memsize) {
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ CIRPtr pCir = CIRPTR(pScrn);
+
+ *offset = pCir->FbAddress;
+ *banksize = pScrn->videoRam * 1024;
+ *memsize = pScrn->videoRam * 1024;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRDGAGetParams %d = 0x%08x, %d, %d\n",
+ scrnIndex, *banksize, *memsize);
+#endif
+ return TRUE;
+}
+
+static Bool
+CIRDGASetDirect(int scrnIndex, Bool enable) {
+ return TRUE;
+}
+
+static Bool
+CIRDGASetBank(int scrnIndex, int bank, int flags) {
+ return TRUE;
+}
+
+static Bool
+CIRDGASetViewport(int scrnIndex, int x, int y, int flags) {
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ (*pScrn->AdjustFrame)(scrnIndex, x, y, 0);
+ return TRUE;
+}
+
+static Bool
+CIRDGAViewportChanged(int scrnIndex, int n, int flags) {
+ return TRUE;
+}
+
+Bool
+CIRDGAInit(ScreenPtr pScreen) {
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CIRPtr pCir = CIRPTR(pScrn);
+ DGAInfoPtr pDGAInfo;
+
+ pDGAInfo = DGACreateInfoRec();
+ if(pDGAInfo == NULL)
+ return FALSE;
+
+ pCir->DGAInfo = pDGAInfo;
+
+ pDGAInfo->GetParams = CIRDGAGetParams;
+ pDGAInfo->SetDirectMode = CIRDGASetDirect;
+ pDGAInfo->SetBank = CIRDGASetBank;
+ pDGAInfo->SetViewport = CIRDGASetViewport;
+ pDGAInfo->ViewportChanged = CIRDGAViewportChanged;;
+
+ return DGAInit(pScreen, pDGAInfo, 0);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_driver.c
new file mode 100644
index 000000000..0302a60cc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_driver.c
@@ -0,0 +1,2251 @@
+/*
+ * Driver for CL-GD5480.
+ * Itai Nahshon.
+ *
+ * This is mainly a cut & paste from the MGA driver.
+ * Original autors and contributors list include:
+ * Radoslaw Kapitan, Andrew Vanderstock, Dirk Hohndel,
+ * David Dawes, Andrew E. Mileski, Leonard N. Zubkoff,
+ * Guy DESBIEF
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_driver.c,v 1.42 1999/07/11 08:49:24 dawes Exp $ */
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.h"
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include "xf86Resources.h"
+
+/* All drivers need this */
+#include "xf86_ansic.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* All drivers using the vgahw module need this */
+/* This driver needs to be modified to not use vgaHW for multihead operation */
+#include "vgaHW.h"
+
+#include "xf86RAC.h"
+
+/* All drivers initialising the SW cursor need this */
+#include "mipointer.h"
+
+/* All drivers implementing backing store need this */
+#include "mibstore.h"
+
+#include "micmap.h"
+
+/*
+ * If using cfb, cfb.h is required. Select the others for the bpp values
+ * the driver supports.
+ */
+#include "xf4bpp.h"
+#include "xf1bpp.h"
+#define PSZ 8 /* needed for cfb.h */
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+#include "cfb24_32.h"
+
+/* These need to be checked */
+#if 0
+#ifdef XFreeXDGA
+#define _XF86DGA_SERVER_
+#include "extensions/xf86dgastr.h"
+#endif
+#endif
+
+#include "xf86DDC.h"
+
+#include "cir.h"
+
+#ifdef XvExtension
+#include "xf86xv.h"
+#include "Xv.h"
+#endif
+
+#ifdef CIRPROBEI2C
+/* For debugging... should go away. */
+static void CirProbeI2C(int scrnIndex);
+#endif
+
+/*
+ * Forward definitions for the functions that make up the driver.
+ */
+
+/* Mandatory functions */
+
+static void CIRIdentify(int flags);
+static Bool CIRProbe(DriverPtr drv, int flags);
+extern Bool LgPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool CIRPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool CIRScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+extern Bool LgScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool CIREnterVT(int scrnIndex, int flags);
+static void CIRLeaveVT(int scrnIndex, int flags);
+extern Bool LgEnterVT(int scrnIndex, int flags);
+extern void LgLeaveVT(int scrnIndex, int flags);
+static Bool CIRCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool CIRSaveScreen(ScreenPtr pScreen, Bool unblank);
+
+/* Required if the driver supports mode switching */
+static Bool CIRSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+extern Bool LgSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+/* Required if the driver supports moving the viewport */
+static void CIRAdjustFrame(int scrnIndex, int x, int y, int flags);
+extern void LgAdjustFrame(int scrnIndex, int x, int y, int flags);
+
+/* Optional functions */
+static void CIRFreeScreen(int scrnIndex, int flags);
+extern void LgFreeScreen(int scrnIndex, int flags);
+static int CIRValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
+int LgValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
+#ifdef DPMSExtension
+static void CIRDisplayPowerManagementSet(ScrnInfoPtr pScrn,
+ int PowerManagementMode,
+ int flags);
+#endif
+
+/* Internally used functions */
+Bool CIRMapMem(ScrnInfoPtr pScrn);
+Bool CIRUnmapMem(ScrnInfoPtr pScrn);
+static void CIRSave(ScrnInfoPtr pScrn);
+static void CIRRestore(ScrnInfoPtr pScrn);
+static Bool CIRModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+
+/*
+ * This is intentionally screen-independent. It indicates the binding
+ * choice made in the first PreInit.
+ */
+static int pix24bpp = 0;
+
+#define VERSION 4000
+#define CIR_NAME "CIRRUS"
+#define CIR_DRIVER_NAME "cirrus"
+#define CIR_MAJOR_VERSION 1
+#define CIR_MINOR_VERSION 0
+#define CIR_PATCHLEVEL 0
+
+/*
+ * This contains the functions needed by the server after loading the
+ * driver module. It must be supplied, and gets added the driver list by
+ * the Module Setup funtion in the dynamic case. In the static case a
+ * reference to this is compiled in, and this requires that the name of
+ * this DriverRec be an upper-case version of the driver name.
+ */
+
+DriverRec CIRRUS = {
+ VERSION,
+ "Driver for Cirrus Logic GD5446, GD5480, and GD5462/4/5 cards",
+ CIRIdentify,
+ CIRProbe,
+ NULL,
+ 0
+};
+
+/* Supported chipsets */
+SymTabRec CIRChipsets[] = {
+ { PCI_CHIP_GD5430, "CLGD5430" },
+ { PCI_CHIP_GD5434_4, "CLGD5434-4" },
+ { PCI_CHIP_GD5434_8, "CLGD5434-8" },
+ { PCI_CHIP_GD5436, "CLGD5436" },
+/* { PCI_CHIP_GD5440, "CLGD5440" }, */
+ { PCI_CHIP_GD5446, "CLGD5446" },
+ { PCI_CHIP_GD5480, "CLGD5480" },
+ { PCI_CHIP_GD5462, "CL-GD5462" },
+ { PCI_CHIP_GD5464, "CL-GD5464" },
+ { PCI_CHIP_GD5464BD, "CL-GD5464BD" },
+ { PCI_CHIP_GD5465, "CL-GD5465" },
+ {-1, NULL }
+};
+
+/* List of PCI chipset names */
+static PciChipsets CIRPciChipsets[] = {
+ { PCI_CHIP_GD5430, PCI_CHIP_GD5430, RES_SHARED_VGA },
+ { PCI_CHIP_GD5434_4,PCI_CHIP_GD5434_4, RES_SHARED_VGA },
+ { PCI_CHIP_GD5434_8,PCI_CHIP_GD5434_8, RES_SHARED_VGA },
+ { PCI_CHIP_GD5436, PCI_CHIP_GD5436, RES_SHARED_VGA },
+/* { PCI_CHIP_GD5440, PCI_CHIP_GD5440, RES_SHARED_VGA }, */
+ { PCI_CHIP_GD5446, PCI_CHIP_GD5446, RES_SHARED_VGA },
+ { PCI_CHIP_GD5480, PCI_CHIP_GD5480, RES_SHARED_VGA },
+ { PCI_CHIP_GD5462, PCI_CHIP_GD5462, RES_SHARED_VGA },
+ { PCI_CHIP_GD5464, PCI_CHIP_GD5464, RES_SHARED_VGA },
+ { PCI_CHIP_GD5464BD,PCI_CHIP_GD5464BD, RES_SHARED_VGA },
+ { PCI_CHIP_GD5465, PCI_CHIP_GD5465, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED}
+};
+
+typedef enum {
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+ OPTION_PCI_RETRY,
+ OPTION_NOACCEL,
+ OPTION_MMIO,
+ OPTION_MEMCFG1,
+ OPTION_MEMCFG2
+} CIROpts;
+
+static OptionInfoRec CIROptions[] = {
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_MMIO, "MMIO", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_MEMCFG1, "MemCFG1", OPTV_INTEGER, {0}, -1 },
+ { OPTION_MEMCFG2, "MemCFG2", OPTV_INTEGER, {0}, -1 },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+/*
+ * List of symbols from other modules that this module references. This
+ * list is used to tell the loader that it is OK for symbols here to be
+ * unresolved providing that it hasn't been told that they haven't been
+ * told that they are essential via a call to xf86LoaderReqSymbols() or
+ * xf86LoaderReqSymLists(). The purpose is this is to avoid warnings about
+ * unresolved symbols that are not required.
+ */
+
+static const char *vgahwSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWUnlock",
+ "vgaHWInit",
+ "vgaHWProtect",
+ "vgaHWSetMmioFuncs",
+ "vgaHWGetIOBase",
+ "vgaHWMapMem",
+ "vgaHWLock",
+ "vgaHWFreeHWRec",
+ "vgaHWSaveScreen",
+ "vgaHWddc1SetSpeed",
+ NULL
+};
+
+static const char *cfbSymbols[] = {
+ "xf1bppScreenInit",
+ "xf4bppScreenInit",
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb24ScreenInit",
+ "cfb32ScreenInit",
+ "cfb8_32ScreenInit",
+ "cfb24_32ScreenInit",
+ NULL
+};
+
+static const char *xf8_32bppSymbols[] = {
+ "xf86Overlay8Plus32Init",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAADestroyInfoRec",
+ "XAACreateInfoRec",
+ "XAAInit",
+ "XAAStippleScanlineFuncLSBFirst",
+ "XAAOverlayFBfuncs",
+ "XAACachePlanarMonoStipple",
+ "XAAScreenIndex",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86InitCursor",
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ NULL
+};
+
+#define CIRuseI2C 0
+
+static const char *ddcSymbols[] = {
+ "xf86PrintEDID",
+ "xf86DoEDID_DDC1",
+#if CIRuseI2C
+ "xf86DoEDID_DDC2",
+#endif
+ NULL
+};
+
+static const char *i2cSymbols[] = {
+ "xf86CreateI2CBusRec",
+ "xf86I2CBusInit",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(cirSetup);
+
+static XF86ModuleVersionInfo cirVersRec =
+{
+ "cirrus",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ CIR_MAJOR_VERSION, CIR_MINOR_VERSION, CIR_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+/*
+ * This is the module init data.
+ * Its name has to be the driver name followed by ModuleData.
+ */
+XF86ModuleData cirrusModuleData = { &cirVersRec, cirSetup, NULL };
+
+static pointer
+cirSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ /* This module should be loaded only once, but check to be sure. */
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&CIRRUS, module, 0);
+
+ /*
+ * Modules that this driver always requires may be loaded here
+ * by calling LoadSubModule().
+ *
+ * Although this driver currently always requires the vgahw module
+ * that dependency will be removed later, so we don't load it here.
+ */
+
+ /*
+ * Tell the loader about symbols from other modules that this module
+ * might refer to.
+ */
+ LoaderRefSymLists(vgahwSymbols, cfbSymbols, xaaSymbols,
+ xf8_32bppSymbols, ramdacSymbols,
+ ddcSymbols, i2cSymbols, shadowSymbols, NULL);
+
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer)1;
+ } else {
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+#endif /* XFree86LOADER */
+
+/* 1/4bpp 8bpp 15/16bpp 24bpp 32bpp
+static int unsupp_MaxClocks[] = { 0, 0, 0, 0, 0 }; */
+static int gd5430_MaxClocks[] = { 85500, 85500, 50000, 28500, 0 };
+static int gd5446_MaxClocks[] = { 135100, 135100, 85500, 85500, 0 };
+static int gd5480_MaxClocks[] = { 135100, 200000, 200000, 135100, 135100 };
+
+static Bool
+CIRGetRec(ScrnInfoPtr pScrn)
+{
+#ifdef CIR_DEBUG
+ ErrorF("CIRGetRec\n");
+#endif
+ /*
+ * Allocate an CIRRec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(CIRRec), 1);
+ /* Initialise it */
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRGetRec 0x%x\n", CIRPTR(pScrn));
+#endif
+ return TRUE;
+}
+
+static void
+CIRFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+
+/* Mandatory */
+static void
+CIRIdentify(int flags)
+{
+ xf86PrintChipsets(CIR_NAME, "driver for Cirrus chipsets", CIRChipsets);
+}
+
+
+/* Mandatory */
+static Bool
+CIRProbe(DriverPtr drv, int flags)
+{
+ int i;
+ GDevPtr *devSections;
+ pciVideoPtr pPci;
+ int *usedChips;
+ int numDevSections;
+ int numUsed;
+ Bool foundScreen = FALSE;
+
+ /*
+ * The aim here is to find all cards that this driver can handle,
+ * and for the ones not already claimed by another driver, claim the
+ * slot, and allocate a ScrnInfoRec.
+ *
+ * This should be a minimal probe, and it should under no circumstances
+ * change the state of the hardware. Because a device is found, don't
+ * assume that it will be used. Don't do any initialisations other than
+ * the required ScrnInfoRec initialisations. Don't allocate any new
+ * data structures.
+ *
+ * Since this test version still uses vgaHW, we'll only actually claim
+ * one for now, and just print a message about the others.
+ */
+
+
+ /*
+ * Next we check, if there has been a chipset override in the config file.
+ * For this we must find out if there is an active device section which
+ * is relevant, i.e., which has no driver specified or has THIS driver
+ * specified.
+ */
+
+ if ((numDevSections = xf86MatchDevice(CIR_DRIVER_NAME,
+ &devSections)) <= 0) {
+ /*
+ * There's no matching device section in the config file, so quit
+ * now.
+ */
+ return FALSE;
+ }
+
+ /*
+ * While we're VGA-dependent, can really only have one such instance, but
+ * we'll ignore that.
+ */
+
+ /*
+ * We need to probe the hardware first. We then need to see how this
+ * fits in with what is given in the config file, and allow the config
+ * file info to override any contradictions.
+ */
+
+ /*
+ * All of the cards this driver supports are PCI, so the "probing" just
+ * amounts to checking the PCI data that the server has already collected.
+ */
+ if (xf86GetPciVideoInfo() == NULL) {
+ /*
+ * We won't let anything in the config file override finding no
+ * PCI video cards at all. This seems reasonable now, but we'll see.
+ */
+ return FALSE;
+ }
+
+ numUsed = xf86MatchPciInstances(CIR_NAME, PCI_VENDOR_CIRRUS,
+ CIRChipsets, CIRPciChipsets, devSections,
+ numDevSections, drv, &usedChips);
+ /* Free it since we don't need that list after this */
+ xfree(devSections);
+ devSections = NULL;
+ if (numUsed <= 0)
+ return FALSE;
+
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn;
+
+ /* Allocate a ScrnInfoRec and claim the slot */
+ pScrn = xf86AllocateScreen(drv, 0);
+
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = CIR_DRIVER_NAME;
+ pScrn->name = CIR_NAME;
+ pScrn->Probe = CIRProbe;
+ /* The Laguna family of chips is so different from the Alpine
+ family that we won't share even the highest-level of
+ functions. But, the Laguna chips /are/ Cirrus chips, so
+ they should be handled in this driver (as opposed to their
+ own driver). */
+ pPci = xf86GetPciInfoForEntity(usedChips[i]);
+ if (pPci->chipType == PCI_CHIP_GD5462 ||
+ pPci->chipType == PCI_CHIP_GD5464 ||
+ pPci->chipType == PCI_CHIP_GD5464BD ||
+ pPci->chipType == PCI_CHIP_GD5465) {
+ pScrn->PreInit = LgPreInit;
+#if 1
+ pScrn->ScreenInit = LgScreenInit;
+ pScrn->SwitchMode = LgSwitchMode;
+ pScrn->AdjustFrame = LgAdjustFrame;
+ pScrn->EnterVT = LgEnterVT;
+ pScrn->LeaveVT = LgLeaveVT;
+ pScrn->FreeScreen = LgFreeScreen;
+ pScrn->ValidMode = LgValidMode;
+#endif
+ } else {
+ pScrn->PreInit = CIRPreInit;
+ pScrn->ScreenInit = CIRScreenInit;
+ pScrn->SwitchMode = CIRSwitchMode;
+ pScrn->AdjustFrame = CIRAdjustFrame;
+ pScrn->EnterVT = CIREnterVT;
+ pScrn->LeaveVT = CIRLeaveVT;
+ pScrn->FreeScreen = CIRFreeScreen;
+ pScrn->ValidMode = CIRValidMode;
+ }
+ foundScreen = TRUE;
+ xf86ConfigActivePciEntity(pScrn, usedChips[i], CIRPciChipsets, NULL,
+ NULL, NULL, NULL, NULL);
+ }
+ xfree(usedChips);
+
+ return foundScreen;
+}
+
+/*
+ * CIRCountRAM --
+ *
+ * Counts amount of installed RAM
+ *
+ * XXX Can use options to configure memory on non-primary cards.
+ */
+static int
+CIRCountRam(ScrnInfoPtr pScrn)
+{
+ CIRPtr pCir = CIRPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ MessageType from;
+ int videoram = 0;
+
+ /* Map the CIR memory and MMIO areas */
+ pCir->FbMapSize = 1024*1024; /* XX temp */
+ if (!CIRMapMem(pScrn))
+ return 0;
+
+ if(pCir->UseMMIO) {
+ vgaHWSetMmioFuncs(hwp, pCir->IOBase, -0x3C0);
+ }
+
+ if(pCir->SR0F != (CARD32)-1) {
+ from = X_CONFIG;
+ hwp->writeSeq(hwp, 0x0F, pCir->SR0F);
+ }
+ else {
+ from = X_PROBED;
+ pCir->SR0F = hwp->readSeq(hwp, 0x0F);
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Memory Config reg 1 is 0x%02X\n",
+ pCir->SR0F);
+
+ switch (pCir->Chipset) {
+ case PCI_CHIP_GD5430:
+/* case PCI_CHIP_GD5440: */
+ switch(pCir->SR0F & 0x18) {
+ case 0x08:
+ videoram = 512;
+ break;
+ case 0x10:
+ videoram = 1024;
+ break;
+ case 0x18:
+ videoram = 2048;
+ break;
+ }
+ break;
+
+ case PCI_CHIP_GD5434_4:
+ case PCI_CHIP_GD5434_8:
+ case PCI_CHIP_GD5436:
+ switch(pCir->SR0F & 0x18) {
+ case 0x10:
+ videoram = 1024;
+ break;
+ case 0x18:
+ videoram = 2048;
+ if(pCir->SR0F & 0x80)
+ videoram = 4096;
+ break;
+ }
+
+ case PCI_CHIP_GD5446:
+ videoram = 1024;
+
+ if(pCir->SR17 != (CARD32)-1) {
+ from = X_CONFIG;
+ hwp->writeSeq(hwp, 0x17, pCir->SR17);
+ }
+ else {
+ from = X_PROBED;
+ pCir->SR17 = hwp->readSeq(hwp, 0x17);
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Memory Config reg 2 is 0x%02X\n",
+ pCir->SR17);
+
+ if ((pCir->SR0F & 0x18) == 0x18) {
+ if(pCir->SR0F & 0x80) {
+ if(pCir->SR17 & 0x80)
+ videoram = 2048;
+ else if(pCir->SR17 & 0x02)
+ videoram = 3072;
+ else
+ videoram = 4096;
+ }
+ else {
+ if((pCir->SR17 & 80) == 0)
+ videoram = 2048;
+ }
+ }
+ break;
+
+ case PCI_CHIP_GD5480:
+ videoram = 1024;
+ if ((pCir->SR0F & 0x18) == 0x18) { /* 2 or 4 MB */
+ videoram *= 2048;
+ if (pCir->SR0F & 0x80) /* Second bank enable */
+ videoram = 4096;
+ }
+ break;
+ }
+
+ /* UNMap the CIR memory and MMIO areas */
+ if (!CIRUnmapMem(pScrn))
+ return 0;
+
+ return videoram;
+}
+
+
+/*
+ * GetAccelPitchValues -
+ *
+ * This function returns a list of display width (pitch) values that can
+ * be used in accelerated mode.
+ */
+static int *
+GetAccelPitchValues(ScrnInfoPtr pScrn)
+{
+ int *linePitches = NULL;
+ int i, n = 0;
+ CIRPtr pCir = CIRPTR(pScrn);
+
+ /* XXX ajv - 512, 576, and 1536 may not be supported
+ line pitches. see sdk pp 4-59 for more
+ details. Why anyone would want less than 640 is
+ bizarre. (maybe lots of pixels tall?) */
+
+ /* The only line pitches the accelerator supports */
+#if 0
+ int accelWidths[] = { 512, 576, 640, 768, 800, 960,
+ 1024, 1152, 1280, 1536, 1600, 1920, 2048, 0 };
+#else
+ int accelWidths[] = { 640, 768, 800, 960, 1024, 1152, 1280,
+ 1600, 1920, 2048, 0 };
+#endif
+
+ for (i = 0; accelWidths[i] != 0; i++) {
+ if (accelWidths[i] % pCir->Rounding == 0) {
+ n++;
+ linePitches = xnfrealloc(linePitches, n * sizeof(int));
+ linePitches[n - 1] = accelWidths[i];
+ }
+ }
+ /* Mark the end of the list */
+ if (n > 0) {
+ linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
+ linePitches[n] = 0;
+ }
+ return linePitches;
+}
+
+
+/* Mandatory */
+static Bool
+CIRPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ CIRPtr pCir;
+ MessageType from;
+ int i;
+ ClockRangePtr clockRanges;
+ char *mod = NULL;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRPreInit\n");
+#endif
+
+ /*
+ * Note: This function is only called once at server startup, and
+ * not at the start of each server generation. This means that
+ * only things that are persistent across server generations can
+ * be initialised here. xf86Screens[] is (pScrn is a pointer to one
+ * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex()
+ * are too, and should be used for data that must persist across
+ * server generations.
+ *
+ * Per-generation data should be allocated with
+ * AllocateScreenPrivateIndex() from the ScreenInit() function.
+ */
+
+ /* Check the number of entities, and fail if it isn't one. */
+ if (pScrn->numEntities != 1)
+ return FALSE;
+
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /*
+ * Allocate a vgaHWRec
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ /* Allocate the CIRRec driverPrivate */
+ if (!CIRGetRec(pScrn)) {
+ return FALSE;
+ }
+ pCir = CIRPTR(pScrn);
+ pCir->pScrn = pScrn;
+
+ /* Get the entity, and make sure it is PCI. */
+ pCir->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pCir->pEnt->location.type != BUS_PCI)
+ return FALSE;
+
+ /* Find the PCI info for this screen */
+ pCir->PciInfo = xf86GetPciInfoForEntity(pCir->pEnt->index);
+ pCir->PciTag = pciTag(pCir->PciInfo->bus, pCir->PciInfo->device,
+ pCir->PciInfo->func);
+
+ /*
+ * XXX Check which of the VGA resources are decode and/or actually
+ * required in operating mode? For now, assume everything is needed,
+ * so don't call xf86SetOperatingState().
+ */
+ pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+ pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*
+ * The first thing we should figure out is the depth, bpp, etc.
+ * Our default depth is 8, so pass it to the helper function.
+ * We support both 24bpp and 32bpp layouts, so indicate that.
+ */
+ if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb | Support32bppFb |
+ SupportConvert32to24 | PreferConvert32to24)) {
+ return FALSE;
+ } else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 1:
+ case 4:
+ case 8:
+ case 15:
+ case 16:
+ case 24:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+ xf86PrintDepthBpp(pScrn);
+
+ /* Get the depth24 pixmap format */
+ if (pScrn->depth == 24 && pix24bpp == 0)
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /* The gamma fields must be initialised when using the new cmap code */
+ if (pScrn->depth > 1) {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros))
+ return FALSE;
+ }
+
+ /* We use a programamble clock */
+ pScrn->progClock = TRUE;
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, CIROptions);
+
+ pScrn->rgbBits = 6;
+ from = X_DEFAULT;
+ pCir->HWCursor = FALSE;
+ if (xf86GetOptValBool(CIROptions, OPTION_HW_CURSOR, &pCir->HWCursor)) {
+ from = X_CONFIG;
+ }
+ if (xf86ReturnOptValBool(CIROptions, OPTION_SW_CURSOR, FALSE)) {
+ from = X_CONFIG;
+ pCir->HWCursor = FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pCir->HWCursor ? "HW" : "SW");
+ if (xf86ReturnOptValBool(CIROptions, OPTION_NOACCEL, FALSE)) {
+ pCir->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+ if(pScrn->bitsPerPixel < 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Cannot use accelerations in less than 8 bpp\n");
+ pCir->NoAccel = TRUE;
+ }
+
+ /*
+ * Set the Chipset and ChipRev, allowing config file entries to
+ * override.
+ */
+ if (pCir->pEnt->device->chipset && *pCir->pEnt->device->chipset) {
+ pScrn->chipset = pCir->pEnt->device->chipset;
+ pCir->Chipset = xf86StringToToken(CIRChipsets, pScrn->chipset);
+ from = X_CONFIG;
+ } else if (pCir->pEnt->device->chipID >= 0) {
+ pCir->Chipset = pCir->pEnt->device->chipID;
+ pScrn->chipset = (char *)xf86TokenToString(CIRChipsets, pCir->Chipset);
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pCir->Chipset);
+ } else {
+ from = X_PROBED;
+ pCir->Chipset = pCir->PciInfo->chipType;
+ pScrn->chipset = (char *)xf86TokenToString(CIRChipsets, pCir->Chipset);
+ }
+ if (pCir->pEnt->device->chipRev >= 0) {
+ pCir->ChipRev = pCir->pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pCir->ChipRev);
+ } else {
+ pCir->ChipRev = pCir->PciInfo->chipRev;
+ }
+
+ /*
+ * This shouldn't happen because such problems should be caught in
+ * CIRProbe(), but check it just in case.
+ */
+ if (pScrn->chipset == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ChipID 0x%04X is not recognised\n", pCir->Chipset);
+ return FALSE;
+ }
+ if (pCir->Chipset < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Chipset \"%s\" is not recognised\n", pScrn->chipset);
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
+
+ /* Find the frame buffer base address */
+ if (pCir->pEnt->device->MemBase != 0) {
+ /*
+ * XXX Should check that the config file value matches one of the
+ * PCI base address values.
+ */
+ pCir->FbAddress = pCir->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ if (pCir->PciInfo->memBase[0] != 0) {
+ /* 5446B and 5480 use mask of 0xfe000000.
+ 5446A uses 0xff000000. */
+ pCir->FbAddress = pCir->PciInfo->memBase[0] & 0xff000000;
+ from = X_PROBED;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid FB address in PCI config space\n");
+ CIRFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pCir->FbAddress);
+
+ if (pCir->pEnt->device->IOBase != 0) {
+ pCir->IOAddress = pCir->pEnt->device->IOBase;
+ from = X_CONFIG;
+ } else {
+ if (pCir->PciInfo->memBase[1] != 0) {
+ pCir->IOAddress = pCir->PciInfo->memBase[1] & 0xfffff000;
+ from = X_PROBED;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid MMIO address in PCI config space\n");
+ /* 5446 rev A do not use a separate MMIO segment */
+ /* We do not really need that YET. */
+ }
+ }
+ if(pCir->IOAddress != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
+ (unsigned long)pCir->IOAddress);
+ /* Default to MMIO if we have a separate IOAddress and
+ not in monochrome mode (IO 0x3Bx is not relocated!) */
+ if (pScrn->bitsPerPixel != 1)
+ pCir->UseMMIO = TRUE;
+ }
+
+ /* User options can override the MMIO default */
+#if 0
+ /* Will we ever support MMIO on 5446A or older? */
+ if (xf86ReturnOptValBool(CIROptions, OPTION_MMIO, FALSE)) {
+ pCir->UseMMIO = TRUE;
+ from = X_CONFIG;
+ }
+#endif
+ if (!xf86ReturnOptValBool(CIROptions, OPTION_MMIO, TRUE)) {
+ pCir->UseMMIO = FALSE;
+ from = X_CONFIG;
+ }
+ if (pCir->UseMMIO) {
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using MMIO\n");
+ }
+
+ /* Register the PCI-assigned resources. */
+ if (xf86RegisterResources(pCir->pEnt->index, NULL, ResExclusive)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n");
+ return FALSE;
+ }
+
+ /* XXX If UseMMIO == TRUE and for any reason we cannot do MMIO,
+ abort here */
+
+ /* XXX We do not know yet how to configure memory on this card.
+ Use options MemCFG1 and MemCFG2 to set registers SR0F and
+ SR17 before trying to count ram size. */
+
+ pCir->SR0F = (CARD32)-1;
+ pCir->SR17 = (CARD32)-1;
+
+ (void) xf86GetOptValULong(CIROptions, OPTION_MEMCFG1, &pCir->SR0F);
+ (void) xf86GetOptValULong(CIROptions, OPTION_MEMCFG2, &pCir->SR17);
+
+ /*
+ * If the user has specified the amount of memory in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pCir->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pCir->pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else {
+ pScrn->videoRam = CIRCountRam(pScrn);
+ from = X_PROBED;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+
+ pCir->FbMapSize = pScrn->videoRam * 1024;
+
+ /* XXX Set HW cursor use */
+
+ /* Set the min pixel clock */
+ pCir->MinClock = 12000; /* XXX Guess, need to check this */
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
+ pCir->MinClock / 1000);
+ /*
+ * If the user has specified ramdac speed in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pCir->pEnt->device->dacSpeeds[0]) {
+ ErrorF("Do not specily a Clocks line for Cirrus chips\n");
+ return FALSE;
+ } else {
+ int speed;
+ int *p = NULL;
+ switch (pCir->Chipset) {
+ case PCI_CHIP_GD5430:
+ case PCI_CHIP_GD5434_4:
+ case PCI_CHIP_GD5434_8:
+ case PCI_CHIP_GD5436:
+/* case PCI_CHIP_GD5440: */
+ p = gd5430_MaxClocks;
+ break;
+ case PCI_CHIP_GD5446:
+ p = gd5446_MaxClocks;
+ break;
+ case PCI_CHIP_GD5480:
+ p = gd5480_MaxClocks;
+ break;
+ }
+ if (!p)
+ return FALSE;
+ switch(pScrn->bitsPerPixel) {
+ case 1:
+ case 4:
+ speed = p[0];
+ break;
+ case 8:
+ speed = p[1];
+ break;
+ case 15:
+ case 16:
+ speed = p[2];
+ break;
+ case 24:
+ speed = p[3];
+ break;
+ case 32:
+ speed = p[4];
+ break;
+ default:
+ /* Should not get here */
+ speed = 0;
+ break;
+ }
+ pCir->MaxClock = speed;
+ from = X_PROBED;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
+ pCir->MaxClock / 1000);
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+ clockRanges = xnfalloc(sizeof(ClockRange));
+ clockRanges->next = NULL;
+ clockRanges->minClock = pCir->MinClock;
+ clockRanges->maxClock = pCir->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = FALSE; /* XXX check this */
+ clockRanges->doubleScanAllowed = FALSE; /* XXX check this */
+ clockRanges->doubleScanAllowed = FALSE; /* XXX check this */
+ clockRanges->doubleScanAllowed = FALSE; /* XXX check this */
+ clockRanges->ClockMulFactor = 1;
+ clockRanges->ClockDivFactor = 1;
+ clockRanges->PrivFlags = 0;
+
+ pCir->Rounding = 128 >> pCir->BppShift;
+
+#if 0
+ if(pCir->Chipset != PCI_CHIP_GD5446 &&
+ pCir->Chipset != PCI_CHIP_GD5480) {
+ /* XXX Kludge */
+ pCir->NoAccel = TRUE;
+ }
+#endif
+
+ /*
+ * xf86ValidateModes will check that the mode HTotal and VTotal values
+ * don't exceed the chipset's limit if pScrn->maxHValue and
+ * pScrn->maxVValue are set. Since our CIRValidMode() already takes
+ * care of this, we don't worry about setting them here.
+ */
+
+ /* Select valid modes from those available */
+ if (pCir->NoAccel) {
+ /*
+ * XXX Assuming min pitch 256, max 2048
+ * XXX Assuming min height 128, max 2048
+ */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, 256, 2048,
+ pCir->Rounding * pScrn->bitsPerPixel, 128, 2048,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pCir->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+
+ } else {
+ /*
+ * XXX Assuming min height 128, max 2048
+ */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ GetAccelPitchValues(pScrn), 0, 0,
+ pCir->Rounding * pScrn->bitsPerPixel, 128, 2048,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pCir->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+ }
+ if (i == -1) {
+ CIRFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ CIRFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /*
+ * Set the CRTC parameters for all of the modes based on the type
+ * of mode, and the chipset's interlace requirements.
+ *
+ * Calling this is required if the mode->Crtc* values are used by the
+ * driver and if the driver doesn't provide code to set them. They
+ * are not pre-initialised at all.
+ */
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 1: mod = "xf1bpp"; break;
+ case 4: mod = "xf4bpp"; break;
+ case 8: mod = "cfb"; break;
+ case 16: mod = "cfb16"; break;
+ case 24: if (pix24bpp == 24)
+ mod = "cfb24";
+ else
+ mod = "xf24_32bpp";
+ break;
+ case 32: mod = "cfb32"; break;
+ }
+ if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ CIRFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Load XAA if needed */
+ if (!pCir->NoAccel) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ CIRFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ /* Load ramdac if needed */
+ if (pCir->HWCursor) {
+ if (!xf86LoadSubModule(pScrn, "ramdac")) {
+ CIRFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+ }
+
+ if (!xf86LoadSubModule(pScrn, "i2c")) {
+ CIRFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(i2cSymbols,NULL);
+
+ if (!xf86LoadSubModule(pScrn, "ddc")) {
+ CIRFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+
+ return TRUE;
+}
+
+/*
+ * Map the framebuffer and MMIO memory.
+ */
+
+Bool
+CIRMapMem(ScrnInfoPtr pScrn)
+{
+ CIRPtr pCir;
+ int mmioFlags;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRMapMem\n");
+#endif
+
+ pCir = CIRPTR(pScrn);
+
+ /*
+ * Map the frame buffer.
+ */
+
+ pCir->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pCir->PciTag,
+ (unsigned long)pCir->FbAddress,
+ pCir->FbMapSize);
+ if (pCir->FbBase == NULL)
+ return FALSE;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRMapMem pCir->FbBase=0x%08x\n", pCir->FbBase);
+#endif
+
+ /*
+ * Map IO registers to virtual address space
+ */
+ if (pCir->IOAddress == 0) {
+ pCir->IOBase = NULL; /* Until we are ready to use MMIO */
+ }
+ else {
+#if !defined(__alpha__)
+ mmioFlags = VIDMEM_MMIO;
+#else
+ /*
+ * For Alpha, we need to map SPARSE memory, since we need
+ * byte/short access.
+ */
+ mmioFlags = VIDMEM_MMIO | VIDMEM_SPARSE;
+#endif
+ pCir->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+ pCir->PciTag,
+ pCir->IOAddress, 0x4000);
+ if (pCir->IOBase == NULL)
+ return FALSE;
+ }
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRMapMem pCir->IOBase=0x%08x\n", pCir->IOBase);
+#endif
+
+#ifdef __alpha__
+ if (pCir->IOAddress == 0) {
+ pCir->IOBaseDense = NULL;
+ }
+ else {
+ /*
+ * for Alpha, we need to map DENSE memory as well, for
+ * setting CPUToScreenColorExpandBase.
+ */
+ pCir->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pCir->PciTag, pCir->IOAddress,
+ 0x4000);
+ if (pCir->IOBaseDense == NULL)
+ return FALSE;
+ }
+#endif /* __alpha__ */
+
+ return TRUE;
+}
+
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+Bool
+CIRUnmapMem(ScrnInfoPtr pScrn)
+{
+ CIRPtr pCir;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRUnmapMem\n");
+#endif
+
+ pCir = CIRPTR(pScrn);
+
+ if(pCir->IOBase != NULL) {
+ /*
+ * Unmap IO registers to virtual address space
+ */
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pCir->IOBase, 0x4000);
+ pCir->IOBase = NULL;
+ }
+
+#ifdef __alpha__
+ if(pCir->IOBaseDense != NULL) {
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pCir->IOBaseDense, 0x4000);
+ pCir->IOBaseDense = NULL;
+ }
+#endif /* __alpha__ */
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pCir->FbBase, pCir->FbMapSize);
+ pCir->FbBase = NULL;
+ return TRUE;
+}
+
+
+/*
+ * This function saves the video state.
+ */
+static void
+CIRSave(ScrnInfoPtr pScrn)
+{
+ CIRPtr pCir;
+ vgaHWPtr hwp;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRSave\n");
+#endif
+
+ hwp = VGAHWPTR(pScrn);
+ pCir = CIRPTR(pScrn);
+
+ vgaHWSave(pScrn, &VGAHWPTR(pScrn)->SavedReg, VGA_SR_ALL);
+
+#if 1
+ pCir->ModeReg.ExtVga[CR1A] = pCir->SavedReg.ExtVga[CR1A] = hwp->readCrtc(hwp, 0x1A);
+ pCir->ModeReg.ExtVga[CR1B] = pCir->SavedReg.ExtVga[CR1B] = hwp->readCrtc(hwp, 0x1B);
+ pCir->ModeReg.ExtVga[CR1D] = pCir->SavedReg.ExtVga[CR1D] = hwp->readCrtc(hwp, 0x1D);
+ pCir->ModeReg.ExtVga[SR07] = pCir->SavedReg.ExtVga[SR07] = hwp->readSeq(hwp, 0x07);
+ pCir->ModeReg.ExtVga[SR0E] = pCir->SavedReg.ExtVga[SR0E] = hwp->readSeq(hwp, 0x0E);
+ pCir->ModeReg.ExtVga[SR12] = pCir->SavedReg.ExtVga[SR12] = hwp->readSeq(hwp, 0x12);
+ pCir->ModeReg.ExtVga[SR13] = pCir->SavedReg.ExtVga[SR13] = hwp->readSeq(hwp, 0x13);
+ pCir->ModeReg.ExtVga[SR1E] = pCir->SavedReg.ExtVga[SR1E] = hwp->readSeq(hwp, 0x1E);
+ pCir->ModeReg.ExtVga[GR17] = pCir->SavedReg.ExtVga[GR17] = hwp->readGr(hwp, 0x17);
+ pCir->ModeReg.ExtVga[GR18] = pCir->SavedReg.ExtVga[GR18] = hwp->readGr(hwp, 0x18);
+ /* The first 4 reads are for the pixel mask register. After 4 times that
+ this register is accessed in succession reading/writing this address
+ accesses the HDR. */
+ hwp->readDacMask(hwp); hwp->readDacMask(hwp);
+ hwp->readDacMask(hwp); hwp->readDacMask(hwp);
+ pCir->ModeReg.ExtVga[HDR ] = pCir->SavedReg.ExtVga[HDR ] = hwp->readDacMask(hwp);
+#else
+ outb(hwp->IOBase+4, 0x1A); pCir->ModeReg.ExtVga[CR1A] = pCir->SavedReg.ExtVga[CR1A] = inb(hwp->IOBase + 5);
+ outb(hwp->IOBase+4, 0x1B); pCir->ModeReg.ExtVga[CR1B] = pCir->SavedReg.ExtVga[CR1B] = inb(hwp->IOBase + 5);
+ outb(hwp->IOBase+4, 0x1D); pCir->ModeReg.ExtVga[CR1D] = pCir->SavedReg.ExtVga[CR1D] = inb(hwp->IOBase + 5);
+ outb(0x3C4, 0x07); pCir->ModeReg.ExtVga[SR07] = pCir->SavedReg.ExtVga[SR07] = inb(0x3C5);
+ outb(0x3C4, 0x0E); pCir->ModeReg.ExtVga[SR0E] = pCir->SavedReg.ExtVga[SR0E] = inb(0x3C5);
+ outb(0x3C4, 0x12); pCir->ModeReg.ExtVga[SR12] = pCir->SavedReg.ExtVga[SR12] = inb(0x3C5);
+ outb(0x3C4, 0x13); pCir->ModeReg.ExtVga[SR13] = pCir->SavedReg.ExtVga[SR13] = inb(0x3C5);
+ outb(0x3C4, 0x1E); pCir->ModeReg.ExtVga[SR1E] = pCir->SavedReg.ExtVga[SR1E] = inb(0x3C5);
+ outb(0x3CE, 0x17); pCir->ModeReg.ExtVga[GR17] = pCir->SavedReg.ExtVga[GR17] = inb(0x3CF);
+ outb(0x3CE, 0x18); pCir->ModeReg.ExtVga[GR18] = pCir->SavedReg.ExtVga[GR18] = inb(0x3CF);
+ /* The first 4 reads are for the pixel mask register. After 4 times that
+ this register is accessed in succession reading/writing this address
+ accesses the HDR. */
+ inb(0x3C6); inb(0x3C6); inb(0x3C6); inb(0x3C6);
+ pCir->ModeReg.ExtVga[HDR ] = pCir->SavedReg.ExtVga[HDR ] = inb(0x3C6);
+#endif
+}
+
+/* XXX */
+static void
+CIRFix1bppColorMap(ScrnInfoPtr pScrn) {
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+/* In 1 bpp we have color 0 at LUT 0 and color 1 at LUT 0x3f.
+ This makes white and black look right (otherwise they were both
+ black. I'm sure there's a better way to do that, just lazy to
+ search the docs. */
+
+#if 1
+ hwp->writeDacWriteAddr(hwp, 0x00);
+ hwp->writeDacData(hwp, 0x00); hwp->writeDacData(hwp, 0x00); hwp->writeDacData(hwp, 0x00);
+ hwp->writeDacWriteAddr(hwp, 0x3F);
+ hwp->writeDacData(hwp, 0x3F); hwp->writeDacData(hwp, 0x3F); hwp->writeDacData(hwp, 0x3F);
+#else
+ outb(0x3C8, 0x00); outb(0x3C9, 0x00); outb(0x3C9, 0x00); outb(0x3C9, 0x00);
+ outb(0x3C8, 0x3F); outb(0x3C9, 0x3F); outb(0x3C9, 0x3F); outb(0x3C9, 0x3F);
+#endif
+}
+
+
+/*
+ * Initialise a new mode. This is currently still using the old
+ * "initialise struct, restore/write struct to HW" model. That could
+ * be changed.
+ */
+
+static Bool
+CIRModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp;
+ vgaRegPtr vgaReg;
+ CIRPtr pCir;
+ int depthcode;
+ int width;
+ Bool HDiv2 = FALSE, VDiv2 = FALSE;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRModeInit %d bpp, %d %d %d %d %d %d %d %d %d\n",
+ pScrn->bitsPerPixel,
+ mode->Clock,
+ mode->HDisplay,
+ mode->HSyncStart,
+ mode->HSyncEnd,
+ mode->HTotal,
+ mode->VDisplay,
+ mode->VSyncStart,
+ mode->VSyncEnd,
+ mode->VTotal);
+
+ ErrorF("CIRModeInit: depth %d bits\n", pScrn->depth);
+#endif
+
+ pCir = CIRPTR(pScrn);
+ hwp = VGAHWPTR(pScrn);
+ vgaHWUnlock(hwp);
+
+ depthcode = pScrn->depth;
+ if(pScrn->bitsPerPixel == 32)
+ depthcode = 32;
+
+ if ((pCir->Chipset == PCI_CHIP_GD5480 && mode->Clock > 135100) ||
+ (pCir->Chipset == PCI_CHIP_GD5446 && mode->Clock > 85500)) {
+ /* The actual DAC register value is set later. */
+ /* The CRTC is clocked at VCLK / 2, so we must half the */
+ /* horizontal timings. */
+ if (!mode->CrtcHAdjusted) {
+ mode->CrtcHDisplay >>= 1;
+ mode->CrtcHSyncStart >>= 1;
+ mode->CrtcHTotal >>= 1;
+ mode->CrtcHSyncEnd >>= 1;
+ mode->SynthClock >>= 1;
+ mode->CrtcHAdjusted = TRUE;
+ }
+ depthcode += 64;
+ HDiv2 = TRUE;
+ }
+
+ if (mode->VTotal >= 1024 && !(mode->Flags & V_INTERLACE)) {
+ /* For non-interlaced vertical timing >= 1024, the vertical timings */
+ /* are divided by 2 and VGA CRTC 0x17 bit 2 is set. */
+ if (!mode->CrtcVAdjusted) {
+ mode->CrtcVDisplay >>= 1;
+ mode->CrtcVSyncStart >>= 1;
+ mode->CrtcVSyncEnd >>= 1;
+ mode->CrtcVTotal >>= 1;
+ mode->CrtcVAdjusted = TRUE;
+ }
+ VDiv2 = TRUE;
+ }
+
+ /* Initialise the ModeReg values */
+ if (!vgaHWInit(pScrn, mode))
+ return FALSE;
+ pScrn->vtSema = TRUE;
+
+ /* Program the registers */
+ vgaHWProtect(pScrn, TRUE);
+
+ /* Turn off HW cursor, gamma correction, overscan color protect. */
+ pCir->ModeReg.ExtVga[SR12] = 0;
+#if 1
+ hwp->writeSeq(hwp, 0x12, pCir->ModeReg.ExtVga[SR12]);
+#else
+ outw(0x3C4, (pCir->ModeReg.ExtVga[SR12] << 8) | 0x12);
+#endif
+
+ if(VDiv2)
+ hwp->ModeReg.CRTC[0x17] |= 0x04;
+
+#ifdef CIR_DEBUG
+ ErrorF("SynthClock = %d\n", mode->SynthClock);
+#endif
+ CirrusSetClock(pScrn, mode->SynthClock);
+
+ /* Disable DCLK pin driver, interrupts. */
+ pCir->ModeReg.ExtVga[GR17] |= 0x08;
+ pCir->ModeReg.ExtVga[GR17] &= ~0x04;
+#if 1
+ hwp->writeGr(hwp, 0x17, pCir->ModeReg.ExtVga[GR17]);
+#else
+ outw(0x3CE, (pCir->ModeReg.ExtVga[GR17] << 8) | 0x17);
+#endif
+
+ vgaReg = &hwp->ModeReg;
+
+ pCir->ModeReg.ExtVga[HDR] = 0;
+ /* Enable linear mode and high-res packed pixel mode */
+ pCir->ModeReg.ExtVga[SR07] &= 0xe0;
+#ifdef CIR_DEBUG
+ ErrorF("depthcode = %d\n", depthcode);
+#endif
+
+ if(pScrn->bitsPerPixel == 1) {
+ hwp->IOBase = 0x3B0;
+ hwp->ModeReg.MiscOutReg &= ~0x01;
+ }
+ else {
+ hwp->IOBase = 0x3D0;
+ hwp->ModeReg.MiscOutReg |= 0x01;
+ }
+
+ switch(depthcode) {
+ case 1:
+ case 4:
+ pCir->ModeReg.ExtVga[SR07] |= 0x10;
+ break;
+ case 8:
+ pCir->ModeReg.ExtVga[SR07] |= 0x11;
+ break;
+ case 64+8:
+ pCir->ModeReg.ExtVga[SR07] |= 0x17;
+ break;
+ case 15:
+ pCir->ModeReg.ExtVga[SR07] |= 0x17;
+ pCir->ModeReg.ExtVga[HDR ] = 0xC0;
+ break;
+ case 64+15:
+ pCir->ModeReg.ExtVga[SR07] |= 0x19;
+ pCir->ModeReg.ExtVga[HDR ] = 0xC0;
+ break;
+ case 16:
+ pCir->ModeReg.ExtVga[SR07] |= 0x17;
+ pCir->ModeReg.ExtVga[HDR ] = 0xC1;
+ break;
+ case 64+16:
+ pCir->ModeReg.ExtVga[SR07] |= 0x19;
+ pCir->ModeReg.ExtVga[HDR ] = 0xC1;
+ break;
+ case 24:
+ pCir->ModeReg.ExtVga[SR07] |= 0x15;
+ pCir->ModeReg.ExtVga[HDR ] = 0xC5;
+ break;
+ case 32:
+ pCir->ModeReg.ExtVga[SR07] |= 0x19;
+ pCir->ModeReg.ExtVga[HDR ] = 0xC5;
+ break;
+ default:
+ ErrorF("X11: Internal error: CIRModeInit: Cannot Initialize display to requested mode\n");
+#ifdef CIR_DEBUG
+ ErrorF("CIRModeInit returning FALSE on depthcode %d\n", depthcode);
+#endif
+ return FALSE;
+ }
+ if(HDiv2)
+ pCir->ModeReg.ExtVga[GR18] |= 0x20;
+ else
+ pCir->ModeReg.ExtVga[GR18] &= ~0x20;
+
+ /* No support for interlace (yet) */
+ pCir->ModeReg.ExtVga[CR1A] = 0x00;
+
+#if 1
+ hwp->writeGr(hwp, 0x18, pCir->ModeReg.ExtVga[GR18]);
+#else
+ outw(0x3CE, (pCir->ModeReg.ExtVga[GR18] << 8) | 0x18);
+#endif
+
+#if 1
+ hwp->writeMiscOut(hwp, hwp->ModeReg.MiscOutReg);
+#else
+ outb(0x3C2, hwp->ModeReg.MiscOutReg);
+#endif
+
+#if 1
+ hwp->writeSeq(hwp, 0x07, pCir->ModeReg.ExtVga[SR07]);
+ hwp->readDacMask(hwp); hwp->readDacMask(hwp); hwp->readDacMask(hwp); hwp->readDacMask(hwp);
+ hwp->writeDacMask(hwp, pCir->ModeReg.ExtVga[HDR ]);
+#else
+ outw(0x3C4, (pCir->ModeReg.ExtVga[SR07] << 8) | 0x07);
+ inb(0x3C6); inb(0x3C6); inb(0x3C6); inb(0x3C6);
+ outb(0x3C6, pCir->ModeReg.ExtVga[HDR ]);
+#endif
+
+ width = pScrn->displayWidth * pScrn->bitsPerPixel / 8;
+ if(pScrn->bitsPerPixel == 1)
+ width <<= 2;
+ hwp->ModeReg.CRTC[0x13] = width >> 3;
+ /* Offset extension (see CR13) */
+ pCir->ModeReg.ExtVga[CR1B] &= 0xAF;
+ pCir->ModeReg.ExtVga[CR1B] |= (width >> (3+4)) & 0x10;
+ pCir->ModeReg.ExtVga[CR1B] |= (width >> (3+3)) & 0x40;
+ pCir->ModeReg.ExtVga[CR1B] |= 0x22;
+
+#if 1
+ hwp->writeCrtc(hwp, 0x1A, pCir->ModeReg.ExtVga[CR1A]);
+ hwp->writeCrtc(hwp, 0x1B, pCir->ModeReg.ExtVga[CR1B]);
+#else
+ outw(hwp->IOBase + 4, (pCir->ModeReg.ExtVga[CR1A] << 8) | 0x1A);
+ outw(hwp->IOBase + 4, (pCir->ModeReg.ExtVga[CR1B] << 8) | 0x1B);
+#endif
+
+ /* Programme the registers */
+ vgaHWRestore(pScrn, &hwp->ModeReg, VGA_SR_MODE | VGA_SR_CMAP);
+
+ /* XXX */
+ if(pScrn->bitsPerPixel == 1)
+ CIRFix1bppColorMap(pScrn);
+
+ vgaHWProtect(pScrn, FALSE);
+
+ return TRUE;
+}
+
+/*
+ * Restore the initial (text) mode.
+ */
+static void
+CIRRestore(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp;
+ vgaRegPtr vgaReg;
+ CIRPtr pCir;
+ CIRRegPtr cirReg;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRRestore\n");
+#endif
+
+ hwp = VGAHWPTR(pScrn);
+ pCir = CIRPTR(pScrn);
+ vgaReg = &hwp->SavedReg;
+ cirReg = &pCir->SavedReg;
+
+ vgaHWProtect(pScrn, TRUE);
+
+#if 1
+ hwp->writeCrtc(hwp, 0x1A, cirReg->ExtVga[CR1A]);
+ hwp->writeCrtc(hwp, 0x1B, cirReg->ExtVga[CR1B]);
+ hwp->writeCrtc(hwp, 0x1D, cirReg->ExtVga[CR1D]);
+ hwp->writeSeq(hwp, 0x07, cirReg->ExtVga[SR07]);
+ hwp->writeSeq(hwp, 0x0E, cirReg->ExtVga[SR0E]);
+ hwp->writeSeq(hwp, 0x12, cirReg->ExtVga[SR12]);
+ hwp->writeSeq(hwp, 0x13, cirReg->ExtVga[SR13]);
+ hwp->writeSeq(hwp, 0x1E, cirReg->ExtVga[SR1E]);
+ hwp->writeGr(hwp, 0x17, cirReg->ExtVga[GR17]);
+ hwp->writeGr(hwp, 0x18, cirReg->ExtVga[GR18]);
+ /* The first 4 reads are for the pixel mask register. After 4 times that
+ this register is accessed in succession reading/writing this address
+ accesses the HDR. */
+ hwp->readDacMask(hwp); hwp->readDacMask(hwp); hwp->readDacMask(hwp); hwp->readDacMask(hwp);
+ hwp->writeDacMask(hwp, pCir->SavedReg.ExtVga[HDR ]);
+#else
+ outw(hwp->IOBase + 4, (cirReg->ExtVga[CR1A] << 8) | 0x1A);
+ outw(hwp->IOBase + 4, (cirReg->ExtVga[CR1B] << 8) | 0x1B);
+ outw(hwp->IOBase + 4, (cirReg->ExtVga[CR1D] << 8) | 0x1D);
+ outw(0x3C4, (cirReg->ExtVga[SR07] << 8) | 0x07);
+ outw(0x3C4, (cirReg->ExtVga[SR0E] << 8) | 0x0E);
+ outw(0x3C4, (cirReg->ExtVga[SR12] << 8) | 0x12);
+ outw(0x3C4, (cirReg->ExtVga[SR13] << 8) | 0x13);
+ outw(0x3C4, (cirReg->ExtVga[SR1E] << 8) | 0x1E);
+ outw(0x3CE, (cirReg->ExtVga[GR17] << 8) | 0x17);
+ outw(0x3CE, (cirReg->ExtVga[GR18] << 8) | 0x18);
+ /* The first 4 reads are for the pixel mask register. After 4 times that
+ this register is accessed in succession reading/writing this address
+ accesses the HDR. */
+ inb(0x3C6); inb(0x3C6); inb(0x3C6); inb(0x3C6);
+ outb(0x3C6, pCir->SavedReg.ExtVga[HDR ]);
+#endif
+
+ if (xf86IsPrimaryPci(pCir->PciInfo))
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+ else
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+ vgaHWProtect(pScrn, FALSE);
+}
+
+/* Mandatory */
+
+/* This gets called at the start of each server generation */
+
+static Bool
+CIRScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ /* The vgaHW references will disappear one day */
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ CIRPtr pCir;
+ int i, ret;
+ VisualPtr visual;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRScreenInit\n");
+#endif
+
+ /*
+ * First get the ScrnInfoRec
+ */
+ pScrn = xf86Screens[pScreen->myNum];
+
+ hwp = VGAHWPTR(pScrn);
+ pCir = CIRPTR(pScrn);
+
+ /* Map the VGA memory when the primary video */
+ if (xf86IsPrimaryPci(pCir->PciInfo)) {
+ hwp->MapSize = 0x10000; /* Standard 64k VGA window */
+ if (!vgaHWMapMem(pScrn))
+ return FALSE;
+ }
+
+ /* Map the CIR memory and MMIO areas */
+ if (!CIRMapMem(pScrn))
+ return FALSE;
+
+ if(pCir->UseMMIO) {
+ vgaHWSetMmioFuncs(hwp, pCir->IOBase, -0x3C0);
+ }
+
+ vgaHWGetIOBase(hwp);
+
+ /* Save the current state */
+ CIRSave(pScrn);
+
+ /* Initialise the first mode */
+ if (!CIRModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ /* Set the viewport */
+ CIRAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset the visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ /*
+ * For bpp > 8, the default visuals are not acceptable because we only
+ * support TrueColor and not DirectColor. To deal with this, call
+ * miSetVisualTypes with the appropriate visual mask.
+ */
+#ifdef CIR_DEBUG
+ ErrorF("CIRScreenInit before miSetVisualTypes\n");
+#endif
+ if (pScrn->bitsPerPixel > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
+ pScrn->defaultVisual))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+#ifdef CIR_DEBUG
+ ErrorF("CIRScreenInit after miSetVisualTypes\n");
+#endif
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ ret = xf1bppScreenInit(pScreen, pCir->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 4:
+ ret = xf4bppScreenInit(pScreen, pCir->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 8:
+ ret = cfbScreenInit(pScreen, pCir->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 16:
+ ret = cfb16ScreenInit(pScreen, pCir->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 24:
+ if (pix24bpp == 24)
+ ret = cfb24ScreenInit(pScreen, pCir->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ else
+ ret = cfb24_32ScreenInit(pScreen, pCir->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 32:
+ ret = cfb32ScreenInit(pScreen, pCir->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "X11: Internal error: invalid bpp (%d) in CIRScreenInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ if (!ret)
+ return FALSE;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRScreenInit after depth dependent init\n");
+#endif
+
+ /* Override the default mask/offset settings */
+ if (pScrn->bitsPerPixel > 8) {
+ for (i = 0; i < pScreen->numVisuals; i++) {
+ visual = &pScreen->visuals[i];
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ miInitializeBackingStore(pScreen);
+
+ /*
+ * Set initial black & white colourmap indices.
+ */
+ xf86SetBlackWhitePixels(pScreen);
+
+ if(!pCir->NoAccel) { /* Initialize XAA functions */
+ if(!(pCir->UseMMIO ? CIRXAAInitMMIO(pScreen) :
+ CIRXAAInit(pScreen)))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not initialize XAA\n");
+ }
+
+ /* Initialise cursor functions */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ if (pCir->HWCursor) { /* Initialize HW cursor layer */
+ if(!CIRHWCursorInit(pScreen))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ }
+#if 0
+ if(!CIRDGAInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "DGA initialization failed\n");
+ }
+#endif
+
+ if(!CIRI2CInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "I2C initialization failed\n");
+ }
+ else
+ xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,pCir->I2CPtr1));
+
+#ifdef CIRPROBEI2C
+ CirProbeI2C(pScrn->scrnIndex);
+#endif
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ if (pScrn->bitsPerPixel > 1 &&
+ pScrn->bitsPerPixel <= 8)
+ vgaHWHandleColormaps(pScreen);
+
+#ifdef DPMSExtension
+ xf86DPMSInit(pScreen, CIRDisplayPowerManagementSet, 0);
+#endif
+
+ pScrn->memPhysBase = pCir->FbAddress;
+ pScrn->fbOffset = 0;
+
+#ifdef XvExtension
+ {
+ XF86VideoAdaptorPtr *ptr;
+ int n;
+
+ n = xf86XVListGenericAdaptors(&ptr);
+ if (n) {
+ xf86XVScreenInit(pScreen, ptr, n);
+ }
+ }
+#endif
+
+ /*
+ * Wrap the CloseScreen vector and set SaveScreen.
+ */
+ pScreen->SaveScreen = CIRSaveScreen;
+ pCir->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = CIRCloseScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ /* Done */
+ return TRUE;
+}
+
+
+/* Usually mandatory */
+static Bool
+CIRSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return CIRModeInit(xf86Screens[scrnIndex], mode);
+}
+
+
+/*
+ * This function is used to initialize the Start Address - the first
+ * displayed location in the video memory.
+ */
+/* Usually mandatory */
+static void
+CIRAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn;
+ int Base, tmp;
+ CIRPtr pCir;
+ vgaHWPtr hwp;
+
+ pScrn = xf86Screens[scrnIndex];
+ hwp = VGAHWPTR(pScrn);
+ pCir = CIRPTR(pScrn);
+
+ Base = ((y * pScrn->displayWidth + x) / 8);
+ if(pScrn->bitsPerPixel != 1)
+ Base *= (pScrn->bitsPerPixel/4);
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRAdjustFrame %d %d 0x%x %d %x\n", x, y, flags, Base, Base);
+#endif
+
+ if ((Base & ~0x000FFFFF) != 0) {
+ ErrorF("X11: Internal error: CIRAdjustFrame: cannot handle overflow\n");
+ return;
+ }
+
+#if 1
+ hwp->writeCrtc(hwp, 0x0C, (Base >> 8) & 0xff);
+ hwp->writeCrtc(hwp, 0x0D, Base & 0xff);
+ tmp = hwp->readCrtc(hwp, 0x1B);
+#else
+ outw(hwp->IOBase + 4, (Base & 0x00FF00) | 0x0C);
+ outw(hwp->IOBase + 4, ((Base & 0x0000FF) << 8) | 0x0D);
+ outb(hwp->IOBase + 4, 0x1B);
+ tmp = inb(hwp->IOBase + 5);
+#endif
+ tmp &= 0xF2;
+ tmp |= (Base >> 16) & 0x01;
+ tmp |= (Base >> 15) & 0x0C;
+#if 1
+ hwp->writeCrtc(hwp, 0x1B, tmp);
+ tmp = hwp->readCrtc(hwp, 0x1D);
+#else
+ outb(hwp->IOBase + 5, tmp);
+ outb(hwp->IOBase + 4, 0x1D);
+ tmp = inb(hwp->IOBase + 5);
+#endif
+ tmp &= 0x7F;
+ tmp |= (Base >> 12) & 0x80;
+#if 1
+ hwp->writeCrtc(hwp, 0x1D, tmp);
+#else
+ outb(hwp->IOBase + 5, tmp);
+#endif
+}
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ *
+ * We may wish to unmap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static Bool
+CIREnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+#ifdef CIR_DEBUG
+ ErrorF("CIREnterVT\n");
+#endif
+
+ /* Should we re-save the text mode on each VT enter? */
+ return CIRModeInit(pScrn, pScrn->currentMode);
+}
+
+
+/*
+ * This is called when VT switching away from the X server. Its job is
+ * to restore the previous (text) mode.
+ *
+ * We may wish to remap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static void
+CIRLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+#ifdef CIR_DEBUG
+ ErrorF("CIRLeaveVT\n");
+#endif
+
+ CIRRestore(pScrn);
+ vgaHWLock(hwp);
+}
+
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode. It should also unmap the video memory, and free
+ * any per-generation data allocated by the driver. It should finish
+ * by unwrapping and calling the saved CloseScreen function.
+ */
+
+/* Mandatory */
+static Bool
+CIRCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CIRPtr pCir = CIRPTR(pScrn);
+
+ CIRRestore(pScrn);
+ vgaHWLock(hwp);
+
+ CIRUnmapMem(pScrn);
+ if (pCir->AccelInfoRec)
+ XAADestroyInfoRec(pCir->AccelInfoRec);
+ pCir->AccelInfoRec = NULL;
+ if (pCir->CursorInfoRec)
+ xf86DestroyCursorInfoRec(pCir->CursorInfoRec);
+ pCir->CursorInfoRec = NULL;
+#if 0
+ if (pCir->DGAInfo)
+ DGADestroyInfoRec(pCir->DGAInfo);
+ pCir->DGAInfo = NULL;
+#endif
+
+ pScrn->vtSema = FALSE;
+
+ pScreen->CloseScreen = pCir->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+
+/* Free up any persistent data structures */
+
+/* Optional */
+static void
+CIRFreeScreen(int scrnIndex, int flags)
+{
+#ifdef CIR_DEBUG
+ ErrorF("CIRFreeScreen\n");
+#endif
+ /*
+ * This only gets called when a screen is being deleted. It does not
+ * get called routinely at the end of a server generation.
+ */
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ CIRFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+/* Optional */
+static int
+CIRValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ int lace;
+
+ lace = 1 + ((mode->Flags & V_INTERLACE) != 0);
+
+ if ((mode->CrtcHDisplay <= 2048) &&
+ (mode->CrtcHSyncStart <= 4096) &&
+ (mode->CrtcHSyncEnd <= 4096) &&
+ (mode->CrtcHTotal <= 4096) &&
+ (mode->CrtcVDisplay <= 2048 * lace) &&
+ (mode->CrtcVSyncStart <= 4096 * lace) &&
+ (mode->CrtcVSyncEnd <= 4096 * lace) &&
+ (mode->CrtcVTotal <= 4096 * lace)) {
+ return(MODE_OK);
+ } else {
+ return(MODE_BAD);
+ }
+}
+
+/* Do screen blanking */
+
+/* Mandatory */
+static Bool
+CIRSaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+ return vgaHWSaveScreen(pScreen, unblank);
+}
+
+#if 0
+static CARD16
+CirrusSetClock(ScrnInfoPtr pScrn, int freq)
+{
+ int num, den, usemclk;
+ CARD8 tmp;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ CIRPtr pCir = CIRPTR(pScrn);
+
+ ErrorF("CirrusSetClock\n");
+
+ if(!CirrusFindClock(hwp, freq, pCir->MaxClock, &num, &den, &usemclk))
+ return 0;
+
+ ErrorF("CirrusSetClock: nom=%x den=%x usemclk=%x\n",
+ num, den, usemclk);
+
+ /* Set VCLK3. */
+#if 1
+ tmp = hwp->readSeq(hwp, 0x0E);
+ hwp->writeSeq(hwp, 0x0E, (tmp & 0x80) | num);
+ hwp->writeSeq(hwp, 0x1E, den);
+#else
+ outb(0x3c4, 0x0e);
+ tmp = inb(0x3c5);
+ outb(0x3c5, (tmp & 0x80) | num);
+ outb(0x3c4, 0x1e);
+ outb(0x3c5, den);
+#endif
+
+ return (num << 8) | den;
+}
+#endif
+
+/*
+ * CIRDisplayPowerManagementSet --
+ *
+ * Sets VESA Display Power Management Signaling (DPMS) Mode.
+ */
+#ifdef DPMSExtension
+static void
+CIRDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
+ int flags)
+{
+ unsigned char sr01, gr0e;
+ vgaHWPtr hwp;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRDisplayPowerManagementSet\n");
+#endif
+
+ hwp = VGAHWPTR(pScrn);
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRDisplayPowerManagementSet: %d\n", PowerManagementMode);
+#endif
+
+ switch (PowerManagementMode)
+ {
+ case DPMSModeOn:
+ /* Screen: On; HSync: On, VSync: On */
+ sr01 = 0x00;
+ gr0e = 0x00;
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off; HSync: Off, VSync: On */
+ sr01 = 0x20;
+ gr0e = 0x02;
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off; HSync: On, VSync: Off */
+ sr01 = 0x20;
+ gr0e = 0x04;
+ break;
+ case DPMSModeOff:
+ /* Screen: Off; HSync: Off, VSync: Off */
+ sr01 = 0x20;
+ gr0e = 0x06;
+ break;
+ default:
+ return;
+ }
+
+ sr01 |= hwp->readSeq(hwp, 0x01) & ~0x20;
+ hwp->writeSeq(hwp, 0x01, sr01);
+ gr0e |= hwp->readGr(hwp, 0x0E) & ~0x06;
+ hwp->writeGr(hwp, 0x0E, gr0e);
+}
+#endif
+
+#ifdef CIRPROBEI2C
+static void CirProbeI2C(int scrnIndex) {
+ int i;
+ I2CBusPtr b;
+
+ b = xf86I2CFindBus(scrnIndex, "I2C bus 1");
+ if (b == NULL)
+ ErrorF("Could not find I2C bus \"%s\"\n", "I2C bus 1");
+ else {
+ for(i = 2; i < 256; i += 2)
+ if(xf86I2CProbeAddress(b, i))
+ ErrorF("Found device 0x%02x on bus \"%s\"\n",
+ i, b->BusName);
+ }
+ b = xf86I2CFindBus(scrnIndex, "I2C bus 2");
+ if (b == NULL)
+ ErrorF("Could not find I2C bus \"%s\"\n", "I2C bus 2");
+ else {
+ for(i = 2; i < 256; i += 2)
+ if(xf86I2CProbeAddress(b, i))
+ ErrorF("Found device 0x%02x on bus \"%s\"\n",
+ i, b->BusName);
+ }
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_hwcurs.c b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_hwcurs.c
new file mode 100644
index 000000000..825b309f0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_hwcurs.c
@@ -0,0 +1,250 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_hwcurs.c,v 1.6 1999/04/25 10:02:07 dawes Exp $ */
+
+/* (c) Itai Nahshon */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+#include "vgaHW.h"
+
+#include "cir.h"
+
+#define CURSORWIDTH 32
+#define CURSORHEIGHT 32
+#define CURSORSIZE (CURSORWIDTH*CURSORHEIGHT/8)
+
+static void
+CIRSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) {
+ CIRPtr pCir = CIRPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+#ifdef CIR_DEBUG
+ ErrorF("CIRSetCursorColors\n");
+#endif
+#if 1
+ hwp->writeSeq(hwp, 0x12, pCir->ModeReg.ExtVga[SR12]|0x02);
+ hwp->writeDacWriteAddr(hwp, 0x00);
+ hwp->writeDacData(hwp, 0x3f & (bg >> 18));
+ hwp->writeDacData(hwp, 0x3f & (bg >> 10));
+ hwp->writeDacData(hwp, 0x3f & (bg >> 2));
+ hwp->writeDacWriteAddr(hwp, 0x0F);
+ hwp->writeDacData(hwp, 0x3F & (fg >> 18));
+ hwp->writeDacData(hwp, 0x3F & (fg >> 10));
+ hwp->writeDacData(hwp, 0x3F & (fg >> 2));
+ hwp->writeSeq(hwp, 0x12, pCir->ModeReg.ExtVga[SR12]);
+#else
+ outw(0x3C4, ((pCir->ModeReg.ExtVga[SR12] | 0x02) << 8) | 0x12);
+ outb(0x3c8, 0x00); outb(0x3c9, 0x3f & (bg >> 18)); outb(0x3c9, 0x3f & (bg >> 10)); outb(0x3c9, 0x3f & (bg >> 2));
+ outb(0x3c8, 0x0f); outb(0x3c9, 0x3f & (fg >> 18)); outb(0x3c9, 0x3f & (fg >> 10)); outb(0x3c9, 0x3f & (fg >> 2));
+ outw(0x3C4, (pCir->ModeReg.ExtVga[SR12] << 8) | 0x12);
+#endif
+}
+
+static void
+CIRLoadSkewedCursor(unsigned char *memx, unsigned char *CursorBits,
+ int x, int y) {
+ unsigned char mem[2*CURSORSIZE];
+ unsigned char *p1, *p2;
+ int i, j, m, a, b;
+
+ if(x > 0) x = 0; else x = -x;
+ if(y > 0) y = 0; else y = -y;
+
+ a = (x+y*CURSORWIDTH)>>3;
+ b = x & 7;
+
+ /* Copy the skewed mask bits */
+ p1 = mem;
+ p2 = CursorBits+a;
+ for(i = 0; i < CURSORSIZE-a-1; i++) {
+ *p1++ = (p2[0] << b) | (p2[1] >> (8-b));
+ p2++;
+ }
+ /* last mask byte */
+ *p1++ = (p2[0] << b);
+
+ /* Clear to end (bottom) of mask. */
+ for(i = i+1; i < CURSORSIZE; i++) {
+ *p1++ = 0;
+ }
+
+ /* Now copy the cursor bits */
+ /* p1 is already right */
+ p2 = CursorBits+CURSORSIZE+a;
+ for(i = 0; i < CURSORSIZE-a-1; i++) {
+ *p1++ = (p2[0] << b) | (p2[1] >> (8-b));
+ p2++;
+ }
+ /* last cursor byte */
+ *p1++ = (p2[0] << b);
+
+ /* Clear to end (bottom) of cursor. */
+ for(i = i+1; i < CURSORSIZE; i++) {
+ *p1++ = 0;
+ }
+
+ /* Clear the right unused area of the mask
+ and cyrsor bits. */
+ p2 = mem + CURSORWIDTH/8 - (x>>3) - 1;
+ for(i = 0; i < 2*CURSORHEIGHT; i++) {
+ m = (-1)<<(x&7);
+ p1 = p2;
+ p2 += CURSORWIDTH/8;
+ for(j = x>>3; j >= 0; j--) {
+ *p1 &= m;
+ m = 0;
+ p1++;
+ }
+ }
+ memcpy(memx, mem, 2*CURSORSIZE);
+}
+
+
+static void
+CIRSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) {
+ CIRPtr pCir = CIRPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+#if 0
+#ifdef CIR_DEBUG
+ ErrorF("CIRSetCursorPosition %d %d\n", x, y);
+#endif
+#endif
+
+ if(x < 0 || y < 0) {
+ if(x+CURSORWIDTH <= 0 || y+CURSORHEIGHT <= 0) {
+#if 1
+ hwp->writeSeq(hwp, 0x12, pCir->ModeReg.ExtVga[SR12] & ~0x01);
+#else
+ outw(0x3C4, ((pCir->ModeReg.ExtVga[SR12] & ~0x01) << 8) | 0x12);
+#endif
+ return;
+ }
+ CIRLoadSkewedCursor(pCir->HWCursorBits, pCir->CursorBits, x, y);
+ pCir->CursorIsSkewed = TRUE;
+ if(x < 0) x = 0;
+ if(y < 0) y = 0;
+ }
+ else if(pCir->CursorIsSkewed) {
+ memcpy(pCir->HWCursorBits, pCir->CursorBits, 2*CURSORSIZE);
+ pCir->CursorIsSkewed = FALSE;
+ }
+#if 1
+ hwp->writeSeq(hwp, 0x12, pCir->ModeReg.ExtVga[SR12]);
+ hwp->writeSeq(hwp, ((x << 5)|0x10)&0xff, x >> 3);
+ hwp->writeSeq(hwp, ((y << 5)|0x11)&0xff, y >> 3);
+#else
+ outw(0x3C4, (pCir->ModeReg.ExtVga[SR12] << 8) | 0x12);
+ outw(0x3C4, (x << 5) | 0x10);
+ outw(0x3C4, (y << 5) | 0x11);
+#endif
+}
+
+static void
+CIRLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits) {
+ CIRPtr pCir = CIRPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRLoadCursorImage\n");
+#endif
+
+ pCir->CursorBits = bits;
+ memcpy(pCir->HWCursorBits, bits, 2*CURSORSIZE);
+ pCir->ModeReg.ExtVga[SR13] = 0x3f;
+#if 1
+ hwp->writeSeq(hwp, 0x13, 0x3f);
+#else
+ outw(0x3C4, 0x3f13);
+#endif
+}
+
+static void
+CIRHideCursor(ScrnInfoPtr pScrn) {
+ CIRPtr pCir = CIRPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRHideCursor\n");
+#endif
+ pCir->ModeReg.ExtVga[SR12] &= ~0x01;
+#if 1
+ hwp->writeSeq(hwp, 0x12, pCir->ModeReg.ExtVga[SR12]);
+#else
+ outw(0x3C4, (pCir->ModeReg.ExtVga[SR12] << 8) | 0x12);
+#endif
+}
+
+static void
+CIRShowCursor(ScrnInfoPtr pScrn) {
+ CIRPtr pCir = CIRPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRShowCursor\n");
+#endif
+ pCir->ModeReg.ExtVga[SR12] |= 0x01;
+#if 1
+ hwp->writeSeq(hwp, 0x12, pCir->ModeReg.ExtVga[SR12]);
+#else
+ outw(0x3C4, (pCir->ModeReg.ExtVga[SR12] << 8) | 0x12);
+#endif
+}
+
+static Bool
+CIRUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) {
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+#ifdef CIR_DEBUG
+ ErrorF("CIRUseHWCursor\n");
+#endif
+ if(pScrn->bitsPerPixel < 8)
+ return FALSE;
+
+ return TRUE;
+}
+
+Bool
+CIRHWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CIRPtr pCir = CIRPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRHWCursorInit\n");
+#endif
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pCir->CursorInfoRec = infoPtr;
+ pCir->HWCursorBits = pCir->FbBase + 1024*pScrn->videoRam - 2*CURSORSIZE;
+ pCir->CursorIsSkewed = FALSE;
+ pCir->CursorBits = NULL;
+
+ infoPtr->MaxWidth = CURSORWIDTH;
+ infoPtr->MaxHeight = CURSORHEIGHT;
+ infoPtr->Flags =
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+#endif
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
+ infoPtr->SetCursorColors = CIRSetCursorColors;
+ infoPtr->SetCursorPosition = CIRSetCursorPosition;
+ infoPtr->LoadCursorImage = CIRLoadCursorImage;
+ infoPtr->HideCursor = CIRHideCursor;
+ infoPtr->ShowCursor = CIRShowCursor;
+ infoPtr->UseHWCursor = CIRUseHWCursor;
+ infoPtr->RealizeCursor = NULL;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRHWCursorInit before xf86InitCursor\n");
+#endif
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_i2c.c b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_i2c.c
new file mode 100644
index 000000000..e056c5c8a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_i2c.c
@@ -0,0 +1,122 @@
+/* (c) Itai Nahshon */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_i2c.c,v 1.6 1999/02/28 11:19:38 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+#include "vgaHW.h"
+
+#include "cir.h"
+
+/*
+ * Switch between internal I2C bus and external (DDC) bus.
+ * There is one I2C port controlled bu SR08 and the programmable
+ * outputs control a multiplexer.
+ */
+static Bool
+CIRI2CSwitchToBus(I2CBusPtr b) {
+ CIRPtr pCir = ((CIRPtr)b->DriverPrivate.ptr);
+ vgaHWPtr hwp = VGAHWPTR(pCir->pScrn);
+ if (b == pCir->I2CPtr1) {
+ if ((pCir->ModeReg.ExtVga[GR17] & 0x60) == 0)
+ return TRUE;
+ pCir->ModeReg.ExtVga[GR17] &= ~0x60;
+ }
+ else if(b == pCir->I2CPtr2) {
+ if ((pCir->ModeReg.ExtVga[GR17] & 0x60) != 0)
+ return TRUE;
+ pCir->ModeReg.ExtVga[GR17] |= 0x60;
+ }
+ else return FALSE;
+
+ /* ErrorF("CIRI2CSwitchToBus: \"%s\"\n", b->BusName); */
+ hwp->writeGr(hwp, 0x17, pCir->ModeReg.ExtVga[GR17]);
+ return TRUE;
+}
+
+static void
+CIRI2CPutBits(I2CBusPtr b, int clock, int data) {
+ unsigned int reg = 0xfc;
+ CIRPtr pCir = ((CIRPtr)b->DriverPrivate.ptr);
+ vgaHWPtr hwp = VGAHWPTR(pCir->pScrn);
+
+ if(!CIRI2CSwitchToBus(b))
+ return;
+
+ if(clock) reg |= 1;
+ if(data) reg |= 2;
+ hwp->writeSeq(hwp, 0x08, reg);
+ /* ErrorF("CIRI2CPutBits: %d %d\n", clock, data); */
+}
+
+static void
+CIRI2CGetBits(I2CBusPtr b, int *clock, int *data) {
+ unsigned int reg;
+ CIRPtr pCir = ((CIRPtr)b->DriverPrivate.ptr);
+ vgaHWPtr hwp = VGAHWPTR(pCir->pScrn);
+
+ if(!CIRI2CSwitchToBus(b))
+ return;
+
+ reg = hwp->readSeq(hwp, 0x08);
+ *clock = (reg & 0x04) != 0;
+ *data = (reg & 0x80) != 0;
+ /* ErrorF("CIRI2CGetBits: %d %d\n", *clock, *data); */
+}
+
+Bool
+CIRI2CInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CIRPtr pCir = CIRPTR(pScrn);
+ I2CBusPtr I2CPtr;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRI2CInit\n");
+#endif
+
+ switch(pCir->Chipset) {
+ case PCI_CHIP_GD5446:
+ case PCI_CHIP_GD5480:
+ break;
+ default:
+ return FALSE;
+ }
+
+
+ I2CPtr = xf86CreateI2CBusRec();
+ if(!I2CPtr) return FALSE;
+
+ pCir->I2CPtr1 = I2CPtr;
+
+ I2CPtr->BusName = "I2C bus 1";
+ I2CPtr->scrnIndex = pScrn->scrnIndex;
+ I2CPtr->I2CPutBits = CIRI2CPutBits;
+ I2CPtr->I2CGetBits = CIRI2CGetBits;
+ I2CPtr->DriverPrivate.ptr = pCir;
+
+ if(!xf86I2CBusInit(I2CPtr))
+ return FALSE;
+
+ I2CPtr = xf86CreateI2CBusRec();
+ if(!I2CPtr) return FALSE;
+
+ pCir->I2CPtr2 = I2CPtr;
+
+ I2CPtr->BusName = "I2C bus 2";
+ I2CPtr->scrnIndex = pScrn->scrnIndex;
+ I2CPtr->I2CPutBits = CIRI2CPutBits;
+ I2CPtr->I2CGetBits = CIRI2CGetBits;
+ I2CPtr->DriverPrivate.ptr = pCir;
+
+ if(!xf86I2CBusInit(I2CPtr))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_xaa.c b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_xaa.c
new file mode 100644
index 000000000..4137552b2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_xaa.c
@@ -0,0 +1,251 @@
+/* (c) Itai Nahshon */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_xaa.c,v 1.2 1999/02/28 11:19:38 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+#include "vgaHW.h"
+
+#include "cir.h"
+
+static void CIRSync(ScrnInfoPtr pScrn)
+{
+#ifdef CIR_DEBUG
+ ErrorF("CIRSync\n");
+#endif
+
+ outb(0x3CE, 0x31);
+ while(inb(0x3CF) & 0x01)
+ ;
+
+ return;
+}
+
+static void
+CIRSetupForScreenToScreenCopy(
+ ScrnInfoPtr pScrn,
+ int xdir, int ydir,
+ int rop,
+ unsigned int planemask,
+ int trans_color) {
+
+ CIRPtr pCir = CIRPTR(pScrn);
+ int pitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8;
+
+ outb(0x3CE, 0x31);
+ while(inb(0x3CF) & 0x01)
+ ;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRSetupForScreenToScreenCopy xdir=%d ydir=%d rop=%x planemask=%x trans_color=%x\n",
+ xdir, ydir, rop, planemask, trans_color);
+#endif
+
+ outb(0x3CE, 0x32); outb(0x3CF, 0x0d);
+
+ /* Set dest pitch */
+ outb(0x3CE, 0x24);
+ outb(0x3CF, pitch & 0xff);
+ outb(0x3CE, 0x25);
+ outb(0x3CF, (pitch >> 8) & 0x1f);
+ /* Set source pitch */
+ outb(0x3CE, 0x26);
+ outb(0x3CF, pitch & 0xff);
+ outb(0x3CE, 0x27);
+ outb(0x3CF, (pitch >> 8) & 0x1f);
+}
+
+static void
+CIRSubsequentScreenToScreenCopy(
+ ScrnInfoPtr pScrn,
+ int x1, int y1,
+ int x2, int y2,
+ int w, int h) {
+
+ CIRPtr pCir = CIRPTR(pScrn);
+ int source, dest;
+ int hh, ww;
+ int decrement = 0;
+ int pitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8;
+
+ outb(0x3CE, 0x31);
+ while(inb(0x3CF) & 0x01)
+ ;
+
+ ww = (w * pScrn->bitsPerPixel / 8) - 1;
+ hh = h - 1;
+ /* Width */
+ outb(0x3CE, 0x20);
+ outb(0x3CF, ww & 0xff);
+ outb(0x3CE, 0x21);
+ outb(0x3CF, (ww >> 8)& 0x1f);
+ /* Height */
+ outb(0x3CE, 0x22);
+ outb(0x3CF, hh & 0xff);
+ outb(0x3CE, 0x23);
+ outb(0x3CF, (hh >> 8) & 0x07);
+
+ dest = y2 * pitch + x2 * pScrn->bitsPerPixel / 8;
+ source = y1 * pitch + x1 * pScrn->bitsPerPixel / 8;
+ if(dest > source) {
+ decrement = 1;
+ dest += hh * pitch + ww;
+ source += hh * pitch + ww;
+ }
+ /* dest */
+ outb(0x3CE, 0x28);
+ outb(0x3CF, dest & 0xff);
+ outb(0x3CE, 0x29);
+ outb(0x3CF, (dest >> 8) & 0xff);
+ outb(0x3CE, 0x2A);
+ outb(0x3CF, (dest >> 16) & 0x3f);
+ /* source */
+ outb(0x3CE, 0x2C);
+ outb(0x3CF, source & 0xff);
+ outb(0x3CE, 0x2D);
+ outb(0x3CF, (source >> 8) & 0xff);
+ outb(0x3CE, 0x2E);
+ outb(0x3CF, (source >> 16) & 0x3f);
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRSubsequentScreenToScreenCopy x1=%d y1=%d x2=%d y2=%d w=%d h=%d\n",
+ x1, y1, x2, y2, w, h);
+ ErrorF("CIRSubsequentScreenToScreenCopy s=%d d=%d ww=%d hh=%d\n",
+ source, dest, ww, hh);
+#endif
+
+ outb(0x3CE, 0x30);
+ outb(0x3CF, decrement);
+ outb(0x3CE, 0x31);
+ outb(0x3CF, 2);
+}
+
+static void
+CIRSetupForSolidFill(
+ ScrnInfoPtr pScrn,
+ int color,
+ int rop,
+ unsigned int planemask) {
+
+ CIRPtr pCir = CIRPTR(pScrn);
+ int pitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8;
+
+ outb(0x3CE, 0x31);
+ while(inb(0x3CF) & 0x01)
+ ;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRSetupForSolidFill color=%x rop=%x planemask=%x\n",
+ color, rop, planemask);
+#endif
+
+ outb(0x3CE, 0x32); outb(0x3CF, 0x0d);
+
+ outb(0x3CE, 0x33);
+ outb(0x3CF, 0x04);
+ outb(0x3CE, 0x30);
+ outb(0x3CF, 0xC0|((pScrn->bitsPerPixel - 8) << 1));
+
+ outb(0x3CE, 0x01);
+ outb(0x3CF, color & 0xff);
+ outb(0x3CE, 0x11);
+ outb(0x3CF, (color >> 8) & 0xff);
+ outb(0x3CE, 0x13);
+ outb(0x3CF, (color >> 16) & 0xff);
+ outb(0x3CE, 0x15);
+ outb(0x3CF, 0);
+
+ /* Set dest pitch */
+ outb(0x3CE, 0x24);
+ outb(0x3CF, pitch & 0xff);
+ outb(0x3CE, 0x25);
+ outb(0x3CF, (pitch >> 8) & 0x1f);
+}
+
+static void
+CIRSubsequentSolidFillRect(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h) {
+
+ CIRPtr pCir = CIRPTR(pScrn);
+ int dest;
+ int hh, ww;
+ int pitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8;
+
+ outb(0x3CE, 0x31);
+ while(inb(0x3CF) & 0x01)
+ ;
+
+ ww = (w * pScrn->bitsPerPixel / 8) - 1;
+ hh = h - 1;
+ /* Width */
+ outb(0x3CE, 0x20);
+ outb(0x3CF, ww & 0xff);
+ outb(0x3CE, 0x21);
+ outb(0x3CF, (ww >> 8)& 0x1f);
+ /* Height */
+ outb(0x3CE, 0x22);
+ outb(0x3CF, hh & 0xff);
+ outb(0x3CE, 0x23);
+ outb(0x3CF, (hh >> 8) & 0x07);
+
+ dest = y * pitch + x * pScrn->bitsPerPixel / 8;
+ /* dest */
+ outb(0x3CE, 0x28);
+ outb(0x3CF, dest & 0xff);
+ outb(0x3CE, 0x29);
+ outb(0x3CF, (dest >> 8) & 0xff);
+ outb(0x3CE, 0x2A);
+ outb(0x3CF, (dest >> 16) & 0x3f);
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRSubsequentSolidFillRect x=%d y=%d w=%d h=%d\n",
+ x, y, w, h);
+#endif
+
+ outb(0x3CE, 0x31);
+ outb(0x3CF, 2);
+}
+
+Bool
+CIRXAAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CIRPtr pCir = CIRPTR(pScrn);
+ XAAInfoRecPtr XAAPtr;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRXAAInit\n");
+#endif
+
+ XAAPtr = XAACreateInfoRec();
+ if(!XAAPtr) return FALSE;
+
+ XAAPtr->SetupForScreenToScreenCopy = CIRSetupForScreenToScreenCopy;
+ XAAPtr->SubsequentScreenToScreenCopy = CIRSubsequentScreenToScreenCopy;
+ XAAPtr->ScreenToScreenCopyFlags = GXCOPY_ONLY|NO_TRANSPARENCY|NO_PLANEMASK;
+
+ if(pCir->Chipset == PCI_CHIP_GD5446 ||
+ pCir->Chipset == PCI_CHIP_GD5480) {
+
+ XAAPtr->SetupForSolidFill = CIRSetupForSolidFill;
+ XAAPtr->SubsequentSolidFillRect = CIRSubsequentSolidFillRect;
+ XAAPtr->SubsequentSolidFillTrap = NULL;
+ XAAPtr->SolidFillFlags = GXCOPY_ONLY|NO_TRANSPARENCY|NO_PLANEMASK;
+ }
+
+ XAAPtr->Sync = CIRSync;
+
+ outw(0x3CE, 0x200E); /* enable writes to gr33 */
+
+ if(!XAAInit(pScreen, XAAPtr))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_xaam.c b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_xaam.c
new file mode 100644
index 000000000..200094977
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_xaam.c
@@ -0,0 +1,264 @@
+/* (c) Itai Nahshon */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/cir_xaam.c,v 1.1 1998/11/15 04:30:24 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+#include "vgaHW.h"
+
+#include "cir.h"
+
+#ifndef __alpha__
+#define minb(p) (*(volatile CARD8 *)(hwp->MMIOBase + hwp->MMIOOffset + (p)))
+#define moutb(p,v) \
+ (*(volatile CARD8 *)(hwp->MMIOBase + hwp->MMIOOffset + (p)) = (v))
+#else
+#define minb(p) xf86ReadSparse8(hwp->MMIOBase, hwp->MMIOOffset + (p))
+#define moutb(p,v) \
+ xf86WriteSparse8((v), hwp->MMIOBase, hwp->MMIOOffset + (p))
+#endif
+
+static void CIRSync(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+#ifdef CIR_DEBUG
+ ErrorF("CIRSync mm\n");
+#endif
+
+ moutb(0x3CE, 0x31);
+ while(minb(0x3CF) & 0x01)
+ ;
+
+ return;
+}
+
+static void
+CIRSetupForScreenToScreenCopy(
+ ScrnInfoPtr pScrn,
+ int xdir, int ydir,
+ int rop,
+ unsigned int planemask,
+ int trans_color) {
+
+ CIRPtr pCir = CIRPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ int pitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8;
+
+ moutb(0x3CE, 0x31);
+ while(minb(0x3CF) & 0x01)
+ ;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRSetupForScreenToScreenCopy xdir=%d ydir=%d rop=%x planemask=%x trans_color=%x\n",
+ xdir, ydir, rop, planemask, trans_color);
+#endif
+
+ moutb(0x3CE, 0x32); moutb(0x3CF, 0x0d);
+
+ /* Set dest pitch */
+ moutb(0x3CE, 0x24);
+ moutb(0x3CF, pitch & 0xff);
+ moutb(0x3CE, 0x25);
+ moutb(0x3CF, (pitch >> 8) & 0x1f);
+ /* Set source pitch */
+ moutb(0x3CE, 0x26);
+ moutb(0x3CF, pitch & 0xff);
+ moutb(0x3CE, 0x27);
+ moutb(0x3CF, (pitch >> 8) & 0x1f);
+}
+
+static void
+CIRSubsequentScreenToScreenCopy(
+ ScrnInfoPtr pScrn,
+ int x1, int y1,
+ int x2, int y2,
+ int w, int h) {
+
+ CIRPtr pCir = CIRPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ int source, dest;
+ int hh, ww;
+ int decrement = 0;
+ int pitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8;
+
+ moutb(0x3CE, 0x31);
+ while(minb(0x3CF) & 0x01)
+ ;
+
+ ww = (w * pScrn->bitsPerPixel / 8) - 1;
+ hh = h - 1;
+ /* Width */
+ moutb(0x3CE, 0x20);
+ moutb(0x3CF, ww & 0xff);
+ moutb(0x3CE, 0x21);
+ moutb(0x3CF, (ww >> 8)& 0x1f);
+ /* Height */
+ moutb(0x3CE, 0x22);
+ moutb(0x3CF, hh & 0xff);
+ moutb(0x3CE, 0x23);
+ moutb(0x3CF, (hh >> 8) & 0x07);
+
+ dest = y2 * pitch + x2 * pScrn->bitsPerPixel / 8;
+ source = y1 * pitch + x1 * pScrn->bitsPerPixel / 8;
+ if(dest > source) {
+ decrement = 1;
+ dest += hh * pitch + ww;
+ source += hh * pitch + ww;
+ }
+ /* dest */
+ moutb(0x3CE, 0x28);
+ moutb(0x3CF, dest & 0xff);
+ moutb(0x3CE, 0x29);
+ moutb(0x3CF, (dest >> 8) & 0xff);
+ moutb(0x3CE, 0x2A);
+ moutb(0x3CF, (dest >> 16) & 0x3f);
+ /* source */
+ moutb(0x3CE, 0x2C);
+ moutb(0x3CF, source & 0xff);
+ moutb(0x3CE, 0x2D);
+ moutb(0x3CF, (source >> 8) & 0xff);
+ moutb(0x3CE, 0x2E);
+ moutb(0x3CF, (source >> 16) & 0x3f);
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRSubsequentScreenToScreenCopy x1=%d y1=%d x2=%d y2=%d w=%d h=%d\n",
+ x1, y1, x2, y2, w, h);
+ ErrorF("CIRSubsequentScreenToScreenCopy s=%d d=%d ww=%d hh=%d\n",
+ source, dest, ww, hh);
+#endif
+
+ moutb(0x3CE, 0x30);
+ moutb(0x3CF, decrement);
+ moutb(0x3CE, 0x31);
+ moutb(0x3CF, 2);
+}
+
+static void
+CIRSetupForSolidFill(
+ ScrnInfoPtr pScrn,
+ int color,
+ int rop,
+ unsigned int planemask) {
+
+ CIRPtr pCir = CIRPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ int pitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8;
+
+ moutb(0x3CE, 0x31);
+ while(minb(0x3CF) & 0x01)
+ ;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRSetupForSolidFill color=%x rop=%x planemask=%x\n",
+ color, rop, planemask);
+#endif
+
+ moutb(0x3CE, 0x32); moutb(0x3CF, 0x0d);
+
+ moutb(0x3CE, 0x33);
+ moutb(0x3CF, 0x04);
+ moutb(0x3CE, 0x30);
+ moutb(0x3CF, 0xC0|((pScrn->bitsPerPixel - 8) << 1));
+
+ moutb(0x3CE, 0x01);
+ moutb(0x3CF, color & 0xff);
+ moutb(0x3CE, 0x11);
+ moutb(0x3CF, (color >> 8) & 0xff);
+ moutb(0x3CE, 0x13);
+ moutb(0x3CF, (color >> 16) & 0xff);
+ moutb(0x3CE, 0x15);
+ moutb(0x3CF, 0);
+
+ /* Set dest pitch */
+ moutb(0x3CE, 0x24);
+ moutb(0x3CF, pitch & 0xff);
+ moutb(0x3CE, 0x25);
+ moutb(0x3CF, (pitch >> 8) & 0x1f);
+}
+
+static void
+CIRSubsequentSolidFillRect(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h) {
+
+ CIRPtr pCir = CIRPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ int dest;
+ int hh, ww;
+ int pitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8;
+
+ moutb(0x3CE, 0x31);
+ while(minb(0x3CF) & 0x01)
+ ;
+
+ ww = (w * pScrn->bitsPerPixel / 8) - 1;
+ hh = h - 1;
+ /* Width */
+ moutb(0x3CE, 0x20);
+ moutb(0x3CF, ww & 0xff);
+ moutb(0x3CE, 0x21);
+ moutb(0x3CF, (ww >> 8)& 0x1f);
+ /* Height */
+ moutb(0x3CE, 0x22);
+ moutb(0x3CF, hh & 0xff);
+ moutb(0x3CE, 0x23);
+ moutb(0x3CF, (hh >> 8) & 0x07);
+
+ dest = y * pitch + x * pScrn->bitsPerPixel / 8;
+ /* dest */
+ moutb(0x3CE, 0x28);
+ moutb(0x3CF, dest & 0xff);
+ moutb(0x3CE, 0x29);
+ moutb(0x3CF, (dest >> 8) & 0xff);
+ moutb(0x3CE, 0x2A);
+ moutb(0x3CF, (dest >> 16) & 0x3f);
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRSubsequentSolidFillRect x=%d y=%d w=%d h=%d\n",
+ x, y, w, h);
+#endif
+
+ moutb(0x3CE, 0x31);
+ moutb(0x3CF, 2);
+}
+
+Bool
+CIRXAAInitMMIO(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CIRPtr pCir = CIRPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ XAAInfoRecPtr XAAPtr;
+
+#ifdef CIR_DEBUG
+ ErrorF("CIRXAAInit\n");
+#endif
+
+ XAAPtr = XAACreateInfoRec();
+ if(!XAAPtr) return FALSE;
+
+ XAAPtr->SetupForScreenToScreenCopy = CIRSetupForScreenToScreenCopy;
+ XAAPtr->SubsequentScreenToScreenCopy = CIRSubsequentScreenToScreenCopy;
+ XAAPtr->ScreenToScreenCopyFlags = GXCOPY_ONLY|NO_TRANSPARENCY|NO_PLANEMASK;
+
+ XAAPtr->SetupForSolidFill = CIRSetupForSolidFill;
+ XAAPtr->SubsequentSolidFillRect = CIRSubsequentSolidFillRect;
+ XAAPtr->SubsequentSolidFillTrap = NULL;
+ XAAPtr->SolidFillFlags = GXCOPY_ONLY|NO_TRANSPARENCY|NO_PLANEMASK;
+
+ XAAPtr->Sync = CIRSync;
+
+ moutb(0x3CE, 0x0E); /* enable writes to gr33 */
+ moutb(0x3CF, 0x20); /* enable writes to gr33 */
+
+ if(!XAAInit(pScreen, XAAPtr))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg.h b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg.h
new file mode 100644
index 000000000..0883ccd91
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg.h
@@ -0,0 +1,145 @@
+/*
+ * Common strutures and function for CL-GD546x -- The Laguna family
+ *
+ * lg.h
+ *
+ * (c) 1998 Corin Anderson.
+ * corina@the4cs.com
+ * Tukwila, WA
+ *
+ * Inspired by cir.h
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg.h,v 1.7 1999/07/11 08:49:25 dawes Exp $ */
+
+#ifndef LG_H
+#define LG_H
+
+#include "xf86Cursor.h"
+#include "xaa.h"
+#include "xf86i2c.h"
+
+#define LG_DEBUG
+
+/* Saved registers that are not part of the core VGA */
+/* CRTC >= 0x19; Sequencer >= 0x05; Graphics >= 0x09; Attribute >= 0x15 */
+enum {
+ /* CR regs */
+ CR1A,
+ CR1B,
+ CR1D,
+ CR1E,
+ /* SR regs */
+ SR07,
+ SR0E,
+ SR12,
+ SR13,
+ SR1E,
+ /* Must be last! */
+ LG_LAST_REG
+};
+
+#undef FORMAT
+
+typedef struct {
+ unsigned char ExtVga[LG_LAST_REG];
+
+ /* Laguna regs */
+ CARD8 TILE, BCLK;
+ CARD16 FORMAT, DTTC, TileCtrl, CONTROL;
+ CARD32 VSC;
+} LgRegRec, *LgRegPtr;
+
+/* Card-specific driver information */
+#define LGPTR(p) ((LgPtr)((p)->driverPrivate))
+
+typedef struct {
+ ScrnInfoPtr pScrn;
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ EntityInfoPtr pEnt;
+ int Chipset;
+ int ChipRev;
+ int Rounding;
+ int BppShift;
+ Bool HasFBitBlt;
+ CARD32 IOAddress;
+ CARD32 FbAddress;
+ unsigned char * IOBase;
+#ifdef __alpha__
+ unsigned char * IOBaseDense;
+#endif
+ unsigned char * FbBase;
+ long FbMapSize;
+ int MinClock;
+ int MaxClock;
+ Bool NoAccel;
+ Bool HWCursor;
+ Bool UseMMIO;
+ XAAInfoRecPtr AccelInfoRec;
+ xf86CursorInfoPtr CursorInfoRec;
+#if 0
+ DGAInfoPtr DGAInfo;
+#endif
+ I2CBusPtr I2CPtr1;
+ I2CBusPtr I2CPtr2;
+ CloseScreenProcPtr CloseScreen;
+
+/* Difference from Cirrus start here */
+ CARD32 HWCursorAddr;
+ int HWCursorImageX;
+ int HWCursorImageY;
+ int HWCursorTileWidth;
+ int HWCursorTileHeight;
+ Bool CursorIsSkewed;
+
+ int lineDataIndex;
+
+ int memInterleave;
+
+ LgRegRec SavedReg;
+ LgRegRec ModeReg;
+
+ CARD32 oldBitmask;
+ Bool blitTransparent;
+ int blitYDir;
+#if 0
+ CARD32 BltScanDirection;
+ CARD32 FilledRectCMD;
+ CARD32 SolidLineCMD;
+ CARD32 PatternRectCMD;
+ CARD32 AccelFlags;
+#endif
+} LgRec, *LgPtr;
+
+typedef struct {
+ int tilesPerLine; /* Number of tiles per line */
+ int pitch; /* Display pitch, in bytes */
+ int width; /* Tile width. 0 = 128 byte 1 = 256 byte */
+} LgLineDataRec, *LgLineDataPtr;
+
+
+/* lg_driver.c */
+extern LgLineDataRec LgLineData[];
+
+/* cir_driver.c */
+extern SymTabRec CIRChipsets[];
+
+Bool CIRMapMem(ScrnInfoPtr pScrn);
+Bool CIRUnmapMem(ScrnInfoPtr pScrn);
+
+/* CirrusClk.c */
+extern CARD16 CirrusSetClock(ScrnInfoPtr pScrn, int freq);
+
+/* lg_xaa.c */
+extern Bool LgXAAInit(ScreenPtr pScreen);
+
+/* lg_hwcurs.c */
+extern Bool LgHWCursorInit(ScreenPtr pScreen);
+extern void LgHideCursor(ScrnInfoPtr pScrn);
+extern void LgShowCursor(ScrnInfoPtr pScrn);
+
+/* lg_i2c.c */
+extern Bool LGI2CInit(ScreenPtr pScreen);
+
+#endif /* LG_H */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_driver.c
new file mode 100644
index 000000000..95c862162
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_driver.c
@@ -0,0 +1,1795 @@
+/*
+ * Driver for CL-GD546x -- The Laguna family
+ *
+ * lg_driver.c
+ *
+ * (c) 1998 Corin Anderson.
+ * corina@the4cs.com
+ * Tukwila, WA
+ *
+ * This driver is derived from the cir_driver.c module.
+ * Original authors and contributors list include:
+ * Radoslaw Kapitan, Andrew Vanderstock, Dirk Hohndel,
+ * David Dawes, Andrew E. Mileski, Leonard N. Zubkoff,
+ * Guy DESBIEF, Itai Nahshon.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_driver.c,v 1.13 1999/06/13 16:30:37 dawes Exp $ */
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.h"
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+/* All drivers need this */
+#include "xf86_ansic.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* All drivers using the vgahw module need this */
+/* This driver needs to be modified to not use vgaHW for multihead operation */
+#include "vgaHW.h"
+
+#include "xf86RAC.h"
+
+/* All drivers initialising the SW cursor need this */
+#include "mipointer.h"
+
+/* All drivers implementing backing store need this */
+#include "mibstore.h"
+
+#include "micmap.h"
+
+/*
+ * If using cfb, cfb.h is required. Select the others for the bpp values
+ * the driver supports.
+ */
+#if 0
+#include "xf1bpp.h"
+#include "xf4bpp.h"
+#endif
+#define PSZ 8 /* needed for cfb.h */
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb24_32.h"
+#include "cfb32.h"
+
+#include "xf86DDC.h"
+
+/*
+#define LG_DEBUG
+*/
+
+#include "lg.h"
+
+#ifdef XvExtension
+#include "xf86xv.h"
+#include "Xv.h"
+#endif
+
+/*
+ * Forward definitions for the functions that make up the driver.
+ */
+
+/* Mandatory functions */
+Bool LgPreInit(ScrnInfoPtr pScrn, int flags);
+Bool LgScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+Bool LgEnterVT(int scrnIndex, int flags);
+void LgLeaveVT(int scrnIndex, int flags);
+static Bool LgCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool LgSaveScreen(ScreenPtr pScreen, Bool unblank);
+
+/* Required if the driver supports mode switching */
+Bool LgSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+/* Required if the driver supports moving the viewport */
+void LgAdjustFrame(int scrnIndex, int x, int y, int flags);
+
+/* Optional functions */
+void LgFreeScreen(int scrnIndex, int flags);
+int LgValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
+
+/* Internally used functions */
+static void LgRestoreLgRegs(ScrnInfoPtr pScrn, LgRegPtr lgReg);
+static int LgFindLineData(int displayWidth, int bpp);
+
+#ifdef DPMSExtension
+static void LgDisplayPowerManagementSet(ScrnInfoPtr pScrn,
+ int PowerManagementMode,
+ int flags);
+#endif
+
+/*
+ * This is intentionally screen-independent. It indicates the binding
+ * choice made in the first PreInit.
+ */
+static int pix24bpp = 0;
+
+/*
+ * This contains the functions needed by the server after loading the
+ * driver module. It must be supplied, and gets added the driver list by
+ * the Module Setup funtion in the dynamic case. In the static case a
+ * reference to this is compiled in, and this requires that the name of
+ * this DriverRec be an upper-case version of the driver name.
+ */
+
+typedef enum {
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+ OPTION_PCI_RETRY,
+ OPTION_NOACCEL
+} LgOpts;
+
+static OptionInfoRec LgOptions[] = {
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ /* fifo_conservative/aggressive; fast/med/slow_dram; ... */
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+
+/* 1/4bpp 8bpp 15/16bpp 24bpp 32bpp */
+static int gd5462_MaxClocks[] = { 170000, 170000, 135100, 135100, 85500 };
+static int gd5464_MaxClocks[] = { 170000, 250000, 170000, 170000, 135100 };
+static int gd5465_MaxClocks[] = { 170000, 250000, 170000, 170000, 135100 };
+
+LgLineDataRec LgLineData[] = {
+ {5, 640, 0}, /* We're rather use skinny tiles, so put all of */
+ {8, 1024, 0}, /* them at the head of the table */
+ {10, 1280, 0},
+ {13, 1664, 0},
+ {16, 2048, 0},
+ {20, 2560, 0},
+ {10, 2560, 1},
+ {26, 3328, 0},
+ {5, 1280, 1},
+ {8, 2048, 1},
+ {13, 3328, 1},
+ {16, 4096, 1},
+ {20, 5120, 1},
+ {26, 6656, 1},
+ {-1, -1, -1} /* Sentinal to indicate end of table */
+};
+
+static int LgLinePitches[4][11] = {
+ /* 8 */ { 640, 1024, 1280, 1664, 2048, 2560, 3328, 4096, 5120, 6656, 0 },
+ /* 16 */ { 320, 512, 640, 832, 1024, 1280, 1664, 2048, 2560, 3328, 0 },
+ /* 24 */ { 213, 341, 426, 554, 682, 853, 1109, 1365, 1706, 2218, 0 },
+ /* 32 */ { 160, 256, 320, 416, 512, 640, 832, 1024, 1280, 1664, 0 } };
+
+/*
+ * List of symbols from other modules that this module references. This
+ * list is used to tell the loader that it is OK for symbols here to be
+ * unresolved providing that it hasn't been told that they haven't been
+ * told that they are essential via a call to xf86LoaderReqSymbols() or
+ * xf86LoaderReqSymLists(). The purpose is this is to avoid warnings about
+ * unresolved symbols that are not required.
+ */
+
+static const char *vgahwSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWUnlock",
+ "vgaHWInit",
+ "vgaHWProtect",
+ "vgaHWSetMmioFuncs",
+ "vgaHWGetIOBase",
+ "vgaHWMapMem",
+ "vgaHWLock",
+ "vgaHWFreeHWRec",
+ "vgaHWSaveScreen",
+ "vgaHWddc1SetSpeed",
+ NULL
+};
+
+static const char *cfbSymbols[] = {
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb24ScreenInit",
+ "cfb32ScreenInit",
+ "cfb8_32ScreenInit",
+ "cfb24_32ScreenInit",
+ NULL
+};
+
+static const char *xf8_32bppSymbols[] = {
+ "xf86Overlay8Plus32Init",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAADestroyInfoRec",
+ "XAACreateInfoRec",
+ "XAAInit",
+ "XAAStippleScanlineFuncLSBFirst",
+ "XAAOverlayFBfuncs",
+ "XAACachePlanarMonoStipple",
+ "XAAScreenIndex",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86InitCursor",
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ NULL
+};
+
+#define LGuseI2C 0
+
+static const char *ddcSymbols[] = {
+ "xf86PrintEDID",
+ "xf86DoEDID_DDC1",
+#if LGuseI2C
+ "xf86DoEDID_DDC2",
+#endif
+ NULL
+};
+
+static const char *i2cSymbols[] = {
+ "xf86CreateI2CBusRec",
+ "xf86I2CBusInit",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+
+static Bool
+LgGetRec(ScrnInfoPtr pScrn)
+{
+ LgPtr pLg;
+ /*
+ * Allocate a LgRec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(LgRec), 1);
+
+ /* Initialize it */
+ pLg = LGPTR(pScrn);
+ pLg->oldBitmask = 0x00000000;
+
+ return TRUE;
+}
+
+static void
+LgFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+
+
+/*
+ * LgCountRAM --
+ *
+ * Counts amount of installed RAM
+ */
+
+/* XXX We need to get rid of this PIO (MArk) */
+static int
+LgCountRam(ScrnInfoPtr pScrn)
+{
+ CARD8 SR14;
+
+ /* The ROM BIOS scratchpad registers contain,
+ among other things, the amount of installed
+ RDRAM on the laguna chip. */
+ outb(0x3C4, 0x14);
+ SR14 = inb(0x3C5);
+
+ return 1024 * ((SR14&0x7) + 1);
+
+ /* !!! This function seems to be incorrect... */
+}
+
+
+/* Mandatory */
+ Bool
+LgPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ LgPtr pLg;
+ MessageType from;
+ int i;
+ ClockRangePtr clockRanges;
+ char *mod = NULL;
+ int fbPCIReg, ioPCIReg;
+
+#ifdef LG_DEBUG
+ ErrorF("LgPreInit\n");
+#endif
+
+ /*
+ * Note: This function is only called once at server startup, and
+ * not at the start of each server generation. This means that
+ * only things that are persistent across server generations can
+ * be initialised here. xf86Screens[] is (pScrn is a pointer to one
+ * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex()
+ * are too, and should be used for data that must persist across
+ * server generations.
+ *
+ * Per-generation data should be allocated with
+ * AllocateScreenPrivateIndex() from the ScreenInit() function.
+ */
+
+ /* Check the number of entities, and fail if it isn't one. */
+ if (pScrn->numEntities != 1)
+ return FALSE;
+
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /*
+ * Allocate a vgaHWRec
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ /* Allocate the LgRec driverPrivate */
+ if (!LgGetRec(pScrn)) {
+ return FALSE;
+ }
+ pLg = LGPTR(pScrn);
+ pLg->pScrn = pScrn;
+
+ /* Get the entity, and make sure it is PCI. */
+ pLg->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pLg->pEnt->location.type != BUS_PCI)
+ return FALSE;
+
+ /* Find the PCI info for this screen */
+ pLg->PciInfo = xf86GetPciInfoForEntity(pLg->pEnt->index);
+ pLg->PciTag = pciTag(pLg->PciInfo->bus, pLg->PciInfo->device,
+ pLg->PciInfo->func);
+
+ /*
+ * XXX Check which of the VGA resources are decode and/or actually
+ * required in operating mode? For now, assume everything is needed,
+ * so don't call xf86SetOperatingState().
+ */
+ pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+ pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*
+ * The first thing we should figure out is the depth, bpp, etc.
+ * Our default depth is 8, so pass it to the helper function.
+ * We support both 24bpp and 32bpp layouts, so indicate that.
+ */
+ if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb | Support32bppFb |
+ SupportConvert32to24 | PreferConvert32to24)) {
+ return FALSE;
+ } else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 8:
+ case 15:
+ case 16:
+ case 24:
+ case 32:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+ xf86PrintDepthBpp(pScrn);
+
+ /* Get the depth24 pixmap format */
+ if (pScrn->depth == 24 && pix24bpp == 0)
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ /* !!! I think we can force 5-6-5 weight for 16bpp here for
+ the 5462. */
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /* The gamma fields must be initialised when using the new cmap code */
+ if (pScrn->depth > 1) {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros))
+ return FALSE;
+ }
+
+ /* We use a programamble clock */
+ pScrn->progClock = TRUE;
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, LgOptions);
+
+ pScrn->rgbBits = 6; /* ??? What's this? */
+ from = X_DEFAULT;
+ pLg->HWCursor = FALSE;
+ if (xf86GetOptValBool(LgOptions, OPTION_HW_CURSOR, &pLg->HWCursor)) {
+ from = X_CONFIG;
+ }
+ if (xf86ReturnOptValBool(LgOptions, OPTION_SW_CURSOR, FALSE)) {
+ from = X_CONFIG;
+ pLg->HWCursor = FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pLg->HWCursor ? "HW" : "SW");
+ if (xf86ReturnOptValBool(LgOptions, OPTION_NOACCEL, FALSE)) {
+ pLg->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+ if(pScrn->bitsPerPixel < 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Cannot use accelerations in less than 8 bpp\n");
+ pLg->NoAccel = TRUE;
+ }
+
+ /*
+ * Set the Chipset and ChipRev, allowing config file entries to
+ * override.
+ */
+ if (pLg->pEnt->device->chipset && *pLg->pEnt->device->chipset) {
+ pScrn->chipset = pLg->pEnt->device->chipset;
+ pLg->Chipset = xf86StringToToken(CIRChipsets, pScrn->chipset);
+ from = X_CONFIG;
+ } else if (pLg->pEnt->device->chipID >= 0) {
+ pLg->Chipset = pLg->pEnt->device->chipID;
+ pScrn->chipset = (char *)xf86TokenToString(CIRChipsets, pLg->Chipset);
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pLg->Chipset);
+ } else {
+ from = X_PROBED;
+ pLg->Chipset = pLg->PciInfo->chipType;
+ pScrn->chipset = (char *)xf86TokenToString(CIRChipsets, pLg->Chipset);
+ }
+ if (pLg->pEnt->device->chipRev >= 0) {
+ pLg->ChipRev = pLg->pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pLg->ChipRev);
+ } else {
+ pLg->ChipRev = pLg->PciInfo->chipRev;
+ }
+
+ /*
+ * This shouldn't happen because such problems should be caught in
+ * CIRProbe(), but check it just in case.
+ */
+ if (pScrn->chipset == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ChipID 0x%04X is not recognised\n", pLg->Chipset);
+ return FALSE;
+ }
+ if (pLg->Chipset < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Chipset \"%s\" is not recognised\n", pScrn->chipset);
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
+
+ /* Cirrus swapped the FB and IO registers in the 5465 (by design). */
+ if (PCI_CHIP_GD5465 == pLg->Chipset) {
+ fbPCIReg = 0;
+ ioPCIReg = 1;
+ } else {
+ fbPCIReg = 1;
+ ioPCIReg = 0;
+ }
+
+ /* Find the frame buffer base address */
+ if (pLg->pEnt->device->MemBase != 0) {
+ /*
+ * XXX Should check that the config file value matches one of the
+ * PCI base address values.
+ */
+ pLg->FbAddress = pLg->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ if (pLg->PciInfo->memBase[fbPCIReg] != 0) {
+ pLg->FbAddress = pLg->PciInfo->memBase[fbPCIReg] & 0xff000000;
+ from = X_PROBED;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid FB address in PCI config space\n");
+ LgFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pLg->FbAddress);
+
+ /* Find the MMIO base address */
+ if (pLg->pEnt->device->IOBase != 0) {
+ pLg->IOAddress = pLg->pEnt->device->IOBase;
+ from = X_CONFIG;
+ } else {
+ if (pLg->PciInfo->memBase[ioPCIReg] != 0) {
+ pLg->IOAddress = pLg->PciInfo->memBase[ioPCIReg] & 0xfffff000;
+ from = X_PROBED;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid MMIO address in PCI config space\n");
+ }
+ }
+ if(pLg->IOAddress != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
+ (unsigned long)pLg->IOAddress);
+ }
+
+ /* Register the PCI-assigned resources. */
+ if (xf86RegisterResources(pLg->pEnt->index, NULL, ResExclusive)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n");
+ return FALSE;
+ }
+
+ /*
+ * If the user has specified the amount of memory in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pLg->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pLg->pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else {
+ vgaHWProtect(pScrn, TRUE);
+ pScrn->videoRam = LgCountRam(pScrn);
+ vgaHWProtect(pScrn, FALSE);
+ from = X_PROBED;
+ }
+ if (2048 == pScrn->videoRam) {
+ /* Two-way interleaving */
+ pLg->memInterleave = 0x40;
+ } else if (4096 == pScrn->videoRam || 8192 == pScrn->videoRam) {
+ /* Four-way interleaving */
+ pLg->memInterleave = 0x80;
+ } else {
+ /* One-way interleaving */
+ pLg->memInterleave = 0x00;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+
+ pLg->FbMapSize = pScrn->videoRam * 1024;
+
+ /* XXX Set HW cursor use */
+
+ /* Set the min pixel clock */
+ pLg->MinClock = 12000; /* XXX Guess, need to check this */
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
+ pLg->MinClock / 1000);
+ /*
+ * If the user has specified ramdac speed in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pLg->pEnt->device->dacSpeeds[0]) {
+ ErrorF("Do not specify a Clocks line for Cirrus chips\n");
+ return FALSE;
+ } else {
+ int speed;
+ int *p;
+ switch (pLg->Chipset) {
+ case PCI_CHIP_GD5462:
+ p = gd5462_MaxClocks;
+ break;
+ case PCI_CHIP_GD5464:
+ case PCI_CHIP_GD5464BD:
+ p = gd5464_MaxClocks;
+ break;
+ case PCI_CHIP_GD5465:
+ p = gd5465_MaxClocks;
+ break;
+ default:
+ ErrorF("???\n");
+ return FALSE;
+ }
+ switch(pScrn->bitsPerPixel) {
+#if 0
+ case 1:
+ case 4:
+ speed = p[0];
+ break;
+#endif
+ case 8:
+ speed = p[1];
+ break;
+ case 15:
+ case 16:
+ speed = p[2];
+ break;
+ case 24:
+ speed = p[3];
+ break;
+ case 32:
+ speed = p[4];
+ break;
+ default:
+ /* Should not get here */
+ speed = 0;
+ break;
+ }
+ pLg->MaxClock = speed;
+ from = X_PROBED;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
+ pLg->MaxClock / 1000);
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+ clockRanges = xnfalloc(sizeof(ClockRange));
+ clockRanges->next = NULL;
+ clockRanges->minClock = pLg->MinClock;
+ clockRanges->maxClock = pLg->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = FALSE; /* XXX check this */
+ clockRanges->doubleScanAllowed = FALSE; /* XXX check this */
+ clockRanges->doubleScanAllowed = FALSE; /* XXX check this */
+ clockRanges->doubleScanAllowed = FALSE; /* XXX check this */
+ clockRanges->ClockMulFactor = 1;
+ clockRanges->ClockDivFactor = 1;
+ clockRanges->PrivFlags = 0;
+
+ /* Depending upon what sized tiles used, either 128 or 256. */
+ /* Aw, heck. Just say 128. */
+ pLg->Rounding = 128 >> pLg->BppShift;
+
+ /*
+ * xf86ValidateModes will check that the mode HTotal and VTotal values
+ * don't exceed the chipset's limit if pScrn->maxHValue and
+ * pScrn->maxVValue are set. Since our CIRValidMode() already takes
+ * care of this, we don't worry about setting them here.
+ */
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ LgLinePitches[pScrn->bitsPerPixel / 8 - 1],
+ 0, 0, 128 * 8,
+ 0, 0, /* Any virtual height is allowed. */
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pLg->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+
+ pLg->lineDataIndex = LgFindLineData(pScrn->displayWidth,
+ pScrn->bitsPerPixel);
+
+ if (i == -1) {
+ LgFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ LgFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /*
+ * Set the CRTC parameters for all of the modes based on the type
+ * of mode, and the chipset's interlace requirements.
+ *
+ * Calling this is required if the mode->Crtc* values are used by the
+ * driver and if the driver doesn't provide code to set them. They
+ * are not pre-initialised at all.
+ */
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+#if 0
+ case 1: mod = "xf1bpp"; break;
+ case 4: mod = "xf4bpp"; break;
+#endif
+ case 8: mod = "cfb"; break;
+ case 16: mod = "cfb16"; break;
+ case 24: if (pix24bpp == 24)
+ mod = "cfb24";
+ else
+ mod = "xf24_32bpp";
+ break;
+ case 32: mod = "cfb32"; break;
+ }
+ if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ LgFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Load XAA if needed */
+ if (!pLg->NoAccel) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ LgFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ /* Load ramdac if needed */
+ if (pLg->HWCursor) {
+ if (!xf86LoadSubModule(pScrn, "ramdac")) {
+ LgFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+ }
+
+ if (!xf86LoadSubModule(pScrn, "i2c")) {
+ LgFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(i2cSymbols, NULL);
+
+ if (!xf86LoadSubModule(pScrn, "ddc")) {
+ LgFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+
+ return TRUE;
+}
+
+/*
+ * This function saves the video state.
+ */
+static void
+LgSave(ScrnInfoPtr pScrn)
+{
+ LgPtr pLg;
+ vgaHWPtr hwp;
+ CARD8 *p8;
+ CARD16 *p16;
+ CARD32 *p32;
+
+#ifdef LG_DEBUG
+ ErrorF("LgSave\n");
+#endif
+
+ hwp = VGAHWPTR(pScrn);
+ pLg = LGPTR(pScrn);
+
+ vgaHWSave(pScrn, &VGAHWPTR(pScrn)->SavedReg, VGA_SR_ALL);
+
+ outb(hwp->IOBase+4, 0x1A); pLg->ModeReg.ExtVga[CR1A] = pLg->SavedReg.ExtVga[CR1A] = inb(hwp->IOBase + 5);
+ outb(hwp->IOBase+4, 0x1B); pLg->ModeReg.ExtVga[CR1B] = pLg->SavedReg.ExtVga[CR1B] = inb(hwp->IOBase + 5);
+ outb(hwp->IOBase+4, 0x1D); pLg->ModeReg.ExtVga[CR1D] = pLg->SavedReg.ExtVga[CR1D] = inb(hwp->IOBase + 5);
+ outb(hwp->IOBase+4, 0x1E); pLg->ModeReg.ExtVga[CR1E] = pLg->SavedReg.ExtVga[CR1E] = inb(hwp->IOBase + 5);
+ outb(0x3C4, 0x07); pLg->ModeReg.ExtVga[SR07] = pLg->SavedReg.ExtVga[SR07] = inb(0x3C5);
+ outb(0x3C4, 0x0E); pLg->ModeReg.ExtVga[SR0E] = pLg->SavedReg.ExtVga[SR0E] = inb(0x3C5);
+ outb(0x3C4, 0x12); pLg->ModeReg.ExtVga[SR12] = pLg->SavedReg.ExtVga[SR12] = inb(0x3C5);
+ outb(0x3C4, 0x13); pLg->ModeReg.ExtVga[SR13] = pLg->SavedReg.ExtVga[SR13] = inb(0x3C5);
+ outb(0x3C4, 0x1E); pLg->ModeReg.ExtVga[SR1E] = pLg->SavedReg.ExtVga[SR1E] = inb(0x3C5);
+
+ p16 = (CARD16 *)(pLg->IOBase + 0xC0);
+ pLg->ModeReg.FORMAT = pLg->SavedReg.FORMAT = *p16;
+
+ p32 = (CARD32 *)(pLg->IOBase + 0x3FC);
+ pLg->ModeReg.VSC = pLg->SavedReg.VSC = *p32;
+
+ p16 = (CARD16 *)(pLg->IOBase + 0xEA);
+ pLg->ModeReg.DTTC = pLg->SavedReg.DTTC = *p16;
+
+ if (pLg->Chipset == PCI_CHIP_GD5465) {
+ p16 = (CARD16 *)(pLg->IOBase + 0x2C4);
+ pLg->ModeReg.TileCtrl = pLg->SavedReg.TileCtrl = *p16;
+ }
+
+ p8 = (CARD8 *)(pLg->IOBase + 0x407);
+ pLg->ModeReg.TILE = pLg->SavedReg.TILE = *p8;
+
+ if (pLg->Chipset == PCI_CHIP_GD5465)
+ p8 = (CARD8 *)(pLg->IOBase + 0x2C0);
+ else
+ p8 = (CARD8 *)(pLg->IOBase + 0x8C);
+ pLg->ModeReg.BCLK = pLg->SavedReg.BCLK = *p8;
+
+ p16 = (CARD16 *)(pLg->IOBase + 0x402);
+ pLg->ModeReg.CONTROL = pLg->SavedReg.CONTROL = *p16;
+}
+
+/*
+ * Initialise a new mode. This is currently still using the old
+ * "initialise struct, restore/write struct to HW" model. That could
+ * be changed.
+ */
+
+static Bool
+LgModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp;
+ vgaRegPtr vgaReg;
+ LgPtr pLg;
+ int width;
+ Bool VDiv2 = FALSE;
+ CARD16 clockData;
+ LgLineDataPtr lineData;
+
+#ifdef LG_DEBUG
+ ErrorF("LgModeInit %d bpp, %d %d %d %d %d %d %d %d %d\n",
+ pScrn->bitsPerPixel,
+ mode->Clock,
+ mode->HDisplay,
+ mode->HSyncStart,
+ mode->HSyncEnd,
+ mode->HTotal,
+ mode->VDisplay,
+ mode->VSyncStart,
+ mode->VSyncEnd,
+ mode->VTotal);
+
+ ErrorF("LgModeInit: depth %d bits\n", pScrn->depth);
+#endif
+
+ pLg = LGPTR(pScrn);
+ hwp = VGAHWPTR(pScrn);
+ vgaHWUnlock(hwp);
+
+ if (mode->VTotal >= 1024 && !(mode->Flags & V_INTERLACE)) {
+ /* For non-interlaced vertical timing >= 1024, the vertical timings */
+ /* are divided by 2 and VGA CRTC 0x17 bit 2 is set. */
+ if (!mode->CrtcVAdjusted) {
+ mode->CrtcVDisplay >>= 1;
+ mode->CrtcVSyncStart >>= 1;
+ mode->CrtcVSyncEnd >>= 1;
+ mode->CrtcVTotal >>= 1;
+ mode->CrtcVAdjusted = TRUE;
+ }
+ VDiv2 = TRUE;
+ }
+
+ /* Initialise the ModeReg values */
+ if (!vgaHWInit(pScrn, mode))
+ return FALSE;
+ pScrn->vtSema = TRUE;
+
+ /* Program the registers */
+ vgaHWProtect(pScrn, TRUE);
+
+ if(VDiv2)
+ hwp->ModeReg.CRTC[0x17] |= 0x04;
+
+#ifdef LG_DEBUG
+ ErrorF("SynthClock = %d\n", mode->SynthClock);
+#endif
+ clockData = CirrusSetClock(pScrn, mode->SynthClock);
+ pLg->ModeReg.ExtVga[SR0E] = (clockData >> 8) & 0xFF;
+ pLg->ModeReg.ExtVga[SR1E] = clockData & 0xFF;
+
+ vgaReg = &hwp->ModeReg;
+
+ if(pScrn->bitsPerPixel == 1) {
+ hwp->IOBase = 0x3B0;
+ hwp->ModeReg.MiscOutReg &= ~0x01;
+ }
+ else {
+ hwp->IOBase = 0x3D0;
+ hwp->ModeReg.MiscOutReg |= 0x01;
+ }
+
+ outb(0x3C2, hwp->ModeReg.MiscOutReg);
+
+ /* ??? Should these be both ...End or ...Start, not one of each? */
+ pLg->ModeReg.ExtVga[CR1A] = (((mode->CrtcVSyncStart + 1) & 0x300 ) >> 2)
+ | (((mode->CrtcHSyncEnd >> 3) & 0xC0) >> 2);
+
+ width = pScrn->displayWidth * pScrn->bitsPerPixel / 8;
+ if(pScrn->bitsPerPixel == 1)
+ width <<= 2;
+ hwp->ModeReg.CRTC[0x13] = (width + 7) >> 3;
+ /* Offset extension (see CR13) */
+ pLg->ModeReg.ExtVga[CR1B] &= 0xEF;
+ pLg->ModeReg.ExtVga[CR1B] |= (((width + 7) >> 3) & 0x100)?0x10:0x00;
+ pLg->ModeReg.ExtVga[CR1B] |= 0x22;
+ pLg->ModeReg.ExtVga[CR1D] = (((width + 7) >> 3) & 0x200)?0x01:0x00;
+
+ /* Set the 28th bit to enable extended modes. */
+ pLg->ModeReg.VSC = 0x10000000;
+
+ /* Overflow register (sure are a lot of overflow bits around...) */
+ pLg->ModeReg.ExtVga[CR1E] = 0x00;
+ pLg->ModeReg.ExtVga[CR1E] |= ((mode->CrtcHTotal>>3 & 0x0100)?1:0)<<7;
+ pLg->ModeReg.ExtVga[CR1E] |= ((mode->CrtcHDisplay>>3 & 0x0100)?1:0)<<6;
+ pLg->ModeReg.ExtVga[CR1E] |= ((mode->CrtcHSyncStart>>3 & 0x0100)?1:0)<<5;
+ pLg->ModeReg.ExtVga[CR1E] |= ((mode->CrtcHSyncStart>>3 & 0x0100)?1:0)<<4;
+ pLg->ModeReg.ExtVga[CR1E] |= ((mode->CrtcVTotal & 0x0400)?1:0)<<3;
+ pLg->ModeReg.ExtVga[CR1E] |= ((mode->CrtcVDisplay & 0x0400)?1:0)<<2;
+ pLg->ModeReg.ExtVga[CR1E] |= ((mode->CrtcVSyncStart & 0x0400)?1:0)<<1;
+ pLg->ModeReg.ExtVga[CR1E] |= ((mode->CrtcVSyncStart & 0x0400)?1:0)<<0;
+
+ lineData = &LgLineData[pLg->lineDataIndex];
+
+ pLg->ModeReg.TILE = lineData->tilesPerLine & 0x3F;
+
+ if (8 == pScrn->bitsPerPixel) {
+ pLg->ModeReg.FORMAT = 0x0000;
+
+ pLg->ModeReg.DTTC = (pLg->ModeReg.TILE << 8) | 0x0080 |
+ (lineData->width << 6);
+ pLg->ModeReg.CONTROL = 0x0000 | (lineData->width << 11);
+
+
+ /* There is an optimal FIFO threshold value (lower 5 bits of DTTC)
+ for every resolution and color depth combination. We'll hit
+ the highlights here, and get close for anything that's not
+ covered. */
+ if (mode->CrtcHDisplay <= 640) {
+ /* BAD numbers: 0x1E */
+ /* GOOD numbers: 0x14 */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x0014);
+ } else if (mode->CrtcHDisplay <= 800) {
+ /* BAD numbers: 0x16 */
+ /* GOOD numbers: 0x13 0x14 */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x0014);
+ } else if (mode->CrtcHDisplay <= 1024) {
+ /* BAD numbers: */
+ /* GOOD numbers: 0x15 */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x0015);
+ } else if (mode->CrtcHDisplay <= 1280) {
+ /* BAD numbers: */
+ /* GOOD numbers: 0x16 */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x0016);
+ } else {
+ /* BAD numbers: */
+ /* GOOD numbers: */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x0017);
+ }
+
+ } else if (16 == pScrn->bitsPerPixel) {
+
+ /* !!! Assume 5-6-5 RGB mode (for now...) */
+ pLg->ModeReg.FORMAT = 0x1400;
+
+ if(pScrn->depth == 15)
+ pLg->ModeReg.FORMAT = 0x1600;
+
+ pLg->ModeReg.DTTC = (pLg->ModeReg.TILE << 8) | 0x0080 |
+ (lineData->width << 6);
+ pLg->ModeReg.CONTROL = 0x2000 | (lineData->width << 11);
+
+ if (mode->CrtcHDisplay <= 640) {
+ /* BAD numbers: 0x12 */
+ /* GOOD numbers: 0x10 */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x0010);
+ } else if (mode->CrtcHDisplay <= 800) {
+ /* BAD numbers: 0x13 */
+ /* GOOD numbers: 0x11 */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x0011);
+ } else if (mode->CrtcHDisplay <= 1024) {
+ /* BAD numbers: 0x14 */
+ /* GOOD numbers: 0x12 */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x0012);
+ } else if (mode->CrtcHDisplay <= 1280) {
+ /* BAD numbers: 0x08 0x10 */
+ /* Borderline numbers: 0x12 */
+ /* GOOD numbers: 0x15 */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x0015);
+ } else {
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x0017);
+ }
+
+ } else if (24 == pScrn->bitsPerPixel) {
+
+ pLg->ModeReg.FORMAT = 0x2400;
+
+ pLg->ModeReg.DTTC = (pLg->ModeReg.TILE << 8) | 0x0080 |
+ (lineData->width << 6);
+ pLg->ModeReg.CONTROL = 0x4000 | (lineData->width << 11);
+
+
+ if (mode->CrtcHDisplay <= 640) {
+ /* BAD numbers: */
+ /* GOOD numbers: 0x10 */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x0010);
+ } else if (mode->CrtcHDisplay <= 800) {
+ /* BAD numbers: */
+ /* GOOD numbers: 0x11 */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x0011);
+ } else if (mode->CrtcHDisplay <= 1024) {
+ /* BAD numbers: 0x12 0x13 */
+ /* Borderline numbers: 0x15 */
+ /* GOOD numbers: 0x17 */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x0017);
+ } else if (mode->CrtcHDisplay <= 1280) {
+ /* BAD numbers: */
+ /* GOOD numbers: 0x1E */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x001E);
+ } else {
+ /* BAD numbers: */
+ /* GOOD numbers: */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x0020);
+ }
+
+ } else if (32 == pScrn->bitsPerPixel) {
+
+ pLg->ModeReg.FORMAT = 0x3400;
+
+ pLg->ModeReg.DTTC = (pLg->ModeReg.TILE << 8) | 0x0080 |
+ (lineData->width << 6);
+ pLg->ModeReg.CONTROL = 0x6000 | (lineData->width << 11);
+
+
+ if (mode->CrtcHDisplay <= 640) {
+ /* GOOD numbers: 0x0E */
+ /* BAD numbers: */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x000E);
+ } else if (mode->CrtcHDisplay <= 800) {
+ /* GOOD numbers: 0x17 */
+ /* BAD numbers: */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x0017);
+ } else if (mode->CrtcHDisplay <= 1024) {
+ /* GOOD numbers: 0x1D */
+ /* OKAY numbers: 0x15 0x14 0x16 0x18 0x19 */
+ /* BAD numbers: 0x0E 0x12 0x13 0x0D */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x001D);
+ } else if (mode->CrtcHDisplay <= 1280) {
+ /* GOOD numbers: */
+ /* BAD numbers: */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x0022); /* 10 */
+ } else {
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xFFE0) | (0x0024);
+ }
+ } else {
+ /* ??? What could it be? Use some sane numbers. */
+ }
+
+ /* Setup the appropriate memory interleaving */
+ pLg->ModeReg.DTTC |= (pLg->memInterleave << 8);
+ pLg->ModeReg.TILE |= pLg->memInterleave & 0xC0;
+
+ if (PCI_CHIP_GD5465 == pLg->Chipset) {
+ /* The tile control information in the DTTC is also mirrored
+ elsewhere. */
+ pLg->ModeReg.TileCtrl = pLg->ModeReg.DTTC & 0xFFC0;
+
+ /* The 5465's DTTC records _fetches_ per line, not
+ tiles per line. Fetchs are 128-byte fetches. */
+ if (pLg->ModeReg.DTTC & 0x0040) {
+ /* Using 256-byte wide tiles. Double the fetches
+ per line field. */
+ pLg->ModeReg.DTTC = (pLg->ModeReg.DTTC & 0xC0FF) |
+ ((pLg->ModeReg.DTTC & 0x3F00) << 1);
+ }
+ }
+
+ /* Write those registers out to the card. */
+ LgRestoreLgRegs(pScrn, &pLg->ModeReg);
+
+ /* Programme the registers */
+ vgaHWRestore(pScrn, &hwp->ModeReg, VGA_SR_MODE | VGA_SR_CMAP);
+
+ vgaHWProtect(pScrn, FALSE);
+
+ return TRUE;
+}
+
+static int LgFindLineData(int displayWidth, int bpp) {
+ /* Find the smallest tile-line-pitch such that the total byte pitch
+ is greater than or equal to displayWidth*Bpp. */
+ int i;
+
+ /* Some pitch sizes are duplicates in the table. BUT, the invariant is
+ that the _first_ time a pitch occurs in the table is always _before_
+ all other pitches greater than it. Said in another way... if all
+ duplicate entries from the table were removed, then the resulting pitch
+ values are strictly increasing. */
+
+ for (i = 0; LgLineData[i].pitch > 0; i++)
+ if (LgLineData[i].pitch >= displayWidth*bpp>>3) {
+ return i;
+ }
+
+ /* Um, uh oh! */
+ return -1;
+}
+
+
+
+
+static void
+LgRestoreLgRegs(ScrnInfoPtr pScrn, LgRegPtr lgReg) {
+ CARD8 *p8;
+ CARD16 *p16;
+ CARD32 *p32;
+ LgPtr pLg;
+ vgaHWPtr hwp;
+ CARD8 cr1D;
+
+ pLg = LGPTR(pScrn);
+
+ /* First, VGAish registers. */
+ hwp = VGAHWPTR(pScrn);
+ outw(hwp->IOBase + 4, (lgReg->ExtVga[CR1A] << 8) | 0x1A);
+ outw(hwp->IOBase + 4, (lgReg->ExtVga[CR1B] << 8) | 0x1B);
+ outb(hwp->IOBase+4, 0x1D);
+ cr1D = inb(hwp->IOBase + 5);
+ cr1D &= ~(0x01);
+ cr1D |= (lgReg->ExtVga[CR1D] & 0x01);
+ outw(hwp->IOBase + 4, (cr1D << 8) | 0x1D);
+ outw(hwp->IOBase + 4, (lgReg->ExtVga[CR1E] << 8) | 0x1E);
+ outw(0x3C4, (lgReg->ExtVga[SR07] << 8) | 0x07);
+ outw(0x3C4, (lgReg->ExtVga[SR0E] << 8) | 0x0E);
+ outw(0x3C4, (lgReg->ExtVga[SR12] << 8) | 0x12);
+ outw(0x3C4, (lgReg->ExtVga[SR13] << 8) | 0x13);
+ outw(0x3C4, (lgReg->ExtVga[SR1E] << 8) | 0x1E);
+
+ p16 = (CARD16 *)(pLg->IOBase + 0xC0);
+ *p16 = lgReg->FORMAT;
+
+ /* Vendor Specific Control is touchy. Only bit 28 is of concern. */
+ p32 = (CARD32 *)(pLg->IOBase + 0x3FC);
+ *p32 = (*p32 & ~(1<<28)) | (lgReg->VSC & (1<<28));
+
+ p16 = (CARD16 *)(pLg->IOBase + 0xEA);
+ *p16 = lgReg->DTTC;
+
+ if (pLg->Chipset == PCI_CHIP_GD5465) {
+ p16 = (CARD16 *)(pLg->IOBase + 0x2C4);
+ *p16 = lgReg->TileCtrl;
+ }
+
+ p8 = (CARD8 *)(pLg->IOBase + 0x407);
+ *p8 = lgReg->TILE;
+
+ if (pLg->Chipset == PCI_CHIP_GD5465)
+ p8 = (CARD8 *)(pLg->IOBase + 0x2C0);
+ else
+ p8 = (CARD8 *)(pLg->IOBase + 0x8C);
+ *p8 = lgReg->BCLK;
+
+ p16 = (CARD16 *)(pLg->IOBase + 0x402);
+ *p16 = lgReg->CONTROL;
+}
+
+/*
+ * Restore the initial (text) mode.
+ */
+static void
+LgRestore(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp;
+ vgaRegPtr vgaReg;
+ LgPtr pLg;
+ LgRegPtr lgReg;
+
+#ifdef LG_DEBUG
+ ErrorF("LgRestore pScrn = 0x%08X\n", pScrn);
+#endif
+
+ pLg = LGPTR(pScrn);
+ hwp = VGAHWPTR(pScrn);
+ vgaReg = &hwp->SavedReg;
+ lgReg = &pLg->SavedReg;
+
+ vgaHWProtect(pScrn, TRUE);
+
+ LgRestoreLgRegs(pScrn, lgReg);
+
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+ vgaHWProtect(pScrn, FALSE);
+}
+
+/* Mandatory */
+
+/* This gets called at the start of each server generation */
+
+Bool
+LgScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ /* The vgaHW references will disappear one day */
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ LgPtr pLg;
+ int i, ret;
+ VisualPtr visual;
+
+#ifdef LG_DEBUG
+ ErrorF("LgScreenInit\n");
+#endif
+
+ /*
+ * First get the ScrnInfoRec
+ */
+ pScrn = xf86Screens[pScreen->myNum];
+
+ hwp = VGAHWPTR(pScrn);
+
+ hwp->MapSize = 0x10000; /* Standard 64k VGA window */
+
+ pLg = LGPTR(pScrn);
+
+ /* Map the VGA memory and get the VGA IO base */
+ if (!vgaHWMapMem(pScrn))
+ return FALSE;
+
+ vgaHWGetIOBase(hwp);
+
+ /* Map the CIR memory and MMIO areas */
+ if (!CIRMapMem(pScrn))
+ return FALSE;
+
+ /* Save the current state */
+ LgSave(pScrn);
+
+ /* Initialise the first mode */
+ if (!LgModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ /* Set the viewport */
+ LgAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset the visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ /*
+ * For bpp > 8, the default visuals are not acceptable because we only
+ * support TrueColor and not DirectColor. To deal with this, call
+ * miSetVisualTypes with the appropriate visual mask.
+ */
+#ifdef LG_DEBUG
+ ErrorF("LgScreenInit before miSetVisualTypes\n");
+#endif
+ if (pScrn->bitsPerPixel > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
+ pScrn->defaultVisual))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+#ifdef LG_DEBUG
+ ErrorF("LgScreenInit after miSetVisualTypes\n");
+#endif
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+
+ switch (pScrn->bitsPerPixel) {
+#if 0
+ case 1:
+ ret = xf1bppScreenInit(pScreen, pLg->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 4:
+ ret = xf4bppScreenInit(pScreen, pLg->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+#endif
+ case 8:
+ ret = cfbScreenInit(pScreen, pLg->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 16:
+ ret = cfb16ScreenInit(pScreen, pLg->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 24:
+ if (pix24bpp == 24)
+ ret = cfb24ScreenInit(pScreen, pLg->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ else
+ ret = cfb24_32ScreenInit(pScreen, pLg->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 32:
+ ret = cfb32ScreenInit(pScreen, pLg->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "X11: Internal error: invalid bpp (%d) in LgScreenInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ if (!ret)
+ return FALSE;
+
+#ifdef LG_DEBUG
+ ErrorF("LgScreenInit after depth dependent init\n");
+#endif
+
+ /* Override the default mask/offset settings */
+ if (pScrn->bitsPerPixel > 8) {
+ for (i = 0; i < pScreen->numVisuals; i++) {
+ visual = &pScreen->visuals[i];
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ miInitializeBackingStore(pScreen);
+
+ /*
+ * Set initial black & white colourmap indices.
+ */
+ xf86SetBlackWhitePixels(pScreen);
+
+ if(!pLg->NoAccel) { /* Initialize XAA functions */
+ if(!LgXAAInit(pScreen))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not initialize XAA\n");
+ }
+
+ /* Initialise cursor functions */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ if (pLg->HWCursor) { /* Initialize HW cursor layer */
+ if(!LgHWCursorInit(pScreen))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ }
+
+ if(!LGI2CInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "I2C initialization failed\n");
+ }
+ else
+ xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,pLg->I2CPtr1));
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ if (pScrn->bitsPerPixel > 1 &&
+ pScrn->bitsPerPixel <= 8)
+ vgaHWHandleColormaps(pScreen);
+
+#ifdef DPMSExtension
+ xf86DPMSInit(pScreen, LgDisplayPowerManagementSet, 0);
+#endif
+
+ pScrn->memPhysBase = pLg->FbAddress;
+ pScrn->fbOffset = 0;
+
+#ifdef XvExtension
+ {
+ XF86VideoAdaptorPtr *ptr;
+ int n;
+
+ n = xf86XVListGenericAdaptors(&ptr);
+ if (n) {
+ xf86XVScreenInit(pScreen, ptr, n);
+ }
+ }
+#endif
+
+ /*
+ * Wrap the CloseScreen vector and set SaveScreen.
+ */
+ pScreen->SaveScreen = LgSaveScreen;
+ pLg->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = LgCloseScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ /* Done */
+ return TRUE;
+}
+
+
+/* Usually mandatory */
+Bool
+LgSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return LgModeInit(xf86Screens[scrnIndex], mode);
+}
+
+#define ROUND_DOWN(x, mod) (((x) / (mod)) * (mod))
+#define ROUND_UP(x, mod) ((((x) + (mod) - 1) / (mod)) * (mod))
+
+/*
+ * This function is used to initialize the Start Address - the first
+ * displayed location in the video memory.
+ */
+/* Usually mandatory */
+void
+LgAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ int Base, tmp;
+ LgPtr pLg = LGPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ int cursorX, cursorY;
+ int middleX, middleY;
+ const LgLineDataPtr lineData = &LgLineData[pLg->lineDataIndex];
+ const int viewportXRes =
+ (PCI_CHIP_GD5465 == pLg->Chipset) ? (24==pScrn->bitsPerPixel?24:1) :
+ (lineData->width?256:128) /
+ (24==pScrn->bitsPerPixel?1:(pScrn->bitsPerPixel>>3));
+ const int viewportYRes =
+ (PCI_CHIP_GD5465 == pLg->Chipset) ? 1 : (24==pScrn->bitsPerPixel?3:1);
+
+ /* Where's the pointer? */
+ miPointerPosition(&cursorX, &cursorY);
+
+ /* Where's the middle of the screen? We want to eventually know
+ which side of the screen the pointer is on. */
+ middleX = (pScrn->frameX1 + pScrn->frameX0) / 2;
+ middleY = (pScrn->frameY1 + pScrn->frameY0) / 2;
+
+ if (cursorX < middleX) {
+ /* Pointer is on left side of screen. Round the frame value
+ down. */
+ pScrn->frameX0 = ROUND_DOWN(pScrn->frameX0, viewportXRes);
+ } else {
+ /* Pointer is on right side of screen. Round the frame value
+ up. A side effect of this rounding up is that we might expose
+ a part of the screen that's actually on the far /left/ of the
+ frame buffer. That's because, although the virtual desktop might
+ be an integral number of tiles, the display might not. We'll
+ just live with this artifact. */
+ pScrn->frameX0 = ROUND_UP(pScrn->frameX0, viewportXRes);
+ }
+ pScrn->frameX1 = pScrn->frameX0 + pScrn->currentMode->HDisplay - 1;
+
+ if (cursorY < middleY) {
+ pScrn->frameY0 = ROUND_DOWN(pScrn->frameY0, viewportYRes);
+ } else {
+ pScrn->frameY0 = ROUND_UP(pScrn->frameY0, viewportYRes);
+ }
+ pScrn->frameY1 = pScrn->frameY0 + pScrn->currentMode->VDisplay - 1;
+
+
+ if (x != pScrn->frameX0 || y != pScrn->frameY0) {
+ /* !!! */
+ /* We moved the frame from where xf86SetViewport() placed it.
+ If we're using a SW cursor, that's okay -- the pointer exists in
+ the framebuffer, and those bits are still all aligned. But
+ if we're using a HW cursor, then we need to re-align the pointer.
+ Call SetCursorPosition() with the appropriate new pointer
+ values, adjusted to be wrt the new frame. */
+
+ x = pScrn->frameX0;
+ y = pScrn->frameY0;
+ }
+
+ /* ??? Will this work for 1bpp? */
+ Base = (y * lineData->pitch + (x*pScrn->bitsPerPixel/8)) / 4;
+
+ if ((Base & ~0x000FFFFF) != 0) {
+ /* ??? */
+ ErrorF("X11: Internal error: LgAdjustFrame: cannot handle overflow\n");
+ return;
+ }
+
+ outw(hwp->IOBase + 4, (Base & 0x00FF00) | 0x0C);
+ outw(hwp->IOBase + 4, ((Base & 0x0000FF) << 8) | 0x0D);
+ outb(hwp->IOBase + 4, 0x1B);
+ tmp = inb(hwp->IOBase + 5);
+ tmp &= 0xF2;
+ tmp |= (Base >> 16) & 0x01;
+ tmp |= (Base >> 15) & 0x0C;
+ outb(hwp->IOBase + 5, tmp);
+ outb(hwp->IOBase + 4, 0x1D);
+ tmp = inb(hwp->IOBase + 5);
+ tmp &= 0xE7;
+ tmp |= (Base >> 16) & 0x18;
+ outb(hwp->IOBase + 5, tmp);
+}
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ *
+ * We may wish to unmap video/MMIO memory too.
+ */
+
+/* Mandatory */
+Bool
+LgEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ LgPtr pLg = LGPTR(pScrn);
+#ifdef LG_DEBUG
+ ErrorF("LgEnterVT\n");
+#endif
+
+ /* XXX Shouldn't this be in LeaveVT? */
+ /* Disable HW cursor */
+ if (pLg->HWCursor)
+ LgHideCursor(pScrn);
+
+ /* Should we re-save the text mode on each VT enter? */
+ return LgModeInit(pScrn, pScrn->currentMode);
+}
+
+
+/*
+ * This is called when VT switching away from the X server. Its job is
+ * to restore the previous (text) mode.
+ *
+ * We may wish to remap video/MMIO memory too.
+ */
+
+/* Mandatory */
+void
+LgLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ LgPtr pLg = LGPTR(pScrn);
+#ifdef LG_DEBUG
+ ErrorF("LgLeaveVT\n");
+#endif
+
+ /* XXX Shouldn't this be in EnterVT? */
+ /* Enable HW cursor */
+ if (pLg->HWCursor)
+ LgShowCursor(pScrn);
+
+ LgRestore(pScrn);
+ vgaHWLock(hwp);
+}
+
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode. It should also unmap the video memory, and free
+ * any per-generation data allocated by the driver. It should finish
+ * by unwrapping and calling the saved CloseScreen function.
+ */
+
+/* Mandatory */
+static Bool
+LgCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ LgPtr pLg = LGPTR(pScrn);
+
+ LgRestore(pScrn);
+
+ if (pLg->HWCursor)
+ LgHideCursor(pScrn);
+
+ vgaHWLock(hwp);
+
+ CIRUnmapMem(pScrn);
+
+ if (pLg->AccelInfoRec)
+ XAADestroyInfoRec(pLg->AccelInfoRec);
+ pLg->AccelInfoRec = NULL;
+
+ if (pLg->CursorInfoRec)
+ xf86DestroyCursorInfoRec(pLg->CursorInfoRec);
+ pLg->CursorInfoRec = NULL;
+
+ pScrn->vtSema = FALSE;
+
+ pScreen->CloseScreen = pLg->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+
+/* Free up any persistent data structures */
+
+/* Optional */
+void
+LgFreeScreen(int scrnIndex, int flags)
+{
+#ifdef LG_DEBUG
+ ErrorF("LgFreeScreen\n");
+#endif
+ /*
+ * This only gets called when a screen is being deleted. It does not
+ * get called routinely at the end of a server generation.
+ */
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ LgFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+/* Optional */
+int
+LgValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ int lace;
+
+ lace = 1 + ((mode->Flags & V_INTERLACE) != 0);
+
+ if ((mode->CrtcHDisplay <= 2048) &&
+ (mode->CrtcHSyncStart <= 4096) &&
+ (mode->CrtcHSyncEnd <= 4096) &&
+ (mode->CrtcHTotal <= 4096) &&
+ (mode->CrtcVDisplay <= 2048 * lace) &&
+ (mode->CrtcVSyncStart <= 4096 * lace) &&
+ (mode->CrtcVSyncEnd <= 4096 * lace) &&
+ (mode->CrtcVTotal <= 4096 * lace)) {
+ return(MODE_OK);
+ } else {
+ return(MODE_BAD);
+ }
+}
+
+
+/* Do screen blanking */
+
+/* Mandatory */
+static Bool
+LgSaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+ volatile unsigned char *p;
+
+ p = LGPTR(xf86Screens[pScreen->myNum])->IOBase+0xB0;
+ if(unblank)
+ /* Power up the palette DAC */
+ *p &= 0x7F;
+ else
+ /* Power down the palette DAC */
+ *p |= 0x80;
+
+ return vgaHWSaveScreen(pScreen, unblank);
+}
+
+/*
+ * CIRDisplayPowerManagementSet --
+ *
+ * Sets VESA Display Power Management Signaling (DPMS) Mode.
+ */
+#ifdef DPMSExtension
+static void
+LgDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
+ int flags)
+{
+ unsigned char sr01, cr1a;
+ vgaHWPtr hwp;
+
+#ifdef CIR_DEBUG
+ ErrorF("LgDisplayPowerManagementSet\n");
+#endif
+
+ hwp = VGAHWPTR(pScrn);
+
+#ifdef CIR_DEBUG
+ ErrorF("LgDisplayPowerManagementSet: %d\n", PowerManagementMode);
+#endif
+
+ switch (PowerManagementMode)
+ {
+ case DPMSModeOn:
+ /* Screen: On; HSync: On, VSync: On */
+ sr01 = 0x00;
+ cr1a = 0x00;
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off; HSync: Off, VSync: On */
+ sr01 = 0x20;
+ cr1a = 0x08;
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off; HSync: On, VSync: Off */
+ sr01 = 0x20;
+ cr1a = 0x04;
+ break;
+ case DPMSModeOff:
+ /* Screen: Off; HSync: Off, VSync: Off */
+ sr01 = 0x20;
+ cr1a = 0x0c;
+ break;
+ default:
+ return;
+ }
+
+#if 0
+ sr01 |= hwp->readSeq(hwp, 0x01) & ~0x20;
+ hwp->writeSeq(hwp, 0x01, sr01);
+ cr1a |= hwp->readCrtc(hwp, 0x1A) & ~0x0C;
+ hwp->writeCrtc(hwp, 0x1A, cr1a);
+#else
+ outb(0x3c4, 0x01);
+ sr01 |= inb(0x3c5) & ~0x20;
+ outb(0x3C5, sr01);
+ outb(hwp->IOBase + 4, 0x1A);
+ cr1a |= inb(hwp->IOBase + 5) & ~0x0C;
+ outb(hwp->IOBase + 5, cr1a);
+#endif
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_hwcurs.c b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_hwcurs.c
new file mode 100644
index 000000000..a2c425285
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_hwcurs.c
@@ -0,0 +1,392 @@
+/*
+ * Hardware cursor support for CL-GD546x -- The Laugna family
+ *
+ * lg_hwcurs.c
+ *
+ * (c) 1998 Corin Anderson.
+ * corina@the4cs.com
+ * Tukwila, WA
+ *
+ * Much of this code is inspired by the HW cursor code from XFree86
+ * 3.3.3.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_hwcurs.c,v 1.1 1998/11/22 10:37:20 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+#include "vgaHW.h"
+
+#include "lg.h"
+#include "lg_xaa.h" /* For BitBLT engine macros */
+
+/*
+#define LG_CURSOR_DEBUG
+*/
+
+#define CURSORWIDTH 64
+#define CURSORHEIGHT 64
+#define CURSORSIZE (CURSORWIDTH*CURSORHEIGHT/8)
+
+/* Some registers used for the HW cursor. */
+enum {
+ PALETTE_READ_ADDR = 0x00A4,
+ PALETTE_WRITE_ADDR = 0x00A8,
+ PALETTE_DATA = 0x00AC,
+
+ PALETTE_STATE = 0x00B0,
+ CURSOR_X_POS = 0x00E0,
+ CURSOR_Y_POS = 0x00E2,
+ CURSOR_PRESET = 0x00E4,
+ MISC_CONTROL = 0x00E6,
+ CURSOR_ADDR = 0x00E8
+};
+
+
+static void
+LgFindCursorTile(ScrnInfoPtr pScrn, int *x, int *y, int *width, int *height,
+ CARD32 *curAddr);
+
+
+/*
+ * Set the FG and BG colors of the HW cursor.
+ */
+static void LgSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) {
+ LgPtr pLg = LGPTR(pScrn);
+
+ volatile CARD8 *pPaletteState = (CARD8 *)(pLg->IOBase + PALETTE_STATE);
+ volatile CARD8 *pPaletteAddr = (CARD8 *)(pLg->IOBase + PALETTE_WRITE_ADDR);
+ volatile CARD8 *pPaletteData = (CARD8 *)(pLg->IOBase + PALETTE_DATA);
+
+
+
+#ifdef LG_CURSOR_DEBUG
+ ErrorF("LgSetCursorColors\n");
+#endif
+
+ /* Enable access to cursor colors in palette */
+ *pPaletteState |= (1<<3);
+
+ /* Slam in the color */
+ *pPaletteAddr = 0x00;
+ *pPaletteData = (bg >> 16); /* The 5446 & 5480 code shifted an extra 2 */
+ *pPaletteData = (bg >> 8); /* positions right, and masked everything */
+ *pPaletteData = (bg >> 0); /* with 0x3F. Why? */
+ *pPaletteAddr = 0x0F;
+ *pPaletteData = (fg >> 16);
+ *pPaletteData = (fg >> 8);
+ *pPaletteData = (fg >> 0);
+
+ /* Disable access to cursor colors */
+ *pPaletteState &= ~(1<<3);
+}
+
+
+/*
+ * Set the (x,y) position of the pointer.
+ *
+ * Note: (x,y) are /frame/ relative, not /framebuffer/ relative.
+ * That is, if the virtual desktop has been panned all the way to
+ * the right, and the pointer is to be in the upper-right hand corner
+ * of the viewable screen, the pointer coords are (0,0) (even though
+ * the pointer is on, say (550,0) wrt the frame buffer). This is, of
+ * course, a /good/ thing -- we don't want to have to deal with where
+ * the virtual display is, etc, in the cursor code.
+ *
+ */
+static void LgSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) {
+ LgPtr pLg = LGPTR(pScrn);
+ volatile CARD16 *pXPos = (CARD16 *)(pLg->IOBase + CURSOR_X_POS);
+ volatile CARD16 *pYPos = (CARD16 *)(pLg->IOBase + CURSOR_Y_POS);
+ volatile CARD16 *pPreset = (CARD16 *)(pLg->IOBase + CURSOR_PRESET);
+
+#if 0
+#ifdef LG_CURSOR_DEBUG
+ ErrorF("LgSetCursorPosition %d %d\n", x, y);
+#endif
+#endif
+
+ if (x < 0 || y < 0) {
+ CARD16 oldPreset = *pPreset;
+ CARD16 newPreset = 0x8080 & oldPreset; /* Reserved bits */
+
+ if (x < 0) {
+ newPreset |= ((-x & 0x7F) << 8);
+ x = 0;
+ }
+
+ if (y < 0) {
+ newPreset |= ((-y & 0x7F) << 0);
+ y = 0;
+ }
+
+ *pPreset = newPreset;
+ pLg->CursorIsSkewed = TRUE;
+
+ } else if (pLg->CursorIsSkewed) {
+
+ /* Reset the hotspot location. */
+ *pPreset &= 0x8080;
+ pLg->CursorIsSkewed = FALSE;
+ }
+
+ /* Commit the new position to the card. */
+ *pXPos = x;
+ *pYPos = y;
+}
+
+
+/*
+ * Load the cursor image to the card. The cursor image is given in
+ * bits. The format is: ???
+ */
+static void LgLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits) {
+ LgPtr pLg = LGPTR(pScrn);
+ volatile CARD32 *pXCursorBits = (CARD32 *)bits;
+
+ volatile CARD32 *pHOSTDATA = (CARD32 *)(pLg->IOBase + HOSTDATA);
+ volatile CARD8 *pQFREE = (CARD8 *)(pLg->IOBase + QFREE);
+ int l, w;
+
+#ifdef LG_CURSOR_DEBUG
+ ErrorF("LgLoadCursorImage\n");
+#endif
+
+ /* All ("all") we have to do is a simple CPU-to-screen copy of the
+ cursor image to the frame buffer. */
+
+ while (!LgREADY())
+ ;
+
+ /* Wait until there's ample room in the chip's queue */
+ while (*pQFREE < 10)
+ ;
+
+ LgSETMODE(HOST2SCR); /* Host-to-screen blit */
+ LgSETROP(0x00CC); /* Source copy */
+
+ /* First, copy our transparent cursor image to the next 1/2 tile boundry */
+ /* Destination */
+ LgSETMDSTXY(pLg->HWCursorImageX+pLg->HWCursorTileWidth, pLg->HWCursorImageY);
+
+ /* Set the source pitch. 0 means that, worst case, the source is
+ alligned only on a byte boundry */
+ LgSETMPHASE1(0);
+
+ LgSETMEXTENTSNOMONOQW(pLg->HWCursorTileWidth, pLg->HWCursorTileHeight);
+
+ for (l = 0; l < CURSORHEIGHT; l++) {
+ /* Plane 0 */
+ for (w = 0; w < CURSORWIDTH >> 5; w++)
+ *pHOSTDATA = 0x00000000;
+ /* Plane 1 */
+ for (w = 0; w < CURSORWIDTH >> 5; w++)
+ *pHOSTDATA = 0x00000000;
+ }
+
+ /* Now, copy the real cursor image */
+
+ /* Set the destination */
+ LgSETMDSTXY(pLg->HWCursorImageX, pLg->HWCursorImageY);
+
+ /* Set the source pitch. 0 means that, worst case, the source is
+ alligned only on a byte boundry */
+ LgSETMPHASE1(0);
+
+ /* Always copy an entire cursor image to the card. */
+ LgSETMEXTENTSNOMONOQW(pLg->HWCursorTileWidth, pLg->HWCursorTileHeight);
+
+ for (l = 0; l < CURSORHEIGHT; l++) {
+ /* Plane 0 */
+ for (w = 0; w < CURSORWIDTH >> 5; w++)
+ *pHOSTDATA = *pXCursorBits++;
+ /* Plane 1 */
+ for (w = 0; w < CURSORWIDTH >> 5; w++)
+ *pHOSTDATA = *pXCursorBits++;
+ }
+
+ while (!LgREADY())
+ ;
+}
+
+
+
+/*
+ * LgFindCursorTile() finds the tile of display memory that will be
+ * used to load the pointer image into. The tile chosen will be the
+ * last tile in the last line of the frame buffer.
+ */
+static void
+LgFindCursorTile(ScrnInfoPtr pScrn, int *x, int *y, int *width, int *height,
+ CARD32 *curAddr) {
+ LgPtr pLg = LGPTR(pScrn);
+
+ int videoRam = pScrn->videoRam; /* in K */
+ int tileHeight = LgLineData[pLg->lineDataIndex].width?8:16;
+ int tileWidth = LgLineData[pLg->lineDataIndex].width?256:128;
+ int tilesPerLine = LgLineData[pLg->lineDataIndex].tilesPerLine;
+ int filledOutTileLines, leftoverMem;
+ int yTile, xTile;
+ int tileNumber;
+
+ filledOutTileLines = videoRam / (tilesPerLine * 2); /* tiles are 2K */
+ leftoverMem = videoRam - filledOutTileLines*tilesPerLine*2;
+
+ if (leftoverMem > 0) {
+ yTile = filledOutTileLines;
+ } else {
+ /* There is no incomplete row of tiles. Then just use the last
+ tile in the last line */
+ yTile = filledOutTileLines - 1;
+ }
+ xTile = 0; /* Always use the first tile in the determined tile row */
+
+ /* The (x,y) coords of the pointer image. */
+ if (x)
+ *x = xTile * tileWidth;
+ if (y)
+ *y = yTile * tileHeight;
+
+ if (width)
+ *width = tileWidth;
+ if (height)
+ *height = tileHeight / 2;
+
+ /* Now, compute the linear address of the cursor image. This process
+ is unpleasant because the memory is tiled, and we essetially have
+ to undo the tiling computation. */
+ if (curAddr) {
+ unsigned int nIL; /* Interleaving */
+ nIL = pLg->memInterleave==0x00? 1 : (pLg->memInterleave==0x40 ? 2 : 4);
+
+ if (PCI_CHIP_GD5465 == pLg->Chipset) {
+ /* The Where's The Cursor formula changed for the 5465. It's really
+ kinda wierd now. */
+ unsigned long page, bank;
+ unsigned int nX, nY;
+
+ nX = xTile * tileWidth;
+ nY = yTile * tileHeight;
+
+ page = (nY / (tileHeight * nIL)) * tilesPerLine + nX / tileWidth;
+ bank = (nX/tileWidth + nY/tileHeight) % nIL + page/(512*nIL);
+ page = page & 0x1FF;
+ *curAddr = bank*1024*1024L + page*2048 + (nY%tileHeight)*tileWidth;
+
+ } else {
+ tileNumber = (tilesPerLine*nIL) * (yTile/nIL) + yTile % nIL;
+ *curAddr = tileNumber * 2048;
+ }
+ }
+}
+
+
+
+
+/*
+ * Hide/disable the HW cursor.
+ */
+void LgHideCursor(ScrnInfoPtr pScrn) {
+ LgPtr pLg = LGPTR(pScrn);
+ volatile CARD16 *pMiscControl = (CARD16 *)(pLg->IOBase + MISC_CONTROL);
+
+ /* To hide the cursor, we kick it off into the corner, and then set the
+ cursor image to be a transparent bitmap. That way, if X continues
+ to move the cursor while it is hidden, there is no way that the user
+ can move the cursor back on screen!
+
+ We don't just clear the cursor enable bit because doesn't work in some
+ cases (like when switching back to text mode).
+ */
+
+#ifdef LG_CURSOR_DEBUG
+ ErrorF("LgHideCursor\n");
+#endif
+
+ *pMiscControl &= 0xFFFE;
+}
+
+void LgShowCursor(ScrnInfoPtr pScrn) {
+ LgPtr pLg = LGPTR(pScrn);
+ volatile CARD16 *pMiscControl = (CARD16 *)(pLg->IOBase + MISC_CONTROL);
+ volatile CARD16 *pCursorAddr = (CARD16 *)(pLg->IOBase + CURSOR_ADDR);
+
+#ifdef LG_CURSOR_DEBUG
+ ErrorF("LgShowCursor\n");
+#endif
+
+ *pMiscControl |= (1<<0);
+ *pCursorAddr = pLg->HWCursorAddr & 0x7FFC;
+}
+
+
+/*
+ * Can the HW cursor be used?
+ */
+static Bool LgUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) {
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+#ifdef LG_CURSOR_DEBUG
+ ErrorF("LgUseHWCursor\n");
+#endif
+
+ if(pScrn->bitsPerPixel < 8)
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * Initialize all the fun HW cursor code.
+ */
+Bool LgHWCursorInit(ScreenPtr pScreen) {
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ LgPtr pLg = LGPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+#ifdef LG_CURSOR_DEBUG
+ ErrorF("LgHWCursorInit\n");
+#endif
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pLg->CursorInfoRec = infoPtr;
+ LgFindCursorTile(pScrn,
+ &pLg->HWCursorImageX, &pLg->HWCursorImageY,
+ &pLg->HWCursorTileWidth, &pLg->HWCursorTileHeight,
+ &pLg->HWCursorAddr);
+ /* Keep only bits 22:10 of the address. */
+ pLg->HWCursorAddr = (pLg->HWCursorAddr >> 8) & 0x7FFC;
+
+ pLg->CursorIsSkewed = FALSE;
+
+ infoPtr->MaxWidth = CURSORWIDTH;
+ infoPtr->MaxHeight = CURSORHEIGHT;
+ infoPtr->Flags =
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64;
+ infoPtr->SetCursorColors = LgSetCursorColors;
+ infoPtr->SetCursorPosition = LgSetCursorPosition;
+ infoPtr->LoadCursorImage = LgLoadCursorImage;
+ infoPtr->HideCursor = LgHideCursor;
+ infoPtr->ShowCursor = LgShowCursor;
+ infoPtr->UseHWCursor = LgUseHWCursor;
+ /* RealizeCursor is how the cursor bits are converted from an infoPtr
+ to the bits to slam out to the card. Can we use one of the
+ pre-defined realize'rs? Look in ramdac/xf86HWCurs.c. */
+ infoPtr->RealizeCursor = NULL;
+
+#ifdef LG_CURSOR_DEBUG
+ ErrorF("LgHWCursorInit before xf86InitCursor\n");
+#endif
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_i2c.c b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_i2c.c
new file mode 100644
index 000000000..665d0223b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_i2c.c
@@ -0,0 +1,90 @@
+/* (c) Itai Nahshon */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_i2c.c,v 1.1 1998/11/15 04:30:25 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+#include "vgaHW.h"
+
+#include "lg.h"
+
+static void
+LGI2CPutBits(I2CBusPtr b, int clock, int data) {
+ unsigned int regval, regno;
+ LgPtr pLg = ((LgPtr)b->DriverPrivate.ptr);
+ if (b == pLg->I2CPtr1)
+ regno = 0x280;
+ else if(b == pLg->I2CPtr2)
+ regno = 0x282;
+ else return;
+
+ regval = 0xff7e;
+ if(clock) regval |= 0x0080;
+ if(data) regval |= 0x0001;
+ *((volatile CARD16 *)(pLg->IOBase + regno)) = regval;
+ /* ErrorF("LGI2CPutBits: %d %d\n", clock, data); */
+}
+
+static void
+LGI2CGetBits(I2CBusPtr b, int *clock, int *data) {
+ unsigned int regval, regno;
+ LgPtr pLg = ((LgPtr)b->DriverPrivate.ptr);
+ if (b == pLg->I2CPtr1)
+ regno = 0x280;
+ else if(b == pLg->I2CPtr2)
+ regno = 0x282;
+ else return;
+
+ regval = *((volatile CARD16 *)(pLg->IOBase + regno));
+ *clock = (regval & 0x8000) != 0;
+ *data = (regval & 0x0100) != 0;
+ /* ErrorF("LGI2CGetBits: %d %d\n", *clock, *data); */
+}
+
+Bool
+LGI2CInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ LgPtr pLg = LGPTR(pScrn);
+ I2CBusPtr I2CPtr;
+
+#ifdef CIR_DEBUG
+ ErrorF("LGI2CInit\n");
+#endif
+
+ I2CPtr = xf86CreateI2CBusRec();
+ if(!I2CPtr) return FALSE;
+
+ pLg->I2CPtr1 = I2CPtr;
+
+ I2CPtr->BusName = "I2C bus 1";
+ I2CPtr->scrnIndex = pScrn->scrnIndex;
+ I2CPtr->I2CPutBits = LGI2CPutBits;
+ I2CPtr->I2CGetBits = LGI2CGetBits;
+ I2CPtr->DriverPrivate.ptr = pLg;
+
+ if(!xf86I2CBusInit(I2CPtr))
+ return FALSE;
+
+ I2CPtr = xf86CreateI2CBusRec();
+ if(!I2CPtr) return FALSE;
+
+ pLg->I2CPtr2 = I2CPtr;
+
+ I2CPtr->BusName = "I2C bus 2";
+ I2CPtr->scrnIndex = pScrn->scrnIndex;
+ I2CPtr->I2CPutBits = LGI2CPutBits;
+ I2CPtr->I2CGetBits = LGI2CGetBits;
+ I2CPtr->DriverPrivate.ptr = pLg;
+
+ if(!xf86I2CBusInit(I2CPtr))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_xaa.c b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_xaa.c
new file mode 100644
index 000000000..17e9b5792
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_xaa.c
@@ -0,0 +1,294 @@
+/*
+ * XAA acceleration for CL-GD546x -- The Laugna family
+ *
+ * lg_xaa.c
+ *
+ * (c) 1998 Corin Anderson.
+ * corina@the4cs.com
+ * Tukwila, WA
+ *
+ * Much of this code is inspired by the XAA acceleration from XFree86
+ * 3.3.3, laguna_acl.c
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_xaa.c,v 1.1 1998/11/22 10:37:21 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+#include "vgaHW.h"
+
+#include "lg.h"
+#include "lg_xaa.h"
+
+/* Laguna raster operations, source is OP1 and destination is OP0. */
+/* The order in this array is important! */
+static int lgRop[16] = {
+ /* Lg Op X name */
+
+ 0x00, /* 0 GXclear */
+ 0x88, /* S.D GXand */
+ 0x44, /* S.~D GXandReverse */
+ 0xCC, /* S GXcopy */
+ 0x22, /* ~S.D GXandInverted */
+ 0xAA, /* D GXnoop */
+ 0x66, /* S~=D GXxor */
+ 0xEE, /* S+D GXor */
+ 0x77, /* ~S.~D GXnor */
+ 0x99, /* S=D GXequiv */
+ 0x55, /* ~D GXinvert */
+ 0xDD, /* S+~D GXorReverse */
+ 0x33, /* ~S GXcopyInverted */
+ 0xBB, /* ~S+D GXorInverted */
+ 0x11, /* ~S+~D GXnand */
+ 0xFF /* 1 GXset */
+};
+
+#if 0
+/* Laguna raster operations, source is OP2 and destination is OP0. */
+static int lgPatRop[16] = {
+ /* Lg Op X name */
+
+ 0x00, /* 0 GXclear */
+ 0xA0, /* S.D GXand */
+ 0x50, /* S.~D GXandReverse */
+ 0xF0, /* S GXcopy */
+ 0x0A, /* ~S.D GXandInverted */
+ 0xAA, /* D GXnoop */
+ 0x5A, /* S~=D GXxor */
+ 0xFA, /* S+D GXor */
+ 0x05, /* ~S.~D GXnor */
+ 0xA5, /* S=D GXequiv */
+ 0x55, /* ~D GXinvert */
+ 0xF5, /* S+~D GXorReverse */
+ 0x0F, /* ~S GXcopyInverted */
+ 0xAF, /* ~S+D GXorInverted */
+ 0x5F, /* ~S+~D GXnand */
+ 0xFF /* 1 GXset */
+};
+#endif
+
+
+static void LgSetBitmask(LgPtr pLg, const CARD32 m);
+static void LgWaitQAvail(LgPtr pLg, int n);
+static CARD32 LgExpandColor(CARD32 color, int bpp);
+static void LgSync(ScrnInfoPtr pScrn);
+static void LgSetupForSolidFill(ScrnInfoPtr pScrn,
+ int color,
+ int rop,
+ unsigned int planemask);
+
+static void LgSubsequentSolidFillRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h);
+static void LgSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir,
+ int rop,
+ unsigned int planemask,
+ int transparency_color);
+static void LgSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1,
+ int x2, int y2,
+ int w, int h);
+
+
+
+
+
+
+
+
+
+/**************************************************** LgXAAInit *****/
+
+Bool LgXAAInit(ScreenPtr pScreen) {
+ XAAInfoRecPtr XAAPtr;
+
+ XAAPtr = XAACreateInfoRec();
+ if(!XAAPtr) return FALSE;
+
+ /*
+ * Solid color fills.
+ */
+ XAAPtr->SetupForSolidFill = LgSetupForSolidFill;
+ XAAPtr->SubsequentSolidFillRect = LgSubsequentSolidFillRect;
+ XAAPtr->SubsequentSolidFillTrap = NULL;
+ XAAPtr->SolidFillFlags = 0;
+
+ /*
+ * Screen-to-screen copies.
+ */
+ XAAPtr->SetupForScreenToScreenCopy = LgSetupForScreenToScreenCopy;
+ XAAPtr->SubsequentScreenToScreenCopy = LgSubsequentScreenToScreenCopy;
+ /* Maybe ONLY_LEFT_TO_RIGHT_BITBLT or ONLY_TWO_BITBLT_DIRECTIONS? */
+ XAAPtr->ScreenToScreenCopyFlags = ONLY_LEFT_TO_RIGHT_BITBLT;
+
+ /*
+ * Miscellany.
+ */
+ XAAPtr->Sync = LgSync;
+
+ if(!XAAInit(pScreen, XAAPtr))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+
+
+
+
+
+
+/******************************************** Lg XAA helper functions ***/
+
+/*
+ * The bitmask is usually all 1's, so it's silly to spend a DWORD write
+ * to program the register with the same value each time. Bitmask is
+ * about the only register whose value is worth shadowing, so we special-
+ * case it.
+ */
+static void LgSetBitmask(LgPtr pLg, const CARD32 m) {
+ if (m != pLg->oldBitmask) {
+ LgSETBITMASK(m);
+ pLg->oldBitmask = m;
+ }
+}
+
+/*
+ * Return from the function only when there's room somewhere for the
+ * upcoming register writes. That means that either PCI retry is enabled
+ * (i.e., we let the PCI bus buffer the register writes), or we wait for
+ * room in the Laguna's command queue explicitly.
+ */
+static void LgWaitQAvail(LgPtr pLg, int n) {
+ if (!0/*lgUsePCIRetry*/) {
+ CARD8 qfree;
+
+ /* Wait until n entries are open in the command queue */
+ do
+ qfree = *(volatile CARD8 *)(pLg->IOBase + QFREE);
+ while (qfree < n);
+ }
+}
+
+
+/* We might want to make this a macro at some point. */
+static CARD32 LgExpandColor(CARD32 color, int bpp) {
+ if (8 == bpp)
+ color = ((color&0xFF) << 8) | (color&0xFF);
+
+ if (8 == bpp || 16 == bpp)
+ color = ((color&0xFFFF) << 16) | (color&0xFFFF);
+
+ return color;
+}
+
+
+/*************************************************** Lg XAA functions ***/
+
+
+static void LgSync(ScrnInfoPtr pScrn) {
+ LgPtr pLg = LGPTR(pScrn);
+
+ while (!LgREADY())
+ ;
+}
+
+static void LgSetupForSolidFill(ScrnInfoPtr pScrn,
+ int color,
+ int rop,
+ unsigned int planemask) {
+
+ const LgPtr pLg = LGPTR(pScrn);
+
+ color = LgExpandColor(color, pScrn->bitsPerPixel);
+
+ LgWaitQAvail(pLg, 4);
+
+ LgSETBACKGROUND(color);
+ LgSETROP(lgRop[rop]);
+ LgSETMODE(SCR2SCR | COLORFILL);
+ LgSetBitmask(pLg, planemask);
+}
+
+static void LgSubsequentSolidFillRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h) {
+ const LgPtr pLg = LGPTR(pScrn);
+
+ /* Wait for room in the command queue. */
+ LgWaitQAvail(pLg, 2);
+
+ LgSETDSTXY(x, y);
+ LgSETEXTENTS(w, h);
+}
+
+static void LgSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir,
+ int rop,
+ unsigned int planemask,
+ int transparency_color) {
+ int bltmode = 0;
+ LgPtr const pLg = LGPTR(pScrn);
+
+ pLg->blitTransparent = (transparency_color != -1);
+ pLg->blitYDir = ydir;
+
+ LgWaitQAvail(pLg, 4);
+
+ /* We set the rop up here because the LgSETROP macro conveniently
+ (really -- it is convenient!) clears the transparency bits
+ in DRAWDEF. We'll set those bits appropriatly later. */
+ LgSETROP(lgRop[rop]);
+
+ if (ydir < 0)
+ bltmode |= BLITUP;
+ if (pLg->blitTransparent) {
+ /* Gotta extend the transparency_color to the full 32-bit
+ size of the register. */
+ transparency_color = LgExpandColor(transparency_color,
+ pScrn->bitsPerPixel);
+
+ bltmode |= COLORTRANS;
+ LgSETBACKGROUND(transparency_color);
+ LgSETTRANSPARENCY(TRANSEQ);
+ } else {
+ LgSETTRANSPARENCY(TRANSNONE);
+ }
+
+ LgSETMODE(SCR2SCR | COLORSRC | bltmode);
+ LgSetBitmask(pLg, planemask);
+}
+
+static void LgSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1,
+ int x2, int y2,
+ int w, int h) {
+ const LgPtr pLg = LGPTR(pScrn);
+
+ /*
+ * We have set the flag indicating that xdir must be one,
+ * so we can assume that here.
+ */
+ if (pLg->blitYDir == -1) {
+ y1 += h - 1;
+ y2 += h - 1;
+ }
+
+ if (pLg->blitTransparent) {
+ /* We're doing a transparent blit. We'll need to point
+ OP2 to the color compare mask. */
+ LgWaitQAvail(pLg, 4);
+ LgSETTRANSMASK(x1, y1);
+ } else {
+ LgWaitQAvail(pLg, 3);
+ }
+ LgSETSRCXY(x1, y1);
+ LgSETDSTXY(x2, y2);
+ LgSETEXTENTS(w, h);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_xaa.h b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_xaa.h
new file mode 100644
index 000000000..b07773502
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_xaa.h
@@ -0,0 +1,209 @@
+#ifndef __LG_XAA_H
+#define __LG_XAA_H
+
+/*
+ * XAA acceleration for CL-GD546x -- The Laugna family
+ *
+ * lg_xaa.h
+ *
+ * (c) 1996,1998 Corin Anderson.
+ * corina@the4cs.com
+ * Tukwila, WA
+ *
+ * This header file draws much from the file cir_blitLG.h in version 3.3.3
+ * of XFree86.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/lg_xaa.h,v 1.1 1998/11/22 10:37:21 dawes Exp $ */
+
+/* This header file defines the necessary structures, contstants, and
+ variables for using the bitBLT engine on a Laguna family graphics
+ accelerator. */
+
+
+enum { /* Offsets into MMIO space for bitBLT regs */
+ STATUS = 0x0400,
+ OP0_opRDRAM = 0x0520,
+ OP1_opRDRAM = 0x0540,
+ OP2_opRDRAM = 0x0560,
+ OP0_opMRDRAM = 0x0524,
+ OP1_opMRDRAM = 0x0544,
+ OP2_opMRDRAM = 0x0564,
+ OP0_opSRAM = 0x0528,
+ OP1_opSRAM = 0x0548,
+ OP2_opSRAM = 0x0568,
+ OP1_opMSRAM = 0x054A,
+ OP2_opMSRAM = 0x056A,
+ DRAWDEF = 0x0584,
+ BLTDEF = 0x0586,
+ BLTEXT_EX = 0x0700,
+ MBLTEXT_EX = 0x0720,
+ MONOQW = 0x0588,
+ QFREE = 0x0404,
+ PATOFF = 0x052A,
+ HOSTDATA = 0x0800,
+ OP_opBGCOLOR = 0x05E4,
+ OP_opFGCOLOR = 0x05E0,
+ bltCONTROL = 0x0402,
+ BITMASK = 0x05E8
+};
+
+enum { HOSTDATASIZE = 2048 }; /* The HOSTDATA port is 2048 BYTES */
+
+enum { /* OR these together to form a bitBLT mode */
+ HOST2SCR = 0x1120, /* CPU/Screen transfer modes */
+ SCR2HOST = 0x2010,
+ HOST2PAT = 0x1102,
+ HOST2SRAM2 = 0x6020, /* CPU to SRAM2 transfer */
+
+ SCR2SCR = 0x1110, /* Screen/Screen transfers */
+ COLORSRC = 0x0000, /* Source is color data */
+ MONOSRC = 0x0040, /* Source is mono data (color expansion) */
+ COLORTRANS = 0x0001, /* Transparent screen/screen transfer */
+ MONOTRANS = 0x0005, /* Transparent screen/screen color expansion */
+ COLORFILL = 0x0070, /* Solid color fill mode */
+ SRAM1SCR2SCR = 0x1180, /* Pattern fill, source from SRAM1 */
+
+ PAT2SCR = 0x1109, /* Pattern/Screen transfers */
+ COLORPAT = 0x0000, /* Pattern is color data */
+ MONOPAT = 0x0004, /* Pattern is mono data (color expansion) */
+ SRAM2PAT2SCR = 0x1108, /* SRAM2 is pattern source */
+
+ PATeqSRC = 0x0800, /* The Pattern and Source operands are the same */
+ /* Advice from Corey: don't ever try to use
+ this option! 8) There's a documented bug
+ with it on the '62, and, well, I have
+ empirical evidence that either the bug's
+ still around, even in the '64 and the '65.
+ It's a performance option, anyway, so not
+ using it should be okay. */
+
+
+ BLITUP = 0x8000 /* The blit is proceeding from bottom to top */
+};
+
+enum { /* Select transparency compare */
+ TRANSBG = 0x0100,
+ TRANSFG = 0x0300,
+ TRANSEQ = 0x0100,
+ TRANSNE = 0x0300,
+ TRANSNONE = 0x0000
+};
+
+
+#define LgREADY() \
+ ((*(volatile CARD8 *)(pLg->IOBase + STATUS) & 0x07) == 0x00)
+
+#define LgSETROP(rop) \
+ *(CARD16 *)(pLg->IOBase + DRAWDEF) = (rop);
+
+#define LgSETTRANSPARENCY(trans) \
+ *(CARD16 *)(pLg->IOBase + DRAWDEF) = \
+ (trans) | (*(volatile CARD16 *)(pLg->IOBase + DRAWDEF) & 0x00FF);
+
+#define LgSETMODE(mode) \
+ *(CARD16 *)(pLg->IOBase + BLTDEF) = (mode);
+
+#define LgSETDSTXY(X, Y) \
+ *(CARD32 *)(pLg->IOBase + OP0_opRDRAM) = (((Y) << 16) | (X));
+
+#define LgSETSRCXY(X, Y) \
+ *(CARD32 *)(pLg->IOBase + OP1_opRDRAM) = (((Y) << 16) | (X));
+
+#define LgSETPATXY(X, Y) \
+ *(CARD32 *)(pLg->IOBase + OP2_opRDRAM) = (((Y) << 16) | (X));
+
+#define LgSETTRANSMASK(X, Y) LgSETPATXY(X, Y)
+
+#define LgSETSRAMDST(offset) \
+ *(CARD16 *)(pLg->IOBase + OP0_opSRAM) = (offset);
+
+#define LgSETSRAM1OFFSET(offset) \
+ *(CARD16 *)(pLg->IOBase + OP2_opSRAM) = (offset);
+
+#define LgSETSRAM2OFFSET(offset) \
+ *(CARD16 *)(pLg->IOBase + OP2_opSRAM) = (offset);
+
+#define LgSETMSRAM1OFFSET(offset) \
+ *(CARD16 *)(pLg->IOBase + OP1_opMSRAM) = (offset);
+
+#define LgSETMSRAM2OFFSET(offset) \
+ *(CARD16 *)(pLg->IOBase + OP2_opMSRAM) = (offset);
+
+#define LgSETMDSTXY(X, Y) \
+ *(CARD32 *)(pLg->IOBase + OP0_opMRDRAM) = (((Y) << 16) | (X));
+
+#define LgSETMSRCXY(X, Y) \
+ *(CARD32 *)(pLg->IOBase + OP1_opMRDRAM) = (((Y) << 16) | (X));
+
+#define LgSETMPATXY(X, Y) \
+ *(CARD32 *)(pLg->IOBase + OP2_opMRDRAM) = (((Y) << 16) | (X));
+
+#define LgSETMTRANSMASK(X, Y) LgSETMPATXY(X, Y)
+
+#define LgSETPHASE0(phase) \
+ *(CARD32 *)(pLg->IOBase + OP0_opRDRAM) = (phase);
+
+#define LgSETPHASE1(phase) \
+ *(CARD32 *)(pLg->IOBase + OP1_opRDRAM) = (phase);
+
+#define LgSETPHASE2(phase) \
+ *(CARD32 *)(pLg->IOBase + OP2_opRDRAM) = (phase);
+
+#define LgSETMPHASE0(phase) \
+ *(CARD32 *)(pLg->IOBase + OP0_opMRDRAM) = (phase);
+
+#define LgSETMPHASE1(phase) \
+ *(CARD32 *)(pLg->IOBase + OP1_opMRDRAM) = (phase);
+
+#define LgSETEXTENTS(width, height) \
+ *(CARD32 *)(pLg->IOBase + BLTEXT_EX) = (((height) << 16)|(width));
+
+#if 0
+#define LgSETMEXTENTS(width, height) \
+ *(CARD32 *)(pLg->IOBase + MBLTEXT_EX) = (((height) << 16)|(width));
+#else
+/* For monochrome (byte) blits, we need to set how many QWORDs of data
+ encompass the X extent. Write this piece of data into MONOQW. */
+#define LgSETMEXTENTS(width, height) \
+ { \
+ *(CARD16 *)(pLg->IOBase + MONOQW) = ((width + 7) >> 3); \
+ *(CARD32 *)(pLg->IOBase + MBLTEXT_EX) = \
+ (((height) << 16)|(width)); \
+ }
+
+#define LgSETMEXTENTSNOMONOQW(width, height) \
+ *(CARD32 *)(pLg->IOBase + MBLTEXT_EX) = (((height) << 16)|(width));
+
+/*
+ *(CARD16 *)(pLg->IOBase + MBLTEXT_EX) = height;
+ *(CARD16 *)(pLg->IOBase + MBLTEXT_EX + 2) = width;
+*/
+#endif
+
+#define LgHOSTDATAWRITE(data) \
+ *(CARD32 *)(pLg->IOBase + HOSTDATA) = (data);
+
+#define LgHOSTDATAREAD() \
+ (*(CARD32 *)(pLg->IOBase + HOSTDATA))
+
+#define LgSETBACKGROUND(color) \
+ *(CARD32 *)(pLg->IOBase + OP_opBGCOLOR) = (color);
+
+#define LgSETFOREGROUND(color) \
+ *(CARD32 *)(pLg->IOBase + OP_opFGCOLOR) = (color);
+
+#define LgSETPATOFF(xoff, yoff) \
+ *(CARD16 *)(pLg->IOBase + PATOFF) = (((yoff) << 8) | (xoff));
+
+#define LgSETSWIZZLE() \
+ *(CARD16 *)(pLg->IOBase + bltCONTROL) |= 0x0400;
+
+#define LgCLEARSWIZZLE() \
+ *(CARD16 *)(pLg->IOBase + bltCONTROL) &= ~0x0400;
+
+#define LgSETBITMASK(m) \
+ *(unsigned int *)(pLg->IOBase + BITMASK) = m;
+
+
+
+#endif /* __LG_XAA_H */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/confdrv.sh b/xc/programs/Xserver/hw/xfree86/drivers/confdrv.sh
new file mode 100644
index 000000000..00f06c18f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/confdrv.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# $XFree86: xc/programs/Xserver/hw/xfree86/drivers/confdrv.sh,v 1.2 1998/07/25 16:55:33 dawes Exp $
+#
+# This script generates drvConf.c
+#
+# usage: confdrv.sh driver1 driver2 ...
+#
+
+DRVCONF=./drvConf.c
+
+cat > $DRVCONF <<EOF
+/*
+ * This file is generated automatically -- DO NOT EDIT
+ */
+
+#include "xf86.h"
+
+extern DriverRec
+EOF
+Args="`echo $* | tr '[a-z]' '[A-Z]'`"
+set - $Args
+while [ $# -gt 1 ]; do
+ echo " $1," >> $DRVCONF
+ shift
+done
+echo " $1;" >> $DRVCONF
+cat >> $DRVCONF <<EOF
+
+DriverPtr xf86DriverList[] =
+{
+EOF
+for i in $Args; do
+ echo " &$i," >> $DRVCONF
+done
+echo "};" >> $DRVCONF
+
+cat >> $DRVCONF <<EOF
+
+int xf86NumDrivers = sizeof(xf86DriverList) / sizeof(xf86DriverList[0]);
+
+EOF
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/fbdev/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/fbdev/Imakefile
new file mode 100644
index 000000000..76e6f413b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/fbdev/Imakefile
@@ -0,0 +1,49 @@
+XCOMM
+XCOMM This is an Imakefile for the fbdev driver.
+XCOMM
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/fbdev/Imakefile,v 1.6 1999/08/14 10:49:44 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = fbdev.c
+OBJS = fbdev.o
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/afb \
+ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \
+ -I$(XF86SRC)/fbdevhw -I$(XF86SRC)/ramdac \
+ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
+ -I$(XF86SRC)/rac \
+ -I$(SERVERSRC)/Xext -I$(XF86SRC)/xf8_32bpp\
+ -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(XF86SRC)/shadowfb -I$(EXTINCSRC)
+#endif
+
+DEFINES = FbdevDefines
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget(fbdev,$(OBJS))
+
+InstallObjectModule(fbdev,$(MODULEDIR),drivers)
+
+#if !defined(XF86DriverSDK)
+CppManTarget(fbdev,)
+InstallModuleManPage(fbdev)
+#endif
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/fbdev)
+InstallDriverSDKNonExecFile(fbdev.c,$(DRIVERSDKDIR)/drivers/fbdev)
+
+InstallDriverSDKObjectModule(fbdev,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c b/xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c
new file mode 100644
index 000000000..71dd66cf8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c
@@ -0,0 +1,743 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c,v 1.10 1999/06/27 16:17:31 dawes Exp $ */
+
+/* all driver need this */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "mipointer.h"
+#include "mibstore.h"
+#include "micmap.h"
+#include "colormapst.h"
+#include "xf86cmap.h"
+#include "shadowfb.h"
+
+/* for visuals */
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+#ifdef USE_AFB
+#include "afb.h"
+#endif
+
+#include "xf86Resources.h"
+#include "xf86RAC.h"
+
+#include "fbdevhw.h"
+
+#ifdef XvExtension
+#include "xf86xv.h"
+#endif
+
+#define DEBUG 0
+
+#if DEBUG
+# define TRACE_ENTER(str) ErrorF("fbdev: " str " %d\n",pScrn->scrnIndex)
+# define TRACE_EXIT(str) ErrorF("fbdev: " str " done\n")
+# define TRACE(str) ErrorF("fbdev trace: " str "\n")
+#else
+# define TRACE_ENTER(str)
+# define TRACE_EXIT(str)
+# define TRACE(str)
+#endif
+
+/* -------------------------------------------------------------------- */
+/* prototypes */
+
+static void FBDevIdentify(int flags);
+static Bool FBDevProbe(DriverPtr drv, int flags);
+static Bool FBDevPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool FBDevScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool FBDevCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool FBDevSaveScreen(ScreenPtr pScreen, Bool unblank);
+
+/* -------------------------------------------------------------------- */
+
+#define VERSION 4000
+#define FBDEV_NAME "FBDev"
+#define FBDEV_DRIVER_NAME "fbdev"
+#define FBDEV_MAJOR_VERSION 0
+#define FBDEV_MINOR_VERSION 1
+
+DriverRec FBDEV = {
+ VERSION,
+ "driver for linux framebuffer devices",
+ FBDevIdentify,
+ FBDevProbe,
+ NULL,
+ 0
+};
+
+/* Supported "chipsets" */
+static SymTabRec FBDevChipsets[] = {
+ { 0, "fbdev" },
+#ifdef USE_AFB
+ { 0, "afb" },
+#endif
+#if 0
+ { 0, "cfb8" },
+ { 0, "cfb16" },
+ { 0, "cfb24" },
+ { 0, "cfb32" },
+#endif
+ {-1, NULL }
+};
+
+/* Supported options */
+typedef enum {
+ OPTION_SHADOW_FB,
+ OPTION_FBDEV
+} FBDevOpts;
+
+static OptionInfoRec FBDevOptions[] = {
+ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_FBDEV, "fbdev", OPTV_STRING, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+/* -------------------------------------------------------------------- */
+
+static const char *afbSymbols[] = {
+ "afbScreenInit",
+ "afbCreateDefColormap",
+ NULL
+};
+
+static const char *cfbSymbols[] = {
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb24ScreenInit",
+ "cfb32ScreenInit",
+ "cfbCreateDefColormap",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+static const char *fbdevHWSymbols[] = {
+ "fbdevHWProbe",
+ "fbdevHWInit",
+ "fbdevHWSetVideoModes",
+ "fbdevHWUseBuildinMode",
+
+ "fbdevHWGetName",
+ "fbdevHWGetDepth",
+ "fbdevHWGetVidmem",
+
+ /* colormap */
+ "fbdevHWLoadpalette",
+
+ /* ScrnInfo hooks */
+ "fbdevHWSwitchMode",
+ "fbdevHWAdjustFrame",
+ "fbdevHWEnterVT",
+ "fbdevHWLeaveVT",
+ "fbdevHWValidMode",
+ NULL
+};
+
+#ifdef XFree86LOADER
+
+MODULESETUPPROTO(FBDevSetup);
+
+static XF86ModuleVersionInfo FBDevVersRec =
+{
+ "fbdev",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ FBDEV_MAJOR_VERSION, FBDEV_MINOR_VERSION, 0,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ NULL,
+ {0,0,0,0}
+};
+
+XF86ModuleData fbdevModuleData = { &FBDevVersRec, FBDevSetup, NULL };
+
+pointer
+FBDevSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&FBDEV, module, 0);
+ LoaderRefSymLists(afbSymbols, cfbSymbols, shadowSymbols, NULL);
+ return (pointer)1;
+ } else {
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+#endif /* XFree86LOADER */
+
+/* -------------------------------------------------------------------- */
+/* our private data, and two functions to allocate/free this */
+
+typedef struct {
+ unsigned char* fbstart;
+ unsigned char* fbmem;
+ int fboff;
+ unsigned char* shadowmem;
+ int shadowPitch;
+ Bool shadowFB;
+ CloseScreenProcPtr CloseScreen;
+ EntityInfoPtr pEnt;
+} FBDevRec, *FBDevPtr;
+
+#define FBDEVPTR(p) ((FBDevPtr)((p)->driverPrivate))
+
+static Bool
+FBDevGetRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(FBDevRec), 1);
+ return TRUE;
+}
+
+static void
+FBDevFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+/* -------------------------------------------------------------------- */
+
+static void
+FBDevIdentify(int flags)
+{
+ xf86PrintChipsets(FBDEV_NAME, "driver for linux framebuffer", FBDevChipsets);
+}
+
+static Bool
+FBDevProbe(DriverPtr drv, int flags)
+{
+ int i;
+ ScrnInfoPtr pScrn, pScrn0;
+ GDevPtr *devSections;
+ int numDevSections;
+ int bus,device,func;
+ char *dev;
+ Bool foundScreen = FALSE;
+
+ TRACE("probe start");
+ pScrn0 = xf86AllocateScreen(drv, 0);
+ if (!xf86LoadSubModule(pScrn0, "fbdevhw")) {
+ xf86DeleteScreen(pScrn0->scrnIndex,0);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(fbdevHWSymbols, NULL);
+
+ if ((numDevSections = xf86MatchDevice(FBDEV_DRIVER_NAME, &devSections)) <= 0) {
+ xf86DeleteScreen(pScrn0->scrnIndex,0);
+ return FALSE;
+ }
+
+ for (i = 0; i < numDevSections; i++) {
+ dev = xf86FindOptionValue(devSections[i]->options,"fbdev");
+ if (devSections[i]->busID) {
+ xf86ParsePciBusString(devSections[i]->busID,&bus,&device,&func);
+ if (!xf86CheckPciSlot(bus,device,func))
+ continue;
+ }
+ if (fbdevHWProbe(NULL,dev)) {
+ foundScreen = TRUE;
+ pScrn = xf86AllocateScreen(drv, 0);
+ xf86LoadSubModule(pScrn, "fbdevhw");
+ xf86LoaderReqSymLists(fbdevHWSymbols, NULL);
+
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = FBDEV_DRIVER_NAME;
+ pScrn->name = FBDEV_NAME;
+ pScrn->Probe = FBDevProbe;
+ pScrn->PreInit = FBDevPreInit;
+ pScrn->ScreenInit = FBDevScreenInit;
+ pScrn->SwitchMode = fbdevHWSwitchMode;
+ pScrn->AdjustFrame = fbdevHWAdjustFrame;
+ pScrn->EnterVT = fbdevHWEnterVT;
+ pScrn->LeaveVT = fbdevHWLeaveVT;
+ pScrn->ValidMode = fbdevHWValidMode;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "using %s\n", dev ? dev : "default device");
+ if (devSections[i]->busID) {
+ /* XXX what about when there's no busID set? */
+ int entity;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "claimed PCI slot %d:%d:%d\n",bus,device,func);
+ entity = xf86ClaimPciSlot(bus,device,func,drv,
+ 0,devSections[i],
+ TRUE);
+ xf86ConfigActivePciEntity(pScrn,entity,
+ NULL,RES_SHARED_VGA,
+ NULL,NULL,NULL,NULL);
+ } else {
+ /* XXX This is a quick hack */
+ int entity;
+
+ entity = xf86ClaimIsaSlot(drv, 0,
+ devSections[i], TRUE);
+ xf86ConfigActiveIsaEntity(pScrn,entity,
+ NULL,RES_SHARED_VGA,
+ NULL,NULL,NULL,NULL);
+ }
+ }
+ }
+ xfree(devSections);
+ xf86DeleteScreen(pScrn0->scrnIndex,0);
+ TRACE("probe done");
+ return foundScreen;
+}
+
+static Bool
+FBDevPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ FBDevPtr fPtr;
+ int default_depth;
+ char *mod = NULL;
+ const char *reqSym = NULL;
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ TRACE_ENTER("PreInit");
+
+ /* Check the number of entities, and fail if it isn't one. */
+ if (pScrn->numEntities != 1)
+ return FALSE;
+
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ FBDevGetRec(pScrn);
+ fPtr = FBDEVPTR(pScrn);
+
+ fPtr->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+
+ pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+ /* XXX Is this right? Can probably remove RAC_FB */
+ pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+
+ if (fPtr->pEnt->location.type == BUS_PCI &&
+ xf86RegisterResources(fPtr->pEnt->index,NULL,ResExclusive)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n");
+ return FALSE;
+ }
+
+ /* open device */
+ if (!fbdevHWInit(pScrn,NULL,xf86FindOptionValue(fPtr->pEnt->device->options,"fbdev")))
+ return FALSE;
+ default_depth = fbdevHWGetDepth(pScrn);
+ if (!xf86SetDepthBpp(pScrn, default_depth, default_depth, default_depth,
+ Support24bppFb | Support32bppFb))
+ return FALSE;
+ xf86PrintDepthBpp(pScrn);
+
+ /* color weight */
+ if (pScrn->depth > 8) {
+ rgb zeros = { 0, 0, 0 };
+ if (!xf86SetWeight(pScrn, zeros, zeros))
+ return FALSE;
+ }
+
+ /* visual init */
+ if (!xf86SetDefaultVisual(pScrn, -1))
+ return FALSE;
+
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+
+ xf86SetGamma(pScrn,zeros);
+
+ pScrn->progClock = TRUE;
+ pScrn->rgbBits = 8;
+ pScrn->chipset = "fbdev";
+ pScrn->videoRam = fbdevHWGetVidmem(pScrn);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware: %s (vidmem: %dk)\n",
+ fbdevHWGetName(pScrn),pScrn->videoRam/1024);
+
+ /* handle options */
+ xf86CollectOptions(pScrn, NULL);
+ xf86ProcessOptions(pScrn->scrnIndex, fPtr->pEnt->device->options, FBDevOptions);
+ fPtr->shadowFB = xf86ReturnOptValBool(FBDevOptions, OPTION_SHADOW_FB, TRUE);
+ xf86DrvMsg(pScrn->scrnIndex,
+ xf86IsOptionSet(FBDevOptions, OPTION_SHADOW_FB) ? X_CONFIG : X_DEFAULT,
+ "Option ShadowFB is %s\n",fPtr->shadowFB ? "on" : "off");
+
+ /* select video modes */
+ fbdevHWSetVideoModes(pScrn);
+ if (NULL == pScrn->modes)
+ fbdevHWUseBuildinMode(pScrn);
+ pScrn->currentMode = pScrn->modes;
+ pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch (fbdevHWGetType(pScrn))
+ {
+ case FBDEVHW_PLANES:
+ mod = "afb";
+ reqSym = "afbScreenInit";
+ break;
+ case FBDEVHW_PACKED_PIXELS:
+ switch (pScrn->bitsPerPixel)
+ {
+ case 8:
+ mod = "cfb";
+ reqSym = "cfbScreenInit";
+ break;
+ case 16:
+ mod = "cfb16";
+ reqSym = "cfb16ScreenInit";
+ break;
+ case 24:
+ mod = "cfb24";
+ reqSym = "cfb24ScreenInit";
+ break;
+ case 32:
+ mod = "cfb32";
+ reqSym = "cfb32ScreenInit";
+ break;
+ }
+ break;
+ case FBDEVHW_INTERLEAVED_PLANES:
+ /* Not supported yet, don't know what to do with this */
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Interleaved Planes are not supprted yet by drivers/fbdev.");
+ break;
+ case FBDEVHW_TEXT:
+ /* This should never happen ...
+ * we should check for this much much earlier ... */
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Text mode is not supprted by drivers/fbdev.\n"
+ "Why do you want to run the X in TEXT mode anyway ?");
+ break;
+ case FBDEVHW_VGA_PLANES:
+ /* Not supported yet */
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "EGA/VGA Planes are not supprted yet by drivers/fbdev.");
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Fbdev type (%d) not supported yet.");
+ break;
+ }
+ if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ FBDevFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymbols(reqSym, NULL);
+
+ /* Load shadowFB if needed */
+ if (fPtr->shadowFB) {
+ if (!xf86LoadSubModule(pScrn, "shadowfb")) {
+ FBDevFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymbols("ShadowFBInit", NULL);
+ }
+
+ TRACE_EXIT("PreInit");
+ return TRUE;
+}
+
+/* for ShadowFB */
+static void
+FBDevRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ FBDevPtr fPtr = FBDEVPTR(pScrn);
+ int width, height, Bpp, FBPitch;
+ unsigned char *src, *dst;
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ FBPitch = pScrn->displayWidth * Bpp;
+
+ while(num--) {
+ width = (pbox->x2 - pbox->x1) * Bpp;
+ height = pbox->y2 - pbox->y1;
+ src = fPtr->shadowmem + (pbox->y1 * fPtr->shadowPitch) +
+ (pbox->x1 * Bpp);
+ dst = fPtr->fbmem + fPtr->fboff + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
+
+ while(height--) {
+ memcpy(dst, src, width);
+ dst += FBPitch;
+ src += fPtr->shadowPitch;
+ }
+ pbox++;
+ }
+}
+
+static Bool
+FBDevSaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ FBDevPtr fPtr = FBDEVPTR(pScrn);
+ BoxRec box;
+
+ TRACE_ENTER("FBDevSaveScreen");
+ if (!(fPtr->shadowFB))
+ /* Not implemented yet - alloc huge memory block and copy ? */
+ return TRUE;
+
+ if (unblank) {
+ box.x1 = 0;
+ box.x2 = pScrn->virtualX;
+ box.y1 = 0;
+ box.y2 = pScrn->virtualY;
+ FBDevRefreshArea(pScrn, 1, &box);
+ } else {
+ memset(fPtr->fbmem + fPtr->fboff, 0,
+ pScrn->virtualX * pScrn->virtualY * ((pScrn->bitsPerPixel+7)/8));
+ }
+ return TRUE;
+}
+
+static Bool
+FBDevScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ FBDevPtr fPtr = FBDEVPTR(pScrn);
+ VisualPtr visual;
+ int ret,flags;
+
+ TRACE_ENTER("FBDevScreenInit");
+#if DEBUG
+ ErrorF("\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n"
+ "\tmask: %x,%x,%x, offset: %d,%d,%d\n",
+ pScrn->bitsPerPixel,
+ pScrn->depth,
+ xf86GetVisualName(pScrn->defaultVisual),
+ pScrn->mask.red,pScrn->mask.green,pScrn->mask.blue,
+ pScrn->offset.red,pScrn->offset.green,pScrn->offset.blue);
+#endif
+
+ if (NULL == (fPtr->fbmem = fbdevHWMapVidmem(pScrn)))
+ return FALSE;
+ fPtr->fboff = fbdevHWLinearOffset(pScrn);
+
+ fbdevHWSave(pScrn);
+
+ if (!fbdevHWModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ fbdevHWAdjustFrame(scrnIndex,0,0,0);
+
+ /* mi layer */
+ miClearVisualTypes();
+ if (pScrn->bitsPerPixel > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits, TrueColor))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+ /* shadowfb */
+ if (fPtr->shadowFB) {
+ fPtr->shadowPitch =
+ ((pScrn->virtualX * pScrn->bitsPerPixel >> 3) + 3) & ~3L;
+ fPtr->shadowmem = xalloc(fPtr->shadowPitch * pScrn->virtualY);
+ fPtr->fbstart = fPtr->shadowmem;
+ } else {
+ fPtr->shadowmem = NULL;
+ fPtr->fbstart = fPtr->fbmem + fPtr->fboff;
+ }
+
+ switch (fbdevHWGetType(pScrn))
+ {
+#ifdef USE_AFB
+ case FBDEVHW_PLANES:
+ ret = afbScreenInit
+ (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth);
+ break;
+#endif
+ case FBDEVHW_PACKED_PIXELS:
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ ret = cfbScreenInit
+ (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth);
+ break;
+ case 16:
+ ret = cfb16ScreenInit
+ (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth);
+ break;
+ case 24:
+ ret = cfb24ScreenInit
+ (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth);
+ break;
+ case 32:
+ ret = cfb32ScreenInit
+ (pScreen, fPtr->fbstart, pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in FBDevScreenInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ break;
+ case FBDEVHW_INTERLEAVED_PLANES:
+ /* This should never happen ...
+ * we should check for this much much earlier ... */
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: Text mode is not supprted by drivers/fbdev.\n"
+ "Comment: Why do you want to run the X in TEXT mode anyway ?");
+ ret = FALSE;
+ break;
+ case FBDEVHW_TEXT:
+ /* This should never happen ...
+ * we should check for this much much earlier ... */
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: Text mode is not supprted by drivers/fbdev.\n"
+ "Comment: Why do you want to run the X in TEXT mode anyway ?");
+ ret = FALSE;
+ break;
+ case FBDEVHW_VGA_PLANES:
+ /* Not supported yet */
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: EGA/VGA Planes are not supprted"
+ " yet by drivers/fbdev.");
+ ret = FALSE;
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: fbdev type (%d) unsupported in"
+ " FBDevScreenInit\n");
+ ret = FALSE;
+ break;
+ }
+ if (!ret)
+ return FALSE;
+
+ if (pScrn->bitsPerPixel > 8) {
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ xf86SetBlackWhitePixels(pScreen);
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ /* software cursor */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ if(fPtr->shadowFB)
+ ShadowFBInit(pScreen, FBDevRefreshArea);
+
+ /* colormap */
+ switch (fbdevHWGetType(pScrn))
+ {
+ /* XXX It would be simpler to use miCreateDefColormap() in all cases. */
+#ifdef USE_AFB
+ case FBDEVHW_PLANES:
+ if (!afbCreateDefColormap(pScreen))
+ return FALSE;
+ break;
+#endif
+ case FBDEVHW_PACKED_PIXELS:
+ if (!cfbCreateDefColormap(pScreen))
+ return FALSE;
+ break;
+ case FBDEVHW_INTERLEAVED_PLANES:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid fbdev type (interleaved planes)"
+ " in FBDevScreenInit\n");
+ return FALSE;
+ case FBDEVHW_TEXT:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid fbdev type (text)"
+ " in FBDevScreenInit\n");
+ return FALSE;
+ case FBDEVHW_VGA_PLANES:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid fbdev type (ega/vga planes)"
+ " in FBDevScreenInit\n");
+ return FALSE;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid fbdev type (%d) in FBDevScreenInit\n");
+ return FALSE;
+ }
+ flags = CMAP_PALETTED_TRUECOLOR;
+ if(!xf86HandleColormaps(pScreen, 256, 8, fbdevHWLoadPalette, NULL, flags))
+ return FALSE;
+
+ pScreen->SaveScreen = FBDevSaveScreen;
+
+ /* Wrap the current CloseScreen function */
+ fPtr->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = FBDevCloseScreen;
+
+#ifdef XvExtension
+ {
+ XF86VideoAdaptorPtr *ptr;
+
+ int n = xf86XVListGenericAdaptors(&ptr);
+ if (n) {
+ xf86XVScreenInit(pScreen,ptr,n);
+ }
+ }
+#endif
+
+#if DEBUG
+ ErrorF("FBDevScreenInit done\n",pScrn->scrnIndex);
+#endif
+ return TRUE;
+}
+
+static Bool
+FBDevCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ FBDevPtr fPtr = FBDEVPTR(pScrn);
+
+ fbdevHWRestore(pScrn);
+ fbdevHWUnmapVidmem(pScrn);
+ if (fPtr->shadowmem)
+ xfree(fPtr->shadowmem);
+ pScrn->vtSema = FALSE;
+
+ pScreen->CloseScreen = fPtr->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.cpp b/xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.cpp
new file mode 100644
index 000000000..d64701b92
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.cpp
@@ -0,0 +1,56 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.cpp,v 1.4 1999/08/22 13:04:25 dawes Exp $
+.TH FBDEV __drivermansuffix__ "Version 3.9.16" "XFree86"
+.SH NAME
+fbdev \- video driver for framebuffer device
+.SH SYNOPSIS
+.B "Section ""Device"""
+.br
+.BI " Identifier """ devname """"
+.br
+.B " Driver ""fbdev"""
+.br
+.BI " BusID ""pci:" bus : dev : func """
+.br
+\ \ ...
+.br
+.B EndSection
+.SH DESCRIPTION
+.B fbdev
+is an XFree86 driver for framebuffer devices. This is a non-accelerated
+driver, the following framebuffer depths are supported: 8, 15, 16, 24.
+All visual types are supported for depth 8, and TrueColor visual is
+supported for the other depths. Multi-head configurations are supported.
+.SH SUPPORTED HARDWARE
+The
+.B fbdev
+driver supports all hardware where a framebuffer driver is available.
+fbdev uses the os-specific submodule fbdevhw(__drivermansuffix__) to talk
+to the kernel
+device driver. Currently a fbdevhw module is available for linux.
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details. This section only covers configuration details specific to
+this driver.
+.PP
+For this driver it is not required to specify modes in the screen
+section of the config file. The
+.B fbdev
+driver can pick up the currently used video mode from the framebuffer
+driver and will use it if there are no video modes configured.
+.PP
+For PCI boards you might have to add a BusID line to the Device
+section. See above for a sample line. You can use "XFree86 -scanpci"
+to figure out the correct values.
+.PP
+The following driver
+.B Options
+are supported:
+.TP
+.BI "Option ""ShadowFB"" """ boolean """
+Enable or disable use of the shadow framebuffer layer. See
+shadowfb(__drivermansuffix__) for further information. Default: on.
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1),
+X(1), fbdevhw(__drivermansuffix__)
+.SH AUTHORS
+Authors include: Gerd Knorr
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glide/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/glide/Imakefile
new file mode 100644
index 000000000..433f48917
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glide/Imakefile
@@ -0,0 +1,52 @@
+XCOMM
+XCOMM This is an Imakefile for the glide driver.
+XCOMM
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glide/Imakefile,v 1.2 1999/08/14 10:49:44 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#if !HasGlide || !defined(GlideIncDir)
+all::
+ @echo "This driver requires that you define HasGlide and GlideIncDir in host.def"
+ @exit 1
+install::
+ @echo "This driver requires that you define HasGlide and GlideIncDir in host.def"
+ @exit 1
+#endif
+
+SRCS = glide_driver.c
+OBJS = glide_driver.o
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(GLIDEINCDIR) -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \
+ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \
+ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
+ -I$(SERVERSRC)/Xext -I$(XF86SRC)/xf8_32bpp\
+ -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(XF86SRC)/xf24_32bpp -I$(XF86SRC)/shadowfb
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget(glide,$(OBJS))
+
+InstallObjectModule(glide,$(MODULEDIR),drivers)
+
+CppManTarget(glide,)
+InstallModuleManPage(glide)
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/glide)
+InstallDriverSDKNonExecFile(glide_driver.c,$(DRIVERSDKDIR)/drivers/glide)
+
+InstallDriverSDKObjectModule(glide,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glide/glide.cpp b/xc/programs/Xserver/hw/xfree86/drivers/glide/glide.cpp
new file mode 100644
index 000000000..6213314be
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glide/glide.cpp
@@ -0,0 +1,298 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glide/glide.cpp,v 1.6 1999/08/28 10:43:35 dawes Exp $
+.TH GLIDE __drivermansuffix__ "Version 3.9.16" "XFree86"
+.SH NAME
+glide \- Glide video driver
+.SH SYNOPSIS
+.B "Section ""Device"""
+.br
+.BI " Identifier """ devname """"
+.br
+.B " Driver ""glide"""
+.br
+\ \ ...
+.br
+.B EndSection
+.SH READ THIS IF NOTHING ELSE
+This driver has a special requirement that needs to be fulfilled
+before it will work: You need Glide installed and you need to make a link for the libglide2x.so
+file. Read the second paragraph in the description below to find out how.
+.SH DESCRIPTION
+.B glide
+is an XFree86 driver for Glide capable video boards (such as 3Dfx
+Voodoo boards). This driver is mainly for Voodoo 1 and Voodoo 2 boards, later
+boards from 3Dfx have 2D built-in and you should preferably use a driver separate for
+those boards or the fbdev(__drivermansuffix__) driver.
+This driver is a bit special because Voodoo 1 and 2 boards are
+very much NOT made for running 2D graphics. Therefore, this driver
+uses no hardware acceleration (since there is no acceleration for 2D,
+only 3D). Instead it is implemented with the help of a "shadow"
+framebuffer that resides entirely in RAM. Selected portions of this
+shadow framebuffer are then copied out to the Voodoo board at the right
+time. Because of this, the speed of the driver is very dependent on
+the CPU. But since the CPU is nowadays actually rather fast at moving
+data, we get very good speed anyway, especially since the whole shadow
+framebuffer is in cached RAM.
+.PP
+This driver requires that you have installed Glide. (Which can, at the
+time of this writing, be found at
+http://glide.xxedgexx.com/3DfxRPMS.html). Also, you need to tell
+XFree86 where the libglide2x.so file is placed by making a soft link
+in the /usr/X11R6/lib/modules directory that points to the libglide2x.so
+file. For example (if your libglide2x.so file is in /usr/lib):
+.PP
+ # ln -s /usr/lib/libglide2x.so /usr/X11R6/lib/modules
+.PP
+If you have installed /dev/3dfx, the driver will be able to turn on
+the MTRR registers (through the glide library) if you have a CPU with
+such registers (see http://glide.xxedgexx.com/MTRR.html). This will
+speed up copying data to the Voodoo board by as much as 2.7 times and
+is very noticeable since this driver copies a lot of
+data... Highly recommended.
+.PP
+This driver supports 16 and 24 bit color modes. The 24 bit color mode
+uses a 32 bit framebuffer (it has no support for 24 bit packed-pixel
+framebuffers). Notice that the Voodoo boards can only display 16 bit
+color, but the shadow framebuffer can be run in 24 bit color. The
+point of supporting 24 bit mode is that this enables you to run in a
+multihead configuration with Xinerama together with another board that
+runs in real 24 bit color mode. (All boards must run the same color
+depth when you use Xinerama).
+.PP
+Resolutions supported are: 640x480, 800x600, 960x720, 1024x768,
+1280x1024 and 1600x1200. Note that not all modes will work on all
+Voodoo boards. It seems that Voodoo 2 boards support no higher than
+1024x768 and Voodoo 1 boards can go to 800x600. If you see a message like this in the output from the server:
+.PP
+ (EE) GLIDE(0): grSstWinOpen returned ...
+.PP
+Then you are probably trying to use a resolution that is supported by
+the driver but not supported by the hardware.
+.PP
+Refresh rates supported are: 60Hz, 75Hz and 85Hz. The refresh rate
+used is derived from the normal mode line according
+to the following table:
+.TP 28
+Mode-line refresh rate
+Used refresh rate
+.TP 28
+ 0-74 Hz
+ 60 Hz
+.TP 28
+ 74-84 Hz
+ 75 Hz
+.TP 28
+ 84- Hz
+ 85 Hz
+.PP
+Thus, if you use a modeline that for example has a 70Hz refresh rate
+you will only get a 60Hz refresh rate in actuality.
+.PP
+Selecting which Voodoo board to use with the driver is done by using
+an option called "GlideDevice" in the "Device" section. (If you don't
+have this option present then the first board found will be selected for that Device section). For
+example: To use the first Voodoo board, use a "Device" section like
+this, for example:
+.PP
+Section "Device"
+.br
+ Identifier "Voodoo"
+.br
+ Driver "glide"
+.br
+ Option "dpms" "on"
+.br
+ Option "GlideDevice" "0"
+.br
+EndSection
+.PP
+And if you have more than one Voodoo board, add another "Device"
+section with a GlideDevice option with value 1, and so on. (You can use more than one
+Voodoo board, but SLI configured boards will be treated as a single board.)
+.PP
+Multihead and Xinerama configurations are supported.
+.PP
+Limited support for DPMS screen saving is available. The "standby" and
+"suspend" modes are just painting the screen black. The "off" mode turns
+the Voodoo board off and thus works correctly.
+.PP
+This driver does not support a virtual screen size different from the display size.
+.SH SUPPORTED HARDWARE
+The
+.B glide
+driver supports any board that can be used with Glide (such as 3Dfx Voodoo boards)
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details. This section only covers configuration details specific to this
+driver.
+.PP
+The following driver
+.B Options
+are supported:
+.TP
+.BI "Option ""OnAtExit"" """ boolean """
+If true, will leave the Voodoo board on when the server exits. Useful in a multihead setup when
+only the Voodoo board is connected to a second monitor and you don't want that monitor to lose
+signal when you quit the server. Put this option in the Device section.
+Default: off.
+.TP
+.BI "Option ""GlideDevice"" """ integer """
+Selects which Voodoo board to use. (Or boards, in an SLI configuration).
+The value should be 0 for the first board, 1 for the second and so on.
+If it is not present, the first Voodoo board found will be selected.
+Put this option in the Device section.
+.SH "EXAMPLE"
+Here is an example of a part of an XF86Config file that uses a multihead
+configuration with two monitors. The first monitor is driven by the
+fbdev video driver and the second monitor is driven by the glide
+driver.
+.PP
+.br
+Section "Monitor"
+.br
+ Identifier "Monitor 1"
+.br
+ VendorName "Unknown"
+.br
+ ModelName "Unknown"
+.br
+ HorizSync 30-70
+.br
+ VertRefresh 50-80
+.br
+
+.br
+ # 1024x768 @ 76 Hz, 62.5 kHz hsync
+.br
+ Modeline "1024x768" 85 1024 1032 1152 1360 768 784 787 823
+.br
+EndSection
+.br
+
+.br
+Section "Monitor"
+.br
+ Identifier "Monitor 2"
+.br
+ VendorName "Unknown"
+.br
+ ModelName "Unknown"
+.br
+ HorizSync 30-70
+.br
+ VertRefresh 50-80
+.br
+
+.br
+ # 1024x768 @ 76 Hz, 62.5 kHz hsync
+.br
+ Modeline "1024x768" 85 1024 1032 1152 1360 768 784 787 823
+.br
+EndSection
+.br
+
+.br
+Section "Device"
+.br
+ Identifier "fb"
+.br
+ Driver "fbdev"
+.br
+ Option "shadowfb"
+.br
+ Option "dpms" "on"
+.br
+ # My video card is on the AGP bus which is usually
+.br
+ # located as PCI bus 1, device 0, function 0.
+.br
+ BusID "PCI:1:0:0"
+.br
+EndSection
+.br
+
+.br
+Section "Device"
+.br
+ # I have a Voodoo 2 board
+.br
+ Identifier "Voodoo"
+.br
+ Driver "glide"
+.br
+ Option "dpms" "on"
+.br
+ # The next line says I want to use the first board.
+.br
+ Option "GlideDevice" "0"
+.br
+EndSection
+.br
+
+.br
+Section "Screen"
+.br
+ Identifier "Screen 1"
+.br
+ Device "fb"
+.br
+ Monitor "Monitor 1"
+.br
+ DefaultDepth 16
+.br
+ Subsection "Display"
+.br
+ Depth 16
+.br
+ Modes "1024x768"
+.br
+ EndSubSection
+.br
+EndSection
+.br
+
+.br
+Section "Screen"
+.br
+ Identifier "Screen 2"
+.br
+ Device "Voodoo"
+.br
+ Monitor "Monitor 2"
+.br
+ DefaultDepth 16
+.br
+ Subsection "Display"
+.br
+ Depth 16
+.br
+ Modes "1024x768"
+.br
+ EndSubSection
+.br
+EndSection
+.br
+
+.br
+Section "ServerLayout"
+.br
+ Identifier "Main Layout"
+.br
+ # Screen 1 is to the right and screen 2 is to the left
+.br
+ Screen "Screen 2"
+.br
+ Screen "Screen 1" "" "" "Screen 2" ""
+.br
+EndSection
+.PP
+If you use this configuration file and start the server with the
++xinerama command line option, the two monitors will be showing a
+single large area where windows can be moved between monitors and
+overlap from one monitor to the other. Starting the X server with the
+Xinerama extension can be done for example like this:
+.PP
+$ xinit -- +xinerama
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(1)
+.SH AUTHORS
+Author: Henrik Harmsen.
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glide/glide_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/glide/glide_driver.c
new file mode 100644
index 000000000..b2f4dc608
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glide/glide_driver.c
@@ -0,0 +1,1122 @@
+
+/*
+ XFree86 driver for Glide(tm). (Mainly for Voodoo 1 and 2 cards)
+
+ Since Voodoo 1 and Voodoo 2 cards are very, very NOT made for
+ running a 2D windowing system, this driver is a little
+ special. Basically, we have a virtual framebuffer in RAM (the
+ Shadow Framebuffer) and we copy selected regions of this to the
+ voodoo card at appropriate times. We get no hardware acceleration
+ help (there isn't any for 2D on these cards), but since the
+ framebuffer is in cached RAM, we get a useable display
+ anyway. Also, we don't have any interaction with any hardware since
+ Glide is the layer beneath the driver.
+
+ Author:
+ Henrik Harmsen (hch@cd.chalmers.se or Henrik.Harmsen@erv.ericsson.se)
+
+ HISTORY
+ 1999-04-05
+ - First release for 3.9Pi
+
+ 1999-04-17
+ - Soft link to libglide2x.so instead of addition to ModulePath
+ - Changed "EXTERN_MODULE" to EXTERN_MODULE
+ - Uses the "GlideDevice" option instead of the "BusID" line to select
+ which voodoo board to use.
+ - Manpage updates
+
+ 1999-06-25
+ - Modify glideSetup to not register the driver when libglide2x.so cannot
+ be loaded, and to return appropriate error codes when it fails.
+ - Prevent GLIDEFreeScreen() from crashing if called early.
+
+ 1999-08-22
+ - Minor fixes.
+
+ TODO
+ * Support for adjusting gamma correction.
+ * Support for setting gamma individually for R,G,B when Glide 3 arrives
+ for Linux. This will allow me to get rid of that sick green tint my
+ voodoo2 board produces...
+ * Support static loading.
+*/
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glide/glide_driver.c,v 1.5 1999/08/28 09:01:04 dawes Exp $ */
+
+#include "xaa.h"
+#include "xf86Cursor.h"
+#include "colormapst.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "mipointer.h"
+#include "mibstore.h"
+#include "micmap.h"
+#include "xf86DDC.h"
+#ifdef DPMSExtension
+#include "globals.h"
+#define DPMS_SERVER
+#include "extensions/dpms.h"
+#endif
+#define PSZ 8 /* needed for cfb.h */
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb32.h"
+#include "xf86cmap.h"
+#include "shadowfb.h"
+
+#include <glide.h>
+
+#define TRUE 1
+#define FALSE 0
+#ifdef NULL
+#undef NULL
+#endif
+#define NULL 0
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+typedef signed char s8;
+typedef unsigned char u8;
+typedef signed short int s16;
+typedef unsigned short int u16;
+typedef signed long int s32;
+typedef unsigned long int u32;
+typedef u8 bool;
+
+/* Card-specific driver information */
+
+#define GLIDEPTR(p) ((GLIDEPtr)((p)->driverPrivate))
+
+
+typedef FxBool (*pgrSstQueryBoards_t)(GrHwConfiguration*);
+typedef void (*pgrGlideInit_t)(void);
+typedef void (*pgrSstSelect_t)(int which_sst);
+typedef FxBool (*pgrSstWinOpen_t)(FxU32, GrScreenResolution_t, GrScreenRefresh_t,
+ GrColorFormat_t, GrOriginLocation_t, int, int);
+typedef void (*pgrRenderBuffer_t)(GrBuffer_t);
+typedef void (*pgrClipWindow_t)(FxU32, FxU32, FxU32, FxU32);
+typedef void (*pgrBufferClear_t)(GrColor_t, GrAlpha_t, FxU16);
+typedef FxBool (*pgrLfbLock_t)(GrLock_t, GrBuffer_t, GrLfbWriteMode_t, GrOriginLocation_t,
+ FxBool, GrLfbInfo_t*);
+typedef FxBool (*pgrLfbUnlock_t)(GrLock_t, GrBuffer_t);
+typedef void (*pgrGlideShutdown_t)(void);
+
+
+#if defined(GLIDE3) && defined(GLIDE3_ALPHA)
+typedef FxBool (*pgrLfbWriteRegion_t)(GrBuffer_t, FxU32, FxU32, GrLfbSrcFmt_t,
+ FxU32, FxU32, FxBool, FxI32, void*);
+#else
+typedef FxBool (*pgrLfbWriteRegion_t)(GrBuffer_t, FxU32, FxU32, GrLfbSrcFmt_t,
+ FxU32, FxU32, FxI32, void*);
+#endif
+
+
+typedef struct {
+ u8* ShadowPtr;
+ u32 ShadowPitch;
+ u32 SST_Index;
+ CloseScreenProcPtr CloseScreen;
+ Bool Blanked;
+ u32 grRefreshRate;
+ u32 grResolution;
+ Bool OnAtExit;
+ Bool GlideInitiated;
+ EntityInfoPtr pEnt;
+} GLIDERec, *GLIDEPtr;
+
+static pgrSstQueryBoards_t pgrSstQueryBoards;
+static pgrGlideInit_t pgrGlideInit;
+static pgrSstSelect_t pgrSstSelect;
+static pgrSstWinOpen_t pgrSstWinOpen;
+static pgrRenderBuffer_t pgrRenderBuffer;
+static pgrClipWindow_t pgrClipWindow;
+static pgrBufferClear_t pgrBufferClear;
+static pgrLfbLock_t pgrLfbLock;
+static pgrLfbUnlock_t pgrLfbUnlock;
+static pgrGlideShutdown_t pgrGlideShutdown;
+static pgrLfbWriteRegion_t pgrLfbWriteRegion;
+
+static void GLIDEIdentify(int flags);
+static Bool GLIDEProbe(DriverPtr drv, int flags);
+static Bool GLIDEPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool GLIDEScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv);
+static Bool GLIDEEnterVT(int scrnIndex, int flags);
+static void GLIDELeaveVT(int scrnIndex, int flags);
+static Bool GLIDECloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool GLIDESaveScreen(ScreenPtr pScreen, Bool unblank);
+static void GLIDEFreeScreen(int scrnIndex, int flags);
+static void GLIDERefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+static Bool GLIDEModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static void GLIDERestore(ScrnInfoPtr pScrn, Bool Closing);
+static void GLIDERefreshAll(ScrnInfoPtr pScrn);
+
+#ifdef DPMSExtension
+static void GLIDEDisplayPowerManagementSet(ScrnInfoPtr pScrn,
+ int PowerManagementMode,
+ int flags);
+#endif
+
+
+static int LoadGlide(void);
+
+#define VERSION 4000
+#define GLIDE_NAME "GLIDE"
+#define GLIDE_DRIVER_NAME "glide"
+#define GLIDE_MAJOR_VERSION 1
+#define GLIDE_MINOR_VERSION 0
+#define GLIDE_PATCHLEVEL 0
+
+/*
+ * This contains the functions needed by the server after loading the
+ * driver module. It must be supplied, and gets added the driver list by
+ * the Module Setup funtion in the dynamic case. In the static case a
+ * reference to this is compiled in, and this requires that the name of
+ * this DriverRec be an upper-case version of the driver name.
+ */
+
+DriverRec GLIDE = {
+ VERSION,
+ "driver for Glide devices (Voodoo cards)",
+ GLIDEIdentify,
+ GLIDEProbe,
+ NULL,
+ 0
+};
+
+typedef enum {
+ OPTION_ON_AT_EXIT,
+ OPTION_GLIDEDEVICE
+} GLIDEOpts;
+
+static OptionInfoRec GLIDEOptions[] = {
+ { OPTION_ON_AT_EXIT, "OnAtExit", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_GLIDEDEVICE, "GlideDevice", OPTV_INTEGER, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+/* Supported chipsets */
+static SymTabRec GLIDEChipsets[] = {
+ { 0, "Voodoo" },
+ {-1, NULL }
+};
+
+
+/*
+ * List of symbols from other modules that this module references. This
+ * list is used to tell the loader that it is OK for symbols here to be
+ * unresolved providing that it hasn't been told that they haven't been
+ * told that they are essential via a call to xf86LoaderReqSymbols() or
+ * xf86LoaderReqSymLists(). The purpose is this is to avoid warnings about
+ * unresolved symbols that are not required.
+ */
+
+static const char *cfbSymbols[] = {
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb32ScreenInit",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(glideSetup);
+
+static XF86ModuleVersionInfo glideVersRec =
+{
+ "glide",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ GLIDE_MAJOR_VERSION, GLIDE_MINOR_VERSION, GLIDE_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+XF86ModuleData glideModuleData = { &glideVersRec, glideSetup, NULL };
+
+static pointer
+glideSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+ pointer ret;
+ int errmaj2 = 0, errmin2 = 0;
+
+ /* This module should be loaded only once, but check to be sure. */
+
+ if (!setupDone)
+ {
+ /*
+ * Modules that this driver always requires may be loaded here
+ * by calling LoadSubModule().
+ */
+
+ ret = LoadSubModule(module, "glide2x", NULL, NULL, EXTERN_MODULE, NULL,
+ &errmaj2, &errmin2);
+ if (!ret)
+ {
+ xf86Msg(X_ERROR, "Glide driver:\n"
+"\n"
+"Could not load the shared library file for Glide: \"libglide2x.so\"! \n"
+"\n"
+"You need to have Glide installed to run the glide driver for XFree86.\n"
+"Also, you need to tell XFree86 where the libglide2x.so file is placed\n"
+"by making a soft link in the /usr/X11R6/lib/modules directory that points\n"
+"to the libglide2x.so file. For example (if your libglide2x.so file is in\n"
+"/usr/lib):\n"
+"\n"
+" # ln -s /usr/lib/libglide2x.so /usr/X11R6/lib/modules\n"
+"\n"
+"\n");
+ if (errmaj)
+ *errmaj = LDR_NOSUBENT;
+ if (errmin)
+ *errmin = errmaj2;
+ return NULL;
+ }
+
+ if (!LoadGlide()) {
+ if (errmaj)
+ *errmaj = LDR_MODSPECIFIC;
+ if (errmin)
+ *errmin = 0;
+ return NULL;
+ }
+
+ setupDone = TRUE;
+ xf86AddDriver(&GLIDE, module, 0);
+
+ /*
+ * Tell the loader about symbols from other modules that this module
+ * might refer to.
+ */
+ LoaderRefSymLists(cfbSymbols, shadowSymbols, NULL);
+
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer)1;
+ }
+ else
+ {
+ if (errmaj)
+ *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+#endif /* XFree86LOADER */
+
+static Bool
+GLIDEGetRec(ScrnInfoPtr pScrn)
+{
+ /*
+ * Allocate an GLIDERec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(GLIDERec), 1);
+
+ /* Initialize it */
+ /* No init here yet */
+ return TRUE;
+}
+
+static void
+GLIDEFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+
+/* Mandatory */
+static void
+GLIDEIdentify(int flags)
+{
+ xf86PrintChipsets(GLIDE_NAME, "driver for Glide devices (Voodoo cards)", GLIDEChipsets);
+}
+
+
+/* Mandatory */
+static Bool
+GLIDEProbe(DriverPtr drv, int flags)
+{
+ GrHwConfiguration hw;
+ int i, sst, r;
+ GDevPtr *devList = NULL;
+ GDevPtr dev = NULL;
+ int numdevList;
+ Bool foundScreen = FALSE;
+ ScrnInfoPtr pScrn;
+ int GlideDevice;
+
+ if ((numdevList = xf86MatchDevice(GLIDE_DRIVER_NAME, &devList)) <= 0)
+ return FALSE;
+
+ r = pgrSstQueryBoards(&hw);
+ if (!r)
+ {
+ xf86Msg(X_ERROR, "GLIDEProbe(): Error calling pgrSstQueryBoards!\n");
+ goto cleanup;
+ }
+
+
+ /* hw.num_sst : number of Glide boards available */
+ for (sst = 0; sst < hw.num_sst; sst++)
+ {
+ for (i = 0; i < numdevList; i++)
+ {
+ dev = devList[i];
+ GlideDevice = xf86SetIntOption(dev->options, "GlideDevice", 0);
+ if (GlideDevice == sst)
+ {
+ int entity;
+ /* Match */
+ /* Allocate a ScrnInfoRec and claim the slot */
+ pScrn = xf86AllocateScreen(drv, 0);
+
+ /* I'm not going to "claim" the glide device since no other driver than this can drive it */
+ /* (A glide device is not a PCI device) */
+ /* XXX Need to see how this fits in with the new RAC */
+
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = GLIDE_DRIVER_NAME;
+ pScrn->name = GLIDE_NAME;
+ pScrn->Probe = GLIDEProbe;
+ pScrn->PreInit = GLIDEPreInit;
+ pScrn->ScreenInit = GLIDEScreenInit;
+ pScrn->EnterVT = GLIDEEnterVT;
+ pScrn->LeaveVT = GLIDELeaveVT;
+ pScrn->FreeScreen = GLIDEFreeScreen;
+ pScrn->driverPrivate = (void*)sst;
+ /*
+ * XXX This is a hack because don't have the PCI info. Set it as
+ * an ISA entity with no resources.
+ */
+ entity = xf86ClaimIsaSlot(drv, 0, dev, TRUE);
+ xf86ConfigActiveIsaEntity(pScrn, entity, NULL, NULL, NULL, NULL, NULL,
+ NULL);
+ foundScreen = TRUE;
+ break;
+ }
+ }
+ }
+
+cleanup:
+ if (devList) xfree(devList);
+ return foundScreen;
+}
+
+
+
+
+/* Mandatory */
+static Bool
+GLIDEPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ GLIDEPtr pGlide;
+ MessageType from;
+ int i;
+ ClockRangePtr clockRanges;
+ char *mod = NULL;
+ const char *reqSym = NULL;
+ int sst;
+
+ /* Check the number of entities, and fail if it isn't one. */
+ if (pScrn->numEntities != 1)
+ return FALSE;
+
+ sst = (int)(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ if (!xf86SetDepthBpp(pScrn, 16, 0, 0, Support32bppFb)) {
+ return FALSE;
+ }
+
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 16:
+ case 24:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ xf86PrintDepthBpp(pScrn);
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+
+ /* Set the default visual. */
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ }
+ /* We don't support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+
+ /* Set default gamma */
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+
+ /* We use a programamble clock */
+ pScrn->progClock = TRUE;
+
+ /* Allocate the GLIDERec driverPrivate */
+ if (!GLIDEGetRec(pScrn)) {
+ return FALSE;
+ }
+
+ pGlide = GLIDEPTR(pScrn);
+
+ /* Get the entity */
+ pGlide->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, GLIDEOptions);
+
+ pGlide->OnAtExit = FALSE;
+ from = X_DEFAULT;
+ if (xf86GetOptValBool(GLIDEOptions, OPTION_ON_AT_EXIT, &(pGlide->OnAtExit)))
+ from = X_CONFIG;
+
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Voodoo card will be %s when exiting server.\n",
+ pGlide->OnAtExit ? "ON" : "OFF");
+
+ pGlide->SST_Index = sst;
+
+ /*
+ * If the user has specified the amount of memory in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pGlide->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pGlide->pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else {
+ pScrn->videoRam = 8192; /* It's just virtual framebuffer anyway so let's say we have an 8MB sized framebuffer */
+ from = X_PROBED;
+ }
+#if 0
+ xf86DrvMsg(pScrn->scrnIndex, from, "Virtual video RAM: %d kB\n",
+ pScrn->videoRam);
+#endif
+
+ /* Set up clock ranges so that the xf86ValidateModes() function will not fail a mode because of the clock
+ requirement (because we don't use the clock value anyway) */
+ clockRanges = xnfalloc(sizeof(ClockRange));
+ clockRanges->next = NULL;
+ clockRanges->minClock = 10000;
+ clockRanges->maxClock = 300000;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = TRUE;
+
+ /* Select valid modes from those available */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, 256, 2048,
+ pScrn->bitsPerPixel, 128, 2048,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pScrn->videoRam * 1024,
+ LOOKUP_BEST_REFRESH);
+
+ if (i == -1) {
+ GLIDEFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ /* If no valid modes, return */
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ GLIDEFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Do some checking, we will not support a virtual framebuffer larger than
+ the visible screen. */
+ if (pScrn->currentMode->HDisplay != pScrn->virtualX ||
+ pScrn->currentMode->VDisplay != pScrn->virtualY ||
+ pScrn->displayWidth != pScrn->virtualX)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Virtual size doesn't equal display size. Forcing virtual size to equal display size.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "(Virtual size: %dx%d, Display size: %dx%d)\n", pScrn->virtualX, pScrn->virtualY,
+ pScrn->currentMode->HDisplay, pScrn->currentMode->VDisplay);
+ /* I'm not entirely sure this is "legal" but I hope so. */
+ pScrn->virtualX = pScrn->currentMode->HDisplay;
+ pScrn->virtualY = pScrn->currentMode->VDisplay;
+ pScrn->displayWidth = pScrn->virtualX;
+ }
+
+ /* TODO: Note: If I return FALSE right here, the server will not restore the console correctly,
+ forcing a reboot. Must find that. (valid for 3.9Pi) */
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 16:
+ mod = "cfb16";
+ reqSym = "cfb16ScreenInit";
+ break;
+ case 32:
+ mod = "cfb32";
+ reqSym = "cfb32ScreenInit";
+ break;
+ }
+ if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ GLIDEFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymbols(reqSym, NULL);
+
+ /* Load the shadow framebuffer */
+ if (!xf86LoadSubModule(pScrn, "shadowfb")) {
+ GLIDEFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+
+ return TRUE;
+}
+
+
+/* Mandatory */
+/* This gets called at the start of each server generation */
+static Bool
+GLIDEScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn;
+ GLIDEPtr pGlide;
+ int ret;
+ VisualPtr visual;
+
+ /*
+ * First get the ScrnInfoRec
+ */
+ pScrn = xf86Screens[pScreen->myNum];
+
+ pGlide = GLIDEPTR(pScrn);
+
+ if (!GLIDEModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset the visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. Only TrueColor. */
+ if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+
+ pGlide->ShadowPitch = ((pScrn->virtualX * pScrn->bitsPerPixel >> 3) + 3) & ~3L;
+ pGlide->ShadowPtr = xnfalloc(pGlide->ShadowPitch * pScrn->virtualY);
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+ switch (pScrn->bitsPerPixel) {
+ case 16:
+ ret = cfb16ScreenInit(pScreen, pGlide->ShadowPtr,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 32:
+ ret = cfb32ScreenInit(pScreen, pGlide->ShadowPtr,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in GLIDEScreenInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ if (!ret)
+ return FALSE;
+
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBlackWhitePixels(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ /* Initialize software cursor.
+ Must precede creation of the default colormap */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ ShadowFBInit(pScreen, GLIDERefreshArea);
+
+#ifdef DPMSExtension
+ xf86DPMSInit(pScreen, GLIDEDisplayPowerManagementSet, 0);
+#endif
+
+ pScreen->SaveScreen = GLIDESaveScreen;
+
+ /* Wrap the current CloseScreen function */
+ pGlide->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = GLIDECloseScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+#if 0
+ LoaderCheckUnresolved(LD_RESOLV_NOW);
+ return FALSE;
+#endif
+
+ /* Done */
+ return TRUE;
+}
+
+
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ *
+ * We may wish to unmap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static Bool
+GLIDEEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ return GLIDEModeInit(pScrn, pScrn->currentMode);
+}
+
+/*
+ * This is called when VT switching away from the X server. Its job is
+ * to restore the previous (text) mode.
+ *
+ * We may wish to remap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static void
+GLIDELeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ GLIDERestore(pScrn, FALSE);
+}
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode. It should also unmap the video memory, and free
+ * any per-generation data allocated by the driver. It should finish
+ * by unwrapping and calling the saved CloseScreen function.
+ */
+
+/* Mandatory */
+static Bool
+GLIDECloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ GLIDEPtr pGlide = GLIDEPTR(pScrn);
+
+ GLIDERestore(pScrn, TRUE);
+ xfree(pGlide->ShadowPtr);
+
+ pScrn->vtSema = FALSE;
+
+ pScreen->CloseScreen = pGlide->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+
+/* Free up any persistent data structures */
+
+/* Optional */
+static void
+GLIDEFreeScreen(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ GLIDEPtr pGlide = GLIDEPTR(pScrn);
+ /*
+ * This only gets called when a screen is being deleted. It does not
+ * get called routinely at the end of a server generation.
+ */
+ if (pGlide && pGlide->ShadowPtr)
+ xfree(pGlide->ShadowPtr);
+ GLIDEFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Do screen blanking */
+/* Mandatory */
+static Bool
+GLIDESaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+ ScrnInfoPtr pScrn;
+ GLIDEPtr pGlide;
+
+ pScrn = xf86Screens[pScreen->myNum];
+ pGlide = GLIDEPTR(pScrn);
+ pGlide->Blanked = !unblank;
+ if (unblank)
+ GLIDERefreshAll(pScrn);
+ else
+ pgrBufferClear(0, 0, GR_ZDEPTHVALUE_FARTHEST);
+
+ return TRUE;
+}
+
+static Bool
+GLIDEModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ GLIDEPtr pGlide;
+ int r;
+ int width, height;
+ double refresh;
+ Bool match = FALSE;
+
+ pGlide = GLIDEPTR(pScrn);
+
+ if (mode->Flags & V_INTERLACE)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Interlaced modes not supported\n");
+ return FALSE;
+ }
+
+ width = mode->HDisplay;
+ height = mode->VDisplay;
+
+#if 0
+ ErrorF("mode->HDisplay = %d, pScrn->displayWidth = %d\n", mode->HDisplay, pScrn->displayWidth);
+ ErrorF("mode->VDisplay = %d, mode->HTotal = %d, mode->VTotal = %d\n",
+ mode->VDisplay, mode->HTotal, mode->VTotal);
+ ErrorF("mode->Clock = %d\n", mode->Clock);
+#endif
+
+ if (width == 640 && height == 480)
+ {
+ match = TRUE;
+ pGlide->grResolution = GR_RESOLUTION_640x480;
+ }
+ if (width == 800 && height == 600)
+ {
+ match = TRUE;
+ pGlide->grResolution = GR_RESOLUTION_800x600;
+ }
+ if (width == 960 && height == 720)
+ {
+ match = TRUE;
+ pGlide->grResolution = GR_RESOLUTION_960x720;
+ }
+ if (width == 1024 && height == 768)
+ {
+ match = TRUE;
+ pGlide->grResolution = GR_RESOLUTION_1024x768;
+ }
+ if (width == 1280 && height == 1024)
+ {
+ match = TRUE;
+ pGlide->grResolution = GR_RESOLUTION_1280x1024;
+ }
+ if (width == 1600 && height == 1200)
+ {
+ match = TRUE;
+ pGlide->grResolution = GR_RESOLUTION_1600x1200;
+ }
+
+ if (!match)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Selected width = %d and height = %d is not supported by glide\n", width, height);
+ return FALSE;
+ }
+
+ refresh = (mode->Clock * 1.0e3)/((double)(mode->HTotal) *
+ (double)(mode->VTotal));
+#if 0
+ ErrorF("Calculated refresh rate for mode is %.2fHz\n",refresh);
+#endif
+
+ /* The Glide header files indicate there are a rather large number of
+ refresh rates available. In practice, though, only 60, 75 and 85Hz
+ seem to be available. If we try using another refresh rate, glide
+ will default to 60Hz. */
+ pGlide->grRefreshRate = GR_REFRESH_60Hz;
+ if (refresh > 74.0) pGlide->grRefreshRate = GR_REFRESH_75Hz;
+ if (refresh > 84.0) pGlide->grRefreshRate = GR_REFRESH_85Hz;
+
+
+ /* Initialize the video card */
+ pgrGlideInit();
+ pgrSstSelect(pGlide->SST_Index);
+
+ r = pgrSstWinOpen(0,
+ pGlide->grResolution,
+ pGlide->grRefreshRate,
+ GR_COLORFORMAT_ARGB,
+ GR_ORIGIN_UPPER_LEFT,
+ 2, 0);
+ if (!r)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "grSstWinOpen returned %d. "
+ "You are probably trying to use a resolution that is not supported by your hardware.", r);
+ return FALSE;
+ }
+
+ pgrRenderBuffer(GR_BUFFER_FRONTBUFFER);
+ pgrClipWindow(0, 0, 1024, 768);
+ pgrBufferClear(0, 0, GR_ZDEPTHVALUE_FARTHEST);
+
+ if (!r)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not lock glide frame buffer\n");
+ return FALSE;
+ }
+
+ pGlide->Blanked = FALSE;
+ pGlide->GlideInitiated = TRUE;
+ return TRUE;
+}
+
+static void
+GLIDERestore(ScrnInfoPtr pScrn, Bool Closing)
+{
+ GLIDEPtr pGlide;
+
+ pGlide = GLIDEPTR(pScrn);
+
+ if (!(pGlide->GlideInitiated))
+ return;
+ pGlide->GlideInitiated = FALSE;
+ pGlide->Blanked = TRUE;
+ pgrBufferClear(0, 0, GR_ZDEPTHVALUE_FARTHEST);
+ if (!Closing || !(pGlide->OnAtExit))
+ pgrGlideShutdown();
+}
+
+
+#define GLIDE_FIND_FUNC(x,y) \
+ p##x = (p##x##_t)LoaderSymbol(y); \
+ if (!p##x) \
+ { \
+ xf86Msg(X_ERROR, "Could not find " y "() in libglide2x.so.\n"); \
+ return FALSE; \
+ }
+
+static int
+LoadGlide(void)
+{
+ GLIDE_FIND_FUNC(grSstQueryBoards, "grSstQueryBoards");
+ GLIDE_FIND_FUNC(grGlideInit, "grGlideInit");
+ GLIDE_FIND_FUNC(grSstSelect, "grSstSelect");
+ GLIDE_FIND_FUNC(grSstWinOpen, "grSstWinOpen");
+ GLIDE_FIND_FUNC(grRenderBuffer, "grRenderBuffer");
+ GLIDE_FIND_FUNC(grClipWindow, "grClipWindow");
+ GLIDE_FIND_FUNC(grBufferClear, "grBufferClear");
+ GLIDE_FIND_FUNC(grLfbLock, "grLfbLock");
+ GLIDE_FIND_FUNC(grLfbUnlock, "grLfbUnlock");
+ GLIDE_FIND_FUNC(grGlideShutdown, "grGlideShutdown");
+ GLIDE_FIND_FUNC(grLfbWriteRegion, "grLfbWriteRegion");
+ return TRUE;
+}
+
+static void
+GLIDERefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ GLIDEPtr pGlide = GLIDEPTR(pScrn);
+ int Bpp;
+ unsigned char *src;
+ s32 x1, x2;
+
+ if (pGlide->Blanked) return;
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ if (pScrn->bitsPerPixel == 16)
+ {
+ while(num--) {
+ /* We align to an even number of pixels so we won't have to copy
+ half-words over the PCI bus */
+ x1 = (pbox->x1) & ~1;
+ x2 = (pbox->x2 + 1) & ~1;
+ src = pGlide->ShadowPtr + (pbox->y1 * pGlide->ShadowPitch) +
+ (x1 * Bpp);
+#if defined(GLIDE3) && defined(GLIDE3_ALPHA)
+ pgrLfbWriteRegion(GR_BUFFER_FRONTBUFFER, x1, pbox->y1,
+ GR_LFB_SRC_FMT_565, x2-x1, pbox->y2-pbox->y1, FALSE,
+ pGlide->ShadowPitch, src);
+#else
+ pgrLfbWriteRegion(GR_BUFFER_FRONTBUFFER, x1, pbox->y1,
+ GR_LFB_SRC_FMT_565, x2-x1, pbox->y2-pbox->y1,
+ pGlide->ShadowPitch, src);
+#endif
+ pbox++;
+ }
+ }
+ else
+ {
+ while(num--) {
+ x1 = pbox->x1;
+ x2 = pbox->x2;
+ src = pGlide->ShadowPtr + (pbox->y1 * pGlide->ShadowPitch) +
+ (pbox->x1 * Bpp);
+#if defined(GLIDE3) && defined(GLIDE3_ALPHA)
+ pgrLfbWriteRegion(GR_BUFFER_FRONTBUFFER, x1, pbox->y1,
+ GR_LFB_SRC_FMT_888, x2-x1, pbox->y2-pbox->y1, FALSE,
+ pGlide->ShadowPitch, src);
+#else
+ pgrLfbWriteRegion(GR_BUFFER_FRONTBUFFER, x1, pbox->y1,
+ GR_LFB_SRC_FMT_888, x2-x1, pbox->y2-pbox->y1,
+ pGlide->ShadowPitch, src);
+#endif
+ pbox++;
+ }
+ }
+}
+
+
+/*
+ * GLIDEDisplayPowerManagementSet --
+ *
+ * Sets VESA Display Power Management Signaling (DPMS) Mode.
+ */
+#ifdef DPMSExtension
+static void
+GLIDEDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
+ int flags)
+{
+ GLIDEPtr pGlide = GLIDEPTR(pScrn);
+ static int oldmode = -1;
+
+#if 0
+ ErrorF("GLIDEDisplayPowerManagementSet: %d\n", PowerManagementMode);
+#endif
+
+ if (oldmode == DPMSModeOff && PowerManagementMode != DPMSModeOff)
+ {
+ GLIDEModeInit(pScrn, pScrn->currentMode);
+ }
+
+ switch (PowerManagementMode)
+ {
+ case DPMSModeOn:
+ /* Screen: On; HSync: On, VSync: On */
+ pGlide->Blanked = FALSE;
+ GLIDERefreshAll(pScrn);
+ break;
+ case DPMSModeStandby:
+ case DPMSModeSuspend:
+ pGlide->Blanked = TRUE;
+ pgrBufferClear(0, 0, GR_ZDEPTHVALUE_FARTHEST);
+ break;
+ case DPMSModeOff:
+ GLIDERestore(pScrn, FALSE);
+ break;
+ }
+ oldmode = PowerManagementMode;
+}
+#endif
+
+
+static void
+GLIDERefreshAll(ScrnInfoPtr pScrn)
+{
+ BoxRec box;
+ box.x1 = 0;
+ box.x2 = pScrn->virtualX;
+ box.y1 = 0;
+ box.y2 = pScrn->virtualY;
+ GLIDERefreshArea(pScrn, 1, &box);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/DRI.txt b/xc/programs/Xserver/hw/xfree86/drivers/glint/DRI.txt
new file mode 100644
index 000000000..5e175996e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/DRI.txt
@@ -0,0 +1,408 @@
+
+ GLINT State Transition Strategy
+
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is granted to make and distribute verbatim copies
+of this document provided the copyright notice and this permission
+notice are preserved on all copies.
+
+$XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/DRI.txt,v 1.1 1999/06/14 07:31:50 dawes Exp $
+$PI: xc/programs/Xserver/hw/xfree86/drivers/glint/DRI.txt,v 1.6 1999/05/27 03:46:29 jens Exp $
+
+GLINT State Transition Strategy
+
+Direct Rendering requires a coordinated method of state management
+across all drivers accessing this device. This document defines the
+expected behavior of all drivers participating in direct rendering with
+this device.
+
+Currently only the GMX2000 supports direct rendering.
+
+
+Section 1) State Transition Types
+
+The direct rendering document entitled "state-mgmt.txt" gives a device
+independent overview on the different types of state transitions. This
+section gives a more detailed description of GLINT specific hardware state.
+
+No context switch--no state saves or restores will be done for transitions,
+however the device can be busy executing commands from previous accesses to
+the device.
+
+X context switch--the intersection of 2D and 3D state will be saved
+and restored. This is the state marked as DDX/3DClient in Appendix A.
+The device will be synced and idle after this switch.
+
+3D context switch--all 3D state will be saved and restored. 3D state is
+defined as all registered owned by the 3DClient driver. See Appendix A
+for more details. The device will be synced and idle after this switch.
+
+The registers owned by the DRM kernel module and submodules are not
+managed by context switches.
+
+
+Section 2) VT Switching and DGA Access
+
+VT Switching away from the X Server or client access to the device
+framebuffer via DGA require the device to be locked away from 3D direct
+rendering accesses. The X Server will hold the lock on behalf of these
+services until access is restored.
+
+
+Section 3) Potential Optimizations
+
+Lighten the number of registers required for context switches by using a
+mechanism to determine whether stipple or pattern registers need to be
+saved/restored. This optimization has not been done for the initial
+direct rendering infrastructure sample implementation.
+
+
+Appendix A: GMX2000 Register Ownership
+
+driver column contains:
+ DDX - DDX driver manages register
+ DRM - DRM or DRM subdriver manages register
+ 3DClient - 3D Client Driver manges register
+ DDX/3DClient, DDX/DRM, 3DClient/DRM - register access is shared
+
+if the RO (read only) column is marked with a *, then no writes are
+permitted to this register, and thus no drivers own it.
+
+primary and secondary columns contain the default values after
+initialization. primary is the master rasterizer, secondary is the
+slave rasterizer.
+
+
+Name offset primary secondary RO driver
+------------------------------------------------------------------------------
+ResetStatus o=0000 0x00000000 0x00000000 DDX/DRM
+IntEnable o=0008 0x00000000 0x00000000 DRM
+IntFlags o=0010 0x00000000 0x00000018 DRM
+InFIFOSpace o=0018 0x00000000 0x00000021 *
+OutFIFOWords o=0020 0x00000000 0x00000000 *
+DMAAddress o=0028 0x00000000 0x00000000 DRM
+DMACount o=0030 0x00000000 0x00000000 DRM
+ErrorFlags o=0038 0x00000000 0x00000002 DRM
+VClkCtl o=0040 0x00000000 0x00000000 DDX
+TestRegister o=0048 0x00000000 0x00000000 DDX
+Aperture0 o=0050 0x00000000 0x00000000 DDX
+Aperture1 o=0058 0x00000000 0x00000000 DDX
+DMAControl o=0060 0x00000000 0x00000000 DRM
+FIFODis o=0068 0x00000000 0x00000001 DDX
+LBMemoryCtl o=1000 0x00000000 0x770883ff DDX
+LBMemoryEDO o=1008 0x00000000 0x77080000 DDX
+FBMemoryCtl o=1800 0x00000000 0x63c00800 DDX
+FBModeSel o=1808 0x00000000 0x00000907 DDX
+FBGCWrMask o=1810 0x00000000 0xffffffff *
+FBGCColorLower o=1818 0x00000000 0x00828282 *
+FBTXMemCtl o=1820 0x00000000 0x00000002 DDX
+FBWrMask o=1830 0x00000000 0xffffffff *
+FBGCColorUpper o=1838 0x00000000 0x00828282 *
+VTGHLimit o=3000 0x00000000 0x000000c8 DDX
+VTGHSyncStart o=3008 0x00ffffff 0x00000006 DDX
+VTGHSyncEnd o=3010 0x00000000 0x00000016 DDX
+VTGHBlankEnd o=3018 0x00ffffff 0x00000028 DDX
+VTGVLimit o=3020 0x00000000 0x000001fb DDX
+VTGVSyncStart o=3028 0x00ffffff 0x00000004 DDX
+VTGVSyncEnd o=3030 0x00000000 0x0000000a DDX
+VTGVBlankEnd o=3038 0x00ffffff 0x0000001b DDX
+VTGHGateStart o=3040 0x00000000 0x00000027 DDX
+VTGHGateEnd o=3048 0x00ffffff 0x000000c7 DDX
+VTGVGateStart o=3050 0x00000000 0x0000001a DDX
+VTGVGateEnd o=3058 0x00ffffff 0x0000001b DDX
+VTGPolarity o=3060 0x00000000 0x000000ba DDX
+VTGFrameRowAddr o=3068 0x00ffffff 0x00000000 DDX
+VTGVLineNumber o=3070 0x00000000 0x00000079 DDX
+VTGSerialClk o=3078 0x00ffffff 0x00000002 DDX
+VTGModeCtl o=3080 0x00000000 0x00000000 DDX
+GInFIFOSpace o=0018 0x00000000 *
+GDMAAddress o=0028 0x00000000 DRM
+GDMACount o=0030 0x00000000 DRM
+GDMAControl o=0060 0x00000000 DRM
+GOutDMA o=0080 0x00000000 DRM
+GOutDMACount o=0088 0x00000000 DRM
+GResetStatus o=0800 0x00000000 DRM
+GIntEnable o=0808 0x00000000 DRM
+GIntFlags o=0810 0x00000000 DRM
+GErrorFlags o=0838 0x00000000 DRM
+GTestRegister o=0848 0x00000000 DDX
+GFIFODis o=0868 0x00000000 DDX
+GChipConfig o=0870 0x00000000 DDX
+GCSRAperture o=0878 0x00000000 DDX
+GPageTableAddr o=0c00 0x00000000 DRM
+GPageTableLength o=0c08 0x00000000 DRM
+GDelayTimer o=0c38 0x00000000 DRM
+GCommandMode o=0c40 0x00000000 DRM
+GCommandIntEnable o=0c48 0x00000000 DRM
+GCommandIntFlags o=0c50 0x00000000 DRM
+GCommandErrorFlags o=0c58 0x00000000 DRM
+GCommandStatus o=0c60 0x00000000 *
+GCommandFaultingAddr o=0c68 0x00000000 *
+GVertexFaultingAddr o=0c70 0x00000000 *
+GWriteFaultingAddr o=0c88 0x00000000 *
+GFeedbackSelectCount o=0c98 0x00000000 *
+GGammaProcessorMode o=0cb8 0x00000000 DDX
+GVGAShadow o=0d00 0x00000000 DDX
+GMultGLINTAperture o=0d08 0x00000000 DDX
+GMultGLINT1 o=0d10 0x00000000 DDX
+GMultGLINT2 o=0d18 0x00000000 DDX
+StartXDom t=0000 undefined undefined DDX/3DClient
+dXDom t=0001 undefined undefined DDX/3DClient
+StartXSub t=0002 undefined undefined DDX/3DClient
+dXSub t=0003 undefined undefined DDX/3DClient
+StartY t=0004 undefined undefined DDX/3DClient
+dY t=0005 undefined undefined DDX/3DClient
+GLINTCount t=0006 undefined undefined DDX/3DClient
+PointTable0 t=0010 undefined undefined DDX/3DClient
+PointTable1 t=0011 undefined undefined DDX/3DClient
+PointTable2 t=0012 undefined undefined DDX/3DClient
+PointTable3 t=0013 undefined undefined DDX/3DClient
+RasterizerMode t=0014 undefined undefined DDX/3DClient
+YLimits t=0015 undefined undefined DDX/3DClient
+ScanLineOwnership t=0016 0x00000001 0x00000005 DDX
+PixelSize t=0018 undefined undefined DDX/3DClient
+ScissorMode t=0030 undefined undefined DDX/3DClient
+ScissorMinXY t=0031 undefined undefined DDX/3DClient
+ScissorMaxXY t=0032 undefined undefined DDX/3DClient
+ScreenSize t=0033 undefined undefined DDX/3DClient
+AreaStippleMode t=0034 undefined undefined DDX/3DClient
+LineStippleMode t=0035 undefined undefined DDX/3DClient
+LoadLineStippleCounters t=0036 undefined undefined DDX/3DClient
+WindowOrigin t=0039 undefined undefined DDX/3DClient
+AreaStipplePattern0 t=0040 undefined undefined DDX/3DClient
+AreaStipplePattern1 t=0041 undefined undefined DDX/3DClient
+AreaStipplePattern2 t=0042 undefined undefined DDX/3DClient
+AreaStipplePattern3 t=0043 undefined undefined DDX/3DClient
+AreaStipplePattern4 t=0044 undefined undefined DDX/3DClient
+AreaStipplePattern5 t=0045 undefined undefined DDX/3DClient
+AreaStipplePattern6 t=0046 undefined undefined DDX/3DClient
+AreaStipplePattern7 t=0047 undefined undefined DDX/3DClient
+AreaStipplePattern8 t=0048 undefined undefined DDX/3DClient
+AreaStipplePattern9 t=0049 undefined undefined DDX/3DClient
+AreaStipplePattern10 t=004a undefined undefined DDX/3DClient
+AreaStipplePattern11 t=004b undefined undefined DDX/3DClient
+AreaStipplePattern12 t=004c undefined undefined DDX/3DClient
+AreaStipplePattern13 t=004d undefined undefined DDX/3DClient
+AreaStipplePattern14 t=004e undefined undefined DDX/3DClient
+AreaStipplePattern15 t=004f undefined undefined DDX/3DClient
+AreaStipplePattern16 t=0050 undefined undefined DDX/3DClient
+AreaStipplePattern17 t=0051 undefined undefined DDX/3DClient
+AreaStipplePattern18 t=0052 undefined undefined DDX/3DClient
+AreaStipplePattern19 t=0053 undefined undefined DDX/3DClient
+AreaStipplePattern20 t=0054 undefined undefined DDX/3DClient
+AreaStipplePattern21 t=0055 undefined undefined DDX/3DClient
+AreaStipplePattern22 t=0056 undefined undefined DDX/3DClient
+AreaStipplePattern23 t=0057 undefined undefined DDX/3DClient
+AreaStipplePattern24 t=0058 undefined undefined DDX/3DClient
+AreaStipplePattern25 t=0059 undefined undefined DDX/3DClient
+AreaStipplePattern26 t=005a undefined undefined DDX/3DClient
+AreaStipplePattern27 t=005b undefined undefined DDX/3DClient
+AreaStipplePattern28 t=005c undefined undefined DDX/3DClient
+AreaStipplePattern29 t=005d undefined undefined DDX/3DClient
+AreaStipplePattern30 t=005e undefined undefined DDX/3DClient
+AreaStipplePattern31 t=005f undefined undefined DDX/3DClient
+RouterMode t=0108 undefined undefined DDX/3DClient
+TextureAddressMode t=0070 undefined undefined DDX/3DClient
+SStart t=0071 undefined undefined 3DClient
+dSdx t=0072 undefined undefined 3DClient
+dSdyDom t=0073 undefined undefined 3DClient
+TStart t=0074 undefined undefined 3DClient
+dTdx t=0075 undefined undefined 3DClient
+dTdyDom t=0076 undefined undefined 3DClient
+QStart t=0077 undefined undefined 3DClient
+dQdx t=0078 undefined undefined 3DClient
+dQdyDom t=0079 undefined undefined 3DClient
+LOD t=007a undefined undefined 3DClient
+dSdy t=007b undefined undefined 3DClient
+dTdy t=007c undefined undefined 3DClient
+dQdy t=007d undefined undefined 3DClient
+TextureReadMode t=0090 undefined undefined DDX/3DClient
+TextureFormat t=0091 undefined undefined 3DClient
+TextureCacheControl t=0092 undefined undefined 3DClient
+GLINTBorderColor t=0095 undefined undefined 3DClient
+TexelLUTIndex t=0098 undefined undefined 3DClient
+TexelLUTData t=0099 undefined undefined 3DClient
+TexelLUTAddress t=009a undefined undefined 3DClient
+TexelLUTTransfer t=009b undefined undefined 3DClient
+TextureFilterMode t=009c undefined undefined 3DClient
+TextureChromaUpper t=009d undefined undefined 3DClient
+TextureChromaLower t=009e undefined undefined 3DClient
+TxBaseAddr0 t=00a0 undefined undefined 3DClient
+TxBaseAddr1 t=00a1 undefined undefined 3DClient
+TxBaseAddr2 t=00a2 undefined undefined 3DClient
+TxBaseAddr3 t=00a3 undefined undefined 3DClient
+TxBaseAddr4 t=00a4 undefined undefined 3DClient
+TxBaseAddr5 t=00a5 undefined undefined 3DClient
+TxBaseAddr6 t=00a6 undefined undefined 3DClient
+TxBaseAddr7 t=00a7 undefined undefined 3DClient
+TxBaseAddr8 t=00a8 undefined undefined 3DClient
+TxBaseAddr9 t=00a9 undefined undefined 3DClient
+TxBaseAddr10 t=00aa undefined undefined 3DClient
+TxBaseAddr11 t=00ab undefined undefined 3DClient
+TexelLUT0 t=01d0 undefined undefined 3DClient
+TexelLUT1 t=01d1 undefined undefined 3DClient
+TexelLUT2 t=01d2 undefined undefined 3DClient
+TexelLUT3 t=01d3 undefined undefined 3DClient
+TexelLUT4 t=01d4 undefined undefined 3DClient
+TexelLUT5 t=01d5 undefined undefined 3DClient
+TexelLUT6 t=01d6 undefined undefined 3DClient
+TexelLUT7 t=01d7 undefined undefined 3DClient
+TexelLUT8 t=01d8 undefined undefined 3DClient
+TexelLUT9 t=01d9 undefined undefined 3DClient
+TexelLUT10 t=01da undefined undefined 3DClient
+TexelLUT11 t=01db undefined undefined 3DClient
+TexelLUT12 t=01dc undefined undefined 3DClient
+TexelLUT13 t=01dd undefined undefined 3DClient
+TexelLUT14 t=01de undefined undefined 3DClient
+TexelLUT15 t=01df undefined undefined 3DClient
+Texel0 t=00c0 undefined undefined 3DClient
+Texel1 t=00c1 undefined undefined 3DClient
+Texel2 t=00c2 undefined undefined 3DClient
+Texel3 t=00c3 undefined undefined 3DClient
+Texel4 t=00c4 undefined undefined 3DClient
+Texel5 t=00c5 undefined undefined 3DClient
+Texel6 t=00c6 undefined undefined 3DClient
+Texel7 t=00c7 undefined undefined 3DClient
+Interp0 t=00c8 undefined undefined 3DClient
+Interp1 t=00c9 undefined undefined 3DClient
+Interp2 t=00ca undefined undefined 3DClient
+Interp3 t=00cb undefined undefined 3DClient
+Interp4 t=00cc undefined undefined 3DClient
+TextureFilter t=00cd undefined undefined 3DClient
+TextureColorMode t=00d0 undefined undefined DDX/3DClient
+TextureEnvColor t=00d1 undefined undefined 3DClient
+FogMode t=00d2 undefined undefined DDX/3DClient
+FogColor t=00d3 undefined undefined 3DClient
+FStart t=00d4 undefined undefined 3DClient
+dFdx t=00d5 undefined undefined 3DClient
+dFdyDom t=00d6 undefined undefined 3DClient
+KsStart t=00d9 undefined undefined 3DClient
+dKsdx t=00da undefined undefined 3DClient
+dKsdyDom t=00db undefined undefined 3DClient
+KdStart t=00dc undefined undefined 3DClient
+dKdStart t=00dd undefined undefined 3DClient
+dKddyDom t=00de undefined undefined 3DClient
+RStart t=00f0 undefined undefined 3DClient
+dRdx t=00f1 undefined undefined 3DClient
+dRdyDom t=00f2 undefined undefined 3DClient
+GStart t=00f3 undefined undefined 3DClient
+dGdx t=00f4 undefined undefined 3DClient
+dGdyDom t=00f5 undefined undefined 3DClient
+BStart t=00f6 undefined undefined 3DClient
+dBdx t=00f7 undefined undefined 3DClient
+dBdyDom t=00f8 undefined undefined 3DClient
+AStart t=00f9 undefined undefined 3DClient
+dAdx t=00fa undefined undefined 3DClient
+dAdyDom t=00fb undefined undefined 3DClient
+ColorDDAMode t=00fc undefined undefined DDX/3DClient
+ConstantColor t=00fd undefined undefined 3DClient
+GLINTColor t=00fe undefined undefined DDX/3DClient
+AlphaTestMode t=0100 undefined undefined DDX/3DClient
+AntialiasMode t=0101 undefined undefined DDX/3DClient
+AlphaBlendMode t=0102 undefined undefined DDX/3DClient
+ChromaUpper t=01e1 undefined undefined 3DClient
+ChromaLower t=01e2 undefined undefined 3DClient
+ChromaTestMode t=01e3 undefined undefined 3DClient
+DitherMode t=0103 undefined undefined DDX/3DClient
+FBSoftwareWriteMask t=0104 undefined undefined DDX/3DClient
+LogicalOpMode t=0105 undefined undefined DDX/3DClient
+FBWriteData t=0106 undefined undefined DDX/3DClient
+LBReadMode t=0110 undefined undefined DDX/3DClient
+ Partial Product bit 0-5 need by 3DClient
+LBReadFormat t=0111 set by DDX set by DDX DDX
+LBSourceOffset t=0112 undefined undefined DDX/3DClient
+LBStencil t=0115 undefined undefined *
+LBDepth t=0116 undefined undefined *
+LBWindowBase t=0117 undefined undefined DDX/3DClient
+LBWriteMode t=0118 undefined undefined DDX/3DClient
+LBWriteFormat t=0119 set by DDX set by DDX DDX
+TextureDownloadOffset t=011e undefined undefined DDX/3DClient
+LBWindowOffset t=011f undefined undefined DDX/3DClient
+GLINTWindow t=0130 undefined undefined DDX/3DClient
+StencilMode t=0131 undefined undefined DDX/3DClient
+StencilData t=0132 undefined undefined 3DClient
+GLINTStencil t=0133 undefined undefined 3DClient
+DepthMode t=0134 undefined undefined DDX/3DClient
+GLINTDepth t=0135 undefined undefined DDX/3DClient
+ZStartU t=0136 undefined undefined 3DClient
+ZStartL t=0137 undefined undefined 3DClient
+dZdxU t=0138 undefined undefined 3DClient
+dZdxL t=0139 undefined undefined 3DClient
+dZdyDomU t=013a undefined undefined 3DClient
+dZdyDomL t=013b undefined undefined 3DClient
+FastClearDepth t=013c undefined undefined 3DClient
+FBReadMode t=0150 set by DDX set by DDX DDX/3DClient
+ Partial Product bit 0-5 need by 3DClient
+LBReadFormat t=0111 set by DDX set by DDX DDX
+FBSourceOffset t=0151 undefined undefined DDX/3DClient
+FBPixelOffset t=0152 undefined undefined DDX/3DClient
+FBWindowBase t=0156 undefined undefined DDX/3DClient
+FBWriteMode t=0157 undefined undefined DDX/3DClient
+FBHardwareWriteMask t=0158 undefined undefined DDX/3DClient
+FBBlockColor t=0159 undefined undefined DDX/3DClient
+PatternRamMode t=015f undefined undefined DDX/3DClient
+PatternRamData0 t=0160 undefined undefined DDX/3DClient
+PatternRamData1 t=0161 undefined undefined DDX/3DClient
+PatternRamData2 t=0162 undefined undefined DDX/3DClient
+PatternRamData3 t=0163 undefined undefined DDX/3DClient
+PatternRamData4 t=0164 undefined undefined DDX/3DClient
+PatternRamData5 t=0165 undefined undefined DDX/3DClient
+PatternRamData6 t=0166 undefined undefined DDX/3DClient
+PatternRamData7 t=0167 undefined undefined DDX/3DClient
+PatternRamData8 t=0168 undefined undefined DDX/3DClient
+PatternRamData9 t=0169 undefined undefined DDX/3DClient
+PatternRamData10 t=016a undefined undefined DDX/3DClient
+PatternRamData11 t=016b undefined undefined DDX/3DClient
+PatternRamData12 t=016c undefined undefined DDX/3DClient
+PatternRamData13 t=016d undefined undefined DDX/3DClient
+PatternRamData14 t=016e undefined undefined DDX/3DClient
+PatternRamData15 t=016f undefined undefined DDX/3DClient
+PatternRamData16 t=0170 undefined undefined DDX/3DClient
+PatternRamData17 t=0171 undefined undefined DDX/3DClient
+PatternRamData18 t=0172 undefined undefined DDX/3DClient
+PatternRamData19 t=0173 undefined undefined DDX/3DClient
+PatternRamData20 t=0174 undefined undefined DDX/3DClient
+PatternRamData21 t=0175 undefined undefined DDX/3DClient
+PatternRamData22 t=0176 undefined undefined DDX/3DClient
+PatternRamData23 t=0177 undefined undefined DDX/3DClient
+PatternRamData24 t=0178 undefined undefined DDX/3DClient
+PatternRamData25 t=0179 undefined undefined DDX/3DClient
+PatternRamData26 t=017a undefined undefined DDX/3DClient
+PatternRamData27 t=017b undefined undefined DDX/3DClient
+PatternRamData28 t=017c undefined undefined DDX/3DClient
+PatternRamData29 t=017d undefined undefined DDX/3DClient
+PatternRamData30 t=017e undefined undefined DDX/3DClient
+PatternRamData31 t=017f undefined undefined DDX/3DClient
+FBBlockColorU t=018d undefined undefined DDX/3DClient
+FBBlockColorL t=018e undefined undefined DDX/3DClient
+FilterMode t=0180 undefined undefined DDX/3DClient
+StatisticMode t=0181 undefined undefined DDX/3DClient
+MinRegion t=0182 undefined undefined 3DClient
+MaxRegion t=0183 undefined undefined 3DClient
+KsRStart t=0190 undefined undefined 3DClient
+dKsRdx t=0191 undefined undefined 3DClient
+dKsRdyDom t=0192 undefined undefined 3DClient
+KsGStart t=0193 undefined undefined 3DClient
+dKsGdx t=0194 undefined undefined 3DClient
+dKsGdyDom t=0195 undefined undefined 3DClient
+KsBStart t=0196 undefined undefined 3DClient
+dKsBdx t=0197 undefined undefined 3DClient
+dKsBdyDom t=0198 undefined undefined 3DClient
+KdRStart t=01a0 undefined undefined 3DClient
+dKdRdx t=01a1 undefined undefined 3DClient
+dKdRdyDom t=01a2 undefined undefined 3DClient
+KdGStart t=01a3 undefined undefined 3DClient
+dKdGdx t=01a4 undefined undefined 3DClient
+dKdGdyDom t=01a5 undefined undefined 3DClient
+KdBStart t=01a6 undefined undefined 3DClient
+dKdBdx t=01a7 undefined undefined 3DClient
+dKdBdyDom t=01a8 undefined undefined 3DClient
+
+All Gamma State is undefined and owned by 3DClient driver except for:
+
+BroadcastMask o=026f 0x00000003 DDX/3DClient
+
+All TI RAMDAC State is owned by DDX driver.
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/IBMramdac.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/IBMramdac.c
new file mode 100644
index 000000000..2a41fab89
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/IBMramdac.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright 1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * glintOutIBMRGBIndReg() and glintInIBMRGBIndReg() are used to access
+ * the indirect IBM RAMDAC registers only.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/IBMramdac.c,v 1.6 1999/02/12 22:52:02 hohndel Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "IBM.h"
+#include "glint_regs.h"
+#include "glint.h"
+
+#define IBMRGB_WRITE_ADDR 0x4000
+#define IBMRGB_RAMDAC_DATA 0x4008
+#define IBMRGB_PIXEL_MASK 0x4010
+#define IBMRGB_READ_ADDR 0x4018
+#define IBMRGB_INDEX_LOW 0x4020
+#define IBMRGB_INDEX_HIGH 0x4028
+#define IBMRGB_INDEX_DATA 0x4030
+#define IBMRGB_INDEX_CONTROL 0x4038
+
+void
+glintOutIBMRGBIndReg(ScrnInfoPtr pScrn,
+ CARD32 reg, unsigned char mask, unsigned char data)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ unsigned char tmp = 0x00;
+
+ GLINT_SLOW_WRITE_REG((reg>>8) & 0xff, IBMRGB_INDEX_HIGH);
+ GLINT_SLOW_WRITE_REG (reg & 0xFF, IBMRGB_INDEX_LOW);
+
+ if (mask != 0x00)
+ tmp = GLINT_READ_REG (IBMRGB_INDEX_DATA) & mask;
+
+ GLINT_SLOW_WRITE_REG (tmp | data, IBMRGB_INDEX_DATA);
+}
+
+unsigned char
+glintInIBMRGBIndReg (ScrnInfoPtr pScrn, CARD32 reg)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ unsigned char ret;
+
+ GLINT_SLOW_WRITE_REG(reg & 0xFF, IBMRGB_INDEX_LOW);
+ GLINT_SLOW_WRITE_REG((reg>>8) & 0xff, IBMRGB_INDEX_HIGH);
+ ret = GLINT_READ_REG(IBMRGB_INDEX_DATA);
+ return (ret);
+}
+
+void
+glintIBMWriteAddress (ScrnInfoPtr pScrn, CARD32 index)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_SLOW_WRITE_REG(index, IBMRGB_WRITE_ADDR);
+}
+
+void
+glintIBMWriteData (ScrnInfoPtr pScrn, unsigned char data)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_SLOW_WRITE_REG(data, IBMRGB_RAMDAC_DATA);
+}
+
+void
+glintIBMReadAddress (ScrnInfoPtr pScrn, CARD32 index)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_SLOW_WRITE_REG(0xFF, IBMRGB_PIXEL_MASK);
+ GLINT_SLOW_WRITE_REG(index, IBMRGB_READ_ADDR);
+}
+
+unsigned char
+glintIBMReadData (ScrnInfoPtr pScrn)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ return(GLINT_READ_REG(IBMRGB_RAMDAC_DATA));
+}
+
+Bool
+glintIBMHWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pGlint->CursorInfoRec = infoPtr;
+
+ (*pGlint->RamDac->HWCursorInit)(infoPtr);
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile
new file mode 100644
index 000000000..11e4164c2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile
@@ -0,0 +1,75 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile,v 1.15 1999/08/14 10:49:45 dawes Exp $
+XCOMM $PI: xc/programs/Xserver/hw/xfree86/drivers/glint/Imakefile,v 1.11 1999/06/26 03:13:53 faith Exp $
+XCOMM
+XCOMM This is an Imakefile for the GLINT driver.
+XCOMM
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#if BuildXF86DRI /* || BuildXF86DRIDriverSupport -- does not currently work */
+DRISRC=glint_dri.c
+DRIOBJ=glint_dri.o
+DRIINCLUDES=-I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri
+#endif
+
+SRCS = glint_driver.c pm2_dac.c pm2ramdac.c pm2_accel.c pm_dac.c IBMramdac.c \
+ pm_accel.c tx_dac.c tx_accel.c pm2v_dac.c pm2vramdac.c pm2_video.c \
+ TIramdac.c dualmx_dac.c dualmx_accel.c $(DRISRC)
+OBJS = glint_driver.o pm2_dac.o pm2ramdac.o pm2_accel.o pm_dac.o IBMramdac.o \
+ pm_accel.o tx_dac.o tx_accel.o pm2v_dac.o pm2vramdac.o pm2_video.o \
+ TIramdac.o dualmx_dac.o dualmx_accel.o $(DRIOBJ)
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/Xext \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \
+ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \
+ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
+ -I$(XF86SRC)/rac \
+ -I$(XF86SRC)/xf24_32bpp -I$(FONTINCSRC) \
+ -I$(XF86SRC)/xf8_32bpp -I$(XF86SRC)/xf1bpp \
+ -I$(XF86SRC)/xf4bpp -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c -I$(EXTINCSRC) $(DRIINCLUDES) \
+ -I$(XTOP)/include
+#endif
+
+DEFINES = $(GLX_DEFINES)
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget(glint,$(OBJS))
+
+InstallObjectModule(glint,$(MODULEDIR),drivers)
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(IBMramdac.c,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(TIramdac.c,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(dualmx_accel.c,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(dualmx_dac.c,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(glint.h,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(glint_dri.c,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(glint_dri.h,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(glint_dripriv.h,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(glint_driver.c,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(glint_regs.h,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(pm2_accel.c,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(pm2_dac.c,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(pm2_video.c,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(pm2ramdac.c,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(pm2v_dac.c,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(pm2vramdac.c,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(pm_accel.c,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(pm_dac.c,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(tx_accel.c,$(DRIVERSDKDIR)/drivers/glint)
+InstallDriverSDKNonExecFile(tx_dac.c,$(DRIVERSDKDIR)/drivers/glint)
+
+InstallDriverSDKObjectModule(glint,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/TIramdac.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/TIramdac.c
new file mode 100644
index 000000000..2fa291bb3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/TIramdac.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright 1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Modified from IBMramdac.c to support TI RAMDAC routines
+ * by Jens Owen, <jens@precisioninsight.com>.
+ *
+ * glintOutTIIndReg() and glintInTIIndReg() are used to access
+ * the indirect TI RAMDAC registers only.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/TIramdac.c,v 1.1 1999/06/14 07:31:51 dawes Exp $ */
+/* $PI: xc/programs/Xserver/hw/xfree86/drivers/glint/TIramdac.c,v 1.4 1999/05/27 03:46:29 jens Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "TI.h"
+#include "glint_regs.h"
+#include "glint.h"
+
+#define TI_WRITE_ADDR 0x4000
+#define TI_RAMDAC_DATA 0x4008
+#define TI_PIXEL_MASK 0x4010
+#define TI_READ_ADDR 0x4018
+#define TI_CURS_COLOR_WRITE_ADDR 0x4020
+#define TI_CURS_COLOR_DATA 0x4028
+#define TI_CURS_COLOR_READ_ADDR 0x4038
+#define TI_DIRECT_CURS_CTRL 0x4048
+#define TI_INDEX_DATA 0x4050
+#define TI_CURS_RAM_DATA 0x4058
+#define TI_CURS_X_LOW 0x4060
+#define TI_CURS_X_HIGH 0x4068
+#define TI_CURS_Y_LOW 0x4070
+#define TI_CURS_Y_HIGH 0x4078
+
+void
+glintOutTIIndReg(ScrnInfoPtr pScrn,
+ CARD32 reg, unsigned char mask, unsigned char data)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ unsigned char tmp = 0x00;
+ int offset;
+
+ if ((reg & 0xf0) == 0xa0) { /* this is really a direct register write */
+ offset = TI_WRITE_ADDR + ((reg & 0xf) << 3);
+ if (mask != 0x00)
+ tmp = GLINT_SECONDARY_READ_REG(offset) & mask;
+
+ GLINT_SECONDARY_SLOW_WRITE_REG(tmp | data, offset);
+ }
+ else { /* normal indirect access */
+ GLINT_SECONDARY_SLOW_WRITE_REG(reg & 0xFF, TI_WRITE_ADDR);
+
+ if (mask != 0x00)
+ tmp = GLINT_SECONDARY_READ_REG(TI_INDEX_DATA) & mask;
+
+ GLINT_SECONDARY_SLOW_WRITE_REG(tmp | data, TI_INDEX_DATA);
+ }
+}
+
+unsigned char
+glintInTIIndReg (ScrnInfoPtr pScrn, CARD32 reg)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ unsigned char ret;
+ int offset;
+
+ if ((reg & 0xf0) == 0xa0) { /* this is really a direct register write */
+ offset = TI_WRITE_ADDR + ((reg & 0xf) << 3);
+ ret = GLINT_SECONDARY_READ_REG(offset);
+ }
+ else { /* normal indirect access */
+ GLINT_SECONDARY_SLOW_WRITE_REG(reg & 0xFF, TI_WRITE_ADDR);
+ ret = GLINT_SECONDARY_READ_REG(TI_INDEX_DATA);
+ }
+
+ return (ret);
+}
+
+void
+glintTIWriteAddress (ScrnInfoPtr pScrn, CARD32 index)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_SECONDARY_SLOW_WRITE_REG(index, TI_WRITE_ADDR);
+}
+
+void
+glintTIWriteData (ScrnInfoPtr pScrn, unsigned char data)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_SECONDARY_SLOW_WRITE_REG(data, TI_RAMDAC_DATA);
+}
+
+void
+glintTIReadAddress (ScrnInfoPtr pScrn, CARD32 index)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_SECONDARY_SLOW_WRITE_REG(0xFF, TI_PIXEL_MASK);
+ GLINT_SECONDARY_SLOW_WRITE_REG(index, TI_READ_ADDR);
+}
+
+unsigned char
+glintTIReadData (ScrnInfoPtr pScrn)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ return(GLINT_SECONDARY_READ_REG(TI_RAMDAC_DATA));
+}
+
+Bool
+glintTIHWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pGlint->CursorInfoRec = infoPtr;
+
+ (*pGlint->RamDac->HWCursorInit)(infoPtr);
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_accel.c
new file mode 100644
index 000000000..28a9e474f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_accel.c
@@ -0,0 +1,1099 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ * Dirk Hohndel, <hohndel@suse.de>
+ * Stefan Dirsch, <sndirsch@suse.de>
+ *
+ * Dual MX accelerated options.
+ *
+ * Modified version of tx_accel.c to support dual MX chips by
+ * Jens Owen, <jens@precisioninsight.com>
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_accel.c,v 1.1 1999/06/14 07:31:51 dawes Exp $ */
+/* $PI: xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_accel.c,v 1.15 1999/06/09 20:05:12 jens Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb32.h"
+
+#include "miline.h"
+
+#include "glint_regs.h"
+#include "glint.h"
+
+#include "xaalocal.h" /* For replacements */
+
+static void DualMXSync(ScrnInfoPtr pScrn);
+static void DualMXSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+static void DualMXSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h);
+static void DualMXSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx,
+ int patterny,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void DualMXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
+ int patterny, int x, int y,
+ int w, int h);
+static void DualMXSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned int planemask,
+ int transparency_color);
+static void DualMXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h);
+static void DualMXWriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth,
+ int skipleft, int fg, int bg, int rop,
+ unsigned int planemask);
+static void DualMXSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2,int y2);
+static void DualMXDisableClipping(ScrnInfoPtr pScrn);
+static void DualMXWritePixmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int rop,
+ unsigned int planemask, int trans,
+ int bpp, int depth);
+static void DualMXSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg,
+ int bg, int rop, unsigned int planemask);
+static void DualMXSubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h, int skipleft);
+static void DualMXSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg,
+ int bg, int rop, unsigned int planemask);
+static void DualMXSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h, int skipleft);
+static void DualMXSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
+static void DualMXLoadCoord(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ int a, int d);
+static void DualMXSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+static void DualMXSubsequentHorVertLine(ScrnInfoPtr pScrn, int x1, int y1,
+ int len, int dir);
+static void DualMXSubsequentSolidBresenhamLine8bpp(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+static void DualMXSubsequentSolidBresenhamLine16bpp(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+static void DualMXSubsequentSolidBresenhamLine32bpp(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+static void DualMXPolylinesThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC,
+ int mode, int npt, DDXPointPtr pPts);
+static void DualMXPolySegmentThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC,
+ int nseg, xSegment *pSeg);
+
+#define MAX_FIFO_ENTRIES 15
+
+static void
+DualMXInitializeEngine(ScrnInfoPtr pScrn)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ pGlint->rasterizerMode = RMMultiGLINT;
+ pGlint->pprod |= FBRM_ScanlineInt2;
+
+ /* Initialize the Accelerator Engine to defaults */
+
+ /* Only write the following registerto the first MX */
+ GLINT_SLOW_WRITE_REG(1, BroadcastMask);
+ GLINT_SLOW_WRITE_REG(0x00000001, ScanLineOwnership);
+
+ /* Only write the following register to the second MX */
+ GLINT_SLOW_WRITE_REG(2, BroadcastMask);
+ GLINT_SLOW_WRITE_REG(0x00000005, ScanLineOwnership);
+
+ /* Make sure the rest of the register writes go to both MX's */
+ GLINT_SLOW_WRITE_REG(3, BroadcastMask);
+
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode);
+ GLINT_SLOW_WRITE_REG(pGlint->pprod, LBReadMode);
+ GLINT_SLOW_WRITE_REG(pGlint->pprod, FBReadMode);
+ GLINT_SLOW_WRITE_REG(0, dXSub);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBWriteMode);
+ GLINT_SLOW_WRITE_REG(UNIT_ENABLE, FBWriteMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DitherMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureColorMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureAddressMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureReadMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, GLINTWindow);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RouterMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FogMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AntialiasMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaTestMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StencilMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AreaStippleMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LineStippleMode);
+ GLINT_SLOW_WRITE_REG(0, UpdateLineStippleCounters);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LogicalOpMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StatisticMode);
+ GLINT_SLOW_WRITE_REG(0x400, FilterMode);
+ GLINT_SLOW_WRITE_REG(0xffffffff, FBHardwareWriteMask);
+ GLINT_SLOW_WRITE_REG(0xffffffff, FBSoftwareWriteMask);
+ GLINT_SLOW_WRITE_REG(pGlint->rasterizerMode, RasterizerMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, GLINTDepth);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBSourceOffset);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBPixelOffset);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBSourceOffset);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, WindowOrigin);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBWindowBase);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBWindowBase);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureAddressMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RouterMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PatternRamMode);
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ GLINT_SLOW_WRITE_REG(0x2, PixelSize);
+ break;
+ case 16:
+ GLINT_SLOW_WRITE_REG(0x1, PixelSize);
+ break;
+ case 32:
+ GLINT_SLOW_WRITE_REG(0x0, PixelSize);
+ break;
+ }
+ pGlint->ROP = 0xFF;
+ pGlint->ClippingOn = FALSE;
+ pGlint->startxsub = 0;
+ pGlint->startxdom = 0;
+ pGlint->starty = 0;
+ pGlint->count = 0;
+ pGlint->dxdom = 0;
+ pGlint->dy = 1;
+ pGlint->planemask = 0;
+ GLINT_SLOW_WRITE_REG(0, StartXSub);
+ GLINT_SLOW_WRITE_REG(0, StartXDom);
+ GLINT_SLOW_WRITE_REG(0, StartY);
+ GLINT_SLOW_WRITE_REG(0, GLINTCount);
+ GLINT_SLOW_WRITE_REG(0, dXDom);
+ GLINT_SLOW_WRITE_REG(1<<16, dY);
+}
+
+Bool
+DualMXAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ long memory = pGlint->FbMapSize;
+ BoxRec AvailFBArea;
+
+ pGlint->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ DualMXInitializeEngine(pScrn);
+
+ infoPtr->Flags = PIXMAP_CACHE |
+ LINEAR_FRAMEBUFFER |
+ OFFSCREEN_PIXMAPS;
+
+ infoPtr->Sync = DualMXSync;
+
+ infoPtr->SetClippingRectangle = DualMXSetClippingRectangle;
+ infoPtr->DisableClipping = DualMXDisableClipping;
+ infoPtr->ClippingFlags = HARDWARE_CLIP_MONO_8x8_FILL |
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
+ HARDWARE_CLIP_SOLID_FILL;
+
+ infoPtr->SolidFillFlags = 0;
+ infoPtr->SetupForSolidFill = DualMXSetupForFillRectSolid;
+ infoPtr->SubsequentSolidFillRect = DualMXSubsequentFillRectSolid;
+
+ /*
+ * The following optimized routines are copied from tx_accel.c,
+ * but haven't been ported to a dual MX board.
+ */
+#ifdef NOT_DONE
+ infoPtr->SolidLineFlags = 0;
+ infoPtr->PolySegmentThinSolidFlags = 0;
+ infoPtr->PolylinesThinSolidFlags = 0;
+ infoPtr->SetupForSolidLine = DualMXSetupForSolidLine;
+ infoPtr->SubsequentSolidHorVertLine = DualMXSubsequentHorVertLine;
+ switch(pScrn->bitsPerPixel) {
+ case 8: infoPtr->SubsequentSolidBresenhamLine =
+ DualMXSubsequentSolidBresenhamLine8bpp;
+ break;
+ case 16: infoPtr->SubsequentSolidBresenhamLine =
+ DualMXSubsequentSolidBresenhamLine16bpp;
+ break;
+ case 32: infoPtr->SubsequentSolidBresenhamLine =
+ DualMXSubsequentSolidBresenhamLine32bpp;
+ break;
+ }
+ infoPtr->PolySegmentThinSolid = DualMXPolySegmentThinSolidWrapper;
+ infoPtr->PolylinesThinSolid = DualMXPolylinesThinSolidWrapper;
+
+ infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY |
+ ONLY_LEFT_TO_RIGHT_BITBLT;
+ infoPtr->SetupForScreenToScreenCopy = DualMXSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy = DualMXSubsequentScreenToScreenCopy;
+
+ infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS;
+ infoPtr->SetupForMono8x8PatternFill = DualMXSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ DualMXSubsequentMono8x8PatternFillRect;
+
+ if (!pGlint->UsePCIRetry) {
+ infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
+ TRANSPARENCY_ONLY |
+#if 0
+ LEFT_EDGE_CLIPPING |
+ LEFT_EDGE_CLIPPING_NEGATIVE_X |
+#endif
+ BIT_ORDER_IN_BYTE_LSBFIRST;
+
+ pGlint->XAAScanlineColorExpandBuffers[0] =
+ xnfalloc(((pScrn->virtualX + 63)/32) *4* (pScrn->bitsPerPixel / 8));
+ pGlint->XAAScanlineColorExpandBuffers[1] =
+ xnfalloc(((pScrn->virtualX + 63)/32) *4* (pScrn->bitsPerPixel / 8));
+
+ infoPtr->NumScanlineColorExpandBuffers = 2;
+ infoPtr->ScanlineColorExpandBuffers =
+ pGlint->XAAScanlineColorExpandBuffers;
+
+ infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
+ DualMXSetupForScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
+ DualMXSubsequentScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentColorExpandScanline =
+ DualMXSubsequentColorExpandScanline;
+ } else {
+ infoPtr->CPUToScreenColorExpandFillFlags = TRANSPARENCY_ONLY |
+ SYNC_AFTER_COLOR_EXPAND |
+ CPU_TRANSFER_PAD_DWORD |
+#if 0
+ LEFT_EDGE_CLIPPING |
+ LEFT_EDGE_CLIPPING_NEGATIVE_X |
+#endif
+ BIT_ORDER_IN_BYTE_LSBFIRST;
+ infoPtr->ColorExpandBase = pGlint->IOBase + OutputFIFO + 4;
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ DualMXSetupForCPUToScreenColorExpandFill;
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ DualMXSubsequentCPUToScreenColorExpandFill;
+ }
+
+ infoPtr->ColorExpandRange = MAX_FIFO_ENTRIES;
+
+ infoPtr->WriteBitmap = DualMXWriteBitmap;
+ infoPtr->WritePixmap = DualMXWritePixmap;
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ if (memory > (16383*1024)) memory = 16383*1024;
+ AvailFBArea.y2 = memory / (pScrn->displayWidth *
+ pScrn->bitsPerPixel / 8);
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+#endif /* NOT_DONE */
+
+ return (XAAInit(pScreen, infoPtr));
+}
+
+static void DualMXLoadCoord(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h,
+ int a, int d
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ /*
+ * Optimization from tx_accel.c where these values are cached on the
+ * host doesn't appear to work. We definitely need to reload at least
+ * the StartXDom value. I'll play it safe and reload them all.
+ */
+ GLINT_WRITE_REG(w<<16, StartXSub);
+ GLINT_WRITE_REG(x<<16,StartXDom);
+ GLINT_WRITE_REG(y<<16,StartY);
+ GLINT_WRITE_REG(h,GLINTCount);
+ GLINT_WRITE_REG(a<<16,dXDom);
+ GLINT_WRITE_REG(d<<16,dY);
+}
+
+static void MoveDWORDS(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ *(dest + 2) = *(src + 2);
+ *(dest + 3) = *(src + 3);
+ src += 4;
+ dest += 4;
+ dwords -= 4;
+ }
+ if (!dwords) return;
+ *dest = *src;
+ if (dwords == 1) return;
+ *(dest + 1) = *(src + 1);
+ if (dwords == 2) return;
+ *(dest + 2) = *(src + 2);
+}
+
+#define Sync_tag 0x188
+
+static void
+DualMXSync(
+ ScrnInfoPtr pScrn
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ unsigned long readValue;
+
+ CHECKCLIPPING;
+
+ while (GLINT_READ_REG(DMACount) != 0);
+ GLINT_WAIT(3);
+ GLINT_WRITE_REG(3, BroadcastMask); /* hack! this shouldn't need to be reloaded */
+ GLINT_WRITE_REG(1<<10, FilterMode);
+ GLINT_WRITE_REG(0, GlintSync);
+
+ /* Read 1st MX until Sync Tag shows */
+ do {
+ while(GLINT_READ_REG(OutFIFOWords) == 0);
+ readValue = GLINT_READ_REG(OutputFIFO);
+#ifdef DEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "1st MX: OutputFIFO %x\n",readValue);
+#endif
+ } while (readValue != Sync_tag);
+
+ /* Read 2nd MX until Sync Tag shows */
+ do {
+ while(GLINT_SECONDARY_READ_REG(OutFIFOWords) == 0);
+ readValue = GLINT_SECONDARY_READ_REG(OutputFIFO);
+#ifdef DEBUG
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "2nd MX: OutputFIFO %x\n",readValue);
+#endif
+ } while (readValue != Sync_tag);
+
+#ifdef DEBUG
+ if (GLINT_READ_REG(OutFIFOWords)||GLINT_SECONDARY_READ_REG(OutFIFOWords)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Unread data in output FIFO after sync\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "1st MX: OutFifoWords %d\n",GLINT_READ_REG(OutFIFOWords));
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "2nd MX: OutFifoWords %d\n",GLINT_SECONDARY_READ_REG(OutFIFOWords));
+ }
+#endif
+}
+
+static void
+DualMXSetupForFillRectSolid(
+ ScrnInfoPtr pScrn,
+ int color, int rop,
+ unsigned int planemask
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ pGlint->ForeGroundColor = color;
+
+ GLINT_WAIT(5);
+ REPLICATE(color);
+ DO_PLANEMASK(planemask);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
+ GLINT_WRITE_REG(color, FBBlockColor);
+ pGlint->FrameBufferReadMode = FastFillEnable;
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode);
+ GLINT_WRITE_REG(color, PatternRamData0);
+ pGlint->FrameBufferReadMode = FastFillEnable | SpanOperation;
+ }
+ LOADROP(rop);
+}
+
+static void
+DualMXSubsequentFillRectSolid(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_WAIT(8);
+ DualMXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
+ GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode,Render);
+}
+
+static void
+DualMXSetClippingRectangle(
+ ScrnInfoPtr pScrn,
+ int x1, int y1,
+ int x2, int y2
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_WAIT(3);
+ GLINT_WRITE_REG((y1&0xFFFF)<<16|(x1&0xFFFF), ScissorMinXY);
+ GLINT_WRITE_REG((y2&0xFFFF)<<16|(x2&0xFFFF), ScissorMaxXY);
+ GLINT_WRITE_REG(1, ScissorMode); /* Enable Scissor Mode */
+ pGlint->ClippingOn = TRUE;
+}
+
+static void
+DualMXDisableClipping(
+ ScrnInfoPtr pScrn
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ CHECKCLIPPING;
+}
+
+static void
+DualMXSetupForScreenToScreenCopy(
+ ScrnInfoPtr pScrn,
+ int xdir, int ydir,
+ int rop,
+ unsigned int planemask,
+ int transparency_color
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ pGlint->BltScanDirection = ydir;
+
+ GLINT_WAIT(5);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
+
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_SrcEnable, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_SrcEnable | FBRM_DstEnable, FBReadMode);
+ }
+ LOADROP(rop);
+}
+
+static void
+DualMXSubsequentScreenToScreenCopy(
+ ScrnInfoPtr pScrn,
+ int x1, int y1,
+ int x2, int y2,
+ int w, int h
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int srcaddr, dstaddr;
+
+ GLINT_WAIT(10);
+ if (pGlint->BltScanDirection != 1) {
+ y1 += h - 1;
+ y2 += h - 1;
+ DualMXLoadCoord(pScrn, x2, y2, x2+w, h, 0, -1);
+ } else {
+ DualMXLoadCoord(pScrn, x2, y2, x2+w, h, 0, 1);
+ }
+
+ srcaddr = y1 * pScrn->displayWidth + x1;
+ dstaddr = y2 * pScrn->displayWidth + x2;
+
+ GLINT_WRITE_REG(srcaddr - dstaddr, FBSourceOffset);
+ GLINT_WRITE_REG(PrimitiveTrapezoid| FastFillEnable | SpanOperation, Render);
+}
+
+static void
+DualMXSetupForScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ REPLICATE(fg);
+ REPLICATE(bg);
+ GLINT_WAIT(6);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(pGlint->rasterizerMode, RasterizerMode);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
+ pGlint->FrameBufferReadMode = FastFillEnable;
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode);
+ pGlint->FrameBufferReadMode = FastFillEnable | SpanOperation;
+ GLINT_WRITE_REG(fg, PatternRamData0);
+ }
+ LOADROP(rop);
+}
+
+static void
+DualMXSubsequentScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ pGlint->dwords = ((w + 31) >> 5); /* dwords per scanline */
+
+#if 0
+ DualMXSetClippingRectangle(pScrn,x+skipleft, y, x+w, y+h);
+#endif
+
+ pGlint->cpucount = y;
+ pGlint->cpuheight = h;
+ GLINT_WAIT(6);
+ DualMXLoadCoord(pScrn, x, pGlint->cpucount, x+w, 1, 0, 1);
+}
+
+static void
+DualMXSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ CARD32 *src;
+ int dwords = pGlint->dwords;
+
+ GLINT_WAIT(7);
+ DualMXLoadCoord(pScrn, pGlint->startxdom, pGlint->cpucount, pGlint->startxsub, 1, 0, 1);
+
+ GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode | SyncOnBitMask,
+ Render);
+
+ src = (CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno];
+ while (dwords >= infoRec->ColorExpandRange) {
+ GLINT_WAIT(infoRec->ColorExpandRange);
+ GLINT_WRITE_REG((infoRec->ColorExpandRange - 2)<<16 | 0x0D, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), src,
+ infoRec->ColorExpandRange - 1);
+ dwords -= (infoRec->ColorExpandRange - 1);
+ src += (infoRec->ColorExpandRange - 1);
+ }
+ if (dwords) {
+ GLINT_WAIT(dwords);
+ GLINT_WRITE_REG((dwords - 1)<<16 | 0x0D, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), src,dwords);
+ }
+ pGlint->cpucount += 1;
+#if 0
+ if (pGlint->cpucount == (pGlint->cpuheight + 1))
+ CHECKCLIPPING;
+#endif
+}
+
+static void
+DualMXSetupForCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ REPLICATE(fg);
+
+ DO_PLANEMASK(planemask);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ pGlint->FrameBufferReadMode = FastFillEnable;
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode);
+ GLINT_WRITE_REG(fg, PatternRamData0);
+ pGlint->FrameBufferReadMode = FastFillEnable | SpanOperation;
+ }
+ LOADROP(rop);
+}
+
+static void
+DualMXSubsequentCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int dwords = ((w + 31) >> 5) * h;
+
+#if 0
+ DualMXSetClippingRectangle(pScrn,x+skipleft, y, x+w, y+h);
+#endif
+
+ DualMXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
+ GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode |
+ SyncOnBitMask, Render);
+ GLINT_WRITE_REG((dwords - 1)<<16 | 0x0D, OutputFIFO);
+}
+
+void DualMXSetupForMono8x8PatternFill(
+ ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int fg, int bg, int rop,
+ unsigned int planemask
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ if (bg == -1) pGlint->FrameBufferReadMode = -1;
+ else pGlint->FrameBufferReadMode = 0;
+ pGlint->ForeGroundColor = fg;
+ pGlint->BackGroundColor = bg;
+ REPLICATE(pGlint->ForeGroundColor);
+ REPLICATE(pGlint->BackGroundColor);
+
+ GLINT_WAIT(13);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG((patternx & 0x000000FF), AreaStipplePattern0);
+ GLINT_WRITE_REG((patternx & 0x0000FF00) >> 8, AreaStipplePattern1);
+ GLINT_WRITE_REG((patternx & 0x00FF0000) >> 16, AreaStipplePattern2);
+ GLINT_WRITE_REG((patternx & 0xFF000000) >> 24, AreaStipplePattern3);
+ GLINT_WRITE_REG((patterny & 0x000000FF), AreaStipplePattern4);
+ GLINT_WRITE_REG((patterny & 0x0000FF00) >> 8, AreaStipplePattern5);
+ GLINT_WRITE_REG((patterny & 0x00FF0000) >> 16, AreaStipplePattern6);
+ GLINT_WRITE_REG((patterny & 0xFF000000) >> 24, AreaStipplePattern7);
+
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode);
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ LOADROP(rop);
+}
+
+static void
+DualMXSubsequentMono8x8PatternFillRect(
+ ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int span = 0;
+
+ GLINT_WAIT(12);
+ DualMXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
+
+ if (pGlint->FrameBufferReadMode != -1) {
+ if (pGlint->ROP == GXcopy) {
+ GLINT_WRITE_REG(pGlint->BackGroundColor, FBBlockColor);
+ GLINT_WRITE_REG(PrimitiveTrapezoid | FastFillEnable,Render);
+ } else {
+ GLINT_WRITE_REG(pGlint->BackGroundColor, PatternRamData0);
+ GLINT_WRITE_REG(2<<1|2<<4|patternx<<7|patterny<<12|ASM_InvertPattern |
+ UNIT_ENABLE, AreaStippleMode);
+ GLINT_WRITE_REG(AreaStippleEnable | SpanOperation | FastFillEnable |
+ PrimitiveTrapezoid, Render);
+ }
+ }
+
+ if (pGlint->ROP == GXcopy) {
+ GLINT_WRITE_REG(pGlint->ForeGroundColor, FBBlockColor);
+ span = 0;
+ } else {
+ GLINT_WRITE_REG(pGlint->ForeGroundColor, PatternRamData0);
+ span = SpanOperation;
+ }
+ GLINT_WRITE_REG(2<<1|2<<4|patternx<<7|patterny<<12|
+ UNIT_ENABLE, AreaStippleMode);
+ GLINT_WRITE_REG(AreaStippleEnable | span | FastFillEnable |
+ PrimitiveTrapezoid, Render);
+}
+
+static void
+DualMXWriteBitmap(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ unsigned char *srcpntr;
+ int dwords, height, mode;
+ Bool SecondPass = FALSE;
+ register int count;
+ register CARD32* pattern;
+
+ w += skipleft;
+ x -= skipleft;
+ dwords = (w + 31) >> 5;
+
+ DualMXSetClippingRectangle(pScrn,x+skipleft, y, x+w, y+h);
+
+ GLINT_WAIT(11);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(pGlint->rasterizerMode, RasterizerMode);
+ LOADROP(rop);
+ if (rop == GXcopy) {
+ mode = 0;
+ GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ mode = SpanOperation;
+ GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode);
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ DualMXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
+
+ if(bg == -1) {
+ /* >>>>> set fg <<<<<<<< */
+ REPLICATE(fg);
+ GLINT_WAIT(3);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(fg, PatternRamData0);
+ }
+ } else if(rop == GXcopy) {
+ REPLICATE(bg);
+ GLINT_WAIT(5);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(bg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(bg, PatternRamData0);
+ }
+ GLINT_WRITE_REG(PrimitiveTrapezoid |mode|FastFillEnable,Render);
+ REPLICATE(fg);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(fg, PatternRamData0);
+ }
+ } else {
+ SecondPass = TRUE;
+ REPLICATE(fg);
+ GLINT_WAIT(3);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(fg, PatternRamData0);
+ }
+ }
+
+SECOND_PASS:
+ GLINT_WRITE_REG(PrimitiveTrapezoid | FastFillEnable | mode | SyncOnBitMask, Render);
+
+ height = h;
+ srcpntr = src;
+ while(height--) {
+ count = dwords >> 3;
+ pattern = (CARD32*)srcpntr;
+ while(count--) {
+ GLINT_WAIT(8);
+ GLINT_WRITE_REG(*(pattern), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+1), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+2), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+3), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+4), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+5), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+6), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+7), BitMaskPattern);
+ pattern+=8;
+ }
+ count = dwords & 0x07;
+ GLINT_WAIT(count);
+ while (count--)
+ GLINT_WRITE_REG(*(pattern++), BitMaskPattern);
+ srcpntr += srcwidth;
+ }
+
+ if(SecondPass) {
+ SecondPass = FALSE;
+ REPLICATE(bg);
+ GLINT_WAIT(4);
+ GLINT_WRITE_REG((pGlint->rasterizerMode|InvertBitMask), RasterizerMode);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(bg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(bg, PatternRamData0);
+ }
+ goto SECOND_PASS;
+ }
+
+ GLINT_WAIT(2);
+ GLINT_WRITE_REG(pGlint->rasterizerMode, RasterizerMode);
+ CHECKCLIPPING;
+ SET_SYNC_FLAG(infoRec);
+}
+
+static void
+DualMXWritePixmap(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth, /* bytes */
+ int rop,
+ unsigned int planemask,
+ int trans,
+ int bpp, int depth
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ CARD32 *srcp;
+ int count,dwords, skipleft, Bpp = bpp >> 3;
+
+ if((skipleft = (long)src & 0x03L)) {
+ skipleft /= Bpp;
+
+ x -= skipleft;
+ w += skipleft;
+
+ src = (unsigned char*)((long)src & ~0x03L);
+ }
+
+ switch(Bpp) {
+ case 1: dwords = (w + 3) >> 2;
+ break;
+ case 2: dwords = (w + 1) >> 1;
+ break;
+ case 4: dwords = w;
+ break;
+ default: return;
+ }
+
+ DualMXSetClippingRectangle(pScrn,x+skipleft, y, x+w, y+h);
+
+ GLINT_WAIT(12);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(0, PatternRamMode);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ LOADROP(rop);
+ DualMXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
+ GLINT_WRITE_REG(PrimitiveTrapezoid | FastFillEnable | SpanOperation |
+ SyncOnHostData, Render);
+
+ while(h--) {
+ count = dwords;
+ srcp = (CARD32*)src;
+ while(count >= infoRec->ColorExpandRange) {
+ GLINT_WAIT(infoRec->ColorExpandRange);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, infoRec->ColorExpandRange - 1);
+ count -= infoRec->ColorExpandRange - 1;
+ srcp += infoRec->ColorExpandRange - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, count);
+ }
+ src += srcwidth;
+ }
+ CHECKCLIPPING;
+ SET_SYNC_FLAG(infoRec);
+}
+
+static void
+DualMXPolylinesThinSolidWrapper(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ GLINTPtr pGlint = GLINTPTR(infoRec->pScrn);
+ pGlint->CurrentGC = pGC;
+ if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn);
+ XAAPolyLines(pDraw, pGC, mode, npt, pPts);
+}
+
+static void
+DualMXPolySegmentThinSolidWrapper(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ GLINTPtr pGlint = GLINTPTR(infoRec->pScrn);
+ pGlint->CurrentGC = pGC;
+ if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn);
+ XAAPolySegment(pDraw, pGC, nseg, pSeg);
+}
+
+static void
+DualMXSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_WAIT(5);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(color, GLINTColor);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ LOADROP(rop);
+}
+
+static void
+DualMXSubsequentHorVertLine(ScrnInfoPtr pScrn,int x,int y,int len,int dir)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_WAIT(7);
+ if (dir == DEGREES_0) {
+ DualMXLoadCoord(pScrn, x, y, 0, len, 1, 0);
+ } else {
+ DualMXLoadCoord(pScrn, x, y, 0, len, 0, 1);
+ }
+
+ GLINT_WRITE_REG(PrimitiveLine, Render);
+}
+
+static void
+DualMXSubsequentSolidBresenhamLine8bpp( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ cfbPrivGCPtr devPriv;
+ int dxdom, dy;
+
+ if(dmaj == dmin) {
+ GLINT_WAIT(7);
+ if(octant & YDECREASING) {
+ dy = -1;
+ } else {
+ dy = 1;
+ }
+
+ if(octant & XDECREASING) {
+ dxdom = -1;
+ } else {
+ dxdom = 1;
+ }
+
+ DualMXLoadCoord(pScrn, x, y, 0, len, dxdom, dy);
+ GLINT_WRITE_REG(PrimitiveLine, Render);
+ return;
+ }
+
+ devPriv = cfbGetGCPrivate(pGlint->CurrentGC);
+
+ cfbBresS(devPriv->rop, devPriv->and, devPriv->xor,
+ (unsigned long*)pGlint->FbBase, pScrn->displayWidth >> 2,
+ (octant & XDECREASING) ? -1 : 1,
+ (octant & YDECREASING) ? -1 : 1,
+ (octant & YMAJOR) ? Y_AXIS : X_AXIS,
+ x, y, dmin + e, dmin, dmin - dmaj, len);
+}
+
+static void
+DualMXSubsequentSolidBresenhamLine16bpp( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ cfbPrivGCPtr devPriv;
+ int dxdom, dy;
+
+ if(dmaj == dmin) {
+ GLINT_WAIT(7);
+ if(octant & YDECREASING) {
+ dy = -1;
+ } else {
+ dy = 1;
+ }
+
+ if(octant & XDECREASING) {
+ dxdom = -1;
+ } else {
+ dxdom = 1;
+ }
+
+ DualMXLoadCoord(pScrn, x, y, 0, len, dxdom, dy);
+ GLINT_WRITE_REG(PrimitiveLine, Render);
+ return;
+ }
+
+ devPriv = cfbGetGCPrivate(pGlint->CurrentGC);
+
+ cfb16BresS(devPriv->rop, devPriv->and, devPriv->xor,
+ (unsigned long*)pGlint->FbBase, pScrn->displayWidth >> 1,
+ (octant & XDECREASING) ? -1 : 1,
+ (octant & YDECREASING) ? -1 : 1,
+ (octant & YMAJOR) ? Y_AXIS : X_AXIS,
+ x, y, dmin + e, dmin, dmin - dmaj, len);
+}
+
+static void
+DualMXSubsequentSolidBresenhamLine32bpp( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ cfbPrivGCPtr devPriv;
+ int dxdom, dy;
+
+ if(dmaj == dmin) {
+ GLINT_WAIT(7);
+ if(octant & YDECREASING) {
+ dy = -1;
+ } else {
+ dy = 1;
+ }
+
+ if(octant & XDECREASING) {
+ dxdom = -1;
+ } else {
+ dxdom = 1;
+ }
+
+ DualMXLoadCoord(pScrn, x, y, 0, len, dxdom, dy);
+ GLINT_WRITE_REG(PrimitiveLine, Render);
+ return;
+ }
+
+ devPriv = cfbGetGCPrivate(pGlint->CurrentGC);
+
+ cfb32BresS(devPriv->rop, devPriv->and, devPriv->xor,
+ (unsigned long*)pGlint->FbBase, pScrn->displayWidth,
+ (octant & XDECREASING) ? -1 : 1,
+ (octant & YDECREASING) ? -1 : 1,
+ (octant & YMAJOR) ? Y_AXIS : X_AXIS,
+ x, y, dmin + e, dmin, dmin - dmaj, len);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_dac.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_dac.c
new file mode 100644
index 000000000..1bc32ea8d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_dac.c
@@ -0,0 +1,749 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane <alanh@fairlite.demon.co.uk>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE 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.
+ *
+ * Original Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ * Dirk Hohndel, <hohndel@suse.de>
+ * Stefan Dirsch, <sndirsch@suse.de>
+ * Helmut Fahrion, <hf@suse.de>
+ *
+ * Modified version of tx_dac.c to support Dual MX rasterizers by
+ * Jens Owen <jens@precisioninsight.com>
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_dac.c,v 1.2 1999/07/04 06:38:56 dawes Exp $ */
+/* $PI: xc/programs/Xserver/hw/xfree86/drivers/glint/dualmx_dac.c,v 1.13 1999/06/09 20:05:12 jens Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "TI.h"
+#include "glint_regs.h"
+#include "glint.h"
+
+#ifdef DEBUG
+#define DUMP(name,field) do { \
+ value = GLINT_READ_REG(field); \
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\t\t%s(primary): 0x%lX\n", name, value); \
+ value = GLINT_SECONDARY_READ_REG(field); \
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\t\t%s(secondary): 0x%lX\n", name, value); \
+} while (0)
+
+#define TIDUMP(name,field) do { \
+ value = glintInTIIndReg(pScrn,field); \
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\t\t%s: 0x%lX\n", name, value); \
+} while (0)
+
+void
+GLINTDumpRegs(ScrnInfoPtr pScrn) {
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ unsigned long value;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\tGAMMA/MX regs:\n");
+ DUMP("ResetStatus",ResetStatus);
+ DUMP("IntEnable",IntEnable);
+ DUMP("IntFlags",IntFlags);
+ DUMP("InFIFOSpace",InFIFOSpace);
+ DUMP("OutFIFOWords",OutFIFOWords);
+ DUMP("DMAAddress",DMAAddress);
+ DUMP("DMACount",DMACount);
+ DUMP("ErrorFlags",ErrorFlags);
+ DUMP("VClkCtl",VClkCtl);
+ DUMP("TestRegister",TestRegister);
+ DUMP("Aperture0",Aperture0);
+ DUMP("Aperture1",Aperture1);
+ DUMP("DMAControl",DMAControl);
+ DUMP("FIFODis",FIFODis);
+ DUMP("LBMemoryCtl",LBMemoryCtl);
+ DUMP("LBMemoryEDO",LBMemoryEDO);
+ DUMP("FBMemoryCtl",FBMemoryCtl);
+ DUMP("FBModeSel",FBModeSel);
+ DUMP("FBGCWrMask",FBGCWrMask);
+ DUMP("FBGCColorLower",FBGCColorLower);
+ DUMP("FBTXMemCtl",FBTXMemCtl);
+ DUMP("FBWrMaskk",FBWrMaskk);
+ DUMP("FBGCColorUpper",FBGCColorUpper);
+ DUMP("OutputFIFO",OutputFIFO);
+ DUMP("VTGHLimit",VTGHLimit);
+ DUMP("VTGHSyncStart",VTGHSyncStart);
+ DUMP("VTGHSyncEnd",VTGHSyncEnd);
+ DUMP("VTGHBlankEnd",VTGHBlankEnd);
+ DUMP("VTGVLimit",VTGVLimit);
+ DUMP("VTGVSyncStart",VTGVSyncStart);
+ DUMP("VTGVSyncEnd",VTGVSyncEnd);
+ DUMP("VTGVBlankEnd",VTGVBlankEnd);
+ DUMP("VTGHGateStart",VTGHGateStart);
+ DUMP("VTGHGateEnd",VTGHGateEnd);
+ DUMP("VTGVGateStart",VTGVGateStart);
+ DUMP("VTGVGateEnd",VTGVGateEnd);
+ DUMP("VTGPolarity",VTGPolarity);
+ DUMP("VTGFrameRowAddr",VTGFrameRowAddr);
+ DUMP("VTGVLineNumber",VTGVLineNumber);
+ DUMP("VTGSerialClk",VTGSerialClk);
+ DUMP("VTGModeCtl",VTGModeCtl);
+ DUMP("GInFIFOSpace",GInFIFOSpace);
+ DUMP("GDMAAddress",GDMAAddress);
+ DUMP("GDMAControl",GDMAControl);
+ DUMP("GOutDMA",GOutDMA);
+ DUMP("GOutDMACount",GOutDMACount);
+ DUMP("GResetStatus",GResetStatus);
+ DUMP("GIntEnable",GIntEnable);
+ DUMP("GIntFlags",GIntFlags);
+ DUMP("GErrorFlags",GErrorFlags);
+ DUMP("GTestRegister",GTestRegister);
+ DUMP("GFIFODis",GFIFODis);
+ DUMP("GChipConfig",GChipConfig);
+ DUMP("GCSRAperture",GCSRAperture);
+ DUMP("GPageTableAddr",GPageTableAddr);
+ DUMP("GPageTableLength",GPageTableLength);
+ DUMP("GDelayTimer",GDelayTimer);
+ DUMP("GCommandMode",GCommandMode);
+ DUMP("GCommandIntEnable",GCommandIntEnable);
+ DUMP("GCommandIntFlags",GCommandIntFlags);
+ DUMP("GCommandErrorFlags",GCommandErrorFlags);
+ DUMP("GCommandStatus",GCommandStatus);
+ DUMP("GCommandFaultingAddr",GCommandFaultingAddr);
+ DUMP("GVertexFaultingAddr",GVertexFaultingAddr);
+ DUMP("GWriteFaultingAddr",GWriteFaultingAddr);
+ DUMP("GFeedbackSelectCount",GFeedbackSelectCount);
+ DUMP("GGammaProcessorMode",GGammaProcessorMode);
+ DUMP("GVGAShadow",GVGAShadow);
+ DUMP("GMultGLINTAperture",GMultGLINTAperture);
+ DUMP("GMultGLINT1",GMultGLINT1);
+ DUMP("GMultGLINT2",GMultGLINT2);
+ DUMP("StartXDom",StartXDom);
+ DUMP("dXDom",dXDom);
+ DUMP("StartXSub",StartXSub);
+ DUMP("dXSub",dXSub);
+ DUMP("StartY",StartY);
+ DUMP("dY",dY);
+ DUMP("GLINTCount",GLINTCount);
+ DUMP("Render",Render);
+ DUMP("ContinueNewLine",ContinueNewLine);
+ DUMP("ContinueNewDom",ContinueNewDom);
+ DUMP("ContinueNewSub",ContinueNewSub);
+ DUMP("Continue",Continue);
+ DUMP("FlushSpan",FlushSpan);
+ DUMP("BitMaskPattern",BitMaskPattern);
+ DUMP("PointTable0",PointTable0);
+ DUMP("PointTable1",PointTable1);
+ DUMP("PointTable2",PointTable2);
+ DUMP("PointTable3",PointTable3);
+ DUMP("RasterizerMode",RasterizerMode);
+ DUMP("YLimits",YLimits);
+ DUMP("ScanLineOwnership",ScanLineOwnership);
+ DUMP("WaitForCompletion",WaitForCompletion);
+ DUMP("PixelSize",PixelSize);
+ DUMP("XLimits",XLimits);
+ DUMP("RectangleOrigin",RectangleOrigin);
+ DUMP("RectangleSize",RectangleSize);
+ DUMP("PackedDataLimits",PackedDataLimits);
+ DUMP("ScissorMode",ScissorMode);
+ DUMP("ScissorMinXY",ScissorMinXY);
+ DUMP("ScissorMaxXY",ScissorMaxXY);
+ DUMP("ScreenSize",ScreenSize);
+ DUMP("AreaStippleMode",AreaStippleMode);
+ DUMP("LineStippleMode",LineStippleMode);
+ DUMP("LoadLineStippleCounters",LoadLineStippleCounters);
+ DUMP("UpdateLineStippleCounters",UpdateLineStippleCounters);
+ DUMP("SaveLineStippleState",SaveLineStippleState);
+ DUMP("WindowOrigin",WindowOrigin);
+ DUMP("AreaStipplePattern0",AreaStipplePattern0);
+ DUMP("AreaStipplePattern1",AreaStipplePattern1);
+ DUMP("AreaStipplePattern2",AreaStipplePattern2);
+ DUMP("AreaStipplePattern3",AreaStipplePattern3);
+ DUMP("AreaStipplePattern4",AreaStipplePattern4);
+ DUMP("AreaStipplePattern5",AreaStipplePattern5);
+ DUMP("AreaStipplePattern6",AreaStipplePattern6);
+ DUMP("AreaStipplePattern7",AreaStipplePattern7);
+ DUMP("TextureAddressMode",TextureAddressMode);
+ DUMP("TextureReadMode",TextureReadMode);
+ DUMP("TextureFormat",TextureFormat);
+ DUMP("TextureCacheControl",TextureCacheControl);
+ DUMP("GLINTBorderColor",GLINTBorderColor);
+ DUMP("TexelLUTIndex",TexelLUTIndex);
+ DUMP("TexelLUTData",TexelLUTData);
+ DUMP("Texel0",Texel0);
+ DUMP("Texel1",Texel1);
+ DUMP("Texel2",Texel2);
+ DUMP("Texel3",Texel3);
+ DUMP("Texel4",Texel4);
+ DUMP("Texel5",Texel5);
+ DUMP("Texel6",Texel6);
+ DUMP("Texel7",Texel7);
+ DUMP("Interp0",Interp0);
+ DUMP("Interp1",Interp1);
+ DUMP("Interp2",Interp2);
+ DUMP("Interp3",Interp3);
+ DUMP("Interp4",Interp4);
+ DUMP("TextureFilter",TextureFilter);
+ DUMP("TexelLUTMode",TexelLUTMode);
+ DUMP("TextureColorMode",TextureColorMode);
+ DUMP("TextureEnvColor",TextureEnvColor);
+ DUMP("FogMode",FogMode);
+ DUMP("FogColor",FogColor);
+ DUMP("FStart",FStart);
+ DUMP("dFdx",dFdx);
+ DUMP("dFdyDom",dFdyDom);
+ DUMP("KsStart",KsStart);
+ DUMP("dKsdx",dKsdx);
+ DUMP("dKsdyDom",dKsdyDom);
+ DUMP("KdStart", KdStart );
+ DUMP("dKdStart", dKdStart);
+ DUMP("dKddyDom", dKddyDom);
+ DUMP("RStart", RStart );
+ DUMP("dRdx", dRdx);
+ DUMP("dRdyDom", dRdyDom );
+ DUMP("GStart", GStart );
+ DUMP("dGdx", dGdx );
+ DUMP("dGdyDom", dGdyDom );
+ DUMP("BStart", BStart );
+ DUMP("dBdx", dBdx );
+ DUMP("dBdyDom", dBdyDom );
+ DUMP("AStart", AStart );
+ DUMP("dAdx", dAdx );
+ DUMP("dAdyDom", dAdyDom );
+ DUMP("ColorDDAMode", ColorDDAMode );
+ DUMP("ConstantColor", ConstantColor );
+ DUMP("GLINTColor", GLINTColor);
+ DUMP("AlphaTestMode", AlphaTestMode );
+ DUMP("AntialiasMode", AntialiasMode);
+ DUMP("AlphaBlendMode", AlphaBlendMode);
+ DUMP("DitherMode", DitherMode );
+ DUMP("FBSoftwareWriteMask", FBSoftwareWriteMask);
+ DUMP("LogicalOpMode", LogicalOpMode );
+ DUMP("FBWriteData", FBWriteData);
+ DUMP("RouterMode", RouterMode);
+ DUMP("LBReadMode", LBReadMode);
+ DUMP("LBReadFormat", LBReadFormat);
+ DUMP("LBSourceOffset", LBSourceOffset);
+ DUMP("LBStencil", LBStencil);
+ DUMP("LBDepth", LBDepth );
+ DUMP("LBWindowBase", LBWindowBase);
+ DUMP("LBWriteMode", LBWriteMode);
+ DUMP("LBWriteFormat", LBWriteFormat);
+ DUMP("TextureData", TextureData );
+ DUMP("TextureDownloadOffset", TextureDownloadOffset);
+ DUMP("GLINTWindow", GLINTWindow );
+ DUMP("StencilMode", StencilMode);
+ DUMP("StencilData", StencilData);
+ DUMP("GLINTStencil", GLINTStencil );
+ DUMP("DepthMode", DepthMode);
+ DUMP("GLINTDepth", GLINTDepth );
+ DUMP("ZStartU", ZStartU );
+ DUMP("ZStartL", ZStartL );
+ DUMP("dZdxU", dZdxU);
+ DUMP("dZdxL", dZdxL);
+ DUMP("dZdyDomU",dZdyDomU );
+ DUMP("dZdyDomL", dZdyDomL);
+ DUMP("FastClearDepth", FastClearDepth);
+ DUMP("FBReadMode", FBReadMode);
+ DUMP("FBSourceOffset", FBSourceOffset );
+ DUMP("FBPixelOffset", FBPixelOffset);
+ DUMP("FBColor", FBColor );
+ DUMP("FBData", FBData);
+ DUMP("FBSourceData", FBSourceData );
+ DUMP("FBWindowBase", FBWindowBase );
+ DUMP("FBWriteMode", FBWriteMode );
+ DUMP("FBHardwareWriteMask", FBHardwareWriteMask );
+ DUMP("FBBlockColor", FBBlockColor );
+ DUMP("FBReadPixel", FBReadPixel);
+ DUMP("PatternRamMode", PatternRamMode );
+ DUMP("PatternRamData0", PatternRamData0 );
+ DUMP("PatternRamData1", PatternRamData1);
+ DUMP("PatternRamData2", PatternRamData2 );
+ DUMP("PatternRamData3", PatternRamData3 );
+ DUMP("PatternRamData4", PatternRamData4);
+ DUMP("PatternRamData5", PatternRamData5 );
+ DUMP("PatternRamData6", PatternRamData6 );
+ DUMP("PatternRamData7", PatternRamData7 );
+ DUMP("FilterMode", FilterMode );
+ DUMP("StatisticMode", StatisticMode);
+ DUMP("MinRegion", MinRegion );
+ DUMP("MaxRegion", MaxRegion );
+ DUMP("ResetPickResult", ResetPickResult );
+ DUMP("MitHitRegion", MitHitRegion );
+ DUMP("MaxHitRegion", MaxHitRegion );
+ DUMP("PickResult", PickResult );
+ DUMP("GlintSync", GlintSync);
+ DUMP("FBBlockColorU", FBBlockColorU );
+ DUMP("FBBlockColorL", FBBlockColorL );
+ DUMP("SuspendUntilFrameBlank", SuspendUntilFrameBlank );
+ DUMP("FBSourceBase", FBSourceBase );
+ DUMP("FBSourceDelta", FBSourceDelta);
+ DUMP("Config", Config );
+ DUMP("YUVMode", YUVMode );
+ DUMP("DrawTriangle", DrawTriangle);
+ DUMP("RepeatTriangle", RepeatTriangle);
+ DUMP("DrawLine01", DrawLine01);
+ DUMP("DrawLine10", DrawLine10 );
+ DUMP("RepeatLine", RepeatLine );
+ DUMP("BroadcastMask", BroadcastMask );
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\tTI3030 direct regs:\n");
+#define TI_WRITE_ADDR 0x4000
+#define TI_RAMDAC_DATA 0x4008
+#define TI_PIXEL_MASK 0x4010
+#define TI_READ_ADDR 0x4018
+#define TI_CURS_COLOR_WRITE_ADDR 0x4020
+#define TI_CURS_COLOR_DATA 0x4028
+#define TI_CURS_COLOR_READ_ADDR 0x4038
+#define TI_DIRECT_CURS_CTRL 0x4048
+#define TI_INDEX_DATA 0x4050
+#define TI_CURS_RAM_DATA 0x4058
+#define TI_CURS_X_LOW 0x4060
+#define TI_CURS_X_HIGH 0x4068
+#define TI_CURS_Y_LOW 0x4070
+#define TI_CURS_Y_HIGH 0x4078
+ DUMP("TI_WRITE_ADDR", TI_WRITE_ADDR);
+ DUMP("TI_RAMDAC_DATA", TI_RAMDAC_DATA);
+ DUMP("TI_PIXEL_MASK", TI_PIXEL_MASK);
+ DUMP("TI_READ_ADDR", TI_READ_ADDR);
+ DUMP("TI_CURS_COLOR_WRITE_ADDR", TI_CURS_COLOR_WRITE_ADDR);
+ DUMP("TI_CURS_COLOR_DATA", TI_CURS_COLOR_DATA);
+ DUMP("TI_CURS_COLOR_READ_ADDR", TI_CURS_COLOR_READ_ADDR);
+ DUMP("TI_DIRECT_CURS_CTRL", TI_DIRECT_CURS_CTRL);
+ DUMP("TI_INDEX_DATA", TI_INDEX_DATA);
+ DUMP("TI_CURS_RAM_DATA", TI_CURS_RAM_DATA);
+ DUMP("TI_CURS_X_LOW", TI_CURS_X_LOW);
+ DUMP("TI_CURS_X_HIGH", TI_CURS_X_HIGH);
+ DUMP("TI_CURS_Y_LOW", TI_CURS_Y_LOW);
+ DUMP("TI_CURS_Y_HIGH", TI_CURS_Y_HIGH);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\tTI3030 indirect regs:\n");
+ TIDUMP("TIDAC_rev",TIDAC_rev);
+ TIDUMP("TIDAC_ind_curs_ctrl",TIDAC_ind_curs_ctrl);
+ TIDUMP("TIDAC_byte_router_ctrl",TIDAC_byte_router_ctrl);
+ TIDUMP("TIDAC_latch_ctrl",TIDAC_latch_ctrl);
+ TIDUMP("TIDAC_true_color_ctrl",TIDAC_true_color_ctrl);
+ TIDUMP("TIDAC_multiplex_ctrl",TIDAC_multiplex_ctrl);
+ TIDUMP("TIDAC_clock_select",TIDAC_clock_select);
+ TIDUMP("TIDAC_palette_page",TIDAC_palette_page);
+ TIDUMP("TIDAC_general_ctrl",TIDAC_general_ctrl);
+ TIDUMP("TIDAC_misc_ctrl",TIDAC_misc_ctrl);
+ TIDUMP("TIDAC_pll_addr",TIDAC_pll_addr);
+ TIDUMP("TIDAC_pll_pixel_data",TIDAC_pll_pixel_data);
+ TIDUMP("TIDAC_pll_memory_data",TIDAC_pll_memory_data);
+ TIDUMP("TIDAC_pll_loop_data",TIDAC_pll_loop_data);
+ TIDUMP("TIDAC_key_over_low",TIDAC_key_over_low);
+ TIDUMP("TIDAC_key_over_high",TIDAC_key_over_high);
+ TIDUMP("TIDAC_key_red_low",TIDAC_key_red_low);
+ TIDUMP("TIDAC_key_red_high",TIDAC_key_red_high);
+ TIDUMP("TIDAC_key_green_low",TIDAC_key_green_low);
+ TIDUMP("TIDAC_key_green_high",TIDAC_key_green_high);
+ TIDUMP("TIDAC_key_blue_low",TIDAC_key_blue_low);
+ TIDUMP("TIDAC_key_blue_high",TIDAC_key_blue_high);
+ TIDUMP("TIDAC_key_ctrl",TIDAC_key_ctrl);
+ TIDUMP("TIDAC_clock_ctrl",TIDAC_clock_ctrl);
+ TIDUMP("TIDAC_sense_test",TIDAC_sense_test);
+ TIDUMP("TIDAC_test_mode_data",TIDAC_test_mode_data);
+ TIDUMP("TIDAC_crc_remain_lsb",TIDAC_crc_remain_lsb);
+ TIDUMP("TIDAC_crc_remain_msb",TIDAC_crc_remain_msb);
+ TIDUMP("TIDAC_crc_bit_select",TIDAC_crc_bit_select);
+ TIDUMP("TIDAC_id",TIDAC_id);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\tTI3030 PLL regs:\n");
+ glintOutTIIndReg(pScrn, TIDAC_pll_addr, 0, 0x00);
+ TIDUMP("Pixel N",TIDAC_pll_pixel_data);
+ glintOutTIIndReg(pScrn, TIDAC_pll_addr, 0, 0x01);
+ TIDUMP("Pixel M",TIDAC_pll_pixel_data);
+ glintOutTIIndReg(pScrn, TIDAC_pll_addr, 0, 0x02);
+ TIDUMP("Pixel P",TIDAC_pll_pixel_data);
+ glintOutTIIndReg(pScrn, TIDAC_pll_addr, 0, 0x00);
+ TIDUMP("Memory N",TIDAC_pll_memory_data);
+ glintOutTIIndReg(pScrn, TIDAC_pll_addr, 0, 0x04);
+ TIDUMP("Memory M",TIDAC_pll_memory_data);
+ glintOutTIIndReg(pScrn, TIDAC_pll_addr, 0, 0x08);
+ TIDUMP("Memory P",TIDAC_pll_memory_data);
+ glintOutTIIndReg(pScrn, TIDAC_pll_addr, 0, 0x00);
+ TIDUMP("Loop N",TIDAC_pll_loop_data);
+ glintOutTIIndReg(pScrn, TIDAC_pll_addr, 0, 0x10);
+ TIDUMP("Loop M",TIDAC_pll_loop_data);
+ glintOutTIIndReg(pScrn, TIDAC_pll_addr, 0, 0x20);
+ TIDUMP("Loop P",TIDAC_pll_loop_data);
+}
+#endif
+
+static int
+Shiftbpp(ScrnInfoPtr pScrn, int value)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int logbytesperaccess;
+
+ logbytesperaccess = 4;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ value >>= logbytesperaccess;
+ pGlint->BppShift = logbytesperaccess;
+ break;
+ case 16:
+ if (pGlint->DoubleBuffer) {
+ value >>= (logbytesperaccess-2);
+ pGlint->BppShift = logbytesperaccess-2;
+ } else {
+ value >>= (logbytesperaccess-1);
+ pGlint->BppShift = logbytesperaccess-1;
+ }
+ break;
+ case 24:
+ value *= 3;
+ value >>= logbytesperaccess;
+ pGlint->BppShift = logbytesperaccess;
+ break;
+ case 32:
+ value >>= (logbytesperaccess-2);
+ pGlint->BppShift = logbytesperaccess-2;
+ break;
+ }
+ return (value);
+}
+
+Bool
+DualMXInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ GLINTRegPtr pReg = &pGlint->ModeReg;
+ RamDacHWRecPtr pTI = RAMDACHWPTR(pScrn);
+ RamDacRegRecPtr ramdacReg = &pTI->ModeReg;
+ CARD32 temp1, temp2, temp3, temp4;
+
+ pReg->glintRegs[Aperture0 >> 3] = 0;
+ pReg->glintRegs[Aperture1 >> 3] = 0;
+
+ if (pGlint->UsePCIRetry) {
+ pReg->glintRegs[DFIFODis >> 3] = 1;
+ pReg->glintRegs[FIFODis >> 3] = 3;
+ } else {
+ pReg->glintRegs[DFIFODis >> 3] = 0;
+ pReg->glintRegs[FIFODis >> 3] = 1;
+ }
+
+ temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay;
+ temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay;
+ temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart;
+ temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+
+ pReg->glintRegs[VTGHLimit >> 3] = Shiftbpp(pScrn,mode->CrtcHTotal);
+ pReg->glintRegs[VTGHSyncEnd >> 3] = Shiftbpp(pScrn, temp1 + temp3);
+ pReg->glintRegs[VTGHSyncStart >> 3] = Shiftbpp(pScrn, temp1);
+ pReg->glintRegs[VTGHBlankEnd >> 3] = Shiftbpp(pScrn, mode->CrtcHTotal -
+ mode->CrtcHDisplay);
+
+ pReg->glintRegs[VTGVLimit >> 3] = mode->CrtcVTotal;
+ pReg->glintRegs[VTGVSyncEnd >> 3] = temp2 + temp4;
+ pReg->glintRegs[VTGVSyncStart >> 3] = temp2;
+ pReg->glintRegs[VTGVBlankEnd >> 3] = mode->CrtcVTotal - mode->CrtcVDisplay;
+
+ pReg->glintRegs[VTGPolarity >> 3] = (((mode->Flags & V_PHSYNC) ? 0:2)<<2) |
+ ((mode->Flags & V_PVSYNC) ? 0 : 2) | (0xb0);
+
+ pReg->glintRegs[VClkCtl >> 3] = 0;
+ pReg->glintRegs[VTGVGateStart >> 3] = pReg->glintRegs[VTGVBlankEnd>>3] - 1;
+ pReg->glintRegs[VTGVGateEnd >> 3] = pReg->glintRegs[VTGVBlankEnd>>3];
+ /*
+ * tell DAC to use the ICD chip clock 0 as ref clock
+ * and set up some more video timining generator registers
+ */
+ pReg->glintRegs[VTGHGateStart >> 3] = pReg->glintRegs[VTGHBlankEnd>>3] - 1;
+ pReg->glintRegs[VTGHGateEnd >> 3] = pReg->glintRegs[VTGHLimit>>3] - 1;
+ pReg->glintRegs[VTGSerialClk >> 3] = 0x0002;
+ pReg->glintRegs[FBModeSel >> 3] = 0x0907;
+ pReg->glintRegs[VTGModeCtl >> 3] = 0x00;
+
+ /*
+ * Setup memory control registers for FB and LB
+ */
+ pReg->glintRegs[FBMemoryCtl >> 3] = 0x00000800;
+ pReg->glintRegs[LBMemoryEDO >> 3] = GLINT_READ_REG(LBMemoryEDO);
+ pReg->glintRegs[LBMemoryEDO >> 3] &= ~(LBEDOMask |
+ LBEDOBankSizeMask |
+ LBTwoPageDetectorMask);
+ pReg->glintRegs[LBMemoryEDO >> 3] |= (LBEDOEnabled |
+ LBEDOBankSize4M |
+ LBTwoPageDetector);
+ pReg->glintRegs[LBMemoryCtl >> 3] = GLINT_READ_REG(LBMemoryCtl);
+ pReg->glintRegs[LBMemoryCtl >> 3] &= ~(LBNumBanksMask |
+ LBPageSizeMask |
+ LBRASCASLowMask |
+ LBRASPrechargeMask |
+ LBCASLowMask |
+ LBPageModeMask |
+ LBRefreshCountMask);
+ pReg->glintRegs[LBMemoryCtl >> 3] |= (LBNumBanks2 |
+ LBPageSize1024 |
+ LBRASCASLow2 |
+ LBRASPrecharge2 |
+ LBCASLow1 |
+ LBPageModeEnabled |
+ (0x20 << LBRefreshCountShift));
+ pReg->glintRegs[GCSRAperture >> 3] = GCSRSecondaryGLINTMapEn;
+
+ /* Copy info to secondary regs */
+ pReg->glintSecondRegs[Aperture0>>3] = pReg->glintRegs[Aperture0>>3];
+ pReg->glintSecondRegs[Aperture1>>3] = pReg->glintRegs[Aperture1>>3];
+ pReg->glintSecondRegs[DFIFODis>>3] = pReg->glintRegs[DFIFODis>>3];
+ pReg->glintSecondRegs[FIFODis>>3] = pReg->glintRegs[FIFODis>>3];
+ pReg->glintSecondRegs[VTGHLimit>>3] = pReg->glintRegs[VTGHLimit>>3];
+ pReg->glintSecondRegs[VTGHSyncEnd>>3] = pReg->glintRegs[VTGHSyncEnd>>3];
+ pReg->glintSecondRegs[VTGHSyncStart>>3] = pReg->glintRegs[VTGHSyncStart>>3];
+ pReg->glintSecondRegs[VTGHBlankEnd>>3] = pReg->glintRegs[VTGHBlankEnd>>3];
+ pReg->glintSecondRegs[VTGVLimit>>3] = pReg->glintRegs[VTGVLimit>>3];
+ pReg->glintSecondRegs[VTGVSyncEnd>>3] = pReg->glintRegs[VTGVSyncEnd>>3];
+ pReg->glintSecondRegs[VTGVSyncStart>>3] = pReg->glintRegs[VTGVSyncStart>>3];
+ pReg->glintSecondRegs[VTGVBlankEnd>>3] = pReg->glintRegs[VTGVBlankEnd>>3];
+ pReg->glintSecondRegs[VTGPolarity>>3] = pReg->glintRegs[VTGPolarity>>3];
+ pReg->glintSecondRegs[VClkCtl>>3] = pReg->glintRegs[VClkCtl>>3];
+ pReg->glintSecondRegs[VTGVGateStart>>3] = pReg->glintRegs[VTGVGateStart>>3];
+ pReg->glintSecondRegs[VTGVGateEnd>>3] = pReg->glintRegs[VTGVGateEnd>>3];
+ pReg->glintSecondRegs[VTGSerialClk>>3] = pReg->glintRegs[VTGSerialClk>>3];
+ pReg->glintSecondRegs[VTGHGateStart>>3] = pReg->glintRegs[VTGHGateStart>>3];
+ pReg->glintSecondRegs[VTGHGateEnd>>3] = pReg->glintRegs[VTGHGateEnd>>3];
+ pReg->glintSecondRegs[FBModeSel>>3] = pReg->glintRegs[FBModeSel>>3];
+ pReg->glintSecondRegs[VTGModeCtl>>3] = pReg->glintRegs[VTGModeCtl>>3];
+ pReg->glintSecondRegs[FBMemoryCtl>>3] = pReg->glintRegs[FBMemoryCtl>>3];
+ pReg->glintSecondRegs[LBMemoryEDO>>3] = pReg->glintRegs[LBMemoryEDO>>3];
+ pReg->glintSecondRegs[LBMemoryCtl>>3] = pReg->glintRegs[LBMemoryCtl>>3];
+ pReg->glintSecondRegs[GCSRAperture>>3] = pReg->glintRegs[GCSRAperture>>3];
+
+ switch (pGlint->RamDac->RamDacType) {
+ case TI3030_RAMDAC:
+ {
+ /* Get the programmable clock values */
+ unsigned long m=0,n=0,p=0;
+ unsigned long clock;
+ int count;
+ unsigned long q, status, VCO;
+
+ clock = TIramdacCalculateMNPForClock(pGlint->RefClock,
+ mode->Clock, 1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p);
+
+ ramdacReg->DacRegs[TIDAC_PIXEL_N] = ((n & 0x3f) | 0xc0);
+ ramdacReg->DacRegs[TIDAC_PIXEL_M] = (m & 0x3f) ;
+ ramdacReg->DacRegs[TIDAC_PIXEL_P] = ((p & 0x03) | 0xb0);
+ ramdacReg->DacRegs[TIDAC_PIXEL_VALID] = TRUE;
+
+ n = 65 - ((128 << 2) / pScrn->bitsPerPixel);
+ m = 61;
+ p = 0;
+ for (q = 0; q < 8; q++) {
+ if (q > 0) p = 3;
+ for ( ; p < 4; p++) {
+ VCO = ((clock * (q + 1) * (65 - m)) / (65 - n)) << (p + 1);
+ if (VCO >= 110000) { break; }
+ }
+ if (VCO >= 110000) { break; }
+ }
+ ramdacReg->DacRegs[TIDAC_clock_ctrl] = (q | 0x38);
+
+ ramdacReg->DacRegs[TIDAC_LOOP_N] = ((n & 0x3f) | 0xc0);
+ ramdacReg->DacRegs[TIDAC_LOOP_M] = (m & 0x3f) ;
+ ramdacReg->DacRegs[TIDAC_LOOP_P] = ((p & 0x03) | 0xf0);
+ ramdacReg->DacRegs[TIDAC_LOOP_VALID] = TRUE;
+ }
+ break;
+ }
+
+ /* Now use helper routines to setup bpp for this driver */
+ (*pGlint->RamDac->SetBpp)(pScrn, ramdacReg);
+
+ return(TRUE);
+}
+
+void
+DualMXSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ glintReg->glintRegs[Aperture0 >> 3] = GLINT_READ_REG(Aperture0);
+ glintReg->glintRegs[Aperture1 >> 3] = GLINT_READ_REG(Aperture1);
+
+ glintReg->glintRegs[DFIFODis >> 3] = GLINT_READ_REG(DFIFODis);
+ glintReg->glintRegs[FIFODis >> 3] = GLINT_READ_REG(FIFODis);
+
+ glintReg->glintRegs[VClkCtl >> 3] = GLINT_READ_REG(VClkCtl);
+ glintReg->glintRegs[VTGPolarity >> 3] = GLINT_READ_REG(VTGPolarity);
+ glintReg->glintRegs[VTGHLimit >> 3] = GLINT_READ_REG(VTGHLimit);
+ glintReg->glintRegs[VTGHBlankEnd >> 3] = GLINT_READ_REG(VTGHBlankEnd);
+ glintReg->glintRegs[VTGHSyncStart >> 3] = GLINT_READ_REG(VTGHSyncStart);
+ glintReg->glintRegs[VTGHSyncEnd >> 3] = GLINT_READ_REG(VTGHSyncEnd);
+ glintReg->glintRegs[VTGVLimit >> 3] = GLINT_READ_REG(VTGVLimit);
+ glintReg->glintRegs[VTGVBlankEnd >> 3] = GLINT_READ_REG(VTGVBlankEnd);
+ glintReg->glintRegs[VTGVSyncStart >> 3] = GLINT_READ_REG(VTGVSyncStart);
+ glintReg->glintRegs[VTGVSyncEnd >> 3] = GLINT_READ_REG(VTGVSyncEnd);
+ glintReg->glintRegs[VTGVGateStart >> 3] = GLINT_READ_REG(VTGVGateStart);
+ glintReg->glintRegs[VTGVGateEnd >> 3] = GLINT_READ_REG(VTGVGateEnd);
+ glintReg->glintRegs[VTGSerialClk >> 3] = GLINT_READ_REG(VTGSerialClk);
+ glintReg->glintRegs[FBModeSel >> 3] = GLINT_READ_REG(FBModeSel);
+ glintReg->glintRegs[VTGModeCtl >> 3] = GLINT_READ_REG(VTGModeCtl);
+ glintReg->glintRegs[VTGHGateStart >> 3] = GLINT_READ_REG(VTGHGateStart);
+ glintReg->glintRegs[VTGHGateEnd >> 3] = GLINT_READ_REG(VTGHGateEnd);
+ glintReg->glintRegs[FBMemoryCtl >> 3] = GLINT_READ_REG(FBMemoryCtl);
+ glintReg->glintRegs[LBMemoryEDO >> 3] = GLINT_READ_REG(LBMemoryEDO);
+ glintReg->glintRegs[LBMemoryCtl >> 3] = GLINT_READ_REG(LBMemoryCtl);
+ glintReg->glintRegs[GCSRAperture >> 3] = GLINT_READ_REG(GCSRAperture);
+
+ glintReg->glintSecondRegs[Aperture0 >> 3] =
+ GLINT_SECONDARY_READ_REG(Aperture0);
+ glintReg->glintSecondRegs[Aperture1 >> 3] =
+ GLINT_SECONDARY_READ_REG(Aperture1);
+
+ glintReg->glintSecondRegs[DFIFODis >> 3] =
+ GLINT_SECONDARY_READ_REG(DFIFODis);
+ glintReg->glintSecondRegs[FIFODis >> 3] =
+ GLINT_SECONDARY_READ_REG(FIFODis);
+
+ glintReg->glintSecondRegs[VClkCtl >> 3] =
+ GLINT_SECONDARY_READ_REG(VClkCtl);
+ glintReg->glintSecondRegs[VTGPolarity >> 3] =
+ GLINT_SECONDARY_READ_REG(VTGPolarity);
+ glintReg->glintSecondRegs[VTGHLimit >> 3] =
+ GLINT_SECONDARY_READ_REG(VTGHLimit);
+ glintReg->glintSecondRegs[VTGHBlankEnd >> 3] =
+ GLINT_SECONDARY_READ_REG(VTGHBlankEnd);
+ glintReg->glintSecondRegs[VTGHSyncStart >> 3] =
+ GLINT_SECONDARY_READ_REG(VTGHSyncStart);
+ glintReg->glintSecondRegs[VTGHSyncEnd >> 3] =
+ GLINT_SECONDARY_READ_REG(VTGHSyncEnd);
+ glintReg->glintSecondRegs[VTGVLimit >> 3] =
+ GLINT_SECONDARY_READ_REG(VTGVLimit);
+ glintReg->glintSecondRegs[VTGVBlankEnd >> 3] =
+ GLINT_SECONDARY_READ_REG(VTGVBlankEnd);
+ glintReg->glintSecondRegs[VTGVSyncStart >> 3] =
+ GLINT_SECONDARY_READ_REG(VTGVSyncStart);
+ glintReg->glintSecondRegs[VTGVSyncEnd >> 3] =
+ GLINT_SECONDARY_READ_REG(VTGVSyncEnd);
+ glintReg->glintSecondRegs[VTGVGateStart >> 3] =
+ GLINT_SECONDARY_READ_REG(VTGVGateStart);
+ glintReg->glintSecondRegs[VTGVGateEnd >> 3] =
+ GLINT_SECONDARY_READ_REG(VTGVGateEnd);
+ glintReg->glintSecondRegs[VTGSerialClk >> 3] =
+ GLINT_SECONDARY_READ_REG(VTGSerialClk);
+ glintReg->glintSecondRegs[FBModeSel >> 3] =
+ GLINT_SECONDARY_READ_REG(FBModeSel);
+ glintReg->glintSecondRegs[VTGModeCtl >> 3] =
+ GLINT_SECONDARY_READ_REG(VTGModeCtl);
+ glintReg->glintSecondRegs[VTGHGateStart >> 3] =
+ GLINT_SECONDARY_READ_REG(VTGHGateStart);
+ glintReg->glintSecondRegs[VTGHGateEnd >> 3] =
+ GLINT_SECONDARY_READ_REG(VTGHGateEnd);
+ glintReg->glintSecondRegs[FBMemoryCtl >> 3] =
+ GLINT_SECONDARY_READ_REG(FBMemoryCtl);
+ glintReg->glintSecondRegs[LBMemoryEDO >> 3] =
+ GLINT_SECONDARY_READ_REG(LBMemoryEDO);
+ glintReg->glintSecondRegs[LBMemoryCtl >> 3] =
+ GLINT_SECONDARY_READ_REG(LBMemoryCtl);
+ glintReg->glintSecondRegs[GCSRAperture >> 3] =
+ GLINT_SECONDARY_READ_REG(GCSRAperture);
+}
+
+void
+DualMXRestore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+#if 0
+ GLINT_SLOW_WRITE_REG(0, ResetStatus);
+ while(GLINT_READ_REG(ResetStatus) != 0) {
+ xf86MsgVerb(X_INFO, 2, "Resetting Engine - Please Wait.\n");
+ };
+#endif
+
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture0 >> 3], Aperture0);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture1 >> 3], Aperture1);
+
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[DFIFODis >> 3], DFIFODis);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[FIFODis >> 3], FIFODis);
+
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGPolarity >> 3], VTGPolarity);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGSerialClk >> 3], VTGSerialClk);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGModeCtl >> 3], VTGModeCtl);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGHLimit >> 3], VTGHLimit);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGHSyncStart >> 3],VTGHSyncStart);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGHSyncEnd >> 3], VTGHSyncEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGHBlankEnd >> 3], VTGHBlankEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGVLimit >> 3], VTGVLimit);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGVSyncStart >> 3],VTGVSyncStart);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGVSyncEnd >> 3], VTGVSyncEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGVBlankEnd >> 3], VTGVBlankEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGVGateStart >> 3],VTGVGateStart);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGVGateEnd >> 3], VTGVGateEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[FBModeSel >> 3], FBModeSel);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGHGateStart >> 3],VTGHGateStart);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGHGateEnd >> 3], VTGHGateEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[FBMemoryCtl >> 3], FBMemoryCtl);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[LBMemoryEDO >> 3], LBMemoryEDO);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[LBMemoryCtl >> 3], LBMemoryCtl);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[GCSRAperture >> 3], GCSRAperture);
+
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[Aperture0 >> 3], Aperture0);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[Aperture1 >> 3], Aperture1);
+
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[DFIFODis >> 3], DFIFODis);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[FIFODis >> 3], FIFODis);
+
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[VTGPolarity >> 3], VTGPolarity);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[VTGSerialClk >> 3], VTGSerialClk);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[VTGModeCtl >> 3], VTGModeCtl);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[VTGHLimit >> 3], VTGHLimit);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[VTGHSyncStart >> 3],VTGHSyncStart);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[VTGHSyncEnd >> 3], VTGHSyncEnd);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[VTGHBlankEnd >> 3], VTGHBlankEnd);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[VTGVLimit >> 3], VTGVLimit);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[VTGVSyncStart >> 3],VTGVSyncStart);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[VTGVSyncEnd >> 3], VTGVSyncEnd);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[VTGVBlankEnd >> 3], VTGVBlankEnd);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[VTGVGateStart >> 3],VTGVGateStart);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[VTGVGateEnd >> 3], VTGVGateEnd);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[FBModeSel >> 3], FBModeSel);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[VTGHGateStart >> 3],VTGHGateStart);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[VTGHGateEnd >> 3], VTGHGateEnd);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[FBMemoryCtl >> 3], FBMemoryCtl);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[LBMemoryEDO >> 3], LBMemoryEDO);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintSecondRegs[LBMemoryCtl >> 3], LBMemoryCtl);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ glintReg->glintRegs[GCSRAperture >> 3], GCSRAperture);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h
new file mode 100644
index 000000000..2d4d3ba88
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h
@@ -0,0 +1,255 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint.h,v 1.21 1999/07/18 03:26:56 dawes Exp $ */
+/*
+ * Copyright 1997,1998 by Alan Hourihane <alanh@fairlite.demon.co.uk>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ * Dirk Hohndel, <hohndel@suse.de>
+ * Stefan Dirsch, <sndirsch@suse.de>
+ *
+ * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and
+ * Siemens Nixdorf Informationssysteme
+ */
+#ifndef _GLINT_H_
+#define _GLINT_H_
+
+#include "xaa.h"
+#include "xf86RamDac.h"
+#include "xf86cmap.h"
+#include "xf86i2c.h"
+#include "xf86DDC.h"
+#ifdef XF86DRI
+#include "xf86drm.h"
+#include "sarea.h"
+#define _XF86DRI_SERVER_
+#include "xf86dri.h"
+#include "dri.h"
+#include "GL/glxint.h"
+#include "glint_dripriv.h"
+#endif
+
+#define GLINT_MAX_MX_DEVICES 2
+
+typedef struct {
+ CARD32 glintRegs[0x2000];
+ CARD32 glintSecondRegs[0x2000];
+ CARD32 DacRegs[0x100]; /* used by internal DACs */
+ CARD8 cmap[0x300];
+} GLINTRegRec, *GLINTRegPtr;
+
+#define GLINTPTR(p) ((GLINTPtr)((p)->driverPrivate))
+
+typedef struct {
+ pciVideoPtr PciInfo;
+ pciVideoPtr PciInfoGeometry;
+ pciVideoPtr MXPciInfo[GLINT_MAX_MX_DEVICES];
+ int numMXDevices;
+ PCITAG PciTag;
+ PCITAG PciTagGeometry;
+ EntityInfoPtr pEnt;
+ EntityInfoPtr pEntGeometry;
+ EntityInfoPtr pEntMX[GLINT_MAX_MX_DEVICES];
+ RamDacHelperRecPtr RamDac;
+ int MemClock;
+ int Chipset;
+ int ChipRev;
+ int HwBpp;
+ int BppShift;
+ int pprod;
+ int ForeGroundColor;
+ int BackGroundColor;
+ int bppalign;
+ int startxdom;
+ int startxsub;
+ int starty;
+ int count;
+ int dy;
+ int x;
+ int y;
+ int w;
+ int h;
+ int dxdom;
+ int dwords;
+ int cpuheight;
+ int cpucount;
+ int planemask;
+ CARD32 IOAddress;
+ CARD32 FbAddress;
+ int irq;
+ unsigned char * IOBase;
+ unsigned char * FbBase;
+ long FbMapSize;
+ Bool DoubleBuffer;
+ Bool NoAccel;
+ Bool Dac6Bit;
+ Bool HWCursor;
+ Bool ClippingOn;
+ Bool UsePCIRetry;
+ Bool UseBlockWrite;
+ Bool UseFireGL3000;
+ Bool VGAcore;
+ int MultiGLINTApSize;
+ int MXFbSize;
+ int realMXWidth;
+ CARD32 SecondaryAddress;
+ CARD32 rasterizerMode;
+ unsigned char * SecondaryBase;
+ int MinClock;
+ int MaxClock;
+ int RefClock;
+ GLINTRegRec SavedReg;
+ GLINTRegRec ModeReg;
+ CARD32 AccelFlags;
+ CARD32 ROP;
+ CARD32 FrameBufferReadMode;
+ CARD32 BltScanDirection;
+ CARD32 TexMapFormat;
+ CARD32 PixelWidth;
+ RamDacRecPtr RamDacRec;
+ xf86CursorInfoPtr CursorInfoRec;
+ XAAInfoRecPtr AccelInfoRec;
+ CloseScreenProcPtr CloseScreen;
+ GCPtr CurrentGC;
+ I2CBusPtr DDCBus, VSBus;
+ CARD8* XAAScanlineColorExpandBuffers[2];
+#ifdef XF86DRI
+ Bool directRenderingEnabled;
+ DRIInfoPtr pDRIInfo;
+ int drmSubFD;
+ drmBufMapPtr drmBufs; /* Map of DMA buffers */
+ int numVisualConfigs;
+ __GLXvisualConfig* pVisualConfigs;
+ GLINTConfigPrivPtr pVisualConfigsPriv;
+ GLINTRegRec DRContextRegs;
+#endif
+} GLINTRec, *GLINTPtr;
+
+/* Defines for PCI data */
+
+#define PCI_VENDOR_TI_CHIP_PERMEDIA2 \
+ ((PCI_VENDOR_TI << 16) | PCI_CHIP_TI_PERMEDIA2)
+#define PCI_VENDOR_TI_CHIP_PERMEDIA \
+ ((PCI_VENDOR_TI << 16) | PCI_CHIP_TI_PERMEDIA)
+#define PCI_VENDOR_3DLABS_CHIP_PERMEDIA \
+ ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_PERMEDIA)
+#define PCI_VENDOR_3DLABS_CHIP_PERMEDIA2 \
+ ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_PERMEDIA2)
+#define PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V \
+ ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_PERMEDIA2V)
+#define PCI_VENDOR_3DLABS_CHIP_500TX \
+ ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_500TX)
+#define PCI_VENDOR_3DLABS_CHIP_MX \
+ ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_MX)
+#define PCI_VENDOR_3DLABS_CHIP_GAMMA \
+ ((PCI_VENDOR_3DLABS << 16) | PCI_CHIP_GAMMA)
+
+/* Prototypes */
+
+void Permedia2StoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs);
+void Permedia2InstallColormap(ColormapPtr pmap);
+void Permedia2UninstallColormap(ColormapPtr pmap);
+int Permedia2ListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps);
+void Permedia2HandleColormaps(ScreenPtr pScreen, ScrnInfoPtr scrnp);
+void Permedia2RestoreDACValues(ScrnInfoPtr pScrn);
+void Permedia2Restore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg);
+void Permedia2Save(ScrnInfoPtr pScrn, GLINTRegPtr glintReg);
+Bool Permedia2Init(ScrnInfoPtr pScrn, DisplayModePtr mode);
+Bool Permedia2AccelInit(ScreenPtr pScreen);
+void Permedia2Sync(ScrnInfoPtr pScrn);
+void Permedia2InitializeEngine(ScrnInfoPtr pScrn);
+Bool Permedia2HWCursorInit(ScreenPtr pScreen);
+
+void PermediaRestore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg);
+void PermediaSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg);
+Bool PermediaInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+Bool PermediaAccelInit(ScreenPtr pScreen);
+void Permedia2VRestore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg);
+void Permedia2VSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg);
+Bool Permedia2VInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+Bool Permedia2vHWCursorInit(ScreenPtr pScreen);
+
+void TXRestore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg);
+void TXSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg);
+Bool TXInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+Bool TXAccelInit(ScreenPtr pScreen);
+
+void DualMXRestore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg);
+void DualMXSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg);
+Bool DualMXInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+Bool DualMXAccelInit(ScreenPtr pScreen);
+
+void glintOutIBMRGBIndReg(ScrnInfoPtr pScrn,
+ CARD32 reg, unsigned char mask, unsigned char data);
+unsigned char glintInIBMRGBIndReg(ScrnInfoPtr pScrn, CARD32 reg);
+void glintIBMWriteAddress(ScrnInfoPtr pScrn, CARD32 index);
+void glintIBMReadAddress(ScrnInfoPtr pScrn, CARD32 index);
+void glintIBMWriteData(ScrnInfoPtr pScrn, unsigned char data);
+Bool glintIBMHWCursorInit(ScreenPtr pScreen);
+unsigned char glintIBMReadData(ScrnInfoPtr pScrn);
+Bool glintIBM526HWCursorInit(ScreenPtr pScreen);
+Bool glintIBM640HWCursorInit(ScreenPtr pScreen);
+
+void glintOutTIIndReg(ScrnInfoPtr pScrn,
+ CARD32 reg, unsigned char mask, unsigned char data);
+unsigned char glintInTIIndReg(ScrnInfoPtr pScrn, CARD32 reg);
+void glintTIWriteAddress(ScrnInfoPtr pScrn, CARD32 index);
+void glintTIReadAddress(ScrnInfoPtr pScrn, CARD32 index);
+void glintTIWriteData(ScrnInfoPtr pScrn, unsigned char data);
+unsigned char glintTIReadData(ScrnInfoPtr pScrn);
+Bool glintTIHWCursorInit(ScreenPtr pScreen);
+
+void Permedia2OutIndReg(ScrnInfoPtr pScrn,
+ CARD32, unsigned char mask, unsigned char data);
+unsigned char Permedia2InIndReg(ScrnInfoPtr pScrn, CARD32);
+void Permedia2WriteAddress(ScrnInfoPtr pScrn, CARD32 index);
+void Permedia2ReadAddress(ScrnInfoPtr pScrn, CARD32 index);
+void Permedia2WriteData(ScrnInfoPtr pScrn, unsigned char data);
+unsigned char Permedia2ReadData(ScrnInfoPtr pScrn);
+void Permedia2LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual);
+void Permedia2LoadPalette16(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual);
+void Permedia2I2CUDelay(I2CBusPtr b, int usec);
+void Permedia2I2CPutBits(I2CBusPtr b, int scl, int sda);
+void Permedia2I2CGetBits(I2CBusPtr b, int *scl, int *sda);
+
+void Permedia2VideoUninit(ScrnInfoPtr pScrn);
+void Permedia2VideoReset(ScrnInfoPtr pScrn);
+void Permedia2VideoInit(ScreenPtr pScreen);
+
+void Permedia2vOutIndReg(ScrnInfoPtr pScrn,
+ CARD32, unsigned char mask, unsigned char data);
+unsigned char Permedia2vInIndReg(ScrnInfoPtr pScrn, CARD32);
+
+extern int partprodPermedia[];
+
+Bool GLINTDRIScreenInit(ScreenPtr pScreen);
+Bool GLINTDRIFinishScreenInit(ScreenPtr pScreen);
+void GLINTDRICloseScreen(ScreenPtr pScreen);
+Bool GLINTInitGLXVisuals(ScreenPtr pScreen);
+void GLINTDRIWakeupHandler(ScreenPtr pScreen);
+void GLINTDRIBlockHandler(ScreenPtr pScreen);
+void GLINTDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index);
+void GLINTDRIMoveBuffers(WindowPtr pWin, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc, CARD32 index);
+
+void GLINT_VERB_WRITE_REG(GLINTPtr, CARD32 v, int r, char *file, int line);
+CARD32 GLINT_VERB_READ_REG(GLINTPtr, CARD32 r, char *file, int line);
+#endif /* _GLINT_H_ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c
new file mode 100644
index 000000000..165234a25
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c
@@ -0,0 +1,1876 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c,v 1.5 1999/07/18 03:26:56 dawes Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+
+/*
+ * Author:
+ * Jens Owen <jens@precisioninsight.com>
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.c,v 1.52 1999/07/08 14:33:38 faith Exp $
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Priv.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb32.h"
+
+#include "miline.h"
+
+#include "GL/glxtokens.h"
+
+#include "glint_regs.h"
+#include "glint.h"
+#include "glint_dri.h"
+
+static char GLINTKernelDriverName[] = "generic";
+static char GLINTClientDriverName[] = "gamma";
+
+#define USE_LEGACY_DMA 1
+
+static int
+GLINTDRIControlInitSingleMX(int drmSubFD, int irq)
+{
+
+ int retcode;
+ static int dma_dispatch[] = {
+#if USE_LEGACY_DMA
+ DRM_I_WRITE_R( DMAAddress, DRM_T_ADDRESS, 0, DRM_V_NONE, 0),
+ DRM_I_WHILE_IMM_R(GCommandStatus, 4, DRM_C_NE),
+#if 0
+ DRM_I_WHILE_IMM_R(DMACount, 0, DRM_C_NE),
+#endif
+ DRM_I_WRITE_R( DMACount, DRM_T_LENGTH, 0, DRM_V_RSHIFT, 2)
+#else
+#define GDMAAddressTag 0x530
+#define GDMACountTag 0x531
+ DRM_I_WHILE_IMM_R(InFIFOSpace, 2, DRM_C_LT),
+ DRM_I_WRITE_IMM_R(OutputFIFO, GDMAAddressTag),
+ DRM_I_WRITE_R( OutputFIFO, DRM_T_ADDRESS, 0, DRM_V_NONE, 0),
+ DRM_I_WRITE_IMM_R(OutputFIFO, GDMACountTag),
+ DRM_I_WRITE_R( OutputFIFO, DRM_T_LENGTH, 0, DRM_V_RSHIFT, 2)
+
+#endif
+ };
+ static int dma_quiescent[] = {
+ DRM_I_WHILE_IMM_R(DMACount, 0, DRM_C_NE), /* 0 */
+ DRM_I_WHILE_IMM_R(InFIFOSpace, 3, DRM_C_LT), /* 1 */
+ DRM_I_WRITE_IMM_R(FilterMode, 1<<10), /* 2 */
+ DRM_I_WRITE_IMM_R(GLINTSync, 0), /* 3 */
+ /* Read from first MX */
+ DRM_I_WHILE_IMM_R(OutFIFOWords, 0, DRM_C_EQ), /* 4 */
+ DRM_I_IF_IMM_R( OutputFIFO, GLINTSyncTag, DRM_C_EQ, 7), /* 5 */
+ DRM_I_GOTO(5), /* 6 */
+ DRM_I_RETURN(0) /* 7 */
+ };
+ static int dma_ready[] = {
+ DRM_I_WHILE_IMM_R(DMACount, 0, DRM_C_NE)
+ };
+ static int dma_is_ready[] = {
+ /* Return */
+ DRM_I_IF_IMM_R( DMACount, 0, DRM_C_NE, 2),/* DMA in progress 0 */
+ DRM_I_RETURN(1), /* 1 */
+ DRM_I_RETURN(0) /* 2 */
+ };
+ static int dma_service[] = {
+#if 0
+ /* 0xc350 is 0.1S */
+ DRM_I_WRITE_IMM_R(GDelayTimer, 0xc350), /* 0.1S */ /* 0 */
+#else
+ DRM_I_WRITE_IMM_R(GDelayTimer, 0xc350/2), /* 0.05S */ /* 0 */
+#endif
+ DRM_I_WRITE_IMM_R(GCommandIntFlags, USE_LEGACY_DMA ? 8 : 9 ), /* 1 */
+ DRM_I_WRITE_IMM_R(GIntFlags, 0x2001), /* 2 */
+ DRM_I_IF_IMM_R(DMACount, 0, DRM_C_NE, 7), /* DMA in progress 3 */
+ DRM_I_DO(DRM_F_CLEAR), /* 4 */
+ DRM_I_DO(DRM_F_DMA), /* DMA */ /* 5 */
+ DRM_I_RETURN(0), /* 6 */
+#if 0
+ DRM_I_WRITE_IMM_R(GDelayTimer, 0xc350/4), /* 0.025S */ /* 7 */
+#endif
+ };
+ static int dma_pre_inst[] = {
+ DRM_I_WRITE_IMM_R(GCommandMode, USE_LEGACY_DMA ? 0x0000 : 0x0001),
+ DRM_I_WRITE_IMM_R(GDMAControl, 0x0000)
+ };
+ static int dma_post_inst[] = {
+ DRM_I_WRITE_IMM_R(GIntEnable, 0x2001),
+ DRM_I_WRITE_IMM_R(GCommandIntEnable, USE_LEGACY_DMA ? 0x0008 : 0x0009),
+ DRM_I_WRITE_IMM_R(GDelayTimer, 0x3d090)
+ };
+ static int dma_pre_uninst[] = {
+ DRM_I_WRITE_IMM_R(GDelayTimer, 0x0000),
+ DRM_I_WRITE_IMM_R(GCommandIntEnable, 0x0000),
+ DRM_I_WRITE_IMM_R(GIntEnable, 0x0000)
+ };
+
+
+#define DRM_COUNT(x) ((sizeof(x)/sizeof(x[0]))/DRM_INST_LENGTH)
+
+ struct {
+ int *inst;
+ int count;
+ drmCtlDesc desc;
+ } *pt, dma_control_routines[] = {
+ { dma_dispatch, DRM_COUNT(dma_dispatch), DRM_DMA_DISPATCH },
+ { dma_quiescent, DRM_COUNT(dma_quiescent), DRM_DMA_QUIESCENT },
+ { dma_ready, DRM_COUNT(dma_ready), DRM_DMA_READY },
+ { dma_is_ready, DRM_COUNT(dma_is_ready), DRM_DMA_IS_READY },
+ { dma_service, DRM_COUNT(dma_service), DRM_IH_SERVICE },
+ { dma_pre_inst, DRM_COUNT(dma_pre_inst), DRM_IH_PRE_INST },
+ { dma_post_inst, DRM_COUNT(dma_post_inst), DRM_IH_POST_INST },
+ { dma_pre_uninst, DRM_COUNT(dma_pre_uninst), DRM_IH_PRE_UNINST },
+ { NULL, 0 }
+ };
+
+ for (pt = dma_control_routines; pt->count; pt++) {
+ if ((retcode = drmCtlAddCommand(drmSubFD,
+ pt->desc, pt->count, pt->inst))) {
+ return 1;
+ }
+ }
+
+ if ((retcode = drmCtlInstHandler(drmSubFD, irq))) return 1;
+ return 0;
+}
+
+static int
+GLINTDRIControlInitDualMX(int drmSubFD, int irq)
+{
+ int retcode;
+ static int dma_dispatch[] = {
+#if USE_LEGACY_DMA
+ DRM_I_WRITE_R( DMAAddress, DRM_T_ADDRESS, 0, DRM_V_NONE, 0),
+ DRM_I_WHILE_IMM_R(GCommandStatus, 4, DRM_C_NE),
+#if 0
+ DRM_I_WHILE_IMM_R(DMACount, 0, DRM_C_NE),
+#endif
+ DRM_I_WRITE_R( DMACount, DRM_T_LENGTH, 0, DRM_V_RSHIFT, 2)
+#else
+#define GDMAAddressTag 0x530
+#define GDMACountTag 0x531
+ DRM_I_WHILE_IMM_R(InFIFOSpace, 2, DRM_C_LT),
+ DRM_I_WRITE_IMM_R(OutputFIFO, GDMAAddressTag),
+ DRM_I_WRITE_R( OutputFIFO, DRM_T_ADDRESS, 0, DRM_V_NONE, 0),
+ DRM_I_WRITE_IMM_R(OutputFIFO, GDMACountTag),
+ DRM_I_WRITE_R( OutputFIFO, DRM_T_LENGTH, 0, DRM_V_RSHIFT, 2)
+
+#endif
+ };
+ static int dma_quiescent[] = {
+ DRM_I_WHILE_IMM_R(DMACount, 0, DRM_C_NE), /* 0 */
+ DRM_I_WHILE_IMM_R(InFIFOSpace, 3, DRM_C_LT), /* 1 */
+ DRM_I_WRITE_IMM_R(BroadcastMask, 3), /* 2 */
+ DRM_I_WRITE_IMM_R(FilterMode, 1<<10), /* 3 */
+ DRM_I_WRITE_IMM_R(GLINTSync, 0), /* 4 */
+ /* Read from first MX */
+ DRM_I_WHILE_IMM_R(OutFIFOWords, 0, DRM_C_EQ), /* 5 */
+ DRM_I_IF_IMM_R( OutputFIFO, GLINTSyncTag, DRM_C_EQ, 8), /* 6 */
+ DRM_I_GOTO(5), /* 7 */
+ /* Read from second MX */
+ DRM_I_WHILE_IMM_R(OutFIFOWords+0x10000, 0, DRM_C_EQ), /* 8 */
+ DRM_I_IF_IMM_R(OutputFIFO+0x10000, GLINTSyncTag, DRM_C_EQ,11),/* 9 */
+ DRM_I_GOTO(8), /* 10 */
+ DRM_I_RETURN(0) /* 11 */
+ };
+ static int dma_ready[] = {
+ DRM_I_WHILE_IMM_R(DMACount, 0, DRM_C_NE)
+ };
+ static int dma_is_ready[] = {
+ /* Return */
+ DRM_I_IF_IMM_R( DMACount, 0, DRM_C_NE, 2),/* DMA in progress 0 */
+ DRM_I_RETURN(1), /* 1 */
+ DRM_I_RETURN(0) /* 2 */
+ };
+ static int dma_service[] = {
+#if 0
+ /* 0xc350 is 0.1S */
+ DRM_I_WRITE_IMM_R(GDelayTimer, 0xc350), /* 0.1S */ /* 0 */
+#else
+ DRM_I_WRITE_IMM_R(GDelayTimer, 0xc350/2), /* 0.05S */ /* 0 */
+#endif
+ DRM_I_WRITE_IMM_R(GCommandIntFlags, USE_LEGACY_DMA ? 8 : 9 ), /* 1 */
+ DRM_I_WRITE_IMM_R(GIntFlags, 0x2001), /* 2 */
+ DRM_I_IF_IMM_R(DMACount, 0, DRM_C_NE, 7), /* DMA in progress 3 */
+ DRM_I_DO(DRM_F_CLEAR), /* 4 */
+ DRM_I_DO(DRM_F_DMA), /* DMA */ /* 5 */
+ DRM_I_RETURN(0), /* 6 */
+#if 0
+ DRM_I_WRITE_IMM_R(GDelayTimer, 0xc350/4), /* 0.025S */ /* 7 */
+#endif
+ };
+ static int dma_pre_inst[] = {
+ DRM_I_WRITE_IMM_R(GCommandMode, USE_LEGACY_DMA ? 0x0000 : 0x0001),
+ DRM_I_WRITE_IMM_R(GDMAControl, 0x0000)
+ };
+ static int dma_post_inst[] = {
+ DRM_I_WRITE_IMM_R(GIntEnable, 0x2001),
+ DRM_I_WRITE_IMM_R(GCommandIntEnable, USE_LEGACY_DMA ? 0x0008 : 0x0009),
+ DRM_I_WRITE_IMM_R(GDelayTimer, 0x3d090)
+ };
+ static int dma_pre_uninst[] = {
+ DRM_I_WRITE_IMM_R(GDelayTimer, 0x0000),
+ DRM_I_WRITE_IMM_R(GCommandIntEnable, 0x0000),
+ DRM_I_WRITE_IMM_R(GIntEnable, 0x0000)
+ };
+
+
+#define DRM_COUNT(x) ((sizeof(x)/sizeof(x[0]))/DRM_INST_LENGTH)
+
+ struct {
+ int *inst;
+ int count;
+ drmCtlDesc desc;
+ } *pt, dma_control_routines[] = {
+ { dma_dispatch, DRM_COUNT(dma_dispatch), DRM_DMA_DISPATCH },
+ { dma_quiescent, DRM_COUNT(dma_quiescent), DRM_DMA_QUIESCENT },
+ { dma_ready, DRM_COUNT(dma_ready), DRM_DMA_READY },
+ { dma_is_ready, DRM_COUNT(dma_is_ready), DRM_DMA_IS_READY },
+ { dma_service, DRM_COUNT(dma_service), DRM_IH_SERVICE },
+ { dma_pre_inst, DRM_COUNT(dma_pre_inst), DRM_IH_PRE_INST },
+ { dma_post_inst, DRM_COUNT(dma_post_inst), DRM_IH_POST_INST },
+ { dma_pre_uninst, DRM_COUNT(dma_pre_uninst), DRM_IH_PRE_UNINST },
+ { NULL, 0 }
+ };
+
+ for (pt = dma_control_routines; pt->count; pt++) {
+ if ((retcode = drmCtlAddCommand(drmSubFD,
+ pt->desc, pt->count, pt->inst))) {
+ return 1;
+ }
+ }
+
+ if ((retcode = drmCtlInstHandler(drmSubFD, irq))) return 1;
+ return 0;
+}
+
+static Bool
+GLINTInitVisualConfigs(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int numConfigs = 0;
+ __GLXvisualConfig *pConfigs = NULL;
+ GLINTConfigPrivPtr pGlintConfigs = NULL;
+ GLINTConfigPrivPtr *pGlintConfigPtrs = NULL;
+ int i;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ break;
+ case 16:
+ if (pGlint->DoubleBuffer) {
+ }
+ else {
+ }
+ break;
+ case 24:
+ break;
+ case 32:
+ /* if(pGlint->Overlay): differentiate overlays when we support
+ either alpha buffer or 3D rendering in Overlay */
+ numConfigs = 5;
+
+ if (!(pConfigs = (__GLXvisualConfig *)xnfcalloc(
+ sizeof(__GLXvisualConfig),
+ numConfigs))) {
+ return FALSE;
+ }
+
+ if (!(pGlintConfigs = (GLINTConfigPrivPtr)xnfcalloc(
+ sizeof(GLINTConfigPrivRec),
+ numConfigs))) {
+ xfree(pConfigs);
+ return FALSE;
+ }
+
+ if (!(pGlintConfigPtrs = (GLINTConfigPrivPtr *)xnfcalloc(
+ sizeof(GLINTConfigPrivPtr),
+ numConfigs))) {
+ xfree(pGlintConfigs);
+ xfree(pConfigs);
+ return FALSE;
+ }
+
+ /* Init the list of Glint config pointers */
+ for (i = 0; i < numConfigs; i++)
+ pGlintConfigPtrs[i] = &pGlintConfigs[i];
+
+ /* config 0: db=FALSE, depth=0, stencil=0, conformant (a lie) */
+ pConfigs[0].vid = -1;
+ pConfigs[0].class = -1;
+ pConfigs[0].rgba = TRUE;
+ pConfigs[0].redSize = 8;
+ pConfigs[0].greenSize = 8;
+ pConfigs[0].blueSize = 8;
+ pConfigs[0].alphaSize = 0;
+ pConfigs[0].redMask = 0x00ff0000;
+ pConfigs[0].greenMask = 0x0000ff00;
+ pConfigs[0].blueMask = 0x000000ff;
+ pConfigs[0].alphaMask = 0;
+ pConfigs[0].accumRedSize = 0;
+ pConfigs[0].accumGreenSize = 0;
+ pConfigs[0].accumBlueSize = 0;
+ pConfigs[0].accumAlphaSize = 0;
+ pConfigs[0].doubleBuffer = FALSE;
+ pConfigs[0].stereo = FALSE;
+ pConfigs[0].bufferSize = 32;
+ pConfigs[0].depthSize = 0;
+ pConfigs[0].stencilSize = 0;
+ pConfigs[0].auxBuffers = 0;
+ pConfigs[0].level = 0;
+ pConfigs[0].visualRating = 0;
+ pConfigs[0].transparentPixel = 0;
+ pConfigs[0].transparentRed = 0;
+ pConfigs[0].transparentGreen = 0;
+ pConfigs[0].transparentBlue = 0;
+ pConfigs[0].transparentAlpha = 0;
+ pConfigs[0].transparentIndex = 0;
+ pGlintConfigs[0].index = 0;
+
+ /* config 1: db=FALSE, depth=16, stencil=0, conformant (a lie) */
+ pConfigs[1].vid = -1;
+ pConfigs[1].class = -1;
+ pConfigs[1].rgba = TRUE;
+ pConfigs[1].redSize = 8;
+ pConfigs[1].greenSize = 8;
+ pConfigs[1].blueSize = 8;
+ pConfigs[1].alphaSize = 0;
+ pConfigs[1].redMask = 0x00ff0000;
+ pConfigs[1].greenMask = 0x0000ff00;
+ pConfigs[1].blueMask = 0x000000ff;
+ pConfigs[1].alphaMask = 0;
+ pConfigs[1].accumRedSize = 0;
+ pConfigs[1].accumGreenSize = 0;
+ pConfigs[1].accumBlueSize = 0;
+ pConfigs[1].accumAlphaSize = 0;
+ pConfigs[1].doubleBuffer = FALSE;
+ pConfigs[1].stereo = FALSE;
+ pConfigs[1].bufferSize = 32;
+ pConfigs[1].depthSize = 16;
+ pConfigs[1].stencilSize = 0;
+ pConfigs[1].auxBuffers = 0;
+ pConfigs[1].level = 0;
+ pConfigs[1].visualRating = 0;
+ pConfigs[1].transparentPixel = 0;
+ pConfigs[1].transparentRed = 0;
+ pConfigs[1].transparentGreen = 0;
+ pConfigs[1].transparentBlue = 0;
+ pConfigs[1].transparentAlpha = 0;
+ pConfigs[1].transparentIndex = 0;
+ pGlintConfigs[1].index = 1;
+
+ /* config 2: db=TRUE, depth=0, stencil=0, conformant (a lie) */
+ pConfigs[2].vid = -1;
+ pConfigs[2].class = -1;
+ pConfigs[2].rgba = TRUE;
+ pConfigs[2].redSize = 8;
+ pConfigs[2].greenSize = 8;
+ pConfigs[2].blueSize = 8;
+ pConfigs[2].alphaSize = 0;
+ pConfigs[2].redMask = 0x00ff0000;
+ pConfigs[2].greenMask = 0x0000ff00;
+ pConfigs[2].blueMask = 0x000000ff;
+ pConfigs[2].alphaMask = 0;
+ pConfigs[2].accumRedSize = 0;
+ pConfigs[2].accumGreenSize = 0;
+ pConfigs[2].accumBlueSize = 0;
+ pConfigs[2].accumAlphaSize = 0;
+ pConfigs[2].doubleBuffer = TRUE;
+ pConfigs[2].stereo = FALSE;
+ pConfigs[2].bufferSize = 32;
+ pConfigs[2].depthSize = 0;
+ pConfigs[2].stencilSize = 0;
+ pConfigs[2].auxBuffers = 0;
+ pConfigs[2].level = 0;
+ pConfigs[2].visualRating = 0;
+ pConfigs[2].transparentPixel = 0;
+ pConfigs[2].transparentRed = 0;
+ pConfigs[2].transparentGreen = 0;
+ pConfigs[2].transparentBlue = 0;
+ pConfigs[2].transparentAlpha = 0;
+ pConfigs[2].transparentIndex = 0;
+ pGlintConfigs[2].index = 2;
+
+ /* config 3: db=TRUE, depth=16, stencil=0, conformant (a lie) */
+ pConfigs[3].vid = -1;
+ pConfigs[3].class = -1;
+ pConfigs[3].rgba = TRUE;
+ pConfigs[3].redSize = 8;
+ pConfigs[3].greenSize = 8;
+ pConfigs[3].blueSize = 8;
+ pConfigs[3].alphaSize = 0;
+ pConfigs[3].redMask = 0x00ff0000;
+ pConfigs[3].greenMask = 0x0000ff00;
+ pConfigs[3].blueMask = 0x000000ff;
+ pConfigs[3].alphaMask = 0;
+ pConfigs[3].accumRedSize = 0;
+ pConfigs[3].accumGreenSize = 0;
+ pConfigs[3].accumBlueSize = 0;
+ pConfigs[3].accumAlphaSize = 0;
+ pConfigs[3].doubleBuffer = TRUE;
+ pConfigs[3].stereo = FALSE;
+ pConfigs[3].bufferSize = 32;
+ pConfigs[3].depthSize = 16;
+ pConfigs[3].stencilSize = 0;
+ pConfigs[3].auxBuffers = 0;
+ pConfigs[3].level = 0;
+ pConfigs[3].visualRating = 0;
+ pConfigs[3].transparentPixel = 0;
+ pConfigs[3].transparentRed = 0;
+ pConfigs[3].transparentGreen = 0;
+ pConfigs[3].transparentBlue = 0;
+ pConfigs[3].transparentAlpha = 0;
+ pConfigs[3].transparentIndex = 0;
+ pGlintConfigs[3].index = 3;
+
+ /* config 4: db=TRUE, depth=16, stencil=8, conformant (a lie) */
+ pConfigs[4].vid = -1;
+ pConfigs[4].class = -1;
+ pConfigs[4].rgba = TRUE;
+ pConfigs[4].redSize = 8;
+ pConfigs[4].greenSize = 8;
+ pConfigs[4].blueSize = 8;
+ pConfigs[4].alphaSize = 0;
+ pConfigs[4].redMask = 0x00ff0000;
+ pConfigs[4].greenMask = 0x0000ff00;
+ pConfigs[4].blueMask = 0x000000ff;
+ pConfigs[4].alphaMask = 0;
+ pConfigs[4].accumRedSize = 0;
+ pConfigs[4].accumGreenSize = 0;
+ pConfigs[4].accumBlueSize = 0;
+ pConfigs[4].accumAlphaSize = 0;
+ pConfigs[4].doubleBuffer = TRUE;
+ pConfigs[4].stereo = FALSE;
+ pConfigs[4].bufferSize = 32;
+ pConfigs[4].depthSize = 16;
+ pConfigs[4].stencilSize = 8;
+ pConfigs[4].auxBuffers = 0;
+ pConfigs[4].level = 0;
+ pConfigs[4].visualRating = 0;
+ pConfigs[4].transparentPixel = 0;
+ pConfigs[4].transparentRed = 0;
+ pConfigs[4].transparentGreen = 0;
+ pConfigs[4].transparentBlue = 0;
+ pConfigs[4].transparentAlpha = 0;
+ pConfigs[4].transparentIndex = 0;
+ pGlintConfigs[4].index = 4;
+
+ break;
+ }
+
+ pGlint->numVisualConfigs = numConfigs;
+ pGlint->pVisualConfigs = pConfigs;
+ pGlint->pVisualConfigsPriv = pGlintConfigs;
+ GlxSetVisualConfigs(numConfigs, pConfigs, (void **)pGlintConfigPtrs);
+
+ /*
+ * All of the above visual configs use the same local buffer memory
+ * organiation, so just set once here at the bottom
+ */
+ GLINT_SLOW_WRITE_REG(
+ (LBRF_DepthWidth16 |
+ LBRF_StencilWidth8 |
+ LBRF_StencilPos16 |
+ LBRF_FrameCount8 |
+ LBRF_FrameCountPos24 |
+ LBRF_GIDWidth4 |
+ LBRF_GIDPos32 ), LBReadFormat);
+ GLINT_SLOW_WRITE_REG(
+ (LBRF_DepthWidth16 |
+ LBRF_StencilWidth8 |
+ LBRF_StencilPos16 |
+ LBRF_FrameCount8 |
+ LBRF_FrameCountPos24 |
+ LBRF_GIDWidth4 |
+ LBRF_GIDPos32 ), LBWriteFormat);
+ if (pGlint->numMXDevices == 2) {
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ (LBRF_DepthWidth16 |
+ LBRF_StencilWidth8 |
+ LBRF_StencilPos16 |
+ LBRF_FrameCount8 |
+ LBRF_FrameCountPos24 |
+ LBRF_GIDWidth4 |
+ LBRF_GIDPos32 ), LBReadFormat);
+ GLINT_SECONDARY_SLOW_WRITE_REG(
+ (LBRF_DepthWidth16 |
+ LBRF_StencilWidth8 |
+ LBRF_StencilPos16 |
+ LBRF_FrameCount8 |
+ LBRF_FrameCountPos24 |
+ LBRF_GIDWidth4 |
+ LBRF_GIDPos32 ), LBWriteFormat);
+ }
+
+ return TRUE;
+}
+
+Bool
+GLINTDRIScreenInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ DRIInfoPtr pDRIInfo;
+ GLINTDRIPtr pGlintDRI;
+ int dmabufs = 0;
+
+#if XFree86LOADER
+ /* Check that the GLX, DRI, and DRM modules have been loaded by testing
+ for canonical symbols in each module. */
+ if (!LoaderSymbol("GlxSetVisualConfigs")) return FALSE;
+ if (!LoaderSymbol("DRIScreenInit")) return FALSE;
+ if (!LoaderSymbol("drmAvailable")) return FALSE;
+#endif
+
+ if (pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_GAMMA) return FALSE;
+
+ if (pGlint->numMXDevices > 2) return FALSE;
+
+ pDRIInfo = DRICreateInfoRec();
+ if(pDRIInfo == NULL)
+ return FALSE;
+
+ pGlint->pDRIInfo = pDRIInfo;
+
+ /* setup device info */
+ pDRIInfo->drmDriverName = GLINTKernelDriverName;
+ pDRIInfo->clientDriverName = GLINTClientDriverName;
+ pDRIInfo->busIdString = xalloc(64); /* Freed in DRIDestroyInfoRec */
+ sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
+ ((pciConfigPtr)pGlint->PciInfo->thisCard)->busnum,
+ ((pciConfigPtr)pGlint->PciInfo->thisCard)->devnum,
+ ((pciConfigPtr)pGlint->PciInfo->thisCard)->funcnum);
+ pDRIInfo->ddxDriverMajorVersion = 0;
+ pDRIInfo->ddxDriverMinorVersion = 1;
+ pDRIInfo->ddxDriverPatchVersion = 0;
+ pDRIInfo->frameBufferPhysicalAddress = pGlint->FbAddress;
+ pDRIInfo->frameBufferSize = pGlint->FbMapSize;
+ pDRIInfo->frameBufferStride =
+ pScrn->displayWidth * (pScrn->bitsPerPixel >> 3);
+ pDRIInfo->ddxDrawableTableEntry = GLINT_MAX_DRAWABLES;
+
+ /* MAX_DRAWABLES set to number of GID's minus one for DDX */
+ if (SAREA_MAX_DRAWABLES < GLINT_MAX_DRAWABLES) {
+ pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES;
+ }
+ else {
+ pDRIInfo->maxDrawableTableEntry = GLINT_MAX_DRAWABLES;
+ }
+
+#ifdef NOT_DONE
+ /* FIXME need to extend DRI protocol to pass this size back to client
+ * for SAREA mapping that includes a device private record
+ */
+ pDRIInfo->SAREASize =
+ ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */
+ /* + shared memory device private rec */
+#else
+ /* For now the mapping works by using a fixed size defined
+ * in the SAREA header
+ */
+ pDRIInfo->SAREASize = SAREA_MAX;
+#endif
+
+ if (!(pGlintDRI = (GLINTDRIPtr)xnfcalloc(sizeof(GLINTDRIRec),1))) {
+ DRIDestroyInfoRec(pGlint->pDRIInfo);
+ return FALSE;
+ }
+ pDRIInfo->devPrivate = pGlintDRI;
+ pDRIInfo->devPrivateSize = sizeof(GLINTDRIRec);
+ pDRIInfo->contextSize = sizeof(GLINTDRIContextRec);
+
+ /* setup call backs */
+ pDRIInfo->CreateContext = GLINTCreateContext;
+ pDRIInfo->SwapContext = GLINTDRISwapContext;
+ pDRIInfo->InitBuffers = GLINTDRIInitBuffers;
+ pDRIInfo->MoveBuffers = GLINTDRIMoveBuffers;
+ pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
+
+ if (!DRIScreenInit(pScreen, pDRIInfo, &(pGlint->drmSubFD))) {
+ DRIDestroyInfoRec(pGlint->pDRIInfo);
+ xfree(pGlintDRI);
+ return FALSE;
+ }
+
+ /* setup device specific direct rendering memory maps */
+
+ /* pci region 0: control regs, first 4k page, priveledged writes */
+ pGlintDRI->flagsControlRegs0 = DRM_READ_ONLY;
+ pGlintDRI->sizeControlRegs0 = 0x1000;
+ if (drmAddMap( pGlint->drmSubFD,
+ (drmHandle)pGlint->IOAddress,
+ pGlintDRI->sizeControlRegs0,
+ DRM_REGISTERS,
+ pGlintDRI->flagsControlRegs0,
+ &pGlintDRI->hControlRegs0) < 0)
+ {
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] Register handle 0 = 0x%08lx\n",
+ pGlintDRI->hControlRegs0);
+
+ /* pci region 0: control regs, following region, client access */
+ pGlintDRI->flagsControlRegs1 = 0;
+ pGlintDRI->sizeControlRegs1 = 0xf000;
+ if (drmAddMap( pGlint->drmSubFD,
+ (drmHandle)(pGlint->IOAddress + 0x1000),
+ pGlintDRI->sizeControlRegs1,
+ DRM_REGISTERS,
+ pGlintDRI->flagsControlRegs1,
+ &pGlintDRI->hControlRegs1) < 0)
+ {
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] Register handle 1 = 0x%08lx\n",
+ pGlintDRI->hControlRegs1);
+
+ /* pci region 0: control regs, second MX, first 4k page */
+ pGlintDRI->flagsControlRegs2 = DRM_READ_ONLY;
+ pGlintDRI->sizeControlRegs2 = 0x1000;
+ if (drmAddMap( pGlint->drmSubFD,
+ (drmHandle)(pGlint->IOAddress + 0x10000),
+ pGlintDRI->sizeControlRegs2,
+ DRM_REGISTERS,
+ pGlintDRI->flagsControlRegs2,
+ &pGlintDRI->hControlRegs2) < 0)
+ {
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] Register handle 2 = 0x%08lx\n",
+ pGlintDRI->hControlRegs2);
+
+ /* pci region 0: control regs, second MX, following region */
+ pGlintDRI->flagsControlRegs3 = 0;
+ pGlintDRI->sizeControlRegs3 = 0xf000;
+ if (drmAddMap( pGlint->drmSubFD,
+ (drmHandle)(pGlint->IOAddress + 0x11000),
+ pGlintDRI->sizeControlRegs3,
+ DRM_REGISTERS,
+ pGlintDRI->flagsControlRegs3,
+ &pGlintDRI->hControlRegs3) < 0)
+ {
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] Register handle 3 = 0x%08lx\n",
+ pGlintDRI->hControlRegs3);
+
+ /* setup DMA buffers */
+
+ if (xf86ConfigDRI.bufs_count) {
+ int i;
+ int bufs;
+
+ for (i = 0; i < xf86ConfigDRI.bufs_count; i++) {
+ if ((bufs = drmAddBufs(pGlint->drmSubFD,
+ xf86ConfigDRI.bufs[i].count,
+ xf86ConfigDRI.bufs[i].size,
+ 0 /* flags */)) <= 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] failure adding %d %d byte DMA buffers\n",
+ xf86ConfigDRI.bufs[i].count,
+ xf86ConfigDRI.bufs[i].size);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] added %d %d byte DMA buffers\n",
+ bufs, xf86ConfigDRI.bufs[i].size);
+ dmabufs += bufs;
+ }
+ }
+ }
+
+ if (dmabufs <= 0) {
+ int bufs;
+
+ if ((bufs = drmAddBufs(pGlint->drmSubFD,
+ GLINT_DRI_BUF_COUNT,
+ GLINT_DRI_BUF_SIZE,
+ 0 /* flags */)) <= 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] failure adding %d %d byte DMA buffers\n",
+ GLINT_DRI_BUF_COUNT,
+ GLINT_DRI_BUF_SIZE);
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] added %d %d byte DMA buffers\n",
+ bufs, GLINT_DRI_BUF_SIZE);
+ }
+
+ /* -->> If you mark the buffer queueing policy, you'd do it here. <<-- */
+
+ if (!(pGlint->drmBufs = drmMapBufs(pGlint->drmSubFD))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] failure mapping DMA buffers\n");
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] buffers mapped with %p\n",
+ pGlint->drmBufs);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] %d DMA buffers mapped\n",
+ pGlint->drmBufs->count);
+
+ /* tell the generic kernel driver how to handle Gamma DMA */
+ if (!pGlint->irq) {
+ pGlint->irq = drmGetInterruptFromBusID(pGlint->drmSubFD,
+ ((pciConfigPtr)pGlint->PciInfo
+ ->thisCard)->busnum,
+ ((pciConfigPtr)pGlint->PciInfo
+ ->thisCard)->devnum,
+ ((pciConfigPtr)pGlint->PciInfo
+ ->thisCard)->funcnum);
+ }
+
+ if (pGlint->numMXDevices == 2) {
+ if ( (pGlint->irq <= 0) ||
+ GLINTDRIControlInitDualMX(pGlint->drmSubFD, pGlint->irq) ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] cannot initialize dma with IRQ %d\n",
+ pGlint->irq);
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ }
+
+ if (pGlint->numMXDevices == 1) {
+ if ( (pGlint->irq <= 0) ||
+ GLINTDRIControlInitSingleMX(pGlint->drmSubFD, pGlint->irq) ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] cannot initialize dma with IRQ %d\n",
+ pGlint->irq);
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] dma control initialized, using IRQ %d\n",
+ pGlint->irq);
+
+ /* setup visual configurations */
+ if (!(GLINTInitVisualConfigs(pScreen))) {
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "visual configs initialized\n" );
+
+ return TRUE;
+}
+
+void
+GLINTDRICloseScreen(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[drm] unmapping %d buffers\n",
+ pGlint->drmBufs->count);
+ if (drmUnmapBufs(pGlint->drmBufs)) {
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "[drm] unable to unmap DMA buffers\n");
+ }
+
+ DRICloseScreen(pScreen);
+
+ if (pGlint->pDRIInfo) {
+ if (pGlint->pDRIInfo->devPrivate) {
+ xfree(pGlint->pDRIInfo->devPrivate);
+ }
+ DRIDestroyInfoRec(pGlint->pDRIInfo);
+ }
+
+ if (pGlint->pVisualConfigs) xfree(pGlint->pVisualConfigs);
+ if (pGlint->pVisualConfigsPriv) xfree(pGlint->pVisualConfigsPriv);
+}
+
+Bool
+GLINTCreateContext(ScreenPtr pScreen,
+ VisualPtr visual,
+ drmContext hwContext,
+ void *pVisualConfigPriv)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ GLINTConfigPrivPtr pGlintConfig = (GLINTConfigPrivPtr)pVisualConfigPriv;
+
+ /* These are really assertions rather than necessary logic,
+ just using this to exercise device private region until really needed */
+
+ if (!pGlintConfig)
+ return TRUE; /* no GLX driver private support, yet */
+
+#if 1
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "[GLINTCreateContext] context priv index = %d\n",
+ pGlintConfig->index);
+#endif
+
+ if (pGlintConfig->index >= pGlint->numVisualConfigs)
+ return FALSE;
+
+ if (pGlint->pVisualConfigs[pGlintConfig->index].redMask != visual->redMask)
+ return FALSE;
+
+ return TRUE;
+}
+
+Bool
+GLINTDRIFinishScreenInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ /*
+ * Setup one of 4 types of context swap handling methods
+ *
+ * Option A: HIDE X CONTEXT SWAPS. X contexts will be flagged as
+ * preserved by the server. The kernel will never swap a preserved
+ * context. The kernel will call back into the server for swapping
+ * all other contexts.
+ *
+ * pGlint->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;
+ *
+ *
+ * Option B: SERVER SIDE CONTEXT SWAPS. X contexts will be flagged
+ * as 2D contexts, but the flag will be ignored by the kernel. The
+ * preserved flag will not be used, so the kernel will call back into
+ * the server for swapping all contexts. The 2D flag will be used by
+ * the server to optimize for 2D/3D switching between a single 3D
+ * context and the servers 2D context.
+ *
+ * pGlint->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP;
+ *
+ *
+ * Option C: KERNEL SIDE GENERIC SWAPS. X server will provide generic
+ * kernel driver with byte codes for performing swap. X contexts will
+ * be flagged as 2D contexts, so 2D/3D switching optimizations can still
+ * be done. This is not supported, yet. Additional work is required
+ * to support generic kernel driver and provide byte code examples.
+ *
+ * pGlint->pDRIInfo->driverSwapMethod = DRI_KERNEL_SWAP;
+ *
+ * add byte codes for context swap here:
+ * drmCtlAddCommand(drmSubFD, ...
+ *
+ *
+ * Option D: KERNEL SIDE DEVICE SPECIFIC SWAPS. DrmSubdriver will
+ * have device specific code for handling swaps. X context will be
+ * flagged as 2D contexts, so 2D/3D switching optimizations can still
+ * be done. This is not supported by gamma driver, yet; however, the
+ * framework is in place to use this option.
+ *
+ * pGlint->pDRIInfo->driverSwapMethod = DRI_KERNEL_SWAP;
+ */
+
+ pGlint->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;
+
+ return(DRIFinishScreenInit(pScreen));
+}
+
+#define ContextDump_tag 0x1b8
+#define ContextRestore_tag 0x1b9
+#define ContextData_tag 0x1ba
+
+void
+GLINTDRISwapContext(
+ ScreenPtr pScreen,
+ DRISyncType syncType,
+ DRIContextType readContextType,
+ void** readContextStore,
+ DRIContextType writeContextType,
+ void** writeContextStore)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ GLINTDRIContextPtr pRC = (GLINTDRIContextPtr)readContextStore;
+ GLINTDRIContextPtr pWC = (GLINTDRIContextPtr)writeContextStore;
+ int dumpIndex;
+ CARD32 readValue;
+
+ /* Sync here covers both read and write context of contexts */
+ if (pGlint->AccelInfoRec->Sync) {
+ (*pGlint->AccelInfoRec->Sync)(pGlint->AccelInfoRec->pScrn);
+ }
+ pGlint->AccelInfoRec->NeedToSync = FALSE;
+
+ if (readContextType != DRI_NO_CONTEXT) {
+
+ /* save the 2D portion of the old context */
+ pRC->MX1.CStartXDom = GLINT_READ_REG(StartXDom);
+ pRC->MX1.CdXDom = GLINT_READ_REG(dXDom);
+ pRC->MX1.CStartXSub = GLINT_READ_REG(StartXSub);
+ pRC->MX1.CdXSub = GLINT_READ_REG(dXSub);
+ pRC->MX1.CStartY = GLINT_READ_REG(StartY);
+ pRC->MX1.CdY = GLINT_READ_REG(dY);
+ pRC->MX1.CGLINTCount = GLINT_READ_REG(GLINTCount);
+ pRC->MX1.CPointTable0 = GLINT_READ_REG(PointTable0);
+ pRC->MX1.CPointTable1 = GLINT_READ_REG(PointTable1);
+ pRC->MX1.CPointTable2 = GLINT_READ_REG(PointTable2);
+ pRC->MX1.CPointTable3 = GLINT_READ_REG(PointTable3);
+ pRC->MX1.CRasterizerMode = GLINT_READ_REG(RasterizerMode);
+ pRC->MX1.CYLimits = GLINT_READ_REG(YLimits);
+ pRC->MX1.CScanLineOwnership = GLINT_READ_REG(ScanLineOwnership);
+ pRC->MX1.CPixelSize = GLINT_READ_REG(PixelSize);
+ pRC->MX1.CScissorMode = GLINT_READ_REG(ScissorMode);
+ pRC->MX1.CScissorMinXY = GLINT_READ_REG(ScissorMinXY);
+ pRC->MX1.CScissorMaxXY = GLINT_READ_REG(ScissorMaxXY);
+ pRC->MX1.CScreenSize = GLINT_READ_REG(ScreenSize);
+ pRC->MX1.CAreaStippleMode = GLINT_READ_REG(AreaStippleMode);
+ pRC->MX1.CLineStippleMode = GLINT_READ_REG(LineStippleMode);
+ pRC->MX1.CLoadLineStippleCounters = GLINT_READ_REG(LoadLineStippleCounters);
+ pRC->MX1.CWindowOrigin = GLINT_READ_REG(WindowOrigin);
+ pRC->MX1.CRouterMode = GLINT_READ_REG(RouterMode);
+ pRC->MX1.CTextureAddressMode = GLINT_READ_REG(TextureAddressMode);
+ pRC->MX1.CTextureReadMode = GLINT_READ_REG(TextureReadMode);
+ pRC->MX1.CTextureColorMode = GLINT_READ_REG(TextureColorMode);
+ pRC->MX1.CFogMode = GLINT_READ_REG(FogMode);
+ pRC->MX1.CColorDDAMode = GLINT_READ_REG(ColorDDAMode);
+ pRC->MX1.CGLINTColor = GLINT_READ_REG(GLINTColor);
+ pRC->MX1.CAlphaTestMode = GLINT_READ_REG(AlphaTestMode);
+ pRC->MX1.CAntialiasMode = GLINT_READ_REG(AntialiasMode);
+ pRC->MX1.CAlphaBlendMode = GLINT_READ_REG(AlphaBlendMode);
+ pRC->MX1.CDitherMode = GLINT_READ_REG(DitherMode);
+ pRC->MX1.CFBSoftwareWriteMask = GLINT_READ_REG(FBSoftwareWriteMask);
+ pRC->MX1.CLogicalOpMode = GLINT_READ_REG(LogicalOpMode);
+ pRC->MX1.CFBWriteData = GLINT_READ_REG(FBWriteData);
+ pRC->MX1.CLBReadMode = GLINT_READ_REG(LBReadMode);
+ pRC->MX1.CLBSourceOffset = GLINT_READ_REG(LBSourceOffset);
+ pRC->MX1.CLBWindowBase = GLINT_READ_REG(LBWindowBase);
+ pRC->MX1.CLBWriteMode = GLINT_READ_REG(LBWriteMode);
+ pRC->MX1.CTextureDownloadOffset = GLINT_READ_REG(TextureDownloadOffset);
+ pRC->MX1.CLBWindowOffset = GLINT_READ_REG(LBWindowOffset);
+ pRC->MX1.CGLINTWindow = GLINT_READ_REG(GLINTWindow);
+ pRC->MX1.CStencilMode = GLINT_READ_REG(StencilMode);
+ pRC->MX1.CDepthMode = GLINT_READ_REG(DepthMode);
+ pRC->MX1.CGLINTDepth = GLINT_READ_REG(GLINTDepth);
+ pRC->MX1.CFBReadMode = GLINT_READ_REG(FBReadMode);
+ pRC->MX1.CFBSourceOffset = GLINT_READ_REG(FBSourceOffset);
+ pRC->MX1.CFBPixelOffset = GLINT_READ_REG(FBPixelOffset);
+ pRC->MX1.CFBWindowBase = GLINT_READ_REG(FBWindowBase);
+ pRC->MX1.CFBWriteMode = GLINT_READ_REG(FBWriteMode);
+ pRC->MX1.CFBHardwareWriteMask = GLINT_READ_REG(FBHardwareWriteMask);
+ pRC->MX1.CFBBlockColor = GLINT_READ_REG(FBBlockColor);
+ pRC->MX1.CPatternRamMode = GLINT_READ_REG(PatternRamMode);
+ pRC->MX1.CFBBlockColorU = GLINT_READ_REG(FBBlockColorU);
+ pRC->MX1.CFBBlockColorL = GLINT_READ_REG(FBBlockColorL);
+ pRC->MX1.CFilterMode = GLINT_READ_REG(FilterMode);
+ pRC->MX1.CStatisticMode = GLINT_READ_REG(StatisticMode);
+
+ if (pGlint->numMXDevices == 2) {
+ pRC->MX1.CBroadcastMask = GLINT_READ_REG(BroadcastMask);
+
+ pRC->MX2.CStartXDom = GLINT_SECONDARY_READ_REG(StartXDom);
+ pRC->MX2.CdXDom = GLINT_SECONDARY_READ_REG(dXDom);
+ pRC->MX2.CStartXSub = GLINT_SECONDARY_READ_REG(StartXSub);
+ pRC->MX2.CdXSub = GLINT_SECONDARY_READ_REG(dXSub);
+ pRC->MX2.CStartY = GLINT_SECONDARY_READ_REG(StartY);
+ pRC->MX2.CdY = GLINT_SECONDARY_READ_REG(dY);
+ pRC->MX2.CGLINTCount = GLINT_SECONDARY_READ_REG(GLINTCount);
+ pRC->MX2.CPointTable0 = GLINT_SECONDARY_READ_REG(PointTable0);
+ pRC->MX2.CPointTable1 = GLINT_SECONDARY_READ_REG(PointTable1);
+ pRC->MX2.CPointTable2 = GLINT_SECONDARY_READ_REG(PointTable2);
+ pRC->MX2.CPointTable3 = GLINT_SECONDARY_READ_REG(PointTable3);
+ pRC->MX2.CRasterizerMode = GLINT_SECONDARY_READ_REG(RasterizerMode);
+ pRC->MX2.CYLimits = GLINT_SECONDARY_READ_REG(YLimits);
+ pRC->MX2.CScanLineOwnership = GLINT_SECONDARY_READ_REG(ScanLineOwnership);
+ pRC->MX2.CPixelSize = GLINT_SECONDARY_READ_REG(PixelSize);
+ pRC->MX2.CScissorMode = GLINT_SECONDARY_READ_REG(ScissorMode);
+ pRC->MX2.CScissorMinXY = GLINT_SECONDARY_READ_REG(ScissorMinXY);
+ pRC->MX2.CScissorMaxXY = GLINT_SECONDARY_READ_REG(ScissorMaxXY);
+ pRC->MX2.CScreenSize = GLINT_SECONDARY_READ_REG(ScreenSize);
+ pRC->MX2.CAreaStippleMode = GLINT_SECONDARY_READ_REG(AreaStippleMode);
+ pRC->MX2.CLineStippleMode = GLINT_SECONDARY_READ_REG(LineStippleMode);
+ pRC->MX2.CLoadLineStippleCounters = GLINT_SECONDARY_READ_REG(LoadLineStippleCounters);
+ pRC->MX2.CWindowOrigin = GLINT_SECONDARY_READ_REG(WindowOrigin);
+ pRC->MX2.CRouterMode = GLINT_SECONDARY_READ_REG(RouterMode);
+ pRC->MX2.CTextureAddressMode = GLINT_SECONDARY_READ_REG(TextureAddressMode);
+ pRC->MX2.CTextureReadMode = GLINT_SECONDARY_READ_REG(TextureReadMode);
+ pRC->MX2.CTextureColorMode = GLINT_SECONDARY_READ_REG(TextureColorMode);
+ pRC->MX2.CFogMode = GLINT_SECONDARY_READ_REG(FogMode);
+ pRC->MX2.CColorDDAMode = GLINT_SECONDARY_READ_REG(ColorDDAMode);
+ pRC->MX2.CGLINTColor = GLINT_SECONDARY_READ_REG(GLINTColor);
+ pRC->MX2.CAlphaTestMode = GLINT_SECONDARY_READ_REG(AlphaTestMode);
+ pRC->MX2.CAntialiasMode = GLINT_SECONDARY_READ_REG(AntialiasMode);
+ pRC->MX2.CAlphaBlendMode = GLINT_SECONDARY_READ_REG(AlphaBlendMode);
+ pRC->MX2.CDitherMode = GLINT_SECONDARY_READ_REG(DitherMode);
+ pRC->MX2.CFBSoftwareWriteMask = GLINT_SECONDARY_READ_REG(FBSoftwareWriteMask);
+ pRC->MX2.CLogicalOpMode = GLINT_SECONDARY_READ_REG(LogicalOpMode);
+ pRC->MX2.CFBWriteData = GLINT_SECONDARY_READ_REG(FBWriteData);
+ pRC->MX2.CLBReadMode = GLINT_SECONDARY_READ_REG(LBReadMode);
+ pRC->MX2.CLBSourceOffset = GLINT_SECONDARY_READ_REG(LBSourceOffset);
+ pRC->MX2.CLBWindowBase = GLINT_SECONDARY_READ_REG(LBWindowBase);
+ pRC->MX2.CLBWriteMode = GLINT_SECONDARY_READ_REG(LBWriteMode);
+ pRC->MX2.CTextureDownloadOffset = GLINT_SECONDARY_READ_REG(TextureDownloadOffset);
+ pRC->MX2.CLBWindowOffset = GLINT_SECONDARY_READ_REG(LBWindowOffset);
+ pRC->MX2.CGLINTWindow = GLINT_SECONDARY_READ_REG(GLINTWindow);
+ pRC->MX2.CStencilMode = GLINT_SECONDARY_READ_REG(StencilMode);
+ pRC->MX2.CDepthMode = GLINT_SECONDARY_READ_REG(DepthMode);
+ pRC->MX2.CGLINTDepth = GLINT_SECONDARY_READ_REG(GLINTDepth);
+ pRC->MX2.CFBReadMode = GLINT_SECONDARY_READ_REG(FBReadMode);
+ pRC->MX2.CFBSourceOffset = GLINT_SECONDARY_READ_REG(FBSourceOffset);
+ pRC->MX2.CFBPixelOffset = GLINT_SECONDARY_READ_REG(FBPixelOffset);
+ pRC->MX2.CFBWindowBase = GLINT_SECONDARY_READ_REG(FBWindowBase);
+ pRC->MX2.CFBWriteMode = GLINT_SECONDARY_READ_REG(FBWriteMode);
+ pRC->MX2.CFBHardwareWriteMask = GLINT_SECONDARY_READ_REG(FBHardwareWriteMask);
+ pRC->MX2.CFBBlockColor = GLINT_SECONDARY_READ_REG(FBBlockColor);
+ pRC->MX2.CPatternRamMode = GLINT_SECONDARY_READ_REG(PatternRamMode);
+ pRC->MX2.CFBBlockColorU = GLINT_SECONDARY_READ_REG(FBBlockColorU);
+ pRC->MX2.CFBBlockColorL = GLINT_SECONDARY_READ_REG(FBBlockColorL);
+ pRC->MX2.CFilterMode = GLINT_SECONDARY_READ_REG(FilterMode);
+ pRC->MX2.CStatisticMode = GLINT_SECONDARY_READ_REG(StatisticMode);
+ }
+
+ if (readContextType == DRI_3D_CONTEXT) {
+ /* save the 3D portion of the old context */
+
+ /* first the MX portions */
+ pRC->MX1.CSStart = GLINT_READ_REG(SStart);
+ pRC->MX1.CdSdx = GLINT_READ_REG(dSdx);
+ pRC->MX1.CdSdyDom = GLINT_READ_REG(dSdyDom);
+ pRC->MX1.CTStart = GLINT_READ_REG(TStart);
+ pRC->MX1.CdTdx = GLINT_READ_REG(dTdx);
+ pRC->MX1.CdTdyDom = GLINT_READ_REG(dTdyDom);
+ pRC->MX1.CQStart = GLINT_READ_REG(QStart);
+ pRC->MX1.CdQdx = GLINT_READ_REG(dQdx);
+ pRC->MX1.CdQdyDom = GLINT_READ_REG(dQdyDom);
+ pRC->MX1.CLOD = GLINT_READ_REG(LOD);
+ pRC->MX1.CdSdy = GLINT_READ_REG(dSdy);
+ pRC->MX1.CdTdy = GLINT_READ_REG(dTdy);
+ pRC->MX1.CdQdy = GLINT_READ_REG(dQdy);
+ pRC->MX1.CTextureFormat = GLINT_READ_REG(TextureFormat);
+ pRC->MX1.CTextureCacheControl = GLINT_READ_REG(TextureCacheControl);
+ pRC->MX1.CGLINTBorderColor = GLINT_READ_REG(GLINTBorderColor);
+ pRC->MX1.CTexelLUTIndex = GLINT_READ_REG(TexelLUTIndex);
+ pRC->MX1.CTexelLUTData = GLINT_READ_REG(TexelLUTData);
+ pRC->MX1.CTexelLUTAddress = GLINT_READ_REG(TexelLUTAddress);
+ pRC->MX1.CTexelLUTTransfer = GLINT_READ_REG(TexelLUTTransfer);
+ pRC->MX1.CTextureFilterMode = GLINT_READ_REG(TextureFilterMode);
+ pRC->MX1.CTextureChromaUpper = GLINT_READ_REG(TextureChromaUpper);
+ pRC->MX1.CTextureChromaLower = GLINT_READ_REG(TextureChromaLower);
+ pRC->MX1.CTxBaseAddr0 = GLINT_READ_REG(TxBaseAddr0);
+ pRC->MX1.CTxBaseAddr1 = GLINT_READ_REG(TxBaseAddr1);
+ pRC->MX1.CTxBaseAddr2 = GLINT_READ_REG(TxBaseAddr2);
+ pRC->MX1.CTxBaseAddr3 = GLINT_READ_REG(TxBaseAddr3);
+ pRC->MX1.CTxBaseAddr4 = GLINT_READ_REG(TxBaseAddr4);
+ pRC->MX1.CTxBaseAddr5 = GLINT_READ_REG(TxBaseAddr5);
+ pRC->MX1.CTxBaseAddr6 = GLINT_READ_REG(TxBaseAddr6);
+ pRC->MX1.CTxBaseAddr7 = GLINT_READ_REG(TxBaseAddr7);
+ pRC->MX1.CTxBaseAddr8 = GLINT_READ_REG(TxBaseAddr8);
+ pRC->MX1.CTxBaseAddr9 = GLINT_READ_REG(TxBaseAddr9);
+ pRC->MX1.CTxBaseAddr10 = GLINT_READ_REG(TxBaseAddr10);
+ pRC->MX1.CTxBaseAddr11 = GLINT_READ_REG(TxBaseAddr11);
+ pRC->MX1.CTexelLUT0 = GLINT_READ_REG(TexelLUT0);
+ pRC->MX1.CTexelLUT1 = GLINT_READ_REG(TexelLUT1);
+ pRC->MX1.CTexelLUT2 = GLINT_READ_REG(TexelLUT2);
+ pRC->MX1.CTexelLUT3 = GLINT_READ_REG(TexelLUT3);
+ pRC->MX1.CTexelLUT4 = GLINT_READ_REG(TexelLUT4);
+ pRC->MX1.CTexelLUT5 = GLINT_READ_REG(TexelLUT5);
+ pRC->MX1.CTexelLUT6 = GLINT_READ_REG(TexelLUT6);
+ pRC->MX1.CTexelLUT7 = GLINT_READ_REG(TexelLUT7);
+ pRC->MX1.CTexelLUT8 = GLINT_READ_REG(TexelLUT8);
+ pRC->MX1.CTexelLUT9 = GLINT_READ_REG(TexelLUT9);
+ pRC->MX1.CTexelLUT10 = GLINT_READ_REG(TexelLUT10);
+ pRC->MX1.CTexelLUT11 = GLINT_READ_REG(TexelLUT11);
+ pRC->MX1.CTexelLUT12 = GLINT_READ_REG(TexelLUT12);
+ pRC->MX1.CTexelLUT13 = GLINT_READ_REG(TexelLUT13);
+ pRC->MX1.CTexelLUT14 = GLINT_READ_REG(TexelLUT14);
+ pRC->MX1.CTexelLUT15 = GLINT_READ_REG(TexelLUT15);
+ pRC->MX1.CTexel0 = GLINT_READ_REG(Texel0);
+ pRC->MX1.CTexel1 = GLINT_READ_REG(Texel1);
+ pRC->MX1.CTexel2 = GLINT_READ_REG(Texel2);
+ pRC->MX1.CTexel3 = GLINT_READ_REG(Texel3);
+ pRC->MX1.CTexel4 = GLINT_READ_REG(Texel4);
+ pRC->MX1.CTexel5 = GLINT_READ_REG(Texel5);
+ pRC->MX1.CTexel6 = GLINT_READ_REG(Texel6);
+ pRC->MX1.CTexel7 = GLINT_READ_REG(Texel7);
+ pRC->MX1.CInterp0 = GLINT_READ_REG(Interp0);
+ pRC->MX1.CInterp1 = GLINT_READ_REG(Interp1);
+ pRC->MX1.CInterp2 = GLINT_READ_REG(Interp2);
+ pRC->MX1.CInterp3 = GLINT_READ_REG(Interp3);
+ pRC->MX1.CInterp4 = GLINT_READ_REG(Interp4);
+ pRC->MX1.CTextureFilter = GLINT_READ_REG(TextureFilter);
+ pRC->MX1.CTextureEnvColor = GLINT_READ_REG(TextureEnvColor);
+ pRC->MX1.CFogColor = GLINT_READ_REG(FogColor);
+ pRC->MX1.CFStart = GLINT_READ_REG(FStart);
+ pRC->MX1.CdFdx = GLINT_READ_REG(dFdx);
+ pRC->MX1.CdFdyDom = GLINT_READ_REG(dFdyDom);
+ pRC->MX1.CKsStart = GLINT_READ_REG(KsStart);
+ pRC->MX1.CdKsdx = GLINT_READ_REG(dKsdx);
+ pRC->MX1.CdKsdyDom = GLINT_READ_REG(dKsdyDom);
+ pRC->MX1.CKdStart = GLINT_READ_REG(KdStart);
+ pRC->MX1.CdKdStart = GLINT_READ_REG(dKdStart);
+ pRC->MX1.CdKddyDom = GLINT_READ_REG(dKddyDom);
+ pRC->MX1.CRStart = GLINT_READ_REG(RStart);
+ pRC->MX1.CdRdx = GLINT_READ_REG(dRdx);
+ pRC->MX1.CdRdyDom = GLINT_READ_REG(dRdyDom);
+ pRC->MX1.CGStart = GLINT_READ_REG(GStart);
+ pRC->MX1.CdGdx = GLINT_READ_REG(dGdx);
+ pRC->MX1.CdGdyDom = GLINT_READ_REG(dGdyDom);
+ pRC->MX1.CBStart = GLINT_READ_REG(BStart);
+ pRC->MX1.CdBdx = GLINT_READ_REG(dBdx);
+ pRC->MX1.CdBdyDom = GLINT_READ_REG(dBdyDom);
+ pRC->MX1.CAStart = GLINT_READ_REG(AStart);
+ pRC->MX1.CdAdx = GLINT_READ_REG(dAdx);
+ pRC->MX1.CdAdyDom = GLINT_READ_REG(dAdyDom);
+ pRC->MX1.CConstantColor = GLINT_READ_REG(ConstantColor);
+ pRC->MX1.CChromaUpper = GLINT_READ_REG(ChromaUpper);
+ pRC->MX1.CChromaLower = GLINT_READ_REG(ChromaLower);
+ pRC->MX1.CChromaTestMode = GLINT_READ_REG(ChromaTestMode);
+ pRC->MX1.CStencilData = GLINT_READ_REG(StencilData);
+ pRC->MX1.CGLINTStencil = GLINT_READ_REG(GLINTStencil);
+ pRC->MX1.CZStartU = GLINT_READ_REG(ZStartU);
+ pRC->MX1.CZStartL = GLINT_READ_REG(ZStartL);
+ pRC->MX1.CdZdxU = GLINT_READ_REG(dZdxU);
+ pRC->MX1.CdZdxL = GLINT_READ_REG(dZdxL);
+ pRC->MX1.CdZdyDomU = GLINT_READ_REG(dZdyDomU);
+ pRC->MX1.CdZdyDomL = GLINT_READ_REG(dZdyDomL);
+ pRC->MX1.CFastClearDepth = GLINT_READ_REG(FastClearDepth);
+ pRC->MX1.CMinRegion = GLINT_READ_REG(MinRegion);
+ pRC->MX1.CMaxRegion = GLINT_READ_REG(MaxRegion);
+ pRC->MX1.CKsRStart = GLINT_READ_REG(KsRStart);
+ pRC->MX1.CdKsRdx = GLINT_READ_REG(dKsRdx);
+ pRC->MX1.CdKsRdyDom = GLINT_READ_REG(dKsRdyDom);
+ pRC->MX1.CKsGStart = GLINT_READ_REG(KsGStart);
+ pRC->MX1.CdKsGdx = GLINT_READ_REG(dKsGdx);
+ pRC->MX1.CdKsGdyDom = GLINT_READ_REG(dKsGdyDom);
+ pRC->MX1.CKsBStart = GLINT_READ_REG(KsBStart);
+ pRC->MX1.CdKsBdx = GLINT_READ_REG(dKsBdx);
+ pRC->MX1.CdKsBdyDom = GLINT_READ_REG(dKsBdyDom);
+ pRC->MX1.CKdRStart = GLINT_READ_REG(KdRStart);
+ pRC->MX1.CdKdRdx = GLINT_READ_REG(dKdRdx);
+ pRC->MX1.CdKdRdyDom = GLINT_READ_REG(dKdRdyDom);
+ pRC->MX1.CKdGStart = GLINT_READ_REG(KdGStart);
+ pRC->MX1.CdKdGdx = GLINT_READ_REG(dKdGdx);
+ pRC->MX1.CdKdGdyDom = GLINT_READ_REG(dKdGdyDom);
+ pRC->MX1.CKdBStart = GLINT_READ_REG(KdBStart);
+ pRC->MX1.CdKdBdx = GLINT_READ_REG(dKdBdx);
+ pRC->MX1.CdKdBdyDom = GLINT_READ_REG(dKdBdyDom);
+ if (pGlint->numMXDevices == 2) {
+ pRC->MX2.CSStart = GLINT_SECONDARY_READ_REG(SStart);
+ pRC->MX2.CdSdx = GLINT_SECONDARY_READ_REG(dSdx);
+ pRC->MX2.CdSdyDom = GLINT_SECONDARY_READ_REG(dSdyDom);
+ pRC->MX2.CTStart = GLINT_SECONDARY_READ_REG(TStart);
+ pRC->MX2.CdTdx = GLINT_SECONDARY_READ_REG(dTdx);
+ pRC->MX2.CdTdyDom = GLINT_SECONDARY_READ_REG(dTdyDom);
+ pRC->MX2.CQStart = GLINT_SECONDARY_READ_REG(QStart);
+ pRC->MX2.CdQdx = GLINT_SECONDARY_READ_REG(dQdx);
+ pRC->MX2.CdQdyDom = GLINT_SECONDARY_READ_REG(dQdyDom);
+ pRC->MX2.CLOD = GLINT_SECONDARY_READ_REG(LOD);
+ pRC->MX2.CdSdy = GLINT_SECONDARY_READ_REG(dSdy);
+ pRC->MX2.CdTdy = GLINT_SECONDARY_READ_REG(dTdy);
+ pRC->MX2.CdQdy = GLINT_SECONDARY_READ_REG(dQdy);
+ pRC->MX2.CTextureFormat = GLINT_SECONDARY_READ_REG(TextureFormat);
+ pRC->MX2.CTextureCacheControl = GLINT_SECONDARY_READ_REG(TextureCacheControl);
+ pRC->MX2.CGLINTBorderColor = GLINT_SECONDARY_READ_REG(GLINTBorderColor);
+ pRC->MX2.CTexelLUTIndex = GLINT_SECONDARY_READ_REG(TexelLUTIndex);
+ pRC->MX2.CTexelLUTData = GLINT_SECONDARY_READ_REG(TexelLUTData);
+ pRC->MX2.CTexelLUTAddress = GLINT_SECONDARY_READ_REG(TexelLUTAddress);
+ pRC->MX2.CTexelLUTTransfer = GLINT_SECONDARY_READ_REG(TexelLUTTransfer);
+ pRC->MX2.CTextureFilterMode = GLINT_SECONDARY_READ_REG(TextureFilterMode);
+ pRC->MX2.CTextureChromaUpper = GLINT_SECONDARY_READ_REG(TextureChromaUpper);
+ pRC->MX2.CTextureChromaLower = GLINT_SECONDARY_READ_REG(TextureChromaLower);
+ pRC->MX2.CTxBaseAddr0 = GLINT_SECONDARY_READ_REG(TxBaseAddr0);
+ pRC->MX2.CTxBaseAddr1 = GLINT_SECONDARY_READ_REG(TxBaseAddr1);
+ pRC->MX2.CTxBaseAddr2 = GLINT_SECONDARY_READ_REG(TxBaseAddr2);
+ pRC->MX2.CTxBaseAddr3 = GLINT_SECONDARY_READ_REG(TxBaseAddr3);
+ pRC->MX2.CTxBaseAddr4 = GLINT_SECONDARY_READ_REG(TxBaseAddr4);
+ pRC->MX2.CTxBaseAddr5 = GLINT_SECONDARY_READ_REG(TxBaseAddr5);
+ pRC->MX2.CTxBaseAddr6 = GLINT_SECONDARY_READ_REG(TxBaseAddr6);
+ pRC->MX2.CTxBaseAddr7 = GLINT_SECONDARY_READ_REG(TxBaseAddr7);
+ pRC->MX2.CTxBaseAddr8 = GLINT_SECONDARY_READ_REG(TxBaseAddr8);
+ pRC->MX2.CTxBaseAddr9 = GLINT_SECONDARY_READ_REG(TxBaseAddr9);
+ pRC->MX2.CTxBaseAddr10 = GLINT_SECONDARY_READ_REG(TxBaseAddr10);
+ pRC->MX2.CTxBaseAddr11 = GLINT_SECONDARY_READ_REG(TxBaseAddr11);
+ pRC->MX2.CTexelLUT0 = GLINT_SECONDARY_READ_REG(TexelLUT0);
+ pRC->MX2.CTexelLUT1 = GLINT_SECONDARY_READ_REG(TexelLUT1);
+ pRC->MX2.CTexelLUT2 = GLINT_SECONDARY_READ_REG(TexelLUT2);
+ pRC->MX2.CTexelLUT3 = GLINT_SECONDARY_READ_REG(TexelLUT3);
+ pRC->MX2.CTexelLUT4 = GLINT_SECONDARY_READ_REG(TexelLUT4);
+ pRC->MX2.CTexelLUT5 = GLINT_SECONDARY_READ_REG(TexelLUT5);
+ pRC->MX2.CTexelLUT6 = GLINT_SECONDARY_READ_REG(TexelLUT6);
+ pRC->MX2.CTexelLUT7 = GLINT_SECONDARY_READ_REG(TexelLUT7);
+ pRC->MX2.CTexelLUT8 = GLINT_SECONDARY_READ_REG(TexelLUT8);
+ pRC->MX2.CTexelLUT9 = GLINT_SECONDARY_READ_REG(TexelLUT9);
+ pRC->MX2.CTexelLUT10 = GLINT_SECONDARY_READ_REG(TexelLUT10);
+ pRC->MX2.CTexelLUT11 = GLINT_SECONDARY_READ_REG(TexelLUT11);
+ pRC->MX2.CTexelLUT12 = GLINT_SECONDARY_READ_REG(TexelLUT12);
+ pRC->MX2.CTexelLUT13 = GLINT_SECONDARY_READ_REG(TexelLUT13);
+ pRC->MX2.CTexelLUT14 = GLINT_SECONDARY_READ_REG(TexelLUT14);
+ pRC->MX2.CTexelLUT15 = GLINT_SECONDARY_READ_REG(TexelLUT15);
+ pRC->MX2.CTexel0 = GLINT_SECONDARY_READ_REG(Texel0);
+ pRC->MX2.CTexel1 = GLINT_SECONDARY_READ_REG(Texel1);
+ pRC->MX2.CTexel2 = GLINT_SECONDARY_READ_REG(Texel2);
+ pRC->MX2.CTexel3 = GLINT_SECONDARY_READ_REG(Texel3);
+ pRC->MX2.CTexel4 = GLINT_SECONDARY_READ_REG(Texel4);
+ pRC->MX2.CTexel5 = GLINT_SECONDARY_READ_REG(Texel5);
+ pRC->MX2.CTexel6 = GLINT_SECONDARY_READ_REG(Texel6);
+ pRC->MX2.CTexel7 = GLINT_SECONDARY_READ_REG(Texel7);
+ pRC->MX2.CInterp0 = GLINT_SECONDARY_READ_REG(Interp0);
+ pRC->MX2.CInterp1 = GLINT_SECONDARY_READ_REG(Interp1);
+ pRC->MX2.CInterp2 = GLINT_SECONDARY_READ_REG(Interp2);
+ pRC->MX2.CInterp3 = GLINT_SECONDARY_READ_REG(Interp3);
+ pRC->MX2.CInterp4 = GLINT_SECONDARY_READ_REG(Interp4);
+ pRC->MX2.CTextureFilter = GLINT_SECONDARY_READ_REG(TextureFilter);
+ pRC->MX2.CTextureEnvColor = GLINT_SECONDARY_READ_REG(TextureEnvColor);
+ pRC->MX2.CFogColor = GLINT_SECONDARY_READ_REG(FogColor);
+ pRC->MX2.CFStart = GLINT_SECONDARY_READ_REG(FStart);
+ pRC->MX2.CdFdx = GLINT_SECONDARY_READ_REG(dFdx);
+ pRC->MX2.CdFdyDom = GLINT_SECONDARY_READ_REG(dFdyDom);
+ pRC->MX2.CKsStart = GLINT_SECONDARY_READ_REG(KsStart);
+ pRC->MX2.CdKsdx = GLINT_SECONDARY_READ_REG(dKsdx);
+ pRC->MX2.CdKsdyDom = GLINT_SECONDARY_READ_REG(dKsdyDom);
+ pRC->MX2.CKdStart = GLINT_SECONDARY_READ_REG(KdStart);
+ pRC->MX2.CdKdStart = GLINT_SECONDARY_READ_REG(dKdStart);
+ pRC->MX2.CdKddyDom = GLINT_SECONDARY_READ_REG(dKddyDom);
+ pRC->MX2.CRStart = GLINT_SECONDARY_READ_REG(RStart);
+ pRC->MX2.CdRdx = GLINT_SECONDARY_READ_REG(dRdx);
+ pRC->MX2.CdRdyDom = GLINT_SECONDARY_READ_REG(dRdyDom);
+ pRC->MX2.CGStart = GLINT_SECONDARY_READ_REG(GStart);
+ pRC->MX2.CdGdx = GLINT_SECONDARY_READ_REG(dGdx);
+ pRC->MX2.CdGdyDom = GLINT_SECONDARY_READ_REG(dGdyDom);
+ pRC->MX2.CBStart = GLINT_SECONDARY_READ_REG(BStart);
+ pRC->MX2.CdBdx = GLINT_SECONDARY_READ_REG(dBdx);
+ pRC->MX2.CdBdyDom = GLINT_SECONDARY_READ_REG(dBdyDom);
+ pRC->MX2.CAStart = GLINT_SECONDARY_READ_REG(AStart);
+ pRC->MX2.CdAdx = GLINT_SECONDARY_READ_REG(dAdx);
+ pRC->MX2.CdAdyDom = GLINT_SECONDARY_READ_REG(dAdyDom);
+ pRC->MX2.CConstantColor = GLINT_SECONDARY_READ_REG(ConstantColor);
+ pRC->MX2.CChromaUpper = GLINT_SECONDARY_READ_REG(ChromaUpper);
+ pRC->MX2.CChromaLower = GLINT_SECONDARY_READ_REG(ChromaLower);
+ pRC->MX2.CChromaTestMode = GLINT_SECONDARY_READ_REG(ChromaTestMode);
+ pRC->MX2.CStencilData = GLINT_SECONDARY_READ_REG(StencilData);
+ pRC->MX2.CGLINTStencil = GLINT_SECONDARY_READ_REG(GLINTStencil);
+ pRC->MX2.CZStartU = GLINT_SECONDARY_READ_REG(ZStartU);
+ pRC->MX2.CZStartL = GLINT_SECONDARY_READ_REG(ZStartL);
+ pRC->MX2.CdZdxU = GLINT_SECONDARY_READ_REG(dZdxU);
+ pRC->MX2.CdZdxL = GLINT_SECONDARY_READ_REG(dZdxL);
+ pRC->MX2.CdZdyDomU = GLINT_SECONDARY_READ_REG(dZdyDomU);
+ pRC->MX2.CdZdyDomL = GLINT_SECONDARY_READ_REG(dZdyDomL);
+ pRC->MX2.CFastClearDepth = GLINT_SECONDARY_READ_REG(FastClearDepth);
+ pRC->MX2.CMinRegion = GLINT_SECONDARY_READ_REG(MinRegion);
+ pRC->MX2.CMaxRegion = GLINT_SECONDARY_READ_REG(MaxRegion);
+ pRC->MX2.CKsRStart = GLINT_SECONDARY_READ_REG(KsRStart);
+ pRC->MX2.CdKsRdx = GLINT_SECONDARY_READ_REG(dKsRdx);
+ pRC->MX2.CdKsRdyDom = GLINT_SECONDARY_READ_REG(dKsRdyDom);
+ pRC->MX2.CKsGStart = GLINT_SECONDARY_READ_REG(KsGStart);
+ pRC->MX2.CdKsGdx = GLINT_SECONDARY_READ_REG(dKsGdx);
+ pRC->MX2.CdKsGdyDom = GLINT_SECONDARY_READ_REG(dKsGdyDom);
+ pRC->MX2.CKsBStart = GLINT_SECONDARY_READ_REG(KsBStart);
+ pRC->MX2.CdKsBdx = GLINT_SECONDARY_READ_REG(dKsBdx);
+ pRC->MX2.CdKsBdyDom = GLINT_SECONDARY_READ_REG(dKsBdyDom);
+ pRC->MX2.CKdRStart = GLINT_SECONDARY_READ_REG(KdRStart);
+ pRC->MX2.CdKdRdx = GLINT_SECONDARY_READ_REG(dKdRdx);
+ pRC->MX2.CdKdRdyDom = GLINT_SECONDARY_READ_REG(dKdRdyDom);
+ pRC->MX2.CKdGStart = GLINT_SECONDARY_READ_REG(KdGStart);
+ pRC->MX2.CdKdGdx = GLINT_SECONDARY_READ_REG(dKdGdx);
+ pRC->MX2.CdKdGdyDom = GLINT_SECONDARY_READ_REG(dKdGdyDom);
+ pRC->MX2.CKdBStart = GLINT_SECONDARY_READ_REG(KdBStart);
+ pRC->MX2.CdKdBdx = GLINT_SECONDARY_READ_REG(dKdBdx);
+ pRC->MX2.CdKdBdyDom = GLINT_SECONDARY_READ_REG(dKdBdyDom);
+ }
+
+ /* send gamma the context dump command */
+ GLINT_WAIT(3);
+ if (pGlint->numMXDevices > 1)
+ GLINT_WRITE_REG(1, BroadcastMask);
+ GLINT_WRITE_REG(3<<14, FilterMode); /* context bits on gamma */
+ GLINT_WRITE_REG(GLINT_GAMMA_CONTEXT_MASK, ContextDump);
+
+ /* save context data from output fifo */
+ dumpIndex = 0;
+ do {
+ while(GLINT_READ_REG(OutFIFOWords) == 0);
+ readValue = GLINT_READ_REG(OutputFIFO);
+#ifdef DEBUG
+xf86DrvMsg(pScreen->myNum, X_INFO, "pRC tag [%d]: %x\n",
+dumpIndex,readValue);
+#endif
+ while(GLINT_READ_REG(OutFIFOWords) == 0);
+ readValue = GLINT_READ_REG(OutputFIFO);
+#ifdef DEBUG
+xf86DrvMsg(pScreen->myNum, X_INFO, "pRC data [%d]: %x\n",
+dumpIndex,readValue);
+#endif
+ pRC->Gamma[dumpIndex++] = readValue;
+ } while (dumpIndex < GLINT_GAMMA_CONTEXT_SIZE);
+
+ /* clear contextDump tag and data out of fifo */
+ while(GLINT_READ_REG(OutFIFOWords) == 0);
+ readValue = GLINT_READ_REG(OutputFIFO);
+ if (readValue != ContextDump_tag) {
+ xf86DrvMsg(pScreen->myNum, X_ERROR, "Context dump error\n");
+ }
+ while(GLINT_READ_REG(OutFIFOWords) == 0);
+ readValue = GLINT_READ_REG(OutputFIFO);
+
+ GLINT_SLOW_WRITE_REG(1<<10, FilterMode);
+ if (pGlint->numMXDevices > 1)
+ GLINT_SLOW_WRITE_REG((1<<pGlint->numMXDevices)-1,BroadcastMask);
+ }
+ }
+
+ if (writeContextType != DRI_NO_CONTEXT) {
+
+ if (writeContextType == DRI_3D_CONTEXT) {
+ /* restore the 3D portion of the new context */
+
+ /* send context restore command */
+ GLINT_WAIT(1);
+ if (pGlint->numMXDevices > 1)
+ GLINT_WRITE_REG(1, BroadcastMask);
+
+ GLINT_WAIT(3);
+ GLINT_WRITE_REG(ContextRestore_tag, OutputFIFO);
+ GLINT_WRITE_REG(GLINT_GAMMA_CONTEXT_MASK, OutputFIFO);
+ GLINT_WRITE_REG((((GLINT_GAMMA_CONTEXT_SIZE-1) << 16) |
+ ContextData_tag), OutputFIFO);
+
+ /* restore context data to context data register */
+ dumpIndex = 0;
+ do {
+ GLINT_WAIT(1);
+#ifdef DEBUG
+xf86DrvMsg(pScreen->myNum, X_INFO, "pWC data [%d]: %x\n",
+dumpIndex,pWC->Gamma[dumpIndex]);
+#endif
+ GLINT_WRITE_REG(pWC->Gamma[dumpIndex++], OutputFIFO);
+ } while (dumpIndex < (GLINT_GAMMA_CONTEXT_SIZE));
+
+ /* Sync after writing gamma context and
+ before writing MX context */
+ if (pGlint->AccelInfoRec->Sync) {
+ (*pGlint->AccelInfoRec->Sync)(pGlint->AccelInfoRec->pScrn);
+ }
+ /* Update XAA's NeedToSync flag */
+ pGlint->AccelInfoRec->NeedToSync = TRUE;
+
+ /* finally the MX portions */
+ if (pGlint->numMXDevices > 1)
+ GLINT_SLOW_WRITE_REG(1, BroadcastMask);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CSStart, SStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdSdx, dSdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdSdyDom, dSdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTStart, TStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdTdx, dTdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdTdyDom, dTdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CQStart, QStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdQdx, dQdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdQdyDom, dQdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CLOD, LOD);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdSdy, dSdy);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdTdy, dTdy);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdQdy, dQdy);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureFormat, TextureFormat);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureCacheControl, TextureCacheControl);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CGLINTBorderColor, GLINTBorderColor);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUTIndex, TexelLUTIndex);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUTData, TexelLUTData);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUTAddress, TexelLUTAddress);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUTTransfer, TexelLUTTransfer);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureFilterMode, TextureFilterMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureChromaUpper, TextureChromaUpper);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureChromaLower, TextureChromaLower);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr0, TxBaseAddr0);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr1, TxBaseAddr1);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr2, TxBaseAddr2);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr3, TxBaseAddr3);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr4, TxBaseAddr4);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr5, TxBaseAddr5);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr6, TxBaseAddr6);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr7, TxBaseAddr7);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr8, TxBaseAddr8);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr9, TxBaseAddr9);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr10, TxBaseAddr10);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTxBaseAddr11, TxBaseAddr11);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT0, TexelLUT0);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT1, TexelLUT1);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT2, TexelLUT2);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT3, TexelLUT3);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT4, TexelLUT4);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT5, TexelLUT5);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT6, TexelLUT6);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT7, TexelLUT7);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT8, TexelLUT8);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT9, TexelLUT9);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT10, TexelLUT10);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT11, TexelLUT11);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT12, TexelLUT12);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT13, TexelLUT13);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT14, TexelLUT14);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexelLUT15, TexelLUT15);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexel0, Texel0);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexel1, Texel1);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexel2, Texel2);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexel3, Texel3);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexel4, Texel4);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexel5, Texel5);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexel6, Texel6);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTexel7, Texel7);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CInterp0, Interp0);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CInterp1, Interp1);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CInterp2, Interp2);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CInterp3, Interp3);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CInterp4, Interp4);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureFilter, TextureFilter);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureEnvColor, TextureEnvColor);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CFogColor, FogColor);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CFStart, FStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdFdx, dFdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdFdyDom, dFdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CKsStart, KsStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdKsdx, dKsdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdKsdyDom, dKsdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CKdStart, KdStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdKdStart, dKdStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdKddyDom, dKddyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CRStart, RStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdRdx, dRdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdRdyDom, dRdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CGStart, GStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdGdx, dGdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdGdyDom, dGdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CBStart, BStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdBdx, dBdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdBdyDom, dBdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CAStart, AStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdAdx, dAdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdAdyDom, dAdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CConstantColor, ConstantColor);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CChromaUpper, ChromaUpper);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CChromaLower, ChromaLower);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CChromaTestMode, ChromaTestMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CStencilData, StencilData);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CGLINTStencil, GLINTStencil);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CZStartU, ZStartU);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CZStartL, ZStartL);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdZdxU, dZdxU);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdZdxL, dZdxL);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdZdyDomU, dZdyDomU);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdZdyDomL, dZdyDomL);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CFastClearDepth, FastClearDepth);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CMinRegion, MinRegion);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CMaxRegion, MaxRegion);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CKsRStart, KsRStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdKsRdx, dKsRdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdKsRdyDom, dKsRdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CKsGStart, KsGStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdKsGdx, dKsGdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdKsGdyDom, dKsGdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CKsBStart, KsBStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdKsBdx, dKsBdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdKsBdyDom, dKsBdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CKdRStart, KdRStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdKdRdx, dKdRdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdKdRdyDom, dKdRdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CKdGStart, KdGStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdKdGdx, dKdGdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdKdGdyDom, dKdGdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CKdBStart, KdBStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdKdBdx, dKdBdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdKdBdyDom, dKdBdyDom);
+
+ if (pGlint->numMXDevices == 2) {
+ GLINT_SLOW_WRITE_REG(2, BroadcastMask);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CSStart, SStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdSdx, dSdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdSdyDom, dSdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTStart, TStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdTdx, dTdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdTdyDom, dTdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CQStart, QStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdQdx, dQdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdQdyDom, dQdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CLOD, LOD);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdSdy, dSdy);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdTdy, dTdy);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdQdy, dQdy);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureFormat, TextureFormat);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureCacheControl, TextureCacheControl);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CGLINTBorderColor, GLINTBorderColor);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUTIndex, TexelLUTIndex);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUTData, TexelLUTData);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUTAddress, TexelLUTAddress);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUTTransfer, TexelLUTTransfer);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureFilterMode, TextureFilterMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureChromaUpper, TextureChromaUpper);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureChromaLower, TextureChromaLower);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr0, TxBaseAddr0);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr1, TxBaseAddr1);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr2, TxBaseAddr2);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr3, TxBaseAddr3);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr4, TxBaseAddr4);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr5, TxBaseAddr5);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr6, TxBaseAddr6);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr7, TxBaseAddr7);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr8, TxBaseAddr8);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr9, TxBaseAddr9);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr10, TxBaseAddr10);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTxBaseAddr11, TxBaseAddr11);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT0, TexelLUT0);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT1, TexelLUT1);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT2, TexelLUT2);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT3, TexelLUT3);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT4, TexelLUT4);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT5, TexelLUT5);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT6, TexelLUT6);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT7, TexelLUT7);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT8, TexelLUT8);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT9, TexelLUT9);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT10, TexelLUT10);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT11, TexelLUT11);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT12, TexelLUT12);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT13, TexelLUT13);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT14, TexelLUT14);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexelLUT15, TexelLUT15);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexel0, Texel0);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexel1, Texel1);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexel2, Texel2);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexel3, Texel3);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexel4, Texel4);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexel5, Texel5);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexel6, Texel6);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTexel7, Texel7);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CInterp0, Interp0);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CInterp1, Interp1);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CInterp2, Interp2);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CInterp3, Interp3);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CInterp4, Interp4);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureFilter, TextureFilter);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureEnvColor, TextureEnvColor);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CFogColor, FogColor);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CFStart, FStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdFdx, dFdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdFdyDom, dFdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CKsStart, KsStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdKsdx, dKsdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdKsdyDom, dKsdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CKdStart, KdStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdKdStart, dKdStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdKddyDom, dKddyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CRStart, RStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdRdx, dRdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdRdyDom, dRdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CGStart, GStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdGdx, dGdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdGdyDom, dGdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CBStart, BStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdBdx, dBdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdBdyDom, dBdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CAStart, AStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdAdx, dAdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdAdyDom, dAdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CConstantColor, ConstantColor);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CChromaUpper, ChromaUpper);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CChromaLower, ChromaLower);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CChromaTestMode, ChromaTestMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CStencilData, StencilData);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CGLINTStencil, GLINTStencil);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CZStartU, ZStartU);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CZStartL, ZStartL);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdZdxU, dZdxU);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdZdxL, dZdxL);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdZdyDomU, dZdyDomU);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdZdyDomL, dZdyDomL);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CFastClearDepth, FastClearDepth);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CMinRegion, MinRegion);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CMaxRegion, MaxRegion);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CKsRStart, KsRStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdKsRdx, dKsRdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdKsRdyDom, dKsRdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CKsGStart, KsGStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdKsGdx, dKsGdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdKsGdyDom, dKsGdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CKsBStart, KsBStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdKsBdx, dKsBdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdKsBdyDom, dKsBdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CKdRStart, KdRStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdKdRdx, dKdRdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdKdRdyDom, dKdRdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CKdGStart, KdGStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdKdGdx, dKdGdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdKdGdyDom, dKdGdyDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CKdBStart, KdBStart);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdKdBdx, dKdBdx);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdKdBdyDom, dKdBdyDom);
+ }
+ }
+
+ /* restore the 2D portion of the new context */
+
+ /* Restore MX1's registers */
+ if (pGlint->numMXDevices > 1)
+ GLINT_SLOW_WRITE_REG(1, BroadcastMask);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CStartXDom, StartXDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdXDom, dXDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CStartXSub, StartXSub);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdXSub, dXSub);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CStartY, StartY);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CdY, dY);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CGLINTCount, GLINTCount);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CPointTable0, PointTable0);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CPointTable1, PointTable1);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CPointTable2, PointTable2);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CPointTable3, PointTable3);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CRasterizerMode, RasterizerMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CYLimits, YLimits);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CScanLineOwnership, ScanLineOwnership);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CPixelSize, PixelSize);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CScissorMode, ScissorMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CScissorMinXY, ScissorMinXY);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CScissorMaxXY, ScissorMaxXY);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CScreenSize, ScreenSize);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CAreaStippleMode, AreaStippleMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CLineStippleMode, LineStippleMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CLoadLineStippleCounters, LoadLineStippleCounters);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CWindowOrigin, WindowOrigin);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CRouterMode, RouterMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureAddressMode, TextureAddressMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureReadMode, TextureReadMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureColorMode, TextureColorMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CFogMode, FogMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CColorDDAMode, ColorDDAMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CGLINTColor, GLINTColor);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CAlphaTestMode, AlphaTestMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CAntialiasMode, AntialiasMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CAlphaBlendMode, AlphaBlendMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CDitherMode, DitherMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CFBSoftwareWriteMask, FBSoftwareWriteMask);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CLogicalOpMode, LogicalOpMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CFBWriteData, FBWriteData);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CLBReadMode, LBReadMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CLBSourceOffset, LBSourceOffset);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CLBWindowBase, LBWindowBase);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CLBWriteMode, LBWriteMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CTextureDownloadOffset, TextureDownloadOffset);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CLBWindowOffset, LBWindowOffset);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CGLINTWindow, GLINTWindow);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CStencilMode, StencilMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CDepthMode, DepthMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CGLINTDepth, GLINTDepth);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CFBReadMode, FBReadMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CFBSourceOffset, FBSourceOffset);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CFBPixelOffset, FBPixelOffset);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CFBWindowBase, FBWindowBase);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CFBWriteMode, FBWriteMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CFBHardwareWriteMask, FBHardwareWriteMask);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CFBBlockColor, FBBlockColor);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CPatternRamMode, PatternRamMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CFBBlockColorU, FBBlockColorU);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CFBBlockColorL, FBBlockColorL);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CFilterMode, FilterMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CStatisticMode, StatisticMode);
+
+ /* Restore MX2's registers */
+ if (pGlint->numMXDevices == 2) {
+ GLINT_SLOW_WRITE_REG(2, BroadcastMask);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CStartXDom, StartXDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdXDom, dXDom);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CStartXSub, StartXSub);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdXSub, dXSub);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CStartY, StartY);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CdY, dY);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CGLINTCount, GLINTCount);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CPointTable0, PointTable0);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CPointTable1, PointTable1);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CPointTable2, PointTable2);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CPointTable3, PointTable3);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CRasterizerMode, RasterizerMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CYLimits, YLimits);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CScanLineOwnership, ScanLineOwnership);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CPixelSize, PixelSize);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CScissorMode, ScissorMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CScissorMinXY, ScissorMinXY);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CScissorMaxXY, ScissorMaxXY);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CScreenSize, ScreenSize);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CAreaStippleMode, AreaStippleMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CLineStippleMode, LineStippleMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CLoadLineStippleCounters, LoadLineStippleCounters);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CWindowOrigin, WindowOrigin);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CRouterMode, RouterMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureAddressMode, TextureAddressMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureReadMode, TextureReadMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureColorMode, TextureColorMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CFogMode, FogMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CColorDDAMode, ColorDDAMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CGLINTColor, GLINTColor);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CAlphaTestMode, AlphaTestMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CAntialiasMode, AntialiasMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CAlphaBlendMode, AlphaBlendMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CDitherMode, DitherMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CFBSoftwareWriteMask, FBSoftwareWriteMask);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CLogicalOpMode, LogicalOpMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CFBWriteData, FBWriteData);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CLBReadMode, LBReadMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CLBSourceOffset, LBSourceOffset);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CLBWindowBase, LBWindowBase);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CLBWriteMode, LBWriteMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CTextureDownloadOffset, TextureDownloadOffset);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CLBWindowOffset, LBWindowOffset);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CGLINTWindow, GLINTWindow);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CStencilMode, StencilMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CDepthMode, DepthMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CGLINTDepth, GLINTDepth);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CFBReadMode, FBReadMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CFBSourceOffset, FBSourceOffset);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CFBPixelOffset, FBPixelOffset);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CFBWindowBase, FBWindowBase);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CFBWriteMode, FBWriteMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CFBHardwareWriteMask, FBHardwareWriteMask);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CFBBlockColor, FBBlockColor);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CPatternRamMode, PatternRamMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CFBBlockColorU, FBBlockColorU);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CFBBlockColorL, FBBlockColorL);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CFilterMode, FilterMode);
+ GLINT_SLOW_WRITE_REG(pWC->MX2.CStatisticMode, StatisticMode);
+
+ /* Restore the "real" broadcast mask last */
+ GLINT_SLOW_WRITE_REG(pWC->MX1.CBroadcastMask, BroadcastMask);
+ }
+ }
+}
+
+void
+GLINTDRIInitBuffers(
+ WindowPtr pWin,
+ RegionPtr prgn,
+ CARD32 index)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ BoxPtr pbox;
+ int nbox;
+
+ pbox = REGION_RECTS(prgn);
+ nbox = REGION_NUM_RECTS(prgn);
+
+ GLINT_WAIT(7);
+ /* Turn off writes the FB */
+ GLINT_WRITE_REG(0, FBWriteMode);
+ GLINT_WRITE_REG(0, LBWindowBase);
+ GLINT_WRITE_REG(1, LBWriteMode);
+ if (pGlint->numMXDevices == 2) {
+ GLINT_WRITE_REG( pGlint->pprod |
+ LBRM_ScanlineInt2 , LBReadMode);
+ } else {
+ GLINT_WRITE_REG( pGlint->pprod , LBReadMode);
+ }
+ GLINT_WRITE_REG(0, LBDepth);
+ GLINT_WRITE_REG(0, LBStencil);
+ GLINT_WRITE_REG( GWIN_UnitEnable |
+ GWIN_ForceLBUpdate |
+ ((index & 0xf) << 5) |
+ GWIN_LBUpdateSourceREG |
+ GWIN_OverrideWriteFilter, GLINTWindow);
+
+ while (nbox--) {
+ GLINT_WAIT(8);
+ GLINT_WRITE_REG((pbox->x2)<<16, StartXSub);
+ GLINT_WRITE_REG((pbox->x1)<<16, StartXDom);
+ GLINT_WRITE_REG((pbox->y1)<<16, StartY);
+ GLINT_WRITE_REG((pbox->y2 - pbox->y1), GLINTCount);
+ GLINT_WRITE_REG(0, dXDom);
+ GLINT_WRITE_REG(0x10000, dY);
+ /* Must also set dXSub, since 3D tris cause it to be != 0 */
+ GLINT_WRITE_REG(0, dXSub);
+ GLINT_WRITE_REG(PrimitiveTrapezoid, Render);
+ pbox++;
+ }
+
+ GLINT_WAIT(3);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBWriteMode);
+ GLINT_SLOW_WRITE_REG(UNIT_ENABLE, FBWriteMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, GLINTWindow);
+
+ /* Update XAA's NeedToSync flag */
+ pGlint->AccelInfoRec->NeedToSync = TRUE;
+}
+
+void
+GLINTDRIMoveBuffers(
+ WindowPtr pParent,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc,
+ CARD32 index)
+{
+#if 0
+ ScreenPtr pScreen = pParent->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+#endif
+ int dx, dy;
+ WindowPtr pChild;
+ RegionRec rgnSubWindow, rgnTranslateSrc;
+ CARD32 indexSubWindow;
+
+ /* NOT_DONE: For now, just init the buffer. We are not copying the depth
+ * and stencil, they just get redrawn for the next frame(s).
+ */
+
+ REGION_INIT(pScreen, &rgnSubWindow, NullBox, 0);
+ REGION_INIT(pScreen, &rgnTranslateSrc, NullBox, 0);
+ REGION_COPY(pScreen, &rgnTranslateSrc, prgnSrc);
+ dx = ptOldOrg.x - pParent->drawable.x;
+ dy = ptOldOrg.y - pParent->drawable.y;
+ REGION_TRANSLATE(pScreen, &rgnTranslateSrc, -dx, -dy);
+
+ pChild = pParent;
+ while (1) {
+ if (pChild->viewable) {
+ REGION_INTERSECT(pScreen, &rgnSubWindow,
+ &pChild->borderClip, &rgnTranslateSrc);
+ indexSubWindow = DRIGetDrawableIndex(pChild);
+ GLINTDRIInitBuffers( pChild, &rgnSubWindow, indexSubWindow);
+ if (pChild->firstChild) {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pParent))
+ pChild = pChild->parent;
+ if (pChild == pParent)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h
new file mode 100644
index 000000000..2b6ff8307
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h
@@ -0,0 +1,57 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h,v 1.2 1999/06/27 14:08:05 dawes Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+
+/*
+ * Author:
+ * Jens Owen <jens@precisioninsight.com>
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dri.h,v 1.5 1999/06/15 17:46:16 faith Exp $
+ */
+
+/*
+ * Glint specific record passed back to client driver
+ * via DRIGetDeviceInfo request
+ */
+typedef struct {
+ drmHandle hControlRegs0;
+ drmHandle hControlRegs1;
+ drmHandle hControlRegs2;
+ drmHandle hControlRegs3;
+ drmSize sizeControlRegs0;
+ drmSize sizeControlRegs1;
+ drmSize sizeControlRegs2;
+ drmSize sizeControlRegs3;
+ drmMapFlags flagsControlRegs0;
+ drmMapFlags flagsControlRegs1;
+ drmMapFlags flagsControlRegs2;
+ drmMapFlags flagsControlRegs3;
+} GLINTDRIRec, *GLINTDRIPtr;
+
+#define GLINT_DRI_BUF_COUNT 20
+#define GLINT_DRI_BUF_SIZE 0x1000
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h
new file mode 100644
index 000000000..26a0b3d30
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h
@@ -0,0 +1,296 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h,v 1.1 1999/06/14 07:31:53 dawes Exp $ */
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+
+/*
+ * Author:
+ * Jens Owen <jens@precisioninsight.com>
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_dripriv.h,v 1.13 1999/06/07 13:05:07 faith Exp $
+ */
+
+extern void GlxSetVisualConfigs(
+ int nconfigs,
+ __GLXvisualConfig *configs,
+ void **configprivs
+);
+
+extern Bool GLINTCreateContext(ScreenPtr pScreen,
+ VisualPtr visual,
+ drmContext hwContext,
+ void* pVisualConfigPriv);
+
+extern void GLINTDRISwapContext( ScreenPtr pScreen,
+ DRISyncType syncType,
+ DRIContextType readContextType,
+ void** readContextStore,
+ DRIContextType writeContextType,
+ void** writeContextStore);
+
+/* Macros to Setup Generic Kernel Device Driver to Handle DMA for gamma */
+
+/* WARNING!!! MAGIC NUMBER!!! The number of regions already added to the
+ kernel must be specified here. Currently, the number is 2. */
+#define DRM_REG(reg) \
+ (2 \
+ + ((reg < 0x1000) \
+ ? 0 \
+ : ((reg < 0x10000) ? 1 : ((reg < 0x11000) ? 2 : 3))))
+
+#define DRM_OFF(reg) \
+ ((reg < 0x1000) \
+ ? reg \
+ : ((reg < 0x10000) \
+ ? (reg - 0x1000) \
+ : ((reg < 0x11000) \
+ ? (reg - 0x10000) \
+ : (reg - 0x11000))))
+
+
+#define DRM_I_WRITE_R(reg,a,b,c,d) \
+ DRM_I_WRITE(DRM_REG(reg), DRM_OFF(reg), a, b, c, d)
+
+#define DRM_I_WRITE_IMM_R(reg,a) \
+ DRM_I_WRITE_IMM(DRM_REG(reg), DRM_OFF(reg), a)
+
+#define DRM_I_READ_R(reg) \
+ DRM_I_READ(DRM_REG(reg), DRM_OFF(reg))
+
+#define DRM_I_WHILE_IMM_R(reg,a,b) \
+ DRM_I_WHILE_IMM(DRM_REG(reg), DRM_OFF(reg), a, b)
+
+#define DRM_I_IF_IMM_R(reg,a,b,c) \
+ DRM_I_IF_IMM(DRM_REG(reg), DRM_OFF(reg), a, b, c)
+
+#define GLINTSync GlintSync
+#define GLINTSyncTag 0x188
+
+#define GLINT_MAX_DRAWABLES 15
+#define GLINT_GAMMA_CONTEXT_SIZE 964
+#define GLINT_GAMMA_CONTEXT_MASK 0x7ff
+
+typedef struct {
+ int index;
+} GLINTConfigPrivRec, *GLINTConfigPrivPtr;
+
+typedef struct {
+
+ /* 2D components */
+ CARD32 CStartXDom;
+ CARD32 CdXDom;
+ CARD32 CStartXSub;
+ CARD32 CdXSub;
+ CARD32 CStartY;
+ CARD32 CdY;
+ CARD32 CGLINTCount;
+ CARD32 CPointTable0;
+ CARD32 CPointTable1;
+ CARD32 CPointTable2;
+ CARD32 CPointTable3;
+ CARD32 CRasterizerMode;
+ CARD32 CYLimits;
+ CARD32 CScanLineOwnership;
+ CARD32 CPixelSize;
+ CARD32 CScissorMode;
+ CARD32 CScissorMinXY;
+ CARD32 CScissorMaxXY;
+ CARD32 CScreenSize;
+ CARD32 CAreaStippleMode;
+ CARD32 CLineStippleMode;
+ CARD32 CLoadLineStippleCounters;
+ CARD32 CWindowOrigin;
+ CARD32 CRouterMode;
+ CARD32 CTextureAddressMode;
+ CARD32 CTextureReadMode;
+ CARD32 CTextureColorMode;
+ CARD32 CFogMode;
+ CARD32 CColorDDAMode;
+ CARD32 CGLINTColor;
+ CARD32 CAlphaTestMode;
+ CARD32 CAntialiasMode;
+ CARD32 CAlphaBlendMode;
+ CARD32 CDitherMode;
+ CARD32 CFBSoftwareWriteMask;
+ CARD32 CLogicalOpMode;
+ CARD32 CFBWriteData;
+ CARD32 CLBReadMode;
+ CARD32 CLBSourceOffset;
+ CARD32 CLBWindowBase;
+ CARD32 CLBWriteMode;
+ CARD32 CTextureDownloadOffset;
+ CARD32 CLBWindowOffset;
+ CARD32 CGLINTWindow;
+ CARD32 CStencilMode;
+ CARD32 CDepthMode;
+ CARD32 CGLINTDepth;
+ CARD32 CFBReadMode;
+ CARD32 CFBSourceOffset;
+ CARD32 CFBPixelOffset;
+ CARD32 CFBWindowBase;
+ CARD32 CFBWriteMode;
+ CARD32 CFBHardwareWriteMask;
+ CARD32 CFBBlockColor;
+ CARD32 CPatternRamMode;
+ CARD32 CFBBlockColorU;
+ CARD32 CFBBlockColorL;
+ CARD32 CFilterMode;
+ CARD32 CStatisticMode;
+ CARD32 CBroadcastMask;
+
+ /* 3D components */
+ CARD32 CSStart;
+ CARD32 CdSdx;
+ CARD32 CdSdyDom;
+ CARD32 CTStart;
+ CARD32 CdTdx;
+ CARD32 CdTdyDom;
+ CARD32 CQStart;
+ CARD32 CdQdx;
+ CARD32 CdQdyDom;
+ CARD32 CLOD;
+ CARD32 CdSdy;
+ CARD32 CdTdy;
+ CARD32 CdQdy;
+ CARD32 CTex;
+ CARD32 CTextureFormat;
+ CARD32 CTextureCacheControl;
+ CARD32 CGLINTBorderColor;
+ CARD32 CTexelLUTIndex;
+ CARD32 CTexelLUTData;
+ CARD32 CTexelLUTAddress;
+ CARD32 CTexelLUTTransfer;
+ CARD32 CTextureFilterMode;
+ CARD32 CTextureChromaUpper;
+ CARD32 CTextureChromaLower;
+ CARD32 CTxBaseAddr0;
+ CARD32 CTxBaseAddr1;
+ CARD32 CTxBaseAddr2;
+ CARD32 CTxBaseAddr3;
+ CARD32 CTxBaseAddr4;
+ CARD32 CTxBaseAddr5;
+ CARD32 CTxBaseAddr6;
+ CARD32 CTxBaseAddr7;
+ CARD32 CTxBaseAddr8;
+ CARD32 CTxBaseAddr9;
+ CARD32 CTxBaseAddr10;
+ CARD32 CTxBaseAddr11;
+ CARD32 CTxBaseAddr12;
+ CARD32 CTexelLUT0;
+ CARD32 CTexelLUT1;
+ CARD32 CTexelLUT2;
+ CARD32 CTexelLUT3;
+ CARD32 CTexelLUT4;
+ CARD32 CTexelLUT5;
+ CARD32 CTexelLUT6;
+ CARD32 CTexelLUT7;
+ CARD32 CTexelLUT8;
+ CARD32 CTexelLUT9;
+ CARD32 CTexelLUT10;
+ CARD32 CTexelLUT11;
+ CARD32 CTexelLUT12;
+ CARD32 CTexelLUT13;
+ CARD32 CTexelLUT14;
+ CARD32 CTexelLUT15;
+ CARD32 CTexel0;
+ CARD32 CTexel1;
+ CARD32 CTexel2;
+ CARD32 CTexel3;
+ CARD32 CTexel4;
+ CARD32 CTexel5;
+ CARD32 CTexel6;
+ CARD32 CTexel7;
+ CARD32 CInterp0;
+ CARD32 CInterp1;
+ CARD32 CInterp2;
+ CARD32 CInterp3;
+ CARD32 CInterp4;
+ CARD32 CTextureFilter;
+ CARD32 CTextureEnvColor;
+ CARD32 CFogColor;
+ CARD32 CFStart;
+ CARD32 CdFdx;
+ CARD32 CdFdyDom;
+ CARD32 CKsStart;
+ CARD32 CdKsdx;
+ CARD32 CdKsdyDom;
+ CARD32 CKdStart;
+ CARD32 CdKdStart;
+ CARD32 CdKddyDom;
+ CARD32 CRStart;
+ CARD32 CdRdx;
+ CARD32 CdRdyDom;
+ CARD32 CGStart;
+ CARD32 CdGdx;
+ CARD32 CdGdyDom;
+ CARD32 CBStart;
+ CARD32 CdBdx;
+ CARD32 CdBdyDom;
+ CARD32 CAStart;
+ CARD32 CdAdx;
+ CARD32 CdAdyDom;
+ CARD32 CConstantColor;
+ CARD32 CChromaUpper;
+ CARD32 CChromaLower;
+ CARD32 CChromaTestMode;
+ CARD32 CStencilData;
+ CARD32 CGLINTStencil;
+ CARD32 CZStartU;
+ CARD32 CZStartL;
+ CARD32 CdZdxU;
+ CARD32 CdZdxL;
+ CARD32 CdZdyDomU;
+ CARD32 CdZdyDomL;
+ CARD32 CFastClearDepth;
+ CARD32 CMinRegion;
+ CARD32 CMaxRegion;
+ CARD32 CKsRStart;
+ CARD32 CdKsRdx;
+ CARD32 CdKsRdyDom;
+ CARD32 CKsGStart;
+ CARD32 CdKsGdx;
+ CARD32 CdKsGdyDom;
+ CARD32 CKsBStart;
+ CARD32 CdKsBdx;
+ CARD32 CdKsBdyDom;
+ CARD32 CKdRStart;
+ CARD32 CdKdRdx;
+ CARD32 CdKdRdyDom;
+ CARD32 CKdGStart;
+ CARD32 CdKdGdx;
+ CARD32 CdKdGdyDom;
+ CARD32 CKdBStart;
+ CARD32 CdKdBdx;
+ CARD32 CdKdBdyDom;
+
+} GLINTMXRec;
+
+typedef struct {
+ GLINTMXRec MX1;
+ GLINTMXRec MX2;
+ CARD32 Gamma[GLINT_GAMMA_CONTEXT_SIZE];
+} GLINTDRIContextRec, *GLINTDRIContextPtr;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c
new file mode 100644
index 000000000..fb03edb31
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c
@@ -0,0 +1,2674 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ * Dirk Hohndel, <hohndel@suse.de>
+ * Stefan Dirsch, <sndirsch@suse.de>
+ *
+ * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and
+ * Siemens Nixdorf Informationssysteme
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c,v 1.46 1999/07/04 06:38:57 dawes Exp $ */
+/* $PI: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_driver.c,v 1.37 1999/07/02 18:38:31 faith Exp $ */
+
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+#include "cfb24_32.h"
+#include "cfb8_32.h"
+#include "xf1bpp.h"
+#include "xf4bpp.h"
+#include "micmap.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Version.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86cmap.h"
+#include "vgaHW.h"
+#include "xf86RAC.h"
+#include "xf86Resources.h"
+
+#include "mipointer.h"
+
+#include "mibstore.h"
+
+#include "glint_regs.h"
+#include "IBM.h"
+#include "TI.h"
+#include "glint.h"
+
+#ifdef XFreeXDGA
+#define _XF86DGA_SERVER_
+#include "extensions/xf86dgastr.h"
+#endif
+
+#ifdef DPMSExtension
+#include "globals.h"
+#define DPMS_SERVER
+#include "extensions/dpms.h"
+#endif
+
+static void GLINTIdentify(int flags);
+static Bool GLINTProbe(DriverPtr drv, int flags);
+static Bool GLINTPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool GLINTScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool GLINTEnterVT(int scrnIndex, int flags);
+static void GLINTLeaveVT(int scrnIndex, int flags);
+static Bool GLINTCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool GLINTSaveScreen(ScreenPtr pScreen, Bool unblank);
+
+/* Required if the driver supports mode switching */
+static Bool GLINTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+/* Required if the driver supports moving the viewport */
+static void GLINTAdjustFrame(int scrnIndex, int x, int y, int flags);
+
+/* Optional functions */
+static void GLINTFreeScreen(int scrnIndex, int flags);
+static int GLINTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
+
+/* Internally used functions */
+static Bool GLINTMapMem(ScrnInfoPtr pScrn);
+static Bool GLINTUnmapMem(ScrnInfoPtr pScrn);
+static void GLINTSave(ScrnInfoPtr pScrn);
+static void GLINTRestore(ScrnInfoPtr pScrn);
+static Bool GLINTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+
+/*
+ * This is intentionally screen-independent. It indicates the binding
+ * choice made in the first PreInit.
+ */
+static int pix24bpp = 0;
+
+#define VERSION 4000
+#define GLINT_NAME "GLINT"
+#define GLINT_DRIVER_NAME "glint"
+#define GLINT_MAJOR_VERSION 1
+#define GLINT_MINOR_VERSION 0
+#define GLINT_PATCHLEVEL 0
+
+/*
+ * This contains the functions needed by the server after loading the driver
+ * module. It must be supplied, and gets passed back by the SetupProc
+ * function in the dynamic case. In the static case, a reference to this
+ * is compiled in, and this requires that the name of this DriverRec be
+ * an upper-case version of the driver name.
+ */
+
+DriverRec GLINT = {
+ VERSION,
+ "accelerated driver for 3dlabs and derived chipsets",
+ GLINTIdentify,
+ GLINTProbe,
+ NULL,
+ 0
+};
+
+static SymTabRec GLINTChipsets[] = {
+ { PCI_VENDOR_TI_CHIP_PERMEDIA2, "ti_pm2" },
+ { PCI_VENDOR_TI_CHIP_PERMEDIA, "ti_pm" },
+ { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, "pm2v" },
+ { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2, "pm2" },
+ { PCI_VENDOR_3DLABS_CHIP_PERMEDIA, "pm" },
+ { PCI_VENDOR_3DLABS_CHIP_500TX, "500tx" },
+ { PCI_VENDOR_3DLABS_CHIP_MX, "mx" },
+ { PCI_VENDOR_3DLABS_CHIP_GAMMA, "gamma" },
+ { -1, NULL }
+};
+
+static PciChipsets GLINTPciChipsets[] = {
+ { PCI_VENDOR_TI_CHIP_PERMEDIA2, PCI_VENDOR_TI_CHIP_PERMEDIA2, RES_SHARED_VGA },
+ { PCI_VENDOR_TI_CHIP_PERMEDIA, PCI_VENDOR_TI_CHIP_PERMEDIA, NULL },
+ { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V, RES_SHARED_VGA },
+ { PCI_VENDOR_3DLABS_CHIP_PERMEDIA2, PCI_VENDOR_3DLABS_CHIP_PERMEDIA2, RES_SHARED_VGA },
+ { PCI_VENDOR_3DLABS_CHIP_PERMEDIA, PCI_VENDOR_3DLABS_CHIP_PERMEDIA, NULL },
+ { PCI_VENDOR_3DLABS_CHIP_500TX, PCI_VENDOR_3DLABS_CHIP_500TX, NULL },
+ { PCI_VENDOR_3DLABS_CHIP_MX, PCI_VENDOR_3DLABS_CHIP_MX, NULL },
+ { PCI_VENDOR_3DLABS_CHIP_GAMMA, PCI_VENDOR_3DLABS_CHIP_GAMMA, NULL },
+ { -1, -1, RES_UNDEFINED }
+};
+
+
+typedef enum {
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+ OPTION_PCI_RETRY,
+ OPTION_RGB_BITS,
+ OPTION_NOACCEL,
+ OPTION_BLOCK_WRITE,
+ OPTION_FIREGL3000,
+ OPTION_MEM_CLK,
+ OPTION_OVERLAY
+} GLINTOpts;
+
+static OptionInfoRec GLINTOptions[] = {
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_RGB_BITS, "RGBbits", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_BLOCK_WRITE, "BlockWrite", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_FIREGL3000, "FireGL3000", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_MEM_CLK, "SetMClk", OPTV_FREQ, {0}, FALSE },
+ { OPTION_OVERLAY, "Overlay", OPTV_ANYSTR, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+static RamDacSupportedInfoRec PermediaRamdacs[] = {
+ { IBM526DB_RAMDAC },
+ { IBM526_RAMDAC },
+ { -1 }
+};
+
+static RamDacSupportedInfoRec TXMXRamdacs[] = {
+ { IBM526DB_RAMDAC },
+ { IBM526_RAMDAC },
+ { IBM640_RAMDAC },
+ { -1 }
+};
+
+static RamDacSupportedInfoRec GMX2000Ramdacs[] = {
+ { TI3030_RAMDAC },
+ { -1 }
+};
+
+
+static const char *vgahwSymbols[] = {
+ "vgaHWGetIndex",
+ "vgaHWSave",
+ "vgaHWRestore",
+ "vgaHWGetHWRec",
+ "vgaHWUnlock",
+ "vgaHWInit",
+ "vgaHWProtect",
+ "vgaHWSetMmioFuncs",
+ "vgaHWGetIOBase",
+ "vgaHWMapMem",
+ "vgaHWLock",
+ "vgaHWFreeHWRec",
+ "vgaHWSaveScreen",
+ "vgaHWddc1SetSpeed",
+ NULL
+};
+
+static const char *xf8_32bppSymbols[] = {
+ "xf86Overlay8Plus32Init",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAADestroyInfoRec",
+ "XAACreateInfoRec",
+ "XAAInit",
+ "XAAStippleScanlineFuncLSBFirst",
+ "XAAOverlayFBfuncs",
+ "XAACachePlanarMonoStipple",
+ "XAAScreenIndex",
+ "XAAPolyLines",
+ "XAAPolySegment",
+ NULL
+};
+
+static const char *fbSymbols[] = {
+ "xf1bppScreenInit",
+ "xf4bppScreenInit",
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb24ScreenInit",
+ "cfb24_32ScreenInit",
+ "cfb32ScreenInit",
+ "cfb8_32ScreenInit",
+ "cfbGCPrivateIndex",
+ "cfb16GCPrivateIndex",
+ "cfb32GCPrivateIndex",
+ "cfbBresS",
+ "cfb16BresS",
+ "cfb32BresS",
+ NULL
+};
+
+static const char *ddcSymbols[] = {
+ "xf86PrintEDID",
+ "xf86DoEDID_DDC1",
+ "xf86DoEDID_DDC2",
+ NULL
+};
+
+static const char *i2cSymbols[] = {
+ "xf86CreateI2CBusRec",
+ "xf86DestroyI2CBusRec",
+ "xf86I2CBusInit",
+ "xf86I2CDevInit",
+ "xf86I2CProbeAddress",
+ "xf86I2CWriteByte",
+ "xf86I2CWriteVec",
+ NULL
+};
+
+#ifdef XF86DRI
+static const char *drmSymbols[] = {
+ "drmAddBufs",
+ "drmAddMap",
+ "drmCtlAddCommand",
+ "drmCtlInstHandler",
+ "drmGetInterruptFromBusID",
+ "drmMapBufs",
+ "drmMarkBufs",
+ "drmUnmapBufs",
+ NULL
+};
+
+static const char *driSymbols[] = {
+ "DRIGetDrawableIndex",
+ "DRIFinishScreenInit",
+ "DRIDestroyInfoRec",
+ "DRICloseScreen",
+ "DRIDestroyInfoRec",
+ "DRIScreenInit",
+ "DRIDestroyInfoRec",
+ "DRICreateInfoRec",
+ "GlxSetVisualConfigs",
+ NULL
+};
+#endif
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(glintSetup);
+
+static XF86ModuleVersionInfo glintVersRec =
+{
+ "glint",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ GLINT_MAJOR_VERSION, GLINT_MINOR_VERSION, GLINT_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+XF86ModuleData glintModuleData = { &glintVersRec, glintSetup, NULL };
+
+pointer
+glintSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&GLINT, module, 0);
+ LoaderRefSymLists(vgahwSymbols, fbSymbols, ddcSymbols, i2cSymbols,
+ xaaSymbols, xf8_32bppSymbols,
+#ifdef XF86DRI
+ drmSymbols, driSymbols,
+#endif
+ NULL);
+ return (pointer)TRUE;
+ }
+
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+}
+
+#endif /* XFree86LOADER */
+
+#define PARTPROD(a,b,c) (((a)<<6) | ((b)<<3) | (c))
+
+static char bppand[4] = { 0x03, /* 8bpp */
+ 0x01, /* 16bpp */
+ 0x00, /* 24bpp */
+ 0x00 /* 32bpp */};
+
+static int partprod500TX[] = {
+ -1,
+ PARTPROD(0,0,1), PARTPROD(0,0,2), PARTPROD(0,1,2), PARTPROD(0,0,3),
+ PARTPROD(0,1,3), PARTPROD(0,2,3), PARTPROD(1,2,3), PARTPROD(0,0,4),
+ PARTPROD(0,1,4), PARTPROD(0,2,4), PARTPROD(1,2,4), PARTPROD(0,3,4),
+ PARTPROD(1,3,4), PARTPROD(2,3,4), -1, PARTPROD(0,0,5),
+ PARTPROD(0,1,5), PARTPROD(0,2,5), PARTPROD(1,2,5), PARTPROD(0,3,5),
+ PARTPROD(1,3,5), PARTPROD(2,3,5), -1, PARTPROD(0,4,5),
+ PARTPROD(1,4,5), PARTPROD(2,4,5), PARTPROD(3,4,5), -1,
+ -1, -1, -1, PARTPROD(0,0,6),
+ PARTPROD(0,1,6), PARTPROD(0,2,6), PARTPROD(1,2,6), PARTPROD(0,3,6),
+ PARTPROD(1,3,6), PARTPROD(2,3,6), -1, PARTPROD(0,4,6),
+ PARTPROD(1,4,6), PARTPROD(2,4,6), -1, PARTPROD(3,4,6),
+ -1, -1, -1, PARTPROD(0,5,6),
+ PARTPROD(1,5,6), PARTPROD(2,5,6), -1, PARTPROD(3,5,6),
+ -1, -1, -1, PARTPROD(4,5,6),
+ -1, -1, -1, -1,
+ -1, -1, -1, PARTPROD(0,0,7),
+ -1, PARTPROD(0,2,7), PARTPROD(1,2,7), PARTPROD(0,3,7),
+ PARTPROD(1,3,7), PARTPROD(2,3,7), -1, PARTPROD(0,4,7),
+ PARTPROD(1,4,7), PARTPROD(2,4,7), -1, PARTPROD(3,4,7),
+ -1, -1, -1, PARTPROD(0,5,7),
+ PARTPROD(1,5,7), PARTPROD(2,5,7), -1, PARTPROD(3,5,7),
+ -1, -1, -1, PARTPROD(4,5,7),
+ -1, -1, -1, -1,
+ -1, -1, -1, PARTPROD(0,6,7),
+ PARTPROD(1,6,7), PARTPROD(2,6,7), -1, PARTPROD(3,6,7),
+ -1, -1, -1, PARTPROD(4,6,7),
+ -1, -1, -1, -1,
+ -1, -1, -1, PARTPROD(5,6,7),
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, PARTPROD(0,7,7),
+ 0};
+
+int partprodPermedia[] = {
+ -1,
+ PARTPROD(0,0,1), PARTPROD(0,1,1), PARTPROD(1,1,1), PARTPROD(1,1,2),
+ PARTPROD(1,2,2), PARTPROD(1,2,2), PARTPROD(1,2,3), PARTPROD(2,2,3),
+ PARTPROD(1,3,3), PARTPROD(2,3,3), PARTPROD(1,2,4), PARTPROD(3,3,3),
+ PARTPROD(1,3,4), PARTPROD(2,3,4), -1, PARTPROD(3,3,4),
+ PARTPROD(1,4,4), PARTPROD(2,4,4), -1, PARTPROD(3,4,4),
+ -1, PARTPROD(2,3,5), -1, PARTPROD(4,4,4),
+ PARTPROD(1,4,5), PARTPROD(2,4,5), PARTPROD(3,4,5), -1,
+ -1, -1, -1, PARTPROD(4,4,5),
+ PARTPROD(1,5,5), PARTPROD(2,5,5), -1, PARTPROD(3,5,5),
+ -1, -1, -1, PARTPROD(4,5,5),
+ -1, -1, -1, PARTPROD(3,4,6),
+ -1, -1, -1, PARTPROD(5,5,5),
+ PARTPROD(1,5,6), PARTPROD(2,5,6), -1, PARTPROD(3,5,6),
+ -1, -1, -1, PARTPROD(4,5,6),
+ -1, -1, -1, -1,
+ -1, -1, -1, PARTPROD(5,5,6),
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ -1, -1, -1, -1,
+ 0};
+
+#ifdef DPMSExtension
+static void
+GLINTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
+ int flags)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int videocontrol = 0, vtgpolarity = 0;
+
+ if((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_500TX) ||
+ (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_MX) ||
+ (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA)) {
+ vtgpolarity = GLINT_READ_REG(VTGPolarity) & 0xFFFFFFF0;
+ } else {
+ videocontrol = GLINT_READ_REG(PMVideoControl) & 0xFFFFFFD6;
+ }
+
+ switch (PowerManagementMode) {
+ case DPMSModeOn:
+ /* Screen: On, HSync: On, VSync: On */
+ videocontrol |= 0x29;
+ vtgpolarity |= 0x05;
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off, HSync: Off, VSync: On */
+ videocontrol |= 0x20;
+ vtgpolarity |= 0x04;
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off, HSync: On, VSync: Off */
+ videocontrol |= 0x08;
+ vtgpolarity |= 0x01;
+ break;
+ case DPMSModeOff:
+ /* Screen: Off, HSync: Off, VSync: Off */
+ videocontrol |= 0x00;
+ vtgpolarity |= 0x00;
+ break;
+ default:
+ return;
+ }
+
+ if((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_500TX) ||
+ (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_MX) ||
+ (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA)) {
+ GLINT_SLOW_WRITE_REG(vtgpolarity, VTGPolarity);
+ } else {
+ GLINT_SLOW_WRITE_REG(videocontrol, PMVideoControl);
+ }
+}
+#endif
+
+static Bool
+GLINTGetRec(ScrnInfoPtr pScrn)
+{
+ /*
+ * Allocate an GLINTRec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(GLINTRec), 1);
+ /* Initialise it */
+
+ return TRUE;
+}
+
+static void
+GLINTFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+
+/* Mandatory */
+static void
+GLINTIdentify(int flags)
+{
+ xf86PrintChipsets(GLINT_NAME, "driver for 3Dlabs chipsets", GLINTChipsets);
+}
+
+
+/* Mandatory */
+static Bool
+GLINTProbe(DriverPtr drv, int flags)
+{
+ int i;
+ pciVideoPtr pPci, *checkusedPci;
+ PCITAG deltatag = 0, chiptag = 0;
+ GDevPtr *devSections;
+ int numDevSections;
+ int numUsed;
+ int *usedChips;
+ Bool foundScreen = FALSE;
+ unsigned long glintbase = 0, glintbase3 = 0, deltabase = 0;
+ unsigned long *delta_pci_base = 0 ;
+
+ /*
+ * The aim here is to find all cards that this driver can handle,
+ * and for the ones not already claimed by another driver, claim the
+ * slot, and allocate a ScrnInfoRec.
+ *
+ * This should be a minimal probe, and it should under no circumstances
+ * change the state of the hardware. Because a device is found, don't
+ * assume that it will be used. Don't do any initialisations other than
+ * the required ScrnInfoRec initialisations. Don't allocate any new
+ * data structures.
+ */
+
+ /*
+ * Next we check, if there has been a chipset override in the config file.
+ * For this we must find out if there is an active device section which
+ * is relevant, i.e., which has no driver specified or has THIS driver
+ * specified.
+ */
+
+ if ((numDevSections = xf86MatchDevice(GLINT_DRIVER_NAME,
+ &devSections)) <= 0) {
+ /*
+ * There's no matching device section in the config file, so quit
+ * now.
+ */
+ return FALSE;
+ }
+
+ /*
+ * We need to probe the hardware first. We then need to see how this
+ * fits in with what is given in the config file, and allow the config
+ * file info to override any contradictions.
+ */
+
+ /*
+ * All of the cards this driver supports are PCI, so the "probing" just
+ * amounts to checking the PCI data that the server has already collected.
+ */
+ checkusedPci = xf86GetPciVideoInfo();
+
+ if (checkusedPci == NULL) {
+ /*
+ * We won't let anything in the config file override finding no
+ * PCI video cards at all. This seems reasonable now, but we'll see.
+ */
+ return FALSE;
+ }
+
+ numUsed = xf86MatchPciInstances(GLINT_NAME, 0,
+ GLINTChipsets, GLINTPciChipsets, devSections,
+ numDevSections, drv, &usedChips);
+ xfree(devSections);
+ devSections = NULL;
+ if (numUsed <= 0)
+ return FALSE;
+
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn;
+
+ /* Allocate a ScrnInfoRec and claim the slot */
+ pScrn = xf86AllocateScreen(drv, 0);
+ ErrorF("used chips: %i\n",usedChips[i]);
+
+ xf86ConfigActivePciEntity(pScrn, usedChips[i], GLINTPciChipsets, NULL,
+ NULL, NULL, NULL, NULL);
+
+ pPci = xf86GetPciInfoForEntity(usedChips[i]);
+ glintbase = pPci->memBase[0];
+ chiptag = pciTag(pPci->bus, pPci->device, pPci->func);
+
+ /* Need to claim Glint Delta for PERMEDIA & 500TX */
+ /* and for the moment we claim all other chips on the same */
+ /* bus/device number */
+ if ( (pPci->chipType == PCI_CHIP_500TX) ||
+ (pPci->chipType == PCI_CHIP_MX) ||
+ (pPci->chipType == PCI_CHIP_GAMMA) ||
+ (pPci->chipType == PCI_CHIP_PERMEDIA) ) {
+
+ while (*checkusedPci != NULL) {
+ int gIndex;
+ /* make sure we claim all but our source device */
+ if ((pPci->bus == (*checkusedPci)->bus &&
+ pPci->device == (*checkusedPci)->device) &&
+ pPci->func != (*checkusedPci)->func) {
+
+ /* Find that Delta chip, and give us the tag value */
+ if ( (((*checkusedPci)->vendor == PCI_VENDOR_TI) ||
+ ((*checkusedPci)->vendor == PCI_VENDOR_3DLABS)) &&
+ (((*checkusedPci)->chipType == PCI_CHIP_DELTA) ||
+ ((*checkusedPci)->chipType == PCI_CHIP_MX)) ) {
+ if ((*checkusedPci)->chipType == PCI_CHIP_DELTA) {
+ deltabase = (*checkusedPci)->memBase[0];
+ delta_pci_base = &((*checkusedPci)->memBase[0]);
+ deltatag = pciTag((*checkusedPci)->bus,
+ (*checkusedPci)->device,
+ (*checkusedPci)->func);
+ }
+ gIndex = xf86ClaimPciSlot((*checkusedPci)->bus,
+ (*checkusedPci)->device,
+ (*checkusedPci)->func, drv,
+ (*checkusedPci)->chipType,
+ NULL, TRUE);
+ if (gIndex == -1) {
+ /* This can't happen */
+ FatalError("someone claimed the free slot!\n");
+ }
+ xf86ConfigActivePciEntity(pScrn, gIndex,
+ NULL, NULL, NULL, NULL,
+ NULL, NULL);
+ } else {
+ int eIndex;
+ /* Claim other entities on the same card */
+ eIndex = xf86ClaimPciSlot((*checkusedPci)->bus,
+ (*checkusedPci)->device,
+ (*checkusedPci)->func,
+ drv, -1 /* XXX */,
+ NULL, FALSE);
+ if (eIndex == -1) {
+ /* This can't happen */
+ FatalError("someone claimed the free slot!\n");
+ }
+ }
+ }
+ checkusedPci++;
+ }
+ }
+
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = GLINT_DRIVER_NAME;
+ pScrn->name = GLINT_NAME;
+ pScrn->Probe = GLINTProbe;
+ pScrn->PreInit = GLINTPreInit;
+ pScrn->ScreenInit = GLINTScreenInit;
+ pScrn->SwitchMode = GLINTSwitchMode;
+ pScrn->AdjustFrame = GLINTAdjustFrame;
+ pScrn->EnterVT = GLINTEnterVT;
+ pScrn->LeaveVT = GLINTLeaveVT;
+ pScrn->FreeScreen = GLINTFreeScreen;
+ pScrn->ValidMode = GLINTValidMode;
+ foundScreen = TRUE;
+
+/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
+/* NEED TO MOVE THIS OUT OF THE PROBE CODE */
+/* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
+ {
+ int temp;
+ int bugbase = 0;
+ /*
+ * due to a few bugs in the GLINT Delta we might have to
+ * relocate the base address of config region of the Delta, if
+ * bit 17 of the base addresses of config region of the Delta
+ * and the 500TX or 300SX are different
+ * We only handle config type 1 at this point
+ */
+ if (deltatag && chiptag) {
+ if ((deltabase & 0x20000) ^ (glintbase & 0x20000)) {
+ /*
+ * if the base addresses are different at bit 17,
+ * we have to remap the base0 for the delta;
+ * as wrong as this looks, we can use the base3 of the
+ * 300SX/500TX for this. The delta is working as a bridge
+ * here and gives its own addresses preference. And we
+ * don't need to access base3, as this one is the bytw
+ * swapped local buffer which we don't need.
+ * Using base3 we know that the space is
+ * a) large enough
+ * b) free (well, almost)
+ *
+ * to be able to do that we need to enable IO
+ */
+ if (pPci->chipType == PCI_CHIP_PERMEDIA) {
+ glintbase3 = pciReadLong(chiptag, 0x20); /* base4 */
+ } else {
+ glintbase3 = pciReadLong(chiptag, 0x1c); /* base3 */
+ }
+ if ((glintbase & 0x20000) ^ (glintbase3 & 0x20000)) {
+ /*
+ * oops, still different; we know that base3 is at least
+ * 16 MB, so we just take 128k offset into it
+ */
+ glintbase3 += 0x20000;
+ }
+ /*
+ * and now for the magic.
+ * read old value
+ * write fffffffff
+ * read value
+ * write new value
+ */
+ bugbase = pciReadLong(deltatag, 0x10);
+ pciWriteLong(deltatag, 0x10, 0xffffffff);
+ temp = pciReadLong(deltatag, 0x10);
+ pciWriteLong(deltatag, 0x10, glintbase3);
+
+ /* Update PCI tables */
+ *delta_pci_base = glintbase3;
+
+ /*
+ * additionally, sometimes we see the baserom which might
+ * confuse the chip, so let's make sure that is disabled
+ */
+ temp = pciReadLong(chiptag, 0x30);
+ pciWriteLong(chiptag, 0x30, 0xffffffff);
+ temp = pciReadLong(chiptag, 0x30);
+ pciWriteLong(chiptag, 0x30, 0);
+ }
+ }
+ if (bugbase)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Glint Delta BUG, fixing.....old = 0x%x, new = 0x%x\n",
+ bugbase, glintbase3);
+ }
+ /*
+ * ok, now let's forget about the Delta, in case we found one
+ */
+ deltatag = deltabase = 0;
+ }
+ xfree(usedChips);
+ return foundScreen;
+}
+
+/*
+ * GetAccelPitchValues -
+ *
+ * This function returns a list of display width (pitch) values that can
+ * be used in accelerated mode.
+ */
+static int *
+GetAccelPitchValues(ScrnInfoPtr pScrn)
+{
+ int *linePitches = NULL;
+ int i, n = 0;
+ int *linep = NULL;
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ switch (pGlint->Chipset) {
+ case PCI_VENDOR_TI_CHIP_PERMEDIA2:
+ case PCI_VENDOR_TI_CHIP_PERMEDIA:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
+ linep = &partprodPermedia[0];
+ break;
+ case PCI_VENDOR_3DLABS_CHIP_500TX:
+ case PCI_VENDOR_3DLABS_CHIP_MX:
+ case PCI_VENDOR_3DLABS_CHIP_GAMMA:
+ linep = &partprod500TX[0];
+ break;
+ }
+
+ for (i = 0; linep[i] != 0; i++) {
+ if (linep[i] != -1) {
+ n++;
+ linePitches = xnfrealloc(linePitches, n * sizeof(int));
+ linePitches[n - 1] = i << 5;
+ }
+ }
+
+ /* Mark the end of the list */
+ if (n > 0) {
+ linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
+ linePitches[n] = 0;
+ }
+
+ return linePitches;
+}
+
+/* Mandatory */
+static Bool
+GLINTPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ GLINTPtr pGlint;
+ MessageType from;
+ int i;
+ int LinearFramebuffer = 0;
+ double real;
+ Bool Overlay = FALSE;
+ int maxwidth = 0, maxheight = 0;
+ ClockRangePtr clockRanges;
+ char *mod = NULL;
+ const char *s;
+
+
+ /*
+ * Note: This function is only called once at server startup, and
+ * not at the start of each server generation. This means that
+ * only things that are persistent across server generations can
+ * be initialised here. xf86Screens[] is (pScrn is a pointer to one
+ * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex()
+ * are too, and should be used for data that must persist across
+ * server generations.
+ *
+ * Per-generation data should be allocated with
+ * AllocateScreenPrivateIndex() from the ScreenInit() function.
+ */
+
+ /* Check the number of entities, and fail if it isn't one or more. */
+ if (pScrn->numEntities < 1)
+ return FALSE;
+
+ /* The ramdac module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "ramdac"))
+ return FALSE;
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /* Allocate the GLINTRec driverPrivate */
+ if (!GLINTGetRec(pScrn)) {
+ return FALSE;
+ }
+ pGlint = GLINTPTR(pScrn);
+
+ /* Get the entities, and make sure they are PCI. */
+ pGlint->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pGlint->pEnt->location.type != BUS_PCI)
+ return FALSE;
+ pGlint->PciInfo = xf86GetPciInfoForEntity(pGlint->pEnt->index);
+ pGlint->PciTag = pciTag(pGlint->PciInfo->bus, pGlint->PciInfo->device,
+ pGlint->PciInfo->func);
+
+ if (pScrn->numEntities > 1) {
+ pciVideoPtr pPci;
+ EntityInfoPtr pEnt;
+
+ for (i = 1; i < pScrn->numEntities; i++) {
+ pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
+ pPci = xf86GetPciInfoForEntity(pEnt->index);
+ if (pPci->chipType == PCI_CHIP_DELTA
+ ) {
+ pGlint->pEntGeometry = pEnt;
+ pGlint->PciInfoGeometry = pPci;
+ pGlint->PciTagGeometry = pciTag(pPci->bus, pPci->device,
+ pPci->func);
+ } else if (pPci->chipType == PCI_CHIP_MX) {
+ if (pGlint->numMXDevices >= GLINT_MAX_MX_DEVICES) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "%d MX chips supported, additional MX device ignored\n",
+ GLINT_MAX_MX_DEVICES);
+ } else {
+ LinearFramebuffer = pPci->memBase[2];
+ pGlint->pEntMX[pGlint->numMXDevices] = pEnt;
+ pGlint->MXPciInfo[pGlint->numMXDevices] = pPci;
+ pGlint->numMXDevices++;
+ }
+ }
+ }
+ }
+
+ /*
+ * VGA isn't used, so mark it so. XXX Should check if any VGA resources
+ * are decoded or not, and if not, change them from Unused to Disabled.
+ */
+ xf86SetOperatingState(RES_SHARED_VGA, pGlint->pEnt->index, ResUnusedOpr);
+
+ /* Operations for which memory access is required. */
+ pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+ pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+
+ /*
+ * The first thing we should figure out is the depth, bpp, etc.
+ * Our default depth is 8, so pass it to the helper function.
+ * We support both 24bpp and 32bpp layouts, so indicate that.
+ */
+ if (!xf86SetDepthBpp(pScrn, 8, 0, 0, /*Support24bppFb |*/ Support32bppFb
+ /*| SupportConvert32to24 | PreferConvert32to24*/)) {
+ return FALSE;
+ } else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 1:
+ case 4:
+ case 8:
+ case 15:
+ case 16:
+ case 24:
+ case 30:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ xf86PrintDepthBpp(pScrn);
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /*
+ * If the driver can do gamma correction, it should call xf86SetGamma()
+ * here.
+ */
+
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+
+ /* We use a programamble clock */
+ pScrn->progClock = TRUE;
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, GLINTOptions);
+
+ /* Default to 8bits per RGB */
+ if (pScrn->depth == 30) pScrn->rgbBits = 10;
+ else pScrn->rgbBits = 8;
+ if (xf86GetOptValInteger(GLINTOptions, OPTION_RGB_BITS, &pScrn->rgbBits)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
+ pScrn->rgbBits);
+ }
+
+ if (xf86GetOptValFreq(GLINTOptions, OPTION_MEM_CLK, OPTUNITS_MHZ, &real)) {
+ pGlint->MemClock = (int)real;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Memory Clock override enabled, set to %dMHz\n",
+ pGlint->MemClock);
+ }
+ from = X_DEFAULT;
+ pGlint->HWCursor = TRUE; /* ON by default */
+ if (xf86GetOptValBool(GLINTOptions, OPTION_HW_CURSOR, &pGlint->HWCursor))
+ from = X_CONFIG;
+ if (xf86ReturnOptValBool(GLINTOptions, OPTION_SW_CURSOR, FALSE)) {
+ from = X_CONFIG;
+ pGlint->HWCursor = FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pGlint->HWCursor ? "HW" : "SW");
+ if (xf86ReturnOptValBool(GLINTOptions, OPTION_NOACCEL, FALSE)) {
+ pGlint->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+ pGlint->UsePCIRetry = FALSE;
+ from = X_DEFAULT;
+ if (xf86GetOptValBool(GLINTOptions, OPTION_PCI_RETRY, &pGlint->UsePCIRetry))
+ from = X_CONFIG;
+ if (pGlint->UsePCIRetry)
+ xf86DrvMsg(pScrn->scrnIndex, from, "PCI retry enabled\n");
+ pScrn->overlayFlags = 0;
+ from = X_DEFAULT;
+ if ((s = xf86GetOptValString(GLINTOptions, OPTION_OVERLAY))) {
+ if (!*s || !xf86NameCmp(s, "8,24") || !xf86NameCmp(s, "24,8")) {
+ Overlay = TRUE;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "\"%s\" is not a valid value for Option \"Overlay\"\n", s);
+ }
+ }
+ if (Overlay) {
+ if ((pScrn->depth == 24) && (pScrn->bitsPerPixel == 32)) {
+ pScrn->colorKey = 255; /* we should let the user change this */
+ pScrn->overlayFlags = OVERLAY_8_32_PLANAR;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "24/8 overlay enabled\n");
+ }
+ }
+
+ pGlint->VGAcore = FALSE;
+ pGlint->DoubleBuffer = FALSE;
+ pGlint->RamDac = NULL;
+ /*
+ * Set the Chipset and ChipRev, allowing config file entries to
+ * override.
+ */
+ if (pGlint->pEnt->device->chipset && *pGlint->pEnt->device->chipset) {
+ pScrn->chipset = pGlint->pEnt->device->chipset;
+ pGlint->Chipset = xf86StringToToken(GLINTChipsets, pScrn->chipset);
+ from = X_CONFIG;
+ } else if (pGlint->pEnt->device->chipID >= 0) {
+ pGlint->Chipset = pGlint->pEnt->device->chipID;
+ pScrn->chipset = (char *)xf86TokenToString(GLINTChipsets,
+ pGlint->Chipset);
+
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pGlint->Chipset);
+ } else {
+ from = X_PROBED;
+ pGlint->Chipset = pGlint->PciInfo->vendor << 16 |
+ pGlint->PciInfo->chipType;
+ pScrn->chipset = (char *)xf86TokenToString(GLINTChipsets,
+ pGlint->Chipset);
+ }
+ if (pGlint->pEnt->device->chipRev >= 0) {
+ pGlint->ChipRev = pGlint->pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pGlint->ChipRev);
+ } else {
+ pGlint->ChipRev = pGlint->PciInfo->chipRev;
+ }
+
+ /*
+ * This shouldn't happen because such problems should be caught in
+ * GLINTProbe(), but check it just in case.
+ */
+ if (pScrn->chipset == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ChipID 0x%04X is not recognised\n", pGlint->Chipset);
+ return FALSE;
+ }
+ if (pGlint->Chipset < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Chipset \"%s\" is not recognised\n", pScrn->chipset);
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
+
+ if ((pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA2) ||
+ (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) ||
+ (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2)) {
+ if (xf86ReturnOptValBool(GLINTOptions, OPTION_BLOCK_WRITE, FALSE)) {
+ pGlint->UseBlockWrite = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Block Writes enabled\n");
+ }
+ }
+
+ if (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_500TX) {
+ if (xf86ReturnOptValBool(GLINTOptions, OPTION_FIREGL3000, FALSE)) {
+ /* Can't we detect a Fire GL 3000 ????? and remove this ? */
+ pGlint->UseFireGL3000 = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Diamond FireGL3000 mode enabled\n");
+ }
+ }
+
+ if (pGlint->pEnt->device->MemBase != 0) {
+ /*
+ * XXX Should check that the config file value matches one of the
+ * PCI base address values.
+ */
+ pGlint->FbAddress = pGlint->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ pGlint->FbAddress = pGlint->PciInfo->memBase[2] & 0xFF800000;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pGlint->FbAddress);
+
+ /* Trap GAMMA & DELTA specification, with no linear address */
+ /* Find the first TX/MX chip and use that address */
+ if (pGlint->FbAddress == 0) {
+ if (LinearFramebuffer) {
+ pGlint->FbAddress = LinearFramebuffer;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "FrameBuffer used from first TX/MX chip at 0x%x\n",
+ LinearFramebuffer);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "No FrameBuffer memory - aborting\n");
+ return FALSE;
+ }
+ }
+
+ if (pGlint->pEnt->device->IOBase != 0) {
+ /*
+ * XXX Should check that the config file value matches one of the
+ * PCI base address values.
+ */
+ pGlint->IOAddress = pGlint->pEnt->device->IOBase;
+ from = X_CONFIG;
+ } else {
+ if (pGlint->PciTagGeometry)
+ pGlint->IOAddress = pGlint->PciInfoGeometry->memBase[0] &0xFFFFC000;
+ else
+ pGlint->IOAddress = pGlint->PciInfo->memBase[0] & 0xFFFFC000;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
+ (unsigned long)pGlint->IOAddress);
+
+ if (pGlint->SecondaryAddress)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Secondary MMIO registers at 0x%lX\n", pGlint->SecondaryAddress);
+
+ pGlint->irq = pGlint->pEnt->device->irq;
+
+ /* Register the PCI-assigned resources. */
+ if (xf86RegisterResources(pGlint->pEnt->index, NULL, ResExclusive)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n");
+ return FALSE;
+ }
+ if (pGlint->pEntGeometry) {
+ if (xf86RegisterResources(pGlint->pEntGeometry->index, NULL, ResExclusive)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n");
+ return FALSE;
+ }
+ }
+ for (i = 0; i < pGlint->numMXDevices; i++) {
+ if (xf86RegisterResources(pGlint->pEntMX[i]->index, NULL,
+ ResExclusive)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n");
+ return FALSE;
+ }
+ }
+
+ /* HW bpp matches reported bpp */
+ pGlint->HwBpp = pScrn->bitsPerPixel;
+
+ pGlint->FbBase = NULL;
+ if (pGlint->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pGlint->pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else {
+ pGlint->FbMapSize = 0; /* Need to set FbMapSize for MMIO access */
+ /* Need to access MMIO to determine videoRam */
+ GLINTMapMem(pScrn);
+ if( (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_500TX) ||
+ (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_MX) ||
+ (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) )
+ pScrn->videoRam = 1024 * (1 << ((GLINT_READ_REG(FBMemoryCtl) &
+ 0xE0000000)>>29));
+ else
+ pScrn->videoRam = 2048 * (((GLINT_READ_REG(PMMemConfig) >> 29) &
+ 0x03) + 1);
+ GLINTUnmapMem(pScrn);
+ }
+
+ if ( (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) &&
+ (pGlint->numMXDevices == 2) ) {
+ unsigned int chipconfig;
+ GLINTMapMem(pScrn);
+
+ /*
+ * This is needed before the first GLINT_SLOW_WRITE_REG --
+ * otherwise the server will hang if it was left in a bad state.
+ */
+ GLINT_WRITE_REG(0, ResetStatus);
+ while (GLINT_READ_REG(ResetStatus) & 0x80000000) {
+ xf86DrvMsg(pScrn->scrnIndex, from, "Resetting Core\n");
+ }
+
+ GLINT_SLOW_WRITE_REG(GCSRSecondaryGLINTMapEn, GCSRAperture);
+
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "InFIFOSpace = %d, %d (after reset)\n",
+ GLINT_READ_REG(InFIFOSpace),
+ GLINT_SECONDARY_READ_REG(InFIFOSpace));
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "OutFIFOSWords = %d, %d (after reset)\n",
+ GLINT_READ_REG(OutFIFOWords),
+ GLINT_SECONDARY_READ_REG(OutFIFOWords));
+
+ /* Reset doesn't appear to drain the Output
+ FIFO. Argh. */
+ while (GLINT_READ_REG(OutFIFOWords)) {
+ GLINT_READ_REG(OutputFIFO);
+ }
+ while (GLINT_SECONDARY_READ_REG(OutFIFOWords)) {
+ GLINT_SECONDARY_READ_REG(OutputFIFO);
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "InFIFOSpace = %d, %d (after drain)\n",
+ GLINT_READ_REG(InFIFOSpace),
+ GLINT_SECONDARY_READ_REG(InFIFOSpace));
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "OutFIFOSWords = %d, %d (after drain)\n",
+ GLINT_READ_REG(OutFIFOWords),
+ GLINT_SECONDARY_READ_REG(OutFIFOWords));
+
+ chipconfig = GLINT_READ_REG(GChipConfig);
+ GLINTUnmapMem(pScrn);
+
+ switch (chipconfig & GChipMultiGLINTApMask) {
+ case GChipMultiGLINTAp_0M:
+ pGlint->MultiGLINTApSize = 0;
+ break;
+ case GChipMultiGLINTAp_16M:
+ pGlint->MultiGLINTApSize = 16 * 1024 * 1024;
+ break;
+ case GChipMultiGLINTAp_32M:
+ pGlint->MultiGLINTApSize = 32 * 1024 * 1024;
+ break;
+ case GChipMultiGLINTAp_64M:
+ pGlint->MultiGLINTApSize = 64 * 1024 * 1024;
+ break;
+ }
+
+ pGlint->FbMapSize = pGlint->MultiGLINTApSize;
+ pGlint->MXFbSize = pScrn->videoRam * 1024;
+ /* we have twice the memory w/ two MX chips */
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
+ pScrn->videoRam * 2);
+ }
+ else {
+ pGlint->FbMapSize = pScrn->videoRam * 1024;
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+ }
+
+ /* Let's check what type of DAC we have and reject if necessary */
+ switch (pGlint->Chipset) {
+ case PCI_VENDOR_TI_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
+ maxheight = 2048;
+ maxwidth = 2048;
+ pGlint->RefClock = 14318;
+ pGlint->VGAcore = TRUE; /* chip has a vga core */
+ pGlint->RamDacRec = RamDacCreateInfoRec();
+ pGlint->RamDacRec->ReadDAC = Permedia2InIndReg;
+ pGlint->RamDacRec->WriteDAC = Permedia2OutIndReg;
+ pGlint->RamDacRec->ReadAddress = Permedia2ReadAddress;
+ pGlint->RamDacRec->WriteAddress = Permedia2WriteAddress;
+ pGlint->RamDacRec->ReadData = Permedia2ReadData;
+ pGlint->RamDacRec->WriteData = Permedia2WriteData;
+ if(!RamDacInit(pScrn, pGlint->RamDacRec)) {
+ RamDacDestroyInfoRec(pGlint->RamDacRec);
+ return FALSE;
+ }
+ break;
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
+ maxheight = 2048;
+ maxwidth = 2048;
+ pGlint->RefClock = 14318;
+ pGlint->VGAcore = TRUE; /* chip has a vga core */
+ pGlint->RamDacRec = RamDacCreateInfoRec();
+ pGlint->RamDacRec->ReadDAC = Permedia2vInIndReg;
+ pGlint->RamDacRec->WriteDAC = Permedia2vOutIndReg;
+ pGlint->RamDacRec->ReadAddress = Permedia2ReadAddress;
+ pGlint->RamDacRec->WriteAddress = Permedia2WriteAddress;
+ pGlint->RamDacRec->ReadData = Permedia2ReadData;
+ pGlint->RamDacRec->WriteData = Permedia2WriteData;
+ if(!RamDacInit(pScrn, pGlint->RamDacRec)) {
+ RamDacDestroyInfoRec(pGlint->RamDacRec);
+ return FALSE;
+ }
+ break;
+ case PCI_VENDOR_TI_CHIP_PERMEDIA:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
+ maxheight = 1024;
+ maxwidth = 1536;
+ pGlint->RefClock = 14318;
+ pGlint->VGAcore = TRUE; /* chip has a vga core */
+ pGlint->RamDacRec = RamDacCreateInfoRec();
+ pGlint->RamDacRec->ReadDAC = glintInIBMRGBIndReg;
+ pGlint->RamDacRec->WriteDAC = glintOutIBMRGBIndReg;
+ pGlint->RamDacRec->ReadAddress = glintIBMReadAddress;
+ pGlint->RamDacRec->WriteAddress = glintIBMWriteAddress;
+ pGlint->RamDacRec->ReadData = glintIBMReadData;
+ pGlint->RamDacRec->WriteData = glintIBMWriteData;
+ if(!RamDacInit(pScrn, pGlint->RamDacRec)) {
+ RamDacDestroyInfoRec(pGlint->RamDacRec);
+ return FALSE;
+ }
+ GLINTMapMem(pScrn);
+ pGlint->RamDac = IBMramdacProbe(pScrn, PermediaRamdacs);
+ GLINTUnmapMem(pScrn);
+ if (pGlint->RamDac == NULL)
+ return FALSE;
+ break;
+ case PCI_VENDOR_3DLABS_CHIP_500TX:
+ case PCI_VENDOR_3DLABS_CHIP_MX:
+ maxheight = 4096;
+ maxwidth = 4096;
+ pGlint->RamDacRec = RamDacCreateInfoRec();
+ pGlint->RamDacRec->ReadDAC = glintInIBMRGBIndReg;
+ pGlint->RamDacRec->WriteDAC = glintOutIBMRGBIndReg;
+ pGlint->RamDacRec->ReadAddress = glintIBMReadAddress;
+ pGlint->RamDacRec->WriteAddress = glintIBMWriteAddress;
+ pGlint->RamDacRec->ReadData = glintIBMReadData;
+ pGlint->RamDacRec->WriteData = glintIBMWriteData;
+ if(!RamDacInit(pScrn, pGlint->RamDacRec)) {
+ RamDacDestroyInfoRec(pGlint->RamDacRec);
+ return FALSE;
+ }
+ GLINTMapMem(pScrn);
+ pGlint->RamDac = IBMramdacProbe(pScrn, TXMXRamdacs);
+ GLINTUnmapMem(pScrn);
+ if (pGlint->RamDac->RamDacType == (IBM640_RAMDAC))
+ pGlint->RefClock = 28322;
+ else
+ if (pGlint->RamDac->RamDacType == (IBM526DB_RAMDAC) ||
+ pGlint->RamDac->RamDacType == (IBM526_RAMDAC))
+ pGlint->RefClock = 40000;
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Undefined RefClock\n");
+ return FALSE;
+ }
+ if (pGlint->RamDac == NULL)
+ return FALSE;
+ break;
+ case PCI_VENDOR_3DLABS_CHIP_GAMMA:
+ maxheight = 4096;
+ maxwidth = 4096;
+ pGlint->RefClock = 14318;
+ pGlint->RamDacRec = RamDacCreateInfoRec();
+ pGlint->RamDacRec->ReadDAC = glintInTIIndReg;
+ pGlint->RamDacRec->WriteDAC = glintOutTIIndReg;
+ pGlint->RamDacRec->ReadAddress = glintTIReadAddress;
+ pGlint->RamDacRec->WriteAddress = glintTIWriteAddress;
+ pGlint->RamDacRec->ReadData = glintTIReadData;
+ pGlint->RamDacRec->WriteData = glintTIWriteData;
+ if(!RamDacInit(pScrn, pGlint->RamDacRec)) {
+ RamDacDestroyInfoRec(pGlint->RamDacRec);
+ return FALSE;
+ }
+ GLINTMapMem(pScrn);
+ pGlint->RamDac = TIramdacProbe(pScrn, GMX2000Ramdacs);
+ GLINTUnmapMem(pScrn);
+ if (!pGlint->RamDac) {
+ pGlint->RamDacRec = RamDacCreateInfoRec();
+ pGlint->RamDacRec->ReadDAC = glintInIBMRGBIndReg;
+ pGlint->RamDacRec->WriteDAC = glintOutIBMRGBIndReg;
+ pGlint->RamDacRec->ReadAddress = glintIBMReadAddress;
+ pGlint->RamDacRec->WriteAddress = glintIBMWriteAddress;
+ pGlint->RamDacRec->ReadData = glintIBMReadData;
+ pGlint->RamDacRec->WriteData = glintIBMWriteData;
+ if(!RamDacInit(pScrn, pGlint->RamDacRec)) {
+ RamDacDestroyInfoRec(pGlint->RamDacRec);
+ return FALSE;
+ }
+ GLINTMapMem(pScrn);
+ pGlint->RamDac = IBMramdacProbe(pScrn, TXMXRamdacs);
+ GLINTUnmapMem(pScrn);
+ if (pGlint->RamDac->RamDacType == (IBM640_RAMDAC))
+ pGlint->RefClock = 28322;
+ else
+ if (pGlint->RamDac->RamDacType == (IBM526DB_RAMDAC) ||
+ pGlint->RamDac->RamDacType == (IBM526_RAMDAC))
+ pGlint->RefClock = 40000;
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Undefined RefClock\n");
+ return FALSE;
+ }
+ }
+ break;
+ }
+
+ if (pGlint->VGAcore) {
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+ /*
+ * Allocate a vgaHWRec
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+ }
+
+ /* Set the min pixel clock */
+ pGlint->MinClock = 16250; /* XXX Guess, need to check this */
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
+ pGlint->MinClock / 1000);
+
+ /*
+ * If the user has specified ramdac speed in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pGlint->pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ speed = pGlint->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ speed = pGlint->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ speed = pGlint->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ case 32:
+ speed = pGlint->pEnt->device->dacSpeeds[DAC_BPP32];
+ break;
+ }
+ if (speed == 0)
+ pGlint->MaxClock = pGlint->pEnt->device->dacSpeeds[0];
+ else
+ pGlint->MaxClock = speed;
+ from = X_CONFIG;
+ } else {
+ if((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_500TX)||
+ (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_MX) ||
+ (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) )
+ pGlint->MaxClock = 220000;
+ if ( (pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA) ||
+ (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA) ) {
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ case 4:
+ case 8:
+ pGlint->MaxClock = 200000;
+ break;
+ case 16:
+ pGlint->MaxClock = 100000;
+ break;
+ case 24:
+ pGlint->MaxClock = 50000;
+ break;
+ case 32:
+ pGlint->MaxClock = 50000;
+ break;
+ }
+ }
+ if ( (pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA2) ||
+ (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2) ||
+ (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) ) {
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ case 4:
+ case 8:
+ pGlint->MaxClock = 230000;
+ break;
+ case 16:
+ pGlint->MaxClock = 230000;
+ break;
+ case 24:
+ pGlint->MaxClock = 150000;
+ break;
+ case 32:
+ pGlint->MaxClock = 110000;
+ break;
+ }
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
+ pGlint->MaxClock / 1000);
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+ clockRanges = xnfalloc(sizeof(ClockRange));
+ clockRanges->next = NULL;
+ clockRanges->minClock = pGlint->MinClock;
+ clockRanges->maxClock = pGlint->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = FALSE; /* XXX check this */
+ clockRanges->doubleScanAllowed = FALSE; /* XXX check this */
+
+ /*
+ * xf86ValidateModes will check that the mode HTotal and VTotal values
+ * don't exceed the chipset's limit if pScrn->maxHValue and
+ * pScrn->maxVValue are set. Since our GLINTValidMode() already takes
+ * care of this, we don't worry about setting them here.
+ */
+
+ /* Select valid modes from those available */
+ if (pGlint->NoAccel) {
+ /*
+ * XXX Assuming min pitch 256, max <maxwidth>
+ * XXX Assuming min height 128, max <maxheight>
+ */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, 256, maxwidth,
+ pScrn->bitsPerPixel, 128, maxheight,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pGlint->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+ } else {
+ /*
+ * Minimum width 32, Maximum width <maxwidth>
+ * Minimum height 128, Maximum height <maxheight>
+ */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ GetAccelPitchValues(pScrn), 32, maxwidth,
+ pScrn->bitsPerPixel, 128, maxheight,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pGlint->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+ }
+
+ if (i == -1) {
+ GLINTFreeRec(pScrn);
+ return FALSE;
+ }
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ GLINTFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ /* Only allow a single mode for MX and TX chipsets */
+ if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_500TX) ||
+ (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_MX) ||
+ (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "GLINT TX/MX chipsets only support one modeline, using first.\n");
+ pScrn->modes->next = NULL;
+ pScrn->virtualX = pScrn->modes->HDisplay;
+ pScrn->virtualY = pScrn->modes->VDisplay;
+ pScrn->displayWidth = pScrn->virtualX;
+ if (partprod500TX[pScrn->displayWidth >> 5] == -1) {
+ i = -1;
+ do {
+ pScrn->displayWidth += 32;
+ i = partprod500TX[pScrn->displayWidth >> 5];
+ } while (i == -1);
+ }
+ pGlint->realMXWidth = pScrn->displayWidth;
+ }
+
+ switch (pGlint->Chipset)
+ { /* Now we know displaywidth, so set linepitch data */
+ case PCI_VENDOR_TI_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
+ case PCI_VENDOR_TI_CHIP_PERMEDIA:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
+ pGlint->pprod = partprodPermedia[pScrn->displayWidth >> 5];
+ pGlint->bppalign = bppand[(pScrn->bitsPerPixel>>3)-1];
+ break;
+ case PCI_VENDOR_3DLABS_CHIP_500TX:
+ case PCI_VENDOR_3DLABS_CHIP_MX:
+ case PCI_VENDOR_3DLABS_CHIP_GAMMA:
+ pGlint->pprod = partprod500TX[pScrn->displayWidth >> 5];
+ pGlint->bppalign = 0;
+ break;
+ }
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ mod = "xf1bpp";
+ break;
+ case 4:
+ mod = "xf4bpp";
+ break;
+ case 8:
+ mod = "cfb";
+ break;
+ case 16:
+ mod = "cfb16";
+ break;
+ case 24:
+ if (pix24bpp == 24)
+ mod = "cfb24";
+ else
+ mod = "xf24_32bpp";
+ break;
+ case 32:
+ if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
+ mod = "xf8_32bpp";
+ } else {
+ mod = "cfb32";
+ }
+ break;
+ }
+ if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ GLINTFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Load XAA if needed */
+ if (!pGlint->NoAccel) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ GLINTFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ /* Load DDC */
+ if (!xf86LoadSubModule(pScrn, "ddc")) {
+ GLINTFreeRec(pScrn);
+ return FALSE;
+ }
+ /* Load I2C if needed */
+ if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2) ||
+ (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) ||
+ (pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA2)) {
+ if (xf86LoadSubModule(pScrn, "i2c")) {
+ I2CBusPtr pBus;
+
+ if ((pBus = xf86CreateI2CBusRec())) {
+ pBus->BusName = "DDC";
+ pBus->scrnIndex = pScrn->scrnIndex;
+ pBus->I2CUDelay = Permedia2I2CUDelay;
+ pBus->I2CPutBits = Permedia2I2CPutBits;
+ pBus->I2CGetBits = Permedia2I2CGetBits;
+ pBus->DriverPrivate.ptr = pGlint;
+ if (!xf86I2CBusInit(pBus)) {
+ xf86DestroyI2CBusRec(pBus, TRUE, TRUE);
+ } else
+ pGlint->DDCBus = pBus;
+ }
+
+ if ((pBus = xf86CreateI2CBusRec())) {
+ pBus->BusName = "Video";
+ pBus->scrnIndex = pScrn->scrnIndex;
+ pBus->I2CUDelay = Permedia2I2CUDelay;
+ pBus->I2CPutBits = Permedia2I2CPutBits;
+ pBus->I2CGetBits = Permedia2I2CGetBits;
+ pBus->DriverPrivate.ptr = pGlint;
+ if (!xf86I2CBusInit(pBus)) {
+ xf86DestroyI2CBusRec(pBus, TRUE, TRUE);
+ } else
+ pGlint->VSBus = pBus;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Map the framebuffer and MMIO memory.
+ */
+
+static Bool
+GLINTMapMem(ScrnInfoPtr pScrn)
+{
+ GLINTPtr pGlint;
+
+ pGlint = GLINTPTR(pScrn);
+
+ /*
+ * Map IO registers to virtual address space
+ */
+ if (pGlint->PciTagGeometry)
+ pGlint->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pGlint->PciTagGeometry, pGlint->IOAddress, 0x20000);
+ else
+ pGlint->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pGlint->PciTag, pGlint->IOAddress, 0x20000);
+
+ if ( (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) &&
+ (pGlint->numMXDevices == 2) ) {
+ pGlint->SecondaryAddress = pGlint->IOAddress;
+ pGlint->SecondaryBase = pGlint->IOBase+0x10000;
+ }
+ else {
+ pGlint->SecondaryAddress = pGlint->IOAddress;
+ pGlint->SecondaryBase = pGlint->IOBase;
+ }
+
+ if (pGlint->IOBase == NULL)
+ return FALSE;
+
+ if (pGlint->FbMapSize != 0) {
+ pGlint->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pGlint->PciTag,
+ pGlint->FbAddress,
+ pGlint->FbMapSize);
+ if (pGlint->FbBase == NULL)
+ return FALSE;
+ }
+
+ /* Due to bugs in the Glint Delta/Permedia/500TX chips we need to do this */
+ /* Bizarre, but it works. */
+ if ((pGlint->Chipset != PCI_VENDOR_TI_CHIP_PERMEDIA2) &&
+ (pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_PERMEDIA2) &&
+ (pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V)) {
+ if (pGlint->PciTag) {
+ unsigned long temp, temp2;
+
+ /*
+ * and now for the magic.
+ * read old value
+ * write fffffffff
+ * read value
+ * write old value
+ */
+ if (pGlint->PciTagGeometry) {
+ temp = pciReadLong(pGlint->PciTagGeometry, 0x10);
+ pciWriteLong(pGlint->PciTagGeometry, 0x10, 0xffffffff);
+ temp2 = pciReadLong(pGlint->PciTagGeometry, 0x10);
+ pciWriteLong(pGlint->PciTagGeometry, 0x10, temp & 0xfffffff0);
+ }
+
+ temp = pciReadLong(pGlint->PciTag, 0x10);
+ pciWriteLong(pGlint->PciTag, 0x10, 0xffffffff);
+ temp2 = pciReadLong(pGlint->PciTag, 0x10);
+ pciWriteLong(pGlint->PciTag, 0x10, temp);
+
+ temp = pciReadLong(pGlint->PciTag, 0x14);
+ pciWriteLong(pGlint->PciTag, 0x14, 0xffffffff);
+ temp2 = pciReadLong(pGlint->PciTag, 0x14);
+ pciWriteLong(pGlint->PciTag, 0x14, temp);
+
+ temp = pciReadLong(pGlint->PciTag, 0x18);
+ pciWriteLong(pGlint->PciTag, 0x18, 0xffffffff);
+ temp2 = pciReadLong(pGlint->PciTag, 0x18);
+ pciWriteLong(pGlint->PciTag, 0x18, temp);
+
+ temp = pciReadLong(pGlint->PciTag, 0x1c);
+ pciWriteLong(pGlint->PciTag, 0x1c, 0xffffffff);
+ temp2 = pciReadLong(pGlint->PciTag, 0x1c);
+ pciWriteLong(pGlint->PciTag, 0x1c, temp);
+
+ temp = pciReadLong(pGlint->PciTag, 0x20);
+ pciWriteLong(pGlint->PciTag, 0x20, 0xffffffff);
+ temp2 = pciReadLong(pGlint->PciTag, 0x20);
+ pciWriteLong(pGlint->PciTag, 0x20, temp);
+ }
+ }
+ return TRUE;
+}
+
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+GLINTUnmapMem(ScrnInfoPtr pScrn)
+{
+ GLINTPtr pGlint;
+
+ pGlint = GLINTPTR(pScrn);
+
+ /*
+ * Unmap IO registers to virtual address space
+ */
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pGlint->IOBase, 0x20000);
+ pGlint->IOBase = NULL;
+
+ if (pGlint->FbBase != NULL)
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pGlint->FbBase, pGlint->FbMapSize);
+ pGlint->FbBase = NULL;
+ return TRUE;
+}
+
+
+/*
+ * This function saves the video state.
+ */
+static void
+GLINTSave(ScrnInfoPtr pScrn)
+{
+ GLINTPtr pGlint;
+ GLINTRegPtr glintReg;
+ RamDacHWRecPtr pRAMDAC;
+ RamDacRegRecPtr RAMDACreg;
+
+ pGlint = GLINTPTR(pScrn);
+ pRAMDAC = RAMDACHWPTR(pScrn);
+ glintReg = &pGlint->SavedReg;
+ RAMDACreg = &pRAMDAC->SavedReg;
+ if (pGlint->VGAcore) {
+ vgaRegPtr vgaReg;
+ vgaReg = &VGAHWPTR(pScrn)->SavedReg;
+ if (xf86IsPrimaryPci(pGlint->PciInfo)) {
+ vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_FONTS);
+ } else {
+ vgaHWSave(pScrn, vgaReg, VGA_SR_MODE);
+ }
+ }
+
+ switch (pGlint->Chipset)
+ {
+ case PCI_VENDOR_TI_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
+ Permedia2Save(pScrn, glintReg);
+ break;
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
+ Permedia2VSave(pScrn, glintReg);
+ break;
+ case PCI_VENDOR_TI_CHIP_PERMEDIA:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
+ PermediaSave(pScrn, glintReg);
+ (*pGlint->RamDac->Save)(pScrn, pGlint->RamDacRec, RAMDACreg);
+ break;
+ case PCI_VENDOR_3DLABS_CHIP_500TX:
+ case PCI_VENDOR_3DLABS_CHIP_MX:
+ case PCI_VENDOR_3DLABS_CHIP_GAMMA:
+ if ( (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) &&
+ (pGlint->numMXDevices == 2) ) {
+ DualMXSave(pScrn, glintReg);
+ }
+ else {
+ TXSave(pScrn, glintReg);
+ }
+ (*pGlint->RamDac->Save)(pScrn, pGlint->RamDacRec, RAMDACreg);
+ break;
+ }
+}
+
+
+/*
+ * Initialise a new mode. This is currently still using the old
+ * "initialise struct, restore/write struct to HW" model. That could
+ * be changed.
+ */
+
+static Bool
+GLINTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ int ret = -1;
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ GLINTRegPtr glintReg;
+ RamDacHWRecPtr pRAMDAC = RAMDACHWPTR(pScrn);
+ RamDacRegRecPtr RAMDACreg;
+ int bytesPerPixel, realMXWidthBytes, inputXSpanBytes;
+ CARD32 glintApSize, postMultiply, productEnable, use16xProduct, inputXSpan;
+ CARD32 binaryEval, value;
+
+ if (pGlint->VGAcore) {
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaHWUnlock(hwp);
+
+ /* Initialise the ModeReg values */
+ if (!vgaHWInit(pScrn, mode))
+ return FALSE;
+ }
+
+ pScrn->vtSema = TRUE;
+
+ switch (pGlint->Chipset) {
+ case PCI_VENDOR_TI_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
+ ret = Permedia2Init(pScrn, mode);
+ break;
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
+ ret = Permedia2VInit(pScrn, mode);
+ break;
+ case PCI_VENDOR_TI_CHIP_PERMEDIA:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
+ ret = PermediaInit(pScrn, mode);
+ break;
+ case PCI_VENDOR_3DLABS_CHIP_500TX:
+ case PCI_VENDOR_3DLABS_CHIP_MX:
+ case PCI_VENDOR_3DLABS_CHIP_GAMMA:
+ if ( (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) &&
+ (pGlint->numMXDevices == 2) ) {
+ ret = DualMXInit(pScrn, mode);
+ }
+ else {
+ ret = TXInit(pScrn, mode);
+ }
+ break;
+ }
+
+ if (!ret)
+ return FALSE;
+
+ /* Program the registers */
+ if (pGlint->VGAcore) {
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &hwp->ModeReg;
+ vgaHWProtect(pScrn, TRUE);
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+ }
+
+ glintReg = &pGlint->ModeReg;
+ RAMDACreg = &pRAMDAC->ModeReg;
+
+ switch (pGlint->Chipset) {
+ case PCI_VENDOR_TI_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
+ Permedia2Restore(pScrn, glintReg);
+ break;
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
+ Permedia2VRestore(pScrn, glintReg);
+ break;
+ case PCI_VENDOR_TI_CHIP_PERMEDIA:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
+ PermediaRestore(pScrn, glintReg);
+ (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg);
+ break;
+ case PCI_VENDOR_3DLABS_CHIP_500TX:
+ case PCI_VENDOR_3DLABS_CHIP_MX:
+ case PCI_VENDOR_3DLABS_CHIP_GAMMA:
+ if ( (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) &&
+ (pGlint->numMXDevices == 2) ) {
+ DualMXRestore(pScrn, glintReg);
+ }
+ else {
+ TXRestore(pScrn, glintReg);
+ }
+ (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg);
+ break;
+ }
+
+ if ( (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) &&
+ (pGlint->numMXDevices == 2) ) {
+
+ /* setup multi glint framebuffer aperture */
+
+ bytesPerPixel = (pScrn->bitsPerPixel >> 3);
+ realMXWidthBytes = pGlint->realMXWidth * bytesPerPixel;
+
+ /* compute Input X Span field */
+ binaryEval = ((realMXWidthBytes << 1) - 1);
+ if (binaryEval & (8 << 10)) { /* 8K */
+ inputXSpan = 3;
+ inputXSpanBytes = 8 * 1024;
+ }
+ else if (binaryEval & (4 << 10)) { /* 4K */
+ inputXSpan = 2;
+ inputXSpanBytes = 4 * 1024;
+ }
+ else if (binaryEval & (2 << 10)) { /* 2K */
+ inputXSpan = 1;
+ inputXSpanBytes = 2 * 1024;
+ }
+ else { /* 1K */
+ inputXSpan = 0;
+ inputXSpanBytes = 1024;
+ }
+
+ /* set the MULTI width for software rendering */
+ pScrn->displayWidth = inputXSpanBytes / bytesPerPixel;
+
+ /* compute post multiply */
+ binaryEval = (realMXWidthBytes >> 3);
+ postMultiply = 0;
+ while ((postMultiply < 5) && !(binaryEval & 1)) {
+ postMultiply++;
+ binaryEval >>= 1;
+ }
+ postMultiply <<= 7;
+
+ /* compute product enable fields */
+ if (binaryEval & ~0x1f) { /* too big */
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "GLINTModeInit: width (%d) too big\n",
+ pScrn->displayWidth);
+ return FALSE;
+ }
+ if ((binaryEval & 0x12) == 0x12) { /* clash between x2 and x16 */
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "GLINTModeInit: width (%d) is mult 18, not supported\n",
+ pScrn->displayWidth);
+ return FALSE;
+ }
+ if (binaryEval & 0x10) {
+ productEnable = (((binaryEval & 0xf) | 0x2) << 3);
+ use16xProduct = (1 << 2);
+ }
+ else {
+ productEnable = ((binaryEval & 0xf) << 3);
+ use16xProduct = 0;
+ }
+
+ /* compute GLINT Aperture Size field */
+ binaryEval = ((pGlint->MXFbSize << 1) - 1);
+ if (binaryEval & (32 << 20)) { /* 32M */
+ glintApSize = 3 << 10;
+ }
+ else if (binaryEval & (16 << 20)) { /* 16M */
+ glintApSize = 2 << 10;
+ }
+ else if (binaryEval & (8 << 20)) { /* 8M */
+ glintApSize = 1 << 10;
+ }
+ else { /* 4M */
+ glintApSize = 0 << 10;
+ }
+
+ /*
+ * Setup HW
+ *
+ * Note: The order of discovery for the MX devices is dependent
+ * on which way the resource allocation code decides to scan the
+ * bus. This setup assumes the first MX found owns the even
+ * scanlines. Should the implementation change an scan the bus
+ * in the opposite direction, then simple invert the indices for
+ * MXPciInfo below. If this is setup wrong, the bug will appear
+ * as incorrect scanline interleaving when software rendering.
+ */
+ value = ( glintApSize |
+ postMultiply |
+ productEnable |
+ use16xProduct |
+ inputXSpan );
+ GLINT_SLOW_WRITE_REG(value, GMultGLINTAperture);
+ value = pGlint->MXPciInfo[0]->memBase[2] & 0xFF800000;
+ GLINT_SLOW_WRITE_REG(value, GMultGLINT1);
+ value = pGlint->MXPciInfo[1]->memBase[2] & 0xFF800000;
+ GLINT_SLOW_WRITE_REG(value, GMultGLINT2);
+ }
+
+ if (pGlint->VGAcore) {
+ vgaHWProtect(pScrn, FALSE);
+ }
+
+ return TRUE;
+}
+
+/*
+ * Restore the initial (text) mode.
+ */
+static void
+GLINTRestore(ScrnInfoPtr pScrn)
+{
+ GLINTPtr pGlint;
+ GLINTRegPtr glintReg;
+ RamDacHWRecPtr pRAMDAC;
+ RamDacRegRecPtr RAMDACreg;
+
+ pGlint = GLINTPTR(pScrn);
+ pRAMDAC = RAMDACHWPTR(pScrn);
+ glintReg = &pGlint->SavedReg;
+ RAMDACreg = &pRAMDAC->SavedReg;
+
+ if (pGlint->VGAcore) {
+ vgaHWProtect(pScrn, TRUE);
+ }
+
+ switch (pGlint->Chipset) {
+ case PCI_VENDOR_TI_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
+ Permedia2VideoReset(pScrn);
+ Permedia2Restore(pScrn, glintReg);
+ break;
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
+ Permedia2VideoReset(pScrn);
+ Permedia2VRestore(pScrn, glintReg);
+ break;
+ case PCI_VENDOR_TI_CHIP_PERMEDIA:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
+ PermediaRestore(pScrn, glintReg);
+ (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg);
+ break;
+ case PCI_VENDOR_3DLABS_CHIP_500TX:
+ case PCI_VENDOR_3DLABS_CHIP_MX:
+ case PCI_VENDOR_3DLABS_CHIP_GAMMA:
+ if ( (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) &&
+ (pGlint->numMXDevices == 2) ) {
+ DualMXRestore(pScrn, glintReg);
+ }
+ else {
+ TXRestore(pScrn, glintReg);
+ }
+ (*pGlint->RamDac->Restore)(pScrn, pGlint->RamDacRec, RAMDACreg);
+ break;
+ }
+
+ if (pGlint->VGAcore) {
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &hwp->SavedReg;
+ if (xf86IsPrimaryPci(pGlint->PciInfo)) {
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_FONTS);
+ } else {
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+ }
+ vgaHWProtect(pScrn, FALSE);
+ }
+}
+
+
+/* Mandatory */
+
+/* This gets called at the start of each server generation */
+
+static Bool
+GLINTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int ret;
+ VisualPtr visual;
+
+ /* Map the GLINT memory and MMIO areas */
+ if (!GLINTMapMem(pScrn))
+ return FALSE;
+
+ /* Initialize the MMIO vgahw functions */
+ if (pGlint->VGAcore) {
+ vgaHWPtr hwp;
+ hwp = VGAHWPTR(pScrn);
+ if (xf86IsPrimaryPci(pGlint->PciInfo)) {
+ hwp->MapSize = 0x10000; /* Standard 64k VGA window */
+ if (!vgaHWMapMem(pScrn))
+ return FALSE;
+ }
+ vgaHWSetMmioFuncs(hwp, pGlint->IOBase, 0x6000);
+ vgaHWGetIOBase(hwp);
+ }
+
+ /* Save the current state */
+ GLINTSave(pScrn);
+
+ /* DDC */
+ {
+ xf86MonPtr pMon = NULL;
+
+ if (pGlint->DDCBus)
+ pMon = xf86DoEDID_DDC2(pScrn->scrnIndex, pGlint->DDCBus);
+
+ if (!pMon)
+ /* Try DDC1 */;
+
+ xf86PrintEDID(pMon);
+ }
+ /* Initialise the first mode */
+ if ( !(GLINTModeInit(pScrn, pScrn->currentMode))) {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid mode\n");
+ return FALSE;
+ }
+
+ /* Darken the screen for aesthetic reasons and set the viewport */
+ GLINTSaveScreen(pScreen, FALSE);
+ GLINTAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ /*
+ * For bpp > 8, the default visuals are not acceptable because we only
+ * support TrueColor and not DirectColor. To deal with this, call
+ * miSetVisualTypes for each visual supported.
+ */
+
+ if((pScrn->overlayFlags & OVERLAY_8_32_PLANAR) &&
+ (pScrn->bitsPerPixel == 32)) {
+ if (!miSetVisualTypes(8, PseudoColorMask | GrayScaleMask,
+ pScrn->rgbBits, PseudoColor))
+ return FALSE;
+ if (!miSetVisualTypes(24, TrueColorMask, pScrn->rgbBits, TrueColor))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+#ifdef XF86DRI
+ /*
+ * Setup DRI after visuals have been established, but before cfbScreenInit
+ * is called. cfbScreenInit will eventually call into the drivers
+ * InitGLXVisuals call back.
+ */
+ if (!pGlint->NoAccel && pGlint->HWCursor) {
+ pGlint->directRenderingEnabled = GLINTDRIScreenInit(pScreen);
+ } else {
+ pGlint->directRenderingEnabled = FALSE;
+ }
+#endif
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ ret = xf1bppScreenInit(pScreen, pGlint->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 4:
+ ret = xf4bppScreenInit(pScreen, pGlint->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 8:
+ ret = cfbScreenInit(pScreen, pGlint->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 16:
+ ret = cfb16ScreenInit(pScreen, pGlint->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 24:
+ if (pix24bpp == 24)
+ ret = cfb24ScreenInit(pScreen, pGlint->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ else
+ ret = cfb24_32ScreenInit(pScreen, pGlint->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 32:
+ if(pScrn->overlayFlags & OVERLAY_8_32_PLANAR)
+ ret = cfb8_32ScreenInit(pScreen, pGlint->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ else
+ ret = cfb32ScreenInit(pScreen, pGlint->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in GLINTScrnInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ if (!ret)
+ return FALSE;
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ if (pScrn->bitsPerPixel > 8) {
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ if (!pGlint->NoAccel) {
+ switch (pGlint->Chipset)
+ {
+ case PCI_VENDOR_TI_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
+ Permedia2AccelInit(pScreen);
+ break;
+ case PCI_VENDOR_TI_CHIP_PERMEDIA:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
+ PermediaAccelInit(pScreen);
+ break;
+ case PCI_VENDOR_3DLABS_CHIP_500TX:
+ case PCI_VENDOR_3DLABS_CHIP_MX:
+ case PCI_VENDOR_3DLABS_CHIP_GAMMA:
+ if ( (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_GAMMA) &&
+ (pGlint->numMXDevices == 2) ) {
+ DualMXAccelInit(pScreen);
+ }
+ else {
+ TXAccelInit(pScreen);
+ }
+ break;
+ }
+ }
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ /* Initialise cursor functions */
+ if (pGlint->HWCursor) {
+ if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2) ||
+ (pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA2))
+ Permedia2HWCursorInit(pScreen);
+ else
+ if (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V)
+ Permedia2vHWCursorInit(pScreen);
+ else
+ if ( ((pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_PERMEDIA2) &&
+ (pGlint->Chipset != PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) &&
+ (pGlint->Chipset != PCI_VENDOR_TI_CHIP_PERMEDIA2)) &&
+ ((pGlint->RamDac->RamDacType == (IBM526DB_RAMDAC)) ||
+ (pGlint->RamDac->RamDacType == (IBM526_RAMDAC)) ||
+ (pGlint->RamDac->RamDacType == (IBM640_RAMDAC))) )
+ glintIBMHWCursorInit(pScreen);
+ else
+ if (pGlint->RamDac->RamDacType == (TI3030_RAMDAC))
+ glintTIHWCursorInit(pScreen);
+ }
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ if ((pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V) ||
+ (pGlint->Chipset == PCI_VENDOR_3DLABS_CHIP_PERMEDIA2) ||
+ (pGlint->Chipset == PCI_VENDOR_TI_CHIP_PERMEDIA2)) {
+ if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits,
+ (pScrn->depth == 16) ? Permedia2LoadPalette16:Permedia2LoadPalette,
+ NULL,
+ CMAP_RELOAD_ON_MODE_SWITCH |
+ ((pScrn->overlayFlags & OVERLAY_8_32_PLANAR)
+ ? 0 : CMAP_PALETTED_TRUECOLOR)))
+ return FALSE;
+ } else {
+ if (pScrn->rgbBits == 10) {
+ if (!RamDacHandleColormaps(pScreen, 1024, pScrn->rgbBits,
+ CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR))
+ return FALSE;
+ } else {
+ if (!RamDacHandleColormaps(pScreen, 256, pScrn->rgbBits,
+ CMAP_RELOAD_ON_MODE_SWITCH |
+ ((pScrn->overlayFlags & OVERLAY_8_32_PLANAR)
+ ? 0 : CMAP_PALETTED_TRUECOLOR)))
+ return FALSE;
+ }
+ }
+
+ if((pScrn->overlayFlags & OVERLAY_8_32_PLANAR) &&
+ (pScrn->bitsPerPixel == 32)) {
+ if(!xf86Overlay8Plus32Init(pScreen))
+ return FALSE;
+ }
+
+#ifdef DPMSExtension
+ xf86DPMSInit(pScreen, (DPMSSetProcPtr)GLINTDisplayPowerManagementSet, 0);
+#endif
+
+#ifdef XF86DRI
+ if (pGlint->directRenderingEnabled) {
+ /* Now that mi, cfb, drm and others have done their thing,
+ * complete the DRI setup.
+ */
+ pGlint->directRenderingEnabled = GLINTDRIFinishScreenInit(pScreen);
+ }
+ if (pGlint->directRenderingEnabled) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "direct rendering enabled\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "direct rendering disabled\n");
+ }
+#endif
+
+ pGlint->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = GLINTCloseScreen;
+ pScreen->SaveScreen = GLINTSaveScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ switch (pGlint->Chipset) {
+ case PCI_VENDOR_TI_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
+ Permedia2VideoInit(pScreen);
+ }
+
+#if 0
+ /* Enable the screen */
+ GLINTSaveScreen(pScreen, TRUE);
+#endif
+
+ /* Done */
+ return TRUE;
+}
+
+/* Usually mandatory */
+static Bool
+GLINTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return GLINTModeInit(xf86Screens[scrnIndex], mode);
+}
+
+
+/*
+ * This function is used to initialize the Start Address - the first
+ * displayed location in the video memory.
+ */
+/* Usually mandatory */
+static void
+GLINTAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn;
+ CARD32 base;
+ GLINTPtr pGlint;
+
+ pScrn = xf86Screens[scrnIndex];
+ pGlint = GLINTPTR(pScrn);
+ if (pGlint->VGAcore) {
+ vgaHWPtr hwp;
+ hwp = VGAHWPTR(pScrn);
+ }
+
+ base = ((y * pScrn->displayWidth + x) >> 1) >> pGlint->BppShift;
+ if (pScrn->bitsPerPixel == 24) base *= 3;
+
+ switch (pGlint->Chipset)
+ {
+ case PCI_VENDOR_TI_CHIP_PERMEDIA:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
+ case PCI_VENDOR_TI_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
+ GLINT_SLOW_WRITE_REG(base, PMScreenBase);
+ break;
+ }
+}
+
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ *
+ * We may wish to unmap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static Bool
+GLINTEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ /* Should we re-save the text mode on each VT enter? */
+ if (!GLINTModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * This is called when VT switching away from the X server. Its job is
+ * to restore the previous (text) mode.
+ *
+ * We may wish to remap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static void
+GLINTLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINTRestore(pScrn);
+ if (pGlint->VGAcore)
+ vgaHWLock(VGAHWPTR(pScrn));
+}
+
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode. It should really also unmap the video memory too.
+ */
+
+/* Mandatory */
+static Bool
+GLINTCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+#ifdef XF86DRI
+ if (pGlint->directRenderingEnabled) {
+ GLINTDRICloseScreen(pScreen);
+ }
+#endif
+
+ switch (pGlint->Chipset) {
+ case PCI_VENDOR_TI_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
+ Permedia2VideoUninit(xf86Screens[scrnIndex]);
+ }
+
+ if (pScrn->vtSema) {
+ GLINTRestore(pScrn);
+ if (pGlint->VGAcore)
+ vgaHWLock(VGAHWPTR(pScrn));
+ GLINTUnmapMem(pScrn);
+ }
+ if(pGlint->AccelInfoRec)
+ XAADestroyInfoRec(pGlint->AccelInfoRec);
+ if(pGlint->CursorInfoRec)
+ xf86DestroyCursorInfoRec(pGlint->CursorInfoRec);
+ pScrn->vtSema = FALSE;
+
+ pScreen->CloseScreen = pGlint->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+
+/* Free up any per-generation data structures */
+
+/* Optional */
+static void
+GLINTFreeScreen(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ if (pGlint->VGAcore)
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ if (pGlint->RamDacRec)
+ RamDacFreeRec(xf86Screens[scrnIndex]);
+ GLINTFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+/* Optional */
+static int
+GLINTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ if (mode->Flags & V_INTERLACE)
+ return(MODE_NO_INTERLACE);
+
+ if (pScrn->bitsPerPixel == 24) {
+ /* A restriction on the PM2 where a black strip on the left hand
+ * side appears if not aligned properly */
+ switch (pGlint->Chipset) {
+ case PCI_VENDOR_TI_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
+ if (mode->HDisplay % 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "HDisplay %d not divisible by 8, fixing...\n", mode->HDisplay);
+ mode->HDisplay -= (mode->HDisplay % 8);
+ }
+
+ if (mode->HSyncStart % 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "HSyncStart %d not divisible by 8, fixing...\n", mode->HSyncStart);
+ mode->HSyncStart -= (mode->HSyncStart % 8);
+ }
+
+ if (mode->HSyncEnd % 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "HSyncEnd %d not divisible by 8, fixing...\n", mode->HSyncEnd);
+ mode->HSyncEnd -= (mode->HSyncEnd % 8);
+ }
+
+ if (mode->HTotal % 8) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "HTotal %d not divisible by 8, fixing...\n", mode->HTotal);
+ mode->HTotal -= (mode->HTotal % 8);
+ }
+ break;
+ }
+ }
+
+ return(MODE_OK);
+}
+
+/* Do screen blanking */
+
+/* Mandatory */
+static Bool
+GLINTSaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ CARD32 temp;
+
+ switch (pGlint->Chipset) {
+ case PCI_VENDOR_TI_CHIP_PERMEDIA2:
+ case PCI_VENDOR_TI_CHIP_PERMEDIA:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA:
+ temp = GLINT_READ_REG(PMVideoControl);
+ if (unblank) temp |= 1;
+ else temp &= 0xFFFFFFFE;
+ GLINT_WRITE_REG(temp, PMVideoControl);
+ break;
+ case PCI_VENDOR_3DLABS_CHIP_500TX:
+ case PCI_VENDOR_3DLABS_CHIP_MX:
+ break;
+ }
+
+ return TRUE;
+}
+
+#ifdef DEBUG
+void
+GLINT_VERB_WRITE_REG(GLINTPtr pGlint, CARD32 v, int r, char *file, int line)
+{
+ if (xf86GetVerbosity() > 2)
+ ErrorF("[0x%04x] <- 0x%08x (%s, %d)\n", r, v, file, line);
+ *(volatile CARD32 *)((char *) pGlint->IOBase + r) = v;
+}
+
+CARD32
+GLINT_VERB_READ_REG(GLINTPtr pGlint, CARD32 r, char *file, int line)
+{
+ CARD32 v = *(volatile CARD32 *)((char *) pGlint->IOBase + r);
+
+ if (xf86GetVerbosity() > 2)
+ ErrorF("[0x%04x] -> 0x%08x (%s, %d)\n", r, v, file, line);
+ return v;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h
new file mode 100644
index 000000000..08ba5a9a1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h
@@ -0,0 +1,1232 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h,v 1.14 1999/07/04 06:39:00 dawes Exp $ */
+
+/*
+ * glint register file
+ *
+ * Copyright by Stefan Dirsch, Dirk Hohndel, Alan Hourihane
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ * Dirk Hohndel, <hohndel@suse.de>
+ * Stefan Dirsch, <sndirsch@suse.de>
+ * Simon P., <sim@suse.de>
+ *
+ * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and
+ * Siemens Nixdorf Informationssysteme
+ *
+ */
+
+#ifndef _GLINTREG_H_
+#define _GLINTREG_H_
+
+/**********************************************
+* GLINT 500TX Configuration Region Registers *
+***********************************************/
+
+/* Device Identification */
+#define CFGVendorId 0x0000
+#define PCI_VENDOR_3DLABS 0x3D3D
+#define PCI_VENDOR_TI 0x104C
+#define CFGDeviceId 0x0002
+
+#define PCI_CHIP_3DLABS_300SX 0x01
+#define PCI_CHIP_3DLABS_500TX 0x02
+#define PCI_CHIP_3DLABS_DELTA 0x03
+#define PCI_CHIP_3DLABS_PERMEDIA 0x04
+#define PCI_CHIP_3DLABS_MX 0x06
+#define PCI_CHIP_3DLABS_PERMEDIA2 0x07
+#define PCI_CHIP_TI_PERMEDIA 0x3d04
+
+#define CFGRevisionId 0x08
+#define CFGClassCode 0x09
+#define CFGHeaderType 0x0E
+
+/* Device Control/Status */
+#define CFGCommand 0x04
+#define CFGStatus 0x06
+
+/* Miscellaneous Functions */
+#define CFGBist 0x0f
+#define CFGLatTimer 0x0d
+#define CFGCacheLine 0x0c
+#define CFGMaxLat 0x3f
+#define CFGMinGrant 0x3e
+#define CFGIntPin 0x3d
+#define CFGIntLine 0x3c
+
+/* Base Adresses */
+#define CFGBaseAddr0 0x10
+#define CFGBaseAddr1 0x14
+#define CFGBaseAddr2 0x18
+#define CFGBaseAddr3 0x1C
+#define CFGBaseAddr4 0x20
+#define CFGRomAddr 0x30
+
+
+
+/**********************************
+ * GLINT 500TX Region 0 Registers *
+ **********************************/
+
+/* Control Status Registers */
+#define ResetStatus 0x0000
+#define IntEnable 0x0008
+#define IntFlags 0x0010
+#define InFIFOSpace 0x0018
+#define OutFIFOWords 0x0020
+#define DMAAddress 0x0028
+#define DMACount 0x0030
+#define ErrorFlags 0x0038
+#define VClkCtl 0x0040
+#define TestRegister 0x0048
+#define Aperture0 0x0050
+#define Aperture1 0x0058
+#define DMAControl 0x0060
+#define FIFODis 0x0068
+
+/* GLINT PerMedia Region 0 additional Registers */
+#define ChipConfig 0x0070
+#define SCLK_SEL_MASK (3 << 10)
+#define SCLK_SEL_MCLK_HALF (3 << 10)
+#define ByDMAControl 0x00D8
+
+/* GLINT 500TX LocalBuffer Registers */
+#define LBMemoryCtl 0x1000
+#define LBNumBanksMask 0x00000001
+#define LBNumBanks1 (0)
+#define LBNumBanks2 (1)
+#define LBPageSizeMask 0x00000006
+#define LBPageSize256 (0<<1)
+#define LBPageSize512 (1<<1)
+#define LBPageSize1024 (2<<1)
+#define LBPageSize2048 (3<<1)
+#define LBRASCASLowMask 0x00000018
+#define LBRASCASLow2 (0<<3)
+#define LBRASCASLow3 (1<<3)
+#define LBRASCASLow4 (2<<3)
+#define LBRASCASLow5 (3<<3)
+#define LBRASPrechargeMask 0x00000060
+#define LBRASPrecharge2 (0<<5)
+#define LBRASPrecharge3 (1<<5)
+#define LBRASPrecharge4 (2<<5)
+#define LBRASPrecharge5 (3<<5)
+#define LBCASLowMask 0x00000180
+#define LBCASLow1 (0<<7)
+#define LBCASLow2 (1<<7)
+#define LBCASLow3 (2<<7)
+#define LBCASLow4 (3<<7)
+#define LBPageModeMask 0x00000200
+#define LBPageModeEnabled (0<<9)
+#define LBPageModeDisabled (1<<9)
+#define LBRefreshCountMask 0x0003fc00
+#define LBRefreshCountShift 10
+
+#define LBMemoryEDO 0x1008
+#define LBEDOMask 0x00000001
+#define LBEDODisabled (0)
+#define LBEDOEnabled (1)
+#define LBEDOBankSizeMask 0x0000000e
+#define LBEDOBankSizeDiabled (0<<1)
+#define LBEDOBankSize256K (1<<1)
+#define LBEDOBankSize512K (2<<1)
+#define LBEDOBankSize1M (3<<1)
+#define LBEDOBankSize2M (4<<1)
+#define LBEDOBankSize4M (5<<1)
+#define LBEDOBankSize8M (6<<1)
+#define LBEDOBankSize16M (7<<1)
+#define LBTwoPageDetectorMask 0x00000010
+#define LBSinglePageDetector (0<<4)
+#define LBTwoPageDetector (1<<4)
+
+/* GLINT PerMedia Memory Control Registers */
+#define PMReboot 0x1000
+#define PMRomControl 0x1040
+#define PMBootAddress 0x1080
+#define PMMemConfig 0x10C0
+ #define RowCharge8 1 << 10
+ #define TimeRCD8 1 << 7
+ #define TimeRC8 0x6 << 3
+ #define TimeRP8 1
+ #define CAS3Latency8 0 << 16
+ #define BootAdress8 0x10
+ #define NumberBanks8 0x3 << 29
+ #define RefreshCount8 0x41 << 21
+ #define TimeRASMin8 1 << 13
+ #define DeadCycle8 1 << 17
+ #define BankDelay8 0 << 18
+ #define Burst1Cycle8 1 << 31
+ #define SDRAM8 0 << 4
+
+ #define RowCharge6 1 << 10
+ #define TimeRCD6 1 << 7
+ #define TimeRC6 0x6 << 3
+ #define TimeRP6 0x2
+ #define CAS3Latency6 1 << 16
+ #define BootAdress6 0x60
+ #define NumberBanks6 0x2 << 29
+ #define RefreshCount6 0x41 << 21
+ #define TimeRASMin6 1 << 13
+ #define DeadCycle6 1 << 17
+ #define BankDelay6 0 << 18
+ #define Burst1Cycle6 1 << 31
+ #define SDRAM6 0 << 4
+
+ #define RowCharge4 0 << 10
+ #define TimeRCD4 0 << 7
+ #define TimeRC4 0x4 << 3
+ #define TimeRP4 1
+ #define CAS3Latency4 0 << 16
+ #define BootAdress4 0x10
+ #define NumberBanks4 1 << 29
+ #define RefreshCount4 0x30 << 21
+ #define TimeRASMin4 1 << 13
+ #define DeadCycle4 0 << 17
+ #define BankDelay4 0 << 18
+ #define Burst1Cycle4 1 << 31
+ #define SDRAM4 0 << 4
+
+/* Permedia 2 Control */
+#define MemControl 0x1040
+
+#define PMBypassWriteMask 0x1100
+#define PMFramebufferWriteMask 0x1140
+#define PMCount 0x1180
+
+/* Framebuffer Registers */
+#define FBMemoryCtl 0x1800
+#define FBModeSel 0x1808
+#define FBGCWrMask 0x1810
+#define FBGCColorLower 0x1818
+#define FBTXMemCtl 0x1820
+#define FBWrMaskk 0x1830
+#define FBGCColorUpper 0x1838
+
+/* Core FIFO */
+#define OutputFIFO 0x2000
+
+/* 500TX Internal Video Registers */
+#define VTGHLimit 0x3000
+#define VTGHSyncStart 0x3008
+#define VTGHSyncEnd 0x3010
+#define VTGHBlankEnd 0x3018
+#define VTGVLimit 0x3020
+#define VTGVSyncStart 0x3028
+#define VTGVSyncEnd 0x3030
+#define VTGVBlankEnd 0x3038
+#define VTGHGateStart 0x3040
+#define VTGHGateEnd 0x3048
+#define VTGVGateStart 0x3050
+#define VTGVGateEnd 0x3058
+#define VTGPolarity 0x3060
+#define VTGFrameRowAddr 0x3068
+#define VTGVLineNumber 0x3070
+#define VTGSerialClk 0x3078
+#define VTGModeCtl 0x3080
+
+/* Permedia Video Control Registers */
+#define PMScreenBase 0x3000
+#define PMScreenStride 0x3008
+#define PMHTotal 0x3010
+#define PMHgEnd 0x3018
+#define PMHbEnd 0x3020
+#define PMHsStart 0x3028
+#define PMHsEnd 0x3030
+#define PMVTotal 0x3038
+#define PMVbEnd 0x3040
+#define PMVsStart 0x3048
+#define PMVsEnd 0x3050
+#define PMVideoControl 0x3058
+#define PMInterruptLine 0x3060
+#define PMDDCData 0x3068
+#define DataIn (1<<0)
+#define ClkIn (1<<1)
+#define DataOut (1<<2)
+#define ClkOut (1<<3)
+#define PMLineCount 0x3070
+#define PMFifoControl 0x3078
+
+/* Permedia 2 RAMDAC Registers */
+#define PM2DACWriteAddress 0x4000
+#define PM2DACIndexReg 0x4000
+#define PM2DACData 0x4008
+#define PM2DACReadMask 0x4010
+#define PM2DACReadAddress 0x4018
+#define PM2DACCursorColorAddress 0x4020
+#define PM2DACCursorColorData 0x4028
+#define PM2DACIndexData 0x4050
+#define PM2DACCursorData 0x4058
+#define PM2DACCursorXLsb 0x4060
+#define PM2DACCursorXMsb 0x4068
+#define PM2DACCursorYLsb 0x4070
+#define PM2DACCursorYMsb 0x4078
+#define PM2DACCursorControl 0x06
+#define PM2DACIndexCMR 0x18
+#define PM2DAC_TRUECOLOR 0x80
+#define PM2DAC_RGB 0x20
+#define PM2DAC_GRAPHICS 0x10
+#define PM2DAC_PACKED 0x09
+#define PM2DAC_8888 0x08
+#define PM2DAC_565 0x06
+#define PM2DAC_4444 0x05
+#define PM2DAC_5551 0x04
+#define PM2DAC_2321 0x03
+#define PM2DAC_2320 0x02
+#define PM2DAC_332 0x01
+#define PM2DAC_CI8 0x00
+#define PM2DACIndexMDCR 0x19
+#define PM2DACIndexPalettePage 0x1c
+#define PM2DACIndexMCR 0x1e
+#define PM2DACIndexClockAM 0x20
+#define PM2DACIndexClockAN 0x21
+#define PM2DACIndexClockAP 0x22
+#define PM2DACIndexClockBM 0x23
+#define PM2DACIndexClockBN 0x24
+#define PM2DACIndexClockBP 0x25
+#define PM2DACIndexClockCM 0x26
+#define PM2DACIndexClockCN 0x27
+#define PM2DACIndexClockCP 0x28
+#define PM2DACIndexClockStatus 0x29
+#define PM2DACIndexMemClockM 0x30
+#define PM2DACIndexMemClockN 0x31
+#define PM2DACIndexMemClockP 0x32
+#define PM2DACIndexMemClockStatus 0x33
+#define PM2DACIndexColorKeyControl 0x40
+#define PM2DACIndexColorKeyOverlay 0x41
+#define PM2DACIndexColorKeyRed 0x42
+#define PM2DACIndexColorKeyGreen 0x43
+#define PM2DACIndexColorKeyBlue 0x44
+
+/* Permedia 2V extensions */
+#define PM2VDACRDMiscControl 0x000
+#define PM2VDACRDSyncControl 0x001
+#define PM2VDACRDDACControl 0x002
+#define PM2VDACRDPixelSize 0x003
+#define PM2VDACRDColorFormat 0x004
+#define PM2VDACRDCursorMode 0x005
+#define PM2VDACRDCursorXLow 0x007
+#define PM2VDACRDCursorXHigh 0x008
+#define PM2VDACRDCursorYLow 0x009
+#define PM2VDACRDCursorYHigh 0x00A
+#define PM2VDACRDCursorHotSpotX 0x00B
+#define PM2VDACRDCursorHotSpotY 0x00C
+#define PM2VDACRDOverlayKey 0x00D
+#define PM2VDACRDPan 0x00E
+#define PM2VDACRDSense 0x00F
+#define PM2VDACRDCheckControl 0x018
+#define PM2VDACIndexClockControl 0x200
+#define PM2VDACRDDClk0PreScale 0x201
+#define PM2VDACRDDClk0FeedbackScale 0x202
+#define PM2VDACRDDClk0PostScale 0x203
+#define PM2VDACRDDClk1PreScale 0x204
+#define PM2VDACRDDClk1FeedbackScale 0x205
+#define PM2VDACRDDClk1PostScale 0x206
+#define PM2VDACRDCursorPalette 0x303
+#define PM2VDACRDCursorPattern 0x400
+#define PM2VDACIndexRegLow 0x4020
+#define PM2VDACIndexRegHigh 0x4028
+#define PM2VDACIndexData 0x4030
+#define PM2VDACRDIndexControl 0x4038
+
+/* Permedia 2 Video Streams Unit Registers */
+#define VSBIntFlag (1<<8)
+#define VSAIntFlag (1<<9)
+
+#define VSConfiguration 0x5800
+#define VS_UnitMode_ROM 0
+#define VS_UnitMode_AB8 3
+#define VS_UnitMode_Mask 7
+#define VS_GPBusMode_A (1<<3)
+#define VS_HRefPolarityA (1<<9)
+#define VS_VRefPolarityA (1<<10)
+#define VS_VActivePolarityA (1<<11)
+#define VS_UseFieldA (1<<12)
+#define VS_FieldPolarityA (1<<13)
+#define VS_FieldEdgeA (1<<14)
+#define VS_VActiveVBIA (1<<15)
+#define VS_InterlaceA (1<<16)
+#define VS_ReverseDataA (1<<17)
+#define VS_HRefPolarityB (1<<18)
+#define VS_VRefPolarityB (1<<19)
+#define VS_VActivePolarityB (1<<20)
+#define VS_UseFieldB (1<<21)
+#define VS_FieldPolarityB (1<<22)
+#define VS_FieldEdgeB (1<<23)
+#define VS_VActiveVBIB (1<<24)
+#define VS_InterlaceB (1<<25)
+#define VS_ColorSpaceB_RGB (1<<26)
+#define VS_ReverseDataB (1<<27)
+#define VS_DoubleEdgeB (1<<28)
+
+#define VSStatus 0x5808
+#define VS_FieldOne0A (1<<9)
+#define VS_FieldOne1A (1<<10)
+#define VS_FieldOne2A (1<<11)
+#define VS_InvalidInterlaceA (1<<12)
+#define VS_FieldOne0B (1<<17)
+#define VS_FieldOne1B (1<<18)
+#define VS_FieldOne2B (1<<19)
+#define VS_InvalidInterlaceB (1<<20)
+
+#define VSSerialBusControl 0x5810
+
+#define VSABase 0x5900
+#define VSA_Video (1<<0)
+#define VSA_VBI (1<<1)
+#define VSA_BufferCtl (1<<2)
+#define VSA_MirrorX (1<<7)
+#define VSA_MirrorY (1<<8)
+#define VSA_Discard_None (0<<9)
+#define VSA_Discard_FieldOne (1<<9)
+#define VSA_Discard_FieldTwo (2<<9)
+#define VSA_CombineFields (1<<11)
+#define VSA_LockToStreamB (1<<12)
+#define VSBBase 0x5A00
+#define VSB_Video (1<<0)
+#define VSB_VBI (1<<1)
+#define VSB_BufferCtl (1<<2)
+#define VSB_CombineFields (1<<3)
+#define VSB_RGBOrder (1<<11)
+#define VSB_GammaCorrect (1<<12)
+#define VSB_LockToStreamA (1<<13)
+
+#define VSControl 0x0000
+#define VSInterrupt 0x0008
+#define VSCurrentLine 0x0010
+#define VSVideoAddressHost 0x0018
+#define VSVideoAddressIndex 0x0020
+#define VSVideoAddress0 0x0028
+#define VSVideoAddress1 0x0030
+#define VSVideoAddress2 0x0038
+#define VSVideoStride 0x0040
+#define VSVideoStartLine 0x0048
+#define VSVideoEndLine 0x0050
+#define VSVideoStartData 0x0058
+#define VSVideoEndData 0x0060
+#define VSVBIAddressHost 0x0068
+#define VSVBIAddressIndex 0x0070
+#define VSVBIAddress0 0x0078
+#define VSVBIAddress1 0x0080
+#define VSVBIAddress2 0x0088
+#define VSVBIStride 0x0090
+#define VSVBIStartLine 0x0098
+#define VSVBIEndLine 0x00A0
+#define VSVBIStartData 0x00A8
+#define VSVBIEndData 0x00B0
+#define VSFifoControl 0x00B8
+
+/**********************************
+ * GLINT Delta Region 0 Registers *
+ **********************************/
+
+/* Control Status Registers */
+#define DResetStatus 0x0800
+#define DIntEnable 0x0808
+#define DIntFlags 0x0810
+#define DErrorFlags 0x0838
+#define DTestRegister 0x0848
+#define DFIFODis 0x0868
+
+
+
+/**********************************
+ * GLINT Gamma Region 0 Registers *
+ **********************************/
+
+/* Control Status Registers */
+#define GInFIFOSpace 0x0018
+#define GDMAAddress 0x0028
+#define GDMACount 0x0030
+#define GDMAControl 0x0060
+#define GOutDMA 0x0080
+#define GOutDMACount 0x0088
+#define GResetStatus 0x0800
+#define GIntEnable 0x0808
+#define GIntFlags 0x0810
+#define GErrorFlags 0x0838
+#define GTestRegister 0x0848
+#define GFIFODis 0x0868
+
+#define GChipConfig 0x0870
+#define GChipAGPCapable 1 << 0
+#define GChipAGPSideband 1 << 1
+#define GChipMultiGLINTApMask 3 << 19
+#define GChipMultiGLINTAp_0M 0 << 19
+#define GChipMultiGLINTAp_16M 1 << 19
+#define GChipMultiGLINTAp_32M 2 << 19
+#define GChipMultiGLINTAp_64M 3 << 19
+
+#define GCSRAperture 0x0878
+#define GCSRSecondaryGLINTMapEn 1 << 0
+
+#define GPageTableAddr 0x0c00
+#define GPageTableLength 0x0c08
+#define GDelayTimer 0x0c38
+#define GCommandMode 0x0c40
+#define GCommandIntEnable 0x0c48
+#define GCommandIntFlags 0x0c50
+#define GCommandErrorFlags 0x0c58
+#define GCommandStatus 0x0c60
+#define GCommandFaultingAddr 0x0c68
+#define GVertexFaultingAddr 0x0c70
+#define GWriteFaultingAddr 0x0c88
+#define GFeedbackSelectCount 0x0c98
+#define GGammaProcessorMode 0x0cb8
+#define GVGAShadow 0x0d00
+#define GMultGLINTAperture 0x0d08
+#define GMultGLINT1 0x0d10
+#define GMultGLINT2 0x0d18
+
+
+
+/************************
+ * GLINT Core Registers *
+ ************************/
+
+#define GLINT_TAG(major,offset) (((major) << 7) | ((offset) << 3))
+#define GLINT_TAG_ADDR(major,offset) (0x8000 | GLINT_TAG((major),(offset)))
+
+#define UNIT_DISABLE 0
+#define UNIT_ENABLE 1
+
+#define StartXDom GLINT_TAG_ADDR(0x00,0x00)
+#define dXDom GLINT_TAG_ADDR(0x00,0x01)
+#define StartXSub GLINT_TAG_ADDR(0x00,0x02)
+#define dXSub GLINT_TAG_ADDR(0x00,0x03)
+#define StartY GLINT_TAG_ADDR(0x00,0x04)
+#define dY GLINT_TAG_ADDR(0x00,0x05)
+#define GLINTCount GLINT_TAG_ADDR(0x00,0x06)
+#define Render GLINT_TAG_ADDR(0x00,0x07)
+ #define AreaStippleEnable 0x00001
+ #define LineStippleEnable 0x00002
+ #define ResetLineStipple 0x00004
+ #define FastFillEnable 0x00008
+ #define PrimitiveLine 0
+ #define PrimitiveTrapezoid 0x00040
+ #define PrimitivePoint 0x00080
+ #define PrimitiveRectangle 0x000C0
+ #define AntialiasEnable 0x00100
+ #define AntialiasingQuality 0x00200
+ #define UsePointTable 0x00400
+ #define SyncOnBitMask 0x00800
+ #define SyncOnHostData 0x01000
+ #define TextureEnable 0x02000
+ #define FogEnable 0x04000
+ #define CoverageEnable 0x08000
+ #define SubPixelCorrectionEnable 0x10000
+ #define SpanOperation 0x40000
+ #define XPositive 1<<21
+ #define YPositive 1<<22
+
+
+#define ContinueNewLine GLINT_TAG_ADDR(0x00,0x08)
+#define ContinueNewDom GLINT_TAG_ADDR(0x00,0x09)
+#define ContinueNewSub GLINT_TAG_ADDR(0x00,0x0a)
+#define Continue GLINT_TAG_ADDR(0x00,0x0b)
+#define FlushSpan GLINT_TAG_ADDR(0x00,0x0c)
+#define BitMaskPattern GLINT_TAG_ADDR(0x00,0x0d)
+
+#define PointTable0 GLINT_TAG_ADDR(0x01,0x00)
+#define PointTable1 GLINT_TAG_ADDR(0x01,0x01)
+#define PointTable2 GLINT_TAG_ADDR(0x01,0x02)
+#define PointTable3 GLINT_TAG_ADDR(0x01,0x03)
+#define RasterizerMode GLINT_TAG_ADDR(0x01,0x04)
+#define RMMultiGLINT 1<<17
+#define BitMaskPackingEachScanline 1<<9
+#define ForceBackgroundColor 1<<6
+#define InvertBitMask 1<<1
+#define YLimits GLINT_TAG_ADDR(0x01,0x05)
+#define ScanLineOwnership GLINT_TAG_ADDR(0x01,0x06)
+#define WaitForCompletion GLINT_TAG_ADDR(0x01,0x07)
+#define PixelSize GLINT_TAG_ADDR(0x01,0x08)
+#define XLimits GLINT_TAG_ADDR(0x01,0x09) /* PM only */
+
+#define RectangleOrigin GLINT_TAG_ADDR(0x01,0x0A) /* PM2 only */
+#define RectangleSize GLINT_TAG_ADDR(0x01,0x0B) /* PM2 only */
+
+#define PackedDataLimits GLINT_TAG_ADDR(0x02,0x0a) /* PM only */
+
+#define ScissorMode GLINT_TAG_ADDR(0x03,0x00)
+ #define SCI_USER 0x01
+ #define SCI_SCREEN 0x02
+ #define SCI_USERANDSCREEN 0x03
+
+#define ScissorMinXY GLINT_TAG_ADDR(0x03,0x01)
+#define ScissorMaxXY GLINT_TAG_ADDR(0x03,0x02)
+#define ScreenSize GLINT_TAG_ADDR(0x03,0x03)
+#define AreaStippleMode GLINT_TAG_ADDR(0x03,0x04)
+ /* 0: */
+ /* NoMirrorY */
+ /* NoMirrorX */
+ /* NoInvertPattern */
+ /* YAddress_1bit */
+ /* XAddress_1bit */
+ /* UNIT_DISABLE */
+
+ #define ASM_XAddress_2bit 1 << 1
+ #define ASM_XAddress_3bit 2 << 1
+ #define ASM_XAddress_4bit 3 << 1
+ #define ASM_XAddress_5bit 4 << 1
+ #define ASM_YAddress_2bit 1 << 4
+ #define ASM_YAddress_3bit 2 << 4
+ #define ASM_YAddress_4bit 3 << 4
+ #define ASM_YAddress_5bit 4 << 4
+ #define ASM_InvertPattern 1 << 17
+ #define ASM_MirrorX 1 << 18
+ #define ASM_MirrorY 1 << 19
+
+#define LineStippleMode GLINT_TAG_ADDR(0x03,0x05)
+#define LoadLineStippleCounters GLINT_TAG_ADDR(0x03,0x06)
+#define UpdateLineStippleCounters GLINT_TAG_ADDR(0x03,0x07)
+#define SaveLineStippleState GLINT_TAG_ADDR(0x03,0x08)
+#define WindowOrigin GLINT_TAG_ADDR(0x03,0x09)
+
+#define AreaStipplePattern0 GLINT_TAG_ADDR(0x04,0x00)
+#define AreaStipplePattern1 GLINT_TAG_ADDR(0x04,0x01)
+#define AreaStipplePattern2 GLINT_TAG_ADDR(0x04,0x02)
+#define AreaStipplePattern3 GLINT_TAG_ADDR(0x04,0x03)
+#define AreaStipplePattern4 GLINT_TAG_ADDR(0x04,0x04)
+#define AreaStipplePattern5 GLINT_TAG_ADDR(0x04,0x05)
+#define AreaStipplePattern6 GLINT_TAG_ADDR(0x04,0x06)
+#define AreaStipplePattern7 GLINT_TAG_ADDR(0x04,0x07)
+
+#define TextureAddressMode GLINT_TAG_ADDR(0x07,0x00)
+#define SStart GLINT_TAG_ADDR(0x07,0x01)
+#define dSdx GLINT_TAG_ADDR(0x07,0x02)
+#define dSdyDom GLINT_TAG_ADDR(0x07,0x03)
+#define TStart GLINT_TAG_ADDR(0x07,0x04)
+#define dTdx GLINT_TAG_ADDR(0x07,0x05)
+#define dTdyDom GLINT_TAG_ADDR(0x07,0x06)
+#define QStart GLINT_TAG_ADDR(0x07,0x07)
+#define dQdx GLINT_TAG_ADDR(0x07,0x08)
+#define dQdyDom GLINT_TAG_ADDR(0x07,0x09)
+#define LOD GLINT_TAG_ADDR(0x07,0x0A)
+#define dSdy GLINT_TAG_ADDR(0x07,0x0B)
+#define dTdy GLINT_TAG_ADDR(0x07,0x0C)
+#define dQdy GLINT_TAG_ADDR(0x07,0x0D)
+
+#define TextureReadMode GLINT_TAG_ADDR(0x09,0x00)
+#define TextureFormat GLINT_TAG_ADDR(0x09,0x01)
+ #define Texture_4_Components 3 << 3
+ #define Texture_Texel 0
+
+#define TextureCacheControl GLINT_TAG_ADDR(0x09,0x02)
+ #define TextureCacheControlEnable 2
+ #define TextureCacheControlInvalidate 1
+
+#define GLINTBorderColor GLINT_TAG_ADDR(0x09,0x05)
+
+#define TexelLUTIndex GLINT_TAG_ADDR(0x09,0x08)
+#define TexelLUTData GLINT_TAG_ADDR(0x09,0x09)
+#define TexelLUTAddress GLINT_TAG_ADDR(0x09,0x0A)
+#define TexelLUTTransfer GLINT_TAG_ADDR(0x09,0x0B)
+#define TextureFilterMode GLINT_TAG_ADDR(0x09,0x0C)
+#define TextureChromaUpper GLINT_TAG_ADDR(0x09,0x0D)
+#define TextureChromaLower GLINT_TAG_ADDR(0x09,0x0E)
+
+#define TxBaseAddr0 GLINT_TAG_ADDR(0x0A,0x00)
+#define TxBaseAddr1 GLINT_TAG_ADDR(0x0A,0x01)
+#define TxBaseAddr2 GLINT_TAG_ADDR(0x0A,0x02)
+#define TxBaseAddr3 GLINT_TAG_ADDR(0x0A,0x03)
+#define TxBaseAddr4 GLINT_TAG_ADDR(0x0A,0x04)
+#define TxBaseAddr5 GLINT_TAG_ADDR(0x0A,0x05)
+#define TxBaseAddr6 GLINT_TAG_ADDR(0x0A,0x06)
+#define TxBaseAddr7 GLINT_TAG_ADDR(0x0A,0x07)
+#define TxBaseAddr8 GLINT_TAG_ADDR(0x0A,0x08)
+#define TxBaseAddr9 GLINT_TAG_ADDR(0x0A,0x09)
+#define TxBaseAddr10 GLINT_TAG_ADDR(0x0A,0x0A)
+#define TxBaseAddr11 GLINT_TAG_ADDR(0x0A,0x0B)
+
+#define PMTextureBaseAddress GLINT_TAG_ADDR(0x0b,0x00)
+#define PMTextureMapFormat GLINT_TAG_ADDR(0x0b,0x01)
+#define PMTextureDataFormat GLINT_TAG_ADDR(0x0b,0x02)
+
+#define Texel0 GLINT_TAG_ADDR(0x0c,0x00)
+#define Texel1 GLINT_TAG_ADDR(0x0c,0x01)
+#define Texel2 GLINT_TAG_ADDR(0x0c,0x02)
+#define Texel3 GLINT_TAG_ADDR(0x0c,0x03)
+#define Texel4 GLINT_TAG_ADDR(0x0c,0x04)
+#define Texel5 GLINT_TAG_ADDR(0x0c,0x05)
+#define Texel6 GLINT_TAG_ADDR(0x0c,0x06)
+#define Texel7 GLINT_TAG_ADDR(0x0c,0x07)
+#define Interp0 GLINT_TAG_ADDR(0x0c,0x08)
+#define Interp1 GLINT_TAG_ADDR(0x0c,0x09)
+#define Interp2 GLINT_TAG_ADDR(0x0c,0x0a)
+#define Interp3 GLINT_TAG_ADDR(0x0c,0x0b)
+#define Interp4 GLINT_TAG_ADDR(0x0c,0x0c)
+#define TextureFilter GLINT_TAG_ADDR(0x0c,0x0d)
+#define PMTextureReadMode GLINT_TAG_ADDR(0x0c,0x0e)
+#define TexelLUTMode GLINT_TAG_ADDR(0x0c,0x0f)
+
+#define TextureColorMode GLINT_TAG_ADDR(0x0d,0x00)
+ #define TextureTypeOpenGL 0
+ #define TextureTypeApple 1 << 4
+ #define TextureKsDDA 1 << 5 /* only Apple-Mode */
+ #define TextureKdDDA 1 << 6 /* only Apple-Mode */
+
+#define TextureEnvColor GLINT_TAG_ADDR(0x0d,0x01)
+#define FogMode GLINT_TAG_ADDR(0x0d,0x02)
+ /* 0: */
+ /* FOG RGBA */
+ /* UNIT_DISABLE */
+
+ #define FOG_CI 0x0002
+
+#define FogColor GLINT_TAG_ADDR(0x0d,0x03)
+#define FStart GLINT_TAG_ADDR(0x0d,0x04)
+#define dFdx GLINT_TAG_ADDR(0x0d,0x05)
+#define dFdyDom GLINT_TAG_ADDR(0x0d,0x06)
+#define KsStart GLINT_TAG_ADDR(0x0d,0x09)
+#define dKsdx GLINT_TAG_ADDR(0x0d,0x0a)
+#define dKsdyDom GLINT_TAG_ADDR(0x0d,0x0b)
+#define KdStart GLINT_TAG_ADDR(0x0d,0x0c)
+#define dKdStart GLINT_TAG_ADDR(0x0d,0x0d)
+#define dKddyDom GLINT_TAG_ADDR(0x0d,0x0e)
+
+#define RStart GLINT_TAG_ADDR(0x0f,0x00)
+#define dRdx GLINT_TAG_ADDR(0x0f,0x01)
+#define dRdyDom GLINT_TAG_ADDR(0x0f,0x02)
+#define GStart GLINT_TAG_ADDR(0x0f,0x03)
+#define dGdx GLINT_TAG_ADDR(0x0f,0x04)
+#define dGdyDom GLINT_TAG_ADDR(0x0f,0x05)
+#define BStart GLINT_TAG_ADDR(0x0f,0x06)
+#define dBdx GLINT_TAG_ADDR(0x0f,0x07)
+#define dBdyDom GLINT_TAG_ADDR(0x0f,0x08)
+#define AStart GLINT_TAG_ADDR(0x0f,0x09)
+#define dAdx GLINT_TAG_ADDR(0x0f,0x0a)
+#define dAdyDom GLINT_TAG_ADDR(0x0f,0x0b)
+#define ColorDDAMode GLINT_TAG_ADDR(0x0f,0x0c)
+ /* 0: */
+ #define CDDA_FlatShading 0
+ /* UNIT_DISABLE */
+ #define CDDA_GouraudShading 0x0002
+
+
+#define ConstantColor GLINT_TAG_ADDR(0x0f,0x0d)
+#define GLINTColor GLINT_TAG_ADDR(0x0f,0x0e)
+#define AlphaTestMode GLINT_TAG_ADDR(0x10,0x00)
+#define AntialiasMode GLINT_TAG_ADDR(0x10,0x01)
+#define AlphaBlendMode GLINT_TAG_ADDR(0x10,0x02)
+ /* 0: */
+ /* SrcZERO */
+ /* DstZERO */
+ /* ColorFormat8888 */
+ /* AlphaBuffer present */
+ /* ColorOrderBGR */
+ /* TypeOpenGL */
+ /* DstFBData */
+ /* UNIT_DISABLE */
+
+ #define ABM_SrcONE 1 << 1
+ #define ABM_SrcDST_COLOR 2 << 1
+ #define ABM_SrcONE_MINUS_DST_COLOR 3 << 1
+ #define ABM_SrcSRC_ALPHA 4 << 1
+ #define ABM_SrcONE_MINUS_SRC_ALPHA 5 << 1
+ #define ABM_SrcDST_ALPHA 6 << 1
+ #define ABM_SrcONE_MINUS_DST_ALPHA 7 << 1
+ #define ABM_SrcSRC_ALPHA_SATURATE 8 << 1
+ #define ABM_DstONE 1 << 5
+ #define ABM_DstSRC_COLOR 2 << 5
+ #define ABM_DstONE_MINUS_SRC_COLOR 3 << 5
+ #define ABM_DstSRC_ALPHA 4 << 5
+ #define ABM_DstONE_MINUS_SRC_ALPHA 5 << 5
+ #define ABM_DstDST_ALPHA 6 << 5
+ #define ABM_DstONE_MINUS_DST_ALPHA 7 << 5
+ #define ABM_ColorFormat5555 1 << 8
+ #define ABM_ColorFormat4444 2 << 8
+ #define ABM_ColorFormat4444_Front 3 << 8
+ #define ABM_ColorFormat4444_Back 4 << 8
+ #define ABM_ColorFormat332_Front 5 << 8
+ #define ABM_ColorFormat332_Back 6 << 8
+ #define ABM_ColorFormat121_Front 7 << 8
+ #define ABM_ColorFormat121_Back 8 << 8
+ #define ABM_ColorFormat555_Back 13 << 8
+ #define ABM_ColorFormat_CI8 14 << 8
+ #define ABM_ColorFormat_CI4 15 << 8
+ #define ABM_NoAlphaBuffer 0x1000
+ #define ABM_ColorOrderRGB 0x2000
+ #define ABM_TypeQuickDraw3D 0x4000
+ #define ABM_DstFBSourceData 0x8000
+
+#define DitherMode GLINT_TAG_ADDR(0x10,0x03)
+ /* 0: */
+ /* ColorOrder BGR */
+ /* AlphaDitherDefault */
+ /* ColorFormat8888 */
+ /* TruncateMode */
+ /* DitherDisable */
+ /* UNIT_DISABLE */
+
+ #define DTM_DitherEnable 1 << 1
+ #define DTM_ColorFormat5555 1 << 2
+ #define DTM_ColorFormat4444 2 << 2
+ #define DTM_ColorFormat4444_Front 3 << 2
+ #define DTM_ColorFormat4444_Back 4 << 2
+ #define DTM_ColorFormat332_Front 5 << 2
+ #define DTM_ColorFormat332_Back 6 << 2
+ #define DTM_ColorFormat121_Front 7 << 2
+ #define DTM_ColorFormat121_Back 8 << 2
+ #define DTM_ColorFormat555_Back 13 << 2
+ #define DTM_ColorFormat_CI8 14 << 2
+ #define DTM_ColorFormat_CI4 15 << 2
+ #define DTM_ColorOrderRGB 1 << 10
+ #define DTM_NoAlphaDither 1 << 14
+ #define DTM_RoundMode 1 << 15
+
+#define FBSoftwareWriteMask GLINT_TAG_ADDR(0x10,0x04)
+#define LogicalOpMode GLINT_TAG_ADDR(0x10,0x05)
+ #define Use_ConstantFBWriteData 0x40
+
+
+#define FBWriteData GLINT_TAG_ADDR(0x10,0x06)
+#define RouterMode GLINT_TAG_ADDR(0x10,0x08)
+ #define ROUTER_Depth_Texture 1
+ #define ROUTER_Texture_Depth 0
+
+
+#define LBReadMode GLINT_TAG_ADDR(0x11,0x00)
+ /* 0: */
+ /* SrcNoRead */
+ /* DstNoRead */
+ /* DataLBDefault */
+ /* WinTopLeft */
+ /* NoPatch */
+ /* ScanlineInterval1 */
+
+ #define LBRM_SrcEnable 1 << 9
+ #define LBRM_DstEnable 1 << 10
+ #define LBRM_DataLBStencil 1 << 16
+ #define LBRM_DataLBDepth 2 << 16
+ #define LBRM_WinBottomLeft 1 << 18
+ #define LBRM_DoPatch 1 << 19
+
+ #define LBRM_ScanlineInt2 1 << 20
+ #define LBRM_ScanlineInt4 2 << 20
+ #define LBRM_ScanlineInt8 3 << 20
+
+
+#define LBReadFormat GLINT_TAG_ADDR(0x11,0x01)
+ #define LBRF_DepthWidth15 0x03 /* only permedia */
+ #define LBRF_DepthWidth16 0x00
+ #define LBRF_DepthWidth24 0x01
+ #define LBRF_DepthWidth32 0x02
+
+ #define LBRF_StencilWidth0 (0 << 2)
+ #define LBRF_StencilWidth4 (1 << 2)
+ #define LBRF_StencilWidth8 (2 << 2)
+
+ #define LBRF_StencilPos16 (0 << 4)
+ #define LBRF_StencilPos20 (1 << 4)
+ #define LBRF_StencilPos24 (2 << 4)
+ #define LBRF_StencilPos28 (3 << 4)
+ #define LBRF_StencilPos32 (4 << 4)
+
+ #define LBRF_FrameCount0 (0 << 7)
+ #define LBRF_FrameCount4 (1 << 7)
+ #define LBRF_FrameCount8 (2 << 7)
+
+ #define LBRF_FrameCountPos16 (0 << 9)
+ #define LBRF_FrameCountPos20 (1 << 9)
+ #define LBRF_FrameCountPos24 (2 << 9)
+ #define LBRF_FrameCountPos28 (3 << 9)
+ #define LBRF_FrameCountPos32 (4 << 9)
+ #define LBRF_FrameCountPos36 (5 << 9)
+ #define LBRF_FrameCountPos40 (6 << 9)
+
+ #define LBRF_GIDWidth0 (0 << 12)
+ #define LBRF_GIDWidth4 (1 << 12)
+
+ #define LBRF_GIDPos16 (0 << 13)
+ #define LBRF_GIDPos20 (1 << 13)
+ #define LBRF_GIDPos24 (2 << 13)
+ #define LBRF_GIDPos28 (3 << 13)
+ #define LBRF_GIDPos32 (4 << 13)
+ #define LBRF_GIDPos36 (5 << 13)
+ #define LBRF_GIDPos40 (6 << 13)
+ #define LBRF_GIDPos44 (7 << 13)
+ #define LBRF_GIDPos48 (8 << 13)
+
+ #define LBRF_Compact32 (1 << 17)
+
+
+
+#define LBSourceOffset GLINT_TAG_ADDR(0x11,0x02)
+#define LBStencil GLINT_TAG_ADDR(0x11,0x05)
+#define LBDepth GLINT_TAG_ADDR(0x11,0x06)
+#define LBWindowBase GLINT_TAG_ADDR(0x11,0x07)
+#define LBWriteMode GLINT_TAG_ADDR(0x11,0x08)
+ #define LBWM_WriteEnable 0x1
+ #define LBWM_UpLoad_LBDepth 0x2
+ #define LBWM_UpLoad_LBStencil 0x4
+
+#define LBWriteFormat GLINT_TAG_ADDR(0x11,0x09)
+
+
+#define TextureData GLINT_TAG_ADDR(0x11,0x0d)
+#define TextureDownloadOffset GLINT_TAG_ADDR(0x11,0x0e)
+#define LBWindowOffset GLINT_TAG_ADDR(0x11,0x0f)
+
+#define GLINTWindow GLINT_TAG_ADDR(0x13,0x00)
+ #define GWIN_UnitEnable (1 << 0)
+ #define GWIN_ForceLBUpdate (1 << 3)
+ #define GWIN_LBUpdateSourceREG (1 << 4)
+ #define GWIN_LBUpdateSourceLB (0 << 4)
+ #define GWIN_StencilFCP (1 << 17)
+ #define GWIN_DepthFCP (1 << 18)
+ #define GWIN_OverrideWriteFilter (1 << 19)
+
+ /* ??? is this needed, set by permedia (2) modules */
+ #define GWIN_DisableLBUpdate 0x40000
+
+#define StencilMode GLINT_TAG_ADDR(0x13,0x01)
+#define StencilData GLINT_TAG_ADDR(0x13,0x02)
+#define GLINTStencil GLINT_TAG_ADDR(0x13,0x03)
+#define DepthMode GLINT_TAG_ADDR(0x13,0x04)
+ /* 0: */
+ /* WriteDisable */
+ /* SrcCompFragment */
+ /* CompFuncNEVER */
+ /* UNIT_DISABLE */
+
+ #define DPM_WriteEnable 1 << 1
+ #define DPM_SrcCompLBData 1 << 2
+ #define DPM_SrcCompDregister 2 << 2
+ #define DPM_SrcCompLBSourceData 3 << 2
+ #define DPM_CompFuncLESS 1 << 4
+ #define DPM_CompFuncEQUAL 2 << 4
+ #define DPM_CompFuncLESS_OR_EQ 3 << 4
+ #define DPM_CompFuncGREATER 4 << 4
+ #define DPM_CompFuncNOT_EQ 5 << 4
+ #define DPM_CompFuncGREATER_OR_EQ 6 << 4
+ #define DPM_CompFuncALWAYS 7 << 4
+
+#define GLINTDepth GLINT_TAG_ADDR(0x13,0x05)
+#define ZStartU GLINT_TAG_ADDR(0x13,0x06)
+#define ZStartL GLINT_TAG_ADDR(0x13,0x07)
+#define dZdxU GLINT_TAG_ADDR(0x13,0x08)
+#define dZdxL GLINT_TAG_ADDR(0x13,0x09)
+#define dZdyDomU GLINT_TAG_ADDR(0x13,0x0a)
+#define dZdyDomL GLINT_TAG_ADDR(0x13,0x0b)
+#define FastClearDepth GLINT_TAG_ADDR(0x13,0x0c)
+
+#define FBReadMode GLINT_TAG_ADDR(0x15,0x00)
+ /* 0: */
+ /* SrcNoRead */
+ /* DstNoRead */
+ /* DataFBDefault */
+ /* WinTopLeft */
+ /* ScanlineInterval1 */
+
+ #define FBRM_SrcEnable 1 << 9
+ #define FBRM_DstEnable 1 << 10
+ #define FBRM_DataFBColor 1 << 15
+ #define FBRM_WinBottomLeft 1 << 16
+ #define FBRM_Packed 1 << 19
+ #define FBRM_ScanlineInt2 1 << 23
+ #define FBRM_ScanlineInt4 2 << 23
+ #define FBRM_ScanlineInt8 3 << 23
+
+
+#define FBSourceOffset GLINT_TAG_ADDR(0x15,0x01)
+#define FBPixelOffset GLINT_TAG_ADDR(0x15,0x02)
+#define FBColor GLINT_TAG_ADDR(0x15,0x03)
+#define FBData GLINT_TAG_ADDR(0x15,0x04)
+#define FBSourceData GLINT_TAG_ADDR(0x15,0x05)
+
+#define FBWindowBase GLINT_TAG_ADDR(0x15,0x06)
+#define FBWriteMode GLINT_TAG_ADDR(0x15,0x07)
+ /* 0: */
+ /* FBWM_NoColorUpload */
+ /* FBWM_WriteDisable */
+
+ #define FBWM_WriteEnable 1
+ #define FBWM_UploadColor 1 << 3
+
+#define FBHardwareWriteMask GLINT_TAG_ADDR(0x15,0x08)
+#define FBBlockColor GLINT_TAG_ADDR(0x15,0x09)
+#define FBReadPixel GLINT_TAG_ADDR(0x15,0x0a) /* PM */
+#define PatternRamMode GLINT_TAG_ADDR(0x15,0x0f)
+
+#define PatternRamData0 GLINT_TAG_ADDR(0x16,0x00)
+#define PatternRamData1 GLINT_TAG_ADDR(0x16,0x01)
+#define PatternRamData2 GLINT_TAG_ADDR(0x16,0x02)
+#define PatternRamData3 GLINT_TAG_ADDR(0x16,0x03)
+#define PatternRamData4 GLINT_TAG_ADDR(0x16,0x04)
+#define PatternRamData5 GLINT_TAG_ADDR(0x16,0x05)
+#define PatternRamData6 GLINT_TAG_ADDR(0x16,0x06)
+#define PatternRamData7 GLINT_TAG_ADDR(0x16,0x07)
+
+#define FilterMode GLINT_TAG_ADDR(0x18,0x00)
+ /* 0: */
+ /* CullDepthTags */
+ /* CullDepthData */
+ /* CullStencilTags */
+ /* CullStencilData */
+ /* CullColorTag */
+ /* CullColorData */
+ /* CullSyncTag */
+ /* CullSyncData */
+ /* CullStatisticTag */
+ /* CullStatisticData */
+
+ #define FM_PassDepthTags 0x0010
+ #define FM_PassDepthData 0x0020
+ #define FM_PassStencilTags 0x0040
+ #define FM_PassStencilData 0x0080
+ #define FM_PassColorTag 0x0100
+ #define FM_PassColorData 0x0200
+ #define FM_PassSyncTag 0x0400
+ #define FM_PassSyncData 0x0800
+ #define FM_PassStatisticTag 0x1000
+ #define FM_PassStatisticData 0x2000
+
+#define StatisticMode GLINT_TAG_ADDR(0x18,0x01)
+#define MinRegion GLINT_TAG_ADDR(0x18,0x02)
+#define MaxRegion GLINT_TAG_ADDR(0x18,0x03)
+#define ResetPickResult GLINT_TAG_ADDR(0x18,0x04)
+#define MitHitRegion GLINT_TAG_ADDR(0x18,0x05)
+#define MaxHitRegion GLINT_TAG_ADDR(0x18,0x06)
+#define PickResult GLINT_TAG_ADDR(0x18,0x07)
+#define GlintSync GLINT_TAG_ADDR(0x18,0x08)
+
+#define FBBlockColorU GLINT_TAG_ADDR(0x18,0x0d)
+#define FBBlockColorL GLINT_TAG_ADDR(0x18,0x0e)
+#define SuspendUntilFrameBlank GLINT_TAG_ADDR(0x18,0x0f)
+
+#define KsRStart GLINT_TAG_ADDR(0x19,0x00)
+#define dKsRdx GLINT_TAG_ADDR(0x19,0x01)
+#define dKsRdyDom GLINT_TAG_ADDR(0x19,0x02)
+#define KsGStart GLINT_TAG_ADDR(0x19,0x03)
+#define dKsGdx GLINT_TAG_ADDR(0x19,0x04)
+#define dKsGdyDom GLINT_TAG_ADDR(0x19,0x05)
+#define KsBStart GLINT_TAG_ADDR(0x19,0x06)
+#define dKsBdx GLINT_TAG_ADDR(0x19,0x07)
+#define dKsBdyDom GLINT_TAG_ADDR(0x19,0x08)
+
+#define KdRStart GLINT_TAG_ADDR(0x1A,0x00)
+#define dKdRdx GLINT_TAG_ADDR(0x1A,0x01)
+#define dKdRdyDom GLINT_TAG_ADDR(0x1A,0x02)
+#define KdGStart GLINT_TAG_ADDR(0x1A,0x03)
+#define dKdGdx GLINT_TAG_ADDR(0x1A,0x04)
+#define dKdGdyDom GLINT_TAG_ADDR(0x1A,0x05)
+#define KdBStart GLINT_TAG_ADDR(0x1A,0x06)
+#define dKdBdx GLINT_TAG_ADDR(0x1A,0x07)
+#define dKdBdyDom GLINT_TAG_ADDR(0x1A,0x08)
+
+#define FBSourceBase GLINT_TAG_ADDR(0x1B,0x00)
+#define FBSourceDelta GLINT_TAG_ADDR(0x1B,0x01)
+#define Config GLINT_TAG_ADDR(0x1B,0x02)
+#define CFBRM_SrcEnable 1<<0
+#define CFBRM_DstEnable 1<<1
+#define CFBRM_Packed 1<<2
+#define CWM_Enable 1<<3
+#define CCDDA_Enable 1<<4
+#define CLogOp_Enable 1<<5
+#define ContextDump GLINT_TAG_ADDR(0x1B,0x08)
+#define ContextRestore GLINT_TAG_ADDR(0x1B,0x09)
+#define ContextData GLINT_TAG_ADDR(0x1B,0x0a)
+
+#define TexelLUT0 GLINT_TAG_ADDR(0x1D,0x00)
+#define TexelLUT1 GLINT_TAG_ADDR(0x1D,0x01)
+#define TexelLUT2 GLINT_TAG_ADDR(0x1D,0x02)
+#define TexelLUT3 GLINT_TAG_ADDR(0x1D,0x03)
+#define TexelLUT4 GLINT_TAG_ADDR(0x1D,0x04)
+#define TexelLUT5 GLINT_TAG_ADDR(0x1D,0x05)
+#define TexelLUT6 GLINT_TAG_ADDR(0x1D,0x06)
+#define TexelLUT7 GLINT_TAG_ADDR(0x1D,0x07)
+#define TexelLUT8 GLINT_TAG_ADDR(0x1D,0x08)
+#define TexelLUT9 GLINT_TAG_ADDR(0x1D,0x09)
+#define TexelLUT10 GLINT_TAG_ADDR(0x1D,0x0A)
+#define TexelLUT11 GLINT_TAG_ADDR(0x1D,0x0B)
+#define TexelLUT12 GLINT_TAG_ADDR(0x1D,0x0C)
+#define TexelLUT13 GLINT_TAG_ADDR(0x1D,0x0D)
+#define TexelLUT14 GLINT_TAG_ADDR(0x1D,0x0E)
+#define TexelLUT15 GLINT_TAG_ADDR(0x1D,0x0F)
+
+#define YUVMode GLINT_TAG_ADDR(0x1E,0x00)
+#define ChromaUpper GLINT_TAG_ADDR(0x1E,0x01)
+#define ChromaLower GLINT_TAG_ADDR(0x1E,0x02)
+#define ChromaTestMode GLINT_TAG_ADDR(0x1E,0x03)
+
+
+/******************************
+ * GLINT Delta Core Registers *
+ ******************************/
+
+#define V0FixedTag GLINT_TAG_ADDR(0x20,0x00)
+#define V1FixedTag GLINT_TAG_ADDR(0x21,0x00)
+#define V2FixedTag GLINT_TAG_ADDR(0x22,0x00)
+#define V0FloatTag GLINT_TAG_ADDR(0x23,0x00)
+#define V1FloatTag GLINT_TAG_ADDR(0x24,0x00)
+#define V2FloatTag GLINT_TAG_ADDR(0x25,0x00)
+
+#define VPAR_s 0x00
+#define VPAR_t 0x08
+#define VPAR_q 0x10
+#define VPAR_Ks 0x18
+#define VPAR_Kd 0x20
+
+/* have changed colors in ramdac !
+#define VPAR_R 0x28
+#define VPAR_G 0x30
+#define VPAR_B 0x38
+#define VPAR_A 0x40
+*/
+#define VPAR_B 0x28
+#define VPAR_G 0x30
+#define VPAR_R 0x38
+#define VPAR_A 0x40
+
+#define VPAR_f 0x48
+
+#define VPAR_x 0x50
+#define VPAR_y 0x58
+#define VPAR_z 0x60
+
+#define DeltaModeTag GLINT_TAG_ADDR(0x26,0x00)
+ /* 0: */
+ /* GLINT_300SX */
+
+ /* DeltaMode Register Bit Field Assignments */
+ #define DM_GLINT_300SX 0x0000
+ #define DM_GLINT_500TX 0x0001
+ #define DM_PERMEDIA 0x0002
+ #define DM_Depth_16BPP (1 << 2)
+ #define DM_Depth_24BPP (2 << 2)
+ #define DM_Depth_32BPP (3 << 2)
+ #define DM_FogEnable 0x0010
+ #define DM_TextureEnable 0x0020
+ #define DM_SmoothShadingEnable 0x0040
+ #define DM_DepthEnable 0x0080
+ #define DM_SpecularTextureEnable 0x0100
+ #define DM_DiffuseTextureEnable 0x0200
+ #define DM_SubPixelCorrectionEnable 0x0400
+ #define DM_DiamondExit 0x0800
+ #define DM_NoDraw 0x1000
+ #define DM_ClampEnable 0x2000
+ #define DM_ClampedTexParMode 0x4000
+ #define DM_NormalizedTexParMode 0xC000
+
+
+ #define DDCMD_AreaStrippleEnable 0x0001
+ #define DDCMD_LineStrippleEnable 0x0002
+ #define DDCMD_ResetLineStripple 1 << 2
+ #define DDCMD_FastFillEnable 1 << 3
+ /* 2 Bits reserved */
+ #define DDCMD_PrimitiveType_Point 2 << 6
+ #define DDCMD_PrimitiveType_Line 0 << 6
+ #define DDCMD_PrimitiveType_Trapezoid 1 << 6
+ #define DDCMD_AntialiasEnable 1 << 8
+ #define DDCMD_AntialiasingQuality 1 << 9
+ #define DDCMD_UsePointTable 1 << 10
+ #define DDCMD_SyncOnBitMask 1 << 11
+ #define DDCMD_SyncOnHostDate 1 << 12
+ #define DDCMD_TextureEnable 1 << 13
+ #define DDCMD_FogEnable 1 << 14
+ #define DDCMD_CoverageEnable 1 << 15
+ #define DDCMD_SubPixelCorrectionEnable 1 << 16
+
+
+
+#define DrawTriangle GLINT_TAG_ADDR(0x26,0x01)
+#define RepeatTriangle GLINT_TAG_ADDR(0x26,0x02)
+#define DrawLine01 GLINT_TAG_ADDR(0x26,0x03)
+#define DrawLine10 GLINT_TAG_ADDR(0x26,0x04)
+#define RepeatLine GLINT_TAG_ADDR(0x26,0x05)
+#define BroadcastMask GLINT_TAG_ADDR(0x26,0x0F)
+
+/* Colorformats */
+#define BGR555 1
+#define BGR565 16
+#define CI8 14
+#define CI4 15
+
+#ifdef DEBUG
+#define GLINT_WRITE_REG(v,r) \
+ GLINT_VERB_WRITE_REG(pGlint,v,r,__FILE__,__LINE__)
+#define GLINT_READ_REG(r) \
+ GLINT_VERB_READ_REG(pGlint,r,__FILE__,__LINE__)
+#else
+#define GLINT_WRITE_REG(v,r) \
+do{ \
+ *(volatile CARD32 *)((char *)pGlint->IOBase+(r))=v; \
+}while(0)
+#define GLINT_READ_REG(r) \
+ (*(volatile CARD32 *)((char *)pGlint->IOBase+(r)))
+#endif
+
+#define GLINT_WAIT(n) \
+do{ \
+ if(!pGlint->UsePCIRetry) \
+ while(GLINT_READ_REG(InFIFOSpace)<(n)); \
+}while(0)
+
+#define GLINT_MASK_WRITE_REG(v,m,r) \
+ GLINT_WRITE_REG((GLINT_READ_REG(r)&(m))|(v),r)
+
+#define GLINTDACDelay(x) do { \
+ int delay = x; \
+ unsigned char tmp; \
+ while(delay--){tmp = GLINT_READ_REG(InFIFOSpace);}; \
+ } while(0)
+
+#define GLINT_SLOW_WRITE_REG(v,r) \
+do{ \
+ GLINTDACDelay(5); \
+ GLINT_WRITE_REG(v,r); \
+ GLINTDACDelay(5); \
+}while(0)
+
+#define GLINT_SECONDARY_WRITE_REG(v,r) \
+do{ \
+ *(volatile CARD32 *)((char *)pGlint->SecondaryBase+(r))=v; \
+}while(0)
+
+#define GLINT_SECONDARY_READ_REG(r) \
+ (*(volatile CARD32 *)((char *)pGlint->SecondaryBase+(r)))
+
+#define GLINT_SECONDARY_SLOW_WRITE_REG(v,r) \
+do{ \
+ while(GLINT_READ_REG(InFIFOSpace)<1); \
+ GLINT_SECONDARY_WRITE_REG(v,r); \
+}while(0)
+
+#define GLINT_LOAD_PAR(v,r) \
+ *(unsigned long *)((char*)pGlint->IOBase+r) = *((unsigned long *) &v)
+
+#define REPLICATE(r) \
+{ \
+ if (pScrn->bitsPerPixel == 16) { \
+ r = ((r & 0xFFFF) << 16) | (r & 0xFFFF); \
+ } else \
+ if (pScrn->bitsPerPixel == 8) { \
+ r &= 0xFF; \
+ r |= (r<<8); \
+ r |= (r<<16); \
+ } \
+}
+
+#define LOADROP(rop) \
+{ \
+ if (pGlint->ROP != rop) { \
+ GLINT_WRITE_REG(rop<<1|UNIT_ENABLE, LogicalOpMode); \
+ pGlint->ROP = rop; \
+ } \
+}
+
+
+#define CHECKCLIPPING \
+{ \
+ if (pGlint->ClippingOn) { \
+ pGlint->ClippingOn = FALSE; \
+ GLINT_WAIT(1); \
+ GLINT_WRITE_REG(0, ScissorMode); \
+ } \
+}
+
+#define DO_PLANEMASK(planemask) \
+{ \
+ if (planemask != pGlint->planemask) { \
+ pGlint->planemask = planemask; \
+ REPLICATE(planemask); \
+ GLINT_WRITE_REG(planemask, FBHardwareWriteMask);\
+ } \
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_accel.c
new file mode 100644
index 000000000..1e7fad981
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_accel.c
@@ -0,0 +1,1773 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ * Dirk Hohndel, <hohndel@suse.de>
+ * Stefan Dirsch, <sndirsch@suse.de>
+ * Mark Vojkovich, <mvojkovi@ucsd.edu>
+ *
+ * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and
+ * Siemens Nixdorf Informationssysteme
+ *
+ * Permedia 2 accelerated options.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_accel.c,v 1.17 1999/07/11 08:49:26 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "miline.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+
+#include "glint_regs.h"
+#include "glint.h"
+
+#include "xaalocal.h" /* For replacements */
+
+static void Permedia2SetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void Permedia2SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h);
+static void Permedia2SetupForFillRectSolid24bpp(ScrnInfoPtr pScrn,int color,
+ int rop, unsigned int planemask);
+static void Permedia2SubsequentFillRectSolid24bpp(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h);
+static void Permedia2SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2,
+ int y2, int w, int h);
+static void Permedia2SetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask,
+ int transparency_color);
+static void Permedia2SubsequentScreenToScreenCopy2432bpp(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int w, int h);
+static void Permedia2SetupForScreenToScreenCopy2432bpp(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask,
+ int transparency_color);
+static void Permedia2SetClippingRectangle(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h);
+static void Permedia2DisableClipping(ScrnInfoPtr pScrn);
+static void Permedia2SetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void Permedia2SubsequentHorVertLine(ScrnInfoPtr pScrn, int x, int y,
+ int len, int dir);
+static void Permedia2SubsequentSolidBresenhamLine8bpp(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+static void Permedia2SubsequentSolidBresenhamLine16bpp(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+static void Permedia2SubsequentSolidBresenhamLine32bpp(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+static void Permedia2WriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int skipleft,
+ int fg, int bg, int rop,unsigned int planemask);
+static void Permedia2SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int fg, int bg,
+ int rop, unsigned int planemask);
+static void Permedia2SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+static void Permedia2SetupForMono8x8PatternFill24bpp(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int fg, int bg,
+ int rop, unsigned int planemask);
+static void Permedia2SubsequentMono8x8PatternFillRect24bpp(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+static void Permedia2WritePixmap8bpp(ScrnInfoPtr pScrn, int x, int y, int w,
+ int h, unsigned char *src, int srcwidth,
+ int rop, unsigned int planemask,
+ int transparency_color, int bpp, int depth);
+static void Permedia2WritePixmap16bpp(ScrnInfoPtr pScrn, int x, int y, int w,
+ int h, unsigned char *src, int srcwidth,
+ int rop, unsigned int planemask,
+ int transparency_color, int bpp, int depth);
+static void Permedia2WritePixmap24bpp(ScrnInfoPtr pScrn, int x, int y, int w,
+ int h, unsigned char *src, int srcwidth,
+ int rop, unsigned int planemask,
+ int transparency_color, int bpp, int depth);
+static void Permedia2WritePixmap32bpp(ScrnInfoPtr pScrn, int x, int y, int w,
+ int h, unsigned char *src, int srcwidth,
+ int rop, unsigned int planemask,
+ int transparency_color, int bpp, int depth);
+static void Permedia2SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,unsigned int planemask);
+static void Permedia2SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft);
+static void Permedia2SetupForScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void Permedia2SubsequentScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn, int x,
+ int y, int w, int h, int skipleft);
+static void Permedia2SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
+static void Permedia2LoadCoord(ScrnInfoPtr pScrn, int x, int y, int w, int h);
+static void Permedia2PolylinesThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC,
+ int mode, int npt, DDXPointPtr pPts);
+static void Permedia2PolySegmentThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC,
+ int nseg, xSegment *pSeg);
+
+#define MAX_FIFO_ENTRIES 256
+
+void
+Permedia2InitializeEngine(ScrnInfoPtr pScrn)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ /* Initialize the Accelerator Engine to defaults */
+
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode);
+ GLINT_SLOW_WRITE_REG(UNIT_ENABLE, FBWriteMode);
+ GLINT_SLOW_WRITE_REG(0, dXSub);
+ GLINT_SLOW_WRITE_REG(GWIN_DisableLBUpdate, GLINTWindow);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DitherMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureColorMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureAddressMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PMTextureReadMode);
+ GLINT_SLOW_WRITE_REG(pGlint->pprod, LBReadMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TexelLUTMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, YUVMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RouterMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FogMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AntialiasMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaTestMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StencilMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AreaStippleMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LogicalOpMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StatisticMode);
+ GLINT_SLOW_WRITE_REG(0xc00, FilterMode);
+ GLINT_SLOW_WRITE_REG(0xffffffff, FBHardwareWriteMask);
+ GLINT_SLOW_WRITE_REG(0xffffffff, FBSoftwareWriteMask);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RasterizerMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, GLINTDepth);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBSourceOffset);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBPixelOffset);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBSourceOffset);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, WindowOrigin);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBWindowBase);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBSourceBase);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBWindowBase);
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ pGlint->PixelWidth = 0x0; /* 8 Bits */
+ pGlint->TexMapFormat = pGlint->pprod;
+ break;
+ case 16:
+ pGlint->PixelWidth = 0x1; /* 16 Bits */
+ pGlint->TexMapFormat = pGlint->pprod | 1<<19;
+ break;
+ case 24:
+ pGlint->PixelWidth = 0x4; /* 24 Bits */
+ pGlint->TexMapFormat = pGlint->pprod | 2<<19;
+ break;
+ case 32:
+ pGlint->PixelWidth = 0x2; /* 32 Bits */
+ pGlint->TexMapFormat = pGlint->pprod | 2<<19;
+ break;
+ }
+ pGlint->ClippingOn = FALSE;
+ pGlint->startxdom = 0;
+ pGlint->startxsub = 0;
+ pGlint->starty = 0;
+ pGlint->count = 0;
+ pGlint->dy = 1<<16;
+ pGlint->dxdom = 0;
+ pGlint->x = 0;
+ pGlint->y = 0;
+ pGlint->h = 0;
+ pGlint->w = 0;
+ pGlint->ROP = 0xFF;
+ GLINT_SLOW_WRITE_REG(pGlint->PixelWidth, FBReadPixel);
+ GLINT_SLOW_WRITE_REG(pGlint->TexMapFormat, PMTextureMapFormat);
+ GLINT_SLOW_WRITE_REG(0, RectangleSize);
+ GLINT_SLOW_WRITE_REG(0, RectangleOrigin);
+ GLINT_SLOW_WRITE_REG(0, dXDom);
+ GLINT_SLOW_WRITE_REG(1<<16, dY);
+ GLINT_SLOW_WRITE_REG(0, StartXDom);
+ GLINT_SLOW_WRITE_REG(0, StartXSub);
+ GLINT_SLOW_WRITE_REG(0, StartY);
+ GLINT_SLOW_WRITE_REG(0, GLINTCount);
+}
+
+Bool
+Permedia2AccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ BoxRec AvailFBArea;
+
+ pGlint->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ Permedia2InitializeEngine(pScrn);
+
+ infoPtr->Flags = PIXMAP_CACHE |
+ OFFSCREEN_PIXMAPS |
+ LINEAR_FRAMEBUFFER;
+
+ infoPtr->Sync = Permedia2Sync;
+
+ infoPtr->SetClippingRectangle = Permedia2SetClippingRectangle;
+ infoPtr->DisableClipping = Permedia2DisableClipping;
+ infoPtr->ClippingFlags = HARDWARE_CLIP_MONO_8x8_FILL;
+
+ infoPtr->SolidFillFlags = 0;
+ infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
+ infoPtr->WriteBitmapFlags = 0;
+ if (pScrn->bitsPerPixel == 24) {
+ infoPtr->SetupForSolidFill =
+ Permedia2SetupForFillRectSolid24bpp;
+ infoPtr->SubsequentSolidFillRect =
+ Permedia2SubsequentFillRectSolid24bpp;
+ } else {
+ infoPtr->SolidLineFlags = 0;
+ infoPtr->PolySegmentThinSolidFlags = 0;
+ infoPtr->PolylinesThinSolidFlags = 0;
+ infoPtr->SetupForSolidLine = Permedia2SetupForSolidLine;
+ infoPtr->SubsequentSolidHorVertLine = Permedia2SubsequentHorVertLine;
+ switch(pScrn->bitsPerPixel) {
+ case 8: infoPtr->SubsequentSolidBresenhamLine =
+ Permedia2SubsequentSolidBresenhamLine8bpp;
+ break;
+ case 16: infoPtr->SubsequentSolidBresenhamLine =
+ Permedia2SubsequentSolidBresenhamLine16bpp;
+ break;
+ case 32: infoPtr->SubsequentSolidBresenhamLine =
+ Permedia2SubsequentSolidBresenhamLine32bpp;
+ break;
+ }
+ infoPtr->PolySegmentThinSolid = Permedia2PolySegmentThinSolidWrapper;
+ infoPtr->PolylinesThinSolid = Permedia2PolylinesThinSolidWrapper;
+ infoPtr->SetupForSolidFill = Permedia2SetupForFillRectSolid;
+ infoPtr->SubsequentSolidFillRect = Permedia2SubsequentFillRectSolid;
+ }
+
+ if (pScrn->bitsPerPixel >= 24) {
+ infoPtr->SetupForScreenToScreenCopy =
+ Permedia2SetupForScreenToScreenCopy2432bpp;
+ infoPtr->SubsequentScreenToScreenCopy =
+ Permedia2SubsequentScreenToScreenCopy2432bpp;
+ } else {
+ infoPtr->SetupForScreenToScreenCopy =
+ Permedia2SetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy =
+ Permedia2SubsequentScreenToScreenCopy;
+ }
+
+ infoPtr->Mono8x8PatternFillFlags =
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ HARDWARE_PATTERN_SCREEN_ORIGIN;
+
+ if (pScrn->bitsPerPixel == 24) {
+ infoPtr->SetupForMono8x8PatternFill =
+ Permedia2SetupForMono8x8PatternFill24bpp;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ Permedia2SubsequentMono8x8PatternFillRect24bpp;
+ } else {
+ infoPtr->SetupForMono8x8PatternFill =
+ Permedia2SetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ Permedia2SubsequentMono8x8PatternFillRect;
+ }
+
+ if (pGlint->UsePCIRetry) {
+ infoPtr->CPUToScreenColorExpandFillFlags = SYNC_AFTER_COLOR_EXPAND |
+ BIT_ORDER_IN_BYTE_LSBFIRST |
+ CPU_TRANSFER_PAD_DWORD;
+
+ infoPtr->ColorExpandBase = pGlint->IOBase + OutputFIFO + 4;
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ Permedia2SetupForCPUToScreenColorExpandFill;
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ Permedia2SubsequentCPUToScreenColorExpandFill;
+ } else {
+ infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_LSBFIRST;
+
+ infoPtr->NumScanlineColorExpandBuffers = 1;
+ infoPtr->ScanlineColorExpandBuffers =
+ pGlint->XAAScanlineColorExpandBuffers;
+ pGlint->XAAScanlineColorExpandBuffers[0] =
+ pGlint->IOBase + OutputFIFO + 4;
+
+ infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
+ Permedia2SetupForScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
+ Permedia2SubsequentScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentColorExpandScanline =
+ Permedia2SubsequentColorExpandScanline;
+ }
+
+ infoPtr->ColorExpandRange = MAX_FIFO_ENTRIES;
+
+ infoPtr->WriteBitmap = Permedia2WriteBitmap;
+
+ if (pScrn->bitsPerPixel == 8)
+ infoPtr->WritePixmap = Permedia2WritePixmap8bpp;
+ else
+ if (pScrn->bitsPerPixel == 16)
+ infoPtr->WritePixmap = Permedia2WritePixmap16bpp;
+ else
+#if 0
+ if (pScrn->bitsPerPixel == 24) {
+ infoPtr->WritePixmap = Permedia2WritePixmap24bpp;
+ infoPtr->WritePixmapFlags |= NO_PLANEMASK;
+ }
+ else
+#endif
+ if (pScrn->bitsPerPixel == 32)
+ infoPtr->WritePixmap = Permedia2WritePixmap32bpp;
+
+ /* Now fixup if we are 24bpp */
+ if (pScrn->bitsPerPixel == 24) {
+ infoPtr->SolidFillFlags |= NO_PLANEMASK;
+ infoPtr->ScreenToScreenCopyFlags |= NO_PLANEMASK;
+ infoPtr->WriteBitmapFlags |= NO_PLANEMASK;
+ infoPtr->CPUToScreenColorExpandFillFlags |= NO_PLANEMASK;
+ infoPtr->ScanlineCPUToScreenColorExpandFillFlags |= NO_PLANEMASK;
+ infoPtr->Mono8x8PatternFillFlags |= NO_PLANEMASK;
+ }
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = pGlint->FbMapSize / (pScrn->displayWidth *
+ pScrn->bitsPerPixel / 8);
+
+ if (AvailFBArea.y2 > 2047) AvailFBArea.y2 = 2047;
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ return(XAAInit(pScreen, infoPtr));
+}
+
+static void Permedia2LoadCoord(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ if ((h != pGlint->h) || (w != pGlint->w)) {
+ pGlint->w = w;
+ pGlint->h = h;
+ GLINT_WRITE_REG(((h&0x0FFF)<<16)|(w&0x0FFF), RectangleSize);
+ }
+ if ((y != pGlint->y) || (x != pGlint->x)) {
+ pGlint->x = x;
+ pGlint->y = y;
+ GLINT_WRITE_REG(((y&0x0FFF)<<16)|(x&0x0FFF), RectangleOrigin);
+ }
+}
+
+
+void
+Permedia2Sync(ScrnInfoPtr pScrn)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ CHECKCLIPPING;
+
+ while (GLINT_READ_REG(DMACount) != 0);
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(0, GlintSync);
+ do {
+ while(GLINT_READ_REG(OutFIFOWords) == 0);
+#define Sync_tag 0x188
+ } while (GLINT_READ_REG(OutputFIFO) != Sync_tag);
+}
+
+static void
+Permedia2SetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ GLINT_WAIT(3);
+ GLINT_WRITE_REG(((y1&0x0fff)<<16)|(x1&0x0fff), ScissorMinXY);
+ GLINT_WRITE_REG(((y2&0x0fff)<<16)|(x2&0x0fff), ScissorMaxXY);
+ GLINT_WRITE_REG(1, ScissorMode);
+ pGlint->ClippingOn = TRUE;
+}
+
+static void
+Permedia2DisableClipping(ScrnInfoPtr pScrn)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ CHECKCLIPPING;
+}
+
+static void
+Permedia2SetupForScreenToScreenCopy2432bpp(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int transparency_color)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ pGlint->BltScanDirection = 0;
+ if (xdir == 1) pGlint->BltScanDirection |= XPositive;
+ if (ydir == 1) pGlint->BltScanDirection |= YPositive;
+
+ if (pScrn->bitsPerPixel == 24) {
+ GLINT_WAIT(4);
+ } else {
+ GLINT_WAIT(5);
+ DO_PLANEMASK(planemask);
+ }
+
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ if ((rop == GXset) || (rop == GXclear)) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ if ((rop == GXcopy) || (rop == GXcopyInverted)) {
+ GLINT_WRITE_REG(pGlint->pprod|FBRM_SrcEnable, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod|FBRM_SrcEnable|FBRM_DstEnable,
+ FBReadMode);
+ }
+ }
+ LOADROP(rop);
+}
+
+static void
+Permedia2SubsequentScreenToScreenCopy2432bpp(ScrnInfoPtr pScrn, int x1,
+ int y1, int x2, int y2, int w, int h)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_WAIT(4);
+ Permedia2LoadCoord(pScrn, x2, y2, w, h);
+ GLINT_WRITE_REG(((y1-y2)&0x0FFF)<<16 | ((x1-x2)&0x0FFF), FBSourceDelta);
+ GLINT_WRITE_REG(PrimitiveRectangle | pGlint->BltScanDirection, Render);
+}
+
+static void
+Permedia2SetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int transparency_color)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ pGlint->BltScanDirection = 0;
+ if (xdir == 1) pGlint->BltScanDirection |= XPositive;
+ if (ydir == 1) pGlint->BltScanDirection |= YPositive;
+
+ GLINT_WAIT(4);
+ DO_PLANEMASK(planemask);
+
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ if ((rop == GXset) || (rop == GXclear)) {
+ pGlint->FrameBufferReadMode = pGlint->pprod;
+ } else
+ if ((rop == GXcopy) || (rop == GXcopyInverted)) {
+ pGlint->FrameBufferReadMode = pGlint->pprod |FBRM_SrcEnable;
+ } else {
+ pGlint->FrameBufferReadMode = pGlint->pprod | FBRM_SrcEnable |
+ FBRM_DstEnable;
+ }
+ LOADROP(rop);
+}
+
+static void
+Permedia2SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ char align;
+
+ /* We can only use GXcopy for Packed modes */
+ if (pGlint->ROP != GXcopy) {
+ GLINT_WAIT(5);
+ GLINT_WRITE_REG(pGlint->FrameBufferReadMode, FBReadMode);
+ Permedia2LoadCoord(pScrn, x2, y2, w, h);
+ GLINT_WRITE_REG(((y1-y2)&0x0FFF)<<16 | ((x1-x2)&0x0FFF), FBSourceDelta);
+ } else {
+ align = (x2 & pGlint->bppalign) - (x1 & pGlint->bppalign);
+ GLINT_WAIT(6);
+ GLINT_WRITE_REG(pGlint->FrameBufferReadMode|FBRM_Packed, FBReadMode);
+ Permedia2LoadCoord(pScrn, x2>>pGlint->BppShift, y2,
+ (w+7)>>pGlint->BppShift, h);
+ GLINT_WRITE_REG(align<<29|x2<<16|(x2+w), PackedDataLimits);
+ GLINT_WRITE_REG(((y1-y2)&0x0FFF)<<16 | (((x1 & ~pGlint->bppalign)-(x2 & ~pGlint->bppalign))&0x0FFF), FBSourceDelta);
+ }
+
+ GLINT_WRITE_REG(PrimitiveRectangle | pGlint->BltScanDirection, Render);
+}
+
+
+
+static void
+Permedia2PolylinesThinSolidWrapper(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ GLINTPtr pGlint = GLINTPTR(infoRec->pScrn);
+ pGlint->CurrentGC = pGC;
+ if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn);
+ XAAPolyLines(pDraw, pGC, mode, npt, pPts);
+}
+
+static void
+Permedia2PolySegmentThinSolidWrapper(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ GLINTPtr pGlint = GLINTPTR(infoRec->pScrn);
+ pGlint->CurrentGC = pGC;
+ if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn);
+ XAAPolySegment(pDraw, pGC, nseg, pSeg);
+}
+
+static void
+Permedia2SetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_WAIT(6);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ GLINT_WRITE_REG(color, GLINTColor);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ LOADROP(rop);
+}
+
+static void
+Permedia2SubsequentHorVertLine(ScrnInfoPtr pScrn,int x,int y,int len,int dir)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_WAIT(6);
+ GLINT_WRITE_REG(x<<16, StartXDom);
+ GLINT_WRITE_REG(y<<16, StartY);
+ if (dir == DEGREES_0) {
+ GLINT_WRITE_REG(1<<16, dXDom);
+ GLINT_WRITE_REG(0<<16, dY);
+ } else {
+ GLINT_WRITE_REG(0<<16, dXDom);
+ GLINT_WRITE_REG(1<<16, dY);
+ }
+
+ GLINT_WRITE_REG(len, GLINTCount);
+ GLINT_WRITE_REG(PrimitiveLine, Render);
+}
+
+static void
+Permedia2SubsequentSolidBresenhamLine8bpp( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ cfbPrivGCPtr devPriv;
+
+ if(dmaj == dmin) {
+ GLINT_WAIT(6);
+ if(octant & YDECREASING) {
+ GLINT_WRITE_REG(-1<<16, dY);
+ } else {
+ GLINT_WRITE_REG(1<<16, dY);
+ }
+
+ if(octant & XDECREASING) {
+ GLINT_WRITE_REG(-1<<16, dXDom);
+ } else {
+ GLINT_WRITE_REG(1<<16, dXDom);
+ }
+
+ GLINT_WRITE_REG(x<<16, StartXDom);
+ GLINT_WRITE_REG(y<<16, StartY);
+ GLINT_WRITE_REG(len,GLINTCount);
+ GLINT_WRITE_REG(PrimitiveLine, Render);
+ return;
+ }
+
+ devPriv = cfbGetGCPrivate(pGlint->CurrentGC);
+
+ cfbBresS(devPriv->rop, devPriv->and, devPriv->xor,
+ (unsigned long*)pGlint->FbBase, pScrn->displayWidth >> 2,
+ (octant & XDECREASING) ? -1 : 1,
+ (octant & YDECREASING) ? -1 : 1,
+ (octant & YMAJOR) ? Y_AXIS : X_AXIS,
+ x, y, dmin + e, dmin, dmin - dmaj, len);
+}
+
+static void
+Permedia2SubsequentSolidBresenhamLine16bpp( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ cfbPrivGCPtr devPriv;
+
+ if(dmaj == dmin) {
+ GLINT_WAIT(6);
+ if(octant & YDECREASING) {
+ GLINT_WRITE_REG(-1<<16, dY);
+ } else {
+ GLINT_WRITE_REG(1<<16, dY);
+ }
+
+ if(octant & XDECREASING) {
+ GLINT_WRITE_REG(-1<<16, dXDom);
+ } else {
+ GLINT_WRITE_REG(1<<16, dXDom);
+ }
+
+ GLINT_WRITE_REG(x<<16, StartXDom);
+ GLINT_WRITE_REG(y<<16, StartY);
+ GLINT_WRITE_REG(len,GLINTCount);
+ GLINT_WRITE_REG(PrimitiveLine, Render);
+ return;
+ }
+
+ devPriv = cfbGetGCPrivate(pGlint->CurrentGC);
+
+ cfb16BresS(devPriv->rop, devPriv->and, devPriv->xor,
+ (unsigned long*)pGlint->FbBase, pScrn->displayWidth >> 1,
+ (octant & XDECREASING) ? -1 : 1,
+ (octant & YDECREASING) ? -1 : 1,
+ (octant & YMAJOR) ? Y_AXIS : X_AXIS,
+ x, y, dmin + e, dmin, dmin - dmaj, len);
+}
+
+static void
+Permedia2SubsequentSolidBresenhamLine32bpp( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ cfbPrivGCPtr devPriv;
+
+ if(dmaj == dmin) {
+ GLINT_WAIT(6);
+ if(octant & YDECREASING) {
+ GLINT_WRITE_REG(-1<<16, dY);
+ } else {
+ GLINT_WRITE_REG(1<<16, dY);
+ }
+
+ if(octant & XDECREASING) {
+ GLINT_WRITE_REG(-1<<16, dXDom);
+ } else {
+ GLINT_WRITE_REG(1<<16, dXDom);
+ }
+
+ GLINT_WRITE_REG(x<<16, StartXDom);
+ GLINT_WRITE_REG(y<<16, StartY);
+ GLINT_WRITE_REG(len,GLINTCount);
+ GLINT_WRITE_REG(PrimitiveLine, Render);
+ return;
+ }
+
+ devPriv = cfbGetGCPrivate(pGlint->CurrentGC);
+
+ cfb32BresS(devPriv->rop, devPriv->and, devPriv->xor,
+ (unsigned long*)pGlint->FbBase, pScrn->displayWidth,
+ (octant & XDECREASING) ? -1 : 1,
+ (octant & YDECREASING) ? -1 : 1,
+ (octant & YMAJOR) ? Y_AXIS : X_AXIS,
+ x, y, dmin + e, dmin, dmin - dmaj, len);
+}
+
+
+static void
+Permedia2SetupForFillRectSolid24bpp(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ pGlint->ForeGroundColor = color;
+
+ GLINT_WAIT(5);
+ GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
+ GLINT_WRITE_REG(color, ConstantColor);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ LOADROP(rop);
+}
+
+static void
+Permedia2SetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ REPLICATE(color);
+
+ GLINT_WAIT(6);
+ DO_PLANEMASK(planemask);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ GLINT_WRITE_REG(color, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
+ GLINT_WRITE_REG(color, ConstantColor);
+ /* We can use Packed mode for filling solid non-GXcopy rasters */
+ GLINT_WRITE_REG(pGlint->pprod|FBRM_DstEnable|FBRM_Packed, FBReadMode);
+ }
+ LOADROP(rop);
+}
+
+static void
+Permedia2SubsequentFillRectSolid24bpp(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ GLINT_WAIT(3);
+ Permedia2LoadCoord(pScrn, x, y, w, h);
+ GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive, Render);
+}
+
+static void
+Permedia2SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int speed = 0;
+
+ if (pGlint->ROP == GXcopy) {
+ GLINT_WAIT(3);
+ Permedia2LoadCoord(pScrn, x, y, w, h);
+ speed = FastFillEnable;
+ } else {
+ GLINT_WAIT(4);
+ Permedia2LoadCoord(pScrn, x>>pGlint->BppShift, y,
+ (w+7)>>pGlint->BppShift, h);
+ GLINT_WRITE_REG(x<<16|(x+w), PackedDataLimits);
+ speed = 0;
+ }
+ GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive | speed, Render);
+}
+
+static void MoveBYTE(
+ register CARD32* dest,
+ register unsigned char* src,
+ register int dwords
+)
+{
+ while(dwords) {
+ *dest = *src;
+ src += 1;
+ dest += 1;
+ dwords -= 1;
+ }
+}
+
+static void MoveWORDS(
+ register CARD32* dest,
+ register unsigned short* src,
+ register int dwords
+)
+{
+ while(dwords & ~0x01) {
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ src += 2;
+ dest += 2;
+ dwords -= 2;
+ }
+ switch(dwords) {
+ case 0: return;
+ case 1: *dest = *src;
+ return;
+ }
+}
+
+static void MoveDWORDS(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ *(dest + 2) = *(src + 2);
+ *(dest + 3) = *(src + 3);
+ src += 4;
+ dest += 4;
+ dwords -= 4;
+ }
+ if (!dwords) return;
+ *dest = *src;
+ if (dwords == 1) return;
+ *(dest + 1) = *(src + 1);
+ if (dwords == 2) return;
+ *(dest + 2) = *(src + 2);
+}
+
+static void
+Permedia2SetupForMono8x8PatternFill24bpp(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ if (bg == -1) pGlint->FrameBufferReadMode = -1;
+ else pGlint->FrameBufferReadMode = 0;
+
+ pGlint->ForeGroundColor = fg;
+ pGlint->BackGroundColor = bg;
+ REPLICATE(pGlint->ForeGroundColor);
+ REPLICATE(pGlint->BackGroundColor);
+
+ GLINT_WAIT(12);
+ GLINT_WRITE_REG((patternx & 0xFF), AreaStipplePattern0);
+ GLINT_WRITE_REG((patternx & 0xFF00) >> 8, AreaStipplePattern1);
+ GLINT_WRITE_REG((patternx & 0xFF0000) >> 16, AreaStipplePattern2);
+ GLINT_WRITE_REG((patternx & 0xFF000000) >> 24, AreaStipplePattern3);
+ GLINT_WRITE_REG((patterny & 0xFF), AreaStipplePattern4);
+ GLINT_WRITE_REG((patterny & 0xFF00) >> 8, AreaStipplePattern5);
+ GLINT_WRITE_REG((patterny & 0xFF0000) >> 16, AreaStipplePattern6);
+ GLINT_WRITE_REG((patterny & 0xFF000000) >> 24, AreaStipplePattern7);
+
+ GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ LOADROP(rop);
+}
+
+static void
+Permedia2SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ if (bg == -1) pGlint->FrameBufferReadMode = -1;
+ else pGlint->FrameBufferReadMode = 0;
+
+ pGlint->ForeGroundColor = fg;
+ pGlint->BackGroundColor = bg;
+ REPLICATE(pGlint->ForeGroundColor);
+ REPLICATE(pGlint->BackGroundColor);
+
+ GLINT_WAIT(13);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG((patternx & 0xFF), AreaStipplePattern0);
+ GLINT_WRITE_REG((patternx & 0xFF00) >> 8, AreaStipplePattern1);
+ GLINT_WRITE_REG((patternx & 0xFF0000) >> 16, AreaStipplePattern2);
+ GLINT_WRITE_REG((patternx & 0xFF000000) >> 24, AreaStipplePattern3);
+ GLINT_WRITE_REG((patterny & 0xFF), AreaStipplePattern4);
+ GLINT_WRITE_REG((patterny & 0xFF00) >> 8, AreaStipplePattern5);
+ GLINT_WRITE_REG((patterny & 0xFF0000) >> 16, AreaStipplePattern6);
+ GLINT_WRITE_REG((patterny & 0xFF000000) >> 24, AreaStipplePattern7);
+
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ LOADROP(rop);
+}
+
+static void
+Permedia2SubsequentMono8x8PatternFillRect24bpp(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_WAIT(8);
+ Permedia2LoadCoord(pScrn, x, y, w, h);
+
+ if (pGlint->FrameBufferReadMode != -1) {
+ GLINT_WRITE_REG(pGlint->BackGroundColor, ConstantColor);
+ GLINT_WRITE_REG(patternx<<7|patterny<<12| ASM_InvertPattern |
+ UNIT_ENABLE, AreaStippleMode);
+ GLINT_WRITE_REG(AreaStippleEnable | XPositive |
+ YPositive | PrimitiveRectangle, Render);
+ }
+
+ GLINT_WRITE_REG(pGlint->ForeGroundColor, ConstantColor);
+ GLINT_WRITE_REG(patternx<<7|patterny<<12|UNIT_ENABLE, AreaStippleMode);
+ GLINT_WRITE_REG(AreaStippleEnable | XPositive | YPositive |
+ PrimitiveRectangle, Render);
+}
+
+static void
+Permedia2SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_WAIT(9);
+ Permedia2LoadCoord(pScrn, x, y, w, h);
+
+ if (pGlint->FrameBufferReadMode != -1) {
+ if (pGlint->ROP == GXcopy) {
+ GLINT_WRITE_REG(pGlint->BackGroundColor, FBBlockColor);
+ GLINT_WRITE_REG(ASM_InvertPattern|patternx<<7|patterny<<12|
+ UNIT_ENABLE, AreaStippleMode);
+ GLINT_WRITE_REG(AreaStippleEnable | FastFillEnable |
+ XPositive | YPositive | PrimitiveRectangle, Render);
+ } else {
+ GLINT_WRITE_REG(pGlint->ForeGroundColor, ConstantColor);
+ GLINT_WRITE_REG(pGlint->BackGroundColor, Texel0);
+ GLINT_WRITE_REG(patternx<<7|patterny<<12|
+ UNIT_ENABLE, AreaStippleMode);
+ GLINT_WRITE_REG(AreaStippleEnable | XPositive | TextureEnable |
+ YPositive | PrimitiveRectangle, Render);
+ return;
+ }
+ }
+
+ if (pGlint->ROP == GXcopy) {
+ GLINT_WRITE_REG(pGlint->ForeGroundColor, FBBlockColor);
+ pGlint->FrameBufferReadMode = FastFillEnable;
+ } else {
+ GLINT_WRITE_REG(pGlint->ForeGroundColor, ConstantColor);
+ pGlint->FrameBufferReadMode = 0;
+ }
+ GLINT_WRITE_REG(patternx<<7|patterny<<12|UNIT_ENABLE, AreaStippleMode);
+ GLINT_WRITE_REG(AreaStippleEnable | pGlint->FrameBufferReadMode |
+ XPositive | YPositive | PrimitiveRectangle, Render);
+}
+
+static void
+Permedia2SetupForCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int dobackground = 0;
+
+ if (bg != -1) dobackground |= ForceBackgroundColor;
+
+ GLINT_WAIT(7);
+ DO_PLANEMASK(planemask);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+
+ pGlint->ForeGroundColor = fg;
+ pGlint->BackGroundColor = bg;
+ REPLICATE(fg);
+ REPLICATE(bg);
+
+ if ((pScrn->bitsPerPixel != 24) && (rop == GXcopy)) {
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ if (dobackground) {
+ GLINT_WRITE_REG(bg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ }
+ GLINT_WRITE_REG(0, RasterizerMode);
+ pGlint->FrameBufferReadMode = FastFillEnable;
+ } else {
+ GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
+ GLINT_WRITE_REG(BitMaskPackingEachScanline|dobackground,RasterizerMode);
+ GLINT_WRITE_REG(fg, ConstantColor);
+ if (dobackground) {
+ pGlint->FrameBufferReadMode = TextureEnable;
+ GLINT_WRITE_REG(bg, Texel0);
+ } else
+ pGlint->FrameBufferReadMode = 0;
+ }
+ LOADROP(rop);
+}
+
+static void
+Permedia2SubsequentCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int dwords = ((w + 31) >> 5) * h;
+
+ GLINT_WAIT(8);
+ Permedia2LoadCoord(pScrn, x, y, w, h);
+
+ if ((pGlint->ROP == GXcopy) && (pGlint->BackGroundColor != -1)) {
+ GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive | FastFillEnable, Render);
+ REPLICATE(pGlint->ForeGroundColor)
+ GLINT_WRITE_REG(pGlint->ForeGroundColor, FBBlockColor);
+ }
+
+ GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive | SyncOnBitMask |
+ pGlint->FrameBufferReadMode, Render);
+ GLINT_WRITE_REG((dwords - 1)<<16 | 0x0D, OutputFIFO);
+ GLINT_WAIT(dwords);
+}
+
+static void
+Permedia2SetupForScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int dobackground = 0;
+
+ if (bg != -1) dobackground |= ForceBackgroundColor;
+ pGlint->BackGroundColor = bg;
+ pGlint->ForeGroundColor = fg;
+ REPLICATE(fg);
+ REPLICATE(bg);
+ GLINT_WAIT(7);
+ DO_PLANEMASK(planemask);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod|FBRM_DstEnable, FBReadMode);
+ }
+ if ((rop == GXcopy) && (pGlint->BackGroundColor == -1)) {
+ pGlint->FrameBufferReadMode = FastFillEnable;
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ GLINT_WRITE_REG(0,RasterizerMode);
+ } else {
+ GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
+ GLINT_WRITE_REG(fg, ConstantColor);
+ GLINT_WRITE_REG(BitMaskPackingEachScanline|dobackground,RasterizerMode);
+ if (dobackground) {
+ GLINT_WRITE_REG(bg, Texel0);
+ pGlint->FrameBufferReadMode = TextureEnable;
+ } else {
+ pGlint->FrameBufferReadMode = 0;
+ }
+ }
+ LOADROP(rop);
+}
+
+static void
+Permedia2SubsequentScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ pGlint->dwords = ((w + 31) >> 5); /* dwords per scanline */
+
+ pGlint->cpucount = h;
+
+ GLINT_WAIT(6);
+ Permedia2LoadCoord(pScrn, x, y, w, h);
+ GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive | pGlint->FrameBufferReadMode | SyncOnBitMask, Render);
+ GLINT_WRITE_REG(((pGlint->dwords*h)-1)<<16 | 0x0D, OutputFIFO);
+ GLINT_WAIT(pGlint->dwords);
+ pGlint->cpucount--;
+}
+
+static void
+Permedia2SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ if (pGlint->cpucount--)
+ GLINT_WAIT(pGlint->dwords);
+}
+
+
+static void
+Permedia2WriteBitmap(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ unsigned char *srcpntr;
+ int dwords, height, mode;
+ Bool SecondPass = FALSE;
+
+ w += skipleft;
+ x -= skipleft;
+ dwords = (w + 31) >> 5;
+
+ Permedia2SetClippingRectangle(pScrn,x+skipleft,y,x+w,y+h);
+
+ if (pScrn->bitsPerPixel == 24) {
+ GLINT_WAIT(10);
+ } else {
+ GLINT_WAIT(11);
+ DO_PLANEMASK(planemask);
+ }
+ LOADROP(rop);
+ Permedia2LoadCoord(pScrn, x&0xFFFF, y, w, h);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ if ((pScrn->bitsPerPixel != 24) && (rop == GXcopy)) {
+ mode = FastFillEnable;
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ GLINT_WRITE_REG(0, RasterizerMode);
+ } else {
+ mode = 0;
+ GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
+ GLINT_WRITE_REG(BitMaskPackingEachScanline,RasterizerMode);
+ }
+
+ if(bg == -1) {
+ /* >>>>> set fg <<<<<<<< */
+ REPLICATE(fg);
+ if ((pScrn->bitsPerPixel != 24) && (rop == GXcopy)) {
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(fg, ConstantColor);
+ }
+ } else if(rop == GXcopy) {
+ /* >>>>> set bg <<<<<<< */
+ /* >>>>> draw rect (x,y,w,h) */
+ REPLICATE(bg);
+ if ((pScrn->bitsPerPixel != 24) && (rop == GXcopy)) {
+ GLINT_WRITE_REG(bg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(bg, ConstantColor);
+ }
+ GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive |mode,Render);
+ /* >>>>>> set fg <<<<<< */
+ REPLICATE(fg);
+ if ((pScrn->bitsPerPixel != 24) && (rop == GXcopy)) {
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(fg, ConstantColor);
+ }
+ } else {
+ SecondPass = TRUE;
+ /* >>>>> set fg <<<<<<< */
+ REPLICATE(fg);
+ if ((pScrn->bitsPerPixel != 24) && (rop == GXcopy)) {
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(fg, ConstantColor);
+ }
+ }
+
+ /* >>>>>>>>> initiate transfer (x,y,w,h). Skipleft pixels on the
+ left edge will be clipped <<<<<< */
+
+SECOND_PASS:
+ GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive | mode | SyncOnBitMask, Render);
+
+ height = h;
+ srcpntr = src;
+ while(height--) {
+ GLINT_WAIT(dwords);
+ /* 0x0D is the TAG value for BitMaskPattern */
+ GLINT_WRITE_REG(((dwords - 1) << 16) | 0x0D, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32 *)srcpntr, dwords);
+ srcpntr += srcwidth;
+ }
+
+ if(SecondPass) {
+ SecondPass = FALSE;
+ /* >>>>>> invert bitmask and set bg <<<<<<<< */
+ REPLICATE(bg);
+ GLINT_WAIT(3);
+ if ((pScrn->bitsPerPixel != 24) && (rop == GXcopy)) {
+ GLINT_WRITE_REG(InvertBitMask, RasterizerMode);
+ GLINT_WRITE_REG(bg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(InvertBitMask|BitMaskPackingEachScanline,
+ RasterizerMode);
+ GLINT_WRITE_REG(bg, ConstantColor);
+ }
+ goto SECOND_PASS;
+ }
+
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(0, RasterizerMode);
+ Permedia2DisableClipping(pScrn);
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+static void
+Permedia2WritePixmap8bpp(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int skipleft, dwords, count;
+ CARD32* srcp;
+ unsigned char *srcpbyte;
+ Bool FastTexLoad = FALSE;
+
+ GLINT_WAIT(3);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(0, RasterizerMode);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_Packed, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+
+ dwords = (w + 3) >> 2;
+ if((!(x&3)) && (!(w&3))) FastTexLoad = TRUE;
+ if((rop != GXcopy) || (planemask != ~0))
+ FastTexLoad = FALSE;
+
+ if (rop == GXcopy) {
+ skipleft = 0;
+ } else {
+ if((skipleft = (long)src & 0x03)) {
+ skipleft /= (bpp>>3);
+
+ x -= skipleft;
+ w += skipleft;
+
+ src = (unsigned char*)((long)src & ~0x03);
+ }
+ }
+
+
+ if(FastTexLoad) {
+ int address;
+
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode);
+ Permedia2Sync(pScrn); /* we are not using the rasterizer */
+ while(h--) {
+ count = dwords;
+ address = ((y * pScrn->displayWidth) + x) >> 2;
+ srcp = (CARD32*)src;
+ GLINT_WRITE_REG(address, TextureDownloadOffset);
+ while(count >= MAX_FIFO_ENTRIES) {
+ GLINT_WAIT(MAX_FIFO_ENTRIES);
+ /* (0x11 << 4) | 0x0D is the TAG for TextureData */
+ GLINT_WRITE_REG(((MAX_FIFO_ENTRIES - 2) << 16) | (0x11 << 4) |
+ 0x0D, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, MAX_FIFO_ENTRIES - 1);
+ count -= MAX_FIFO_ENTRIES - 1;
+ address += MAX_FIFO_ENTRIES - 1;
+ srcp += MAX_FIFO_ENTRIES - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count + 1);
+ /* (0x11 << 4) | 0x0D is the TAG for TextureData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D,
+ OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, count);
+ }
+ src += srcwidth;
+ y++;
+ }
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode);
+ } else {
+ char align = (x & pGlint->bppalign);
+
+
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ if (rop == GXcopy) {
+ GLINT_WAIT(6);
+ Permedia2LoadCoord(pScrn, x>>pGlint->BppShift, y,
+ (w+pGlint->bppalign)>>pGlint->BppShift, h);
+ GLINT_WRITE_REG(align<<29|x<<16|(x+w), PackedDataLimits);
+ } else {
+ Permedia2SetClippingRectangle(pScrn,x+skipleft,y,x+w,y+h);
+ GLINT_WAIT(5);
+ Permedia2LoadCoord(pScrn, x, y, w, h);
+ }
+ LOADROP(rop);
+ GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive |
+ SyncOnHostData, Render);
+
+ if (rop == GXcopy) {
+ while(h--) {
+ count = dwords;
+ srcp = (CARD32*)src;
+ while(count >= MAX_FIFO_ENTRIES) {
+ GLINT_WAIT(MAX_FIFO_ENTRIES);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((MAX_FIFO_ENTRIES - 2) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, MAX_FIFO_ENTRIES - 1);
+ count -= MAX_FIFO_ENTRIES - 1;
+ srcp += MAX_FIFO_ENTRIES - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count + 1);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, count);
+ }
+ src += srcwidth;
+ }
+ } else {
+ while(h--) {
+ count = w;
+ srcpbyte = (unsigned char *)src;
+ while(count >= MAX_FIFO_ENTRIES) {
+ GLINT_WAIT(MAX_FIFO_ENTRIES);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((MAX_FIFO_ENTRIES - 2) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveBYTE((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (unsigned char *)srcpbyte, MAX_FIFO_ENTRIES - 1);
+ count -= MAX_FIFO_ENTRIES - 1;
+ srcpbyte += MAX_FIFO_ENTRIES - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count + 1);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveBYTE((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (unsigned char *)srcpbyte, count);
+ }
+ src += srcwidth;
+ }
+ }
+ }
+
+ Permedia2DisableClipping(pScrn);
+ SET_SYNC_FLAG(infoRec);
+}
+
+static void
+Permedia2WritePixmap16bpp(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int skipleft, dwords, count;
+ CARD32* srcp;
+ unsigned short* srcpword;
+ Bool FastTexLoad;
+
+ GLINT_WAIT(3);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(0, RasterizerMode);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_Packed, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+
+ FastTexLoad = FALSE;
+ dwords = (w + 1) >> 1;
+ if((!(x&1)) && (!(w&1))) FastTexLoad = TRUE;
+ if((rop != GXcopy) || (planemask != ~0))
+ FastTexLoad = FALSE;
+
+ if (rop == GXcopy) {
+ skipleft = 0;
+ } else {
+ if((skipleft = (long)src & 0x03L)) {
+ skipleft /= (bpp>>3);
+
+ x -= skipleft;
+ w += skipleft;
+
+ src = (unsigned char*)((long)src & ~0x03L);
+ }
+ }
+
+ if(FastTexLoad) {
+ int address;
+
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode);
+ Permedia2Sync(pScrn); /* we are not using the rasterizer */
+ while(h--) {
+ count = dwords;
+ address = ((y * pScrn->displayWidth) + x) >> 1;
+ srcp = (CARD32*)src;
+ GLINT_WRITE_REG(address, TextureDownloadOffset);
+ while(count >= MAX_FIFO_ENTRIES) {
+ GLINT_WAIT(MAX_FIFO_ENTRIES);
+ /* (0x11 << 4) | 0x0D is the TAG for TextureData */
+ GLINT_WRITE_REG(((MAX_FIFO_ENTRIES - 2) << 16) | (0x11 << 4) |
+ 0x0D, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, MAX_FIFO_ENTRIES - 1);
+ count -= MAX_FIFO_ENTRIES - 1;
+ address += MAX_FIFO_ENTRIES - 1;
+ srcp += MAX_FIFO_ENTRIES - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count + 1);
+ /* (0x11 << 4) | 0x0D is the TAG for TextureData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D,
+ OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, count);
+ }
+ src += srcwidth;
+ y++;
+ }
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode);
+ } else {
+ char align = (x & pGlint->bppalign);
+
+
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ if (rop == GXcopy) {
+ GLINT_WAIT(6);
+ Permedia2LoadCoord(pScrn, x>>pGlint->BppShift, y,
+ (w+pGlint->bppalign)>>pGlint->BppShift, h);
+ GLINT_WRITE_REG(align<<29|x<<16|(x+w), PackedDataLimits);
+ } else {
+ Permedia2SetClippingRectangle(pScrn,x+skipleft,y,x+w,y+h);
+ GLINT_WAIT(5);
+ Permedia2LoadCoord(pScrn, x, y, w, h);
+ }
+ LOADROP(rop);
+ GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive |
+ SyncOnHostData, Render);
+
+ if (rop == GXcopy) {
+ while(h--) {
+ count = dwords;
+ srcp = (CARD32*)src;
+ while(count >= MAX_FIFO_ENTRIES) {
+ GLINT_WAIT(MAX_FIFO_ENTRIES);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((MAX_FIFO_ENTRIES - 2) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, MAX_FIFO_ENTRIES - 1);
+ count -= MAX_FIFO_ENTRIES - 1;
+ srcp += MAX_FIFO_ENTRIES - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count + 1);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, count);
+ }
+ src += srcwidth;
+ }
+ } else {
+ while(h--) {
+ count = w;
+ srcpword = (unsigned short *)src;
+ while(count >= MAX_FIFO_ENTRIES) {
+ GLINT_WAIT(MAX_FIFO_ENTRIES);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((MAX_FIFO_ENTRIES - 2) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (unsigned short *)srcpword, MAX_FIFO_ENTRIES - 1);
+ count -= MAX_FIFO_ENTRIES - 1;
+ srcpword += MAX_FIFO_ENTRIES - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count + 1);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (unsigned short *)srcpword, count);
+ }
+ src += srcwidth;
+ }
+ }
+ }
+
+ Permedia2DisableClipping(pScrn);
+ SET_SYNC_FLAG(infoRec);
+}
+
+static void
+Permedia2WritePixmap24bpp(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int skipleft = 0, dwords, count;
+ unsigned char* srcpbyte;
+ CARD32* srcp;
+
+ GLINT_WAIT(3);
+ GLINT_WRITE_REG(0, RasterizerMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+
+ dwords = ((w+1)*3)>>2;
+ if((skipleft = (long)src & 0x03L)) {
+ skipleft = 4 - skipleft;
+
+ x -= skipleft;
+ w += skipleft;
+
+ src = (unsigned char*)(src - (3*skipleft));
+ }
+
+ {
+ Permedia2SetClippingRectangle(pScrn,x+skipleft,y,x+w,y+h);
+
+ GLINT_WAIT(4);
+ Permedia2LoadCoord(pScrn, x&0xFFFF, y, w, h);
+ LOADROP(rop);
+ GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive |
+ SyncOnHostData, Render);
+
+#if 1
+ while(h--) {
+ count = w;
+ srcpbyte = (unsigned char *)src;
+ while(count >= MAX_FIFO_ENTRIES) {
+ GLINT_WAIT(MAX_FIFO_ENTRIES);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((MAX_FIFO_ENTRIES - 2) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveBYTE((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (unsigned char *)srcpbyte, MAX_FIFO_ENTRIES - 1);
+ count -= MAX_FIFO_ENTRIES - 1;
+ srcpbyte += MAX_FIFO_ENTRIES - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count + 1);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveBYTE((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (unsigned char *)srcpbyte, count);
+ }
+ src += srcwidth;
+#else
+ while(h--) {
+ count = dwords;
+ srcp = (CARD32*)src;
+ while(count >= MAX_FIFO_ENTRIES) {
+ GLINT_WAIT(MAX_FIFO_ENTRIES);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((MAX_FIFO_ENTRIES - 2) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, MAX_FIFO_ENTRIES - 1);
+ count -= MAX_FIFO_ENTRIES - 1;
+ srcp += MAX_FIFO_ENTRIES - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count + 1);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, count);
+ }
+ src += srcwidth;
+#endif
+ }
+ }
+
+ Permedia2DisableClipping(pScrn);
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+static void
+Permedia2WritePixmap32bpp(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int skipleft, dwords, count;
+ CARD32* srcp;
+ Bool FastTexLoad;
+
+ GLINT_WAIT(3);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(0, RasterizerMode);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+
+ FastTexLoad = TRUE;
+ dwords = w;
+ if((rop != GXcopy) || (planemask != ~0))
+ FastTexLoad = FALSE;
+
+ if (!FastTexLoad) {
+ if((skipleft = (long)src & 0x03L)) {
+ skipleft /= (bpp>>3);
+
+ x -= skipleft;
+ w += skipleft;
+
+ src = (unsigned char*)((long)src & ~0x03L);
+ }
+ }
+
+ if(FastTexLoad) {
+ int address;
+
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode);
+ Permedia2Sync(pScrn); /* we are not using the rasterizer */
+ while(h--) {
+ count = dwords;
+ address = (y * pScrn->displayWidth) + x;
+ srcp = (CARD32*)src;
+ GLINT_WRITE_REG(address, TextureDownloadOffset);
+ while(count >= MAX_FIFO_ENTRIES) {
+ GLINT_WAIT(MAX_FIFO_ENTRIES);
+ /* (0x11 << 4) | 0x0D is the TAG for TextureData */
+ GLINT_WRITE_REG(((MAX_FIFO_ENTRIES - 2) << 16) | (0x11 << 4) |
+ 0x0D, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, MAX_FIFO_ENTRIES - 1);
+ count -= MAX_FIFO_ENTRIES - 1;
+ address += MAX_FIFO_ENTRIES - 1;
+ srcp += MAX_FIFO_ENTRIES - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count + 1);
+ /* (0x11 << 4) | 0x0D is the TAG for TextureData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D,
+ OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, count);
+ }
+ src += srcwidth;
+ y++;
+ }
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode);
+ } else {
+ Permedia2SetClippingRectangle(pScrn,x+skipleft,y,x+w,y+h);
+
+ GLINT_WAIT(6);
+ Permedia2LoadCoord(pScrn, x, y, w, h);
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ LOADROP(rop);
+ GLINT_WRITE_REG(PrimitiveRectangle | XPositive | YPositive |
+ SyncOnHostData, Render);
+
+ while(h--) {
+ count = dwords;
+ srcp = (CARD32*)src;
+ while(count >= MAX_FIFO_ENTRIES) {
+ GLINT_WAIT(MAX_FIFO_ENTRIES);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((MAX_FIFO_ENTRIES - 2) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, MAX_FIFO_ENTRIES - 1);
+ count -= MAX_FIFO_ENTRIES - 1;
+ srcp += MAX_FIFO_ENTRIES - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count + 1);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, count);
+ }
+ src += srcwidth;
+ }
+ }
+
+ Permedia2DisableClipping(pScrn);
+ SET_SYNC_FLAG(infoRec);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_dac.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_dac.c
new file mode 100644
index 000000000..a188a7596
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_dac.c
@@ -0,0 +1,537 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane <alanh@fairlite.demon.co.uk>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ * Dirk Hohndel, <hohndel@suse.de>
+ * Stefan Dirsch, <sndirsch@suse.de>
+ * Helmut Fahrion, <hf@suse.de>
+ *
+ * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and
+ * Siemens Nixdorf Informationssysteme
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_dac.c,v 1.16 1999/07/04 06:39:01 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "glint_regs.h"
+#include "glint.h"
+
+#define INITIALFREQERR 100000
+#define MINCLK 110000 /* VCO frequency range */
+#define MAXCLK 250000
+
+static int
+Shiftbpp(ScrnInfoPtr pScrn, int value)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ /* shift horizontal timings for 64bit VRAM's or 32bit SGRAMs */
+ int logbytesperaccess = 2;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ value >>= logbytesperaccess;
+ pGlint->BppShift = logbytesperaccess;
+ break;
+ case 16:
+ if (pGlint->DoubleBuffer) {
+ value >>= (logbytesperaccess-2);
+ pGlint->BppShift = logbytesperaccess-2;
+ } else {
+ value >>= (logbytesperaccess-1);
+ pGlint->BppShift = logbytesperaccess-1;
+ }
+ break;
+ case 24:
+ value *= 3;
+ value >>= logbytesperaccess;
+ pGlint->BppShift = logbytesperaccess;
+ break;
+ case 32:
+ value >>= (logbytesperaccess-2);
+ pGlint->BppShift = logbytesperaccess-2;
+ break;
+ }
+ return (value);
+}
+
+static unsigned long
+PM2DAC_CalculateMNPCForClock
+(
+ unsigned long reqclock, /* In kHz units */
+ unsigned long refclock, /* In kHz units */
+ unsigned char *rm, /* M Out */
+ unsigned char *rn, /* N Out */
+ unsigned char *rp /* P Out */
+ )
+{
+ unsigned char m, n, p;
+ unsigned long f;
+ long freqerr, lowestfreqerr = INITIALFREQERR;
+ unsigned long clock,actualclock = 0;
+
+ for (n = 2; n <= 14; n++) {
+ for (m = 2; m != 0; m++) { /* this is a char, so this counts to 255 */
+ f = refclock * m / n;
+ if ( (f < MINCLK) || (f > MAXCLK) )
+ continue;
+ for (p = 0; p <= 4; p++) {
+ clock = f >> p;
+ freqerr = reqclock - clock;
+ if (freqerr < 0)
+ freqerr = -freqerr;
+ if (freqerr < lowestfreqerr) {
+ *rn = n;
+ *rm = m;
+ *rp = p;
+ lowestfreqerr = freqerr;
+ actualclock = clock;
+#ifdef DEBUG
+ ErrorF("Best %ld diff %ld\n",actualclock,freqerr);
+#endif
+ }
+ }
+ }
+ }
+
+ return(actualclock);
+}
+
+Bool
+Permedia2Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ GLINTRegPtr pReg = &pGlint->ModeReg;
+ CARD32 temp1, temp2, temp3, temp4;
+
+ pReg->glintRegs[Aperture0 >> 3] = 0;
+ pReg->glintRegs[Aperture1 >> 3] = 0;
+ pReg->glintRegs[PMFramebufferWriteMask >> 3] = 0xFFFFFFFF;
+ pReg->glintRegs[PMBypassWriteMask >> 3] = 0xFFFFFFFF;
+
+ if (pGlint->UsePCIRetry) {
+ pReg->glintRegs[DFIFODis >> 3] = 1;
+ pReg->glintRegs[FIFODis >> 3] = 3;
+ } else {
+ pReg->glintRegs[DFIFODis >> 3] = 0;
+ pReg->glintRegs[FIFODis >> 3] = 1;
+ }
+
+ if (pGlint->UseBlockWrite)
+ pReg->glintRegs[PMMemConfig >> 3] = GLINT_READ_REG(PMMemConfig) | 1<<21;
+
+
+ temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay;
+ temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay;
+ temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart;
+ temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+
+ pReg->glintRegs[PMHTotal >> 3] = Shiftbpp(pScrn,mode->CrtcHTotal);
+ pReg->glintRegs[PMHsEnd >> 3] = Shiftbpp(pScrn, temp1 + temp3);
+ pReg->glintRegs[PMHsStart >> 3] = Shiftbpp(pScrn, temp1);
+ pReg->glintRegs[PMHbEnd >> 3] =
+ Shiftbpp(pScrn,mode->CrtcHTotal-mode->CrtcHDisplay);
+ pReg->glintRegs[PMScreenStride >> 3] =
+ Shiftbpp(pScrn,pScrn->displayWidth>>1);
+
+ pReg->glintRegs[PMVTotal >> 3] = mode->CrtcVTotal;
+ pReg->glintRegs[PMVsEnd >> 3] = temp2 + temp4;
+ pReg->glintRegs[PMVsStart >> 3] = temp2;
+ pReg->glintRegs[PMVbEnd >> 3] = mode->CrtcVTotal - mode->CrtcVDisplay;
+
+ /* The hw cursor needs /VSYNC to recognize vert retrace. We'll stick
+ both sync lines to active low here and if needed invert them
+ using the RAMDAC's MCR below. */
+ pReg->glintRegs[PMVideoControl >> 3] =
+ (1 << 5) | (1 << 3) | 1;
+
+ if (pScrn->bitsPerPixel > 8) {
+ /* When != 8bpp then we stick the RAMDAC into 64bit mode */
+ /* And reduce the horizontal timings by half */
+ pReg->glintRegs[PMVideoControl >> 3] |= 1<<16;
+ pReg->glintRegs[PMHTotal >> 3] >>= 1;
+ pReg->glintRegs[PMHsEnd >> 3] >>= 1;
+ pReg->glintRegs[PMHsStart >> 3] >>= 1;
+ pReg->glintRegs[PMHbEnd >> 3] >>= 1;
+ }
+
+ pReg->glintRegs[VClkCtl >> 3] = (GLINT_READ_REG(VClkCtl) & 0xFFFFFFFC);
+ pReg->glintRegs[PMScreenBase >> 3] = 0;
+ pReg->glintRegs[PMHTotal >> 3] -= 1;
+ pReg->glintRegs[PMHsStart >> 3] -= 1;
+ pReg->glintRegs[PMVTotal >> 3] -= 1;
+
+ pReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig) & 0xFFFFFFDD;
+
+ pReg->DacRegs[PM2DACIndexMDCR] = 0x00; /* Disable Overlay */
+
+ {
+ /* Get the programmable clock values */
+ unsigned char m,n,p;
+ unsigned long clockused;
+
+ clockused = PM2DAC_CalculateMNPCForClock(mode->Clock,pGlint->RefClock,
+ &m,&n,&p);
+ pReg->DacRegs[PM2DACIndexClockAM] = m;
+ pReg->DacRegs[PM2DACIndexClockAN] = n;
+ pReg->DacRegs[PM2DACIndexClockAP] = p|0x08;
+ }
+
+ if (pGlint->MemClock) {
+ /* Get the memory clock values */
+ unsigned char m,n,p;
+ unsigned long clockused;
+
+ clockused = PM2DAC_CalculateMNPCForClock(pGlint->MemClock*1000,
+ pGlint->RefClock,&m,&n,&p);
+ pReg->DacRegs[PM2DACIndexMemClockM] = m;
+ pReg->DacRegs[PM2DACIndexMemClockN] = n;
+ pReg->DacRegs[PM2DACIndexMemClockP] = p;
+ }
+
+ if (pScrn->rgbBits == 8)
+ pReg->DacRegs[PM2DACIndexMCR] = 0x02; /* 8bit DAC */
+ else
+ pReg->DacRegs[PM2DACIndexMCR] = 0x00; /* 6bit DAC */
+
+ if (!(mode->Flags & V_PHSYNC))
+ pReg->DacRegs[PM2DACIndexMCR] |= 0x04; /* invert hsync */
+ if (!(mode->Flags & V_PVSYNC))
+ pReg->DacRegs[PM2DACIndexMCR] |= 0x08; /* invert vsync */
+
+ switch (pScrn->bitsPerPixel)
+ {
+ case 8:
+ pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | PM2DAC_GRAPHICS |
+ PM2DAC_CI8;
+ break;
+ case 16:
+ if (pScrn->depth == 15) {
+ pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | PM2DAC_TRUECOLOR|
+ PM2DAC_GRAPHICS | PM2DAC_5551;
+ } else {
+ pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | PM2DAC_TRUECOLOR|
+ PM2DAC_GRAPHICS | PM2DAC_565;
+ }
+ break;
+ case 24:
+ pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB | PM2DAC_TRUECOLOR|
+ PM2DAC_GRAPHICS | PM2DAC_PACKED;
+ break;
+ case 32:
+ pReg->DacRegs[PM2DACIndexCMR] = PM2DAC_RGB |
+ PM2DAC_GRAPHICS | PM2DAC_8888;
+ if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
+ pReg->DacRegs[PM2DACIndexColorKeyControl] = 0x11;
+ pReg->DacRegs[PM2DACIndexColorKeyOverlay] = 0xFF;
+ } else
+ pReg->DacRegs[PM2DACIndexCMR] |= PM2DAC_TRUECOLOR;
+ break;
+ }
+
+ return(TRUE);
+}
+
+void
+Permedia2Save(ScrnInfoPtr pScrn, GLINTRegPtr glintReg)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int i;
+
+ glintReg->glintRegs[Aperture0 >> 3] = GLINT_READ_REG(Aperture0);
+ glintReg->glintRegs[Aperture1 >> 3] = GLINT_READ_REG(Aperture1);
+ glintReg->glintRegs[PMFramebufferWriteMask >> 3] =
+ GLINT_READ_REG(PMFramebufferWriteMask);
+ glintReg->glintRegs[PMBypassWriteMask >> 3] = GLINT_READ_REG(PMBypassWriteMask);
+ glintReg->glintRegs[DFIFODis >> 3] = GLINT_READ_REG(DFIFODis);
+ glintReg->glintRegs[FIFODis >> 3] = GLINT_READ_REG(FIFODis);
+ /* We only muck about with PMMemConfig, if user wants to */
+ if (pGlint->UseBlockWrite)
+ glintReg->glintRegs[PMMemConfig >> 3] = GLINT_READ_REG(PMMemConfig);
+ glintReg->glintRegs[PMHTotal >> 3] = GLINT_READ_REG(PMHTotal);
+ glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHbEnd);
+ glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHgEnd);
+ glintReg->glintRegs[PMScreenStride >> 3] = GLINT_READ_REG(PMScreenStride);
+ glintReg->glintRegs[PMHsStart >> 3] = GLINT_READ_REG(PMHsStart);
+ glintReg->glintRegs[PMHsEnd >> 3] = GLINT_READ_REG(PMHsEnd);
+ glintReg->glintRegs[PMVTotal >> 3] = GLINT_READ_REG(PMVTotal);
+ glintReg->glintRegs[PMVbEnd >> 3] = GLINT_READ_REG(PMVbEnd);
+ glintReg->glintRegs[PMVsStart >> 3] = GLINT_READ_REG(PMVsStart);
+ glintReg->glintRegs[PMVsEnd >> 3] = GLINT_READ_REG(PMVsEnd);
+ glintReg->glintRegs[PMScreenBase >> 3] = GLINT_READ_REG(PMScreenBase);
+ glintReg->glintRegs[PMVideoControl >> 3] = GLINT_READ_REG(PMVideoControl);
+ glintReg->glintRegs[VClkCtl >> 3] = GLINT_READ_REG(VClkCtl);
+ glintReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig);
+
+
+ for (i=0;i<768;i++) {
+ Permedia2ReadAddress(pScrn, i);
+ glintReg->cmap[i] = Permedia2ReadData(pScrn);
+ }
+
+ glintReg->DacRegs[PM2DACIndexColorKeyOverlay] =
+ Permedia2InIndReg(pScrn, PM2DACIndexColorKeyOverlay);
+ glintReg->DacRegs[PM2DACIndexColorKeyControl] =
+ Permedia2InIndReg(pScrn, PM2DACIndexColorKeyControl);
+ glintReg->DacRegs[PM2DACIndexMCR] =
+ Permedia2InIndReg(pScrn, PM2DACIndexMCR);
+ glintReg->DacRegs[PM2DACIndexMDCR] =
+ Permedia2InIndReg(pScrn, PM2DACIndexMDCR);
+ glintReg->DacRegs[PM2DACIndexCMR] =
+ Permedia2InIndReg(pScrn, PM2DACIndexCMR);
+
+ glintReg->DacRegs[PM2DACIndexClockAM] =
+ Permedia2InIndReg(pScrn, PM2DACIndexClockAM);
+ glintReg->DacRegs[PM2DACIndexClockAN] =
+ Permedia2InIndReg(pScrn, PM2DACIndexClockAN);
+ glintReg->DacRegs[PM2DACIndexClockAP] =
+ Permedia2InIndReg(pScrn, PM2DACIndexClockAP);
+
+#if 0 /* In theory we should restore the memory clock, we can't as the register
+ * is write only. This code is here for completeness and possible
+ * restoring to a default clock */
+ if (pGlint->MemClock) {
+ glintReg->DacRegs[PM2DACIndexMemClockM] =
+ Permedia2InIndReg(pScrn, PM2DACIndexMemClockM);
+ glintReg->DacRegs[PM2DACIndexMemClockN] =
+ Permedia2InIndReg(pScrn, PM2DACIndexMemClockN);
+ glintReg->DacRegs[PM2DACIndexMemClockP] =
+ Permedia2InIndReg(pScrn, PM2DACIndexMemClockP);
+ }
+#endif
+}
+
+void
+Permedia2Restore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int i;
+
+#if 0
+ GLINT_SLOW_WRITE_REG(0, ResetStatus);
+ while(GLINT_READ_REG(ResetStatus) != 0) {
+ xf86MsgVerb(X_INFO, 2, "Resetting Engine - Please Wait.\n");
+ };
+#endif
+
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture0 >> 3], Aperture0);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture1 >> 3], Aperture1);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMFramebufferWriteMask >> 3],
+ PMFramebufferWriteMask);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMBypassWriteMask >> 3],
+ PMBypassWriteMask);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[DFIFODis >> 3], DFIFODis);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[FIFODis >> 3], FIFODis);
+ /* We only muck about with PMMemConfig, if user wants to */
+ if (pGlint->UseBlockWrite)
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMMemConfig >> 3],PMMemConfig);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVideoControl >> 3],
+ PMVideoControl);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHbEnd >> 3], PMHgEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenBase >> 3], PMScreenBase);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VClkCtl >> 3], VClkCtl);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenStride >> 3],
+ PMScreenStride);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHTotal >> 3], PMHTotal);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHbEnd >> 3], PMHbEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsStart >> 3], PMHsStart);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsEnd >> 3], PMHsEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVTotal >> 3], PMVTotal);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVbEnd >> 3], PMVbEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsStart >> 3], PMVsStart);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsEnd >> 3], PMVsEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[ChipConfig >> 3], ChipConfig);
+
+ Permedia2OutIndReg(pScrn, PM2DACIndexColorKeyOverlay, 0x00,
+ glintReg->DacRegs[PM2DACIndexColorKeyOverlay]);
+ Permedia2OutIndReg(pScrn, PM2DACIndexColorKeyControl, 0x00,
+ glintReg->DacRegs[PM2DACIndexColorKeyControl]);
+ Permedia2OutIndReg(pScrn, PM2DACIndexMCR, 0x00,
+ glintReg->DacRegs[PM2DACIndexMCR]);
+ Permedia2OutIndReg(pScrn, PM2DACIndexMDCR, 0x00,
+ glintReg->DacRegs[PM2DACIndexMDCR]);
+ Permedia2OutIndReg(pScrn, PM2DACIndexCMR, 0x00,
+ glintReg->DacRegs[PM2DACIndexCMR]);
+
+ Permedia2OutIndReg(pScrn, PM2DACIndexClockAM, 0x00,
+ glintReg->DacRegs[PM2DACIndexClockAM]);
+ Permedia2OutIndReg(pScrn, PM2DACIndexClockAN, 0x00,
+ glintReg->DacRegs[PM2DACIndexClockAN]);
+ Permedia2OutIndReg(pScrn, PM2DACIndexClockAP, 0x00,
+ glintReg->DacRegs[PM2DACIndexClockAP]);
+
+ for (i=0;i<768;i++) {
+ Permedia2WriteAddress(pScrn, i);
+ Permedia2WriteData(pScrn, glintReg->cmap[i]);
+ }
+
+ if (pGlint->MemClock) {
+ Permedia2OutIndReg(pScrn, PM2DACIndexMemClockM, 0x00,
+ glintReg->DacRegs[PM2DACIndexMemClockM]);
+ Permedia2OutIndReg(pScrn, PM2DACIndexMemClockN, 0x00,
+ glintReg->DacRegs[PM2DACIndexMemClockN]);
+ Permedia2OutIndReg(pScrn, PM2DACIndexMemClockP, 0x00,
+ glintReg->DacRegs[PM2DACIndexMemClockP]);
+ }
+}
+
+static void
+Permedia2ShowCursor(ScrnInfoPtr pScrn)
+{
+ /* Enable cursor - X11 mode */
+ Permedia2OutIndReg(pScrn, PM2DACCursorControl, 0x00, 0x43);
+}
+
+static void
+Permedia2HideCursor(ScrnInfoPtr pScrn)
+{
+ /* Disable cursor */
+ Permedia2OutIndReg(pScrn, PM2DACCursorControl, 0x00, 0x00);
+}
+
+static void
+Permedia2LoadCursorImage(
+ ScrnInfoPtr pScrn,
+ unsigned char *src
+)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int i;
+
+ GLINT_SLOW_WRITE_REG(0x00, PM2DACWriteAddress);
+ for (i=0; i<1024; i++) {
+ GLINT_SLOW_WRITE_REG(*(src++), PM2DACCursorData);
+ }
+}
+
+static void
+Permedia2SetCursorPosition(
+ ScrnInfoPtr pScrn,
+ int x, int y
+)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ x += 64;
+ y += 64;
+
+ /* Output position - "only" 11 bits of location documented */
+
+ GLINT_WRITE_REG(x & 0xFF, PM2DACCursorXLsb);
+ GLINT_WRITE_REG((x>>8) & 0x07, PM2DACCursorXMsb);
+ GLINT_WRITE_REG(y & 0xFF, PM2DACCursorYLsb);
+ GLINT_WRITE_REG((y>>8) & 0x07, PM2DACCursorYMsb);
+}
+
+static void
+Permedia2SetCursorColors(
+ ScrnInfoPtr pScrn,
+ int bg, int fg
+)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ /* The Permedia2 cursor is always 8 bits so shift 8, not 10 */
+
+ GLINT_SLOW_WRITE_REG(1, PM2DACCursorColorAddress);
+ /* Background color */
+ GLINT_SLOW_WRITE_REG(bg >> 0, PM2DACCursorColorData);
+ GLINT_SLOW_WRITE_REG(bg >> 8, PM2DACCursorColorData);
+ GLINT_SLOW_WRITE_REG(bg >> 16, PM2DACCursorColorData);
+
+ /* Foreground color */
+ GLINT_SLOW_WRITE_REG(fg >> 0, PM2DACCursorColorData);
+ GLINT_SLOW_WRITE_REG(fg >> 8, PM2DACCursorColorData);
+ GLINT_SLOW_WRITE_REG(fg >> 16, PM2DACCursorColorData);
+}
+
+static Bool
+Permedia2UseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
+{
+ return TRUE;
+}
+
+Bool
+Permedia2HWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pGlint->CursorInfoRec = infoPtr;
+
+ infoPtr->MaxWidth = 64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED |
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST;
+ infoPtr->SetCursorColors = Permedia2SetCursorColors;
+ infoPtr->SetCursorPosition = Permedia2SetCursorPosition;
+ infoPtr->LoadCursorImage = Permedia2LoadCursorImage;
+ infoPtr->HideCursor = Permedia2HideCursor;
+ infoPtr->ShowCursor = Permedia2ShowCursor;
+ infoPtr->UseHWCursor = Permedia2UseHWCursor;
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
+
+/* I2C Functions */
+
+void
+Permedia2I2CUDelay(I2CBusPtr b, int usec)
+{
+ GLINTPtr pGlint = (GLINTPtr) b->DriverPrivate.ptr;
+ CARD32 ct1 = GLINT_READ_REG(PMCount);
+ CARD32 ct2 = usec * ((pGlint->MemClock > 0) ? pGlint->MemClock : 100);
+
+ if (GLINT_READ_REG(PMCount) != ct1)
+ while ((GLINT_READ_REG(PMCount) - ct1) < ct2);
+}
+
+void
+Permedia2I2CPutBits(I2CBusPtr b, int scl, int sda)
+{
+ GLINTPtr pGlint = (GLINTPtr) b->DriverPrivate.ptr;
+ int r = (pGlint->DDCBus == b) ? PMDDCData : VSSerialBusControl;
+ CARD32 v = GLINT_READ_REG(r) & ~(ClkOut | DataOut);
+
+ if (scl > 0) v |= ClkOut;
+ if (sda > 0) v |= DataOut;
+
+ GLINT_WRITE_REG(v, r);
+}
+
+void
+Permedia2I2CGetBits(I2CBusPtr b, int *scl, int *sda)
+{
+ GLINTPtr pGlint = (GLINTPtr) b->DriverPrivate.ptr;
+ CARD32 v = GLINT_READ_REG((pGlint->DDCBus == b) ?
+ PMDDCData : VSSerialBusControl);
+
+ *scl = (v & ClkIn) > 0;
+ *sda = (v & DataIn) > 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_video.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_video.c
new file mode 100644
index 000000000..1bf9d21bc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_video.c
@@ -0,0 +1,2187 @@
+/*
+ * Permedia 2 Xv Driver for Elsa Winner Office/2000 and GLoria Synergy cards
+ *
+ * Copyright (C) 1998, 1999 Michael Schimek <m.schimek@netway.at>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Michael Schimek not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Michael Schimek makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * MICHAEL SCHIMEK DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL MICHAEL SCHIMEK 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.
+ *
+ * Kernel backbone, docs and test/demo applications at
+ * <http://millennium.diads.com/mschimek/pm2>.
+ *
+ * Implementation note: The kernel backbone uses VSA, VSB and DMA (FIFO)
+ * interrupts. It launches Input and Output FIFO DMAs when entered in
+ * xvipcHandshake(). These resources are assumed to be available any time,
+ * the server code must not touch them. All DMA will be completed before
+ * returning from the kernel, no need to test.
+ *
+ * This driver is meant for the on-board video hardware only, no V4L
+ * support in this file.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm2_video.c,v 1.12 1999/07/11 08:49:27 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "xf86Xinput.h"
+#include "xf86fbman.h"
+#include "xf86i2c.h"
+#include "xf86xv.h"
+#include "Xv.h"
+
+#include "glint_regs.h"
+#include "glint.h"
+
+#define XVIPC_MAGIC 0x6A5D70E6
+#define XVIPC_VERSION 1
+#define VIDIOC_PM2_XVIPC 0x00007F7F
+
+typedef enum {
+ OP_ATTR = 0,
+ OP_RESET = 8, /* unused */
+ OP_START,
+ OP_STOP,
+ OP_PLUG,
+ OP_VIDEOSTD,
+ OP_WINDOW, /* unused */
+ OP_CONNECT,
+ OP_EVENT,
+ OP_ALLOC,
+ OP_FREE,
+ OP_UPDATE,
+ OP_NOP /* ignored */
+} xvipc_op;
+
+typedef struct _pm2_xvipc {
+ int magic;
+ void *pm2p, *pAPriv;
+ int port, op, time, block;
+ int a,b,c,d,e,f;
+} pm2_xvipc;
+
+static pm2_xvipc xvipc;
+static int xvipc_fd = -1;
+
+typedef enum {
+ OPTION_DEVICE,
+ OPTION_FPS,
+ OPTION_BUFFERS,
+ OPTION_EXPOSE
+} OptToken;
+
+static OptionInfoRec AdaptorOptions[] = {
+ { OPTION_DEVICE, "Device", OPTV_STRING, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+static OptionInfoRec InputOptions[] = {
+ { OPTION_BUFFERS, "Buffers", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_FPS, "FramesPerSec", OPTV_INTEGER, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+static OptionInfoRec OutputOptions[] = {
+ { OPTION_BUFFERS, "Buffers", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_EXPOSE, "Expose", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_FPS, "FramesPerSec", OPTV_INTEGER, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+#define PCI_SUBSYSTEM_ID_WINNER_2000_P2C 0x0a311048
+#define PCI_SUBSYSTEM_ID_GLORIA_SYNERGY_P2C 0x0a321048
+#define PCI_SUBSYSTEM_ID_GLORIA_SYNERGY_P2A 0x0a351048
+#define PCI_SUBSYSTEM_ID_WINNER_2000_P2A 0x0a441048
+
+#define SAA7111_SLAVE_ADDRESS 0x48
+#define SAA7125_SLAVE_ADDRESS 0x88
+
+typedef struct {
+ CARD32 xy, wh; /* 16.0 16.0 dw */
+ INT32 s, t; /* 12.20 fp */
+ short y1, y2;
+} CookieRec, *CookiePtr;
+
+typedef struct _PortPrivRec {
+ struct _AdaptorPrivRec * pAdaptor;
+ I2CDevRec I2CDev;
+ int Plug;
+ INT32 Attribute[8]; /* Brig, Con, Sat, Hue, Int, Filt */
+ FBAreaPtr pFBArea[3];
+ int Buffers;
+ CARD32 BufferBase[3]; /* x1 */
+ CARD32 BufferStride; /* x1 */
+ CARD32 BufferPProd; /* PProd(BufferStride / 2) */
+ INT32 vx, vy, vw, vh; /* 12.10 fp; int */
+ int dx, dy, dw, dh;
+ int fw, fh;
+ CookiePtr pCookies;
+ int nCookies;
+ INT32 dS, dT; /* 12.20 fp */
+ int APO;
+ int FramesPerSec, FrameAcc;
+ int BkgCol; /* RGB 5:6:5;5:6:5 */
+ int VideoOn; /* No, Once, Yes */
+ Bool StreamOn;
+} PortPrivRec, *PortPrivPtr;
+
+typedef struct _LFBAreaRec {
+ struct _LFBAreaRec * Next;
+ FBAreaPtr pFBArea;
+ int Linear;
+} LFBAreaRec, *LFBAreaPtr;
+
+typedef struct _AdaptorPrivRec {
+ struct _AdaptorPrivRec * Next;
+ ScrnInfoPtr pScrn;
+ void * pm2p;
+ LFBAreaPtr LFBList;
+ CARD32 FifoControl;
+ OsTimerPtr Timer;
+ int VideoStd;
+ int FramesPerSec;
+ int FrameLines;
+ int IntLine; /* Frame */
+ int LinePer; /* nsec */
+ PortPrivRec Port[2];
+} AdaptorPrivRec, *AdaptorPrivPtr;
+
+static AdaptorPrivPtr AdaptorPrivList = NULL;
+
+#define PORTNUM(p) (((p) == &pAPriv->Port[0]) ? 0 : 1)
+#define BPPSHIFT(g) (2 - (g)->BppShift) /* BytesPerPixel = 1 << BPPSHIFT(pGlint) */
+
+#undef COLORBARS /* Display them while output is unused, else just shut off */
+#define DEBUG(x) /* x */
+
+#define FreeCookies(pPPriv) \
+do { \
+ if ((pPPriv)->pCookies) { \
+ xfree((pPPriv)->pCookies); \
+ (pPPriv)->pCookies = NULL; \
+ } \
+} while (0)
+
+/* Forward */
+static CARD32 TimerCallback(OsTimerPtr pTim, CARD32 now, pointer p);
+static void DelayedStopVideo(PortPrivPtr pPPriv);
+static Bool xvipcHandshake(PortPrivPtr pPPriv, int op, Bool block);
+
+#define XV_ENCODING "XV_ENCODING"
+#define XV_BRIGHTNESS "XV_BRIGHTNESS"
+#define XV_CONTRAST "XV_CONTRAST"
+#define XV_SATURATION "XV_SATURATION"
+#define XV_HUE "XV_HUE"
+/* Proprietary */
+#define XV_INTERLACE "XV_INTERLACE" /* Integer */
+#define XV_FILTER "XV_FILTER" /* Boolean */
+#define XV_BKGCOLOR "XV_BKGCOLOR" /* Integer */
+
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+static Atom xvEncoding, xvBrightness, xvContrast, xvSaturation, xvHue;
+static Atom xvInterlace, xvFilter, xvBkgColor;
+
+static XF86VideoEncodingRec
+InputVideoEncodings[] =
+{
+ { 0, "pal-composite", 704, 576, { 1, 50 }},
+ { 1, "pal-composite_adaptor", 704, 576, { 1, 50 }},
+ { 2, "pal-svideo", 704, 576, { 1, 50 }},
+ { 3, "ntsc-composite", 704, 480, { 1001, 60000 }},
+ { 4, "ntsc-composite_adaptor", 704, 480, { 1001, 60000 }},
+ { 5, "ntsc-svideo", 704, 480, { 1001, 60000 }},
+ { 6, "secam-composite", 704, 576, { 1, 50 }},
+ { 7, "secam-composite_adaptor", 704, 576, { 1, 50 }},
+ { 8, "secam-svideo", 704, 576, { 1, 50 }},
+};
+
+static XF86VideoEncodingRec
+OutputVideoEncodings[] =
+{
+ { 0, "pal-composite_adaptor", 704, 576, { 1, 50 }},
+ { 1, "pal-svideo", 704, 576, { 1, 50 }},
+ { 2, "ntsc-composite_adaptor", 704, 480, { 1001, 60000 }},
+ { 3, "ntsc-svideo", 704, 480, { 1001, 60000 }},
+};
+
+static XF86VideoFormatRec
+InputVideoFormats[] = {
+ { 8, TrueColor }, /* Dithered */
+ { 15, TrueColor },
+ { 16, TrueColor },
+ { 24, TrueColor },
+};
+
+static XF86VideoFormatRec
+OutputVideoFormats[] = {
+ { 8, TrueColor },
+ { 8, PseudoColor }, /* Using .. */
+ { 8, StaticColor },
+ { 8, GrayScale },
+ { 8, StaticGray }, /* .. TexelLUT */
+ { 15, TrueColor },
+ { 16, TrueColor },
+ { 24, TrueColor },
+};
+
+static I2CByte
+DecInitVec[] =
+{
+ 0x11, 0x00,
+ 0x02, 0xC1, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00,
+ 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x4A,
+ 0x0A, 0x80, 0x0B, 0x40, 0x0C, 0x40, 0x0D, 0x00,
+ 0x0E, 0x01, 0x10, 0xC8, 0x12, 0x20,
+ 0x13, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
+};
+
+static I2CByte
+EncInitVec[] =
+{
+ 0x3A, 0x83, 0x61, 0xC2,
+ 0x5A, 119, 0x5B, 0x7D,
+ 0x5C, 0xAF, 0x5D, 0x3C, 0x5E, 0x3F, 0x5F, 0x3F,
+ 0x60, 0x70, 0x62, 0x4B, 0x67, 0x00,
+ 0x68, 0x00, 0x69, 0x00, 0x6A, 0x00, 0x6B, 0x20,
+ 0x6C, 0x03, 0x6D, 0x30, 0x6E, 0xA0, 0x6F, 0x00,
+ 0x70, 0x80, 0x71, 0xE8, 0x72, 0x10,
+ 0x7A, 0x13, 0x7B, 0xFB, 0x7C, 0x00, 0x7D, 0x00,
+};
+
+static I2CByte Dec02[3] = { 0xC1, 0xC0, 0xC4 };
+static I2CByte Dec09[3] = { 0x4A, 0x4A, 0xCA };
+static I2CByte Enc3A[3] = { 0x03, 0x03, 0x23 };
+static I2CByte Enc61[3] = { 0x06, 0x01, 0xC2 };
+
+static I2CByte
+DecVS[3][8] =
+{
+ { 0x06, 108, 0x07, 108, 0x08, 0x09, 0x0E, 0x01 },
+ { 0x06, 107, 0x07, 107, 0x08, 0x49, 0x0E, 0x31 },
+ { 0x06, 108, 0x07, 108, 0x08, 0x01, 0x0E, 0x51 }
+};
+
+#define FSC(n) ((CARD32)((n) / 27e6 * 4294967296.0 + .5))
+#define SUBCARRIER_FREQ_PAL (4.433619e6)
+#define SUBCARRIER_FREQ_NTSC (3.579545e6)
+
+static I2CByte
+EncVS[2][14] =
+{
+ { 0x62, 0x4B, 0x6B, 0x28, 0x6E, 0xA0,
+ 0x63, (I2CByte)(FSC(SUBCARRIER_FREQ_PAL) >> 0),
+ 0x64, (I2CByte)(FSC(SUBCARRIER_FREQ_PAL) >> 8),
+ 0x65, (I2CByte)(FSC(SUBCARRIER_FREQ_PAL) >> 16),
+ 0x66, (I2CByte)(FSC(SUBCARRIER_FREQ_PAL) >> 24) },
+ { 0x62, 0x6A, 0x6B, 0x20, 0x6E, 0x20,
+ 0x63, (I2CByte)(FSC(SUBCARRIER_FREQ_NTSC) >> 0),
+ 0x64, (I2CByte)(FSC(SUBCARRIER_FREQ_NTSC) >> 8),
+ 0x65, (I2CByte)(FSC(SUBCARRIER_FREQ_NTSC) >> 16),
+ 0x66, (I2CByte)(FSC(SUBCARRIER_FREQ_NTSC) >> 24) }
+};
+
+#undef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+#undef CLAMP
+#define CLAMP(v, min, max) (((v) < (min)) ? (min) : MIN(v, max))
+
+#undef ABS
+#define ABS(n) (((n) < 0) ? -(n) : (n))
+
+static int
+SetAttr(PortPrivPtr pPPriv, int i, I2CByte s, I2CByte v)
+{
+ AdaptorPrivPtr pAPriv = pPPriv->pAdaptor;
+
+ if (pAPriv->pm2p) {
+ xvipc.a = v << 8;
+ return xvipcHandshake(pPPriv, OP_ATTR + i, TRUE) ?
+ Success : XvBadAlloc;
+ }
+
+ return xf86I2CWriteByte(&pPPriv->I2CDev, s, v) ?
+ Success : XvBadAlloc;
+}
+
+static Bool
+SetPlug(PortPrivPtr pPPriv)
+{
+ AdaptorPrivPtr pAPriv = pPPriv->pAdaptor;
+
+ if (pAPriv->pm2p) {
+ xvipc.a = pPPriv->Plug - PORTNUM(pPPriv);
+ return xvipcHandshake(pPPriv, OP_PLUG, TRUE);
+ } else {
+ if (pPPriv == &pAPriv->Port[0]) {
+ xf86I2CWriteByte(&pPPriv->I2CDev, 0x02, Dec02[pPPriv->Plug]);
+ xf86I2CWriteByte(&pPPriv->I2CDev, 0x09, Dec09[pPPriv->Plug]);
+ } else {
+ if (pPPriv->StreamOn)
+ xf86I2CWriteByte(&pPPriv->I2CDev, 0x3A, Enc3A[pPPriv->Plug]);
+#ifdef COLORBARS
+ else
+ xf86I2CWriteByte(&pPPriv->I2CDev, 0x3A, 0x83);
+#endif
+ }
+ }
+
+ return TRUE;
+}
+
+static Bool
+SetVideoStd(AdaptorPrivPtr pAPriv)
+{
+ Bool r;
+
+ if (pAPriv->pm2p) {
+ xvipc.a = pAPriv->VideoStd;
+ r = xvipcHandshake(&pAPriv->Port[0], OP_VIDEOSTD, TRUE);
+ pAPriv->VideoStd = xvipc.a; /* Actual */
+ } else {
+ if (pAPriv->VideoStd >= 2)
+ xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x61, 0xC2);
+
+ xf86I2CWriteVec(&pAPriv->Port[0].I2CDev, &DecVS[pAPriv->VideoStd][0], 4);
+
+ if (pAPriv->VideoStd < 2)
+ xf86I2CWriteVec(&pAPriv->Port[1].I2CDev, &EncVS[pAPriv->VideoStd][0], 7);
+
+ r = TRUE;
+ }
+
+ if (pAPriv->VideoStd == 1) {
+ pAPriv->FramesPerSec = 30;
+ pAPriv->FrameLines = 525;
+ pAPriv->IntLine = 513;
+ pAPriv->LinePer = 63555;
+ } else {
+ pAPriv->FramesPerSec = 25;
+ pAPriv->FrameLines = 625;
+ pAPriv->IntLine = 613;
+ pAPriv->LinePer = 64000;
+ }
+
+#if 0
+ pAPriv->Port[0].FramesPerSec = pAPriv->FramesPerSec;
+ pAPriv->Port[1].FramesPerSec = pAPriv->FramesPerSec;
+#endif
+
+ return r;
+}
+
+/* **FIXME**: 2048 limit */
+
+static Bool
+AllocOffRec(PortPrivPtr pPPriv, int i)
+{
+ AdaptorPrivPtr pAPriv = pPPriv->pAdaptor;
+ ScrnInfoPtr pScrn = pAPriv->pScrn;
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int width, height;
+
+ height = (pAPriv->VideoStd == 1) ? 512 : 608;
+
+ if (!pPPriv->Attribute[4])
+ height >>= 1;
+
+ width = (704 << 4) / pScrn->bitsPerPixel;
+
+ pPPriv->BufferStride = pScrn->displayWidth << BPPSHIFT(pGlint);
+
+ if (pPPriv->pFBArea[i] != NULL) {
+ if (xf86ResizeOffscreenArea(pPPriv->pFBArea[i], width, height))
+ return TRUE;
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_ERROR, 2,
+ "AOR couldn't resize buffer %d,%d-%d,%d to %dx%d\n",
+ pPPriv->pFBArea[i]->box.x1, pPPriv->pFBArea[i]->box.y1,
+ pPPriv->pFBArea[i]->box.x2, pPPriv->pFBArea[i]->box.y2,
+ width, height));
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2,
+ "AOR free buffer 0x%08x\n", pPPriv->BufferBase[i]));
+
+ xf86FreeOffscreenArea(pPPriv->pFBArea[i]);
+ pPPriv->pFBArea[i] = NULL;
+ }
+
+ pPPriv->pFBArea[i] = xf86AllocateOffscreenArea(pScrn->pScreen,
+ width, height, 2, NULL, NULL, NULL);
+
+ if (pPPriv->pFBArea[i] != NULL)
+ return TRUE;
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_ERROR, 2,
+ "AOR couldn't allocate buffer %dx%d\n",
+ width, height));
+
+ return FALSE;
+}
+
+static Bool
+AllocOffLin(PortPrivPtr pPPriv, int i)
+{
+ AdaptorPrivPtr pAPriv = pPPriv->pAdaptor;
+ ScrnInfoPtr pScrn = pAPriv->pScrn;
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int length;
+
+ length = ((704 << 1) * ((pAPriv->VideoStd == 1) ? 512 : 608)) >> BPPSHIFT(pGlint);
+
+ if (!pPPriv->Attribute[4])
+ length >>= 1;
+
+ pPPriv->BufferStride = 704 << 1;
+
+ if (pPPriv->pFBArea[i] != NULL) {
+ xf86FreeOffscreenArea(pPPriv->pFBArea[i]);
+ pPPriv->pFBArea[i] = NULL;
+ }
+
+ pPPriv->pFBArea[i] = xf86AllocateLinearOffscreenArea(pScrn->pScreen,
+ length, 2, NULL, NULL, NULL);
+
+ if (pPPriv->pFBArea[i] != NULL)
+ return TRUE;
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_ERROR, 2,
+ "AOL couldn't allocate buffer %d\n",
+ length));
+
+ return FALSE;
+}
+
+static Bool
+ReallocateOffscreenBuffer(PortPrivPtr pPPriv, int num)
+{
+ AdaptorPrivPtr pAPriv = pPPriv->pAdaptor;
+ ScrnInfoPtr pScrn = pAPriv->pScrn;
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int i;
+
+ if (pAPriv->pm2p != NULL)
+ return FALSE;
+
+ for (i = 2; i >= 0; i--)
+ if (pPPriv->pFBArea[i]) {
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2,
+ "ROB free buffer 0x%08x\n", pPPriv->BufferBase[i]));
+
+ xf86FreeOffscreenArea(pPPriv->pFBArea[i]);
+ pPPriv->pFBArea[i] = NULL;
+ }
+
+ if (num <= 0)
+ return FALSE;
+
+ while (1) {
+ PortPrivPtr pPPrivN = &pAPriv->Port[1 - PORTNUM(pPPriv)];
+
+ for (i = 0; i < num; i++)
+ if (!AllocOffLin(pPPriv, i)) break;
+ if (i > 0) break;
+
+ for (i = 0; i < num; i++)
+ if (!AllocOffRec(pPPriv, i)) break;
+ if (i > 0) break;
+
+ if (pPPrivN->VideoOn <= 0 && pPPrivN->APO >= 0)
+ DelayedStopVideo(pPPrivN);
+ else
+ return FALSE;
+ }
+
+ for (i = 0; i <= 2; i++)
+ if (pPPriv->pFBArea[i]) {
+ pPPriv->BufferBase[i] =
+ ((pPPriv->pFBArea[i]->box.y1 * pScrn->displayWidth) +
+ pPPriv->pFBArea[i]->box.x1) << BPPSHIFT(pGlint);
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2,
+ "ROB buffer #%d 0x%08x str %d\n",
+ i, pPPriv->BufferBase[i], pPPriv->BufferStride));
+ }
+
+ pPPriv->BufferPProd = partprodPermedia[(pPPriv->BufferStride / 2) >> 5];
+
+ pPPriv->fw = 704;
+ pPPriv->fh = InputVideoEncodings[pAPriv->VideoStd * 3].height >>
+ (!pPPriv->Attribute[4]);
+
+ return TRUE;
+}
+
+static Bool
+PutCookies(PortPrivPtr pPPriv, RegionPtr pRegion)
+{
+ BoxPtr pBox;
+ CookiePtr pCookie;
+ int nBox;
+
+ if (!pRegion) {
+ pBox = (BoxPtr) NULL;
+ nBox = pPPriv->nCookies;
+ } else {
+ pBox = REGION_RECTS(pRegion);
+ nBox = REGION_NUM_RECTS(pRegion);
+
+ if (!pPPriv->pCookies || pPPriv->nCookies < nBox) {
+ if (!(pCookie = (CookiePtr) xrealloc(pPPriv->pCookies, nBox * sizeof(CookieRec))))
+ return FALSE;
+
+ pPPriv->pCookies = pCookie;
+ }
+ }
+
+ pPPriv->dS = (pPPriv->vw << 10) / pPPriv->dw;
+ pPPriv->dT = (pPPriv->vh << 10) / pPPriv->dh;
+
+ for (pCookie = pPPriv->pCookies; nBox--; pCookie++, pBox++) {
+ if (pRegion) {
+ pCookie->y1 = pBox->y1;
+ pCookie->y2 = pBox->x1;
+ pCookie->xy = (pBox->y1 << 16) | pBox->x1;
+ pCookie->wh = ((pBox->y2 - pBox->y1) << 16) |
+ (pBox->x2 - pBox->x1);
+ }
+
+ pCookie->s = (pPPriv->vx << 10) + (pCookie->y2 - pPPriv->dx) * pPPriv->dS;
+ pCookie->t = (pPPriv->vy << 10) + (pCookie->y1 - pPPriv->dy) * pPPriv->dT;
+ }
+
+ pPPriv->nCookies = pCookie - pPPriv->pCookies;
+
+ return TRUE;
+}
+
+static void
+PutYUV(PortPrivPtr pPPriv, int BufferBase)
+{
+ ScrnInfoPtr pScrn = pPPriv->pAdaptor->pScrn;
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ CookiePtr pCookie = pPPriv->pCookies;
+ int nCookies = pPPriv->nCookies;
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "PutYUV %08x\n", BufferBase));
+
+ if (!nCookies)
+ return;
+
+ /* Setup */
+
+ GLINT_WAIT(25);
+ CHECKCLIPPING;
+
+ switch (pScrn->depth) {
+ case 8:
+ GLINT_WRITE_REG((0 << 10) | /* BGR */
+ (1 << 1) | /* Dither */
+ ((5 & 0x10)<<12) |
+ ((5 & 0x0F)<<2) | /* 3:3:2f */
+ UNIT_ENABLE, DitherMode);
+ break;
+ case 15:
+ GLINT_WRITE_REG((1 << 10) | /* RGB */
+ ((1 & 0x10)<<12)|
+ ((1 & 0x0F)<<2) | /* 5:5:5:1f */
+ UNIT_ENABLE, DitherMode);
+ break;
+ case 16:
+ GLINT_WRITE_REG((1 << 10) | /* RGB */
+ ((16 & 0x10)<<12)|
+ ((16 & 0x0F)<<2) | /* 5:6:5f */
+ UNIT_ENABLE, DitherMode);
+ break;
+ case 24:
+ GLINT_WRITE_REG((1 << 10) | /* RGB */
+ ((0 & 0x10)<<12)|
+ ((0 & 0x0F)<<2) | /* 8:8:8:8 */
+ UNIT_ENABLE, DitherMode);
+ break;
+ default:
+ return; /* Oops */
+ }
+
+ GLINT_WRITE_REG(1 << 16, dY);
+ GLINT_WRITE_REG(0, RasterizerMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, AreaStippleMode);
+ GLINT_WRITE_REG(BufferBase >> 1 /* 16 */, PMTextureBaseAddress);
+ GLINT_WRITE_REG((1 << 19) /* 16 */ | pPPriv->BufferPProd,
+ PMTextureMapFormat);
+ GLINT_WRITE_REG((1 << 4) /* No alpha */ |
+ ((19 & 0x10) << 2) |
+ ((19 & 0x0F) << 0) /* YUYV */,
+ PMTextureDataFormat);
+ GLINT_WRITE_REG((pPPriv->Attribute[5] << 17) | /* FilterMode */
+ (11 << 13) | (11 << 9) | /* TextureSize log2 */
+ UNIT_ENABLE, PMTextureReadMode);
+ GLINT_WRITE_REG((0 << 4) /* RGB */ |
+ (3 << 1) /* Copy */ |
+ UNIT_ENABLE, TextureColorMode);
+ GLINT_WRITE_REG(UNIT_ENABLE, YUVMode);
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, LogicalOpMode);
+ GLINT_WRITE_REG(UNIT_ENABLE, TextureAddressMode);
+ GLINT_WRITE_REG(pPPriv->dS, dSdx);
+ GLINT_WRITE_REG(0, dSdyDom);
+ GLINT_WRITE_REG(0, dTdx);
+ GLINT_WRITE_REG(pPPriv->dT, dTdyDom);
+
+ /* Subsequent */
+
+ for (; nCookies--; pCookie++) {
+ GLINT_WAIT(5);
+ GLINT_WRITE_REG(pCookie->xy, RectangleOrigin);
+ GLINT_WRITE_REG(pCookie->wh, RectangleSize);
+ GLINT_WRITE_REG(pCookie->s, SStart);
+ GLINT_WRITE_REG(pCookie->t, TStart);
+ GLINT_WRITE_REG(PrimitiveRectangle |
+ XPositive |
+ YPositive |
+ TextureEnable, Render);
+ }
+
+ /* Cleanup */
+
+ pGlint->x = pGlint->y = -1; /* Force reload */
+ pGlint->w = pGlint->h = -1;
+ pGlint->ROP = 0xFF;
+ GLINT_WAIT(6);
+ GLINT_WRITE_REG(pGlint->TexMapFormat, PMTextureMapFormat);
+ GLINT_WRITE_REG(UNIT_DISABLE, DitherMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, TextureColorMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, TextureAddressMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, PMTextureReadMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, YUVMode);
+}
+
+static void
+BlackOut(PortPrivPtr pPPriv, RegionPtr pRegion)
+{
+ ScrnInfoPtr pScrn = pPPriv->pAdaptor->pScrn;
+ ScreenPtr pScreen = pScrn->pScreen;
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ RegionRec DRegion;
+ BoxRec DBox;
+ BoxPtr pBox;
+ int nBox;
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4,
+ "BlackOut %d,%d,%d,%d -- %d,%d,%d,%d\n",
+ pPPriv->vx, pPPriv->vy, pPPriv->vw, pPPriv->vh,
+ pPPriv->dx, pPPriv->dy, pPPriv->dw, pPPriv->dh));
+
+ DBox.x1 = pPPriv->dx - (pPPriv->vx * pPPriv->dw) / pPPriv->vw;
+ DBox.y1 = pPPriv->dy - (pPPriv->vy * pPPriv->dh) / pPPriv->vh;
+ DBox.x2 = DBox.x1 + (pPPriv->fw * pPPriv->dw) / pPPriv->vw;
+ DBox.y2 = DBox.y1 + (pPPriv->fh * pPPriv->dh) / pPPriv->vh;
+
+ REGION_INIT(pScreen, &DRegion, &DBox, 1);
+
+ if (pRegion)
+ REGION_SUBTRACT(pScreen, &DRegion, &DRegion, pRegion);
+
+ nBox = REGION_NUM_RECTS(&DRegion);
+ pBox = REGION_RECTS(&DRegion);
+
+ GLINT_WAIT(15);
+ CHECKCLIPPING;
+
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ GLINT_WRITE_REG(pPPriv->BufferPProd, FBReadMode);
+ GLINT_WRITE_REG(0x1, FBReadPixel); /* 16 */
+ GLINT_WRITE_REG(pPPriv->BkgCol, FBBlockColor);
+ GLINT_WRITE_REG(pPPriv->BufferBase[0] >> 1 /* 16 */, FBWindowBase);
+ GLINT_WRITE_REG(UNIT_DISABLE, LogicalOpMode);
+
+ for (; nBox--; pBox++) {
+ int w = ((pBox->x2 - pBox->x1) * pPPriv->vw + pPPriv->dw) / pPPriv->dw + 1;
+ int h = ((pBox->y2 - pBox->y1) * pPPriv->vh + pPPriv->dh) / pPPriv->dh + 1;
+ int x = ((pBox->x1 - DBox.x1) * pPPriv->vw + (pPPriv->dw >> 1)) / pPPriv->dw;
+ int y = ((pBox->y1 - DBox.y1) * pPPriv->vh + (pPPriv->dh >> 1)) / pPPriv->dh;
+
+ if ((x + w) > pPPriv->fw)
+ w = pPPriv->fw - x;
+ if ((y + h) > pPPriv->fh)
+ h = pPPriv->fh - y;
+
+ GLINT_WAIT(3);
+ GLINT_WRITE_REG((y << 16) | x, RectangleOrigin);
+ GLINT_WRITE_REG((h << 16) | w, RectangleSize);
+ GLINT_WRITE_REG(PrimitiveRectangle |
+ XPositive | YPositive | FastFillEnable, Render);
+ }
+
+ REGION_UNINIT(pScreen, &DRegion);
+
+ pGlint->x = pGlint->y = -1; /* Force reload */
+ pGlint->w = pGlint->h = -1;
+ pGlint->ROP = 0xFF;
+ GLINT_WAIT(3);
+ GLINT_WRITE_REG(0, FBWindowBase);
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ GLINT_WRITE_REG(pGlint->PixelWidth, FBReadPixel);
+}
+
+static Bool
+GetCookies(PortPrivPtr pPPriv, RegionPtr pRegion)
+{
+ BoxPtr pBox;
+ CookiePtr pCookie;
+ int nBox;
+ int dw1 = pPPriv->dw - 1;
+ int dh1 = pPPriv->dh - 1;
+
+ if (!pRegion) {
+ pBox = (BoxPtr) NULL;
+ nBox = pPPriv->nCookies;
+ } else {
+ pBox = REGION_RECTS(pRegion);
+ nBox = REGION_NUM_RECTS(pRegion);
+
+ if (!pPPriv->pCookies || pPPriv->nCookies < nBox) {
+ if (!(pCookie = (CookiePtr) xrealloc(pPPriv->pCookies, nBox * sizeof(CookieRec))))
+ return FALSE;
+
+ pPPriv->pCookies = pCookie;
+ }
+ }
+
+ pPPriv->dS = (pPPriv->dw << 20) / pPPriv->vw;
+ pPPriv->dT = (pPPriv->dh << 20) / pPPriv->vh;
+
+ for (pCookie = pPPriv->pCookies; nBox--; pBox++) {
+ int n1, n2;
+
+ if (pRegion) {
+ n1 = ((pBox->x1 - pPPriv->dx) * pPPriv->vw + dw1) / pPPriv->dw;
+ n2 = ((pBox->x2 - pPPriv->dx) * pPPriv->vw - 1) / pPPriv->dw;
+ if (n1 > n2) continue; /* Clip is subpixel */
+ pCookie->xy = n1 + pPPriv->vx;
+ pCookie->wh = n2 - n1 + 1;
+ pCookie->s = n1 * pPPriv->dS + (pPPriv->dx << 20);
+ pCookie->y1 = pBox->y1;
+ pCookie->y2 = pBox->y2;
+ }
+
+ n1 = ((pCookie->y1 - pPPriv->dy) * pPPriv->vh + dh1) / pPPriv->dh;
+ n2 = ((pCookie->y2 - pPPriv->dy) * pPPriv->vh - 1) / pPPriv->dh;
+ pCookie->xy = (pCookie->xy & 0xFFFF) | ((n1 + pPPriv->vy) << 16);
+ pCookie->wh = (pCookie->wh & 0xFFFF) | ((n2 - n1 + 1) << 16);
+ pCookie->t = n1 * pPPriv->dT + (pPPriv->dy << 20);
+ if (n1 > n2) pCookie->t = -1;
+
+ pCookie++;
+ }
+
+ pPPriv->nCookies = pCookie - pPPriv->pCookies;
+ return TRUE;
+}
+
+static void
+GetYUV(PortPrivPtr pPPriv)
+{
+ ScrnInfoPtr pScrn = pPPriv->pAdaptor->pScrn;
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ CookiePtr pCookie = pPPriv->pCookies;
+ int nCookies = pPPriv->nCookies;
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 4, "GetYUV\n"));
+
+ if (!nCookies)
+ return;
+
+ /* FIXME? clip + filt d-1 */
+
+ /* Setup */
+
+ GLINT_WAIT(25);
+ CHECKCLIPPING;
+
+ switch (pScrn->depth) {
+ case 8:
+ GLINT_WRITE_REG(UNIT_ENABLE, TexelLUTMode);
+ GLINT_WRITE_REG((1 << 4) | /* No alpha */
+ ((14 & 0x10) << 2) |
+ ((14 & 0x0F) << 0), /* CI8 */
+ PMTextureDataFormat);
+ break;
+
+ case 15:
+ GLINT_WRITE_REG((1 << 5) | /* RGB */
+ (1 << 4) |
+ ((1 & 0x10) << 2) |
+ ((1 & 0x0F) << 0), /* 5:5:5:1f */
+ PMTextureDataFormat);
+ break;
+ case 16:
+ GLINT_WRITE_REG((1 << 5) |
+ (1 << 4) |
+ ((16 & 0x10) << 2) |
+ ((16 & 0x0F) << 0), /* 5:6:5f */
+ PMTextureDataFormat);
+ break;
+ case 24:
+ GLINT_WRITE_REG((1 << 5) |
+ (1 << 4) |
+ ((0 & 0x10) << 2) |
+ ((0 & 0x0F) << 0), /* 8:8:8:8 */
+ PMTextureDataFormat);
+ break;
+ default:
+ return;
+ }
+
+ GLINT_WRITE_REG(UNIT_DISABLE, AreaStippleMode);
+ GLINT_WRITE_REG(0, PMTextureBaseAddress);
+ GLINT_WRITE_REG((1 << 10) | /* RGB */
+ ((16 & 0x10)<<12)|
+ ((16 & 0x0F)<<2) | /* 5:6:5f */
+ UNIT_ENABLE, DitherMode);
+ GLINT_WRITE_REG((pPPriv->Attribute[5] << 17) | /* FilterMode */
+ (11 << 13) | (11 << 9) | /* TextureSize log2 */
+ UNIT_ENABLE, PMTextureReadMode);
+ GLINT_WRITE_REG((0 << 4) /* RGB */ |
+ (3 << 1) /* Copy */ |
+ UNIT_ENABLE, TextureColorMode);
+ GLINT_WRITE_REG(0x1, FBReadPixel); /* 16 */
+ GLINT_WRITE_REG(UNIT_DISABLE, YUVMode);
+ GLINT_WRITE_REG(pPPriv->BufferPProd, FBReadMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, LogicalOpMode);
+ GLINT_WRITE_REG(UNIT_ENABLE, TextureAddressMode);
+ GLINT_WRITE_REG(pPPriv->dS, dSdx);
+ GLINT_WRITE_REG(0, dSdyDom);
+ GLINT_WRITE_REG(0, dTdx);
+ GLINT_WRITE_REG(pPPriv->dT, dTdyDom);
+ GLINT_WRITE_REG(1 << 16, dY);
+ GLINT_WRITE_REG(0, RasterizerMode);
+ GLINT_WRITE_REG(pPPriv->BufferBase[0] >> 1 /* 16 */, FBWindowBase);
+
+ /* Subsequent */
+
+ for (; nCookies--; pCookie++)
+ if (pCookie->t >= 0) {
+ GLINT_WAIT(5);
+ GLINT_WRITE_REG(pCookie->xy, RectangleOrigin);
+ GLINT_WRITE_REG(pCookie->wh, RectangleSize);
+ GLINT_WRITE_REG(pCookie->s, SStart);
+ GLINT_WRITE_REG(pCookie->t, TStart);
+ GLINT_WRITE_REG(PrimitiveRectangle |
+ XPositive |
+ YPositive |
+ TextureEnable, Render);
+ }
+
+ /* Cleanup */
+
+ pGlint->x = pGlint->y = -1; /* Force reload */
+ pGlint->w = pGlint->h = -1;
+ pGlint->ROP = 0xFF;
+ GLINT_WAIT(10);
+ GLINT_WRITE_REG(0, FBWindowBase);
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ GLINT_WRITE_REG(pGlint->PixelWidth, FBReadPixel);
+ GLINT_WRITE_REG(UNIT_DISABLE, DitherMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, TextureColorMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, TextureAddressMode);
+ GLINT_WRITE_REG(pGlint->TexMapFormat, PMTextureMapFormat);
+ GLINT_WRITE_REG(UNIT_DISABLE, TexelLUTMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, PMTextureReadMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, YUVMode);
+}
+
+static void
+StopVideoStream(AdaptorPrivPtr pAPriv, int which)
+{
+ GLINTPtr pGlint = GLINTPTR(pAPriv->pScrn);
+
+ if (which & 1) pAPriv->Port[0].VideoOn = 0;
+ if (which & 2) pAPriv->Port[1].VideoOn = 0;
+
+ if (pAPriv->pm2p) {
+ /* Hard stop, frees buffers */
+
+ if (which & 2) {
+ xvipcHandshake(&pAPriv->Port[1], OP_STOP, TRUE);
+ pAPriv->Port[1].StreamOn = FALSE;
+ }
+
+ if (which & 1) {
+ xvipcHandshake(&pAPriv->Port[0], OP_STOP, TRUE);
+ pAPriv->Port[0].StreamOn = FALSE;
+ }
+
+ return;
+ }
+
+ if (which & 2) {
+ xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x3A, 0x83);
+#ifndef COLORBARS
+ xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x61, 0xC2);
+#endif
+ GLINT_WRITE_REG(0, VSBBase + VSControl);
+ pAPriv->Port[1].StreamOn = FALSE;
+ }
+
+ if (which & 1) {
+ GLINT_WRITE_REG(0, VSABase + VSControl);
+ pAPriv->Port[0].StreamOn = FALSE;
+ usleep(80000);
+ }
+
+ if (!(pAPriv->Port[0].StreamOn || pAPriv->Port[1].StreamOn)) {
+ if (which & 4)
+ xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x61, 0xC2);
+ xf86I2CWriteByte(&pAPriv->Port[0].I2CDev, 0x11, 0x00);
+ TimerCancel(pAPriv->Timer);
+ }
+}
+
+static Bool
+StartVideoStream(PortPrivPtr pPPriv, RegionPtr pRegion)
+{
+ AdaptorPrivPtr pAPriv = pPPriv->pAdaptor;
+ GLINTPtr pGlint = GLINTPTR(pAPriv->pScrn);
+
+ pPPriv->APO = -1;
+
+ if (pAPriv->pm2p) {
+ if (pPPriv == &pAPriv->Port[0]) {
+ if (!PutCookies(pPPriv, pRegion))
+ return FALSE;
+ if (pPPriv->StreamOn)
+ return TRUE;
+ } else {
+ if (!GetCookies(pPPriv, pRegion))
+ return FALSE;
+ if (pPPriv->StreamOn) {
+ BlackOut(pPPriv, pRegion);
+ return TRUE;
+ }
+ }
+
+ xvipc.a = pPPriv->Buffers;
+ xvipc.b = !pPPriv->Attribute[4];
+ xvipc.c = 1 + (pPPriv->Attribute[4] & 2);
+
+ if (!xvipcHandshake(pPPriv, OP_START, TRUE))
+ return FALSE;
+
+ if (pPPriv == &pAPriv->Port[1]) {
+ pPPriv->BufferBase[0] = xvipc.d;
+ BlackOut(pPPriv, pRegion);
+ }
+
+ return pPPriv->StreamOn = TRUE;
+ } else {
+ CARD32 Base = (pPPriv == &pAPriv->Port[0]) ? VSABase : VSBBase;
+
+ if (pPPriv->pFBArea[0] == NULL)
+ if (!ReallocateOffscreenBuffer(pPPriv, (pPPriv == &pAPriv->Port[0]) ? 2 : 1))
+ return FALSE;
+
+ if (pPPriv == &pAPriv->Port[0]) {
+ if (!PutCookies(pPPriv, pRegion))
+ return FALSE;
+ } else {
+ if (!GetCookies(pPPriv, pRegion))
+ return FALSE;
+ BlackOut(pPPriv, pRegion);
+ }
+
+ if (pPPriv->StreamOn)
+ return TRUE;
+
+ GLINT_WRITE_REG(pPPriv->BufferBase[0] / 8, Base + VSVideoAddress0);
+ if (pPPriv->pFBArea[1])
+ GLINT_WRITE_REG(pPPriv->BufferBase[1] / 8, Base + VSVideoAddress1);
+ else
+ GLINT_WRITE_REG(pPPriv->BufferBase[0] / 8, Base + VSVideoAddress1);
+ GLINT_WRITE_REG(pPPriv->BufferStride / 8, Base + VSVideoStride);
+
+ GLINT_WRITE_REG(0, Base + VSCurrentLine);
+
+ if (pAPriv->VideoStd == 1) {
+ /* NTSC untested */
+ GLINT_WRITE_REG(16, Base + VSVideoStartLine);
+ GLINT_WRITE_REG(16 + 240, Base + VSVideoEndLine);
+ GLINT_WRITE_REG(288 + (8 & ~3) * 2, Base + VSVideoStartData);
+ GLINT_WRITE_REG(288 + ((8 & ~3) + 704) * 2, Base + VSVideoEndData);
+ } else {
+ /* PAL, SECAM (untested) */
+ GLINT_WRITE_REG(16, Base + VSVideoStartLine);
+ GLINT_WRITE_REG(16 + 288, Base + VSVideoEndLine);
+ GLINT_WRITE_REG(288 + (8 & ~3) * 2, Base + VSVideoStartData);
+ GLINT_WRITE_REG(288 + ((8 & ~3) + 704) * 2, Base + VSVideoEndData);
+ }
+
+ GLINT_WRITE_REG(2, Base + VSVideoAddressHost);
+ GLINT_WRITE_REG(0, Base + VSVideoAddressIndex);
+
+ if (pPPriv == &pAPriv->Port[0]) {
+ xf86I2CWriteByte(&pAPriv->Port[0].I2CDev, 0x11, 0x0D);
+ GLINT_WRITE_REG(VSA_Video |
+ (pPPriv->Attribute[4] ?
+ VSA_CombineFields : VSA_Discard_FieldTwo),
+ VSABase + VSControl);
+#ifdef COLORBARS
+ if (!pAPriv->Port[1].StreamOn) {
+ xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x3A, 0x83);
+ xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x61, Enc61[pAPriv->VideoStd]);
+ }
+#endif
+ } else {
+ GLINT_WRITE_REG(VSB_Video |
+ (pPPriv->Attribute[4] ? VSB_CombineFields : 0) |
+ /* VSB_GammaCorrect | */
+ (16 << 4) | /* 5:6:5 FIXME? */
+ (1 << 9) | /* 16 */
+ VSB_RGBOrder, VSBBase + VSControl);
+ xf86I2CWriteByte(&pAPriv->Port[0].I2CDev, 0x11, 0x0D);
+ xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x3A, Enc3A[pPPriv->Plug]);
+ xf86I2CWriteByte(&pAPriv->Port[1].I2CDev, 0x61, Enc61[pAPriv->VideoStd]);
+ }
+
+ TimerSet(pAPriv->Timer, 0, 80, TimerCallback, pAPriv);
+
+ return pPPriv->StreamOn = TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Pseudo interrupt - better than nothing
+ * (not used in kernel backbone mode)
+ */
+
+static CARD32
+TimerCallback(OsTimerPtr pTim, CARD32 now, pointer p)
+{
+ AdaptorPrivPtr pAPriv = (AdaptorPrivPtr) p;
+ GLINTPtr pGlint = GLINTPTR(pAPriv->pScrn);
+ PortPrivPtr pPPriv;
+ int delay;
+
+ pPPriv = &pAPriv->Port[0];
+
+ if (pPPriv->VideoOn >= 1) {
+ pPPriv->FrameAcc += pPPriv->FramesPerSec;
+ if (pPPriv->FrameAcc >= pAPriv->FramesPerSec) {
+ pPPriv->FrameAcc -= pAPriv->FramesPerSec;
+
+ PutYUV(pPPriv, (!pPPriv->pFBArea[1]) ?
+ pPPriv->BufferBase[0] : pPPriv->BufferBase[1 -
+ GLINT_READ_REG(VSABase + VSVideoAddressIndex)]);
+
+ if (pPPriv->VideoOn == 1)
+ pPPriv->VideoOn = 0;
+ }
+ } else if (pPPriv->APO >= 0 && !(pPPriv->APO--))
+ DelayedStopVideo(pPPriv);
+
+ pPPriv = &pAPriv->Port[1];
+
+ if (pPPriv->VideoOn >= 1) {
+ pPPriv->FrameAcc += pPPriv->FramesPerSec;
+ if (pPPriv->FrameAcc >= pAPriv->FramesPerSec) {
+ pPPriv->FrameAcc -= pAPriv->FramesPerSec;
+
+ GetYUV(pPPriv);
+
+ if (pPPriv->VideoOn == 1)
+ pPPriv->VideoOn = 0;
+ }
+ } else if (pPPriv->APO >= 0 && !(pPPriv->APO--))
+ DelayedStopVideo(pPPriv);
+
+ if (pAPriv->Port[0].StreamOn) {
+ delay = GLINT_READ_REG(VSABase + VSCurrentLine);
+ if (!(GLINT_READ_REG(VSStatus) & VS_FieldOne0A))
+ delay += pAPriv->FrameLines >> 1;
+ } else if (pAPriv->Port[1].StreamOn) {
+ delay = GLINT_READ_REG(VSBBase + VSCurrentLine);
+ if (!(GLINT_READ_REG(VSStatus) & VS_FieldOne0B))
+ delay += pAPriv->FrameLines >> 1;
+ } else
+ delay = pAPriv->IntLine;
+
+ if (delay > (pAPriv->IntLine - 16))
+ delay -= pAPriv->FrameLines;
+
+ return (((pAPriv->IntLine - delay) * pAPriv->LinePer) + 999999) / 1000000;
+}
+
+static int
+Permedia2PutVideo(ScrnInfoPtr pScrn,
+ short vid_x, short vid_y, short drw_x, short drw_y,
+ short vid_w, short vid_h, short drw_w, short drw_h,
+ RegionPtr clipBoxes, pointer data)
+{
+ PortPrivPtr pPPriv = (PortPrivPtr) data;
+ AdaptorPrivPtr pAPriv = pPPriv->pAdaptor;
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "PutVideo %d,%d,%d,%d -> %d,%d,%d,%d\n",
+ vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h));
+
+ if (pPPriv == &pAPriv->Port[0]) {
+ int sw = InputVideoEncodings[pAPriv->VideoStd * 3].width;
+ int sh = InputVideoEncodings[pAPriv->VideoStd * 3].height;
+
+ if ((vid_x + vid_w) > sw ||
+ (vid_y + vid_h) > sh)
+ return BadValue;
+
+ pPPriv->VideoOn = 0;
+
+ pPPriv->vx = ((vid_x << 10) * pPPriv->fw) / sw;
+ pPPriv->vy = ((vid_y << 10) * pPPriv->fh) / sh;
+ pPPriv->vw = ((vid_w << 10) * pPPriv->fw) / sw;
+ pPPriv->vh = ((vid_h << 10) * pPPriv->fh) / sh;
+
+ pPPriv->dx = drw_x;
+ pPPriv->dy = drw_y;
+ pPPriv->dw = drw_w;
+ pPPriv->dh = drw_h;
+
+ pPPriv->FrameAcc = pAPriv->FramesPerSec;
+
+ if (!StartVideoStream(pPPriv, clipBoxes))
+ return XvBadAlloc;
+
+ pPPriv->VideoOn = 2;
+
+ return Success;
+ }
+
+ return XvBadAlloc;
+}
+
+static int
+Permedia2PutStill(ScrnInfoPtr pScrn,
+ short vid_x, short vid_y, short drw_x, short drw_y,
+ short vid_w, short vid_h, short drw_w, short drw_h,
+ RegionPtr clipBoxes, pointer data)
+{
+ PortPrivPtr pPPriv = (PortPrivPtr) data;
+ AdaptorPrivPtr pAPriv = pPPriv->pAdaptor;
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "PutStill %d,%d,%d,%d -> %d,%d,%d,%d\n",
+ vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h));
+
+ if (pPPriv == &pAPriv->Port[0]) {
+ int sw = InputVideoEncodings[pAPriv->VideoStd * 3].width;
+ int sh = InputVideoEncodings[pAPriv->VideoStd * 3].height;
+
+ if ((vid_x + vid_w) > sw ||
+ (vid_y + vid_h) > sh)
+ return BadValue;
+
+ pPPriv->VideoOn = 0;
+
+ pPPriv->vx = ((vid_x << 10) * pPPriv->fw) / sw;
+ pPPriv->vy = ((vid_y << 10) * pPPriv->fh) / sh;
+ pPPriv->vw = ((vid_w << 10) * pPPriv->fw) / sw;
+ pPPriv->vh = ((vid_h << 10) * pPPriv->fh) / sh;
+
+ pPPriv->dx = drw_x;
+ pPPriv->dy = drw_y;
+ pPPriv->dw = drw_w;
+ pPPriv->dh = drw_h;
+
+ {
+ Bool r = TRUE;
+
+ pPPriv->FrameAcc = pAPriv->FramesPerSec;
+
+ if (!StartVideoStream(pPPriv, clipBoxes))
+ return XvBadAlloc;
+
+ if (pAPriv->pm2p) {
+ /* Sleep, not busy wait, until the very next frame is ready.
+ Accept memory requests and other window's update events
+ in the meantime. */
+ for (pPPriv->VideoOn = 1; pPPriv->VideoOn;)
+ if (!xvipcHandshake(pPPriv, OP_UPDATE, TRUE)) {
+ r = FALSE;
+ break;
+ }
+ } else {
+ usleep(80000);
+ PutYUV(pPPriv, (!pPPriv->pFBArea[1]) ?
+ pPPriv->BufferBase[0] : pPPriv->BufferBase[1 -
+ GLINT_READ_REG(VSABase + VSVideoAddressIndex)]);
+ }
+
+ pPPriv->APO = 125; /* Delayed stop: consider PutStill staccato */
+
+ if (r)
+ return Success;
+ }
+ }
+
+ return XvBadAlloc;
+}
+
+static int
+Permedia2GetVideo(ScrnInfoPtr pScrn,
+ short vid_x, short vid_y, short drw_x, short drw_y,
+ short vid_w, short vid_h, short drw_w, short drw_h,
+ RegionPtr clipBoxes, pointer data)
+{
+ PortPrivPtr pPPriv = (PortPrivPtr) data;
+ AdaptorPrivPtr pAPriv = pPPriv->pAdaptor;
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "GetVideo %d,%d,%d,%d <- %d,%d,%d,%d\n",
+ vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h));
+
+ if (pPPriv == &pAPriv->Port[1]) {
+ int sw = InputVideoEncodings[pAPriv->VideoStd * 3].width;
+ int sh = InputVideoEncodings[pAPriv->VideoStd * 3].height;
+
+ if ((vid_x + vid_w) > sw ||
+ (vid_y + vid_h) > sh)
+ return BadValue;
+
+ pPPriv->VideoOn = 0;
+
+ pPPriv->vx = (vid_x * pPPriv->fw) / sw;
+ pPPriv->vy = (vid_y * pPPriv->fh) / sh;
+ pPPriv->vw = (vid_w * pPPriv->fw) / sw;
+ pPPriv->vh = (vid_h * pPPriv->fh) / sh;
+
+ pPPriv->dx = drw_x;
+ pPPriv->dy = drw_y;
+ pPPriv->dw = drw_w;
+ pPPriv->dh = drw_h;
+
+ pPPriv->FrameAcc = pAPriv->FramesPerSec;
+
+ if (!StartVideoStream(pPPriv, clipBoxes))
+ return XvBadAlloc;
+
+ GetYUV(pPPriv);
+
+ pPPriv->VideoOn = 2;
+
+ return Success;
+ }
+
+ return XvBadAlloc;
+}
+
+static int
+Permedia2GetStill(ScrnInfoPtr pScrn,
+ short vid_x, short vid_y, short drw_x, short drw_y,
+ short vid_w, short vid_h, short drw_w, short drw_h,
+ RegionPtr clipBoxes, pointer data)
+{
+ PortPrivPtr pPPriv = (PortPrivPtr) data;
+ AdaptorPrivPtr pAPriv = pPPriv->pAdaptor;
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "GetStill %d,%d,%d,%d <- %d,%d,%d,%d\n",
+ vid_x, vid_y, vid_w, vid_h, drw_x, drw_y, drw_w, drw_h));
+
+ if (pPPriv == &pAPriv->Port[1]) {
+ int sw = InputVideoEncodings[pAPriv->VideoStd * 3].width;
+ int sh = InputVideoEncodings[pAPriv->VideoStd * 3].height;
+
+ if ((vid_x + vid_w) > sw ||
+ (vid_y + vid_h) > sh)
+ return BadValue;
+
+ pPPriv->VideoOn = 0;
+
+ pPPriv->vx = (vid_x * pPPriv->fw) / sw;
+ pPPriv->vy = (vid_y * pPPriv->fh) / sh;
+ pPPriv->vw = (vid_w * pPPriv->fw) / sw;
+ pPPriv->vh = (vid_h * pPPriv->fh) / sh;
+
+ pPPriv->dx = drw_x;
+ pPPriv->dy = drw_y;
+ pPPriv->dw = drw_w;
+ pPPriv->dh = drw_h;
+
+ pPPriv->FrameAcc = pAPriv->FramesPerSec;
+
+ if (!StartVideoStream(pPPriv, clipBoxes))
+ return XvBadAlloc;
+
+ GetYUV(pPPriv);
+
+ /* Remains active until the client (implicitly)
+ calls StopVideo for this port, GetStill, or GetVideo */
+
+ return Success;
+ }
+
+ return XvBadAlloc;
+}
+
+static void
+Permedia2StopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit)
+{
+ PortPrivPtr pPPriv = (PortPrivPtr) data;
+ AdaptorPrivPtr pAPriv = pPPriv->pAdaptor;
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "StopVideo port=%d, exit=%d\n",
+ PORTNUM(pPPriv), exit));
+
+ pPPriv->VideoOn = 0;
+
+ if (exit) {
+ StopVideoStream(pAPriv, 1 << PORTNUM(pPPriv));
+ ReallocateOffscreenBuffer(pPPriv, 0);
+ } else
+ pPPriv->APO = 750; /* Delay, appx. 30 sec */
+
+ if (pGlint->NoAccel)
+ Permedia2Sync(pScrn);
+}
+
+static void
+DelayedStopVideo(PortPrivPtr pPPriv)
+{
+ AdaptorPrivPtr pAPriv = pPPriv->pAdaptor;
+
+ DEBUG(xf86DrvMsgVerb(pAPriv->pScrn->scrnIndex, X_INFO, 3,
+ "DelayedStopVideo port=%d\n", PORTNUM(pPPriv)));
+
+ pPPriv->APO = -1;
+ Permedia2StopVideo(pAPriv->pScrn, (pointer) pPPriv, TRUE);
+}
+
+/* Remind Port[0].v* are shifted 1 << 10 */
+
+static void
+AdjustVideoW(PortPrivPtr pPPriv, int num, int denom)
+{
+ pPPriv->vx = (pPPriv->vx * num) / denom;
+ pPPriv->vw = (pPPriv->vw * num) / denom;
+}
+
+static void
+AdjustVideoH(PortPrivPtr pPPriv, int num, int denom)
+{
+ pPPriv->vy = (pPPriv->vy * num) / denom;
+ pPPriv->vh = (pPPriv->vh * num) / denom;
+}
+
+static int
+Permedia2SetPortAttribute(ScrnInfoPtr pScrn,
+ Atom attribute, INT32 value, pointer data)
+{
+ PortPrivPtr pPPriv = (PortPrivPtr) data;
+ AdaptorPrivPtr pAPriv = pPPriv->pAdaptor;
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "SPA attr=%d, val=%d, port=%d\n",
+ attribute, value, PORTNUM(pPPriv)));
+
+ if (attribute == xvFilter) {
+ pPPriv->Attribute[5] = !!value;
+ return Success;
+ } else if (attribute == xvInterlace) {
+ value %= 3;
+
+ if (value != pPPriv->Attribute[4]) {
+ int VideoOn = ABS(pPPriv->VideoOn);
+ int fh;
+
+ StopVideoStream(pAPriv, 1 << PORTNUM(pPPriv));
+
+ ReallocateOffscreenBuffer(pPPriv, 0);
+
+ pPPriv->Attribute[4] = value;
+
+ fh = InputVideoEncodings[pAPriv->VideoStd * 3].height >> (1 - (value & 1));
+ AdjustVideoH(pPPriv, fh, pPPriv->fh);
+ pPPriv->fh = fh;
+
+ if (VideoOn) {
+ if (StartVideoStream(pPPriv, NULL)) {
+ pPPriv->VideoOn = VideoOn;
+ if (pPPriv == &pAPriv->Port[1])
+ GetYUV(pPPriv);
+ } else {
+ pPPriv->VideoOn = -VideoOn;
+ return XvBadAlloc;
+ }
+ }
+ }
+
+ return Success;
+ }
+
+ if (PORTNUM(pPPriv) == 0) {
+ if (attribute == xvEncoding) {
+ if (value < 0 || value > 8) {
+ return XvBadEncoding;
+ }
+ /* Fall through */
+ } else if (attribute == xvBrightness) {
+ pPPriv->Attribute[0] = value = CLAMP(value, -1000, +1000);
+ return SetAttr(&pAPriv->Port[0], 0, 0x0A, 128 + (MIN(value, +999) * 128) / 1000);
+ } else if (attribute == xvContrast) {
+ pPPriv->Attribute[1] = value = CLAMP(value, -3000, +1000);
+ return SetAttr(&pAPriv->Port[0], 1, 0x0B, 64 + (MIN(value, +999) * 64) / 1000);
+ } else if (attribute == xvSaturation) {
+ pPPriv->Attribute[2] = value = CLAMP(value, -3000, +1000);
+ return SetAttr(&pAPriv->Port[0], 2, 0x0C, 64 + (MIN(value, +999) * 64) / 1000);
+ } else if (attribute == xvHue) {
+ pPPriv->Attribute[3] = value = CLAMP(value, -1000, +1000);
+ return SetAttr(&pAPriv->Port[0], 3, 0x0D, (MIN(value, +999) * 128) / 1000);
+ } else
+ return BadMatch;
+ } else { /* Output */
+ if (attribute == xvEncoding) {
+ if (value < 0 || value > 3)
+ return XvBadEncoding;
+ if (++value >= 3) value++;
+ } else if (attribute == xvBkgColor) {
+ pPPriv->Attribute[6] = value;
+ pPPriv->BkgCol = ((value & 0xF80000) >> 8) |
+ ((value & 0x00FC00) >> 5) |
+ ((value & 0x0000F8) >> 3);
+ pPPriv->BkgCol |= pPPriv->BkgCol << 16;
+ if (pPPriv->StreamOn) {
+ BlackOut(pPPriv, NULL);
+ GetYUV(pPPriv);
+ }
+ return Success;
+ } else
+ return Success;
+ }
+
+ if (attribute == xvEncoding) {
+ pPPriv->Plug = value % 3;
+
+ if (!SetPlug(pPPriv))
+ return XvBadAlloc;
+
+ value /= 3;
+
+ if (value != pAPriv->VideoStd) {
+ int VideoOn0 = ABS(pAPriv->Port[0].VideoOn);
+ int VideoOn1 = ABS(pAPriv->Port[1].VideoOn);
+ int fh;
+
+ StopVideoStream(pAPriv, 1 | 2);
+
+ if (value == 1 || pAPriv->VideoStd == 1) {
+ ReallocateOffscreenBuffer(&pAPriv->Port[0], 0);
+ ReallocateOffscreenBuffer(&pAPriv->Port[1], 0);
+ }
+
+ pAPriv->VideoStd = value;
+
+ SetVideoStd(pAPriv);
+
+ fh = InputVideoEncodings[pAPriv->VideoStd * 3].height >> (!pAPriv->Port[0].Attribute[4]);
+ AdjustVideoH(&pAPriv->Port[0], fh, pAPriv->Port[0].fh);
+ pAPriv->Port[0].fh = fh;
+
+ fh = InputVideoEncodings[pAPriv->VideoStd * 3].height >> (!pAPriv->Port[1].Attribute[4]);
+ AdjustVideoH(&pAPriv->Port[1], fh, pAPriv->Port[1].fh);
+ pAPriv->Port[1].fh = fh;
+
+ if (VideoOn0)
+ pAPriv->Port[0].VideoOn = (StartVideoStream(&pAPriv->Port[0], NULL)) ?
+ VideoOn0 : -VideoOn0;
+
+ if (VideoOn1) {
+ if (StartVideoStream(&pAPriv->Port[1], NULL)) {
+ pAPriv->Port[1].VideoOn = VideoOn1;
+ GetYUV(pPPriv);
+ } else
+ pAPriv->Port[1].VideoOn = -VideoOn1;
+ }
+
+ if (pAPriv->Port[0].VideoOn < 0 ||
+ pAPriv->Port[1].VideoOn < 0 ||
+ pAPriv->VideoStd != value)
+ return XvBadAlloc;
+ }
+ }
+
+ return Success;
+}
+
+/* Should update attrs via XVIPC too,
+ * Xv has XvPortNotify but no DDX equivalent.
+ */
+
+static int
+Permedia2GetPortAttribute(ScrnInfoPtr pScrn,
+ Atom attribute, INT32 *value, pointer data)
+{
+ PortPrivPtr pPPriv = (PortPrivPtr) data;
+ AdaptorPrivPtr pAPriv = pPPriv->pAdaptor;
+
+ if (attribute == xvEncoding)
+ *value = pAPriv->VideoStd * 3 + pPPriv->Plug;
+ else if (attribute == xvBrightness)
+ *value = pPPriv->Attribute[0];
+ else if (attribute == xvContrast)
+ *value = pPPriv->Attribute[1];
+ else if (attribute == xvSaturation)
+ *value = pPPriv->Attribute[2];
+ else if (attribute == xvHue)
+ *value = pPPriv->Attribute[3];
+ else if (attribute == xvInterlace)
+ *value = pPPriv->Attribute[4];
+ else if (attribute == xvFilter)
+ *value = pPPriv->Attribute[5];
+ else if (attribute == xvBkgColor)
+ *value = pPPriv->Attribute[6];
+ else
+ return BadMatch;
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "GPA attr=%d, val=%d, port=%d\n",
+ attribute, *value, PORTNUM(pPPriv)));
+
+ return Success;
+}
+
+static void
+Permedia2QueryBestSize(ScrnInfoPtr pScrn, Bool motion,
+ short vid_w, short vid_h, short drw_w, short drw_h,
+ unsigned int *p_w, unsigned int *p_h, pointer data)
+{
+ *p_w = drw_w;
+ *p_h = drw_h;
+}
+
+static Bool
+xvipcHandshake(PortPrivPtr pPPriv, int op, Bool block)
+{
+ int r;
+ int brake = 150;
+
+ xvipc.magic = XVIPC_MAGIC;
+ xvipc.op = op;
+ xvipc.block = block; /* Wait (with timeout), else don't wait for events
+ if none are pending. */
+
+ if (pPPriv) {
+ AdaptorPrivPtr pAPriv = pPPriv->pAdaptor;
+
+ xvipc.pm2p = pAPriv->pm2p;
+ xvipc.pAPriv = pAPriv;
+ xvipc.port = PORTNUM(pPPriv);
+ } else {
+ xvipc.pm2p = (void *) -1;
+ xvipc.pAPriv = NULL;
+ xvipc.port = -1;
+ }
+
+ while (TRUE) {
+ if (brake-- <= 0) return FALSE; /* We have a bug. */
+
+ DEBUG(xf86MsgVerb(X_INFO, 4,
+ "PM2 XVIPC send op=%d bl=%d po=%d a=%d b=%d c=%d\n",
+ xvipc.op, xvipc.block, xvipc.port, xvipc.a, xvipc.b, xvipc.c));
+
+ r = ioctl(xvipc_fd, VIDIOC_PM2_XVIPC, (void *) &xvipc);
+
+ DEBUG(xf86MsgVerb(X_INFO, 4,
+ "PM2 XVIPC recv op=%d bl=%d po=%d a=%d b=%d c=%d err=%d/%d\n",
+ xvipc.op, xvipc.block, xvipc.port, xvipc.a, xvipc.b, xvipc.c, r, errno));
+
+ switch (xvipc.op) {
+ case OP_ALLOC:
+ {
+ AdaptorPrivPtr pAPriv = xvipc.pAPriv;
+ ScrnInfoPtr pScrn = pAPriv->pScrn;
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ FBAreaPtr pFBArea;
+ LFBAreaPtr pLFBArea = NULL;
+
+ xvipc.a = -1;
+
+ if ((pFBArea = xf86AllocateLinearOffscreenArea(pScrn->pScreen,
+ xvipc.b >> BPPSHIFT(pGlint), 2, NULL, NULL, NULL)))
+ xvipc.a = ((pFBArea->box.y1 * pScrn->displayWidth) +
+ pFBArea->box.x1) << BPPSHIFT(pGlint);
+
+ if (ioctl(xvipc_fd, VIDIOC_PM2_XVIPC, (void *) &xvipc) != 0) {
+ if (pFBArea) xf86FreeOffscreenArea(pFBArea);
+ pFBArea = NULL;
+ }
+
+ if (pFBArea && (pLFBArea = xalloc(sizeof(LFBAreaRec)))) {
+ pLFBArea->Next = pAPriv->LFBList;
+ pLFBArea->pFBArea = pFBArea;
+ pLFBArea->Linear = xvipc.a;
+ pAPriv->LFBList = pLFBArea;
+ }
+
+ DEBUG(xf86MsgVerb(X_INFO, 3, "PM2 XVIPC alloc addr=%d=0x%08x pFB=%p pLFB=%p\n",
+ xvipc.a, xvipc.a, pFBArea, pLFBArea));
+
+ goto event;
+ }
+
+ case OP_FREE:
+ {
+ AdaptorPrivPtr pAPriv = xvipc.pAPriv;
+ LFBAreaPtr pLFBArea, *ppLFBArea;
+
+ for (ppLFBArea = &pAPriv->LFBList; (pLFBArea = *ppLFBArea);
+ ppLFBArea = &pLFBArea->Next)
+ if (pLFBArea->Linear == xvipc.a)
+ break;
+
+ if (!pLFBArea)
+ xvipc.a = -1;
+
+ DEBUG(xf86MsgVerb(X_INFO, 3, "PM2 XVIPC free addr=%d=0x%08x pLFB=%p\n",
+ xvipc.a, xvipc.a, pLFBArea));
+
+ if (ioctl(xvipc_fd, VIDIOC_PM2_XVIPC, (void *) &xvipc) == 0) {
+ xf86FreeOffscreenArea(pLFBArea->pFBArea);
+ *ppLFBArea = pLFBArea->Next;
+ xfree(pLFBArea);
+ pLFBArea = NULL;
+ }
+
+ goto event;
+ }
+
+ case OP_UPDATE:
+ {
+ AdaptorPrivPtr pAPriv = xvipc.pAPriv;
+ PortPrivPtr pPPriv;
+
+ pPPriv = &pAPriv->Port[0];
+
+ if (pPPriv->VideoOn >= 1 && xvipc.a > 0) {
+ pPPriv->FrameAcc += pPPriv->FramesPerSec;
+ if (pPPriv->FrameAcc >= pAPriv->FramesPerSec) {
+ pPPriv->FrameAcc -= pAPriv->FramesPerSec;
+
+ /* Asynchronous resizing caused by kernel app */
+
+ if (xvipc.c != pPPriv->fw ||
+ xvipc.d != pPPriv->fh) {
+ AdjustVideoW(pPPriv, xvipc.c, pPPriv->fw);
+ AdjustVideoH(pPPriv, xvipc.d, pPPriv->fh);
+ pPPriv->fw = xvipc.c;
+ pPPriv->fh = xvipc.d;
+ pPPriv->BufferPProd = xvipc.e;
+
+ PutCookies(pPPriv, NULL);
+ }
+
+ PutYUV(pPPriv, xvipc.a);
+
+ if (pPPriv->VideoOn == 1)
+ pPPriv->VideoOn = 0;
+ }
+ } else if (pPPriv->APO >= 0 && !(pPPriv->APO--))
+ DelayedStopVideo(pPPriv);
+
+ pPPriv = &pAPriv->Port[1];
+
+ if (pPPriv->VideoOn >= 1 && xvipc.b > 0) {
+ pPPriv->FrameAcc += pPPriv->FramesPerSec;
+ if (pPPriv->FrameAcc >= pAPriv->FramesPerSec) {
+ pPPriv->FrameAcc -= pAPriv->FramesPerSec;
+
+ pPPriv->BufferBase[0] = xvipc.b;
+
+ /* Output is always exclusive, no async resizing */
+
+ GetYUV(pPPriv);
+
+ if (pPPriv->VideoOn == 1)
+ pPPriv->VideoOn = 0;
+ }
+ } else if (pPPriv->APO >= 0 && !(pPPriv->APO--))
+ DelayedStopVideo(pPPriv);
+
+ /* Fall through */
+ }
+
+ default:
+ event:
+ if (xvipc.op == op)
+ return r == 0;
+
+ xvipc.op = OP_EVENT;
+ xvipc.block = block;
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+Permedia2ReadInput(int fd, pointer unused)
+{
+ xvipcHandshake(NULL, OP_EVENT, FALSE);
+}
+
+static void
+AdaptorPrivUninit(AdaptorPrivPtr pAPriv)
+{
+ GLINTPtr pGlint = GLINTPTR(pAPriv->pScrn);
+
+ if (!pAPriv->pm2p) {
+ TimerFree(pAPriv->Timer);
+ xf86DestroyI2CDevRec(&pAPriv->Port[0].I2CDev, FALSE);
+ xf86DestroyI2CDevRec(&pAPriv->Port[1].I2CDev, FALSE);
+ GLINT_MASK_WRITE_REG(VS_UnitMode_ROM, ~VS_UnitMode_Mask, VSConfiguration);
+ GLINT_WRITE_REG(pAPriv->FifoControl, PMFifoControl);
+ }
+
+ FreeCookies(&pAPriv->Port[0]);
+ FreeCookies(&pAPriv->Port[1]);
+
+ xfree(pAPriv);
+}
+
+/* Only a single file for all heads, the device ID is transmitted at initial
+ * handshake and encoded in all subsequent xvipc headers.
+ */
+
+static Bool
+xvipcOpen(char *name, ScrnInfoPtr pScrn)
+{
+ const char *osname;
+
+ if (xvipc_fd >= 0)
+ return TRUE;
+
+ xf86GetOS(&osname, NULL, NULL, NULL);
+
+ if (!osname || strcmp(osname, "linux"))
+ return FALSE;
+
+ while (1) {
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "XVIPC probing device %s\n", name));
+
+ if ((xvipc_fd = open(name, O_RDWR /* | O_TRUNC */, 0)) < 0)
+ break;
+
+ xvipc.magic = XVIPC_MAGIC;
+ xvipc.pm2p = (void *) -1;
+ xvipc.pAPriv = NULL;
+ xvipc.op = OP_CONNECT;
+ xvipc.a = 0;
+ xvipc.b = 0;
+ xvipc.c = 0;
+ xvipc.d = 0;
+
+ if (ioctl(xvipc_fd, VIDIOC_PM2_XVIPC, (void *) &xvipc) < 0 || xvipc.pm2p)
+ break;
+
+ if (xvipc.c != XVIPC_VERSION) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Your Permedia 2 kernel driver %d.%d uses XVIPC protocol "
+ "V.%d while this Xv driver expects V.%d. Please update.\n",
+ xvipc.a, xvipc.b, xvipc.c, XVIPC_VERSION);
+ break;
+ }
+
+ /* Typical input devices should be closed when VT switched away, but
+ * this is proprietary IPC between this driver and the kernel driver
+ * only. Actually, it would be better to continue listening to kernel
+ * events, at least keeping the file open, to avoid side effects of
+ * repeated dis- and reconnection, shouldn't hurt.
+ */
+
+ xf86AddInputHandler(xvipc_fd, Permedia2ReadInput, NULL);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Xv driver connected to %s\n", name);
+
+ return TRUE;
+ }
+
+ if (xvipc_fd >= 0)
+ close(xvipc_fd);
+
+ xvipc_fd = -1;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Cannot connect to Permedia 2 kernel driver. "
+ "Note that using both drivers at the same time "
+ "will cause problems.\n");
+ return FALSE;
+}
+
+static AdaptorPrivPtr
+AdaptorPrivInit(ScrnInfoPtr pScrn)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ AdaptorPrivPtr pAPriv = (AdaptorPrivPtr) xcalloc(1, sizeof(AdaptorPrivRec));
+ int i;
+
+ if (pAPriv) {
+ pAPriv->pScrn = pScrn;
+ pAPriv->Port[0].pAdaptor = pAPriv;
+ pAPriv->Port[1].pAdaptor = pAPriv;
+
+ pAPriv->Port[0].Attribute[0] = 0; /* Brightness (-1000..+1000) */
+ pAPriv->Port[0].Attribute[1] = 0; /* Contrast (-3000..+1000) */
+ pAPriv->Port[0].Attribute[2] = 0; /* Color saturation (-3000..+1000) */
+ pAPriv->Port[0].Attribute[3] = 0; /* Hue (-1000..+1000) */
+ pAPriv->Port[0].Attribute[4] = 1; /* Interlaced (0 = not, 1 = yes, 2 = dscan) */
+ pAPriv->Port[0].Attribute[5] = 0; /* Bilinear Filter (Bool) */
+
+ pAPriv->Port[1].Attribute[4] = 1; /* Interlaced (Bool) */
+ pAPriv->Port[1].Attribute[5] = 0; /* Bilinear Filter (Bool) */
+ pAPriv->Port[1].Attribute[6] = 0; /* BkgColor 0x00RRGGBB */
+ pAPriv->Port[1].BkgCol = 0;
+
+ pAPriv->Port[0].Buffers = 2;
+ pAPriv->Port[1].Buffers = 1;
+
+ for (i = 0; i <= 1; i++) {
+ pAPriv->Port[i].fw = 704;
+ pAPriv->Port[i].fh = 576;
+ pAPriv->Port[i].FramesPerSec = 30;
+ pAPriv->Port[i].APO = -1;
+ pAPriv->Port[i].BufferPProd = partprodPermedia[704 >> 5];
+ }
+
+ if (xvipc_fd >= 0) {
+ /* Initial handshake, take over control of this head */
+
+ xvipc.magic = XVIPC_MAGIC;
+ xvipc.pm2p = (void *) -1; /* Kernel head ID */
+ xvipc.pAPriv = pAPriv; /* Server head ID */
+ xvipc.op = OP_CONNECT;
+
+ xvipc.a = pGlint->PciInfo->bus;
+ xvipc.b = pGlint->PciInfo->device;
+ xvipc.c = pGlint->PciInfo->func;
+
+ xvipc.d = pScrn->videoRam << 10; /* XF86Config overrides probing */
+
+ if (ioctl(xvipc_fd, VIDIOC_PM2_XVIPC, (void *) &xvipc) < 0) {
+ if (errno == EBUSY)
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Another application already opened the Permedia 2 "
+ "kernel driver for this board. To enable "
+ "shared access please start the server first.\n");
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Initialization of Xv support with kernel backbone "
+ "failed due to error %d: %s.\n", errno, strerror(errno));
+ goto failed;
+ }
+
+ pAPriv->pm2p = xvipc.pm2p;
+
+ SetVideoStd(pAPriv);
+ } else {
+ GLINT_WRITE_REG(0, VSABase + VSControl);
+ GLINT_WRITE_REG(0, VSBBase + VSControl);
+#if 0
+ GLINT_MASK_WRITE_REG(0, ~(VSAIntFlag | VSBIntFlag), IntEnable);
+ GLINT_WRITE_REG(VSAIntFlag | VSBIntFlag, IntFlags); /* Reset */
+#endif
+ for (i = 0x0018; i <= 0x00B0; i += 8) {
+ GLINT_WRITE_REG(0, VSABase + i);
+ GLINT_WRITE_REG(0, VSBBase + i);
+ }
+
+ GLINT_WRITE_REG((0 << 8) | (132 << 0), VSABase + VSFifoControl);
+ GLINT_WRITE_REG((0 << 8) | (132 << 0), VSBBase + VSFifoControl);
+
+ GLINT_MASK_WRITE_REG(
+ VS_UnitMode_AB8 |
+ VS_GPBusMode_A |
+ /* VS_HRefPolarityA | */
+ VS_VRefPolarityA |
+ VS_VActivePolarityA |
+ /* VS_UseFieldA | */
+ VS_FieldPolarityA |
+ /* VS_FieldEdgeA | */
+ /* VS_VActiveVBIA | */
+ VS_InterlaceA |
+ VS_ReverseDataA |
+
+ /* VS_HRefPolarityB | */
+ VS_VRefPolarityB |
+ VS_VActivePolarityB |
+ /* VS_UseFieldB | */
+ VS_FieldPolarityB |
+ /* VS_FieldEdgeB | */
+ /* VS_VActiveVBIB | */
+ VS_InterlaceB |
+ /* VS_ColorSpaceB_RGB | */
+ /* VS_ReverseDataB | */
+ /* VS_DoubleEdgeB | */
+ 0, ~0x1FFFFE0F, VSConfiguration);
+
+ pAPriv->FifoControl = GLINT_READ_REG(PMFifoControl);
+ GLINT_WRITE_REG((12 << 8) | 8, PMFifoControl); /* FIXME */
+
+ if (!xf86I2CProbeAddress(pGlint->VSBus, SAA7111_SLAVE_ADDRESS))
+ goto failed;
+
+ pAPriv->Port[0].I2CDev.DevName = "Decoder";
+ pAPriv->Port[0].I2CDev.SlaveAddr = SAA7111_SLAVE_ADDRESS;
+ pAPriv->Port[0].I2CDev.pI2CBus = pGlint->VSBus;
+
+ if (!xf86I2CDevInit(&pAPriv->Port[0].I2CDev))
+ goto failed;
+
+ if (!xf86I2CWriteVec(&pAPriv->Port[0].I2CDev, DecInitVec,
+ (sizeof(DecInitVec) / sizeof(I2CByte)) / 2))
+ goto failed;
+
+ if (!xf86I2CProbeAddress(pGlint->VSBus, SAA7125_SLAVE_ADDRESS))
+ goto failed;
+
+ pAPriv->Port[1].I2CDev.DevName = "Encoder";
+ pAPriv->Port[1].I2CDev.SlaveAddr = SAA7125_SLAVE_ADDRESS;
+ pAPriv->Port[1].I2CDev.pI2CBus = pGlint->VSBus;
+
+ if (!xf86I2CDevInit(&pAPriv->Port[1].I2CDev))
+ goto failed;
+
+ if (!xf86I2CWriteVec(&pAPriv->Port[1].I2CDev, EncInitVec,
+ (sizeof(EncInitVec) / sizeof(I2CByte)) / 2))
+ goto failed;
+
+ SetVideoStd(pAPriv);
+
+ pAPriv->Timer = TimerSet(NULL, 0, 0, TimerCallback, pAPriv);
+
+ if (!pAPriv->Timer)
+ goto failed;
+ }
+
+ return pAPriv;
+
+failed:
+ AdaptorPrivUninit(pAPriv);
+ }
+
+ return NULL;
+}
+
+void
+Permedia2VideoUninit(ScrnInfoPtr pScrn)
+{
+ AdaptorPrivPtr pAPriv, *ppAPriv;
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1, "Xv driver cleanup\n"));
+
+ for (ppAPriv = &AdaptorPrivList; (pAPriv = *ppAPriv); ppAPriv = &(pAPriv->Next))
+ if (pAPriv->pScrn == pScrn) {
+ *ppAPriv = pAPriv->Next;
+ StopVideoStream(pAPriv, 1 | 2 | 4);
+ AdaptorPrivUninit(pAPriv);
+ break;
+ }
+
+ if (xvipc_fd >= 0) {
+ close(xvipc_fd);
+ xvipc_fd = -1;
+ }
+}
+
+/* Required to retire delayed stop (VT switching away) */
+
+void
+Permedia2VideoReset(ScrnInfoPtr pScrn)
+{
+ AdaptorPrivPtr pAPriv;
+
+ for (pAPriv = AdaptorPrivList; pAPriv != NULL; pAPriv = pAPriv->Next)
+ if (pAPriv->pScrn == pScrn) {
+ StopVideoStream(pAPriv, 1 | 2 | 4);
+ break;
+ }
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1, "Xv driver halted\n"));
+}
+
+void
+Permedia2VideoInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ AdaptorPrivPtr pAPriv;
+ DevUnion Private[2];
+ XF86VideoAdaptorRec VAR[2];
+ XF86VideoAdaptorPtr VARPtrs[2];
+ pointer options[3];
+ Bool VideoIO = TRUE;
+ int i;
+
+ options[0] = NULL;
+ options[1] = NULL;
+ options[2] = NULL;
+
+ for (i = 0;; i++) {
+ char *adaptor;
+
+ if (!options[0])
+ options[0] = xf86FindXvOptions(pScreen->myNum, i, "input", &adaptor, &options[2]);
+ if (!options[1])
+ options[1] = xf86FindXvOptions(pScreen->myNum, i, "output", &adaptor, NULL);
+ if (!adaptor) {
+ if (!i) VideoIO = FALSE;
+ break;
+ } else if (options[0] && options[1])
+ break;
+ }
+
+ if (!VideoIO) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1, "Xv driver disabled\n");
+ return;
+ }
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 1, "Initializing Xv driver\n");
+
+ switch (pGlint->Chipset) {
+ case PCI_VENDOR_TI_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2:
+ case PCI_VENDOR_3DLABS_CHIP_PERMEDIA2V:
+ break;
+ default:
+ VideoIO = FALSE;
+ }
+
+ switch (pciReadLong(pGlint->PciTag, PCI_SUBSYSTEM_ID_REG)) {
+ case PCI_SUBSYSTEM_ID_WINNER_2000_P2A:
+ case PCI_SUBSYSTEM_ID_WINNER_2000_P2C:
+ case PCI_SUBSYSTEM_ID_GLORIA_SYNERGY_P2A:
+ case PCI_SUBSYSTEM_ID_GLORIA_SYNERGY_P2C:
+ break;
+ default:
+ VideoIO = FALSE;
+ }
+
+ if (!VideoIO) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 1, "No Xv support for this board\n");
+ return;
+ }
+
+ for (i = 0; i <= 2; i++) {
+ xf86ProcessOptions(pScrn->scrnIndex, options[i],
+ (i == 0) ? InputOptions : ((i == 1) ? OutputOptions : AdaptorOptions));
+ xf86ShowUnusedOptions(pScrn->scrnIndex, options[i]);
+ }
+
+ if (xf86IsOptionSet(AdaptorOptions, OPTION_DEVICE))
+ xvipcOpen(xf86GetOptValString(AdaptorOptions, OPTION_DEVICE), pScrn);
+
+ if (!(pAPriv = AdaptorPrivInit(pScrn))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Xv driver initialization failed\n");
+ return;
+ }
+
+ for (i = 0; i <= 1; i++) {
+ int n;
+
+ if (xf86GetOptValInteger(i ? OutputOptions : InputOptions, OPTION_BUFFERS, &n))
+ pAPriv->Port[i].Buffers = CLAMP(n, 1, i ? 1 : 2); /* FIXME */
+ if (xf86GetOptValInteger(i ? OutputOptions : InputOptions, OPTION_FPS, &n))
+ pAPriv->Port[i].FramesPerSec = CLAMP(n, 1, 30);
+ }
+
+ if (pGlint->NoAccel) {
+ BoxRec AvailFBArea;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Xv driver overrides NoAccel option\n");
+
+ Permedia2InitializeEngine(pScrn);
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = pGlint->FbMapSize /
+ (pScrn->displayWidth * pScrn->bitsPerPixel / 8);
+
+ /* if (AvailFBArea.y2 > 2047)
+ AvailFBArea.y2 = 2047; */
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+ }
+
+ memset(VAR, 0, sizeof(VAR));
+
+ for (i = 0; i < 2; i++) {
+ Private[i].ptr = (pointer) &pAPriv->Port[i];
+ VARPtrs[i] = &VAR[i];
+
+ VAR[i].type = (i == 0) ? XvInputMask : XvOutputMask;
+ VAR[i].name = "Permedia 2";
+
+ if (i == 0) {
+ VAR[0].nEncodings = sizeof(InputVideoEncodings) / sizeof(InputVideoEncodings[0]);
+ VAR[0].pEncodings = InputVideoEncodings;
+ VAR[0].nFormats = sizeof(InputVideoFormats) / sizeof(InputVideoFormats[0]);
+ VAR[0].pFormats = InputVideoFormats;
+ } else {
+ Bool expose = FALSE;
+
+ xf86GetOptValBool(OutputOptions, OPTION_EXPOSE, &expose);
+ if (expose) VAR[1].flags = VIDEO_EXPOSE;
+
+ VAR[1].nEncodings = sizeof(OutputVideoEncodings) / sizeof(OutputVideoEncodings[0]);
+ VAR[1].pEncodings = OutputVideoEncodings;
+ VAR[1].nFormats = sizeof(OutputVideoFormats) / sizeof(OutputVideoFormats[0]);
+ VAR[1].pFormats = OutputVideoFormats;
+ }
+
+ VAR[i].nPorts = 1;
+ VAR[i].pPortPrivates = &Private[i];
+ VAR[i].PutVideo = Permedia2PutVideo;
+ VAR[i].PutStill = Permedia2PutStill;
+ VAR[i].GetVideo = Permedia2GetVideo;
+ VAR[i].GetStill = Permedia2GetStill;
+ VAR[i].StopVideo = Permedia2StopVideo;
+ VAR[i].SetPortAttribute = Permedia2SetPortAttribute;
+ VAR[i].GetPortAttribute = Permedia2GetPortAttribute;
+ VAR[i].QueryBestSize = Permedia2QueryBestSize;
+ }
+
+ if (!xf86XVScreenInit(pScreen, VARPtrs, 2)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Xv initialization failed\n");
+ return;
+ }
+
+ xvEncoding = MAKE_ATOM(XV_ENCODING);
+ xvHue = MAKE_ATOM(XV_HUE);
+ xvSaturation = MAKE_ATOM(XV_SATURATION);
+ xvBrightness = MAKE_ATOM(XV_BRIGHTNESS);
+ xvContrast = MAKE_ATOM(XV_CONTRAST);
+ xvInterlace = MAKE_ATOM(XV_INTERLACE);
+ xvFilter = MAKE_ATOM(XV_FILTER);
+ xvBkgColor = MAKE_ATOM(XV_BKGCOLOR);
+
+ pAPriv->Next = AdaptorPrivList;
+ AdaptorPrivList = pAPriv;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Xv driver %senabled\n",
+ (xvipc_fd >= 0) ? "with kernel backbone " : "");
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2ramdac.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2ramdac.c
new file mode 100644
index 000000000..2266a16b0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2ramdac.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright 1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Permedia2OutIndReg() and Permedia2InIndReg() are used to access
+ * the indirect Permedia2 RAMDAC registers only.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm2ramdac.c,v 1.10 1999/07/18 03:26:57 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "glint_regs.h"
+#include "glint.h"
+
+void
+Permedia2OutIndReg(ScrnInfoPtr pScrn,
+ CARD32 reg, unsigned char mask, unsigned char data)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ unsigned char tmp = 0x00;
+
+ GLINT_SLOW_WRITE_REG (reg, PM2DACIndexReg);
+
+ if (mask != 0x00)
+ tmp = GLINT_READ_REG (PM2DACIndexData) & mask;
+
+ GLINT_SLOW_WRITE_REG (tmp | data, PM2DACIndexData);
+}
+
+unsigned char
+Permedia2InIndReg (ScrnInfoPtr pScrn, CARD32 reg)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ unsigned char ret;
+
+ GLINT_SLOW_WRITE_REG (reg, PM2DACIndexReg);
+ ret = GLINT_READ_REG (PM2DACIndexData);
+
+ return (ret);
+}
+
+void
+Permedia2WriteAddress (ScrnInfoPtr pScrn, CARD32 index)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_SLOW_WRITE_REG(index, PM2DACWriteAddress);
+}
+
+void
+Permedia2WriteData (ScrnInfoPtr pScrn, unsigned char data)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_SLOW_WRITE_REG(data, PM2DACData);
+}
+
+void
+Permedia2ReadAddress (ScrnInfoPtr pScrn, CARD32 index)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_SLOW_WRITE_REG(0xFF, PM2DACReadMask);
+ GLINT_SLOW_WRITE_REG(index, PM2DACReadAddress);
+}
+
+unsigned char
+Permedia2ReadData (ScrnInfoPtr pScrn)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ GLINTDACDelay(5);
+ return(GLINT_READ_REG(PM2DACData));
+}
+
+void Permedia2LoadPalette(
+ ScrnInfoPtr pScrn,
+ int numColors,
+ int *indices,
+ LOCO *colors,
+ VisualPtr pVisual
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int i, index, shift;
+
+ shift = (pScrn->depth == 15) ? 3 : 0;
+
+ for(i = 0; i < numColors; i++) {
+ index = indices[i];
+ Permedia2WriteAddress(pScrn, index << shift);
+ Permedia2WriteData(pScrn, colors[index].red);
+ Permedia2WriteData(pScrn, colors[index].green);
+ Permedia2WriteData(pScrn, colors[index].blue);
+ /* for video i/o */
+ GLINT_SLOW_WRITE_REG(index, TexelLUTIndex);
+ GLINT_SLOW_WRITE_REG((colors[index].red & 0xFF) |
+ ((colors[index].green & 0xFF) << 8) |
+ ((colors[index].blue & 0xFF) << 16),
+ TexelLUTData);
+ }
+}
+
+/* special one for 565 mode */
+void Permedia2LoadPalette16(
+ ScrnInfoPtr pScrn,
+ int numColors,
+ int *indices,
+ LOCO *colors,
+ VisualPtr pVisual
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int i, index;
+
+ for(i = 0; i < numColors; i++) {
+ index = indices[i];
+ Permedia2WriteAddress(pScrn, index << 2);
+ Permedia2WriteData(pScrn, colors[index >> 1].red);
+ Permedia2WriteData(pScrn, colors[index].green);
+ Permedia2WriteData(pScrn, colors[index >> 1].blue);
+ GLINT_SLOW_WRITE_REG(index, TexelLUTIndex);
+ GLINT_SLOW_WRITE_REG((colors[index].red & 0xFF) |
+ ((colors[index].green & 0xFF) << 8) |
+ ((colors[index].blue & 0xFF) << 16),
+ TexelLUTData);
+
+ if(index <= 31) {
+ Permedia2WriteAddress(pScrn, index << 3);
+ Permedia2WriteData(pScrn, colors[index].red);
+ Permedia2WriteData(pScrn, colors[(index << 1) + 1].green);
+ Permedia2WriteData(pScrn, colors[index].blue);
+ }
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2v_dac.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2v_dac.c
new file mode 100644
index 000000000..481cc98b9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2v_dac.c
@@ -0,0 +1,456 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane <alanh@fairlite.demon.co.uk>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ * Dirk Hohndel, <hohndel@suse.de>
+ * Stefan Dirsch, <sndirsch@suse.de>
+ * Helmut Fahrion, <hf@suse.de>
+ *
+ * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and
+ * Siemens Nixdorf Informationssysteme
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm2v_dac.c,v 1.12 1999/07/04 06:39:02 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "glint_regs.h"
+#include "glint.h"
+
+static int
+Shiftbpp(ScrnInfoPtr pScrn, int value)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ /* shift horizontal timings for 64bit VRAM's or 32bit SGRAMs */
+ int logbytesperaccess = 2;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ value >>= logbytesperaccess;
+ pGlint->BppShift = logbytesperaccess;
+ break;
+ case 16:
+ if (pGlint->DoubleBuffer) {
+ value >>= (logbytesperaccess-2);
+ pGlint->BppShift = logbytesperaccess-2;
+ } else {
+ value >>= (logbytesperaccess-1);
+ pGlint->BppShift = logbytesperaccess-1;
+ }
+ break;
+ case 24:
+ value *= 3;
+ value >>= logbytesperaccess;
+ pGlint->BppShift = logbytesperaccess;
+ break;
+ case 32:
+ value >>= (logbytesperaccess-2);
+ pGlint->BppShift = logbytesperaccess-2;
+ break;
+ }
+ return (value);
+}
+
+static unsigned long
+PM2VDAC_CalculateClock
+(
+ unsigned long reqclock, /* In kHz units */
+ unsigned long refclock, /* In kHz units */
+ unsigned char *prescale, /* ClkPreScale */
+ unsigned char *feedback, /* ClkFeedBackScale */
+ unsigned char *postscale /* ClkPostScale */
+ )
+{
+ int f, pre, post;
+ unsigned long freq;
+ long freqerr = 1000;
+ unsigned long actualclock = 0;
+ unsigned char divide[5] = { 1, 2, 4, 8, 16 };
+
+ for (f=1;f<256;f++) {
+ for (pre=1;pre<256;pre++) {
+ for (post=0;post<2;post++) {
+ freq = ((refclock * f) / (pre * (1 << divide[post])));
+ if ((reqclock > freq - freqerr)&&(reqclock < freq + freqerr)){
+ freqerr = (reqclock > freq) ?
+ reqclock - freq : freq - reqclock;
+ *feedback = f;
+ *prescale = pre;
+ *postscale = post;
+ actualclock = freq;
+ }
+ }
+ }
+ }
+
+ return(actualclock);
+}
+
+Bool
+Permedia2VInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ GLINTRegPtr pReg = &pGlint->ModeReg;
+ CARD32 temp1, temp2, temp3, temp4;
+
+ pReg->glintRegs[Aperture0 >> 3] = 0;
+ pReg->glintRegs[Aperture1 >> 3] = 0;
+ pReg->glintRegs[PMFramebufferWriteMask >> 3] = 0xFFFFFFFF;
+ pReg->glintRegs[PMBypassWriteMask >> 3] = 0xFFFFFFFF;
+
+ if (pGlint->UsePCIRetry) {
+ pReg->glintRegs[DFIFODis >> 3] = 1;
+ pReg->glintRegs[FIFODis >> 3] = 3;
+ } else {
+ pReg->glintRegs[DFIFODis >> 3] = 0;
+ pReg->glintRegs[FIFODis >> 3] = 1;
+ }
+
+ if (pGlint->UseBlockWrite)
+ pReg->glintRegs[PMMemConfig >> 3] = GLINT_READ_REG(PMMemConfig) | 1<<21;
+
+ temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay;
+ temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay;
+ temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart;
+ temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+
+ pReg->glintRegs[PMHTotal >> 3] = Shiftbpp(pScrn,mode->CrtcHTotal);
+ pReg->glintRegs[PMHsEnd >> 3] = Shiftbpp(pScrn, temp1 + temp3);
+ pReg->glintRegs[PMHsStart >> 3] = Shiftbpp(pScrn, temp1);
+ pReg->glintRegs[PMHbEnd >> 3] =
+ Shiftbpp(pScrn,mode->CrtcHTotal-mode->CrtcHDisplay);
+ pReg->glintRegs[PMScreenStride >> 3] =
+ Shiftbpp(pScrn,pScrn->displayWidth>>1);
+
+ pReg->glintRegs[PMVTotal >> 3] = mode->CrtcVTotal;
+ pReg->glintRegs[PMVsEnd >> 3] = temp2 + temp4;
+ pReg->glintRegs[PMVsStart >> 3] = temp2;
+ pReg->glintRegs[PMVbEnd >> 3] = mode->CrtcVTotal - mode->CrtcVDisplay;
+
+ /* The hw cursor needs /VSYNC to recognize vert retrace. We'll stick
+ both sync lines to active low here and if needed invert them
+ using the RAMDAC's RDSyncControl below. */
+ pReg->glintRegs[PMVideoControl >> 3] =
+ (1 << 5) | (1 << 3) | 1;
+
+ /* We stick the RAMDAC into 64bit mode */
+ /* And reduce the horizontal timings and clock by half */
+ pReg->glintRegs[PMVideoControl >> 3] |= 1<<16;
+ pReg->glintRegs[PMHTotal >> 3] >>= 1;
+ pReg->glintRegs[PMHsEnd >> 3] >>= 1;
+ pReg->glintRegs[PMHsStart >> 3] >>= 1;
+ pReg->glintRegs[PMHbEnd >> 3] >>= 1;
+
+ pReg->glintRegs[VClkCtl >> 3] = (GLINT_READ_REG(VClkCtl) & 0xFFFFFFFC);
+ pReg->glintRegs[PMScreenBase >> 3] = 0;
+ pReg->glintRegs[PMHTotal >> 3] -= 1;
+ pReg->glintRegs[PMHsStart >> 3] -= 1; /* PMHsStart */
+ pReg->glintRegs[PMVTotal >> 3] -= 1; /* PMVTotal */
+
+ pReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig) & 0xFFFFFFDD;
+ pReg->DacRegs[PM2VDACRDDACControl] = 0x00;
+
+ {
+ /* Get the programmable clock values */
+ unsigned char m,n,p;
+ unsigned long clockused;
+
+ clockused = PM2VDAC_CalculateClock(mode->Clock/2,pGlint->RefClock,
+ &m,&n,&p);
+ pReg->DacRegs[PM2VDACRDDClk0PreScale] = m;
+ pReg->DacRegs[PM2VDACRDDClk0FeedbackScale] = n;
+ pReg->DacRegs[PM2VDACRDDClk0PostScale] = p;
+ }
+
+ pReg->DacRegs[PM2VDACRDIndexControl] = 0x00;
+
+ if (pScrn->rgbBits == 8)
+ pReg->DacRegs[PM2VDACRDMiscControl] = 0x01; /* 8bit DAC */
+ else
+ pReg->DacRegs[PM2VDACRDMiscControl] = 0x00; /* 6bit DAC */
+
+ pReg->DacRegs[PM2VDACRDSyncControl] = 0x00;
+ if (!(mode->Flags & V_PHSYNC))
+ pReg->DacRegs[PM2VDACRDSyncControl] |= 0x01; /* invert hsync */
+ if (!(mode->Flags & V_PVSYNC))
+ pReg->DacRegs[PM2VDACRDSyncControl] |= 0x04; /* invert vsync */
+
+ switch (pScrn->bitsPerPixel)
+ {
+ case 8:
+ pReg->DacRegs[PM2VDACRDPixelSize] = 0x00;
+ pReg->DacRegs[PM2VDACRDColorFormat] = 0x2E;
+ break;
+ case 15:
+ pReg->DacRegs[PM2VDACRDMiscControl] |= 0x08;
+ pReg->DacRegs[PM2VDACRDPixelSize] = 0x01;
+ pReg->DacRegs[PM2VDACRDColorFormat] = 0x61;
+ break;
+ case 16:
+ pReg->DacRegs[PM2VDACRDMiscControl] |= 0x08;
+ pReg->DacRegs[PM2VDACRDPixelSize] = 0x01;
+ pReg->DacRegs[PM2VDACRDColorFormat] = 0x70;
+ break;
+ case 24:
+ pReg->DacRegs[PM2VDACRDMiscControl] |= 0x08;
+ pReg->DacRegs[PM2VDACRDPixelSize] = 0x04;
+ pReg->DacRegs[PM2VDACRDColorFormat] = 0x60;
+ break;
+ case 32:
+ pReg->DacRegs[PM2VDACRDMiscControl] |= 0x08;
+ pReg->DacRegs[PM2VDACRDPixelSize] = 0x02;
+ pReg->DacRegs[PM2VDACRDColorFormat] = 0x20;
+ if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
+ pReg->DacRegs[PM2VDACRDMiscControl] |= 0x10;
+ pReg->DacRegs[PM2VDACRDOverlayKey] = 0xFF;
+ }
+ break;
+ }
+
+ return(TRUE);
+}
+
+void
+Permedia2VSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int i;
+
+ glintReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig);
+ glintReg->glintRegs[Aperture0 >> 3] = GLINT_READ_REG(Aperture0);
+ glintReg->glintRegs[Aperture1 >> 3] = GLINT_READ_REG(Aperture1);
+ glintReg->glintRegs[PMFramebufferWriteMask >> 3] =
+ GLINT_READ_REG(PMFramebufferWriteMask);
+ glintReg->glintRegs[PMBypassWriteMask >> 3] =
+ GLINT_READ_REG(PMBypassWriteMask);
+ glintReg->glintRegs[DFIFODis >> 3] = GLINT_READ_REG(DFIFODis);
+ glintReg->glintRegs[FIFODis >> 3] = GLINT_READ_REG(FIFODis);
+ /* We only muck about with PMMemConfig, if user wants to */
+ if (pGlint->UseBlockWrite)
+ glintReg->glintRegs[PMMemConfig >> 3] = GLINT_READ_REG(PMMemConfig);
+ glintReg->glintRegs[PMHTotal >> 3] = GLINT_READ_REG(PMHTotal);
+ glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHbEnd);
+ glintReg->glintRegs[PMHbEnd >> 3] = GLINT_READ_REG(PMHgEnd);
+ glintReg->glintRegs[PMScreenStride >> 3] = GLINT_READ_REG(PMScreenStride);
+ glintReg->glintRegs[PMHsStart >> 3] = GLINT_READ_REG(PMHsStart);
+ glintReg->glintRegs[PMHsEnd >> 3] = GLINT_READ_REG(PMHsEnd);
+ glintReg->glintRegs[PMVTotal >> 3] = GLINT_READ_REG(PMVTotal);
+ glintReg->glintRegs[PMVbEnd >> 3] = GLINT_READ_REG(PMVbEnd);
+ glintReg->glintRegs[PMVsStart >> 3] = GLINT_READ_REG(PMVsStart);
+ glintReg->glintRegs[PMVsEnd >> 3] = GLINT_READ_REG(PMVsEnd);
+ glintReg->glintRegs[PMScreenBase >> 3] = GLINT_READ_REG(PMScreenBase);
+ glintReg->glintRegs[PMVideoControl >> 3] = GLINT_READ_REG(PMVideoControl);
+ glintReg->glintRegs[VClkCtl >> 3] = GLINT_READ_REG(VClkCtl);
+
+ for (i=0;i<768;i++) {
+ Permedia2ReadAddress(pScrn, i);
+ glintReg->cmap[i] = Permedia2ReadData(pScrn);
+ }
+
+ glintReg->DacRegs[PM2VDACRDIndexControl] =
+ Permedia2vInIndReg(pScrn, PM2VDACRDIndexControl);
+ glintReg->DacRegs[PM2VDACRDOverlayKey] =
+ Permedia2vInIndReg(pScrn, PM2VDACRDOverlayKey);
+ glintReg->DacRegs[PM2VDACRDSyncControl] =
+ Permedia2vInIndReg(pScrn, PM2VDACRDSyncControl);
+ glintReg->DacRegs[PM2VDACRDMiscControl] =
+ Permedia2vInIndReg(pScrn, PM2VDACRDMiscControl);
+ glintReg->DacRegs[PM2VDACRDDACControl] =
+ Permedia2vInIndReg(pScrn, PM2VDACRDDACControl);
+ glintReg->DacRegs[PM2VDACRDPixelSize] =
+ Permedia2vInIndReg(pScrn, PM2VDACRDPixelSize);
+ glintReg->DacRegs[PM2VDACRDColorFormat] =
+ Permedia2vInIndReg(pScrn, PM2VDACRDColorFormat);
+
+ glintReg->DacRegs[PM2VDACRDDClk0PreScale] = Permedia2vInIndReg(pScrn, PM2VDACRDDClk0PreScale);
+ glintReg->DacRegs[PM2VDACRDDClk0FeedbackScale] = Permedia2vInIndReg(pScrn, PM2VDACRDDClk0FeedbackScale);
+ glintReg->DacRegs[PM2VDACRDDClk0PostScale] = Permedia2vInIndReg(pScrn, PM2VDACRDDClk0PostScale);
+}
+
+void
+Permedia2VRestore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ CARD32 temp;
+ int i;
+
+#if 0
+ GLINT_SLOW_WRITE_REG(0, ResetStatus);
+ while(GLINT_READ_REG(ResetStatus) != 0) {
+ xf86MsgVerb(X_INFO, 2, "Resetting Engine - Please Wait.\n");
+ };
+#endif
+
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[ChipConfig >> 3], ChipConfig);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture0 >> 3], Aperture0);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture1 >> 3], Aperture1);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMFramebufferWriteMask >> 3],
+ PMFramebufferWriteMask);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMBypassWriteMask >> 3],
+ PMBypassWriteMask);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[DFIFODis >> 3], DFIFODis);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[FIFODis >> 3], FIFODis);
+ /* We only muck about with PMMemConfig, if user wants to */
+ if (pGlint->UseBlockWrite)
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMMemConfig >> 3],PMMemConfig);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVideoControl >> 3],
+ PMVideoControl);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHbEnd >> 3], PMHgEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenBase >> 3], PMScreenBase);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VClkCtl >> 3], VClkCtl);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenStride >> 3],
+ PMScreenStride);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHTotal >> 3], PMHTotal);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHbEnd >> 3], PMHbEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsStart >> 3], PMHsStart);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsEnd >> 3], PMHsEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVTotal >> 3], PMVTotal);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVbEnd >> 3], PMVbEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsStart >> 3], PMVsStart);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsEnd >> 3], PMVsEnd);
+
+ Permedia2vOutIndReg(pScrn, PM2VDACRDIndexControl, 0x00,
+ glintReg->DacRegs[PM2VDACRDIndexControl]);
+ Permedia2vOutIndReg(pScrn, PM2VDACRDOverlayKey, 0x00,
+ glintReg->DacRegs[PM2VDACRDOverlayKey]);
+ Permedia2vOutIndReg(pScrn, PM2VDACRDSyncControl, 0x00,
+ glintReg->DacRegs[PM2VDACRDSyncControl]);
+ Permedia2vOutIndReg(pScrn, PM2VDACRDMiscControl, 0x00,
+ glintReg->DacRegs[PM2VDACRDMiscControl]);
+ Permedia2vOutIndReg(pScrn, PM2VDACRDDACControl, 0x00,
+ glintReg->DacRegs[PM2VDACRDDACControl]);
+ Permedia2vOutIndReg(pScrn, PM2VDACRDPixelSize, 0x00,
+ glintReg->DacRegs[PM2VDACRDPixelSize]);
+ Permedia2vOutIndReg(pScrn, PM2VDACRDColorFormat, 0x00,
+ glintReg->DacRegs[PM2VDACRDColorFormat]);
+
+ for (i=0;i<768;i++) {
+ Permedia2WriteAddress(pScrn, i);
+ Permedia2WriteData(pScrn, glintReg->cmap[i]);
+ }
+
+ temp = Permedia2vInIndReg(pScrn, PM2VDACIndexClockControl) & 0xFC;
+ Permedia2vOutIndReg(pScrn, PM2VDACRDDClk0PreScale, 0x00,
+ glintReg->DacRegs[PM2VDACRDDClk0PreScale]);
+ Permedia2vOutIndReg(pScrn, PM2VDACRDDClk0FeedbackScale, 0x00,
+ glintReg->DacRegs[PM2VDACRDDClk0FeedbackScale]);
+ Permedia2vOutIndReg(pScrn, PM2VDACRDDClk0PostScale, 0x00,
+ glintReg->DacRegs[PM2VDACRDDClk0PostScale]);
+ Permedia2vOutIndReg(pScrn, PM2VDACIndexClockControl, 0x00, temp|0x03);
+}
+
+static void
+Permedia2vShowCursor(ScrnInfoPtr pScrn)
+{
+ /* Enable cursor - X11 mode */
+ Permedia2vOutIndReg(pScrn, PM2VDACRDCursorMode, 0x00, 0x11);
+}
+
+static void
+Permedia2vHideCursor(ScrnInfoPtr pScrn)
+{
+ /* Disable cursor - X11 mode */
+ Permedia2vOutIndReg(pScrn, PM2VDACRDCursorMode, 0x00, 0x10);
+}
+
+static void
+Permedia2vLoadCursorImage(
+ ScrnInfoPtr pScrn,
+ unsigned char *src
+)
+{
+ int i;
+
+ for (i=0; i<1024; i++)
+ Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPattern+i, 0x00, *(src++));
+}
+
+static void
+Permedia2vSetCursorPosition(
+ ScrnInfoPtr pScrn,
+ int x, int y
+)
+{
+ x += 64;
+ y += 64;
+ /* Output position - "only" 11 bits of location documented */
+
+ Permedia2vOutIndReg(pScrn, PM2VDACRDCursorHotSpotX, 0x00, 0x3f);
+ Permedia2vOutIndReg(pScrn, PM2VDACRDCursorHotSpotY, 0x00, 0x3f);
+ Permedia2vOutIndReg(pScrn, PM2VDACRDCursorXLow, 0x00, x & 0xFF);
+ Permedia2vOutIndReg(pScrn, PM2VDACRDCursorXHigh, 0x00, (x>>8) & 0x0F);
+ Permedia2vOutIndReg(pScrn, PM2VDACRDCursorYLow, 0x00, y & 0xFF);
+ Permedia2vOutIndReg(pScrn, PM2VDACRDCursorYHigh, 0x00, (y>>8) & 0x0F);
+}
+
+static void
+Permedia2vSetCursorColors(
+ ScrnInfoPtr pScrn,
+ int bg, int fg
+)
+{
+ int i;
+ /* The Permedia2v cursor is always 8 bits so shift 8, not 10 */
+
+ Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+0, 0x00, bg >> 16);
+ Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+1, 0x00, bg >> 8);
+ Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+2, 0x00, bg);
+
+ Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+3, 0x00, fg >> 16);
+ Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+4, 0x00, fg >> 8);
+ Permedia2vOutIndReg(pScrn, PM2VDACRDCursorPalette+5, 0x00, fg);
+}
+
+static Bool
+Permedia2vUseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
+{
+ return TRUE;
+}
+
+Bool
+Permedia2vHWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pGlint->CursorInfoRec = infoPtr;
+
+ infoPtr->MaxWidth = 64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1;
+ infoPtr->SetCursorColors = Permedia2vSetCursorColors;
+ infoPtr->SetCursorPosition = Permedia2vSetCursorPosition;
+ infoPtr->LoadCursorImage = Permedia2vLoadCursorImage;
+ infoPtr->HideCursor = Permedia2vHideCursor;
+ infoPtr->ShowCursor = Permedia2vShowCursor;
+ infoPtr->UseHWCursor = Permedia2vUseHWCursor;
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2vramdac.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2vramdac.c
new file mode 100644
index 000000000..409dd62af
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm2vramdac.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Permedia2vOutIndReg() and Permedia2vInIndReg() are used to access
+ * the indirect Permedia2v RAMDAC registers only.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm2vramdac.c,v 1.4 1999/02/12 22:52:05 hohndel Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "glint_regs.h"
+#include "glint.h"
+
+void
+Permedia2vOutIndReg(ScrnInfoPtr pScrn,
+ CARD32 reg, unsigned char mask, unsigned char data)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ unsigned char tmp = 0x00;
+
+ GLINT_SLOW_WRITE_REG((reg>>8) & 0xff, PM2VDACIndexRegHigh);
+ GLINT_SLOW_WRITE_REG(reg&0xff, PM2VDACIndexRegLow);
+
+ if (mask != 0x00)
+ tmp = GLINT_READ_REG (PM2VDACIndexData) & mask;
+
+ GLINT_SLOW_WRITE_REG (tmp | data, PM2VDACIndexData);
+}
+
+unsigned char
+Permedia2vInIndReg (ScrnInfoPtr pScrn, CARD32 reg)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ unsigned char ret;
+
+ GLINT_SLOW_WRITE_REG (reg&0xff, PM2VDACIndexRegLow);
+ GLINT_SLOW_WRITE_REG((reg>>8) & 0xff, PM2VDACIndexRegHigh);
+ ret = GLINT_READ_REG (PM2VDACIndexData);
+
+ return (ret);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm_accel.c
new file mode 100644
index 000000000..e3f2bf222
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm_accel.c
@@ -0,0 +1,1407 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ * Dirk Hohndel, <hohndel@suse.de>
+ * Stefan Dirsch, <sndirsch@suse.de>
+ *
+ * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and
+ * Siemens Nixdorf Informationssysteme
+ *
+ * Permedia accelerated options.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm_accel.c,v 1.13 1999/03/21 07:35:10 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb32.h"
+
+#include "glint_regs.h"
+#include "glint.h"
+
+#include "miline.h" /* for octants */
+#include "xaalocal.h" /* For replacements */
+
+static void PermediaSync(ScrnInfoPtr pScrn);
+static void PermediaSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+static void PermediaSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h);
+static void PermediaSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void PermediaSubsequentHorVertLine(ScrnInfoPtr pScrn, int x, int y,
+ int len, int dir);
+static void PermediaSubsequentSolidBresenhamLine8bpp(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+static void PermediaSubsequentSolidBresenhamLine16bpp(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+static void PermediaSubsequentSolidBresenhamLine32bpp(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+static void PermediaSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1,
+ int y1, int x2, int y2, int w, int h);
+static void PermediaSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
+ int ydir, int rop, unsigned int planemask,
+ int transparency_color);
+static void PermediaSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2);
+static void PermediaDisableClipping(ScrnInfoPtr pScrn);
+static void PermediaSetupForScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void PermediaSubsequentScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn, int x,
+ int y, int w, int h, int skipleft);
+static void PermediaSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
+static void PermediaSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,unsigned int planemask);
+static void PermediaSubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft);
+static void PermediaWriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int skipleft,
+ int fg, int bg, int rop,unsigned int planemask);
+static void PermediaWritePixmap8bpp(ScrnInfoPtr pScrn, int x, int y, int w,
+ int h, unsigned char *src, int srcwidth,
+ int rop, unsigned int planemask,
+ int transparency_color, int bpp, int depth);
+static void PermediaWritePixmap16bpp(ScrnInfoPtr pScrn, int x, int y, int w,
+ int h, unsigned char *src, int srcwidth,
+ int rop, unsigned int planemask,
+ int transparency_color, int bpp, int depth);
+static void PermediaWritePixmap32bpp(ScrnInfoPtr pScrn, int x, int y, int w,
+ int h, unsigned char *src, int srcwidth,
+ int rop, unsigned int planemask,
+ int transparency_color, int bpp, int depth);
+static void PermediaSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int fg, int bg, int rop,
+ unsigned planemask);
+static void PermediaSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+static void PermediaLoadCoord(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ int a, int d);
+static void PermediaPolylinesThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC,
+ int mode, int npt, DDXPointPtr pPts);
+static void PermediaPolySegmentThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC,
+ int nseg, xSegment *pSeg);
+
+#define MAX_FIFO_ENTRIES 15
+
+static void
+PermediaInitializeEngine(ScrnInfoPtr pScrn)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ /* Initialize the Accelerator Engine to defaults */
+
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode);
+ GLINT_SLOW_WRITE_REG(UNIT_ENABLE, FBWriteMode);
+ GLINT_SLOW_WRITE_REG(0, dXSub);
+ GLINT_SLOW_WRITE_REG(GWIN_DisableLBUpdate, GLINTWindow);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DitherMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureColorMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureAddressMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PMTextureReadMode);
+ GLINT_SLOW_WRITE_REG(pGlint->pprod, LBReadMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TexelLUTMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, YUVMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RouterMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FogMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AntialiasMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaTestMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StencilMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AreaStippleMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LogicalOpMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StatisticMode);
+ GLINT_SLOW_WRITE_REG(0xc00, FilterMode);
+ GLINT_SLOW_WRITE_REG(0xffffffff, FBHardwareWriteMask);
+ GLINT_SLOW_WRITE_REG(0xffffffff, FBSoftwareWriteMask);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RasterizerMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, GLINTDepth);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBSourceOffset);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBPixelOffset);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBSourceOffset);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, WindowOrigin);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBWindowBase);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBWindowBase);
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ GLINT_SLOW_WRITE_REG(0x0, FBReadPixel); /* 8 Bits */
+ GLINT_SLOW_WRITE_REG(pGlint->pprod, PMTextureMapFormat);
+ break;
+ case 16:
+ GLINT_SLOW_WRITE_REG(0x1, FBReadPixel); /* 16 Bits */
+ GLINT_SLOW_WRITE_REG(pGlint->pprod | 1<<19, PMTextureMapFormat);
+ break;
+ case 32:
+ GLINT_SLOW_WRITE_REG(0x2, FBReadPixel); /* 32 Bits */
+ GLINT_SLOW_WRITE_REG(pGlint->pprod | 2<<19, PMTextureMapFormat);
+ break;
+ }
+ pGlint->ROP = 0xFF;
+ pGlint->ClippingOn = FALSE;
+ pGlint->startxsub = 0;
+ pGlint->startxdom = 0;
+ pGlint->starty = 0;
+ pGlint->count = 0;
+ pGlint->dxdom = 0;
+ pGlint->dy = 1<<16;
+ GLINT_WAIT(6);
+ GLINT_WRITE_REG(0, StartXSub);
+ GLINT_WRITE_REG(0,StartXDom);
+ GLINT_WRITE_REG(0,StartY);
+ GLINT_WRITE_REG(0,GLINTCount);
+ GLINT_WRITE_REG(0,dXDom);
+ GLINT_WRITE_REG(1<<16,dY);
+}
+
+Bool
+PermediaAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ BoxRec AvailFBArea;
+
+ pGlint->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ PermediaInitializeEngine(pScrn);
+
+ infoPtr->Flags = PIXMAP_CACHE |
+ LINEAR_FRAMEBUFFER |
+ OFFSCREEN_PIXMAPS;
+
+ infoPtr->Sync = PermediaSync;
+
+ infoPtr->SetClippingRectangle = PermediaSetClippingRectangle;
+ infoPtr->DisableClipping = PermediaDisableClipping;
+ infoPtr->ClippingFlags = HARDWARE_CLIP_MONO_8x8_FILL;
+
+ infoPtr->SolidFillFlags = 0;
+ infoPtr->SetupForSolidFill = PermediaSetupForFillRectSolid;
+ infoPtr->SubsequentSolidFillRect = PermediaSubsequentFillRectSolid;
+ infoPtr->SolidLineFlags = 0;
+ infoPtr->PolySegmentThinSolidFlags = 0;
+ infoPtr->PolylinesThinSolidFlags = 0;
+ infoPtr->SetupForSolidLine = PermediaSetupForSolidLine;
+ infoPtr->SubsequentSolidHorVertLine = PermediaSubsequentHorVertLine;
+ switch(pScrn->bitsPerPixel) {
+ case 8: infoPtr->SubsequentSolidBresenhamLine =
+ PermediaSubsequentSolidBresenhamLine8bpp;
+ break;
+ case 16: infoPtr->SubsequentSolidBresenhamLine =
+ PermediaSubsequentSolidBresenhamLine16bpp;
+ break;
+ case 32: infoPtr->SubsequentSolidBresenhamLine =
+ PermediaSubsequentSolidBresenhamLine32bpp;
+ break;
+ }
+ infoPtr->PolySegmentThinSolid = PermediaPolySegmentThinSolidWrapper;
+ infoPtr->PolylinesThinSolid = PermediaPolylinesThinSolidWrapper;
+
+ infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY |
+ ONLY_LEFT_TO_RIGHT_BITBLT;
+
+ infoPtr->SetupForScreenToScreenCopy = PermediaSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy = PermediaSubsequentScreenToScreenCopy;
+
+ infoPtr->Mono8x8PatternFillFlags =
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ HARDWARE_PATTERN_SCREEN_ORIGIN;
+
+ infoPtr->SetupForMono8x8PatternFill =
+ PermediaSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ PermediaSubsequentMono8x8PatternFillRect;
+
+ if (!pGlint->UsePCIRetry) {
+ infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
+#if 0
+ LEFT_EDGE_CLIPPING |
+ LEFT_EDGE_CLIPPING_NEGATIVE_X |
+#endif
+ BIT_ORDER_IN_BYTE_LSBFIRST;
+
+ pGlint->XAAScanlineColorExpandBuffers[0] =
+ xnfalloc(((pScrn->virtualX + 63)/32) *4* (pScrn->bitsPerPixel / 8));
+ pGlint->XAAScanlineColorExpandBuffers[1] =
+ xnfalloc(((pScrn->virtualX + 63)/32) *4* (pScrn->bitsPerPixel / 8));
+
+ infoPtr->NumScanlineColorExpandBuffers = 2;
+ infoPtr->ScanlineColorExpandBuffers =
+ pGlint->XAAScanlineColorExpandBuffers;
+
+ infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
+ PermediaSetupForScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
+ PermediaSubsequentScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentColorExpandScanline =
+ PermediaSubsequentColorExpandScanline;
+ } else {
+ infoPtr->CPUToScreenColorExpandFillFlags = CPU_TRANSFER_PAD_DWORD |
+#if 0
+ LEFT_EDGE_CLIPPING |
+ LEFT_EDGE_CLIPPING_NEGATIVE_X |
+#endif
+ BIT_ORDER_IN_BYTE_LSBFIRST;
+
+ infoPtr->ColorExpandBase = pGlint->IOBase + OutputFIFO + 4;
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ PermediaSetupForCPUToScreenColorExpandFill;
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ PermediaSubsequentCPUToScreenColorExpandFill;
+ }
+
+ infoPtr->ColorExpandRange = MAX_FIFO_ENTRIES;
+
+ infoPtr->WriteBitmap = PermediaWriteBitmap;
+
+ if (pScrn->bitsPerPixel == 8)
+ infoPtr->WritePixmap = PermediaWritePixmap8bpp;
+ else
+ if (pScrn->bitsPerPixel == 16)
+ infoPtr->WritePixmap = PermediaWritePixmap16bpp;
+ else
+ if (pScrn->bitsPerPixel == 32)
+ infoPtr->WritePixmap = PermediaWritePixmap32bpp;
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = pGlint->FbMapSize / (pScrn->displayWidth *
+ pScrn->bitsPerPixel / 8);
+
+ if (AvailFBArea.y2 > 1023) AvailFBArea.y2 = 1023;
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ return (XAAInit(pScreen, infoPtr));
+}
+
+static void MoveBYTE(
+ register CARD32* dest,
+ register unsigned char* src,
+ register int dwords
+)
+{
+ while(dwords) {
+ *dest = *src;
+ src += 1;
+ dest += 1;
+ dwords -= 1;
+ }
+}
+
+static void MoveWORDS(
+ register CARD32* dest,
+ register unsigned short* src,
+ register int dwords
+)
+{
+ while(dwords & ~0x01) {
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ src += 2;
+ dest += 2;
+ dwords -= 2;
+ }
+ switch(dwords) {
+ case 0: return;
+ case 1: *dest = *src;
+ return;
+ }
+}
+
+static void MoveDWORDS(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ *(dest + 2) = *(src + 2);
+ *(dest + 3) = *(src + 3);
+ src += 4;
+ dest += 4;
+ dwords -= 4;
+ }
+ if (!dwords) return;
+ *dest = *src;
+ if (dwords == 1) return;
+ *(dest + 1) = *(src + 1);
+ if (dwords == 2) return;
+ *(dest + 2) = *(src + 2);
+}
+
+static void PermediaLoadCoord(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h,
+ int a, int d
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ if (w != pGlint->startxsub) {
+ GLINT_WRITE_REG(w, StartXSub);
+ pGlint->startxsub = w;
+ }
+ if (x != pGlint->startxdom) {
+ GLINT_WRITE_REG(x,StartXDom);
+ pGlint->startxdom = x;
+ }
+ if (y != pGlint->starty) {
+ GLINT_WRITE_REG(y,StartY);
+ pGlint->starty = y;
+ }
+ if (h != pGlint->count) {
+ GLINT_WRITE_REG(h,GLINTCount);
+ pGlint->count = h;
+ }
+ if (a != pGlint->dxdom) {
+ GLINT_WRITE_REG(a,dXDom);
+ pGlint->dxdom = a;
+ }
+ if (d != pGlint->dy) {
+ GLINT_WRITE_REG(d,dY);
+ pGlint->dy = d;
+ }
+}
+
+static void
+PermediaSync(ScrnInfoPtr pScrn)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ CHECKCLIPPING;
+
+ while (GLINT_READ_REG(DMACount) != 0);
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(0, GlintSync);
+ do {
+ while(GLINT_READ_REG(OutFIFOWords) == 0);
+#define Sync_tag 0x188
+ } while (GLINT_READ_REG(OutputFIFO) != Sync_tag);
+}
+
+static void
+PermediaSetClippingRectangle(
+ ScrnInfoPtr pScrn,
+ int x1, int y1,
+ int x2, int y2
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ GLINT_WAIT(3);
+ GLINT_WRITE_REG (((y1&0x0FFF) << 16) | (x1&0x0FFF), ScissorMinXY);
+ GLINT_WRITE_REG (((y2&0x0FFF) << 16) | (x2&0x0FFF), ScissorMaxXY);
+ GLINT_WRITE_REG (1, ScissorMode);
+ pGlint->ClippingOn = TRUE;
+}
+
+static void
+PermediaDisableClipping(
+ ScrnInfoPtr pScrn
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ CHECKCLIPPING;
+}
+
+static void
+PermediaSetupForScreenToScreenCopy(
+ ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int transparency_color
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ pGlint->BltScanDirection = 0;
+ if (ydir == 1) pGlint->BltScanDirection |= YPositive;
+
+ GLINT_WAIT(4);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(0, RasterizerMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+
+ if ((rop == GXset) || (rop == GXclear)) {
+ pGlint->FrameBufferReadMode = pGlint->pprod;
+ } else
+ if ((rop == GXcopy) || (rop == GXcopyInverted)) {
+ pGlint->FrameBufferReadMode = pGlint->pprod | FBRM_SrcEnable;
+ } else {
+ pGlint->FrameBufferReadMode = pGlint->pprod | FBRM_SrcEnable |
+ FBRM_DstEnable;
+ }
+ LOADROP(rop);
+}
+
+static void
+PermediaSubsequentScreenToScreenCopy(
+ ScrnInfoPtr pScrn,
+ int x1, int y1,
+ int x2, int y2,
+ int w, int h)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int srcaddr;
+ int dstaddr;
+ char align;
+ int direction;
+
+ if (!(pGlint->BltScanDirection & YPositive)) {
+ y1 = y1 + h - 1;
+ y2 = y2 + h - 1;
+ direction = -1<<16;
+ } else {
+ direction = 1<<16;
+ }
+
+ /* We can only use GXcopy for Packed modes, and less than 32 width
+ * gives us speed for small blits. */
+ if ((w < 32) || (pGlint->ROP != GXcopy)) {
+ GLINT_WAIT(9);
+ PermediaLoadCoord(pScrn, x2<<16, y2<<16, (x2+w)<<16, h, 0, direction);
+ srcaddr = x1;
+ dstaddr = x2;
+ GLINT_WRITE_REG(pGlint->FrameBufferReadMode, FBReadMode);
+ } else {
+ GLINT_WAIT(10);
+ PermediaLoadCoord(pScrn, (x2>>pGlint->BppShift)<<16, y2<<16,
+ ((x2+w+7)>>pGlint->BppShift)<<16, h, 0,
+ direction);
+ srcaddr = (x1 & ~pGlint->bppalign);
+ dstaddr = (x2 & ~pGlint->bppalign);
+ align = (x2 & pGlint->bppalign) - (x1 & pGlint->bppalign);
+ GLINT_WRITE_REG(pGlint->FrameBufferReadMode | FBRM_Packed |
+ (align&7)<<20, FBReadMode);
+ GLINT_WRITE_REG(x2<<16|(x2+w), PackedDataLimits);
+ }
+ srcaddr += y1 * pScrn->displayWidth;
+ dstaddr += y2 * pScrn->displayWidth;
+ GLINT_WRITE_REG(srcaddr - dstaddr, FBSourceOffset);
+ GLINT_WRITE_REG(PrimitiveTrapezoid, Render);
+}
+
+static void
+PermediaSetupForFillRectSolid(
+ ScrnInfoPtr pScrn,
+ int color, int rop,
+ unsigned int planemask
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ REPLICATE(color);
+
+ GLINT_WAIT(6);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(0, RasterizerMode);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ GLINT_WRITE_REG(color, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
+ GLINT_WRITE_REG(color, ConstantColor);
+ }
+ LOADROP(rop);
+}
+
+static void
+PermediaSubsequentFillRectSolid(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int speed = 0;
+ if (pGlint->ROP == GXcopy) {
+ GLINT_WAIT(7);
+ PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16);
+ speed = FastFillEnable;
+ } else {
+ GLINT_WAIT(9);
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_Packed | FBRM_DstEnable, FBReadMode);
+ PermediaLoadCoord(pScrn, (x>>pGlint->BppShift)<<16, y<<16,
+ ((x+w+7)>>pGlint->BppShift)<<16, h, 0, 1<<16);
+ GLINT_WRITE_REG(x<<16|(x+w), PackedDataLimits);
+ }
+ GLINT_WRITE_REG(PrimitiveTrapezoid | speed, Render);
+}
+
+static void
+PermediaSetupForMono8x8PatternFill(
+ ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ if (bg == -1) pGlint->FrameBufferReadMode = -1;
+ else pGlint->FrameBufferReadMode = 0;
+ pGlint->ForeGroundColor = fg;
+ pGlint->BackGroundColor = bg;
+ REPLICATE(pGlint->ForeGroundColor);
+ REPLICATE(pGlint->BackGroundColor);
+
+ GLINT_WAIT(8);
+ GLINT_WRITE_REG ((patternx & 0x000000ff), AreaStipplePattern0);
+ GLINT_WRITE_REG ((patternx & 0x0000ff00) >> 8, AreaStipplePattern1);
+ GLINT_WRITE_REG ((patternx & 0x00ff0000) >> 16, AreaStipplePattern2);
+ GLINT_WRITE_REG ((patternx & 0xff000000) >> 24, AreaStipplePattern3);
+ GLINT_WRITE_REG ((patterny & 0x000000ff), AreaStipplePattern4);
+ GLINT_WRITE_REG ((patterny & 0x0000ff00) >> 8, AreaStipplePattern5);
+ GLINT_WRITE_REG ((patterny & 0x00ff0000) >> 16, AreaStipplePattern6);
+ GLINT_WRITE_REG ((patterny & 0xff000000) >> 24, AreaStipplePattern7);
+
+ GLINT_WAIT(7);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(0, RasterizerMode);
+
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
+ GLINT_WRITE_REG(pGlint->ForeGroundColor, ConstantColor);
+ GLINT_WRITE_REG(pGlint->BackGroundColor, Texel0);
+ LOADROP(rop);
+}
+
+static void
+PermediaSubsequentMono8x8PatternFillRect(
+ ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ GLINT_WAIT(8);
+ PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16);
+ if (pGlint->FrameBufferReadMode != -1) {
+ GLINT_WRITE_REG(1<<20|patternx<<7|patterny<<12|UNIT_ENABLE,
+ AreaStippleMode);
+ GLINT_WRITE_REG(AreaStippleEnable | TextureEnable | PrimitiveTrapezoid,
+ Render);
+ } else {
+ GLINT_WRITE_REG(patternx<<7|patterny<<12|UNIT_ENABLE, AreaStippleMode);
+ GLINT_WRITE_REG(AreaStippleEnable | PrimitiveTrapezoid, Render);
+ }
+}
+
+static void
+PermediaWriteBitmap(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ unsigned char *srcpntr;
+ int dwords, height;
+ register int count;
+ register CARD32* pattern;
+ int dobackground = 0;
+
+ skipleft = 0;
+
+ w += skipleft;
+ x -= skipleft;
+ dwords = (w + 31) >> 5;
+
+#if 0
+ PermediaSetClippingRectangle(pScrn, x+skipleft, y, x+w, y+h);
+#endif
+
+ GLINT_WAIT(14);
+ DO_PLANEMASK(planemask);
+ LOADROP(rop);
+ if (bg != -1) dobackground = ForceBackgroundColor;
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ pGlint->BackGroundColor = bg;
+ pGlint->ForeGroundColor = fg;
+ REPLICATE(fg);
+ REPLICATE(bg);
+ if ((rop == GXcopy) && (pGlint->BackGroundColor == -1)) {
+ pGlint->FrameBufferReadMode = FastFillEnable;
+ GLINT_WRITE_REG(0, RasterizerMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(BitMaskPackingEachScanline|dobackground,RasterizerMode);
+ GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
+ GLINT_WRITE_REG(fg, ConstantColor);
+ if (dobackground) {
+ GLINT_WRITE_REG(bg, Texel0);
+ pGlint->FrameBufferReadMode = TextureEnable;
+ } else {
+ pGlint->FrameBufferReadMode = 0;
+ }
+ }
+ PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16);
+
+ GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode | SyncOnBitMask, Render);
+
+ height = h;
+ srcpntr = src;
+ while(height--) {
+ count = dwords >> 3;
+ pattern = (CARD32*)srcpntr;
+ while(count--) {
+ GLINT_WAIT(8);
+ GLINT_WRITE_REG(*(pattern), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+1), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+2), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+3), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+4), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+5), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+6), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+7), BitMaskPattern);
+ pattern+=8;
+ }
+ count = dwords & 0x07;
+ GLINT_WAIT(count);
+ while (count--)
+ GLINT_WRITE_REG(*(pattern++), BitMaskPattern);
+ srcpntr += srcwidth;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+static void
+PermediaSetupForScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int dobackground = 0;
+
+ if (bg != -1) dobackground |= ForceBackgroundColor;
+ pGlint->BackGroundColor = bg;
+ pGlint->ForeGroundColor = fg;
+ REPLICATE(fg);
+ REPLICATE(bg);
+ GLINT_WAIT(7);
+ DO_PLANEMASK(planemask);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod|FBRM_DstEnable, FBReadMode);
+ }
+ if ((rop == GXcopy) && (pGlint->BackGroundColor == -1)) {
+ pGlint->FrameBufferReadMode = FastFillEnable;
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ GLINT_WRITE_REG(0,RasterizerMode);
+ } else {
+ GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
+ GLINT_WRITE_REG(fg, ConstantColor);
+ GLINT_WRITE_REG(BitMaskPackingEachScanline|dobackground,RasterizerMode);
+ if (dobackground) {
+ GLINT_WRITE_REG(bg, Texel0);
+ pGlint->FrameBufferReadMode = TextureEnable;
+ } else {
+ pGlint->FrameBufferReadMode = 0;
+ }
+ }
+ LOADROP(rop);
+}
+
+static void
+PermediaSubsequentScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ pGlint->dwords = ((w + 31) >> 5); /* dwords per scanline */
+
+#if 0
+ PermediaSetClippingRectangle(pScrn, x+skipleft, y, x+w, y+h);
+#endif
+
+ pGlint->cpucount = y;
+ pGlint->cpuheight = h;
+
+ GLINT_WAIT(6);
+ PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, 1, 0, 1<<16);
+}
+
+static void
+PermediaSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ CARD32 *src;
+ int dwords = pGlint->dwords;
+
+ GLINT_WAIT(7);
+ PermediaLoadCoord(pScrn, pGlint->startxdom, pGlint->cpucount<<16, pGlint->startxsub, 1, 0, 1<<16);
+
+ GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode | SyncOnBitMask,
+ Render);
+ dwords = pGlint->dwords;
+
+ src = (CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno];
+ while (dwords >= infoRec->ColorExpandRange) {
+ GLINT_WAIT(infoRec->ColorExpandRange);
+ GLINT_WRITE_REG((infoRec->ColorExpandRange - 2)<<16 | 0x0D, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), src,
+ infoRec->ColorExpandRange - 1);
+ dwords -= (infoRec->ColorExpandRange - 1);
+ src += (infoRec->ColorExpandRange - 1);
+ }
+ if (dwords) {
+ GLINT_WAIT(dwords);
+ GLINT_WRITE_REG((dwords - 1)<<16 | 0x0D, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), src,dwords);
+ }
+ pGlint->cpucount += 1;
+#if 0
+ if (pGlint->cpucount == (pGlint->cpuheight + 1))
+ CHECKCLIPPING;
+#endif
+}
+
+static void
+PermediaSetupForCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int dobackground = 0;
+
+ if (bg != -1) dobackground |= ForceBackgroundColor;
+
+ DO_PLANEMASK(planemask);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+
+ pGlint->ForeGroundColor = fg;
+ pGlint->BackGroundColor = bg;
+ REPLICATE(fg);
+ REPLICATE(bg);
+
+ if ((rop == GXcopy) && (pGlint->BackGroundColor == -1)) {
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ GLINT_WRITE_REG(0, RasterizerMode);
+ pGlint->FrameBufferReadMode = FastFillEnable;
+ } else {
+ GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode);
+ GLINT_WRITE_REG(BitMaskPackingEachScanline|dobackground,RasterizerMode);
+ GLINT_WRITE_REG(fg, ConstantColor);
+ if (dobackground) {
+ GLINT_WRITE_REG(bg, Texel0);
+ pGlint->FrameBufferReadMode = TextureEnable;
+ } else
+ pGlint->FrameBufferReadMode = 0;
+ }
+ LOADROP(rop);
+}
+
+static void
+PermediaSubsequentCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int dwords = ((w + 31) >> 5) * h;
+
+ PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16);
+
+ GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode |
+ SyncOnBitMask, Render);
+ GLINT_WRITE_REG((dwords - 1)<<16 | 0x0D, OutputFIFO);
+}
+
+static void
+PermediaWritePixmap8bpp(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int skipleft, dwords, count;
+ CARD32* srcp;
+ unsigned char *srcpbyte;
+ Bool FastTexLoad = FALSE;
+
+ GLINT_WAIT(2);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(0, RasterizerMode);
+
+ dwords = (w + 3) >> 2;
+ if((!(x&3)) && (!(w&3))) FastTexLoad = TRUE;
+ if((rop != GXcopy) || (planemask != ~0))
+ FastTexLoad = FALSE;
+
+#if 0
+ if (rop == GXcopy) {
+ skipleft = 0;
+ } else {
+ if((skipleft = (long)src & 0x03)) {
+ skipleft /= (bpp>>3);
+
+ x -= skipleft;
+ w += skipleft;
+
+ src = (unsigned char*)((long)src & ~0x03);
+ }
+ }
+#endif
+ skipleft = 0;
+
+ if(FastTexLoad) {
+ int address;
+
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode);
+ PermediaSync(pScrn); /* we are not using the rasterizer */
+ while(h--) {
+ count = dwords;
+ address = ((y * pScrn->displayWidth) + x) >> 2;
+ srcp = (CARD32*)src;
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(address, TextureDownloadOffset);
+ while(count >= infoRec->ColorExpandRange) {
+ GLINT_WAIT(infoRec->ColorExpandRange);
+ /* (0x11 << 4) | 0x0D is the TAG for TextureData */
+ GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16)
+ | (0x11 << 4) | 0x0D, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, infoRec->ColorExpandRange - 1);
+ count -= infoRec->ColorExpandRange - 1;
+ address += infoRec->ColorExpandRange - 1;
+ srcp += infoRec->ColorExpandRange - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count + 1);
+ /* (0x11 << 4) | 0x0D is the TAG for TextureData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D,
+ OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, count);
+ }
+ src += srcwidth;
+ y++;
+ }
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode);
+ } else {
+ GLINT_WAIT(10);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16);
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ LOADROP(rop);
+ GLINT_WRITE_REG(PrimitiveTrapezoid | SyncOnHostData, Render);
+
+ {
+ while(h--) {
+ count = w;
+ srcpbyte = (unsigned char *)src;
+ while(count >= infoRec->ColorExpandRange) {
+ GLINT_WAIT(infoRec->ColorExpandRange);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) |
+ (0x15 << 4) | 0x05, OutputFIFO);
+ MoveBYTE((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (unsigned char *)srcpbyte, infoRec->ColorExpandRange-1);
+ count -= infoRec->ColorExpandRange - 1;
+ srcpbyte += infoRec->ColorExpandRange - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count + 1);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveBYTE((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (unsigned char *)srcpbyte, count);
+ }
+ src += srcwidth;
+ }
+ }
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+static void
+PermediaWritePixmap16bpp(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int skipleft, dwords, count;
+ CARD32* srcp;
+ unsigned short* srcpword;
+ Bool FastTexLoad;
+
+ GLINT_WAIT(2);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(0, RasterizerMode);
+
+ FastTexLoad = FALSE;
+ dwords = (w + 1) >> 1;
+ if((!(x&1)) && (!(w&1))) FastTexLoad = TRUE;
+ if((rop != GXcopy) || (planemask != ~0))
+ FastTexLoad = FALSE;
+
+#if 0
+ if (rop == GXcopy) {
+ skipleft = 0;
+ } else {
+ if((skipleft = (long)src & 0x03L)) {
+ skipleft /= (bpp>>3);
+
+ x -= skipleft;
+ w += skipleft;
+
+ src = (unsigned char*)((long)src & ~0x03L);
+ }
+ }
+#endif
+ skipleft = 0;
+
+ if(FastTexLoad) {
+ int address;
+
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode);
+ PermediaSync(pScrn); /* we are not using the rasterizer */
+ while(h--) {
+ count = dwords;
+ address = ((y * pScrn->displayWidth) + x) >> 1;
+ srcp = (CARD32*)src;
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(address, TextureDownloadOffset);
+ while(count >= infoRec->ColorExpandRange) {
+ GLINT_WAIT(infoRec->ColorExpandRange);
+ /* (0x11 << 4) | 0x0D is the TAG for TextureData */
+ GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) |
+ (0x11 << 4) | 0x0D, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, infoRec->ColorExpandRange - 1);
+ count -= infoRec->ColorExpandRange - 1;
+ address += infoRec->ColorExpandRange - 1;
+ srcp += infoRec->ColorExpandRange - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count + 1);
+ /* (0x11 << 4) | 0x0D is the TAG for TextureData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D,
+ OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, count);
+ }
+ src += srcwidth;
+ y++;
+ }
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode);
+ } else {
+ GLINT_WAIT(10);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16);
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ LOADROP(rop);
+ GLINT_WRITE_REG(PrimitiveTrapezoid | SyncOnHostData, Render);
+
+ {
+ while(h--) {
+ count = w;
+ srcpword = (unsigned short *)src;
+ while(count >= infoRec->ColorExpandRange) {
+ GLINT_WAIT(infoRec->ColorExpandRange);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) |
+ (0x15 << 4) | 0x05, OutputFIFO);
+ MoveWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (unsigned short *)srcpword,infoRec->ColorExpandRange-1);
+ count -= infoRec->ColorExpandRange - 1;
+ srcpword += infoRec->ColorExpandRange - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count + 1);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (unsigned short *)srcpword, count);
+ }
+ src += srcwidth;
+ }
+ }
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+static void
+PermediaWritePixmap32bpp(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int skipleft, dwords, count;
+ CARD32* srcp;
+ Bool FastTexLoad;
+
+ GLINT_WAIT(3);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(0, RasterizerMode);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+
+ FastTexLoad = TRUE;
+ dwords = w;
+ if((rop != GXcopy) || (planemask != ~0))
+ FastTexLoad = FALSE;
+
+#if 0
+ if (!FastTexLoad) {
+ if((skipleft = (long)src & 0x03L)) {
+ skipleft /= (bpp>>3);
+
+ x -= skipleft;
+ w += skipleft;
+
+ src = (unsigned char*)((long)src & ~0x03L);
+ }
+ }
+#endif
+ skipleft = 0;
+
+ if(FastTexLoad) {
+ int address;
+
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode);
+ PermediaSync(pScrn); /* we are not using the rasterizer */
+ while(h--) {
+ count = dwords;
+ address = (y * pScrn->displayWidth) + x;
+ srcp = (CARD32*)src;
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(address, TextureDownloadOffset);
+ while(count >= infoRec->ColorExpandRange) {
+ GLINT_WAIT(infoRec->ColorExpandRange);
+ /* (0x11 << 4) | 0x0D is the TAG for TextureData */
+ GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) |
+ (0x11 << 4) | 0x0D, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, infoRec->ColorExpandRange - 1);
+ count -= infoRec->ColorExpandRange - 1;
+ address += infoRec->ColorExpandRange - 1;
+ srcp += infoRec->ColorExpandRange - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count + 1);
+ /* (0x11 << 4) | 0x0D is the TAG for TextureData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D,
+ OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, count);
+ }
+ src += srcwidth;
+ y++;
+ }
+ GLINT_WAIT(1);
+ GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode);
+ } else {
+ GLINT_WAIT(9);
+ PermediaLoadCoord(pScrn, (x&0xFFFF)<<16, y<<16, ((x&0xFFFF)+w)<<16, h, 0, 1<<16);
+ LOADROP(rop);
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ GLINT_WRITE_REG(PrimitiveTrapezoid | SyncOnHostData, Render);
+
+ while(h--) {
+ count = dwords;
+ srcp = (CARD32*)src;
+ while(count >= infoRec->ColorExpandRange) {
+ GLINT_WAIT(infoRec->ColorExpandRange);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) |
+ (0x15 << 4) | 0x05, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, infoRec->ColorExpandRange - 1);
+ count -= infoRec->ColorExpandRange - 1;
+ srcp += infoRec->ColorExpandRange - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count + 1);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, count);
+ }
+ src += srcwidth;
+ }
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+static void
+PermediaPolylinesThinSolidWrapper(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ GLINTPtr pGlint = GLINTPTR(infoRec->pScrn);
+ pGlint->CurrentGC = pGC;
+ if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn);
+ XAAPolyLines(pDraw, pGC, mode, npt, pPts);
+}
+
+static void
+PermediaPolySegmentThinSolidWrapper(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ GLINTPtr pGlint = GLINTPTR(infoRec->pScrn);
+ pGlint->CurrentGC = pGC;
+ if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn);
+ XAAPolySegment(pDraw, pGC, nseg, pSeg);
+}
+
+static void
+PermediaSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_WAIT(6);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ GLINT_WRITE_REG(color, GLINTColor);
+ GLINT_WRITE_REG(0, RasterizerMode);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ LOADROP(rop);
+}
+
+static void
+PermediaSubsequentHorVertLine(ScrnInfoPtr pScrn,int x,int y,int len,int dir)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_WAIT(7);
+ if (dir == DEGREES_0) {
+ PermediaLoadCoord(pScrn, x<<16, y<<16, 0, len, 1<<16, 0);
+ } else {
+ PermediaLoadCoord(pScrn, x<<16, y<<16, 0, len, 0, 1<<16);
+ }
+
+ GLINT_WRITE_REG(PrimitiveLine, Render);
+}
+
+static void
+PermediaSubsequentSolidBresenhamLine8bpp( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ cfbPrivGCPtr devPriv;
+ int dxdom, dy;
+
+ if(dmaj == dmin) {
+ GLINT_WAIT(7);
+ if(octant & YDECREASING) {
+ dy = -1<<16;
+ } else {
+ dy = 1<<16;
+ }
+
+ if(octant & XDECREASING) {
+ dxdom = -1<<16;
+ } else {
+ dxdom = 1<<16;
+ }
+
+ PermediaLoadCoord(pScrn, x<<16, y<<16, 0, len, dxdom, dy);
+ GLINT_WRITE_REG(PrimitiveLine, Render);
+ return;
+ }
+
+ devPriv = cfbGetGCPrivate(pGlint->CurrentGC);
+
+ cfbBresS(devPriv->rop, devPriv->and, devPriv->xor,
+ (unsigned long*)pGlint->FbBase, pScrn->displayWidth >> 2,
+ (octant & XDECREASING) ? -1 : 1,
+ (octant & YDECREASING) ? -1 : 1,
+ (octant & YMAJOR) ? Y_AXIS : X_AXIS,
+ x, y, dmin + e, dmin, dmin - dmaj, len);
+}
+
+static void
+PermediaSubsequentSolidBresenhamLine16bpp( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ cfbPrivGCPtr devPriv;
+ int dxdom, dy;
+
+ if(dmaj == dmin) {
+ GLINT_WAIT(7);
+ if(octant & YDECREASING) {
+ dy = -1<<16;
+ } else {
+ dy = 1<<16;
+ }
+
+ if(octant & XDECREASING) {
+ dxdom = -1<<16;
+ } else {
+ dxdom = 1<<16;
+ }
+
+ PermediaLoadCoord(pScrn, x<<16, y<<16, 0, len, dxdom, dy);
+ GLINT_WRITE_REG(PrimitiveLine, Render);
+ return;
+ }
+
+ devPriv = cfbGetGCPrivate(pGlint->CurrentGC);
+
+ cfb16BresS(devPriv->rop, devPriv->and, devPriv->xor,
+ (unsigned long*)pGlint->FbBase, pScrn->displayWidth >> 1,
+ (octant & XDECREASING) ? -1 : 1,
+ (octant & YDECREASING) ? -1 : 1,
+ (octant & YMAJOR) ? Y_AXIS : X_AXIS,
+ x, y, dmin + e, dmin, dmin - dmaj, len);
+}
+
+static void
+PermediaSubsequentSolidBresenhamLine32bpp( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ cfbPrivGCPtr devPriv;
+ int dxdom, dy;
+
+ if(dmaj == dmin) {
+ GLINT_WAIT(7);
+ if(octant & YDECREASING) {
+ dy = -1<<16;
+ } else {
+ dy = 1<<16;
+ }
+
+ if(octant & XDECREASING) {
+ dxdom = -1<<16;
+ } else {
+ dxdom = 1<<16;
+ }
+
+ PermediaLoadCoord(pScrn, x<<16, y<<16, 0, len, dxdom, dy);
+ GLINT_WRITE_REG(PrimitiveLine, Render);
+ return;
+ }
+
+ devPriv = cfbGetGCPrivate(pGlint->CurrentGC);
+
+ cfb32BresS(devPriv->rop, devPriv->and, devPriv->xor,
+ (unsigned long*)pGlint->FbBase, pScrn->displayWidth,
+ (octant & XDECREASING) ? -1 : 1,
+ (octant & YDECREASING) ? -1 : 1,
+ (octant & YMAJOR) ? Y_AXIS : X_AXIS,
+ x, y, dmin + e, dmin, dmin - dmaj, len);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/pm_dac.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm_dac.c
new file mode 100644
index 000000000..59a41eac1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/pm_dac.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane <alanh@fairlite.demon.co.uk>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ * Dirk Hohndel, <hohndel@suse.de>
+ * Stefan Dirsch, <sndirsch@suse.de>
+ * Helmut Fahrion, <hf@suse.de>
+ *
+ * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and
+ * Siemens Nixdorf Informationssysteme
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm_dac.c,v 1.7 1999/03/28 15:32:39 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "IBM.h"
+#include "glint_regs.h"
+#include "glint.h"
+
+static int
+Shiftbpp(ScrnInfoPtr pScrn, int value)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ /* shift horizontal timings for 64bit VRAM's or 32bit SGRAMs */
+ int logbytesperaccess = 2;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ value >>= logbytesperaccess;
+ pGlint->BppShift = logbytesperaccess;
+ break;
+ case 16:
+ if (pGlint->DoubleBuffer) {
+ value >>= (logbytesperaccess-2);
+ pGlint->BppShift = logbytesperaccess-2;
+ } else {
+ value >>= (logbytesperaccess-1);
+ pGlint->BppShift = logbytesperaccess-1;
+ }
+ break;
+ case 24:
+ value *= 3;
+ value >>= logbytesperaccess;
+ pGlint->BppShift = logbytesperaccess;
+ break;
+ case 32:
+ value >>= (logbytesperaccess-2);
+ pGlint->BppShift = logbytesperaccess-2;
+ break;
+ }
+ return (value);
+}
+
+Bool
+PermediaInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ GLINTRegPtr pReg = &pGlint->ModeReg;
+ RamDacHWRecPtr pIBM = RAMDACHWPTR(pScrn);
+ RamDacRegRecPtr ramdacReg = &pIBM->ModeReg;
+ CARD32 temp1, temp2, temp3, temp4;
+
+ pReg->glintRegs[Aperture0 >> 3] = 0;
+ pReg->glintRegs[Aperture1 >> 3] = 0;
+ pReg->glintRegs[PMFramebufferWriteMask >> 3] = 0xFFFFFFFF;
+ pReg->glintRegs[PMBypassWriteMask >> 3] = 0xFFFFFFFF;
+
+ if (pGlint->UsePCIRetry) {
+ pReg->glintRegs[DFIFODis >> 3] = 1;
+ pReg->glintRegs[FIFODis >> 3] = 3;
+ } else {
+ pReg->glintRegs[DFIFODis >> 3] = 0;
+ pReg->glintRegs[FIFODis >> 3] = 1;
+ }
+
+ temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay;
+ temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay;
+ temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart;
+ temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+
+ pReg->glintRegs[PMHTotal >> 3] = Shiftbpp(pScrn,mode->CrtcHTotal);
+ pReg->glintRegs[PMHsEnd >> 3] = Shiftbpp(pScrn, temp1 + temp3);
+ pReg->glintRegs[PMHsStart >> 3] = Shiftbpp(pScrn, temp1);
+ pReg->glintRegs[PMHgEnd >> 3] = Shiftbpp(pScrn, mode->CrtcHTotal -
+ mode->CrtcHDisplay);
+ pReg->glintRegs[PMScreenStride >> 3] =
+ Shiftbpp(pScrn,pScrn->displayWidth>>1);
+
+ pReg->glintRegs[PMVTotal >> 3] = mode->CrtcVTotal;
+ pReg->glintRegs[PMVsEnd >> 3] = temp2 + temp4;
+ pReg->glintRegs[PMVsStart >> 3] = temp2;
+ pReg->glintRegs[PMVbEnd >> 3] = mode->CrtcVTotal - mode->CrtcVDisplay;
+
+ pReg->glintRegs[PMVideoControl >> 3] =
+ (((mode->Flags & V_PHSYNC) ? 0x1 : 0x3) << 3) |
+ (((mode->Flags & V_PVSYNC) ? 0x1 : 0x3) << 5) | 1;
+
+ pReg->glintRegs[VClkCtl >> 3] = 3;
+ pReg->glintRegs[PMScreenBase >> 3] = 0;
+ pReg->glintRegs[PMHTotal >> 3] -= 1; /* PMHTotal */
+ pReg->glintRegs[PMHsStart >> 3] -= 1; /* PMHsStart */
+ pReg->glintRegs[PMVTotal >> 3] -= 1; /* PMVTotal */
+ pReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig) & 0xFFFFFFFD;
+
+ {
+ /* Get the programmable clock values */
+ unsigned long m=0,n=0,p=0,c=0;
+ unsigned long clock;
+
+ clock = IBMramdac526CalculateMNPCForClock(pGlint->RefClock, mode->Clock,
+ 1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c);
+
+ ramdacReg->DacRegs[IBMRGB_m0] = m;
+ ramdacReg->DacRegs[IBMRGB_n0] = n;
+ ramdacReg->DacRegs[IBMRGB_p0] = p;
+ ramdacReg->DacRegs[IBMRGB_c0] = c;
+
+ ramdacReg->DacRegs[IBMRGB_pll_ctrl1] = 0x05;
+ ramdacReg->DacRegs[IBMRGB_pll_ctrl2] = 0x00;
+
+ p = 1;
+ clock = IBMramdac526CalculateMNPCForClock(pGlint->RefClock, mode->Clock,
+ 0, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c);
+
+ ramdacReg->DacRegs[IBMRGB_sysclk] = 0x05;
+ ramdacReg->DacRegs[IBMRGB_sysclk_m] = m;
+ ramdacReg->DacRegs[IBMRGB_sysclk_n] = n;
+ ramdacReg->DacRegs[IBMRGB_sysclk_p] = p;
+ ramdacReg->DacRegs[IBMRGB_sysclk_c] = c;
+ }
+
+ ramdacReg->DacRegs[IBMRGB_misc1] = SENS_DSAB_DISABLE | VRAM_SIZE_32;
+ ramdacReg->DacRegs[IBMRGB_misc2] = COL_RES_8BIT | PORT_SEL_VRAM;
+ if (pScrn->depth >= 24)
+ ramdacReg->DacRegs[IBMRGB_misc2] |= PCLK_SEL_LCLK;
+ else
+ ramdacReg->DacRegs[IBMRGB_misc2] |= PCLK_SEL_PLL;
+ ramdacReg->DacRegs[IBMRGB_misc_clock] = 1;
+ ramdacReg->DacRegs[IBMRGB_sync] = 0;
+ ramdacReg->DacRegs[IBMRGB_hsync_pos] = 0;
+ ramdacReg->DacRegs[IBMRGB_pwr_mgmt] = 0;
+ ramdacReg->DacRegs[IBMRGB_dac_op] = 0;
+ ramdacReg->DacRegs[IBMRGB_pal_ctrl] = 0;
+
+ (*pGlint->RamDac->SetBpp)(pScrn, ramdacReg);
+
+ return(TRUE);
+}
+
+void
+PermediaSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ glintReg->glintRegs[Aperture0 >> 3] = GLINT_READ_REG(Aperture0);
+ glintReg->glintRegs[Aperture1 >> 3] = GLINT_READ_REG(Aperture1);
+ glintReg->glintRegs[PMFramebufferWriteMask] =
+ GLINT_READ_REG(PMFramebufferWriteMask);
+ glintReg->glintRegs[PMBypassWriteMask >> 3] =
+ GLINT_READ_REG(PMBypassWriteMask);
+ glintReg->glintRegs[DFIFODis >> 3] = GLINT_READ_REG(DFIFODis);
+ glintReg->glintRegs[FIFODis >> 3] = GLINT_READ_REG(FIFODis);
+
+ glintReg->glintRegs[PMHTotal >> 3] = GLINT_READ_REG(PMHTotal);
+ glintReg->glintRegs[PMHgEnd >> 3] = GLINT_READ_REG(PMHbEnd);
+ glintReg->glintRegs[PMHgEnd >> 3] = GLINT_READ_REG(PMHgEnd);
+ glintReg->glintRegs[PMScreenStride >> 3] = GLINT_READ_REG(PMScreenStride);
+ glintReg->glintRegs[PMHsStart >> 3] = GLINT_READ_REG(PMHsStart);
+ glintReg->glintRegs[PMHsEnd >> 3] = GLINT_READ_REG(PMHsEnd);
+ glintReg->glintRegs[PMVTotal >> 3] = GLINT_READ_REG(PMVTotal);
+ glintReg->glintRegs[PMVbEnd >> 3] = GLINT_READ_REG(PMVbEnd);
+ glintReg->glintRegs[PMVsStart >> 3] = GLINT_READ_REG(PMVsStart);
+ glintReg->glintRegs[PMVsEnd >> 3] = GLINT_READ_REG(PMVsEnd);
+ glintReg->glintRegs[PMScreenBase >> 3] = GLINT_READ_REG(PMScreenBase);
+ glintReg->glintRegs[PMVideoControl >> 3] = GLINT_READ_REG(PMVideoControl);
+ glintReg->glintRegs[VClkCtl >> 3] = GLINT_READ_REG(VClkCtl);
+ glintReg->glintRegs[ChipConfig >> 3] = GLINT_READ_REG(ChipConfig);
+}
+
+void
+PermediaRestore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+#if 0
+ GLINT_SLOW_WRITE_REG(0, ResetStatus);
+ while(GLINT_READ_REG(ResetStatus) != 0) {
+ xf86MsgVerb(X_INFO, 2, "Resetting Engine - Please Wait.\n");
+ };
+#endif
+
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[ChipConfig >> 3], ChipConfig);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[DFIFODis >> 3], DFIFODis);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[FIFODis >> 3], FIFODis);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture0 >> 3], Aperture0);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture1 >> 3], Aperture1);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMFramebufferWriteMask >> 3],
+ PMFramebufferWriteMask);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMBypassWriteMask >> 3],
+ PMBypassWriteMask);
+
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVideoControl >> 3],
+ PMVideoControl);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHgEnd >> 3], PMHgEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VClkCtl >> 3], VClkCtl);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHTotal >> 3], PMHTotal);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHgEnd >> 3], PMHbEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsStart >> 3], PMHsStart);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMHsEnd >> 3], PMHsEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVTotal >> 3], PMVTotal);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVbEnd >> 3], PMVbEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsStart >> 3], PMVsStart);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMVsEnd >> 3], PMVsEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenBase >> 3], PMScreenBase);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[PMScreenStride >> 3],
+ PMScreenStride);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/tx_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/tx_accel.c
new file mode 100644
index 000000000..27068af1b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/tx_accel.c
@@ -0,0 +1,1041 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ * Dirk Hohndel, <hohndel@suse.de>
+ * Stefan Dirsch, <sndirsch@suse.de>
+ *
+ * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and
+ * Siemens Nixdorf Informationssysteme
+ *
+ * GLINT 500TX / MX accelerated options.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/tx_accel.c,v 1.15 1999/07/04 06:39:02 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb32.h"
+
+#include "miline.h"
+
+#include "glint_regs.h"
+#include "glint.h"
+
+#include "xaalocal.h" /* For replacements */
+
+static void TXSync(ScrnInfoPtr pScrn);
+static void TXSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+static void TXSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h);
+static void TXSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx,
+ int patterny,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void TXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
+ int patterny, int x, int y,
+ int w, int h);
+static void TXSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned int planemask,
+ int transparency_color);
+static void TXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h);
+static void TXWriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth,
+ int skipleft, int fg, int bg, int rop,
+ unsigned int planemask);
+static void TXSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2,int y2);
+static void TXDisableClipping(ScrnInfoPtr pScrn);
+static void TXWritePixmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int rop,
+ unsigned int planemask, int trans,
+ int bpp, int depth);
+static void TXSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg,
+ int bg, int rop, unsigned int planemask);
+static void TXSubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h, int skipleft);
+static void TXSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg,
+ int bg, int rop, unsigned int planemask);
+static void TXSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h, int skipleft);
+static void TXSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
+static void TXLoadCoord(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ int a, int d);
+static void TXSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+static void TXSubsequentHorVertLine(ScrnInfoPtr pScrn, int x1, int y1,
+ int len, int dir);
+static void TXSubsequentSolidBresenhamLine8bpp(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+static void TXSubsequentSolidBresenhamLine16bpp(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+static void TXSubsequentSolidBresenhamLine32bpp(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+static void TXPolylinesThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC,
+ int mode, int npt, DDXPointPtr pPts);
+static void TXPolySegmentThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC,
+ int nseg, xSegment *pSeg);
+
+#define MAX_FIFO_ENTRIES 15
+
+static void
+TXInitializeEngine(ScrnInfoPtr pScrn)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ /* Initialize the Accelerator Engine to defaults */
+
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode);
+ GLINT_SLOW_WRITE_REG(pGlint->pprod, LBReadMode);
+ GLINT_SLOW_WRITE_REG(pGlint->pprod, FBReadMode);
+ GLINT_SLOW_WRITE_REG(0, dXSub);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBWriteMode);
+ GLINT_SLOW_WRITE_REG(UNIT_ENABLE, FBWriteMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DitherMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ColorDDAMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureColorMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureAddressMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureReadMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, GLINTWindow);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RouterMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FogMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AntialiasMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaTestMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StencilMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AreaStippleMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LineStippleMode);
+ GLINT_SLOW_WRITE_REG(0, UpdateLineStippleCounters);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LogicalOpMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StatisticMode);
+ GLINT_SLOW_WRITE_REG(0x400, FilterMode);
+ GLINT_SLOW_WRITE_REG(0xffffffff, FBHardwareWriteMask);
+ GLINT_SLOW_WRITE_REG(0xffffffff, FBSoftwareWriteMask);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RasterizerMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, GLINTDepth);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBSourceOffset);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBPixelOffset);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBSourceOffset);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, WindowOrigin);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBWindowBase);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBWindowBase);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureAddressMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RouterMode);
+ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PatternRamMode);
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ GLINT_SLOW_WRITE_REG(0x2, PixelSize);
+ break;
+ case 16:
+ GLINT_SLOW_WRITE_REG(0x1, PixelSize);
+ break;
+ case 32:
+ GLINT_SLOW_WRITE_REG(0x0, PixelSize);
+ break;
+ }
+ pGlint->ROP = 0xFF;
+ pGlint->ClippingOn = FALSE;
+ pGlint->startxsub = 0;
+ pGlint->startxdom = 0;
+ pGlint->starty = 0;
+ pGlint->count = 0;
+ pGlint->dxdom = 0;
+ pGlint->dy = 1;
+ pGlint->planemask = 0;
+ GLINT_SLOW_WRITE_REG(0, StartXSub);
+ GLINT_SLOW_WRITE_REG(0, StartXDom);
+ GLINT_SLOW_WRITE_REG(0, StartY);
+ GLINT_SLOW_WRITE_REG(0, GLINTCount);
+ GLINT_SLOW_WRITE_REG(0, dXDom);
+ GLINT_SLOW_WRITE_REG(1<<16, dY);
+}
+
+Bool
+TXAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ long memory = pGlint->FbMapSize;
+ BoxRec AvailFBArea;
+
+ pGlint->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ TXInitializeEngine(pScrn);
+
+ infoPtr->Flags = PIXMAP_CACHE |
+ LINEAR_FRAMEBUFFER |
+ OFFSCREEN_PIXMAPS;
+
+ infoPtr->Sync = TXSync;
+
+ infoPtr->SetClippingRectangle = TXSetClippingRectangle;
+ infoPtr->DisableClipping = TXDisableClipping;
+ infoPtr->ClippingFlags = HARDWARE_CLIP_MONO_8x8_FILL |
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
+ HARDWARE_CLIP_SOLID_FILL;
+
+ infoPtr->SolidFillFlags = 0;
+ infoPtr->SetupForSolidFill = TXSetupForFillRectSolid;
+ infoPtr->SubsequentSolidFillRect = TXSubsequentFillRectSolid;
+
+ infoPtr->SolidLineFlags = 0;
+ infoPtr->PolySegmentThinSolidFlags = 0;
+ infoPtr->PolylinesThinSolidFlags = 0;
+ infoPtr->SetupForSolidLine = TXSetupForSolidLine;
+ infoPtr->SubsequentSolidHorVertLine = TXSubsequentHorVertLine;
+ switch(pScrn->bitsPerPixel) {
+ case 8: infoPtr->SubsequentSolidBresenhamLine =
+ TXSubsequentSolidBresenhamLine8bpp;
+ break;
+ case 16: infoPtr->SubsequentSolidBresenhamLine =
+ TXSubsequentSolidBresenhamLine16bpp;
+ break;
+ case 32: infoPtr->SubsequentSolidBresenhamLine =
+ TXSubsequentSolidBresenhamLine32bpp;
+ break;
+ }
+ infoPtr->PolySegmentThinSolid = TXPolySegmentThinSolidWrapper;
+ infoPtr->PolylinesThinSolid = TXPolylinesThinSolidWrapper;
+
+ infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY |
+ ONLY_LEFT_TO_RIGHT_BITBLT;
+ infoPtr->SetupForScreenToScreenCopy = TXSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy = TXSubsequentScreenToScreenCopy;
+
+ infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS;
+ infoPtr->SetupForMono8x8PatternFill = TXSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect = TXSubsequentMono8x8PatternFillRect;
+
+ if (!pGlint->UsePCIRetry) {
+ infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
+ TRANSPARENCY_ONLY |
+ BIT_ORDER_IN_BYTE_LSBFIRST;
+
+ pGlint->XAAScanlineColorExpandBuffers[0] =
+ xnfalloc(((pScrn->virtualX + 63)/32) *4* (pScrn->bitsPerPixel / 8));
+ pGlint->XAAScanlineColorExpandBuffers[1] =
+ xnfalloc(((pScrn->virtualX + 63)/32) *4* (pScrn->bitsPerPixel / 8));
+
+ infoPtr->NumScanlineColorExpandBuffers = 2;
+ infoPtr->ScanlineColorExpandBuffers =
+ pGlint->XAAScanlineColorExpandBuffers;
+
+ infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
+ TXSetupForScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
+ TXSubsequentScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentColorExpandScanline =
+ TXSubsequentColorExpandScanline;
+ } else {
+ infoPtr->CPUToScreenColorExpandFillFlags = TRANSPARENCY_ONLY |
+ SYNC_AFTER_COLOR_EXPAND |
+ CPU_TRANSFER_PAD_DWORD |
+ BIT_ORDER_IN_BYTE_LSBFIRST;
+ infoPtr->ColorExpandBase = pGlint->IOBase + OutputFIFO + 4;
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ TXSetupForCPUToScreenColorExpandFill;
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ TXSubsequentCPUToScreenColorExpandFill;
+ }
+
+ infoPtr->ColorExpandRange = MAX_FIFO_ENTRIES;
+
+ infoPtr->WriteBitmap = TXWriteBitmap;
+ infoPtr->WritePixmap = TXWritePixmap;
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ if (memory > (16383*1024)) memory = 16383*1024;
+ AvailFBArea.y2 = memory / (pScrn->displayWidth *
+ pScrn->bitsPerPixel / 8);
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ return (XAAInit(pScreen, infoPtr));
+}
+
+static void TXLoadCoord(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h,
+ int a, int d
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ if (w != pGlint->startxsub) {
+ GLINT_WRITE_REG(w<<16, StartXSub);
+ pGlint->startxsub = w;
+ }
+ if (x != pGlint->startxdom) {
+ GLINT_WRITE_REG(x<<16,StartXDom);
+ pGlint->startxdom = x;
+ }
+ if (y != pGlint->starty) {
+ GLINT_WRITE_REG(y<<16,StartY);
+ pGlint->starty = y;
+ }
+ if (h != pGlint->count) {
+ GLINT_WRITE_REG(h,GLINTCount);
+ pGlint->count = h;
+ }
+ if (a != pGlint->dxdom) {
+ GLINT_WRITE_REG(a<<16,dXDom);
+ pGlint->dxdom = a;
+ }
+ if (d != pGlint->dy) {
+ GLINT_WRITE_REG(d<<16,dY);
+ pGlint->dy = d;
+ }
+}
+
+static void MoveDWORDS(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ *(dest + 2) = *(src + 2);
+ *(dest + 3) = *(src + 3);
+ src += 4;
+ dest += 4;
+ dwords -= 4;
+ }
+ if (!dwords) return;
+ *dest = *src;
+ if (dwords == 1) return;
+ *(dest + 1) = *(src + 1);
+ if (dwords == 2) return;
+ *(dest + 2) = *(src + 2);
+}
+
+static void
+TXSync(
+ ScrnInfoPtr pScrn
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ CARD32 readValue;
+
+ CHECKCLIPPING;
+
+ while (GLINT_READ_REG(DMACount) != 0);
+ GLINT_WAIT(2);
+ GLINT_WRITE_REG(0x400, FilterMode);
+ GLINT_WRITE_REG(0, GlintSync);
+ do {
+ while(GLINT_READ_REG(OutFIFOWords) == 0);
+#define Sync_tag 0x188
+ readValue = GLINT_READ_REG(OutputFIFO);
+ } while (readValue != Sync_tag);
+}
+
+static void
+TXSetupForFillRectSolid(
+ ScrnInfoPtr pScrn,
+ int color, int rop,
+ unsigned int planemask
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ pGlint->ForeGroundColor = color;
+
+ GLINT_WAIT(5);
+ REPLICATE(color);
+ DO_PLANEMASK(planemask);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
+ GLINT_WRITE_REG(color, FBBlockColor);
+ pGlint->FrameBufferReadMode = FastFillEnable;
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode);
+ GLINT_WRITE_REG(color, PatternRamData0);
+ pGlint->FrameBufferReadMode = FastFillEnable | SpanOperation;
+ }
+ LOADROP(rop);
+}
+
+static void
+TXSubsequentFillRectSolid(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_WAIT(7);
+ TXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
+ GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode,Render);
+}
+
+static void
+TXSetClippingRectangle(
+ ScrnInfoPtr pScrn,
+ int x1, int y1,
+ int x2, int y2
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_WAIT(3);
+ GLINT_WRITE_REG((y1&0xFFFF)<<16|(x1&0xFFFF), ScissorMinXY);
+ GLINT_WRITE_REG((y2&0xFFFF)<<16|(x2&0xFFFF), ScissorMaxXY);
+ GLINT_WRITE_REG(1, ScissorMode); /* Enable Scissor Mode */
+ pGlint->ClippingOn = TRUE;
+}
+
+static void
+TXDisableClipping(
+ ScrnInfoPtr pScrn
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ CHECKCLIPPING;
+}
+
+static void
+TXSetupForScreenToScreenCopy(
+ ScrnInfoPtr pScrn,
+ int xdir, int ydir,
+ int rop,
+ unsigned int planemask,
+ int transparency_color
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ pGlint->BltScanDirection = ydir;
+
+ GLINT_WAIT(5);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
+
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_SrcEnable, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_SrcEnable | FBRM_DstEnable, FBReadMode);
+ }
+ LOADROP(rop);
+}
+
+static void
+TXSubsequentScreenToScreenCopy(
+ ScrnInfoPtr pScrn,
+ int x1, int y1,
+ int x2, int y2,
+ int w, int h
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int srcaddr, dstaddr;
+
+ GLINT_WAIT(8);
+ if (pGlint->BltScanDirection != 1) {
+ y1 += h - 1;
+ y2 += h - 1;
+ TXLoadCoord(pScrn, x2, y2, x2+w, h, 0, -1);
+ } else {
+ TXLoadCoord(pScrn, x2, y2, x2+w, h, 0, 1);
+ }
+
+ srcaddr = y1 * pScrn->displayWidth + x1;
+ dstaddr = y2 * pScrn->displayWidth + x2;
+
+ GLINT_WRITE_REG(srcaddr - dstaddr, FBSourceOffset);
+ GLINT_WRITE_REG(PrimitiveTrapezoid| FastFillEnable | SpanOperation, Render);
+}
+
+static void
+TXSetupForScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ REPLICATE(fg);
+ REPLICATE(bg);
+ GLINT_WAIT(6);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(0, RasterizerMode);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
+ pGlint->FrameBufferReadMode = FastFillEnable;
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode);
+ pGlint->FrameBufferReadMode = FastFillEnable | SpanOperation;
+ GLINT_WRITE_REG(fg, PatternRamData0);
+ }
+ LOADROP(rop);
+}
+
+static void
+TXSubsequentScanlineCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ pGlint->dwords = ((w + 31) >> 5); /* dwords per scanline */
+
+ pGlint->cpucount = y;
+ pGlint->cpuheight = h;
+ GLINT_WAIT(6);
+ TXLoadCoord(pScrn, x, pGlint->cpucount, x+w, 1, 0, 1);
+}
+
+static void
+TXSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ CARD32 *src;
+ int dwords = pGlint->dwords;
+
+ GLINT_WAIT(7);
+ TXLoadCoord(pScrn, pGlint->startxdom, pGlint->cpucount, pGlint->startxsub, 1, 0, 1);
+
+ GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode | SyncOnBitMask,
+ Render);
+
+ src = (CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno];
+ while (dwords >= infoRec->ColorExpandRange) {
+ GLINT_WAIT(infoRec->ColorExpandRange);
+ GLINT_WRITE_REG((infoRec->ColorExpandRange - 2)<<16 | 0x0D, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), src,
+ infoRec->ColorExpandRange - 1);
+ dwords -= (infoRec->ColorExpandRange - 1);
+ src += (infoRec->ColorExpandRange - 1);
+ }
+ if (dwords) {
+ GLINT_WAIT(dwords);
+ GLINT_WRITE_REG((dwords - 1)<<16 | 0x0D, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), src,dwords);
+ }
+ pGlint->cpucount += 1;
+}
+
+static void
+TXSetupForCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ REPLICATE(fg);
+
+ DO_PLANEMASK(planemask);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ pGlint->FrameBufferReadMode = FastFillEnable;
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode);
+ GLINT_WRITE_REG(fg, PatternRamData0);
+ pGlint->FrameBufferReadMode = FastFillEnable | SpanOperation;
+ }
+ LOADROP(rop);
+}
+
+static void
+TXSubsequentCPUToScreenColorExpandFill(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int dwords = ((w + 31) >> 5) * h;
+
+ TXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
+ GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode |
+ SyncOnBitMask, Render);
+ GLINT_WRITE_REG((dwords - 1)<<16 | 0x0D, OutputFIFO);
+}
+
+void TXSetupForMono8x8PatternFill(
+ ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int fg, int bg, int rop,
+ unsigned int planemask
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ if (bg == -1) pGlint->FrameBufferReadMode = -1;
+ else pGlint->FrameBufferReadMode = 0;
+ pGlint->ForeGroundColor = fg;
+ pGlint->BackGroundColor = bg;
+ REPLICATE(pGlint->ForeGroundColor);
+ REPLICATE(pGlint->BackGroundColor);
+
+ GLINT_WAIT(13);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG((patternx & 0x000000FF), AreaStipplePattern0);
+ GLINT_WRITE_REG((patternx & 0x0000FF00) >> 8, AreaStipplePattern1);
+ GLINT_WRITE_REG((patternx & 0x00FF0000) >> 16, AreaStipplePattern2);
+ GLINT_WRITE_REG((patternx & 0xFF000000) >> 24, AreaStipplePattern3);
+ GLINT_WRITE_REG((patterny & 0x000000FF), AreaStipplePattern4);
+ GLINT_WRITE_REG((patterny & 0x0000FF00) >> 8, AreaStipplePattern5);
+ GLINT_WRITE_REG((patterny & 0x00FF0000) >> 16, AreaStipplePattern6);
+ GLINT_WRITE_REG((patterny & 0xFF000000) >> 24, AreaStipplePattern7);
+
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode);
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ LOADROP(rop);
+}
+
+static void
+TXSubsequentMono8x8PatternFillRect(
+ ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h
+){
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int span = 0;
+
+ GLINT_WAIT(12);
+ TXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
+
+ if (pGlint->FrameBufferReadMode != -1) {
+ if (pGlint->ROP == GXcopy) {
+ GLINT_WRITE_REG(pGlint->BackGroundColor, FBBlockColor);
+ span = 0;
+ } else {
+ GLINT_WRITE_REG(pGlint->BackGroundColor, PatternRamData0);
+ span = SpanOperation;
+ }
+ GLINT_WRITE_REG(2<<1|2<<4|patternx<<7|patterny<<12|ASM_InvertPattern |
+ UNIT_ENABLE, AreaStippleMode);
+ GLINT_WRITE_REG(AreaStippleEnable | span | FastFillEnable |
+ PrimitiveTrapezoid, Render);
+ }
+
+ if (pGlint->ROP == GXcopy) {
+ GLINT_WRITE_REG(pGlint->ForeGroundColor, FBBlockColor);
+ span = 0;
+ } else {
+ GLINT_WRITE_REG(pGlint->ForeGroundColor, PatternRamData0);
+ span = SpanOperation;
+ }
+ GLINT_WRITE_REG(2<<1|2<<4|patternx<<7|patterny<<12|
+ UNIT_ENABLE, AreaStippleMode);
+ GLINT_WRITE_REG(AreaStippleEnable | span | FastFillEnable |
+ PrimitiveTrapezoid, Render);
+}
+
+static void
+TXWriteBitmap(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ unsigned char *srcpntr;
+ int dwords, height, mode;
+ Bool SecondPass = FALSE;
+ register int count;
+ register CARD32* pattern;
+
+ w += skipleft;
+ x -= skipleft;
+ dwords = (w + 31) >> 5;
+
+ TXSetClippingRectangle(pScrn,x+skipleft, y, x+w, y+h);
+
+ GLINT_WAIT(11);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(0, RasterizerMode);
+ LOADROP(rop);
+ if (rop == GXcopy) {
+ mode = 0;
+ GLINT_WRITE_REG(UNIT_DISABLE, PatternRamMode);
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ mode = SpanOperation;
+ GLINT_WRITE_REG(UNIT_ENABLE, PatternRamMode);
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ TXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
+
+ if(bg == -1) {
+ /* >>>>> set fg <<<<<<<< */
+ REPLICATE(fg);
+ GLINT_WAIT(3);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(fg, PatternRamData0);
+ }
+ } else if(rop == GXcopy) {
+ REPLICATE(bg);
+ GLINT_WAIT(5);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(bg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(bg, PatternRamData0);
+ }
+ GLINT_WRITE_REG(PrimitiveTrapezoid |mode|FastFillEnable,Render);
+ REPLICATE(fg);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(fg, PatternRamData0);
+ }
+ } else {
+ SecondPass = TRUE;
+ REPLICATE(fg);
+ GLINT_WAIT(3);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(fg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(fg, PatternRamData0);
+ }
+ }
+
+SECOND_PASS:
+ GLINT_WRITE_REG(PrimitiveTrapezoid | FastFillEnable | mode | SyncOnBitMask, Render);
+
+ height = h;
+ srcpntr = src;
+ while(height--) {
+ count = dwords >> 3;
+ pattern = (CARD32*)srcpntr;
+ while(count--) {
+ GLINT_WAIT(8);
+ GLINT_WRITE_REG(*(pattern), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+1), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+2), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+3), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+4), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+5), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+6), BitMaskPattern);
+ GLINT_WRITE_REG(*(pattern+7), BitMaskPattern);
+ pattern+=8;
+ }
+ count = dwords & 0x07;
+ GLINT_WAIT(count);
+ while (count--)
+ GLINT_WRITE_REG(*(pattern++), BitMaskPattern);
+ srcpntr += srcwidth;
+ }
+
+ if(SecondPass) {
+ SecondPass = FALSE;
+ REPLICATE(bg);
+ GLINT_WAIT(4);
+ GLINT_WRITE_REG(InvertBitMask, RasterizerMode);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(bg, FBBlockColor);
+ } else {
+ GLINT_WRITE_REG(bg, PatternRamData0);
+ }
+ goto SECOND_PASS;
+ }
+
+ GLINT_WAIT(2);
+ GLINT_WRITE_REG(0, RasterizerMode);
+ CHECKCLIPPING;
+ SET_SYNC_FLAG(infoRec);
+}
+
+static void
+TXWritePixmap(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth, /* bytes */
+ int rop,
+ unsigned int planemask,
+ int trans,
+ int bpp, int depth
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ CARD32 *srcp;
+ int count,dwords, skipleft, Bpp = bpp >> 3;
+
+ if((skipleft = (long)src & 0x03L)) {
+ skipleft /= Bpp;
+
+ x -= skipleft;
+ w += skipleft;
+
+ src = (unsigned char*)((long)src & ~0x03L);
+ }
+
+ switch(Bpp) {
+ case 1: dwords = (w + 3) >> 2;
+ break;
+ case 2: dwords = (w + 1) >> 1;
+ break;
+ case 4: dwords = w;
+ break;
+ default: return;
+ }
+
+ TXSetClippingRectangle(pScrn,x+skipleft, y, x+w, y+h);
+
+ GLINT_WAIT(12);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(0, PatternRamMode);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ LOADROP(rop);
+ TXLoadCoord(pScrn, x, y, x+w, h, 0, 1);
+ GLINT_WRITE_REG(PrimitiveTrapezoid | FastFillEnable | SpanOperation |
+ SyncOnHostData, Render);
+
+ while(h--) {
+ count = dwords;
+ srcp = (CARD32*)src;
+ while(count >= infoRec->ColorExpandRange) {
+ GLINT_WAIT(infoRec->ColorExpandRange);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, infoRec->ColorExpandRange - 1);
+ count -= infoRec->ColorExpandRange - 1;
+ srcp += infoRec->ColorExpandRange - 1;
+ }
+ if(count) {
+ GLINT_WAIT(count);
+ /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */
+ GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) |
+ 0x05, OutputFIFO);
+ MoveDWORDS((CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4),
+ (CARD32*)srcp, count);
+ }
+ src += srcwidth;
+ }
+ CHECKCLIPPING;
+ SET_SYNC_FLAG(infoRec);
+}
+
+static void
+TXPolylinesThinSolidWrapper(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ GLINTPtr pGlint = GLINTPTR(infoRec->pScrn);
+ pGlint->CurrentGC = pGC;
+ if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn);
+ XAAPolyLines(pDraw, pGC, mode, npt, pPts);
+}
+
+static void
+TXPolySegmentThinSolidWrapper(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ GLINTPtr pGlint = GLINTPTR(infoRec->pScrn);
+ pGlint->CurrentGC = pGC;
+ if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn);
+ XAAPolySegment(pDraw, pGC, nseg, pSeg);
+}
+
+static void
+TXSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_WAIT(5);
+ DO_PLANEMASK(planemask);
+ GLINT_WRITE_REG(color, GLINTColor);
+ if (rop == GXcopy) {
+ GLINT_WRITE_REG(pGlint->pprod, FBReadMode);
+ } else {
+ GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode);
+ }
+ LOADROP(rop);
+}
+
+static void
+TXSubsequentHorVertLine(ScrnInfoPtr pScrn,int x,int y,int len,int dir)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ GLINT_WAIT(7);
+ if (dir == DEGREES_0) {
+ TXLoadCoord(pScrn, x, y, 0, len, 1, 0);
+ } else {
+ TXLoadCoord(pScrn, x, y, 0, len, 0, 1);
+ }
+
+ GLINT_WRITE_REG(PrimitiveLine, Render);
+}
+
+static void
+TXSubsequentSolidBresenhamLine8bpp( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ cfbPrivGCPtr devPriv;
+ int dxdom, dy;
+
+ if(dmaj == dmin) {
+ GLINT_WAIT(7);
+ if(octant & YDECREASING) {
+ dy = -1;
+ } else {
+ dy = 1;
+ }
+
+ if(octant & XDECREASING) {
+ dxdom = -1;
+ } else {
+ dxdom = 1;
+ }
+
+ TXLoadCoord(pScrn, x, y, 0, len, dxdom, dy);
+ GLINT_WRITE_REG(PrimitiveLine, Render);
+ return;
+ }
+
+ devPriv = cfbGetGCPrivate(pGlint->CurrentGC);
+
+ cfbBresS(devPriv->rop, devPriv->and, devPriv->xor,
+ (unsigned long*)pGlint->FbBase, pScrn->displayWidth >> 2,
+ (octant & XDECREASING) ? -1 : 1,
+ (octant & YDECREASING) ? -1 : 1,
+ (octant & YMAJOR) ? Y_AXIS : X_AXIS,
+ x, y, dmin + e, dmin, dmin - dmaj, len);
+}
+
+static void
+TXSubsequentSolidBresenhamLine16bpp( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ cfbPrivGCPtr devPriv;
+ int dxdom, dy;
+
+ if(dmaj == dmin) {
+ GLINT_WAIT(7);
+ if(octant & YDECREASING) {
+ dy = -1;
+ } else {
+ dy = 1;
+ }
+
+ if(octant & XDECREASING) {
+ dxdom = -1;
+ } else {
+ dxdom = 1;
+ }
+
+ TXLoadCoord(pScrn, x, y, 0, len, dxdom, dy);
+ GLINT_WRITE_REG(PrimitiveLine, Render);
+ return;
+ }
+
+ devPriv = cfbGetGCPrivate(pGlint->CurrentGC);
+
+ cfb16BresS(devPriv->rop, devPriv->and, devPriv->xor,
+ (unsigned long*)pGlint->FbBase, pScrn->displayWidth >> 1,
+ (octant & XDECREASING) ? -1 : 1,
+ (octant & YDECREASING) ? -1 : 1,
+ (octant & YMAJOR) ? Y_AXIS : X_AXIS,
+ x, y, dmin + e, dmin, dmin - dmaj, len);
+}
+
+static void
+TXSubsequentSolidBresenhamLine32bpp( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ cfbPrivGCPtr devPriv;
+ int dxdom, dy;
+
+ if(dmaj == dmin) {
+ GLINT_WAIT(7);
+ if(octant & YDECREASING) {
+ dy = -1;
+ } else {
+ dy = 1;
+ }
+
+ if(octant & XDECREASING) {
+ dxdom = -1;
+ } else {
+ dxdom = 1;
+ }
+
+ TXLoadCoord(pScrn, x, y, 0, len, dxdom, dy);
+ GLINT_WRITE_REG(PrimitiveLine, Render);
+ return;
+ }
+
+ devPriv = cfbGetGCPrivate(pGlint->CurrentGC);
+
+ cfb32BresS(devPriv->rop, devPriv->and, devPriv->xor,
+ (unsigned long*)pGlint->FbBase, pScrn->displayWidth,
+ (octant & XDECREASING) ? -1 : 1,
+ (octant & YDECREASING) ? -1 : 1,
+ (octant & YMAJOR) ? Y_AXIS : X_AXIS,
+ x, y, dmin + e, dmin, dmin - dmaj, len);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/glint/tx_dac.c b/xc/programs/Xserver/hw/xfree86/drivers/glint/tx_dac.c
new file mode 100644
index 000000000..c2cc94452
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/glint/tx_dac.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane <alanh@fairlite.demon.co.uk>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ * Dirk Hohndel, <hohndel@suse.de>
+ * Stefan Dirsch, <sndirsch@suse.de>
+ * Helmut Fahrion, <hf@suse.de>
+ *
+ * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and
+ * Siemens Nixdorf Informationssysteme
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/tx_dac.c,v 1.8 1999/03/28 15:32:39 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "IBM.h"
+#include "glint_regs.h"
+#include "glint.h"
+
+static int
+Shiftbpp(ScrnInfoPtr pScrn, int value)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ int logbytesperaccess;
+
+ if (pGlint->RamDac->RamDacType == (IBM640_RAMDAC))
+ logbytesperaccess = 4;
+ else
+ logbytesperaccess = 3;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ value >>= logbytesperaccess;
+ pGlint->BppShift = logbytesperaccess;
+ break;
+ case 16:
+ if (pGlint->DoubleBuffer) {
+ value >>= (logbytesperaccess-2);
+ pGlint->BppShift = logbytesperaccess-2;
+ } else {
+ value >>= (logbytesperaccess-1);
+ pGlint->BppShift = logbytesperaccess-1;
+ }
+ break;
+ case 24:
+ value *= 3;
+ value >>= logbytesperaccess;
+ pGlint->BppShift = logbytesperaccess;
+ break;
+ case 32:
+ value >>= (logbytesperaccess-2);
+ pGlint->BppShift = logbytesperaccess-2;
+ break;
+ }
+ return (value);
+}
+
+Bool
+TXInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+ GLINTRegPtr pReg = &pGlint->ModeReg;
+ RamDacHWRecPtr pIBM = RAMDACHWPTR(pScrn);
+ RamDacRegRecPtr ramdacReg = &pIBM->ModeReg;
+ CARD32 temp1, temp2, temp3, temp4;
+
+ pReg->glintRegs[Aperture0 >> 3] = 0;
+ pReg->glintRegs[Aperture1 >> 3] = 0;
+
+ if (pGlint->UsePCIRetry) {
+ pReg->glintRegs[DFIFODis >> 3] = 1;
+ pReg->glintRegs[FIFODis >> 3] = 3;
+ } else {
+ pReg->glintRegs[DFIFODis >> 3] = 0;
+ pReg->glintRegs[FIFODis >> 3] = 1;
+ }
+
+ temp1 = mode->CrtcHSyncStart - mode->CrtcHDisplay;
+ temp2 = mode->CrtcVSyncStart - mode->CrtcVDisplay;
+ temp3 = mode->CrtcHSyncEnd - mode->CrtcHSyncStart;
+ temp4 = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+
+ pReg->glintRegs[VTGHLimit >> 3] = Shiftbpp(pScrn,mode->CrtcHTotal);
+ pReg->glintRegs[VTGHSyncEnd >> 3] = Shiftbpp(pScrn, temp1 + temp3);
+ pReg->glintRegs[VTGHSyncStart >> 3] = Shiftbpp(pScrn, temp1);
+ pReg->glintRegs[VTGHBlankEnd >> 3] = Shiftbpp(pScrn, mode->CrtcHTotal -
+ mode->CrtcHDisplay);
+
+ pReg->glintRegs[VTGVLimit >> 3] = mode->CrtcVTotal;
+ pReg->glintRegs[VTGVSyncEnd >> 3] = temp2 + temp4;
+ pReg->glintRegs[VTGVSyncStart >> 3] = temp2;
+ pReg->glintRegs[VTGVBlankEnd >> 3] = mode->CrtcVTotal - mode->CrtcVDisplay;
+
+ pReg->glintRegs[VTGPolarity >> 3] = (((mode->Flags & V_PHSYNC) ? 0:2)<<2) |
+ ((mode->Flags & V_PVSYNC) ? 0 : 2) | (0xb0);
+
+ pReg->glintRegs[VClkCtl >> 3] = 0;
+ pReg->glintRegs[VTGVGateStart >> 3] = pReg->glintRegs[VTGVBlankEnd>>3] - 1;
+ pReg->glintRegs[VTGVGateEnd >> 3] = pReg->glintRegs[VTGVBlankEnd>>3];
+ /*
+ * tell DAC to use the ICD chip clock 0 as ref clock
+ * and set up some more video timining generator registers
+ */
+ pReg->glintRegs[VTGSerialClk >> 3] = 0x05;
+
+ /* This is ugly */
+ if (pGlint->UseFireGL3000) {
+ pReg->glintRegs[VTGHGateStart >> 3] =
+ pReg->glintRegs[VTGHBlankEnd>>3] - 1;
+ pReg->glintRegs[VTGHGateEnd >> 3] = pReg->glintRegs[VTGHLimit>>3] - 1;
+ pReg->glintRegs[FBModeSel >> 3] = 0x907;
+ pReg->glintRegs[VTGModeCtl >> 3] = 0x00;
+ } else {
+ pReg->glintRegs[VTGHGateStart >> 3] =
+ pReg->glintRegs[VTGHBlankEnd>>3] - 2;
+ pReg->glintRegs[VTGHGateEnd >> 3] = pReg->glintRegs[VTGHLimit>>3] - 2;
+ pReg->glintRegs[FBModeSel >> 3] = 0x0A07;
+ pReg->glintRegs[VTGModeCtl >> 3] = 0x44;
+ }
+
+ switch (pGlint->RamDac->RamDacType) {
+ case IBM526DB_RAMDAC:
+ case IBM526_RAMDAC:
+ {
+ /* Get the programmable clock values */
+ unsigned long m=0,n=0,p=0,c=0;
+ unsigned long clock;
+
+ clock = IBMramdac526CalculateMNPCForClock(pGlint->RefClock, mode->Clock,
+ 1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c);
+
+ ramdacReg->DacRegs[IBMRGB_m0] = m;
+ ramdacReg->DacRegs[IBMRGB_n0] = n;
+ ramdacReg->DacRegs[IBMRGB_p0] = p;
+ ramdacReg->DacRegs[IBMRGB_c0] = c;
+
+ ramdacReg->DacRegs[IBMRGB_pll_ctrl1] = 0x05;
+ ramdacReg->DacRegs[IBMRGB_pll_ctrl2] = 0x00;
+
+ p = 1;
+ clock = IBMramdac526CalculateMNPCForClock(pGlint->RefClock, mode->Clock,
+ 0, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c);
+
+ ramdacReg->DacRegs[IBMRGB_sysclk] = 0x05;
+ ramdacReg->DacRegs[IBMRGB_sysclk_m] = m;
+ ramdacReg->DacRegs[IBMRGB_sysclk_n] = n;
+ ramdacReg->DacRegs[IBMRGB_sysclk_p] = p;
+ ramdacReg->DacRegs[IBMRGB_sysclk_c] = c;
+ }
+ ramdacReg->DacRegs[IBMRGB_misc1] = SENS_DSAB_DISABLE | VRAM_SIZE_64;
+ ramdacReg->DacRegs[IBMRGB_misc2] = COL_RES_8BIT|PORT_SEL_VRAM|PCLK_SEL_PLL;
+ ramdacReg->DacRegs[IBMRGB_misc3] = 0;
+ ramdacReg->DacRegs[IBMRGB_misc_clock] = 1;
+ ramdacReg->DacRegs[IBMRGB_sync] = 0;
+ ramdacReg->DacRegs[IBMRGB_hsync_pos] = 0;
+ ramdacReg->DacRegs[IBMRGB_pwr_mgmt] = 0;
+ ramdacReg->DacRegs[IBMRGB_dac_op] = 0;
+ ramdacReg->DacRegs[IBMRGB_pal_ctrl] = 0;
+
+ break;
+ case IBM640_RAMDAC:
+ {
+ /* Get the programmable clock values */
+ unsigned long m=0,n=0,p=0,c=0;
+ unsigned long clock;
+
+ clock = IBMramdac640CalculateMNPCForClock(pGlint->RefClock, mode->Clock,
+ 1, pGlint->MinClock, pGlint->MaxClock, &m, &n, &p, &c);
+
+ ramdacReg->DacRegs[RGB640_PLL_N] = n;
+ ramdacReg->DacRegs[RGB640_PLL_M] = m;
+ ramdacReg->DacRegs[RGB640_PLL_P] = p<<1;
+ ramdacReg->DacRegs[RGB640_PLL_CTL] = c | IBM640_PLL_EN;
+ ramdacReg->DacRegs[RGB640_AUX_PLL_CTL] = 0; /* Disable AUX PLL */
+ }
+ ramdacReg->DacRegs[RGB640_PIXEL_INTERLEAVE] = 0x00;
+ ramdacReg->DacRegs[RGB640_VGA_CONTROL] = IBM640_RDBK | IBM640_VRAM;
+ if (pScrn->rgbBits == 8)
+ ramdacReg->DacRegs[RGB640_VGA_CONTROL] |= IBM640_PSIZE8;
+ ramdacReg->DacRegs[RGB640_DAC_CONTROL] = IBM640_DACENBL | IBM640_SHUNT;
+ ramdacReg->DacRegs[RGB640_OUTPUT_CONTROL] = IBM640_WATCTL;
+ ramdacReg->DacRegs[RGB640_SYNC_CONTROL] = 0x00;
+ ramdacReg->DacRegs[RGB640_VRAM_MASK0] = 0xFF;
+ ramdacReg->DacRegs[RGB640_VRAM_MASK1] = 0xFF;
+ ramdacReg->DacRegs[RGB640_VRAM_MASK2] = 0x0F;
+
+ pReg->glintRegs[VTGModeCtl >> 3] = 0x04;
+ }
+
+ /* Now use helper routines to setup bpp for this driver */
+ (*pGlint->RamDac->SetBpp)(pScrn, ramdacReg);
+
+ return(TRUE);
+}
+
+void
+TXSave(ScrnInfoPtr pScrn, GLINTRegPtr glintReg)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+ glintReg->glintRegs[Aperture0 >> 3] = GLINT_READ_REG(Aperture0);
+ glintReg->glintRegs[Aperture1 >> 3] = GLINT_READ_REG(Aperture1);
+
+ glintReg->glintRegs[DFIFODis >> 3] = GLINT_READ_REG(DFIFODis);
+ glintReg->glintRegs[FIFODis >> 3] = GLINT_READ_REG(FIFODis);
+
+ glintReg->glintRegs[VClkCtl >> 3] = GLINT_READ_REG(VClkCtl);
+ glintReg->glintRegs[VTGPolarity >> 3] = GLINT_READ_REG(VTGPolarity);
+ glintReg->glintRegs[VTGHLimit >> 3] = GLINT_READ_REG(VTGHLimit);
+ glintReg->glintRegs[VTGHBlankEnd >> 3] = GLINT_READ_REG(VTGHBlankEnd);
+ glintReg->glintRegs[VTGHSyncStart >> 3] = GLINT_READ_REG(VTGHSyncStart);
+ glintReg->glintRegs[VTGHSyncEnd >> 3] = GLINT_READ_REG(VTGHSyncEnd);
+ glintReg->glintRegs[VTGVLimit >> 3] = GLINT_READ_REG(VTGVLimit);
+ glintReg->glintRegs[VTGVBlankEnd >> 3] = GLINT_READ_REG(VTGVBlankEnd);
+ glintReg->glintRegs[VTGVSyncStart >> 3] = GLINT_READ_REG(VTGVSyncStart);
+ glintReg->glintRegs[VTGVSyncEnd >> 3] = GLINT_READ_REG(VTGVSyncEnd);
+ glintReg->glintRegs[VTGVGateStart >> 3] = GLINT_READ_REG(VTGVGateStart);
+ glintReg->glintRegs[VTGVGateEnd >> 3] = GLINT_READ_REG(VTGVGateEnd);
+ glintReg->glintRegs[VTGSerialClk >> 3] = GLINT_READ_REG(VTGSerialClk);
+ glintReg->glintRegs[FBModeSel >> 3] = GLINT_READ_REG(FBModeSel);
+ glintReg->glintRegs[VTGModeCtl >> 3] = GLINT_READ_REG(VTGModeCtl);
+ glintReg->glintRegs[VTGHGateStart >> 3] = GLINT_READ_REG(VTGHGateStart);
+ glintReg->glintRegs[VTGHGateEnd >> 3] = GLINT_READ_REG(VTGHGateEnd);
+}
+
+void
+TXRestore(ScrnInfoPtr pScrn, GLINTRegPtr glintReg)
+{
+ GLINTPtr pGlint = GLINTPTR(pScrn);
+
+#if 1
+ GLINT_SLOW_WRITE_REG(0, ResetStatus);
+ while(GLINT_READ_REG(ResetStatus) != 0) {
+ xf86MsgVerb(X_INFO, 2, "Resetting Engine - Please Wait.\n");
+ };
+#endif
+
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture0 >> 3], Aperture0);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[Aperture1 >> 3], Aperture1);
+
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[DFIFODis >> 3], DFIFODis);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[FIFODis >> 3], FIFODis);
+
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGPolarity >> 3], VTGPolarity);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VClkCtl >> 3], VClkCtl);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGSerialClk >> 3], VTGSerialClk);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGModeCtl >> 3], VTGModeCtl);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGHLimit >> 3], VTGHLimit);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGHSyncStart >> 3],VTGHSyncStart);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGHSyncEnd >> 3], VTGHSyncEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGHBlankEnd >> 3], VTGHBlankEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGVLimit >> 3], VTGVLimit);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGVSyncStart >> 3],VTGVSyncStart);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGVSyncEnd >> 3], VTGVSyncEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGVBlankEnd >> 3], VTGVBlankEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGVGateStart >> 3],VTGVGateStart);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGVGateEnd >> 3], VTGVGateEnd);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[FBModeSel >> 3], FBModeSel);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGHGateStart >> 3],VTGHGateStart);
+ GLINT_SLOW_WRITE_REG(glintReg->glintRegs[VTGHGateEnd >> 3], VTGHGateEnd);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i740/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/i740/Imakefile
new file mode 100644
index 000000000..48c466ce3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i740/Imakefile
@@ -0,0 +1,52 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i740/Imakefile,v 1.2 1999/08/30 01:25:03 dawes Exp $
+XCOMM
+XCOMM This is the Imakefile for the i740 driver.
+XCOMM
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = i740_driver.c i740_cursor.c i740_accel.c i740_io.c
+
+OBJS = i740_driver.o i740_cursor.o i740_accel.o i740_io.o
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(XF86SRC)/xaa -I$(XF86SRC)/rac \
+ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa -I$(XF86SRC)/ramdac \
+ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
+ -I$(SERVERSRC)/Xext \
+ -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(EXTINCSRC)
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget(i740,$(OBJS))
+
+InstallObjectModule(i740,$(MODULEDIR),drivers)
+
+XCOMM To install a man page remove the x and add these lines
+XCOMM xCppManTarget(i740,)
+XCOMM xInstallModuleManPage(i740)
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/i740)
+InstallDriverSDKNonExecFile(i740.h,$(DRIVERSDKDIR)/drivers/i740)
+InstallDriverSDKNonExecFile(i740_accel.c,$(DRIVERSDKDIR)/drivers/i740)
+InstallDriverSDKNonExecFile(i740_cursor.c,$(DRIVERSDKDIR)/drivers/i740)
+InstallDriverSDKNonExecFile(i740_driver.c,$(DRIVERSDKDIR)/drivers/i740)
+InstallDriverSDKNonExecFile(i740_io.c,$(DRIVERSDKDIR)/drivers/i740)
+InstallDriverSDKNonExecFile(i740_macros.h,$(DRIVERSDKDIR)/drivers/i740)
+InstallDriverSDKNonExecFile(i740_reg.h,$(DRIVERSDKDIR)/drivers/i740)
+
+InstallDriverSDKObjectModule(i740,$(DRIVERSDKMODULEDIR),drivers)
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i740/README b/xc/programs/Xserver/hw/xfree86/drivers/i740/README
new file mode 100644
index 000000000..33159398a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i740/README
@@ -0,0 +1,127 @@
+ Information for i740 Users
+ i740 Driver Version 3.0
+
+
+1. Supported Hardware
+
+ * Intel 740 based cards
+
+
+2. Features
+
+ * Full support for 8, 15, 16, 24 and 32 bit per pixel depths.
+ * Hardware cursor support to reduce sprite flicker.
+ * Hardware accelerated 2D drawing engine support for 8, 15, 16 and
+ 24 bit per pixel depths.
+ * Support for high resolution video modes up to 1600x1200.
+ * Support for doublescan video modes (e.g., 320x200 and 320x240).
+ * Support for gamma correction at all pixel depths.
+ * Fully programmable clock supported.
+ * Robust text mode restore for VT switching.
+
+
+3. Technical Notes
+
+ * Hardware acceleration is not possible in 32 bit per pixel depth.
+ * Interlace modes cannot be supported.
+
+
+4. Reported Working Video Cards
+
+ *** Currently support for PCI based cards is not working ***
+
+ * Real3D Starfighter AGP
+ * Real3D Starfighter PCI
+ * Diamond Stealth II/G460 AGP
+ * 3DVision-i740 AGP
+ * ABIT G740 8MB SDRAM
+ * Acorp AGP i740
+ * AGP 2D/3D V. 1N, AGP-740D
+ * AOpen AGP 2X 3D Navigator PA740
+ * ARISTO i740 AGP (ART-i740-G)
+ * ASUS AGP-V2740
+ * Atrend (Speedy) 3DIO740 AGP (ATC-2740)
+ * Chaintech AGP-740D
+ * EliteGroup(ECS) 3DVision-i740 AGP
+ * EONtronics Picasso 740
+ * EONtronics Van Gogh
+ * Everex MVGA i740/AG
+ * Flagpoint Shocker i740 8MB
+ * Gainward CardExpert 740 8MB
+ * Genoa Systems Phantom 740
+ * Gigabyte Predator i740 8MB AGP
+ * Hercules Terminator 128 2X/i AGP
+ * HOT-158 (Shuttle)
+ * Intel Express 3D AGP
+ * Jaton Video-740 AGP 3D
+ * Jetway J-740-3D 8MB AGP, i740 AGP 3D
+ * Joymedia Apollo 7400
+ * Leadtek Winfast S900
+ * Machspeed Raptor i740 AGP 4600
+ * Magic-Pro MP-740DVD
+ * MAXI Gamer AGP 8 MB
+ * Palit Daytona AGP740
+ * PowerColor C740 (SG/SD) AGP
+ * QDI Amazing I
+ * Soyo AGP (SY-740 AGP)
+ * Spacewalker Hot-158
+ * VideoExcel AGP 740
+ * ViewTop ZeusL 8MB
+ * Winfast S900 i740 AGP 8MB
+
+
+5. Configuration
+
+ The driver auto-detects all device information necessary to
+ initialize the card. The only lines you need in the "Device"
+ section of your XF86Config file are:
+
+ Section "Device"
+ Identifier "Intel i740"
+ Driver "i740"
+ EndSection
+
+ or let xf86config or XF86Setup do this for you.
+
+ However, if you have problems with auto-detection, you can specify:
+
+ VideoRam - in kilobytes
+ DacSpeed - in MHz
+ MemBase - physical address of the linear framebuffer
+ IOBase - physical address of the memory mapped IO registers
+
+
+6. Driver Options
+
+ The server automatically detects its configuration, so none of
+ these options should be required.
+
+ "NoAccel" - Turn off hardware acceleration
+ "SWCursor" - Request a software cursor (hardware is default)
+ "SDRAM" - Force the use of SDRAM timings
+ "SGRAM" - Force the use of SGRAM timings
+ "SlowRam" - Force the use of slower ram timings
+ "Dac6Bit" - Force the use of a 6 Bit Dac (8 Bit is the default)
+ "UsePIO - Force the use of programmed IO (Memory mapped is the default)
+
+7. Known Limitations
+
+ * Certain drawing operations are very slow when using 24 bit per
+ pixel depth mode.
+
+8. Author
+
+ Original version by Kevin E Martin <kevin@precisioninsight.com>
+
+ Daryll Strauss <daryll@precisioninsight.com>
+
+ Precision Insight, Inc.
+ Cedar Park, TX
+ USA
+
+ http://www.precisioninsight.com
+
+
+
+
+$XFree86: xc/programs/Xserver/hw/xfree86/drivers/i740/README,v 1.1 1999/08/29 12:20:57 dawes Exp $
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i740/i740.h b/xc/programs/Xserver/hw/xfree86/drivers/i740/i740.h
new file mode 100644
index 000000000..b0b1287b2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i740/i740.h
@@ -0,0 +1,141 @@
+
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i740/i740.h,v 1.1 1999/08/29 12:20:58 dawes Exp $ */
+
+/*
+ * Authors:
+ * Daryll Strauss <daryll@precisioninsight.com>
+ *
+ * $PI$
+ */
+
+#ifndef _I740_H_
+#define _I740_H_
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "i740_reg.h"
+#include "i740_macros.h"
+
+#include "xaa.h"
+#include "xf86Cursor.h"
+
+/* Globals */
+/* Memory mapped register access macros */
+#define INREG8(addr) *(volatile CARD8 *)(pI740->MMIOBase + (addr))
+#define INREG16(addr) *(volatile CARD16 *)(pI740->MMIOBase + (addr))
+#define INREG(addr) *(volatile CARD32 *)(pI740->MMIOBase + (addr))
+#define OUTREG8(addr, val) *(volatile CARD8 *)(pI740->MMIOBase + (addr)) = (val)
+#define OUTREG16(addr, val) *(volatile CARD16 *)(pI740->MMIOBase + (addr)) = (val)
+#define OUTREG(addr, val) *(volatile CARD32 *)(pI740->MMIOBase + (addr)) = (val)
+
+typedef struct _I740Rec *I740Ptr;
+
+typedef void (*I740WriteIndexedByteFunc)(I740Ptr pI740, int addr,
+ char index, char value);
+typedef char (*I740ReadIndexedByteFunc)(I740Ptr pI740, int addr,
+ char index);
+typedef void (*I740WriteByteFunc)(I740Ptr pI740, int addr, char value);
+typedef char (*I740ReadByteFunc)(I740Ptr pI740, int addr);
+
+typedef struct {
+ unsigned char DisplayControl;
+ unsigned char PixelPipeCfg0;
+ unsigned char PixelPipeCfg1;
+ unsigned char PixelPipeCfg2;
+ unsigned char VideoClk2_M;
+ unsigned char VideoClk2_N;
+ unsigned char VideoClk2_MN_MSBs;
+ unsigned char VideoClk2_DivisorSel;
+ unsigned char PLLControl;
+ unsigned char AddressMapping;
+ unsigned char IOControl;
+ unsigned char BitBLTControl;
+ unsigned char ExtVertTotal;
+ unsigned char ExtVertDispEnd;
+ unsigned char ExtVertSyncStart;
+ unsigned char ExtVertBlankStart;
+ unsigned char ExtHorizTotal;
+ unsigned char ExtHorizBlank;
+ unsigned char ExtOffset;
+ unsigned char InterlaceControl;
+ unsigned int LMI_FIFO_Watermark;
+} I740RegRec, *I740RegPtr;
+
+typedef struct _I740Rec {
+ unsigned char *MMIOBase;
+ unsigned char *FbBase;
+ long FbMapSize;
+ int cpp;
+ int MaxClock;
+ int CursorStart;
+ int Chipset;
+ int LinearAddr;
+ int MMIOAddr;
+ EntityInfoPtr pEnt;
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ int HasSGRAM;
+ I740RegRec SavedReg;
+ I740RegRec ModeReg;
+ XAAInfoRecPtr AccelInfoRec;
+ xf86CursorInfoPtr CursorInfoRec;
+ FBAreaPtr CursorData;
+ CloseScreenProcPtr CloseScreen;
+ GFX2DOPREG_BLTER_FULL_LOAD bltcmd;
+ Bool usePIO;
+ I740WriteIndexedByteFunc writeControl;
+ I740ReadIndexedByteFunc readControl;
+ I740WriteByteFunc writeStandard;
+ I740ReadByteFunc readStandard;
+} I740Rec;
+
+#define I740PTR(p) ((I740Ptr)((p)->driverPrivate))
+
+extern Bool I740CursorInit(ScreenPtr pScreen);
+extern Bool I740AccelInit(ScreenPtr pScreen);
+void I740SetPIOAccess(I740Ptr pI740);
+void I740SetMMIOAccess(I740Ptr pI740);
+
+#ifndef __alpha__
+#define minb(p) *(volatile CARD8 *)(pI740->MMIOBase + (p))
+#define moutb(p,v) \
+ *(volatile CARD8 *)(pI740->MMIOBase + (p)) = (v)
+#else
+#define minb(p) xf86ReadSparse8(pI740->MMIOBase, (p))
+#define moutb(p,v) \
+ xf86WriteSparse8((v), pI740->MMIOBase, (p))
+#endif
+
+#endif
+
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_accel.c
new file mode 100644
index 000000000..a10860688
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_accel.c
@@ -0,0 +1,397 @@
+
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i740/i740_accel.c,v 1.1 1999/08/29 12:20:58 dawes Exp $ */
+
+/*
+ * Authors:
+ * Daryll Strauss <daryll@precisioninsight.com>
+ *
+ * $PI$
+ */
+
+#include <math.h>
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "compiler.h"
+
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+#include "xaa.h"
+
+#include "i740.h"
+
+static unsigned int i740Rop[16] = {
+ 0x00, /* GXclear */
+ 0x88, /* GXand */
+ 0x44, /* GXandReverse */
+ 0xCC, /* GXcopy */
+ 0x22, /* GXandInvert */
+ 0xAA, /* GXnoop */
+ 0x66, /* GXxor */
+ 0xEE, /* GXor */
+ 0x11, /* GXnor */
+ 0x99, /* GXequiv */
+ 0x55, /* GXinvert */
+ 0xDD, /* GXorReverse */
+ 0x33, /* GXcopyInvert */
+ 0xBB, /* GXorInverted */
+ 0x77, /* GXnand */
+ 0xFF /* GXset */
+};
+
+static unsigned int i740PatternRop[16] = {
+ 0x00, /* GXclear */
+ 0xA0, /* GXand */
+ 0x50, /* GXandReverse */
+ 0xF0, /* GXcopy */
+ 0x0A, /* GXandInvert */
+ 0xAA, /* GXnoop */
+ 0x5A, /* GXxor */
+ 0xFA, /* GXor */
+ 0x05, /* GXnor */
+ 0xA5, /* GXequiv */
+ 0x55, /* GXinvert */
+ 0xF5, /* GXorReverse */
+ 0x0F, /* GXcopyInvert */
+ 0xAF, /* GXorInverted */
+ 0x5F, /* GXnand */
+ 0xFF /* GXset */
+};
+
+static void I740SyncPIO(ScrnInfoPtr pScrn);
+static void I740SyncMMIO(ScrnInfoPtr pScrn);
+static void I740SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+static void I740SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h);
+static void I740SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
+ int ydir, int rop,
+ unsigned int planemask,
+ int transparency_color);
+static void I740SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h);
+static void I740SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int pattx, int patty,
+ int bg, int fg, int rop,
+ unsigned int planemask);
+static void I740SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int pattx, int patty,
+ int x, int y, int w, int h);
+static void I740SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int bg, int fg, int rop,
+ unsigned int planemask);
+static void I740SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft);
+
+/*
+ * The following function sets up the supported acceleration. Call it
+ * from the FbInit() function in the SVGA driver, or before ScreenInit
+ * in a monolithic server.
+ */
+Bool
+I740AccelInit(ScreenPtr pScreen) {
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ I740Ptr pI740 = I740PTR(pScrn);
+
+ pI740->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ if (pScrn->bitsPerPixel == 32) {
+ infoPtr->Flags = 0; /* Disables all acceleration */
+ return TRUE;;
+ }
+
+ infoPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER;
+
+ /* Sync */
+ if (pI740->usePIO)
+ infoPtr->Sync = I740SyncPIO;
+ else
+ infoPtr->Sync = I740SyncMMIO;
+
+ infoPtr->CachePixelGranularity=8/pI740->cpp;
+
+ /* Solid filled rectangles */
+ infoPtr->PolyFillRectSolidFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill = I740SetupForSolidFill;
+ infoPtr->SubsequentSolidFillRect = I740SubsequentSolidFillRect;
+
+ /* Screen to screen copy */
+ infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK;
+ if (pScrn->bitsPerPixel == 24) {
+ infoPtr->ScreenToScreenCopyFlags |= NO_TRANSPARENCY;
+ }
+ infoPtr->SetupForScreenToScreenCopy = I740SetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy = I740SubsequentScreenToScreenCopy;
+
+ /* 8x8 pattern fills */
+ infoPtr->SetupForMono8x8PatternFill = I740SetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect = I740SubsequentMono8x8PatternFillRect;
+ infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_SCREEN_ORIGIN |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ /* CPU to screen color expansion */
+#ifndef ALLOW_PCI_COLOR_EXP
+ if (pI740->Chipset != PCI_CHIP_I740_PCI) {
+#endif
+ /*
+ * Currently, we are not properly able to read the bitblt engine
+ * busy bit on the PCI i740 card. When we are able to do so, we
+ * can re-enable color expansion.
+ */
+ infoPtr->CPUToScreenColorExpandFillFlags =
+#ifdef USE_DWORD_COLOR_EXP
+ SCANLINE_PAD_DWORD |
+#endif
+ CPU_TRANSFER_PAD_QWORD |
+ SYNC_AFTER_COLOR_EXPAND |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+ infoPtr->ColorExpandBase = (unsigned char *)(pI740->MMIOBase + BLTDATA);
+ infoPtr->ColorExpandRange = 0x10000;
+ infoPtr->SetupForCPUToScreenColorExpandFill = I740SetupForCPUToScreenColorExpandFill;
+ infoPtr->SubsequentCPUToScreenColorExpandFill = I740SubsequentCPUToScreenColorExpandFill;
+#ifndef ALLOW_PCI_COLOR_EXP
+ }
+#endif
+
+ return XAAInit(pScreen, infoPtr);
+}
+
+static void
+I740SyncPIO(ScrnInfoPtr pScrn) {
+ WAIT_ENGINE_IDLE_PIO();
+}
+
+static void
+I740SyncMMIO(ScrnInfoPtr pScrn) {
+ I740Ptr pI740;
+
+ pI740 = I740PTR(pScrn);
+ WAIT_ENGINE_IDLE_MMIO();
+}
+
+static void
+I740SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask) {
+ I740Ptr pI740;
+
+ pI740 = I740PTR(pScrn);
+
+ pI740->bltcmd.BR00 = ((pScrn->displayWidth * pI740->cpp) << 16) |
+ (pScrn->displayWidth * pI740->cpp);
+ pI740->bltcmd.BR01 = color;
+ pI740->bltcmd.BR04 = SOLID_PAT_SELECT | PAT_IS_MONO | i740PatternRop[rop];
+}
+
+static void
+I740SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) {
+ I740Ptr pI740;
+
+ pI740 = I740PTR(pScrn);
+ WAIT_LP_FIFO(12);
+ OUTREG(LP_FIFO, 0x6000000A);
+ OUTREG(LP_FIFO, pI740->bltcmd.BR00);
+ OUTREG(LP_FIFO, pI740->bltcmd.BR01);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, pI740->bltcmd.BR04);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, (y * pScrn->displayWidth + x) * pI740->cpp);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, (h << 16) | (w * pI740->cpp));
+}
+
+static void
+I740SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
+ unsigned int planemask, int transparency_color)
+{
+ I740Ptr pI740;
+
+ pI740 = I740PTR(pScrn);
+ pI740->bltcmd.BR00 = (((pScrn->displayWidth * pI740->cpp) << 16) |
+ (pScrn->displayWidth * pI740->cpp));
+
+ pI740->bltcmd.BR04 = SRC_IS_IN_COLOR | SRC_USE_SRC_ADDR | i740Rop[rop];
+ if (xdir == -1)
+ pI740->bltcmd.BR04 |= BLT_RIGHT_TO_LEFT;
+ else
+ pI740->bltcmd.BR04 |= BLT_LEFT_TO_RIGHT;
+
+ if (ydir == -1)
+ pI740->bltcmd.BR04 |= BLT_BOT_TO_TOP;
+ else
+ pI740->bltcmd.BR04 |= BLT_TOP_TO_BOT;
+
+ if (transparency_color != -1) {
+ pI740->bltcmd.BR01 = transparency_color;
+ pI740->bltcmd.BR04 |= (COLOR_TRANSP_ENABLE |
+ COLOR_TRANSP_ROP |
+ COLOR_TRANSP_EQ);
+ } else {
+ pI740->bltcmd.BR01 = 0x00000000;
+ }
+}
+
+static void
+I740SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h) {
+ I740Ptr pI740;
+
+ pI740 = I740PTR(pScrn);
+ if (pI740->bltcmd.BR04 & BLT_BOT_TO_TOP) {
+ pI740->bltcmd.BR06 = (y1 + h - 1) *
+ pScrn->displayWidth * pI740->cpp;
+ pI740->bltcmd.BR07 = (y2 + h - 1) *
+ pScrn->displayWidth * pI740->cpp;
+ } else {
+ pI740->bltcmd.BR06 = y1 * pScrn->displayWidth * pI740->cpp;
+ pI740->bltcmd.BR07 = y2 * pScrn->displayWidth * pI740->cpp;
+ }
+
+ if (pI740->bltcmd.BR04 & BLT_RIGHT_TO_LEFT) {
+ pI740->bltcmd.BR06 += (x1 + w - 1) * pI740->cpp + pI740->cpp - 1;
+ pI740->bltcmd.BR07 += (x2 + w - 1) * pI740->cpp + pI740->cpp - 1;
+ } else {
+ pI740->bltcmd.BR06 += x1 * pI740->cpp;
+ pI740->bltcmd.BR07 += x2 * pI740->cpp;
+ }
+
+ WAIT_LP_FIFO(12);
+ OUTREG(LP_FIFO, 0x6000000A);
+ OUTREG(LP_FIFO, pI740->bltcmd.BR00);
+ OUTREG(LP_FIFO, pI740->bltcmd.BR01);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, pI740->bltcmd.BR04);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, pI740->bltcmd.BR06);
+ OUTREG(LP_FIFO, pI740->bltcmd.BR07);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, (h << 16) | (w * pI740->cpp));
+}
+
+static void
+I740SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty,
+ int bg, int fg, int rop,
+ unsigned int planemask) {
+ I740Ptr pI740;
+
+ pI740 = I740PTR(pScrn);
+ pI740->bltcmd.BR00 = ((pScrn->displayWidth * pI740->cpp) << 16) |
+ (pScrn->displayWidth * pI740->cpp);
+
+ pI740->bltcmd.BR01 = bg;
+ pI740->bltcmd.BR02 = fg;
+
+ pI740->bltcmd.BR04 = PAT_IS_MONO | i740PatternRop[rop];
+ if (bg == -1) pI740->bltcmd.BR04 |= MONO_PAT_TRANSP;
+
+ pI740->bltcmd.BR05 = (pattx + patty * pScrn->displayWidth) * pI740->cpp;
+}
+
+static void
+I740SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty,
+ int x, int y, int w, int h) {
+ I740Ptr pI740;
+
+ pI740 = I740PTR(pScrn);
+ WAIT_LP_FIFO(12);
+ OUTREG(LP_FIFO, 0x6000000A);
+ OUTREG(LP_FIFO, pI740->bltcmd.BR00);
+ OUTREG(LP_FIFO, pI740->bltcmd.BR01);
+ OUTREG(LP_FIFO, pI740->bltcmd.BR02);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, pI740->bltcmd.BR04 | ((y<<20) & PAT_VERT_ALIGN));
+ OUTREG(LP_FIFO, pI740->bltcmd.BR05);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, (y * pScrn->displayWidth + x) * pI740->cpp);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, (h << 16) | (w * pI740->cpp));
+}
+
+static void
+I740SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int bg, int fg,
+ int rop, unsigned int planemask) {
+ I740Ptr pI740;
+
+ pI740 = I740PTR(pScrn);
+ pI740->bltcmd.BR00 = (pScrn->displayWidth * pI740->cpp) << 16;
+ pI740->bltcmd.BR01 = bg;
+ pI740->bltcmd.BR02 = fg;
+#ifdef USE_DWORD_COLOR_EXP
+ pI740->bltcmd.BR03 = MONO_DWORD_ALIGN | MONO_USE_COLEXP;
+#else
+ pI740->bltcmd.BR03 = MONO_BIT_ALIGN | MONO_USE_COLEXP;
+#endif
+ pI740->bltcmd.BR04 = SRC_IS_MONO | SRC_USE_BLTDATA | i740Rop[rop];
+ if (bg == -1) pI740->bltcmd.BR04 |= MONO_SRC_TRANSP;
+}
+
+static void
+I740SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h, int skipleft) {
+ I740Ptr pI740;
+
+ pI740 = I740PTR(pScrn);
+ pI740->AccelInfoRec->Sync(pScrn);
+ OUTREG(LP_FIFO, 0x6000000A);
+ OUTREG(LP_FIFO, pI740->bltcmd.BR00);
+ OUTREG(LP_FIFO, pI740->bltcmd.BR01);
+ OUTREG(LP_FIFO, pI740->bltcmd.BR02);
+ OUTREG(LP_FIFO, pI740->bltcmd.BR03 | (skipleft & MONO_SRC_LEFT_CLIP));
+ OUTREG(LP_FIFO, pI740->bltcmd.BR04);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, (y * pScrn->displayWidth + x) * pI740->cpp);
+ OUTREG(LP_FIFO, 0x00000000);
+ OUTREG(LP_FIFO, 0x00000000);
+#ifdef USE_DWORD_COLOR_EXP
+ /*
+ * This extra wait is necessary to keep the bitblt engine from
+ * locking up, but I am not sure why it is needed. If we take it
+ * out, "x11perf -copyplane10" will lock the bitblt engine. When
+ * the bitblt engine is locked, it is waiting for mono data to be
+ * written to the BLTDATA region, which seems to imply that some of
+ * the data that was written was lost. This might be fixed by
+ * BLT_SKEW changes. Update: The engine still locks up with this
+ * extra wait. More investigation (and time) is needed.
+ */
+ WAIT_BLT_IDLE();
+#endif
+ OUTREG(LP_FIFO, (h << 16) | (w * pI740->cpp));
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_cursor.c
new file mode 100644
index 000000000..d469a924c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_cursor.c
@@ -0,0 +1,205 @@
+
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i740/i740_cursor.c,v 1.1 1999/08/29 12:20:58 dawes Exp $ */
+
+/*
+ * Authors:
+ * Daryll Strauss <daryll@precisioninsight.com>
+ *
+ * $PI$
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+#include "xf86fbman.h"
+
+#include "i740.h"
+
+static void I740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
+static void I740ShowCursor(ScrnInfoPtr pScrn);
+static void I740HideCursor(ScrnInfoPtr pScrn);
+static void I740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
+static void I740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fb);
+static Bool I740UseHWCursor(ScreenPtr pScrn, CursorPtr pCurs);
+
+Bool
+I740CursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn;
+ I740Ptr pI740;
+ xf86CursorInfoPtr infoPtr;
+ FBAreaPtr fbarea;
+
+ pScrn = xf86Screens[pScreen->myNum];
+ pI740 = I740PTR(pScrn);
+ pI740->CursorInfoRec = infoPtr = xf86CreateCursorInfoRec();
+ if (!infoPtr) return FALSE;
+
+ infoPtr->MaxWidth = 64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_INVERT_MASK |
+ HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
+ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64;
+
+ infoPtr->SetCursorColors = I740SetCursorColors;
+ infoPtr->SetCursorPosition = I740SetCursorPosition;
+ infoPtr->LoadCursorImage = I740LoadCursorImage;
+ infoPtr->HideCursor = I740HideCursor;
+ infoPtr->ShowCursor = I740ShowCursor;
+ infoPtr->UseHWCursor = I740UseHWCursor;
+
+ fbarea = xf86AllocateOffscreenArea(pScreen,
+ (1024+pI740->cpp-1)/pI740->cpp,
+ (1024+pScrn->displayWidth*pI740->cpp-1) /
+ (pScrn->displayWidth*pI740->cpp),
+ 4096, 0, 0, 0);
+ pI740->CursorStart = (fbarea->box.x1 + pScrn->displayWidth * fbarea->box.y1)
+ * pI740->cpp;
+
+ if (pI740->CursorStart>4*1024*1024) {
+ pI740->CursorStart=0;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling hardware cursor due to large framebuffer\n");
+ }
+ return xf86InitCursor(pScreen, infoPtr);
+}
+
+static Bool
+I740UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) {
+ ScrnInfoPtr pScrn;
+ I740Ptr pI740;
+
+ pScrn = xf86Screens[pScreen->myNum];
+ pI740 = I740PTR(pScrn);
+ if (pScrn->currentMode->Flags&V_DBLSCAN)
+ return FALSE;
+ if (!pI740->CursorStart) return FALSE;
+ return TRUE;
+}
+
+static void
+I740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) {
+ I740Ptr pI740;
+ int x, y;
+ CARD8 *pcurs;
+
+ pI740 = I740PTR(pScrn);
+ pcurs = (CARD8 *)(pI740->FbBase + pI740->CursorStart);
+ for (y = 0; y < 64; y++) {
+ for (x = 0; x < 64 / 4; x++) {
+ *pcurs++ = *src++;
+ }
+ }
+}
+
+static void
+I740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) {
+ I740Ptr pI740;
+ int flag;
+
+ pI740 = I740PTR(pScrn);
+ if (x >= 0) flag = CURSOR_X_POS;
+ else {
+ flag = CURSOR_X_NEG;
+ x=-x;
+ }
+ pI740->writeControl(pI740, XRX, CURSOR_X_LO, x&0xFF);
+ pI740->writeControl(pI740, XRX, CURSOR_X_HI, (((x >> 8) & 0x07) | flag));
+
+ if (y >= 0) flag = CURSOR_Y_POS;
+ else {
+ flag = CURSOR_Y_NEG;
+ y=-y;
+ }
+ pI740->writeControl(pI740, XRX, CURSOR_Y_LO, y&0xFF);
+ pI740->writeControl(pI740, XRX, CURSOR_Y_HI, (((y >> 8) & 0x07) | CURSOR_Y_POS));
+}
+
+static void
+I740ShowCursor(ScrnInfoPtr pScrn) {
+ I740Ptr pI740;
+ unsigned char tmp;
+
+ pI740 = I740PTR(pScrn);
+ pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_LO,
+ (pI740->CursorStart & 0x0000F000) >> 8);
+ pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_HI,
+ (pI740->CursorStart & 0x003F0000) >> 16);
+ pI740->writeControl(pI740, XRX, CURSOR_CONTROL,
+ CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C);
+
+ tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
+ tmp |= HW_CURSOR_ENABLE;
+ pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
+}
+
+static void
+I740HideCursor(ScrnInfoPtr pScrn) {
+ unsigned char tmp;
+ I740Ptr pI740;
+
+ pI740 = I740PTR(pScrn);
+ tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
+ tmp &= ~HW_CURSOR_ENABLE;
+ pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
+}
+
+static void
+I740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) {
+ int tmp;
+ I740Ptr pI740;
+
+ pI740 = I740PTR(pScrn);
+ tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
+ tmp |= EXTENDED_PALETTE;
+ pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
+
+ pI740->writeStandard(pI740, DACMASK, 0xFF);
+ pI740->writeStandard(pI740, DACWX, 0x04);
+
+ pI740->writeStandard(pI740, DACDATA, (bg & 0x00FF0000) >> 16);
+ pI740->writeStandard(pI740, DACDATA, (bg & 0x0000FF00) >> 8);
+ pI740->writeStandard(pI740, DACDATA, (bg & 0x000000FF));
+
+ pI740->writeStandard(pI740, DACDATA, (fg & 0x00FF0000) >> 16);
+ pI740->writeStandard(pI740, DACDATA, (fg & 0x0000FF00) >> 8);
+ pI740->writeStandard(pI740, DACDATA, (fg & 0x000000FF));
+
+ tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
+ tmp &= ~EXTENDED_PALETTE;
+ pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp);
+}
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_driver.c
new file mode 100644
index 000000000..218decd41
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_driver.c
@@ -0,0 +1,1713 @@
+
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i740/i740_driver.c,v 1.2 1999/08/29 12:42:56 dawes Exp $ */
+
+/*
+ * Authors:
+ * Daryll Strauss <daryll@precisioninsight.com>
+ *
+ * $PI$
+ */
+
+/*
+ * This server does not support these XFree86 4.0 features yet
+ * DDC1 & DDC2 (requires I2C)
+ * shadowFb (if requested or acceleration is off)
+ * Overlay planes
+ * DGA
+ */
+
+/*
+ * These are X and server generic header files.
+ */
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86RAC.h"
+#include "xf86cmap.h"
+
+/* If the driver uses port I/O directly, it needs: */
+
+#include "compiler.h"
+
+/* Drivers using the mi implementation of backing store need: */
+
+#include "mibstore.h"
+
+/* All drivers using the vgahw module need this */
+/* This driver needs to be modified to not use vgaHW for multihead operation */
+#include "vgaHW.h"
+
+/* Drivers using the mi SW cursor need: */
+
+#include "mipointer.h"
+
+/* Drivers using the mi colourmap code need: */
+
+#include "micmap.h"
+
+/* Drivers using cfb need: */
+
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+
+/* Drivers supporting bpp 16, 24 or 32 with cfb need one or more of: */
+
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+
+/* The driver's own header file: */
+
+#include "i740.h"
+
+#include "miscstruct.h"
+
+#include "xf86xv.h"
+#include "Xv.h"
+
+/* Required Functions: */
+
+/* Print a driver identifying message. */
+static void I740Identify(int flags);
+
+/* Identify if there is any hardware present that I know how to drive. */
+static Bool I740Probe(DriverPtr drv, int flags);
+
+/* Process the config file and see if we have a valid configuration */
+static Bool I740PreInit(ScrnInfoPtr pScrn, int flags);
+
+/* Initialize a screen */
+static Bool I740ScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv);
+
+/* Enter from a virtual terminal */
+static Bool I740EnterVT(int scrnIndex, int flags);
+
+/* Leave to a virtual terminal */
+static void I740LeaveVT(int scrnIndex, int flags);
+
+/* Close down each screen we initialized */
+static Bool I740CloseScreen(int scrnIndex, ScreenPtr pScreen);
+
+/* Change screensaver state */
+static Bool I740SaveScreen(ScreenPtr pScreen, Bool unblank);
+
+/* Allow mode switching */
+static Bool I740SwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+/* Allow moving the viewport */
+static void I740AdjustFrame(int scrnIndex, int x, int y, int flags);
+
+/* Cleanup server private data */
+static void I740FreeScreen(int scrnIndex, int flags);
+
+/* Check if a mode is valid on the hardware */
+static int I740ValidMode(int scrnIndex, DisplayModePtr mode, Bool
+ verbose, int flags);
+
+#ifdef DPMSExtension
+/* Switch to various Display Power Management System levels */
+static void I740DisplayPowerManagementSet(ScrnInfoPtr pScrn,
+ int PowerManagermentMode, int flags);
+#endif
+
+#define VERSION 4000
+#define I740_NAME "I740"
+#define I740_DRIVER_NAME "i740"
+#define I740_MAJOR_VERSION 1
+#define I740_MINOR_VERSION 0
+#define I740_PATCHLEVEL 0
+
+DriverRec I740 = {
+ VERSION,
+ "Accelerated driver for Intel i740 cards",
+ I740Identify,
+ I740Probe,
+ NULL,
+ 0
+};
+
+/* Chipsets */
+static SymTabRec I740Chipsets[] = {
+ { PCI_CHIP_I740_AGP, "i740 (agp)"},
+ { PCI_CHIP_I740_PCI, "i740 (pci)"},
+ { -1, NULL }
+};
+
+static PciChipsets I740PciChipsets[] = {
+ { PCI_CHIP_I740_AGP, PCI_CHIP_I740_AGP, RES_SHARED_VGA },
+ { PCI_CHIP_I740_PCI, PCI_CHIP_I740_PCI, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED }
+};
+
+typedef enum {
+ OPTION_NOACCEL,
+ OPTION_SW_CURSOR,
+ OPTION_SDRAM,
+ OPTION_SGRAM,
+ OPTION_SLOW_RAM,
+ OPTION_DAC_6BIT,
+ OPTION_USE_PIO
+} I740Opts;
+
+static OptionInfoRec I740Options[] = {
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SDRAM, "SDRAM", OPTV_BOOLEAN, {0}, FALSE},
+ { OPTION_SGRAM, "SGRAM", OPTV_BOOLEAN, {0}, FALSE},
+ { OPTION_SLOW_RAM, "SlowRam", OPTV_BOOLEAN, {0}, FALSE},
+ { OPTION_DAC_6BIT, "Dac6Bit", OPTV_BOOLEAN, {0}, FALSE},
+ { OPTION_USE_PIO, "UsePIO", OPTV_BOOLEAN, {0}, FALSE},
+ { -1, NULL, OPTV_NONE, {0}, FALSE}
+};
+
+static const char *vgahwSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWSave", /* Added */
+ "vgaHWRestore", /* Added */
+ "vgaHWProtect",
+ "vgaHWInit",
+ "vgaHWMapMem",
+ "vgaHWSetMmioFuncs",
+ "vgaHWGetIOBase",
+ "vgaHWLock",
+ "vgaHWUnlock",
+ "vgaHWFreeHWRec",
+ "vgaHWSaveScreen",
+ "vgaHWHandleColormaps",
+ 0
+};
+
+static const char *cfbSymbols[] = {
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb24ScreenInit",
+ "cfb32ScreenInit",
+ "cfb8_32ScreenInit",
+ "cfb24_32ScreenInit",
+ NULL
+};
+
+static const char *xf8_32bppSymbols[] = {
+ "xf86Overlay8Plus32Init",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAADestroyInfoRec",
+ "XAACreateInfoRec",
+ "XAAInit",
+ "XAAStippleScanlineFuncLSBFirst",
+ "XAAOverlayFBfuncs",
+ "XAACachePlanarMonoStipple",
+ "XAAScreenIndex",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86InitCursor",
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ NULL
+};
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(i740Setup);
+
+static XF86ModuleVersionInfo i740VersRec =
+{
+ "i740",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ I740_MAJOR_VERSION, I740_MINOR_VERSION, I740_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+XF86ModuleData i740ModuleData = {&i740VersRec, i740Setup, 0};
+
+static pointer
+i740Setup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ /* This module should be loaded only once, but check to be sure. */
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&I740, module, 0);
+
+ /*
+ * Modules that this driver always requires may be loaded here
+ * by calling LoadSubModule().
+ */
+
+ /*
+ * Tell the loader about symbols from other modules that this module
+ * might refer to.
+ */
+ LoaderRefSymLists(vgahwSymbols, cfbSymbols, xaaSymbols,
+ xf8_32bppSymbols, ramdacSymbols,
+ 0 /* ddcsymbols */, 0 /* i2csymbols */, 0 /* shadowSymbols */,
+ 0 /* fbdevsymbols */, NULL);
+
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer)1;
+ } else {
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+#endif
+
+/*
+ * I740GetRec and I740FreeRec --
+ *
+ * Private data for the driver is stored in the screen structure.
+ * These two functions create and destroy that private data.
+ *
+ */
+static Bool
+I740GetRec(ScrnInfoPtr pScrn) {
+ if (pScrn->driverPrivate) return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(I740Rec), 1);
+ return TRUE;
+}
+
+static void
+I740FreeRec(ScrnInfoPtr pScrn) {
+ if (!pScrn) return;
+ if (!pScrn->driverPrivate) return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate=0;
+}
+
+/*
+ * I740Identify --
+ *
+ * Returns the string name for the driver based on the chipset. In this
+ * case it will always be an I740, so we can return a static string.
+ *
+ */
+static void
+I740Identify(int flags) {
+ xf86PrintChipsets(I740_NAME, "Driver for Intel i740 chipset", I740Chipsets);
+}
+
+/*
+ * I740Probe --
+ *
+ * Look through the PCI bus to find cards that are I740 boards.
+ * Setup the dispatch table for the rest of the driver functions.
+ *
+ */
+static Bool
+I740Probe(DriverPtr drv, int flags) {
+ int i, numUsed, numDevSections, *usedChips;
+ GDevPtr *devSections;
+ Bool foundScreen = FALSE;
+ EntityInfoPtr pEnt;
+
+ /*
+ Find the config file Device sections that match this
+ driver, and return if there are none.
+ */
+ if ((numDevSections = xf86MatchDevice(I740_DRIVER_NAME, &devSections))<=0) {
+ return FALSE;
+ }
+
+ /*
+ Since these Probing is just checking the PCI data the server already
+ collected.
+ */
+ if (!xf86GetPciVideoInfo()) return FALSE;
+
+ /* Look for Intel based chips */
+ numUsed = xf86MatchPciInstances(I740_NAME, PCI_VENDOR_INTEL,
+ I740Chipsets, I740PciChipsets,
+ devSections, numDevSections,
+ drv, &usedChips);
+
+ for (i=0; i<numUsed; i++) {
+ pEnt = xf86GetEntityInfo(usedChips[i]);
+
+ if (pEnt->active) {
+ ScrnInfoPtr pScrn;
+
+ /* Allocate new ScrnInfoRec and claim the slot */
+ pScrn = xf86AllocateScreen(drv, 0);
+
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = I740_DRIVER_NAME;
+ pScrn->name = I740_NAME;
+ pScrn->Probe = I740Probe;
+ pScrn->PreInit = I740PreInit;
+ pScrn->ScreenInit = I740ScreenInit;
+ pScrn->SwitchMode = I740SwitchMode;
+ pScrn->AdjustFrame = I740AdjustFrame;
+ pScrn->EnterVT = I740EnterVT;
+ pScrn->LeaveVT = I740LeaveVT;
+ pScrn->FreeScreen = I740FreeScreen;
+ pScrn->ValidMode = I740ValidMode;
+ foundScreen = TRUE;
+
+ xf86ConfigActivePciEntity(pScrn, usedChips[i], I740PciChipsets, 0, 0, 0, 0, 0);
+ }
+ xfree(pEnt);
+ }
+ if (numUsed) xfree(usedChips);
+
+ /* Look for Real3D based chips */
+ numUsed = xf86MatchPciInstances(I740_NAME, PCI_VENDOR_REAL3D,
+ I740Chipsets, I740PciChipsets,
+ devSections, numDevSections,
+ drv, &usedChips);
+
+ for (i=0; i<numUsed; i++) {
+ pEnt = xf86GetEntityInfo(usedChips[i]);
+
+ if (pEnt->active) {
+ ScrnInfoPtr pScrn;
+
+ /* Allocate new ScrnInfoRec and claim the slot */
+ pScrn = xf86AllocateScreen(drv, 0);
+
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = I740_DRIVER_NAME;
+ pScrn->name = I740_NAME;
+ pScrn->Probe = I740Probe;
+ pScrn->PreInit = I740PreInit;
+ pScrn->ScreenInit = I740ScreenInit;
+ pScrn->SwitchMode = I740SwitchMode;
+ pScrn->AdjustFrame = I740AdjustFrame;
+ pScrn->EnterVT = I740EnterVT;
+ pScrn->LeaveVT = I740LeaveVT;
+ pScrn->FreeScreen = I740FreeScreen;
+ pScrn->ValidMode = I740ValidMode;
+ foundScreen = TRUE;
+
+ xf86ConfigActivePciEntity(pScrn, usedChips[i], I740PciChipsets, 0, 0, 0, 0, 0);
+ }
+ xfree(pEnt);
+ }
+ if (numUsed) xfree(usedChips);
+
+ xfree(devSections);
+
+ return foundScreen;
+}
+
+/*
+ * I740PreInit --
+ *
+ * Do initial setup of the board before we know what resolution we will
+ * be running at.
+ *
+ */
+static Bool
+I740PreInit(ScrnInfoPtr pScrn, int flags) {
+ vgaHWPtr hwp;
+ I740Ptr pI740;
+ ClockRangePtr clockRanges;
+ int i;
+ MessageType from;
+ int temp;
+ char *mod=0, *reqSym=0;
+ int flags24;
+ rgb defaultWeight = {0, 0, 0};
+
+ if (pScrn->numEntities != 1) return FALSE;
+
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw")) return FALSE;
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /* Allocate a vgaHWRec */
+ if (!vgaHWGetHWRec(pScrn)) return FALSE;
+
+ /* Allocate driverPrivate */
+ if (!I740GetRec(pScrn)) {
+ return FALSE;
+ }
+
+ pI740 = I740PTR(pScrn);
+
+ pI740->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pI740->pEnt->location.type != BUS_PCI) return FALSE;
+
+ pI740->PciInfo = xf86GetPciInfoForEntity(pI740->pEnt->index);
+ pI740->PciTag = pciTag(pI740->PciInfo->bus, pI740->PciInfo->device,
+ pI740->PciInfo->func);
+
+ if (xf86RegisterResources(pI740->pEnt->index, 0, ResNone))
+ return FALSE;
+ if (pI740->usePIO)
+ pScrn->racIoFlags = RAC_FB | RAC_COLORMAP;
+ else
+ pScrn->racMemFlags = RAC_FB | RAC_COLORMAP;
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ flags24=Support24bppFb | Support32bppFb | SupportConvert32to24;
+ if (!xf86SetDepthBpp(pScrn, 8, 8, 8, flags24)) {
+ return FALSE;
+ } else {
+ switch (pScrn->depth) {
+ case 8:
+ case 16:
+ case 24:
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by i740 driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+ xf86PrintDepthBpp(pScrn);
+
+ pScrn->rgbBits=8;
+ if (xf86ReturnOptValBool(I740Options, OPTION_DAC_6BIT, FALSE))
+ pScrn->rgbBits=6;
+ if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight))
+ return FALSE;
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /* We use a programamble clock */
+ pScrn->progClock = TRUE;
+
+ hwp = VGAHWPTR(pScrn);
+ pI740->cpp = pScrn->bitsPerPixel/8;
+
+ /* Process the options */
+ xf86CollectOptions(pScrn, NULL);
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, I740Options);
+
+ /* 6-BIT dac isn't reasonable for modes with > 8bpp */
+ if (xf86ReturnOptValBool(I740Options, OPTION_DAC_6BIT, FALSE) &&
+ pScrn->bitsPerPixel>8) {
+ OptionInfoPtr ptr;
+ ptr=xf86TokenToOptinfo(I740Options, OPTION_DAC_6BIT);
+ ptr->found=FALSE;
+ }
+
+ /* We have to use PIO to probe, because we haven't mappend yet */
+ I740SetPIOAccess(pI740);
+
+ /*
+ * Set the Chipset and ChipRev, allowing config file entries to
+ * override.
+ */
+ if (pI740->pEnt->device->chipset && *pI740->pEnt->device->chipset) {
+ pScrn->chipset = pI740->pEnt->device->chipset;
+ from = X_CONFIG;
+ } else if (pI740->pEnt->device->chipID >= 0) {
+ pScrn->chipset = (char *)xf86TokenToString(I740Chipsets, pI740->pEnt->device->chipID);
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pI740->pEnt->device->chipID);
+ } else {
+ from = X_PROBED;
+ pScrn->chipset = (char *)xf86TokenToString(I740Chipsets, pI740->pEnt->device->chipID);
+ }
+ if (pI740->pEnt->device->chipRev >= 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pI740->pEnt->device->chipRev);
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
+
+ if (pI740->pEnt->device->MemBase != 0) {
+ pI740->LinearAddr = pI740->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ if (pI740->PciInfo->memBase[1] != 0) {
+ pI740->LinearAddr = pI740->PciInfo->memBase[0]&0xFF000000;
+ from = X_PROBED;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid FB address in PCI config space\n");
+ I740FreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pI740->LinearAddr);
+
+ if (pI740->pEnt->device->IOBase != 0) {
+ pI740->MMIOAddr = pI740->pEnt->device->IOBase;
+ from = X_CONFIG;
+ } else {
+ if (pI740->PciInfo->memBase[1]) {
+ pI740->MMIOAddr = pI740->PciInfo->memBase[1]&0xFFF80000;
+ from = X_PROBED;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid MMIO address in PCI config space\n");
+ I740FreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n",
+ (unsigned long)pI740->MMIOAddr);
+
+ /* Calculate memory */
+ if (pI740->pEnt->device->videoRam) {
+ pScrn->videoRam = pI740->pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else {
+ if ((pI740->readControl(pI740, XRX, DRAM_ROW_TYPE)&DRAM_ROW_1)==DRAM_ROW_1_SDRAM)
+ pScrn->videoRam=pI740->readControl(pI740, XRX, DRAM_ROW_BNDRY_1);
+ else
+ pScrn->videoRam=pI740->readControl(pI740, XRX, DRAM_ROW_BNDRY_0);
+ pScrn->videoRam = (pScrn->videoRam&0x0F)*1024;
+ from = X_PROBED;
+ }
+
+ temp=pI740->readControl(pI740, XRX, DRAM_ROW_CNTL_LO);
+ pI740->HasSGRAM = !((temp&DRAM_RAS_TIMING)||(temp&DRAM_RAS_PRECHARGE));
+ if (xf86IsOptionSet(I740Options, OPTION_SDRAM)) {
+ if (xf86IsOptionSet(I740Options, OPTION_SGRAM)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "It is nonsensical to set both SDRAM and SGRAM options\n");
+ return FALSE;
+ }
+ if (xf86ReturnOptValBool(I740Options, OPTION_SDRAM, FALSE)) {
+ pI740->HasSGRAM = FALSE;
+ } else {
+ pI740->HasSGRAM = TRUE;
+ }
+ } else {
+ if (xf86IsOptionSet(I740Options, OPTION_SDRAM)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "It is nonsensical to set both SDRAM and SGRAM options\n");
+ return FALSE;
+ }
+ if (xf86ReturnOptValBool(I740Options, OPTION_SGRAM, FALSE)) {
+ pI740->HasSGRAM = TRUE;
+ } else {
+ pI740->HasSGRAM = FALSE;
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte %s\n",
+ pScrn->videoRam, (pI740->HasSGRAM)?"SGRAM":"SDRAM");
+ pI740->FbMapSize = pScrn->videoRam*1024;
+
+ /*
+ * If the driver can do gamma correction, it should call xf86SetGamma()
+ * here.
+ */
+
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+
+ pI740->MaxClock = 0;
+ if (pI740->pEnt->device->dacSpeeds[0]) {
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ pI740->MaxClock = pI740->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ pI740->MaxClock = pI740->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ pI740->MaxClock = pI740->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ case 32:
+ pI740->MaxClock = pI740->pEnt->device->dacSpeeds[DAC_BPP32];
+ break;
+ }
+ if (!pI740->MaxClock)
+ pI740->MaxClock = pI740->pEnt->device->dacSpeeds[0];
+ from = X_CONFIG;
+ } else {
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ pI740->MaxClock = 203000;
+ break;
+ case 16:
+ pI740->MaxClock = 163000;
+ break;
+ case 24:
+ if (pI740->HasSGRAM)
+ pI740->MaxClock = 136000;
+ else
+ pI740->MaxClock = 128000;
+ break;
+ case 32:
+ pI740->MaxClock = 86000;
+ }
+ }
+ clockRanges = xnfalloc(sizeof(ClockRange));
+ clockRanges->next=NULL;
+ clockRanges->minClock= 12000; /* !!! What's the min clock? !!! */
+ clockRanges->maxClock=pI740->MaxClock;
+ clockRanges->clockIndex = -1;
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = FALSE;
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ 0, 320, 1600,
+ 8, 200, 1200,
+ pScrn->display->virtualX, pScrn->display->virtualY,
+ pI740->FbMapSize, LOOKUP_BEST_REFRESH);
+
+ if (i==-1) {
+ I740FreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86PruneDriverModes(pScrn);
+
+ if (!i || !pScrn->modes) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ I740FreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ pScrn->currentMode = pScrn->modes;
+
+ xf86PrintModes(pScrn);
+
+ xf86SetDpi(pScrn, 0, 0);
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ mod = "cfb";
+ reqSym = "cfbScreenInit";
+ break;
+ case 16:
+ mod = "cfb16";
+ reqSym = "cfb16ScreenInit";
+ break;
+ case 24:
+ mod = "cfb24";
+ reqSym = "cfb24ScreenInit";
+ break;
+ case 32:
+ mod = "cfb32";
+ reqSym = "cfb32ScreenInit";
+ break;
+ }
+ if (mod && !xf86LoadSubModule(pScrn, mod)) {
+ I740FreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymbols(reqSym, NULL);
+
+ if (!xf86ReturnOptValBool(I740Options, OPTION_NOACCEL, FALSE)) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ I740FreeRec(pScrn);
+ return FALSE;
+ }
+ }
+
+ if (!xf86ReturnOptValBool(I740Options, OPTION_SW_CURSOR, FALSE)) {
+ if (!xf86LoadSubModule(pScrn, "ramdac")) {
+ I740FreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+ }
+
+ /* We wont be using the VGA access after the probe */
+ if (!xf86ReturnOptValBool(I740Options, OPTION_USE_PIO, FALSE)) {
+ resRange vgaio[] = { {ResShrIoBlock,0x3B0,0x3BB},
+ {ResShrIoBlock,0x3C0,0x3DF},
+ _END };
+ resRange vgamem[] = {{ResShrMemBlock,0xA0000,0xAFFFF},
+ {ResShrMemBlock,0xB8000,0xBFFFF},
+ {ResShrMemBlock,0xB0000,0xB7FFF},
+ _END };
+
+ pI740->usePIO=FALSE;
+ I740SetMMIOAccess(pI740);
+ xf86SetOperatingState(vgaio, pI740->pEnt->index, ResUnusedOpr);
+ xf86SetOperatingState(vgamem, pI740->pEnt->index, ResDisableOpr);
+ } else {
+ pI740->usePIO=TRUE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+I740MapMem(ScrnInfoPtr pScrn)
+{
+ int mmioFlags;
+ I740Ptr pI740;
+
+ pI740 = I740PTR(pScrn);
+
+#if !defined(__alpha__)
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
+#else
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT | VIDMEM_SPARSE;
+#endif
+
+ pI740->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+ pI740->PciTag,
+ pI740->MMIOAddr,
+ 0x80000);
+ if (!pI740->MMIOBase) return FALSE;
+
+ pI740->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pI740->PciTag,
+ pI740->LinearAddr,
+ pI740->FbMapSize);
+ if (!pI740->FbBase) return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+I740UnmapMem(ScrnInfoPtr pScrn)
+{
+ I740Ptr pI740;
+
+ pI740 = I740PTR(pScrn);
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pI740->MMIOBase, 0x80000);
+ pI740->MMIOBase=0;
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pI740->FbBase, pI740->FbMapSize);
+ pI740->FbBase = 0;
+ return TRUE;
+}
+
+/*
+ * I740Save --
+ *
+ * This function saves the video state. It reads all of the SVGA registers
+ * into the vgaI740Rec data structure. There is in general no need to
+ * mask out bits here - just read the registers.
+ */
+static void
+DoSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, I740RegPtr i740Reg, Bool saveFonts)
+{
+ I740Ptr pI740;
+ vgaHWPtr hwp;
+
+ pI740 = I740PTR(pScrn);
+ hwp = VGAHWPTR(pScrn);
+
+ /*
+ * This function will handle creating the data structure and filling
+ * in the generic VGA portion.
+ */
+ if (saveFonts)
+ vgaHWSave(pScrn, vgaReg, VGA_SR_MODE|VGA_SR_FONTS);
+ else
+ vgaHWSave(pScrn, vgaReg, VGA_SR_MODE);
+
+ /*
+ * The port I/O code necessary to read in the extended registers
+ * into the fields of the vgaI740Rec structure goes here.
+ */
+
+ i740Reg->IOControl = pI740->readControl(pI740, XRX, IO_CTNL);
+ i740Reg->AddressMapping = pI740->readControl(pI740, XRX, ADDRESS_MAPPING);
+ i740Reg->BitBLTControl = pI740->readControl(pI740, XRX, BITBLT_CNTL);
+ i740Reg->VideoClk2_M = pI740->readControl(pI740, XRX, VCLK2_VCO_M);
+ i740Reg->VideoClk2_N = pI740->readControl(pI740, XRX, VCLK2_VCO_N);
+ i740Reg->VideoClk2_MN_MSBs = pI740->readControl(pI740, XRX, VCLK2_VCO_MN_MSBS);
+ i740Reg->VideoClk2_DivisorSel = pI740->readControl(pI740, XRX, VCLK2_VCO_DIV_SEL);
+ i740Reg->PLLControl = pI740->readControl(pI740, XRX, PLL_CNTL);
+
+ i740Reg->ExtVertTotal=hwp->readCrtc(hwp, EXT_VERT_TOTAL);
+ i740Reg->ExtVertDispEnd=hwp->readCrtc(hwp, EXT_VERT_DISPLAY);
+ i740Reg->ExtVertSyncStart=hwp->readCrtc(hwp, EXT_VERT_SYNC_START);
+ i740Reg->ExtVertBlankStart=hwp->readCrtc(hwp, EXT_VERT_BLANK_START);
+ i740Reg->ExtHorizTotal=hwp->readCrtc(hwp, EXT_HORIZ_TOTAL);
+ i740Reg->ExtHorizBlank=hwp->readCrtc(hwp, EXT_HORIZ_BLANK);
+ i740Reg->ExtOffset=hwp->readCrtc(hwp, EXT_OFFSET);
+ i740Reg->InterlaceControl=hwp->readCrtc(hwp, INTERLACE_CNTL);
+
+ i740Reg->PixelPipeCfg0 = pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
+ i740Reg->PixelPipeCfg1 = pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_1);
+ i740Reg->PixelPipeCfg2 = pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_2);
+ i740Reg->DisplayControl = pI740->readControl(pI740, XRX, DISPLAY_CNTL);
+
+ i740Reg->LMI_FIFO_Watermark = INREG(FWATER_BLC);
+}
+
+static void
+I740Save(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp;
+ I740Ptr pI740;
+
+ hwp = VGAHWPTR(pScrn);
+ pI740 = I740PTR(pScrn);
+ DoSave(pScrn, &hwp->SavedReg, &pI740->SavedReg, TRUE);
+}
+
+static void
+DoRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, I740RegPtr i740Reg,
+ Bool restoreFonts) {
+ I740Ptr pI740;
+ vgaHWPtr hwp;
+ unsigned char temp;
+ unsigned int itemp;
+
+ pI740 = I740PTR(pScrn);
+ hwp = VGAHWPTR(pScrn);
+
+ vgaHWProtect(pScrn, TRUE);
+#if 0
+ temp=hwp->readCrtc(hwp, VERT_SYNC_END);
+ hwp->writeCrtc(hwp, VERT_SYNC_END, temp&0x7F);
+#endif
+
+ temp = pI740->readControl(pI740, MRX, ACQ_CNTL_2);
+ if ((temp & FRAME_CAP_MODE) == SINGLE_CAP_MODE) {
+ temp=pI740->readControl(pI740, MRX, COL_KEY_CNTL_1);
+ temp |= BLANK_DISP_OVERLAY; /* Disable the overlay */
+ pI740->writeControl(pI740, MRX, COL_KEY_CNTL_1, temp);
+ } else {
+ temp &= ~FRAME_CAP_MODE;
+ pI740->writeControl(pI740, MRX, ACQ_CNTL_2, temp);
+ }
+ usleep(50000);
+
+ /* Turn off DRAM Refresh */
+ pI740->writeControl(pI740, XRX, DRAM_EXT_CNTL, DRAM_REFRESH_DISABLE);
+
+ usleep(1000); /* Wait 1 ms */
+
+ /* Write the M, N and P values */
+ pI740->writeControl(pI740, XRX, VCLK2_VCO_M, i740Reg->VideoClk2_M);
+ pI740->writeControl(pI740, XRX, VCLK2_VCO_N, i740Reg->VideoClk2_N);
+ pI740->writeControl(pI740, XRX, VCLK2_VCO_MN_MSBS, i740Reg->VideoClk2_MN_MSBs);
+ pI740->writeControl(pI740, XRX, VCLK2_VCO_DIV_SEL, i740Reg->VideoClk2_DivisorSel);
+
+ /*
+ * Turn on 8 bit dac mode, if requested. This is needed to make
+ * sure that vgaHWRestore writes the values into the DAC properly.
+ * The problem occurs if 8 bit dac mode is requested and the HW is
+ * in 6 bit dac mode. If this happens, all the values are
+ * automatically shifted left twice by the HW and incorrect colors
+ * will be displayed on the screen. The only time this can happen
+ * is at server startup time and when switching back from a VT.
+ */
+ temp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
+ temp &= 0x7F; /* Save all but the 8 bit dac mode bit */
+ temp |= (i740Reg->PixelPipeCfg0 & DAC_8_BIT);
+ pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, temp);
+
+ /*
+ * Code to restore any SVGA registers that have been saved/modified
+ * goes here. Note that it is allowable, and often correct, to
+ * only modify certain bits in a register by a read/modify/write cycle.
+ *
+ * A special case - when using an external clock-setting program,
+ * this function must not change bits associated with the clock
+ * selection. This condition can be checked by the condition:
+ *
+ * if (restore->std.NoClock >= 0)
+ * restore clock-select bits.
+ */
+ if (restoreFonts)
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS|VGA_SR_MODE);
+ else
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+
+ hwp->writeCrtc(hwp, EXT_VERT_TOTAL, i740Reg->ExtVertTotal);
+ hwp->writeCrtc(hwp, EXT_VERT_DISPLAY, i740Reg->ExtVertDispEnd);
+ hwp->writeCrtc(hwp, EXT_VERT_SYNC_START, i740Reg->ExtVertSyncStart);
+ hwp->writeCrtc(hwp, EXT_VERT_BLANK_START, i740Reg->ExtVertBlankStart);
+ hwp->writeCrtc(hwp, EXT_HORIZ_TOTAL, i740Reg->ExtHorizTotal);
+ hwp->writeCrtc(hwp, EXT_HORIZ_BLANK, i740Reg->ExtHorizBlank);
+ hwp->writeCrtc(hwp, EXT_OFFSET, i740Reg->ExtOffset);
+
+ temp=hwp->readCrtc(hwp, INTERLACE_CNTL);
+ temp &= ~INTERLACE_ENABLE;
+ temp |= i740Reg->InterlaceControl;
+ hwp->writeCrtc(hwp, INTERLACE_CNTL, temp);
+
+ temp=pI740->readControl(pI740, XRX, ADDRESS_MAPPING);
+ temp &= 0xE0; /* Save reserved bits 7:5 */
+ temp |= i740Reg->AddressMapping;
+ pI740->writeControl(pI740, XRX, ADDRESS_MAPPING, temp);
+
+ temp=pI740->readControl(pI740, XRX, BITBLT_CNTL);
+ temp &= ~COLEXP_MODE;
+ temp |= i740Reg->BitBLTControl;
+ pI740->writeControl(pI740, XRX, BITBLT_CNTL, temp);
+
+ temp=pI740->readControl(pI740, XRX, DISPLAY_CNTL);
+ temp &= ~(VGA_WRAP_MODE | GUI_MODE);
+ temp |= i740Reg->DisplayControl;
+ pI740->writeControl(pI740, XRX, DISPLAY_CNTL, temp);
+
+ temp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0);
+ temp &= 0x64; /* Save reserved bits 6:5,2 */
+ temp |= i740Reg->PixelPipeCfg0;
+ pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, temp);
+
+ temp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_2);
+ temp &= 0xF3; /* Save reserved bits 7:4,1:0 */
+ temp |= i740Reg->PixelPipeCfg2;
+ pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_2, temp);
+
+ temp=pI740->readControl(pI740, XRX, PLL_CNTL);
+ temp = i740Reg->PLLControl; /* To fix the 2.3X BIOS problem */
+ pI740->writeControl(pI740, XRX, PLL_CNTL, temp);
+
+ temp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_1);
+ temp &= ~DISPLAY_COLOR_MODE;
+ temp |= i740Reg->PixelPipeCfg1;
+ pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_1, temp);
+
+ itemp = INREG(FWATER_BLC);
+ itemp &= ~(LMI_BURST_LENGTH | LMI_FIFO_WATERMARK);
+ itemp |= i740Reg->LMI_FIFO_Watermark;
+ OUTREG(FWATER_BLC, itemp);
+
+ /* Turn on DRAM Refresh */
+ pI740->writeControl(pI740, XRX, DRAM_EXT_CNTL, DRAM_REFRESH_60HZ);
+
+ temp=pI740->readControl(pI740, MRX, COL_KEY_CNTL_1);
+ temp &= ~BLANK_DISP_OVERLAY; /* Re-enable the overlay */
+ pI740->writeControl(pI740, MRX, COL_KEY_CNTL_1, temp);
+
+ if (!(vgaReg->Attribute[0x10] & 0x1)) {
+ usleep(50000);
+ if (restoreFonts)
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS|VGA_SR_MODE);
+ else
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+ }
+
+ vgaHWProtect(pScrn, FALSE);
+ temp=pI740->readControl(pI740, XRX, IO_CTNL);
+ temp &= ~(EXTENDED_ATTR_CNTL | EXTENDED_CRTC_CNTL);
+ temp |= i740Reg->IOControl;
+ pI740->writeControl(pI740, XRX, IO_CTNL, temp);
+#if 0
+ temp=hwp->readCrtc(hwp, VERT_SYNC_END);
+ hwp->writeCrtc(hwp, VERT_SYNC_END, temp|0x80);
+#endif
+}
+
+static void
+I740Restore(ScrnInfoPtr pScrn) {
+ vgaHWPtr hwp;
+ I740Ptr pI740;
+
+ hwp = VGAHWPTR(pScrn);
+ pI740 = I740PTR(pScrn);
+
+ DoRestore(pScrn, &hwp->SavedReg, &pI740->SavedReg, TRUE);
+}
+
+/*
+ * I740CalcFIFO --
+ *
+ * Calculate burst length and FIFO watermark.
+ */
+
+static unsigned int
+I740CalcFIFO(ScrnInfoPtr pScrn, double freq)
+{
+ unsigned int wm = 0x18120000;
+ I740Ptr pI740;
+
+ pI740 = I740PTR(pScrn);
+
+ /*
+ * Would like to calculate these values automatically, but a generic
+ * algorithm does not seem possible. Note: These FIFO water mark
+ * values were tested on several cards and seem to eliminate the
+ * all of the snow and vertical banding, but fine adjustments will
+ * probably be required for other cards.
+ */
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ if (pI740->HasSGRAM) {
+ if (freq > 200) wm = 0x18120000;
+ else if (freq > 175) wm = 0x16110000;
+ else if (freq > 135) wm = 0x120E0000;
+ else wm = 0x100D0000;
+ } else {
+ if (freq > 200) wm = 0x18120000;
+ else if (freq > 175) wm = 0x16110000;
+ else if (freq > 135) wm = 0x120E0000;
+ else wm = 0x100D0000;
+ }
+ break;
+ case 16:
+ if (pI740->HasSGRAM) {
+ if (freq > 140) wm = 0x2C1D0000;
+ else if (freq > 120) wm = 0x2C180000;
+ else if (freq > 100) wm = 0x24160000;
+ else if (freq > 90) wm = 0x18120000;
+ else if (freq > 50) wm = 0x16110000;
+ else if (freq > 32) wm = 0x13100000;
+ else wm = 0x120E0000;
+ } else {
+ if (freq > 160) wm = 0x28200000;
+ else if (freq > 140) wm = 0x2A1E0000;
+ else if (freq > 130) wm = 0x2B1A0000;
+ else if (freq > 120) wm = 0x2C180000;
+ else if (freq > 100) wm = 0x24180000;
+ else if (freq > 90) wm = 0x18120000;
+ else if (freq > 50) wm = 0x16110000;
+ else if (freq > 32) wm = 0x13100000;
+ else wm = 0x120E0000;
+ }
+ break;
+ case 24:
+ if (pI740->HasSGRAM) {
+ if (freq > 130) wm = 0x31200000;
+ else if (freq > 120) wm = 0x2E200000;
+ else if (freq > 100) wm = 0x2C1D0000;
+ else if (freq > 80) wm = 0x25180000;
+ else if (freq > 64) wm = 0x24160000;
+ else if (freq > 49) wm = 0x18120000;
+ else if (freq > 32) wm = 0x16110000;
+ else wm = 0x13100000;
+ } else {
+ if (freq > 120) wm = 0x311F0000;
+ else if (freq > 100) wm = 0x2C1D0000;
+ else if (freq > 80) wm = 0x25180000;
+ else if (freq > 64) wm = 0x24160000;
+ else if (freq > 49) wm = 0x18120000;
+ else if (freq > 32) wm = 0x16110000;
+ else wm = 0x13100000;
+ }
+ break;
+ case 32:
+ if (pI740->HasSGRAM) {
+ if (freq > 80) wm = 0x2A200000;
+ else if (freq > 60) wm = 0x281A0000;
+ else if (freq > 49) wm = 0x25180000;
+ else if (freq > 32) wm = 0x18120000;
+ else wm = 0x16110000;
+ } else {
+ if (freq > 80) wm = 0x29200000;
+ else if (freq > 60) wm = 0x281A0000;
+ else if (freq > 49) wm = 0x25180000;
+ else if (freq > 32) wm = 0x18120000;
+ else wm = 0x16110000;
+ }
+ break;
+ }
+
+ return wm;
+}
+
+/*
+ * I740CalcVCLK --
+ *
+ * Determine the closest clock frequency to the one requested.
+ */
+
+#define MAX_VCO_FREQ 450.0
+#define TARGET_MAX_N 30
+#define REF_FREQ 66.66666666667
+
+#define CALC_VCLK(m,n,p,d) \
+ (double)m / ((double)n * (1 << p)) * (4 << (d << 1)) * REF_FREQ
+
+static void
+I740CalcVCLK(ScrnInfoPtr pScrn, double freq)
+{
+ I740Ptr pI740;
+ I740RegPtr i740Reg;
+ int m, n, p, d;
+ double f_out;
+ double f_err;
+ double f_vco;
+ int m_best = 0, n_best = 0, p_best = 0, d_best = 0;
+ double f_target = freq;
+ double err_max = 0.005;
+ double err_target = 0.001;
+ double err_best = 999999.0;
+
+ pI740 = I740PTR(pScrn);
+ i740Reg = &pI740->ModeReg;
+
+ p_best = p = log(MAX_VCO_FREQ/f_target)/log((double)2);
+ d_best = d = 0;
+
+ f_vco = f_target * (1 << p);
+
+ n = 2;
+ do {
+ n++;
+ m = f_vco / (REF_FREQ / (double)n) / (double)4.0 + 0.5;
+ if (m < 3) m = 3;
+ f_out = CALC_VCLK(m,n,p,d);
+ f_err = 1.0 - (f_target/f_out);
+ if (fabs(f_err) < err_max) {
+ m_best = m;
+ n_best = n;
+ err_best = f_err;
+ }
+ } while ((fabs(f_err) >= err_target) &&
+ ((n <= TARGET_MAX_N) || (fabs(err_best) > err_max)));
+
+ if (fabs(f_err) < err_target) {
+ m_best = m;
+ n_best = n;
+ }
+
+ i740Reg->VideoClk2_M = (m_best-2) & 0xFF;
+ i740Reg->VideoClk2_N = (n_best-2) & 0xFF;
+ i740Reg->VideoClk2_MN_MSBs = ((((n_best-2) >> 4) & VCO_N_MSBS) |
+ (((m_best-2) >> 8) & VCO_M_MSBS));
+ i740Reg->VideoClk2_DivisorSel = ((p_best << 4) |
+ (d_best ? 4 : 0) |
+ REF_DIV_1);
+}
+
+static Bool
+I740SetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) {
+ I740Ptr pI740;
+ I740RegPtr i740Reg;
+ vgaRegPtr pVga;
+ double dclk = mode->Clock/1000.0;
+
+ pI740 = I740PTR(pScrn);
+ i740Reg = &pI740->ModeReg;
+ pVga = &VGAHWPTR(pScrn)->ModeReg;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ /* pVga->CRTC[0x13] = pScrn->displayWidth >> 3; */
+ i740Reg->ExtOffset = pScrn->displayWidth >> 11;
+ i740Reg->PixelPipeCfg1 = DISPLAY_8BPP_MODE;
+ i740Reg->BitBLTControl = COLEXP_8BPP;
+ break;
+ case 16:
+ if (pScrn->weight.green == 5) {
+ i740Reg->PixelPipeCfg1 = DISPLAY_15BPP_MODE;
+ } else {
+ i740Reg->PixelPipeCfg1 = DISPLAY_16BPP_MODE;
+ }
+ /* pVga->CRTC[0x13] = pScrn->displayWidth >> 2; */
+ i740Reg->ExtOffset = pScrn->displayWidth >> 10;
+ i740Reg->BitBLTControl = COLEXP_16BPP;
+ break;
+ case 24:
+ /* pVga->CRTC[0x13] = (pScrn->displayWidth * 3) >> 3; */
+ i740Reg->ExtOffset = (pScrn->displayWidth * 3)>> 11;
+ i740Reg->PixelPipeCfg1 = DISPLAY_24BPP_MODE;
+ i740Reg->BitBLTControl = COLEXP_24BPP;
+ break;
+ case 32:
+ /* pVga->CRTC[0x13] = pScrn->displayWidth >> 1; */
+ i740Reg->ExtOffset = pScrn->displayWidth >> 9;
+ i740Reg->PixelPipeCfg1 = DISPLAY_32BPP_MODE;
+ i740Reg->BitBLTControl = COLEXP_RESERVED; /* Not implemented on i740 */
+ break;
+ default:
+ break;
+ }
+
+ /* Turn on 8 bit dac if requested */
+ if (xf86ReturnOptValBool(I740Options, OPTION_DAC_6BIT, FALSE))
+ i740Reg->PixelPipeCfg0 = DAC_6_BIT;
+ else
+ i740Reg->PixelPipeCfg0 = DAC_8_BIT;
+
+ i740Reg->PixelPipeCfg2 = DISPLAY_GAMMA_ENABLE | OVERLAY_GAMMA_ENABLE;
+
+ /* Turn on Extended VGA Interpretation */
+ i740Reg->IOControl = EXTENDED_CRTC_CNTL;
+
+ /* Turn on linear and page mapping */
+ i740Reg->AddressMapping = LINEAR_MODE_ENABLE | PAGE_MAPPING_ENABLE;
+
+ /* Turn on GUI mode */
+ i740Reg->DisplayControl = HIRES_MODE;
+
+ /* Set the MCLK freq */
+ if (xf86ReturnOptValBool(I740Options, OPTION_SLOW_RAM, FALSE))
+ i740Reg->PLLControl = PLL_MEMCLK__66667KHZ; /* 66 MHz */
+ else
+ i740Reg->PLLControl = PLL_MEMCLK_100000KHZ; /* 100 MHz -- use as default */
+
+ /* Calculate the extended CRTC regs */
+ i740Reg->ExtVertTotal = (mode->CrtcVTotal - 2) >> 8;
+ i740Reg->ExtVertDispEnd = (mode->CrtcVDisplay - 1) >> 8;
+ i740Reg->ExtVertSyncStart = mode->CrtcVSyncStart >> 8;
+ i740Reg->ExtVertBlankStart = mode->CrtcVBlankStart >> 8;
+ i740Reg->ExtHorizTotal = ((mode->CrtcHTotal >> 3) - 5) >> 8;
+ i740Reg->ExtHorizBlank = ((mode->CrtcHSyncEnd >> 3) & 0x40) >> 6;
+
+ /* Turn on interlaced mode if necessary */
+ if (mode->Flags & V_INTERLACE)
+ i740Reg->InterlaceControl = INTERLACE_ENABLE;
+ else
+ i740Reg->InterlaceControl = INTERLACE_DISABLE;
+
+ /*
+ * Set the overscan color to 0.
+ * NOTE: This only affects >8bpp mode.
+ */
+ pVga->Attribute[0x11] = 0;
+
+ /*
+ * Calculate the VCLK that most closely matches the requested dot
+ * clock.
+ */
+ I740CalcVCLK(pScrn, dclk);
+
+ /* Since we program the clocks ourselves, always use VCLK2. */
+ pVga->MiscOutReg |= 0x0C;
+
+ /* Calculate the FIFO Watermark and Burst Length. */
+ i740Reg->LMI_FIFO_Watermark = I740CalcFIFO(pScrn, dclk);
+
+ return TRUE;
+}
+
+static Bool
+I740ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp;
+ I740Ptr pI740;
+
+ hwp = VGAHWPTR(pScrn);
+ pI740 = I740PTR(pScrn);
+
+ vgaHWUnlock(hwp);
+
+ if (!vgaHWInit(pScrn, mode)) return FALSE;
+
+ pScrn->vtSema = TRUE;
+
+ if (!I740SetMode(pScrn, mode)) return FALSE;
+
+ DoRestore(pScrn, &hwp->ModeReg, &pI740->ModeReg, FALSE);
+
+ return TRUE;
+}
+
+static void
+I740LoadPalette16(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
+ VisualPtr pVisual) {
+ I740Ptr pI740;
+ vgaHWPtr hwp;
+ int i, index;
+ unsigned char r, g, b;
+
+ pI740 = I740PTR(pScrn);
+ hwp = VGAHWPTR(pScrn);
+ for (i=0; i<numColors; i++) {
+ index=indices[i/2];
+ r=colors[index].red;
+ b=colors[index].blue;
+ index=indices[i];
+ g=colors[index].green;
+ hwp->writeDacWriteAddr(hwp, index<<2);
+ hwp->writeDacData(hwp, r);
+ hwp->writeDacData(hwp, g);
+ hwp->writeDacData(hwp, b);
+ i++;
+ index=indices[i];
+ g=colors[index].green;
+ hwp->writeDacWriteAddr(hwp, index<<2);
+ hwp->writeDacData(hwp, r);
+ hwp->writeDacData(hwp, g);
+ hwp->writeDacData(hwp, b);
+ }
+}
+
+static void
+I740LoadPalette24(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
+ VisualPtr pVisual) {
+ I740Ptr pI740;
+ vgaHWPtr hwp;
+ int i, index;
+ unsigned char r, g, b;
+
+ pI740 = I740PTR(pScrn);
+ hwp = VGAHWPTR(pScrn);
+ for (i=0; i<numColors; i++) {
+ index=indices[i];
+ r=colors[index].red;
+ b=colors[index].blue;
+ index=indices[i];
+ g=colors[index].green;
+ hwp->writeDacWriteAddr(hwp, index);
+ hwp->writeDacData(hwp, r);
+ hwp->writeDacData(hwp, g);
+ hwp->writeDacData(hwp, b);
+ }
+}
+
+static Bool
+I740ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) {
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ I740Ptr pI740;
+ VisualPtr visual;
+ BoxRec MemBox;
+
+ pScrn = xf86Screens[pScreen->myNum];
+ pI740 = I740PTR(pScrn);
+ hwp = VGAHWPTR(pScrn);
+
+ if (!I740MapMem(pScrn)) return FALSE;
+ pScrn->memPhysBase = (int)pI740->FbBase;
+ pScrn->fbOffset = 0;
+
+ if (!pI740->usePIO)
+ vgaHWSetMmioFuncs(hwp, pI740->MMIOBase, 0);
+ vgaHWGetIOBase(hwp);
+ if (!vgaHWMapMem(pScrn)) return FALSE;
+
+ I740Save(pScrn);
+ if (!I740ModeInit(pScrn, pScrn->currentMode)) return FALSE;
+
+ I740SaveScreen(pScreen, FALSE);
+ I740AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ miClearVisualTypes();
+
+ if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ if (!cfbScreenInit(pScreen, pI740->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth))
+ return FALSE;
+ break;
+ case 16:
+ if (!cfb16ScreenInit(pScreen, pI740->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth))
+ return FALSE;
+ break;
+ case 24:
+ if (!cfb24ScreenInit(pScreen, pI740->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth))
+ return FALSE;
+ break;
+ case 32:
+ if (!cfb32ScreenInit(pScreen, pI740->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth))
+ return FALSE;
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in I740ScrnInit\n",
+ pScrn->bitsPerPixel);
+ return FALSE;
+ }
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ if (pScrn->bitsPerPixel>8) {
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ if (!miCreateDefColormap(pScreen)) return FALSE;
+
+ if (pScrn->bitsPerPixel==16) {
+ if (!xf86HandleColormaps(pScreen, 256, 8, I740LoadPalette16, 0,
+ CMAP_PALETTED_TRUECOLOR|CMAP_RELOAD_ON_MODE_SWITCH))
+ return FALSE;
+ } else {
+ if (!xf86HandleColormaps(pScreen, 256, 8, I740LoadPalette24, 0,
+ CMAP_PALETTED_TRUECOLOR|CMAP_RELOAD_ON_MODE_SWITCH))
+ return FALSE;
+ }
+
+#ifdef DPMSExtension
+ xf86DPMSInit(pScreen, I740DisplayPowerManagementSet, 0);
+#endif
+
+#ifdef XvExtension
+ {
+ XF86VideoAdaptorPtr *ptr;
+ int n;
+
+ n = xf86XVListGenericAdaptors(&ptr);
+ if (n) {
+ xf86XVScreenInit(pScreen, ptr, n);
+ }
+ }
+#endif
+
+ MemBox.x1=0;
+ MemBox.x2=pScrn->displayWidth;
+ MemBox.y1=0;
+ MemBox.y2=pI740->FbMapSize/(pScrn->displayWidth*pI740->cpp);
+
+ if (!xf86InitFBManager(pScreen, &MemBox)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to init memory manager\n");
+ return FALSE;
+ }
+
+ if (!xf86ReturnOptValBool(I740Options, OPTION_NOACCEL, FALSE)) {
+ if (!I740AccelInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware acceleration initialization failed\n");
+ }
+ }
+
+ if (!xf86ReturnOptValBool(I740Options, OPTION_SW_CURSOR, FALSE)) {
+ if (!I740CursorInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ }
+ }
+
+ pScreen->SaveScreen = I740SaveScreen;
+ pI740->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = I740CloseScreen;
+
+ if (serverGeneration == 1)
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+
+ return TRUE;
+}
+
+static Bool
+I740SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) {
+ ScrnInfoPtr pScrn;
+
+ pScrn=xf86Screens[scrnIndex];
+ return I740ModeInit(pScrn, mode);
+}
+
+static void
+I740AdjustFrame(int scrnIndex, int x, int y, int flags) {
+ ScrnInfoPtr pScrn;
+ I740Ptr pI740;
+ int Base;
+ vgaHWPtr hwp;
+
+ pScrn = xf86Screens[scrnIndex];
+ pI740 = I740PTR(pScrn);
+ hwp = VGAHWPTR(pScrn);
+
+ Base = (y * pScrn->displayWidth + x) >> 2;
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ break;
+ case 16:
+ Base *= 2;
+ break;
+ case 24:
+ /*
+ * The last bit does not seem to have any effect on the start
+ * address register in 24bpp mode, so...
+ */
+ Base &= 0xFFFFFFFE; /* ...ignore the last bit. */
+ Base *= 3;
+ break;
+ case 32:
+ Base *= 4;
+ break;
+ }
+
+ hwp->writeCrtc(hwp, START_ADDR_LO, Base&0xFF);
+ hwp->writeCrtc(hwp, START_ADDR_HI, (Base&0xFF00)>>8);
+ hwp->writeCrtc(hwp, EXT_START_ADDR_HI, (Base&0x3FC00000)>>22);
+ hwp->writeCrtc(hwp, EXT_START_ADDR,
+ ((Base&0x00eF0000)>>16|EXT_START_ADDR_ENABLE));
+}
+
+static Bool
+I740EnterVT(int scrnIndex, int flags) {
+ ScrnInfoPtr pScrn;
+
+ pScrn = xf86Screens[scrnIndex];
+ if (!I740ModeInit(pScrn, pScrn->currentMode)) return FALSE;
+ I740AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ return TRUE;
+}
+
+static void
+I740LeaveVT(int scrnIndex, int flags) {
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+
+ pScrn = xf86Screens[scrnIndex];
+ hwp=VGAHWPTR(pScrn);
+ I740Restore(pScrn);
+ vgaHWLock(hwp);
+}
+
+static Bool
+I740CloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ I740Ptr pI740;
+
+ pScrn = xf86Screens[scrnIndex];
+ hwp = VGAHWPTR(pScrn);
+ pI740 = I740PTR(pScrn);
+
+ I740Restore(pScrn);
+ vgaHWLock(hwp);
+ I740UnmapMem(pScrn);
+ vgaHWUnmapMem(pScrn);
+ if (pI740->AccelInfoRec)
+ XAADestroyInfoRec(pI740->AccelInfoRec);
+ pI740->AccelInfoRec=0;
+ if (pI740->CursorInfoRec)
+ xf86DestroyCursorInfoRec(pI740->CursorInfoRec);
+ pI740->CursorInfoRec=0;
+ pScrn->vtSema=FALSE;
+
+ pScreen->CloseScreen = pI740->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+static void
+I740FreeScreen(int scrnIndex, int flags) {
+ I740FreeRec(xf86Screens[scrnIndex]);
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+}
+
+static int
+I740ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) {
+ if (mode->Flags & V_INTERLACE) {
+ if (verbose) {
+ xf86DrvMsg(scrnIndex, X_PROBED,
+ "Removing interlaced mode \"%s\"\n",
+ mode->name);
+ }
+ return MODE_BAD;
+ }
+ return MODE_OK;
+}
+
+static Bool
+I740SaveScreen(ScreenPtr pScreen, Bool unblack)
+{
+ /* if (unblack) outw(SRX, 0x0300);
+ else outw(SRX, 0x0100); */
+ return vgaHWSaveScreen(pScreen, unblack);
+}
+
+#ifdef DPMSExtension
+static void
+I740DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
+ int flags) {
+ I740Ptr pI740;
+ unsigned char SEQ01=0;
+ int DPMSSyncSelect=0;
+
+ pI740 = I740PTR(pScrn);
+ switch (PowerManagementMode) {
+ case DPMSModeOn:
+ /* Screen: On; HSync: On, VSync: On */
+ SEQ01 = 0x00;
+ DPMSSyncSelect = HSYNC_ON | VSYNC_ON;
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off; HSync: Off, VSync: On */
+ SEQ01 = 0x20;
+ DPMSSyncSelect = HSYNC_OFF | VSYNC_ON;
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off; HSync: On, VSync: Off */
+ SEQ01 = 0x20;
+ DPMSSyncSelect = HSYNC_ON | VSYNC_OFF;
+ break;
+ case DPMSModeOff:
+ /* Screen: Off; HSync: Off, VSync: Off */
+ SEQ01 = 0x20;
+ DPMSSyncSelect = HSYNC_OFF | VSYNC_OFF;
+ break;
+ }
+
+ /* Turn the screen on/off */
+ SEQ01 |= pI740->readControl(pI740, SRX, 0x01) & ~0x20;
+ pI740->writeControl(pI740, SRX, 0x01, SEQ01);
+
+ /* Set the DPMS mode */
+ pI740->writeControl(pI740, XRX, DPMS_SYNC_SELECT, DPMSSyncSelect);
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_io.c b/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_io.c
new file mode 100644
index 000000000..9dcfba2a5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_io.c
@@ -0,0 +1,92 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i740/i740_io.c,v 1.1 1999/08/29 12:20:59 dawes Exp $ */
+
+/*
+ * Authors:
+ * Daryll Strauss <daryll@precisioninsight.com>
+ *
+ * $PI$
+ */
+
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+#include "compiler.h"
+
+#include "i740.h"
+
+static void I740WriteControlPIO(I740Ptr pI740, int addr, char index, char val) {
+ outb(addr, index);
+ outb(addr+1, val);
+}
+
+static char I740ReadControlPIO(I740Ptr pI740, int addr, char index) {
+ outb(addr, index);
+ return inb(addr+1);
+}
+
+static void I740WriteStandardPIO(I740Ptr pI740, int addr, char val) {
+ outb(addr, val);
+}
+
+static char I740ReadStandardPIO(I740Ptr pI740, int addr) {
+ return inb(addr);
+}
+
+void I740SetPIOAccess(I740Ptr pI740) {
+ pI740->writeControl=I740WriteControlPIO;
+ pI740->readControl=I740ReadControlPIO;
+ pI740->writeStandard=I740WriteStandardPIO;
+ pI740->readStandard=I740ReadStandardPIO;
+}
+
+static void I740WriteControlMMIO(I740Ptr pI740, int addr, char index, char val) {
+ moutb(addr, index);
+ moutb(addr+1, val);
+}
+
+static char I740ReadControlMMIO(I740Ptr pI740, int addr, char index) {
+ moutb(addr, index);
+ return minb(addr+1);
+}
+
+static void I740WriteStandardMMIO(I740Ptr pI740, int addr, char val) {
+ moutb(addr, val);
+}
+
+static char I740ReadStandardMMIO(I740Ptr pI740, int addr) {
+ return minb(addr);
+}
+
+void I740SetMMIOAccess(I740Ptr pI740) {
+ pI740->writeControl=I740WriteControlMMIO;
+ pI740->readControl=I740ReadControlMMIO;
+ pI740->writeStandard=I740WriteStandardMMIO;
+ pI740->readStandard=I740ReadStandardMMIO;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_macros.h b/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_macros.h
new file mode 100644
index 000000000..bdaf0a599
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_macros.h
@@ -0,0 +1,59 @@
+
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i740/i740_macros.h,v 1.1 1999/08/29 12:20:59 dawes Exp $ */
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $PI$
+ */
+
+#define WAIT_ENGINE_IDLE_PIO() { \
+ outb(XRX, BITBLT_CNTL); \
+ while (inb(XRX+1) & BITBLT_STATUS) \
+ outb(XRX, BITBLT_CNTL); \
+ }
+
+#define WAIT_ENGINE_IDLE_MMIO() { \
+ moutb(XRX, BITBLT_CNTL); \
+ while (minb(XRX+1) & BITBLT_STATUS) \
+ moutb(XRX, BITBLT_CNTL); \
+ }
+
+#define WAIT_BLT_IDLE() { \
+ while (INREG(BITBLT_CONTROL) & BLTR_STATUS); \
+ }
+
+#define WAIT_LP_FIFO(n) { \
+ while (INREG8(LP_FIFO_COUNT) > 15-(n)); \
+ }
+
+#define WAIT_HP_FIFO(n) { \
+ while (INREG8(HP_FIFO_COUNT) > 15-(n)); \
+ }
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_reg.h
new file mode 100644
index 000000000..2431605b7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/i740/i740_reg.h
@@ -0,0 +1,328 @@
+
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i740/i740_reg.h,v 1.1 1999/08/29 12:20:59 dawes Exp $ */
+
+/*
+ * Authors:
+ * Kevin E. Martin <kevin@precisioninsight.com>
+ *
+ * $PI$
+ */
+
+/* I/O register offsets */
+#define SRX 0x3C4
+#define GRX 0x3CE
+#define ARX 0x3C0
+#define XRX 0x3D6
+#define MRX 0x3D2
+
+/* VGA Color Palette Registers */
+#define DACMASK 0x3C6
+#define DACSTATE 0x3C7
+#define DACRX 0x3C7
+#define DACWX 0x3C8
+#define DACDATA 0x3C9
+
+/* CRT Controller Registers (CRX) */
+#define START_ADDR_HI 0x0C
+#define START_ADDR_LO 0x0D
+#define VERT_SYNC_END 0x11
+#define EXT_VERT_TOTAL 0x30
+#define EXT_VERT_DISPLAY 0x31
+#define EXT_VERT_SYNC_START 0x32
+#define EXT_VERT_BLANK_START 0x33
+#define EXT_HORIZ_TOTAL 0x35
+#define EXT_HORIZ_BLANK 0x39
+#define EXT_START_ADDR 0x40
+#define EXT_START_ADDR_ENABLE 0x80
+#define EXT_OFFSET 0x41
+#define EXT_START_ADDR_HI 0x42
+#define INTERLACE_CNTL 0x70
+#define INTERLACE_ENABLE 0x80
+#define INTERLACE_DISABLE 0x00
+
+/* Miscellaneous Output Register */
+#define MSR_R 0x3CC
+#define MSR_W 0x3C2
+#define IO_ADDR_SELECT 0x01
+
+#define MDA_BASE 0x3B0
+#define CGA_BASE 0x3D0
+
+/* System Configuration Extension Registers (XRX) */
+#define IO_CTNL 0x09
+#define EXTENDED_ATTR_CNTL 0x02
+#define EXTENDED_CRTC_CNTL 0x01
+
+#define ADDRESS_MAPPING 0x0A
+#define PACKED_MODE_ENABLE 0x04
+#define LINEAR_MODE_ENABLE 0x02
+#define PAGE_MAPPING_ENABLE 0x01
+
+#define BITBLT_CNTL 0x20
+#define COLEXP_MODE 0x30
+#define COLEXP_8BPP 0x00
+#define COLEXP_16BPP 0x10
+#define COLEXP_24BPP 0x20
+#define COLEXP_RESERVED 0x30
+#define CHIP_RESET 0x02
+#define BITBLT_STATUS 0x01
+
+#define DISPLAY_CNTL 0x40
+#define VGA_WRAP_MODE 0x02
+#define VGA_WRAP_AT_256KB 0x00
+#define VGA_NO_WRAP 0x02
+#define GUI_MODE 0x01
+#define STANDARD_VGA_MODE 0x00
+#define HIRES_MODE 0x01
+
+#define DRAM_ROW_TYPE 0x50
+#define DRAM_ROW_0 0x07
+#define DRAM_ROW_0_SDRAM 0x00
+#define DRAM_ROW_0_EMPTY 0x07
+#define DRAM_ROW_1 0x38
+#define DRAM_ROW_1_SDRAM 0x00
+#define DRAM_ROW_1_EMPTY 0x38
+#define DRAM_ROW_CNTL_LO 0x51
+#define DRAM_CAS_LATENCY 0x10
+#define DRAM_RAS_TIMING 0x08
+#define DRAM_RAS_PRECHARGE 0x04
+#define DRAM_ROW_CNTL_HI 0x52
+#define DRAM_EXT_CNTL 0x53
+#define DRAM_REFRESH_RATE 0x03
+#define DRAM_REFRESH_DISABLE 0x00
+#define DRAM_REFRESH_60HZ 0x01
+#define DRAM_REFRESH_FAST_TEST 0x02
+#define DRAM_REFRESH_RESERVED 0x03
+#define DRAM_TIMING 0x54
+#define DRAM_ROW_BNDRY_0 0x55
+#define DRAM_ROW_BNDRY_1 0x56
+
+#define DPMS_SYNC_SELECT 0x61
+#define VSYNC_CNTL 0x08
+#define VSYNC_ON 0x00
+#define VSYNC_OFF 0x08
+#define HSYNC_CNTL 0x02
+#define HSYNC_ON 0x00
+#define HSYNC_OFF 0x02
+
+#define PIXPIPE_CONFIG_0 0x80
+#define DAC_8_BIT 0x80
+#define DAC_6_BIT 0x00
+#define HW_CURSOR_ENABLE 0x10
+#define EXTENDED_PALETTE 0x01
+
+#define PIXPIPE_CONFIG_1 0x81
+#define DISPLAY_COLOR_MODE 0x0F
+#define DISPLAY_VGA_MODE 0x00
+#define DISPLAY_8BPP_MODE 0x02
+#define DISPLAY_15BPP_MODE 0x04
+#define DISPLAY_16BPP_MODE 0x05
+#define DISPLAY_24BPP_MODE 0x06
+#define DISPLAY_32BPP_MODE 0x07
+
+#define PIXPIPE_CONFIG_2 0x82
+#define DISPLAY_GAMMA_ENABLE 0x08
+#define DISPLAY_GAMMA_DISABLE 0x00
+#define OVERLAY_GAMMA_ENABLE 0x04
+#define OVERLAY_GAMMA_DISABLE 0x00
+
+#define CURSOR_CONTROL 0xA0
+#define CURSOR_ORIGIN_SCREEN 0x00
+#define CURSOR_ORIGIN_DISPLAY 0x10
+#define CURSOR_MODE 0x07
+#define CURSOR_MODE_DISABLE 0x00
+#define CURSOR_MODE_32_4C_AX 0x01
+#define CURSOR_MODE_128_2C 0x02
+#define CURSOR_MODE_128_1C 0x03
+#define CURSOR_MODE_64_3C 0x04
+#define CURSOR_MODE_64_4C_AX 0x05
+#define CURSOR_MODE_64_4C 0x06
+#define CURSOR_MODE_RESERVED 0x07
+#define CURSOR_BASEADDR_LO 0xA2
+#define CURSOR_BASEADDR_HI 0xA3
+#define CURSOR_X_LO 0xA4
+#define CURSOR_X_HI 0xA5
+#define CURSOR_X_POS 0x00
+#define CURSOR_X_NEG 0x80
+#define CURSOR_Y_LO 0xA6
+#define CURSOR_Y_HI 0xA7
+#define CURSOR_Y_POS 0x00
+#define CURSOR_Y_NEG 0x80
+
+#define VCLK2_VCO_M 0xC8
+#define VCLK2_VCO_N 0xC9
+#define VCLK2_VCO_MN_MSBS 0xCA
+#define VCO_N_MSBS 0x30
+#define VCO_M_MSBS 0x03
+#define VCLK2_VCO_DIV_SEL 0xCB
+#define POST_DIV_SELECT 0x70
+#define POST_DIV_1 0x00
+#define POST_DIV_2 0x10
+#define POST_DIV_4 0x20
+#define POST_DIV_8 0x30
+#define POST_DIV_16 0x40
+#define POST_DIV_32 0x50
+#define VCO_LOOP_DIV_BY_4M 0x00
+#define VCO_LOOP_DIV_BY_16M 0x04
+#define REF_CLK_DIV_BY_5 0x02
+#define REF_DIV_4 0x00
+#define REF_DIV_1 0x01
+
+#define PLL_CNTL 0xCE
+#define PLL_MEMCLK_SEL 0x03
+#define PLL_MEMCLK__66667KHZ 0x00
+#define PLL_MEMCLK__75000KHZ 0x01
+#define PLL_MEMCLK__88889KHZ 0x02
+#define PLL_MEMCLK_100000KHZ 0x03
+
+/* Multimedia Extension Registers (MRX) */
+#define ACQ_CNTL_1 0x02
+#define ACQ_CNTL_2 0x03
+#define FRAME_CAP_MODE 0x01
+#define CONT_CAP_MODE 0x00
+#define SINGLE_CAP_MODE 0x01
+#define ACQ_CNTL_3 0x04
+#define COL_KEY_CNTL_1 0x3C
+#define BLANK_DISP_OVERLAY 0x20
+
+/* FIFOs */
+#define LP_FIFO 0x1000
+#define HP_FIFO 0x2000
+#define INSTPNT 0x3040
+#define LP_FIFO_COUNT 0x3040
+#define HP_FIFO_COUNT 0x3041
+
+/* FIFO Commands */
+#define CLIENT 0xE0000000
+#define CLIENT_2D 0x60000000
+
+/* Command Parser Mode Register */
+#define COMPARS 0x3038
+#define TWO_D_INST_DISABLE 0x08
+#define THREE_D_INST_DISABLE 0x04
+#define STATE_VAR_UPDATE_DISABLE 0x02
+#define PAL_STIP_DISABLE 0x01
+
+/* Interrupt Control Registers */
+#define IER 0x3030
+#define IIR 0x3032
+#define IMR 0x3034
+#define ISR 0x3036
+#define VMIINTB_EVENT 0x2000
+#define GPIO4_INT 0x1000
+#define DISP_FLIP_EVENT 0x0800
+#define DVD_PORT_DMA 0x0400
+#define DISP_VBLANK 0x0200
+#define FIFO_EMPTY_DMA_DONE 0x0100
+#define INST_PARSER_ERROR 0x0080
+#define USER_DEFINED 0x0040
+#define BREAKPOINT 0x0020
+#define DISP_HORIZ_COUNT 0x0010
+#define DISP_VSYNC 0x0008
+#define CAPTURE_HORIZ_COUNT 0x0004
+#define CAPTURE_VSYNC 0x0002
+#define THREE_D_PIPE_FLUSHED 0x0001
+
+/* FIFO Watermark and Burst Length Control Register */
+#define FWATER_BLC 0x00006000
+#define LMI_BURST_LENGTH 0x7F000000
+#define LMI_FIFO_WATERMARK 0x003F0000
+#define AGP_BURST_LENGTH 0x00007F00
+#define AGP_FIFO_WATERMARK 0x0000003F
+
+/* BitBLT Registers */
+#define SRC_DST_PITCH 0x00040000
+#define DST_PITCH 0x1FFF0000
+#define SRC_PITCH 0x00001FFF
+#define COLEXP_BG_COLOR 0x00040004
+#define COLEXP_FG_COLOR 0x00040008
+#define MONO_SRC_CNTL 0x0004000C
+#define MONO_USE_COLEXP 0x00000000
+#define MONO_USE_SRCEXP 0x08000000
+#define MONO_DATA_ALIGN 0x07000000
+#define MONO_BIT_ALIGN 0x01000000
+#define MONO_BYTE_ALIGN 0x02000000
+#define MONO_WORD_ALIGN 0x03000000
+#define MONO_DWORD_ALIGN 0x04000000
+#define MONO_QWORD_ALIGN 0x05000000
+#define MONO_SRC_INIT_DSCRD 0x003F0000
+#define MONO_SRC_RIGHT_CLIP 0x00003F00
+#define MONO_SRC_LEFT_CLIP 0x0000003F
+#define BITBLT_CONTROL 0x00040010
+#define BLTR_STATUS 0x80000000
+#define DYN_DEPTH 0x03000000
+#define DYN_DEPTH_8BPP 0x00000000
+#define DYN_DEPTH_16BPP 0x01000000
+#define DYN_DEPTH_24BPP 0x02000000
+#define DYN_DEPTH_32BPP 0x03000000 /* Not implemented on the i740 */
+#define DYN_DEPTH_ENABLE 0x00800000
+#define PAT_VERT_ALIGN 0x00700000
+#define SOLID_PAT_SELECT 0x00080000
+#define PAT_IS_IN_COLOR 0x00000000
+#define PAT_IS_MONO 0x00040000
+#define MONO_PAT_TRANSP 0x00020000
+#define COLOR_TRANSP_ROP 0x00000000
+#define COLOR_TRANSP_DST 0x00008000
+#define COLOR_TRANSP_EQ 0x00000000
+#define COLOR_TRANSP_NOT_EQ 0x00010000
+#define COLOR_TRANSP_ENABLE 0x00004000
+#define MONO_SRC_TRANSP 0x00002000
+#define SRC_IS_IN_COLOR 0x00000000
+#define SRC_IS_MONO 0x00001000
+#define SRC_USE_SRC_ADDR 0x00000000
+#define SRC_USE_BLTDATA 0x00000400
+#define BLT_TOP_TO_BOT 0x00000000
+#define BLT_BOT_TO_TOP 0x00000200
+#define BLT_LEFT_TO_RIGHT 0x00000000
+#define BLT_RIGHT_TO_LEFT 0x00000100
+#define BLT_ROP 0x000000FF
+#define BLT_PAT_ADDR 0x00040014
+#define BLT_SRC_ADDR 0x00040018
+#define BLT_DST_ADDR 0x0004001C
+#define BLT_DST_H_W 0x00040020
+#define BLT_DST_HEIGHT 0x1FFF0000
+#define BLT_DST_WIDTH 0x00001FFF
+#define SRCEXP_BG_COLOR 0x00040024
+#define SRCEXP_FG_COLOR 0x00040028
+#define BLTDATA 0x00050000
+
+typedef struct {
+ unsigned int cmd;
+ unsigned int BR00;
+ unsigned int BR01;
+ unsigned int BR02;
+ unsigned int BR03;
+ unsigned int BR04;
+ unsigned int BR05;
+ unsigned int BR06;
+ unsigned int BR07;
+ unsigned int BR09;
+ unsigned int BR0A;
+ unsigned int BR08;
+} GFX2DOPREG_BLTER_FULL_LOAD;
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile
new file mode 100644
index 000000000..e9a42442d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile
@@ -0,0 +1,67 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/Imakefile,v 1.26 1999/08/21 13:48:34 dawes Exp $
+XCOMM
+XCOMM This is an Imakefile for the MGA driver.
+XCOMM
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = mga_driver.c mga_hwcurs.c /* mga_cmap.c */ mga_dac3026.c mga_dacG.c \
+ mga_storm8.c mga_storm16.c mga_storm24.c mga_storm32.c mga_arc.c \
+ mga_dga.c mga_shadow.c
+OBJS = mga_driver.o mga_hwcurs.o /* mga_cmap.o */ mga_dac3026.o mga_dacG.o \
+ mga_storm8.o mga_storm16.o mga_storm24.o mga_storm32.o mga_arc.o \
+ mga_dga.o mga_shadow.o
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa -I$(XF86SRC)/rac \
+ -I$(XF86SRC)/vgahw -I$(XF86SRC)/fbdevhw \
+ -I$(XF86SRC)/ramdac -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
+ -I$(SERVERSRC)/Xext -I$(XF86SRC)/xf8_32bpp\
+ -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(XF86SRC)/xf24_32bpp -I$(XF86SRC)/shadowfb -I$(EXTINCSRC)
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget(mga,$(OBJS))
+
+ObjectFromSpecialSource(mga_storm8, mga_storm, -DPSZ=8)
+ObjectFromSpecialSource(mga_storm16, mga_storm, -DPSZ=16)
+ObjectFromSpecialSource(mga_storm24, mga_storm, -DPSZ=24)
+ObjectFromSpecialSource(mga_storm32, mga_storm, -DPSZ=32)
+
+InstallObjectModule(mga,$(MODULEDIR),drivers)
+
+#if !defined(XF86DriverSDK)
+CppManTarget(mga,)
+InstallModuleManPage(mga)
+#endif
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/mga)
+InstallDriverSDKNonExecFile(mga.h,$(DRIVERSDKDIR)/drivers/mga)
+InstallDriverSDKNonExecFile(mga_arc.c,$(DRIVERSDKDIR)/drivers/mga)
+InstallDriverSDKNonExecFile(mga_bios.h,$(DRIVERSDKDIR)/drivers/mga)
+InstallDriverSDKNonExecFile(mga_dac3026.c,$(DRIVERSDKDIR)/drivers/mga)
+InstallDriverSDKNonExecFile(mga_dacG.c,$(DRIVERSDKDIR)/drivers/mga)
+InstallDriverSDKNonExecFile(mga_dga.c,$(DRIVERSDKDIR)/drivers/mga)
+InstallDriverSDKNonExecFile(mga_driver.c,$(DRIVERSDKDIR)/drivers/mga)
+InstallDriverSDKNonExecFile(mga_hwcurs.c,$(DRIVERSDKDIR)/drivers/mga)
+InstallDriverSDKNonExecFile(mga_macros.h,$(DRIVERSDKDIR)/drivers/mga)
+InstallDriverSDKNonExecFile(mga_map.h,$(DRIVERSDKDIR)/drivers/mga)
+InstallDriverSDKNonExecFile(mga_reg.h,$(DRIVERSDKDIR)/drivers/mga)
+InstallDriverSDKNonExecFile(mga_shadow.c,$(DRIVERSDKDIR)/drivers/mga)
+InstallDriverSDKNonExecFile(mga_storm.c,$(DRIVERSDKDIR)/drivers/mga)
+
+InstallDriverSDKObjectModule(mga,$(DRIVERSDKMODULEDIR),drivers)
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/README b/xc/programs/Xserver/hw/xfree86/drivers/mga/README
new file mode 100644
index 000000000..4ebb3533a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/README
@@ -0,0 +1,185 @@
+$XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/README,v 1.5 1997/09/09 10:27:45 hohndel Exp $
+
+MGA Millennium (MGA2064W) with TVP3026 RAMDAC Driver v1.3
+=========================================================
+MGA Mystique (MGA1064W) with integrated RAMDAC Driver v1.3
+=========================================================
+MGA Millennium II (MGA2164W) with TVP3026 RAMDAC Driver v1.3
+
+NOTE: This driver is fairly new, and not everything works like you expect
+it to. It shouldn't crash your machine, and there are problems with 24 bpp,
+but it should work pretty well. Please report any and all problems to
+XFree86@Xfree86.org using the appropriate bug report sheet.
+
+Features:
+---------
+
+* Supports the Matrox Millennium, Mystique and Millennium II adapters
+* Can only use a linear frame buffer
+* It should be possible to reach resolutions up to 1920x1024 or 1600x1200
+* It should be possible to use pixel depths of:
+ - 8 bits per pixel (256 pseudo colour)
+ - 16 bits per pixel (high colour)
+ - 24 bits per pixel (packed true colour) **
+ - 32 bits per pixel (true colour)
+
+There are some 24 bpp mode problems - tiling doesn't work properly, so for some
+programs, notably Netscape, gimp, xsetroot, etc, you may see corrupted images.
+
+Planned Features
+----------------
+
+In order from highest to lowest priority:
+
+* More accurate rendering at all speeds
+* More reliability, especially in autodetection
+* 3D acceleration
+
+Technical Notes:
+----------------
+
+Hardware Supported:
+-------------------
+
+Matrox Millennium I rev 1 and 2
+- with TVP3026 RAMDAC at 175, 220, 250 MHz
+Matrox Millennium II rev 1
+- with TVP3026 RAMDAC at 220 MHz
+Matrox Mystique rev 1
+- with internal RAMDAC at 135 (rare), 170, and 220 MHz
+
+The driver autodetects the amount of video memory availble (for both SGRAM
+and WRAM models), so it is unnecessary to specify the VideoMem option.
+
+Support for other Matrox cards is planned, pending the receipt of documentation
+from Matrox.
+
+Configuration:
+--------------
+
+The driver auto-detects all device info included memory size, so use the following device
+section in your XF86Config file:
+
+- for Millenium board:
+----------------------
+ Section "Device"
+ Identifier "Matrox Millennium"
+ VendorName "Matrox"
+ BoardName "Millennium"
+ EndSection
+
+- for Mystique board:
+- - - - - - - - - - -
+ Section "Device"
+ Identifier "Mystique"
+ VendorName "Matrox"
+ BoardName "mga1064sg"
+ EndSection
+
+or let xf86config or XF86Setup do this for you.
+
+But if you have problems with auto-detection, you can specify:
+
+ VideoRam - in kilobytes
+ DacSpeed - in MHz
+ MemBase - physical address of the linear framebuffer
+ IoBase - physical address of the memory mapped IO registers
+ BiosBase - physical address of BIOS
+
+
+Driver Options:
+---------------
+
+"noaccel" - turns off Drawing Engine (mandatory for Mystique)
+"sw_cursor" - turns hardware cursor off
+"xaa_benchmark" - do some benchmarks during startup
+
+- for Mystique board:
+- - - - - - - - - - -
+Interleaved features are not available
+
+Memory Clock Hack
+-----------------
+
+- for Millenium and Millennium II adapter:
+- - - - - - - - - - -
+
+It seems some Millenniums have a BIOS that defines the memory clock
+for 2 MB and 4 MB cards to be 50 MHz, while others define it to be
+60 MHz. Using the faster clock speeds up drawing operations a good
+amount, so a hack has been put in place to set MCLK from XF86Config.
+
+In the file mga_dac3026.c, simply change the following line:
+ #define MCLK_FROM_XCONFIG 0
+to this:
+ #define MCLK_FROM_XCONFIG 1
+
+and specify in XF86Config:
+
+ Set_Mclk - in MHz
+
+USE THIS HACK ENTIRELY AT YOUR OWN RISK!!!!!!!!!!!!
+
+Using memory clocks from 40 to 50 MHz should be completely safe. Setting
+the memory clock higher than 50 MHz, up to 65 MHz has been tested, and
+seems to work. DO NOT EXCEED 65 MHz, or the video memory contents will
+become corrupted and you may damage the card!
+
+The Millennium II is automatically set to 60 MHz, so this hack is of limited
+use. It also has the ability to tune itself for 4, 8, 12 and 16 MB of WRAM
+installed. We recommend against using this option on the Millennium II at
+this time.
+
+- for Mystique board:
+- - - - - - - - - - -
+MCLK_FROM_XCONFIG flag has no effect.
+
+Main author:
+------------
+
+Radoslaw Kapitan, Tarnow, Poland
+kapitan@student.uci.agh.edu.pl
+
+Code, Additions and Testing:
+----------------------------
+
+Andrew E. Mileski, Ottawa, Canada
+aem@ott.hookup.net
+
+Andrew van der Stock, Melbourne, Australia
+Andrew.van.der.Stock@member.sage-au.org.au
+
+Angsar Hockmann
+Ansgar.Hockmann@hrz.uni-dortmund.de
+
+A Joseph Koshy, Tester
+koshy@india.hp.com
+
+Leonard N. Zubkoff
+lnz@dandelion.com
+
+Mark Vojkovich
+mvojkovi@sdcc10.ucsd.edu
+
+Michael Will
+zxmgv07@student.uni-tuebingen.de
+
+Guy DESBIEF
+g.desbief@aix.pacwan.net
+
+XAA
+---
+
+Harm Hanemaayer
+mailto:H.Hanemaayer@inter.nl.net
+
+Various hacks, features and patcher
+-----------------------------------
+
+Dirk Hohndel
+hohndel@XFree86.Org
+
+Visit the Matrox Millennium XServer for XFree86 Home Page:
+ http://www.bf.rmit.edu.au/~ajv/xf86-matrox.html
+to keep upto date with the latest news.
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.cpp b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.cpp
new file mode 100644
index 000000000..9711e40d1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.cpp
@@ -0,0 +1,122 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga.cpp,v 1.9 1999/08/28 10:43:36 dawes Exp $
+.TH MGA __drivermansuffix__ "Version 3.9.16" "XFree86"
+.SH NAME
+mga \- Matrox video driver
+.SH SYNOPSIS
+.B "Section ""Device"""
+.br
+.BI " Identifier """ devname """"
+.br
+.B " Driver ""mga"""
+.br
+\ \ ...
+.br
+.B EndSection
+.SH DESCRIPTION
+.B mga
+is an XFree86 driver for Matrox video cards. The driver is fully
+accelerated, and provides support for the following framebuffer depths:
+8, 15, 16, 24, and an 8+24 overlay mode (all chips except G100). All
+visual types are supported for depth 8, and both TrueColor and DirectColor
+visuals are supported for the other depths except 8+24 mode which supports
+PseudoColor, GrayScale and TrueColor. Multi-head configurations
+are supported.
+.SH SUPPORTED HARDWARE
+The
+.B mga
+driver supports PCI and AGP video cards based on the following Matrox chips:
+.TP 12
+.B MGA2064W
+Millennium (original)
+.TP 12
+.B MGA1064SG
+Mystique
+.TP 12
+.B MGA2164W
+Millennium II
+.TP 12
+.B G100
+.TP 12
+.B G200
+Millennium G200 and Mystique G200
+.TP 12
+.B G400
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details. This section only covers configuration details specific to this
+driver.
+.PP
+The driver auto-detects the chipset type, but the following
+.B ChipSet
+names may optionally be specified in the config file
+.B """Device"""
+section, and will override the auto-detection:
+.PP
+.RS 4
+"mga2064w", "mga1064sg", "mga2164w", "mga2164w agp", "mgag100", "mgag200",
+"mgag200 pci" "mgag400".
+.RE
+.PP
+The driver will auto-detect the amount of video memory present for all
+chips except the Millennium II. In the Millennium II case it defaults
+to 4096\ kBytes. When using a Millennium II, the actual amount of video
+memory should be specified with a
+.B VideoRam
+entry in the config file
+.B """Device"""
+section.
+.PP
+The following driver
+.B Options
+are supported:
+.TP
+.BI "Option ""ColorKey"" """ integer """
+Set the colormap index used for the transparency key for the depth 8 plane
+when operating in 8+24 overlay mode. The value must be in the range
+2\-255. Default: 255.
+.TP
+.BI "Option ""HWCursor"" """ boolean """
+Enable or disable the HW cursor. Default: on.
+.TP
+.BI "Option ""MGASDRAM"" """ boolean """
+Specify whether G100 and G200 cards have SDRAM. The driver attempts to
+auto-detect this based on the card's PCI subsystem ID. This option may
+be used to override that auto-detection. Default: auto-detected.
+.TP
+.BI "Option ""NoAccel"" """ boolean """
+Disable or enable acceleration. Default: acceleration is enabled.
+.TP
+.BI "Option ""OverclockMem""
+Set clocks to values used by some commercial X-Servers (G100, G200 and G400
+only). Default: off.
+.TP
+.BI "Option ""Overlay""
+Enable 8+24 overlay mode. Only appropriate for depth 24. Default: off.
+.TP
+.BI "Option ""PciRetry"" """ boolean """
+Enable or disable PCI retries. Default: off.
+.TP
+.BI "Option ""Rotate"" ""CW""
+.TP
+.BI "Option ""Rotate"" ""CCW""
+Rotate the display clockwise or counterclockwise. This mode is unaccelerated.
+Default: no rotation.
+.TP
+.BI "Option ""ShadowFB"" """ boolean """
+Enable or disable use of the shadow framebuffer layer. See
+shadowfb(__drivermansuffix__) for further information. Default: off.
+.TP
+.BI "Option ""SyncOnGreen"" """ boolean """
+Enable or disable combining the sync signals with the green signal.
+Default: off.
+.TP
+.BI "Option ""UseFBDev"" """ boolean """
+Enable or disable use of on OS-specific fb interface (and is not supported
+on all OSs). See fbdevhw(__drivermansuffix__) for further information.
+Default: off.
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(1)
+.SH AUTHORS
+Authors include: Radoslaw Kapitan, Mark Vojkovich, and also David Dawes, Guy
+Desbief, Dirk Hohndel, Doug Merritt, Andrew E. Mileski, Andrew Vanderstock,
+Leonard N. Zubkoff.
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h
new file mode 100644
index 000000000..bc927c8a4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h
@@ -0,0 +1,271 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga.h,v 1.47 1999/08/22 05:57:33 dawes Exp $ */
+/*
+ * MGA Millennium (MGA2064W) functions
+ *
+ * Copyright 1996 The XFree86 Project, Inc.
+ *
+ * Authors
+ * Dirk Hohndel
+ * hohndel@XFree86.Org
+ * David Dawes
+ * dawes@XFree86.Org
+ */
+
+#ifndef MGA_H
+#define MGA_H
+
+#include "xaa.h"
+#include "xf86Cursor.h"
+#include "vgaHW.h"
+#include "colormapst.h"
+#include "xf86DDC.h"
+
+#if defined(__alpha__)
+#define INREG8(addr) xf86ReadSparse8(pMga->IOBase, (addr))
+#define INREG16(addr) xf86ReadSparse16(pMga->IOBase, (addr))
+#define INREG(addr) xf86ReadSparse32(pMga->IOBase, (addr))
+#define OUTREG8(addr,val) xf86WriteSparse8((val),pMga->IOBase,(addr))
+#define OUTREG16(addr,val) xf86WriteSparse16((val),pMga->IOBase,(addr))
+#define OUTREG(addr, val) xf86WriteSparse32((val),pMga->IOBase,(addr))
+#else /* __alpha__ */
+#if defined(EXTRADEBUG)
+CARD8 dbg_inreg8(ScrnInfoPtr,int,int);
+CARD16 dbg_inreg16(ScrnInfoPtr,int,int);
+CARD32 dbg_inreg32(ScrnInfoPtr,int,int);
+void dbg_outreg8(ScrnInfoPtr,int,int);
+void dbg_outreg16(ScrnInfoPtr,int,int);
+void dbg_outreg32(ScrnInfoPtr,int,int);
+#define INREG8(addr) dbg_inreg8(pScrn,addr,1)
+#define INREG16(addr) dbg_inreg16(pScrn,addr,1)
+#define INREG(addr) dbg_inreg32(pScrn,addr,1)
+#define OUTREG8(addr,val) dbg_outreg8(pScrn,addr,val)
+#define OUTREG16(addr,val) dbg_outreg16(pScrn,addr,val)
+#define OUTREG(addr,val) dbg_outreg32(pScrn,addr,val)
+#else /* EXTRADEBUG */
+#define INREG8(addr) *(volatile CARD8 *)(pMga->IOBase + (addr))
+#define INREG16(addr) *(volatile CARD16 *)(pMga->IOBase + (addr))
+#define INREG(addr) *(volatile CARD32 *)(pMga->IOBase + (addr))
+#define OUTREG8(addr, val) *(volatile CARD8 *)(pMga->IOBase + (addr)) = (val)
+#define OUTREG16(addr, val) *(volatile CARD16 *)(pMga->IOBase + (addr)) = (val)
+#define OUTREG(addr, val) *(volatile CARD32 *)(pMga->IOBase + (addr)) = (val)
+#endif /* EXTRADEBUG */
+#endif /* __alpha__ */
+
+#define PORT_OFFSET (0x1F00 - 0x300)
+
+typedef struct {
+ unsigned char ExtVga[6];
+ unsigned char DacClk[6];
+ unsigned char * DacRegs;
+ CARD32 Option;
+ CARD32 Option2;
+ CARD32 Option3;
+} MGARegRec, *MGARegPtr;
+
+typedef struct {
+ Bool isHwCursor;
+ int CursorMaxWidth;
+ int CursorMaxHeight;
+ int CursorFlags;
+ int CursorOffscreenMemSize;
+ Bool (*UseHWCursor)(ScreenPtr, CursorPtr);
+ void (*LoadCursorImage)(ScrnInfoPtr, unsigned char*);
+ void (*ShowCursor)(ScrnInfoPtr);
+ void (*HideCursor)(ScrnInfoPtr);
+ void (*SetCursorPosition)(ScrnInfoPtr, int, int);
+ void (*SetCursorColors)(ScrnInfoPtr, int, int);
+ long maxPixelClock;
+ long MemoryClock;
+ MessageType ClockFrom;
+ MessageType MemClkFrom;
+ Bool SetMemClk;
+ void (*LoadPalette)(ScrnInfoPtr, int, int*, LOCO*, VisualPtr);
+ void (*PreInit)(ScrnInfoPtr);
+ void (*Save)(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool);
+ void (*Restore)(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool);
+ Bool (*ModeInit)(ScrnInfoPtr, DisplayModePtr);
+} MGARamdacRec, *MGARamdacPtr;
+
+
+typedef struct {
+ int bitsPerPixel;
+ int depth;
+ int displayWidth;
+ rgb weight;
+ Bool Overlay8Plus24;
+} MGAFBLayout;
+
+
+/* Card-specific driver information */
+
+#define MGAPTR(p) ((MGAPtr)((p)->driverPrivate))
+
+#ifdef DISABLE_VGA_IO
+typedef struct mgaSave {
+ pciVideoPtr pvp;
+ Bool enable;
+} MgaSave, *MgaSavePtr;
+#endif
+
+typedef struct {
+ EntityInfoPtr pEnt;
+ MGABiosInfo Bios;
+ MGABios2Info Bios2;
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ xf86AccessRec Access;
+ int Chipset;
+ int ChipRev;
+ Bool Primary;
+ Bool Interleave;
+ int HwBpp;
+ int Roundings[4];
+ int BppShifts[4];
+ Bool HasFBitBlt;
+ Bool OverclockMem;
+ int YDstOrg;
+ int DstOrg;
+ int SrcOrg;
+ CARD32 IOAddress;
+ CARD32 FbAddress;
+ CARD32 ILOADAddress;
+ int FbBaseReg;
+ CARD32 BiosAddress;
+ MessageType BiosFrom;
+ unsigned char * IOBase;
+#ifdef __alpha__
+ unsigned char * IOBaseDense;
+#endif
+ unsigned char * FbBase;
+ unsigned char * ILOADBase;
+ unsigned char * FbStart;
+ long FbMapSize;
+ long FbUsableSize;
+ long FbCursorOffset;
+ MGARamdacRec Dac;
+ Bool HasSDRAM;
+ Bool NoAccel;
+ Bool SyncOnGreen;
+ Bool Dac6Bit;
+ Bool HWCursor;
+ Bool UsePCIRetry;
+ Bool ShowCache;
+ Bool Overlay8Plus24;
+ Bool ShadowFB;
+ unsigned char * ShadowPtr;
+ int ShadowPitch;
+ int MemClk;
+ int MinClock;
+ int MaxClock;
+ MGARegRec SavedReg;
+ MGARegRec ModeReg;
+ int MaxFastBlitY;
+ CARD32 BltScanDirection;
+ CARD32 FilledRectCMD;
+ CARD32 SolidLineCMD;
+ CARD32 PatternRectCMD;
+ CARD32 DashCMD;
+ CARD32 NiceDashCMD;
+ CARD32 AccelFlags;
+ CARD32 PlaneMask;
+ CARD32 FgColor;
+ CARD32 BgColor;
+ int StyleLen;
+ XAAInfoRecPtr AccelInfoRec;
+ xf86CursorInfoPtr CursorInfoRec;
+ DGAModePtr DGAModes;
+ int numDGAModes;
+ Bool DGAactive;
+ int DGAViewportStatus;
+ CARD32 *Atype;
+ CARD32 *AtypeNoBLK;
+ void (*PreInit)(ScrnInfoPtr pScrn);
+ void (*Save)(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool);
+ void (*Restore)(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool);
+ Bool (*ModeInit)(ScrnInfoPtr, DisplayModePtr);
+ void (*PointerMoved)(int index, int x, int y);
+ CloseScreenProcPtr CloseScreen;
+ unsigned int (*ddc1Read)(ScrnInfoPtr);
+ void (*DDC1SetSpeed)(ScrnInfoPtr, xf86ddcSpeed);
+ Bool (*i2cInit)(ScrnInfoPtr);
+ I2CBusPtr I2C;
+ Bool FBDev;
+ int colorKey;
+ int fifoCount;
+ int Rotate;
+ MGAFBLayout CurrentLayout;
+ Bool DrawTransparent;
+ int MaxBlitDWORDS;
+} MGARec, *MGAPtr;
+
+extern CARD32 MGAAtype[16];
+extern CARD32 MGAAtypeNoBLK[16];
+
+#define USE_RECTS_FOR_LINES 0x00000001
+#define FASTBLT_BUG 0x00000002
+#define CLIPPER_ON 0x00000004
+#define BLK_OPAQUE_EXPANSION 0x00000008
+#define TRANSC_SOLID_FILL 0x00000010
+#define NICE_DASH_PATTERN 0x00000020
+#define TWO_PASS_COLOR_EXPAND 0x00000040
+#define MGA_NO_PLANEMASK 0x00000080
+#define USE_LINEAR_EXPANSION 0x00000100
+#define LARGE_ADDRESSES 0x00000200
+
+
+#define TRANSPARENCY_KEY 255
+#define KEY_COLOR 0
+
+/* Prototypes */
+
+void MGAAdjustFrame(int scrnIndex, int x, int y, int flags);
+Bool MGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+
+void MGA2064SetupFuncs(ScrnInfoPtr pScrn);
+void MGAGSetupFuncs(ScrnInfoPtr pScrn);
+
+void MGAStormSync(ScrnInfoPtr pScrn);
+void MGAStormEngineInit(ScrnInfoPtr pScrn);
+Bool MGAStormAccelInit(ScreenPtr pScreen);
+Bool MGAHWCursorInit(ScreenPtr pScreen);
+
+Bool Mga8AccelInit(ScreenPtr pScreen);
+Bool Mga16AccelInit(ScreenPtr pScreen);
+Bool Mga24AccelInit(ScreenPtr pScreen);
+Bool Mga32AccelInit(ScreenPtr pScreen);
+
+void MGAPolyArcThinSolid(DrawablePtr, GCPtr, int, xArc*);
+
+Bool MGADGAInit(ScreenPtr pScreen);
+
+void MGARefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void MGARefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void MGARefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void MGARefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+void MGARefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+
+void Mga8SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
+ int ydir, int rop, unsigned int planemask,
+ int trans);
+void Mga16SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
+ int ydir, int rop, unsigned int planemask,
+ int trans);
+void Mga24SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
+ int ydir, int rop, unsigned int planemask,
+ int trans);
+void Mga32SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
+ int ydir, int rop, unsigned int planemask,
+ int trans);
+
+void Mga8SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+void Mga16SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+void Mga24SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+void Mga32SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+
+void MGAPointerMoved(int index, int x, int y);
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_arc.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_arc.c
new file mode 100644
index 000000000..2844302ff
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_arc.c
@@ -0,0 +1,217 @@
+/************************************************************
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+********************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_arc.c,v 1.7 1999/08/22 05:57:33 dawes Exp $ */
+
+
+#include "X.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "Xprotostr.h"
+#include "miscstruct.h"
+#include "mizerarc.h"
+#include "mi.h"
+#include "scrnintstr.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xf86_ansic.h"
+
+#include "xf86Pci.h"
+
+#include "mga_bios.h"
+#include "mga.h"
+#include "mga_reg.h"
+#include "mga_macros.h"
+
+
+/*
+ This is only faster than cfb for stuff other than GXcopy.
+ And even then, only when pci_retries are on.
+*/
+
+
+#define DRAW_POINT(x, y) { \
+ tmp = x; \
+ OUTREG(MGAREG_FXBNDRY, (tmp) | (((tmp) + 1) << 16)); \
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, ((y) << 16) | 1); \
+}
+
+static void
+MGAZeroArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ xArc *arc
+){
+ int yoffset, dyoffset, x, y, a, b, d, mask, k1, k3, dx, dy, tmp;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ MGAPtr pMga = MGAPTR(infoRec->pScrn);
+ miZeroArcRec info;
+ Bool do360;
+ DDXPointRec org, orgo;
+
+ (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel,
+ pGC->alu, pGC->planemask);
+
+ do360 = miZeroArcSetup(arc, &info, TRUE);
+ org.y = info.yorg + pDraw->y;
+ org.x = 0;
+ orgo.y = info.yorgo + pDraw->y;
+ orgo.x = 0;
+ info.xorg += pDraw->x;
+ info.xorgo += pDraw->x;
+
+ MIARCSETUP();
+ yoffset = y ? 1 : 0;
+ dyoffset = 0;
+ mask = info.initialMask;
+ if (!(arc->width & 1)) {
+ WAITFIFO(4);
+ if (mask & 2)
+ DRAW_POINT(info.xorgo, org.y);
+ if (mask & 8)
+ DRAW_POINT(info.xorgo, orgo.y);
+ }
+ if (!info.end.x || !info.end.y) {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ if (do360 && (arc->width == arc->height) && !(arc->width & 1)) {
+ int xoffset = 1;
+ DDXPointRec orghb, orgohb;
+
+ orghb.y = org.y + info.h;
+ orghb.x = org.x + info.xorg;
+ orgohb.y = orghb.y;
+ orgohb.x = orghb.x - info.h;
+
+ org.x += info.xorg;
+ orgo.x += info.xorg;
+ orghb.x += info.h;
+ while (1) {
+ WAITFIFO(16);
+ DRAW_POINT(org.x + x, org.y + yoffset);
+ DRAW_POINT(org.x - x, org.y + yoffset);
+ DRAW_POINT(orgo.x - x, orgo.y - yoffset);
+ DRAW_POINT(orgo.x + x, orgo.y - yoffset);
+ if (a < 0) break;
+ DRAW_POINT(orghb.x - y, orghb.y - xoffset);
+ DRAW_POINT(orgohb.x + y, orgohb.y - xoffset);
+ DRAW_POINT(orgohb.x + y, orgohb.y + xoffset);
+ DRAW_POINT(orghb.x - y, orghb.y + xoffset);
+ xoffset ++;
+ MIARCCIRCLESTEP(yoffset ++;);
+ }
+ org.x -= info.xorg;
+ orgo.x -= info.xorg;
+ x = info.w;
+ yoffset = info.h;
+ }
+ else if (do360) {
+ while (y < info.h || x < info.w) {
+ MIARCOCTANTSHIFT(dyoffset = 1;);
+ WAITFIFO(8);
+ DRAW_POINT(org.x + info.xorg + x, org.y + yoffset);
+ DRAW_POINT(org.x + info.xorgo - x, org.y + yoffset);
+ DRAW_POINT(orgo.x + info.xorgo - x, orgo.y - yoffset);
+ DRAW_POINT(orgo.x + info.xorg + x, orgo.y - yoffset);
+ MIARCSTEP(yoffset += dyoffset;, yoffset++;);
+ }
+ }
+ else {
+ while (y < info.h || x < info.w) {
+ MIARCOCTANTSHIFT(dyoffset = 1;);
+ if ((x == info.start.x) || (y == info.start.y)) {
+ mask = info.start.mask;
+ info.start = info.altstart;
+ }
+ WAITFIFO(8);
+ if (mask & 1)
+ DRAW_POINT(org.x + info.xorg + x, org.y + yoffset);
+ if (mask & 2)
+ DRAW_POINT(org.x + info.xorgo - x, org.y + yoffset);
+ if (mask & 4)
+ DRAW_POINT(orgo.x + info.xorgo - x, orgo.y - yoffset);
+ if (mask & 8)
+ DRAW_POINT(orgo.x + info.xorg + x, orgo.y - yoffset);
+ if ((x == info.end.x) || (y == info.end.y)) {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ MIARCSTEP(yoffset += dyoffset;, yoffset++;);
+ }
+ }
+ if ((x == info.start.x) || (y == info.start.y))
+ mask = info.start.mask;
+
+ WAITFIFO(4);
+ if (mask & 1)
+ DRAW_POINT(org.x + info.xorg + x, org.y + yoffset);
+ if (mask & 4)
+ DRAW_POINT(orgo.x + info.xorgo - x, orgo.y - yoffset);
+ if (arc->height & 1) {
+ WAITFIFO(4);
+ if (mask & 2)
+ DRAW_POINT(org.x + info.xorgo - x, org.y + yoffset);
+ if (mask & 8)
+ DRAW_POINT(orgo.x + info.xorg + x, orgo.y - yoffset);
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+void
+MGAPolyArcThinSolid (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ xArc *arc;
+ BoxRec box;
+ int i, x2, y2;
+ RegionPtr cclip;
+
+ cclip = pGC->pCompositeClip;
+
+ if(!REGION_NUM_RECTS(cclip))
+ return;
+
+ for (arc = parcs, i = narcs; --i >= 0; arc++) {
+ if (miCanZeroArc(arc)) {
+ box.x1 = arc->x + pDraw->x;
+ box.y1 = arc->y + pDraw->y;
+ x2 = box.x1 + (int)arc->width + 1;
+ box.x2 = x2;
+ y2 = box.y1 + (int)arc->height + 1;
+ box.y2 = y2;
+ if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) &&
+ (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
+ MGAZeroArc (pDraw, pGC, arc);
+ else
+ miZeroPolyArc(pDraw, pGC, 1, arc);
+ }
+ else
+ miPolyArc(pDraw, pGC, 1, arc);
+ }
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_bios.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_bios.h
new file mode 100644
index 000000000..120c73930
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_bios.h
@@ -0,0 +1,143 @@
+/* $XConsortium: mga_bios.h /main/2 1996/10/28 04:48:23 kaleb $ */
+#ifndef MGA_BIOS_H
+#define MGA_BIOS_H
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_bios.h,v 1.3 1998/07/25 16:55:51 dawes Exp $ */
+
+/*
+ * MGABiosInfo - This struct describes the video BIOS info block.
+ *
+ * DESCRIPTION
+ * Do not mess with this, unless you know what you are doing.
+ * The data lengths and types are critical.
+ *
+ * HISTORY
+ * October 7, 1996 - [aem] Andrew E. Mileski
+ * This struct was shamelessly stolen from the MGA DDK.
+ * It has been reformatted, and the data types changed.
+ */
+typedef struct {
+ /* Length of this structure in bytes */
+ CARD16 StructLen;
+
+ /*
+ * Unique number identifying the product type
+ * 0 : MGA-S1P20 (2MB base with 175MHz Ramdac)
+ * 1 : MGA-S1P21 (2MB base with 220MHz Ramdac)
+ * 2 : Reserved
+ * 3 : Reserved
+ * 4 : MGA-S1P40 (4MB base with 175MHz Ramdac)
+ * 5 : MGA-S1P41 (4MB base with 220MHz Ramdac)
+ */
+ CARD16 ProductID;
+
+ /* Serial number of the board */
+ CARD8 SerNo[ 10 ];
+
+ /*
+ * Manufacturing date of the board (at product test)
+ * Format: yyyy yyym mmmd dddd
+ */
+ CARD16 ManufDate;
+
+ /* Identification of manufacturing site */
+ CARD16 ManufId;
+
+ /*
+ * Number and revision level of the PCB
+ * Format: nnnn nnnn nnnr rrrr
+ * n = PCB number ex:576 (from 0->2047)
+ * r = PCB revision (from 0->31)
+ */
+ CARD16 PCBInfo;
+
+ /* Identification of any PMBs */
+ CARD16 PMBInfo;
+
+ /*
+ * Bit 0-7 : Ramdac speed (0=175MHz, 1=220MHz)
+ * Bit 8-15 : Ramdac type (0=TVP3026, 1=TVP3027)
+ */
+ CARD16 RamdacType;
+
+ /* Maximum PCLK of the ramdac */
+ CARD16 PclkMax;
+
+ /* Maximum LDCLK supported by the WRAM memory */
+ CARD16 LclkMax;
+
+ /* Maximum MCLK of base board */
+ CARD16 ClkBase;
+
+ /* Maximum MCLK of 4Mb board */
+ CARD16 Clk4MB;
+
+ /* Maximum MCLK of 8Mb board */
+ CARD16 Clk8MB;
+
+ /* Maximum MCLK of board with multimedia module */
+ CARD16 ClkMod;
+
+ /* Diagnostic test pass frequency */
+ CARD16 TestClk;
+
+ /* Default VGA mode1 pixel frequency */
+ CARD16 VGAFreq1;
+
+ /* Default VGA mode2 pixel frequency */
+ CARD16 VGAFreq2;
+
+ /* Date of last BIOS programming/update */
+ CARD16 ProgramDate;
+
+ /* Number of times BIOS has been programmed */
+ CARD16 ProgramCnt;
+
+ /* Support for up to 32 hardware/software options */
+ CARD32 Options;
+
+ /* Support for up to 32 hardware/software features */
+ CARD32 FeatFlag;
+
+ /* Definition of VGA mode MCLK */
+ CARD16 VGAClk;
+
+ /* Indicate the revision level of this header struct */
+ CARD16 StructRev;
+
+ CARD16 Reserved[ 3 ];
+} MGABiosInfo;
+
+/* from the PINS structure, refer pins info from MGA */
+typedef struct tagParamMGA {
+ CARD16 PinID; /* 0 */
+ CARD8 StructLen; /* 2 */
+ CARD8 Rsvd1; /* 3 */
+ CARD16 StructRev; /* 4 */
+ CARD16 ProgramDate; /* 6 */
+ CARD16 ProgramCnt; /* 8 */
+ CARD16 ProductID; /* 10 */
+ CARD8 SerNo[16]; /* 12 */
+ CARD8 PLInfo[6]; /* 28 */
+ CARD16 PCBInfo; /* 34 */
+ CARD32 FeatFlag; /* 36 */
+ CARD8 RamdacType; /* 40 */
+ CARD8 RamdacSpeed; /* 41 */
+ CARD8 PclkMax; /* 42 */
+ CARD8 ClkGE; /* 43 */
+ CARD8 ClkMem; /* 44 */
+ CARD8 Clk4MB; /* 45 */
+ CARD8 Clk8MB; /* 46 */
+ CARD8 ClkMod; /* 47 */
+ CARD8 TestClk; /* 48 */
+ CARD8 VGAFreq1; /* 49 */
+ CARD8 VGAFreq2; /* 50 */
+ CARD8 MCTLWTST; /* 51 */
+ CARD8 VidCtrl; /* 52 */
+ CARD8 Clk12MB; /* 53 */
+ CARD8 Clk16MB; /* 54 */
+ CARD8 Reserved[8]; /* 55-62 */
+ CARD8 PinCheck; /* 63 */
+} MGABios2Info;
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c
new file mode 100644
index 000000000..f9a07ade3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c
@@ -0,0 +1,1212 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dac3026.c,v 1.48 1999/08/21 13:48:35 dawes Exp $ */
+/*
+ * Copyright 1994 by Robin Cutshaw <robin@XFree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Robin Cutshaw not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Robin Cutshaw makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ROBIN CUTSHAW DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ROBIN CUTSHAW 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.
+ *
+ *
+ * Modified for TVP3026 by Harald Koenig <koenig@tat.physik.uni-tuebingen.de>
+ *
+ * Modified for MGA Millennium by Xavier Ducoin <xavier@rd.lectra.fr>
+ *
+ * Doug Merritt <doug@netcom.com>
+ * 24bpp: fixed high res stripe glitches, clock glitches on all res
+ *
+ */
+
+
+/*
+ * This is a first cut at a non-accelerated version to work with the
+ * new server design (DHD).
+ */
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+#include "mga_bios.h"
+#include "mga_reg.h"
+#include "mga.h"
+
+#include "xf86DDC.h"
+
+/* Set to 1 if you want to set MCLK from XF86Config - AT YOUR OWN RISK! */
+#define MCLK_FROM_XCONFIG 0
+
+/*
+ * Only change these bits in the Option register. Make sure that the
+ * vgaioen bit is never in this mask because it is controlled elsewhere
+ */
+#define OPTION_MASK 0xFFEFFEFF /* ~(eepromwt | vgaioen) */
+
+static void MGA3026LoadPalette(ScrnInfoPtr, int, int*, LOCO*, VisualPtr);
+static void MGA3026SavePalette(ScrnInfoPtr, unsigned char*);
+static void MGA3026RestorePalette(ScrnInfoPtr, unsigned char*);
+static void MGA3026RamdacInit(ScrnInfoPtr);
+static void MGA3026Save(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool);
+static void MGA3026Restore(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool);
+static Bool MGA3026Init(ScrnInfoPtr, DisplayModePtr);
+static Bool MGA3026_i2cInit(ScrnInfoPtr pScrn);
+
+
+/*
+ * implementation
+ */
+
+/*
+ * indexes to ti3026 registers (the order is important)
+ */
+const static unsigned char MGADACregs[] = {
+ 0x0F, 0x18, 0x19, 0x1A, 0x1C, 0x1D, 0x1E, 0x2A, 0x2B, 0x30,
+ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
+ 0x06
+};
+
+#define DACREGSIZE sizeof(MGADACregs)
+/*
+ * initial values of ti3026 registers
+ */
+const static unsigned char MGADACbpp8[DACREGSIZE] = {
+ 0x06, 0x80, 0x48, 0x25, 0x00, 0x00, 0x0C, 0x00, 0x1E, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0, 0x00,
+ 0x00
+};
+const static unsigned char MGADACbpp16[DACREGSIZE] = {
+ 0x07, 0x45, 0x50, 0x15, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0, 0x00,
+ 0x00
+};
+/*
+ * [0] value was 0x07, but changed to 0x06 by Doug Merrit to fix high res
+ * stripe glitches and clock glitches at 24bpp.
+ */
+const static unsigned char MGADACbpp24[DACREGSIZE] = {
+ 0x06, 0x56, 0x58, 0x25, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0, 0x00,
+ 0x00
+};
+const static unsigned char MGADACbpp32[DACREGSIZE] = {
+ 0x07, 0x46, 0x58, 0x05, 0x00, 0x00, 0x2C, 0x00, 0x1E, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0, 0x00,
+ 0x00
+};
+const static unsigned char MGADACbpp8plus24[DACREGSIZE] = {
+ 0x07, 0x06, 0x58, 0x05, 0x00, 0x00, 0x3C, 0x00, 0x1E, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0x00,
+ 0x00
+};
+
+/*
+ * Read/write to the DAC via MMIO
+ */
+
+/*
+ * These were functions. Use macros instead to avoid the need to
+ * pass pMga to them.
+ */
+
+#define inTi3026dreg(reg) INREG8(RAMDAC_OFFSET + (reg))
+
+#define outTi3026dreg(reg, val) OUTREG8(RAMDAC_OFFSET + (reg), val)
+
+#define inTi3026(reg) \
+ (outTi3026dreg(TVP3026_INDEX, reg), inTi3026dreg(TVP3026_DATA))
+
+#define outTi3026(reg, mask, val) \
+ do { /* note: mask and reg may get evaluated twice */ \
+ unsigned char tmp = (mask) ? (inTi3026(reg) & (mask)) : 0; \
+ outTi3026dreg(TVP3026_INDEX, reg); \
+ outTi3026dreg(TVP3026_DATA, tmp | (val)); \
+ } while (0)
+
+
+/*
+ * MGATi3026CalcClock - Calculate the PLL settings (m, n, p).
+ *
+ * DESCRIPTION
+ * For more information, refer to the Texas Instruments
+ * "TVP3026 Data Manual" (document SLAS098B).
+ * Section 2.4 "PLL Clock Generators"
+ * Appendix A "Frequency Synthesis PLL Register Settings"
+ * Appendix B "PLL Programming Examples"
+ *
+ * PARAMETERS
+ * f_out IN Desired clock frequency.
+ * f_max IN Maximum allowed clock frequency.
+ * m OUT Value of PLL 'm' register.
+ * n OUT Value of PLL 'n' register.
+ * p OUT Value of PLL 'p' register.
+ *
+ * HISTORY
+ * January 11, 1997 - [aem] Andrew E. Mileski
+ * Split off from MGATi3026SetClock.
+ */
+
+/* The following values are in kHz */
+#define TI_MIN_VCO_FREQ 110000
+#define TI_MAX_VCO_FREQ 220000
+#define TI_MAX_MCLK_FREQ 100000
+#define TI_REF_FREQ 14318.18
+
+static double
+MGATi3026CalcClock (
+ long f_out, long f_max,
+ int *m, int *n, int *p
+){
+ int best_m = 0, best_n = 0;
+ double f_pll, f_vco;
+ double m_err, inc_m, calc_m;
+
+ /* Make sure that f_min <= f_out <= f_max */
+ if ( f_out < ( TI_MIN_VCO_FREQ / 8 ))
+ f_out = TI_MIN_VCO_FREQ / 8;
+ if ( f_out > f_max )
+ f_out = f_max;
+
+ /*
+ * f_pll = f_vco / 2 ^ p
+ * Choose p so that TI_MIN_VCO_FREQ <= f_vco <= TI_MAX_VCO_FREQ
+ * Note that since TI_MAX_VCO_FREQ = 2 * TI_MIN_VCO_FREQ
+ * we don't have to bother checking for this maximum limit.
+ */
+ f_vco = ( double ) f_out;
+ for ( *p = 0; *p < 3 && f_vco < TI_MIN_VCO_FREQ; ( *p )++ )
+ f_vco *= 2.0;
+
+ /*
+ * We avoid doing multiplications by ( 65 - n ),
+ * and add an increment instead - this keeps any error small.
+ */
+ inc_m = f_vco / ( TI_REF_FREQ * 8.0 );
+
+ /* Initial value of calc_m for the loop */
+ calc_m = inc_m + inc_m + inc_m;
+
+ /* Initial amount of error for an integer - impossibly large */
+ m_err = 2.0;
+
+ /* Search for the closest INTEGER value of ( 65 - m ) */
+ for ( *n = 3; *n <= 25; ( *n )++, calc_m += inc_m ) {
+
+ /* Ignore values of ( 65 - m ) which we can't use */
+ if ( calc_m < 3.0 || calc_m > 64.0 )
+ continue;
+
+ /*
+ * Pick the closest INTEGER (has smallest fractional part).
+ * The optimizer should clean this up for us.
+ */
+ if (( calc_m - ( int ) calc_m ) < m_err ) {
+ m_err = calc_m - ( int ) calc_m;
+ best_m = ( int ) calc_m;
+ best_n = *n;
+ }
+ }
+
+ /* 65 - ( 65 - x ) = x */
+ *m = 65 - best_m;
+ *n = 65 - best_n;
+
+ /* Now all the calculations can be completed */
+ f_vco = 8.0 * TI_REF_FREQ * best_m / best_n;
+ f_pll = f_vco / ( 1 << *p );
+
+#ifdef DEBUG
+ ErrorF( "f_out=%ld f_pll=%.1f f_vco=%.1f n=%d m=%d p=%d\n",
+ f_out, f_pll, f_vco, *n, *m, *p );
+#endif
+
+ return f_pll;
+}
+
+/*
+ * MGATi3026SetMCLK - Set the memory clock (MCLK) PLL.
+ *
+ * HISTORY
+ * January 11, 1997 - [aem] Andrew E. Mileski
+ * Written and tested.
+ */
+static void
+MGATi3026SetMCLK( ScrnInfoPtr pScrn, long f_out )
+{
+ double f_pll;
+ int mclk_m, mclk_n, mclk_p;
+ int pclk_m, pclk_n, pclk_p;
+ int mclk_ctl;
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ f_pll = MGATi3026CalcClock(
+ f_out, TI_MAX_MCLK_FREQ,
+ & mclk_m, & mclk_n, & mclk_p
+ );
+
+ /* Save PCLK settings */
+ outTi3026( TVP3026_PLL_ADDR, 0, 0xfc );
+ pclk_n = inTi3026( TVP3026_PIX_CLK_DATA );
+ outTi3026( TVP3026_PLL_ADDR, 0, 0xfd );
+ pclk_m = inTi3026( TVP3026_PIX_CLK_DATA );
+ outTi3026( TVP3026_PLL_ADDR, 0, 0xfe );
+ pclk_p = inTi3026( TVP3026_PIX_CLK_DATA );
+
+ /* Stop PCLK (PLLEN = 0, PCLKEN = 0) */
+ outTi3026( TVP3026_PLL_ADDR, 0, 0xfe );
+ outTi3026( TVP3026_PIX_CLK_DATA, 0, 0x00 );
+
+ /* Set PCLK to the new MCLK frequency (PLLEN = 1, PCLKEN = 0 ) */
+ outTi3026( TVP3026_PLL_ADDR, 0, 0xfc );
+ outTi3026( TVP3026_PIX_CLK_DATA, 0, ( mclk_n & 0x3f ) | 0xc0 );
+ outTi3026( TVP3026_PIX_CLK_DATA, 0, mclk_m & 0x3f );
+ outTi3026( TVP3026_PIX_CLK_DATA, 0, ( mclk_p & 0x03 ) | 0xb0 );
+
+ /* Wait for PCLK PLL to lock on frequency */
+ while (( inTi3026( TVP3026_PIX_CLK_DATA ) & 0x40 ) == 0 ) {
+ ;
+ }
+
+ /* Output PCLK on MCLK pin */
+ mclk_ctl = inTi3026( TVP3026_MCLK_CTL );
+ outTi3026( TVP3026_MCLK_CTL, 0, mclk_ctl & 0xe7 );
+ outTi3026( TVP3026_MCLK_CTL, 0, ( mclk_ctl & 0xe7 ) | 0x08 );
+
+ /* Stop MCLK (PLLEN = 0 ) */
+ outTi3026( TVP3026_PLL_ADDR, 0, 0xfb );
+ outTi3026( TVP3026_MEM_CLK_DATA, 0, 0x00 );
+
+ /* Set MCLK to the new frequency (PLLEN = 1) */
+ outTi3026( TVP3026_PLL_ADDR, 0, 0xf3 );
+ outTi3026( TVP3026_MEM_CLK_DATA, 0, ( mclk_n & 0x3f ) | 0xc0 );
+ outTi3026( TVP3026_MEM_CLK_DATA, 0, mclk_m & 0x3f );
+ outTi3026( TVP3026_MEM_CLK_DATA, 0, ( mclk_p & 0x03 ) | 0xb0 );
+
+ /* Wait for MCLK PLL to lock on frequency */
+ while (( inTi3026( TVP3026_MEM_CLK_DATA ) & 0x40 ) == 0 ) {
+ ;
+ }
+
+ /* Output MCLK PLL on MCLK pin */
+ outTi3026( TVP3026_MCLK_CTL, 0, ( mclk_ctl & 0xe7 ) | 0x10 );
+ outTi3026( TVP3026_MCLK_CTL, 0, ( mclk_ctl & 0xe7 ) | 0x18 );
+
+ /* Stop PCLK (PLLEN = 0, PCLKEN = 0 ) */
+ outTi3026( TVP3026_PLL_ADDR, 0, 0xfe );
+ outTi3026( TVP3026_PIX_CLK_DATA, 0, 0x00 );
+
+ /* Restore PCLK (PLLEN = ?, PCLKEN = ?) */
+ outTi3026( TVP3026_PLL_ADDR, 0, 0xfc );
+ outTi3026( TVP3026_PIX_CLK_DATA, 0, pclk_n );
+ outTi3026( TVP3026_PIX_CLK_DATA, 0, pclk_m );
+ outTi3026( TVP3026_PIX_CLK_DATA, 0, pclk_p );
+
+ /* Wait for PCLK PLL to lock on frequency */
+ while (( inTi3026( TVP3026_PIX_CLK_DATA ) & 0x40 ) == 0 ) {
+ ;
+ }
+}
+
+/*
+ * MGATi3026SetPCLK - Set the pixel (PCLK) and loop (LCLK) clocks.
+ *
+ * PARAMETERS
+ * f_pll IN Pixel clock PLL frequencly in kHz.
+ * bpp IN Bytes per pixel.
+ *
+ * HISTORY
+ * January 11, 1997 - [aem] Andrew E. Mileski
+ * Split to simplify code for MCLK (=GCLK) setting.
+ *
+ * December 14, 1996 - [aem] Andrew E. Mileski
+ * Fixed loop clock to be based on the calculated, not requested,
+ * pixel clock. Added f_max = maximum f_vco frequency.
+ *
+ * October 19, 1996 - [aem] Andrew E. Mileski
+ * Commented the loop clock code (wow, I understand everything now),
+ * and simplified it a bit. This should really be two separate functions.
+ *
+ * October 1, 1996 - [aem] Andrew E. Mileski
+ * Optimized the m & n picking algorithm. Added maxClock detection.
+ * Low speed pixel clock fix (per the docs). Documented what I understand.
+ *
+ * ?????, ??, ???? - [???] ????????????
+ * Based on the TVP3026 code in the S3 driver.
+ */
+
+static void
+MGATi3026SetPCLK( ScrnInfoPtr pScrn, long f_out, int bpp )
+{
+ /* Pixel clock values */
+ int m, n, p;
+
+ /* Loop clock values */
+ int lm, ln, lp, lq;
+ double z;
+
+ /* The actual frequency output by the clock */
+ double f_pll;
+
+ long f_max = TI_MAX_VCO_FREQ;
+
+ MGAPtr pMga = MGAPTR(pScrn);
+ MGARegPtr pReg = &pMga->ModeReg;
+
+ /* Get the maximum pixel clock frequency */
+ if ( pMga->MaxClock > TI_MAX_VCO_FREQ )
+ f_max = pMga->MaxClock;
+
+ /* Do the calculations for m, n, and p */
+ f_pll = MGATi3026CalcClock( f_out, f_max, & m, & n, & p );
+
+ /* Values for the pixel clock PLL registers */
+ pReg->DacClk[ 0 ] = ( n & 0x3f ) | 0xc0;
+ pReg->DacClk[ 1 ] = ( m & 0x3f );
+ pReg->DacClk[ 2 ] = ( p & 0x03 ) | 0xb0;
+
+ /*
+ * Now that the pixel clock PLL is setup,
+ * the loop clock PLL must be setup.
+ */
+
+ /*
+ * First we figure out lm, ln, and z.
+ * Things are different in packed pixel mode (24bpp) though.
+ */
+ if ( pMga->CurrentLayout.bitsPerPixel == 24 ) {
+
+ /* ln:lm = ln:3 */
+ lm = 65 - 3;
+
+ /* Check for interleaved mode */
+ if ( bpp == 2 )
+ /* ln:lm = 4:3 */
+ ln = 65 - 4;
+ else
+ /* ln:lm = 8:3 */
+ ln = 65 - 8;
+
+ /* Note: this is actually 100 * z for more precision */
+ z = ( 11000 * ( 65 - ln )) / (( f_pll / 1000 ) * ( 65 - lm ));
+ }
+ else {
+ /* ln:lm = ln:4 */
+ lm = 65 - 4;
+
+ /* Note: bpp = bytes per pixel */
+ ln = 65 - 4 * ( 64 / 8 ) / bpp;
+
+ /* Note: this is actually 100 * z for more precision */
+ z = (( 11000 / 4 ) * ( 65 - ln )) / ( f_pll / 1000 );
+ }
+
+ /*
+ * Now we choose dividers lp and lq so that the VCO frequency
+ * is within the operating range of 110 MHz to 220 MHz.
+ */
+
+ /* Assume no lq divider */
+ lq = 0;
+
+ /* Note: z is actually 100 * z for more precision */
+ if ( z <= 200.0 )
+ lp = 0;
+ else if ( z <= 400.0 )
+ lp = 1;
+ else if ( z <= 800.0 )
+ lp = 2;
+ else if ( z <= 1600.0 )
+ lp = 3;
+ else {
+ lp = 3;
+ lq = ( int )( z / 1600.0 );
+ }
+
+ /* Values for the loop clock PLL registers */
+ if ( pMga->CurrentLayout.bitsPerPixel == 24 ) {
+ /* Packed pixel mode values */
+ pReg->DacClk[ 3 ] = ( ln & 0x3f ) | 0x80;
+ pReg->DacClk[ 4 ] = ( lm & 0x3f ) | 0x80;
+ pReg->DacClk[ 5 ] = ( lp & 0x03 ) | 0xf8;
+ } else {
+ /* Non-packed pixel mode values */
+ pReg->DacClk[ 3 ] = ( ln & 0x3f ) | 0xc0;
+ pReg->DacClk[ 4 ] = ( lm & 0x3f );
+ pReg->DacClk[ 5 ] = ( lp & 0x03 ) | 0xf0;
+ }
+ pReg->DacRegs[ 18 ] = lq | 0x38;
+
+#ifdef DEBUG
+ ErrorF( "bpp=%d z=%.1f ln=%d lm=%d lp=%d lq=%d\n",
+ bpp, z, ln, lm, lp, lq );
+#endif
+}
+
+/*
+ * MGA3026Init -- for mga2064 with ti3026
+ *
+ * The 'mode' parameter describes the video mode. The 'mode' structure
+ * as well as the 'vga256InfoRec' structure can be dereferenced for
+ * information that is needed to initialize the mode. The 'new' macro
+ * (see definition above) is used to simply fill in the structure.
+ */
+static Bool
+MGA3026Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ int hd, hs, he, ht, vd, vs, ve, vt, wd;
+ int i, BppShift, index_1d = 0;
+ const unsigned char* initDAC;
+ MGAPtr pMga = MGAPTR(pScrn);
+ MGARamdacPtr MGAdac = &pMga->Dac;
+ MGAFBLayout *pLayout = &pMga->CurrentLayout;
+ MGARegPtr pReg = &pMga->ModeReg;
+ vgaRegPtr pVga = &VGAHWPTR(pScrn)->ModeReg;
+
+ BppShift = pMga->BppShifts[(pLayout->bitsPerPixel >> 3) - 1];
+
+ switch(pLayout->bitsPerPixel)
+ {
+ case 8:
+ initDAC = MGADACbpp8;
+ break;
+ case 16:
+ initDAC = MGADACbpp16;
+ break;
+ case 24:
+ initDAC = MGADACbpp24;
+ break;
+ case 32:
+ if(pLayout->Overlay8Plus24)
+ initDAC = MGADACbpp8plus24;
+ else
+ initDAC = MGADACbpp32;
+ break;
+ default:
+ FatalError("MGA: unsupported bits per pixel\n");
+ }
+
+ /* Allocate the DacRegs space if not done already */
+ if (pReg->DacRegs == NULL) {
+ pReg->DacRegs = xnfcalloc(DACREGSIZE, 1);
+ }
+ for (i = 0; i < DACREGSIZE; i++) {
+ pReg->DacRegs[i] = initDAC[i];
+ if (MGADACregs[i] == 0x1D)
+ index_1d = i;
+ }
+
+ if((pLayout->bitsPerPixel == 32) && pLayout->Overlay8Plus24) {
+ pReg->DacRegs[9] = pMga->colorKey;
+ pReg->DacRegs[10] = pMga->colorKey;
+ }
+
+ if ( (pLayout->bitsPerPixel == 16) && (pLayout->weight.red == 5)
+ && (pLayout->weight.green == 5) && (pLayout->weight.blue == 5) ) {
+ pReg->DacRegs[1] &= ~0x01;
+ }
+ pReg->DacRegs[2] |= pMga->Interleave? 0x04 : 0x03;
+
+ /*
+ * This will initialize all of the generic VGA registers.
+ */
+ if (!vgaHWInit(pScrn, mode))
+ return(FALSE);
+
+ /*
+ * Here all of the MGA registers get filled in.
+ */
+ hd = (mode->CrtcHDisplay >> 3) - 1;
+ hs = (mode->CrtcHSyncStart >> 3) - 1;
+ he = (mode->CrtcHSyncEnd >> 3) - 1;
+ ht = (mode->CrtcHTotal >> 3) - 1;
+ vd = mode->CrtcVDisplay - 1;
+ vs = mode->CrtcVSyncStart - 1;
+ ve = mode->CrtcVSyncEnd - 1;
+ vt = mode->CrtcVTotal - 2;
+
+ /* HTOTAL & 0x7 equal to 0x6 in 8bpp or 0x4 in 24bpp causes strange
+ * vertical stripes
+ */
+ if((ht & 0x07) == 0x06 || (ht & 0x07) == 0x04)
+ ht++;
+
+ if (pLayout->bitsPerPixel == 24)
+ wd = (pLayout->displayWidth * 3) >> (4 - BppShift);
+ else
+ wd = pLayout->displayWidth >> (4 - BppShift);
+
+ pReg->ExtVga[0] = 0;
+ pReg->ExtVga[5] = 0;
+
+ if (mode->Flags & V_INTERLACE)
+ {
+ pReg->ExtVga[0] = 0x80;
+ pReg->ExtVga[5] = (hs + he - ht) >> 1;
+ wd <<= 1;
+ vt &= 0xFFFE;
+
+ /* enable interlaced cursor */
+ pReg->DacRegs[20] |= 0x20;
+ }
+
+ pReg->ExtVga[0] |= (wd & 0x300) >> 4;
+ pReg->ExtVga[1] = (((ht - 4) & 0x100) >> 8) |
+ ((hd & 0x100) >> 7) |
+ ((hs & 0x100) >> 6) |
+ (ht & 0x40);
+ pReg->ExtVga[2] = ((vt & 0xc00) >> 10) |
+ ((vd & 0x400) >> 8) |
+ ((vd & 0xc00) >> 7) |
+ ((vs & 0xc00) >> 5);
+ if (pLayout->bitsPerPixel == 24)
+ pReg->ExtVga[3] = (((1 << BppShift) * 3) - 1) | 0x80;
+ else
+ pReg->ExtVga[3] = ((1 << BppShift) - 1) | 0x80;
+
+ /* Set viddelay (CRTCEXT3 Bits 3-4). */
+ pReg->ExtVga[3] |= (pScrn->videoRam == 8192 ? 0x10
+ : pScrn->videoRam == 2048 ? 0x08 : 0x00);
+
+ pReg->ExtVga[4] = 0;
+
+ pVga->CRTC[0] = ht - 4;
+ pVga->CRTC[1] = hd;
+ pVga->CRTC[2] = hd;
+ pVga->CRTC[3] = (ht & 0x1F) | 0x80;
+ pVga->CRTC[4] = hs;
+ pVga->CRTC[5] = ((ht & 0x20) << 2) | (he & 0x1F);
+ pVga->CRTC[6] = vt & 0xFF;
+ pVga->CRTC[7] = ((vt & 0x100) >> 8 ) |
+ ((vd & 0x100) >> 7 ) |
+ ((vs & 0x100) >> 6 ) |
+ ((vd & 0x100) >> 5 ) |
+ 0x10 |
+ ((vt & 0x200) >> 4 ) |
+ ((vd & 0x200) >> 3 ) |
+ ((vs & 0x200) >> 2 );
+ pVga->CRTC[9] = ((vd & 0x200) >> 4) | 0x40;
+ pVga->CRTC[16] = vs & 0xFF;
+ pVga->CRTC[17] = (ve & 0x0F) | 0x20;
+ pVga->CRTC[18] = vd & 0xFF;
+ pVga->CRTC[19] = wd & 0xFF;
+ pVga->CRTC[21] = vd & 0xFF;
+ pVga->CRTC[22] = (vt + 1) & 0xFF;
+
+ if (mode->Flags & V_DBLSCAN)
+ pVga->CRTC[9] |= 0x80;
+
+ /* Per DDK vid.c line 75, sync polarity should be controlled
+ * via the TVP3026 RAMDAC register 1D and so MISC Output Register
+ * should always have bits 6 and 7 set. */
+
+ pVga->MiscOutReg |= 0xC0;
+ if ((mode->Flags & (V_PHSYNC | V_NHSYNC)) &&
+ (mode->Flags & (V_PVSYNC | V_NVSYNC)))
+ {
+ if (mode->Flags & V_PHSYNC)
+ pReg->DacRegs[index_1d] |= 0x01;
+ if (mode->Flags & V_PVSYNC)
+ pReg->DacRegs[index_1d] |= 0x02;
+ }
+ else
+ {
+ int VDisplay = mode->VDisplay;
+ if (mode->Flags & V_DBLSCAN)
+ VDisplay *= 2;
+ if (VDisplay < 400)
+ pReg->DacRegs[index_1d] |= 0x01; /* +hsync -vsync */
+ else if (VDisplay < 480)
+ pReg->DacRegs[index_1d] |= 0x02; /* -hsync +vsync */
+ else if (VDisplay < 768)
+ pReg->DacRegs[index_1d] |= 0x00; /* -hsync -vsync */
+ else
+ pReg->DacRegs[index_1d] |= 0x03; /* +hsync +vsync */
+ }
+
+ if (pMga->SyncOnGreen)
+ pReg->DacRegs[index_1d] |= 0x20;
+
+ pReg->Option = 0x402C0100; /* fine for 2064 and 2164 */
+
+ if (pMga->Interleave)
+ pReg->Option |= 0x1000;
+ else
+ pReg->Option &= ~0x1000;
+
+ if(pMga->UsePCIRetry)
+ pReg->Option &= ~0x20000000;
+ else
+ pReg->Option |= 0x20000000;
+
+ pVga->MiscOutReg |= 0x0C;
+ /* XXX Need to check the first argument */
+ MGATi3026SetPCLK( pScrn, mode->Clock, 1 << BppShift );
+
+ /* this one writes registers rather than writing to the
+ mgaReg->ModeReg and letting Restore write to the hardware
+ but that's no big deal since we will Restore right after
+ this function */
+ MGATi3026SetMCLK( pScrn, MGAdac->MemoryClock );
+
+#ifdef DEBUG
+ ErrorF("%6ld: %02X %02X %02X %02X %02X %02X %08lX\n", mode->Clock,
+ pReg->DacClk[0], pReg->DacClk[1], pReg->DacClk[2], pReg->DacClk[3], pReg->DacClk[4], pReg->DacClk[5], pReg->Option);
+ for (i=0; i<sizeof(MGADACregs); i++) ErrorF("%02X ", pReg->DacRegs[i]);
+ for (i=0; i<6; i++) ErrorF(" %02X", pReg->ExtVga[i]);
+ ErrorF("\n");
+#endif
+
+ /* This disables the VGA memory aperture */
+ pVga->MiscOutReg &= ~0x02;
+ return(TRUE);
+}
+
+/*
+ * MGA3026Restore -- for mga2064 with ti3026
+ *
+ * This function restores a video mode. It basically writes out all of
+ * the registers that have previously been saved in the vgaMGARec data
+ * structure.
+ */
+static void
+MGA3026Restore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg,
+ Bool restoreFonts)
+{
+ int i;
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ /*
+ * Code is needed to get things back to bank zero.
+ */
+ for (i = 0; i < 6; i++)
+ OUTREG16(0x1FDE, (mgaReg->ExtVga[i] << 8) | i);
+
+ pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, OPTION_MASK,
+ mgaReg->Option);
+
+ /* select pixel clock PLL as clock source */
+ outTi3026(TVP3026_CLK_SEL, 0, mgaReg->DacRegs[3]);
+
+ /* set loop and pixel clock PLL PLLEN bits to 0 */
+ outTi3026(TVP3026_PLL_ADDR, 0, 0x2A);
+ outTi3026(TVP3026_LOAD_CLK_DATA, 0, 0);
+ outTi3026(TVP3026_PIX_CLK_DATA, 0, 0);
+
+ /*
+ * This function handles restoring the generic VGA registers.
+ */
+ vgaHWRestore(pScrn, vgaReg,
+ VGA_SR_MODE | (restoreFonts ? VGA_SR_FONTS : 0));
+ MGA3026RestorePalette(pScrn, vgaReg->DAC);
+
+ /*
+ * Code to restore SVGA registers that have been saved/modified
+ * goes here.
+ */
+
+ /* program pixel clock PLL */
+ outTi3026(TVP3026_PLL_ADDR, 0, 0x00);
+ for (i = 0; i < 3; i++)
+ outTi3026(TVP3026_PIX_CLK_DATA, 0, mgaReg->DacClk[i]);
+
+ if (vgaReg->MiscOutReg & 0x08) {
+ /* poll until pixel clock PLL LOCK bit is set */
+ outTi3026(TVP3026_PLL_ADDR, 0, 0x3F);
+ while ( ! (inTi3026(TVP3026_PIX_CLK_DATA) & 0x40) );
+ }
+ /* set Q divider for loop clock PLL */
+ outTi3026(TVP3026_MCLK_CTL, 0, mgaReg->DacRegs[18]);
+
+ /* program loop PLL */
+ outTi3026(TVP3026_PLL_ADDR, 0, 0x00);
+ for (i = 3; i < 6; i++)
+ outTi3026(TVP3026_LOAD_CLK_DATA, 0, mgaReg->DacClk[i]);
+
+ if ((vgaReg->MiscOutReg & 0x08) && ((mgaReg->DacClk[3] & 0xC0) == 0xC0) ) {
+ /* poll until loop PLL LOCK bit is set */
+ outTi3026(TVP3026_PLL_ADDR, 0, 0x3F);
+ while ( ! (inTi3026(TVP3026_LOAD_CLK_DATA) & 0x40) );
+ }
+
+ /*
+ * restore other DAC registers
+ */
+ for (i = 0; i < DACREGSIZE; i++)
+ outTi3026(MGADACregs[i], 0, mgaReg->DacRegs[i]);
+
+#ifdef DEBUG
+ ErrorF("PCI retry (0-enabled / 1-disabled): %d\n",
+ !!(mgaReg->Option & 0x20000000));
+#endif
+}
+
+/*
+ * MGA3026Save -- for mga2064 with ti3026
+ *
+ * This function saves the video state.
+ */
+static void
+MGA3026Save(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg,
+ Bool saveFonts)
+{
+ int i;
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ /* Allocate the DacRegs space if not done already */
+ if (mgaReg->DacRegs == NULL) {
+ mgaReg->DacRegs = xnfcalloc(DACREGSIZE, 1);
+ }
+
+ /*
+ * Code is needed to get back to bank zero.
+ */
+ OUTREG16(0x1FDE, 0x0004);
+
+ /*
+ * This function will handle creating the data structure and filling
+ * in the generic VGA portion.
+ */
+ vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | (saveFonts ? VGA_SR_FONTS : 0));
+ MGA3026SavePalette(pScrn, vgaReg->DAC);
+
+ /*
+ * The port I/O code necessary to read in the extended registers
+ * into the fields of the vgaMGARec structure.
+ */
+ for (i = 0; i < 6; i++)
+ {
+ OUTREG8(0x1FDE, i);
+ mgaReg->ExtVga[i] = INREG8(0x1FDF);
+ }
+
+ outTi3026(TVP3026_PLL_ADDR, 0, 0x00);
+ for (i = 0; i < 3; i++)
+ outTi3026(TVP3026_PIX_CLK_DATA, 0, mgaReg->DacClk[i] =
+ inTi3026(TVP3026_PIX_CLK_DATA));
+
+ outTi3026(TVP3026_PLL_ADDR, 0, 0x00);
+ for (i = 3; i < 6; i++)
+ outTi3026(TVP3026_LOAD_CLK_DATA, 0, mgaReg->DacClk[i] =
+ inTi3026(TVP3026_LOAD_CLK_DATA));
+
+ for (i = 0; i < DACREGSIZE; i++)
+ mgaReg->DacRegs[i] = inTi3026(MGADACregs[i]);
+
+ mgaReg->Option = pciReadLong(pMga->PciTag, PCI_OPTION_REG);
+
+#ifdef DEBUG
+ ErrorF("read: %02X %02X %02X %02X %02X %02X %08lX\n",
+ mgaReg->DacClk[0], mgaReg->DacClk[1], mgaReg->DacClk[2], mgaReg->DacClk[3], mgaReg->DacClk[4], mgaReg->DacClk[5], mgaReg->Option);
+ for (i=0; i<sizeof(MGADACregs); i++) ErrorF("%02X ", mgaReg->DacRegs[i]);
+ for (i=0; i<6; i++) ErrorF(" %02X", mgaReg->ExtVga[i]);
+ ErrorF("\n");
+#endif
+}
+
+
+static void
+MGA3026LoadCursorImage(
+ ScrnInfoPtr pScrn,
+ unsigned char *src
+)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ int i = 1024;
+
+ outTi3026(TVP3026_CURSOR_CTL, 0xf3, 0x00); /* reset A9,A8 */
+ /* reset cursor RAM load address A7..A0 */
+ outTi3026dreg(TVP3026_WADR_PAL, 0x00);
+
+ while(i--) {
+ while (INREG8(0x1FDA) & 0x01);
+ while (!(INREG8(0x1FDA) & 0x01));
+ outTi3026dreg(TVP3026_CUR_RAM, *(src++));
+ }
+}
+
+
+static void
+MGA3026ShowCursor(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ /* Enable cursor - X11 mode */
+ outTi3026(TVP3026_CURSOR_CTL, 0x6c, 0x13);
+}
+
+static void
+MGA3026HideCursor(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ /* Disable cursor */
+ outTi3026(TVP3026_CURSOR_CTL, 0xfc, 0x00);
+}
+
+static void
+MGA3026SetCursorPosition(
+ ScrnInfoPtr pScrn,
+ int x, int y
+)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ x += 64;
+ y += 64;
+
+ /* Output position - "only" 12 bits of location documented */
+
+ outTi3026dreg(TVP3026_CUR_XLOW, x & 0xFF);
+ outTi3026dreg(TVP3026_CUR_XHI, (x >> 8) & 0x0F);
+ outTi3026dreg(TVP3026_CUR_YLOW, y & 0xFF);
+ outTi3026dreg(TVP3026_CUR_YHI, (y >> 8) & 0x0F);
+}
+
+static void
+MGA3026SetCursorColors(
+ ScrnInfoPtr pScrn,
+ int bg, int fg
+)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ /* The TI 3026 cursor is always 8 bits so shift 8, not 10 */
+
+ /* Background color */
+ outTi3026dreg(TVP3026_CUR_COL_ADDR, 1);
+ outTi3026dreg(TVP3026_CUR_COL_DATA, (bg & 0x00FF0000) >> 16);
+ outTi3026dreg(TVP3026_CUR_COL_DATA, (bg & 0x0000FF00) >> 8);
+ outTi3026dreg(TVP3026_CUR_COL_DATA, (bg & 0x000000FF));
+
+ /* Foreground color */
+ outTi3026dreg(TVP3026_CUR_COL_ADDR, 2);
+ outTi3026dreg(TVP3026_CUR_COL_DATA, (fg & 0x00FF0000) >> 16);
+ outTi3026dreg(TVP3026_CUR_COL_DATA, (fg & 0x0000FF00) >> 8);
+ outTi3026dreg(TVP3026_CUR_COL_DATA, (fg & 0x000000FF));
+}
+
+static Bool
+MGA3026UseHWCursor(ScreenPtr pScrn, CursorPtr pCurs)
+{
+ if( XF86SCRNINFO(pScrn)->currentMode->Flags & V_DBLSCAN )
+ return FALSE;
+ return TRUE;
+}
+
+static const int DDC_SDA_MASK = 1 << 2;
+static const int DDC_SCL_MASK = 1 << 4;
+
+static unsigned int
+MGA3026_ddc1Read(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ /* Define the SDA as an input */
+ outTi3026(TVP3026_GEN_IO_CTL, 0xfb, 0);
+
+ /* wait for Vsync */
+ while( INREG( MGAREG_Status ) & 0x08 );
+ while( ! (INREG( MGAREG_Status ) & 0x08) );
+
+ /* Get the result */
+ return (inTi3026(TVP3026_GEN_IO_DATA) & DDC_SDA_MASK) >> 2 ;
+}
+
+static void
+MGA3026_I2CGetBits(I2CBusPtr b, int *clock, int *data)
+{
+ MGAPtr pMga = MGAPTR(xf86Screens[b->scrnIndex]);
+ unsigned char val;
+
+ /* Get the result. */
+ val = inTi3026(TVP3026_GEN_IO_DATA);
+ *clock = (val & DDC_SCL_MASK) != 0;
+ *data = (val & DDC_SDA_MASK) != 0;
+
+#ifdef DEBUG
+ ErrorF("MGA3026_I2CGetBits(%p,...) val=0x%x, returns clock %d, data %d\n", b, val, *clock, *data);
+#endif
+}
+
+/*
+ * ATTENTION! - the DATA and CLOCK lines need to be tri-stated when
+ * high. Therefore turn off output driver for the line to set line
+ * to high. High signal is maintained by a 15k Ohm pll-up resistor.
+ */
+static void
+MGA3026_I2CPutBits(I2CBusPtr b, int clock, int data)
+{
+ MGAPtr pMga = MGAPTR(xf86Screens[b->scrnIndex]);
+ unsigned char val,drv;
+
+ /* Write the values */
+ val = (clock ? DDC_SCL_MASK : 0) | (data ? DDC_SDA_MASK : 0);
+ drv = ((!clock) ? DDC_SCL_MASK : 0) | ((!data) ? DDC_SDA_MASK : 0);
+ /* Define the SDA (Data) and SCL (clock) as outputs */
+ outTi3026(TVP3026_GEN_IO_CTL, ~(DDC_SDA_MASK | DDC_SCL_MASK), drv);
+ outTi3026(TVP3026_GEN_IO_DATA, ~(DDC_SDA_MASK | DDC_SCL_MASK), val);
+
+#ifdef DEBUG
+ ErrorF("MGA3026_I2CPutBits(%p, %d, %d) val=0x%x\n", b, clock, data, val);
+#endif
+
+}
+
+
+Bool
+MGA3026_i2cInit(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ I2CBusPtr I2CPtr;
+
+ I2CPtr = xf86CreateI2CBusRec();
+ if(!I2CPtr) return FALSE;
+
+ pMga->I2C = I2CPtr;
+
+ I2CPtr->BusName = "DDC";
+ I2CPtr->scrnIndex = pScrn->scrnIndex;
+ I2CPtr->I2CPutBits = MGA3026_I2CPutBits;
+ I2CPtr->I2CGetBits = MGA3026_I2CGetBits;
+
+ /* I2CPutByte is timing out, experimenting with AcknTimeout
+ * default is 2CPtr->AcknTimeout = 5;
+ */
+ /* I2CPtr->AcknTimeout = 10; */
+
+ if (!xf86I2CBusInit(I2CPtr)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void
+MGA3026RamdacInit(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga;
+ MGARamdacPtr MGAdac;
+
+ pMga = MGAPTR(pScrn);
+ MGAdac = &pMga->Dac;
+
+ MGAdac->isHwCursor = TRUE;
+ MGAdac->CursorMaxWidth = 64;
+ MGAdac->CursorMaxHeight = 64;
+ MGAdac->SetCursorColors = MGA3026SetCursorColors;
+ MGAdac->SetCursorPosition = MGA3026SetCursorPosition;
+ MGAdac->LoadCursorImage = MGA3026LoadCursorImage;
+ MGAdac->HideCursor = MGA3026HideCursor;
+ MGAdac->ShowCursor = MGA3026ShowCursor;
+ MGAdac->UseHWCursor = MGA3026UseHWCursor;
+ MGAdac->CursorFlags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
+
+ MGAdac->LoadPalette = MGA3026LoadPalette;
+
+ MGAdac->ClockFrom = X_PROBED;
+ if ( pMga->Chipset == PCI_CHIP_MGA2064 && pMga->Bios2.PinID == 0 )
+ {
+ switch( pMga->Bios.RamdacType & 0xff )
+ {
+ case 1: MGAdac->maxPixelClock = 220000;
+ break;
+ case 2: MGAdac->maxPixelClock = 250000;
+ break;
+ default:
+ MGAdac->maxPixelClock = 175000;
+ MGAdac->ClockFrom = X_DEFAULT;
+ break;
+ }
+ /* Set MCLK based on amount of memory */
+ if ( pScrn->videoRam < 4096 )
+ MGAdac->MemoryClock = pMga->Bios.ClkBase * 10;
+ else if ( pScrn->videoRam < 8192 )
+ MGAdac->MemoryClock = pMga->Bios.Clk4MB * 10;
+ else
+ MGAdac->MemoryClock = pMga->Bios.Clk8MB * 10;
+ MGAdac->MemClkFrom = X_PROBED;
+ MGAdac->SetMemClk = TRUE;
+ }
+ else
+ {
+ if ( pMga->Bios2.PinID ) /* make sure BIOS is available */
+ {
+ if ( pMga->Bios2.PclkMax != 0xff )
+ {
+ MGAdac->maxPixelClock = (pMga->Bios2.PclkMax + 100) * 1000;
+ }
+ else
+ MGAdac->maxPixelClock = 220000;
+
+ /* make sure we are not overdriving the GE for the amount of WRAM */
+ switch ( pScrn->videoRam )
+ {
+ case 4096:
+ if (pMga->Bios2.Clk4MB != 0xff)
+ pMga->Bios2.ClkGE = pMga->Bios2.Clk4MB;
+ break;
+ case 8192:
+ if (pMga->Bios2.Clk8MB != 0xff)
+ pMga->Bios2.ClkGE = pMga->Bios2.Clk8MB;
+ break;
+ case 12288:
+ if (pMga->Bios2.Clk12MB != 0xff)
+ pMga->Bios2.ClkGE = pMga->Bios2.Clk12MB;
+ break;
+ case 16384:
+ if (pMga->Bios2.Clk16MB != 0xff)
+ pMga->Bios2.ClkGE = pMga->Bios2.Clk16MB;
+ break;
+ default:
+ break;
+ }
+
+ if ( pMga->Bios2.ClkGE != 0xff && pMga->Bios2.ClkMem == 0xff )
+ pMga->Bios2.ClkMem = pMga->Bios2.ClkGE;
+ else if ( pMga->Bios2.ClkGE == 0xff && pMga->Bios2.ClkMem != 0xff )
+ ; /* don't need to do anything */
+ else if ( pMga->Bios2.ClkGE == pMga->Bios2.ClkMem && pMga->Bios2.ClkGE != 0xff )
+ pMga->Bios2.ClkMem = pMga->Bios2.ClkGE;
+ else
+ pMga->Bios2.ClkMem = 60;
+
+ MGAdac->MemoryClock = pMga->Bios2.ClkMem * 1000;
+ MGAdac->MemClkFrom = X_PROBED;
+ MGAdac->SetMemClk = TRUE;
+ } /* BIOS enabled initialization */
+ else
+ {
+ /* bios is not available, initialize to rational figures */
+ MGAdac->MemoryClock = 60000; /* 60 MHz WRAM */
+ MGAdac->maxPixelClock = 220000; /* 220 MHz */
+ MGAdac->ClockFrom = X_DEFAULT;
+ }
+ } /* 2164 specific initialization */
+
+ /* safety check */
+ if ( (MGAdac->MemoryClock < 40000) ||
+ (MGAdac->MemoryClock > 70000) )
+ MGAdac->MemoryClock = 50000;
+
+ /*
+ * Should initialise a sane default when the probed value is
+ * obviously garbage.
+ */
+
+ /* Check if interleaving can be used and set the rounding value */
+ if (pScrn->videoRam > 2048)
+ pMga->Interleave = TRUE;
+ else {
+ pMga->Interleave = FALSE;
+ pMga->BppShifts[0]++;
+ pMga->BppShifts[1]++;
+ pMga->BppShifts[2]++;
+ pMga->BppShifts[3]++;
+ }
+
+ pMga->Roundings[0] = 128 >> pMga->BppShifts[0];
+ pMga->Roundings[1] = 128 >> pMga->BppShifts[1];
+ pMga->Roundings[2] = 128 >> pMga->BppShifts[2];
+ pMga->Roundings[3] = 128 >> pMga->BppShifts[3];
+
+ /* Set Fast bitblt flag */
+ pMga->HasFBitBlt = !(pMga->Bios.FeatFlag & 0x00000001);
+}
+
+void MGA3026LoadPalette(
+ ScrnInfoPtr pScrn,
+ int numColors,
+ int *indices,
+ LOCO *colors,
+ VisualPtr pVisual
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+ int i, index;
+
+ if(pMga->CurrentLayout.Overlay8Plus24 && (pVisual->nplanes != 8))
+ return;
+
+ if (pVisual->nplanes == 16) {
+ for(i = 0; i < numColors; i++) {
+ index = indices[i];
+ outTi3026dreg(MGA1064_WADR_PAL, index << 2);
+ outTi3026dreg(MGA1064_COL_PAL, colors[index >> 1].red);
+ outTi3026dreg(MGA1064_COL_PAL, colors[index].green);
+ outTi3026dreg(MGA1064_COL_PAL, colors[index >> 1].blue);
+
+ /* we have to write 2 indices since the pixel X on the
+ TVP3026 has green colors at different locations from
+ the red and blue colors */
+ if(index <= 31) {
+ outTi3026dreg(MGA1064_WADR_PAL, index << 3);
+ outTi3026dreg(MGA1064_COL_PAL, colors[index].red);
+ outTi3026dreg(MGA1064_COL_PAL, colors[(index << 1) + 1].green);
+ outTi3026dreg(MGA1064_COL_PAL, colors[index].blue);
+ }
+ }
+ } else {
+ int shift = (pVisual->nplanes == 15) ? 3 : 0;
+
+ for(i = 0; i < numColors; i++) {
+ index = indices[i];
+ outTi3026dreg(MGA1064_WADR_PAL, index << shift);
+ outTi3026dreg(MGA1064_COL_PAL, colors[index].red);
+ outTi3026dreg(MGA1064_COL_PAL, colors[index].green);
+ outTi3026dreg(MGA1064_COL_PAL, colors[index].blue);
+ }
+ }
+}
+
+
+static void
+MGA3026SavePalette(ScrnInfoPtr pScrn, unsigned char* pntr)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ int i = 768;
+
+ outTi3026dreg(TVP3026_RADR_PAL, 0x00);
+ while(i--)
+ *(pntr++) = inTi3026dreg(TVP3026_COL_PAL);
+}
+
+static void
+MGA3026RestorePalette(ScrnInfoPtr pScrn, unsigned char* pntr)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ int i = 768;
+
+ outTi3026dreg(TVP3026_WADR_PAL, 0x00);
+ while(i--)
+ outTi3026dreg(TVP3026_COL_PAL, *(pntr++));
+}
+
+
+void MGA2064SetupFuncs(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ pMga->PreInit = MGA3026RamdacInit;
+ pMga->Save = MGA3026Save;
+ pMga->Restore = MGA3026Restore;
+ pMga->ModeInit = MGA3026Init;
+ pMga->ddc1Read = MGA3026_ddc1Read;
+ /* vgaHWddc1SetSpeed will only work if the card is in VGA mode */
+ pMga->DDC1SetSpeed = vgaHWddc1SetSpeed;
+ pMga->i2cInit = MGA3026_i2cInit;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c
new file mode 100644
index 000000000..1cfa03f31
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c
@@ -0,0 +1,951 @@
+/*
+ * MGA-1064, MGA-G100, MGA-G200, MGA-G400 RAMDAC driver
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dacG.c,v 1.30 1999/08/22 05:57:33 dawes Exp $ */
+
+/*
+ * This is a first cut at a non-accelerated version to work with the
+ * new server design (DHD).
+ */
+
+#include "colormapst.h"
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+#include "mga_bios.h"
+#include "mga_reg.h"
+#include "mga.h"
+
+#include "xf86DDC.h"
+
+
+/*
+ * implementation
+ */
+
+#define DACREGSIZE 0x50
+
+/*
+ * Only change bits shown in this mask. Ideally reserved bits should be
+ * zeroed here. Also, don't change the vgaioen bit here since it is
+ * controlled elsewhere.
+ *
+ * XXX These settings need to be checked.
+ */
+#define OPTION1_MASK 0xFFFFFEFF
+#define OPTION2_MASK 0xFFFFFFFF
+#define OPTION3_MASK 0xFFFFFFFF
+
+/*
+ * Read/write to the DAC via MMIO
+ */
+
+/*
+ * These were functions. Use macros instead to avoid the need to
+ * pass pMga to them.
+ */
+
+#define inMGAdreg(reg) INREG8(RAMDAC_OFFSET + (reg))
+
+#define outMGAdreg(reg, val) OUTREG8(RAMDAC_OFFSET + (reg), val)
+
+#define inMGAdac(reg) \
+ (outMGAdreg(MGA1064_INDEX, reg), inMGAdreg(MGA1064_DATA))
+
+#define outMGAdac(reg, val) \
+ (outMGAdreg(MGA1064_INDEX, reg), outMGAdreg(MGA1064_DATA, val))
+
+#define outMGAdacmsk(reg, mask, val) \
+ do { /* note: mask and reg may get evaluated twice */ \
+ unsigned char tmp = (mask) ? (inMGAdac(reg) & (mask)) : 0; \
+ outMGAdreg(MGA1064_INDEX, reg); \
+ outMGAdreg(MGA1064_DATA, tmp | (val)); \
+ } while (0)
+
+
+static void MGAGRamdacInit(ScrnInfoPtr);
+static void MGAGSave(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool);
+static void MGAGRestore(ScrnInfoPtr, vgaRegPtr, MGARegPtr, Bool);
+static Bool MGAGInit(ScrnInfoPtr, DisplayModePtr);
+static void MGAGLoadPalette(ScrnInfoPtr, int, int*, LOCO*, VisualPtr);
+static Bool MGAG_i2cInit(ScrnInfoPtr pScrn);
+
+/*
+ * MGAGCalcClock - Calculate the PLL settings (m, n, p, s).
+ *
+ * DESCRIPTION
+ * For more information, refer to the Matrox
+ * "MGA1064SG Developer Specification (document 10524-MS-0100).
+ * chapter 5.7.8. "PLLs Clocks Generators"
+ *
+ * PARAMETERS
+ * f_out IN Desired clock frequency.
+ * f_max IN Maximum allowed clock frequency.
+ * m OUT Value of PLL 'm' register.
+ * n OUT Value of PLL 'n' register.
+ * p OUT Value of PLL 'p' register.
+ * s OUT Value of PLL 's' filter register
+ * (pix pll clock only).
+ *
+ * HISTORY
+ * August 18, 1998 - Radoslaw Kapitan
+ * Adapted for G200 DAC
+ *
+ * February 28, 1997 - Guy DESBIEF
+ * Adapted for MGA1064SG DAC.
+ * based on MGACalcClock written by [aem] Andrew E. Mileski
+ */
+
+/* The following values are in kHz */
+#define MGA_MIN_VCO_FREQ 50000
+#define MGA_MAX_VCO_FREQ 310000
+
+static double
+MGAGCalcClock ( ScrnInfoPtr pScrn, long f_out,
+ int *best_m, int *best_n, int *p, int *s )
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ int m, n;
+ double f_pll, f_vco;
+ double m_err, calc_f;
+ double ref_freq;
+ int feed_div_min, feed_div_max;
+ int in_div_min, in_div_max;
+ int post_div_max;
+
+ switch( pMga->Chipset )
+ {
+ case PCI_CHIP_MGA1064:
+ ref_freq = 14318.18;
+ feed_div_min = 100;
+ feed_div_max = 127;
+ in_div_min = 1;
+ in_div_max = 31;
+ post_div_max = 7;
+ break;
+ case PCI_CHIP_MGAG400:
+ ref_freq = 27050.5;
+ feed_div_min = 7;
+ feed_div_max = 127;
+ in_div_min = 1;
+ in_div_max = 31;
+ post_div_max = 7;
+ break;
+ case PCI_CHIP_MGAG100:
+ case PCI_CHIP_MGAG200:
+ case PCI_CHIP_MGAG200_PCI:
+ default:
+ if (pMga->Bios2.PinID && (pMga->Bios2.VidCtrl & 0x20))
+ ref_freq = 14318.18;
+ else
+ ref_freq = 27050.5;
+ feed_div_min = 7;
+ feed_div_max = 127;
+ in_div_min = 1;
+ in_div_max = 6;
+ post_div_max = 7;
+ break;
+ }
+
+ /* Make sure that f_min <= f_out */
+ if ( f_out < ( MGA_MIN_VCO_FREQ / 8))
+ f_out = MGA_MIN_VCO_FREQ / 8;
+
+ /*
+ * f_pll = f_vco / (p+1)
+ * Choose p so that MGA_MIN_VCO_FREQ <= f_vco <= MGA_MAX_VCO_FREQ
+ * we don't have to bother checking for this maximum limit.
+ */
+ f_vco = ( double ) f_out;
+ for ( *p = 0; *p <= post_div_max && f_vco < MGA_MIN_VCO_FREQ;
+ *p = *p * 2 + 1, f_vco *= 2.0);
+
+ /* Initial amount of error for frequency maximum */
+ m_err = f_out;
+
+ /* Search for the different values of ( m ) */
+ for ( m = in_div_min ; m <= in_div_max ; m++ )
+ {
+ /* see values of ( n ) which we can't use */
+ for ( n = feed_div_min; n <= feed_div_max; n++ )
+ {
+ calc_f = ref_freq * (n + 1) / (m + 1) ;
+
+ /*
+ * Pick the closest frequency.
+ */
+ if ( abs(calc_f - f_vco) < m_err ) {
+ m_err = abs(calc_f - f_vco);
+ *best_m = m;
+ *best_n = n;
+ }
+ }
+ }
+
+ /* Now all the calculations can be completed */
+ f_vco = ref_freq * (*best_n + 1) / (*best_m + 1);
+
+ /* Adjustments for filtering pll feed back */
+ if ( (50000.0 <= f_vco)
+ && (f_vco < 100000.0) )
+ *s = 0;
+ if ( (100000.0 <= f_vco)
+ && (f_vco < 140000.0) )
+ *s = 1;
+ if ( (140000.0 <= f_vco)
+ && (f_vco < 180000.0) )
+ *s = 2;
+ if ( (180000.0 <= f_vco) )
+ *s = 3;
+
+ f_pll = f_vco / ( *p + 1 );
+
+#ifdef DEBUG
+ ErrorF( "f_out_requ =%ld f_pll_real=%.1f f_vco=%.1f n=0x%x m=0x%x p=0x%x s=0x%x\n",
+ f_out, f_pll, f_vco, *best_n, *best_m, *p, *s );
+#endif
+
+ return f_pll;
+}
+
+
+/*
+ * MGAGSetPCLK - Set the pixel (PCLK) clock.
+ */
+static void
+MGAGSetPCLK( ScrnInfoPtr pScrn, long f_out )
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ MGARegPtr pReg = &pMga->ModeReg;
+
+ /* Pixel clock values */
+ int m, n, p, s;
+
+ /* The actual frequency output by the clock */
+ double f_pll;
+
+ /* Do the calculations for m, n, p and s */
+ f_pll = MGAGCalcClock( pScrn, f_out, &m, &n, &p, &s );
+
+ /* Values for the pixel clock PLL registers */
+ pReg->DacRegs[ MGA1064_PIX_PLLC_M ] = m & 0x1F;
+ pReg->DacRegs[ MGA1064_PIX_PLLC_N ] = n & 0x7F;
+ pReg->DacRegs[ MGA1064_PIX_PLLC_P ] = (p & 0x07) | ((s & 0x03) << 3);
+}
+
+/*
+ * MGAGInit
+ */
+static Bool
+MGAGInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ /*
+ * initial values of the DAC registers
+ */
+ const static unsigned char initDAC[] = {
+ /* 0x00: */ 0, 0, 0, 0, 0, 0, 0x00, 0,
+ /* 0x08: */ 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x10: */ 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x18: */ 0x00, 0, 0xC9, 0xFF, 0xBF, 0x20, 0x1F, 0x20,
+ /* 0x20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 0x28: */ 0x00, 0x00, 0x00, 0x00, 0, 0, 0, 0x40,
+ /* 0x30: */ 0x00, 0xB0, 0x00, 0xC2, 0x34, 0x14, 0x02, 0x83,
+ /* 0x38: */ 0x00, 0x93, 0x00, 0x77, 0x00, 0x00, 0x00, 0x3A,
+ /* 0x40: */ 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x48: */ 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ int hd, hs, he, ht, vd, vs, ve, vt, wd;
+ int i, BppShift;
+ MGAPtr pMga;
+ MGARegPtr pReg;
+ vgaRegPtr pVga;
+ MGAFBLayout *pLayout;
+ int weight555 = FALSE;
+
+ pMga = MGAPTR(pScrn);
+ pReg = &pMga->ModeReg;
+ pVga = &VGAHWPTR(pScrn)->ModeReg;
+ pLayout = &pMga->CurrentLayout;
+
+ BppShift = pMga->BppShifts[(pLayout->bitsPerPixel >> 3) - 1];
+
+ /* Allocate the DacRegs space if not done already */
+ if (pReg->DacRegs == NULL) {
+ pReg->DacRegs = xnfcalloc(DACREGSIZE, 1);
+ }
+ for (i = 0; i < DACREGSIZE; i++) {
+ pReg->DacRegs[i] = initDAC[i];
+ }
+
+ switch(pMga->Chipset)
+ {
+ case PCI_CHIP_MGA1064:
+ pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x04;
+ pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x44;
+ pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18;
+ pReg->Option = 0x5F094F21;
+ pReg->Option2 = 0x00000000;
+ break;
+ case PCI_CHIP_MGAG100:
+ case PCI_CHIP_MGAG100_PCI:
+ pReg->DacRegs[ MGAGDAC_XVREFCTRL ] = 0x03;
+ if(pMga->HasSDRAM) {
+ if(pMga->OverclockMem) {
+ /* 220 Mhz */
+ pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x06;
+ pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x38;
+ pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18;
+ } else {
+ /* 203 Mhz */
+ pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x01;
+ pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x0E;
+ pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x18;
+ }
+ pReg->Option = 0x404991a9;
+ } else {
+ if(pMga->OverclockMem) {
+ /* 143 Mhz */
+ pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x06;
+ pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x24;
+ pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x10;
+ } else {
+ /* 124 Mhz */
+ pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x04;
+ pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x16;
+ pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x08;
+ }
+ pReg->Option = 0x4049d121;
+ }
+ pReg->Option2 = 0x0000007;
+ break;
+ case PCI_CHIP_MGAG400:
+ if(pMga->OverclockMem) {
+ /* 166 Mhz but faster graphics engine clock */
+ pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x13;
+ pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x7A;
+ pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x08;
+ pReg->Option3 = 0x0190a421;
+ } else {
+ /* 165 Mhz */
+ pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x09;
+ pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x3C;
+ pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x10;
+ pReg->Option3 = 0x0190a419;
+ }
+ pReg->Option2 = 0x01003000;
+ if(pMga->HasSDRAM)
+ pReg->Option = 0x50040120;
+ else
+ pReg->Option = 0x50044120;
+ break;
+ case PCI_CHIP_MGAG200:
+ case PCI_CHIP_MGAG200_PCI:
+ default:
+ if(pMga->OverclockMem) {
+ /* 143 Mhz */
+ pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x06;
+ pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x24;
+ pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x10;
+ } else {
+ /* 124 Mhz */
+ pReg->DacRegs[ MGA1064_SYS_PLL_M ] = 0x04;
+ pReg->DacRegs[ MGA1064_SYS_PLL_N ] = 0x2D;
+ pReg->DacRegs[ MGA1064_SYS_PLL_P ] = 0x19;
+ }
+ pReg->Option2 = 0x00008000;
+ if(pMga->HasSDRAM)
+ pReg->Option = 0x40499121;
+ else
+ pReg->Option = 0x4049cd21;
+ break;
+ }
+
+ if(pMga->UsePCIRetry)
+ pReg->Option &= ~0x20000000;
+ else
+ pReg->Option |= 0x20000000;
+
+ switch(pLayout->bitsPerPixel)
+ {
+ case 8:
+ pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_8bits;
+ break;
+ case 16:
+ pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_16bits;
+ if ( (pLayout->weight.red == 5) && (pLayout->weight.green == 5)
+ && (pLayout->weight.blue == 5) ) {
+ weight555 = TRUE;
+ pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_15bits;
+ }
+ break;
+ case 24:
+ pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_24bits;
+ break;
+ case 32:
+ if(pLayout->Overlay8Plus24) {
+ pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_32bits;
+ pReg->DacRegs[ MGA1064_COL_KEY_MSK_LSB ] = 0xFF;
+ pReg->DacRegs[ MGA1064_COL_KEY_LSB ] = pMga->colorKey;
+ } else
+ pReg->DacRegs[ MGA1064_MUL_CTL ] = MGA1064_MUL_CTL_32_24bits;
+ break;
+ default:
+ FatalError("MGA: unsupported depth\n");
+ }
+
+ /*
+ * This will initialize all of the generic VGA registers.
+ */
+ if (!vgaHWInit(pScrn, mode))
+ return(FALSE);
+
+ /*
+ * Here all of the MGA registers get filled in.
+ */
+ hd = (mode->CrtcHDisplay >> 3) - 1;
+ hs = (mode->CrtcHSyncStart >> 3) - 1;
+ he = (mode->CrtcHSyncEnd >> 3) - 1;
+ ht = (mode->CrtcHTotal >> 3) - 1;
+ vd = mode->CrtcVDisplay - 1;
+ vs = mode->CrtcVSyncStart - 1;
+ ve = mode->CrtcVSyncEnd - 1;
+ vt = mode->CrtcVTotal - 2;
+
+ /* HTOTAL & 0x7 equal to 0x6 in 8bpp or 0x4 in 24bpp causes strange
+ * vertical stripes
+ */
+ if((ht & 0x07) == 0x06 || (ht & 0x07) == 0x04)
+ ht++;
+
+ if (pLayout->bitsPerPixel == 24)
+ wd = (pLayout->displayWidth * 3) >> (4 - BppShift);
+ else
+ wd = pLayout->displayWidth >> (4 - BppShift);
+
+ pReg->ExtVga[0] = 0;
+ pReg->ExtVga[5] = 0;
+
+ if (mode->Flags & V_INTERLACE)
+ {
+ pReg->ExtVga[0] = 0x80;
+ pReg->ExtVga[5] = (hs + he - ht) >> 1;
+ wd <<= 1;
+ vt &= 0xFFFE;
+ }
+
+ pReg->ExtVga[0] |= (wd & 0x300) >> 4;
+ pReg->ExtVga[1] = (((ht - 4) & 0x100) >> 8) |
+ ((hd & 0x100) >> 7) |
+ ((hs & 0x100) >> 6) |
+ (ht & 0x40);
+ pReg->ExtVga[2] = ((vt & 0xc00) >> 10) |
+ ((vd & 0x400) >> 8) |
+ ((vd & 0xc00) >> 7) |
+ ((vs & 0xc00) >> 5);
+ if (pLayout->bitsPerPixel == 24)
+ pReg->ExtVga[3] = (((1 << BppShift) * 3) - 1) | 0x80;
+ else
+ pReg->ExtVga[3] = ((1 << BppShift) - 1) | 0x80;
+
+#if 0
+ /* Set viddelay (CRTCEXT3 Bits 3-4). */
+ pReg->ExtVga[3] |= (pScrn->videoRam == 8192 ? 0x10
+ : pScrn->videoRam == 2048 ? 0x08 : 0x00);
+#endif
+
+ pReg->ExtVga[4] = 0;
+
+ pVga->CRTC[0] = ht - 4;
+ pVga->CRTC[1] = hd;
+ pVga->CRTC[2] = hd;
+ pVga->CRTC[3] = (ht & 0x1F) | 0x80;
+ pVga->CRTC[4] = hs;
+ pVga->CRTC[5] = ((ht & 0x20) << 2) | (he & 0x1F);
+ pVga->CRTC[6] = vt & 0xFF;
+ pVga->CRTC[7] = ((vt & 0x100) >> 8 ) |
+ ((vd & 0x100) >> 7 ) |
+ ((vs & 0x100) >> 6 ) |
+ ((vd & 0x100) >> 5 ) |
+ 0x10 |
+ ((vt & 0x200) >> 4 ) |
+ ((vd & 0x200) >> 3 ) |
+ ((vs & 0x200) >> 2 );
+ pVga->CRTC[9] = ((vd & 0x200) >> 4) | 0x40;
+ pVga->CRTC[16] = vs & 0xFF;
+ pVga->CRTC[17] = (ve & 0x0F) | 0x20;
+ pVga->CRTC[18] = vd & 0xFF;
+ pVga->CRTC[19] = wd & 0xFF;
+ pVga->CRTC[21] = vd & 0xFF;
+ pVga->CRTC[22] = (vt + 1) & 0xFF;
+
+ if (mode->Flags & V_DBLSCAN)
+ pVga->CRTC[9] |= 0x80;
+
+ pReg->DacRegs[ MGA1064_CURSOR_BASE_ADR_LOW ] =
+ pMga->FbCursorOffset >> 10;
+ pReg->DacRegs[ MGA1064_CURSOR_BASE_ADR_HI ] =
+ pMga->FbCursorOffset >> 18;
+
+ if (pMga->SyncOnGreen) {
+ pReg->DacRegs[ MGA1064_GEN_CTL ] &= ~0x20;
+ pReg->ExtVga[3] |= 0x40;
+ }
+
+ /* select external clock */
+ pVga->MiscOutReg |= 0x0C;
+
+ MGAGSetPCLK( pScrn, mode->Clock );
+
+ /* This disables the VGA memory aperture */
+ pVga->MiscOutReg &= ~0x02;
+ return(TRUE);
+}
+
+/*
+ * MGAGLoadPalette
+ */
+
+void MGAGLoadPalette(
+ ScrnInfoPtr pScrn,
+ int numColors,
+ int *indices,
+ LOCO *colors,
+ VisualPtr pVisual
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+ int i, index;
+
+ if(pMga->CurrentLayout.Overlay8Plus24 && (pVisual->nplanes != 8))
+ return;
+
+ for(i = 0; i < numColors; i++) {
+ index = indices[i];
+ outMGAdreg(MGA1064_WADR_PAL, index);
+ outMGAdreg(MGA1064_COL_PAL, colors[index].red);
+ outMGAdreg(MGA1064_COL_PAL, colors[index].green);
+ outMGAdreg(MGA1064_COL_PAL, colors[index].blue);
+ }
+}
+
+/*
+ * MGAGRestorePalette
+ */
+static void
+MGAGRestorePalette(ScrnInfoPtr pScrn, unsigned char* pntr)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ int i = 768;
+
+ outMGAdreg(MGA1064_WADR_PAL, 0x00);
+ while(i--)
+ outMGAdreg(MGA1064_COL_PAL, *(pntr++));
+}
+
+/*
+ * MGAGSavePalette
+ */
+static void
+MGAGSavePalette(ScrnInfoPtr pScrn, unsigned char* pntr)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ int i = 768;
+
+ outMGAdreg(MGA1064_RADR_PAL, 0x00);
+ while(i--)
+ *(pntr++) = inMGAdreg(MGA1064_COL_PAL);
+}
+
+/*
+ * MGAGRestore
+ *
+ * This function restores a video mode. It basically writes out all of
+ * the registers that have previously been saved.
+ */
+static void
+MGAGRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg,
+ Bool restoreFonts)
+{
+ int i;
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ /*
+ * Code is needed to get things back to bank zero.
+ */
+
+ /* restore DAC registers
+ * according to the docs we shouldn't write to reserved regs*/
+ for (i = 0; i < DACREGSIZE; i++) {
+ if( (i <= 0x03) ||
+ (i == 0x07) ||
+ (i == 0x0b) ||
+ (i == 0x0f) ||
+ ((i >= 0x13) && (i <= 0x17)) ||
+ (i == 0x1b) ||
+ (i == 0x1c) ||
+ ((i >= 0x1f) && (i <= 0x29)) ||
+ ((i >= 0x30) && (i <= 0x37)) )
+ continue;
+ outMGAdac(i, mgaReg->DacRegs[i]);
+ }
+
+ /* restore pci_option register */
+ pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, OPTION1_MASK,
+ mgaReg->Option);
+ if (pMga->Chipset != PCI_CHIP_MGA1064)
+ pciSetBitsLong(pMga->PciTag, PCI_MGA_OPTION2, OPTION2_MASK,
+ mgaReg->Option2);
+ if (pMga->Chipset == PCI_CHIP_MGAG400)
+ pciSetBitsLong(pMga->PciTag, PCI_MGA_OPTION3, OPTION3_MASK,
+ mgaReg->Option3);
+
+ /* restore CRTCEXT regs */
+ for (i = 0; i < 6; i++)
+ OUTREG16(0x1FDE, (mgaReg->ExtVga[i] << 8) | i);
+
+ /*
+ * This function handles restoring the generic VGA registers.
+ */
+ vgaHWRestore(pScrn, vgaReg,
+ VGA_SR_MODE | (restoreFonts ? VGA_SR_FONTS : 0));
+ MGAGRestorePalette(pScrn, vgaReg->DAC);
+
+ /*
+ * this is needed to properly restore start address
+ */
+ OUTREG16(0x1FDE, (mgaReg->ExtVga[0] << 8) | 0);
+
+#ifdef DEBUG
+ ErrorF("Setting DAC:");
+ for (i=0; i<DACREGSIZE; i++) {
+#if 1
+ if(!(i%16)) ErrorF("\n%02X: ",i);
+ ErrorF("%02X ", mgaReg->DacRegs[i]);
+#else
+ if(!(i%8)) ErrorF("\n%02X: ",i);
+ ErrorF("0x%02X, ", mgaReg->DacRegs[i]);
+#endif
+ }
+ ErrorF("\nOPTION = %08lX\n", mgaReg->Option);
+ ErrorF("OPTION2 = %08lX\n", mgaReg->Option2);
+ ErrorF("CRTCEXT:");
+ for (i=0; i<6; i++) ErrorF(" %02X", mgaReg->ExtVga[i]);
+ ErrorF("\n");
+#endif
+}
+
+/*
+ * MGAGSave
+ *
+ * This function saves the video state.
+ */
+static void
+MGAGSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, MGARegPtr mgaReg,
+ Bool saveFonts)
+{
+ int i;
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ /* Allocate the DacRegs space if not done already */
+ if (mgaReg->DacRegs == NULL) {
+ mgaReg->DacRegs = xnfcalloc(DACREGSIZE, 1);
+ }
+
+ /*
+ * Code is needed to get back to bank zero.
+ */
+ OUTREG16(0x1FDE, 0x0004);
+
+ /*
+ * This function will handle creating the data structure and filling
+ * in the generic VGA portion.
+ */
+ vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | (saveFonts ? VGA_SR_FONTS : 0));
+ MGAGSavePalette(pScrn, vgaReg->DAC);
+
+ /*
+ * The port I/O code necessary to read in the extended registers.
+ */
+ for (i = 0; i < DACREGSIZE; i++)
+ mgaReg->DacRegs[i] = inMGAdac(i);
+
+ mgaReg->Option = pciReadLong(pMga->PciTag, PCI_OPTION_REG);
+
+ mgaReg->Option2 = pciReadLong(pMga->PciTag, PCI_MGA_OPTION2);
+ if (pMga->Chipset == PCI_CHIP_MGAG400)
+ mgaReg->Option3 = pciReadLong(pMga->PciTag, PCI_MGA_OPTION3);
+
+ for (i = 0; i < 6; i++)
+ {
+ OUTREG8(0x1FDE, i);
+ mgaReg->ExtVga[i] = INREG8(0x1FDF);
+ }
+#ifdef DEBUG
+ ErrorF("Saved values:\nDAC:");
+ for (i=0; i<DACREGSIZE; i++) {
+#if 1
+ if(!(i%16)) ErrorF("\n%02X: ",i);
+ ErrorF("%02X ", mgaReg->DacRegs[i]);
+#else
+ if(!(i%8)) ErrorF("\n%02X: ",i);
+ ErrorF("0x%02X, ", mgaReg->DacRegs[i]);
+#endif
+ }
+ ErrorF("\nOPTION = %08lX\n:", mgaReg->Option);
+ ErrorF("OPTION2 = %08lX\nCRTCEXT:", mgaReg->Option2);
+ for (i=0; i<6; i++) ErrorF(" %02X", mgaReg->ExtVga[i]);
+ ErrorF("\n");
+#endif
+}
+
+/****
+ *** HW Cursor
+ */
+static void
+MGAGLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ CARD32 *dst = (CARD32*)(pMga->FbBase + pMga->FbCursorOffset);
+ int i = 128;
+
+ /* swap bytes in each line */
+ while( i-- ) {
+ *dst++ = (src[4] << 24) | (src[5] << 16) | (src[6] << 8) | src[7];
+ *dst++ = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3];
+ src += 8;
+ }
+}
+
+static void
+MGAGShowCursor(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ /* Enable cursor - X-Windows mode */
+ outMGAdac(MGA1064_CURSOR_CTL, 0x03);
+}
+
+static void
+MGAGHideCursor(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ /* Disable cursor */
+ outMGAdac(MGA1064_CURSOR_CTL, 0x00);
+}
+
+static void
+MGAGSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ x += 64;
+ y += 64;
+
+ /* cursor update must never occurs during a retrace period (pp 4-160) */
+ while( INREG( MGAREG_Status ) & 0x08 );
+
+ /* Output position - "only" 12 bits of location documented */
+ OUTREG( RAMDAC_OFFSET + MGA1064_CUR_XLOW, (y << 16) | (x & 0xFFFF));
+}
+
+static void
+MGAGSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ /* Background color */
+ outMGAdac(MGA1064_CURSOR_COL0_RED, (bg & 0x00FF0000) >> 16);
+ outMGAdac(MGA1064_CURSOR_COL0_GREEN, (bg & 0x0000FF00) >> 8);
+ outMGAdac(MGA1064_CURSOR_COL0_BLUE, (bg & 0x000000FF));
+
+ /* Foreground color */
+ outMGAdac(MGA1064_CURSOR_COL1_RED, (fg & 0x00FF0000) >> 16);
+ outMGAdac(MGA1064_CURSOR_COL1_GREEN, (fg & 0x0000FF00) >> 8);
+ outMGAdac(MGA1064_CURSOR_COL1_BLUE, (fg & 0x000000FF));
+}
+
+static Bool
+MGAGUseHWCursor(ScreenPtr pScrn, CursorPtr pCurs)
+{
+ if( XF86SCRNINFO(pScrn)->currentMode->Flags & V_DBLSCAN )
+ return FALSE;
+ return TRUE;
+}
+
+
+/*
+ * According to mga-1064g.pdf pp215-216 (4-179 & 4-180) the low bits of
+ * XGENIODATA and XGENIOCTL are connected to the 4 DDC pins, but don't say
+ * which VGA line is connected to each DDC pin, so I've had to guess.
+ *
+ * DDC1 support only requires DDC_SDA_MASK,
+ * DDC2 support reuqiers DDC_SDA_MASK and DDC_SCL_MASK
+ */
+static const int DDC_SDA_MASK = 1 << 1;
+static const int DDC_SCL_MASK = 1 << 3;
+
+static unsigned int
+MGAG_ddc1Read(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ unsigned char val;
+
+ /* Define the SDA as an input */
+ outMGAdacmsk(MGA1064_GEN_IO_CTL, ~(DDC_SCL_MASK | DDC_SDA_MASK), 0);
+
+ /* wait for Vsync */
+ while( INREG( MGAREG_Status ) & 0x08 );
+ while( ! (INREG( MGAREG_Status ) & 0x08) );
+
+ /* Get the result */
+ val = (inMGAdac(MGA1064_GEN_IO_DATA) & DDC_SDA_MASK);
+ return val;
+}
+
+static void
+MGAG_I2CGetBits(I2CBusPtr b, int *clock, int *data)
+{
+ MGAPtr pMga = MGAPTR(xf86Screens[b->scrnIndex]);
+ unsigned char val;
+
+ /* Get the result. */
+ val = inMGAdac(MGA1064_GEN_IO_DATA);
+
+ *clock = (val & DDC_SCL_MASK) != 0;
+ *data = (val & DDC_SDA_MASK) != 0;
+#ifdef DEBUG
+ ErrorF("MGAG_I2CGetBits(%p,...) val=0x%x, returns clock %d, data %d\n", b, val, *clock, *data);
+#endif
+}
+
+/*
+ * ATTENTION! - the DATA and CLOCK lines need to be tri-stated when
+ * high. Therefore turn off output driver for the line to set line
+ * to high. High signal is maintained by a 15k Ohm pll-up resistor.
+ */
+static void
+MGAG_I2CPutBits(I2CBusPtr b, int clock, int data)
+{
+ MGAPtr pMga = MGAPTR(xf86Screens[b->scrnIndex]);
+ unsigned char drv, val;
+
+ val = (clock ? DDC_SCL_MASK : 0) | (data ? DDC_SDA_MASK : 0);
+ drv = ((!clock) ? DDC_SCL_MASK : 0) | ((!data) ? DDC_SDA_MASK : 0);
+
+ /* Write the values */
+ outMGAdacmsk(MGA1064_GEN_IO_CTL, ~(DDC_SCL_MASK | DDC_SDA_MASK) , drv);
+ outMGAdacmsk(MGA1064_GEN_IO_DATA, ~(DDC_SCL_MASK | DDC_SDA_MASK) , val);
+#ifdef DEBUG
+ ErrorF("MGAG_I2CPutBits(%p, %d, %d) val=0x%x\n", b, clock, data, val);
+#endif
+}
+
+
+Bool
+MGAG_i2cInit(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ I2CBusPtr I2CPtr;
+
+ I2CPtr = xf86CreateI2CBusRec();
+ if(!I2CPtr) return FALSE;
+
+ pMga->I2C = I2CPtr;
+
+ I2CPtr->BusName = "DDC";
+ I2CPtr->scrnIndex = pScrn->scrnIndex;
+ I2CPtr->I2CPutBits = MGAG_I2CPutBits;
+ I2CPtr->I2CGetBits = MGAG_I2CGetBits;
+ I2CPtr->AcknTimeout = 5;
+
+ if (!xf86I2CBusInit(I2CPtr)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*
+ * MGAGRamdacInit
+ */
+static void
+MGAGRamdacInit(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ MGARamdacPtr MGAdac = &pMga->Dac;
+
+ MGAdac->isHwCursor = TRUE;
+ MGAdac->CursorOffscreenMemSize = 1024;
+ MGAdac->CursorMaxWidth = 64;
+ MGAdac->CursorMaxHeight = 64;
+ MGAdac->SetCursorColors = MGAGSetCursorColors;
+ MGAdac->SetCursorPosition = MGAGSetCursorPosition;
+ MGAdac->LoadCursorImage = MGAGLoadCursorImage;
+ MGAdac->HideCursor = MGAGHideCursor;
+ MGAdac->ShowCursor = MGAGShowCursor;
+ MGAdac->UseHWCursor = MGAGUseHWCursor;
+ MGAdac->CursorFlags =
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
+
+ MGAdac->LoadPalette = MGAGLoadPalette;
+
+ if ( pMga->Bios2.PinID && pMga->Bios2.PclkMax != 0xFF )
+ {
+ MGAdac->maxPixelClock = (pMga->Bios2.PclkMax + 100) * 1000;
+ MGAdac->ClockFrom = X_PROBED;
+ }
+ else
+ {
+ switch( pMga->Chipset )
+ {
+ case PCI_CHIP_MGA1064:
+ if ( pMga->ChipRev < 3 )
+ MGAdac->maxPixelClock = 170000;
+ else
+ MGAdac->maxPixelClock = 220000;
+ break;
+ case PCI_CHIP_MGAG400:
+ MGAdac->maxPixelClock = 300000;
+ break;
+ default:
+ MGAdac->maxPixelClock = 250000;
+ }
+ MGAdac->ClockFrom = X_DEFAULT;
+ }
+
+ /* Disable interleaving and set the rounding value */
+ pMga->Interleave = FALSE;
+
+ pMga->Roundings[0] = 64;
+ pMga->Roundings[1] = 32;
+ pMga->Roundings[2] = 64;
+ pMga->Roundings[3] = 32;
+
+ /* Clear Fast bitblt flag */
+ pMga->HasFBitBlt = FALSE;
+}
+
+void MGAGSetupFuncs(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ pMga->PreInit = MGAGRamdacInit;
+ pMga->Save = MGAGSave;
+ pMga->Restore = MGAGRestore;
+ pMga->ModeInit = MGAGInit;
+ pMga->ddc1Read = MGAG_ddc1Read;
+ /* vgaHWddc1SetSpeed will only work if the card is in VGA mode */
+ pMga->DDC1SetSpeed = vgaHWddc1SetSpeed;
+ pMga->i2cInit = MGAG_i2cInit;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dga.c
new file mode 100644
index 000000000..8edad4ac8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dga.c
@@ -0,0 +1,443 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dga.c,v 1.12 1999/08/22 05:57:34 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "mga_bios.h"
+#include "mga.h"
+#include "mga_reg.h"
+#include "dgaproc.h"
+
+
+static Bool MGA_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
+ int *, int *, int *);
+static Bool MGA_SetMode(ScrnInfoPtr, DGAModePtr);
+static int MGA_GetViewport(ScrnInfoPtr);
+static void MGA_SetViewport(ScrnInfoPtr, int, int, int);
+static void MGA_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
+static void MGA_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+static void MGA_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
+ unsigned long);
+
+static
+DGAFunctionRec MGA_DGAFuncs = {
+ MGA_OpenFramebuffer,
+ NULL,
+ MGA_SetMode,
+ MGA_SetViewport,
+ MGA_GetViewport,
+ MGAStormSync,
+ MGA_FillRect,
+ MGA_BlitRect,
+ MGA_BlitTransRect
+};
+
+
+static int
+FindSmallestPitch(
+ MGAPtr pMga,
+ int Bpp,
+ int width
+){
+ int Pitches1[] =
+ {640, 768, 800, 960, 1024, 1152, 1280, 1600, 1920, 2048, 0};
+ int Pitches2[] =
+ {512, 640, 768, 800, 832, 960, 1024, 1152, 1280, 1600, 1664,
+ 1920, 2048, 0};
+ int *linePitches = NULL;
+ int pitch;
+
+
+ if(!pMga->NoAccel) {
+ switch(pMga->Chipset) {
+ case PCI_CHIP_MGA2064:
+ linePitches = Pitches1;
+ break;
+ case PCI_CHIP_MGA2164:
+ case PCI_CHIP_MGA2164_AGP:
+ case PCI_CHIP_MGA1064:
+ linePitches = Pitches2;
+ break;
+ }
+ }
+
+ pitch = pMga->Roundings[Bpp - 1] - 1;
+
+ if(linePitches) {
+ while((*linePitches < width) || (*linePitches & pitch))
+ linePitches++;
+ return *linePitches;
+ }
+
+ return ((width + pitch) & ~pitch);
+}
+
+static DGAModePtr
+MGASetupDGAMode(
+ ScrnInfoPtr pScrn,
+ DGAModePtr modes,
+ int *num,
+ int bitsPerPixel,
+ int depth,
+ Bool pixmap,
+ int secondPitch,
+ unsigned long red,
+ unsigned long green,
+ unsigned long blue,
+ short visualClass
+){
+ DisplayModePtr firstMode, pMode;
+ MGAPtr pMga = MGAPTR(pScrn);
+ DGAModePtr mode, newmodes;
+ int size, pitch, Bpp = bitsPerPixel >> 3;
+
+SECOND_PASS:
+
+ pMode = firstMode = pScrn->modes;
+
+ while(1) {
+
+ pitch = FindSmallestPitch(pMga, Bpp, pMode->HDisplay);
+ size = pitch * Bpp * pMode->VDisplay;
+
+ if((!secondPitch || (pitch != secondPitch)) &&
+ (size <= pMga->FbUsableSize)) {
+
+ if(secondPitch)
+ pitch = secondPitch;
+
+ if(!(newmodes = xrealloc(modes, (*num + 1) * sizeof(DGAModeRec))))
+ break;
+
+ modes = newmodes;
+ mode = modes + *num;
+
+ mode->mode = pMode;
+ mode->flags = DGA_CONCURRENT_ACCESS;
+
+ if(pixmap)
+ mode->flags |= DGA_PIXMAP_AVAILABLE;
+ if(!pMga->NoAccel) {
+ mode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
+ if((Bpp != 3) && (pMga->Chipset != PCI_CHIP_MGA2064))
+ mode->flags |= DGA_BLIT_RECT_TRANS;
+ }
+ if(pMode->Flags & V_DBLSCAN)
+ mode->flags |= DGA_DOUBLESCAN;
+ if(pMode->Flags & V_INTERLACE)
+ mode->flags |= DGA_INTERLACED;
+ mode->byteOrder = pScrn->imageByteOrder;
+ mode->depth = depth;
+ mode->bitsPerPixel = bitsPerPixel;
+ mode->red_mask = red;
+ mode->green_mask = green;
+ mode->blue_mask = blue;
+ mode->visualClass = visualClass;
+ mode->viewportWidth = pMode->HDisplay;
+ mode->viewportHeight = pMode->VDisplay;
+ mode->xViewportStep = (3 - pMga->BppShifts[Bpp - 1]);
+ if((Bpp == 3) && (pMga->Chipset == PCI_CHIP_MGAG400))
+ mode->xViewportStep <<= 1;
+ mode->yViewportStep = 1;
+ mode->viewportFlags = DGA_FLIP_RETRACE;
+ mode->offset = pMga->YDstOrg * Bpp; /* gonna need to fix that */
+ mode->address = pMga->FbStart;
+ mode->bytesPerScanline = pitch * Bpp;
+ mode->imageWidth = pitch;
+ mode->imageHeight = pMga->FbUsableSize / mode->bytesPerScanline;
+ mode->pixmapWidth = mode->imageWidth;
+ mode->pixmapHeight = mode->imageHeight;
+ mode->maxViewportX = mode->imageWidth - mode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ mode->maxViewportY = mode->imageHeight - mode->viewportHeight;
+
+ (*num)++;
+ }
+
+ pMode = pMode->next;
+ if(pMode == firstMode)
+ break;
+ }
+
+ if(secondPitch) {
+ secondPitch = 0;
+ goto SECOND_PASS;
+ }
+
+ return modes;
+}
+
+
+Bool
+MGADGAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ MGAPtr pMga = MGAPTR(pScrn);
+ DGAModePtr modes = NULL;
+ int num = 0;
+
+ /* 8 */
+ modes = MGASetupDGAMode (pScrn, modes, &num, 8, 8,
+ (pScrn->bitsPerPixel == 8),
+ (pScrn->bitsPerPixel != 8) ? 0 : pScrn->displayWidth,
+ 0, 0, 0, PseudoColor);
+
+ /* 15 */
+ modes = MGASetupDGAMode (pScrn, modes, &num, 16, 15,
+ (pScrn->bitsPerPixel == 16),
+ (pScrn->depth != 15) ? 0 : pScrn->displayWidth,
+ 0x7c00, 0x03e0, 0x001f, TrueColor);
+
+ modes = MGASetupDGAMode (pScrn, modes, &num, 16, 15,
+ (pScrn->bitsPerPixel == 16),
+ (pScrn->depth != 15) ? 0 : pScrn->displayWidth,
+ 0x7c00, 0x03e0, 0x001f, DirectColor);
+
+ /* 16 */
+ modes = MGASetupDGAMode (pScrn, modes, &num, 16, 16,
+ (pScrn->bitsPerPixel == 16),
+ (pScrn->depth != 16) ? 0 : pScrn->displayWidth,
+ 0xf800, 0x07e0, 0x001f, TrueColor);
+
+ modes = MGASetupDGAMode (pScrn, modes, &num, 16, 16,
+ (pScrn->bitsPerPixel == 16),
+ (pScrn->depth != 16) ? 0 : pScrn->displayWidth,
+ 0xf800, 0x07e0, 0x001f, DirectColor);
+
+ /* 24 */
+ modes = MGASetupDGAMode (pScrn, modes, &num, 24, 24,
+ (pScrn->bitsPerPixel == 24),
+ (pScrn->bitsPerPixel != 24) ? 0 : pScrn->displayWidth,
+ 0xff0000, 0x00ff00, 0x0000ff, TrueColor);
+
+ modes = MGASetupDGAMode (pScrn, modes, &num, 24, 24,
+ (pScrn->bitsPerPixel == 24),
+ (pScrn->bitsPerPixel != 24) ? 0 : pScrn->displayWidth,
+ 0xff0000, 0x00ff00, 0x0000ff, DirectColor);
+
+ /* 32 */
+ modes = MGASetupDGAMode (pScrn, modes, &num, 32, 24,
+ (pScrn->bitsPerPixel == 32),
+ (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth,
+ 0xff0000, 0x00ff00, 0x0000ff, TrueColor);
+
+ modes = MGASetupDGAMode (pScrn, modes, &num, 32, 24,
+ (pScrn->bitsPerPixel == 32),
+ (pScrn->bitsPerPixel != 32) ? 0 : pScrn->displayWidth,
+ 0xff0000, 0x00ff00, 0x0000ff, DirectColor);
+
+ pMga->numDGAModes = num;
+ pMga->DGAModes = modes;
+
+ return DGAInit(pScreen, &MGA_DGAFuncs, modes, num);
+}
+
+
+static int
+BitsSet(unsigned long data)
+{
+ unsigned long mask;
+ int set = 0;
+
+ for(mask = 1; mask; mask <<= 1)
+ if(mask & data) set++;
+
+ return set;
+}
+
+static Bool
+MGA_SetMode(
+ ScrnInfoPtr pScrn,
+ DGAModePtr pMode
+){
+ static MGAFBLayout SavedLayouts[MAXSCREENS];
+ int index = pScrn->pScreen->myNum;
+
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ if(!pMode) { /* restore the original mode */
+ if(pMga->DGAactive)
+ memcpy(&pMga->CurrentLayout, &SavedLayouts[index], sizeof(MGAFBLayout));
+
+ MGASwitchMode(index, pScrn->currentMode, 0);
+ MGAAdjustFrame(index, pScrn->frameX0, pScrn->frameY0, 0);
+ pMga->DGAactive = FALSE;
+ } else {
+ if(!pMga->DGAactive) { /* save the old parameters */
+ memcpy(&SavedLayouts[index], &pMga->CurrentLayout, sizeof(MGAFBLayout));
+ pMga->DGAactive = TRUE;
+ }
+
+ /* update CurrentLayout */
+ pMga->CurrentLayout.bitsPerPixel = pMode->bitsPerPixel;
+ pMga->CurrentLayout.depth = pMode->depth;
+ pMga->CurrentLayout.displayWidth = pMode->bytesPerScanline /
+ (pMode->bitsPerPixel >> 3);
+ pMga->CurrentLayout.weight.red = BitsSet(pMode->red_mask);
+ pMga->CurrentLayout.weight.green = BitsSet(pMode->green_mask);
+ pMga->CurrentLayout.weight.blue = BitsSet(pMode->blue_mask);
+ pMga->CurrentLayout.Overlay8Plus24 = FALSE;
+
+ MGASwitchMode(index, pMode->mode, 0);
+ }
+
+ return TRUE;
+}
+
+
+
+static int
+MGA_GetViewport(
+ ScrnInfoPtr pScrn
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ return pMga->DGAViewportStatus;
+}
+
+static void
+MGA_SetViewport(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int flags
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ MGAAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
+ pMga->DGAViewportStatus = 0; /* MGAAdjustFrame loops until finished */
+}
+
+static void
+MGA_FillRect (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned long color
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ if(!pMga->AccelInfoRec) return;
+
+ switch(pMga->CurrentLayout.bitsPerPixel) {
+ case 8:
+ Mga8SetupForSolidFill(pScrn, color, GXcopy, ~0);
+ break;
+ case 16:
+ Mga16SetupForSolidFill(pScrn, color, GXcopy, ~0);
+ break;
+ case 24:
+ Mga24SetupForSolidFill(pScrn, color, GXcopy, ~0);
+ break;
+ case 32:
+ Mga32SetupForSolidFill(pScrn, color, GXcopy, ~0);
+ break;
+ }
+
+ (*pMga->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+
+ SET_SYNC_FLAG(pMga->AccelInfoRec);
+}
+
+static void
+MGA_BlitRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ if(!pMga->AccelInfoRec) return;
+
+ switch(pMga->CurrentLayout.bitsPerPixel) {
+ case 8:
+ Mga8SetupForScreenToScreenCopy(
+ pScrn, xdir, ydir, GXcopy, ~0, -1);
+ break;
+ case 16:
+ Mga16SetupForScreenToScreenCopy(
+ pScrn, xdir, ydir, GXcopy, ~0, -1);
+ break;
+ case 24:
+ Mga24SetupForScreenToScreenCopy(
+ pScrn, xdir, ydir, GXcopy, ~0, -1);
+ break;
+ case 32:
+ Mga32SetupForScreenToScreenCopy(
+ pScrn, xdir, ydir, GXcopy, ~0, -1);
+ break;
+ }
+
+ (*pMga->AccelInfoRec->SubsequentScreenToScreenCopy)(
+ pScrn, srcx, srcy, dstx, dsty, w, h);
+
+ SET_SYNC_FLAG(pMga->AccelInfoRec);
+}
+
+
+static void
+MGA_BlitTransRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty,
+ unsigned long color
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ if(!pMga->AccelInfoRec) return;
+ if(pMga->CurrentLayout.bitsPerPixel == 24) return;
+ if(pMga->Chipset == PCI_CHIP_MGA2064) return;
+
+ pMga->DrawTransparent = TRUE;
+
+ switch(pMga->CurrentLayout.bitsPerPixel) {
+ case 8:
+ Mga8SetupForScreenToScreenCopy(
+ pScrn, xdir, ydir, GXcopy, ~0, color);
+ break;
+ case 16:
+ Mga16SetupForScreenToScreenCopy(
+ pScrn, xdir, ydir, GXcopy, ~0, color);
+ break;
+ case 32:
+ Mga32SetupForScreenToScreenCopy(
+ pScrn, xdir, ydir, GXcopy, ~0, color);
+ break;
+ }
+
+ pMga->DrawTransparent = FALSE;
+
+ (*pMga->AccelInfoRec->SubsequentScreenToScreenCopy)(
+ pScrn, srcx, srcy, dstx, dsty, w, h);
+
+ SET_SYNC_FLAG(pMga->AccelInfoRec);
+}
+
+
+static Bool
+MGA_OpenFramebuffer(
+ ScrnInfoPtr pScrn,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *flags
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ *name = NULL; /* no special device */
+ *mem = (unsigned char*)pMga->FbAddress;
+ *size = pMga->FbMapSize;
+ *offset = 0;
+ *flags = DGA_NEED_ROOT;
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c
new file mode 100644
index 000000000..85a529068
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c
@@ -0,0 +1,2721 @@
+/* $XConsortium: mga_driver.c /main/12 1996/10/28 05:13:26 kaleb $ */
+/*
+ * MGA Millennium (MGA2064W) with Ti3026 RAMDAC driver v.1.1
+ *
+ * The driver is written without any chip documentation. All extended ports
+ * and registers come from tracing the VESA-ROM functions.
+ * The BitBlt Engine comes from tracing the windows BitBlt function.
+ *
+ * Author: Radoslaw Kapitan, Tarnow, Poland
+ * kapitan@student.uci.agh.edu.pl
+ * original source
+ *
+ * Now that MATROX has released documentation to the public, enhancing
+ * this driver has become much easier. Nevertheless, this work continues
+ * to be based on Radoslaw's original source
+ *
+ * Contributors:
+ * Andrew Vanderstock, Melbourne, Australia
+ * vanderaj@mail2.svhm.org.au
+ * additions, corrections, cleanups
+ *
+ * Dirk Hohndel
+ * hohndel@XFree86.Org
+ * integrated into XFree86-3.1.2Gg
+ * fixed some problems with PCI probing and mapping
+ *
+ * David Dawes
+ * dawes@XFree86.Org
+ * some cleanups, and fixed some problems
+ *
+ * Andrew E. Mileski
+ * aem@ott.hookup.net
+ * RAMDAC timing, and BIOS stuff
+ *
+ * Leonard N. Zubkoff
+ * lnz@dandelion.com
+ * Support for 8MB boards, RGB Sync-on-Green, and DPMS.
+ * Guy DESBIEF
+ * g.desbief@aix.pacwan.net
+ * RAMDAC MGA1064 timing,
+ * Doug Merritt
+ * doug@netcom.com
+ * Fixed 32bpp hires 8MB horizontal line glitch at middle right
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c,v 1.114 1999/08/28 14:32:47 dawes Exp $ */
+
+/*
+ * This is a first cut at a non-accelerated version to work with the
+ * new server design (DHD).
+ */
+
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+
+/* All drivers need this */
+#include "xf86_ansic.h"
+
+#include "compiler.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* All drivers initialising the SW cursor need this */
+#include "mipointer.h"
+
+/* All drivers implementing backing store need this */
+#include "mibstore.h"
+
+#include "micmap.h"
+
+#include "xf86DDC.h"
+
+#include "xf86RAC.h"
+
+/*
+ * If using cfb, cfb.h is required. Select the others for the bpp values
+ * the driver supports.
+ */
+#define PSZ 8 /* needed for cfb.h */
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+#include "cfb24_32.h"
+#include "cfb8_32.h"
+
+#include "mga_bios.h"
+#include "mga_reg.h"
+#include "mga.h"
+#include "mga_macros.h"
+
+#include "xaa.h"
+#include "xf86cmap.h"
+#include "shadowfb.h"
+#include "fbdevhw.h"
+
+#include "xf86xv.h"
+#include "Xv.h"
+
+
+/*
+ * Forward definitions for the functions that make up the driver.
+ */
+
+/* Mandatory functions */
+static void MGAIdentify(int flags);
+static Bool MGAProbe(DriverPtr drv, int flags);
+static Bool MGAPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool MGAScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool MGAEnterVT(int scrnIndex, int flags);
+static Bool MGAEnterVTFBDev(int scrnIndex, int flags);
+static void MGALeaveVT(int scrnIndex, int flags);
+static Bool MGACloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool MGASaveScreen(ScreenPtr pScreen, Bool unblank);
+
+/* This shouldn't be needed since RAC will disable all I/O for MGA cards. */
+#ifdef DISABLE_VGA_IO
+static void VgaIOSave(int i, void *arg);
+static void VgaIORestore(int i, void *arg);
+#endif
+
+/* Optional functions */
+static void MGAFreeScreen(int scrnIndex, int flags);
+static int MGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
+#ifdef DPMSExtension
+static void MGADisplayPowerManagementSet(ScrnInfoPtr pScrn,
+ int PowerManagementMode,
+ int flags);
+#endif
+
+/* Internally used functions */
+static Bool MGAMapMem(ScrnInfoPtr pScrn);
+static Bool MGAUnmapMem(ScrnInfoPtr pScrn);
+static void MGASave(ScrnInfoPtr pScrn);
+static void MGARestore(ScrnInfoPtr pScrn);
+static Bool MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+
+#define VERSION 4000
+#define MGA_NAME "MGA"
+#define MGA_DRIVER_NAME "mga"
+#define MGA_MAJOR_VERSION 1
+#define MGA_MINOR_VERSION 0
+#define MGA_PATCHLEVEL 0
+
+/*
+ * This contains the functions needed by the server after loading the
+ * driver module. It must be supplied, and gets added the driver list by
+ * the Module Setup funtion in the dynamic case. In the static case a
+ * reference to this is compiled in, and this requires that the name of
+ * this DriverRec be an upper-case version of the driver name.
+ */
+
+DriverRec MGA = {
+ VERSION,
+ "accelerated driver for Matrox Millennium and Mystique cards",
+ MGAIdentify,
+ MGAProbe,
+ NULL,
+ 0
+};
+
+/* Supported chipsets */
+static SymTabRec MGAChipsets[] = {
+ { PCI_CHIP_MGA2064, "mga2064w" },
+ { PCI_CHIP_MGA1064, "mga1064sg" },
+ { PCI_CHIP_MGA2164, "mga2164w" },
+ { PCI_CHIP_MGA2164_AGP, "mga2164w AGP" },
+ { PCI_CHIP_MGAG100, "mgag100" },
+ { PCI_CHIP_MGAG200, "mgag200" },
+ { PCI_CHIP_MGAG200_PCI, "mgag200 PCI" },
+ { PCI_CHIP_MGAG400, "mgag400" },
+ {-1, NULL }
+};
+
+static PciChipsets MGAPciChipsets[] = {
+ { PCI_CHIP_MGA2064, PCI_CHIP_MGA2064, RES_SHARED_VGA },
+ { PCI_CHIP_MGA1064, PCI_CHIP_MGA1064, RES_SHARED_VGA },
+ { PCI_CHIP_MGA2164, PCI_CHIP_MGA2164, RES_SHARED_VGA },
+ { PCI_CHIP_MGA2164_AGP, PCI_CHIP_MGA2164_AGP, RES_SHARED_VGA },
+ { PCI_CHIP_MGAG100, PCI_CHIP_MGAG100, RES_SHARED_VGA },
+ { PCI_CHIP_MGAG200, PCI_CHIP_MGAG200, RES_SHARED_VGA },
+ { PCI_CHIP_MGAG200_PCI, PCI_CHIP_MGAG200_PCI, RES_SHARED_VGA },
+ { PCI_CHIP_MGAG400, PCI_CHIP_MGAG400, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED }
+};
+
+typedef enum {
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+ OPTION_PCI_RETRY,
+ OPTION_SYNC_ON_GREEN,
+ OPTION_NOACCEL,
+ OPTION_SHOWCACHE,
+ OPTION_OVERLAY,
+ OPTION_MGA_SDRAM,
+ OPTION_SHADOW_FB,
+ OPTION_FBDEV,
+ OPTION_COLOR_KEY,
+ OPTION_SET_MCLK,
+ OPTION_OVERCLOCK_MEM,
+ OPTION_ROTATE
+} MGAOpts;
+
+static OptionInfoRec MGAOptions[] = {
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SYNC_ON_GREEN, "SyncOnGreen", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_OVERLAY, "Overlay", OPTV_ANYSTR, {0}, FALSE },
+ { OPTION_MGA_SDRAM, "MGASDRAM", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_SET_MCLK, "SetMclk", OPTV_FREQ, {0}, FALSE },
+ { OPTION_OVERCLOCK_MEM, "OverclockMem", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+
+/*
+ * List of symbols from other modules that this module references. This
+ * list is used to tell the loader that it is OK for symbols here to be
+ * unresolved providing that it hasn't been told that they haven't been
+ * told that they are essential via a call to xf86LoaderReqSymbols() or
+ * xf86LoaderReqSymLists(). The purpose is this is to avoid warnings about
+ * unresolved symbols that are not required.
+ */
+
+static const char *vgahwSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWUnlock",
+ "vgaHWInit",
+ "vgaHWProtect",
+ "vgaHWSetMmioFuncs",
+ "vgaHWGetIOBase",
+ "vgaHWMapMem",
+ "vgaHWLock",
+ "vgaHWFreeHWRec",
+ "vgaHWSaveScreen",
+ "vgaHWddc1SetSpeed",
+ NULL
+};
+
+static const char *cfbSymbols[] = {
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb24ScreenInit",
+ "cfb32ScreenInit",
+ "cfb8_32ScreenInit",
+ "cfb24_32ScreenInit",
+ NULL
+};
+
+static const char *xf8_32bppSymbols[] = {
+ "xf86Overlay8Plus32Init",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAADestroyInfoRec",
+ "XAACreateInfoRec",
+ "XAAInit",
+ "XAAStippleScanlineFuncLSBFirst",
+ "XAAOverlayFBfuncs",
+ "XAACachePlanarMonoStipple",
+ "XAAScreenIndex",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86InitCursor",
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ NULL
+};
+
+#define MGAuseI2C 1
+
+static const char *ddcSymbols[] = {
+ "xf86PrintEDID",
+ "xf86DoEDID_DDC1",
+#if MGAuseI2C
+ "xf86DoEDID_DDC2",
+#endif
+ NULL
+};
+
+static const char *i2cSymbols[] = {
+ "xf86CreateI2CBusRec",
+ "xf86I2CBusInit",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+static const char *fbdevHWSymbols[] = {
+ "fbdevHWInit",
+ "fbdevHWUseBuildinMode",
+
+ "fbdevHWGetDepth",
+ "fbdevHWGetVidmem",
+
+ /* colormap */
+ "fbdevHWLoadPalette",
+
+ /* ScrnInfo hooks */
+ "fbdevHWSwitchMode",
+ "fbdevHWAdjustFrame",
+ "fbdevHWEnterVT",
+ "fbdevHWLeaveVT",
+ "fbdevHWValidMode",
+ "fbdevHWRestore",
+ "fbdevHWModeInit",
+ "fbdevHWSave",
+
+ "fbdevHWUnmapMMIO",
+ "fbdevHWUnmapVidmem",
+ "fbdevHWMapMMIO",
+ "fbdevHWMapVidmem",
+
+ NULL
+};
+
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(mgaSetup);
+
+static XF86ModuleVersionInfo mgaVersRec =
+{
+ "mga",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ MGA_MAJOR_VERSION, MGA_MINOR_VERSION, MGA_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+XF86ModuleData mgaModuleData = { &mgaVersRec, mgaSetup, NULL };
+
+static pointer
+mgaSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ /* This module should be loaded only once, but check to be sure. */
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&MGA, module, 0);
+
+ /*
+ * Modules that this driver always requires may be loaded here
+ * by calling LoadSubModule().
+ */
+
+ /*
+ * Tell the loader about symbols from other modules that this module
+ * might refer to.
+ */
+ LoaderRefSymLists(vgahwSymbols, cfbSymbols, xaaSymbols,
+ xf8_32bppSymbols, ramdacSymbols,
+ ddcSymbols, i2cSymbols, shadowSymbols,
+ fbdevHWSymbols, NULL);
+
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer)1;
+ } else {
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+
+#endif /* XFree86LOADER */
+
+/*
+ * This is intentionally screen-independent. It indicates the binding
+ * choice made in the first PreInit.
+ */
+static int pix24bpp = 0;
+
+/*
+ * ramdac info structure initialization
+ */
+static MGARamdacRec DacInit = {
+ FALSE, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL,
+ 90000, /* maxPixelClock */
+ 0, X_DEFAULT, X_DEFAULT, FALSE
+};
+
+static Bool
+MGAGetRec(ScrnInfoPtr pScrn)
+{
+ /*
+ * Allocate an MGARec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(MGARec), 1);
+ /* Initialise it */
+
+ MGAPTR(pScrn)->Dac = DacInit;
+ return TRUE;
+}
+
+static void
+MGAFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+
+/* Mandatory */
+static void
+MGAIdentify(int flags)
+{
+ xf86PrintChipsets(MGA_NAME, "driver for Matrox chipsets", MGAChipsets);
+}
+
+
+/* Mandatory */
+static Bool
+MGAProbe(DriverPtr drv, int flags)
+{
+ int i;
+ GDevPtr *devSections;
+ int *usedChips;
+ int numDevSections;
+ int numUsed;
+ Bool foundScreen = FALSE;
+
+ /*
+ * The aim here is to find all cards that this driver can handle,
+ * and for the ones not already claimed by another driver, claim the
+ * slot, and allocate a ScrnInfoRec.
+ *
+ * This should be a minimal probe, and it should under no circumstances
+ * change the state of the hardware. Because a device is found, don't
+ * assume that it will be used. Don't do any initialisations other than
+ * the required ScrnInfoRec initialisations. Don't allocate any new
+ * data structures.
+ */
+
+ /*
+ * Check if there has been a chipset override in the config file.
+ * For this we must find out if there is an active device section which
+ * is relevant, i.e., which has no driver specified or has THIS driver
+ * specified.
+ */
+
+ if ((numDevSections = xf86MatchDevice(MGA_DRIVER_NAME,
+ &devSections)) <= 0) {
+ /*
+ * There's no matching device section in the config file, so quit
+ * now.
+ */
+ return FALSE;
+ }
+
+ /*
+ * We need to probe the hardware first. We then need to see how this
+ * fits in with what is given in the config file, and allow the config
+ * file info to override any contradictions.
+ */
+
+ /*
+ * All of the cards this driver supports are PCI, so the "probing" just
+ * amounts to checking the PCI data that the server has already collected.
+ */
+ if (xf86GetPciVideoInfo() == NULL) {
+ /*
+ * We won't let anything in the config file override finding no
+ * PCI video cards at all. This seems reasonable now, but we'll see.
+ */
+ return FALSE;
+ }
+
+ numUsed = xf86MatchPciInstances(MGA_NAME, PCI_VENDOR_MATROX,
+ MGAChipsets, MGAPciChipsets, devSections,
+ numDevSections, drv, &usedChips);
+ /* Free it since we don't need that list after this */
+ xfree(devSections);
+ devSections = NULL;
+ if (numUsed <= 0)
+ return FALSE;
+
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn;
+#ifdef DISABLE_VGA_IO
+ MgaSavePtr smga;
+#endif
+
+ /* Allocate a ScrnInfoRec and claim the slot */
+ pScrn = xf86AllocateScreen(drv, 0);
+
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = MGA_DRIVER_NAME;
+ pScrn->name = MGA_NAME;
+ pScrn->Probe = MGAProbe;
+ pScrn->PreInit = MGAPreInit;
+ pScrn->ScreenInit = MGAScreenInit;
+ pScrn->SwitchMode = MGASwitchMode;
+ pScrn->AdjustFrame = MGAAdjustFrame;
+ pScrn->EnterVT = MGAEnterVT;
+ pScrn->LeaveVT = MGALeaveVT;
+ pScrn->FreeScreen = MGAFreeScreen;
+ pScrn->ValidMode = MGAValidMode;
+ foundScreen = TRUE;
+#ifndef DISABLE_VGA_IO
+ xf86ConfigActivePciEntity(pScrn, usedChips[i], MGAPciChipsets, NULL,
+ NULL, NULL, NULL, NULL);
+#else
+ smga = xnfalloc(sizeof(MgaSave));
+ smga->pvp = xf86GetPciInfoForEntity(usedChips[i]);
+ xf86ConfigActivePciEntity(pScrn, usedChips[i], MGAPciChipsets, NULL,
+ VgaIOSave, VgaIOSave, VgaIORestore,
+ smga);
+#endif
+ }
+ xfree(usedChips);
+ return foundScreen;
+}
+
+
+/*
+ * Should aim towards not relying on this.
+ */
+
+/*
+ * MGAReadBios - Read the video BIOS info block.
+ *
+ * DESCRIPTION
+ * Warning! This code currently does not detect a video BIOS.
+ * In the future, support for motherboards with the mga2064w
+ * will be added (no video BIOS) - this is not a huge concern
+ * for me today though. (XXX)
+ *
+ * EXTERNAL REFERENCES
+ * vga256InfoRec.BIOSbase IN Physical address of video BIOS.
+ * MGABios OUT The video BIOS info block.
+ *
+ * HISTORY
+ * August 31, 1997 - [ajv] Andrew van der Stock
+ * Fixed to understand Mystique and Millennium II
+ *
+ * January 11, 1997 - [aem] Andrew E. Mileski
+ * Set default values for GCLK (= MCLK / pre-scale ).
+ *
+ * October 7, 1996 - [aem] Andrew E. Mileski
+ * Written and tested.
+ */
+
+static void
+MGAReadBios(ScrnInfoPtr pScrn)
+{
+ CARD8 tmp[ 64 ];
+ CARD16 offset;
+ CARD8 chksum;
+ CARD8 *pPINSInfo;
+ MGAPtr pMga;
+ MGABiosInfo *pBios;
+ MGABios2Info *pBios2;
+ Bool pciBIOS = TRUE;
+
+ pMga = MGAPTR(pScrn);
+ pBios = &pMga->Bios;
+ pBios2 = &pMga->Bios2;
+
+ /*
+ * If the BIOS address was probed, it was found from the PCI config
+ * space. If it was given in the config file, try to guess when it
+ * looks like it might be controlled by the PCI config space.
+ */
+ if (pMga->BiosFrom == X_DEFAULT)
+ pciBIOS = FALSE;
+ else if (pMga->BiosFrom == X_CONFIG && pMga->BiosAddress < 0x100000)
+ pciBIOS = TRUE;
+
+#define MGADoBIOSRead(offset, buf, len) \
+ (pciBIOS ? \
+ xf86ReadPciBIOS(offset, pMga->PciTag, pMga->FbBaseReg, buf, len) : \
+ xf86ReadBIOS(pMga->BiosAddress, offset, buf, len))
+
+ MGADoBIOSRead(0, tmp, sizeof( tmp ));
+ if (
+ tmp[ 0 ] != 0x55
+ || tmp[ 1 ] != 0xaa
+ || strncmp(( char * )( tmp + 45 ), "MATROX", 6 )
+ ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Video BIOS info block not detected!\n");
+ return;
+ }
+
+ /* Get the info block offset */
+ MGADoBIOSRead(0x7ffc, ( CARD8 * ) & offset, sizeof( offset ));
+
+
+ /* Let the world know what we are up to */
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Video BIOS info block at offset 0x%05lX\n",
+ (long)(offset));
+
+ /* Copy the info block */
+ switch (pMga->Chipset){
+ case PCI_CHIP_MGA2064:
+ MGADoBIOSRead(offset,
+ ( CARD8 * ) & pBios->StructLen, sizeof( MGABiosInfo ));
+ break;
+ default:
+ MGADoBIOSRead(offset,
+ ( CARD8 * ) & pBios2->PinID, sizeof( MGABios2Info ));
+ }
+
+
+ /* matrox millennium-2 and mystique pins info */
+ if ( pBios2->PinID == 0x412e ) {
+ int i;
+ /* check that the pins info is correct */
+ if ( pBios2->StructLen != 0x40 ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Video BIOS info block not detected!\n");
+ pBios2->PinID = 0;
+ return;
+ }
+ /* check that the chksum is correct */
+ chksum = 0;
+ pPINSInfo = (CARD8 *) &pBios2->PinID;
+
+ for (i=0; i < pBios2->StructLen; i++) {
+ chksum += *pPINSInfo;
+ pPINSInfo++;
+ }
+
+ if ( chksum ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Video BIOS info block did not checksum!\n");
+ pBios2->PinID = 0;
+ return;
+ }
+
+ /* last check */
+ if ( pBios2->StructRev == 0 ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Video BIOS info block does not have a valid revision!\n");
+ pBios2->PinID = 0;
+ return;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Found and verified enhanced Video BIOS info block\n");
+
+ /* Set default MCLK values (scaled by 100 kHz) */
+ if ( pBios2->ClkMem == 0 )
+ pBios2->ClkMem = 50;
+ if ( pBios2->Clk4MB == 0 )
+ pBios2->Clk4MB = pBios->ClkBase;
+ if ( pBios2->Clk8MB == 0 )
+ pBios2->Clk8MB = pBios->Clk4MB;
+ pBios->StructLen = 0; /* not in use */
+#ifdef DEBUG
+ for (i = 0; i < 0x40; i++)
+ ErrorF("Pins[0x%02x] is 0x%02x\n", i,
+ ((unsigned char *)pBios2)[i]);
+#endif
+ ErrorF("0x20 of Pins[0x34] is %s\n",
+ (pBios2->VidCtrl & 0x20) ? "set" : "cleared");
+ return;
+ } else {
+ /* Set default MCLK values (scaled by 10 kHz) */
+ if ( pBios->ClkBase == 0 )
+ pBios->ClkBase = 4500;
+ if ( pBios->Clk4MB == 0 )
+ pBios->Clk4MB = pBios->ClkBase;
+ if ( pBios->Clk8MB == 0 )
+ pBios->Clk8MB = pBios->Clk4MB;
+ pBios2->PinID = 0; /* not in use */
+ return;
+ }
+}
+
+/*
+ * MGASoftReset --
+ *
+ * Resets drawing engine
+ */
+static void
+MGASoftReset(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ int i;
+
+ pMga->FbMapSize = 8192 * 1024;
+ MGAMapMem(pScrn);
+
+ /* set soft reset bit */
+ OUTREG(MGAREG_Reset, 1);
+ usleep(200);
+ OUTREG(MGAREG_Reset, 0);
+
+ /* reset memory */
+ OUTREG(MGAREG_MACCESS, 1<<15);
+ usleep(10);
+
+ /* wait until drawing engine is ready */
+ while ( MGAISBUSY() )
+ usleep(1000);
+
+ /* flush FIFO */
+ i = 32;
+ WAITFIFO(i);
+ while ( i-- )
+ OUTREG(MGAREG_SHIFT, 0);
+
+ MGAUnmapMem(pScrn);
+}
+
+/*
+ * MGACountRAM --
+ *
+ * Counts amount of installed RAM
+ */
+static int
+MGACountRam(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ if (pMga->FbAddress)
+ {
+ volatile unsigned char* base;
+ unsigned char tmp, tmp3, tmp5;
+
+ pMga->FbMapSize = 8192 * 1024;
+ MGAMapMem(pScrn);
+ base = pMga->FbBase;
+
+ /* turn MGA mode on - enable linear frame buffer (CRTCEXT3) */
+ OUTREG8(0x1FDE, 3);
+ tmp = INREG8(0x1FDF);
+ OUTREG8(0x1FDF, tmp | 0x80);
+
+ /* write, read and compare method */
+ base[0x500000] = 0x55;
+ base[0x300000] = 0x33;
+ base[0x100000] = 0x11;
+ tmp5 = base[0x500000];
+ tmp3 = base[0x300000];
+
+ /* restore CRTCEXT3 state */
+ OUTREG8(0x1FDE, 3);
+ OUTREG8(0x1FDF, tmp);
+
+ MGAUnmapMem(pScrn);
+
+ if(tmp5 == 0x55)
+ return 8192;
+ if(tmp3 == 0x33)
+ return 4096;
+ }
+ return 2048;
+}
+
+/*
+ * GetAccelPitchValues -
+ *
+ * This function returns a list of display width (pitch) values that can
+ * be used in accelerated mode.
+ */
+#if 0
+static int *
+GetAccelPitchValues(ScrnInfoPtr pScrn)
+{
+ int *linePitches = NULL;
+ int i, n = 0;
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ /* XXX ajv - 512, 576, and 1536 may not be supported
+ line pitches. see sdk pp 4-59 for more
+ details. Why anyone would want less than 640 is
+ bizarre. (maybe lots of pixels tall?) */
+
+ /* The only line pitches the accelerator supports */
+#if 0
+ int accelWidths[] = { 512, 576, 640, 768, 800, 960,
+ 1024, 1152, 1280, 1536, 1600, 1920, 2048, 0 };
+#else
+ int accelWidths[] = { 640, 768, 800, 960, 1024, 1152, 1280,
+ 1600, 1920, 2048, 0 };
+#endif
+
+ for (i = 0; accelWidths[i] != 0; i++) {
+ if (accelWidths[i] % pMga->Rounding == 0) {
+ n++;
+ linePitches = xnfrealloc(linePitches, n * sizeof(int));
+ linePitches[n - 1] = accelWidths[i];
+ }
+ }
+ /* Mark the end of the list */
+ if (n > 0) {
+ linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
+ linePitches[n] = 0;
+ }
+ return linePitches;
+}
+#endif
+
+static xf86MonPtr
+MGAdoDDC(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp;
+ MGAPtr pMga;
+ MGARamdacPtr MGAdac;
+ xf86MonPtr MonInfo = NULL;
+
+ hwp = VGAHWPTR(pScrn);
+ pMga = MGAPTR(pScrn);
+ MGAdac = &pMga->Dac;
+
+ /* Map the MGA memory and MMIO areas */
+ if (!MGAMapMem(pScrn))
+ return NULL;
+
+ /* Initialise the MMIO vgahw functions */
+ vgaHWSetMmioFuncs(hwp, pMga->IOBase, PORT_OFFSET);
+ vgaHWGetIOBase(hwp);
+
+ /* Map the VGA memory when the primary video */
+ if (pMga->Primary) {
+ hwp->MapSize = 0x10000;
+ if (!vgaHWMapMem(pScrn))
+ return NULL;
+ } else {
+ /* XXX Need to write an MGA mode ddc1SetSpeed */
+ if (pMga->DDC1SetSpeed == vgaHWddc1SetSpeed) {
+ pMga->DDC1SetSpeed = NULL;
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2,
+ "DDC1 disabled - chip not in VGA mode\n");
+ }
+ }
+
+ /* Save the current state */
+ MGASave(pScrn);
+
+ /* It is now safe to talk to the card */
+
+#if MGAuseI2C
+ /* Initialize I2C bus - used by DDC if available */
+ if (pMga->i2cInit) {
+ pMga->i2cInit(pScrn);
+ErrorF("I2C initialized on %p\n",pMga->I2C);
+ }
+ /* Read and output monitor info using DDC2 over I2C bus */
+ if (pMga->I2C) {
+ MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex,pMga->I2C);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "I2C Monitor info: %p\n", MonInfo);
+ xf86PrintEDID(MonInfo);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of I2C Monitor info\n\n");
+ }
+ if (!MonInfo)
+#endif /* MGAuseI2C */
+ /* Read and output monitor info using DDC1 */
+ if (pMga->ddc1Read && pMga->DDC1SetSpeed) {
+ MonInfo = xf86DoEDID_DDC1(pScrn->scrnIndex,
+ pMga->DDC1SetSpeed,
+ pMga->ddc1Read ) ;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC Monitor info: %p\n", MonInfo);
+ xf86PrintEDID( MonInfo );
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "end of DDC Monitor info\n\n");
+ }
+
+
+ /* Restore previous state and unmap MGA memory and MMIO areas */
+ MGARestore(pScrn);
+ MGAUnmapMem(pScrn);
+ /* Unmap vga memory if we mapped it */
+ if (xf86IsPrimaryPci(pMga->PciInfo) && !pMga->FBDev) {
+ vgaHWUnmapMem(pScrn);
+ }
+
+ return MonInfo;
+}
+
+#ifdef DISABLE_VGA_IO
+static void
+VgaIOSave(int i, void *arg)
+{
+ MgaSavePtr sMga = arg;
+ PCITAG tag = pciTag(sMga->pvp->bus,sMga->pvp->device,sMga->pvp->func);
+
+#ifdef DEBUG
+ ErrorF("mga: VgaIOSave: %d:%d:%d\n", sMga->pvp->bus, sMga->pvp->device,
+ sMga->pvp->func);
+#endif
+ sMga->enable = (pciReadLong(tag, PCI_OPTION_REG) & 0x100) != 0;
+}
+
+static void
+VgaIORestore(int i, void *arg)
+{
+ MgaSavePtr sMga = arg;
+ PCITAG tag = pciTag(sMga->pvp->bus,sMga->pvp->device,sMga->pvp->func);
+
+#ifdef DEBUG
+ ErrorF("mga: VgaIORestore: %d:%d:%d\n", sMga->pvp->bus, sMga->pvp->device,
+ sMga->pvp->func);
+#endif
+ pciSetBitsLong(tag, PCI_OPTION_REG, 0x100, sMga->enable ? 0x100 : 0x000);
+}
+
+static void
+VgaIODisable(void *arg)
+{
+ MGAPtr pMga = arg;
+
+#ifdef DEBUG
+ ErrorF("mga: VgaIODisable: %d:%d:%d, %s, xf86ResAccessEnter is %s\n",
+ pMga->PciInfo->bus, pMga->PciInfo->device, pMga->PciInfo->func,
+ pMga->Primary ? "primary" : "secondary",
+ BOOLTOSTRING(xf86ResAccessEnter));
+#endif
+ /* Turn off the vgaioen bit. */
+ pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, 0x100, 0x000);
+}
+
+static void
+VgaIOEnable(void *arg)
+{
+ MGAPtr pMga = arg;
+
+#ifdef DEBUG
+ ErrorF("mga: VgaIOEnable: %d:%d:%d, %s, xf86ResAccessEnter is %s\n",
+ pMga->PciInfo->bus, pMga->PciInfo->device, pMga->PciInfo->func,
+ pMga->Primary ? "primary" : "secondary",
+ BOOLTOSTRING(xf86ResAccessEnter));
+#endif
+ /* Turn on the vgaioen bit. */
+ if (pMga->Primary)
+ pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, 0x100, 0x100);
+}
+#endif /* DISABLE_VGA_IO */
+
+/* Mandatory */
+static Bool
+MGAPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ MGAPtr pMga;
+ MessageType from;
+ int i;
+ double real;
+ int bytesPerPixel;
+ ClockRangePtr clockRanges;
+ char *mod = NULL;
+ const char *reqSym = NULL;
+ const char *s;
+ int flags24;
+
+ /*
+ * Note: This function is only called once at server startup, and
+ * not at the start of each server generation. This means that
+ * only things that are persistent across server generations can
+ * be initialised here. xf86Screens[] is (pScrn is a pointer to one
+ * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex()
+ * are too, and should be used for data that must persist across
+ * server generations.
+ *
+ * Per-generation data should be allocated with
+ * AllocateScreenPrivateIndex() from the ScreenInit() function.
+ */
+
+ /* Check the number of entities, and fail if it isn't one. */
+ if (pScrn->numEntities != 1)
+ return FALSE;
+
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /*
+ * Allocate a vgaHWRec
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ /* Allocate the MGARec driverPrivate */
+ if (!MGAGetRec(pScrn)) {
+ return FALSE;
+ }
+ pMga = MGAPTR(pScrn);
+
+ /* Get the entity, and make sure it is PCI. */
+ pMga->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pMga->pEnt->location.type != BUS_PCI)
+ return FALSE;
+
+ /* Find the PCI info for this screen */
+ pMga->PciInfo = xf86GetPciInfoForEntity(pMga->pEnt->index);
+ pMga->PciTag = pciTag(pMga->PciInfo->bus, pMga->PciInfo->device,
+ pMga->PciInfo->func);
+
+ pMga->Primary = xf86IsPrimaryPci(pMga->PciInfo);
+
+#ifndef DISABLE_VGA_IO
+ {
+ resRange vgaio[] = { {ResShrIoBlock,0x3B0,0x3BB},
+ {ResShrIoBlock,0x3C0,0x3DF},
+ _END };
+ resRange vga1mem[] = { {ResShrMemBlock,0xA0000,0xAFFFF},
+ {ResShrMemBlock,0xB8000,0xBFFFF},
+ _END };
+ resRange vga2mem[] = { {ResShrMemBlock,0xB0000,0xB7FFF},
+ _END };
+ xf86SetOperatingState(vgaio, pMga->pEnt->index, ResUnusedOpr);
+ xf86SetOperatingState(vga1mem, pMga->pEnt->index, ResDisableOpr);
+ xf86SetOperatingState(vga2mem, pMga->pEnt->index, ResDisableOpr);
+ }
+#else
+ /*
+ * Set our own access functions, which control the vgaioen bit.
+ */
+ pMga->Access.AccessDisable = VgaIODisable;
+ pMga->Access.AccessEnable = VgaIOEnable;
+ pMga->Access.arg = pMga;
+ /* please check if this is correct. I've impiled that the VGA fb
+ is handled locally and not visible outside. If the VGA fb is
+ handeled by the same function the third argument has to be set,
+ too.*/
+ xf86SetAccessFuncs(pMga->pEnt, &pMga->Access, &pMga->Access,
+ &pMga->Access, NULL);
+#endif
+
+ pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*
+ * The first thing we should figure out is the depth, bpp, etc.
+ * Our default depth is 8, so pass it to the helper function.
+ * We support both 24bpp and 32bpp layouts, so indicate that.
+ */
+
+ /* Prefer 24bpp fb unless the Overlay option is set */
+ flags24 = Support24bppFb | Support32bppFb | SupportConvert32to24;
+ s = xf86TokenToOptName(MGAOptions, OPTION_OVERLAY);
+ if (!(xf86FindOption(pScrn->confScreen->options, s) ||
+ xf86FindOption(pMga->pEnt->device->options, s))) {
+ flags24 |= PreferConvert32to24;
+ }
+
+ if (!xf86SetDepthBpp(pScrn, 8, 8, 8, flags24)) {
+ return FALSE;
+ } else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 8:
+ case 15:
+ case 16:
+ case 24:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+ xf86PrintDepthBpp(pScrn);
+
+ /* Get the depth24 pixmap format */
+ if (pScrn->depth == 24 && pix24bpp == 0)
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ bytesPerPixel = pScrn->bitsPerPixel / 8;
+
+ /* We use a programamble clock */
+ pScrn->progClock = TRUE;
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, MGAOptions);
+
+ /* Set the bits per RGB for 8bpp mode */
+ if (pScrn->depth == 8) {
+ /* XXX This is here just to test options. */
+ /* Default to 8 */
+ pScrn->rgbBits = 8;
+#if 0
+ if (xf86GetOptValInteger(MGAOptions, OPTION_RGB_BITS,
+ &pScrn->rgbBits)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
+ pScrn->rgbBits);
+ }
+#endif
+ }
+
+
+ from = X_DEFAULT;
+ pMga->HWCursor = TRUE;
+ /*
+ * The preferred method is to use the "hw cursor" option as a tri-state
+ * option, with the default set above.
+ */
+ if (xf86GetOptValBool(MGAOptions, OPTION_HW_CURSOR, &pMga->HWCursor)) {
+ from = X_CONFIG;
+ }
+ /* For compatibility, accept this too (as an override) */
+ if (xf86ReturnOptValBool(MGAOptions, OPTION_SW_CURSOR, FALSE)) {
+ from = X_CONFIG;
+ pMga->HWCursor = FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pMga->HWCursor ? "HW" : "SW");
+ if (xf86ReturnOptValBool(MGAOptions, OPTION_NOACCEL, FALSE)) {
+ pMga->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+ if (xf86ReturnOptValBool(MGAOptions, OPTION_PCI_RETRY, FALSE)) {
+ pMga->UsePCIRetry = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
+ }
+ if (xf86ReturnOptValBool(MGAOptions, OPTION_SYNC_ON_GREEN, FALSE)) {
+ pMga->SyncOnGreen = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Sync-on-Green enabled\n");
+ }
+ if (xf86ReturnOptValBool(MGAOptions, OPTION_SHOWCACHE, FALSE)) {
+ pMga->ShowCache = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShowCache enabled\n");
+ }
+ if (xf86ReturnOptValBool(MGAOptions, OPTION_MGA_SDRAM, FALSE)) {
+ pMga->HasSDRAM = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Has SDRAM\n");
+ }
+ if (xf86GetOptValFreq(MGAOptions, OPTION_SET_MCLK, OPTUNITS_MHZ, &real)) {
+ pMga->MemClk = (int)(real * 1000.0);
+ }
+ if ((s = xf86GetOptValString(MGAOptions, OPTION_OVERLAY))) {
+ if (!*s || !xf86NameCmp(s, "8,24") || !xf86NameCmp(s, "24,8")) {
+ if(pMga->Chipset == PCI_CHIP_MGAG100) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Option \"Overlay\" is not supported by the G100\n");
+ } else if(pScrn->bitsPerPixel == 32) {
+ pMga->Overlay8Plus24 = TRUE;
+ if(!xf86GetOptValInteger(
+ MGAOptions, OPTION_COLOR_KEY,&(pMga->colorKey)))
+ pMga->colorKey = TRANSPARENCY_KEY;
+ pScrn->colorKey = pMga->colorKey;
+ pScrn->overlayFlags = OVERLAY_8_32_PLANAR;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "PseudoColor overlay enabled\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Option \"Overlay\" is not supported in this configuration\n");
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "\"%s\" is not a valid value for Option \"Overlay\"\n", s);
+ }
+ }
+ if (xf86ReturnOptValBool(MGAOptions, OPTION_SHADOW_FB, FALSE)) {
+ pMga->ShadowFB = TRUE;
+ pMga->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using \"Shadow Framebuffer\" - acceleration disabled\n");
+ }
+ if (xf86ReturnOptValBool(MGAOptions, OPTION_FBDEV, FALSE)) {
+ pMga->FBDev = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using framebuffer device\n");
+ }
+ if (xf86ReturnOptValBool(MGAOptions, OPTION_OVERCLOCK_MEM, FALSE)) {
+ pMga->OverclockMem = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Overclocking memory\n");
+ }
+ if (pMga->FBDev) {
+ /* check for linux framebuffer device */
+ if (!xf86LoadSubModule(pScrn, "fbdevhw"))
+ return FALSE;
+ xf86LoaderReqSymLists(fbdevHWSymbols, NULL);
+ if (!fbdevHWInit(pScrn, pMga->PciInfo, NULL))
+ return FALSE;
+ pScrn->SwitchMode = fbdevHWSwitchMode;
+ pScrn->AdjustFrame = fbdevHWAdjustFrame;
+ pScrn->EnterVT = MGAEnterVTFBDev;
+ pScrn->LeaveVT = fbdevHWLeaveVT;
+ pScrn->ValidMode = fbdevHWValidMode;
+ }
+ pMga->Rotate = 0;
+ if ((s = xf86GetOptValString(MGAOptions, OPTION_ROTATE))) {
+ if(!xf86NameCmp(s, "CW")) {
+ pMga->ShadowFB = TRUE;
+ pMga->NoAccel = TRUE;
+ pMga->HWCursor = FALSE;
+ pMga->Rotate = 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Rotating screen clockwise - acceleration disabled\n");
+ } else
+ if(!xf86NameCmp(s, "CCW")) {
+ pMga->ShadowFB = TRUE;
+ pMga->NoAccel = TRUE;
+ pMga->HWCursor = FALSE;
+ pMga->Rotate = -1;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Rotating screen counter clockwise - acceleration disabled\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "\"%s\" is not a valid value for Option \"Rotate\"\n", s);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Valid options are \"CW\" or \"CCW\"\n");
+ }
+ }
+
+
+ /*
+ * Set the Chipset and ChipRev, allowing config file entries to
+ * override.
+ */
+ if (pMga->pEnt->device->chipset && *pMga->pEnt->device->chipset) {
+ pScrn->chipset = pMga->pEnt->device->chipset;
+ pMga->Chipset = xf86StringToToken(MGAChipsets, pScrn->chipset);
+ from = X_CONFIG;
+ } else if (pMga->pEnt->device->chipID >= 0) {
+ pMga->Chipset = pMga->pEnt->device->chipID;
+ pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset);
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pMga->Chipset);
+ } else {
+ from = X_PROBED;
+ pMga->Chipset = pMga->PciInfo->chipType;
+ pScrn->chipset = (char *)xf86TokenToString(MGAChipsets, pMga->Chipset);
+ }
+ if (pMga->pEnt->device->chipRev >= 0) {
+ pMga->ChipRev = pMga->pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pMga->ChipRev);
+ } else {
+ pMga->ChipRev = pMga->PciInfo->chipRev;
+ }
+
+ /*
+ * This shouldn't happen because such problems should be caught in
+ * MGAProbe(), but check it just in case.
+ */
+ if (pScrn->chipset == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ChipID 0x%04X is not recognised\n", pMga->Chipset);
+ return FALSE;
+ }
+ if (pMga->Chipset < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Chipset \"%s\" is not recognised\n", pScrn->chipset);
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
+
+ if ((pMga->PciInfo->subsysCard == PCI_CARD_MILL_G200_SD) ||
+ (pMga->PciInfo->subsysCard == PCI_CARD_MARV_G200_SD) ||
+ (pMga->PciInfo->subsysCard == PCI_CARD_MYST_G200_SD) ||
+ (pMga->PciInfo->subsysCard == PCI_CARD_PROD_G100_SD)) {
+ pMga->HasSDRAM = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Has SDRAM\n");
+ }
+
+ switch (pMga->Chipset) {
+ case PCI_CHIP_MGA2064:
+ case PCI_CHIP_MGA2164:
+ case PCI_CHIP_MGA2164_AGP:
+ MGA2064SetupFuncs(pScrn);
+ break;
+ case PCI_CHIP_MGA1064:
+ case PCI_CHIP_MGAG100:
+ case PCI_CHIP_MGAG200:
+ case PCI_CHIP_MGAG200_PCI:
+ case PCI_CHIP_MGAG400:
+ MGAGSetupFuncs(pScrn);
+ break;
+ }
+
+ /* ajv changes to reflect actual values. see sdk pp 3-2. */
+ /* these masks just get rid of the crap in the lower bits */
+
+ /*
+ * For the 2064 and older rev 1064, base0 is the MMIO and base0 is
+ * the framebuffer is base1. Let the config file override these.
+ */
+ if (pMga->pEnt->device->MemBase != 0) {
+ /* Require that the config file value matches one of the PCI values. */
+ if (!xf86CheckPciMemBase(pMga->PciInfo, pMga->pEnt->device->MemBase)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "MemBase 0x%08lX doesn't match any PCI base register.\n",
+ pMga->pEnt->device->MemBase);
+ MGAFreeRec(pScrn);
+ return FALSE;
+ }
+ pMga->FbAddress = pMga->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ /* details: mgabase2 sdk pp 4-12 */
+ int i = ((pMga->Chipset == PCI_CHIP_MGA1064 && pMga->ChipRev < 3) ||
+ pMga->Chipset == PCI_CHIP_MGA2064) ? 1 : 0;
+ pMga->FbBaseReg = i;
+ if (pMga->PciInfo->memBase[i] != 0) {
+ pMga->FbAddress = pMga->PciInfo->memBase[i] & 0xff800000;
+ from = X_PROBED;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid FB address in PCI config space\n");
+ MGAFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pMga->FbAddress);
+
+ if (pMga->pEnt->device->IOBase != 0) {
+ /* Require that the config file value matches one of the PCI values. */
+ if (!xf86CheckPciMemBase(pMga->PciInfo, pMga->pEnt->device->IOBase)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "IOBase 0x%08lX doesn't match any PCI base register.\n",
+ pMga->pEnt->device->IOBase);
+ MGAFreeRec(pScrn);
+ return FALSE;
+ }
+ pMga->IOAddress = pMga->pEnt->device->IOBase;
+ from = X_CONFIG;
+ } else {
+ /* details: mgabase1 sdk pp 4-11 */
+ int i = ((pMga->Chipset == PCI_CHIP_MGA1064 && pMga->ChipRev < 3) ||
+ pMga->Chipset == PCI_CHIP_MGA2064) ? 0 : 1;
+ if (pMga->PciInfo->memBase[i] != 0) {
+ pMga->IOAddress = pMga->PciInfo->memBase[i] & 0xffffc000;
+ from = X_PROBED;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid MMIO address in PCI config space\n");
+ MGAFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
+ (unsigned long)pMga->IOAddress);
+
+
+ pMga->ILOADAddress = 0;
+ if ( pMga->Chipset != PCI_CHIP_MGA2064 ) {
+ if (pMga->PciInfo->memBase[2] != 0) {
+ pMga->ILOADAddress = pMga->PciInfo->memBase[2] & 0xffffc000;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Pseudo-DMA transfer window at 0x%lX\n",
+ (unsigned long)pMga->ILOADAddress);
+ }
+ }
+
+
+ /*
+ * Find the BIOS base. Get it from the PCI config if possible. Otherwise
+ * use the VGA default. Allow the config file to override this.
+ */
+
+ pMga->BiosFrom = X_NONE;
+ if (pMga->pEnt->device->BiosBase != 0) {
+ /* XXX This isn't used */
+ pMga->BiosAddress = pMga->pEnt->device->BiosBase;
+ pMga->BiosFrom = X_CONFIG;
+ } else {
+ /* details: rombase sdk pp 4-15 */
+ if (pMga->PciInfo->biosBase != 0) {
+ pMga->BiosAddress = pMga->PciInfo->biosBase & 0xffff0000;
+ pMga->BiosFrom = X_PROBED;
+ } else if (pMga->Primary) {
+ pMga->BiosAddress = 0xc0000;
+ pMga->BiosFrom = X_DEFAULT;
+ }
+ }
+ if (pMga->BiosAddress) {
+ xf86DrvMsg(pScrn->scrnIndex, pMga->BiosFrom, "BIOS at 0x%lX\n",
+ (unsigned long)pMga->BiosAddress);
+ }
+
+ if (xf86RegisterResources(pMga->pEnt->index, NULL, ResExclusive)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n");
+ MGAFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /*
+ * Read the BIOS data struct
+ */
+
+ MGAReadBios(pScrn);
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2,
+ "MGABios.RamdacType = 0x%x\n", pMga->Bios.RamdacType);
+
+ /* HW bpp matches reported bpp */
+ pMga->HwBpp = pScrn->bitsPerPixel;
+
+ /*
+ * Reset card if it isn't primary one
+ */
+ if (!pMga->Primary && !pMga->FBDev)
+ MGASoftReset(pScrn);
+ /*
+ * If the user has specified the amount of memory in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pMga->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pMga->pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else if((pMga->Chipset == PCI_CHIP_MGA2164) ||
+ (pMga->Chipset == PCI_CHIP_MGA2164_AGP)){
+ pScrn->videoRam = 4096;
+ from = X_DEFAULT;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Skipping memory probe due to hardware bug. Assuming 4096 kBytes\n");
+ } else {
+ if (pMga->FBDev) {
+ pScrn->videoRam = fbdevHWGetVidmem(pScrn)/1024;
+ } else {
+ pScrn->videoRam = MGACountRam(pScrn);
+ }
+ from = X_PROBED;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+
+ pMga->FbMapSize = pScrn->videoRam * 1024;
+
+ /* Set the bpp shift value */
+ pMga->BppShifts[0] = 0;
+ pMga->BppShifts[1] = 1;
+ pMga->BppShifts[2] = 0;
+ pMga->BppShifts[3] = 2;
+
+ /*
+ * fill MGAdac struct
+ * Warning: currently, it should be after RAM counting
+ */
+ (*pMga->PreInit)(pScrn);
+
+ /* Load DDC if we have the code to use it */
+ /* This gives us DDC1 */
+ if (pMga->ddc1Read || pMga->i2cInit) {
+ if (xf86LoadSubModule(pScrn, "ddc")) {
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+ } else {
+ /* ddc module not found, we can do without it */
+ pMga->ddc1Read = NULL;
+
+ /* Without DDC, we have no use for the I2C bus */
+ pMga->i2cInit = NULL;
+ }
+ }
+#if MGAuseI2C
+ /* - DDC can use I2C bus */
+ /* Load I2C if we have the code to use it */
+ if (pMga->i2cInit) {
+ if ( xf86LoadSubModule(pScrn, "i2c") ) {
+ xf86LoaderReqSymLists(i2cSymbols,NULL);
+ } else {
+ /* i2c module not found, we can do without it */
+ pMga->i2cInit = NULL;
+ pMga->I2C = NULL;
+ }
+ }
+#endif /* MGAuseI2C */
+
+ /* Read and print the Monitor DDC info */
+ pScrn->monitor->DDC = MGAdoDDC(pScrn);
+
+ /*
+ * If the driver can do gamma correction, it should call xf86SetGamma()
+ * here.
+ */
+
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+
+
+ /* XXX Set HW cursor use */
+
+ /* Set the min pixel clock */
+ pMga->MinClock = 12000; /* XXX Guess, need to check this */
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
+ pMga->MinClock / 1000);
+ /*
+ * If the user has specified ramdac speed in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pMga->pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ speed = pMga->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ speed = pMga->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ speed = pMga->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ case 32:
+ speed = pMga->pEnt->device->dacSpeeds[DAC_BPP32];
+ break;
+ }
+ if (speed == 0)
+ pMga->MaxClock = pMga->pEnt->device->dacSpeeds[0];
+ else
+ pMga->MaxClock = speed;
+ from = X_CONFIG;
+ } else {
+ pMga->MaxClock = pMga->Dac.maxPixelClock;
+ from = pMga->Dac.ClockFrom;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
+ pMga->MaxClock / 1000);
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+ clockRanges = xnfalloc(sizeof(ClockRange));
+ clockRanges->next = NULL;
+ clockRanges->minClock = pMga->MinClock;
+ clockRanges->maxClock = pMga->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = TRUE;
+
+ /* Only set MemClk if appropriate for the ramdac */
+ if (pMga->Dac.SetMemClk) {
+ if (pMga->MemClk == 0) {
+ pMga->MemClk = pMga->Dac.MemoryClock;
+ from = pMga->Dac.MemClkFrom;
+ } else
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, from, "MCLK used is %.1f MHz\n",
+ pMga->MemClk / 1000.0);
+ }
+
+ /*
+ * xf86ValidateModes will check that the mode HTotal and VTotal values
+ * don't exceed the chipset's limit if pScrn->maxHValue and
+ * pScrn->maxVValue are set. Since our MGAValidMode() already takes
+ * care of this, we don't worry about setting them here.
+ */
+ {
+ int Pitches1[] =
+ {640, 768, 800, 960, 1024, 1152, 1280, 1600, 1920, 2048, 0};
+ int Pitches2[] =
+ {512, 640, 768, 800, 832, 960, 1024, 1152, 1280, 1600, 1664,
+ 1920, 2048, 0};
+ int *linePitches = NULL;
+ int minPitch = 256;
+ int maxPitch = 2048;
+
+ switch(pMga->Chipset) {
+ case PCI_CHIP_MGA2064:
+ if (!pMga->NoAccel) {
+ linePitches = xalloc(sizeof(Pitches1));
+ memcpy(linePitches, Pitches1, sizeof(Pitches1));
+ minPitch = maxPitch = 0;
+ }
+ break;
+ case PCI_CHIP_MGA2164:
+ case PCI_CHIP_MGA2164_AGP:
+ case PCI_CHIP_MGA1064:
+ if (!pMga->NoAccel) {
+ linePitches = xalloc(sizeof(Pitches2));
+ memcpy(linePitches, Pitches2, sizeof(Pitches2));
+ minPitch = maxPitch = 0;
+ }
+ break;
+ case PCI_CHIP_MGAG100:
+ maxPitch = 2048;
+ break;
+ case PCI_CHIP_MGAG200:
+ case PCI_CHIP_MGAG200_PCI:
+ case PCI_CHIP_MGAG400:
+ maxPitch = 4096;
+ break;
+ }
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ linePitches, minPitch, maxPitch,
+ pMga->Roundings[(pScrn->bitsPerPixel >> 3) - 1] *
+ pScrn->bitsPerPixel, 128, 2048,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pMga->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+
+ if (linePitches)
+ xfree(linePitches);
+ }
+
+
+ if (i < 1 && pMga->FBDev) {
+ fbdevHWUseBuildinMode(pScrn);
+ pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */
+ i = 1;
+ }
+ if (i == -1) {
+ MGAFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ MGAFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /*
+ * Set the CRTC parameters for all of the modes based on the type
+ * of mode, and the chipset's interlace requirements.
+ *
+ * Calling this is required if the mode->Crtc* values are used by the
+ * driver and if the driver doesn't provide code to set them. They
+ * are not pre-initialised at all.
+ */
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /*
+ * Compute the byte offset into the linear frame buffer where the
+ * frame buffer data should actually begin. According to DDK misc.c
+ * line 1023, if more than 4MB is to be displayed, YDSTORG must be set
+ * appropriately to align memory bank switching, and this requires a
+ * corresponding offset on linear frame buffer access.
+ * This is only needed for WRAM.
+ */
+
+ pMga->YDstOrg = 0;
+ if (((pMga->Chipset == PCI_CHIP_MGA2064) ||
+ (pMga->Chipset == PCI_CHIP_MGA2164) ||
+ (pMga->Chipset == PCI_CHIP_MGA2164_AGP)) &&
+ (pScrn->virtualX * pScrn->virtualY * bytesPerPixel > 4*1024*1024))
+ {
+ int offset, offset_modulo, ydstorg_modulo;
+
+ offset = (4*1024*1024) % (pScrn->displayWidth * bytesPerPixel);
+ offset_modulo = 4;
+ ydstorg_modulo = 64;
+ if (pScrn->bitsPerPixel == 24)
+ offset_modulo *= 3;
+ if (pMga->Interleave)
+ {
+ offset_modulo <<= 1;
+ ydstorg_modulo <<= 1;
+ }
+ pMga->YDstOrg = offset / bytesPerPixel;
+
+ /*
+ * When this was unconditional, it caused a line of horizontal garbage
+ * at the middle right of the screen at the 4Meg boundary in 32bpp
+ * (and presumably any other modes that use more than 4M). But it's
+ * essential for 24bpp (it may not matter either way for 8bpp & 16bpp,
+ * I'm not sure; I didn't notice problems when I checked with and
+ * without.)
+ * DRM Doug Merritt 12/97, submitted to XFree86 6/98 (oops)
+ */
+ if (bytesPerPixel < 4) {
+ while ((offset % offset_modulo) != 0 ||
+ (pMga->YDstOrg % ydstorg_modulo) != 0) {
+ offset++;
+ pMga->YDstOrg = offset / bytesPerPixel;
+ }
+ }
+ }
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "YDstOrg is set to %d\n",
+ pMga->YDstOrg);
+ pMga->FbUsableSize = pMga->FbMapSize - pMga->YDstOrg * bytesPerPixel;
+ /*
+ * XXX This should be taken into account in some way in the mode valdation
+ * section.
+ */
+
+ /* Allocate HW cursor buffer at the end of video ram */
+ if( pMga->HWCursor && pMga->Dac.CursorOffscreenMemSize ) {
+ if( pScrn->virtualY * pScrn->displayWidth * pScrn->bitsPerPixel / 8 <=
+ pMga->FbUsableSize - pMga->Dac.CursorOffscreenMemSize ) {
+ pMga->FbUsableSize -= pMga->Dac.CursorOffscreenMemSize;
+ pMga->FbCursorOffset =
+ pMga->FbMapSize - pMga->Dac.CursorOffscreenMemSize;
+ } else {
+ pMga->HWCursor = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Too little offscreen memory for HW cursor; using SW cursor\n");
+ }
+ }
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ mod = "cfb";
+ reqSym = "cfbScreenInit";
+ break;
+ case 16:
+ mod = "cfb16";
+ reqSym = "cfb16ScreenInit";
+ break;
+ case 24:
+ if (pix24bpp == 24) {
+ mod = "cfb24";
+ reqSym = "cfb24ScreenInit";
+ } else {
+ mod = "xf24_32bpp";
+ reqSym = "cfb24_32ScreenInit";
+ }
+ break;
+ case 32:
+ if (pMga->Overlay8Plus24) {
+ mod = "xf8_32bpp";
+ reqSym = "cfb8_32ScreenInit";
+ xf86LoaderReqSymLists(xf8_32bppSymbols, NULL);
+ } else {
+ mod = "cfb32";
+ reqSym = "cfb32ScreenInit";
+
+ }
+ break;
+ }
+ if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ MGAFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymbols(reqSym, NULL);
+
+ /* Load XAA if needed */
+ if (!pMga->NoAccel) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ MGAFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ /* Load ramdac if needed */
+ if (pMga->HWCursor) {
+ if (!xf86LoadSubModule(pScrn, "ramdac")) {
+ MGAFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+ }
+
+ /* Load shadowfb if needed */
+ if (pMga->ShadowFB) {
+ if (!xf86LoadSubModule(pScrn, "shadowfb")) {
+ MGAFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+ }
+
+ pMga->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel;
+ pMga->CurrentLayout.depth = pScrn->depth;
+ pMga->CurrentLayout.displayWidth = pScrn->displayWidth;
+ pMga->CurrentLayout.weight.red = pScrn->weight.red;
+ pMga->CurrentLayout.weight.green = pScrn->weight.green;
+ pMga->CurrentLayout.weight.blue = pScrn->weight.blue;
+ pMga->CurrentLayout.Overlay8Plus24 = pMga->Overlay8Plus24;
+
+ return TRUE;
+}
+
+
+/*
+ * Map the framebuffer and MMIO memory.
+ */
+
+static Bool
+MGAMapMem(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga;
+ int mmioFlags;
+
+ pMga = MGAPTR(pScrn);
+
+ /*
+ * Map IO registers to virtual address space
+ */
+#if !defined(__alpha__)
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
+#else
+ /*
+ * For Alpha, we need to map SPARSE memory, since we need
+ * byte/short access.
+ */
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT | VIDMEM_SPARSE;
+#endif
+ pMga->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pMga->PciTag,
+ pMga->IOAddress, 0x4000);
+ if (pMga->IOBase == NULL)
+ return FALSE;
+
+#ifdef __alpha__
+ /*
+ * for Alpha, we need to map DENSE memory as well, for
+ * setting CPUToScreenColorExpandBase.
+ */
+ pMga->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pMga->PciTag, pMga->IOAddress, 0x4000);
+ if (pMga->IOBaseDense == NULL)
+ return FALSE;
+#endif /* __alpha__ */
+
+ pMga->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pMga->PciTag, pMga->FbAddress,
+ pMga->FbMapSize);
+ if (pMga->FbBase == NULL)
+ return FALSE;
+
+ pMga->FbStart = pMga->FbBase + pMga->YDstOrg * (pScrn->bitsPerPixel / 8);
+
+
+ /* Map the ILOAD transfer window if there is one. We only make
+ DWORD access on DWORD boundaries to this window */
+ if (pMga->ILOADAddress) {
+ pMga->ILOADBase = xf86MapPciMem(pScrn->scrnIndex,
+ VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
+ pMga->PciTag, pMga->ILOADAddress, 0x800000);
+ } else
+ pMga->ILOADBase = NULL;
+
+ return TRUE;
+}
+
+static Bool
+MGAMapMemFBDev(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga;
+
+ pMga = MGAPTR(pScrn);
+
+ pMga->FbBase = fbdevHWMapVidmem(pScrn);
+ if (pMga->FbBase == NULL)
+ return FALSE;
+
+ pMga->IOBase = fbdevHWMapMMIO(pScrn);
+ if (pMga->IOBase == NULL)
+ return FALSE;
+
+ pMga->FbStart = pMga->FbBase + pMga->YDstOrg * (pScrn->bitsPerPixel / 8);
+
+#if 1 /* can't ask matroxfb for a mapping of the iload window */
+
+ /* Map the ILOAD transfer window if there is one. We only make
+ DWORD access on DWORD boundaries to this window */
+ if(pMga->ILOADAddress)
+ pMga->ILOADBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pMga->PciTag, pMga->ILOADAddress, 0x800000);
+ else pMga->ILOADBase = NULL;
+#endif
+ return TRUE;
+}
+
+
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+MGAUnmapMem(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga;
+
+ pMga = MGAPTR(pScrn);
+
+ /*
+ * Unmap IO registers to virtual address space
+ */
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->IOBase, 0x4000);
+ pMga->IOBase = NULL;
+
+#ifdef __alpha__
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->IOBaseDense, 0x4000);
+ pMga->IOBaseDense = NULL;
+#endif /* __alpha__ */
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->FbBase, pMga->FbMapSize);
+ pMga->FbBase = NULL;
+ pMga->FbStart = NULL;
+
+ if(pMga->ILOADBase)
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->ILOADBase, 0x800000);
+ pMga->ILOADBase = NULL;
+ return TRUE;
+}
+
+static Bool
+MGAUnmapMemFBDev(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga;
+
+ pMga = MGAPTR(pScrn);
+ fbdevHWUnmapVidmem(pScrn);
+ pMga->FbBase = NULL;
+ pMga->FbStart = NULL;
+ fbdevHWUnmapMMIO(pScrn);
+ pMga->IOBase = NULL;
+ /* XXX ILOADBase */
+ return TRUE;
+}
+
+
+
+
+/*
+ * This function saves the video state.
+ */
+static void
+MGASave(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &hwp->SavedReg;
+ MGAPtr pMga = MGAPTR(pScrn);
+ MGARegPtr mgaReg = &pMga->SavedReg;
+
+ /* Only save text mode fonts/text for the primary card */
+ (*pMga->Save)(pScrn, vgaReg, mgaReg, pMga->Primary);
+}
+
+
+/*
+ * Initialise a new mode. This is currently still using the old
+ * "initialise struct, restore/write struct to HW" model. That could
+ * be changed.
+ */
+
+static Bool
+MGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg;
+ MGAPtr pMga = MGAPTR(pScrn);
+ MGARegPtr mgaReg;
+
+ vgaHWUnlock(hwp);
+
+ /* Initialise the ModeReg values */
+ if (!vgaHWInit(pScrn, mode))
+ return FALSE;
+ pScrn->vtSema = TRUE;
+
+ if (!(*pMga->ModeInit)(pScrn, mode))
+ return FALSE;
+
+ /* Program the registers */
+ vgaHWProtect(pScrn, TRUE);
+ vgaReg = &hwp->ModeReg;
+ mgaReg = &pMga->ModeReg;
+
+ (*pMga->Restore)(pScrn, vgaReg, mgaReg, FALSE);
+
+ MGAStormSync(pScrn);
+ MGAStormEngineInit(pScrn);
+ vgaHWProtect(pScrn, FALSE);
+
+ if (xf86IsPc98()) {
+ if (pMga->Chipset == PCI_CHIP_MGA2064)
+ outb(0xfac, 0x01);
+ else
+ outb(0xfac, 0x02);
+ }
+
+ return TRUE;
+}
+
+/*
+ * Restore the initial (text) mode.
+ */
+static void
+MGARestore(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &hwp->SavedReg;
+ MGAPtr pMga = MGAPTR(pScrn);
+ MGARegPtr mgaReg = &pMga->SavedReg;
+
+ MGAStormSync(pScrn);
+
+ /* Only restore text mode fonts/text for the primary card */
+ vgaHWProtect(pScrn, TRUE);
+ if (pMga->Primary)
+ (*pMga->Restore)(pScrn, vgaReg, mgaReg, TRUE);
+ else
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+ vgaHWProtect(pScrn, FALSE);
+}
+
+
+/* Mandatory */
+
+/* This gets called at the start of each server generation */
+
+static Bool
+MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ MGAPtr pMga;
+ MGARamdacPtr MGAdac;
+ int ret;
+ VisualPtr visual;
+ unsigned char *FBStart;
+ int width, height, displayWidth;
+
+ /*
+ * First get the ScrnInfoRec
+ */
+ pScrn = xf86Screens[pScreen->myNum];
+
+ hwp = VGAHWPTR(pScrn);
+ pMga = MGAPTR(pScrn);
+ MGAdac = &pMga->Dac;
+
+ /* Map the MGA memory and MMIO areas */
+ if (pMga->FBDev) {
+ if (!MGAMapMemFBDev(pScrn))
+ return FALSE;
+ } else {
+ if (!MGAMapMem(pScrn))
+ return FALSE;
+ }
+
+ /* Initialise the MMIO vgahw functions */
+ vgaHWSetMmioFuncs(hwp, pMga->IOBase, PORT_OFFSET);
+ vgaHWGetIOBase(hwp);
+
+ /* Map the VGA memory when the primary video */
+ if (pMga->Primary && !pMga->FBDev) {
+ hwp->MapSize = 0x10000;
+ if (!vgaHWMapMem(pScrn))
+ return FALSE;
+ }
+
+ if (pMga->FBDev) {
+ fbdevHWSave(pScrn);
+ /* Disable VGA core, and leave memory access on */
+ pciSetBitsLong(pMga->PciTag, PCI_OPTION_REG, 0x100, 0x000);
+ if (!fbdevHWModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ MGAStormSync(pScrn);
+ MGAStormEngineInit(pScrn);
+ } else {
+ /* Save the current state */
+ MGASave(pScrn);
+ /* Initialise the first mode */
+ if (!MGAModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ }
+
+
+ /* Darken the screen for aesthetic reasons and set the viewport */
+ MGASaveScreen(pScreen, FALSE);
+ pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset the visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ /* All MGA support DirectColor and can do overlays in 32bpp */
+ if(pMga->Overlay8Plus24 && (pScrn->bitsPerPixel == 32)) {
+ if (!miSetVisualTypes(8, PseudoColorMask | GrayScaleMask,
+ pScrn->rgbBits, PseudoColor))
+ return FALSE;
+ if (!miSetVisualTypes(24, TrueColorMask, pScrn->rgbBits, TrueColor))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+
+ width = pScrn->virtualX;
+ height = pScrn->virtualY;
+ displayWidth = pScrn->displayWidth;
+
+
+ if(pMga->Rotate) {
+ height = pScrn->virtualX;
+ width = pScrn->virtualY;
+ }
+
+ if(pMga->ShadowFB) {
+ pMga->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width);
+ pMga->ShadowPtr = xalloc(pMga->ShadowPitch * height);
+ displayWidth = pMga->ShadowPitch / (pScrn->bitsPerPixel >> 3);
+ FBStart = pMga->ShadowPtr;
+ } else {
+ pMga->ShadowPtr = NULL;
+ FBStart = pMga->FbStart;
+ }
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ ret = cfbScreenInit(pScreen, FBStart,
+ width, height,
+ pScrn->xDpi, pScrn->yDpi,
+ displayWidth);
+ break;
+ case 16:
+ ret = cfb16ScreenInit(pScreen, FBStart,
+ width, height,
+ pScrn->xDpi, pScrn->yDpi,
+ displayWidth);
+ break;
+ case 24:
+ if (pix24bpp == 24)
+ ret = cfb24ScreenInit(pScreen, FBStart,
+ width, height,
+ pScrn->xDpi, pScrn->yDpi,
+ displayWidth);
+ else
+ ret = cfb24_32ScreenInit(pScreen, FBStart,
+ width, height,
+ pScrn->xDpi, pScrn->yDpi,
+ displayWidth);
+ break;
+ case 32:
+ if(pMga->Overlay8Plus24)
+ ret = cfb8_32ScreenInit(pScreen, FBStart,
+ width, height,
+ pScrn->xDpi, pScrn->yDpi,
+ displayWidth);
+ else
+ ret = cfb32ScreenInit(pScreen, FBStart,
+ width, height,
+ pScrn->xDpi, pScrn->yDpi,
+ displayWidth);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in MGAScreenInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ if (!ret)
+ return FALSE;
+
+
+ if (pScrn->bitsPerPixel > 8) {
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ if(!pMga->ShadowFB) /* hardware cursor needs to wrap this layer */
+ MGADGAInit(pScreen);
+
+ if (!pMga->NoAccel)
+ MGAStormAccelInit(pScreen);
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ /* Initialize software cursor.
+ Must precede creation of the default colormap */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ /* Initialize HW cursor layer.
+ Must follow software cursor initialization*/
+ if (pMga->HWCursor) {
+ if(!MGAHWCursorInit(pScreen))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ }
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ /* Initialize colormap layer.
+ Must follow initialization of the default colormap */
+ if(!xf86HandleColormaps(pScreen, 256, 8,
+ (pMga->FBDev ? fbdevHWLoadPalette : MGAdac->LoadPalette), NULL,
+ CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH))
+ return FALSE;
+
+ if(pMga->Overlay8Plus24) { /* Must come after colormap initialization */
+ if(!xf86Overlay8Plus32Init(pScreen))
+ return FALSE;
+ }
+
+ if(pMga->ShadowFB) {
+ RefreshAreaFuncPtr refreshArea = MGARefreshArea;
+
+ if(pMga->Rotate) {
+ pMga->PointerMoved = pScrn->PointerMoved;
+ pScrn->PointerMoved = MGAPointerMoved;
+
+ switch(pScrn->bitsPerPixel) {
+ case 8: refreshArea = MGARefreshArea8; break;
+ case 16: refreshArea = MGARefreshArea16; break;
+ case 24: refreshArea = MGARefreshArea24; break;
+ case 32: refreshArea = MGARefreshArea32; break;
+ }
+ }
+
+ ShadowFBInit(pScreen, refreshArea);
+ }
+
+#ifdef DPMSExtension
+ xf86DPMSInit(pScreen, MGADisplayPowerManagementSet, 0);
+#endif
+
+ pScrn->memPhysBase = pMga->FbAddress;
+ pScrn->fbOffset = pMga->YDstOrg * (pScrn->bitsPerPixel / 8);
+
+#ifdef XvExtension
+ {
+ XF86VideoAdaptorPtr *ptr;
+ int n;
+
+ n = xf86XVListGenericAdaptors(&ptr);
+ if (n) {
+ xf86XVScreenInit(pScreen, ptr, n);
+ }
+ }
+#endif
+
+ pScreen->SaveScreen = MGASaveScreen;
+
+ /* Wrap the current CloseScreen function */
+ pMga->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = MGACloseScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ /* Done */
+ return TRUE;
+}
+
+
+/* Usually mandatory */
+Bool
+MGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return MGAModeInit(xf86Screens[scrnIndex], mode);
+}
+
+
+/*
+ * This function is used to initialize the Start Address - the first
+ * displayed location in the video memory.
+ */
+/* Usually mandatory */
+void
+MGAAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn;
+ int Base, tmp, count;
+ MGAFBLayout *pLayout;
+ MGAPtr pMga;
+
+ pScrn = xf86Screens[scrnIndex];
+ pMga = MGAPTR(pScrn);
+ pLayout = &pMga->CurrentLayout;
+
+
+ if(pMga->ShowCache && y && pScrn->vtSema) {
+ int lastline = pMga->FbUsableSize /
+ (pScrn->displayWidth * pScrn->bitsPerPixel/8);
+
+ lastline -= pScrn->currentMode->VDisplay;
+ y += pScrn->virtualY - 1;
+ if(y > lastline) y = lastline;
+ }
+
+ Base = (y * pLayout->displayWidth + x + pMga->YDstOrg) >>
+ (3 - pMga->BppShifts[(pLayout->bitsPerPixel >> 3) - 1]);
+
+ if (pLayout->bitsPerPixel == 24) {
+ if (pMga->Chipset == PCI_CHIP_MGAG400)
+ Base &= ~1; /* Not sure why */
+ Base *= 3;
+ }
+
+ /* find start of retrace */
+ while (INREG8(0x1FDA) & 0x08);
+ while (!(INREG8(0x1FDA) & 0x08));
+ /* wait until we're past the start (fixseg.c in the DDK) */
+ count = INREG(MGAREG_VCOUNT) + 2;
+ while(INREG(MGAREG_VCOUNT) < count);
+
+ OUTREG16(MGAREG_CRTC_INDEX, (Base & 0x00FF00) | 0x0C);
+ OUTREG16(MGAREG_CRTC_INDEX, ((Base & 0x0000FF) << 8) | 0x0D);
+ OUTREG8(MGAREG_CRTCEXT_INDEX, 0x00);
+ tmp = INREG8(MGAREG_CRTCEXT_DATA);
+ OUTREG8(MGAREG_CRTCEXT_DATA, (tmp & 0xF0) | ((Base & 0x0F0000) >> 16));
+
+}
+
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ *
+ * We may wish to unmap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static Bool
+MGAEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ if (!MGAModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ MGAAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ return TRUE;
+}
+
+static Bool
+MGAEnterVTFBDev(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ fbdevHWEnterVT(scrnIndex,flags);
+ MGAStormSync(pScrn);
+ MGAStormEngineInit(pScrn);
+ return TRUE;
+}
+
+/*
+ * This is called when VT switching away from the X server. Its job is
+ * to restore the previous (text) mode.
+ *
+ * We may wish to remap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static void
+MGALeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ MGARestore(pScrn);
+ vgaHWLock(hwp);
+
+ if (xf86IsPc98())
+ outb(0xfac, 0x00);
+}
+
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode. It should also unmap the video memory, and free
+ * any per-generation data allocated by the driver. It should finish
+ * by unwrapping and calling the saved CloseScreen function.
+ */
+
+/* Mandatory */
+static Bool
+MGACloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ if (pScrn->vtSema) {
+ if (pMga->FBDev) {
+ fbdevHWRestore(pScrn);
+ MGAUnmapMemFBDev(pScrn);
+ } else {
+ MGARestore(pScrn);
+ vgaHWLock(hwp);
+ MGAUnmapMem(pScrn);
+ vgaHWUnmapMem(pScrn);
+ }
+ }
+ if (pMga->AccelInfoRec)
+ XAADestroyInfoRec(pMga->AccelInfoRec);
+ if (pMga->CursorInfoRec)
+ xf86DestroyCursorInfoRec(pMga->CursorInfoRec);
+ if (pMga->ShadowPtr)
+ xfree(pMga->ShadowPtr);
+ if (pMga->DGAModes)
+ xfree(pMga->DGAModes);
+ pScrn->vtSema = FALSE;
+
+ if (xf86IsPc98())
+ outb(0xfac, 0x00);
+
+ pScreen->CloseScreen = pMga->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+
+/* Free up any persistent data structures */
+
+/* Optional */
+static void
+MGAFreeScreen(int scrnIndex, int flags)
+{
+ /*
+ * This only gets called when a screen is being deleted. It does not
+ * get called routinely at the end of a server generation.
+ */
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ MGAFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+/* Optional */
+static int
+MGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ int lace;
+
+ lace = 1 + ((mode->Flags & V_INTERLACE) != 0);
+
+ if ((mode->CrtcHDisplay <= 2048) &&
+ (mode->CrtcHSyncStart <= 4096) &&
+ (mode->CrtcHSyncEnd <= 4096) &&
+ (mode->CrtcHTotal <= 4096) &&
+ (mode->CrtcVDisplay <= 2048 * lace) &&
+ (mode->CrtcVSyncStart <= 4096 * lace) &&
+ (mode->CrtcVSyncEnd <= 4096 * lace) &&
+ (mode->CrtcVTotal <= 4096 * lace)) {
+ return(MODE_OK);
+ } else {
+ return(MODE_BAD);
+ }
+}
+
+
+/* Do screen blanking */
+
+/* Mandatory */
+static Bool
+MGASaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+ return vgaHWSaveScreen(pScreen, unblank);
+}
+
+
+/*
+ * MGADisplayPowerManagementSet --
+ *
+ * Sets VESA Display Power Management Signaling (DPMS) Mode.
+ */
+#ifdef DPMSExtension
+static void
+MGADisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
+ int flags)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ unsigned char seq1 = 0, crtcext1 = 0;
+
+ErrorF("MGADisplayPowerManagementSet: %d\n", PowerManagementMode);
+
+ switch (PowerManagementMode)
+ {
+ case DPMSModeOn:
+ /* Screen: On; HSync: On, VSync: On */
+ seq1 = 0x00;
+ crtcext1 = 0x00;
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off; HSync: Off, VSync: On */
+ seq1 = 0x20;
+ crtcext1 = 0x10;
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off; HSync: On, VSync: Off */
+ seq1 = 0x20;
+ crtcext1 = 0x20;
+ break;
+ case DPMSModeOff:
+ /* Screen: Off; HSync: Off, VSync: Off */
+ seq1 = 0x20;
+ crtcext1 = 0x30;
+ break;
+ }
+ /* XXX Prefer an implementation that doesn't depend on VGA specifics */
+ OUTREG8(0x1FC4, 0x01); /* Select SEQ1 */
+ seq1 |= INREG8(0x1FC5) & ~0x20;
+ OUTREG8(0x1FC5, seq1);
+ OUTREG8(0x1FDE, 0x01); /* Select CRTCEXT1 */
+ crtcext1 |= INREG8(0x1FDF) & ~0x30;
+ OUTREG8(0x1FDF, crtcext1);
+}
+#endif
+
+#if defined (DEBUG)
+/*
+ * some functions to track input/output in the server
+ */
+
+CARD8
+dbg_inreg8(ScrnInfoPtr pScrn,int addr,int verbose)
+{
+ MGAPtr pMga;
+ CARD8 ret;
+
+ pMga = MGAPTR(pScrn);
+ ret = *(volatile CARD8 *)(pMga->IOBase + (addr));
+ if(verbose)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "inreg8 : 0x%8x = 0x%x\n",addr,ret);
+ return ret;
+}
+
+CARD16
+dbg_inreg16(ScrnInfoPtr pScrn,int addr,int verbose)
+{
+ MGAPtr pMga;
+ CARD16 ret;
+
+ pMga = MGAPTR(pScrn);
+ ret = *(volatile CARD16 *)(pMga->IOBase + (addr));
+ if(verbose)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "inreg16: 0x%8x = 0x%x\n",addr,ret);
+ return ret;
+}
+
+CARD32
+dbg_inreg32(ScrnInfoPtr pScrn,int addr,int verbose)
+{
+ MGAPtr pMga;
+ CARD32 ret;
+
+ pMga = MGAPTR(pScrn);
+ ret = *(volatile CARD32 *)(pMga->IOBase + (addr));
+ if(verbose)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "inreg32: 0x%8x = 0x%x\n",addr,ret);
+ return ret;
+}
+
+void
+dbg_outreg8(ScrnInfoPtr pScrn,int addr,int val)
+{
+ MGAPtr pMga;
+ CARD8 ret;
+
+ pMga = MGAPTR(pScrn);
+#if 0
+ if( addr = 0x1fdf )
+ return;
+#endif
+ if( addr != 0x3c00 ) {
+ ret = dbg_inreg8(pScrn,addr,0);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "outreg8 : 0x%8x = 0x%x was 0x%x\n",addr,val,ret);
+ }
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "outreg8 : index 0x%x\n",val);
+ }
+ *(volatile CARD8 *)(pMga->IOBase + (addr)) = (val);
+}
+
+void
+dbg_outreg16(ScrnInfoPtr pScrn,int addr,int val)
+{
+ MGAPtr pMga;
+ CARD16 ret;
+
+#if 0
+ if (addr == 0x1fde)
+ return;
+#endif
+ pMga = MGAPTR(pScrn);
+ ret = dbg_inreg16(pScrn,addr,0);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "outreg16 : 0x%8x = 0x%x was 0x%x\n",addr,val,ret);
+ *(volatile CARD16 *)(pMga->IOBase + (addr)) = (val);
+}
+
+void
+dbg_outreg32(ScrnInfoPtr pScrn,int addr,int val)
+{
+ MGAPtr pMga;
+ CARD32 ret;
+
+ if (((addr & 0xff00) == 0x1c00)
+ && (addr != 0x1c04)
+/* && (addr != 0x1c1c) */
+ && (addr != 0x1c20)
+ && (addr != 0x1c24)
+ && (addr != 0x1c80)
+ && (addr != 0x1c8c)
+ && (addr != 0x1c94)
+ && (addr != 0x1c98)
+ && (addr != 0x1c9c)
+ ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "refused address 0x%x\n",addr);
+ return;
+ }
+ pMga = MGAPTR(pScrn);
+ ret = dbg_inreg32(pScrn,addr,0);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "outreg32 : 0x%8x = 0x%x was 0x%x\n",addr,val,ret);
+ *(volatile CARD32 *)(pMga->IOBase + (addr)) = (val);
+}
+#endif /* DEBUG */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_hwcurs.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_hwcurs.c
new file mode 100644
index 000000000..8b4e66b2e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_hwcurs.c
@@ -0,0 +1,41 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_hwcurs.c,v 1.9 1999/03/14 03:22:00 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+#include "mga_bios.h"
+#include "mga.h"
+#include "mga_reg.h"
+
+Bool
+MGAHWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ MGAPtr pMga = MGAPTR(pScrn);
+ MGARamdacPtr MGAdac = &pMga->Dac;
+ xf86CursorInfoPtr infoPtr;
+
+ if (!MGAdac->isHwCursor)
+ return FALSE;
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pMga->CursorInfoRec = infoPtr;
+
+ infoPtr->MaxWidth = MGAdac->CursorMaxWidth;
+ infoPtr->MaxHeight = MGAdac->CursorMaxHeight;
+ infoPtr->Flags = MGAdac->CursorFlags;
+ infoPtr->SetCursorColors = MGAdac->SetCursorColors;
+ infoPtr->SetCursorPosition = MGAdac->SetCursorPosition;
+ infoPtr->LoadCursorImage = MGAdac->LoadCursorImage;
+ infoPtr->HideCursor = MGAdac->HideCursor;
+ infoPtr->ShowCursor = MGAdac->ShowCursor;
+ infoPtr->UseHWCursor = MGAdac->UseHWCursor;
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h
new file mode 100644
index 000000000..15d57b287
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h
@@ -0,0 +1,74 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_macros.h,v 1.10 1999/08/14 10:49:48 dawes Exp $ */
+
+#ifndef _MGA_MACROS_H_
+#define _MGA_MACROS_H_
+
+#ifndef PSZ
+#define PSZ 8
+#endif
+
+#if PSZ == 8
+#define REPLICATE(r) r &= 0xFF; r |= r << 8; r |= r << 16
+#elif PSZ == 16
+#define REPLICATE(r) r &= 0xFFFF; r |= r << 16
+#elif PSZ == 24
+#define REPLICATE(r) r &= 0xFFFFFF; r |= r << 24
+#else
+#define REPLICATE(r) /* */
+#endif
+
+#define RGBEQUAL(c) (!((((c) >> 8) ^ (c)) & 0xffff))
+
+#define MGAISBUSY() (INREG8(MGAREG_Status + 2) & 0x01)
+
+#define WAITFIFO(n) \
+ if(!pMga->UsePCIRetry) {\
+ while(pMga->fifoCount < (n))\
+ pMga->fifoCount = INREG8(MGAREG_FIFOSTATUS);\
+ pMga->fifoCount -= n;\
+ }
+
+#define XYADDRESS(x,y) \
+ ((y) * pMga->CurrentLayout.displayWidth + (x) + pMga->YDstOrg)
+
+#define MAKEDMAINDEX(index) ((((index) >> 2) & 0x7f) | (((index) >> 6) & 0x80))
+
+#define DMAINDICES(one,two,three,four) \
+ ( MAKEDMAINDEX(one) | \
+ (MAKEDMAINDEX(two) << 8) | \
+ (MAKEDMAINDEX(three) << 16) | \
+ (MAKEDMAINDEX(four) << 24) )
+
+
+#if PSZ == 24
+#define SET_PLANEMASK(p) /**/
+#else
+#define SET_PLANEMASK(p) \
+ if(!(pMga->AccelFlags & MGA_NO_PLANEMASK) && ((p) != pMga->PlaneMask)) { \
+ pMga->PlaneMask = (p); \
+ REPLICATE((p)); \
+ OUTREG(MGAREG_PLNWT,(p)); \
+ }
+#endif
+
+
+#define SET_FOREGROUND(c) \
+ if((c) != pMga->FgColor) { \
+ pMga->FgColor = (c); \
+ REPLICATE((c)); \
+ OUTREG(MGAREG_FCOL,(c)); \
+ }
+
+#define SET_BACKGROUND(c) \
+ if((c) != pMga->BgColor) { \
+ pMga->BgColor = (c); \
+ REPLICATE((c)); \
+ OUTREG(MGAREG_BCOL,(c)); \
+ }
+
+#define DISABLE_CLIP() { \
+ pMga->AccelFlags &= ~CLIPPER_ON; \
+ WAITFIFO(1); \
+ OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); }
+
+#endif /* _MGA_MACROS_H_ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_map.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_map.h
new file mode 100644
index 000000000..dfac0df2b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_map.h
@@ -0,0 +1,17 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_map.h,v 1.1 1997/03/06 23:16:01 hohndel Exp $ */
+
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define CATNAME(prefix,subname) prefix##subname
+#else
+#define CATNAME(prefix,subname) prefix/**/subname
+#endif
+
+#if PSZ == 8
+#define MGANAME(subname) CATNAME(Mga8,subname)
+#elif PSZ == 16
+#define MGANAME(subname) CATNAME(Mga16,subname)
+#elif PSZ == 24
+#define MGANAME(subname) CATNAME(Mga24,subname)
+#elif PSZ == 32
+#define MGANAME(subname) CATNAME(Mga32,subname)
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h
new file mode 100644
index 000000000..10bbb5217
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h
@@ -0,0 +1,381 @@
+/* $XConsortium: mgareg.h /main/2 1996/10/25 10:33:21 kaleb $ */
+
+
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_reg.h,v 1.9 1999/06/06 08:48:51 dawes Exp $ */
+
+
+
+/*
+ * MGA Millennium (MGA2064W) functions
+ * MGA Mystique (MGA1064SG) functions
+ *
+ * Copyright 1996 The XFree86 Project, Inc.
+ *
+ * Authors
+ * Dirk Hohndel
+ * hohndel@XFree86.Org
+ * David Dawes
+ * dawes@XFree86.Org
+ * Contributors:
+ * Guy DESBIEF, Aix-en-provence, France
+ * g.desbief@aix.pacwan.net
+ * MGA1064SG Mystique register file
+ */
+
+
+#ifndef _MGA_REG_H_
+#define _MGA_REG_H_
+
+#define MGAREG_DWGCTL 0x1c00
+#define MGAREG_MACCESS 0x1c04
+/* the following is a mystique only register */
+#define MGAREG_MCTLWTST 0x1c08
+#define MGAREG_ZORG 0x1c0c
+
+#define MGAREG_PAT0 0x1c10
+#define MGAREG_PAT1 0x1c14
+#define MGAREG_PLNWT 0x1c1c
+
+#define MGAREG_BCOL 0x1c20
+#define MGAREG_FCOL 0x1c24
+
+#define MGAREG_SRC0 0x1c30
+#define MGAREG_SRC1 0x1c34
+#define MGAREG_SRC2 0x1c38
+#define MGAREG_SRC3 0x1c3c
+
+#define MGAREG_XYSTRT 0x1c40
+#define MGAREG_XYEND 0x1c44
+
+#define MGAREG_SHIFT 0x1c50
+/* the following is a mystique only register */
+#define MGAREG_DMAPAD 0x1c54
+#define MGAREG_SGN 0x1c58
+#define MGAREG_LEN 0x1c5c
+
+#define MGAREG_AR0 0x1c60
+#define MGAREG_AR1 0x1c64
+#define MGAREG_AR2 0x1c68
+#define MGAREG_AR3 0x1c6c
+#define MGAREG_AR4 0x1c70
+#define MGAREG_AR5 0x1c74
+#define MGAREG_AR6 0x1c78
+
+#define MGAREG_CXBNDRY 0x1c80
+#define MGAREG_FXBNDRY 0x1c84
+#define MGAREG_YDSTLEN 0x1c88
+#define MGAREG_PITCH 0x1c8c
+
+#define MGAREG_YDST 0x1c90
+#define MGAREG_YDSTORG 0x1c94
+#define MGAREG_YTOP 0x1c98
+#define MGAREG_YBOT 0x1c9c
+
+#define MGAREG_CXLEFT 0x1ca0
+#define MGAREG_CXRIGHT 0x1ca4
+#define MGAREG_FXLEFT 0x1ca8
+#define MGAREG_FXRIGHT 0x1cac
+
+#define MGAREG_XDST 0x1cb0
+
+#define MGAREG_DR0 0x1cc0
+#define MGAREG_DR1 0x1cc4
+#define MGAREG_DR2 0x1cc8
+#define MGAREG_DR3 0x1ccc
+
+#define MGAREG_DR4 0x1cd0
+#define MGAREG_DR5 0x1cd4
+#define MGAREG_DR6 0x1cd8
+#define MGAREG_DR7 0x1cdc
+
+#define MGAREG_DR8 0x1ce0
+#define MGAREG_DR9 0x1ce4
+#define MGAREG_DR10 0x1ce8
+#define MGAREG_DR11 0x1cec
+
+#define MGAREG_DR12 0x1cf0
+#define MGAREG_DR13 0x1cf4
+#define MGAREG_DR14 0x1cf8
+#define MGAREG_DR15 0x1cfc
+
+#define MGAREG_SRCORG 0x2cb4
+#define MGAREG_DSTORG 0x2cb8
+
+/* add or or this to one of the previous "power registers" to start
+ the drawing engine */
+
+#define MGAREG_EXEC 0x0100
+
+#define MGAREG_FIFOSTATUS 0x1e10
+#define MGAREG_Status 0x1e14
+#define MGAREG_ICLEAR 0x1e18
+#define MGAREG_IEN 0x1e1c
+
+#define MGAREG_VCOUNT 0x1e20
+
+#define MGAREG_Reset 0x1e40
+
+#define MGAREG_OPMODE 0x1e54
+
+/* OPMODE register additives */
+
+#define MGAOPM_DMA_GENERAL (0x00 << 2)
+#define MGAOPM_DMA_BLIT (0x01 << 2)
+#define MGAOPM_DMA_VECTOR (0x10 << 2)
+
+/* DWGCTL register additives */
+
+/* Lines */
+
+#define MGADWG_LINE_OPEN 0x00
+#define MGADWG_AUTOLINE_OPEN 0x01
+#define MGADWG_LINE_CLOSE 0x02
+#define MGADWG_AUTOLINE_CLOSE 0x03
+
+/* Trapezoids */
+#define MGADWG_TRAP 0x04
+#define MGADWG_TEXTURE_TRAP 0x05
+
+/* BitBlts */
+
+#define MGADWG_BITBLT 0x08
+#define MGADWG_FBITBLT 0x0c
+#define MGADWG_ILOAD 0x09
+#define MGADWG_ILOAD_SCALE 0x0d
+#define MGADWG_ILOAD_FILTER 0x0f
+#define MGADWG_IDUMP 0x0a
+
+/* atype access to WRAM */
+
+#define MGADWG_RPL ( 0x00 << 4 )
+#define MGADWG_RSTR ( 0x01 << 4 )
+#define MGADWG_ZI ( 0x03 << 4 )
+#define MGADWG_BLK ( 0x04 << 4 )
+#define MGADWG_I ( 0x07 << 4 )
+
+/* specifies whether bit blits are linear or xy */
+#define MGADWG_LINEAR ( 0x01 << 7 )
+
+/* z drawing mode. use MGADWG_NOZCMP for always */
+
+#define MGADWG_NOZCMP ( 0x00 << 8 )
+#define MGADWG_ZE ( 0x02 << 8 )
+#define MGADWG_ZNE ( 0x03 << 8 )
+#define MGADWG_ZLT ( 0x04 << 8 )
+#define MGADWG_ZLTE ( 0x05 << 8 )
+#define MGADWG_GT ( 0x06 << 8 )
+#define MGADWG_GTE ( 0x07 << 8 )
+
+/* use this to force colour expansion circuitry to do its stuff */
+
+#define MGADWG_SOLID ( 0x01 << 11 )
+
+/* ar register at zero */
+
+#define MGADWG_ARZERO ( 0x01 << 12 )
+
+#define MGADWG_SGNZERO ( 0x01 << 13 )
+
+#define MGADWG_SHIFTZERO ( 0x01 << 14 )
+
+/* See table on 4-43 for bop ALU operations */
+
+/* See table on 4-44 for translucidity masks */
+
+#define MGADWG_BMONOLEF ( 0x00 << 25 )
+#define MGADWG_BMONOWF ( 0x04 << 25 )
+#define MGADWG_BPLAN ( 0x01 << 25 )
+
+/* note that if bfcol is specified and you're doing a bitblt, it causes
+ a fbitblt to be performed, so check that you obey the fbitblt rules */
+
+#define MGADWG_BFCOL ( 0x02 << 25 )
+#define MGADWG_BUYUV ( 0x0e << 25 )
+#define MGADWG_BU32BGR ( 0x03 << 25 )
+#define MGADWG_BU32RGB ( 0x07 << 25 )
+#define MGADWG_BU24BGR ( 0x0b << 25 )
+#define MGADWG_BU24RGB ( 0x0f << 25 )
+
+#define MGADWG_PATTERN ( 0x01 << 29 )
+#define MGADWG_TRANSC ( 0x01 << 30 )
+#define MGAREG_MISC_WRITE 0x3c2
+#define MGAREG_MISC_READ 0x3cc
+#define MGAREG_MISC_IOADSEL (0x1 << 0)
+#define MGAREG_MISC_RAMMAPEN (0x1 << 1)
+#define MGAREG_MISC_CLK_SEL_VGA25 (0x0 << 2)
+#define MGAREG_MISC_CLK_SEL_VGA28 (0x1 << 2)
+#define MGAREG_MISC_CLK_SEL_MGA_PIX (0x2 << 2)
+#define MGAREG_MISC_CLK_SEL_MGA_MSK (0x3 << 2)
+#define MGAREG_MISC_VIDEO_DIS (0x1 << 4)
+#define MGAREG_MISC_HIGH_PG_SEL (0x1 << 5)
+
+/* MMIO VGA registers */
+#define MGAREG_CRTC_INDEX 0x1fd4
+#define MGAREG_CRTC_DATA 0x1fd5
+#define MGAREG_CRTCEXT_INDEX 0x1fde
+#define MGAREG_CRTCEXT_DATA 0x1fdf
+
+
+/* MGA bits for registers PCI_OPTION_REG */
+#define MGA1064_OPT_SYS_CLK_PCI ( 0x00 << 0 )
+#define MGA1064_OPT_SYS_CLK_PLL ( 0x01 << 0 )
+#define MGA1064_OPT_SYS_CLK_EXT ( 0x02 << 0 )
+#define MGA1064_OPT_SYS_CLK_MSK ( 0x03 << 0 )
+
+#define MGA1064_OPT_SYS_CLK_DIS ( 0x01 << 2 )
+#define MGA1064_OPT_G_CLK_DIV_1 ( 0x01 << 3 )
+#define MGA1064_OPT_M_CLK_DIV_1 ( 0x01 << 4 )
+
+#define MGA1064_OPT_SYS_PLL_PDN ( 0x01 << 5 )
+#define MGA1064_OPT_VGA_ION ( 0x01 << 8 )
+
+/* MGA registers in PCI config space */
+#define PCI_MGA_INDEX 0x44
+#define PCI_MGA_DATA 0x48
+#define PCI_MGA_OPTION2 0x50
+#define PCI_MGA_OPTION3 0x54
+
+#define RAMDAC_OFFSET 0x3c00
+
+/* TVP3026 direct registers */
+
+#define TVP3026_INDEX 0x00
+#define TVP3026_WADR_PAL 0x00
+#define TVP3026_COL_PAL 0x01
+#define TVP3026_PIX_RD_MSK 0x02
+#define TVP3026_RADR_PAL 0x03
+#define TVP3026_CUR_COL_ADDR 0x04
+#define TVP3026_CUR_COL_DATA 0x05
+#define TVP3026_DATA 0x0a
+#define TVP3026_CUR_RAM 0x0b
+#define TVP3026_CUR_XLOW 0x0c
+#define TVP3026_CUR_XHI 0x0d
+#define TVP3026_CUR_YLOW 0x0e
+#define TVP3026_CUR_YHI 0x0f
+
+/* TVP3026 indirect registers */
+
+#define TVP3026_SILICON_REV 0x01
+#define TVP3026_CURSOR_CTL 0x06
+#define TVP3026_LATCH_CTL 0x0f
+#define TVP3026_TRUE_COLOR_CTL 0x18
+#define TVP3026_MUX_CTL 0x19
+#define TVP3026_CLK_SEL 0x1a
+#define TVP3026_PAL_PAGE 0x1c
+#define TVP3026_GEN_CTL 0x1d
+#define TVP3026_MISC_CTL 0x1e
+#define TVP3026_GEN_IO_CTL 0x2a
+#define TVP3026_GEN_IO_DATA 0x2b
+#define TVP3026_PLL_ADDR 0x2c
+#define TVP3026_PIX_CLK_DATA 0x2d
+#define TVP3026_MEM_CLK_DATA 0x2e
+#define TVP3026_LOAD_CLK_DATA 0x2f
+#define TVP3026_KEY_RED_LOW 0x32
+#define TVP3026_KEY_RED_HI 0x33
+#define TVP3026_KEY_GREEN_LOW 0x34
+#define TVP3026_KEY_GREEN_HI 0x35
+#define TVP3026_KEY_BLUE_LOW 0x36
+#define TVP3026_KEY_BLUE_HI 0x37
+#define TVP3026_KEY_CTL 0x38
+#define TVP3026_MCLK_CTL 0x39
+#define TVP3026_SENSE_TEST 0x3a
+#define TVP3026_TEST_DATA 0x3b
+#define TVP3026_CRC_LSB 0x3c
+#define TVP3026_CRC_MSB 0x3d
+#define TVP3026_CRC_CTL 0x3e
+#define TVP3026_ID 0x3f
+#define TVP3026_RESET 0xff
+
+
+/* MGA1064 DAC Register file */
+/* MGA1064 direct registers */
+
+#define MGA1064_INDEX 0x00
+#define MGA1064_WADR_PAL 0x00
+#define MGA1064_COL_PAL 0x01
+#define MGA1064_PIX_RD_MSK 0x02
+#define MGA1064_RADR_PAL 0x03
+#define MGA1064_DATA 0x0a
+
+#define MGA1064_CUR_XLOW 0x0c
+#define MGA1064_CUR_XHI 0x0d
+#define MGA1064_CUR_YLOW 0x0e
+#define MGA1064_CUR_YHI 0x0f
+
+/* MGA1064 indirect registers */
+#define MGA1064_CURSOR_BASE_ADR_LOW 0x04
+#define MGA1064_CURSOR_BASE_ADR_HI 0x05
+#define MGA1064_CURSOR_CTL 0x06
+#define MGA1064_CURSOR_COL0_RED 0x08
+#define MGA1064_CURSOR_COL0_GREEN 0x09
+#define MGA1064_CURSOR_COL0_BLUE 0x0a
+
+#define MGA1064_CURSOR_COL1_RED 0x0c
+#define MGA1064_CURSOR_COL1_GREEN 0x0d
+#define MGA1064_CURSOR_COL1_BLUE 0x0e
+
+#define MGA1064_CURSOR_COL2_RED 0x010
+#define MGA1064_CURSOR_COL2_GREEN 0x011
+#define MGA1064_CURSOR_COL2_BLUE 0x012
+
+#define MGA1064_VREF_CTL 0x018
+
+#define MGA1064_MUL_CTL 0x19
+#define MGA1064_MUL_CTL_8bits 0x0
+#define MGA1064_MUL_CTL_15bits 0x01
+#define MGA1064_MUL_CTL_16bits 0x02
+#define MGA1064_MUL_CTL_24bits 0x03
+#define MGA1064_MUL_CTL_32bits 0x04
+#define MGA1064_MUL_CTL_2G8V16bits 0x05
+#define MGA1064_MUL_CTL_G16V16bits 0x06
+#define MGA1064_MUL_CTL_32_24bits 0x07
+
+#define MGAGDAC_XVREFCTRL 0x18
+#define MGA1064_PIX_CLK_CTL 0x1a
+#define MGA1064_PIX_CLK_CTL_CLK_DIS ( 0x01 << 2 )
+#define MGA1064_PIX_CLK_CTL_CLK_POW_DOWN ( 0x01 << 3 )
+#define MGA1064_PIX_CLK_CTL_SEL_PCI ( 0x00 << 0 )
+#define MGA1064_PIX_CLK_CTL_SEL_PLL ( 0x01 << 0 )
+#define MGA1064_PIX_CLK_CTL_SEL_EXT ( 0x02 << 0 )
+#define MGA1064_PIX_CLK_CTL_SEL_MSK ( 0x03 << 0 )
+
+#define MGA1064_GEN_CTL 0x1d
+#define MGA1064_MISC_CTL 0x1e
+#define MGA1064_MISC_CTL_DAC_POW_DN ( 0x01 << 0 )
+#define MGA1064_MISC_CTL_VGA ( 0x01 << 1 )
+#define MGA1064_MISC_CTL_DIS_CON ( 0x03 << 1 )
+#define MGA1064_MISC_CTL_MAFC ( 0x02 << 1 )
+#define MGA1064_MISC_CTL_VGA8 ( 0x01 << 3 )
+#define MGA1064_MISC_CTL_DAC_RAM_CS ( 0x01 << 4 )
+
+#define MGA1064_GEN_IO_CTL 0x2a
+#define MGA1064_GEN_IO_DATA 0x2b
+#define MGA1064_SYS_PLL_M 0x2c
+#define MGA1064_SYS_PLL_N 0x2d
+#define MGA1064_SYS_PLL_P 0x2e
+#define MGA1064_SYS_PLL_STAT 0x2f
+#define MGA1064_ZOOM_CTL 0x38
+#define MGA1064_SENSE_TST 0x3a
+
+#define MGA1064_CRC_LSB 0x3c
+#define MGA1064_CRC_MSB 0x3d
+#define MGA1064_CRC_CTL 0x3e
+#define MGA1064_COL_KEY_MSK_LSB 0x40
+#define MGA1064_COL_KEY_MSK_MSB 0x41
+#define MGA1064_COL_KEY_LSB 0x42
+#define MGA1064_COL_KEY_MSB 0x43
+#define MGA1064_PIX_PLLA_M 0x44
+#define MGA1064_PIX_PLLA_N 0x45
+#define MGA1064_PIX_PLLA_P 0x46
+#define MGA1064_PIX_PLLB_M 0x48
+#define MGA1064_PIX_PLLB_N 0x49
+#define MGA1064_PIX_PLLB_P 0x4a
+#define MGA1064_PIX_PLLC_M 0x4c
+#define MGA1064_PIX_PLLC_N 0x4d
+#define MGA1064_PIX_PLLC_P 0x4e
+
+#define MGA1064_PIX_PLL_STAT 0x4f
+
+#endif
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_shadow.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_shadow.c
new file mode 100644
index 000000000..b55105582
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_shadow.c
@@ -0,0 +1,254 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_shadow.c,v 1.2 1999/08/22 05:57:35 dawes Exp $ */
+
+/*
+ Copyright (c) 1999, The XFree86 Project Inc.
+ Written by Mark Vojkovich <markv@valinux.com>
+*/
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "mga_bios.h"
+#include "mga_reg.h"
+#include "mga.h"
+#include "shadowfb.h"
+#include "servermd.h"
+
+
+
+void
+MGARefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ int width, height, Bpp, FBPitch;
+ unsigned char *src, *dst;
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ FBPitch = BitmapBytePad(pScrn->displayWidth * pScrn->bitsPerPixel);
+
+ while(num--) {
+ width = (pbox->x2 - pbox->x1) * Bpp;
+ height = pbox->y2 - pbox->y1;
+ src = pMga->ShadowPtr + (pbox->y1 * pMga->ShadowPitch) +
+ (pbox->x1 * Bpp);
+ dst = pMga->FbStart + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
+
+ while(height--) {
+ memcpy(dst, src, width);
+ dst += FBPitch;
+ src += pMga->ShadowPitch;
+ }
+
+ pbox++;
+ }
+}
+
+void
+MGAPointerMoved(int index, int x, int y)
+{
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ MGAPtr pMga = MGAPTR(pScrn);
+ int newX, newY;
+
+ if(pMga->Rotate == 1) {
+ newX = pScrn->currentMode->HDisplay - y - 1;
+ newY = x;
+ } else {
+ newX = y;
+ newY = pScrn->currentMode->VDisplay - x - 1;
+ }
+
+ (*pMga->PointerMoved)(index, newX, newY);
+}
+
+void
+MGARefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD8 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pMga->Rotate * pMga->ShadowPitch;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~3;
+ y2 = (pbox->y2 + 3) & ~3;
+ height = (y2 - y1) >> 2; /* in dwords */
+
+ if(pMga->Rotate == 1) {
+ dstPtr = pMga->FbStart +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
+ srcPtr = pMga->ShadowPtr + ((1 - y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = pMga->FbStart +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
+ srcPtr = pMga->ShadowPtr + (y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = (CARD32*)dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = src[0] | (src[srcPitch] << 8) |
+ (src[srcPitch * 2] << 16) |
+ (src[srcPitch * 3] << 24);
+ src += srcPitch * 4;
+ }
+ srcPtr += pMga->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+void
+MGARefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD16 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pMga->Rotate * pMga->ShadowPitch >> 1;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~1;
+ y2 = (pbox->y2 + 1) & ~1;
+ height = (y2 - y1) >> 1; /* in dwords */
+
+ if(pMga->Rotate == 1) {
+ dstPtr = (CARD16*)pMga->FbStart +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - y2;
+ srcPtr = (CARD16*)pMga->ShadowPtr +
+ ((1 - y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = (CARD16*)pMga->FbStart +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + y1;
+ srcPtr = (CARD16*)pMga->ShadowPtr +
+ (y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = (CARD32*)dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = src[0] | (src[srcPitch] << 16);
+ src += srcPitch * 2;
+ }
+ srcPtr += pMga->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+/* this one could be faster */
+void
+MGARefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ int count, width, height, y1, y2, dstPitch, srcPitch;
+ CARD8 *dstPtr, *srcPtr, *src;
+ CARD32 *dst;
+
+ dstPitch = BitmapBytePad(pScrn->displayWidth * 24);
+ srcPitch = -pMga->Rotate * pMga->ShadowPitch;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ y1 = pbox->y1 & ~3;
+ y2 = (pbox->y2 + 3) & ~3;
+ height = (y2 - y1) >> 2; /* blocks of 3 dwords */
+
+ if(pMga->Rotate == 1) {
+ dstPtr = pMga->FbStart +
+ (pbox->x1 * dstPitch) + ((pScrn->virtualX - y2) * 3);
+ srcPtr = pMga->ShadowPtr + ((1 - y2) * srcPitch) + (pbox->x1 * 3);
+ } else {
+ dstPtr = pMga->FbStart +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + (y1 * 3);
+ srcPtr = pMga->ShadowPtr + (y1 * srcPitch) + (pbox->x2 * 3) - 3;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = (CARD32*)dstPtr;
+ count = height;
+ while(count--) {
+ dst[0] = src[0] | (src[1] << 8) | (src[2] << 16) |
+ (src[srcPitch] << 24);
+ dst[1] = src[srcPitch + 1] | (src[srcPitch + 2] << 8) |
+ (src[srcPitch * 2] << 16) |
+ (src[(srcPitch * 2) + 1] << 24);
+ dst[2] = src[(srcPitch * 2) + 2] | (src[srcPitch * 3] << 8) |
+ (src[(srcPitch * 3) + 1] << 16) |
+ (src[(srcPitch * 3) + 2] << 24);
+ dst += 3;
+ src += srcPitch * 4;
+ }
+ srcPtr += pMga->Rotate * 3;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+void
+MGARefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ int count, width, height, dstPitch, srcPitch;
+ CARD32 *dstPtr, *srcPtr, *src, *dst;
+
+ dstPitch = pScrn->displayWidth;
+ srcPitch = -pMga->Rotate * pMga->ShadowPitch >> 2;
+
+ while(num--) {
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ if(pMga->Rotate == 1) {
+ dstPtr = (CARD32*)pMga->FbStart +
+ (pbox->x1 * dstPitch) + pScrn->virtualX - pbox->y2;
+ srcPtr = (CARD32*)pMga->ShadowPtr +
+ ((1 - pbox->y2) * srcPitch) + pbox->x1;
+ } else {
+ dstPtr = (CARD32*)pMga->FbStart +
+ ((pScrn->virtualY - pbox->x2) * dstPitch) + pbox->y1;
+ srcPtr = (CARD32*)pMga->ShadowPtr +
+ (pbox->y1 * srcPitch) + pbox->x2 - 1;
+ }
+
+ while(width--) {
+ src = srcPtr;
+ dst = dstPtr;
+ count = height;
+ while(count--) {
+ *(dst++) = *src;
+ src += srcPitch;
+ }
+ srcPtr += pMga->Rotate;
+ dstPtr += dstPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c
new file mode 100644
index 000000000..e97030796
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c
@@ -0,0 +1,1922 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_storm.c,v 1.59 1999/08/29 12:21:01 dawes Exp $ */
+
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* For correct __inline__ usage */
+#include "compiler.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that use XAA need this */
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xf86fbman.h"
+#include "miline.h"
+#include "servermd.h"
+
+#include "mga_bios.h"
+#include "mga.h"
+#include "mga_reg.h"
+#include "mga_map.h"
+#include "mga_macros.h"
+
+static void MGANAME(SubsequentScreenToScreenCopy)(ScrnInfoPtr pScrn,
+ int srcX, int srcY, int dstX, int dstY,
+ int w, int h);
+static void MGANAME(SubsequentScreenToScreenCopy_FastBlit)(ScrnInfoPtr pScrn,
+ int srcX, int srcY, int dstX, int dstY,
+ int w, int h);
+static void MGANAME(SetupForCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int fg,
+ int bg, int rop, unsigned int planemask);
+static void MGANAME(SubsequentCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft);
+static void MGANAME(SubsequentSolidFillRect)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h);
+static void MGANAME(SubsequentSolidFillTrap)(ScrnInfoPtr pScrn, int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR);
+static void MGANAME(SubsequentSolidHorVertLine) (ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir);
+static void MGANAME(SubsequentSolidTwoPointLine)(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags);
+static void MGANAME(SetupForMono8x8PatternFill)(ScrnInfoPtr pScrn,
+ int patx, int paty, int fg, int bg,
+ int rop, unsigned int planemask);
+static void MGANAME(SubsequentMono8x8PatternFillRect)(ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h );
+static void MGANAME(SubsequentMono8x8PatternFillRect_Additional)(
+ ScrnInfoPtr pScrn, int patx, int paty,
+ int x, int y, int w, int h );
+static void MGANAME(SubsequentMono8x8PatternFillTrap)( ScrnInfoPtr pScrn,
+ int patx, int paty, int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR);
+static void MGANAME(SetupForImageWrite)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask,
+ int transparency_color, int bpp, int depth);
+static void MGANAME(SubsequentImageWriteRect)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft);
+#if PSZ != 24
+static void MGANAME(SetupForPlanarScreenToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask);
+static void MGANAME(SubsequentPlanarScreenToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int skipleft);
+#endif
+static void MGANAME(SetupForScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void MGANAME(SubsequentScreenToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int skipleft);
+static void MGANAME(SetupForDashedLine)(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop, unsigned int planemask, int length,
+ unsigned char *pattern);
+static void MGANAME(SubsequentDashedTwoPointLine)(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2,
+ int flags, int phase);
+
+extern void MGAWriteBitmapColorExpand(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h, unsigned char *src, int srcwidth,
+ int skipleft, int fg, int bg, int rop,
+ unsigned int planemask);
+extern void MGAFillColorExpandRects(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int nBox, BoxPtr pBox,
+ int xorg, int yorg, PixmapPtr pPix);
+extern void MGASetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2);
+extern void MGADisableClipping(ScrnInfoPtr pScrn);
+extern void MGAFillSolidRectsDMA(ScrnInfoPtr pScrn, int fg, int rop,
+ unsigned int planemask, int nBox, BoxPtr pBox);
+extern void MGAFillSolidSpansDMA(ScrnInfoPtr pScrn, int fg, int rop,
+ unsigned int planemask, int n, DDXPointPtr ppt,
+ int *pwidth, int fSorted);
+extern void MGAFillMono8x8PatternRectsTwoPass(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop, unsigned int planemask, int nBox,
+ BoxPtr pBox, int pattern0, int pattern1,
+ int xorigin, int yorigin);
+extern void MGANonTEGlyphRenderer(ScrnInfoPtr pScrn, int x, int y, int n,
+ NonTEGlyphPtr glyphs, BoxPtr pbox,
+ int fg, int rop, unsigned int planemask);
+extern void MGAValidatePolyArc(GCPtr, unsigned long, DrawablePtr);
+extern void MGAValidatePolyPoint(GCPtr, unsigned long, DrawablePtr);
+extern void MGAFillCacheBltRects(ScrnInfoPtr, int, unsigned int, int, BoxPtr,
+ int, int, XAACacheInfoPtr);
+
+Bool
+MGANAME(AccelInit)(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ MGAPtr pMga = MGAPTR(pScrn);
+ int maxFastBlitMem;
+ BoxRec AvailFBArea;
+
+ pMga->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pMga->MaxFastBlitY = 0;
+ pMga->MaxBlitDWORDS = 0x40000 >> 5;
+
+ switch (pMga->Chipset) {
+ case PCI_CHIP_MGA2064:
+ pMga->AccelFlags = BLK_OPAQUE_EXPANSION | FASTBLT_BUG;
+ break;
+ case PCI_CHIP_MGA2164:
+ case PCI_CHIP_MGA2164_AGP:
+ pMga->AccelFlags = BLK_OPAQUE_EXPANSION |
+ TRANSC_SOLID_FILL |
+ USE_RECTS_FOR_LINES;
+ break;
+ case PCI_CHIP_MGAG400:
+ pMga->MaxBlitDWORDS = 0x400000 >> 5;
+ case PCI_CHIP_MGAG200:
+ case PCI_CHIP_MGAG200_PCI:
+ pMga->AccelFlags = TRANSC_SOLID_FILL |
+ TWO_PASS_COLOR_EXPAND;
+
+ if(pMga->FbMapSize > 8*1024*1024)
+ pMga->AccelFlags |= LARGE_ADDRESSES;
+ break;
+ case PCI_CHIP_MGA1064:
+ pMga->AccelFlags = 0;
+ break;
+ case PCI_CHIP_MGAG100:
+ default:
+ pMga->AccelFlags = MGA_NO_PLANEMASK;
+ break;
+ }
+
+ /* all should be able to use this now with the bug fixes */
+ pMga->AccelFlags |= USE_LINEAR_EXPANSION;
+
+#if PSZ == 24
+ pMga->AccelFlags |= MGA_NO_PLANEMASK;
+#endif
+
+ if(pMga->HasSDRAM) {
+ pMga->Atype = pMga->AtypeNoBLK = MGAAtypeNoBLK;
+ pMga->AccelFlags &= ~TWO_PASS_COLOR_EXPAND;
+ } else {
+ pMga->Atype = MGAAtype;
+ pMga->AtypeNoBLK = MGAAtypeNoBLK;
+ }
+
+ /* fill out infoPtr here */
+ infoPtr->Flags = PIXMAP_CACHE |
+ OFFSCREEN_PIXMAPS |
+ LINEAR_FRAMEBUFFER |
+ MICROSOFT_ZERO_LINE_BIAS;
+
+ /* sync */
+ infoPtr->Sync = MGAStormSync;
+
+ /* screen to screen copy */
+ infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
+ infoPtr->SetupForScreenToScreenCopy =
+ MGANAME(SetupForScreenToScreenCopy);
+ infoPtr->SubsequentScreenToScreenCopy =
+ MGANAME(SubsequentScreenToScreenCopy);
+
+ if(pMga->HasFBitBlt) {
+ infoPtr->FillCacheBltRects = MGAFillCacheBltRects;
+ infoPtr->FillCacheBltRectsFlags = NO_TRANSPARENCY;
+ }
+
+ /* solid fills */
+ infoPtr->SetupForSolidFill = MGANAME(SetupForSolidFill);
+ infoPtr->SubsequentSolidFillRect = MGANAME(SubsequentSolidFillRect);
+ infoPtr->SubsequentSolidFillTrap = MGANAME(SubsequentSolidFillTrap);
+
+ /* solid lines */
+ infoPtr->SetupForSolidLine = infoPtr->SetupForSolidFill;
+ infoPtr->SubsequentSolidHorVertLine =
+ MGANAME(SubsequentSolidHorVertLine);
+ infoPtr->SubsequentSolidTwoPointLine =
+ MGANAME(SubsequentSolidTwoPointLine);
+
+ /* clipping */
+ infoPtr->SetClippingRectangle = MGASetClippingRectangle;
+ infoPtr->DisableClipping = MGADisableClipping;
+ infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE |
+ HARDWARE_CLIP_DASHED_LINE |
+ HARDWARE_CLIP_SOLID_FILL |
+ HARDWARE_CLIP_MONO_8x8_FILL |
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND;
+
+ /* dashed lines */
+ infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED;
+ infoPtr->SetupForDashedLine = MGANAME(SetupForDashedLine);
+ infoPtr->SubsequentDashedTwoPointLine =
+ MGANAME(SubsequentDashedTwoPointLine);
+ infoPtr->DashPatternMaxLength = 128;
+
+
+ /* 8x8 mono patterns */
+ infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_BITS |
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+ infoPtr->SetupForMono8x8PatternFill = MGANAME(SetupForMono8x8PatternFill);
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ MGANAME(SubsequentMono8x8PatternFillRect);
+ infoPtr->SubsequentMono8x8PatternFillTrap =
+ MGANAME(SubsequentMono8x8PatternFillTrap);
+
+ /* cpu to screen color expansion */
+ infoPtr->CPUToScreenColorExpandFillFlags = CPU_TRANSFER_PAD_DWORD |
+ SCANLINE_PAD_DWORD |
+ BIT_ORDER_IN_BYTE_LSBFIRST |
+ LEFT_EDGE_CLIPPING |
+ LEFT_EDGE_CLIPPING_NEGATIVE_X |
+ SYNC_AFTER_COLOR_EXPAND;
+ if(pMga->ILOADBase) {
+ infoPtr->ColorExpandRange = 0x800000;
+ infoPtr->ColorExpandBase = pMga->ILOADBase;
+ } else {
+ infoPtr->ColorExpandRange = 0x1C00;
+ infoPtr->ColorExpandBase = pMga->IOBase;
+ }
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ MGANAME(SetupForCPUToScreenColorExpandFill);
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ MGANAME(SubsequentCPUToScreenColorExpandFill);
+
+
+ /* screen to screen color expansion */
+ if(pMga->AccelFlags & USE_LINEAR_EXPANSION) {
+ infoPtr->ScreenToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_LSBFIRST;
+ infoPtr->SetupForScreenToScreenColorExpandFill =
+ MGANAME(SetupForScreenToScreenColorExpandFill);
+ infoPtr->SubsequentScreenToScreenColorExpandFill =
+ MGANAME(SubsequentScreenToScreenColorExpandFill);
+ } else {
+#if PSZ != 24
+ /* Alternate (but slower) planar expansions */
+ infoPtr->SetupForScreenToScreenColorExpandFill =
+ MGANAME(SetupForPlanarScreenToScreenColorExpandFill);
+ infoPtr->SubsequentScreenToScreenColorExpandFill =
+ MGANAME(SubsequentPlanarScreenToScreenColorExpandFill);
+ infoPtr->CacheColorExpandDensity = PSZ;
+ infoPtr->CacheMonoStipple = XAACachePlanarMonoStipple;
+ /* It's faster to blit the stipples if you have fastbilt */
+ if(pMga->HasFBitBlt)
+ infoPtr->ScreenToScreenColorExpandFillFlags = TRANSPARENCY_ONLY;
+#endif
+ }
+
+ /* image writes */
+ infoPtr->ImageWriteFlags = CPU_TRANSFER_PAD_DWORD |
+ SCANLINE_PAD_DWORD |
+ LEFT_EDGE_CLIPPING |
+ LEFT_EDGE_CLIPPING_NEGATIVE_X |
+ SYNC_AFTER_IMAGE_WRITE;
+
+ /* if we're write combining */
+ infoPtr->ImageWriteFlags |= NO_GXCOPY;
+
+ if(pMga->ILOADBase) {
+ infoPtr->ImageWriteRange = 0x800000;
+ infoPtr->ImageWriteBase = pMga->ILOADBase;
+ } else {
+ infoPtr->ImageWriteRange = 0x1C00;
+ infoPtr->ImageWriteBase = pMga->IOBase;
+ }
+ infoPtr->SetupForImageWrite = MGANAME(SetupForImageWrite);
+ infoPtr->SubsequentImageWriteRect = MGANAME(SubsequentImageWriteRect);
+
+
+ /* midrange replacements */
+
+ if(infoPtr->SetupForCPUToScreenColorExpandFill &&
+ infoPtr->SubsequentCPUToScreenColorExpandFill) {
+ infoPtr->FillColorExpandRects = MGAFillColorExpandRects;
+ infoPtr->WriteBitmap = MGAWriteBitmapColorExpand;
+ if(BITMAP_SCANLINE_PAD == 32)
+ infoPtr->NonTEGlyphRenderer = MGANonTEGlyphRenderer;
+ }
+
+ if(pMga->ILOADBase && pMga->UsePCIRetry && infoPtr->SetupForSolidFill) {
+ infoPtr->FillSolidRects = MGAFillSolidRectsDMA;
+ infoPtr->FillSolidSpans = MGAFillSolidSpansDMA;
+ }
+
+ if(pMga->AccelFlags & TWO_PASS_COLOR_EXPAND) {
+ if(infoPtr->SetupForMono8x8PatternFill)
+ infoPtr->FillMono8x8PatternRects =
+ MGAFillMono8x8PatternRectsTwoPass;
+ }
+
+ if(infoPtr->SetupForSolidFill) {
+ infoPtr->ValidatePolyArc = MGAValidatePolyArc;
+ infoPtr->PolyArcMask = GCFunction | GCLineWidth | GCPlaneMask |
+ GCLineStyle | GCFillStyle;
+ infoPtr->ValidatePolyPoint = MGAValidatePolyPoint;
+ infoPtr->PolyPointMask = GCFunction | GCPlaneMask;
+ }
+
+ if(pMga->AccelFlags & MGA_NO_PLANEMASK) {
+ infoPtr->ImageWriteFlags |= NO_PLANEMASK;
+ infoPtr->ScreenToScreenCopyFlags |= NO_PLANEMASK;
+ infoPtr->CPUToScreenColorExpandFillFlags |= NO_PLANEMASK;
+ infoPtr->WriteBitmapFlags |= NO_PLANEMASK;
+ infoPtr->SolidFillFlags |= NO_PLANEMASK;
+ infoPtr->SolidLineFlags |= NO_PLANEMASK;
+ infoPtr->DashedLineFlags |= NO_PLANEMASK;
+ infoPtr->Mono8x8PatternFillFlags |= NO_PLANEMASK;
+ infoPtr->FillColorExpandRectsFlags |= NO_PLANEMASK;
+ infoPtr->ScreenToScreenColorExpandFillFlags |= NO_PLANEMASK;
+ infoPtr->FillSolidRectsFlags |= NO_PLANEMASK;
+ infoPtr->FillSolidSpansFlags |= NO_PLANEMASK;
+ infoPtr->FillMono8x8PatternRectsFlags |= NO_PLANEMASK;
+ infoPtr->NonTEGlyphRendererFlags |= NO_PLANEMASK;
+ infoPtr->FillCacheBltRectsFlags |= NO_PLANEMASK;
+ }
+
+
+ maxFastBlitMem = (pMga->Interleave ? 4096 : 2048) * 1024;
+
+ if(pMga->FbMapSize > maxFastBlitMem) {
+ pMga->MaxFastBlitY = maxFastBlitMem / (pScrn->displayWidth * PSZ / 8);
+ }
+
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = pMga->FbUsableSize / (pScrn->displayWidth * PSZ / 8);
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ return(XAAInit(pScreen, infoPtr));
+}
+
+#if PSZ == 8
+
+CARD32 MGAAtype[16] = {
+ MGADWG_RPL | 0x00000000, MGADWG_RSTR | 0x00080000,
+ MGADWG_RSTR | 0x00040000, MGADWG_BLK | 0x000c0000,
+ MGADWG_RSTR | 0x00020000, MGADWG_RSTR | 0x000a0000,
+ MGADWG_RSTR | 0x00060000, MGADWG_RSTR | 0x000e0000,
+ MGADWG_RSTR | 0x00010000, MGADWG_RSTR | 0x00090000,
+ MGADWG_RSTR | 0x00050000, MGADWG_RSTR | 0x000d0000,
+ MGADWG_RPL | 0x00030000, MGADWG_RSTR | 0x000b0000,
+ MGADWG_RSTR | 0x00070000, MGADWG_RPL | 0x000f0000
+};
+
+
+CARD32 MGAAtypeNoBLK[16] = {
+ MGADWG_RPL | 0x00000000, MGADWG_RSTR | 0x00080000,
+ MGADWG_RSTR | 0x00040000, MGADWG_RPL | 0x000c0000,
+ MGADWG_RSTR | 0x00020000, MGADWG_RSTR | 0x000a0000,
+ MGADWG_RSTR | 0x00060000, MGADWG_RSTR | 0x000e0000,
+ MGADWG_RSTR | 0x00010000, MGADWG_RSTR | 0x00090000,
+ MGADWG_RSTR | 0x00050000, MGADWG_RSTR | 0x000d0000,
+ MGADWG_RPL | 0x00030000, MGADWG_RSTR | 0x000b0000,
+ MGADWG_RSTR | 0x00070000, MGADWG_RPL | 0x000f0000
+};
+
+
+Bool
+MGAStormAccelInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ switch( pScrn->bitsPerPixel )
+ {
+ case 8:
+ return Mga8AccelInit(pScreen);
+ case 16:
+ return Mga16AccelInit(pScreen);
+ case 24:
+ return Mga24AccelInit(pScreen);
+ case 32:
+ return Mga32AccelInit(pScreen);
+ }
+ return FALSE;
+}
+
+
+
+void
+MGAStormSync(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ while(MGAISBUSY());
+ /* flush cache before a read (mga-1064g 5.1.6) */
+ OUTREG8(MGAREG_CRTC_INDEX, 0);
+ if(pMga->AccelFlags & CLIPPER_ON) {
+ pMga->AccelFlags &= ~CLIPPER_ON;
+ OUTREG(MGAREG_CXBNDRY, 0xFFFF0000);
+ }
+}
+
+void MGAStormEngineInit(ScrnInfoPtr pScrn)
+{
+ long maccess = 0;
+ MGAPtr pMga = MGAPTR(pScrn);
+ MGAFBLayout *pLayout = &pMga->CurrentLayout;
+
+ if (pMga->Chipset == PCI_CHIP_MGAG100)
+ maccess = 1 << 14;
+
+ switch( pLayout->bitsPerPixel )
+ {
+ case 8:
+ break;
+ case 16:
+ /* set 16 bpp, turn off dithering, turn on 5:5:5 pixels */
+ maccess |= 1 + (1 << 30) + (1 << 31);
+ break;
+ case 24:
+ maccess |= 3;
+ break;
+ case 32:
+ maccess |= 2;
+ break;
+ }
+
+ pMga->fifoCount = 0;
+
+ WAITFIFO(12);
+ OUTREG(MGAREG_PITCH, pLayout->displayWidth);
+ OUTREG(MGAREG_YDSTORG, pMga->YDstOrg);
+ OUTREG(MGAREG_MACCESS, maccess);
+ pMga->PlaneMask = ~0;
+ if(pMga->Chipset != PCI_CHIP_MGAG100)
+ OUTREG(MGAREG_PLNWT, pMga->PlaneMask);
+ pMga->FgColor = 0;
+ OUTREG(MGAREG_FCOL, pMga->FgColor);
+ pMga->BgColor = 0;
+ OUTREG(MGAREG_BCOL, pMga->BgColor);
+ OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT);
+
+ /* put clipping in a known state */
+ OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */
+ OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */
+ OUTREG(MGAREG_YBOT, 0x007FFFFF); /* maxPixelPointer */
+ pMga->AccelFlags &= ~CLIPPER_ON;
+
+ switch(pMga->Chipset) {
+ case PCI_CHIP_MGAG400:
+ case PCI_CHIP_MGAG200:
+ case PCI_CHIP_MGAG200_PCI:
+ pMga->SrcOrg = 0;
+ pMga->DstOrg = 0;
+ OUTREG(MGAREG_SRCORG, 0);
+ OUTREG(MGAREG_DSTORG, 0);
+ break;
+ default:
+ break;
+ }
+}
+
+void MGASetClippingRectangle(
+ ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ WAITFIFO(3);
+ OUTREG(MGAREG_CXBNDRY,(x2 << 16) | x1);
+ OUTREG(MGAREG_YTOP, (y1 * pScrn->displayWidth) + pMga->YDstOrg);
+ OUTREG(MGAREG_YBOT, (y2 * pScrn->displayWidth) + pMga->YDstOrg);
+ pMga->AccelFlags |= CLIPPER_ON;
+}
+
+void MGADisableClipping(ScrnInfoPtr pScrn)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ WAITFIFO(3);
+ OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */
+ OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */
+ OUTREG(MGAREG_YBOT, 0x007FFFFF); /* maxPixelPointer */
+ pMga->AccelFlags &= ~CLIPPER_ON;
+}
+
+
+#endif
+
+
+ /*********************************************\
+ | Screen-to-Screen Copy |
+ \*********************************************/
+
+#define BLIT_LEFT 1
+#define BLIT_UP 4
+
+void
+MGANAME(SetupForScreenToScreenCopy)(
+ ScrnInfoPtr pScrn,
+ int xdir, int ydir,
+ int rop,
+ unsigned int planemask,
+ int trans
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+ CARD32 dwgctl = pMga->AtypeNoBLK[rop] | MGADWG_SHIFTZERO |
+ MGADWG_BITBLT | MGADWG_BFCOL;
+
+ pMga->AccelInfoRec->SubsequentScreenToScreenCopy =
+ MGANAME(SubsequentScreenToScreenCopy);
+
+ pMga->BltScanDirection = 0;
+ if(ydir == -1) pMga->BltScanDirection |= BLIT_UP;
+ if(xdir == -1)
+ pMga->BltScanDirection |= BLIT_LEFT;
+ else if(pMga->HasFBitBlt && (rop == GXcopy) && !pMga->DrawTransparent)
+ pMga->AccelInfoRec->SubsequentScreenToScreenCopy =
+ MGANAME(SubsequentScreenToScreenCopy_FastBlit);
+
+ if(pMga->DrawTransparent) {
+ dwgctl |= MGADWG_TRANSC;
+ WAITFIFO(2);
+ SET_FOREGROUND(trans);
+ trans = ~0;
+ SET_BACKGROUND(trans);
+ }
+
+ WAITFIFO(4);
+ OUTREG(MGAREG_DWGCTL, dwgctl);
+ OUTREG(MGAREG_SGN, pMga->BltScanDirection);
+ SET_PLANEMASK(planemask);
+ OUTREG(MGAREG_AR5, ydir * pMga->CurrentLayout.displayWidth);
+}
+
+
+static void
+MGANAME(SubsequentScreenToScreenCopy)(
+ ScrnInfoPtr pScrn,
+ int srcX, int srcY, int dstX, int dstY, int w, int h
+){
+ int start, end, SrcOrg = 0, DstOrg = 0;
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ if (pMga->AccelFlags & LARGE_ADDRESSES) {
+ SrcOrg = ((srcY & ~1023) * pMga->CurrentLayout.displayWidth * PSZ) >> 9;
+ DstOrg = ((dstY & ~1023) * pMga->CurrentLayout.displayWidth * PSZ) >> 9;
+ dstY &= 1023;
+ }
+
+ if(pMga->BltScanDirection & BLIT_UP) {
+ srcY += h - 1;
+ dstY += h - 1;
+ }
+
+ w--;
+ start = end = XYADDRESS(srcX, srcY);
+
+ if(pMga->BltScanDirection & BLIT_LEFT) start += w;
+ else end += w;
+
+ if (pMga->AccelFlags & LARGE_ADDRESSES) {
+ WAITFIFO(7);
+ if(DstOrg)
+ OUTREG(MGAREG_DSTORG, DstOrg << 6);
+ if(SrcOrg != pMga->SrcOrg) {
+ pMga->SrcOrg = SrcOrg;
+ OUTREG(MGAREG_SRCORG, SrcOrg << 6);
+ }
+ if(SrcOrg) {
+ SrcOrg = (SrcOrg << 9) / PSZ;
+ end -= SrcOrg;
+ start -= SrcOrg;
+ }
+ OUTREG(MGAREG_AR0, end);
+ OUTREG(MGAREG_AR3, start);
+ OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h);
+ if(DstOrg)
+ OUTREG(MGAREG_DSTORG, 0);
+ } else {
+ WAITFIFO(4);
+ OUTREG(MGAREG_AR0, end);
+ OUTREG(MGAREG_AR3, start);
+ OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h);
+ }
+}
+
+
+static void
+MGANAME(SubsequentScreenToScreenCopy_FastBlit)(
+ ScrnInfoPtr pScrn,
+ int srcX, int srcY, int dstX, int dstY, int w, int h
+)
+{
+ int start, end;
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ if(pMga->BltScanDirection & BLIT_UP) {
+ srcY += h - 1;
+ dstY += h - 1;
+ }
+
+ w--;
+ start = XYADDRESS(srcX, srcY);
+ end = start + w;
+
+ /* we assume the driver asserts screen pitches such that
+ we can always use fastblit for scrolling */
+ if(
+#if PSZ == 32
+ !((srcX ^ dstX) & 31)
+#elif PSZ == 16
+ !((srcX ^ dstX) & 63)
+#else
+ !((srcX ^ dstX) & 127)
+#endif
+ ) {
+ if(pMga->MaxFastBlitY) {
+ if(pMga->BltScanDirection & BLIT_UP) {
+ if((srcY >= pMga->MaxFastBlitY) ||
+ (dstY >= pMga->MaxFastBlitY))
+ goto FASTBLIT_BAILOUT;
+ } else {
+ if(((srcY + h) > pMga->MaxFastBlitY) ||
+ ((dstY + h) > pMga->MaxFastBlitY))
+ goto FASTBLIT_BAILOUT;
+ }
+ }
+
+ /* Millennium 1 fastblit bug fix */
+ if(pMga->AccelFlags & FASTBLT_BUG) {
+ int fxright = dstX + w;
+#if PSZ == 8
+ if((dstX & (1 << 6)) && (((fxright >> 6) - (dstX >> 6)) & 7) == 7) {
+ fxright |= 1 << 6;
+#elif PSZ == 16
+ if((dstX & (1 << 5)) && (((fxright >> 5) - (dstX >> 5)) & 7) == 7) {
+ fxright |= 1 << 5;
+#elif PSZ == 24
+ if(((dstX * 3) & (1 << 6)) &&
+ ((((fxright * 3 + 2) >> 6) - ((dstX * 3) >> 6)) & 7) == 7) {
+ fxright = ((fxright * 3 + 2) | (1 << 6)) / 3;
+#elif PSZ == 32
+ if((dstX & (1 << 4)) && (((fxright >> 4) - (dstX >> 4)) & 7) == 7) {
+ fxright |= 1 << 4;
+#endif
+ WAITFIFO(8);
+ OUTREG(MGAREG_CXRIGHT, dstX + w);
+ OUTREG(MGAREG_DWGCTL, 0x040A400C);
+ OUTREG(MGAREG_AR0, end);
+ OUTREG(MGAREG_AR3, start);
+ OUTREG(MGAREG_FXBNDRY, (fxright << 16) | (dstX & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h);
+ OUTREG(MGAREG_DWGCTL, pMga->AtypeNoBLK[GXcopy] |
+ MGADWG_SHIFTZERO | MGADWG_BITBLT | MGADWG_BFCOL);
+ OUTREG(MGAREG_CXRIGHT, 0xFFFF);
+ return;
+ } /* } } } (preserve pairs for pair matching) */
+ }
+
+ WAITFIFO(6);
+ OUTREG(MGAREG_DWGCTL, 0x040A400C);
+ OUTREG(MGAREG_AR0, end);
+ OUTREG(MGAREG_AR3, start);
+ OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h);
+ OUTREG(MGAREG_DWGCTL, pMga->AtypeNoBLK[GXcopy] | MGADWG_SHIFTZERO |
+ MGADWG_BITBLT | MGADWG_BFCOL);
+ return;
+ }
+
+FASTBLIT_BAILOUT:
+
+ WAITFIFO(4);
+ OUTREG(MGAREG_AR0, end);
+ OUTREG(MGAREG_AR3, start);
+ OUTREG(MGAREG_FXBNDRY, ((dstX + w) << 16) | (dstX & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (dstY << 16) | h);
+}
+
+
+ /******************\
+ | Solid Fills |
+ \******************/
+
+void
+MGANAME(SetupForSolidFill)(
+ ScrnInfoPtr pScrn,
+ int color,
+ int rop,
+ unsigned int planemask )
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+
+#if PSZ == 24
+ if(!RGBEQUAL(color))
+ pMga->FilledRectCMD = MGADWG_TRAP | MGADWG_SOLID | MGADWG_ARZERO |
+ MGADWG_SGNZERO | MGADWG_SHIFTZERO |
+ MGADWG_BMONOLEF | pMga->AtypeNoBLK[rop];
+ else
+#endif
+ pMga->FilledRectCMD = MGADWG_TRAP | MGADWG_SOLID | MGADWG_ARZERO |
+ MGADWG_SGNZERO | MGADWG_SHIFTZERO |
+ MGADWG_BMONOLEF | pMga->Atype[rop];
+
+ pMga->SolidLineCMD = MGADWG_SOLID | MGADWG_SHIFTZERO | MGADWG_BFCOL |
+ pMga->AtypeNoBLK[rop];
+
+ if(pMga->AccelFlags & TRANSC_SOLID_FILL)
+ pMga->FilledRectCMD |= MGADWG_TRANSC;
+
+ WAITFIFO(3);
+ SET_FOREGROUND(color);
+ SET_PLANEMASK(planemask);
+ OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD);
+}
+
+static void
+MGANAME(SubsequentSolidFillRect)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h )
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ WAITFIFO(2);
+ OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
+}
+
+static void
+MGANAME(SubsequentSolidFillTrap)(ScrnInfoPtr pScrn, int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR )
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ int sdxl = (dxL < 0);
+ int ar2 = sdxl? dxL : -dxL;
+ int sdxr = (dxR < 0);
+ int ar5 = sdxr? dxR : -dxR;
+
+ WAITFIFO(11);
+ OUTREG(MGAREG_DWGCTL,
+ pMga->FilledRectCMD & ~(MGADWG_ARZERO | MGADWG_SGNZERO));
+ OUTREG(MGAREG_AR0, dyL);
+ OUTREG(MGAREG_AR1, ar2 - eL);
+ OUTREG(MGAREG_AR2, ar2);
+ OUTREG(MGAREG_AR4, ar5 - eR);
+ OUTREG(MGAREG_AR5, ar5);
+ OUTREG(MGAREG_AR6, dyR);
+ OUTREG(MGAREG_SGN, (sdxl << 1) | (sdxr << 5));
+ OUTREG(MGAREG_FXBNDRY, ((right + 1) << 16) | (left & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
+ OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD);
+}
+
+ /***************\
+ | Solid Lines |
+ \***************/
+
+
+static void
+MGANAME(SubsequentSolidHorVertLine) (
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int len, int dir
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ if(dir == DEGREES_0) {
+ WAITFIFO(2);
+ OUTREG(MGAREG_FXBNDRY, ((x + len) << 16) | (x & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | 1);
+ } else if(pMga->AccelFlags & USE_RECTS_FOR_LINES) {
+ WAITFIFO(2);
+ OUTREG(MGAREG_FXBNDRY, ((x + 1) << 16) | (x & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | len);
+ } else {
+ WAITFIFO(4);
+ OUTREG(MGAREG_DWGCTL, pMga->SolidLineCMD | MGADWG_AUTOLINE_OPEN);
+ OUTREG(MGAREG_XYSTRT, (y << 16) | (x & 0xffff));
+ OUTREG(MGAREG_XYEND + MGAREG_EXEC, ((y + len) << 16) | (x & 0xffff));
+ OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD);
+ }
+}
+
+
+static void
+MGANAME(SubsequentSolidTwoPointLine)(
+ ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ WAITFIFO(4);
+ OUTREG(MGAREG_DWGCTL, pMga->SolidLineCMD |
+ ((flags & OMIT_LAST) ? MGADWG_AUTOLINE_OPEN : MGADWG_AUTOLINE_CLOSE));
+ OUTREG(MGAREG_XYSTRT, (y1 << 16) | (x1 & 0xFFFF));
+ OUTREG(MGAREG_XYEND + MGAREG_EXEC, (y2 << 16) | (x2 & 0xFFFF));
+ OUTREG(MGAREG_DWGCTL, pMga->FilledRectCMD);
+}
+
+
+
+ /***************************\
+ | 8x8 Mono Pattern Fills |
+ \***************************/
+
+
+static void
+MGANAME(SetupForMono8x8PatternFill)(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask )
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
+
+ pMga->PatternRectCMD = MGADWG_TRAP | MGADWG_ARZERO | MGADWG_SGNZERO |
+ MGADWG_BMONOLEF;
+
+ infoRec->SubsequentMono8x8PatternFillRect =
+ MGANAME(SubsequentMono8x8PatternFillRect);
+
+ if(bg == -1) {
+#if PSZ == 24
+ if(!RGBEQUAL(fg))
+ pMga->PatternRectCMD |= MGADWG_TRANSC | pMga->AtypeNoBLK[rop];
+ else
+#endif
+ pMga->PatternRectCMD |= MGADWG_TRANSC | pMga->Atype[rop];
+
+ WAITFIFO(5);
+ } else {
+#if PSZ == 24
+ if((pMga->AccelFlags & BLK_OPAQUE_EXPANSION) && RGBEQUAL(fg) && RGBEQUAL(bg))
+#else
+ if(pMga->AccelFlags & BLK_OPAQUE_EXPANSION)
+#endif
+ pMga->PatternRectCMD |= pMga->Atype[rop];
+ else
+ pMga->PatternRectCMD |= pMga->AtypeNoBLK[rop];
+ WAITFIFO(6);
+ SET_BACKGROUND(bg);
+ }
+
+ SET_FOREGROUND(fg);
+ SET_PLANEMASK(planemask);
+ OUTREG(MGAREG_DWGCTL, pMga->PatternRectCMD);
+ OUTREG(MGAREG_PAT0, patx);
+ OUTREG(MGAREG_PAT1, paty);
+}
+
+
+
+static void
+MGANAME(SubsequentMono8x8PatternFillRect)(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h )
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ WAITFIFO(3);
+ OUTREG(MGAREG_SHIFT, (paty << 4) | patx);
+ OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
+ pMga->AccelInfoRec->SubsequentMono8x8PatternFillRect =
+ MGANAME(SubsequentMono8x8PatternFillRect_Additional);
+}
+
+static void
+MGANAME(SubsequentMono8x8PatternFillRect_Additional)(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h )
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ WAITFIFO(2);
+ OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
+}
+
+
+static void
+MGANAME(SubsequentMono8x8PatternFillTrap)(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ int sdxl = (dxL < 0) ? (1<<1) : 0;
+ int ar2 = sdxl? dxL : -dxL;
+ int sdxr = (dxR < 0) ? (1<<5) : 0;
+ int ar5 = sdxr? dxR : -dxR;
+
+ WAITFIFO(12);
+ OUTREG(MGAREG_SHIFT, (paty << 4) | patx);
+ OUTREG(MGAREG_DWGCTL,
+ pMga->PatternRectCMD & ~(MGADWG_ARZERO | MGADWG_SGNZERO));
+ OUTREG(MGAREG_AR0, dyL);
+ OUTREG(MGAREG_AR1, ar2 - eL);
+ OUTREG(MGAREG_AR2, ar2);
+ OUTREG(MGAREG_AR4, ar5 - eR);
+ OUTREG(MGAREG_AR5, ar5);
+ OUTREG(MGAREG_AR6, dyR);
+ OUTREG(MGAREG_SGN, sdxl | sdxr);
+ OUTREG(MGAREG_FXBNDRY, ((right + 1) << 16) | (left & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
+ OUTREG(MGAREG_DWGCTL, pMga->PatternRectCMD);
+}
+
+ /***********************\
+ | Color Expand Rect |
+ \***********************/
+
+
+static void
+MGANAME(SetupForCPUToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask )
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ CARD32 mgaCMD = MGADWG_ILOAD | MGADWG_LINEAR | MGADWG_SGNZERO |
+ MGADWG_SHIFTZERO | MGADWG_BMONOLEF;
+
+ if(bg == -1) {
+#if PSZ == 24
+ if(!RGBEQUAL(fg))
+ mgaCMD |= MGADWG_TRANSC | pMga->AtypeNoBLK[rop];
+ else
+#endif
+ mgaCMD |= MGADWG_TRANSC | pMga->Atype[rop];
+
+ WAITFIFO(3);
+ } else {
+#if PSZ == 24
+ if((pMga->AccelFlags & BLK_OPAQUE_EXPANSION) &&
+ RGBEQUAL(fg) && RGBEQUAL(bg))
+#else
+ if(pMga->AccelFlags & BLK_OPAQUE_EXPANSION)
+#endif
+ mgaCMD |= pMga->Atype[rop];
+ else
+ mgaCMD |= pMga->AtypeNoBLK[rop];
+ WAITFIFO(4);
+ SET_BACKGROUND(bg);
+ }
+
+ SET_FOREGROUND(fg);
+ SET_PLANEMASK(planemask);
+ OUTREG(MGAREG_DWGCTL, mgaCMD);
+}
+
+static void
+MGANAME(SubsequentCPUToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ pMga->AccelFlags |= CLIPPER_ON;
+ WAITFIFO(5);
+ OUTREG(MGAREG_CXBNDRY, ((x + w - 1) << 16) | ((x + skipleft) & 0xFFFF));
+ w = (w + 31) & ~31; /* source is dword padded */
+ OUTREG(MGAREG_AR0, (w * h) - 1);
+ OUTREG(MGAREG_AR3, 0); /* crashes occasionally without this */
+ OUTREG(MGAREG_FXBNDRY, ((x + w - 1) << 16) | (x & 0xFFFF));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
+}
+
+ /*******************\
+ | Image Writes |
+ \*******************/
+
+
+static void MGANAME(SetupForImageWrite)(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ WAITFIFO(3);
+ OUTREG(MGAREG_AR5, 0);
+ SET_PLANEMASK(planemask);
+ OUTREG(MGAREG_DWGCTL, MGADWG_ILOAD | MGADWG_BFCOL | MGADWG_SHIFTZERO |
+ MGADWG_SGNZERO | pMga->AtypeNoBLK[rop]);
+}
+
+
+static void MGANAME(SubsequentImageWriteRect)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ pMga->AccelFlags |= CLIPPER_ON;
+
+ WAITFIFO(5);
+ OUTREG(MGAREG_CXBNDRY, 0xFFFF0000 | ((x + skipleft) & 0xFFFF));
+ OUTREG(MGAREG_AR0, w - 1);
+ OUTREG(MGAREG_AR3, 0);
+ OUTREG(MGAREG_FXBNDRY, ((x + w - 1) << 16) | (x & 0xFFFF));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
+}
+
+
+ /***************************\
+ | Dashed Lines |
+ \***************************/
+
+
+void
+MGANAME(SetupForDashedLine)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int length,
+ unsigned char *pattern
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+ CARD32 *DashPattern = (CARD32*)pattern;
+ CARD32 NiceDashPattern = DashPattern[0];
+ int dwords = (length + 31) >> 5;
+
+ pMga->DashCMD = MGADWG_BFCOL | pMga->AtypeNoBLK[rop];
+ pMga->StyleLen = length - 1;
+
+ if(bg == -1) {
+ pMga->DashCMD |= MGADWG_TRANSC;
+ WAITFIFO(dwords + 2);
+ } else {
+ WAITFIFO(dwords + 3);
+ SET_BACKGROUND(bg);
+ }
+ SET_PLANEMASK(planemask);
+ SET_FOREGROUND(fg);
+
+ /* We see if we can draw horizontal lines as 8x8 pattern fills.
+ This is worthwhile since the pattern fills can use block mode
+ and the default X pattern is 8 pixels long. The forward pattern
+ is the top scanline, the backwards pattern is the next one. */
+ switch(length) {
+ case 2: NiceDashPattern |= NiceDashPattern << 2;
+ case 4: NiceDashPattern |= NiceDashPattern << 4;
+ case 8: NiceDashPattern |= byte_reversed[NiceDashPattern] << 16;
+ NiceDashPattern |= NiceDashPattern << 8;
+ pMga->NiceDashCMD = MGADWG_TRAP | MGADWG_ARZERO |
+ MGADWG_SGNZERO | MGADWG_BMONOLEF;
+ pMga->AccelFlags |= NICE_DASH_PATTERN;
+ if(bg == -1) {
+#if PSZ == 24
+ if(!RGBEQUAL(fg))
+ pMga->NiceDashCMD |= MGADWG_TRANSC | pMga->AtypeNoBLK[rop];
+ else
+#endif
+ pMga->NiceDashCMD |= MGADWG_TRANSC | pMga->Atype[rop];
+ } else {
+#if PSZ == 24
+ if((pMga->AccelFlags & BLK_OPAQUE_EXPANSION) &&
+ RGBEQUAL(fg) && RGBEQUAL(bg))
+#else
+ if(pMga->AccelFlags & BLK_OPAQUE_EXPANSION)
+#endif
+ pMga->NiceDashCMD |= pMga->Atype[rop];
+ else
+ pMga->NiceDashCMD |= pMga->AtypeNoBLK[rop];
+ }
+ OUTREG(MGAREG_SRC0, NiceDashPattern);
+ break;
+ default: pMga->AccelFlags &= ~NICE_DASH_PATTERN;
+ switch (dwords) {
+ case 4: OUTREG(MGAREG_SRC3, DashPattern[3]);
+ case 3: OUTREG(MGAREG_SRC2, DashPattern[2]);
+ case 2: OUTREG(MGAREG_SRC1, DashPattern[1]);
+ default: OUTREG(MGAREG_SRC0, DashPattern[0]);
+ }
+ }
+}
+
+
+void
+MGANAME(SubsequentDashedTwoPointLine)(
+ ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2,
+ int flags, int phase
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ WAITFIFO(4);
+ if((pMga->AccelFlags & NICE_DASH_PATTERN) && (y1 == y2)) {
+ OUTREG(MGAREG_DWGCTL, pMga->NiceDashCMD);
+ if(x2 < x1) {
+ if(flags & OMIT_LAST) x2++;
+ OUTREG(MGAREG_SHIFT, ((-y1 & 0x07) << 4) |
+ ((7 - phase - x1) & 0x07));
+ OUTREG(MGAREG_FXBNDRY, ((x1 + 1) << 16) | (x2 & 0xffff));
+ } else {
+ if(!flags) x2++;
+ OUTREG(MGAREG_SHIFT, (((1 - y1) & 0x07) << 4) |
+ ((phase - x1) & 0x07));
+ OUTREG(MGAREG_FXBNDRY, (x2 << 16) | (x1 & 0xffff));
+ }
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y1 << 16) | 1);
+ } else {
+ OUTREG(MGAREG_SHIFT, (pMga->StyleLen << 16 ) |
+ (pMga->StyleLen - phase));
+ OUTREG(MGAREG_DWGCTL, pMga->DashCMD | ((flags & OMIT_LAST) ?
+ MGADWG_AUTOLINE_OPEN : MGADWG_AUTOLINE_CLOSE));
+ OUTREG(MGAREG_XYSTRT, (y1 << 16) | (x1 & 0xFFFF));
+ OUTREG(MGAREG_XYEND + MGAREG_EXEC, (y2 << 16) | (x2 & 0xFFFF));
+ }
+}
+
+
+#if PSZ != 24
+
+ /******************************************\
+ | Planar Screen to Screen Color Expansion |
+ \******************************************/
+
+static void
+MGANAME(SetupForPlanarScreenToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+ CARD32 mgaCMD = pMga->AtypeNoBLK[rop] | MGADWG_BITBLT |
+ MGADWG_SGNZERO | MGADWG_BPLAN;
+
+ if(bg == -1) {
+ mgaCMD |= MGADWG_TRANSC;
+ WAITFIFO(4);
+ } else {
+ WAITFIFO(5);
+ SET_BACKGROUND(bg);
+ }
+
+ SET_FOREGROUND(fg);
+ SET_PLANEMASK(planemask);
+ OUTREG(MGAREG_AR5, pScrn->displayWidth);
+ OUTREG(MGAREG_DWGCTL, mgaCMD);
+}
+
+static void
+MGANAME(SubsequentPlanarScreenToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy,
+ int skipleft
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+ int start, end;
+
+ w--;
+ start = XYADDRESS(srcx, srcy) + skipleft;
+ end = start + w;
+
+ WAITFIFO(4);
+ OUTREG(MGAREG_AR3, start);
+ OUTREG(MGAREG_AR0, end);
+ OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
+}
+
+#endif
+
+ /***********************************\
+ | Screen to Screen Color Expansion |
+ \***********************************/
+
+static void
+MGANAME(SetupForScreenToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+ CARD32 mgaCMD = MGADWG_BITBLT | MGADWG_SGNZERO | MGADWG_SHIFTZERO;
+
+ if(bg == -1) {
+#if PSZ == 24
+ if(!RGBEQUAL(fg))
+ mgaCMD |= MGADWG_TRANSC | pMga->AtypeNoBLK[rop];
+ else
+#endif
+ mgaCMD |= MGADWG_TRANSC | pMga->Atype[rop];
+
+ WAITFIFO(4);
+ } else {
+#if PSZ == 24
+ if((pMga->AccelFlags & BLK_OPAQUE_EXPANSION) &&
+ RGBEQUAL(fg) && RGBEQUAL(bg))
+#else
+ if((pMga->AccelFlags & BLK_OPAQUE_EXPANSION))
+#endif
+ mgaCMD |= pMga->Atype[rop];
+ else
+ mgaCMD |= pMga->AtypeNoBLK[rop];
+ WAITFIFO(5);
+ SET_BACKGROUND(bg);
+ }
+
+ SET_FOREGROUND(fg);
+ SET_PLANEMASK(planemask);
+ OUTREG(MGAREG_AR5, pScrn->displayWidth * PSZ);
+ OUTREG(MGAREG_DWGCTL, mgaCMD);
+
+}
+
+static void
+MGANAME(SubsequentScreenToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy,
+ int skipleft
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+ int pitch = pScrn->displayWidth * PSZ;
+ int start, end, next, num;
+ int SrcOrg = 0, DstOrg = 0;
+
+ if (pMga->AccelFlags & LARGE_ADDRESSES) {
+ DstOrg = ((y & ~1023) * pScrn->displayWidth * PSZ) >> 9;
+ SrcOrg = ((srcy & ~1023) * pScrn->displayWidth * PSZ) >> 9;
+ y &= 1023;
+
+ WAITFIFO(2);
+ if(DstOrg)
+ OUTREG(MGAREG_DSTORG, DstOrg << 6);
+ if(SrcOrg != pMga->SrcOrg) {
+ pMga->SrcOrg = SrcOrg;
+ OUTREG(MGAREG_SRCORG, SrcOrg << 6);
+ }
+ SrcOrg <<= 9;
+ }
+
+ w--;
+ start = (XYADDRESS(srcx, srcy) * PSZ) + skipleft;
+ end = start + w + (pitch * (h - 1));
+
+ /* src cannot split a 2 Meg boundary */
+ if(!((start ^ end) & 0xff000000)) {
+ WAITFIFO(4);
+ OUTREG(MGAREG_AR3, start - SrcOrg);
+ OUTREG(MGAREG_AR0, start + w - SrcOrg);
+ OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
+ } else {
+ while(h) {
+ next = (start + 0x00ffffff) & 0xff000000;
+ if(next <= (start + w)) {
+ num = next - start - 1;
+
+ WAITFIFO(7);
+ OUTREG(MGAREG_AR3, start - SrcOrg);
+ OUTREG(MGAREG_AR0, start + num - SrcOrg);
+ OUTREG(MGAREG_FXBNDRY, ((x + num) << 16) | (x & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | h);
+
+ OUTREG(MGAREG_AR3, next - SrcOrg);
+ OUTREG(MGAREG_AR0, start + w - SrcOrg);
+ OUTREG(MGAREG_FXBNDRY + MGAREG_EXEC, ((x + w) << 16) |
+ ((x + num + 1) & 0xffff));
+ start += pitch;
+ h--; y++;
+ } else {
+ num = ((next - start - w)/pitch) + 1;
+ if(num > h) num = h;
+
+ WAITFIFO(4);
+ OUTREG(MGAREG_AR3, start - SrcOrg);
+ OUTREG(MGAREG_AR0, start + w - SrcOrg);
+ OUTREG(MGAREG_FXBNDRY, ((x + w) << 16) | (x & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y << 16) | num);
+
+ start += num * pitch;
+ h -= num; y += num;
+ }
+ }
+ }
+
+ if(DstOrg) {
+ WAITFIFO(1);
+ OUTREG(MGAREG_DSTORG, 0);
+ }
+}
+
+
+
+#if PSZ == 8
+
+
+static __inline__ CARD32* MoveDWORDS(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords
+)
+{
+ while(dwords & ~0x03) {
+ dest[0] = src[0];
+ dest[1] = src[1];
+ dest[2] = src[2];
+ dest[3] = src[3];
+ src += 4;
+ dest += 4;
+ dwords -= 4;
+ }
+
+ if(!dwords) return(dest);
+ dest[0] = src[0];
+ if(dwords == 1) return(dest+1);
+ dest[1] = src[1];
+ if(dwords == 2) return(dest+2);
+ dest[2] = src[2];
+ return(dest+3);
+}
+
+void
+MGAWriteBitmapColorExpand(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+)
+{
+ MGAPtr pMga = MGAPTR(pScrn);
+ XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
+ CARD32* destptr = (CARD32*)infoRec->ColorExpandBase;
+ CARD32* maxptr;
+ int dwords, maxlines, count;
+
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ w += skipleft;
+ x -= skipleft;
+ dwords = (w + 31) >> 5;
+ maxlines = pMga->MaxBlitDWORDS / dwords;
+ maxptr = destptr + infoRec->ColorExpandRange - dwords;
+
+ while(h > maxlines) {
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)
+ (pScrn, x, y, w, maxlines, skipleft);
+ count = maxlines;
+ while(count--) {
+ destptr = MoveDWORDS(destptr, (CARD32*)src, dwords);
+ src += srcwidth;
+ if(destptr > maxptr)
+ destptr = (CARD32*)infoRec->ColorExpandBase;
+ }
+ h -= maxlines;
+ y += maxlines;
+ }
+
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, x, y, w, h, skipleft);
+
+ while(h--) {
+ destptr = MoveDWORDS(destptr, (CARD32*)src, dwords);
+ src += srcwidth;
+ if(destptr > maxptr)
+ destptr = (CARD32*)infoRec->ColorExpandBase;
+ }
+ MGAStormSync(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+}
+
+
+void
+MGAFillColorExpandRects(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+ XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
+ CARD32 *destptr, *maxptr;
+ StippleScanlineProcPtr StippleFunc;
+ unsigned char *src = (unsigned char*)pPix->devPrivate.ptr;
+ int stipplewidth = pPix->drawable.width;
+ int stippleheight = pPix->drawable.height;
+ int srcwidth = pPix->devKind;
+ int dwords, h, y, maxlines, count, srcx, srcy;
+ unsigned char *srcp;
+
+ if(stipplewidth <= 32) {
+ if(stipplewidth & (stipplewidth - 1))
+ StippleFunc = XAAStippleScanlineFuncLSBFirst[1];
+ else
+ StippleFunc = XAAStippleScanlineFuncLSBFirst[0];
+ } else
+ StippleFunc = XAAStippleScanlineFuncLSBFirst[2];
+
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ while(nBox--) {
+ dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
+ destptr = (CARD32*)infoRec->ColorExpandBase;
+ maxptr = destptr + infoRec->ColorExpandRange - dwords;
+ maxlines = pMga->MaxBlitDWORDS / dwords;
+ y = pBox->y1;
+ h = pBox->y2 - y;
+
+ srcy = (pBox->y1 - yorg) % stippleheight;
+ if(srcy < 0) srcy += stippleheight;
+ srcx = (pBox->x1 - xorg) % stipplewidth;
+ if(srcx < 0) srcx += stipplewidth;
+
+ srcp = (srcwidth * srcy) + src;
+
+ while(h > maxlines) {
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(pScrn,
+ pBox->x1, y, pBox->x2 - pBox->x1, maxlines, 0);
+ count = maxlines;
+ while(count--) {
+ destptr = (*StippleFunc)(
+ destptr, (CARD32*)srcp, srcx, stipplewidth, dwords);
+ if(destptr > maxptr)
+ destptr = (CARD32*)infoRec->ColorExpandBase;
+ srcy++;
+ srcp += srcwidth;
+ if (srcy >= stippleheight) {
+ srcy = 0;
+ srcp = src;
+ }
+ }
+ h -= maxlines;
+ y += maxlines;
+ }
+
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(pScrn,
+ pBox->x1, y , pBox->x2 - pBox->x1, h, 0);
+
+ while(h--) {
+ destptr = (*StippleFunc)(
+ destptr, (CARD32*)srcp, srcx, stipplewidth, dwords);
+ if(destptr > maxptr)
+ destptr = (CARD32*)infoRec->ColorExpandBase;
+ srcy++;
+ srcp += srcwidth;
+ if (srcy >= stippleheight) {
+ srcy = 0;
+ srcp = src;
+ }
+ }
+
+ pBox++;
+ }
+ MGAStormSync(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+}
+
+
+void
+MGAFillSolidRectsDMA(
+ ScrnInfoPtr pScrn,
+ int fg, int rop,
+ unsigned int planemask,
+ int nBox, /* number of rectangles to fill */
+ BoxPtr pBox /* Pointer to first rectangle to fill */
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+ XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
+ CARD32 *base = (CARD32*)pMga->ILOADBase;
+
+ SET_SYNC_FLAG(infoRec);
+ (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask);
+
+ if(nBox & 1) {
+ OUTREG(MGAREG_FXBNDRY, ((pBox->x2) << 16) | (pBox->x1 & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC,
+ (pBox->y1 << 16) | (pBox->y2 - pBox->y1));
+ nBox--; pBox++;
+ }
+
+ if(!nBox) return;
+
+ OUTREG(MGAREG_OPMODE, MGAOPM_DMA_GENERAL);
+ while(nBox) {
+ base[0] = DMAINDICES(MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC,
+ MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC);
+ base[1] = ((pBox->x2) << 16) | (pBox->x1 & 0xffff);
+ base[2] = (pBox->y1 << 16) | (pBox->y2 - pBox->y1);
+ pBox++;
+ base[3] = ((pBox->x2) << 16) | (pBox->x1 & 0xffff);
+ base[4] = (pBox->y1 << 16) | (pBox->y2 - pBox->y1);
+ pBox++;
+ base += 5; nBox -= 2;
+ }
+ OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT);
+}
+
+void
+MGAFillSolidSpansDMA(
+ ScrnInfoPtr pScrn,
+ int fg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+ XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
+ CARD32 *base = (CARD32*)pMga->ILOADBase;
+
+ SET_SYNC_FLAG(infoRec);
+
+ if(infoRec->ClipBox) {
+ OUTREG(MGAREG_CXBNDRY,
+ ((infoRec->ClipBox->x2 - 1) << 16) | infoRec->ClipBox->x1);
+ OUTREG(MGAREG_YTOP,
+ (infoRec->ClipBox->y1 * pScrn->displayWidth) + pMga->YDstOrg);
+ OUTREG(MGAREG_YBOT,
+ ((infoRec->ClipBox->y2 - 1) * pScrn->displayWidth) + pMga->YDstOrg);
+ }
+
+ (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask);
+
+ if(n & 1) {
+ OUTREG(MGAREG_FXBNDRY, ((ppt->x + *pwidth) << 16) | (ppt->x & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (ppt->y << 16) | 1);
+ ppt++; pwidth++; n--;
+ }
+
+ if(n) {
+ if(n > 838860) n = 838860; /* maximum number we have room for */
+
+ OUTREG(MGAREG_OPMODE, MGAOPM_DMA_GENERAL);
+ while(n) {
+ base[0] = DMAINDICES(MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC,
+ MGAREG_FXBNDRY, MGAREG_YDSTLEN + MGAREG_EXEC);
+ base[1] = ((ppt->x + *(pwidth++)) << 16) | (ppt->x & 0xffff);
+ base[2] = (ppt->y << 16) | 1;
+ ppt++;
+ base[3] = ((ppt->x + *(pwidth++)) << 16) | (ppt->x & 0xffff);
+ base[4] = (ppt->y << 16) | 1;
+ ppt++;
+ base += 5; n -= 2;
+ }
+ OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT);
+ }
+
+ if(infoRec->ClipBox) {
+ OUTREG(MGAREG_CXBNDRY, 0xFFFF0000); /* (maxX << 16) | minX */
+ OUTREG(MGAREG_YTOP, 0x00000000); /* minPixelPointer */
+ OUTREG(MGAREG_YBOT, 0x007FFFFF); /* maxPixelPointer */
+ }
+}
+
+
+void
+MGAFillMono8x8PatternRectsTwoPass(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBoxInit,
+ BoxPtr pBoxInit,
+ int pattern0, int pattern1,
+ int xorg, int yorg
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+ XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
+ int nBox, SecondPassColor;
+ BoxPtr pBox;
+
+ if((rop == GXcopy) && (bg != -1)) {
+ SecondPassColor = bg;
+ bg = -1;
+ } else SecondPassColor = -1;
+
+ WAITFIFO(1);
+ OUTREG(MGAREG_SHIFT, (((-yorg) & 0x07) << 4) | ((-xorg) & 0x07));
+
+SECOND_PASS:
+
+ nBox = nBoxInit;
+ pBox = pBoxInit;
+
+ (*infoRec->SetupForMono8x8PatternFill)(pScrn, pattern0, pattern1,
+ fg, bg, rop, planemask);
+
+ while(nBox--) {
+ WAITFIFO(2);
+ OUTREG(MGAREG_FXBNDRY, ((pBox->x2) << 16) | (pBox->x1 & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC,
+ (pBox->y1 << 16) | (pBox->y2 - pBox->y1));
+ pBox++;
+ }
+
+ if(SecondPassColor != -1) {
+ fg = SecondPassColor;
+ SecondPassColor = -1;
+ pattern0 = ~pattern0;
+ pattern1 = ~pattern1;
+ goto SECOND_PASS;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+void MGANonTEGlyphRenderer(
+ ScrnInfoPtr pScrn,
+ int x, int y, int n,
+ NonTEGlyphPtr glyphs,
+ BoxPtr pbox,
+ int fg, int rop,
+ unsigned int planemask
+){
+ MGAPtr pMga = MGAPTR(pScrn);
+ XAAInfoRecPtr infoRec = pMga->AccelInfoRec;
+ int x1, x2, y1, y2, i, h, skiptop, dwords, maxlines;
+ unsigned char *src;
+
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, -1, rop, planemask);
+ WAITFIFO(1);
+ OUTREG(MGAREG_CXBNDRY, ((pbox->x2 - 1) << 16) | pbox->x1);
+ pMga->AccelFlags |= CLIPPER_ON;
+
+ for(i = 0; i < n; i++, glyphs++) {
+ if(!glyphs->srcwidth) continue;
+
+ y1 = y - glyphs->yoff;
+ y2 = y1 + glyphs->height;
+ if(y1 < pbox->y1) {
+ skiptop = pbox->y1 - y1;
+ y1 = pbox->y1;
+ } else skiptop = 0;
+ if(y2 > pbox->y2) y2 = pbox->y2;
+
+ h = y2 - y1;
+ if(h <= 0) continue;
+
+ src = glyphs->bits + (skiptop * glyphs->srcwidth);
+
+ dwords = glyphs->srcwidth >> 2; /* dwords per line */
+ x1 = x + glyphs->start;
+ x2 = x1 + (dwords << 5);
+
+ maxlines = min(pMga->MaxBlitDWORDS, infoRec->ColorExpandRange);
+ maxlines /= dwords;
+
+ while(h > maxlines) {
+ WAITFIFO(4);
+ OUTREG(MGAREG_AR0, (dwords * maxlines << 5) - 1);
+ OUTREG(MGAREG_AR3, 0);
+ OUTREG(MGAREG_FXBNDRY, ((x2 - 1) << 16) | (x1 & 0xFFFF));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y1 << 16) | h);
+ MoveDWORDS((CARD32*)infoRec->ColorExpandBase,
+ (CARD32*)src, dwords * maxlines);
+ src += dwords * maxlines << 2;
+ h -= maxlines;
+ y1 += maxlines;
+ }
+
+ dwords *= h; /* total dwords */
+ WAITFIFO(4);
+ OUTREG(MGAREG_AR0, (dwords << 5) - 1);
+ OUTREG(MGAREG_AR3, 0);
+ OUTREG(MGAREG_FXBNDRY, ((x2 - 1) << 16) | (x1 & 0xFFFF));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (y1 << 16) | h);
+
+ MoveDWORDS((CARD32*)infoRec->ColorExpandBase, (CARD32*)src, dwords);
+ }
+
+ MGAStormSync(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+}
+
+void
+MGAValidatePolyArc(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+){
+ ScrnInfoPtr pScrn = xf86Screens[pGC->pScreen->myNum];
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ if((pMga->AccelFlags & MGA_NO_PLANEMASK) && (pGC->planemask != ~0))
+ return;
+
+ if(!pGC->lineWidth &&
+ (pGC->fillStyle == FillSolid) &&
+ (pGC->lineStyle == LineSolid) &&
+ ((pGC->alu != GXcopy) || (pGC->planemask != ~0) ||
+ (pScrn->bitsPerPixel == 24))) {
+ pGC->ops->PolyArc = MGAPolyArcThinSolid;
+ }
+}
+
+static void
+MGAPolyPoint (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *ppt
+){
+ int numRects = REGION_NUM_RECTS(pGC->pCompositeClip);
+ XAAInfoRecPtr infoRec;
+ BoxPtr pbox;
+ MGAPtr pMga;
+ int xorg, yorg;
+
+ if(!numRects) return;
+
+ if(numRects != 1) {
+ XAAFallbackOps.PolyPoint(pDraw, pGC, mode, npt, ppt);
+ return;
+ }
+
+ infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ pMga = MGAPTR(infoRec->pScrn);
+ xorg = pDraw->x;
+ yorg = pDraw->y;
+
+ pbox = REGION_RECTS(pGC->pCompositeClip);
+
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ pbox->x1, pbox->y1, pbox->x2 - 1, pbox->y2 - 1);
+ (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
+ pGC->planemask);
+
+ if(mode == CoordModePrevious) {
+ while(npt--) {
+ xorg += ppt->x;
+ yorg += ppt->y;
+ WAITFIFO(2);
+ OUTREG(MGAREG_FXBNDRY, ((xorg + 1) << 16) | (xorg & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, (yorg << 16) | 1);
+ ppt++;
+ }
+ } else {
+ int x;
+ while(npt--) {
+ x = ppt->x + xorg;
+ WAITFIFO(2);
+ OUTREG(MGAREG_FXBNDRY, ((x + 1) << 16) | (x & 0xffff));
+ OUTREG(MGAREG_YDSTLEN + MGAREG_EXEC, ((ppt->y + yorg) << 16) | 1);
+ ppt++;
+ }
+ }
+
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+void
+MGAValidatePolyPoint(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+){
+ ScrnInfoPtr pScrn = xf86Screens[pGC->pScreen->myNum];
+ MGAPtr pMga = MGAPTR(pScrn);
+
+ pGC->ops->PolyPoint = XAAFallbackOps.PolyPoint;
+
+ if((pMga->AccelFlags & MGA_NO_PLANEMASK) && (pGC->planemask != ~0))
+ return;
+
+ if((pGC->alu != GXcopy) || (pGC->planemask != ~0) ||
+ (pScrn->bitsPerPixel == 24))
+ pGC->ops->PolyPoint = MGAPolyPoint;
+}
+
+
+void
+MGAFillCacheBltRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, y, phaseY, phaseX, skipleft, height, width, w, blit_w, blit_h, start;
+
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, rop, planemask,
+ pCache->trans_color);
+
+ while(nBox--) {
+ y = pBox->y1;
+ phaseY = (y - yorg) % pCache->orig_h;
+ if(phaseY < 0) phaseY += pCache->orig_h;
+ phaseX = (pBox->x1 - xorg) % pCache->orig_w;
+ if(phaseX < 0) phaseX += pCache->orig_w;
+ height = pBox->y2 - y;
+ width = pBox->x2 - pBox->x1;
+ start = phaseY ? (pCache->orig_h - phaseY) : 0;
+
+ /* This is optimized for WRAM */
+
+ if ((rop == GXcopy) && (height >= (pCache->orig_h + start))) {
+ w = width; skipleft = phaseX; x = pBox->x1;
+ blit_h = pCache->orig_h;
+
+ while(1) {
+ blit_w = pCache->w - skipleft;
+ if(blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pCache->x + skipleft, pCache->y,
+ x, y + start, blit_w, blit_h);
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ skipleft = (skipleft + blit_w) % pCache->orig_w;
+ }
+ height -= blit_h;
+
+ if(start) {
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pBox->x1, y + blit_h, pBox->x1, y, width, start);
+ height -= start;
+ y += start;
+ }
+ start = blit_h;
+
+ while(height) {
+ if(blit_h > height) blit_h = height;
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pBox->x1, y,
+ pBox->x1, y + start, width, blit_h);
+ height -= blit_h;
+ start += blit_h;
+ blit_h <<= 1;
+ }
+ } else {
+ while(1) {
+ w = width; skipleft = phaseX; x = pBox->x1;
+ blit_h = pCache->h - phaseY;
+ if(blit_h > height) blit_h = height;
+
+ while(1) {
+ blit_w = pCache->w - skipleft;
+ if(blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pCache->x + skipleft, pCache->y + phaseY,
+ x, y, blit_w, blit_h);
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ skipleft = (skipleft + blit_w) % pCache->orig_w;
+ }
+ height -= blit_h;
+ if(!height) break;
+ y += blit_h;
+ phaseY = (phaseY + blit_h) % pCache->orig_h;
+ }
+ }
+ pBox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+#endif
+
+
+
+
+
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/util/Makefile b/xc/programs/Xserver/hw/xfree86/drivers/mga/util/Makefile
new file mode 100644
index 000000000..e0de4ea90
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/util/Makefile
@@ -0,0 +1,12 @@
+# $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/util/Makefile,v 1.1 1997/04/12 14:11:28 hohndel Exp $
+
+
+
+all: stormdwg
+
+stormdwg: stormdwg.c
+ cc -o stormdwg stormdwg.c
+
+clean:
+ rm -f *.o stormdwg
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/util/README b/xc/programs/Xserver/hw/xfree86/drivers/mga/util/README
new file mode 100644
index 000000000..3d7275254
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/util/README
@@ -0,0 +1,25 @@
+
+Tech Note: dwg.c
+
+author: ajv
+
+purpose: to display MGA Storm's dwg register in human readable output.
+
+compilation: cc -o stormdwg stormdwg.c or just type make
+
+usage: stormdwg hexval
+
+hexval will then be decomposed into it's constituent parts and displayed in human
+readable format.
+
+BUGS: none known except that it needs to kept upto date if the storms
+ spec is changed
+
+NOTE: This is not by itself a very usable utility.
+
+Andrew van der Stock
+ajv@greebo.svhm.org.au
+
+
+
+$XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/util/README,v 1.1 1997/04/12 14:11:28 hohndel Exp $
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/mga/util/stormdwg.c b/xc/programs/Xserver/hw/xfree86/drivers/mga/util/stormdwg.c
new file mode 100644
index 000000000..e13916cbf
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/mga/util/stormdwg.c
@@ -0,0 +1,184 @@
+/* $XConsortium: dwg.c /main/2 1996/10/28 06:57:55 kaleb $ */
+
+
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/util/stormdwg.c,v 1.1 1997/04/12 14:11:29 hohndel Exp $ */
+
+#include <stdio.h>
+/* #include <stdlib.h> */
+
+char *opcodes[] = {
+ "line_open", /* 0000 */
+ "autoline_open", /* 0001 */
+ "line_close", /* 0010 */
+ "autoline_close", /* 0011 */
+
+ "trapezoid", /* 0100 */
+ "trapezoid texture map", /* 0101 */
+ "reserved trap", /* 0110 */
+ "reserved trap", /* 0111 */
+
+ "bitblt", /* 1000 */
+ "iload", /* 1001 */
+ "reserved", /* 1010 */
+ "reserved", /* 1011 */
+
+ "fbitblt", /* 1100 */
+ "iload scale", /* 1101 */
+ "reserved", /* 1110 */
+ "iload filter" /* 1111 */
+};
+
+char *atype[] = {
+ "rpl - Write (Replace)", /* 000 */
+ "rstr - read-modify-write (raster)", /* 001 */
+ "reserved", /* 010 */
+ "z1 - depth mode with gouraud", /* 011 */
+ "blk - block write mode", /* 100 */
+ "reserved", /* 101 */
+ "reserved", /* 110 */
+ "I - Gouraud (with depth compare)" /* 111 */
+};
+
+char *zmode[] = {
+ "NOZCMP - always", /* 000 */
+ "reserved", /* 001 */
+ "ZE - depth =", /* 010 */
+ "zne - depth !=", /* 011 */
+ "zlt", /* 100 */
+ "zlte", /* 101 */
+ "zgt", /* 110 */
+ "zgte" /* 111 */
+};
+
+char *bop[] = {
+ "0", /* 0000 */
+ "~(D|S)", /* 0001 */
+ "D & ~S", /* 0010 */
+ "~S", /* 0011 */
+
+ "(~D) & S", /* 0100 */
+ "~D", /* 0101 */
+ "D ^ S", /* 0110 */
+ "~ (D & S)", /* 0111 */
+
+ "D & S", /* 1000 */
+ "~(D^S)", /* 1001 */
+ "D", /* 1010 */
+ "D | ~S", /* 1011 */
+
+ "S", /* 1100 */
+ "(~D) | S", /* 1101 */
+ "D | S", /* 1110 */
+ "1" /* 1111 */
+};
+
+char *bitmod[] = {
+ "BMONOLEF - Source is mono, or if iload, source is little endian", /* 0000 */
+ "BPLAN - source is mono from one plane", /* 0001 */
+ "BFCOL - source is colour, and is formatted from host", /* 0010 */
+ "BU32BGR - source is colour. For ILOAD, it's in 32bpp, BGR format", /* 0011 */
+
+ "BMONOWEF - source is mono, or if iload, source is windows format", /* 0100 */
+ "error! no such mode", /* 0101 */
+ "error! no such mode", /* 0110 */
+ "BU32RGB - source is colour, or if iload, source is 32 bpp RGB", /* 0111 */
+
+ "error! no such mode", /* 1000 */
+ "error! no such mode", /* 1001 */
+ "error! no such mode", /* 1010 */
+ "BU24BGR - source is colour, of if iload, source is 24 bpp BGR", /* 1011 */
+
+ "error! no such mode", /* 1100 */
+ "error! no such mode", /* 1101 */
+ "BUYUV - source is color, or for ILOAD, it's in 4:2:2 YUV format", /* 1110 */
+ "BU24RGB - source is color, or for ILOAD, it's in 24 bpp RGB" /* 1111 */
+};
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ unsigned long val, tmp;
+
+ if ( argc != 2 )
+ {
+ fprintf(stderr, "usage: %s hexval\n", argv[0]);
+ return 1;
+ }
+
+ val = strtoul(argv[1], NULL, 16);
+
+ printf("the val is : %d\n", val);
+
+ /* opcode */
+
+ tmp = val & 0x0f;
+
+ printf("opcode: %s\n", opcodes[tmp]);
+
+ tmp = ( val >> 4 ) & 0x7;
+
+ printf("atype: %s\n", atype[tmp]);
+
+
+ if ( val & 128 )
+ printf("xy bitblt\n");
+ else
+ printf("linear bitblt\n");
+
+ tmp = ( val >> 8 ) & 7;
+
+ printf("zmode: %s\n", zmode[tmp]);
+
+
+ if ( val & ( 1 << 11 ) )
+ printf("solid line or constant trapezoid\n");
+ else
+ printf("src0 - 3 may need to be loaded");
+
+ if ( val & ( 1 << 12 ))
+ printf("ar0-ar6 = 0\n");
+ else
+ printf("you may need to set ar0-6.\n");
+
+
+ if ( val & ( 1 << 13 ))
+ printf("sgn = 0\n");
+ else
+ printf("sgn is not affected\n");
+
+
+ if ( val & ( 1 << 14 ))
+ printf("shift = 0\n");
+ else
+ printf("shift is not affected\n");
+
+
+ tmp = (val>>16) & 0x0f;
+
+ if ( ((val >> 4) & 7) == 4 && tmp != 0x0c )
+ printf("Error! Block (BLK) atype and non-source binary op chosen. Replace (S) bop will be used.\n");
+
+ printf("bop = %s, where ~ = bitwise complement, ^ = xor\n", bop[tmp]);
+
+ if ( ((val >> 20) & 0x0f) == 0 )
+ printf("opaque object\n");
+ else
+ printf("partially opaque object\n");
+
+ tmp = (val >> 25) & 0x0f;
+ printf("bitmod: %s\n", bitmod[tmp]);
+
+ if ((val >> 29) & 0x01)
+ printf("patterning enabled\n");
+ else
+ printf("patterning disabled\n");
+
+ if ((val >> 30) & 0x01)
+ printf("background colour is transparent\n");
+ else
+ printf("background colour is opaque\n");
+
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile
new file mode 100644
index 000000000..7b84852f1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile
@@ -0,0 +1,53 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/Imakefile,v 1.2 1999/08/14 10:49:50 dawes Exp $
+#define IHaveModules
+#include <Server.tmpl>
+
+
+SRCS = neo_driver.c neo_bank.c neo_cursor.c neo_2097.c neo_2070.c \
+ neo_2090.c neo_2200.c neo_i2c.c
+
+OBJS = neo_driver.o neo_bank.o neo_cursor.o neo_2097.o neo_2070.o \
+ neo_2090.o neo_2200.o neo_i2c.o
+
+DEFINES = -DPSZ=8
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(XF86SRC)/vgafb -I$(XF86SRC)/vgahw -I$(SERVERSRC)/include \
+ -I$(SERVERSRC)/mi -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mfb \
+ -I$(XINCLUDESRC) -I$(XF86SRC)/xaa -I$(FONTINCSRC) \
+ -I$(XF86SRC)/ramdac -I$(XF86SRC)/rac -I$(XF86SRC)/ddc \
+ -I$(XF86SRC)/i2c -I$(XF86SRC)/shadowfb -I$(XF86SRC)/xf24_32bpp
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+
+ModuleObjectRule()
+
+ObjectModuleTarget(neomagic,$(OBJS))
+
+InstallObjectModule(neomagic,$(MODULEDIR),drivers)
+
+#ifndef OS2Architecture
+DependTarget()
+#endif
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/neomagic)
+InstallDriverSDKNonExecFile(neo.h,$(DRIVERSDKDIR)/drivers/neomagic)
+InstallDriverSDKNonExecFile(neo_2070.c,$(DRIVERSDKDIR)/drivers/neomagic)
+InstallDriverSDKNonExecFile(neo_2090.c,$(DRIVERSDKDIR)/drivers/neomagic)
+InstallDriverSDKNonExecFile(neo_2097.c,$(DRIVERSDKDIR)/drivers/neomagic)
+InstallDriverSDKNonExecFile(neo_2200.c,$(DRIVERSDKDIR)/drivers/neomagic)
+InstallDriverSDKNonExecFile(neo_bank.c,$(DRIVERSDKDIR)/drivers/neomagic)
+InstallDriverSDKNonExecFile(neo_cursor.c,$(DRIVERSDKDIR)/drivers/neomagic)
+InstallDriverSDKNonExecFile(neo_driver.c,$(DRIVERSDKDIR)/drivers/neomagic)
+InstallDriverSDKNonExecFile(neo_i2c.c,$(DRIVERSDKDIR)/drivers/neomagic)
+InstallDriverSDKNonExecFile(neo_macros.h,$(DRIVERSDKDIR)/drivers/neomagic)
+InstallDriverSDKNonExecFile(neo_reg.h,$(DRIVERSDKDIR)/drivers/neomagic)
+
+InstallDriverSDKObjectModule(neomagic,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/README b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/README
new file mode 100644
index 000000000..059be1857
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/README
@@ -0,0 +1,150 @@
+
+ Information for NeoMagic Users
+ NeoMagic Driver Version 0.2/4.0
+ (based on version 2.0.0/3.3.3)
+
+
+1) Supported hardware
+
+ * NeoMagic 2200 (MagicMedia256AV)
+ * NeoMagic 2160 (MagicGraph128XD)
+ * NeoMagic 2097 (MagicGraph128ZV+)
+ * NeoMagic 2093 (MagicGraph128ZV)
+ * NeoMagic 2090 (MagicGraph128V)
+ * NeoMagic 2070 (MagicGraph128)
+
+
+2) Features
+
+ * Full support for internal flat panels, external monitors, and
+ simultaneous internal/external displays.
+
+ * Complete set of Panel Resolutions supported including stretch and
+ centering modes for running lower resolutions on fixed resolution
+ panels.
+
+ * Support for depths of 8, 15, 16 and 24 bits per pixel.
+
+ * Hardware Cursor support to reduce sprite flicker.
+
+ * Hardware accelerated drawing engine for 8, 15 and 16 bit per
+ pixel modes.
+
+ * Fully programmable clocks supported in external monitor only
+ mode.
+
+ * Robust text mode restore for VT switching.
+
+
+3) Technical Notes
+
+ * Enable both internal "intern_disp" and external "extern_disp"
+ options to get simultaneous panel/CRT support.
+
+
+4) Reported Working Laptops
+
+ * Acer Travelmate 7120T
+ * Acer Extensa 367, 367D & 710TE
+ * Actebis TN559Pro
+ * Asus P6300
+ * CTX EzBook 700 & 77X series
+ * Compaq Presario 1080, 1210, 1215, 1220, 1610, 1611, 1620, 1621 & 1640
+ * Dell Inspiron 3000 & 3200
+ * Dell Latitude CP, CPi, LM & XPi
+ * Digital VP HiNote 575, 703, 717 & 720
+ * FIC DESIGNote 5550
+ * Fujitsu LifeBook 420D & 656Tx
+ * Gateway 2000 Solo 2300XL, 2500LS & 5150
+ * Highscreen XD Advance II 21,1" TFT
+ * Hi-Grade Notino AS6000 pII/266Mhz
+ * Hitachi VisionBook Plus 5000
+ * HP Omnibook 800, 3000, 3100, 4100 & Sojourn
+ * IBM ThinkPad 380D, 380E, 380ED, 380XD, 385XD, 560X & 600
+ * LEO DESIGNote 5550
+ * Micron Transport XKE
+ * NEC Ready 330T
+ * NEC Versa 2780 MT, 5060X, 5080X, 6060 & 6230
+ * NEC MB12C/UV (mobio NX)
+ * OPTI Phoenix
+ * Panasonic CF_S21, CF-25 MKIII & CF-35
+ * Quantex H-1330
+ * Sceptre 4500
+ * SEH DESIGNote 5550
+ * Siemens Nixdorf Scenic 510
+ * Sony PCG-505, PCG-705, PCG-717, PCG-719 & PCG-731
+ * TI Extensa 660 CDT
+ * Toshiba Libretto 100CT
+ * Toshiba Protege SS3000
+ * UMAX 520T
+
+
+5) Configuration
+
+ The driver auto-detects all device info included memory size, so
+ use the following device section in your XF86Config file:
+
+ Section "Device"
+ Identifier "NeoMagic"
+ EndSection
+
+ or let xf86config or XF86Setup do this for you.
+
+ But if you have problems with auto-detection, you can specify:
+
+ VideoRam - in kilobytes
+ DacSpeed - in MHz
+ MemBase - physical address of the linear framebuffer
+ IOBase - physical address of the memory mapped IO registers
+
+
+6) Driver Options
+
+ "no_linear" - banked framebuffer mode
+ "no_accel" - software rendering only
+ "sw_cursor" - software cursor only
+ "no_mmio" - use I/O space directly
+ "intern_disp" - enable internal display (default)
+ "extern_disp" - enable external display
+ "no_stretch" - disable stretching of lower resolution modes on panel
+ "lcd_center" - center lower resolution modes on panel
+
+ NOTE: Stretching of panel image is on by default for lower panel
+ resolutions.
+
+ Options useful for special lcd mode setting (should not be needed):
+ "prog_lcd_mode_regs" - set special lcd mode registers (2070 default)
+ "no_prog_lcd_mode_regs" - don't set lcd mode registers (non-2070 default)
+ "prog_lcd_mode_stretch" - force lcd mode regs if stretching is enabled
+ "no_prog_lcd_mode_stretch" - no lcd mode regs if stretching (default)
+
+ Option for subnotebooks and other laptops with uncommon size panels:
+ "override_validate_mode" - disable LCD mode checking
+
+ WARNING: Disabling mode checking will allow for invalid modes that
+ could damage your LCD.
+
+7) Known Limitations
+
+ * External monitor support on the NM2070.
+ * Banked, or no_linear mode on the NM2070.
+ * Horizontal centering for lower than panel resolution on NM2070.
+
+8) Authors
+
+ The original version of the driver - written for Xfree86 3.3 -
+ done by:
+ Jens Owen (jens@precisioninsight.com)
+ Kevin E. Martin (kevin@precisioninsight.com)
+
+ Precision Insight, Inc.
+ Cedar Park, TX USA
+
+ http://www.precisioninsight.com
+
+ Port to Xfree86 4.0 done by:
+ Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.de)
+
+
+
+$XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/README,v 1.1 1999/04/17 07:06:15 dawes Exp $
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/TODO b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/TODO
new file mode 100644
index 000000000..ab255c1db
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/TODO
@@ -0,0 +1,20 @@
+1. Acceleration:
+
+ a. Limitations from 3.3 apply.
+ b. No CPU to Screen color expand. Chipset requires SCANLINE_PAD_BYTE
+ XAA only supports SCANLINE_PAD_WORD
+
+2. Driver itself:
+
+ a. VL bus probe might be too intrusive
+ b. min clock guessed 11.0 MHz
+ c. guessed: interlace allowed only when external display is enabled.
+ d. display pitch guessed to be 8 bit.
+
+3. I2C Support:
+
+ a. Readback of clockline not implemented.
+
+
+
+$XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/TODO,v 1.1 1999/04/17 07:06:16 dawes Exp $
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h
new file mode 100644
index 000000000..34047d90d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h
@@ -0,0 +1,248 @@
+/**********************************************************************
+Copyright 1998, 1999 by Precision Insight, Inc., Cedar Park, Texas.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Precision Insight not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission. Precision Insight
+and its suppliers make no representations about the suitability of this
+software for any purpose. It is provided "as is" without express or
+implied warranty.
+
+PRECISION INSIGHT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+**********************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo.h,v 1.4 1999/06/27 14:08:08 dawes Exp $ */
+
+/*
+ * The original Precision Insight driver for
+ * XFree86 v.3.3 has been sponsored by Red Hat.
+ *
+ * Authors:
+ * Jens Owen (jens@precisioninsight.com)
+ * Kevin E. Martin (kevin@precisioninsight.com)
+ *
+ * Port to Xfree86 v.4.0
+ * 1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE)
+ */
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.h"
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xaa.h"
+#include "xaalocal.h" /* XAA internals as we replace some of XAA */
+#include "xf86Cursor.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+#include "xf86i2c.h"
+
+/*
+ * Driver data structures.
+ */
+#include "neo_reg.h"
+#include "neo_macros.h"
+
+/* Supported chipsets */
+typedef enum {
+ NM2070,
+ NM2090,
+ NM2093,
+ NM2097,
+ NM2160,
+ NM2200
+} NEOType;
+
+/* function prototypes */
+
+/* in neo_2070.c */
+extern Bool Neo2070AccelInit(ScreenPtr pScreen);
+
+/* in neo_2090.c */
+extern Bool Neo2090AccelInit(ScreenPtr pScreen);
+
+/* in neo_2097.c */
+extern Bool Neo2097AccelInit(ScreenPtr pScreen);
+
+/* in neo_2200.c */
+extern Bool Neo2200AccelInit(ScreenPtr pScreen);
+
+/* in neo_cursor.c */
+extern Bool NeoCursorInit(ScreenPtr pScrn);
+extern void NeoShowCursor(ScrnInfoPtr pScrn);
+extern void NeoHideCursor(ScrnInfoPtr pScrn);
+
+/* in neo_bank.c */
+int NEOSetReadWrite(ScreenPtr pScreen, int bank);
+int NEOSetWrite(ScreenPtr pScreen, int bank);
+int NEOSetRead(ScreenPtr pScreen, int bank);
+
+/* in neo_i2c.c */
+extern Bool neo_I2CInit(ScrnInfoPtr pScrn);
+
+/* shadow regs */
+
+#define NEO_EXT_CR_MAX 0x85
+#define NEO_EXT_GR_MAX 0xC7
+typedef struct {
+ unsigned char CR[NEO_EXT_CR_MAX+1];
+ unsigned char GR[NEO_EXT_GR_MAX+1];
+} regSaveRec, *regSavePtr;
+
+/* registers */
+typedef struct {
+ unsigned char GeneralLockReg;
+ unsigned char ExtCRTDispAddr;
+ unsigned char ExtCRTOffset;
+ unsigned char SysIfaceCntl1;
+ unsigned char SysIfaceCntl2;
+ unsigned char ExtColorModeSelect;
+ unsigned char SingleAddrPage;
+ unsigned char DualAddrPage;
+ unsigned char PanelDispCntlReg1;
+ unsigned char PanelDispCntlReg2;
+ unsigned char PanelDispCntlReg3;
+ unsigned char PanelVertCenterReg1;
+ unsigned char PanelVertCenterReg2;
+ unsigned char PanelVertCenterReg3;
+ unsigned char PanelVertCenterReg4;
+ unsigned char PanelVertCenterReg5;
+ unsigned char PanelHorizCenterReg1;
+ unsigned char PanelHorizCenterReg2;
+ unsigned char PanelHorizCenterReg3;
+ unsigned char PanelHorizCenterReg4;
+ unsigned char PanelHorizCenterReg5;
+ Bool ProgramVCLK;
+ unsigned char VCLK3NumeratorLow;
+ unsigned char VCLK3NumeratorHigh;
+ unsigned char VCLK3Denominator;
+ unsigned char VerticalExt;
+ regSavePtr reg;
+} NeoRegRec, *NeoRegPtr;
+
+typedef struct {
+ /* Hardware cursor address */
+ unsigned int CursorAddress;
+ Bool UseHWCursor;
+ /* Boundaries of the pixmap cache */
+ unsigned int cacheStart;
+ unsigned int cacheEnd;
+ /* Blitter */
+ unsigned int tmpBltCntlFlags;
+ unsigned int BltCntlFlags;
+ unsigned int BltModeFlags;
+ unsigned int ColorShiftAmt;
+ unsigned int Pitch;
+ unsigned int PixelWidth;
+ unsigned int PlaneMask;
+} NEOACLRec, *NEOACLPtr;
+#define NEOACLPTR(p) &((NEOPtr)((p)->driverPrivate))->Accel
+
+/* globals */
+typedef struct neoRec
+{
+ int NeoChipset;
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ EntityInfoPtr pEnt;
+ XAAInfoRecPtr AccelInfoRec;
+ NEOACLRec Accel;
+ unsigned int NeoMMIOAddr;
+ unsigned int NeoLinearAddr;
+ unsigned char* NeoMMIOBase;
+ unsigned char* NeoFbBase;
+ long NeoFbMapSize;
+ unsigned int vgaIOBase;
+ /* ??? */
+ int NeoFifoCount;
+ /* cursor */
+ int NeoCursorMem;
+ Bool NeoHWCursorShown;
+ Bool NeoHWCursorInitialized;
+ xf86CursorInfoPtr CursorInfo;
+ int NeoCursorOffset;
+ int NeoCursorPrevX;
+ int NeoCursorPrevY;
+ unsigned char *NeoCursorImage;
+ /* Panels size */
+ int NeoPanelWidth;
+ int NeoPanelHeight;
+ /* options */
+ OptionInfoPtr Options;
+ Bool noLinear;
+ Bool noAccel;
+ Bool swCursor;
+ Bool noMMIO;
+ Bool internDisp;
+ Bool externDisp;
+ Bool noLcdStretch;
+ Bool shadowFB;
+ Bool lcdCenter;
+ Bool onPciBurst;
+ Bool progLcdRegs;
+ Bool progLcdStretch;
+ Bool progLcdStrechOpt;
+ Bool overrideValidate;
+ /* registers */
+ NeoRegRec NeoModeReg;
+ NeoRegRec NeoSavedReg;
+ /* proc pointer */
+ CloseScreenProcPtr CloseScreen;
+ I2CBusPtr I2C;
+ unsigned char * ShadowPtr;
+ int ShadowPitch;
+} NEORec, *NEOPtr;
+
+/* The privates of the NEO driver */
+#define NEOPTR(p) ((NEOPtr)((p)->driverPrivate))
+
+/* I/O register offsets */
+#define GRAX 0x3CE
+
+/* vga IO functions */
+#define VGArCR(index) hwp->readCrtc(hwp,index)
+#define VGAwCR(index,val) hwp->writeCrtc(hwp,index,val)
+#define VGArGR(index) hwp->readGr(hwp,index)
+#define VGAwGR(index,val) hwp->writeGr(hwp,index,val)
+
+/* memory mapped register access macros */
+#define INREG8(addr) *(volatile CARD8 *)(nPtr->NeoMMIOBase + (addr))
+#define INREG16(addr) *(volatile CARD16 *)(nPtr->NeoMMIOBase + (addr))
+#define INREG(addr) *(volatile CARD32 *)(nPtr->NeoMMIOBase + (addr))
+#define OUTREG8(addr, val) *(volatile CARD8 *)(nPtr->NeoMMIOBase + (addr)) = (val)
+#define OUTREG16(addr, val) *(volatile CARD16 *)(nPtr->NeoMMIOBase + (addr)) = (val)
+#define OUTREG(addr, val) *(volatile CARD32 *)(nPtr->NeoMMIOBase + (addr)) = (val)
+
+/* This swizzle macro is to support the manipulation of cursor masks when
+ * the sprite moves off the left edge of the display. This code is
+ * platform specific, and is known to work with 32bit little endian machines
+ */
+#define SWIZZLE32(__b) { \
+ ((unsigned char *)&__b)[0] = byte_reversed[((unsigned char *)&__b)[0]]; \
+ ((unsigned char *)&__b)[1] = byte_reversed[((unsigned char *)&__b)[1]]; \
+ ((unsigned char *)&__b)[2] = byte_reversed[((unsigned char *)&__b)[2]]; \
+ ((unsigned char *)&__b)[3] = byte_reversed[((unsigned char *)&__b)[3]]; \
+}
+
+#define PROBED_NM2070 0x01
+#define PROBED_NM2090 0x42
+#define PROBED_NM2093 0x43
+#define PROBED_NM2097 0x83
+#define PROBED_NM2160 0x44
+#define PROBED_NM2200 0x45
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c
new file mode 100644
index 000000000..47584537c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c
@@ -0,0 +1,276 @@
+/**********************************************************************
+Copyright 1998, 1999 by Precision Insight, Inc., Cedar Park, Texas.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Precision Insight not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission. Precision Insight
+and its suppliers make no representations about the suitability of this
+software for any purpose. It is provided "as is" without express or
+implied warranty.
+
+PRECISION INSIGHT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+**********************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2070.c,v 1.2 1999/06/27 14:08:08 dawes Exp $ */
+
+/*
+ * The original Precision Insight driver for
+ * XFree86 v.3.3 has been sponsored by Red Hat.
+ *
+ * Authors:
+ * Jens Owen (jens@precisioninsight.com)
+ * Kevin E. Martin (kevin@precisioninsight.com)
+ *
+ * Port to Xfree86 v.4.0
+ * 1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE)
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+/* Drivers that use XAA need this */
+#include "xf86fbman.h"
+
+#include "miline.h"
+
+#include "neo.h"
+#include "neo_reg.h"
+#include "neo_macros.h"
+
+/* Memory Mapped I/O for BitBlt */
+#define NEO2070_BLTSTAT 0x00
+#define NEO2070_BLTCNTL 0x04
+#define NEO2070_XPCOLOR 0x08
+#define NEO2070_FGCOLOR 0x0c
+#define NEO2070_BGCOLOR 0x10
+#define NEO2070_PLANEMASK 0x14
+#define NEO2070_XYEXT 0x18
+#define NEO2070_SRCPITCH 0x1c
+#define NEO2070_SRCBITOFF 0x20
+#define NEO2070_SRCSTART 0x24
+#define NEO2070_DSTPITCH 0x28
+#define NEO2070_DSTBITOFF 0x2c
+#define NEO2070_DSTSTART 0x30
+
+static unsigned int neo2070Rop[16] = {
+ 0x000000, /* 0x0000 - GXclear */
+ 0x080000, /* 0x1000 - GXand */
+ 0x040000, /* 0x0100 - GXandReverse */
+ 0x0c0000, /* 0x1100 - GXcopy */
+ 0x020000, /* 0x0010 - GXandInvert */
+ 0x0a0000, /* 0x1010 - GXnoop */
+ 0x060000, /* 0x0110 - GXxor */
+ 0x0e0000, /* 0x1110 - GXor */
+ 0x010000, /* 0x0001 - GXnor */
+ 0x090000, /* 0x1001 - GXequiv */
+ 0x050000, /* 0x0101 - GXinvert */
+ 0x0d0000, /* 0x1101 - GXorReverse */
+ 0x030000, /* 0x0011 - GXcopyInvert */
+ 0x0b0000, /* 0x1011 - GXorInverted */
+ 0x070000, /* 0x0111 - GXnand */
+ 0x0f0000 /* 0x1111 - GXset */
+};
+
+static void Neo2070Sync(ScrnInfoPtr pScrn);
+static void Neo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
+ int ydir, int rop,
+ unsigned int planemask,
+ int trans_color);
+static void Neo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX,
+ int srcY, int dstX, int dstY,
+ int w, int h);
+static void Neo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+static void Neo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h);
+
+Bool
+Neo2070AccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+ BoxRec AvailFBArea;
+
+ nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if(!infoPtr) return FALSE;
+
+ /*
+ * Set up the main acceleration flags.
+ */
+ infoPtr->Flags |= LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
+ if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags = PIXMAP_CACHE;
+#if 0
+ infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES;
+#endif
+ /* sync */
+ infoPtr->Sync = Neo2070Sync;
+
+ /* screen to screen copy */
+ infoPtr->ScreenToScreenCopyFlags = (NO_TRANSPARENCY | GXCOPY_ONLY);
+ infoPtr->SetupForScreenToScreenCopy =
+ Neo2070SetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy =
+ Neo2070SubsequentScreenToScreenCopy;
+
+ /* solid filled rectangles */
+ infoPtr->SolidFillFlags = GXCOPY_ONLY;
+ infoPtr->SetupForSolidFill =
+ Neo2070SetupForSolidFillRect;
+ infoPtr->SubsequentSolidFillRect =
+ Neo2070SubsequentSolidFillRect;
+
+ /*
+ * Setup some global variables
+ */
+
+ /* Initialize for 8bpp or 15/16bpp support accellerated */
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ nAcl->BltCntlFlags = NEO_BC1_DEPTH8;
+ nAcl->ColorShiftAmt = 8;
+ nAcl->PixelWidth = 1;
+ nAcl->PlaneMask = 0xff;
+ break;
+ case 15:
+ case 16:
+ nAcl->BltCntlFlags = NEO_BC1_DEPTH16;
+ nAcl->ColorShiftAmt = 0;
+ nAcl->PixelWidth = 2;
+ nAcl->PlaneMask = 0xffff;
+ break;
+ case 24: /* not supported, but check anyway */
+ default:
+ return FALSE;
+ }
+
+ /* Initialize for widths */
+ nAcl->Pitch = pScrn->displayWidth * nAcl->PixelWidth;
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = nAcl->cacheEnd /
+ (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ return(XAAInit(pScreen, infoPtr));
+
+}
+
+static void
+Neo2070Sync(ScrnInfoPtr pScrn)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ WAIT_ENGINE_IDLE();
+}
+
+static void
+Neo2070SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop,
+ unsigned int planemask,
+ int trans_color)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ /* set blt control */
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags);
+ OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt));
+ OUTREG(NEO2070_SRCPITCH, nAcl->Pitch);
+ OUTREG(NEO2070_DSTPITCH, nAcl->Pitch);
+ OUTREG(NEO2070_SRCBITOFF, 0);
+ OUTREG(NEO2070_DSTBITOFF, 0);
+}
+
+static void
+Neo2070SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int srcX, int srcY,
+ int dstX, int dstY,
+ int w, int h)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) {
+ /* start with upper left corner */
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEO2070_BLTCNTL, nAcl->tmpBltCntlFlags);
+ OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff));
+ OUTREG(NEO2070_SRCSTART,
+ (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth));
+ OUTREG(NEO2070_DSTSTART,
+ (dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth));
+ }
+ else {
+ /* start with lower right corner */
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEO2070_BLTCNTL, (nAcl->tmpBltCntlFlags | NEO_BC0_X_DEC
+ | NEO_BC0_DST_Y_DEC
+ | NEO_BC0_SRC_Y_DEC));
+ OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff));
+ OUTREG(NEO2070_SRCSTART,
+ ((srcY+h-1) * nAcl->Pitch) + ((srcX+w-1) * nAcl->PixelWidth));
+ OUTREG(NEO2070_DSTSTART,
+ ((dstY+h-1) * nAcl->Pitch) + ((dstX+w-1) * nAcl->PixelWidth));
+ }
+}
+
+
+static void
+Neo2070SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ planemask &= nAcl->PlaneMask;
+ if (!rop) color=0;
+
+ WAIT_ENGINE_IDLE();
+
+ OUTREG(NEO2070_BLTCNTL, nAcl->BltCntlFlags |
+ NEO_BC0_SRC_IS_FG | neo2070Rop[3]);
+ OUTREG(NEO2070_PLANEMASK, planemask |= (planemask << nAcl->ColorShiftAmt));
+ if (pScrn->bitsPerPixel == 8)
+ OUTREG(NEO2070_FGCOLOR, color |= (color << 8));
+ else
+ /* swap bytes in color */
+ OUTREG(NEO2070_FGCOLOR, ((color&0xff00) >> 8) | (color << 8));
+ OUTREG(NEO2070_SRCPITCH, nAcl->Pitch);
+ OUTREG(NEO2070_DSTPITCH, nAcl->Pitch);
+ OUTREG(NEO2070_SRCBITOFF, 0);
+ OUTREG(NEO2070_DSTBITOFF, 0);
+}
+
+
+static void
+Neo2070SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEO2070_XYEXT, ((h-1)<<16) | ((w-1) & 0xffff));
+ OUTREG(NEO2070_DSTSTART, (y * nAcl->Pitch) + (x * nAcl->PixelWidth));
+}
+
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c
new file mode 100644
index 000000000..d9f311504
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c
@@ -0,0 +1,343 @@
+/**********************************************************************
+Copyright 1998, 1999 by Precision Insight, Inc., Cedar Park, Texas.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Precision Insight not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission. Precision Insight
+and its suppliers make no representations about the suitability of this
+software for any purpose. It is provided "as is" without express or
+implied warranty.
+
+PRECISION INSIGHT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+**********************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2090.c,v 1.2 1999/06/27 14:08:08 dawes Exp $ */
+
+/*
+ * The original Precision Insight driver for
+ * XFree86 v.3.3 has been sponsored by Red Hat.
+ *
+ * Authors:
+ * Jens Owen (jens@precisioninsight.com)
+ * Kevin E. Martin (kevin@precisioninsight.com)
+ *
+ * Port to Xfree86 v.4.0
+ * 1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE)
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+/* Drivers that use XAA need this */
+#include "xf86fbman.h"
+
+#include "miline.h"
+
+#include "neo.h"
+#include "neo_reg.h"
+#include "neo_macros.h"
+
+static unsigned int neo2090Rop[16] = {
+ 0x000000, /* 0x0000 - GXclear */
+ 0x080000, /* 0x1000 - GXand */
+ 0x040000, /* 0x0100 - GXandReverse */
+ 0x0c0000, /* 0x1100 - GXcopy */
+ 0x020000, /* 0x0010 - GXandInvert */
+ 0x0a0000, /* 0x1010 - GXnoop */
+ 0x060000, /* 0x0110 - GXxor */
+ 0x0e0000, /* 0x1110 - GXor */
+ 0x010000, /* 0x0001 - GXnor */
+ 0x090000, /* 0x1001 - GXequiv */
+ 0x050000, /* 0x0101 - GXinvert */
+ 0x0d0000, /* 0x1101 - GXorReverse */
+ 0x030000, /* 0x0011 - GXcopyInvert */
+ 0x0b0000, /* 0x1011 - GXorInverted */
+ 0x070000, /* 0x0111 - GXnand */
+ 0x0f0000 /* 0x1111 - GXset */
+};
+
+static void Neo2090Sync(ScrnInfoPtr pScrn);
+static void Neo2090SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
+ int ydir, int rop,
+ unsigned int planemask,
+ int trans_color);
+static void Neo2090SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX,
+ int srcY, int dstX, int dstY,
+ int w, int h);
+static void Neo2090SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+static void Neo2090SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h);
+#ifdef colorexpandfill
+static void Neo2090SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask);
+static void Neo2093SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h,
+ int skipleft);
+#endif
+
+Bool
+Neo2090AccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+ BoxRec AvailFBArea;
+
+ nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if(!infoPtr) return FALSE;
+
+ /*
+ * Set up the main acceleration flags.
+ */
+ infoPtr->Flags |= LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
+ if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags = PIXMAP_CACHE;
+#if 0
+ infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES;
+#endif
+ /* sync */
+ infoPtr->Sync = Neo2090Sync;
+
+ /* screen to screen copy */
+ infoPtr->ScreenToScreenCopyFlags = (NO_TRANSPARENCY | NO_PLANEMASK);
+ infoPtr->SetupForScreenToScreenCopy =
+ Neo2090SetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy =
+ Neo2090SubsequentScreenToScreenCopy;
+
+ /* solid filled rectangles */
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill =
+ Neo2090SetupForSolidFillRect;
+ infoPtr->SubsequentSolidFillRect =
+ Neo2090SubsequentSolidFillRect;
+#ifdef colorexpandfill
+ /* We need byte scanline padding before we can use this
+ * or does anyone know how to switch the chip to dword
+ * padding? if we could do right edge clipping this would
+ * help also. Left edge clipping cannot be used since it
+ * allows only clipping of up to 8 pixels :-((
+ */ /*§§§*/
+ if (NeoChipset == PCI_CHIP_NM2093) {
+ /* cpu to screen color expansion */
+ infoPtr->CPUToScreenColorExpandFillFlags = ( NO_PLANEMASK |
+ SCANLINE_PAD_BYTE |
+ CPU_TRANSFER_PAD_DWORD |
+ BIT_ORDER_IN_BYTE_MSBFIRST );
+ infoPtr->ColorExpandBase =
+ (unsigned char *)(nPtr->NeoMMIOBase + 0x100000);
+ infoPtr->ColorExpandRange = 0x100000;
+
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ Neo2093SetupForCPUToScreenColorExpandFill;
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ Neo2093SubsequentCPUToScreenColorExpandFill;
+ }
+#endif
+ /*
+ * Setup some global variables
+ */
+ nAcl->ColorShiftAmt = 0;
+
+ /* Initialize for 8bpp or 15/16bpp support accellerated */
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ nAcl->BltCntlFlags = NEO_BC1_DEPTH8;
+ nAcl->ColorShiftAmt = 8;
+ break;
+ case 15:
+ case 16:
+ nAcl->BltCntlFlags = NEO_BC1_DEPTH16;
+ nAcl->ColorShiftAmt = 0;
+ break;
+ case 24:
+ default:
+ return FALSE;
+ }
+
+ /* Initialize for widths */
+ switch (pScrn->displayWidth) {
+ case 640:
+ nAcl->BltCntlFlags |= NEO_BC1_X_640;
+ break;
+ case 800:
+ nAcl->BltCntlFlags |= NEO_BC1_X_800;
+ break;
+ case 1024:
+ nAcl->BltCntlFlags |= NEO_BC1_X_1024;
+ break;
+ default:
+ return FALSE;
+ }
+
+ nAcl->BltCntlFlags |= NEO_BC3_FIFO_EN;
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = nAcl->cacheEnd /
+ (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ return(XAAInit(pScreen, infoPtr));
+
+}
+
+static void
+Neo2090Sync(ScrnInfoPtr pScrn)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+
+ WAIT_ENGINE_IDLE();
+}
+
+static void
+Neo2090SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop,
+ unsigned int planemask,
+ int trans_color)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ nAcl->tmpBltCntlFlags = (nAcl->BltCntlFlags |
+ NEO_BC3_SKIP_MAPPING |
+ NEO_BC3_DST_XY_ADDR |
+ NEO_BC3_SRC_XY_ADDR | neo2090Rop[rop]);
+
+ /* set blt control */
+ WAIT_FIFO(2);
+ OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags);
+}
+
+static void
+Neo2090SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int srcX, int srcY,
+ int dstX, int dstY,
+ int w, int h)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) {
+ /* start with upper left corner */
+ WAIT_FIFO(4);
+ OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags);
+ OUTREG(NEOREG_SRCSTARTOFF, (srcY<<16) | (srcX & 0xffff));
+ OUTREG(NEOREG_DSTSTARTOFF, (dstY<<16) | (dstX & 0xffff));
+ OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
+ }
+ else {
+ /* start with lower right corner */
+ WAIT_FIFO(4);
+ OUTREG(NEOREG_BLTCNTL, (nAcl->tmpBltCntlFlags | NEO_BC0_X_DEC
+ | NEO_BC0_DST_Y_DEC
+ | NEO_BC0_SRC_Y_DEC));
+ OUTREG(NEOREG_SRCSTARTOFF, ((srcY+h-1)<<16) | ((srcX+w-1) & 0xffff));
+ OUTREG(NEOREG_DSTSTARTOFF, ((dstY+h-1)<<16) | ((dstX+w-1) & 0xffff));
+ OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
+ }
+}
+
+
+static void
+Neo2090SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ WAIT_FIFO(2);
+
+ /* set blt control */
+ OUTREG(NEOREG_BLTCNTL, nAcl->BltCntlFlags |
+ NEO_BC0_SRC_IS_FG |
+ NEO_BC3_SKIP_MAPPING |
+ NEO_BC3_DST_XY_ADDR |
+ NEO_BC3_SRC_XY_ADDR | neo2090Rop[rop]);
+
+ /* set foreground color */
+ OUTREG(NEOREG_FGCOLOR, color |= (color << nAcl->ColorShiftAmt));
+}
+
+
+static void
+Neo2090SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+
+ WAIT_FIFO(2);
+ OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff));
+ OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
+
+}
+
+#ifdef colorexpandfill
+static void
+Neo2093SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop,
+ unsigned int planemask)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ if (bg == -1) {
+ /* transparent setup */
+ WAIT_FIFO(2);
+ OUTREG(NEOREG_BLTCNTL, nAcl->BltCntlFlags |
+ NEO_BC0_SYS_TO_VID |
+ NEO_BC0_SRC_MONO |
+ NEO_BC0_SRC_TRANS |
+ NEO_BC3_SKIP_MAPPING |
+ NEO_BC3_DST_XY_ADDR | neo2090Rop[rop]);
+
+ OUTREG(NEOREG_FGCOLOR, fg |= (fg << nAcl->ColorShiftAmt));
+ }
+ else {
+ /* opaque setup */
+ WAIT_FIFO(3);
+ OUTREG(NEOREG_BLTCNTL, nAcl->BltCntlFlags |
+ NEO_BC0_SYS_TO_VID |
+ NEO_BC0_SRC_MONO |
+ NEO_BC3_SKIP_MAPPING |
+ NEO_BC3_DST_XY_ADDR | neo2090Rop[rop]);
+
+ OUTREG(NEOREG_FGCOLOR, fg |= (fg << nAcl->ColorShiftAmt));
+ OUTREG(NEOREG_BGCOLOR, bg |= (bg << nAcl->ColorShiftAmt));
+ }
+}
+
+static void
+Neo2093SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h,
+ int skipleft)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+
+ WAIT_FIFO(4);
+ OUTREG(NEOREG_SRCBITOFF, skipleft);
+ OUTREG(NEOREG_SRCSTARTOFF, 0);
+ OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff));
+ OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
+}
+#endif
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c
new file mode 100644
index 000000000..563e720b5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c
@@ -0,0 +1,430 @@
+/**********************************************************************
+Copyright 1998, 1999 by Precision Insight, Inc., Cedar Park, Texas.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Precision Insight not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission. Precision Insight
+and its suppliers make no representations about the suitability of this
+software for any purpose. It is provided "as is" without express or
+implied warranty.
+
+PRECISION INSIGHT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+**********************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2097.c,v 1.2 1999/06/27 14:08:08 dawes Exp $ */
+
+/*
+ * The original Precision Insight driver for
+ * XFree86 v.3.3 has been sponsored by Red Hat.
+ *
+ * Authors:
+ * Jens Owen (jens@precisioninsight.com)
+ * Kevin E. Martin (kevin@precisioninsight.com)
+ *
+ * Port to Xfree86 v.4.0
+ * 1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE)
+ */
+
+/*
+ * This module supports acceleration for 2097 and 2160.
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+/* Drivers that use XAA need this */
+#include "xf86fbman.h"
+
+#include "miline.h"
+
+#include "neo.h"
+#include "neo_reg.h"
+#include "neo_macros.h"
+
+static void Neo2097Sync(ScrnInfoPtr pScrn);
+static void Neo2097SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
+ int ydir, int rop,
+ unsigned int planemask,
+ int trans_color);
+static void Neo2097SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX,
+ int srcY, int dstX, int dstY,
+ int w, int h);
+static void Neo2097SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+static void Neo2097SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h);
+#ifdef colorexpandfill
+static void Neo2097SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask);
+static void Neo2097SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h,
+ int skipleft);
+#endif
+static void Neo2097SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx,
+ int patterny,
+ int fg, int bg,
+ int rop, unsigned int planemask);
+static void Neo2097SubsequentMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx,
+ int patterny,
+ int x, int y,
+ int w, int h);
+
+
+
+static unsigned int neo2097Rop[16] = {
+ 0x000000, /* 0x0000 - GXclear */
+ 0x080000, /* 0x1000 - GXand */
+ 0x040000, /* 0x0100 - GXandReverse */
+ 0x0c0000, /* 0x1100 - GXcopy */
+ 0x020000, /* 0x0010 - GXandInvert */
+ 0x0a0000, /* 0x1010 - GXnoop */
+ 0x060000, /* 0x0110 - GXxor */
+ 0x0e0000, /* 0x1110 - GXor */
+ 0x010000, /* 0x0001 - GXnor */
+ 0x090000, /* 0x1001 - GXequiv */
+ 0x050000, /* 0x0101 - GXinvert */
+ 0x0d0000, /* 0x1101 - GXorReverse */
+ 0x030000, /* 0x0011 - GXcopyInvert */
+ 0x0b0000, /* 0x1011 - GXorInverted */
+ 0x070000, /* 0x0111 - GXnand */
+ 0x0f0000 /* 0x1111 - GXset */
+};
+
+
+Bool
+Neo2097AccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+ BoxRec AvailFBArea;
+
+ nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if(!infoPtr) return FALSE;
+
+ /*
+ * Set up the main acceleration flags.
+ */
+ infoPtr->Flags |= LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
+ if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags = PIXMAP_CACHE;
+#if 0
+ infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES;
+#endif
+ /* sync */
+ infoPtr->Sync = Neo2097Sync;
+
+ /* screen to screen copy */
+ infoPtr->ScreenToScreenCopyFlags = (NO_TRANSPARENCY | NO_PLANEMASK);
+ infoPtr->SetupForScreenToScreenCopy =
+ Neo2097SetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy =
+ Neo2097SubsequentScreenToScreenCopy;
+
+ /* solid filled rectangles */
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill =
+ Neo2097SetupForSolidFillRect;
+ infoPtr->SubsequentSolidFillRect =
+ Neo2097SubsequentSolidFillRect;
+
+#ifdef colorexpandfill
+ /* We need byte scanline padding before we can use this
+ * or does anyone know how to switch the chip to dword
+ * padding? if we could do right edge clipping this would
+ * help also. Left edge clipping cannot be used since it
+ * allows only clipping of up to 8 pixels :-((
+ */ /*§§§*/
+
+ /* cpu to screen color expansion */
+ infoPtr->CPUToScreenColorExpandFillFlags = ( NO_PLANEMASK |
+ CPU_TRANSFER_PAD_DWORD |
+ BIT_ORDER_IN_BYTE_MSBFIRST );
+ infoPtr->ColorExpandBase =
+ (unsigned char *)(nPtr->NeoMMIOBase + 0x100000);
+ infoPtr->ColorExpandRange = 0x100000;
+
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ Neo2097SetupForCPUToScreenColorExpandFill;
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ Neo2097SubsequentCPUToScreenColorExpandFill;
+#endif
+ /* 8x8 pattern fills */
+ infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK
+ | HARDWARE_PATTERN_PROGRAMMED_ORIGIN
+ |BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ infoPtr->SetupForMono8x8PatternFill =
+ Neo2097SetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ Neo2097SubsequentMono8x8PatternFill;
+
+ /*
+ * Setup some global variables
+ */
+ nAcl->ColorShiftAmt = 0;
+
+ /* Initialize for 8bpp or 15/16bpp support accellerated */
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ nAcl->BltCntlFlags = NEO_BC1_DEPTH8;
+ nAcl->ColorShiftAmt = 8;
+ break;
+ case 15:
+ case 16:
+ nAcl->BltCntlFlags = NEO_BC1_DEPTH16;
+ nAcl->ColorShiftAmt = 0;
+ break;
+ case 24:
+ default:
+ return FALSE;
+ }
+
+ /* Initialize for widths */
+ switch (pScrn->displayWidth) {
+ case 640:
+ nAcl->BltCntlFlags |= NEO_BC1_X_640;
+ break;
+ case 800:
+ nAcl->BltCntlFlags |= NEO_BC1_X_800;
+ break;
+ case 1024:
+ nAcl->BltCntlFlags |= NEO_BC1_X_1024;
+ break;
+ default:
+ return FALSE;
+ }
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = nAcl->cacheEnd /
+ (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ return(XAAInit(pScreen, infoPtr));
+
+}
+
+static void
+Neo2097Sync(ScrnInfoPtr pScrn)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+
+ WAIT_ENGINE_IDLE();
+}
+
+static void
+Neo2097SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop,
+ unsigned int planemask,
+ int trans_color)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ nAcl->tmpBltCntlFlags = (nAcl->BltCntlFlags |
+ NEO_BC3_SKIP_MAPPING |
+ NEO_BC3_DST_XY_ADDR |
+ NEO_BC3_SRC_XY_ADDR | neo2097Rop[rop]);
+
+ /* set blt control */
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEOREG_BLTCNTL, nAcl->BltCntlFlags);
+}
+
+static void
+Neo2097SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int srcX, int srcY,
+ int dstX, int dstY,
+ int w, int h)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) {
+ /* start with upper left corner */
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags);
+ OUTREG(NEOREG_SRCSTARTOFF, (srcY<<16) | (srcX & 0xffff));
+ OUTREG(NEOREG_DSTSTARTOFF, (dstY<<16) | (dstX & 0xffff));
+ OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
+ }
+ else {
+ /* start with lower right corner */
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEOREG_BLTCNTL, (nAcl->tmpBltCntlFlags | NEO_BC0_X_DEC
+ | NEO_BC0_DST_Y_DEC
+ | NEO_BC0_SRC_Y_DEC));
+ OUTREG(NEOREG_SRCSTARTOFF, ((srcY+h-1)<<16) | ((srcX+w-1) & 0xffff));
+ OUTREG(NEOREG_DSTSTARTOFF, ((dstY+h-1)<<16) | ((dstX+w-1) & 0xffff));
+ OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
+ }
+}
+
+
+static void
+Neo2097SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ WAIT_ENGINE_IDLE();
+
+ /* set blt control */
+ OUTREG(NEOREG_BLTCNTL, nAcl->BltCntlFlags |
+ NEO_BC0_SRC_IS_FG |
+ NEO_BC3_SKIP_MAPPING |
+ NEO_BC3_DST_XY_ADDR |
+ NEO_BC3_SRC_XY_ADDR | neo2097Rop[rop]);
+
+ /* set foreground color */
+ OUTREG(NEOREG_FGCOLOR, color |= (color << nAcl->ColorShiftAmt));
+}
+
+
+static void
+Neo2097SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff));
+ OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
+}
+
+
+#ifdef colorexpandfill
+static void
+Neo2097SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop,
+ unsigned int planemask)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ if (bg == -1) {
+ /* transparent setup */
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEOREG_BLTCNTL, nAcl->BltCntlFlags |
+ NEO_BC0_SYS_TO_VID |
+ NEO_BC0_SRC_MONO |
+ NEO_BC0_SRC_TRANS |
+ NEO_BC3_SKIP_MAPPING |
+ NEO_BC3_DST_XY_ADDR | neo2097Rop[rop]);
+
+ OUTREG(NEOREG_FGCOLOR, fg |= (fg << nAcl->ColorShiftAmt));
+ }
+ else {
+ /* opaque setup */
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEOREG_BLTCNTL, nAcl->BltCntlFlags |
+ NEO_BC0_SYS_TO_VID |
+ NEO_BC0_SRC_MONO |
+ NEO_BC3_SKIP_MAPPING |
+ NEO_BC3_DST_XY_ADDR | neo2097Rop[rop]);
+
+ OUTREG(NEOREG_FGCOLOR, fg |= (fg << nAcl->ColorShiftAmt));
+ OUTREG(NEOREG_BGCOLOR, bg |= (bg << nAcl->ColorShiftAmt));
+ }
+}
+#endif
+#ifdef colorexpandfill
+static void
+Neo2097SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h,
+ int skipleft)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEOREG_SRCSTARTOFF, 0);
+ OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff));
+ OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
+}
+#endif
+
+static void
+Neo2097SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx,
+ int patterny,
+ int fg, int bg,
+ int rop, unsigned int planemask)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ if (bg == -1) {
+ /* transparent setup */
+ nAcl->tmpBltCntlFlags = ( nAcl->BltCntlFlags |
+ NEO_BC0_SRC_MONO |
+ NEO_BC0_FILL_PAT |
+ NEO_BC0_SRC_TRANS |
+ NEO_BC3_SKIP_MAPPING |
+ NEO_BC3_DST_XY_ADDR | neo2097Rop[rop]);
+
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEOREG_FGCOLOR, fg |= (fg << nAcl->ColorShiftAmt));
+ OUTREG(NEOREG_SRCSTARTOFF,
+ (patterny*pScrn->displayWidth*pScrn->bitsPerPixel + patternx)
+ >> 3);
+ }
+ else {
+ /* opaque setup */
+ nAcl->tmpBltCntlFlags = ( nAcl->BltCntlFlags |
+ NEO_BC0_SRC_MONO |
+ NEO_BC0_FILL_PAT |
+ NEO_BC3_SKIP_MAPPING |
+ NEO_BC3_DST_XY_ADDR | neo2097Rop[rop]);
+
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEOREG_FGCOLOR, fg |= (fg << nAcl->ColorShiftAmt));
+ OUTREG(NEOREG_BGCOLOR, bg |= (bg << nAcl->ColorShiftAmt));
+ OUTREG(NEOREG_SRCSTARTOFF,
+ (patterny*pScrn->displayWidth*pScrn->bitsPerPixel + patternx)
+ >> 3);
+ }
+}
+
+
+static void
+Neo2097SubsequentMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx,
+ int patterny,
+ int x, int y,
+ int w, int h)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ patterny &= 0x7;
+
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags | (patterny << 20));
+ OUTREG(NEOREG_SRCBITOFF, patternx);
+ OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff));
+ OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
+}
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c
new file mode 100644
index 000000000..9df558dc1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c
@@ -0,0 +1,455 @@
+/**********************************************************************
+Copyright 1998, 1999 by Precision Insight, Inc., Cedar Park, Texas.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Precision Insight not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission. Precision Insight
+and its suppliers make no representations about the suitability of this
+software for any purpose. It is provided "as is" without express or
+implied warranty.
+
+PRECISION INSIGHT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+**********************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_2200.c,v 1.2 1999/06/27 14:08:09 dawes Exp $ */
+
+/*
+ * The original Precision Insight driver for
+ * XFree86 v.3.3 has been sponsored by Red Hat.
+ *
+ * Authors:
+ * Jens Owen (jens@precisioninsight.com)
+ * Kevin E. Martin (kevin@precisioninsight.com)
+ *
+ * Port to Xfree86 v.4.0
+ * 1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE)
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+/* Drivers that use XAA need this */
+#include "xf86fbman.h"
+
+#include "miline.h"
+
+#include "neo.h"
+#include "neo_reg.h"
+#include "neo_macros.h"
+
+static void Neo2200Sync(ScrnInfoPtr pScrn);
+static void Neo2200SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
+ int ydir, int rop,
+ unsigned int planemask,
+ int trans_color);
+static void Neo2200SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX,
+ int srcY, int dstX, int dstY,
+ int w, int h);
+static void Neo2200SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+static void Neo2200SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h);
+#ifdef colorexpandfill
+static void Neo2200SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask);
+static void Neo2200SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h,
+ int skipleft);
+#endif
+static void Neo2200SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx,
+ int patterny,
+ int bg,
+ int fg,
+ int rop,
+ unsigned int planemask);
+static void Neo2200SubsequentMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx,
+ int patterny,
+ int x, int y,
+ int w, int h);
+
+
+
+static unsigned int neo2200Rop[16] = {
+ 0x000000, /* 0x0000 - GXclear */
+ 0x080000, /* 0x1000 - GXand */
+ 0x040000, /* 0x0100 - GXandReverse */
+ 0x0c0000, /* 0x1100 - GXcopy */
+ 0x020000, /* 0x0010 - GXandInvert */
+ 0x0a0000, /* 0x1010 - GXnoop */
+ 0x060000, /* 0x0110 - GXxor */
+ 0x0e0000, /* 0x1110 - GXor */
+ 0x010000, /* 0x0001 - GXnor */
+ 0x090000, /* 0x1001 - GXequiv */
+ 0x050000, /* 0x0101 - GXinvert */
+ 0x0d0000, /* 0x1101 - GXorReverse */
+ 0x030000, /* 0x0011 - GXcopyInvert */
+ 0x0b0000, /* 0x1011 - GXorInverted */
+ 0x070000, /* 0x0111 - GXnand */
+ 0x0f0000 /* 0x1111 - GXset */
+};
+
+
+Bool
+Neo2200AccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+ BoxRec AvailFBArea;
+
+ nPtr->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if(!infoPtr) return FALSE;
+
+ /*
+ * Set up the main acceleration flags.
+ */
+ infoPtr->Flags |= LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
+ if(nAcl->cacheEnd > nAcl->cacheStart) infoPtr->Flags = PIXMAP_CACHE;
+#if 0
+ infoPtr->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES;
+#endif
+ /* sync */
+ infoPtr->Sync = Neo2200Sync;
+
+ /* screen to screen copy */
+ infoPtr->ScreenToScreenCopyFlags = (NO_TRANSPARENCY | NO_PLANEMASK);
+ infoPtr->SetupForScreenToScreenCopy =
+ Neo2200SetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy =
+ Neo2200SubsequentScreenToScreenCopy;
+
+ /* solid filled rectangles */
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill =
+ Neo2200SetupForSolidFillRect;
+ infoPtr->SubsequentSolidFillRect =
+ Neo2200SubsequentSolidFillRect;
+
+#ifdef colorexpandfill
+ /* We need byte scanline padding before we can use this
+ * or does anyone know how to switch the chip to dword
+ * padding? if we could do right edge clipping this would
+ * help also. Left edge clipping cannot be used since it
+ * allows only clipping of up to 8 pixels :-((
+ */ /*§§§*/
+
+ /* cpu to screen color expansion */
+ infoPtr->CPUToScreenColorExpandFillFlags = ( NO_PLANEMASK |
+ /* SCANLINE_PAD_BYTE | */
+ CPU_TRANSFER_PAD_DWORD |
+ BIT_ORDER_IN_BYTE_MSBFIRST );
+ infoPtr->ColorExpandBase =
+ (unsigned char *)(nPtr->NeoMMIOBase + 0x100000);
+ infoPtr->ColorExpandRange = 0x100000;
+
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ Neo2200SetupForCPUToScreenColorExpandFill;
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ Neo2200SubsequentCPUToScreenColorExpandFill;
+#endif
+ /* 8x8 pattern fills */
+ infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK
+ | HARDWARE_PATTERN_PROGRAMMED_ORIGIN
+ |BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ infoPtr->SetupForMono8x8PatternFill =
+ Neo2200SetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ Neo2200SubsequentMono8x8PatternFill;
+
+ /*
+ * Setup some global variables
+ */
+ nAcl->Pitch = pScrn->displayWidth * nAcl->PixelWidth;
+
+ /* Initialize for 8bpp or 15/16bpp support accellerated */
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ nAcl->BltModeFlags = NEO_MODE1_DEPTH8;
+ nAcl->PixelWidth = 1;
+ break;
+ case 15:
+ case 16:
+ nAcl->BltModeFlags = NEO_MODE1_DEPTH16;
+ nAcl->PixelWidth = 2;
+ break;
+ case 24:
+ default:
+ return FALSE;
+ }
+
+ /* Initialize for widths */
+ switch (pScrn->displayWidth) {
+ case 320:
+ nAcl->BltModeFlags |= NEO_MODE1_X_320;
+ break;
+ case 640:
+ nAcl->BltModeFlags |= NEO_MODE1_X_640;
+ break;
+ case 800:
+ nAcl->BltModeFlags |= NEO_MODE1_X_800;
+ break;
+ case 1024:
+ nAcl->BltModeFlags |= NEO_MODE1_X_1024;
+ break;
+ case 1152:
+ nAcl->BltModeFlags |= NEO_MODE1_X_1152;
+ break;
+ case 1280:
+ nAcl->BltModeFlags |= NEO_MODE1_X_1280;
+ break;
+ case 1600:
+ nAcl->BltModeFlags |= NEO_MODE1_X_1600;
+ break;
+ default:
+ return FALSE;
+ }
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = nAcl->cacheEnd /
+ (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ return(XAAInit(pScreen, infoPtr));
+
+}
+
+static void
+Neo2200Sync(ScrnInfoPtr pScrn)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+
+ WAIT_ENGINE_IDLE();
+}
+
+static void
+Neo2200SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop,
+ unsigned int planemask,
+ int trans_color)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ nAcl->tmpBltCntlFlags = (NEO_BC3_SKIP_MAPPING | neo2200Rop[rop]);
+
+ /* set blt control */
+ WAIT_ENGINE_IDLE();
+ OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);
+ OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags);
+ OUTREG(NEOREG_PITCH, (nAcl->Pitch<<16)
+ | (nAcl->Pitch & 0xffff));
+}
+
+static void
+Neo2200SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int srcX, int srcY,
+ int dstX, int dstY,
+ int w, int h)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ if ((dstY < srcY) || ((dstY == srcY) && (dstX < srcX))) {
+ /* start with upper left corner */
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags);
+ OUTREG(NEOREG_SRCSTARTOFF,
+ (srcY * nAcl->Pitch) + (srcX * nAcl->PixelWidth));
+ OUTREG(NEOREG_DSTSTARTOFF,
+ (dstY * nAcl->Pitch) + (dstX * nAcl->PixelWidth));
+ OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
+ }
+ else {
+ /* start with lower right corner */
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEOREG_BLTCNTL, (nAcl->tmpBltCntlFlags
+ | NEO_BC0_X_DEC
+ | NEO_BC0_DST_Y_DEC
+ | NEO_BC0_SRC_Y_DEC));
+ OUTREG(NEOREG_SRCSTARTOFF,
+ ((srcY+h-1) * nAcl->Pitch) + ((srcX+w-1)
+ * nAcl->PixelWidth));
+ OUTREG(NEOREG_DSTSTARTOFF,
+ ((dstY+h-1) * nAcl->Pitch) + ((dstX+w-1)
+ * nAcl->PixelWidth));
+ OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
+ }
+}
+
+
+static void
+Neo2200SetupForSolidFillRect(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ WAIT_ENGINE_IDLE();
+
+ /* set blt control */
+ OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);
+ OUTREG(NEOREG_BLTCNTL, NEO_BC0_SRC_IS_FG |
+ NEO_BC3_SKIP_MAPPING |
+ NEO_BC3_DST_XY_ADDR |
+ NEO_BC3_SRC_XY_ADDR | neo2200Rop[rop]);
+
+ /* set foreground color */
+ OUTREG(NEOREG_FGCOLOR, color);
+}
+
+
+static void
+Neo2200SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff));
+ OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
+}
+
+
+#ifdef colorexpandfill
+static void
+Neo2200SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop,
+ unsigned int planemask)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ if (bg == -1) {
+ /* transparent setup */
+ nAcl->tmpBltCntlFlags = ( NEO_BC0_SYS_TO_VID |
+ NEO_BC0_SRC_MONO |
+ NEO_BC0_SRC_TRANS |
+ NEO_BC3_SKIP_MAPPING |
+ NEO_BC3_DST_XY_ADDR |
+ neo2200Rop[rop]);
+
+ WAIT_ENGINE_IDLE();
+ OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);
+ OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags);
+ OUTREG(NEOREG_FGCOLOR, fg);
+ }
+ else {
+ /* opaque setup */
+ nAcl->tmpBltCntlFlags = ( NEO_BC0_SYS_TO_VID |
+ NEO_BC0_SRC_MONO |
+ NEO_BC3_SKIP_MAPPING |
+ NEO_BC3_DST_XY_ADDR |
+ neo2200Rop[rop]);
+
+ WAIT_ENGINE_IDLE();
+ OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);
+ OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags);
+ OUTREG(NEOREG_FGCOLOR, fg);
+ OUTREG(NEOREG_BGCOLOR, bg);
+ }
+}
+
+
+static void
+Neo2200SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h,
+ int skipleft)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags
+ | ((skipleft << 2) & 0x1C));
+ OUTREG(NEOREG_SRCSTARTOFF, 0);
+ OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff));
+ OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
+}
+#endif
+
+static void
+Neo2200SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx,
+ int patterny,
+ int fg, int bg,
+ int rop, unsigned int planemask)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ if (bg == -1) {
+ /* transparent setup */
+ nAcl->tmpBltCntlFlags = ( NEO_BC0_SRC_MONO |
+ NEO_BC0_FILL_PAT |
+ NEO_BC0_SRC_TRANS |
+ NEO_BC3_SKIP_MAPPING |
+ NEO_BC3_DST_XY_ADDR |
+ neo2200Rop[rop]);
+
+ WAIT_ENGINE_IDLE();
+ OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);
+ OUTREG(NEOREG_FGCOLOR, fg);
+ OUTREG(NEOREG_SRCSTARTOFF,
+ (patterny * pScrn->displayWidth * pScrn->bitsPerPixel
+ + patternx) >> 3);
+ }
+ else {
+ /* opaque setup */
+ nAcl->tmpBltCntlFlags = ( NEO_BC0_SRC_MONO |
+ NEO_BC0_FILL_PAT |
+ NEO_BC3_SKIP_MAPPING |
+ NEO_BC3_DST_XY_ADDR |
+ neo2200Rop[rop]);
+
+ WAIT_ENGINE_IDLE();
+ OUTREG16(NEOREG_BLTMODE, nAcl->BltModeFlags);
+ OUTREG(NEOREG_FGCOLOR, fg);
+ OUTREG(NEOREG_BGCOLOR, bg);
+ OUTREG(NEOREG_SRCSTARTOFF,
+ (patterny * pScrn->displayWidth * pScrn->bitsPerPixel
+ + patternx) >> 3);
+ }
+}
+
+
+static void
+Neo2200SubsequentMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx,
+ int patterny,
+ int x, int y,
+ int w, int h)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+
+ patterny &= 0x7;
+
+ WAIT_ENGINE_IDLE();
+ OUTREG(NEOREG_BLTCNTL, nAcl->tmpBltCntlFlags |
+ (patterny << 20) |
+ ((patternx << 10) & 0x1C00));
+ OUTREG(NEOREG_SRCBITOFF, patternx);
+ OUTREG(NEOREG_DSTSTARTOFF, (y<<16) | (x & 0xffff));
+ OUTREG(NEOREG_XYEXT, (h<<16) | (w & 0xffff));
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_bank.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_bank.c
new file mode 100644
index 000000000..c7e1c6237
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_bank.c
@@ -0,0 +1,95 @@
+/**********************************************************************
+Copyright 1998, 1999 by Precision Insight, Inc., Cedar Park, Texas.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Precision Insight not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission. Precision Insight
+and its suppliers make no representations about the suitability of this
+software for any purpose. It is provided "as is" without express or
+implied warranty.
+
+PRECISION INSIGHT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+**********************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_bank.c,v 1.1 1999/04/17 07:06:22 dawes Exp $ */
+
+/*
+ * The original Precision Insight driver for
+ * XFree86 v.3.3 has been sponsored by Red Hat.
+ *
+ * Authors:
+ * Jens Owen (jens@precisioninsight.com)
+ * Kevin E. Martin (kevin@precisioninsight.com)
+ *
+ * Port to Xfree86 v.4.0
+ * 1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE)
+ */
+
+#define PSZ 8
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.h"
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* Driver specific headers */
+#include "neo.h"
+
+int
+NEOSetReadWrite(ScreenPtr pScreen, int bank)
+{
+ unsigned char tmp;
+
+ outb(0x3CE, 0x11);
+ tmp = inb(0x3CF);
+ outw(0x3CE, (( tmp & 0xFC ) << 8 ) | 0x11);
+ outw(0x3CE, ((((bank << 2) & 0xFF) << 8) | 0x15));
+ return 0;
+}
+
+int
+NEOSetWrite(ScreenPtr pScreen, int bank)
+{
+ unsigned char tmp;
+
+ outb(0x3CE, 0x11);
+ tmp = inb(0x3CF);
+ outw(0x3CE, ((( tmp & 0xFC ) | 0x01 ) << 8 ) | 0x11);
+ outw(0x3CE, ((((bank << 2) & 0xFF) << 8) | 0x16));
+ return 0;
+}
+
+
+int
+NEOSetRead(ScreenPtr pScreen, int bank)
+{
+ unsigned char tmp;
+
+ outb(0x3CE, 0x11);
+ tmp = inb(0x3CF);
+ outw(0x3CE, ((( tmp & 0xFC ) | 0x01 ) << 8 ) | 0x11);
+ outw(0x3CE, ((((bank << 2) & 0xFF) << 8) | 0x15));
+ return 0;
+}
+
+
+
+
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c
new file mode 100644
index 000000000..f476fb66e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c
@@ -0,0 +1,267 @@
+/**********************************************************************
+Copyright 1998, 1999 by Precision Insight, Inc., Cedar Park, Texas.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Precision Insight not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission. Precision Insight
+and its suppliers make no representations about the suitability of this
+software for any purpose. It is provided "as is" without express or
+implied warranty.
+
+PRECISION INSIGHT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+**********************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_cursor.c,v 1.2 1999/06/27 14:08:09 dawes Exp $ */
+
+/*
+ * The original Precision Insight driver for
+ * XFree86 v.3.3 has been sponsored by Red Hat.
+ *
+ * Authors:
+ * Jens Owen (jens@precisioninsight.com)
+ * Kevin E. Martin (kevin@precisioninsight.com)
+ *
+ * Port to Xfree86 v.4.0
+ * 1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE)
+ */
+
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "vgaHW.h"
+
+#include "xf86Cursor.h"
+#include "cursorstr.h"
+/* Driver specific headers */
+#include "neo.h"
+
+static void _neoLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src,
+ int xoff, int yoff);
+
+void
+NeoShowCursor(ScrnInfoPtr pScrn)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+
+ /* turn cursor on */
+ OUTREG(NEOREG_CURSCNTL, NEO_CURS_ENABLE);
+ nPtr->NeoHWCursorShown = TRUE;
+}
+
+void
+NeoHideCursor(ScrnInfoPtr pScrn)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ /*
+ * turn cursor off
+ *
+ * Sometimes we loose the I/O map, so directly use I/O here
+ */
+
+ VGAwGR(0x82,0x00);
+
+ nPtr->NeoHWCursorShown = FALSE;
+}
+
+static void
+neoSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ int xoff = 0, yoff = 0;
+
+ if (y < 0) {
+ yoff = -y;
+ y = 0;
+ }
+ if (x < 0) {
+ xoff = -x;
+ x = 0;
+ }
+ if (yoff != nPtr->NeoCursorPrevY || xoff !=nPtr->NeoCursorPrevX) {
+ _neoLoadCursorImage(pScrn, nPtr->NeoCursorImage
+ + ((nPtr->CursorInfo->MaxWidth >> 2) * yoff)
+ + ((xoff + 4) >> 3),(xoff + 4),yoff);
+ nPtr->NeoCursorPrevY = yoff;
+ nPtr->NeoCursorPrevX = xoff;
+ }
+
+ /* Move the cursor */
+ OUTREG(NEOREG_CURSX, x);
+ OUTREG(NEOREG_CURSY, y);
+}
+
+static void
+neoSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+
+ /* swap blue and red */
+ fg = ((fg & 0xff0000) >> 16) | ((fg & 0xff) << 16) | (fg & 0xff00);
+ bg = ((bg & 0xff0000) >> 16) | ((bg & 0xff) << 16) | (bg & 0xff00);
+
+ /* load colors */
+ OUTREG(NEOREG_CURSFGCOLOR, fg);
+ OUTREG(NEOREG_CURSBGCOLOR, bg);
+}
+
+static void
+_neoLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src, int xoff, int yoff)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+ int i;
+ unsigned char *_dest, *_src;
+ int _width, _fill;
+
+ if (!nPtr->noLinear) {
+ for (i = 0; i< nPtr->CursorInfo->MaxHeight - yoff; i++) {
+ _dest = ((unsigned char *)nPtr->NeoFbBase
+ + nAcl->CursorAddress
+ + ((nPtr->CursorInfo->MaxWidth >> 2) * i));
+ _width = (nPtr->CursorInfo->MaxWidth
+ - (xoff & 0x38)) >> 3;
+ _src = (src + ((nPtr->CursorInfo->MaxWidth >> 2) * i));
+ _fill = (xoff & 0x38) >> 3;
+
+ memcpy(_dest,_src,_width);
+ memset(_dest + _width, 0, _fill);
+
+ _dest += (nPtr->CursorInfo->MaxWidth >> 3);
+ _src += (nPtr->CursorInfo->MaxWidth >> 3);
+ memcpy(_dest,_src,_width);
+ memset(_dest + _width, 0, _fill);
+ }
+ memset(nPtr->NeoFbBase + nAcl->CursorAddress
+ + ((nPtr->CursorInfo->MaxWidth >> 2) * i),
+ 0, (nPtr->CursorInfo->MaxHeight - i)
+ * (nPtr->CursorInfo->MaxWidth >> 2));
+ } else {
+ /*
+ * The cursor can only be in the last 16K of video memory,
+ * which fits in the last banking window.
+ */
+ for (i = 0; i<nPtr->CursorInfo->MaxHeight; i++) {
+ _dest = ((unsigned char *)nPtr->NeoFbBase
+ + (nAcl->CursorAddress & 0xFFFF)
+ + ((nPtr->CursorInfo->MaxWidth >> 2) * i));
+ _width = (nPtr->CursorInfo->MaxWidth
+ - ((xoff & 0x38) >> 3));
+ _src = (src + ((nPtr->CursorInfo->MaxWidth >> 2) * i));
+ _fill = (xoff & 0x38) >> 3;
+
+ NEOSetWrite(pScrn->pScreen, (int)(nAcl->CursorAddress >> 16));
+ memcpy(_dest,_src,_width);
+ memset(_dest + _width, 0, _fill);
+
+ _dest += (nPtr->CursorInfo->MaxWidth >> 3);
+ _src += (nPtr->CursorInfo->MaxWidth >> 3);
+ memcpy(_dest,_src,_width);
+ memset(_dest + _width, 0, _fill);
+ }
+ }
+ /* set cursor address here or we loose the cursor on video mode change */
+ /* Load storage location. */
+ OUTREG(NEOREG_CURSMEMPOS, ((0x000f & (nAcl->CursorAddress >> 10)) << 8) |
+ ((0x0ff0 & (nAcl->CursorAddress >> 10)) >> 4));
+}
+
+static void
+neoLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ nPtr->NeoCursorImage = src; /* store src address for later use */
+ _neoLoadCursorImage(pScrn,src,0,0);
+}
+
+static Bool
+neoUseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
+{
+ NEOACLPtr nAcl = NEOACLPTR(xf86Screens[pScr->myNum]);
+
+ return nAcl->UseHWCursor;
+}
+
+static unsigned char*
+neoRealizeCursor(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
+{
+ CARD32 *SrcS, *SrcM, *DstS, *DstM;
+ CARD32 *pSrc, *pMsk;
+ unsigned char *mem;
+ int SrcPitch, DstPitch, y, x, z;
+
+ mem = (unsigned char*)xnfcalloc(4096,1);
+ SrcPitch = (pCurs->bits->width + 31) >> 5;
+ DstPitch = infoPtr->MaxWidth >> 4;
+ SrcS = (CARD32*)pCurs->bits->source;
+ SrcM = (CARD32*)pCurs->bits->mask;
+ DstS = (CARD32*)mem;
+ DstM = DstS + (DstPitch >> 1);
+
+ for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
+ y--;
+ pSrc+=DstPitch, pMsk+=DstPitch, SrcS+=SrcPitch, SrcM+=SrcPitch) {
+ for(x = 0; x < SrcPitch; x++) {
+ pSrc[x] = ~SrcS[x] & SrcM[x];
+ pMsk[x] = SrcM[x];
+ for (z = 0; z < 4; z++) {
+ ((char *)pSrc)[x*4+z] =
+ byte_reversed[((char *)pSrc)[x*4+z] & 0xFF];
+ ((char *)pMsk)[x*4+z] =
+ byte_reversed[((char *)pMsk)[x*4+z] & 0xFF];
+ }
+ }
+#if 0
+ for (;x < DstPitch; x++) {
+ pSrc[x] = 0;
+ pMsk[x] = 0;
+ }
+#endif
+ }
+
+ return (unsigned char *)mem;
+}
+
+Bool
+NeoCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ NEOPtr nPtr = NEOPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ nPtr->CursorInfo = infoPtr;
+
+ infoPtr->MaxHeight = 64;
+ infoPtr->MaxWidth = 64;
+ infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
+
+ infoPtr->SetCursorColors = neoSetCursorColors;
+ infoPtr->SetCursorPosition = neoSetCursorPosition;
+ infoPtr->LoadCursorImage = neoLoadCursorImage;
+ infoPtr->HideCursor = NeoHideCursor;
+ infoPtr->ShowCursor = NeoShowCursor;
+ infoPtr->UseHWCursor = neoUseHWCursor;
+ infoPtr->RealizeCursor = neoRealizeCursor;
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c
new file mode 100644
index 000000000..f508c5c1b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c
@@ -0,0 +1,2526 @@
+/**********************************************************************
+Copyright 1998, 1999 by Precision Insight, Inc., Cedar Park, Texas.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Precision Insight not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission. Precision Insight
+and its suppliers make no representations about the suitability of this
+software for any purpose. It is provided "as is" without express or
+implied warranty.
+
+PRECISION INSIGHT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+**********************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_driver.c,v 1.7 1999/08/21 13:48:38 dawes Exp $ */
+
+/*
+ * The original Precision Insight driver for
+ * XFree86 v.3.3 has been sponsored by Red Hat.
+ *
+ * Authors:
+ * Jens Owen (jens@precisioninsight.com)
+ * Kevin E. Martin (kevin@precisioninsight.com)
+ *
+ * Port to Xfree86 v.4.0
+ * 1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE)
+ */
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.h"
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86Resources.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* This is used for module versioning */
+#include "xf86Version.h"
+
+/* All drivers using the vgahw module need this */
+#include "vgaHW.h"
+
+/* All drivers initialising the SW cursor need this */
+#include "mipointer.h"
+
+/* All drivers implementing backing store need this */
+#include "mibstore.h"
+
+/* All drivers using the mi banking wrapper need this */
+#include "mibank.h"
+
+/* All drivers using the mi colormap manipulation need this */
+#include "micmap.h"
+
+/* If using cfb, cfb.h is required. */
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+#include "cfb24_32.h"
+
+/* Needed by Resources Access Control (RAC) */
+#include "xf86RAC.h"
+
+/* Needed by the Shadow Framebuffer */
+#include "shadowfb.h"
+
+/* Needed for Device Data Channel (DDC) support */
+#include "xf86DDC.h"
+
+/*
+ * Driver data structures.
+ */
+#include "neo.h"
+#include "neo_reg.h"
+#include "neo_macros.h"
+
+/* These need to be checked */
+#if 0
+#ifdef XFreeXDGA
+#include "X.h"
+#include "Xproto.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#define _XF86DGA_SERVER_
+#include "extensions/xf86dgastr.h"
+#endif
+#endif
+
+/* Mandatory functions */
+static void NEOIdentify(int flags);
+static Bool NEOProbe(DriverPtr drv, int flags);
+static Bool NEOPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool NEOScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool NEOSwitchMode(int scrnIndex, DisplayModePtr mode,
+ int flags);
+static void NEOAdjustFrame(int scrnIndex, int x, int y, int flags);
+static Bool NEOEnterVT(int scrnIndex, int flags);
+static void NEOLeaveVT(int scrnIndex, int flags);
+static Bool NEOCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static void NEOFreeScreen(int scrnIndex, int flags);
+static int NEOValidMode(int scrnIndex, DisplayModePtr mode,
+ Bool verbose, int flags);
+
+/* Internally used functions */
+static int neoFindIsaDevice(GDevPtr dev);
+static Bool neoModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static void neoSave(ScrnInfoPtr pScrn);
+static void neoRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg,
+ NeoRegPtr NeoReg, Bool restoreFonts);
+static void neoLock(ScrnInfoPtr pScrn);
+static void neoUnlock(ScrnInfoPtr pScrn);
+static Bool neoMapMem(ScrnInfoPtr pScrn);
+static Bool neoUnmapMem(ScrnInfoPtr pScrn);
+static void neoProgramShadowRegs(ScrnInfoPtr pScrn, vgaRegPtr VgaReg,
+ NeoRegPtr restore);
+static void neoCalcVCLK(ScrnInfoPtr pScrn, long freq);
+static void neo_ddc1(int scrnIndex);
+static void neoRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+static void NeoDisplayPowerManagementSet(ScrnInfoPtr pScrn,
+ int PowerManagementMode, int flags);
+
+#define VERSION 4000
+#define NEO_NAME "NEOMAGIC"
+#define NEO_DRIVER_NAME "neomagic"
+
+#define NEO_MAJOR_VERSION 1
+#define NEO_MINOR_VERSION 0
+#define NEO_PATCHLEVEL 0
+
+/*
+ * This is intentionally screen-independent. It indicates the binding
+ * choice made in the first PreInit.
+ */
+static int pix24bpp = 0;
+
+/*
+ * This contains the functions needed by the server after loading the driver
+ * module. It must be supplied, and gets passed back by the SetupProc
+ * function in the dynamic case. In the static case, a reference to this
+ * is compiled in, and this requires that the name of this DriverRec be
+ * an upper-case version of the driver name.
+ */
+
+DriverRec NEOMAGIC = {
+ VERSION,
+ "Driver for the Neomagic chipsets",
+ NEOIdentify,
+ NEOProbe,
+ NULL,
+ 0
+};
+
+static SymTabRec NEOChipsets[] = {
+ { NM2070, "neo2070" },
+ { NM2090, "neo2090" },
+ { NM2093, "neo2093" },
+ { NM2097, "neo2097" },
+ { NM2160, "neo2160" },
+ { NM2200, "neo2200" },
+ { -1, NULL }
+};
+
+/* Conversion PCI ID to chipset name */
+static PciChipsets NEOPCIchipsets[] = {
+ { NM2070, PCI_CHIP_NM2070, RES_SHARED_VGA },
+ { NM2090, PCI_CHIP_NM2090, RES_SHARED_VGA },
+ { NM2093, PCI_CHIP_NM2093, RES_SHARED_VGA },
+ { NM2097, PCI_CHIP_NM2097, RES_SHARED_VGA },
+ { NM2160, PCI_CHIP_NM2160, RES_SHARED_VGA },
+ { NM2200, PCI_CHIP_NM2200, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED}
+};
+
+static IsaChipsets NEOISAchipsets[] = {
+ { NM2070, RES_EXCLUSIVE_VGA },
+ { NM2090, RES_EXCLUSIVE_VGA },
+ { NM2093, RES_EXCLUSIVE_VGA },
+ { NM2097, RES_EXCLUSIVE_VGA },
+ { NM2160, RES_EXCLUSIVE_VGA },
+ { NM2200, RES_EXCLUSIVE_VGA },
+ { -1, RES_UNDEFINED }
+};
+
+/* The options supported by the Neomagic Driver */
+typedef enum {
+ OPTION_NOLINEAR_MODE,
+ OPTION_NOACCEL,
+ OPTION_SW_CURSOR,
+ OPTION_NO_MMIO,
+ OPTION_INTERN_DISP,
+ OPTION_EXTERN_DISP,
+ OPTION_LCD_CENTER,
+ OPTION_LCD_STRETCH,
+ OPTION_SHADOW_FB,
+ OPTION_PCI_BURST,
+ OPTION_PROG_LCD_MODE_REGS,
+ OPTION_PROG_LCD_MODE_STRETCH,
+ OPTION_OVERRIDE_VALIDATE_MODE
+} NEOOpts;
+
+static OptionInfoRec NEO_2070_Options[] = {
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NO_MMIO, "noMMIO", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_INTERN_DISP,"internDisp", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_EXTERN_DISP,"externDisp", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_LCD_CENTER, "LcdCenter", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_LCD_STRETCH, "NoStretch", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PCI_BURST, "pciBurst", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PROG_LCD_MODE_REGS, "progLcdModeRegs",
+ OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PROG_LCD_MODE_STRETCH, "progLcdModeStretch",
+ OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_OVERRIDE_VALIDATE_MODE, "overrideValidateMode",
+ OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+static OptionInfoRec NEOOptions[] = {
+ { OPTION_NOLINEAR_MODE,"NoLinear", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NO_MMIO, "noMMIO", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_INTERN_DISP,"internDisp", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_EXTERN_DISP,"externDisp", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_LCD_CENTER, "LcdCenter", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_LCD_STRETCH,"NoStretch", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PCI_BURST, "pciBurst", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PROG_LCD_MODE_REGS, "progLcdModeRegs",
+ OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PROG_LCD_MODE_STRETCH, "progLcdModeStretch",
+ OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_OVERRIDE_VALIDATE_MODE, "overrideValidateMode",
+ OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+/*
+ * List of symbols from other modules that this module references. This
+ * list is used to tell the loader that it is OK for symbols here to be
+ * unresolved providing that it hasn't been told that they haven't been
+ * told that they are essential via a call to xf86LoaderReqSymbols() or
+ * xf86LoaderReqSymLists(). The purpose is this is to avoid warnings about
+ * unresolved symbols that are not required.
+ */
+
+static const char *vgahwSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWUnlock",
+ "vgaHWInit",
+ "vgaHWProtect",
+ "vgaHWGetIOBase",
+ "vgaHWMapMem",
+ "vgaHWLock",
+ "vgaHWFreeHWRec",
+ "vgaHWSaveScreen",
+ NULL
+};
+
+static const char *cfbSymbols[] = {
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb24ScreenInit",
+ "cfb24_32ScreenInit",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAADestroyInfoRec",
+ "XAACreateInfoRec",
+ "XAAInit",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86InitCursor",
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+static const char *ddcSymbols[] = {
+ "xf86PrintEDID",
+ "xf86DoEDID_DDC1",
+ "xf86DoEDID_DDC2",
+ NULL
+};
+
+static const char *i2cSymbols[] = {
+ "xf86CreateI2CBusRec",
+ "xf86I2CBusInit",
+ NULL
+};
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(neoSetup);
+
+static XF86ModuleVersionInfo neoVersRec =
+{
+ "neomagic",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ NEO_MAJOR_VERSION, NEO_MINOR_VERSION, NEO_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+/*
+ * This is the module init data.
+ * Its name has to be the driver name followed by ModuleData
+ */
+XF86ModuleData neomagicModuleData = { &neoVersRec, neoSetup, NULL };
+
+static pointer
+neoSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&NEOMAGIC, module, 0);
+
+ /*
+ * Modules that this driver always requires can be loaded here
+ * by calling LoadSubModule().
+ */
+
+ /*
+ * Tell the loader about symbols from other modules that this module
+ * might refer to.
+ */
+ LoaderRefSymLists(vgahwSymbols, cfbSymbols, xaaSymbols,
+ ramdacSymbols, shadowSymbols,
+ ddcSymbols, i2cSymbols, NULL);
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer)1;
+ } else {
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+#endif /* XFree86LOADER */
+
+static Bool
+NEOGetRec(ScrnInfoPtr pScrn)
+{
+ /*
+ * Allocate a NEORec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(NEORec), 1);
+
+ if (pScrn->driverPrivate == NULL)
+ return FALSE;
+ return TRUE;
+}
+
+static void
+NEOFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+/* Mandatory */
+static void
+NEOIdentify(int flags)
+{
+ xf86PrintChipsets(NEO_NAME, "Driver for Neomagic chipsets",
+ NEOChipsets);
+}
+
+/* Mandatory */
+static Bool
+NEOProbe(DriverPtr drv, int flags)
+{
+ Bool foundScreen = FALSE;
+ int numDevSections, numUsed;
+ GDevPtr *devSections;
+ int *usedChips;
+ int i;
+
+ /*
+ * Find the config file Device sections that match this
+ * driver, and return if there are none.
+ */
+ if ((numDevSections = xf86MatchDevice(NEO_DRIVER_NAME,
+ &devSections)) <= 0) {
+ return FALSE;
+ }
+
+ /* PCI BUS */
+ if (xf86GetPciVideoInfo() ) {
+ numUsed = xf86MatchPciInstances(NEO_NAME, PCI_VENDOR_NEOMAGIC,
+ NEOChipsets, NEOPCIchipsets,
+ devSections,numDevSections,
+ drv, &usedChips);
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn;
+ /* Allocate a ScrnInfoRec and claim the slot */
+ pScrn = xf86AllocateScreen(drv,0);
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = NEO_DRIVER_NAME;
+ pScrn->name = NEO_NAME;
+ pScrn->Probe = NEOProbe;
+ pScrn->PreInit = NEOPreInit;
+ pScrn->ScreenInit = NEOScreenInit;
+ pScrn->SwitchMode = NEOSwitchMode;
+ pScrn->AdjustFrame = NEOAdjustFrame;
+ pScrn->EnterVT = NEOEnterVT;
+ pScrn->LeaveVT = NEOLeaveVT;
+ pScrn->FreeScreen = NEOFreeScreen;
+ pScrn->ValidMode = NEOValidMode;
+ foundScreen = TRUE;
+ xf86ConfigActivePciEntity(pScrn, usedChips[i], NEOPCIchipsets,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+ if (numUsed > 0)
+ xfree(usedChips);
+ }
+ /* Isa Bus */
+
+ numUsed = xf86MatchIsaInstances(NEO_NAME,NEOChipsets,NEOISAchipsets,
+ drv,neoFindIsaDevice,devSections,
+ numDevSections,&usedChips);
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn;
+
+ pScrn = xf86AllocateScreen(drv,0);
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = NEO_DRIVER_NAME;
+ pScrn->name = NEO_NAME;
+ pScrn->Probe = NEOProbe;
+ pScrn->PreInit = NEOPreInit;
+ pScrn->ScreenInit = NEOScreenInit;
+ pScrn->SwitchMode = NEOSwitchMode;
+ pScrn->AdjustFrame = NEOAdjustFrame;
+ pScrn->EnterVT = NEOEnterVT;
+ pScrn->LeaveVT = NEOLeaveVT;
+ pScrn->FreeScreen = NEOFreeScreen;
+ pScrn->ValidMode = NEOValidMode;
+ foundScreen = TRUE;
+ xf86ConfigActiveIsaEntity(pScrn, usedChips[i], NEOISAchipsets,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+ if (numUsed > 0)
+ xfree(usedChips);
+
+ xfree(devSections);
+ return foundScreen;
+}
+
+static int
+neoFindIsaDevice(GDevPtr dev)
+{
+ unsigned char vgaIOBase;
+ unsigned char id;
+
+ vgaIOBase = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0;
+ /* §§§ Too intrusive ? */
+ outw(GRAX, 0x2609); /* Unlock NeoMagic registers */
+
+ outb(vgaIOBase + 4, 0x1A);
+ id = inb(vgaIOBase + 5);
+
+ outw(GRAX, 0x0009); /* Lock NeoMagic registers */
+
+ switch (id) {
+ case PROBED_NM2070 :
+ return NM2070;
+ case PROBED_NM2090 :
+ return NM2090;
+ case PROBED_NM2093 :
+ return NM2093;
+ default :
+ return -1;
+ }
+}
+
+
+/* Mandatory */
+Bool
+NEOPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ ClockRangePtr clockRanges;
+ char *mod = NULL;
+ int i;
+ NEOPtr nPtr;
+ vgaHWPtr hwp;
+ const char *reqSym = NULL;
+ int bppSupport = NoDepth24Support;
+ int videoRam = 896;
+ int maxClock = 65000;
+ int CursorMem = 1024;
+ int CursorOff = 0x100;
+ int linearSize = 1024;
+ int maxWidth = 1024;
+ unsigned char type;
+ int w;
+ int apertureSize;
+
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /*
+ * Allocate a vgaHWRec.
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+ hwp = VGAHWPTR(pScrn);
+
+ /* Allocate the NeoRec driverPrivate */
+ if (!NEOGetRec(pScrn)) {
+ return FALSE;
+ }
+# define RETURN \
+ { NEOFreeRec(pScrn);\
+ return FALSE;\
+ }
+
+ nPtr = NEOPTR(pScrn);
+
+ /* Since, the capabilities are determined by the chipset the very
+ * first thing to do is, figure out the chipset and its capabilities
+ */
+ /* This driver doesn't expect more than one entity per screen */
+ if (pScrn->numEntities > 1)
+ RETURN;
+
+ /* This is the general case */
+ for (i = 0; i<pScrn->numEntities; i++) {
+ nPtr->pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
+ if (nPtr->pEnt->resources) return FALSE;
+ nPtr->NeoChipset = nPtr->pEnt->chipset;
+ pScrn->chipset = (char *)xf86TokenToString(NEOChipsets,
+ nPtr->pEnt->chipset);
+ /* This driver can handle ISA and PCI buses */
+ if (nPtr->pEnt->location.type == BUS_PCI) {
+ nPtr->PciInfo = xf86GetPciInfoForEntity(nPtr->pEnt->index);
+ nPtr->PciTag = pciTag(nPtr->PciInfo->bus,
+ nPtr->PciInfo->device,
+ nPtr->PciInfo->func);
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Chipset is a ");
+ switch(nPtr->NeoChipset){
+ case NM2070:
+ ErrorF("MagicGraph 128 (NM2070)");
+ break;
+ case NM2090 :
+ ErrorF("MagicGraph 128V (NM2090)");
+ break;
+ case NM2093 :
+ ErrorF("MagicGraph 128ZV (NM2093)");
+ break;
+ case NM2097 :
+ ErrorF("MagicGraph 128ZV+ (NM2097)");
+ break;
+ case NM2160 :
+ ErrorF("MagicGraph 128XD (NM2160)");
+ break;
+ case NM2200 :
+ ErrorF("MagicMedia 256AV (NM2200)");
+ break;
+ }
+ ErrorF("\n");
+
+ vgaHWGetIOBase(hwp);
+ nPtr->vgaIOBase = hwp->IOBase;
+ vgaHWSetStdFuncs(hwp);
+
+ /* Determine the panel type */
+ VGAwGR(0x09,0x26);
+ type = VGArGR(0x21);
+
+ /* Determine panel width -- used in NeoValidMode. */
+ w = VGArGR(0x20);
+ VGAwGR(0x09,0x00);
+ switch ((w & 0x18) >> 3) {
+ case 0x00 :
+ nPtr->NeoPanelWidth = 640;
+ nPtr->NeoPanelHeight = 480;
+ break;
+ case 0x01 :
+ nPtr->NeoPanelWidth = 800;
+ nPtr->NeoPanelHeight = 600;
+ break;
+ case 0x02 :
+ nPtr->NeoPanelWidth = 1024;
+ nPtr->NeoPanelHeight = 768;
+ break;
+ case 0x03 :
+ /* 1280x1024 panel support needs to be added */
+#ifdef NOT_DONE
+ nPtr->NeoPanelWidth = 1280;
+ nPtr->NeoPanelHeight = 1024;
+ break;
+#else
+ ErrorF("\nOnly 640x480,\n"
+ " 800x600,\n"
+ " and 1024x768 panels are currently supported\n");
+ return FALSE;
+#endif
+ default :
+ nPtr->NeoPanelWidth = 640;
+ nPtr->NeoPanelHeight = 480;
+ break;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel is a %dx%d %s %s display\n",
+ nPtr->NeoPanelWidth,
+ nPtr->NeoPanelHeight,
+ (type & 0x02) ? "color" : "monochrome",
+ (type & 0x10) ? "TFT" : "dual scan");
+
+ switch (nPtr->NeoChipset){
+ case NM2070:
+ bppSupport = NoDepth24Support;
+ videoRam = 896;
+ maxClock = 65000;
+ CursorMem = 2048;
+ CursorOff = 0x100;
+ linearSize = 1024;
+ maxWidth = 1024;
+ break;
+ case NM2090:
+ case NM2093:
+ bppSupport = Support24bppFb | Support32bppFb |
+ SupportConvert32to24 | PreferConvert32to24;
+ videoRam = 1152;
+ maxClock = 80000;
+ CursorMem = 2048;
+ CursorOff = 0x100;
+ linearSize = 2048;
+ maxWidth = 1024;
+ break;
+ case NM2097:
+ bppSupport = Support24bppFb | Support32bppFb |
+ SupportConvert32to24 | PreferConvert32to24;
+ videoRam = 1152;
+ maxClock = 80000;
+ CursorMem = 1024;
+ CursorOff = 0x100;
+ linearSize = 2048;
+ maxWidth = 1024;
+ break;
+ case NM2160:
+ bppSupport = Support24bppFb | Support32bppFb |
+ SupportConvert32to24 | PreferConvert32to24;
+ videoRam = 2048;
+ maxClock = 90000;
+ CursorMem = 1024;
+ CursorOff = 0x100;
+ linearSize = 2048;
+ maxWidth = 1024;
+ break;
+ case NM2200:
+ bppSupport = Support24bppFb | Support32bppFb |
+ SupportConvert32to24 | PreferConvert32to24;
+ videoRam = 2560;
+ maxClock = 110000;
+ CursorMem = 1024;
+ CursorOff = 0x1000;
+ linearSize = 4096;
+ maxWidth = 1280;
+ break;
+ }
+
+ if (!xf86LoadSubModule(pScrn, "ddc"))
+ return FALSE;
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+#if 0
+ VGAwGR(0x09,0x26);
+ neo_ddc1(pScrn->scrnIndex);
+ VGAwGR(0x09,0x00);
+#endif
+ if (!xf86LoadSubModule(pScrn, "i2c"))
+ return FALSE;
+ xf86LoaderReqSymLists(i2cSymbols, NULL);
+ if (!neo_I2CInit(pScrn))
+ return FALSE;
+
+ VGAwGR(0x09,0x26);
+ xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,nPtr->I2C));
+ VGAwGR(0x09,0x00);
+
+ pScrn->monitor = pScrn->confScreen->monitor;
+ if (!xf86SetDepthBpp(pScrn, 8, 8, 8, bppSupport ))
+ return FALSE;
+ else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 8:
+ case 16:
+ break;
+ case 24:
+ if (nPtr->NeoChipset != NM2070)
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+ xf86PrintDepthBpp(pScrn);
+ if (pScrn->depth == 8)
+ pScrn->rgbBits = 6;
+
+ /* Get the depth24 pixmap format */
+ if (pScrn->depth == 24 && pix24bpp == 0)
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+ /* Process the options */
+ if (nPtr->NeoChipset == NM2070)
+ nPtr->Options = (OptionInfoPtr)NEO_2070_Options;
+ else
+ nPtr->Options = (OptionInfoPtr)NEOOptions;
+
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, nPtr->Options);
+
+ xf86GetOptValBool(nPtr->Options, OPTION_NOLINEAR_MODE,&nPtr->noLinear);
+ xf86GetOptValBool(nPtr->Options, OPTION_NOACCEL,&nPtr->noAccel);
+ xf86GetOptValBool(nPtr->Options, OPTION_SW_CURSOR,&nPtr->swCursor);
+ xf86GetOptValBool(nPtr->Options, OPTION_NO_MMIO,&nPtr->noMMIO);
+ xf86GetOptValBool(nPtr->Options, OPTION_INTERN_DISP,&nPtr->internDisp);
+ xf86GetOptValBool(nPtr->Options, OPTION_EXTERN_DISP,&nPtr->externDisp);
+ xf86GetOptValBool(nPtr->Options, OPTION_LCD_CENTER,&nPtr->lcdCenter);
+ xf86GetOptValBool(nPtr->Options, OPTION_LCD_STRETCH,&nPtr->noLcdStretch);
+ xf86GetOptValBool(nPtr->Options, OPTION_SHADOW_FB,&nPtr->shadowFB);
+ xf86GetOptValBool(nPtr->Options, OPTION_PCI_BURST,&nPtr->onPciBurst);
+ xf86GetOptValBool(nPtr->Options,
+ OPTION_PROG_LCD_MODE_REGS,&nPtr->progLcdRegs);
+ if (xf86GetOptValBool(nPtr->Options,
+ OPTION_PROG_LCD_MODE_STRETCH,&nPtr->progLcdStretch))
+ nPtr->progLcdStrechOpt = TRUE;
+ xf86GetOptValBool(nPtr->Options,
+ OPTION_OVERRIDE_VALIDATE_MODE, &nPtr->overrideValidate);
+ if (nPtr->shadowFB)
+ ErrorF("shadow\n");
+ else
+ ErrorF("no shadow\n");
+
+ if (nPtr->internDisp && nPtr->externDisp)
+ xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,
+ "Simultaneous LCD/CRT display mode\n");
+ else if (nPtr->externDisp)
+ xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,
+ "External CRT only display mode\n");
+ else if (nPtr->internDisp)
+ xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,
+ "Internal LCD only display mode\n");
+ if (nPtr->noLcdStretch)
+ xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,
+ "Low resolution video modes are not stretched\n");
+ if (nPtr->lcdCenter)
+ xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,
+ "Video modes are centered on the display\n");
+ if (nPtr->noLinear)
+ xf86DrvMsg(pScrn->scrnIndex,X_CONFIG, "using nonlinear mode\n");
+ else
+ xf86DrvMsg(pScrn->scrnIndex,X_DEFAULT, "using linear mode\n");
+ if (nPtr->swCursor)
+ xf86DrvMsg(pScrn->scrnIndex,X_CONFIG, "using sofware cursor\n");
+ if (nPtr->noMMIO)
+ xf86DrvMsg(pScrn->scrnIndex,X_CONFIG, "MMIO mode disabled\n");
+ if (nPtr->onPciBurst)
+ xf86DrvMsg(pScrn->scrnIndex,X_CONFIG, "using PCI Burst mode\n");
+ if (nPtr->shadowFB) {
+ if (nPtr->noLinear) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Option \"ShadowFB\" ignored. Not supported without"
+ " linear addressing\n");
+ nPtr->shadowFB = FALSE;
+ } else {
+ nPtr->noAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using \"Shadow Framebuffer\" - acceleration disabled\n");
+ }
+ }
+
+ nPtr->NeoFbMapSize = linearSize * 1024;
+ nPtr->NeoCursorOffset = CursorOff;
+
+ if (nPtr->pEnt->device->MemBase) {
+ /* XXX Check this matches a PCI base address */
+ nPtr->NeoLinearAddr = nPtr->pEnt->device->MemBase;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "base address is set at 0x%X.\n",
+ nPtr->NeoLinearAddr);
+ } else {
+ nPtr->NeoLinearAddr = 0;
+ }
+
+ if (nPtr->pEnt->device->IOBase) {
+ /* XXX Check this matches a PCI base address */
+ nPtr->NeoMMIOAddr = nPtr->pEnt->device->IOBase;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "base address is set at 0x%X.\n",
+ nPtr->NeoMMIOAddr);
+ } else {
+ nPtr->NeoMMIOAddr = 0;
+ }
+
+ if (nPtr->pEnt->location.type == BUS_PCI) {
+ if (!nPtr->NeoLinearAddr) {
+ nPtr->NeoLinearAddr = nPtr->PciInfo->memBase[0];
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "base address is set at 0x%X.\n",
+ nPtr->NeoLinearAddr);
+ }
+ if (!nPtr->NeoMMIOAddr) {
+ switch (nPtr->NeoChipset) {
+ case NM2070 :
+ nPtr->NeoMMIOAddr = nPtr->NeoLinearAddr + 0x100000;
+ break;
+ case NM2090:
+ case NM2093:
+ nPtr->NeoMMIOAddr = nPtr->NeoLinearAddr + 0x200000;
+ break;
+ case NM2160:
+ case NM2097:
+ case NM2200:
+ nPtr->NeoMMIOAddr = nPtr->PciInfo->memBase[1];
+ break;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "base address is set at 0x%X.\n",
+ nPtr->NeoMMIOAddr);
+ }
+ /* XXX What about VGA resources in OPERATING mode? */
+ if (xf86RegisterResources(nPtr->pEnt->index, NULL, ResExclusive))
+ RETURN;
+
+ } else if (nPtr->pEnt->location.type == BUS_ISA) {
+ unsigned int addr;
+ resRange linearRes[] = { {ResExcMemBlock|ResBios,0,0},_END };
+
+ if (!nPtr->NeoLinearAddr) {
+ VGAwGR(0x09,0x26);
+ addr = VGArGR(0x13);
+ VGAwGR(0x09,0x00);
+ nPtr->NeoLinearAddr = addr << 20;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "base address is set at 0x%X.\n",
+ nPtr->NeoLinearAddr);
+ }
+ if (!nPtr->NeoMMIOAddr) {
+ nPtr->NeoMMIOAddr = nPtr->NeoLinearAddr + 0x100000;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "base address is set at 0x%X.\n",
+ nPtr->NeoMMIOAddr);
+ }
+ linearRes[0].rBegin = nPtr->NeoLinearAddr;
+ linearRes[1].rEnd = nPtr->NeoLinearAddr + nPtr->NeoFbMapSize - 1;
+ if (xf86RegisterResources(nPtr->pEnt->index,linearRes,ResNone)) {
+ nPtr->noLinear = TRUE; /* XXX */
+ }
+ } else
+ RETURN;
+
+ if (nPtr->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = nPtr->pEnt->device->videoRam;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+ } else {
+ pScrn->videoRam = videoRam;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+ }
+
+ if (nPtr->pEnt->device->dacSpeeds[0] != 0) {
+ maxClock = nPtr->pEnt->device->dacSpeeds[0];
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Max Clock: %d kHz\n",
+ maxClock);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Max Clock: %d kByte\n",
+ maxClock);
+ }
+
+ pScrn->progClock = TRUE;
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+ clockRanges = (ClockRangePtr)xnfalloc(sizeof(ClockRange));
+ clockRanges->next = NULL;
+ clockRanges->ClockMulFactor = 1;
+ clockRanges->minClock = 11000; /* guessed §§§ */
+ clockRanges->maxClock = maxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ if (!nPtr->internDisp && nPtr->externDisp)
+ clockRanges->interlaceAllowed = TRUE; /* §§§ */
+ else
+ clockRanges->interlaceAllowed = FALSE;
+ clockRanges->doubleScanAllowed = TRUE;
+
+ /* Subtract memory for HW cursor */
+ if (!nPtr->swCursor)
+ nPtr->NeoCursorMem = CursorMem;
+ else
+ nPtr->NeoCursorMem = 0;
+ apertureSize = nPtr->NeoFbMapSize - nPtr->NeoCursorMem;
+ /*
+ * For external displays, limit the width to 1024 pixels or less.
+ */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, 256, maxWidth,(8 * pScrn->bitsPerPixel),/*§§§*/
+ 128, 2048, pScrn->display->virtualX,
+ pScrn->display->virtualY, apertureSize,
+ LOOKUP_BEST_REFRESH);
+
+ if (i == -1)
+ RETURN;
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ RETURN;
+ }
+
+ /*
+ * Set the CRTC parameters for all of the modes based on the type
+ * of mode, and the chipset's interlace requirements.
+ *
+ * Calling this is required if the mode->Crtc* values are used by the
+ * driver and if the driver doesn't provide code to set them. They
+ * are not pre-initialised at all.
+ */
+ xf86SetCrtcForModes(pScrn, 0);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* If monitor resolution is set on the command line, use it */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ mod = "cfb";
+ reqSym = "cfbScreenInit";
+ break;
+ case 16:
+ mod = "cfb16";
+ reqSym = "cfb16ScreenInit";
+ break;
+ case 24:
+ if (pix24bpp == 24) {
+ mod = "cfb24";
+ reqSym = "cfb24ScreenInit";
+ } else {
+ mod = "xf24_32bpp";
+ reqSym = "cfb24_32ScreenInit";
+ }
+ break;
+ }
+ if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ RETURN;
+ }
+
+ xf86LoaderReqSymbols(reqSym, NULL);
+
+ if (!nPtr->noLinear) {
+ if (!xf86LoadSubModule(pScrn, "xaa"))
+ RETURN;
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ if (nPtr->shadowFB) {
+ if (!xf86LoadSubModule(pScrn, "shadowfb")) {
+ RETURN;
+ }
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+ }
+
+ if (!nPtr->swCursor) {
+ if (!xf86LoadSubModule(pScrn, "ramdac"))
+ RETURN;
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+ }
+
+ return TRUE;
+}
+#undef RETURN
+
+/* Mandatory */
+static Bool
+NEOEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ NEOPtr nPtr = NEOPTR(pScrn);
+
+ /* Should we re-save the text mode on each VT enter? */
+ if(!neoModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ if (nPtr->NeoHWCursorShown)
+ NeoShowCursor(pScrn);
+ NEOAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ return TRUE;
+}
+
+/* Mandatory */
+static void
+NEOLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ NEOPtr nPtr = NEOPTR(pScrn);
+
+#if 0
+#ifdef XFreeXDGA
+ if (vga256InfoRec.directMode&XF86DGADirectGraphics && !enter) {
+ /*
+ * Disable HW cursor. I hope DGA can't call this function twice
+ * in a row, without calling EnterVT in between. Otherwise the
+ * effect will be to hide the cursor, perhaps permanently!!
+ */
+ if (nPtr->NeoHWCursorShown)
+ NeoHideCursor(pScrn);
+ return;
+ }
+#endif
+#endif
+
+ /* Invalidate the cached acceleration registers */
+ if (nPtr->NeoHWCursorShown)
+ NeoHideCursor(pScrn);
+ neoRestore(pScrn, &(VGAHWPTR(pScrn))->SavedReg, &nPtr->NeoSavedReg, TRUE);
+ neoLock(pScrn);
+}
+
+/* Mandatory */
+static Bool
+NEOScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ NEOPtr nPtr;
+ NEOACLPtr nAcl;
+ int ret;
+ VisualPtr visual;
+ int allocatebase, freespace, currentaddr;
+ unsigned int racflag = RAC_FB;
+ unsigned char *FBStart;
+
+ /*
+ * we need to get the ScrnInfoRec for this screen, so let's allocate
+ * one first thing
+ */
+ pScrn = xf86Screens[pScreen->myNum];
+ nPtr = NEOPTR(pScrn);
+ nAcl = NEOACLPTR(pScrn);
+
+ hwp = VGAHWPTR(pScrn);
+ hwp->MapSize = 0x10000; /* Standard 64k VGA window */
+ /* Map the VGA memory */
+ if (!vgaHWMapMem(pScrn))
+ return FALSE;
+
+ /* Map the Neo memory and possible MMIO areas */
+ if (!neoMapMem(pScrn))
+ return FALSE;
+
+ /*
+ * next we save the current state and setup the first mode
+ */
+ neoSave(pScrn);
+
+ if (!neoModeInit(pScrn,pScrn->currentMode))
+ return FALSE;
+ vgaHWSaveScreen(pScreen,FALSE);
+ NEOAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ /*
+ * For bpp > 8, the default visuals are not acceptable because we only
+ * support TrueColor and not DirectColor. To deal with this, call
+ * miSetVisualTypes for each visual supported.
+ */
+
+ if (pScrn->depth > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
+ pScrn->defaultVisual))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+ /*
+ * Temporarily set the global defaultColorVisualClass to make
+ * cfbInitVisuals do what we want.
+ */
+#if 0
+ savedDefaultVisualClass = xf86GetDefaultColorVisualClass();
+ xf86SetDefaultColorVisualClass(pScrn->defaultVisual);
+#endif
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+ if(nPtr->shadowFB) {
+ nPtr->ShadowPitch =
+ ((pScrn->virtualX * pScrn->bitsPerPixel >> 3) + 3) & ~3L;
+ nPtr->ShadowPtr = xalloc(nPtr->ShadowPitch * pScrn->virtualY);
+ FBStart = nPtr->ShadowPtr;
+ } else {
+ nPtr->ShadowPtr = NULL;
+ FBStart = nPtr->NeoFbBase;
+ }
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ ret = cfbScreenInit(pScreen, FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 16:
+ ret = cfb16ScreenInit(pScreen, FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 24:
+ if (pix24bpp == 24)
+ ret = cfb24ScreenInit(pScreen, FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ else
+ ret = cfb24_32ScreenInit(pScreen, FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in NEOScreenInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+
+#if 0
+ xf86SetDefaultColorVisualClass(savedDefaultVisualClass);
+#endif
+ if (!ret)
+ return FALSE;
+
+ if (pScrn->depth > 8) {
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ nPtr->NeoHWCursorShown = FALSE;
+ nPtr->NeoHWCursorInitialized = FALSE;
+ nAcl->UseHWCursor = FALSE;
+
+ if (nPtr->noLinear) {
+ miBankInfoPtr pBankInfo;
+
+ /* Setup the vga banking variables */
+ pBankInfo = (miBankInfoPtr)xnfcalloc(sizeof(miBankInfoRec),1);
+ if (pBankInfo == NULL)
+ return FALSE;
+
+ pBankInfo->pBankA = hwp->Base;
+ pBankInfo->pBankB = (unsigned char *)hwp->Base + 0x10000;
+ pBankInfo->BankSize = 0x10000;
+ pBankInfo->nBankDepth = pScrn->depth;
+
+ pBankInfo->SetSourceBank = (miBankProcPtr)NEOSetRead;
+ pBankInfo->SetDestinationBank =
+ (miBankProcPtr)NEOSetWrite;
+ pBankInfo->SetSourceAndDestinationBanks =
+ (miBankProcPtr)NEOSetReadWrite;
+ if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
+ pScrn->displayWidth, pBankInfo)) {
+ xfree(pBankInfo);
+ pBankInfo = NULL;
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Using nonlinear mode\n");
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO, "Using software cursor\n");
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ /* Initialise cursor functions */
+ miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
+
+ } else {
+ nAcl->CursorAddress = -1;
+ nAcl->cacheStart = -1;
+ nAcl->cacheEnd = -1;
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,
+ "Using linear framebuffer at: 0x%08lX\n",
+ nPtr->NeoLinearAddr);
+ /* Setup pointers to free space in video ram */
+ allocatebase = (pScrn->videoRam << 10);
+ freespace = allocatebase - pScrn->displayWidth *
+ pScrn->virtualY * (pScrn->bitsPerPixel >> 3);
+ currentaddr = allocatebase;
+ xf86DrvMsg(scrnIndex, X_PROBED,
+ "%d bytes off-screen memory available\n", freespace);
+
+ if (nPtr->swCursor || nPtr->noMMIO) {
+ xf86DrvMsg(scrnIndex, X_CONFIG,
+ "Using Software Cursor.\n");
+ } else if (nPtr->NeoCursorMem <= freespace) {
+ currentaddr -= nPtr->NeoCursorMem;
+ freespace -= nPtr->NeoCursorMem;
+ /* alignment */
+ freespace -= currentaddr & 0x3FF;
+ currentaddr &= 0xfffffc00;
+ nAcl->CursorAddress = currentaddr;
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Using H/W Cursor.\n");
+ } else xf86DrvMsg(scrnIndex, X_ERROR,
+ "Too little space for H/W cursor.\n");
+
+ /* Setup the acceleration primitives */
+ if (!nPtr->noAccel) {
+ nAcl->cacheStart = currentaddr - freespace;
+ nAcl->cacheEnd = currentaddr;
+ freespace = 0;
+ if (nAcl->cacheStart >= nAcl->cacheEnd) {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Too little space for pixmap cache.\n");
+ }
+ switch(nPtr->NeoChipset) {
+ case NM2070 :
+ Neo2070AccelInit(pScreen);
+ break;
+ case NM2090 :
+ case NM2093 :
+ Neo2090AccelInit(pScreen);
+ break;
+ case NM2097 :
+ case NM2160 :
+ Neo2097AccelInit(pScreen);
+ break;
+ case NM2200 :
+ Neo2200AccelInit(pScreen);
+ break;
+ }
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Acceleration Initialized\n");
+ }
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ /* Initialise cursor functions */
+ miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
+
+ if (nAcl->CursorAddress != -1) {
+ /* HW cursor functions */
+ if (!NeoCursorInit(pScreen)) {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ return FALSE;
+ }
+ nAcl->UseHWCursor = TRUE;
+ nPtr->NeoHWCursorInitialized = TRUE;
+ }
+ }
+
+ if (nPtr->shadowFB)
+ ShadowFBInit(pScreen, neoRefreshArea);
+
+ /* Initialise default colourmap */
+ if(!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ if (!vgaHWHandleColormaps(pScreen))
+ return FALSE;
+
+ if (pScrn->bitsPerPixel == 8)
+ racflag |= RAC_COLORMAP;
+ if (nPtr->NeoHWCursorInitialized)
+ racflag |= RAC_CURSOR;
+
+ pScrn->racIoFlags = pScrn->racMemFlags = racflag;
+
+ pScreen->SaveScreen = vgaHWSaveScreen;
+
+#ifdef DPMSExtension
+ /* Setup DPMS mode */
+ if (nPtr->NeoChipset != NM2070)
+ xf86DPMSInit(pScreen, (DPMSSetProcPtr)NeoDisplayPowerManagementSet,
+ 0);
+#endif
+
+ /* Wrap the current CloseScreen function */
+ nPtr->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = NEOCloseScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ return TRUE;
+}
+
+/* Mandatory */
+static Bool
+NEOSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return neoModeInit(xf86Screens[scrnIndex], mode);
+}
+
+/* Mandatory */
+static void
+NEOAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn;
+ NEOPtr nPtr;
+ vgaHWPtr hwp;
+ int oldExtCRTDispAddr;
+ int Base;
+
+ pScrn = xf86Screens[scrnIndex];
+ Base = (y * pScrn->displayWidth + x) >> 2;
+ hwp = VGAHWPTR(pScrn);
+ nPtr = NEOPTR(pScrn);
+ /* Scale Base by the number of bytes per pixel. */
+
+ switch (pScrn->bitsPerPixel) {
+ case 8 :
+ break;
+ case 15 :
+ case 16 :
+ Base *= 2;
+ break;
+ case 24 :
+ Base *= 3;
+ break;
+ default :
+ break;
+ }
+ /*
+ * These are the generic starting address registers.
+ */
+ VGAwCR(0x0C, (Base & 0x00FF00) >> 8);
+ VGAwCR(0x0D, (Base & 0x00FF));
+
+ /*
+ * Make sure we don't clobber some other bits that might already
+ * have been set. NOTE: NM2200 has a writable bit 3, but it shouldn't
+ * be needed.
+ */
+ oldExtCRTDispAddr = VGArGR(0x0E);
+ VGAwGR(0x0E,(((Base >> 16) & 0x07) | (oldExtCRTDispAddr & 0xf8)));
+#if 0
+ /*
+ * This is a workaround for a higher level bug that causes the cursor
+ * to be at the wrong position after a virtual screen resolution change
+ */
+ if (nPtr->NeoHWCursorInitialized) { /*§§§ do we still need this?*/
+ NeoRepositionCursor();
+ }
+#endif
+}
+
+/* Mandatory */
+static Bool
+NEOCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ NEOPtr nPtr = NEOPTR(pScrn);
+
+ if(pScrn->vtSema){
+ if (nPtr->NeoHWCursorShown)
+ NeoHideCursor(pScrn);
+ neoRestore(pScrn, &(VGAHWPTR(pScrn))->SavedReg, &nPtr->NeoSavedReg, TRUE);
+ neoLock(pScrn);
+ neoUnmapMem(pScrn);
+ }
+ if (nPtr->AccelInfoRec)
+ XAADestroyInfoRec(nPtr->AccelInfoRec);
+ if (nPtr->CursorInfo)
+ xf86DestroyCursorInfoRec(nPtr->CursorInfo);
+
+ pScrn->vtSema = FALSE;
+ pScreen->CloseScreen = nPtr->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+/* Optional */
+static void
+NEOFreeScreen(int scrnIndex, int flags)
+{
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ NEOFreeRec(xf86Screens[scrnIndex]);
+}
+
+/* Optional */
+static int
+NEOValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ NEOPtr nPtr = NEOPTR(pScrn);
+
+ /*
+ * Limit the modes to just those allowed by the various NeoMagic
+ * chips.
+ */
+
+ if (nPtr->overrideValidate) {
+ xf86DrvMsg(scrnIndex, X_WARNING, "display mode validation disabled\n");
+ } else {
+ /*
+ * When the LCD is active, only allow modes that are (1) equal to
+ * or smaller than the size of the panel and (2) are one of the
+ * following sizes: 1024x768, 800x600, 640x480.
+ */
+ if (nPtr->internDisp || !nPtr->externDisp) {
+ /* Is the mode larger than the LCD panel? */
+ if ((mode->HDisplay > nPtr->NeoPanelWidth) ||
+ (mode->VDisplay > nPtr->NeoPanelHeight)) {
+ xf86DrvMsg(scrnIndex,X_INFO, "Removing mode (%dx%d) "
+ "larger than the LCD panel (%dx%d)\n",
+ mode->HDisplay,
+ mode->VDisplay,
+ nPtr->NeoPanelWidth,
+ nPtr->NeoPanelHeight);
+ return(MODE_BAD);
+ }
+
+ /* Is the mode one of the acceptable sizes? */
+ switch (mode->HDisplay) {
+ case 1280:
+ if (mode->VDisplay == 1024)
+ return(MODE_OK);
+ break;
+ case 1024 :
+ if (mode->VDisplay == 768)
+ return(MODE_OK);
+ break;
+ case 800 :
+ if (mode->VDisplay == 600)
+ return(MODE_OK);
+ break;
+ case 640 :
+ if (mode->VDisplay == 480)
+ return(MODE_OK);
+ break;
+ }
+
+ xf86DrvMsg(scrnIndex, X_INFO, "Removing mode (%dx%d) that won't "
+ "display properly on LCD\n",
+ mode->HDisplay,
+ mode->VDisplay);
+ return(MODE_BAD);
+ }
+ }
+ return(MODE_OK);
+}
+
+static void
+neoLock(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ VGAwGR(0x09,0x00);
+ vgaHWLock(hwp);
+}
+
+static void
+neoUnlock(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ vgaHWUnlock(hwp);
+ VGAwGR(0x09,0x26);
+}
+
+static Bool
+neoMapMem(ScrnInfoPtr pScrn)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ if (!nPtr->noLinear) {
+ if (!nPtr->noMMIO) {
+ if (nPtr->pEnt->location.type == BUS_PCI)
+ nPtr->NeoMMIOBase =
+ xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ nPtr->PciTag, nPtr->NeoMMIOAddr,
+ 0x200000L);
+ else
+ nPtr->NeoMMIOBase =
+ xf86MapVidMem(pScrn->scrnIndex,
+ VIDMEM_MMIO, nPtr->NeoMMIOAddr,
+ 0x200000L);
+ }
+ if (nPtr->NeoMMIOBase == NULL)
+ return FALSE;
+
+ if (nPtr->pEnt->location.type == BUS_PCI)
+ nPtr->NeoFbBase =
+ xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ nPtr->PciTag,
+ (unsigned long)nPtr->NeoLinearAddr,
+ nPtr->NeoFbMapSize);
+ else
+ nPtr->NeoFbBase =
+ xf86MapVidMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ (unsigned long)nPtr->NeoLinearAddr,
+ nPtr->NeoFbMapSize);
+ if (nPtr->NeoFbBase == NULL)
+ return FALSE;
+ } else {
+ /* In paged mode Base is the VGA window at 0xA0000 */
+ nPtr->NeoFbBase = hwp->Base;
+ }
+ return TRUE;
+}
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+neoUnmapMem(ScrnInfoPtr pScrn)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+
+ if (!nPtr->noLinear) {
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)nPtr->NeoMMIOBase, 0x200000L);
+ nPtr->NeoMMIOBase = NULL;
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)nPtr->NeoFbBase,
+ nPtr->NeoFbMapSize);
+ }
+ nPtr->NeoFbBase = NULL;
+
+ return TRUE;
+}
+
+static void
+neoSave(ScrnInfoPtr pScrn)
+{
+ vgaRegPtr VgaSave = &VGAHWPTR(pScrn)->SavedReg;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NeoRegPtr save;
+ int i;
+
+ save = &nPtr->NeoSavedReg;
+
+ VGAwGR(0x09,0x26);
+ /*
+ * Whatever code is needed to get back to bank zero goes here.
+ */
+ VGAwGR(0x15,0x00);
+
+ /* get generic registers */
+ vgaHWSave(pScrn, VgaSave, VGA_SR_ALL);
+
+ /*
+ * The port I/O code necessary to read in the extended registers
+ * into the fields of the vgaNeoRec structure goes here.
+ */
+
+ save->GeneralLockReg = VGArGR(0x0A);
+
+ save->ExtCRTDispAddr = VGArGR(0x0E);
+ if (nPtr->NeoChipset != NM2070) {
+ save->ExtCRTOffset = VGArGR(0x0F);
+ }
+ save->SysIfaceCntl1 = VGArGR(0x10);
+ save->SysIfaceCntl2 = VGArGR(0x11);
+ save->SingleAddrPage = VGArGR(0x15);
+ save->DualAddrPage = VGArGR(0x16);
+ save->PanelDispCntlReg1 = VGArGR(0x20);
+ save->PanelDispCntlReg2 = VGArGR(0x25);
+ save->PanelDispCntlReg3 = VGArGR(0x30);
+ save->PanelVertCenterReg1 = VGArGR(0x28);
+ save->PanelVertCenterReg2 = VGArGR(0x29);
+ save->PanelVertCenterReg3 = VGArGR(0x2A);
+ if (nPtr->NeoChipset != NM2070) {
+ save->PanelVertCenterReg4 = VGArGR(0x32);
+ save->PanelHorizCenterReg1 = VGArGR(0x33);
+ save->PanelHorizCenterReg2 = VGArGR(0x34);
+ save->PanelHorizCenterReg3 = VGArGR(0x35);
+ }
+ if (nPtr->NeoChipset == NM2160) {
+ save->PanelHorizCenterReg4 = VGArGR(0x36);
+ }
+ if (nPtr->NeoChipset == NM2200) {
+ save->PanelHorizCenterReg4 = VGArGR(0x36);
+ save->PanelVertCenterReg5 = VGArGR(0x37);
+ save->PanelHorizCenterReg5 = VGArGR(0x38);
+ }
+ save->ExtColorModeSelect = VGArGR(0x90);
+ save->VCLK3NumeratorLow = VGArGR(0x9B);
+ if (nPtr->NeoChipset == NM2200)
+ save->VCLK3NumeratorHigh = VGArGR(0x8F);
+ save->VCLK3Denominator = VGArGR(0x9F);
+
+ if (save->reg == NULL)
+ save->reg = (regSavePtr)xnfcalloc(sizeof(regSaveRec), 1);
+ else
+ ErrorF("WARNING: Non-NULL reg in NeoSave: reg=0x%08X\n", save->reg);
+
+ save->reg->CR[0x25] = VGArCR(0x25);
+ save->reg->CR[0x2F] = VGArCR(0x2F);
+ for (i = 0x40; i <= 0x59; i++) {
+ save->reg->CR[i] = VGArCR(i);
+ }
+ for (i = 0x60; i <= 0x69; i++) {
+ save->reg->CR[i] = VGArCR(i);
+ }
+ for (i = 0x70; i <= NEO_EXT_CR_MAX; i++) {
+ save->reg->CR[i] = VGArCR(i);
+ }
+
+ for (i = 0x0A; i <= NEO_EXT_GR_MAX; i++) {
+ save->reg->GR[i] = VGArGR(i);
+ }
+}
+
+/*
+ * neoProgramShadowRegs
+ *
+ * Setup the shadow registers to their default values. The NeoSave
+ * routines will restore the proper values on server exit.
+ */
+static void
+neoProgramShadowRegs(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore)
+{
+ int i;
+ Bool noProgramShadowRegs;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ NEOPtr nPtr = NEOPTR(pScrn);
+
+ /*
+ * Convoluted logic for shadow register programming.
+ *
+ * As far as we know, shadow programming is needed for the 2070,
+ * but not in stretched modes. Special case this code.
+ */
+ switch (nPtr->NeoChipset) {
+ case NM2070:
+ /* Program the shadow regs by default */
+ noProgramShadowRegs = FALSE;
+ if (!nPtr->progLcdRegs)
+ noProgramShadowRegs = TRUE;
+
+ if (restore->PanelDispCntlReg2 & 0x84) {
+ /* Don't program by default if in stretch mode */
+ noProgramShadowRegs = TRUE;
+ if (nPtr->progLcdStretch)
+ noProgramShadowRegs = FALSE;
+ }
+ break;
+ case NM2090:
+ case NM2093:
+ case NM2097:
+ case NM2160:
+ case NM2200:
+ default:
+ /* Don't program the shadow regs by default */
+ noProgramShadowRegs = TRUE;
+ if (nPtr->progLcdRegs)
+ noProgramShadowRegs = FALSE;
+
+ if (restore->PanelDispCntlReg2 & 0x84) {
+ /* Only change the behavior if an option is set */
+ if (nPtr->progLcdStrechOpt)
+ noProgramShadowRegs = !nPtr->progLcdStretch;
+ }
+ break;
+ }
+
+ if (noProgramShadowRegs) {
+ if (nPtr->NeoSavedReg.reg){
+ for (i = 0x40; i <= 0x59; i++) {
+ VGAwCR(i, nPtr->NeoSavedReg.reg->CR[i]);
+ }
+ for (i = 0x60; i <= 0x64; i++) {
+ VGAwCR(i, nPtr->NeoSavedReg.reg->CR[i]);
+ }
+ }
+ } else {
+ /*
+ * Program the shadow regs based on the panel width. This works
+ * fine for normal sized panels, but what about the odd ones like
+ * the Libretto 100 which has an 800x480 panel???
+ */
+ switch (nPtr->NeoPanelWidth) {
+ case 640 :
+ VGAwCR(0x40,0x5F);
+ VGAwCR(0x41,0x50);
+ VGAwCR(0x42,0x02);
+ VGAwCR(0x43,0x55);
+ VGAwCR(0x44,0x81);
+ VGAwCR(0x45,0x0B);
+ VGAwCR(0x46,0x2E);
+ VGAwCR(0x47,0xEA);
+ VGAwCR(0x48,0x0C);
+ VGAwCR(0x49,0xE7);
+ VGAwCR(0x4A,0x04);
+ VGAwCR(0x4B,0x2D);
+ VGAwCR(0x4C,0x28);
+ VGAwCR(0x4D,0x90);
+ VGAwCR(0x4E,0x2B);
+ VGAwCR(0x4F,0xA0);
+ break;
+ case 800 :
+ VGAwCR(0x40,0x7F);
+ VGAwCR(0x41,0x63);
+ VGAwCR(0x42,0x02);
+ VGAwCR(0x43,0x6C);
+ VGAwCR(0x44,0x1C);
+ VGAwCR(0x45,0x72);
+ VGAwCR(0x46,0xE0);
+ VGAwCR(0x47,0x58);
+ VGAwCR(0x48,0x0C);
+ VGAwCR(0x49,0x57);
+ VGAwCR(0x4A,0x73);
+ VGAwCR(0x4B,0x3D);
+ VGAwCR(0x4C,0x31);
+ VGAwCR(0x4D,0x01);
+ VGAwCR(0x4E,0x36);
+ VGAwCR(0x4F,0x1E);
+ if (nPtr->NeoChipset != NM2070) {
+ VGAwCR(0x50,0x6B);
+ VGAwCR(0x51,0x4F);
+ VGAwCR(0x52,0x0E);
+ VGAwCR(0x53,0x58);
+ VGAwCR(0x54,0x88);
+ VGAwCR(0x55,0x33);
+ VGAwCR(0x56,0x27);
+ VGAwCR(0x57,0x16);
+ VGAwCR(0x58,0x2C);
+ VGAwCR(0x59,0x94);
+ }
+ break;
+ case 1024 :
+ VGAwCR(0x40,0xA3);
+ VGAwCR(0x41,0x7F);
+ VGAwCR(0x42,0x06);
+ VGAwCR(0x43,0x85);
+ VGAwCR(0x44,0x96);
+ VGAwCR(0x45,0x24);
+ VGAwCR(0x46,0xE5);
+ VGAwCR(0x47,0x02);
+ VGAwCR(0x48,0x08);
+ VGAwCR(0x49,0xFF);
+ VGAwCR(0x4A,0x25);
+ VGAwCR(0x4B,0x4F);
+ VGAwCR(0x4C,0x40);
+ VGAwCR(0x4D,0x00);
+ VGAwCR(0x4E,0x44);
+ VGAwCR(0x4F,0x0C);
+ VGAwCR(0x50,0x7A);
+ VGAwCR(0x51,0x56);
+ VGAwCR(0x52,0x00);
+ VGAwCR(0x53,0x5D);
+ VGAwCR(0x54,0x0E);
+ VGAwCR(0x55,0x3B);
+ VGAwCR(0x56,0x2B);
+ VGAwCR(0x57,0x00);
+ VGAwCR(0x58,0x2F);
+ VGAwCR(0x59,0x18);
+ VGAwCR(0x60,0x88);
+ VGAwCR(0x61,0x63);
+ VGAwCR(0x62,0x0B);
+ VGAwCR(0x63,0x69);
+ VGAwCR(0x64,0x1A);
+ break;
+ case 1280:
+#ifdef NOT_DONE
+ VGAwCR(0x40,0x?? );
+ .
+ .
+ .
+ VGAwCR(0x64,0x?? );
+ break;
+#else
+ /* Probe should prevent this case for now */
+ FatalError("1280 panel support incomplete\n");
+#endif
+ }
+ }
+}
+
+static void
+neoRestore(ScrnInfoPtr pScrn, vgaRegPtr VgaReg, NeoRegPtr restore,
+ Bool restoreFonts)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ unsigned char temp;
+ int i;
+
+ vgaHWProtect(pScrn,TRUE); /* Blank the screen */
+
+ VGAwGR(0x09,0x26);
+
+ /* Init the shadow registers if necessary */
+ neoProgramShadowRegs(pScrn, VgaReg, restore);
+
+ VGAwGR(0x15,0x00);
+
+ VGAwGR(0x0A,restore->GeneralLockReg);
+
+ /*
+ * The color mode needs to be set before calling vgaHWRestore
+ * to ensure the DAC is initialized properly.
+ *
+ * NOTE: Make sure we don't change bits make sure we don't change
+ * any reserved bits.
+ */
+ temp = VGArGR(0x90);
+ switch (nPtr->NeoChipset) {
+ case NM2070 :
+ temp &= 0xF0; /* Save bits 7:4 */
+ temp |= (restore->ExtColorModeSelect & ~0xF0);
+ break;
+ case NM2090 :
+ case NM2093 :
+ case NM2097 :
+ case NM2160 :
+ case NM2200 :
+ temp &= 0x70; /* Save bits 6:4 */
+ temp |= (restore->ExtColorModeSelect & ~0x70);
+ break;
+ }
+ VGAwGR(0x90,temp);
+
+ /*
+ * Disable horizontal and vertical graphics and text expansions so
+ * that vgaHWRestore works properly.
+ */
+ temp = VGArGR(0x25);
+ temp &= 0x39;
+ VGAwGR(0x25, temp);
+
+ /*
+ * Sleep for 200ms to make sure that the two operations above have
+ * had time to take effect.
+ */
+ usleep(200000);
+
+ /*
+ * This function handles restoring the generic VGA registers. */
+ vgaHWRestore(pScrn, VgaReg,
+ VGA_SR_MODE | VGA_SR_CMAP | (restoreFonts ? VGA_SR_FONTS : 0));
+
+ VGAwGR(0x0E, restore->ExtCRTDispAddr);
+ VGAwGR(0x0F, restore->ExtCRTOffset);
+ temp = VGArGR(0x10);
+ temp &= 0x0F; /* Save bits 3:0 */
+ temp |= (restore->SysIfaceCntl1 & ~0x0F);
+ VGAwGR(0x10, temp);
+
+ VGAwGR(0x11, restore->SysIfaceCntl2);
+ VGAwGR(0x15, restore->SingleAddrPage);
+ VGAwGR(0x16, restore->DualAddrPage);
+ temp = VGArGR(0x20);
+ switch (nPtr->NeoChipset) {
+ case NM2070 :
+ temp &= 0xFC; /* Save bits 7:2 */
+ temp |= (restore->PanelDispCntlReg1 & ~0xFC);
+ break;
+ case NM2090 :
+ case NM2093 :
+ case NM2097 :
+ case NM2160 :
+ temp &= 0xDC; /* Save bits 7:6,4:2 */
+ temp |= (restore->PanelDispCntlReg1 & ~0xDC);
+ break;
+ case NM2200 :
+ temp &= 0x98; /* Save bits 7,4:3 */
+ temp |= (restore->PanelDispCntlReg1 & ~0x98);
+ break;
+ }
+ VGAwGR(0x20, temp);
+ temp = VGArGR(0x25);
+ temp &= 0x38; /* Save bits 5:3 */
+ temp |= (restore->PanelDispCntlReg2 & ~0x38);
+ VGAwGR(0x25, temp);
+
+ if (nPtr->NeoChipset != NM2070) {
+ temp = VGArGR(0x30);
+ temp &= 0xEF; /* Save bits 7:5 and bits 3:0 */
+ temp |= (restore->PanelDispCntlReg3 & ~0xEF);
+ VGAwGR(0x30, temp);
+ }
+
+ VGAwGR(0x28, restore->PanelVertCenterReg1);
+ VGAwGR(0x29, restore->PanelVertCenterReg2);
+ VGAwGR(0x2a, restore->PanelVertCenterReg3);
+
+ if (nPtr->NeoChipset != NM2070) {
+ VGAwGR(0x32, restore->PanelVertCenterReg4);
+ VGAwGR(0x33, restore->PanelHorizCenterReg1);
+ VGAwGR(0x34, restore->PanelHorizCenterReg2);
+ VGAwGR(0x35, restore->PanelHorizCenterReg3);
+ }
+
+ if (nPtr->NeoChipset == NM2160) {
+ VGAwGR(0x36, restore->PanelHorizCenterReg4);
+ }
+
+ if (nPtr->NeoChipset == NM2200) {
+ VGAwGR(0x36, restore->PanelHorizCenterReg4);
+ VGAwGR(0x37, restore->PanelVertCenterReg5);
+ VGAwGR(0x38, restore->PanelHorizCenterReg5);
+ }
+
+ /* Program VCLK3 if needed. */
+ if (restore->ProgramVCLK) {
+ VGAwGR(0x9B, restore->VCLK3NumeratorLow);
+ if (nPtr->NeoChipset == NM2200) {
+ temp = VGArGR(0x8F);
+ temp &= 0x0F; /* Save bits 3:0 */
+ temp |= (restore->VCLK3NumeratorHigh & ~0x0F);
+ VGAwGR(0x8F, temp);
+ }
+ VGAwGR(0x9F, restore->VCLK3Denominator);
+ }
+
+ if (restore->reg) {
+ VGAwCR(0x25,restore->reg->CR[0x25]);
+ VGAwCR(0x2F,restore->reg->CR[0x2F]);
+ for (i = 0x40; i <= 0x59; i++) {
+ VGAwCR(i, restore->reg->CR[i]);
+ }
+ for (i = 0x60; i <= 0x69; i++) {
+ VGAwCR(i, restore->reg->CR[i]);
+ }
+ for (i = 0x70; i <= NEO_EXT_CR_MAX; i++) {
+ VGAwCR(i, restore->reg->CR[i]);
+ }
+
+ for (i = 0x0a; i <= 0x3f; i++) {
+ VGAwGR(i, restore->reg->GR[i]);
+ }
+ for (i = 0x90; i <= NEO_EXT_GR_MAX; i++) {
+ VGAwGR(i, restore->reg->GR[i]);
+ }
+ xfree(restore->reg);
+ restore->reg = NULL;
+ }
+ /* Program vertical extension register */
+ if (nPtr->NeoChipset == NM2200) {
+ VGAwCR(0x70, restore->VerticalExt);
+ }
+
+
+ vgaHWProtect(pScrn, FALSE); /* Turn on screen */
+
+}
+
+static Bool
+neoModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ NEOACLPtr nAcl = NEOACLPTR(pScrn);
+ int i;
+ int hoffset, voffset;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ NeoRegPtr NeoNew = &nPtr->NeoModeReg;
+ vgaRegPtr NeoStd = &hwp->ModeReg;
+
+ neoUnlock(pScrn);
+
+ /*
+ * This will allocate the datastructure and initialize all of the
+ * generic VGA registers.
+ */
+ if (!vgaHWInit(pScrn, mode))
+ return(FALSE);
+
+ /*
+ * Several registers need to be corrected from the default values
+ * assigned by vgaHWinit().
+ */
+ pScrn->vtSema = TRUE;
+
+ /*
+ * The default value assigned by vgaHW.c is 0x41, but this does
+ * not work for NeoMagic.
+ */
+ NeoStd->Attribute[16] = 0x01;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8 :
+ NeoStd->CRTC[0x13] = pScrn->displayWidth >> 3;
+ NeoNew->ExtCRTOffset = pScrn->displayWidth >> 11;
+ NeoNew->ExtColorModeSelect = 0x11;
+ break;
+ case 15 :
+ case 16 :
+ if ((pScrn->weight.red == 5) &&
+ (pScrn->weight.green == 5) &&
+ (pScrn->weight.blue == 5)) {
+ /* 15bpp */
+ for (i = 0; i < 64; i++) {
+ NeoStd->DAC[i*3+0] = i << 1;
+ NeoStd->DAC[i*3+1] = i << 1;
+ NeoStd->DAC[i*3+2] = i << 1;
+ }
+ NeoNew->ExtColorModeSelect = 0x12;
+ } else {
+ /* 16bpp */
+ for (i = 0; i < 64; i++) {
+ NeoStd->DAC[i*3+0] = i << 1;
+ NeoStd->DAC[i*3+1] = i;
+ NeoStd->DAC[i*3+2] = i << 1;
+ }
+ NeoNew->ExtColorModeSelect = 0x13;
+ }
+ /* 15bpp & 16bpp */
+ NeoStd->CRTC[0x13] = pScrn->displayWidth >> 2;
+ NeoNew->ExtCRTOffset = pScrn->displayWidth >> 10;
+ break;
+ case 24 :
+ for (i = 0; i < 256; i++) {
+ NeoStd->DAC[i*3+0] = i;
+ NeoStd->DAC[i*3+1] = i;
+ NeoStd->DAC[i*3+2] = i;
+ }
+ NeoStd->CRTC[0x13] = (pScrn->displayWidth * 3) >> 3;
+ NeoNew->ExtCRTOffset = (pScrn->displayWidth * 3) >> 11;
+ NeoNew->ExtColorModeSelect = 0x14;
+ break;
+ default :
+ break;
+ }
+
+ NeoNew->ExtCRTDispAddr = 0x10;
+
+ /* Vertical Extension */
+ NeoNew->VerticalExt = (((mode->CrtcVTotal -2) & 0x400) >> 10 )
+ | (((mode->CrtcVDisplay -1) & 0x400) >> 9 )
+ | (((mode->CrtcVSyncStart) & 0x400) >> 8 )
+ | (((mode->CrtcVSyncStart) & 0x400) >> 7 );
+
+ /* Disable read/write bursts if requested. */
+ if (nPtr->onPciBurst) {
+ NeoNew->SysIfaceCntl1 = 0x30;
+ } else {
+ NeoNew->SysIfaceCntl1 = 0x00;
+ }
+
+ /* If they are used, enable linear addressing and/or enable MMIO. */
+ NeoNew->SysIfaceCntl2 = 0x00;
+ if (!nPtr->noLinear)
+ NeoNew->SysIfaceCntl2 |= 0x80;
+ if (!nPtr->noMMIO)
+ NeoNew->SysIfaceCntl2 |= 0x40;
+
+ /* Enable any user specified display devices. */
+ NeoNew->PanelDispCntlReg1 = 0x00;
+ if (nPtr->internDisp) {
+ NeoNew->PanelDispCntlReg1 |= 0x02;
+ }
+ if (nPtr->externDisp) {
+ NeoNew->PanelDispCntlReg1 |= 0x01;
+ }
+
+ /* If the user did not specify any display devices, then... */
+ if (NeoNew->PanelDispCntlReg1 == 0x00) {
+ /* Default to internal (i.e., LCD) only. */
+ NeoNew->PanelDispCntlReg1 |= 0x02;
+ }
+
+ /* If we are using a fixed mode, then tell the chip we are. */
+ switch (mode->HDisplay) {
+ case 1280:
+ NeoNew->PanelDispCntlReg1 |= 0x60;
+ break;
+ case 1024:
+ NeoNew->PanelDispCntlReg1 |= 0x40;
+ break;
+ case 800:
+ NeoNew->PanelDispCntlReg1 |= 0x20;
+ break;
+ case 640:
+ default:
+ break;
+ }
+
+ /* Setup shadow register locking. */
+ switch (NeoNew->PanelDispCntlReg1 & 0x03) {
+ case 0x01 : /* External CRT only mode: */
+ NeoNew->GeneralLockReg = 0x00;
+ /* We need to program the VCLK for external display only mode. */
+ NeoNew->ProgramVCLK = TRUE;
+ break;
+ case 0x02 : /* Internal LCD only mode: */
+ case 0x03 : /* Simultaneous internal/external (LCD/CRT) mode: */
+ NeoNew->GeneralLockReg = 0x01;
+ /* Don't program the VCLK when using the LCD. */
+ NeoNew->ProgramVCLK = FALSE;
+ break;
+ }
+
+ /*
+ * If the screen is to be stretched, turn on stretching for the
+ * various modes.
+ *
+ * OPTION_LCD_STRETCH means stretching should be turned off!
+ */
+ NeoNew->PanelDispCntlReg2 = 0x00;
+ NeoNew->PanelDispCntlReg3 = 0x00;
+ if ((!nPtr->noLcdStretch) &&
+ (NeoNew->PanelDispCntlReg1 & 0x02)) {
+ if (mode->HDisplay == nPtr->NeoPanelWidth) {
+ /*
+ * No stretching required when the requested display width
+ * equals the panel width.
+ */
+ if (nPtr->NeoHWCursorInitialized) nAcl->UseHWCursor = TRUE;
+ } else {
+ switch (mode->HDisplay) {
+ case 320 : /* Needs testing. KEM -- 24 May 98 */
+ case 400 : /* Needs testing. KEM -- 24 May 98 */
+ case 640 :
+ case 800 :
+ case 1024 :
+ NeoNew->PanelDispCntlReg2 |= 0xC6;
+ if (nPtr->NeoHWCursorInitialized) nAcl->UseHWCursor = FALSE;
+ break;
+ default :
+ /* No stretching in these modes. */
+ if (nPtr->NeoHWCursorInitialized) nAcl->UseHWCursor = TRUE;
+ break;
+ }
+ }
+ } else if (mode->Flags & V_DBLSCAN) {
+ if (nPtr->NeoHWCursorInitialized) nAcl->UseHWCursor = FALSE;
+ } else {
+ if (nPtr->NeoHWCursorInitialized) nAcl->UseHWCursor = TRUE;
+ }
+
+ /*
+ * If the screen is to be centerd, turn on the centering for the
+ * various modes.
+ */
+ NeoNew->PanelVertCenterReg1 = 0x00;
+ NeoNew->PanelVertCenterReg2 = 0x00;
+ NeoNew->PanelVertCenterReg3 = 0x00;
+ NeoNew->PanelVertCenterReg4 = 0x00;
+ NeoNew->PanelVertCenterReg5 = 0x00;
+ NeoNew->PanelHorizCenterReg1 = 0x00;
+ NeoNew->PanelHorizCenterReg2 = 0x00;
+ NeoNew->PanelHorizCenterReg3 = 0x00;
+ NeoNew->PanelHorizCenterReg4 = 0x00;
+ NeoNew->PanelHorizCenterReg5 = 0x00;
+
+ if (nPtr->lcdCenter &&
+ (NeoNew->PanelDispCntlReg1 & 0x02)) {
+ if (mode->HDisplay == nPtr->NeoPanelWidth) {
+ /*
+ * No centering required when the requested display width
+ * equals the panel width.
+ */
+ } else {
+ NeoNew->PanelDispCntlReg2 |= 0x01;
+ NeoNew->PanelDispCntlReg3 |= 0x10;
+
+ /* Calculate the horizontal and vertical offsets. */
+ if (nPtr->noLcdStretch) {
+ hoffset = ((nPtr->NeoPanelWidth - mode->HDisplay) >> 4) - 1;
+ voffset = ((nPtr->NeoPanelHeight - mode->VDisplay) >> 1) - 2;
+ } else {
+ /* Stretched modes cannot be centered. */
+ hoffset = 0;
+ voffset = 0;
+ }
+
+ switch (mode->HDisplay) {
+ case 320 : /* Needs testing. KEM -- 24 May 98 */
+ NeoNew->PanelHorizCenterReg3 = hoffset;
+ NeoNew->PanelVertCenterReg2 = voffset;
+ break;
+ case 400 : /* Needs testing. KEM -- 24 May 98 */
+ NeoNew->PanelHorizCenterReg4 = hoffset;
+ NeoNew->PanelVertCenterReg1 = voffset;
+ break;
+ case 640 :
+ NeoNew->PanelHorizCenterReg1 = hoffset;
+ NeoNew->PanelVertCenterReg3 = voffset;
+ break;
+ case 800 :
+ NeoNew->PanelHorizCenterReg2 = hoffset;
+ NeoNew->PanelVertCenterReg4 = voffset;
+ break;
+ case 1024 :
+ NeoNew->PanelHorizCenterReg5 = hoffset;
+ NeoNew->PanelVertCenterReg5 = voffset;
+ break;
+ case 1280 :
+ default :
+ /* No centering in these modes. */
+ break;
+ }
+ }
+ }
+
+ /*
+ * New->reg should be empty. Just in
+ * case it isn't, warn us and clear it anyway.
+ */
+ if (NeoNew->reg) {
+ ErrorF("WARNING: Non-NULL reg in NeoInit: reg=0x%08X\n", NeoNew->reg);
+ xfree(NeoNew->reg);
+ NeoNew->reg = NULL;
+ }
+
+ /*
+ * Calculate the VCLK that most closely matches the requested dot
+ * clock.
+ */
+ neoCalcVCLK(pScrn, mode->SynthClock);
+
+ /* Since we program the clocks ourselves, always use VCLK3. */
+ NeoStd->MiscOutReg |= 0x0C;
+
+ neoRestore(pScrn, NeoStd, NeoNew, FALSE);
+
+ return(TRUE);
+}
+
+/*
+ * neoCalcVCLK --
+ *
+ * Determine the closest clock frequency to the one requested.
+ */
+#define REF_FREQ 14.31818
+#define MAX_N 127
+#define MAX_D 31
+#define MAX_F 1
+
+static void
+neoCalcVCLK(ScrnInfoPtr pScrn, long freq)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+
+ int n, d, f;
+ double f_out;
+ double f_diff;
+ int n_best = 0, d_best = 0, f_best = 0;
+ double f_best_diff = 999999.0;
+ double f_target = freq/1000.0;
+
+ for (f = 0; f <= MAX_F; f++)
+ for (n = 0; n <= MAX_N; n++)
+ for (d = 0; d <= MAX_D; d++) {
+ f_out = (n+1.0)/((d+1.0)*(1<<f))*REF_FREQ;
+ f_diff = abs(f_out-f_target);
+ if (f_diff < f_best_diff) {
+ f_best_diff = f_diff;
+ n_best = n;
+ d_best = d;
+ f_best = f;
+ }
+ }
+
+ if (nPtr->NeoChipset == NM2200) {
+ /* NOT_DONE: We are trying the full range of the 2200 clock.
+ We should be able to try n up to 2047 */
+ nPtr->NeoModeReg.VCLK3NumeratorLow = n_best;
+ nPtr->NeoModeReg.VCLK3NumeratorHigh = (f_best << 7);
+ }
+ else {
+ nPtr->NeoModeReg.VCLK3NumeratorLow = n_best | (f_best << 7);
+ }
+ nPtr->NeoModeReg.VCLK3Denominator = d_best;
+}
+
+/*
+ * NeoDisplayPowerManagementSet --
+ *
+ * Sets VESA Display Power Management Signaling (DPMS) Mode.
+ */
+#ifdef DPMSExtension
+static void
+NeoDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
+ int flags)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ unsigned char SEQ01 = 0;
+ unsigned char LogicPowerMgmt = 0;
+ unsigned char LCD_on = 0;
+
+ if (pScrn->vtSema)
+ return;
+
+ switch (PowerManagementMode) {
+ case DPMSModeOn:
+ /* Screen: On; HSync: On, VSync: On */
+ SEQ01 = 0x00;
+ LogicPowerMgmt = 0x00;
+ if (nPtr->internDisp || ! nPtr->externDisp)
+ LCD_on = 0x02;
+ else
+ LCD_on = 0x00;
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off; HSync: Off, VSync: On */
+ SEQ01 = 0x20;
+ LogicPowerMgmt = 0x10;
+ LCD_on = 0x00;
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off; HSync: On, VSync: Off */
+ SEQ01 = 0x20;
+ LogicPowerMgmt = 0x20;
+ LCD_on = 0x00;
+ break;
+ case DPMSModeOff:
+ /* Screen: Off; HSync: Off, VSync: Off */
+ SEQ01 = 0x20;
+ LogicPowerMgmt = 0x30;
+ LCD_on = 0x00;
+ break;
+ }
+
+ /* Turn the screen on/off */
+ outb(0x3C4, 0x01);
+ SEQ01 |= inb(0x3C5) & ~0x20;
+ outb(0x3C5, SEQ01);
+
+ /* Turn the LCD on/off */
+ LCD_on |= VGArGR(0x20) & ~0x02;
+ VGAwGR(0x20, LCD_on);
+
+ /* Set the DPMS mode */
+ LogicPowerMgmt |= 0x80;
+ LogicPowerMgmt |= VGArGR(0x01) & ~0xF0;
+ VGAwGR(0x01,LogicPowerMgmt);
+}
+#endif
+
+static unsigned int
+neo_ddc1Read(ScrnInfoPtr pScrn)
+{
+ register vgaHWPtr hwp = VGAHWPTR(pScrn);
+#if 0
+ register unsigned int ST01reg = ((NEOPtr)pScrn->driverPrivate)->vgaIOBase
+ + 0x0A;
+#endif
+ register unsigned int tmp;
+
+#if 0
+ while(inb(ST01reg)&0x8){};
+ while(!(inb(ST01reg)&0x8)) {};
+#endif
+ while (hwp->readST01(hwp)&0x8) {};
+ while (!hwp->readST01(hwp)&0x8) {};
+
+ tmp = (VGArGR(0xA1) & 0x08);
+
+ return (tmp);
+}
+
+static void
+neo_ddc1(int scrnIndex)
+{
+ vgaHWPtr hwp = VGAHWPTR(xf86Screens[scrnIndex]);
+ unsigned int reg1, reg2, reg3;
+
+ /* initialize chipset */
+ reg1 = VGArCR(0x21);
+ reg2 = VGArCR(0x1D);
+ reg3 = VGArCR(0x1A);
+ VGAwCR(0x21,0x00);
+ VGAwCR(0x1D,0x01); /* some Voodoo */
+ VGAwGR(0xA1,0x2F);
+ xf86PrintEDID(xf86DoEDID_DDC1(scrnIndex,vgaHWddc1SetSpeed,neo_ddc1Read));
+ /* undo initialization */
+ VGAwCR(0x21,reg1);
+ VGAwCR(0x1D,reg2);
+}
+
+static void
+neoRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ NEOPtr nPtr = NEOPTR(pScrn);
+ int width, height, Bpp, FBPitch;
+ unsigned char *src = NULL, *dst = NULL;
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ FBPitch = pScrn->displayWidth * Bpp;
+
+ while(num--) {
+ width = (pbox->x2 - pbox->x1) * Bpp;
+ height = pbox->y2 - pbox->y1;
+ src = nPtr->ShadowPtr + (pbox->y1 * nPtr->ShadowPitch) +
+ (pbox->x1 * Bpp);
+ dst = nPtr->NeoFbBase + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
+
+ while(height--) {
+ memcpy(dst, src, width);
+ dst += FBPitch;
+ src += nPtr->ShadowPitch;
+ }
+
+ pbox++;
+ }
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c
new file mode 100644
index 000000000..e7f74f327
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c
@@ -0,0 +1,100 @@
+/**********************************************************************
+Copyright 1998, 1999 by Precision Insight, Inc., Cedar Park, Texas.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Precision Insight not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission. Precision Insight
+and its suppliers make no representations about the suitability of this
+software for any purpose. It is provided "as is" without express or
+implied warranty.
+
+PRECISION INSIGHT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+**********************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_i2c.c,v 1.2 1999/06/27 14:08:10 dawes Exp $ */
+
+/*
+ * The original Precision Insight driver for
+ * XFree86 v.3.3 has been sponsored by Red Hat.
+ *
+ * Authors:
+ * Jens Owen (jens@precisioninsight.com)
+ * Kevin E. Martin (kevin@precisioninsight.com)
+ *
+ * Port to Xfree86 v.4.0
+ * 1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE)
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+#include "vgaHW.h"
+
+#include "neo.h"
+
+static void
+neo_I2CPutBits(I2CBusPtr b, int clock, int data) {
+ vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]);
+ unsigned int reg = 0xF0;
+
+ VGAwCR(0x21,0x00);
+ VGAwCR(0x1D,0x01);
+
+ if(clock) reg |= 1;
+ if(data) reg |= 0x4;
+ VGAwGR(0xA1,reg);
+ /*ErrorF("neo_I2CPutBits: %d %d\n", clock, data); */
+}
+
+static void
+neo_I2CGetBits(I2CBusPtr b, int *clock, int *data) {
+ unsigned int reg;
+ vgaHWPtr hwp = VGAHWPTR(xf86Screens[b->scrnIndex]);
+
+ reg = VGArGR(0xA1);
+ *clock = 1 /* (reg & 0x?? ) */;
+ *data = (reg & 0x8) != 0;
+ /*ErrorF("neo_I2CGetBits: %d %d\n", *clock, *data);*/
+}
+
+Bool
+neo_I2CInit(ScrnInfoPtr pScrn)
+{
+ NEOPtr pNeo = NEOPTR(pScrn);
+ I2CBusPtr I2CPtr;
+
+
+ I2CPtr = xf86CreateI2CBusRec();
+ if(!I2CPtr) return FALSE;
+
+ pNeo->I2C = I2CPtr;
+
+ I2CPtr->BusName = "I2C bus";
+ I2CPtr->scrnIndex = pScrn->scrnIndex;
+ I2CPtr->I2CPutBits = neo_I2CPutBits;
+ I2CPtr->I2CGetBits = neo_I2CGetBits;
+
+ if (!xf86I2CBusInit(I2CPtr))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h
new file mode 100644
index 000000000..fdb4d44c1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h
@@ -0,0 +1,63 @@
+/**********************************************************************
+Copyright 1998, 1999 by Precision Insight, Inc., Cedar Park, Texas.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Precision Insight not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission. Precision Insight
+and its suppliers make no representations about the suitability of this
+software for any purpose. It is provided "as is" without express or
+implied warranty.
+
+PRECISION INSIGHT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+**********************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_macros.h,v 1.1 1999/04/17 07:06:27 dawes Exp $ */
+
+/*
+ * The original Precision Insight driver for
+ * XFree86 v.3.3 has been sponsored by Red Hat.
+ *
+ * Authors:
+ * Jens Owen (jens@precisioninsight.com)
+ * Kevin E. Martin (kevin@precisioninsight.com)
+ *
+ * Port to Xfree86 v.4.0
+ * 1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE)
+ */
+
+#define WAIT_FB_FIFO_EMPTY() { \
+ while( INREG(NEOREG_BLTSTAT) & NEO_BS0_FIFO_PEND); \
+ }
+
+#define WAIT_BLT_DONE() { \
+ while( INREG(NEOREG_BLTSTAT) & NEO_BS0_BLT_BUSY); \
+ }
+
+#define WAIT_ENGINE_IDLE() { \
+ WAIT_BLT_DONE(); \
+ }
+
+#ifdef NOT_DONE
+#define WAIT_FIFO(n) { \
+ while( NeoFifoCount < (n)) { \
+ NeoFifoCount = (INREG(NEOREG_BLTSTAT) >> 8); \
+ } \
+ NeoFifoCount -= (n); \
+ }
+#else
+#define WAIT_FIFO(n) { \
+ WAIT_ENGINE_IDLE(); \
+ }
+#endif
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h
new file mode 100644
index 000000000..676719f75
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h
@@ -0,0 +1,117 @@
+/**********************************************************************
+Copyright 1998, 1999 by Precision Insight, Inc., Cedar Park, Texas.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, distribute, and sell this software and
+its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Precision Insight not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission. Precision Insight
+and its suppliers make no representations about the suitability of this
+software for any purpose. It is provided "as is" without express or
+implied warranty.
+
+PRECISION INSIGHT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+**********************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/neomagic/neo_reg.h,v 1.1 1999/04/17 07:06:29 dawes Exp $ */
+
+/*
+ * The original Precision Insight driver for
+ * XFree86 v.3.3 has been sponsored by Red Hat.
+ *
+ * Authors:
+ * Jens Owen (jens@precisioninsight.com)
+ * Kevin E. Martin (kevin@precisioninsight.com)
+ *
+ * Port to Xfree86 v.4.0
+ * 1998, 1999 by Egbert Eich (Egbert.Eich@Physik.TU-Darmstadt.DE)
+ */
+
+#define NEOREG_BLTSTAT 0x00
+#define NEOREG_BLTCNTL 0x04
+#define NEOREG_XPCOLOR 0x08
+#define NEOREG_FGCOLOR 0x0c
+#define NEOREG_BGCOLOR 0x10
+#define NEOREG_PITCH 0x14
+#define NEOREG_CLIPLT 0x18
+#define NEOREG_CLIPRB 0x1c
+#define NEOREG_SRCBITOFF 0x20
+#define NEOREG_SRCSTARTOFF 0x24
+#define NEOREG_DSTSTARTOFF 0x2c
+#define NEOREG_XYEXT 0x30
+#define NEOREG_PAGECNTL 0x80
+#define NEOREG_PAGEBASE 0x84
+#define NEOREG_POSTBASE 0x88
+#define NEOREG_POSTPTR 0x8c
+#define NEOREG_DATAPTR 0x90
+#define NEOREG_BLTMODE 0x02
+
+#define NEO_BS0_BLT_BUSY 0x00000001
+#define NEO_BS0_FIFO_AVAIL 0x00000002
+#define NEO_BS0_FIFO_PEND 0x00000004
+
+#define NEO_BC0_DST_Y_DEC 0x00000001
+#define NEO_BC0_X_DEC 0x00000002
+#define NEO_BC0_SRC_TRANS 0x00000004
+#define NEO_BC0_SRC_IS_FG 0x00000008
+#define NEO_BC0_SRC_Y_DEC 0x00000010
+#define NEO_BC0_FILL_PAT 0x00000020
+#define NEO_BC0_SRC_MONO 0x00000040
+#define NEO_BC0_SYS_TO_VID 0x00000080
+
+#define NEO_BC1_DEPTH8 0x00000100
+#define NEO_BC1_DEPTH16 0x00000200
+#define NEO_BC1_X_320 0x00000400
+#define NEO_BC1_X_640 0x00000800
+#define NEO_BC1_X_800 0x00000c00
+#define NEO_BC1_X_1024 0x00001000
+#define NEO_BC1_X_1152 0x00001400
+#define NEO_BC1_X_1280 0x00001800
+#define NEO_BC1_X_1600 0x00001c00
+#define NEO_BC1_DST_TRANS 0x00002000
+#define NEO_BC1_MSTR_BLT 0x00004000
+#define NEO_BC1_FILTER_Z 0x00008000
+
+#define NEO_BC2_WR_TR_DST 0x00800000
+
+#define NEO_BC3_SRC_XY_ADDR 0x01000000
+#define NEO_BC3_DST_XY_ADDR 0x02000000
+#define NEO_BC3_CLIP_ON 0x04000000
+#define NEO_BC3_FIFO_EN 0x08000000
+#define NEO_BC3_BLT_ON_ADDR 0x10000000
+#define NEO_BC3_SKIP_MAPPING 0x80000000
+
+#define NEO_MODE1_DEPTH8 0x0100
+#define NEO_MODE1_DEPTH16 0x0200
+#define NEO_MODE1_DEPTH24 0x0300
+#define NEO_MODE1_X_320 0x0400
+#define NEO_MODE1_X_640 0x0800
+#define NEO_MODE1_X_800 0x0c00
+#define NEO_MODE1_X_1024 0x1000
+#define NEO_MODE1_X_1152 0x1400
+#define NEO_MODE1_X_1280 0x1800
+#define NEO_MODE1_X_1600 0x1c00
+#define NEO_MODE1_BLT_ON_ADDR 0x2000
+
+#define NEOREG_CURSCNTL (nPtr->NeoCursorOffset + 0x00)
+#define NEOREG_CURSX (nPtr->NeoCursorOffset + 0x04)
+#define NEOREG_CURSY (nPtr->NeoCursorOffset + 0x08)
+#define NEOREG_CURSBGCOLOR (nPtr->NeoCursorOffset + 0x0c)
+#define NEOREG_CURSFGCOLOR (nPtr->NeoCursorOffset + 0x10)
+#define NEOREG_CURSMEMPOS (nPtr->NeoCursorOffset + 0x14)
+
+#define NEO_CURS_DISABLE 0x00000000
+#define NEO_CURS_ENABLE 0x00000001
+#define NEO_ICON64_ENABLE 0x00000008
+#define NEO_ICON128_ENABLE 0x0000000c
+#define NEO_ICON_BLANK 0x00000010
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/nv/Imakefile
new file mode 100644
index 000000000..275824cab
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/Imakefile
@@ -0,0 +1,68 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/Imakefile,v 1.6 1999/08/14 10:49:50 dawes Exp $
+XCOMM
+XCOMM This is an Imakefile for the NVIDIA driver.
+XCOMM
+
+
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/Imakefile,v 1.6 1999/08/14 10:49:50 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = nv_driver.c nv_dac.c nv_setup.c nv_cursor.c nv_xaa.c nv_dga.c riva_hw.c
+
+XCOMM nv1driver.c nv1accel.c nv1setup.c \
+XCOMM nv1cursor.c riva_hw.c riva_xaa.c
+
+OBJS = nv_driver.o nv_dac.o nv_setup.o nv_cursor.o nv_xaa.o nv_dga.o riva_hw.o
+
+XCOMM nv1driver.o nv1accel.o nv1setup.o \
+XCOMM nv1cursor.o riva_hw.o riva_xaa.o
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa -I$(XF86SRC)/rac \
+ -I$(XF86SRC)/vgahw -I$(XF86SRC)/fbdevhw \
+ -I$(XF86SRC)/ramdac -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
+ -I$(SERVERSRC)/Xext -I$(XF86SRC)/xf8_32bpp\
+ -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(XF86SRC)/xf24_32bpp -I$(XF86SRC)/shadowfb -I$(EXTINCSRC)
+#endif
+DEFINES = -DPSZ=8
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget(nv,$(OBJS))
+
+InstallObjectModule(nv,$(MODULEDIR),drivers)
+
+#if !defined(XF86DriverSDK)
+CppManTarget(nv,)
+InstallModuleManPage(nv)
+#endif
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/nv)
+InstallDriverSDKNonExecFile(nv_const.h,$(DRIVERSDKDIR)/drivers/nv)
+InstallDriverSDKNonExecFile(nv_cursor.c,$(DRIVERSDKDIR)/drivers/nv)
+InstallDriverSDKNonExecFile(nv_dac.c,$(DRIVERSDKDIR)/drivers/nv)
+InstallDriverSDKNonExecFile(nv_dga.c,$(DRIVERSDKDIR)/drivers/nv)
+InstallDriverSDKNonExecFile(nv_driver.c,$(DRIVERSDKDIR)/drivers/nv)
+InstallDriverSDKNonExecFile(nv_include.h,$(DRIVERSDKDIR)/drivers/nv)
+InstallDriverSDKNonExecFile(nv_proto.h,$(DRIVERSDKDIR)/drivers/nv)
+InstallDriverSDKNonExecFile(nv_setup.c,$(DRIVERSDKDIR)/drivers/nv)
+InstallDriverSDKNonExecFile(nv_type.h,$(DRIVERSDKDIR)/drivers/nv)
+InstallDriverSDKNonExecFile(nv_xaa.c,$(DRIVERSDKDIR)/drivers/nv)
+InstallDriverSDKNonExecFile(nvreg.h,$(DRIVERSDKDIR)/drivers/nv)
+InstallDriverSDKNonExecFile(nvvga.h,$(DRIVERSDKDIR)/drivers/nv)
+InstallDriverSDKNonExecFile(riva_hw.c,$(DRIVERSDKDIR)/drivers/nv)
+InstallDriverSDKNonExecFile(riva_hw.h,$(DRIVERSDKDIR)/drivers/nv)
+InstallDriverSDKNonExecFile(riva_tbl.h,$(DRIVERSDKDIR)/drivers/nv)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv.cpp b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv.cpp
new file mode 100644
index 000000000..4f748aa57
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv.cpp
@@ -0,0 +1,61 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv.cpp,v 1.3 1999/08/28 09:01:06 dawes Exp $
+.TH NV __drivermansuffix__ "Version 3.9.16" "XFree86"
+.SH NAME
+nv \-NVIDIA video driver
+.SH SYNOPSIS
+.B "Section ""Device"""
+.br
+.BI " Identifier """ devname """"
+.br
+.B " Driver ""nv"""
+.br
+\ \ ...
+.br
+.B EndSection
+.SH DESCRIPTION
+.B nv
+is an XFree86 driver for NVIDIA video cards. The driver is fully
+accelerated, and provides support for the following framebuffer depths:
+8, 15, 16 and 24. All
+visual types are supported for depth 8, and both TrueColor and DirectColor
+visuals are supported for the other depths. Multi-head configurations
+are supported.
+.SH SUPPORTED HARDWARE
+The
+.B nv
+driver supports PCI and AGP video cards based on the following NVIDIA chips:
+.TP 12
+.B RIVA 128
+NV3
+.TP 12
+.B RIVA TNT
+NV4
+.TP 12
+.B RIVA TNT2
+NV5
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details. This section only covers configuration details specific to this
+driver.
+.PP
+The driver auto-detects the chipset type and the amount of video memory
+present for all chips.
+.PP
+The following driver
+.B Options
+are supported:
+.TP
+.BI "Option ""HWCursor"" """ boolean """
+Enable or disable the HW cursor. Default: on.
+.TP
+.BI "Option ""NoAccel"" """ boolean """
+Disable or enable acceleration. Default: acceleration is enabled.
+.TP
+.BI "Option ""UseFBDev"" """ boolean """
+Enable or disable use of on OS-specific fb interface (and is not supported
+on all OSs). See fbdevhw(__drivermansuffix__) for further information.
+Default: off.
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(1)
+.SH AUTHORS
+Authors include: David McKay, Jarno Paananen, Chas Inman, Dave Schmenk
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_const.h b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_const.h
new file mode 100644
index 000000000..aa92f4ff5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_const.h
@@ -0,0 +1,20 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_const.h,v 1.2 1999/08/01 12:17:40 dawes Exp $ */
+
+#ifndef __NV_CONST_H__
+#define __NV_CONST_H__
+
+#define VERSION 4000
+#define NV_NAME "NV"
+#define NV_DRIVER_NAME "nv"
+#define NV_MAJOR_VERSION 1
+#define NV_MINOR_VERSION 0
+#define NV_PATCHLEVEL 0
+
+#ifdef DEBUG_PRINT
+#define DEBUG(x) x
+#else
+#define DEBUG(x)
+#endif
+
+#endif /* __NV_CONST_H__ */
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_cursor.c
new file mode 100644
index 000000000..cbd6b5c6d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_cursor.c
@@ -0,0 +1,193 @@
+/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
+/*
+ * Copyright 1996-1997 David J. McKay
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * DAVID J. MCKAY 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.
+ */
+
+/* Rewritten with reference from mga driver and 3.3.4 NVIDIA driver by
+ Jarno Paananen <jpaana@s2.org> */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_cursor.c,v 1.1 1999/08/01 07:20:55 dawes Exp $ */
+
+#include "nv_include.h"
+
+#include "nvreg.h"
+#include "nvvga.h"
+
+/****************************************************************************\
+* *
+* XAA HW Cursor Entrypoints *
+* *
+\****************************************************************************/
+/*
+ * RIVA supports full colour cursors as X1R5G5B5. Upper bit is the XOR
+ * bit. All 0's equals transparency.
+ */
+#define MAX_CURS 32
+#define TRANSPARENT_PIXEL 0
+#define ConvertToRGB555(c) \
+( (( c & 0xf80000 ) >> 9 ) | (( c & 0xf800 ) >> 6 ) | (( c & 0xf8) >> 3 ) |0x8000)
+
+/*
+ * Internal colors
+ */
+static unsigned short foreColor, backColor; /* Color for cursor in RGB555 */
+static unsigned bitimage[MAX_CURS*2]; /* Previous image */
+
+static void ConvertCursor(unsigned int* src, unsigned short *dst)
+{
+ int i, j, b, m;
+
+ for ( i = 0; i < MAX_CURS; i++ )
+ {
+ b = *src++;
+ m = *src++;
+ for ( j = 0; j < MAX_CURS; j++ )
+ {
+ if ( m & 1 )
+ *dst = ( b & 1) ? foreColor : backColor;
+ else
+ *dst = TRANSPARENT_PIXEL;
+
+ dst++;
+ b >>= 1;
+ m >>= 1;
+ }
+ }
+}
+
+static void
+LoadCursor(ScrnInfoPtr pScrn, unsigned short *tmp)
+{
+ int *image, i, numInts, save;
+ NVPtr pNv = NVPTR(pScrn);
+
+ numInts = (MAX_CURS*MAX_CURS*2) / sizeof(int);
+ image = (int *)tmp;
+ save = pNv->riva.ShowHideCursor(&pNv->riva, 0); /* Hide cursor, saving its current display state */
+ for (i = 0; i < numInts; i++)
+ pNv->riva.CURSOR[i] = image[i];
+ pNv->riva.ShowHideCursor(&pNv->riva, save); /* Restore cursor display state */
+}
+
+static void
+NVLoadCursorImage( ScrnInfoPtr pScrn, unsigned char *src )
+{
+ unsigned short tmp[MAX_CURS*MAX_CURS];
+
+ /* Copy image for color changes */
+ memcpy(bitimage, src, MAX_CURS*2*4);
+
+ ConvertCursor((unsigned int*)src, tmp);
+ LoadCursor(pScrn, tmp);
+}
+
+
+/*
+ * This function should display a new cursor at a new position.
+ */
+static void
+NVSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ if (pScrn->vtSema)
+ {
+ pNv->riva.ShowHideCursor(&pNv->riva, 0);
+ if ( pScrn->currentMode->Flags & V_DBLSCAN)
+ y *= 2;
+
+ *(pNv->riva.CURSORPOS) = (x & 0xFFFF) | (y << 16);
+ pNv->riva.ShowHideCursor(&pNv->riva, 1);
+ }
+}
+
+static void
+NVSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ unsigned short fore, back;
+
+ if (pScrn->vtSema)
+ {
+ fore = ConvertToRGB555(fg);
+ back = ConvertToRGB555(bg);
+
+ if (foreColor != fore || backColor != back)
+ {
+ unsigned short tmp[MAX_CURS*MAX_CURS];
+
+ foreColor = fore;
+ backColor = back;
+
+ ConvertCursor(bitimage, tmp);
+ LoadCursor(pScrn, tmp);
+ }
+ }
+}
+
+
+static void
+NVShowCursor(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ /* Enable cursor - X-Windows mode */
+ pNv->riva.ShowHideCursor(&pNv->riva, 1);
+}
+
+static void
+NVHideCursor(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ /* Disable cursor */
+ pNv->riva.ShowHideCursor(&pNv->riva, 0);
+}
+
+static Bool
+NVUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ return TRUE;
+}
+
+Bool
+NVCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVCursorInit\n"));
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pNv->CursorInfoRec = infoPtr;
+
+ infoPtr->MaxWidth = MAX_CURS;
+ infoPtr->MaxHeight = MAX_CURS;
+ infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32;
+ infoPtr->SetCursorColors = NVSetCursorColors;
+ infoPtr->SetCursorPosition = NVSetCursorPosition;
+ infoPtr->LoadCursorImage = NVLoadCursorImage;
+ infoPtr->HideCursor = NVHideCursor;
+ infoPtr->ShowCursor = NVShowCursor;
+ infoPtr->UseHWCursor = NVUseHWCursor;
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c
new file mode 100644
index 000000000..43940ac51
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c
@@ -0,0 +1,210 @@
+/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
+/*
+ * Copyright 1996-1997 David J. McKay
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * DAVID J. MCKAY 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.
+ */
+
+/* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen
+ <jpaana@s2.org> */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c,v 1.2 1999/08/14 10:49:50 dawes Exp $ */
+
+#include "nv_include.h"
+
+#include "nvreg.h"
+#include "nvvga.h"
+
+Bool
+NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ int i;
+ int horizDisplay = (mode->CrtcHDisplay/8) - 1;
+ int horizStart = (mode->CrtcHSyncStart/8) - 1;
+ int horizEnd = (mode->CrtcHSyncEnd/8) - 1;
+ int horizTotal = (mode->CrtcHTotal/8) - 1;
+ int vertDisplay = mode->CrtcVDisplay - 1;
+ int vertStart = mode->CrtcVSyncStart - 1;
+ int vertEnd = mode->CrtcVSyncEnd - 1;
+ int vertTotal = mode->CrtcVTotal - 2;
+
+ NVPtr pNv = NVPTR(pScrn);
+ NVRegPtr nvReg = &pNv->ModeReg;
+ vgaRegPtr pVga;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVDACInit\n"));
+
+ /*
+ * This will initialize all of the generic VGA registers.
+ */
+ if (!vgaHWInit(pScrn, mode))
+ return(FALSE);
+
+ pVga = &VGAHWPTR(pScrn)->ModeReg;
+
+ /*
+ * Set all CRTC values.
+ */
+
+ pVga->CRTC[0x0] = Set8Bits(horizTotal - 4);
+ pVga->CRTC[0x1] = Set8Bits(horizDisplay);
+ pVga->CRTC[0x2] = Set8Bits(horizDisplay);
+ pVga->CRTC[0x3] = SetBitField(horizTotal,4:0,4:0)
+ | SetBit(7);
+ pVga->CRTC[0x4] = Set8Bits(horizStart);
+ pVga->CRTC[0x5] = SetBitField(horizTotal,5:5,7:7)
+ | SetBitField(horizEnd,4:0,4:0);
+ pVga->CRTC[0x6] = SetBitField(vertTotal,7:0,7:0);
+ pVga->CRTC[0x7] = SetBitField(vertTotal,8:8,0:0)
+ | SetBitField(vertDisplay,8:8,1:1)
+ | SetBitField(vertStart,8:8,2:2)
+ | SetBitField(vertDisplay,8:8,3:3)
+ | SetBit(4)
+ | SetBitField(vertTotal,9:9,5:5)
+ | SetBitField(vertDisplay,9:9,6:6)
+ | SetBitField(vertStart,9:9,7:7);
+ pVga->CRTC[0x9] = SetBitField(vertDisplay,9:9,5:5)
+ | SetBit(6)
+ | ((mode->Flags & V_DBLSCAN) ? 0x80 : 0x00);
+ pVga->CRTC[0x10] = Set8Bits(vertStart);
+ pVga->CRTC[0x11] = SetBitField(vertEnd,3:0,3:0) | SetBit(5);
+ pVga->CRTC[0x12] = Set8Bits(vertDisplay);
+ pVga->CRTC[0x13] = ((pScrn->displayWidth/8)*(pScrn->bitsPerPixel/8)) & 0xFF;
+ pVga->CRTC[0x15] = Set8Bits(vertDisplay);
+ pVga->CRTC[0x16] = Set8Bits(vertTotal + 1);
+
+ /*
+ * Initialize DAC palette.
+ */
+ if(pScrn->bitsPerPixel != 8 )
+ {
+ if (pNv->riva.Architecture == 3)
+ for (i = 0; i < 256; i++)
+ {
+ pVga->DAC[i*3] = i >> 2;
+ pVga->DAC[(i*3)+1] = i >> 2;
+ pVga->DAC[(i*3)+2] = i >> 2;
+ }
+ else
+ for (i = 0; i < 256; i++)
+ {
+ pVga->DAC[i*3] = i;
+ pVga->DAC[(i*3)+1] = i;
+ pVga->DAC[(i*3)+2] = i;
+ }
+ }
+ /*
+ * Calculate the extended registers.
+ */
+ switch (pScrn->bitsPerPixel)
+ {
+ case 8:
+ i = 8;
+ break;
+ case 15:
+ case 16:
+ i = (pScrn->weight.green == 6) ? 16 : 15;
+ break;
+ default:
+ i = 32;
+ }
+
+ pNv->riva.CalcStateExt(&pNv->riva,
+ nvReg,
+ i, /* BPP */
+ pScrn->displayWidth,
+ mode->CrtcHDisplay,
+ horizDisplay,
+ horizStart,
+ horizEnd,
+ horizTotal,
+ pScrn->virtualY,
+ vertDisplay,
+ vertStart,
+ vertEnd,
+ vertTotal,
+ mode->Clock);
+
+ return (TRUE);
+}
+
+void
+NVDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, NVRegPtr nvReg,
+ Bool restoreFonts)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVDACRestore\n"));
+ pNv->riva.LoadStateExt(&pNv->riva, nvReg);
+ vgaHWRestore(pScrn, vgaReg,
+ VGA_SR_MODE | (restoreFonts? VGA_SR_FONTS : 0));
+}
+
+/*
+ * NVRamdacInit
+ */
+void
+NVRamdacInit(ScrnInfoPtr pScrn)
+{
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVRamdacInit\n"));
+}
+
+/*
+ * NVDACSave
+ *
+ * This function saves the video state.
+ */
+void
+NVDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, NVRegPtr nvReg,
+ Bool saveFonts)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVDACSave\n"));
+ vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | (saveFonts? VGA_SR_FONTS : 0));
+ pNv->riva.UnloadStateExt(&pNv->riva, nvReg);
+}
+
+void
+NVDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
+ VisualPtr pVisual )
+{
+ NVPtr pNv = NVPTR(pScrn);
+ int i, index;
+ vgaRegPtr pVga;
+
+ pVga = &VGAHWPTR(pScrn)->ModeReg;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVDACLoadPalette\n"));
+ for(i = 0; i < numColors; i++) {
+ index = indices[i];
+ if (pNv->riva.Architecture == 3)
+ {
+ pVga->DAC[index*3] = colors[index].red >> 2;
+ pVga->DAC[(index*3)+1] = colors[index].green >> 2;
+ pVga->DAC[(index*3)+2] = colors[index].blue >> 2;
+ }
+ else
+ {
+ pVga->DAC[index*3] = colors[index].red;
+ pVga->DAC[(index*3)+1] = colors[index].green;
+ pVga->DAC[(index*3)+2] = colors[index].blue;
+ }
+ }
+ vgaHWRestore(pScrn, pVga, VGA_SR_CMAP);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dga.c
new file mode 100644
index 000000000..f1c6380e6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dga.c
@@ -0,0 +1,267 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dga.c,v 1.2 1999/08/14 10:49:50 dawes Exp $ */
+
+/* Straight theft from mga-driver */
+
+#include "nv_include.h"
+#include "xaalocal.h"
+#include "dgaproc.h"
+
+
+static Bool NV_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
+ int *, int *, int *);
+static Bool NV_SetMode(ScrnInfoPtr, DGAModePtr);
+static int NV_GetViewport(ScrnInfoPtr);
+static void NV_SetViewport(ScrnInfoPtr, int, int, int);
+static void NV_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
+static void NV_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+static void NV_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
+ unsigned long);
+
+static
+DGAFunctionRec NV_DGAFuncs = {
+ NV_OpenFramebuffer,
+ NULL,
+ NV_SetMode,
+ NV_SetViewport,
+ NV_GetViewport,
+ NVSync,
+ NV_FillRect,
+ NV_BlitRect,
+ NV_BlitTransRect
+};
+
+
+Bool
+NVDGAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+ DGAModePtr modes = NULL, newmodes = NULL, currentMode;
+ DisplayModePtr pMode, firstMode;
+ int Bpp = pScrn->bitsPerPixel >> 3;
+ int num = 0;
+ Bool oneMore;
+
+ pMode = firstMode = pScrn->modes;
+
+ while(pMode) {
+ /* The NV driver wasn't designed with switching depths in
+ mind. Subsequently, large chunks of it will probably need
+ to be rewritten to accommodate depth changes in DGA mode */
+
+ if(0 /*pScrn->displayWidth != pMode->HDisplay*/) {
+ newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec));
+ oneMore = TRUE;
+ } else {
+ newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec));
+ oneMore = FALSE;
+ }
+
+ if(!newmodes) {
+ xfree(modes);
+ return FALSE;
+ }
+ modes = newmodes;
+
+SECOND_PASS:
+
+ currentMode = modes + num;
+ num++;
+
+ currentMode->mode = pMode;
+ currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
+ if(!pNv->NoAccel)
+ currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
+ if(pMode->Flags & V_DBLSCAN)
+ currentMode->flags |= DGA_DOUBLESCAN;
+ if(pMode->Flags & V_INTERLACE)
+ currentMode->flags |= DGA_INTERLACED;
+ currentMode->byteOrder = pScrn->imageByteOrder;
+ currentMode->depth = pScrn->depth;
+ currentMode->bitsPerPixel = pScrn->bitsPerPixel;
+ currentMode->red_mask = pScrn->mask.red;
+ currentMode->green_mask = pScrn->mask.green;
+ currentMode->blue_mask = pScrn->mask.blue;
+ currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor;
+ currentMode->viewportWidth = pMode->HDisplay;
+ currentMode->viewportHeight = pMode->VDisplay;
+ currentMode->xViewportStep = (3 - pNv->BppShift);
+ currentMode->yViewportStep = 1;
+ currentMode->viewportFlags = DGA_FLIP_RETRACE;
+ currentMode->offset = pNv->YDstOrg * Bpp;
+ currentMode->address = pNv->FbStart;
+
+ if(oneMore) { /* first one is narrow width */
+ currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L;
+ currentMode->imageWidth = pMode->HDisplay;
+ currentMode->imageHeight = pNv->FbUsableSize /
+ currentMode->bytesPerScanline;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+ oneMore = FALSE;
+ goto SECOND_PASS;
+ } else {
+ currentMode->bytesPerScanline =
+ ((pScrn->displayWidth * Bpp) + 3) & ~3L;
+ currentMode->imageWidth = pScrn->displayWidth;
+ currentMode->imageHeight = pNv->FbUsableSize /
+ currentMode->bytesPerScanline;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+ }
+
+ pMode = pMode->next;
+ if(pMode == firstMode)
+ break;
+ }
+
+ pNv->numDGAModes = num;
+ pNv->DGAModes = modes;
+
+ return DGAInit(pScreen, &NV_DGAFuncs, modes, num);
+}
+
+
+static Bool
+NV_SetMode(
+ ScrnInfoPtr pScrn,
+ DGAModePtr pMode
+){
+ static int OldDisplayWidth[MAXSCREENS];
+ int index = pScrn->pScreen->myNum;
+
+ NVPtr pNv = NVPTR(pScrn);
+
+ if(!pMode) { /* restore the original mode */
+ /* put the ScreenParameters back */
+
+ pScrn->displayWidth = OldDisplayWidth[index];
+
+ NVSwitchMode(index, pScrn->currentMode, 0);
+ pNv->DGAactive = FALSE;
+ } else {
+ if(!pNv->DGAactive) { /* save the old parameters */
+ OldDisplayWidth[index] = pScrn->displayWidth;
+
+ pNv->DGAactive = TRUE;
+ }
+
+ pScrn->displayWidth = pMode->bytesPerScanline /
+ (pMode->bitsPerPixel >> 3);
+
+ NVSwitchMode(index, pMode->mode, 0);
+ }
+
+ return TRUE;
+}
+
+
+
+static int
+NV_GetViewport(
+ ScrnInfoPtr pScrn
+){
+ NVPtr pNv = NVPTR(pScrn);
+
+ return pNv->DGAViewportStatus;
+}
+
+static void
+NV_SetViewport(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int flags
+){
+ NVPtr pNv = NVPTR(pScrn);
+
+ NVSync(pScrn);
+
+ if ( flags & DGA_FLIP_RETRACE )
+ {
+ /* Wait for retrace */
+ while ( !(inb(0x3da) & 8) );
+ }
+
+ NVAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
+ pNv->DGAViewportStatus = 0;
+}
+
+static void
+NV_FillRect (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned long color
+){
+ NVPtr pNv = NVPTR(pScrn);
+
+ if(pNv->AccelInfoRec) {
+ (*pNv->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
+ (*pNv->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ SET_SYNC_FLAG(pNv->AccelInfoRec);
+ }
+}
+
+static void
+NV_BlitRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty
+){
+ NVPtr pNv = NVPTR(pScrn);
+
+ if(pNv->AccelInfoRec) {
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ (*pNv->AccelInfoRec->SetupForScreenToScreenCopy)(
+ pScrn, xdir, ydir, GXcopy, ~0, -1);
+ (*pNv->AccelInfoRec->SubsequentScreenToScreenCopy)(
+ pScrn, srcx, srcy, dstx, dsty, w, h);
+ SET_SYNC_FLAG(pNv->AccelInfoRec);
+ }
+}
+
+
+static void
+NV_BlitTransRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty,
+ unsigned long color
+){
+ /* this one should be separate since the XAA function would
+ prohibit usage of ~0 as the key */
+}
+
+
+static Bool
+NV_OpenFramebuffer(
+ ScrnInfoPtr pScrn,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *flags
+){
+ NVPtr pNv = NVPTR(pScrn);
+
+ *name = NULL; /* no special device */
+ *mem = (unsigned char*)pNv->FbAddress;
+ *size = pNv->FbMapSize;
+ *offset = 0;
+ *flags = DGA_NEED_ROOT;
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c
new file mode 100644
index 000000000..e625d0272
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c
@@ -0,0 +1,1664 @@
+/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
+/*
+ * Copyright 1996-1997 David J. McKay
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * DAVID J. MCKAY 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.
+ */
+
+/* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen
+ <jpaana@s2.org> */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c,v 1.13 1999/08/28 09:01:06 dawes Exp $ */
+
+#include "nv_include.h"
+
+/* Little hack to declare all the base pointers */
+#define extern
+#include "nvreg.h"
+#undef extern
+#include "nvvga.h"
+
+
+/*
+ * Forward definitions for the functions that make up the driver.
+ */
+/* Mandatory functions */
+static void NVIdentify(int flags);
+static Bool NVProbe(DriverPtr drv, int flags);
+static Bool NVPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool NVScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool NVEnterVT(int scrnIndex, int flags);
+static Bool NVEnterVTFBDev(int scrnIndex, int flags);
+static void NVLeaveVT(int scrnIndex, int flags);
+static Bool NVCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool NVSaveScreen(ScreenPtr pScreen, Bool unblank);
+
+/* Optional functions */
+static void NVFreeScreen(int scrnIndex, int flags);
+static int NVValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
+static void NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+
+/* Internally used functions */
+
+static Bool NVMapMem(ScrnInfoPtr pScrn);
+static Bool NVMapMemFBDev(ScrnInfoPtr pScrn);
+static Bool NVUnmapMem(ScrnInfoPtr pScrn);
+static void NVSave(ScrnInfoPtr pScrn);
+static void NVRestore(ScrnInfoPtr pScrn);
+static Bool NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+
+
+/*
+ * This contains the functions needed by the server after loading the
+ * driver module. It must be supplied, and gets added the driver list by
+ * the Module Setup funtion in the dynamic case. In the static case a
+ * reference to this is compiled in, and this requires that the name of
+ * this DriverRec be an upper-case version of the driver name.
+ */
+
+DriverRec NV = {
+ VERSION,
+ "accelerated driver for NVIDIA RIVA 128, TNT and TNT2 cards",
+ NVIdentify,
+ NVProbe,
+ NULL,
+ 0
+};
+
+#define NV_CHIP_RIVA128 ((PCI_VENDOR_NVIDIA_SGS << 16)| PCI_CHIP_RIVA128)
+#define NV_CHIP_TNT ((PCI_VENDOR_NVIDIA << 16)| PCI_CHIP_TNT)
+#define NV_CHIP_TNT2 ((PCI_VENDOR_NVIDIA << 16)| PCI_CHIP_TNT2)
+#define NV_CHIP_UTNT2 ((PCI_VENDOR_NVIDIA << 16)| PCI_CHIP_UTNT2)
+#define NV_CHIP_VTNT2 ((PCI_VENDOR_NVIDIA << 16)| PCI_CHIP_VTNT2)
+#define NV_CHIP_ITNT2 ((PCI_VENDOR_NVIDIA << 16)| PCI_CHIP_ITNT2)
+
+/* Supported chipsets */
+static SymTabRec NVChipsets[] = {
+ { NV_CHIP_RIVA128, "RIVA128" },
+ { NV_CHIP_TNT, "RIVATNT" },
+ { NV_CHIP_TNT2, "RIVATNT2" },
+ { NV_CHIP_UTNT2, "RIVATNT2 (Ultra)" },
+ { NV_CHIP_VTNT2, "RIVATNT2 (Vanta)" },
+ { NV_CHIP_ITNT2, "RIVATNT2 (Integrated)" },
+ {-1, NULL }
+};
+
+static PciChipsets NVPciChipsets[] = {
+ { NV_CHIP_RIVA128, NV_CHIP_RIVA128, RES_SHARED_VGA },
+ { NV_CHIP_TNT, NV_CHIP_TNT, RES_SHARED_VGA },
+ { NV_CHIP_TNT2, NV_CHIP_TNT2, RES_SHARED_VGA },
+ { NV_CHIP_UTNT2, NV_CHIP_UTNT2, RES_SHARED_VGA },
+ { NV_CHIP_VTNT2, NV_CHIP_VTNT2, RES_SHARED_VGA },
+ { NV_CHIP_ITNT2, NV_CHIP_ITNT2, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED }
+};
+
+/*
+ * List of symbols from other modules that this module references. This
+ * list is used to tell the loader that it is OK for symbols here to be
+ * unresolved providing that it hasn't been told that they haven't been
+ * told that they are essential via a call to xf86LoaderReqSymbols() or
+ * xf86LoaderReqSymLists(). The purpose is this is to avoid warnings about
+ * unresolved symbols that are not required.
+ */
+
+static const char *vgahwSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWUnlock",
+ "vgaHWInit",
+ "vgaHWProtect",
+ "vgaHWGetIOBase",
+ "vgaHWMapMem",
+ "vgaHWLock",
+ "vgaHWFreeHWRec",
+ "vgaHWSaveScreen",
+ "vgaHWddc1SetSpeed",
+#ifdef DPMSExtension
+ "vgaHWDPMSSet",
+#endif
+ NULL
+};
+
+static const char *cfbSymbols[] = {
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb24ScreenInit",
+ "cfb32ScreenInit",
+ "cfb8_32ScreenInit",
+ "cfb24_32ScreenInit",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAADestroyInfoRec",
+ "XAACreateInfoRec",
+ "XAAInit",
+ "XAAStippleScanlineFuncLSBFirst",
+ "XAAOverlayFBfuncs",
+ "XAACachePlanarMonoStipple",
+ "XAAScreenIndex",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86InitCursor",
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ NULL
+};
+
+static const char *shadowSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+static const char *fbdevHWSymbols[] = {
+ "fbdevHWInit",
+ "fbdevHWUseBuildinMode",
+
+ "fbdevHWGetDepth",
+ "fbdevHWGetVidmem",
+
+ /* colormap */
+ "fbdevHWLoadPalette",
+
+ /* ScrnInfo hooks */
+ "fbdevHWSwitchMode",
+ "fbdevHWAdjustFrame",
+ "fbdevHWEnterVT",
+ "fbdevHWLeaveVT",
+ "fbdevHWValidMode",
+ "fbdevHWRestore",
+ "fbdevHWModeInit",
+ "fbdevHWSave",
+
+ "fbdevHWUnmapMMIO",
+ "fbdevHWUnmapVidmem",
+ "fbdevHWMapMMIO",
+ "fbdevHWMapVidmem",
+
+ NULL
+};
+
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(nvSetup);
+
+static XF86ModuleVersionInfo nvVersRec =
+{
+ "nv",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ NV_MAJOR_VERSION, NV_MINOR_VERSION, NV_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+XF86ModuleData nvModuleData = { &nvVersRec, nvSetup, NULL };
+#endif
+
+static OptionInfoRec NVOptions[] = {
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_RGB_BITS, "RGBbits", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_FBDEV, "UseFBDev", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_SET_MCLK, "SetMclk", OPTV_FREQ, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+/*
+ * This is intentionally screen-independent. It indicates the binding
+ * choice made in the first PreInit.
+ */
+static int pix24bpp = 0;
+
+/*
+ * ramdac info structure initialization
+ */
+static NVRamdacRec DacInit = {
+ FALSE, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL,
+ 0, 0, X_DEFAULT, X_DEFAULT, FALSE
+};
+
+
+/* another theft from MGA-driver */
+static void
+NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ int width, height, Bpp, FBPitch;
+ unsigned char *src, *dst;
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ FBPitch = pScrn->displayWidth * Bpp;
+
+ while(num--) {
+ width = (pbox->x2 - pbox->x1) * Bpp;
+ height = pbox->y2 - pbox->y1;
+ src = pNv->ShadowPtr + (pbox->y1 * pNv->ShadowPitch) +
+ (pbox->x1 * Bpp);
+ dst = pNv->FbStart + (pbox->y1 * FBPitch) + (pbox->x1 * Bpp);
+
+ while(height--) {
+ memcpy(dst, src, width);
+ dst += FBPitch;
+ src += pNv->ShadowPitch;
+ }
+
+ pbox++;
+ }
+}
+
+
+static Bool
+NVGetRec(ScrnInfoPtr pScrn)
+{
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVGetRec\n"));
+ /*
+ * Allocate an NVRec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(NVRec), 1);
+ /* Initialise it */
+
+ NVPTR(pScrn)->Dac = DacInit;
+ return TRUE;
+}
+
+static void
+NVFreeRec(ScrnInfoPtr pScrn)
+{
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVFreeRec\n"));
+
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+
+#ifdef XFree86LOADER
+
+static pointer
+nvSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ /* This module should be loaded only once, but check to be sure. */
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&NV, module, 0);
+
+ /*
+ * Modules that this driver always requires may be loaded here
+ * by calling LoadSubModule().
+ */
+
+ /*
+ * Tell the loader about symbols from other modules that this module
+ * might refer to.
+ */
+ LoaderRefSymLists(vgahwSymbols, cfbSymbols, xaaSymbols,
+ ramdacSymbols, shadowSymbols,
+ fbdevHWSymbols, NULL);
+
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer)1;
+ } else {
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+
+#endif /* XFree86LOADER */
+
+
+
+/* Mandatory */
+static void
+NVIdentify(int flags)
+{
+ xf86PrintChipsets(NV_NAME, "driver for NVIDIA chipsets", NVChipsets);
+}
+
+
+/* Mandatory */
+static Bool
+NVProbe(DriverPtr drv, int flags)
+{
+ int i;
+ GDevPtr *devSections;
+ int *usedChips;
+ int numDevSections;
+ int numUsed;
+ Bool foundScreen = FALSE;
+
+ /*
+ * The aim here is to find all cards that this driver can handle,
+ * and for the ones not already claimed by another driver, claim the
+ * slot, and allocate a ScrnInfoRec.
+ *
+ * This should be a minimal probe, and it should under no circumstances
+ * change the state of the hardware. Because a device is found, don't
+ * assume that it will be used. Don't do any initialisations other than
+ * the required ScrnInfoRec initialisations. Don't allocate any new
+ * data structures.
+ */
+
+ /*
+ * Check if there has been a chipset override in the config file.
+ * For this we must find out if there is an active device section which
+ * is relevant, i.e., which has no driver specified or has THIS driver
+ * specified.
+ */
+
+ if ((numDevSections = xf86MatchDevice(NV_DRIVER_NAME,
+ &devSections)) <= 0) {
+ /*
+ * There's no matching device section in the config file, so quit
+ * now.
+ */
+ return FALSE;
+ }
+
+ /*
+ * We need to probe the hardware first. We then need to see how this
+ * fits in with what is given in the config file, and allow the config
+ * file info to override any contradictions.
+ */
+
+ /*
+ * All of the cards this driver supports are PCI, so the "probing" just
+ * amounts to checking the PCI data that the server has already collected.
+ */
+ if (xf86GetPciVideoInfo() == NULL) {
+ /*
+ * We won't let anything in the config file override finding no
+ * PCI video cards at all. This seems reasonable now, but we'll see.
+ */
+ return FALSE;
+ }
+
+ /* This should match both vendors, PCI_VENDOR_NVIDIA_SGS and
+ PCI_VENDOR_NVIDIA, see above */
+ numUsed = xf86MatchPciInstances(NV_NAME, 0, NVChipsets, NVPciChipsets,
+ devSections, numDevSections, drv,
+ &usedChips);
+
+ /* Free it since we don't need that list after this */
+ xfree(devSections);
+ devSections = NULL;
+ if (numUsed <= 0)
+ return FALSE;
+
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn;
+
+ /* Allocate a ScrnInfoRec and claim the slot */
+ pScrn = xf86AllocateScreen(drv, 0);
+
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = NV_DRIVER_NAME;
+ pScrn->name = NV_NAME;
+ pScrn->Probe = NVProbe;
+ pScrn->PreInit = NVPreInit;
+ pScrn->ScreenInit = NVScreenInit;
+ pScrn->SwitchMode = NVSwitchMode;
+ pScrn->AdjustFrame = NVAdjustFrame;
+ pScrn->EnterVT = NVEnterVT;
+ pScrn->LeaveVT = NVLeaveVT;
+ pScrn->FreeScreen = NVFreeScreen;
+ pScrn->ValidMode = NVValidMode;
+ foundScreen = TRUE;
+ xf86ConfigActivePciEntity(pScrn, usedChips[i], NVPciChipsets, NULL,
+ NULL, NULL, NULL, NULL);
+ }
+ xfree(usedChips);
+ return foundScreen;
+}
+
+/* Usually mandatory */
+Bool
+NVSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVSwitchMode\n"));
+ return NVModeInit(xf86Screens[scrnIndex], mode);
+}
+
+/*
+ * This function is used to initialize the Start Address - the first
+ * displayed location in the video memory.
+ */
+/* Usually mandatory */
+void
+NVAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ int startAddr;
+ NVPtr pNv = NVPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVAdjustFrame\n"));
+
+ startAddr = (((y*pScrn->virtualX)+x)*(pScrn->bitsPerPixel/8));
+ pNv->riva.SetStartAddress(&pNv->riva, startAddr);
+}
+
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ *
+ * We may wish to unmap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static Bool
+NVEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVEnterVT\n"));
+
+ RivaEnterLeave(pScrn, TRUE);
+ if (!NVModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ NVAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ return TRUE;
+}
+
+static Bool
+NVEnterVTFBDev(int scrnIndex, int flags)
+{
+/* ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; */
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVEnterVTFBDev\n"));
+
+ fbdevHWEnterVT(scrnIndex,flags);
+/* MGAStormSync(pScrn);
+ MGAStormEngineInit(pScrn); */
+ return TRUE;
+}
+
+/*
+ * This is called when VT switching away from the X server. Its job is
+ * to restore the previous (text) mode.
+ *
+ * We may wish to remap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static void
+NVLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVLeaveVT\n"));
+
+ NVRestore(pScrn);
+ RivaEnterLeave(pScrn, FALSE);
+}
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode. It should also unmap the video memory, and free
+ * any per-generation data allocated by the driver. It should finish
+ * by unwrapping and calling the saved CloseScreen function.
+ */
+
+/* Mandatory */
+static Bool
+NVCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ NVPtr pNv = NVPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVCloseScreen\n"));
+
+ if (pScrn->vtSema) {
+ NVRestore(pScrn);
+ vgaHWLock(hwp);
+ NVUnmapMem(pScrn);
+ vgaHWUnmapMem(pScrn);
+ }
+
+ if (pNv->AccelInfoRec)
+ XAADestroyInfoRec(pNv->AccelInfoRec);
+ if (pNv->CursorInfoRec)
+ xf86DestroyCursorInfoRec(pNv->CursorInfoRec);
+ if (pNv->ShadowPtr)
+ xfree(pNv->ShadowPtr);
+ if (pNv->DGAModes)
+ xfree(pNv->DGAModes);
+ if ( pNv->expandBuffer )
+ xfree(pNv->expandBuffer);
+
+
+ pScrn->vtSema = FALSE;
+ return TRUE;
+/* return (*pScreen->CloseScreen)(scrnIndex, pScreen); */
+}
+
+/* Free up any persistent data structures */
+
+/* Optional */
+static void
+NVFreeScreen(int scrnIndex, int flags)
+{
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVFreeScreen\n"));
+ /*
+ * This only gets called when a screen is being deleted. It does not
+ * get called routinely at the end of a server generation.
+ */
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ NVFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+/* Optional */
+static int
+NVValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ DEBUG(xf86DrvMsg(scrnIndex, X_INFO, "NVValidMode\n"));
+ /* HACK HACK HACK */
+ return (MODE_OK);
+}
+
+/* Mandatory */
+Bool
+NVPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ NVPtr pNv;
+ MessageType from;
+ int i;
+ double real;
+ int bytesPerPixel;
+ ClockRangePtr clockRanges;
+ char *mod = NULL;
+ const char *reqSym = NULL;
+ int flags24;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVPreInit\n"));
+ /*
+ * Note: This function is only called once at server startup, and
+ * not at the start of each server generation. This means that
+ * only things that are persistent across server generations can
+ * be initialised here. xf86Screens[] is (pScrn is a pointer to one
+ * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex()
+ * are too, and should be used for data that must persist across
+ * server generations.
+ *
+ * Per-generation data should be allocated with
+ * AllocateScreenPrivateIndex() from the ScreenInit() function.
+ */
+
+ /* Check the number of entities, and fail if it isn't one. */
+ if (pScrn->numEntities != 1)
+ return FALSE;
+
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /*
+ * Allocate a vgaHWRec
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ /* Allocate the NVRec driverPrivate */
+ if (!NVGetRec(pScrn)) {
+ return FALSE;
+ }
+ pNv = NVPTR(pScrn);
+
+ /* Get the entity, and make sure it is PCI. */
+ pNv->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pNv->pEnt->location.type != BUS_PCI)
+ return FALSE;
+
+ /* Find the PCI info for this screen */
+ pNv->PciInfo = xf86GetPciInfoForEntity(pNv->pEnt->index);
+ pNv->PciTag = pciTag(pNv->PciInfo->bus, pNv->PciInfo->device,
+ pNv->PciInfo->func);
+
+ pNv->Primary = xf86IsPrimaryPci(pNv->PciInfo);
+
+ {
+ resRange vga1mem[] = { {ResShrMemBlock,0xA0000,0xAFFFF},
+ {ResShrMemBlock,0xB8000,0xBFFFF},
+ _END };
+ resRange vga2mem[] = { {ResShrMemBlock,0xB0000,0xB7FFF},
+ _END };
+ xf86SetOperatingState(vga1mem, pNv->pEnt->index, ResDisableOpr);
+ xf86SetOperatingState(vga2mem, pNv->pEnt->index, ResDisableOpr);
+ }
+
+ pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+ pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*
+ * The first thing we should figure out is the depth, bpp, etc.
+ * Our default depth is 8, so pass it to the helper function.
+ * We support both 24bpp and 32bpp layouts, so indicate that.
+ */
+
+/* flags24 = Support24bppFb | Support32bppFb | SupportConvert32to24; */
+ flags24 = Support32bppFb;
+
+ if (!xf86SetDepthBpp(pScrn, 8, 8, 8, flags24)) {
+ return FALSE;
+ } else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 8:
+ case 15:
+ case 16:
+ case 24:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+ xf86PrintDepthBpp(pScrn);
+
+ /* Get the depth24 pixmap format */
+ if (pScrn->depth == 24 && pix24bpp == 0)
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ bytesPerPixel = pScrn->bitsPerPixel / 8;
+
+ /* We use a programamble clock */
+ pScrn->progClock = TRUE;
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, NVOptions);
+
+ /* Set the bits per RGB for 8bpp mode */
+ if (pScrn->depth == 8) {
+ /* XXX This is here just to test options. */
+ /* Default to 8 */
+ pScrn->rgbBits = 8;
+ if (xf86GetOptValInteger(NVOptions, OPTION_RGB_BITS,
+ &pScrn->rgbBits)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
+ pScrn->rgbBits);
+ }
+ }
+ from = X_DEFAULT;
+ pNv->HWCursor = TRUE;
+ /*
+ * The preferred method is to use the "hw cursor" option as a tri-state
+ * option, with the default set above.
+ */
+ if (xf86GetOptValBool(NVOptions, OPTION_HW_CURSOR, &pNv->HWCursor)) {
+ from = X_CONFIG;
+ }
+ /* For compatibility, accept this too (as an override) */
+ if (xf86ReturnOptValBool(NVOptions, OPTION_SW_CURSOR, FALSE)) {
+ from = X_CONFIG;
+ pNv->HWCursor = FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pNv->HWCursor ? "HW" : "SW");
+ if (xf86ReturnOptValBool(NVOptions, OPTION_NOACCEL, FALSE)) {
+ pNv->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+ if (xf86ReturnOptValBool(NVOptions, OPTION_PCI_RETRY, FALSE)) {
+ pNv->UsePCIRetry = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
+ }
+ if (xf86ReturnOptValBool(NVOptions, OPTION_SHOWCACHE, FALSE)) {
+ pNv->ShowCache = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShowCache enabled\n");
+ }
+ if (xf86GetOptValFreq(NVOptions, OPTION_SET_MCLK, OPTUNITS_MHZ, &real)) {
+ pNv->MemClk = (int)(real * 1000.0);
+ }
+ if (xf86ReturnOptValBool(NVOptions, OPTION_SHADOW_FB, FALSE)) {
+ pNv->ShadowFB = TRUE;
+ pNv->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using \"Shadow Framebuffer\" - acceleration disabled\n");
+ }
+ if (xf86ReturnOptValBool(NVOptions, OPTION_FBDEV, FALSE)) {
+ pNv->FBDev = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Using framebuffer device\n");
+ }
+ if (pNv->FBDev) {
+ /* check for linux framebuffer device */
+ if (!xf86LoadSubModule(pScrn, "fbdevhw"))
+ return FALSE;
+ xf86LoaderReqSymLists(fbdevHWSymbols, NULL);
+ if (!fbdevHWInit(pScrn, pNv->PciInfo, NULL))
+ return FALSE;
+ pScrn->SwitchMode = fbdevHWSwitchMode;
+ pScrn->AdjustFrame = fbdevHWAdjustFrame;
+ pScrn->EnterVT = NVEnterVTFBDev;
+ pScrn->LeaveVT = fbdevHWLeaveVT;
+ pScrn->ValidMode = fbdevHWValidMode;
+ }
+
+ /*
+ * Set the Chipset and ChipRev, allowing config file entries to
+ * override.
+ */
+ if (pNv->pEnt->device->chipset && *pNv->pEnt->device->chipset) {
+ pScrn->chipset = pNv->pEnt->device->chipset;
+ pNv->Chipset = xf86StringToToken(NVChipsets, pScrn->chipset);
+ from = X_CONFIG;
+ } else if (pNv->pEnt->device->chipID >= 0) {
+ pNv->Chipset = pNv->pEnt->device->chipID;
+ pScrn->chipset = (char *)xf86TokenToString(NVChipsets, pNv->Chipset);
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pNv->Chipset);
+ } else {
+ from = X_PROBED;
+ pNv->Chipset = (pNv->PciInfo->vendor << 16) |pNv->PciInfo->chipType;
+ pScrn->chipset = (char *)xf86TokenToString(NVChipsets, pNv->Chipset);
+ }
+ if (pNv->pEnt->device->chipRev >= 0) {
+ pNv->ChipRev = pNv->pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pNv->ChipRev);
+ } else {
+ pNv->ChipRev = pNv->PciInfo->chipRev;
+ }
+
+ /*
+ * This shouldn't happen because such problems should be caught in
+ * NVProbe(), but check it just in case.
+ */
+ if (pScrn->chipset == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ChipID 0x%04X is not recognised\n", pNv->Chipset);
+ return FALSE;
+ }
+ if (pNv->Chipset < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Chipset \"%s\" is not recognised\n", pScrn->chipset);
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
+
+ if (pNv->pEnt->device->MemBase != 0) {
+ /* Require that the config file value matches one of the PCI values. */
+ if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->MemBase)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "MemBase 0x%08lX doesn't match any PCI base register.\n",
+ pNv->pEnt->device->MemBase);
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+ pNv->FbAddress = pNv->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ int i = 1;
+ pNv->FbBaseReg = i;
+ if (pNv->PciInfo->memBase[i] != 0) {
+ pNv->FbAddress = pNv->PciInfo->memBase[i] & 0xff800000;
+ from = X_PROBED;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid FB address in PCI config space\n");
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pNv->FbAddress);
+
+ if (pNv->pEnt->device->IOBase != 0) {
+ /* Require that the config file value matches one of the PCI values. */
+ if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->IOBase)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "IOBase 0x%08lX doesn't match any PCI base register.\n",
+ pNv->pEnt->device->IOBase);
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+ pNv->IOAddress = pNv->pEnt->device->IOBase;
+ from = X_CONFIG;
+ } else {
+ int i = 0;
+ if (pNv->PciInfo->memBase[i] != 0) {
+ pNv->IOAddress = pNv->PciInfo->memBase[i] & 0xffffc000;
+ from = X_PROBED;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid MMIO address in PCI config space\n");
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
+ (unsigned long)pNv->IOAddress);
+
+ if (xf86RegisterResources(pNv->pEnt->index, NULL, ResExclusive)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n");
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+
+ switch (pNv->Chipset) {
+ case NV_CHIP_RIVA128:
+ NV3Setup(pScrn);
+ break;
+
+ case NV_CHIP_TNT:
+ case NV_CHIP_TNT2:
+ case NV_CHIP_UTNT2:
+ case NV_CHIP_VTNT2:
+ case NV_CHIP_ITNT2:
+ NV4Setup(pScrn);
+ break;
+ }
+
+ /*
+ * fill riva structure etc.
+ */
+ (*pNv->PreInit)(pScrn);
+
+ /* HW bpp matches reported bpp */
+ pNv->HwBpp = pScrn->bitsPerPixel;
+
+ /*
+ * If the user has specified the amount of memory in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pNv->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pNv->pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else {
+ if (pNv->FBDev) {
+ pScrn->videoRam = fbdevHWGetVidmem(pScrn)/1024;
+ } else {
+ pScrn->videoRam = pNv->riva.RamAmountKBytes;
+ }
+ from = X_PROBED;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kBytes\n",
+ pScrn->videoRam);
+
+ pNv->FbMapSize = pScrn->videoRam * 1024;
+
+ /* Set the bpp shift value */
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ pNv->BppShift = 0;
+ break;
+ case 16:
+ pNv->BppShift = 1;
+ break;
+ case 24:
+ pNv->BppShift = 0;
+ break;
+ case 32:
+ pNv->BppShift = 2;
+ break;
+ }
+
+ pNv->Rounding = 128 >> pNv->BppShift;
+
+ /*
+ * If the driver can do gamma correction, it should call xf86SetGamma()
+ * here.
+ */
+
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+
+ /* XXX Set HW cursor use */
+
+ /* Set the min pixel clock */
+ pNv->MinClock = 12000; /* XXX Guess, need to check this */
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
+ pNv->MinClock / 1000);
+ /*
+ * If the user has specified ramdac speed in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pNv->pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ speed = pNv->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ speed = pNv->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ speed = pNv->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ case 32:
+ speed = pNv->pEnt->device->dacSpeeds[DAC_BPP32];
+ break;
+ }
+ if (speed == 0)
+ pNv->MaxClock = pNv->pEnt->device->dacSpeeds[0];
+ else
+ pNv->MaxClock = speed;
+ from = X_CONFIG;
+ } else {
+ pNv->MaxClock = pNv->Dac.maxPixelClock;
+ from = pNv->Dac.ClockFrom;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
+ pNv->MaxClock / 1000);
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+ clockRanges = xnfalloc(sizeof(ClockRange));
+ clockRanges->next = NULL;
+ clockRanges->minClock = pNv->MinClock;
+ clockRanges->maxClock = pNv->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = TRUE;
+
+ /* Only set MemClk if appropriate for the ramdac */
+ if (pNv->Dac.SetMemClk) {
+ if (pNv->MemClk == 0) {
+ pNv->MemClk = pNv->Dac.MemoryClock;
+ from = pNv->Dac.MemClkFrom;
+ } else
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, from, "MCLK used is %.1f MHz\n",
+ pNv->MemClk / 1000.0);
+ }
+
+ /*
+ * xf86ValidateModes will check that the mode HTotal and VTotal values
+ * don't exceed the chipset's limit if pScrn->maxHValue and
+ * pScrn->maxVValue are set. Since our NVValidMode() already takes
+ * care of this, we don't worry about setting them here.
+ */
+ {
+ int *linePitches = NULL;
+ int minPitch = 256;
+ int maxPitch = 2048;
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ linePitches, minPitch, maxPitch,
+ pNv->Rounding * pScrn->bitsPerPixel, 128, 2048,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pNv->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+
+ if (linePitches)
+ xfree(linePitches);
+ }
+
+ if (i < 1 && pNv->FBDev) {
+ fbdevHWUseBuildinMode(pScrn);
+ pScrn->displayWidth = pScrn->virtualX; /* FIXME: might be wrong */
+ i = 1;
+ }
+ if (i == -1) {
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /*
+ * Set the CRTC parameters for all of the modes based on the type
+ * of mode, and the chipset's interlace requirements.
+ *
+ * Calling this is required if the mode->Crtc* values are used by the
+ * driver and if the driver doesn't provide code to set them. They
+ * are not pre-initialised at all.
+ */
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /*
+ * Compute the byte offset into the linear frame buffer where the
+ * frame buffer data should actually begin.
+ */
+
+ pNv->YDstOrg = 0;
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "YDstOrg is set to %d\n",
+ pNv->YDstOrg);
+ pNv->FbUsableSize = pNv->FbMapSize - pNv->YDstOrg * bytesPerPixel;
+
+ /* Remove reserved memory from end of buffer */
+ switch( pNv->riva.Architecture ) {
+ case 3:
+ pNv->FbUsableSize -= 32 * 1024;
+ break;
+ case 4:
+ pNv->FbUsableSize -= 128 * 1024;
+ break;
+ }
+
+ /*
+ * XXX This should be taken into account in some way in the mode valdation
+ * section.
+ */
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ mod = "cfb";
+ reqSym = "cfbScreenInit";
+ break;
+ case 16:
+ mod = "cfb16";
+ reqSym = "cfb16ScreenInit";
+ break;
+ case 24:
+ if (pix24bpp == 24) {
+ mod = "cfb24";
+ reqSym = "cfb24ScreenInit";
+ } else {
+ mod = "xf24_32bpp";
+ reqSym = "cfb24_32ScreenInit";
+ }
+ break;
+ case 32:
+ mod = "cfb32";
+ reqSym = "cfb32ScreenInit";
+ break;
+ }
+ if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymbols(reqSym, NULL);
+
+ /* Load XAA if needed */
+ if (!pNv->NoAccel) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ /* Load ramdac if needed */
+ if (pNv->HWCursor) {
+ if (!xf86LoadSubModule(pScrn, "ramdac")) {
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+ }
+
+ /* Load shadowfb if needed */
+ if (pNv->ShadowFB) {
+ if (!xf86LoadSubModule(pScrn, "shadowfb")) {
+ NVFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(shadowSymbols, NULL);
+ }
+ return TRUE;
+}
+
+
+/*
+ * Map the framebuffer and MMIO memory.
+ */
+
+static Bool
+NVMapMem(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv;
+ int mmioFlags;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVMapMem\n"));
+ pNv = NVPTR(pScrn);
+
+ /*
+ * Map IO registers to virtual address space
+ */
+#if !defined(__alpha__)
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
+#else
+ /*
+ * For Alpha, we need to map SPARSE memory, since we need
+ * byte/short access.
+ */
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT | VIDMEM_SPARSE;
+#endif
+ pNv->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ pNv->IOAddress, 0x4000);
+ if (pNv->IOBase == NULL)
+ return FALSE;
+
+#ifdef __alpha__
+ /*
+ * for Alpha, we need to map DENSE memory as well, for
+ * setting CPUToScreenColorExpandBase.
+ */
+ pNv->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pNv->PciTag, pNv->IOAddress, 0x4000);
+ if (pNv->IOBaseDense == NULL)
+ return FALSE;
+#endif /* __alpha__ */
+
+ pNv->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pNv->PciTag, pNv->FbAddress,
+ pNv->FbMapSize);
+ if (pNv->FbBase == NULL)
+ return FALSE;
+
+ pNv->FbStart = pNv->FbBase + pNv->YDstOrg * (pScrn->bitsPerPixel / 8);
+
+ return TRUE;
+}
+
+Bool
+NVMapMemFBDev(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVMamMemFBDev\n"));
+ pNv = NVPTR(pScrn);
+
+ pNv->FbBase = fbdevHWMapVidmem(pScrn);
+ if (pNv->FbBase == NULL)
+ return FALSE;
+
+ pNv->IOBase = fbdevHWMapMMIO(pScrn);
+ if (pNv->IOBase == NULL)
+ return FALSE;
+
+ pNv->FbStart = pNv->FbBase + pNv->YDstOrg * (pScrn->bitsPerPixel / 8);
+
+ return TRUE;
+}
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+NVUnmapMem(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVUnmapMem\n"));
+ pNv = NVPTR(pScrn);
+
+ /*
+ * Unmap IO registers to virtual address space
+ */
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pNv->IOBase, 0x4000);
+ pNv->IOBase = NULL;
+
+#ifdef __alpha__
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pNv->IOBaseDense, 0x4000);
+ pNv->IOBaseDense = NULL;
+#endif /* __alpha__ */
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pNv->FbBase, pNv->FbMapSize);
+ pNv->FbBase = NULL;
+ pNv->FbStart = NULL;
+
+ return TRUE;
+}
+
+
+/*
+ * Initialise a new mode. This is currently still using the old
+ * "initialise struct, restore/write struct to HW" model. That could
+ * be changed.
+ */
+
+static Bool
+NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg;
+ NVPtr pNv = NVPTR(pScrn);
+ NVRegPtr nvReg;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVModeInit\n"));
+
+ /* Initialise the ModeReg values */
+ if (!vgaHWInit(pScrn, mode))
+ return FALSE;
+ pScrn->vtSema = TRUE;
+
+ if ( pNv->ModeInit ) {
+ if (!(*pNv->ModeInit)(pScrn, mode))
+ return FALSE;
+ }
+
+ /* Program the registers */
+ vgaHWProtect(pScrn, TRUE);
+ vgaReg = &hwp->ModeReg;
+ nvReg = &pNv->ModeReg;
+
+ if ( pNv->Restore )
+ (*pNv->Restore)(pScrn, vgaReg, nvReg, FALSE);
+
+ vgaHWProtect(pScrn, FALSE);
+
+ return TRUE;
+}
+
+/*
+ * Restore the initial (text) mode.
+ */
+static void
+NVRestore(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &hwp->SavedReg;
+ NVPtr pNv = NVPTR(pScrn);
+ NVRegPtr nvReg = &pNv->SavedReg;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVRestore\n"));
+ /* Only restore text mode fonts/text for the primary card */
+ vgaHWProtect(pScrn, TRUE);
+ if (pNv->Primary)
+ (*pNv->Restore)(pScrn, vgaReg, nvReg, TRUE);
+ else
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+ vgaHWProtect(pScrn, FALSE);
+}
+
+
+/* Mandatory */
+
+/* This gets called at the start of each server generation */
+
+static Bool
+NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ NVPtr pNv;
+ NVRamdacPtr NVdac;
+ int ret;
+ VisualPtr visual;
+ unsigned char *FBStart;
+
+ /*
+ * First get the ScrnInfoRec
+ */
+ pScrn = xf86Screens[pScreen->myNum];
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVScreenInit\n"));
+
+ hwp = VGAHWPTR(pScrn);
+ pNv = NVPTR(pScrn);
+ NVdac = &pNv->Dac;
+
+ /* Map the NV memory and MMIO areas */
+ if (pNv->FBDev) {
+ if (!NVMapMemFBDev(pScrn))
+ return FALSE;
+ } else {
+ if (!NVMapMem(pScrn))
+ return FALSE;
+ }
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Mem Mapped\n"));
+
+ /* Map the VGA memory when the primary video */
+ if (pNv->Primary && !pNv->FBDev) {
+ hwp->MapSize = 0x10000;
+ if (!vgaHWMapMem(pScrn))
+ return FALSE;
+ }
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- VGA Mapped\n"));
+
+ if (pNv->FBDev) {
+ fbdevHWSave(pScrn);
+ if (!fbdevHWModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ } else {
+ /* Save the current state */
+ NVSave(pScrn);
+ /* Initialise the first mode */
+ if (!NVModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ }
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- State saved\n"));
+
+ /* Darken the screen for aesthetic reasons and set the viewport */
+ NVSaveScreen(pScreen, FALSE);
+ pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Blanked\n"));
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset the visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ /* All NV support DirectColor and can do overlays in 32bpp */
+ if(pNv->Overlay8Plus24 && (pScrn->bitsPerPixel == 32)) {
+ if (!miSetVisualTypes(8, PseudoColorMask | GrayScaleMask,
+ pScrn->rgbBits, PseudoColor))
+ return FALSE;
+ if (!miSetVisualTypes(24, TrueColorMask, pScrn->rgbBits, TrueColor))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Visuals set up\n"));
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+
+ if(pNv->ShadowFB) {
+ pNv->ShadowPitch =
+ ((pScrn->virtualX * pScrn->bitsPerPixel >> 3) + 3) & ~3L;
+ pNv->ShadowPtr = xalloc(pNv->ShadowPitch * pScrn->virtualY);
+ FBStart = pNv->ShadowPtr;
+ } else {
+ pNv->ShadowPtr = NULL;
+ FBStart = pNv->FbStart;
+ }
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ ret = cfbScreenInit(pScreen, FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 16:
+ ret = cfb16ScreenInit(pScreen, FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 24:
+ if (pix24bpp == 24)
+ ret = cfb24ScreenInit(pScreen, FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ else
+ ret = cfb24_32ScreenInit(pScreen, FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 32:
+ if(pNv->Overlay8Plus24)
+ ret = cfb8_32ScreenInit(pScreen, FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ else
+ ret = cfb32ScreenInit(pScreen, FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in NVScreenInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ if (!ret)
+ return FALSE;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- cfb set up\n"));
+
+ if (pScrn->bitsPerPixel > 8) {
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- B & W\n"));
+
+ if(!pNv->ShadowFB) /* hardware cursor needs to wrap this layer */
+ NVDGAInit(pScreen);
+
+ if (!pNv->NoAccel)
+ NVAccelInit(pScreen);
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Backing store set up\n"));
+
+ /* Initialize software cursor.
+ Must precede creation of the default colormap */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- SW cursor set up\n"));
+
+ /* Initialize HW cursor layer.
+ Must follow software cursor initialization*/
+ if (pNv->HWCursor) {
+ if(!NVCursorInit(pScreen))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ }
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Def Color map set up\n"));
+
+ /* Initialize colormap layer.
+ Must follow initialization of the default colormap */
+ if(!xf86HandleColormaps(pScreen, 256, 8,
+ (pNv->FBDev ? fbdevHWLoadPalette : NVdac->LoadPalette), NULL,
+ (pNv->Overlay8Plus24 ? 0 : CMAP_PALETTED_TRUECOLOR) |
+ CMAP_RELOAD_ON_MODE_SWITCH))
+ return FALSE;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Palette loaded\n"));
+
+ if(pNv->ShadowFB)
+ ShadowFBInit(pScreen, NVRefreshArea);
+
+#ifdef DPMSExtension
+ /* Call the vgaHW DPMS function directly.
+ XXX There must be a way to get all the DPMS modes. */
+ xf86DPMSInit(pScreen, vgaHWDPMSSet, 0);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- DPMS set up\n"));
+#endif
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Color maps etc. set up\n"));
+
+ pScrn->memPhysBase = pNv->FbAddress;
+ pScrn->fbOffset = pNv->YDstOrg * (pScrn->bitsPerPixel / 8);
+
+#ifdef XvExtension
+ {
+ XF86VideoAdaptorPtr *ptr;
+ int n;
+
+ n = xf86XVListGenericAdaptors(&ptr);
+ if (n) {
+ xf86XVScreenInit(pScreen, ptr, n);
+ }
+ }
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Xv set up\n"));
+#endif
+
+ pScreen->SaveScreen = NVSaveScreen;
+
+ /* Wrap the current CloseScreen function */
+ pNv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = NVCloseScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+ /* Done */
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Done\n"));
+ return TRUE;
+}
+
+/* Free up any persistent data structures */
+
+
+/* Do screen blanking */
+
+/* Mandatory */
+static Bool
+NVSaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+ return vgaHWSaveScreen(pScreen, unblank);
+}
+
+static void
+NVSave(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ NVRegPtr nvReg = &pNv->SavedReg;
+ vgaHWPtr pVga = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg = &pVga->SavedReg;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVSave\n"));
+ vgaHWSave(pScrn, vgaReg, VGA_SR_MODE|VGA_SR_FONTS);
+ pNv->riva.UnloadStateExt(&pNv->riva, nvReg);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_include.h b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_include.h
new file mode 100644
index 000000000..2dbd1b40b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_include.h
@@ -0,0 +1,60 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_include.h,v 1.3 1999/08/14 10:49:51 dawes Exp $ */
+
+#ifndef __NV_INCLUDE_H__
+#define __NV_INCLUDE_H__
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "compiler.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* All drivers initialising the SW cursor need this */
+#include "mipointer.h"
+
+/* All drivers implementing backing store need this */
+#include "mibstore.h"
+
+#include "micmap.h"
+
+#include "xf86DDC.h"
+
+#include "xf86RAC.h"
+/*
+ * If using cfb, cfb.h is required. Select the others for the bpp values
+ * the driver supports.
+ */
+#define PSZ 8 /* needed for cfb.h */
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+#include "cfb24_32.h"
+#include "cfb8_32.h"
+
+#include "xaa.h"
+#include "xf86cmap.h"
+#include "shadowfb.h"
+#include "fbdevhw.h"
+
+#include "xf86xv.h"
+#include "Xv.h"
+
+#include "vgaHW.h"
+
+#include "xf86Cursor.h"
+
+#include "region.h"
+
+#include "nv_const.h"
+#include "nv_type.h"
+#include "nv_proto.h"
+
+#endif /* __NV_INCLUDE_H__ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_proto.h b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_proto.h
new file mode 100644
index 000000000..fa45b8755
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_proto.h
@@ -0,0 +1,37 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_proto.h,v 1.2 1999/08/01 12:17:41 dawes Exp $ */
+
+#ifndef __NV_PROTO_H__
+#define __NV_PROTO_H__
+
+/* in nv_driver.c */
+Bool NVSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+void NVAdjustFrame(int scrnIndex, int x, int y, int flags);
+
+/* in nv_dac.c */
+void NVRamdacInit(ScrnInfoPtr pScrn);
+Bool NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void NVDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg,
+ NVRegPtr nvReg, Bool saveFonts);
+void NVDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg,
+ NVRegPtr nvReg, Bool restoreFonts);
+void NVDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual );
+
+/* in nv_setup.c */
+void RivaEnterLeave(ScrnInfoPtr pScrn, Bool enter);
+void NV1Setup(ScrnInfoPtr pScrn);
+void NV3Setup(ScrnInfoPtr pScrn);
+void NV4Setup(ScrnInfoPtr pScrn);
+
+/* in nv_cursor.c */
+Bool NVCursorInit(ScreenPtr pScreen);
+
+/* in nv_xaa.c */
+Bool NVAccelInit(ScreenPtr pScreen);
+void NVSync(ScrnInfoPtr pScrn);
+
+/* in nv_dga.c */
+Bool NVDGAInit(ScreenPtr pScreen);
+
+#endif /* __NV_PROTO_H__ */
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c
new file mode 100644
index 000000000..cf7551d3a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c
@@ -0,0 +1,200 @@
+/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
+/*
+ * Copyright 1996-1997 David J. McKay
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * DAVID J. MCKAY 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.
+ */
+
+/* Hacked together from mga driver and 3.3.4 NVIDIA driver by Jarno Paananen
+ <jpaana@s2.org> */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_setup.c,v 1.1 1999/08/01 07:20:58 dawes Exp $ */
+
+#include "nv_include.h"
+
+#include "nvreg.h"
+#include "nvvga.h"
+
+/*
+ * Lock and unlock VGA and SVGA registers.
+ */
+void RivaEnterLeave(ScrnInfoPtr pScrn, Bool enter)
+{
+ unsigned char tmp;
+ CARD16 vgaIOBase = VGAHW_GET_IOBASE();
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ NVPtr pNv = NVPTR(pScrn);
+
+ if (enter)
+ {
+ vgaHWUnlock(hwp);
+ outb(vgaIOBase + 4, 0x11);
+ tmp = inb(vgaIOBase + 5);
+ outb(vgaIOBase + 5, tmp & 0x7F);
+ outb(pNv->riva.LockUnlockIO, pNv->riva.LockUnlockIndex);
+ outb(pNv->riva.LockUnlockIO + 1, 0x57);
+ }
+ else
+ {
+ outb(vgaIOBase + 4, 0x11);
+ tmp = inb(vgaIOBase + 5);
+ outb(vgaIOBase + 5, (tmp & 0x7F) | 0x80);
+ outb(pNv->riva.LockUnlockIO, pNv->riva.LockUnlockIndex);
+ outb(pNv->riva.LockUnlockIO + 1, 0x99);
+ vgaHWLock(hwp);
+ }
+}
+
+static void
+NVCommonSetup(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ CARD32 regBase = pNv->IOAddress;
+ int mmioFlags;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV4CommonSetup\n"));
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Regbase %x\n", regBase));
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- riva %x\n", &pNv->riva));
+
+ pNv->PreInit = NVRamdacInit;
+ pNv->Save = NVDACSave;
+ pNv->Restore = NVDACRestore;
+ pNv->ModeInit = NVDACInit;
+
+ pNv->Dac.LoadPalette = NVDACLoadPalette;
+
+ /*
+ * No IRQ in use.
+ */
+ pNv->riva.EnableIRQ = 0;
+ /*
+ * Map remaining registers. This MUST be done in the OS specific driver code.
+ */
+ pNv->riva.IO = VGAHW_GET_IOBASE();
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- IO %x\n", pNv->riva.IO));
+
+#if !defined(__alpha__)
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
+#else
+ /*
+ * For Alpha, we need to map SPARSE memory, since we need
+ * byte/short access.
+ */
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT | VIDMEM_SPARSE;
+#endif
+
+ pNv->riva.PRAMDAC = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00680000, 0x00001000);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PRAMDAC %x\n", pNv->riva.PRAMDAC));
+ pNv->riva.PFB = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00100000, 0x00001000);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PFB %x\n", pNv->riva.PFB));
+ pNv->riva.PFIFO = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00002000, 0x00002000);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PFIFO %x\n", pNv->riva.PFIFO));
+ pNv->riva.PGRAPH = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00400000, 0x00002000);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PGRAPH %x\n", pNv->riva.PGRAPH));
+ pNv->riva.PEXTDEV = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00101000, 0x00001000);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PEXTDEV %x\n", pNv->riva.PEXTDEV));
+ pNv->riva.PTIMER = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00009000, 0x00001000);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PTIMER %x\n", pNv->riva.PTIMER));
+ pNv->riva.PMC = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00000000, 0x00001000);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- PMC %x\n", pNv->riva.PMC));
+ pNv->riva.FIFO = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00800000, 0x00010000);
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- FIFO %x\n", pNv->riva.FIFO));
+
+ RivaGetConfig(&pNv->riva);
+
+ pNv->Dac.maxPixelClock = pNv->riva.MaxVClockFreqKHz;
+
+ RivaEnterLeave(pScrn, TRUE);
+}
+
+void
+NV1Setup(ScrnInfoPtr pScrn)
+{
+}
+
+void
+NV3Setup(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ CARD32 frameBase = pNv->FbAddress;
+ int mmioFlags;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV3Setup\n"));
+
+ /*
+ * Record chip architecture based in PCI probe.
+ */
+ pNv->riva.Architecture = 3;
+ /*
+ * Map chip-specific memory-mapped registers. This MUST be done in the OS specific driver code.
+ */
+#if !defined(__alpha__)
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
+#else
+ /*
+ * For Alpha, we need to map SPARSE memory, since we need
+ * byte/short access.
+ */
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT | VIDMEM_SPARSE;
+#endif
+ pNv->riva.PRAMIN = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ frameBase+0x00C00000, 0x00008000);
+
+ NVCommonSetup(pScrn);
+}
+
+void
+NV4Setup(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ CARD32 regBase = pNv->IOAddress;
+ int mmioFlags;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NV4Setup\n"));
+
+ pNv->riva.Architecture = 4;
+ /*
+ * Map chip-specific memory-mapped registers. This MUST be done in the OS specific driver code.
+ */
+#if !defined(__alpha__)
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
+#else
+ /*
+ * For Alpha, we need to map SPARSE memory, since we need
+ * byte/short access.
+ */
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT | VIDMEM_SPARSE;
+#endif
+ pNv->riva.PRAMIN = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00710000, 0x00010000);
+ pNv->riva.PCRTC = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, pNv->PciTag,
+ regBase+0x00600000, 0x00001000);
+
+ NVCommonSetup(pScrn);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_type.h b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_type.h
new file mode 100644
index 000000000..0de384999
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_type.h
@@ -0,0 +1,140 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_type.h,v 1.4 1999/08/28 09:01:06 dawes Exp $ */
+
+#ifndef __NV_STRUCT_H__
+#define __NV_STRUCT_H__
+
+#include "riva_hw.h"
+
+#define SetBitField(value,from,to) SetBF(to, GetBF(value,from))
+#define SetBit(n) (1<<(n))
+#define Set8Bits(value) ((value)&0xff)
+
+
+typedef RIVA_HW_STATE* NVRegPtr;
+
+typedef struct {
+ Bool isHwCursor;
+ int CursorMaxWidth;
+ int CursorMaxHeight;
+ int CursorFlags;
+ int CursorOffscreenMemSize;
+ Bool (*UseHWCursor)(ScreenPtr, CursorPtr);
+ void (*LoadCursorImage)(ScrnInfoPtr, unsigned char*);
+ void (*ShowCursor)(ScrnInfoPtr);
+ void (*HideCursor)(ScrnInfoPtr);
+ void (*SetCursorPosition)(ScrnInfoPtr, int, int);
+ void (*SetCursorColors)(ScrnInfoPtr, int, int);
+ long maxPixelClock;
+ long MemoryClock;
+ MessageType ClockFrom;
+ MessageType MemClkFrom;
+ Bool SetMemClk;
+ void (*LoadPalette)(ScrnInfoPtr, int, int*, LOCO*, VisualPtr);
+ void (*PreInit)(ScrnInfoPtr);
+ void (*Save)(ScrnInfoPtr, vgaRegPtr, NVRegPtr, Bool);
+ void (*Restore)(ScrnInfoPtr, vgaRegPtr, NVRegPtr, Bool);
+ Bool (*ModeInit)(ScrnInfoPtr, DisplayModePtr);
+} NVRamdacRec, *NVRamdacPtr;
+
+
+typedef struct {
+ RIVA_HW_INST riva;
+ RIVA_HW_STATE SavedReg;
+ RIVA_HW_STATE ModeReg;
+ EntityInfoPtr pEnt;
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ xf86AccessRec Access;
+ int Chipset;
+ int ChipRev;
+ Bool Primary;
+ Bool Interleave;
+ int HwBpp;
+ int Rounding;
+ int BppShift;
+ Bool HasFBitBlt;
+ Bool OverclockMem;
+ int YDstOrg;
+ int DstOrg;
+ int SrcOrg;
+ CARD32 IOAddress;
+ CARD32 FbAddress;
+ int FbBaseReg;
+ unsigned char * IOBase;
+#ifdef __alpha__
+ unsigned char * IOBaseDense;
+#endif
+ unsigned char * FbBase;
+ unsigned char * FbStart;
+ long FbMapSize;
+ long FbUsableSize;
+ long FbCursorOffset;
+ NVRamdacRec Dac;
+ Bool NoAccel;
+ Bool SyncOnGreen;
+ Bool Dac6Bit;
+ Bool HWCursor;
+ Bool UsePCIRetry;
+ Bool ShowCache;
+ Bool Overlay8Plus24;
+ Bool ShadowFB;
+ unsigned char * ShadowPtr;
+ int ShadowPitch;
+ int MemClk;
+ int MinClock;
+ int MaxClock;
+ CARD32 BltScanDirection;
+ CARD32 FilledRectCMD;
+ CARD32 SolidLineCMD;
+ CARD32 PatternRectCMD;
+ CARD32 DashCMD;
+ CARD32 NiceDashCMD;
+ CARD32 AccelFlags;
+ CARD32 PlaneMask;
+ CARD32 FgColor;
+ CARD32 BgColor;
+ int StyleLen;
+ XAAInfoRecPtr AccelInfoRec;
+ xf86CursorInfoPtr CursorInfoRec;
+ DGAModePtr DGAModes;
+ int numDGAModes;
+ Bool DGAactive;
+ int DGAViewportStatus;
+ CARD32 *Atype;
+ CARD32 *AtypeNoBLK;
+ void (*PreInit)(ScrnInfoPtr pScrn);
+ void (*Save)(ScrnInfoPtr, vgaRegPtr, NVRegPtr, Bool);
+ void (*Restore)(ScrnInfoPtr, vgaRegPtr, NVRegPtr, Bool);
+ Bool (*ModeInit)(ScrnInfoPtr, DisplayModePtr);
+ CloseScreenProcPtr CloseScreen;
+/* unsigned int (*ddc1Read)(ScrnInfoPtr);
+ void (*DDC1SetSpeed)(ScrnInfoPtr, xf86ddcSpeed);
+ Bool (*i2cInit)(ScrnInfoPtr);
+ I2CBusPtr I2C;*/
+ Bool FBDev;
+ int colorKey;
+ /* Color expansion */
+ Bool useFifo;
+ unsigned char *expandBuffer;
+ unsigned char *expandFifo;
+ int expandWidth;
+ int expandRows;
+} NVRec, *NVPtr;
+
+#define NVPTR(p) ((NVPtr)((p)->driverPrivate))
+
+
+typedef enum {
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+ OPTION_PCI_RETRY,
+ OPTION_RGB_BITS,
+ OPTION_NOACCEL,
+ OPTION_SHOWCACHE,
+ OPTION_SHADOW_FB,
+ OPTION_FBDEV,
+ OPTION_COLOR_KEY,
+ OPTION_SET_MCLK
+} NVOpts;
+
+#endif /* __NV_STRUCT_H__ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c
new file mode 100644
index 000000000..1b4d7c454
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c
@@ -0,0 +1,726 @@
+/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
+ /***************************************************************************\
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* NOTICE TO USER: The source code is copyrighted under U.S. and *|
+|* international laws. Users and possessors of this source code are *|
+|* hereby granted a nonexclusive, royalty-free copyright license to *|
+|* use this code in individual and commercial software. *|
+|* *|
+|* Any use of this source code must include, in the user documenta- *|
+|* tion and internal comments to the code, notices to the end user *|
+|* as follows: *|
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
+|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
+|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
+|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
+|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
+|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
+|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
+|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
+|* SULTING 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 SOURCE CODE. *|
+|* *|
+|* U.S. Government End Users. This source code is a "commercial *|
+|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
+|* consisting of "commercial computer software" and "commercial *|
+|* computer software documentation," as such terms are used in *|
+|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
+|* ment only as a commercial end item. Consistent with 48 C.F.R. *|
+|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
+|* all U.S. Government End Users acquire the source code with only *|
+|* those rights set forth herein. *|
+|* *|
+ \***************************************************************************/
+
+/* Hacked together from mga driver and 3.3.4 NVIDIA driver by
+ Jarno Paananen <jpaana@s2.org> */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c,v 1.3 1999/08/28 09:01:07 dawes Exp $ */
+
+#include "nv_include.h"
+#include "xaalocal.h"
+
+#include "nvreg.h"
+#include "nvvga.h"
+
+/*
+ * Macro to define valid rectangle.
+ */
+#define NV_RECT_VALID(rr) (((rr).x1 < (rr).x2) && ((rr).y1 < (rr).y2))
+
+
+/*
+ * 2D render flag for 3D code.
+ */
+int rivaRendered2D = 0;
+
+/*
+ * Opaque monochrome bits.
+ */
+unsigned int rivaOpaqueMonochrome;
+
+/*
+ * Set scissor clip rect.
+ */
+static void NVSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2)
+{
+ int height = y2-y1 + 1;
+ int width = x2-x1 + 1;
+ NVPtr pNv = NVPTR(pScrn);
+
+ rivaRendered2D = 1;
+ RIVA_FIFO_FREE(pNv->riva, Clip, 2);
+ pNv->riva.Clip->TopLeft = (y1 << 16) | (x1 & 0xffff);
+ pNv->riva.Clip->WidthHeight = (height << 16) | width;
+}
+
+static void NVDisableClipping(ScrnInfoPtr pScrn)
+{
+ NVSetClippingRectangle(pScrn, 0, 0, 0x7FFF, 0x7FFF);
+}
+
+/*
+ * Set pattern. Internal routine. The upper bits of the colors
+ * are the ALPHA bits. 0 == transparency.
+ */
+static void NVSetPattern(NVPtr pNv, int clr0, int clr1, int pat0,
+ int pat1)
+{
+ rivaRendered2D = 1;
+ RIVA_FIFO_FREE(pNv->riva, Patt, 5);
+ pNv->riva.Patt->Shape = 0; /* 0 = 8X8, 1 = 64X1, 2 = 1X64 */
+ pNv->riva.Patt->Color0 = clr0;
+ pNv->riva.Patt->Color1 = clr1;
+ pNv->riva.Patt->Monochrome[0] = pat0;
+ pNv->riva.Patt->Monochrome[1] = pat1;
+}
+
+/*
+ * Set ROP. Translate X rop into ROP3. Internal routine.
+ */
+static int currentRop = -1;
+static void NVSetRopSolid(NVPtr pNv, int rop)
+{
+ static int ropTrans[16] =
+ {
+ 0x00, /* GXclear */
+ 0x88, /* Gxand */
+ 0x44, /* GXandReverse */
+ 0xCC, /* GXcopy */
+ 0x22, /* GXandInverted */
+ 0xAA, /* GXnoop */
+ 0x66, /* GXxor */
+ 0xEE, /* GXor */
+ 0x11, /* GXnor */
+ 0x99, /* GXequiv */
+ 0x55, /* GXinvert */
+ 0xDD, /* GXorReverse */
+ 0x33, /* GXcopyInverted */
+ 0xBB, /* GXorInverted */
+ 0x77, /* GXnand */
+ 0xFF /* GXset */
+ };
+
+ if (currentRop != rop)
+ {
+ if (currentRop > 16)
+ NVSetPattern(pNv, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF);
+ currentRop = rop;
+ rivaRendered2D = 1;
+ RIVA_FIFO_FREE(pNv->riva, Rop, 1);
+ pNv->riva.Rop->Rop3 = ropTrans[rop];
+ }
+}
+
+static void NVSetRopPattern(NVPtr pNv, int rop)
+{
+ static int ropTrans[16] =
+ {
+ 0x00, /* GXclear */
+ 0xA0, /* Gxand */
+ 0x0A, /* GXandReverse */
+ 0xF0, /* GXcopy */
+ 0x30, /* GXandInverted */
+ 0xAA, /* GXnoop */
+ 0x3A, /* GXxor */
+ 0xFA, /* GXor */
+ 0x03, /* GXnor */
+ 0xA0, /* Gxequiv */
+ 0x0F, /* GXinvert */
+ 0xAF, /* GXorReverse */
+ 0x33, /* GXcopyInverted */
+ 0xBB, /* GXorInverted */
+ 0xF3, /* GXnand */
+ 0xFF /* GXset */
+ };
+
+ if (currentRop != rop + 16)
+ {
+ currentRop = rop + 16; /* +16 is important */
+ rivaRendered2D = 1;
+ RIVA_FIFO_FREE(pNv->riva, Rop, 1);
+ pNv->riva.Rop->Rop3 = ropTrans[rop];
+ }
+}
+
+/*
+ * Fill solid rectangles.
+ */
+static void NVSetupForSolidFill(ScrnInfoPtr pScrn,
+ int color, int rop, unsigned planemask)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ NVSetRopSolid(pNv, rop);
+ rivaRendered2D = 1;
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, 1);
+ pNv->riva.Bitmap->Color1A = color;
+}
+
+static void NVSubsequentSolidFillRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, 2);
+ pNv->riva.Bitmap->UnclippedRectangle[0].TopLeft = (x << 16) | y;
+ pNv->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h;
+}
+
+/*
+ * Screen to screen BLTs.
+ */
+static void NVSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned planemask,
+ int transparency_color)
+{
+ rivaRendered2D = 1;
+ NVSetRopSolid(NVPTR(pScrn), rop);
+}
+
+static void NVSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ RIVA_FIFO_FREE(pNv->riva, Blt, 3);
+ pNv->riva.Blt->TopLeftSrc = (y1 << 16) | x1;
+ pNv->riva.Blt->TopLeftDst = (y2 << 16) | x2;
+ pNv->riva.Blt->WidthHeight = (h << 16) | w;
+}
+
+
+/*
+ * Fill 8x8 monochrome pattern rectangles. patternx and patterny are
+ * the overloaded pattern bits themselves. The pattern colors don't
+ * support 565, only 555. Hack around it.
+ */
+static void NVSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int fg, int bg, int rop,
+ unsigned planemask)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ NVSetRopPattern(pNv, rop);
+ rivaRendered2D = 1;
+ if (pScrn->bitsPerPixel == 16 && pScrn->weight.green == 6)
+ {
+ fg = ((fg & 0x0000F800) << 8)
+ | ((fg & 0x000007E0) << 5)
+ | ((fg & 0x0000001F) << 3)
+ | 0xFF000000;
+ if (bg != -1)
+ bg = ((bg & 0x0000F800) << 8)
+ | ((bg & 0x000007E0) << 5)
+ | ((bg & 0x0000001F) << 3)
+ | 0xFF000000;
+ else
+ bg = 0;
+ }
+ else
+ {
+ fg |= rivaOpaqueMonochrome;
+ bg = (bg == -1) ? 0 : bg | rivaOpaqueMonochrome;
+ };
+ NVSetPattern(pNv, bg, fg, patternx, patterny);
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, 1);
+ pNv->riva.Bitmap->Color1A = fg;
+}
+
+static void NVSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y, int w, int h)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, 2);
+ pNv->riva.Bitmap->UnclippedRectangle[0].TopLeft = (x << 16) | y;
+ pNv->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h;
+}
+
+
+
+/*
+ * Synchronise with graphics engine. Make sure it is idle before returning.
+ * Should attempt to yield CPU if busy for awhile.
+ *
+ * Also used in an evil hack with the color expansion
+ */
+void NVSync(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ while (pNv->riva.Busy(&pNv->riva));
+}
+
+/* Color expansion */
+static void
+NVSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ rivaRendered2D = 1;
+
+ NVSetRopSolid(pNv, rop);
+
+ if ( bg == -1 )
+ {
+ /* Transparent case */
+ bg = 0x80000000;
+ pNv->expandFifo = (unsigned char*)&pNv->riva.Bitmap->MonochromeData1C;
+ }
+ else
+ {
+ pNv->expandFifo = (unsigned char*)&pNv->riva.Bitmap->MonochromeData01E;
+ if (pScrn->bitsPerPixel == 16 && pScrn->weight.green == 6)
+ {
+ bg = ((bg & 0x0000F800) << 8)
+ | ((bg & 0x000007E0) << 5)
+ | ((bg & 0x0000001F) << 3)
+ | 0xFF000000;
+ }
+ else
+ {
+ bg |= rivaOpaqueMonochrome;
+ };
+ }
+ pNv->FgColor = fg;
+ pNv->BgColor = bg;
+}
+
+static void
+NVSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h,
+ int skipleft)
+{
+ int bw;
+ NVPtr pNv = NVPTR(pScrn);
+
+ bw = (w + 31) & ~31;
+ pNv->expandWidth = bw >> 5;
+
+ if ( pNv->BgColor == 0x80000000 )
+ {
+ /* Use faster transparent method */
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, 5);
+ pNv->riva.Bitmap->ClipC.TopLeft = (y << 16) | ((x+skipleft) & 0xFFFF);
+ pNv->riva.Bitmap->ClipC.BottomRight = ((y+h) << 16) | ((x+w)&0xffff);
+ pNv->riva.Bitmap->Color1C = pNv->FgColor;
+ pNv->riva.Bitmap->WidthHeightC = (h << 16) | bw;
+ pNv->riva.Bitmap->PointC = (y << 16) | (x & 0xFFFF);
+ }
+ else
+ {
+ /* Opaque */
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, 7);
+ pNv->riva.Bitmap->ClipE.TopLeft = (y << 16) | ((x+skipleft) & 0xFFFF);
+ pNv->riva.Bitmap->ClipE.BottomRight = ((y+h) << 16) | ((x+w)&0xffff);
+ pNv->riva.Bitmap->Color0E = pNv->BgColor;
+ pNv->riva.Bitmap->Color1E = pNv->FgColor;
+ pNv->riva.Bitmap->WidthHeightInE = (h << 16) | bw;
+ pNv->riva.Bitmap->WidthHeightOutE = (h << 16) | bw;
+ pNv->riva.Bitmap->PointE = (y << 16) | (x & 0xFFFF);
+ }
+
+ if ( pNv->useFifo )
+ {
+ /* Using fifo writes, set it up */
+ pNv->expandRows = h;
+ while (pNv->riva.Busy(&pNv->riva));
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, pNv->expandWidth);
+ }
+}
+
+
+static void
+NVSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ int t = pNv->expandWidth;
+ unsigned int *pbits = (unsigned int*)pNv->expandBuffer;
+ unsigned int *d = (unsigned int*)pNv->expandFifo;
+
+ while (pNv->riva.Busy(&pNv->riva));
+ while(t >= 4)
+ {
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, 4);
+ d[0] = pbits[0]; /* burst */
+ d[1] = pbits[1];
+ d[2] = pbits[2];
+ d[3] = pbits[3];
+ t -= 4; d += 4; pbits += 4;
+ }
+
+ while(t--)
+ {
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, 1);
+ *d++ = *pbits++;
+ }
+}
+
+static void
+NVSubsequentColorExpandScanlineFifo(ScrnInfoPtr pScrn, int bufno)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ if ( --pNv->expandRows )
+ {
+ while (pNv->riva.Busy(&pNv->riva));
+ RIVA_FIFO_FREE(pNv->riva, Bitmap, pNv->expandWidth);
+ }
+}
+
+
+/* Image writes */
+static void
+NVSetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int transparency_color,
+ int bpp, int depth)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setup\n"
+ "rop %i\n"
+ "planemask %i\n"
+ "transparency_color %i\n"
+ "bpp %i\n"
+ "depth %i\n",
+ rop, planemask, transparency_color, bpp, depth);
+
+ rivaRendered2D = 1;
+ NVSetRopSolid(pNv, rop);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "-Done\n");
+}
+
+static void
+NVSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h, int skipleft)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ int bpp = pScrn->bitsPerPixel/8;
+ int bw = ((w * bpp) + 3) & ~3;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Subsequent\n"
+ "x %i\n"
+ "y %i\n"
+ "w %i\n"
+ "h %i\n"
+ "skip %i\n"
+ "bw %i\n"
+ "bpp %i\n",
+ x, y, w, h, skipleft, bw, bpp);
+
+ pNv->expandWidth = bw >> 2;
+
+ RIVA_FIFO_FREE(pNv->riva, Pixmap, 3);
+ pNv->riva.Pixmap->TopLeft = (y << 16) | (x & 0xFFFF);
+ pNv->riva.Pixmap->WidthHeight = (h << 16) | w;
+ pNv->riva.Pixmap->WidthHeightIn = (h << 16) | w;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "-Done\n");
+}
+
+
+static void
+NVSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ int t = pNv->expandWidth;
+ unsigned int *pbits = (unsigned int*)pNv->expandBuffer;
+ unsigned int *d = (unsigned int*)&pNv->riva.Pixmap->Pixels;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Write %i\n", t);
+
+ while (pNv->riva.Busy(&pNv->riva));
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Synced\n");
+
+ do
+ {
+ RIVA_FIFO_FREE(pNv->riva, Pixmap, 1);
+ *d = *pbits++;
+ }while(--t);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "-Done\n");
+}
+
+
+
+/* Initialize XAA acceleration info */
+Bool
+NVAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+ BoxRec AvailFBArea;
+
+ pNv->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if(!infoPtr) return FALSE;
+
+ /* fill out infoPtr here */
+/* infoPtr->Flags = PIXMAP_CACHE |
+ OFFSCREEN_PIXMAPS |
+ LINEAR_FRAMEBUFFER |
+ MICROSOFT_ZERO_LINE_BIAS;
+*/
+ infoPtr->Flags = LINEAR_FRAMEBUFFER | PIXMAP_CACHE | OFFSCREEN_PIXMAPS;
+
+ /* Initialize pixmap cache */
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = pNv->FbUsableSize / (pScrn->displayWidth * pScrn->bitsPerPixel / 8);
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ /* sync */
+ infoPtr->Sync = NVSync;
+
+ /* solid fills */
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill = NVSetupForSolidFill;
+ infoPtr->SubsequentSolidFillRect = NVSubsequentSolidFillRect;
+/* infoPtr->SubsequentSolidFillTrap = NVSubsequentSolidFillTrap; */
+
+ /* screen to screen copy */
+ infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK;
+ infoPtr->SetupForScreenToScreenCopy = NVSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy = NVSubsequentScreenToScreenCopy;
+
+ /* 8x8 mono patterns */
+ /*
+ * Set pattern opaque bits based on pixel format.
+ */
+ switch (pScrn->bitsPerPixel)
+ {
+ case 8:
+ rivaOpaqueMonochrome = 0xFFFFFF00;
+ break;
+ case 15:
+ case 16:
+ rivaOpaqueMonochrome = (pScrn->weight.green == 5) ? 0xFFFF8000 : 0xFFFF0000;
+ break;
+ default:
+ rivaOpaqueMonochrome = 0xFF000000;
+ }
+
+ infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_SCREEN_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS | NO_PLANEMASK;
+ infoPtr->SetupForMono8x8PatternFill = NVSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ NVSubsequentMono8x8PatternFillRect;
+ /*infoPtr->SubsequentMono8x8PatternFillTrap =
+ NVSubsequentMono8x8PatternFillTrap; */
+
+ /* clipping */
+ infoPtr->SetClippingRectangle = NVSetClippingRectangle;
+ infoPtr->DisableClipping = NVDisableClipping;
+ infoPtr->ClippingFlags = /*HARDWARE_CLIP_SOLID_FILL |
+ HARDWARE_CLIP_MONO_8x8_FILL | */
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY;
+
+ /* Color expansion */
+ infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_LSBFIRST | NO_PLANEMASK | CPU_TRANSFER_PAD_DWORD |
+ LEFT_EDGE_CLIPPING | LEFT_EDGE_CLIPPING_NEGATIVE_X;
+
+ infoPtr->NumScanlineColorExpandBuffers = 1;
+ infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
+ NVSetupForScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
+ NVSubsequentScanlineCPUToScreenColorExpandFill;
+
+ pNv->expandFifo = (unsigned char*)&pNv->riva.Bitmap->MonochromeData01E;
+
+ /* Allocate buffer for color expansion and also image writes in the
+ future */
+ pNv->expandBuffer = xnfalloc((pScrn->virtualX + 62)
+ * pScrn->bitsPerPixel / 8);
+ if ( pNv->riva.Architecture == 3 )
+ {
+ /* Riva 128(ZX) can't use direct fifo writes, so we use buffer */
+ pNv->useFifo = FALSE;
+ infoPtr->ScanlineColorExpandBuffers = &pNv->expandBuffer;
+ infoPtr->SubsequentColorExpandScanline =
+ NVSubsequentColorExpandScanline;
+ }
+ else
+ {
+ /* TNT(2) can */
+ pNv->useFifo = TRUE;
+ infoPtr->ScanlineColorExpandBuffers = &pNv->expandFifo;
+ infoPtr->SubsequentColorExpandScanline =
+ NVSubsequentColorExpandScanlineFifo;
+ }
+#if 0
+ /* Image writes */
+ infoPtr->ScanlineImageWriteFlags = CPU_TRANSFER_PAD_DWORD |
+ SCANLINE_PAD_DWORD |
+/* LEFT_EDGE_CLIPPING |
+ LEFT_EDGE_CLIPPING_NEGATIVE_X; */
+ NO_PLANEMASK | NO_TRANSPARENCY |
+ NO_GXCOPY;
+
+ infoPtr->SetupForScanlineImageWrite = NVSetupForScanlineImageWrite;
+ infoPtr->SubsequentScanlineImageWriteRect =
+ NVSubsequentScanlineImageWriteRect;
+ infoPtr->SubsequentImageWriteScanline = NVSubsequentImageWriteScanline;
+
+ /* We reuse the same buffer as color expansion */
+ infoPtr->NumScanlineImageWriteBuffers = 1;
+ infoPtr->ScanlineImageWriteBuffers = &pNv->expandBuffer;
+#endif
+#if 0
+ /* Left-overs from mga driver */
+ /* solid lines */
+ infoPtr->SetupForSolidLine = infoPtr->SetupForSolidFill;
+ infoPtr->SubsequentSolidHorVertLine =
+ NVNAME(SubsequentSolidHorVertLine);
+ infoPtr->SubsequentSolidTwoPointLine =
+ NVNAME(SubsequentSolidTwoPointLine);
+
+
+ /* dashed lines */
+ infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED;
+ infoPtr->SetupForDashedLine = NVNAME(SetupForDashedLine);
+ infoPtr->SubsequentDashedTwoPointLine =
+ NVNAME(SubsequentDashedTwoPointLine);
+ infoPtr->DashPatternMaxLength = 128;
+
+
+ /* cpu to screen color expansion */
+ infoPtr->CPUToScreenColorExpandFillFlags = CPU_TRANSFER_PAD_DWORD |
+ SCANLINE_PAD_DWORD |
+ BIT_ORDER_IN_BYTE_LSBFIRST |
+ LEFT_EDGE_CLIPPING |
+ LEFT_EDGE_CLIPPING_NEGATIVE_X |
+ SYNC_AFTER_COLOR_EXPAND;
+ if(pNv->ILOADBase) {
+ infoPtr->ColorExpandRange = 0x800000;
+ infoPtr->ColorExpandBase = pNv->ILOADBase;
+ } else {
+ infoPtr->ColorExpandRange = 0x1C00;
+ infoPtr->ColorExpandBase = pNv->IOBase;
+ }
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ NVNAME(SetupForCPUToScreenColorExpandFill);
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ NVNAME(SubsequentCPUToScreenColorExpandFill);
+
+
+ /* screen to screen color expansion */
+ if(pNv->AccelFlags & USE_LINEAR_EXPANSION) {
+ infoPtr->ScreenToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_LSBFIRST;
+ infoPtr->SetupForScreenToScreenColorExpandFill =
+ NVNAME(SetupForScreenToScreenColorExpandFill);
+ infoPtr->SubsequentScreenToScreenColorExpandFill =
+ NVNAME(SubsequentScreenToScreenColorExpandFill);
+ } else {
+#if PSZ != 24
+ /* Alternate (but slower) planar expansions */
+ infoPtr->SetupForScreenToScreenColorExpandFill =
+ NVNAME(SetupForPlanarScreenToScreenColorExpandFill);
+ infoPtr->SubsequentScreenToScreenColorExpandFill =
+ NVNAME(SubsequentPlanarScreenToScreenColorExpandFill);
+ infoPtr->CacheColorExpandDensity = PSZ;
+ infoPtr->CacheMonoStipple = XAACachePlanarMonoStipple;
+ /* It's faster to blit the stipples if you have fastbilt */
+ if(pNv->HasFBitBlt)
+ infoPtr->ScreenToScreenColorExpandFillFlags = TRANSPARENCY_ONLY;
+#endif
+ }
+
+ /* image reads */
+ infoPtr->ImageReadFlags = CPU_TRANSFER_PAD_DWORD |
+ SCANLINE_PAD_DWORD;
+ if(pNv->ILOADBase) {
+ infoPtr->ImageReadRange = 0x800000;
+ infoPtr->ImageReadBase = pNv->ILOADBase;
+ } else {
+ infoPtr->ImageReadRange = 0x1C00;
+ infoPtr->ImageReadBase = pNv->IOBase;
+ }
+ infoPtr->SetupForImageRead = NVNAME(SetupForImageRead);
+ infoPtr->SubsequentImageReadRect = NVNAME(SubsequentImageReadRect);
+
+ /* midrange replacements */
+
+ if(infoPtr->SetupForCPUToScreenColorExpandFill &&
+ infoPtr->SubsequentCPUToScreenColorExpandFill) {
+ infoPtr->FillColorExpandRects = NVFillColorExpandRects;
+ infoPtr->WriteBitmap = NVWriteBitmapColorExpand;
+ if(BITMAP_SCANLINE_PAD == 32)
+ infoPtr->NonTEGlyphRenderer = NVNonTEGlyphRenderer;
+ }
+
+ if(pNv->ILOADBase && pNv->UsePCIRetry && infoPtr->SetupForSolidFill) {
+ infoPtr->FillSolidRects = NVFillSolidRectsDMA;
+ infoPtr->FillSolidSpans = NVFillSolidSpansDMA;
+ }
+
+ if(pNv->AccelFlags & TWO_PASS_COLOR_EXPAND) {
+ if(infoPtr->SetupForMono8x8PatternFill)
+ infoPtr->FillMono8x8PatternRects =
+ NVFillMono8x8PatternRectsTwoPass;
+ }
+
+ infoPtr->ValidatePolyArc = NVValidatePolyArc;
+ infoPtr->PolyArcMask = GCFunction | GCLineWidth | GCPlaneMask |
+ GCLineStyle | GCFillStyle;
+
+ if((PSZ == 24) || (pNv->AccelFlags & NV_NO_PLANEMASK)) {
+ infoPtr->ImageWriteFlags |= NO_PLANEMASK;
+ infoPtr->ScreenToScreenCopyFlags |= NO_PLANEMASK;
+ infoPtr->CPUToScreenColorExpandFillFlags |= NO_PLANEMASK;
+ infoPtr->WriteBitmapFlags |= NO_PLANEMASK;
+ infoPtr->SolidFillFlags |= NO_PLANEMASK;
+ infoPtr->SolidLineFlags |= NO_PLANEMASK;
+ infoPtr->DashedLineFlags |= NO_PLANEMASK;
+ infoPtr->Mono8x8PatternFillFlags |= NO_PLANEMASK;
+ infoPtr->FillColorExpandRectsFlags |= NO_PLANEMASK;
+ infoPtr->ScreenToScreenColorExpandFillFlags |= NO_PLANEMASK;
+ infoPtr->FillSolidRectsFlags |= NO_PLANEMASK;
+ infoPtr->FillSolidSpansFlags |= NO_PLANEMASK;
+ infoPtr->FillMono8x8PatternRectsFlags |= NO_PLANEMASK;
+ infoPtr->NonTEGlyphRendererFlags |= NO_PLANEMASK;
+ infoPtr->FillCacheBltRectsFlags |= NO_PLANEMASK;
+ }
+#endif
+
+ NVSetClippingRectangle(pScrn, 0, 0, 0x7fff, 0x7fff);
+ return(XAAInit(pScreen, infoPtr));
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nvreg.h b/xc/programs/Xserver/hw/xfree86/drivers/nv/nvreg.h
new file mode 100644
index 000000000..9a8402211
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nvreg.h
@@ -0,0 +1,209 @@
+/* $XConsortium: nvreg.h /main/2 1996/10/28 05:13:41 kaleb $ */
+/*
+ * Copyright 1996-1997 David J. McKay
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * DAVID J. MCKAY 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.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nvreg.h,v 1.4 1999/08/01 07:20:59 dawes Exp $ */
+
+#ifndef __NVREG_H_
+#define __NVREG_H_
+
+/* Little macro to construct bitmask for contiguous ranges of bits */
+#define BITMASK(t,b) (((unsigned)(1U << (((t)-(b)+1)))-1) << (b))
+#define MASKEXPAND(mask) BITMASK(1?mask,0?mask)
+
+/* Macro to set specific bitfields (mask has to be a macro x:y) ! */
+#define SetBF(mask,value) ((value) << (0?mask))
+#define GetBF(var,mask) (((unsigned)((var) & MASKEXPAND(mask))) >> (0?mask) )
+
+#define MaskAndSetBF(var,mask,value) (var)=(((var)&(~MASKEXPAND(mask)) \
+ | SetBF(mask,value)))
+
+#define DEVICE_BASE(device) (0?NV##_##device)
+#define DEVICE_SIZE(device) ((1?NV##_##device) - DEVICE_BASE(device)+1)
+
+/* This is where we will have to have conditional compilation */
+#define DEVICE_ACCESS(device,reg) \
+ nv##device##Port[((NV_##device##_##reg)-DEVICE_BASE(device))/4]
+
+#define DEVICE_WRITE(device,reg,value) DEVICE_ACCESS(device,reg)=(value)
+#define DEVICE_READ(device,reg) DEVICE_ACCESS(device,reg)
+#define DEVICE_PRINT(device,reg) \
+ ErrorF("NV_"#device"_"#reg"=#%08lx\n",DEVICE_ACCESS(device,reg))
+#define DEVICE_DEF(device,mask,value) \
+ SetBF(NV_##device##_##mask,NV_##device##_##mask##_##value)
+#define DEVICE_VALUE(device,mask,value) SetBF(NV_##device##_##mask,value)
+#define DEVICE_MASK(device,mask) MASKEXPAND(NV_##device##_##mask)
+
+#define PDAC_Write(reg,value) DEVICE_WRITE(PDAC,reg,value)
+#define PDAC_Read(reg) DEVICE_READ(PDAC,reg)
+#define PDAC_Print(reg) DEVICE_PRINT(PDAC,reg)
+#define PDAC_Def(mask,value) DEVICE_DEF(PDAC,mask,value)
+#define PDAC_Val(mask,value) DEVICE_VALUE(PDAC,mask,value)
+#define PDAC_Mask(mask) DEVICE_MASK(PDAC,mask)
+
+#define PFB_Write(reg,value) DEVICE_WRITE(PFB,reg,value)
+#define PFB_Read(reg) DEVICE_READ(PFB,reg)
+#define PFB_Print(reg) DEVICE_PRINT(PFB,reg)
+#define PFB_Def(mask,value) DEVICE_DEF(PFB,mask,value)
+#define PFB_Val(mask,value) DEVICE_VALUE(PFB,mask,value)
+#define PFB_Mask(mask) DEVICE_MASK(PFB,mask)
+
+#define PRM_Write(reg,value) DEVICE_WRITE(PRM,reg,value)
+#define PRM_Read(reg) DEVICE_READ(PRM,reg)
+#define PRM_Print(reg) DEVICE_PRINT(PRM,reg)
+#define PRM_Def(mask,value) DEVICE_DEF(PRM,mask,value)
+#define PRM_Val(mask,value) DEVICE_VALUE(PRM,mask,value)
+#define PRM_Mask(mask) DEVICE_MASK(PRM,mask)
+
+#define PGRAPH_Write(reg,value) DEVICE_WRITE(PGRAPH,reg,value)
+#define PGRAPH_Read(reg) DEVICE_READ(PGRAPH,reg)
+#define PGRAPH_Print(reg) DEVICE_PRINT(PGRAPH,reg)
+#define PGRAPH_Def(mask,value) DEVICE_DEF(PGRAPH,mask,value)
+#define PGRAPH_Val(mask,value) DEVICE_VALUE(PGRAPH,mask,value)
+#define PGRAPH_Mask(mask) DEVICE_MASK(PGRAPH,mask)
+
+#define PDMA_Write(reg,value) DEVICE_WRITE(PDMA,reg,value)
+#define PDMA_Read(reg) DEVICE_READ(PDMA,reg)
+#define PDMA_Print(reg) DEVICE_PRINT(PDMA,reg)
+#define PDMA_Def(mask,value) DEVICE_DEF(PDMA,mask,value)
+#define PDMA_Val(mask,value) DEVICE_VALUE(PDMA,mask,value)
+#define PDMA_Mask(mask) DEVICE_MASK(PDMA,mask)
+
+#define PTIMER_Write(reg,value) DEVICE_WRITE(PTIMER,reg,value)
+#define PTIMER_Read(reg) DEVICE_READ(PTIMER,reg)
+#define PTIMER_Print(reg) DEVICE_PRINT(PTIMER,reg)
+#define PTIMER_Def(mask,value) DEVICE_DEF(PTIMER,mask,value)
+#define PTIMER_Val(mask,value) DEVICE_VALUE(PTIEMR,mask,value)
+#define PTIMER_Mask(mask) DEVICE_MASK(PTIMER,mask)
+
+#define PEXTDEV_Write(reg,value) DEVICE_WRITE(PEXTDEV,reg,value)
+#define PEXTDEV_Read(reg) DEVICE_READ(PEXTDEV,reg)
+#define PEXTDEV_Print(reg) DEVICE_PRINT(PEXTDEV,reg)
+#define PEXTDEV_Def(mask,value) DEVICE_DEF(PEXTDEV,mask,value)
+#define PEXTDEV_Val(mask,value) DEVICE_VALUE(PEXTDEV,mask,value)
+#define PEXTDEV_Mask(mask) DEVICE_MASK(PEXTDEV,mask)
+
+#define PFIFO_Write(reg,value) DEVICE_WRITE(PFIFO,reg,value)
+#define PFIFO_Read(reg) DEVICE_READ(PFIFO,reg)
+#define PFIFO_Print(reg) DEVICE_PRINT(PFIFO,reg)
+#define PFIFO_Def(mask,value) DEVICE_DEF(PFIFO,mask,value)
+#define PFIFO_Val(mask,value) DEVICE_VALUE(PFIFO,mask,value)
+#define PFIFO_Mask(mask) DEVICE_MASK(PFIFO,mask)
+
+#define PRAM_Write(reg,value) DEVICE_WRITE(PRAM,reg,value)
+#define PRAM_Read(reg) DEVICE_READ(PRAM,reg)
+#define PRAM_Print(reg) DEVICE_PRINT(PRAM,reg)
+#define PRAM_Def(mask,value) DEVICE_DEF(PRAM,mask,value)
+#define PRAM_Val(mask,value) DEVICE_VALUE(PRAM,mask,value)
+#define PRAM_Mask(mask) DEVICE_MASK(PRAM,mask)
+
+#define PRAMFC_Write(reg,value) DEVICE_WRITE(PRAMFC,reg,value)
+#define PRAMFC_Read(reg) DEVICE_READ(PRAMFC,reg)
+#define PRAMFC_Print(reg) DEVICE_PRINT(PRAMFC,reg)
+#define PRAMFC_Def(mask,value) DEVICE_DEF(PRAMFC,mask,value)
+#define PRAMFC_Val(mask,value) DEVICE_VALUE(PRAMFC,mask,value)
+#define PRAMFC_Mask(mask) DEVICE_MASK(PRAMFC,mask)
+
+#define PMC_Write(reg,value) DEVICE_WRITE(PMC,reg,value)
+#define PMC_Read(reg) DEVICE_READ(PMC,reg)
+#define PMC_Print(reg) DEVICE_PRINT(PMC,reg)
+#define PMC_Def(mask,value) DEVICE_DEF(PMC,mask,value)
+#define PMC_Val(mask,value) DEVICE_VALUE(PMC,mask,value)
+#define PMC_Mask(mask) DEVICE_MASK(PMC,mask)
+
+#define PMC_Write(reg,value) DEVICE_WRITE(PMC,reg,value)
+#define PMC_Read(reg) DEVICE_READ(PMC,reg)
+#define PMC_Print(reg) DEVICE_PRINT(PMC,reg)
+#define PMC_Def(mask,value) DEVICE_DEF(PMC,mask,value)
+#define PMC_Val(mask,value) DEVICE_VALUE(PMC,mask,value)
+#define PMC_Mask(mask) DEVICE_MASK(PMC,mask)
+
+
+#define PBUS_Write(reg,value) DEVICE_WRITE(PBUS,reg,value)
+#define PBUS_Read(reg) DEVICE_READ(PBUS,reg)
+#define PBUS_Print(reg) DEVICE_PRINT(PBUS,reg)
+#define PBUS_Def(mask,value) DEVICE_DEF(PBUS,mask,value)
+#define PBUS_Val(mask,value) DEVICE_VALUE(PBUS,mask,value)
+#define PBUS_Mask(mask) DEVICE_MASK(PBUS,mask)
+
+
+#define PRAMDAC_Write(reg,value) DEVICE_WRITE(PRAMDAC,reg,value)
+#define PRAMDAC_Read(reg) DEVICE_READ(PRAMDAC,reg)
+#define PRAMDAC_Print(reg) DEVICE_PRINT(PRAMDAC,reg)
+#define PRAMDAC_Def(mask,value) DEVICE_DEF(PRAMDAC,mask,value)
+#define PRAMDAC_Val(mask,value) DEVICE_VALUE(PRAMDAC,mask,value)
+#define PRAMDAC_Mask(mask) DEVICE_MASK(PRAMDAC,mask)
+
+
+#define PDAC_ReadExt(reg) \
+ ((PDAC_Write(INDEX_LO,(NV_PDAC_EXT_##reg) & 0xff)),\
+ (PDAC_Write(INDEX_HI,((NV_PDAC_EXT_##reg) >> 8) & 0xff)),\
+ (PDAC_Read(INDEX_DATA)))
+
+#define PDAC_WriteExt(reg,value)\
+ ((PDAC_Write(INDEX_LO,(NV_PDAC_EXT_##reg) & 0xff)),\
+ (PDAC_Write(INDEX_HI,((NV_PDAC_EXT_##reg) >> 8) & 0xff)),\
+ (PDAC_Write(INDEX_DATA,(value))))
+
+#define CRTC_Write(index,value) outb(0x3d4,(index));outb(0x3d5,value)
+#define CRTC_Read(index) (outb(0x3d4,index),inb(0x3d5))
+
+#define PCRTC_Write(index,value) CRTC_Write(NV_PCRTC_##index,value)
+#define PCRTC_Read(index) CRTC_Read(NV_PCRTC_##index)
+
+#define PCRTC_Def(mask,value) DEVICE_DEF(PCRTC,mask,value)
+#define PCRTC_Val(mask,value) DEVICE_VALUE(PCRTC,mask,value)
+#define PCRTC_Mask(mask) DEVICE_MASK(PCRTC,mask)
+
+#define SR_Write(index,value) outb(0x3c4,(index));outb(0x3c5,value)
+#define SR_Read(index) (outb(0x3c4,index),inb(0x3c5))
+
+
+/* These are the variables which actually point at the register blocks */
+extern volatile unsigned *nvPDACPort; /* Points to the DAC */
+extern volatile unsigned *nvPFBPort; /* Points to the Frame buffer */
+extern volatile unsigned *nvPRMPort; /* Points to real mode stuff */
+extern volatile unsigned *nvPGRAPHPort; /* Graphics unit */
+extern volatile unsigned *nvPDMAPort; /* DMA engine */
+extern volatile unsigned *nvPFIFOPort; /* FIFO registers */
+extern volatile unsigned *nvPTIMERPort; /* TIMER registers */
+extern volatile unsigned *nvPEXTDEVPort; /* EXTDEV registers */
+extern volatile unsigned *nvPRAMPort; /* Priviliged RAM registers */
+extern volatile unsigned *nvPRAMFCPort; /* Priviliged RAM (Fifo) */
+extern volatile unsigned *nvPRAMHTPort; /* Priviliged RAM (hash) */
+extern volatile unsigned *nvPMCPort; /* Priviliged RAM (hash) */
+extern volatile unsigned *nvCHAN0Port; /* User channel 0 */
+extern volatile unsigned *nvPRAMDACPort; /* Points to the RAMDAC */
+extern volatile unsigned *nvPRAMINPort; /* Privileges instance memory */
+extern volatile unsigned *nvPBUSPort; /* Priviled Bus */
+extern volatile unsigned *nvPNVMPort; /* Priviled Bus */
+extern volatile unsigned *dumb; /* FrameBuffer - hack!!!! */
+
+
+typedef enum {NV1,NV3,NV4,NumNVChips} NVChipType;
+
+NVChipType GetChipType(void);
+
+
+#endif
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/nvvga.h b/xc/programs/Xserver/hw/xfree86/drivers/nv/nvvga.h
new file mode 100644
index 000000000..c8c34a1fb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/nvvga.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright 1996-1997 David J. McKay
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * DAVID J. MCKAY 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.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nvvga.h,v 1.1 1999/08/01 07:21:00 dawes Exp $ */
+
+#ifndef __NVVGA_H__
+#define __NVVGA_H__
+
+#ifndef __RIVA_HW_H__
+#include "riva_hw.h"
+#endif
+
+#define PALETTE_SIZE 256
+
+#define NV_PDAC_CURSOR_SIZE 32
+#define NV_PDAC_CURSOR_PLANE_SIZE (NV_PDAC_CURSOR_SIZE*4)
+
+/* This is the structure for the NV1. It is not a VGA based core */
+
+typedef struct {
+ unsigned char Nparam, Mparam, Oparam, Pparam;
+ unsigned char NparamMPLL, MparamMPLL, OparamMPLL, PparamMPLL;
+ unsigned char dacConfReg0;
+ unsigned char dacConfReg1;
+ unsigned char dacRgbPalCtrl;
+ unsigned long confReg0;
+ unsigned long green0; /* DPMS and sync polarity control */
+ unsigned long memoryTrace;
+ unsigned long startAddr; /* Where to start reading out from the buffer */
+ /* All the following registers control the display */
+ unsigned long prmConfig0; /* Controls if text mode on or off */
+ unsigned long horFrontPorch; /* Front porch in pixels */
+ unsigned long horSyncWidth; /* Sync Width in pixels */
+ unsigned long horBackPorch; /* horizontal back porch in in pixels */
+ unsigned long horDispWidth; /* Horizontal display width in pixels */
+ unsigned long verFrontPorch; /* Vertical front porch in lines */
+ unsigned long verSyncWidth; /* Vertical sync width in lines */
+ unsigned long verBackPorch; /* Vertical back porch in lines */
+ unsigned long verDispWidth; /* Vertical display width in lines */
+ /* Hardware cursor registers */
+ unsigned char cursorCtrl;
+ unsigned char xHi,xLo,yHi,yLo;
+ unsigned char colour1[3]; /* RGB values for cursor planes */
+ unsigned char colour2[3];
+ unsigned char colour3[3];
+ unsigned char plane0[NV_PDAC_CURSOR_PLANE_SIZE];
+ unsigned char plane1[NV_PDAC_CURSOR_PLANE_SIZE];
+ unsigned char palette[PALETTE_SIZE][3];
+}NV1Registers;
+
+/*
+ * Driver data structures.
+ */
+typedef struct {
+/* vgaHWRec std; good old IBM VGA */
+ int vgaValid; /* is the above state valid?? */
+ NVChipType type; /* What the union holds */
+
+ union {
+ NV1Registers nv1;
+ RIVA_HW_STATE RivaState;
+ }regs;
+} vgaNVRec, *vgaNVPtr;
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.c b/xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.c
new file mode 100644
index 000000000..9cee62ce8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.c
@@ -0,0 +1,1368 @@
+ /***************************************************************************\
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* NOTICE TO USER: The source code is copyrighted under U.S. and *|
+|* international laws. Users and possessors of this source code are *|
+|* hereby granted a nonexclusive, royalty-free copyright license to *|
+|* use this code in individual and commercial software. *|
+|* *|
+|* Any use of this source code must include, in the user documenta- *|
+|* tion and internal comments to the code, notices to the end user *|
+|* as follows: *|
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
+|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
+|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
+|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
+|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
+|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
+|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
+|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
+|* SULTING 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 SOURCE CODE. *|
+|* *|
+|* U.S. Government End Users. This source code is a "commercial *|
+|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
+|* consisting of "commercial computer software" and "commercial *|
+|* computer software documentation," as such terms are used in *|
+|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
+|* ment only as a commercial end item. Consistent with 48 C.F.R. *|
+|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
+|* all U.S. Government End Users acquire the source code with only *|
+|* those rights set forth herein. *|
+|* *|
+ \***************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.c,v 1.3 1999/08/28 09:01:07 dawes Exp $ */
+
+#include "riva_hw.h"
+#include "riva_tbl.h"
+/*#include "nv_local.h" */
+#include "compiler.h"
+/*
+ * This file is an OS-agnostic file used to make RIVA 128 and RIVA TNT
+ * operate identically (except TNT has more memory and better 3D quality.
+ */
+static int nv3Busy
+(
+ RIVA_HW_INST *chip
+)
+{
+ return ((chip->FIFO[5] < chip->FifoEmptyCount) || (chip->PGRAPH[0x000006B0/4] & 0x01));
+}
+static int nv4Busy
+(
+ RIVA_HW_INST *chip
+)
+{
+ return ((chip->FIFO[5] < chip->FifoEmptyCount) || (chip->PGRAPH[0x00000700/4] & 0x01));
+}
+
+static int ShowHideCursor
+(
+ RIVA_HW_INST *chip,
+ int ShowHide
+)
+{
+ int current;
+ current = chip->CurrentState->cursor1;
+ chip->CurrentState->cursor1 = (chip->CurrentState->cursor1 & 0xFE) | (ShowHide & 0x01);
+ outb(0x3D4,0x31);
+ outb(0x3D5, chip->CurrentState->cursor1);
+ return (current & 0x01);
+}
+
+/****************************************************************************\
+* *
+* The video arbitration routines calculate some "magic" numbers. Fixes *
+* the snow seen when accessing the framebuffer without it. *
+* It just works (I hope). *
+* *
+\****************************************************************************/
+
+#define DEFAULT_GR_LWM 100
+#define DEFAULT_VID_LWM 100
+#define DEFAULT_GR_BURST_SIZE 256
+#define DEFAULT_VID_BURST_SIZE 128
+#define VIDEO 0
+#define GRAPHICS 1
+#define MPORT 2
+#define ENGINE 3
+#define GFIFO_SIZE 320
+#define GFIFO_SIZE_128 256
+#define MFIFO_SIZE 120
+#define VFIFO_SIZE 256
+#define ABS(a) (a>0?a:-a)
+typedef struct {
+ int gdrain_rate;
+ int vdrain_rate;
+ int mdrain_rate;
+ int gburst_size;
+ int vburst_size;
+ char vid_en;
+ char gr_en;
+ int wcmocc, wcgocc, wcvocc, wcvlwm, wcglwm;
+ int by_gfacc;
+ char vid_only_once;
+ char gr_only_once;
+ char first_vacc;
+ char first_gacc;
+ char first_macc;
+ int vocc;
+ int gocc;
+ int mocc;
+ char cur;
+ char engine_en;
+ char converged;
+ int priority;
+} nv3_arb_info;
+typedef struct {
+ int graphics_lwm;
+ int video_lwm;
+ int graphics_burst_size;
+ int video_burst_size;
+ int graphics_hi_priority;
+ int media_hi_priority;
+ int rtl_values;
+ int valid;
+} nv3_fifo_info;
+typedef struct {
+ char pix_bpp;
+ char enable_video;
+ char gr_during_vid;
+ char enable_mp;
+ int memory_width;
+ int video_scale;
+ int pclk_khz;
+ int mclk_khz;
+ int mem_page_miss;
+ int mem_latency;
+ char mem_aligned;
+} nv3_sim_state;
+typedef struct {
+ int graphics_lwm;
+ int video_lwm;
+ int graphics_burst_size;
+ int video_burst_size;
+ int valid;
+} nv4_fifo_info;
+typedef struct {
+ int pclk_khz;
+ int mclk_khz;
+ int nvclk_khz;
+ char mem_page_miss;
+ char mem_latency;
+ int memory_width;
+ char enable_video;
+ char gr_during_vid;
+ char pix_bpp;
+ char mem_aligned;
+ char enable_mp;
+} nv4_sim_state;
+static int nv3_iterate(nv3_fifo_info *res_info, nv3_sim_state * state, nv3_arb_info *ainfo)
+{
+ int iter = 0;
+ int tmp;
+ int vfsize, mfsize, gfsize;
+ int mburst_size = 32;
+ int mmisses, gmisses, vmisses;
+ int misses;
+ int vlwm, glwm, mlwm;
+ int last, next, cur;
+ int max_gfsize ;
+ long ns;
+
+ vlwm = 0;
+ glwm = 0;
+ mlwm = 0;
+ vfsize = 0;
+ gfsize = 0;
+ cur = ainfo->cur;
+ mmisses = 2;
+ gmisses = 2;
+ vmisses = 2;
+ if (ainfo->gburst_size == 128) max_gfsize = GFIFO_SIZE_128;
+ else max_gfsize = GFIFO_SIZE;
+ max_gfsize = GFIFO_SIZE;
+ while (1)
+ {
+ if (ainfo->vid_en)
+ {
+ if (ainfo->wcvocc > ainfo->vocc) ainfo->wcvocc = ainfo->vocc;
+ if (ainfo->wcvlwm > vlwm) ainfo->wcvlwm = vlwm ;
+ ns = 1000000 * ainfo->vburst_size/(state->memory_width/8)/state->mclk_khz;
+ vfsize = ns * ainfo->vdrain_rate / 1000000;
+ vfsize = ainfo->wcvlwm - ainfo->vburst_size + vfsize;
+ }
+ if (state->enable_mp)
+ {
+ if (ainfo->wcmocc > ainfo->mocc) ainfo->wcmocc = ainfo->mocc;
+ }
+ if (ainfo->gr_en)
+ {
+ if (ainfo->wcglwm > glwm) ainfo->wcglwm = glwm ;
+ if (ainfo->wcgocc > ainfo->gocc) ainfo->wcgocc = ainfo->gocc;
+ ns = 1000000 * (ainfo->gburst_size/(state->memory_width/8))/state->mclk_khz;
+ gfsize = (ns * (long) ainfo->gdrain_rate)/1000000;
+ gfsize = ainfo->wcglwm - ainfo->gburst_size + gfsize;
+ }
+ mfsize = 0;
+ if (!state->gr_during_vid && ainfo->vid_en)
+ if (ainfo->vid_en && (ainfo->vocc < 0) && !ainfo->vid_only_once)
+ next = VIDEO;
+ else if (ainfo->mocc < 0)
+ next = MPORT;
+ else if (ainfo->gocc< ainfo->by_gfacc)
+ next = GRAPHICS;
+ else return (0);
+ else switch (ainfo->priority)
+ {
+ case VIDEO:
+ if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
+ next = VIDEO;
+ else if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
+ next = GRAPHICS;
+ else if (ainfo->mocc<0)
+ next = MPORT;
+ else return (0);
+ break;
+ case GRAPHICS:
+ if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
+ next = GRAPHICS;
+ else if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
+ next = VIDEO;
+ else if (ainfo->mocc<0)
+ next = MPORT;
+ else return (0);
+ break;
+ default:
+ if (ainfo->mocc<0)
+ next = MPORT;
+ else if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
+ next = GRAPHICS;
+ else if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
+ next = VIDEO;
+ else return (0);
+ break;
+ }
+ last = cur;
+ cur = next;
+ iter++;
+ switch (cur)
+ {
+ case VIDEO:
+ if (last==cur) misses = 0;
+ else if (ainfo->first_vacc) misses = vmisses;
+ else misses = 1;
+ ainfo->first_vacc = 0;
+ if (last!=cur)
+ {
+ ns = 1000000 * (vmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz;
+ vlwm = ns * ainfo->vdrain_rate/ 1000000;
+ vlwm = ainfo->vocc - vlwm;
+ }
+ ns = 1000000*(misses*state->mem_page_miss + ainfo->vburst_size)/(state->memory_width/8)/state->mclk_khz;
+ ainfo->vocc = ainfo->vocc + ainfo->vburst_size - ns*ainfo->vdrain_rate/1000000;
+ ainfo->gocc = ainfo->gocc - ns*ainfo->gdrain_rate/1000000;
+ ainfo->mocc = ainfo->mocc - ns*ainfo->mdrain_rate/1000000;
+ break;
+ case GRAPHICS:
+ if (last==cur) misses = 0;
+ else if (ainfo->first_gacc) misses = gmisses;
+ else misses = 1;
+ ainfo->first_gacc = 0;
+ if (last!=cur)
+ {
+ ns = 1000000*(gmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz ;
+ glwm = ns * ainfo->gdrain_rate/1000000;
+ glwm = ainfo->gocc - glwm;
+ }
+ ns = 1000000*(misses*state->mem_page_miss + ainfo->gburst_size/(state->memory_width/8))/state->mclk_khz;
+ ainfo->vocc = ainfo->vocc + 0 - ns*ainfo->vdrain_rate/1000000;
+ ainfo->gocc = ainfo->gocc + ainfo->gburst_size - ns*ainfo->gdrain_rate/1000000;
+ ainfo->mocc = ainfo->mocc + 0 - ns*ainfo->mdrain_rate/1000000;
+ break;
+ default:
+ if (last==cur) misses = 0;
+ else if (ainfo->first_macc) misses = mmisses;
+ else misses = 1;
+ ainfo->first_macc = 0;
+ ns = 1000000*(misses*state->mem_page_miss + mburst_size/(state->memory_width/8))/state->mclk_khz;
+ ainfo->vocc = ainfo->vocc + 0 - ns*ainfo->vdrain_rate/1000000;
+ ainfo->gocc = ainfo->gocc + 0 - ns*ainfo->gdrain_rate/1000000;
+ ainfo->mocc = ainfo->mocc + mburst_size - ns*ainfo->mdrain_rate/1000000;
+ break;
+ }
+ if (iter>100)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ ns = 1000000*ainfo->gburst_size/(state->memory_width/8)/state->mclk_khz;
+ tmp = ns * ainfo->gdrain_rate/1000000;
+ if (ABS(ainfo->gburst_size) + ((ABS(ainfo->wcglwm) + 16 ) & ~0x7) - tmp > max_gfsize)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ ns = 1000000*ainfo->vburst_size/(state->memory_width/8)/state->mclk_khz;
+ tmp = ns * ainfo->vdrain_rate/1000000;
+ if (ABS(ainfo->vburst_size) + (ABS(ainfo->wcvlwm + 32) & ~0xf) - tmp> VFIFO_SIZE)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ if (ABS(ainfo->gocc) > max_gfsize)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ if (ABS(ainfo->vocc) > VFIFO_SIZE)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ if (ABS(ainfo->mocc) > MFIFO_SIZE)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ if (ABS(vfsize) > VFIFO_SIZE)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ if (ABS(gfsize) > max_gfsize)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ if (ABS(mfsize) > MFIFO_SIZE)
+ {
+ ainfo->converged = 0;
+ return (1);
+ }
+ }
+}
+static char nv3_arb(nv3_fifo_info * res_info, nv3_sim_state * state, nv3_arb_info *ainfo)
+{
+ long ens, vns, mns, gns;
+ int mmisses, gmisses, vmisses, eburst_size, mburst_size;
+ int refresh_cycle;
+
+ refresh_cycle = 0;
+ refresh_cycle = 2*(state->mclk_khz/state->pclk_khz) + 5;
+ mmisses = 2;
+ if (state->mem_aligned) gmisses = 2;
+ else gmisses = 3;
+ vmisses = 2;
+ eburst_size = state->memory_width * 1;
+ mburst_size = 32;
+ gns = 1000000 * (gmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz;
+ ainfo->by_gfacc = gns*ainfo->gdrain_rate/1000000;
+ ainfo->wcmocc = 0;
+ ainfo->wcgocc = 0;
+ ainfo->wcvocc = 0;
+ ainfo->wcvlwm = 0;
+ ainfo->wcglwm = 0;
+ ainfo->engine_en = 1;
+ ainfo->converged = 1;
+ if (ainfo->engine_en)
+ {
+ ens = 1000000*(state->mem_page_miss + eburst_size/(state->memory_width/8) +refresh_cycle)/state->mclk_khz;
+ ainfo->mocc = state->enable_mp ? 0-ens*ainfo->mdrain_rate/1000000 : 0;
+ ainfo->vocc = ainfo->vid_en ? 0-ens*ainfo->vdrain_rate/1000000 : 0;
+ ainfo->gocc = ainfo->gr_en ? 0-ens*ainfo->gdrain_rate/1000000 : 0;
+ ainfo->cur = ENGINE;
+ ainfo->first_vacc = 1;
+ ainfo->first_gacc = 1;
+ ainfo->first_macc = 1;
+ nv3_iterate(res_info, state,ainfo);
+ }
+ if (state->enable_mp)
+ {
+ mns = 1000000 * (mmisses*state->mem_page_miss + mburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
+ ainfo->mocc = state->enable_mp ? 0 : mburst_size - mns*ainfo->mdrain_rate/1000000;
+ ainfo->vocc = ainfo->vid_en ? 0 : 0- mns*ainfo->vdrain_rate/1000000;
+ ainfo->gocc = ainfo->gr_en ? 0: 0- mns*ainfo->gdrain_rate/1000000;
+ ainfo->cur = MPORT;
+ ainfo->first_vacc = 1;
+ ainfo->first_gacc = 1;
+ ainfo->first_macc = 0;
+ nv3_iterate(res_info, state,ainfo);
+ }
+ if (ainfo->gr_en)
+ {
+ ainfo->first_vacc = 1;
+ ainfo->first_gacc = 0;
+ ainfo->first_macc = 1;
+ gns = 1000000*(gmisses*state->mem_page_miss + ainfo->gburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
+ ainfo->gocc = ainfo->gburst_size - gns*ainfo->gdrain_rate/1000000;
+ ainfo->vocc = ainfo->vid_en? 0-gns*ainfo->vdrain_rate/1000000 : 0;
+ ainfo->mocc = state->enable_mp ? 0-gns*ainfo->mdrain_rate/1000000: 0;
+ ainfo->cur = GRAPHICS;
+ nv3_iterate(res_info, state,ainfo);
+ }
+ if (ainfo->vid_en)
+ {
+ ainfo->first_vacc = 0;
+ ainfo->first_gacc = 1;
+ ainfo->first_macc = 1;
+ vns = 1000000*(vmisses*state->mem_page_miss + ainfo->vburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
+ ainfo->vocc = ainfo->vburst_size - vns*ainfo->vdrain_rate/1000000;
+ ainfo->gocc = ainfo->gr_en? (0-vns*ainfo->gdrain_rate/1000000) : 0;
+ ainfo->mocc = state->enable_mp? 0-vns*ainfo->mdrain_rate/1000000 :0 ;
+ ainfo->cur = VIDEO;
+ nv3_iterate(res_info, state, ainfo);
+ }
+ if (ainfo->converged)
+ {
+ res_info->graphics_lwm = (int)ABS(ainfo->wcglwm) + 16;
+ res_info->video_lwm = (int)ABS(ainfo->wcvlwm) + 32;
+ res_info->graphics_burst_size = ainfo->gburst_size;
+ res_info->video_burst_size = ainfo->vburst_size;
+ res_info->graphics_hi_priority = (ainfo->priority == GRAPHICS);
+ res_info->media_hi_priority = (ainfo->priority == MPORT);
+ if (res_info->video_lwm > 160)
+ {
+ res_info->graphics_lwm = 256;
+ res_info->video_lwm = 128;
+ res_info->graphics_burst_size = 64;
+ res_info->video_burst_size = 64;
+ res_info->graphics_hi_priority = 0;
+ res_info->media_hi_priority = 0;
+ ainfo->converged = 0;
+ return (0);
+ }
+ if (res_info->video_lwm > 128)
+ {
+ res_info->video_lwm = 128;
+ }
+ return (1);
+ }
+ else
+ {
+ res_info->graphics_lwm = 256;
+ res_info->video_lwm = 128;
+ res_info->graphics_burst_size = 64;
+ res_info->video_burst_size = 64;
+ res_info->graphics_hi_priority = 0;
+ res_info->media_hi_priority = 0;
+ return (0);
+ }
+}
+static char nv3_get_param(nv3_fifo_info *res_info, nv3_sim_state * state, nv3_arb_info *ainfo)
+{
+ int done, g,v, p;
+
+ done = 0;
+ for (p=0; p < 2; p++)
+ {
+ for (g=128 ; g > 32; g= g>> 1)
+ {
+ for (v=128; v >=32; v = v>> 1)
+ {
+ ainfo->priority = p;
+ ainfo->gburst_size = g;
+ ainfo->vburst_size = v;
+ done = nv3_arb(res_info, state,ainfo);
+ if (done && (g==128))
+ if ((res_info->graphics_lwm + g) > 256)
+ done = 0;
+ if (done)
+ goto Done;
+ }
+ }
+ }
+
+ Done:
+ return done;
+}
+static void nv3CalcArbitration
+(
+ nv3_fifo_info * res_info,
+ nv3_sim_state * state
+)
+{
+ nv3_fifo_info save_info;
+ nv3_arb_info ainfo;
+ char res_gr, res_vid;
+
+ ainfo.gr_en = 1;
+ ainfo.vid_en = state->enable_video;
+ ainfo.vid_only_once = 0;
+ ainfo.gr_only_once = 0;
+ ainfo.gdrain_rate = (int) state->pclk_khz * (state->pix_bpp/8);
+ ainfo.vdrain_rate = (int) state->pclk_khz * 2;
+ if (state->video_scale != 0)
+ ainfo.vdrain_rate = ainfo.vdrain_rate/state->video_scale;
+ ainfo.mdrain_rate = 33000;
+ res_info->rtl_values = 0;
+ if (!state->gr_during_vid && state->enable_video)
+ {
+ ainfo.gr_only_once = 1;
+ ainfo.gr_en = 1;
+ ainfo.gdrain_rate = 0;
+ res_vid = nv3_get_param(res_info, state, &ainfo);
+ res_vid = ainfo.converged;
+ save_info.video_lwm = res_info->video_lwm;
+ save_info.video_burst_size = res_info->video_burst_size;
+ ainfo.vid_en = 1;
+ ainfo.vid_only_once = 1;
+ ainfo.gr_en = 1;
+ ainfo.gdrain_rate = (int) state->pclk_khz * (state->pix_bpp/8);
+ ainfo.vdrain_rate = 0;
+ res_gr = nv3_get_param(res_info, state, &ainfo);
+ res_gr = ainfo.converged;
+ res_info->video_lwm = save_info.video_lwm;
+ res_info->video_burst_size = save_info.video_burst_size;
+ res_info->valid = res_gr & res_vid;
+ }
+ else
+ {
+ if (!ainfo.gr_en) ainfo.gdrain_rate = 0;
+ if (!ainfo.vid_en) ainfo.vdrain_rate = 0;
+ res_gr = nv3_get_param(res_info, state, &ainfo);
+ res_info->valid = ainfo.converged;
+ }
+}
+static void nv3UpdateArbitrationSettings
+(
+ unsigned VClk,
+ unsigned pixelDepth,
+ unsigned *burst,
+ unsigned *lwm,
+ RIVA_HW_INST *chip
+)
+{
+ nv3_fifo_info fifo_data;
+ nv3_sim_state sim_data;
+ unsigned int M, N, P, pll, MClk;
+
+ pll = chip->PRAMDAC[0x00000504/4];
+ M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
+ MClk = (N * chip->CrystalFreqKHz / M) >> P;
+ sim_data.pix_bpp = (char)pixelDepth;
+ sim_data.enable_video = 0;
+ sim_data.enable_mp = 0;
+ sim_data.video_scale = 1;
+ sim_data.memory_width = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64;
+ sim_data.memory_width = 128;
+
+ sim_data.mem_latency = 9;
+ sim_data.mem_aligned = 1;
+ sim_data.mem_page_miss = 11;
+ sim_data.gr_during_vid = 0;
+ sim_data.pclk_khz = VClk;
+ sim_data.mclk_khz = MClk;
+ nv3CalcArbitration(&fifo_data, &sim_data);
+ if (fifo_data.valid)
+ {
+ int b = fifo_data.graphics_burst_size >> 4;
+ *burst = 0;
+ while (b >>= 1) (*burst)++;
+ *lwm = fifo_data.graphics_lwm >> 3;
+ }
+ else
+ {
+ *lwm = 0x24;
+ *burst = 0x2;
+ }
+}
+static void nv4CalcArbitration
+(
+ nv4_fifo_info *fifo,
+ nv4_sim_state *arb
+)
+{
+ int data, pagemiss, cas,width, video_enable, color_key_enable, bpp, align;
+ int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs;
+ int found, mclk_extra, mclk_loop, cbs, m1, p1;
+ int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
+ int us_m, us_n, us_p, video_drain_rate, crtc_drain_rate;
+ int vpm_us, us_video, vlwm, video_fill_us, cpm_us, us_crt,clwm;
+ int craw, vraw;
+
+ fifo->valid = 1;
+ pclk_freq = arb->pclk_khz;
+ mclk_freq = arb->mclk_khz;
+ nvclk_freq = arb->nvclk_khz;
+ pagemiss = arb->mem_page_miss;
+ cas = arb->mem_latency;
+ width = arb->memory_width >> 6;
+ video_enable = arb->enable_video;
+ color_key_enable = arb->gr_during_vid;
+ bpp = arb->pix_bpp;
+ align = arb->mem_aligned;
+ mp_enable = arb->enable_mp;
+ clwm = 0;
+ vlwm = 0;
+ cbs = 128;
+ pclks = 2;
+ nvclks = 2;
+ nvclks += 2;
+ nvclks += 1;
+ mclks = 5;
+ mclks += 3;
+ mclks += 1;
+ mclks += cas;
+ mclks += 1;
+ mclks += 1;
+ mclks += 1;
+ mclks += 1;
+ mclk_extra = 3;
+ nvclks += 2;
+ nvclks += 1;
+ nvclks += 1;
+ nvclks += 1;
+ if (mp_enable)
+ mclks+=4;
+ nvclks += 0;
+ pclks += 0;
+ found = 0;
+ vbs = 0;
+ while (found != 1)
+ {
+ fifo->valid = 1;
+ found = 1;
+ mclk_loop = mclks+mclk_extra;
+ us_m = mclk_loop *1000*1000 / mclk_freq;
+ us_n = nvclks*1000*1000 / nvclk_freq;
+ us_p = nvclks*1000*1000 / pclk_freq;
+ if (video_enable)
+ {
+ video_drain_rate = pclk_freq * 2;
+ crtc_drain_rate = pclk_freq * bpp/8;
+ vpagemiss = 2;
+ vpagemiss += 1;
+ crtpagemiss = 2;
+ vpm_us = (vpagemiss * pagemiss)*1000*1000/mclk_freq;
+ if (nvclk_freq * 2 > mclk_freq * width)
+ video_fill_us = cbs*1000*1000 / 16 / nvclk_freq ;
+ else
+ video_fill_us = cbs*1000*1000 / (8 * width) / mclk_freq;
+ us_video = vpm_us + us_m + us_n + us_p + video_fill_us;
+ vlwm = us_video * video_drain_rate/(1000*1000);
+ vlwm++;
+ vbs = 128;
+ if (vlwm > 128) vbs = 64;
+ if (vlwm > (256-64)) vbs = 32;
+ if (nvclk_freq * 2 > mclk_freq * width)
+ video_fill_us = vbs *1000*1000/ 16 / nvclk_freq ;
+ else
+ video_fill_us = vbs*1000*1000 / (8 * width) / mclk_freq;
+ cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
+ us_crt =
+ us_video
+ +video_fill_us
+ +cpm_us
+ +us_m + us_n +us_p
+ ;
+ clwm = us_crt * crtc_drain_rate/(1000*1000);
+ clwm++;
+ }
+ else
+ {
+ crtc_drain_rate = pclk_freq * bpp/8;
+ crtpagemiss = 2;
+ crtpagemiss += 1;
+ cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
+ us_crt = cpm_us + us_m + us_n + us_p ;
+ clwm = us_crt * crtc_drain_rate/(1000*1000);
+ clwm++;
+ }
+ m1 = clwm + cbs - 512;
+ p1 = m1 * pclk_freq / mclk_freq;
+ p1 = p1 * bpp / 8;
+ if ((p1 < m1) && (m1 > 0))
+ {
+ fifo->valid = 0;
+ found = 0;
+ if (mclk_extra ==0) found = 1;
+ mclk_extra--;
+ }
+ else if (video_enable)
+ {
+ if ((clwm > 511) || (vlwm > 255))
+ {
+ fifo->valid = 0;
+ found = 0;
+ if (mclk_extra ==0) found = 1;
+ mclk_extra--;
+ }
+ }
+ else
+ {
+ if (clwm > 519)
+ {
+ fifo->valid = 0;
+ found = 0;
+ if (mclk_extra ==0) found = 1;
+ mclk_extra--;
+ }
+ }
+ craw = clwm;
+ vraw = vlwm;
+ if (clwm < 384) clwm = 384;
+ if (vlwm < 128) vlwm = 128;
+ data = (int)(clwm);
+ fifo->graphics_lwm = data;
+ fifo->graphics_burst_size = 128;
+ data = (int)((vlwm+15));
+ fifo->video_lwm = data;
+ fifo->video_burst_size = vbs;
+ }
+}
+static void nv4UpdateArbitrationSettings
+(
+ unsigned VClk,
+ unsigned pixelDepth,
+ unsigned *burst,
+ unsigned *lwm,
+ RIVA_HW_INST *chip
+)
+{
+ nv4_fifo_info fifo_data;
+ nv4_sim_state sim_data;
+ unsigned int M, N, P, pll, MClk, NVClk, cfg1;
+
+ pll = chip->PRAMDAC[0x00000504/4];
+ M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
+ MClk = (N * chip->CrystalFreqKHz / M) >> P;
+ pll = chip->PRAMDAC[0x00000500/4];
+ M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
+ NVClk = (N * chip->CrystalFreqKHz / M) >> P;
+ cfg1 = chip->PFB[0x00000204/4];
+ sim_data.pix_bpp = (char)pixelDepth;
+ sim_data.enable_video = 0;
+ sim_data.enable_mp = 0;
+ sim_data.memory_width = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64;
+ sim_data.mem_latency = (char)cfg1 & 0x0F;
+ sim_data.mem_aligned = 1;
+ sim_data.mem_page_miss = (char)(((cfg1 >> 4) &0x0F) + ((cfg1 >> 31) & 0x01));
+ sim_data.gr_during_vid = 0;
+ sim_data.pclk_khz = VClk;
+ sim_data.mclk_khz = MClk;
+ sim_data.nvclk_khz = NVClk;
+ nv4CalcArbitration(&fifo_data, &sim_data);
+ if (fifo_data.valid)
+ {
+ int b = fifo_data.graphics_burst_size >> 4;
+ *burst = 0;
+ while (b >>= 1) (*burst)++;
+ *lwm = fifo_data.graphics_lwm >> 3;
+ }
+}
+
+/****************************************************************************\
+* *
+* RIVA Mode State Routines *
+* *
+\****************************************************************************/
+
+/*
+ * Calculate the Video Clock parameters for the PLL.
+ */
+static int CalcVClock
+(
+ int clockIn,
+ int double_scan,
+ int *clockOut,
+ int *mOut,
+ int *nOut,
+ int *pOut,
+ RIVA_HW_INST *chip
+)
+{
+ unsigned lowM, highM, highP;
+ unsigned DeltaNew, DeltaOld;
+ unsigned VClk, Freq;
+ unsigned M, N, P;
+
+ DeltaOld = 0xFFFFFFFF;
+
+ VClk = (unsigned)clockIn;
+ if (double_scan)
+ VClk *= 2;
+
+ if (chip->CrystalFreqKHz == 14318)
+ {
+ lowM = 8;
+ highM = 14 - (chip->Architecture == 3);
+ }
+ else
+ {
+ lowM = 7;
+ highM = 13 - (chip->Architecture == 3);
+ }
+
+ highP = 4 - (chip->Architecture == 3);
+ for (P = 0; P <= highP; P ++)
+ {
+ Freq = VClk << P;
+ if ((Freq >= 128000) && (Freq <= chip->MaxVClockFreqKHz))
+ {
+ for (M = lowM; M <= highM; M++)
+ {
+ N = (VClk * M / chip->CrystalFreqKHz) << P;
+ Freq = (chip->CrystalFreqKHz * N / M) >> P;
+ if (Freq > VClk)
+ DeltaNew = Freq - VClk;
+ else
+ DeltaNew = VClk - Freq;
+ if (DeltaNew < DeltaOld)
+ {
+ *mOut = M;
+ *nOut = N;
+ *pOut = P;
+ *clockOut = Freq;
+ DeltaOld = DeltaNew;
+ }
+ }
+ }
+ }
+ return (DeltaOld != 0xFFFFFFFF);
+}
+/*
+ * Calculate extended mode parameters (SVGA) and save in a
+ * mode state structure.
+ */
+static void CalcStateExt
+(
+ RIVA_HW_INST *chip,
+ RIVA_HW_STATE *state,
+ int bpp,
+ int width,
+ int hDisplaySize,
+ int hDisplay,
+ int hStart,
+ int hEnd,
+ int hTotal,
+ int height,
+ int vDisplay,
+ int vStart,
+ int vEnd,
+ int vTotal,
+ int dotClock
+)
+{
+ int pixelDepth, VClk, m, n, p;
+ /*
+ * Save mode parameters.
+ */
+ state->bpp = bpp;
+ state->width = width;
+ state->height = height;
+ /*
+ * Extended RIVA registers.
+ */
+ pixelDepth = (bpp + 1)/8;
+ CalcVClock(dotClock, hDisplaySize < 512, /* double scan? */
+ &VClk, &m, &n, &p, chip);
+
+ switch (chip->Architecture)
+ {
+ case 3:
+ nv3UpdateArbitrationSettings(VClk,
+ pixelDepth * 8,
+ &(state->arbitration0),
+ &(state->arbitration1),
+ chip);
+ state->cursor0 = 0x00;
+ state->cursor1 = 0x78;
+ state->cursor2 = 0x00000000;
+ state->pllsel = 0x10010100;
+ state->config = ((width + 31)/32)
+ | (((pixelDepth > 2) ? 3 : pixelDepth) << 8)
+ | 0x1000;
+ state->general = 0x00000100;
+ state->repaint1 = hDisplaySize < 1280 ? 0x06 : 0x02;
+ break;
+ case 4:
+ nv4UpdateArbitrationSettings(VClk,
+ pixelDepth * 8,
+ &(state->arbitration0),
+ &(state->arbitration1),
+ chip);
+ state->cursor0 = 0x00;
+ state->cursor1 = 0xFC;
+ state->cursor2 = 0x00000000;
+ state->pllsel = 0x10000700;
+ state->config = 0x00001114;
+ state->general = bpp == 16 ? 0x00101100 : 0x00100100;
+ state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
+ break;
+ }
+ state->vpll = (p << 16) | (n << 8) | m;
+ state->screen = ((hTotal & 0x040) >> 2)
+ | ((vDisplay & 0x400) >> 7)
+ | ((vStart & 0x400) >> 8)
+ | ((vDisplay & 0x400) >> 9)
+ | ((vTotal & 0x400) >> 10);
+ state->repaint0 = (((width/8)*pixelDepth) & 0x700) >> 3;
+ state->horiz = hTotal < 260 ? 0x00 : 0x01;
+ state->pixel = pixelDepth > 2 ? 3 : pixelDepth;
+ state->offset0 =
+ state->offset1 =
+ state->offset2 =
+ state->offset3 = 0;
+ state->pitch0 =
+ state->pitch1 =
+ state->pitch2 =
+ state->pitch3 = pixelDepth * width;
+}
+/*
+ * Load fixed function state and pre-calculated/stored state.
+ */
+#define LOAD_FIXED_STATE(tbl,dev) \
+ for (i = 0; i < sizeof(tbl##Table##dev)/8; i++) \
+ chip->dev[tbl##Table##dev[i][0]] = tbl##Table##dev[i][1]
+#define LOAD_FIXED_STATE_8BPP(tbl,dev) \
+ for (i = 0; i < sizeof(tbl##Table##dev##_8BPP)/8; i++) \
+ chip->dev[tbl##Table##dev##_8BPP[i][0]] = tbl##Table##dev##_8BPP[i][1]
+#define LOAD_FIXED_STATE_15BPP(tbl,dev) \
+ for (i = 0; i < sizeof(tbl##Table##dev##_15BPP)/8; i++) \
+ chip->dev[tbl##Table##dev##_15BPP[i][0]] = tbl##Table##dev##_15BPP[i][1]
+#define LOAD_FIXED_STATE_16BPP(tbl,dev) \
+ for (i = 0; i < sizeof(tbl##Table##dev##_16BPP)/8; i++) \
+ chip->dev[tbl##Table##dev##_16BPP[i][0]] = tbl##Table##dev##_16BPP[i][1]
+#define LOAD_FIXED_STATE_32BPP(tbl,dev) \
+ for (i = 0; i < sizeof(tbl##Table##dev##_32BPP)/8; i++) \
+ chip->dev[tbl##Table##dev##_32BPP[i][0]] = tbl##Table##dev##_32BPP[i][1]
+static void LoadStateExt
+(
+ RIVA_HW_INST *chip,
+ RIVA_HW_STATE *state
+)
+{
+ int i;
+
+ /*
+ * Load HW fixed function state.
+ */
+ LOAD_FIXED_STATE(Riva,PMC);
+ LOAD_FIXED_STATE(Riva,PTIMER);
+ /*
+ * Make sure frame buffer config gets set before loading PRAMIN.
+ */
+ chip->PFB[0x00000200/4] = state->config;
+ switch (chip->Architecture)
+ {
+ case 3:
+ LOAD_FIXED_STATE(nv3,PFIFO);
+ LOAD_FIXED_STATE(nv3,PRAMIN);
+ LOAD_FIXED_STATE(nv3,PGRAPH);
+ switch (state->bpp)
+ {
+ case 15:
+ case 16:
+ LOAD_FIXED_STATE_15BPP(nv3,PRAMIN);
+ LOAD_FIXED_STATE_15BPP(nv3,PGRAPH);
+ chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]);
+ break;
+ case 24:
+ case 32:
+ LOAD_FIXED_STATE_32BPP(nv3,PRAMIN);
+ LOAD_FIXED_STATE_32BPP(nv3,PGRAPH);
+ chip->Tri03 = 0L;
+ break;
+ case 8:
+ default:
+ LOAD_FIXED_STATE_8BPP(nv3,PRAMIN);
+ LOAD_FIXED_STATE_8BPP(nv3,PGRAPH);
+ chip->Tri03 = 0L;
+ break;
+ }
+ for (i = 0x00000; i < 0x00800; i++)
+ chip->PRAMIN[0x00000502 + i] = (i << 12) | 0x03;
+ chip->PGRAPH[0x00000630/4] = state->offset0;
+ chip->PGRAPH[0x00000634/4] = state->offset1;
+ chip->PGRAPH[0x00000638/4] = state->offset2;
+ chip->PGRAPH[0x0000063C/4] = state->offset3;
+ chip->PGRAPH[0x00000650/4] = state->pitch0;
+ chip->PGRAPH[0x00000654/4] = state->pitch1;
+ chip->PGRAPH[0x00000658/4] = state->pitch2;
+ chip->PGRAPH[0x0000065C/4] = state->pitch3;
+ break;
+ case 4:
+ LOAD_FIXED_STATE(nv4,PFIFO);
+ LOAD_FIXED_STATE(nv4,PRAMIN);
+ LOAD_FIXED_STATE(nv4,PGRAPH);
+ switch (state->bpp)
+ {
+ case 15:
+ LOAD_FIXED_STATE_15BPP(nv4,PRAMIN);
+ LOAD_FIXED_STATE_15BPP(nv4,PGRAPH);
+ chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]);
+ break;
+ case 16:
+ LOAD_FIXED_STATE_16BPP(nv4,PRAMIN);
+ LOAD_FIXED_STATE_16BPP(nv4,PGRAPH);
+ chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]);
+ break;
+ case 24:
+ case 32:
+ LOAD_FIXED_STATE_32BPP(nv4,PRAMIN);
+ LOAD_FIXED_STATE_32BPP(nv4,PGRAPH);
+ chip->Tri03 = 0L;
+ break;
+ case 8:
+ default:
+ LOAD_FIXED_STATE_8BPP(nv4,PRAMIN);
+ LOAD_FIXED_STATE_8BPP(nv4,PGRAPH);
+ chip->Tri03 = 0L;
+ break;
+ }
+ chip->PGRAPH[0x00000640/4] = state->offset0;
+ chip->PGRAPH[0x00000644/4] = state->offset1;
+ chip->PGRAPH[0x00000648/4] = state->offset2;
+ chip->PGRAPH[0x0000064C/4] = state->offset3;
+ chip->PGRAPH[0x00000670/4] = state->pitch0;
+ chip->PGRAPH[0x00000674/4] = state->pitch1;
+ chip->PGRAPH[0x00000678/4] = state->pitch2;
+ chip->PGRAPH[0x0000067C/4] = state->pitch3;
+ break;
+ }
+ LOAD_FIXED_STATE(Riva,FIFO);
+ /*
+ * Load HW mode state.
+ */
+ outb(0x3D4,0x19); outb(0x3D5, state->repaint0);
+ outb(0x3D4,0x1A); outb(0x3D5, state->repaint1);
+ outb(0x3D4,0x25); outb(0x3D5, state->screen);
+ outb(0x3D4,0x28); outb(0x3D5, state->pixel);
+ outb(0x3D4,0x2D); outb(0x3D5, state->horiz);
+ outb(0x3D4,0x1B); outb(0x3D5, state->arbitration0);
+ outb(0x3D4,0x20); outb(0x3D5, state->arbitration1);
+ outb(0x3D4,0x30); outb(0x3D5, state->cursor0);
+ outb(0x3D4,0x31); outb(0x3D5, state->cursor1);
+ chip->PRAMDAC[0x00000300/4] = state->cursor2;
+ chip->PRAMDAC[0x00000508/4] = state->vpll;
+ chip->PRAMDAC[0x0000050C/4] = state->pllsel;
+ chip->PRAMDAC[0x00000600/4] = state->general;
+ /*
+ * Turn off VBlank enable and reset.
+ */
+ *(chip->VBLANKENABLE) = 0;
+ *(chip->VBLANK) = chip->VBlankBit;
+ /*
+ * Set interrupt enable.
+ */
+ chip->PMC[0x00000140/4] = chip->EnableIRQ & 0x01;
+ /*
+ * Set current state pointer.
+ */
+ chip->CurrentState = state;
+ /*
+ * Reset FIFO free and empty counts.
+ */
+ chip->FifoFreeCount = 0;
+ chip->FifoEmptyCount = chip->FIFO[5]; /* Free count from first subchannel */
+}
+static void UnloadStateExt
+(
+ RIVA_HW_INST *chip,
+ RIVA_HW_STATE *state
+)
+{
+ /*
+ * Save current HW state.
+ */
+ outb(0x3D4,0x19); state->repaint0 = inb(0x3D5);
+ outb(0x3D4,0x1A); state->repaint1 = inb(0x3D5);
+ outb(0x3D4,0x25); state->screen = inb(0x3D5);
+ outb(0x3D4,0x28); state->pixel = inb(0x3D5);
+ outb(0x3D4,0x2D); state->horiz = inb(0x3D5);
+ outb(0x3D4,0x1B); state->arbitration0 = inb(0x3D5);
+ outb(0x3D4,0x20); state->arbitration1 = inb(0x3D5);
+ outb(0x3D4,0x30); state->cursor0 = inb(0x3D5);
+ outb(0x3D4,0x31); state->cursor1 = inb(0x3D5);
+ state->cursor2 = chip->PRAMDAC[0x00000300/4];
+ state->vpll = chip->PRAMDAC[0x00000508/4];
+ state->pllsel = chip->PRAMDAC[0x0000050C/4];
+ state->general = chip->PRAMDAC[0x00000600/4];
+ state->config = chip->PFB[0x00000200/4];
+ switch (chip->Architecture)
+ {
+ case 3:
+ state->offset0 = chip->PGRAPH[0x00000630/4];
+ state->offset1 = chip->PGRAPH[0x00000634/4];
+ state->offset2 = chip->PGRAPH[0x00000638/4];
+ state->offset3 = chip->PGRAPH[0x0000063C/4];
+ state->pitch0 = chip->PGRAPH[0x00000650/4];
+ state->pitch1 = chip->PGRAPH[0x00000654/4];
+ state->pitch2 = chip->PGRAPH[0x00000658/4];
+ state->pitch3 = chip->PGRAPH[0x0000065C/4];
+ break;
+ case 4:
+ state->offset0 = chip->PGRAPH[0x00000640/4];
+ state->offset1 = chip->PGRAPH[0x00000644/4];
+ state->offset2 = chip->PGRAPH[0x00000648/4];
+ state->offset3 = chip->PGRAPH[0x0000064C/4];
+ state->pitch0 = chip->PGRAPH[0x00000670/4];
+ state->pitch1 = chip->PGRAPH[0x00000674/4];
+ state->pitch2 = chip->PGRAPH[0x00000678/4];
+ state->pitch3 = chip->PGRAPH[0x0000067C/4];
+ break;
+ }
+}
+static void SetStartAddress
+(
+ RIVA_HW_INST *chip,
+ unsigned start
+)
+{
+ int offset = start >> 2;
+ int pan = (start & 3) << 1;
+ unsigned char tmp;
+
+ /*
+ * Unlock extended registers.
+ */
+ outb(chip->LockUnlockIO, chip->LockUnlockIndex);
+ outb(chip->LockUnlockIO + 1, 0x57);
+ /*
+ * Set start address.
+ */
+ outb(0x3D4, 0x0D);
+ outb(0x3D5, offset);
+ outb(0x3D4, 0x0C);
+ outb(0x3D5, offset >> 8);
+ outb(0x3D4, 0x19);
+ tmp = inb(0x3D5);
+ outb(0x3D5, ((offset >> 16) & 0x0F) | (tmp & 0xF0));
+ /*
+ * 4 pixel pan register.
+ */
+ offset = inb(chip->IO + 0x0A);
+ outb(0x3C0, 0x13);
+ outb(0x3C0, pan);
+}
+static void nv3SetSurfaces2D
+(
+ RIVA_HW_INST *chip,
+ unsigned surf0,
+ unsigned surf1
+)
+{
+ while (nv3Busy(chip));
+ chip->PGRAPH[0x00000630/4] = surf0;
+ chip->PGRAPH[0x00000634/4] = surf1;
+}
+static void nv4SetSurfaces2D
+(
+ RIVA_HW_INST *chip,
+ unsigned surf0,
+ unsigned surf1
+)
+{
+ while (nv4Busy(chip));
+ chip->PGRAPH[0x00000640/4] = surf0;
+ chip->PGRAPH[0x00000644/4] = surf1;
+}
+static void nv3SetSurfaces3D
+(
+ RIVA_HW_INST *chip,
+ unsigned surf0,
+ unsigned surf1
+)
+{
+ while (nv3Busy(chip));
+ chip->PGRAPH[0x00000638/4] = surf0;
+ chip->PGRAPH[0x0000063C/4] = surf1;
+}
+static void nv4SetSurfaces3D
+(
+ RIVA_HW_INST *chip,
+ unsigned surf0,
+ unsigned surf1
+)
+{
+ while (nv4Busy(chip));
+ chip->PGRAPH[0x00000648/4] = surf0;
+ chip->PGRAPH[0x0000064C/4] = surf1;
+}
+
+/****************************************************************************\
+* *
+* Probe RIVA Chip Configuration *
+* *
+\****************************************************************************/
+
+static void nv3GetConfig
+(
+ RIVA_HW_INST *chip
+)
+{
+ /*
+ * Fill in chip configuration.
+ */
+ if (chip->PFB[0x00000000/4] & 0x00000020)
+ {
+ if (((chip->PMC[0x00000000/4] & 0xF0) == 0x20)
+ && ((chip->PMC[0x00000000/4] & 0x0F) >= 0x02))
+ {
+ /*
+ * SDRAM 128 ZX.
+ */
+ chip->RamBandwidthKBytesPerSec = 800000;
+ switch (chip->PFB[0x00000000/4] & 0x03)
+ {
+ case 2:
+ chip->RamAmountKBytes = 1024 * 4;
+ break;
+ case 1:
+ chip->RamAmountKBytes = 1024 * 2;
+ break;
+ default:
+ chip->RamAmountKBytes = 1024 * 8;
+ break;
+ }
+ }
+ else
+ {
+ chip->RamBandwidthKBytesPerSec = 1000000;
+ chip->RamAmountKBytes = 1024 * 8;
+ }
+ }
+ else
+ {
+ /*
+ * SGRAM 128.
+ */
+ chip->RamBandwidthKBytesPerSec = 1000000;
+ switch (chip->PFB[0x00000000/4] & 0x00000003)
+ {
+ case 0:
+ chip->RamAmountKBytes = 1024 * 8;
+ break;
+ case 2:
+ chip->RamAmountKBytes = 1024 * 4;
+ break;
+ default:
+ chip->RamAmountKBytes = 1024 * 2;
+ break;
+ }
+ }
+ chip->CrystalFreqKHz = (chip->PEXTDEV[0x00000000/4] & 0x00000020) ? 14318 : 13500;
+ chip->CURSOR = &(chip->PRAMIN[0x00008000/4 - 0x0800/4]);
+ chip->CURSORPOS = &(chip->PRAMDAC[0x0300/4]);
+ chip->VBLANKENABLE = &(chip->PGRAPH[0x0140/4]);
+ chip->VBLANK = &(chip->PGRAPH[0x0100/4]);
+ chip->VBlankBit = 0x00000100;
+ chip->MaxVClockFreqKHz = 256000;
+ chip->LockUnlockIO = 0x3C4;
+ chip->LockUnlockIndex = 0x06;
+ /*
+ * Set chip functions.
+ */
+ chip->Busy = nv3Busy;
+ chip->ShowHideCursor = ShowHideCursor;
+ chip->CalcStateExt = CalcStateExt;
+ chip->LoadStateExt = LoadStateExt;
+ chip->UnloadStateExt = UnloadStateExt;
+ chip->SetStartAddress = SetStartAddress;
+ chip->SetSurfaces2D = nv3SetSurfaces2D;
+ chip->SetSurfaces3D = nv3SetSurfaces3D;
+}
+static void nv4GetConfig
+(
+ RIVA_HW_INST *chip
+)
+{
+ /*
+ * Fill in chip configuration.
+ */
+ if (chip->PFB[0x00000000/4] & 0x00000100)
+ {
+ chip->RamAmountKBytes = ((chip->PFB[0x00000000/4] >> 12) & 0x0F) * 1024 * 2
+ + 1024 * 2;
+ }
+ else
+ {
+ switch (chip->PFB[0x00000000/4] & 0x00000003)
+ {
+ case 0:
+ chip->RamAmountKBytes = 1024 * 32;
+ break;
+ case 1:
+ chip->RamAmountKBytes = 1024 * 4;
+ break;
+ case 2:
+ chip->RamAmountKBytes = 1024 * 8;
+ break;
+ case 3:
+ default:
+ chip->RamAmountKBytes = 1024 * 16;
+ break;
+ }
+ }
+ switch ((chip->PFB[0x00000000/4] >> 3) & 0x00000003)
+ {
+ case 3:
+ chip->RamBandwidthKBytesPerSec = 800000;
+ break;
+ default:
+ chip->RamBandwidthKBytesPerSec = 1000000;
+ break;
+ }
+ chip->CrystalFreqKHz = (chip->PEXTDEV[0x00000000/4] & 0x00000040) ? 14318 : 13500;
+ chip->CURSOR = &(chip->PRAMIN[0x00010000/4 - 0x0800/4]);
+ chip->CURSORPOS = &(chip->PRAMDAC[0x0300/4]);
+ chip->VBLANKENABLE = &(chip->PCRTC[0x0140/4]);
+ chip->VBLANK = &(chip->PCRTC[0x0100/4]);
+ chip->VBlankBit = 0x00000001;
+ chip->MaxVClockFreqKHz = 350000;
+ chip->LockUnlockIO = 0x3D4;
+ chip->LockUnlockIndex = 0x1F;
+ /*
+ * Set chip functions.
+ */
+ chip->Busy = nv4Busy;
+ chip->ShowHideCursor = ShowHideCursor;
+ chip->CalcStateExt = CalcStateExt;
+ chip->LoadStateExt = LoadStateExt;
+ chip->UnloadStateExt = UnloadStateExt;
+ chip->SetStartAddress = SetStartAddress;
+ chip->SetSurfaces2D = nv4SetSurfaces2D;
+ chip->SetSurfaces3D = nv4SetSurfaces3D;
+}
+int RivaGetConfig
+(
+ RIVA_HW_INST *chip
+)
+{
+ /*
+ * Save this so future SW know whats it's dealing with.
+ */
+ chip->Version = RIVA_SW_VERSION;
+ /*
+ * Chip specific configuration.
+ */
+ switch (chip->Architecture)
+ {
+ case 3:
+ nv3GetConfig(chip);
+ break;
+ case 4:
+ nv4GetConfig(chip);
+ break;
+ default:
+ return (-1);
+ }
+ /*
+ * Fill in FIFO pointers.
+ */
+ chip->Rop = (RivaRop *)&(chip->FIFO[0x00000000/4]);
+ chip->Clip = (RivaClip *)&(chip->FIFO[0x00002000/4]);
+ chip->Patt = (RivaPattern *)&(chip->FIFO[0x00004000/4]);
+ chip->Pixmap = (RivaPixmap *)&(chip->FIFO[0x00006000/4]);
+ chip->Blt = (RivaScreenBlt *)&(chip->FIFO[0x00008000/4]);
+ chip->Bitmap = (RivaBitmap *)&(chip->FIFO[0x0000A000/4]);
+ chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]);
+ return (0);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.h b/xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.h
new file mode 100644
index 000000000..ac0bec75f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.h
@@ -0,0 +1,341 @@
+/***************************************************************************\
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* NOTICE TO USER: The source code is copyrighted under U.S. and *|
+|* international laws. Users and possessors of this source code are *|
+|* hereby granted a nonexclusive, royalty-free copyright license to *|
+|* use this code in individual and commercial software. *|
+|* *|
+|* Any use of this source code must include, in the user documenta- *|
+|* tion and internal comments to the code, notices to the end user *|
+|* as follows: *|
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
+|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
+|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
+|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
+|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
+|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
+|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
+|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
+|* SULTING 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 SOURCE CODE. *|
+|* *|
+|* U.S. Government End Users. This source code is a "commercial *|
+|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
+|* consisting of "commercial computer software" and "commercial *|
+|* computer software documentation," as such terms are used in *|
+|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
+|* ment only as a commercial end item. Consistent with 48 C.F.R. *|
+|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
+|* all U.S. Government End Users acquire the source code with only *|
+|* those rights set forth herein. *|
+|* *|
+\***************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.h,v 1.2 1999/08/14 10:49:52 dawes Exp $ */
+#ifndef __RIVA_HW_H__
+#define __RIVA_HW_H__
+#define RIVA_SW_VERSION 0x00010001
+
+/***************************************************************************\
+* *
+* FIFO registers. *
+* *
+\***************************************************************************/
+
+/*
+ * Raster OPeration. Windows style ROP3.
+ */
+typedef volatile struct
+{
+ unsigned reserved00[4];
+ unsigned short FifoFree;
+ unsigned short Nop;
+ unsigned reserved01[0x0BB];
+ unsigned Rop3;
+} RivaRop;
+/*
+ * 8X8 Monochrome pattern.
+ */
+typedef volatile struct
+{
+ unsigned reserved00[4];
+ unsigned short FifoFree;
+ unsigned short Nop;
+ unsigned reserved01[0x0BD];
+ unsigned Shape;
+ unsigned reserved03[0x001];
+ unsigned Color0;
+ unsigned Color1;
+ unsigned Monochrome[2];
+} RivaPattern;
+/*
+ * Scissor clip rectangle.
+ */
+typedef volatile struct
+{
+ unsigned reserved00[4];
+ unsigned short FifoFree;
+ unsigned short Nop;
+ unsigned reserved01[0x0BB];
+ unsigned TopLeft;
+ unsigned WidthHeight;
+} RivaClip;
+/*
+ * 2D filled rectangle.
+ */
+typedef volatile struct
+{
+ unsigned reserved00[4];
+ unsigned short FifoFree;
+ unsigned short Nop[1];
+ unsigned reserved01[0x0BC];
+ unsigned Color;
+ unsigned reserved03[0x03E];
+ unsigned TopLeft;
+ unsigned WidthHeight;
+} RivaRectangle;
+/*
+ * 2D screen-screen BLT.
+ */
+typedef volatile struct
+{
+ unsigned reserved00[4];
+ unsigned short FifoFree;
+ unsigned short Nop;
+ unsigned reserved01[0x0BB];
+ unsigned TopLeftSrc;
+ unsigned TopLeftDst;
+ unsigned WidthHeight;
+} RivaScreenBlt;
+/*
+ * 2D pixel BLT.
+ */
+typedef volatile struct
+{
+ unsigned reserved00[4];
+ unsigned short FifoFree;
+ unsigned short Nop[1];
+ unsigned reserved01[0x0BC];
+ unsigned TopLeft;
+ unsigned WidthHeight;
+ unsigned WidthHeightIn;
+ unsigned reserved02[0x03C];
+ unsigned Pixels;
+} RivaPixmap;
+/*
+ * Filled rectangle combined with monochrome expand. Useful for glyphs.
+ */
+typedef volatile struct
+{
+ unsigned reserved00[4];
+ unsigned short FifoFree;
+ unsigned short Nop;
+ unsigned reserved01[0x0BB];
+ unsigned reserved03[(0x040)-1];
+ unsigned Color1A;
+ struct
+ {
+ unsigned TopLeft;
+ unsigned WidthHeight;
+ } UnclippedRectangle[64];
+ unsigned reserved04[(0x080)-3];
+ struct
+ {
+ unsigned TopLeft;
+ unsigned BottomRight;
+ } ClipB;
+ unsigned Color1B;
+ struct
+ {
+ unsigned TopLeft;
+ unsigned BottomRight;
+ } ClippedRectangle[64];
+ unsigned reserved05[(0x080)-5];
+ struct
+ {
+ unsigned TopLeft;
+ unsigned BottomRight;
+ } ClipC;
+ unsigned Color1C;
+ unsigned WidthHeightC;
+ unsigned PointC;
+ unsigned MonochromeData1C;
+ unsigned reserved06[(0x080)+121];
+ struct
+ {
+ unsigned TopLeft;
+ unsigned BottomRight;
+ } ClipD;
+ unsigned Color1D;
+ unsigned WidthHeightInD;
+ unsigned WidthHeightOutD;
+ unsigned PointD;
+ unsigned MonochromeData1D;
+ unsigned reserved07[(0x080)+120];
+ struct
+ {
+ unsigned TopLeft;
+ unsigned BottomRight;
+ } ClipE;
+ unsigned Color0E;
+ unsigned Color1E;
+ unsigned WidthHeightInE;
+ unsigned WidthHeightOutE;
+ unsigned PointE;
+ unsigned MonochromeData01E;
+} RivaBitmap;
+/*
+ * 3D textured, Z buffered triangle.
+ */
+typedef volatile struct
+{
+ unsigned reserved00[4];
+ unsigned short FifoFree;
+ unsigned short Nop;
+ unsigned reserved01[0x0BC];
+ unsigned TextureOffset;
+ unsigned TextureFormat;
+ unsigned TextureFilter;
+ unsigned FogColor;
+/* This is a problem on LynxOS */
+#ifdef Control
+#undef Control
+#endif
+ unsigned Control;
+ unsigned AlphaTest;
+ unsigned reserved02[0x339];
+ unsigned FogAndIndex;
+ unsigned Color;
+ float ScreenX;
+ float ScreenY;
+ float ScreenZ;
+ float EyeM;
+ float TextureS;
+ float TextureT;
+} RivaTexturedTriangle03;
+
+/***************************************************************************\
+* *
+* Virtualized RIVA H/W interface. *
+* *
+\***************************************************************************/
+
+struct _riva_hw_inst;
+struct _riva_hw_state;
+/*
+ * Virtialized chip interface. Makes RIVA 128 and TNT look alike.
+ */
+typedef struct _riva_hw_inst
+{
+ /*
+ * Chip specific settings.
+ */
+ unsigned Architecture;
+ unsigned Version;
+ unsigned CrystalFreqKHz;
+ unsigned RamAmountKBytes;
+ unsigned MaxVClockFreqKHz;
+ unsigned RamBandwidthKBytesPerSec;
+ unsigned EnableIRQ;
+ unsigned IO;
+ unsigned LockUnlockIO;
+ unsigned LockUnlockIndex;
+ unsigned VBlankBit;
+ unsigned FifoFreeCount;
+ unsigned FifoEmptyCount;
+ /*
+ * Non-FIFO registers.
+ */
+ volatile unsigned *PCRTC;
+ volatile unsigned *PRAMDAC;
+ volatile unsigned *PFB;
+ volatile unsigned *PFIFO;
+ volatile unsigned *PGRAPH;
+ volatile unsigned *PEXTDEV;
+ volatile unsigned *PTIMER;
+ volatile unsigned *PMC;
+ volatile unsigned *PRAMIN;
+ volatile unsigned *FIFO;
+ volatile unsigned *CURSOR;
+ volatile unsigned *CURSORPOS;
+ volatile unsigned *VBLANKENABLE;
+ volatile unsigned *VBLANK;
+ /*
+ * Common chip functions.
+ */
+ int (*Busy)(struct _riva_hw_inst *);
+ void (*CalcStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *,int,int,int,int,int,int,int,int,int,int,int,int,int);
+ void (*LoadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
+ void (*UnloadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
+ void (*SetStartAddress)(struct _riva_hw_inst *,unsigned);
+ void (*SetSurfaces2D)(struct _riva_hw_inst *,unsigned,unsigned);
+ void (*SetSurfaces3D)(struct _riva_hw_inst *,unsigned,unsigned);
+ int (*ShowHideCursor)(struct _riva_hw_inst *,int);
+ /*
+ * Current extended mode settings.
+ */
+ struct _riva_hw_state *CurrentState;
+ /*
+ * FIFO registers.
+ */
+ RivaRop *Rop;
+ RivaPattern *Patt;
+ RivaClip *Clip;
+ RivaPixmap *Pixmap;
+ RivaScreenBlt *Blt;
+ RivaBitmap *Bitmap;
+ RivaTexturedTriangle03 *Tri03;
+} RIVA_HW_INST;
+/*
+ * Extended mode state information.
+ */
+typedef struct _riva_hw_state
+{
+ unsigned bpp;
+ unsigned width;
+ unsigned height;
+ unsigned repaint0;
+ unsigned repaint1;
+ unsigned screen;
+ unsigned pixel;
+ unsigned horiz;
+ unsigned arbitration0;
+ unsigned arbitration1;
+ unsigned vpll;
+ unsigned pllsel;
+ unsigned general;
+ unsigned config;
+ unsigned cursor0;
+ unsigned cursor1;
+ unsigned cursor2;
+ unsigned offset0;
+ unsigned offset1;
+ unsigned offset2;
+ unsigned offset3;
+ unsigned pitch0;
+ unsigned pitch1;
+ unsigned pitch2;
+ unsigned pitch3;
+} RIVA_HW_STATE;
+/*
+ * External routines.
+ */
+int RivaGetConfig(RIVA_HW_INST *);
+/*
+ * FIFO Free Count. Should attempt to yield processor if RIVA is busy.
+ */
+#define RIVA_FIFO_FREE(hwinst,hwptr,cnt) \
+{ \
+while ((hwinst).FifoFreeCount < (cnt)) \
+{ \
+ (hwinst).FifoFreeCount = (hwinst).hwptr->FifoFree >> 2; \
+} \
+(hwinst).FifoFreeCount -= (cnt); \
+}
+#endif /* __RIVA_HW_H__ */
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/nv/riva_tbl.h b/xc/programs/Xserver/hw/xfree86/drivers/nv/riva_tbl.h
new file mode 100644
index 000000000..664cf1d92
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/nv/riva_tbl.h
@@ -0,0 +1,427 @@
+ /***************************************************************************\
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* NOTICE TO USER: The source code is copyrighted under U.S. and *|
+|* international laws. Users and possessors of this source code are *|
+|* hereby granted a nonexclusive, royalty-free copyright license to *|
+|* use this code in individual and commercial software. *|
+|* *|
+|* Any use of this source code must include, in the user documenta- *|
+|* tion and internal comments to the code, notices to the end user *|
+|* as follows: *|
+|* *|
+|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
+|* *|
+|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
+|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
+|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
+|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
+|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
+|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
+|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
+|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
+|* SULTING 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 SOURCE CODE. *|
+|* *|
+|* U.S. Government End Users. This source code is a "commercial *|
+|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
+|* consisting of "commercial computer software" and "commercial *|
+|* computer software documentation," as such terms are used in *|
+|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
+|* ment only as a commercial end item. Consistent with 48 C.F.R. *|
+|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
+|* all U.S. Government End Users acquire the source code with only *|
+|* those rights set forth herein. *|
+|* *|
+ \***************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_tbl.h,v 1.1 1999/08/01 07:21:01 dawes Exp $ */
+/*
+ * RIVA Fixed Functionality Init Tables.
+ */
+static unsigned RivaTablePMC[][2] =
+{
+ {0x00000050, 0x00000000},
+ {0x00000080, 0xFFFF00FF},
+ {0x00000080, 0xFFFFFFFF}
+};
+static unsigned RivaTablePTIMER[][2] =
+{
+ {0x00000080, 0x00000008},
+ {0x00000084, 0x00000003},
+ {0x00000050, 0x00000000},
+ {0x00000040, 0xFFFFFFFF}
+};
+static unsigned RivaTableFIFO[][2] =
+{
+ {0x00000000, 0x80000000},
+ {0x00000800, 0x80000001},
+ {0x00001000, 0x80000002},
+ {0x00001800, 0x80000010},
+ {0x00002000, 0x80000011},
+ {0x00002800, 0x80000012},
+ {0x00003800, 0x80000013}
+};
+static unsigned nv3TablePFIFO[][2] =
+{
+ {0x00000140, 0x00000000},
+ {0x00000480, 0x00000000},
+ {0x00000490, 0x00000000},
+ {0x00000494, 0x00000000},
+ {0x00000481, 0x00000000},
+ {0x00000084, 0x00000000},
+ {0x00000086, 0x00002000},
+ {0x00000085, 0x00002200},
+ {0x00000484, 0x00000000},
+ {0x0000049C, 0x00000000},
+ {0x00000104, 0x00000000},
+ {0x00000108, 0x00000000},
+ {0x00000100, 0x00000000},
+ {0x000004A0, 0x00000000},
+ {0x000004A4, 0x00000000},
+ {0x000004A8, 0x00000000},
+ {0x000004AC, 0x00000000},
+ {0x000004B0, 0x00000000},
+ {0x000004B4, 0x00000000},
+ {0x000004B8, 0x00000000},
+ {0x000004BC, 0x00000000},
+ {0x00000050, 0x00000000},
+ {0x00000040, 0xFFFFFFFF},
+ {0x00000480, 0x00000001},
+ {0x00000490, 0x00000001},
+ {0x00000140, 0x00000001}
+};
+static unsigned nv3TablePGRAPH[][2] =
+{
+ {0x00000020, 0x1230001F},
+ {0x00000021, 0x10113000},
+ {0x00000022, 0x1131F101},
+ {0x00000023, 0x0100F531},
+ {0x00000060, 0x00000000},
+ {0x00000065, 0x00000000},
+ {0x00000068, 0x00000000},
+ {0x00000069, 0x00000000},
+ {0x0000006A, 0x00000000},
+ {0x0000006B, 0x00000000},
+ {0x0000006C, 0x00000000},
+ {0x0000006D, 0x00000000},
+ {0x0000006E, 0x00000000},
+ {0x0000006F, 0x00000000},
+ {0x000001A8, 0x00000000},
+ {0x00000440, 0xFFFFFFFF},
+ {0x00000480, 0x00000001},
+ {0x000001A0, 0x00000000},
+ {0x000001A2, 0x00000000},
+ {0x0000018A, 0xFFFFFFFF},
+ {0x00000190, 0x00000000},
+ {0x00000142, 0x00000000},
+ {0x00000154, 0x00000000},
+ {0x00000155, 0xFFFFFFFF},
+ {0x00000156, 0x00000000},
+ {0x00000157, 0xFFFFFFFF},
+ {0x00000064, 0x10010002},
+ {0x00000050, 0x00000000},
+ {0x00000051, 0x00000000},
+ {0x00000040, 0xFFFFFFFF},
+ {0x00000041, 0xFFFFFFFF},
+ {0x00000440, 0xFFFFFFFF},
+ {0x000001A9, 0x00000001}
+};
+static unsigned nv3TablePGRAPH_8BPP[][2] =
+{
+ {0x000001AA, 0x00001111}
+};
+static unsigned nv3TablePGRAPH_15BPP[][2] =
+{
+ {0x000001AA, 0x00002222}
+};
+static unsigned nv3TablePGRAPH_32BPP[][2] =
+{
+ {0x000001AA, 0x00003333}
+};
+static unsigned nv3TablePRAMIN[][2] =
+{
+ {0x00000500, 0x00010000},
+ {0x00000501, 0x007FFFFF},
+ {0x00000200, 0x80000000},
+ {0x00000201, 0x00C20341},
+ {0x00000204, 0x80000001},
+ {0x00000205, 0x00C50342},
+ {0x00000208, 0x80000002},
+ {0x00000209, 0x00C60343},
+ {0x00000240, 0x80000010},
+ {0x00000241, 0x00D10344},
+ {0x00000244, 0x80000011},
+ {0x00000245, 0x00D00345},
+ {0x00000248, 0x80000012},
+ {0x00000249, 0x00CC0346},
+ {0x0000024C, 0x80000013},
+ {0x0000024D, 0x00D70347},
+ {0x00000D05, 0x00000000},
+ {0x00000D06, 0x00000000},
+ {0x00000D07, 0x00000000},
+ {0x00000D09, 0x00000000},
+ {0x00000D0A, 0x00000000},
+ {0x00000D0B, 0x00000000},
+ {0x00000D0D, 0x00000000},
+ {0x00000D0E, 0x00000000},
+ {0x00000D0F, 0x00000000},
+ {0x00000D11, 0x00000000},
+ {0x00000D12, 0x00000000},
+ {0x00000D13, 0x00000000},
+ {0x00000D15, 0x00000000},
+ {0x00000D16, 0x00000000},
+ {0x00000D17, 0x00000000},
+ {0x00000D19, 0x00000000},
+ {0x00000D1A, 0x00000000},
+ {0x00000D1B, 0x00000000},
+ {0x00000D1D, 0x00000140},
+ {0x00000D1E, 0x00000000},
+ {0x00000D1F, 0x00000000}
+};
+static unsigned nv3TablePRAMIN_8BPP[][2] =
+{
+ /* 0xXXXXX3XX For MSB mono format */
+ /* 0xXXXXX2XX For LSB mono format */
+ {0x00000D04, 0x10110203},
+ {0x00000D08, 0x10110203},
+ {0x00000D0C, 0x1011020B},
+ {0x00000D10, 0x10118203},
+ {0x00000D14, 0x10110203},
+ {0x00000D18, 0x10110203},
+ {0x00000D1C, 0x10419208}
+};
+static unsigned nv3TablePRAMIN_15BPP[][2] =
+{
+ /* 0xXXXXX2XX For MSB mono format */
+ /* 0xXXXXX3XX For LSB mono format */
+ {0x00000D04, 0x10110200},
+ {0x00000D08, 0x10110200},
+ {0x00000D0C, 0x10110208},
+ {0x00000D10, 0x10118200},
+ {0x00000D14, 0x10110200},
+ {0x00000D18, 0x10110200},
+ {0x00000D1C, 0x10419208}
+};
+static unsigned nv3TablePRAMIN_32BPP[][2] =
+{
+ /* 0xXXXXX3XX For MSB mono format */
+ /* 0xXXXXX2XX For LSB mono format */
+ {0x00000D04, 0x10110201},
+ {0x00000D08, 0x10110201},
+ {0x00000D0C, 0x10110209},
+ {0x00000D10, 0x10118201},
+ {0x00000D14, 0x10110201},
+ {0x00000D18, 0x10110201},
+ {0x00000D1C, 0x10419208}
+};
+static unsigned nv4TablePFIFO[][2] =
+{
+ {0x00000140, 0x00000000},
+ {0x00000480, 0x00000000},
+ {0x00000494, 0x00000000},
+ {0x00000400, 0x00000000},
+ {0x00000414, 0x00000000},
+ {0x00000084, 0x03000100},
+ {0x00000085, 0x00000110},
+ {0x00000086, 0x00000112},
+ {0x00000143, 0x0000FFFF},
+ {0x00000496, 0x0000FFFF},
+ {0x00000050, 0x00000000},
+ {0x00000040, 0xFFFFFFFF},
+ {0x00000415, 0x00000001},
+ {0x00000480, 0x00000001},
+ {0x00000494, 0x00000001},
+ {0x00000495, 0x00000001},
+ {0x00000140, 0x00000001}
+};
+static unsigned nv4TablePGRAPH[][2] =
+{
+ {0x00000020, 0x1231C001},
+ {0x00000021, 0x72111101},
+ {0x00000022, 0x11D5F071},
+ {0x00000023, 0x10D4FF31},
+ {0x00000060, 0x00000000},
+ {0x00000068, 0x00000000},
+ {0x00000070, 0x00000000},
+ {0x00000078, 0x00000000},
+ {0x00000061, 0x00000000},
+ {0x00000069, 0x00000000},
+ {0x00000071, 0x00000000},
+ {0x00000079, 0x00000000},
+ {0x00000062, 0x00000000},
+ {0x0000006A, 0x00000000},
+ {0x00000072, 0x00000000},
+ {0x0000007A, 0x00000000},
+ {0x00000063, 0x00000000},
+ {0x0000006B, 0x00000000},
+ {0x00000073, 0x00000000},
+ {0x0000007B, 0x00000000},
+ {0x00000064, 0x00000000},
+ {0x0000006C, 0x00000000},
+ {0x00000074, 0x00000000},
+ {0x0000007C, 0x00000000},
+ {0x00000065, 0x00000000},
+ {0x0000006D, 0x00000000},
+ {0x00000075, 0x00000000},
+ {0x0000007D, 0x00000000},
+ {0x00000066, 0x00000000},
+ {0x0000006E, 0x00000000},
+ {0x00000076, 0x00000000},
+ {0x0000007E, 0x00000000},
+ {0x00000067, 0x00000000},
+ {0x0000006F, 0x00000000},
+ {0x00000077, 0x00000000},
+ {0x0000007F, 0x00000000},
+ {0x00000058, 0x00000000},
+ {0x00000059, 0x00000000},
+ {0x0000005A, 0x00000000},
+ {0x0000005B, 0x00000000},
+ {0x00000196, 0x00000000},
+ {0x000001A1, 0x01FFFFFF},
+ {0x00000197, 0x00000000},
+ {0x000001A2, 0x01FFFFFF},
+ {0x00000198, 0x00000000},
+ {0x000001A3, 0x01FFFFFF},
+ {0x00000199, 0x00000000},
+ {0x000001A4, 0x01FFFFFF},
+ {0x00000050, 0x00000000},
+ {0x00000040, 0xFFFFFFFF},
+ {0x0000005C, 0x10010100},
+ {0x000001C4, 0xFFFFFFFF},
+ {0x000001C8, 0x00000001},
+ {0x00000204, 0x00000000}
+};
+static unsigned nv4TablePGRAPH_8BPP[][2] =
+{
+ {0x000001C9, 0x00111111},
+ {0x00000186, 0x00001010},
+ {0x0000020C, 0x03020202}
+};
+static unsigned nv4TablePGRAPH_15BPP[][2] =
+{
+ {0x000001C9, 0x00226222},
+ {0x00000186, 0x00002071},
+ {0x0000020C, 0x09080808}
+};
+static unsigned nv4TablePGRAPH_16BPP[][2] =
+{
+ {0x000001C9, 0x00556555},
+ {0x00000186, 0x000050C2},
+ {0x0000020C, 0x0C0B0B0B}
+};
+static unsigned nv4TablePGRAPH_32BPP[][2] =
+{
+ {0x000001C9, 0x0077D777},
+ {0x00000186, 0x000070E5},
+ {0x0000020C, 0x0E0D0D0D}
+};
+static unsigned nv4TablePRAMIN[][2] =
+{
+ {0x00000000, 0x80000010},
+ {0x00000001, 0x80011145},
+ {0x00000002, 0x80000011},
+ {0x00000003, 0x80011146},
+ {0x00000004, 0x80000012},
+ {0x00000005, 0x80011147},
+ {0x00000006, 0x80000013},
+ {0x00000007, 0x80011148},
+ {0x00000008, 0x80000014},
+ {0x00000009, 0x80011149},
+ {0x0000000A, 0x80000015},
+ {0x0000000B, 0x8001114A},
+ {0x00000020, 0x80000000},
+ {0x00000021, 0x80011142},
+ {0x00000022, 0x80000001},
+ {0x00000023, 0x80011143},
+ {0x00000024, 0x80000002},
+ {0x00000025, 0x80011144},
+ {0x00000500, 0x00003000},
+ {0x00000501, 0x01FFFFFF},
+ {0x00000502, 0x00000002},
+ {0x00000503, 0x00000002},
+ {0x00000508, 0x01008043},
+ {0x0000050A, 0x00000000},
+ {0x0000050B, 0x00000000},
+ {0x0000050C, 0x01008019},
+ {0x0000050E, 0x00000000},
+ {0x0000050F, 0x00000000},
+#if 1
+ {0x00000510, 0x01008018},
+#else
+ {0x00000510, 0x01008044},
+#endif
+ {0x00000512, 0x00000000},
+ {0x00000513, 0x00000000},
+ {0x00000514, 0x0100A033},
+ {0x00000516, 0x00000000},
+ {0x00000517, 0x00000000},
+ {0x00000518, 0x0100805F},
+ {0x0000051A, 0x00000000},
+ {0x0000051B, 0x00000000},
+#if 1
+ {0x0000051C, 0x0100804B},
+#else
+ {0x0000051C, 0x0100804A},
+#endif
+ {0x0000051E, 0x00000000},
+ {0x0000051F, 0x00000000},
+ {0x00000520, 0x0100A048},
+ {0x00000521, 0x00000D01},
+ {0x00000522, 0x11401140},
+ {0x00000523, 0x00000000},
+ {0x00000524, 0x0100A054},
+ {0x00000525, 0x00000D01},
+ {0x00000526, 0x11401140},
+ {0x00000527, 0x00000000},
+ {0x00000528, 0x0100A055},
+ {0x00000529, 0x00000D01},
+ {0x0000052A, 0x11401140},
+ {0x0000052B, 0x00000000}
+};
+static unsigned nv4TablePRAMIN_8BPP[][2] =
+{
+ /* 0xXXXXXX01 For MSB mono format */
+ /* 0xXXXXXX02 For LSB mono format */
+ {0x00000509, 0x00000302},
+ {0x0000050D, 0x00000302},
+ {0x00000511, 0x00000202},
+ {0x00000515, 0x00000302},
+ {0x00000519, 0x00000302},
+ {0x0000051D, 0x00000302}
+};
+static unsigned nv4TablePRAMIN_15BPP[][2] =
+{
+ /* 0xXXXXXX01 For MSB mono format */
+ /* 0xXXXXXX02 For LSB mono format */
+ {0x00000509, 0x00000902},
+ {0x0000050D, 0x00000902},
+ {0x00000511, 0x00000802},
+ {0x00000515, 0x00000902},
+ {0x00000519, 0x00000902},
+ {0x0000051D, 0x00000902}
+};
+static unsigned nv4TablePRAMIN_16BPP[][2] =
+{
+ /* 0xXXXXXX01 For MSB mono format */
+ /* 0xXXXXXX02 For LSB mono format */
+ {0x00000509, 0x00000C02},
+ {0x0000050D, 0x00000C02},
+ {0x00000511, 0x00000B02},
+ {0x00000515, 0x00000C02},
+ {0x00000519, 0x00000C02},
+ {0x0000051D, 0x00000C02}
+};
+static unsigned nv4TablePRAMIN_32BPP[][2] =
+{
+ /* 0xXXXXXX01 For MSB mono format */
+ /* 0xXXXXXX02 For LSB mono format */
+ {0x00000509, 0x00000E02},
+ {0x0000050D, 0x00000E02},
+ {0x00000511, 0x00000D02},
+ {0x00000515, 0x00000E02},
+ {0x00000519, 0x00000E02},
+ {0x0000051D, 0x00000E02}
+};
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/rendition/Imakefile
new file mode 100644
index 000000000..443d4b5ce
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/Imakefile
@@ -0,0 +1,60 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/Imakefile,v 1.6 1999/08/14 10:49:53 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = rendition.c vboard.c vmodes.c vramdac.c v1krisc.c vvga.c
+
+OBJS = rendition.o vboard.o vmodes.o vramdac.o v1krisc.o vvga.o
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86SRC)/xf4bpp -I$(XF86SRC)/xf1bpp \
+ -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mfb \
+ -I$(SERVERSRC)/mi -I$(SERVERSRC)/cfb\
+ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c -I$(XF86SRC)/vgahw \
+ -I$(XF86SRC)/rac \
+ -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(FONTINCSRC) -I$(XINCLUDESRC) \
+ -I$(SERVERSRC)/include -I$(XF86SRC)/xaa \
+ -I$(XF86SRC)/xf24_32bpp -I$(XF86SRC)/xf8_32bpp \
+ -I$(XF86SRC)/ramdac -I$(SERVERSRC)/Xext \
+ -I$(XF86SRC)/shadowfb -I$(XF86SRC)/rac
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget(rendition,$(OBJS))
+
+InstallObjectModule(rendition,$(MODULEDIR),drivers)
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(cscode.h,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(rendition.c,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(v1kregs.h,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(v1krisc.c,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(v1krisc.h,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(v1kregs.h,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(vboard.c,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(vboard.h,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(vloaduc.h,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(vmodes.c,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(vmodes.h,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(vos.h,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(vramdac.c,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(vramdac.h,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(vtypes.h,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(vvga.c,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(vvga.h,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(v2kregs.h,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(vgafont-vrx.data,$(DRIVERSDKDIR)/drivers/rendition)
+InstallDriverSDKNonExecFile(vgapalette.data,$(DRIVERSDKDIR)/drivers/rendition)
+
+InstallDriverSDKObjectModule(rendition,$(DRIVERSDKMODULEDIR),drivers)
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/cscode.h b/xc/programs/Xserver/hw/xfree86/drivers/rendition/cscode.h
new file mode 100644
index 000000000..354eb9e43
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/cscode.h
@@ -0,0 +1,37 @@
+/****************************************************************************\
+ * NOTE: This file generated automatically. Do not edit by hand! *
+\****************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/cscode.h,v 1.2 1999/04/17 07:06:31 dawes Exp $ */
+
+static vu32 csrisc[]={
+ 0x10802100L,
+ 0x5d808000L,
+ 0x4c808002L,
+ 0x6b820000L,
+ 0x00818002L,
+ 0x45818103L,
+ 0x10828281L,
+ 0x6f000082L,
+ 0x00000000L,
+ 0x62000500L,
+ 0x00000000L,
+ 0x62000300L,
+ 0x00000000L,
+ 0x62000800L,
+ 0x00000000L,
+ 0x10812100L,
+ 0x10822100L,
+ 0x10c02100L,
+ 0x6ffe00c0L,
+ 0x00000000L,
+ 0x62ffeb00L,
+ 0x00000000L,
+ 0x04812502L,
+ 0x61fffe81L,
+ 0x00000000L,
+ 0x10218000L,
+ 0x00000000L,
+ 0x00000000L,
+ 0x62ffe300L,
+ 0x00000000L,
+};
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/rendition.c b/xc/programs/Xserver/hw/xfree86/drivers/rendition/rendition.c
new file mode 100644
index 000000000..48cfcd29e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/rendition.c
@@ -0,0 +1,1081 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/rendition.c,v 1.6 1999/06/27 09:20:22 dawes Exp $ */
+/*
+ * Copyright (C) 1998 The XFree86 Project, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * XFREE86 PROJECT 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 XFree86 Project 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
+ * XFree86 Project.
+ */
+
+/*
+ * This is essentially a transfer of the 3.3 sources written by
+ * Marc Langenbach and Tim Rowley.
+ *
+ * The initial port of this driver to XFree86 4.0 was done by
+ * Marc Langenbach <mlangen@studcs.uni-sb.de>
+ */
+
+/*
+ * includes
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "compiler.h"
+#include "vgaHW.h"
+#include "xf86RAC.h"
+
+/* This is used for module versioning */
+#include "xf86Version.h"
+
+#undef PSZ
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb32.h"
+
+#include "mipointer.h"
+#include "micmap.h"
+
+#include "xf86RAC.h"
+
+#include "vtypes.h"
+#include "vboard.h"
+#include "vmodes.h"
+#include "vvga.h"
+
+
+
+/*
+ * defines
+ */
+
+#undef DEBUG
+
+#define RENDITION_NAME "Rendition"
+#define RENDITION_DRIVER_NAME "rendition"
+#define RENDITION_VERSION_NAME "4.0"
+#define RENDITION_VERSION_MAJOR 4
+#define RENDITION_VERSION_MINOR 0
+#define RENDITION_PATCHLEVEL 0
+#define RENDITION_VERSION_CURRENT ((RENDITION_VERSION_MAJOR << 24) | \
+ (RENDITION_VERSION_MINOR << 16) | RENDITION_PATCHLEVEL)
+
+#define RENDITIONPTR(p) ((renditionPtr)((p)->driverPrivate))
+
+
+/*
+ * local function prototypes
+ */
+
+static void renditionIdentify(int);
+static Bool renditionProbe(DriverPtr, int);
+static Bool renditionPreInit(ScrnInfoPtr, int);
+static Bool renditionScreenInit(int, ScreenPtr, int, char **);
+static Bool renditionSwitchMode(int, DisplayModePtr, int);
+static void renditionAdjustFrame(int, int, int, int);
+static Bool renditionEnterVT(int, int);
+static void renditionLeaveVT(int, int);
+static void renditionFreeScreen(int, int);
+
+static ModeStatus renditionValidMode(int, DisplayModePtr, Bool, int);
+static Bool renditionMapMem(ScrnInfoPtr pScreenInfo);
+static Bool renditionUnmapMem(ScrnInfoPtr pScreenInfo);
+
+
+
+/*
+ * global data
+ */
+
+DriverRec RENDITION={
+ RENDITION_VERSION_CURRENT,
+ "rendition driver",
+ renditionIdentify,
+ renditionProbe,
+ NULL,
+ 0
+};
+
+static const char *vgahwSymbols[]={
+ "vgaHWGetHWRec",
+ "vgaHWUnlock",
+ "vgaHWInit",
+ "vgaHWProtect",
+ "vgaHWGetIOBase",
+ "vgaHWMapMem",
+ "vgaHWUnmapMem",
+ "vgaHWLock",
+ "vgaHWFreeHWRec",
+ "vgaHWSaveScreen",
+ "vgaHWSave",
+ "vgaHWRestore",
+ "vgaHWGetIndex",
+ "vgaHWDPMSSet",
+ "vgaHWBlankScreen",
+ "vgaHWHandleColormaps",
+ NULL
+};
+
+static const char *fbSymbols[]={
+ "xf1bppScreenInit",
+ "xf4bppScreenInit",
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb32ScreenInit",
+ NULL
+};
+
+#ifdef XFree86LOADER
+
+/* Module loader interface */
+
+static MODULESETUPPROTO(renditionSetup);
+
+static XF86ModuleVersionInfo renditionVersionRec = {
+ RENDITION_DRIVER_NAME,
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ RENDITION_VERSION_MAJOR, RENDITION_VERSION_MINOR, RENDITION_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0, 0, 0, 0}
+};
+
+XF86ModuleData renditionModuleData =
+ { &renditionVersionRec, renditionSetup, NULL };
+
+static pointer
+renditionSetup(pointer Module, pointer Options, int *ErrorMajor,
+ int *ErrorMinor)
+{
+ static Bool Initialised=FALSE;
+
+ if (!Initialised) {
+ Initialised=TRUE;
+ xf86AddDriver(&RENDITION, Module, 0);
+ LoaderRefSymLists(vgahwSymbols, fbSymbols, NULL);
+ return (pointer)TRUE;
+ }
+
+ if (ErrorMajor)
+ *ErrorMajor=LDR_ONCEONLY;
+
+ return NULL;
+}
+
+#endif
+
+
+enum renditionTypes {
+ CHIP_RENDITION_V1000,
+ CHIP_RENDITION_V2x00
+};
+
+/* supported chipsets */
+static SymTabRec renditionChipsets[] = {
+ {CHIP_RENDITION_V1000, "Verite 1000"},
+ {CHIP_RENDITION_V2x00, "Verite 2x00"},
+ {-1, NULL}
+};
+
+static PciChipsets renditionPCIchipsets[] = {
+ { CHIP_RENDITION_V1000, PCI_CHIP_V1000, RES_SHARED_VGA },
+ { CHIP_RENDITION_V2x00, PCI_CHIP_V2x00, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED }
+};
+
+/* supported options */
+typedef enum {
+ OPTION_FBWC,
+ OPTION_SW_CURSOR,
+ OPTION_NOACCEL
+} renditionOpts;
+
+static OptionInfoRec renditionOptions[]={
+ { OPTION_FBWC, "FramebufferWC", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SW_CURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+
+
+/*
+ * functions
+ */
+
+static void
+renditionIdentify(int flags)
+{
+ xf86PrintChipsets(RENDITION_NAME,
+ "rendition driver (version " RENDITION_VERSION_NAME ") for chipsets",
+ renditionChipsets);
+}
+
+
+
+/*
+ * This function is called once, at the start of the first server generation to
+ * do a minimal probe for supported hardware.
+ */
+static Bool
+renditionProbe(DriverPtr drv, int flags)
+{
+ Bool foundScreen=FALSE;
+ int numDevSections, numUsed;
+ GDevPtr *devSections;
+ int *usedChips;
+ int c;
+
+ /* Find the config file Device sections that match this
+ * driver, and return if there are none. */
+ if ((numDevSections=xf86MatchDevice(RENDITION_NAME, &devSections)) <= 0)
+ return FALSE;
+
+ /* PCI BUS */
+ if (xf86GetPciVideoInfo()) {
+ numUsed=xf86MatchPciInstances(RENDITION_NAME, PCI_VENDOR_RENDITION,
+ renditionChipsets, renditionPCIchipsets,
+ devSections, numDevSections, drv, &usedChips);
+ for (c=0; c<numUsed; c++) {
+ ScrnInfoPtr pScrn;
+ /* Allocate a ScrnInfoRec and claim the slot */
+ pScrn=xf86AllocateScreen(drv, 0);
+ pScrn->driverVersion=RENDITION_VERSION_CURRENT;
+ pScrn->driverName =RENDITION_DRIVER_NAME;
+ pScrn->name =RENDITION_NAME;
+ pScrn->Probe =renditionProbe;
+ pScrn->PreInit =renditionPreInit;
+ pScrn->ScreenInit =renditionScreenInit;
+ pScrn->SwitchMode =renditionSwitchMode;
+ pScrn->AdjustFrame =renditionAdjustFrame;
+ pScrn->EnterVT =renditionEnterVT;
+ pScrn->LeaveVT =renditionLeaveVT;
+ pScrn->FreeScreen =renditionFreeScreen;
+ pScrn->ValidMode =renditionValidMode;
+ foundScreen=TRUE;
+ xf86ConfigActivePciEntity(pScrn, usedChips[c],
+ renditionPCIchipsets, NULL, NULL, NULL, NULL, NULL);
+ }
+ if (numUsed > 0)
+ xfree(usedChips);
+ }
+ xfree(devSections);
+ return foundScreen;
+}
+
+
+
+static Bool
+renditionClockSelect(ScrnInfoPtr pScreenInfo, int ClockNumber)
+{
+ static CARD8 save_misc;
+
+ switch (ClockNumber)
+ {
+ case CLK_REG_SAVE:
+ save_misc = inb(0x3CC);
+ break;
+
+ case CLK_REG_RESTORE:
+ outb(0x3C2, save_misc);
+ break;
+
+ default:
+ outb(0x3C2, (save_misc & 0xF3) | ((ClockNumber << 2) & 0x0C));
+ break;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * This structure is used to wrap the screen's CloseScreen vector.
+ */
+typedef struct _renditionRec
+{
+ struct v_board_t board; /* information on the board */
+ struct v_modeinfo_t mode; /* information on the mode */
+ int pcitag; /* tag for the PCI config space */
+ pciVideoPtr PciInfo; /* PCI config data */
+ EntityInfoPtr pEnt; /* entity information */
+ CloseScreenProcPtr CloseScreen; /* wrap CloseScreen */
+} renditionRec, *renditionPtr;
+
+
+static renditionPtr
+renditionGetRec(ScrnInfoPtr pScreenInfo)
+{
+ if (!pScreenInfo->driverPrivate)
+ pScreenInfo->driverPrivate=xcalloc(sizeof(renditionRec), 1);
+
+ /* perhaps some initialization? <ml> */
+
+ return (renditionPtr)pScreenInfo->driverPrivate;
+}
+
+
+static void
+renditionFreeRec(ScrnInfoPtr pScreenInfo)
+{
+ vgaHWFreeHWRec(pScreenInfo);
+ xfree(pScreenInfo->driverPrivate);
+ pScreenInfo->driverPrivate=NULL;
+}
+
+
+static void
+renditionProtect(ScrnInfoPtr pScreenInfo, Bool On)
+{
+ vgaHWProtect(pScreenInfo, On);
+}
+
+
+static Bool
+renditionSaveScreen(ScreenPtr pScreen, Bool Unblank)
+{
+ return vgaHWSaveScreen(pScreen, Unblank);
+}
+
+static void
+renditionBlankScreen(ScrnInfoPtr pScreenInfo, Bool Unblank)
+{
+ vgaHWBlankScreen(pScreenInfo, Unblank);
+}
+
+
+/*
+ * This function is called once for each screen at the start of the first
+ * server generation to initialise the screen for all server generations.
+ */
+static Bool
+renditionPreInit(ScrnInfoPtr pScreenInfo, int flags)
+{
+ static ClockRange renditionClockRange = {NULL, 0, 135000, -1, FALSE, TRUE, 1, 1, 0};
+ MessageType From;
+ int i, videoRam, Rounding, nModes = 0;
+ char *Module;
+ const char *Sym;
+ vgaHWPtr pvgaHW;
+ renditionPtr pRendition;
+
+
+#ifdef DEBUG
+ ErrorF("Rendition: renditionPreInit() called\n");
+#endif
+
+ /* Check the number of entities, and fail if it isn't one. */
+ if (pScreenInfo->numEntities != 1)
+ return FALSE;
+
+ /* set the monitor */
+ pScreenInfo->monitor=pScreenInfo->confScreen->monitor;
+
+ /* allocate driver private structure */
+ if (!renditionGetRec(pScreenInfo))
+ return FALSE;
+ pRendition=RENDITIONPTR(pScreenInfo);
+
+ /* Get the entity, and make sure it is PCI. */
+ pRendition->pEnt = xf86GetEntityInfo(pScreenInfo->entityList[0]);
+ if (pRendition->pEnt->location.type != BUS_PCI)
+ return FALSE;
+
+ /* Find the PCI info for this screen */
+ pRendition->PciInfo = xf86GetPciInfoForEntity(pRendition->pEnt->index);
+ pRendition->pcitag= pciTag(pRendition->PciInfo->bus,
+ pRendition->PciInfo->device, pRendition->PciInfo->func);
+
+ /*
+ * XXX This could be refined if some VGA memory resources are not
+ * decoded in operating mode.
+ */
+ {
+ resRange vgamem[] = { {ResShrMemBlock,0xA0000,0xAFFFF},
+ {ResShrMemBlock,0xB0000,0xB7FFF},
+ {ResShrMemBlock,0xB8000,0xBFFFF},
+ _END };
+ xf86SetOperatingState(vgamem, pRendition->pEnt->index, ResUnusedOpr);
+ }
+ /* Operations for which memory access is required. */
+ pScreenInfo->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+ /* Operations for which I/O access is required. (XXX Check this) */
+ pScreenInfo->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+
+ /* determine depth, bpp, etc. */
+ if (!xf86SetDepthBpp(pScreenInfo, 8, 8, 8, NoDepth24Support))
+ return FALSE;
+
+ switch (pScreenInfo->depth) {
+ case 8: Module = "cfb"; Sym = "cfbScreenInit"; break;
+ case 16: Module = "cfb16"; Sym = "cfbScreenInit16"; break;
+ case 24: Module = "cfb32"; Sym = "cfbScreenInit32"; break;
+
+ default:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver.\n",
+ pScreenInfo->depth);
+ return FALSE;
+ }
+
+ /* Ensure depth-specific entry points are available */
+ if (!xf86LoadSubModule(pScreenInfo, Module))
+ return FALSE;
+
+ xf86LoaderReqSymbols(Sym, NULL);
+
+ /* determine colour weights */
+ pScreenInfo->rgbBits=8;
+
+ if (pScreenInfo->depth > 8) {
+ rgb zeros = {0, 0, 0};
+
+ xf86PrintDepthBpp(pScreenInfo);
+
+ /* Standard defaults are OK if depths are OK */
+ if (!xf86SetWeight(pScreenInfo, zeros, zeros))
+ return FALSE;
+ else{
+ /* XXX: Check that returned weight is supported */
+ }
+ }
+
+ /* determine default visual */
+ if (!xf86SetDefaultVisual(pScreenInfo, -1))
+ return FALSE;
+
+ /* the gamma fields must be initialised when using the new cmap code */
+ if (pScreenInfo->depth > 1) {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScreenInfo, zeros))
+ return FALSE;
+ }
+
+ /* the Rendition chips have a programmable clock */
+ pScreenInfo->progClock=TRUE;
+
+ /* collect all of the options flags and process them */
+ /* Deal with options */
+
+ xf86CollectOptions(pScreenInfo, NULL);
+ xf86ProcessOptions(pScreenInfo->scrnIndex, pScreenInfo->options,
+ renditionOptions);
+
+ /* set various fields according to the given options */
+ /* to be filled in <ml> */
+
+ if (PCI_CHIP_V1000==pRendition->PciInfo->chipType){
+ pRendition->board.chip=V1000_DEVICE;
+ }
+ else {
+ pRendition->board.chip=V2000_DEVICE;
+ renditionClockRange.maxClock = 170000;
+ renditionClockRange.clockIndex = -1;
+ }
+
+ pRendition->board.accel=0;
+ pRendition->board.io_base=pRendition->PciInfo->ioBase[1];
+ pRendition->board.mmio_base=0;
+ pRendition->board.vmmio_base=0;
+ pRendition->board.mem_size=0;
+ pRendition->board.mem_base=(vu8 *)pRendition->PciInfo->memBase[0];
+ pRendition->board.vmem_base=NULL;
+ pRendition->board.init=0;
+
+ if (pScreenInfo->chipset)
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG, "Chipset: \"%s\".\n",
+ pScreenInfo->chipset);
+ else
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, "Chipset: \"%s\".\n",
+ renditionChipsets[
+ pRendition->board.chip==V1000_DEVICE ? 0:1].name);
+
+ /* I do not get the IO base addres <ml> */
+ /* XXX Is this still true? If so, the wrong base is being checked */
+ ErrorF("Rendition %s @ %x/%x\n",renditionChipsets[
+ pRendition->board.chip==V1000_DEVICE ? 0:1].name,
+ pRendition->board.io_base,
+ pRendition->board.mem_base);
+ /* so I hardcoded it <ml> */
+ /* pRendition->board.io_base=0x9800; */
+
+ /* determine video ram -- to do so, we assume a full size memory of 16M,
+ * then map it and use v_getmemorysize() to determine the real amount of
+ * memory */
+ pScreenInfo->videoRam=pRendition->board.mem_size=16<<20;
+ renditionMapMem(pScreenInfo);
+ videoRam=v_getmemorysize(&pRendition->board)>>10;
+ renditionUnmapMem(pScreenInfo);
+ From = X_PROBED;
+ xf86DrvMsg(pScreenInfo->scrnIndex, From, "videoRam: %d kBytes\n", videoRam);
+ pScreenInfo->videoRam=videoRam;
+ pRendition->board.mem_size=videoRam;
+
+ if (!xf86LoadSubModule(pScreenInfo, "vgahw"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /* ensure vgahw private structure is allocated */
+ if (!vgaHWGetHWRec(pScreenInfo))
+ return FALSE;
+
+ pvgaHW = VGAHWPTR(pScreenInfo);
+ pvgaHW->MapSize = 0x00010000; /* Standard 64kB VGA window */
+ vgaHWGetIOBase(pvgaHW); /* Get VGA I/O base */
+
+ /*
+ * Determine clocks. Limit them to the first four because that's all that
+ * can be addressed.
+ * XXX Aren't the clocks programmable? If so, this discrete clock stuff
+ * shouldn't be used.
+ */
+ if ((pScreenInfo->numClocks = pRendition->pEnt->device->numclocks))
+ {
+ if (pScreenInfo->numClocks > 4)
+ pScreenInfo->numClocks = 4;
+ for (i = 0; i < pScreenInfo->numClocks; i++)
+ pScreenInfo->clock[i] = pRendition->pEnt->device->clock[i];
+ From = X_CONFIG;
+ }
+ else
+ {
+ xf86GetClocks(pScreenInfo, 4, renditionClockSelect, renditionProtect,
+ renditionBlankScreen, VGAHW_GET_IOBASE() + 0x0A, 0x08, 1, 28322);
+ From = X_PROBED;
+ }
+ xf86ShowClocks(pScreenInfo, From);
+
+ if (pScreenInfo->display->modes && pScreenInfo->display->modes[0])
+ {
+ /* Set the virtual X rounding (in bits) */
+ if (pScreenInfo->depth == 8)
+ Rounding = 16 * 8;
+ else
+ Rounding = 16;
+
+ /*
+ * Validate the modes. Note that the limits passed to
+ * xf86ValidateModes() are VGA CRTC architectural limits.
+ */
+ pScreenInfo->maxHValue = 2080;
+ pScreenInfo->maxVValue = 1025;
+ nModes = xf86ValidateModes(pScreenInfo,
+ pScreenInfo->monitor->Modes, pScreenInfo->display->modes,
+ &renditionClockRange, NULL, 8, 2040, Rounding, 1, 1024,
+ pScreenInfo->display->virtualX, pScreenInfo->display->virtualY,
+ 0x10000, LOOKUP_CLOSEST_CLOCK | LOOKUP_CLKDIV2);
+
+ if (nModes < 0)
+ return FALSE;
+
+ /* Remove invalid modes */
+ xf86PruneDriverModes(pScreenInfo);
+ }
+
+ /* Set CRTC values for the modes */
+ xf86SetCrtcForModes(pScreenInfo, 0);
+
+ /* Set current mode to the first in list */
+ pScreenInfo->currentMode = pScreenInfo->modes;
+
+ /* Print mode list */
+ xf86PrintModes(pScreenInfo);
+
+ /* Set display resolution */
+ xf86SetDpi(pScreenInfo, 0, 0);
+
+ /* Only one chipset here */
+ if (!pScreenInfo->chipset)
+ pScreenInfo->chipset = (char *)renditionChipsets[0].name;
+
+ return TRUE; /* Tada! */
+}
+
+
+/* Save mode on server entry */
+static void
+renditionSave(ScrnInfoPtr pScreenInfo)
+{
+ vgaHWSave(pScreenInfo, &VGAHWPTR(pScreenInfo)->SavedReg, VGA_SR_ALL);
+}
+
+
+/* Restore the mode that was saved on server entry */
+static void
+renditionRestore(ScrnInfoPtr pScreenInfo)
+{
+ vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo);
+
+ vgaHWProtect(pScreenInfo, TRUE);
+ vgaHWRestore(pScreenInfo, &pvgaHW->SavedReg, VGA_SR_ALL);
+ vgaHWProtect(pScreenInfo, FALSE);
+
+ v_setmode(&RENDITIONPTR(pScreenInfo)->board,
+ &RENDITIONPTR(pScreenInfo)->mode);
+}
+
+
+/* Set a graphics mode */
+static Bool
+renditionSetMode(ScrnInfoPtr pScreenInfo, DisplayModePtr pMode)
+{
+ vgaHWPtr pvgaHW=VGAHWPTR(pScreenInfo);
+ struct v_modeinfo_t *modeinfo=&RENDITIONPTR(pScreenInfo)->mode;
+
+#ifdef DEBUG
+ ErrorF("RENDITION: renditionSetMode() called\n");
+#endif
+
+ /* construct a modeinfo for the v_setmode function */
+ modeinfo->clock=pMode->SynthClock;
+ modeinfo->hdisplay=pMode->HDisplay;
+ modeinfo->hsyncstart=pMode->HSyncStart;
+ modeinfo->hsyncend=pMode->HSyncEnd;
+ modeinfo->htotal=pMode->HTotal;
+ modeinfo->hskew=pMode->HSkew;
+ modeinfo->vdisplay=pMode->VDisplay;
+ modeinfo->vsyncstart=pMode->VSyncStart;
+ modeinfo->vsyncend=pMode->VSyncEnd;
+ modeinfo->vtotal=pMode->VTotal;
+
+ modeinfo->screenwidth=pMode->HDisplay;
+ modeinfo->virtualwidth=pScreenInfo->virtualX&0xfff8;
+ modeinfo->screenheight=pMode->VDisplay;
+ modeinfo->virtualheight=pScreenInfo->virtualY&0xfff8;
+
+ if ((pMode->Flags&(V_PHSYNC|V_NHSYNC))
+ && (pMode->Flags&(V_PVSYNC|V_NVSYNC))) {
+ modeinfo->hsynchi=((pMode->Flags&V_PHSYNC) == V_PHSYNC);
+ modeinfo->vsynchi=((pMode->Flags&V_PVSYNC) == V_PVSYNC);
+ }
+ else {
+ int VDisplay=pMode->VDisplay;
+ if (pMode->Flags & V_DBLSCAN)
+ VDisplay*=2;
+ if (VDisplay < 400) {
+ /* +hsync -vsync */
+ modeinfo->hsynchi=1;
+ modeinfo->vsynchi=0;
+ }
+ else if (VDisplay < 480) {
+ /* -hsync +vsync */
+ modeinfo->hsynchi=0;
+ modeinfo->vsynchi=1;
+ }
+ else if (VDisplay < 768) {
+ /* -hsync -vsync */
+ modeinfo->hsynchi=0;
+ modeinfo->vsynchi=0;
+ }
+ else {
+ /* +hsync +vsync */
+ modeinfo->hsynchi=1;
+ modeinfo->vsynchi=1;
+ }
+ }
+
+ switch (pScreenInfo->bitsPerPixel) {
+ case 8:
+ modeinfo->bitsperpixel=8;
+ modeinfo->pixelformat=V_PIXFMT_8I;
+ break;
+ case 16:
+ modeinfo->bitsperpixel=16;
+#if 0
+ if (vga256InfoRec.weight.green == 5)
+ /* on a V1000, this looks too 'red/magenta' <ml> */
+ modeinfo->pixelformat=V_PIXFMT_1555;
+ else
+#endif
+ modeinfo->pixelformat=V_PIXFMT_565;
+ break;
+ case 32:
+ modeinfo->bitsperpixel=32;
+ modeinfo->pixelformat=V_PIXFMT_8888;
+ break;
+ }
+ modeinfo->fifosize=128;
+
+ v_setmode(&RENDITIONPTR(pScreenInfo)->board,
+ &RENDITIONPTR(pScreenInfo)->mode);
+
+ return TRUE;
+}
+
+
+static Bool
+renditionEnterGraphics(ScreenPtr pScreen, ScrnInfoPtr pScreenInfo)
+{
+ vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo);
+
+#ifdef DEBUG
+ ErrorF("RENDITION: renditionEnterGraphics() called\n");
+#endif
+
+ /* Map VGA aperture */
+ if (!vgaHWMapMem(pScreenInfo))
+ return FALSE;
+
+ /* Unlock VGA registers */
+ vgaHWUnlock(pvgaHW);
+
+ /* Save the current state and setup the current mode */
+ renditionSave(pScreenInfo);
+ if (!renditionSetMode(pScreenInfo, pScreenInfo->currentMode))
+ return FALSE;
+
+ /* Possibly blank the screen */
+ if (pScreen)
+ renditionSaveScreen(pScreen, FALSE);
+
+ (*pScreenInfo->AdjustFrame)(pScreenInfo->scrnIndex,
+ pScreenInfo->frameX0, pScreenInfo->frameY0, 0);
+
+ return TRUE;
+}
+
+
+static void
+renditionLeaveGraphics(ScrnInfoPtr pScreenInfo)
+{
+#ifdef DEBUG
+ ErrorF("RENDITION: renditionLeaveGraphics() called\n");
+#endif
+
+ renditionRestore(pScreenInfo);
+ vgaHWLock(VGAHWPTR(pScreenInfo));
+ vgaHWUnmapMem(pScreenInfo);
+
+ v_textmode(&RENDITIONPTR(pScreenInfo)->board);
+}
+
+
+/* Unravel the screen */
+static Bool
+renditionCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex];
+ renditionPtr prenditionPriv=renditionGetRec(pScreenInfo);
+ Bool Closed = TRUE;
+
+#ifdef DEBUG
+ ErrorF("RENDITION: renditionCloseScreen() called\n");
+#endif
+
+ if (prenditionPriv && (pScreen->CloseScreen = prenditionPriv->CloseScreen))
+ {
+ prenditionPriv->CloseScreen = NULL;
+ Closed = (*pScreen->CloseScreen)(scrnIndex, pScreen);
+ }
+
+ renditionLeaveGraphics(pScreenInfo);
+ pScreenInfo->vtSema = FALSE;
+
+ return Closed;
+}
+
+
+#ifdef DPMSExtension
+static void
+renditionDPMSSet(ScrnInfoPtr pScreen, int mode, int flags)
+{
+#ifdef DEBUG
+ ErrorF("RENDITION: renditionDPMSSet() called\n");
+#endif
+
+ vgaHWDPMSSet(pScreen, mode, flags);
+}
+#endif
+
+
+static Bool
+renditionScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex];
+
+ renditionPtr prenditionPriv;
+ Bool Inited = FALSE;
+ unsigned char *FBBase=RENDITIONPTR(pScreenInfo)->board.vmem_base;
+ VisualPtr visual;
+
+#ifdef DEBUG
+ ErrorF("RENDITION: renditionScreenInit() called\n");
+#endif
+
+ /* Get driver private */
+ prenditionPriv=renditionGetRec(pScreenInfo);
+ if (NULL == prenditionPriv) /* xcalloc failed */
+ return FALSE;
+
+ /* Initialise graphics mode */
+ if (!renditionEnterGraphics(pScreen, pScreenInfo))
+ return FALSE;
+
+ /* Get vgahw private
+ pvgaHW = VGAHWPTR(pScreenInfo);
+ */
+
+ miClearVisualTypes();
+
+ if (!miSetVisualTypes(pScreenInfo->depth,
+ miGetDefaultVisualMask(pScreenInfo->depth),
+ pScreenInfo->rgbBits, pScreenInfo->defaultVisual))
+ return FALSE;
+
+ /* initialise the framebuffer */
+ switch (pScreenInfo->bitsPerPixel)
+ {
+ case 8:
+ Inited = cfbScreenInit(pScreen, FBBase,
+ pScreenInfo->virtualX, pScreenInfo->virtualY,
+ pScreenInfo->xDpi, pScreenInfo->yDpi,
+ pScreenInfo->displayWidth);
+ break;
+ case 16:
+ Inited = cfb16ScreenInit(pScreen, FBBase,
+ pScreenInfo->virtualX, pScreenInfo->virtualY,
+ pScreenInfo->xDpi, pScreenInfo->yDpi,
+ pScreenInfo->displayWidth);
+ break;
+ case 32:
+ Inited = cfb32ScreenInit(pScreen, FBBase,
+ pScreenInfo->virtualX, pScreenInfo->virtualY,
+ pScreenInfo->xDpi, pScreenInfo->yDpi,
+ pScreenInfo->displayWidth);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in renditionScreenInit\n",
+ pScreenInfo->bitsPerPixel);
+ break;
+ }
+
+ if (!Inited)
+ return FALSE;
+
+ miInitializeBackingStore(pScreen);
+
+ if (pScreenInfo->bitsPerPixel > 8) {
+ /* Fixup RGB ordering */
+ visual=pScreen->visuals+pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if (0 && (visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScreenInfo->offset.red;
+ visual->offsetGreen = pScreenInfo->offset.green;
+ visual->offsetBlue = pScreenInfo->offset.blue;
+ visual->redMask = pScreenInfo->mask.red;
+ visual->greenMask = pScreenInfo->mask.green;
+ visual->blueMask = pScreenInfo->mask.blue;
+ }
+ else {
+ ErrorF("Changing masks!!!\n");
+ if (pScreenInfo->bitsPerPixel == 32) {
+ visual->offsetRed=16;
+ visual->offsetGreen=8;
+ visual->offsetBlue=0;
+ visual->redMask=0xff0000;
+ visual->greenMask=0xff00;
+ visual->blueMask=0xff;
+ } else {
+ visual->offsetRed=11;
+ visual->offsetGreen=5;
+ visual->offsetBlue=0;
+ visual->redMask=0xf800;
+ visual->greenMask=0x7e0;
+ visual->blueMask=0x1f;
+ }
+/*
+ visual->offsetRed=0;
+ visual->offsetGreen=5;
+ visual->offsetBlue=11;
+ visual->redMask=0x1f;
+ visual->greenMask=0x7e0;
+ visual->blueMask=0xf800;
+*/
+ }
+ }
+ }
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ /* Initialise cursor */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ /* Setup default colourmap */
+ Inited = miCreateDefColormap(pScreen);
+
+ /* Try the new code based on the new colormap layer */
+ if (pScreenInfo->depth > 1)
+ vgaHWHandleColormaps(pScreen);
+
+#ifdef DPMSExtension
+ xf86DPMSInit(pScreen, renditionDPMSSet, 0);
+#endif
+
+ /* Wrap the screen's CloseScreen vector and set its SaveScreen vector */
+ prenditionPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = renditionCloseScreen;
+ pScreen->SaveScreen = renditionSaveScreen;
+
+ if (!Inited)
+ renditionCloseScreen(scrnIndex, pScreen);
+
+ if (serverGeneration == 1)
+ xf86ShowUnusedOptions(pScreenInfo->scrnIndex, pScreenInfo->options);
+
+ return Inited;
+}
+/*
+
+ ErrorF ("XX Pee: **\n");
+ LoaderCheckUnresolved(LD_RESOLV_IFDONE);
+ return FALSE;
+*/
+
+static Bool
+renditionSwitchMode(int scrnIndex, DisplayModePtr pMode, int flags)
+{
+#ifdef DEBUG
+ ErrorF("RENDITION: renditionSwitchMode() called\n");
+#endif
+ return renditionSetMode(xf86Screens[scrnIndex], pMode);
+}
+
+
+static void
+renditionAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScreenInfo=xf86Screens[scrnIndex];
+ int offset, virtualwidth, bitsPerPixel;
+
+#ifdef DEBUG
+ ErrorF("RENDITION: renditionAdjustFrame() called\n");
+#endif
+
+ bitsPerPixel=pScreenInfo->bitsPerPixel;
+ virtualwidth=RENDITIONPTR(pScreenInfo)->mode.virtualwidth;
+ offset=(y*virtualwidth+x)*(bitsPerPixel>>3);
+
+ v_setframebase(&RENDITIONPTR(pScreenInfo)->board, offset+FBOFFSET);
+}
+
+
+static Bool
+renditionEnterVT(int scrnIndex, int flags)
+{
+#ifdef DEBUG
+ ErrorF("RENDITION: renditionEnterVT() called\n");
+#endif
+ return renditionEnterGraphics(NULL, xf86Screens[scrnIndex]);
+}
+
+
+static void
+renditionLeaveVT(int scrnIndex, int flags)
+{
+#ifdef DEBUG
+ ErrorF("RENDITION: renditionLeaveVT() called\n");
+#endif
+ renditionLeaveGraphics(xf86Screens[scrnIndex]);
+}
+
+
+static void
+renditionFreeScreen(int scrnIndex, int flags)
+{
+ renditionFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+static ModeStatus
+renditionValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags)
+{
+ if (pMode->Flags & V_INTERLACE)
+ return MODE_NO_INTERLACE;
+
+ return MODE_OK;
+}
+
+static Bool renditionMapMem(ScrnInfoPtr pScreenInfo)
+{
+ Bool WriteCombine;
+ int mapOption;
+
+#ifdef DEBUG0
+ ErrorF("Mapping ...\n");
+ ErrorF("%d %d %d %x %d\n", pScreenInfo->scrnIndex, VIDMEM_FRAMEBUFFER,
+ RENDITIONPTR(pScreenInfo)->pcitag,
+ RENDITIONPTR(pScreenInfo)->board.mem_base, pScreenInfo->videoRam);
+#endif
+
+ if (RENDITIONPTR(pScreenInfo)->board.chip==V1000_DEVICE){
+ /* Some V1000 boards are known to have problems with Write-Combining */
+ WriteCombine = 0;
+ }
+ else{
+ /* Activate Write_Combine if possible */
+ WriteCombine = 1;
+ }
+ /* Override on users request */
+ WriteCombine=xf86ReturnOptValBool(renditionOptions, OPTION_FBWC, WriteCombine);
+ if (WriteCombine)
+ mapOption = VIDMEM_FRAMEBUFFER;
+ else
+ mapOption = VIDMEM_MMIO;
+
+ xf86MarkOptionUsedByName(renditionOptions,"FramebufferWC");
+
+ RENDITIONPTR(pScreenInfo)->board.vmem_base=
+ xf86MapPciMem(pScreenInfo->scrnIndex, mapOption,
+ RENDITIONPTR(pScreenInfo)->pcitag,
+ (unsigned long)RENDITIONPTR(pScreenInfo)->board.mem_base,
+ pScreenInfo->videoRam);
+ return TRUE;
+
+#ifdef DEBUG0
+ ErrorF("Done\n");
+#endif
+}
+
+static Bool renditionUnmapMem(ScrnInfoPtr pScreenInfo)
+{
+#ifdef DEBUG0
+ ErrorF("Unmapping ...\n");
+#endif
+ xf86UnMapVidMem(pScreenInfo->scrnIndex,
+ RENDITIONPTR(pScreenInfo)->board.mem_base, pScreenInfo->videoRam);
+ return TRUE;
+#ifdef DEBUG0
+ ErrorF("Done\n");
+#endif
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/v1kregs.h b/xc/programs/Xserver/hw/xfree86/drivers/rendition/v1kregs.h
new file mode 100644
index 000000000..733899390
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/v1kregs.h
@@ -0,0 +1,217 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/v1kregs.h,v 1.2 1999/04/17 07:06:34 dawes Exp $ */
+
+#ifndef _V1KREGS_H_
+#define _V1KREGS_H_
+
+
+#define FIFO_SIZE 0x1f
+
+/* IO register offsets. */
+#define FIFO_SWAP_NO 0x00 /* FIFO. No byte swap. */
+#define FIFO_SWAP_END 0x04 /* FIFO. Swap bytes 3<>0, 2<>1. */
+#define FIFO_SWAP_INHW 0x08 /* FIFO. Swap bytes 3<>2, 1<>0. */
+#define FIFO_SWAP_HW 0x0c /* FIFO. Swap half-words. */
+#define FIFOINFREE 0x40 /* Input FIFO free entry count. */
+#define FIFOOUTVALID 0x41 /* Output FIFO valid entry count. */
+#define COMM 0x42 /* dual 4 bit communications ports */
+#define MEMENDIAN 0x43 /* set byte swapping on PCI mem accesses */
+#define INTR 0x44 /* which interrupts occurred */
+#define INTREN 0x46 /* enable different interrupts */
+#define DEBUGREG 0x48 /* soft resets, RISC hold/single step */
+#define LOWWATERMARK 0x49 /* Input FIFO low water mark for interrupt */
+#define PCITEST 0x4C /* PCI test */
+#define DMACMDPTR 0x50 /* DMA command list pointer */
+#define DMA_ADDRESS 0x54 /* DMA data address */
+#define DMA_COUNT 0x58 /* DMA remaining transfer count */
+#define STATEINDEX 0x60 /* state index info */
+#define STATEDATA 0x64 /* state data info */
+#define SCRATCH 0x70 /* 16-bit BIOS scratch space */
+#define MODEREG 0x72 /* Mode -- to differentiate from old MODE */
+#define MODE_ MODEREG
+#define MODE MODEREG
+#define BANKSELECT 0x74 /* Local memory to A0000 mapping */
+#define BANKSELECT_PHYSADDR ((unsigned long)(0xA0000))
+#define CRTCTEST 0x80 /* CRTC test register */
+#define CRTCCTL 0x84 /* CRTC mode */
+#define CRTCHORZ 0x88 /* CRTC horizontal timing */
+#define CRTCVERT 0x8c /* CRTC vertical timing */
+#define FRAMEBASEB 0x90 /* Stereoscopic frame base b address */
+#define FRAMEBASEA 0x94 /* Frame base A address */
+#define CRTCOFFSET 0x98 /* CRTC StrideOffset */
+#define CRTCSTATUS 0x9c /* CRTC video scan position */
+#define DRAMCTL 0xa0 /* DRAM timing */
+#define PALETTE 0xb0 /* Access to DAC */
+#define RAMDACBASEADDR 0xb0 /* Access to DAC */
+#define DEVICE0 0xc0 /* external device 0 (PLL) */
+#define DEVICE1 0xd0 /* external device 1 */
+
+/* IO register flag bits */
+/* _MASK defined for multi-bit values */
+/* _ADDR defined for registers accessible from RISC */
+
+/* COMM */
+#define SYSSTATUS_MASK 0x0f /* host->RISC comm */
+#define SYSSTATUS_SHIFT 0
+#define RISCSTATUS_MASK 0xf0 /* RISC->host comm r/o */
+#define RISCSTATUS_SHIFT 4
+
+/* MEMENDIAN */
+#define MEMENDIAN_NO 0 /* No byte swap. */
+#define MEMENDIAN_END 1 /* Swap bytes 3<>0, 2<>1. */
+#define MEMENDIAN_INHW 2 /* Swap bytes 3<>2, 1<>0. */
+#define MEMENDIAN_HW 3 /* Swap half-words. */
+#define MEMENDIAN_MASK 3
+#define MEMENDIAN_SHIFT 0
+
+#define DMABUSY 0x80 /* DMA busy r/o */
+#define DMACMDPTR_DMABUSY 0x1 /* corresponding bit in other reg */
+
+/* INTR */
+#define VERTINTR 0x01 /* vert retrace */
+#define FIFOLOWINTR 0x02 /* free entries rose above low water */
+#define RISCINTR 0x04 /* RISC firmware interrupt */
+#define HALTINTR 0x08 /* RISC halted */
+#define FIFOERRORINTR 0x10 /* FIFO under/over flow */
+#define DMAERRORINTR 0x20 /* PCI error during DMA */
+#define DMAINTR 0x40 /* DMA done interrupt */
+#define XINTR 0x80 /* external device pass thru intr */
+
+/* INTREN */
+#define VERTINTREN 0x01 /* vert retrace */
+#define FIFOLOWINTREN 0x02 /* free entries rose above low water */
+#define RISCINTREN 0x04 /* RISC firmware interrupt */
+#define HALTINTREN 0x08 /* RISC halted */
+#define FIFOERRORINTREN 0x10 /* FIFO under/over flow */
+#define DMAERRORINTREN 0x20 /* PCI error during DMA */
+#define DMAINTREN 0x40 /* DMA done interrupt */
+#define XINTREN 0x80 /* external device pass thru intr */
+
+/* DEBUG */
+#define SOFTRESET 0x01 /* soft reset chip */
+#define HOLDRISC 0x02 /* stop RISC when set */
+#define STEPRISC 0x04 /* single step RISC */
+#define DIRECTSCLK 0x08 /* disable internal divide by 2 for sys clk */
+#define SOFTVGARESET 0x10 /* assert VGA reset */
+#define SOFTXRESET 0x20 /* assert XReset output to ext devices */
+
+/* MODE_ register */
+#define VESA_MODE 0x01 /* enable 0xA0000 in native mode */
+#define VGA_MODE 0x02 /* VGA mode if set else native mode */
+#define VGA_32 0x04 /* enable VGA 32 bit accesses */
+#define DMA_EN 0x08 /* enable DMA accesses */
+
+#define NATIVE_MODE 0 /* not VESA and not VGA */
+
+/* DRAM register */
+#define DRAMCTL_ADDR 0xffe00500
+#define DRAMCTL_SLOWPRECHARGE 0x140010
+#define DRAMCTL_NORMAL 0x140000
+
+/* CRTC registers */
+#define CRTCTEST_ADDR 0xffe00400
+#define CRTCCTL_ADDR 0xffe00420
+#define CRTCHORZ_ADDR 0xffe00440
+#define CRTCVERT_ADDR 0xffe00460
+#define FRAMEBASEB_ADDR 0xffe00480
+#define FRAMEBASEA_ADDR 0xffe004a0
+#define CRTCOFFSET_ADDR 0xffe004c0
+#define CRTCSTATUS_ADDR 0xffe004e0
+
+#define CRTCTEST_VIDEOLATENCY_MASK 0x1F
+#define CRTCTEST_NOTVBLANK 0x10000
+#define CRTCTEST_VBLANK 0x40000
+
+#define CRTCCTL_SCRNFMT_MASK 0xF
+#define CRTCCTL_VIDEOFIFOSIZE128 0x10
+#define CRTCCTL_ENABLEDDC 0x20
+#define CRTCCTL_DDCOUTPUT 0x40
+#define CRTCCTL_DDCDATA 0x80
+#define CRTCCTL_VSYNCHI 0x100
+#define CRTCCTL_HSYNCHI 0x200
+#define CRTCCTL_VSYNCENABLE 0x400
+#define CRTCCTL_HSYNCENABLE 0x800
+#define CRTCCTL_VIDEOENABLE 0x1000
+#define CRTCCTL_STEREOSCOPIC 0x2000
+#define CRTCCTL_FRAMEDISPLAYED 0x4000
+#define CRTCCTL_FRAMEBUFFERBGR 0x8000
+#define CRTCCTL_EVENFRAME 0x10000
+#define CRTCCTL_LINEDOUBLE 0x20000
+#define CRTCCTL_FRAMESWITCHED 0x40000
+
+#define CRTCHORZ_ACTIVE_MASK 0xFF
+#define CRTCHORZ_ACTIVE_SHIFT 0
+#define CRTCHORZ_BACKPORCH_MASK 0x7E00
+#define CRTCHORZ_BACKPORCH_SHIFT 11
+#define CRTCHORZ_SYNC_MASK 0x1F0000L
+#define CRTCHORZ_SYNC_SHIFT 16
+#define CRTCHORZ_FRONTPORCH_MASK 0xE00000L
+#define CRTCHORZ_FRONTPORCH_SHIFT 20
+
+#define CRTCVERT_ACTIVE_MASK 0x7FF
+#define CRTCVERT_BACKPORCH_MASK 0x1F800
+#define CRTCVERT_SYNC_MASK 0xE0000
+#define CRTCVERT_FRONTPORCH_MASK 0x03F00000
+
+#define CRTCOFFSET_MASK 0xFFFF
+
+#define CRTCSTATUS_HORZCLOCKS_MASK 0xFF
+#define CRTCSTATUS_HORZ_MASK 0x600
+#define CRTCSTATUS_HORZ_FPORCH 0x200
+#define CRTCSTATUS_HORZ_SYNC 0x600
+#define CRTCSTATUS_HORZ_BPORCH 0x400
+#define CRTCSTATUS_HORZ_ACTIVE 0x000
+#define CRTCSTATUS_SCANLINESLEFT_MASK 0x003FF800
+#define CRTCSTATUS_VERT_MASK 0xC00000
+#define CRTCSTATUS_VERT_FPORCH 0x400000
+#define CRTCSTATUS_VERT_SYNC 0xC00000
+#define CRTCSTATUS_VERT_BPORCH 0x800000
+#define CRTCSTATUS_VERT_ACTIVE 0x000000
+
+/* RAMDAC registers - avail through I/O space */
+
+#define DACRAMWRITEADR 0xb0
+#define DACRAMDATA 0xb1
+#define DACPIXELMSK 0xb2
+#define DACRAMREADADR 0xb3
+#define DACOVSWRITEADR 0xb4
+#define DACOVSDATA 0xb5
+#define DACCOMMAND0 0xb6
+#define DACOVSREADADR 0xb7
+#define DACCOMMAND1 0xb8
+#define DACCOMMAND2 0xb9
+#define DACSTATUS 0xba
+#define DACCOMMAND3 0xba /* accessed via unlocking/indexing */
+#define DACCURSORDATA 0xbb
+#define DACCURSORXLOW 0xbc
+#define DACCURSORXHIGH 0xbd
+#define DACCURSORYLOW 0xbe
+#define DACCURSORYHIGH 0xbf
+
+/* values for DACCOMMAND3 */
+#define DACCOMMAND3_INIT 0x00
+#define DAC_CLK_DOUBLER 0x8
+
+#define PLLDEV DEVICE0
+
+/* Some state indices */
+#define STATEINDEX_IR 128
+#define STATEINDEX_PC 129
+#define STATEINDEX_S1 130
+
+/* PCI configuration registers. */
+#define CONFIGIOREG 0xE0000014
+#define CONFIGENABLE 0xE0000004
+#ifdef USEROM
+#define CONFIGROMREG 0xE0000030
+#endif
+
+/* Cache parameters. */
+#define ICACHESIZE 2048 /* I cache size. */
+#define ICACHELINESIZE 32 /* I cache line size. */
+#define ICACHE_ONOFF_MASK (((vu32)1<<17)|(1<<3))
+#define ICACHE_ON ((0<<17)|(0<<3))
+#define ICACHE_OFF (((vu32)1<<17)|(1<<3))
+
+
+
+#endif /* _V1KREGS_H_ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/v1krisc.c b/xc/programs/Xserver/hw/xfree86/drivers/rendition/v1krisc.c
new file mode 100644
index 000000000..e3bafe881
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/v1krisc.c
@@ -0,0 +1,504 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/v1krisc.c,v 1.2 1999/04/17 07:06:34 dawes Exp $ */
+/*
+ *
+ */
+
+/*
+ * includes
+ */
+
+#include "v1krisc.h"
+#include "vos.h"
+
+
+
+/*
+ * defines
+ */
+
+/* RISC registers */
+#define RISC_FLAG 37 /* RISC flags register */
+#define RISC_SP 252 /* RISC stack pointer/scratch register */
+#define RISC_IRA 253 /* RISC register */
+#define RISC_RA 254 /* RISC program link/scratch register */
+#define RISC_FP 255 /* RISC frame pointer/scratch register */
+
+/* RISC opcodes used */
+#define NOP_INSTR 0x00000000 /* really add immed with D=zero */
+#define ADDI_OP 0x00
+#define SPRI_OP 0x4f
+#define ADD_OP 0x10
+#define ANDN_OP 0x12
+#define OR_OP 0x15
+#define ADDIFI_OP 0x40
+#define ADDSL8_OP 0x4b
+#define LB_OP 0x70
+#define LH_OP 0x71
+#define LW_OP 0x72
+#define LI_OP 0x76
+#define LUI_OP 0x77
+#define SB_OP 0x78
+#define SH_OP 0x79
+#define SW_OP 0x7a
+#define JMP_OP 0x6c
+
+/* defines for instruction composition */
+#define INT_INSTR(op, d, s2, s1) \
+ (((vu32)(op)<<24) | ((vu32)(d)<<16) | ((vu32)(s2)<<8) | ((vu32)(s1)&0xff))
+#define STR_INSTR(op, off8, s2, s1) \
+ (((vu32)(op)<<24) | (((vu32)(off8)&0xff)<<16) | ((vu32)(s2)<<8) | ((vu32)(s1)))
+#define LD_INSTR(op, d, off8, s1) \
+ (((vu32)(op)<<24) | ((vu32)(d)<<16) | (((vu32)(off8)&0xff)<<8) | ((vu32)(s1)))
+#define LI_INSTR(op, d, immed16) \
+ (((vu32)(op)<<24) | ((vu32)(d)<<16) | ((vu32)(immed16)&0xffff))
+#define BR_INSTR(op, off16, s1) \
+ (((vu32)(op)<<24) | (((vu32)(off16)&0xffff)<<8) | ((vu32)(s1)))
+#define JMP_INSTR(op, addr24) \
+ (((vu32)(op)<<24) | ((vu32)(addr24)))
+
+/* some masks */
+#define TYPEINSTR 0xf0000000
+#define TYPEBRANCH 0x60000000
+#define HALTBIT 0x00000008
+
+#define VBIOS_DTNR 0x2000
+
+#define READ_BYTE 0
+#define READ_SHORT 1
+#define READ_WORD 2
+
+#define WRITE_BYTE 0
+#define WRITE_SHORT 1
+#define WRITE_WORD 2
+
+#define V_MAX_POLLS 100
+
+
+
+/*
+ * local function prototypes
+ */
+
+static void v_iopoll(vu16 port, vu32 data, vu32 mask);
+static void v_iopoll8(vu16 port, vu8 data, vu8 mask);
+
+static vu32 readRF(vu16 io_base, vu8 index);
+static void writeRF(vu16 io_base, vu8 index, vu32 data);
+
+static vu32 risc_readmem(vu16 io_base, vu32 addr, vu8 read_type);
+static void risc_writemem(vu16 io_base, vu32 addr, vu32 data, vu8 write_type);
+
+static void risc_step(vu16 io_base, vu32 count);
+static void risc_forcestep(vu16 io_base, vu32 instruction);
+static void risc_continue(vu16 io_base);
+
+
+
+/*
+ * functions
+ */
+
+/*
+ * void v1k_start(struct v_board_t *board, vu32 pc)
+ *
+ * Start the RISC with its PC set to |pc|.
+ */
+void v1k_start(struct v_board_t *board, vu32 pc)
+{
+ vu16 io_base=board->io_base;
+
+ v1k_stop(board);
+ risc_forcestep(io_base, NOP_INSTR);
+ risc_forcestep(io_base, NOP_INSTR);
+ risc_forcestep(io_base, NOP_INSTR);
+ risc_forcestep(io_base, JMP_INSTR(JMP_OP, pc>>2));
+ risc_forcestep(io_base, NOP_INSTR);
+
+ v1k_continue(board);
+}
+
+
+
+/*
+ * void v1k_continue(struct v_board_t *board)
+ *
+ * Let the RISC do its work.
+ */
+void v1k_continue(struct v_board_t *board)
+{
+ risc_continue(board->io_base);
+}
+
+
+
+/*
+ * void v1k_stop(struct v_board_t *board)
+ *
+ * Stop the RISC.
+ */
+void v1k_stop(struct v_board_t *board)
+{
+ vu8 debugreg, statusreg;
+ vu16 io_base=board->io_base;
+ vu16 STATUS = 0x4A; /* v2x00 io register offset */
+
+ debugreg=v_in8(io_base+DEBUGREG);
+
+ if (board->chip == V2000_DEVICE)
+ do {
+ statusreg = v_in8((vu16)(io_base+STATUS));
+ if ((statusreg & 0x8C) == 0x8C)
+ break;
+ } while (1);
+
+ v_out8(io_base+DEBUGREG, debugreg|HOLDRISC);
+
+ if (board->chip == V2000_DEVICE)
+ do {
+ statusreg = v_in8((vu16)(io_base+STATUS));
+ if (statusreg & HOLDRISC) break;
+ } while (1);
+ else {
+ v_iopoll(io_base+STATEDATA, 0, 0); /* short pause */
+ v_iopoll(io_base+STATEDATA, 0, 0); /* short pause */
+ v_iopoll(io_base+STATEDATA, 0, 0); /* short pause */
+ }
+}
+
+
+
+/*
+ * void v1k_flushicache(struct v_board_t *board)
+ *
+ * Returns with Icache on, also flushes Pixel engine line buffers
+ * in the Dcache.
+ */
+void v1k_flushicache(struct v_board_t *board)
+{
+ vu32 c, p1, p2;
+ vu16 io_base=board->io_base;
+
+ /* first flush store accumulation buffers so data is all in memory */
+ p1=risc_readmem(io_base, 0, READ_WORD);
+ p2=risc_readmem(io_base, 8, READ_WORD);
+ risc_writemem(io_base, 0, p1, WRITE_WORD);
+ risc_writemem(io_base, 8, p2, WRITE_WORD);
+ (void)risc_readmem(io_base, 0, READ_WORD);
+ (void)risc_readmem(io_base, 8, READ_WORD);
+
+ /* now force a spr Sync,zero to cause the pixel engine line buffers
+ * to be flushed. */
+ risc_forcestep(io_base, INT_INSTR(SPRI_OP, 0, 0, 31)); /* spri Sync,zero */
+ risc_forcestep(io_base, NOP_INSTR);
+ risc_forcestep(io_base, NOP_INSTR);
+ risc_forcestep(io_base, NOP_INSTR);
+
+
+ writeRF(io_base, RISC_RA, ICACHE_ONOFF_MASK); /* load mask */
+ /* set bits */
+ risc_forcestep(io_base, INT_INSTR(OR_OP, RISC_FLAG, RISC_FLAG, RISC_RA));
+ risc_forcestep(io_base, NOP_INSTR); /* clear hazard */
+ risc_forcestep(io_base, NOP_INSTR);
+ risc_forcestep(io_base, NOP_INSTR);
+
+ /* flush ICache */
+ for (c=0; c<ICACHESIZE*2; c+=ICACHELINESIZE)
+ risc_forcestep(io_base, JMP_INSTR(JMP_OP, c>>2)); /* jmp NextCacheLine. */
+
+ writeRF(io_base, RISC_RA, ICACHE_ONOFF_MASK); /* load mask */
+ /* clear bits */
+ risc_forcestep(io_base, INT_INSTR(ANDN_OP, RISC_FLAG, RISC_FLAG, RISC_RA));
+ risc_forcestep(io_base, NOP_INSTR); /* jump back to PC=0 */
+ risc_forcestep(io_base, JMP_INSTR(JMP_OP, 0));
+ risc_forcestep(io_base, NOP_INSTR);
+}
+
+
+
+/*
+ * void v1k_softreset(struct v_board_t *board)
+ *
+ * Soft Reset RISC.
+ */
+void v1k_softreset(struct v_board_t *board)
+{
+ vu16 io_base=board->io_base;
+
+ v_out8(io_base+DEBUGREG, SOFTRESET|HOLDRISC);
+ v_out8(io_base+STATEINDEX, STATEINDEX_PC);
+ v_iopoll(io_base+STATEDATA, 0, 0xffffffff);
+ v_iopoll(io_base+STATEDATA, 0, 0xffffffff);
+ v_iopoll(io_base+STATEDATA, 0, 0xffffffff);
+
+ v_out8(io_base+DEBUGREG, HOLDRISC);
+ v_iopoll(io_base+STATEDATA, 0, 0);
+ v_iopoll(io_base+STATEDATA, 0, 0);
+ v_iopoll(io_base+STATEDATA, 0, 0);
+
+ /* turn icache on */
+ risc_forcestep(io_base, LI_INSTR(LI_OP, RISC_RA, ICACHE_ONOFF_MASK&0xffff));
+ risc_forcestep(io_base, INT_INSTR(ADDIFI_OP, RISC_FLAG, RISC_RA,
+ ICACHE_ONOFF_MASK>>16));
+ /* clear any interrupts */
+ v_out8(io_base+INTR, 0xff);
+ /* byte swap mode=word */
+ v_out8(io_base+MEMENDIAN, MEMENDIAN_NO);
+}
+
+
+
+/*
+void
+v1k_getriscprocs(v_board_desc *boardDesc)
+{
+ boardDesc->risc_procs.risc_softreset = v1krisc_softreset;
+ boardDesc->risc_procs.risc_flushicache = v1krisc_flushicache;
+ boardDesc->risc_procs.risc_start = v1krisc_start;
+ boardDesc->risc_procs.risc_stop = v1krisc_stop;
+ boardDesc->risc_procs.risc_continue = v1krisc_continue;
+ return;
+}
+*/
+
+
+
+/*
+ * local functions
+ */
+
+/*
+ * static void v_iopoll(vu16 port, vu32 data, vu32 mask)
+ *
+ * Loop on IO read until expected data is read or V_MAX_POLLS is reached.
+ */
+static void v_iopoll(vu16 port, vu32 data, vu32 mask)
+{
+ vu32 c, d;
+
+ c=0;
+ do {
+ c++;
+ if (((d=v_in32(port))&mask) == (data&mask))
+ break;
+ } while (c <= V_MAX_POLLS);
+}
+
+
+
+/*
+ * static void v_iopoll8(vu16 port, vu8 data, vu8 mask)
+ *
+ * Loop on IO read until expected data is read or V_MAX_POLLS is reached.
+ */
+static void v_iopoll8(vu16 port, vu8 data, vu8 mask)
+{
+ vu32 c;
+ vu8 d;
+
+ c=0;
+ do {
+ c++;
+ if (((d=v_in8(port))&mask) == (data&mask))
+ break;
+ } while (c <= V_MAX_POLLS);
+}
+
+
+
+/*
+ * static vu32 readRF(vu16 io_base, vu8 index)
+ *
+ * Reads data from register file.
+ */
+static vu32 readRF(vu16 io_base, vu8 index)
+{
+ vu32 data, instr;
+ vu8 debug, stateindex;
+
+ debug=v_in8(io_base+DEBUGREG);
+ stateindex=v_in8(io_base+STATEINDEX);
+
+ /* force RISC instruction: add zero,zero,index
+ * S1 reg address = reg index to read
+ * write to the DEC_IR, but no need to step it! */
+ v_out8(io_base+DEBUGREG, debug|HOLDRISC);
+
+ instr=INT_INSTR(ADD_OP, 0, 0, index);
+ v_out32(io_base+STATEDATA, instr);
+
+ /* wait for instruction to get to RISC IR. */
+ v_out8(io_base+STATEINDEX, STATEINDEX_IR); /* point at DEC_IR */
+ v_iopoll(io_base+STATEDATA, instr, 0xffffffff);
+
+ v_out8(io_base+STATEINDEX, STATEINDEX_S1); /* point at RISCS1 */
+ v_iopoll(io_base+STATEINDEX, 0, 0); /* short pause */
+ data=v_in32(io_base+STATEDATA); /* read RF */
+
+ v_out8(io_base+STATEINDEX, stateindex); /* restore state_index */
+ v_out8(io_base+DEBUGREG, debug); /* restore debug */
+
+ return data;
+}
+
+
+
+/*
+ * static void writeRF(vu16 io_base, vu8 index, vu32 data)
+ *
+ * Set RF register, being careful on how to set regs below 64.
+ */
+static void writeRF(vu16 io_base, vu8 index, vu32 data)
+{
+ vu8 special=0;
+
+ if (index < 64) { /* constants or HW regs */
+ special=index; /* keep track of special register */
+ index=RISC_SP; /* use |sp| as tmp, since it gets restored */
+ }
+
+ if (!(data & 0xff000000)) { /* only 16 or 24 LSBs */
+ /* Set 16 LS bits. */
+ risc_forcestep(io_base, LI_INSTR(LI_OP,index,data&0xffff));
+ if (data & 0x00ff0000) /* need all 24 LS bits? */
+ risc_forcestep(io_base, INT_INSTR(ADDIFI_OP,index,index,data>>16) );
+ }
+ else { /* else, do all 32 bits */
+ risc_forcestep(io_base, LI_INSTR(LUI_OP, index, data>>16));
+ risc_forcestep(io_base, INT_INSTR(ADDSL8_OP, index, index, (data>>8)&0xff));
+ risc_forcestep(io_base, INT_INSTR(ADDI_OP, index, index, data&0xff));
+ }
+
+ if (special) {
+ /* move data to special register */
+ risc_forcestep(io_base, INT_INSTR(ADD_OP, special, 0, RISC_SP));
+ /* clear hazard */
+ risc_forcestep(io_base, NOP_INSTR);
+ risc_forcestep(io_base, NOP_INSTR);
+ risc_forcestep(io_base, NOP_INSTR);
+ }
+}
+
+
+
+/*
+ * static vu32 risc_readmem(vu16 io_base, vu32 addr, vu8 read_type)
+ *
+ * NOTE: Assumes RISC is in hold mode.
+ */
+static vu32 risc_readmem(vu16 io_base, vu32 addr, vu8 read_type)
+{
+ vu32 data;
+
+ writeRF(io_base, RISC_RA, addr); /* point to memory */
+ if (READ_BYTE == read_type) /* read memory */
+ risc_forcestep(io_base, LD_INSTR(LB_OP, RISC_SP, 0, RISC_RA));
+ else
+ if (READ_SHORT == read_type)
+ risc_forcestep(io_base, LD_INSTR(LH_OP, RISC_SP, 0, RISC_RA));
+ else
+ risc_forcestep(io_base, LD_INSTR(LW_OP, RISC_SP, 0, RISC_RA));
+
+ risc_forcestep(io_base, NOP_INSTR); /* need nop's */
+ risc_forcestep(io_base, NOP_INSTR); /* need nop's */
+ data=readRF(io_base, RISC_SP); /* get data */
+
+ return data;
+}
+
+
+
+/*
+ * static vu32 risc_writemem(vu16 io_base, vu32 addr, vu32 data, vu8 write_type)
+ *
+ * NOTE: Assumes RISC is in hold mode.
+ */
+static void risc_writemem(vu16 io_base, vu32 addr, vu32 data, vu8 write_type)
+{
+ writeRF(io_base, RISC_RA, addr); /* point to memory */
+ writeRF(io_base, RISC_FP, data); /* set data */
+ if (WRITE_BYTE == write_type) /* write memory */
+ risc_forcestep(io_base, STR_INSTR(SB_OP, 0, RISC_FP, RISC_RA));
+ else
+ if (WRITE_SHORT == write_type)
+ risc_forcestep(io_base, STR_INSTR(SH_OP, 0, RISC_FP, RISC_RA));
+ else
+ risc_forcestep(io_base, STR_INSTR(SW_OP, 0, RISC_FP, RISC_RA));
+}
+
+
+/*
+ * static void risc_step(vu16 io_base, vu32 count)
+ *
+ * Single step the RISC. NOTE: Do not force instruction into RISCIR!
+ */
+static void risc_step(vu16 io_base, vu32 count)
+{
+ vu32 c, d;
+ vu8 debugreg;
+
+ /* RISC is already held; just single step it */
+
+ for (c=0; c<count; c++) {
+ debugreg=v_in8(io_base+DEBUGREG);
+ v_out8(io_base+DEBUGREG, debugreg|STEPRISC);
+
+ for (d=0; d<1000; d++)
+ if(0 == (v_in8(io_base+DEBUGREG)&STEPRISC))
+ break;
+
+ if (1000 == d)
+ return; /* stall occurred, we're done */
+ }
+}
+
+
+
+/*
+ * static void risc_forcestep(vu16 io_base, vu32 instruction)
+ *
+ * Single step RISC; force instruction; assumes RISC held.
+ */
+static void risc_forcestep(vu16 io_base, vu32 instruction)
+{
+ vu32 c;
+ vu8 debugreg, stateindex;
+
+
+ debugreg=v_in8(io_base+DEBUGREG);
+ stateindex=v_in8(io_base+STATEINDEX);
+ v_out8(io_base+STATEINDEX, STATEINDEX_IR);
+ v_iopoll8(io_base+STATEINDEX, STATEINDEX_IR, 0xff); /* wait */
+ v_out32(io_base+STATEDATA, instruction); /* load instruction */
+ v_iopoll(io_base+STATEDATA, instruction, 0xffffffff); /* wait */
+ v_out8(io_base+DEBUGREG, debugreg|HOLDRISC|STEPRISC); /* step */
+ v_iopoll(io_base+STATEDATA, 0, 0); /* short pause */
+
+ for (c=0; c<V_MAX_POLLS; c++)
+ if (HOLDRISC == (v_in8(io_base+DEBUGREG) & (HOLDRISC|STEPRISC)))
+ break;
+
+ /* restore */
+ v_out8(io_base+STATEINDEX, stateindex);
+}
+
+
+
+/*
+ * static void risc_continue(vu16 io_base)
+ *
+ * Turn off hold bit.
+ */
+static void risc_continue(vu16 io_base)
+{
+ vu8 debugreg;
+
+ debugreg=v_in8(io_base+DEBUGREG);
+ v_out8(io_base+DEBUGREG, debugreg&(~HOLDRISC));
+ v_iopoll(io_base+STATEDATA, 0, 0); /* short pause */
+}
+
+
+
+/*
+ * end of file v1krisc.c
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/v1krisc.h b/xc/programs/Xserver/hw/xfree86/drivers/rendition/v1krisc.h
new file mode 100644
index 000000000..3b8650aa6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/v1krisc.h
@@ -0,0 +1,34 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/v1krisc.h,v 1.2 1999/04/17 07:06:34 dawes Exp $ */
+/*
+ * file v1krisc.h
+ *
+ * low level function to communicate with the on-board RISC
+ */
+
+#ifndef _V1KRISC_H_
+#define _V1KRISC_H_
+
+
+
+/*
+ * includes
+ */
+
+#include "v1kregs.h"
+#include "vtypes.h"
+
+
+
+/*
+ * function prototypes
+ */
+
+void v1k_start(struct v_board_t *board, vu32 pc);
+void v1k_continue(struct v_board_t *board);
+void v1k_stop(struct v_board_t *board);
+void v1k_flushicache(struct v_board_t *board);
+void v1k_softreset(struct v_board_t *board);
+
+
+
+#endif /* #ifndef _V1KRISC_H_ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/v2kregs.h b/xc/programs/Xserver/hw/xfree86/drivers/rendition/v2kregs.h
new file mode 100644
index 000000000..1dbe5efc1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/v2kregs.h
@@ -0,0 +1,369 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/v2kregs.h,v 1.2 1999/04/17 07:06:34 dawes Exp $ */
+#ifndef _V2KREGS_H
+#define _V2KREGS_H
+
+#include "vtypes.h"
+
+#define FIFO_SIZE 0x1f
+
+/* IO register offsets. */
+#define FIFO_SWAP_NO 0x00 /* FIFO. No byte swap. */
+#define FIFO_SWAP_END 0x04 /* FIFO. Swap bytes 3<>0, 2<>1. */
+#define FIFO_SWAP_INHW 0x08 /* FIFO. Swap bytes 3<>2, 1<>0. */
+#define FIFO_SWAP_HW 0x0c /* FIFO. Swap half-words. */
+#define FIFOINFREE 0x40 /* Input FIFO free entry count. */
+#define FIFOOUTVALID 0x41 /* Output FIFO valid entry count. */
+#define COMM 0x42 /* dual 4 bit communications ports */
+#define MEMENDIAN 0x43 /* set byte swapping on PCI mem accesses */
+#define INTR 0x44 /* which interrupts occurred */
+#define INTREN 0x46 /* enable different interrupts */
+#define DEBUGREG 0x48 /* soft resets, RISC hold/single step */
+#define LOWWATERMARK 0x49 /* Input FIFO low water mark for interrupt */
+#define STATUS 0x4A /* specifies which blocks of the V2000 are busy */
+#define XBUSCTL 0x4B /* XBus control register */
+#define PCITEST 0x4C /* PCI test */
+#define DMACMDPTR 0x50 /* DMA command list pointer */
+#define DMA_ADDRESS 0x54 /* DMA data address */
+#define DMA_COUNT 0x58 /* DMA remaining transfer count */
+#define STATEINDEX 0x60 /* state index info */
+#define STATEDATA 0x64 /* state data info */
+#define SCLKPLL 0x68 /* system clock PLL control register */
+#define SCRATCH 0x70 /* 16-bit BIOS scratch space */
+#define MODEREG 0x72 /* Mode -- to differentiate from old MODE */
+#define MODE_ MODEREG
+#define MODE MODEREG
+#define BANKSELECT 0x74 /* Local memory to A0000 mapping */
+#define BANKSELECT_PHYSADDR ((unsigned long)(0xA0000))
+#define CRTCTEST 0x80 /* CRTC test register */
+#define CRTCCTL 0x84 /* CRTC mode */
+#define CRTCHORZ 0x88 /* CRTC horizontal timing */
+#define CRTCVERT 0x8c /* CRTC vertical timing */
+#define FRAMEBASEB 0x90 /* Stereoscopic frame base b address */
+#define FRAMEBASEA 0x94 /* Frame base A address */
+#define CRTCOFFSET 0x98 /* CRTC StrideOffset */
+#define CRTCSTATUS 0x9c /* CRTC video scan position */
+#define DRAMCTL 0xa0 /* DRAM timing */
+#define MEMDIAG 0xa4 /* Memory diagnostic register #1 */
+#define CURSORBASE 0xac /* cursor base address bits [23:10] aligne to 1024 byte boundary */
+#define PALETTE 0xb0 /* Access to DAC */
+#define PCLKPLL 0xc0 /* external device 0 */
+#define VINEVENBASE 0xd0 /* video input even field base address */
+#define VINODDBASE 0xd4 /* video input odd field base address */
+#define WRITEINTR0ADDR 0xd8 /* Memory write interrupt address0 */
+#define WRITEINTR1ADDR 0xdc /* Memory write interrupt address1 */
+#define DEVICE0_V2x000 0xf0 /* external device 1 (PLL) */
+
+/*
+ * PCLKPLL/SCLKPLL register bit defn
+ */
+#define PCLKPLLPMASK 0xffffe1ff
+#define SCLKPLLPMASK 0xffffe1ff
+#define MCLKPLLPMASK 0xfffe1fff
+#define PLLPCLKP 9
+#define PLLSCLKP 9
+#define PLLMCLKP 13
+#define PLLPCLKN 13
+#define PLLSCLKN 17
+#define PLLPCLKDOUBLE 26 /* bit 26 in PClkPLL register */
+
+#define DIRECTPCLKMASK 0x00400000
+#define DIRECTMCLKMASK 0x00800000
+
+#define VGASTDCLOCK 0x100000
+#define EXTRADIV2 0x200000
+
+#define PLLINCLKFREQ 14318 /* PLL input clk freq in KHz */
+
+/*
+ * memory controller
+ */
+#define MCLK_BYPASSEDGEFREQ 90000 /* in KHz */
+
+/*
+ * Microcode commands
+ */
+#define CMD_SETPALETTE 0x21
+
+/*
+ * MMIO registers
+ */
+
+#define MMIO_FIFOINFREE 0x20040
+#define MMIO_COMM 0x20042
+#define MMIO_FIFOOUTVALID 0x20041
+#define MMIO_INTR 0x20044 /* which interrupts occurred */
+#define MMIO_DMACMDPTR 0x20050
+#define MMIO_CRTCHORZ 0x20088 /* CRTC horizontal timing */
+#define MMIO_CRTCVERT 0x2008c /* CRTC vertical timing */
+#define MMIO_CRTCSTATUS 0x2009c
+#define MMIO_DACRAMWRITEADR 0x200b0 /* Palette Write Index */
+#define MMIO_DACRAMDATA 0x200b1 /* Palette Data */
+#define MMIO_VINEVENBASE 0x200d0 /* video input even field base address */
+#define MMIO_VINODDBASE 0x200d4 /* video input odd field base address */
+#define MMIO_WRITEINTR0ADDR 0x200d8 /* Memory write interrupt address0 */
+#define MMIO_WRITEINTR1ADDR 0x200dc /* Memory write interrupt address1 */
+
+#define HOST_INTERRUPT_MUTEX 1
+
+/* memory mapped IO register structure */
+typedef struct _v_mem_io {
+ vu32 fifo_swap_no[0x2000]; /* 0x0 */
+ vu32 fifo_swap_end[0x2000]; /* 0x4000 */
+ vu32 fifo_swap_inhw[0x2000]; /* 0x8000 */
+ vu32 fifo_swap_hw[0x2000]; /* 0xC000 */
+ vu32 reserved0[0x10]; /* 0x10000 */
+ vu8 fifoinFree; /* 0x10040 */
+ vu8 fifooutvalid; /* 0x10041 */
+ vu8 comm; /* 0x10042 */
+ vu8 memendian; /* 0x10043 */
+ vu8 intr; /* 0x10044 */
+ vu8 reserved1; /* 0x10045 */
+ vu8 intren; /* 0x10046 */
+ vu8 reserved2; /* 0x10047 */
+ vu8 debugreg; /* 0x10048 */
+ vu8 lowwatermark; /* 0x10049 */
+ vu8 status; /* 0x1004a */
+ vu8 xbusctl; /* 0x1004b */
+ vu8 pcitest; /* 0x1004c */
+ vu8 reserved3[3]; /* 0x1004d */
+ vu32 dmacmdptr; /* 0x10050 */
+ vu32 dma_address; /* 0x10054 */
+ vu32 dma_count; /* 0x10058 */
+ vu8 vga_extend; /* 0x1005c */
+ vu8 reserved4; /* 0x1005d */
+ vu8 membase; /* 0x1005e */
+ vu8 reserved5; /* 0x1005f */
+ vu32 stateindex; /* 0x10060 */
+ vu32 statedata; /* 0x10064 */
+ vu8 sclkpll; /* 0x10068 */
+ vu8 reserved6[7]; /* 0x10069 */
+ vu16 scratch; /* 0x10070 */
+ vu8 mode; /* 0x10072 */
+ vu8 scratch1; /* 0x10073 */
+ vu8 bankselect; /* 0x10074 */
+ vu8 reserved7[11]; /* 0x10075 */
+ vu32 crtctest; /* 0x10080 */
+ vu32 crtcctl; /* 0x10084 */
+ vu32 crtchorz; /* 0x10088 */
+ vu32 crtcvert; /* 0x1008c */
+ vu32 framebaseb; /* 0x10090 */
+ vu32 framebasea; /* 0x10094 */
+ vu32 crtcoffset; /* 0x10098 */
+ vu32 crtcstatus; /* 0x1009c */
+ vu32 memctl; /* 0x100a0 */
+ vu32 memdiag; /* 0x100a4 */
+ vu32 memcmd; /* 0x100a8 */
+ vu32 cursorbase; /* 0x100ac */
+ vu8 dacramwriteadr; /* 0x100b0 */
+ vu8 dacramdata; /* 0x100b1 */
+ vu8 dacpixelmsk; /* 0x100b2 */
+ vu8 dacramreadadr; /* 0x100b3 */
+ vu8 dacovswriteadr; /* 0x100b4 */
+ vu8 dacovsdata; /* 0x100b5 */
+ vu8 daccommand0; /* 0x100b6 */
+ vu8 dacovsreadadr; /* 0x100b7 */
+ vu8 daccommand1; /* 0x100b8 */
+ vu8 daccommand2; /* 0x100b9 */
+ vu8 daccommand3; /* 0x100ba */
+ vu8 daccursordata; /* 0x100bb */
+ vu8 daccursorxlow; /* 0x100bc */
+ vu8 daccursorxhigh; /* 0x100bd */
+ vu8 daccursorylow; /* 0x100be */
+ vu8 daccursoryhigh; /* 0x100bf */
+ vu8 pclkpll; /* 0x100c0 */
+} v_mem_io;
+
+/* IO register flag bits */
+/* _MASK defined for multi-bit values */
+/* _ADDR defined for registers accessible from RISC */
+
+/* COMM */
+#define SYSSTATUS_MASK 0x0f /* host->RISC comm */
+#define SYSSTATUS_SHIFT 0
+#define RISCSTATUS_MASK 0xf0 /* RISC->host comm r/o */
+#define RISCSTATUS_SHIFT 4
+
+/* MEMENDIAN */
+#define MEMENDIAN_NO 0 /* No byte swap. */
+#define MEMENDIAN_END 1 /* Swap bytes 3<>0, 2<>1. */
+#define MEMENDIAN_INHW 2 /* Swap bytes 3<>2, 1<>0. */
+#define MEMENDIAN_HW 3 /* Swap half-words. */
+#define MEMENDIAN_MASK 3
+#define MEMENDIAN_SHIFT 0
+
+#define DMABUSY 0x80 /* DMA busy r/o */
+#define DMACMDPTR_DMABUSY 0x1 /* corresponding bit in other reg */
+
+/* INTR */
+#define VERTINTR 0x01 /* vert retrace */
+#define FIFOLOWINTR 0x02 /* free entries rose above low water */
+#define RISCINTR 0x04 /* RISC firmware interrupt */
+#define HALTINTR 0x08 /* RISC halted */
+#define FIFOERRORINTR 0x10 /* FIFO under/over flow */
+#define DMAERRORINTR 0x20 /* PCI error during DMA */
+#define DMAINTR 0x40 /* DMA done interrupt */
+#define XINTR 0x80 /* external device pass thru intr */
+#define VIDEOINEVENINTR 0x100 /* Video input even field interrupt */
+#define VIDEOINODDINTR 0x100 /* Video input even field interrupt */
+
+/* INTREN */
+#define VERTINTREN 0x01 /* vert retrace */
+#define FIFOLOWINTREN 0x02 /* free entries rose above low water */
+#define RISCINTREN 0x04 /* RISC firmware interrupt */
+#define HALTINTREN 0x08 /* RISC halted */
+#define FIFOERRORINTREN 0x10 /* FIFO under/over flow */
+#define DMAERRORINTREN 0x20 /* PCI error during DMA */
+#define DMAINTREN 0x40 /* DMA done interrupt */
+#define XINTREN 0x80 /* external device pass thru intr */
+
+/* DEBUG */
+#define SOFTRESET 0x01 /* soft reset chip */
+#define HOLDRISC 0x02 /* stop RISC when set */
+#define STEPRISC 0x04 /* single step RISC */
+#define DIRECTSCLK 0x08 /* disable internal divide by 2 for sys clk */
+#define SOFTVGARESET 0x10 /* assert VGA reset */
+#define SOFTXRESET 0x20 /* assert XReset output to ext devices */
+
+/* MODE_ register */
+#define VESA_MODE 0x01 /* enable 0xA0000 in native mode */
+#define VGA_MODE 0x02 /* VGA mode if set else native mode */
+#define VGA_32 0x04 /* enable VGA 32 bit accesses */
+#define DMA_EN 0x08 /* enable DMA accesses */
+
+#define NATIVE_MODE 0 /* not VESA and not VGA */
+
+/* DRAM register */
+#define DRAMCTL_ADDR 0xffe00500
+
+/* CRTC registers */
+#define CRTCTEST_ADDR 0xffe00400
+#define CRTCCTL_ADDR 0xffe00420
+#define CRTCHORZ_ADDR 0xffe00440
+#define CRTCVERT_ADDR 0xffe00460
+#define FRAMEBASEB_ADDR 0xffe00480
+#define FRAMEBASEA_ADDR 0xffe004a0
+#define CRTCOFFSET_ADDR 0xffe004c0
+#define CRTCSTATUS_ADDR 0xffe004e0
+
+#define CRTCTEST_VIDEOLATENCY_MASK 0x1F
+#define CRTCTEST_NOTVBLANK 0x10000
+#define CRTCTEST_VBLANK 0x40000
+
+#define CRTCCTL_SCRNFMT_MASK 0xF
+#define CRTCCTL_VIDEOFIFOSIZE128 0x10
+#define CRTCCTL_ENABLEDDC 0x20
+#define CRTCCTL_DDCOUTPUT 0x40
+#define CRTCCTL_DDCDATA 0x80
+#define CRTCCTL_VSYNCHI 0x100
+#define CRTCCTL_HSYNCHI 0x200
+#define CRTCCTL_VSYNCENABLE 0x400
+#define CRTCCTL_HSYNCENABLE 0x800
+#define CRTCCTL_VIDEOENABLE 0x1000
+#define CRTCCTL_STEREOSCOPIC 0x2000
+#define CRTCCTL_FRAMEDISPLAYED 0x4000
+#define CRTCCTL_FRAMEBUFFERBGR 0x8000
+#define CRTCCTL_EVENFRAME 0x10000
+#define CRTCCTL_LINEDOUBLE 0x20000
+#define CRTCCTL_FRAMESWITCHED 0x40000
+
+#define CRTCHORZ_ACTIVE_MASK 0xFF
+#define CRTCHORZ_ACTIVE_SHIFT 0
+#define CRTCHORZ_BACKPORCH_MASK 0x7E00
+#define CRTCHORZ_BACKPORCH_SHIFT 11
+#define CRTCHORZ_SYNC_MASK 0x1F0000L
+#define CRTCHORZ_SYNC_SHIFT 16
+#define CRTCHORZ_FRONTPORCH_MASK 0xE00000L
+#define CRTCHORZ_FRONTPORCH_SHIFT 20
+
+#define CRTCVERT_ACTIVE_MASK 0x7FF
+#define CRTCVERT_BACKPORCH_MASK 0x1F800
+#define CRTCVERT_SYNC_MASK 0xE0000
+#define CRTCVERT_FRONTPORCH_MASK 0x03F00000
+
+#define CRTCOFFSET_MASK 0xFFFF
+
+#define CRTCSTATUS_HORZCLOCKS_MASK 0xFF
+#define CRTCSTATUS_HORZ_MASK 0x600
+#define CRTCSTATUS_HORZ_FPORCH 0x200
+#define CRTCSTATUS_HORZ_SYNC 0x600
+#define CRTCSTATUS_HORZ_BPORCH 0x400
+#define CRTCSTATUS_HORZ_ACTIVE 0x000
+#define CRTCSTATUS_SCANLINESLEFT_MASK 0x003FF800
+#define CRTCSTATUS_VERT_MASK 0xC00000
+#define CRTCSTATUS_VERT_FPORCH 0x400000
+#define CRTCSTATUS_VERT_SYNC 0xC00000
+#define CRTCSTATUS_VERT_BPORCH 0x800000
+#define CRTCSTATUS_VERT_ACTIVE 0x000000
+
+/* RAMDAC registers - avail through I/O space */
+
+#define DACRAMWRITEADR 0xb0
+#define DACRAMDATA 0xb1
+#define DACPIXELMSK 0xb2
+#define DACRAMREADADR 0xb3
+#define DACOVSWRITEADR 0xb4
+#define DACOVSDATA 0xb5
+#define DACCOMMAND0 0xb6
+#define DACOVSREADADR 0xb7
+#define DACCOMMAND1 0xb8
+#define DACCOMMAND2 0xb9
+#define DACSTATUS 0xba
+#define DACCOMMAND3 0xba /* accessed via unlocking/indexing */
+#define DACCURSORDATA 0xbb
+#define DACCURSORXLOW 0xbc
+#define DACCURSORXHIGH 0xbd
+#define DACCURSORYLOW 0xbe
+#define DACCURSORYHIGH 0xbf
+
+#define BT_CO_COLORWR_ADDR DACOVSWRITEADR
+#define BT_CO_COLORDATA DACOVSDATA
+#define BT_PTR_ROWOFFSET 32
+#define BT_PTR_COLUMNOFFSET 32
+
+/* PCLKPLL register */
+#define PLLDEV DEVICE0
+#define VOUTEN 0x00080000L /* bit 19 */
+#define VGASCLKOVER2 0x00100000L /* bit 20 */
+#define PCLKSTARTEN 0x00800000L /* bit 23 */
+
+/* Some state indices */
+#define STATEINDEX_IR 128
+#define STATEINDEX_PC 129
+#define STATEINDEX_S1 130
+
+/* PCI configuration registers. */
+#define CONFIGIOREG 0xE0000014
+#define CONFIGENABLE 0xE0000004
+#ifdef USEROM
+#define CONFIGROMREG 0xE0000030
+#endif
+
+/* Cache parameters. */
+#define ICACHESIZE 2048 /* I cache size. */
+#define ICACHELINESIZE 32 /* I cache line size. */
+#ifndef ICACHE_ONOFF_MASK
+#define ICACHE_ONOFF_MASK (((v_u32)1<<17)|(1<<3))
+#define ICACHE_ON ((0<<17)|(0<<3))
+#define ICACHE_OFF (((v_u32)1<<17)|(1<<3))
+#endif
+
+/* Video registers */
+#define BT829_DEV DEVICE0
+#define VIDEO_DECODER_DEV_ENABLE 0x4
+#define VIDEO_DECODER_DEV_DISABLE 0x0
+
+#define VINBASE_MASK 0x1FFFFFL
+#define VINMAXVERT_SHIFT 24
+#define VINSTRIDE_SHIFT 27
+#define VINQSIZE_SHIFT 30
+
+#define VINORDER_SHIFT 24
+#define ACTIVE_LOW 0
+#define ACTIVE_HI 1L
+#define VINHSYNCHI_SHIFT 26
+#define VINVSYNCHI_SHIFT 27
+#define VINACTIVE_SHIFT 28
+#define VINNOODD_SHIFT 29
+#define VINENABLE_SHIFT 30
+
+#endif /* _V2KREGS_H */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/vboard.c b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vboard.c
new file mode 100644
index 000000000..20da156e4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vboard.c
@@ -0,0 +1,159 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/vboard.c,v 1.3 1999/04/25 10:02:15 dawes Exp $ */
+/*
+ * includes
+ */
+
+#include "v1krisc.h"
+#include "vboard.h"
+#include "vloaduc.h"
+#include "vos.h"
+
+
+
+/*
+ * global data
+ */
+
+#include "cscode.h"
+
+
+
+/*
+ * local function prototypes
+ */
+
+
+#ifdef NOT_YET_USED
+/*
+ * functions
+ */
+int v_initboard(struct v_board_t *board)
+{
+ vu16 iob=board->io_base;
+ vu8 *vmb;
+ vu32 offset;
+ int c;
+
+ /* write "monitor" program to memory */
+ v1k_stop(board);
+ board->csucode_base=0x800;
+ v_out8(iob+MEMENDIAN, MEMENDIAN_NO);
+
+ /* Note that CS ucode must wait on address in csucode_base
+ * when initialized for later context switch code to work. */
+ vmb=board->vmem_base;
+ offset=board->csucode_base/4;
+ for (c=0; c<sizeof(csrisc)/sizeof(vu32); c++, offset++)
+ v_write_memory32(vmb, offset, csrisc[c]);
+
+ /* ... and start it */
+ v1k_flushicache(board);
+ v1k_start(board, board->csucode_base);
+
+ c=v_load_ucfile(board, "/home/smurf/RENDITION/rendition/v10002d.uc");
+ if (c == -1) {
+ ErrorF( "Jeuch\n");
+ }
+ else {
+ board->ucode_entry=c;
+ v_out32(iob, 0); /* a0 - ucode init command */
+ v_out32(iob, 0); /* a1 - 1024 byte context store area */
+ v_out32(iob, 0); /* a2 */
+ v_out32(iob, board->ucode_entry);
+ }
+
+ return 0;
+}
+
+#endif
+
+int v_resetboard(struct v_board_t *board)
+{
+/*
+ v1k_softreset(board);
+*/
+ return 0;
+}
+
+
+
+int v_getmemorysize(struct v_board_t *board)
+{
+#define PATTERN 0xf5faaf5f
+#define START 0x12345678
+#define ONEMEG (1024L*1024L)
+ vu32 offset;
+ vu32 pattern;
+ vu32 start;
+ vu8 memendian;
+#ifdef XSERVER
+ vu8 modereg;
+
+ modereg=v_in8(board->io_base+MODEREG);
+ v_out8(board->io_base+MODEREG, NATIVE_MODE);
+#endif
+
+ /* no byte swapping */
+ memendian=v_in8(board->io_base+MEMENDIAN);
+ v_out8(board->io_base+MEMENDIAN, MEMENDIAN_NO);
+
+ /* it looks like the v1000 wraps the memory; but for I'm not sure,
+ * let's test also for non-writable offsets */
+ start=v_read_memory32(board->vmem_base, 0);
+ v_write_memory32(board->vmem_base, 0, START);
+ for (offset=ONEMEG; offset<16*ONEMEG; offset+=ONEMEG) {
+#ifdef DEBUG
+ ErrorF( "Testing %d MB: ", offset/ONEMEG);
+#endif
+ pattern=v_read_memory32(board->vmem_base, offset/4);
+ if (START == pattern) {
+#ifdef DEBUG
+ ErrorF( "Back at the beginning\n");
+#endif
+ break;
+ }
+
+ pattern^=PATTERN;
+ v_write_memory32(board->vmem_base, offset/4, pattern);
+
+#ifdef DEBUG
+ ErrorF( "%x <-> %x\n", (int)pattern,
+ (int)v_read_memory32(board->vmem_base, offset/4));
+#endif
+
+ if (pattern != v_read_memory32(board->vmem_base, offset/4)) {
+ offset-=ONEMEG;
+ break;
+ }
+ v_write_memory32(board->vmem_base, offset/4, pattern^PATTERN);
+ }
+ v_write_memory32(board->vmem_base, 0, start);
+
+ if (16*ONEMEG <= offset)
+ board->mem_size=4*ONEMEG;
+ else
+ board->mem_size=offset;
+
+ /* restore default byte swapping */
+ v_out8(board->io_base+MEMENDIAN, MEMENDIAN_NO);
+
+#ifdef XSERVER
+ v_out8(board->io_base+MODEREG, modereg);
+#endif
+
+ return board->mem_size;
+#undef PATTERN
+#undef ONEMEG
+}
+
+
+
+/*
+ * local functions
+ */
+
+
+
+/*
+ * end of file vboard.c
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/vboard.h b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vboard.h
new file mode 100644
index 000000000..0a67f7aa5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vboard.h
@@ -0,0 +1,34 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/vboard.h,v 1.2 1999/04/17 07:06:36 dawes Exp $ */
+/*
+ * vboard.h
+ *
+ * functions to interact with a Verite board
+ */
+
+#ifndef _VBOARD_H_
+#define _VBOARD_H_
+
+
+/*
+ * includes
+ */
+
+#include "vtypes.h"
+
+
+
+/*
+ * function prototypes
+ */
+
+int v_initboard(struct v_board_t *board);
+int v_resetboard(struct v_board_t *board);
+int v_getmemorysize(struct v_board_t *board);
+
+
+
+#endif /* #define _VBOARD_H_ */
+
+/*
+ * end of file vboard.h
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/vgafont-std.data b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vgafont-std.data
new file mode 100644
index 000000000..5df6c0f98
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vgafont-std.data
@@ -0,0 +1,527 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/vgafont-std.data,v 1.2 1999/04/17 07:06:37 dawes Exp $ */
+/*
+ * file vfont.data
+ *
+ * Standard vga character table.
+ */
+
+unsigned char font8x16[]={
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0 */
+ 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0x81, 0xBD,
+ 0x99, 0x81, 0x81, 0x7E, 0x00, 0x00, 0x00, 0x00, /* 1 */
+ 0x00, 0x00, 0x7E, 0xFF, 0xDB, 0xFF, 0xFF, 0xC3,
+ 0xE7, 0xFF, 0xFF, 0x7E, 0x00, 0x00, 0x00, 0x00, /* 2 */
+ 0x00, 0x00, 0x00, 0x00, 0x6C, 0xFE, 0xFE, 0xFE,
+ 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, /* 3 */
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7C, 0xFE,
+ 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, /* 4 */
+ 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0xE7, 0xE7,
+ 0xE7, 0x99, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, /* 5 */
+ 0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF,
+ 0x7E, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, /* 6 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C,
+ 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 7 */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC3,
+ 0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 8 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x42,
+ 0x42, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9 */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x99, 0xBD,
+ 0xBD, 0x99, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 10 */
+ 0x00, 0x00, 0x1E, 0x0E, 0x1A, 0x32, 0x78, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, /* 11 */
+ 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C,
+ 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 12 */
+ 0x00, 0x00, 0x3F, 0x33, 0x3F, 0x30, 0x30, 0x30,
+ 0x30, 0x70, 0xF0, 0xE0, 0x00, 0x00, 0x00, 0x00, /* 13 */
+ 0x00, 0x00, 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x63,
+ 0x63, 0x67, 0xE7, 0xE6, 0xC0, 0x00, 0x00, 0x00, /* 14 */
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0xDB, 0x3C, 0xE7,
+ 0x3C, 0xDB, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 15 */
+ 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFE, 0xF8,
+ 0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, /* 16 */
+ 0x00, 0x02, 0x06, 0x0E, 0x1E, 0x3E, 0xFE, 0x3E,
+ 0x1E, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, /* 17 */
+ 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18,
+ 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, /* 18 */
+ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, /* 19 */
+ 0x00, 0x00, 0x7F, 0xDB, 0xDB, 0xDB, 0x7B, 0x1B,
+ 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00, 0x00, 0x00, /* 20 */
+ 0x00, 0x7C, 0xC6, 0x60, 0x38, 0x6C, 0xC6, 0xC6,
+ 0x6C, 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00, /* 21 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFE, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, /* 22 */
+ 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18,
+ 0x18, 0x7E, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00, /* 23 */
+ 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 24 */
+ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, /* 25 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0C, 0xFE,
+ 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 26 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xFE,
+ 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 27 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0,
+ 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 28 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6C, 0xFE,
+ 0x6C, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 29 */
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7C,
+ 0x7C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 */
+ 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x7C, 0x7C,
+ 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, /* 31 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 32 */
+ 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x18,
+ 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 33 */
+ 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 34 */
+ 0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C,
+ 0x6C, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, /* 35 */
+ 0x18, 0x18, 0x7C, 0xC6, 0xC2, 0xC0, 0x7C, 0x06,
+ 0x86, 0xC6, 0x7C, 0x18, 0x18, 0x00, 0x00, 0x00, /* 36 */
+ 0x00, 0x00, 0x00, 0x00, 0xC2, 0xC6, 0x0C, 0x18,
+ 0x30, 0x60, 0xC6, 0x86, 0x00, 0x00, 0x00, 0x00, /* 37 */
+ 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x76, 0xDC,
+ 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, /* 38 */
+ 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 39 */
+ 0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, /* 40 */
+ 0x00, 0x00, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, /* 41 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3C, 0xFF,
+ 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 42 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E,
+ 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 43 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, /* 44 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 45 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 46 */
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0C, 0x18,
+ 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, /* 47 */
+ 0x00, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xDB, 0xDB,
+ 0xC3, 0xC3, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, /* 48 */
+ 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00, /* 49 */
+ 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x0C, 0x18, 0x30,
+ 0x60, 0xC0, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, /* 50 */
+ 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06,
+ 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 51 */
+ 0x00, 0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0xCC, 0xFE,
+ 0x0C, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00, /* 52 */
+ 0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xFC, 0x06,
+ 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 53 */
+ 0x00, 0x00, 0x38, 0x60, 0xC0, 0xC0, 0xFC, 0xC6,
+ 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 54 */
+ 0x00, 0x00, 0xFE, 0xC6, 0x06, 0x06, 0x0C, 0x18,
+ 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, /* 55 */
+ 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6,
+ 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 56 */
+ 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7E, 0x06,
+ 0x06, 0x06, 0x0C, 0x78, 0x00, 0x00, 0x00, 0x00, /* 57 */
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
+ 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, /* 58 */
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
+ 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, /* 59 */
+ 0x00, 0x00, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60,
+ 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, /* 60 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00,
+ 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 61 */
+ 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06,
+ 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, /* 62 */
+ 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x0C, 0x18, 0x18,
+ 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 63 */
+ 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xDE, 0xDE,
+ 0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 64 */
+ 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE,
+ 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, /* 65 */
+ 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66,
+ 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00, /* 66 */
+ 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0,
+ 0xC0, 0xC2, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, /* 67 */
+ 0x00, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x6C, 0xF8, 0x00, 0x00, 0x00, 0x00, /* 68 */
+ 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68,
+ 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, /* 69 */
+ 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68,
+ 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, /* 70 */
+ 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xDE,
+ 0xC6, 0xC6, 0x66, 0x3A, 0x00, 0x00, 0x00, 0x00, /* 71 */
+ 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6,
+ 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, /* 72 */
+ 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, /* 73 */
+ 0x00, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, /* 74 */
+ 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C, 0x78, 0x78,
+ 0x6C, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, /* 75 */
+ 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x60,
+ 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, /* 76 */
+ 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6,
+ 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, /* 77 */
+ 0x00, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE,
+ 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, /* 78 */
+ 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
+ 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 79 */
+ 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x60,
+ 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, /* 80 */
+ 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
+ 0xC6, 0xD6, 0xDE, 0x7C, 0x0C, 0x0E, 0x00, 0x00, /* 81 */
+ 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x6C,
+ 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, /* 82 */
+ 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x38, 0x0C,
+ 0x06, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 83 */
+ 0x00, 0x00, 0x7E, 0x7E, 0x5A, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, /* 84 */
+ 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
+ 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 85 */
+ 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
+ 0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, /* 86 */
+ 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6,
+ 0xD6, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, /* 87 */
+ 0x00, 0x00, 0xC6, 0xC6, 0x6C, 0x6C, 0x38, 0x38,
+ 0x6C, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, /* 88 */
+ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18,
+ 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, /* 89 */
+ 0x00, 0x00, 0xFE, 0xC6, 0x86, 0x0C, 0x18, 0x30,
+ 0x60, 0xC2, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, /* 90 */
+ 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x3C, 0x00, 0x00, 0x00, 0x00, /* 91 */
+ 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38,
+ 0x1C, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, /* 92 */
+ 0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
+ 0x0C, 0x0C, 0x0C, 0x3C, 0x00, 0x00, 0x00, 0x00, /* 93 */
+ 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 94 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, /* 95 */
+ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 96 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C,
+ 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, /* 97 */
+ 0x00, 0x00, 0xE0, 0x60, 0x60, 0x78, 0x6C, 0x66,
+ 0x66, 0x66, 0x66, 0xDC, 0x00, 0x00, 0x00, 0x00, /* 98 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0,
+ 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 99 */
+ 0x00, 0x00, 0x1C, 0x0C, 0x0C, 0x3C, 0x6C, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, /* 100 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xFE,
+ 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 101 */
+ 0x00, 0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60,
+ 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, /* 102 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xCC, 0x78, 0x00, /* 103 */
+ 0x00, 0x00, 0xE0, 0x60, 0x60, 0x6C, 0x76, 0x66,
+ 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, /* 104 */
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, /* 105 */
+ 0x00, 0x00, 0x06, 0x06, 0x00, 0x0E, 0x06, 0x06,
+ 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C, 0x00, /* 106 */
+ 0x00, 0x00, 0xE0, 0x60, 0x60, 0x66, 0x6C, 0x78,
+ 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00, /* 107 */
+ 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, /* 108 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0xFE, 0xD6,
+ 0xD6, 0xD6, 0xD6, 0xD6, 0x00, 0x00, 0x00, 0x00, /* 109 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, /* 110 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6,
+ 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 111 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, /* 112 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0x0C, 0x1E, 0x00, /* 113 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x76, 0x62,
+ 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00, /* 114 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x60,
+ 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 115 */
+ 0x00, 0x00, 0x10, 0x30, 0x30, 0xFC, 0x30, 0x30,
+ 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00, /* 116 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, /* 117 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, /* 118 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6,
+ 0xD6, 0xD6, 0xFE, 0x6C, 0x00, 0x00, 0x00, 0x00, /* 119 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0x6C, 0x38,
+ 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, /* 120 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6,
+ 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0xF8, 0x00, /* 121 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xCC, 0x18,
+ 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, /* 122 */
+ 0x00, 0x00, 0x0E, 0x18, 0x18, 0x18, 0x70, 0x18,
+ 0x18, 0x18, 0x18, 0x0E, 0x00, 0x00, 0x00, 0x00, /* 123 */
+ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 124 */
+ 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0E, 0x18,
+ 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, /* 125 */
+ 0x00, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 126 */
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6,
+ 0xC6, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, /* 127 */
+ 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0,
+ 0xC2, 0x66, 0x3C, 0x0C, 0x06, 0x7C, 0x00, 0x00, /* 128 */
+ 0x00, 0x00, 0xCC, 0x00, 0x00, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, /* 129 */
+ 0x00, 0x0C, 0x18, 0x30, 0x00, 0x7C, 0xC6, 0xFE,
+ 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 130 */
+ 0x00, 0x10, 0x38, 0x6C, 0x00, 0x78, 0x0C, 0x7C,
+ 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, /* 131 */
+ 0x00, 0x00, 0xCC, 0x00, 0x00, 0x78, 0x0C, 0x7C,
+ 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, /* 132 */
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0C, 0x7C,
+ 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, /* 133 */
+ 0x00, 0x38, 0x6C, 0x38, 0x00, 0x78, 0x0C, 0x7C,
+ 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, /* 134 */
+ 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x60, 0x60,
+ 0x66, 0x3C, 0x0C, 0x06, 0x3C, 0x00, 0x00, 0x00, /* 135 */
+ 0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xFE,
+ 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 136 */
+ 0x00, 0x00, 0xC6, 0x00, 0x00, 0x7C, 0xC6, 0xFE,
+ 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 137 */
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xFE,
+ 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 138 */
+ 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, /* 139 */
+ 0x00, 0x18, 0x3C, 0x66, 0x00, 0x38, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, /* 140 */
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, /* 141 */
+ 0x00, 0xC6, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6,
+ 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, /* 142 */
+ 0x38, 0x6C, 0x38, 0x00, 0x38, 0x6C, 0xC6, 0xC6,
+ 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, /* 143 */
+ 0x18, 0x30, 0x60, 0x00, 0xFE, 0x66, 0x60, 0x7C,
+ 0x60, 0x60, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00, /* 144 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x76, 0x36,
+ 0x7E, 0xD8, 0xD8, 0x6E, 0x00, 0x00, 0x00, 0x00, /* 145 */
+ 0x00, 0x00, 0x3E, 0x6C, 0xCC, 0xCC, 0xFE, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0xCE, 0x00, 0x00, 0x00, 0x00, /* 146 */
+ 0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C, 0xC6, 0xC6,
+ 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 147 */
+ 0x00, 0x00, 0xC6, 0x00, 0x00, 0x7C, 0xC6, 0xC6,
+ 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 148 */
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x7C, 0xC6, 0xC6,
+ 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 149 */
+ 0x00, 0x30, 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, /* 150 */
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, /* 151 */
+ 0x00, 0x00, 0xC6, 0x00, 0x00, 0xC6, 0xC6, 0xC6,
+ 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0x78, 0x00, /* 152 */
+ 0x00, 0xC6, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6,
+ 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 153 */
+ 0x00, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
+ 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 154 */
+ 0x00, 0x18, 0x18, 0x3C, 0x66, 0x60, 0x60, 0x60,
+ 0x66, 0x3C, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 155 */
+ 0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60,
+ 0x60, 0x60, 0xE6, 0xFC, 0x00, 0x00, 0x00, 0x00, /* 156 */
+ 0x00, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18,
+ 0x7E, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 157 */
+ 0x00, 0xF8, 0xCC, 0xCC, 0xF8, 0xC4, 0xCC, 0xDE,
+ 0xCC, 0xCC, 0xCC, 0xC6, 0x00, 0x00, 0x00, 0x00, /* 158 */
+ 0x00, 0x0E, 0x1B, 0x18, 0x18, 0x18, 0x7E, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0xD8, 0x70, 0x00, 0x00, /* 159 */
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0C, 0x7C,
+ 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, /* 160 */
+ 0x00, 0x0C, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, /* 161 */
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0x7C, 0xC6, 0xC6,
+ 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 162 */
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0xCC, 0xCC, 0xCC,
+ 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00, /* 163 */
+ 0x00, 0x00, 0x76, 0xDC, 0x00, 0xDC, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, /* 164 */
+ 0x76, 0xDC, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE,
+ 0xCE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, /* 165 */
+ 0x00, 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 166 */
+ 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 167 */
+ 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60,
+ 0xC0, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00, /* 168 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xC0,
+ 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, /* 169 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06,
+ 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, /* 170 */
+ 0x00, 0xC0, 0xC0, 0xC2, 0xC6, 0xCC, 0x18, 0x30,
+ 0x60, 0xCE, 0x93, 0x06, 0x0C, 0x1F, 0x00, 0x00, /* 171 */
+ 0x00, 0xC0, 0xC0, 0xC2, 0xC6, 0xCC, 0x18, 0x30,
+ 0x66, 0xCE, 0x9A, 0x3F, 0x06, 0x0F, 0x00, 0x00, /* 172 */
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18,
+ 0x3C, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, /* 173 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x66, 0xCC,
+ 0x66, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 174 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x66, 0x33,
+ 0x66, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 175 */
+ 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
+ 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, /* 176 */
+ 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
+ 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, /* 177 */
+ 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77,
+ 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, /* 178 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 179 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 180 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 181 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 182 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 183 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0xF8,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 184 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xF6,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 185 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 186 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06, 0xF6,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 187 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xFE,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 188 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFE,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 189 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 190 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 191 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 192 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 193 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 194 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 195 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 196 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 197 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 198 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 199 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 200 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30, 0x37,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 201 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 202 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 203 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 204 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 205 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xF7,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 206 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 207 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 208 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 209 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 210 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 211 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 212 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x1F,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 213 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 214 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 215 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0xFF,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 216 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 217 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 218 */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 219 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 220 */
+ 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, /* 221 */
+ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
+ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, /* 222 */
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 223 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0xD8,
+ 0xD8, 0xD8, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00, /* 224 */
+ 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0xD8, 0xCC,
+ 0xC6, 0xC6, 0xC6, 0xCC, 0x00, 0x00, 0x00, 0x00, /* 225 */
+ 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0,
+ 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, /* 226 */
+ 0x00, 0x00, 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C,
+ 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, /* 227 */
+ 0x00, 0x00, 0x00, 0xFE, 0xC6, 0x60, 0x30, 0x18,
+ 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00, /* 228 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xD8, 0xD8,
+ 0xD8, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00, /* 229 */
+ 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x7C, 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, /* 230 */
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 231 */
+ 0x00, 0x00, 0x00, 0x7E, 0x18, 0x3C, 0x66, 0x66,
+ 0x66, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00, /* 232 */
+ 0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xFE,
+ 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, /* 233 */
+ 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C,
+ 0x6C, 0x6C, 0x6C, 0xEE, 0x00, 0x00, 0x00, 0x00, /* 234 */
+ 0x00, 0x00, 0x1E, 0x30, 0x18, 0x0C, 0x3E, 0x66,
+ 0x66, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00, /* 235 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xDB, 0xDB,
+ 0xDB, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 236 */
+ 0x00, 0x00, 0x00, 0x03, 0x06, 0x7E, 0xCF, 0xDB,
+ 0xF3, 0x7E, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, /* 237 */
+ 0x00, 0x00, 0x1C, 0x30, 0x60, 0x60, 0x7C, 0x60,
+ 0x60, 0x60, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00, /* 238 */
+ 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6,
+ 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00, /* 239 */
+ 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE,
+ 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, /* 240 */
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18,
+ 0x18, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, /* 241 */
+ 0x00, 0x00, 0x00, 0x30, 0x18, 0x0C, 0x06, 0x0C,
+ 0x18, 0x30, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, /* 242 */
+ 0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x60, 0x30,
+ 0x18, 0x0C, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, /* 243 */
+ 0x00, 0x00, 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 244 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0xD8, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00, /* 245 */
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7E,
+ 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, /* 246 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x00,
+ 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 247 */
+ 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 248 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 249 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 250 */
+ 0x00, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xEC,
+ 0x6C, 0x6C, 0x3C, 0x1C, 0x00, 0x00, 0x00, 0x00, /* 251 */
+ 0x00, 0xD8, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 252 */
+ 0x00, 0x70, 0x98, 0x30, 0x60, 0xC8, 0xF8, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 253 */
+ 0x00, 0x00, 0x00, 0x00, 0x7C, 0x7C, 0x7C, 0x7C,
+ 0x7C, 0x7C, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, /* 254 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 255 */
+};
+
+
+/*
+ * end of file vgafont.data
+ */
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/vgafont-vrx.data b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vgafont-vrx.data
new file mode 100644
index 000000000..04e16093c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vgafont-vrx.data
@@ -0,0 +1,527 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/vgafont-vrx.data,v 1.2 1999/04/17 07:06:38 dawes Exp $ */
+/*
+ * file vvfont.data
+ *
+ * Standard vga character table dumped from miroCRYSTAL VRX.
+ */
+
+unsigned char font8x16[]={
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0 */
+ 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd,
+ 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 1 */
+ 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3,
+ 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 2 */
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0xee, 0xfe, 0xfe,
+ 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, /* 3 */
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe,
+ 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, /* 4 */
+ 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x5a, 0xff,
+ 0xff, 0x5a, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 5 */
+ 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0xfe,
+ 0xee, 0x54, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, /* 6 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
+ 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 7 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3,
+ 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 8 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42,
+ 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd,
+ 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, /* 10 */
+ 0x00, 0x00, 0x1e, 0x06, 0x0a, 0x7a, 0xcc, 0x84,
+ 0x84, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, /* 11 */
+ 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c,
+ 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 12 */
+ 0x00, 0x08, 0x0c, 0x0a, 0x0a, 0x0a, 0x08, 0x08,
+ 0x08, 0x78, 0xf8, 0x70, 0x00, 0x00, 0x00, 0x00, /* 13 */
+ 0x00, 0x10, 0x18, 0x14, 0x12, 0x1a, 0x16, 0x12,
+ 0x72, 0xf2, 0x62, 0x0e, 0x1e, 0x0c, 0x00, 0x00, /* 14 */
+ 0x00, 0x00, 0x00, 0x10, 0x92, 0x7c, 0x6c, 0xc6,
+ 0x6c, 0x7c, 0x92, 0x10, 0x00, 0x00, 0x00, 0x00, /* 15 */
+ 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf8, 0xfe, 0xf8,
+ 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 16 */
+ 0x00, 0x00, 0x02, 0x06, 0x0e, 0x3e, 0xfe, 0x3e,
+ 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, /* 17 */
+ 0x00, 0x00, 0x10, 0x38, 0x7c, 0xd6, 0x10, 0x10,
+ 0x10, 0xd6, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, /* 18 */
+ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, /* 19 */
+ 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0xdb, 0x7b,
+ 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, /* 20 */
+ 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6,
+ 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, /* 21 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, /* 22 */
+ 0x00, 0x00, 0x10, 0x38, 0x7c, 0xd6, 0x10, 0x10,
+ 0xd6, 0x7c, 0x38, 0x10, 0xfe, 0x00, 0x00, 0x00, /* 23 */
+ 0x00, 0x00, 0x10, 0x38, 0x7c, 0xd6, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, /* 24 */
+ 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0xd6, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, /* 25 */
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x0c, 0xfe,
+ 0x0c, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, /* 26 */
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 0x60, 0xfe,
+ 0x60, 0x30, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, /* 27 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+ 0xc0, 0xc0, 0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, /* 28 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x42, 0xff,
+ 0x42, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 29 */
+ 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x7c,
+ 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30 */
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c,
+ 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, /* 31 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 32 */
+ 0x00, 0x00, 0x30, 0x78, 0x78, 0x78, 0x30, 0x30,
+ 0x30, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, /* 33 */
+ 0x00, 0x66, 0x66, 0x22, 0x22, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 34 */
+ 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c,
+ 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, /* 35 */
+ 0x00, 0x10, 0x10, 0x7c, 0xd6, 0xd6, 0x70, 0x38,
+ 0x1c, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x00, 0x00, /* 36 */
+ 0x00, 0x00, 0x60, 0x92, 0x96, 0x6c, 0x18, 0x30,
+ 0x6c, 0xd2, 0x92, 0x0c, 0x00, 0x00, 0x00, 0x00, /* 37 */
+ 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x30, 0x76,
+ 0xdc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, /* 38 */
+ 0x00, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 39 */
+ 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, /* 40 */
+ 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, /* 41 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff,
+ 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 42 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
+ 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 43 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x30, 0x10, 0x20, 0x00, 0x00, /* 44 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 45 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, /* 46 */
+ 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30,
+ 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 47 */
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6,
+ 0xe6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 48 */
+ 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 49 */
+ 0x00, 0x00, 0x7c, 0xc6, 0x86, 0x06, 0x0c, 0x18,
+ 0x30, 0x60, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, /* 50 */
+ 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06,
+ 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 51 */
+ 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xcc,
+ 0xfe, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, /* 52 */
+ 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06,
+ 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 53 */
+ 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xfc, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 54 */
+ 0x00, 0x00, 0xfe, 0xc6, 0x86, 0x06, 0x0c, 0x0c,
+ 0x18, 0x18, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, /* 55 */
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 56 */
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e,
+ 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 57 */
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
+ 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, /* 58 */
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
+ 0x00, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x00, /* 59 */
+ 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60,
+ 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, /* 60 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
+ 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 61 */
+ 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06,
+ 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, /* 62 */
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x0c, 0x18,
+ 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 63 */
+ 0x00, 0x00, 0x00, 0x3c, 0x42, 0x9d, 0xa5, 0xa5,
+ 0xad, 0xb6, 0x40, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 64 */
+ 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, /* 65 */
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66,
+ 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, /* 66 */
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0,
+ 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 67 */
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, /* 68 */
+ 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x78,
+ 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, /* 69 */
+ 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x78,
+ 0x68, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, /* 70 */
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0xc0, 0xce,
+ 0xc6, 0xc6, 0xc6, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 71 */
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, /* 72 */
+ 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 73 */
+ 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, /* 74 */
+ 0x00, 0x00, 0xe6, 0x66, 0x66, 0x66, 0x7c, 0x78,
+ 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, /* 75 */
+ 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60,
+ 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, /* 76 */
+ 0x00, 0x00, 0x82, 0xc6, 0xee, 0xfe, 0xfe, 0xd6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, /* 77 */
+ 0x00, 0x00, 0x86, 0xc6, 0xe6, 0xf6, 0xfe, 0xde,
+ 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, /* 78 */
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 79 */
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x66, 0x7c,
+ 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, /* 80 */
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xd6, 0xde, 0x7c, 0x06, 0x00, 0x00, 0x00, /* 81 */
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x66, 0x7c,
+ 0x6c, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, /* 82 */
+ 0x00, 0x00, 0x7c, 0xc6, 0xc2, 0x60, 0x38, 0x0c,
+ 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 83 */
+ 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 84 */
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 85 */
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, /* 86 */
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6,
+ 0xfe, 0xee, 0xc6, 0x82, 0x00, 0x00, 0x00, 0x00, /* 87 */
+ 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38,
+ 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, /* 88 */
+ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18,
+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 89 */
+ 0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30,
+ 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, /* 90 */
+ 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 91 */
+ 0x00, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x30, 0x18,
+ 0x0c, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, /* 92 */
+ 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 93 */
+ 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 94 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, /* 95 */
+ 0x00, 0x18, 0x18, 0x10, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 96 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c,
+ 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, /* 97 */
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 98 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0,
+ 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 99 */
+ 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc,
+ 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, /* 100 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6,
+ 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 101 */
+ 0x00, 0x00, 0x1c, 0x36, 0x30, 0x78, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, /* 102 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc,
+ 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, /* 103 */
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66,
+ 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, /* 104 */
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 105 */
+ 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x1c, 0x0c, 0x0c,
+ 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, /* 106 */
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78,
+ 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, /* 107 */
+ 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 108 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6,
+ 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00, /* 109 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, /* 110 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 111 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, /* 112 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xcc, 0xcc,
+ 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, /* 113 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x76, 0x60,
+ 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, /* 114 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60,
+ 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 115 */
+ 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30,
+ 0x30, 0x30, 0x34, 0x18, 0x00, 0x00, 0x00, 0x00, /* 116 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc,
+ 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, /* 117 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc,
+ 0xcc, 0xcc, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, /* 118 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6,
+ 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00, /* 119 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c,
+ 0x38, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, /* 120 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, /* 121 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x8c, 0x18,
+ 0x30, 0x60, 0xc2, 0xfe, 0x00, 0x00, 0x00, 0x00, /* 122 */
+ 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18,
+ 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, /* 123 */
+ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 124 */
+ 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18,
+ 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, /* 125 */
+ 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 126 */
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6,
+ 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, /* 127 */
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0,
+ 0xc0, 0xc6, 0xc6, 0x7c, 0x10, 0x08, 0x70, 0x00, /* 128 */
+ 0x00, 0x00, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0xcc,
+ 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, /* 129 */
+ 0x00, 0x06, 0x0c, 0x10, 0x00, 0x7c, 0xc6, 0xc6,
+ 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 130 */
+ 0x00, 0x30, 0x78, 0xcc, 0x00, 0x78, 0x0c, 0x7c,
+ 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, /* 131 */
+ 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x78, 0x0c, 0x7c,
+ 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, /* 132 */
+ 0x00, 0xc0, 0x60, 0x10, 0x00, 0x78, 0x0c, 0x7c,
+ 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, /* 133 */
+ 0x00, 0x30, 0x48, 0x30, 0x00, 0x78, 0x0c, 0x7c,
+ 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, /* 134 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0,
+ 0xc0, 0xc0, 0xc6, 0x7c, 0x10, 0x08, 0x70, 0x00, /* 135 */
+ 0x00, 0x18, 0x3c, 0x66, 0x00, 0x7c, 0xc6, 0xc6,
+ 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 136 */
+ 0x00, 0x00, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6,
+ 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 137 */
+ 0x00, 0xc0, 0x60, 0x10, 0x00, 0x7c, 0xc6, 0xc6,
+ 0xfe, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 138 */
+ 0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 139 */
+ 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 140 */
+ 0x00, 0xc0, 0x60, 0x10, 0x00, 0x38, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 141 */
+ 0xc6, 0xc6, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, /* 142 */
+ 0x38, 0x44, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0xfe,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, /* 143 */
+ 0x06, 0x0c, 0x10, 0xfe, 0x66, 0x62, 0x68, 0x78,
+ 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, /* 144 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x12, 0x72,
+ 0x9e, 0x90, 0x92, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 145 */
+ 0x00, 0x00, 0x3e, 0x6a, 0xc8, 0xc8, 0xcc, 0xfc,
+ 0xc8, 0xc8, 0xca, 0xce, 0x00, 0x00, 0x00, 0x00, /* 146 */
+ 0x00, 0x18, 0x3c, 0x66, 0x00, 0x7c, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 147 */
+ 0x00, 0x00, 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 148 */
+ 0x00, 0xc0, 0x60, 0x10, 0x00, 0x7c, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 149 */
+ 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc,
+ 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, /* 150 */
+ 0x00, 0xc0, 0x60, 0x10, 0x00, 0xcc, 0xcc, 0xcc,
+ 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, /* 151 */
+ 0x00, 0x00, 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, /* 152 */
+ 0xc6, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 153 */
+ 0xc6, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 154 */
+ 0x00, 0x00, 0x10, 0x10, 0x7c, 0xd6, 0xd0, 0xd0,
+ 0xd6, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, /* 155 */
+ 0x00, 0x00, 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60,
+ 0x60, 0x60, 0xf2, 0xdc, 0x00, 0x00, 0x00, 0x00, /* 156 */
+ 0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e,
+ 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, /* 157 */
+ 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc,
+ 0xde, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00, /* 158 */
+ 0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x7e, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, /* 159 */
+ 0x00, 0x06, 0x0c, 0x10, 0x00, 0x78, 0x0c, 0x7c,
+ 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, /* 160 */
+ 0x00, 0x06, 0x0c, 0x10, 0x00, 0x38, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 161 */
+ 0x00, 0x06, 0x0c, 0x10, 0x00, 0x7c, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 162 */
+ 0x00, 0x06, 0x0c, 0x10, 0x00, 0xcc, 0xcc, 0xcc,
+ 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, /* 163 */
+ 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, /* 164 */
+ 0x76, 0xdc, 0x00, 0x86, 0xc6, 0xe6, 0xf6, 0xfe,
+ 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, /* 165 */
+ 0x00, 0x70, 0x18, 0x78, 0xd8, 0x6c, 0x00, 0xfc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 166 */
+ 0x00, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0xfc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 167 */
+ 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60,
+ 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 168 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+ 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, /* 169 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
+ 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, /* 170 */
+ 0x00, 0x60, 0xe0, 0x64, 0x6c, 0x78, 0x30, 0x60,
+ 0xdc, 0xb6, 0x0c, 0x18, 0x3e, 0x00, 0x00, 0x00, /* 171 */
+ 0x00, 0x60, 0xe0, 0x64, 0x6c, 0x78, 0x30, 0x6c,
+ 0xdc, 0xac, 0x3e, 0x0c, 0x0c, 0x00, 0x00, 0x00, /* 172 */
+ 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x30,
+ 0x78, 0x78, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, /* 173 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8,
+ 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 174 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
+ 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 175 */
+ 0x00, 0x55, 0x00, 0x55, 0x00, 0x55, 0x00, 0x55,
+ 0x00, 0x55, 0x00, 0x55, 0x00, 0x55, 0x00, 0x55, /* 176 */
+ 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55,
+ 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, /* 177 */
+ 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55,
+ 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, /* 178 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 179 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 180 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18,
+ 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 181 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 182 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 183 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18,
+ 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 184 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06,
+ 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 185 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 186 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06,
+ 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 187 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06,
+ 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 188 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 189 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18,
+ 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 190 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 191 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 192 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 193 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 194 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 195 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 196 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 197 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18,
+ 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 198 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 199 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30,
+ 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 200 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30,
+ 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 201 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 202 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 203 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30,
+ 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 204 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 205 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00,
+ 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 206 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 207 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 208 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 209 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 210 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 211 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18,
+ 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 212 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18,
+ 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 213 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 214 */
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, /* 215 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18,
+ 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 216 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 217 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 218 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 219 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 220 */
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 221 */
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, /* 222 */
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 223 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0xdc, 0xc8,
+ 0xc8, 0xc8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, /* 224 */
+ 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6,
+ 0xc6, 0xc6, 0xdc, 0xc0, 0x40, 0x00, 0x00, 0x00, /* 225 */
+ 0x00, 0x00, 0xfe, 0x62, 0x60, 0x60, 0x60, 0x60,
+ 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, /* 226 */
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x7e, 0xec, 0x6c,
+ 0x6c, 0x6c, 0x6c, 0x48, 0x00, 0x00, 0x00, 0x00, /* 227 */
+ 0x00, 0x00, 0xfe, 0xc2, 0x60, 0x30, 0x18, 0x30,
+ 0x60, 0xc0, 0xc2, 0xfe, 0x00, 0x00, 0x00, 0x00, /* 228 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd0, 0xc8,
+ 0xc8, 0xc8, 0xc8, 0x70, 0x00, 0x00, 0x00, 0x00, /* 229 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc,
+ 0xcc, 0xcc, 0xcc, 0xf8, 0x80, 0x80, 0x00, 0x00, /* 230 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0x18,
+ 0x18, 0x18, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, /* 231 */
+ 0x00, 0x00, 0x38, 0x10, 0x7c, 0xd6, 0xd6, 0xd6,
+ 0xd6, 0x7c, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, /* 232 */
+ 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe,
+ 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, /* 233 */
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0x6c, 0x28, 0x28, 0xee, 0x00, 0x00, 0x00, 0x00, /* 234 */
+ 0x00, 0x00, 0x3c, 0x62, 0x30, 0x18, 0x7c, 0xcc,
+ 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, /* 235 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0xdb, 0xdb,
+ 0xdb, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 236 */
+ 0x00, 0x00, 0x00, 0x02, 0x06, 0x7c, 0xce, 0xde,
+ 0xd6, 0xf6, 0xe6, 0x7c, 0xc0, 0x80, 0x00, 0x00, /* 237 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x60, 0xc0,
+ 0xf8, 0xc0, 0x60, 0x3c, 0x00, 0x00, 0x00, 0x00, /* 238 */
+ 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6,
+ 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, /* 239 */
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe,
+ 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, /* 240 */
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18,
+ 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 241 */
+ 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c,
+ 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 242 */
+ 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30,
+ 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, /* 243 */
+ 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 244 */
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, /* 245 */
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e,
+ 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, /* 246 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
+ 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 247 */
+ 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 248 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 249 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 250 */
+ 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec,
+ 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, /* 251 */
+ 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 252 */
+ 0x00, 0x70, 0x98, 0x18, 0x30, 0x60, 0xf8, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 253 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e,
+ 0x7e, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, /* 254 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 255 */
+};
+
+
+
+/*
+ * end of file vvgafont.data
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/vgapalette.data b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vgapalette.data
new file mode 100644
index 000000000..26f8ca4a4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vgapalette.data
@@ -0,0 +1,277 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/vgapalette.data,v 1.2 1999/04/17 07:06:38 dawes Exp $ */
+unsigned char vga_pal[]=
+{
+/* 00 - 0f */
+0x00,0x00,0x00,/*0*/
+0x00,0x00,0x2a,/*1*/
+0x00,0x2a,0x00,/*2*/
+0x00,0x2a,0x2a,/*3*/
+0x2a,0x00,0x00,/*4*/
+0x2a,0x00,0x2a,/*5*/
+0x2a,0x2a,0x00,/*6*/
+0x2a,0x2a,0x2a,/*7*/
+0x00,0x00,0x15,/*8*/
+0x00,0x00,0x3f,/*9*/
+0x00,0x2a,0x15,/*a*/
+0x00,0x2a,0x3f,/*b*/
+0x2a,0x00,0x15,/*c*/
+0x2a,0x00,0x3f,/*d*/
+0x2a,0x2a,0x15,/*e*/
+0x2a,0x2a,0x3f,/*f*/
+/* 10-1f */
+0x00,0x15,0x00,/*0*/
+0x00,0x15,0x2a,/*1*/
+0x00,0x3f,0x00,/*2*/
+0x00,0x3f,0x2a,/*3*/
+0x2a,0x15,0x00,/*4*/
+0x2a,0x15,0x2a,/*5*/
+0x2a,0x3f,0x00,/*6*/
+0x2a,0x3f,0x2a,/*7*/
+0x00,0x15,0x15,/*8*/
+0x00,0x15,0x3f,/*9*/
+0x00,0x3f,0x15,/*a*/
+0x00,0x3f,0x3f,/*b*/
+0x2a,0x15,0x15,/*c*/
+0x2a,0x15,0x3f,/*d*/
+0x2a,0x3f,0x15,/*e*/
+0x2a,0x3f,0x3f,/*f*/
+/* 20-2f */
+0x15,0x00,0x00,/*0*/
+0x15,0x00,0x2a,/*1*/
+0x15,0x2a,0x00,/*2*/
+0x15,0x2a,0x2a,/*3*/
+0x3f,0x00,0x00,/*4*/
+0x3f,0x00,0x2a,/*5*/
+0x3f,0x2a,0x00,/*6*/
+0x3f,0x2a,0x2a,/*7*/
+0x15,0x00,0x15,/*8*/
+0x15,0x00,0x3f,/*9*/
+0x15,0x2a,0x15,/*a*/
+0x15,0x2a,0x3f,/*b*/
+0x3f,0x00,0x15,/*c*/
+0x3f,0x00,0x3f,/*d*/
+0x3f,0x2a,0x15,/*e*/
+0x3f,0x2a,0x3f,/*f*/
+/* 30-3f */
+0x15,0x15,0x00,/*0*/
+0x15,0x15,0x2a,/*1*/
+0x15,0x3f,0x00,/*2*/
+0x15,0x3f,0x2a,/*3*/
+0x3f,0x15,0x00,/*4*/
+0x3f,0x15,0x2a,/*5*/
+0x3f,0x3f,0x00,/*6*/
+0x3f,0x3f,0x2a,/*7*/
+0x15,0x15,0x15,/*8*/
+0x15,0x15,0x3f,/*9*/
+0x15,0x3f,0x15,/*a*/
+0x15,0x3f,0x3f,/*b*/
+0x3f,0x15,0x15,/*c*/
+0x3f,0x15,0x3f,/*d*/
+0x3f,0x3f,0x15,/*e*/
+0x3f,0x3f,0x3f,/*f*/
+/* 40-4f */
+0x39,0x0c,0x05,/*0*/
+0x15,0x2c,0x0f,/*1*/
+0x26,0x10,0x3d,/*2*/
+0x29,0x29,0x38,/*3*/
+0x04,0x1a,0x0e,/*4*/
+0x02,0x1e,0x3a,/*5*/
+0x3c,0x25,0x33,/*6*/
+0x3c,0x0c,0x2c,/*7*/
+0x3f,0x03,0x2b,/*8*/
+0x1c,0x09,0x13,/*9*/
+0x25,0x2a,0x35,/*a*/
+0x1e,0x0a,0x38,/*b*/
+0x24,0x08,0x03,/*c*/
+0x03,0x0e,0x36,/*d*/
+0x0c,0x06,0x2a,/*e*/
+0x26,0x03,0x32,/*f*/
+/* 50-5f */
+0x05,0x2f,0x33,/*0*/
+0x3c,0x35,0x2f,/*1*/
+0x2d,0x26,0x3e,/*2*/
+0x0d,0x0a,0x10,/*3*/
+0x25,0x3c,0x11,/*4*/
+0x0d,0x04,0x2e,/*5*/
+0x05,0x19,0x3e,/*6*/
+0x0c,0x13,0x34,/*7*/
+0x2b,0x06,0x24,/*8*/
+0x04,0x03,0x0d,/*9*/
+0x2f,0x3c,0x0c,/*a*/
+0x2a,0x37,0x1f,/*b*/
+0x0f,0x12,0x38,/*c*/
+0x38,0x0e,0x2a,/*d*/
+0x12,0x2f,0x19,/*e*/
+0x29,0x2e,0x31,/*f*/
+/* 60-6f */
+0x25,0x13,0x3e,/*0*/
+0x33,0x3e,0x33,/*1*/
+0x1d,0x2c,0x25,/*2*/
+0x15,0x15,0x05,/*3*/
+0x32,0x25,0x39,/*4*/
+0x1a,0x07,0x1f,/*5*/
+0x13,0x0e,0x1d,/*6*/
+0x36,0x17,0x34,/*7*/
+0x0f,0x15,0x23,/*8*/
+0x02,0x35,0x0d,/*9*/
+0x15,0x3f,0x0c,/*a*/
+0x14,0x2f,0x0f,/*b*/
+0x19,0x21,0x3e,/*c*/
+0x27,0x11,0x2f,/*d*/
+0x38,0x3f,0x3c,/*e*/
+0x36,0x2d,0x15,/*f*/
+/* 70-7f */
+0x16,0x17,0x02,/*0*/
+0x01,0x0a,0x3d,/*1*/
+0x1b,0x11,0x3f,/*2*/
+0x21,0x3c,0x0d,/*3*/
+0x1a,0x39,0x3d,/*4*/
+0x08,0x0e,0x0e,/*5*/
+0x22,0x21,0x23,/*6*/
+0x1e,0x30,0x05,/*7*/
+0x1f,0x22,0x3d,/*8*/
+0x1e,0x2f,0x0a,/*9*/
+0x00,0x1c,0x0e,/*a*/
+0x00,0x1c,0x15,/*b*/
+0x00,0x1c,0x1c,/*c*/
+0x00,0x15,0x1c,/*d*/
+0x00,0x0e,0x1c,/*e*/
+0x00,0x07,0x1c,/*f*/
+/* 80-8f */
+0x0e,0x0e,0x1c,/*0*/
+0x11,0x0e,0x1c,/*1*/
+0x15,0x0e,0x1c,/*2*/
+0x18,0x0e,0x1c,/*3*/
+0x1c,0x0e,0x1c,/*4*/
+0x1c,0x0e,0x18,/*5*/
+0x1c,0x0e,0x15,/*6*/
+0x1c,0x0e,0x11,/*7*/
+0x1c,0x0e,0x0e,/*8*/
+0x1c,0x11,0x0e,/*9*/
+0x1c,0x15,0x0e,/*a*/
+0x1c,0x18,0x0e,/*b*/
+0x1c,0x1c,0x0e,/*c*/
+0x18,0x1c,0x0e,/*d*/
+0x15,0x1c,0x0e,/*e*/
+0x11,0x1c,0x0e,/*f*/
+/* 90-9f */
+0x0e,0x1c,0x0e,/*0*/
+0x0e,0x1c,0x11,/*1*/
+0x0e,0x1c,0x15,/*2*/
+0x0e,0x1c,0x18,/*3*/
+0x0e,0x1c,0x1c,/*4*/
+0x0e,0x18,0x1c,/*5*/
+0x0e,0x15,0x1c,/*6*/
+0x0e,0x11,0x1c,/*7*/
+0x14,0x14,0x1c,/*8*/
+0x16,0x14,0x1c,/*9*/
+0x18,0x14,0x1c,/*a*/
+0x1a,0x14,0x1c,/*b*/
+0x1c,0x14,0x1c,/*c*/
+0x1c,0x14,0x1a,/*d*/
+0x1c,0x14,0x18,/*e*/
+0x1c,0x14,0x16,/*f*/
+/* a0-af */
+0x1c,0x14,0x14,/*0*/
+0x1c,0x16,0x14,/*1*/
+0x1c,0x18,0x14,/*2*/
+0x1c,0x1a,0x14,/*3*/
+0x1c,0x1c,0x14,/*4*/
+0x1a,0x1c,0x14,/*5*/
+0x18,0x1c,0x14,/*6*/
+0x16,0x1c,0x14,/*7*/
+0x14,0x1c,0x14,/*8*/
+0x14,0x1c,0x16,/*9*/
+0x14,0x1c,0x18,/*a*/
+0x14,0x1c,0x1a,/*b*/
+0x14,0x1c,0x1c,/*c*/
+0x14,0x1a,0x1c,/*d*/
+0x14,0x18,0x1c,/*e*/
+0x14,0x16,0x1c,/*f*/
+/* b0-bf */
+0x00,0x00,0x10,/*0*/
+0x04,0x00,0x10,/*1*/
+0x08,0x00,0x10,/*2*/
+0x0c,0x00,0x10,/*3*/
+0x10,0x00,0x10,/*4*/
+0x10,0x00,0x0c,/*5*/
+0x10,0x00,0x08,/*6*/
+0x10,0x00,0x04,/*7*/
+0x10,0x00,0x00,/*8*/
+0x10,0x04,0x00,/*9*/
+0x10,0x08,0x00,/*a*/
+0x10,0x0c,0x00,/*b*/
+0x10,0x10,0x00,/*c*/
+0x0c,0x10,0x00,/*d*/
+0x08,0x10,0x00,/*e*/
+0x04,0x10,0x00,/*f*/
+/* c0-cf */
+0x00,0x10,0x00,/*0*/
+0x00,0x10,0x04,/*1*/
+0x00,0x10,0x08,/*2*/
+0x00,0x10,0x0c,/*3*/
+0x00,0x10,0x10,/*4*/
+0x00,0x0c,0x10,/*5*/
+0x00,0x08,0x10,/*6*/
+0x00,0x04,0x10,/*7*/
+0x08,0x08,0x10,/*8*/
+0x0a,0x08,0x10,/*9*/
+0x0c,0x08,0x10,/*a*/
+0x0e,0x08,0x10,/*b*/
+0x10,0x08,0x10,/*c*/
+0x10,0x08,0x0e,/*d*/
+0x10,0x08,0x0c,/*e*/
+0x10,0x08,0x0a,/*f*/
+/* d0-df */
+0x10,0x08,0x08,/*0*/
+0x10,0x0a,0x08,/*1*/
+0x10,0x0c,0x08,/*2*/
+0x10,0x0e,0x08,/*3*/
+0x10,0x10,0x08,/*4*/
+0x0e,0x10,0x08,/*5*/
+0x0c,0x10,0x08,/*6*/
+0x0a,0x10,0x08,/*7*/
+0x08,0x10,0x08,/*8*/
+0x08,0x10,0x0a,/*9*/
+0x08,0x10,0x0c,/*a*/
+0x08,0x10,0x0e,/*b*/
+0x08,0x10,0x10,/*c*/
+0x08,0x0e,0x10,/*d*/
+0x08,0x0c,0x10,/*e*/
+0x08,0x0a,0x10,/*f*/
+/* e0-ef */
+0x0b,0x0b,0x10,/*0*/
+0x0c,0x0b,0x10,/*1*/
+0x0d,0x0b,0x10,/*2*/
+0x0f,0x0b,0x10,/*3*/
+0x10,0x0b,0x10,/*4*/
+0x10,0x0b,0x0f,/*5*/
+0x10,0x0b,0x0d,/*6*/
+0x10,0x0b,0x0c,/*7*/
+0x10,0x0b,0x0b,/*8*/
+0x10,0x0c,0x0b,/*9*/
+0x10,0x0d,0x0b,/*a*/
+0x10,0x0f,0x0b,/*b*/
+0x10,0x10,0x0b,/*c*/
+0x0f,0x10,0x0b,/*d*/
+0x0d,0x10,0x0b,/*e*/
+0x0c,0x10,0x0b,/*f*/
+/* f0-ff */
+0x0b,0x10,0x0b,/*0*/
+0x0b,0x10,0x0c,/*1*/
+0x0b,0x10,0x0d,/*2*/
+0x0b,0x10,0x0f,/*3*/
+0x0b,0x10,0x10,/*4*/
+0x0b,0x0f,0x10,/*5*/
+0x0b,0x0d,0x10,/*6*/
+0x0b,0x0c,0x10,/*7*/
+0x00,0x00,0x00,/*8*/
+0x00,0x00,0x00,/*9*/
+0x00,0x00,0x00,/*a*/
+0x00,0x00,0x00,/*b*/
+0x00,0x00,0x00,/*c*/
+0x00,0x00,0x00,/*d*/
+0x00,0x00,0x00,/*e*/
+0x00,0x00,0x00 /*f*/
+};
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/vloaduc.h b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vloaduc.h
new file mode 100644
index 000000000..86f110164
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vloaduc.h
@@ -0,0 +1,41 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/vloaduc.h,v 1.2 1999/04/17 07:06:39 dawes Exp $ */
+
+/*
+ * file vloaduc.h
+ *
+ * loads microcode
+ */
+
+#ifndef _VLOADUC_H_
+#define _VLOADUC_H_
+
+
+
+/*
+ * includes
+ */
+
+#include "vos.h"
+#include "vtypes.h"
+
+
+
+/*
+ * defines
+ */
+
+
+
+/*
+ * function prototypes
+ */
+
+int v_load_ucfile(struct v_board_t *board, char *file_name);
+
+
+
+#endif /* #ifndef _VLOADUC_H_ */
+
+/*
+ * end of file vloaduc.h
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/vmodes.c b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vmodes.c
new file mode 100644
index 000000000..619de708d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vmodes.c
@@ -0,0 +1,538 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/vmodes.c,v 1.4 1999/04/25 10:02:15 dawes Exp $ */
+/*
+ * file vmodes.c
+ *
+ * Routines that handle mode setting.
+ */
+
+
+
+/*
+ * includes
+ */
+
+#include "xf86.h"
+#include "xf86_ansic.h"
+
+#include "vmodes.h"
+#include "vos.h"
+#include "vramdac.h"
+#include "v1krisc.h"
+#include "v1kregs.h"
+#include "v2kregs.h"
+#include "vvga.h"
+
+
+/*
+ * defines
+ */
+
+#define combineNMP(N, M, P) \
+ (((vu32)(M-2)<<10) | ((vu32)P<<8) | (vu32)(N-2))
+
+#define v2kcombineNMP(N, M, P) (((vu32)N<<13) | ((vu32)P<<9) | (vu32)M)
+
+/* defines for doubled clock */
+#define CLK_DOUBLE 1
+#define NO_CLK_DOUBLE 0
+
+/* video FIFO is set to 64 or 128 entries based on req.d bandwidth in bytes/s */
+#define FIFOSIZE_THRESH 100000000 /* set thresh to 100MB/s */
+
+/* compute desired video FIFO size given total bandwidth in bytes/s. */
+#define FIFOSIZE(vclk, Bpp) (((vclk * Bpp) > FIFOSIZE_THRESH) ? 128 : 64)
+
+/* Bt485A RAMDAC control bits */
+#define PALETTEDISABLE 0x10
+
+/* Hold memory refresh cycles until video blank */
+#define HOLD_MEMREFRESHCYCLE 0x2000
+
+/* memCtl bits [16..23] */
+#define DEFAULT_WREFRESH 0x330000
+
+/* Disable memory refresh cycles */
+#define DISABLE_MEMREFRESHCYCLE 0x8000
+
+#define CTL(ldbl, hsynchi, vsynchi) \
+ (((ldbl) ? CRTCCTL_LINEDOUBLE : 0) \
+ |((hsynchi) ? CRTCCTL_HSYNCHI : 0) \
+ |((vsynchi) ? CRTCCTL_VSYNCHI : 0) \
+ |(CRTCCTL_VSYNCENABLE | CRTCCTL_HSYNCENABLE))
+
+#define HORZ(fp, sy, bp, ac) \
+ (((((vu32)(((fp)>>3)-1))&7)<<21)|((((vu32)(((sy)>>3)-1))&0x1F)<<16)|((((vu32)(((bp)>>3)-1))&0x3f)<<9)|((((vu32)(((ac)>>3)-1))&0xff)))
+
+#define VERT(fp, sy, bp, ac) \
+ (((((vu32)(fp-1))&0x3f)<<20)|((((vu32)(sy-1))&0x7)<<17)|((((vu32)(bp-1))&0x3f)<<11)|((((vu32)(ac-1))&0x7ff)))
+
+#define HORZAC(crtchorz) \
+ (((((vu32)crtchorz)&CRTCHORZ_ACTIVE_MASK)+1)<<3)
+
+#define HORZBP(crtchorz) \
+ ((((((vu32)crtchorz)&CRTCHORZ_BACKPORCH_MASK)>>9)+1)<<3)
+
+#define HORZSY(crtchorz) \
+ ((((((vu32)crtchorz)&CRTCHORZ_SYNC_MASK)>>16)+1)<<3)
+
+#define HORZFP(crtchorz) \
+ ((((((vu32)crtchorz)&CRTCHORZ_FRONTPORCH_MASK)>>21)+1)<<3)
+
+#define VERTAC(crtcvert) \
+ ((((vu32)crtcvert)&CRTCVERT_ACTIVE_MASK)+1)
+
+#define VERTBP(crtcvert) \
+ (((((vu32)crtcvert)&CRTCVERT_BACKPORCH_MASK)>>11)+1)
+
+#define VERTSY(crtcvert) \
+ (((((vu32)crtcvert)&CRTCVERT_SYNC_MASK)>>17)+1)
+
+#define VERTFP(crtcvert) \
+ (((((vu32)crtcvert)&CRTCVERT_FRONTPORCH_MASK)>>20)+1)
+
+#define PCLK(N, M, P) (N),(M),(P)
+
+#define TIMING_MASK (CRTCCTL_VIDEOFIFOSIZE128|CRTCCTL_LINEDOUBLE|\
+ CRTCCTL_VSYNCHI|CRTCCTL_HSYNCHI|CRTCCTL_VSYNCENABLE|\
+ CRTCCTL_HSYNCENABLE)
+
+/* addr&7 == 5, 6, 7 are bad */
+#define BADADDR(x) (((x)&(((x)<<1)|((x)<<2)))&0x4)
+
+#define V1_MIN_VCO_FREQ 25
+#define V1_MAX_VCO_FREQ 135
+#define V1_REF_FREQ 14.318
+#define V1_MIN_PCF_FREQ 0.2
+#define V1_MAX_PCF_FREQ 5
+
+#define V2_MIN_VCO_FREQ 125
+#define V2_MAX_VCO_FREQ 250
+#define V2_REF_FREQ 14.31818 /* Eh, is this right? */
+#define V2_MIN_PCF_FREQ 1
+#define V2_MAX_PCF_FREQ 3
+
+
+
+/*
+ * global data
+ */
+
+struct width_to_stride_t {
+ vu32 width8bpp;
+ vu8 stride0;
+ vu8 stride1;
+ vu16 chip;
+} width_to_stride_table[]={
+/* { 0, 0, 0, V1000_DEVICE }, */
+ { 4, 4, 0, V1000_DEVICE },
+ { 16, 0, 1, V1000_DEVICE },
+ { 20, 4, 1, V1000_DEVICE },
+ { 32, 0, 2, V1000_DEVICE },
+ { 36, 4, 2, V1000_DEVICE },
+ { 64, 0, 3, V1000_DEVICE },
+ { 68, 4, 3, V1000_DEVICE },
+ { 128, 0, 4, V1000_DEVICE },
+ { 132, 4, 4, V1000_DEVICE },
+ { 256, 1, 0, V1000_DEVICE },
+ { 272, 1, 1, V1000_DEVICE },
+ { 288, 1, 2, V1000_DEVICE },
+ { 320, 1, 3, V1000_DEVICE },
+ { 384, 1, 4, V1000_DEVICE },
+ { 512, 2, 0, V1000_DEVICE },
+ { 528, 2, 1, V1000_DEVICE },
+ { 544, 2, 2, V1000_DEVICE },
+ { 576, 2, 3, V1000_DEVICE },
+ { 592, 6, 1, V2000_DEVICE },
+ { 608, 6, 2, V2000_DEVICE },
+ { 640, 2, 4, V1000_DEVICE },
+ { 704, 6, 4, V2000_DEVICE },
+ { 768, 5, 0, V2000_DEVICE },
+ { 784, 5, 1, V2000_DEVICE },
+ { 800, 5, 2, V2000_DEVICE },
+ { 832, 5, 3, V2000_DEVICE },
+ { 896, 5, 4, V2000_DEVICE },
+ { 1024, 3, 0, V1000_DEVICE },
+ { 1028, 4, 5, V1000_DEVICE },
+ { 1040, 3, 1, V1000_DEVICE },
+ { 1056, 3, 2, V1000_DEVICE },
+ { 1088, 3, 3, V1000_DEVICE },
+ { 1152, 3, 4, V1000_DEVICE },
+ { 1168, 7, 1, V2000_DEVICE },
+ { 1184, 7, 2, V2000_DEVICE },
+ { 1216, 7, 3, V2000_DEVICE },
+ { 1280, 1, 5, V1000_DEVICE },
+ { 1536, 2, 5, V1000_DEVICE },
+ { 1600, 6, 5, V2000_DEVICE },
+ { 1792, 5, 5, V2000_DEVICE },
+ { 2048, 0, 6, V1000_DEVICE },
+ { 2052, 4, 6, V1000_DEVICE },
+ { 2176, 7, 5, V2000_DEVICE },
+ { 2304, 1, 6, V1000_DEVICE },
+ { 2560, 2, 6, V1000_DEVICE },
+ { 2624, 6, 6, V2000_DEVICE },
+ { 2816, 5, 6, V2000_DEVICE },
+ { 3072, 3, 6, V1000_DEVICE },
+ { 3200, 7, 6, V2000_DEVICE },
+ { 4096, 0, 7, V1000_DEVICE },
+ { 4100, 4, 7, V1000_DEVICE },
+ { 4352, 1, 7, V1000_DEVICE },
+ { 4608, 2, 7, V1000_DEVICE },
+ { 4672, 6, 7, V2000_DEVICE },
+ { 4864, 5, 7, V2000_DEVICE },
+ { 5120, 3, 7, V1000_DEVICE },
+ { 5248, 7, 7, V2000_DEVICE },
+ { 0, 0, 0, 0 }
+};
+
+
+
+/*
+ * local function prototypes
+ */
+
+void set_PLL(vu16 iob, vu32 value);
+static double V1000CalcClock(double target, int *M, int *N, int *P);
+static double V2200CalcClock(double target, int *m, int *n, int *p);
+
+
+
+/*
+ * functions
+ */
+
+int v_setmodefixed(struct v_board_t *board)
+{
+ int iob=board->io_base;
+ int tmp;
+
+#ifdef SAVEVGA
+ v_savetextmode(board);
+#endif
+
+ v1k_softreset(board);
+
+ /* switching to native mode */
+ v_out8(iob+MODEREG, NATIVE_MODE);
+
+ /* flipping some bytes */
+ v_out8(iob+MEMENDIAN, MEMENDIAN_HW);
+
+ /* try programming 1024x768@70 in highcolor */
+ tmp=v_in32(iob+DRAMCTL)&0xdfff; /* reset bit 13 */
+ v_out32(iob+DRAMCTL, tmp|DEFAULT_WREFRESH);
+
+ /* program pixel clock */
+ if (board->chip == V1000_DEVICE) {
+ set_PLL(iob, combineNMP(21, 55, 0));
+ }
+ else {
+ tmp = (~0x1800) & v_in32(iob+DRAMCTL);
+ v_out32(iob+DRAMCTL, tmp);
+ v_out32(iob+PCLKPLL, v2kcombineNMP(2, 21, 2));
+ }
+ usleep(500);
+
+ v_initdac(board, 16, 0);
+
+ v_out32(iob+CRTCHORZ, HORZ(24, 136, 144, 1024));
+ v_out32(iob+CRTCVERT, VERT(3, 6, 29, 768));
+
+ board->mode.screenwidth=1024;
+ board->mode.virtualwidth=1024;
+ board->mode.bitsperpixel=16;
+ board->mode.fifosize=128;
+
+ board->init=1;
+ v_setframebase(board, 0);
+
+ v_out32(iob+CRTCCTL, CTL(0, 0, 0)
+ |V_PIXFMT_565
+ |CRTCCTL_VIDEOFIFOSIZE128
+ |CRTCCTL_HSYNCENABLE
+ |CRTCCTL_VSYNCENABLE
+ |CRTCCTL_VIDEOENABLE);
+
+ return 0;
+}
+
+
+
+int v_setmode(struct v_board_t *board, struct v_modeinfo_t *mode)
+{
+ int tmp;
+ int doubleclock=0;
+ int M, N, P;
+ int iob=board->io_base;
+
+ /* switching to native mode */
+ v_out8(iob+MODEREG, NATIVE_MODE|VESA_MODE);
+
+ /* flipping some bytes */
+ /* Must be something better to do than this -- FIX */
+ switch (mode->bitsperpixel) {
+ case 32:
+ v_out8(iob+MEMENDIAN, MEMENDIAN_NO);
+ break;
+ case 16:
+ v_out8(iob+MEMENDIAN, MEMENDIAN_HW);
+ break;
+ case 8:
+ v_out8(iob+MEMENDIAN, MEMENDIAN_END);
+ break;
+ }
+
+ /* increase Mem/Sys clock to avoid nasty artifacts */
+ if (board->chip != V1000_DEVICE) {
+ v_out32(iob+SCLKPLL, 0xa4854); /* mclk=125 sclk=60 */
+ /* M/N/P/P = 84/5/2/4 */
+ usleep(500);
+ }
+
+ /* this has something to do with memory */
+ tmp=v_in32(iob+DRAMCTL)&0xdfff; /* reset bit 13 */
+ v_out32(iob+DRAMCTL, tmp|0x330000);
+
+ /* program pixel clock */
+ if (board->chip == V1000_DEVICE) {
+ if (110.0 < V1000CalcClock(mode->clock/1000.0, &M, &N, &P)) {
+ P++;
+ doubleclock=1;
+ }
+ set_PLL(iob, combineNMP(N, M, P));
+ }
+ else {
+ tmp = (~0x1800) & v_in32(iob+DRAMCTL);
+ v_out32(iob+DRAMCTL, tmp);
+ V2200CalcClock(mode->clock/1000.0, &M, &N, &P);
+ v_out32(iob+PCLKPLL, v2kcombineNMP(N, M, P));
+ }
+ usleep(500);
+
+ /* init the ramdac */
+ v_initdac(board, mode->bitsperpixel, doubleclock);
+
+ v_out32(iob+CRTCHORZ, HORZ(mode->hsyncstart-mode->hdisplay,
+ mode->hsyncend-mode->hsyncstart,
+ mode->htotal-mode->hsyncend,
+ mode->hdisplay));
+ v_out32(iob+CRTCVERT, VERT(mode->vsyncstart-mode->vdisplay,
+ mode->vsyncend-mode->vsyncstart,
+ mode->vtotal-mode->vsyncend,
+ mode->vdisplay));
+
+ /* fill in the mode parameters */
+ memcpy(&(board->mode), mode, sizeof(struct v_modeinfo_t));
+ board->mode.fifosize=128;
+ board->mode.pll_m=M;
+ board->mode.pll_n=N;
+ board->mode.pll_p=P;
+ board->mode.doubleclock=doubleclock;
+ if (0 == board->mode.virtualwidth)
+ board->mode.virtualwidth=board->mode.screenwidth;
+
+ board->init=1;
+ v_setframebase(board, 0);
+
+ /* Need to fix up syncs */
+
+ /* enable the display */
+ v_out32(iob+CRTCCTL, CTL(0, mode->hsynchi, mode->vsynchi)
+ |mode->pixelformat
+ |CRTCCTL_VIDEOFIFOSIZE128
+ |CRTCCTL_HSYNCENABLE
+ |CRTCCTL_VSYNCENABLE
+ |CRTCCTL_VIDEOENABLE);
+
+ return 0;
+}
+
+
+
+void v_setframebase(struct v_board_t *board, vu32 framebase)
+{
+ vu32 offset;
+
+ int iob=board->io_base;
+ int swidth=board->mode.screenwidth;
+ int vwidth=board->mode.virtualwidth;
+ int bytespp=board->mode.bitsperpixel>>3;
+ int fifo_size=board->mode.fifosize;
+
+#ifdef DEBUG
+ ErrorF( "w=%d v=%d b=%d f=%d\n",
+ swidth, vwidth, bytespp, fifo_size);
+#endif
+
+ /* CRTCOFFSET */
+ offset=vwidth*bytespp /* virtual width in bytes */
+ -swidth*bytespp /* screen width in bytes */
+ +((swidth*bytespp)%fifo_size) /* width in bytes modulo fifo size */
+ ;
+
+ if (!( framebase&7 /* framebase multiple of 8? */
+ || (swidth*bytespp)%128)) /* screenwidth multiple of fifo size */
+ offset+=fifo_size; /* increment offset by fifosize */
+
+ /* wait for vertical retrace */
+#ifndef DEBUG
+ if (!board->init) {
+ while ((v_in32(iob+CRTCSTATUS) & CRTCSTATUS_VERT_MASK) !=
+ CRTCSTATUS_VERT_ACTIVE) ;
+ while ((v_in32(iob+CRTCSTATUS) & CRTCSTATUS_VERT_MASK) ==
+ CRTCSTATUS_VERT_ACTIVE) ;
+ }
+ else
+ board->init=0;
+#endif
+
+ /* framebase */
+ v_out32(iob+FRAMEBASEA, framebase);
+
+ /* crtc offset */
+ v_out32(iob+CRTCOFFSET, offset&0xffff);
+
+}
+
+
+
+int v_getstride(struct v_board_t *board, int *width, vu16 *stride0, vu16 *stride1)
+{
+ int bytesperline;
+ int c=0;
+
+ bytesperline=board->mode.virtualwidth*(board->mode.bitsperpixel>>3);
+#ifdef DEBUG
+ ErrorF("RENDITION: %d bytes per line\n", bytesperline);
+#endif
+
+ /* for now, I implemented a linear search only, should be fixed <ml> */
+ while (0 != width_to_stride_table[c].width8bpp) {
+ if (width_to_stride_table[c].width8bpp==bytesperline
+ && width_to_stride_table[c].chip == board->chip) {
+ *stride0=width_to_stride_table[c].stride0;
+ *stride1=width_to_stride_table[c].stride1;
+ return 1;
+ }
+ c++;
+ }
+
+ return 0;
+}
+
+
+
+/*
+ * local functions
+ */
+
+/*
+ * void set_PLL(vu16 iob, vu32 value)
+ *
+ * Set PLL clock to desired frequency for the V1000.
+ */
+void set_PLL(vu16 iob, vu32 value)
+{
+ vu32 ulD;
+ int b;
+
+ /* shift out the 20 serial bits */
+ for (b=19; b>=0; b--) {
+ ulD=(value>>b)&1;
+ v_out8(iob+PLLDEV, (vu8)ulD);
+ }
+
+ /* read PLL device so the latch is filled with the previously
+ * written value */
+ (void)v_in8(iob+PLLDEV);
+}
+
+
+
+/* Vxx00CalcClock -- finds PLL parameters to match target
+ * frequency (in megahertz)
+ *
+ * Brute force, but takes less than a tenth
+ * of a second and the function is only called
+ * O(1) times during program execution.
+ */
+static double V1000CalcClock(double target, int *M, int *N, int *P)
+{
+ double mindiff = 1e10;
+ double vco, pcf, diff, freq;
+ int mm, nn, pp;
+
+ for (pp=0; pp<4; pp++)
+ for (nn=1; nn<=129; nn++)
+ for (mm=1; mm<=129; mm++) {
+ vco=V1_REF_FREQ*2.0*mm/nn;
+ if ((vco<V1_MIN_VCO_FREQ) || (vco>V1_MAX_VCO_FREQ))
+ continue;
+ pcf = V1_REF_FREQ/nn;
+ if ((pcf<V1_MIN_PCF_FREQ) || (pcf>V1_MAX_PCF_FREQ))
+ continue;
+ freq=vco/(1<<pp);
+ diff=fabs(target-freq);
+ if (diff < mindiff) {
+ *M=mm;
+ *N=nn;
+ *P=pp;
+ mindiff=diff;
+ }
+ }
+
+ vco=V1_REF_FREQ*2*(*M)/(*N);
+ pcf=V1_REF_FREQ/(*N);
+ freq=vco/(1<<(*P));
+
+#ifdef DEBUG
+ ErrorF(
+ "RENDITION: target=%f freq=%f vco=%f pcf=%f n=%d m=%d p=%d\n",
+ target, freq, vco, pcf, *N, *M, *P);
+#endif
+
+ return freq;
+}
+
+
+
+static double V2200CalcClock(double target, int *m, int *n, int *p)
+{
+ double mindiff = 1e10;
+ double vco, pcf, diff, freq;
+ int mm, nn, pp;
+
+ for (pp=1; pp<=0x0f; pp++)
+ for (nn=1; nn<=0x3f; nn++)
+ for (mm=1; mm<=0xff; mm++) {
+ vco = V2_REF_FREQ*mm/nn;
+ if ((vco < V2_MIN_VCO_FREQ) || (vco > V2_MAX_VCO_FREQ))
+ continue;
+ pcf = V2_REF_FREQ/nn;
+ if ((pcf < V2_MIN_PCF_FREQ) || (pcf > V2_MAX_PCF_FREQ))
+ continue;
+ freq = vco/pp;
+ diff = fabs(target-freq);
+ if (diff < mindiff) {
+ *m = mm; *n = nn; *p = pp;
+ mindiff = diff;
+ }
+ }
+
+ vco = V2_REF_FREQ * *m / *n;
+ pcf = V2_REF_FREQ / *n;
+ freq = vco / *p;
+
+#ifdef DEBUG
+ ErrorF(
+ "RENDITION: target=%f freq=%f vco=%f pcf=%f n=%d m=%d p=%d\n",
+ target, freq, vco, pcf, *n, *m, *p);
+#endif
+
+ return freq;
+}
+
+
+
+/*
+ * end of file vmodes.c
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/vmodes.h b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vmodes.h
new file mode 100644
index 000000000..63f5f74a4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vmodes.h
@@ -0,0 +1,36 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/vmodes.h,v 1.2 1999/04/17 07:06:42 dawes Exp $ */
+/*
+ * file vmodes.h
+ *
+ * headerfile for vmodes.c
+ */
+
+#ifndef _VMODES_H_
+#define _VMODES_H_
+
+
+
+/*
+ * includes
+ */
+
+#include "vtypes.h"
+
+
+
+/*
+ * function prototypes
+ */
+
+int v_setmodefixed(struct v_board_t *board);
+int v_setmode(struct v_board_t *board, struct v_modeinfo_t *mode);
+void v_setframebase(struct v_board_t *board, vu32 framebase);
+int v_getstride(struct v_board_t *board, int *width, vu16 *stride0, vu16 *stride1);
+
+
+
+#endif /* #ifndef _VMODES_H_ */
+
+/*
+ * end of file vmodes.h
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/vos.h b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vos.h
new file mode 100644
index 000000000..81a193089
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vos.h
@@ -0,0 +1,88 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/vos.h,v 1.3 1999/04/25 10:02:16 dawes Exp $ */
+/*
+ * file vos.h
+ *
+ * layer to map operating system dependent system calls
+ */
+
+#ifndef _VOS_H_
+#define _VOS_H_
+
+
+
+/*
+ * includes
+ */
+
+#include "vtypes.h"
+#include <compiler.h>
+
+
+
+/*
+ * function prototypes
+ */
+
+/* IO port programming */
+#ifdef DEBUG
+#define /*void*/ v_out8(/*vu16*/ port, /*vu8*/ data) \
+ ErrorF("v_out8(%x, %x)\n", port, data); \
+ outb(port, data)
+#define /*void*/ v_out16(/*vu16*/ port, /*vu16*/ data) \
+ ErrorF("v_out16(%x, %x)\n", port, data); \
+ outw(port, data)
+#define /*void*/ v_out32(/*vu16*/ port, /*vu32*/ data) \
+ ErrorF("v_out32(%x, %x)\n", port, data); \
+ outl(port, data)
+#else
+#define /*void*/ v_out8(/*vu16*/ port, /*vu8*/ data) outb(port, data)
+#define /*void*/ v_out16(/*vu16*/ port, /*vu16*/ data) outw(port, data)
+#define /*void*/ v_out32(/*vu16*/ port, /*vu32*/ data) outl(port, data)
+#endif
+
+#define /*vu8*/ v_in8(/*vu16*/ io_base) ((vu8)inb(io_base))
+#define /*vu16*/ v_in16(/*vu16*/ io_base) ((vu16)inw(io_base))
+#define /*vu32*/ v_in32(/*vu16*/ io_base) ((vu32)inl(io_base))
+
+/* memory accesses */
+#ifdef __alpha__
+#define v_read_memory32(base, offset) xf86ReadSparse32(base, 4*(offset))
+#define v_read_memory16(base, offset) xf86ReadSparse16(base, 2*(offset))
+#define v_read_memory8(base, offset) xf86ReadSparse8(base, offset)
+#define v_write_memory32(base, offset, data) xf86WriteSparse32(data,base,4*(offset))
+#define v_write_memory16(base, offset, data) xf86WriteSparse16(data,base,2*(offset))
+#define v_write_memory8(base, offset, data) xf86WriteSparse8(data,base,offset)
+#else
+#define /*vu8*/ v_read_memory8(/*vu8 **/ vmem_base, /*vu32*/ offset) \
+ (*((vmem_base)+(offset)))
+#define /*vu16*/ v_read_memory16(/*vu8 **/ vmem_base, /*vu32*/ offset) \
+ (*(((vu16 *)(vmem_base))+(offset)))
+#define /*vu32*/ v_read_memory32(/*vu8 **/ vmem_base, /*vu32*/ offset) \
+ (*(((vu32 *)(vmem_base))+(offset)))
+
+#define /*void*/ v_write_memory8(/*vu8 **/ vmem_base, /*vu32*/ offset, \
+ /*vu8*/ data) \
+ (*((vmem_base)+(offset)))=(data)
+#define /*void*/ v_write_memory16(/*vu8 **/ vmem_base, /*vu32*/ offset, \
+ /*vu16*/ data) \
+ (*(((vu16 *)(vmem_base))+(offset)))=(data)
+#define /*void*/ v_write_memory32(/*vu8 **/ vmem_base, /*vu32*/ offset, \
+ /*vu32*/ data) \
+ (*(((vu32 *)(vmem_base))+(offset)))=(data)
+#endif
+
+
+void v_enableio(void);
+void v_disableio(void);
+vu8 *v_mapmemory(vu8 *membase, vu32 size);
+void v_unmapmemory(vu8 *vmembase, vu32 size);
+
+struct v_board_t *v_findverite(void);
+
+
+
+#endif /* #ifndef _VOS_H_ */
+
+/*
+ * end of file vos.h
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/vramdac.c b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vramdac.c
new file mode 100644
index 000000000..2c21c992d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vramdac.c
@@ -0,0 +1,457 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/vramdac.c,v 1.3 1999/04/25 10:02:16 dawes Exp $ */
+/*
+ * includes
+ */
+
+#include "vramdac.h"
+#include "vos.h"
+#include "v1kregs.h"
+#include "xf86.h"
+
+/*
+#define XCONFIG_FLAGS_ONLY
+#include "xf86_Config.h"
+*/
+
+
+
+
+/*
+ * defines
+ */
+
+/* directly accessable RAMDAC registers */
+#define BT485_WRITE_ADDR 0x00
+#define BT485_RAMDAC_DATA 0x01
+#define BT485_PIXEL_MASK 0x02
+#define BT485_READ_ADDR 0x03
+#define BT485_CURS_WR_ADDR 0x04
+#define BT485_CURS_DATA 0x05
+#define BT485_COMMAND_REG_0 0x06
+#define BT485_CURS_RD_ADDR 0x07
+#define BT485_COMMAND_REG_1 0x08
+#define BT485_COMMAND_REG_2 0x09
+#define BT485_STATUS_REG 0x0a
+#define BT485_CURS_RAM_DATA 0x0b
+#define BT485_CURS_X_LOW 0x0c
+#define BT485_CURS_X_HIGH 0x0d
+#define BT485_CURS_Y_LOW 0x0e
+#define BT485_CURS_Y_HIGH 0x0f
+
+/* indirectly accessable ramdac registers */
+#define BT485_COMMAND_REG_3 0x01
+
+/* bits in command register 0 */
+#define BT485_CR0_EXTENDED_REG_ACCESS 0x80
+#define BT485_CR0_SCLK_SLEEP_DISABLE 0x40
+#define BT485_CR0_BLANK_PEDESTAL 0x20
+#define BT485_CR0_SYNC_ON_BLUE 0x10
+#define BT485_CR0_SYNC_ON_GREEN 0x08
+#define BT485_CR0_SYNC_ON_RED 0x04
+#define BT485_CR0_8_BIT_DAC 0x02
+#define BT485_CR0_SLEEP_ENABLE 0x01
+
+/* bits in command register 1 */
+#define BT485_CR1_24BPP 0x00
+#define BT485_CR1_16BPP 0x20
+#define BT485_CR1_8BPP 0x40
+#define BT485_CR1_4BPP 0x60
+#define BT485_CR1_1BPP 0x80
+#define BT485_CR1_BYPASS_CLUT 0x10
+#define BT485_CR1_565_16BPP 0x08
+#define BT485_CR1_555_16BPP 0x00
+#define BT485_CR1_1_TO_1_16BPP 0x04
+#define BT485_CR1_2_TO_1_16BPP 0x00
+#define BT485_CR1_PD7_PIXEL_SWITCH 0x02
+#define BT485_CR1_PIXEL_PORT_CD 0x01
+#define BT485_CR1_PIXEL_PORT_AB 0x00
+
+/* bits in command register 2 */
+#define BT485_CR2_SCLK_DISABLE 0x80
+#define BT485_TEST_PATH_SELECT 0x40
+#define BT485_PIXEL_INPUT_GATE 0x20
+#define BT485_PIXEL_CLK_SELECT 0x10
+#define BT485_INTERLACE_SELECT 0x08
+#define BT485_16BPP_CLUT_PACKED 0x04
+#define BT485_X_WINDOW_CURSOR 0x03
+#define BT485_2_COLOR_CURSOR 0x02
+#define BT485_3_COLOR_CURSOR 0x01
+#define BT485_DISABLE_CURSOR 0x00
+#define BT485_CURSOR_MASK 0x03
+
+/* bits in command register 3 */
+#define BT485_4BPP_NIBBLE_SWAP 0x10
+#define BT485_CLOCK_DOUBLER 0x08
+#define BT485_64_BY_64_CURSOR 0x04
+#define BT485_32_BY_32_CURSOR 0x00
+#define BT485_SIZE_MASK 0x04
+
+/* special constants for the Brooktree BT485 RAMDAC */
+#define BT485_INPUT_LIMIT 110000000
+
+
+
+/*
+ * local function prototypes
+ */
+
+static void Bt485_write_masked(vu16 port, vu8 reg, vu8 mask, vu8 data);
+static void Bt485_write_cmd3_masked(vu16 port, vu8 mask, vu8 data);
+static vu8 Bt485_read_masked(vu16 port, vu8 reg, vu8 mask);
+static vu8 Bt485_read_cmd3_masked(vu16 port, vu8 mask);
+
+
+
+/*
+ * global data
+ */
+
+int Cursor_size=0;
+
+
+
+/*
+ * functions
+ */
+
+/*
+ * int v_initdac(struct v_board_t *board, vu8 bpp, vu8 doubleclock)
+ *
+ * Used to initialize the ramdac. Palette-bypass is dis-/enabled with respect
+ * to the color depth, the cursor is disabled by default. If needed (i.e. if
+ * the corresponding field in the v_board_t struct is set), the clock doubling
+ * is turned on.
+ */
+int v_initdac(struct v_board_t *board, vu8 bpp, vu8 doubleclock)
+{
+ vu16 iob=board->io_base+RAMDACBASEADDR;
+ vu8 cmd3_data=0;
+
+ if (doubleclock)
+ cmd3_data|=BT485_CLOCK_DOUBLER;
+
+ switch (bpp) {
+ case 1:
+ case 4:
+ ErrorF("%s %s: color depth %d not (yet ?) supported\n",
+ X_CONFIG, /*vga256InfoRec.name*/"Rendition", bpp);
+ return -1;
+
+ case 8:
+ v_out8(iob+BT485_COMMAND_REG_0, BT485_CR0_EXTENDED_REG_ACCESS );
+ v_out8(iob+BT485_COMMAND_REG_1, BT485_CR1_8BPP |
+ BT485_CR1_PIXEL_PORT_AB);
+ v_out8(iob+BT485_COMMAND_REG_2, BT485_PIXEL_INPUT_GATE |
+ BT485_DISABLE_CURSOR);
+ break;
+
+ case 15:
+ v_out8(iob+BT485_COMMAND_REG_0, BT485_CR0_EXTENDED_REG_ACCESS |
+ BT485_CR0_8_BIT_DAC);
+ v_out8(iob+BT485_COMMAND_REG_1, BT485_CR1_16BPP |
+ BT485_CR1_BYPASS_CLUT |
+ BT485_CR1_555_16BPP |
+ BT485_CR1_2_TO_1_16BPP |
+ BT485_CR1_PIXEL_PORT_AB);
+ v_out8(iob+BT485_COMMAND_REG_2, BT485_PIXEL_INPUT_GATE |
+ BT485_DISABLE_CURSOR);
+ break;
+
+ case 16:
+ v_out8(iob+BT485_COMMAND_REG_0, BT485_CR0_EXTENDED_REG_ACCESS |
+ BT485_CR0_8_BIT_DAC);
+ v_out8(iob+BT485_COMMAND_REG_1, BT485_CR1_16BPP |
+ BT485_CR1_BYPASS_CLUT |
+ BT485_CR1_565_16BPP |
+ BT485_CR1_2_TO_1_16BPP |
+ BT485_CR1_PIXEL_PORT_AB);
+ v_out8(iob+BT485_COMMAND_REG_2, BT485_PIXEL_INPUT_GATE |
+ BT485_DISABLE_CURSOR);
+ break;
+
+ case 32:
+ v_out8(iob+BT485_COMMAND_REG_0, BT485_CR0_EXTENDED_REG_ACCESS |
+ BT485_CR0_8_BIT_DAC);
+ v_out8(iob+BT485_COMMAND_REG_1, BT485_CR1_24BPP |
+ BT485_CR1_BYPASS_CLUT |
+ BT485_CR1_PIXEL_PORT_AB);
+ v_out8(iob+BT485_COMMAND_REG_2, BT485_PIXEL_INPUT_GATE |
+ BT485_DISABLE_CURSOR);
+ break;
+
+ default:
+ ErrorF( "%s %s: Color depth not supported (%d bpp)\n",
+ X_CONFIG, /*vga256InfoRec.name*/"Rendition", bpp);
+ return -1;
+ break;
+ }
+
+ v_out8(iob+BT485_WRITE_ADDR, BT485_COMMAND_REG_3);
+ v_out8(iob+BT485_STATUS_REG, cmd3_data);
+/*
+ Bt485_write_masked(iob, BT485_COMMAND_REG_0, 0x7f, 0x00);
+*/
+ v_out8(iob+BT485_PIXEL_MASK, 0xff);
+
+ return 0;
+}
+
+
+
+/*
+ * void v_enablecursor(struct v_board_t *board, int type, int size)
+ *
+ * Used to enable the hardware cursor. Size indicates, whether to use no cursor
+ * at all, a 32x32 or a 64x64 cursor. The type selects a two-color, three-color
+ * or X-window-like cursor. Valid values are defined in vramdac.h.
+ */
+void v_enablecursor(struct v_board_t *board, int type, int size)
+{
+ static vu8 ctypes[]={ BT485_DISABLE_CURSOR, BT485_2_COLOR_CURSOR,
+ BT485_3_COLOR_CURSOR, BT485_X_WINDOW_CURSOR };
+ static vu8 csizes[]={ BT485_32_BY_32_CURSOR, BT485_64_BY_64_CURSOR };
+
+ vu16 iob=board->io_base+RAMDACBASEADDR;
+
+ /* ensure proper ranges */
+ type&=3;
+ size&=1;
+
+ /* type goes to command register 2 */
+ Bt485_write_masked(iob, BT485_COMMAND_REG_2, ~BT485_CURSOR_MASK,
+ ctypes[type]);
+
+ /* size is in command register 3 */
+ Bt485_write_cmd3_masked(iob, ~BT485_SIZE_MASK, csizes[size]);
+
+ if (type)
+ Cursor_size=(size ? 64 : 32);
+}
+
+
+
+
+/*
+ * void v_movecursor(struct v_board_t *board, vu16 x, vu16 y, vu8 xo, vu8 yo)
+ *
+ * Moves the cursor to the specified location. To hide the cursor, call
+ * this routine with x=0x0 and y=0x0.
+ */
+void v_movecursor(struct v_board_t *board, vu16 x, vu16 y, vu8 xo, vu8 yo)
+{
+ vu16 iob=board->io_base+RAMDACBASEADDR;
+
+ x+=Cursor_size-xo;
+ y+=Cursor_size-yo;
+
+ v_out8(iob+BT485_CURS_X_LOW, x&0xff);
+ v_out8(iob+BT485_CURS_X_HIGH, (x>>8)&0x0f);
+ v_out8(iob+BT485_CURS_Y_LOW, y&0xff);
+ v_out8(iob+BT485_CURS_Y_HIGH, (y>>8)&0x0f);
+}
+
+
+
+/*
+ * void v_setcursorcolor(struct v_board_t *board, vu32 fg, vu32 bg)
+ *
+ * Sets the color of the cursor -- should be revised for use with 3 colors!
+ */
+void v_setcursorcolor(struct v_board_t *board, vu32 fg, vu32 bg)
+{
+ vu16 iob=board->io_base+RAMDACBASEADDR;
+
+ /* load the cursor color 0, i.e. overscan */
+ v_out8(iob+BT485_CURS_WR_ADDR, 0x00);
+ v_out8(iob+BT485_CURS_DATA, 0x00);
+ v_out8(iob+BT485_CURS_DATA, 0x00);
+ v_out8(iob+BT485_CURS_DATA, 0x00);
+
+ /* load the cursor color 1 */
+ v_out8(iob+BT485_CURS_DATA, bg&0xff);
+ v_out8(iob+BT485_CURS_DATA, (bg>>8)&0xff);
+ v_out8(iob+BT485_CURS_DATA, (bg>>16)&0xff);
+
+ /* load the cursor color 2 */
+ v_out8(iob+BT485_CURS_DATA, fg&0xff);
+ v_out8(iob+BT485_CURS_DATA, (fg>>8)&0xff);
+ v_out8(iob+BT485_CURS_DATA, (fg>>16)&0xff);
+
+}
+
+
+
+/*
+ * Oh god, this code is quite a mess ... should be re-written soon.
+ * But for now I'm happy it works ;) <ml>
+ */
+void v_loadcursor(struct v_board_t *board, vu8 size, vu8 *cursorimage)
+{
+ int c, bytes, row;
+ vu8 *src;
+ vu16 iob=board->io_base+RAMDACBASEADDR;
+ vu8 tmp;
+
+ if (NULL == cursorimage)
+ return;
+
+ size&=1;
+ if (size)
+ bytes=64;
+ else
+ bytes=32;
+ bytes=(bytes*bytes)/8;
+
+ if (board->chip == V1000_DEVICE) {
+ /* now load the cursor data into the cursor ram */
+/*
+ Bt485_write_cmd3_masked(iob, 0xfc, 0x00);
+ Bt485_write_masked(iob, BT485_COMMAND_REG_0, 0x7d, 0x00);
+*/
+ /*Bt485_write_masked(iob, BT485_COMMAND_REG_0, 0x7f, 0x80);*/
+ tmp=v_in8(iob+BT485_COMMAND_REG_0)&0x7f;
+ v_out8(iob+BT485_COMMAND_REG_0, tmp|0x80);
+ v_out8(iob+BT485_WRITE_ADDR, BT485_COMMAND_REG_3);
+ /*Bt485_write_masked(iob, BT485_STATUS_REG, 0xfc, size<<2);*/
+ tmp=v_in8(iob+BT485_STATUS_REG)&0xf8;
+ v_out8(iob+BT485_STATUS_REG, tmp|(size<<2));
+ v_out8(iob+BT485_WRITE_ADDR, 0x00);
+
+ /* output cursor image */
+ src=cursorimage+1;
+
+ for (c=0; c<bytes; c++) {
+ v_out8(iob+BT485_CURS_RAM_DATA, *src);
+ src+=2;
+ }
+
+/*
+ tmp=v_in8(iob+BT485_STATUS_REG)&0xf8;
+ v_out8(iob+BT485_STATUS_REG, tmp|(size<<2)|(1<<size));
+ if (size)
+ v_out8(iob+BT485_WRITE_ADDR, 0x00);
+*/
+
+ src=cursorimage;
+ for (c=0; c<bytes; c++) {
+ v_out8(iob+BT485_CURS_RAM_DATA, *src);
+ src+=2;
+ }
+ } else { /* V2x00 */
+ v_out32(iob+0xAC /* CURSORBASE - v2k */, 0);
+ for (row=0; row<64; row++)
+ for (c=0, src=cursorimage+1+16*row; c<8; c++, src+=2)
+ v_write_memory8(board->vmem_base, 16*(63-row)+c,
+ (c&1)?(*(src-2)):(*(src+2)));
+
+ for (row=0; row<64; row++)
+ for (c=0, src=cursorimage+16*row; c<8; c++, src+=2)
+ v_write_memory8(board->vmem_base, 8+16*(63-row)+c,
+ (c&1)?(*(src-2)):(*(src+2)));
+ }
+}
+
+
+
+/* NOTE: count is the actual number of colors decremented by 1 */
+void v_setpalette(struct v_board_t *board, vu8 start, vu8 count, vu8 *table)
+{
+ vu16 iob=board->io_base;
+ vu32 crtc_status;
+ int c;
+
+ while (1) {
+ crtc_status=v_in32(iob+CRTCSTATUS);
+ if (crtc_status & CRTCSTATUS_VERT_SYNC)
+ break;
+ };
+
+ iob+=RAMDACBASEADDR;
+
+ if (((int)start+count) > 255)
+ count=255-start;
+
+ v_out8(iob+BT485_WRITE_ADDR, start);
+
+ for (c=0; c<=count; c++) {
+ v_out8(iob+BT485_RAMDAC_DATA, *table++);
+ v_out8(iob+BT485_RAMDAC_DATA, *table++);
+ v_out8(iob+BT485_RAMDAC_DATA, *table++);
+ }
+}
+
+
+
+
+/*
+ * local functions
+ */
+
+/*
+ * static void Bt485_write_masked(vu16 port, vu8 reg, vu8 mask, vu8 data)
+ *
+ *
+ */
+static void Bt485_write_masked(vu16 port, vu8 reg, vu8 mask, vu8 data)
+{
+ vu8 tmp;
+
+ tmp=v_in8(port+reg)&mask;
+ v_out8(port+reg, tmp|data);
+}
+
+
+
+/*
+ * static void Bt485_write_cmd3_masked(vu16 port, vu8 mask, vu8 data)
+ *
+ *
+ */
+static void Bt485_write_cmd3_masked(vu16 port, vu8 mask, vu8 data)
+{
+/*
+ Bt485_write_masked(port, BT485_COMMAND_REG_0, 0x7f, 0x80);
+*/
+ v_out8(port+BT485_WRITE_ADDR, BT485_COMMAND_REG_3);
+ Bt485_write_masked(port, BT485_STATUS_REG, mask, data);
+/*
+ Bt485_write_masked(port, BT485_COMMAND_REG_0, 0x7f, 0x00);
+*/
+}
+
+
+
+/*
+ * static vu8 Bt485_read_masked(vu16 port, vu8 reg, vu8 mask)
+ *
+ *
+ */
+static vu8 Bt485_read_masked(vu16 port, vu8 reg, vu8 mask)
+{
+ return v_in8(port+reg)&mask;
+}
+
+
+
+/*
+ * static vu8 Bt485_read_cmd3_masked(vu16 port, vu8 mask)
+ *
+ *
+ */
+static vu8 Bt485_read_cmd3_masked(vu16 port, vu8 mask)
+{
+ vu8 value;
+
+ Bt485_write_masked(port, BT485_COMMAND_REG_0, 0x7f, 0x80);
+ v_out8(port+BT485_WRITE_ADDR, BT485_COMMAND_REG_3);
+ value=Bt485_read_masked(port, BT485_STATUS_REG, mask);
+ Bt485_write_masked(port, BT485_COMMAND_REG_0, 0x7f, 0x00);
+
+ return value;
+}
+
+
+
+/*
+ * end of file vramdac.c
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/vramdac.h b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vramdac.h
new file mode 100644
index 000000000..a2a821b36
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vramdac.h
@@ -0,0 +1,52 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/vramdac.h,v 1.2 1999/04/17 07:06:44 dawes Exp $ */
+/*
+ * file vramdac.h
+ *
+ * headfile for vramdac.c
+ */
+
+#ifndef _VRAMDAC_H_
+#define _VRAMDAC_H_
+
+
+
+/*
+ * includes
+ */
+
+#include "vtypes.h"
+
+
+
+/*
+ * defines
+ */
+
+#define V_NOCURSOR 0
+#define V_2COLORS 1
+#define V_3COLORS 2
+#define V_XCURSOR 3
+
+#define V_CURSOR32 0
+#define V_CURSOR64 1
+
+
+
+/*
+ * function prototypes
+ */
+
+int v_initdac(struct v_board_t *board, vu8 bpp, vu8 doubleclock);
+void v_enablecursor(struct v_board_t *board, int type, int size);
+void v_movecursor(struct v_board_t *board, vu16 x, vu16 y, vu8 xo, vu8 yo);
+void v_setcursorcolor(struct v_board_t *board, vu32 fg, vu32 bg);
+void v_loadcursor(struct v_board_t *board, vu8 type, vu8 *cursorimage);
+void v_setpalette(struct v_board_t *board, vu8 start, vu8 count, vu8 *table);
+
+
+
+#endif /* #ifndef _VRAMDAC_H_ */
+
+/*
+ * end of file vramdac.h
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/vtypes.h b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vtypes.h
new file mode 100644
index 000000000..6c24a558b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vtypes.h
@@ -0,0 +1,146 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/vtypes.h,v 1.2 1999/04/17 07:06:45 dawes Exp $ */
+#ifndef _VTYPES_H_
+#define _VTYPES_H_
+
+
+
+/*
+ * includes
+ */
+
+#if 0
+#include <sys/types.h>
+#endif
+#include "Xmd.h"
+
+
+/*
+ * defines
+ */
+
+/* chip types */
+#define V1000_DEVICE 0x0001
+#define V2000_DEVICE 0x2000
+
+#define FBOFFSET 0x0 /* for now <ml> */
+/*
+#define FBOFFSET 0x10000
+*/
+
+#define XSERVER
+
+
+
+/*
+ * typedefs
+ */
+
+/* generic type definitions for central services */
+typedef CARD32 vu32;
+typedef CARD16 vu16;
+typedef CARD8 vu8;
+typedef INT32 vs32;
+typedef INT16 vs16;
+typedef INT8 vs8;
+#ifdef __alpha__
+typedef unsigned long vu64;
+typedef long vs64;
+#endif
+
+typedef enum {
+ V_PIXFMT_DSTFMT=0,
+ V_PIXFMT_332=1, /**/
+#define V_PIXFMT_233 V_PIXFMT_332
+ V_PIXFMT_8I=2, /**/
+ V_PIXFMT_8A=3,
+ V_PIXFMT_565=4, /**/
+ V_PIXFMT_4444=5, /**/
+ V_PIXFMT_1555=6, /**/
+ /* 7 reserved */
+ V_PIXFMT_4I_565=8,
+ V_PIXFMT_4I_4444=9,
+ V_PIXFMT_4I_1555=10,
+ /* 11 reserved */
+ V_PIXFMT_8888=12, /**/
+ V_PIXFMT_Y0CRY1CB=13
+#define V_PIXFMT_Y0CBY1CR V_PIXFMT_Y0CRY1CB
+ /* 14 reserved */
+ /* 15 reserved */
+} vpixfmt;
+
+
+
+/*
+ * structs
+ */
+
+struct v_modeinfo_t {
+ int clock; /* pixel clock */
+ int hdisplay; /* horizontal timing */
+ int hsyncstart;
+ int hsyncend;
+ int htotal;
+ int hskew;
+ int vdisplay; /* vertical timing */
+ int vsyncstart;
+ int vsyncend;
+ int vtotal;
+ int screenwidth; /* further mode information */
+ int virtualwidth;
+ int screenheight;
+ int virtualheight;
+ int bitsperpixel;
+ int hsynchi;
+ int vsynchi;
+ int pixelformat; /* set by the mode init routines */
+ int fifosize;
+ vu8 pll_n;
+ vu8 pll_m;
+ vu8 pll_p;
+ vu8 refresh;
+ vu8 doubleclock;
+ vu16 stride0;
+ vu16 stride1;
+};
+
+
+
+/* structure describing the Verite board and its functionality */
+struct v_board_t {
+ /* type of chip */
+ vu16 chip;
+ vu8 accel;
+
+ /* */
+ vu16 io_base;
+ vu32 mmio_base;
+ vu32 vmmio_base;
+ vu32 mem_size;
+ vu8 *mem_base;
+ vu8 *vmem_base;
+ vu8 init;
+
+ /* */
+ vu32 csucode_base;
+ vu32 ucode_base;
+ vu32 ucode_entry;
+ vu32 cursor_base;
+
+ /* mode information */
+ struct v_modeinfo_t mode;
+
+ /* saved text mode settings */
+ vu8 cursor_hi;
+ vu8 cursor_low;
+ vu8 offset_hi;
+ vu8 offset_low;
+ vu8 *scr_contents;
+};
+
+
+
+#endif /* #ifndef _VTYPES_H_ */
+
+/*
+ * end of file vtypes.h
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/vvga.c b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vvga.c
new file mode 100644
index 000000000..0908227b1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vvga.c
@@ -0,0 +1,349 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/vvga.c,v 1.5 1999/04/25 10:02:16 dawes Exp $ */
+/*
+ * file vvga.c
+ *
+ * Functions that handle the generic vga part of the Verite chips.
+ */
+
+
+
+/*
+ * includes
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "vvga.h"
+#include "vtypes.h"
+#include "vos.h"
+#include "v1kregs.h"
+#include "v2kregs.h"
+
+void set_PLL(vu16, vu32);
+
+/*
+ * global data
+ */
+
+#ifdef STDVGAFONT
+#include "vgafont-std.data"
+#else
+#include "vgafont-vrx.data"
+#endif
+#include "vgapalette.data"
+
+#ifdef __alpha__
+void v_bustomem(vu8 *dst, vu8 *src, vu32 num)
+{
+ int i;
+ for (i=0; i<num; i++)
+ dst[i] = v_read_memory8(src, i);
+}
+
+void v_memtobus(vu8 *dst, vu32 offset, vu8 *src, vu32 num)
+{
+ int i;
+ for (i=0; i<num; i++)
+ v_write_memory8(dst, offset+i, src[i]);
+}
+#else
+#define v_bustomem(dst, src, num) memcpy(dst,src,num)
+#define v_memtobus(dst, offset, src, num) memcpy((dst)+(offset),src,num)
+#endif
+
+/*
+ * local function prototypes
+ */
+
+static vu8 getvgareg(vu16 port, vu8 index);
+static void setvgareg(vu16 port, vu8 index, vu8 value);
+static void updattr(vu8 index, vu8 value);
+
+
+
+/*
+ * functions
+ */
+
+void v_resetvga(void)
+{
+ static struct VIDEO_REGS {
+ vu8 seq[8]; /* sequencer regs */
+ vu8 crtc[26]; /* crtc regs */
+ vu8 grph[9]; /* graphics regs */
+ vu8 attr[21]; /* attribute regs */
+ } mode3={
+ /* seq */
+ {0x03,0x00,0x03,0x00,0x02,0xfa,0x01,0xfa},
+
+ /* crtc */
+ {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+ 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x01,0xe0,
+ 0x9c,0xae,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+ 0xff,0x19},
+
+ /* grph */
+ {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,0xff},
+
+ /* attr */
+ {0x00,0x01,0x02,0x03,0x04,0x05,0x14,
+ 0x07,0x38,0x39,0x3a,0x3b,0x3c,0x3d,
+ 0x3e,0x3f,0x0c,0x00,0x0f,0x08,0x00},
+ };
+ int c;
+
+ /* set attribute controller */
+ for (c=0; c<0x15; c++)
+ updattr(c, mode3.attr[c]);
+
+ /* set CRTC registers */
+ for (c=0; c<0x19; c++)
+ setvgareg(0x3d4, c, mode3.crtc[c]);
+
+ /* set graphics registers */
+ for (c=0x00; c<0x09; c++)
+ setvgareg(0x3ce, c, mode3.grph[c]);
+
+ /* set sequencer registers */
+ setvgareg(0x3c4, 0x00, 0x03); /* restart sequencer */
+ for (c=0; c<5; c++)
+ setvgareg(0x3c4, c, mode3.seq[c]);
+}
+
+
+
+void v_loadvgafont(void)
+{
+ int c;
+ vu8 b;
+ vu8 *address;
+ vu8 *vidmem;
+ vu8 *vbase;
+ int fbFlags;
+
+ /* Assert synchroneous reset while setting the clock mode */
+ setvgareg(0x3c4, 0, 1); /* assert synchronous reset */
+ v_out8(0x3c2, 0x67); /* select clock */
+ setvgareg(0x3c4, 0, 3); /* de-assert synchronous reset */
+
+ /* load 8x16 font into plane 2 */
+ b=(getvgareg(0x3c4, 0x04)|0x04)&0x07; /* memory mode reg - */
+ setvgareg(0x3c4, 0x04, b); /* disable odd/even and chain 4 */
+
+ /* disable video and enable all to cpu to enable maximum video
+ * memory access */
+ b=getvgareg(0x3c4, 0x01)|0x20; /* clocking mode register - */
+ setvgareg(0x3c4, 0x01, b); /* enable all to cpu, disable video */
+
+ b=getvgareg(0x3ce, 0x05)&0xef; /* graphics controller - */
+ setvgareg(0x3ce, 0x05, b); /* disable odd/even */
+
+ setvgareg(0x3ce, 0x06, 0x05); /* memory map - set it to A000
+ * and graphics mode */
+
+ setvgareg(0x3c4, 2, 4); /* enable write plane 2 */
+
+ /* fill plane 2 with 8x16 font */
+ address=font8x16;
+#if defined(__alpha__)
+ fbFlags = VIDMEM_FRAMEBUFFER | VIDMEM_SPARSE;
+#else
+ fbFlags = VIDMEM_FRAMEBUFFER;
+#endif
+ vbase = xf86MapVidMem(0, fbFlags, 0xa0000, 64*1024);
+ vidmem=vbase;
+ for (c=0; c<=255; c++) {
+ v_memtobus(vbase, 32*c, address, 16);
+ address+=16;
+ }
+
+ xf86UnMapVidMem(0, vbase, 64*1024);
+
+ /* restore the standard vga register values */
+ v_resetvga();
+}
+
+
+
+void v_textmode(struct v_board_t *board)
+{
+ vu16 iob=board->io_base;
+ int tmp;
+
+ /* dac */
+ v_out8(iob+DACCOMMAND0, 0x80); /* 6 bit op, enable extended */
+ v_out8(iob+DACCOMMAND1, 0x68); /* disable palette bypass */
+ v_out8(iob+DACCOMMAND2, 0x00); /* disable cursor & pixel packing */
+ if (V1000_DEVICE == board->chip) {
+ v_out8(iob+DACRAMWRITEADR, 0x01); /* select COMMAND3 register */
+ v_out8(iob+DACCOMMAND3, 0x00); /* no clock doubling */
+ }
+ v_out8(iob+DACCOMMAND0, 0x00); /* 6 bit op */
+
+ if (V1000_DEVICE == board->chip) {
+ v_out32(iob+DRAMCTL, 0x140000);
+ set_PLL(iob, 0x40000);
+ usleep(500);
+ }
+ else {
+ /* memctl */
+ tmp = 0x1800|v_in32(iob+DRAMCTL);
+ v_out32(iob+DRAMCTL, tmp); /* linear mode */
+
+ /* pixel clock */
+ v_out32(iob+PCLKPLL, 0x300000);
+ /* system and memory clock */
+ v_out32(iob+SCLKPLL, 0x2480C); /* mclk=86 sclk=43 */
+
+ /* Need to wait 200uS for PLL to stabilize --
+ * let's play it safe with 500 */
+ usleep(500);
+
+ /* wait until VBLANK */
+ while ((v_in32(iob+CRTCSTATUS)&CRTCSTATUS_VERT_MASK) !=
+ CRTCSTATUS_VERT_ACTIVE);
+ while ((v_in32(iob+CRTCSTATUS)&CRTCSTATUS_VERT_MASK) ==
+ CRTCSTATUS_VERT_ACTIVE);
+ }
+
+ /* vga mode */
+ v_out8(iob+MODEREG, VGA_MODE);
+
+ /* crtc */
+ v_out32(iob+CRTCCTL, 0x44cc2);
+ v_out32(iob+CRTCHORZ, 0x2b0a4f);
+ v_out32(iob+CRTCVERT, 0x9301df);
+ v_out32(iob+CRTCOFFSET, 0x40);
+
+#ifdef SAVEVGA
+ v_loadvgafont();
+ v_restoretextmode(board);
+ v_restorepalette();
+#else
+#ifdef XSERVER
+ v_loadvgafont();
+ v_restorepalette();
+#endif
+#endif
+
+}
+
+
+
+void v_savetextmode(struct v_board_t *board)
+{
+ vu8 *vbase;
+ int fbFlags;
+
+ /* save the cursor position */
+ board->cursor_hi=getvgareg(0x3d4, 0xe);
+ board->cursor_low=getvgareg(0x3d4, 0xf);
+
+ /* save the screen offset */
+ board->offset_hi=getvgareg(0x3d4, 0xc);
+ board->offset_low=getvgareg(0x3d4, 0xd);
+
+ /* save the screen contents */
+ board->scr_contents=(vu8 *)xalloc(0x8000);
+#if defined(__alpha__)
+ fbFlags = VIDMEM_FRAMEBUFFER | VIDMEM_SPARSE;
+#else
+ fbFlags = VIDMEM_FRAMEBUFFER;
+#endif
+ vbase = xf86MapVidMem(0, fbFlags, 0xb8000, 0x8000);
+ v_bustomem(board->scr_contents, vbase, 0x8000);
+ xf86UnMapVidMem(0, vbase, 0x8000);
+}
+
+
+
+void v_restoretextmode(struct v_board_t *board)
+{
+ vu8 *vbase;
+ int fbFlags;
+
+ /* restore the cursor position */
+ setvgareg(0x3d4, 0xe, board->cursor_hi);
+ setvgareg(0x3d4, 0xf, board->cursor_low);
+
+ /* restore the screen offset */
+ setvgareg(0x3d4, 0xc, board->offset_hi);
+ setvgareg(0x3d4, 0xd, board->offset_low);
+
+ /* restore the screen contents */
+#if defined(__alpha__)
+ fbFlags = VIDMEM_FRAMEBUFFER | VIDMEM_SPARSE;
+#else
+ fbFlags = VIDMEM_FRAMEBUFFER;
+#endif
+ vbase = xf86MapVidMem(0, VIDMEM_FRAMEBUFFER, 0xb8000, 0x8000);
+ v_memtobus(vbase, 0, board->scr_contents, 0x8000);
+ xf86UnMapVidMem(0, vbase, 0x8000);
+ xfree(board->scr_contents);
+}
+
+
+
+void v_restorepalette(void)
+{
+ int c;
+ vu8 *pal=vga_pal;
+
+ v_out8(0x3c8, 0);
+ for (c=0; c<768; c++)
+ v_out8(0x3c9, *pal++);
+}
+
+
+
+/*
+ * local functions
+ */
+
+/*
+ * static vu8 getvgareg(vu16 port, vu8 index)
+ *
+ * Reads in a vga register.
+ */
+static vu8 getvgareg(vu16 port, vu8 index)
+{
+ v_out8(port, index);
+ return v_in8(port+1);
+}
+
+
+
+/*
+ * static void setvgareg(vu16 port, vu8 index, vu8 value)
+ *
+ * Sets a vga register.
+ */
+static void setvgareg(vu16 port, vu8 index, vu8 value)
+{
+ v_out8(port, index);
+ v_out8(port+1, value);
+}
+
+
+
+/*
+ * static void updattr(vu8 index, vu8 value)
+ *
+ * Used to write the attribute controller registers.
+ */
+static void updattr(vu8 index, vu8 value)
+{
+ v_in8(0x3da); /* points to index register for color adapter */
+ v_in8(0x3ba); /* points to index register for mono */
+ v_out8(0x3c0, index);
+ v_out8(0x3c0, value);
+ v_out8(0x3c0, index|0x20);
+}
+
+
+
+/*
+ * end of file vvga.c
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/rendition/vvga.h b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vvga.h
new file mode 100644
index 000000000..d54b3bb10
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/rendition/vvga.h
@@ -0,0 +1,38 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/rendition/vvga.h,v 1.2 1999/04/17 07:06:46 dawes Exp $ */
+/*
+ * file vvga.h
+ *
+ * Headerfile for vvga.c
+ */
+
+#ifndef _VVGA_H_
+#define _VVGA_H_
+
+
+
+/*
+ * includes
+ */
+
+#include "vtypes.h"
+
+
+
+/*
+ * function prototypes
+ */
+
+void v_resetvga(void);
+void v_loadvgafont(void);
+void v_textmode(struct v_board_t *board);
+void v_savetextmode(struct v_board_t *board);
+void v_restoretextmode(struct v_board_t *board);
+void v_restorepalette(void);
+
+
+
+#endif /* #ifndef _VVGA_H_ */
+
+/*
+ * end of file vvga.h
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/CALLMAP b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/CALLMAP
new file mode 100644
index 000000000..b6d1b3fee
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/CALLMAP
@@ -0,0 +1,23 @@
+-- Only Once, calling order --
+ChipIdentify (S3VIdentify)
+ChipProbe (S3VProbe)
+ Passive only, no ram determination, no writing
+
+-- For each ScrnInfoRec, still calling order --
+ChipPreInit (S3VPreInit)
+ Allows probing and mapping, hardware must remain unchanged
+ ChipGetRec
+
+ChipScreenInit
+ ChipMapMem
+ ChipSave
+ vgaHWSaveMMIO
+ ChipModeInit
+ vtSema=TRUE
+ ChipWriteMode
+ vgaHWRestoreMMIO
+
+
+
+
+$XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/CALLMAP,v 1.2 1998/11/22 10:37:28 dawes Exp $
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/Imakefile
new file mode 100644
index 000000000..330cd5793
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/Imakefile
@@ -0,0 +1,63 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/Imakefile,v 1.13 1999/08/28 09:01:08 dawes Exp $
+/*
+ *
+ * Copyright 1995-1998 The XFree86 Project, Inc.
+ *
+ */
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = s3v_driver.c s3v_accel.c s3v_dac.c s3v_hwcurs.c s3v_dga.c s3v_i2c.c
+
+OBJS = s3v_driver.o s3v_accel.o s3v_dac.o s3v_hwcurs.o s3v_dga.o s3v_i2c.o
+
+DEFINES = -DPSZ=8
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \
+ -I$(XF86SRC)/xf1bpp -I$(XF86SRC)/xf4bpp \
+ -I$(XF86SRC)/xf24_32bpp -I$(SERVERSRC)/Xext \
+ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \
+ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
+ -I$(XF86SRC)/rac \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(FONTINCSRC) \
+ -I$(EXTINCSRC)
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+NormalAsmObjectRule()
+
+ModuleObjectRule()
+ObjectModuleTarget(s3virge, $(OBJS))
+
+InstallObjectModule(s3virge,$(MODULEDIR),drivers)
+
+#if !defined(XF86DriverSDK)
+CppManTarget(s3virge,)
+InstallModuleManPage(s3virge)
+#endif
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/s3virge)
+InstallDriverSDKNonExecFile(newmmio.h,$(DRIVERSDKDIR)/drivers/s3virge)
+InstallDriverSDKNonExecFile(regs3v.h,$(DRIVERSDKDIR)/drivers/s3virge)
+InstallDriverSDKNonExecFile(s3v.h,$(DRIVERSDKDIR)/drivers/s3virge)
+InstallDriverSDKNonExecFile(s3v_accel.c,$(DRIVERSDKDIR)/drivers/s3virge)
+InstallDriverSDKNonExecFile(s3v_dac.c,$(DRIVERSDKDIR)/drivers/s3virge)
+InstallDriverSDKNonExecFile(s3v_dga.c,$(DRIVERSDKDIR)/drivers/s3virge)
+InstallDriverSDKNonExecFile(s3v_driver.c,$(DRIVERSDKDIR)/drivers/s3virge)
+InstallDriverSDKNonExecFile(s3v_hwcurs.c,$(DRIVERSDKDIR)/drivers/s3virge)
+InstallDriverSDKNonExecFile(s3v_i2c.c,$(DRIVERSDKDIR)/drivers/s3virge)
+InstallDriverSDKNonExecFile(s3v_macros.h,$(DRIVERSDKDIR)/drivers/s3virge)
+InstallDriverSDKNonExecFile(s3v_rop.h,$(DRIVERSDKDIR)/drivers/s3virge)
+
+InstallDriverSDKObjectModule(s3virge,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/README b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/README
new file mode 100644
index 000000000..ae754b4e6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/README
@@ -0,0 +1,70 @@
+
+What works:
+- Supports 8bpp, 15/16bpp, 24bpp and 32bpp. Tested on ViRGE DX
+
+XCONFIG options:
+
+The driver supports quite a few different XConfig options, which can
+be used to tune the driver and improve performance. Without any options,
+the driver will use conservative settings which should work on most
+hardware. Large improvements in performance are possible by selecting
+the proper options, which will probably work on most systems.
+
+Cursor:
+
+- "hwcursor" "off" behaves exactly like "swcursor". Default: "on"
+- "swcursor" will disable the HW Cursor. HW Cursor is used by default and
+ no option is needed to enable it.
+
+Video memory:
+
+- "slow_edodram" will switch the standard ViRGE to 2-cycle edo mode. Try this
+ if you encounter pixel corruption on the ViRGE. Using this option will
+ cause a large decrease in performance.
+- "fpm_vram" will switch the ViRGE/VX to fast page mode vram mode
+- "early_ras_precharge", "late_ras_precharge" adjust memory parameters. One
+ of these will us the same settings as your video card defaults, and
+ using neither in the config file does the same.
+- "set_mclk" sets the memory clock, format is:
+ Option "set_mclk" "50000"
+ in the XF86Config file. Valid values are any
+ integer <= 100000, where 100000 == 100 MHz.
+
+Acceleration and graphic engine:
+
+- "NoAccel" turns off all acceleration
+- "fifo_aggressive", "fifo_moderate" and "fifo_conservative" alter the settings
+ for the threshold at which the pixel FIFO takes over the internal
+ memory bus to refill itself. The smaller this threshold, the better
+ the acceleration performance of the card. You may try the fastest
+ setting ("aggressive") and move down if you encounter pixel corruption.
+ The optimal setting will probably depend on dot-clock and on color
+ depth. Note that specifying any of these options will also alter other
+ memory settings which should increase performance, so you should at
+ least use "fifo_conservative" (this uses the chip defaults).
+- Common XAA acceleration options to disable primitives for test purposes:
+ "XaaNoScreenToScreenCopy"
+ "XaaNoSolidFillRect"
+ "XaaNoColor8x8PatternFillRect"
+ "XaaNoImageWriteRect"
+ "XaaNoPixmapCache"
+
+PCI bus:
+- "pci_burst" will enable PCI burst mode. This should work on all but a
+ few "broken" PCI chipsets, and will increase performance. Option may
+ take a parameter "on", "off", "yes", etc...
+- "pci_retry" will allow the driver to rely on PCI Retry to program the
+ ViRGE registers. "pci_burst" must be enabled for this to work.
+ This will increase performance, especially for small fills/blits,
+ because the driver does not have to poll the ViRGE before sending it
+ commands to make sure it is ready. It should work on most
+ recent PCI chipsets.
+
+ViRGE MX LCD options:
+- "lcd_center"
+- "set_lcdclk" allows setting the clock for a ViRGE MX LCD display. Format is:
+ Option "set_lcdclk" "30000"
+ in the config file. Valid values are ?
+
+
+$XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/README,v 1.7 1999/04/04 08:46:16 dawes Exp $
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/TODO_NOTES b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/TODO_NOTES
new file mode 100644
index 000000000..d7322dbb3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/TODO_NOTES
@@ -0,0 +1,184 @@
+S3 ViRGE 4.0 devel notes
+
+rev:
+26 Jun 1999 KJB
+
+
+Function Implemented
+-------- -----------
+-required-
+S3VProbe; X
+S3VPreInit; X
+S3VScreenInit; X
+S3VSwitchMode; X
+S3VAdjustFrame; X
+S3VEnterVT; X
+S3VLeaveVT; X
+S3VFreeScreen; X
+S3VValidMode; X - dummy
+-private-
+S3VSave X
+S3VRestore X
+
+
+Status
+------
+6/26/99 KJB
+Make the memory settings for fifo_conservative the default, 'fifo_conservative'
+does nothing additional now. Patch includes DGA2 additions below, non-working.
+Expected to be included in 3.9Pu.
+
+Changes in 3.9Pt by others include additions for newer RAC support. Some reports
+say multi-head works now with ViRGE.
+
+6/17/99 KJB
+Ver 0.9.0 - Prelim DGA2 support modeled after MGA.
+
+5/28/99 KJB
+Ver 0.8.0 - Changes to 3.9Po - Cleaned up debug register printing function, minor
+changes to man page, remove S3V.sgml and add new s3virge.sgml in doc/sgml, also
+remove README.S3V from doc directory.
+
+
+4/5/99 KJB
+3.9Ph - Ver 0.7.0 - Virge man page added, HW Cursor fixed, rename chipsets removing
+slashes in the names.
+
+03/27/99 KJB
+Ver 0.6.0 - hwcursor additions, added s3v_hwcurs.c and Option "swcursor".
+Default is hwcursor, Option "swcursor" will disable it.
+
+Ver 0.5.0 - patch against 3.9Pf (seq 2615), fix depth 24 and Accel flags, sync pci_burst option to previous changes, remove s3v_comp.h and s3v_pio.c and merge as needed.
+
+03/21/99 KJB
+3.9Pf has Matt Grossman's Alpha changes.
+For next patch - remove s3v_pio.c and s3v_comp.h. Include the EnableMMIO and
+DisableMMIO functions from s3v_pio.c in s3v_driver.c.
+
+03/02/99 KJB
+3.9Pc - depth 24 doesn't work on my ViRGE DX. NoAccel doesn't start, accel does
+but has blocky noise.
+
+03/01/99 KJB
+Macro change done, VGAIN/VGAOUT for register access, INREG/OUTREG for s3v_accel.c.
+Added Mark Vojkovich's re-write of the accel code. It may only be clean for ViRGE DX
+at the moment. x11perf showed a couple artifacts in 'move window via parent'.
+In progress, attempt to call cfbScreenInit() functions after MapMem/EnterVT. Not
+working yet. Version stamped 0.4.0.
+
+02/22/99 KJB
+Macro change coming to add Mark's accel update. VGAOUT for old stuff and MEMOUT
+for new stuff? That way there's no confusion with the old INREG/OUTREG macros.
+Or maybe just stick with INREG/OUTREG for new stuff.
+
+01/30/99 KJB
+Version stamp 0.3.0. Changed Chipset flags to use PCI IDs exclusively, also use
+common/xf86PciInfo.h for PCI IDs rather than coding them in regs3v.h.
+
+11/28/98 KJB
+Bumped version stamp to 0.2, expect code in 3.9No. Cleaned up s3v.h and
+s3v_driver.c by removing unused definition & code sections. Added
+options set_mclk (from 3.3.2) and set_lcdclk (3.3.3 MX). Code support
+from 3.3.3 for ViRGE GX2 and MX+ is included.
+Disabled call to 32 bpp AccelInit to get -depth 24 -bpp 32 working again.
+
+11/27/98 KJB
+More 3.3.3 import.
+New registers saved, CR40,CR45,SR8,(for MX) SR29,SR45,SR55,SR56,SR57.
+Reviewed s3vdriver.h, rehs3v.h, newmmio.h, s3v_accel.c, s3v_driver.c.
+Added ViRGE MX, MX+ & GX2 support. Re-synced parts of mode save and init
+with 3.3.3 versions. Added timeout ability for WaitIdle() and friends.
+Added chipnames and numbers to Chipsets struct.
+
+11/26/98 KJB
+Import additions from 3.3.3, newmmio.h, regs3v.h,
+
+Trap fills disabled because they don't match cfb, pixmap cache & ImageWrite
+working, fixed depth 8 color loss on VT switches, INREG & OUTREG modified to
+use a single offset value instead of adding the base and offset together.
+
+11/18/98 KJB
+3.9Nn
+Acceleration working for Bitblt, ScreenToScreenCopy, Color 8x8 Rect fills,
+and Rect/Trap fills.
+Trap fills do not support transparency, so that needs to be exported to XAA.
+
+
+10/31/98 KJB
+Working depth 8, discolored dep 16 but runs, dep 24 screen goes black,
+C-A-Bkspc restores text console. At 3.9Nk tree level, module would not
+load in Loader server. why? Static server tested.
+
+10/29/98 KJB
+ModeInit() needs work, options are heavily #if'd to try and get 8bpp
+working.
+
+10/16/98 KJB
+General 4.0 architecture is setup. Presently at 3.9Nc level, if moved
+to a newer tree you will need to add the resource handling functions from
+Egbert (I haven't tackled that yet).
+
+At the moment the ScreenInit() function is coded to return FALSE. On my
+ViRGE DX card this version does not lock up, but it does destroy the
+video mode. Make sure you have an external terminal or network connection
+if you run it (or blindly do a restart from your main terminal). I make
+no guarantees that it won't hard lock other versions of ViRGE.
+
+I've left out the Alpha memory mapping, along with all option processing.
+Those will need to be done once the driver is minimally working.
+
+Note that everything in s3v_driver.c is MMIO only. There are a pair of
+PIO functions in s3v_pio.c, but that is the only place. See notes below
+about my ViRGE DX BIOS and why I needed to do this on my hardware.
+
+Other stuff...
+Some test stuff is assuming 8bpp, so 16 & 24 are broken.
+On my hardware, I am presently trying to get the Save/Restore sequence to
+recover the video mode. At the moment, when I run this driver, I get:
+ScreenInit() runs to completion.
+It returns FALSE, so the Server aborts.
+LeaveVT() is called, and runs to completion.
+The Server exits gracefully, but my monitor goes powersaver and the video
+mode is not recovered.
+
+
+
+TODO items
+----------
+Put vgaHWUnlockmmio in S3VModeInit (see MGAModeInit for example)?
+
+
+ViRGE MX code appears to be in 3.3.2 tree only, port to 4.0. I have
+started to added the chipset info in the main driver code. (KJB)
+
+modes notes: move mode Private S3V settings to mode init function?
+
+Check CR65 usage, bit 2 set based on S3_EARLY_SC? In my manual bit 2 is
+enable MMIO to RAMDAC registers.
+
+Notes:
+----------
+
+/config/cf/xfree86.cf
+
+have to add s3v to XF86CardDrivers for imake to make the
+drivers/s3v Makefile.
+
+To remake makefiles, after editing Imakefile, go to dir above drivers/s3v
+and do a 'make Makefiles'.
+
+For debug, make CDEBUGFLAGS='-g -DDEBUG', adding -DMetroLink enables
+timeout for VerticalRetraceWait().
+
+
+
+S3 ViRGE DX stuff:
+
+Card seems to power up (or BIOS forces) with MMIO disabled. All flavors are
+disabled, because CR53 comes up as 0. This may preclude using this card
+as the second device in a multi-head situation although David D. says that
+the new config. management stuff may help here.
+
+
+
+$XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/TODO_NOTES,v 1.10 1999/06/27 14:08:11 dawes Exp $
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/newmmio.h b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/newmmio.h
new file mode 100644
index 000000000..59ba57571
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/newmmio.h
@@ -0,0 +1,619 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/newmmio.h,v 1.5 1999/03/21 07:35:15 dawes Exp $ */
+
+/*
+Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+XFREE86 PROJECT 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 XFree86 Project 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 XFree86 Project.
+*/
+
+/***************************************************************************
+ *
+ * typedefs and macros for MMIO mode, S3 ViRGE
+ *
+ * who when vers
+ * HK 9609126 0.0
+ *
+ * based on:
+ *
+ * typedefs and macros for old and new MMIO mode, Trio64V+ and 868/968
+ *
+ * who when vers
+ * BL 0300296 0.1
+ * SM 200497 0.2 Added Caching version of register macros.
+ * KJB 9/98 0.3 Added S3V_MMIO_REGSIZE
+ ***************************************************************************/
+
+#ifndef _NEWMMIO_H
+#define _NEWMMIO_H
+
+/* base for S3_OUTW macro */
+#define S3_NEWMMIO_REGBASE 0x1000000 /* 16MB */
+#define S3_NEWMMIO_REGSIZE 0x10000 /* 64KB */
+#define S3V_MMIO_REGSIZE 0x8000 /* 32KB */
+
+
+/* #include <Xmd.h> */
+
+
+#define int16 CARD16
+#define int32 CARD32
+
+#define S3_NEWMMIO_VGABASE (S3_NEWMMIO_REGBASE + 0x8000)
+
+#if 0
+typedef struct { int16 vendor_ID; int16 device_ID; } pci_id;
+typedef struct { int16 cmd; int16 devsel; } cmd_devsel;
+
+typedef struct {
+ pci_id pci_ident;
+ cmd_devsel cmd_device_sel;
+ int32 class_code;
+ char dummy_0c;
+ char latnecy_timer;
+ int16 dummy_0e;
+ int32 base0;
+ char dummy_14[0x20-sizeof(int32)];
+ int32 bios_base;
+ int32 dummy_34;
+ int32 dummy_38;
+ char int_line;
+ char int_pin;
+ int16 latency_grant;
+} pci_conf_regs;
+
+
+typedef struct {
+ int32 prim_stream_cntl;
+ int32 col_chroma_key_cntl;
+ char dummy1[0x8190 - 0x8184-sizeof(int32)];
+ int32 second_stream_cntl;
+ int32 chroma_key_upper_bound;
+ int32 second_stream_stretch;
+ char dummy2[0x81a0 - 0x8198-sizeof(int32)];
+ int32 blend_cntl;
+ char dummy3[0x81c0 - 0x81a0-sizeof(int32)];
+ int32 prim_fbaddr0;
+ int32 prim_fbaddr1;
+ int32 prim_stream_stride;
+ int32 double_buffer;
+ int32 second_fbaddr0;
+ int32 second_fbaddr1;
+ int32 second_stream_stride;
+ int32 opaq_overlay_cntl;
+ int32 k1;
+ int32 k2;
+ int32 dda_vert;
+ int32 streams_fifo;
+ int32 prim_start_coord;
+ int32 prim_window_size;
+ int32 second_start_coord;
+ int32 second_window_size;
+} streams_proc_regs;
+
+typedef struct {
+ int32 fifo_control;
+ int32 miu_control;
+ int32 streams_timeout;
+ int32 misc_timeout;
+ int32 dummy_8210, dummy_8214, dummy_8218, dummy_821c;
+ int32 dma_read_base_addr;
+ int32 dma_read_stride_width;
+} memport_proc_regs;
+
+typedef struct {
+ int32 subsystem_csr;
+ int32 dummy_8508;
+ int32 adv_func_cntl;
+} subsys_regs;
+
+typedef struct {
+ int32 start_sysmem_addr;
+ int32 transfer_length;
+ int32 transfer_enable;
+} video_dma_regs;
+
+typedef struct {
+ int32 base_addr;
+ int32 write_pointer;
+ int32 read_pointer;
+ int32 dma_enable;
+} cmd_dma_regs;
+
+typedef struct {
+ video_dma_regs video;
+ int32 dummy_858c;
+ cmd_dma_regs cmd;
+} dma_regs;
+
+typedef struct {
+ int32 lpb_mode;
+ int32 lpb_fifostat;
+ int32 lpb_intflags;
+ int32 lpb_fb0addr;
+ int32 lpb_fb1addr;
+ int32 lpb_direct_addr;
+ int32 lpb_direct_data;
+ int32 lpb_gpio;
+ int32 lpb_serial_port;
+ int32 lpb_input_winsize;
+ int32 lpb_data_offsets;
+ int32 lpb_hor_decimctl;
+ int32 lpb_vert_decimctl;
+ int32 lpb_line_stride;
+ int32 lpb_output_fifo;
+} lpbus_regs;
+
+
+typedef struct { char atr_cntl_ind; char attr_cntl_dat; char misc_out;
+ char viseo_enable; } v3c0;
+typedef struct { char seq_index; char seq_data; char dac_mask;
+ char dac_rd_index; } v3c4;
+typedef struct { char dac_wr_index; char dac_data; char feature_cntl;
+ char filler; } v3c8;
+typedef struct v3cc { char misc_out; char filler; char graph_cntl_index;
+ char graph_cntl_data; } v3cc;
+typedef struct {
+ v3c0 v3c0_regs;
+ v3c4 v3c4_regs;
+ v3c8 v3c8_regs;
+ v3cc v3cc_regs;
+} vga_3c_regs;
+
+typedef struct { char crt_index; char crt_data; int16 filler; } v3d4;
+typedef struct { int16 filler1; char feature_cntl; char filler2;} v3d8;
+
+typedef struct {
+ int32 filler;
+ v3d4 v3d4_regs;
+ v3d8 v3d8_regs;
+} vga_3bd_regs ;
+
+
+
+typedef struct {
+ char filler1[-(0xa000-0xa100)];
+ int32 patt[-(0xa100-0xa1bc) / sizeof(int32) + 1];
+} colpatt_regs;
+
+typedef struct {
+ char filler1[-(0xa400-0xa4d4)];
+ int32 src_base;
+ int32 dest_base;
+ int32 clip_l_r;
+ int32 clip_t_b;
+ int32 dest_src_str;
+ int32 mono_pat0;
+ int32 mono_pat1;
+ int32 pat_bg_clr;
+ int32 pat_fg_clr;
+ int32 src_bg_clr;
+ int32 src_fg_clr;
+ int32 cmd_set;
+ int32 rwidth_height;
+ int32 rsrc_xy;
+ int32 rdest_xy;
+} bltfill_regs;
+
+typedef struct {
+ char filler1[-(0xa800-0xa8d4)];
+ int32 src_base;
+ int32 dest_base;
+ int32 clip_l_r;
+ int32 clip_t_b;
+ int32 dest_src_str;
+ int32 dummy1;
+ int32 dummy2;
+ int32 dummy3;
+ int32 pat_fg_clr;
+ int32 dummy4;
+ int32 dummy5;
+ int32 cmd_set;
+ char filler2[-(0xa904-0xa96c)];
+ int32 lxend0_end1;
+ int32 ldx;
+ int32 lxstart;
+ int32 lystart;
+ int32 lycnt;
+} line_regs;
+
+typedef struct {
+ char filler1[-(0xac00-0xacd4)];
+ int32 src_base;
+ int32 dest_base;
+ int32 clip_l_r;
+ int32 clip_t_b;
+ int32 dest_src_str;
+ int32 mono_pat0;
+ int32 mono_pat1;
+ int32 pat_bg_clr;
+ int32 pat_fg_clr;
+ int32 dummy1;
+ int32 dummy2;
+ int32 cmd_set;
+ char filler2[-(0xad04-0xad68)];
+ int32 prdx;
+ int32 prxstart;
+ int32 pldx;
+ int32 plxstart;
+ int32 pystart;
+ int32 pycnt;
+} polyfill_regs;
+
+typedef struct {
+ char filler1[-(0xb000-0xb0d4)];
+ int32 z_base;
+ int32 dest_base;
+ int32 clip_l_r;
+ int32 clip_t_b;
+ int32 dest_src_str;
+ int32 z_stride;
+ int32 dummy1;
+ int32 dummy2;
+ int32 fog_clr;
+ int32 dummy3;
+ int32 dummy4;
+ int32 cmd_set;
+ char filler2[-(0xb104-0xb144)];
+ int32 dgdy_dbdy;
+ int32 dady_drdy;
+ int32 gs_bs;
+ int32 as_rs;
+ int32 dummy5;
+ int32 dz;
+ int32 zstart;
+ int32 dummy6;
+ int32 dummy7;
+ int32 dummy8;
+ int32 xend0_end1;
+ int32 dx;
+ int32 xstart;
+ int32 ystart;
+ int32 ycnt;
+} line3d_regs;
+
+typedef struct {
+ char filler1[-(0xb400-0xb4d4)];
+ int32 z_base;
+ int32 dest_base;
+ int32 clip_l_r;
+ int32 clip_t_b;
+ int32 dest_src_str;
+ int32 z_stride;
+ int32 tex_base;
+ int32 tex_bdr_clr;
+ int32 fog_clr;
+ int32 color0;
+ int32 color1;
+ int32 cmd_set;
+ int32 bv;
+ int32 bu;
+ int32 dwdx;
+ int32 dwdy;
+ int32 ws;
+ int32 dddx;
+ int32 dvdx;
+ int32 dudx;
+ int32 dddy;
+ int32 dvdy;
+ int32 dudy;
+ int32 ds;
+ int32 vs;
+ int32 us;
+ int32 dgdx_dbdx;
+ int32 dadx_drdx;
+ int32 dgdy_dbdy;
+ int32 dady_drdy;
+ int32 gs_bs;
+ int32 as_rs;
+ int32 dzdx;
+ int32 dzdy;
+ int32 zs;
+ int32 dxdy12;
+ int32 xend12;
+ int32 dxdy01;
+ int32 xend01;
+ int32 dxdy02;
+ int32 xstart02;
+ int32 ystart;
+ int32 y01_y12;
+} triangle3d_regs;
+
+
+typedef struct {
+ int32 img[0x8000/4];
+ union { pci_conf_regs regs;
+ char dummy[-(0x8000 - 0x8180)];
+ } pci_regs;
+ union { streams_proc_regs regs;
+ char dummy[-(0x8180 - 0x8200)];
+ } streams_regs;
+ union { memport_proc_regs regs;
+ char dummy[-(0x8200 - 0x83b0)];
+ } memport_regs;
+ union { vga_3bd_regs regs;
+ char dummy[-(0x83b0 - 0x83c0)];
+ } v3b_regs;
+ union { vga_3c_regs regs;
+ char dummy[-(0x83c0 - 0x83d0)];
+ } v3c_regs;
+ union { vga_3bd_regs regs;
+ char dummy[-(0x83d0 - 0x8504)];
+ } v3d_regs;
+ union { subsys_regs regs;
+ char dummy[-(0x8504 - 0x8580)];
+ } subsys_regs;
+ union { dma_regs regs;
+ char dummy[-(0x8580 - 0xa000)];
+ } dma_regs;
+ union { colpatt_regs regs;
+ char dummy[-(0xa000 - 0xa400)];
+ } colpatt_regs;
+ union { bltfill_regs regs;
+ char dummy[-(0xa400 - 0xa800)];
+ } bltfill_regs;
+ union { line_regs regs;
+ char dummy[-(0xa800 - 0xac00)];
+ } line_regs;
+ union { polyfill_regs regs;
+ char dummy[-(0xac00 - 0xb000)];
+ } polyfill_regs;
+ union { line3d_regs regs;
+ char dummy[-(0xb000 - 0xb400)];
+ } line3d_regs;
+ union { triangle3d_regs regs;
+ char dummy[-(0xb400 - 0xff00)];
+ } triangle3d_regs;
+ union { lpbus_regs regs;
+ char dummy[-(0xff00 - 0xff5c)];
+ } lbp_regs;
+} mm_virge_regs ;
+
+
+
+#define mmtr volatile mm_virge_regs *
+
+#define SET_WRT_MASK(msk) /* */
+#define SET_RD_MASK(msk) /* */
+#define SET_FRGD_COLOR(col) /* */
+#define SET_BKGD_COLOR(col) /* */
+#define SET_FRGD_MIX(fmix) /* */
+#define SET_BKGD_MIX(bmix) /* */
+#define SET_PIX_CNTL(val) /* */
+#define SET_MIN_AXIS_PCNT(min) /* */
+#define SET_MAJ_AXIS_PCNT(maj) /* */
+#define SET_CURPT(c_x, c_y) /* */
+#define SET_CUR_X(c_x) /* */
+#define SET_CUR_Y(c_y) /* */
+#define SET_DESTSTP(x,y) /* */
+#define SET_AXIS_PCNT(maj, min) /* */
+#define SET_CMD(c_d) /* */
+#define SET_ERR_TERM(e) /* */
+#define SET_SCISSORS(x1,y1,x2,y2) /* */
+#define SET_SCISSORS_RB(x,y) /* */
+#define SET_MULT_MISC(val) /* */
+
+#define SET_PIX_TRANS_W(val) /* */
+#define SET_PIX_TRANS_L(val) /* */
+#define SET_MIX(fmix,bmix) /* */
+
+#endif /* 0 */
+
+/*
+ * reads from SUBSYS_STAT
+ */
+#define IN_SUBSYS_STAT() (INREG(SUBSYS_STAT_REG))
+#define SET_SUBSYS_CRTL(val) do { write_mem_barrier();\
+OUTREG((val), SUBSYS_STAT_REG);\
+write_mem_barrier(); } while (0)
+
+
+#if 0
+#define SET_DAC_W_INDEX(index) OUTREG8(DAC_W_INDEX, index)
+#define SET_DAC_DATA(val) OUTREG8(DAC_DATA,val)
+#endif
+
+#if 0
+
+#define IMG_TRANS (((mmtr)s3vMmioMem)->img)
+#define SET_PIXTRANS(a,v) IMG_TRANS[a] = (v)
+#define COLOR_PATTERN (((mmtr)s3vMmioMem)->colpatt_regs.regs)
+
+#define CMD_DMA_BASE(val) (((mmtr)s3vMmioMem)->dma_regs.regs.cmd.base_addr) = (val)
+#define CMD_DMA_WRITEP(val) (((mmtr)s3vMmioMem)->dma_regs.regs.cmd.write_pointer) = (val)
+#define CMD_DMA_READP(val) (((mmtr)s3vMmioMem)->dma_regs.regs.cmd.read_pointer) = (val)
+#define CMD_DMA_ENABLE(val) (((mmtr)s3vMmioMem)->dma_regs.regs.cmd.dma_enable) = (val)
+
+#define SETB_SRC_BASE(val) ((mmtr)s3vMmioMem)->bltfill_regs.regs.src_base = (val)
+#define SETB_DEST_BASE(val) ((mmtr)s3vMmioMem)->bltfill_regs.regs.dest_base = (val)
+#define SETB_CLIP_L_R(l,r) ((mmtr)s3vMmioMem)->bltfill_regs.regs.clip_l_r = ((l)<<16 | (r))
+#define SETB_CLIP_T_B(t,b) ((mmtr)s3vMmioMem)->bltfill_regs.regs.clip_t_b = ((t)<<16 | (b))
+/* #define SETB_DEST_SRC_STR(d,s) ((mmtr)s3vMmioMem)->bltfill_regs.regs.dest_src_str = ((d)<<16 | (s)) */
+
+#define SETB_DEST_SRC_STR(d, s) (OUTREG(DEST_SRC_STR, ((d) << 16 | (s))))
+
+#define SETB_MONO_PAT0(val) ((mmtr)s3vMmioMem)->bltfill_regs.regs.mono_pat0 = (val)
+#define SETB_MONO_PAT1(val) ((mmtr)s3vMmioMem)->bltfill_regs.regs.mono_pat1 = (val)
+#define SETB_PAT_BG_CLR(val) ((mmtr)s3vMmioMem)->bltfill_regs.regs.pat_bg_clr = (val)
+#define SETB_PAT_FG_CLR(val) ((mmtr)s3vMmioMem)->bltfill_regs.regs.pat_fg_clr = (val)
+#define SETB_SRC_BG_CLR(val) ((mmtr)s3vMmioMem)->bltfill_regs.regs.src_bg_clr = (val)
+#define SETB_SRC_FG_CLR(val) ((mmtr)s3vMmioMem)->bltfill_regs.regs.src_fg_clr = (val)
+#define SETB_CMD_SET(val) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->bltfill_regs.regs.cmd_set = (val); write_mem_barrier(); } while (0)
+#define SETB_RWIDTH_HEIGHT(w,h) ((mmtr)s3vMmioMem)->bltfill_regs.regs.rwidth_height = ((w)<<16 | (h))
+#define SETB_RSRC_XY(x,y) ((mmtr)s3vMmioMem)->bltfill_regs.regs.rsrc_xy = ((x)<<16 | (y))
+#define SETB_RDEST_XY(x,y) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->bltfill_regs.regs.rdest_xy = ((x)<<16 | (y)); write_mem_barrier(); } while (0)
+
+/* Caching version of the same MACROs */
+
+#define CACHE_SETB_CLIP_L_R(l,r) do { unsigned int clip = ((l)<<16 | (r)); if (s3vCached_CLIP_LR != clip) { ((mmtr)s3vMmioMem)->bltfill_regs.regs.clip_l_r = clip; s3vCached_CLIP_LR = clip; s3vCacheMiss++;} else s3vCacheHit++;} while(0)
+#define CACHE_SETB_CLIP_T_B(t,b) do { unsigned int clip = ((t)<<16 | (b)); if (s3vCached_CLIP_TB != clip) { ((mmtr)s3vMmioMem)->bltfill_regs.regs.clip_t_b = clip; s3vCached_CLIP_TB = clip; s3vCacheMiss++;} else s3vCacheHit++;} while(0)
+#define CACHE_SETB_RSRC_XY(x,y) do { unsigned int src = ((x)<<16 | (y)); if (s3vCached_RSRC_XY != src) { ((mmtr)s3vMmioMem)->bltfill_regs.regs.rsrc_xy = src; s3vCached_RSRC_XY = src; s3vCacheMiss++;} else s3vCacheHit++;} while(0)
+#define CACHE_SETB_RWIDTH_HEIGHT(w,h) do { unsigned int rwh = ((w)<<16 | (h)); if (s3vCached_RWIDTH_HEIGHT != rwh) { ((mmtr)s3vMmioMem)->bltfill_regs.regs.rwidth_height = rwh; s3vCached_RWIDTH_HEIGHT = rwh; s3vCacheMiss++;} else s3vCacheHit++;} while(0)
+#define CACHE_SETB_MONO_PAT0(val) do { \
+ if (s3vCached_MONO_PATTERN0 != (val)) { \
+ ((mmtr)s3vMmioMem)->bltfill_regs.regs.mono_pat0 = (val); \
+ s3vCached_MONO_PATTERN0 = (val); \
+ s3vCacheMiss++; \
+ } else s3vCacheHit++; \
+} while(0)
+#define CACHE_SETB_MONO_PAT1(val) do { \
+ if (s3vCached_MONO_PATTERN1 != (val)) { \
+ ((mmtr)s3vMmioMem)->bltfill_regs.regs.mono_pat1 = (val); \
+ s3vCached_MONO_PATTERN1 = (val); \
+ s3vCacheMiss++; \
+ } else s3vCacheHit++;\
+} while(0)
+#define CACHE_SETB_PAT_FG_CLR(val) do { \
+ if (s3vCached_PAT_FGCLR != (val)) { \
+ ((mmtr)s3vMmioMem)->bltfill_regs.regs.pat_fg_clr = (val); \
+ s3vCached_PAT_FGCLR = (val); \
+ s3vCacheMiss++; \
+ } else s3vCacheHit++; \
+} while(0)
+#define CACHE_SETB_PAT_BG_CLR(val) do { \
+ if (s3vCached_PAT_BGCLR != (val)) { \
+ ((mmtr)s3vMmioMem)->bltfill_regs.regs.pat_bg_clr = (val); \
+ s3vCached_PAT_BGCLR = (val); \
+ s3vCacheMiss++; \
+ } else s3vCacheHit++; \
+} while(0)
+#define CACHE_SETB_CMD_SET(val) do { \
+ if (s3vCached_CMD_SET != (val)) { \
+ write_mem_barrier(); \
+ ((mmtr)s3vMmioMem)->bltfill_regs.regs.cmd_set = (val); \
+ s3vCached_CMD_SET = (val); \
+ s3vCacheMiss++; \
+ write_mem_barrier(); \
+ } else s3vCacheHit++; \
+} while(0)
+#define SETL_SRC_BASE(val) ((mmtr)s3vMmioMem)->line_regs.regs.src_base = (val)
+#define SETL_DEST_BASE(val) ((mmtr)s3vMmioMem)->line_regs.regs.dest_base = (val)
+#define SETL_CLIP_L_R(l,r) ((mmtr)s3vMmioMem)->line_regs.regs.clip_l_r = ((l)<<16 | (r))
+#define SETL_CLIP_T_B(t,b) ((mmtr)s3vMmioMem)->line_regs.regs.clip_t_b = ((t)<<16 | (b))
+#define SETL_DEST_SRC_STR(d,s) ((mmtr)s3vMmioMem)->line_regs.regs.dest_src_str = ((d)<<16 | (s))
+#define SETL_PAT_FG_CLR(val) ((mmtr)s3vMmioMem)->line_regs.regs.pat_fg_clr = (val)
+#define SETL_CMD_SET(val) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->line_regs.regs.cmd_set = (val); write_mem_barrier(); } while (0)
+#define SETL_LXEND0_END1(e0,e1) ((mmtr)s3vMmioMem)->line_regs.regs.lxend0_end1 = ((e0)<<16 | (e1))
+#define SETL_LDX(val) ((mmtr)s3vMmioMem)->line_regs.regs.ldx = (val)
+#define SETL_LXSTART(val) ((mmtr)s3vMmioMem)->line_regs.regs.lxstart = (val)
+#define SETL_LYSTART(val) ((mmtr)s3vMmioMem)->line_regs.regs.lystart = (val)
+#define SETL_LYCNT(val) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->line_regs.regs.lycnt = (val); write_mem_barrier(); } while (0)
+
+/* Cache version */
+#define CACHE_SETL_CMD_SET(val) do { if (s3vCached_CMD_SET != val) { write_mem_barrier(); ((mmtr)s3vMmioMem)->line_regs.regs.cmd_set = val; s3vCached_CMD_SET = val; s3vCacheMiss++; write_mem_barrier(); } else s3vCacheHit++;} while(0)
+
+
+
+#define SETP_SRC_BASE(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.src_base = (val)
+#define SETP_DEST_BASE(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.dest_base = (val)
+#define SETP_CLIP_L_R(l,r) ((mmtr)s3vMmioMem)->polyfill_regs.regs.clip_l_r = ((l)<<16 | (r))
+#define SETP_CLIP_T_B(t,b) ((mmtr)s3vMmioMem)->polyfill_regs.regs.clip_t_b = ((t)<<16 | (b))
+#define SETP_DEST_SRC_STR(d,s) ((mmtr)s3vMmioMem)->polyfill_regs.regs.dest_src_str = ((d)<<16 | (s))
+#define SETP_MONO_PAT0(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.mono_pat0 = (val)
+#define SETP_MONO_PAT1(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.mono_pat1 = (val)
+#define SETP_PAT_BG_CLR(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.pat_bg_clr = (val)
+#define SETP_PAT_FG_CLR(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.pat_fg_clr = (val)
+#define SETP_CMD_SET(val) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->polyfill_regs.regs.cmd_set = (val); write_mem_barrier(); } while (0)
+#define SETP_RWIDTH_HEIGHT(w,h) ((mmtr)s3vMmioMem)->polyfill_regs.regs.rwidth_height = ((w)<<16 | (h))
+#define SETP_PRDX(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.prdx = (val)
+#define SETP_PRXSTART(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.prxstart = (val)
+#define SETP_PLDX(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.pldx = (val)
+#define SETP_PLXSTART(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.plxstart = (val)
+#define SETP_PYSTART(val) ((mmtr)s3vMmioMem)->polyfill_regs.regs.pystart = (val)
+#define SETP_PYCNT(val) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->polyfill_regs.regs.pycnt = (val); write_mem_barrier(); } while (0)
+
+/* Cache version */
+#define CACHE_SETP_CMD_SET(val) do { if (s3vCached_CMD_SET != val) { write_mem_barrier(); ((mmtr)s3vMmioMem)->polyfill_regs.regs.cmd_set = val; s3vCached_CMD_SET = val; s3vCacheMiss++; write_mem_barrier(); } else s3vCacheHit++;} while(0)
+
+
+#define SETL3_Z_BASE(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.z_base = (val)
+#define SETL3_DEST_BASE(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.dest_base = (val)
+#define SETL3_CLIP_L_R(l,r) ((mmtr)s3vMmioMem)->line3d_regs.regs.clip_l_r = ((l)<<16 | (r))
+#define SETL3_CLIP_T_B(t,b) ((mmtr)s3vMmioMem)->line3d_regs.regs.clip_t_b = ((t)<<16 | (b))
+#define SETL3_DEST_SRC_STR(d,s) ((mmtr)s3vMmioMem)->line3d_regs.regs.dest_src_str = ((d)<<16 | (s))
+#define SETL3_Z_STRIDE(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.z_stride = (val)
+#define SETL3_FOG_CLR(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.fog_clr = (val)
+#define SETL3_CMD_SET(val) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->line3d_regs.regs.cmd_set = (val); write_mem_barrier(); } while (0)
+#define SETL3_DGDY_DBDY(dg,db) ((mmtr)s3vMmioMem)->line3d_regs.regs.dgdy_dbdy = ((dg)<<16 | (db))
+#define SETL3_DADY_DRDY(da,dr) ((mmtr)s3vMmioMem)->line3d_regs.regs.dady_drdy = ((da)<<16 | (dr))
+#define SETL3_GS_BS(gs,bs) ((mmtr)s3vMmioMem)->line3d_regs.regs.gs_bs = ((gs)<<16 | (bs))
+#define SETL3_AS_RS(as,rs) ((mmtr)s3vMmioMem)->line3d_regs.regs.as_rs = ((as)<<16 | (rs))
+#define SETL3_DZ(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.dz = (val)
+#define SETL3_ZSTART(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.zstart = (val)
+#define SETL3_XEND0_END1(e0,e1) ((mmtr)s3vMmioMem)->line3d_regs.regs.xend0_end1 = ((e0)<<16 | (e1))
+#define SETL3_DX(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.dx = (val)
+#define SETL3_XSTART(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.xstart = (val)
+#define SETL3_YSTART(val) ((mmtr)s3vMmioMem)->line3d_regs.regs.ystart = (val)
+#define SETL3_YCNT(val) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->line3d_regs.regs.ycnt = (val); write_mem_barrier(); } while (0)
+
+
+
+#define SETT3_Z_BASE(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.z_base = (val)
+#define SETT3_DEST_BASE(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dest_base = (val)
+#define SETT3_CLIP_L_R(l,r) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.clip_l_r = ((l)<<16 | (r))
+#define SETT3_CLIP_T_B(t,b) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.clip_t_b = ((t)<<16 | (b))
+#define SETT3_DEST_SRC_STR(d,s) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dest_src_str = ((d)<<16 | (s))
+#define SETT3_Z_STRIDE(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.z_stride = (val)
+#define SETT3_TEX_BASE(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.tex_base = (val)
+#define SETT3_TEX_BDR_CLR(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.tex_bdr_clr = (val)
+#define SETT3_FOG_CLR(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.fog_clr = (val)
+#define SETT3_COLOR0(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.color0 = (val)
+#define SETT3_COLOR1(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.color1 = (val)
+#define SETT3_CMD_SET(val) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->triangle3d_regs.regs.cmd_set = (val); write_mem_barrier(); } while (0)
+#define SETT3_BV(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.bv = (val)
+#define SETT3_BU(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.bu = (val)
+#define SETT3_DWDX(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dwdx = (val)
+#define SETT3_DWDY(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dwdy = (val)
+#define SETT3_WS(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.ws = (val)
+#define SETT3_DDDX(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dddx = (val)
+#define SETT3_DVDX(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dvdx = (val)
+#define SETT3_DUDX(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dudx = (val)
+#define SETT3_DDDY(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dddy = (val)
+#define SETT3_DVDY(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dvdy = (val)
+#define SETT3_DUDY(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dudy = (val)
+#define SETT3_DS(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.ds = (val)
+#define SETT3_VS(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.vs = (val)
+#define SETT3_US(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.us = (val)
+#define SETT3_DGDX_DBDX(gx,bx) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dgdx_dbdx = ((gx)<<16 | (bx))
+#define SETT3_DADX_DRDX(ax,rx) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dadx_drdx = ((ax)<<16 | (rx))
+#define SETT3_DGDY_DBDY(gy,by) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dgdy_dbdy = ((gy)<<16 | (by))
+#define SETT3_DADY_DRDY(ay,ry) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dady_drdy = ((ay)<<16 | (ry))
+#define SETT3_GS_BS(gs,bs) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.gs_bs = ((gs)<<16 | (bs))
+#define SETT3_AS_RS(as,rs) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.as_rs = ((as)<<16 | (rs))
+#define SETT3_DZDX(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dzdx = (val)
+#define SETT3_DZDY(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dzdy = (val)
+#define SETT3_ZS(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.zs = (val)
+#define SETT3_DXDY12(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dxdy12 = (val)
+#define SETT3_XEND12(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.xend12 = (val)
+#define SETT3_DXDY01(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dxdy01 = (val)
+#define SETT3_XEND01(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.xend01 = (val)
+#define SETT3_DXDY02(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.dxdy02 = (val)
+#define SETT3_XSTART02(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.xstart02 = (val)
+#define SETT3_YSTART(val) ((mmtr)s3vMmioMem)->triangle3d_regs.regs.ystart = (val)
+#define SETT3_Y01_Y12(y01,y12) do { write_mem_barrier(); ((mmtr)s3vMmioMem)->triangle3d_regs.regs.y01_y12 = ((y01)<<16 | (y12)); write_mem_barrier(); } while (0)
+
+
+
+#define DBGOUT(p) /* OUTREG8(0x3bc,p) */
+
+#endif /* 0 */
+
+#endif /* _NEWMMIO_H */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/regs3v.h b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/regs3v.h
new file mode 100644
index 000000000..1558867d6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/regs3v.h
@@ -0,0 +1,433 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/regs3v.h,v 1.5 1999/03/21 07:35:16 dawes Exp $ */
+
+/*
+Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+XFREE86 PROJECT 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 XFree86 Project 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 XFree86 Project.
+*/
+
+/*
+ * regs3v.h
+ *
+ * Port to 4.0 design level
+ *
+ * S3 ViRGE driver
+ *
+ * Portions based on code containing the following notices:
+ **********************************************************
+ *
+ * Written by Jake Richter Copyright (c) 1989, 1990 Panacea Inc., Londonderry,
+ * NH - All Rights Reserved
+ *
+ * This code may be freely incorporated in any program without royalty, as long
+ * as the copyright notice stays intact.
+ *
+ * Additions by Kevin E. Martin (martin@cs.unc.edu)
+ *
+ * KEVIN E. MARTIN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEVIN E. MARTIN 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.
+ *
+ */
+
+/* Taken from accel/s3_virge code */
+/* 23/03/97 S. Marineau: fixed bug with first Doubleword Offset macros
+ * and added macro CommandWaitIdle to wait for the command FIFO to empty
+ */
+
+
+#ifndef _REGS3V_H
+#define _REGS3V_H
+
+#if 0
+/* for OUT instructions */
+#include "compiler.h"
+
+/* for new trio64V+ and 968 mmio */
+#include "newmmio.h"
+
+
+/* S3 chipset definitions */
+
+
+#define UNLOCK_SYS_REGS do { \
+ outb(vgaCRIndex, 0x39); \
+ outb(vgaCRReg, 0xa5); } while (0)
+
+
+#ifndef MetroLink
+#define VerticalRetraceWait() do { \
+ outb(vgaCRIndex, 0x17); \
+ if ( inb(vgaCRReg) & 0x80 ) { \
+ while ((inb(vgaIOBase + 0x0A) & 0x08) == 0x00) ; \
+ while ((inb(vgaIOBase + 0x0A) & 0x08) == 0x08) ; \
+ while ((inb(vgaIOBase + 0x0A) & 0x08) == 0x00) ; \
+ }\
+} while (0)
+#else
+#define SPIN_LIMIT 1000000
+#define VerticalRetraceWait() do { \
+ outb(vgaCRIndex, 0x17); \
+ if ( inb(vgaCRReg) & 0x80 ) { \
+ volatile unsigned long _spin_me; \
+ for (_spin_me = 0; \
+ ((inb(vgaIOBase + 0x0A) & 0x08) == 0x00) && _spin_me <= SPIN_LIMIT; \
+ _spin_me++) ; \
+ if (_spin_me > SPIN_LIMIT) \
+ ErrorF("s3v: warning: VerticalRetraceWait timed out.\n"); \
+ for (_spin_me = 0; \
+ ((inb(vgaIOBase + 0x0A) & 0x08) == 0x08) && _spin_me <= SPIN_LIMIT; \
+ _spin_me++) ; \
+ if (_spin_me > SPIN_LIMIT) \
+ ErrorF("s3v: warning: VerticalRetraceWait timed out.\n"); \
+ for (_spin_me = 0; \
+ ((inb(vgaIOBase + 0x0A) & 0x08) == 0x00) && _spin_me <= SPIN_LIMIT; \
+ _spin_me++) ; \
+ if (_spin_me > SPIN_LIMIT) \
+ ErrorF("s3v: warning: VerticalRetraceWait timed out.\n"); \
+ } \
+} while (0)
+#endif
+
+#endif /* 0 */
+
+
+
+#define S3_ViRGE_SERIES(chip) ((chip&0xfff0)==0x31e0)
+#define S3_ViRGE_GX2_SERIES(chip) (chip == S3_ViRGE_GX2)
+#define S3_ViRGE_MX_SERIES(chip) (chip == S3_ViRGE_MX || chip == S3_ViRGE_MXP)
+#define S3_ViRGE_MXP_SERIES(chip) (chip == S3_ViRGE_MXP)
+#define S3_ViRGE_VX_SERIES(chip) ((chip&0xfff0)==0x3de0)
+
+#if 0
+#define S3_ANY_ViRGE_SERIES(chip) ( S3_ViRGE_SERIES(chip) \
+ || S3_ViRGE_VX_SERIES(chip))
+#define S3_ANY_SERIES(chip) ( S3_ViRGE_SERIES(chip) \
+ || S3_ViRGE_VX_SERIES(chip))
+#endif /* 0 */
+
+#if 0
+/* take these from ../../common/xf86PciInfo.h instead */
+/* PCI data */
+#define PCI_S3_VENDOR_ID 0x5333
+#define PCI_ViRGE 0x5631
+#define PCI_ViRGE_VX 0x883D
+#define PCI_ViRGE_DXGX 0x8A01
+#define PCI_ViRGE_GX2 0x8A10
+#define PCI_ViRGE_MX 0x8C01
+#define PCI_ViRGE_MXP 0x8C03
+#endif /* 0 */
+
+/* Chip tags */
+#if 1
+#define PCI_S3_VENDOR_ID PCI_VENDOR_S3
+#define S3_UNKNOWN 0
+#define S3_ViRGE PCI_CHIP_VIRGE
+#define S3_ViRGE_VX PCI_CHIP_VIRGE_VX
+#define S3_ViRGE_DXGX PCI_CHIP_VIRGE_DXGX
+#define S3_ViRGE_GX2 PCI_CHIP_VIRGE_GX2
+#define S3_ViRGE_MX PCI_CHIP_VIRGE_MX
+#define S3_ViRGE_MXP PCI_CHIP_VIRGE_MXP
+#else
+#define S3_UNKNOWN 0
+#define S3_ViRGE 1
+#define S3_ViRGE_VX 2
+#define S3_ViRGE_DXGX 3
+#define S3_ViRGE_GX2 4
+#define S3_ViRGE_MX 5
+#define S3_ViRGE_MXP 6
+#endif /* 1 */
+
+#if 0
+
+/* VESA Approved Register Definitions */
+#define DAC_MASK 0x03c6
+#define DAC_R_INDEX 0x03c7
+#define DAC_W_INDEX 0x03c8
+#define DAC_DATA 0x03c9
+
+#endif /* 0 */
+
+/* Subsystem Control Register */
+#define GPCTRL_NC 0x0000
+#define GPCTRL_ENAB 0x4000
+#define GPCTRL_RESET 0x8000
+
+
+/* Command Register */
+#define CMD_OP_MSK (0xf << 27)
+#define CMD_BITBLT (0x0 << 27)
+#define CMD_RECT ((0x2 << 27) | 0x0100)
+#define CMD_LINE (0x3 << 27)
+#define CMD_POLYFILL (0x5 << 27)
+#define CMD_NOP (0xf << 27)
+
+#define BYTSEQ 0
+#define _16BIT 0
+#define PCDATA 0x80
+#define INC_Y CMD_YP
+#define YMAJAXIS 0
+#define INC_X CMD_XP
+#define DRAW 0x0020
+#define LINETYPE 0x0008
+#define LASTPIX 0
+#define PLANAR 0 /* MIX_MONO_SRC */
+#define WRTDATA 0
+
+/*
+ * Short Stroke Vector Transfer Register (The angular Defs also apply to the
+ * Command Register
+ */
+#define VECDIR_000 0x0000
+#define VECDIR_045 0x0020
+#define VECDIR_090 0x0040
+#define VECDIR_135 0x0060
+#define VECDIR_180 0x0080
+#define VECDIR_225 0x00a0
+#define VECDIR_270 0x00c0
+#define VECDIR_315 0x00e0
+#define SSVDRAW 0x0010
+
+/* Command AutoExecute */
+#define CMD_AUTOEXEC 0x01
+
+/* Command Hardware Clipping Enable */
+#define CMD_HWCLIP 0x02
+
+/* Destination Color Format */
+#define DST_8BPP 0x00
+#define DST_16BPP 0x04
+#define DST_24BPP 0x08
+
+/* BLT Mix modes */
+#define MIX_BITBLT 0x0000
+#define MIX_MONO_SRC 0x0040
+#define MIX_CPUDATA 0x0080
+#define MIX_MONO_PATT 0x0100
+#define MIX_COLOR_PATT 0x0000
+#define MIX_MONO_TRANSP 0x0200
+
+/* Image Transfer Alignments */
+#define CMD_ITA_BYTE 0x0000
+#define CMD_ITA_WORD 0x0400
+#define CMD_ITA_DWORD 0x0800
+
+/* First Doubleword Offset (Image Transfer) */
+#define CMD_FDO_BYTE0 0x00000
+#define CMD_FDO_BYTE1 0x01000
+#define CMD_FDO_BYTE2 0x02000
+#define CMD_FDO_BYTE3 0x03000
+
+/* X Positive, Y Positive (Bit BLT) */
+#define CMD_XP 0x2000000
+#define CMD_YP 0x4000000
+
+/* 2D or 3D Select */
+#define CMD_2D 0x00000000
+#define CMD_3D 0x80000000
+
+/* The Mix ROPs (selected ones, not all 256) */
+#if 0
+
+#define ROP_0 (0x00<<17)
+#define ROP_DSon (0x11<<17)
+#define ROP_DSna (0x22<<17)
+#define ROP_Sn (0x33<<17)
+#define ROP_SDna (0x44<<17)
+#define ROP_Dn (0x55<<17)
+#define ROP_DSx (0x66<<17)
+#define ROP_DSan (0x77<<17)
+#define ROP_DSa (0x88<<17)
+#define ROP_DSxn (0x99<<17)
+#define ROP_D (0xaa<<17)
+#define ROP_DSno (0xbb<<17)
+#define ROP_S (0xcc<<17)
+#define ROP_SDno (0xdd<<17)
+#define ROP_DSo (0xee<<17)
+#define ROP_1 (0xff<<17)
+
+/* ROP -> (ROP & P) | (D & ~P) */
+#define ROP_0_PaDPnao /* DPna */ (0x0a<<17)
+#define ROP_DSon_PaDPnao /* PDSPaox */ (0x1a<<17)
+#define ROP_DSna_PaDPnao /* DPSana */ (0x2a<<17)
+#define ROP_Sn_PaDPnao /* SPDSxox */ (0x3a<<17)
+#define ROP_SDna_PaDPnao /* DPSDoax */ (0x4a<<17)
+#define ROP_Dn_PaDPnao /* DPx */ (0x5a<<17)
+#define ROP_DSx_PaDPnao /* DPSax */ (0x6a<<17)
+#define ROP_DSan_PaDPnao /* DPSDnoax */ (0x7a<<17)
+#define ROP_DSa_PaDPnao /* DSPnoa */ (0x8a<<17)
+#define ROP_DSxn_PaDPnao /* DPSnax */ (0x9a<<17)
+#define ROP_D_PaDPnao /* D */ (0xaa<<17)
+#define ROP_DSno_PaDPnao /* DPSnao */ (0xba<<17)
+#define ROP_S_PaDPnao /* DPSDxax */ (0xca<<17)
+#define ROP_SDno_PaDPnao /* DPSDanax */ (0xda<<17)
+#define ROP_DSo_PaDPnao /* DPSao */ (0xea<<17)
+#define ROP_1_PaDPnao /* DPo */ (0xfa<<17)
+
+
+/* S -> P */
+#define ROP_DPon (0x05<<17)
+#define ROP_DPna (0x0a<<17)
+#define ROP_Pn (0x0f<<17)
+#define ROP_PDna (0x50<<17)
+#define ROP_DPx (0x5a<<17)
+#define ROP_DPan (0x5f<<17)
+#define ROP_DPa (0xa0<<17)
+#define ROP_DPxn (0xa5<<17)
+#define ROP_DPno (0xaf<<17)
+#define ROP_P (0xf0<<17)
+#define ROP_PDno (0xf5<<17)
+#define ROP_DPo (0xfa<<17)
+
+/* ROP -> (ROP & S) | (~ROP & D) */
+#define ROP_DPSDxax (0xca<<17)
+#define ROP_DSPnoa (0x8a<<17)
+#define ROP_DPSao (0xea<<17)
+#define ROP_DPSoa (0xa8<<17)
+#define ROP_DSa (0x88<<17)
+#define ROP_SSPxDSxax (0xe8<<17)
+#define ROP_SDPoa (0xc8<<17)
+#define ROP_DSPnao (0xae<<17)
+#define ROP_SSDxPDxax (0x8e<<17)
+#define ROP_DSo (0xee<<17)
+#define ROP_SDPnao (0xce<<17)
+#define ROP_SPDSxax (0xac<<17)
+#define ROP_SDPnoa (0x8c<<17)
+#define ROP_SDPao (0xec<<17)
+
+/* ROP_sp -> (ROP_sp & S) | (D & ~S) */
+#define ROP_0_SaDSnao /* DSna */ (0x22<<17)
+#define ROP_DPa_SaDSnao /* DPSnoa */ (0xa2<<17)
+#define ROP_PDna_SaDSnao /* DSPDoax */ (0x62<<17)
+#define ROP_P_SaDSnao /* DSPDxax */ (0xe2<<17)
+#define ROP_DPna_SaDSnao /* DPSana */ (0x2a<<17)
+#define ROP_D_SaDSnao /* D */ (0xaa<<17)
+#define ROP_DPx_SaDSnao /* DPSax */ (0x6a<<17)
+#define ROP_DPo_SaDSnao /* DPSao */ (0xea<<17)
+#define ROP_DPon_SaDSnao /* SDPSaox */ (0x26<<17)
+#define ROP_DPxn_SaDSnao /* DSPnax */ (0xa6<<17)
+#define ROP_Dn_SaDSnao /* DSx */ (0x66<<17)
+#define ROP_PDno_SaDSnao /* SDPSanax */ (0xe6<<17)
+#define ROP_Pn_SaDSnao /* PSDPxox */ (0x2e<<17)
+#define ROP_DPno_SaDSnao /* DSPnao */ (0xae<<17)
+#define ROP_DPan_SaDSnao /* SDPSnoax */ (0x6e<<17)
+#define ROP_1_SaDSnao /* DSo */ (0xee<<17)
+
+#endif
+
+#if 0
+
+typedef struct {
+ unsigned char r, g, b;
+}
+LUTENTRY;
+
+#endif /* 0 */
+
+#if 0 /* delete me 3.9Nn */
+/* Wait until "v" queue entries are free */
+#define WaitQueue(v) if (ps3v->NoPCIRetry) { do { mem_barrier(); \
+ while (((IN_SUBSYS_STAT()) & 0x1f00) < (((v)+2) << 8)); \
+ } while (0); }
+
+/* Wait until GP is idle and queue is empty */
+#define WaitIdleEmpty() do { mem_barrier(); \
+ while ((IN_SUBSYS_STAT() & 0x3f00) != 0x3000); } while (0)
+
+/* Wait until GP is idle */
+#define WaitIdle() do { mem_barrier(); while (!(IN_SUBSYS_STAT() & 0x2000)); } while (0)
+
+/* Wait until Command FIFO is empty */
+#define WaitCommandEmpty() do { mem_barrier(); \
+ while (!(((((mmtr)s3vMmioMem)->subsys_regs.regs.adv_func_cntl)) & 0x200)); } while (0)
+
+/* Wait until a DMA transfer is done */
+#define WaitDMAEmpty() do { mem_barrier(); while ((((mmtr)s3vMmioMem)->dma_regs.regs.cmd.write_pointer) != (((mmtr)s3vMmioMem)->dma_regs.regs.cmd.read_pointer)); } while(0)
+#endif /* 0 */
+
+
+#define MAXLOOP 0xffffff /* timeout value for engine waits, ~6 secs */
+
+/* Wait until "v" queue entries are free */
+#define WaitQueue(v) \
+ if (ps3v->NoPCIRetry) { \
+ do { int loop=0; mem_barrier(); \
+ while ((((IN_SUBSYS_STAT()) & 0x1f00) < (((v)+2) << 8)) && (loop++<MAXLOOP)); \
+ if (loop >= MAXLOOP) S3VGEReset(pScrn,1,__LINE__,__FILE__); \
+ } while (0); }
+
+/* Wait until GP is idle and queue is empty */
+#define WaitIdleEmpty() \
+ do { int loop=0; mem_barrier(); \
+ while (((IN_SUBSYS_STAT() & 0x3f00) != 0x3000) && (loop++<MAXLOOP)); \
+ if (loop >= MAXLOOP) S3VGEReset(pScrn,1,__LINE__,__FILE__); \
+ } while (0)
+
+/* Wait until GP is idle */
+#define WaitIdle() \
+ do { int loop=0; mem_barrier(); \
+ while ((!(IN_SUBSYS_STAT() & 0x2000)) && (loop++<MAXLOOP)); \
+ if (loop >= MAXLOOP) S3VGEReset(pScrn,1,__LINE__,__FILE__); \
+ } while (0)
+
+
+/* Wait until Command FIFO is empty */
+#define WaitCommandEmpty() do { int loop=0; mem_barrier(); \
+ if (ps3v->Chipset == S3_ViRGE_GX2 || ps3v->Chipset == S3_ViRGE_MX || ps3v->Chipset == S3_ViRGE_MXP) \
+ while ((!(((((mmtr)s3vMmioMem)->subsys_regs.regs.adv_func_cntl)) & 0x400)) && (loop++<MAXLOOP)); \
+ else \
+ while ((!(((((mmtr)s3vMmioMem)->subsys_regs.regs.adv_func_cntl)) & 0x200)) && (loop++<MAXLOOP)); \
+ if (loop >= MAXLOOP) S3VGEReset(pScrn,1,__LINE__,__FILE__); \
+ } while (0)
+
+/* Wait until a DMA transfer is done */
+#define WaitDMAEmpty() \
+ do { int loop=0; mem_barrier(); \
+ while (((((mmtr)s3vMmioMem)->dma_regs.regs.cmd.write_pointer) != (((mmtr)s3vMmioMem)->dma_regs.regs.cmd.read_pointer)) && (loop++<MAXLOOP)); \
+ if (loop >= MAXLOOP) S3VGEReset(pScrn,1,__LINE__,__FILE__); \
+ } while(0)
+
+
+#if 0
+
+#ifndef NULL
+#define NULL 0
+
+#endif /* NULL */
+
+
+#endif /* 0 */
+
+
+
+
+#define RGB8_PSEUDO (-1)
+#define RGB16_565 0
+#define RGB16_555 1
+#define RGB32_888 2
+
+#endif /* _REGS3V_H */
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v.h b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v.h
new file mode 100644
index 000000000..765301ebe
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v.h
@@ -0,0 +1,377 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v.h,v 1.15 1999/08/21 13:48:38 dawes Exp $ */
+
+/*
+Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+XFREE86 PROJECT 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 XFree86 Project 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 XFree86 Project.
+*/
+
+#ifndef _S3V_H
+#define _S3V_H
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.h"
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+/* All drivers need this */
+#include "xf86_ansic.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+#include "xf86Cursor.h"
+
+#include "vgaHW.h"
+
+#include "s3v_macros.h"
+
+/* All drivers initialising the SW cursor need this */
+#include "mipointer.h"
+
+/* All drivers using the mi colormap manipulation need this */
+#include "micmap.h"
+
+/* Drivers using cfb need this */
+
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+
+/* Drivers supporting bpp 16, 24 or 32 with cfb need these */
+
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+#include "cfb24_32.h"
+
+/* Drivers using the XAA interface ... */
+#include "xaa.h"
+#include "xf86cmap.h"
+#include "xf86i2c.h"
+
+#ifndef _S3V_VGAHWMMIO_H
+#define _S3V_VGAHWMMIO_H
+
+#ifdef __alpha__
+#define VGAIN8(addr) xf86ReadSparse8(ps3v->IOBase, (addr))
+#define VGAIN16(addr) xf86ReadSparse16(ps3v->IOBase, (addr))
+#define VGAIN(addr) xf86ReadSparse32(ps3v->IOBase, (addr))
+#define VGAOUT8(addr,val) xf86WriteSparse8((val),ps3v->IOBase,(addr))
+#define VGAOUT16(addr,val) xf86WriteSparse16((val),ps3v->IOBase,(addr))
+#define VGAOUT(addr, val) xf86WriteSparse32((val),ps3v->IOBase,(addr))
+
+#define INREG(addr) xf86ReadSparse32(ps3v->MapBase, (addr))
+#define OUTREG(addr, val) xf86WriteSparse32((val),ps3v->MapBase,(addr))
+#define NEW_INREG(addr) xf86ReadSparse32(s3vMmioMem, (addr))
+#define NEW_OUTREG(addr, val) xf86WriteSparse32((val), s3vMmioMem, (addr))
+
+#else
+
+#define VGAIN8(addr) *(volatile CARD8 *)(ps3v->IOBase + (addr))
+#define VGAIN16(addr) *(volatile CARD16 *)(ps3v->IOBase + (addr))
+#define VGAIN(addr) *(volatile CARD32 *)(ps3v->IOBase + (addr))
+#define VGAOUT8(addr, val) *(volatile CARD8 *)(ps3v->IOBase + (addr)) = (val)
+#define VGAOUT16(addr, val) *(volatile CARD16 *)(ps3v->IOBase + (addr)) = (val)
+#define VGAOUT(addr, val) *(volatile CARD32 *)(ps3v->IOBase + (addr)) = (val)
+
+#define INREG(addr) *(volatile CARD32*)(ps3v->MapBase + (addr))
+#define OUTREG(addr, val) *(volatile CARD32 *)(ps3v->MapBase + (addr)) = (val)
+#define NEW_INREG(addr) INREG(addr)
+#define NEW_OUTREG(addr, val) OUTREG(addr, val)
+#endif /* __alpha__ */
+
+
+#endif /*_S3V_VGAHWMMIO_H*/
+
+/******************* s3v_i2c ****************************/
+
+Bool S3V_I2CInit(ScrnInfoPtr pScrn);
+
+/******************* s3v_accel ****************************/
+
+void S3VGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file);
+
+
+/*********************************************/
+/* locals */
+
+/* Some S3 ViRGE structs */
+#include "newmmio.h"
+
+/* More ViRGE defines */
+#include "regs3v.h"
+
+/*********************************************/
+
+
+
+/* Driver data structure; this should contain all needed info for a mode */
+/* used to be in s3v_driver.h for pre 4.0 */
+typedef struct {
+ unsigned char SR8;
+ unsigned char SR10, SR11, SR12, SR13, SR15, SR18; /* SR9-SR1C, ext seq. */
+ unsigned char SR29;
+ unsigned char SR54, SR55, SR56, SR57;
+ unsigned char Clock;
+ unsigned char s3DacRegs[0x101];
+ unsigned char CR31, CR33, CR34, CR36, CR3A, CR3B, CR3C;
+ unsigned char CR40, CR42, CR43, CR45;
+ unsigned char CR51, CR53, CR54, CR55, CR58, CR5D, CR5E;
+ unsigned char CR63, CR65, CR66, CR67, CR68, CR69, CR6D; /* Video attrib. */
+ unsigned char CR86;
+ unsigned char CR90;
+ unsigned char ColorStack[8]; /* S3 hw cursor color stack CR4A/CR4B */
+ unsigned int STREAMS[22]; /* Streams regs */
+ unsigned int MMPR0, MMPR1, MMPR2, MMPR3; /* MIU regs */
+} S3VRegRec, *S3VRegPtr;
+
+
+ /*************************/
+ /* S3VRec */
+ /*************************/
+typedef struct {
+ /* accel additions */
+ CARD32 AccelFlags;
+ CARD32 AccelCmd;
+ CARD32 SrcBaseY, DestBaseY;
+ CARD32 Stride;
+ CARD32 CommonCmd;
+ CARD32 FullPlaneMask;
+ GCPtr CurrentGC;
+ /* end accel stuff */
+ /* ViRGE specifics -start- */
+ /* S3V console saved mode registers */
+ S3VRegRec SavedReg;
+ /* XServer video state mode registers */
+ S3VRegRec ModeReg;
+ /* HW Cursor info */
+ xf86CursorInfoPtr CursorInfoRec;
+ /* Flag indicating ModeReg has been */
+ /* duped from console state. */
+ Bool ModeStructInit;
+ /* Is STREAMS processor needed for */
+ /* this mode? */
+ Bool NeedSTREAMS;
+ /* Is STREAMS running now ? */
+ Bool STREAMSRunning;
+ /* Compatibility variables */
+ int vgaCRIndex, vgaCRReg;
+ int Width, Bpp,Bpl, ScissB;
+ /* XAA */
+ unsigned PlaneMask;
+ int bltbug_width1, bltbug_width2;
+ /* In units as noted, set in PreInit */
+ int videoRambytes;
+ int videoRamKbytes;
+ /* In Kbytes, set in PreInit */
+ int MemOffScreen;
+ /* Holds the virtual memory address */
+ /* returned when the MMIO registers */
+ /* are mapped with xf86MapPciMem */
+ unsigned char * MapBase;
+#ifdef __alpha__
+ unsigned char * MapBaseDense;
+#endif
+
+ /* MapBase + 0x8000 */
+ unsigned char * IOBase;
+ /* Same as MapBase, except framebuffer*/
+ unsigned char * FBBase;
+ /* Current visual FB starting location */
+ unsigned char * FBStart;
+ /* Cursor storage location */
+ CARD32 FBCursorOffset;
+ /* Saved CR53 value */
+ unsigned char EnableMmioCR53;
+ /* Extended reg unlock storage */
+ unsigned char CR38,CR39,CR40;
+ /* Flag indicating if vgaHWMapMem was */
+ /* used successfully for this screen */
+ Bool PrimaryVidMapped;
+ /* Clock value */
+ int dacSpeedBpp;
+ int minClock;
+ /* Maximum clock for present bpp */
+ int maxClock;
+ int HorizScaleFactor;
+ Bool bankedMono;
+ /* Memory Clock */
+ int MCLK;
+ /* MX LCD clock */
+ int LCDClk;
+ /* Limit the number of errors */
+ /* printed using a counter */
+ int GEResetCnt;
+ /*************************/
+ /* ViRGE options -start- */
+
+ /* Enable PCI burst mode for reads? */
+ Bool pci_burst;
+ /* Diasable PCI retries */
+ Bool NoPCIRetry;
+ /* Adjust fifo for acceleration? */
+ Bool fifo_conservative;
+ Bool fifo_moderate;
+ Bool fifo_aggressive;
+ /* Set memory options */
+ Bool slow_edodram;
+ Bool fast_dram;
+ Bool fpm_vram;
+ /* Disable Acceleration */
+ Bool NoAccel;
+ /* Adjust memory ras precharge */
+ /* timing */
+ Bool ShowCache;
+ Bool early_ras_precharge;
+ Bool late_ras_precharge;
+ /* MX LCD centering */
+ Bool lcd_center;
+ /* hardware cursor enabled */
+ Bool hwcursor;
+ /* ViRGE options -end- */
+ /***********************/
+ /* ViRGE specifics -end- */
+
+ /* Used by ViRGE driver, but generic */
+
+ /* Pointer used to save wrapped */
+ /* CloseScreen function. */
+ CloseScreenProcPtr CloseScreen;
+ /* XAA info Rec */
+ XAAInfoRecPtr AccelInfoRec;
+ /* PCI info vars. */
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ /* Chip info, set using PCI */
+ /* above. */
+ int Chipset;
+ int ChipRev;
+ /* DGA2 */
+ DGAModePtr DGAModes;
+ int numDGAModes;
+ Bool DGAactive;
+ int DGAViewportStatus;
+ I2CBusPtr I2C;
+
+ /* Used by ViRGE driver, but generic -end- */
+
+
+} S3VRec, *S3VPtr;
+
+
+#define S3VPTR(p) ((S3VPtr)((p)->driverPrivate))
+
+
+/* #define S3V_DEBUG */
+
+#ifdef S3V_DEBUG
+#define PVERB5(arg) ErrorF(arg)
+#define VERBLEV 1
+#else
+#define PVERB5(arg) xf86ErrorFVerb(2, arg)
+#define VERBLEV 2
+#endif
+
+
+/******************* regs3v *******************************/
+
+/* #ifndef MetroLink */
+#if !defined (MetroLink) && !defined (VertDebug)
+#define VerticalRetraceWait() do { \
+ outb(vgaCRIndex, 0x17); \
+ if ( inb(vgaCRReg) & 0x80 ) { \
+ while ((inb(vgaIOBase + 0x0A) & 0x08) == 0x00) ; \
+ while ((inb(vgaIOBase + 0x0A) & 0x08) == 0x08) ; \
+ while ((inb(vgaIOBase + 0x0A) & 0x08) == 0x00) ; \
+ }\
+} while (0)
+
+#else
+#define SPIN_LIMIT 1000000
+#define VerticalRetraceWait() do { \
+ outb(vgaCRIndex, 0x17); \
+ if ( inb(vgaCRReg) & 0x80 ) { \
+ volatile unsigned long _spin_me; \
+ for (_spin_me = 0; \
+ ((inb(vgaIOBase + 0x0A) & 0x08) == 0x00) && _spin_me <= SPIN_LIMIT; \
+ _spin_me++) ; \
+ if (_spin_me > SPIN_LIMIT) \
+ ErrorF("s3v: warning: VerticalRetraceWait timed out.\n"); \
+ for (_spin_me = 0; \
+ ((inb(vgaIOBase + 0x0A) & 0x08) == 0x08) && _spin_me <= SPIN_LIMIT; \
+ _spin_me++) ; \
+ if (_spin_me > SPIN_LIMIT) \
+ ErrorF("s3v: warning: VerticalRetraceWait timed out.\n"); \
+ for (_spin_me = 0; \
+ ((inb(vgaIOBase + 0x0A) & 0x08) == 0x00) && _spin_me <= SPIN_LIMIT; \
+ _spin_me++) ; \
+ if (_spin_me > SPIN_LIMIT) \
+ ErrorF("s3v: warning: VerticalRetraceWait timed out.\n"); \
+ } \
+} while (0)
+#endif
+
+
+/*********************************************************/
+
+
+/* Various defines which are used to pass flags between the Setup and
+ * Subsequent functions.
+ */
+
+#define NO_MONO_FILL 0x00
+#define NEED_MONO_FILL 0x01
+#define MONO_TRANSPARENCY 0x02
+
+/* prototypes */
+/* s3v_dac.c */
+extern void S3VCommonCalcClock(long freq, int min_m, int min_n1, int max_n1,
+ int min_n2, int max_n2, long freq_min, long freq_max,
+ unsigned char * mdiv, unsigned char * ndiv);
+
+/* s3v_accel.c */
+extern Bool S3VAccelInit(ScreenPtr pScreen);
+extern Bool S3VAccelInit32(ScreenPtr pScreen);
+void S3VAccelSync(ScrnInfoPtr);
+
+/* s3v_hwcurs.c */
+extern Bool S3VHWCursorInit(ScreenPtr pScreen);
+
+/* s3v_driver.c */
+void S3VAdjustFrame(int scrnIndex, int x, int y, int flags);
+Bool S3VSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+
+/* s3v_dga.c */
+Bool S3VDGAInit(ScreenPtr pScreen);
+
+#endif /*_S3V_H*/
+
+
+/*EOF*/
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_accel.c
new file mode 100644
index 000000000..875c42d82
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_accel.c
@@ -0,0 +1,848 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_accel.c,v 1.13 1999/06/27 14:08:12 dawes Exp $ */
+
+/*
+Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+XFREE86 PROJECT 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 XFree86 Project 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 XFree86 Project.
+*/
+
+#include "s3v.h"
+#include "s3v_macros.h"
+
+#include "miline.h"
+ /* cfb includes are in s3v.h */
+#include "xaalocal.h"
+#include "xaarop.h"
+
+#include "servermd.h" /* LOG2_BYTES_PER_SCANLINE_PAD */
+
+static void S3VWriteMask(CARD32*, int);
+
+static void S3VEngineReset(ScrnInfoPtr pScrn);
+/* s3v.h - static void S3VAccelSync(ScrnInfoPtr); */
+static void S3VSetupForSolidFill(ScrnInfoPtr, int, int, unsigned);
+static void S3VSubsequentSolidFillRect(ScrnInfoPtr, int, int, int, int);
+static void S3VSubsequentSolidFillRectPlaneMask(ScrnInfoPtr, int, int,
+ int, int);
+static void S3VSetupForMono8x8PatternFill(ScrnInfoPtr,int, int, int, int,
+ int, unsigned int);
+static void S3VSubsequentMono8x8PatternFillRect(ScrnInfoPtr,int, int,
+ int, int, int, int);
+static void S3VSubsequentMono8x8PatternFillRectPlaneMask(ScrnInfoPtr,int, int,
+ int, int, int, int);
+static void S3VSetupForScreenToScreenCopy(ScrnInfoPtr, int, int, int,
+ unsigned int, int);
+static void S3VSubsequentScreenToScreenCopy(ScrnInfoPtr, int, int, int, int,
+ int, int);
+static void S3VSetupForCPUToScreenColorExpand(ScrnInfoPtr, int, int, int,
+ unsigned int);
+static void S3VSubsequentCPUToScreenColorExpand(ScrnInfoPtr, int, int, int,
+ int, int);
+static void S3VSetupForImageWrite(ScrnInfoPtr, int, unsigned int, int,
+ int, int);
+static void S3VSubsequentImageWriteRect(ScrnInfoPtr, int, int, int, int, int);
+static void S3VSubsequentSolidHorVertLine(ScrnInfoPtr, int, int, int, int);
+static void S3VSubsequentSolidHorVertLinePlaneMask(ScrnInfoPtr, int, int,
+ int, int);
+static void S3VSubsequentSolidBresenhamLine(ScrnInfoPtr, int, int, int,
+ int, int, int, int);
+static void S3VPolylinesThinSolidWrapper(DrawablePtr, GCPtr, int, int,
+ DDXPointPtr);
+static void S3VPolySegmentThinSolidWrapper(DrawablePtr, GCPtr, int, xSegment*);
+
+Bool
+S3VAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ S3VPtr ps3v = S3VPTR(pScrn);
+ BoxRec AvailFBArea;
+
+ ps3v->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if(!infoPtr) return FALSE;
+
+
+ switch(ps3v->Chipset) {
+ case S3_ViRGE:
+ case S3_ViRGE_VX:
+ ps3v->AccelFlags = BLT_BUG;
+ default:
+ ps3v->AccelFlags = 0;
+ break;
+ }
+
+ ps3v->AccelFlags |= MONO_TRANS_BUG; /* which aren't broken ? */
+
+
+ infoPtr->Flags = PIXMAP_CACHE |
+ LINEAR_FRAMEBUFFER |
+ OFFSCREEN_PIXMAPS;
+
+ infoPtr->Sync = S3VAccelSync;
+
+ /* Solid filled rects */
+ infoPtr->SetupForSolidFill =
+ S3VSetupForSolidFill;
+ infoPtr->SubsequentSolidFillRect =
+ S3VSubsequentSolidFillRect;
+
+ /* Screen to screen copies */
+ infoPtr->SetupForScreenToScreenCopy =
+ S3VSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy =
+ S3VSubsequentScreenToScreenCopy;
+ infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
+
+ /* Mono 8x8 patterns */
+ infoPtr->SetupForMono8x8PatternFill =
+ S3VSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ S3VSubsequentMono8x8PatternFillRect;
+ infoPtr->Mono8x8PatternFillFlags = NO_TRANSPARENCY |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ BIT_ORDER_IN_BYTE_LSBFIRST;
+
+
+#ifndef __alpha__
+ /* CPU to screen color expansion */
+ infoPtr->CPUToScreenColorExpandFillFlags = ROP_NEEDS_SOURCE |
+ CPU_TRANSFER_PAD_DWORD |
+ SCANLINE_PAD_DWORD |
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ LEFT_EDGE_CLIPPING;
+
+ if(ps3v->AccelFlags & MONO_TRANS_BUG)
+ infoPtr->CPUToScreenColorExpandFillFlags |= NO_TRANSPARENCY;
+
+ infoPtr->ColorExpandRange = 0x8000;
+#ifdef __alpha__
+ infoPtr->ColorExpandBase = ps3v->MapBaseDense;
+#else
+ infoPtr->ColorExpandBase = ps3v->MapBase;
+#endif /* __alpha__ */
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ S3VSetupForCPUToScreenColorExpand;
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ S3VSubsequentCPUToScreenColorExpand;
+
+
+ /* Image Writes */
+ infoPtr->ImageWriteFlags = ROP_NEEDS_SOURCE |
+ NO_TRANSPARENCY |
+ CPU_TRANSFER_PAD_DWORD |
+ SCANLINE_PAD_DWORD |
+ LEFT_EDGE_CLIPPING;
+
+ infoPtr->ImageWriteRange = 0x8000;
+#ifdef __alpha__
+ infoPtr->ImageWriteBase = ps3v->MapBaseDense;
+#else
+ infoPtr->ImageWriteBase = ps3v->MapBase;
+#endif /* __alpha__ */
+ infoPtr->SetupForImageWrite = S3VSetupForImageWrite;
+ infoPtr->SubsequentImageWriteRect = S3VSubsequentImageWriteRect;
+
+ /* on alpha, I see corruption in the xscreensaver program "hypercube"
+ as the line acceleration is just stubs, it loses us nothing to
+ disable it on alphas */
+
+ /* Lines */
+ infoPtr->SetupForSolidLine = S3VSetupForSolidFill;
+ infoPtr->SubsequentSolidHorVertLine = S3VSubsequentSolidHorVertLine;
+ infoPtr->SubsequentSolidBresenhamLine = S3VSubsequentSolidBresenhamLine;
+ infoPtr->PolySegmentThinSolid = S3VPolySegmentThinSolidWrapper;
+ infoPtr->PolylinesThinSolid = S3VPolylinesThinSolidWrapper;
+
+#endif /* !__alpha__ */
+
+ /* And these are screen parameters used to setup the GE */
+
+ ps3v->Width = pScrn->displayWidth;
+ /* Bytes per pixel */
+ ps3v->Bpp = pScrn->bitsPerPixel / 8;
+ /* Bytes per line */
+ ps3v->Bpl = ps3v->Width * ps3v->Bpp;
+ /* ScissB is max height, minus 1k */
+ /* for hwcursor?, then limited by */
+ /* ViRGE max height register of */
+ /* 2047 */
+ ps3v->ScissB = (pScrn->videoRam * 1024 - 1024) / ps3v->Bpl;
+ if (ps3v->ScissB > 2047)
+ ps3v->ScissB = 2047;
+
+
+ S3VEngineReset(pScrn);
+
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = (pScrn->videoRam * 1024 - 1024) /
+ (pScrn->displayWidth * pScrn->bitsPerPixel / 8);
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ /* make sure offscreen pixmaps aren't bigger than our address space */
+ infoPtr->maxOffPixWidth = 2048;
+ infoPtr->maxOffPixHeight = 2048;
+
+ return (XAAInit(pScreen, infoPtr));
+}
+
+
+Bool
+S3VAccelInit32(ScreenPtr pScreen)
+{
+ return FALSE;
+}
+
+void
+S3VGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file)
+{
+ unsigned char tmp;
+ int r;
+ CARD32 fifo_control = 0, miu_control = 0;
+ CARD32 streams_timeout = 0, misc_timeout = 0;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ S3VPtr ps3v = S3VPTR(pScrn);
+ int vgaCRIndex, vgaCRReg, vgaIOBase;
+ vgaIOBase = hwp->IOBase;
+ vgaCRIndex = vgaIOBase + 4;
+ vgaCRReg = vgaIOBase + 5;
+
+
+ if (from_timeout) {
+ if (ps3v->GEResetCnt++ < 10 || xf86GetVerbosity() > 1)
+ ErrorF("\tS3VGEReset called from %s line %d\n",file,line);
+ }
+ else
+ WaitIdleEmpty();
+
+
+ if (from_timeout && (ps3v->Chipset == S3_ViRGE || ps3v->Chipset == S3_ViRGE_VX || ps3v->Chipset == S3_ViRGE_DXGX)) {
+ /* reset will trash these registers, so save them */
+ fifo_control = INREG(FIFO_CONTROL_REG);
+ miu_control = INREG(MIU_CONTROL_REG);
+ streams_timeout = INREG(STREAMS_TIMEOUT_REG);
+ misc_timeout = INREG(MISC_TIMEOUT_REG);
+ }
+
+ if(ps3v->Chipset == S3_ViRGE_VX){
+ VGAOUT8(vgaCRIndex, 0x63);
+ }
+ else {
+ VGAOUT8(vgaCRIndex, 0x66);
+ }
+ tmp = VGAIN8(vgaCRReg);
+
+ usleep(10000);
+ for (r=1; r<10; r++) { /* try multiple times to avoid lockup of ViRGE/MX */
+ VGAOUT8(vgaCRReg, tmp | 0x02);
+ usleep(10000);
+ VGAOUT8(vgaCRReg, tmp & ~0x02);
+ usleep(10000);
+
+ xf86ErrorFVerb(VERBLEV, " S3VGEReset sub_stat=%x \n",
+ IN_SUBSYS_STAT()
+ );
+
+ if (!from_timeout)
+ WaitIdleEmpty();
+
+ OUTREG(DEST_SRC_STR, ps3v->Bpl << 16 | ps3v->Bpl);
+
+ usleep(10000);
+ if (((IN_SUBSYS_STAT() & 0x3f00) != 0x3000))
+ xf86ErrorFVerb(VERBLEV, "restarting S3 graphics engine reset %2d ...\n",r);
+ else
+ break;
+ }
+
+ if (from_timeout && (ps3v->Chipset == S3_ViRGE || ps3v->Chipset == S3_ViRGE_VX
+ || ps3v->Chipset == S3_ViRGE_DXGX)) {
+ /* restore trashed registers */
+ OUTREG(FIFO_CONTROL_REG, fifo_control);
+ OUTREG(MIU_CONTROL_REG, miu_control);
+ OUTREG(STREAMS_TIMEOUT_REG, streams_timeout);
+ OUTREG(MISC_TIMEOUT_REG, misc_timeout);
+ }
+
+ WAITFIFO(2);
+/* SETB_SRC_BASE(0); */
+/* SETB_DEST_BASE(0); */
+ OUTREG(SRC_BASE, 0);
+ OUTREG(DEST_BASE, 0);
+
+ WAITFIFO(4);
+ OUTREG(CLIP_L_R, ((0) << 16) | ps3v->Width);
+ OUTREG(CLIP_T_B, ((0) << 16) | ps3v->ScissB);
+ OUTREG(MONO_PAT_0, ~0);
+ OUTREG(MONO_PAT_1, ~0);
+
+}
+
+/* The sync function for the GE */
+void
+S3VAccelSync(ScrnInfoPtr pScrn)
+{
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ WAITIDLE();
+}
+
+
+static void
+S3VEngineReset(ScrnInfoPtr pScrn)
+{
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ ps3v->SrcBaseY = 0;
+ ps3v->DestBaseY = 0;
+ ps3v->Stride = pScrn->displayWidth * pScrn->bitsPerPixel >> 3;
+
+ switch(pScrn->bitsPerPixel) {
+ case 8: ps3v->CommonCmd = DRAW | DST_8BPP;
+ ps3v->FullPlaneMask = 0x000000ff;
+ ps3v->bltbug_width1 = 51;
+ ps3v->bltbug_width2 = 64;
+ break;
+ case 16: ps3v->CommonCmd = DRAW | DST_16BPP;
+ ps3v->FullPlaneMask = 0x0000ffff;
+ ps3v->bltbug_width1 = 26;
+ ps3v->bltbug_width2 = 32;
+ break;
+ case 24: ps3v->CommonCmd = DRAW | DST_24BPP;
+ ps3v->FullPlaneMask = 0x00ffffff;
+ ps3v->bltbug_width1 = 16;
+ ps3v->bltbug_width2 = 22;
+ break;
+ }
+
+
+ WAITFIFO(5);
+ OUTREG(SRC_BASE, 0);
+ OUTREG(DEST_BASE, 0);
+ OUTREG(DEST_SRC_STR, ps3v->Stride | (ps3v->Stride << 16));
+
+ OUTREG(CLIP_L_R, ((0) << 16) | ps3v->Width);
+ OUTREG(CLIP_T_B, ((0) << 16) | ps3v->ScissB);
+}
+
+
+static void
+S3VWriteMask(
+ CARD32 *dstBase,
+ int dwords
+){
+ /* on alphas, be sure to call this with MapBaseDense, not MapBase! */
+ int numLeft;
+ CARD32 *dst = dstBase;
+
+ while(dwords >= 8192) {
+ numLeft = 8192;
+ while(numLeft) {
+ dst[0] = ~0; dst[1] = ~0;
+ dst[2] = ~0; dst[3] = ~0;
+ dst += 4;
+ numLeft -= 4;
+ }
+ dwords -= 8192;
+ dst = dstBase;
+ }
+ while(dwords >= 4) {
+ dst[0] = ~0; dst[1] = ~0;
+ dst[2] = ~0; dst[3] = ~0;
+ dst += 4;
+ dwords -= 4;
+ }
+ if(!dwords) return;
+ dst[0] = ~0;
+ if(dwords == 1) return;
+ dst[1] = ~0;
+ if(dwords == 2) return;
+ dst[2] = ~0;
+
+ return;
+}
+
+
+ /************************\
+ | Solid Filled Rects |
+ \************************/
+
+static void
+S3VSetupForSolidFill(
+ ScrnInfoPtr pScrn,
+ int color, int rop,
+ unsigned int planemask
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+ int mix;
+
+ mix = XAAHelpSolidROP(pScrn, &color, planemask, &rop);
+
+ ps3v->AccelCmd = ps3v->CommonCmd | (rop << 17) |
+ CMD_XP | CMD_YP | CMD_AUTOEXEC | CMD_BITBLT;
+
+ if(mix & ROP_SRC) {
+ ps3v->AccelCmd |= MIX_CPUDATA | CMD_ITA_DWORD | MIX_MONO_SRC;
+ ps3v->AccelInfoRec->SubsequentSolidFillRect =
+ S3VSubsequentSolidFillRectPlaneMask;
+ ps3v->AccelInfoRec->SubsequentSolidHorVertLine =
+ S3VSubsequentSolidHorVertLinePlaneMask;
+ WAITFIFO(5);
+ OUTREG(SRC_FG_CLR, planemask);
+ } else {
+ ps3v->AccelInfoRec->SubsequentSolidFillRect =
+ S3VSubsequentSolidFillRect;
+ ps3v->AccelInfoRec->SubsequentSolidHorVertLine =
+ S3VSubsequentSolidHorVertLine;
+ WAITFIFO(4);
+ }
+
+ if(mix & ROP_PAT) {
+ ps3v->AccelCmd |= MIX_MONO_PATT;
+ OUTREG(PAT_FG_CLR, color);
+ OUTREG(MONO_PAT_0, ~0);
+ OUTREG(MONO_PAT_1, ~0);
+ }
+
+ OUTREG(CMD_SET, ps3v->AccelCmd);
+}
+
+
+void
+S3VSubsequentSolidFillRect(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ CHECK_DEST_BASE(y,h);
+
+ WAITFIFO(2);
+ OUTREG(RWIDTH_HEIGHT, ((w - 1) << 16) | h);
+ OUTREG(RDEST_XY, (x << 16) | y);
+}
+
+
+void
+S3VSubsequentSolidFillRectPlaneMask(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+ int dwords;
+
+ CHECK_DEST_BASE(y,h);
+
+ dwords = ((w + 31) >> 5) * h;
+
+ WAITFIFO(2);
+ OUTREG(RWIDTH_HEIGHT, ((w - 1) << 16) | h);
+ OUTREG(RDEST_XY, (x << 16) | y);
+#ifndef __alpha__
+ S3VWriteMask((CARD32*)ps3v->MapBase, dwords);
+#else
+ S3VWriteMask((CARD32*)ps3v->MapBaseDense, dwords);
+#endif
+}
+
+
+ /**************************\
+ | Screen to Screen Copies |
+ \**************************/
+
+static void
+S3VSetupForScreenToScreenCopy(
+ ScrnInfoPtr pScrn,
+ int xdir, int ydir,
+ int rop,
+ unsigned int planemask,
+ int trans
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ planemask &= ps3v->FullPlaneMask;
+ ps3v->AccelCmd = ps3v->CommonCmd | CMD_AUTOEXEC | CMD_BITBLT;
+
+ if(planemask != ps3v->FullPlaneMask) {
+ ps3v->AccelCmd |= (XAACopyROP_PM[rop] << 17) | MIX_MONO_PATT;
+ WAITFIFO(4);
+ OUTREG(PAT_FG_CLR, planemask);
+ OUTREG(MONO_PAT_0, ~0);
+ OUTREG(MONO_PAT_1, ~0);
+ }
+ else {
+ ps3v->AccelCmd |= XAACopyROP[rop] << 17;
+ WAITFIFO(1);
+ }
+ if(xdir == 1) ps3v->AccelCmd |= CMD_XP;
+ if(ydir == 1) ps3v->AccelCmd |= CMD_YP;
+
+ OUTREG(CMD_SET, ps3v->AccelCmd);
+}
+
+
+static void
+S3VSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h)
+{
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ CHECK_SRC_BASE(y1,h);
+ CHECK_DEST_BASE(y2,h);
+
+ w--;
+
+ if(!(ps3v->AccelCmd & CMD_YP)) {
+ y1 += h - 1; y2 += h - 1;
+ }
+
+ if(!(ps3v->AccelCmd & CMD_XP)) {
+ x1 += w; x2 += w;
+ }
+
+ WAITFIFO(3);
+ OUTREG(RWIDTH_HEIGHT, (w << 16) | h);
+ OUTREG(RSRC_XY, (x1 << 16) | y1);
+ OUTREG(RDEST_XY, (x2 << 16) | y2);
+}
+
+
+ /*********************\
+ | 8x8 Pattern fills |
+ \*********************/
+
+
+static void
+S3VSetupForMono8x8PatternFill(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int fg, int bg,
+ int rop, unsigned int planemask
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+ int mix;
+
+ mix = XAAHelpPatternROP(pScrn, &fg, &bg, planemask, &rop);
+
+ ps3v->AccelCmd = ps3v->CommonCmd | (rop << 17) |
+ CMD_XP | CMD_YP | CMD_AUTOEXEC | CMD_BITBLT;
+
+ if(mix & ROP_SRC) {
+ ps3v->AccelCmd |= MIX_CPUDATA | CMD_ITA_DWORD | MIX_MONO_SRC;
+ ps3v->AccelInfoRec->SubsequentMono8x8PatternFillRect =
+ S3VSubsequentMono8x8PatternFillRectPlaneMask;
+ WAITFIFO(6);
+ OUTREG(SRC_FG_CLR, planemask);
+ } else {
+ ps3v->AccelInfoRec->SubsequentMono8x8PatternFillRect =
+ S3VSubsequentMono8x8PatternFillRect;
+ WAITFIFO(5);
+ }
+
+ if(mix & ROP_PAT) {
+ ps3v->AccelCmd |= MIX_MONO_PATT;
+ OUTREG(PAT_FG_CLR, fg);
+ OUTREG(PAT_BG_CLR, bg);
+ OUTREG(MONO_PAT_0, patx);
+ OUTREG(MONO_PAT_1, paty);
+ }
+
+ OUTREG(CMD_SET, ps3v->AccelCmd);
+}
+
+
+static void
+S3VSubsequentMono8x8PatternFillRect(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ CHECK_DEST_BASE(y,h);
+
+ WAITFIFO(2);
+ OUTREG(RWIDTH_HEIGHT, ((w - 1) << 16) | h);
+ OUTREG(RDEST_XY, (x << 16) | y);
+}
+
+
+static void
+S3VSubsequentMono8x8PatternFillRectPlaneMask(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+ int dwords;
+
+ CHECK_DEST_BASE(y,h);
+
+ dwords = ((w + 31) >> 5) * h;
+
+ WAITFIFO(2);
+ OUTREG(RWIDTH_HEIGHT, ((w - 1) << 16) | h);
+ OUTREG(RDEST_XY, (x << 16) | y);
+
+#ifndef __alpha__
+ S3VWriteMask((CARD32*)ps3v->MapBase, dwords);
+#else
+ S3VWriteMask((CARD32*)ps3v->MapBaseDense, dwords);
+#endif
+}
+
+ /*********************************\
+ | CPU to Screen Color Expansion |
+ \*********************************/
+
+
+static void
+S3VSetupForCPUToScreenColorExpand(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ planemask &= ps3v->FullPlaneMask;
+ ps3v->AccelCmd = ps3v->CommonCmd | CMD_AUTOEXEC | CMD_BITBLT |
+ CMD_XP | CMD_YP | CMD_ITA_DWORD | CMD_HWCLIP |
+ MIX_CPUDATA | MIX_MONO_SRC;
+
+
+ if(planemask == ps3v->FullPlaneMask) {
+ ps3v->AccelCmd |= XAACopyROP[rop] << 17;
+ WAITFIFO(3);
+ } else {
+ ps3v->AccelCmd |= (XAACopyROP_PM[rop] << 17) | MIX_MONO_PATT;
+ WAITFIFO(6);
+ OUTREG(MONO_PAT_0, ~0);
+ OUTREG(MONO_PAT_1, ~0);
+ OUTREG(PAT_FG_CLR, planemask);
+ }
+
+ if(bg == -1)
+ ps3v->AccelCmd |= MIX_MONO_TRANSP;
+ else
+ OUTREG(SRC_BG_CLR, bg);
+
+ OUTREG(SRC_FG_CLR, fg);
+ OUTREG(CMD_SET, ps3v->AccelCmd);
+}
+
+
+void
+S3VSubsequentCPUToScreenColorExpand(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h,
+ int skipleft
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ CHECK_DEST_BASE(y,h);
+
+ WAITFIFO(3);
+ OUTREG(CLIP_L_R, ((x + skipleft) << 16) | 0xffff);
+ OUTREG(RWIDTH_HEIGHT, ((w - 1) << 16) | h);
+ OUTREG(RDEST_XY, (x << 16) | y);
+}
+
+
+ /****************\
+ | Image Writes |
+ \****************/
+
+
+static void
+S3VSetupForImageWrite(
+ ScrnInfoPtr pScrn,
+ int rop, unsigned int planemask,
+ int trans_color, int bpp, int depth
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ planemask &= ps3v->FullPlaneMask;
+ ps3v->AccelCmd = ps3v->CommonCmd | CMD_AUTOEXEC | CMD_BITBLT |
+ MIX_CPUDATA | CMD_ITA_DWORD | CMD_HWCLIP | CMD_XP | CMD_YP;
+
+ if(planemask != ps3v->FullPlaneMask) {
+ ps3v->AccelCmd |= (XAACopyROP_PM[rop] << 17) | MIX_MONO_PATT;
+ WAITFIFO(4);
+ OUTREG(PAT_FG_CLR, planemask);
+ OUTREG(MONO_PAT_0, ~0);
+ OUTREG(MONO_PAT_1, ~0);
+ } else {
+ ps3v->AccelCmd |= XAACopyROP[rop] << 17;
+ WAITFIFO(1);
+ }
+
+ OUTREG(CMD_SET, ps3v->AccelCmd);
+}
+
+
+static void
+S3VSubsequentImageWriteRect(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int w, int h,
+ int skipleft
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ CHECK_DEST_BASE(y,h);
+
+ WAITFIFO(3);
+ OUTREG(CLIP_L_R, ((x + skipleft) << 16) | 0xffff);
+ OUTREG(RWIDTH_HEIGHT, ((w - 1) << 16) | h);
+ OUTREG(RDEST_XY, (x << 16) | y);
+}
+
+
+ /***********\
+ | Lines |
+ \***********/
+
+static void
+S3VPolylinesThinSolidWrapper(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ S3VPtr ps3v = S3VPTR(infoRec->pScrn);
+ ps3v->CurrentGC = pGC;
+ if(infoRec->NeedToSync)
+ S3VAccelSync(infoRec->pScrn);
+ XAAPolyLines(pDraw, pGC, mode, npt, pPts);
+}
+
+static void
+S3VPolySegmentThinSolidWrapper(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ S3VPtr ps3v = S3VPTR(infoRec->pScrn);
+ ps3v->CurrentGC = pGC;
+ if(infoRec->NeedToSync)
+ S3VAccelSync(infoRec->pScrn);
+ XAAPolySegment(pDraw, pGC, nseg, pSeg);
+}
+
+static void
+S3VSubsequentSolidHorVertLine(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int len, int dir
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+ int w, h;
+
+ if(dir == DEGREES_0) {
+ w = len; h = 1;
+ } else {
+ w = 1; h = len;
+ }
+
+ CHECK_DEST_BASE(y,h);
+
+ WAITFIFO(2);
+ OUTREG(RWIDTH_HEIGHT, ((w - 1) << 16) | h);
+ OUTREG(RDEST_XY, (x << 16) | y);
+}
+
+static void
+S3VSubsequentSolidHorVertLinePlaneMask(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int len, int dir
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+ int w, h, dwords;
+
+ if(dir == DEGREES_0) {
+ w = len; h = 1; dwords = (len + 31) >> 5;
+ } else {
+ w = 1; h = len; dwords = len;
+ }
+
+ CHECK_DEST_BASE(y,h);
+
+ WAITFIFO(2);
+ OUTREG(RWIDTH_HEIGHT, ((w - 1) << 16) | h);
+ OUTREG(RDEST_XY, (x << 16) | y);
+
+#ifndef __alpha__
+ S3VWriteMask((CARD32*)ps3v->MapBase, dwords);
+#else
+ S3VWriteMask((CARD32*)ps3v->MapBaseDense, dwords);
+#endif
+}
+
+
+void (*LineFuncs[3])() = {
+ cfbBresS,
+ cfb16BresS,
+ cfb24BresS
+};
+
+
+static void
+S3VSubsequentSolidBresenhamLine(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int dmaj, int dmin,
+ int e, int len, int octant
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+ cfbPrivGCPtr devPriv;
+ int Bpp = pScrn->bitsPerPixel >> 3;
+
+ devPriv = cfbGetGCPrivate(ps3v->CurrentGC);
+
+ /* you could trap for lines you could do here and accelerate them */
+
+ (*LineFuncs[Bpp - 1])
+ (devPriv->rop, devPriv->and, devPriv->xor,
+ (unsigned long*)ps3v->FBBase,
+ (pScrn->displayWidth * Bpp) >> LOG2_BYTES_PER_SCANLINE_PAD,
+ (octant & XDECREASING) ? -1 : 1,
+ (octant & YDECREASING) ? -1 : 1,
+ (octant & YMAJOR) ? Y_AXIS : X_AXIS,
+ x, y, dmin + e, dmin, dmin - dmaj, len);
+}
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_dac.c b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_dac.c
new file mode 100644
index 000000000..de701f7f6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_dac.c
@@ -0,0 +1,109 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_dac.c,v 1.3 1999/03/29 12:17:55 dawes Exp $ */
+
+/*
+Copyright (C) 1994-1998 The XFree86 Project, Inc. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+XFREE86 PROJECT 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 XFree86 Project 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 XFree86 Project.
+*/
+
+/*
+ * s3v_dac.c
+ * Port to 4.0 design level
+ *
+ * S3 ViRGE driver
+ *
+ *
+ * s3vcommonCalcClock from S3gendac.c in pre 4.0 tree.
+ *
+ */
+
+#include "s3v.h"
+
+
+#define BASE_FREQ 14.31818 /* MHz */
+
+
+ /* function */
+void
+S3VCommonCalcClock(long freq, int min_m, int min_n1, int max_n1, int min_n2, int max_n2,
+ long freq_min, long freq_max,
+ unsigned char * mdiv, unsigned char * ndiv)
+{
+ double ffreq, ffreq_min, ffreq_max;
+ double div, diff, best_diff;
+ unsigned int m;
+ unsigned char n1, n2;
+ unsigned char best_n1=16+2, best_n2=2, best_m=125+2;
+
+ ffreq = freq / 1000.0 / BASE_FREQ;
+ ffreq_min = freq_min / 1000.0 / BASE_FREQ;
+ ffreq_max = freq_max / 1000.0 / BASE_FREQ;
+
+ if (ffreq < ffreq_min / (1<<max_n2)) {
+ ErrorF("invalid frequency %1.3f MHz [freq >= %1.3f MHz]\n",
+ ffreq*BASE_FREQ, ffreq_min*BASE_FREQ / (1<<max_n2));
+ ffreq = ffreq_min / (1<<max_n2);
+ }
+ if (ffreq > ffreq_max / (1<<min_n2)) {
+ ErrorF("invalid frequency %1.3f MHz [freq <= %1.3f MHz]\n",
+ ffreq*BASE_FREQ, ffreq_max*BASE_FREQ / (1<<min_n2));
+ ffreq = ffreq_max / (1<<min_n2);
+ }
+
+ /* work out suitable timings */
+
+ best_diff = ffreq;
+
+ for (n2=min_n2; n2<=max_n2; n2++) {
+ for (n1 = min_n1+2; n1 <= max_n1+2; n1++) {
+ m = (int)(ffreq * n1 * (1<<n2) + 0.5) ;
+ if (m < min_m+2 || m > 127+2)
+ continue;
+ div = (double)(m) / (double)(n1);
+ if ((div >= ffreq_min) &&
+ (div <= ffreq_max)) {
+ diff = ffreq - div / (1<<n2);
+ if (diff < 0.0)
+ diff = -diff;
+ if (diff < best_diff) {
+ best_diff = diff;
+ best_m = m;
+ best_n1 = n1;
+ best_n2 = n2;
+ }
+ }
+ }
+ }
+
+#ifdef EXTENDED_DEBUG
+ ErrorF("Clock parameters for %1.6f MHz: m=%d, n1=%d, n2=%d\n",
+ ((double)(best_m) / (double)(best_n1) / (1 << best_n2)) * BASE_FREQ,
+ best_m-2, best_n1-2, best_n2);
+#endif
+
+ if (max_n1 == 63)
+ *ndiv = (best_n1 - 2) | (best_n2 << 6);
+ else
+ *ndiv = (best_n1 - 2) | (best_n2 << 5);
+ *mdiv = best_m - 2;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_dga.c
new file mode 100644
index 000000000..cd0bbc55f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_dga.c
@@ -0,0 +1,309 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_dga.c,v 1.4 1999/07/18 08:14:33 dawes Exp $ */
+
+/*
+ * file: s3v_dga.c
+ * ported from mga
+ *
+ */
+
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "s3v.h"
+#if 0
+#include "mga_bios.h"
+#include "mga.h"
+#include "mga_reg.h"
+#include "mga_macros.h"
+#endif
+#include "dgaproc.h"
+
+
+static Bool S3V_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
+ int *, int *, int *);
+static Bool S3V_SetMode(ScrnInfoPtr, DGAModePtr);
+static int S3V_GetViewport(ScrnInfoPtr);
+static void S3V_SetViewport(ScrnInfoPtr, int, int, int);
+static void S3V_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
+static void S3V_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+/* dummy... */
+#if 0
+static void MGA_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
+ unsigned long);
+#endif
+
+static
+DGAFunctionRec S3V_DGAFuncs = {
+ S3V_OpenFramebuffer,
+ NULL,
+ S3V_SetMode,
+ S3V_SetViewport,
+ S3V_GetViewport,
+ S3VAccelSync,
+ S3V_FillRect,
+ S3V_BlitRect,
+ NULL
+ /* dummy... MGA_BlitTransRect */
+};
+
+
+Bool
+S3VDGAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ S3VPtr ps3v = S3VPTR(pScrn);
+ DGAModePtr modes = NULL, newmodes = NULL, currentMode;
+ DisplayModePtr pMode, firstMode;
+ int Bpp = pScrn->bitsPerPixel >> 3;
+ int num = 0;
+ Bool oneMore;
+
+ PVERB5(" S3VDGAInit\n");
+
+ pMode = firstMode = pScrn->modes;
+
+ while(pMode) {
+ /* The MGA driver wasn't designed with switching depths in
+ mind. Subsequently, large chunks of it will probably need
+ to be rewritten to accommodate depth changes in DGA mode */
+
+ if(0 /*pScrn->displayWidth != pMode->HDisplay*/) {
+ newmodes = xrealloc(modes, (num + 2) * sizeof(DGAModeRec));
+ oneMore = TRUE;
+ } else {
+ newmodes = xrealloc(modes, (num + 1) * sizeof(DGAModeRec));
+ oneMore = FALSE;
+ }
+
+ if(!newmodes) {
+ xfree(modes);
+ return FALSE;
+ }
+ modes = newmodes;
+
+SECOND_PASS:
+
+ currentMode = modes + num;
+ num++;
+
+ currentMode->mode = pMode;
+ currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
+ if(!ps3v->NoAccel)
+ currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
+ if(pMode->Flags & V_DBLSCAN)
+ currentMode->flags |= DGA_DOUBLESCAN;
+ if(pMode->Flags & V_INTERLACE)
+ currentMode->flags |= DGA_INTERLACED;
+ currentMode->byteOrder = pScrn->imageByteOrder;
+ currentMode->depth = pScrn->depth;
+ currentMode->bitsPerPixel = pScrn->bitsPerPixel;
+ currentMode->red_mask = pScrn->mask.red;
+ currentMode->green_mask = pScrn->mask.green;
+ currentMode->blue_mask = pScrn->mask.blue;
+ currentMode->visualClass = (Bpp == 1) ? PseudoColor : TrueColor;
+ currentMode->viewportWidth = pMode->HDisplay;
+ currentMode->viewportHeight = pMode->VDisplay;
+ /* currentMode->xViewportStep = (3 - ps3v->BppShift); */
+ /* always 1 on ViRGE ? */
+ currentMode->xViewportStep = 1;
+ currentMode->yViewportStep = 1;
+ currentMode->viewportFlags = DGA_FLIP_RETRACE;
+ /* currentMode->offset = ps3v->YDstOrg * (pScrn->bitsPerPixel / 8);
+ * MGA, 0 for ViRGE */
+ currentMode->offset = 0;
+ /* currentMode->address = pMga->FbStart; MGA */
+ currentMode->address = ps3v->FBBase;
+/*cep*/
+ xf86ErrorFVerb(VERBLEV,
+ " S3VDGAInit firstone vpWid=%d, vpHgt=%d, Bpp=%d, mdbitsPP=%d\n",
+ currentMode->viewportWidth,
+ currentMode->viewportHeight,
+ Bpp,
+ currentMode->bitsPerPixel
+ );
+
+
+ if(oneMore) { /* first one is narrow width */
+ currentMode->bytesPerScanline = ((pMode->HDisplay * Bpp) + 3) & ~3L;
+ currentMode->imageWidth = pMode->HDisplay;
+ /* currentMode->imageHeight = pMga->FbUsableSize /
+ currentMode->bytesPerScanline;
+ MGA above */
+ currentMode->imageHeight = pMode->VDisplay;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+ oneMore = FALSE;
+
+/*cep*/
+ xf86ErrorFVerb(VERBLEV,
+ " S3VDGAInit imgHgt=%d, ram=%d, bytesPerScanl=%d\n",
+ currentMode->imageHeight,
+ ps3v->videoRambytes,
+ currentMode->bytesPerScanline );
+
+ goto SECOND_PASS;
+ } else {
+ currentMode->bytesPerScanline =
+ ((pScrn->displayWidth * Bpp) + 3) & ~3L;
+ currentMode->imageWidth = pScrn->displayWidth;
+ /* currentMode->imageHeight = pMga->FbUsableSize /
+ currentMode->bytesPerScanline;
+ */
+ currentMode->imageHeight = ps3v->videoRambytes /
+ currentMode->bytesPerScanline;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+ }
+
+ pMode = pMode->next;
+ if(pMode == firstMode)
+ break;
+ }
+
+ ps3v->numDGAModes = num;
+ ps3v->DGAModes = modes;
+
+ return DGAInit(pScreen, &S3V_DGAFuncs, modes, num);
+}
+
+
+static Bool
+S3V_SetMode(
+ ScrnInfoPtr pScrn,
+ DGAModePtr pMode
+){
+ static int OldDisplayWidth[MAXSCREENS];
+ int index = pScrn->pScreen->myNum;
+
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ if(!pMode) { /* restore the original mode */
+ /* put the ScreenParameters back */
+
+ pScrn->displayWidth = OldDisplayWidth[index];
+
+ S3VSwitchMode(index, pScrn->currentMode, 0);
+ ps3v->DGAactive = FALSE;
+ } else {
+ if(!ps3v->DGAactive) { /* save the old parameters */
+ OldDisplayWidth[index] = pScrn->displayWidth;
+
+ ps3v->DGAactive = TRUE;
+ }
+
+ pScrn->displayWidth = pMode->bytesPerScanline /
+ (pMode->bitsPerPixel >> 3);
+
+ S3VSwitchMode(index, pMode->mode, 0);
+ }
+
+ return TRUE;
+}
+
+
+
+static int
+S3V_GetViewport(
+ ScrnInfoPtr pScrn
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ return ps3v->DGAViewportStatus;
+}
+
+static void
+S3V_SetViewport(
+ ScrnInfoPtr pScrn,
+ int x, int y,
+ int flags
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ S3VAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
+ ps3v->DGAViewportStatus = 0; /* MGAAdjustFrame loops until finished */
+}
+
+static void
+S3V_FillRect (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned long color
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ if(ps3v->AccelInfoRec) {
+ (*ps3v->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
+ (*ps3v->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ SET_SYNC_FLAG(ps3v->AccelInfoRec);
+ }
+}
+
+static void
+S3V_BlitRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ if(ps3v->AccelInfoRec) {
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ (*ps3v->AccelInfoRec->SetupForScreenToScreenCopy)(
+ pScrn, xdir, ydir, GXcopy, ~0, -1);
+ (*ps3v->AccelInfoRec->SubsequentScreenToScreenCopy)(
+ pScrn, srcx, srcy, dstx, dsty, w, h);
+ SET_SYNC_FLAG(ps3v->AccelInfoRec);
+ }
+}
+
+#if 0
+static void
+MGA_BlitTransRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty,
+ unsigned long color
+){
+ /* this one should be separate since the XAA function would
+ prohibit usage of ~0 as the key */
+}
+#endif
+
+static Bool
+S3V_OpenFramebuffer(
+ ScrnInfoPtr pScrn,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *flags
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ *name = NULL; /* no special device */
+ *mem = (unsigned char*)ps3v->FBBase;
+ *size = ps3v->videoRambytes;
+ *offset = 0;
+ *flags = DGA_NEED_ROOT;
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_driver.c
new file mode 100644
index 000000000..59160fc61
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_driver.c
@@ -0,0 +1,3208 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_driver.c,v 1.34 1999/08/22 05:35:54 dawes Exp $ */
+
+/*
+Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+XFREE86 PROJECT 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 XFree86 Project 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 XFree86 Project.
+*/
+#include "xf86Resources.h"
+/* Needed by Resources Access Control (RAC) */
+#include "xf86RAC.h"
+
+#include "xf86DDC.h"
+/*
+ * s3v_driver.c
+ * Port to 4.0 design level
+ *
+ * S3 ViRGE driver
+ *
+ * 10/98 - 3/99 Kevin Brosius
+ * based largely on the SVGA ViRGE driver from 3.3.3x,
+ * Started 09/03/97 by S. Marineau
+ *
+ *
+ */
+
+
+ /* Most xf86 commons are already in s3v.h */
+#include "s3v.h"
+
+
+#ifdef DPMSExtension
+#include "globals.h"
+#define DPMS_SERVER
+#include "extensions/dpms.h"
+#endif /* DPMSExtension */
+
+#ifdef XvExtension
+#include "xf86xv.h"
+#endif
+
+/*
+ * Internals
+ */
+static void S3VEnableMmio(ScrnInfoPtr pScrn);
+static void S3VDisableMmio(ScrnInfoPtr pScrn);
+
+/*
+ * Forward definitions for the functions that make up the driver.
+ */
+
+/* Mandatory functions */
+static void S3VIdentify(int flags);
+static Bool S3VProbe(DriverPtr drv, int flags);
+static Bool S3VPreInit(ScrnInfoPtr pScrn, int flags);
+
+static Bool S3VEnterVT(int scrnIndex, int flags);
+static void S3VLeaveVT(int scrnIndex, int flags);
+static void S3VSave (ScrnInfoPtr pScrn);
+static void S3VWriteMode (ScrnInfoPtr pScrn, vgaRegPtr, S3VRegPtr);
+
+static void S3VSaveSTREAMS(ScrnInfoPtr pScrn, unsigned int *streams);
+static void S3VRestoreSTREAMS(ScrnInfoPtr pScrn, unsigned int *streams);
+static void S3VDisableSTREAMS(ScrnInfoPtr pScrn);
+static Bool S3VScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv);
+static int S3VInternalScreenInit( int scrnIndex, ScreenPtr pScreen);
+static void S3VPrintRegs(ScrnInfoPtr);
+static ModeStatus S3VValidMode(int index, DisplayModePtr mode, Bool verbose, int flags);
+
+static Bool S3VMapMem(ScrnInfoPtr pScrn);
+static void S3VUnmapMem(ScrnInfoPtr pScrn);
+static Bool S3VModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static Bool S3VCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool S3VSaveScreen(ScreenPtr pScreen, Bool unblank);
+static void S3VInitSTREAMS(ScrnInfoPtr pScrn, unsigned int *streams, DisplayModePtr mode);
+/* s3v.h - static void S3VAdjustFrame(int scrnIndex, int x, int y, int flags); */
+/* s3v.h - static Bool S3VSwitchMode(int scrnIndex, DisplayModePtr mode, int flags); */
+static void S3VLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, LOCO *colors, VisualPtr pVisual);
+
+#ifdef DPMSExtension
+static void S3VDisplayPowerManagementSet(ScrnInfoPtr pScrn,
+ int PowerManagementMode,
+ int flags);
+#endif
+static void S3Vddc1(int scrnIndex);
+static unsigned int S3Vddc1Read(ScrnInfoPtr pScrn);
+
+/*
+ * This is intentionally screen-independent. It indicates the binding
+ * choice made in the first PreInit.
+ */
+static int pix24bpp = 0;
+
+
+#define S3VIRGE_NAME "S3VIRGE"
+#define S3VIRGE_DRIVER_NAME "s3virge"
+#define S3VIRGE_VERSION_NAME "0.10.0"
+#define S3VIRGE_VERSION_MAJOR 0
+#define S3VIRGE_VERSION_MINOR 10
+#define S3VIRGE_PATCHLEVEL 0
+#define S3VIRGE_DRIVER_VERSION ((S3VIRGE_VERSION_MAJOR << 24) | \
+ (S3VIRGE_VERSION_MINOR << 16) | \
+ S3VIRGE_PATCHLEVEL)
+
+/*
+ * This contains the functions needed by the server after loading the
+ * driver module. It must be supplied, and gets added the driver list by
+ * the Module Setup funtion in the dynamic case. In the static case a
+ * reference to this is compiled in, and this requires that the name of
+ * this DriverRec be an upper-case version of the driver name.
+ */
+
+DriverRec S3VIRGE =
+{
+ S3VIRGE_DRIVER_VERSION,
+ "driver for S3 ViRGE based cards, including DX, GX, GX2, VX, MX & MX+",
+ S3VIdentify,
+ S3VProbe,
+ NULL,
+ 0
+};
+
+
+/* Supported chipsets */
+static SymTabRec S3VChipsets[] = {
+ /* base (86C325) */
+ { PCI_CHIP_VIRGE, "virge" },
+ { PCI_CHIP_VIRGE, "86C325" },
+ /* VX (86C988) */
+ { PCI_CHIP_VIRGE_VX, "virge vx" },
+ { PCI_CHIP_VIRGE_VX, "86C988" },
+ /* DX (86C375) GX (86C385) */
+ { PCI_CHIP_VIRGE_DXGX, "virge dx" },
+ { PCI_CHIP_VIRGE_DXGX, "virge gx" },
+ { PCI_CHIP_VIRGE_DXGX, "86C375" },
+ { PCI_CHIP_VIRGE_DXGX, "86C385" },
+ /* GX2 (86C357) */
+ { PCI_CHIP_VIRGE_GX2, "virge gx2" },
+ { PCI_CHIP_VIRGE_GX2, "86C357" },
+ /* MX (86C260) */
+ { PCI_CHIP_VIRGE_MX, "virge mx" },
+ { PCI_CHIP_VIRGE_MX, "86C260" },
+ /* MX+ (86C280) */
+ { PCI_CHIP_VIRGE_MXP, "virge mx+" },
+ { PCI_CHIP_VIRGE_MXP, "86C280" },
+ {-1, NULL }
+};
+
+static PciChipsets S3VPciChipsets[] = {
+ /* numChipset, PciID, Resource */
+ { PCI_CHIP_VIRGE, PCI_CHIP_VIRGE, RES_SHARED_VGA },
+ { PCI_CHIP_VIRGE_VX, PCI_CHIP_VIRGE_VX, RES_SHARED_VGA },
+ { PCI_CHIP_VIRGE_DXGX, PCI_CHIP_VIRGE_DXGX, RES_SHARED_VGA },
+ { PCI_CHIP_VIRGE_GX2, PCI_CHIP_VIRGE_GX2, RES_SHARED_VGA },
+ { PCI_CHIP_VIRGE_MX, PCI_CHIP_VIRGE_MX, RES_SHARED_VGA },
+ { PCI_CHIP_VIRGE_MXP, PCI_CHIP_VIRGE_MXP, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED }
+};
+
+typedef enum {
+ OPTION_SLOW_EDODRAM,
+ OPTION_FAST_DRAM,
+ OPTION_FPM_VRAM,
+ OPTION_PCI_BURST,
+ OPTION_FIFO_CONSERV,
+ OPTION_FIFO_MODERATE,
+ OPTION_FIFO_AGGRESSIVE,
+ OPTION_PCI_RETRY,
+ OPTION_NOACCEL,
+ OPTION_EARLY_RAS_PRECHARGE,
+ OPTION_LATE_RAS_PRECHARGE,
+ OPTION_LCD_CENTER,
+ OPTION_LCDCLOCK,
+ OPTION_MCLK,
+ OPTION_SHOWCACHE,
+ OPTION_SWCURSOR,
+ OPTION_HWCURSOR
+} S3VOpts;
+
+static OptionInfoRec S3VOptions[] =
+{
+ { OPTION_SLOW_EDODRAM, "slow_edodram", OPTV_BOOLEAN, {0}, FALSE },
+ /* not yet ...
+ { OPTION_FAST_DRAM, "fast_dram", OPTV_BOOLEAN, {0}, FALSE },
+ */
+ { OPTION_FPM_VRAM, "fpm_vram", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PCI_BURST, "pci_burst", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_FIFO_CONSERV, "fifo_conservative", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_FIFO_MODERATE, "fifo_moderate", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_FIFO_AGGRESSIVE, "fifo_aggressive", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PCI_RETRY, "pci_retry", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_EARLY_RAS_PRECHARGE, "early_ras_precharge", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_LATE_RAS_PRECHARGE, "late_ras_precharge", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_LCD_CENTER, "lcd_center", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_LCDCLOCK, "set_lcdclk", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_MCLK, "set_mclk", OPTV_FREQ, {0}, FALSE },
+ { OPTION_SHOWCACHE, "show_cache", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SWCURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE },
+ {-1, NULL, OPTV_NONE, {0}, FALSE}
+};
+
+
+/*
+ * Lists of symbols that may/may not be required by this driver.
+ * This allows the loader to know which ones to issue warnings for.
+ *
+ * Note that vgahwSymbols and xaaSymbols are referenced outside the
+ * XFree86LOADER define in later code, so are defined outside of that
+ * define here also.
+ * cfbSymbols and ramdacSymbols are only referenced from within the
+ * ...LOADER define.
+ */
+
+static const char *vgahwSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWSetMmioFuncs",
+ "vgaHWGetIOBase",
+ "vgaHWSave",
+ "vgaHWProtect",
+ "vgaHWRestore",
+ "vgaHWMapMem",
+ "vgaHWUnmapMem",
+ "vgaHWInit",
+ "vgaHWSaveScreen",
+ "vgaHWLock",
+ /* not used by ViRGE (at the moment :( ) */
+ /*
+ "vgaHWUnlock",
+ "vgaHWFreeHWRec",
+ */
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAADestroyInfoRec",
+ "XAACreateInfoRec",
+ "XAAInit",
+ /*
+ "XAAStippleScanlineFuncLSBFirst",
+ "XAAOverlayFBfuncs",
+ */
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86InitCursor",
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ NULL
+};
+
+static const char *ddcSymbols[] = {
+ "xf86PrintEDID",
+ "xf86DoEDID_DDC1",
+ "xf86DoEDID_DDC2",
+ NULL
+};
+
+
+#ifdef XFree86LOADER
+
+static const char *cfbSymbols[] = {
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb24ScreenInit",
+ "cfb24_32ScreenInit",
+ "cfb32ScreenInit",
+ NULL
+};
+
+static const char *i2cSymbols[] = {
+ "xf86CreateI2CBusRec",
+ "xf86I2CBusInit",
+ NULL
+};
+
+static MODULESETUPPROTO(s3virgeSetup);
+
+static XF86ModuleVersionInfo S3VVersRec =
+{
+ "s3virge",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ S3VIRGE_VERSION_MAJOR, S3VIRGE_VERSION_MINOR, S3VIRGE_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0, 0, 0, 0}
+};
+
+
+/*
+ * This is the module init data for XFree86 modules.
+ *
+ * Its name has to be the driver name followed by ModuleData.
+ */
+XF86ModuleData s3virgeModuleData = { &S3VVersRec, s3virgeSetup, NULL };
+
+static pointer
+s3virgeSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&S3VIRGE, module, 0);
+
+ /*
+ * Modules that this driver always requires can be loaded here
+ * by calling LoadSubModule().
+ */
+
+ /*
+ * Tell the loader about symbols from other modules that this module
+ * might refer to.
+ */
+ LoaderRefSymLists(vgahwSymbols, cfbSymbols, xaaSymbols,
+ ramdacSymbols, NULL);
+
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer) 1;
+ } else {
+ if (errmaj)
+ *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+#endif /* XFree86LOADER */
+
+
+static Bool
+S3VGetRec(ScrnInfoPtr pScrn)
+{
+ PVERB5(" S3VGetRec\n");
+ /*
+ * Allocate an 'Chip'Rec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(S3VRec), 1);
+ /* Initialise it here when needed (or possible) */
+
+ return TRUE;
+}
+
+static void
+S3VFreeRec(ScrnInfoPtr pScrn)
+{
+ PVERB5(" S3VFreeRec\n");
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+static void
+S3VIdentify(int flags)
+{
+ PVERB5(" S3VIdentify\n");
+ xf86PrintChipsets(S3VIRGE_NAME,
+ "driver (version " S3VIRGE_VERSION_NAME ") for S3 ViRGE chipsets",
+ S3VChipsets);
+}
+
+
+static Bool
+S3VProbe(DriverPtr drv, int flags)
+{
+ int i;
+ GDevPtr *devSections;
+ int *usedChips;
+ int numDevSections;
+ int numUsed;
+ Bool foundScreen = FALSE;
+
+ PVERB5(" S3VProbe begin\n");
+
+ if ((numDevSections = xf86MatchDevice(S3VIRGE_DRIVER_NAME,
+ &devSections)) <= 0) {
+ /*
+ * There's no matching device section in the config file, so quit
+ * now.
+ */
+ return FALSE;
+ }
+ if (xf86GetPciVideoInfo() == NULL) {
+ return FALSE;
+ }
+
+ numUsed = xf86MatchPciInstances(S3VIRGE_NAME, PCI_S3_VENDOR_ID,
+ S3VChipsets, S3VPciChipsets, devSections,
+ numDevSections, drv, &usedChips);
+ /* Free it since we don't need that list after this */
+ xfree(devSections);
+ devSections = NULL;
+ if (numUsed <= 0)
+ return FALSE;
+
+ for (i = 0; i < numUsed; i++) {
+ /* Allocate a ScrnInfoRec and claim the slot */
+ ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0);
+
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn->driverVersion = S3VIRGE_DRIVER_VERSION;
+ pScrn->driverName = S3VIRGE_DRIVER_NAME;
+ pScrn->name = S3VIRGE_NAME;
+ pScrn->Probe = S3VProbe;
+ pScrn->PreInit = S3VPreInit;
+ pScrn->ScreenInit = S3VScreenInit;
+ pScrn->SwitchMode = S3VSwitchMode;
+ pScrn->AdjustFrame = S3VAdjustFrame;
+ pScrn->EnterVT = S3VEnterVT;
+ pScrn->LeaveVT = S3VLeaveVT;
+ pScrn->FreeScreen = NULL; /*S3VFreeScreen;*/
+ pScrn->ValidMode = S3VValidMode;
+ foundScreen = TRUE;
+ xf86ConfigActivePciEntity(pScrn,usedChips[i],S3VPciChipsets,
+ NULL,NULL, NULL,NULL,NULL);
+
+ }
+ xfree(usedChips);
+ PVERB5(" S3VProbe end\n");
+ return foundScreen;
+}
+
+
+/* Mandatory */
+static Bool
+S3VPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ EntityInfoPtr pEnt;
+ S3VPtr ps3v;
+ MessageType from;
+ int i;
+ double real;
+ ClockRangePtr clockRanges;
+ char *mod = NULL;
+ const char *reqSym = NULL;
+
+ unsigned char config1, config2, m, n, n1, n2, cr66;
+ int mclk;
+
+ vgaHWPtr hwp;
+ int vgaCRIndex, vgaCRReg, vgaIOBase;
+
+ PVERB5(" S3VPreInit 1\n");
+
+
+ /*
+ * Note: This function is only called once at server startup, and
+ * not at the start of each server generation. This means that
+ * only things that are persistent across server generations can
+ * be initialised here. xf86Screens[] is (pScrn is a pointer to one
+ * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex()
+ * are too, and should be used for data that must persist across
+ * server generations.
+ *
+ * Per-generation data should be allocated with
+ * AllocateScreenPrivateIndex() from the ScreenInit() function.
+ */
+
+ /* The vgahw module should be loaded here when needed */
+
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /*
+ * Allocate a vgaHWRec
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*
+ * The first thing we should figure out is the depth, bpp, etc.
+ * Our default depth is 8, so pass it to the helper function.
+ * We support both 24bpp and 32bpp layouts, so indicate that.
+ */
+ if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb | Support32bppFb |
+ SupportConvert32to24 | PreferConvert32to24)) {
+ return FALSE;
+ } else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 8:
+ case 15:
+ case 16:
+ case 24:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+ xf86PrintDepthBpp(pScrn);
+
+ /* Get the depth24 pixmap format */
+ if (pScrn->depth == 24 && pix24bpp == 0)
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else { /* editme - from MGA, does ViRGE? */
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /* We use a programamble clock */
+ pScrn->progClock = TRUE;
+
+ /* Allocate the S3VRec driverPrivate */
+ if (!S3VGetRec(pScrn)) {
+ return FALSE;
+ }
+ ps3v = S3VPTR(pScrn);
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Set the bits per RGB for 8bpp mode */
+ if (pScrn->depth == 8) {
+ /* ViRGE supports 6 RGB bits in depth 8 */
+ /* modes (with 256 entry LUT) */
+ pScrn->rgbBits = 6;
+ }
+
+ /* Process the options */
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, S3VOptions);
+
+
+ if (xf86ReturnOptValBool(S3VOptions, OPTION_PCI_BURST, FALSE)) {
+ ps3v->pci_burst = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: pci_burst - PCI burst read enabled\n");
+ } else
+ ps3v->pci_burst = FALSE;
+ /* default */
+ ps3v->NoPCIRetry = 1;
+ /* Set option */
+ if (xf86ReturnOptValBool(S3VOptions, OPTION_PCI_RETRY, FALSE)) {
+ if (xf86ReturnOptValBool(S3VOptions, OPTION_PCI_BURST, FALSE)) {
+ ps3v->NoPCIRetry = 0;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: pci_retry\n");
+ }
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "\"pci_retry\" option requires \"pci_burst\".\n");
+ }
+ }
+ if (xf86IsOptionSet(S3VOptions, OPTION_FIFO_CONSERV)) {
+ ps3v->fifo_conservative = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fifo_conservative set\n");
+ } else
+ ps3v->fifo_conservative = FALSE;
+
+ if (xf86IsOptionSet(S3VOptions, OPTION_FIFO_MODERATE)) {
+ ps3v->fifo_moderate = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fifo_moderate set\n");
+ } else
+ ps3v->fifo_moderate = FALSE;
+
+ if (xf86IsOptionSet(S3VOptions, OPTION_FIFO_AGGRESSIVE)) {
+ ps3v->fifo_aggressive = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fifo_aggressive set\n");
+ } else
+ ps3v->fifo_aggressive = FALSE;
+
+ if (xf86IsOptionSet(S3VOptions, OPTION_SLOW_EDODRAM)) {
+ ps3v->slow_edodram = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: slow_edodram set\n");
+ } else
+ ps3v->slow_edodram = FALSE;
+
+ if (xf86IsOptionSet(S3VOptions, OPTION_FAST_DRAM)) {
+ ps3v->fast_dram = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fast_dram set\n");
+ } else
+ ps3v->fast_dram = FALSE;
+
+ if (xf86IsOptionSet(S3VOptions, OPTION_FPM_VRAM)) {
+ ps3v->fpm_vram = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: fpm_vram set\n");
+ } else
+ ps3v->fpm_vram = FALSE;
+
+ if (xf86ReturnOptValBool(S3VOptions, OPTION_NOACCEL, FALSE)) {
+ ps3v->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: NoAccel - Acceleration disabled\n");
+ } else
+ ps3v->NoAccel = FALSE;
+
+ if (xf86ReturnOptValBool(S3VOptions, OPTION_EARLY_RAS_PRECHARGE, FALSE)) {
+ ps3v->early_ras_precharge = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: early_ras_precharge set\n");
+ } else
+ ps3v->early_ras_precharge = FALSE;
+
+ if (xf86ReturnOptValBool(S3VOptions, OPTION_LATE_RAS_PRECHARGE, FALSE)) {
+ ps3v->late_ras_precharge = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: late_ras_precharge set\n");
+ } else
+ ps3v->late_ras_precharge = FALSE;
+
+ if (xf86ReturnOptValBool(S3VOptions, OPTION_LCD_CENTER, FALSE)) {
+ ps3v->lcd_center = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: lcd_center set\n");
+ } else
+ ps3v->lcd_center = FALSE;
+
+ if (xf86ReturnOptValBool(S3VOptions, OPTION_SHOWCACHE, FALSE)) {
+ ps3v->ShowCache = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: show_cache set\n");
+ } else
+ ps3v->ShowCache = FALSE;
+
+ if (xf86GetOptValInteger(S3VOptions, OPTION_LCDCLOCK, &ps3v->LCDClk)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: lcd_setclk set to %1.3f Mhz\n",
+ ps3v->LCDClk / 1000.0 );
+ } else
+ ps3v->LCDClk = 0;
+
+ if (xf86GetOptValFreq(S3VOptions, OPTION_MCLK, OPTUNITS_MHZ, &real)) {
+ ps3v->MCLK = (int)(real * 1000.0);
+ if (ps3v->MCLK <= 100000) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: set_mclk set to %1.3f Mhz\n",
+ ps3v->MCLK / 1000.0 );
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING
+ , "Memory Clock value of %1.3f MHz is larger than limit of 100 MHz\n"
+ , ps3v->MCLK/1000.0);
+ ps3v->MCLK = 0;
+ }
+ } else
+ ps3v->MCLK = 0;
+
+ from = X_DEFAULT;
+ ps3v->hwcursor = TRUE;
+ if (xf86GetOptValBool(S3VOptions, OPTION_HWCURSOR, &ps3v->hwcursor))
+ from = X_CONFIG;
+ if (xf86ReturnOptValBool(S3VOptions, OPTION_SWCURSOR, FALSE)) {
+ ps3v->hwcursor = FALSE;
+ from = X_CONFIG;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s Cursor\n",
+ ps3v->hwcursor ? "HW" : "SW");
+
+ /* Find the PCI slot for this screen */
+ /*
+ * XXX Ignoring the Type list for now. It might be needed when
+ * multiple cards are supported.
+ */
+ if (pScrn->numEntities > 1) {
+ S3VFreeRec(pScrn);
+ return FALSE;
+ }
+
+ pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+
+ if (pEnt->resources) {
+ xfree(pEnt);
+ S3VFreeRec(pScrn);
+ return FALSE;
+ }
+ ps3v->PciInfo = xf86GetPciInfoForEntity(pEnt->index);
+ xf86RegisterResources(pEnt->index,NULL,ResNone);
+ xf86SetOperatingState(RES_SHARED_VGA, pEnt->index, ResUnusedOpr);
+ {
+ resRange vgamem[] = { {ResShrMemBlock,0xA0000,0xAFFFF},
+ {ResShrMemBlock,0xB0000,0xB7FFF},
+ {ResShrMemBlock,0xB8000,0xBFFFF},
+ _END };
+ xf86SetOperatingState(vgamem, pEnt->index, ResDisableOpr);
+ }
+
+ /*
+ * Set the Chipset and ChipRev, allowing config file entries to
+ * override.
+ */
+ if (pEnt->device->chipset && *pEnt->device->chipset) {
+ pScrn->chipset = pEnt->device->chipset;
+ ps3v->Chipset = xf86StringToToken(S3VChipsets, pScrn->chipset);
+ from = X_CONFIG;
+ } else if (pEnt->device->chipID >= 0) {
+ ps3v->Chipset = pEnt->device->chipID;
+ pScrn->chipset = (char *)xf86TokenToString(S3VChipsets, ps3v->Chipset);
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ ps3v->Chipset);
+ } else {
+ from = X_PROBED;
+ ps3v->Chipset = ps3v->PciInfo->chipType;
+ pScrn->chipset = (char *)xf86TokenToString(S3VChipsets, ps3v->Chipset);
+ }
+
+ if (pEnt->device->chipRev >= 0) {
+ ps3v->ChipRev = pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ ps3v->ChipRev);
+ } else {
+ ps3v->ChipRev = ps3v->PciInfo->chipRev;
+ }
+ xfree(pEnt);
+
+ /*
+ * This shouldn't happen because such problems should be caught in
+ * S3VProbe(), but check it just in case.
+ */
+ if (pScrn->chipset == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ChipID 0x%04X is not recognised\n", ps3v->Chipset);
+ return FALSE;
+ }
+ if (ps3v->Chipset < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Chipset \"%s\" is not recognised\n", pScrn->chipset);
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
+
+ ps3v->PciTag = pciTag(ps3v->PciInfo->bus, ps3v->PciInfo->device,
+ ps3v->PciInfo->func);
+
+ S3VMapMem(pScrn);
+ hwp = VGAHWPTR(pScrn);
+ vgaIOBase = hwp->IOBase;
+ vgaCRIndex = vgaIOBase + 4;
+ vgaCRReg = vgaIOBase + 5;
+
+ xf86ErrorFVerb(VERBLEV,
+ " S3VPreInit vgaCRIndex=%x, vgaIOBase=%x, MMIOBase=%x\n",
+ vgaCRIndex, vgaIOBase, hwp->MMIOBase );
+
+
+ #if 0 /* Not needed in 4.0 flavors */
+ /* Unlock sys regs */
+ VGAOUT8(vgaCRIndex, 0x38);
+ VGAOUT8(vgaCRReg, 0x48);
+ #endif
+
+ /* Next go on to detect amount of installed ram */
+
+ VGAOUT8(vgaCRIndex, 0x36); /* for register CR36 (CONFG_REG1), */
+ config1 = VGAIN8(vgaCRReg); /* get amount of vram installed */
+
+ VGAOUT8(vgaCRIndex, 0x37); /* for register CR37 (CONFG_REG2), */
+ config2 = VGAIN8(vgaCRReg); /* get amount of off-screen ram */
+
+ if (xf86LoadSubModule(pScrn, "ddc")) {
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+#if 1
+ S3Vddc1(pScrn->scrnIndex);
+#else
+ if ( xf86LoadSubModule(pScrn, "i2c") ) {
+ xf86LoaderReqSymLists(i2cSymbols,NULL);
+ if (S3V_I2CInit(pScrn)) {
+ CARD32 tmp = (INREG(DDC_REG));
+ OUTREG(DDC_REG,(tmp | 0x13));
+ xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,ps3v->I2C));
+ OUTREG(DDC_REG,tmp);
+ }
+ }
+#endif
+ }
+
+ /*
+ * If the driver can do gamma correction, it should call xf86SetGamma()
+ * here. (from MGA, no ViRGE gamma support yet, but needed for
+ * xf86HandleColormaps support.)
+ */
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+
+ /* And compute the amount of video memory and offscreen memory */
+ ps3v->MemOffScreen = 0;
+
+ if (!pScrn->videoRam) {
+ if (ps3v->Chipset == S3_ViRGE_VX) {
+ switch((config2 & 0x60) >> 5) {
+ case 1:
+ ps3v->MemOffScreen = 4 * 1024;
+ break;
+ case 2:
+ ps3v->MemOffScreen = 2 * 1024;
+ break;
+ }
+ switch ((config1 & 0x60) >> 5) {
+ case 0:
+ ps3v->videoRamKbytes = 2 * 1024;
+ break;
+ case 1:
+ ps3v->videoRamKbytes = 4 * 1024;
+ break;
+ case 2:
+ ps3v->videoRamKbytes = 6 * 1024;
+ break;
+ case 3:
+ ps3v->videoRamKbytes = 8 * 1024;
+ break;
+ }
+ ps3v->videoRamKbytes -= ps3v->MemOffScreen;
+ }
+ else if (S3_ViRGE_GX2_SERIES(ps3v->Chipset) || S3_ViRGE_MX_SERIES(ps3v->Chipset)) {
+ switch((config1 & 0xC0) >> 6) {
+ case 1:
+ ps3v->videoRamKbytes = 4 * 1024;
+ break;
+ case 3:
+ ps3v->videoRamKbytes = 2 * 1024;
+ break;
+ }
+ }
+ else {
+ switch((config1 & 0xE0) >> 5) {
+ case 0:
+ ps3v->videoRamKbytes = 4 * 1024;
+ break;
+ case 4:
+ ps3v->videoRamKbytes = 2 * 1024;
+ break;
+ case 6:
+ ps3v->videoRamKbytes = 1 * 1024;
+ break;
+ }
+ }
+ /* And save a byte value also */
+ ps3v->videoRambytes = ps3v->videoRamKbytes * 1024;
+ /* Make sure the screen also */
+ /* has correct videoRam setting */
+ pScrn->videoRam = ps3v->videoRamKbytes;
+
+ if (ps3v->MemOffScreen)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "videoram: %dk (plus %dk off-screen)\n",
+ ps3v->videoRamKbytes, ps3v->MemOffScreen);
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "videoram: %dk\n",
+ ps3v->videoRamKbytes);
+ } else {
+ /* Note: if ram is not probed then */
+ /* ps3v->videoRamKbytes will not be init'd */
+ /* should we? can do it here... */
+
+
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "videoram: %dk\n",
+ ps3v->videoRamKbytes);
+ }
+
+ /* reset S3 graphics engine to avoid memory corruption */
+ if (ps3v->Chipset != S3_ViRGE_VX) {
+ VGAOUT8(vgaCRIndex, 0x66);
+ cr66 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRReg, cr66 | 0x02);
+ usleep(10000); /* wait a little bit... */
+ }
+
+/*cep*/
+#if 0 /* write find_bios_string... */
+ if (find_bios_string(vga256InfoRec.BIOSbase,"S3 86C325",
+ "MELCO WGP-VG VIDEO BIOS") != NULL) {
+ if (xf86Verbose)
+ ErrorF("%s %s: MELCO BIOS found\n",
+ XCONFIG_PROBED, vga256InfoRec.name);
+ if (vga256InfoRec.MemClk <= 0) vga256InfoRec.MemClk = 74000;
+ if (pScrn->clock[0] <= 0) pScrn->clock[0] = 191500;
+ if (pScrn->clock[1] <= 0) pScrn->clock[1] = 162500;
+ if (pScrn->clock[2] <= 0) pScrn->clock[2] = 111500;
+ if (pScrn->clock[3] <= 0) pScrn->clock[3] = 83500;
+ }
+#endif
+
+ if (ps3v->Chipset != S3_ViRGE_VX) {
+ VGAOUT8(vgaCRIndex, 0x66);
+ VGAOUT8(vgaCRReg, cr66 & ~0x02); /* clear reset flag */
+ usleep(10000); /* wait a little bit... */
+ }
+
+ /* ViRGE built-in ramdac speeds */
+ /* ViRGE has four default clocks */
+ pScrn->numClocks = 4;
+
+ if (pScrn->clock[3] <= 0 && pScrn->clock[2] > 0)
+ pScrn->clock[3] = pScrn->clock[2];
+
+ if (ps3v->Chipset == S3_ViRGE_VX) {
+ if (pScrn->clock[0] <= 0) pScrn->clock[0] = 220000;
+ if (pScrn->clock[1] <= 0) pScrn->clock[1] = 220000;
+ if (pScrn->clock[2] <= 0) pScrn->clock[2] = 135000;
+ if (pScrn->clock[3] <= 0) pScrn->clock[3] = 135000;
+ }
+ else if (ps3v->Chipset == S3_ViRGE_DXGX || S3_ViRGE_GX2_SERIES(ps3v->Chipset)) {
+ if (pScrn->clock[0] <= 0) pScrn->clock[0] = 170000;
+ if (pScrn->clock[1] <= 0) pScrn->clock[1] = 170000;
+ if (pScrn->clock[2] <= 0) pScrn->clock[2] = 135000;
+ if (pScrn->clock[3] <= 0) pScrn->clock[3] = 135000;
+ }
+ else if (S3_ViRGE_MX_SERIES(ps3v->Chipset)) {
+ if (pScrn->clock[0] <= 0) pScrn->clock[0] = 135000;
+ if (pScrn->clock[1] <= 0) pScrn->clock[1] = 135000;
+ if (pScrn->clock[2] <= 0) pScrn->clock[2] = 100000;
+ if (pScrn->clock[3] <= 0) pScrn->clock[3] = 100000;
+ }
+ else {
+ if (pScrn->clock[0] <= 0) pScrn->clock[0] = 135000;
+ if (pScrn->clock[1] <= 0) pScrn->clock[1] = 95000;
+ if (pScrn->clock[2] <= 0) pScrn->clock[2] = 57000;
+ if (pScrn->clock[3] <= 0) pScrn->clock[3] = 57000;
+ }
+
+ if (ps3v->dacSpeedBpp <= 0) {
+ if (pScrn->bitsPerPixel > 24 && pScrn->clock[3] > 0)
+ ps3v->dacSpeedBpp = pScrn->clock[3];
+ else if (pScrn->bitsPerPixel >= 24 && pScrn->clock[2] > 0)
+ ps3v->dacSpeedBpp = pScrn->clock[2];
+ else if (pScrn->bitsPerPixel > 8 && pScrn->bitsPerPixel < 24 && pScrn->clock[1] > 0)
+ ps3v->dacSpeedBpp = pScrn->clock[1];
+ else if (pScrn->bitsPerPixel <= 8 && pScrn->clock[0] > 0)
+ ps3v->dacSpeedBpp = pScrn->clock[0];
+ }
+/*cep*/
+#if 0
+ if (xf86Verbosity()) {
+ ErrorF("%s %s: Ramdac speed: %d MHz",
+ OFLG_ISSET(XCONFIG_DACSPEED, &vga256InfoRec.xconfigFlag) ?
+ XCONFIG_GIVEN : XCONFIG_PROBED, vga256InfoRec.name,
+ pScrn->clock[0] / 1000);
+ if (ps3v->dacSpeedBpp != pScrn->clock[0])
+ ErrorF(" (%d MHz for %d bpp)",ps3v->dacSpeedBpp / 1000, pScrn->bitsPerPixel);
+ ErrorF("\n");
+ }
+#endif
+
+ /* Now set RAMDAC limits */
+ /*ps3v->maxClock = ps3v->dacSpeedBpp;*/
+ if (ps3v->Chipset == S3_ViRGE_VX ) {
+ ps3v->maxClock = 440000;
+ } else {
+ ps3v->maxClock = 270000;
+ }
+
+ /* Detect current MCLK and print it for user */
+ VGAOUT8(0x3c4, 0x08);
+ VGAOUT8(0x3c5, 0x06);
+ VGAOUT8(0x3c4, 0x10);
+ n = VGAIN8(0x3c5);
+ VGAOUT8(0x3c4, 0x11);
+ m = VGAIN8(0x3c5);
+ m &= 0x7f;
+ n1 = n & 0x1f;
+ n2 = (n>>5) & 0x03;
+ mclk = ((1431818 * (m+2)) / (n1+2) / (1 << n2) + 50) / 100;
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected current MCLK value of %1.3f MHz\n",
+ mclk / 1000.0);
+
+ if (S3_ViRGE_MX_SERIES(ps3v->Chipset) && xf86GetVerbosity()) {
+ int lcdclk, h_lcd, v_lcd;
+ if (ps3v->LCDClk) {
+ lcdclk = ps3v->LCDClk;
+ } else {
+ int n1, n2, sr12, sr13, sr29;
+ VGAOUT8(0x3c4, 0x12);
+ sr12 = VGAIN8(0x3c5);
+ VGAOUT8(0x3c4, 0x13);
+ sr13 = VGAIN8(0x3c5) & 0x7f;
+ VGAOUT8(0x3c4, 0x29);
+ sr29 = VGAIN8(0x3c5);
+ n1 = sr12 & 0x1f;
+ n2 = ((sr12>>6) & 0x03) | ((sr29 & 0x01) << 2);
+ lcdclk = ((2 * 1431818 * (sr13+2)) / (n1+2) / (1 << n2) + 50) / 100;
+ }
+ VGAOUT8(0x3c4, 0x61);
+ h_lcd = VGAIN8(0x3c5);
+ VGAOUT8(0x3c4, 0x66);
+ h_lcd |= ((VGAIN8(0x3c5) & 0x02) << 7);
+ h_lcd = (h_lcd+1) * 8;
+ VGAOUT8(0x3c4, 0x69);
+ v_lcd = VGAIN8(0x3c5);
+ VGAOUT8(0x3c4, 0x6e);
+ v_lcd |= ((VGAIN8(0x3c5) & 0x70) << 4);
+ v_lcd++;
+ xf86DrvMsg(pScrn->scrnIndex
+ , ps3v->LCDClk ? X_CONFIG : X_PROBED
+ , "LCD size %dx%d, clock %1.3f MHz\n"
+ , h_lcd, v_lcd
+ , lcdclk / 1000.0);
+ }
+
+ S3VUnmapMem(pScrn);
+
+ /* Set scale factors for mode timings */
+
+ if (ps3v->Chipset == S3_ViRGE_VX || S3_ViRGE_GX2_SERIES(ps3v->Chipset) ||
+ S3_ViRGE_MX_SERIES(ps3v->Chipset)){
+ ps3v->HorizScaleFactor = 1;
+ }
+ else if (pScrn->bitsPerPixel == 8){
+ ps3v->HorizScaleFactor = 1;
+ }
+ else if (pScrn->bitsPerPixel == 16){
+ ps3v->HorizScaleFactor = 2;
+ }
+ else {
+ ps3v->HorizScaleFactor = 1;
+ }
+
+
+ /* And finally set various possible option flags */
+
+ ps3v->bankedMono = FALSE;
+
+
+#if 0
+#ifdef XFreeXDGA
+ vga256InfoRec.directMode = XF86DGADirectPresent;
+#endif
+#endif
+
+
+ /* find BIOS base? See above, do MELCO bios detect */
+
+
+ #if 0
+ if (ps3v->Chipset == S3_ViRGE_VX ) {
+ ps3v->minClock = 220000;
+ } else {
+ ps3v->minClock = 135000;
+ }
+ #else
+ ps3v->minClock = 20000; /* cep */
+ #endif
+
+ xf86ErrorFVerb(VERBLEV,
+ " S3VPreInit minClock=%d, maxClock=%d\n",
+ ps3v->minClock,
+ ps3v->maxClock
+ );
+
+ /*
+ * xf86ValidateModes will check that the mode HTotal and VTotal values
+ * don't exceed the chipset's limit if pScrn->maxHValue and
+ * pScrn->maxVValue are set.
+ */
+ /* true for all ViRGE? */
+ pScrn->maxHValue = 2048;
+ pScrn->maxVValue = 2048;
+
+ /* Lower depths default to config file */
+ pScrn->virtualX = pScrn->display->virtualX;
+ /* Adjust the virtualX to meet ViRGE hardware */
+ /* limits for depth 24, bpp 24 & 32. This is */
+ /* mostly for 32 bpp as 1024x768 is one pixel */
+ /* larger than supported. */
+ if (pScrn->depth == 24)
+ if ( ((pScrn->bitsPerPixel/8) * pScrn->display->virtualX) > 4095 ) {
+ pScrn->virtualX = 4095 / (pScrn->bitsPerPixel / 8);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Virtual width adjusted, max for this depth & bpp is %d.\n",
+ pScrn->virtualX );
+ }
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+ clockRanges = xnfalloc(sizeof(ClockRange));
+ clockRanges->next = NULL;
+ clockRanges->minClock = ps3v->minClock;
+ clockRanges->maxClock = ps3v->maxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = TRUE; /* yes, S3V SVGA 3.3.2 */
+ clockRanges->doubleScanAllowed = FALSE; /* no, S3V SVGA 3.3.2 */
+
+ /* Screen pointer */
+ i = xf86ValidateModes(pScrn,
+ /* Available monitor modes */
+ /* (DisplayModePtr availModes) */
+ pScrn->monitor->Modes,
+ /* req mode names for screen */
+ /* (char **modesNames) */
+ pScrn->display->modes,
+ /* list of clock ranges allowed */
+ /* (ClockRangePtr clockRanges) */
+ clockRanges,
+ /* list of driver line pitches, */
+ /* supply or NULL and use min/ */
+ /* max below */
+ /* (int *linePitches) */
+ NULL,
+ /* min lin pitch (width) */
+ /* (int minPitch) */
+ 256,
+ /* max line pitch (width) */
+ /* (int maxPitch) */
+ 2048,
+ /* bits of granularity for line */
+ /* pitch (width) above, reguired*/
+ /* (int pitchInc) */
+ pScrn->bitsPerPixel,
+ /* min virt height, 0 no limit */
+ /* (int minHeight) */
+ 128,
+ /* max virt height, 0 no limit */
+ /* (int maxHeight) */
+ 2048,
+ /* force virtX, 0 for auto */
+ /* (int VirtualX) */
+ /* value is adjusted above for */
+ /* hardware limits */
+ pScrn->virtualX,
+ /* force virtY, 0 for auto */
+ /* (int VirtualY) */
+ pScrn->display->virtualY,
+ /* size (bytes) of aper used to */
+ /* access video memory */
+ /* (unsigned long apertureSize) */
+ ps3v->videoRambytes,
+ /* how to pick mode */
+ /* (LookupModeFlags strategy) */
+ LOOKUP_BEST_REFRESH);
+
+ if (i == -1) {
+ S3VFreeRec(pScrn);
+ return FALSE;
+ }
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ S3VFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+ /*xf86SetCrtcForModes(pScrn, 0);*/
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+ /* When running the STREAMS processor */
+ /* the max. stride is limited to 4096-1 */
+ /* so this is the virtualX limit. */
+ /* STREAMS is needed for 24 & 32 bpp, */
+ /* (all depth 24 modes) */
+ /* This should never happen... we */
+ /* checked it before ValidateModes */
+ if ( (pScrn->depth == 24) &&
+ ((pScrn->bitsPerPixel/8) * pScrn->virtualX > 4095) ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Virtual width to large for ViRGE\n");
+ S3VFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ mod = "cfb";
+ reqSym = "cfbScreenInit";
+ break;
+ case 16:
+ mod = "cfb16";
+ reqSym = "cfb16ScreenInit";
+ break;
+ case 24:
+ if (pix24bpp == 24) {
+ mod = "cfb24";
+ reqSym = "cfb24ScreenInit";
+ } else {
+ mod = "xf24_32bpp";
+ reqSym = "cfb24_32ScreenInit";
+ }
+ break;
+ case 32:
+ mod = "cfb32";
+ reqSym = "cfb32ScreenInit";
+ break;
+ }
+ if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ S3VFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymbols(reqSym, NULL);
+
+ /* Load XAA if needed */
+ if (!ps3v->NoAccel || ps3v->hwcursor ) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ S3VFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ /* Load ramdac if needed */
+ if (ps3v->hwcursor) {
+ if (!xf86LoadSubModule(pScrn, "ramdac")) {
+ S3VFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ *
+ * We may wish to unmap video/MMIO memory too.
+ */
+
+
+/* Mandatory */
+static Bool
+S3VEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+/* ScreenPtr pScreen = xf86Screens[scrnIndex]->pScreen; */
+ /*vgaHWPtr hwp = VGAHWPTR(pScrn);*/
+
+ PVERB5(" S3VEnterVT\n");
+ /*vgaHWUnlockMMIO(hwp);*/
+ /* Enable MMIO and map memory */
+#ifdef unmap_always
+ S3VMapMem(pScrn);
+#endif
+ #if 0
+ /* todo - KJB - cep */
+ /* New pointer mapping means we need to call */
+ /* cfb...Init again and anything else required */
+ /* to notify the upper layers of the change. */
+ if( !S3VInternalScreenInit(scrnIndex, pScreen) )
+ return FALSE;
+ #endif
+ S3VSave(pScrn);
+ return S3VModeInit(pScrn, pScrn->currentMode);
+}
+
+
+/*
+ * This is called when VT switching away from the X server. Its job is
+ * to restore the previous (text) mode.
+ *
+ * We may wish to remap video/MMIO memory too.
+ *
+ */
+
+/* Mandatory */
+static void
+S3VLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ S3VPtr ps3v = S3VPTR(pScrn);
+ vgaRegPtr vgaSavePtr = &hwp->SavedReg;
+ S3VRegPtr S3VSavePtr = &ps3v->SavedReg;
+
+ PVERB5(" S3VLeaveVT\n");
+ /* Like S3VRestore, but uses passed */
+ /* mode registers. */
+ S3VWriteMode(pScrn, vgaSavePtr, S3VSavePtr);
+ /* Restore standard register access */
+ /* and unmap memory. */
+#ifdef unmap_always
+ S3VUnmapMem(pScrn);
+#endif
+ /*vgaHWLockMMIO(hwp);*/
+
+}
+
+
+/*
+ * This function performs the inverse of the restore function: It saves all
+ * the standard and extended registers that we are going to modify to set
+ * up a video mode. Again, we also save the STREAMS context if it is needed.
+ *
+ * prototype
+ * void ChipSave(ScrnInfoPtr pScrn)
+ *
+ */
+
+static void
+S3VSave (ScrnInfoPtr pScrn)
+{
+ unsigned char cr3a, cr66;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaSavePtr = &hwp->SavedReg;
+ S3VPtr ps3v = S3VPTR(pScrn);
+ S3VRegPtr save = &ps3v->SavedReg;
+/* void *s3vMmioMem = ps3v->MapBase; */
+ int vgaCRIndex, vgaCRReg, vgaIOBase;
+ vgaIOBase = hwp->IOBase;
+ vgaCRIndex = 0;
+
+ vgaCRReg = 0;
+
+ vgaCRReg = vgaIOBase + 5;
+ vgaCRIndex = vgaIOBase + 4;
+
+ PVERB5(" S3VSave\n");
+
+ /*
+ * This function will handle creating the data structure and filling
+ * in the generic VGA portion.
+ */
+
+ VGAOUT8(vgaCRIndex, 0x66);
+ cr66 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRReg, cr66 | 0x80);
+ VGAOUT8(vgaCRIndex, 0x3a);
+ cr3a = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRReg, cr3a | 0x80);
+
+ /* VGA_SR_MODE saves mode info only, no fonts, no colormap */
+ /* Save all for primary, anything */
+ /* for secondary cards?, do MODE */
+ /* for the moment. */
+ if (xf86IsPrimaryPci(ps3v->PciInfo))
+ vgaHWSave(pScrn, vgaSavePtr, VGA_SR_ALL);
+ else
+ vgaHWSave(pScrn, vgaSavePtr, VGA_SR_MODE);
+
+ VGAOUT8(vgaCRIndex, 0x66);
+ VGAOUT8(vgaCRReg, cr66);
+ VGAOUT8(vgaCRIndex, 0x3a);
+ VGAOUT8(vgaCRReg, cr3a);
+
+ /* First unlock extended sequencer regs */
+ VGAOUT8(0x3c4, 0x08);
+ save->SR8 = VGAIN8(0x3c5);
+ VGAOUT8(0x3c5, 0x06);
+
+ /* Now we save all the s3 extended regs we need */
+ VGAOUT8(vgaCRIndex, 0x31);
+ save->CR31 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x34);
+ save->CR34 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x36);
+ save->CR36 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x3a);
+ save->CR3A = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x40);
+ save->CR40 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x42);
+ save->CR42 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x45);
+ save->CR45 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x51);
+ save->CR51 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x53);
+ save->CR53 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x54);
+ save->CR54 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x55);
+ save->CR55 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x58);
+ save->CR58 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x63);
+ save->CR63 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x66);
+ save->CR66 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x67);
+ save->CR67 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x68);
+ save->CR68 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x69);
+ save->CR69 = VGAIN8(vgaCRReg);
+
+ VGAOUT8(vgaCRIndex, 0x33);
+ save->CR33 = VGAIN8(vgaCRReg);
+ if (ps3v->Chipset == S3_ViRGE_DXGX) {
+ VGAOUT8(vgaCRIndex, 0x86);
+ save->CR86 = VGAIN8(vgaCRReg);
+ }
+ if (ps3v->Chipset == S3_ViRGE_DXGX || S3_ViRGE_GX2_SERIES(ps3v->Chipset) ||
+ S3_ViRGE_MX_SERIES(ps3v->Chipset)) {
+ VGAOUT8(vgaCRIndex, 0x90);
+ save->CR90 = VGAIN8(vgaCRReg);
+ }
+
+ /* Extended mode timings regs */
+
+ VGAOUT8(vgaCRIndex, 0x3b);
+ save->CR3B = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x3c);
+ save->CR3C = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x43);
+ save->CR43 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x5d);
+ save->CR5D = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x5e);
+ save->CR5E = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x65);
+ save->CR65 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRIndex, 0x6d);
+ save->CR6D = VGAIN8(vgaCRReg);
+
+
+ /* Save sequencer extended regs for DCLK PLL programming */
+
+ VGAOUT8(0x3c4, 0x10);
+ save->SR10 = VGAIN8(0x3c5);
+ VGAOUT8(0x3c4, 0x11);
+ save->SR11 = VGAIN8(0x3c5);
+
+ VGAOUT8(0x3c4, 0x12);
+ save->SR12 = VGAIN8(0x3c5);
+ VGAOUT8(0x3c4, 0x13);
+ save->SR13 = VGAIN8(0x3c5);
+ if (S3_ViRGE_GX2_SERIES(ps3v->Chipset) || S3_ViRGE_MX_SERIES(ps3v->Chipset)) {
+ VGAOUT8(0x3c4, 0x29);
+ save->SR29 = VGAIN8(0x3c5);
+ VGAOUT8(0x3c4, 0x54);
+ save->SR54 = VGAIN8(0x3c5);
+ VGAOUT8(0x3c4, 0x55);
+ save->SR55 = VGAIN8(0x3c5);
+ VGAOUT8(0x3c4, 0x56);
+ save->SR56 = VGAIN8(0x3c5);
+ VGAOUT8(0x3c4, 0x57);
+ save->SR57 = VGAIN8(0x3c5);
+ }
+
+ VGAOUT8(0x3c4, 0x15);
+ save->SR15 = VGAIN8(0x3c5);
+ VGAOUT8(0x3c4, 0x18);
+ save->SR18 = VGAIN8(0x3c5);
+
+ VGAOUT8(vgaCRIndex, 0x66);
+ cr66 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRReg, cr66 | 0x80);
+ VGAOUT8(vgaCRIndex, 0x3a);
+ cr3a = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRReg, cr3a | 0x80);
+
+ /* And if streams is to be used, save that as well */
+
+ if(ps3v->NeedSTREAMS) {
+ S3VSaveSTREAMS(pScrn, save->STREAMS);
+ }
+
+ /* Now save Memory Interface Unit registers */
+ save->MMPR0 = INREG(FIFO_CONTROL_REG);
+ save->MMPR1 = INREG(MIU_CONTROL_REG);
+ save->MMPR2 = INREG(STREAMS_TIMEOUT_REG);
+ save->MMPR3 = INREG(MISC_TIMEOUT_REG);
+
+ if (xf86GetVerbosity() > 1) {
+ /* Debug */
+ ErrorF("MMPR regs: %08x %08x %08x %08x\n",
+ INREG(FIFO_CONTROL_REG),
+ INREG(MIU_CONTROL_REG),
+ INREG(STREAMS_TIMEOUT_REG),
+ INREG(MISC_TIMEOUT_REG));
+
+ PVERB5("\n\nViRGE driver: saved current video mode. Register dump:\n\n");
+ }
+
+ VGAOUT8(vgaCRIndex, 0x3a);
+ VGAOUT8(vgaCRReg, cr3a);
+ VGAOUT8(vgaCRIndex, 0x66);
+ VGAOUT8(vgaCRReg, cr66);
+ /* Dup the VGA & S3V state to the */
+ /* new mode state, but only first time. */
+ if( !ps3v->ModeStructInit ) {
+ /* XXX Should check the return value of vgaHWCopyReg() */
+ vgaHWCopyReg( &hwp->ModeReg, vgaSavePtr );
+ memcpy( &ps3v->ModeReg, save, sizeof(S3VRegRec) );
+ ps3v->ModeStructInit = TRUE;
+ }
+
+ if (xf86GetVerbosity() > 1) S3VPrintRegs(pScrn);
+
+ return;
+}
+
+
+/* This function saves the STREAMS registers to our private structure */
+
+static void
+S3VSaveSTREAMS(ScrnInfoPtr pScrn, unsigned int *streams)
+{
+ S3VPtr ps3v = S3VPTR(pScrn);
+/* void *s3vMmioMem = ps3v->MapBase; */
+
+ streams[0] = INREG(PSTREAM_CONTROL_REG);
+ streams[1] = INREG(COL_CHROMA_KEY_CONTROL_REG);
+ streams[2] = INREG(SSTREAM_CONTROL_REG);
+ streams[3] = INREG(CHROMA_KEY_UPPER_BOUND_REG);
+ streams[4] = INREG(SSTREAM_STRETCH_REG);
+ streams[5] = INREG(BLEND_CONTROL_REG);
+ streams[6] = INREG(PSTREAM_FBADDR0_REG);
+ streams[7] = INREG(PSTREAM_FBADDR1_REG);
+ streams[8] = INREG(PSTREAM_STRIDE_REG);
+ streams[9] = INREG(DOUBLE_BUFFER_REG);
+ streams[10] = INREG(SSTREAM_FBADDR0_REG);
+ streams[11] = INREG(SSTREAM_FBADDR1_REG);
+ streams[12] = INREG(SSTREAM_STRIDE_REG);
+ streams[13] = INREG(OPAQUE_OVERLAY_CONTROL_REG);
+ streams[14] = INREG(K1_VSCALE_REG);
+ streams[15] = INREG(K2_VSCALE_REG);
+ streams[16] = INREG(DDA_VERT_REG);
+ streams[17] = INREG(STREAMS_FIFO_REG);
+ streams[18] = INREG(PSTREAM_START_REG);
+ streams[19] = INREG(PSTREAM_WINDOW_SIZE_REG);
+ streams[20] = INREG(SSTREAM_START_REG);
+ streams[21] = INREG(SSTREAM_WINDOW_SIZE_REG);
+
+}
+
+
+/*
+ * This function is used to restore a video mode. It writes out all
+ * of the standard VGA and extended S3 registers needed to setup a
+ * video mode.
+ *
+ * Note that our life is made more difficult because of the STREAMS
+ * processor which must be used for 24bpp. We need to disable STREAMS
+ * before we switch video modes, or we risk locking up the machine.
+ * We also have to follow a certain order when reenabling it.
+ */
+/* let's try restoring in the same order as in the 3.3.2.3 driver */
+static void
+S3VWriteMode (ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, S3VRegPtr restore)
+{
+ unsigned char tmp, cr3a, cr66, cr67;
+
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ S3VPtr ps3v = S3VPTR(pScrn);
+/* void *s3vMmioMem = ps3v->MapBase; */
+ int vgaCRIndex, vgaCRReg, vgaIOBase;
+ vgaIOBase = hwp->IOBase;
+ vgaCRIndex = vgaIOBase + 4;
+ vgaCRReg = vgaIOBase + 5;
+
+ PVERB5(" S3VWriteMode\n");
+
+ vgaHWProtect(pScrn, TRUE);
+
+ /* Are we going to reenable STREAMS in this new mode? */
+ ps3v->STREAMSRunning = restore->CR67 & 0x0c;
+
+ /* First reset GE to make sure nothing is going on */
+ if(ps3v->Chipset == S3_ViRGE_VX) {
+ VGAOUT8(vgaCRIndex, 0x63);
+ if(VGAIN8(vgaCRReg) & 0x01) S3VGEReset(pScrn,0,__LINE__,__FILE__);
+ }
+ else {
+ VGAOUT8(vgaCRIndex, 0x66);
+ if(VGAIN8(vgaCRReg) & 0x01) S3VGEReset(pScrn,0,__LINE__,__FILE__);
+ }
+
+ /* As per databook, always disable STREAMS before changing modes */
+ VGAOUT8(vgaCRIndex, 0x67);
+ cr67 = VGAIN8(vgaCRReg);
+ if ((cr67 & 0x0c) == 0x0c) {
+ S3VDisableSTREAMS(pScrn); /* If STREAMS was running, disable it */
+ }
+
+ /* Restore S3 extended regs */
+ VGAOUT8(vgaCRIndex, 0x63);
+ VGAOUT8(vgaCRReg, restore->CR63);
+ VGAOUT8(vgaCRIndex, 0x66);
+ VGAOUT8(vgaCRReg, restore->CR66);
+ VGAOUT8(vgaCRIndex, 0x3a);
+ VGAOUT8(vgaCRReg, restore->CR3A);
+ VGAOUT8(vgaCRIndex, 0x31);
+ VGAOUT8(vgaCRReg, restore->CR31);
+ VGAOUT8(vgaCRIndex, 0x58);
+ VGAOUT8(vgaCRReg, restore->CR58);
+ VGAOUT8(vgaCRIndex, 0x55);
+ VGAOUT8(vgaCRReg, restore->CR55);
+
+ /* Extended mode timings registers */
+ VGAOUT8(vgaCRIndex, 0x53);
+ VGAOUT8(vgaCRReg, restore->CR53);
+ VGAOUT8(vgaCRIndex, 0x5d);
+ VGAOUT8(vgaCRReg, restore->CR5D);
+ VGAOUT8(vgaCRIndex, 0x5e);
+ VGAOUT8(vgaCRReg, restore->CR5E);
+ VGAOUT8(vgaCRIndex, 0x3b);
+ VGAOUT8(vgaCRReg, restore->CR3B);
+ VGAOUT8(vgaCRIndex, 0x3c);
+ VGAOUT8(vgaCRReg, restore->CR3C);
+ VGAOUT8(vgaCRIndex, 0x43);
+ VGAOUT8(vgaCRReg, restore->CR43);
+ VGAOUT8(vgaCRIndex, 0x65);
+ VGAOUT8(vgaCRReg, restore->CR65);
+ VGAOUT8(vgaCRIndex, 0x6d);
+ VGAOUT8(vgaCRReg, restore->CR6D);
+
+
+ /* Restore the desired video mode with CR67 */
+
+ VGAOUT8(vgaCRIndex, 0x67);
+ cr67 = VGAIN8(vgaCRReg) & 0xf; /* Possible hardware bug on VX? */
+ VGAOUT8(vgaCRReg, 0x50 | cr67);
+ usleep(10000);
+ VGAOUT8(vgaCRIndex, 0x67);
+ VGAOUT8(vgaCRReg, restore->CR67 & ~0x0c); /* Don't enable STREAMS yet */
+
+ /* Other mode timing and extended regs */
+ VGAOUT8(vgaCRIndex, 0x34);
+ VGAOUT8(vgaCRReg, restore->CR34);
+ VGAOUT8(vgaCRIndex, 0x40);
+ VGAOUT8(vgaCRReg, restore->CR40);
+ VGAOUT8(vgaCRIndex, 0x42);
+ VGAOUT8(vgaCRReg, restore->CR42);
+ VGAOUT8(vgaCRIndex, 0x45);
+ VGAOUT8(vgaCRReg, restore->CR45);
+ VGAOUT8(vgaCRIndex, 0x51);
+ VGAOUT8(vgaCRReg, restore->CR51);
+ VGAOUT8(vgaCRIndex, 0x54);
+ VGAOUT8(vgaCRReg, restore->CR54);
+
+ /* Memory timings */
+ VGAOUT8(vgaCRIndex, 0x36);
+ VGAOUT8(vgaCRReg, restore->CR36);
+ VGAOUT8(vgaCRIndex, 0x68);
+ VGAOUT8(vgaCRReg, restore->CR68);
+ VGAOUT8(vgaCRIndex, 0x69);
+ VGAOUT8(vgaCRReg, restore->CR69);
+
+ VGAOUT8(vgaCRIndex, 0x33);
+ VGAOUT8(vgaCRReg, restore->CR33);
+ if (ps3v->Chipset == S3_ViRGE_DXGX) {
+ VGAOUT8(vgaCRIndex, 0x86);
+ VGAOUT8(vgaCRReg, restore->CR86);
+ }
+ if (ps3v->Chipset == S3_ViRGE_DXGX || S3_ViRGE_GX2_SERIES(ps3v->Chipset) ||
+ S3_ViRGE_MX_SERIES(ps3v->Chipset)) {
+ VGAOUT8(vgaCRIndex, 0x90);
+ VGAOUT8(vgaCRReg, restore->CR90);
+ }
+
+ /* Unlock extended sequencer regs */
+ VGAOUT8(0x3c4, 0x08);
+ VGAOUT8(0x3c5, 0x06);
+
+
+ /* Restore extended sequencer regs for MCLK. SR10 == 255 indicates that
+ * we should leave the default SR10 and SR11 values there.
+ */
+
+ if (restore->SR10 != 255) {
+ VGAOUT8(0x3c4, 0x10);
+ VGAOUT8(0x3c5, restore->SR10);
+ VGAOUT8(0x3c4, 0x11);
+ VGAOUT8(0x3c5, restore->SR11);
+ }
+
+ /* Restore extended sequencer regs for DCLK */
+ VGAOUT8(0x3c4, 0x12);
+ VGAOUT8(0x3c5, restore->SR12);
+ VGAOUT8(0x3c4, 0x13);
+ VGAOUT8(0x3c5, restore->SR13);
+ if (S3_ViRGE_GX2_SERIES(ps3v->Chipset) || S3_ViRGE_MX_SERIES(ps3v->Chipset)) {
+ VGAOUT8(0x3c4, 0x29);
+ VGAOUT8(0x3c5, restore->SR29);
+ VGAOUT8(0x3c4, 0x54);
+ VGAOUT8(0x3c5, restore->SR54);
+ VGAOUT8(0x3c4, 0x55);
+ VGAOUT8(0x3c5, restore->SR55);
+ VGAOUT8(0x3c4, 0x56);
+ VGAOUT8(0x3c5, restore->SR56);
+ VGAOUT8(0x3c4, 0x57);
+ VGAOUT8(0x3c5, restore->SR57);
+ }
+
+ VGAOUT8(0x3c4, 0x18);
+ VGAOUT8(0x3c5, restore->SR18);
+
+ /* Load new m,n PLL values for DCLK & MCLK */
+ VGAOUT8(0x3c4, 0x15);
+ tmp = VGAIN8(0x3c5) & ~0x21;
+
+ VGAOUT8(0x3c5, tmp | 0x03);
+ VGAOUT8(0x3c5, tmp | 0x23);
+ VGAOUT8(0x3c5, tmp | 0x03);
+ VGAOUT8(0x3c5, restore->SR15);
+
+ VGAOUT8(0x3c4, 0x08);
+ VGAOUT8(0x3c5, restore->SR8);
+
+
+ /* Now write out CR67 in full, possibly starting STREAMS */
+
+ VerticalRetraceWait();
+ VGAOUT8(vgaCRIndex, 0x67);
+ VGAOUT8(vgaCRReg, 0x50); /* For possible bug on VX?! */
+ usleep(10000);
+ VGAOUT8(vgaCRIndex, 0x67);
+ VGAOUT8(vgaCRReg, restore->CR67);
+
+ VGAOUT8(vgaCRIndex, 0x66);
+ cr66 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRReg, cr66 | 0x80);
+ VGAOUT8(vgaCRIndex, 0x3a);
+ cr3a = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRReg, cr3a | 0x80);
+
+ /* And finally, we init the STREAMS processor if we have CR67 indicate 24bpp
+ * We also restore FIFO and TIMEOUT memory controller registers. (later...)
+ */
+
+ if (ps3v->NeedSTREAMS) {
+ if(ps3v->STREAMSRunning) S3VRestoreSTREAMS(pScrn, restore->STREAMS);
+ }
+
+ /* Now, before we continue, check if this mode has the graphic engine ON
+ * If yes, then we reset it.
+ * This fixes some problems with corruption at 24bpp with STREAMS
+ * Also restore the MIU registers.
+ */
+
+#ifndef MetroLink
+ if(ps3v->Chipset == S3_ViRGE_VX) {
+ if(restore->CR63 & 0x01) S3VGEReset(pScrn,0,__LINE__,__FILE__);
+ }
+ else {
+ if(restore->CR66 & 0x01) S3VGEReset(pScrn,0,__LINE__,__FILE__);
+ }
+#else
+ S3VGEReset(pScrn,0,__LINE__,__FILE__);
+#endif
+
+ VerticalRetraceWait();
+ OUTREG(FIFO_CONTROL_REG, restore->MMPR0);
+ WaitIdle(); /* Don't ask... */
+ OUTREG(MIU_CONTROL_REG, restore->MMPR1);
+ WaitIdle();
+ OUTREG(STREAMS_TIMEOUT_REG, restore->MMPR2);
+ WaitIdle();
+ OUTREG(MISC_TIMEOUT_REG, restore->MMPR3);
+
+
+ /* Restore the standard VGA registers */
+ /* False indicates no fontinfo restore. */
+ /* VGA_SR_MODE restores mode info only, no font, no colormap */
+ /* Do all for primary video */
+ if (xf86IsPrimaryPci(ps3v->PciInfo))
+ vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_ALL);
+ /* Mode only for non-primary? */
+ else
+ vgaHWRestore(pScrn, vgaSavePtr, VGA_SR_MODE);
+ /* moved from before vgaHWRestore, to prevent segfault? */
+ VGAOUT8(vgaCRIndex, 0x66);
+ VGAOUT8(vgaCRReg, cr66);
+ VGAOUT8(vgaCRIndex, 0x3a);
+ VGAOUT8(vgaCRReg, cr3a);
+
+ if (xf86GetVerbosity() > 1) {
+ ErrorF("\n\nViRGE driver: done restoring mode, dumping CR registers:\n\n");
+ S3VPrintRegs(pScrn);
+ }
+
+ vgaHWProtect(pScrn, FALSE);
+
+ return;
+
+}
+
+
+/* This function restores the saved STREAMS registers */
+
+static void
+S3VRestoreSTREAMS(ScrnInfoPtr pScrn, unsigned int *streams)
+{
+ S3VPtr ps3v = S3VPTR(pScrn);
+/* void *s3vMmioMem = ps3v->MapBase; */
+
+
+/* For now, set most regs to their default values for 24bpp
+ * Restore only those that are needed for width/height/stride
+ * Otherwise, we seem to get lockups because some registers
+ * when saved have some reserved bits set.
+ */
+
+ OUTREG(PSTREAM_CONTROL_REG, streams[0] & 0x77000000);
+ OUTREG(COL_CHROMA_KEY_CONTROL_REG, 0x00);
+ OUTREG(SSTREAM_CONTROL_REG, 0x03000000);
+ OUTREG(CHROMA_KEY_UPPER_BOUND_REG, 0x00);
+ OUTREG(SSTREAM_STRETCH_REG, 0x00);
+ OUTREG(BLEND_CONTROL_REG, 0x01000000);
+ OUTREG(PSTREAM_FBADDR0_REG, 0x00);
+ OUTREG(PSTREAM_FBADDR1_REG, 0x00);
+ OUTREG(PSTREAM_STRIDE_REG, streams[8] & 0x0fff);
+ OUTREG(DOUBLE_BUFFER_REG, 0x00);
+ OUTREG(SSTREAM_FBADDR0_REG, 0x00);
+ OUTREG(SSTREAM_FBADDR1_REG, 0x00);
+ OUTREG(SSTREAM_STRIDE_REG, 0x01);
+ OUTREG(OPAQUE_OVERLAY_CONTROL_REG, 0x40000000);
+ OUTREG(K1_VSCALE_REG, 0x00);
+ OUTREG(K2_VSCALE_REG, 0x00);
+ OUTREG(DDA_VERT_REG, 0x00);
+ OUTREG(PSTREAM_START_REG, 0x00010001);
+ OUTREG(PSTREAM_WINDOW_SIZE_REG, streams[19] & 0x07ff07ff);
+ OUTREG(SSTREAM_START_REG, 0x07ff07ff);
+ OUTREG(SSTREAM_WINDOW_SIZE_REG, 0x00010001);
+
+
+}
+
+
+
+
+/* And this function disables the STREAMS processor as per databook.
+ * This is usefull before we do a mode change
+ */
+
+static void
+S3VDisableSTREAMS(ScrnInfoPtr pScrn)
+{
+unsigned char tmp;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ S3VPtr ps3v = S3VPTR(pScrn);
+/* void *s3vMmioMem = ps3v->MapBase; */
+ int vgaCRIndex, vgaCRReg, vgaIOBase;
+ vgaIOBase = hwp->IOBase;
+ vgaCRIndex = vgaIOBase + 4;
+ vgaCRReg = vgaIOBase + 5;
+
+ VerticalRetraceWait();
+ OUTREG(FIFO_CONTROL_REG, 0xC000);
+ VGAOUT8(vgaCRIndex, 0x67);
+ tmp = VGAIN8(vgaCRReg);
+ /* Disable STREAMS processor */
+ VGAOUT8( vgaCRReg, tmp & ~0x0C );
+
+ return;
+}
+
+
+
+/* MapMem - contains half of pre-4.0 EnterLeave function */
+/* The EnterLeave function which en/dis access to IO ports and ext. regs */
+ /********************************************************/
+ /* Aaagh... So many locations! On my machine (KJB) the*/
+ /* following is true. */
+ /* PciInfo->memBase[0] returns e400 0000 */
+ /* From my ViRGE manual, the memory map looks like */
+ /* Linear mem - 16M 000 0000 - 0ff ffff */
+ /* Image xfer - 32k 100 0000 - 100 7fff */
+ /* PCI cnfg 100 8000 - 100 8043 */
+ /* ... */
+ /* CRT VGA 3b? reg 100 83b0 - */
+ /* And S3_NEWMMIO_VGABASE = S3_NEWMMIO_REGBASE + 0x8000 */
+ /* where S3_NEWMMIO_REGBASE = 0x100 0000 ( 16MB ) */
+ /* S3_NEWMMIO_REGSIZE = 0x1 0000 ( 64KB ) */
+ /* S3V_MMIO_REGSIZE = 0x8000 ( 32KB ) - above includes */
+ /* the image transfer area, so this one is used instead.*/
+ /* ps3v->IOBase is assinged the virtual address returned*/
+ /* from MapPciMem, it is the address to base all */
+ /* register access. (It is a pointer.) */
+ /* hwp->MemBase is a CARD32, containing the register */
+ /* base. (It's a conversion from IOBase above.) */
+ /********************************************************/
+
+
+static Bool
+S3VMapMem(ScrnInfoPtr pScrn)
+{
+ S3VPtr ps3v;
+ vgaHWPtr hwp;
+ int mmioFlags;
+
+ PVERB5(" S3VMapMem\n");
+
+ ps3v = S3VPTR(pScrn);
+
+ /* Map the ViRGE register space */
+ /* Starts with Image Transfer area */
+ /* so that we can use registers map */
+ /* structure - see newmmio.h */
+ /* around 0x10000 from MemBase */
+#ifdef __alpha__
+ mmioFlags = VIDMEM_MMIO | VIDMEM_SPARSE;
+#else
+ mmioFlags = VIDMEM_MMIO;
+#endif
+ ErrorF("1\n");
+
+ ps3v->MapBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, ps3v->PciTag,
+ ps3v->PciInfo->memBase[0] + S3_NEWMMIO_REGBASE,
+ S3_NEWMMIO_REGSIZE);
+
+#ifdef __alpha__
+ ps3v->MapBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ ps3v->PciTag,
+ ps3v->PciInfo->memBase[0] + S3_NEWMMIO_REGBASE,
+ 0x8000);
+
+ /* XXX the shift of 5 isn't correct for JENSEN */
+ ps3v->IOBase = ps3v->MapBase + (S3V_MMIO_REGSIZE << 5);
+#else
+ /* IOBase starts at PCI registers */
+ ps3v->IOBase = ps3v->MapBase + S3V_MMIO_REGSIZE;
+#endif
+
+ if( !ps3v->MapBase ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Internal error: could not map registers.\n");
+ return FALSE;
+ }
+ /* Map the framebuffer */
+ if (ps3v->videoRambytes) { /* not set in PreInit() */
+ ps3v->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ ps3v->PciTag, ps3v->PciInfo->memBase[0],
+ ps3v->videoRambytes );
+
+ if( !ps3v->FBBase ) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Internal error: could not map framebuffer.\n");
+ return FALSE;
+ }
+ /* Initially the visual display start */
+ /* is the same as the mapped start. */
+ ps3v->FBStart = ps3v->FBBase;
+ }
+
+ pScrn->memPhysBase = ps3v->PciInfo->memBase[0];
+ pScrn->fbOffset = 0;
+
+ /* Set up offset to hwcursor memory area */
+ /* It's a 1K chunk at the end of the frame buffer */
+ ps3v->FBCursorOffset = ps3v->videoRambytes - 1024;
+ S3VEnableMmio( pScrn);
+ /* Assign hwp->MemBase & IOBase here */
+ hwp = VGAHWPTR(pScrn);
+ /* Sets MMIOBase and Offset, assigns */
+ /* functions. Offset from map area */
+ /* to VGA reg area is 0x8000. */
+ vgaHWSetMmioFuncs( hwp, ps3v->MapBase, S3V_MMIO_REGSIZE );
+ /* assigns hwp->IOBase to 3D0 or 3B0 */
+ /* needs hwp->MMIOBase to work */
+ vgaHWGetIOBase(hwp);
+
+ /* Map the VGA memory when the */
+ /* primary video */
+
+ if (xf86IsPrimaryPci(ps3v->PciInfo)) {
+ hwp->MapSize = 0x10000;
+ if (!vgaHWMapMem(pScrn))
+ return FALSE;
+ ps3v->PrimaryVidMapped = TRUE;
+ }
+
+ return TRUE;
+}
+
+
+
+/* UnMapMem - contains half of pre-4.0 EnterLeave function */
+/* The EnterLeave function which en/dis access to IO ports and ext. regs */
+
+static void
+S3VUnmapMem(ScrnInfoPtr pScrn)
+{
+ S3VPtr ps3v;
+
+ ps3v = S3VPTR(pScrn);
+ /* Unmap VGA mem if mapped. */
+ if( ps3v->PrimaryVidMapped ) {
+ vgaHWUnmapMem( pScrn );
+ ps3v->PrimaryVidMapped = FALSE;
+ }
+
+ S3VDisableMmio(pScrn);
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)ps3v->MapBase,
+ S3_NEWMMIO_REGSIZE);
+ if (ps3v->FBBase)
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)ps3v->FBBase,
+ ps3v->videoRambytes);
+#ifdef __alpha__
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)ps3v->MapBaseDense,
+ 0x8000);
+#endif /* __alpha__ */
+
+ return;
+}
+
+
+
+/* Mandatory */
+
+/* This gets called at the start of each server generation */
+
+static Bool
+S3VScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn;
+ S3VPtr ps3v;
+ int ret;
+ PVERB5(" S3VScreenInit\n");
+ /* First get the ScrnInfoRec */
+ pScrn = xf86Screens[pScreen->myNum];
+ /* Get S3V rec */
+ ps3v = S3VPTR(pScrn);
+ /* Make sure we have card access */
+/* xf86EnableAccess(pScrn);*/
+ /* Map MMIO regs and framebuffer */
+ if( !S3VMapMem(pScrn) )
+ return FALSE;
+ /* Save the chip/graphics state */
+ S3VSave(pScrn);
+ /* Blank the screen during init */
+ vgaHWBlankScreen(pScrn, TRUE );
+ /* Initialise the first mode */
+ if (!S3VModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ /* Adjust the viewport */
+ S3VAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset the visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ /*
+ * For bpp > 8, the default visuals are not acceptable because we only
+ * support TrueColor and not DirectColor. To deal with this, call
+ * miSetVisualTypes with the appropriate visual mask.
+ */
+
+ if (pScrn->bitsPerPixel > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
+ pScrn->defaultVisual))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+ ret = S3VInternalScreenInit(scrnIndex, pScreen);
+
+ if (!ret)
+ return FALSE;
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ if (pScrn->bitsPerPixel > 8) {
+ VisualPtr visual;
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+ /* Initialize acceleration layer */
+ if (!ps3v->NoAccel) {
+ if(pScrn->bitsPerPixel == 32) {
+ /* 32 bit Accel currently broken
+ if (!S3VAccelInit32(pScreen))
+ return FALSE;
+ */
+ ;
+ } else
+ if (!S3VAccelInit(pScreen))
+ return FALSE;
+ }
+
+ miInitializeBackingStore(pScreen);
+ /* hardware cursor needs to wrap this layer */
+ S3VDGAInit(pScreen);
+
+ /* Initialise cursor functions */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ /* Initialize HW cursor layer.
+ Must follow software cursor initialization*/
+ if (ps3v->hwcursor) {
+ if(!S3VHWCursorInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ }
+ }
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+ /* Initialize colormap layer. */
+ /* Must follow initialization */
+ /* of the default colormap. */
+ /* And SetGamma call, else it */
+ /* will load palette with solid */
+ /* white. */
+ if(!xf86HandleColormaps(pScreen, 256, 6, S3VLoadPalette, NULL,
+ CMAP_RELOAD_ON_MODE_SWITCH ))
+ return FALSE;
+ /* All the ugly stuff is done, */
+ /* so re-enable the screen. */
+ vgaHWBlankScreen(pScrn, FALSE );
+
+#if 0
+ pScrn->racMemFlags = RAC_COLORMAP | RAC_CURSOR | RAC_FB | RAC_VIEWPORT;
+#endif
+ pScreen->SaveScreen = S3VSaveScreen;
+
+ /* Wrap the current CloseScreen function */
+ ps3v->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = S3VCloseScreen;
+
+#ifdef DPMSExtension
+ if(xf86DPMSInit(pScreen, S3VDisplayPowerManagementSet, 0) == FALSE)
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DPMS initialization failed!\n");
+#endif
+
+#ifdef XvExtension
+ {
+ XF86VideoAdaptorPtr *ptr;
+ int n;
+
+ n = xf86XVListGenericAdaptors(&ptr);
+ if (n) {
+ xf86XVScreenInit(pScreen, ptr, n);
+ }
+ }
+#endif
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+ /* Done */
+ return TRUE;
+}
+
+
+
+/* Common init routines needed in EnterVT and ScreenInit */
+
+static int
+S3VInternalScreenInit( int scrnIndex, ScreenPtr pScreen)
+{
+ int ret = TRUE;
+ ScrnInfoPtr pScrn;
+ S3VPtr ps3v;
+ /* First get the ScrnInfoRec */
+ pScrn = xf86Screens[pScreen->myNum];
+
+ ps3v = S3VPTR(pScrn);
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ ret = cfbScreenInit(pScreen, ps3v->FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 16:
+ ret = cfb16ScreenInit(pScreen, ps3v->FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 24:
+ if (pix24bpp ==24) {
+ ret = cfb24ScreenInit(pScreen, ps3v->FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ } else {
+ ret = cfb24_32ScreenInit(pScreen, ps3v->FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ }
+ break;
+ case 32:
+ ret = cfb32ScreenInit(pScreen, ps3v->FBStart,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in S3VScreenInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ } /*switch*/
+
+ return ret;
+}
+
+
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+static ModeStatus
+S3VValidMode(int index, DisplayModePtr mode, Bool verbose, int flags)
+{
+
+ return MODE_OK;
+}
+
+
+
+static Bool
+S3VModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ S3VPtr ps3v = S3VPTR(pScrn);
+ int width, dclk;
+ int i, j;
+ unsigned char tmp = 0;
+
+ /* Store values to current mode register structs */
+ S3VRegPtr new = &ps3v->ModeReg;
+ vgaRegPtr vganew = &hwp->ModeReg;
+ int vgaCRIndex, vgaCRReg, vgaIOBase;
+
+ vgaIOBase = hwp->IOBase;
+ vgaCRIndex = vgaIOBase + 4;
+ vgaCRReg = vgaIOBase + 5;
+
+ PVERB5(" S3VModeInit\n");
+
+ /* First we adjust the horizontal timings if needed */
+
+ if(ps3v->HorizScaleFactor != 1)
+ if (!mode->CrtcHAdjusted) {
+ mode->CrtcHDisplay *= ps3v->HorizScaleFactor;
+ mode->CrtcHSyncStart *= ps3v->HorizScaleFactor;
+ mode->CrtcHSyncEnd *= ps3v->HorizScaleFactor;
+ mode->CrtcHTotal *= ps3v->HorizScaleFactor;
+ mode->CrtcHSkew *= ps3v->HorizScaleFactor;
+ mode->CrtcHAdjusted = TRUE;
+ }
+
+ if(!vgaHWInit (pScrn, mode))
+ return FALSE;
+
+ /* Now we fill in the rest of the stuff we need for the virge */
+ /* Start with MMIO, linear addr. regs */
+
+ VGAOUT8(vgaCRIndex, 0x3a);
+ tmp = VGAIN8(vgaCRReg);
+ if(ps3v->pci_burst)
+ new->CR3A = (tmp & 0x7f) | 0x15; /* ENH 256, PCI burst */
+ else
+ new->CR3A = tmp | 0x95; /* ENH 256, no PCI burst! */
+
+ VGAOUT8(vgaCRIndex, 0x55);
+ new->CR55 = VGAIN8(vgaCRReg);
+ if (ps3v->hwcursor)
+ new->CR55 |= 0x10; /* Enables X11 hw cursor mode */
+ new->CR53 = 0x08; /* Enables MMIO */
+ new->CR31 = 0x8c; /* Dis. 64k window, en. ENH maps */
+
+ /* Enables S3D graphic engine and PCI disconnects */
+ if(ps3v->Chipset == S3_ViRGE_VX){
+ new->CR66 = 0x90;
+ new->CR63 = 0x09;
+ }
+ else {
+ new->CR66 = 0x89;
+ new->CR63 = 0;
+ }
+
+ /* Now set linear addr. registers */
+ /* LAW size: we have 2 cases, 2MB, 4MB or >= 4MB for VX */
+ VGAOUT8(vgaCRIndex, 0x58);
+ new->CR58 = VGAIN8(vgaCRReg) & 0x80;
+ if(pScrn->videoRam == 2048){
+ new->CR58 |= 0x02 | 0x10;
+ }
+ else {
+ new->CR58 |= 0x03 | 0x10; /* 4MB window on virge, 8MB on VX */
+ }
+ if(ps3v->Chipset == S3_ViRGE_VX)
+ new->CR58 |= 0x40;
+ if (ps3v->early_ras_precharge)
+ new->CR58 |= 0x80;
+ if (ps3v->late_ras_precharge)
+ new->CR58 &= 0x7f;
+
+ /* ** On PCI bus, no need to reprogram the linear window base address */
+
+ /* Now do clock PLL programming. Use the s3gendac function to get m,n */
+ /* Also determine if we need doubling etc. */
+
+ dclk = mode->Clock;
+ new->CR67 = 0x00; /* Defaults */
+ new->SR15 = 0x03 | 0x80;
+ new->SR18 = 0x00;
+ new->CR43 = 0x00;
+ new->CR45 = 0x00;
+ /* Enable MMIO to RAMDAC registers */
+ new->CR65 = 0x00; /* CR65_2 must be zero, doc seems to be wrong */
+ new->CR54 = 0x00;
+
+ VGAOUT8(vgaCRIndex, 0x40);
+ new->CR40 = VGAIN8(vgaCRReg) & ~0x01;
+
+ /*cep*/
+ xf86ErrorFVerb(VERBLEV, " S3VModeInit dclk=%i \n",
+ dclk
+ );
+
+ /* Memory controller registers. Optimize for better graphics engine
+ * performance. These settings are adjusted/overridden below for other bpp/
+ * XConfig options.The idea here is to give a longer number of contiguous
+ * MCLK's to both refresh and the graphics engine, to diminish the
+ * relative penalty of 3 or 4 mclk's needed to setup memory transfers.
+ */
+ new->MMPR0 = 0x010400; /* defaults */
+ new->MMPR1 = 0x00;
+ new->MMPR2 = 0x0808;
+ new->MMPR3 = 0x08080810;
+
+ /*
+ * These settings look like they ought to be better adjusted for depth,
+ * so for problem modes running without any fifo_ option should be
+ * usable. Note that these adjust some memory timings and relate to
+ * the boards MCLK setting.
+ * */
+ if( ps3v->fifo_aggressive || ps3v->fifo_moderate ||
+ ps3v->fifo_conservative ) {
+
+ new->MMPR1 = 0x0200; /* Low P. stream waits before filling */
+ new->MMPR2 = 0x1808; /* Let the FIFO refill itself */
+ new->MMPR3 = 0x08081810; /* And let the GE hold the bus for a while */
+ }
+
+ /* And setup here the new value for MCLK. We use the XConfig
+ * option "set_mclk", whose value gets stored in ps3v->MCLK.
+ * I'm not sure what the maximum "permitted" value should be, probably
+ * 100 MHz is more than enough for now.
+ */
+
+ if(ps3v->MCLK> 0) {
+ S3VCommonCalcClock(ps3v->MCLK, 1, 1, 31, 0, 3,
+ 135000, 270000, &new->SR11, &new->SR10);
+ }
+ else {
+ new->SR10 = 255; /* This is a reserved value, so we use as flag */
+ new->SR11 = 255;
+ }
+
+ /* most modes don't need STREAMS */
+ /* processor, preset FALSE */
+ ps3v->NeedSTREAMS = FALSE;
+
+ if(ps3v->Chipset == S3_ViRGE_VX){
+ if (pScrn->bitsPerPixel == 8) {
+ if (dclk <= 110000) new->CR67 = 0x00; /* 8bpp, 135MHz */
+ else new->CR67 = 0x10; /* 8bpp, 220MHz */
+ }
+ else if ((pScrn->bitsPerPixel == 16) && (pScrn->weight.green == 5)) {
+ if (dclk <= 110000) new->CR67 = 0x20; /* 15bpp, 135MHz */
+ else new->CR67 = 0x30; /* 15bpp, 220MHz */
+ }
+ else if (pScrn->bitsPerPixel == 16) {
+ if (dclk <= 110000) new->CR67 = 0x40; /* 16bpp, 135MHz */
+ else new->CR67 = 0x50; /* 16bpp, 220MHz */
+ }
+ else if ((pScrn->bitsPerPixel == 24) || (pScrn->bitsPerPixel == 32)) {
+ new->CR67 = 0xd0 | 0x0c; /* 24bpp, 135MHz, STREAMS */
+ /* Flag STREAMS proc. required */
+ ps3v->NeedSTREAMS = TRUE;
+ S3VInitSTREAMS(pScrn, new->STREAMS, mode);
+ new->MMPR0 = 0xc098; /* Adjust FIFO slots */
+ }
+ S3VCommonCalcClock(dclk, 1, 1, 31, 0, 4,
+ 220000, 440000, &new->SR13, &new->SR12);
+
+ }
+ else if (S3_ViRGE_GX2_SERIES(ps3v->Chipset) || S3_ViRGE_MX_SERIES(ps3v->Chipset)) {
+ if (pScrn->bitsPerPixel == 8)
+ new->CR67 = 0x00;
+ else if (pScrn->bitsPerPixel == 16) {
+ if (pScrn->weight.green == 5)
+ new->CR67 = 0x30; /* 15bpp */
+ else
+ new->CR67 = 0x50; /* 16bpp */
+ }
+ else if ((pScrn->bitsPerPixel == 24) /* || (pScrn->bitsPerPixel == 32) */ ) {
+ new->CR67 = 0x74; /* 24bpp, STREAMS */
+ /* Flag STREAMS proc. required */
+ ps3v->NeedSTREAMS = TRUE;
+ S3VInitSTREAMS(pScrn, new->STREAMS, mode);
+ new->MMPR0 = 0xc098; /* Adjust FIFO slots */
+ }
+ else if (pScrn->bitsPerPixel == 32) {
+ new->CR67 = 0xd0; /* 32bpp */
+ /* Missing STREAMs and other stuff here? KJB */
+ /* new->MMPR0 = 0xc098; / Adjust FIFO slots */
+ }
+ {
+ unsigned char ndiv;
+ if (S3_ViRGE_MX_SERIES(ps3v->Chipset)) {
+ unsigned char sr8;
+ VGAOUT8(0x3c4, 0x08); /* unlock extended SEQ regs */
+ sr8 = VGAIN8(0x3c5);
+ VGAOUT8(0x3c5, 0x06);
+ VGAOUT8(0x3c4, 0x31);
+ if (VGAIN8(0x3c5) & 0x10) { /* LCD on */
+ if (!ps3v->LCDClk) { /* entered only once for first mode */
+ int h_lcd, v_lcd;
+ VGAOUT8(0x3c4, 0x61);
+ h_lcd = VGAIN8(0x3c5);
+ VGAOUT8(0x3c4, 0x66);
+ h_lcd |= ((VGAIN8(0x3c5) & 0x02) << 7);
+ h_lcd = (h_lcd+1) * 8;
+ VGAOUT8(0x3c4, 0x69);
+ v_lcd = VGAIN8(0x3c5);
+ VGAOUT8(0x3c4, 0x6e);
+ v_lcd |= ((VGAIN8(0x3c5) & 0x70) << 4);
+ v_lcd++;
+
+ /* check if first mode has physical LCD resolution */
+ if (pScrn->modes->HDisplay == h_lcd && pScrn->modes->VDisplay == v_lcd)
+ ps3v->LCDClk = pScrn->clock[pScrn->modes->Clock];
+ else {
+ int n1, n2, sr12, sr13, sr29;
+ VGAOUT8(0x3c4, 0x12);
+ sr12 = VGAIN8(0x3c5);
+ VGAOUT8(0x3c4, 0x13);
+ sr13 = VGAIN8(0x3c5) & 0x7f;
+ VGAOUT8(0x3c4, 0x29);
+ sr29 = VGAIN8(0x3c5);
+ n1 = sr12 & 0x1f;
+ n2 = ((sr12>>6) & 0x03) | ((sr29 & 0x01) << 2);
+ ps3v->LCDClk = ((2 * 1431818 * (sr13+2)) / (n1+2) / (1 << n2) + 50) / 100;
+ }
+ }
+ S3VCommonCalcClock(ps3v->LCDClk/2, 1, 1, 31, 0, 4,
+ 170000, 340000, &new->SR13, &ndiv);
+ }
+ else
+ S3VCommonCalcClock(dclk/2, 1, 1, 31, 0, 4,
+ 170000, 340000, &new->SR13, &ndiv);
+ VGAOUT8(0x3c4, 0x08);
+ VGAOUT8(0x3c5, sr8);
+ }
+ else /* S3_ViRGE_GX2 */
+ S3VCommonCalcClock(dclk, 1, 1, 31, 0, 4,
+ 170000, 340000, &new->SR13, &ndiv);
+ new->SR29 = ndiv >> 7;
+ new->SR12 = (ndiv & 0x1f) | ((ndiv & 0x60) << 1);
+ }
+ }
+ else { /* Is this correct for DX/GX as well? */
+ if (pScrn->bitsPerPixel == 8) {
+ if(dclk > 80000) { /* We need pixmux */
+ new->CR67 = 0x10;
+ new->SR15 |= 0x10; /* Set DCLK/2 bit */
+ new->SR18 = 0x80; /* Enable pixmux */
+ }
+ }
+ else if ((pScrn->bitsPerPixel == 16) && (pScrn->weight.green == 5)) {
+ new->CR67 = 0x30; /* 15bpp */
+ }
+ else if (pScrn->bitsPerPixel == 16) {
+ new->CR67 = 0x50;
+ }
+ else if (pScrn->bitsPerPixel == 24) {
+ new->CR67 = 0xd0 | 0x0c;
+ /* Flag STREAMS proc. required */
+ ps3v->NeedSTREAMS = TRUE;
+ S3VInitSTREAMS(pScrn, new->STREAMS, mode);
+ new->MMPR0 = 0xc000; /* Adjust FIFO slots */
+ }
+ else if (pScrn->bitsPerPixel == 32) {
+ new->CR67 = 0xd0 | 0x0c;
+ /* Flag STREAMS proc. required */
+ ps3v->NeedSTREAMS = TRUE;
+ S3VInitSTREAMS(pScrn, new->STREAMS, mode);
+ new->MMPR0 = 0x10000; /* Still more FIFO slots */
+ }
+ S3VCommonCalcClock(dclk, 1, 1, 31, 0, 3,
+ 135000, 270000, &new->SR13, &new->SR12);
+ }
+
+ /* Now adjust the value of the FIFO based upon options specified */
+ if( ps3v->fifo_moderate ) {
+ if(pScrn->bitsPerPixel < 24)
+ new->MMPR0 -= 0x8000;
+ else
+ new->MMPR0 -= 0x4000;
+ }
+ else if( ps3v->fifo_aggressive ) {
+ if(pScrn->bitsPerPixel < 24)
+ new->MMPR0 -= 0xc000;
+ else
+ new->MMPR0 -= 0x6000;
+ }
+
+ /* If we have an interlace mode, set the interlace bit. Note that mode
+ * vertical timings are already adjusted by the standard VGA code
+ */
+ if(mode->Flags & V_INTERLACE) {
+ new->CR42 = 0x20; /* Set interlace mode */
+ }
+ else {
+ new->CR42 = 0x00;
+ }
+
+ /* Set display fifo */
+ new->CR34 = 0x10;
+
+ /* Now we adjust registers for extended mode timings */
+ /* This is taken without change from the accel/s3_virge code */
+
+ i = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8) |
+ ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7) |
+ ((((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6) |
+ ((mode->CrtcHSyncStart & 0x800) >> 7);
+
+ if ((mode->CrtcHSyncEnd >> 3) - (mode->CrtcHSyncStart >> 3) > 64)
+ i |= 0x08; /* add another 64 DCLKs to blank pulse width */
+
+ if ((mode->CrtcHSyncEnd >> 3) - (mode->CrtcHSyncStart >> 3) > 32)
+ i |= 0x20; /* add another 32 DCLKs to hsync pulse width */
+
+ j = ( vganew->CRTC[0] + ((i&0x01)<<8)
+ + vganew->CRTC[4] + ((i&0x10)<<4) + 1) / 2;
+
+ if (j-(vganew->CRTC[4] + ((i&0x10)<<4)) < 4) {
+ if (vganew->CRTC[4] + ((i&0x10)<<4) + 4 <= vganew->CRTC[0]+ ((i&0x01)<<8))
+ j = vganew->CRTC[4] + ((i&0x10)<<4) + 4;
+ else
+ j = vganew->CRTC[0]+ ((i&0x01)<<8) + 1;
+ }
+ new->CR3B = j & 0xFF;
+ i |= (j & 0x100) >> 2;
+ new->CR3C = (vganew->CRTC[0] + ((i&0x01)<<8))/2;
+ new->CR5D = i;
+
+ new->CR5E = (((mode->CrtcVTotal - 2) & 0x400) >> 10) |
+ (((mode->CrtcVDisplay - 1) & 0x400) >> 9) |
+ (((mode->CrtcVSyncStart) & 0x400) >> 8) |
+ (((mode->CrtcVSyncStart) & 0x400) >> 6) | 0x40;
+
+
+ width = (pScrn->displayWidth * (pScrn->bitsPerPixel / 8))>> 3;
+ vganew->CRTC[19] = 0xFF & width;
+ new->CR51 = (0x300 & width) >> 4; /* Extension bits */
+
+ /* And finally, select clock source 2 for programmable PLL */
+ vganew->MiscOutReg |= 0x0c;
+
+
+ new->CR33 = 0x20;
+ if (ps3v->Chipset == S3_ViRGE_DXGX) {
+ new->CR86 = 0x80; /* disable DAC power saving to avoid bright left edge */
+ }
+ if (ps3v->Chipset == S3_ViRGE_DXGX || S3_ViRGE_GX2_SERIES(ps3v->Chipset)) {
+ new->CR90 = 0x00; /* disable the stream display fetch length control */
+ }
+
+
+ /* Now we handle various XConfig memory options and others */
+
+ VGAOUT8(vgaCRIndex, 0x36);
+ new->CR36 = VGAIN8(vgaCRReg);
+ /* option "slow_edodram" sets EDO to 2 cycle mode on ViRGE */
+ if (ps3v->Chipset == S3_ViRGE) {
+ if( ps3v->slow_edodram )
+ new->CR36 = (new->CR36 & 0xf3) | 0x08;
+ else
+ new->CR36 &= 0xf3;
+ }
+
+ /* Option "fpm_vram" for ViRGE_VX sets memory in fast page mode */
+ if (ps3v->Chipset == S3_ViRGE_VX) {
+ if( ps3v->fpm_vram )
+ new->CR36 |= 0x0c;
+ else
+ new->CR36 &= ~0x0c;
+ }
+
+ /* S3_INVERT_VCLK was defaulted to 0 */
+ /* in 3.3.3 and never changed. */
+ /* Also, bit 0 is never set in 3.9Nm, */
+ /* so I left this out for 4.0. */
+ #if 0
+ if (mode->Private[0] & (1 << S3_INVERT_VCLK)) {
+ if (mode->Private[S3_INVERT_VCLK])
+ new->CR67 |= 1;
+ else
+ new->CR67 &= ~1;
+ }
+ #endif
+ /* S3_BLANK_DELAY settings based on */
+ /* defaults only. From 3.3.3 */
+ {
+ int blank_delay;
+
+ if(ps3v->Chipset == S3_ViRGE_VX)
+ /* these values need to be changed once CR67_1 is set
+ for gamma correction (see S3V server) ! */
+ if (pScrn->bitsPerPixel == 8)
+ blank_delay = 0x00;
+ else if (pScrn->bitsPerPixel == 16)
+ blank_delay = 0x00;
+ else
+ blank_delay = 0x51;
+ else
+ if (pScrn->bitsPerPixel == 8)
+ blank_delay = 0x00;
+ else if (pScrn->bitsPerPixel == 16)
+ blank_delay = 0x02;
+ else
+ blank_delay = 0x04;
+
+ if (ps3v->Chipset == S3_ViRGE_VX)
+ new->CR6D = blank_delay;
+ else {
+ new->CR65 = (new->CR65 & ~0x38)
+ | (blank_delay & 0x07) << 3;
+ VGAOUT8(vgaCRIndex, 0x6d);
+ new->CR6D = VGAIN8(vgaCRReg);
+ }
+ }
+ /* S3_EARLY_SC was defaulted to 0 */
+ /* in 3.3.3 and never changed. */
+ /* Also, bit 1 is never set in 3.9Nm, */
+ /* so I left this out for 4.0. */
+ #if 0
+ if (mode->Private[0] & (1 << S3_EARLY_SC)) {
+ if (mode->Private[S3_EARLY_SC])
+ new->CR65 |= 2;
+ else
+ new->CR65 &= ~2;
+ }
+ #endif
+
+ VGAOUT8(vgaCRIndex, 0x68);
+ new->CR68 = VGAIN8(vgaCRReg);
+ new->CR69 = 0;
+
+ if (S3_ViRGE_MX_SERIES(ps3v->Chipset) && (ps3v->lcd_center)) {
+ new->SR54 = 0x10 ;
+ new->SR55 = 0x80 ;
+ new->SR56 = 0x10 ;
+ new->SR57 = 0x80 ;
+ } else {
+ new->SR54 = 0x1f ;
+ new->SR55 = 0x9f ;
+ new->SR56 = 0x1f ;
+ new->SR57 = 0xff ;
+ }
+
+ pScrn->vtSema = TRUE;
+
+ /* Do it! Write the mode registers */
+ /* to hardware, start STREAMS if */
+ /* needed, etc. */
+ S3VWriteMode( pScrn, vganew, new );
+
+ return TRUE;
+}
+
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode. It should also unmap the video memory, and free
+ * any per-generation data allocated by the driver. It should finish
+ * by unwrapping and calling the saved CloseScreen function.
+ */
+
+/* Mandatory */
+static Bool
+S3VCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ S3VPtr ps3v = S3VPTR(pScrn);
+ vgaRegPtr vgaSavePtr = &hwp->SavedReg;
+ S3VRegPtr S3VSavePtr = &ps3v->SavedReg;
+
+ /* Like S3VRestore, but uses passed */
+ /* mode registers. */
+ if (pScrn->vtSema) {
+ S3VWriteMode(pScrn, vgaSavePtr, S3VSavePtr);
+ vgaHWLock(hwp);
+ S3VUnmapMem(pScrn);
+ }
+ if (ps3v->AccelInfoRec)
+ XAADestroyInfoRec(ps3v->AccelInfoRec);
+ if (ps3v->DGAModes)
+ xfree(ps3v->DGAModes);
+
+ pScrn->vtSema = FALSE;
+
+ pScreen->CloseScreen = ps3v->CloseScreen;
+
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+
+
+
+/* Do screen blanking */
+
+/* Mandatory */
+static Bool
+S3VSaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+ return vgaHWSaveScreen(pScreen, unblank);
+}
+
+
+
+
+
+/* This function inits the STREAMS processor variables.
+ * This has essentially been taken from the accel/s3_virge code and the databook.
+ */
+static void
+S3VInitSTREAMS(ScrnInfoPtr pScrn, unsigned int *streams, DisplayModePtr mode)
+{
+
+ if ( pScrn->bitsPerPixel == 24 ) {
+ /* data format 8.8.8 (24 bpp) */
+ streams[0] = 0x06000000;
+ }
+ else if (pScrn->bitsPerPixel == 32) {
+ /* one more bit for X.8.8.8, 32 bpp */
+ streams[0] = 0x07000000;
+ }
+ /* NO chroma keying... */
+ streams[1] = 0x0;
+ /* Secondary stream format KRGB-16 */
+ /* data book suggestion... */
+ streams[2] = 0x03000000;
+
+ streams[3] = 0x0;
+
+ streams[4] = 0x0;
+ /* use 0x01000000 for primary over second. */
+ /* use 0x0 for second over prim. */
+ streams[5] = 0x01000000;
+
+ streams[6] = 0x0;
+
+ streams[7] = 0x0;
+ /* Stride is 3 bytes for 24 bpp mode and */
+ /* 4 bytes for 32 bpp. */
+ if ( pScrn->bitsPerPixel == 24 ) {
+ streams[8] =
+ pScrn->displayWidth * 3;
+ }
+ else {
+ streams[8] =
+ pScrn->displayWidth * 4;
+ }
+ /* Choose fbaddr0 as stream source. */
+ streams[9] = 0x0;
+ streams[10] = 0x0;
+ streams[11] = 0x0;
+ streams[12] = 0x1;
+
+ /* Set primary stream on top of secondary */
+ /* stream. */
+ streams[13] = 0xc0000000;
+ /* Vertical scale factor. */
+ streams[14] = 0x0;
+
+ streams[15] = 0x0;
+ /* Vertical accum. initial value. */
+ streams[16] = 0x0;
+ /* X and Y start coords + 1. */
+ streams[18] = 0x00010001;
+
+ /* Specify window Width -1 and Height of */
+ /* stream. */
+ streams[19] =
+ (mode->HDisplay - 1) << 16 |
+ (mode->VDisplay);
+
+ /* Book says 0x07ff07ff. */
+ streams[20] = 0x07ff07ff;
+
+ streams[21] = 0x00010001;
+
+}
+
+
+
+
+/* Used to adjust start address in frame buffer. We use the new
+ * CR69 reg for this purpose instead of the older CR31/CR51 combo.
+ * If STREAMS is running, we program the STREAMS start addr. registers.
+ */
+
+void
+S3VAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ S3VPtr ps3v = S3VPTR(pScrn);
+/* void *s3vMmioMem = ps3v->MapBase; */
+ int Base;
+ int vgaCRIndex, vgaCRReg, vgaIOBase;
+ vgaIOBase = hwp->IOBase;
+ vgaCRIndex = vgaIOBase + 4;
+ vgaCRReg = vgaIOBase + 5;
+
+ if(ps3v->ShowCache && y)
+ y += pScrn->virtualY - 1;
+
+ if( (ps3v->STREAMSRunning == FALSE) ||
+ S3_ViRGE_GX2_SERIES(ps3v->Chipset) || S3_ViRGE_MX_SERIES(ps3v->Chipset)) {
+ Base = ((y * pScrn->displayWidth + x)
+ * (pScrn->bitsPerPixel / 8)) >> 2;
+ if (pScrn->bitsPerPixel == 24)
+ Base = Base+2 - (Base+2) % 3;
+
+ /* Now program the start address registers */
+ VGAOUT16(vgaCRIndex, (Base & 0x00FF00) | 0x0C);
+ VGAOUT16(vgaCRIndex, ((Base & 0x00FF) << 8) | 0x0D);
+ VGAOUT8(vgaCRIndex, 0x69);
+ VGAOUT8(vgaCRReg, (Base & 0x0F0000) >> 16);
+ }
+ else { /* Change start address for STREAMS case */
+ VerticalRetraceWait();
+ if(ps3v->Chipset == S3_ViRGE_VX)
+ OUTREG(PSTREAM_FBADDR0_REG,
+ ((y * pScrn->displayWidth + (x & ~7)) *
+ pScrn->bitsPerPixel / 8));
+ else
+ OUTREG(PSTREAM_FBADDR0_REG,
+ ((y * pScrn->displayWidth + (x & ~3)) *
+ pScrn->bitsPerPixel / 8));
+ }
+
+ return;
+}
+
+
+
+
+/* Usually mandatory */
+Bool
+S3VSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return S3VModeInit(xf86Screens[scrnIndex], mode);
+}
+
+
+
+void S3VLoadPalette(
+ ScrnInfoPtr pScrn,
+ int numColors,
+ int *indicies,
+ LOCO *colors,
+ VisualPtr pVisual
+){
+ S3VPtr ps3v = S3VPTR(pScrn);
+ int i, index;
+
+ for(i = 0; i < numColors; i++) {
+ index = indicies[i];
+ VGAOUT8(0x3c8, index);
+ VGAOUT8(0x3c9, colors[index].red);
+ VGAOUT8(0x3c9, colors[index].green);
+ VGAOUT8(0x3c9, colors[index].blue);
+ }
+}
+
+
+/*
+ * Functions to support getting a ViRGE card into MMIO mode if it fails to
+ * default to MMIO enabled.
+ */
+
+void
+S3VEnableMmio(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp;
+ S3VPtr ps3v;
+ int vgaCRIndex, vgaCRReg;
+ unsigned char val;
+
+ PVERB5(" S3VEnableMmio\n");
+
+ hwp = VGAHWPTR(pScrn);
+ ps3v = S3VPTR(pScrn);
+ /*
+ * enable chipset (seen on uninitialized secondary cards)
+ * might not be needed once we use the VGA softbooter
+ * (EE 05/04/99)
+ */
+ vgaHWSetStdFuncs(hwp);
+
+ val = inb(0x3C3); /*@@@EE*/
+ outb(0x3C3,val | 0x01);
+ /*
+ * set CR registers to color mode
+ * in mono mode extended CR registers
+ * are not accessible. (EE 05/04/99)
+ */
+ val = inb(VGA_MISC_OUT_R); /*@@@EE*/
+ outb(VGA_MISC_OUT_W,val | 0x01);
+ vgaHWGetIOBase(hwp); /* Get VGA I/O base */
+ vgaCRIndex = hwp->IOBase + 4;
+ vgaCRReg = hwp->IOBase + 5;
+#if 1
+ /*
+ * set linear base register to the PCI register values
+ * some DX chipsets don´t seem to do it automatically
+ * (EE 06/03/99)
+ */
+ outb(vgaCRIndex, 0x59); /*@@@EE*/
+ outb(vgaCRReg, ps3v->PciInfo->memBase[0] >> 24);
+ outb(vgaCRIndex, 0x5A);
+ outb(vgaCRReg, ps3v->PciInfo->memBase[0] >> 16);
+ outb(vgaCRIndex, 0x53);
+#endif
+ /* Save register for restore */
+ ps3v->EnableMmioCR53 = inb(vgaCRReg);
+ /* Enable new MMIO, if TRIO mmio is already */
+ /* enabled, then it stays enabled. */
+ outb(vgaCRReg, (ps3v->EnableMmioCR53 | 0x08) );
+ outb(VGA_MISC_OUT_W,val);
+ return;
+}
+
+
+
+void
+S3VDisableMmio(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp;
+ S3VPtr ps3v;
+ int vgaCRIndex, vgaCRReg;
+
+ PVERB5(" S3VDisableMmio\n");
+
+ hwp = VGAHWPTR(pScrn);
+
+ ps3v = S3VPTR(pScrn);
+
+ vgaCRIndex = hwp->IOBase + 4;
+ vgaCRReg = hwp->IOBase + 5;
+ outb(vgaCRIndex, 0x53);
+ /* Restore register's original state */
+ outb(vgaCRReg,ps3v->EnableMmioCR53 );
+ return;
+}
+
+
+
+/* This function is used to debug, it prints out the contents of s3 regs */
+
+static void
+S3VPrintRegs(ScrnInfoPtr pScrn)
+{
+ unsigned char tmp1, tmp2;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ S3VPtr ps3v = S3VPTR(pScrn);
+ int vgaCRIndex, vgaCRReg, vgaIOBase, vgaIR;
+ vgaIOBase = hwp->IOBase;
+ vgaCRIndex = vgaIOBase + 4;
+ vgaCRReg = vgaIOBase + 5;
+ vgaIR = vgaIOBase + 0xa;
+
+/* All registers */
+/* New formatted registers, matches s3rc (sort of) */
+ ErrorF("Misc Out[3CC]\n ");
+ ErrorF("%02x\n",VGAIN8(0x3cc));
+
+ ErrorF("\nCR[00-2f]\n ");
+ for(tmp1=0x0;tmp1<=0x2f;tmp1++){
+ VGAOUT8(vgaCRIndex, tmp1);
+ ErrorF("%02x ",VGAIN8(vgaCRReg));
+ if((tmp1 & 0x3) == 0x3) ErrorF(" ");
+ if((tmp1 & 0xf) == 0xf) ErrorF("\n ");
+ }
+
+ ErrorF("\nSR[00-27]\n ");
+ for(tmp1=0x0;tmp1<=0x27;tmp1++){
+ VGAOUT8(0x3c4, tmp1);
+ ErrorF("%02x ",VGAIN8(0x3c5));
+ if((tmp1 & 0x3) == 0x3) ErrorF(" ");
+ if((tmp1 & 0xf) == 0xf) ErrorF("\n ");
+ }
+ ErrorF("\n"); /* odd hex number of digits... */
+
+ ErrorF("\nGr Cont GR[00-0f]\n ");
+ for(tmp1=0x0;tmp1<=0x0f;tmp1++){
+ VGAOUT8(0x3ce, tmp1);
+ ErrorF("%02x ",VGAIN8(0x3cf));
+ if((tmp1 & 0x3) == 0x3) ErrorF(" ");
+ if((tmp1 & 0xf) == 0xf) ErrorF("\n ");
+ }
+
+ ErrorF("\nAtt Cont AR[00-1f]\n ");
+ VGAIN8(vgaIR); /* preset AR flip-flop by reading 3DA, ignore return value */
+ tmp2=VGAIN8(0x3c0) & 0x20;
+ for(tmp1=0x0;tmp1<=0x1f;tmp1++){
+ VGAIN8(vgaIR); /* preset AR flip-flop by reading 3DA, ignore return value */
+ VGAOUT8(0x3c0, (tmp1 & ~0x20) | tmp2);
+ ErrorF("%02x ",VGAIN8(0x3c1));
+ if((tmp1 & 0x3) == 0x3) ErrorF(" ");
+ if((tmp1 & 0xf) == 0xf) ErrorF("\n ");
+ }
+
+ ErrorF("\nCR[30-6f]\n ");
+ for(tmp1=0x30;tmp1<=0x6f;tmp1++){
+ VGAOUT8(vgaCRIndex, tmp1);
+ ErrorF("%02x ",VGAIN8(vgaCRReg));
+ if((tmp1 & 0x3) == 0x3) ErrorF(" ");
+ if((tmp1 & 0xf) == 0xf) ErrorF("\n ");
+ }
+
+ ErrorF("\n\n");
+}
+
+/* this is just a debugger hook */
+/*
+void print_subsys_stat(void *s3vMmioMem);
+void
+print_subsys_stat(void *s3vMmioMem)
+{
+ ErrorF("IN_SUBSYS_STAT() = %x\n", IN_SUBSYS_STAT());
+ return;
+}
+*/
+
+/*
+ * S3VDisplayPowerManagementSet --
+ *
+ * Sets VESA Display Power Management Signaling (DPMS) Mode.
+ */
+#ifdef DPMSExtension
+static void
+S3VDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
+ int flags)
+{
+ S3VPtr ps3v;
+ unsigned char sr8 = 0x0, srd = 0x0;
+
+ ps3v = S3VPTR(pScrn);
+
+ /* unlock extended sequence registers */
+
+ VGAOUT8(0x3c4, 0x08);
+ sr8 = VGAIN8(0x3c5);
+ sr8 |= 0x6;
+ VGAOUT8(0x3c5, sr8);
+
+ /* load SRD */
+ VGAOUT8(0x3c4, 0x0d);
+ srd = VGAIN8(0x3c5);
+
+ srd &= 0x03; /* clear the sync control bits of srd */
+
+ switch (PowerManagementMode) {
+ case DPMSModeOn:
+ /* Screen: On; HSync: On, VSync: On */
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off; HSync: Off, VSync: On */
+ srd |= 0x10;
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off; HSync: On, VSync: Off */
+ srd |= 0x40;
+ break;
+ case DPMSModeOff:
+ /* Screen: Off; HSync: Off, VSync: Off */
+ srd |= 0x50;
+ break;
+ default:
+ ErrorF("Invalid PowerManagementMode %d passed to S3VDisplayPowerManagementSet\n", PowerManagementMode);
+ break;
+ }
+
+ VGAOUT8(0x3c4, 0x0d);
+ VGAOUT8(0x3c5, srd);
+
+ return;
+}
+#endif /* DPMSExtension */
+
+static unsigned int
+S3Vddc1Read(ScrnInfoPtr pScrn)
+{
+ register vgaHWPtr hwp = VGAHWPTR(pScrn);
+ register CARD32 tmp;
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ while (hwp->readST01(hwp)&0x8) {};
+ while (!(hwp->readST01(hwp)&0x8)) {};
+
+ tmp = (INREG(DDC_REG));
+ return ((unsigned int) (tmp & 0x08));
+}
+
+static void
+S3Vddc1(int scrnIndex)
+{
+ S3VPtr ps3v = S3VPTR(xf86Screens[scrnIndex]);
+ CARD32 tmp;
+
+ /* initialize chipset */
+ tmp = INREG(DDC_REG);
+ OUTREG(DDC_REG,(tmp | 0x12));
+
+ xf86PrintEDID(xf86DoEDID_DDC1(scrnIndex,vgaHWddc1SetSpeed,S3Vddc1Read));
+
+ /* undo initialization */
+ OUTREG(DDC_REG,(tmp));
+}
+/*EOF*/
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_hwcurs.c b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_hwcurs.c
new file mode 100644
index 000000000..6f0ce0585
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_hwcurs.c
@@ -0,0 +1,233 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_hwcurs.c,v 1.3 1999/06/12 15:37:07 dawes Exp $ */
+
+/*
+Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+XFREE86 PROJECT 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 XFree86 Project 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 XFree86 Project.
+*/
+
+
+/*
+ * s3v_hwcurs.c
+ * HW Cursor support for 4.0 design level
+ *
+ * S3 ViRGE driver
+ *
+ *
+ */
+
+
+#include "s3v.h"
+
+/* protos */
+
+static void S3VLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
+static void S3VShowCursor(ScrnInfoPtr pScrn);
+static void S3VHideCursor(ScrnInfoPtr pScrn);
+static void S3VSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
+static void S3VSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
+
+
+/*
+ * Read/write to the DAC via MMIO
+ */
+
+#define inCRReg(reg) (VGAHWPTR(pScrn))->readCrtc( VGAHWPTR(pScrn), reg )
+#define outCRReg(reg, val) (VGAHWPTR(pScrn))->writeCrtc( VGAHWPTR(pScrn), reg, val )
+
+
+
+/****
+ *** HW Cursor
+ */
+static void
+S3VLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+{
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ /*PVERB5(" S3VLoadCursorImage\n");*/
+
+ /* Load storage location. */
+ outCRReg( HWCURSOR_ADDR_LOW_CR4D, 0xff & (ps3v->FBCursorOffset/1024));
+ outCRReg( HWCURSOR_ADDR_HIGH_CR4C, (0x0f00 & (ps3v->FBCursorOffset/1024)) >> 8);
+
+ /* Copy cursor image to framebuffer storage */
+ memcpy( (ps3v->FBBase + ps3v->FBCursorOffset), src, 1024);
+
+}
+
+
+static void
+S3VShowCursor(ScrnInfoPtr pScrn)
+{
+ char tmp;
+
+ tmp = inCRReg(HWCURSOR_MODE_CR45);
+ /* Enable cursor */
+ outCRReg(HWCURSOR_MODE_CR45, tmp | 1 );
+}
+
+
+static void
+S3VHideCursor(ScrnInfoPtr pScrn)
+{
+ char tmp;
+
+ tmp = inCRReg(HWCURSOR_MODE_CR45);
+ /* Disable cursor */
+ outCRReg(HWCURSOR_MODE_CR45, tmp & ~1 );
+}
+
+
+static void
+S3VSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ unsigned char xoff = 0, yoff = 0;
+
+ /*
+ if (!xf86VTSema)
+ return;
+ */
+
+ /*
+ x -= s3vHotX;
+ y -= s3vHotY;
+ */
+
+ /*
+ * Make these even when used. There is a bug/feature on at least
+ * some chipsets that causes a "shadow" of the cursor in interlaced
+ * mode. Making this even seems to have no visible effect, so just
+ * do it for the generic case.
+ * note - xoff & yoff are used for displaying partial cursors on screen
+ * edges.
+ */
+
+ if (x < 0) {
+ xoff = ((-x) & 0xFE);
+ x = 0;
+ }
+
+ if (y < 0) {
+ yoff = ((-y) & 0xFE);
+ y = 0;
+ }
+
+ /* This is the recomended order to move the cursor */
+
+ outCRReg( 0x46, (x & 0xff00)>>8 );
+ outCRReg( 0x47, (x & 0xff) );
+ outCRReg( 0x49, (y & 0xff) );
+ outCRReg( 0x4e, xoff );
+ outCRReg( 0x4f, yoff );
+ outCRReg( 0x48, (y & 0xff00)>>8 );
+}
+
+
+static void
+S3VSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ S3VPtr ps3v = S3VPTR(pScrn);
+
+ /*PVERB5(" S3VSetCursorColors\n");*/
+
+ switch( pScrn->bitsPerPixel) {
+ case 8:
+ /* Dup color indexes in low, mid, & high bytes */
+ fg &= 0x000000ff;
+ fg |= (fg << 16) | (fg << 8);
+ bg &= 0x000000ff;
+ bg |= (bg << 16) | (bg << 8);
+ break;
+ case 16:
+ /* adjust colors to 16 bits */
+ if (pScrn->weight.green == 5 && ps3v->Chipset != S3_ViRGE_VX) {
+ fg = ((fg & 0xf80000) >> 9) |
+ ((fg & 0xf800) >> 6) |
+ ((fg & 0xf8) >> 3);
+ bg = ((bg & 0xf80000) >> 9) |
+ ((bg & 0xf800) >> 6) |
+ ((bg & 0xf8) >> 3);
+
+ } else {
+ fg = ((fg & 0xf80000) >> 8) |
+ ((fg & 0xfc00) >> 5) |
+ ((fg & 0xf8) >> 3);
+ bg = ((bg & 0xf80000) >> 8) |
+ ((bg & 0xfc00) >> 5) |
+ ((bg & 0xf8) >> 3);
+ }
+
+ break;
+
+ case 24:
+ case 32:
+ /* Do it straight, full 24 bit color. */
+ break;
+ }
+
+ /* Reset the cursor color stack pointer */
+ inCRReg( 0x45 );
+ /* Write low, mid, high bytes - foreground */
+ outCRReg( 0x4a, (fg & 0x000000FF));
+ outCRReg( 0x4a, (fg & 0x0000FF00) >> 8);
+ outCRReg( 0x4a, (fg & 0x00FF0000) >> 16);
+ /* Reset the cursor color stack pointer */
+ inCRReg( 0x45 );
+ /* Write low, mid, high bytes - background */
+ outCRReg( 0x4b, (bg & 0x000000FF));
+ outCRReg( 0x4b, (bg & 0x0000FF00) >> 8);
+ outCRReg( 0x4b, (bg & 0x00FF0000) >> 16);
+}
+
+
+Bool
+S3VHWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ S3VPtr ps3v = S3VPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+ PVERB5(" S3VHWCursorInit\n");
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ ps3v->CursorInfoRec = infoPtr;
+
+ infoPtr->MaxWidth = 64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->Flags = HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 |
+ HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST;
+
+ infoPtr->SetCursorColors = S3VSetCursorColors;
+ infoPtr->SetCursorPosition = S3VSetCursorPosition;
+ infoPtr->LoadCursorImage = S3VLoadCursorImage;
+ infoPtr->HideCursor = S3VHideCursor;
+ infoPtr->ShowCursor = S3VShowCursor;
+ infoPtr->UseHWCursor = NULL;
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
+
+/*EOF*/
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_i2c.c b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_i2c.c
new file mode 100644
index 000000000..f02185ee6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_i2c.c
@@ -0,0 +1,67 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_i2c.c,v 1.1 1999/08/21 13:48:39 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+#include "vgaHW.h"
+
+#include "s3v.h"
+
+static void
+s3v_I2CPutBits(I2CBusPtr b, int clock, int data)
+{
+ S3VPtr ps3v = S3VPTR(xf86Screens[b->scrnIndex]);
+ unsigned int reg = 0x10;
+
+ if(clock) reg |= 0x1;
+ if(data) reg |= 0x2;
+
+ OUTREG(DDC_REG,reg);
+ /*ErrorF("s3v_I2CPutBits: %d %d\n", clock, data); */
+}
+
+static void
+s3v_I2CGetBits(I2CBusPtr b, int *clock, int *data)
+{
+ S3VPtr ps3v = S3VPTR(xf86Screens[b->scrnIndex]);
+ unsigned int reg = 0x13;
+
+ OUTREG(DDC_REG,reg);
+ reg = (INREG(DDC_REG));
+
+ *clock = reg & 0x4;
+ *data = reg & 0x8;
+
+ /*ErrorF("s3v_I2CGetBits: %d %d\n", *clock, *data);*/
+}
+
+Bool
+S3V_I2CInit(ScrnInfoPtr pScrn)
+{
+ S3VPtr ps3v = S3VPTR(pScrn);
+ I2CBusPtr I2CPtr;
+
+
+ I2CPtr = xf86CreateI2CBusRec();
+ if(!I2CPtr) return FALSE;
+
+ ps3v->I2C = I2CPtr;
+
+ I2CPtr->BusName = "I2C bus";
+ I2CPtr->scrnIndex = pScrn->scrnIndex;
+ I2CPtr->I2CPutBits = s3v_I2CPutBits;
+ I2CPtr->I2CGetBits = s3v_I2CGetBits;
+
+ if (!xf86I2CBusInit(I2CPtr))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_macros.h b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_macros.h
new file mode 100644
index 000000000..8512f4480
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_macros.h
@@ -0,0 +1,119 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_macros.h,v 1.8 1999/08/21 13:48:40 dawes Exp $ */
+
+/*
+Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+XFREE86 PROJECT 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 XFree86 Project 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 XFree86 Project.
+*/
+
+#ifndef _S3V_MACROS_H
+#define _S3V_MACROS_H
+
+/* use these macros and INREG/OUTREG to access the extended registers
+ of s3 virge -- add any others you need here */
+
+/* miscellaneous registers */
+#define SUBSYS_STAT_REG 0x8504
+
+/* memory port controller registers */
+#define FIFO_CONTROL_REG 0x8200
+#define MIU_CONTROL_REG 0x8204
+#define STREAMS_TIMEOUT_REG 0x8208
+#define MISC_TIMEOUT_REG 0x820c
+
+/* Cursor Registers */
+#define HWCURSOR_MODE_CR45 0x45
+#define HWCURSOR_ADDR_LOW_CR4D 0x4d
+#define HWCURSOR_ADDR_HIGH_CR4C 0x4c
+
+/* streams registers */
+#define PSTREAM_CONTROL_REG 0x8180
+#define COL_CHROMA_KEY_CONTROL_REG 0x8184
+#define SSTREAM_CONTROL_REG 0x8190
+#define CHROMA_KEY_UPPER_BOUND_REG 0x8194
+#define SSTREAM_STRETCH_REG 0x8198
+#define BLEND_CONTROL_REG 0x81A0
+#define PSTREAM_FBADDR0_REG 0x81C0
+#define PSTREAM_FBADDR1_REG 0x81C4
+#define PSTREAM_STRIDE_REG 0x81C8
+#define DOUBLE_BUFFER_REG 0x81CC
+#define SSTREAM_FBADDR0_REG 0x81D0
+#define SSTREAM_FBADDR1_REG 0x81D4
+#define SSTREAM_STRIDE_REG 0x81D8
+#define OPAQUE_OVERLAY_CONTROL_REG 0x81DC
+#define K1_VSCALE_REG 0x81E0
+#define K2_VSCALE_REG 0x81E4
+#define DDA_VERT_REG 0x81E8
+#define STREAMS_FIFO_REG 0x81EC
+#define PSTREAM_START_REG 0x81F0
+#define PSTREAM_WINDOW_SIZE_REG 0x81F4
+#define SSTREAM_START_REG 0x81F8
+#define SSTREAM_WINDOW_SIZE_REG 0x81FC
+
+/* image write stuff */
+#define SRC_BASE 0xA4D4
+#define DEST_BASE 0xA4D8
+#define CLIP_L_R 0xA4DC
+#define CLIP_T_B 0xA4E0
+#define DEST_SRC_STR 0xA4E4
+#define MONO_PAT_0 0xA4E8
+#define MONO_PAT_1 0xA4EC
+#define PAT_BG_CLR 0xA4F0
+#define PAT_FG_CLR 0xA4F4
+#define SRC_BG_CLR 0xA4F8
+#define SRC_FG_CLR 0xA4FC
+#define CMD_SET 0xA500
+#define RWIDTH_HEIGHT 0xA504
+#define RSRC_XY 0xA508
+#define RDEST_XY 0xA50C
+
+/* Local Periperal Bus Registers */
+
+#define DDC_REG 0xFF20
+#define BLT_BUG 0x00000001
+#define MONO_TRANS_BUG 0x00000002
+
+
+
+#define WAITFIFO(n) if(ps3v->NoPCIRetry) \
+ while(((INREG(SUBSYS_STAT_REG) >> 8) & 0x1f) < n){}
+
+#define WAITIDLE() while((INREG(SUBSYS_STAT_REG) & 0x3f00) < 0x3000){}
+
+#define CHECK_DEST_BASE(y,h)\
+ if((y < ps3v->DestBaseY) || ((y + h) > (ps3v->DestBaseY + 2048))) {\
+ ps3v->DestBaseY = ((y + h) <= 2048) ? 0 : y;\
+ WAITFIFO(1);\
+ OUTREG(DEST_BASE, ps3v->DestBaseY * ps3v->Stride);\
+ }\
+ y -= ps3v->DestBaseY
+
+#define CHECK_SRC_BASE(y,h)\
+ if((y < ps3v->SrcBaseY) || ((y + h) > (ps3v->SrcBaseY + 2048))) {\
+ ps3v->SrcBaseY = ((y + h) <= 2048) ? 0 : y;\
+ WAITFIFO(1);\
+ OUTREG(SRC_BASE, ps3v->SrcBaseY * ps3v->Stride);\
+ }\
+ y -= ps3v->SrcBaseY
+
+
+#endif /* _S3V_MACROS_H */
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_rop.h b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_rop.h
new file mode 100644
index 000000000..11e0bd3a9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_rop.h
@@ -0,0 +1,207 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_rop.h,v 1.3 1999/03/14 03:22:04 dawes Exp $ */
+
+/*
+Copyright (C) 1994-1998 The XFree86 Project, Inc. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+XFREE86 PROJECT 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 XFree86 Project 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 XFree86 Project.
+*/
+
+/* This file contains the data structures which map the X ROPs to the
+ * ViRGE ROPs. It also contains other mappings which are used when supporting
+ * planemasks and transparency.
+ *
+ * Created by Sebastien Marineau, 29/03/97.
+ * This file should be included only from s3v_accel.c to avoid
+ * duplicate symbols.
+ *
+ */
+
+#include "regs3v.h"
+
+static int s3vAlu[16] =
+{
+ ROP_0, /* GXclear */
+ ROP_DSa, /* GXand */
+ ROP_SDna, /* GXandReverse */
+ ROP_S, /* GXcopy */
+ ROP_DSna, /* GXandInverted */
+ ROP_D, /* GXnoop */
+ ROP_DSx, /* GXxor */
+ ROP_DSo, /* GXor */
+ ROP_DSon, /* GXnor */
+ ROP_DSxn, /* GXequiv */
+ ROP_Dn, /* GXinvert*/
+ ROP_SDno, /* GXorReverse */
+ ROP_Sn, /* GXcopyInverted */
+ ROP_DSno, /* GXorInverted */
+ ROP_DSan, /* GXnand */
+ ROP_1 /* GXset */
+};
+
+/* S -> P, for solid and pattern fills. */
+static int s3vAlu_sp[16]=
+{
+ ROP_0,
+ ROP_DPa,
+ ROP_PDna,
+ ROP_P,
+ ROP_DPna,
+ ROP_D,
+ ROP_DPx,
+ ROP_DPo,
+ ROP_DPon,
+ ROP_DPxn,
+ ROP_Dn,
+ ROP_PDno,
+ ROP_Pn,
+ ROP_DPno,
+ ROP_DPan,
+ ROP_1
+};
+
+/* ROP -> (ROP & P) | (D & ~P) */
+/* These are used to support a planemask for S->D ops */
+static int s3vAlu_pat[16] =
+{
+ ROP_0_PaDPnao,
+ ROP_DSa_PaDPnao,
+ ROP_SDna_PaDPnao,
+ ROP_S_PaDPnao,
+ ROP_DSna_PaDPnao,
+ ROP_D_PaDPnao,
+ ROP_DSx_PaDPnao,
+ ROP_DSo_PaDPnao,
+ ROP_DSon_PaDPnao,
+ ROP_DSxn_PaDPnao,
+ ROP_Dn_PaDPnao,
+ ROP_SDno_PaDPnao,
+ ROP_Sn_PaDPnao,
+ ROP_DSno_PaDPnao,
+ ROP_DSan_PaDPnao,
+ ROP_1_PaDPnao
+};
+
+/* ROP_sp -> (ROP_sp & S) | (D & ~S) */
+/* This is used for our transparent mono pattern fills to support trans/plane*/
+static int s3vAlu_MonoTrans[16] =
+{
+ ROP_0_SaDSnao,
+ ROP_DPa_SaDSnao,
+ ROP_PDna_SaDSnao,
+ ROP_P_SaDSnao,
+ ROP_DPna_SaDSnao,
+ ROP_D_SaDSnao,
+ ROP_DPx_SaDSnao,
+ ROP_DPo_SaDSnao,
+ ROP_DPon_SaDSnao,
+ ROP_DPxn_SaDSnao,
+ ROP_Dn_SaDSnao,
+ ROP_PDno_SaDSnao,
+ ROP_Pn_SaDSnao,
+ ROP_DPno_SaDSnao,
+ ROP_DPan_SaDSnao,
+ ROP_1_SaDSnao
+};
+
+
+
+/* This function was taken from accel/s3v.h. It adjusts the width
+ * of transfers for mono images to works around some bugs.
+ */
+
+static __inline__ int S3VCheckLSPN(S3VPtr ps3v, int w, int dir)
+{
+ int lspn = (w * ps3v->Bpp) & 63; /* scanline width in bytes modulo 64*/
+
+ if (ps3v->Bpp == 1) {
+ if (lspn <= 8*1)
+ w += 16;
+ else if (lspn <= 16*1)
+ w += 8;
+ } else if (ps3v->Bpp == 2) {
+ if (lspn <= 4*2)
+ w += 8;
+ else if (lspn <= 8*2)
+ w += 4;
+ } else { /* ps3v->Bpp == 3 */
+ if (lspn <= 3*3)
+ w += 6;
+ else if (lspn <= 6*3)
+ w += 3;
+ }
+ if (dir && w >= ps3v->bltbug_width1 && w <= ps3v->bltbug_width2) {
+ w = ps3v->bltbug_width2 + 1;
+ }
+
+ return w;
+}
+
+/* And this adjusts color bitblts widths to work around GE bugs */
+
+static __inline__ int S3VCheckBltWidth(S3VPtr ps3v, int w)
+{
+ if (w >= ps3v->bltbug_width1 && w <= ps3v->bltbug_width2) {
+ w = ps3v->bltbug_width2 + 1;
+ }
+ return w;
+}
+
+/* This next function determines if the Source operand is present in the
+ * given ROP. The rule is that both the lower and upper nibble of the rop
+ * have to be neither 0x00, 0x05, 0x0a or 0x0f. If a CPU-Screen blit is done
+ * with a ROP which does not contain the source, the virge will hang when
+ * data is written to the image transfer area.
+ */
+
+static __inline__ Bool S3VROPHasSrc(int shifted_rop)
+{
+ int rop = (shifted_rop & (0xff << 17)) >> 17;
+
+ if ((((rop & 0x0f) == 0x0a) | ((rop & 0x0f) == 0x0f)
+ | ((rop & 0x0f) == 0x05) | ((rop & 0x0f) == 0x00)) &
+ (((rop & 0xf0) == 0xa0) | ((rop & 0xf0) == 0xf0)
+ | ((rop & 0xf0) == 0x50) | ((rop & 0xf0) == 0x00)))
+ return FALSE;
+ else
+ return TRUE;
+}
+
+/* This next function determines if the Destination operand is present in the
+ * given ROP. The rule is that both the lower and upper nibble of the rop
+ * have to be neither 0x00, 0x03, 0x0c or 0x0f.
+ */
+
+static __inline__ Bool S3VROPHasDst(int shifted_rop)
+{
+ int rop = (shifted_rop & (0xff << 17)) >> 17;
+
+ if ((((rop & 0x0f) == 0x0c) | ((rop & 0x0f) == 0x0f)
+ | ((rop & 0x0f) == 0x03) | ((rop & 0x0f) == 0x00)) &
+ (((rop & 0xf0) == 0xc0) | ((rop & 0xf0) == 0xf0)
+ | ((rop & 0xf0) == 0x30) | ((rop & 0xf0) == 0x00)))
+ return FALSE;
+ else
+ return TRUE;
+}
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3virge.cpp b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3virge.cpp
new file mode 100644
index 000000000..44ba44e9f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3virge.cpp
@@ -0,0 +1,186 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3virge.cpp,v 1.4 1999/08/22 13:04:27 dawes Exp $
+.TH s3virge __drivermansuffix__ "Version 3.9.16" "XFree86"
+.SH NAME
+s3virge \- S3 ViRGE video driver
+.SH SYNOPSIS
+.B "Section ""Device"""
+.br
+.BI " Identifier """ devname """"
+.br
+.B " Driver ""s3virge"""
+.br
+\ \ ...
+.br
+\ \ [
+.B "Option"
+"optionname" ["optionvalue"]]
+.br
+.B EndSection
+.SH DESCRIPTION
+.B s3virge
+is an XFree86 driver for S3 based video cards. The driver is fully
+accelerated, and provides support for the following framebuffer depths:
+8, 15, 16, and 24. All
+visual types are supported for depth 8, and TrueColor
+visuals are supported for the other depths.
+.SH SUPPORTED HARDWARE
+The
+.B s3virge
+driver supports PCI video cards based on the following S3 chips:
+.TP 12
+.B ViRGE
+86C325
+.TP 12
+.B ViRGE VX
+86C988
+.TP 12
+.B ViRGE DX
+86C375
+.TP 12
+.B ViRGE GX
+86C385
+.TP 12
+.B ViRGE GX2
+86C357
+.TP 12
+.B ViRGE MX
+86C260
+.TP 12
+.B ViRGE MX+
+86C280
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details. This section only covers configuration details specific to this
+driver.
+.PP
+The driver auto-detects the chipset type, but the following
+.B ChipSet
+names may optionally be specified in the config file
+.B """Device"""
+section, and will override the auto-detection:
+.PP
+.RS 4
+"virge", "86c325", "virge vx", "86c988", "virge dx", "86c375",
+"virge gx", "86c385", "virge gx2", "86c357", "virge mx", "86c260",
+"virge mx+", "86c280".
+.RE
+.PP
+The following Cursor
+.B Options
+are supported:
+.TP
+.BI "Option ""HWCursor"" """ boolean """
+Enable or disable the HW cursor. Default: on.
+.TP
+.BI "Option ""SWCursor"" """ boolean """
+Inverse of "HWCursor". Default: off.
+.PP
+The following video memory
+.B Options
+are supported:
+.TP
+.BI "Option ""slow_edodram"""
+Switch the standard ViRGE to 2-cycle edo mode. Try this
+if you encounter pixel corruption on the ViRGE. Using this option will
+cause a large decrease in performance. Default: off
+.TP
+.BI "Option ""fpm_vram"""
+Switch the ViRGE/VX to fast page mode vram mode. Default: off.
+.TP
+.BR "Option ""early_ras_precharge " | " late_ras_precharge"""
+adjust memory parameters. One
+of these will us the same settings as your video card defaults, and
+using neither in the config file does the same. Default: none.
+.TP
+.BI "Option ""set_mclk"" """ integer """
+sets the memory clock, where
+.I integer
+is in kHz, and
+.I integer
+<= 100000. Default: probe the memory clock value,
+and use it at server start.
+.PP
+The following acceleration and graphic engine
+.B Options
+are supported:
+.TP
+.B "Option ""NoAccel""
+Disable acceleration. Very useful for determining if the
+driver has problems with drawing and acceleration routines. This is the first
+option to try if your server runs but you see graphic corruption on the screen.
+Using it decreases performance, as it uses software emulation for drawing
+operations the video driver can accelerate with hardware.
+Default: acceleration is enabled.
+.TP
+.BR "Option ""fifo_aggressive " | " fifo_moderate " | " fifo_conservative"""
+alter the settings
+for the threshold at which the pixel FIFO takes over the internal
+memory bus to refill itself. The smaller this threshold, the better
+the acceleration performance of the card. You may try the fastest
+setting
+.RB ( "fifo_aggressive" )
+and move down if you encounter pixel corruption.
+The optimal setting will probably depend on dot-clock and on color
+depth. Note that specifying any of these options will also alter other
+memory settings which may increase performance, so trying
+.B "fifo_conservative"
+will in most cases be a slight benefit (this uses the chip defaults).
+If pixel corruption or transient streaking is observed during drawing
+operations then removing any fifo options is recommended. Default: none.
+
+.PP
+The following PCI bus
+.B Options
+are supported:
+.TP
+.BI "Option ""pci_burst"" """ boolean """
+will enable PCI burst mode. This should work on all but a
+few broken PCI chipsets, and will increase performance. Default: off.
+.TP
+.BI "Option ""pci_retry"" """ boolean """
+will allow the driver to rely on PCI Retry to program the
+ViRGE registers.
+.B "pci_burst"
+must be enabled for this to work.
+This will increase performance, especially for small fills/blits,
+because the driver does not have to poll the ViRGE before sending it
+commands to make sure it is ready. It should work on most
+recent PCI chipsets. Default: off.
+.PP
+The following ViRGE MX LCD
+.B Options
+are supported:
+.TP
+.BI "Option ""lcd_center""
+.TP
+.BI "Option ""set_lcdclk"" """ integer """
+allows setting the clock for a ViRGE MX LCD display.
+.I integer
+is in Hz. Default: use probed value.
+
+.PP
+The following additional
+.B Options
+are supported:
+.TP
+.BI "Option ""ShowCache"" """ boolean """
+Enable or disable viewing offscreen memory. Default: off.
+
+.SH SEE ALSO
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(1)
+
+.SH SUPPORT
+For assistance with this driver, or XFree86 in general, check the XFree86 web
+site at http://www.xfree86.org. A FAQ is available on the web site at
+http://www.xfree86.org/FAQ/. If you find a problem with XFree86 or have a
+question not answered in the FAQ please use our bug report form available on
+the web site or send mail to XFree86@XFree86.org. When reporting problems
+with the driver send as much detail as possible, including chipset type, a
+server output log, and operating system specifics.
+
+.SH AUTHORS
+Kevin Brosius,
+Matt Grossman,
+Harald Koenig,
+Sebastien Marineau,
+Mark Vojkovich.
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/sis/Imakefile
new file mode 100644
index 000000000..2b4b45271
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/Imakefile
@@ -0,0 +1,49 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/Imakefile,v 1.9 1999/08/14 10:49:54 dawes Exp $
+XCOMM
+XCOMM This is an Imakefile for the SIS driver.
+XCOMM
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = sis_driver.c sis_dac.c sis_accel.c sis_accel2.c
+OBJS = sis_driver.o sis_dac.o sis_accel.o sis_accel2.o
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/Xext \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \
+ -I$(XF86SRC)/xf1bpp -I$(XF86SRC)/xf4bpp \
+ -I$(XF86SRC)/xf24_32bpp \
+ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \
+ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
+ -I$(XF86SRC)/rac \
+ -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(XTOP)/include/extensions
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget(sis,$(OBJS))
+
+InstallObjectModule(sis,$(MODULEDIR),drivers)
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/sis)
+InstallDriverSDKNonExecFile(sis.h,$(DRIVERSDKDIR)/drivers/sis)
+InstallDriverSDKNonExecFile(sis_accel.c,$(DRIVERSDKDIR)/drivers/sis)
+InstallDriverSDKNonExecFile(sis_accel2.c,$(DRIVERSDKDIR)/drivers/sis)
+InstallDriverSDKNonExecFile(sis_dac.c,$(DRIVERSDKDIR)/drivers/sis)
+InstallDriverSDKNonExecFile(sis_driver.c,$(DRIVERSDKDIR)/drivers/sis)
+InstallDriverSDKNonExecFile(sis_driver.h,$(DRIVERSDKDIR)/drivers/sis)
+InstallDriverSDKNonExecFile(sis_regs.h,$(DRIVERSDKDIR)/drivers/sis)
+InstallDriverSDKNonExecFile(sis_regs2.h,$(DRIVERSDKDIR)/drivers/sis)
+
+InstallDriverSDKObjectModule(sis,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis.h
new file mode 100644
index 000000000..f854e33d3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright 1998,1999 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>
+ * David Thomas <davtom@dream.org.uk>.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis.h,v 1.8 1999/06/20 15:02:55 dawes Exp $ */
+
+#ifndef _SIS_H
+#define _SIS_H_
+
+#include "xf86Cursor.h"
+#include "xaa.h"
+#include "compiler.h"
+#include "vgaHW.h"
+
+typedef struct {
+ unsigned char sisRegs3x4[0x100];
+ unsigned char sisRegs3C4[0x100];
+ unsigned char sisRegs3C2[0x100];
+} SISRegRec, *SISRegPtr;
+
+#define SISPTR(p) ((SISPtr)((p)->driverPrivate))
+
+typedef struct {
+ ScrnInfoPtr pScrn;
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ EntityInfoPtr pEnt;
+ int Chipset;
+ int ChipRev;
+ int DACtype;
+ int HwBpp;
+ int BppShift;
+ CARD32 IOAddress;
+ CARD32 FbAddress;
+ unsigned char * IOBase;
+#ifdef __alpha__
+ unsigned char * IOBaseDense;
+#endif
+ unsigned char * FbBase;
+ CARD32 IOAccelAddress;
+ unsigned char * IOAccel;
+ long FbMapSize;
+ Bool NoAccel;
+ Bool HWCursor;
+ Bool UsePCIRetry;
+ Bool TurboQueue;
+ Bool ValidWidth;
+ Bool FastVram;
+ Bool ClipEnabled;
+ int MemClock;
+ int MinClock;
+ int MaxClock;
+ int Xdirection;
+ int Ydirection;
+ int sisPatternReg[4];
+ int ROPReg; /* for sis530 */
+ int CommandReg; /* for sis530 */
+ int DstX;
+ int DstY;
+ unsigned char * XAAScanlineColorExpandBuffers[2];
+ SISRegRec SavedReg;
+ SISRegRec ModeReg;
+ CARD32 AccelFlags;
+ xf86CursorInfoPtr CursorInfoRec;
+ XAAInfoRecPtr AccelInfoRec;
+ CloseScreenProcPtr CloseScreen;
+ unsigned int (*ddc1Read)(ScrnInfoPtr);
+} SISRec, *SISPtr;
+
+/* Prototypes */
+
+unsigned int SiSddc1Read(ScrnInfoPtr pScrn);
+void SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg);
+void SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg);
+Bool SiSInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+Bool SiSAccelInit(ScreenPtr pScreen);
+Bool SiS2AccelInit(ScreenPtr pScreen);
+int SiSMclk(void);
+int sisMemBandWidth(ScrnInfoPtr pScrn);
+Bool SiSHWCursorInit(ScreenPtr pScreen);
+
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c
new file mode 100644
index 000000000..f107599f1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c
@@ -0,0 +1,485 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel.c,v 1.12 1999/05/30 02:28:12 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "miline.h"
+
+#include "sis_regs.h"
+#include "sis.h"
+#include "xaarop.h"
+
+static void SiSSync(ScrnInfoPtr pScrn);
+
+static void SiSSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+
+static void SiSSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h);
+
+static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask,
+ int transparency_color);
+
+static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2,
+ int y2, int w, int h);
+
+static void SiSSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int fg, int bg,
+ int rop, unsigned int planemask);
+
+static void SiSSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+
+static void SiSSetupForScreenToScreenColorExpandFill (ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop, unsigned int planemask);
+
+static void SiSSubsequentScreenToScreenColorExpandFill( ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int offset );
+
+static void SiSSetClippingRectangle ( ScrnInfoPtr pScrn,
+ int left, int top, int right, int bottom);
+
+static void SiSDisableClipping (ScrnInfoPtr pScrn);
+
+static void SiSSetupForSolidLine(ScrnInfoPtr pScrn,
+ int color, int rop, unsigned int planemask);
+
+static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags);
+
+static void SiSSubsequentSolidHorVertLine(ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir);
+
+
+static void SiSInitializeAccelerator(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+}
+
+Bool SiSAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSiS = SISPTR(pScrn);
+ BoxRec AvailFBArea;
+ int offset;
+
+ pSiS->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ SiSInitializeAccelerator(pScrn);
+
+ infoPtr->Flags = PIXMAP_CACHE |
+ OFFSCREEN_PIXMAPS |
+ LINEAR_FRAMEBUFFER;
+
+ infoPtr->Sync = SiSSync;
+ /* Clipping and lines only works on 5597 and 6326
+ for 1024, 2048, 4096 logical width */
+ if (pSiS->ValidWidth) {
+ infoPtr->SetClippingRectangle = SiSSetClippingRectangle;
+ infoPtr->DisableClipping = SiSDisableClipping;
+ infoPtr->ClippingFlags =
+ HARDWARE_CLIP_SOLID_LINE |
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
+ HARDWARE_CLIP_MONO_8x8_FILL |
+ HARDWARE_CLIP_SOLID_FILL ;
+
+ /* Solid Lines */
+ infoPtr->SolidLineFlags = NO_PLANEMASK |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ infoPtr->SetupForSolidLine = SiSSetupForSolidLine;
+ infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine;
+ infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorVertLine;
+ }
+
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill = SiSSetupForFillRectSolid;
+ infoPtr->SubsequentSolidFillRect = SiSSubsequentFillRectSolid;
+
+ infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK;
+ infoPtr->SetupForScreenToScreenCopy =
+ SiSSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy =
+ SiSSubsequentScreenToScreenCopy;
+
+ if (pScrn->bitsPerPixel != 24) {
+ infoPtr->Mono8x8PatternFillFlags =
+ NO_PLANEMASK |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+ infoPtr->SetupForMono8x8PatternFill =
+ SiSSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ SiSSubsequentMono8x8PatternFillRect;
+ }
+
+#if 0 /* Don't work until we implement skipleft */
+ if (pScrn->bitsPerPixel != 24) {
+ infoPtr->ScreenToScreenColorExpandFillFlags = GXCOPY_ONLY |
+ CPU_TRANSFER_PAD_DWORD |
+ SCANLINE_PAD_DWORD |
+ NO_PLANEMASK |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ infoPtr->SetupForScreenToScreenColorExpandFill =
+ SiSSetupForScreenToScreenColorExpandFill;
+ infoPtr->SubsequentScreenToScreenColorExpandFill =
+ SiSSubsequentScreenToScreenColorExpandFill;
+ }
+#endif
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ if (pSiS->HWCursor || pSiS->TurboQueue) offset = 262144;
+ else offset = 0;
+ AvailFBArea.y2 = (pSiS->FbMapSize - offset) / (pScrn->displayWidth *
+ pScrn->bitsPerPixel / 8);
+ if (AvailFBArea.y2 > 2047) AvailFBArea.y2 = 2047;
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ return(XAAInit(pScreen, infoPtr));
+}
+
+static void
+SiSSync(ScrnInfoPtr pScrn) {
+ SISPtr pSiS = SISPTR(pScrn);
+ sisBLTSync;
+}
+
+static void
+SiSSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ sisSETFGCOLOR(color);
+ sisSETROP(XAACopyROP[rop]);
+ sisSETPITCH(pScrn->displayWidth * pScrn->bitsPerPixel / 8,
+ pScrn->displayWidth * pScrn->bitsPerPixel / 8);
+ /*
+ * If you don't support a write planemask, and have set the
+ * appropriate flag, then the planemask can be safely ignored.
+ * The same goes for the raster-op if only GXcopy is supported.
+ */
+ /*SETWRITEPLANEMASK(planemask);*/
+}
+
+static void
+SiSSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int destaddr, op;
+
+ destaddr = y * pScrn->displayWidth + x;
+ op = sisCMDBLT | sisSRCFG | sisTOP2BOTTOM | sisLEFT2RIGHT;
+ if (pSiS->ClipEnabled) op |= sisCLIPINTRN | sisCLIPENABL;
+ destaddr *= (pScrn->bitsPerPixel / 8);
+
+ sisSETHEIGHTWIDTH(h-1, w * (pScrn->bitsPerPixel/8)-1);
+ sisSETDSTADDR(destaddr);
+ sisSETCMD(op);
+ SiSSync(pScrn);
+}
+
+static void
+SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned int planemask,
+ int transparency_color)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ sisSETPITCH(pScrn->displayWidth * pScrn->bitsPerPixel / 8,
+ pScrn->displayWidth * pScrn->bitsPerPixel / 8);
+ sisSETROP(XAACopyROP[rop]);
+ pSiS->Xdirection = xdir;
+ pSiS->Ydirection = ydir;
+}
+
+static void
+SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int w, int h)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int srcaddr, destaddr;
+ int op ;
+
+ op = sisCMDBLT | sisSRCVIDEO;
+ if (pSiS->Ydirection == -1) {
+ op |= sisBOTTOM2TOP;
+ srcaddr = (y1 + h - 1) * pScrn->displayWidth;
+ destaddr = (y2 + h - 1) * pScrn->displayWidth;
+ } else {
+ op |= sisTOP2BOTTOM;
+ srcaddr = y1 * pScrn->displayWidth;
+ destaddr = y2 * pScrn->displayWidth;
+ }
+ if (pSiS->Xdirection == -1) {
+ op |= sisRIGHT2LEFT;
+ srcaddr += x1 + w - 1;
+ destaddr += x2 + w - 1;
+ } else {
+ op |= sisLEFT2RIGHT;
+ srcaddr += x1;
+ destaddr += x2;
+ }
+ if (pSiS->ClipEnabled) op |= sisCLIPINTRN | sisCLIPENABL;
+ srcaddr *= (pScrn->bitsPerPixel/8);
+ destaddr *= (pScrn->bitsPerPixel/8);
+ if ( ((pScrn->bitsPerPixel/8)>1) && (pSiS->Xdirection == -1) ) {
+ srcaddr += (pScrn->bitsPerPixel/8)-1;
+ destaddr += (pScrn->bitsPerPixel/8)-1;
+ }
+
+ sisSETSRCADDR(srcaddr);
+ sisSETDSTADDR(destaddr);
+ sisSETHEIGHTWIDTH(h-1, w * (pScrn->bitsPerPixel/8)-1);
+ sisSETCMD(op);
+ SiSSync(pScrn);
+}
+
+static void
+SiSSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
+ int fg, int bg, int rop, unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned int *patternRegPtr ;
+ int i ;
+ int dstpitch;
+ int mix = XAAHelpPatternROP(pScrn, &fg, &bg, planemask, &rop);
+ int isTransparent = ( bg == -1 );
+
+ dstpitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8 ;
+ sisSETBGCOLOR(bg);
+ sisSETFGCOLOR(fg);
+ sisSETROPFG(rop);
+ if (!isTransparent) {
+ sisSETROPBG(0xcc); /* copy */
+ } else {
+ sisSETROPBG(0xAA); /* dst */
+ }
+ sisSETPITCH(0, dstpitch);
+ sisSETSRCADDR(0);
+ patternRegPtr = (unsigned int *)sisSETPATREG();
+ pSiS->sisPatternReg[0] = pSiS->sisPatternReg[2] = patternx ;
+ pSiS->sisPatternReg[1] = pSiS->sisPatternReg[3] = patterny ;
+ for ( i = 0 ; i < 16 /* sisPatternHeight */ ; ) {
+ patternRegPtr[i++] = patternx ;
+ patternRegPtr[i++] = patterny ;
+ }
+}
+
+static void
+SiSSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
+ int patterny, int x, int y, int w, int h)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int dstaddr;
+ register unsigned char *patternRegPtr ;
+ register unsigned char *srcPatternRegPtr ;
+ register unsigned int *patternRegPtrL ;
+ int i, k ;
+ unsigned short tmp;
+ int shift ;
+ int op = sisCMDCOLEXP | sisTOP2BOTTOM | sisLEFT2RIGHT |
+ sisPATFG | sisSRCBG ;
+ if (pSiS->ClipEnabled) op |= sisCLIPINTRN | sisCLIPENABL;
+
+ dstaddr = ( y * pScrn->displayWidth + x ) * pScrn->bitsPerPixel / 8;
+ patternRegPtr = sisSETPATREG();
+ srcPatternRegPtr = (unsigned char *)pSiS->sisPatternReg ;
+ shift = 8-patternx ;
+ for ( i = 0, k = patterny ; i < 8 ; i++, k++ ) {
+ tmp = srcPatternRegPtr[k]<<8 | srcPatternRegPtr[k] ;
+ tmp >>= shift ;
+ patternRegPtr[i] = tmp & 0xff ;
+ }
+ patternRegPtrL = (unsigned int *)sisSETPATREG();
+ for ( i = 2 ; i < 16 /* sisPatternHeight */; ) {
+ patternRegPtrL[i++] = patternRegPtrL[0];
+ patternRegPtrL[i++] = patternRegPtrL[1];
+ }
+
+ sisSETDSTADDR(dstaddr);
+ sisSETHEIGHTWIDTH(h-1, w*(pScrn->bitsPerPixel/8)-1);
+ sisSETCMD(op);
+ SiSSync(pScrn);
+}
+/*
+ * setup for screen-to-screen color expansion
+ */
+static void
+SiSSetupForScreenToScreenColorExpandFill (ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop, unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int isTransparent = ( bg == -1 );
+
+ /*ErrorF("SISSetupScreenToScreenColorExpand()\n");*/
+
+ /*
+ * check transparency
+ */
+ /* becareful with rop */
+
+ if (isTransparent) {
+ sisSETBGCOLOR(bg);
+ sisSETFGCOLOR(fg);
+ sisSETROPFG(0xf0); /* pat copy */
+ sisSETROPBG(0xAA); /* dst */
+ } else {
+ sisSETBGCOLOR(bg);
+ sisSETFGCOLOR(fg);
+ sisSETROPFG(0xf0); /* pat copy */
+ sisSETROPBG(0xcc); /* copy */
+ }
+}
+
+/*
+ * executing screen-to-screen color expansion
+ */
+static void
+SiSSubsequentScreenToScreenColorExpandFill( ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int offset )
+/* Offset needs to be taken into account. By now, is not used */
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int destpitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8 ;
+ int srcaddr = srcy * destpitch * + srcx ;
+ int destaddr = y * destpitch + x * pScrn->bitsPerPixel / 8;
+ int srcpitch ;
+ int ww ;
+ int widthTodo ;
+ int op ;
+
+ op = sisCMDCOLEXP | sisTOP2BOTTOM | sisLEFT2RIGHT | sisPATFG | sisSRCBG | sisCMDENHCOLEXP ;
+ if (pSiS->ClipEnabled) op |= sisCLIPINTRN | sisCLIPENABL;
+
+
+/* ErrorF("SISSubsequentScreenToScreenColorExpand()\n"); */
+#define maxWidth 144
+ /* can't expand more than maxWidth in one time.
+ it's a work around for scanline greater than maxWidth
+ */
+ destpitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8 ;
+ srcpitch = ((w + 31)& ~31) /8 ;
+ sisSETPITCH(srcpitch, destpitch);
+ widthTodo = w ;
+ do {
+ ww = widthTodo < maxWidth ? widthTodo : maxWidth ;
+ sisSETDSTADDR(destaddr);
+ sisSETSRCADDR(srcaddr);
+ sisSETHEIGHTWIDTH(h-1, ww*(pScrn->bitsPerPixel / 8)-1);
+ sisSETCMD(op);
+ srcaddr += ww ;
+ destaddr += ww*pScrn->bitsPerPixel / 8 ;
+ widthTodo -= ww ;
+ } while ( widthTodo > 0 ) ;
+ SiSSync(pScrn);
+}
+
+static void SiSSetClippingRectangle ( ScrnInfoPtr pScrn,
+ int left, int top, int right, int bottom)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ sisSETCLIPTOP(left,top);
+ sisSETCLIPBOTTOM(right,bottom);
+ pSiS->ClipEnabled = TRUE;
+
+}
+
+static void SiSDisableClipping (ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ pSiS->ClipEnabled = FALSE;
+}
+
+static void SiSSetupForSolidLine(ScrnInfoPtr pScrn,
+ int color, int rop, unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ sisSETFGCOLOR(color);
+ sisSETBGCOLOR(0);
+ sisSETROP(XAACopyROP[rop]); /* dst */
+}
+
+
+static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags)
+
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int op ;
+ int major, minor, err,K1,K2, tmp;
+ op = sisCMDLINE | sisSRCFG;
+ if ((flags & OMIT_LAST)) op |= sisLASTPIX ;
+ if (pSiS->ClipEnabled) op |= sisCLIPINTRN | sisCLIPENABL;
+ if ((major = x2 - x1) <= 0) {
+ major = -major;
+ } else op |= sisXINCREASE;;
+ if ((minor = y2 - y1) <= 0) {
+ minor = -minor;
+ } else op |= sisYINCREASE;
+ if(minor >= major){
+ tmp = minor; minor = major; major = tmp;
+ }
+ else op |= sisXMAJOR;
+
+ K1 = (minor-major)<<1;
+ K2 = minor<<1;
+ err = (minor<<1) - major;
+
+ sisSETXStart(x1);
+ sisSETYStart(y1);
+ sisSETLineSteps((short)K1,(short)K2);
+ sisSETLineErrorTerm((short)err);
+ sisSETLineMajorCount((short)major);
+ sisSETCMD(op);
+/* SiSSync(pScrn);*/
+}
+
+
+static void SiSSubsequentSolidHorVertLine(ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int destaddr, op;
+
+ destaddr = y * pScrn->displayWidth + x;
+ op = sisCMDBLT | sisSRCFG | sisTOP2BOTTOM | sisLEFT2RIGHT;
+ if (pSiS->ClipEnabled) op |= sisCLIPINTRN | sisCLIPENABL;
+ destaddr *= (pScrn->bitsPerPixel / 8);
+
+ sisSETPITCH(pScrn->displayWidth * pScrn->bitsPerPixel / 8,
+ pScrn->displayWidth * pScrn->bitsPerPixel / 8);
+
+ if(dir == DEGREES_0)
+ sisSETHEIGHTWIDTH(0, len * (pScrn->bitsPerPixel>>3)-1);
+ else
+ sisSETHEIGHTWIDTH(len-1, (pScrn->bitsPerPixel>>3)-1 );
+
+
+ sisSETDSTADDR(destaddr);
+ sisSETCMD(op);
+ SiSSync(pScrn);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel2.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel2.c
new file mode 100644
index 000000000..9fd1a97de
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel2.c
@@ -0,0 +1,472 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_accel2.c,v 1.1 1999/03/21 07:35:19 dawes Exp $ */
+
+/*
+ *
+ * Acceleration for SiS530 SiS620.
+ * It is done in a separate file because the register formats are
+ * very different from the previous chips.
+ *
+ *
+ *
+ * Xavier Ducoin <x.ducoin@lectra.com>
+ */
+
+#if 0
+#define PDEBUG(arg) arg
+#else
+#define PDEBUG(arg)
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "miline.h"
+
+#include "sis_regs2.h"
+#include "sis.h"
+
+static void SiS2Sync(ScrnInfoPtr pScrn);
+static void SiS2SetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void SiS2SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h);
+static void SiS2SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2,
+ int y2, int w, int h);
+static void SiS2SetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask,
+ int transparency_color);
+static void SiS2SetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int fg, int bg,
+ int rop, unsigned int planemask);
+static void SiS2SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+static void SiS2SetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+#if 0
+static void SiS2SubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int skipleft);
+#endif
+static void SiS2SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft);
+static void SiS2SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
+
+
+
+static void
+SiS2InitializeAccelerator(ScrnInfoPtr pScrn)
+{
+}
+
+Bool
+SiS2AccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSiS = SISPTR(pScrn);
+ BoxRec AvailFBArea;
+ int offset=0;
+ int OffscreenAvailable, BLTPatternOffscreenSize;
+
+ pSiS->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ SiS2InitializeAccelerator(pScrn);
+
+ /* fill out infoPtr here */
+ infoPtr->Flags = PIXMAP_CACHE |
+ OFFSCREEN_PIXMAPS |
+ LINEAR_FRAMEBUFFER;
+
+ /* sync */
+ infoPtr->Sync = SiS2Sync;
+
+
+ /* solid fills */
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill = SiS2SetupForFillRectSolid;
+ infoPtr->SubsequentSolidFillRect = SiS2SubsequentFillRectSolid;
+
+
+ /* screen to screen copy */
+ infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK;
+ infoPtr->SetupForScreenToScreenCopy =
+ SiS2SetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy =
+ SiS2SubsequentScreenToScreenCopy;
+
+
+ /* 8x8 mono patterns */
+ infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
+ NO_TRANSPARENCY | /* transp does not work right now */
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ infoPtr->SetupForMono8x8PatternFill =
+ SiS2SetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ SiS2SubsequentMono8x8PatternFillRect;
+
+ /* screen to screen color expansion */
+#if 0
+ /* don't know how to specify the with, height of the
+ source bitmap for the replication along Width, Height of destination area
+ */
+ infoPtr->ScreenToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ SCANLINE_PAD_DWORD |
+ /*GXCOPY_ONLY | be careful not fully tested */
+ TRANSPARENCY_ONLY | /* opaque does not work right now */
+ NO_PLANEMASK;
+
+ infoPtr->SetupForScreenToScreenColorExpandFill =
+ SiS2SetupForScreenToScreenColorExpandFill;
+ infoPtr->SubsequentScreenToScreenColorExpandFill =
+ SiS2SubsequentScreenToScreenColorExpandFill;
+#endif
+
+ if (pSiS->TurboQueue) offset = 32768;
+ if (pSiS->HWCursor) offset = 16384;
+ if (pSiS->HWCursor && pSiS->TurboQueue) offset = 65536;
+
+ /* CPU To screen color expansion indirect method */
+ OffscreenAvailable = pSiS->FbMapSize - pScrn->displayWidth * pScrn->virtualY
+ * (pScrn->bitsPerPixel / 8) ;
+ OffscreenAvailable -= offset;
+ BLTPatternOffscreenSize = 2 * (((pScrn->virtualX + 31)/32) * 4);
+ if (OffscreenAvailable < BLTPatternOffscreenSize) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, 0,
+ "Not enough off-screen video memory for expand color.\n");
+ }
+ else {
+ infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
+ SYNC_AFTER_COLOR_EXPAND |
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ SCANLINE_PAD_DWORD |
+ /*GXCOPY_ONLY | not fully tested */
+ TRANSPARENCY_ONLY | /* opaque doesn't work*/
+ NO_PLANEMASK;
+
+ pSiS->XAAScanlineColorExpandBuffers[0] =
+ pSiS->FbBase + pSiS->FbMapSize - offset -
+ (((pScrn->virtualX + 31)/32) * 4);
+ pSiS->XAAScanlineColorExpandBuffers[1] =
+ pSiS->FbBase + pSiS->FbMapSize - offset -
+ (((pScrn->virtualX + 31)/32) * 4)*2;
+
+ infoPtr->NumScanlineColorExpandBuffers = 2;
+ infoPtr->ScanlineColorExpandBuffers =
+ pSiS->XAAScanlineColorExpandBuffers;
+ offset += BLTPatternOffscreenSize;
+
+ infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
+ SiS2SetupForScreenToScreenColorExpandFill;
+ infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
+ SiS2SubsequentScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentColorExpandScanline =
+ SiS2SubsequentColorExpandScanline;
+ }
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = (pSiS->FbMapSize - offset) / (pScrn->displayWidth *
+ pScrn->bitsPerPixel / 8);
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ return(XAAInit(pScreen, infoPtr));
+}
+
+static void
+SiS2Sync(ScrnInfoPtr pScrn) {
+ SISPtr pSiS = SISPTR(pScrn);
+ sisBLTSync;
+}
+
+static int sisALUConv[] =
+{
+ 0x00, /* dest = 0; 0, GXclear, 0 */
+ 0x88, /* dest &= src; DSa, GXand, 0x1 */
+ 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */
+ 0xCC, /* dest = src; S, GXcopy, 0x3 */
+ 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; D, GXnoop, 0x5 */
+ 0x66, /* dest = ^src; DSx, GXxor, 0x6 */
+ 0xEE, /* dest |= src; DSo, GXor, 0x7 */
+ 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */
+ 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
+ 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */
+ 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */
+ 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */
+ 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
+};
+/* same ROP but with Pattern as Source */
+static int sisPatALUConv[] =
+{
+ 0x00, /* dest = 0; 0, GXclear, 0 */
+ 0xA0, /* dest &= src; DPa, GXand, 0x1 */
+ 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */
+ 0xF0, /* dest = src; P, GXcopy, 0x3 */
+ 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */
+ 0xAA, /* dest = dest; D, GXnoop, 0x5 */
+ 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */
+ 0xFA, /* dest |= src; DPo, GXor, 0x7 */
+ 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */
+ 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */
+ 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
+ 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */
+ 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */
+ 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */
+ 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */
+ 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
+};
+
+static void
+SiS2SetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ PDEBUG(ErrorF("SiS2SetupForFillRectSolid()\n"));
+ sisBLTWAIT;
+ sisSETPATFGCOLOR(color);
+ sisSETROP(sisPatALUConv[rop & 0xF]);
+ sisSETPITCH(pScrn->displayWidth * pScrn->bitsPerPixel / 8,
+ pScrn->displayWidth * pScrn->bitsPerPixel / 8);
+ sisSETDSTHEIGHT(-1); /* disable merge clipping */
+
+ sisSETSRCADDR(0);
+ sisSETDSTADDR(0);
+ sisSETSRCXSRCY(0,0);
+
+}
+
+static void
+SiS2SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int op;
+
+ op = sisCMDBLT | sisTOP2BOTTOM | sisLEFT2RIGHT | sisROP;
+
+ sisSETHEIGHTWIDTH(h, w);
+ sisSETDSTXDSTY(x,y);
+
+ sisSETCMD(op);
+
+}
+
+static void
+SiS2SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned int planemask,
+ int transparency_color)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ PDEBUG(ErrorF("SiS2SetupForScreenToScreenCopy()\n"));
+ sisBLTWAIT;
+ sisSETPITCH(pScrn->displayWidth * pScrn->bitsPerPixel / 8,
+ pScrn->displayWidth * pScrn->bitsPerPixel / 8);
+ sisSETROP(sisALUConv[rop & 0xF]);
+ sisSETDSTHEIGHT(-1); /* disable merge clipping */
+ sisSETSRCADDR(0);
+ sisSETDSTADDR(0);
+ pSiS->Xdirection = xdir;
+ pSiS->Ydirection = ydir;
+}
+
+static void
+SiS2SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int w, int h)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int op ;
+
+ op = sisCMDBLT | sisSRCVIDEO | sisROP;
+ if (pSiS->Ydirection == -1) {
+ op |= sisBOTTOM2TOP;
+ y1 += h-1;
+ y2 += h-1;
+ } else {
+ op |= sisTOP2BOTTOM;
+ }
+ if (pSiS->Xdirection == -1) {
+ op |= sisRIGHT2LEFT;
+ x1 += w-1;
+ x2 += w-1;
+ } else {
+ op |= sisLEFT2RIGHT;
+ }
+
+ sisSETHEIGHTWIDTH(h, w);
+ sisSETSRCXSRCY(x1,y1);
+ sisSETDSTXDSTY(x2,y2);
+
+ sisSETCMD(op);
+}
+
+static void
+SiS2SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
+ int fg, int bg, int rop, unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ unsigned int *patternRegPtr ;
+ int dstpitch;
+ int isTransparent = ( bg == -1 );
+ int op = sisCMDCOLEXP | sisTOP2BOTTOM | sisLEFT2RIGHT |
+ sisPATMASK;
+
+ PDEBUG(ErrorF("SiS2SetupFor8x8PatternColorExpand()\n"));
+
+ dstpitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8 ;
+ /*
+ * check transparency
+ */
+ /* becareful with rop */
+ if (isTransparent) {
+ op |= sisTRANSPARENT;
+ PDEBUG(ErrorF("doesn't work right now: should never be called\n"));
+ }
+
+ sisBLTWAIT;
+ sisSETPATBGCOLOR(bg);
+ sisSETPATFGCOLOR(fg);
+ sisSETROP(sisPatALUConv[rop & 0xF]); /* pat copy */
+
+ sisSETPITCH(1, dstpitch);
+ sisSETSRCADDR(0);
+ sisSETDSTADDR(0);
+ sisSETSRCXSRCY(0,0);
+ sisSETDSTHEIGHT(-1); /* disable merge clipping */
+ pSiS->CommandReg = op | sisROP ;
+
+ patternRegPtr = (unsigned int *)sisSETPATMASKREG();
+ patternRegPtr[0] = patternx ;
+ patternRegPtr[1] = patterny ;
+}
+
+static void
+SiS2SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
+ int patterny, int x, int y, int w, int h)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ /*
+ * what do I need to do with patternx, patterny ?
+ */
+
+ sisSETDSTXDSTY(x,y);
+ sisSETHEIGHTWIDTH(h, w);
+
+ sisSETCMD(pSiS->CommandReg);
+}
+
+static void
+SiS2SetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ int isTransparent = ( bg == -1 );
+ int op ;
+
+ PDEBUG(ErrorF("SiS2SetupScreenToScreenColorExpand()\n"));
+
+ op = sisCMDENHCOLEXP | sisTOP2BOTTOM | sisLEFT2RIGHT;
+
+ if (isTransparent) {
+ op |= sisTRANSPARENT;
+ }
+
+ sisBLTWAIT;
+ sisSETPATBGCOLOR(bg);
+ sisSETPATFGCOLOR(fg);
+ /* becareful with rop */
+ sisSETROP(sisPatALUConv[rop & 0xF]);
+
+ sisSETDSTADDR(0);
+ sisSETSRCADDR(0);
+ sisSETSRCXSRCY(0,0);
+ sisSETDSTHEIGHT(-1); /* disable merge clipping */
+
+ pSiS->CommandReg = op | sisROP;
+
+}
+#if 0
+static void
+SiS2SubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int skipleft)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+
+ int pitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8;
+
+ sisBLTWAIT;
+ sisSETPITCH(pitch, pitch);
+ sisSETHEIGHTWIDTH(h, w);
+ sisSETSRCXSRCY(srcx, srcy);
+ sisSETDSTXDSTY(x, y);
+ sisSETCMD(pSiS->CommandReg);
+}
+#endif
+void
+SiS2SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int pitch = pScrn->displayWidth * pScrn->bitsPerPixel / 8;
+ int srcpitch = ((w + 31)& ~31) /8 ;
+
+ PDEBUG(ErrorF("SiS2SubsequentScanlineCPUToScreenColorExpandFill\n"));
+
+ sisBLTWAIT;
+ sisSETDSTXDSTY(x,y);
+ sisSETHEIGHTWIDTH(1, w);
+ sisSETPITCH(srcpitch, pitch);
+
+ pSiS->DstX = x;
+ pSiS->DstY = y;
+
+}
+
+void
+SiS2SubsequentColorExpandScanline(ScrnInfoPtr pScrn,
+ int bufno)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int srcaddr;
+
+ PDEBUG(ErrorF("SiS2SubsequentColorExpandScanline\n"));
+
+ srcaddr = pSiS->XAAScanlineColorExpandBuffers[bufno] - pSiS->FbBase;
+
+ sisBLTWAIT;
+ sisSETSRCADDR(srcaddr);
+ sisSETDSTXDSTY(pSiS->DstX, pSiS->DstY);
+ sisSETCMD(pSiS->CommandReg);
+ sisBLTWAIT;
+ pSiS->DstY++;
+}
+
+
+
+
+
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c
new file mode 100644
index 000000000..5d0054bef
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c
@@ -0,0 +1,734 @@
+/*
+ * Copyright 1998,1999 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>
+ * David Thomas <davtom@dream.org.uk>.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dac.c,v 1.11 1999/07/06 11:38:45 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Version.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "vgaHW.h"
+
+#include "sis.h"
+#include "sis_regs.h"
+
+static void
+SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int M, N, P , PSN, VLD , PSNx ;
+ int bestM, bestN, bestP, bestPSN, bestVLD;
+ double bestError, abest = 42.0, bestFout;
+ double target;
+ double Fvco, Fout;
+ double error, aerror;
+
+ /*
+ * fd = fref*(Numerator/Denumerator)*(Divider/PostScaler)
+ *
+ * M = Numerator [1:128]
+ * N = DeNumerator [1:32]
+ * VLD = Divider (Vco Loop Divider) : divide by 1, 2
+ * P = Post Scaler : divide by 1, 2, 3, 4
+ * PSN = Pre Scaler (Reference Divisor Select)
+ *
+ * result in vclk[]
+ */
+#define Midx 0
+#define Nidx 1
+#define VLDidx 2
+#define Pidx 3
+#define PSNidx 4
+#define Fref 14318180
+/* stability constraints for internal VCO -- MAX_VCO also determines
+ * the maximum Video pixel clock */
+#define MIN_VCO Fref
+#define MAX_VCO 135000000
+#define MAX_VCO_5597 353000000
+#define MAX_PSN 0 /* no pre scaler for this chip */
+#define TOLERANCE 0.01 /* search smallest M and N in this tolerance */
+
+ int M_min = 2;
+ int M_max = 128;
+
+/* abest=10000.0; */
+
+ target = clock * 1000;
+
+
+ if (pSiS->Chipset == PCI_CHIP_SIS5597 || pSiS->Chipset == PCI_CHIP_SIS6326){
+ int low_N = 2;
+ int high_N = 5;
+ int PSN = 1;
+
+ P = 1;
+ if (target < MAX_VCO_5597 / 2)
+ P = 2;
+ if (target < MAX_VCO_5597 / 3)
+ P = 3;
+ if (target < MAX_VCO_5597 / 4)
+ P = 4;
+ if (target < MAX_VCO_5597 / 6)
+ P = 6;
+ if (target < MAX_VCO_5597 / 8)
+ P = 8;
+
+ Fvco = P * target;
+
+ for (N = low_N; N <= high_N; N++){
+ double M_desired = Fvco / Fref * N;
+ if (M_desired > M_max * max_VLD)
+ continue;
+
+ if ( M_desired > M_max ) {
+ M = M_desired / 2 + 0.5;
+ VLD = 2;
+ } else {
+ M = Fvco / Fref * N + 0.5;
+ VLD = 1;
+ }
+
+ Fout = (double)Fref * (M * VLD)/(N * P);
+
+ error = (target - Fout) / target;
+ aerror = (error < 0) ? -error : error;
+/* if (aerror < abest && abest > TOLERANCE) {*/
+ if (aerror < abest) {
+ abest = aerror;
+ bestError = error;
+ bestM = M;
+ bestN = N;
+ bestP = P;
+ bestPSN = PSN;
+ bestVLD = VLD;
+ bestFout = Fout;
+ }
+ }
+ }
+ else {
+ for (PSNx = 0; PSNx <= MAX_PSN ; PSNx++) {
+ int low_N, high_N;
+ double FrefVLDPSN;
+
+ PSN = !PSNx ? 1 : 4;
+
+ low_N = 2;
+ high_N = 32;
+
+ for ( VLD = 1 ; VLD <= max_VLD ; VLD++ ) {
+
+ FrefVLDPSN = (double)Fref * VLD / PSN;
+ for (N = low_N; N <= high_N; N++) {
+ double tmp = FrefVLDPSN / N;
+
+ for (P = 1; P <= 4; P++) {
+ double Fvco_desired = target * ( P );
+ double M_desired = Fvco_desired / tmp;
+
+ /* Which way will M_desired be rounded?
+ * Do all three just to be safe.
+ */
+ int M_low = M_desired - 1;
+ int M_hi = M_desired + 1;
+
+ if (M_hi < M_min || M_low > M_max)
+ continue;
+
+ if (M_low < M_min)
+ M_low = M_min;
+ if (M_hi > M_max)
+ M_hi = M_max;
+
+ for (M = M_low; M <= M_hi; M++) {
+ Fvco = tmp * M;
+ if (Fvco <= MIN_VCO)
+ continue;
+ if (Fvco > MAX_VCO)
+ break;
+
+ Fout = Fvco / ( P );
+
+ error = (target - Fout) / target;
+ aerror = (error < 0) ? -error : error;
+ if (aerror < abest) {
+ abest = aerror;
+ bestError = error;
+ bestM = M;
+ bestN = N;
+ bestP = P;
+ bestPSN = PSN;
+ bestVLD = VLD;
+ bestFout = Fout;
+ }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"Freq. selected: %.2f MHz, M=%d, N=%d, VLD=%d,"
+ " P=%d, PSN=%d\n",
+ (float)(clock / 1000.), M, N, P, VLD, PSN);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"Freq. set: %.2f MHz\n", Fout / 1.0e6);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ vclk[Midx] = bestM;
+ vclk[Nidx] = bestN;
+ vclk[VLDidx] = bestVLD;
+ vclk[Pidx] = bestP;
+ vclk[PSNidx] = bestPSN;
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"Freq. selected: %.2f MHz, M=%d, N=%d, VLD=%d, P=%d, PSN=%d\n",
+ (float)(clock / 1000.), vclk[Midx], vclk[Nidx], vclk[VLDidx],
+ vclk[Pidx], vclk[PSNidx]);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"Freq. set: %.2f MHz\n", bestFout / 1.0e6);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"VCO Freq.: %.2f MHz\n", bestFout*bestP / 1.0e6);
+}
+
+Bool
+SiSInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ SISRegPtr pReg = &pSiS->ModeReg;
+ int gap, safetymargin, MemBand;
+ int vgaIOBase;
+ unsigned char temp;
+#if 1
+ int Base,mclk;
+#endif
+ int offset;
+ int clock = mode->Clock;
+ unsigned int vclk[5];
+ unsigned int CRT_CPUthresholdLow ;
+ unsigned int CRT_CPUthresholdHigh ;
+ unsigned int CRT_ENGthreshold ;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"SiSInit()\n");
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ offset = pScrn->displayWidth >> (mode->Flags & V_INTERLACE ? 2 : 3);
+
+ SiSSave(pScrn, pReg);
+
+ outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */
+ temp = inb(VGA_SEQ_DATA);
+ outw(VGA_SEQ_INDEX, 0x8605);
+
+ pReg->sisRegs3C4[BankReg] |= 0x82; /* Enable Linear */
+
+ switch (pScrn->depth) {
+ case 8:
+ break;
+ case 15:
+ offset <<= 1;
+ pReg->sisRegs3C4[BankReg] |= 0x04;
+ break;
+ case 16:
+ offset <<= 1;
+ pReg->sisRegs3C4[BankReg] |= 0x08;
+ break;
+ case 24:
+ offset += (offset << 1);
+ pReg->sisRegs3C4[BankReg] |= 0x10;
+ pReg->sisRegs3C4[MMIOEnable] |= 0x90;
+ break;
+ }
+
+ pReg->sisRegs3C4[LinearAdd0] = (pSiS->FbAddress & 0x07F80000) >> 19;
+ pReg->sisRegs3C4[LinearAdd1] = ((pSiS->FbAddress & 0xF8000000) >> 27) | 0x60;
+ pReg->sisRegs3x4[Offset] = offset & 0xFF;
+ pReg->sisRegs3C4[CRTCOff] = ((offset & 0xF00) >> 4) |
+ (((mode->CrtcVTotal-2) & 0x400) >> 10 ) |
+ (((mode->CrtcVDisplay-1) & 0x400) >> 9 ) |
+ ((mode->CrtcVSyncStart & 0x400) >> 8 ) |
+ (((mode->CrtcVSyncStart) & 0x400) >> 7 ) ;
+
+ {
+
+ SiSCalcClock(pScrn, clock, 2, vclk);
+
+ pReg->sisRegs3C4[XR2A] = (vclk[Midx] - 1) & 0x7f ;
+ pReg->sisRegs3C4[XR2A] |= ((vclk[VLDidx] == 2 ) ? 1 : 0 ) << 7 ;
+ pReg->sisRegs3C4[XR2B] = (vclk[Nidx] -1) & 0x1f ; /* bits [4:0] contain denumerator -MC */
+
+ if (vclk[Pidx] <= 4){
+ pReg->sisRegs3C4[XR2B] |= (vclk[Pidx] -1 ) << 5 ; /* postscale 1,2,3,4 */
+ pReg->sisRegs3C4[ClockBase] &= 0xBF;
+ } else {
+ pReg->sisRegs3C4[XR2B] |= ((vclk[Pidx] / 2) -1 ) << 5 ; /* postscale 6,8 */
+ pReg->sisRegs3C4[ClockBase] |= 0x40;
+ }
+ pReg->sisRegs3C4[XR2B] |= 0x80 ; /* gain for high frequency */
+
+ if (clock > 135000) pReg->sisRegs3C4[ClockReg] |= 0x02;
+
+ pReg->sisRegs3C2[0x00] = inb(0x3CC) | 0x0C; /* Programmable Clock */
+ }
+
+ if (pSiS->FastVram)
+ pReg->sisRegs3C4[ExtMiscCont5]|= 0xC0;
+ else
+ pReg->sisRegs3C4[ExtMiscCont5]&= ~0xC0;
+
+ pReg->sisRegs3C4[GraphEng] |= 0x40;
+ pSiS->ValidWidth = TRUE;
+ pReg->sisRegs3C4[GraphEng] &= 0xCF; /* Clear logical width bits */
+
+ if (pScrn->bitsPerPixel == 24) {
+ pReg->sisRegs3C4[GraphEng] |= 0x30; /* Invalid logical width */
+ pSiS->ValidWidth = FALSE;
+ }
+ else
+ {
+ switch ( pScrn->virtualX * (pScrn->bitsPerPixel >> 3) ) {
+ case 1024:
+ pReg->sisRegs3C4[GraphEng] |= 0x00; /* | 00 = No change */
+ break;
+ case 2048:
+ pReg->sisRegs3C4[GraphEng] |= 0x10;
+ break;
+ case 4096:
+ pReg->sisRegs3C4[GraphEng] |= 0x20;
+ break;
+ default:
+ pReg->sisRegs3C4[GraphEng] = 0x30; /* Invalid logical width */
+ pSiS->ValidWidth = FALSE;
+ break;
+ }
+ }
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,
+ "virtualX = %d depth = %d Logical width = %d\n",
+ pScrn->virtualX, pScrn->depth, pScrn->virtualX * (pScrn->bitsPerPixel >> 3));
+
+ if (!pSiS->NoAccel) {
+ pReg->sisRegs3C4[GraphEng] |= 0x40;
+ if (pSiS->TurboQueue) {
+ pReg->sisRegs3C4[GraphEng] |= 0x80;
+ pReg->sisRegs3C4[ExtMiscCont9] &= 0xFC; /* All Queue for 2D */
+ if (pSiS->HWCursor)
+ pReg->sisRegs3C4[TurboQueueBase] = (pScrn->videoRam/32) - 2;
+ else
+ pReg->sisRegs3C4[TurboQueueBase] = (pScrn->videoRam/32) - 1;
+ }
+ pReg->sisRegs3C4[MMIOEnable] |= 0x60; /* At PCI base */
+ }
+ pReg->sisRegs3C4[Mode64] |= 0x80;
+
+ /* Set memclock */
+ if ((pSiS->Chipset == PCI_CHIP_SIS5597) || (pSiS->Chipset == PCI_CHIP_SIS6326)) {
+ if (pSiS->MemClock > 66000) {
+ SiSCalcClock(pScrn, pSiS->MemClock, 1, vclk);
+
+ pReg->sisRegs3C4[MemClock0] = (vclk[Midx] - 1) & 0x7f ;
+ pReg->sisRegs3C4[MemClock0] |= ((vclk[VLDidx] == 2 ) ? 1 : 0 ) << 7 ;
+ pReg->sisRegs3C4[MemClock1] = (vclk[Nidx] -1) & 0x1f ; /* bits [4:0] contain denumerator -MC */
+ if (vclk[Pidx] <= 4){
+ pReg->sisRegs3C4[MemClock1] |= (vclk[Pidx] -1 ) << 5 ; /* postscale 1,2,3,4 */
+ pReg->sisRegs3C4[ClockBase] &= 0x7F;
+ } else {
+ pReg->sisRegs3C4[MemClock1] |= ((vclk[Pidx] / 2) -1 ) << 5 ; /* postscale 6,8 */
+ pReg->sisRegs3C4[ClockBase] |= 0x80;
+ }
+
+#if 1 /* Check programmed memory clock. Enable only to check the above code */
+ mclk=14318*((pReg->sisRegs3C4[MemClock0] & 0x7f)+1);
+ mclk=mclk/((pReg->sisRegs3C4[MemClock1] & 0x0f)+1);
+ Base = pReg->sisRegs3C4[ClockBase];
+ if ( (Base & 0x80)==0 ) {
+ mclk = mclk / (((pReg->sisRegs3C4[MemClock1] & 0x60) >> 5)+1);
+ } else {
+ if ((pReg->sisRegs3C4[MemClock1] & 0x60) == 0x40) { mclk=mclk/6;}
+ if ((pReg->sisRegs3C4[MemClock1] & 0x60) == 0x60) { mclk=mclk/8;}
+ }
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,2,
+ "Setting memory clock to %.3f MHz\n",
+ mclk/1000.0);
+#endif
+ }
+ }
+
+ MemBand = sisMemBandWidth(pScrn) / 10 ;
+ safetymargin = 1;
+ gap = 4;
+
+ CRT_ENGthreshold = 0x0F ;
+ CRT_CPUthresholdLow = ((pScrn->depth*clock) / MemBand)+safetymargin;
+ CRT_CPUthresholdHigh = ((pScrn->depth*clock) / MemBand)+gap+safetymargin;
+
+ if ( CRT_CPUthresholdLow > (pScrn->depth < 24 ? 0xe:0x0d) ) {
+ CRT_CPUthresholdLow = (pScrn->depth < 24 ? 0xe:0x0d);
+ }
+
+ if ( CRT_CPUthresholdHigh > (pScrn->depth < 24 ? 0x10:0x0f) ) {
+ CRT_CPUthresholdHigh = (pScrn->depth < 24 ? 0x10:0x0f);
+ }
+
+ pReg->sisRegs3C4[CPUThreshold] = (CRT_ENGthreshold & 0x0F) |
+ (CRT_CPUthresholdLow & 0x0F)<<4 ;
+ pReg->sisRegs3C4[CRTThreshold] = CRT_CPUthresholdHigh & 0x0F;
+
+ outw(VGA_SEQ_INDEX, (temp << 8) | 0x05); /* Relock Registers */
+ return(TRUE);
+}
+
+void
+SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int vgaIOBase;
+ int i,max;
+ unsigned char temp;
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"SiSRestore(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n");
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */
+ temp = inb(VGA_SEQ_DATA);
+ outw(VGA_SEQ_INDEX, 0x8605);
+
+ switch (pSiS->Chipset) {
+ case PCI_CHIP_SIS5597:
+ max=0x39;
+ break;
+ case PCI_CHIP_SIS6326:
+ max=0x3c;
+ break;
+ default:
+ max=0x37;
+ break;
+ }
+
+ for (i = 0x06; i <= max; i++) {
+ outb(VGA_SEQ_INDEX,i);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,4,
+ "XR%X Contents - %02X ", i, inb(VGA_SEQ_DATA));
+ outb(VGA_SEQ_DATA,sisReg->sisRegs3C4[i]);
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,4,
+ "Restore to - %02X Read after - %02X\n",sisReg->sisRegs3C4[i], inb(VGA_SEQ_DATA));
+ }
+ outw(vgaIOBase + 4, (sisReg->sisRegs3x4[Offset] << 8) | Offset);
+
+ outb(0x3C2, sisReg->sisRegs3C2[0x00]);
+
+ /* MemClock needs this to take effect */
+
+ outw(VGA_SEQ_INDEX, 0x0100); /* Synchronous Reset */
+ outw(VGA_SEQ_INDEX, 0x0300); /* End Reset */
+
+ outw(VGA_SEQ_INDEX, (temp << 8) | 0x05); /* Relock Registers */
+}
+
+void
+SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int vgaIOBase;
+ int i,max;
+ unsigned char temp;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"SiSSave(ScrnInfoPtr pScrn, SISRegPtr sisReg)\n");
+
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,3,"vgaIOBase = %04X\n", vgaIOBase);
+
+ outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */
+ temp = inb(VGA_SEQ_DATA);
+ outw(VGA_SEQ_INDEX, 0x8605);
+
+ switch (pSiS->Chipset) {
+ case PCI_CHIP_SIS5597:
+ max=0x39;
+ break;
+ case PCI_CHIP_SIS6326:
+ max=0x3c;
+ break;
+ default:
+ max=0x37;
+ break;
+ }
+
+ for (i = 0x06; i <= max; i++) {
+ outb(VGA_SEQ_INDEX, i);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO,4,
+ "XR%02X Contents - %02X \n", i, inb(VGA_SEQ_DATA));
+ sisReg->sisRegs3C4[i] = inb(VGA_SEQ_DATA);
+
+ }
+ outb(vgaIOBase + 4, Offset);
+ sisReg->sisRegs3x4[Offset] = inb(VGA_SEQ_DATA);
+
+ sisReg->sisRegs3C2[0x00] = inb(0x3CC);
+
+ outw(VGA_SEQ_INDEX, (temp << 8) | 0x05); /* Relock Registers */
+}
+
+static void
+SiSShowCursor(ScrnInfoPtr pScrn)
+{
+ unsigned char temp, temp2;
+
+ outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */
+ temp2 = inb(VGA_SEQ_DATA);
+ outw(VGA_SEQ_INDEX, 0x8605);
+
+ outb(VGA_SEQ_INDEX, 0x06); temp = inb(VGA_SEQ_DATA);
+ outb(VGA_SEQ_DATA, temp | 0x40);
+
+ outw(VGA_SEQ_INDEX, (temp2 << 8) | 0x05);
+}
+
+static void
+SiSHideCursor(ScrnInfoPtr pScrn) {
+ unsigned char temp, temp2;
+
+ outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */
+ temp2 = inb(VGA_SEQ_DATA);
+ outw(VGA_SEQ_INDEX, 0x8605);
+
+ outb(VGA_SEQ_INDEX, 0x06); temp = inb(VGA_SEQ_DATA);
+ outb(VGA_SEQ_DATA, temp & 0xBF);
+
+ outw(VGA_SEQ_INDEX, (temp2 << 8) | 0x05);
+}
+
+static void
+SiSSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ unsigned char temp2;
+
+ outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */
+ temp2 = inb(VGA_SEQ_DATA);
+ outw(VGA_SEQ_INDEX, 0x8605);
+
+ if (x < 0) {
+ outw(VGA_SEQ_INDEX, (-x)<<8 | 0x1C);
+ x = 0;
+ } else
+ outw(VGA_SEQ_INDEX, 0x001C);
+
+ if (y < 0) {
+ outw(VGA_SEQ_INDEX, (-y)<<8 | 0x1F);
+ y = 0;
+ } else
+ outw(VGA_SEQ_INDEX, 0x001F);
+
+ outw(VGA_SEQ_INDEX, (x&0xFF)<<8 | 0x1A);
+ outw(VGA_SEQ_INDEX, (x&0xFF00) | 0x1B);
+ outw(VGA_SEQ_INDEX, (y&0xFF)<<8 | 0x1D);
+ outw(VGA_SEQ_INDEX, (y&0xFF00) | 0x1E);
+
+ outw(VGA_SEQ_INDEX, (temp2 << 8) | 0x05);
+}
+
+static void
+SiSSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ unsigned char temp2;
+
+ outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */
+ temp2 = inb(VGA_SEQ_DATA);
+ outw(VGA_SEQ_INDEX, 0x8605);
+
+ outw(VGA_SEQ_INDEX, (fg & 0x000000FF)<<8 | 0x17);
+ outw(VGA_SEQ_INDEX, (fg & 0x0000FF00) | 0x18);
+ outw(VGA_SEQ_INDEX, (fg & 0x00FF0000)>>8 | 0x19);
+ outw(VGA_SEQ_INDEX, (bg & 0x000000FF)<<8 | 0x14);
+ outw(VGA_SEQ_INDEX, (bg & 0x0000FF00) | 0x15);
+ outw(VGA_SEQ_INDEX, (bg & 0x00FF0000)>>8 | 0x16);
+
+ outw(VGA_SEQ_INDEX, (temp2 << 8) | 0x05);
+}
+
+static void
+SiSLoadCursorImage(
+ ScrnInfoPtr pScrn,
+ unsigned char *src
+)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ int cursoraddress = ((pScrn->videoRam * 1024) - 16384) / 262144;
+ unsigned char temp, temp2;
+
+ outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */
+ temp2 = inb(VGA_SEQ_DATA);
+ outw(VGA_SEQ_INDEX, 0x8605);
+
+ memcpy((unsigned char *)pSiS->FbBase + (pScrn->videoRam * 1024) - 16384,
+ src, pSiS->CursorInfoRec->MaxWidth *
+ pSiS->CursorInfoRec->MaxHeight / 4);
+
+ outb(VGA_SEQ_INDEX, 0x38); temp = inb(VGA_SEQ_DATA);
+ outb(VGA_SEQ_DATA, (temp & 0x0F) | (cursoraddress << 4));
+ outb(VGA_SEQ_INDEX, 0x1E); temp = inb(VGA_SEQ_DATA); outb(VGA_SEQ_DATA, (temp & 0xF7) | 0x08);
+
+ outw(VGA_SEQ_INDEX, (temp2 << 8) | 0x05);
+}
+
+static Bool
+SiSUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+#if 0
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSiS = SISPTR(pScrn);
+#endif
+ return TRUE;
+}
+
+Bool
+SiSHWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ SISPtr pSiS = SISPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+#if 0
+ int memory = pScrn->displayWidth * pScrn->virtualY * pScrn->bitsPerPixel/8;
+
+ if (memory > (pScrn->videoRam * 1024 - 16384)) return FALSE;
+#endif
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pSiS->CursorInfoRec = infoPtr;
+
+ infoPtr->MaxWidth = 64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->Flags =
+ HARDWARE_CURSOR_INVERT_MASK |
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_NIBBLE_SWAPPED |
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1;
+ infoPtr->SetCursorColors = SiSSetCursorColors;
+ infoPtr->SetCursorPosition = SiSSetCursorPosition;
+ infoPtr->LoadCursorImage = SiSLoadCursorImage;
+ infoPtr->HideCursor = SiSHideCursor;
+ infoPtr->ShowCursor = SiSShowCursor;
+ infoPtr->UseHWCursor = SiSUseHWCursor;
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
+
+unsigned int
+SiSddc1Read(ScrnInfoPtr pScrn)
+{
+#if 0
+ SISPtr pSiS = SISPTR(pScrn);
+#endif
+ int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+ unsigned char temp, temp2;
+
+ outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */
+ temp2 = inb(VGA_SEQ_DATA);
+ outw(VGA_SEQ_INDEX, 0x8605);
+
+ /* Wait until vertical retrace is in progress. */
+ while (inb(vgaIOBase + 0xA) & 0x08);
+ while (!(inb(vgaIOBase + 0xA) & 0x08));
+
+ /* Get the result */
+ outb(VGA_SEQ_INDEX, 0x11); temp = inb(VGA_SEQ_DATA);
+
+ outw(VGA_SEQ_INDEX, (temp2 << 8) | 0x05);
+
+ return ((temp & 0x02)>>1);
+}
+
+/* Auxiliary function to find real memory clock (in Khz) */
+int
+SiSMclk()
+{ int mclk;
+ unsigned char Num, Denum, Base;
+
+ /* Numerator */
+
+ read_xr(MemClock0,Num);
+ mclk=14318*((Num & 0x7f)+1);
+
+ /* Denumerator */
+ read_xr(MemClock1,Denum);
+ mclk=mclk/((Denum & 0x0f)+1);
+
+ /* Divider. Don't seems to work for mclk with some cards ? */
+ if ( (Num & 0x80)!=0 ) {
+ mclk = mclk*2;
+ }
+
+ /* Post-scaler. Values depends on SR13 bit 7 */
+ outb(VGA_SEQ_INDEX, ClockBase);
+ Base = inb(VGA_SEQ_DATA);
+
+ if ( (Base & 0x80)==0 ) {
+ mclk = mclk / (((Denum & 0x60) >> 5)+1);
+ }
+ else {
+ /* Values 00 and 01 are reserved */
+ if ((Denum & 0x60) == 0x40) { mclk=mclk/6;
+ }
+ if ((Denum & 0x60) == 0x60) { mclk=mclk/8;
+ }
+ }
+
+ return(mclk);
+}
+
+/* Returns estimated memory bandwidth in Kbits/sec (for dotclock defaults) */
+/* Currently, a very rough estimate (2 cycles / read ; 1 for fast_vram), with 70% to allow for */
+int
+sisMemBandWidth(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS = SISPTR(pScrn);
+ SISRegPtr pReg = &pSiS->ModeReg;
+ int band;
+
+ if (pSiS->MemClock)
+ band=pSiS->MemClock;
+ else
+ band=SiSMclk();
+
+ if (((pReg->sisRegs3C4[Mode64] >> 1) & 3) == 0) /* Only 1 bank Vram */
+ band = (band * 16);
+ else
+ band = (band * 32);
+
+ if (pSiS->FastVram) {
+ band=band*2;
+ } else {
+ if (((pReg->sisRegs3C4[ExtMiscCont5]) & 0xC0) == 0xC0) band=band*2;
+ };
+
+ /* Check AGP 2x Transfer Rate */
+ if (((pReg->sisRegs3C4[ExtConfStatus0]) & 0x30) == 0x30) band=band*2;
+
+ return(band*7/10);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c
new file mode 100644
index 000000000..ce650153d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c
@@ -0,0 +1,1715 @@
+/*
+ * Copyright 1998,1999 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>
+ * David Thomas <davtom@dream.org.uk>.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.c,v 1.29 1999/06/20 15:02:56 dawes Exp $ */
+
+#define DEBUG
+
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+#include "cfb24_32.h"
+#include "xf1bpp.h"
+#include "xf4bpp.h"
+#include "mibank.h"
+#include "micmap.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "xf86Version.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86cmap.h"
+#include "vgaHW.h"
+#include "xf86RAC.h"
+
+#include "mipointer.h"
+
+#include "mibstore.h"
+
+#include "sis_regs.h"
+#include "sis.h"
+
+#ifdef XFreeXDGA
+#define _XF86DGA_SERVER_
+#include "extensions/xf86dgastr.h"
+#endif
+
+#ifdef DPMSExtension
+#include "globals.h"
+#define DPMS_SERVER
+#include "extensions/dpms.h"
+#endif
+
+static void SISIdentify(int flags);
+static Bool SISProbe(DriverPtr drv, int flags);
+static Bool SISPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool SISScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool SISEnterVT(int scrnIndex, int flags);
+static void SISLeaveVT(int scrnIndex, int flags);
+static Bool SISCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool SISSaveScreen(ScreenPtr pScreen, Bool unblank);
+
+/* Required if the driver supports mode switching */
+static Bool SISSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+/* Required if the driver supports moving the viewport */
+static void SISAdjustFrame(int scrnIndex, int x, int y, int flags);
+
+/* Optional functions */
+static void SISFreeScreen(int scrnIndex, int flags);
+static int SISValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
+
+/* Internally used functions */
+static Bool SISMapMem(ScrnInfoPtr pScrn);
+static Bool SISUnmapMem(ScrnInfoPtr pScrn);
+static void SISSave(ScrnInfoPtr pScrn);
+static void SISRestore(ScrnInfoPtr pScrn);
+static Bool SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+
+/*
+ * This is intentionally screen-independent. It indicates the binding
+ * choice made in the first PreInit.
+ */
+static int pix24bpp = 0;
+
+#define VERSION 4000
+#define SIS_NAME "SIS"
+#define SIS_DRIVER_NAME "sis"
+#define SIS_MAJOR_VERSION 1
+#define SIS_MINOR_VERSION 0
+#define SIS_PATCHLEVEL 0
+
+/*
+ * This contains the functions needed by the server after loading the driver
+ * module. It must be supplied, and gets passed back by the SetupProc
+ * function in the dynamic case. In the static case, a reference to this
+ * is compiled in, and this requires that the name of this DriverRec be
+ * an upper-case version of the driver name.
+ */
+
+DriverRec SIS = {
+ VERSION,
+ "accelerated driver for SiS chipsets",
+ SISIdentify,
+ SISProbe,
+ NULL,
+ 0
+};
+
+static SymTabRec SISChipsets[] = {
+ { PCI_CHIP_SG86C201, "SIS86c201" },
+ { PCI_CHIP_SG86C202, "SIS86c202" },
+ { PCI_CHIP_SG86C205, "SIS86c205" },
+ { PCI_CHIP_SG86C215, "SIS86c215" },
+ { PCI_CHIP_SG86C225, "SIS86c225" },
+ { PCI_CHIP_SIS5597, "SIS5597" },
+ { PCI_CHIP_SIS5597, "SIS5598" },
+ { PCI_CHIP_SIS530, "SIS530" },
+ { PCI_CHIP_SIS6326, "SIS6326" },
+ { -1, NULL }
+};
+
+static PciChipsets SISPciChipsets[] = {
+ { PCI_CHIP_SG86C201, PCI_CHIP_SG86C201, RES_SHARED_VGA },
+ { PCI_CHIP_SG86C202, PCI_CHIP_SG86C202, RES_SHARED_VGA },
+ { PCI_CHIP_SG86C205, PCI_CHIP_SG86C205, RES_SHARED_VGA },
+ { PCI_CHIP_SG86C205, PCI_CHIP_SG86C205, RES_SHARED_VGA },
+ { PCI_CHIP_SIS5597, PCI_CHIP_SIS5597, RES_SHARED_VGA },
+ { PCI_CHIP_SIS530, PCI_CHIP_SIS530, RES_SHARED_VGA },
+ { PCI_CHIP_SIS6326, PCI_CHIP_SIS6326, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED }
+};
+
+typedef enum {
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+ OPTION_PCI_RETRY,
+ OPTION_RGB_BITS,
+ OPTION_NOACCEL,
+ OPTION_TURBOQUEUE,
+ OPTION_FAST_VRAM,
+ OPTION_SET_MEMCLOCK
+} SISOpts;
+
+static OptionInfoRec SISOptions[] = {
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_RGB_BITS, "rgbbits", OPTV_INTEGER, {0}, -1 },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_TURBOQUEUE, "TurboQueue", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SET_MEMCLOCK, "SetMClk", OPTV_FREQ, {0}, -1 },
+ { OPTION_FAST_VRAM, "FastVram", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+int sisReg32MMIO[]={0x8280,0x8284,0x8288,0x828C,0x8290,0x8294,0x8298,0x829C,
+ 0x82A0,0x82A4,0x82A8,0x82AC};
+/* Engine Register for the 2nd Generation Graphics Engine */
+int sis2Reg32MMIO[]={0x8200,0x8204,0x8208,0x820C,0x8210,0x8214,0x8218,0x821C,
+ 0x8220,0x8224,0x8228,0x822C,0x8230,0x8234,0x8238,0x823C,
+ 0x8240, 0x8300};
+
+static const char *xaaSymbols[] = {
+ "XAADestroyInfoRec",
+ "XAACreateInfoRec",
+ "XAAInit",
+ "XAAStippleScanlineFuncLSBFirst",
+ "XAAOverlayFBfuncs",
+ "XAACachePlanarMonoStipple",
+ "XAAScreenIndex",
+ NULL
+};
+
+static const char *vgahwSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWUnlock",
+ "vgaHWInit",
+ "vgaHWSave",
+ "vgaHWRestore",
+ "vgaHWProtect",
+ "vgaHWGetIOBase",
+ "vgaHWMapMem",
+ "vgaHWLock",
+ "vgaHWFreeHWRec",
+ "vgaHWSaveScreen",
+ NULL
+};
+
+static const char *fbSymbols[] = {
+ "xf1bppScreenInit",
+ "xf4bppScreenInit",
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb24ScreenInit",
+ "cfb24_32ScreenInit",
+ "cfb32ScreenInit",
+ NULL
+};
+
+static const char *ddcSymbols[] = {
+ "xf86PrintEDID",
+ "xf86DoEDID_DDC1",
+ NULL
+};
+
+static const char *i2cSymbols[] = {
+ "xf86I2CBusInit",
+ "xf86CreateI2CBusRec",
+ NULL
+};
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(sisSetup);
+
+static XF86ModuleVersionInfo sisVersRec =
+{
+ "sis",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ SIS_MAJOR_VERSION, SIS_MINOR_VERSION, SIS_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+XF86ModuleData sisModuleData = { &sisVersRec, sisSetup, NULL };
+
+pointer
+sisSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&SIS, module, 0);
+ LoaderRefSymLists(vgahwSymbols, fbSymbols, i2cSymbols,
+ xaaSymbols, NULL);
+ return (pointer)TRUE;
+ }
+
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+}
+
+#endif /* XFree86LOADER */
+
+static Bool
+SISGetRec(ScrnInfoPtr pScrn)
+{
+ /*
+ * Allocate an SISRec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(SISRec), 1);
+ /* Initialise it */
+
+ return TRUE;
+}
+
+static void
+SISFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+#ifdef DPMSExtension
+static void
+SISDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
+{
+ unsigned char extDDC_PCR;
+ unsigned char crtc17 = 0;
+ unsigned char seq1 = 0 ;
+ int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,"SISDisplayPowerManagementSet(%d)\n",PowerManagementMode);
+ outb(vgaIOBase + 4, 0x17);
+ crtc17 = inb(vgaIOBase + 5);
+ outb(VGA_SEQ_INDEX, 0x11);
+ extDDC_PCR = inb(VGA_SEQ_DATA) & ~0xC0;
+ switch (PowerManagementMode)
+ {
+ case DPMSModeOn:
+ /* HSync: On, VSync: On */
+ seq1 = 0x00 ;
+ crtc17 |= 0x80;
+ break;
+ case DPMSModeStandby:
+ /* HSync: Off, VSync: On */
+ seq1 = 0x20 ;
+ extDDC_PCR |= 0x40;
+ break;
+ case DPMSModeSuspend:
+ /* HSync: On, VSync: Off */
+ seq1 = 0x20 ;
+ extDDC_PCR |= 0x80;
+ break;
+ case DPMSModeOff:
+ /* HSync: Off, VSync: Off */
+ seq1 = 0x20 ;
+ extDDC_PCR |= 0xC0;
+ /* DPMSModeOff is not supported with ModeStandby | ModeSuspend */
+ /* need same as the generic VGA function */
+ crtc17 &= ~0x80;
+ break;
+ }
+ outw(VGA_SEQ_INDEX, 0x0100); /* Synchronous Reset */
+ outb(VGA_SEQ_INDEX, 0x01); /* Select SEQ1 */
+ seq1 |= inb(VGA_SEQ_DATA) & ~0x20;
+ outb(VGA_SEQ_DATA, seq1);
+ usleep(10000);
+ outb(vgaIOBase + 4, 0x17);
+ outb(vgaIOBase + 5, crtc17);
+ outb(VGA_SEQ_INDEX, 0x11);
+ outb(VGA_SEQ_DATA, extDDC_PCR);
+ outw(VGA_SEQ_INDEX, 0x0300); /* End Reset */
+}
+#endif
+
+/* Mandatory */
+static void
+SISIdentify(int flags)
+{
+ xf86PrintChipsets(SIS_NAME, "driver for SiS chipsets", SISChipsets);
+}
+
+static void
+SIS1bppColorMap(ScrnInfoPtr pScrn) {
+/* In 1 bpp we have color 0 at LUT 0 and color 1 at LUT 0x3f.
+ This makes white and black look right (otherwise they were both
+ black. I'm sure there's a better way to do that, just lazy to
+ search the docs. */
+
+ outb(0x3C8, 0x00); outb(0x3C9, 0x00); outb(0x3C9, 0x00); outb(0x3C9, 0x00);
+ outb(0x3C8, 0x3F); outb(0x3C9, 0x3F); outb(0x3C9, 0x3F); outb(0x3C9, 0x3F);
+}
+
+/* Mandatory */
+static Bool
+SISProbe(DriverPtr drv, int flags)
+{
+ int i;
+ GDevPtr *devSections;
+ int *usedChips;
+ int numDevSections;
+ int numUsed;
+ Bool foundScreen = FALSE;
+
+ /*
+ * The aim here is to find all cards that this driver can handle,
+ * and for the ones not already claimed by another driver, claim the
+ * slot, and allocate a ScrnInfoRec.
+ *
+ * This should be a minimal probe, and it should under no circumstances
+ * change the state of the hardware. Because a device is found, don't
+ * assume that it will be used. Don't do any initialisations other than
+ * the required ScrnInfoRec initialisations. Don't allocate any new
+ * data structures.
+ *
+ * Since this test version still uses vgaHW, we'll only actually claim
+ * one for now, and just print a message about the others.
+ */
+
+ /*
+ * Next we check, if there has been a chipset override in the config file.
+ * For this we must find out if there is an active device section which
+ * is relevant, i.e., which has no driver specified or has THIS driver
+ * specified.
+ */
+
+ if ((numDevSections = xf86MatchDevice(SIS_DRIVER_NAME,
+ &devSections)) <= 0) {
+ /*
+ * There's no matching device section in the config file, so quit
+ * now.
+ */
+ return FALSE;
+ }
+
+ /*
+ * While we're VGA-dependent, can really only have one such instance, but
+ * we'll ignore that.
+ */
+
+ /*
+ * We need to probe the hardware first. We then need to see how this
+ * fits in with what is given in the config file, and allow the config
+ * file info to override any contradictions.
+ */
+
+ /*
+ * All of the cards this driver supports are PCI, so the "probing" just
+ * amounts to checking the PCI data that the server has already collected.
+ */
+ if (xf86GetPciVideoInfo() == NULL) {
+ /*
+ * We won't let anything in the config file override finding no
+ * PCI video cards at all. This seems reasonable now, but we'll see.
+ */
+ return FALSE;
+ }
+
+ numUsed = xf86MatchPciInstances(SIS_NAME, PCI_VENDOR_SIS,
+ SISChipsets, SISPciChipsets, devSections,
+ numDevSections, drv, &usedChips);
+
+ /* Free it since we don't need that list after this */
+ xfree(devSections);
+ devSections = NULL;
+ if (numUsed <= 0)
+ return FALSE;
+
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn;
+
+ /* Allocate a ScrnInfoRec and claim the slot */
+ pScrn = xf86AllocateScreen(drv, 0);
+
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = SIS_DRIVER_NAME;
+ pScrn->name = SIS_NAME;
+ pScrn->Probe = SISProbe;
+ pScrn->PreInit = SISPreInit;
+ pScrn->ScreenInit = SISScreenInit;
+ pScrn->SwitchMode = SISSwitchMode;
+ pScrn->AdjustFrame = SISAdjustFrame;
+ pScrn->EnterVT = SISEnterVT;
+ pScrn->LeaveVT = SISLeaveVT;
+ pScrn->FreeScreen = SISFreeScreen;
+ pScrn->ValidMode = SISValidMode;
+ foundScreen = TRUE;
+ xf86ConfigActivePciEntity(pScrn, usedChips[i], SISPciChipsets,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+ xfree(usedChips);
+ return foundScreen;
+}
+
+#if 0 /* xf86ValidateModes() takes care of this */
+/*
+ * GetAccelPitchValues -
+ *
+ * This function returns a list of display width (pitch) values that can
+ * be used in accelerated mode.
+ */
+static int
+GetAccelPitchValues(ScrnInfoPtr pScrn)
+{
+ return ((pScrn->displayWidth + 7) & ~7);
+}
+#endif
+
+/* Mandatory */
+static Bool
+SISPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ SISPtr pSiS;
+ MessageType from;
+ unsigned char videoram;
+ char *ramtype = NULL, *mclk = NULL;
+ int vgaIOBase;
+ int i;
+ double real;
+ unsigned char temp, unlock;
+ ClockRangePtr clockRanges;
+ char *mod = NULL;
+ const char *Sym = NULL;
+
+ /*
+ * Note: This function is only called once at server startup, and
+ * not at the start of each server generation. This means that
+ * only things that are persistent across server generations can
+ * be initialised here. xf86Screens[] is (pScrn is a pointer to one
+ * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex()
+ * are too, and should be used for data that must persist across
+ * server generations.
+ *
+ * Per-generation data should be allocated with
+ * AllocateScreenPrivateIndex() from the ScreenInit() function.
+ */
+
+ /* Check the number of entities, and fail if it isn't one. */
+ if (pScrn->numEntities != 1)
+ return FALSE;
+
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /*
+ * Allocate a vgaHWRec
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ VGAHWPTR(pScrn)->MapSize = 0x10000; /* Standard 64k VGA window */
+
+ if (!vgaHWMapMem(pScrn))
+ return FALSE;
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ /* Allocate the SISRec driverPrivate */
+ if (!SISGetRec(pScrn)) {
+ return FALSE;
+ }
+ pSiS = SISPTR(pScrn);
+ pSiS->pScrn = pScrn;
+
+ /* Get the entity, and make sure it is PCI. */
+ pSiS->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pSiS->pEnt->location.type != BUS_PCI)
+ return FALSE;
+
+ /* Find the PCI info for this screen */
+ pSiS->PciInfo = xf86GetPciInfoForEntity(pSiS->pEnt->index);
+ pSiS->PciTag = pciTag(pSiS->PciInfo->bus, pSiS->PciInfo->device,
+ pSiS->PciInfo->func);
+
+ /*
+ * XXX This could be refined if some VGA memory resources are not
+ * decoded in operating mode.
+ */
+ {
+ resRange vgamem[] = { {ResShrMemBlock,0xA0000,0xAFFFF},
+ {ResShrMemBlock,0xB0000,0xB7FFF},
+ {ResShrMemBlock,0xB8000,0xBFFFF},
+ _END };
+ xf86SetOperatingState(vgamem, pSiS->pEnt->index, ResUnusedOpr);
+ }
+
+ /* Operations for which memory access is required */
+ pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+ /* Operations for which I/O access is required (XXX check this) */
+ pScrn->racIoFlags = RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+
+ /* The ramdac module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "ramdac"))
+ return FALSE;
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*
+ * The first thing we should figure out is the depth, bpp, etc.
+ * Our default depth is 8, so pass it to the helper function.
+ * Our preference for depth 24 is 24bpp, so tell it that too.
+ */
+ if (!xf86SetDepthBpp(pScrn, 8, 0, 0, Support24bppFb |
+ SupportConvert32to24 | PreferConvert32to24)) {
+ return FALSE;
+ } else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 1:
+ case 4:
+ case 8:
+ case 15:
+ case 16:
+ case 24:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ xf86PrintDepthBpp(pScrn);
+
+ /* Get the depth24 pixmap format */
+ if (pScrn->depth == 24 && pix24bpp == 0)
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /*
+ * The new cmap layer needs this to be initialised.
+ */
+
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+
+ /* We use a programamble clock */
+ pScrn->progClock = TRUE;
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, SISOptions);
+
+ /* Set the bits per RGB for 8bpp mode */
+ if (pScrn->depth == 8) {
+ /* XXX This is here just to test options. */
+ /* Default to 8 */
+ pScrn->rgbBits = 6;
+#if 0
+ if (xf86GetOptValInteger(SISOptions, OPTION_RGB_BITS,
+ &pScrn->rgbBits)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
+ pScrn->rgbBits);
+ }
+#endif
+ }
+ from = X_DEFAULT;
+ pSiS->HWCursor = TRUE;
+ if (xf86GetOptValBool(SISOptions, OPTION_HW_CURSOR, &pSiS->HWCursor))
+ from = X_CONFIG;
+ if (xf86ReturnOptValBool(SISOptions, OPTION_SW_CURSOR, FALSE)) {
+ from = X_CONFIG;
+ pSiS->HWCursor = FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pSiS->HWCursor ? "HW" : "SW");
+ if (xf86ReturnOptValBool(SISOptions, OPTION_NOACCEL, FALSE)) {
+ pSiS->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+ if (xf86ReturnOptValBool(SISOptions, OPTION_PCI_RETRY, FALSE)) {
+ pSiS->UsePCIRetry = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
+ }
+ if (xf86GetOptValFreq(SISOptions, OPTION_SET_MEMCLOCK, OPTUNITS_MHZ,
+ &real)) {
+ pSiS->MemClock = (int)(real * 1000.0);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Memory clock set to %.3f MHz\n",
+ pSiS->MemClock/1000.0);
+ }
+ if (xf86ReturnOptValBool(SISOptions, OPTION_FAST_VRAM, FALSE)) {
+ pSiS->FastVram = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Fast VRAM enabled\n");
+ }
+
+ pSiS->TurboQueue = FALSE; /* For now */
+ pSiS->ddc1Read = SiSddc1Read;
+ /*
+ * Set the Chipset and ChipRev, allowing config file entries to
+ * override.
+ */
+ if (pSiS->pEnt->device->chipset && *pSiS->pEnt->device->chipset) {
+ pScrn->chipset = pSiS->pEnt->device->chipset;
+ pSiS->Chipset = xf86StringToToken(SISChipsets, pScrn->chipset);
+ from = X_CONFIG;
+ } else if (pSiS->pEnt->device->chipID >= 0) {
+ pSiS->Chipset = pSiS->pEnt->device->chipID;
+ pScrn->chipset = (char *)xf86TokenToString(SISChipsets, pSiS->Chipset);
+
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pSiS->Chipset);
+ } else {
+ from = X_PROBED;
+ pSiS->Chipset = pSiS->PciInfo->chipType;
+ pScrn->chipset = (char *)xf86TokenToString(SISChipsets, pSiS->Chipset);
+ }
+ if (pSiS->pEnt->device->chipRev >= 0) {
+ pSiS->ChipRev = pSiS->pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pSiS->ChipRev);
+ } else {
+ pSiS->ChipRev = pSiS->PciInfo->chipRev;
+ }
+
+ /*
+ * This shouldn't happen because such problems should be caught in
+ * SISProbe(), but check it just in case.
+ */
+ if (pScrn->chipset == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ChipID 0x%04X is not recognised\n", pSiS->Chipset);
+ return FALSE;
+ }
+ if (pSiS->Chipset < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Chipset \"%s\" is not recognised\n", pScrn->chipset);
+ return FALSE;
+ }
+
+ outb(VGA_SEQ_INDEX, 0x05); unlock = inb(VGA_SEQ_DATA);
+ outw(VGA_SEQ_INDEX, 0x8605); /* Unlock registers */
+
+ switch (pSiS->Chipset) {
+ case PCI_CHIP_SG86C201:
+ case PCI_CHIP_SG86C202:
+ case PCI_CHIP_SG86C205:
+ case PCI_CHIP_SG86C215:
+ case PCI_CHIP_SG86C225:
+ pSiS->MaxClock = 135000;
+ pSiS->TurboQueue = FALSE;
+ break;
+ case PCI_CHIP_SIS5597:
+ pSiS->MaxClock = 135000;
+ pSiS->TurboQueue = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Memory clock was set by BIOS to %3.3fMHz\n",SiSMclk()/1000.0);
+ if (xf86ReturnOptValBool(SISOptions, OPTION_TURBOQUEUE, FALSE)) {
+ pSiS->TurboQueue = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Enabling TurboQueue\n");
+ }
+ break;
+ case PCI_CHIP_SIS6326:
+ case PCI_CHIP_SIS530:
+ pSiS->MaxClock = 175000; /* XXX Guess, need to check this */
+ pSiS->TurboQueue = FALSE; /* Turn on for 6326 */
+ xf86DrvMsg(pScrn->scrnIndex, from, "Memory clock was set by BIOS to %3.3fMHz\n",SiSMclk()/1000.0);
+ if (xf86ReturnOptValBool(SISOptions, OPTION_TURBOQUEUE, FALSE)) {
+ pSiS->TurboQueue = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Enabling TurboQueue\n");
+ }
+ outb(VGA_SEQ_INDEX, ExtConfStatus1); temp = inb(VGA_SEQ_DATA);
+ switch (temp & 0x03) {
+ case 0x00:
+ ramtype = "SGRAM/SDRAM";
+ switch ((temp & 0xE0)>>5) {
+ case 0x00:
+ mclk = "66";
+ break;
+ case 0x01:
+ mclk = "75";
+ break;
+ case 0x02:
+ mclk = "83";
+ break;
+ case 0x03:
+ mclk = "90";
+ break;
+ case 0x04:
+ mclk = "100";
+ break;
+ case 0x05:
+ mclk = "115";
+ break;
+ case 0x06:
+ mclk = "134";
+ break;
+ case 0x07:
+ mclk = "50";
+ break;
+ }
+ break;
+ case 0x01:
+ ramtype = "2cycle EDO DRAM";
+ switch ((temp & 0xE0)>>5) {
+ case 0x00:
+ mclk = "65";
+ break;
+ case 0x01:
+ mclk = "70";
+ break;
+ case 0x02:
+ mclk = "75";
+ break;
+ case 0x03:
+ mclk = "80";
+ break;
+ case 0x04:
+ mclk = "85";
+ break;
+ case 0x05:
+ mclk = "90";
+ break;
+ case 0x06:
+ mclk = "55";
+ break;
+ case 0x07:
+ mclk = "60";
+ break;
+ }
+ break;
+ case 0x02:
+ ramtype = "1cycle EDO DRAM";
+ switch ((temp & 0xE0)>>5) {
+ case 0x00:
+ mclk = "50";
+ break;
+ case 0x01:
+ mclk = "55";
+ break;
+ case 0x02:
+ mclk = "60";
+ break;
+ case 0x03:
+ mclk = "65";
+ break;
+ case 0x04:
+ mclk = "70";
+ break;
+ case 0x05:
+ mclk = "75";
+ break;
+ case 0x06:
+ mclk = "80";
+ break;
+ case 0x07:
+ mclk = "45";
+ break;
+ }
+ break;
+ case 0x03:
+ ramtype = "Fast Page DRAM";
+ switch ((temp & 0xE0)>>5) {
+ case 0x00:
+ mclk = "55";
+ break;
+ case 0x01:
+ mclk = "60";
+ break;
+ case 0x02:
+ mclk = "65";
+ break;
+ case 0x03:
+ mclk = "70";
+ break;
+ case 0x04:
+ mclk = "75";
+ break;
+ case 0x05:
+ mclk = "80";
+ break;
+ case 0x06:
+ mclk = "45";
+ break;
+ case 0x07:
+ mclk = "50";
+ break;
+ }
+ break;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Installed RAM type is %s\n",ramtype);
+ xf86DrvMsg(pScrn->scrnIndex, from, "Memory speed is %sMHz\n",mclk);
+ break;
+ }
+
+ if (pSiS->pEnt->device->MemBase != 0) {
+ /*
+ * XXX Should check that the config file value matches one of the
+ * PCI base address values.
+ */
+ pSiS->FbAddress = pSiS->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ pSiS->FbAddress = pSiS->PciInfo->memBase[0] & 0xFFFFFFF0;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pSiS->FbAddress);
+
+ if (pSiS->pEnt->device->IOBase != 0) {
+ /*
+ * XXX Should check that the config file value matches one of the
+ * PCI base address values.
+ */
+ pSiS->IOAddress = pSiS->pEnt->device->IOBase;
+ from = X_CONFIG;
+ } else {
+ pSiS->IOAddress = pSiS->PciInfo->memBase[1] & 0xFFFFFFF0;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
+ (unsigned long)pSiS->IOAddress);
+
+ /* Register the PCI-assigned resources. */
+ if (xf86RegisterResources(pSiS->pEnt->index, NULL, ResExclusive)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n");
+ return FALSE;
+ }
+
+ /* HW bpp matches reported bpp */
+ pSiS->HwBpp = pScrn->bitsPerPixel;
+
+ if (pSiS->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pSiS->pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else {
+ switch (pSiS->Chipset) {
+
+ case PCI_CHIP_SG86C201:
+ case PCI_CHIP_SG86C202:
+ case PCI_CHIP_SG86C205:
+ case PCI_CHIP_SG86C215:
+ case PCI_CHIP_SG86C225:
+ outb(VGA_SEQ_INDEX, RAMSize); /* Memory configuration register */
+ temp = inb(VGA_SEQ_DATA);
+ switch (temp & 0x03) {
+ case 0:
+ pScrn->videoRam = 1024;
+ break;
+ case 1:
+ pScrn->videoRam = 2048;
+ break;
+ case 2:
+ pScrn->videoRam = 4096;
+ break;
+ case 3:
+ pScrn->videoRam = 1024;
+ break;
+ }
+ case PCI_CHIP_SIS5597:
+ outb(VGA_SEQ_INDEX, FBSize);
+ /* The framebuffer size is configured in 256K increments
+ (512 for 64 bits bus) */
+ pScrn->videoRam = (1+(inb(VGA_SEQ_DATA) & 7))*256;
+ outb(VGA_SEQ_INDEX, Mode64);
+ if ((inb(VGA_SEQ_DATA) >> 1) & 3) {
+ pScrn->videoRam *= 2;
+ }
+ break;
+ case PCI_CHIP_SIS6326:
+ case PCI_CHIP_SIS530:
+ outb(VGA_SEQ_INDEX, RAMSize); /* Get memory size */
+ videoram = (inb(VGA_SEQ_DATA) >> 1);
+ switch (videoram & 0x0B) {
+ case 0x00:
+ pScrn->videoRam = 1024;
+ break;
+ case 0x01:
+ pScrn->videoRam = 2048;
+ break;
+ case 0x02:
+ pScrn->videoRam = 4096;
+ break;
+ case 0x03:
+ pScrn->videoRam = 1024;
+ break;
+ case 0x08:
+ pScrn->videoRam = 0; /* OUCH ! */
+ break;
+ case 0x09:
+ pScrn->videoRam = 2048;
+ break;
+ case 0x0A:
+ pScrn->videoRam = 4096;
+ break;
+ case 0x0B:
+ pScrn->videoRam = 8192;
+ break;
+ default:
+ pScrn->videoRam = 1024;
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Unable to determine VideoRam, defaulting to 1MB\n",
+ pScrn->videoRam);
+ break;
+ }
+ break;
+ }
+ }
+ outw(VGA_SEQ_INDEX, (unlock << 8) | 0x05);
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+
+ pSiS->FbMapSize = pScrn->videoRam * 1024;
+
+ /* Set the min pixel clock */
+ pSiS->MinClock = 16250; /* XXX Guess, need to check this */
+ pSiS->MinClock = 10000; /* XXX Guess, need to check this */
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
+ pSiS->MinClock / 1000);
+
+ /*
+ * If the user has specified ramdac speed in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pSiS->pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ speed = pSiS->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ speed = pSiS->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ speed = pSiS->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ case 32:
+ speed = pSiS->pEnt->device->dacSpeeds[DAC_BPP32];
+ break;
+ }
+ if (speed == 0)
+ pSiS->MaxClock = pSiS->pEnt->device->dacSpeeds[0];
+ else
+ pSiS->MaxClock = speed;
+ from = X_CONFIG;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
+ pSiS->MaxClock / 1000);
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+ clockRanges = xnfalloc(sizeof(ClockRange));
+ clockRanges->next = NULL;
+ clockRanges->minClock = pSiS->MinClock;
+ clockRanges->maxClock = pSiS->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = TRUE; /* XXX check this */
+
+ /*
+ * xf86ValidateModes will check that the mode HTotal and VTotal values
+ * don't exceed the chipset's limit if pScrn->maxHValue and
+ * pScrn->maxVValue are set. Since our SISValidMode() already takes
+ * care of this, we don't worry about setting them here.
+ */
+
+ /* Select valid modes from those available */
+ /*
+ * XXX Assuming min pitch 256, max 4096
+ * XXX Assuming min height 128, max 4096
+ */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, 256, 4096,
+ pScrn->bitsPerPixel * 8, 128, 4096,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pSiS->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+
+ if (i == -1) {
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ mod = "xf1bpp";
+ Sym = "xf1bppScreenInit";
+ break;
+ case 4:
+ mod = "xf4bpp";
+ Sym = "xf4bppScreenInit";
+ break;
+ case 8:
+ mod = "cfb";
+ Sym = "cfbScreenInit";
+ break;
+ case 16:
+ mod = "cfb16";
+ Sym = "cfb16ScreenInit";
+ break;
+ case 24:
+ if (pix24bpp == 24) {
+ mod = "cfb24";
+ Sym = "cfb24ScreenInit";
+ } else {
+ mod = "xf24_32bpp";
+ Sym = "cfb24_32ScreenInit";
+ }
+ break;
+ case 32:
+ mod = "cfb32";
+ Sym = "cfb32ScreenInit";
+ break;
+ }
+
+ if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymbols(Sym, NULL);
+
+ if (!xf86LoadSubModule(pScrn, "i2c")) {
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(i2cSymbols, NULL);
+
+ /* Load XAA if needed */
+ if (!pSiS->NoAccel) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+ }
+
+ /* Load DDC if needed */
+ /* This gives us DDC1 - we should be able to get DDC2B using i2c */
+ if (!xf86LoadSubModule(pScrn, "ddc")) {
+ SISFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+
+ /* Initialize DDC1 if possible */
+ if (pSiS->ddc1Read)
+ xf86PrintEDID(xf86DoEDID_DDC1(pScrn->scrnIndex,vgaHWddc1SetSpeed,pSiS->ddc1Read ) );
+
+
+ return TRUE;
+}
+
+
+/*
+ * Map the framebuffer and MMIO memory.
+ */
+
+static Bool
+SISMapMem(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS;
+ int mmioFlags;
+
+ pSiS = SISPTR(pScrn);
+
+ /*
+ * Map IO registers to virtual address space
+ */
+#if !defined(__alpha__)
+ mmioFlags = VIDMEM_MMIO;
+#else
+ /*
+ * For Alpha, we need to map SPARSE memory, since we need
+ * byte/short access.
+ */
+ mmioFlags = VIDMEM_MMIO | VIDMEM_SPARSE;
+#endif
+ pSiS->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+ pSiS->PciTag, pSiS->IOAddress, 0x10000);
+ if (pSiS->IOBase == NULL)
+ return FALSE;
+
+#ifdef __alpha__
+ /*
+ * for Alpha, we need to map DENSE memory as well, for
+ * setting CPUToScreenColorExpandBase.
+ */
+ pSiS->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pSiS->PciTag, pSiS->IOAddress, 0x10000);
+
+ if (pSiS->IOBaseDense == NULL)
+ return FALSE;
+#endif /* __alpha__ */
+
+ pSiS->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pSiS->PciTag,
+ (unsigned long)pSiS->FbAddress,
+ pSiS->FbMapSize);
+ if (pSiS->FbBase == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+SISUnmapMem(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS;
+
+ pSiS = SISPTR(pScrn);
+
+ /*
+ * Unmap IO registers to virtual address space
+ */
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->IOBase, 0x10000);
+ pSiS->IOBase = NULL;
+
+#ifdef __alpha__
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->IOBaseDense, 0x10000);
+ pSiS->IOBaseDense = NULL;
+#endif /* __alpha__ */
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->FbBase, pSiS->FbMapSize);
+ pSiS->FbBase = NULL;
+ return TRUE;
+}
+
+
+/*
+ * This function saves the video state.
+ */
+static void
+SISSave(ScrnInfoPtr pScrn)
+{
+ SISPtr pSiS;
+ vgaRegPtr vgaReg;
+ SISRegPtr sisReg;
+
+ pSiS = SISPTR(pScrn);
+ vgaReg = &VGAHWPTR(pScrn)->SavedReg;
+ sisReg = &pSiS->SavedReg;
+
+ vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
+
+ SiSSave(pScrn, sisReg);
+}
+
+
+/*
+ * Initialise a new mode. This is currently still using the old
+ * "initialise struct, restore/write struct to HW" model. That could
+ * be changed.
+ */
+
+static Bool
+SISModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg;
+ SISPtr pSiS = SISPTR(pScrn);
+ SISRegPtr sisReg;
+
+ vgaHWUnlock(hwp);
+
+ /* Initialise the ModeReg values */
+ if (!vgaHWInit(pScrn, mode))
+ return FALSE;
+ pScrn->vtSema = TRUE;
+
+ if (!SiSInit(pScrn, mode))
+ return FALSE;
+
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,"HDisplay: %d, VDisplay: %d \n",mode->HDisplay,mode->VDisplay);
+ /* Program the registers */
+ vgaHWProtect(pScrn, TRUE);
+ vgaReg = &hwp->ModeReg;
+ sisReg = &pSiS->ModeReg;
+
+ vgaReg->Attribute[0x10] = 0x01;
+ if (pScrn->bitsPerPixel > 8)
+ vgaReg->Graphics[0x05] = 0x00;
+
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+
+ SiSRestore(pScrn, sisReg);
+
+ vgaHWProtect(pScrn, FALSE);
+
+ if (pSiS->MemClock)
+ xf86DrvMsgVerb(pScrn->scrnIndex,2, X_INFO, "Memory clock is set to %3.3fMHz\n",SiSMclk()/1000.0);
+
+ return TRUE;
+}
+
+/*
+ * Restore the initial (text) mode.
+ */
+static void
+SISRestore(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp;
+ vgaRegPtr vgaReg;
+ SISPtr pSiS;
+ SISRegPtr sisReg;
+
+ hwp = VGAHWPTR(pScrn);
+ pSiS = SISPTR(pScrn);
+ vgaReg = &hwp->SavedReg;
+ sisReg = &pSiS->SavedReg;
+
+ vgaHWProtect(pScrn, TRUE);
+
+ SiSRestore(pScrn, sisReg);
+
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+
+ vgaHWProtect(pScrn, FALSE);
+}
+
+
+/* Mandatory */
+
+/* This gets called at the start of each server generation */
+
+static Bool
+SISScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ /* The vgaHW references will disappear one day */
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ SISPtr pSiS;
+ int ret;
+ VisualPtr visual;
+
+ /*
+ * First get the ScrnInfoRec
+ */
+ pScrn = xf86Screens[pScreen->myNum];
+
+ hwp = VGAHWPTR(pScrn);
+
+ hwp->MapSize = 0x10000; /* Standard 64k VGA window */
+
+ pSiS = SISPTR(pScrn);
+
+ /* Map the VGA memory and get the VGA IO base */
+ if (!vgaHWMapMem(pScrn))
+ return FALSE;
+ vgaHWGetIOBase(hwp);
+
+ /* Map the SIS memory and MMIO areas */
+ if (!SISMapMem(pScrn))
+ return FALSE;
+
+ /* Save the current state */
+ SISSave(pScrn);
+
+ /* Darken the screen for aesthetic reasons and set the viewport */
+ SISSaveScreen(pScreen, FALSE);
+
+ /* Initialise the first mode */
+ if (!SISModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ /* Darken the screen for aesthetic reasons and set the viewport */
+ SISSaveScreen(pScreen, FALSE);
+ SISAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ /*
+ * For bpp > 8, the default visuals are not acceptable because we only
+ * support TrueColor and not DirectColor.
+ */
+
+ if (pScrn->bitsPerPixel > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
+ pScrn->defaultVisual))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ ret = xf1bppScreenInit(pScreen, pSiS->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 4:
+ ret = xf4bppScreenInit(pScreen, pSiS->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 8:
+ ret = cfbScreenInit(pScreen, pSiS->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 16:
+ ret = cfb16ScreenInit(pScreen, pSiS->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 24:
+ if (pix24bpp == 24)
+ ret = cfb24ScreenInit(pScreen, pSiS->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ else
+ ret = cfb24_32ScreenInit(pScreen, pSiS->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 32:
+ ret = cfb32ScreenInit(pScreen, pSiS->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in SISScrnInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ if (!ret)
+ return FALSE;
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ if (pScrn->bitsPerPixel > 8) {
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ } else if (pScrn->depth == 1) {
+ SIS1bppColorMap(pScrn);
+ }
+
+ if (!pSiS->NoAccel) {
+ if ( pSiS->Chipset == PCI_CHIP_SIS530 )
+ SiS2AccelInit(pScreen);
+ else
+ SiSAccelInit(pScreen);
+ }
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ /* Initialise cursor functions */
+ miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
+
+ if (pSiS->HWCursor)
+ SiSHWCursorInit(pScreen);
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ if (!vgaHWHandleColormaps(pScreen))
+ return FALSE;
+
+#ifdef DPMSExtension
+ xf86DPMSInit(pScreen, (DPMSSetProcPtr)SISDisplayPowerManagementSet, 0);
+#endif
+
+ pSiS->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = SISCloseScreen;
+ pScreen->SaveScreen = SISSaveScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ /* Turn on the screen now */
+ SISSaveScreen(pScreen, TRUE);
+
+ return TRUE;
+}
+
+
+/* Usually mandatory */
+static Bool
+SISSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return SISModeInit(xf86Screens[scrnIndex], mode);
+}
+
+
+/*
+ * This function is used to initialize the Start Address - the first
+ * displayed location in the video memory.
+ */
+/* Usually mandatory */
+static void
+SISAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ SISPtr pSiS;
+ vgaHWPtr hwp;
+ int base = y * pScrn->displayWidth + x;
+ int vgaIOBase;
+ unsigned char temp,temp2;
+
+ hwp = VGAHWPTR(pScrn);
+ pSiS = SISPTR(pScrn);
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ outb(VGA_SEQ_INDEX, 0x05); /* Unlock Registers */
+ temp = inb(VGA_SEQ_DATA);
+ outw(VGA_SEQ_INDEX, 0x8605);
+
+ if (pScrn->bitsPerPixel < 8) {
+ base = (y * pScrn->displayWidth + x + 3) >> 3;
+ } else {
+ base = y * pScrn->displayWidth + x ;
+ /* calculate base bpp dep. */
+ switch (pScrn->bitsPerPixel) {
+ case 16:
+ base >>= 1;
+ break;
+ case 24:
+ base = ((base * 3)) >> 2;
+ base -= base % 6;
+ break;
+ default: /* 8bpp */
+ base >>= 2;
+ break;
+ }
+ }
+
+ outw(vgaIOBase + 4, (base & 0x00FF00) | 0x0C);
+ outw(vgaIOBase + 4, ((base & 0x00FF) << 8) | 0x0D);
+
+ outb(VGA_SEQ_INDEX, 0x27);
+ temp2 = inb(VGA_SEQ_DATA) & 0xF0;
+ temp2 |= (base & 0x0F0000) >> 16;
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+ "3C5/27h set to hex %2X, base %d\n", temp, base);
+ outb(VGA_SEQ_DATA, temp2);
+
+ outw(VGA_SEQ_INDEX, (temp << 8) | 0x05); /* Relock Registers */
+}
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ *
+ * We may wish to unmap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static Bool
+SISEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ /* Should we re-save the text mode on each VT enter? */
+ if (!SISModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * This is called when VT switching away from the X server. Its job is
+ * to restore the previous (text) mode.
+ *
+ * We may wish to remap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static void
+SISLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ SISRestore(pScrn);
+ vgaHWLock(hwp);
+}
+
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode. It should really also unmap the video memory too.
+ */
+
+/* Mandatory */
+static Bool
+SISCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ SISPtr pSiS = SISPTR(pScrn);
+
+ if (pScrn->vtSema) {
+ SISRestore(pScrn);
+ vgaHWLock(hwp);
+ SISUnmapMem(pScrn);
+ }
+ if(pSiS->AccelInfoRec)
+ XAADestroyInfoRec(pSiS->AccelInfoRec);
+ if(pSiS->CursorInfoRec)
+ xf86DestroyCursorInfoRec(pSiS->CursorInfoRec);
+ pScrn->vtSema = FALSE;
+
+ pScreen->CloseScreen = pSiS->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+
+/* Free up any per-generation data structures */
+
+/* Optional */
+static void
+SISFreeScreen(int scrnIndex, int flags)
+{
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ SISFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+/* Optional */
+static int
+SISValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ return(MODE_OK);
+}
+
+/* Do screen blanking */
+
+/* Mandatory */
+static Bool
+SISSaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+ return vgaHWSaveScreen(pScreen, unblank);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.h
new file mode 100644
index 000000000..56a3778b5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.h
@@ -0,0 +1,101 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_driver.h,v 1.3 1999/01/31 12:22:00 dawes Exp $ */
+
+/*
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS 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.
+ *
+ * Modified for Sis by Xavier Ducoin (xavier@rd.lectra.fr)
+ *
+ */
+
+
+/*#define DEBUG*/
+
+#include "xf86_ansic.h"
+
+extern int SISchipset;
+
+extern Bool sisLinearSupport; /*linear addressing enable */
+
+extern Bool sisUseMMIO;
+extern unsigned char *sisMMIOBase;
+extern unsigned int sisBLTPatternAddress;
+extern int sisBLTPatternOffscreenSize;
+extern Bool sisAvoidImageBLT;
+extern unsigned char *sisBltDataWindow;
+
+extern Bool sisHWCursor;
+
+extern int sisAluConv[]; /* Map Alu to SIS ROP source data */
+
+/*
+ * Definitions for IO access to 32 bit ports
+ */
+extern int sisReg32MMIO[];
+#define BR(x) sisReg32MMIO[x]
+
+
+/*
+ * Forward definitions for the functions that make up the driver. See
+ * the definitions of these functions for the real scoop.
+ */
+
+/* in sis_blitter.c */
+extern void sisBitBlt();
+extern void sisMMIOBitBlt();
+
+/* in sis_BitBlt.c */
+extern void siscfbDoBitbltCopy();
+extern void siscfbFillBoxSolid();
+
+/* in sis_solid.c */
+extern void siscfbFillRectSolid();
+extern void siscfbFillSolidSpansGeneral();
+extern void sisMMIOFillRectSolid();
+extern void sisMMIOFillSolidSpansGeneral();
+
+/* in sis_blt16.c */
+extern RegionPtr siscfb16CopyArea();
+extern RegionPtr siscfb24CopyArea();
+extern void siscfbCopyWindow();
+
+/* in sis_line.c */
+extern void sisMMIOLineSS();
+extern void sisMMIOSegmentSS();
+
+/* in sis_pntwin.c */
+extern void sisPaintWindow();
+
+/* in sis_FillRct.c */
+extern void siscfbPolyFillRect();
+
+/* in ct_FillSt.c */
+extern void siscfbFillRectOpaqueStippled32();
+extern void siscfbFillRectTransparentStippled32();
+extern void sisMMIOFillRectOpaqueStippled32();
+extern void sisMMIOFillRectTransparentStippled32();
+
+/* in sis_teblt8.c */
+extern void sisMMIOImageGlyphBlt();
+extern void sisMMIOPolyGlyphBlt();
+
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_regs.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_regs.h
new file mode 100644
index 000000000..cc86dd422
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_regs.h
@@ -0,0 +1,207 @@
+/*
+ * Copyright 1998,1999 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>
+ * David Thomas <davtom@dream.org.uk>.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_regs.h,v 1.9 1999/07/06 11:38:46 dawes Exp $ */
+
+/* 3C4 */
+#define BankReg 0x06
+#define ClockReg 0x07
+#define CPUThreshold 0x08
+#define CRTThreshold 0x09
+#define CRTCOff 0x0A
+#define DualBanks 0x0B
+#define MMIOEnable 0x0B
+#define RAMSize 0x0C
+#define Mode64 0x0C
+#define ExtConfStatus0 0x0D
+#define ExtConfStatus1 0x0E
+#define ClockBase 0x13
+#define LinearAdd0 0x20
+#define LinearAdd1 0x21
+#define GraphEng 0x27
+#define MemClock0 0x28
+#define MemClock1 0x29
+#define XR2A 0x2A
+#define XR2B 0x2B
+#define TurboQueueBase 0x2C
+#define FBSize 0x2F
+#define ExtMiscCont5 0x34
+#define ExtMiscCont9 0x3C
+
+/* 3x4 */
+#define Offset 0x13
+
+#define read_xr(num,var) do {outb(0x3c4, num);var=inb(0x3c5);} while (0)
+
+/* Definitions for the SIS engine communication. */
+
+extern int sisReg32MMIO[];
+#define BR(x) sisReg32MMIO[x]
+
+/* These are done using Memory Mapped IO, of the registers */
+/*
+ * Modified for Sis by Xavier Ducoin (xavier@rd.lectra.fr)
+ */
+
+
+#define sisLEFT2RIGHT 0x10
+#define sisRIGHT2LEFT 0x00
+#define sisTOP2BOTTOM 0x20
+#define sisBOTTOM2TOP 0x00
+
+#define sisSRCSYSTEM 0x03
+#define sisSRCVIDEO 0x02
+#define sisSRCFG 0x01
+#define sisSRCBG 0x00
+
+#define sisCMDBLT 0x0000
+#define sisCMDBLTMSK 0x0100
+#define sisCMDCOLEXP 0x0200
+#define sisCMDLINE 0x0300
+
+#define sisCMDENHCOLEXP 0x2000
+
+#define sisXINCREASE 0x10
+#define sisYINCREASE 0x20
+#define sisCLIPENABL 0x40
+#define sisCLIPINTRN 0x80
+#define sisCLIPEXTRN 0x00
+
+
+#define sisPATREG 0x08
+#define sisPATFG 0x04
+#define sisPATBG 0x00
+
+#define sisLASTPIX 0x0800
+#define sisXMAJOR 0x0400
+
+
+/* Macros to do useful things with the SIS BitBLT engine */
+
+#define sisBLTSync \
+ while(*(volatile unsigned short *)(pSiS->IOBase + BR(10)+2) & \
+ (0x4000)){}
+
+/* According to SiS 6326 2D programming guide, 16 bits position at */
+/* 0x82A8 returns queue free. But this don't work, so don't wait */
+/* anything when turbo-queue is enabled. If there are frequent syncs */
+/* this should work. But not for xaa_benchmark :-( */
+
+#define sisBLTWAIT \
+ if (!pSiS->TurboQueue) {\
+ while(*(volatile unsigned short *)(pSiS->IOBase + BR(10)+2) & \
+ (0x4000)){}} /* \
+ else {while(*(volatile unsigned short *)(pSiS->IOBase + BR(10)) < \
+ 63){}} */
+
+#define sisSETPATREG()\
+ ((unsigned char *)(pSiS->IOBase + BR(11)))
+
+#define sisSETPATREGL()\
+ ((unsigned long *)(pSiS->IOBase + BR(11)))
+
+#define sisSETCMD(op) \
+ *(volatile unsigned short *)(pSiS->IOBase + BR(10) +2 ) = op
+
+#define sisSETROPFG(op) \
+ *(volatile unsigned int *)(pSiS->IOBase + BR(4)) = ((*(volatile unsigned int *)(pSiS->IOBase + BR(4)))&0xffffff) | (op<<24)
+
+#define sisSETROPBG(op) \
+ *(volatile unsigned int *)(pSiS->IOBase + BR(5)) = ((*(volatile unsigned int *)(pSiS->IOBase + BR(5)))&0xffffff) | (op<<24)
+
+#define sisSETROP(op) \
+ sisSETROPFG(op);sisSETROPBG(op);
+
+
+#define sisSETSRCADDR(srcAddr) \
+ *(volatile unsigned int *)(pSiS->IOBase + BR(0)) = srcAddr&0x3FFFFFL
+
+#define sisSETDSTADDR(dstAddr) \
+ *(volatile unsigned int *)(pSiS->IOBase + BR(1)) = dstAddr&0x3FFFFFL
+
+#define sisSETPITCH(srcPitch,dstPitch) \
+ *(volatile unsigned int *)(pSiS->IOBase + BR(2)) = ((dstPitch&0xFFFF)<<16)| \
+ (srcPitch&0xFFFF)
+
+/* according to SIS 2D Engine Programming Guide
+ * width -1 independant of Bpp
+ */
+#define sisSETHEIGHTWIDTH(Height,Width)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(3)) = (((Height)&0xFFFF)<<16)| \
+ ((Width)&0xFFFF)
+
+#define sisSETCLIPTOP(x,y)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(8)) = (((y)&0xFFFF)<<16)| \
+ ((x)&0xFFFF)
+
+#define sisSETCLIPBOTTOM(x,y)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(9)) = (((y)&0xFFFF)<<16)| \
+ ((x)&0xFFFF)
+
+#define sisSETBGCOLOR(bgColor)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(5)) = (bgColor)
+
+#define sisSETBGCOLOR8(bgColor)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(5)) = (bgColor&0xFF)
+
+#define sisSETBGCOLOR16(bgColor)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(5)) = (bgColor&0xFFFF)
+
+#define sisSETBGCOLOR24(bgColor)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(5)) = (bgColor&0xFFFFFF)
+
+
+#define sisSETFGCOLOR(fgColor)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(4)) = (fgColor)
+
+#define sisSETFGCOLOR8(fgColor)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(4)) = (fgColor&0xFF)
+
+#define sisSETFGCOLOR16(fgColor)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(4)) = (fgColor&0xFFFF)
+
+#define sisSETFGCOLOR24(fgColor)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(4)) = (fgColor&0xFFFFFF)
+
+/* Line drawing */
+
+#define sisSETXStart(XStart) \
+ *(volatile unsigned int *)(pSiS->IOBase + BR(0)) = XStart&0xFFFF
+
+#define sisSETYStart(YStart) \
+ *(volatile unsigned int *)(pSiS->IOBase + BR(1)) = YStart&0xFFFF
+
+#define sisSETLineMajorCount(MajorAxisCount) \
+ *(volatile unsigned int *)(pSiS->IOBase + BR(3)) = MajorAxisCount&0xFFFF
+
+#define sisSETLineSteps(K1,K2) \
+ *(volatile unsigned int *)(pSiS->IOBase + BR(6)) = (((K1)&0xFFFF)<<16)| \
+ ((K2)&0xFFFF)
+
+#define sisSETLineErrorTerm(ErrorTerm) \
+ *(volatile unsigned short *)(pSiS->IOBase + BR(7)) = ErrorTerm
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_regs2.h b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_regs2.h
new file mode 100644
index 000000000..82e115c9f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis_regs2.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright 1998,1999 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Mike Chapman <mike@paranoia.com>,
+ * Juanjo Santamarta <santamarta@ctv.es>,
+ * Mitani Hiroshi <hmitani@drl.mei.co.jp>
+ * David Thomas <davtom@dream.org.uk>.
+ * Xavier Ducoin <x.ducoin@lectra.com>
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_regs2.h,v 1.2 1999/05/15 06:24:56 dawes Exp $ */
+
+/* 3C4 */
+#define BankReg 0x06
+#define ClockReg 0x07
+#define CPUThreshold 0x08
+#define CRTThreshold 0x09
+#define CRTCOff 0x0A
+#define DualBanks 0x0B
+#define MMIOEnable 0x0B
+#define RAMSize 0x0C
+#define Mode64 0x0C
+#define ExtConfStatus1 0x0E
+#define ClockBase 0x13
+#define LinearAdd0 0x20
+#define LinearAdd1 0x21
+#define GraphEng 0x27
+#define MemClock0 0x28
+#define MemClock1 0x29
+#define XR2A 0x2A
+#define XR2B 0x2B
+#define TurboQueueBase 0x2C
+#define FBSize 0x2F
+#define ExtMiscCont5 0x34
+#define ExtMiscCont9 0x3C
+
+/* 3x4 */
+#define Offset 0x13
+
+#define read_xr(num,var) do {outb(0x3c4, num);var=inb(0x3c5);} while (0)
+
+/* Definitions for the SIS engine communication. */
+
+extern int sis2Reg32MMIO[];
+#define BR(x) sis2Reg32MMIO[x]
+
+#define sisLEFT2RIGHT 0x00010000
+#define sisRIGHT2LEFT 0x00000000
+#define sisTOP2BOTTOM 0x00020000
+#define sisBOTTOM2TOP 0x00000000
+
+#define sisSRCSYSTEM 0x00000010
+#define sisSRCVIDEO 0x00000000
+
+#define sisNOMERGECLIP 0x04000000
+
+#define sisCMDBLT 0x00000000
+#define sisCMDCOLEXP 0x00000001
+#define sisCMDLINE 0x00000004
+#define sisCMDENHCOLEXP 0x00000002
+
+#define sisTRANSPARENT 0x00100000
+
+#define sisCLIPINTRN 0x00000000
+#define sisCLIPEXTRN 0x04000000
+#define sisCLIPENABL 0x00040000
+
+#define sisPATFG 0x00000000
+#define sisPATREG 0x00000040
+#define sisPATMASK 0x00000080
+
+/* Macros to do useful things with the SIS BitBLT engine */
+
+/*
+ bit 31 2D engine: 1 is idle,
+ bit 30 3D engine: 1 is idle,
+ bit 29 Command queue: 1 is empty
+*/
+#define sisBLTSync \
+ while(!(*(volatile unsigned short *)(pSiS->IOBase + BR(16)+2) & \
+ (0x8000))){}
+
+#define sisBLTWAIT \
+ if (!pSiS->TurboQueue) {\
+ while(!(*(volatile unsigned short *)(pSiS->IOBase + BR(16)+2) & \
+ (0x8000))){}}
+
+#define sisSETPATMASKREG()\
+ ((unsigned char *)(pSiS->IOBase + BR(11)))
+
+#define sisSETPATREG()\
+ ((unsigned char *)(pSiS->IOBase + BR(17)))
+
+#define sisSETCMD(op) \
+ *(volatile unsigned long *)(pSiS->IOBase + BR(15) ) = op
+
+#define sisSETROP(op) \
+ pSiS->ROPReg = (op<<8)
+
+#define sisROP pSiS->ROPReg
+
+#define sisSETSRCADDR(srcAddr) \
+ *(volatile unsigned long *)(pSiS->IOBase + BR(0)) = srcAddr
+
+#define sisSETDSTADDR(dstAddr) \
+ *(volatile unsigned int *)(pSiS->IOBase + BR(4)) = dstAddr
+
+#define sisSETPITCH(srcPitch,dstPitch) \
+ *(volatile unsigned short *)(pSiS->IOBase + BR(1)) = (srcPitch); \
+ *(volatile unsigned short *)(pSiS->IOBase + BR(5)) = (dstPitch)
+
+#define sisSETHEIGHTWIDTH(Height,Width)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(6)) = (((Height)&0xFFFF)<<16) | ((Width)&0xFFFF)
+
+#define sisSETDSTHEIGHT(Height)\
+ *(volatile unsigned short *)(pSiS->IOBase + BR(5)+2) = (Height)
+
+
+#define sisSETSRCXSRCY(X,Y)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(2)) = (((X)&0xFFFF)<<16)| \
+ ((Y)&0xFFFF)
+
+#define sisSETDSTXDSTY(X,Y)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(3)) = (((X)&0xFFFF)<<16)| \
+ ((Y)&0xFFFF)
+
+#define sisSETCLIPTOP(x,y)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(13)) = (((y)&0xFFFF)<<16)| \
+ ((x)&0xFFFF)
+
+#define sisSETCLIPBOTTOM(x,y)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(14)) = (((y)&0xFFFF)<<16)| \
+ ((x)&0xFFFF)
+
+
+#define sisSETBGCOLOR(bgColor)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(10)) = (bgColor)
+
+#define sisSETFGCOLOR(fgColor)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(9)) = (fgColor)
+
+
+#define sisSETPATBGCOLOR(bgColor)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(8)) = (bgColor)
+
+#define sisSETPATFGCOLOR(fgColor)\
+ *(volatile unsigned int *)(pSiS->IOBase + BR(7)) = (fgColor)
+
+
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/Imakefile
new file mode 100644
index 000000000..012df1eda
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/Imakefile
@@ -0,0 +1,66 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/Imakefile,v 1.3 1999/08/30 01:25:04 dawes Exp $
+XCOMM
+XCOMM This is the Imakefile for the TDFX driver.
+XCOMM
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#if BuildXF86DRI /* || BuildXF86DRIDriverSupport -- does not currently work */
+DRISRC = tdfx_dri.c
+DRIOBJ = tdfx_dri.o
+DRIINCLUDES=-I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri
+DRIDEFINES = $(GLX_DEFINES)
+#endif
+
+SRCS = tdfx_driver.c tdfx_io.c tdfx_hwcurs.c tdfx_accel.c \
+ tdfx_dga.c $(DRISRCS)
+
+OBJS = tdfx_driver.o tdfx_io.o tdfx_hwcurs.o tdfx_accel.o \
+ tdfx_dga.o $(DRIOBJS)
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(XF86SRC)/xaa -I$(XF86SRC)/rac \
+ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa -I$(XF86SRC)/ramdac \
+ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
+ -I$(SERVERSRC)/Xext \
+ -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(EXTINCSRC) $(DRIINCLUDES)
+#endif
+
+DEFINES = $(DRIDEFINES)
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget(tdfx,$(OBJS))
+
+InstallObjectModule(tdfx,$(MODULEDIR),drivers)
+
+XCOMM To install a man page remove the x and add these lines
+XCOMM xCppManTarget(tdfx,)
+XCOMM xInstallModuleManPage(tdfx)
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/tdfx)
+InstallDriverSDKNonExecFile(tdfx.h,$(DRIVERSDKDIR)/drivers/tdfx)
+
+InstallDriverSDKNonExecFile(tdfx_accel.c,$(DRIVERSDKDIR)/drivers/tdfx)
+InstallDriverSDKNonExecFile(tdfx_dga.c,$(DRIVERSDKDIR)/drivers/tdfx)
+InstallDriverSDKNonExecFile(tdfx_dri.c,$(DRIVERSDKDIR)/drivers/tdfx)
+InstallDriverSDKNonExecFile(tdfx_dri.h,$(DRIVERSDKDIR)/drivers/tdfx)
+InstallDriverSDKNonExecFile(tdfx_dripriv.h,$(DRIVERSDKDIR)/drivers/tdfx)
+InstallDriverSDKNonExecFile(tdfx_driver.c,$(DRIVERSDKDIR)/drivers/tdfx)
+InstallDriverSDKNonExecFile(tdfx_hwcurs.c,$(DRIVERSDKDIR)/drivers/tdfx)
+InstallDriverSDKNonExecFile(tdfx_io.c,$(DRIVERSDKDIR)/drivers/tdfx)
+InstallDriverSDKNonExecFile(tdfx_io.h,$(DRIVERSDKDIR)/drivers/tdfx)
+
+InstallDriverSDKObjectModule(tdfx,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx.h b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx.h
new file mode 100644
index 000000000..0359a3787
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx.h
@@ -0,0 +1,183 @@
+/*
+ Voodoo Banshee driver version 1.0.2
+
+ Author: Daryll Strauss
+
+ Copyright: 1998,1999
+*/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx.h,v 1.3 1999/08/30 01:25:04 dawes Exp $ */
+
+#ifndef _TDFX_H_
+#define _TDFX_H_
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "tdfxdefs.h"
+
+#ifdef XF86DRI
+#include "xf86drm.h"
+#include "sarea.h"
+#define _XF86DRI_SERVER_
+#include "xf86dri.h"
+#include "dri.h"
+#include "GL/glxint.h"
+#include "tdfx_dri.h"
+#include "tdfx_dripriv.h"
+#endif
+
+struct _TDFXRec;
+typedef struct _TDFXRec *TDFXPtr;
+
+#ifdef PROP_3DFX
+#include "tdfx_priv.h"
+#endif
+extern Bool TDFXInitPrivate(ScreenPtr pScreen);
+extern void TDFXShutdownPrivate(ScreenPtr pScreen);
+
+#ifdef XF86DRI
+extern void FillPrivateDRI(TDFXPtr pTDFX, TDFXDRIPtr pTDFXDRI);
+#endif
+
+#if 0
+/* These are not normally turned on. They are only included for debugging. */
+#define TRACEACCEL 1
+#define TRACE 1
+#define TRACECURS 1
+#define REGDEBUG 1
+#endif
+
+#ifdef TRACE
+#define TDFXTRACE ErrorF
+#else
+#define TDFXTRACE 0 && (unsigned long)
+#endif
+
+#ifdef TRACEACCEL
+#define TDFXTRACEACCEL ErrorF
+#else
+#define TDFXTRACEACCEL 0 && (unsigned long)
+#endif
+
+#ifdef TRACECURS
+#define TDFXTRACECURS ErrorF
+#else
+#define TDFXTRACECURS 0 && (unsigned long)
+#endif
+
+#ifdef TRACEREG
+#define TDFXTRACEREG ErrorF
+#else
+#define TDFXTRACEREG 0 && (unsigned long)
+#endif
+
+#include <xaa.h>
+#include <xf86Cursor.h>
+
+typedef void (*TDFXWriteIndexedByteFunc)(TDFXPtr pTDFX, int addr,
+ char index, char value);
+typedef char (*TDFXReadIndexedByteFunc)(TDFXPtr pTDFX, int addr,
+ char index);
+typedef void (*TDFXWriteWordFunc)(TDFXPtr pTDFX, int addr, int value);
+typedef int (*TDFXReadWordFunc)(TDFXPtr pTDFX, int addr);
+typedef void (*TDFXSyncFunc)(ScrnInfoPtr pScrn);
+
+typedef struct {
+ unsigned int vidcfg;
+ unsigned int vidpll;
+ unsigned int dacmode;
+ unsigned int vgainit0;
+ unsigned int vgainit1;
+ unsigned int screensize;
+ unsigned int stride;
+ unsigned int cursloc;
+ unsigned int startaddr;
+ unsigned int clip0min;
+ unsigned int clip0max;
+ unsigned int clip1min;
+ unsigned int clip1max;
+ unsigned char ExtVga[2];
+} TDFXRegRec, *TDFXRegPtr;
+
+typedef struct _TDFXRec {
+ unsigned char *MMIOBase;
+ unsigned char *FbBase;
+ unsigned int PIOBase;
+ long FbMapSize;
+ int stride;
+ int cpp;
+ int maxClip;
+ int MaxClock;
+ int Chipset;
+ int LinearAddr;
+ int MMIOAddr;
+ EntityInfoPtr pEnt;
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ int HasSGRAM;
+ int PciCnt;
+ int DrawState;
+ int Cmd;
+ BoxRec prevBlitDest;
+ TDFXRegRec SavedReg;
+ TDFXRegRec ModeReg;
+ XAAInfoRecPtr AccelInfoRec;
+ xf86CursorInfoPtr CursorInfoRec;
+ CloseScreenProcPtr CloseScreen;
+ Bool usePIO;
+ Bool NoAccel;
+ DGAModePtr DGAModes;
+ Bool DGAactive;
+ int DGAViewportStatus;
+ int lowMemLoc;
+ int cursorOffset;
+ int fbOffset;
+ int texOffset;
+ TDFXWriteIndexedByteFunc writeControl;
+ TDFXReadIndexedByteFunc readControl;
+ TDFXWriteWordFunc writeLong;
+ TDFXReadWordFunc readLong;
+ TDFXSyncFunc sync;
+ int syncDone;
+#ifdef PROPDATA
+ PROPDATA;
+#endif
+#ifdef XF86DRI
+ Bool directRenderingEnabled;
+ DRIInfoPtr pDRIInfo;
+ int drmSubFD;
+ int numVisualConfigs;
+ __GLXvisualConfig* pVisualConfigs;
+ TDFXConfigPrivPtr pVisualConfigsPriv;
+ TDFXRegRec DRContextRegs;
+#endif
+} TDFXRec;
+
+#define TDFXPTR(p) ((TDFXPtr)((p)->driverPrivate))
+
+#define DRAW_STATE_CLIPPING 0x1
+#define DRAW_STATE_TRANSPARENT 0x2
+
+#define TDFX2XCUTOFF 135000
+
+extern Bool TDFXAccelInit(ScreenPtr pScreen);
+extern Bool TDFXCursorInit(ScreenPtr pScreen);
+extern void TDFXSync(ScrnInfoPtr pScrn);
+extern Bool TDFXDRIScreenInit(ScreenPtr pScreen);
+extern void TDFXDRICloseScreen(ScreenPtr pScreen);
+extern Bool TDFXDRIFinishScreenInit(ScreenPtr pScreen);
+extern Bool TDFXDGAInit(ScreenPtr pScreen);
+
+extern Bool TDFXSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+extern void TDFXAdjustFrame(int scrnIndex, int x, int y, int flags);
+
+extern void TDFXSetPIOAccess(TDFXPtr pTDFX);
+extern void TDFXSetMMIOAccess(TDFXPtr pTDFX);
+extern void TDFXWriteLongMMIO(TDFXPtr pTDFX, int addr, int val);
+extern int TDFXReadLongMMIO(TDFXPtr pTDFX, int addr);
+
+extern void TDFXNeedSync(ScrnInfoPtr pScrn);
+extern void TDFXCheckSync(ScrnInfoPtr pScrn);
+
+#endif
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_accel.c
new file mode 100644
index 000000000..cd8a89ea3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_accel.c
@@ -0,0 +1,511 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_accel.c,v 1.1 1999/08/29 12:21:02 dawes Exp $ */
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that use XAA need this */
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xf86fbman.h"
+
+#include "tdfx.h"
+
+#ifndef PROP_3DFX
+#define TDFXWriteLong(p, a, v) TDFXWriteLongMMIO(p, a, v)
+#define DECLARE(a)
+#define TDFXMakeRoom(p, n) TDFXMakeRoomNoProp(p, n)
+#endif
+
+static int TDFXROPCvt[] = {0x00, 0x88, 0x44, 0xCC, 0x22, 0xAA, 0x66, 0xEE,
+ 0x11, 0x99, 0x55, 0xDD, 0x33, 0xBB, 0x77, 0xFF,
+ 0x00, 0xA0, 0x50, 0xF0, 0x0A, 0xAA, 0x5A, 0xFA,
+ 0x05, 0xA5, 0x55, 0xF5, 0x0F, 0xAF, 0x5F, 0xFF};
+#define ROP_PATTERN_OFFSET 16
+
+#ifndef PROP_3DFX
+static void TDFXMakeRoom(TDFXPtr pTDFX, int size);
+#endif
+static void TDFXSetClippingRectangle(ScrnInfoPtr pScrn, int left, int top,
+ int right, int bottom);
+static void TDFXDisableClipping(ScrnInfoPtr pScrn);
+static void TDFXSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir,
+ int ydir, int rop,
+ unsigned int planemask,
+ int trans_color);
+static void TDFXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX,
+ int srcY, int dstX, int dstY,
+ int w, int h);
+static void TDFXSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+static void TDFXSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h);
+static void TDFXSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx,
+ int paty, int fg, int bg, int rop,
+ unsigned int planemask);
+static void TDFXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx,
+ int pay, int x, int y,
+ int w, int h);
+static void TDFXSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+static void TDFXSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int srcx,
+ int srcy, int dstx, int dsty,
+ int flags);
+static void TDFXSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y,
+ int len, int dir);
+#if 0
+static void TDFXNonTEGlyphRenderer(ScrnInfoPtr pScrn, int x, int y, int n,
+ NonTEGlyphPtr glyphs, BoxPtr pbox, int fg,
+ int rop, unsigned int planemask);
+#endif
+
+void
+TDFXNeedSync(ScrnInfoPtr pScrn) {
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+ pTDFX->syncDone=FALSE;
+}
+
+static void
+TDFXFirstSync(ScrnInfoPtr pScrn) {
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+
+ if (!pTDFX->syncDone) {
+ pTDFX->sync(pScrn);
+ pTDFX->syncDone=TRUE;
+ }
+}
+
+void
+TDFXCheckSync(ScrnInfoPtr pScrn) {
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+
+ if (pTDFX->syncDone) {
+ pTDFX->sync(pScrn);
+ pTDFX->syncDone=FALSE;
+ }
+}
+
+Bool
+TDFXAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+ CARD32 commonFlags;
+
+ pTDFX->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ infoPtr->Flags = PIXMAP_CACHE |
+ OFFSCREEN_PIXMAPS |
+ LINEAR_FRAMEBUFFER |
+ MICROSOFT_ZERO_LINE_BIAS;
+
+ infoPtr->Sync = pTDFX->sync;
+ infoPtr->SetClippingRectangle = TDFXSetClippingRectangle;
+ infoPtr->DisableClipping = TDFXDisableClipping;
+ infoPtr->ClippingFlags = HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND |
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
+ HARDWARE_CLIP_MONO_8x8_FILL |
+ HARDWARE_CLIP_COLOR_8x8_FILL |
+ HARDWARE_CLIP_SOLID_FILL |
+ HARDWARE_CLIP_DASHED_LINE |
+ HARDWARE_CLIP_SOLID_LINE;
+
+ commonFlags = BIT_ORDER_IN_BYTE_MSBFIRST | NO_PLANEMASK;
+
+ infoPtr->SetupForScreenToScreenCopy = TDFXSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy = TDFXSubsequentScreenToScreenCopy;
+ infoPtr->ScreenToScreenCopyFlags = commonFlags;
+
+ infoPtr->SetupForSolidFill = TDFXSetupForSolidFill;
+ infoPtr->SubsequentSolidFillRect = TDFXSubsequentSolidFillRect;
+ infoPtr->SolidFillFlags = commonFlags;
+
+ infoPtr->SetupForMono8x8PatternFill = TDFXSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect = TDFXSubsequentMono8x8PatternFillRect;
+ infoPtr->Mono8x8PatternFillFlags = commonFlags |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
+ HARDWARE_PATTERN_SCREEN_ORIGIN;
+
+ infoPtr->SetupForSolidLine = TDFXSetupForSolidLine;
+ infoPtr->SubsequentSolidTwoPointLine = TDFXSubsequentSolidTwoPointLine;
+ infoPtr->SubsequentSolidHorVertLine = TDFXSubsequentSolidHorVertLine;
+ infoPtr->SolidLineFlags = commonFlags;
+
+#if 0
+ infoPtr->NonTEGlyphRenderer = TDFXNonTEGlyphRenderer;
+ infoPtr->NonTEGlyphRendererFlags = commonFlags;
+
+ infoPtr->TEGlyphRenderer = TDFXTEGlyphRenderer;
+ infoPtr->TEGlyphRendererFlags = commonFlags;
+#endif
+
+ infoPtr->CPUToScreenColorExpandFillFlags = commonFlags;
+
+ pTDFX->PciCnt=TDFXReadLongMMIO(pTDFX, 0)&0x1F;
+ pTDFX->DrawState=0;
+
+ TDFXWriteLongMMIO(pTDFX, SST_2D_SRCBASEADDR, pTDFX->fbOffset);
+ TDFXWriteLongMMIO(pTDFX, SST_2D_DSTBASEADDR, pTDFX->fbOffset);
+
+ /* Fill in acceleration functions */
+ return XAAInit(pScreen, infoPtr);
+}
+
+static void TDFXMakeRoomNoProp(TDFXPtr pTDFX, int size) {
+ int stat;
+
+ pTDFX->PciCnt-=size;
+ if (pTDFX->PciCnt<1) {
+ do {
+ stat=TDFXReadLongMMIO(pTDFX, 0);
+ pTDFX->PciCnt=stat&0x1F;
+ } while (pTDFX->PciCnt<size);
+ }
+}
+
+void TDFXSync(ScrnInfoPtr pScrn)
+{
+ TDFXPtr pTDFX;
+ int i;
+ int stat;
+
+ TDFXTRACEACCEL("TDFXSync start\n");
+ pTDFX=TDFXPTR(pScrn);
+ TDFXMakeRoomNoProp(pTDFX, 1);
+ TDFXWriteLongMMIO(pTDFX, SST_3D_COMMAND, SST_3D_NOP);
+ i=0;
+ do {
+ stat=TDFXReadLongMMIO(pTDFX, 0);
+ if (stat&SST_BUSY) i=0; else i++;
+ } while (i<3);
+ pTDFX->PciCnt=stat&0x1F;
+}
+
+static void
+TDFXMatchState(TDFXPtr pTDFX)
+{
+#ifdef PROP_3DFX
+ /* FLUSH_WCB(); !!! Is this really needed? !!! */
+#endif
+ if (pTDFX->DrawState&DRAW_STATE_CLIPPING)
+ pTDFX->Cmd |= BIT(23);
+ else
+ pTDFX->Cmd &= ~BIT(23);
+ if (pTDFX->DrawState&DRAW_STATE_TRANSPARENT) {
+ TDFXMakeRoom(pTDFX, 1);
+ DECLARE(SSTCP_COMMANDEXTRA);
+ TDFXWriteLong(pTDFX, SST_2D_COMMANDEXTRA, 0);
+ pTDFX->DrawState&=~DRAW_STATE_TRANSPARENT;
+ }
+}
+
+static void
+TDFXSetClippingRectangle(ScrnInfoPtr pScrn, int left, int top, int right,
+ int bottom)
+{
+ TDFXPtr pTDFX;
+
+ TDFXTRACEACCEL("TDFXSetClippingRectangle start\n");
+ pTDFX=TDFXPTR(pScrn);
+ TDFXMakeRoom(pTDFX, 2);
+ DECLARE(SSTCP_CLIP1MIN|SSTCP_CLIP1MAX);
+ TDFXWriteLong(pTDFX, SST_2D_CLIP1MIN, (top&0xFFF)<<16 | (left&0xFFF));
+ TDFXWriteLong(pTDFX, SST_2D_CLIP1MAX, ((bottom+1)&0xFFF)<<16 |
+ ((right+1)&0xFFF));
+ pTDFX->DrawState|=DRAW_STATE_CLIPPING;
+}
+
+static void
+TDFXDisableClipping(ScrnInfoPtr pScrn)
+{
+ TDFXPtr pTDFX;
+
+ TDFXTRACEACCEL("TDFXDisableClippingRectangle start\n");
+ pTDFX=TDFXPTR(pScrn);
+ pTDFX->DrawState&=~DRAW_STATE_CLIPPING;
+}
+
+static void
+TDFXSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
+ unsigned int planemask, int trans_color)
+{
+ TDFXPtr pTDFX;
+ int fmt;
+
+ TDFXTRACEACCEL("TDFXSetupForScreenToScreenCopy start\n xdir=%d ydir=%d rop=%d planemask=%d trans_color=%d\n", xdir, ydir, rop, planemask, trans_color);
+ pTDFX=TDFXPTR(pScrn);
+ TDFXFirstSync(pScrn);
+ if (trans_color!=-1) {
+ TDFXMakeRoom(pTDFX, 4);
+ DECLARE(SSTCP_SRCCOLORKEYMIN|SSTCP_SRCCOLORKEYMAX|
+ SSTCP_ROP|SSTCP_COMMANDEXTRA);
+ TDFXWriteLong(pTDFX, SST_2D_SRCCOLORKEYMIN, trans_color);
+ TDFXWriteLong(pTDFX, SST_2D_SRCCOLORKEYMAX, trans_color);
+ TDFXWriteLong(pTDFX, SST_2D_ROP, TDFXROPCvt[GXinvert]<<8);
+ TDFXWriteLong(pTDFX, SST_2D_COMMANDEXTRA, SST_2D_SRC_COLORKEY_EX);
+ pTDFX->DrawState|=DRAW_STATE_TRANSPARENT;
+ }
+ pTDFX->Cmd = (TDFXROPCvt[rop]<<24) | SST_2D_SCRNTOSCRNBLIT;
+ if (xdir==-1) pTDFX->Cmd |= SST_2D_X_RIGHT_TO_LEFT;
+ if (ydir==-1) pTDFX->Cmd |= SST_2D_Y_BOTTOM_TO_TOP;
+ if (pTDFX->cpp==1) fmt=pTDFX->stride|(1<<16);
+ else fmt=pTDFX->stride|((pTDFX->cpp+1)<<16);
+ TDFXMakeRoom(pTDFX, 2);
+ DECLARE(SSTCP_SRCFORMAT|SSTCP_DSTFORMAT);
+ TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, fmt);
+ TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, fmt);
+}
+
+static void
+TDFXSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX, int srcY,
+ int dstX, int dstY, int w, int h)
+{
+ TDFXPtr pTDFX;
+
+ TDFXTRACEACCEL("TDFXSubsequentScreenToScreenCopy start\n srcX=%d srcY=%d dstX=%d dstY=%d w=%d h=%d\n", srcX, srcY, dstX, dstY, w, h);
+ pTDFX=TDFXPTR(pScrn);
+ if (pTDFX->Cmd&BIT(15)) {
+ srcY += h-1;
+ dstY += h-1;
+ }
+ if (pTDFX->Cmd&BIT(14)) {
+ srcX += w-1;
+ dstX += w-1;
+ }
+ pTDFX->Cmd|=SST_2D_GO;
+ TDFXMatchState(pTDFX);
+ /* Board hangs if you send sequential overlapping blits */
+ if (!((srcX+w<pTDFX->prevBlitDest.x1) || (srcX>pTDFX->prevBlitDest.x2) ||
+ (srcY+h<pTDFX->prevBlitDest.y1) || (srcY>pTDFX->prevBlitDest.y2))) {
+ TDFXMakeRoom(pTDFX, 1);
+ DECLARE(SSTCP_COMMAND);
+ TDFXWriteLong(pTDFX, SST_2D_COMMAND, SST_2D_NOP|SST_2D_GO);
+ }
+ TDFXMakeRoom(pTDFX, 4);
+ DECLARE(SSTCP_DSTSIZE|SSTCP_DSTXY|SSTCP_SRCXY|SSTCP_COMMAND);
+ TDFXWriteLong(pTDFX, SST_2D_SRCXY, (srcX&0x1FFF) | ((srcY&0x1FFF)<<16));
+ TDFXWriteLong(pTDFX, SST_2D_DSTSIZE, (w&0x1FFF) | ((h&0x1FFF)<<16));
+ TDFXWriteLong(pTDFX, SST_2D_DSTXY, (dstX&0x1FFF) | ((dstY&0x1FFF)<<16));
+ TDFXWriteLong(pTDFX, SST_2D_COMMAND, pTDFX->Cmd);
+ if (pTDFX->DrawState&DRAW_STATE_TRANSPARENT) {
+ TDFXMakeRoom(pTDFX, 1);
+ DECLARE(SSTCP_COMMANDEXTRA);
+ TDFXWriteLong(pTDFX, SST_2D_COMMANDEXTRA, 0);
+ pTDFX->DrawState&=~DRAW_STATE_TRANSPARENT;
+ }
+ pTDFX->prevBlitDest.x1=dstX;
+ pTDFX->prevBlitDest.x2=dstX+w-1;
+ pTDFX->prevBlitDest.y1=dstY;
+ pTDFX->prevBlitDest.y2=dstY+h-1;
+}
+
+static void
+TDFXSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ TDFXPtr pTDFX;
+ int fmt;
+
+ TDFXTRACEACCEL("TDFXSetupForSolidFill start color=%d rop=%d planemask=%d\n", color, rop, planemask);
+ pTDFX=TDFXPTR(pScrn);
+ pTDFX->Cmd=TDFXROPCvt[rop]<<24;
+ if (pTDFX->cpp==1) fmt=(1<<16)|pTDFX->stride;
+ else fmt=((pTDFX->cpp+1)<<16)|pTDFX->stride;
+ TDFXFirstSync(pScrn);
+ TDFXMakeRoom(pTDFX, 3);
+ DECLARE(SSTCP_DSTFORMAT|SSTCP_COLORFORE|
+ SSTCP_COLORBACK);
+ TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, fmt);
+ TDFXWriteLong(pTDFX, SST_2D_COLORBACK, color);
+ TDFXWriteLong(pTDFX, SST_2D_COLORFORE, color);
+}
+
+static void
+TDFXSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ TDFXPtr pTDFX;
+
+ TDFXTRACEACCEL("TDFXSubsequentSolidFillRect start x=%d y=%d w=%d h=%d\n", x, y, w, h);
+ pTDFX=TDFXPTR(pScrn);
+ TDFXMatchState(pTDFX);
+ TDFXMakeRoom(pTDFX, 3);
+ DECLARE(SSTCP_DSTSIZE|SSTCP_DSTXY|SSTCP_COMMAND);
+ TDFXWriteLong(pTDFX, SST_2D_DSTSIZE, ((h&0x1FFF)<<16) | (w&0x1FFF));
+ TDFXWriteLong(pTDFX, SST_2D_DSTXY, ((y&0x1FFF)<<16) | (x&0x1FFF));
+ TDFXWriteLong(pTDFX, SST_2D_COMMAND, SST_2D_RECTANGLEFILL|pTDFX->Cmd|SST_2D_GO);
+}
+
+static void
+TDFXSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
+ int fg, int bg, int rop, unsigned int planemask)
+{
+ TDFXPtr pTDFX;
+ int fmt;
+
+ TDFXTRACEACCEL("TDFXSetupForMono8x8PatternFill start patx=%x paty=%x fg=%d bg=%d rop=%d planemask=%d\n", patx, paty, fg, bg, rop, planemask);
+ pTDFX=TDFXPTR(pScrn);
+ pTDFX->Cmd = (TDFXROPCvt[rop+ROP_PATTERN_OFFSET]<<24) | SST_2D_MONOCHROME_PATTERN;
+ if (bg==-1) {
+ pTDFX->Cmd |= SST_2D_TRANSPARENT_MONOCHROME;
+ }
+
+ if (pTDFX->cpp==1) fmt=(1<<16)|pTDFX->stride;
+ else fmt=((pTDFX->cpp+1)<<16)|pTDFX->stride;
+ TDFXFirstSync(pScrn);
+ TDFXMakeRoom(pTDFX, 5);
+ DECLARE(SSTCP_DSTFORMAT|SSTCP_PATTERN0ALIAS
+ |SSTCP_PATTERN1ALIAS|SSTCP_COLORFORE|
+ SSTCP_COLORBACK);
+ TDFXWriteLong(pTDFX, SST_2D_DSTFORMAT, fmt);
+ TDFXWriteLong(pTDFX, SST_2D_PATTERN0, patx);
+ TDFXWriteLong(pTDFX, SST_2D_PATTERN1, paty);
+ TDFXWriteLong(pTDFX, SST_2D_COLORBACK, bg);
+ TDFXWriteLong(pTDFX, SST_2D_COLORFORE, fg);
+}
+
+static void
+TDFXSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty,
+ int x, int y, int w, int h)
+{
+ TDFXPtr pTDFX;
+
+ TDFXTRACEACCEL("TDFXSubsequentMono8x8PatternFillRect start patx=%x paty=%x x=%d y=%d w=%d h=%d\n", patx, paty, x, y, w, h);
+ pTDFX=TDFXPTR(pScrn);
+ pTDFX->Cmd |= ((patx&0x7)<<SST_2D_X_PATOFFSET_SHIFT) |
+ ((paty&0x7)<<SST_2D_Y_PATOFFSET_SHIFT);
+ TDFXMatchState(pTDFX);
+ TDFXSubsequentSolidFillRect(pScrn, x, y, w, h);
+}
+
+static void
+TDFXSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ TDFXPtr pTDFX;
+
+ TDFXTRACEACCEL("TDFXSetupForSolidLine start\n");
+ pTDFX=TDFXPTR(pScrn);
+ pTDFX->Cmd = (TDFXROPCvt[rop]<<24) | SST_2D_MONOCHROME_PATTERN;
+ TDFXFirstSync(pScrn);
+ TDFXMakeRoom(pTDFX, 2);
+ DECLARE(SSTCP_COLORFORE|SSTCP_COLORBACK);
+ TDFXWriteLong(pTDFX, SST_2D_COLORBACK, color);
+ TDFXWriteLong(pTDFX, SST_2D_COLORFORE, color);
+}
+
+static void
+TDFXSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int srcx, int srcy,
+ int dstx, int dsty, int flags)
+{
+ TDFXPtr pTDFX;
+
+ TDFXTRACEACCEL("TDFXSubsequentSolidTwoPointLine start\n");
+ pTDFX=TDFXPTR(pScrn);
+ if (flags&OMIT_LAST) pTDFX->Cmd|=SST_2D_POLYLINE;
+ else pTDFX->Cmd|=SST_2D_LINE;
+ TDFXMatchState(pTDFX);
+ TDFXMakeRoom(pTDFX, 3);
+ DECLARE(SSTCP_SRCXY|SSTCP_DSTXY|SSTCP_COMMAND);
+ TDFXWriteLong(pTDFX, SST_2D_SRCXY, (srcy&0x1FFF)<<16 | (srcx&0x1FFF));
+ TDFXWriteLong(pTDFX, SST_2D_DSTXY, (dsty&0x1FFF)<<16 | (dstx&0x1FFF));
+ TDFXWriteLong(pTDFX, SST_2D_COMMAND, pTDFX->Cmd|SST_2D_GO);
+}
+
+static void
+TDFXSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len,
+ int dir)
+{
+ TDFXPtr pTDFX;
+
+ TDFXTRACEACCEL("TDFXSubsequentSolidHorVertLine start\n");
+ pTDFX=TDFXPTR(pScrn);
+ TDFXMatchState(pTDFX);
+ TDFXMakeRoom(pTDFX, 3);
+ DECLARE(SSTCP_SRCXY|SSTCP_DSTXY|SSTCP_COMMAND);
+ TDFXWriteLong(pTDFX, SST_2D_SRCXY, (y&0x1FFF)<<16 | (x&0x1FFF));
+ if (dir == DEGREES_0)
+ TDFXWriteLong(pTDFX, SST_2D_DSTXY, (y&0x1FFF)<<16 | ((x+len)&0x1FFF));
+ else
+ TDFXWriteLong(pTDFX, SST_2D_DSTXY, ((y+len)&0x1FFF)<<16 | (x&0x1FFF));
+ TDFXWriteLong(pTDFX, SST_2D_COMMAND, pTDFX->Cmd|SST_2D_POLYLINE|SST_2D_GO);
+}
+
+#if 0
+static void
+TDFXNonTEGlyphRenderer(ScrnInfoPtr pScrn, int x, int y, int n,
+ NonTEGlyphPtr glyphs, BoxPtr pbox, int fg, int rop,
+ unsigned int planemask)
+{
+ TDFXPtr pTDFX;
+ int ndwords;
+ int g;
+ int clip0min, clip0max, srcformat;
+
+ TDFXTRACEACCEL("TDFXNonTEGlyphRenderer start\n");
+ pTDFX = TDFXPTR(pScrn);
+ clip0min=TDFXReadLongMMIO(pTDFX, SST_2D_CLIP0MIN);
+ clip0max=TDFXReadLongMMIO(pTDFX, SST_2D_CLIP0MAX);
+ srcformat=TDFXReadLongMMIO(pTDFX, SST_2D_SRCFORMAT);
+ TDFXMakeRoom(pTDFX, 6);
+ DECLARE(SSTCP_CLIP0MIN|SSTCP_CLIP0MAX|SSTCP_SRCFORMAT|
+ SSTCP_SRCXY|SSTCP_COLORFORE|SSTCP_COMMAND);
+ TDFXWriteLong(pTDFX, SST_2D_CLIP0MIN, (pbox->y1<<16) | pbox->x1);
+ TDFXWriteLong(pTDFX, SST_2D_CLIP0MAX, (pbox->u2<<16) | pbox->x2);
+ TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, SST_2D_SRC_PIXFMT_1BPP |
+ SST_2D_SOURCE_PACKING_WORD);
+ TDFXWriteLong(pTDFX, SST_2D_SRCXY, 0);
+ TDFXWriteLong(pTDFX, SST_2D_COLORFORE, fg);
+ TDFXWriteLong(pTDFX, SST_2D_COMMAND, pTDFX->Cmd | (TDFXROPCvt[rop]<<24) |
+ SST_2D_TRANSPARENT_MONOCHROME | SST_2D_SCRNTOSCRNBLIT);
+ for (g=0, glyph=glyphs; g<n; g++, glyph++) {
+ int dx = x+glyph->start;
+ int dy = y-glyph->yoff;
+ char *bitmap = glyph->bits;
+ int w = glyph->end - glyph->start;
+
+ ndwords = (glyph->srcwidth+31)>>5;
+ ndwords *= glyph->height;
+
+ TDFXMakeRoom(pTDFX, 2);
+ DECLARE(SSTCP_DSTSIZE|SSTCP_DSTXY);
+ TDFXWriteLong(pTDFX, SST_2D_DSTSIZE, (glyph->height<<16)|w);
+ TDFXWriteLong(pTDFX, SST_2D_DSTXY, (dy<<16)|dx&0xFFFF);
+
+ do {
+ int i = ndwords;
+ int j;
+ int *glyph_data = (int*)bitmap;
+ int dwords_per_line = (glyph->srcwidth+3)>>2;
+
+ /* !!! This needs to change to for proprietary interface !!! */
+ if (i>LAUNCH_AREA_SIZE) i=LAUNCH_AREA_SIZE;
+ TDFXMakeRoom(pTDFX, i);
+ for (j=0; j<i; j++) {
+ TDFXWriteLong(pTDFX, SST_2D_LAUNCH+j, XAAReverseBitOrder(*glyph_data));
+ glyph_data += dwords_per_line;
+ }
+ bitmap += i*4;
+ ndwords -= i;
+ } while (ndwords);
+ }
+
+ TDFXMakeRoom(pTDFX, 3);
+ DECLARE(SSTCP_CLIP0MIN|SSTCP_CLIP0MAX|SSTCP_SRCFORMAT);
+ TDFXWriteLong(pTDFX, SST_2D_CLIP0MIN, clip0min);
+ TDFXWriteLong(pTDFX, SST_2D_CLIP0MAX, clip0max);
+ TDFXWriteLong(pTDFX, SST_2D_SRCFORMAT, srcformat);
+}
+#endif
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dga.c b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dga.c
new file mode 100644
index 000000000..fa84f3a61
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dga.c
@@ -0,0 +1,223 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dga.c,v 1.1 1999/08/29 12:21:03 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "dgaproc.h"
+
+#include "tdfx.h"
+
+static Bool TDFX_OpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
+ int *, int *, int *);
+static Bool TDFX_SetMode(ScrnInfoPtr, DGAModePtr);
+static int TDFX_GetViewport(ScrnInfoPtr);
+static void TDFX_SetViewport(ScrnInfoPtr, int, int, int);
+static void TDFX_FillRect(ScrnInfoPtr, int, int, int, int, unsigned long);
+static void TDFX_BlitRect(ScrnInfoPtr, int, int, int, int, int, int);
+static void TDFX_BlitTransRect(ScrnInfoPtr, int, int, int, int, int, int,
+ unsigned long);
+
+
+static
+DGAFunctionRec TDFX_DGAFuncs = {
+ TDFX_OpenFramebuffer,
+ 0,
+ TDFX_SetMode,
+ TDFX_SetViewport,
+ TDFX_GetViewport,
+ TDFXSync,
+ TDFX_FillRect,
+ TDFX_BlitRect,
+ TDFX_BlitTransRect
+};
+
+Bool
+TDFXDGAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TDFXPtr pTDFX;
+ DisplayModePtr pMode, firstMode;
+ DGAModePtr modes=0, newmodes=0, currentMode;
+ int num=0;
+ Bool oneMore;
+
+ pTDFX = TDFXPTR(pScrn);
+ pMode = firstMode = pScrn->modes;
+
+ while (pMode) {
+ newmodes = xrealloc(modes, (num+1)*sizeof(DGAModeRec));
+ oneMore = FALSE;
+ if (!newmodes) {
+ xfree(modes);
+ return FALSE;
+ }
+ modes = newmodes;
+
+SECOND_PASS:
+
+ currentMode = modes+num;
+ num++;
+ currentMode->mode = pMode;
+ currentMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
+ if (!pTDFX->NoAccel)
+ currentMode->flags |= DGA_FILL_RECT | DGA_BLIT_RECT;
+ if (pMode->Flags & V_DBLSCAN)
+ currentMode->flags |= DGA_DOUBLESCAN;
+ if (pMode->Flags & V_INTERLACE)
+ currentMode->flags |= DGA_INTERLACED;
+ currentMode->byteOrder = pScrn->imageByteOrder;
+ currentMode->depth = pScrn->depth;
+ currentMode->bitsPerPixel = pScrn->bitsPerPixel;
+ currentMode->red_mask = pScrn->mask.red;
+ currentMode->green_mask = pScrn->mask.green;
+ currentMode->blue_mask = pScrn->mask.blue;
+ currentMode->viewportWidth = pMode->HDisplay;
+ currentMode->viewportHeight = pMode->VDisplay;
+ currentMode->xViewportStep = (3 - pTDFX->cpp);
+ currentMode->yViewportStep = 1;
+ currentMode->viewportFlags = DGA_FLIP_RETRACE;
+ currentMode->offset = 0;
+ currentMode->address = pTDFX->FbBase;
+
+ if (oneMore) { /* first one is narrow width */
+ currentMode->bytesPerScanline = ((pMode->HDisplay * pTDFX->cpp) + 3) & ~3L;
+ currentMode->imageWidth = pMode->HDisplay;
+ currentMode->imageHeight = pScrn->virtualY;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+ oneMore = FALSE;
+ goto SECOND_PASS;
+ } else {
+ currentMode->bytesPerScanline = ((pScrn->displayWidth * pTDFX->cpp) + 3) & ~3L;
+ currentMode->imageWidth = pScrn->displayWidth;
+ currentMode->imageHeight = pScrn->virtualY;
+ currentMode->pixmapWidth = currentMode->imageWidth;
+ currentMode->pixmapHeight = currentMode->imageHeight;
+ currentMode->maxViewportX = currentMode->imageWidth -
+ currentMode->viewportWidth;
+ /* this might need to get clamped to some maximum */
+ currentMode->maxViewportY = currentMode->imageHeight -
+ currentMode->viewportHeight;
+ }
+
+ pMode = pMode->next;
+ if (pMode == firstMode) break;
+ }
+
+ pTDFX->DGAModes = modes;
+
+ return DGAInit(pScreen, &TDFX_DGAFuncs, modes, num);
+}
+
+static Bool
+TDFX_SetMode(ScrnInfoPtr pScrn, DGAModePtr pMode)
+{
+ static int OldDisplayWidth[MAXSCREENS];
+ int index = pScrn->pScreen->myNum;
+
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+
+ if (!pMode) { /* restore the original mode */
+ /* put the ScreenParameters back */
+ pScrn->displayWidth = OldDisplayWidth[index];
+ TDFXSwitchMode(index, pScrn->currentMode, 0);
+ pTDFX->DGAactive = FALSE;
+ } else {
+ if (!pTDFX->DGAactive) { /* save the old parameters */
+ OldDisplayWidth[index] = pScrn->displayWidth;
+
+ pTDFX->DGAactive = TRUE;
+ }
+
+ pScrn->displayWidth = pMode->bytesPerScanline / pTDFX->cpp;
+
+ TDFXSwitchMode(index, pMode->mode, 0);
+ }
+
+ return TRUE;
+}
+
+static int
+TDFX_GetViewport(ScrnInfoPtr pScrn)
+{
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+
+ return pTDFX->DGAViewportStatus;
+}
+
+static void
+TDFX_SetViewport(ScrnInfoPtr pScrn, int x, int y, int flags)
+{
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+
+ TDFXAdjustFrame(pScrn->pScreen->myNum, x, y, flags);
+ pTDFX->DGAViewportStatus = 0; /* TDFXAdjustFrame loops until finished */
+}
+
+static void
+TDFX_FillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned long color)
+{
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+
+ if (pTDFX->AccelInfoRec) {
+ (*pTDFX->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0);
+ (*pTDFX->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ }
+}
+
+static void
+TDFX_BlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h,
+ int dstx, int dsty)
+{
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+
+ if (pTDFX->AccelInfoRec) {
+ int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
+ int ydir = (srcy < dsty) ? -1 : 1;
+
+ (*pTDFX->AccelInfoRec->SetupForScreenToScreenCopy)(pScrn, xdir, ydir,
+ GXcopy, ~0, -1);
+ (*pTDFX->AccelInfoRec->SubsequentScreenToScreenCopy)(pScrn, srcx, srcy,
+ dstx, dsty, w, h);
+ }
+}
+
+
+static void
+TDFX_BlitTransRect(
+ ScrnInfoPtr pScrn,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty,
+ unsigned long color
+){
+ /* this one should be separate since the XAA function would
+ prohibit usage of ~0 as the key */
+}
+
+
+static Bool
+TDFX_OpenFramebuffer(
+ ScrnInfoPtr pScrn,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *flags
+){
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+
+ *name = NULL; /* no special device */
+ *mem = (unsigned char*)pTDFX->FbBase;
+ *size = pTDFX->FbMapSize;
+ *offset = 0;
+ *flags = DGA_NEED_ROOT;
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c
new file mode 100644
index 000000000..0f43ecc5b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c
@@ -0,0 +1,398 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c,v 1.2 1999/08/30 01:25:04 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Priv.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb32.h"
+
+#include "miline.h"
+
+#include "GL/glxtokens.h"
+
+#include "tdfx.h"
+#include "tdfx_dri.h"
+#include "tdfx_dripriv.h"
+
+static char TDFXKernelDriverName[] = "generic";
+static char TDFXClientDriverName[] = "tdfx";
+
+static Bool TDFXInitVisualConfigs(ScreenPtr pScreen);
+static Bool TDFXCreateContext(ScreenPtr pScreen, VisualPtr visual,
+ drmContext hwContext, void *pVisualConfigPriv);
+static void TDFXDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
+ DRIContextType readContextType,
+ void **readContextStore,
+ DRIContextType writeContextType,
+ void **writeContextStore);
+static void TDFXDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index);
+static void TDFXDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc, CARD32 index);
+
+static Bool
+TDFXInitVisualConfigs(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+ int numConfigs = 0;
+ __GLXvisualConfig *pConfigs = 0;
+ TDFXConfigPrivPtr pTDFXConfigs = 0;
+ TDFXConfigPrivPtr *pTDFXConfigPtrs = 0;
+ int i;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ case 24:
+ case 32:
+ break;
+ case 16:
+ numConfigs = 4;
+
+ if (!(pConfigs = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig),
+ numConfigs))) {
+ return FALSE;
+ }
+ if (!(pTDFXConfigs = (TDFXConfigPrivPtr)xnfcalloc(sizeof(TDFXConfigPrivRec),
+ numConfigs))) {
+ xfree(pConfigs);
+ return FALSE;
+ }
+ if (!(pTDFXConfigPtrs = (TDFXConfigPrivPtr*)xnfcalloc(sizeof(TDFXConfigPrivPtr),
+ numConfigs))) {
+ xfree(pConfigs);
+ xfree(pTDFXConfigs);
+ return FALSE;
+ }
+ for (i=0; i<numConfigs; i++)
+ pTDFXConfigPtrs[i] = &pTDFXConfigs[i];
+
+ /* config 0: db=FALSE, depth=0
+ config 1: db=FALSE, depth=16
+ config 2: db=TRUE, depth=0;
+ config 3: db=TRUE, depth=16
+ */
+ pConfigs[0].vid = -1;
+ pConfigs[0].class = -1;
+ pConfigs[0].rgba = TRUE;
+ pConfigs[0].redSize = 8;
+ pConfigs[0].greenSize = 8;
+ pConfigs[0].blueSize = 8;
+ pConfigs[0].redMask = 0x00FF0000;
+ pConfigs[0].greenMask = 0x0000FF00;
+ pConfigs[0].blueMask = 0x000000FF;
+ pConfigs[0].alphaMask = 0;
+ pConfigs[0].accumRedSize = 0;
+ pConfigs[0].accumGreenSize = 0;
+ pConfigs[0].accumBlueSize = 0;
+ pConfigs[0].accumAlphaSize = 0;
+ pConfigs[0].doubleBuffer = FALSE;
+ pConfigs[0].stereo = FALSE;
+ pConfigs[0].bufferSize = 16;
+ pConfigs[0].depthSize = 0;
+ pConfigs[0].stencilSize = 0;
+ pConfigs[0].auxBuffers = 0;
+ pConfigs[0].level = 0;
+ pConfigs[0].visualRating = 0;
+ pConfigs[0].transparentPixel = 0;
+ pConfigs[0].transparentRed = 0;
+ pConfigs[0].transparentGreen = 0;
+ pConfigs[0].transparentBlue = 0;
+ pConfigs[0].transparentAlpha = 0;
+ pConfigs[0].transparentIndex = 0;
+
+ pConfigs[1].vid = -1;
+ pConfigs[1].class = -1;
+ pConfigs[1].rgba = TRUE;
+ pConfigs[1].redSize = 8;
+ pConfigs[1].greenSize = 8;
+ pConfigs[1].blueSize = 8;
+ pConfigs[1].redMask = 0x00FF0000;
+ pConfigs[1].greenMask = 0x0000FF00;
+ pConfigs[1].blueMask = 0x000000FF;
+ pConfigs[1].alphaMask = 0;
+ pConfigs[1].accumRedSize = 0;
+ pConfigs[1].accumGreenSize = 0;
+ pConfigs[1].accumBlueSize = 0;
+ pConfigs[1].accumAlphaSize = 0;
+ pConfigs[1].doubleBuffer = FALSE;
+ pConfigs[1].stereo = FALSE;
+ pConfigs[1].bufferSize = 16;
+ pConfigs[1].depthSize = 16;
+ pConfigs[1].stencilSize = 0;
+ pConfigs[1].auxBuffers = 0;
+ pConfigs[1].level = 0;
+ pConfigs[1].visualRating = 0;
+ pConfigs[1].transparentPixel = 0;
+ pConfigs[1].transparentRed = 0;
+ pConfigs[1].transparentGreen = 0;
+ pConfigs[1].transparentBlue = 0;
+ pConfigs[1].transparentAlpha = 0;
+ pConfigs[1].transparentIndex = 0;
+
+ pConfigs[2].vid = -1;
+ pConfigs[2].class = -1;
+ pConfigs[2].rgba = TRUE;
+ pConfigs[2].redSize = 8;
+ pConfigs[2].greenSize = 8;
+ pConfigs[2].blueSize = 8;
+ pConfigs[2].redMask = 0x00FF0000;
+ pConfigs[2].greenMask = 0x0000FF00;
+ pConfigs[2].blueMask = 0x000000FF;
+ pConfigs[2].alphaMask = 0;
+ pConfigs[2].accumRedSize = 0;
+ pConfigs[2].accumGreenSize = 0;
+ pConfigs[2].accumBlueSize = 0;
+ pConfigs[2].accumAlphaSize = 0;
+ pConfigs[2].doubleBuffer = TRUE;
+ pConfigs[2].stereo = FALSE;
+ pConfigs[2].bufferSize = 16;
+ pConfigs[2].depthSize = 0;
+ pConfigs[2].stencilSize = 0;
+ pConfigs[2].auxBuffers = 0;
+ pConfigs[2].level = 0;
+ pConfigs[2].visualRating = 0;
+ pConfigs[2].transparentPixel = 0;
+ pConfigs[2].transparentRed = 0;
+ pConfigs[2].transparentGreen = 0;
+ pConfigs[2].transparentBlue = 0;
+ pConfigs[2].transparentAlpha = 0;
+ pConfigs[2].transparentIndex = 0;
+
+ pConfigs[3].vid = -1;
+ pConfigs[3].class = -1;
+ pConfigs[3].rgba = TRUE;
+ pConfigs[3].redSize = 8;
+ pConfigs[3].greenSize = 8;
+ pConfigs[3].blueSize = 8;
+ pConfigs[3].redMask = 0x00FF0000;
+ pConfigs[3].greenMask = 0x0000FF00;
+ pConfigs[3].blueMask = 0x000000FF;
+ pConfigs[3].alphaMask = 0;
+ pConfigs[3].accumRedSize = 0;
+ pConfigs[3].accumGreenSize = 0;
+ pConfigs[3].accumBlueSize = 0;
+ pConfigs[3].accumAlphaSize = 0;
+ pConfigs[3].doubleBuffer = TRUE;
+ pConfigs[3].stereo = FALSE;
+ pConfigs[3].bufferSize = 16;
+ pConfigs[3].depthSize = 16;
+ pConfigs[3].stencilSize = 0;
+ pConfigs[3].auxBuffers = 0;
+ pConfigs[3].level = 0;
+ pConfigs[3].visualRating = 0;
+ pConfigs[3].transparentPixel = 0;
+ pConfigs[3].transparentRed = 0;
+ pConfigs[3].transparentGreen = 0;
+ pConfigs[3].transparentBlue = 0;
+ pConfigs[3].transparentAlpha = 0;
+ pConfigs[3].transparentIndex = 0;
+ break;
+ }
+ pTDFX->numVisualConfigs = numConfigs;
+ pTDFX->pVisualConfigs = pConfigs;
+ pTDFX->pVisualConfigsPriv = pTDFXConfigs;
+ GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pTDFXConfigPtrs);
+ return TRUE;
+}
+
+Bool TDFXDRIScreenInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+ DRIInfoPtr pDRIInfo;
+ TDFXDRIPtr pTDFXDRI;
+
+#if XFree86LOADER
+ if (!LoaderSymbol("GlxSetVisualConfigs")) return FALSE;
+ if (!LoaderSymbol("DRIScreenInit")) return FALSE;
+ if (!LoaderSymbol("drmAvailable")) return FALSE;
+#endif
+
+ pDRIInfo = DRICreateInfoRec();
+ if (!pDRIInfo) return FALSE;
+ pTDFX->pDRIInfo = pDRIInfo;
+
+ pDRIInfo->drmDriverName = TDFXKernelDriverName;
+ pDRIInfo->clientDriverName = TDFXClientDriverName;
+ pDRIInfo->busIdString = xalloc(64);
+ sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
+ ((pciConfigPtr)pTDFX->PciInfo->thisCard)->busnum,
+ ((pciConfigPtr)pTDFX->PciInfo->thisCard)->devnum,
+ ((pciConfigPtr)pTDFX->PciInfo->thisCard)->funcnum);
+ pDRIInfo->ddxDriverMajorVersion = 0;
+ pDRIInfo->ddxDriverMinorVersion = 1;
+ pDRIInfo->ddxDriverPatchVersion = 0;
+ pDRIInfo->frameBufferPhysicalAddress = pTDFX->LinearAddr;
+ pDRIInfo->frameBufferSize = pTDFX->FbMapSize;
+ pDRIInfo->frameBufferStride = pTDFX->stride;
+ pDRIInfo->ddxDrawableTableEntry = TDFX_MAX_DRAWABLES;
+
+ if (SAREA_MAX_DRAWABLES < TDFX_MAX_DRAWABLES)
+ pDRIInfo->maxDrawableTableEntry = SAREA_MAX_DRAWABLES;
+ else
+ pDRIInfo->maxDrawableTableEntry = TDFX_MAX_DRAWABLES;
+
+#ifdef NOT_DONE
+ /* FIXME need to extend DRI protocol to pass this size back to client
+ * for SAREA mapping that includes a device private record
+ */
+ pDRIInfo->SAREASize =
+ ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */
+ /* + shared memory device private rec */
+#else
+ /* For now the mapping works by using a fixed size defined
+ * in the SAREA header
+ */
+ pDRIInfo->SAREASize = SAREA_MAX;
+#endif
+
+ if (!(pTDFXDRI = (TDFXDRIPtr)xnfcalloc(sizeof(TDFXDRIRec),1))) {
+ DRIDestroyInfoRec(pTDFX->pDRIInfo);
+ pTDFX->pDRIInfo=0;
+ return FALSE;
+ }
+ pDRIInfo->devPrivate = pTDFXDRI;
+ pDRIInfo->devPrivateSize = sizeof(TDFXDRIRec);
+ pDRIInfo->contextSize = sizeof(TDFXDRIContextRec);
+
+ pDRIInfo->CreateContext = TDFXCreateContext;
+ pDRIInfo->SwapContext = TDFXDRISwapContext;
+ pDRIInfo->InitBuffers = TDFXDRIInitBuffers;
+ pDRIInfo->MoveBuffers = TDFXDRIMoveBuffers;
+ pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; /* !!! WHAT IS THIS? !!! */
+
+ if (!DRIScreenInit(pScreen, pDRIInfo, &pTDFX->drmSubFD)) {
+ xfree(pDRIInfo->devPrivate);
+ pDRIInfo->devPrivate=0;
+ DRIDestroyInfoRec(pTDFX->pDRIInfo);
+ pTDFX->pDRIInfo=0;
+ return FALSE;
+ }
+
+ pTDFXDRI->regsSize=TDFXIOMAPSIZE;
+ if (drmAddMap(pTDFX->drmSubFD, (drmHandle)pTDFX->MMIOAddr,
+ pTDFXDRI->regsSize, DRM_REGISTERS, 0, &pTDFXDRI->regs)<0) {
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08lx\n",
+ pTDFXDRI->regs);
+
+ if (!(TDFXInitVisualConfigs(pScreen))) {
+ DRICloseScreen(pScreen);
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "visual configs initialized\n" );
+
+ return TRUE;
+}
+
+void
+TDFXDRICloseScreen(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+
+ DRICloseScreen(pScreen);
+
+ if (pTDFX->pDRIInfo) {
+ if (pTDFX->pDRIInfo->devPrivate) {
+ xfree(pTDFX->pDRIInfo->devPrivate);
+ pTDFX->pDRIInfo->devPrivate=0;
+ }
+ DRIDestroyInfoRec(pTDFX->pDRIInfo);
+ pTDFX->pDRIInfo=0;
+ }
+ if (pTDFX->pVisualConfigs) xfree(pTDFX->pVisualConfigs);
+ if (pTDFX->pVisualConfigsPriv) xfree(pTDFX->pVisualConfigsPriv);
+}
+
+static Bool
+TDFXCreateContext(ScreenPtr pScreen, VisualPtr visual,
+ drmContext hwContext, void *pVisualConfigPriv)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+ TDFXConfigPrivPtr pTDFXConfig = (TDFXConfigPrivPtr)pVisualConfigPriv;
+
+ /* !!! I don't think we need anything here !!! */
+ return TRUE;
+}
+
+Bool
+TDFXDRIFinishScreenInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+ TDFXDRIPtr pTDFXDRI;
+ int size;
+
+ pTDFX->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;
+
+ pTDFXDRI=(TDFXDRIPtr)pTDFX->pDRIInfo->devPrivate;
+ pTDFXDRI->deviceID=pTDFX->PciInfo->chipType;
+ pTDFXDRI->cpp=pTDFX->cpp;
+ pTDFXDRI->stride=pTDFX->stride;
+#ifdef PROP_3DFX
+ FillPrivateDRI(pTDFX, pTDFXDRI);
+#endif
+ pTDFXDRI->textureOffset=pTDFX->texOffset;
+ pTDFXDRI->textureSize=4*1024*1024; /* !!! This should be calculated !!! */
+ pTDFXDRI->fbOffset=pTDFX->fbOffset;
+ pTDFXDRI->backOffset=(pTDFX->lowMemLoc+4095)&~0xFFF;
+ size=2*pScrn->virtualX*pScrn->virtualY;
+ pTDFXDRI->depthOffset=(pTDFXDRI->backOffset+size+4095)&~0xFFF;
+
+ return DRIFinishScreenInit(pScreen);
+}
+
+static void
+TDFXDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
+ DRIContextType readContextType, void **readContextStore,
+ DRIContextType writeContextType, void **writeContextStore)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+ TDFXDRIContextPtr pRC = (TDFXDRIContextPtr)readContextStore;
+ TDFXDRIContextPtr pWC = (TDFXDRIContextPtr)writeContextStore;
+
+ if ((syncType==DRI_3D_SYNC) && (readContextType==DRI_2D_CONTEXT) &&
+ (writeContextType==DRI_3D_CONTEXT)) {
+ /* Entering through wakeup handler */
+ TDFXNeedSync(pScrn);
+ }
+ if ((syncType==DRI_2D_SYNC) && (readContextType==DRI_NO_CONTEXT) &&
+ (writeContextType==DRI_2D_CONTEXT)) {
+ /* Exiting through block handler */
+ TDFXCheckSync(pScrn);
+ }
+}
+
+static void
+TDFXDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+
+ /* Setup ancillary buffers */
+ /* There really isn't setup to do */
+}
+
+static void
+TDFXDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc, CARD32 index)
+{
+ ScreenPtr pScreen = pParent->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TDFXPtr pTDFX = TDFXPTR(pScrn);
+
+ /* Move ancillary buffers */
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.h
new file mode 100644
index 000000000..d3da9edc7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.h
@@ -0,0 +1,24 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.h,v 1.1 1999/08/29 12:21:03 dawes Exp $ */
+
+#ifndef _TDFX_DRI_
+#define _TDFX_DRI_
+
+#include <xf86drm.h>
+
+typedef struct {
+ drmHandle regs;
+ drmSize regsSize;
+ drmAddress regsMap;
+ int deviceID;
+ int cpp;
+ int stride;
+ int priv1;
+ int priv2;
+ int fbOffset;
+ int backOffset;
+ int depthOffset;
+ int textureOffset;
+ int textureSize;
+} TDFXDRIRec, *TDFXDRIPtr;
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dripriv.h
new file mode 100644
index 000000000..70a1af32d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dripriv.h
@@ -0,0 +1,24 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dripriv.h,v 1.1 1999/08/29 12:21:03 dawes Exp $ */
+
+#ifndef _TDFX_DRIPRIV_H_
+#define _TDFX_DRIPRIV_H_
+
+#define TDFX_MAX_DRAWABLES 5
+
+extern void GlxSetVisualConfigs(
+ int nconfigs,
+ __GLXvisualConfig *configs,
+ void **configprivs
+);
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} TDFXConfigPrivRec, *TDFXConfigPrivPtr;
+
+typedef struct {
+ /* Nothing here yet */
+ int dummy;
+} TDFXDRIContextRec, *TDFXDRIContextPtr;
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c
new file mode 100644
index 000000000..ca35b5be2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c
@@ -0,0 +1,1681 @@
+
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c,v 1.1 1999/08/29 12:21:03 dawes Exp $ */
+
+/*
+ * Authors:
+ * Daryll Strauss <daryll@precisioninsight.com>
+ *
+ * $PI$
+ */
+
+/*
+ * This server does not support these XFree86 4.0 features yet
+ * DDC1 & DDC2 (requires I2C)
+ * shadowFb (if requested or acceleration is off)
+ * Overlay planes
+ * DGA
+ */
+
+/*
+ * These are X and server generic header files.
+ */
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86RAC.h"
+#include "xf86cmap.h"
+
+/* If the driver uses port I/O directly, it needs: */
+
+#include "compiler.h"
+
+/* Drivers using the mi implementation of backing store need: */
+
+#include "mibstore.h"
+
+/* All drivers using the vgahw module need this */
+/* This driver needs to be modified to not use vgaHW for multihead operation */
+#include "vgaHW.h"
+
+/* Drivers using the mi SW cursor need: */
+
+#include "mipointer.h"
+
+/* Drivers using the mi colourmap code need: */
+
+#include "micmap.h"
+
+/* Drivers using cfb need: */
+
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+
+/* Drivers supporting bpp 16, 24 or 32 with cfb need one or more of: */
+
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+
+/* !!! These need to be checked !!! */
+#if 0
+#ifdef XFreeXDGA
+#define _XF86DGA_SERVER_
+#include "extensions/xf86dgastr.h"
+#endif
+#endif
+
+/* The driver's own header file: */
+
+#include "tdfx.h"
+
+#include "miscstruct.h"
+
+#include "xf86xv.h"
+#include "Xv.h"
+
+/* Required Functions: */
+
+/* Print a driver identifying message. */
+static void TDFXIdentify(int flags);
+
+/* Identify if there is any hardware present that I know how to drive. */
+static Bool TDFXProbe(DriverPtr drv, int flags);
+
+/* Process the config file and see if we have a valid configuration */
+static Bool TDFXPreInit(ScrnInfoPtr pScrn, int flags);
+
+/* Initialize a screen */
+static Bool TDFXScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv);
+
+/* Enter from a virtual terminal */
+static Bool TDFXEnterVT(int scrnIndex, int flags);
+
+/* Leave to a virtual terminal */
+static void TDFXLeaveVT(int scrnIndex, int flags);
+
+/* Close down each screen we initialized */
+static Bool TDFXCloseScreen(int scrnIndex, ScreenPtr pScreen);
+
+/* Change screensaver state */
+static Bool TDFXSaveScreen(ScreenPtr pScreen, Bool unblank);
+
+/* Allow mode switching */
+Bool TDFXSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+
+/* Cleanup server private data */
+static void TDFXFreeScreen(int scrnIndex, int flags);
+
+/* Check if a mode is valid on the hardware */
+static int TDFXValidMode(int scrnIndex, DisplayModePtr mode, Bool
+ verbose, int flags);
+
+#ifdef DPMSExtension
+/* Switch to various Display Power Management System levels */
+static void TDFXDisplayPowerManagementSet(ScrnInfoPtr pScrn,
+ int PowerManagermentMode, int flags);
+#endif
+
+#define VERSION 4000
+#define TDFX_NAME "TDFX"
+#define TDFX_DRIVER_NAME "tdfx"
+#define TDFX_MAJOR_VERSION 1
+#define TDFX_MINOR_VERSION 0
+#define TDFX_PATCHLEVEL 0
+
+DriverRec TDFX = {
+ VERSION,
+ "Accelerated driver for 3dfx Voodoo Banshee and Voodoo3 cards",
+ TDFXIdentify,
+ TDFXProbe,
+ NULL,
+ 0
+};
+
+/* Chipsets */
+static SymTabRec TDFXChipsets[] = {
+ { PCI_CHIP_BANSHEE, "3dfx Banshee"},
+ { PCI_CHIP_VOODOO3, "3dfx Voodoo3"},
+ { -1, NULL }
+};
+
+static PciChipsets TDFXPciChipsets[] = {
+ { PCI_CHIP_BANSHEE, PCI_CHIP_BANSHEE, RES_SHARED_VGA },
+ { PCI_CHIP_VOODOO3, PCI_CHIP_VOODOO3, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED }
+};
+
+/* !!! Do we want an option for PIO address space? !!! */
+/* !!! Do we want an option for alternate clocking? !!! */
+
+typedef enum {
+ OPTION_NOACCEL,
+ OPTION_SW_CURSOR,
+ OPTION_USE_PIO,
+} TDFXOpts;
+
+static OptionInfoRec TDFXOptions[] = {
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_USE_PIO, "UsePIO", OPTV_BOOLEAN, {0}, FALSE},
+ { -1, NULL, OPTV_NONE, {0}, FALSE}
+};
+
+static const char *vgahwSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWSave", /* Added */
+ "vgaHWRestore", /* Added */
+ "vgaHWProtect",
+ "vgaHWInit",
+ "vgaHWMapMem",
+ "vgaHWSetMmioFuncs",
+ "vgaHWGetIOBase",
+ "vgaHWLock",
+ "vgaHWUnlock",
+ "vgaHWFreeHWRec",
+ "vgaHWSaveScreen",
+ "vgaHWHandleColormaps",
+ 0
+};
+
+static const char *cfbSymbols[] = {
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb24ScreenInit",
+ "cfb32ScreenInit",
+ "cfb8_32ScreenInit",
+ "cfb24_32ScreenInit",
+ NULL
+};
+
+static const char *xf8_32bppSymbols[] = {
+ "xf86Overlay8Plus32Init",
+ NULL
+};
+
+static const char *xaaSymbols[] = {
+ "XAADestroyInfoRec",
+ "XAACreateInfoRec",
+ "XAAInit",
+ "XAAStippleScanlineFuncLSBFirst",
+ "XAAOverlayFBfuncs",
+ "XAACachePlanarMonoStipple",
+ "XAAScreenIndex",
+ NULL
+};
+
+static const char *ramdacSymbols[] = {
+ "xf86InitCursor",
+ "xf86CreateCursorInfoRec",
+ "xf86DestroyCursorInfoRec",
+ NULL
+};
+
+#ifdef XF86DRI
+static const char *drmSymbols[] = {
+ "drmAddBufs",
+ "drmAddMap",
+ "drmCtlAddCommand",
+ "drmCtlInstHandler",
+ "drmGetInterruptFromBusID",
+ "drmMapBufs",
+ "drmMarkBufs",
+ "drmUnmapBufs",
+ NULL
+};
+
+static const char *driSymbols[] = {
+ "DRIGetDrawableIndex",
+ "DRIFinishScreenInit",
+ "DRIDestroyInfoRec",
+ "DRICloseScreen",
+ "DRIDestroyInfoRec",
+ "DRIScreenInit",
+ "DRIDestroyInfoRec",
+ "DRICreateInfoRec",
+ "GlxSetVisualConfigs",
+ NULL
+};
+#endif
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(tdfxSetup);
+
+static XF86ModuleVersionInfo tdfxVersRec =
+{
+ "tdfx",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ TDFX_MAJOR_VERSION, TDFX_MINOR_VERSION, TDFX_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+XF86ModuleData tdfxModuleData = {&tdfxVersRec, tdfxSetup, 0};
+
+static pointer
+tdfxSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ /* This module should be loaded only once, but check to be sure. */
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&TDFX, module, 0);
+
+ /*
+ * Modules that this driver always requires may be loaded here
+ * by calling LoadSubModule().
+ */
+
+ /*
+ * Tell the loader about symbols from other modules that this module
+ * might refer to.
+ */
+ LoaderRefSymLists(vgahwSymbols, cfbSymbols, xaaSymbols,
+ xf8_32bppSymbols, ramdacSymbols,
+#ifdef XF86DRI
+ drmSymbols, driSymbols,
+#endif
+ NULL);
+
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer)1;
+ } else {
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+#endif
+
+/*
+ * TDFXGetRec and TDFXFreeRec --
+ *
+ * Private data for the driver is stored in the screen structure.
+ * These two functions create and destroy that private data.
+ *
+ */
+static Bool
+TDFXGetRec(ScrnInfoPtr pScrn) {
+ if (pScrn->driverPrivate) return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(TDFXRec), 1);
+ return TRUE;
+}
+
+static void
+TDFXFreeRec(ScrnInfoPtr pScrn) {
+ if (!pScrn) return;
+ if (!pScrn->driverPrivate) return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate=0;
+}
+
+/*
+ * TDFXIdentify --
+ *
+ * Returns the string name for the driver based on the chipset. In this
+ * case it will always be an TDFX, so we can return a static string.
+ *
+ */
+static void
+TDFXIdentify(int flags) {
+ xf86PrintChipsets(TDFX_NAME, "Driver for 3dfx Banshee/Voodoo3 chipsets", TDFXChipsets);
+}
+
+/*
+ * TDFXProbe --
+ *
+ * Look through the PCI bus to find cards that are TDFX boards.
+ * Setup the dispatch table for the rest of the driver functions.
+ *
+ */
+static Bool
+TDFXProbe(DriverPtr drv, int flags) {
+ int i, numUsed, numDevSections, *usedChips;
+ GDevPtr *devSections;
+ Bool foundScreen = FALSE;
+
+ TDFXTRACE("TDFXProbe start\n");
+ /*
+ Find the config file Device sections that match this
+ driver, and return if there are none.
+ */
+ if ((numDevSections = xf86MatchDevice(TDFX_DRIVER_NAME, &devSections))<=0) {
+ return FALSE;
+ }
+
+ /*
+ Since these Probing is just checking the PCI data the server already
+ collected.
+ */
+ if (!xf86GetPciVideoInfo()) return FALSE;
+
+ numUsed = xf86MatchPciInstances(TDFX_NAME, PCI_VENDOR_3DFX,
+ TDFXChipsets, TDFXPciChipsets,
+ devSections, numDevSections,
+ drv, &usedChips);
+ xfree(devSections);
+ devSections=0;
+ if (numUsed<=0) return FALSE;
+
+ for (i=0; i<numUsed; i++) {
+ ScrnInfoPtr pScrn;
+
+ /* Allocate new ScrnInfoRec and claim the slot */
+ pScrn = xf86AllocateScreen(drv, 0);
+
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = TDFX_DRIVER_NAME;
+ pScrn->name = TDFX_NAME;
+ pScrn->Probe = TDFXProbe;
+ pScrn->PreInit = TDFXPreInit;
+ pScrn->ScreenInit = TDFXScreenInit;
+ pScrn->SwitchMode = TDFXSwitchMode;
+ pScrn->AdjustFrame = TDFXAdjustFrame;
+ pScrn->EnterVT = TDFXEnterVT;
+ pScrn->LeaveVT = TDFXLeaveVT;
+ pScrn->FreeScreen = TDFXFreeScreen;
+ pScrn->ValidMode = TDFXValidMode;
+ foundScreen = TRUE;
+
+ xf86ConfigActivePciEntity(pScrn, usedChips[i], TDFXPciChipsets, 0, 0, 0, 0, 0);
+ }
+ xfree(usedChips);
+
+ return foundScreen;
+}
+
+static int
+TDFXCountRam(ScrnInfoPtr pScrn) {
+ TDFXPtr pTDFX;
+ int memSize;
+ int memType=-1; /* SDRAM or SGRAM */
+
+ pTDFX = TDFXPTR(pScrn);
+ TDFXTRACE("TDFXCountRam start\n");
+ memSize=0;
+ if (pTDFX->PIOBase) {
+ CARD32
+ partSize, /* size of SGRAM chips in Mbits */
+ nChips, /* # chips of SDRAM/SGRAM */
+ dramInit0_strap,
+ dramInit1_strap,
+ dramInit1,
+ miscInit1;
+
+ /* determine memory type: SDRAM or SGRAM */
+ memType = MEM_TYPE_SGRAM;
+ dramInit1_strap = pTDFX->readLong(pTDFX, DRAMINIT1);
+ dramInit1_strap &= SST_MCTL_TYPE_SDRAM;
+ if (dramInit1_strap) memType = MEM_TYPE_SDRAM;
+
+ /* set memory interface delay values and enable refresh */
+ /* these apply to all RAM vendors */
+ dramInit1 = 0x0;
+ dramInit1 |= 2<<SST_SGRAM_OFLOP_DEL_ADJ_SHIFT;
+ dramInit1 |= SST_SGRAM_CLK_NODELAY;
+ dramInit1 |= SST_DRAM_REFRESH_EN;
+ dramInit1 |= (0x18 << SST_DRAM_REFRESH_VALUE_SHIFT) & SST_DRAM_REFRESH_VALUE;
+ dramInit1 &= ~SST_MCTL_TYPE_SDRAM;
+ dramInit1 |= dramInit1_strap;
+ pTDFX->writeLong(pTDFX, DRAMINIT1, dramInit1);
+
+ /* determine memory size from strapping pins (dramInit0 and dramInit1) */
+ dramInit0_strap = pTDFX->readLong(pTDFX, DRAMINIT0);
+
+ dramInit0_strap &= SST_SGRAM_TYPE | SST_SGRAM_NUM_CHIPSETS;
+
+ if ( memType == MEM_TYPE_SDRAM ) {
+ memSize = 16;
+ } else {
+ nChips = ((dramInit0_strap & SST_SGRAM_NUM_CHIPSETS) == 0) ? 4 : 8;
+
+ if ( (dramInit0_strap & SST_SGRAM_TYPE) == SST_SGRAM_TYPE_8MBIT ) {
+ partSize = 8;
+ } else if ( (dramInit0_strap & SST_SGRAM_TYPE) == SST_SGRAM_TYPE_16MBIT) {
+ partSize = 16;
+ } else {
+ ErrorF("Invalid sgram type = 0x%x",
+ (dramInit0_strap & SST_SGRAM_TYPE) << SST_SGRAM_TYPE_SHIFT );
+ return 0;
+ }
+ memSize = (nChips * partSize) / 8; /* in MBytes */
+ }
+ TDFXTRACEREG("dramInit0 = %x dramInit1 = %x\n", dramInit0_strap, dramInit1_strap);
+ TDFXTRACEREG("MemConfig %d chips %d size %d total\n", nChips, partSize, memSize);
+
+ /*
+ disable block writes for SDRAM
+ */
+ miscInit1 = pTDFX->readLong(pTDFX, MISCINIT1);
+ if ( memType == MEM_TYPE_SDRAM ) {
+ miscInit1 |= SST_DISABLE_2D_BLOCK_WRITE;
+ }
+ miscInit1|=1;
+ pTDFX->writeLong(pTDFX, MISCINIT1, miscInit1);
+ }
+
+ /* return # of KBytes of board memory */
+ return memSize*1024;
+}
+
+/*
+ * TDFXPreInit --
+ *
+ * Do initial setup of the board before we know what resolution we will
+ * be running at.
+ *
+ */
+static Bool
+TDFXPreInit(ScrnInfoPtr pScrn, int flags) {
+ vgaHWPtr hwp;
+ TDFXPtr pTDFX;
+ ClockRangePtr clockRanges;
+ int i;
+ MessageType from;
+ char *mod=0, *reqSym=0;
+ int flags24;
+ rgb defaultWeight = {0, 0, 0};
+
+ TDFXTRACE("TDFXPreInit start\n");
+ if (pScrn->numEntities != 1) return FALSE;
+
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw")) return FALSE;
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /* Allocate a vgaHWRec */
+ if (!vgaHWGetHWRec(pScrn)) return FALSE;
+
+ /* Allocate driverPrivate */
+ if (!TDFXGetRec(pScrn)) {
+ return FALSE;
+ }
+
+ pTDFX = TDFXPTR(pScrn);
+
+ pTDFX->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pTDFX->pEnt->location.type != BUS_PCI) return FALSE;
+
+ pTDFX->PciInfo = xf86GetPciInfoForEntity(pTDFX->pEnt->index);
+ pTDFX->PciTag = pciTag(pTDFX->PciInfo->bus, pTDFX->PciInfo->device,
+ pTDFX->PciInfo->func);
+
+ if (xf86RegisterResources(pTDFX->pEnt->index, 0, ResNone))
+ return FALSE;
+ if (pTDFX->usePIO)
+ pScrn->racIoFlags = RAC_FB | RAC_COLORMAP;
+ else
+ pScrn->racMemFlags = RAC_FB | RAC_COLORMAP;
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ flags24=Support24bppFb | Support32bppFb | SupportConvert32to24;
+ if (!xf86SetDepthBpp(pScrn, 8, 8, 8, flags24)) {
+ return FALSE;
+ } else {
+ switch (pScrn->depth) {
+ case 8:
+ case 16:
+ case 24:
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by tdfx driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+ xf86PrintDepthBpp(pScrn);
+
+ pScrn->rgbBits=8;
+ if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight))
+ return FALSE;
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /* We use a programamble clock */
+ pScrn->progClock = TRUE;
+
+ hwp = VGAHWPTR(pScrn);
+ pTDFX->cpp = pScrn->bitsPerPixel/8;
+
+ /* Process the options */
+ xf86CollectOptions(pScrn, NULL);
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, TDFXOptions);
+
+ /*
+ * Set the Chipset and ChipRev, allowing config file entries to
+ * override.
+ */
+ if (pTDFX->pEnt->device->chipset && *pTDFX->pEnt->device->chipset) {
+ pScrn->chipset = pTDFX->pEnt->device->chipset;
+ from = X_CONFIG;
+ } else if (pTDFX->pEnt->device->chipID >= 0) {
+ pScrn->chipset = (char *)xf86TokenToString(TDFXChipsets, pTDFX->pEnt->device->chipID);
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pTDFX->pEnt->device->chipID);
+ } else {
+ from = X_PROBED;
+ pScrn->chipset = (char *)xf86TokenToString(TDFXChipsets, pTDFX->PciInfo->chipType);
+ }
+ if (pTDFX->pEnt->device->chipRev >= 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pTDFX->pEnt->device->chipRev);
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
+
+ if (pTDFX->pEnt->device->MemBase != 0) {
+ pTDFX->LinearAddr = pTDFX->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ if (pTDFX->PciInfo->memBase[1] != 0) {
+ pTDFX->LinearAddr = pTDFX->PciInfo->memBase[1];
+ from = X_PROBED;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid FB address in PCI config space\n");
+ TDFXFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pTDFX->LinearAddr);
+
+ if (pTDFX->pEnt->device->IOBase != 0) {
+ pTDFX->MMIOAddr = pTDFX->pEnt->device->IOBase;
+ from = X_CONFIG;
+ } else {
+ if (pTDFX->PciInfo->memBase[0]) {
+ pTDFX->MMIOAddr = pTDFX->PciInfo->memBase[0];
+ from = X_PROBED;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid MMIO address in PCI config space\n");
+ TDFXFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at addr 0x%lX\n",
+ (unsigned long)pTDFX->MMIOAddr);
+
+ if (pTDFX->PciInfo->ioBase[2]) {
+ pTDFX->PIOBase = pTDFX->PciInfo->ioBase[2]&0xFFFFFFFC;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid PIO address in PCI config space\n");
+ TDFXFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PIO registers at addr 0x%lX\n",
+ (unsigned long)pTDFX->PIOBase);
+
+ /* We have to use PIO to probe, because we haven't mappend yet */
+ TDFXSetPIOAccess(pTDFX);
+
+ /* Calculate memory */
+ pScrn->videoRam = TDFXCountRam(pScrn);
+ from = X_PROBED;
+ if (pTDFX->pEnt->device->videoRam) {
+ pScrn->videoRam = pTDFX->pEnt->device->videoRam;
+ from = X_CONFIG;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+ pTDFX->FbMapSize = pScrn->videoRam*1024;
+
+ /*
+ * If the driver can do gamma correction, it should call xf86SetGamma()
+ * here.
+ */
+
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+
+ pTDFX->MaxClock = 0;
+ if (pTDFX->pEnt->device->dacSpeeds[0]) {
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ pTDFX->MaxClock = pTDFX->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ pTDFX->MaxClock = pTDFX->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ pTDFX->MaxClock = pTDFX->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ case 32:
+ pTDFX->MaxClock = pTDFX->pEnt->device->dacSpeeds[DAC_BPP32];
+ break;
+ }
+ if (!pTDFX->MaxClock)
+ pTDFX->MaxClock = pTDFX->pEnt->device->dacSpeeds[0];
+ from = X_CONFIG;
+ } else {
+ switch (pTDFX->PciInfo->chipType) {
+ case PCI_CHIP_BANSHEE:
+ pTDFX->MaxClock = 270000;
+ break;
+ case PCI_CHIP_VOODOO3:
+ pTDFX->MaxClock = 300000;
+ break;
+ }
+ }
+ clockRanges = xnfalloc(sizeof(ClockRange));
+ clockRanges->next=NULL;
+ clockRanges->minClock= 12000; /* !!! What's the min clock? !!! */
+ clockRanges->maxClock=pTDFX->MaxClock;
+ clockRanges->clockIndex = -1;
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = FALSE;
+
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ 0, 320, 2048, 16*pScrn->bitsPerPixel,
+ 200, 1536,
+ pScrn->virtualX, pScrn->virtualY,
+ pTDFX->FbMapSize, LOOKUP_BEST_REFRESH);
+
+ if (i==-1) {
+ TDFXFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86PruneDriverModes(pScrn);
+
+ if (!i || !pScrn->modes) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ TDFXFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ pScrn->currentMode = pScrn->modes;
+
+ xf86PrintModes(pScrn);
+
+ xf86SetDpi(pScrn, 0, 0);
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ mod = "cfb";
+ reqSym = "cfbScreenInit";
+ break;
+ case 16:
+ mod = "cfb16";
+ reqSym = "cfb16ScreenInit";
+ break;
+ case 24:
+ mod = "cfb24";
+ reqSym = "cfb24ScreenInit";
+ break;
+ case 32:
+ mod = "cfb32";
+ reqSym = "cfb32ScreenInit";
+ break;
+ }
+ if (mod && !xf86LoadSubModule(pScrn, mod)) {
+ TDFXFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymbols(reqSym, NULL);
+
+ if (!xf86ReturnOptValBool(TDFXOptions, OPTION_NOACCEL, FALSE)) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ TDFXFreeRec(pScrn);
+ return FALSE;
+ }
+ }
+
+ if (!xf86ReturnOptValBool(TDFXOptions, OPTION_SW_CURSOR, FALSE)) {
+ if (!xf86LoadSubModule(pScrn, "ramdac")) {
+ TDFXFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ramdacSymbols, NULL);
+ }
+
+ /* We wont be using the VGA access after the probe */
+ if (!xf86ReturnOptValBool(TDFXOptions, OPTION_USE_PIO, FALSE)) {
+ resRange vgaio[] = { {ResShrIoBlock,0x3B0,0x3BB},
+ {ResShrIoBlock,0x3C0,0x3DF},
+ _END };
+ resRange vgamem[] = {{ResShrMemBlock,0xA0000,0xAFFFF},
+ {ResShrMemBlock,0xB8000,0xBFFFF},
+ {ResShrMemBlock,0xB0000,0xB7FFF},
+ _END };
+
+ pTDFX->usePIO=FALSE;
+ xf86SetOperatingState(vgaio, pTDFX->pEnt->index, ResUnusedOpr);
+ xf86SetOperatingState(vgamem, pTDFX->pEnt->index, ResDisableOpr);
+ } else {
+ pTDFX->usePIO=TRUE;
+ }
+
+ return TRUE;
+}
+
+static Bool
+TDFXMapMem(ScrnInfoPtr pScrn)
+{
+ int mmioFlags;
+ TDFXPtr pTDFX;
+
+ TDFXTRACE("TDFXMapMem start\n");
+ pTDFX = TDFXPTR(pScrn);
+
+#if !defined(__alpha__)
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT;
+#else
+ mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT | VIDMEM_SPARSE;
+#endif
+
+ pTDFX->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+ pTDFX->PciTag,
+ pTDFX->MMIOAddr,
+ TDFXIOMAPSIZE);
+ if (!pTDFX->MMIOBase) return FALSE;
+
+ pTDFX->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pTDFX->PciTag,
+ pTDFX->LinearAddr,
+ pTDFX->FbMapSize);
+ if (!pTDFX->FbBase) return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+TDFXUnmapMem(ScrnInfoPtr pScrn)
+{
+ TDFXPtr pTDFX;
+
+ TDFXTRACE("TDFXUnmapMem start\n");
+ pTDFX = TDFXPTR(pScrn);
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTDFX->MMIOBase, TDFXIOMAPSIZE);
+ pTDFX->MMIOBase=0;
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTDFX->FbBase, pTDFX->FbMapSize);
+ pTDFX->FbBase = 0;
+ return TRUE;
+}
+
+static void
+PrintRegisters(ScrnInfoPtr pScrn, TDFXRegPtr regs)
+{
+#ifdef TRACE
+ int i;
+ TDFXPtr pTDFX;
+
+ pTDFX = TDFXPTR(pScrn);
+#if 0
+ ErrorF("VGA Registers\n");
+#ifdef VB_PCI_IO
+ ErrorF("Using PCI I/O Registers\n");
+#endif
+ ErrorF("MiscOutReg = %x versus %x\n", inb(VGA_REG(0x3cc)), regs->std.MiscOutReg);
+ ErrorF("Noclock is %d\n", regs->std.NoClock);
+ for (i=0; i<25; i++) {
+ outb(VGA_REG(0x3D4), i);
+ ErrorF("CRTC[%d]=%d versus %d\n", i, inb(VGA_REG(0x3D5)), regs->std.CRTC[i]);
+ }
+ if (!vgaIOBase)
+ vgaIOBase = (inb(VGA_REG(0x3cc)) & 0x1) ? 0x3D0 : 0x3B0;
+ for (i=0; i<21; i++) {
+ inb(VGA_REG(vgaIOBase+0xA));
+ outb(VGA_REG(0x3C0), i);
+ ErrorF("Attribute[%d]=%d versus %d\n", i, inb(VGA_REG(0x3C1)), regs->std.Attribute[i]);
+ }
+ inb(VGA_REG(vgaIOBase+0xA));
+ outb(VGA_REG(0x3C0), BIT(5));
+ for (i=0; i<9; i++) {
+ outb(VGA_REG(0x3CE), i);
+ ErrorF("Graphics[%d]=%d versus %d\n", i, inb(VGA_REG(0x3CF)), regs->std.Graphics[i]);
+ }
+ for (i=0; i<5; i++) {
+ outb(VGA_REG(0x3C4), i);
+ ErrorF("Sequencer[%d]=%d versus %d\n", i, inb(VGA_REG(0x3C5)), regs->std.Sequencer[i]);
+ }
+#endif
+#if 1
+ ErrorF("Banshee Registers\n");
+ ErrorF("VidCfg = %x versus %x\n", pTDFX->readLong(pTDFX, VIDPROCCFG), regs->vidcfg);
+ ErrorF("DACmode = %x versus %x\n", pTDFX->readLong(pTDFX, DACMODE), regs->dacmode);
+ ErrorF("Vgainit0 = %x versus %x\n", pTDFX->readLong(pTDFX, VGAINIT0), regs->vgainit0);
+ ErrorF("Vgainit1 = %x versus %x\n", pTDFX->readLong(pTDFX, VGAINIT1), regs->vgainit1);
+ ErrorF("DramInit0 = %x\n", pTDFX->readLong(pTDFX, DRAMINIT0));
+ ErrorF("DramInit1 = %x\n", pTDFX->readLong(pTDFX, DRAMINIT1));
+ ErrorF("VidPLL = %x versus %x\n", pTDFX->readLong(pTDFX, PLLCTRL0), regs->vidpll);
+ ErrorF("screensize = %x versus %x\n", pTDFX->readLong(pTDFX, VIDSCREENSIZE), regs->screensize);
+ ErrorF("stride = %x versus %x\n", pTDFX->readLong(pTDFX, VIDDESKTOPOVERLAYSTRIDE), regs->stride);
+ ErrorF("startaddr = %x versus %x\n", pTDFX->readLong(pTDFX, VIDDESKTOPSTARTADDR), regs->startaddr);
+ ErrorF("Input Status 0 = %x\n", pTDFX->readLong(pTDFX, 0xc2));
+ ErrorF("Input Status 1 = %x\n", pTDFX->readLong(pTDFX, 0xda));
+ ErrorF("2D Status = %x\n", pTDFX->readLong(pTDFX, SST_2D_OFFSET));
+ ErrorF("3D Status = %x\n", pTDFX->readLong(pTDFX, SST_3D_OFFSET));
+#endif
+#endif
+}
+
+/*
+ * TDFXSave --
+ *
+ * This function saves the video state. It reads all of the SVGA registers
+ * into the vgaTDFXRec data structure. There is in general no need to
+ * mask out bits here - just read the registers.
+ */
+static void
+DoSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, TDFXRegPtr tdfxReg, Bool saveFonts)
+{
+ TDFXPtr pTDFX;
+ vgaHWPtr hwp;
+
+ TDFXTRACE("TDFXDoSave start\n");
+ pTDFX = TDFXPTR(pScrn);
+ hwp = VGAHWPTR(pScrn);
+
+ /*
+ * This function will handle creating the data structure and filling
+ * in the generic VGA portion.
+ */
+ if (saveFonts)
+ vgaHWSave(pScrn, vgaReg, VGA_SR_MODE|VGA_SR_FONTS);
+ else
+ vgaHWSave(pScrn, vgaReg, VGA_SR_MODE);
+
+ tdfxReg->ExtVga[0] = hwp->readCrtc(hwp, 0x1a);
+ tdfxReg->ExtVga[1] = hwp->readCrtc(hwp, 0x1b);
+ tdfxReg->vgainit0=pTDFX->readLong(pTDFX, VGAINIT0);
+ tdfxReg->vidcfg=pTDFX->readLong(pTDFX, VIDPROCCFG);
+ tdfxReg->vidpll=pTDFX->readLong(pTDFX, PLLCTRL0);
+ tdfxReg->dacmode=pTDFX->readLong(pTDFX, DACMODE);
+ tdfxReg->screensize=pTDFX->readLong(pTDFX, VIDSCREENSIZE);
+ tdfxReg->stride=pTDFX->readLong(pTDFX, VIDDESKTOPOVERLAYSTRIDE);
+ tdfxReg->cursloc=pTDFX->readLong(pTDFX, HWCURPATADDR);
+ tdfxReg->startaddr=pTDFX->readLong(pTDFX, VIDDESKTOPSTARTADDR);
+ tdfxReg->clip0min=TDFXReadLongMMIO(pTDFX, SST_2D_CLIP0MIN);
+ tdfxReg->clip0max=TDFXReadLongMMIO(pTDFX, SST_2D_CLIP0MAX);
+ tdfxReg->clip1min=TDFXReadLongMMIO(pTDFX, SST_2D_CLIP1MIN);
+ tdfxReg->clip1max=TDFXReadLongMMIO(pTDFX, SST_2D_CLIP1MAX);
+}
+
+static void
+TDFXSave(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp;
+ TDFXPtr pTDFX;
+
+ TDFXTRACE("TDFXSave start\n");
+ hwp = VGAHWPTR(pScrn);
+ pTDFX = TDFXPTR(pScrn);
+ DoSave(pScrn, &hwp->SavedReg, &pTDFX->SavedReg, TRUE);
+}
+
+static void
+DoRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, TDFXRegPtr tdfxReg,
+ Bool restoreFonts) {
+ TDFXPtr pTDFX;
+ vgaHWPtr hwp;
+
+ TDFXTRACE("TDFXDoRestore start\n");
+ pTDFX = TDFXPTR(pScrn);
+ hwp = VGAHWPTR(pScrn);
+
+ pTDFX->sync(pScrn);
+
+ vgaHWProtect(pScrn, TRUE);
+
+ if (restoreFonts)
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS|VGA_SR_MODE);
+ else
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+
+ hwp->writeCrtc(hwp, 0x1a, tdfxReg->ExtVga[0]);
+ hwp->writeCrtc(hwp, 0x1b, tdfxReg->ExtVga[1]);
+ pTDFX->writeLong(pTDFX, PLLCTRL0, tdfxReg->vidpll);
+ pTDFX->writeLong(pTDFX, DACMODE, tdfxReg->dacmode);
+ pTDFX->writeLong(pTDFX, VIDDESKTOPOVERLAYSTRIDE, tdfxReg->stride);
+ pTDFX->writeLong(pTDFX, HWCURPATADDR, tdfxReg->cursloc);
+ pTDFX->writeLong(pTDFX, VIDSCREENSIZE, tdfxReg->screensize);
+ pTDFX->writeLong(pTDFX, VIDDESKTOPSTARTADDR, tdfxReg->startaddr);
+ TDFXWriteLongMMIO(pTDFX, SST_2D_CLIP0MIN, tdfxReg->clip0min);
+ TDFXWriteLongMMIO(pTDFX, SST_2D_CLIP0MAX, tdfxReg->clip0max);
+ TDFXWriteLongMMIO(pTDFX, SST_2D_CLIP1MIN, tdfxReg->clip1min);
+ TDFXWriteLongMMIO(pTDFX, SST_2D_CLIP1MAX, tdfxReg->clip1max);
+ pTDFX->writeLong(pTDFX, VGAINIT0, tdfxReg->vgainit0);
+ pTDFX->writeLong(pTDFX, VIDPROCCFG, tdfxReg->vidcfg);
+
+ vgaHWProtect(pScrn, FALSE);
+
+ pTDFX->sync(pScrn);
+}
+
+static void
+TDFXRestore(ScrnInfoPtr pScrn) {
+ vgaHWPtr hwp;
+ TDFXPtr pTDFX;
+
+ TDFXTRACE("TDFXRestore start\n");
+ hwp = VGAHWPTR(pScrn);
+ pTDFX = TDFXPTR(pScrn);
+
+ DoRestore(pScrn, &hwp->SavedReg, &pTDFX->SavedReg, TRUE);
+}
+
+#define REFFREQ 14318.18
+
+static int
+CalcPLL(int freq, int *f_out) {
+ int m, n, k, best_m, best_n, best_k, f_cur, best_error;
+
+ TDFXTRACE("CalcPLL start\n");
+ best_error=freq;
+ best_n=best_m=best_k=0;
+ for (n=1; n<256; n++) {
+ f_cur=REFFREQ*(n+2);
+ if (f_cur<freq) {
+ f_cur=f_cur/3;
+ if (freq-f_cur<best_error) {
+ best_error=freq-f_cur;
+ best_n=n;
+ best_m=1;
+ best_k=0;
+ continue;
+ }
+ }
+ for (m=1; m<64; m++) {
+ for (k=0; k<4; k++) {
+ f_cur=REFFREQ*(n+2)/(m+2)/(1<<k);
+ if (abs(f_cur-freq)<best_error) {
+ best_error=abs(f_cur-freq);
+ best_n=n;
+ best_m=m;
+ best_k=k;
+ }
+ }
+ }
+ }
+ n=best_n;
+ m=best_m;
+ k=best_k;
+ *f_out=REFFREQ*(n+2)/(m+2)/(1<<k);
+ return (n<<8)|(m<<2)|k;
+}
+
+static Bool
+SetupVidPLL(ScrnInfoPtr pScrn, DisplayModePtr mode) {
+ TDFXPtr pTDFX;
+ TDFXRegPtr tdfxReg;
+ int freq, f_out;
+
+ TDFXTRACE("SetupVidPLL start\n");
+ pTDFX = TDFXPTR(pScrn);
+ tdfxReg = &pTDFX->ModeReg;
+ freq=mode->Clock;
+ tdfxReg->dacmode&=~SST_DAC_MODE_2X;
+ tdfxReg->vidcfg&=~SST_VIDEO_2X_MODE_EN;
+ if (freq>TDFX2XCUTOFF) {
+ if (freq>pTDFX->MaxClock) {
+ ErrorF("Overclocked PLLs\n");
+ freq=pTDFX->MaxClock;
+ }
+ tdfxReg->dacmode|=SST_DAC_MODE_2X;
+ tdfxReg->vidcfg|=SST_VIDEO_2X_MODE_EN;
+ }
+ tdfxReg->vidpll=CalcPLL(freq, &f_out);
+ TDFXTRACEREG("Vid PLL freq=%d f_out=%d reg=%x\n", freq, f_out,
+ tdfxReg->vidpll);
+ return TRUE;
+}
+
+#if 0
+static Bool
+SetupMemPLL(int freq) {
+ TDFXPtr pTDFX;
+ vgaTDFXPtr tdfxReg;
+ int f_out;
+
+ TDFXTRACE("SetupMemPLL start\n");
+ pTDFX=TDFXPTR();
+ tdfxReg=(vgaTDFXPtr)vgaNewVideoState;
+ tdfxReg->mempll=CalcPLL(freq, &f_out);
+ pTDFX->writeLong(pTDFX, PLLCTRL1, tdfxReg->mempll);
+ TDFXTRACEREG("Mem PLL freq=%d f_out=%d reg=%x\n", freq, f_out,
+ tdfxReg->mempll);
+ return TRUE;
+}
+
+static Bool
+SetupGfxPLL(int freq) {
+ TDFXPtr pTDFX;
+ vgaTDFXPtr tdfxReg;
+ int f_out;
+
+ TDFXTRACE("SetupGfxPLL start\n");
+ pTDFX=TDFXPTR();
+ tdfxReg=(vgaTDFXPtr)vgaNewVideoState;
+ tdfxReg->gfxpll=CalcPLL(freq, &f_out);
+ pTDFX->writeLong(pTDFX, PLLCTRL2, tdfxReg->gfxpll);
+ TDFXTRACEREG("Gfx PLL freq=%d f_out=%d reg=%x\n", freq, f_out,
+ tdfxReg->gfxpll);
+ return TRUE;
+}
+#endif
+
+static Bool
+TDFXInitVGA(ScrnInfoPtr pScrn)
+{
+ static Bool initDone=FALSE;
+ TDFXPtr pTDFX;
+ TDFXRegPtr tdfxReg;
+
+ TDFXTRACE("TDFXInitVGA start\n");
+ if (initDone) return TRUE;
+ initDone=TRUE;
+ pTDFX=TDFXPTR(pScrn);
+ tdfxReg = &pTDFX->ModeReg;
+ tdfxReg->vgainit0 = 0;
+ tdfxReg->vgainit0 |= SST_VGA0_EXTENSIONS;
+ tdfxReg->vgainit0 |= SST_WAKEUP_3C3 << SST_VGA0_WAKEUP_SELECT_SHIFT;
+ if (pTDFX->usePIO) {
+ tdfxReg->vgainit0 |= SST_VGA0_ENABLE_DECODE << SST_VGA0_LEGACY_DECODE_SHIFT;
+ }
+ tdfxReg->vgainit0 |= SST_ENABLE_ALT_READBACK << SST_VGA0_CONFIG_READBACK_SHIFT;
+ tdfxReg->vgainit0 |= BIT(12);
+
+ tdfxReg->vidcfg = SST_VIDEO_PROCESSOR_EN | SST_CURSOR_X11 | SST_DESKTOP_EN |
+ (pTDFX->cpp-1)<<SST_DESKTOP_PIXEL_FORMAT_SHIFT;
+ if (pTDFX->cpp!=1) tdfxReg->vidcfg |= SST_DESKTOP_CLUT_BYPASS;
+
+ tdfxReg->stride = pTDFX->stride;
+
+ tdfxReg->clip0min = tdfxReg->clip1min = 0;
+ tdfxReg->clip0max = tdfxReg->clip1max = pTDFX->maxClip;
+
+ return TRUE;
+}
+
+static Bool
+TDFXSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) {
+ TDFXPtr pTDFX;
+ TDFXRegPtr tdfxReg;
+ vgaRegPtr pVga;
+ int hbs, hbe, vbs, vbe, hse, wd;
+ int hd, hss, ht, vss, vt, vd, vse;
+
+ TDFXTRACE("TDFXSetMode start\n");
+
+ TDFXInitVGA(pScrn);
+ pTDFX = TDFXPTR(pScrn);
+ tdfxReg = &pTDFX->ModeReg;
+ pVga = &VGAHWPTR(pScrn)->ModeReg;
+
+ if (pTDFX->cpp==4)
+ wd = pScrn->displayWidth>>1;
+ else
+ wd = pScrn->displayWidth>>(4-pTDFX->cpp);
+
+ /* Tell the board we're using a programmable clock */
+ pVga->MiscOutReg |= 0xC;
+
+ /* Calculate the CRTC values */
+ hd = (mode->CrtcHDisplay>>3)-1;
+ hss = (mode->CrtcHSyncStart>>3);
+ hse = (mode->CrtcHSyncEnd>>3);
+ ht = (mode->CrtcHTotal>>3)-5;
+ hbs = (mode->CrtcHBlankStart>>3)-1;
+ hbe = (mode->CrtcHBlankEnd>>3)-1;
+
+ vd = mode->CrtcVDisplay-1;
+ vss = mode->CrtcVSyncStart;
+ vse = mode->CrtcVSyncEnd;
+ vt = mode->CrtcVTotal-2;
+ vbs = mode->CrtcVBlankStart-1;
+ vbe = mode->CrtcVBlankEnd-1;
+
+ /* Undo the "KGA fixes" */
+ pVga->CRTC[3] = (hbe&0x1F)|0x80;
+ pVga->CRTC[5] = (((hbe)&0x20)<<2) | (hse&0x1F);
+ pVga->CRTC[22] =vbe&0xFF;
+
+ /* Handle the higher resolution modes */
+ tdfxReg->ExtVga[0] = (ht&0x100)>>8 | (hd&0x100)>>6 | (hbs&0x100)>>4 |
+ (hbe&0x40)>>1 | (hss&0x100)>>2 | (hse&0x20)<<2;
+
+ tdfxReg->ExtVga[1] = (vt&0x400)>>10 | (vd&0x400)>>8 | (vbs&0x400)>>6 |
+ (vbe&0x400)>>4;
+
+ if (!SetupVidPLL(pScrn, mode)) return FALSE;
+
+ /* Set the screen size */
+ if (mode->Flags&V_DBLSCAN) {
+ pVga->CRTC[9] |= 0x80;
+ tdfxReg->screensize=mode->HDisplay|(mode->VDisplay<<13);
+ tdfxReg->vidcfg |= SST_HALF_MODE;
+ } else {
+ tdfxReg->screensize=mode->HDisplay|(mode->VDisplay<<12);
+ tdfxReg->vidcfg &= ~SST_HALF_MODE;
+ }
+
+ TDFXTRACEREG("cpp=%d Hdisplay=%d Vdisplay=%d stride=%d screensize=%x\n",
+ pTDFX->cpp, mode->HDisplay, mode->VDisplay, tdfxReg->stride,
+ tdfxReg->screensize);
+
+ return TRUE;
+}
+
+static Bool
+TDFXModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp;
+ TDFXPtr pTDFX;
+ int hd, hbs, hss, hse, hbe, ht, hskew;
+ Bool dbl;
+
+ hwp = VGAHWPTR(pScrn);
+ pTDFX = TDFXPTR(pScrn);
+
+ TDFXTRACE("TDFXModeInit start\n");
+ dbl=FALSE;
+ /* Check for 2x mode and halve all the timing values */
+ if (mode->Clock>TDFX2XCUTOFF) {
+ hd=mode->CrtcHDisplay;
+ hbs=mode->CrtcHBlankStart;
+ hss=mode->CrtcHSyncStart;
+ hse=mode->CrtcHSyncEnd;
+ hbe=mode->CrtcHBlankEnd;
+ ht=mode->CrtcHTotal;
+ hskew=mode->CrtcHSkew;
+ mode->CrtcHDisplay=hd>>1;
+ mode->CrtcHBlankStart=hbs>>1;
+ mode->CrtcHSyncStart=hss>>1;
+ mode->CrtcHSyncEnd=hse>>1;
+ mode->CrtcHBlankEnd=hbe>>1;
+ mode->CrtcHTotal=ht>>1;
+ mode->CrtcHSkew=hskew>>1;
+ dbl=TRUE;
+ }
+
+ vgaHWUnlock(hwp);
+
+ if (!vgaHWInit(pScrn, mode)) return FALSE;
+
+ pScrn->vtSema = TRUE;
+
+ if (!TDFXSetMode(pScrn, mode)) return FALSE;
+
+ if (dbl) {
+ mode->CrtcHDisplay=hd;
+ mode->CrtcHBlankStart=hbs;
+ mode->CrtcHSyncStart=hss;
+ mode->CrtcHSyncEnd=hse;
+ mode->CrtcHBlankEnd=hbe;
+ mode->CrtcHTotal=ht;
+ mode->CrtcHSkew=hskew;
+ }
+
+ DoRestore(pScrn, &hwp->ModeReg, &pTDFX->ModeReg, FALSE);
+
+ return TRUE;
+}
+
+static void
+TDFXLoadPalette16(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
+ short visualClass) {
+ TDFXPtr pTDFX;
+ vgaHWPtr hwp;
+ int i, index;
+ unsigned char r, g, b;
+
+ TDFXTRACE("TDFXLoadPalette16 start\n");
+ pTDFX = TDFXPTR(pScrn);
+ hwp = VGAHWPTR(pScrn);
+ for (i=0; i<numColors; i++) {
+ index=indices[i/2];
+ r=colors[index].red;
+ b=colors[index].blue;
+ index=indices[i];
+ g=colors[index].green;
+ hwp->writeDacWriteAddr(hwp, index<<2);
+ hwp->writeDacData(hwp, r);
+ hwp->writeDacData(hwp, g);
+ hwp->writeDacData(hwp, b);
+ i++;
+ index=indices[i];
+ g=colors[index].green;
+ hwp->writeDacWriteAddr(hwp, index<<2);
+ hwp->writeDacData(hwp, r);
+ hwp->writeDacData(hwp, g);
+ hwp->writeDacData(hwp, b);
+ }
+}
+
+static void
+TDFXLoadPalette24(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
+ short visualClass) {
+ TDFXPtr pTDFX;
+ vgaHWPtr hwp;
+ int i, index;
+ unsigned char r, g, b;
+
+ TDFXTRACE("TDFXLoadPalette24 start\n");
+ pTDFX = TDFXPTR(pScrn);
+ hwp = VGAHWPTR(pScrn);
+ for (i=0; i<numColors; i++) {
+ index=indices[i];
+ r=colors[index].red;
+ b=colors[index].blue;
+ index=indices[i];
+ g=colors[index].green;
+ hwp->writeDacWriteAddr(hwp, index);
+ hwp->writeDacData(hwp, r);
+ hwp->writeDacData(hwp, g);
+ hwp->writeDacData(hwp, b);
+ }
+}
+
+static Bool
+TDFXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) {
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ TDFXPtr pTDFX;
+ VisualPtr visual;
+ BoxRec MemBox;
+ RegionRec MemRegion;
+
+ TDFXTRACE("TDFXScreenInit start\n");
+ pScrn = xf86Screens[pScreen->myNum];
+ pTDFX = TDFXPTR(pScrn);
+ hwp = VGAHWPTR(pScrn);
+
+ if (!TDFXMapMem(pScrn)) return FALSE;
+ pScrn->memPhysBase = (int)pTDFX->FbBase;
+ pTDFX->lowMemLoc=0;
+
+ if (!pTDFX->usePIO) {
+ TDFXSetMMIOAccess(pTDFX);
+ hwp->IOBase = ((hwp->readMiscOut(hwp) & 0x01) ?
+ VGA_IOBASE_COLOR : VGA_IOBASE_MONO) + pTDFX->MMIOBase - 0x300;
+ } else {
+ vgaHWGetIOBase(hwp);
+ }
+ if (!vgaHWMapMem(pScrn)) return FALSE;
+ pTDFX->stride = pScrn->displayWidth*pTDFX->cpp;
+
+ TDFXCursorGrabMemory(pScreen);
+
+#ifdef PROP_3DFX
+ if (!TDFXInitPrivate(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to initialize private\n");
+ return FALSE;
+ }
+#else
+ pTDFX->sync=TDFXSync;
+#endif
+
+ pTDFX->lowMemLoc=((pTDFX->lowMemLoc+pTDFX->stride-1)/pTDFX->stride)*pTDFX->stride;
+ pTDFX->fbOffset=pTDFX->lowMemLoc;
+ MemBox.y1 = pScrn->virtualY;
+ MemBox.x1 = 0;
+ MemBox.x2 = pScrn->displayWidth;
+ MemBox.y2 = MemBox.y1+128;
+ pTDFX->lowMemLoc += MemBox.y2*pTDFX->stride;
+ pTDFX->maxClip=(MemBox.x2&0xFFF)|((MemBox.y2&0xFFF)<<16);
+
+ TDFXSave(pScrn);
+ if (!TDFXModeInit(pScrn, pScrn->currentMode)) return FALSE;
+
+ miClearVisualTypes();
+
+ if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+
+#ifdef XF86DRI
+ /*
+ * Setup DRI after visuals have been established, but before cfbScreenInit
+ * is called. cfbScreenInit will eventually call into the drivers
+ * InitGLXVisuals call back.
+ */
+ pTDFX->directRenderingEnabled = TDFXDRIScreenInit(pScreen);
+#endif
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ if (!cfbScreenInit(pScreen, pTDFX->FbBase+pTDFX->fbOffset,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth))
+ return FALSE;
+ break;
+ case 16:
+ if (!cfb16ScreenInit(pScreen, pTDFX->FbBase+pTDFX->fbOffset,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth))
+ return FALSE;
+ break;
+ case 24:
+ if (!cfb24ScreenInit(pScreen, pTDFX->FbBase+pTDFX->fbOffset,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth))
+ return FALSE;
+ break;
+ case 32:
+ if (!cfb32ScreenInit(pScreen, pTDFX->FbBase+pTDFX->fbOffset,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth))
+ return FALSE;
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in TDFXScrnInit\n",
+ pScrn->bitsPerPixel);
+ return FALSE;
+ }
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ if (pScrn->bitsPerPixel>8) {
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ if (!miCreateDefColormap(pScreen)) return FALSE;
+
+ if (pScrn->bitsPerPixel==16) {
+ if (!xf86HandleColormaps(pScreen, 256, 8, TDFXLoadPalette16, 0,
+ CMAP_PALETTED_TRUECOLOR|CMAP_RELOAD_ON_MODE_SWITCH))
+ return FALSE;
+ } else {
+ if (!xf86HandleColormaps(pScreen, 256, 8, TDFXLoadPalette24, 0,
+ CMAP_PALETTED_TRUECOLOR|CMAP_RELOAD_ON_MODE_SWITCH))
+ return FALSE;
+ }
+
+ TDFXAdjustFrame(scrnIndex, 0, 0, 0);
+
+ REGION_INIT(pScreen, &MemRegion, &MemBox, 1);
+ if (!xf86InitFBManagerRegion(pScreen, &MemRegion)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to init memory manager\n");
+ REGION_UNINIT(pScreen, &MemRegion);
+ return FALSE;
+ }
+ REGION_UNINIT(pScreen, &MemRegion);
+
+#ifdef DPMSExtension
+ xf86DPMSInit(pScreen, TDFXDisplayPowerManagementSet, 0);
+#endif
+
+#ifdef XF86DRI
+ if (pTDFX->directRenderingEnabled) {
+ /* Now that mi, cfb, drm and others have done their thing,
+ * complete the DRI setup.
+ */
+ pTDFX->directRenderingEnabled = TDFXDRIFinishScreenInit(pScreen);
+ }
+ if (pTDFX->directRenderingEnabled) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering enabled\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering disabled\n");
+ }
+#endif
+
+#ifdef XvExtension
+ {
+ XF86VideoAdaptorPtr *ptr;
+ int n;
+
+ n = xf86XVListGenericAdaptors(&ptr);
+ if (n) {
+ xf86XVScreenInit(pScreen, ptr, n);
+ }
+ }
+#endif
+
+ TDFXDGAInit(pScreen);
+
+ pTDFX->NoAccel=xf86ReturnOptValBool(TDFXOptions, OPTION_NOACCEL, FALSE);
+ if (!pTDFX->NoAccel) {
+ if (!TDFXAccelInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware acceleration initialization failed\n");
+ }
+ }
+
+ if (!xf86ReturnOptValBool(TDFXOptions, OPTION_SW_CURSOR, FALSE)) {
+ if (!TDFXCursorInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ }
+ }
+
+ pScreen->SaveScreen = TDFXSaveScreen;
+ pTDFX->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = TDFXCloseScreen;
+
+ if (serverGeneration == 1)
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+
+ return TRUE;
+}
+
+Bool
+TDFXSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) {
+ ScrnInfoPtr pScrn;
+
+ TDFXTRACE("TDFXSwitchMode start\n");
+ pScrn=xf86Screens[scrnIndex];
+ return TDFXModeInit(pScrn, mode);
+}
+
+void
+TDFXAdjustFrame(int scrnIndex, int x, int y, int flags) {
+ ScrnInfoPtr pScrn;
+ TDFXPtr pTDFX;
+ TDFXRegPtr tdfxReg;
+
+ TDFXTRACE("TDFXAdjustFrame start\n");
+ pScrn = xf86Screens[scrnIndex];
+ pTDFX = TDFXPTR(pScrn);
+ tdfxReg = &pTDFX->ModeReg;
+ tdfxReg->startaddr = pTDFX->fbOffset+y*pTDFX->stride+(x*pTDFX->cpp);
+ TDFXTRACE("TDFXAdjustFrame to x=%d y=%d offset=%d\n", x, y, tdfxReg->startaddr);
+ pTDFX->writeLong(pTDFX, VIDDESKTOPSTARTADDR, tdfxReg->startaddr);
+}
+
+static Bool
+TDFXEnterVT(int scrnIndex, int flags) {
+ ScrnInfoPtr pScrn;
+
+ TDFXTRACE("TDFXEnterVT start\n");
+ pScrn = xf86Screens[scrnIndex];
+ if (!TDFXModeInit(pScrn, pScrn->currentMode)) return FALSE;
+ TDFXAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ return TRUE;
+}
+
+static void
+TDFXLeaveVT(int scrnIndex, int flags) {
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+
+ TDFXTRACE("TDFXLeaveVT start\n");
+ pScrn = xf86Screens[scrnIndex];
+ hwp=VGAHWPTR(pScrn);
+ TDFXRestore(pScrn);
+ vgaHWLock(hwp);
+}
+
+static Bool
+TDFXCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ TDFXPtr pTDFX;
+
+ TDFXTRACE("TDFXCloseScreen start\n");
+ pScrn = xf86Screens[scrnIndex];
+ hwp = VGAHWPTR(pScrn);
+ pTDFX = TDFXPTR(pScrn);
+
+#ifdef XF86DRI
+ if (pTDFX->directRenderingEnabled) {
+ TDFXDRICloseScreen(pScreen);
+ }
+#endif
+
+#ifdef PROP_3DFX
+ TDFXShutdownPrivate(pScreen);
+#endif
+
+ TDFXRestore(pScrn);
+ vgaHWLock(hwp);
+ TDFXUnmapMem(pScrn);
+ vgaHWUnmapMem(pScrn);
+ if (pTDFX->AccelInfoRec) XAADestroyInfoRec(pTDFX->AccelInfoRec);
+ pTDFX->AccelInfoRec=0;
+ if (pTDFX->DGAModes) xfree(pTDFX->DGAModes);
+ pScrn->vtSema=FALSE;
+
+ pScreen->CloseScreen = pTDFX->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+static void
+TDFXFreeScreen(int scrnIndex, int flags) {
+ TDFXTRACE("TDFXFreeScreen start\n");
+ TDFXFreeRec(xf86Screens[scrnIndex]);
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+}
+
+static int
+TDFXValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) {
+ TDFXTRACE("TDFXValidMode start\n");
+ if ((mode->HDisplay>2046) || (mode->VDisplay>1536))
+ return MODE_BAD;
+ /* Banshee doesn't support interlace. Does V3? */
+ if (mode->Flags&V_INTERLACE)
+ return MODE_BAD;
+ /* In clock doubled mode widths must be divisible by 16 instead of 8 */
+ if ((mode->Clock>TDFX2XCUTOFF) && (mode->HDisplay%16))
+ return MODE_BAD;
+ return MODE_OK;
+}
+
+static Bool
+TDFXSaveScreen(ScreenPtr pScreen, Bool unblack)
+{
+ TDFXTRACE("TDFXSaveScreen start\n");
+ return vgaHWSaveScreen(pScreen, unblack);
+}
+
+#ifdef DPMSExtension
+static void
+TDFXDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
+ int flags) {
+ TDFXPtr pTDFX;
+ int dacmode, state=0;
+
+ TDFXTRACE("TDFXDPMS start\n");
+ pTDFX = TDFXPTR(pScrn);
+ dacmode=pTDFX->readLong(pTDFX, DACMODE);
+ switch (PowerManagementMode) {
+ case DPMSModeOn:
+ /* Screen: On; HSync: On, VSync: On */
+ state=0;
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off; HSync: Off, VSync: On */
+ state=BIT(1);
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off; HSync: On, VSync: Off */
+ state=BIT(3);
+ break;
+ case DPMSModeOff:
+ /* Screen: Off; HSync: Off, VSync: Off */
+ state=BIT(1)|BIT(3);
+ break;
+ }
+ dacmode&=~(BIT(1)|BIT(3));
+ dacmode|=state;
+ pTDFX->writeLong(pTDFX, DACMODE, dacmode);
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_hwcurs.c b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_hwcurs.c
new file mode 100644
index 000000000..7cb462f37
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_hwcurs.c
@@ -0,0 +1,136 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_hwcurs.c,v 1.1 1999/08/29 12:21:04 dawes Exp $ */
+/*
+ Voodoo Banshee driver version 1.0.2
+
+ Author: Daryll Strauss
+
+ Copyright: 1998,1999
+*/
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86fbman.h"
+
+#include "tdfx.h"
+
+void TDFXCursorGrabMemory(ScreenPtr pScreen);
+static void TDFXLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
+static void TDFXShowCursor(ScrnInfoPtr pScrn);
+static void TDFXHideCursor(ScrnInfoPtr pScrn);
+static void TDFXSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
+static void TDFXSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
+static Bool TDFXUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs);
+
+void
+TDFXCursorGrabMemory(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn;
+ TDFXPtr pTDFX;
+
+ pScrn = xf86Screens[pScreen->myNum];
+ pTDFX = TDFXPTR(pScrn);
+
+ /* Grab a whole page to help with alignment */
+ pTDFX->cursorOffset=pTDFX->lowMemLoc;
+ pTDFX->lowMemLoc+=1024;
+}
+
+Bool
+TDFXCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn;
+ TDFXPtr pTDFX;
+ xf86CursorInfoPtr infoPtr;
+
+ TDFXTRACECURS("TDFXCursorInit start\n");
+ pScrn = xf86Screens[pScreen->myNum];
+ pTDFX = TDFXPTR(pScrn);
+ pTDFX->CursorInfoRec = infoPtr = xf86CreateCursorInfoRec();
+ if (!infoPtr) return FALSE;
+
+ infoPtr->MaxWidth = 64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST|
+ HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK|
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64;
+ infoPtr->SetCursorColors = TDFXSetCursorColors;
+ infoPtr->SetCursorPosition = TDFXSetCursorPosition;
+ infoPtr->LoadCursorImage = TDFXLoadCursorImage;
+ infoPtr->HideCursor = TDFXHideCursor;
+ infoPtr->ShowCursor = TDFXShowCursor;
+ infoPtr->UseHWCursor = TDFXUseHWCursor;
+
+ pTDFX->ModeReg.cursloc = pTDFX->cursorOffset;
+ pTDFX->writeLong(pTDFX, HWCURPATADDR, pTDFX->cursorOffset);
+
+ return xf86InitCursor(pScreen, infoPtr);
+}
+
+static void
+TDFXLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+{
+ TDFXPtr pTDFX;
+
+ TDFXTRACECURS("TDFXLoadCursorImage start\n");
+ pTDFX = TDFXPTR(pScrn);
+ memcpy(pTDFX->FbBase+pTDFX->cursorOffset, src, 1024);
+}
+
+static void
+TDFXShowCursor(ScrnInfoPtr pScrn)
+{
+ TDFXPtr pTDFX;
+
+ TDFXTRACECURS("TDFXShowCursor start\n");
+ pTDFX = TDFXPTR(pScrn);
+ pTDFX->ModeReg.vidcfg|=BIT(27);
+ pTDFX->writeLong(pTDFX, VIDPROCCFG, pTDFX->ModeReg.vidcfg);
+}
+
+void
+TDFXHideCursor(ScrnInfoPtr pScrn)
+{
+ TDFXPtr pTDFX;
+
+ TDFXTRACECURS("TDFXHideCursor start\n");
+ pTDFX = TDFXPTR(pScrn);
+ pTDFX->ModeReg.vidcfg&=~BIT(27);
+ pTDFX->writeLong(pTDFX, VIDPROCCFG, pTDFX->ModeReg.vidcfg);
+}
+
+static void
+TDFXSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ TDFXPtr pTDFX;
+
+ /* TDFXTRACECURS("TDFXSetCursorPosition start\n"); */
+ pTDFX = TDFXPTR(pScrn);
+ pTDFX->writeLong(pTDFX, HWCURLOC, ((y+64)<<16)|(x+64));
+}
+
+static void
+TDFXSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ TDFXPtr pTDFX;
+
+ TDFXTRACECURS("TDFXSetCursorColors start\n");
+ pTDFX = TDFXPTR(pScrn);
+ pTDFX->writeLong(pTDFX, HWCURC0, bg);
+ pTDFX->writeLong(pTDFX, HWCURC1, fg);
+}
+
+static Bool
+TDFXUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrn;
+ TDFXPtr pTDFX;
+
+ TDFXTRACECURS("TDFXUseHWCursor start\n");
+ pScrn = xf86Screens[pScreen->myNum];
+ pTDFX = TDFXPTR(pScrn);
+ if (pScrn->currentMode->Flags&V_DBLSCAN)
+ return FALSE;
+ if (!pTDFX->CursorInfoRec) return FALSE;
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_io.c b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_io.c
new file mode 100644
index 000000000..496fccfcd
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_io.c
@@ -0,0 +1,112 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_io.c,v 1.1 1999/08/29 12:21:04 dawes Exp $ */
+
+/*
+ * Authors:
+ * Daryll Strauss <daryll@precisioninsight.com>
+ *
+ * $PI$
+ */
+
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+#include "compiler.h"
+
+#include "tdfx.h"
+
+#ifndef __alpha__
+#define minb(p) *(volatile CARD8 *)(pTDFX->MMIOBase + (p))
+#define moutb(p,v) \
+ *(volatile CARD8 *)(pTDFX->MMIOBase + (p)) = (v)
+#define minl(p) *(volatile CARD32 *)(pTDFX->MMIOBase + (p))
+#define moutl(p,v) \
+ *(volatile CARD32 *)(pTDFX->MMIOBase + (p)) = (v)
+#else
+#define minb(p) xf86ReadSparse8(pI740->MMIOBase, (p))
+#define moutb(p,v) \
+ xf86WriteSparse8((v), pI740->MMIOBase, (p))
+#define minl(p) xf86ReadSparse32(pI740->MMIOBase, (p))
+#define moutl(p,v) \
+ xf86WriteSparse32((v), pI740->MMIOBase, (p))
+#endif
+
+static void TDFXWriteControlPIO(TDFXPtr pTDFX, int addr, char index, char val) {
+ outb(pTDFX->PIOBase+addr, index);
+ outb(pTDFX->PIOBase+addr+1, val);
+}
+
+static char TDFXReadControlPIO(TDFXPtr pTDFX, int addr, char index) {
+ outb(pTDFX->PIOBase+addr, index);
+ return inb(pTDFX->PIOBase+addr+1);
+}
+
+static void TDFXWriteLongPIO(TDFXPtr pTDFX, int addr, int val) {
+ outl(pTDFX->PIOBase+addr, val);
+}
+
+static int TDFXReadLongPIO(TDFXPtr pTDFX, int addr) {
+ return inl(pTDFX->PIOBase+addr);
+}
+
+void TDFXSetPIOAccess(TDFXPtr pTDFX) {
+ if (!pTDFX->PIOBase)
+ ErrorF("Can not set PIO Access before PIOBase\n");
+ pTDFX->writeControl=TDFXWriteControlPIO;
+ pTDFX->readControl=TDFXReadControlPIO;
+ pTDFX->writeLong=TDFXWriteLongPIO;
+ pTDFX->readLong=TDFXReadLongPIO;
+}
+
+static void TDFXWriteControlMMIO(TDFXPtr pTDFX, int addr, char index, char val) {
+ moutb(addr, index);
+ moutb(addr+1, val);
+}
+
+static char TDFXReadControlMMIO(TDFXPtr pTDFX, int addr, char index) {
+ moutb(addr, index);
+ return minb(addr+1);
+}
+
+void TDFXWriteLongMMIO(TDFXPtr pTDFX, int addr, int val) {
+ moutl(addr, val);
+}
+
+int TDFXReadLongMMIO(TDFXPtr pTDFX, int addr) {
+ return minl(addr);
+}
+
+void TDFXSetMMIOAccess(TDFXPtr pTDFX) {
+ if (!pTDFX->MMIOBase)
+ ErrorF("Can not set MMIO access before MMIOBase\n");
+ pTDFX->writeControl=TDFXWriteControlMMIO;
+ pTDFX->readControl=TDFXReadControlMMIO;
+ pTDFX->writeLong=TDFXWriteLongMMIO;
+ pTDFX->readLong=TDFXReadLongMMIO;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfxdefs.h b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfxdefs.h
new file mode 100644
index 000000000..76a7da63f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfxdefs.h
@@ -0,0 +1,175 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfxdefs.h,v 1.1 1999/08/29 12:21:04 dawes Exp $ */
+/*
+ Voodoo Banshee driver version 1.0.1
+
+ Author: Daryll Strauss
+
+ Copyright: 1998,1999
+*/
+
+#ifndef _TDFXDEFS_H_
+#define _TDFXDEFS_H_
+
+#define TDFXIOMAPSIZE 0x2000000
+
+/* Flags */
+#define BIT(n) (1UL<<(n))
+#define SST_SGRAM_OFLOP_DEL_ADJ_SHIFT 20
+#define SST_SGRAM_CLK_NODELAY BIT(13)
+#define SST_DRAM_REFRESH_EN BIT(0)
+#define SST_DRAM_REFRESH_VALUE_SHIFT 1
+#define SST_DRAM_REFRESH_VALUE (0x1FF<<SST_DRAM_REFRESH_VALUE_SHIFT)
+#define SST_SGRAM_TYPE_SHIFT 27
+#define SST_SGRAM_TYPE (0x1L<<SST_SGRAM_TYPE_SHIFT)
+#define SST_SGRAM_NUM_CHIPSETS BIT(26)
+#define SST_SGRAM_TYPE_8MBIT (0x0L<<SST_SGRAM_TYPE_SHIFT)
+#define SST_SGRAM_TYPE_16MBIT (0x1L<<SST_SGRAM_TYPE_SHIFT)
+#define SST_DISABLE_2D_BLOCK_WRITE BIT(15)
+#define SST_MCTL_TYPE_SDRAM BIT(30)
+#define SST_DAC_MODE_2X BIT(0)
+#define SST_VIDEO_2X_MODE_EN BIT(26)
+#define SST_VGA0_EXTENSIONS BIT(6)
+#define SST_WAKEUP_3C3 1
+#define SST_VGA0_WAKEUP_SELECT_SHIFT 8
+#define SST_VGA0_LEGACY_DECODE_SHIFT 9
+#define SST_VGA0_LEGACY_DECODE (1 << SST_VGA0_LEGACY_DECODE_SHIFT)
+#define SST_VGA0_ENABLE_DECODE 0
+#define SST_ENABLE_ALT_READBACK 0
+#define SST_VGA0_CONFIG_READBACK_SHIFT 10
+#define SST_VIDEO_PROCESSOR_EN BIT(0)
+#define SST_CURSOR_MODE_SHIFT 1
+#define SST_CURSOR_X11 (1<<SST_CURSOR_MODE_SHIFT)
+#define SST_DESKTOP_EN BIT(7)
+#define SST_DESKTOP_PIXEL_FORMAT_SHIFT 18
+#define SST_DESKTOP_CLUT_BYPASS BIT(10)
+#define SST_HALF_MODE BIT(4)
+#define SST_CURSOR_EN BIT(27)
+#define SST_BUSY BIT(9)
+#define SST_RETRACE BIT(6)
+
+#define MEM_TYPE_SGRAM 0
+#define MEM_TYPE_SDRAM 1
+
+#define BLIT_LEFT 1
+#define BLIT_UP 2
+
+/* Base Registers */
+#define STATUS 0x0
+#define PCIINIT0 0x4
+#define SIPMONITOR 0x8
+#define LFBMEMORYCONFIG 0xC
+#define MISCINIT0 0x10
+#define MISCINIT1 0x14
+#define DRAMINIT0 0x18
+#define DRAMINIT1 0x1C
+#define AGPINIT 0x20
+#define TMUGBEINIT 0x24
+#define VGAINIT0 0x28
+#define VGAINIT1 0x2c
+#define DRAMCOMMAND 0x30
+#define DRAMDATA 0x34
+#define PLLCTRL0 0x40
+#define PLLCTRL1 0x44
+#define PLLCTRL2 0x48
+#define DACMODE 0x4c
+#define DACADDR 0x50
+#define DACDATA 0x54
+#define RGBMAXDELTA 0x58
+#define VIDPROCCFG 0x5c
+#define HWCURPATADDR 0x60
+#define HWCURLOC 0x64
+#define HWCURC0 0x68
+#define HWCURC1 0x6c
+#define VIDINFORMAT 0x70
+#define VIDINSTATUS 0x74
+#define VIDSERIALPARALLELPORT 0x78
+#define VIDINXDECIMDELTAS 0x7c
+#define VIDINDECIMINITERRS 0x80
+#define VIDYDECIMDELTA 0x84
+#define VIDPXELBUGTHOLD 0x88
+#define VIDCHROMAMIN 0x8c
+#define VIDCHROMAMAX 0x90
+#define VIDCURRENTLINE 0x94
+#define VIDSCREENSIZE 0x98
+#define VIDOVERLAYSTARTCOORDS 0x9c
+#define VIDOVERLAYENDSCREENCOORDS 0xa0
+#define VIDOVERLAYDUDX 0xa4
+#define VIDOVERLAYDUDXOFFSETSRCWIDTH 0xa8
+#define VIDOVERLAYDVDY 0xac
+#define VIDOVERLAYDVDYOFFSET 0xe0
+#define VIDDESKTOPSTARTADDR 0xe4
+#define VIDDESKTOPOVERLAYSTRIDE 0xe8
+#define VIDINADDR0 0xec
+#define VIDINADDR1 0xf0
+#define VIDINADDR2 0xf4
+#define VIDINSTRIDE 0xf8
+#define VIDCUROVERLAYSTARTADDR 0xfc
+
+/* 2D Commands */
+#define SST_2D_NOP 0
+#define SST_2D_SCRNTOSCRNBLIT 1
+#define SST_2D_SCRNTOSCRNSTRETCH 2
+#define SST_2D_HOSTTOSCRNBLIT 3
+#define SST_2D_HOSTTOSCRNSTRECH 4
+#define SST_2D_RECTANGLEFILL 5
+#define SST_2D_LINE (6 | SST_2D_REVERSIBLE)
+#define SST_2D_POLYLINE (7 | SST_2D_REVERSIBLE)
+#define SST_2D_POLYGONFILL (8 | SST_2D_REVERSIBLE)
+
+/* Flags */
+#define SST_2D_REVERSIBLE BIT(9)
+#define SST_2D_STIPPLE_LINE BIT(12)
+#define SST_2D_MONOCHROME_PATTERN BIT(13)
+#define SST_2D_X_RIGHT_TO_LEFT BIT(14)
+#define SST_2D_Y_BOTTOM_TO_TOP BIT(15)
+#define SST_2D_TRANSPARENT_MONOCHROME BIT(16)
+#define SST_2D_SOURCE_PACKING_SHIFT 22
+#define SST_2D_SOURCE_PACKING_BYTE (1<<SST_2D_SOURCE_PACKING_SHIFT)
+#define SST_2D_SOURCE_PACKING_WORD (2<<SST_2D_SOURCE_PACKING_SHIFT)
+#define SST_2D_SOURCE_PACKING_DWORD (3<<SST_2D_SOURCE_PACKING_SHIFT)
+#define SST_2D_X_PATOFFSET_SHIFT 17
+#define SST_2D_Y_PATOFFSET_SHIFT 20
+#define SST_2D_SRC_FORMAT_SHIFT 16
+#define SST_2D_PIXFMT_1BPP (0<<SST_2D_SRC_FORMAT_SHIFT)
+#define SST_2D_SRC_COLORKEY_EX BIT(0)
+#define SST_2D_GO BIT(8)
+
+/* 2D Registers */
+#define SST_2D_OFFSET 0x100000
+#define SST_2D_CLIP0MIN SST_2D_OFFSET+0x8
+#define SST_2D_CLIP0MAX SST_2D_OFFSET+0xC
+#define SST_2D_DSTBASEADDR SST_2D_OFFSET+0x10
+#define SST_2D_DSTFORMAT SST_2D_OFFSET+0x14
+#define SST_2D_SRCCOLORKEYMIN SST_2D_OFFSET+0x18
+#define SST_2D_SRCCOLORKEYMAX SST_2D_OFFSET+0x1c
+#define SST_2D_DSTCOLORKEYMIN SST_2D_OFFSET+0x20
+#define SST_2D_DSTCOLORKEYMAX SST_2D_OFFSET+0x24
+#define SST_2D_BRESERROR0 SST_2D_OFFSET+0x28
+#define SST_2D_BRESERROR1 SST_2D_OFFSET+0x2c
+#define SST_2D_ROP SST_2D_OFFSET+0x30
+#define SST_2D_SRCBASEADDR SST_2D_OFFSET+0x34
+#define SST_2D_COMMANDEXTRA SST_2D_OFFSET+0x38
+#define SST_2D_LINESTIPPLE SST_2D_OFFSET+0x3c
+#define SST_2D_LINESTYLE SST_2D_OFFSET+0x40
+#define SST_2D_CLIP1MIN SST_2D_OFFSET+0x4C
+#define SST_2D_CLIP1MAX SST_2D_OFFSET+0x50
+#define SST_2D_SRCFORMAT SST_2D_OFFSET+0x54
+#define SST_2D_SRCSIZE SST_2D_OFFSET+0x58
+#define SST_2D_SRCXY SST_2D_OFFSET+0x5C
+#define SST_2D_COLORBACK SST_2D_OFFSET+0x60
+#define SST_2D_COLORFORE SST_2D_OFFSET+0x64
+#define SST_2D_DSTSIZE SST_2D_OFFSET+0x68
+#define SST_2D_DSTXY SST_2D_OFFSET+0x6C
+#define SST_2D_COMMAND SST_2D_OFFSET+0x70
+#define SST_2D_LAUNCH SST_2D_OFFSET+0x80
+#define SST_2D_PATTERN0 SST_2D_OFFSET+0x100
+#define SST_2D_PATTERN1 SST_2D_OFFSET+0x104
+
+/* 3D Commands */
+#define SST_3D_NOP 0
+
+/* 3D Registers */
+#define SST_3D_OFFSET 0x200000
+#define SST_3D_COMMAND SST_3D_OFFSET+0x120
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tga/BT463ramdac.c b/xc/programs/Xserver/hw/xfree86/drivers/tga/BT463ramdac.c
new file mode 100644
index 000000000..44d1f24d7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tga/BT463ramdac.c
@@ -0,0 +1,140 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/BT463ramdac.c,v 1.1 1998/08/29 05:43:34 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "BT.h"
+#include "tga_regs.h"
+#include "tga.h"
+
+
+#define BT463_LOAD_ADDR(a) \
+ TGA_WRITE_REG(BT463_ADDR_LO<<2, TGA_RAMDAC_SETUP_REG); \
+ TGA_WRITE_REG((BT463_ADDR_LO<<10)|((a)&0xff), TGA_RAMDAC_REG); \
+ TGA_WRITE_REG(BT463_ADDR_HI<<2, TGA_RAMDAC_SETUP_REG); \
+ TGA_WRITE_REG((BT463_ADDR_HI<<10)|(((a)>>8)&0xff), TGA_RAMDAC_REG);
+
+#define BT463_WRITE(m,a,v) \
+ BT463_LOAD_ADDR((a)); \
+ TGA_WRITE_REG(((m)<<2),TGA_RAMDAC_SETUP_REG); \
+ TGA_WRITE_REG(((m)<<10)|((v)&0xff),TGA_RAMDAC_REG);
+
+/*
+ * useful defines for managing the BT463 on the 24-plane TGAs
+ */
+#define BT463_READ_BIT 0x2
+
+#define BT463_ADDR_LO 0x0
+#define BT463_ADDR_HI 0x1
+#define BT463_REG_ACC 0x2
+#define BT463_PALETTE 0x3
+
+#define BT463_CUR_CLR_0 0x0100
+#define BT463_CUR_CLR_1 0x0101
+
+#define BT463_CMD_REG_0 0x0201
+#define BT463_CMD_REG_1 0x0202
+#define BT463_CMD_REG_2 0x0203
+
+#define BT463_READ_MASK_0 0x0205
+#define BT463_READ_MASK_1 0x0206
+#define BT463_READ_MASK_2 0x0207
+#define BT463_READ_MASK_3 0x0208
+
+#define BT463_BLINK_MASK_0 0x0209
+#define BT463_BLINK_MASK_1 0x020a
+#define BT463_BLINK_MASK_2 0x020b
+#define BT463_BLINK_MASK_3 0x020c
+
+#define BT463_WINDOW_TYPE_BASE 0x0300
+
+
+static unsigned
+BT463_READ(TGAPtr pTga, unsigned m, unsigned a)
+{
+ unsigned val;
+
+ BT463_LOAD_ADDR(a);
+ TGA_WRITE_REG((m<<2)|0x2, TGA_RAMDAC_SETUP_REG);
+ val = TGA_READ_REG(TGA_RAMDAC_REG);
+ val = (val >> 16) & 0xff;
+ return val;
+}
+
+
+void
+BT463ramdacSave(ScrnInfoPtr pScrn, unsigned char *Bt463)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+ int i, j;
+
+ Bt463[0] = BT463_READ(pTga, BT463_REG_ACC, BT463_CMD_REG_0);
+ Bt463[1] = BT463_READ(pTga, BT463_REG_ACC, BT463_CMD_REG_1);
+ Bt463[2] = BT463_READ(pTga, BT463_REG_ACC, BT463_CMD_REG_2);
+
+ Bt463[3] = BT463_READ(pTga, BT463_REG_ACC, BT463_READ_MASK_0);
+ Bt463[4] = BT463_READ(pTga, BT463_REG_ACC, BT463_READ_MASK_1);
+ Bt463[5] = BT463_READ(pTga, BT463_REG_ACC, BT463_READ_MASK_2);
+ Bt463[6] = BT463_READ(pTga, BT463_REG_ACC, BT463_READ_MASK_3);
+
+ Bt463[7] = BT463_READ(pTga, BT463_REG_ACC, BT463_BLINK_MASK_0);
+ Bt463[8] = BT463_READ(pTga, BT463_REG_ACC, BT463_BLINK_MASK_1);
+ Bt463[9] = BT463_READ(pTga, BT463_REG_ACC, BT463_BLINK_MASK_2);
+ Bt463[10] = BT463_READ(pTga, BT463_REG_ACC, BT463_BLINK_MASK_3);
+
+ BT463_LOAD_ADDR(BT463_WINDOW_TYPE_BASE);
+ TGA_WRITE_REG((BT463_REG_ACC<<2)|0x2, TGA_RAMDAC_SETUP_REG);
+
+ for (i = 0, j = 11; i < 16; i++) {
+ Bt463[j++] = (TGA_READ_REG(TGA_RAMDAC_REG)>>16)&0xff;
+ Bt463[j++] = (TGA_READ_REG(TGA_RAMDAC_REG)>>16)&0xff;
+ Bt463[j++] = (TGA_READ_REG(TGA_RAMDAC_REG)>>16)&0xff;
+ }
+
+/*
+ fprintf(stderr, "BT463ramdacSave (%p)\n", Bt463);
+ for (i=0; i<58; i++)
+ fprintf(stderr, "%2d: 0x%02x\n", i, (unsigned)Bt463[i]);
+*/
+}
+
+
+void
+BT463ramdacRestore(ScrnInfoPtr pScrn, unsigned char *Bt463)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+ int i, j;
+
+ BT463_WRITE(BT463_REG_ACC, BT463_CMD_REG_0, Bt463[0]);
+ BT463_WRITE(BT463_REG_ACC, BT463_CMD_REG_1, Bt463[1]);
+ BT463_WRITE(BT463_REG_ACC, BT463_CMD_REG_2, Bt463[2]);
+
+ BT463_WRITE(BT463_REG_ACC, BT463_READ_MASK_0, Bt463[3]);
+ BT463_WRITE(BT463_REG_ACC, BT463_READ_MASK_1, Bt463[4]);
+ BT463_WRITE(BT463_REG_ACC, BT463_READ_MASK_2, Bt463[5]);
+ BT463_WRITE(BT463_REG_ACC, BT463_READ_MASK_3, Bt463[6]);
+
+ BT463_WRITE(BT463_REG_ACC, BT463_BLINK_MASK_0, Bt463[7]);
+ BT463_WRITE(BT463_REG_ACC, BT463_BLINK_MASK_1, Bt463[8]);
+ BT463_WRITE(BT463_REG_ACC, BT463_BLINK_MASK_2, Bt463[9]);
+ BT463_WRITE(BT463_REG_ACC, BT463_BLINK_MASK_3, Bt463[10]);
+
+ BT463_LOAD_ADDR(BT463_WINDOW_TYPE_BASE);
+ TGA_WRITE_REG((BT463_REG_ACC<<2), TGA_RAMDAC_SETUP_REG);
+
+ for (i = 0, j = 11; i < 16; i++) {
+ TGA_WRITE_REG(Bt463[j++]|(BT463_REG_ACC<<10), TGA_RAMDAC_REG);
+ TGA_WRITE_REG(Bt463[j++]|(BT463_REG_ACC<<10), TGA_RAMDAC_REG);
+ TGA_WRITE_REG(Bt463[j++]|(BT463_REG_ACC<<10), TGA_RAMDAC_REG);
+ }
+
+/*
+ fprintf(stderr, "BT463ramdacRestore (%p)\n", Bt463);
+ for (i=0; i<58; i++)
+ fprintf(stderr, "%2d: 0x%02x\n", i, (unsigned)Bt463[i]);
+*/
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tga/BTramdac.c b/xc/programs/Xserver/hw/xfree86/drivers/tga/BTramdac.c
new file mode 100644
index 000000000..287f0206d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tga/BTramdac.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright 1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * tgaBTOutIndReg() and tgaBTInIndReg() are used to access
+ * the indirect TGA BT RAMDAC registers only.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/BTramdac.c,v 1.4 1999/02/07 11:11:14 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "tga_regs.h"
+#include "BT.h"
+#include "tga.h"
+
+void
+tgaBTOutIndReg(ScrnInfoPtr pScrn,
+ CARD32 reg, unsigned char mask, unsigned char data)
+{
+ TGAPtr pTga;
+ unsigned char tmp = 0x00;
+
+ pTga = TGAPTR(pScrn);
+
+ TGA_WRITE_REG(reg << 1 | BT485_READ_BIT, TGA_RAMDAC_SETUP_REG);
+
+ if (mask != 0x00)
+ tmp = (TGA_READ_REG(TGA_RAMDAC_REG)>>16) & mask;
+
+ TGA_WRITE_REG(reg << 1 | BT485_WRITE_BIT, TGA_RAMDAC_SETUP_REG);
+
+ TGA_WRITE_REG ((tmp | data) | (reg<<9), TGA_RAMDAC_REG);
+}
+
+unsigned char
+tgaBTInIndReg (ScrnInfoPtr pScrn, CARD32 reg)
+{
+ TGAPtr pTga;
+ unsigned char ret;
+
+ pTga = TGAPTR(pScrn);
+
+ TGA_WRITE_REG(reg << 1 | BT485_READ_BIT, TGA_RAMDAC_SETUP_REG);
+ ret = TGA_READ_REG (TGA_RAMDAC_REG)>>16;
+
+ return (ret);
+}
+
+void
+tgaBTWriteAddress (ScrnInfoPtr pScrn, CARD32 index)
+{
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+
+ TGA_WRITE_REG(BT_WRITE_ADDR << 1 | BT485_WRITE_BIT, TGA_RAMDAC_SETUP_REG);
+ TGA_WRITE_REG(index | (BT_WRITE_ADDR<<9), TGA_RAMDAC_REG);
+ TGA_WRITE_REG(BT_RAMDAC_DATA << 1 | BT485_WRITE_BIT, TGA_RAMDAC_SETUP_REG);
+}
+
+void
+tgaBTWriteData (ScrnInfoPtr pScrn, unsigned char data)
+{
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+
+ TGA_WRITE_REG(data | (BT_RAMDAC_DATA << 9), TGA_RAMDAC_REG);
+}
+
+void
+tgaBTReadAddress (ScrnInfoPtr pScrn, CARD32 index)
+{
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+
+ TGA_WRITE_REG(BT_PIXEL_MASK << 1 | BT485_WRITE_BIT, TGA_RAMDAC_SETUP_REG);
+ TGA_WRITE_REG(0xFF | (BT_PIXEL_MASK<<9), TGA_RAMDAC_REG);
+ TGA_WRITE_REG(BT_READ_ADDR << 1 | BT485_WRITE_BIT, TGA_RAMDAC_SETUP_REG);
+ TGA_WRITE_REG(index | (BT_READ_ADDR<<9), TGA_RAMDAC_REG);
+ TGA_WRITE_REG(BT_RAMDAC_DATA << 1 | BT485_READ_BIT, TGA_RAMDAC_SETUP_REG);
+}
+
+unsigned char
+tgaBTReadData (ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+
+ return(TGA_READ_REG(TGA_RAMDAC_REG)>>16);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tga/ICS1562.c b/xc/programs/Xserver/hw/xfree86/drivers/tga/ICS1562.c
new file mode 100644
index 000000000..ac72b24e7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tga/ICS1562.c
@@ -0,0 +1,114 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/ICS1562.c,v 1.3 1999/04/17 07:06:56 dawes Exp $ */
+
+#define BASE_FREQ 14.31818
+#define MAX_FREQ 230000
+
+#define reorder(a) ( \
+ (a & 0x80) >> 7 | \
+ (a & 0x40) >> 5 | \
+ (a & 0x20) >> 3 | \
+ (a & 0x10) >> 1 | \
+ (a & 0x08) << 1 | \
+ (a & 0x04) << 3 | \
+ (a & 0x02) << 5 | \
+ (a & 0x01) << 7 )
+
+#define CHECK_MIN(m,a,r,n) do { \
+ diff = f - (BASE_FREQ * 1e3 * (n)) / (r << p); \
+ if (diff < 0) diff = -diff; \
+ if (diff < min_diff) { \
+ min_diff = diff; \
+ best_m = m; \
+ best_a = a; \
+ best_r = r; \
+ } \
+ } while(0)
+
+
+static void Set_1562_PLL(int f, int p, int m, int a, int r, unsigned char *bits)
+{
+ bits[0] = 0x80; /* N1 = 4, not used for PLL */
+ bits[1] = reorder(p) >> 4;
+ bits[2] = 0x00; /* N2 = 1 */
+ if (f <= 120000)
+ bits[3] = 0x20; /* V = 100 */
+ else if (f <= 200000)
+ bits[3] = 0xa0; /* V = 101 */
+ else
+ bits[3] = 0x60; /* V = 110 */
+ bits[3] |= 0x05; /* P = 10, phase detector on */
+ bits[4] = reorder(m);
+ bits[5] = reorder(a);
+ bits[6] = reorder(r);
+
+#ifdef DEBUG
+ {
+ int i;
+ for(i=0; i<7; i++)
+ ErrorF("%02x ", bits[i]);
+ ErrorF("\n");
+ }
+#endif
+}
+
+void ICS1562_CalcClockBits(long f, unsigned char *bits);
+
+void ICS1562_CalcClockBits(long f, unsigned char *bits)
+{
+ int n,r, a,m, p, r0,r1,n0,n1;
+ int best_m=34, best_a=1, best_r=30;
+ double diff, min_diff;
+ double ff, ffp;
+
+ if (f > MAX_FREQ)
+ f = MAX_FREQ;
+
+ if (f >= MAX_FREQ/2)
+ p=0;
+ else if (f >= MAX_FREQ/4)
+ p=1;
+ else
+ p=2;
+
+ ff = f / 1e3 / BASE_FREQ;
+ ffp = ff * (1 << p);
+ min_diff = 999999999;
+
+ r0 = (int)(7/ffp);
+ if (r0 < 1) r0 = 1;
+ r1 = (int)(449/ffp);
+ if (r1 > 0x7f+1) r1 = 0x7f+1;
+ if (r1 < r0) r1 = r0;
+
+ for (r=r0; r<r1; r++) {
+ n0 = (int)(ffp * r);
+ if (n0 < 7) n0 = 7;
+ n1 = (int)(ffp * (r+1));
+ if (n1 > 448) n1 = 448;
+ for (n=n0; n<n1; n++) {
+ m = ((n+3)/7) - 1;
+ if (m <= 0x3f) CHECK_MIN(m, 0, r, (m+1)*7);
+ if (++m <= 0x3f) CHECK_MIN(m, 0, r, (m+1)*7);
+ m = (n/6) - 1;
+ a = n - (m+1)*6;
+ if (m <= 0x3f && a > 0 && a<=7) CHECK_MIN(m, a, r, (m+1)*6+a);
+ m++;
+ a = n - (m+1)*6;
+ if (m <= 0x3f && a > 0 && a<=7) CHECK_MIN(m, a, r, (m+1)*6+a);
+ }
+ }
+
+ if (best_a) n = (best_m+1)*6+best_a;
+ else n = (best_m+1)*7;
+
+#ifdef DEBUG
+ ErrorF("%8.3f %f %f p=%d m=%d a=%d r=%d %d/%d\n"
+ ,f/1e3
+ ,min_diff,(BASE_FREQ * (n)) / (best_r << p)
+ ,p ,best_m, best_a, best_r-1
+ ,n,best_r
+ );
+#endif
+
+ Set_1562_PLL(f, p, best_m, best_a, best_r-1, bits);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tga/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/tga/Imakefile
new file mode 100644
index 000000000..ae7ede741
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tga/Imakefile
@@ -0,0 +1,47 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/Imakefile,v 1.10 1999/08/14 10:49:55 dawes Exp $
+XCOMM
+XCOMM This is an Imakefile for the TGA driver.
+XCOMM
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = tga_driver.c tga_dac.c tga_accel8.c tga_accel32.c BTramdac.c ICS1562.c BT463ramdac.c tga_cursor.c
+OBJS = tga_driver.o tga_dac.o tga_accel8.o tga_accel32.o BTramdac.o ICS1562.o BT463ramdac.o tga_cursor.o
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/Xext \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \
+ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \
+ -I$(XF86SRC)/rac \
+ /*-I$(FONTINCSRC)*/ -I$(SERVERSRC)/include -I$(XINCLUDESRC)
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget(tga,$(OBJS))
+
+InstallObjectModule(tga,$(MODULEDIR),drivers)
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(BT463ramdac.c,$(DRIVERSDKDIR)/drivers/tga)
+InstallDriverSDKNonExecFile(BTramdac.c,$(DRIVERSDKDIR)/drivers/tga)
+InstallDriverSDKNonExecFile(ICS1562.c,$(DRIVERSDKDIR)/drivers/tga)
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/tga)
+InstallDriverSDKNonExecFile(tga.h,$(DRIVERSDKDIR)/drivers/tga)
+InstallDriverSDKNonExecFile(tga_accel32.c,$(DRIVERSDKDIR)/drivers/tga)
+InstallDriverSDKNonExecFile(tga_accel8.c,$(DRIVERSDKDIR)/drivers/tga)
+InstallDriverSDKNonExecFile(tga_cursor.c,$(DRIVERSDKDIR)/drivers/tga)
+InstallDriverSDKNonExecFile(tga_dac.c,$(DRIVERSDKDIR)/drivers/tga)
+InstallDriverSDKNonExecFile(tga_driver.c,$(DRIVERSDKDIR)/drivers/tga)
+InstallDriverSDKNonExecFile(tga_regs.h,$(DRIVERSDKDIR)/drivers/tga)
+
+InstallDriverSDKObjectModule(tga,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tga/tga.h b/xc/programs/Xserver/hw/xfree86/drivers/tga/tga.h
new file mode 100644
index 000000000..e8a792861
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tga/tga.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane <alanh@fairlite.demon.co.uk>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga.h,v 1.11 1999/07/10 12:17:34 dawes Exp $ */
+
+#ifndef _TGA_H_
+#define _TGA_H_
+
+#include "xaa.h"
+#include "xf86RamDac.h"
+
+typedef struct {
+ unsigned long tgaRegs[0x100];
+} TGARegRec, *TGARegPtr;
+
+#define TGAPTR(p) ((TGAPtr)((p)->driverPrivate))
+
+typedef struct {
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ int Chipset;
+ RamDacHelperRecPtr RamDac;
+ int ChipRev;
+ int HwBpp;
+ int BppShift;
+ int pprod;
+ CARD32 IOAddress;
+ CARD32 FbAddress;
+ unsigned char * FbBase;
+ unsigned char * IOBase;
+ long FbMapSize;
+ unsigned long regOffset;
+ Bool NoAccel;
+/* Bool Dac6Bit; */
+ Bool HWCursor;
+ Bool UsePCIRetry;
+ int MinClock;
+ int MaxClock;
+ TGARegRec SavedReg;
+ TGARegRec ModeReg;
+ CARD32 AccelFlags;
+ RamDacRecPtr RamDacRec;
+ XAAInfoRecPtr AccelInfoRec;
+ xf86CursorInfoPtr CursorInfoRec;
+ CloseScreenProcPtr CloseScreen;
+ int CardType;
+ unsigned char Bt463modeReg[59];
+ unsigned char Bt463saveReg[59];
+ EntityInfoPtr pEnt;
+#ifdef __alpha__
+ CARD64 *buffers[1];
+#endif
+ unsigned int current_rop;
+ int transparent_pattern_p;
+ int blitdir;
+ int block_or_opaque_p;
+ int ce_height;
+ int ce_width;
+ int ce_x;
+ int ce_y;
+ int ce_skipleft;
+} TGARec, *TGAPtr;
+
+/* Prototypes */
+
+/* tga_dac.c */
+void DEC21030Restore(ScrnInfoPtr pScrn,/* vgaRegPtr vgaReg,*/
+ TGARegPtr tgaReg/*, Bool restoreFonts*/);
+void DEC21030Save(ScrnInfoPtr pScrn, /*vgaRegPtr vgaReg,*/ TGARegPtr tgaReg/*,
+ Bool saveFonts*/);
+Bool DEC21030Init(ScrnInfoPtr pScrn, DisplayModePtr mode);
+
+/* tga_accel8.c */
+Bool DEC21030AccelInit8(ScreenPtr pScreen);
+
+/* tga_accel32.c */
+Bool DEC21030AccelInit32(ScreenPtr pScreen);
+
+/* BTramdac.c */
+void tgaBTOutIndReg(ScrnInfoPtr pScrn,
+ CARD32 reg, unsigned char mask, unsigned char data);
+unsigned char tgaBTInIndReg(ScrnInfoPtr pScrn, CARD32 reg);
+void tgaBTWriteAddress(ScrnInfoPtr pScrn, CARD32 index);
+void tgaBTReadAddress(ScrnInfoPtr pScrn, CARD32 index);
+void tgaBTWriteData(ScrnInfoPtr pScrn, unsigned char data);
+unsigned char tgaBTReadData(ScrnInfoPtr pScrn);
+
+/* BT463ramdac.c */
+void BT463ramdacSave(ScrnInfoPtr pScrn, unsigned char *data);
+void BT463ramdacRestore(ScrnInfoPtr pScrn, unsigned char *data);
+
+/* tga_cursor.c */
+Bool TGAHWCursorInit(ScreenPtr pScreen);
+
+#endif /* _TGA_H_ */
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_accel32.c b/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_accel32.c
new file mode 100644
index 000000000..9e0841da9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_accel32.c
@@ -0,0 +1,739 @@
+/*
+ * Copyright 1996,1997 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
+ *
+ * DEC TGA accelerated options.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_accel32.c,v 1.3 1999/07/10 12:17:35 dawes Exp $ */
+
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+/*
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+*/
+#include "micmap.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86cmap.h"
+#include "mipointer.h"
+
+#include "mibstore.h"
+#include "miline.h"
+
+#include "tga_regs.h"
+#include "BT.h"
+#include "tga.h"
+
+/* defines */
+
+#define BLIT_FORWARDS 0
+#define BLIT_BACKWARDS 1
+#define BLIT_LEFT 0
+#define BLIT_RIGHT 1
+#define USE_BLOCK_FILL 2
+#define USE_OPAQUE_FILL 3
+#define MIX_SRC 0x03
+
+/* prototypes */
+
+static unsigned int __inline__ fb_offset(ScrnInfoPtr pScrn, int x, int y);
+static void TGACopyLineForwards(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int w);
+static void TGACopyLineBackwards(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int w);
+static void TGASync(ScrnInfoPtr pScrn);
+static void TGASetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+static void TGASubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h);
+static void TGASetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned int planemask,
+ int transparency_color);
+static void TGASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h);
+static void TGASetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void TGASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx,
+ int paty, int x, int y, int w,
+ int h);
+
+/* static int block_or_opaque_p; */
+static int blitdirY, blitdirX;
+/* static unsigned int current_rop; */
+/* static int transparent_pattern_p; */
+
+
+/*
+ * The following function sets up the supported acceleration. Call it
+ * from the FbInit() function in the SVGA driver.
+ */
+Bool
+DEC21030AccelInit32(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr TGA_AccelInfoRec;
+ BoxRec AvailFBArea;
+ ScrnInfoPtr pScrn;
+
+ /* ErrorF("DEC21030AccelInit called!"); */
+
+ /* first, create the XAAInfoRec */
+ TGA_AccelInfoRec = XAACreateInfoRec();
+
+ /* ErrorF("XAACreateInfoRec called"); */
+
+ TGA_AccelInfoRec->Flags = PIXMAP_CACHE | LINEAR_FRAMEBUFFER |
+ OFFSCREEN_PIXMAPS;
+
+ TGA_AccelInfoRec->Sync = TGASync;
+
+ TGA_AccelInfoRec->SolidFillFlags = 0;
+ TGA_AccelInfoRec->SetupForSolidFill = TGASetupForSolidFill;
+ TGA_AccelInfoRec->SubsequentSolidFillRect = TGASubsequentSolidFillRect;
+
+/*
+ TGA_AccelInfoRec->ScreenToScreenCopyFlags = NO_TRANSPARENCY |
+ ONLY_LEFT_TO_RIGHT_BITBLT;
+ TGA_AccelInfoRec->SetupForScreenToScreenCopy =
+ TGASetupForScreenToScreenCopy;
+ TGA_AccelInfoRec->SubsequentScreenToScreenCopy =
+ TGASubsequentScreenToScreenCopy;
+*/
+
+ TGA_AccelInfoRec->Mono8x8PatternFillFlags =
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ BIT_ORDER_IN_BYTE_LSBFIRST;
+ TGA_AccelInfoRec->SetupForMono8x8PatternFill =
+ TGASetupForMono8x8PatternFill;
+ TGA_AccelInfoRec->SubsequentMono8x8PatternFillRect =
+ TGASubsequentMono8x8PatternFillRect;
+
+ /* initialize the pixmap cache */
+
+ pScrn = xf86Screens[pScreen->myNum];
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0; /* these gotta be 0 */
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = (pScrn->videoRam * 1024) / (pScrn->displayWidth * 4);
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ TGA_AccelInfoRec->PixmapCacheFlags = 0;
+
+ /* initialize XAA */
+ return(XAAInit(pScreen, TGA_AccelInfoRec));
+}
+
+unsigned int __inline__
+fb_offset(ScrnInfoPtr pScrn, int x, int y)
+{
+ return((y * pScrn->displayWidth * 4) + x*4);
+}
+
+/*
+ * This is the implementation of the Sync() function.
+ */
+void
+TGASync(ScrnInfoPtr pScrn)
+{
+#if 0
+ mb();
+ while (TGA_READ_REG(TGA_CMD_STAT_REG) & 0x01);
+#endif
+ return;
+}
+
+/*
+ 1) translate the source and destination addresses into PCI addresses
+ 2) compute the mask source and mask destination
+ 3) compute the pixel shift
+ 4) write mask source to address source
+ 5) write mask destination to address destination
+
+ Mask source and mask destination specify which pixels are read or written
+*/
+
+/* Block Fill mode is faster, but only works for certain rops. So we will
+ have to implement Opaque Fill anyway, so we will do that first, then
+ do Block Fill for the special cases
+*/
+void
+TGASetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ register unsigned long iobase, offset;
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+ /* ErrorF("TGASetupForSolidFill called"); */
+
+ if(rop == MIX_SRC) { /* we can just do a block copy */
+ pTga->block_or_opaque_p = USE_BLOCK_FILL;
+ TGA_FAST_WRITE_REG(color, TGA_BLOCK_COLOR0_REG);
+ TGA_FAST_WRITE_REG(color, TGA_BLOCK_COLOR1_REG);
+ TGA_FAST_WRITE_REG(color, TGA_BLOCK_COLOR2_REG);
+ TGA_FAST_WRITE_REG(color, TGA_BLOCK_COLOR3_REG);
+ TGA_FAST_WRITE_REG(color, TGA_BLOCK_COLOR4_REG);
+ TGA_FAST_WRITE_REG(color, TGA_BLOCK_COLOR5_REG);
+ TGA_FAST_WRITE_REG(color, TGA_BLOCK_COLOR6_REG);
+ TGA_FAST_WRITE_REG(color, TGA_BLOCK_COLOR7_REG);
+ }
+ else {
+ pTga->block_or_opaque_p = USE_OPAQUE_FILL;
+ pTga->current_rop = rop | BPP24;
+ TGA_FAST_WRITE_REG(color, TGA_FOREGROUND_REG);
+/* ErrorF("opaque fill called\n"); */
+ }
+
+ TGA_FAST_WRITE_REG(planemask, TGA_PLANEMASK_REG);
+/*
+ TGA_FAST_WRITE_REG((planemask | (planemask << 8) |
+ (planemask << 16) |
+ (planemask << 24)), TGA_PLANEMASK_REG);
+*/
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_DATA_REG);
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+void
+TGASubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ unsigned int mode_reg = 0;
+ int i = 0;
+ unsigned int pixel_count = 0; /* the actual # of pixels to be written */
+ unsigned int write_data = 0; /* the actual data written */
+ int a1 = 0;
+#ifdef PROFILE
+ unsigned int stop, start;
+#endif
+ register unsigned long iobase, offset;
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ /* ErrorF("TGASubsequentFillRectSolid called\n"); */
+
+ if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) {
+ mode_reg = OPAQUEFILL | X11 | BPP24;
+ TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG);
+ /* we have to set this to GXCOPY every time before we exit */
+ }
+ else
+ mode_reg = BLOCKFILL | X11 | BPP24;
+
+ TGA_FAST_WRITE_REG(mode_reg, TGA_MODE_REG);
+
+ if(w > 2048) {
+ ErrorF("TGASubsequentSolidFillRect called with w = %d, truncating.\n");
+ w = 2048;
+ }
+ pixel_count = w - 1;
+
+ for(i = 0; i < h; i++) {
+ a1 = fb_offset(pScrn, x, y + i);
+ if(pTga->block_or_opaque_p == USE_OPAQUE_FILL)
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG);
+ write_data = pixel_count;
+ TGA_FAST_WRITE_REG(a1, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(write_data, TGA_CONTINUE_REG);
+ }
+
+ mode_reg = SIMPLE | X11 | BPP24;
+ TGA_FAST_WRITE_REG(mode_reg, TGA_MODE_REG);
+ if(pTga->block_or_opaque_p == USE_OPAQUE_FILL)
+ TGA_FAST_WRITE_REG(MIX_SRC | BPP24, TGA_RASTEROP_REG); /* GXCOPY */
+
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+/* we only need to calculate the direction of a move once per move,
+ so we do it in the setup function and leave it */
+
+void
+TGASetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned int planemask,
+ int transparency_color)
+ /* xdir 1 = left-to-right, -1 = right to left
+ ydir 1 = top-to-bottom, -1 = bottom to top
+ */
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ register unsigned long iobase, offset;
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ /* see section 6.2.9 */
+
+ ErrorF("TGASetupForScreenToScreenCopy (xdir=%2d ydir=%2d)\n", xdir, ydir);
+
+ TGA_FAST_WRITE_REG(planemask, TGA_PLANEMASK_REG);
+
+ pTga->current_rop = rop;
+ if(pTga->current_rop == MIX_SRC)
+ TGA_FAST_WRITE_REG(pTga->current_rop | BPP24, TGA_RASTEROP_REG);
+
+ /* do we copy a rectangle from top to bottom or bottom to top? */
+ if(ydir == -1)
+ blitdirY = BLIT_FORWARDS;
+ else
+ blitdirY = BLIT_BACKWARDS;
+
+ if(xdir == -1)
+ blitdirX = BLIT_BACKWARDS;
+ else
+ blitdirX = BLIT_FORWARDS;
+
+ TGA_SAVE_OFFSET();
+ return;
+}
+/*
+ * This is the implementation of the SubsequentForScreenToScreenCopy
+ * that sends commands to the coprocessor to perform a screen-to-screen
+ * copy of the specified areas, with the parameters from the SetUp call.
+ */
+void
+TGASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int w, int h)
+{
+ /* x1, y1 = source coords
+ x2, y2 = destination coords
+ w = width
+ h = height
+ */
+
+ int i = 0, mode_reg = 0;
+ void (*copy_func)(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w);
+#ifdef PROFILE
+ unsigned int stop, start;
+#endif
+ register unsigned long iobase, offset;
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ ErrorF("TGASubsequentScreenToScreenCopy(x1=%4d y1=%4d x2=%4d y2=%4d w=%4d h=%4d\n",
+ x1, y1, x2, y2, w, h);
+
+ mode_reg = COPY | X11 | BPP24 | (0x3<<8); /* the others are 0 but what the
+ heck */
+ TGA_FAST_WRITE_REG(mode_reg, TGA_MODE_REG);
+ if(pTga->current_rop != MIX_SRC)
+ TGA_FAST_WRITE_REG(pTga->current_rop | BPP24, TGA_RASTEROP_REG);
+
+
+ if (blitdirX == BLIT_FORWARDS) {
+/* if(x2 > x1 && (x1 + w) > x2) { */
+ fprintf(stderr, " ----->>>>> \n");
+ copy_func = TGACopyLineForwards;
+ } else {
+ fprintf(stderr, " <<<<<----- \n");
+ copy_func = TGACopyLineBackwards;
+ }
+
+ TGA_SAVE_OFFSET();
+ if(blitdirY == BLIT_FORWARDS) {
+ for(i = h - 1; i >= 0; i--) { /* copy from bottom to top */
+ (*copy_func)(pScrn, x1, y1 + i, x2, y2 + i, w);
+ }
+ }
+ else {
+ for(i = 0; i < h; i++) {
+ (*copy_func)(pScrn, x1, y1 + i, x2, y2 + i, w);
+ }
+ }
+
+ TGA_GET_OFFSET();
+ mode_reg = SIMPLE | X11 | BPP24;
+ TGA_FAST_WRITE_REG(mode_reg,TGA_MODE_REG);
+ if(pTga->current_rop != MIX_SRC)
+ TGA_FAST_WRITE_REG(MIX_SRC | BPP24, TGA_RASTEROP_REG);
+ TGA_SAVE_OFFSET();
+
+ return;
+}
+
+
+void
+TGACopyLineForwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w)
+{
+ /* copy a line of width w from x1,y1 to x2,y2 using copy mode */
+ int read, span_dir, line_dir;
+ unsigned long source_address, destination_address;
+ unsigned int mask_source, mask_destination;
+ int source_align, destination_align;
+ int pixel_shift;
+ register unsigned long iobase, offset;
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ span_dir = BLIT_FORWARDS;
+ line_dir = BLIT_FORWARDS;
+
+ source_address = fb_offset(pScrn, x1, y1);
+ destination_address = fb_offset(pScrn, x2, y2);
+
+ read = 0;
+ while(read < w) {
+ mask_source = 0xFFFFFFFF;
+ if((w - read) >= 16)
+ mask_destination = 0xFFFFFFFF;
+ else
+ mask_destination = ((unsigned int)0xFFFFFFFF) >> (16 - (w - read));
+ source_align = source_address & 0x04;
+ destination_align = destination_address & 0x04;
+ source_address = source_address - source_align;
+ mask_source <<= source_align;
+ destination_address = destination_address - destination_align;
+ mask_destination <<= destination_align;
+
+ if(destination_align >= source_align)
+ pixel_shift = destination_align - source_align;
+ else {
+ pixel_shift = 8 - (source_align - destination_align);
+ /* we need to prime the residue register in this case */
+ destination_address = destination_address - 4*8;
+ mask_destination <<= 8;
+ }
+
+ TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG);
+ /* use GADR and GCTR */
+ TGA_FAST_WRITE_REG(source_address, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(mask_source, TGA_CONTINUE_REG);
+ TGA_FAST_WRITE_REG(destination_address, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(mask_destination, TGA_CONTINUE_REG);
+
+ source_address = source_address + 4*(16 - pixel_shift);
+ destination_address += 16*4;
+
+ read += 16;
+ read -= destination_align; /* "read" is perhaps better
+ called "written"... */
+ if(destination_align < source_align) {
+ read -= 8;
+ }
+ }
+
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+
+void
+TGACopyLineBackwards(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int w)
+ /* x1, y1 = source
+ x2, y2 = destination
+ w = width
+ */
+{
+ unsigned long a1, a2;
+ unsigned long source_address, destination_address;
+ unsigned int mask_source, mask_destination;
+ int source_align, destination_align;
+ int pixel_shift;
+ int read;
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ register unsigned long iobase, offset;
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ a1 = fb_offset(pScrn, x1, y1);
+ a2 = fb_offset(pScrn, x2, y2);
+
+ source_address = fb_offset(pScrn, (x1 + w) - 16, y1);
+ destination_address = fb_offset(pScrn, (x2 + w) - 16, y2);
+ source_align = source_address & 0x04;
+ destination_align = destination_address & 0x04;
+/*
+ ErrorF("source_align=%d sestination_align=%d\n",
+ source_align, destination_align);
+*/
+
+ read = 0;
+ while(read < w) {
+ mask_source = 0xFFFFFFFF;
+ if((w - read) >= 16)
+ mask_destination = 0xFFFFFFFF;
+ else
+ mask_destination = ((unsigned int)0xFFFFFFFF) << (16 - (w - read));
+
+ if(read == 0 && destination_align &&
+ (source_align > destination_align)) {
+ /* we want to take out all the destination_align pixels in one
+ little copy first, then move on to the main stuff */
+ unsigned long tmp_src, tmp_dest;
+ unsigned int tmp_src_mask, tmp_dest_mask;
+
+ tmp_src = (a1 + w) - source_align;
+ tmp_dest = ((a2 + w) - destination_align) - 8;
+ tmp_src_mask = 0xFFFFFFFF;
+ tmp_dest_mask = ((unsigned int)0x000000FF) >> (8 - destination_align);
+ tmp_dest_mask <<= 8;
+ pixel_shift = (8 - source_align) + destination_align;
+
+ TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG);
+ TGA_FAST_WRITE_REG(tmp_src, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(tmp_src_mask, TGA_CONTINUE_REG);
+ TGA_FAST_WRITE_REG(tmp_dest, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(tmp_dest_mask, TGA_CONTINUE_REG);
+
+/* ErrorF("premature copy: sa = %d, da = %d, ps =%d\n", source_align, */
+/* destination_align, pixel_shift); */
+
+ source_address += 4*(8 - source_align);
+ mask_source >>= (8 - source_align);
+ mask_source >>= destination_align;
+ mask_destination >>= destination_align;
+ }
+ else if(read == 0 && (source_align != destination_align)) {
+ source_address += 4*(8 - source_align);
+ /* mask_source >>= (8 - source_align); */
+ /* if we comment this out, it breaks...TGA tries to
+ optimize away a read of our last pixels... */
+ }
+ else if(source_align) {
+ source_address += 4*(8 - source_align);
+ mask_source >>= (8 - source_align);
+ }
+ if(destination_align) {
+ destination_address += 4*(8 - destination_align);
+ mask_destination >>= (8 - destination_align);
+ }
+
+ if(destination_align >= source_align)
+ pixel_shift = destination_align - source_align;
+ else {
+ pixel_shift = (8 - source_align) + destination_align;
+ if(destination_align) {
+ source_address += 8*4;
+ mask_source >>= 8;
+ }
+ }
+
+ TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG);
+ /* use GADR and GCTR */
+ TGA_FAST_WRITE_REG(source_address, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(mask_source, TGA_CONTINUE_REG);
+ TGA_FAST_WRITE_REG(destination_address, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(mask_destination, TGA_CONTINUE_REG);
+
+/* if(read == 0) */
+/* ErrorF("sa = %d, da = %d, ps = %d\n", source_align, destination_align, */
+/* pixel_shift); */
+
+ if(destination_align > source_align) {
+ source_address -= 8*4;
+ destination_address -= 4*(16 - pixel_shift);
+ if(read == 0)
+ read += 8 + source_align;
+ else
+ read += 8;
+ }
+ else if(destination_align == source_align) {
+ source_address -= 16*4;
+ destination_address -= 16*4;
+ if(read == 0 && destination_align)
+ read += (16 - (8 - destination_align));
+ else
+ read += 16;
+ }
+ else if(source_align > destination_align) {
+ source_address -= 8*4;
+ destination_address -= 4*(16 - pixel_shift);
+ /* only happens when read == 0 */
+ if(destination_align)
+ read += 8 + source_align;
+ else
+ read += 16 - pixel_shift;
+ }
+ }
+
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+void
+TGASetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
+ int fg, int bg, int rop, unsigned int planemask)
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ register unsigned long iobase, offset;
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+/* ErrorF("TGASetupForMono8x8PatternFill called with patx = %d, paty = %d, fg = %d, bg = %d, rop = %d, planemask = %d\n", */
+/* patx, paty, fg, bg, rop, planemask); */
+ if(bg == -1) /* we are transparent */
+ pTga->transparent_pattern_p = 1;
+ else
+ pTga->transparent_pattern_p = 0;
+
+ if(rop == MIX_SRC)
+ pTga->block_or_opaque_p = USE_BLOCK_FILL;
+ else
+ pTga->block_or_opaque_p = USE_OPAQUE_FILL;
+
+ if(pTga->transparent_pattern_p && pTga->block_or_opaque_p == USE_BLOCK_FILL) {
+ /* we can use block fill mode to draw a transparent stipple */
+ TGA_FAST_WRITE_REG(fg, TGA_BLOCK_COLOR0_REG);
+ TGA_FAST_WRITE_REG(fg, TGA_BLOCK_COLOR1_REG);
+ TGA_FAST_WRITE_REG(fg, TGA_BLOCK_COLOR2_REG);
+ TGA_FAST_WRITE_REG(fg, TGA_BLOCK_COLOR3_REG);
+ TGA_FAST_WRITE_REG(fg, TGA_BLOCK_COLOR4_REG);
+ TGA_FAST_WRITE_REG(fg, TGA_BLOCK_COLOR5_REG);
+ TGA_FAST_WRITE_REG(fg, TGA_BLOCK_COLOR6_REG);
+ TGA_FAST_WRITE_REG(fg, TGA_BLOCK_COLOR7_REG);
+ }
+ else if(pTga->transparent_pattern_p) {
+ TGA_FAST_WRITE_REG(fg, TGA_FOREGROUND_REG);
+ }
+ else {
+ TGA_FAST_WRITE_REG(bg, TGA_BACKGROUND_REG);
+ TGA_FAST_WRITE_REG(fg, TGA_FOREGROUND_REG);
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG);
+ }
+ pTga->current_rop = rop;
+ TGA_FAST_WRITE_REG(planemask, TGA_PLANEMASK_REG);
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+void
+TGASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty,
+ int x, int y, int w, int h)
+/* patx and paty = first & second dwords of pattern to be rendered, packed */
+{
+ TGAPtr pTga;
+ int i, j;
+ unsigned int stipple_mask[8], align, tmp;
+#ifdef PROFILE
+ register unsigned int stop, start;
+#endif
+ register unsigned long iobase, offset;
+
+/* ErrorF("TGASubsequentMono8x8PatternFillRect called with x = %4d, y = %4d, w = %4d, h = %4d\n", x, y, w, h); */
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ if(w > 2048)
+ ErrorF("TGASubsequentMono8x8PatternFillRect called with w > 2048, truncating\n");
+ if(pTga->block_or_opaque_p == USE_OPAQUE_FILL)
+ TGA_FAST_WRITE_REG(pTga->current_rop | BPP24, TGA_RASTEROP_REG);
+
+ align = x%4;
+
+ for(i = 0; i < 4; i++) {
+ tmp = (patx >> (i * 8)) & 0xFF;
+ stipple_mask[i] = (tmp | (tmp << 8) | (tmp << 16) | (tmp << 24));
+ }
+ for(i = 4; i < 8; i++) {
+ tmp = (paty >> ((i - 4) * 8)) & 0xFF;
+ stipple_mask[i] = (tmp | (tmp << 8) | (tmp << 16) | (tmp << 24));
+ }
+
+ if(align) { /* stipples must be aligned to four bytes */
+ for(i = 0; i < 8; i++) {
+ stipple_mask[i] = (stipple_mask[i] << align) |
+ ((stipple_mask[i] & 0xFF000000) >> (32 - align));
+ }
+ }
+
+ if((pTga->block_or_opaque_p == USE_BLOCK_FILL) && pTga->transparent_pattern_p) {
+ /* use block fill */
+ /* ErrorF("Using block fill mode\n"); */
+ TGA_FAST_WRITE_REG(BLOCKFILL | X11 | BPP24, TGA_MODE_REG);
+
+ for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) {
+ TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG);
+ TGA_FAST_WRITE_REG(fb_offset(pScrn, x, y + i), TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG);
+ }
+ }
+ else if(pTga->transparent_pattern_p) {
+ /* if we can't use block fill, we'll use transparent fill */
+ /* ErrorF("Using transparent fill mode\n"); */
+ TGA_FAST_WRITE_REG(TRANSPARENTFILL | X11 | BPP24, TGA_MODE_REG);
+ for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) {
+ TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG);
+ TGA_FAST_WRITE_REG(fb_offset(pScrn, x, y + i), TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG);
+ }
+ }
+ else { /* use opaque fill mode */
+ /* ErrorF("Using opaque fill mode\n"); */
+ TGA_FAST_WRITE_REG(OPAQUEFILL | X11 | BPP24, TGA_MODE_REG);
+ for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) {
+ TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG);
+ TGA_FAST_WRITE_REG(fb_offset(pScrn, x, y + i), TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG);
+ }
+ }
+
+ TGA_FAST_WRITE_REG(SIMPLE | X11 | BPP24, TGA_MODE_REG);
+ if(pTga->current_rop != MIX_SRC)
+ TGA_FAST_WRITE_REG(MIX_SRC | BPP24, TGA_RASTEROP_REG);
+
+ TGA_SAVE_OFFSET();
+
+ return;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_accel8.c b/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_accel8.c
new file mode 100644
index 000000000..c9997aad4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_accel8.c
@@ -0,0 +1,947 @@
+/*
+ * Copyright 1996,1997 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
+ *
+ * DEC TGA accelerated options.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_accel8.c,v 1.4 1999/07/19 13:36:32 dawes Exp $ */
+
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+/*
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+*/
+#include "micmap.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86cmap.h"
+#include "mipointer.h"
+
+#include "mibstore.h"
+#include "miline.h"
+
+#include "tga_regs.h"
+#include "BT.h"
+#include "tga.h"
+
+/* defines */
+
+#define BLIT_FORWARDS 0
+#define BLIT_BACKWARDS 1
+#define USE_BLOCK_FILL 2
+#define USE_OPAQUE_FILL 3
+#define MIX_SRC 0x03
+
+/* prototypes */
+
+static unsigned int __inline__ fb_offset(ScrnInfoPtr pScrn, int x, int y);
+static void TGACopyLineForwards(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int w);
+static void TGACopyLineBackwards(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int w);
+static void TGASync();
+static void TGASetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+static void TGASubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h);
+static void TGASetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned int planemask,
+ int transparency_color);
+static void TGASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h);
+static void TGASetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void TGASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx,
+ int paty, int x, int y, int w,
+ int h);
+static void TGASetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask);
+
+static void
+TGASubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w,
+ int h, int skipleft);
+static void
+TGASubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
+
+/*
+static int block_or_opaque_p;
+static int blitdir;
+static unsigned int current_rop;
+static int transparent_pattern_p;
+*/
+
+
+/*
+ * The following function sets up the supported acceleration. Call it
+ * from the FbInit() function in the SVGA driver.
+ */
+Bool
+DEC21030AccelInit8(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr TGA_AccelInfoRec;
+ BoxRec AvailFBArea;
+ ScrnInfoPtr pScrn;
+ TGAPtr pTga;
+
+ pScrn = xf86Screens[pScreen->myNum];
+ pTga = TGAPTR(pScrn);
+
+ /* ErrorF("DEC21030AccelInit called!"); */
+
+ /* first, create the XAAInfoRec */
+ TGA_AccelInfoRec = XAACreateInfoRec();
+
+ /* ErrorF("XAACreateInfoRec called"); */
+
+ TGA_AccelInfoRec->Flags = PIXMAP_CACHE | LINEAR_FRAMEBUFFER |
+ OFFSCREEN_PIXMAPS;
+
+ TGA_AccelInfoRec->Sync = TGASync;
+
+/* solid fill */
+
+ TGA_AccelInfoRec->SolidFillFlags = 0;
+ TGA_AccelInfoRec->SetupForSolidFill = TGASetupForSolidFill;
+ TGA_AccelInfoRec->SubsequentSolidFillRect = TGASubsequentSolidFillRect;
+
+/* screen to screen copy */
+
+ TGA_AccelInfoRec->ScreenToScreenCopyFlags = NO_TRANSPARENCY;
+ TGA_AccelInfoRec->SetupForScreenToScreenCopy =
+ TGASetupForScreenToScreenCopy;
+ TGA_AccelInfoRec->SubsequentScreenToScreenCopy =
+ TGASubsequentScreenToScreenCopy;
+
+/* mono 8x8 pattern fill */
+
+ TGA_AccelInfoRec->Mono8x8PatternFillFlags =
+ HARDWARE_PATTERN_PROGRAMMED_BITS | BIT_ORDER_IN_BYTE_LSBFIRST;
+ TGA_AccelInfoRec->SetupForMono8x8PatternFill =
+ TGASetupForMono8x8PatternFill;
+ TGA_AccelInfoRec->SubsequentMono8x8PatternFillRect =
+ TGASubsequentMono8x8PatternFillRect;
+
+/* color expand */
+
+#ifdef __alpha__
+ TGA_AccelInfoRec->ScanlineCPUToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_LSBFIRST | LEFT_EDGE_CLIPPING;
+
+ TGA_AccelInfoRec->NumScanlineColorExpandBuffers = 1;
+ pTga->buffers[0] = (CARD64 *)malloc(1024); /* make it 8-byte aligned */
+ TGA_AccelInfoRec->ScanlineColorExpandBuffers =
+ (unsigned char **)pTga->buffers;
+ TGA_AccelInfoRec->SetupForScanlineCPUToScreenColorExpandFill =
+ TGASetupForScanlineCPUToScreenColorExpandFill;
+ TGA_AccelInfoRec->SubsequentScanlineCPUToScreenColorExpandFill =
+ TGASubsequentScanlineCPUToScreenColorExpandFill;
+ TGA_AccelInfoRec->SubsequentColorExpandScanline =
+ TGASubsequentColorExpandScanline;
+#endif
+
+ /* initialize the pixmap cache */
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0; /* these gotta be 0 */
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = (pScrn->videoRam * 1024) / (pScrn->displayWidth);
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ TGA_AccelInfoRec->PixmapCacheFlags = 0;
+
+ /* initialize XAA */
+ return(XAAInit(pScreen, TGA_AccelInfoRec));
+}
+
+unsigned int __inline__
+fb_offset(ScrnInfoPtr pScrn, int x, int y)
+{
+ return((y * pScrn->displayWidth) + x);
+}
+
+/*
+ * This is the implementation of the Sync() function.
+ */
+void
+TGASync()
+{
+#if 0
+ mb();
+ while (TGA_READ_REG(TGA_CMD_STAT_REG) & 0x01);
+#endif
+ return;
+}
+
+
+#ifdef __alpha__
+static void
+TGASetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ register unsigned long iobase, offset;
+ TGAPtr pTga;
+ unsigned int color;
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+/* ErrorF("TGASetupForScanlineCPUToScreenColorExpandFill called\n"); */
+
+ color = (fg | (fg << 8) | (fg << 16) | (fg << 24));
+
+ pTga->current_rop = rop | BPP8PACKED;
+ if(bg == -1) {
+ pTga->transparent_pattern_p = 1;
+ if(rop == MIX_SRC) {
+ pTga->block_or_opaque_p = USE_BLOCK_FILL;
+ TGA_FAST_WRITE_REG(color, TGA_BLOCK_COLOR0_REG);
+ TGA_FAST_WRITE_REG(color, TGA_BLOCK_COLOR1_REG);
+ }
+ else {
+ pTga->block_or_opaque_p = USE_OPAQUE_FILL;
+ TGA_FAST_WRITE_REG(color, TGA_FOREGROUND_REG);
+ }
+ }
+ else {
+ pTga->transparent_pattern_p = 0;
+ TGA_FAST_WRITE_REG((bg | (bg << 8) | (bg << 16) |
+ (bg << 24)), TGA_BACKGROUND_REG);
+ TGA_FAST_WRITE_REG(color, TGA_FOREGROUND_REG);
+ }
+
+ TGA_FAST_WRITE_REG((planemask | (planemask << 8) | (planemask << 16) |
+ (planemask << 24)), TGA_PLANEMASK_REG);
+ TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG);
+
+ TGA_SAVE_OFFSET();
+
+ return;
+}
+
+static void
+TGASubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w,
+ int h, int skipleft)
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ register unsigned long iobase, offset;
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+/* ErrorF("TGASubsequentScanlineCPUToScreenColorExpandFill called\n"); */
+/* ErrorF("w = %d, h = %d\n", w, h); */
+
+ pTga->ce_height = h;
+ pTga->ce_width = w;
+ pTga->ce_x = x;
+ pTga->ce_y = y;
+ pTga->ce_skipleft = skipleft;
+/* ErrorF("skipleft is %d\n", skipleft); */
+
+ if(pTga->transparent_pattern_p) {
+ if(pTga->block_or_opaque_p == USE_BLOCK_FILL)
+ TGA_FAST_WRITE_REG(BLOCKSTIPPLE | X11 | BPP8PACKED,
+ TGA_MODE_REG);
+ else
+ TGA_FAST_WRITE_REG(TRANSPARENTSTIPPLE | X11 | BPP8PACKED,
+ TGA_MODE_REG);
+/* ErrorF("transparent stipple with x = %d, y = %d, w = %d, h = %d\n", */
+/* x, y, w, h); */
+ }
+ else
+ TGA_FAST_WRITE_REG(OPAQUESTIPPLE | X11 | BPP8PACKED,
+ TGA_MODE_REG);
+
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+static void
+TGASubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ register unsigned long iobase, offset;
+ TGAPtr pTga;
+ unsigned char *p = NULL;
+ int width = 0;
+ unsigned long addr;
+ unsigned int pixelmask = 0;
+ unsigned int stipple;
+ int align = 0;
+ int skipleft;
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+/* ErrorF("TGASubsequentColorExpandScanline called\n"); */
+/* if(pTga->transparent_pattern_p) */
+/* ErrorF("transparent color expand\n"); */
+
+ p = (unsigned char *)pTga->buffers[0];
+ addr = fb_offset(pScrn, pTga->ce_x, pTga->ce_y);
+ width = pTga->ce_width;
+ skipleft = pTga->ce_skipleft;
+
+ while(width > 0) {
+ if(!pTga->transparent_pattern_p)
+ pixelmask = 0xFFFFFFFF;
+ if(addr & 0x3) {
+ align = addr & 0x3;
+ if(!pTga->transparent_pattern_p)
+ pixelmask <<= align;
+/* ErrorF("aligment is %d\n", align); */
+ addr -= align;
+ width += align;
+ {
+ CARD64 c = 0, d = 0;
+ CARD64 *e = NULL;
+ int i = 0, j = 0;
+
+ e = (CARD64 *)p;
+ j = (width / 64) + 1;
+ if(j > 128) { /* shouldn't happen */
+ ErrorF("TGASubsequentColorExpandScanline passed scanline %d bytes long, truncating\n", j * 8);
+ j = 128;
+ }
+ for(i = 0; i < j; i++) {
+ c = e[i];
+ if(i == 0)
+ e[i] = c << align;
+ else
+ e[i] = (d >> (64 - align)) | (c << align);
+ d = c;
+ }
+ }
+ }
+
+ if(!pTga->transparent_pattern_p) {
+ if(skipleft) {
+ pixelmask <<= skipleft;
+ skipleft = 0;
+ }
+ if(width < 32)
+ pixelmask &= (0xFFFFFFFF >> (32 - width));
+ }
+ else {
+ unsigned int *i = NULL;
+
+/* ErrorF("transparent scanline with x = %d, y = %d, w = %d, h = %d\n", pTga->ce_x, pTga->ce_y, pTga->ce_width, pTga->ce_height); */
+ if(skipleft) {
+ i = (unsigned int *)p;
+ *i &= (0xFFFFFFFF << skipleft);
+ skipleft = 0;
+ }
+ if(width < 32) {
+ i = (unsigned int *)p;
+ *i &= (0xFFFFFFFF >> (32 - width));
+ }
+ }
+
+ if(!pTga->transparent_pattern_p)
+ TGA_FAST_WRITE_REG(pixelmask, TGA_PIXELMASK_REG);
+ TGA_FAST_WRITE_REG(addr, TGA_ADDRESS_REG);
+ stipple = *((unsigned int *)p);
+ TGA_FAST_WRITE_REG(stipple, TGA_CONTINUE_REG);
+ addr += 32;
+ p += 4;
+ width -= 32;
+ if(align) {
+ align = 0;
+ }
+ }
+ pTga->ce_height--;
+ if(pTga->ce_height == 0) {
+ TGA_FAST_WRITE_REG(SIMPLE | X11 | BPP8PACKED,
+ TGA_MODE_REG);
+ TGA_FAST_WRITE_REG(MIX_SRC | BPP8PACKED, TGA_RASTEROP_REG);
+ }
+ else
+ pTga->ce_y += 1;
+
+ TGA_SAVE_OFFSET();
+ return;
+}
+#endif /* __alpha__ */
+
+/* Block Fill mode is faster, but only works for certain rops. So we will
+ have to implement Opaque Fill anyway, so we will do that first, then
+ do Block Fill for the special cases
+*/
+void
+TGASetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ register unsigned long iobase, offset;
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+ /* ErrorF("TGASetupForSolidFill called"); */
+
+ if(rop == MIX_SRC) { /* we can just do a block copy */
+ pTga->block_or_opaque_p = USE_BLOCK_FILL;
+ TGA_FAST_WRITE_REG((color | (color << 8) | (color << 16) |
+ (color << 24)), TGA_BLOCK_COLOR0_REG);
+ TGA_FAST_WRITE_REG((color | (color << 8) | (color << 16) |
+ (color << 24)), TGA_BLOCK_COLOR1_REG);
+ }
+ else {
+ pTga->block_or_opaque_p = USE_OPAQUE_FILL;
+ pTga->current_rop = rop | BPP8PACKED;
+ TGA_FAST_WRITE_REG((color | (color << 8) | (color << 16) |
+ (color << 24)), TGA_FOREGROUND_REG);
+/* ErrorF("opaque fill called\n"); */
+ }
+
+ TGA_FAST_WRITE_REG((planemask | (planemask << 8) |
+ (planemask << 16) |
+ (planemask << 24)), TGA_PLANEMASK_REG);
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_DATA_REG);
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+void
+TGASubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ unsigned int mode_reg = 0;
+ int i = 0;
+ unsigned int pixel_count = 0; /* the actual # of pixels to be written */
+ unsigned int write_data = 0; /* the actual data written */
+ int a1 = 0;
+#ifdef PROFILE
+ unsigned int stop, start;
+#endif
+ register unsigned long iobase, offset;
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ /* ErrorF("TGASubsequentFillRectSolid called\n"); */
+
+ if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) {
+ mode_reg = OPAQUEFILL | X11 | BPP8PACKED;
+ TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG);
+ /* we have to set this to GXCOPY every time before we exit */
+ }
+ else
+ mode_reg = BLOCKFILL | X11 | BPP8PACKED;
+
+ TGA_FAST_WRITE_REG(mode_reg, TGA_MODE_REG);
+
+ if(w > 2048) {
+ ErrorF("TGASubsequentSolidFillRect called with w = %d, truncating.\n");
+ w = 2048;
+ }
+ pixel_count = w - 1;
+
+ for(i = 0; i < h; i++) {
+ a1 = fb_offset(pScrn, x, y + i);
+ if(pTga->block_or_opaque_p == USE_OPAQUE_FILL)
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG);
+ write_data = pixel_count;
+ TGA_FAST_WRITE_REG(a1, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(write_data, TGA_CONTINUE_REG);
+ }
+
+ mode_reg = SIMPLE | X11 | BPP8PACKED;
+ TGA_FAST_WRITE_REG(mode_reg, TGA_MODE_REG);
+ if(pTga->block_or_opaque_p == USE_OPAQUE_FILL)
+ TGA_FAST_WRITE_REG(MIX_SRC | BPP8PACKED, TGA_RASTEROP_REG); /* GXCOPY */
+
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+/* we only need to calculate the direction of a move once per move,
+ so we do it in the setup function and leave it */
+
+void
+TGASetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned int planemask,
+ int transparency_color)
+ /* xdir 1 = left-to-right, -1 = right to left
+ ydir 1 = top-to-bottom, -1 = bottom to top
+ */
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ register unsigned long iobase, offset;
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ /* see section 6.2.9 */
+
+ /* ErrorF("TGASetupForScreenToScreenCopy called\n"); */
+
+ TGA_FAST_WRITE_REG((planemask | (planemask << 8) | (planemask << 16) |
+ (planemask << 24)), TGA_PLANEMASK_REG);
+
+ pTga->current_rop = rop;
+ if(pTga->current_rop == MIX_SRC)
+ TGA_FAST_WRITE_REG(pTga->current_rop | BPP8PACKED, TGA_RASTEROP_REG);
+
+ /* do we copy a rectangle from top to bottom or bottom to top? */
+ if(ydir == -1) {
+ pTga->blitdir = BLIT_FORWARDS;
+ }
+ else {
+ pTga->blitdir = BLIT_BACKWARDS;
+ }
+ TGA_SAVE_OFFSET();
+ return;
+}
+/*
+ * This is the implementation of the SubsequentForScreenToScreenCopy
+ * that sends commands to the coprocessor to perform a screen-to-screen
+ * copy of the specified areas, with the parameters from the SetUp call.
+ */
+void
+TGASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int w, int h)
+{
+ /* x1, y1 = source coords
+ x2, y2 = destination coords
+ w = width
+ h = height
+ */
+
+ int i = 0, mode_reg = 0;
+ void (*copy_func)();
+#ifdef PROFILE
+ unsigned int stop, start;
+#endif
+ register unsigned long iobase, offset;
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ /* ErrorF("TGASubsequentScreenToScreenCopy called\n"); */
+
+ mode_reg = COPY | X11 | BPP8PACKED; /* the others are 0 but what the
+ heck */
+ TGA_FAST_WRITE_REG(mode_reg, TGA_MODE_REG);
+ if(pTga->current_rop != MIX_SRC)
+ TGA_FAST_WRITE_REG(pTga->current_rop | BPP8PACKED, TGA_RASTEROP_REG);
+
+
+ if(x2 > x1 && (x1 + w) > x2)
+ copy_func = TGACopyLineBackwards;
+ else
+ copy_func = TGACopyLineForwards;
+
+ TGA_SAVE_OFFSET();
+ if(pTga->blitdir == BLIT_FORWARDS) {
+ for(i = h - 1; i >= 0; i--) { /* copy from bottom to top */
+ (*copy_func)(pScrn, x1, y1 + i, x2, y2 + i, w);
+ }
+ }
+ else {
+ for(i = 0; i < h; i++) {
+ (*copy_func)(pScrn, x1, y1 + i, x2, y2 + i, w);
+ }
+ }
+
+ TGA_GET_OFFSET();
+ mode_reg = SIMPLE | X11 | BPP8PACKED;
+ TGA_FAST_WRITE_REG(mode_reg,TGA_MODE_REG);
+ if(pTga->current_rop != MIX_SRC)
+ TGA_FAST_WRITE_REG(MIX_SRC | BPP8PACKED, TGA_RASTEROP_REG);
+ TGA_SAVE_OFFSET();
+
+ return;
+}
+
+
+void
+TGACopyLineForwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w)
+{
+ /* copy a line of width w from x1,y1 to x2,y2 using copy mode */
+ int read, span_dir, line_dir;
+ unsigned long source_address, destination_address;
+ unsigned int mask_source, mask_destination;
+ int source_align, destination_align;
+ int pixel_shift;
+ register unsigned long iobase, offset;
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ span_dir = BLIT_FORWARDS;
+ line_dir = BLIT_FORWARDS;
+
+ source_address = fb_offset(pScrn, x1, y1);
+ destination_address = fb_offset(pScrn, x2, y2);
+
+ read = 0;
+ while(read < w) {
+ mask_source = 0xFFFFFFFF;
+ if((w - read) >= 32)
+ mask_destination = 0xFFFFFFFF;
+ else
+ mask_destination = ((unsigned int)0xFFFFFFFF) >> (32 - (w - read));
+ source_align = source_address & 0x07;
+ destination_align = destination_address & 0x07;
+ source_address = source_address - source_align;
+ mask_source <<= source_align;
+ destination_address = destination_address - destination_align;
+ mask_destination <<= destination_align;
+
+ if(destination_align >= source_align)
+ pixel_shift = destination_align - source_align;
+ else {
+ pixel_shift = 8 - (source_align - destination_align);
+ /* we need to prime the residue register in this case */
+ destination_address = destination_address - 8;
+ mask_destination <<= 8;
+ }
+
+ TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG);
+ /* use GADR and GCTR */
+ TGA_FAST_WRITE_REG(source_address, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(mask_source, TGA_CONTINUE_REG);
+ TGA_FAST_WRITE_REG(destination_address, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(mask_destination, TGA_CONTINUE_REG);
+
+ source_address = source_address + (32 - pixel_shift);
+ destination_address += 32;
+
+ read += 32;
+ read -= destination_align; /* "read" is perhaps better
+ called "written"... */
+ if(destination_align < source_align) {
+ read -= 8;
+ }
+ }
+
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+
+void
+TGACopyLineBackwards(ScrnInfoPtr pScrn, int x1, int y1, int x2,
+ int y2, int w)
+ /* x1, y1 = source
+ x2, y2 = destination
+ w = width
+ */
+{
+ unsigned long a1, a2;
+ unsigned long source_address, destination_address;
+ unsigned int mask_source, mask_destination;
+ int source_align, destination_align;
+ int pixel_shift;
+ int read;
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ register unsigned long iobase, offset;
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ a1 = fb_offset(pScrn, x1, y1);
+ a2 = fb_offset(pScrn, x2, y2);
+
+ source_address = fb_offset(pScrn, (x1 + w) - 32, y1);
+ destination_address = fb_offset(pScrn, (x2 + w) - 32, y2);
+
+ read = 0;
+ while(read < w) {
+ mask_source = 0xFFFFFFFF;
+ if((w - read) >= 32)
+ mask_destination = 0xFFFFFFFF;
+ else
+ mask_destination = ((unsigned int)0xFFFFFFFF) << (32 - (w - read));
+
+ source_align = source_address & 0x07;
+ destination_align = destination_address & 0x07;
+
+ if(read == 0 && destination_align &&
+ (source_align > destination_align)) {
+ /* we want to take out all the destination_align pixels in one
+ little copy first, then move on to the main stuff */
+ unsigned long tmp_src, tmp_dest;
+ unsigned int tmp_src_mask, tmp_dest_mask;
+
+ tmp_src = (a1 + w) - source_align;
+ tmp_dest = ((a2 + w) - destination_align) - 8;
+ tmp_src_mask = 0xFFFFFFFF;
+ tmp_dest_mask = ((unsigned int)0x000000FF) >> (8 - destination_align);
+ tmp_dest_mask <<= 8;
+ pixel_shift = (8 - source_align) + destination_align;
+
+ TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG);
+ TGA_FAST_WRITE_REG(tmp_src, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(tmp_src_mask, TGA_CONTINUE_REG);
+ TGA_FAST_WRITE_REG(tmp_dest, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(tmp_dest_mask, TGA_CONTINUE_REG);
+
+/* ErrorF("premature copy: sa = %d, da = %d, ps =%d\n", source_align, */
+/* destination_align, pixel_shift); */
+
+ source_address += (8 - source_align);
+ mask_source >>= (8 - source_align);
+ mask_source >>= destination_align;
+ mask_destination >>= destination_align;
+ }
+ else if(read == 0 && (source_align != destination_align)) {
+ source_address += (8 - source_align);
+ /* mask_source >>= (8 - source_align); */
+ /* if we comment this out, it breaks...TGA tries to
+ optimize away a read of our last pixels... */
+ }
+ else if(source_align) {
+ source_address += (8 - source_align);
+ mask_source >>= (8 - source_align);
+ }
+ if(destination_align) {
+ destination_address += (8 - destination_align);
+ mask_destination >>= (8 - destination_align);
+ }
+
+ if(destination_align >= source_align)
+ pixel_shift = destination_align - source_align;
+ else {
+ pixel_shift = (8 - source_align) + destination_align;
+ if(destination_align) {
+ source_address += 8;
+ mask_source >>= 8;
+ }
+ }
+
+ TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG);
+ /* use GADR and GCTR */
+ TGA_FAST_WRITE_REG(source_address, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(mask_source, TGA_CONTINUE_REG);
+ TGA_FAST_WRITE_REG(destination_address, TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(mask_destination, TGA_CONTINUE_REG);
+
+/* if(read == 0) */
+/* ErrorF("sa = %d, da = %d, ps = %d\n", source_align, destination_align, */
+/* pixel_shift); */
+
+ if(destination_align > source_align) {
+ source_address -= 24;
+ destination_address -= (32 - pixel_shift);
+ if(read == 0)
+ read += 24 + source_align;
+ else
+ read += 24;
+ }
+ else if(destination_align == source_align) {
+ source_address -= 32;
+ destination_address -= 32;
+ if(read == 0 && destination_align)
+ read += (32 - (8 - destination_align));
+ else
+ read += 32;
+ }
+ else if(source_align > destination_align) {
+ source_address -= 24;
+ destination_address -= (32 - pixel_shift);
+ /* only happens when read == 0 */
+ if(destination_align)
+ read += 16 + source_align;
+ else
+ read += 32 - pixel_shift;
+ }
+ }
+
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+void
+TGASetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
+ int fg, int bg, int rop, unsigned int planemask)
+{
+#ifdef PROFILE
+ unsigned int start, stop;
+#endif
+ register unsigned long iobase, offset;
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+/* ErrorF("TGASetupForMono8x8PatternFill called with patx = %d, paty = %d, fg = %d, bg = %d, rop = %d, planemask = %d\n", */
+/* patx, paty, fg, bg, rop, planemask); */
+ if(bg == -1) /* we are transparent */
+ pTga->transparent_pattern_p = 1;
+ else
+ pTga->transparent_pattern_p = 0;
+
+ if(rop == MIX_SRC)
+ pTga->block_or_opaque_p = USE_BLOCK_FILL;
+ else
+ pTga->block_or_opaque_p = USE_OPAQUE_FILL;
+
+ if(pTga->transparent_pattern_p && pTga->block_or_opaque_p == USE_BLOCK_FILL) {
+ /* we can use block fill mode to draw a transparent stipple */
+ TGA_FAST_WRITE_REG((fg | (fg << 8) | (fg << 16) | (fg << 24)),
+ TGA_BLOCK_COLOR0_REG);
+ TGA_FAST_WRITE_REG((fg | (fg << 8) | (fg << 16) | (fg << 24)),
+ TGA_BLOCK_COLOR1_REG);
+ }
+ else if(pTga->transparent_pattern_p) {
+ TGA_FAST_WRITE_REG((fg | (fg << 8) | (fg << 16) | (fg << 24)),
+ TGA_FOREGROUND_REG);
+ }
+ else {
+ TGA_FAST_WRITE_REG((bg | (bg << 8) | (bg << 16) | (bg << 24)),
+ TGA_BACKGROUND_REG);
+ TGA_FAST_WRITE_REG((fg | (fg << 8) | (fg << 16) | (fg << 24)),
+ TGA_FOREGROUND_REG);
+ TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG);
+ }
+ pTga->current_rop = rop;
+ TGA_FAST_WRITE_REG((planemask | (planemask << 8) | (planemask << 16) |
+ (planemask << 24)), TGA_PLANEMASK_REG);
+ TGA_SAVE_OFFSET();
+ return;
+}
+
+void
+TGASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty,
+ int x, int y, int w, int h)
+/* patx and paty = first & second dwords of pattern to be rendered, packed */
+{
+ TGAPtr pTga;
+ int i, j;
+ unsigned int stipple_mask[8], align, tmp;
+#ifdef PROFILE
+ register unsigned int stop, start;
+#endif
+ register unsigned long iobase, offset;
+
+
+/* ErrorF("TGASubsequentMono8x8PatternFillRect called with x = %d, y = %d, w = %d, h = %d\n", x, y, w, h); */
+
+ pTga = TGAPTR(pScrn);
+ TGA_GET_IOBASE();
+ TGA_GET_OFFSET();
+
+ if(w > 2048)
+ ErrorF("TGASubsequentMono8x8PatternFillRect called with w > 2048, truncating\n");
+ if(pTga->block_or_opaque_p == USE_OPAQUE_FILL)
+ TGA_FAST_WRITE_REG(pTga->current_rop | BPP8PACKED, TGA_RASTEROP_REG);
+
+ align = fb_offset(pScrn, x, y) % 4;
+
+ for(i = 0; i < 4; i++) {
+ tmp = (patx >> (i * 8)) & 0xFF;
+ stipple_mask[i] = (tmp | (tmp << 8) | (tmp << 16) | (tmp << 24));
+ }
+ for(i = 4; i < 8; i++) {
+ tmp = (paty >> ((i - 4) * 8)) & 0xFF;
+ stipple_mask[i] = (tmp | (tmp << 8) | (tmp << 16) | (tmp << 24));
+ }
+ if(align) { /* stipples must be aligned to four bytes */
+ for(i = 0; i < 8; i++) {
+ stipple_mask[i] = (stipple_mask[i] << align) |
+ ((stipple_mask[i] & 0xFF000000) >> (32 - align));
+ }
+ }
+
+ if((pTga->block_or_opaque_p == USE_BLOCK_FILL) && pTga->transparent_pattern_p) {
+ /* use block fill */
+ TGA_FAST_WRITE_REG(BLOCKFILL | X11 | BPP8PACKED, TGA_MODE_REG);
+
+ for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) {
+ TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG);
+ TGA_FAST_WRITE_REG(fb_offset(pScrn, x, y + i), TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG);
+ }
+ }
+ else if(pTga->transparent_pattern_p) {
+ /* if we can't use block fill, we'll use transparent fill */
+ TGA_FAST_WRITE_REG(TRANSPARENTFILL | X11 | BPP8PACKED, TGA_MODE_REG);
+ for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) {
+ TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG);
+ TGA_FAST_WRITE_REG(fb_offset(pScrn, x, y + i), TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG);
+ }
+ }
+ else { /* use opaque fill mode */
+/* ErrorF("Using opaque fill mode\n"); */
+ TGA_FAST_WRITE_REG(OPAQUEFILL | X11 | BPP8PACKED, TGA_MODE_REG);
+ for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) {
+ TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG);
+ TGA_FAST_WRITE_REG(fb_offset(pScrn, x, y + i), TGA_ADDRESS_REG);
+ TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG);
+ }
+ }
+
+ TGA_FAST_WRITE_REG(SIMPLE | X11 | BPP8PACKED, TGA_MODE_REG);
+ if(pTga->current_rop != MIX_SRC)
+ TGA_FAST_WRITE_REG(MIX_SRC | BPP8PACKED, TGA_RASTEROP_REG);
+
+ TGA_SAVE_OFFSET();
+
+ return;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_cursor.c
new file mode 100644
index 000000000..370a793da
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_cursor.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright 1999 by Matthew Grossman, Seattle, USA.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Matthew
+ * Grossman not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Matthew Grossman makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * MATTHEW GROSSMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL MATTHEW GROSSMAN BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Author: Matthew Grossman, mattg@oz.net
+ *
+ * DEC TGA hardware cursor using BT485 ramdac
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_cursor.c,v 1.1 1999/04/17 07:06:58 dawes Exp $ */
+
+
+/* tga_cursor.c */
+
+#include "xf86.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "BT.h"
+
+#include "tga.h"
+#include "tga_regs.h"
+
+/* defines */
+/* BT485 also supports 32 bit cursor, but why use it? */
+#define CURSOR_SIZE 64
+
+/* protos */
+
+static void TGALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
+static void TGAShowCursor(ScrnInfoPtr pScrn);
+static void TGAHideCursor(ScrnInfoPtr pScrn);
+static void TGASetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
+static void TGASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
+
+static void
+TGALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+{
+ int i;
+
+ /* set 64 bit cursor */
+ tgaBTOutIndReg(pScrn, BT_COMMAND_REG_0, 0x7F, 0x80);
+ tgaBTOutIndReg(pScrn, BT_WRITE_ADDR, 0x00, 0x01);
+ tgaBTOutIndReg(pScrn, BT_STATUS_REG, 0xF8, 0x04);
+
+ /* first write address reg @ 0x0, then write 0xb with the data (for 32 bit
+ cursor) */
+
+ tgaBTOutIndReg(pScrn, BT_WRITE_ADDR, 0xFC, 0x00);
+
+ for(i = 0; i < ((CURSOR_SIZE * CURSOR_SIZE) / 8); i++)
+ tgaBTOutIndReg(pScrn, BT_CURS_RAM_DATA, 0x00, *src++);
+
+ for(i = 0; i < ((CURSOR_SIZE * CURSOR_SIZE) / 8); i++)
+ tgaBTOutIndReg(pScrn, BT_CURS_RAM_DATA, 0x00, *src++);
+
+/* tgaBTOutIndReg(pScrn, BT_WRITE_ADDR, 0xFC, 0x00); */
+
+ return;
+}
+
+
+static void
+TGAShowCursor(ScrnInfoPtr pScrn)
+{
+ /* enable BT485 X11 cursor */
+ tgaBTOutIndReg(pScrn, BT_COMMAND_REG_2, 0xFC, 0x03);
+
+ return;
+}
+
+
+static void
+TGAHideCursor(ScrnInfoPtr pScrn)
+{
+ tgaBTOutIndReg(pScrn, BT_COMMAND_REG_2, 0xFC, 0x00);
+
+ return;
+}
+
+static void
+TGASetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ unsigned int tmp_x, tmp_y;
+
+ /* translate x && y to BT485 cursor addresses */
+
+ tmp_x = x + CURSOR_SIZE;
+ tmp_x &= 0x0FFF;
+
+ tmp_y = y + CURSOR_SIZE;
+ tmp_y &= 0x0FFF;
+
+ /* write out the addresses */
+ tgaBTOutIndReg(pScrn, BT_CURS_X_LOW, 0x00, (tmp_x & 0xFF));
+ tgaBTOutIndReg(pScrn, BT_CURS_X_HIGH, 0xF0, (tmp_x >> 8));
+
+ tgaBTOutIndReg(pScrn, BT_CURS_Y_LOW, 0x00, (tmp_y & 0xFF));
+ tgaBTOutIndReg(pScrn, BT_CURS_Y_HIGH, 0xF0, (tmp_y >> 8));
+
+ return;
+}
+
+
+static void
+TGASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+ /* set pScrn->cursor_fg and pScrn->cursor_bg */
+{
+ /* first, load address register at 0x4 with 0x1, then write 3 color
+ octets RGB to 0x5 (background), then write three octets to 0x5
+ (foreground), then write to address register 0xFC */
+
+ tgaBTOutIndReg(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x01);
+
+ /* we don't seem to support the 6 bit DAC option as of 4.0, and why
+ would we? */
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, (bg & 0x00FF0000) >> 16);
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, (bg & 0x0000FF00) >> 8);
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, (bg & 0x000000FF));
+
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, (fg & 0x00FF0000) >> 16);
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, (fg & 0x0000FF00) >> 8);
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, (fg & 0x000000FF));
+
+/* tgaBTOutIndReg(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x00); */
+
+ return;
+}
+
+
+Bool
+TGAHWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TGAPtr pTga;
+ xf86CursorInfoPtr infoPtr;
+
+ pTga = TGAPTR(pScrn);
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pTga->CursorInfoRec = infoPtr;
+
+ infoPtr->MaxWidth = CURSOR_SIZE;
+ infoPtr->MaxHeight = CURSOR_SIZE;
+ infoPtr->Flags = HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
+
+ infoPtr->SetCursorColors = TGASetCursorColors;
+ infoPtr->SetCursorPosition = TGASetCursorPosition;
+ infoPtr->LoadCursorImage = TGALoadCursorImage;
+ infoPtr->HideCursor = TGAHideCursor;
+ infoPtr->ShowCursor = TGAShowCursor;
+ infoPtr->UseHWCursor = NULL;
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_dac.c b/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_dac.c
new file mode 100644
index 000000000..dc4566794
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_dac.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane <alanh@fairlite.demon.co.uk>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_dac.c,v 1.8 1999/08/14 10:49:55 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "BT.h"
+#include "tga_regs.h"
+#include "tga.h"
+
+static void ICS1562ClockSelect(ScrnInfoPtr pScrn, int freq);
+extern void ICS1562_CalcClockBits(long f, unsigned char *bits);
+
+static void
+ICS1562ClockSelect(ScrnInfoPtr pScrn, int freq)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+ unsigned char pll_bits[7];
+ unsigned long temp;
+ int i, j;
+
+ /*
+ * For the DEC 21030 TGA, There lies an ICS1562 Clock Generator.
+ * This requires the 55 clock bits be written in a serial manner to
+ * bit 0 of the CLOCK register and on the 56th bit set the hold flag.
+ */
+ ICS1562_CalcClockBits(freq, pll_bits);
+ for (i = 0;i <= 6; i++) {
+ for (j = 0; j <= 7; j++) {
+ temp = (pll_bits[i] >> (7-j)) & 1;
+ if (i == 6 && j == 7)
+ temp |= 2;
+ TGA_WRITE_REG(temp, TGA_CLOCK_REG);
+ }
+ }
+}
+
+
+Bool
+DEC21030Init(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+ TGARegPtr pReg = &pTga->ModeReg;
+
+ if (pTga->RamDac != NULL) {
+ RamDacHWRecPtr pBT = RAMDACHWPTR(pScrn);
+ RamDacRegRecPtr ramdacReg = &pBT->ModeReg;
+
+ ramdacReg->DacRegs[BT_COMMAND_REG_0] = 0xA0 | (pScrn->rgbBits ? 2 : 0);
+ ramdacReg->DacRegs[BT_COMMAND_REG_2] = 0x20;
+ ramdacReg->DacRegs[BT_STATUS_REG] = 0x14;
+ (*pTga->RamDac->SetBpp)(pScrn, ramdacReg);
+ } else {
+ unsigned char *Bt463 = pTga->Bt463modeReg;
+ int i, j;
+
+ /* Command registers */
+ Bt463[0] = 0x40; Bt463[1] = 0x08; Bt463[2] = 0x00;
+
+ /* Read mask */
+ Bt463[3] = 0xff; Bt463[4] = 0xff; Bt463[5] = 0xff; Bt463[6] = 0x0f;
+
+ /* Blink mask */
+ Bt463[7] = 0x00; Bt463[8] = 0x00; Bt463[9] = 0x00; Bt463[10] = 0x00;
+
+ /* Window attributes */
+ for (i = 0, j=11; i < 16; i++) {
+ Bt463[j++] = 0x00; Bt463[j++] = 0x01; Bt463[j++] = 0x80;
+ }
+ }
+
+ pReg->tgaRegs[0x00] = mode->CrtcHDisplay;
+ pReg->tgaRegs[0x01] = (mode->CrtcHSyncStart - mode->CrtcHDisplay) / 4;
+ pReg->tgaRegs[0x02] = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 4;
+ pReg->tgaRegs[0x03] = (mode->CrtcHTotal - mode->CrtcHSyncEnd) / 4;
+ pReg->tgaRegs[0x04] = mode->CrtcVDisplay;
+ pReg->tgaRegs[0x05] = mode->CrtcVSyncStart - mode->CrtcVDisplay;
+ pReg->tgaRegs[0x06] = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+ pReg->tgaRegs[0x07] = mode->CrtcVTotal - mode->CrtcVSyncEnd;
+
+ /*
+ * We do polarity the Step B way of the 21030
+ * Tell me how I can detect a Step A, and I'll support that too.
+ * But I think that the Step B's are most common
+ */
+ if (mode->Flags & V_PHSYNC)
+ pReg->tgaRegs[0x08] = 1; /* Horizontal Polarity */
+ else
+ pReg->tgaRegs[0x08] = 0;
+
+ if (mode->Flags & V_PVSYNC)
+ pReg->tgaRegs[0x09] = 1; /* Vertical Polarity */
+ else
+ pReg->tgaRegs[0x09] = 0;
+
+ pReg->tgaRegs[0x0A] = mode->Clock;
+
+ pReg->tgaRegs[0x10] = ((pReg->tgaRegs[0x00] / 4) & 0x1FF) |
+ (((pReg->tgaRegs[0x00] / 4) & 0x600) << 19) |
+ (pReg->tgaRegs[0x01] << 9) |
+ (pReg->tgaRegs[0x02] << 14) |
+ (pReg->tgaRegs[0x03] << 21) |
+ (pReg->tgaRegs[0x08] << 30);
+ pReg->tgaRegs[0x11] = pReg->tgaRegs[0x04] |
+ (pReg->tgaRegs[0x05] << 11) |
+ (pReg->tgaRegs[0x06] << 16) |
+ (pReg->tgaRegs[0x07] << 22) |
+ (pReg->tgaRegs[0x09] << 30);
+
+ pReg->tgaRegs[0x12] = 0x05;
+
+ pReg->tgaRegs[0x13] = 0x0000;
+ return TRUE;
+}
+
+void
+DEC21030Save(ScrnInfoPtr pScrn, TGARegPtr tgaReg)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+
+ tgaReg->tgaRegs[0x10] = TGA_READ_REG(TGA_HORIZ_REG);
+ tgaReg->tgaRegs[0x11] = TGA_READ_REG(TGA_VERT_REG);
+ tgaReg->tgaRegs[0x12] = TGA_READ_REG(TGA_VALID_REG);
+
+ return;
+}
+
+void
+DEC21030Restore(ScrnInfoPtr pScrn, TGARegPtr tgaReg)
+{
+ TGAPtr pTga = TGAPTR(pScrn);
+
+ TGA_WRITE_REG(0x00, TGA_VALID_REG); /* Disable Video */
+
+ ICS1562ClockSelect(pScrn, tgaReg->tgaRegs[0x0A]);
+
+ TGA_WRITE_REG(tgaReg->tgaRegs[0x10], TGA_HORIZ_REG);
+ TGA_WRITE_REG(tgaReg->tgaRegs[0x11], TGA_VERT_REG);
+
+ TGA_WRITE_REG(tgaReg->tgaRegs[0x12], TGA_VALID_REG); /* Re-enable Video */
+
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c
new file mode 100644
index 000000000..581244f97
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c
@@ -0,0 +1,1528 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ * Matthew Grossman, <mattg@oz.net> - acceleration and misc fixes
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_driver.c,v 1.28 1999/08/14 10:49:55 dawes Exp $ */
+
+/* #include "compiler.h" */
+/* everybody includes these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* PCI headers */
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+/* module versioning */
+#include "xf86Version.h"
+
+/* RAC stuff */
+#include "xf86Resources.h"
+
+/* #include "vgaHW.h" */
+
+/* software cursor */
+#include "mipointer.h"
+/* backing store */
+#include "mibstore.h"
+
+/* #include "mibank.h" */
+/* colormap manipulation */
+#include "micmap.h"
+
+/* TGA only does 8 and 32 bpp */
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+/* #include "cfb16.h" */
+/* #include "cfb24.h" */
+#include "cfb32.h"
+
+/* more RAC stuff */
+#include "xf86RAC.h"
+
+/* Gamma Correction? */
+#include "xf86cmap.h"
+
+#include "tga_regs.h"
+#include "BT.h"
+#include "tga.h"
+
+#ifdef XFreeXDGA
+#define _XF86DGA_SERVER_
+#include "extensions/xf86dgastr.h"
+#endif
+
+#ifdef DPMSExtension
+#include "globals.h"
+#define DPMS_SERVER
+#include "extensions/dpms.h"
+#endif
+
+static void TGAIdentify(int flags);
+static Bool TGAProbe(DriverPtr drv, int flags);
+static Bool TGAPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool TGAScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool TGAEnterVT(int scrnIndex, int flags);
+static void TGALeaveVT(int scrnIndex, int flags);
+static Bool TGACloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool TGASaveScreen(ScreenPtr pScreen, Bool unblank);
+
+/* Required if the driver supports mode switching */
+static Bool TGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+/* Required if the driver supports moving the viewport */
+static void TGAAdjustFrame(int scrnIndex, int x, int y, int flags);
+
+/* Optional functions */
+static void TGAFreeScreen(int scrnIndex, int flags);
+static int TGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
+
+/* Internally used functions */
+static Bool TGAMapMem(ScrnInfoPtr pScrn);
+static Bool TGAUnmapMem(ScrnInfoPtr pScrn);
+static void TGASave(ScrnInfoPtr pScrn);
+static void TGARestore(ScrnInfoPtr pScrn);
+static Bool TGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+
+static void TGARestoreHWCursor(ScrnInfoPtr pScrn);
+
+#ifdef DPMSExtension
+static void TGADisplayPowerManagementSet(ScrnInfoPtr pScrn,
+ int PowerManagementMode,
+ int flags);
+#endif
+
+#define VERSION 4000
+#define TGA_NAME "TGA"
+#define TGA_DRIVER_NAME "tga"
+#define TGA_MAJOR_VERSION 1
+#define TGA_MINOR_VERSION 0
+#define TGA_PATCHLEVEL 0
+
+/*
+ * This contains the functions needed by the server after loading the driver
+ * module. It must be supplied, and gets passed back by the SetupProc
+ * function in the dynamic case. In the static case, a reference to this
+ * is compiled in, and this requires that the name of this DriverRec be
+ * an upper-case version of the driver name.
+ */
+
+DriverRec TGA = {
+ VERSION,
+ "accelerated driver for Digital chipsets",
+ TGAIdentify,
+ TGAProbe,
+ NULL,
+ 0
+};
+
+static SymTabRec TGAChipsets[] = {
+ { PCI_CHIP_DEC21030, "tga" },
+ { -1, NULL }
+};
+
+static PciChipsets TGAPciChipsets[] = {
+ { PCI_CHIP_DEC21030, PCI_CHIP_DEC21030, NULL },
+ { -1, -1, RES_UNDEFINED }
+};
+
+typedef enum {
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+ OPTION_PCI_RETRY,
+ OPTION_RGB_BITS,
+ OPTION_NOACCEL
+} TGAOpts;
+
+static OptionInfoRec TGAOptions[] = {
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_RGB_BITS, "RGBbits", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+static RamDacSupportedInfoRec BTramdacs[] = {
+ { BT485_RAMDAC },
+ { -1 }
+};
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(tgaSetup);
+
+static XF86ModuleVersionInfo tgaVersRec =
+{
+ "tga",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ TGA_MAJOR_VERSION, TGA_MINOR_VERSION, TGA_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+XF86ModuleData tgaModuleData = { &tgaVersRec, tgaSetup, NULL };
+
+pointer
+tgaSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&TGA, module, 0);
+
+ /*
+ * Modules that this driver always requires can be loaded here
+ * by calling LoadSubModule().
+ */
+
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer)1;
+ } else {
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+#endif /* XFree86LOADER */
+
+static unsigned int fb_offset_presets[4] = {
+ TGA_8PLANE_FB_OFFSET,
+ TGA_24PLANE_FB_OFFSET,
+ 0xffffffff,
+ TGA_24PLUSZ_FB_OFFSET
+};
+
+static char *tga_cardnames[4] = {
+ "TGA 8 Plane",
+ "TGA 24 Plane",
+ NULL,
+ "TGA 24 Plane 3D"
+};
+
+static Bool
+TGAGetRec(ScrnInfoPtr pScrn)
+{
+ /*
+ * Allocate an TGARec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(TGARec), 1);
+ /* Initialise it */
+
+
+ return TRUE;
+}
+
+static void
+TGAFreeRec(ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga;
+
+ if (pScrn->driverPrivate == NULL)
+ return;
+
+ pTga = TGAPTR(pScrn);
+#ifdef __alpha__
+ if(pTga->buffers)
+ free(pTga->buffers[0]);
+#endif
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+
+/* Mandatory */
+static void
+TGAIdentify(int flags)
+{
+ xf86PrintChipsets(TGA_NAME, "driver for Digital chipsets", TGAChipsets);
+}
+
+
+/* Mandatory */
+static Bool
+TGAProbe(DriverPtr drv, int flags)
+{
+ int i;
+ pciVideoPtr pPci;
+ GDevPtr *devSections;
+/* GDevPtr *usedDevs; */
+ int *usedChips;
+ int numDevSections;
+ int numUsed;
+ Bool foundScreen = FALSE;
+ EntityInfoPtr pEnt;
+
+ /*
+ * The aim here is to find all cards that this driver can handle,
+ * and for the ones not already claimed by another driver, claim the
+ * slot, and allocate a ScrnInfoRec.
+ *
+ * This should be a minimal probe, and it should under no circumstances
+ * change the state of the hardware. Because a device is found, don't
+ * assume that it will be used. Don't do any initialisations other than
+ * the required ScrnInfoRec initialisations. Don't allocate any new
+ * data structures.
+ */
+
+ /*
+ * Next we check, if there has been a chipset override in the config file.
+ * For this we must find out if there is an active device section which
+ * is relevant, i.e., which has no driver specified or has THIS driver
+ * specified.
+ */
+
+ if ((numDevSections = xf86MatchDevice(TGA_DRIVER_NAME,
+ &devSections)) <= 0) {
+ /*
+ * There's no matching device section in the config file, so quit
+ * now.
+ */
+ return FALSE;
+ }
+
+ /*
+ * We need to probe the hardware first. We then need to see how this
+ * fits in with what is given in the config file, and allow the config
+ * file info to override any contradictions.
+ */
+
+ /*
+ * All of the cards this driver supports are PCI, so the "probing" just
+ * amounts to checking the PCI data that the server has already collected.
+ */
+ if (xf86GetPciVideoInfo() == NULL) {
+ /*
+ * We won't let anything in the config file override finding no
+ * PCI video cards at all. This seems reasonable now, but we'll see.
+ */
+ return FALSE;
+ }
+
+ numUsed = xf86MatchPciInstances(TGA_NAME, PCI_VENDOR_DIGITAL,
+ TGAChipsets, TGAPciChipsets, devSections, numDevSections,
+ drv, &usedChips);
+
+ xfree(devSections);
+ devSections = NULL;
+ if (numUsed <= 0)
+ return FALSE;
+
+ for (i = 0; i < numUsed; i++) {
+ pEnt = xf86GetEntityInfo(usedChips[i]);
+
+ /*
+ * Check that nothing else has claimed the slots.
+ */
+ if(pEnt->active) {
+ ScrnInfoPtr pScrn;
+
+ /* Allocate a ScrnInfoRec and claim the slot */
+ pScrn = xf86AllocateScreen(drv, 0);
+
+ pPci = xf86GetPciInfoForEntity(pEnt->index);
+
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = TGA_DRIVER_NAME;
+ pScrn->name = TGA_NAME;
+ pScrn->Probe = TGAProbe;
+ pScrn->PreInit = TGAPreInit;
+ pScrn->ScreenInit = TGAScreenInit;
+ pScrn->SwitchMode = TGASwitchMode;
+ pScrn->AdjustFrame = TGAAdjustFrame;
+ pScrn->EnterVT = TGAEnterVT;
+ pScrn->LeaveVT = TGALeaveVT;
+ pScrn->FreeScreen = TGAFreeScreen;
+ pScrn->ValidMode = TGAValidMode;
+/* pScrn->device = usedDevs[i]; */
+ xf86ConfigActivePciEntity(pScrn, pEnt->index, TGAPciChipsets, NULL,
+ NULL, NULL, NULL, NULL);
+ foundScreen = TRUE;
+ }
+ xfree(pEnt);
+ }
+/* xfree(usedDevs); */
+/* xfree(usedPci); */
+ return foundScreen;
+}
+
+#if 0
+/*
+ * GetAccelPitchValues -
+ *
+ * This function returns a list of display width (pitch) values that can
+ * be used in accelerated mode.
+ */
+static int *
+GetAccelPitchValues(ScrnInfoPtr pScrn)
+{
+ int *linePitches = NULL;
+ int i, n = 0;
+ int *linep = NULL;
+ /* TGAPtr pTga = TGAPTR(pScrn); */
+
+ for (i = 0; linep[i] != 0; i++) {
+ if (linep[i] != -1) {
+ n++;
+ linePitches = xnfrealloc(linePitches, n * sizeof(int));
+ linePitches[n - 1] = i << 5;
+ }
+ }
+
+ /* Mark the end of the list */
+ if (n > 0) {
+ linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
+ linePitches[n] = 0;
+ }
+ return linePitches;
+}
+#endif /* 0 */
+
+/* Mandatory */
+static Bool
+TGAPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ pciVideoPtr pciPtr;
+ TGAPtr pTga;
+ MessageType from;
+ int i;
+ ClockRangePtr clockRanges;
+ char *mod = NULL;
+ pointer Base;
+
+ /*
+ * Note: This function is only called once at server startup, and
+ * not at the start of each server generation. This means that
+ * only things that are persistent across server generations can
+ * be initialised here. xf86Screens[] is (pScrn is a pointer to one
+ * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex()
+ * are too, and should be used for data that must persist across
+ * server generations.
+ *
+ * Per-generation data should be allocated with
+ * AllocateScreenPrivateIndex() from the ScreenInit() function.
+ */
+
+ /* The ramdac module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "ramdac"))
+ return FALSE;
+
+ /* Allocate the TGARec driverPrivate */
+ if (!TGAGetRec(pScrn)) {
+ return FALSE;
+ }
+ pTga = TGAPTR(pScrn);
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*********************
+ Handle pci and chipset stuff
+ *********************/
+
+
+ /* This driver doesn't expect more than one entity per screen */
+ if (pScrn->numEntities > 1)
+ return FALSE;
+ /* This is the general case */
+ for (i = 0; i < pScrn->numEntities; i++) {
+ pTga->pEnt = xf86GetEntityInfo(pScrn->entityList[i]);
+ if (pTga->pEnt->resources) return FALSE;
+ pTga->Chipset = pTga->pEnt->chipset;
+ pScrn->chipset = (char *)xf86TokenToString(TGAChipsets,
+ pTga->pEnt->chipset);
+
+ /* TGA is purely PCI */
+ if (pTga->pEnt->location.type == BUS_PCI) {
+ pciPtr = xf86GetPciInfoForEntity(pTga->pEnt->index);
+ pTga->PciInfo = pciPtr;
+ pTga->PciTag = pciTag(pTga->PciInfo->bus,
+ pTga->PciInfo->device,
+ pTga->PciInfo->func);
+ }
+ else
+ return FALSE;
+ }
+
+ /*
+ * This shouldn't happen because such problems should be caught in
+ * TGAProbe(), but check it just in case.
+ */
+ if (pScrn->chipset == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ChipID 0x%04X is not recognised\n", pTga->Chipset);
+ return FALSE;
+ }
+ if (pTga->Chipset < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Chipset \"%s\" is not recognised\n", pScrn->chipset);
+ return FALSE;
+ }
+
+ from = X_PROBED;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
+
+ pTga->PciTag = pciTag(pTga->PciInfo->bus, pTga->PciInfo->device,
+ pTga->PciInfo->func);
+
+
+
+ /*********************
+ deal with depth and framebuffer size
+ *********************/
+
+ if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) {
+ return FALSE;
+ } else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 8:
+ case 24:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /* we can do option processing now */
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+ /* Process the options */
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, TGAOptions);
+ if (xf86ReturnOptValBool(TGAOptions, OPTION_PCI_RETRY, FALSE)) {
+ pTga->UsePCIRetry = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
+ }
+ /* end option processing */
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /*
+ * The new cmap code requires this to be initialised.
+ */
+
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+
+ /* Set the bits per RGB for 8bpp mode */
+ if (pScrn->depth == 8) {
+ /* XXX This is here just to test options. */
+ /* Default to 8 */
+ pScrn->rgbBits = 8;
+ if (xf86GetOptValInteger(TGAOptions, OPTION_RGB_BITS,
+ &pScrn->rgbBits)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
+ pScrn->rgbBits);
+ }
+ }
+ from = X_DEFAULT;
+
+ /* determine whether we use hardware or software cursor */
+
+ pTga->HWCursor = TRUE;
+ if (xf86GetOptValBool(TGAOptions, OPTION_HW_CURSOR, &pTga->HWCursor))
+ from = X_CONFIG;
+ if (xf86ReturnOptValBool(TGAOptions, OPTION_SW_CURSOR, FALSE)) {
+ from = X_CONFIG;
+ pTga->HWCursor = FALSE;
+ }
+
+ if(pScrn->depth != 8) {
+ pTga->HWCursor = FALSE;
+ from = X_WARNING;
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Hardware cursor currently only works with BT485 ramdac\n");
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pTga->HWCursor ? "HW" : "SW");
+
+ if (xf86ReturnOptValBool(TGAOptions, OPTION_NOACCEL, FALSE)) {
+ pTga->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+
+ if (pTga->pEnt->device->MemBase != 0) {
+ pTga->FbAddress = pTga->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ pTga->FbAddress = pTga->PciInfo->memBase[0] & 0xFF800000;
+ }
+
+ /* Adjust MMIO region */
+ pTga->IOAddress = pTga->FbAddress + TGA_REGS_OFFSET;
+
+
+ /*********************
+ determine what sort of TGA card we have -- the only differences are
+ framebuffer size and ramdac type, all TGA cards use 21030 chips
+ *********************/
+
+ /* check what the user has specified in XF86Config */
+ if(pTga->pEnt->device->videoRam) {
+ switch(pTga->pEnt->device->videoRam) {
+ case 2048:
+ pTga->CardType = TYPE_TGA_8PLANE;
+ break;
+ case 8192:
+ pTga->CardType = TYPE_TGA_24PLANE;
+ break;
+ case 16384:
+ pTga->CardType = TYPE_TGA_24PLUSZ;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "%d KB video RAM specified, driver only supports 2048, 8192, or 16384 KB cards\n",
+ pTga->pEnt->device->videoRam);
+ return FALSE;
+ }
+ }
+ else { /* try to divine the amount of RAM */
+ Base = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pTga->PciTag, pTga->FbAddress, 4);
+ pTga->CardType = (*(unsigned int *)Base >> 12) & 0xf;
+ xf86UnMapVidMem(pScrn->scrnIndex, Base, 4);
+ }
+
+ switch (pTga->CardType) {
+ case TYPE_TGA_8PLANE:
+ case TYPE_TGA_24PLANE:
+ case TYPE_TGA_24PLUSZ:
+ xf86DrvMsg(pScrn->scrnIndex, from, "Card Name: \"%s\"\n",
+ tga_cardnames[pTga->CardType]);
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Card \"0x%02x\" is not recognised\n", pTga->CardType);
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Assuming 8 plane TGA with 2MB frame buffer\n");
+ pTga->CardType = TYPE_TGA_8PLANE;
+ break;
+ }
+
+ /* Adjust framebuffer for card type */
+ pTga->FbAddress += fb_offset_presets[pTga->CardType];
+
+ if (!(((pScrn->depth == 8) && (pTga->CardType == TYPE_TGA_8PLANE)) ||
+ ((pScrn->depth == 24) && (pTga->CardType == TYPE_TGA_24PLANE)) ||
+ ((pScrn->depth == 24) && (pTga->CardType == TYPE_TGA_24PLUSZ)))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this card\n",
+ pScrn->depth);
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pTga->FbAddress);
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n",
+ (unsigned long)pTga->IOAddress);
+
+ /* RAC stuff: we don't have any resources we need to reserve,
+ but we should do this here anyway */
+ if (xf86RegisterResources(pTga->pEnt->index, NULL, ResExclusive)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n");
+ TGAFreeRec(pScrn);
+ return FALSE;
+ }
+
+
+
+ /* HW bpp matches reported bpp */
+ pTga->HwBpp = pScrn->bitsPerPixel;
+
+ if (pTga->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pTga->pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else {
+ switch (pTga->CardType) {
+ case TYPE_TGA_8PLANE:
+ pScrn->videoRam = 2*1024;
+ break;
+ case TYPE_TGA_24PLANE:
+ pScrn->videoRam = 8*1024;
+ break;
+ case TYPE_TGA_24PLUSZ:
+ pScrn->videoRam = 16*1024;
+ break;
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+
+ pTga->FbMapSize = pScrn->videoRam * 1024;
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ mod = "cfb";
+ break;
+ case 32:
+ mod = "cfb32";
+ break;
+ }
+ if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ TGAFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Load XAA if needed */
+ if (!pTga->NoAccel || pTga->HWCursor)
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ TGAFreeRec(pScrn);
+ return FALSE;
+ }
+
+
+ /*********************
+ Let's check what type of DAC we have and reject if necessary
+ *********************/
+
+ pTga->RamDac = NULL;
+
+ switch (pTga->Chipset)
+ {
+ case PCI_CHIP_DEC21030:
+ if (pTga->CardType != TYPE_TGA_8PLANE) {
+ pTga->RamDacRec = NULL;
+ pTga->RamDac = NULL;
+ break;
+ }
+ pTga->RamDacRec = RamDacCreateInfoRec();
+ pTga->RamDacRec->ReadDAC = tgaBTInIndReg;
+ pTga->RamDacRec->WriteDAC = tgaBTOutIndReg;
+ pTga->RamDacRec->ReadAddress = tgaBTReadAddress;
+ pTga->RamDacRec->WriteAddress = tgaBTWriteAddress;
+ pTga->RamDacRec->ReadData = tgaBTReadData;
+ pTga->RamDacRec->WriteData = tgaBTWriteData;
+ if(!RamDacInit(pScrn, pTga->RamDacRec)) {
+ RamDacDestroyInfoRec(pTga->RamDacRec);
+ return FALSE;
+ }
+
+ TGAMapMem(pScrn);
+
+ pTga->RamDac = BTramdacProbe(pScrn, BTramdacs);
+
+ TGAUnmapMem(pScrn);
+
+ if (pTga->RamDac == NULL)
+ return FALSE;
+ break;
+ }
+
+
+ /*********************
+ set up clock and mode stuff
+ *********************/
+
+ pScrn->progClock = TRUE;
+
+ /* Set the min pixel clock */
+ pTga->MinClock = 16250; /* XXX Guess, need to check this */
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
+ pTga->MinClock / 1000);
+
+ /*
+ * If the user has specified ramdac speed in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pTga->pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ speed = pTga->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 32:
+ speed = pTga->pEnt->device->dacSpeeds[DAC_BPP32];
+ break;
+ }
+ if (speed == 0)
+ pTga->MaxClock = pTga->pEnt->device->dacSpeeds[0];
+ else
+ pTga->MaxClock = speed;
+ from = X_CONFIG;
+ } else {
+ if (pTga->Chipset == PCI_CHIP_DEC21030)
+ pTga->MaxClock = 135000;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
+ pTga->MaxClock / 1000);
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+ clockRanges = xnfalloc(sizeof(ClockRange));
+ clockRanges->next = NULL;
+ clockRanges->minClock = pTga->MinClock;
+ clockRanges->maxClock = pTga->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = FALSE; /* XXX check this */
+ clockRanges->doubleScanAllowed = FALSE; /* XXX check this */
+
+ if(pScrn->display->virtualX || pScrn->display->virtualY) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "TGA does not support a virtual desktop\n");
+ pScrn->display->virtualX = 0;
+ pScrn->display->virtualY = 0;
+ }
+
+ /*
+ * xf86ValidateModes will check that the mode HTotal and VTotal values
+ * don't exceed the chipset's limit if pScrn->maxHValue and
+ * pScrn->maxVValue are set. Since our TGAValidMode() already takes
+ * care of this, we don't worry about setting them here.
+ */
+ /* Select valid modes from those available */
+ /*
+ * XXX Assuming min pitch 256, max 2048
+ * XXX Assuming min height 128, max 2048
+ */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, 256, 2048,
+ pScrn->bitsPerPixel, 128, 2048,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pTga->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+
+ if (i == -1) {
+ TGAFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ TGAFreeRec(pScrn);
+ return FALSE;
+ }
+
+ if(i > 1) {
+ DisplayModePtr mp1 = NULL, mp2 = NULL;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "TGA only supports one mode, using first mode.\n");
+ mp1 = pScrn->modes->next;
+ mp2 = mp1;
+ while(mp1 && mp1->next != mp1) {
+ mp1 = mp1->next;
+ xf86DeleteMode(&(pScrn->modes), mp2);
+ mp2 = mp1;
+ }
+ }
+
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ return TRUE;
+}
+
+
+/*
+ * Map the framebuffer and MMIO memory.
+ */
+
+static Bool
+TGAMapMem(ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+
+ /*
+ * Map IO registers to virtual address space
+ */
+
+ /* TGA doesn't need a sparse memory mapping, because all register
+ accesses are doublewords */
+
+ pTga->IOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pTga->PciTag,
+ pTga->IOAddress, 0x100000);
+ if (pTga->IOBase == NULL)
+ return FALSE;
+
+ pTga->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pTga->PciTag,
+ (unsigned long)pTga->FbAddress,
+ pTga->FbMapSize);
+ if (pTga->FbBase == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+TGAUnmapMem(ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga;
+
+ pTga = TGAPTR(pScrn);
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->IOBase, 0x100000);
+ pTga->IOBase = NULL;
+
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTga->FbBase, pTga->FbMapSize);
+ pTga->FbBase = NULL;
+
+ return TRUE;
+}
+
+
+/*
+ * This function saves the video state.
+ */
+static void
+TGASave(ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga;
+ TGARegPtr tgaReg;
+ RamDacHWRecPtr pBT;
+ RamDacRegRecPtr BTreg;
+
+ pTga = TGAPTR(pScrn);
+ tgaReg = &pTga->SavedReg;
+
+ switch (pTga->Chipset)
+ {
+ case PCI_CHIP_DEC21030:
+ DEC21030Save(pScrn, tgaReg);
+ if (pTga->RamDac) {
+ pBT = RAMDACHWPTR(pScrn);
+ BTreg = &pBT->SavedReg;
+ (*pTga->RamDac->Save)(pScrn, pTga->RamDacRec, BTreg);
+ } else {
+ BT463ramdacSave(pScrn, pTga->Bt463saveReg);
+ }
+ break;
+ }
+}
+
+
+/*
+ * Initialise a new mode. This is currently still using the old
+ * "initialise struct, restore/write struct to HW" model. That could
+ * be changed.
+ */
+
+static Bool
+TGAModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ int ret = -1;
+ TGAPtr pTga;
+ TGARegPtr tgaReg;
+ RamDacHWRecPtr pBT;
+ RamDacRegRecPtr BTreg;
+
+ pTga = TGAPTR(pScrn);
+
+ pScrn->vtSema = TRUE;
+
+ switch (pTga->Chipset) {
+ case PCI_CHIP_DEC21030:
+ ret = DEC21030Init(pScrn, mode);
+ break;
+ }
+
+ if (!ret)
+ return FALSE;
+
+ /* Program the registers */
+ tgaReg = &pTga->ModeReg;
+
+ switch (pTga->Chipset) {
+ case PCI_CHIP_DEC21030:
+ DEC21030Restore(pScrn, tgaReg);
+ if (pTga->RamDac != NULL) {
+ pBT = RAMDACHWPTR(pScrn);
+ BTreg = &pBT->ModeReg;
+ (*pTga->RamDac->Restore)(pScrn, pTga->RamDacRec, BTreg);
+ } else {
+ BT463ramdacRestore(pScrn, pTga->Bt463modeReg);
+ }
+ break;
+ }
+
+ return TRUE;
+}
+
+/*
+ * Restore the initial (text) mode.
+ */
+static void
+TGARestore(ScrnInfoPtr pScrn)
+{
+ TGAPtr pTga;
+ TGARegPtr tgaReg;
+ RamDacHWRecPtr pBT;
+ RamDacRegRecPtr BTreg;
+
+ pTga = TGAPTR(pScrn);
+ tgaReg = &pTga->SavedReg;
+
+ /* Initial Text mode clock */
+ tgaReg->tgaRegs[0x0A] = 25175;
+
+ switch (pTga->Chipset) {
+ case PCI_CHIP_DEC21030:
+ DEC21030Restore(pScrn, tgaReg);
+ if (pTga->RamDac != NULL) {
+ pBT = RAMDACHWPTR(pScrn);
+ BTreg = &pBT->SavedReg;
+ (*pTga->RamDac->Restore)(pScrn, pTga->RamDacRec, BTreg);
+ if(pTga->HWCursor)
+ TGARestoreHWCursor(pScrn);
+ } else {
+ BT463ramdacRestore(pScrn, pTga->Bt463saveReg);
+ }
+ break;
+ }
+}
+
+
+/* Mandatory */
+
+/* This gets called at the start of each server generation */
+
+static Bool
+TGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn;
+ TGAPtr pTga;
+ int ret;
+ VisualPtr visual;
+
+ /*
+ * First get the ScrnInfoRec
+ */
+ pScrn = xf86Screens[pScreen->myNum];
+
+ pTga = TGAPTR(pScrn);
+
+ /* Map the TGA memory and MMIO areas */
+ if (!TGAMapMem(pScrn))
+ return FALSE;
+
+ /* Save the current state */
+ TGASave(pScrn);
+
+ /* Initialise the first mode */
+ TGAModeInit(pScrn, pScrn->currentMode);
+
+ /* Darken the screen for aesthetic reasons and set the viewport */
+ TGASaveScreen(pScreen, FALSE);
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ /*
+ * For bpp > 8, the default visuals are not acceptable because we only
+ * support TrueColor and not DirectColor. To deal with this, call
+ * miSetVisualTypes for each visual supported.
+ */
+
+ if (pScrn->bitsPerPixel > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
+ pScrn->defaultVisual))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ ret = cfbScreenInit(pScreen, pTga->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 32:
+ ret = cfb32ScreenInit(pScreen, pTga->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in TGAScrnInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ if (!ret)
+ return FALSE;
+
+ miInitializeBackingStore(pScreen);
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ if (pScrn->bitsPerPixel > 8) {
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ if (!pTga->NoAccel) {
+ switch (pTga->Chipset)
+ {
+ case PCI_CHIP_DEC21030:
+ if (pScrn->bitsPerPixel == 8) {
+ if(DEC21030AccelInit8(pScreen) == FALSE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "XAA Initialization failed\n");
+ return(FALSE);
+ }
+ } else if (pScrn->bitsPerPixel == 32) {
+ if(DEC21030AccelInit32(pScreen) == FALSE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "XAA Initialization failed\n");
+ return(FALSE);
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unsupported acceleration depth\n");
+ return(FALSE);
+ }
+ break;
+ }
+ }
+
+ /* Initialise cursor functions */
+ miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
+
+ /* Initialize HW cursor layer.
+ Must follow software cursor initialization*/
+ if (pTga->HWCursor) {
+ if(!TGAHWCursorInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ return(FALSE);
+ }
+ }
+
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ if ((pScrn->bitsPerPixel==8) &&
+ (!RamDacHandleColormaps(pScreen, 256, pScrn->rgbBits,
+ CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)))
+ return FALSE;
+
+ pTga->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = TGACloseScreen;
+ pScreen->SaveScreen = TGASaveScreen;
+
+#ifdef DPMSExtension
+ if(xf86DPMSInit(pScreen, TGADisplayPowerManagementSet, 0) == FALSE)
+ ErrorF("DPMS initialization failed!\n");
+#endif /* DPMSExtension */
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+ /* unblank the screen */
+ TGASaveScreen(pScreen, TRUE);
+
+ /* Done */
+ return TRUE;
+}
+
+
+/* Usually mandatory */
+static Bool
+TGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return TGAModeInit(xf86Screens[scrnIndex], mode);
+}
+
+
+/*
+ * This function is used to initialize the Start Address - the first
+ * displayed location in the video memory.
+ */
+/* Usually mandatory */
+static void
+TGAAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ /* we don't support virtual desktops, because TGA doesn't have the
+ ability to set the start of the visible framebuffer at an arbitrary
+ pixel */
+ return;
+}
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ *
+ * We may wish to unmap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static Bool
+TGAEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ /* Should we re-save the text mode on each VT enter? */
+ if (!TGAModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * This is called when VT switching away from the X server. Its job is
+ * to restore the previous (text) mode.
+ *
+ * We may wish to remap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static void
+TGALeaveVT(int scrnIndex, int flags)
+{
+ TGAPtr pTga;
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ pTga = TGAPTR(pScrn);
+ TGARestore(pScrn);
+
+ /* clear the screen...there's probably a better way to do this */
+ memset(pTga->FbBase, 0, pTga->FbMapSize);
+ return;
+}
+
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode. It should really also unmap the video memory too.
+ */
+
+/* Mandatory */
+static Bool
+TGACloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ TGAPtr pTga = TGAPTR(pScrn);
+
+ TGARestore(pScrn);
+ memset(pTga->FbBase, 0, pScrn->videoRam * 1024);
+ TGAUnmapMem(pScrn);
+ if(pTga->AccelInfoRec)
+ XAADestroyInfoRec(pTga->AccelInfoRec);
+ pScrn->vtSema = FALSE;
+
+ pScreen->CloseScreen = pTga->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+
+/* Free up any per-generation data structures */
+
+/* Optional */
+static void
+TGAFreeScreen(int scrnIndex, int flags)
+{
+ RamDacFreeRec(xf86Screens[scrnIndex]);
+ TGAFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+/* Optional */
+static int
+TGAValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ if (mode->Flags & V_INTERLACE)
+ return(MODE_BAD);
+
+ return(MODE_OK);
+}
+
+/* Do screen blanking */
+
+/* Mandatory */
+static Bool
+TGASaveScreen(ScreenPtr pScreen, Bool unblank)
+ /* this function should blank the screen when unblank is FALSE and
+ unblank it when unblank is TRUE -- it doesn't actually seem to be
+ used for much though */
+{
+ TGAPtr pTga;
+ ScrnInfoPtr pScrn;
+ int valid_reg = 0;
+
+ pScrn = xf86Screens[pScreen->myNum];
+ pTga = TGAPTR(pScrn);
+ valid_reg = TGA_READ_REG(TGA_VALID_REG);
+ valid_reg &= 0xFFFFFFFC;
+
+ if(unblank == FALSE)
+ valid_reg |= 0x3;
+ else /* this function is sometimes called w/1 || 2 as TRUE */
+ valid_reg |= 0x1;
+
+ TGA_WRITE_REG(valid_reg, TGA_VALID_REG);
+
+/* ErrorF("TGASaveScreen called\n"); */
+
+ return TRUE;
+}
+
+
+/*
+ * TGADisplayPowerManagementSet --
+ *
+ * Sets VESA Display Power Management Signaling (DPMS) Mode.
+ */
+#ifdef DPMSExtension
+static void
+TGADisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
+ int flags)
+{
+ TGAPtr pTga;
+ int valid_reg = 0;
+
+ pTga = TGAPTR(pScrn);
+ valid_reg = TGA_READ_REG(TGA_VALID_REG);
+ valid_reg &= 0xFFFFFFFC;
+
+ switch(PowerManagementMode) {
+ case DPMSModeOn:
+ /* HSync: On, VSync: On */
+ valid_reg |= 0x1;
+ break;
+ case DPMSModeStandby:
+ case DPMSModeSuspend:
+ /* TGA gives us a function to blank the screen while maintaining sync...
+ I guess we can just use that here... */
+ valid_reg |= 0x3;
+ break;
+ case DPMSModeOff:
+ valid_reg |= 0x2;
+ break;
+ default:
+ ErrorF("Invalid PowerManagementMode %d passed to TGADisplayPowerManagementSet\n", PowerManagementMode);
+ break;
+ }
+
+ TGA_WRITE_REG(valid_reg, TGA_VALID_REG);
+ return;
+}
+
+#endif /* DPMSExtension */
+
+
+static void
+TGARestoreHWCursor(ScrnInfoPtr pScrn)
+ /*
+ from tga.c in the linux kernel...may not work for BSD...
+ when the cursor is restored, it is one line down from where it should
+ be...this is disconcerting, but purely cosmetic. Unfortunately reading
+ in the cursor framebuffer doesn't seem to work, I get a bunch of junk
+ at the beginning...other than that, see tga_cursor.c
+ I believe this to be a problem with the linux kernel code.
+ Hmm...this seems to be a 2.0.* problem, 2.2 works ok
+ */
+{
+ unsigned char *p = NULL;
+ int i = 0;
+ TGAPtr pTga;
+ /* this is the linux console hw cursor...what about the bsd console? */
+ /* what about tgafb? */
+ const CARD32 cursor_source[128] = {
+ 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff,
+ 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000,
+ 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff,
+ 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000,
+ 0x000000ff, 0x00000000, 0x000000ff, 0x00000000, 0x000000ff,
+ 0x00000000, 0x000000ff, 0x00000000, 0x000000ff, 0x00000000,
+ 0x000000ff, 0x00000000,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+ };
+
+ pTga = TGAPTR(pScrn);
+
+ /* we want to move the cursor off the screen before we do anything with it
+ otherwise, there is a "ghost cursor" that shows up */
+ tgaBTOutIndReg(pScrn, BT_CURS_X_LOW, 0x00, 0);
+ tgaBTOutIndReg(pScrn, BT_CURS_X_HIGH, 0xF0, 0);
+
+ tgaBTOutIndReg(pScrn, BT_CURS_Y_LOW, 0x00, 0);
+ tgaBTOutIndReg(pScrn, BT_CURS_Y_HIGH, 0xF0, 0);
+
+
+ /* set a windows cursor -- oddly, this doesn't seem necessary */
+ tgaBTOutIndReg(pScrn, BT_COMMAND_REG_2, 0xFC, 0x02);
+
+ /* set a 64 bit cursor */
+/* tgaBTOutIndReg(pScrn, BT_COMMAND_REG_0, 0x7F, 0x80); */
+/* tgaBTOutIndReg(pScrn, BT_WRITE_ADDR, 0x00, 0x01); */
+/* tgaBTOutIndReg(pScrn, BT_STATUS_REG, 0xF8, 0x04); */
+
+ /* set the colors */
+ tgaBTOutIndReg(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x01);
+
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, 0xaa);
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, 0xaa);
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, 0xaa);
+
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, 0x00);
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, 0x00);
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, 0x00);
+
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, 0x00);
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, 0x00);
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, 0x00);
+
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, 0x00);
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, 0x00);
+ tgaBTOutIndReg(pScrn, BT_CURS_DATA, 0x00, 0x00);
+
+
+ /* load the console cursor */
+ tgaBTOutIndReg(pScrn, BT_WRITE_ADDR, 0xFC, 0x00);
+ p = (unsigned char *)cursor_source;
+ for(i = 0; i < 512; i++)
+ tgaBTOutIndReg(pScrn, BT_CURS_RAM_DATA, 0x00, *p++);
+ for(i = 0; i < 512; i++)
+ tgaBTOutIndReg(pScrn, BT_CURS_RAM_DATA, 0x00, 0xff);
+
+ return;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_regs.h b/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_regs.h
new file mode 100644
index 000000000..df00691d9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tga/tga_regs.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_regs.h,v 1.8 1999/04/25 10:02:26 dawes Exp $ */
+
+/* TGA hardware description (minimal)
+ *
+ * Offsets within Memory Space
+ *
+ * Portions taken from linux's own tga driver...
+ * Courtesy of Jay Estabrook.
+ */
+
+#ifndef TGA_REGS_H
+#define TGA_REGS_H
+
+#include "compiler.h"
+
+#define TYPE_TGA_8PLANE 0
+#define TYPE_TGA_24PLANE 1
+#define TYPE_TGA_24PLUSZ 3
+
+#define TGA_WRITE_REG(v,r) \
+ do {\
+ *(unsigned int *)((char*)(pTga->IOBase)+(r)) = v;\
+ mem_barrier();\
+ } while (0)
+#define TGA_READ_REG(r) \
+ ( *(unsigned int *)((char*)(pTga->IOBase)+(r)))
+
+#ifdef __alpha__
+/* we can avoid an mb() if we write to an alternate register space each time */
+
+#define MAX_OFFSET 8192
+#define OFFSET_INC 1024
+
+#define TGA_GET_IOBASE() iobase = (unsigned long)pTga->IOBase;
+#define TGA_GET_OFFSET() offset = pTga->regOffset;
+#define TGA_SAVE_OFFSET() pTga->regOffset = offset;
+
+/* #define PROFILE */
+#undef PROFILE
+
+#ifdef PROFILE
+static __inline__ unsigned int realcc()
+{
+ u_long cc;
+ __asm__ volatile("rpcc %0" : "=r"(cc) : : "memory");
+ return cc;
+}
+
+#define TGA_FAST_WRITE_REG(v,r) \
+do {\
+start = realcc();\
+ *(unsigned int *)(iobase + offset + (r)) = v;\
+ offset += OFFSET_INC;\
+ if(offset > MAX_OFFSET) (offset = 0);\
+ stop = realcc();\
+ ErrorF("TGA_FAST_WRITE_REG = %d\n", stop - start);\
+} while (0)
+
+#else /* PROFILE */
+
+#define TGA_FAST_WRITE_REG(v,r) \
+do {\
+ *(unsigned int *)(iobase + offset + (r)) = v;\
+ offset += OFFSET_INC;\
+ if(offset > MAX_OFFSET) (offset = 0);\
+} while (0)
+#endif /* PROFILE */
+
+#else /* __alpha__ */
+
+#define TGA_GET_IOBASE() ;
+#define TGA_GET_OFFSET() ;
+#define TGA_SAVE_OFFSET() ;
+#define TGA_FAST_WRITE_REG(v,r) TGA_WRITE_REG(v,r)
+
+#endif /* __alpha__ */
+
+#define BT485_WRITE(v,r) \
+ TGA_WRITE_REG((r),TGA_RAMDAC_SETUP_REG); \
+ TGA_WRITE_REG(((v)&0xff)|((r)<<8),TGA_RAMDAC_REG);
+
+#define TGA_ROM_OFFSET 0x0000000
+#define TGA_REGS_OFFSET 0x0100000
+#define TGA_8PLANE_FB_OFFSET 0x0200000
+#define TGA_24PLANE_FB_OFFSET 0x0800000
+#define TGA_24PLUSZ_FB_OFFSET 0x1000000
+
+#define TGA_FOREGROUND_REG 0x0020
+#define TGA_BACKGROUND_REG 0x0024
+#define TGA_PLANEMASK_REG 0x0028
+#define TGA_MODE_REG 0x0030
+#define SIMPLE 0x00
+#define Z3D 0x10
+#define OPAQUESTIPPLE 0x01
+#define FILL 0x20
+#define TRANSPARENTSTIPPLE 0x05
+#define BLOCKSTIPPLE 0x0D
+#define BLOCKFILL 0x2D
+#define OPAQUELINE 0x02
+#define TRANSPARENTLINE 0x06
+#define BPP8PACKED (0x00 << 8)
+#define BPP8UNPACK (0x01 << 8)
+#define BPP12LOW (0x02 << 8)
+#define BPP12HIGH (0x06 << 8)
+#define BPP24 (0x03 << 8)
+#define CAP_ENDS 0x8000
+#define X11 0x0000
+#define WIN32 0x2000
+ /* copy mode */
+#define COPY 0x07
+ /* opaque fill mode */
+#define OPAQUEFILL 0x21
+#define TRANSPARENTFILL 0x45
+#define TGA_RASTEROP_REG 0x0034
+#define TGA_PIXELSHIFT_REG 0x0038
+#define TGA_ADDRESS_REG 0x003c
+#define TGA_CONTINUE_REG 0x004c
+#define TGA_DEEP_REG 0x0050
+#define TGA_PIXELMASK_REG 0x002c
+#define TGA_CURSOR_BASE_REG 0x0060
+#define TGA_HORIZ_REG 0x0064
+#define TGA_VERT_REG 0x0068
+#define TGA_BASE_ADDR_REG 0x006c
+#define TGA_VALID_REG 0x0070
+#define TGA_CURSOR_XY_REG 0x0074
+#define TGA_INTR_STAT_REG 0x007c
+ /* GDAR */
+#define TGA_DATA_REG 0x0080
+#define TGA_WIDTH_REG 0x009c
+#define TGA_SPAN_REG 0x00bc
+#define TGA_RAMDAC_SETUP_REG 0x00c0
+#define TGA_SLOPE0_REG 0x0120
+#define TGA_SLOPE1_REG 0x0124
+#define TGA_SLOPE2_REG 0x0128
+#define TGA_SLOPE3_REG 0x012C
+#define TGA_SLOPE4_REG 0x0130
+#define TGA_SLOPE5_REG 0x0134
+#define TGA_SLOPE6_REG 0x0138
+#define TGA_SLOPE7_REG 0x013C
+#define TGA_BRES3_REG 0x0048;
+#define TGA_BRES2_REG 0x0044;
+#define TGA_BRES1_REG 0x0040;
+
+#define TGA_BLOCK_COLOR0_REG 0x0140
+#define TGA_BLOCK_COLOR1_REG 0x0144
+#define TGA_BLOCK_COLOR2_REG 0x0148
+#define TGA_BLOCK_COLOR3_REG 0x014c
+#define TGA_BLOCK_COLOR4_REG 0x0150
+#define TGA_BLOCK_COLOR5_REG 0x0154
+#define TGA_BLOCK_COLOR6_REG 0x0158
+#define TGA_BLOCK_COLOR7_REG 0x015c
+#define TGA_CLOCK_REG 0x01e8
+#define TGA_RAMDAC_REG 0x01f0
+#define TGA_CMD_STAT_REG 0x01f8
+
+#define BT485_READ_BIT 0x01
+#define BT485_WRITE_BIT 0x00
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/trident/Imakefile
new file mode 100644
index 000000000..4d4b72a72
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/trident/Imakefile
@@ -0,0 +1,56 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/Imakefile,v 1.13 1999/08/14 10:49:56 dawes Exp $
+XCOMM
+XCOMM This is an Imakefile for the TRIDENT driver.
+XCOMM
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = trident_driver.c tridentramdac.c trident_dac.c tridenthelper.c \
+ trident_accel.c trident_i2c.c /* trident_bank.c */ \
+ image_accel.c blade_accel.c
+OBJS = trident_driver.o tridentramdac.o trident_dac.o tridenthelper.o \
+ trident_accel.o trident_i2c.o /* trident_bank.o */ \
+ image_accel.o blade_accel.o
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/Xext \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \
+ -I$(XF86SRC)/xf1bpp -I$(XF86SRC)/xf4bpp \
+ -I$(XF86SRC)/xf24_32bpp \
+ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \
+ -I$(XF86SRC)/rac \
+ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
+ -I$(FONTINCSRC) -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(XTOP)/include/extensions
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget(trident,$(OBJS))
+
+InstallObjectModule(trident,$(MODULEDIR),drivers)
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/trident)
+InstallDriverSDKNonExecFile(blade_accel.c,$(DRIVERSDKDIR)/drivers/trident)
+InstallDriverSDKNonExecFile(image_accel.c,$(DRIVERSDKDIR)/drivers/trident)
+InstallDriverSDKNonExecFile(trident.h,$(DRIVERSDKDIR)/drivers/trident)
+InstallDriverSDKNonExecFile(trident_accel.c,$(DRIVERSDKDIR)/drivers/trident)
+InstallDriverSDKNonExecFile(trident_bank.c,$(DRIVERSDKDIR)/drivers/trident)
+InstallDriverSDKNonExecFile(trident_dac.c,$(DRIVERSDKDIR)/drivers/trident)
+InstallDriverSDKNonExecFile(trident_driver.c,$(DRIVERSDKDIR)/drivers/trident)
+InstallDriverSDKNonExecFile(trident_i2c.c,$(DRIVERSDKDIR)/drivers/trident)
+InstallDriverSDKNonExecFile(trident_regs.h,$(DRIVERSDKDIR)/drivers/trident)
+InstallDriverSDKNonExecFile(tridenthelper.c,$(DRIVERSDKDIR)/drivers/trident)
+InstallDriverSDKNonExecFile(tridentramdac.c,$(DRIVERSDKDIR)/drivers/trident)
+
+InstallDriverSDKObjectModule(trident,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/blade_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/trident/blade_accel.c
new file mode 100644
index 000000000..c273afde4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/trident/blade_accel.c
@@ -0,0 +1,628 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Trident Blade3D accelerated options.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/blade_accel.c,v 1.3 1999/06/20 07:14:32 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "miline.h"
+
+#include "trident_regs.h"
+#include "trident.h"
+
+#include "xaarop.h"
+#include "xaalocal.h"
+
+static void BladeSync(ScrnInfoPtr pScrn);
+static void BladeSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void BladeSubsequentSolidTwoPointLine( ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags);
+static void BladeSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop, unsigned int planemask, int length,
+ unsigned char *pattern);
+static void BladeSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags,
+ int phase);
+static void BladeSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void BladeSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h);
+static void BladeSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2,
+ int y2, int w, int h);
+static void BladeSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask,
+ int transparency_color);
+static void BladeSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void BladeSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int srcx, int srcy,
+ int offset);
+static void BladeSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void BladeSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft);
+static void BladeSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2);
+static void BladeDisableClipping(ScrnInfoPtr pScrn);
+static void BladeSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int fg, int bg,
+ int rop, unsigned int planemask);
+static void BladeSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+static void BladeSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int rop, unsigned int planemask, int trans_col);
+static void BladeSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+static void BladeSetupForImageWrite(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int transparency_color,
+ int bpp, int depth);
+static void BladeSubsequentImageWriteRect(ScrnInfoPtr pScrn, int x, int y,
+ int w, int h, int skipleft);
+
+static void
+BladeInitializeAccelerator(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ CARD32 stride;
+
+ stride = (pScrn->displayWidth >> 3) << 20;
+ BLADE_OUT(0x21C8, stride);
+ BLADE_OUT(0x21CC, stride);
+ BLADE_OUT(0x21D0, stride);
+ BLADE_OUT(0x21D4, stride);
+ switch (pScrn->depth) {
+ case 8:
+ stride |= 0<<29;
+ break;
+ case 15:
+ stride |= 5<<29;
+ break;
+ case 16:
+ stride |= 1<<29;
+ break;
+ case 24:
+ stride |= 2<<29;
+ break;
+ }
+ BLADE_OUT(0x21B8, stride);
+ BLADE_OUT(0x21BC, stride);
+ BLADE_OUT(0x21C0, stride);
+ BLADE_OUT(0x21C4, stride);
+}
+
+Bool
+BladeAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ BoxRec AvailFBArea;
+
+ pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ BladeInitializeAccelerator(pScrn);
+
+ infoPtr->Flags = PIXMAP_CACHE |
+ LINEAR_FRAMEBUFFER |
+ OFFSCREEN_PIXMAPS;
+
+ infoPtr->Sync = BladeSync;
+
+ infoPtr->SetClippingRectangle = BladeSetClippingRectangle;
+ infoPtr->DisableClipping = BladeDisableClipping;
+ infoPtr->ClippingFlags = /* HARDWARE_CLIP_SOLID_FILL | */
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
+ HARDWARE_CLIP_MONO_8x8_FILL;
+
+#if 0
+ infoPtr->SolidLineFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidLine = BladeSetupForSolidLine;
+ infoPtr->SubsequentSolidTwoPointLine = BladeSubsequentSolidTwoPointLine;
+ infoPtr->SetupForDashedLine = BladeSetupForDashedLine;
+ infoPtr->SubsequentDashedTwoPointLine = BladeSubsequentDashedTwoPointLine;
+ infoPtr->DashPatternMaxLength = 16;
+ infoPtr->DashedLineFlags = LINE_PATTERN_LSBFIRST_LSBJUSTIFIED |
+ LINE_PATTERN_POWER_OF_2_ONLY |
+ NO_TRANSPARENCY |
+ NO_PLANEMASK;
+#endif
+
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill = BladeSetupForFillRectSolid;
+ infoPtr->SubsequentSolidFillRect = BladeSubsequentFillRectSolid;
+
+ infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK |
+ NO_TRANSPARENCY |
+ ONLY_TWO_BITBLT_DIRECTIONS;
+
+ infoPtr->SetupForScreenToScreenCopy =
+ BladeSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy =
+ BladeSubsequentScreenToScreenCopy;
+
+ infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
+ NO_TRANSPARENCY |
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS;
+
+ infoPtr->SetupForMono8x8PatternFill =
+ BladeSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ BladeSubsequentMono8x8PatternFillRect;
+
+#if 0
+ infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ NO_TRANSPARENCY |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ infoPtr->SetupForColor8x8PatternFill =
+ TridentSetupForColor8x8PatternFill;
+ infoPtr->SubsequentColor8x8PatternFillRect =
+ TridentSubsequentColor8x8PatternFillRect;
+
+ infoPtr->ScreenToScreenColorExpandFillFlags = NO_TRANSPARENCY |NO_PLANEMASK;
+
+ infoPtr->SetupForScreenToScreenColorExpandFill =
+ BladeSetupForScreenToScreenColorExpand;
+ infoPtr->SubsequentScreenToScreenColorExpandFill =
+ BladeSubsequentScreenToScreenColorExpand;
+#endif
+
+ infoPtr->CPUToScreenColorExpandFillFlags = CPU_TRANSFER_PAD_DWORD |
+ LEFT_EDGE_CLIPPING |
+ SYNC_AFTER_COLOR_EXPAND |
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ SCANLINE_PAD_DWORD |
+ NO_PLANEMASK;
+ infoPtr->ColorExpandRange = 0x8000;
+ infoPtr->ColorExpandBase = pTrident->IOBase + 0x10000;
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ BladeSetupForCPUToScreenColorExpand;
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ BladeSubsequentCPUToScreenColorExpand;
+
+ infoPtr->SetupForImageWrite = BladeSetupForImageWrite;
+ infoPtr->SubsequentImageWriteRect = BladeSubsequentImageWriteRect;
+ infoPtr->ImageWriteFlags = NO_TRANSPARENCY | NO_PLANEMASK |
+ LEFT_EDGE_CLIPPING |
+ CPU_TRANSFER_PAD_DWORD |
+ SYNC_AFTER_IMAGE_WRITE;
+ infoPtr->ImageWriteBase = pTrident->IOBase + 0x10000;
+ infoPtr->ImageWriteRange = 0x10000;
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = (pTrident->FbMapSize - 4096) / (pScrn->displayWidth *
+ pScrn->bitsPerPixel / 8);
+ if (AvailFBArea.y2 > 4095) AvailFBArea.y2 = 4095;
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ return(XAAInit(pScreen, infoPtr));
+}
+
+static void
+BladeSyncClip(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int busy;
+ int cnt = 500000;
+
+ BLADEBUSY(busy);
+ while (busy != 0) {
+ if (--cnt < 0) {
+ ErrorF("GE timeout\n");
+ BLADE_OUT(0x2120, 0x00000000);
+ BladeInitializeAccelerator(pScrn);
+ break;
+ }
+ BLADEBUSY(busy);
+ }
+}
+
+static void
+BladeSync(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int busy;
+ int cnt = 500000;
+
+ if (pTrident->Clipping) BladeDisableClipping(pScrn);
+
+ BLADEBUSY(busy);
+ while (busy != 0) {
+ if (--cnt < 0) {
+ ErrorF("GE timeout\n");
+ BLADE_OUT(0x2120, 0x00000000);
+ BladeInitializeAccelerator(pScrn);
+ break;
+ }
+ BLADEBUSY(busy);
+ }
+}
+
+static void
+BladeSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int transparency_color)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pTrident->BltScanDirection = 0;
+ if ((xdir < 0) || (ydir < 0)) pTrident->BltScanDirection |= 1<<1;
+
+ BLADE_OUT(0x2148, XAACopyROP[rop]);
+}
+
+static void
+BladeSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int clip = 0;
+
+ if (pTrident->Clipping) clip = 1;
+
+ BLADE_OUT(0x2144, 0xE0000000 | 1<<19 | 1<<4 | 1<<2 | pTrident->BltScanDirection | clip);
+
+ if (pTrident->BltScanDirection) {
+ BLADE_OUT(0x2100, (y1+h-1)<<16 | (x1+w-1));
+ BLADE_OUT(0x2104, y1<<16 | x1);
+ BLADE_OUT(0x2108, (y2+h-1)<<16 | (x2+w-1));
+ BLADE_OUT(0x210C, y2<<16 | x2);
+ } else {
+ BLADE_OUT(0x2100, y1<<16 | x1);
+ BLADE_OUT(0x2104, (y1+h-1)<<16 | (x1+w-1));
+ BLADE_OUT(0x2108, y2<<16 | x2);
+ BLADE_OUT(0x210C, (y2+h-1)<<16 | (x2+w-1));
+ }
+ if (!pTrident->UsePCIRetry)
+ BladeSyncClip(pScrn);
+}
+
+static void
+BladeSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ BLADE_OUT(0x2154, (y1&0x0fff)<<16 | (x1&0x0fff));
+ BLADE_OUT(0x2158, (y2&0x0fff)<<16 | (x2&0x0fff));
+ pTrident->Clipping = TRUE;
+}
+
+static void
+BladeDisableClipping(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ pTrident->Clipping = FALSE;
+}
+
+static void
+BladeSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ REPLICATE(color);
+ BLADE_OUT(0x2160, color);
+ BLADE_OUT(0x2148, XAACopyROP[rop]);
+}
+
+static void
+BladeSubsequentSolidTwoPointLine( ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (flags & OMIT_LAST)
+ BladeSetClippingRectangle(pScrn,x1,y1,x2-1,y2-1);
+
+ BLADE_OUT(0x2144, 0x20000000 | 1<<19 | 1<<4 | 2<<2);
+ BLADE_OUT(0x2108, y1<<16 | x1);
+ BLADE_OUT(0x210C, y2<<16 | x2);
+
+ if (flags & OMIT_LAST)
+ BladeDisableClipping(pScrn);
+
+ if (!pTrident->UsePCIRetry)
+ BladeSyncClip(pScrn);
+}
+
+static void
+BladeSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int length, unsigned char *pattern)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pTrident->LinePattern = *((CARD16 *)pattern) & ((1<<length) - 1);
+ switch (length) {
+ case 2:
+ pTrident->LinePattern = pTrident->LinePattern | (pTrident->LinePattern << 2);
+ case 4:
+ pTrident->LinePattern = pTrident->LinePattern | (pTrident->LinePattern << 4);
+ case 8:
+ pTrident->LinePattern = pTrident->LinePattern | (pTrident->LinePattern << 8);
+ }
+
+ REPLICATE(fg);
+ REPLICATE(bg);
+ BLADE_OUT(0x2160, fg);
+ BLADE_OUT(0x2164, bg);
+ BLADE_OUT(0x2148, XAACopyROP[rop]);
+}
+
+static void
+BladeSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags, int phase)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (flags & OMIT_LAST)
+ BladeSetClippingRectangle(pScrn,x1,y1,x2-1,y2-1);
+
+ BLADE_OUT(0x216C, (pTrident->LinePattern >> phase) | (pTrident->LinePattern << (16-phase)));
+ BLADE_OUT(0x2144, 0x20000000 | 1<<27 | 1<<19 | 1<<4 | 2<<2);
+ BLADE_OUT(0x2108, y1<<16 | x1);
+ BLADE_OUT(0x210C, y2<<16 | x2);
+
+ if (flags & OMIT_LAST)
+ BladeDisableClipping(pScrn);
+
+ if (!pTrident->UsePCIRetry)
+ BladeSyncClip(pScrn);
+}
+
+static void
+BladeSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pTrident->ROP = rop;
+ REPLICATE(color);
+ BLADE_OUT(0x2160, color);
+ BLADE_OUT(0x2148, XAACopyROP[rop]);
+}
+
+static void
+BladeSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int clip = 0;
+
+ if (pTrident->Clipping) clip = 1;
+ BLADE_OUT(0x2144, 0x20000000 | 1<<19 | 1<<4 | 2<<2 | clip);
+ BLADE_OUT(0x2108, y<<16 | x);
+ BLADE_OUT(0x210C, (y+h-1)<<16 | (x+w-1));
+ if (!pTrident->UsePCIRetry)
+ BladeSyncClip(pScrn);
+}
+
+static void
+BladeSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pTrident->ROP = rop;
+
+ REPLICATE(bg);
+ REPLICATE(fg);
+ IMAGE_OUT(0x44, fg);
+ IMAGE_OUT(0x48, bg);
+ IMAGE_OUT(0x20, 0x90000000 | XAACopyROP[rop]);
+}
+
+static void
+BladeSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int srcx, int srcy, int offset)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ IMAGE_OUT(0x00, srcy<<16 | srcx);
+ IMAGE_OUT(0x04, (srcy+h-1)<<16 | (srcx+w-1));
+ IMAGE_OUT(0x08, y<<16 | x);
+ IMAGE_OUT(0x0C, (y+h-1)<<16 | (x+w-1));
+
+ IMAGE_OUT(0x24, 0x80000000 | 3<<22 | 1<<7 | (pTrident->ROP == GXcopy ? 0 : 1<<10) | offset<<25);
+}
+
+static void
+BladeSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (bg == -1) pTrident->ROP = 2<<19;
+ else pTrident->ROP = 3<<19;
+ REPLICATE(fg);
+ REPLICATE(bg);
+ BLADE_OUT(0x2160, fg);
+ BLADE_OUT(0x2164, bg);
+ BLADE_OUT(0x2148, XAACopyROP[rop]);
+}
+
+static void
+BladeSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (skipleft) BladeSetClippingRectangle(pScrn,x+skipleft,y,(x+w-1),(y+h-1));
+ BLADE_OUT(0x2144, 0xE0000000 | pTrident->ROP | 1<<4 | (skipleft ? 1 : 0));
+ BLADE_OUT(0x2108, y<<16 | x);
+ BLADE_OUT(0x210C, (y+h-1)<<16 | (x+w-1));
+}
+
+static void MoveDWORDS(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ *(dest + 2) = *(src + 2);
+ *(dest + 3) = *(src + 3);
+ src += 4;
+ dest += 4;
+ dwords -= 4;
+ }
+ if (!dwords) return;
+ *dest = *src;
+ dest += 1;
+ src += 1;
+ if (dwords == 1) return;
+ *dest = *src;
+ dest += 1;
+ src += 1;
+ if (dwords == 2) return;
+ *dest = *src;
+ dest += 1;
+ src += 1;
+}
+
+static void
+BladeSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ BLADE_OUT(0x2148, XAAPatternROP[rop]);
+ if (bg == -1) {
+ REPLICATE(fg);
+ BLADE_OUT(0x216C, 0x80000000 | 1<<30);
+ BLADE_OUT(0x216C, 0x80000000 | 1<<28 | 1<<30);
+ BLADE_OUT(0x2170, patternx);
+ BLADE_OUT(0x2170, patterny);
+ BLADE_OUT(0x2174, fg);
+ } else {
+ REPLICATE(fg);
+ REPLICATE(bg);
+ BLADE_OUT(0x216C, 0x80000000);
+ BLADE_OUT(0x216C, 0x80000000 | 1<<28);
+ BLADE_OUT(0x2170, patternx);
+ BLADE_OUT(0x2170, patterny);
+ BLADE_OUT(0x2174, fg);
+ BLADE_OUT(0x2178, bg);
+ }
+}
+
+static void
+BladeSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int clip = 0;
+
+ if (pTrident->Clipping) clip = 1;
+ BLADE_OUT(0x2144, 0x20000000 | 7<<12 | 1<<4 | 1<<19 | 2<<2 | clip);
+ BLADE_OUT(0x2108, y<<16 | x);
+ BLADE_OUT(0x210C, (y+h-1)<<16 | (x+w-1));
+ if (!pTrident->UsePCIRetry)
+ BladeSyncClip(pScrn);
+}
+
+static void
+BladeSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int rop,
+ unsigned int planemask,
+ int trans_col)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_PATLOC(((patterny * pScrn->displayWidth * pScrn->bitsPerPixel / 8) +
+ (patternx * pScrn->bitsPerPixel / 8)) >> 6);
+ if (trans_col == -1) {
+ REPLICATE(trans_col);
+ TGUI_BCOLOUR(trans_col);
+ TGUI_DRAWFLAG(PAT2SCR | 1<<12);
+ } else
+ TGUI_DRAWFLAG(PAT2SCR);
+ TGUI_FMIX(XAAPatternROP[rop]);
+}
+
+static void
+BladeSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_DEST_XY(x,y);
+ TGUI_DIM_XY(w,h);
+ TGUI_COMMAND(GE_BLT);
+ CHECKCLIPPING;
+}
+
+static void BladeSetupForImageWrite(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ BLADE_OUT(0x2148, XAACopyROP[rop]);
+}
+
+static void BladeSubsequentImageWriteRect(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (skipleft) BladeSetClippingRectangle(pScrn,x+skipleft,y,(x+w-1),(y+h-1));
+ BLADE_OUT(0x2144, 0xE0000000 | 1<<19 | 1<<4 | (skipleft ? 1 : 0));
+ BLADE_OUT(0x2108, y<<16 | x);
+ BLADE_OUT(0x210C, (y+h-1)<<16 | (x+w-1));
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/image_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/trident/image_accel.c
new file mode 100644
index 000000000..b25e9dd64
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/trident/image_accel.c
@@ -0,0 +1,605 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Trident 3DImage' accelerated options.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/image_accel.c,v 1.12 1999/08/24 07:31:26 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "miline.h"
+
+#include "trident_regs.h"
+#include "trident.h"
+
+#include "xaarop.h"
+#include "xaalocal.h"
+
+static void ImageSync(ScrnInfoPtr pScrn);
+static void ImageSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void ImageSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+static void ImageSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void ImageSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h);
+static void ImageSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2,
+ int y2, int w, int h);
+static void ImageSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask,
+ int transparency_color);
+static void ImageSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void ImageSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int srcx, int srcy,
+ int offset);
+static void ImageSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void ImageSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft);
+static void ImageSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2);
+static void ImageDisableClipping(ScrnInfoPtr pScrn);
+static void ImageSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int fg, int bg,
+ int rop, unsigned int planemask);
+static void ImageSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+static void ImageSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int rop, unsigned int planemask, int trans_col);
+static void ImageSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+static void ImageSetupForImageWrite(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+);
+static void ImageSubsequentImageWriteRect(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+);
+
+static void
+ImageInitializeAccelerator(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ IMAGE_OUT(0x2120, 0xF0000000);
+ switch (pScrn->depth) {
+ case 8:
+ pTrident->EngineOperation = 0;
+ break;
+ case 15:
+ pTrident->EngineOperation = 5;
+ break;
+ case 16:
+ pTrident->EngineOperation = 1;
+ break;
+ case 24:
+ pTrident->EngineOperation = 2;
+ break;
+ }
+ IMAGE_OUT(0x2120, 0x40000000 | pTrident->EngineOperation);
+ IMAGE_OUT(0x2120, 0x80000000);
+ IMAGE_OUT(0x2144, 0x00000000);
+ IMAGE_OUT(0x2148, 0x00000000);
+ IMAGE_OUT(0x2120, 0x60000000 | pScrn->displayWidth<<16 | pScrn->displayWidth);
+ IMAGE_OUT(0x216C, 0x00000000);
+ IMAGE_OUT(0x2170, 0x00000000);
+ IMAGE_OUT(0x217C, 0x00000000);
+ IMAGE_OUT(0x2120, 0x10000000 | 4095 << 16 | 4095);
+ IMAGE_OUT(0x2130, 4095 << 16 | 4095);
+ pTrident->DstEnable = FALSE;
+}
+
+Bool
+ImageAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ BoxRec AvailFBArea;
+
+ pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ ImageInitializeAccelerator(pScrn);
+
+ infoPtr->Flags = PIXMAP_CACHE |
+ LINEAR_FRAMEBUFFER |
+ OFFSCREEN_PIXMAPS;
+
+ infoPtr->Sync = ImageSync;
+
+ infoPtr->SetClippingRectangle = ImageSetClippingRectangle;
+ infoPtr->DisableClipping = ImageDisableClipping;
+ infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_FILL |
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
+ HARDWARE_CLIP_MONO_8x8_FILL;
+
+#if 0
+ infoPtr->SolidLineFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidLine = ImageSetupForFillRectSolid;
+ infoPtr->SolidBresenhamLineErrorTermBits = 11;
+ infoPtr->SubsequentSolidBresenhamLine = ImageSubsequentSolidBresenhamLine;
+#endif
+
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill = ImageSetupForFillRectSolid;
+ infoPtr->SubsequentSolidFillRect = ImageSubsequentFillRectSolid;
+
+ infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK |
+ NO_TRANSPARENCY |
+ ONLY_TWO_BITBLT_DIRECTIONS;
+
+ infoPtr->SetupForScreenToScreenCopy =
+ ImageSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy =
+ ImageSubsequentScreenToScreenCopy;
+
+ infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS;
+
+ infoPtr->SetupForMono8x8PatternFill =
+ ImageSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ ImageSubsequentMono8x8PatternFillRect;
+
+#if 0
+ infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ NO_TRANSPARENCY |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ infoPtr->SetupForColor8x8PatternFill =
+ TridentSetupForColor8x8PatternFill;
+ infoPtr->SubsequentColor8x8PatternFillRect =
+ TridentSubsequentColor8x8PatternFillRect;
+
+ infoPtr->ScreenToScreenColorExpandFillFlags = NO_TRANSPARENCY |NO_PLANEMASK;
+
+ infoPtr->SetupForScreenToScreenColorExpandFill =
+ ImageSetupForScreenToScreenColorExpand;
+ infoPtr->SubsequentScreenToScreenColorExpandFill =
+ ImageSubsequentScreenToScreenColorExpand;
+#endif
+
+#if 0
+ infoPtr->CPUToScreenColorExpandFillFlags = CPU_TRANSFER_PAD_QWORD |
+ NO_TRANSPARENCY |
+ SYNC_AFTER_COLOR_EXPAND |
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ SCANLINE_PAD_DWORD |
+ NO_PLANEMASK;
+ infoPtr->ColorExpandRange = 0x8000;
+ infoPtr->ColorExpandBase = pTrident->IOBase + 0x10000;
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ ImageSetupForCPUToScreenColorExpand;
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ ImageSubsequentCPUToScreenColorExpand;
+#endif
+
+#if 0
+ infoPtr->SetupForImageWrite = ImageSetupForImageWrite;
+ infoPtr->SubsequentImageWriteRect = ImageSubsequentImageWriteRect;
+ infoPtr->ImageWriteFlags = NO_TRANSPARENCY | NO_PLANEMASK |
+ CPU_TRANSFER_PAD_QWORD |
+ SYNC_AFTER_IMAGE_WRITE;
+ infoPtr->ImageWriteBase = pTrident->IOBase + 0x10000;
+ infoPtr->ImageWriteRange = 0x8000;
+#endif
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = (pTrident->FbMapSize - 4096) / (pScrn->displayWidth *
+ pScrn->bitsPerPixel / 8);
+ if (AvailFBArea.y2 > 4095) AvailFBArea.y2 = 4095;
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ return(XAAInit(pScreen, infoPtr));
+}
+
+static void
+ImageSync(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int busy;
+ int cnt = 500000;
+
+ if (pTrident->Clipping) ImageDisableClipping(pScrn);
+
+ IMAGEBUSY(busy);
+ while (busy != 0) {
+ if (--cnt < 0) {
+ ErrorF("GE timeout\n");
+ IMAGE_OUT(0x2164, 0x00000000);
+ ImageInitializeAccelerator(pScrn);
+ break;
+ }
+ IMAGEBUSY(busy);
+ }
+}
+
+static void
+ImageSyncClip(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int busy;
+ int cnt = 500000;
+
+ IMAGEBUSY(busy);
+ while (busy != 0) {
+ if (--cnt < 0) {
+ ErrorF("GE timeout\n");
+ IMAGE_OUT(0x2164, 0x00000000);
+ ImageInitializeAccelerator(pScrn);
+ break;
+ }
+ IMAGEBUSY(busy);
+ }
+}
+
+static void
+ImageSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int transparency_color)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pTrident->BltScanDirection = 0;
+ if ((xdir < 0) || (ydir < 0)) pTrident->BltScanDirection |= 1<<2;
+
+ IMAGE_OUT(0x2120, 0x80000000);
+ IMAGE_OUT(0x2120, 0x90000000 | XAACopyROP[rop]);
+}
+
+static void
+ImageSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (pTrident->BltScanDirection) {
+ IMAGE_OUT(0x2100, (y1+h-1)<<16 | (x1+w-1));
+ IMAGE_OUT(0x2104, y1<<16 | x1);
+ IMAGE_OUT(0x2108, (y2+h-1)<<16 | (x2+w-1));
+ IMAGE_OUT(0x210C, y2<<16 | x2);
+ } else {
+ IMAGE_OUT(0x2100, y1<<16 | x1);
+ IMAGE_OUT(0x2104, (y1+h-1)<<16 | (x1+w-1));
+ IMAGE_OUT(0x2108, y2<<16 | x2);
+ IMAGE_OUT(0x210C, (y2+h-1)<<16 | (x2+w-1));
+ }
+
+ IMAGE_OUT(0x2124, 0x80000000 | 1<<22 | 1<<7 | 1<<10 | pTrident->BltScanDirection | (pTrident->Clipping ? 1 : 0));
+
+ if (!pTrident->UsePCIRetry)
+ ImageSyncClip(pScrn);
+}
+
+static void
+ImageSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ IMAGE_OUT(0x2120, 0x10000000 | y1<<16 | x1);
+ IMAGE_OUT(0x2130, y2<<16 | x2);
+ pTrident->Clipping = TRUE;
+}
+
+static void
+ImageDisableClipping(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ pTrident->Clipping = FALSE;
+}
+
+static void
+ImageSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ IMAGE_OUT(0x2120, 0x90000000 | XAACopyROP[rop]);
+ IMAGE_OUT(0x2144, color);
+}
+
+static void
+ImageSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int direction = 0;
+
+ pTrident->BltScanDirection = 0;
+ if (octant & YMAJOR) pTrident->BltScanDirection = 1<<18;
+ if (octant & XDECREASING) direction |= 1<<30;
+ if (octant & YDECREASING) direction |= 1<<31;
+
+ IMAGE_OUT(0x2124, 0x20000000 | 1<<22 | 1<<10 | 1<<9);
+ IMAGE_OUT(0x21FC, 0x20000000 | 1<<19 | pTrident->BltScanDirection);
+ IMAGE_OUT(0x2200, y<<16 | x);
+ IMAGE_OUT(0x2204, direction | dmaj << 16 | dmin);
+ IMAGE_OUT(0x2208, (e << 16) | len);
+
+ if (!pTrident->UsePCIRetry)
+ ImageSyncClip(pScrn);
+}
+
+static void
+ImageSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ IMAGE_OUT(0x2120, 0x80000000);
+ REPLICATE(color);
+ pTrident->ROP = rop;
+ IMAGE_OUT(0x2120, 0x90000000 | XAACopyROP[rop]);
+ IMAGE_OUT(0x2144, color);
+}
+
+static void
+ImageSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int clip = 0;
+
+ if (pTrident->Clipping) clip = 1;
+
+ IMAGE_OUT(0x2108, y<<16 | x);
+ IMAGE_OUT(0x210C, ((y+h-1)<<16) | (x+w-1));
+ IMAGE_OUT(0x2124, 0x80000000 | 1<<22 | 1<<10 | 1<<9 | clip);
+ if (!pTrident->UsePCIRetry)
+ ImageSyncClip(pScrn);
+}
+
+static void
+ImageSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pTrident->ROP = rop;
+
+ REPLICATE(bg);
+ REPLICATE(fg);
+ IMAGE_OUT(0x2144, fg);
+ IMAGE_OUT(0x2148, bg);
+ IMAGE_OUT(0x2120, 0x90000000 | XAACopyROP[rop]);
+}
+
+static void
+ImageSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int srcx, int srcy, int offset)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ IMAGE_OUT(0x2100, srcy<<16 | srcx);
+ IMAGE_OUT(0x2104, ((srcy+h-1)<<16) | (srcx+w-1));
+ IMAGE_OUT(0x2108, y<<16 | x);
+ IMAGE_OUT(0x210C, ((y+h-1)<<16) | (x+w-1));
+
+ IMAGE_OUT(0x2124, 0x80000000 | 3<<22 | 1<<7 | 1<<10 | offset<<18);
+
+ if (!pTrident->UsePCIRetry)
+ ImageSyncClip(pScrn);
+}
+
+static void
+ImageSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (bg == -1) pTrident->ROP = 2<<22;
+ else pTrident->ROP = 3<<22;
+ REPLICATE(fg);
+ REPLICATE(bg);
+ IMAGE_OUT(0x2120, 0x80000000);
+ IMAGE_OUT(0x2144, fg);
+ IMAGE_OUT(0x2148, bg);
+ IMAGE_OUT(0x2120, 0x90000000 | XAACopyROP[rop]);
+}
+
+static void
+ImageSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+if ((w==0) || (h==0))return;
+ IMAGE_OUT(0x2108, y<<16 | x);
+ IMAGE_OUT(0x210C, ((y+h-1)<<16) | (x+w-1));
+ IMAGE_OUT(0x2124, 0x80000000 | pTrident->ROP | 1<<10);
+}
+
+static void MoveBYTE(
+ register unsigned char* dest,
+ register unsigned char* src,
+ register int bytes
+)
+{
+ while(bytes) {
+ *dest = *src;
+ src += 1;
+ dest += 1;
+ bytes -= 1;
+ }
+}
+
+static void MoveDWORDS(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ *(dest + 2) = *(src + 2);
+ *(dest + 3) = *(src + 3);
+ src += 4;
+ dest += 4;
+ dwords -= 4;
+ }
+ if (!dwords) return;
+ *dest = *src;
+ dest += 1;
+ src += 1;
+ if (dwords == 1) return;
+ *dest = *src;
+ dest += 1;
+ src += 1;
+ if (dwords == 2) return;
+ *dest = *src;
+ dest += 1;
+ src += 1;
+}
+
+static void
+ImageSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int mix = XAAHelpPatternROP(pScrn, &fg, &bg, planemask, &rop);
+
+ IMAGE_OUT(0x2120, 0x90000000 | rop);
+ if (bg == -1) {
+ REPLICATE(fg);
+ IMAGE_OUT(0x2120, 0x80000000 | 1<<27);
+ IMAGE_OUT(0x2130, patternx);
+ IMAGE_OUT(0x2134, patterny);
+ IMAGE_OUT(0x2150, fg);
+ } else {
+ REPLICATE(bg);
+ REPLICATE(fg);
+ IMAGE_OUT(0x2120, 0x80000000 | 1<<27 | 1<<26);
+ IMAGE_OUT(0x2130, patternx);
+ IMAGE_OUT(0x2134, patterny);
+ IMAGE_OUT(0x2150, fg);
+ IMAGE_OUT(0x2154, bg);
+ }
+}
+
+static void
+ImageSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int clip = 0;
+
+ if (pTrident->Clipping) clip = 1;
+ IMAGE_OUT(0x2108, y<<16 | x);
+ IMAGE_OUT(0x210C, (y+h-1)<<16 | (x+w-1));
+ IMAGE_OUT(0x2124, 0x80000000 | 7<<18 | 1<<22 | 1<<10 | 1<<9 | clip);
+ if (!pTrident->UsePCIRetry)
+ ImageSyncClip(pScrn);
+}
+
+static void
+ImageSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int rop,
+ unsigned int planemask,
+ int trans_col)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_PATLOC(((patterny * pScrn->displayWidth * pScrn->bitsPerPixel / 8) +
+ (patternx * pScrn->bitsPerPixel / 8)) >> 6);
+ if (trans_col == -1) {
+ REPLICATE(trans_col);
+ TGUI_BCOLOUR(trans_col);
+ TGUI_DRAWFLAG(PAT2SCR | 1<<12);
+ } else
+ TGUI_DRAWFLAG(PAT2SCR);
+ TGUI_FMIX(XAAPatternROP[rop]);
+}
+
+static void
+ImageSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_DEST_XY(x,y);
+ TGUI_DIM_XY(w,h);
+ TGUI_COMMAND(GE_BLT);
+ if (!pTrident->UsePCIRetry)
+ ImageSyncClip(pScrn);
+}
+
+static void ImageSetupForImageWrite(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pTrident->ROP = rop;
+ IMAGE_OUT(0x2120, 0x80000000);
+ IMAGE_OUT(0x2120, 0x90000000 | XAACopyROP[rop]);
+}
+
+static void ImageSubsequentImageWriteRect(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ IMAGE_OUT(0x2108, y<<16 | x);
+ IMAGE_OUT(0x210C, (y+h-1)<<16 | (x+w-1));
+ IMAGE_OUT(0x2124, 0x80000000 | 1<<22 | ((pTrident->ROP == GXcopy) ? 0 : 1<<10));
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/trident.h b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident.h
new file mode 100644
index 000000000..d4ec579a5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright 1998 by Alan Hourihane <alanh@fairlite.demon.co.uk>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident.h,v 1.14 1999/07/18 03:27:00 dawes Exp $ */
+
+#ifndef _TRIDENT_H_
+#define _TRIDENT_H_
+
+#include "xf86Cursor.h"
+#include "xaa.h"
+#include "xf86RamDac.h"
+#include "compiler.h"
+#include "vgaHW.h"
+#include "xf86i2c.h"
+
+typedef struct {
+ unsigned char tridentRegs3x4[0x100];
+ unsigned char tridentRegs3CE[0x100];
+ unsigned char tridentRegs3C4[0x100];
+ unsigned char tridentRegsDAC[0x01];
+ unsigned char tridentRegsClock[0x03];
+ unsigned char DacRegs[0x300];
+} TRIDENTRegRec, *TRIDENTRegPtr;
+
+#define TRIDENTPTR(p) ((TRIDENTPtr)((p)->driverPrivate))
+
+typedef struct {
+ ScrnInfoPtr pScrn;
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ EntityInfoPtr pEnt;
+ int Chipset;
+ int DACtype;
+ int RamDac;
+ int ChipRev;
+ int HwBpp;
+ int BppShift;
+ CARD32 IOAddress;
+ CARD32 FbAddress;
+ unsigned char * IOBase;
+#ifdef __alpha__
+ unsigned char * IOBaseDense;
+#endif
+ unsigned char * FbBase;
+ long FbMapSize;
+ Bool NoAccel;
+ Bool HWCursor;
+ Bool UsePCIRetry;
+ Bool UseGERetry;
+ Bool NewClockCode;
+ Bool IsCyber;
+ Bool Clipping;
+ Bool DstEnable;
+ Bool ROP;
+ Bool HasSGRAM;
+ Bool MUX;
+ float frequency;
+ unsigned char REGPCIReg;
+ unsigned char REGNewMode1;
+ int MinClock;
+ int MaxClock;
+ int MUXThreshold;
+ int MCLK;
+ int bytes;
+ TRIDENTRegRec SavedReg;
+ TRIDENTRegRec ModeReg;
+ I2CBusPtr DDC;
+ CARD16 EngineOperation;
+ CARD32 AccelFlags;
+ CARD32 BltScanDirection;
+ CARD16 LinePattern;
+ RamDacRecPtr RamDacRec;
+ xf86CursorInfoPtr CursorInfoRec;
+ XAAInfoRecPtr AccelInfoRec;
+ CloseScreenProcPtr CloseScreen;
+ unsigned int (*ddc1Read)(ScrnInfoPtr);
+ unsigned char * XAAScanlineColorExpandBuffers[1];
+} TRIDENTRec, *TRIDENTPtr;
+
+/* Prototypes */
+
+unsigned int Tridentddc1Read(ScrnInfoPtr pScrn);
+void TridentRestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg);
+void TridentSave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg);
+Bool TridentInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+Bool TridentAccelInit(ScreenPtr pScreen);
+Bool ImageAccelInit(ScreenPtr pScreen);
+Bool BladeAccelInit(ScreenPtr pScreen);
+Bool TridentHWCursorInit(ScreenPtr pScreen);
+void TGUISetClock(ScrnInfoPtr pScrn, int clock, unsigned char *a, unsigned char *b);
+void TGUISetMCLK(ScrnInfoPtr pScrn, int clock, unsigned char *a, unsigned char *b);
+void TridentOutIndReg(ScrnInfoPtr pScrn,
+ CARD32 reg, unsigned char mask, unsigned char data);
+unsigned char TridentInIndReg(ScrnInfoPtr pScrn, CARD32 reg);
+void TridentWriteAddress(ScrnInfoPtr pScrn, CARD32 index);
+void TridentReadAddress(ScrnInfoPtr pScrn, CARD32 index);
+void TridentWriteData(ScrnInfoPtr pScrn, unsigned char data);
+unsigned char TridentReadData(ScrnInfoPtr pScrn);
+void TridentLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, LOCO *colors, VisualPtr pVisual);
+void TGUISetRead(int bank);
+void TGUISetWrite(int bank);
+void TGUISetReadWrite(int bank);
+
+float CalculateMCLK(ScrnInfoPtr pScrn);
+
+/*
+ * Trident Chipset Definitions
+ */
+
+#define TVGA8200LX 0
+#define TVGA8800CS 1
+#define TVGA8900B 2
+#define TVGA8900C 3
+#define TVGA8900CL 4
+#define TVGA8900D 5
+#define TVGA9000 6
+#define TVGA9000i 7
+#define TVGA9100B 8
+#define TVGA9200CXr 9
+#define TGUI9400CXi 10
+#define TGUI9420 11
+#define TGUI9420DGi 12
+#define TGUI9430DGi 13
+#define TGUI9440AGi 14
+#define CYBER9320 15
+#define TGUI96xx 16 /* Backwards compatibility */
+#define TGUI9660 16
+#define TGUI9680 17
+#define PROVIDIA9682 18
+#define PROVIDIA9685 19
+#define CYBER9382 20
+#define CYBER9385 21
+#define CYBER9388 22
+#define CYBER9397 23
+#define CYBER9520 24
+#define IMAGE975 25
+#define IMAGE985 26
+#define CYBER939A 27
+#define CYBER9525 28
+#define BLADE3D 29
+#define CYBERBLADEI7 30
+#define CYBERBLADEI7D 31
+#define CYBERBLADEI1 32
+
+#define HAS_DST_TRANS (pTrident->Chipset == PROVIDIA9682)
+
+#define Is3Dchip ((pTrident->Chipset == CYBER9388) || \
+ (pTrident->Chipset == CYBER9397) || \
+ (pTrident->Chipset == CYBER939A) || \
+ (pTrident->Chipset == CYBER9520) || \
+ (pTrident->Chipset == CYBER9525) || \
+ (pTrident->Chipset == IMAGE975) || \
+ (pTrident->Chipset == IMAGE985) || \
+ (pTrident->Chipset == CYBERBLADEI7) || \
+ (pTrident->Chipset == CYBERBLADEI7D) || \
+ (pTrident->Chipset == CYBERBLADEI1) || \
+ (pTrident->Chipset == BLADE3D))
+
+/*
+ * Trident DAC's
+ */
+
+#define TKD8001 0
+#define TGUIDAC 1
+
+#endif /* _TRIDENT_H_ */
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_accel.c
new file mode 100644
index 000000000..3044e5445
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_accel.c
@@ -0,0 +1,692 @@
+/*
+ * Copyright 1997,1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Trident accelerated options.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_accel.c,v 1.7 1999/06/20 07:14:34 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "miline.h"
+
+#include "trident_regs.h"
+#include "trident.h"
+
+#include "xaalocal.h"
+#include "xaarop.h"
+
+static void TridentSync(ScrnInfoPtr pScrn);
+static void TridentSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void Trident9685SetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void TridentSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e,
+ int len, int octant);
+static void TridentSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void Trident9685SetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask);
+static void TridentSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h);
+static void TridentSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2,
+ int y2, int w, int h);
+static void TridentSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask,
+ int transparency_color);
+static void TridentSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void TridentSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int srcx, int srcy,
+ int offset);
+static void TridentSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+static void TridentSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft);
+static void TridentSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2);
+static void TridentDisableClipping(ScrnInfoPtr pScrn);
+static void TridentWritePixmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int rop,
+ unsigned int planemask, int transparency_color,
+ int bpp, int depth);
+static void TridentSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int fg, int bg,
+ int rop, unsigned int planemask);
+static void TridentSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+static void TridentSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int rop, unsigned int planemask, int trans_col);
+static void TridentSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny, int x, int y,
+ int w, int h);
+
+static void
+TridentInitializeAccelerator(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ CHECKCLIPPING;
+ if (pTrident->Chipset == PROVIDIA9682)
+ pTrident->EngineOperation |= 0x100; /* Disable Clipping */
+ TGUI_OPERMODE(pTrident->EngineOperation);
+}
+
+Bool
+TridentAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ BoxRec AvailFBArea;
+
+ pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if (!infoPtr) return FALSE;
+
+ TridentInitializeAccelerator(pScrn);
+
+ infoPtr->Flags = PIXMAP_CACHE |
+ OFFSCREEN_PIXMAPS |
+ LINEAR_FRAMEBUFFER;
+
+ infoPtr->Sync = TridentSync;
+
+ if (pTrident->Chipset >= TGUI9660) {
+ infoPtr->SetClippingRectangle = TridentSetClippingRectangle;
+ infoPtr->DisableClipping = TridentDisableClipping;
+ infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_FILL |
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
+ HARDWARE_CLIP_MONO_8x8_FILL;
+ }
+
+#if 0 /* Lines are slower than cfb/mi */
+ infoPtr->SolidLineFlags = NO_PLANEMASK;
+ if (pTrident->Chipset == PROVIDIA9685)
+ infoPtr->SetupForSolidLine = Trident9685SetupForSolidLine;
+ else
+ infoPtr->SetupForSolidLine = TridentSetupForSolidLine;
+
+ infoPtr->SolidBresenhamLineErrorTermBits = 11;
+ infoPtr->SubsequentSolidBresenhamLine = TridentSubsequentSolidBresenhamLine;
+#endif
+
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ if (pTrident->Chipset == PROVIDIA9685)
+ infoPtr->SetupForSolidFill = Trident9685SetupForFillRectSolid;
+ else
+ infoPtr->SetupForSolidFill = TridentSetupForFillRectSolid;
+ infoPtr->SubsequentSolidFillRect = TridentSubsequentFillRectSolid;
+
+ infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK;
+
+ if (!HAS_DST_TRANS) infoPtr->ScreenToScreenCopyFlags |= NO_TRANSPARENCY;
+
+ infoPtr->SetupForScreenToScreenCopy =
+ TridentSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy =
+ TridentSubsequentScreenToScreenCopy;
+
+ infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
+ NO_TRANSPARENCY |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ infoPtr->SetupForMono8x8PatternFill =
+ TridentSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ TridentSubsequentMono8x8PatternFillRect;
+ infoPtr->MonoPatternPitch = 64;
+
+#if 0
+ infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK |
+ HARDWARE_PATTERN_SCREEN_ORIGIN |
+ NO_TRANSPARENCY |
+ BIT_ORDER_IN_BYTE_MSBFIRST;
+
+ infoPtr->SetupForColor8x8PatternFill =
+ TridentSetupForColor8x8PatternFill;
+ infoPtr->SubsequentColor8x8PatternFillRect =
+ TridentSubsequentColor8x8PatternFillRect;
+#endif
+
+#if 0
+ infoPtr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK |
+ NO_TRANSPARENCY;
+
+ infoPtr->SetupForScreenToScreenColorExpandFill =
+ TridentSetupForScreenToScreenColorExpand;
+ infoPtr->SubsequentScreenToScreenColorExpandFill =
+ TridentSubsequentScreenToScreenColorExpand;
+#endif
+
+ if (pTrident->Chipset == PROVIDIA9685) {
+ infoPtr->CPUToScreenColorExpandFillFlags = CPU_TRANSFER_PAD_DWORD |
+ LEFT_EDGE_CLIPPING |
+ LEFT_EDGE_CLIPPING_NEGATIVE_X |
+ SYNC_AFTER_COLOR_EXPAND |
+ BIT_ORDER_IN_BYTE_MSBFIRST |
+ SCANLINE_PAD_DWORD |
+ NO_TRANSPARENCY |
+ NO_PLANEMASK;
+ infoPtr->ColorExpandRange = pScrn->displayWidth * pScrn->bitsPerPixel/8;
+ infoPtr->ColorExpandBase = pTrident->FbBase;
+ infoPtr->SetupForCPUToScreenColorExpandFill =
+ TridentSetupForCPUToScreenColorExpand;
+ infoPtr->SubsequentCPUToScreenColorExpandFill =
+ TridentSubsequentCPUToScreenColorExpand;
+ }
+
+ /* Requires clipping, therefore only 9660's or above */
+ if (pTrident->Chipset >= TGUI9660) {
+ infoPtr->WritePixmap = TridentWritePixmap;
+ infoPtr->WritePixmapFlags = NO_PLANEMASK;
+
+ if (!HAS_DST_TRANS) infoPtr->WritePixmapFlags |= NO_TRANSPARENCY;
+ }
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = (pTrident->FbMapSize - 4096) / (pScrn->displayWidth *
+ pScrn->bitsPerPixel / 8);
+
+ if (AvailFBArea.y2 > 2048) AvailFBArea.y2 = 2047;
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ return(XAAInit(pScreen, infoPtr));
+}
+
+static void
+TridentSync(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int count = 0, timeout = 0;
+ int busy;
+
+ infoRec->NeedToSync = FALSE;
+
+ for (;;) {
+ BLTBUSY(busy);
+ if (busy != GE_BUSY) {
+ return;
+ }
+ count++;
+ if (count == 10000000) {
+ ErrorF("Trident: BitBLT engine time-out.\n");
+ count = 9990000;
+ timeout++;
+ if (timeout == 8) {
+ /* Reset BitBLT Engine */
+ TGUI_STATUS(0x00);
+ return;
+ }
+ }
+ }
+}
+
+static void
+TridentSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int transparency_color)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int dst = 0;
+
+ pTrident->BltScanDirection = 0;
+ if (xdir < 0) pTrident->BltScanDirection |= XNEG;
+ if (ydir < 0) pTrident->BltScanDirection |= YNEG;
+
+ if (transparency_color != -1) {
+ pTrident->DstEnable = TRUE;
+ if (pTrident->Chipset == PROVIDIA9685) {
+ dst = 3<<16;
+ } else {
+ TGUI_OPERMODE(pTrident->EngineOperation | DST_ENABLE);
+ }
+ REPLICATE(transparency_color);
+ TGUI_CKEY(transparency_color);
+ }
+
+ if ((pTrident->Chipset == PROVIDIA9682 ||
+ pTrident->Chipset == TGUI9680) && rop == GXcopy)
+ dst = FASTMODE;
+
+ if (pTrident->Chipset == PROVIDIA9685 && rop == GXcopy) dst |= 1<<21;
+
+ TGUI_DRAWFLAG(pTrident->BltScanDirection | SCR2SCR | dst);
+ TGUI_FMIX(XAACopyROP[rop]);
+}
+
+static void
+TridentSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (pTrident->BltScanDirection & YNEG) {
+ y1 = y1 + h - 1;
+ y2 = y2 + h - 1;
+ }
+ if (pTrident->BltScanDirection & XNEG) {
+ x1 = x1 + w - 1;
+ x2 = x2 + w - 1;
+ }
+ TGUI_SRC_XY(x1,y1);
+ TGUI_DEST_XY(x2,y2);
+ TGUI_DIM_XY(w,h);
+ TGUI_COMMAND(GE_BLT);
+ if (!pTrident->UseGERetry)
+ TridentSync(pScrn);
+ if (pTrident->DstEnable) {
+ if (pTrident->Chipset != PROVIDIA9685) {
+ TGUI_OPERMODE(pTrident->EngineOperation);
+ }
+ pTrident->DstEnable = FALSE;
+ }
+}
+
+static void
+TridentSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_SRCCLIP_XY(x1, y1);
+ TGUI_DSTCLIP_XY(x2, y2);
+ pTrident->Clipping = TRUE;
+}
+
+static void
+TridentDisableClipping(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ CHECKCLIPPING;
+}
+
+static void
+TridentSetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ REPLICATE(color);
+ TGUI_FCOLOUR(color);
+ TGUI_BCOLOUR(color);
+ TGUI_FMIX(XAAPatternROP[rop]);
+}
+
+static void
+Trident9685SetupForSolidLine(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pTrident->ROP = rop;
+ REPLICATE(color);
+ TGUI_FPATCOL(color);
+ TGUI_BPATCOL(color);
+ TGUI_FMIX(XAAPatternROP[rop]);
+}
+
+static void
+TridentSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn,
+ int x, int y, int dmaj, int dmin, int e, int len, int octant)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ pTrident->BltScanDirection = 0;
+ if (octant & YMAJOR) pTrident->BltScanDirection |= YMAJ;
+ if (octant & XDECREASING) pTrident->BltScanDirection |= XNEG;
+ if (octant & YDECREASING) pTrident->BltScanDirection |= YNEG;
+ if ((pTrident->Chipset == PROVIDIA9682 ||
+ pTrident->Chipset == TGUI9680) && pTrident->ROP == GXcopy)
+ pTrident->BltScanDirection |= FASTMODE | 1<<11;
+ if (pTrident->Chipset == PROVIDIA9685 && pTrident->ROP == GXcopy)
+ pTrident->BltScanDirection |= 1<<21;
+ TGUI_DRAWFLAG(SOLIDFILL | STENCIL | pTrident->BltScanDirection);
+ TGUI_SRC_XY(dmin-dmaj,dmin);
+ TGUI_DEST_XY(x,y);
+ TGUI_DIM_XY(dmin+e,len);
+ TGUI_COMMAND(GE_BRESLINE);
+ if (!pTrident->UseGERetry)
+ TridentSync(pScrn);
+}
+
+static void
+TridentSetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int drawflag = 0;
+
+ REPLICATE(color);
+ TGUI_FCOLOUR(color);
+ TGUI_BCOLOUR(color);
+ TGUI_FMIX(XAAPatternROP[rop]);
+ if ((pTrident->Chipset == PROVIDIA9682 ||
+ pTrident->Chipset == TGUI9680) && rop == GXcopy) drawflag = FASTMODE;
+ if (pTrident->Chipset == PROVIDIA9685 && rop == GXcopy) drawflag |= 1<<21;
+ TGUI_DRAWFLAG(SOLIDFILL | PATMONO | drawflag);
+}
+
+static void
+Trident9685SetupForFillRectSolid(ScrnInfoPtr pScrn, int color,
+ int rop, unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ REPLICATE(color);
+ TGUI_FPATCOL(color);
+ TGUI_BPATCOL(color);
+ TGUI_FMIX(XAAPatternROP[rop]);
+ TGUI_DRAWFLAG(SOLIDFILL | PATMONO);
+}
+
+static void
+TridentSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_DIM_XY(w,h);
+ TGUI_DEST_XY(x,y);
+ TGUI_COMMAND(GE_BLT);
+ if (!pTrident->UseGERetry)
+ TridentSync(pScrn);
+}
+
+static void
+TridentSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ REPLICATE(fg);
+ REPLICATE(bg);
+ TGUI_FCOLOUR(fg);
+ TGUI_BCOLOUR(bg);
+
+ TGUI_DRAWFLAG(SRCMONO | SCR2SCR);
+ TGUI_FMIX(XAACopyROP[rop]);
+}
+
+static void
+TridentSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int srcx, int srcy, int offset)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_OUTL(0x44, (offset << 28) | ((srcy * pScrn->displayWidth + srcx) * pScrn->bitsPerPixel * 8));
+ TGUI_SRC_XY(srcx,srcy);
+ TGUI_DEST_XY(x,y);
+ TGUI_DIM_XY(w,h);
+ TGUI_COMMAND(GE_BLT);
+ if (!pTrident->UseGERetry)
+ TridentSync(pScrn);
+}
+
+static void
+TridentSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int drawflag = 0;
+
+ if (bg != -1)
+ drawflag |= SRCMONO;
+ else
+ drawflag |= SRCMONO | 1<<12;
+
+ if (pTrident->Chipset == PROVIDIA9685)
+ drawflag |= 1<<30;
+
+ REPLICATE(fg);
+ REPLICATE(bg);
+ TGUI_FCOLOUR(fg);
+ TGUI_BCOLOUR(bg);
+ TGUI_SRC_XY(0,0);
+ TGUI_DRAWFLAG(drawflag);
+ TGUI_FMIX(XAACopyROP[rop]);
+}
+
+static void
+TridentSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int bpp = pScrn->bitsPerPixel >> 3;
+
+ if (skipleft) {
+ TridentSetClippingRectangle(pScrn,((x+skipleft)*bpp),y,
+ ((w+x)*bpp)-1,y+h-1);
+ if (pTrident->Chipset == PROVIDIA9682)
+ TGUI_OPERMODE(pTrident->EngineOperation & 0xFEFF);
+ }
+
+ TGUI_DEST_XY(x,y);
+ TGUI_DIM_XY(w,h);
+ TGUI_COMMAND(GE_BLT);
+
+ if (!pTrident->UseGERetry)
+ TridentSync(pScrn);
+
+ if (skipleft) {
+ if (pTrident->Chipset == PROVIDIA9682)
+ TGUI_OPERMODE(pTrident->EngineOperation);
+ }
+}
+
+static void MoveDWORDS(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ *(dest + 2) = *(src + 2);
+ *(dest + 3) = *(src + 3);
+ src += 4;
+ dest += 4;
+ dwords -= 4;
+ }
+ if (!dwords) return;
+ *dest = *src;
+ dest += 1;
+ src += 1;
+ if (dwords == 1) return;
+ *dest = *src;
+ dest += 1;
+ src += 1;
+ if (dwords == 2) return;
+ *dest = *src;
+ dest += 1;
+ src += 1;
+}
+
+static void
+TridentWritePixmap(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int dst = 0;
+
+ TridentSetClippingRectangle(pScrn,(x*(bpp>>3)),y,((w+x)*(bpp>>3))-1,y+h-1);
+
+ if (w & 7)
+ w += 8 - (w & 7);
+
+ if (transparency_color != -1) {
+ pTrident->DstEnable = TRUE;
+ if (pTrident->Chipset == PROVIDIA9685) {
+ dst = 3<<16;
+ } else {
+ TGUI_OPERMODE(pTrident->EngineOperation | DST_ENABLE);
+ }
+ REPLICATE(transparency_color);
+ TGUI_CKEY(transparency_color);
+ }
+ TGUI_SRC_XY(0,0);
+ TGUI_FMIX(XAACopyROP[rop]);
+ TGUI_DEST_XY(x,y);
+ TGUI_DIM_XY(w,h);
+ if (pTrident->Chipset == PROVIDIA9685) {
+ if (rop == GXcopy) dst |= 1<<21;
+ TGUI_DRAWFLAG(1<<30 | dst); /* Enable Clipping */
+ } else {
+ if ((pTrident->Chipset == PROVIDIA9682 ||
+ pTrident->Chipset == TGUI9680) && rop == GXcopy) {
+ TGUI_DRAWFLAG(FASTMODE);
+ } else {
+ TGUI_DRAWFLAG(0);
+ }
+ }
+ if (pTrident->Chipset == PROVIDIA9682)
+ TGUI_OPERMODE(pTrident->EngineOperation & 0xFEFF); /* Enable Clipping */
+ TGUI_COMMAND(GE_BLT);
+
+ if (pScrn->bitsPerPixel == 8)
+ w >>= 2;
+ if (pScrn->bitsPerPixel == 16)
+ w >>= 1;
+
+ while (h--) {
+ MoveDWORDS((CARD32*)pTrident->FbBase,(CARD32*)src,w);
+ src += srcwidth;
+ }
+
+ if (pTrident->UseGERetry)
+ SET_SYNC_FLAG(infoRec);
+ else
+ TridentSync(pScrn);
+
+ if (pTrident->DstEnable) {
+ if (pTrident->Chipset != PROVIDIA9685) {
+ TGUI_OPERMODE(pTrident->EngineOperation);
+ }
+ pTrident->DstEnable = FALSE;
+ }
+ if (pTrident->Chipset == PROVIDIA9682)
+ TGUI_OPERMODE(pTrident->EngineOperation);
+}
+
+static void
+TridentSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int drawflag = 0;
+
+ REPLICATE(bg);
+ REPLICATE(fg);
+ if (pTrident->Chipset == PROVIDIA9685) {
+ drawflag |= 7<<18;
+ TGUI_BPATCOL(bg);
+ TGUI_FPATCOL(fg);
+ if (rop == GXcopy) drawflag |= 1<<21;
+ } else {
+ TGUI_BCOLOUR(bg);
+ TGUI_FCOLOUR(fg);
+ if ((pTrident->Chipset == PROVIDIA9682 ||
+ pTrident->Chipset == TGUI9680) && rop == GXcopy)
+ drawflag |= FASTMODE;
+ }
+ TGUI_DRAWFLAG(PAT2SCR | PATMONO | drawflag);
+ TGUI_PATLOC(((patterny * pScrn->displayWidth * pScrn->bitsPerPixel / 8) +
+ (patternx * pScrn->bitsPerPixel / 8)) >> 6);
+ TGUI_FMIX(XAAPatternROP[rop]);
+}
+
+static void
+TridentSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_DEST_XY(x,y);
+ TGUI_DIM_XY(w,h);
+ TGUI_COMMAND(GE_BLT);
+ if (!pTrident->UseGERetry)
+ TridentSync(pScrn);
+}
+
+static void
+TridentSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int rop,
+ unsigned int planemask,
+ int trans_col)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_PATLOC(((patterny * pScrn->displayWidth * pScrn->bitsPerPixel / 8) +
+ (patternx * pScrn->bitsPerPixel / 8)) >> 6);
+ if (trans_col == -1) {
+ REPLICATE(trans_col);
+ TGUI_BCOLOUR(trans_col);
+ TGUI_DRAWFLAG(PAT2SCR | 1<<12);
+ } else
+ TGUI_DRAWFLAG(PAT2SCR);
+ TGUI_FMIX(XAAPatternROP[rop]);
+}
+
+static void
+TridentSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y,
+ int w, int h)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ TGUI_DEST_XY(x,y);
+ TGUI_DIM_XY(w,h);
+ TGUI_COMMAND(GE_BLT);
+ if (!pTrident->UseGERetry)
+ TridentSync(pScrn);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_bank.c b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_bank.c
new file mode 100644
index 000000000..0c935c1ca
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_bank.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright 1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_bank.c,v 1.2 1999/04/25 10:02:28 dawes Exp $ */
+
+#include "trident_regs.h"
+
+void TVGA8900SetRead(int bank)
+{
+ MMIO_OUTW(0x3c4, (((bank & 0xff) ^ 0x02)<<8)|0x0E);
+}
+void TGUISetRead(int bank)
+{
+ MMIO_OUTB(0x3d9, bank & 0xff);
+}
+void TVGA8900SetWrite(int bank)
+{
+ MMIO_OUTW(0x3c4, (((bank & 0xff) ^ 0x02)<<8)|0x0E);
+}
+void TGUISetWrite(int bank)
+{
+ MMIO_OUTB(0x3d8, bank & 0xff);
+}
+void TVGA8900SetReadWrite(int bank)
+{
+ MMIO_OUTW(0x3c4, (((bank & 0xff) ^ 0x02)<<8)|0x0E);
+}
+void TGUISetReadWrite(int bank)
+{
+ MMIO_OUTW(0x3d8, (bank & 0xff)<< 8 | bank & 0xff);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c
new file mode 100644
index 000000000..1191a8cbb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c
@@ -0,0 +1,463 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_dac.c,v 1.12 1999/07/18 03:27:00 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Version.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "vgaHW.h"
+
+#include "trident.h"
+#include "trident_regs.h"
+
+Bool
+TridentInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ TRIDENTRegPtr pReg = &pTrident->ModeReg;
+ int vgaIOBase;
+ int offset = 0;
+ int clock = mode->Clock;
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ pReg->tridentRegs3x4[PixelBusReg] = 0x00;
+ pReg->tridentRegsDAC[0x00] = 0x00;
+ MMIO_OUTB(vgaIOBase + 4, NewMode2);
+ pReg->tridentRegs3C4[NewMode2] = 0x20;
+ MMIO_OUTB(0x3CE, MiscExtFunc);
+ pReg->tridentRegs3CE[MiscExtFunc] = MMIO_INB(0x3CF);
+ pReg->tridentRegs3x4[GraphEngReg] = 0x00;
+
+ /* Enable Chipset specific options */
+ switch (pTrident->Chipset) {
+ case CYBERBLADEI7:
+ case CYBERBLADEI7D:
+ case CYBERBLADEI1:
+ case BLADE3D:
+ case CYBER9520:
+ case CYBER9397:
+ case CYBER939A:
+ case CYBER9525:
+ case IMAGE975:
+ case IMAGE985:
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x10;
+ /* Fall Through */
+ case PROVIDIA9685:
+ if (pTrident->UsePCIRetry) {
+ pTrident->UseGERetry = TRUE;
+ pReg->tridentRegs3x4[Enhancement0] = 0x50;
+ } else {
+ pTrident->UseGERetry = FALSE;
+ pReg->tridentRegs3x4[Enhancement0] = 0x00;
+ }
+ /* Fall Through */
+ case TGUI9660:
+ case TGUI9680:
+ case PROVIDIA9682:
+ if (pTrident->MUX && pScrn->bitsPerPixel == 8 && mode->CrtcHAdjusted) {
+ pReg->tridentRegs3x4[PixelBusReg] |= 0x01; /* 16bit bus */
+ pReg->tridentRegs3C4[NewMode2] |= 0x02; /* half clock */
+ pReg->tridentRegsDAC[0x00] |= 0x20; /* mux mode */
+ }
+ break;
+ }
+
+ /* Defaults for all trident chipsets follows */
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ case 4:
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x04;
+ offset = pScrn->displayWidth >> 3;
+ break;
+ case 8:
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
+ offset = pScrn->displayWidth >> 3;
+ break;
+ case 16:
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
+ offset = pScrn->displayWidth >> 2;
+ if (pScrn->depth == 15)
+ pReg->tridentRegsDAC[0x00] = 0x10;
+ else
+ pReg->tridentRegsDAC[0x00] = 0x30;
+ pReg->tridentRegs3x4[PixelBusReg] = 0x04;
+ if (pTrident->Chipset > CYBER9320)
+ pReg->tridentRegs3x4[PixelBusReg] |= 0x01;
+ break;
+ case 24:
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
+ offset = (pScrn->displayWidth * 3) >> 3;
+ pReg->tridentRegs3x4[PixelBusReg] = 0x29;
+ pReg->tridentRegsDAC[0x00] = 0xD0;
+ break;
+ case 32:
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x02;
+ pReg->tridentRegs3CE[MiscExtFunc] |= 0x08; /* Clock Division by 2*/
+ clock *= 2; /* Double the clock */
+ offset = pScrn->displayWidth >> 1;
+ pReg->tridentRegs3x4[PixelBusReg] = 0x09;
+ pReg->tridentRegsDAC[0x00] = 0xD0;
+ break;
+ }
+ pReg->tridentRegs3x4[Offset] = offset & 0xFF;
+
+ {
+ CARD8 a, b;
+
+ TGUISetClock(pScrn, clock, &a, &b);
+ pReg->tridentRegsClock[0x00] = (MMIO_INB(0x3CC) & 0xF3) | 0x08;
+ pReg->tridentRegsClock[0x01] = a;
+ pReg->tridentRegsClock[0x02] = b;
+ if (pTrident->MCLK > 0) {
+ TGUISetMCLK(pScrn, pTrident->MCLK, &a, &b);
+ pReg->tridentRegsClock[0x03] = a;
+ pReg->tridentRegsClock[0x04] = b;
+ }
+ }
+
+ pReg->tridentRegs3C4[NewMode1] = 0xC0;
+
+ pReg->tridentRegs3x4[LinearAddReg] = ((pTrident->FbAddress >> 24) << 6) |
+ ((pTrident->FbAddress >> 20) & 0x0F)|
+ 0x20;
+ pReg->tridentRegs3x4[CRTHiOrd] = (((mode->CrtcVBlankEnd-1) & 0x400) >> 4) |
+ (((mode->CrtcVTotal - 2) & 0x400) >> 3) |
+ ((mode->CrtcVSyncStart & 0x400) >> 5) |
+ (((mode->CrtcVDisplay - 1) & 0x400) >> 6) |
+ 0x08;
+ pReg->tridentRegs3x4[CRTCModuleTest] = (mode->Flags & V_INTERLACE ? 0x84 : 0x80);
+ MMIO_OUTB(vgaIOBase+ 4, InterfaceSel);
+ pReg->tridentRegs3x4[InterfaceSel] = MMIO_INB(vgaIOBase + 5) | 0x40;
+ MMIO_OUTB(vgaIOBase+ 4, Performance);
+ pReg->tridentRegs3x4[Performance] = MMIO_INB(vgaIOBase + 5) | 0x10;
+ MMIO_OUTB(vgaIOBase+ 4, DRAMControl);
+ pReg->tridentRegs3x4[DRAMControl] = MMIO_INB(vgaIOBase + 5) | 0x10;
+ MMIO_OUTB(vgaIOBase+ 4, AddColReg);
+ pReg->tridentRegs3x4[AddColReg] = (MMIO_INB(vgaIOBase + 5) & 0xCF) |
+ ((offset & 0x300) >> 4);
+
+ if (!pTrident->NoAccel)
+ pReg->tridentRegs3x4[GraphEngReg] |= 0x80;
+
+ MMIO_OUTB(0x3CE, MiscIntContReg);
+ pReg->tridentRegs3CE[MiscIntContReg] = MMIO_INB(0x3CF) | 0x04;
+
+ MMIO_OUTB(vgaIOBase+ 4, PCIReg);
+ pReg->tridentRegs3x4[PCIReg] = MMIO_INB(vgaIOBase + 5) & 0xF9;
+ /* Enable PCI Bursting on capable chips */
+ if (pTrident->Chipset >= TGUI96xx) pReg->tridentRegs3x4[PCIReg] |= 0x06;
+
+ return(TRUE);
+}
+
+void
+TridentRestore(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ CARD8 temp;
+ int vgaIOBase;
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ /* Goto New Mode */
+ MMIO_OUTB(0x3C4, 0x0B);
+ temp = MMIO_INB(0x3C5);
+
+ /* Unprotect registers */
+ MMIO_OUTW(0x3C4, ((0xC0 ^ 0x02) << 8) | NewMode1);
+
+ temp = MMIO_INB(0x3C8);
+ temp = MMIO_INB(0x3C6);
+ temp = MMIO_INB(0x3C6);
+ temp = MMIO_INB(0x3C6);
+ temp = MMIO_INB(0x3C6);
+ MMIO_OUTB(0x3C6, tridentReg->tridentRegsDAC[0x00]);
+ temp = MMIO_INB(0x3C8);
+
+ MMIO_OUTW_3x4(CursorControl);
+ MMIO_OUTW_3x4(CRTCModuleTest);
+ MMIO_OUTW_3x4(LinearAddReg);
+ MMIO_OUTW_3C4(NewMode2);
+ MMIO_OUTW_3x4(CRTHiOrd);
+ MMIO_OUTW_3x4(AddColReg);
+ MMIO_OUTW_3CE(MiscExtFunc);
+ MMIO_OUTW_3x4(GraphEngReg);
+ MMIO_OUTW_3x4(Performance);
+ MMIO_OUTW_3x4(InterfaceSel);
+ MMIO_OUTW_3x4(DRAMControl);
+ MMIO_OUTW_3x4(PixelBusReg);
+ MMIO_OUTW_3CE(MiscIntContReg);
+ MMIO_OUTW_3x4(Offset);
+ MMIO_OUTW_3x4(PCIReg);
+ if (pTrident->Chipset >= PROVIDIA9685) MMIO_OUTW_3x4(Enhancement0);
+
+ if (Is3Dchip) {
+ MMIO_OUTW(0x3C4, (tridentReg->tridentRegsClock[0x01])<<8 | ClockLow);
+ MMIO_OUTW(0x3C4, (tridentReg->tridentRegsClock[0x02])<<8 | ClockHigh);
+ if (pTrident->MCLK > 0) {
+ MMIO_OUTW(0x3C4,(tridentReg->tridentRegsClock[0x03])<<8 | MCLKLow);
+ MMIO_OUTW(0x3C4,(tridentReg->tridentRegsClock[0x04])<<8 | MCLKHigh);
+ }
+ } else {
+ MMIO_OUTB(0x43C8, tridentReg->tridentRegsClock[0x01]);
+ MMIO_OUTB(0x43C9, tridentReg->tridentRegsClock[0x02]);
+ if (pTrident->MCLK > 0) {
+ MMIO_OUTB(0x43C6, tridentReg->tridentRegsClock[0x03]);
+ MMIO_OUTB(0x43C7, tridentReg->tridentRegsClock[0x04]);
+ }
+ }
+ MMIO_OUTB(0x3C2, tridentReg->tridentRegsClock[0x00]);
+
+ MMIO_OUTW(0x3C4, ((tridentReg->tridentRegs3C4[NewMode1] ^ 0x02) << 8) | NewMode1);
+}
+
+void
+TridentSave(ScrnInfoPtr pScrn, TRIDENTRegPtr tridentReg)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ CARD8 temp;
+ int vgaIOBase;
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ MMIO_OUTB(vgaIOBase + 4, Offset);
+
+ tridentReg->tridentRegs3x4[Offset] = MMIO_INB(vgaIOBase + 5);
+
+ /* Goto New Mode */
+ MMIO_OUTB(0x3C4, 0x0B);
+ temp = MMIO_INB(0x3C5);
+
+ MMIO_INB_3C4(NewMode1);
+
+ /* Unprotect registers */
+ MMIO_OUTW(0x3C4, ((0xC0 ^ 0x02) << 8) | NewMode1);
+
+ MMIO_INB_3x4(LinearAddReg);
+ MMIO_INB_3x4(CRTCModuleTest);
+ MMIO_INB_3x4(CRTHiOrd);
+ MMIO_INB_3x4(Performance);
+ MMIO_INB_3x4(InterfaceSel);
+ MMIO_INB_3x4(DRAMControl);
+ MMIO_INB_3x4(AddColReg);
+ MMIO_INB_3x4(PixelBusReg);
+ MMIO_INB_3x4(GraphEngReg);
+ if (pTrident->Chipset >= PROVIDIA9685) MMIO_INB_3x4(Enhancement0);
+ MMIO_INB_3x4(PCIReg);
+
+ /* save cursor registers */
+ MMIO_INB_3x4(CursorControl);
+
+ MMIO_INB_3CE(MiscExtFunc);
+ MMIO_INB_3CE(MiscIntContReg);
+
+ temp = MMIO_INB(0x3C8);
+ temp = MMIO_INB(0x3C6);
+ temp = MMIO_INB(0x3C6);
+ temp = MMIO_INB(0x3C6);
+ temp = MMIO_INB(0x3C6);
+ tridentReg->tridentRegsDAC[0x00] = MMIO_INB(0x3C6);
+ temp = MMIO_INB(0x3C8);
+
+ tridentReg->tridentRegsClock[0x00] = MMIO_INB(0x3CC);
+ if (Is3Dchip) {
+ MMIO_OUTB(0x3C4, ClockLow);
+ tridentReg->tridentRegsClock[0x01] = MMIO_INB(0x3C5);
+ MMIO_OUTB(0x3C4, ClockHigh);
+ tridentReg->tridentRegsClock[0x02] = MMIO_INB(0x3C5);
+ if (pTrident->MCLK > 0) {
+ MMIO_OUTB(0x3C4, MCLKLow);
+ tridentReg->tridentRegsClock[0x03] = MMIO_INB(0x3C5);
+ MMIO_OUTB(0x3C4, MCLKHigh);
+ tridentReg->tridentRegsClock[0x04] = MMIO_INB(0x3C5);
+ }
+ } else {
+ tridentReg->tridentRegsClock[0x01] = MMIO_INB(0x43C8);
+ tridentReg->tridentRegsClock[0x02] = MMIO_INB(0x43C9);
+ if (pTrident->MCLK > 0) {
+ tridentReg->tridentRegsClock[0x03] = MMIO_INB(0x43C6);
+ tridentReg->tridentRegsClock[0x04] = MMIO_INB(0x43C7);
+ }
+ }
+ MMIO_INB_3C4(NewMode2);
+
+ /* Protect registers */
+ MMIO_OUTW_3C4(NewMode1);
+}
+
+static void
+TridentShowCursor(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int vgaIOBase;
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ /* 64x64 */
+ MMIO_OUTW(vgaIOBase + 4, 0xC150);
+}
+
+static void
+TridentHideCursor(ScrnInfoPtr pScrn) {
+ int vgaIOBase;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ MMIO_OUTW(vgaIOBase + 4, 0x4150);
+}
+
+static void
+TridentSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ int vgaIOBase;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ if (x < 0) {
+ MMIO_OUTW(vgaIOBase + 4, (-x)<<8 | 0x46);
+ x = 0;
+ } else
+ MMIO_OUTW(vgaIOBase + 4, 0x0046);
+
+ if (y < 0) {
+ MMIO_OUTW(vgaIOBase + 4, (-y)<<8 | 0x47);
+ y = 0;
+ } else
+ MMIO_OUTW(vgaIOBase + 4, 0x0047);
+
+ MMIO_OUTW(vgaIOBase + 4, (x&0xFF)<<8 | 0x40);
+ MMIO_OUTW(vgaIOBase + 4, (x&0x0F00) | 0x41);
+ MMIO_OUTW(vgaIOBase + 4, (y&0xFF)<<8 | 0x42);
+ MMIO_OUTW(vgaIOBase + 4, (y&0x0F00) | 0x43);
+}
+
+static void
+TridentSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ int vgaIOBase;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ MMIO_OUTW(vgaIOBase + 4, (fg & 0x000000FF)<<8 | 0x48);
+ MMIO_OUTW(vgaIOBase + 4, (fg & 0x0000FF00) | 0x49);
+ MMIO_OUTW(vgaIOBase + 4, (fg & 0x00FF0000)>>8 | 0x4A);
+ MMIO_OUTW(vgaIOBase + 4, (fg & 0xFF000000)>>16 | 0x4B);
+ MMIO_OUTW(vgaIOBase + 4, (bg & 0x000000FF)<<8 | 0x4C);
+ MMIO_OUTW(vgaIOBase + 4, (bg & 0x0000FF00) | 0x4D);
+ MMIO_OUTW(vgaIOBase + 4, (bg & 0x00FF0000)>>8 | 0x4E);
+ MMIO_OUTW(vgaIOBase + 4, (bg & 0xFF000000)>>16 | 0x4F);
+}
+
+static void
+TridentLoadCursorImage(
+ ScrnInfoPtr pScrn,
+ CARD8 *src
+)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int vgaIOBase;
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ memcpy((CARD8 *)pTrident->FbBase + (pScrn->videoRam * 1024) - 4096,
+ src, pTrident->CursorInfoRec->MaxWidth *
+ pTrident->CursorInfoRec->MaxHeight / 4);
+
+ MMIO_OUTW(vgaIOBase + 4, (((pScrn->videoRam-4) & 0xFF) << 8) | 0x44);
+ MMIO_OUTW(vgaIOBase + 4, ((pScrn->videoRam-4) & 0xFF00) | 0x45);
+}
+
+static Bool
+TridentUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (pTrident->MUX && pScrn->bitsPerPixel == 8) return FALSE;
+
+ return TRUE;
+}
+
+Bool
+TridentHWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+ int memory = pScrn->displayWidth * pScrn->virtualY * pScrn->bitsPerPixel/8;
+
+ if (memory > (pScrn->videoRam * 1024 - 4096)) return FALSE;
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pTrident->CursorInfoRec = infoPtr;
+
+ infoPtr->MaxWidth = 64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32;
+ infoPtr->SetCursorColors = TridentSetCursorColors;
+ infoPtr->SetCursorPosition = TridentSetCursorPosition;
+ infoPtr->LoadCursorImage = TridentLoadCursorImage;
+ infoPtr->HideCursor = TridentHideCursor;
+ infoPtr->ShowCursor = TridentShowCursor;
+ infoPtr->UseHWCursor = TridentUseHWCursor;
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}
+
+unsigned int
+Tridentddc1Read(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+ CARD8 temp;
+
+ /* New mode */
+ MMIO_OUTB(0x3C4, 0x0B); temp = MMIO_INB(0x3C5);
+
+ MMIO_OUTB(vgaIOBase + 4, NewMode1);
+ temp = MMIO_INB(vgaIOBase + 5);
+ MMIO_OUTB(vgaIOBase + 5, temp | 0x80);
+
+ /* Define SDA as input */
+ MMIO_OUTW(vgaIOBase + 4, (0x04 << 8) | I2C);
+
+ MMIO_OUTW(vgaIOBase + 4, (temp << 8) | NewMode1);
+
+ /* Wait until vertical retrace is in progress. */
+ while (MMIO_INB(vgaIOBase + 0xA) & 0x08);
+ while (!(MMIO_INB(vgaIOBase + 0xA) & 0x08));
+
+ /* Get the result */
+ MMIO_OUTB(vgaIOBase + 4, I2C);
+ return ( MMIO_INB(vgaIOBase + 5) & 0x01 );
+}
+
+void TridentLoadPalette(
+ ScrnInfoPtr pScrn,
+ int numColors,
+ int *indicies,
+ LOCO *colors,
+ VisualPtr pVisual
+){
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int i, index;
+
+ for(i = 0; i < numColors; i++) {
+ index = indicies[i];
+ MMIO_OUTB(0x3C6, 0xFF);
+ MMIO_OUTB(0x3c8, index);
+ MMIO_OUTB(0x3c9, colors[index].red);
+ MMIO_OUTB(0x3c9, colors[index].green);
+ MMIO_OUTB(0x3c9, colors[index].blue);
+ }
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c
new file mode 100644
index 000000000..f05bd01ea
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c
@@ -0,0 +1,2175 @@
+/*
+ * Copyright 1992-1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
+ * Re-written for XFree86 v4.0
+ *
+ * Previous driver (pre-XFree86 v4.0) by
+ * Alan Hourihane, alanh@fairlite.demon.co.uk
+ * David Wexelblat (major contributor)
+ * Massimiliano Ghilardi, max@Linuz.sns.it, some fixes to the
+ * clockchip programming code.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_driver.c,v 1.62 1999/07/04 06:39:07 dawes Exp $ */
+
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+#include "cfb24_32.h"
+#include "xf1bpp.h"
+#include "xf4bpp.h"
+#include "mibank.h"
+#include "micmap.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86_ansic.h"
+#include "xf86Version.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+#include "xf86cmap.h"
+#include "vgaHW.h"
+#include "xf86RAC.h"
+
+#include "mipointer.h"
+
+#include "mibstore.h"
+
+#include "trident_regs.h"
+#include "trident.h"
+
+#ifdef XFreeXDGA
+#define _XF86DGA_SERVER_
+#include "extensions/xf86dgastr.h"
+#endif
+
+#ifdef DPMSExtension
+#include "globals.h"
+#define DPMS_SERVER
+#include "extensions/dpms.h"
+#endif
+
+#ifdef XvExtension
+#include "xf86xv.h"
+#endif
+
+static void TRIDENTIdentify(int flags);
+static Bool TRIDENTProbe(DriverPtr drv, int flags);
+static Bool TRIDENTPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool TRIDENTScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool TRIDENTEnterVT(int scrnIndex, int flags);
+static void TRIDENTLeaveVT(int scrnIndex, int flags);
+static Bool TRIDENTCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool TRIDENTSaveScreen(ScreenPtr pScreen, Bool unblank);
+
+/* Required if the driver supports mode switching */
+static Bool TRIDENTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+/* Required if the driver supports moving the viewport */
+static void TRIDENTAdjustFrame(int scrnIndex, int x, int y, int flags);
+
+/* Optional functions */
+static void TRIDENTFreeScreen(int scrnIndex, int flags);
+static int TRIDENTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
+
+/* Internally used functions */
+static Bool TRIDENTMapMem(ScrnInfoPtr pScrn);
+static Bool TRIDENTUnmapMem(ScrnInfoPtr pScrn);
+static void TRIDENTSave(ScrnInfoPtr pScrn);
+static void TRIDENTRestore(ScrnInfoPtr pScrn);
+static Bool TRIDENTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+
+static void TRIDENTEnableMMIO(ScrnInfoPtr pScrn);
+static void TRIDENTDisableMMIO(ScrnInfoPtr pScrn);
+/*
+ * This is intentionally screen-independent. It indicates the binding
+ * choice made in the first PreInit.
+ */
+static int pix24bpp = 0;
+
+#define VERSION 4000
+#define TRIDENT_NAME "TRIDENT"
+#define TRIDENT_DRIVER_NAME "trident"
+#define TRIDENT_MAJOR_VERSION 1
+#define TRIDENT_MINOR_VERSION 0
+#define TRIDENT_PATCHLEVEL 0
+
+/*
+ * This contains the functions needed by the server after loading the driver
+ * module. It must be supplied, and gets passed back by the SetupProc
+ * function in the dynamic case. In the static case, a reference to this
+ * is compiled in, and this requires that the name of this DriverRec be
+ * an upper-case version of the driver name.
+ */
+
+DriverRec TRIDENT = {
+ VERSION,
+ "accelerated driver for Trident chipsets",
+ TRIDENTIdentify,
+ TRIDENTProbe,
+ NULL,
+ 0
+};
+
+static SymTabRec TRIDENTChipsets[] = {
+ { PCI_CHIP_9320, "cyber9320" },
+ { PCI_CHIP_9388, "cyber9388" },
+ { PCI_CHIP_9397, "cyber9397" },
+ { PCI_CHIP_939A, "cyber939a" },
+ { PCI_CHIP_9520, "cyber9520" },
+ { PCI_CHIP_9525, "cyber9525" },
+ { PCI_CHIP_9420, "tgui9420" },
+ { PCI_CHIP_9440, "tgui9440" },
+ { PCI_CHIP_9660, "tgui9660" },
+ { PCI_CHIP_9660, "tgui9680" },
+ { PCI_CHIP_9660, "providia9682" },
+ { PCI_CHIP_9660, "providia9685" },
+ { PCI_CHIP_9750, "3dimage975" },
+ { PCI_CHIP_9850, "3dimage985" },
+ { PCI_CHIP_9880, "blade3d" },
+ { PCI_CHIP_8400, "cyberbladei7" },
+ { PCI_CHIP_8420, "cyberbladei7d" },
+ { PCI_CHIP_8500, "cyberbladei1" },
+ { -1, NULL }
+};
+
+static PciChipsets TRIDENTPciChipsets[] = {
+ { PCI_CHIP_9320, PCI_CHIP_9320, RES_SHARED_VGA },
+ { PCI_CHIP_9388, PCI_CHIP_9388, RES_SHARED_VGA },
+ { PCI_CHIP_9397, PCI_CHIP_9397, RES_SHARED_VGA },
+ { PCI_CHIP_939A, PCI_CHIP_939A, RES_SHARED_VGA },
+ { PCI_CHIP_9520, PCI_CHIP_9520, RES_SHARED_VGA },
+ { PCI_CHIP_9525, PCI_CHIP_9525, RES_SHARED_VGA },
+ { PCI_CHIP_9420, PCI_CHIP_9420, RES_SHARED_VGA },
+ { PCI_CHIP_9440, PCI_CHIP_9440, RES_SHARED_VGA },
+ { PCI_CHIP_9660, PCI_CHIP_9660, RES_SHARED_VGA },
+ { PCI_CHIP_9750, PCI_CHIP_9750, RES_SHARED_VGA },
+ { PCI_CHIP_9850, PCI_CHIP_9850, RES_SHARED_VGA },
+ { PCI_CHIP_9880, PCI_CHIP_9880, RES_SHARED_VGA },
+ { PCI_CHIP_8400, PCI_CHIP_8400, RES_SHARED_VGA },
+ { PCI_CHIP_8420, PCI_CHIP_8420, RES_SHARED_VGA },
+ { PCI_CHIP_8500, PCI_CHIP_8500, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED }
+};
+
+typedef enum {
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+ OPTION_PCI_RETRY,
+ OPTION_RGB_BITS,
+ OPTION_NOACCEL,
+ OPTION_SETMCLK,
+ OPTION_MUX_THRESHOLD
+} TRIDENTOpts;
+
+static OptionInfoRec TRIDENTOptions[] = {
+ { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_SETMCLK, "SetMClk", OPTV_FREQ, {0}, FALSE },
+ { OPTION_MUX_THRESHOLD, "MUXThreshold", OPTV_INTEGER, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+#if 0
+static int AvailablePitches[] = {
+ { 0 }, /* 8200LX */
+ { 0 }, /* 8800CS */
+ { 0 }, /* 8900B */
+ { 0 }, /* 8900C */
+ { 0 }, /* 8900CL */
+ { 0 }, /* 8900D */
+ { 0 }, /* 9000 */
+ { 0 }, /* 9000i */
+ { 0 }, /* 9100B */
+ { 0 }, /* 9200CXr */
+ { 0 }, /* 9400CXi */
+ { 0 }, /* 9420 */
+ { 0 }, /* 9420DGi */
+ { 0 }, /* 9430DGi */
+ { 512, 1024, 2048, 4096 }, /* 9440AGi */
+ { 512, 640, 800, 1024, 1280, 2048, 4096 }, /* 9320 */
+ { 512, 640, 832, 1024, 1280, 2048, 4096 }, /* 9660 */
+ { 512, 640, 800, 1024, 1280, 2048, 4096 }, /* 9680 */
+ { 512, 640, 800, 832, 1024, 1280, 1600, 2048, 4096 }, /* 9682 */
+ { 512, 640, 800, 832, 1024, 1280, 1600, 2048, 4096 }, /* 9685 */
+ { 512, 640, 800, 832, 1024, 1280, 1600, 2048, 4096 }, /* 9685 */
+ { 512, 640, 800, 832, 1024, 1280, 1600, 2048, 4096 }, /* 9685 */
+ { 0 },
+ { 0 },
+ { 0 },
+ { 0 },
+ { 0 },
+};
+#endif
+
+/* Clock Limits */
+static int ClockLimit[] = {
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 80000,
+ 90000,
+ 90000,
+ 135000,
+ 135000,
+ 135000,
+ 170000,
+ 135000,
+ 135000,
+ 170000,
+ 170000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+};
+
+static int ClockLimit16bpp[] = {
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 40000,
+ 45000,
+ 45000,
+ 135000,
+ 135000,
+ 135000,
+ 170000,
+ 135000,
+ 135000,
+ 170000,
+ 170000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+ 230000,
+};
+
+static int ClockLimit24bpp[] = {
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 70000,
+ 70000,
+ 70000,
+ 85000,
+ 70000,
+ 70000,
+ 85000,
+ 85000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+};
+
+static int ClockLimit32bpp[] = {
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 25180,
+ 70000,
+ 70000,
+ 70000,
+ 85000,
+ 70000,
+ 70000,
+ 85000,
+ 85000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+ 115000,
+};
+
+static const char *xaaSymbols[] = {
+ "XAADestroyInfoRec",
+ "XAACreateInfoRec",
+ "XAAHelpPatternROP",
+ "XAAHelpSolidROP",
+ "XAACopyROP",
+ "XAAPatternROP",
+ "XAAInit",
+ "XAAStippleScanlineFuncLSBFirst",
+ "XAAOverlayFBfuncs",
+ "XAACachePlanarMonoStipple",
+ "XAAScreenIndex",
+ NULL
+};
+
+static const char *vgahwSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWUnlock",
+ "vgaHWInit",
+ "vgaHWProtect",
+ "vgaHWGetIOBase",
+ "vgaHWMapMem",
+ "vgaHWLock",
+ "vgaHWFreeHWRec",
+ "vgaHWSaveScreen",
+ NULL
+};
+
+static const char *fbSymbols[] = {
+ "xf1bppScreenInit",
+ "xf4bppScreenInit",
+ "cfbScreenInit",
+ "cfb16ScreenInit",
+ "cfb24ScreenInit",
+ "cfb32ScreenInit",
+ "cfb24_32ScreenInit",
+ NULL
+};
+
+static const char *ddcSymbols[] = {
+ "xf86PrintEDID",
+ "xf86DoEDID_DDC1",
+ NULL
+};
+
+static const char *i2cSymbols[] = {
+ "xf86I2CBusInit",
+ "xf86CreateI2CBusRec",
+ NULL
+};
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(tridentSetup);
+
+static XF86ModuleVersionInfo tridentVersRec =
+{
+ "trident",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ TRIDENT_MAJOR_VERSION, TRIDENT_MINOR_VERSION, TRIDENT_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0,0,0,0}
+};
+
+XF86ModuleData tridentModuleData = { &tridentVersRec, tridentSetup, NULL };
+
+pointer
+tridentSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&TRIDENT, module, 0);
+ LoaderRefSymLists(vgahwSymbols, fbSymbols, i2cSymbols,
+ xaaSymbols, NULL);
+ return (pointer)TRUE;
+ }
+
+ if (errmaj) *errmaj = LDR_ONCEONLY;
+ return NULL;
+}
+
+#endif /* XFree86LOADER */
+
+static Bool
+TRIDENTGetRec(ScrnInfoPtr pScrn)
+{
+ /*
+ * Allocate an TRIDENTRec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(TRIDENTRec), 1);
+ /* Initialise it */
+
+ return TRUE;
+}
+
+static void
+TRIDENTFreeRec(ScrnInfoPtr pScrn)
+{
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+#ifdef DPMSExtension
+static void
+TRIDENTDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ CARD8 DPMSCont, PMCont, temp;
+
+ MMIO_OUTB(0x3C4, 0x0E);
+ temp = MMIO_INB(0x3C5);
+ MMIO_OUTB(0x3C5, 0xC2);
+ MMIO_OUTB(0x83C8, 0x04); /* Read DPMS Control */
+ PMCont = MMIO_INB(0x83C6) & 0xFC;
+ MMIO_OUTB(0x3CE, 0x23);
+ DPMSCont = MMIO_INB(0x3CF) & 0xFC;
+ switch (PowerManagementMode)
+ {
+ case DPMSModeOn:
+ /* Screen: On, HSync: On, VSync: On */
+ PMCont |= 0x03;
+ DPMSCont |= 0x00;
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off, HSync: Off, VSync: On */
+ PMCont |= 0x02;
+ DPMSCont |= 0x01;
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off, HSync: On, VSync: Off */
+ PMCont |= 0x02;
+ DPMSCont |= 0x02;
+ break;
+ case DPMSModeOff:
+ /* Screen: Off, HSync: Off, VSync: Off */
+ PMCont |= 0x00;
+ DPMSCont |= 0x03;
+ break;
+ }
+ MMIO_OUTB(0x3CF, DPMSCont);
+ MMIO_OUTB(0x83C8, 0x04);
+ MMIO_OUTB(0x83C6, PMCont);
+ MMIO_OUTW(0x3C4, (temp<<8) | 0x0E);
+}
+#endif
+
+/* Mandatory */
+static void
+TRIDENTIdentify(int flags)
+{
+ xf86PrintChipsets(TRIDENT_NAME, "driver for Trident chipsets", TRIDENTChipsets);
+}
+
+static void
+Trident1bppColorMap(ScrnInfoPtr pScrn) {
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+/* In 1 bpp we have color 0 at LUT 0 and color 1 at LUT 0x3f.
+ This makes white and black look right (otherwise they were both
+ black. I'm sure there's a better way to do that, just lazy to
+ search the docs. */
+
+ MMIO_OUTB(0x3C8, 0x00); MMIO_OUTB(0x3C9, 0x00); MMIO_OUTB(0x3C9, 0x00); MMIO_OUTB(0x3C9, 0x00);
+ MMIO_OUTB(0x3C8, 0x3F); MMIO_OUTB(0x3C9, 0x3F); MMIO_OUTB(0x3C9, 0x3F); MMIO_OUTB(0x3C9, 0x3F);
+}
+
+/* Mandatory */
+static Bool
+TRIDENTProbe(DriverPtr drv, int flags)
+{
+ int i;
+ GDevPtr *devSections;
+ int *usedChips;
+ int numDevSections;
+ int numUsed;
+ Bool foundScreen = FALSE;
+
+ /*
+ * The aim here is to find all cards that this driver can handle,
+ * and for the ones not already claimed by another driver, claim the
+ * slot, and allocate a ScrnInfoRec.
+ *
+ * This should be a minimal probe, and it should under no circumstances
+ * change the state of the hardware. Because a device is found, don't
+ * assume that it will be used. Don't do any initialisations other than
+ * the required ScrnInfoRec initialisations. Don't allocate any new
+ * data structures.
+ *
+ * Since this test version still uses vgaHW, we'll only actually claim
+ * one for now, and just print a message about the others.
+ */
+
+ /*
+ * Next we check, if there has been a chipset override in the config file.
+ * For this we must find out if there is an active device section which
+ * is relevant, i.e., which has no driver specified or has THIS driver
+ * specified.
+ */
+
+ if ((numDevSections = xf86MatchDevice(TRIDENT_DRIVER_NAME,
+ &devSections)) <= 0) {
+ /*
+ * There's no matching device section in the config file, so quit
+ * now.
+ */
+ return FALSE;
+ }
+
+ /*
+ * While we're VGA-dependent, can really only have one such instance, but
+ * we'll ignore that.
+ */
+
+ /*
+ * We need to probe the hardware first. We then need to see how this
+ * fits in with what is given in the config file, and allow the config
+ * file info to override any contradictions.
+ */
+
+ /*
+ * All of the cards this driver supports are PCI, so the "probing" just
+ * amounts to checking the PCI data that the server has already collected.
+ */
+ if (xf86GetPciVideoInfo() == NULL) {
+ /*
+ * We won't let anything in the config file override finding no
+ * PCI video cards at all. This seems reasonable now, but we'll see.
+ */
+ return FALSE;
+ }
+
+ numUsed = xf86MatchPciInstances(TRIDENT_NAME, PCI_VENDOR_TRIDENT,
+ TRIDENTChipsets, TRIDENTPciChipsets, devSections,
+ numDevSections, drv, &usedChips);
+
+ /* Free it since we don't need that list after this */
+ xfree(devSections);
+ devSections = NULL;
+ if (numUsed <= 0)
+ return FALSE;
+
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn;
+
+ /* Allocate a ScrnInfoRec and claim the slot */
+ pScrn = xf86AllocateScreen(drv, 0);
+
+ /* Fill in what we can of the ScrnInfoRec */
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = TRIDENT_DRIVER_NAME;
+ pScrn->name = TRIDENT_NAME;
+ pScrn->Probe = TRIDENTProbe;
+ pScrn->PreInit = TRIDENTPreInit;
+ pScrn->ScreenInit = TRIDENTScreenInit;
+ pScrn->SwitchMode = TRIDENTSwitchMode;
+ pScrn->AdjustFrame = TRIDENTAdjustFrame;
+ pScrn->EnterVT = TRIDENTEnterVT;
+ pScrn->LeaveVT = TRIDENTLeaveVT;
+ pScrn->FreeScreen = TRIDENTFreeScreen;
+ pScrn->ValidMode = TRIDENTValidMode;
+ foundScreen = TRUE;
+ xf86ConfigActivePciEntity(pScrn, usedChips[i], TRIDENTPciChipsets,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+ xfree(usedChips);
+ return foundScreen;
+}
+
+/*
+ * GetAccelPitchValues -
+ *
+ * This function returns a list of display width (pitch) values that can
+ * be used in accelerated mode.
+ */
+static int *
+GetAccelPitchValues(ScrnInfoPtr pScrn)
+{
+#if 0
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+#endif
+ int *linePitches = NULL;
+ int lines[4] = { 512, 1024, 2048, 4096 }; /* 9440AGi */
+#if 0
+ int lines[sizeof(AvailablePitches[pTrident->Chipset])] =
+ AvailablePitches[pTrident->Chipset];
+#endif
+ int i, n = 0;
+
+ for (i = 0; i < 4; i++) {
+ n++;
+ linePitches = xnfrealloc(linePitches, n * sizeof(int));
+ linePitches[n - 1] = lines[i];
+ }
+
+ /* Mark the end of the list */
+ if (n > 0) {
+ linePitches = xnfrealloc(linePitches, (n + 1) * sizeof(int));
+ linePitches[n] = 0;
+ }
+ return linePitches;
+}
+
+/* Mandatory */
+static Bool
+TRIDENTPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ TRIDENTPtr pTrident;
+ MessageType from;
+ CARD8 videoram;
+ char *ramtype = NULL, *chipset = NULL;
+ Bool Support24bpp;
+ int vgaIOBase;
+ float mclk;
+ double real;
+ int i;
+ CARD8 revision;
+ ClockRangePtr clockRanges;
+ char *mod = NULL;
+ const char *Sym = "";
+
+ /*
+ * Note: This function is only called once at server startup, and
+ * not at the start of each server generation. This means that
+ * only things that are persistent across server generations can
+ * be initialised here. xf86Screens[] is (pScrn is a pointer to one
+ * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex()
+ * are too, and should be used for data that must persist across
+ * server generations.
+ *
+ * Per-generation data should be allocated with
+ * AllocateScreenPrivateIndex() from the ScreenInit() function.
+ */
+
+ /* Check the number of entities, and fail if it isn't one. */
+ if (pScrn->numEntities != 1)
+ return FALSE;
+
+ /* The vgahw module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /*
+ * Allocate a vgaHWRec
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ /* Allocate the TRIDENTRec driverPrivate */
+ if (!TRIDENTGetRec(pScrn)) {
+ return FALSE;
+ }
+ pTrident = TRIDENTPTR(pScrn);
+ pTrident->pScrn = pScrn;
+
+ /* Get the entity, and make sure it is PCI. */
+ pTrident->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+ if (pTrident->pEnt->location.type != BUS_PCI)
+ return FALSE;
+
+ /* Find the PCI info for this screen */
+ pTrident->PciInfo = xf86GetPciInfoForEntity(pTrident->pEnt->index);
+ pTrident->PciTag = pciTag(pTrident->PciInfo->bus, pTrident->PciInfo->device,
+ pTrident->PciInfo->func);
+
+ xf86SetOperatingState(RES_SHARED_VGA, pTrident->pEnt->index, ResUnusedOpr);
+
+ /* Operations for which memory access is required. */
+ pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+#if 0
+ pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+#endif
+
+ /* The ramdac module should be loaded here when needed */
+ if (!xf86LoadSubModule(pScrn, "ramdac"))
+ return FALSE;
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*
+ * The first thing we should figure out is the depth, bpp, etc.
+ * Our default depth is 8, so pass it to the helper function.
+ * Our preference for depth 24 is 24bpp, so tell it that too.
+ */
+ if (!xf86SetDepthBpp(pScrn, 8, 0, 0, Support24bppFb | Support32bppFb |
+ SupportConvert32to24 /*| PreferConvert32to24*/)) {
+ return FALSE;
+ } else {
+ /* Check that the returned depth is one we support */
+ switch (pScrn->depth) {
+ case 1:
+ case 4:
+ case 8:
+ case 15:
+ case 16:
+ case 24:
+ /* OK */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ xf86PrintDepthBpp(pScrn);
+
+ /* Get the depth24 pixmap format */
+ if (pScrn->depth == 24 && pix24bpp == 0)
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros = {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ /* We don't currently support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /*
+ * The new cmap layer needs this to be initialised.
+ */
+
+ {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+
+ /* We use a programamble clock */
+ pScrn->progClock = TRUE;
+
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, TRIDENTOptions);
+
+ /* Set the bits per RGB for 8bpp mode */
+ if (pScrn->depth == 8) {
+ /* XXX This is here just to test options. */
+ /* Default to 8 */
+ pScrn->rgbBits = 6;
+#if 0
+ if (xf86GetOptValInteger(TRIDENTOptions, OPTION_RGB_BITS,
+ &pScrn->rgbBits)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Bits per RGB set to %d\n",
+ pScrn->rgbBits);
+ }
+#endif
+ }
+ from = X_DEFAULT;
+ pTrident->HWCursor = TRUE;
+ if (xf86GetOptValBool(TRIDENTOptions, OPTION_HW_CURSOR, &pTrident->HWCursor))
+ from = X_CONFIG;
+ if (xf86ReturnOptValBool(TRIDENTOptions, OPTION_SW_CURSOR, FALSE)) {
+ from = X_CONFIG;
+ pTrident->HWCursor = FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pTrident->HWCursor ? "HW" : "SW");
+ if (xf86ReturnOptValBool(TRIDENTOptions, OPTION_NOACCEL, FALSE)) {
+ pTrident->NoAccel = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+ if (xf86ReturnOptValBool(TRIDENTOptions, OPTION_PCI_RETRY, FALSE)) {
+ pTrident->UsePCIRetry = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
+ }
+ pTrident->MUXThreshold = 100000; /* 100MHz */
+ if (xf86GetOptValInteger(TRIDENTOptions, OPTION_MUX_THRESHOLD,
+ &pTrident->MUXThreshold)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "MUX Threshold set to %d\n",
+ pTrident->MUXThreshold);
+ }
+
+ pTrident->RamDac = -1;
+ /*
+ * Set the Chipset and ChipRev, allowing config file entries to
+ * override.
+ */
+ if (pTrident->pEnt->device->chipset && *pTrident->pEnt->device->chipset) {
+ pScrn->chipset = pTrident->pEnt->device->chipset;
+ pTrident->Chipset = xf86StringToToken(TRIDENTChipsets, pScrn->chipset);
+ from = X_CONFIG;
+ } else if (pTrident->pEnt->device->chipID >= 0) {
+ pTrident->Chipset = pTrident->pEnt->device->chipID;
+ pScrn->chipset = (char *)xf86TokenToString(TRIDENTChipsets, pTrident->Chipset);
+
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pTrident->Chipset);
+ } else {
+ from = X_PROBED;
+ pTrident->Chipset = pTrident->PciInfo->chipType;
+ pScrn->chipset = (char *)xf86TokenToString(TRIDENTChipsets, pTrident->Chipset);
+ }
+ if (pTrident->pEnt->device->chipRev >= 0) {
+ pTrident->ChipRev = pTrident->pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pTrident->ChipRev);
+ } else {
+ pTrident->ChipRev = pTrident->PciInfo->chipRev;
+ }
+
+ /*
+ * This shouldn't happen because such problems should be caught in
+ * TRIDENTProbe(), but check it just in case.
+ */
+ if (pScrn->chipset == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ChipID 0x%04X is not recognised\n", pTrident->Chipset);
+ return FALSE;
+ }
+ if (pTrident->Chipset < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Chipset \"%s\" is not recognised\n", pScrn->chipset);
+ return FALSE;
+ }
+
+ if (pTrident->pEnt->device->MemBase != 0) {
+ /*
+ * XXX Should check that the config file value matches one of the
+ * PCI base address values.
+ */
+ pTrident->FbAddress = pTrident->pEnt->device->MemBase;
+ from = X_CONFIG;
+ } else {
+ pTrident->FbAddress = pTrident->PciInfo->memBase[0] & 0xFFFFFFF0;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pTrident->FbAddress);
+
+ if (pTrident->pEnt->device->IOBase != 0) {
+ /*
+ * XXX Should check that the config file value matches one of the
+ * PCI base address values.
+ */
+ pTrident->IOAddress = pTrident->pEnt->device->IOBase;
+ from = X_CONFIG;
+ } else {
+ pTrident->IOAddress = pTrident->PciInfo->memBase[1] & 0xFFFFC000;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex,X_PROBED,"IO registers at 0x%lX\n",pTrident->IOAddress);
+
+ /* Register the PCI-assigned resources. */
+ if (xf86RegisterResources(pTrident->pEnt->index, NULL, ResExclusive)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "xf86RegisterResources() found resource conflicts\n");
+ return FALSE;
+ }
+
+ if (!TRIDENTMapMem(pScrn))
+ return FALSE;
+
+ TRIDENTEnableMMIO(pScrn);
+
+ MMIO_OUTB(0x3C4, RevisionID); revision = MMIO_INB(0x3C5);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Revision is %d\n",revision);
+
+ pTrident->EngineOperation = 0x00;
+ pTrident->UseGERetry = FALSE;
+ pTrident->IsCyber = FALSE;
+ pTrident->HasSGRAM = FALSE;
+ pTrident->NewClockCode = FALSE;
+ pTrident->MUX = FALSE;
+ Support24bpp = FALSE;
+
+ MMIO_OUTB(vgaIOBase + 4, InterfaceSel);
+
+ switch (pTrident->Chipset) {
+ case PCI_CHIP_9440:
+ pTrident->ddc1Read = Tridentddc1Read;
+ pTrident->HWCursor = FALSE;
+ chipset = "TGUI9440";
+ pTrident->Chipset = TGUI9440AGi;
+ ramtype = "Standard DRAM";
+ if (pTrident->UsePCIRetry)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
+ pTrident->UsePCIRetry = FALSE; /* Not Supported */
+ pTrident->frequency = NTSC;
+ break;
+ case PCI_CHIP_9320:
+ pTrident->ddc1Read = Tridentddc1Read;
+ chipset = "Cyber9320";
+ pTrident->Chipset = CYBER9320;
+ ramtype = "Standard DRAM";
+ if (pTrident->UsePCIRetry)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
+ pTrident->UsePCIRetry = FALSE; /* Not Supported */
+ break;
+ case PCI_CHIP_9660:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x0C)
+ ramtype = "Standard DRAM";
+ switch (revision) {
+ case 0x00:
+ chipset = "TGUI9660";
+ pTrident->Chipset = TGUI9660;
+ if (pTrident->UsePCIRetry)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
+ pTrident->UsePCIRetry = FALSE; /* Not Supported */
+ break;
+ case 0x01:
+ chipset = "TGUI9680";
+ pTrident->Chipset = TGUI9680;
+ if (pTrident->UsePCIRetry)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
+ pTrident->UsePCIRetry = FALSE; /* Not Supported */
+ break;
+ case 0x10:
+ chipset = "ProVidia 9682";
+ Support24bpp = TRUE;
+ pTrident->Chipset = PROVIDIA9682;
+ if (pTrident->UsePCIRetry)
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry not supported, disabling\n");
+ pTrident->UsePCIRetry = FALSE; /* Not Supported */
+ break;
+ case 0x21:
+ chipset = "ProVidia 9685";
+ Support24bpp = TRUE;
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = PROVIDIA9685;
+ break;
+ case 0x22:
+ case 0x23:
+ chipset = "Cyber 9397";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = CYBER9397;
+ pTrident->IsCyber = TRUE;
+ break;
+ case 0x2a:
+ chipset = "Cyber 939A/DVD";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = CYBER939A;
+ pTrident->IsCyber = TRUE;
+ break;
+ case 0x30:
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0xB3:
+ chipset = "Cyber 9385";
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = CYBER9385;
+ pTrident->IsCyber = TRUE;
+ break;
+ case 0x38:
+ case 0x3A:
+ chipset = "Cyber 9385-1";
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = CYBER9385;
+ pTrident->IsCyber = TRUE;
+ break;
+ case 0x40:
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ chipset = "Cyber 9382";
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = CYBER9382;
+ pTrident->IsCyber = TRUE;
+ break;
+ case 0x4A:
+ chipset = "Cyber 9388";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = CYBER9388;
+ pTrident->IsCyber = TRUE;
+ break;
+ default:
+ chipset = "Unknown";
+ pTrident->Chipset = TGUI9660;
+ break;
+ }
+ break;
+ case PCI_CHIP_9520:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ Support24bpp = TRUE;
+ chipset = "Cyber 9520";
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = CYBER9520;
+ break;
+ case PCI_CHIP_9525:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ Support24bpp = TRUE;
+ chipset = "Cyber 9525/DVD";
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = CYBER9525;
+ break;
+ case PCI_CHIP_9750:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ Support24bpp = TRUE;
+ chipset = "3DImage975";
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = IMAGE975;
+ break;
+ case PCI_CHIP_9850:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x04)
+ ramtype = "EDO Ram";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ Support24bpp = TRUE;
+ chipset = "3DImage985";
+ pTrident->NewClockCode = TRUE;
+ pTrident->Chipset = IMAGE985;
+ break;
+ case PCI_CHIP_9880:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ Support24bpp = TRUE;
+ chipset = "Blade3D";
+ pTrident->NewClockCode = TRUE;
+ pTrident->frequency = NTSC;
+ pTrident->Chipset = BLADE3D;
+ break;
+ case PCI_CHIP_8400:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ Support24bpp = TRUE;
+ chipset = "CyberBlade/i7";
+ pTrident->NewClockCode = TRUE;
+ pTrident->frequency = NTSC;
+ pTrident->Chipset = BLADE3D;
+ break;
+ case PCI_CHIP_8420:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ Support24bpp = TRUE;
+ chipset = "CyberBlade/DSTN/i7";
+ pTrident->NewClockCode = TRUE;
+ pTrident->frequency = NTSC;
+ pTrident->Chipset = BLADE3D;
+ break;
+ case PCI_CHIP_8500:
+ pTrident->ddc1Read = Tridentddc1Read;
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x08)
+ ramtype = "SDRAM";
+ if ((MMIO_INB(vgaIOBase + 5) & 0x0C) == 0x0C) {
+ pTrident->HasSGRAM = TRUE;
+ ramtype = "SGRAM";
+ }
+ Support24bpp = TRUE;
+ chipset = "CyberBlade/i1";
+ pTrident->NewClockCode = TRUE;
+ pTrident->frequency = NTSC;
+ pTrident->Chipset = BLADE3D;
+ break;
+ }
+
+
+ if (!chipset) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No support for \"%s\"\n",
+ pScrn->chipset);
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Found %s chip\n", chipset);
+ if (ramtype)
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "RAM type is %s\n", ramtype);
+
+ if (pScrn->bitsPerPixel == 24 && !Support24bpp) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No support for 24bpp on this chipset, use -pixmap32.\n");
+ return FALSE;
+ }
+
+ /* HW bpp matches reported bpp */
+ pTrident->HwBpp = pScrn->bitsPerPixel;
+
+ if (pTrident->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pTrident->pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else {
+ MMIO_OUTB(vgaIOBase + 4, SPR);
+ videoram = MMIO_INB(vgaIOBase + 5);
+ switch (videoram & 0x0F) {
+ case 0x03:
+ pScrn->videoRam = 1024;
+ break;
+ case 0x04: /* 8MB, but - hw cursor can't store above 4MB */
+ /* So, we force to 4MB for now */
+ /* pScrn->videoRam = 8192; */
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Found 8MB board, using 4MB\n");
+ pScrn->videoRam = 4096;
+ break;
+ case 0x07:
+ pScrn->videoRam = 2048;
+ break;
+ case 0x0F:
+ pScrn->videoRam = 4096;
+ break;
+ default:
+ pScrn->videoRam = 1024;
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Unable to determine VideoRam, defaulting to 1MB\n",
+ pScrn->videoRam);
+ break;
+ }
+ }
+
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
+ pScrn->videoRam);
+
+ pTrident->MCLK = 0;
+ mclk = CalculateMCLK(pScrn);
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Memory Clock is %3.2f MHz\n", mclk);
+ if (xf86GetOptValFreq(TRIDENTOptions, OPTION_SETMCLK, OPTUNITS_MHZ,
+ &real)) {
+ pTrident->MCLK = (int)(real * 1000.0);
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Setting new Memory Clock to %3.2f MHz\n",
+ (float)(pTrident->MCLK / 1000));
+ }
+
+ /* Set the min pixel clock */
+ pTrident->MinClock = 16250; /* XXX Guess, need to check this */
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
+ pTrident->MinClock / 1000);
+
+ /*
+ * If the user has specified ramdac speed in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pTrident->pEnt->device->dacSpeeds[0]) {
+ int speed = 0;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ case 32:
+ speed = pTrident->pEnt->device->dacSpeeds[DAC_BPP32];
+ break;
+ }
+ if (speed == 0)
+ pTrident->MaxClock = pTrident->pEnt->device->dacSpeeds[0];
+ else
+ pTrident->MaxClock = speed;
+ from = X_CONFIG;
+ } else {
+ switch (pScrn->bitsPerPixel) {
+ case 16:
+ pTrident->MaxClock = ClockLimit16bpp[pTrident->Chipset];
+ break;
+ case 24:
+ pTrident->MaxClock = ClockLimit24bpp[pTrident->Chipset];
+ break;
+ case 32:
+ pTrident->MaxClock = ClockLimit32bpp[pTrident->Chipset];
+ break;
+ default:
+ pTrident->MaxClock = ClockLimit[pTrident->Chipset];
+ break;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
+ pTrident->MaxClock / 1000);
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ */
+ clockRanges = xnfalloc(sizeof(ClockRange));
+ clockRanges->next = NULL;
+ clockRanges->minClock = pTrident->MinClock;
+ clockRanges->maxClock = pTrident->MaxClock;
+ clockRanges->clockIndex = -1; /* programmable */
+ clockRanges->interlaceAllowed = TRUE;
+ clockRanges->doubleScanAllowed = FALSE; /* XXX check this */
+
+ /*
+ * xf86ValidateModes will check that the mode HTotal and VTotal values
+ * don't exceed the chipset's limit if pScrn->maxHValue and
+ * pScrn->maxVValue are set. Since our TRIDENTValidMode() already takes
+ * care of this, we don't worry about setting them here.
+ */
+
+ if ((pScrn->depth < 8) ||
+ (pScrn->bitsPerPixel == 24))
+ pTrident->NoAccel = TRUE;
+
+ /* Select valid modes from those available */
+ if (pTrident->NoAccel) {
+ /*
+ * XXX Assuming min pitch 256, max 4096
+ * XXX Assuming min height 128, max 4096
+ */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ NULL, 256, 4096,
+ pScrn->bitsPerPixel, 128, 4096,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pTrident->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+ } else {
+ /*
+ * XXX Assuming min height 128, max 2048
+ */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, clockRanges,
+ GetAccelPitchValues(pScrn), 0, 0,
+ pScrn->bitsPerPixel, 128, 2048,
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pTrident->FbMapSize,
+ LOOKUP_BEST_REFRESH);
+ }
+
+ if (i == -1) {
+ TRIDENTFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ TRIDENTFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ pTrident->EngineOperation |= 0x00;
+ mod = "xf1bpp";
+ Sym = "xf1bppScreenInit";
+ break;
+ case 4:
+ pTrident->EngineOperation |= 0x00;
+ mod = "xf4bpp";
+ Sym = "xf4bppScreenInit";
+ break;
+ case 8:
+ pTrident->EngineOperation |= 0x00;
+ mod = "cfb";
+ Sym = "cfbScreenInit";
+ break;
+ break;
+ case 16:
+ pTrident->EngineOperation |= 0x01;
+ mod = "cfb16";
+ Sym = "cfb16ScreenInit";
+ break;
+ case 24:
+ pTrident->EngineOperation |= 0x03;
+ if (pix24bpp == 24) {
+ mod = "cfb24";
+ Sym = "cfb24ScreenInit";
+ } else {
+ mod = "xf24_32bpp";
+ Sym = "cfb24_32ScreenInit";
+ }
+ break;
+ case 32:
+ pTrident->EngineOperation |= 0x02;
+ mod = "cfb32";
+ Sym = "cfb32ScreenInit";
+ break;
+ }
+
+ if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ TRIDENTFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymbols(Sym, NULL);
+
+ if (!xf86LoadSubModule(pScrn, "i2c")) {
+ TRIDENTFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(i2cSymbols, NULL);
+
+ /* Load XAA if needed */
+ if (!pTrident->NoAccel) {
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ TRIDENTFreeRec(pScrn);
+ return FALSE;
+ }
+
+ xf86LoaderReqSymLists(xaaSymbols, NULL);
+
+ switch (pScrn->displayWidth * pScrn->bitsPerPixel / 8) {
+ case 512:
+ pTrident->EngineOperation |= 0x00;
+ break;
+ case 1024:
+ pTrident->EngineOperation |= 0x04;
+ break;
+ case 2048:
+ pTrident->EngineOperation |= 0x08;
+ break;
+ case 4096:
+ pTrident->EngineOperation |= 0x0C;
+ break;
+ }
+ }
+
+ /* Load DDC if needed */
+ /* This gives us DDC1 - we should be able to get DDC2B using i2c */
+ if (!xf86LoadSubModule(pScrn, "ddc")) {
+ TRIDENTFreeRec(pScrn);
+ return FALSE;
+ }
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+
+#if 0
+ /* Initialize DDC1 if possible */
+ if (pTrident->ddc1Read)
+ xf86PrintEDID(xf86DoEDID_DDC1(pScrn->scrnIndex,vgaHWddc1SetSpeed,pTrident->ddc1Read ) );
+#endif
+
+ TRIDENTDisableMMIO(pScrn);
+
+ TRIDENTUnmapMem(pScrn);
+
+ pTrident->FbMapSize = pScrn->videoRam * 1024;
+
+ return TRUE;
+}
+
+
+/*
+ * Map the framebuffer and MMIO memory.
+ */
+
+static Bool
+TRIDENTMapMem(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int mmioFlags;
+
+ /*
+ * Map IO registers to virtual address space
+ */
+#if !defined(__alpha__)
+ mmioFlags = VIDMEM_MMIO;
+#else
+ /*
+ * For Alpha, we need to map SPARSE memory, since we need
+ * byte/short access.
+ */
+ mmioFlags = VIDMEM_MMIO | VIDMEM_SPARSE;
+#endif
+ pTrident->IOBase = xf86MapPciMem(pScrn->scrnIndex, mmioFlags,
+ pTrident->PciTag, pTrident->IOAddress, 0x20000);
+ if (pTrident->IOBase == NULL)
+ return FALSE;
+
+#ifdef __alpha__
+ /*
+ * for Alpha, we need to map DENSE memory as well, for
+ * setting CPUToScreenColorExpandBase.
+ */
+ pTrident->IOBaseDense = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+ pTrident->PciTag, pTrident->IOAddress, 0x20000);
+
+ if (pTrident->IOBaseDense == NULL)
+ return FALSE;
+#endif /* __alpha__ */
+
+ if (pTrident->FbMapSize != 0) {
+ pTrident->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pTrident->PciTag,
+ (unsigned long)pTrident->FbAddress,
+ pTrident->FbMapSize);
+ if (pTrident->FbBase == NULL)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Unmap the framebuffer and MMIO memory.
+ */
+
+static Bool
+TRIDENTUnmapMem(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ /*
+ * Unmap IO registers to virtual address space
+ */
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->IOBase, 0x20000);
+ pTrident->IOBase = NULL;
+
+#ifdef __alpha__
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->IOBaseDense, 0x20000);
+ pTrident->IOBaseDense = NULL;
+#endif /* __alpha__ */
+
+ if (pTrident->FbMapSize != 0) {
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTrident->FbBase, pTrident->FbMapSize);
+ pTrident->FbBase = NULL;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * This function saves the video state.
+ */
+static void
+TRIDENTSave(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident;
+ vgaRegPtr vgaReg;
+ TRIDENTRegPtr tridentReg;
+
+ pTrident = TRIDENTPTR(pScrn);
+ vgaReg = &VGAHWPTR(pScrn)->SavedReg;
+ tridentReg = &pTrident->SavedReg;
+
+ if (xf86IsPrimaryPci(pTrident->PciInfo))
+ vgaHWSave(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_FONTS);
+ else
+ vgaHWSave(pScrn, vgaReg, VGA_SR_MODE);
+
+ TridentSave(pScrn, tridentReg);
+}
+
+
+/*
+ * Initialise a new mode. This is currently still using the old
+ * "initialise struct, restore/write struct to HW" model. That could
+ * be changed.
+ */
+
+static Bool
+TRIDENTModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ vgaRegPtr vgaReg;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ TRIDENTRegPtr tridentReg;
+
+ if (mode->Clock > pTrident->MUXThreshold) pTrident->MUX = TRUE;
+ else pTrident->MUX = FALSE;
+
+ switch (pTrident->Chipset) {
+ case TGUI9660:
+ case TGUI9680:
+ case PROVIDIA9682:
+ case PROVIDIA9685:
+ case IMAGE975:
+ case IMAGE985:
+ case BLADE3D:
+ case CYBERBLADEI7:
+ case CYBERBLADEI7D:
+ case CYBERBLADEI1:
+ case CYBER9520:
+ case CYBER9525:
+ case CYBER9397:
+ case CYBER939A:
+ /* Get ready for MUX mode */
+ if (pTrident->MUX &&
+ pScrn->bitsPerPixel == 8 &&
+ !mode->CrtcHAdjusted) {
+ mode->CrtcHDisplay >>= 1;
+ mode->CrtcHSyncStart >>= 1;
+ mode->CrtcHSyncEnd >>= 1;
+ mode->CrtcHBlankStart >>= 1;
+ mode->CrtcHBlankEnd >>= 1;
+ mode->CrtcHTotal >>= 1;
+ mode->CrtcHAdjusted = TRUE;
+ }
+ break;
+ }
+
+ vgaHWUnlock(hwp);
+
+ /* Initialise the ModeReg values */
+ if (!vgaHWInit(pScrn, mode))
+ return FALSE;
+ pScrn->vtSema = TRUE;
+
+ if (!TridentInit(pScrn, mode))
+ return FALSE;
+
+ /* Program the registers */
+ vgaHWProtect(pScrn, TRUE);
+ vgaReg = &hwp->ModeReg;
+ tridentReg = &pTrident->ModeReg;
+
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+
+ TridentRestore(pScrn, tridentReg);
+
+ vgaHWProtect(pScrn, FALSE);
+
+ return TRUE;
+}
+
+/*
+ * Restore the initial (text) mode.
+ */
+static void
+TRIDENTRestore(ScrnInfoPtr pScrn)
+{
+ vgaHWPtr hwp;
+ vgaRegPtr vgaReg;
+ TRIDENTPtr pTrident;
+ TRIDENTRegPtr tridentReg;
+
+ hwp = VGAHWPTR(pScrn);
+ pTrident = TRIDENTPTR(pScrn);
+ vgaReg = &hwp->SavedReg;
+ tridentReg = &pTrident->SavedReg;
+
+ vgaHWProtect(pScrn, TRUE);
+
+ TridentRestore(pScrn, tridentReg);
+
+ if (xf86IsPrimaryPci(pTrident->PciInfo))
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE | VGA_SR_FONTS);
+ else
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE);
+
+ vgaHWProtect(pScrn, FALSE);
+}
+
+
+/* Mandatory */
+
+/* This gets called at the start of each server generation */
+
+static Bool
+TRIDENTScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ /* The vgaHW references will disappear one day */
+ ScrnInfoPtr pScrn;
+ vgaHWPtr hwp;
+ TRIDENTPtr pTrident;
+ int ret;
+ VisualPtr visual;
+
+ /*
+ * First get the ScrnInfoRec
+ */
+ pScrn = xf86Screens[pScreen->myNum];
+ pTrident = TRIDENTPTR(pScrn);
+
+ /* Map the TRIDENT memory and MMIO areas */
+ if (!TRIDENTMapMem(pScrn))
+ return FALSE;
+
+ hwp = VGAHWPTR(pScrn);
+ hwp->MapSize = 0x10000; /* Standard 64k VGA window */
+
+ if (xf86IsPrimaryPci(pTrident->PciInfo)) {
+ if (!vgaHWMapMem(pScrn))
+ return FALSE;
+ }
+
+ TRIDENTEnableMMIO(pScrn);
+
+ /* Initialize the MMIO vgahw functions */
+ vgaHWSetMmioFuncs(hwp, pTrident->IOBase, 0);
+ vgaHWGetIOBase(hwp);
+
+ /* Save the current state */
+ TRIDENTSave(pScrn);
+
+ /* Initialise the first mode */
+ if (!TRIDENTModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ /* Darken the screen for aesthetic reasons and set the viewport */
+ TRIDENTSaveScreen(pScreen, FALSE);
+ TRIDENTAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ /*
+ * For bpp > 8, the default visuals are not acceptable because we only
+ * support TrueColor and not DirectColor.
+ */
+
+ if (pScrn->bitsPerPixel > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
+ pScrn->defaultVisual))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ ret = xf1bppScreenInit(pScreen, pTrident->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 4:
+ ret = xf4bppScreenInit(pScreen, pTrident->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 8:
+ ret = cfbScreenInit(pScreen, pTrident->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 16:
+ ret = cfb16ScreenInit(pScreen, pTrident->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 24:
+ if (pix24bpp == 24)
+ ret = cfb24ScreenInit(pScreen, pTrident->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ else
+ ret = cfb24_32ScreenInit(pScreen, pTrident->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 32:
+ ret = cfb32ScreenInit(pScreen, pTrident->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in TRIDENTScrnInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ if (!ret)
+ return FALSE;
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ if (pScrn->bitsPerPixel > 8) {
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ } else if (pScrn->depth == 1) {
+ Trident1bppColorMap(pScrn);
+ }
+
+#if 0 /* Banking support has been disabled */
+ if (pScrn->depth < 8) {
+ miBankInfoPtr pBankInfo;
+
+ /* Setup the vga banking variables */
+ pBankInfo = xnfcalloc(sizeof(miBankInfoRec),1);
+ if (pBankInfo == NULL)
+ return FALSE;
+
+ pBankInfo->pBankA = hwp->Base;
+ pBankInfo->pBankB = hwp->Base;
+ pBankInfo->BankSize = 0x10000;
+ pBankInfo->nBankDepth = pScrn->depth;
+
+ pBankInfo->SetSourceBank =
+ (miBankProcPtr)TGUISetRead;
+ pBankInfo->SetDestinationBank =
+ (miBankProcPtr)TGUISetWrite;
+ pBankInfo->SetSourceAndDestinationBanks =
+ (miBankProcPtr)TGUISetReadWrite;
+ if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
+ pScrn->displayWidth, pBankInfo)) {
+ xfree(pBankInfo);
+ pBankInfo = NULL;
+ return FALSE;
+ }
+ }
+#endif
+
+ if (!pTrident->NoAccel) {
+ if (Is3Dchip) {
+ if ((pTrident->Chipset == CYBERBLADEI7) ||
+ (pTrident->Chipset == CYBERBLADEI7D) ||
+ (pTrident->Chipset == CYBERBLADEI1) ||
+ (pTrident->Chipset == BLADE3D))
+ BladeAccelInit(pScreen);
+ else
+ ImageAccelInit(pScreen);
+ } else {
+ TridentAccelInit(pScreen);
+ }
+ }
+
+ miInitializeBackingStore(pScreen);
+ xf86SetBackingStore(pScreen);
+
+ /* Initialise cursor functions */
+ miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
+
+ if (pTrident->HWCursor)
+ TridentHWCursorInit(pScreen);
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ if(!xf86HandleColormaps(pScreen, 256, 6, TridentLoadPalette,
+ NULL, CMAP_RELOAD_ON_MODE_SWITCH|CMAP_PALETTED_TRUECOLOR))
+ return FALSE;
+
+#ifdef DPMSExtension
+ xf86DPMSInit(pScreen, (DPMSSetProcPtr)TRIDENTDisplayPowerManagementSet, 0);
+#endif
+
+ pScrn->memPhysBase = pTrident->FbAddress;
+ pScrn->fbOffset = 0;
+
+#ifdef XvExtension
+ {
+ XF86VideoAdaptorPtr *ptr;
+ int n;
+
+ n = xf86XVListGenericAdaptors(&ptr);
+ if (n) {
+ xf86XVScreenInit(pScreen, ptr, n);
+ }
+ }
+#endif
+
+ pTrident->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = TRIDENTCloseScreen;
+ pScreen->SaveScreen = TRIDENTSaveScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+
+#if 0
+ TRIDENTI2CInit(pScreen);
+
+ xf86PrintEDID(xf86DoEDID_DDC2(pScrn->scrnIndex,pTrident->DDC));
+#endif
+
+ return TRUE;
+}
+
+
+/* Usually mandatory */
+static Bool
+TRIDENTSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return TRIDENTModeInit(xf86Screens[scrnIndex], mode);
+}
+
+
+/*
+ * This function is used to initialize the Start Address - the first
+ * displayed location in the video memory.
+ */
+/* Usually mandatory */
+static void
+TRIDENTAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ TRIDENTPtr pTrident;
+ vgaHWPtr hwp;
+ int base = y * pScrn->displayWidth + x;
+ int vgaIOBase;
+ CARD8 temp;
+
+ hwp = VGAHWPTR(pScrn);
+ pTrident = TRIDENTPTR(pScrn);
+ vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+
+ switch (pScrn->bitsPerPixel) {
+ case 4:
+ base >>= 3;
+ break;
+ case 8:
+ base = (base & 0xFFFFFFF8) >> 2;
+ break;
+ case 16:
+ base >>= 1;
+ break;
+ case 24:
+ base = (((base + 1) & ~0x03) * 3) >> 2;
+ break;
+ case 32:
+ break;
+ }
+
+ /* CRT bits 0-15 */
+ MMIO_OUTW(vgaIOBase + 4, (base & 0x00FF00) | 0x0C);
+ MMIO_OUTW(vgaIOBase + 4, ((base & 0x00FF) << 8) | 0x0D);
+ /* CRT bit 16 */
+ MMIO_OUTB(vgaIOBase + 4, CRTCModuleTest); temp = MMIO_INB(vgaIOBase + 5) & 0xDF;
+ MMIO_OUTB(vgaIOBase + 5, temp | ((base & 0x10000) >> 11));
+ /* CRT bit 17-19 */
+ MMIO_OUTB(vgaIOBase + 4, CRTHiOrd); temp = MMIO_INB(vgaIOBase + 5) & 0xF8;
+ MMIO_OUTB(vgaIOBase + 5, temp | ((base & 0xE0000) >> 17));
+}
+
+
+/*
+ * This is called when VT switching back to the X server. Its job is
+ * to reinitialise the video mode.
+ */
+
+/* Mandatory */
+static Bool
+TRIDENTEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ TRIDENTEnableMMIO(pScrn);
+
+ /* Should we re-save the text mode on each VT enter? */
+ if (!TRIDENTModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * This is called when VT switching away from the X server. Its job is
+ * to restore the previous (text) mode.
+ *
+ * We may wish to remap video/MMIO memory too.
+ */
+
+/* Mandatory */
+static void
+TRIDENTLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ TRIDENTRestore(pScrn);
+ vgaHWLock(hwp);
+ TRIDENTDisableMMIO(pScrn);
+}
+
+
+/*
+ * This is called at the end of each server generation. It restores the
+ * original (text) mode. It should really also unmap the video memory too.
+ */
+
+/* Mandatory */
+static Bool
+TRIDENTCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ if (pScrn->vtSema) {
+ TRIDENTRestore(pScrn);
+ vgaHWLock(hwp);
+ TRIDENTDisableMMIO(pScrn);
+ TRIDENTUnmapMem(pScrn);
+ }
+ if(pTrident->AccelInfoRec)
+ XAADestroyInfoRec(pTrident->AccelInfoRec);
+ if(pTrident->CursorInfoRec)
+ xf86DestroyCursorInfoRec(pTrident->CursorInfoRec);
+ pScrn->vtSema = FALSE;
+
+ pScreen->CloseScreen = pTrident->CloseScreen;
+ return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+}
+
+
+/* Free up any per-generation data structures */
+
+/* Optional */
+static void
+TRIDENTFreeScreen(int scrnIndex, int flags)
+{
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ RamDacFreeRec(xf86Screens[scrnIndex]);
+ TRIDENTFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+/* Checks if a mode is suitable for the selected chipset. */
+
+/* Optional */
+static int
+TRIDENTValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ return(MODE_OK);
+}
+
+/* Do screen blanking */
+
+/* Mandatory */
+static Bool
+TRIDENTSaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+ return vgaHWSaveScreen(pScreen, unblank);
+}
+
+static void
+TRIDENTEnableMMIO(ScrnInfoPtr pScrn)
+{
+ int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+ CARD8 temp = 0;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ /* Goto New Mode */
+ outb(0x3C4, 0x0B); inb(0x3C5);
+
+ /* Unprotect registers */
+ outb(0x3C4, NewMode1); temp = inb(0x3C5);
+ outb(0x3C5, 0xC0);
+
+ /* Enable MMIO */
+ outb(vgaIOBase + 4, PCIReg); pTrident->REGPCIReg = inb(vgaIOBase + 5);
+ outb(vgaIOBase + 5, pTrident->REGPCIReg | 0x01); /* Enable it */
+
+ /* Protect registers */
+ MMIO_OUTB(0x3C4, NewMode1);
+ MMIO_OUTB(0x3C5, temp);
+}
+
+static void
+TRIDENTDisableMMIO(ScrnInfoPtr pScrn)
+{
+ int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+ CARD8 temp = 0;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+
+ /* Goto New Mode */
+ MMIO_OUTB(0x3C4, 0x0B); temp = MMIO_INB(0x3C5);
+
+ /* Unprotect registers */
+ MMIO_OUTB(0x3C4, NewMode1); temp = MMIO_INB(0x3C5);
+ MMIO_OUTB(0x3C5, 0xC0);
+
+ /* Disable MMIO access */
+ MMIO_OUTB(vgaIOBase + 4, PCIReg);
+ pTrident->REGPCIReg = MMIO_INB(vgaIOBase + 5);
+ MMIO_OUTB(vgaIOBase + 5, pTrident->REGPCIReg & 0xFE);
+
+ /* Protect registers */
+ outb(0x3C4, NewMode1);
+ outb(0x3C5, temp);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_i2c.c b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_i2c.c
new file mode 100644
index 000000000..f0b3a26ea
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_i2c.c
@@ -0,0 +1,77 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_i2c.c,v 1.3 1999/04/25 10:02:31 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+
+#include "vgaHW.h"
+
+#include "trident.h"
+#include "trident_regs.h"
+
+static void
+TRIDENTI2CPutBits(I2CBusPtr b, int clock, int data) {
+ unsigned int reg = 0x0C;
+ TRIDENTPtr pTrident = ((TRIDENTPtr)b->DriverPrivate.ptr);
+ int vgaIOBase = VGAHWPTR(pTrident->pScrn)->IOBase;
+
+#if 0
+ if(!TRIDENTI2CSwitchToBus(b))
+ return FALSE;
+#endif
+
+ if(clock) reg |= 2;
+ if(data) reg |= 1;
+ MMIO_OUTB(vgaIOBase + 4, I2C);
+ MMIO_OUTB(vgaIOBase + 5, reg);
+#if 0
+ ErrorF("TRIDENTI2CPutBits: %d %d\n", clock, data);
+#endif
+}
+
+static void
+TRIDENTI2CGetBits(I2CBusPtr b, int *clock, int *data) {
+ unsigned int reg;
+ TRIDENTPtr pTrident = ((TRIDENTPtr)b->DriverPrivate.ptr);
+ int vgaIOBase = VGAHWPTR(pTrident->pScrn)->IOBase;
+
+#if 0
+ if(!TRIDENTI2CSwitchToBus(b))
+ return FALSE;
+#endif
+
+ MMIO_OUTB(vgaIOBase + 4, I2C);
+ reg = MMIO_INB(vgaIOBase + 5);
+ *clock = (reg & 0x02) != 0;
+ *data = (reg & 0x01) != 0;
+#if 0
+ ErrorF("TRIDENTI2CGetBits: %d %d\n", *clock, *data);
+#endif
+}
+
+Bool
+TRIDENTI2CInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ I2CBusPtr I2CPtr;
+
+ I2CPtr = xf86CreateI2CBusRec();
+
+ pTrident->DDC = I2CPtr;
+
+ I2CPtr->BusName = "DDC";
+ I2CPtr->scrnIndex = pScrn->scrnIndex;
+ I2CPtr->I2CPutBits = TRIDENTI2CPutBits;
+ I2CPtr->I2CGetBits = TRIDENTI2CGetBits;
+ I2CPtr->DriverPrivate.ptr = pTrident;
+
+ if(!xf86I2CBusInit(I2CPtr))
+ return FALSE;
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_regs.h b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_regs.h
new file mode 100644
index 000000000..7f7f540cf
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/trident/trident_regs.h
@@ -0,0 +1,304 @@
+/*
+ * Copyright 1992-1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_regs.h,v 1.8 1999/06/20 07:14:37 dawes Exp $ */
+
+#define NTSC 14.31818
+#define PAL 17.73448
+
+/* General Registers */
+#define SPR 0x1F /* Software Programming Register (videoram) */
+
+/* 3C4 */
+#define RevisionID 0x09
+#define ConfPort 0x0C
+#define NewMode2 0x0D
+#define OldMode2 0x0D
+#define OldMode1 0x0E
+#define NewMode1 0x0E
+#define MCLKLow 0x16
+#define MCLKHigh 0x17
+#define ClockLow 0x18
+#define ClockHigh 0x19
+
+/* 3x4 */
+#define Offset 0x13
+#define CRTCModuleTest 0x1E
+#define FIFOControl 0x20
+#define LinearAddReg 0x21
+#define DRAMTiming 0x23
+#define CRTHiOrd 0x27
+#define AddColReg 0x29
+#define InterfaceSel 0x2A
+#define GETest 0x2D
+#define Performance 0x2F
+#define GraphEngReg 0x36
+#define I2C 0x37
+#define PixelBusReg 0x38
+#define PCIReg 0x39
+#define DRAMControl 0x3A
+#define CursorXLow 0x40
+#define CursorXHigh 0x41
+#define CursorYLow 0x42
+#define CursorYHigh 0x43
+#define CursorLocLow 0x44
+#define CursorLocHigh 0x45
+#define CursorXOffset 0x46
+#define CursorYOffset 0x47
+#define CursorFG1 0x48
+#define CursorFG2 0x49
+#define CursorFG3 0x4A
+#define CursorFG4 0x4B
+#define CursorBG1 0x4C
+#define CursorBG2 0x4D
+#define CursorBG3 0x4E
+#define CursorBG4 0x4F
+#define CursorControl 0x50
+#define PCIRetry 0x55
+#define PCIMaster 0x60
+#define Enhancement0 0x62
+#define NewEDO 0x64
+#define TVinterface 0xC0
+#define TVMode 0xC1
+#define ClockControl 0xCF
+
+/* 3CE */
+#define MiscExtFunc 0x0F
+#define MiscIntContReg 0x2F
+
+/* Graphics Engine for 9420/9430 */
+
+#define GER_INDEX 0x210A
+#define GER_BYTE0 0x210C
+#define GER_BYTE1 0x210D
+#define GER_BYTE2 0x210E
+#define GER_BYTE3 0x210F
+#define MMIOBASE 0x7C
+#define OLDGER_STATUS 0x90
+#define OLDGER_MWIDTH 0xB8
+#define OLDGER_MFORMAT 0xBC
+#define OLDGER_STYLE 0xC4
+#define OLDGER_FMIX 0xC8
+#define OLDGER_BMIX 0xC8
+#define OLDGER_FCOLOUR 0xD8
+#define OLDGER_BCOLOUR 0xDC
+#define OLDGER_DIMXY 0xE0
+#define OLDGER_DESTLINEAR 0xE4
+#define OLDGER_DESTXY 0xF8
+#define OLDGER_COMMAND 0xFC
+#define OLDGE_FILL 0x000A0000 /* Area Fill */
+
+/* Graphics Engine for 9440/9660/9680 */
+
+#define GER_STATUS 0x2120
+#define GE_BUSY 0x80
+#define GER_OPERMODE 0x2122 /* Byte for 9440, Word for 96xx */
+#define DST_ENABLE 0x200 /* Destination Transparency */
+#define GER_COMMAND 0x2124
+#define GE_NOP 0x00 /* No Operation */
+#define GE_BLT 0x01 /* BitBLT ROP3 only */
+#define GE_BLT_ROP4 0x02 /* BitBLT ROP4 (96xx only) */
+#define GE_SCANLINE 0x03 /* Scan Line */
+#define GE_BRESLINE 0x04 /* Bresenham Line */
+#define GE_SHVECTOR 0x05 /* Short Vector */
+#define GE_FASTLINE 0x06 /* Fast Line (96xx only) */
+#define GE_TRAPEZ 0x07 /* Trapezoidal fill (96xx only) */
+#define GE_ELLIPSE 0x08 /* Ellipse (96xx only) (RES) */
+#define GE_ELLIP_FILL 0x09 /* Ellipse Fill (96xx only) (RES)*/
+#define GER_FMIX 0x2127
+#define GER_DRAWFLAG 0x2128 /* long */
+#define FASTMODE 1<<28
+#define STENCIL 0x8000
+#define SOLIDFILL 0x4000
+#define TRANS_ENABLE 0x1000
+#define TRANS_REVERSE 0x2000
+#define YMAJ 0x0400
+#define XNEG 0x0200
+#define YNEG 0x0100
+#define SRCMONO 0x0040
+#define PATMONO 0x0020
+#define SCR2SCR 0x0004
+#define PAT2SCR 0x0002
+#define GER_FCOLOUR 0x212C /* Word for 9440, long for 96xx */
+#define GER_BCOLOUR 0x2130 /* Word for 9440, long for 96xx */
+#define GER_PATLOC 0x2134 /* Word */
+#define GER_DEST_XY 0x2138
+#define GER_DEST_X 0x2138 /* Word */
+#define GER_DEST_Y 0x213A /* Word */
+#define GER_SRC_XY 0x213C
+#define GER_SRC_X 0x213C /* Word */
+#define GER_SRC_Y 0x213E /* Word */
+#define GER_DIM_XY 0x2140
+#define GER_DIM_X 0x2140 /* Word */
+#define GER_DIM_Y 0x2142 /* Word */
+#define GER_CKEY 0x2168 /* Long */
+#define GER_FPATCOL 0x2178
+#define GER_BPATCOL 0x217C
+#define GER_PATTERN 0x2180 /* from 0x2180 to 0x21FF */
+
+/* Additional - Graphics Engine for 96xx */
+#define GER_SRCCLIP_XY 0x2148
+#define GER_SRCCLIP_X 0x2148 /* Word */
+#define GER_SRCCLIP_Y 0x214A /* Word */
+#define GER_DSTCLIP_XY 0x214C
+#define GER_DSTCLIP_X 0x214C /* Word */
+#define GER_DSTCLIP_Y 0x214E /* Word */
+
+/* Defines for IMAGE Graphics Engine */
+#define IMAGE_GE_STATUS 0x2164
+#define IMAGE_GE_DRAWENV 0x2120
+
+/* Defines for BLADE Graphics Engine */
+#define BLADE_GE_STATUS 0x2120
+
+#define REPLICATE(x) \
+ if (pScrn->bitsPerPixel < 32) { \
+ x |= x << 16; \
+ if (pScrn->bitsPerPixel < 16) \
+ x |= x << 8; \
+ }
+
+#define CHECKCLIPPING \
+ if (pTrident->Clipping) { \
+ pTrident->Clipping = FALSE; \
+ if (pTrident->Chipset < PROVIDIA9682) { \
+ TGUI_SRCCLIP_XY(0,0); \
+ TGUI_DSTCLIP_XY(4095,2047); \
+ } \
+ }
+
+
+/* Merge XY */
+#define XY_MERGE(x,y) \
+ ((((CARD32)(y)&0xFFFF) << 16) | ((CARD32)(x) & 0xffff))
+
+#define TRIDENT_WRITE_REG(v,r) \
+ (*(volatile CARD32 *)((char*)pTrident->IOBase+(r)) = (v))
+
+#define TRIDENT_READ_REG(r) \
+ *(volatile CARD32 *)((char*)pTrident->IOBase+(r))
+
+#define MMIO_OUTB(addr, data) \
+ (*(volatile CARD8 *)(pTrident->IOBase + (addr)) = (data))
+#define MMIO_OUTW(addr, data) \
+ (*(volatile CARD16 *)(pTrident->IOBase + (addr)) = (data))
+#define MMIO_INB(addr) \
+ *(volatile CARD8 *)(pTrident->IOBase + (addr))
+
+#define MMIO_OUTW_3C4(reg) \
+ MMIO_OUTW(0x3C4, (tridentReg->tridentRegs3C4[reg])<<8 | (reg))
+#define MMIO_OUTW_3CE(reg) \
+ MMIO_OUTW(0x3CE, (tridentReg->tridentRegs3CE[reg])<<8 | (reg))
+#define MMIO_OUTW_3x4(reg) \
+ MMIO_OUTW(vgaIOBase + 4, (tridentReg->tridentRegs3x4[reg])<<8 | (reg))
+#define MMIO_INB_3x4(reg) \
+ (MMIO_OUTB(vgaIOBase + 4, reg), \
+ tridentReg->tridentRegs3x4[reg] = MMIO_INB(vgaIOBase + 5))
+#define MMIO_INB_3C4(reg) \
+ (MMIO_OUTB(0x3C4, reg), \
+ tridentReg->tridentRegs3C4[reg] = MMIO_INB(0x3C5))
+#define MMIO_INB_3CE(reg) \
+ (MMIO_OUTB(0x3CE, reg), \
+ tridentReg->tridentRegs3CE[reg] = MMIO_INB(0x3CF))
+
+#define IMAGEBUSY(b) \
+ (b = (*(volatile CARD32 *)(pTrident->IOBase+IMAGE_GE_STATUS)) & 0xF0000000)
+#define BLADEBUSY(b) \
+ (b = (*(volatile CARD32 *)(pTrident->IOBase+BLADE_GE_STATUS)) & 0xFE800000)
+#define BLTBUSY(b) \
+ (b = (*(volatile CARD8 *)(pTrident->IOBase+GER_STATUS)) & GE_BUSY)
+#define OLDBLTBUSY(b) \
+ (b = (*(volatile CARD8 *)(pTrident->IOBase+OLDGER_STATUS))&GE_BUSY)
+#define IMAGE_STATUS(c) \
+ (*(volatile CARD32 *)(pTrident->IOBase + IMAGE_GE_STATUS) = (c))
+#define TGUI_STATUS(c) \
+ (*(volatile CARD8 *)(pTrident->IOBase + GER_STATUS) = (c))
+#define OLDTGUI_STATUS(c) \
+ (*(volatile CARD8 *)(pTrident->IOBase + OLDGER_STATUS) = (c))
+#define TGUI_OPERMODE(c) \
+ (*(volatile CARD16 *)(pTrident->IOBase + GER_OPERMODE) = (c))
+/* XXX */
+#define OLDTGUI_OPERMODE(c) \
+ { \
+ *(CARD16 *)(pTrident->IOBase + OLDGER_MWIDTH) = \
+ vga256InfoRec.displayWidth - 1; \
+ *(CARD8 *)(pTrident->IOBase + OLDGER_MFORMAT) = c; \
+ }
+#define TGUI_FCOLOUR(c) \
+ (*(volatile CARD32 *)(pTrident->IOBase + GER_FCOLOUR) = (c))
+#define TGUI_FPATCOL(c) \
+ (*(volatile CARD32 *)(pTrident->IOBase + GER_FPATCOL) = (c))
+#define OLDTGUI_FCOLOUR(c) \
+ (*(volatile CARD32 *)(pTrident->IOBase + OLDGER_FCOLOUR) = (c))
+#define TGUI_BCOLOUR(c) \
+ (*(volatile CARD32 *)(pTrident->IOBase + GER_BCOLOUR) = (c))
+#define TGUI_BPATCOL(c) \
+ (*(volatile CARD32 *)(pTrident->IOBase + GER_BPATCOL) = (c))
+#define OLDTGUI_BCOLOUR(c) \
+ (*(volatile CARD32 *)(pTrident->IOBase + OLDGER_BCOLOUR) = (c))
+#define IMAGE_DRAWENV(c) \
+ (*(volatile CARD32 *)(pTrident->IOBase + IMAGE_GE_DRAWENV) = (c))
+#define TGUI_DRAWFLAG(c) \
+ (*(volatile CARD32 *)(pTrident->IOBase + GER_DRAWFLAG) = (c))
+#define OLDTGUI_STYLE(c) \
+ (*(volatile CARD16 *)(pTrident->IOBase + OLDGER_STYLE) = (c))
+#define TGUI_FMIX(c) \
+ (*(volatile CARD8 *)(pTrident->IOBase + GER_FMIX) = (c))
+#define OLDTGUI_FMIX(c) \
+ (*(volatile CARD8 *)(pTrident->IOBase + OLDGER_FMIX) = (c))
+#define OLDTGUI_BMIX(c) \
+ (*(volatile CARD8 *)(pTrident->IOBase + OLDGER_BMIX) = (c))
+#define TGUI_DIM_XY(w,h) \
+ (*(volatile CARD32 *)(pTrident->IOBase + GER_DIM_XY) = XY_MERGE((w)-1,(h)-1))
+#define OLDTGUI_DIMXY(w,h) \
+ (*(volatile CARD32 *)(pTrident->IOBase + OLDGER_DIMXY) = XY_MERGE((w)-1,(h)-1))
+#define TGUI_SRC_XY(x,y) \
+ (*(volatile CARD32 *)(pTrident->IOBase + GER_SRC_XY) = XY_MERGE(x,y))
+#define TGUI_DEST_XY(x,y) \
+ (*(volatile CARD32 *)(pTrident->IOBase + GER_DEST_XY) = XY_MERGE(x,y))
+#define OLDTGUI_DESTXY(x,y) \
+ (*(volatile CARD32 *)(pTrident->IOBase + OLDGER_DESTXY) = XY_MERGE(x,y))
+#define OLDTGUI_DESTLINEAR(c) \
+ (*(volatile CARD32 *)(pTrident->IOBase + OLDGER_DESTLINEAR) = (c))
+#define TGUI_SRCCLIP_XY(x,y) \
+ (*(volatile CARD32 *)(pTrident->IOBase + GER_SRCCLIP_XY) = XY_MERGE(x,y))
+#define TGUI_DSTCLIP_XY(x,y) \
+ (*(volatile CARD32 *)(pTrident->IOBase + GER_DSTCLIP_XY) = XY_MERGE(x,y))
+#define TGUI_PATLOC(addr) \
+ (*(volatile CARD16 *)(pTrident->IOBase +GER_PATLOC) = (addr))
+#define TGUI_CKEY(c) \
+ (*(volatile CARD32 *)(pTrident->IOBase + GER_CKEY) = (c))
+#define IMAGE_OUT(addr, c) \
+ (*(volatile CARD32 *)(pTrident->IOBase + addr) = (c))
+#define BLADE_OUT(addr, c) \
+ (*(volatile CARD32 *)(pTrident->IOBase + addr) = (c))
+#define TGUI_OUTL(addr, c) \
+ (*(volatile CARD32 *)(pTrident->IOBase + addr) = (c))
+#define TGUI_COMMAND(c) \
+ (*(volatile CARD8 *)(pTrident->IOBase + GER_COMMAND) = (c))
+#define OLDTGUI_COMMAND(c) \
+ do { \
+ OLDTGUI_OPERMODE(GE_OP); \
+ OLDTGUISync(); \
+ *(volatile CARD32 *)(pTrident->IOBase + OLDGER_COMMAND) = (c); \
+ } while (0)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/tridenthelper.c b/xc/programs/Xserver/hw/xfree86/drivers/trident/tridenthelper.c
new file mode 100644
index 000000000..2356307d9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/trident/tridenthelper.c
@@ -0,0 +1,256 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/tridenthelper.c,v 1.9 1999/06/20 07:14:39 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Version.h"
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "vgaHW.h"
+
+#include "trident.h"
+#include "trident_regs.h"
+
+static void IsClearTV(ScrnInfoPtr pScrn);
+
+void
+TGUISetClock(ScrnInfoPtr pScrn, int clock, CARD8 *a, CARD8 *b)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int powerup[4] = { 1,2,4,8 };
+ int clock_diff = 750;
+ int freq, ffreq;
+ int m, n, k;
+ int p, q, r, s;
+ int startn, endn;
+ int endm, endk;
+
+ p = q = r = s = 0;
+
+ IsClearTV(pScrn);
+
+ if (pTrident->NewClockCode)
+ {
+ startn = 64;
+ endn = 255;
+ endm = 63;
+ endk = 3;
+ }
+ else
+ {
+ startn = 0;
+ endn = 121;
+ endm = 31;
+ endk = 1;
+ }
+
+ freq = clock;
+
+ for (k=0;k<=endk;k++)
+ for (n=startn;n<=endn;n++)
+ for (m=1;m<=endm;m++)
+ {
+ ffreq = ( ( ((n + 8) * pTrident->frequency) / ((m + 2) * powerup[k]) ) * 1000);
+ if ((ffreq > freq - clock_diff) && (ffreq < freq + clock_diff))
+ {
+/*
+ * It seems that the 9440 docs have this STRICT limitation, although
+ * most 9440 boards seem to cope. 96xx/Cyber chips don't need this limit
+ * so, I'm gonna remove it and it allows lower clocks < 25.175 too !
+ */
+#ifdef STRICT
+ if ( (n+8)*100/(m+2) < 978 && (n+8)*100/(m+2) > 349 ) {
+#endif
+ clock_diff = (freq > ffreq) ? freq - ffreq : ffreq - freq;
+ p = n; q = m; r = k; s = ffreq;
+#ifdef STRICT
+ }
+#endif
+ }
+ }
+
+ if (s == 0)
+ {
+ FatalError("Unable to set programmable clock.\n"
+ "Frequency %d is not a valid clock.\n"
+ "Please modify XF86Config for a new clock.\n",
+ freq);
+ }
+
+ if (pTrident->NewClockCode)
+ {
+ /* N is all 8bits */
+ *a = p;
+ /* M is first 6bits, with K last 2bits */
+ *b = (q & 0x3F) | (r << 6);
+ }
+ else
+ {
+ /* N is first 7bits, first M bit is 8th bit */
+ *a = ((1 & q) << 7) | p;
+ /* first 4bits are rest of M, 1bit for K value */
+ *b = (((q & 0xFE) >> 1) | (r << 4));
+ }
+}
+
+static void
+IsClearTV(ScrnInfoPtr pScrn)
+{
+ int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ CARD8 temp;
+
+ if (pTrident->frequency != 0) return;
+
+ MMIO_OUTB(vgaIOBase + 4, 0xC0);
+ temp = MMIO_INB(vgaIOBase + 5);
+ if (temp & 0x80)
+ pTrident->frequency = PAL;
+ else
+ pTrident->frequency = NTSC;
+}
+
+float
+CalculateMCLK(ScrnInfoPtr pScrn)
+{
+ int vgaIOBase = VGAHWPTR(pScrn)->IOBase;
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int a,b;
+ int m,n,k;
+ float freq = 0.0;
+ int powerup[4] = { 1,2,4,8 };
+ CARD8 temp;
+
+ if (pTrident->HasSGRAM) {
+ MMIO_OUTB(vgaIOBase + 4, 0x28);
+ switch(MMIO_INB(vgaIOBase + 5) & 0x07) {
+ case 0:
+ freq = 60;
+ break;
+ case 1:
+ freq = 78;
+ break;
+ case 2:
+ freq = 90;
+ break;
+ case 3:
+ freq = 120;
+ break;
+ case 4:
+ freq = 66;
+ break;
+ case 5:
+ freq = 83;
+ break;
+ case 6:
+ freq = 100;
+ break;
+ case 7:
+ freq = 132;
+ break;
+ }
+ } else {
+ MMIO_OUTB(0x3C4, NewMode1);
+ temp = MMIO_INB(0x3C5);
+
+ MMIO_OUTB(0x3C5, 0xC2);
+ if (!Is3Dchip) {
+ a = MMIO_INB(0x43C6);
+ b = MMIO_INB(0x43C7);
+ } else {
+ MMIO_OUTB(0x3C4, 0x16);
+ a = MMIO_INB(0x3C5);
+ MMIO_OUTB(0x3C4, 0x17);
+ b = MMIO_INB(0x3C5);
+ }
+
+ MMIO_OUTB(0x3C4, NewMode1);
+ MMIO_OUTB(0x3C5, temp);
+
+ IsClearTV(pScrn);
+
+ if (pTrident->NewClockCode) {
+ m = b & 0x3F;
+ n = a;
+ k = (b & 0xC0) >> 6;
+ } else {
+ m = (a & 0x07);
+ k = (b & 0x02) >> 1;
+ n = ((a & 0xF8)>>3)|((b&0x01)<<5);
+ }
+
+ freq = ((n+8)*pTrident->frequency)/((m+2)*powerup[k]);
+ }
+ return (freq);
+}
+
+void
+TGUISetMCLK(ScrnInfoPtr pScrn, int clock, CARD8 *a, CARD8 *b)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ int powerup[4] = { 1,2,4,8 };
+ int clock_diff = 750;
+ int freq, ffreq;
+ int m,n,k;
+ int p, q, r, s;
+ int startn, endn;
+ int endm, endk;
+
+ p = q = r = s = 0;
+
+ IsClearTV(pScrn);
+
+ if (pTrident->NewClockCode)
+ {
+ startn = 64;
+ endn = 255;
+ endm = 63;
+ endk = 3;
+ }
+ else
+ {
+ startn = 0;
+ endn = 121;
+ endm = 31;
+ endk = 1;
+ }
+
+ freq = clock;
+
+ if (!pTrident->HasSGRAM) {
+ for (k=0;k<=endk;k++)
+ for (n=startn;n<=endn;n++)
+ for (m=1;m<=endm;m++) {
+ ffreq = ((((n+8)*pTrident->frequency)/((m+2)*powerup[k]))*1000);
+ if ((ffreq > freq - clock_diff) && (ffreq < freq + clock_diff))
+ {
+ clock_diff = (freq > ffreq) ? freq - ffreq : ffreq - freq;
+ p = n; q = m; r = k; s = ffreq;
+ }
+ }
+
+ if (s == 0)
+ {
+ FatalError("Unable to set memory clock.\n"
+ "Frequency %d is not a valid clock.\n"
+ "Please modify XF86Config for a new clock.\n",
+ freq);
+ }
+
+ if (pTrident->NewClockCode)
+ {
+ /* N is all 8bits */
+ *a = p;
+ /* M is first 6bits, with K last 2bits */
+ *b = (q & 0x3F) | (r << 6);
+ }
+ else
+ {
+ /* N is first 7bits, first M bit is 8th bit */
+ *a = ((1 & q) << 7) | p;
+ /* first 4bits are rest of M, 1bit for K value */
+ *b = (((q & 0xFE) >> 1) | (r << 4));
+ }
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/trident/tridentramdac.c b/xc/programs/Xserver/hw/xfree86/drivers/trident/tridentramdac.c
new file mode 100644
index 000000000..2fc50c015
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/trident/tridentramdac.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * TridentOutIndReg() and TridentInIndReg() are used to access
+ * the indirect Trident RAMDAC registers only.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/tridentramdac.c,v 1.3 1999/04/25 10:02:32 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "trident_regs.h"
+#include "trident.h"
+
+void
+TridentWriteAddress(ScrnInfoPtr pScrn, CARD32 index)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ MMIO_OUTB(0x3C6, 0xFF);
+ MMIO_OUTB(0x3C8, index);
+}
+
+void
+TridentWriteData(ScrnInfoPtr pScrn, unsigned char data)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ MMIO_OUTB(0x3C9, data);
+}
+
+void
+TridentReadAddress(ScrnInfoPtr pScrn, CARD32 index)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ MMIO_OUTB(0x3C6, 0xFF);
+ MMIO_OUTB(0x3C7, index);
+}
+
+unsigned char
+TridentReadData(ScrnInfoPtr pScrn)
+{
+ TRIDENTPtr pTrident = TRIDENTPTR(pScrn);
+ return(MMIO_INB(0x3C9));
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tseng/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/tseng/Imakefile
new file mode 100644
index 000000000..8955b339b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tseng/Imakefile
@@ -0,0 +1,63 @@
+XCOMM $XConsortium: Imakefile /main/10 1996/09/28 17:29:32 rws $
+
+
+
+
+
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/Imakefile,v 1.13 1999/08/14 10:49:56 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = tseng_driver.c tseng_ramdac.c tseng_bank.c tseng_clock.c \
+ tseng_accel.c tseng_acl.c tseng_colexp.c tseng_cursor.c \
+ tseng_dpms.c
+
+OBJS = tseng_driver.o tseng_ramdac.o tseng_bank.o tseng_clock.o \
+ tseng_accel.o tseng_acl.o tseng_colexp.o tseng_cursor.o \
+ tseng_dpms.o
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \
+ -I$(XF86SRC)/xf1bpp -I$(XF86SRC)/xf4bpp \
+ -I$(XF86SRC)/xf24_32bpp \
+ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \
+ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
+ -I$(XF86SRC)/rac \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(FONTINCSRC)
+#endif
+
+DEFINES = -DPSZ=8
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+NormalAsmObjectRule()
+
+ModuleObjectRule()
+
+ObjectModuleTarget(tseng, $(OBJS))
+
+InstallObjectModule(tseng,$(MODULEDIR),drivers)
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/tseng)
+InstallDriverSDKNonExecFile(tseng.h,$(DRIVERSDKDIR)/drivers/tseng)
+InstallDriverSDKNonExecFile(tseng_accel.c,$(DRIVERSDKDIR)/drivers/tseng)
+InstallDriverSDKNonExecFile(tseng_acl.c,$(DRIVERSDKDIR)/drivers/tseng)
+InstallDriverSDKNonExecFile(tseng_acl.h,$(DRIVERSDKDIR)/drivers/tseng)
+InstallDriverSDKNonExecFile(tseng_bank.c,$(DRIVERSDKDIR)/drivers/tseng)
+InstallDriverSDKNonExecFile(tseng_clock.c,$(DRIVERSDKDIR)/drivers/tseng)
+InstallDriverSDKNonExecFile(tseng_colexp.c,$(DRIVERSDKDIR)/drivers/tseng)
+InstallDriverSDKNonExecFile(tseng_cursor.c,$(DRIVERSDKDIR)/drivers/tseng)
+InstallDriverSDKNonExecFile(tseng_dpms.c,$(DRIVERSDKDIR)/drivers/tseng)
+InstallDriverSDKNonExecFile(tseng_driver.c,$(DRIVERSDKDIR)/drivers/tseng)
+InstallDriverSDKNonExecFile(tseng_inline.h,$(DRIVERSDKDIR)/drivers/tseng)
+InstallDriverSDKNonExecFile(tseng_ramdac.c,$(DRIVERSDKDIR)/drivers/tseng)
+
+InstallDriverSDKObjectModule(tseng,$(DRIVERSDKMODULEDIR),drivers)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tseng/README b/xc/programs/Xserver/hw/xfree86/drivers/tseng/README
new file mode 100644
index 000000000..ab3e57d47
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tseng/README
@@ -0,0 +1,264 @@
+
+
+This file is NOT up to date for the New Design!
+
+
+
+
+============== old (pre-ND) contents below ==============
+
+"I just thought it would be usefull if we had some kind of TODO and BUGS
+files in the distribution as it would make it easier to see what is needed
+to be done and what could be done better, instead of browsing through the
+sourcecode. And we whould be able to se the progress literally by the ever
+decreasing TODO file :-)"
+
+
+## BUGS:
+
+All Tseng cards:
+
+* We definitely NEED to fix that color-expansion problem. See Appendix A
+below for a detailed explanation.
+
+* There are still some problems with the HW-cursor. The error message about
+"wrong color selected" is disabled, and the limitation documented. Better
+would be to have a way to dynamically switch to software-cursor mode if the
+color can not be made. HW cursor doesn't work in DoubleScan modes yet (only
+half of the cursor displayed)
+
+* text font sometimes corrupted when going back to text mode. This may be
+related to the order in which registers are restored: the ARK driver first
+restores extended registers before restoring the standard registers for
+excactly this reason.
+
+* The code needs to be heavily reworked to fix all sorts of data type
+problems. The current code will certainly not run on an Alpha. The first
+step is to replace all hardware related variables by CARD8/CARD16/CARD32
+types.
+
+
+ET6000:
+
+* The trapezoid code is disabled because it doesn't comply with the way the
+non-accelerated ("cfb") code does things. This needs to be fixed.
+
+
+ET-4000(W32):
+
+* Hardware cursor support for the W32 is still lacking color support. We
+need to reserve color cells #0 and #255 to make this work. From discussions
+on the development list, it seems the best solution is to allocate these cells
+read-write, and then use them for the HW cursor. We MUST however document
+that this will break some clients which depend on a fixed color in cell #0,
+and some others that rely on the presence of 256 color cells. It will also
+cause cursor color problems when someone uses a local color map.
+
+
+## TODO:
+
+All cards:
+
+* The accelerator on the Tseng devices is capable of much more. Especially
+the pattern support is not used most of the time: It can render a pattern in
+just about every accelerated operation. This means patterned lines, bitblts,
+screencopies, etc. are possible. However, operations like these are very
+uncommon in normal server use, so the speed benefit would go largely unnoticed.
+
+
+ET4000:
+
+* support needs to be added for several clockchips and RAMDACs:
+ - 8-bit RAMDAC support for >8bpp modes: Sierra DACs and possibly others
+ - AT&T 20C49x RAMDAC support is not correct.
+
+* SuperProbe could use an update. It doesn't detect some of the RAMDACs that
+are detected by the driver.
+
+* Several of the color expansion-related accelerations are still only 8bpp.
+It should be easy to use the same trick on those as on the standard color
+expand code (use intermediate buffer, expand data before blitting).
+
+* many of the operations that the W32 family can't support natively (e.g.
+FillRectSolid for 24bpp) can be performed using CPU-to-screen operations,
+feeding the correct (color) information through the ACL aperture.
+
+
+ET6000:
+
+* someone might want to look at how the bitBLT engine of the ET6000 is
+constructed, and come up with some fancy ways of abusing it. We're still
+only using a small part of it (I'm thinking about the compare map and the
+extensions to the MIX hardware compared to the ET4000).
+
+* Mclk support is still lacking (that would also allow MClk-dependent
+maximum bandwidth).
+
+* Apart from the things mentionned above, I think the ET6000 server is
+pretty complete. Some optimisations could possibly be added. Like for
+example some assembler code for calculating a framebuffer address from X/Y
+coordinates. That would help to speed up small blits.
+
+
+=======================================================================
+APPENDIX A: the color expansion problem
+----------------------------------------
+
+As suggested in the data book, we're doing font rendering using the
+color-expansion (MIX map) capabilities of the Tseng accelerator.
+
+We're using a ping-pong buffer scheme (triple buffering actually) in
+off-screen memory to store one scanline worth of font data at a time. each
+of these scanlines is "blitted" to on-screen memory using the accelerator.
+The scanline is the MIX map, and there's also a 4x1 solid foreground color
+(SRC map), and a 4x1 solid background color (PAT map).
+
+Basically, the flow is as follows:
+
+ - setup accelerator for font-expansion
+
+ - store scanline 1 in off-screen memory buffer 1
+
+ - start operation
+
+ - store scanline 2 in off-screen memory buffer 2
+
+ - start operation
+
+ - store scanline 3 in off-screen memory buffer 3
+
+ - start operation
+
+ - store scanline 4 in off-screen memory buffer 1
+
+ - start operation
+
+ ... etc, until the whole line of text is drawn.
+
+There is no explicit "waiting" for the accelerator to finish an operation
+before starting a new one, because it has been set up to add "wait-states"
+when the queue is full. We're aiming to use concurrency between the
+accelerator and the storing of scanlines in the buffers. Anyway, waiting
+after each operation doesn't help.
+
+Now, in 99% of all cases, text is rendered OK. But in some cases, we're
+seeing severe font corruption.
+
+What we're seeing is this: sometimes, exactly 32 pixels of a scanline are
+rendered with the scanline data that was there BEFORE, instead of the one
+that was just written into the scanline buffer. In other words, 32 pixels of
+line 2 (for example) are rendered at line 5. The rest of the scanline can be
+OK (i.e. data from scanline 5 is actually written there).
+
+Here's an attempt at showing you what _should_ have been rendered:
+
+1
+2 #####################################################################
+3
+4
+5
+6 #####################################################################
+7
+8
+9
+10 #####################################################################
+11
+12
+13
+14 #####################################################################
+15
+
+
+
+and what _is_ rendered sometimes (only an example):
+
+1
+2 #####################################################################
+3
+4
+5
+6 ######################## #############
+7
+8
+9
+10 #####################################################################
+11
+12
+13 ########################
+14 #####################################################################
+15
+
+At line 6, 32 pixels of the "black" scanline data from line 3 is rendered
+instead of the actual full-white that would normally have to be there. At
+line 13, the opposite happened (data from line 10 rendered at line 13). This
+32-pixel width of the "bug" is independent of the color depth: we're seeing
+this at 8bpp as well as at 16bpp, 24bpp and 32bpp. 32 pixels each time.
+
+Remember, we're talking triple-buffering here, so the "wrongly" rendered
+data is in fact the data that was in the scanline-buffer from the PREVIOUS
+operation that used that buffer.
+
+In fact, my best explanation is that sometimes, a whole DWORD (32 bits) of
+data isn't in the video memory yet by the time the accelerator starts
+rendering with it.
+
+But the data _is_ being written to there by the driver software, because if
+you restart the scanline-operation again, without writing any more data to
+the scanline buffers (only the MIX address and the destination address are
+reprogrammed to restart the scanline color expansion operation -- see code
+in tseng_acl.c), data _is_ rendered correctly.
+
+
+
+I have investigated this as far as I possibly can. I checked if the data was
+actually written in video memory. It was. I checked all kinds of PCI-related
+things, like write-gathering or write-reordering of the PCI chipset, etc. I
+disabled all possible enhanced features, both on the PCI chipset, inside the
+CPU, and on the ET6000.
+
+What strikes me, is that the exact same problems are seen on ET4000W32p as
+on the ET6000. This immediately rules out any special features that were
+only added with the ET6000, like problems with the MDRAM cache buffers, etc.
+It seems to be a generic problem to all Tseng accelerators.
+
+The exact same higher-level code is being used for other chipsets as well
+(i.e. the system of writing scanlines of data to off-screen memory and
+making the accelerator expand it into on-screen memory), and there are no
+problems on these other chipsets. The acceleration architecture we're using
+is completely device-independent up to the point where each chip needs to
+provide a
+
+ SetupForScanlineScreenToScreenColorExpand()
+
+and a
+
+ SubsequentScanlineScreenToScreenColorExpand()
+function.
+
+Since the higher-level code is being used by other chip drivers as well, it
+seems to be OK.
+
+So the problem is either in those device-dependent functions, or in the
+hardware itself.
+
+
+I have found one kludge to work around this problem, and it should (?) tell
+you a lot about the problem: if I start each scanline-colorexpand operation
+TWICE, rendering is suddenly perfect (at least there are so little rendering
+errors that I haven't seen any yet).
+
+
+I am including the two device-depending functions so that you may be able to
+follow what I'm saying here:
+
+
+
+One entire line of text is drawn by calling the Setup() function ONCE. All
+scanlines of text (16 of them in case of a 8x16 font) are drawn by filling
+the off-screen scanline buffers and calling the Subsequent() function.
+
+
+
+
+
+$XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/README,v 1.11 1998/07/25 16:55:59 dawes Exp $
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng.h b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng.h
new file mode 100644
index 000000000..2d8ea0082
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng.h
@@ -0,0 +1,357 @@
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng.h,v 1.27 1999/06/12 07:18:57 dawes Exp $ */
+
+
+
+
+
+#ifndef _TSENG_H
+#define _TSENG_H
+
+/* Everything using inb/outb, etc needs "compiler.h" */
+#include "compiler.h"
+
+/* All drivers should typically include these */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+/* All drivers need this */
+#include "xf86_ansic.h"
+
+/* This is used for module versioning */
+#include "xf86Version.h"
+
+/* Drivers for PCI hardware need this */
+#include "xf86PciInfo.h"
+
+/* Drivers that need to access the PCI config space directly need this */
+#include "xf86Pci.h"
+
+/* All drivers using the vgahw module need this */
+/* All Tseng chips _need_ VGA register access, so multihead operation is out of the question */
+#include "vgaHW.h"
+
+/* Drivers using the mi banking wrapper need this */
+#include "mibank.h"
+
+/* All drivers using the mi colormap manipulation need this */
+#include "micmap.h"
+
+/* Needed for the 1 and 4 bpp framebuffers */
+#include "xf1bpp.h"
+#include "xf4bpp.h"
+
+/* Drivers using cfb need this */
+
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+
+/* Drivers supporting bpp 16, 24 or 32 with cfb need these */
+
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+
+/* Drivers using the XAA interface ... */
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xf86Cursor.h"
+#include "xf86fbman.h"
+
+
+/* functions in tseng_driver.c needed outside it */
+void TsengBlankScreen(ScrnInfoPtr pScrn, Bool unblank);
+void TsengProtect(ScrnInfoPtr pScrn, Bool on);
+
+
+#define MAX_TSENG_CLOCK 86000 /* default max clock for standard boards */
+
+/*
+ * Contrary to the old driver, we use the "Chip Revision" here intead of
+ * multiple chipsets like "TYPE_ET4000W32Pa", "TYPE_ET4000W32Pb", etc.
+ */
+
+typedef enum {
+ TYPE_ET4000,
+ TYPE_ET4000W32,
+ TYPE_ET4000W32I,
+ TYPE_ET4000W32P,
+ TYPE_ET6000,
+ TYPE_ET6100
+} t_tseng_type;
+
+/* revision ID for W32 chips: currently used for W32i and W32p */
+typedef enum {
+ TSENGNOREV = 0,
+ W32REVID_A,
+ W32REVID_B,
+ W32REVID_C,
+ W32REVID_D
+} t_w32_revid;
+
+#define ET6100REVID (0x70)
+
+typedef enum {
+ T_BUS_ISA,
+ T_BUS_MCA,
+ T_BUS_VLB,
+ T_BUS_PCI
+} t_tseng_bus;
+
+extern SymTabRec TsengDacTable[];
+
+typedef enum {
+ UNKNOWN_DAC = -1,
+ NORMAL_DAC,
+ ATT20C47xA_DAC,
+ Sierra1502X_DAC,
+ ATT20C497_DAC,
+ ATT20C490_DAC,
+ ATT20C493_DAC,
+ ATT20C491_DAC,
+ ATT20C492_DAC,
+ ICS5341_DAC,
+ ICS5301_DAC,
+ STG1700_DAC,
+ STG1702_DAC,
+ STG1703_DAC,
+ ET6000_DAC,
+ CH8398_DAC,
+ MUSIC4910_DAC
+} t_ramdactype;
+
+typedef enum {
+ CLOCKCHIP_ICD2061A,
+ CLOCKCHIP_ET6000,
+ CLOCKCHIP_ICS5341,
+ CLOCKCHIP_ICS5301,
+ CLOCKCHIP_CH8398,
+ CLOCKCHIP_STG1703
+} t_clockchip_type;
+
+typedef enum {
+ TSENG_MODE_NORMAL,
+ TSENG_MODE_PIXMUX,
+ TSENG_MODE_DACBUS16
+} t_clockrange_type;
+
+typedef struct {
+ unsigned char cmd_reg;
+ unsigned char f2_M;
+ unsigned char f2_N;
+ unsigned char ctrl;
+ unsigned char w_idx;
+ unsigned char r_idx;
+ unsigned char timingctrl; /* for STG170x */
+ unsigned char MClkM;
+ unsigned char dummy; /* FIXME!!! : someone overwrites saved MClkN without this */
+ unsigned char MClkN; /* PLL M/N values for MemClk programming */
+} PllState;
+
+typedef struct {
+ unsigned char ExtCRTC[16]; /* CRTC 0x30 .. 0x3F */
+ unsigned char ExtTS[2]; /* TS 0x06 .. 0x07 */
+ unsigned char ExtATC; /* ATC 0x16 */
+ unsigned char ExtSegSel[2]; /* 0x3CD , 0x3CB */
+ unsigned char ExtET6K[0x4F]; /* ET6000 PCI config space registers 0x40 .. 0x8F */
+ unsigned char ExtIMACtrl; /* IMA port control register (0x217B index 0xF7) */
+ PllState pll; /* registers in GenDAC-like RAMDAC/clockchips */
+ unsigned char ATTdac_cmd; /* command register for ATT 49x DACs */
+} TsengRegRec, *TsengRegPtr;
+
+typedef struct {
+ Bool Programmable; /* MemClk is programmable if set */
+ Bool Set; /* reprogram MClk if TRUE */
+ int MemClk; /* MemClk value in kHz */
+ int min, max; /* MemClk limits */
+} TsengMClkInfoRec, *TsengMclkInfoPtr;
+
+typedef struct {
+ t_ramdactype DacType;
+ Bool NotAttCompat; /* avoid treating the RAMDAC as AT&T compatible */
+ int RamdacShift; /* typically 10 or 8 for 6- or 8-bit dac */
+ int RamdacMask; /* typically 0x3f for 6 bit, 0xff for 8-bit ramdac */
+ Bool Dac8Bit; /* dac is 8 bit instead of the default 6 bit */
+ Bool DacPort16; /* Ramdac port is 16 bits wide instead of default 8 */
+} TsengDacInfoRec, *TsengDacInfoPtr;
+
+typedef struct {
+ /* we'll put variables that we want to access _fast_ at the beginning (just a hunch) */
+ unsigned char cache_SegSelL, cache_SegSelH; /* for tseng_bank.c */
+ int Bytesperpixel; /* a shorthand for the XAA code */
+ Bool need_wait_acl; /* always need a full "WAIT" for ACL finish */
+ int line_width; /* framebuffer width in bytes per scanline */
+ int planemask_mask; /* mask for active bits in planemask */
+ int neg_x_pixel_offset;
+ int powerPerPixel; /* power-of-2 version of bytesperpixel */
+ unsigned char *BresenhamTable;
+ /* normal stuff starts here */
+ pciVideoPtr PciInfo;
+ PCITAG PciTag;
+ int Save_Divide;
+ Bool UsePCIRetry; /* Do we use PCI-retry or busy-waiting */
+ Bool UseAccel; /* Do we use the XAA acceleration architecture */
+ Bool HWCursor; /* Do we use the hardware cursor (if supported) */
+ Bool Linmem_1meg; /* Is this a card limited to 1Mb of linear memory */
+ Bool UseLinMem;
+ Bool SlowDram;
+ Bool FastDram;
+ Bool MedDram;
+ Bool SetPCIBurst;
+ Bool PCIBurst;
+ Bool SetW32Interleave;
+ Bool W32Interleave;
+ Bool ShowCache;
+ Bool Legend; /* Sigma Legend clock select method */
+ Bool NoClockchip; /* disable clockchip programming clockchip (=use set-of-clocks) */
+ TsengRegRec SavedReg; /* saved Tseng registers at server start */
+ TsengRegRec ModeReg;
+ unsigned long icd2061_dwv; /* To hold the clock data between Init and Restore */
+ t_tseng_bus Bustype; /* W32 bus type (currently used for lin mem on W32i) */
+ t_tseng_type ChipType; /* "Chipset" causes confusion with pScrn->chipset */
+ int ChipRev;
+ CARD32 LinFbAddress;
+ unsigned char *FbBase;
+ CARD32 LinFbAddressMask;
+ long FbMapSize;
+ miBankInfoRec BankInfo;
+ CARD32 IOAddress; /* PCI config space base address for ET6000 */
+ CARD32 MMIOBase;
+ int MinClock;
+ int MaxClock;
+ int MemClk;
+ ClockRangePtr clockRange[2];
+ TsengDacInfoRec DacInfo;
+ TsengMClkInfoRec MClkInfo;
+ t_clockchip_type ClockChip;
+ int max_vco_freq; /* max internal VCO frequency */
+ CloseScreenProcPtr CloseScreen;
+ int save_divide;
+ XAAInfoRecPtr AccelInfoRec;
+ xf86CursorInfoPtr CursorInfoRec;
+ CARD32 AccelColorBufferOffset; /* offset in video memory where FG and BG colors will be stored */
+ CARD32 AccelColorExpandBufferOffsets[3]; /* offset in video memory for ColorExpand buffers */
+ unsigned char * XAAColorExpandBuffers[3]; /* pointers to colorexpand buffers */
+ CARD32 AccelImageWriteBufferOffsets[2]; /* offset in video memory for ImageWrite Buffers */
+ unsigned char * XAAScanlineImageWriteBuffers[2]; /* pointers to ImageWrite Buffers */
+ CARD32 HWCursorBufferOffset;
+ unsigned char *HWCursorBuffer;
+ unsigned char * XAAScanlineColorExpandBuffers[1];
+ CARD32* ColExpLUT;
+ EntityInfoPtr pEnt;
+} TsengRec, *TsengPtr;
+
+#define TsengPTR(p) ((TsengPtr)((p)->driverPrivate))
+
+#define Is_stdET4K ( pTseng->ChipType == TYPE_ET4000 )
+#define Is_W32 ( pTseng->ChipType == TYPE_ET4000W32 )
+#define Is_W32i ( pTseng->ChipType == TYPE_ET4000W32I )
+#define Is_W32p ( pTseng->ChipType == TYPE_ET4000W32P)
+#define Is_ET6000 ( pTseng->ChipType == TYPE_ET6000 )
+#define Is_ET6100 ( pTseng->ChipType == TYPE_ET6100 )
+
+#define Is_W32_W32i ( Is_W32 || Is_W32i )
+#define Is_W32_any ( Is_W32 || Is_W32i || Is_W32p )
+#define Is_W32p_ab ( Is_W32p && ( (pTseng->ChipRev == W32REVID_A) || (pTseng->ChipRev == W32REVID_B) ) )
+#define Is_W32p_cd ( Is_W32p && ( (pTseng->ChipRev == W32REVID_C) || (pTseng->ChipRev == W32REVID_D) ) )
+#define Is_ET6K ( Is_ET6000 || Is_ET6100 )
+
+#define CHIP_SUPPORTS_LINEAR ( Is_W32i || Is_W32p || Is_ET6K )
+
+#define DAC_IS_ATT49x ( (pTseng->DacInfo.DacType == ATT20C490_DAC) \
+ || (pTseng->DacInfo.DacType == ATT20C491_DAC) \
+ || (pTseng->DacInfo.DacType == ATT20C492_DAC) \
+ || (pTseng->DacInfo.DacType == ATT20C493_DAC) \
+ || (pTseng->DacInfo.DacType == MUSIC4910_DAC) )
+
+#define DAC_is_GenDAC ( (pTseng->DacInfo.DacType == ICS5341_DAC) \
+ || (pTseng->DacInfo.DacType == ICS5301_DAC) )
+
+#define DAC_is_STG170x ( (pTseng->DacInfo.DacType == STG1700_DAC) \
+ || (pTseng->DacInfo.DacType == STG1702_DAC) \
+ || (pTseng->DacInfo.DacType == STG1703_DAC) )
+
+#define DAC_IS_CHRONTEL (pTseng->DacInfo.DacType == CH8398_DAC)
+
+#define Gendac_programmable_clock \
+ ( pScrn->progClock && \
+ ( (pTseng->ClockChip == CLOCKCHIP_ICS5341) \
+ || (pTseng->ClockChip == CLOCKCHIP_ICS5301) \
+ ) \
+ )
+
+#define STG170x_programmable_clock \
+ ( pScrn->progClock && (pTseng->ClockChip == CLOCKCHIP_STG1703) )
+
+#define ICD2061a_programmable_clock \
+ ( pScrn->progClock && (pTseng->ClockChip == CLOCKCHIP_ICD2061A) )
+
+#define CH8398_programmable_clock \
+ ( pScrn->progClock && (pTseng->ClockChip == CLOCKCHIP_CH8398) )
+
+#define ET6000_programmable_clock \
+ ( pScrn->progClock && (pTseng->ClockChip == CLOCKCHIP_ET6000) )
+
+/*
+ * From tseng_bank.c
+ */
+
+int ET4000SetRead(ScreenPtr pScrn, unsigned int iBank);
+int ET4000SetWrite(ScreenPtr pScrn, unsigned int iBank);
+int ET4000SetReadWrite(ScreenPtr pScrn, unsigned int iBank);
+int ET4000W32SetRead(ScreenPtr pScrn, unsigned int iBank);
+int ET4000W32SetWrite(ScreenPtr pScrn, unsigned int iBank);
+int ET4000W32SetReadWrite(ScreenPtr pScrn, unsigned int iBank);
+
+/*
+ * From tseng_clocks.c
+ */
+
+Bool Tseng_check_clockchip(ScrnInfoPtr pScrn);
+void tseng_clock_setup(ScrnInfoPtr pScrn);
+void TsengcommonCalcClock(long freq,
+ int min_m, int min_n1, int max_n1, int min_n2, int max_n2,
+ long freq_min, long freq_max,
+ unsigned char *mdiv, unsigned char *ndiv);
+
+/*
+ * From tseng_ramdac.c
+ */
+
+void tseng_dactopel(void);
+unsigned char tseng_dactocomm(void);
+unsigned char tseng_getdaccomm(void);
+void tseng_setdaccomm(unsigned char comm);
+
+Bool Check_Tseng_Ramdac(ScrnInfoPtr pScrn);
+void tseng_set_ramdac_bpp(ScrnInfoPtr pScrn, DisplayModePtr mode);
+
+/*
+ * From tseng_cursor.c
+ */
+
+Bool TsengHWCursorInit(ScreenPtr pScreen);
+
+/*
+ * From tseng_dpms.c
+ */
+
+#ifdef DPMSExtension
+void TsengHVSyncDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
+void TsengCrtcDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
+#endif
+
+/*
+ * For debugging
+ */
+
+#undef TSENG_DEBUG
+
+#ifdef TSENG_DEBUG
+#define PDEBUG(arg) do { ErrorF(arg); } while (0)
+#else
+#define PDEBUG(arg) do {} while (0)
+#endif
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_accel.c
new file mode 100644
index 000000000..79ad50a71
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_accel.c
@@ -0,0 +1,942 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_accel.c,v 1.29 1999/06/12 07:18:57 dawes Exp $ */
+
+
+
+
+
+
+/*
+ * ET4/6K acceleration interface.
+ *
+ * Uses Harm Hanemaayer's generic acceleration interface (XAA).
+ *
+ * Author: Koen Gadeyne
+ *
+ * Much of the acceleration code is based on the XF86_W32 server code from
+ * Glenn Lai.
+ *
+ */
+
+/*
+ * if NO_OPTIMIZE is set, some optimizations are disabled.
+ *
+ * What it basically tries to do is minimize the amounts of writes to
+ * accelerator registers, since these are the ones that slow down small
+ * operations a lot.
+ */
+
+#define NO_OPTIMIZE
+
+/*
+ * if ET6K_TRANSPARENCY is set, ScreentoScreenCopy operations (and pattern
+ * fills) will support transparency. But then the planemask support has to
+ * be dropped. The default here is to support planemasks, because all Tseng
+ * chips can do this. Only the ET6000 supports a transparency compare. The
+ * code could be easily changed to support transparency on the ET6000 and
+ * planemasks on the others, but that's only useful when transparency is
+ * more important than planemasks.
+ */
+
+#undef ET6K_TRANSPARENCY
+
+#include "tseng.h"
+#include "tseng_acl.h"
+#include "tseng_inline.h"
+
+#include "miline.h"
+
+void TsengSync(ScrnInfoPtr pScrn);
+
+void TsengSetupForSolidFill(ScrnInfoPtr pScrn,
+ int color, int rop, unsigned int planemask);
+void TsengW32iSubsequentSolidFillRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h);
+void TsengW32pSubsequentSolidFillRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h);
+void Tseng6KSubsequentSolidFillRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h);
+
+/* void TsengSubsequentFillTrapezoidSolid(); */
+
+void TsengSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int trans_color);
+void TsengSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int w, int h);
+
+void TsengSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty, int rop, unsigned int planemask, int trans_color);
+
+void TsengSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patx, int paty, int x, int y, int w, int h);
+
+void TsengSetupForScanlineImageWrite(ScrnInfoPtr pScrn,
+ int rop, unsigned int planemask, int trans_color, int bpp, int depth);
+
+void TsengSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft);
+
+void TsengSubsequentImageWriteScanline(ScrnInfoPtr pScrn,
+ int bufno);
+
+#if 0
+void TsengSetupForSolidLine(ScrnInfoPtr pScrn,
+ int color, int rop, unsigned int planemask);
+#endif
+
+void TsengSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
+ int x, int y, int major, int minor, int err, int len, int octant);
+
+
+/*
+ * The following function sets up the supported acceleration. Call it from
+ * the FbInit() function in the SVGA driver. Do NOT initialize any hardware
+ * in here. That belongs in tseng_init_acl().
+ */
+Bool
+TsengXAAInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TsengPtr pTseng = TsengPTR(pScrn);
+ XAAInfoRecPtr pXAAinfo;
+ BoxRec AvailFBArea;
+ int i;
+
+ PDEBUG(" TsengXAAInit\n");
+ pTseng->AccelInfoRec = pXAAinfo = XAACreateInfoRec();
+ if (!pXAAinfo)
+ return FALSE;
+
+ /*
+ * Set up the main acceleration flags.
+ */
+ pXAAinfo->Flags = PIXMAP_CACHE;
+
+#ifdef TODO
+ if (Tseng_bus != T_BUS_PCI)
+ pXAAinfo->Flags |= COP_FRAMEBUFFER_CONCURRENCY;
+#endif
+
+ /*
+ * The following line installs a "Sync" function, that waits for
+ * all coprocessor operations to complete.
+ */
+ pXAAinfo->Sync = TsengSync;
+
+ /* W32 and W32i must wait for ACL before changing registers */
+ pTseng->need_wait_acl = Is_W32_W32i;
+
+ pTseng->line_width = pScrn->displayWidth * pTseng->Bytesperpixel;
+
+#if 1
+ /*
+ * SolidFillRect.
+ *
+ * The W32 and W32i chips don't have a register to set the amount of
+ * bytes per pixel, and hence they don't skip 1 byte in each 4-byte word
+ * at 24bpp. Therefor, the FG or BG colors would have to be concatenated
+ * in video memory (R-G-B-R-G-B-... instead of R-G-B-X-R-G-B-X-..., with
+ * X = dont' care), plus a wrap value that is a multiple of 3 would have
+ * to be set. There is no such wrap combination available.
+ */
+#ifdef OBSOLETE
+ pXAAinfo->SolidFillFlags |= NO_PLANEMASK;
+#endif
+
+ if (!(Is_W32_W32i && (pScrn->bitsPerPixel == 24))) {
+ pXAAinfo->SetupForSolidFill = TsengSetupForSolidFill;
+ if (Is_ET6K) {
+ pXAAinfo->SubsequentSolidFillRect = Tseng6KSubsequentSolidFillRect;
+ } else if (Is_W32p)
+ pXAAinfo->SubsequentSolidFillRect = TsengW32pSubsequentSolidFillRect;
+ else /* W32, W32i */
+ pXAAinfo->SubsequentSolidFillRect = TsengW32iSubsequentSolidFillRect;
+ }
+#ifdef TSENG_TRAPEZOIDS
+ if (Is_ET6K) {
+ /* disabled for now: not fully compliant yet */
+ pXAAinfo->SubsequentFillTrapezoidSolid = TsengSubsequentFillTrapezoidSolid;
+ }
+#endif
+#endif
+
+#if 1
+ /*
+ * SceenToScreenCopy (BitBLT).
+ *
+ * Restrictions: On ET6000, we support EITHER a planemask OR
+ * TRANSPARENCY, but not both (they use the same Pattern map).
+ * All other chips can't do TRANSPARENCY at all.
+ */
+#ifdef ET6K_TRANSPARENCY
+ pXAAinfo->CopyAreaFlags = NO_PLANEMASK;
+ if (!Is_ET6K) {
+ pXAAinfo->CopyAreaFlags |= NO_TRANSPARENCY;
+ }
+#else
+ pXAAinfo->CopyAreaFlags = NO_TRANSPARENCY;
+#endif
+
+ pXAAinfo->SetupForScreenToScreenCopy =
+ TsengSetupForScreenToScreenCopy;
+ pXAAinfo->SubsequentScreenToScreenCopy =
+ TsengSubsequentScreenToScreenCopy;
+#endif
+
+#if 0
+ /*
+ * ImageWrite.
+ *
+ * SInce this uses off-screen scanline buffers, it is only of use when
+ * complex ROPs are used. But since the current XAA pixmap cache code
+ * only works when an ImageWrite is provided, the NO_GXCOPY flag is
+ * temporarily disabled.
+ */
+
+ if (pTseng->AccelImageWriteBufferOffsets[0]) {
+ pXAAinfo->ScanlineImageWriteFlags =
+ pXAAinfo->CopyAreaFlags | LEFT_EDGE_CLIPPING /* | NO_GXCOPY */ ;
+ pXAAinfo->NumScanlineImageWriteBuffers = 2;
+ pXAAinfo->SetupForScanlineImageWrite =
+ TsengSetupForScanlineImageWrite;
+ pXAAinfo->SubsequentScanlineImageWriteRect =
+ TsengSubsequentScanlineImageWriteRect;
+ pXAAinfo->SubsequentImageWriteScanline =
+ TsengSubsequentImageWriteScanline;
+
+ /* calculate memory addresses from video memory offsets */
+ for (i = 0; i < pXAAinfo->NumScanlineImageWriteBuffers; i++) {
+ pTseng->XAAScanlineImageWriteBuffers[i] =
+ pTseng->FbBase + pTseng->AccelImageWriteBufferOffsets[i];
+ }
+
+ /*
+ * for banked memory, translate those addresses to fall in the
+ * correct aperture. Imagewrite uses aperture #1, which sits at
+ * pTseng->FbBase + 0x1A000.
+ */
+ if (!pTseng->UseLinMem) {
+ for (i = 0; i < pXAAinfo->NumScanlineImageWriteBuffers; i++) {
+ pTseng->XAAScanlineImageWriteBuffers[i] =
+ pTseng->XAAScanlineImageWriteBuffers[i]
+ - pTseng->AccelImageWriteBufferOffsets[0]
+ + 0x1A000;
+ }
+ }
+ pXAAinfo->ScanlineImageWriteBuffers = pTseng->XAAScanlineImageWriteBuffers;
+ }
+#endif
+ /*
+ * 8x8 pattern tiling not possible on W32/i/p chips in 24bpp mode.
+ * Currently, 24bpp pattern tiling doesn't work at all on those.
+ *
+ * FIXME: On W32 cards, pattern tiling doesn't work as expected.
+ */
+ pXAAinfo->Color8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_ORIGIN;
+
+ pXAAinfo->CachePixelGranularity = 8 * 8;
+
+#ifdef ET6K_TRANSPARENCY
+ pXAAinfo->PatternFlags |= HARDWARE_PATTERN_NO_PLANEMASK;
+ if (Is_ET6K) {
+ pXAAinfo->PatternFlags |= HARDWARE_PATTERN_TRANSPARENCY;
+ }
+#endif
+
+#if 0
+ /* FIXME! This needs to be fixed for W32 and W32i (it "should work") */
+ if ((pScrn->bitsPerPixel != 24) && (Is_W32p || Is_ET6K)) {
+ pXAAinfo->SetupForColor8x8PatternFill =
+ TsengSetupForColor8x8PatternFill;
+ pXAAinfo->SubsequentColor8x8PatternFillRect =
+ TsengSubsequentColor8x8PatternFillRect;
+ }
+#endif
+
+#if 1
+ /*
+ * SolidLine.
+ *
+ * We use Bresenham by preference, because it supports hardware clipping
+ * (using the error term). TwoPointLines() is implemented, but not used,
+ * because clipped lines are not accelerated (hardware clipping support
+ * is lacking)...
+ */
+
+ if (Is_W32p || Is_ET6K) {
+ /*
+ * Fill in the hardware linedraw ACL_XY_DIRECTION table
+ *
+ * W32BresTable[] converts XAA interface Bresenham octants to direct
+ * ACL direction register contents. This includes the correct bias
+ * setting etc.
+ *
+ * According to miline.h (but with base 0 instead of base 1 as in
+ * miline.h), the octants are numbered as follows:
+ *
+ * \ | /
+ * \ 2 | 1 /
+ * \ | /
+ * 3 \ | / 0
+ * \|/
+ * -----------
+ * /|\
+ * 4 / | \ 7
+ * / | \
+ * / 5 | 6 \
+ * / | \
+ *
+ * In ACL_XY_DIRECTION, bits 2:0 are defined as follows:
+ * 0: '1' if XDECREASING
+ * 1: '1' if YDECREASING
+ * 2: '1' if XMAJOR (== not YMAJOR)
+ *
+ * Bit 4 defines the bias. It should be set to '1' for all octants
+ * NOT passed to miSetZeroLineBias(). i.e. the inverse of the X bias.
+ *
+ * (For MS compatible bias, the data book says to set to the same as
+ * YDIR, i.e. bit 1 of the same register, = '1' if YDECREASING. MS
+ * bias is towards octants 0..3 (i.e. Y decreasing), hence this
+ * definition of bit 4)
+ *
+ */
+ pTseng->BresenhamTable = xnfalloc(8);
+ if (pTseng->BresenhamTable == NULL) {
+ xf86Msg(X_ERROR, "Could not malloc Bresenham Table.\n");
+ return FALSE;
+ }
+ for (i=0; i<8; i++) {
+ unsigned char zerolinebias = miGetZeroLineBias(pScreen);
+ pTseng->BresenhamTable[i] = 0xA0; /* command=linedraw, use error term */
+ if (i & XDECREASING) pTseng->BresenhamTable[i] |= 0x01;
+ if (i & YDECREASING) pTseng->BresenhamTable[i] |= 0x02;
+ if (!(i & YMAJOR)) pTseng->BresenhamTable[i] |= 0x04;
+ if ((1 << i) & zerolinebias) pTseng->BresenhamTable[i] |= 0x10;
+ /* ErrorF("BresenhamTable[%d]=0x%x\n", i, pTseng->BresenhamTable[i]); */
+ }
+
+ pXAAinfo->SolidLineFlags = 0;
+ pXAAinfo->SetupForSolidLine = TsengSetupForSolidFill;
+ pXAAinfo->SubsequentSolidBresenhamLine =
+ TsengSubsequentSolidBresenhamLine;
+ /*
+ * ErrorTermBits is used to limit minor, major and error term, so it
+ * must be min(errorterm_size, delta_major_size, delta_minor_size)
+ * But the calculation for major and minor is done on the DOUBLED
+ * values (as per the Bresenham algorithm), so they can also have 13
+ * bits (inside XAA). They are divided by 2 in this driver, so they
+ * are then again limited to 12 bits.
+ */
+ pXAAinfo->SolidBresenhamLineErrorTermBits = 13;
+ }
+#endif
+
+#if 1
+ /* set up color expansion acceleration */
+ if (!TsengXAAInit_Colexp(pScrn))
+ return FALSE;
+#endif
+
+
+ /*
+ * For Tseng, we set up some often-used values
+ */
+
+ switch (pTseng->Bytesperpixel) { /* for MULBPP optimization */
+ case 1:
+ pTseng->powerPerPixel = 0;
+ pTseng->planemask_mask = 0x000000FF;
+ pTseng->neg_x_pixel_offset = 0;
+ break;
+ case 2:
+ pTseng->powerPerPixel = 1;
+ pTseng->planemask_mask = 0x0000FFFF;
+ pTseng->neg_x_pixel_offset = 1;
+ break;
+ case 3:
+ pTseng->powerPerPixel = 1;
+ pTseng->planemask_mask = 0x00FFFFFF;
+ pTseng->neg_x_pixel_offset = 2; /* is this correct ??? */
+ break;
+ case 4:
+ pTseng->powerPerPixel = 2;
+ pTseng->planemask_mask = 0xFFFFFFFF;
+ pTseng->neg_x_pixel_offset = 3;
+ break;
+ }
+
+ /*
+ * Init ping-pong registers.
+ * This might be obsoleted by the BACKGROUND_OPERATIONS flag.
+ */
+ tsengMemFg = MemW32ForegroundPing;
+ tsengFg = W32ForegroundPing;
+ tsengMemBg = MemW32BackgroundPing;
+ tsengBg = W32BackgroundPing;
+ tsengMemPat = MemW32PatternPing;
+ tsengPat = W32PatternPing;
+
+ /*
+ * Finally, we set up the video memory space available to the pixmap
+ * cache. In this case, all memory from the end of the virtual screen to
+ * the end of video memory minus 1K (which we already reserved), can be
+ * used.
+ */
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = pScrn->displayWidth;
+ AvailFBArea.y2 = (pScrn->videoRam * 1024) /
+ (pScrn->displayWidth * pTseng->Bytesperpixel);
+
+ xf86InitFBManager(pScreen, &AvailFBArea);
+
+ return (XAAInit(pScreen, pXAAinfo));
+
+}
+
+/*
+ * This is the implementation of the Sync() function.
+ *
+ * To avoid pipeline/cache/buffer flushing in the PCI subsystem and the VGA
+ * controller, we might replace this read-intensive code with a dummy
+ * accelerator operation that causes a hardware-blocking (wait-states) until
+ * the running operation is done.
+ */
+void
+TsengSync(ScrnInfoPtr pScrn)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ WAIT_ACL;
+}
+
+/*
+ * This is the implementation of the SetupForSolidFill function
+ * that sets up the coprocessor for a subsequent batch for solid
+ * rectangle fills.
+ */
+void
+TsengSetupForSolidFill(ScrnInfoPtr pScrn,
+ int color, int rop, unsigned int planemask)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ /*
+ * all registers are queued in the Tseng chips, except of course for the
+ * stuff we want to store in off-screen memory. So we have to use a
+ * ping-pong method for those if we want to avoid having to wait for the
+ * accelerator when we want to write to these.
+ */
+
+/* ErrorF("S"); */
+
+ PINGPONG();
+
+ wait_acl_queue(pTseng);
+
+ /*
+ * planemask emulation uses a modified "standard" FG ROP (see ET6000
+ * data book p 66 or W32p databook p 37: "Bit masking"). We only enable
+ * the planemask emulation when the planemask is not a no-op, because
+ * blitting speed would suffer.
+ */
+
+ if ((planemask & pTseng->planemask_mask) != pTseng->planemask_mask) {
+ SET_FG_ROP_PLANEMASK(rop);
+ SET_BG_COLOR(pTseng, planemask);
+ } else {
+ SET_FG_ROP(rop);
+ }
+ SET_FG_COLOR(pTseng, color);
+
+ SET_FUNCTION_BLT;
+}
+
+/*
+ * This is the implementation of the SubsequentForSolidFillRect function
+ * that sends commands to the coprocessor to fill a solid rectangle of
+ * the specified location and size, with the parameters from the SetUp
+ * call.
+ *
+ * Splitting it up between ET4000 and ET6000 avoids lots of chipset type
+ * comparisons.
+ */
+void
+TsengW32pSubsequentSolidFillRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+ int destaddr = FBADDR(pTseng, x, y);
+
+ wait_acl_queue(pTseng);
+
+ /*
+ * Restoring the ACL_SOURCE_ADDRESS here is needed as long as Bresenham
+ * lines are enabled for >8bpp. Or until XAA allows us to render
+ * horizontal lines using the same Bresenham code instead of re-routing
+ * them to FillRectSolid. For XDECREASING lines, the SubsequentBresenham
+ * code adjusts the ACL_SOURCE_ADDRESS to make sure XDECREASING lines
+ * are drawn with the correct colors. But if a batch of subsequent
+ * operations also holds a few horizontal lines, they will be routed to
+ * here without calling the SetupFor... code again, and the
+ * ACL_SOURCE_ADDRESS will be wrong.
+ */
+ *ACL_SOURCE_ADDRESS = tsengFg;
+
+ SET_XYDIR(0); /* FIXME: not needed with separate setupforsolidline */
+
+ SET_XY_4(pTseng, w, h);
+ START_ACL(pTseng, destaddr);
+}
+
+void
+TsengW32iSubsequentSolidFillRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+ int destaddr = FBADDR(pTseng, x, y);
+
+ wait_acl_queue(pTseng);
+
+ SET_XYDIR(0);
+
+ SET_XY_6(pTseng, w, h);
+ START_ACL(pTseng, destaddr);
+}
+
+void
+Tseng6KSubsequentSolidFillRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+ int destaddr = FBADDR(pTseng, x, y);
+
+ wait_acl_queue(pTseng);
+
+ /* see comment in TsengW32pSubsequentFillRectSolid */
+ *ACL_SOURCE_ADDRESS = tsengFg;
+
+ /* if XYDIR is not reset here, drawing a hardware line in between
+ * blitting, with the same ROP, color, etc will not cause a call to
+ * SetupFor... (because linedrawing uses SetupForSolidFill() as its
+ * Setup() function), and thus the direction register will have been
+ * changed by the last LineDraw operation.
+ */
+ SET_XYDIR(0);
+
+ SET_XY_6(pTseng, w, h);
+ START_ACL_6(destaddr);
+}
+
+/*
+ * This is the implementation of the SetupForScreenToScreenCopy function
+ * that sets up the coprocessor for a subsequent batch of
+ * screen-to-screen copies.
+ */
+
+static __inline__ void
+Tseng_setup_screencopy(TsengPtr pTseng,
+ int rop, unsigned int planemask,
+ int trans_color, int blit_dir)
+{
+ wait_acl_queue(pTseng);
+
+#ifdef ET6K_TRANSPARENCY
+ if (Is_ET6K && (trans_color != -1)) {
+ SET_BG_COLOR(trans_color);
+ SET_FUNCTION_BLT_TR;
+ } else
+ SET_FUNCTION_BLT;
+
+ SET_FG_ROP(rop);
+#else
+ if ((planemask & pTseng->planemask_mask) != pTseng->planemask_mask) {
+ SET_FG_ROP_PLANEMASK(rop);
+ SET_BG_COLOR(pTseng, planemask);
+ } else {
+ SET_FG_ROP(rop);
+ }
+ SET_FUNCTION_BLT;
+#endif
+ SET_XYDIR(blit_dir);
+}
+
+static int blitxdir, blitydir;
+
+void
+TsengSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int xdir, int ydir, int rop,
+ unsigned int planemask, int trans_color)
+{
+ /*
+ * xdir can be either 1 (left-to-right) or -1 (right-to-left).
+ * ydir can be either 1 (top-to-bottom) or -1 (bottom-to-top).
+ */
+
+ TsengPtr pTseng = TsengPTR(pScrn);
+ int blit_dir = 0;
+
+/* ErrorF("C%d ", trans_color); */
+
+ blitxdir = xdir;
+ blitydir = ydir;
+
+ if (xdir == -1)
+ blit_dir |= 0x1;
+ if (ydir == -1)
+ blit_dir |= 0x2;
+
+ Tseng_setup_screencopy(pTseng, rop, planemask, trans_color, blit_dir);
+
+ *ACL_SOURCE_WRAP = 0x77; /* no wrap */
+ *ACL_SOURCE_Y_OFFSET = pTseng->line_width - 1;
+}
+
+/*
+ * This is the implementation of the SubsequentForScreenToScreenCopy
+ * that sends commands to the coprocessor to perform a screen-to-screen
+ * copy of the specified areas, with the parameters from the SetUp call.
+ * In this sample implementation, the direction must be taken into
+ * account when calculating the addresses (with coordinates, it might be
+ * a little easier).
+ *
+ * Splitting up the SubsequentScreenToScreenCopy between ET4000 and ET6000
+ * doesn't seem to improve speed for small blits (as it did with
+ * SolidFillRect).
+ */
+
+void
+TsengSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2,
+ int w, int h)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+ int srcaddr, destaddr;
+
+ /*
+ * Optimizing note: the pre-calc code below (i.e. until the first
+ * register write) doesn't significantly affect performance. Removing it
+ * all boosts small blits from 24.22 to 25.47 MB/sec. Don't waste time
+ * on that. One less PCI bus write would boost us to 30.00 MB/sec, up
+ * from 24.22. Waste time on _that_...
+ */
+
+ /* tseng chips want x-sizes in bytes, not pixels */
+ x1 = MULBPP(pTseng, x1);
+ x2 = MULBPP(pTseng, x2);
+
+ /*
+ * If the direction is "decreasing", the chip wants the addresses
+ * to be at the other end, so we must be aware of that in our
+ * calculations.
+ */
+ if (blitydir == -1) {
+ srcaddr = (y1 + h - 1) * pTseng->line_width;
+ destaddr = (y2 + h - 1) * pTseng->line_width;
+ } else {
+ srcaddr = y1 * pTseng->line_width;
+ destaddr = y2 * pTseng->line_width;
+ }
+ if (blitxdir == -1) {
+ /* Accelerator start address must point to first byte to be processed.
+ * Depending on the direction, this is the first or the last byte
+ * in the multi-byte pixel.
+ */
+ int eol = MULBPP(pTseng, w);
+
+ srcaddr += x1 + eol - 1;
+ destaddr += x2 + eol - 1;
+ } else {
+ srcaddr += x1;
+ destaddr += x2;
+ }
+
+ wait_acl_queue(pTseng);
+
+ SET_XY(pTseng, w, h);
+ *ACL_SOURCE_ADDRESS = srcaddr;
+ START_ACL(pTseng, destaddr);
+}
+
+static int pat_src_addr;
+
+void
+TsengSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
+ int patx, int paty, int rop, unsigned int planemask, int trans_color)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ pat_src_addr = FBADDR(pTseng, patx, paty);
+
+ ErrorF("P");
+
+ Tseng_setup_screencopy(pTseng, rop, planemask, trans_color, 0);
+
+ switch (pTseng->Bytesperpixel) {
+ case 1:
+ *ACL_SOURCE_WRAP = 0x33; /* 8x8 wrap */
+ *ACL_SOURCE_Y_OFFSET = 8 - 1;
+ break;
+ case 2:
+ *ACL_SOURCE_WRAP = 0x34; /* 16x8 wrap */
+ *ACL_SOURCE_Y_OFFSET = 16 - 1;
+ break;
+ case 3:
+ *ACL_SOURCE_WRAP = 0x3D; /* 24x8 wrap --- only for ET6000 !!! */
+ *ACL_SOURCE_Y_OFFSET = 32 - 1; /* this is no error -- see databook */
+ break;
+ case 4:
+ *ACL_SOURCE_WRAP = 0x35; /* 32x8 wrap */
+ *ACL_SOURCE_Y_OFFSET = 32 - 1;
+ }
+}
+
+void
+TsengSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patx, int paty, int x, int y, int w, int h)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+ int destaddr = FBADDR(pTseng, x, y);
+ int srcaddr = pat_src_addr + MULBPP(pTseng, paty * 8 + patx);
+
+ wait_acl_queue(pTseng);
+
+ *ACL_SOURCE_ADDRESS = srcaddr;
+
+ SET_XY(pTseng, w, h);
+ START_ACL(pTseng, destaddr);
+}
+
+/*
+ * ImageWrite is nothing more than a per-scanline screencopy.
+ */
+
+void
+TsengSetupForScanlineImageWrite(ScrnInfoPtr pScrn,
+ int rop, unsigned int planemask, int trans_color, int bpp, int depth)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+/* ErrorF("IW"); */
+
+ Tseng_setup_screencopy(pTseng, rop, planemask, trans_color, 0);
+
+ *ACL_SOURCE_WRAP = 0x77; /* no wrap */
+ *ACL_SOURCE_Y_OFFSET = pTseng->line_width - 1;
+}
+
+static CARD32 iw_dest, iw_skipleft;
+
+void
+TsengSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+/* ErrorF("r%d",h); */
+
+ iw_dest = y * pTseng->line_width + MULBPP(pTseng, x);
+ iw_skipleft = MULBPP(pTseng, skipleft);
+
+ wait_acl_queue(pTseng);
+ SET_XY(pTseng, w, 1);
+}
+
+void
+TsengSubsequentImageWriteScanline(ScrnInfoPtr pScrn,
+ int bufno)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+/* ErrorF("%d", bufno); */
+
+ wait_acl_queue(pTseng);
+
+ *ACL_SOURCE_ADDRESS = pTseng->AccelImageWriteBufferOffsets[bufno] + iw_skipleft;
+ START_ACL(pTseng, iw_dest);
+ iw_dest += pTseng->line_width;
+}
+
+/*
+ * W32p/ET6000 hardware linedraw code.
+ *
+ * TsengSetupForSolidFill() is used as a setup function.
+ *
+ * Three major problems that needed to be solved here:
+ *
+ * 1. The "bias" value must be translated into the "line draw algorithm"
+ * parameter in the Tseng accelerators. This parameter, although not
+ * documented as such, needs to be set to the _inverse_ of the
+ * appropriate bias bit (i.e. for the appropriate octant).
+ *
+ * 2. In >8bpp modes, the accelerator will render BYTES in the same order as
+ * it is drawing the line. This means it will render the colors in the
+ * same order as well, reversing the byte-order in pixels that are drawn
+ * right-to-left. This causes wrong colors to be rendered.
+ *
+ * 3. The Tseng data book says that the ACL Y count register needs to be
+ * programmed with "dy-1". A similar thing is said about ACL X count. But
+ * this assumes (x2,y2) is NOT drawn (although that is not mentionned in
+ * the data book). X assumes the endpoint _is_ drawn. If "dy-1" is used,
+ * this sometimes results in a negative value (if dx==dy==0),
+ * causing a complete accelerator hang.
+ */
+
+void
+TsengSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
+ int x, int y, int major, int minor, int err, int len, int octant)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+ int destaddr = FBADDR(pTseng, x, y);
+ int xydir = pTseng->BresenhamTable[octant];
+
+ /* Tseng wants the real dx/dy in major/minor. Bresenham uses 2*dx and 2*dy */
+ minor >>= 1;
+ major >>= 1;
+
+ wait_acl_queue(pTseng);
+
+ if (!(octant & YMAJOR)) {
+ SET_X_YRAW(pTseng, len, 0xFFF);
+ } else {
+ SET_XY_RAW(0xFFF, len - 1);
+ }
+
+ SET_DELTA(minor, major);
+ *ACL_ERROR_TERM = -err; /* error term from XAA is NEGATIVE */
+
+ /* make sure colors are rendered correctly if >8bpp */
+ if (octant & XDECREASING) {
+ destaddr += pTseng->Bytesperpixel - 1;
+ *ACL_SOURCE_ADDRESS = tsengFg + pTseng->neg_x_pixel_offset;
+ } else
+ *ACL_SOURCE_ADDRESS = tsengFg;
+
+ SET_XYDIR(xydir);
+
+ START_ACL(pTseng, destaddr);
+}
+
+
+#ifdef TODO
+/*
+ * Trapezoid filling code.
+ *
+ * TsengSetupForSolidFill() is used as a setup function
+ */
+
+#undef DEBUG_TRAP
+
+#ifdef TSENG_TRAPEZOIDS
+void
+TsengSubsequentFillTrapezoidSolid(ytop, height, left, dxL, dyL, eL, right, dxR, dyR, eR)
+ int ytop;
+ int height;
+ int left;
+ int dxL, dyL;
+ int eL;
+ int right;
+ int dxR, dyR;
+ int eR;
+{
+ unsigned int tseng_bias_compensate = 0xd8;
+ int destaddr, algrthm;
+ int xcount = right - left + 1; /* both edges included */
+ int dir_reg = 0x60; /* trapezoid drawing; use error term for primary edge */
+ int sec_dir_reg = 0x20; /* use error term for secondary edge */
+ int octant = 0;
+
+ /* ErrorF("#"); */
+
+ int destaddr, algrthm;
+ int xcount = right - left + 1;
+
+#ifdef USE_ERROR_TERM
+ int dir_reg = 0x60;
+ int sec_dir_reg = 0x20;
+
+#else
+ int dir_reg = 0x40;
+ int sec_dir_reg = 0x00;
+
+#endif
+ int octant = 0;
+ int bias = 0x00; /* FIXME !!! */
+
+/* ErrorF("#"); */
+
+#ifdef DEBUG_TRAP
+ ErrorF("ytop=%d, height=%d, left=%d, dxL=%d, dyL=%d, eL=%d, right=%d, dxR=%d, dyR=%d, eR=%d ",
+ ytop, height, left, dxL, dyL, eL, right, dxR, dyR, eR);
+#endif
+
+ if ((dyL < 0) || (dyR < 0))
+ ErrorF("Tseng Trapezoids: Wrong assumption: dyL/R < 0\n");
+
+ destaddr = FBADDR(pTseng, left, ytop);
+
+ /* left edge */
+ if (dxL < 0) {
+ dir_reg |= 1;
+ octant |= XDECREASING;
+ dxL = -dxL;
+ }
+ /* Y direction is always positive (top-to-bottom drawing) */
+
+ wait_acl_queue(pTseng);
+
+ /* left edge */
+ /* compute axial direction and load registers */
+ if (dxL >= dyL) { /* X is major axis */
+ dir_reg |= 4;
+ SET_DELTA(dyL, dxL);
+ if (dir_reg & 1) { /* edge coherency: draw left edge */
+ destaddr += pTseng->Bytesperpixel;
+ sec_dir_reg |= 0x80;
+ xcount--;
+ }
+ } else { /* Y is major axis */
+ SetYMajorOctant(octant);
+ SET_DELTA(dxL, dyL);
+ }
+ *ACL_ERROR_TERM = eL;
+
+ /* select "linedraw algorithm" (=bias) and load direction register */
+ /* ErrorF(" o=%d ", octant); */
+ algrthm = ((tseng_bias_compensate >> octant) & 1) ^ 1;
+ dir_reg |= algrthm << 4;
+ SET_XYDIR(dir_reg);
+
+ /* right edge */
+ if (dxR < 0) {
+ sec_dir_reg |= 1;
+ dxR = -dxR;
+ }
+ /* compute axial direction and load registers */
+ if (dxR >= dyR) { /* X is major axis */
+ sec_dir_reg |= 4;
+ SET_SECONDARY_DELTA(dyR, dxR);
+ if (dir_reg & 1) { /* edge coherency: do not draw right edge */
+ sec_dir_reg |= 0x40;
+ xcount++;
+ }
+ } else { /* Y is major axis */
+ SET_SECONDARY_DELTA(dxR, dyR);
+ }
+ *ACL_SECONDARY_ERROR_TERM = eR;
+
+ /* ErrorF("%02x", sec_dir_reg); */
+ SET_SECONDARY_XYDIR(sec_dir_reg);
+
+ SET_XY_6(pTseng, xcount, height);
+
+#ifdef DEBUG_TRAP
+ ErrorF("-> %d,%d\n", xcount, height);
+#endif
+
+ START_ACL_6(destaddr);
+}
+#endif
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_acl.c b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_acl.c
new file mode 100644
index 000000000..0a7c9d7aa
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_acl.c
@@ -0,0 +1,402 @@
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_acl.c,v 1.21 1998/09/05 06:36:55 dawes Exp $ */
+
+
+
+
+
+#include "tseng.h"
+#include "tseng_acl.h"
+
+void tseng_terminate_acl(TsengPtr pTseng);
+
+ByteP W32Buffer;
+
+LongP MBP0, MBP1, MBP2;
+ByteP MMU_CONTROL;
+
+ByteP ACL_SUSPEND_TERMINATE, ACL_OPERATION_STATE, ACL_SYNC_ENABLE, ACL_WRITE_INTERFACE_VALID,
+ ACL_INTERRUPT_MASK, ACL_INTERRUPT_STATUS, ACL_ACCELERATOR_STATUS;
+
+WordP ACL_X_POSITION, ACL_Y_POSITION;
+
+WordP ACL_NQ_X_POSITION, ACL_NQ_Y_POSITION;
+
+LongP ACL_PATTERN_ADDRESS, ACL_SOURCE_ADDRESS;
+
+WordP ACL_PATTERN_Y_OFFSET, ACL_SOURCE_Y_OFFSET, ACL_DESTINATION_Y_OFFSET;
+
+ByteP ACL_VIRTUAL_BUS_SIZE, /* only for w32 and w32i */
+ ACL_XY_DIRECTION, /* only for w32 and w32i */
+ ACL_PIXEL_DEPTH; /* only for w32p_rev_A and w32p_rev_B */
+
+ByteP ACL_PATTERN_WRAP, ACL_SOURCE_WRAP;
+
+WordP ACL_X_COUNT, ACL_Y_COUNT;
+LongP ACL_XY_COUNT; /* for combined writes to X and Y count registers */
+
+ByteP ACL_ROUTING_CONTROL, ACL_RELOAD_CONTROL, ACL_BACKGROUND_RASTER_OPERATION,
+ ACL_FOREGROUND_RASTER_OPERATION;
+
+LongP ACL_DESTINATION_ADDRESS, /* only for w32p_rev_A and w32p_rev_B */
+ ACL_MIX_ADDRESS;
+
+WordP ACL_MIX_Y_OFFSET, ACL_ERROR_TERM, ACL_DELTA_MINOR, ACL_DELTA_MAJOR;
+
+/* for ET6000 only */
+ByteP ACL_POWER_CONTROL;
+
+ByteP ACL_SECONDARY_EDGE;
+WordP ACL_SECONDARY_ERROR_TERM, ACL_SECONDARY_DELTA_MINOR, ACL_SECONDARY_DELTA_MAJOR;
+ByteP ACL_TRANSFER_DISABLE;
+
+ByteP W32BytePtr;
+WordP W32WordPtr;
+LongP W32LongPtr;
+
+/*
+ * conversion from X ROPs to Microsoft ROPs.
+ */
+
+int W32OpTable[] =
+{
+ 0x00, /* Xclear 0 */
+ 0x88, /* Xand src AND dst */
+ 0x44, /* XandReverse src AND NOT dst */
+ 0xcc, /* Xcopy src */
+ 0x22, /* XandInverted NOT src AND dst */
+ 0xaa, /* Xnoop dst */
+ 0x66, /* Xxor src XOR dst */
+ 0xee, /* Xor src OR dst */
+ 0x11, /* Xnor NOT src AND NOT dst */
+ 0x99, /* Xequiv NOT src XOR dst */
+ 0x55, /* Xinvert NOT dst */
+ 0xdd, /* XorReverse src OR NOT dst */
+ 0x33, /* XcopyInverted NOT src */
+ 0xbb, /* XorInverted NOT src OR dst */
+ 0x77, /* Xnand NOT src OR NOT dst */
+ 0xff /* Xset 1 */
+};
+
+int W32OpTable_planemask[] =
+{
+ 0x0a, /* Xclear 0 */
+ 0x8a, /* Xand src AND dst */
+ 0x4a, /* XandReverse src AND NOT dst */
+ 0xca, /* Xcopy src */
+ 0x2a, /* XandInverted NOT src AND dst */
+ 0xaa, /* Xnoop dst */
+ 0x6a, /* Xxor src XOR dst */
+ 0xea, /* Xor src OR dst */
+ 0x1a, /* Xnor NOT src AND NOT dst */
+ 0x9a, /* Xequiv NOT src XOR dst */
+ 0x5a, /* Xinvert NOT dst */
+ 0xda, /* XorReverse src OR NOT dst */
+ 0x3a, /* XcopyInverted NOT src */
+ 0xba, /* XorInverted NOT src OR dst */
+ 0x7a, /* Xnand NOT src OR NOT dst */
+ 0xfa /* Xset 1 */
+};
+
+int W32PatternOpTable[] =
+{
+ 0x00, /* Xclear 0 */
+ 0xa0, /* Xand pat AND dst */
+ 0x50, /* XandReverse pat AND NOT dst */
+ 0xf0, /* Xcopy pat */
+ 0x0a, /* XandInverted NOT pat AND dst */
+ 0xaa, /* Xnoop dst */
+ 0x5a, /* Xxor pat XOR dst */
+ 0xfa, /* Xor pat OR dst */
+ 0x05, /* Xnor NOT pat AND NOT dst */
+ 0xa5, /* Xequiv NOT pat XOR dst */
+ 0x55, /* Xinvert NOT dst */
+ 0xf5, /* XorReverse pat OR NOT dst */
+ 0x0f, /* XcopyInverted NOT pat */
+ 0xaf, /* XorInverted NOT pat OR dst */
+ 0x5f, /* Xnand NOT pat OR NOT dst */
+ 0xff /* Xset 1 */
+};
+
+long W32ForegroundPing;
+long W32ForegroundPong;
+long W32BackgroundPing;
+long W32BackgroundPong;
+long W32PatternPing;
+long W32PatternPong;
+
+LongP MemW32ForegroundPing;
+LongP MemW32ForegroundPong;
+LongP MemW32BackgroundPing;
+LongP MemW32BackgroundPong;
+LongP MemW32PatternPing;
+LongP MemW32PatternPong;
+
+unsigned char * tsengCPU2ACLBase;
+
+/* used for optimisation of direction-register writing */
+int tseng_old_dir = -1;
+int old_x = 0, old_y = 0;
+
+/* These will hold the ping-pong registers.
+ * Note that ping-pong registers might not be needed when using
+ * BACKGROUND_OPERATIONS (because of the WAIT()-ing involved)
+ */
+
+LongP tsengMemFg;
+long tsengFg;
+
+LongP tsengMemBg;
+long tsengBg;
+
+LongP tsengMemPat;
+long tsengPat;
+
+/**********************************************************************/
+
+void
+tseng_terminate_acl(TsengPtr pTseng)
+{
+ /* only terminate when needed */
+/* if (*(volatile unsigned char *)ACL_ACCELERATOR_STATUS & 0x06) */
+ {
+ *ACL_SUSPEND_TERMINATE = 0x00;
+ /* suspend any running operation */
+ *ACL_SUSPEND_TERMINATE = 0x01;
+ WAIT_ACL;
+ *ACL_SUSPEND_TERMINATE = 0x00;
+ /* ... and now terminate it */
+ *ACL_SUSPEND_TERMINATE = 0x10;
+ WAIT_ACL;
+ *ACL_SUSPEND_TERMINATE = 0x00;
+ }
+}
+
+void
+tseng_recover_timeout(TsengPtr pTseng)
+{
+ if (!Is_ET6K) {
+ ErrorF("trying to unlock......................................\n");
+ *tsengCPU2ACLBase = 0L; /* try unlocking the bus when CPU-to-accel gets stuck */
+ }
+ if (Is_W32p) { /* flush the accelerator pipeline */
+ *ACL_SUSPEND_TERMINATE = 0x00;
+ *ACL_SUSPEND_TERMINATE = 0x02;
+ *ACL_SUSPEND_TERMINATE = 0x00;
+ }
+}
+
+long MMioBase;
+
+void
+tseng_init_acl(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TsengPtr pTseng = TsengPTR(pScrn);
+ long scratchMemBase;
+
+ PDEBUG(" tseng_init_acl\n");
+ /*
+ * prepare some shortcuts for faster access to memory mapped registers
+ */
+
+ if (pTseng->UseLinMem) {
+ MMioBase = (long)pTseng->FbBase + 0x3FFF00;
+ scratchMemBase = (long)pTseng->FbBase + pTseng->AccelColorBufferOffset;
+ /*
+ * we won't be using tsengCPU2ACLBase in linear memory mode anyway, since
+ * using the MMU apertures restricts the amount of useable video memory
+ * to only 2MB, supposing we ONLY redirect MMU aperture 2 to the CPU.
+ * (see data book W32p, page 207)
+ */
+ tsengCPU2ACLBase = (unsigned char*) ((long)pTseng->FbBase + 0x200000); /* MMU aperture 2 */
+ } else {
+ MMioBase = (long)pTseng->FbBase + 0x1FF00L;
+ /*
+ * MMU 0 is used for the scratchpad (i.e. FG and BG colors).
+ *
+ * MMU 1 is used for the Imagewrite buffers. This code assumes those
+ * buffers are back-to-back, with AccelImageWriteBufferOffsets[0]
+ * being the first, and don't exceed 8kb (aperture size) in total
+ * length.
+ */
+ scratchMemBase = (long)pTseng->FbBase + 0x18000L;
+ *((LongP) (MMioBase + 0x00)) = pTseng->AccelColorBufferOffset;
+ *((LongP) (MMioBase + 0x04)) = pTseng->AccelImageWriteBufferOffsets[0];
+ /*
+ * tsengCPU2ACLBase is used for CPUtoSCreen...() operations on < ET6000 devices
+ */
+ tsengCPU2ACLBase = (unsigned char*) ((long)pTseng->FbBase + 0x1C000L); /* MMU aperture 2 */
+ /* *((LongP) (MMioBase + 0x08)) = 200000; *//* TEST */
+ }
+
+ /* ErrorF("MMioBase = 0x%x, scratchMemBase = 0x%x\n", MMioBase, scratchMemBase); */
+
+ MMU_CONTROL = (ByteP) (MMioBase + 0x13);
+
+ ACL_SUSPEND_TERMINATE = (ByteP) (MMioBase + 0x30);
+ ACL_OPERATION_STATE = (ByteP) (MMioBase + 0x31);
+
+ ACL_SYNC_ENABLE = (ByteP) (MMioBase + 0x32);
+ /* for ET6000, ACL_SYNC_ENABLE becomes ACL_6K_CONFIG */
+
+ ACL_WRITE_INTERFACE_VALID = (ByteP) (MMioBase + 0x33);
+ ACL_INTERRUPT_MASK = (ByteP) (MMioBase + 0x34);
+ ACL_INTERRUPT_STATUS = (ByteP) (MMioBase + 0x35);
+ ACL_ACCELERATOR_STATUS = (ByteP) (MMioBase + 0x36);
+
+ /* and this is only for the ET6000 */
+ ACL_POWER_CONTROL = (ByteP) (MMioBase + 0x37);
+
+ /* non-queued for w32p's and ET6000 */
+ ACL_NQ_X_POSITION = (WordP) (MMioBase + 0x38);
+ ACL_NQ_Y_POSITION = (WordP) (MMioBase + 0x3A);
+ /* queued for w32 and w32i */
+ ACL_X_POSITION = (WordP) (MMioBase + 0x94);
+ ACL_Y_POSITION = (WordP) (MMioBase + 0x96);
+
+ ACL_PATTERN_ADDRESS = (LongP) (MMioBase + 0x80);
+ ACL_SOURCE_ADDRESS = (LongP) (MMioBase + 0x84);
+
+ ACL_PATTERN_Y_OFFSET = (WordP) (MMioBase + 0x88);
+ ACL_SOURCE_Y_OFFSET = (WordP) (MMioBase + 0x8A);
+ ACL_DESTINATION_Y_OFFSET = (WordP) (MMioBase + 0x8C);
+
+ /* W32i */
+ ACL_VIRTUAL_BUS_SIZE = (ByteP) (MMioBase + 0x8E);
+ /* w32p */
+ ACL_PIXEL_DEPTH = (ByteP) (MMioBase + 0x8E);
+
+ /* w32 and w32i */
+ ACL_XY_DIRECTION = (ByteP) (MMioBase + 0x8F);
+
+ ACL_PATTERN_WRAP = (ByteP) (MMioBase + 0x90);
+ ACL_TRANSFER_DISABLE = (ByteP) (MMioBase + 0x91); /* ET6000 only */
+ ACL_SOURCE_WRAP = (ByteP) (MMioBase + 0x92);
+
+ ACL_X_COUNT = (WordP) (MMioBase + 0x98);
+ ACL_Y_COUNT = (WordP) (MMioBase + 0x9A);
+ ACL_XY_COUNT = (LongP) (ACL_X_COUNT); /* shortcut. not a real register */
+
+ ACL_ROUTING_CONTROL = (ByteP) (MMioBase + 0x9C);
+ /* for ET6000, ACL_ROUTING_CONTROL becomes ACL_MIX_CONTROL */
+ ACL_RELOAD_CONTROL = (ByteP) (MMioBase + 0x9D);
+ /* for ET6000, ACL_RELOAD_CONTROL becomes ACL_STEPPING_INHIBIT */
+
+ ACL_BACKGROUND_RASTER_OPERATION = (ByteP) (MMioBase + 0x9E);
+ ACL_FOREGROUND_RASTER_OPERATION = (ByteP) (MMioBase + 0x9F);
+
+ ACL_DESTINATION_ADDRESS = (LongP) (MMioBase + 0xA0);
+
+ /* the following is for the w32p's only */
+ ACL_MIX_ADDRESS = (LongP) (MMioBase + 0xA4);
+
+ ACL_MIX_Y_OFFSET = (WordP) (MMioBase + 0xA8);
+ ACL_ERROR_TERM = (WordP) (MMioBase + 0xAA);
+ ACL_DELTA_MINOR = (WordP) (MMioBase + 0xAC);
+ ACL_DELTA_MAJOR = (WordP) (MMioBase + 0xAE);
+
+ /* ET6000 only (trapezoids) */
+ ACL_SECONDARY_EDGE = (ByteP) (MMioBase + 0x93);
+ ACL_SECONDARY_ERROR_TERM = (WordP) (MMioBase + 0xB2);
+ ACL_SECONDARY_DELTA_MINOR = (WordP) (MMioBase + 0xB4);
+ ACL_SECONDARY_DELTA_MAJOR = (WordP) (MMioBase + 0xB6);
+
+ /* addresses in video memory (i.e. "0" = first byte in video memory) */
+ W32ForegroundPing = pTseng->AccelColorBufferOffset + 0;
+ W32ForegroundPong = pTseng->AccelColorBufferOffset + 8;
+
+ W32BackgroundPing = pTseng->AccelColorBufferOffset + 16;
+ W32BackgroundPong = pTseng->AccelColorBufferOffset + 24;
+
+ W32PatternPing = pTseng->AccelColorBufferOffset + 32;
+ W32PatternPong = pTseng->AccelColorBufferOffset + 40;
+
+ /* addresses in the memory map */
+ MemW32ForegroundPing = (LongP) (scratchMemBase + 0);
+ MemW32ForegroundPong = (LongP) (scratchMemBase + 8);
+
+ MemW32BackgroundPing = (LongP) (scratchMemBase + 16);
+ MemW32BackgroundPong = (LongP) (scratchMemBase + 24);
+
+ MemW32PatternPing = (LongP) (scratchMemBase + 32);
+ MemW32PatternPong = (LongP) (scratchMemBase + 40);
+
+ /*
+ * prepare the accelerator for some real work
+ */
+
+ tseng_terminate_acl(pTseng);
+
+ *ACL_INTERRUPT_STATUS = 0xe; /* clear interrupts */
+ *ACL_INTERRUPT_MASK = 0x04; /* disable interrupts, but enable deadlock exit */
+ *ACL_INTERRUPT_STATUS = 0x0;
+ *ACL_ACCELERATOR_STATUS = 0x0;
+
+ if (Is_ET6K) {
+ *ACL_STEPPING_INHIBIT = 0x0; /* Undefined at power-on, let all maps (Src, Dst, Mix, Pat) step */
+ *ACL_6K_CONFIG = 0x00; /* maximum performance -- what did you think? */
+ *ACL_POWER_CONTROL = 0x01; /* conserve power when ACL is idle */
+ *ACL_MIX_CONTROL = 0x33;
+ *ACL_TRANSFER_DISABLE = 0x00; /* Undefined at power-on, enable all transfers */
+ } else { /* W32i/W32p */
+ *ACL_RELOAD_CONTROL = 0x0;
+ *ACL_SYNC_ENABLE = 0x1; /* | 0x2 = 0WS ACL read. Yields up to 10% faster operation for small blits */
+ *ACL_ROUTING_CONTROL = 0x00;
+ }
+
+ if (Is_W32p || Is_ET6K) {
+ /* Enable the W32p startup bit and set use an eight-bit pixel depth */
+ *ACL_NQ_X_POSITION = 0;
+ *ACL_NQ_Y_POSITION = 0;
+ *ACL_PIXEL_DEPTH = (pScrn->bitsPerPixel - 8) << 1;
+ /* writing destination address will start ACL */
+ *ACL_OPERATION_STATE = 0x10;
+ } else {
+ /* X, Y positions set to zero's for w32 and w32i */
+ *ACL_X_POSITION = 0;
+ *ACL_Y_POSITION = 0;
+ *ACL_OPERATION_STATE = 0x0;
+ /* if we ever use CPU-to-screen pixmap uploading on W32I or W32,
+ * ACL_VIRTUAL_BUS_SIZE will need to be made dynamic (i.e. moved to
+ * Setup() functions).
+ *
+ * VBS = 1 byte is faster than VBS = 4 bytes, since the ACL can
+ * start processing as soon as the first byte arrives.
+ */
+ *ACL_VIRTUAL_BUS_SIZE = 0x00;
+ }
+ *ACL_DESTINATION_Y_OFFSET = pScrn->displayWidth * pTseng->Bytesperpixel - 1;
+ *ACL_XY_DIRECTION = 0;
+
+ *MMU_CONTROL = 0x74;
+
+ if (Is_W32p && pTseng->UseLinMem) {
+ /*
+ * Since the w32p revs C and D don't have any memory mapped when the
+ * accelerator registers are used it is necessary to use the MMUs to
+ * provide a semblance of linear memory. Fortunately on these chips
+ * the MMU appertures are 1 megabyte each. So as long as we are
+ * willing to only use 3 megs of video memory we can have some
+ * acceleration. If we ever get the CPU-to-screen-color-expansion
+ * stuff working then we will NOT need to sacrifice the extra 1MB
+ * provided by MBP2, because we could do dynamic switching of the APT
+ * bit in the MMU control register.
+ *
+ * On W32p rev c and d MBP2 is hardwired to 0x200000 when linear
+ * memory mode is enabled. (On rev a it is programmable).
+ *
+ * W32p rev a and b have their first 2M mapped in the normal (non-MMU)
+ * way, and MMU0 and MMU1, each 512 kb wide, can be used to access
+ * another 1MB of memory. This totals to 3MB of mem. available in
+ * linear memory when the accelerator is enabled.
+ */
+ if (Is_W32p_ab) {
+ *((LongP) (MMioBase + 0x00)) = 0x200000L;
+ *((LongP) (MMioBase + 0x04)) = 0x280000L;
+ } else { /* rev C & D */
+ *((LongP) (MMioBase + 0x00)) = 0x0L;
+ *((LongP) (MMioBase + 0x04)) = 0x100000L;
+ }
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_acl.h b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_acl.h
new file mode 100644
index 000000000..5986b5776
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_acl.h
@@ -0,0 +1,241 @@
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_acl.h,v 1.17 1998/09/05 06:36:55 dawes Exp $ */
+
+
+
+
+
+#ifndef _TSENG_ACL_H
+#define _TSENG_ACL_H
+
+/*
+ * if NO_OPTIMIZE is set, some optimizations are disabled.
+ *
+ * What it basically tries to do is minimize the amounts of writes to
+ * accelerator registers, since these are the ones that slow down small
+ * operations a lot.
+ */
+
+#undef NO_OPTIMIZE
+
+typedef volatile unsigned char *ByteP;
+typedef volatile unsigned short *WordP;
+typedef volatile unsigned *LongP;
+
+void tseng_recover_timeout(TsengPtr pTseng);
+
+/*
+ * Shortcuts to Tseng memory-mapped accelerator-control registers
+ */
+
+extern
+ByteP MMU_CONTROL;
+
+extern
+ByteP ACL_SUSPEND_TERMINATE, ACL_OPERATION_STATE, ACL_SYNC_ENABLE, ACL_WRITE_INTERFACE_VALID,
+ ACL_INTERRUPT_MASK, ACL_INTERRUPT_STATUS, ACL_ACCELERATOR_STATUS;
+
+/* for ET6000: */
+#define ACL_6K_CONFIG ACL_SYNC_ENABLE
+
+extern
+WordP ACL_X_POSITION, ACL_Y_POSITION;
+
+extern
+WordP ACL_NQ_X_POSITION, ACL_NQ_Y_POSITION;
+
+extern
+LongP ACL_PATTERN_ADDRESS, ACL_SOURCE_ADDRESS;
+
+extern
+WordP ACL_PATTERN_Y_OFFSET, ACL_SOURCE_Y_OFFSET, ACL_DESTINATION_Y_OFFSET;
+
+extern
+ByteP ACL_VIRTUAL_BUS_SIZE, /* only for w32 and w32i */
+ ACL_XY_DIRECTION, ACL_PIXEL_DEPTH; /* only for w32p_rev_A and w32p_rev_B */
+
+extern
+ByteP ACL_PATTERN_WRAP, ACL_SOURCE_WRAP;
+
+extern
+WordP ACL_X_COUNT, ACL_Y_COUNT;
+extern
+LongP ACL_XY_COUNT; /* for combined writes to X and Y count registers */
+
+extern
+ByteP ACL_ROUTING_CONTROL, ACL_RELOAD_CONTROL, ACL_BACKGROUND_RASTER_OPERATION,
+ ACL_FOREGROUND_RASTER_OPERATION;
+
+/* for ET6000: */
+#define ACL_MIX_CONTROL ACL_ROUTING_CONTROL
+#define ACL_STEPPING_INHIBIT ACL_RELOAD_CONTROL
+
+extern
+LongP ACL_DESTINATION_ADDRESS, /* only for w32p_rev_A and w32p_rev_B */
+ ACL_MIX_ADDRESS;
+
+extern
+WordP ACL_MIX_Y_OFFSET, ACL_ERROR_TERM, ACL_DELTA_MINOR, ACL_DELTA_MAJOR;
+
+/* for ET6000 only */
+extern
+ByteP ACL_POWER_CONTROL;
+extern
+ByteP ACL_SECONDARY_EDGE;
+extern
+WordP ACL_SECONDARY_ERROR_TERM, ACL_SECONDARY_DELTA_MINOR, ACL_SECONDARY_DELTA_MAJOR;
+extern
+ByteP ACL_TRANSFER_DISABLE;
+
+/*
+ * Some data structures for faster accelerator programming.
+ */
+
+extern int W32OpTable[16];
+extern int W32OpTable_planemask[16];
+extern int W32PatternOpTable[16];
+
+/*
+ * The ping-pong registers. Probably too much hassle for too little gain. "TODO".
+ */
+
+extern long W32ForegroundPing;
+extern long W32ForegroundPong;
+extern long W32BackgroundPing;
+extern long W32BackgroundPong;
+extern long W32PatternPing;
+extern long W32PatternPong;
+
+extern LongP MemW32ForegroundPing;
+extern LongP MemW32ForegroundPong;
+extern LongP MemW32BackgroundPing;
+extern LongP MemW32BackgroundPong;
+extern LongP MemW32PatternPing;
+extern LongP MemW32PatternPong;
+
+extern unsigned char * tsengCPU2ACLBase;
+
+/*
+ * These will hold the ping-pong registers.
+ */
+
+extern LongP tsengMemFg;
+extern long tsengFg;
+
+extern LongP tsengMemBg;
+extern long tsengBg;
+
+extern LongP tsengMemPat;
+extern long tsengPat;
+
+/* for register write optimisation */
+extern int old_x, old_y;
+extern int tseng_old_dir;
+
+/*
+ * Some shortcuts.
+ */
+
+#define MAX_WAIT_CNT 500000 /* how long we wait before we time out */
+#undef WAIT_VERBOSE /* if defined: print out how long we waited */
+
+static __inline__ void
+tseng_wait(TsengPtr pTseng, ByteP reg, char *name, unsigned char mask)
+{
+ int cnt = MAX_WAIT_CNT;
+
+ while (*reg & mask)
+ if (--cnt < 0) {
+ ErrorF("WAIT_%s: timeout.\n", name);
+ tseng_recover_timeout(pTseng);
+ break;
+ }
+#ifdef WAIT_VERBOSE
+ ErrorF("%s%d ", name, MAX_WAIT_CNT - cnt);
+#endif
+}
+
+#define WAIT_QUEUE tseng_wait(pTseng, ACL_ACCELERATOR_STATUS, "QUEUE", 0x1)
+
+/* This is only for W32p rev b...d */
+#define WAIT_INTERFACE tseng_wait(pTseng, ACL_WRITE_INTERFACE_VALID, "INTERFACE", 0xf)
+
+#define WAIT_ACL tseng_wait(pTseng, ACL_ACCELERATOR_STATUS, "ACL", 0x2)
+
+#define WAIT_XY tseng_wait(pTseng, ACL_ACCELERATOR_STATUS, "XY", 0x4)
+
+#define SET_FUNCTION_BLT \
+ if (Is_ET6K) \
+ *ACL_MIX_CONTROL = 0x33; \
+ else \
+ *ACL_ROUTING_CONTROL = 0x00;
+
+#define SET_FUNCTION_BLT_TR \
+ *ACL_MIX_CONTROL = 0x13;
+
+#define FBADDR(pTseng, x,y) ( (y) * pTseng->line_width + MULBPP(pTseng, x) )
+
+#define SET_FG_ROP(rop) \
+ *ACL_FOREGROUND_RASTER_OPERATION = W32OpTable[rop];
+
+#define SET_FG_ROP_PLANEMASK(rop) \
+ *ACL_FOREGROUND_RASTER_OPERATION = W32OpTable_planemask[rop];
+
+#define SET_BG_ROP(rop) \
+ *ACL_BACKGROUND_RASTER_OPERATION = W32PatternOpTable[rop];
+
+#define SET_BG_ROP_TR(rop, bg_color) \
+ if ((bg_color) == -1) /* transparent color expansion */ \
+ *ACL_BACKGROUND_RASTER_OPERATION = 0xaa; \
+ else \
+ *ACL_BACKGROUND_RASTER_OPERATION = W32PatternOpTable[rop];
+
+#define SET_DELTA(Min, Maj) \
+ *((LongP) ACL_DELTA_MINOR) = ((Maj) << 16) + (Min)
+
+#define SET_SECONDARY_DELTA(Min, Maj) \
+ *((LongP) ACL_SECONDARY_DELTA_MINOR) = ((Maj) << 16) + (Min)
+
+#ifdef NO_OPTIMIZE
+#define SET_XYDIR(dir) \
+ *ACL_XY_DIRECTION = (dir);
+#else
+/*
+ * only changing ACL_XY_DIRECTION when it needs to be changed avoids
+ * unnecessary PCI bus writes, which are slow. This shows up very well
+ * on consecutive small fills.
+ */
+#define SET_XYDIR(dir) \
+ if ((dir) != tseng_old_dir) \
+ *ACL_XY_DIRECTION = tseng_old_dir = (dir);
+#endif
+
+#define SET_SECONDARY_XYDIR(dir) \
+ *ACL_SECONDARY_EDGE = (dir);
+
+/* Must do 0x09 (in one operation) for the W32 */
+#define START_ACL(pTseng, dst) \
+ *(ACL_DESTINATION_ADDRESS) = dst; \
+ if (Is_W32 || Is_W32i) *ACL_OPERATION_STATE = 0x09;
+
+/* START_ACL for the ET6000 */
+#define START_ACL_6(dst) \
+ *(ACL_DESTINATION_ADDRESS) = dst;
+
+#define START_ACL_CPU(pTseng, dst) \
+ if (Is_W32 || Is_W32i) \
+ *((LongP) (MMioBase + 0x08)) = (CARD32)dst; /* writing to MMU2 will trigger accel at this address */ \
+ else \
+ *(ACL_DESTINATION_ADDRESS) = dst;
+
+/* *(ACL_DESTINATION_ADDRESS) = dst; should be enough for START_ACL_CPU */
+
+/***********************************************************************/
+
+void tseng_init_acl(ScreenPtr pScreen);
+
+Bool TsengXAAInit(ScreenPtr pScreen);
+
+Bool TsengXAAInit_Colexp(ScrnInfoPtr pScrn);
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_bank.c b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_bank.c
new file mode 100644
index 000000000..f5831b6f1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_bank.c
@@ -0,0 +1,87 @@
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_bank.c,v 1.3 1998/08/02 05:17:01 dawes Exp $ */
+
+
+
+
+
+#include "tseng.h"
+
+/*
+ * Tseng really screwed up when they decided to combine the read and write
+ * bank selectors into one register. Now we need to cache the bank
+ * registers, because IO reads are too expensive.
+ */
+
+
+int
+ET4000W32SetRead(ScreenPtr pScreen, unsigned int iBank)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ pTseng->cache_SegSelL = (pTseng->cache_SegSelL & 0x0f) | (iBank << 4);
+ pTseng->cache_SegSelH = (pTseng->cache_SegSelH & 0x03) | (iBank & 0x30);
+ outb(0x3CB, pTseng->cache_SegSelH);
+ outb(0x3CD, pTseng->cache_SegSelL);
+ return 0;
+}
+
+int
+ET4000W32SetWrite(ScreenPtr pScreen, unsigned int iBank)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ pTseng->cache_SegSelL = (pTseng->cache_SegSelL & 0xf0) | (iBank & 0x0f);
+ pTseng->cache_SegSelH = (pTseng->cache_SegSelH & 0x30) | (iBank >> 4);
+ outb(0x3CB, pTseng->cache_SegSelH);
+ outb(0x3CD, pTseng->cache_SegSelL);
+ return 0;
+}
+
+int
+ET4000W32SetReadWrite(ScreenPtr pScreen, unsigned int iBank)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ pTseng->cache_SegSelL = (iBank & 0x0f) | (iBank << 4);
+ pTseng->cache_SegSelH = (iBank & 0x30) | (iBank >> 4);
+ outb(0x3CB, pTseng->cache_SegSelH);
+ outb(0x3CD, pTseng->cache_SegSelL);
+ return 0;
+}
+
+int
+ET4000SetRead(ScreenPtr pScreen, unsigned int iBank)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ pTseng->cache_SegSelL = (pTseng->cache_SegSelL & 0x0f) | (iBank << 4);
+ outb(0x3CD, pTseng->cache_SegSelL);
+ return 0;
+}
+
+int
+ET4000SetWrite(ScreenPtr pScreen, unsigned int iBank)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ pTseng->cache_SegSelL = (pTseng->cache_SegSelL & 0xf0) | (iBank & 0x0f);
+ outb(0x3CD, pTseng->cache_SegSelL);
+ return 0;
+}
+
+int
+ET4000SetReadWrite(ScreenPtr pScreen, unsigned int iBank)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ pTseng->cache_SegSelL = (iBank & 0x0f) | (iBank << 4);
+ outb(0x3CD, pTseng->cache_SegSelL);
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_clock.c b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_clock.c
new file mode 100644
index 000000000..5363a44ef
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_clock.c
@@ -0,0 +1,509 @@
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_clock.c,v 1.14 1999/06/12 07:18:58 dawes Exp $ */
+
+
+
+
+
+/*
+ *
+ * Copyright 1993-1997 The XFree86 Project, Inc.
+ *
+ */
+/**
+ ** Clock setting methods for Tseng chips
+ **
+ ** The *ClockSelect() fucntions are ONLY used used for clock probing!
+ ** Setting the actual clock is done in TsengRestore().
+ **/
+
+#include "tseng.h"
+
+static Bool Tseng_ET4000ClockSelect(ScrnInfoPtr pScrn, int no);
+static Bool Tseng_LegendClockSelect(ScrnInfoPtr pScrn, int no);
+
+
+static SymTabRec TsengClockChips[] =
+{
+ {CLOCKCHIP_ICD2061A, "icd2061a"},
+ {CLOCKCHIP_ET6000, "et6000"},
+ {CLOCKCHIP_ICS5341, "ics5341"},
+ {CLOCKCHIP_ICS5301, "ics5301"},
+ {CLOCKCHIP_CH8398, "ch8398"},
+ {CLOCKCHIP_STG1703, "stg1703"},
+ {-1, NULL}
+};
+
+Bool
+Tseng_check_clockchip(ScrnInfoPtr pScrn)
+{
+ MessageType from;
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ PDEBUG(" Tseng_check_clockchip\n");
+
+ if (pTseng->pEnt->device->clockchip && *pTseng->pEnt->device->clockchip) {
+ /* clockchip given as a string in the config file */
+ pScrn->clockchip = pTseng->pEnt->device->clockchip;
+ pTseng->ClockChip = xf86StringToToken(TsengClockChips, pScrn->clockchip);
+ if (pTseng->ClockChip == -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unknown clockchip: \"%s\"\n",
+ pScrn->clockchip);
+ return FALSE;
+ }
+ from = X_CONFIG;
+ } else {
+ /* ramdac probe already defined pTseng->ClockChip */
+ pScrn->clockchip = (char *)xf86TokenToString(TsengClockChips, pTseng->ClockChip);
+ from = X_PROBED;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Clockchip: \"%s\"\n",
+ pScrn->clockchip);
+
+ return TRUE;
+}
+
+
+void tseng_clock_setup(ScrnInfoPtr pScrn)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+ int iobase = VGAHW_GET_IOBASE();
+ MessageType from;
+ int dacspeed, mem_bw;
+ Bool forceSpeed = FALSE;
+ int i;
+
+ PDEBUG(" tseng_clock_setup\n");
+
+ /*
+ * Memory bandwidth is important in > 8bpp modes, especially on ET4000
+ *
+ * This code evaluates a video mode with respect to requested dot clock
+ * (depends on the VGA chip and the RAMDAC) and the resulting bandwidth
+ * demand on memory (which in turn depends on color depth).
+ *
+ * For each mode, the minimum of max data transfer speed (dot clock
+ * limit) and memory bandwidth determines if the mode is allowed.
+ *
+ * We should also take acceleration into account: accelerated modes
+ * strain the bandwidth heavily, because they cause lots of random
+ * acesses to video memory, which is bad for bandwidth due to smaller
+ * page-mode memory requests.
+ */
+
+ /* Set the min pixel clock */
+ pTseng->MinClock = 12000; /* XXX Guess, need to check this */
+
+ /*
+ * If the user has specified ramdac speed in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pTseng->pEnt->device->dacSpeeds[0]) {
+ from = X_CONFIG;
+ forceSpeed = TRUE;
+ switch (pScrn->bitsPerPixel) {
+ default:
+ case 1:
+ case 4:
+ case 8:
+ dacspeed = pTseng->pEnt->device->dacSpeeds[DAC_BPP8];
+ break;
+ case 16:
+ dacspeed = pTseng->pEnt->device->dacSpeeds[DAC_BPP16];
+ break;
+ case 24:
+ dacspeed = pTseng->pEnt->device->dacSpeeds[DAC_BPP24];
+ break;
+ case 32:
+ dacspeed = pTseng->pEnt->device->dacSpeeds[DAC_BPP32];
+ break;
+ }
+ pTseng->max_vco_freq = pTseng->pEnt->device->dacSpeeds[0]*2+1;
+ /* if a bpp-specific DacSpeed is not defined, use the "default" one (=8bpp) */
+ if (dacspeed == 0)
+ dacspeed = pTseng->pEnt->device->dacSpeeds[0];
+ } else {
+ from = X_PROBED;
+ forceSpeed = FALSE;
+ /* default */
+ dacspeed = MAX_TSENG_CLOCK;
+ /*
+ * According to Tseng (about the ET6000):
+ * "Besides the 135 MHz maximum pixel clock frequency, the other limit has to
+ * do with where you get FIFO breakdown (usually appears as stray horizontal
+ * lines on the screen). Assuming the accelerator is running steadily doing a
+ * worst case operation, to avoid FIFO breakdown you should keep the product
+ * pixel_clock*(bytes/pixel) <= 225 MHz . This is based on an XCLK
+ * (system/memory) clock of 92 MHz (which is what we currently use) and
+ * a value in the RAS/CAS Configuration register (CFG 44) of either 015h
+ * or 014h (depending on the type of MDRAM chips). Also, the FIFO low
+ * threshold control bit (bit 4 of CFG 41) should be set for modes where
+ * pixel_clock*(bytes/pixel) > 130 MHz . These limits are for the
+ * current ET6000 chips. The ET6100 will raise the pixel clock limit
+ * to 175 MHz and the pixel_clock*(bytes/pixel) FIFO breakdown limit
+ * to about 275 MHz."
+ */
+ if (Is_ET6100) {
+ dacspeed = 175000;
+ mem_bw = 280000; /* 275000 is _just_ not enough for 1152x864x24 @ 70Hz */
+ } else if (Is_ET6000) {
+ dacspeed = 135000;
+ mem_bw = 225000;
+ } else {
+ if ( (pTseng->DacInfo.DacPort16) &&
+ (pScrn->bitsPerPixel == 8) &&
+ (!(DAC_is_GenDAC && pTseng->NoClockchip)) ) {
+ dacspeed = 135000; /* we can do PIXMUX */
+ }
+ mem_bw = 90000;
+ if (pScrn->videoRam > 1024)
+ mem_bw = 150000; /* interleaved DRAM gives 70% more bandwidth */
+ }
+ pTseng->max_vco_freq = dacspeed*2+1;
+ /*
+ * "dacspeed" is the theoretical limit imposed by the RAMDAC.
+ * "mem_bw" is the max memory bandwidth in mb/sec available
+ * for the pixel FIFO.
+ * The lowest of the two determines the actual pixel clock limit.
+ */
+ dacspeed = min(dacspeed, (mem_bw / pTseng->Bytesperpixel));
+ }
+
+ /*
+ * Setup the ClockRanges, which describe what clock ranges are available,
+ * and what sort of modes they can be used for.
+ *
+ * First, we set up the default case, and modify it later if needed.
+ */
+ pTseng->clockRange[0] = xnfalloc(sizeof(ClockRange));
+ pTseng->clockRange[0]->next = NULL;
+ pTseng->clockRange[0]->minClock = pTseng->MinClock;
+ pTseng->clockRange[0]->maxClock = dacspeed;
+ pTseng->clockRange[0]->clockIndex = -1; /* programmable -- not used */
+ pTseng->clockRange[0]->interlaceAllowed = TRUE;
+ pTseng->clockRange[0]->doubleScanAllowed = TRUE;
+ pTseng->clockRange[0]->ClockMulFactor = 1;
+ pTseng->clockRange[0]->ClockDivFactor = 1;
+ pTseng->clockRange[0]->PrivFlags = TSENG_MODE_NORMAL;
+
+ /*
+ * Handle PIXMUX modes.
+ *
+ * NOTE: We disable PIXMUX when clockchip programming on the GenDAC
+ * family is disabled. PIXMUX requires that the N2 post-divider in the
+ * PLL clock programming word is >= 2, which is not always true for the
+ * default (BIOS) clocks programmed in the 8 clock registers.
+ */
+ if ( (pTseng->DacInfo.DacPort16) &&
+ (pScrn->bitsPerPixel == 8) &&
+ (!(DAC_is_GenDAC && pTseng->NoClockchip)) ) {
+ pTseng->clockRange[0]->maxClock = MAX_TSENG_CLOCK;
+ /* set up 2nd clock range for PIXMUX modes */
+ pTseng->clockRange[1] = xnfalloc(sizeof(ClockRange));
+ pTseng->clockRange[0]->next = pTseng->clockRange[1];
+ pTseng->clockRange[1]->next = NULL;
+ pTseng->clockRange[1]->minClock = 75000;
+ pTseng->clockRange[1]->maxClock = dacspeed;
+ pTseng->clockRange[1]->clockIndex = -1; /* programmable -- not used */
+ pTseng->clockRange[1]->interlaceAllowed = TRUE;
+ pTseng->clockRange[1]->doubleScanAllowed = TRUE;
+ pTseng->clockRange[1]->ClockMulFactor = 1;
+ pTseng->clockRange[1]->ClockDivFactor = 2;
+ pTseng->clockRange[1]->PrivFlags = TSENG_MODE_PIXMUX;
+ }
+
+ /*
+ * Handle 16/24/32 bpp modes that require some form of clock scaling. We
+ * can have either 8-bit DACs that require "bytesperpixel" clocks per
+ * pixel, or 16-bit DACs that can transport 8 or 16 bits per clock.
+ */
+ if ((pTseng->Bytesperpixel > 1) && (!Is_ET6K)) {
+ /* in either 8 or 16-bit DAC case, we can use an 8-bit interface */
+ pTseng->clockRange[0]->maxClock = (forceSpeed) ? dacspeed :
+ min(MAX_TSENG_CLOCK / pTseng->Bytesperpixel, dacspeed);
+ pTseng->clockRange[0]->ClockMulFactor = pTseng->Bytesperpixel;
+ pTseng->clockRange[0]->ClockDivFactor = 1;
+ /* in addition, 16-bit DACs can also transport 2 bytes per clock */
+ if (pTseng->DacInfo.DacPort16) {
+ pTseng->clockRange[1] = xnfalloc(sizeof(ClockRange));
+ pTseng->clockRange[0]->next = pTseng->clockRange[1];
+ pTseng->clockRange[1]->next = NULL;
+ pTseng->clockRange[1]->minClock = pTseng->MinClock;
+ pTseng->clockRange[1]->maxClock = (forceSpeed) ? dacspeed :
+ min((MAX_TSENG_CLOCK * 2) / pTseng->Bytesperpixel, dacspeed);
+ pTseng->clockRange[1]->clockIndex = -1; /* programmable -- not used */
+ pTseng->clockRange[1]->interlaceAllowed = TRUE;
+ pTseng->clockRange[1]->doubleScanAllowed = TRUE;
+ pTseng->clockRange[1]->ClockMulFactor = pTseng->Bytesperpixel;
+ pTseng->clockRange[1]->ClockDivFactor = 2;
+ pTseng->clockRange[1]->PrivFlags = TSENG_MODE_DACBUS16;
+ }
+ }
+
+ if (pTseng->clockRange[1])
+ pTseng->MaxClock = pTseng->clockRange[1]->maxClock;
+ else
+ pTseng->MaxClock = pTseng->clockRange[0]->maxClock;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Min pixel clock is %d MHz\n",
+ pTseng->MinClock / 1000);
+ xf86DrvMsg(pScrn->scrnIndex, from, "Max pixel clock is %d MHz\n",
+ pTseng->MaxClock / 1000);
+
+ /* Memory clock setup */
+ pTseng->MClkInfo.Set = FALSE;
+ /* Only set MemClk if appropriate for the ramdac */
+ if (pTseng->MClkInfo.Programmable) {
+ from = X_PROBED;
+ if (pTseng->MemClk > 0) {
+ if ((pTseng->MemClk < pTseng->MClkInfo.min)
+ || (pTseng->MemClk > pTseng->MClkInfo.max)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "MCLK %d MHz out of range (=%d..%d); not changed!\n",
+ pTseng->MemClk / 1000,
+ pTseng->MClkInfo.min / 1000,
+ pTseng->MClkInfo.max / 1000);
+ } else {
+ pTseng->MClkInfo.MemClk = pTseng->MemClk;
+ pTseng->MClkInfo.Set = TRUE;
+ from = X_CONFIG;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "MCLK used is %d MHz\n",
+ pTseng->MClkInfo.MemClk / 1000);
+ }
+
+ /*
+ * Set up the list-of-clocks stuff if we don't have a programmable
+ * clockchip (the RAMDAC probe sets the pScrn->progClock field).
+ */
+ if (!pScrn->progClock) {
+ int NoClocks;
+ Bool (*TsengClockSelect)(ScrnInfoPtr, int);
+
+ /* first determine how many clocks there are (or can be) */
+ if (pTseng->Legend) {
+ TsengClockSelect = Tseng_LegendClockSelect;
+ NoClocks = 32;
+ } else {
+ TsengClockSelect = Tseng_ET4000ClockSelect;
+ /*
+ * The CH8398 RAMDAC uses CS3 for register selection (RS2), not for clock selection.
+ * The GenDAC family only has 8 clocks. Together with MCLK/2, that's 16 clocks.
+ */
+ if ( (!Is_stdET4K)
+ && (!DAC_is_GenDAC) && (pTseng->DacInfo.DacType != CH8398_DAC) )
+ NoClocks = 32;
+ else
+ NoClocks = 16;
+ }
+ /* now probe for the clocks if they are not specified */
+ if (!pTseng->pEnt->device->numclocks) {
+ pScrn->numClocks = NoClocks;
+ xf86GetClocks(pScrn, NoClocks, TsengClockSelect,
+ TsengProtect, TsengBlankScreen,
+ iobase + 0x0A, 0x08, 1, 28322);
+ from = X_PROBED;
+ } else {
+ pScrn->numClocks = pTseng->pEnt->device->numclocks;
+ if (pScrn->numClocks > NoClocks) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Too many Clocks specified in configuration file.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "\t\tAt most %d clocks may be specified\n", NoClocks);
+ pScrn->numClocks= NoClocks;
+ }
+ for (i = 0; i < pScrn->numClocks; i++)
+ pScrn->clock[i] = pTseng->pEnt->device->clock[i];
+ from = X_CONFIG;
+ }
+ /*
+ * Scale clocks for current bpp depending on RAMDAC type, and print
+ * out the list of clocks used.
+ */
+
+#ifdef FIXME
+ for (i = 0; i < pScrn->numClocks; i++) {
+ pScrn->clock[i] *= pTseng->DacInfo.ClockDivFactor;
+ pScrn->clock[i] /= pTseng->DacInfo.ClockMulFactor;
+ }
+#endif
+ xf86ShowClocks(pScrn, from);
+ }
+}
+
+
+/*
+ * ET4000ClockSelect --
+ * select one of the possible clocks ...
+ */
+
+static Bool
+Tseng_ET4000ClockSelect(ScrnInfoPtr pScrn, int no)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+ static unsigned char save1, save2, save3, save4;
+ unsigned char temp;
+ int iobase = VGAHW_GET_IOBASE();
+
+ switch (no) {
+ case CLK_REG_SAVE:
+ save1 = inb(0x3CC);
+ outb(iobase + 4, 0x34);
+ save2 = inb(iobase + 5);
+ outb(0x3C4, 7);
+ save3 = inb(0x3C5);
+ if (!Is_stdET4K) {
+ outb(iobase + 4, 0x31);
+ save4 = inb(iobase + 5);
+ }
+ break;
+ case CLK_REG_RESTORE:
+ outb(0x3C2, save1);
+ outw(iobase + 4, 0x34 | (save2 << 8));
+ outw(0x3C4, 7 | (save3 << 8));
+ if (!Is_stdET4K) {
+ outw(iobase + 4, 0x31 | (save4 << 8));
+ }
+ break;
+ default:
+ /* CS0,CS1 = clock select bits 0,1 */
+ temp = inb(0x3CC);
+ outb(0x3C2, (temp & 0xf3) | ((no << 2) & 0x0C));
+ /* CS2 = clock select bit 2 */
+ outb(iobase + 4, 0x34); /* don't nuke the other bits in CR34 */
+ temp = inb(iobase + 5);
+ outw(iobase + 4, 0x34 | ((temp & 0xFD) << 8) | ((no & 0x04) << 7));
+ /* CS3 = clock select bit 4 */
+ outb(0x3C4, 7);
+ temp = inb(0x3C5);
+ outb(0x3C5, (pTseng->save_divide ^ ((no & 0x8) << 3)) | (temp & 0xBF));
+ /* CS4 = MCLK/2 */
+ outb(iobase + 4, 0x31);
+ temp = inb(iobase + 5);
+ outb(iobase + 5, (temp & 0x3f) | ((no & 0x10) << 2));
+ }
+ return (TRUE);
+}
+
+/*
+ * LegendClockSelect --
+ * select one of the possible clocks ...
+ */
+
+static Bool
+Tseng_LegendClockSelect(ScrnInfoPtr pScrn, int no)
+{
+ /*
+ * Sigma Legend special handling
+ *
+ * The Legend uses an ICS 1394-046 clock generator. This can generate 32
+ * different frequencies. The Legend can use all 32. Here's how:
+ *
+ * There are two flip/flops used to latch two inputs into the ICS clock
+ * generator. The five inputs to the ICS are then
+ *
+ * ICS ET-4000
+ * --- ---
+ * FS0 CS0
+ * FS1 CS1
+ * FS2 ff0 flip/flop 0 output
+ * FS3 CS2
+ * FS4 ff1 flip/flop 1 output
+ *
+ * The flip/flops are loaded from CS0 and CS1. The flip/flops are
+ * latched by CS2, on the rising edge. After CS2 is set low, and then high,
+ * it is then set to its final value.
+ *
+ */
+ static unsigned char save1, save2;
+ unsigned char temp;
+ int iobase = VGAHW_GET_IOBASE();
+
+ switch (no) {
+ case CLK_REG_SAVE:
+ save1 = inb(0x3CC);
+ outb(iobase + 4, 0x34);
+ save2 = inb(iobase + 5);
+ break;
+ case CLK_REG_RESTORE:
+ outb(0x3C2, save1);
+ outw(iobase + 4, 0x34 | (save2 << 8));
+ break;
+ default:
+ temp = inb(0x3CC);
+ outb(0x3C2, (temp & 0xF3) | ((no & 0x10) >> 1) | (no & 0x04));
+ outw(iobase + 4, 0x0034);
+ outw(iobase + 4, 0x0234);
+ outw(iobase + 4, ((no & 0x08) << 6) | 0x34);
+ outb(0x3C2, (temp & 0xF3) | ((no << 2) & 0x0C));
+ }
+ return (TRUE);
+}
+
+
+#define BASE_FREQ 14.31818 /* MHz */
+void
+TsengcommonCalcClock(long freq, int min_m, int min_n1, int max_n1, int min_n2, int max_n2,
+ long freq_min, long freq_max,
+ unsigned char *mdiv, unsigned char *ndiv)
+{
+ double ffreq, ffreq_min, ffreq_max;
+ double div, diff, best_diff;
+ unsigned int m;
+ unsigned char n1, n2;
+ unsigned char best_n1 = 16 + 2, best_n2 = 2, best_m = 125 + 2;
+
+ PDEBUG(" commonCalcClock\n");
+ ffreq = freq / 1000.0 / BASE_FREQ;
+ ffreq_min = freq_min / 1000.0 / BASE_FREQ;
+ ffreq_max = freq_max / 1000.0 / BASE_FREQ;
+
+ if (ffreq < ffreq_min / (1 << max_n2)) {
+ ErrorF("invalid frequency %1.3f MHz [freq >= %1.3f MHz]\n",
+ ffreq * BASE_FREQ, ffreq_min * BASE_FREQ / (1 << max_n2));
+ ffreq = ffreq_min / (1 << max_n2);
+ }
+ if (ffreq > ffreq_max / (1 << min_n2)) {
+ ErrorF("invalid frequency %1.3f MHz [freq <= %1.3f MHz]\n",
+ ffreq * BASE_FREQ, ffreq_max * BASE_FREQ / (1 << min_n2));
+ ffreq = ffreq_max / (1 << min_n2);
+ }
+ /* work out suitable timings */
+
+ best_diff = ffreq;
+
+ for (n2 = min_n2; n2 <= max_n2; n2++) {
+ for (n1 = min_n1 + 2; n1 <= max_n1 + 2; n1++) {
+ m = (int)(ffreq * n1 * (1 << n2) + 0.5);
+ if (m < min_m + 2 || m > 127 + 2)
+ continue;
+ div = (double)(m) / (double)(n1);
+ if ((div >= ffreq_min) &&
+ (div <= ffreq_max)) {
+ diff = ffreq - div / (1 << n2);
+ if (diff < 0.0)
+ diff = -diff;
+ if (diff < best_diff) {
+ best_diff = diff;
+ best_m = m;
+ best_n1 = n1;
+ best_n2 = n2;
+ }
+ }
+ }
+ }
+
+#ifdef EXTENDED_DEBUG
+ ErrorF("Clock parameters for %1.6f MHz: m=%d, n1=%d, n2=%d\n",
+ ((double)(best_m) / (double)(best_n1) / (1 << best_n2)) * BASE_FREQ,
+ best_m - 2, best_n1 - 2, best_n2);
+#endif
+
+ if (max_n1 == 63)
+ *ndiv = (best_n1 - 2) | (best_n2 << 6);
+ else
+ *ndiv = (best_n1 - 2) | (best_n2 << 5);
+ *mdiv = best_m - 2;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_colexp.c b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_colexp.c
new file mode 100644
index 000000000..8aed301bb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_colexp.c
@@ -0,0 +1,547 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_colexp.c,v 1.9 1999/03/14 03:22:07 dawes Exp $ */
+
+
+
+
+
+/*
+ * ET4/6K acceleration interface -- color expansion primitives.
+ *
+ * Uses Harm Hanemaayer's generic acceleration interface (XAA).
+ *
+ * Author: Koen Gadeyne
+ *
+ * Much of the acceleration code is based on the XF86_W32 server code from
+ * Glenn Lai.
+ *
+ *
+ * Color expansion capabilities of the Tseng chip families:
+ *
+ * Chip screen-to-screen CPU-to-screen Supported depths
+ *
+ * ET4000W32/W32i No Yes 8bpp only
+ * ET4000W32p Yes Yes 8bpp only
+ * ET6000 Yes No 8/16/24/32 bpp
+ */
+
+#include "tseng.h"
+#include "tseng_acl.h"
+#include "tseng_inline.h"
+
+void TsengSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop, unsigned int planemask);
+
+void TsengSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int srcx, int srcy, int skipleft);
+
+void TsengSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft);
+
+void TsengSubsequentColorExpandScanline(ScrnInfoPtr pScrn,
+ int bufno);
+
+void TsengSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop, unsigned int planemask);
+
+void TsengSubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft);
+
+void TsengSubsequentColorExpandScanline_8bpp(ScrnInfoPtr pScrn, int bufno);
+void TsengSubsequentColorExpandScanline_16bpp(ScrnInfoPtr pScrn, int bufno);
+void TsengSubsequentColorExpandScanline_24bpp(ScrnInfoPtr pScrn, int bufno);
+void TsengSubsequentColorExpandScanline_32bpp(ScrnInfoPtr pScrn, int bufno);
+
+Bool
+TsengXAAInit_Colexp(ScrnInfoPtr pScrn)
+{
+ int i, j, r;
+ TsengPtr pTseng = TsengPTR(pScrn);
+ XAAInfoRecPtr pXAAInfo = pTseng->AccelInfoRec;
+
+ PDEBUG(" TsengXAAInit_Colexp\n");
+
+#ifdef TODO
+ if (OFLG_ISSET(OPTION_XAA_NO_COL_EXP, &vga256InfoRec.options))
+ return;
+#endif
+
+ /* FIXME! disable accelerated color expansion for W32/W32i until it's fixed */
+/* if (Is_W32 || Is_W32i) return; */
+
+ /*
+ * Screen-to-screen color expansion.
+ *
+ * Scanline-screen-to-screen color expansion is slower than
+ * CPU-to-screen color expansion.
+ */
+
+ pXAAInfo->ScreenToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_LSBFIRST |
+ SCANLINE_PAD_DWORD |
+ LEFT_EDGE_CLIPPING |
+ NO_PLANEMASK;
+
+#if 1
+ if (Is_ET6K || (Is_W32p && (pScrn->bitsPerPixel == 8))) {
+ pXAAInfo->SetupForScreenToScreenColorExpandFill =
+ TsengSetupForScreenToScreenColorExpandFill;
+ pXAAInfo->SubsequentScreenToScreenColorExpandFill =
+ TsengSubsequentScreenToScreenColorExpandFill;
+ }
+#endif
+
+ /*
+ * Scanline CPU to screen color expansion for all W32 engines.
+ *
+ * real CPU-to-screen color expansion is extremely tricky, and only
+ * works for 8bpp anyway.
+ *
+ * This also allows us to do 16, 24 and 32 bpp color expansion by first
+ * doubling the bitmap pattern before color-expanding it, because W32s
+ * can only do 8bpp color expansion.
+ */
+
+ pXAAInfo->ScanlineCPUToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_LSBFIRST |
+ SCANLINE_PAD_DWORD |
+ NO_PLANEMASK;
+
+#if 1
+ if (!Is_ET6K) {
+ pTseng->XAAScanlineColorExpandBuffers[0] =
+ xnfalloc(((pScrn->virtualX + 31)/32) * 4 * pTseng->Bytesperpixel);
+ if (pTseng->XAAScanlineColorExpandBuffers[0] == NULL) {
+ xf86Msg(X_ERROR, "Could not malloc color expansion scanline buffer.\n");
+ return FALSE;
+ }
+ pXAAInfo->NumScanlineColorExpandBuffers = 1;
+ pXAAInfo->ScanlineColorExpandBuffers = pTseng->XAAScanlineColorExpandBuffers;
+
+ pXAAInfo->SetupForScanlineCPUToScreenColorExpandFill =
+ TsengSetupForCPUToScreenColorExpandFill;
+
+ pXAAInfo->SubsequentScanlineCPUToScreenColorExpandFill =
+ TsengSubsequentScanlineCPUToScreenColorExpandFill;
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
+ pXAAInfo->SubsequentColorExpandScanline =
+ TsengSubsequentColorExpandScanline_8bpp;
+ break;
+ case 15:
+ case 16:
+ pXAAInfo->SubsequentColorExpandScanline =
+ TsengSubsequentColorExpandScanline_16bpp;
+ break;
+ case 24:
+ pXAAInfo->SubsequentColorExpandScanline =
+ TsengSubsequentColorExpandScanline_24bpp;
+ break;
+ case 32:
+ pXAAInfo->SubsequentColorExpandScanline =
+ TsengSubsequentColorExpandScanline_32bpp;
+ break;
+ }
+ /* create color expansion LUT (used for >8bpp only) */
+ pTseng->ColExpLUT = xnfalloc(sizeof(CARD32)*256);
+ if (pTseng->ColExpLUT == NULL) {
+ xf86Msg(X_ERROR, "Could not malloc color expansion tables.\n");
+ return FALSE;
+ }
+ for (i = 0; i < 256; i++) {
+ r = 0;
+ for (j = 7; j >= 0; j--) {
+ r <<= pTseng->Bytesperpixel;
+ if ((i >> j) & 1)
+ r |= (1 << pTseng->Bytesperpixel) - 1;
+ }
+ pTseng->ColExpLUT[i] = r;
+ /* ErrorF("0x%08X, ",r ); if ((i%8)==7) ErrorF("\n"); */
+ }
+ }
+#endif
+#if 1
+ if (Is_ET6K) {
+ /*
+ * Triple-buffering is needed to account for double-buffering of Tseng
+ * acceleration registers.
+ */
+ pXAAInfo->NumScanlineColorExpandBuffers = 3;
+ pXAAInfo->ScanlineColorExpandBuffers =
+ pTseng->XAAColorExpandBuffers;
+ pXAAInfo->SetupForScanlineCPUToScreenColorExpandFill =
+ TsengSetupForScreenToScreenColorExpandFill;
+ pXAAInfo->SubsequentScanlineCPUToScreenColorExpandFill =
+ TsengSubsequentScanlineCPUToScreenColorExpandFill;
+ pXAAInfo->SubsequentColorExpandScanline =
+ TsengSubsequentColorExpandScanline;
+
+ /* calculate memory addresses from video memory offsets */
+ for (i = 0; i < pXAAInfo->NumScanlineColorExpandBuffers; i++) {
+ pTseng->XAAColorExpandBuffers[i] =
+ pTseng->FbBase + pTseng->AccelColorExpandBufferOffsets[i];
+ }
+
+ /*
+ * for banked memory, translate those addresses to fall in the
+ * correct aperture. Color expansion uses aperture #0, which sits at
+ * pTseng->FbBase + 0x18000 + 48.
+ */
+ if (!pTseng->UseLinMem) {
+ for (i = 0; i < pXAAInfo->NumScanlineColorExpandBuffers; i++) {
+ pTseng->XAAColorExpandBuffers[i] =
+ pTseng->XAAColorExpandBuffers[i]
+ - pTseng->AccelColorExpandBufferOffsets[0]
+ + 0x18000 + 48;
+ }
+ }
+ pXAAInfo->ScanlineColorExpandBuffers = pTseng->XAAColorExpandBuffers;
+ }
+#endif
+
+#ifdef TSENG_CPU_TO_SCREEN_COLOREXPAND
+ /*
+ * CPU-to-screen color expansion doesn't seem to be reliable yet. The
+ * W32 needs the correct amount of data sent to it in this mode, or it
+ * hangs the machine until is does (?). Currently, the init code in this
+ * file or the XAA code that uses this does something wrong, so that
+ * occasionally we get accelerator timeouts, and after a few, complete
+ * system hangs.
+ *
+ * The W32 engine requires SCANLINE_NO_PAD, but that doesn't seem to
+ * work very well (accelerator hangs).
+ *
+ * What works is this: tell XAA that we have SCANLINE_PAD_DWORD, and then
+ * add the following code in TsengSubsequentCPUToScreenColorExpand():
+ * w = (w + 31) & ~31; this code rounds the width up to the nearest
+ * multiple of 32, and together with SCANLINE_PAD_DWORD, this makes
+ * CPU-to-screen color expansion work. Of course, the display isn't
+ * correct (4 chars are "blanked out" when only one is written, for
+ * example). But this shows that the principle works. But the code
+ * doesn't...
+ *
+ * The same thing goes for PAD_BYTE: this also works (with the same
+ * problems as SCANLINE_PAD_DWORD, although less prominent)
+ */
+
+ pXAAInfo->CPUToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_LSBFIRST |
+ SCANLINE_PAD_DWORD | /* no other choice */
+ CPU_TRANSFER_PAD_DWORD |
+ NO_PLANEMASK;
+
+ if (Is_W32_any && (pScrn->bitsPerPixel == 8)) {
+ pXAAInfo->SetupForCPUToScreenColorExpandFill =
+ TsengSetupForCPUToScreenColorExpandFill;
+ pXAAInfo->SubsequentCPUToScreenColorExpandFill =
+ TsengSubsequentCPUToScreenColorExpandFill;
+
+ /* we'll be using MMU aperture 2 */
+ pXAAInfo->ColorExpandBase = tsengCPU2ACLBase;
+ /* ErrorF("tsengCPU2ACLBase = 0x%x\n", tsengCPU2ACLBase); */
+ /* aperture size is 8kb in banked mode. Larger in linear mode, but 8kb is enough */
+ pXAAInfo->ColorExpandRange = 8192;
+ }
+#endif
+ return TRUE;
+}
+
+#define SET_FUNCTION_COLOREXPAND \
+ if (Is_ET6K) \
+ *ACL_MIX_CONTROL = 0x32; \
+ else \
+ *ACL_ROUTING_CONTROL = 0x08;
+
+#define SET_FUNCTION_COLOREXPAND_CPU \
+ *ACL_ROUTING_CONTROL = 0x02;
+
+static CARD32 ColorExpandDst;
+static int ce_skipleft;
+static int colexp_width_dwords;
+static int colexp_width_bytes;
+
+extern long MMioBase;
+
+
+
+void
+TsengSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ if (!Is_ET6K) {
+ /* the accelerator needs DWORD padding, and "w" is in PIXELS... */
+ colexp_width_dwords = (MULBPP(pTseng, w) + 31) >> 5;
+ colexp_width_bytes = (MULBPP(pTseng, w) + 7) >> 3;
+ }
+
+ ColorExpandDst = FBADDR(pTseng, x, y);
+ ce_skipleft = skipleft;
+
+ wait_acl_queue(pTseng);
+
+#if 0
+ *ACL_MIX_Y_OFFSET = w - 1;
+
+ ErrorF(" W=%d", w);
+#endif
+ SET_XY(pTseng, w, 1);
+}
+
+void
+TsengSubsequentColorExpandScanline(ScrnInfoPtr pScrn,
+ int bufno)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ wait_acl_queue(pTseng);
+
+ *ACL_MIX_ADDRESS = (pTseng->AccelColorExpandBufferOffsets[bufno] << 3) + ce_skipleft;
+ START_ACL(pTseng, ColorExpandDst);
+
+ /* move to next scanline */
+ ColorExpandDst += pTseng->line_width;
+
+ /*
+ * If not using triple-buffering, we need to wait for the queued
+ * register set to be transferred to the working register set here,
+ * because otherwise an e.g. double-buffering mechanism could overwrite
+ * the buffer that's currently being worked with with new data too soon.
+ *
+ * WAIT_QUEUE; // not needed with triple-buffering
+ */
+}
+
+
+
+/*
+ * We use this intermediate CPU-to-Screen color expansion because the one
+ * provided by XAA seems to lock up the accelerator engine.
+ *
+ * One of the main differences between the XAA approach and this one is that
+ * transfers are done per byte. I'm not sure if that is needed though.
+ */
+
+void TsengSubsequentColorExpandScanline_8bpp(ScrnInfoPtr pScrn, int bufno)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+ CARD8 *dest = (CARD8 *) tsengCPU2ACLBase;
+ int i;
+ CARD8 *bufptr;
+
+ i = colexp_width_bytes;
+ bufptr = (CARD8 *) (pTseng->XAAScanlineColorExpandBuffers[bufno]);
+
+ wait_acl_queue(pTseng);
+ START_ACL (pTseng, ColorExpandDst);
+
+/* *((LongP) (MMioBase + 0x08)) = (CARD32) ColorExpandDst;*/
+/* *(CARD32*)tsengCPU2ACLBase = (CARD32)ColorExpandDst; */
+
+ /* Copy scanline data to accelerator MMU aperture byte by byte */
+ while (i--) { /* FIXME: we need to take care of PCI bursting and MMU overflow here! */
+ *dest++ = *bufptr++;
+ }
+
+ /* move to next scanline */
+ ColorExpandDst += pTseng->line_width;
+}
+
+/*
+ * This function does direct memory-to-CPU bit doubling for color-expansion
+ * at 16bpp on W32 chips. They can only do 8bpp color expansion, so we have
+ * to expand the incoming data to 2bpp first.
+ */
+
+void TsengSubsequentColorExpandScanline_16bpp(ScrnInfoPtr pScrn, int bufno)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+ CARD8 *dest = (CARD8 *) tsengCPU2ACLBase;
+ int i;
+ CARD8 *bufptr;
+ register CARD32 bits16;
+
+ i = colexp_width_dwords * 2;
+ bufptr = (CARD8 *) (pTseng->XAAScanlineColorExpandBuffers[bufno]);
+
+ wait_acl_queue(pTseng);
+ START_ACL(pTseng, ColorExpandDst);
+
+ while (i--) {
+ bits16 = pTseng->ColExpLUT[*bufptr++];
+ *dest++ = bits16 & 0xFF;
+ *dest++ = (bits16 >> 8) & 0xFF;
+ }
+
+ /* move to next scanline */
+ ColorExpandDst += pTseng->line_width;
+}
+
+/*
+ * This function does direct memory-to-CPU bit doubling for color-expansion
+ * at 24bpp on W32 chips. They can only do 8bpp color expansion, so we have
+ * to expand the incoming data to 3bpp first.
+ */
+
+void TsengSubsequentColorExpandScanline_24bpp(ScrnInfoPtr pScrn, int bufno)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+ CARD8 *dest = (CARD8 *) tsengCPU2ACLBase;
+ int i, j = -1;
+ CARD8 *bufptr;
+ register CARD32 bits24;
+
+ i = colexp_width_dwords * 4;
+ bufptr = (CARD8 *) (pTseng->XAAScanlineColorExpandBuffers[bufno]);
+
+ wait_acl_queue(pTseng);
+ START_ACL(pTseng, ColorExpandDst);
+
+ /* take 8 input bits, expand to 3 output bytes */
+ bits24 = pTseng->ColExpLUT[*bufptr++];
+ while (i--) {
+ if ((j++) == 2) { /* "i % 3" operation is much to expensive */
+ j = 0;
+ bits24 = pTseng->ColExpLUT[*bufptr++];
+ }
+ *dest++ = bits24 & 0xFF;
+ bits24 >>= 8;
+ }
+
+ /* move to next scanline */
+ ColorExpandDst += pTseng->line_width;
+}
+
+/*
+ * This function does direct memory-to-CPU bit doubling for color-expansion
+ * at 32bpp on W32 chips. They can only do 8bpp color expansion, so we have
+ * to expand the incoming data to 4bpp first.
+ */
+
+void TsengSubsequentColorExpandScanline_32bpp(ScrnInfoPtr pScrn, int bufno)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+ CARD8 *dest = (CARD8 *) tsengCPU2ACLBase;
+ int i;
+ CARD8 *bufptr;
+ register CARD32 bits32;
+
+ i = colexp_width_dwords; /* amount of blocks of 8 bits to expand to 32 bits (=1 DWORD) */
+ bufptr = (CARD8 *) (pTseng->XAAScanlineColorExpandBuffers[bufno]);
+
+ wait_acl_queue(pTseng);
+ START_ACL(pTseng, ColorExpandDst);
+
+ while (i--) {
+ bits32 = pTseng->ColExpLUT[*bufptr++];
+ *dest++ = bits32 & 0xFF;
+ *dest++ = (bits32 >> 8) & 0xFF;
+ *dest++ = (bits32 >> 16) & 0xFF;
+ *dest++ = (bits32 >> 24) & 0xFF;
+ }
+
+ /* move to next scanline */
+ ColorExpandDst += pTseng->line_width;
+}
+
+/*
+ * CPU-to-Screen color expansion.
+ * This is for ET4000 only (The ET6000 cannot do this)
+ */
+
+void TsengSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop, unsigned int planemask)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+/* ErrorF("X"); */
+
+ PINGPONG();
+
+ wait_acl_queue(pTseng);
+
+ SET_FG_ROP(rop);
+ SET_BG_ROP_TR(rop, bg);
+
+ SET_XYDIR(0);
+
+ SET_FG_BG_COLOR(pTseng, fg, bg);
+
+ SET_FUNCTION_COLOREXPAND_CPU;
+
+ /* assure correct alignment of MIX address (ACL needs same alignment here as in MMU aperture) */
+ *ACL_MIX_ADDRESS = 0;
+}
+
+/*
+ * TsengSubsequentCPUToScreenColorExpand() is potentially dangerous:
+ * Not writing enough data to the MMU aperture for CPU-to-screen color
+ * expansion will eventually cause a system deadlock!
+ *
+ * Note that CPUToScreenColorExpand operations _always_ require a
+ * WAIT_INTERFACE before starting a new operation (this is empyrical,
+ * though)
+ */
+
+void TsengSubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+ int destaddr = FBADDR(pTseng, x, y);
+
+ /* ErrorF(" %dx%d|%d ",w,h,skipleft); */
+ if (skipleft)
+ ErrorF("Can't do: Skipleft = %d\n", skipleft);
+
+/* wait_acl_queue(); */
+ ErrorF("=========WAIT FIXME!\n");
+ WAIT_INTERFACE;
+
+ *ACL_MIX_Y_OFFSET = w - 1;
+ SET_XY(pTseng, w, h);
+ START_ACL(pTseng, destaddr);
+}
+
+
+void
+TsengSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop, unsigned int planemask)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+/* ErrorF("SSC "); */
+
+ PINGPONG();
+
+ wait_acl_queue(pTseng);
+
+ SET_FG_ROP(rop);
+ SET_BG_ROP_TR(rop, bg);
+
+ SET_FG_BG_COLOR(pTseng, fg, bg);
+
+ SET_FUNCTION_COLOREXPAND;
+
+ SET_XYDIR(0);
+}
+
+void
+TsengSubsequentScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int srcx, int srcy, int skipleft)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+ int destaddr = FBADDR(pTseng, x, y);
+
+/* int srcaddr = FBADDR(pTseng, srcx, srcy); */
+
+ wait_acl_queue(pTseng);
+
+ SET_XY(pTseng, w, h);
+ *ACL_MIX_ADDRESS = /* MIX address is in BITS */
+ (((srcy * pScrn->displayWidth) + srcx) * pScrn->bitsPerPixel) + skipleft;
+
+ *ACL_MIX_Y_OFFSET = pTseng->line_width << 3;
+
+ START_ACL(pTseng, destaddr);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_cursor.c b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_cursor.c
new file mode 100644
index 000000000..d27763a4b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_cursor.c
@@ -0,0 +1,266 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_cursor.c,v 1.14 1998/08/29 14:34:39 dawes Exp $ */
+
+
+
+
+
+#include "tseng.h"
+
+static void TsengShowCursor(ScrnInfoPtr pScrn);
+static void TsengHideCursor(ScrnInfoPtr pScrn);
+static void TsengSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
+static Bool TsengUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs);
+static void TsengSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
+static void TsengLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits);
+unsigned char *TsengRealizeCursor(xf86CursorInfoPtr infoPtr, CursorPtr pCurs);
+
+Bool
+TsengHWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TsengPtr pTseng = TsengPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+ int iobase = VGAHW_GET_IOBASE();
+ unsigned char tmp;
+
+ PDEBUG(" TsengHWCursorInit\n");
+
+ if (!pTseng->HWCursor)
+ return FALSE;
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if (!infoPtr)
+ return FALSE;
+
+ pTseng->CursorInfoRec = infoPtr;
+
+ /* calculate memory addres from video memory offsets */
+ pTseng->HWCursorBuffer =
+ pTseng->FbBase + pTseng->HWCursorBufferOffset;
+
+ /*
+ * for banked memory, translate this address to fall in the
+ * correct aperture. HWcursor uses aperture #0, which sits at
+ * pTseng->FbBase + 0x18000.
+ */
+ if (!pTseng->UseLinMem) {
+#ifdef TODO
+ pTseng->HWCursorBuffer =
+ pTseng->something
+ - pTseng->what
+ + 0x18000;
+#else
+ ErrorF("banked HW cursor not implemented yet!\n");
+#endif
+ }
+ /*
+ * Program the cursor image address in video memory. This never changes
+ * once the server has started, so we can set it here, once. The adress
+ * is given in doublewords.
+ */
+ if (Is_ET6K) {
+ /* bits 19:16 */
+ outb(iobase + 0x04, 0x0E);
+ tmp = inb(iobase + 0x05) & 0xF0;
+ outb(iobase + 0x05, tmp | (((pTseng->HWCursorBufferOffset / 4) >> 16) & 0x0F));
+ /* bits 15:8 */
+ outb(iobase + 0x04, 0x0F);
+ outb(iobase + 0x05, ((pTseng->HWCursorBufferOffset / 4) >> 8) & 0xFF);
+ /* on the ET6000, bits (7:0) are always 0 */
+ } else {
+ /* bits 19:16 */
+ outb(0x217A, 0xEA);
+ tmp = inb(0x217B) & 0xF0;
+ outb(0x217B, tmp | (((pTseng->HWCursorBufferOffset / 4) >> 16) & 0x0F));
+ /* bits 15:8 */
+ outb(0x217A, 0xE9);
+ outb(0x217B, ((pTseng->HWCursorBufferOffset / 4) >> 8) & 0xFF);
+ /* bits 7:0 */
+ outb(0x217A, 0xE8);
+ outb(0x217B, (pTseng->HWCursorBufferOffset / 4) & 0xFF);
+
+ /* this needs to be set for the sprite */
+ outb(0x217A, 0xEB);
+ outb(0x217B, 2);
+ outb(0x217A, 0xEC);
+ tmp = inb(0x217B);
+ outb(0x217B, tmp & 0xFE);
+ outb(0x217A, 0xEF);
+ tmp = inb(0x217B);
+ outb(0x217B, (tmp & 0xF8) | 0x02);
+ outb(0x217A, 0xEE);
+ outb(0x217B, 1);
+ }
+
+ /* set up the XAA HW cursor structure */
+ infoPtr->MaxWidth = 64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->Flags =
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
+ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+ HARDWARE_CURSOR_INVERT_MASK;
+ infoPtr->SetCursorColors = TsengSetCursorColors;
+ infoPtr->SetCursorPosition = TsengSetCursorPosition;
+ infoPtr->LoadCursorImage = TsengLoadCursorImage;
+ infoPtr->HideCursor = TsengHideCursor;
+ infoPtr->ShowCursor = TsengShowCursor;
+ infoPtr->UseHWCursor = TsengUseHWCursor;
+
+ return (xf86InitCursor(pScreen, infoPtr));
+}
+
+static Bool
+TsengUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ /* have this return false for DoubleScan and Interlaced ? */
+ return TRUE;
+}
+
+static void
+TsengShowCursor(ScrnInfoPtr pScrn)
+{
+ unsigned char tmp;
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ /* Enable the hardware cursor. */
+ if (Is_ET6K) {
+ tmp = inb(pTseng->IOAddress + 0x46);
+ outb(pTseng->IOAddress + 0x46, (tmp | 0x01));
+ } else {
+ outb(0x217A, 0xF7);
+ tmp = inb(0x217B);
+ outb(0x217B, tmp | 0x80);
+ }
+}
+
+static void
+TsengHideCursor(ScrnInfoPtr pScrn)
+{
+ unsigned char tmp;
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ /* Disable the hardware cursor. */
+ if (Is_ET6K) {
+ tmp = inb(pTseng->IOAddress + 0x46);
+ outb(pTseng->IOAddress + 0x46, (tmp & 0xfe));;
+ } else {
+ outb(0x217A, 0xF7);
+ tmp = inb(0x217B);
+ outb(0x217B, tmp & ~0x80);
+ }
+}
+
+static void
+TsengSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ int xorigin, yorigin;
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ /*
+ * If the cursor is partly out of screen at the left or top,
+ * we need to modify the origin.
+ */
+ xorigin = 0;
+ yorigin = 0;
+ if (x < 0) {
+ xorigin = -x;
+ x = 0;
+ }
+ if (y < 0) {
+ yorigin = -y;
+ y = 0;
+ }
+#ifdef TODO
+ /* Correct cursor position in DoubleScan modes */
+ if (XF86SCRNINFO(pScr)->modes->Flags & V_DBLSCAN)
+ y *= 2;
+#endif
+
+ if (Is_ET6K) {
+ outb(pTseng->IOAddress + 0x82, xorigin);
+ outb(pTseng->IOAddress + 0x83, yorigin);
+
+ outb(pTseng->IOAddress + 0x84, (x & 0xff)); /* X bits 7-0 */
+ outb(pTseng->IOAddress + 0x85, ((x >> 8) & 0x0f)); /* X bits 11-8 */
+
+ outb(pTseng->IOAddress + 0x86, (y & 0xff)); /* Y bits 7-0 */
+ outb(pTseng->IOAddress + 0x87, ((y >> 8) & 0x0f)); /* Y bits 11-8 */
+ } else {
+ outb(0x217A, 0xE2);
+ outb(0x217B, xorigin);
+ outb(0x217A, 0xE6);
+ outb(0x217B, yorigin);
+
+ outb(0x217A, 0xE0);
+ outb(0x217B, (x & 0xff)); /* X bits 7-0 */
+ outb(0x217A, 0xE1);
+ outb(0x217B, ((x >> 8) & 0x0f)); /* X bits 10-8 */
+
+ outb(0x217A, 0xE4);
+ outb(0x217B, (y & 0xff)); /* Y bits 7-0 */
+ outb(0x217A, 0xE5);
+ outb(0x217B, ((y >> 8) & 0x0f)); /* Y bits 10-8 */
+ }
+}
+
+/*
+ * The ET6000 cursor color is only 6 bits, with 2 bits per color. This
+ * is of course very inaccurate, but high-bit-depth color differences
+ * are only visible on _large_ planes of equal color. i.e. small areas
+ * of a certain color (like a cursor) don't need many bits per pixel at
+ * all, because the difference will not be seen.
+ *
+ * So it won't be as bad, but should still be documented nonetheless.
+ */
+static void
+TsengSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+ unsigned char et6k_fg, et6k_bg;
+
+ if (Is_ET6K) {
+ et6k_fg = (fg & 0x00000003)
+ | ((fg & 0x00000300) >> 6)
+ | ((fg & 0x00030000) >> 12);
+ et6k_bg = (bg & 0x00000003)
+ | ((bg & 0x00000300) >> 6)
+ | ((bg & 0x00030000) >> 12);
+
+ outb(pTseng->IOAddress + 0x67, 0x09); /* prepare for colour data */
+ outb(pTseng->IOAddress + 0x69, et6k_bg);
+ outb(pTseng->IOAddress + 0x69, et6k_fg);
+ } else {
+ /*
+ * The ET4000 uses color 0 as sprite color "0", and color 0xFF as
+ * sprite color "1". Changing colors implies changing colors 0 and
+ * 255. This is currently not implemented.
+ *
+ * In non-8bpp modes, this would result in always black and white
+ * colors (since the colormap isn't there to translate 0 and 255 to
+ * other colors). And besides, in non-8bpp, there seem to be TWO
+ * cursor images on the screen...
+ */
+ xf86Msg(X_ERROR, "Internal error: ET4000 hardware cursor color changes not implemented\n");
+ }
+}
+
+void
+TsengLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+#ifdef DEBUG_HWC
+ int i;
+ int d;
+
+ for (i = 0; i < 1024; i++) {
+ d = *(bits + i);
+ ErrorF("%d%d%d%d", d & 0x03, (d >> 2) & 0x03, (d >> 4) & 0x03, (d >> 6) & 0x03);
+ if ((i & 15) == 15)
+ ErrorF("\n");
+ }
+#endif
+ /* this assumes the apertures have been set up correctly for banked mode */
+ memcpy(pTseng->HWCursorBuffer, bits, 1024);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_dpms.c b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_dpms.c
new file mode 100644
index 000000000..8f93d0cb2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_dpms.c
@@ -0,0 +1,251 @@
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_dpms.c,v 1.8 1999/06/12 07:18:58 dawes Exp $ */
+
+
+
+
+
+#ifdef DPMSExtension
+
+#include "tseng.h"
+
+/*
+ * TsengCrtcDPMSSet --
+ *
+ * Sets VESA Display Power Management Signaling (DPMS) Mode.
+ * This routine is for the ET4000W32P rev. c and later, which can
+ * use CRTC indexed register 34 to turn off H/V Sync signals.
+ *
+ * '97 Harald Nordgård Hansen
+ */
+void
+TsengCrtcDPMSSet(ScrnInfoPtr pScrn,
+ int PowerManagementMode, int flags)
+{
+ unsigned char seq1, crtc34;
+ int iobase = VGAHWPTR(pScrn)->IOBase;
+
+ xf86EnableAccess(pScrn);
+ switch (PowerManagementMode) {
+ case DPMSModeOn:
+ default:
+ /* Screen: On; HSync: On, VSync: On */
+ seq1 = 0x00;
+ crtc34 = 0x00;
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off; HSync: Off, VSync: On */
+ seq1 = 0x20;
+ crtc34 = 0x01;
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off; HSync: On, VSync: Off */
+ seq1 = 0x20;
+ crtc34 = 0x20;
+ break;
+ case DPMSModeOff:
+ /* Screen: Off; HSync: Off, VSync: Off */
+ seq1 = 0x20;
+ crtc34 = 0x21;
+ break;
+ }
+ outb(0x3C4, 0x01); /* Select SEQ1 */
+ seq1 |= inb(0x3C5) & ~0x20;
+ outb(0x3C5, seq1);
+ outb(iobase + 4, 0x34); /* Select CRTC34 */
+ crtc34 |= inb(iobase + 5) & ~0x21;
+ outb(iobase + 5, crtc34);
+}
+
+/*
+ * TsengHVSyncDPMSSet --
+ *
+ * Sets VESA Display Power Management Signaling (DPMS) Mode.
+ * This routine is for Tseng et4000 chips that do not have any
+ * registers to disable sync output.
+ *
+ * The "classic" (standard VGA compatible) method; disabling all syncs,
+ * causes video memory corruption on Tseng cards, according to "Tseng
+ * ET4000/W32 family tech note #20":
+ *
+ * "Setting CRTC Indexed Register 17 bit 7 = 0 will disable the video
+ * syncs (=VESA DPMS power down), but will also disable DRAM refresh cycles"
+ *
+ * The method used here is derived from the same tech note, which describes
+ * a method to disable specific sync signals on chips that do not have
+ * direct support for it:
+ *
+ * To get vsync off, program VSYNC_START > VTOTAL
+ * (approximately). In particular, the formula used is:
+ *
+ * VSYNC.ADJ = (VTOT - VSYNC.NORM) + VTOT + 4
+ *
+ * To test for this state, test if VTOT + 1 < VSYNC
+ *
+ *
+ * To get hsync off, program HSYNC_START > HTOTAL
+ * (approximately). In particular, the following formula is used:
+ *
+ * HSYNC.ADJ = (HTOT - HSYNC.NORM) + HTOT + 7
+ *
+ * To test for this state, test if HTOT + 3 < HSYNC
+ *
+ * The advantage of these formulas is that the ON state can be restored by
+ * reversing the formula. The original state need not be stored anywhere...
+ *
+ * The trick in the above approach is obviously to put the start of the sync
+ * _beyond_ the total H or V counter range, which causes the sync to never
+ * toggle.
+ */
+void
+TsengHVSyncDPMSSet(ScrnInfoPtr pScrn,
+ int PowerManagementMode, int flags)
+{
+ unsigned char seq1, tmpb;
+ unsigned int HSync, VSync, HTot, VTot, tmp;
+ Bool chgHSync, chgVSync;
+ int iobase = VGAHWPTR(pScrn)->IOBase;
+
+ /* Code here to read the current values of HSync through VTot:
+ * HSYNC:
+ * bits 0..7 : CRTC index 0x04
+ * bit 8 : CRTC index 0x3F, bit 4
+ */
+ outb(iobase + 4, 0x04);
+ HSync = inb(iobase + 5);
+ outb(iobase + 4, 0x3F);
+ HSync += (inb(iobase + 5) & 0x10) << 4;
+ /* VSYNC:
+ * bits 0..7 : CRTC index 0x10
+ * bits 8..9 : CRTC index 0x07 bits 2 (VSYNC bit 8) and 7 (VSYNC bit 9)
+ * bit 10 : CRTC index 0x35 bit 3
+ */
+ outb(iobase + 4, 0x10);
+ VSync = inb(iobase + 5);
+ outb(iobase + 4, 0x07);
+ tmp = inb(iobase + 5);
+ VSync += ((tmp & 0x04) << 6) + ((tmp & 0x80) << 2);
+ outb(iobase + 4, 0x35);
+ VSync += (inb(iobase + 5) & 0x08) << 7;
+ /* HTOT:
+ * bits 0..7 : CRTC index 0x00.
+ * bit 8 : CRTC index 0x3F, bit 0
+ */
+ outb(iobase + 4, 0x00);
+ HTot = inb(iobase + 5);
+ outb(iobase + 4, 0x3F);
+ HTot += (inb(iobase + 5) & 0x01) << 8;
+ /* VTOT:
+ * bits 0..7 : CRTC index 0x06
+ * bits 8..9 : CRTC index 0x07 bits 0 (VTOT bit 8) and 5 (VTOT bit 9)
+ * bit 10 : CRTC index 0x35 bit 1
+ */
+ outb(iobase + 4, 0x06);
+ VTot = inb(iobase + 5);
+ outb(iobase + 4, 0x07);
+ tmp = inb(iobase + 5);
+ VTot += ((tmp & 0x01) << 8) + ((tmp & 0x20) << 4);
+ outb(iobase + 4, 0x35);
+ VTot += (inb(iobase + 5) & 0x02) << 9;
+
+ /* Don't write these unless we have to. */
+ chgHSync = chgVSync = FALSE;
+
+ switch (PowerManagementMode) {
+ case DPMSModeOn:
+ default:
+ /* Screen: On; HSync: On, VSync: On */
+ seq1 = 0x00;
+ if (HSync > HTot + 3) { /* Sync is off now, turn it on. */
+ HSync = (HTot - HSync) + HTot + 7;
+ chgHSync = TRUE;
+ }
+ if (VSync > VTot + 1) { /* Sync is off now, turn it on. */
+ VSync = (VTot - VSync) + VTot + 4;
+ chgVSync = TRUE;
+ }
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off; HSync: Off, VSync: On */
+ seq1 = 0x20;
+ if (HSync <= HTot + 3) { /* Sync is on now, turn it off. */
+ HSync = (HTot - HSync) + HTot + 7;
+ chgHSync = TRUE;
+ }
+ if (VSync > VTot + 1) { /* Sync is off now, turn it on. */
+ VSync = (VTot - VSync) + VTot + 4;
+ chgVSync = TRUE;
+ }
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off; HSync: On, VSync: Off */
+ seq1 = 0x20;
+ if (HSync > HTot + 3) { /* Sync is off now, turn it on. */
+ HSync = (HTot - HSync) + HTot + 7;
+ chgHSync = TRUE;
+ }
+ if (VSync <= VTot + 1) { /* Sync is on now, turn it off. */
+ VSync = (VTot - VSync) + VTot + 4;
+ chgVSync = TRUE;
+ }
+ break;
+ case DPMSModeOff:
+ /* Screen: Off; HSync: Off, VSync: Off */
+ seq1 = 0x20;
+ if (HSync <= HTot + 3) { /* Sync is on now, turn it off. */
+ HSync = (HTot - HSync) + HTot + 7;
+ chgHSync = TRUE;
+ }
+ if (VSync <= VTot + 1) { /* Sync is on now, turn it off. */
+ VSync = (VTot - VSync) + VTot + 4;
+ chgVSync = TRUE;
+ }
+ break;
+ }
+
+ /* If the new hsync or vsync overflows, don't change anything. */
+ if (HSync >= 1 << 9 || VSync >= 1 << 11) {
+ ErrorF("tseng: warning: Cannot go into DPMS from this resolution.\n");
+ chgVSync = chgHSync = FALSE;
+ }
+ /* The code to turn on and off video output is equal for all. */
+ if (chgHSync || chgVSync) {
+ outb(0x3C4, 0x01); /* Select SEQ1 */
+ seq1 |= inb(0x3C5) & ~0x20;
+ outb(0x3C5, seq1);
+ }
+ /* Then the code to write VSync and HSync to the card.
+ * HSYNC:
+ * bits 0..7 : CRTC index 0x04
+ * bit 8 : CRTC index 0x3F, bit 4
+ */
+ if (chgHSync) {
+ outb(iobase + 4, 0x04);
+ tmpb = HSync & 0xFF;
+ outb(iobase + 5, tmpb);
+ outb(iobase + 4, 0x3F);
+ tmpb = (HSync & 0x100) >> 4;
+ tmpb |= inb(iobase + 5) & ~0x10;
+ outb(iobase + 5, tmpb);
+ }
+ /* VSYNC:
+ * bits 0..7 : CRTC index 0x10
+ * bits 8..9 : CRTC index 0x07 bits 2 (VSYNC bit 8) and 7 (VSYNC bit 9)
+ * bit 10 : CRTC index 0x35 bit 3
+ */
+ if (chgVSync) {
+ outb(iobase + 4, 0x10);
+ tmpb = VSync & 0xFF;
+ outb(iobase + 5, tmpb);
+ outb(iobase + 4, 0x07);
+ tmpb = (VSync & 0x100) >> 6;
+ tmpb |= (VSync & 0x200) >> 2;
+ tmpb |= inb(iobase + 5) & ~0x84;
+ outb(iobase + 5, tmpb);
+ outb(iobase + 4, 0x35);
+ tmpb = (VSync & 0x400) >> 7;
+ tmpb |= inb(iobase + 5) & ~0x08;
+ outb(iobase + 5, tmpb);
+ }
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_driver.c
new file mode 100644
index 000000000..c16928e64
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_driver.c
@@ -0,0 +1,3207 @@
+/*
+ * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_driver.c,v 1.55 1999/06/27 09:20:23 dawes Exp $
+ *
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Roell not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Roell makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Thomas Roell, roell@informatik.tu-muenchen.de
+ * ET6000 and ET4000W32 16/24/32 bpp and acceleration support by Koen Gadeyne
+ *
+ * Large parts rewritten for XFree86 4.0 by Koen Gadeyne.
+ */
+/* $XConsortium: et4_driver.c /main/27 1996/10/28 04:48:15 kaleb $ */
+
+
+
+
+
+/*** Generic includes ***/
+
+#include "tseng.h" /* this includes most of the generic ones as well */
+#include "tseng_acl.h"
+
+/* All drivers initialising the SW cursor need this */
+#include "mipointer.h"
+
+/* All drivers implementing backing store need this */
+#include "mibstore.h"
+
+/*
+ * If using cfb, cfb.h is required. Select the others for the bpp values
+ * the driver supports.
+ */
+#define PSZ 8 /* needed for cfb.h */
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb24.h"
+#include "cfb32.h"
+#include "cfb24_32.h"
+#include "xf86RAC.h"
+#include "xf86Resources.h"
+
+/*** Chip-specific includes ***/
+
+/* #include "tseng_acl.h" */
+
+/*
+ * Forward definitions for the functions that make up the driver.
+ */
+
+/* Mandatory functions */
+static void TsengIdentify(int flags);
+static Bool TsengProbe(DriverPtr drv, int flags);
+static Bool TsengPreInit(ScrnInfoPtr pScrn, int flags);
+static Bool TsengScreenInit(int Index, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool TsengEnterVT(int scrnIndex, int flags);
+static void TsengLeaveVT(int scrnIndex, int flags);
+static Bool TsengCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool TsengSaveScreen(ScreenPtr pScreen, Bool unblank);
+
+/* Required if the driver supports mode switching */
+static Bool TsengSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+
+/* Required if the driver supports moving the viewport */
+static void TsengAdjustFrame(int scrnIndex, int x, int y, int flags);
+
+/* Optional functions */
+static void TsengFreeScreen(int scrnIndex, int flags);
+static ModeStatus TsengValidMode(int scrnIndex, DisplayModePtr mode,
+ Bool verbose, int flags);
+
+/* If driver-specific config file entries are needed, this must be defined */
+/*static Bool TsengParseConfig(ParseInfoPtr raw); */
+
+/* Internally used functions (some are defined in tseng.h) */
+static Bool TsengMapMem(ScrnInfoPtr pScrn);
+static Bool TsengUnmapMem(ScrnInfoPtr pScrn);
+static void TsengSave(ScrnInfoPtr pScrn);
+static void TsengRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, TsengRegPtr tsengReg);
+static Bool TsengModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static void TsengUnlock(void);
+static void TsengLock(void);
+
+static Bool ET4000DetailedProbe(t_tseng_type * chiptype, t_w32_revid * rev);
+
+/*
+ * This is intentionally screen-independent. It indicates the binding
+ * choice made in the first PreInit.
+ */
+static int pix24bpp = 0;
+
+#define VERSION 4000
+#define TSENG_NAME "TSENG"
+#define TSENG_DRIVER_NAME "tseng"
+#define TSENG_MAJOR_VERSION 1
+#define TSENG_MINOR_VERSION 0
+#define TSENG_PATCHLEVEL 0
+
+/*
+ * This contains the functions needed by the server after loading the
+ * driver module. It must be supplied, and gets added the driver list by
+ * the Module Setup funtion in the dynamic case. In the static case a
+ * reference to this is compiled in, and this requires that the name of
+ * this DriverRec be an upper-case version of the driver name.
+ */
+
+DriverRec TSENG =
+{
+ VERSION,
+ "unaccelerated driver for Tseng Labs ET4000, accelerated driver for Tseng Labs ET4000W32, W32i, W32p, ET6000 and ET6100 cards",
+ TsengIdentify,
+ TsengProbe,
+ NULL,
+ 0
+};
+
+/* sub-revisions are now dealt with in the ChipRev variable */
+static SymTabRec TsengChipsets[] =
+{
+ {TYPE_ET4000, "ET4000"},
+ {TYPE_ET4000W32, "ET4000W32"},
+ {TYPE_ET4000W32I, "ET4000W32i"},
+ {TYPE_ET4000W32P, "ET4000W32p"},
+ {TYPE_ET6000, "ET6000"},
+ {TYPE_ET6100, "ET6100"},
+ {-1, NULL}
+};
+
+/* Convert PCI ID to chipset name */
+static PciChipsets TsengPciChipsets[] =
+{
+ {TYPE_ET4000W32P, PCI_CHIP_ET4000_W32P_A, RES_SHARED_VGA},
+ {TYPE_ET4000W32P, PCI_CHIP_ET4000_W32P_B, RES_SHARED_VGA},
+ {TYPE_ET4000W32P, PCI_CHIP_ET4000_W32P_C, RES_SHARED_VGA},
+ {TYPE_ET4000W32P, PCI_CHIP_ET4000_W32P_D, RES_SHARED_VGA},
+ {TYPE_ET6000, PCI_CHIP_ET6000, RES_SHARED_VGA},
+ {-1, -1, RES_UNDEFINED}
+};
+
+static IsaChipsets TsengIsaChipsets[] =
+{
+ {TYPE_ET4000, RES_EXCLUSIVE_VGA},
+ {TYPE_ET4000W32, RES_EXCLUSIVE_VGA},
+ {TYPE_ET4000W32I, RES_EXCLUSIVE_VGA},
+ {-1, RES_UNDEFINED}
+};
+
+typedef enum {
+ OPTION_HIBIT_HIGH,
+ OPTION_HIBIT_LOW,
+ OPTION_SW_CURSOR,
+ OPTION_HW_CURSOR,
+ OPTION_PCI_BURST,
+ OPTION_SLOW_DRAM,
+ OPTION_MED_DRAM,
+ OPTION_FAST_DRAM,
+ OPTION_W32_INTERLEAVE,
+ OPTION_NOACCEL,
+ OPTION_NOCLOCKCHIP,
+ OPTION_LINEAR,
+ OPTION_SHOWCACHE,
+ OPTION_LEGEND,
+ OPTION_PCI_RETRY,
+ OPTION_SET_MCLK
+} TsengOpts;
+
+static OptionInfoRec TsengOptions[] =
+{
+ {OPTION_HIBIT_HIGH, "hibit_high", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_HIBIT_LOW, "hibit_low", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_PCI_BURST, "pci_burst", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_SLOW_DRAM, "slow_dram", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_MED_DRAM, "med_dram", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_FAST_DRAM, "fast_dram", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_W32_INTERLEAVE, "w32_interleave", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_NOCLOCKCHIP, "NoClockchip", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_LINEAR, "Linear", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_LEGEND, "Legend", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_PCI_RETRY, "PciRetry", OPTV_BOOLEAN,
+ {0}, FALSE},
+ {OPTION_SET_MCLK, "SetMClk", OPTV_FREQ,
+ {0}, FALSE},
+ {-1, NULL, OPTV_NONE,
+ {0}, FALSE}
+};
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(tsengSetup);
+
+static XF86ModuleVersionInfo tsengVersRec =
+{
+ "tseng",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ TSENG_MAJOR_VERSION, TSENG_MINOR_VERSION, TSENG_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV, /* This is a video driver */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0, 0, 0, 0}
+};
+
+/*
+ * This is the module init data for XFree86 modules.
+ *
+ * Its name has to be the driver name followed by ModuleData.
+ */
+XF86ModuleData tsengModuleData = { &tsengVersRec, tsengSetup, NULL };
+
+static pointer
+tsengSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = FALSE;
+
+ if (!setupDone) {
+ setupDone = TRUE;
+ xf86AddDriver(&TSENG, module, 0);
+
+ /*
+ * Modules that this driver always requires can be loaded here
+ * by calling LoadSubModule().
+ */
+
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer) 1;
+ } else {
+ if (errmaj)
+ *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+#endif /* XFree86LOADER */
+
+static Bool
+TsengGetRec(ScrnInfoPtr pScrn)
+{
+ PDEBUG(" TsengGetRec\n");
+ /*
+ * Allocate an TsengRec, and hook it into pScrn->driverPrivate.
+ * pScrn->driverPrivate is initialised to NULL, so we can check if
+ * the allocation has already been done.
+ */
+ if (pScrn->driverPrivate != NULL)
+ return TRUE;
+
+ pScrn->driverPrivate = xnfcalloc(sizeof(TsengRec), 1);
+ /* Initialise it here when needed (or possible) */
+
+ return TRUE;
+}
+
+static void
+TsengFreeRec(ScrnInfoPtr pScrn)
+{
+ PDEBUG(" TsengFreeRec\n");
+ if (pScrn->driverPrivate == NULL)
+ return;
+ xfree(pScrn->driverPrivate);
+ pScrn->driverPrivate = NULL;
+}
+
+static t_tseng_type
+TsengPCI2Type(ScrnInfoPtr pScrn, int ChipID)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ switch (ChipID) {
+ case PCI_CHIP_ET4000_W32P_A:
+ pTseng->ChipType = TYPE_ET4000W32P;
+ pTseng->ChipRev = W32REVID_A;
+ break;
+ case PCI_CHIP_ET4000_W32P_B:
+ pTseng->ChipType = TYPE_ET4000W32P;
+ pTseng->ChipRev = W32REVID_B;
+ break;
+ case PCI_CHIP_ET4000_W32P_C:
+ pTseng->ChipType = TYPE_ET4000W32P;
+ pTseng->ChipRev = W32REVID_C;
+ break;
+ case PCI_CHIP_ET4000_W32P_D:
+ pTseng->ChipType = TYPE_ET4000W32P;
+ pTseng->ChipRev = W32REVID_D;
+ break;
+ case PCI_CHIP_ET6000:
+ pTseng->ChipType = TYPE_ET6000;
+ pTseng->ChipRev = pTseng->PciInfo->chipRev; /* ET6000 != ET6100 */
+ if (pTseng->ChipRev >= ET6100REVID)
+ pTseng->ChipType = TYPE_ET6100;
+ break;
+ default:
+ xf86Msg(X_ERROR, "%s: Unknown Tseng PCI ID: %X\n", TSENG_NAME, ChipID);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void
+TsengIdentify(int flags)
+{
+ PDEBUG(" TsengIdentify\n");
+ xf86PrintChipsets(TSENG_NAME, "driver for Tseng Labs chipsets",
+ TsengChipsets);
+}
+
+static void
+TsengAssignFPtr(ScrnInfoPtr pScrn)
+{
+ pScrn->driverVersion = VERSION;
+ pScrn->driverName = TSENG_DRIVER_NAME;
+ pScrn->name = TSENG_NAME;
+ pScrn->Probe = TsengProbe;
+ pScrn->PreInit = TsengPreInit;
+ pScrn->ScreenInit = TsengScreenInit;
+ pScrn->SwitchMode = TsengSwitchMode;
+ pScrn->AdjustFrame = TsengAdjustFrame;
+ pScrn->EnterVT = TsengEnterVT;
+ pScrn->LeaveVT = TsengLeaveVT;
+ pScrn->FreeScreen = TsengFreeScreen;
+ pScrn->ValidMode = TsengValidMode;
+}
+
+/* unlock ET4000 using KEY register */
+static void
+TsengUnlock(void)
+{
+ unsigned char temp;
+ int iobase = VGAHW_GET_IOBASE();
+
+ PDEBUG(" TsengUnlock\n");
+ outb(0x3BF, 0x03);
+ outb(iobase + 8, 0xA0);
+ outb(iobase + 4, 0x11);
+ temp = inb(iobase + 5);
+ outb(iobase + 5, temp & 0x7F);
+}
+
+/* lock ET4000 using KEY register. FIXME: should restore old lock status instead */
+static void
+TsengLock(void)
+{
+ unsigned char temp;
+ int iobase = VGAHW_GET_IOBASE();
+
+ PDEBUG(" TsengLock\n");
+ outb(iobase + 4, 0x11);
+ temp = inb(iobase + 5);
+ outb(iobase + 5, temp | 0x80);
+ outb(iobase + 8, 0x00);
+ outb(0x3D8, 0x29);
+ outb(0x3BF, 0x01);
+}
+
+/*
+ * ET4000AutoDetect -- Old-style autodetection code (by register probing)
+ *
+ * This code is only called when the chipset is not given beforehand,
+ * and if the PCI code hasn't detected one previously.
+ */
+static Bool
+ET4000MinimalProbe(void)
+{
+ unsigned char temp, origVal, newVal;
+ int iobase;
+
+ PDEBUG(" ET4000MinimalProbe\n");
+ /*
+ * Note, the vgaHW module cannot be used here, but there are
+ * some macros in vgaHW.h that can be used.
+ */
+ iobase = VGAHW_GET_IOBASE();
+
+ /*
+ * Check first that there is a ATC[16] register and then look at
+ * CRTC[33]. If both are R/W correctly it's a ET4000 !
+ */
+ temp = inb(iobase + 0x0A);
+ TsengUnlock(); /* only ATC 0x16 is protected by KEY */
+ outb(0x3C0, 0x16 | 0x20);
+ origVal = inb(0x3C1);
+ outb(0x3C0, origVal ^ 0x10);
+ outb(0x3C0, 0x16 | 0x20);
+ newVal = inb(0x3C1);
+ outb(0x3C0, origVal);
+/* TsengLock(); FIXME: RESTORE OLD CONTENTS INSTEAD ! */
+ if (newVal != (origVal ^ 0x10)) {
+ return (FALSE);
+ }
+ outb(iobase + 0x04, 0x33);
+ origVal = inb(iobase + 0x05);
+ outb(iobase + 0x05, origVal ^ 0x0F);
+ newVal = inb(iobase + 0x05);
+ outb(iobase + 0x05, origVal);
+ if (newVal != (origVal ^ 0x0F)) {
+ return (FALSE);
+ }
+ return TRUE;
+}
+
+static int
+TsengFindIsaDevice()
+{
+ /* XXX Need to implement this */
+ return -1;
+}
+
+static Bool
+TsengProbe(DriverPtr drv, int flags)
+{
+ int i;
+ GDevPtr *devSections;
+ int numDevSections;
+ int numUsed;
+ int *usedChips;
+ Bool foundScreen = FALSE;
+
+
+ PDEBUG(" TsengProbe\n");
+ /*
+ * The aim here is to find all cards that this driver can handle,
+ * and for the ones not already claimed by another driver, claim the
+ * slot, and allocate a ScrnInfoRec.
+ *
+ * This should be a minimal probe, and it should under no circumstances
+ * change the state of the hardware. Because a device is found, don't
+ * assume that it will be used. Don't do any initialisations other than
+ * the required ScrnInfoRec initialisations. Don't allocate any new
+ * data structures.
+ */
+
+ /*
+ * Find the config file Device sections that match this
+ * driver, and return if there are none.
+ */
+ if ((numDevSections = xf86MatchDevice(TSENG_DRIVER_NAME,
+ &devSections)) <= 0) {
+ return FALSE;
+ }
+
+ /* XXX maybe this can go some time soon */
+ /*
+ * for the Tseng server, there can only be one matching
+ * device section. So issue a warning if more than one show up.
+ * Multiple Tseng cards in the same machine are not possible.
+ */
+ /*
+ * If this is a PCI card, "probing" just amounts to checking the PCI
+ * data that the server has already collected. If there is none,
+ * check for non-PCI boards.
+ *
+ * The provided xf86MatchPciInstances() helper takes care of
+ * the details.
+ */
+ numUsed = 0;
+ if (xf86GetPciVideoInfo() != NULL) {
+ numUsed = xf86MatchPciInstances(TSENG_NAME, PCI_VENDOR_TSENG,
+ TsengChipsets, TsengPciChipsets,
+ devSections,numDevSections, drv,
+ &usedChips);
+ if (numUsed > 0) {
+ for (i = 0; i < numUsed; i++) {
+ /* Allocate a ScrnInfoRec */
+ ScrnInfoPtr pScrn = xf86AllocateScreen(drv,0);
+ TsengAssignFPtr(pScrn);
+ xf86ConfigActivePciEntity(pScrn,usedChips[i],TsengPciChipsets,
+ NULL,NULL,NULL,NULL,NULL);
+ foundScreen = TRUE;
+ }
+ xfree(usedChips);
+ }
+ }
+
+ /* Check for non-PCI cards */
+ numUsed = xf86MatchIsaInstances(TSENG_NAME, TsengChipsets,
+ TsengIsaChipsets,drv, TsengFindIsaDevice, devSections,
+ numDevSections, &usedChips);
+ if (numUsed >= 0) {
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = xf86AllocateScreen(drv,0);
+ TsengAssignFPtr(pScrn);
+ foundScreen = TRUE;
+ xf86ConfigActiveIsaEntity(pScrn,usedChips[i],TsengIsaChipsets,
+ NULL,NULL,NULL,NULL,NULL);
+ }
+ xfree(usedChips);
+ }
+ xfree(devSections);
+ return foundScreen;
+}
+
+/* The PCI part of TsengPreInit() */
+static Bool
+TsengPreInitPCI(ScrnInfoPtr pScrn)
+{
+ MessageType from;
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ PDEBUG(" TsengPreInitPCI\n");
+ /*
+ * * Set the ChipType and ChipRev, allowing config file entries to
+ * * override.
+ */
+ if (pTseng->pEnt->device->chipset && *pTseng->pEnt->device->chipset) {
+ /* chipset given as a string in the config file */
+ pScrn->chipset = pTseng->pEnt->device->chipset;
+ pTseng->ChipType = xf86StringToToken(TsengChipsets, pScrn->chipset);
+ /* FIXME: still need to probe for W32p revision here */
+ from = X_CONFIG;
+ } else if (pTseng->pEnt->device->chipID >= 0) {
+ /* chipset given as a PCI ID in the config file */
+ if (!TsengPCI2Type(pScrn, pTseng->pEnt->device->chipID))
+ return FALSE;
+ pScrn->chipset = (char *)xf86TokenToString(TsengChipsets, pTseng->ChipType);
+ from = X_CONFIG;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
+ pTseng->ChipType);
+ } else {
+ /* probe for chipset type */
+ from = X_PROBED;
+ if (!TsengPCI2Type(pScrn, pTseng->PciInfo->chipType))
+ return FALSE;
+ pScrn->chipset = (char *)xf86TokenToString(TsengChipsets, pTseng->ChipType);
+ }
+
+ if (pTseng->pEnt->device->chipRev >= 0) {
+ pTseng->ChipRev = pTseng->pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pTseng->ChipRev);
+ if ((pTseng->ChipType == TYPE_ET6000) && (pTseng->ChipRev >= ET6100REVID))
+ pTseng->ChipType = TYPE_ET6100;
+ } else {
+ t_tseng_type dum_chiptype;
+ t_w32_revid rev;
+ if (Is_ET6K) {
+ pTseng->ChipRev = pTseng->PciInfo->chipRev;
+ } else {
+ /*
+ * on W32p cards, the PCI ChipRev field is always 0 (it is not
+ * implemented). We will use the ChipRev field to distinguish
+ * between revisions A through D, so we set it up with the
+ * standard register-probing "Detailed Probe" instead.
+ */
+ ET4000DetailedProbe(&dum_chiptype, &rev);
+ pTseng->ChipRev = rev;
+ }
+ }
+
+ if (Is_ET6K) {
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
+ } else {
+ char ch_rev;
+ switch (pTseng->ChipRev) {
+ case W32REVID_A:
+ ch_rev = 'A';
+ break;
+ case W32REVID_B:
+ ch_rev = 'B';
+ break;
+ case W32REVID_C:
+ ch_rev = 'C';
+ break;
+ case W32REVID_D:
+ ch_rev = 'D';
+ break;
+ default:
+ ch_rev = 'X';
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\" (rev %c)\n",
+ pScrn->chipset, ch_rev);
+ }
+
+ pTseng->PciTag = pciTag(pTseng->PciInfo->bus, pTseng->PciInfo->device,
+ pTseng->PciInfo->func);
+
+ /* only the ET6000 implements a PCI IO address */
+ if (Is_ET6K) {
+ if (pTseng->pEnt->device->IOBase != 0) {
+ pTseng->IOAddress = pTseng->pEnt->device->IOBase;
+ from = X_CONFIG;
+ } else {
+ if ((pTseng->PciInfo->ioBase[1]) != 0) {
+ pTseng->IOAddress = pTseng->PciInfo->ioBase[1];
+ from = X_PROBED;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid PCI I/O address in PCI config space\n");
+ return FALSE;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "PCI I/O registers at 0x%lX\n",
+ (unsigned long)pTseng->IOAddress);
+ }
+
+ pTseng->LinFbAddressMask = 0xFF000000;
+
+ return TRUE;
+}
+
+/*
+ * This is a more detailed probe. We already know it's a Tseng chip from
+ * TsengPreInit() and ET4000MinimalProbe().
+ */
+
+static Bool
+ET4000DetailedProbe(t_tseng_type * chiptype, t_w32_revid * rev)
+{
+ unsigned char temp, origVal, newVal;
+
+ PDEBUG(" ET4000DetailedProbe\n");
+
+ /*
+ * We know it's an ET4000, now check for an ET4000/W32.
+ * Test for writability of 0x3cb.
+ */
+
+ origVal = inb(0x3cb);
+ outb(0x3cb, 0x33); /* Arbitrary value */
+ newVal = inb(0x3cb);
+ outb(0x3cb, origVal);
+ if (newVal != 0x33) { /* not a W32; so it's a standard ET4000 */
+ *chiptype = TYPE_ET4000;
+ *rev = TSENGNOREV;
+ return TRUE;
+ }
+ /* We have an ET4000/W32. Now determine the type. */
+ outb(0x217a, 0xec);
+ temp = inb(0x217b) >> 4;
+ switch (temp) {
+ case 0: /* ET4000/W32 */
+ *chiptype = TYPE_ET4000W32;
+ break;
+ case 1: /* ET4000/W32i */
+ *chiptype = TYPE_ET4000W32I;
+ *rev = W32REVID_A;
+ break;
+ case 3: /* ET4000/W32i rev b */
+ *chiptype = TYPE_ET4000W32I;
+ *rev = W32REVID_B;
+ break;
+ case 11: /* ET4000/W32i rev c */
+ *chiptype = TYPE_ET4000W32I;
+ *rev = W32REVID_C;
+ break;
+ case 2: /* ET4000/W32p rev a */
+ *chiptype = TYPE_ET4000W32P;
+ *rev = W32REVID_A;
+ break;
+ case 5: /* ET4000/W32p rev b */
+ *chiptype = TYPE_ET4000W32P;
+ *rev = W32REVID_B;
+ break;
+ case 6: /* ET4000/W32p rev d */
+ *chiptype = TYPE_ET4000W32P;
+ *rev = W32REVID_D;
+ break;
+ case 7: /* ET4000/W32p rev c */
+ *chiptype = TYPE_ET4000W32P;
+ *rev = W32REVID_C;
+ break;
+ default:
+ return (FALSE);
+ }
+
+ return (TRUE);
+}
+
+/*
+ * TsengFindBusType --
+ * determine bus interface type
+ * (also determines Lin Mem address mask, because that depends on bustype)
+ *
+ * We don't need to bother with PCI busses here: TsengPreInitPCI() took care
+ * of that. This code isn't called if it's a PCI bus anyway.
+ */
+
+static void
+TsengFindNonPciBusType(ScrnInfoPtr pScrn)
+{
+ unsigned char bus;
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ PDEBUG(" TsengFindNonPciBusType\n");
+ pTseng->Bustype = T_BUS_ISA;
+ pTseng->Linmem_1meg = FALSE;
+ pTseng->LinFbAddressMask = 0;
+
+ switch (pTseng->ChipType) {
+ case TYPE_ET4000:
+ break;
+ case TYPE_ET4000W32:
+ case TYPE_ET4000W32I:
+ /*
+ * Notation: SMx = bit x of Segment Map Comparator (CRTC index 0x30)
+ *
+ * We assume the driver code disables the image port (which it does)
+ *
+ * ISA: [ A23==SEGE, A22, A21, A20 ] == [ SM1, SM0, 0, 0 ]
+ * MCA: [ A24, A23, A22, A21, A20 ] == [ SM2, SM1, SM0, 0, 0 ]
+ * VLB: [ /A26, /A25, /A24, A23, A22, A21, A20 ] == ("/" means inverted!)
+ * [ SM4, SM3, SM2, SM1, SM0, 0 , 0 ]
+ */
+ outb(0x217A, 0xEF);
+ bus = inb(0x217B) & 0x60; /* Determine bus type */
+ switch (bus) {
+ case 0x40:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected W32/W32i bus type: MCA\n");
+ pTseng->Bustype = T_BUS_MCA;
+ pTseng->LinFbAddressMask = 0x01C00000; /* MADE24, A23 and A22 are decoded */
+ break;
+ case 0x60:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected W32/W32i bus type: Local Bus\n");
+ pTseng->Bustype = T_BUS_VLB;
+ pTseng->LinFbAddressMask = 0x07C00000; /* A26..A22 are decoded */
+ break;
+ case 0x00:
+ case 0x20:
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected W32/W32i bus type (0x%02X): ISA\n", bus);
+ pTseng->Bustype = T_BUS_ISA;
+ pTseng->LinFbAddressMask = 0x00C00000; /* SEGE and A22 are decoded */
+ break;
+ }
+ break;
+ case TYPE_ET4000W32P:
+ outb(0x217A, 0xEF);
+ bus = inb(0x217B) >> 3; /* Determine bus type */
+ switch (bus) {
+ case 0x1C: /* PCI case already handled in TsengPreInitPCI() */
+ pTseng->Bustype = T_BUS_VLB;
+ pTseng->LinFbAddressMask = 0x3FC00000; /* A29..A22 */
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected W32p bus type: Local Buffered Bus\n");
+ pTseng->Linmem_1meg = TRUE; /* IMA bus support allows for only 1M linear memory */
+ break;
+ case 0x13:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected W32p bus type: Local Bus (option 1a)\n");
+ pTseng->Bustype = T_BUS_VLB;
+ if (pTseng->ChipRev == W32REVID_A)
+ pTseng->LinFbAddressMask = 0x07C00000;
+ else
+ pTseng->LinFbAddressMask = 0x1FC00000; /* SEGI,A27..A22 */
+ break;
+ case 0x11:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected W32p bus type: Local Bus (option 1b)\n");
+ pTseng->Bustype = T_BUS_VLB;
+ pTseng->LinFbAddressMask = 0x00C00000; /* SEGI,A22 */
+ pTseng->Linmem_1meg = TRUE; /* IMA bus support allows for only 1M linear memory */
+ break;
+ case 0x08:
+ case 0x0B:
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected W32p bus type: Local Bus (option 2)\n");
+ pTseng->Bustype = T_BUS_VLB;
+ pTseng->LinFbAddressMask = 0x3FC00000; /* A29..A22 */
+ break;
+ }
+ if (Is_W32p_cd && (pTseng->LinFbAddressMask = 0x3FC00000))
+ pTseng->LinFbAddressMask |= 0xC0000000; /* A31,A30 decoded from PCI config space */
+ break;
+ case TYPE_ET6000:
+ case TYPE_ET6100:
+ pTseng->Bustype = T_BUS_PCI;
+ pTseng->LinFbAddressMask = 0xFF000000;
+ break;
+ }
+}
+
+/* The TsengPreInit() part for non-PCI busses */
+static Bool
+TsengPreInitNoPCI(ScrnInfoPtr pScrn)
+{
+ MessageType from;
+ t_w32_revid rev = TSENGNOREV;
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ PDEBUG(" TsengPreInitNoPCI\n");
+ /*
+ * Set the ChipType and ChipRev, allowing config file entries to
+ * override.
+ */
+ if (pTseng->pEnt->device->chipset && *pTseng->pEnt->device->chipset) {
+ /* chipset given as a string in the config file */
+ pScrn->chipset = pTseng->pEnt->device->chipset;
+ pTseng->ChipType = xf86StringToToken(TsengChipsets, pScrn->chipset);
+ from = X_CONFIG;
+ } else if (pTseng->pEnt->device->chipID > 0) {
+ /* chipset given as a PCI ID in the config file */
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ChipID override only possible for PCI cards\n");
+ return FALSE;
+ } else {
+ from = X_PROBED;
+ if (!ET4000DetailedProbe(&(pTseng->ChipType), &rev)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unknown Tseng chip detected. Try chipset override.\n");
+ return FALSE;
+ }
+ pScrn->chipset = (char *)xf86TokenToString(TsengChipsets, pTseng->ChipType);
+ }
+ if (pTseng->pEnt->device->chipRev >= 0) {
+ pTseng->ChipRev = pTseng->pEnt->device->chipRev;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
+ pTseng->ChipRev);
+ } else {
+ pTseng->ChipRev = rev;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset);
+
+ TsengFindNonPciBusType(pScrn);
+
+ return TRUE;
+}
+
+/*
+ * The 8*32kb ET6000 MDRAM granularity causes the more general probe to
+ * detect too much memory in some configurations, because that code has a
+ * 8-bank (=256k) granularity. E.g. it fails to recognize 2.25 MB of memory
+ * (detects 2.5 instead). This function goes to check if the RAM is actually
+ * there. MDRAM comes in multiples of 4 banks (16, 24, 32, 36, 40, 64, 72,
+ * 80, ... 32kb-banks), so checking each 64k block should be enough granularity.
+ *
+ * No more than the amount of refreshed RAM is checked. Non-refreshed RAM
+ * won't work anyway.
+ *
+ * The same code could be used on other Tseng chips, or even on ANY
+ * VGA board, but probably only in case of trouble.
+ *
+ * FIXME: this should be done using linear memory
+ */
+#define VIDMEM ((volatile CARD32*)check_vgabase)
+#define SEGSIZE (64) /* kb */
+
+#define ET6K_SETSEG(seg) \
+ outb(0x3CB, ((seg) & 0x30) | ((seg) >> 4)); \
+ outb(0x3CD, ((seg) & 0x0f) | ((seg) << 4));
+
+static int
+et6000_check_videoram(ScrnInfoPtr pScrn, int ram)
+{
+ unsigned char oldSegSel1, oldSegSel2, oldGR5, oldGR6, oldSEQ2, oldSEQ4;
+ int segment, i;
+ int real_ram = 0;
+ pointer check_vgabase;
+ Bool fooled = FALSE;
+ int save_vidmem;
+
+ PDEBUG(" et6000_check_videoram\n");
+ if (ram > 4096) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Detected more than 4096 kb of video RAM. Clipped to 4096kb\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ " (Tseng VGA chips can only use 4096kb).\n");
+ ram = 4096;
+ }
+ if (!vgaHWMapMem(pScrn)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Could not map VGA memory to check for video memory.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ " Detected amount may be wrong.\n");
+ return ram;
+ }
+ check_vgabase = (VGAHWPTR(pScrn)->Base);
+
+ /*
+ * We need to set the VGA controller in VGA graphics mode, or else we won't
+ * be able to access the full 4MB memory range. First, we save the
+ * registers we modify, of course.
+ */
+
+ oldSegSel1 = inb(0x3CD);
+ oldSegSel2 = inb(0x3CB);
+ outb(0x3CE, 5);
+ oldGR5 = inb(0x3CF);
+ outb(0x3CE, 6);
+ oldGR6 = inb(0x3CF);
+ outb(0x3C4, 2);
+ oldSEQ2 = inb(0x3C5);
+ outb(0x3C4, 4);
+ oldSEQ4 = inb(0x3C5);
+
+ /* set graphics mode */
+ outb(0x3CE, 6);
+ outb(0x3CF, 5);
+ outb(0x3CE, 5);
+ outb(0x3CF, 0x40);
+ outb(0x3C4, 2);
+ outb(0x3C5, 0x0f);
+ outb(0x3C4, 4);
+ outb(0x3C5, 0x0e);
+
+ /*
+ * count down from presumed amount of memory in SEGSIZE steps, and
+ * look at each segment for real RAM.
+ *
+ * To select a segment, we cannot use ET4000W32SetReadWrite(), since
+ * that requires the ScreenPtr, which we don't have here.
+ */
+
+ for (segment = (ram / SEGSIZE) - 1; segment >= 0; segment--) {
+ /* select the segment */
+ ET6K_SETSEG(segment);
+
+ /* save contents of memory probing location */
+ save_vidmem = *(VIDMEM);
+
+ /* test with pattern */
+ *VIDMEM = 0xAAAA5555;
+ if (*VIDMEM != 0xAAAA5555) {
+ *VIDMEM = save_vidmem;
+ continue;
+ }
+ /* test with inverted pattern */
+ *VIDMEM = 0x5555AAAA;
+ if (*VIDMEM != 0x5555AAAA) {
+ *VIDMEM = save_vidmem;
+ continue;
+ }
+ /*
+ * If we get here, the memory seems to be writable/readable
+ * Now check if we aren't fooled by address wrapping (mirroring)
+ */
+ fooled = FALSE;
+ for (i = segment - 1; i >= 0; i--) {
+ /* select the segment */
+ ET6K_SETSEG(i);
+ outb(0x3CB, (i & 0x30) | (i >> 4));
+ outb(0x3CD, (i & 0x0f) | (i << 4));
+ if (*VIDMEM == 0x5555AAAA) {
+ /*
+ * Seems like address wrap, but there could of course be
+ * 0x5555AAAA in here by accident, so we check with another
+ * pattern again.
+ */
+ ET6K_SETSEG(segment);
+ /* test with other pattern again */
+ *VIDMEM = 0xAAAA5555;
+ ET6K_SETSEG(i);
+ if (*VIDMEM == 0xAAAA5555) {
+ /* now we're sure: this is not real memory */
+ fooled = TRUE;
+ break;
+ }
+ }
+ }
+ if (!fooled) {
+ real_ram = (segment + 1) * SEGSIZE;
+ break;
+ }
+ /* restore old contents again */
+ ET6K_SETSEG(segment);
+ *VIDMEM = save_vidmem;
+ }
+
+ /* restore original register contents */
+ outb(0x3CD, oldSegSel1);
+ outb(0x3CB, oldSegSel2);
+ outb(0x3CE, 5);
+ outb(0x3CF, oldGR5);
+ outb(0x3CE, 6);
+ outb(0x3CF, oldGR6);
+ outb(0x3C4, 2);
+ outb(0x3C5, oldSEQ2);
+ outb(0x3C4, 4);
+ outb(0x3C5, oldSEQ4);
+
+ vgaHWUnmapMem(pScrn);
+ return real_ram;
+}
+
+/*
+ * Handle amount of allowed memory: some combinations can't use all
+ * available memory. Should we still allow the user to override this?
+ *
+ * This must be called AFTER the decision has been made to use linear mode
+ * and/or acceleration, or the memory limit code won't be able to work.
+ */
+
+static int
+TsengDoMemLimit(ScrnInfoPtr pScrn, int ram, int limit, char *reason)
+{
+ if (ram > limit) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Only %d kb of memory can be used %s.\n",
+ limit, reason);
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Reducing video memory to %d kb.\n", limit);
+ ram = limit;
+ }
+ return ram;
+}
+
+static int
+TsengLimitMem(ScrnInfoPtr pScrn, int ram)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ if (pTseng->UseLinMem && pTseng->Linmem_1meg) {
+ TsengDoMemLimit(pScrn, ram, 1024, "in linear mode on this VGA board/bus configuration");
+ }
+ if (pTseng->UseAccel && pTseng->UseLinMem) {
+ if (Is_W32_any) {
+ /* <= W32p_ab :
+ * 2 MB direct access + 2*512kb via apertures MBP0 and MBP1
+ * == W32p_cd :
+ * 2*1MB via apertures MBP0 and MBP1
+ */
+ if (Is_W32p_cd)
+ TsengDoMemLimit(pScrn, ram, 2048, "in linear + accelerated mode on W32p rev c and d");
+
+ TsengDoMemLimit(pScrn, ram, 2048 + 1024, "in linear + accelerated mode on W32/W32i/W32p");
+
+ /* upper 516kb of 4MB linear map used for "externally mapped registers" */
+ TsengDoMemLimit(pScrn, ram, 4096 - 516, "in linear + accelerated mode on W32/W32i/W32p");
+ }
+ if (Is_ET6K) {
+ /* upper 8kb used for externally mapped and memory mapped registers */
+ TsengDoMemLimit(pScrn, ram, 4096 - 8, "in linear + accelerated mode on ET6000/6100");
+ }
+ }
+ TsengDoMemLimit(pScrn, ram, 4096, "on any Tseng card");
+ return ram;
+}
+
+/*
+ * TsengDetectMem --
+ * try to find amount of video memory installed.
+ *
+ */
+
+static int
+TsengDetectMem(ScrnInfoPtr pScrn)
+{
+ unsigned char config;
+ int ramtype = 0;
+ int ram = 0;
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ PDEBUG(" TsengDetectMem\n");
+ if (Is_ET6K) {
+ ramtype = inb(0x3C2) & 0x03;
+ switch (ramtype) {
+ case 0x03: /* MDRAM */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Video memory type: Multibank DRAM (MDRAM).\n");
+ ram = ((inb(pTseng->IOAddress + 0x47) & 0x07) + 1) * 8 * 32; /* number of 8 32kb banks */
+ if (inb(pTseng->IOAddress + 0x45) & 0x04) {
+ ram <<= 1;
+ }
+ /*
+ * 8*32kb MDRAM refresh control granularity in the ET6000 fails to
+ * recognize 2.25 MB of memory (detects 2.5 instead)
+ */
+ ram = et6000_check_videoram(pScrn, ram);
+ break;
+ case 0x00: /* DRAM -- VERY unlikely on ET6000 cards, IMPOSSIBLE on ET6100 */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Video memory type: Standard DRAM.\n");
+ ram = 1024 << (inb(pTseng->IOAddress + 0x45) & 0x03);
+ break;
+ default: /* unknown RAM type */
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Unknown ET6000 video memory type %d -- assuming 1 MB (unless specified)\n",
+ ramtype);
+ ram = 1024;
+ }
+ } else { /* pre-ET6000 devices */
+ int iobase = VGAHWPTR(pScrn)->IOBase;
+
+ outb(iobase + 0x04, 0x37);
+ config = inb(iobase + 0x05);
+
+ ram = 128 << (config & 0x03);
+
+ if (config & 0x80)
+ ram <<= 1;
+
+ /* Check for interleaving on W32i/p. */
+ if (Is_W32i || Is_W32p) {
+ outb(iobase + 0x04, 0x32);
+ config = inb(iobase + 0x05);
+ if (config & 0x80) {
+ ram <<= 1;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Video memory type: Interleaved DRAM.\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Video memory type: Standard DRAM.\n");
+ }
+ }
+ }
+ return ram;
+}
+
+static Bool
+TsengProcessHibit(ScrnInfoPtr pScrn)
+{
+ MessageType from = X_CONFIG;
+ int hibit_mode_width;
+ int iobase;
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ PDEBUG(" TsengProcessHibit\n");
+ if (xf86IsOptionSet(TsengOptions, OPTION_HIBIT_HIGH)) {
+ if (xf86IsOptionSet(TsengOptions, OPTION_HIBIT_LOW)) {
+ xf86Msg(X_ERROR, "\nOptions \"hibit_high\" and \"hibit_low\" are incompatible;\n");
+ xf86Msg(X_ERROR, " specify only one (not both) in XFree86 configuration file\n");
+ return FALSE;
+ }
+ pTseng->save_divide = 0x40;
+ } else if (xf86IsOptionSet(TsengOptions, OPTION_HIBIT_HIGH)) {
+ pTseng->save_divide = 0;
+ } else {
+ from = X_PROBED;
+ /* first check to see if hibit is probed from low-res mode */
+ iobase = VGAHWPTR(pScrn)->IOBase;
+ outb(iobase + 4, 1);
+ hibit_mode_width = inb(iobase + 5) + 1;
+ if (hibit_mode_width > 82) {
+ xf86Msg(X_WARNING, "Non-standard VGA text or graphics mode while probing for hibit:\n");
+ xf86Msg(X_WARNING, " probed 'hibit' value may be wrong.\n");
+ xf86Msg(X_WARNING, " Preferably run probe from 80x25 textmode,\n");
+ xf86Msg(X_WARNING, " or specify correct value in XFree86 configuration file.\n");
+ }
+ /* Check for initial state of divide flag */
+ outb(0x3C4, 7);
+ pTseng->save_divide = inb(0x3C5) & 0x40;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Initial ET4000 hibit state: %s\n",
+ pTseng->save_divide & 0x40 ? "high" : "low");
+ return TRUE;
+}
+
+static Bool
+TsengProcessOptions(ScrnInfoPtr pScrn)
+{
+ MessageType from;
+ double real;
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ PDEBUG(" TsengProcessOptions\n");
+ /* Collect all of the relevant option flags (fill in pScrn->options) */
+ xf86CollectOptions(pScrn, NULL);
+
+ /* Process the options */
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, TsengOptions);
+
+ from = X_DEFAULT;
+ pTseng->HWCursor = FALSE; /* default */
+ if (xf86GetOptValBool(TsengOptions, OPTION_HW_CURSOR, &pTseng->HWCursor))
+ from = X_CONFIG;
+ if (xf86ReturnOptValBool(TsengOptions, OPTION_SW_CURSOR, FALSE)) {
+ from = X_CONFIG;
+ pTseng->HWCursor = FALSE;
+ }
+ if (pTseng->HWCursor && !Is_ET6K) {
+ xf86DrvMsg(pScrn->scrnIndex, from,
+ "Hardware Cursor not supported on this chipset\n");
+ pTseng->HWCursor = FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+ pTseng->HWCursor ? "HW" : "SW");
+
+ if (pScrn->bitsPerPixel >= 8) {
+ pTseng->UseAccel = TRUE;
+ if (xf86ReturnOptValBool(TsengOptions, OPTION_NOACCEL, FALSE)) {
+ pTseng->UseAccel = FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n");
+ }
+ } else
+ pTseng->UseAccel = FALSE; /* 1bpp and 4bpp are always non-accelerated */
+
+ pTseng->SlowDram = FALSE;
+ if (xf86IsOptionSet(TsengOptions, OPTION_SLOW_DRAM)) {
+ pTseng->SlowDram = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using slow DRAM access\n");
+ }
+ pTseng->MedDram = FALSE;
+ if (xf86IsOptionSet(TsengOptions, OPTION_MED_DRAM)) {
+ pTseng->MedDram = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using Medium-speed DRAM access\n");
+ }
+ pTseng->FastDram = FALSE;
+ if (xf86IsOptionSet(TsengOptions, OPTION_FAST_DRAM)) {
+ pTseng->FastDram = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using fast DRAM access\n");
+ }
+ if ((pTseng->SetW32Interleave =
+ xf86GetOptValBool(TsengOptions, OPTION_W32_INTERLEAVE, &pTseng->W32Interleave)) )
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing W32p memory interleave %s.\n",
+ pTseng->W32Interleave ? "ON" : "OFF");
+ if ((pTseng->SetPCIBurst =
+ xf86GetOptValBool(TsengOptions, OPTION_PCI_BURST, &pTseng->PCIBurst)) )
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing PCI burst mode %s.\n",
+ pTseng->PCIBurst ? "ON" : "OFF");
+ from = X_CONFIG;
+ if (xf86GetOptValBool(TsengOptions, OPTION_LINEAR, &pTseng->UseLinMem)) {
+ /* check if linear mode is allowed */
+ if (pTseng->UseLinMem) {
+ if (!CHIP_SUPPORTS_LINEAR) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Linear memory not supported on chipset \"%s\".\n",
+ pScrn->chipset);
+ pTseng->UseLinMem = FALSE;
+ } else if (!xf86LinearVidMem()) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "This operating system does not support a linear framebuffer.\n");
+ pTseng->UseLinMem = FALSE;
+ }
+ }
+ } else {
+ /* option not specified: use defaults */
+ from = X_DEFAULT;
+ if (pTseng->PciTag)
+ pTseng->UseLinMem = TRUE; /* use linear memory by default on PCI systems */
+ else
+ pTseng->UseLinMem = FALSE; /* ... and banked on non-PCI systems */
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using %s Memory.\n",
+ (pTseng->UseLinMem) ? "linear" : "banked");
+
+ pTseng->ShowCache = FALSE;
+ if (xf86ReturnOptValBool(TsengOptions, OPTION_SHOWCACHE, FALSE)) {
+ pTseng->ShowCache = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "(for debugging only:) Visible off-screen memory\n");
+ }
+ pTseng->Legend = FALSE;
+ if (xf86ReturnOptValBool(TsengOptions, OPTION_LEGEND, FALSE)) {
+ pTseng->Legend = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using Legend pixel clock selection.\n");
+ }
+ pTseng->NoClockchip = FALSE;
+ if (xf86ReturnOptValBool(TsengOptions, OPTION_NOCLOCKCHIP, FALSE)) {
+ pTseng->NoClockchip = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Disabling clockchip programming.\n");
+ }
+ /*
+ * Check_Tseng_ramdac() already set pScrn->progClock according to probed
+ * values. Override it if requested.
+ */
+ if (pTseng->NoClockchip)
+ pScrn->progClock = FALSE;
+
+ pTseng->UsePCIRetry = FALSE;
+ if (xf86ReturnOptValBool(TsengOptions, OPTION_PCI_RETRY, FALSE)) {
+ pTseng->UsePCIRetry = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "PCI retry enabled\n");
+ }
+ pTseng->MemClk = 0;
+ if (xf86GetOptValFreq(TsengOptions, OPTION_SET_MCLK, OPTUNITS_MHZ, &real))
+ pTseng->MemClk = (int)(real * 1000.0);
+ return TRUE;
+}
+
+static Bool
+TsengGetLinFbAddress(ScrnInfoPtr pScrn)
+{
+ MessageType from;
+ TsengPtr pTseng = TsengPTR(pScrn);
+ resRange range[] = { {ResExcMemBlock,0,0},_END };
+
+ PDEBUG(" TsengGetLinFbAddress\n");
+
+ from = X_PROBED;
+
+ /* let config file override Base address */
+ if (pTseng->pEnt->device->MemBase != 0) {
+ pTseng->LinFbAddress = pTseng->pEnt->device->MemBase;
+ from = X_CONFIG;
+ /* check for possible errors in given linear base address */
+ if ((pTseng->LinFbAddress & (~pTseng->LinFbAddressMask)) != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "MemBase out of range. Must be <= 0x%x on 0x%x boundary.\n",
+ pTseng->LinFbAddressMask, ~(pTseng->LinFbAddressMask | 0xFF000000) + 1);
+ pTseng->LinFbAddress &= ~pTseng->LinFbAddressMask;
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " Clipping MemBase to: 0x%x.\n",
+ pTseng->LinFbAddress);
+ range[0].rBegin = pTseng->LinFbAddress;
+ range[0].rEnd = pTseng->LinFbAddress + 16 * 1024 * 1024;
+ if (xf86RegisterResources(pTseng->pEnt->index,range,ResNone)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ " Cannot register linear memory."
+ " Using banked mode instead.\n");
+ pTseng->UseLinMem = FALSE;
+ return TRUE;
+ }
+ }
+ } else {
+ from = X_PROBED;
+ if (pTseng->PciTag) {
+ /*
+ * base0 is the framebuffer and base1 is the PCI IO space.
+ */
+ if ((pTseng->PciInfo->memBase[0]) != 0) {
+ pTseng->LinFbAddress = pTseng->PciInfo->memBase[0];
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No valid Framebuffer address in PCI config space;\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ " Falling back to banked mode.\n");
+ pTseng->UseLinMem = FALSE;
+ return TRUE;
+ }
+ if (xf86RegisterResources(pTseng->pEnt->index,range,ResNone)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ " Cannot register linear memory."
+ " Using banked mode instead.\n");
+ pTseng->UseLinMem = FALSE;
+ return TRUE;
+ }
+ } else { /* non-PCI boards */
+ /* W32p cards can give us their Lin. memory address through the PCI
+ * configuration. For W32i, this is not possible (VL-bus, MCA or ISA). W32i
+ * cards have three extra external "address" lines, SEG2..SEG0 which _can_
+ * be connected to any set of address lines in addition to the already
+ * connected A23..A0. SEG2..SEG0 are either for three extra address lines
+ * or to connect an external address decoder (mostly an 74F27). It is NOT
+ * possible to know how SEG2..SEG0 are connected. We _assume_ they are
+ * connected to A26..A24 (most likely case). This means linear memory can
+ * be decoded into any 4MB block in the address range 0..128MB.
+ *
+ * For non-PCI cards (especially VLB), most motherboards don't decode all
+ * 32 address bits. The weird default memory base below will always end up
+ * at the end of the decoded address space -- independent of the number of
+ * address bits that are decoded.
+ */
+#define DEFAULT_LIN_MEMBASE ( (256 + 128 + 64 + 32 + 16 + 8 + 4) * 1024*1024 )
+#define DEFAULT_LIN_MEMBASE_PCI (DEFAULT_LIN_MEMBASE & 0xFF000000)
+
+ switch (pTseng->ChipType) {
+ case TYPE_ET4000W32:
+ case TYPE_ET4000W32I:
+ case TYPE_ET4000W32P: /* A31,A30 are decoded as 00 (=always mapped below 512 MB) */
+ pTseng->LinFbAddress = DEFAULT_LIN_MEMBASE;
+ if (pTseng->LinFbAddress > pTseng->LinFbAddressMask) /* ... except if we can't decode that much */
+ pTseng->LinFbAddress = pTseng->LinFbAddressMask - 4 * 1024 * 1024; /* top of decodable memory */
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "TsengNonPciLinMem(): Internal error. This should not happen: please report to XFree86@XFree86.Org\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ " Falling back to banked mode.\n");
+ pTseng->UseLinMem = FALSE;
+ return TRUE;
+ }
+ pTseng->LinFbAddress &= pTseng->LinFbAddressMask;
+
+ /* One final check for a valid MemBase */
+ if (pTseng->LinFbAddress < 4096 * 1024) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Invalid MemBase for linear mode:\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ " please define a non-zero MemBase in XF86Config.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ " See README.tseng or tseng.sgml for more information.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ " Using banked mode instead.\n");
+ pTseng->UseLinMem = FALSE;
+ return TRUE;
+ }
+ range[0].type |= ResBios;
+ range[0].rBegin = pTseng->LinFbAddress;
+ range[0].rEnd = pTseng->LinFbAddress + 16 * 1024 * 1024;
+ if (xf86RegisterResources(pTseng->pEnt->index,range,ResNone)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ " Cannot register linear memory."
+ " Using banked mode instead.\n");
+ pTseng->UseLinMem = FALSE;
+ return TRUE;
+ }
+ }
+ }
+
+ /* The W32 linear map address space is always 4Mb (mainly because the
+ * memory-mapped registers are located near the top of the 4MB area).
+ * The ET6000 maps out 16 Meg, but still uses only 4Mb of that.
+ * However, since all mmap()-ed space is also reflected in the "ps"
+ * listing for the Xserver, many users will be worried by a server that
+ * always eats 16MB of memory, even if it's not "real" memory, just
+ * address space. Not mapping all of the 16M may be a potential problem
+ * though: if another board is mapped on top of the remaining part of
+ * the 16M... Boom!
+ */
+ if (Is_ET6K)
+ pTseng->FbMapSize = 16384 * 1024;
+ else
+ pTseng->FbMapSize = 4096 * 1024;
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n",
+ (unsigned long)pTseng->LinFbAddress);
+
+ return TRUE;
+}
+
+static Bool
+TsengPreInit(ScrnInfoPtr pScrn, int flags)
+{
+ TsengPtr pTseng;
+ MessageType from;
+ int i;
+ char *mod = NULL;
+
+ PDEBUG(" TsengPreInit\n");
+ /*
+ * Note: This function is only called once at server startup, and
+ * not at the start of each server generation. This means that
+ * only things that are persistent across server generations can
+ * be initialised here. xf86Screens[] is (pScrn is a pointer to one
+ * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex()
+ * are too, and should be used for data that must persist across
+ * server generations.
+ *
+ * Per-generation data should be allocated with
+ * AllocateScreenPrivateIndex() from the ScreenInit() function.
+ */
+
+ /* The vgahw module should be loaded here when needed */
+
+ if (!xf86LoadSubModule(pScrn, "vgahw"))
+ return FALSE;
+
+ /*
+ * Allocate a vgaHWRec
+ */
+ if (!vgaHWGetHWRec(pScrn))
+ return FALSE;
+
+ vgaHWGetIOBase(VGAHWPTR(pScrn));
+ /*
+ * Since, the capabilities are determined by the chipset, the very first
+ * thing to do is to figure out the chipset and its capabilities.
+ */
+
+ /* Allocate the TsengRec driverPrivate */
+ if (!TsengGetRec(pScrn)) {
+ return FALSE;
+ }
+ pTseng = TsengPTR(pScrn);
+
+ TsengUnlock();
+
+ /*
+ * Find the bus slot for this screen (PCI or other). This also finds the
+ * exact chipset type.
+ */
+ /* This driver doesn't expect more than one entity per screen */
+ if (pScrn->numEntities > 1) {
+ TsengFreeRec(pScrn);
+ return FALSE;
+ }
+ /* This is the general case */
+ pTseng->pEnt = xf86GetEntityInfo(*pScrn->entityList);
+ /* This driver can handle ISA and PCI buses */
+ if (pTseng->pEnt->location.type == BUS_PCI) {
+ pTseng->PciInfo = xf86GetPciInfoForEntity(pTseng->pEnt->index);
+ if (!TsengPreInitPCI(pScrn)) {
+ TsengFreeRec(pScrn);
+ return FALSE;
+ }
+ } else if (!TsengPreInitNoPCI(pScrn)) {
+ TsengFreeRec(pScrn);
+ return FALSE;
+ }
+
+ /*
+ * Find RAMDAC and CLOCKCHIP type and fill Tsengdac struct
+ */
+ if (!Check_Tseng_Ramdac(pScrn))
+ return FALSE;
+
+ /* check for clockchip */
+ if (!Tseng_check_clockchip(pScrn)) {
+ return FALSE;
+ }
+ /*
+ * Now we can check what depth we support.
+ */
+
+ /* Set pScrn->monitor */
+ pScrn->monitor = pScrn->confScreen->monitor;
+
+ /*
+ * The first thing we should figure out is the depth, bpp, etc.
+ * Our default depth is 8, so pass it to the helper function.
+ * Our preference for depth 24 is 24bpp, so tell it that too.
+ */
+ if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb | Support32bppFb |
+ SupportConvert32to24 | PreferConvert32to24)) {
+ return FALSE;
+ } else {
+ /* Check that the returned depth is one we support */
+ Bool CanDo16bpp = FALSE, CanDo24bpp = FALSE, CanDo32bpp = FALSE;
+ Bool CanDoThis = FALSE;
+
+ switch (pTseng->DacInfo.DacType) {
+ case ET6000_DAC:
+ case ICS5341_DAC:
+ case STG1703_DAC:
+ case STG1702_DAC:
+ CanDo16bpp = TRUE;
+ CanDo24bpp = TRUE;
+ CanDo32bpp = TRUE;
+ break;
+ case ATT20C490_DAC:
+ case ATT20C491_DAC:
+ case ATT20C492_DAC:
+ case ATT20C493_DAC:
+ case ICS5301_DAC:
+ case MUSIC4910_DAC:
+ CanDo16bpp = TRUE;
+ CanDo24bpp = TRUE;
+ break;
+ case CH8398_DAC:
+ CanDo16bpp = TRUE;
+ CanDo24bpp = TRUE;
+ break;
+ case STG1700_DAC: /* can't do packed 24bpp over a 16-bit bus */
+ CanDo16bpp = TRUE; /* FIXME: can do it over 8 bit bus */
+ CanDo32bpp = TRUE;
+ break;
+ default: /* default: only 1, 4, 8 bpp */
+ break;
+ }
+
+ switch (pScrn->depth) {
+ case 1:
+ case 4:
+ case 8:
+ CanDoThis = TRUE;
+ break;
+ case 16:
+ CanDoThis = CanDo16bpp;
+ break;
+ case 24:
+ CanDoThis = (CanDo24bpp || CanDo32bpp);
+ break;
+ }
+ if (!CanDoThis) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this chipset/RAMDAC\n",
+ pScrn->depth);
+ return FALSE;
+ }
+ if ((pScrn->bitsPerPixel == 32) && (!CanDo32bpp)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Given bpp (%d) is not supported by this chipset/RAMDAC\n",
+ pScrn->bitsPerPixel);
+ return FALSE;
+ }
+ }
+ xf86PrintDepthBpp(pScrn);
+
+ /* Get the depth24 pixmap format */
+ if (pScrn->depth == 24 && pix24bpp == 0)
+ pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+
+ if (pScrn->bitsPerPixel > 8)
+ pTseng->Bytesperpixel = pScrn->bitsPerPixel / 8;
+ else
+ pTseng->Bytesperpixel = 1; /* this is fake for < 8bpp, but simplifies other code */
+
+ /* hardware limits */
+ pScrn->maxHValue = 4096 / pTseng->Bytesperpixel;
+ pScrn->maxVValue = 2048;
+
+ /*
+ * This must happen after pScrn->display has been set because
+ * xf86SetWeight references it.
+ */
+
+ /* Set weight/mask/offset for depth > 8 */
+ if (pScrn->depth > 8) {
+ /* The defaults are OK for us */
+ rgb zeros =
+ {0, 0, 0};
+
+ if (!xf86SetWeight(pScrn, zeros, zeros)) {
+ return FALSE;
+ } else {
+ /* XXX check that weight returned is supported */
+ ;
+ }
+ }
+ /* Set the default visual. */
+ if (!xf86SetDefaultVisual(pScrn, -1)) {
+ return FALSE;
+ } else {
+ /* Tseng doesn't support DirectColor at > 8bpp */
+ if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
+ " (%s) is not supported at depth %d\n",
+ xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
+ return FALSE;
+ }
+ }
+
+ /* The gamma fields must be initialised when using the new cmap code */
+ if (pScrn->depth > 1) {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScrn, zeros)) {
+ return FALSE;
+ }
+ }
+
+ /* Set the bits per RGB for 8bpp mode */
+ if (pScrn->depth == 8) {
+ /* Default to 6, because most Tseng chips/RAMDACs don't support it */
+ pScrn->rgbBits = 6;
+ }
+ if (!TsengProcessOptions(pScrn)) /* must be done _after_ we know what chip this is */
+ return FALSE;
+
+ if (pTseng->UseLinMem) {
+ if (!TsengGetLinFbAddress(pScrn))
+ return FALSE;
+ }
+
+ if (pTseng->UseAccel)
+ VGAHWPTR(pScrn)->MapSize = 0x20000; /* accelerator apertures and MMIO */
+ else
+ VGAHWPTR(pScrn)->MapSize = 0x10000;
+
+ if (pTseng->UseLinMem) {
+ resRange vgamem[] = { {ResShrMemBlock,0xA0000,0xAFFFF},
+ {ResShrMemBlock,0xB0000,0xB7FFF},
+ {ResShrMemBlock,0xB8000,0xBFFFF},
+ _END };
+ /*
+ * XXX At least part of this range does appear to be disabled,
+ * but to play safe, it is marked as "unused" for now.
+ */
+ xf86SetOperatingState(vgamem, pTseng->pEnt->index, ResUnusedOpr);
+ }
+
+ /* hibit processing (TsengProcessOptions() must have been called first) */
+ pTseng->save_divide = 0x40; /* default */
+ if (!Is_ET6K) {
+ if (!TsengProcessHibit(pScrn))
+ return FALSE;
+ }
+ /*
+ * If the user has specified the amount of memory in the XF86Config
+ * file, we respect that setting.
+ */
+ if (pTseng->pEnt->device->videoRam != 0) {
+ pScrn->videoRam = pTseng->pEnt->device->videoRam;
+ from = X_CONFIG;
+ } else {
+ from = X_PROBED;
+ pScrn->videoRam = TsengDetectMem(pScrn);
+ }
+ pScrn->videoRam = TsengLimitMem(pScrn, pScrn->videoRam);
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte.\n",
+ pScrn->videoRam);
+
+ /* do all clock-related setup */
+ tseng_clock_setup(pScrn);
+
+ /*
+ * xf86ValidateModes will check that the mode HTotal and VTotal values
+ * don't exceed the chipset's limit if pScrn->maxHValue and
+ * pScrn->maxVValue are set. Since our TsengValidMode() already takes
+ * care of this, we don't worry about setting them here.
+ */
+
+ /* Select valid modes from those available */
+ i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
+ pScrn->display->modes, pTseng->clockRange[0],
+ NULL, 32, pScrn->maxHValue, 8*pTseng->Bytesperpixel, /* H limits */
+ 0, pScrn->maxVValue, /* V limits */
+ pScrn->display->virtualX,
+ pScrn->display->virtualY,
+ pTseng->FbMapSize,
+ LOOKUP_BEST_REFRESH); /* LOOKUP_CLOSEST_CLOCK | LOOKUP_CLKDIV2 when no programable clock ? */
+
+ if (i == -1) {
+ TsengFreeRec(pScrn);
+ return FALSE;
+ }
+ /* Prune the modes marked as invalid */
+ xf86PruneDriverModes(pScrn);
+
+ if (i == 0 || pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+ TsengFreeRec(pScrn);
+ return FALSE;
+ }
+ /*
+ * Set the CRTC parameters for all of the modes based on the type
+ * of mode, and the chipset's interlace requirements.
+ *
+ * Calling this is required if the mode->Crtc* values are used by the
+ * driver and if the driver doesn't provide code to set them. They
+ * are not pre-initialised at all.
+ */
+ xf86SetCrtcForModes(pScrn, 0);
+
+ /* Set the current mode to the first in the list */
+ pScrn->currentMode = pScrn->modes;
+
+ /* Print the list of modes being used */
+ xf86PrintModes(pScrn);
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ /* Load bpp-specific modules */
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ mod = "xf1bpp";
+ break;
+ case 4:
+ mod = "xf4bpp";
+ break;
+ case 8:
+ mod = "cfb";
+ break;
+ case 16:
+ mod = "cfb16";
+ break;
+ case 24:
+ if (pix24bpp == 24)
+ mod = "cfb24";
+ else
+ mod = "xf24_32bpp";
+ break;
+ case 32:
+ mod = "cfb32";
+ break;
+ }
+ if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
+ TsengFreeRec(pScrn);
+ return FALSE;
+ }
+ /* Load XAA if needed */
+ if (pTseng->UseAccel)
+ if (!xf86LoadSubModule(pScrn, "xaa")) {
+ TsengFreeRec(pScrn);
+ return FALSE;
+ }
+ /* Load ramdac if needed */
+ if (pTseng->HWCursor)
+ if (!xf86LoadSubModule(pScrn, "ramdac")) {
+ TsengFreeRec(pScrn);
+ return FALSE;
+ }
+/* TsengLock(); */
+
+ return TRUE;
+}
+
+static void
+TsengSetupAccelMemory(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TsengPtr pTseng = TsengPTR(pScrn);
+ int offscreen_videoram, videoram_end, req_videoram;
+ int i;
+ int v;
+
+ /* XXX Hack to suppress messages in subsequent generations. */
+ if (serverGeneration == 1)
+ v = 1;
+ else
+ v = 100;
+ /*
+ * The accelerator requires free off-screen video memory to operate. The
+ * more there is, the more it can accelerate.
+ */
+
+ videoram_end = pScrn->videoRam * 1024;
+ offscreen_videoram = videoram_end -
+ pScrn->displayWidth * pScrn->virtualY * pTseng->Bytesperpixel;
+ xf86DrvMsgVerb(scrnIndex, X_INFO, v, "Available off-screen memory: %d bytes.\n",
+ offscreen_videoram);
+
+ /*
+ * The HW cursor requires 1kb of off-screen memory, aligned to 1kb
+ * (256 DWORDS). Setting up its memory first ensures the alignment.
+ */
+ if (pTseng->HWCursor) {
+ req_videoram = 1024;
+ if (offscreen_videoram < req_videoram) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, v,
+ "Hardware Cursor disabled. It requires %d bytes of free video memory\n",
+ req_videoram);
+ pTseng->HWCursor = FALSE;
+ pTseng->HWCursorBufferOffset = 0;
+ } else {
+ offscreen_videoram -= req_videoram;
+ videoram_end -= req_videoram;
+ pTseng->HWCursorBufferOffset = videoram_end;
+ }
+ } else {
+ pTseng->HWCursorBufferOffset = 0;
+ }
+
+ /*
+ * Acceleration memory setup. Do this only if acceleration is enabled.
+ */
+ if (!pTseng->UseAccel) return;
+
+ /*
+ * Basic acceleration needs storage for FG, BG and PAT colors in
+ * off-screen memory. Each color requires 2(ping-pong)*8 bytes.
+ */
+ req_videoram = 2 * 8 * 3;
+ if (offscreen_videoram < req_videoram) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, v,
+ "Acceleration disabled. It requires AT LEAST %d bytes of free video memory\n",
+ req_videoram);
+ pTseng->UseAccel = FALSE;
+ pTseng->AccelColorBufferOffset = 0;
+ goto end_memsetup; /* no basic acceleration means none at all */
+ } else {
+ offscreen_videoram -= req_videoram;
+ videoram_end -= req_videoram;
+ pTseng->AccelColorBufferOffset = videoram_end;
+ }
+
+ /*
+ * Color expansion (using triple buffering) requires 3 non-expanded
+ * scanlines, DWORD padded.
+ */
+ req_videoram = 3 * ((pScrn->virtualX + 31) / 32) * 4;
+ if (offscreen_videoram < req_videoram) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, v,
+ "Accelerated color expansion disabled (%d more bytes of free video memory required)\n",
+ req_videoram - offscreen_videoram);
+ pTseng->AccelColorExpandBufferOffsets[0] = 0;
+ } else {
+ offscreen_videoram -= req_videoram;
+ for (i = 0; i < 3; i++) {
+ videoram_end -= req_videoram / 3;
+ pTseng->AccelColorExpandBufferOffsets[i] = videoram_end;
+ }
+ }
+
+ /*
+ * XAA ImageWrite support needs two entire line buffers. The
+ * current code assumes buffer 1 lies in the same 8kb aperture as
+ * buffer 0.
+ *
+ * [ FIXME: aren't we forgetting the DWORD padding here ? ]
+ * [ FIXME: why here double-buffering and in colexp triple-buffering? ]
+ */
+ req_videoram = 2 * (pScrn->virtualX * pTseng->Bytesperpixel);
+ /* banked mode uses an 8kb aperture for imagewrite */
+ if ((req_videoram > 8192) && (!pTseng->UseLinMem)) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, v,
+ "Accelerated ImageWrites disabled (banked %dbpp virtual width must be <= %d)\n",
+ pScrn->bitsPerPixel, 8192 / (2 * pTseng->Bytesperpixel));
+ pTseng->AccelImageWriteBufferOffsets[0] = 0;
+ } else if (offscreen_videoram < req_videoram) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_WARNING, v,
+ "Accelerated ImageWrites disabled (%d more bytes of free video memory required)\n",
+ req_videoram - offscreen_videoram);
+ pTseng->AccelImageWriteBufferOffsets[0] = 0;
+ } else {
+ offscreen_videoram -= req_videoram;
+ for (i = 0; i < 2; i++) {
+ videoram_end -= req_videoram / 2;
+ pTseng->AccelImageWriteBufferOffsets[i] = videoram_end;
+ }
+ }
+
+ xf86DrvMsgVerb(scrnIndex, X_INFO, v,
+ "Remaining off-screen memory available for pixmap cache: %d bytes.\n",
+ offscreen_videoram);
+
+end_memsetup:
+ pScrn->videoRam = videoram_end / 1024;
+}
+
+static Bool
+TsengScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScrn;
+ TsengPtr pTseng;
+ int ret;
+ VisualPtr visual;
+
+ PDEBUG(" TsengScreenInit\n");
+
+ /*
+ * First get the ScrnInfoRec
+ */
+ pScrn = xf86Screens[pScreen->myNum];
+
+ pTseng = TsengPTR(pScrn);
+
+ /* Map the Tseng memory areas */
+ if (!TsengMapMem(pScrn))
+ return FALSE;
+
+ /* Save the current state */
+ TsengSave(pScrn);
+
+ /* Initialise the first mode */
+ TsengModeInit(pScrn, pScrn->currentMode);
+
+ /* Darken the screen for aesthetic reasons and set the viewport */
+ TsengSaveScreen(pScreen, FALSE);
+
+ TsengAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ /* XXX Fill the screen with black */
+
+ /*
+ * The next step is to setup the screen's visuals, and initialise the
+ * framebuffer code. In cases where the framebuffer's default
+ * choices for things like visual layouts and bits per RGB are OK,
+ * this may be as simple as calling the framebuffer's ScreenInit()
+ * function. If not, the visuals will need to be setup before calling
+ * a fb ScreenInit() function and fixed up after.
+ *
+ * For most PC hardware at depths >= 8, the defaults that cfb uses
+ * are not appropriate. In this driver, we fixup the visuals after.
+ */
+
+ /*
+ * Reset visual list.
+ */
+ miClearVisualTypes();
+
+ /* Setup the visuals we support. */
+
+ /*
+ * For bpp > 8, the default visuals are not acceptable because we only
+ * support TrueColor and not DirectColor. To deal with this, call
+ * miSetVisualTypes for each visual supported.
+ */
+
+ if (pScrn->depth > 8) {
+ if (!miSetVisualTypes(pScrn->depth, TrueColorMask, pScrn->rgbBits,
+ pScrn->defaultVisual))
+ return FALSE;
+ } else {
+ if (!miSetVisualTypes(pScrn->depth,
+ miGetDefaultVisualMask(pScrn->depth),
+ pScrn->rgbBits, pScrn->defaultVisual))
+ return FALSE;
+ }
+
+ /*
+ * Call the framebuffer layer's ScreenInit function, and fill in other
+ * pScreen fields.
+ */
+
+ switch (pScrn->bitsPerPixel) {
+ case 1:
+ ret = xf1bppScreenInit(pScreen, pTseng->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 4:
+ ret = xf4bppScreenInit(pScreen, pTseng->FbBase,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 8:
+ ret = cfbScreenInit(pScreen, pTseng->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 16:
+ ret = cfb16ScreenInit(pScreen, pTseng->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 24:
+ ret = cfb24ScreenInit(pScreen, pTseng->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ ret = cfb24_32ScreenInit(pScreen, pTseng->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ case 32:
+ ret = cfb32ScreenInit(pScreen, pTseng->FbBase, pScrn->virtualX,
+ pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
+ pScrn->displayWidth);
+ break;
+ default:
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Internal error: invalid bpp (%d) in TsengScrnInit\n",
+ pScrn->bitsPerPixel);
+ ret = FALSE;
+ break;
+ }
+ if (!ret)
+ return FALSE;
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ if (pScrn->bitsPerPixel > 8) {
+ /* Fixup RGB ordering */
+ visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ /*
+ * If banking is needed, initialise an miBankInfoRec (defined in
+ * "mibank.h"), and call miInitializeBanking().
+ */
+
+ if (!pTseng->UseLinMem) {
+ if (!Is_stdET4K && (pScrn->videoRam > 1024)) {
+ pTseng->BankInfo.SetSourceBank = ET4000W32SetRead;
+ pTseng->BankInfo.SetDestinationBank = ET4000W32SetWrite;
+ pTseng->BankInfo.SetSourceAndDestinationBanks = ET4000W32SetReadWrite;
+ } else {
+ pTseng->BankInfo.SetSourceBank = ET4000SetRead;
+ pTseng->BankInfo.SetDestinationBank = ET4000SetWrite;
+ pTseng->BankInfo.SetSourceAndDestinationBanks = ET4000SetReadWrite;
+ }
+ pTseng->BankInfo.pBankA = pTseng->FbBase;
+ pTseng->BankInfo.pBankB = pTseng->FbBase;
+ pTseng->BankInfo.BankSize = 0x10000;
+ pTseng->BankInfo.nBankDepth = (pScrn->depth == 4) ? 1 : pScrn->depth;
+
+ if (!miInitializeBanking(pScreen, pScrn->virtualX, pScrn->virtualY,
+ pScrn->displayWidth, &pTseng->BankInfo)) {
+ return FALSE;
+ }
+ }
+
+ /*
+ * Initialize the acceleration interface.
+ */
+ TsengSetupAccelMemory(scrnIndex, pScreen);
+ if (pTseng->UseAccel) {
+ tseng_init_acl(pScreen); /* set up accelerator */
+ if (!TsengXAAInit(pScreen)) { /* set up XAA interface */
+ return FALSE;
+ }
+ }
+
+ miInitializeBackingStore(pScreen);
+ /* Initialise cursor functions */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ /* Hardware Cursor layer */
+ if (pTseng->HWCursor) {
+ if (!TsengHWCursorInit(pScreen))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Hardware cursor initialization failed\n");
+ }
+
+ /* Initialise default colourmap */
+ if (!miCreateDefColormap(pScreen))
+ return FALSE;
+
+ if (pScrn->depth == 4 || pScrn->depth == 8) { /* cfb and xf4bpp */
+ vgaHWHandleColormaps(pScreen);
+ }
+ pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
+ pScrn->racMemFlags = pScrn->racIoFlags;
+
+ /* Wrap the current CloseScreen and SaveScreen functions */
+ pScreen->SaveScreen = TsengSaveScreen;
+
+#ifdef DPMSExtension
+ /* Support for DPMS, the ET4000W32Pc and newer uses a different and
+ * simpler method than the older cards.
+ */
+ if (Is_W32p_cd || Is_ET6K) {
+ xf86DPMSInit(pScreen, (DPMSSetProcPtr)TsengCrtcDPMSSet, 0);
+ } else {
+ xf86DPMSInit(pScreen, (DPMSSetProcPtr)TsengHVSyncDPMSSet, 0);
+ }
+#endif
+
+ pTseng->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = TsengCloseScreen;
+
+ /* Report any unused options (only for the first generation) */
+ if (serverGeneration == 1) {
+ xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+ }
+ /* Done */
+ return TRUE;
+}
+
+static Bool
+TsengEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ PDEBUG(" TsengEnterVT\n");
+
+ vgaHWUnlock(VGAHWPTR(pScrn));
+ TsengUnlock();
+
+ return TsengModeInit(pScrn, pScrn->currentMode);
+}
+
+static void
+TsengLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+#ifdef TODO
+#ifdef XFreeXDGA
+ if (pScrn->bitsPerPixel >= 8) {
+ if (pScrn->directMode & XF86DGADirectGraphics) {
+ if (vgaHWCursor.Initialized == TRUE)
+ TsengHideCursor();
+ return;
+ }
+ }
+#endif
+#endif
+
+ PDEBUG(" TsengLeaveVT\n");
+ TsengRestore(pScrn, &(VGAHWPTR(pScrn)->SavedReg), &pTseng->SavedReg);
+
+ TsengLock();
+ vgaHWLock(VGAHWPTR(pScrn));
+}
+
+static Bool
+TsengCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ PDEBUG(" TsengCloseScreen\n");
+
+ if (pScrn->vtSema) {
+ TsengRestore(pScrn, &(VGAHWPTR(pScrn)->SavedReg), &(pTseng->SavedReg));
+ TsengUnmapMem(pScrn);
+ }
+ if (pTseng->AccelInfoRec)
+ XAADestroyInfoRec(pTseng->AccelInfoRec);
+ if (pTseng->CursorInfoRec)
+ xf86DestroyCursorInfoRec(pTseng->CursorInfoRec);
+
+ pScrn->vtSema = FALSE;
+
+ pScreen->CloseScreen = pTseng->CloseScreen;
+ return (*pScreen->CloseScreen) (scrnIndex, pScreen);
+}
+
+/*
+ * SaveScreen --
+ *
+ * perform a sequencer reset.
+ *
+ * The ET4000 "Video System Configuration 1" register (CRTC index 0x36),
+ * which is used to set linear memory mode and MMU-related stuff, is
+ * partially reset to "0" when TS register index 0 bit 1 is set (synchronous
+ * reset): bits 3..5 are reset during a sync. reset.
+ *
+ * We therefor do _not_ call vgaHWSaveScreen here, since it does a sequencer
+ * reset. Instead, we do the same as in vgaHWSaveScreen except for the seq. reset.
+ *
+ * If this is not done, the higher level code will not be able to access the
+ * framebuffer (because it is temporarily in banked mode instead of linear
+ * mode) as long as SaveScreen is active (=in between a
+ * SaveScreen(FALSE)/SaveScreen(TRUE) pair)
+ */
+
+static Bool
+TsengSaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ PDEBUG(" TsengSaveScreen\n");
+
+ if (Is_ET6K) {
+ return vgaHWSaveScreen(pScreen, unblank);
+ } else {
+ if (unblank)
+ SetTimeSinceLastInputEvent();
+
+ if (pScrn->vtSema) {
+ TsengBlankScreen(pScrn, unblank);
+ }
+ return (TRUE);
+ }
+}
+
+static Bool
+TsengMapMem(ScrnInfoPtr pScrn)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ PDEBUG(" TsengMapMem\n");
+
+ /* Map the VGA memory */
+
+ if (!vgaHWMapMem(pScrn)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not mmap standard VGA memory aperture.\n");
+ return FALSE;
+ }
+
+ if (pTseng->UseLinMem) {
+ pTseng->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ pTseng->PciTag,
+ (unsigned long)pTseng->LinFbAddress,
+ pTseng->FbMapSize);
+ if (pTseng->FbBase == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Could not mmap linear video memory.\n");
+ return FALSE;
+ }
+ } else {
+ pTseng->FbBase = VGAHWPTR(pScrn)->Base;
+ }
+
+ if (pTseng->FbBase == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+TsengUnmapMem(ScrnInfoPtr pScrn)
+{
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ PDEBUG(" TsengUnmapMem\n");
+
+ if (pTseng->UseLinMem) {
+ xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pTseng->FbBase, pTseng->FbMapSize);
+ }
+ vgaHWUnmapMem(pScrn);
+
+ pTseng->FbBase = NULL;
+
+ return TRUE;
+}
+
+static void
+TsengFreeScreen(int scrnIndex, int flags)
+{
+ PDEBUG(" TsengFreeScreen\n");
+ vgaHWFreeHWRec(xf86Screens[scrnIndex]);
+ TsengFreeRec(xf86Screens[scrnIndex]);
+}
+
+static Bool
+TsengModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ vgaHWPtr hwp;
+ TsengPtr pTseng = TsengPTR(pScrn);
+ TsengRegPtr new = &(pTseng->ModeReg);
+ TsengRegPtr initial = &(pTseng->SavedReg);
+ int row_offset;
+ int temp1, temp2, temp3;
+ int min_n2;
+ int hdiv = 1, hmul = 1;
+
+ PDEBUG(" TsengModeInit\n");
+
+ switch (mode->PrivFlags) {
+ case TSENG_MODE_PIXMUX:
+ case TSENG_MODE_DACBUS16:
+ hdiv = pTseng->clockRange[1]->ClockDivFactor;
+ hmul = pTseng->clockRange[1]->ClockMulFactor;
+ break;
+ default:
+ hdiv = pTseng->clockRange[0]->ClockDivFactor;
+ hmul = pTseng->clockRange[0]->ClockMulFactor;
+ }
+
+ /*
+ * Modify mode timings accordingly
+ */
+ if (!mode->CrtcHAdjusted) {
+ /* now divide and multiply the horizontal timing parameters as required */
+ mode->CrtcHTotal = (mode->CrtcHTotal * hmul) / hdiv;
+ mode->CrtcHDisplay = (mode->CrtcHDisplay * hmul) / hdiv;
+ mode->CrtcHSyncStart = (mode->CrtcHSyncStart * hmul) / hdiv;
+ mode->CrtcHSyncEnd = (mode->CrtcHSyncEnd * hmul) / hdiv;
+ mode->CrtcHBlankStart = (mode->CrtcHBlankStart * hmul) / hdiv;
+ mode->CrtcHBlankEnd = (mode->CrtcHBlankEnd * hmul) / hdiv;
+ mode->CrtcHSkew = (mode->CrtcHSkew * hmul) / hdiv;
+ if (pScrn->bitsPerPixel == 24) {
+ int rgb_skew;
+
+ /*
+ * in 24bpp, the position of the BLANK signal determines the
+ * phase of the R,G and B values. XFree86 sets blanking equal to
+ * the Sync, so setting the Sync correctly will also set the
+ * BLANK corectly, and thus also the RGB phase
+ */
+ rgb_skew = (mode->CrtcHTotal / 8 - mode->CrtcHBlankEnd / 8 - 1) % 3;
+ mode->CrtcHBlankEnd += rgb_skew * 8 + 24;
+ /* HBlankEnd must come BEFORE HTotal */
+ if (mode->CrtcHBlankEnd > mode->CrtcHTotal)
+ mode->CrtcHBlankEnd -= 24;
+ }
+ mode->CrtcHAdjusted = TRUE;
+ }
+
+ /* set clockIndex to "2" for programmable clocks */
+ if (pScrn->progClock)
+ mode->ClockIndex = 2;
+
+ /* prepare standard VGA register contents */
+ hwp = VGAHWPTR(pScrn);
+ if (!vgaHWInit(pScrn, mode))
+ return (FALSE);
+ pScrn->vtSema = TRUE;
+
+ /* prepare extended (Tseng) register contents */
+ /*
+ * Start by copying all the saved registers in the "new" data, so we
+ * only have to modify those that need to change.
+ */
+
+ memcpy(new, initial, sizeof(TsengRegRec));
+
+ if (pScrn->bitsPerPixel < 8) {
+ /* Don't ask me why this is needed on the ET6000 and not on the others */
+ if (Is_ET6K)
+ hwp->ModeReg.Sequencer[1] |= 0x04;
+ row_offset = hwp->ModeReg.CRTC[19];
+ } else {
+ hwp->ModeReg.Attribute[16] = 0x01; /* use the FAST 256 Color Mode */
+ row_offset = pScrn->displayWidth >> 3; /* overruled by 16/24/32 bpp code */
+ }
+
+ hwp->ModeReg.CRTC[20] = 0x60;
+ hwp->ModeReg.CRTC[23] = 0xAB;
+ new->ExtTS[6] = 0x00;
+ new->ExtTS[7] = 0xBC;
+ new->ExtCRTC[0x33] = 0x00;
+
+ new->ExtCRTC[0x35] = (mode->Flags & V_INTERLACE ? 0x80 : 0x00)
+ | 0x10
+ | ((mode->CrtcVSyncStart & 0x400) >> 7)
+ | (((mode->CrtcVDisplay - 1) & 0x400) >> 8)
+ | (((mode->CrtcVTotal - 2) & 0x400) >> 9)
+ | (((mode->CrtcVBlankStart - 1) & 0x400) >> 10);
+
+ if (pScrn->bitsPerPixel < 8)
+ new->ExtATC = 0x00;
+ else
+ new->ExtATC = 0x80;
+
+ if (pScrn->bitsPerPixel >= 8) {
+ if (pTseng->FastDram && !Is_ET6K) {
+ /*
+ * make sure Trsp is no more than 75ns
+ * Tcsw is 25ns
+ * Tcsp is 25ns
+ * Trcd is no more than 50ns
+ * Timings assume SCLK = 40MHz
+ *
+ * Note, this is experimental, but works for me (DHD)
+ */
+ /* Tcsw, Tcsp, Trsp */
+ new->ExtCRTC[0x32] &= ~0x1F;
+ if (new->ExtCRTC[0x32] & 0x18)
+ new->ExtCRTC[0x32] |= 0x08;
+ /* Trcd */
+ new->ExtCRTC[0x32] &= ~0x20;
+ }
+ }
+ /*
+ * Here we make sure that CRTC regs 0x34 and 0x37 are untouched, except for
+ * some bits we want to change.
+ * Notably bit 7 of CRTC 0x34, which changes RAS setup time from 4 to 0 ns
+ * (performance),
+ * and bit 7 of CRTC 0x37, which changes the CRTC FIFO low treshold control.
+ * At really high pixel clocks, this will avoid lots of garble on the screen
+ * when something is being drawn. This only happens WAY beyond 80 MHz
+ * (those 135 MHz ramdac's...)
+ */
+ if (Is_W32i || Is_W32p) {
+ if (!pTseng->SlowDram)
+ new->ExtCRTC[0x34] = (new->ExtCRTC[0x34] & 0x7F) | 0x80;
+ if ((mode->Clock * pTseng->Bytesperpixel) > 80000)
+ new->ExtCRTC[0x37] = (new->ExtCRTC[0x37] & 0x7f) | 0x80;
+ /*
+ * now on to the memory interleave setting (CR32 bit 7)
+ */
+ if (pTseng->SetW32Interleave) {
+ if (pTseng->W32Interleave)
+ new->ExtCRTC[0x32] |= 0x80;
+ else
+ new->ExtCRTC[0x32] &= 0x7F;
+ }
+ }
+ if (Is_W32p) {
+ /*
+ * CR34 bit 4 controls the PCI Burst option
+ */
+ if (pTseng->SetPCIBurst) {
+ if (pTseng->PCIBurst)
+ new->ExtCRTC[0x34] |= 0x10;
+ else
+ new->ExtCRTC[0x34] &= 0xEF;
+ }
+ }
+
+ /* prepare clock-related registers when not Legend.
+ * cannot really SET the clock here yet, since the ET4000Save()
+ * is called LATER, so it would save the wrong state...
+ * ET4000Restore() is used to actually SET vga regs.
+ */
+
+ if (STG170x_programmable_clock || Gendac_programmable_clock) {
+ if (mode->PrivFlags == TSENG_MODE_PIXMUX)
+ /* pixmux requires a post-div of 4 on ICS GenDAC clock generator */
+ min_n2 = 2;
+ else
+ min_n2 = 0;
+ TsengcommonCalcClock(mode->SynthClock, 1, 1, 31, min_n2, 3,
+ 100000, pTseng->max_vco_freq,
+ &(new->pll.f2_M), &(new->pll.f2_N));
+
+ new->pll.w_idx = 0;
+ new->pll.r_idx = 0;
+
+ /* memory clock */
+ if (Gendac_programmable_clock && pTseng->MClkInfo.Set) {
+ TsengcommonCalcClock(pTseng->MClkInfo.MemClk, 1, 1, 31, 1, 3, 100000, pTseng->MaxClock * 2 + 1,
+ &(new->pll.MClkM), &(new->pll.MClkN));
+ }
+ } else if (ICD2061a_programmable_clock) {
+#ifdef TODO
+ /* FIXME: icd2061_dwv not used anywhere ... */
+ pTseng->icd2061_dwv = AltICD2061CalcClock(mode->SynthClock * 1000);
+ /* Tseng_ICD2061AClockSelect(mode->SynthClock); */
+#endif
+ } else if (CH8398_programmable_clock) {
+#ifdef TODO
+ Chrontel8391CalcClock(mode->SynthClock, &temp1, &temp2, &temp3);
+ new->pll.f2_N = (unsigned char)(temp2);
+ new->pll.f2_M = (unsigned char)(temp1 | (temp3 << 6));
+ /* ok LSB=f2_N and MSB=f2_M */
+ /* now set the Clock Select Register(CSR) */
+ new->pll.ctrl = (new->pll.ctrl | 0x90) & 0xF0;
+ new->pll.timingctrl &= 0x1F;
+ new->pll.r_idx = 0;
+ new->pll.w_idx = 0;
+#endif
+ } else if (Is_ET6K) {
+ /* setting min_n2 to "1" will ensure a more stable clock ("0" is allowed though) */
+ TsengcommonCalcClock(mode->SynthClock, 1, 1, 31, 1, 3, 100000,
+ pTseng->max_vco_freq,
+ &(new->pll.f2_M), &(new->pll.f2_N));
+ /* above 130MB/sec, we enable the "LOW FIFO threshold" */
+ if (mode->Clock * pTseng->Bytesperpixel > 130000) {
+ new->ExtET6K[0x41] |= 0x10;
+ if (Is_ET6100)
+ new->ExtET6K[0x46] |= 0x04;
+ } else {
+ new->ExtET6K[0x41] &= ~0x10;
+ if (Is_ET6100)
+ new->ExtET6K[0x46] &= ~0x04;
+ }
+
+ if (pTseng->MClkInfo.Set) {
+ /* according to Tseng Labs, N1 must be <= 4, and N2 should always be 1 for MClk */
+ TsengcommonCalcClock(pTseng->MClkInfo.MemClk, 1, 1, 4, 1, 1,
+ 100000, pTseng->MaxClock * 2,
+ &(new->pll.MClkM), &(new->pll.MClkN));
+ }
+ /*
+ * Even when we don't allow setting the MClk value as described
+ * above, we can use the FAST/MED/SLOW DRAM options to set up
+ * the RAS/CAS delays as decided by the value of ExtET6K[0x44].
+ * This is also a more correct use of the flags, as it describes
+ * how fast the RAM works. [HNH].
+ */
+ if (pTseng->FastDram)
+ new->ExtET6K[0x44] = 0x04; /* Fastest speed(?) */
+ else if (pTseng->MedDram)
+ new->ExtET6K[0x44] = 0x15; /* Medium speed */
+ else if (pTseng->SlowDram)
+ new->ExtET6K[0x44] = 0x35; /* Slow speed */
+ else
+ ; /* keep current value */
+ }
+ /*
+ * Set the clock selection bits. Because of the odd mapping between
+ * Tseng clock select bits and what XFree86 does, "CSx" refers to a
+ * register bit with the same name in the Tseng data books.
+ *
+ * XFree86 uses the following mapping:
+ *
+ * Tseng register bit name XFree86 clock select bit
+ * CS0 0
+ * CS1 1
+ * CS2 2
+ * MCLK/2 3
+ * CS3 4
+ * CS4 not used
+ */
+ if (mode->ClockIndex >= 0) {
+ /* CS0 and CS1 are set by standard VGA code (vgaHW) */
+ /* CS2 = CRTC 0x34 bit 1 */
+ new->ExtCRTC[0x34] = (new->ExtCRTC[0x34] & 0xFD) |
+ ((mode->ClockIndex & 0x04) >> 1);
+ /* for programmable clocks: disable MCLK/2 and MCLK/4 independent of hibit */
+ new->ExtTS[7] = (new->ExtTS[7] & 0xBE);
+ if (!pScrn->progClock) {
+ /* clock select bit 3 = MCLK/2 disable/enable */
+ new->ExtTS[7] |= (pTseng->save_divide ^ ((mode->ClockIndex & 0x08) << 3));
+ }
+ /* clock select bit 4 = CS3 , clear CS4 */
+ new->ExtCRTC[0x31] = ((mode->ClockIndex & 0x10) << 2) | (new->ExtCRTC[0x31] & 0x3F);
+ }
+ /*
+ * linear mode handling
+ */
+
+ if (Is_ET6K) {
+ if (pTseng->UseLinMem) {
+ new->ExtET6K[0x13] = pTseng->LinFbAddress >> 24;
+ new->ExtET6K[0x40] |= 0x09;
+ } else {
+ new->ExtET6K[0x40] &= ~0x09;
+ }
+ } else { /* et4000 style linear memory */
+ if (pTseng->UseLinMem) {
+ new->ExtCRTC[0x36] |= 0x10;
+ if (Is_W32p || Is_ET6K)
+ new->ExtCRTC[0x30] = (pTseng->LinFbAddress >> 22) & 0xFF;
+ else
+ new->ExtCRTC[0x30] = ((pTseng->LinFbAddress >> 22) & 0x1F) ^ 0x1c; /* invert bits 4..2 */
+ hwp->ModeReg.Graphics[6] &= ~0x0C;
+ new->ExtIMACtrl &= ~0x01; /* disable IMA port (to get >1MB lin mem) */
+ } else {
+ new->ExtCRTC[0x36] &= ~0x10;
+ if (pTseng->ChipType < TYPE_ET4000W32P)
+ new->ExtCRTC[0x30] = 0x1C; /* default value */
+ else
+ new->ExtCRTC[0x30] = 0x00;
+ }
+ }
+
+ /*
+ * 16/24/32 bpp handling.
+ */
+
+ if (pScrn->bitsPerPixel >= 8) {
+ tseng_set_ramdac_bpp(pScrn, mode);
+ row_offset *= pTseng->Bytesperpixel;
+ }
+ /*
+ * Horizontal overflow settings: for modes with > 2048 pixels per line
+ */
+
+ hwp->ModeReg.CRTC[19] = row_offset;
+ new->ExtCRTC[0x3F] = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8)
+ | ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7)
+ | ((((mode->CrtcHBlankStart >> 3) - 1) & 0x100) >> 6)
+ | (((mode->CrtcHSyncStart >> 3) & 0x100) >> 4)
+ | ((row_offset & 0x200) >> 3)
+ | ((row_offset & 0x100) >> 1);
+
+ /*
+ * Enable memory mapped IO registers when acceleration is needed.
+ */
+
+ if (pTseng->UseAccel) {
+ if (Is_ET6K) {
+ if (pTseng->UseLinMem)
+ new->ExtET6K[0x40] |= 0x02; /* MMU can't be used here (causes system hang...) */
+ else
+ new->ExtET6K[0x40] |= 0x06; /* MMU is needed in banked accelerated mode */
+ } else {
+ new->ExtCRTC[0x36] |= 0x28;
+ }
+ }
+ vgaHWUnlock(hwp); /* TODO: is this needed (tsengEnterVT does this) */
+ /* Program the registers */
+ TsengRestore(pScrn, &hwp->ModeReg, new);
+ return TRUE;
+}
+
+static Bool
+TsengSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ PDEBUG(" TsengSwitchMode\n");
+ return TsengModeInit(xf86Screens[scrnIndex], mode);
+}
+
+/*
+ * adjust the current video frame (viewport) to display the mousecursor.
+ */
+static void
+TsengAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ TsengPtr pTseng = TsengPTR(pScrn);
+ int iobase = VGAHWPTR(pScrn)->IOBase;
+ int Base;
+
+ PDEBUG(" TsengAdjustFrame\n");
+
+ if (pTseng->ShowCache) {
+ if (y)
+ y += 256;
+ }
+ if (pScrn->bitsPerPixel < 8)
+ Base = (y * pScrn->displayWidth + x + 3) >> 3;
+ else {
+ Base = ((y * pScrn->displayWidth + x + 1) * pTseng->Bytesperpixel) >> 2;
+ /* adjust Base address so it is a non-fractional multiple of pTseng->Bytesperpixel */
+ Base -= (Base % pTseng->Bytesperpixel);
+ }
+
+ outw(iobase + 4, (Base & 0x00FF00) | 0x0C);
+ outw(iobase + 4, ((Base & 0x00FF) << 8) | 0x0D);
+ outw(iobase + 4, ((Base & 0x0F0000) >> 8) | 0x33);
+
+#ifdef TODO
+#ifdef XFreeXDGA
+ if (pScrn->directMode & XF86DGADirectGraphics) {
+ /* Wait until vertical retrace is in progress. */
+ while (inb(iobase + 0xA) & 0x08) ;
+ while (!(inb(iobase + 0xA) & 0x08)) ;
+ }
+#endif
+#endif
+}
+
+ModeStatus
+TsengValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+#define Tseng_HMAX (4096-8)
+#define Tseng_VMAX (2048-1)
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ PDEBUG(" TsengValidMode\n");
+
+#ifdef FIXME
+ is this needed? xf86ValidMode gets HMAX and VMAX variables, so it could deal with this.
+ need to recheck hsize with mode->Htotal*mulFactor/divFactor
+ /* Check for CRTC timing bits overflow. */
+ if (mode->HTotal * pTseng->Bytesperpixel > Tseng_HMAX) {
+ return MODE_BAD_HVALUE;
+ }
+ if (mode->VTotal > Tseng_VMAX) {
+ return MODE_BAD_VVALUE;
+ }
+#endif
+
+ return MODE_OK;
+}
+
+/*
+ * TsengSave --
+ * save the current video mode
+ */
+
+static void
+TsengSave(ScrnInfoPtr pScrn)
+{
+ unsigned char temp, saveseg1 = 0, saveseg2 = 0;
+ TsengPtr pTseng = TsengPTR(pScrn);
+ vgaRegPtr vgaReg;
+ TsengRegPtr tsengReg;
+ int iobase = VGAHWPTR(pScrn)->IOBase;
+
+ PDEBUG(" TsengSave\n");
+
+ vgaReg = &VGAHWPTR(pScrn)->SavedReg;
+ tsengReg = &pTseng->SavedReg;
+
+ /*
+ * This function will handle creating the data structure and filling
+ * in the generic VGA portion.
+ */
+ vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
+
+ /*
+ * we need this here , cause we MUST disable the ROM SYNC feature
+ * this bit changed with W32p_rev_c...
+ */
+ outb(iobase + 4, 0x34);
+ temp = inb(iobase + 5);
+ tsengReg->ExtCRTC[0x34] = temp;
+ if (Is_stdET4K || Is_W32_W32i || Is_W32p_ab) {
+#ifdef OLD_CODE
+ outb(iobase + 5, temp & 0x1F);
+#else
+ /* data books say translation ROM is controlled by bits 4 and 5 */
+ outb(iobase + 5, temp & 0xCF);
+#endif
+ }
+
+ saveseg1 = inb(0x3CD);
+ outb(0x3CD, 0x00); /* segment select 1 */
+ if (!Is_stdET4K) {
+ saveseg2 = inb(0x3CB);
+ outb(0x3CB, 0x00); /* segment select 2 */
+ }
+ tsengReg->ExtSegSel[0] = saveseg1;
+ tsengReg->ExtSegSel[1] = saveseg2;
+
+ outb(iobase + 4, 0x33);
+ tsengReg->ExtCRTC[0x33] = inb(iobase + 5);
+ outb(iobase + 4, 0x35);
+ tsengReg->ExtCRTC[0x35] = inb(iobase + 5);
+ if (Is_W32_any) {
+ outb(iobase + 4, 0x36);
+ tsengReg->ExtCRTC[0x36] = inb(iobase + 5);
+ outb(iobase + 4, 0x37);
+ tsengReg->ExtCRTC[0x37] = inb(iobase + 5);
+ outb(0x217a, 0xF7);
+ tsengReg->ExtIMACtrl = inb(0x217b);
+ }
+ if (!Is_ET6K) {
+ outb(iobase + 4, 0x32);
+ tsengReg->ExtCRTC[0x32] = inb(iobase + 5);
+ }
+ outb(0x3C4, 6);
+ tsengReg->ExtTS[6] = inb(0x3C5);
+ outb(0x3C4, 7);
+ tsengReg->ExtTS[7] = inb(0x3C5);
+ tsengReg->ExtTS[7] |= 0x14;
+ temp = inb(iobase + 0x0A); /* reset flip-flop */
+ outb(0x3C0, 0x36);
+ tsengReg->ExtATC = inb(0x3C1);
+ outb(0x3C0, tsengReg->ExtATC);
+ if (DAC_is_GenDAC) {
+ /* Save GenDAC Command and PLL registers */
+ outb(iobase + 4, 0x31);
+ temp = inb(iobase + 5);
+ outb(iobase + 5, temp | 0x40);
+
+ tsengReg->pll.cmd_reg = inb(0x3c6); /* Enhanced command register */
+ tsengReg->pll.w_idx = inb(0x3c8); /* PLL write index */
+ tsengReg->pll.r_idx = inb(0x3c7); /* PLL read index */
+ if (Gendac_programmable_clock) {
+ outb(0x3c7, 2); /* index to f2 reg */
+ tsengReg->pll.f2_M = inb(0x3c9); /* f2 PLL M divider */
+ tsengReg->pll.f2_N = inb(0x3c9); /* f2 PLL N1/N2 divider */
+ outb(0x3c7, 10); /* index to Mclk reg */
+#ifdef TODO
+ tsengReg->MClkInfo.MClkM = inb(0x3c9); /* MClk PLL M divider */
+ tsengReg->MClkInfo.MClkN = inb(0x3c9); /* MClk PLL N1/N2 divider */
+#endif
+ }
+ outb(0x3c7, 0x0e); /* index to PLL control */
+ tsengReg->pll.ctrl = inb(0x3c9); /* PLL control */
+ outb(iobase + 4, 0x31);
+ outb(iobase + 5, temp & ~0x40);
+ }
+ if ((pTseng->DacInfo.DacType == STG1702_DAC) || (pTseng->DacInfo.DacType == STG1703_DAC)
+ || (pTseng->DacInfo.DacType == STG1700_DAC)) {
+#ifdef TODO
+ /* Save STG 1703 GenDAC Command and PLL registers
+ * unfortunately we reuse the gendac data structure, so the
+ * field names are not really good.
+ */
+
+ tseng_dactopel();
+ tsengReg->pll.cmd_reg = tseng_getdaccomm(); /* Enhanced command register */
+ if (STG170x_programmable_clock) {
+ tsengReg->pll.f2_M = STG1703getIndex(0x24); /* f2 PLL M divider */
+ tsengReg->pll.f2_N = inb(0x3c6); /* f2 PLL N1/N2 divider */
+ }
+ tsengReg->pll.ctrl = STG1703getIndex(0x03); /* pixel mode select control */
+ tsengReg->pll.timingctrl = STG1703getIndex(0x05); /* pll timing control */
+#endif
+ }
+ if (DAC_IS_CHRONTEL) {
+ tseng_dactopel();
+ tsengReg->pll.cmd_reg = tseng_getdaccomm();
+ if (CH8398_programmable_clock) {
+ inb(0x3c8);
+ inb(0x3c6);
+ inb(0x3c6);
+ inb(0x3c6);
+ inb(0x3c6);
+ inb(0x3c6);
+ tsengReg->pll.timingctrl = inb(0x3c6);
+ /* Save PLL */
+ outb(iobase + 4, 0x31);
+ temp = inb(iobase + 5);
+ outb(iobase + 5, temp | (1 << 6)); /* set RS2 through CS3 */
+ /* We are in ClockRAM mode 0x3c7 = CRA, 0x3c8 = CWA, 0x3c9 = CDR */
+ tsengReg->pll.r_idx = inb(0x3c7);
+ tsengReg->pll.w_idx = inb(0x3c8);
+ outb(0x3c7, 10);
+ tsengReg->pll.f2_N = inb(0x3c9);
+ tsengReg->pll.f2_M = inb(0x3c9);
+ outb(0x3c7, tsengReg->pll.r_idx);
+ inb(0x3c8); /* loop to Clock Select Register */
+ inb(0x3c8);
+ inb(0x3c8);
+ inb(0x3c8);
+ tsengReg->pll.ctrl = inb(0x3c8);
+ outb(iobase + 4, 0x31);
+ outb(iobase + 5, temp);
+ }
+ }
+ if (ET6000_programmable_clock) {
+ /* Save ET6000 CLKDAC PLL registers */
+ temp = inb(pTseng->IOAddress + 0x67); /* remember old CLKDAC index register pointer */
+ outb(pTseng->IOAddress + 0x67, 2);
+ tsengReg->pll.f2_M = inb(pTseng->IOAddress + 0x69);
+ tsengReg->pll.f2_N = inb(pTseng->IOAddress + 0x69);
+ /* save MClk values */
+ outb(pTseng->IOAddress + 0x67, 10);
+ tsengReg->pll.MClkM = inb(pTseng->IOAddress + 0x69);
+ tsengReg->pll.MClkN = inb(pTseng->IOAddress + 0x69);
+ /* restore old index register */
+ outb(pTseng->IOAddress + 0x67, temp);
+ }
+ if (DAC_IS_ATT49x)
+ tsengReg->ATTdac_cmd = tseng_getdaccomm();
+
+ if (Is_ET6K) {
+ tsengReg->ExtET6K[0x13] = inb(pTseng->IOAddress + 0x13);
+ tsengReg->ExtET6K[0x40] = inb(pTseng->IOAddress + 0x40);
+ tsengReg->ExtET6K[0x58] = inb(pTseng->IOAddress + 0x58);
+ tsengReg->ExtET6K[0x41] = inb(pTseng->IOAddress + 0x41);
+ tsengReg->ExtET6K[0x44] = inb(pTseng->IOAddress + 0x44);
+ tsengReg->ExtET6K[0x46] = inb(pTseng->IOAddress + 0x46);
+ }
+ outb(iobase + 4, 0x30);
+ tsengReg->ExtCRTC[0x30] = inb(iobase + 5);
+ outb(iobase + 4, 0x31);
+ tsengReg->ExtCRTC[0x31] = inb(iobase + 5);
+ outb(iobase + 4, 0x3F);
+ tsengReg->ExtCRTC[0x3F] = inb(iobase + 5);
+}
+
+/*
+ * TsengRestore --
+ * restore a video mode
+ */
+
+static void
+TsengRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, TsengRegPtr tsengReg)
+{
+ vgaHWPtr hwp;
+ TsengPtr pTseng;
+ unsigned char tmp;
+ int iobase = VGAHWPTR(pScrn)->IOBase;
+
+ PDEBUG(" TsengRestore\n");
+
+ hwp = VGAHWPTR(pScrn);
+ pTseng = TsengPTR(pScrn);
+
+ TsengProtect(pScrn, TRUE);
+
+ outb(0x3CD, 0x00); /* segment select bits 0..3 */
+ if (!Is_stdET4K)
+ outb(0x3CB, 0x00); /* segment select bits 4,5 */
+
+ if (DAC_is_GenDAC) {
+ /* Restore GenDAC Command and PLL registers */
+ outb(iobase + 4, 0x31);
+ tmp = inb(iobase + 5);
+ outb(iobase + 5, tmp | 0x40);
+
+ outb(0x3c6, tsengReg->pll.cmd_reg); /* Enhanced command register */
+
+ if (Gendac_programmable_clock) {
+ outb(0x3c8, 2); /* index to f2 reg */
+ outb(0x3c9, tsengReg->pll.f2_M); /* f2 PLL M divider */
+ outb(0x3c9, tsengReg->pll.f2_N); /* f2 PLL N1/N2 divider */
+#ifdef TODO
+ if (pTseng->MClkInfo.Set) {
+ outb(0x3c7, 10); /* index to Mclk reg */
+ outb(0x3c9, tsengReg->MClkM); /* MClk PLL M divider */
+ outb(0x3c9, tsengReg->MClkN); /* MClk PLL N1/N2 divider */
+ }
+#endif
+ }
+ outb(0x3c8, 0x0e); /* index to PLL control */
+ outb(0x3c9, tsengReg->pll.ctrl); /* PLL control */
+ outb(0x3c8, tsengReg->pll.w_idx); /* PLL write index */
+ outb(0x3c7, tsengReg->pll.r_idx); /* PLL read index */
+
+ outb(iobase + 4, 0x31);
+ outb(iobase + 5, tmp & ~0x40);
+ }
+ if (DAC_is_STG170x) {
+#ifdef TODO
+ /* Restore STG 170x GenDAC Command and PLL registers
+ * we share one data structure with the gendac code, so the names
+ * are not too good.
+ */
+
+ if (STG170x_programmable_clock) {
+ STG1703setIndex(0x24, tsengReg->pll.f2_M);
+ outb(0x3c6, tsengReg->pll.f2_N); /* use autoincrement */
+ }
+ STG1703setIndex(0x03, tsengReg->pll.ctrl); /* primary pixel mode */
+ outb(0x3c6, tsengReg->pll.ctrl); /* secondary pixel mode */
+ outb(0x3c6, tsengReg->pll.timingctrl); /* pipeline timing control */
+ usleep(500); /* 500 usec PLL settling time required */
+
+ STG1703magic(0);
+ tseng_dactopel();
+ tseng_setdaccomm(tsengReg->pll.cmd_reg); /* write enh command reg */
+#endif
+ }
+ if (DAC_IS_CHRONTEL) {
+ tseng_dactopel();
+ tseng_setdaccomm(tsengReg->pll.cmd_reg);
+ inb(0x3c8);
+ inb(0x3c6);
+ inb(0x3c6);
+ inb(0x3c6);
+ inb(0x3c6);
+ inb(0x3c6);
+ outb(0x3c6, tsengReg->pll.timingctrl);
+ if (CH8398_programmable_clock) {
+ outb(iobase + 4, 0x31);
+ tmp = inb(iobase + 5);
+ outb(iobase + 5, tmp | (1 << 6)); /* Set RS2 through CS3 */
+ /* We are in ClockRAM mode 0x3c7 = CRA, 0x3c8 = CWA, 0x3c9 = CDR */
+ outb(0x3c7, tsengReg->pll.r_idx);
+ outb(0x3c8, 10);
+ outb(0x3c9, tsengReg->pll.f2_N);
+ outb(0x3c9, tsengReg->pll.f2_M);
+ outb(0x3c8, tsengReg->pll.w_idx);
+ usleep(500);
+ inb(0x3c7); /* reset sequence */
+ inb(0x3c8); /* loop to Clock Select Register */
+ inb(0x3c8);
+ inb(0x3c8);
+ inb(0x3c8);
+ outb(0x3c8, tsengReg->pll.ctrl);
+ outb(iobase + 4, 0x31);
+ outb(iobase + 5, (tmp & 0x3F));
+ }
+ }
+ if (ET6000_programmable_clock) {
+ /* Restore ET6000 CLKDAC PLL registers */
+ tmp = inb(pTseng->IOAddress + 0x67); /* remember old CLKDAC index register pointer */
+ outb(pTseng->IOAddress + 0x67, 2);
+ outb(pTseng->IOAddress + 0x69, tsengReg->pll.f2_M);
+ outb(pTseng->IOAddress + 0x69, tsengReg->pll.f2_N);
+ /* set MClk values if needed, but don't touch them if not needed */
+ if (pTseng->MClkInfo.Set) {
+ /*
+ * Since setting the MClk to highly illegal value results in a
+ * total system crash, we'd better play it safe here.
+ * N1 must be <= 4, and N2 should always be 1
+ */
+ if ((tsengReg->pll.MClkN & 0xf8) != 0x20) {
+ xf86Msg(X_ERROR, "Internal Error in MClk registers: MClkM=0x%x, MClkN=0x%x\n",
+ tsengReg->pll.MClkM, tsengReg->pll.MClkN);
+ } else {
+ outb(pTseng->IOAddress + 0x67, 10);
+ outb(pTseng->IOAddress + 0x69, tsengReg->pll.MClkM);
+ outb(pTseng->IOAddress + 0x69, tsengReg->pll.MClkN);
+ }
+ }
+ /* restore old index register */
+ outb(pTseng->IOAddress + 0x67, tmp);
+ }
+ if (DAC_IS_ATT49x)
+ tseng_setdaccomm(tsengReg->ATTdac_cmd);
+
+ if (Is_ET6K) {
+ outb(pTseng->IOAddress + 0x13, tsengReg->ExtET6K[0x13]);
+ outb(pTseng->IOAddress + 0x40, tsengReg->ExtET6K[0x40]);
+ outb(pTseng->IOAddress + 0x58, tsengReg->ExtET6K[0x58]);
+ outb(pTseng->IOAddress + 0x41, tsengReg->ExtET6K[0x41]);
+ outb(pTseng->IOAddress + 0x44, tsengReg->ExtET6K[0x44]);
+ outb(pTseng->IOAddress + 0x46, tsengReg->ExtET6K[0x46]);
+ }
+ outw(iobase + 4, (tsengReg->ExtCRTC[0x3F] << 8) | 0x3F);
+ outw(iobase + 4, (tsengReg->ExtCRTC[0x30] << 8) | 0x30);
+ outw(iobase + 4, (tsengReg->ExtCRTC[0x31] << 8) | 0x31);
+ vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL); /* TODO: does this belong HERE, in the middle? */
+ outw(0x3C4, (tsengReg->ExtTS[6] << 8) | 0x06);
+ outw(0x3C4, (tsengReg->ExtTS[7] << 8) | 0x07);
+ tmp = inb(iobase + 0x0A); /* reset flip-flop */
+ outb(0x3C0, 0x36);
+ outb(0x3C0, tsengReg->ExtATC);
+ outw(iobase + 4, (tsengReg->ExtCRTC[0x33] << 8) | 0x33);
+ outw(iobase + 4, (tsengReg->ExtCRTC[0x34] << 8) | 0x34);
+ outw(iobase + 4, (tsengReg->ExtCRTC[0x35] << 8) | 0x35);
+ if (Is_W32_any) {
+ outw(iobase + 4, (tsengReg->ExtCRTC[0x37] << 8) | 0x37);
+ outw(0x217a, (tsengReg->ExtIMACtrl << 8) | 0xF7);
+ }
+ if (!Is_ET6K) {
+ outw(iobase + 4, (tsengReg->ExtCRTC[0x32] << 8) | 0x32);
+ }
+ outb(0x3CD, tsengReg->ExtSegSel[0]);
+ if (pTseng->ChipType > TYPE_ET4000)
+ outb(0x3CB, tsengReg->ExtSegSel[1]);
+
+#ifdef TODO
+ /*
+ * This might be required for the Legend clock setting method, but
+ * should not be used for the "normal" case because the high order
+ * bits are not set in ClockIndex when returning to text mode.
+ */
+ if (pTseng->Legend) {
+ if (tsengReg->ClockIndex >= 0) {
+ vgaProtect(TRUE);
+ (ClockSelect) (tsengReg->ClockIndex);
+ }
+#endif
+
+ TsengProtect(pScrn, FALSE);
+
+ /*
+ * We must change CRTC 0x36 only OUTSIDE the TsengProtect(pScrn,
+ * TRUE)/TsengProtect(pScrn, FALSE) pair, because the sequencer reset
+ * also resets the linear mode bits in CRTC 0x36.
+ */
+ if (Is_W32_any) {
+ outw(iobase + 4, (tsengReg->ExtCRTC[0x36] << 8) | 0x36);
+ }
+}
+
+/* replacement of vgaHWBlankScreen(pScrn, unblank) without seq reset */
+void
+TsengBlankScreen(ScrnInfoPtr pScrn, Bool unblank)
+{
+ unsigned char scrn;
+ PDEBUG(" TsengBlankScreen\n");
+
+ outb(0x3C4,1);
+ scrn = inb(0x3C5);
+
+ if(unblank) {
+ scrn &= 0xDF; /* enable screen */
+ }else {
+ scrn |= 0x20; /* blank screen */
+ }
+
+/* vgaHWSeqReset(hwp, TRUE);*/
+ outw(0x3C4, (scrn << 8) | 0x01); /* change mode */
+/* vgaHWSeqReset(hwp, FALSE);*/
+}
+
+
+void
+TsengProtect(ScrnInfoPtr pScrn, Bool on)
+{
+ PDEBUG(" TsengProtect\n");
+ vgaHWProtect(pScrn, on);
+}
+
+
+/*
+ * The rest below is stuff from the old driver, which still needs to be
+ * checked and integrated in the ND
+ */
+
+#ifdef OLD_DRIVER
+
+#include "tseng_cursor.h"
+extern vgaHWCursorRec vgaHWCursor;
+
+/*
+ * ET4000Probe --
+ * check whether a Et4000 based board is installed
+ */
+
+static Bool
+ET4000Probe()
+{
+ int numClocks;
+ Bool autodetect = TRUE;
+
+ ...
+
+ if (pScrn->bitsPerPixel >= 8) {
+
+ ...
+
+ /*
+ * Acceleration is only supported on W32 or newer chips.
+ *
+ * Also, some bus configurations only allow for a 1MB linear memory
+ * aperture instead of the default 4M aperture used on all Tseng devices.
+ * If acceleration is also enabled, you only get 512k + (with some aperture
+ * tweaking) 2*128k for a total of max 768 kb of memory. This just isn't
+ * worth having a lot of conditionals in the accelerator code (the
+ * memory-mapped registers move to the top of the 1M aperture), so we
+ * simply don't allow acceleration and linear mode combined on these cards.
+ *
+ */
+
+ if ((pTseng->ChipType < TYPE_ET4000W32) || (pTseng->Linmem_1meg && pTseng->UseLinMem)) {
+ tseng_use_ACL = FALSE;
+ } else {
+ /* enable acceleration-related options */
+ OFLG_SET(OPTION_NOACCEL, &TSENG.ChipOptionFlags);
+ OFLG_SET(OPTION_PCI_RETRY, &TSENG.ChipOptionFlags);
+ OFLG_SET(OPTION_SHOWCACHE, &TSENG.ChipOptionFlags);
+
+ tseng_use_ACL = !OFLG_ISSET(OPTION_NOACCEL, &vga256InfoRec.options);
+ }
+
+ ...
+
+ /* Hardware Cursor support */
+#ifdef W32_HW_CURSOR_FIXED
+ if (pTseng->ChipType >= TYPE_ET4000W32P)
+#else
+ if (Is_ET6K)
+#endif
+ {
+ /* Set HW Cursor option valid */
+ OFLG_SET(OPTION_HW_CURSOR, &TSENG.ChipOptionFlags);
+ }
+ }
+ /* if (pScrn->bitsPerPixel >= 8) */
+ else {
+ OFLG_CLR(OPTION_HW_CURSOR, &vga256InfoRec.options);
+ pTseng->UseLinMem = FALSE;
+ tseng_use_ACL = FALSE;
+ }
+
+ if (!Is_ET6K) {
+ /* Initialize option flags allowed for this driver */
+ OFLG_SET(OPTION_LEGEND, &TSENG.ChipOptionFlags);
+ OFLG_SET(OPTION_HIBIT_HIGH, &TSENG.ChipOptionFlags);
+ OFLG_SET(OPTION_HIBIT_LOW, &TSENG.ChipOptionFlags);
+ if (pScrn->bitsPerPixel >= 8) {
+ OFLG_SET(OPTION_PCI_BURST_ON, &TSENG.ChipOptionFlags);
+ OFLG_SET(OPTION_PCI_BURST_OFF, &TSENG.ChipOptionFlags);
+ OFLG_SET(OPTION_W32_INTERLEAVE_ON, &TSENG.ChipOptionFlags);
+ OFLG_SET(OPTION_W32_INTERLEAVE_OFF, &TSENG.ChipOptionFlags);
+ OFLG_SET(OPTION_SLOW_DRAM, &TSENG.ChipOptionFlags);
+ OFLG_SET(OPTION_FAST_DRAM, &TSENG.ChipOptionFlags);
+ }
+/*
+ * because of some problems with W32 cards, SLOW_DRAM is _always_ enabled
+ * for those cards
+ */
+ if (pTseng->ChipType <= TYPE_ET4000W32) {
+ ErrorF("%s %s: option \"slow_dram\" is enabled by default on this card.\n",
+ XCONFIG_PROBED, vga256InfoRec.name);
+ OFLG_SET(OPTION_SLOW_DRAM, &vga256InfoRec.options);
+ }
+
+ ...
+
+ vga256InfoRec.bankedMono = TRUE;
+#ifdef XFreeXDGA
+ if (pScrn->bitsPerPixel >= 8)
+ vga256InfoRec.directMode = XF86DGADirectPresent;
+#endif
+
+ ...
+
+
+ return (TRUE);
+}
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_inline.h b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_inline.h
new file mode 100644
index 000000000..23149a968
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_inline.h
@@ -0,0 +1,238 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_inline.h,v 1.6 1998/09/05 06:36:56 dawes Exp $ */
+
+
+
+
+
+#include "tseng.h"
+
+/*
+ * Some commonly used inline functions and utility functions.
+ */
+
+static __inline__ int
+COLOR_REPLICATE_DWORD(TsengPtr pTseng, int color)
+{
+ switch (pTseng->Bytesperpixel) {
+ case 1:
+ color &= 0xFF;
+ color = (color << 8) | color;
+ color = (color << 16) | color;
+ break;
+ case 2:
+ color &= 0xFFFF;
+ color = (color << 16) | color;
+ break;
+ }
+ return color;
+}
+
+/*
+ * Optimizing note: increasing the wrap size for fixed-color source/pattern
+ * tiles from 4x1 (as below) to anything bigger doesn't seem to affect
+ * performance (it might have been better for larger wraps, but it isn't).
+ */
+
+static __inline__ void
+SET_FG_COLOR(TsengPtr pTseng, int color)
+{
+ *ACL_SOURCE_ADDRESS = tsengFg;
+ *ACL_SOURCE_Y_OFFSET = 3;
+ color = COLOR_REPLICATE_DWORD(pTseng, color);
+ *tsengMemFg = color;
+ if (Is_W32p || Is_ET6K) {
+ *ACL_SOURCE_WRAP = 0x02;
+ } else {
+ *(tsengMemFg + 1) = color;
+ *ACL_SOURCE_WRAP = 0x12;
+ }
+}
+
+static __inline__ void
+SET_BG_COLOR(TsengPtr pTseng, int color)
+{
+ *ACL_PATTERN_ADDRESS = tsengPat;
+ *ACL_PATTERN_Y_OFFSET = 3;
+ color = COLOR_REPLICATE_DWORD(pTseng, color);
+ *tsengMemPat = color;
+ if (Is_W32p || Is_ET6K) {
+ *ACL_PATTERN_WRAP = 0x02;
+ } else {
+ *(tsengMemPat + 1) = color;
+ *ACL_PATTERN_WRAP = 0x12;
+ }
+}
+
+/*
+ * this does the same as SET_FG_COLOR and SET_BG_COLOR together, but is
+ * faster, because it allows the PCI chipset to chain the requests into a
+ * burst sequence. The order of the commands is partly linear.
+ * So far for the theory...
+ */
+static __inline__ void
+SET_FG_BG_COLOR(TsengPtr pTseng, int fgcolor, int bgcolor)
+{
+ *ACL_PATTERN_ADDRESS = tsengPat;
+ *ACL_SOURCE_ADDRESS = tsengFg;
+ *((LongP) ACL_PATTERN_Y_OFFSET) = 0x00030003;
+ fgcolor = COLOR_REPLICATE_DWORD(pTseng, fgcolor);
+ bgcolor = COLOR_REPLICATE_DWORD(pTseng, bgcolor);
+ *tsengMemFg = fgcolor;
+ *tsengMemPat = bgcolor;
+ if (Is_W32p || Is_ET6K) {
+ *((LongP) ACL_PATTERN_WRAP) = 0x00020002;
+ } else {
+ *(tsengMemFg + 1) = fgcolor;
+ *(tsengMemPat + 1) = bgcolor;
+ *((LongP) ACL_PATTERN_WRAP) = 0x00120012;
+ }
+}
+
+/*
+ * Real 32-bit multiplications are horribly slow compared to 16-bit (on i386).
+ */
+#ifdef NO_OPTIMIZE
+static __inline__ int
+MULBPP(TsengPtr pTseng, int x)
+{
+ return (x * pTseng->Bytesperpixel);
+}
+#else
+static __inline__ int
+MULBPP(TsengPtr pTseng, int x)
+{
+ int result = x << pTseng->powerPerPixel;
+
+ if (pTseng->Bytesperpixel != 3)
+ return result;
+ else
+ return result + x;
+}
+#endif
+
+static __inline__ int
+CALC_XY(TsengPtr pTseng, int x, int y)
+{
+ int new_x, xy;
+
+ if ((old_y == y) && (old_x == x))
+ return -1;
+
+ if (Is_W32p)
+ new_x = MULBPP(pTseng, x - 1);
+ else
+ new_x = MULBPP(pTseng, x) - 1;
+ xy = ((y - 1) << 16) + new_x;
+ old_x = x;
+ old_y = y;
+ return xy;
+}
+
+/* generic SET_XY */
+static __inline__ void
+SET_XY(TsengPtr pTseng, int x, int y)
+{
+ int new_x;
+
+ if (Is_W32p)
+ new_x = MULBPP(pTseng, x - 1);
+ else
+ new_x = MULBPP(pTseng, x) - 1;
+ *ACL_XY_COUNT = ((y - 1) << 16) + new_x;
+ old_x = x;
+ old_y = y;
+}
+
+static __inline__ void
+SET_X_YRAW(TsengPtr pTseng, int x, int y)
+{
+ int new_x;
+
+ if (Is_W32p)
+ new_x = MULBPP(pTseng, x - 1);
+ else
+ new_x = MULBPP(pTseng, x) - 1;
+ *ACL_XY_COUNT = (y << 16) + new_x;
+ old_x = x;
+ old_y = y - 1; /* old_y is invalid (raw transfer) */
+}
+
+/*
+ * This is plain and simple "benchmark rigging".
+ * (no real application does lots of subsequent same-size blits)
+ *
+ * The effect of this is amazingly good on e.g large blits: 400x400
+ * rectangle fill in 24 and 32 bpp on ET6000 jumps from 276 MB/sec to up to
+ * 490 MB/sec... But not always. There must be a good reason why this gives
+ * such a boost, but I don't know it.
+ */
+
+static __inline__ void
+SET_XY_4(TsengPtr pTseng, int x, int y)
+{
+ int new_xy;
+
+ if ((old_y != y) || (old_x != x)) {
+ new_xy = ((y - 1) << 16) + MULBPP(pTseng, x - 1);
+ *ACL_XY_COUNT = new_xy;
+ old_x = x;
+ old_y = y;
+ }
+}
+
+static __inline__ void
+SET_XY_6(TsengPtr pTseng, int x, int y)
+{
+ int new_xy; /* using this intermediate variable is faster */
+
+ if ((old_y != y) || (old_x != x)) {
+ new_xy = ((y - 1) << 16) + MULBPP(pTseng, x) - 1;
+ *ACL_XY_COUNT = new_xy;
+ old_x = x;
+ old_y = y;
+ }
+}
+
+/* generic SET_XY_RAW */
+static __inline__ void
+SET_XY_RAW(int x, int y)
+{
+ *ACL_XY_COUNT = (y << 16) + x;
+ old_x = old_y = -1; /* invalidate old_x/old_y (raw transfers) */
+}
+
+static __inline__ void
+PINGPONG(void)
+{
+ if (tsengFg == W32ForegroundPing) {
+ tsengMemFg = MemW32ForegroundPong;
+ tsengFg = W32ForegroundPong;
+ tsengMemBg = MemW32BackgroundPong;
+ tsengBg = W32BackgroundPong;
+ tsengMemPat = MemW32PatternPong;
+ tsengPat = W32PatternPong;
+ } else {
+ tsengMemFg = MemW32ForegroundPing;
+ tsengFg = W32ForegroundPing;
+ tsengMemBg = MemW32BackgroundPing;
+ tsengBg = W32BackgroundPing;
+ tsengMemPat = MemW32PatternPing;
+ tsengPat = W32PatternPing;
+ }
+}
+
+/*
+ * This is called in each ACL function just before the first ACL register is
+ * written to. It waits for the accelerator to finish on cards that don't
+ * support hardware-wait-state locking, and waits for a free queue entry on
+ * others, if hardware-wait-states are not enabled.
+ */
+static __inline__ void
+wait_acl_queue(TsengPtr pTseng)
+{
+ if (pTseng->UsePCIRetry)
+ WAIT_QUEUE;
+ if (pTseng->need_wait_acl)
+ WAIT_ACL;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_ramdac.c b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_ramdac.c
new file mode 100644
index 000000000..f5f9ed3d1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_ramdac.c
@@ -0,0 +1,662 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tseng/tseng_ramdac.c,v 1.22 1998/08/19 14:05:04 dawes Exp $ */
+
+
+
+
+
+/*
+ *
+ * Copyright 1993-1997 The XFree86 Project, Inc.
+ *
+ */
+
+/*
+ * tseng_ramdac.c.
+ *
+ * Much of this code was taken from the XF86_W32 (3.2) server [kmg]
+ */
+
+#include "tseng.h"
+
+SymTabRec TsengDacTable[] =
+{
+ {NORMAL_DAC, "normal"},
+ {ATT20C47xA_DAC, "att20c47xa"},
+ {Sierra1502X_DAC, "sc1502x"},
+ {ATT20C497_DAC, "att20c497"},
+ {ATT20C490_DAC, "att20c490"},
+ {ATT20C493_DAC, "att20c493"},
+ {ATT20C491_DAC, "att20c491"},
+ {ATT20C492_DAC, "att20c492"},
+ {ICS5341_DAC, "ics5341"},
+ {ICS5301_DAC, "ics5301"},
+ {STG1700_DAC, "stg1700"},
+ {STG1702_DAC, "stg1702"},
+ {STG1703_DAC, "stg1703"},
+ {ET6000_DAC, "et6000"},
+ {CH8398_DAC, "ch8398"},
+ {MUSIC4910_DAC, "music4910"},
+ {UNKNOWN_DAC, "unknown"},
+};
+
+/*** private data ***/
+
+#define RAMDAC_RMR 0x3c6
+#define RAMDAC_READ 0x3c7
+#define RAMDAC_WRITE 0x3c8
+#define RAMDAC_RAM 0x3c9
+
+static unsigned char black_cmap[] =
+{0x0, 0x0, 0x0};
+static unsigned char white_cmap[] =
+{0xff, 0xff, 0xff};
+
+static int saved_cr;
+static int rmr;
+
+void
+tseng_dactopel(void)
+{
+ outb(0x3C8, 0);
+ return;
+}
+
+unsigned char
+tseng_dactocomm(void)
+{
+ (void)inb(0x3C6);
+ (void)inb(0x3C6);
+ (void)inb(0x3C6);
+ return (inb(0x3C6));
+}
+
+unsigned char
+tseng_getdaccomm(void)
+{
+ unsigned char ret;
+
+ tseng_dactopel();
+ (void)tseng_dactocomm();
+ ret = inb(0x3C6);
+ tseng_dactopel();
+ return (ret);
+}
+
+void
+tseng_setdaccomm(unsigned char comm)
+{
+ tseng_dactopel();
+ (void)tseng_dactocomm();
+ outb(0x3C6, comm);
+ tseng_dactopel();
+ return;
+}
+
+static Bool
+ProbeSTG1703(TsengPtr pTseng, Bool quiet)
+{
+ unsigned char cid, did, daccomm, readmask;
+ Bool Found = FALSE;
+
+ readmask = inb(RAMDAC_RMR);
+ tseng_dactopel();
+ daccomm = tseng_getdaccomm();
+ tseng_setdaccomm(daccomm | 0x10);
+ tseng_dactocomm();
+ inb(0x3C6);
+ outb(RAMDAC_RMR, 0x00);
+ outb(RAMDAC_RMR, 0x00);
+ cid = inb(RAMDAC_RMR); /* company ID */
+ did = inb(RAMDAC_RMR); /* device ID */
+ tseng_dactopel();
+ outb(RAMDAC_RMR, readmask);
+ tseng_setdaccomm(daccomm);
+
+ if (cid == 0x44) { /* STG170x RAMDAC found */
+ Found = TRUE;
+ switch (did) {
+ case 0x02:
+ pTseng->DacInfo.DacType = STG1702_DAC;
+ break;
+ case 0x03:
+ pTseng->DacInfo.DacType = STG1703_DAC;
+ break;
+ case 0x00:
+ default:
+ pTseng->DacInfo.DacType = STG1700_DAC;
+ /* treat an unknown STG170x as a 1700 */
+ }
+ }
+ return (Found);
+}
+
+static Bool
+ProbeGenDAC(TsengPtr pTseng, int scrnIndex, Bool quiet)
+{
+ /* probe for ICS GENDAC (ICS5341) */
+ /*
+ * GENDAC and SDAC have two fixed read only PLL clocks
+ * CLK0 f0: 25.255MHz M-byte 0x28 N-byte 0x61
+ * CLK0 f1: 28.311MHz M-byte 0x3d N-byte 0x62
+ * which can be used to detect GENDAC and SDAC since there is no chip-id
+ * for the GENDAC.
+ *
+ * code was taken from S3 XFree86 driver.
+ * NOTE: for the GENDAC on a ET4000W32p, reading PLL values
+ * for CLK0 f0 and f1 always returns 0x7f (but is documented "read only")
+ * In fact, all "read only" registers return 0x7f
+ */
+
+ unsigned char saveCR31, savelut[6];
+ int i;
+ long clock01, clock23;
+ Bool found = FALSE;
+ unsigned char dbyte = 0;
+ int mclk = 0;
+ int iobase = VGAHW_GET_IOBASE();
+
+ outb(iobase + 4, 0x31);
+ saveCR31 = inb(iobase + 5);
+
+ outb(iobase + 5, saveCR31 & ~0x40);
+
+ outb(RAMDAC_READ, 0);
+ for (i = 0; i < 2 * 3; i++) /* save first two LUT entries */
+ savelut[i] = inb(RAMDAC_RAM);
+ outb(RAMDAC_WRITE, 0);
+ for (i = 0; i < 2 * 3; i++) /* set first two LUT entries to zero */
+ outb(RAMDAC_RAM, 0);
+
+ outb(iobase + 4, 0x31);
+ outb(iobase + 5, saveCR31 | 0x40);
+
+ outb(RAMDAC_READ, 0);
+ for (i = clock01 = 0; i < 4; i++)
+ clock01 = (clock01 << 8) | (inb(RAMDAC_RAM) & 0xff);
+ for (i = clock23 = 0; i < 4; i++)
+ clock23 = (clock23 << 8) | (inb(RAMDAC_RAM) & 0xff);
+
+ /* get MClk value */
+ outb(RAMDAC_READ, 0x0a);
+ mclk = (inb(RAMDAC_RAM) + 2) * 14318;
+ dbyte = inb(RAMDAC_RAM);
+ mclk /= ((dbyte & 0x1f) + 2) * (1 << ((dbyte >> 5) & 0x03));
+ pTseng->MClkInfo.MemClk = mclk;
+
+ outb(iobase + 4, 0x31);
+ outb(iobase + 5, saveCR31 & ~0x40);
+
+ outb(RAMDAC_WRITE, 0);
+ for (i = 0; i < 2 * 3; i++) /* restore first two LUT entries */
+ outb(RAMDAC_RAM, savelut[i]);
+
+ outb(iobase + 4, 0x31);
+ outb(iobase + 5, saveCR31);
+
+ if (clock01 == 0x28613d62 ||
+ (clock01 == 0x7f7f7f7f && clock23 != 0x7f7f7f7f)) {
+ found = TRUE;
+
+ tseng_dactopel();
+ inb(RAMDAC_RMR);
+ inb(RAMDAC_RMR);
+ inb(RAMDAC_RMR);
+
+ dbyte = inb(RAMDAC_RMR);
+ /* the fourth read will show the GenDAC/SDAC chip ID and revision */
+ switch (dbyte & 0xf0) {
+ case 0xb0:
+ if (!quiet) {
+ xf86DrvMsg(scrnIndex, X_PROBED, "Ramdac: ICS 5341 GenDAC and programmable clock (MClk = %d MHz)\n",
+ mclk/1000);
+ }
+ pTseng->DacInfo.DacType = ICS5341_DAC;
+ break;
+ case 0xf0:
+ if (!quiet) {
+ xf86DrvMsg(scrnIndex, X_PROBED, "Ramdac: ICS 5301 GenDAC and programmable clock (MClk = %d MHz)\n",
+ mclk/1000);
+ }
+ pTseng->DacInfo.DacType = ICS5301_DAC;
+ break;
+ default:
+ if (!quiet) {
+ xf86DrvMsg(scrnIndex, X_PROBED, "Ramdac: unkown GenDAC and programmable clock (ID code = 0x%02x). Please report. (we'll treat it as a standard ICS5301 for now).\n",
+ dbyte);
+ }
+ pTseng->DacInfo.DacType = ICS5301_DAC;
+ }
+ tseng_dactopel();
+ }
+ return found;
+}
+
+/* probe for RAMDAC using the chip-ID method */
+static Bool
+ProbeRamdacID(TsengPtr pTseng, Bool quiet)
+{
+ unsigned char cid;
+ Bool Found = FALSE;
+
+ tseng_dactopel();
+ cid = inb(RAMDAC_RMR);
+ cid = inb(RAMDAC_RMR);
+ cid = inb(RAMDAC_RMR);
+ cid = inb(RAMDAC_RMR); /* this returns chip ID */
+ switch (cid) {
+ case 0xc0:
+ Found = TRUE;
+ pTseng->DacInfo.DacType = CH8398_DAC;
+ break;
+ case 0x82:
+ Found = TRUE;
+ pTseng->DacInfo.DacType = MUSIC4910_DAC;
+ break;
+ default:
+ Found = FALSE;
+ }
+ tseng_dactopel();
+
+ return Found;
+}
+
+/*
+ * For a description of the following, see AT&T's data sheet for ATT20C490/491
+ * and ATT20C492/493--GGL
+ */
+
+static void
+write_cr(int cr)
+{
+ inb(RAMDAC_WRITE);
+ xf86IODelay();
+ inb(RAMDAC_RMR);
+ xf86IODelay();
+ inb(RAMDAC_RMR);
+ xf86IODelay();
+ inb(RAMDAC_RMR);
+ xf86IODelay();
+ inb(RAMDAC_RMR);
+ xf86IODelay();
+ outb(RAMDAC_RMR, cr);
+ xf86IODelay();
+ inb(RAMDAC_WRITE);
+ xf86IODelay();
+}
+
+static int
+read_cr(void)
+{
+ unsigned int cr;
+
+ inb(RAMDAC_WRITE);
+ xf86IODelay();
+ inb(RAMDAC_RMR);
+ xf86IODelay();
+ inb(RAMDAC_RMR);
+ xf86IODelay();
+ inb(RAMDAC_RMR);
+ xf86IODelay();
+ inb(RAMDAC_RMR);
+ xf86IODelay();
+ cr = inb(RAMDAC_RMR);
+ xf86IODelay();
+ inb(RAMDAC_WRITE);
+ return cr;
+}
+
+static void
+write_color(int entry, unsigned char *cmap)
+{
+ outb(RAMDAC_WRITE, entry);
+ xf86IODelay();
+ outb(RAMDAC_RAM, cmap[0]);
+ xf86IODelay();
+ outb(RAMDAC_RAM, cmap[1]);
+ xf86IODelay();
+ outb(RAMDAC_RAM, cmap[2]);
+ xf86IODelay();
+}
+
+static void
+read_color(int entry, unsigned char *cmap)
+{
+ outb(RAMDAC_READ, entry);
+ xf86IODelay();
+ cmap[0] = inb(RAMDAC_RAM);
+ xf86IODelay();
+ cmap[1] = inb(RAMDAC_RAM);
+ xf86IODelay();
+ cmap[2] = inb(RAMDAC_RAM);
+ xf86IODelay();
+}
+
+Bool
+Check_Tseng_Ramdac(ScrnInfoPtr pScrn)
+{
+ unsigned char cmap[3], save_cmap[3];
+ BOOL cr_saved;
+ int mclk;
+ int temp;
+ int dbyte;
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ PDEBUG(" Check_Tseng_Ramdac\n");
+
+ rmr = inb(RAMDAC_RMR);
+ saved_cr = read_cr();
+ cr_saved = TRUE;
+
+ /* first see if ramdac type was given in XF86Config. If so, assume that is
+ * correct, and don't probe for it.
+ */
+ if (pScrn->ramdac) {
+ pTseng->DacInfo.DacType = xf86StringToToken(TsengDacTable, pScrn->ramdac);
+ if (pTseng->DacInfo.DacType < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unknown RAMDAC type \"%s\" specified\n", pScrn->ramdac);
+ return FALSE;
+ }
+ } else { /* autoprobe for the RAMDAC */
+ if (Is_ET6K) {
+ pTseng->DacInfo.DacType = ET6000_DAC;
+ temp = inb(pTseng->IOAddress + 0x67);
+ outb(pTseng->IOAddress + 0x67, 10);
+ mclk = (inb(pTseng->IOAddress + 0x69) + 2) * 14318;
+ dbyte = inb(pTseng->IOAddress + 0x69);
+ mclk /= ((dbyte & 0x1f) + 2) * (1 << ((dbyte >> 5) & 0x03));
+ pTseng->MClkInfo.MemClk = mclk;
+ } else if (ProbeGenDAC(pTseng, pScrn->scrnIndex, FALSE)) {
+ /* It is. Nothing to do here */
+ } else if (ProbeSTG1703(pTseng, FALSE)) {
+ /* it's a STG170x */
+ } else if (ProbeRamdacID(pTseng, FALSE)) {
+ /* found one using RAMDAC ID code */
+ } else
+ /* if none of the above: start probing for other DACs */
+ {
+ outb(RAMDAC_RMR, 0xff);
+ xf86IODelay();
+ inb(RAMDAC_RMR);
+ xf86IODelay();
+ inb(RAMDAC_RMR);
+ xf86IODelay();
+ inb(RAMDAC_RMR);
+ xf86IODelay();
+ inb(RAMDAC_RMR);
+ xf86IODelay();
+ outb(RAMDAC_RMR, 0x1c);
+ xf86IODelay();
+
+ if (inb(RAMDAC_RMR) != 0xff) {
+ cr_saved = FALSE;
+ pTseng->DacInfo.DacType = ATT20C47xA_DAC;
+ goto dac_found;
+ }
+ write_cr(0xe0);
+ if ((read_cr() >> 5) != 0x7) {
+ pTseng->DacInfo.DacType = ATT20C497_DAC;
+ goto dac_found;
+ }
+ write_cr(0x60);
+ if ((read_cr() >> 5) == 0) {
+ write_cr(0x2);
+ if ((read_cr() & 0x2) != 0)
+ pTseng->DacInfo.DacType = ATT20C490_DAC;
+ else
+ pTseng->DacInfo.DacType = ATT20C493_DAC;
+ } else {
+ write_cr(0x2);
+ outb(RAMDAC_RMR, 0xff);
+ read_color(0xff, save_cmap);
+
+ write_color(0xff, white_cmap);
+ read_color(0xff, cmap);
+
+ if (cmap[0] == 0xff && cmap[1] == 0xff && cmap[2] == 0xff)
+ pTseng->DacInfo.DacType = ATT20C491_DAC;
+ else
+ pTseng->DacInfo.DacType = ATT20C492_DAC;
+
+ write_color(0xff, save_cmap);
+ }
+ }
+ }
+
+ dac_found:
+ /* defaults: 8-bit wide DAC port, 6-bit color lookup-tables */
+ pTseng->DacInfo.RamdacShift = 10;
+ pTseng->DacInfo.RamdacMask = 0x3f;
+ pTseng->DacInfo.Dac8Bit = FALSE;
+ pTseng->DacInfo.DacPort16 = FALSE;
+ pTseng->DacInfo.NotAttCompat = FALSE; /* default: treat as ATT compatible DAC */
+ pScrn->progClock = FALSE;
+ pTseng->ClockChip = -1;
+ pTseng->MClkInfo.Programmable = FALSE;
+
+ /* now override defaults with appropriate values for each RAMDAC */
+ switch (pTseng->DacInfo.DacType) {
+ case ATT20C490_DAC:
+ case ATT20C491_DAC:
+ pTseng->DacInfo.RamdacShift = 8;
+ pTseng->DacInfo.RamdacMask = 0xff;
+ pTseng->DacInfo.Dac8Bit = TRUE;
+ break;
+ case UNKNOWN_DAC:
+ case Sierra1502X_DAC:
+ pTseng->DacInfo.NotAttCompat = TRUE; /* avoids treatment as ATT compatible DAC */
+ break;
+ case ET6000_DAC:
+ pScrn->progClock = TRUE;
+ pTseng->ClockChip = CLOCKCHIP_ET6000;
+ pTseng->DacInfo.NotAttCompat = TRUE; /* avoids treatment as ATT compatible DAC */
+ pTseng->MClkInfo.Programmable = TRUE;
+ pTseng->MClkInfo.min = 80000;
+ pTseng->MClkInfo.max = 110000;
+ break;
+ case ICS5341_DAC:
+ pScrn->progClock = TRUE;
+ pTseng->ClockChip = CLOCKCHIP_ICS5341;
+ pTseng->MClkInfo.Programmable = TRUE;
+ pTseng->MClkInfo.min = 40000;
+ pTseng->MClkInfo.max = 60000;
+ pTseng->DacInfo.DacPort16 = TRUE;
+ break;
+ case ICS5301_DAC:
+ pScrn->progClock = TRUE;
+ pTseng->ClockChip = CLOCKCHIP_ICS5301;
+ break;
+ case STG1702_DAC:
+ case STG1700_DAC:
+ pTseng->DacInfo.DacPort16 = TRUE;
+ break;
+ case STG1703_DAC:
+ pScrn->progClock = TRUE;
+ pTseng->ClockChip = CLOCKCHIP_STG1703;
+ pTseng->DacInfo.DacPort16 = TRUE;
+ break;
+ case CH8398_DAC:
+ pScrn->progClock = TRUE;
+ pTseng->ClockChip = CLOCKCHIP_CH8398;
+ pTseng->DacInfo.DacPort16 = TRUE;
+ break;
+ default:
+ /* defaults already set */
+ ;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, (pScrn->ramdac) ? X_CONFIG : X_PROBED, "Ramdac: \"%s\"\n",
+ xf86TokenToString(TsengDacTable, pTseng->DacInfo.DacType));
+
+ if (cr_saved && pTseng->DacInfo.RamdacShift == 10)
+ write_cr(saved_cr);
+ outb(RAMDAC_RMR, 0xff);
+
+ return TRUE;
+}
+
+/*
+ * The following arrays hold command register values for all possible
+ * modes of the 16-bit DACs used on ET4000W32p cards (bpp/pixel_bus_width):
+ *
+ * { 8bpp/8, 15bpp/8, 16bpp/8, 24bpp/8, 32bpp/8,
+ * 8bpp/16, 15bpp/16, 16bpp/16, 24bpp/16, 32bpp/16
+ * }
+ *
+ * "0xFF" is used as a "not-supported" flag. Assuming no RAMDAC uses this
+ * value for some real configuration...
+ */
+static unsigned char CMD_GENDAC[] =
+{0x00, 0x20, 0x60, 0x40, 0xFF,
+ 0x10, 0x30, 0x50, 0x90, 0x70};
+
+static unsigned char CMD_STG170x[] =
+{0x00, 0x08, 0xFF, 0xFF, 0xFF,
+ 0x05, 0x02, 0x03, 0x09, 0x04};
+
+static unsigned char CMD_CH8398[] =
+{0x04, 0xC4, 0x64, 0x74, 0xFF,
+ 0x24, 0x14, 0x34, 0xB4, 0xFF};
+
+static unsigned char CMD_ATT49x[] =
+{0x00, 0xa0, 0xc0, 0xe0, 0xe0,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+static unsigned char CMD_SC15025[] =
+{0x00, 0xa0, 0xe0, 0x60, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+static unsigned char CMD_MU4910[] =
+{0x1C, 0xBC, 0xDC, 0xFC, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+/*
+ * This sets up the RAMDAC registers for the correct BPP and pixmux values.
+ * (also set VGA controller registers for pixmux and BPP)
+ */
+void
+tseng_set_ramdac_bpp(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ Bool rgb555;
+ Bool dac16bit; /* use DAC in 16-bit mode if set (W32p only) */
+ unsigned char *cmd_array = NULL;
+ unsigned char *cmd_dest = NULL;
+ int index;
+ TsengPtr pTseng = TsengPTR(pScrn);
+
+ rgb555 = (pScrn->weight.red == 5 && pScrn->weight.green == 5
+ && pScrn->weight.blue == 5); /* rgb565 otherwise */
+
+ /* This is not the good way to find out if we're in 8- or 16-bit RAMDAC
+ * mode It should rather be passed on from the TsengValidMode() code.
+ * Right now it'd better agree with what TsengValidMode() proposed. FIXME
+ */
+ dac16bit = (mode->PrivFlags == TSENG_MODE_DACBUS16) ||
+ (mode->PrivFlags == TSENG_MODE_PIXMUX);
+
+ pTseng->ModeReg.ExtATC &= 0xCF; /* ATC index 0x16 -- bits-per-PCLK */
+ if (Is_ET6K)
+ pTseng->ModeReg.ExtATC |= (pTseng->Bytesperpixel - 1) << 4;
+ else if (dac16bit)
+ pTseng->ModeReg.ExtATC |= 0x20;
+
+ switch (pTseng->DacInfo.DacType) {
+ case ATT20C490_DAC:
+ case ATT20C491_DAC:
+ case ATT20C492_DAC:
+ case ATT20C493_DAC:
+ cmd_array = CMD_ATT49x;
+ cmd_dest = &(pTseng->ModeReg.ATTdac_cmd);
+ break;
+ case STG1700_DAC:
+ case STG1702_DAC:
+ case STG1703_DAC:
+ pTseng->ModeReg.pll.cmd_reg &= 0x04; /* keep 7.5 IRE setup setting */
+ pTseng->ModeReg.pll.cmd_reg |= 0x18; /* enable ext regs and pixel modes */
+ switch (pTseng->Bytesperpixel) {
+ case 2:
+ if (rgb555)
+ pTseng->ModeReg.pll.cmd_reg |= 0xA0;
+ else
+ pTseng->ModeReg.pll.cmd_reg |= 0xC0;
+ break;
+ case 3:
+ case 4:
+ pTseng->ModeReg.pll.cmd_reg |= 0xE0;
+ break;
+ }
+ cmd_array = CMD_STG170x;
+ cmd_dest = &(pTseng->ModeReg.pll.ctrl);
+ /* set PLL (input) range */
+ if (mode->SynthClock <= 16000)
+ pTseng->ModeReg.pll.timingctrl = 0;
+ else if (mode->SynthClock <= 32000)
+ pTseng->ModeReg.pll.timingctrl = 1;
+ else if (mode->SynthClock <= 67500)
+ pTseng->ModeReg.pll.timingctrl = 2;
+ else
+ pTseng->ModeReg.pll.timingctrl = 3;
+ break;
+ case ICS5341_DAC:
+ case ICS5301_DAC:
+ cmd_array = CMD_GENDAC;
+ pTseng->ModeReg.pll.ctrl = 0;
+ cmd_dest = &(pTseng->ModeReg.pll.cmd_reg);
+ break;
+ case CH8398_DAC:
+ cmd_array = CMD_CH8398;
+ cmd_dest = &(pTseng->ModeReg.pll.cmd_reg);
+ break;
+ case ET6000_DAC:
+ if (pScrn->bitsPerPixel == 16) {
+ if (rgb555)
+ pTseng->ModeReg.ExtET6K[0x58] &= ~0x02; /* 5-5-5 RGB mode */
+ else
+ pTseng->ModeReg.ExtET6K[0x58] |= 0x02; /* 5-6-5 RGB mode */
+ }
+ break;
+ case MUSIC4910_DAC:
+ cmd_array = CMD_MU4910;
+ cmd_dest = &(pTseng->ModeReg.ATTdac_cmd);
+ break;
+ }
+
+ if (cmd_array != NULL) {
+ switch (pTseng->Bytesperpixel) {
+ default:
+ case 1:
+ index = 0;
+ break;
+ case 2:
+ index = rgb555 ? 1 : 2;
+ break;
+ case 3:
+ index = 3;
+ break;
+ case 4:
+ index = 4;
+ break;
+ }
+ if (dac16bit)
+ index += 5;
+ if (cmd_array[index] != 0xFF) {
+ if (cmd_dest != NULL) {
+ *cmd_dest = cmd_array[index];
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " cmd_dest = NULL -- please report\n");
+ } else {
+ pTseng->ModeReg.pll.cmd_reg = 0;
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " %dbpp not supported in %d-bit DAC mode on this RAMDAC -- Please report.\n",
+ pScrn->bitsPerPixel, dac16bit ? 16 : 8);
+ }
+ }
+#ifdef FIXME /* still needed? */
+ if (mode->PrivFlags == TSENG_MODE_PIXMUX) {
+ VGAHWPTR(pScrn)->ModeReg.CRTC[0x17] &= 0xFB;
+
+ /* to avoid blurred vertical line during flyback, disable H-blanking
+ * (better solution needed !!!)
+ */
+ VGAHWPTR(pScrn)->ModeReg.CRTC[0x02] = 0xff;
+ }
+#endif
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/v4l/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/v4l/Imakefile
new file mode 100644
index 000000000..c7fa64e82
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/v4l/Imakefile
@@ -0,0 +1,41 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/v4l/Imakefile,v 1.3 1999/08/14 10:49:57 dawes Exp $
+XCOMM
+XCOMM This is an Imakefile for the v4l Xv driver.
+XCOMM
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = v4l.c
+OBJS = v4l.o
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/Xext \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/cfb -I$(XF86SRC)/xaa \
+ -I$(XF86SRC)/vgahw -I$(XF86SRC)/ramdac \
+ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
+ -I$(XF86SRC)/xf24_32bpp -I$(FONTINCSRC) \
+ -I$(XF86SRC)/xf8_32bpp -I$(XF86SRC)/xf1bpp \
+ -I$(XF86SRC)/xf4bpp -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c -I$(EXTINCSRC)
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget(v4l,$(OBJS))
+InstallObjectModule(v4l,$(MODULEDIR),drivers/linux)
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/v4l)
+InstallDriverSDKNonExecFile(v4l.c,$(DRIVERSDKDIR)/drivers/v4l)
+InstallDriverSDKNonExecFile(videodev.h,$(DRIVERSDKDIR)/drivers/v4l)
+
+InstallDriverSDKObjectModule(v4l,$(DRIVERSDKMODULEDIR),drivers/linux)
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/v4l/README b/xc/programs/Xserver/hw/xfree86/drivers/v4l/README
new file mode 100644
index 000000000..a3c981265
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/v4l/README
@@ -0,0 +1,39 @@
+
+ Video 4 Linux adaptor driver for XFree86 v4.0
+
+ Developed by Gerd Knorr <kraxel@goldbach.in-berlin.de> and
+ David Woodhouse <David.Woodhouse@mvhi.com>
+
+----------------------------------------------------------------------------
+
+ This chipset driver does not provide a graphics adaptor driver, but instead
+ registers a number of generic Xv adaptors which can be used with any graphics
+ chipset driver.
+
+ In order to use v4l adaptors with your favourite graphics driver, the
+ graphics driver must do two things:
+
+ 1. Correctly set pScrn->memPhysBase and pScrn->fbOffset for the screens that
+ it provides, to the physical address of the frame buffer memory, and
+ the offset within that memory that the current mode starts,
+ respectively.
+
+ 2. Use the xf86XVListGenericAdaptors() routine to list all available Xv
+ adaptors which are usable with any target device, and initialise
+ them on its screens with xf86XVScreenInit() as follows...
+
+ #ifdef XvExtension
+ {
+ XF86VideoAdaptorPtr *ptr;
+
+ int xvexts = xf86XVListGenericAdaptors(&ptr);
+
+ if (xvexts) {
+ xf86XVScreenInit(pScreen,ptr,v4l);
+ }
+ }
+ #endif
+
+
+
+$XFree86: xc/programs/Xserver/hw/xfree86/drivers/v4l/README,v 1.1 1999/03/28 15:32:50 dawes Exp $
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/v4l/v4l.c b/xc/programs/Xserver/hw/xfree86/drivers/v4l/v4l.c
new file mode 100644
index 000000000..5f2f7e61e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/v4l/v4l.c
@@ -0,0 +1,633 @@
+/*
+ * video4linux Xv Driver
+ * based on Michael Schimek's permedia 2 driver.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/v4l/v4l.c,v 1.8 1999/06/06 14:06:07 dawes Exp $ */
+
+#include "videodev.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "xf86Pci.h"
+#include "xf86PciInfo.h"
+#include "xf86fbman.h"
+#include "xf86xv.h"
+#include "Xv.h"
+#include "miscstruct.h"
+#include "dgaproc.h"
+#include "xf86str.h"
+
+
+#include <asm/ioctl.h> /* _IORW(xxx) #defines are here */
+#if 0
+typedef unsigned long ulong;
+#endif
+
+/* XXX Lots of xalloc() calls don't check for failure. */
+
+#define DEBUG(x) (x)
+
+static void V4LIdentify(int flags);
+static Bool V4LProbe(DriverPtr drv, int flags);
+
+DriverRec V4L = {
+ 40000,
+ "Xv driver for video4linux",
+ V4LIdentify, /* Identify*/
+ V4LProbe, /* Probe */
+ NULL,
+ 0
+};
+
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(v4lSetup);
+
+static XF86ModuleVersionInfo v4lVersRec =
+{
+ "v4l",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 0, 0, 1,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0}
+};
+
+XF86ModuleData v4lModuleData = { &v4lVersRec, v4lSetup, NULL };
+
+static pointer
+v4lSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ const char *osname;
+ static Bool setupDone = FALSE;
+
+ if (setupDone) {
+ if (errmaj)
+ *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+
+ setupDone = TRUE;
+
+ /* Check that we're being loaded on a Linux system */
+ LoaderGetOS(&osname, NULL, NULL, NULL);
+ if (!osname || strcmp(osname, "linux") != 0) {
+ if (errmaj)
+ *errmaj = LDR_BADOS;
+ if (errmin)
+ *errmin = 0;
+ return NULL;
+ } else {
+ /* OK */
+
+ xf86AddDriver (&V4L, module, 0);
+
+ return (pointer)1;
+ }
+}
+
+#else
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#endif
+
+typedef struct _PortPrivRec {
+ ScrnInfoPtr pScrn;
+ FBAreaPtr pFBArea[2];
+ int VideoOn; /* yes/no */
+ Bool StreamOn;
+
+ /* file handle */
+ int fd;
+ char devname[16];
+ int useCount;
+
+ /* overlay */
+ struct video_buffer ov_fbuf;
+ struct video_window ov_win;
+
+ /* attributes */
+ struct video_picture pict;
+ struct video_audio audio;
+
+ XF86VideoEncodingPtr enc;
+ int nenc,cenc;
+} PortPrivRec, *PortPrivPtr;
+
+#define XV_ENCODING "XV_ENCODING"
+#define XV_BRIGHTNESS "XV_BRIGHTNESS"
+#define XV_CONTRAST "XV_CONTRAST"
+#define XV_SATURATION "XV_SATURATION"
+#define XV_HUE "XV_HUE"
+
+#define XV_FREQ "XV_FREQ"
+#define XV_MUTE "XV_MUTE"
+#define XV_VOLUME "XV_VOLUME"
+
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+static Atom xvEncoding, xvBrightness, xvContrast, xvSaturation, xvHue;
+static Atom xvFreq, xvMute, xvVolume;
+
+static XF86VideoFormatRec
+InputVideoFormats[] = {
+ { 15, TrueColor },
+ { 16, TrueColor },
+ { 24, TrueColor },
+};
+
+/* ---------------------------------------------------------------------- */
+/* forward decl */
+
+static void V4lQueryBestSize(ScrnInfoPtr pScrn, Bool motion,
+ short vid_w, short vid_h, short drw_w, short drw_h,
+ unsigned int *p_w, unsigned int *p_h, pointer data);
+
+/* ---------------------------------------------------------------------- */
+
+static int V4lOpenDevice(PortPrivPtr pPPriv, ScrnInfoPtr pScrn)
+{
+ pPPriv->useCount++;
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2,
+ "Xv/open: refcount=%d\n",pPPriv->useCount));
+
+ if (pPPriv->fd == -1) {
+ pPPriv->fd = open(pPPriv->devname, O_RDWR, 0);
+
+ pPPriv->ov_fbuf.width = pScrn->virtualX;
+ pPPriv->ov_fbuf.height = pScrn->virtualY;
+ pPPriv->ov_fbuf.depth = pScrn->bitsPerPixel;
+ pPPriv->ov_fbuf.bytesperline = pScrn->displayWidth * ((pScrn->bitsPerPixel + 7)/8);
+ pPPriv->ov_fbuf.base = (pointer)(pScrn->memPhysBase + pScrn->fbOffset);
+
+ if (-1 == ioctl(pPPriv->fd,VIDIOCSFBUF,&(pPPriv->ov_fbuf)))
+ perror("ioctl VIDIOCSFBUF");
+ }
+
+ if (pPPriv->fd == -1)
+ return errno;
+
+ return 0;
+}
+
+static void V4lCloseDevice(PortPrivPtr pPPriv)
+{
+ pPPriv->useCount--;
+
+ DEBUG(xf86DrvMsgVerb(0, X_INFO, 2,
+ "Xv/close: refcount=%d\n",pPPriv->useCount));
+ if(pPPriv->useCount == 0 && pPPriv->fd != -1) {
+ close(pPPriv->fd);
+ pPPriv->fd = -1;
+ }
+}
+
+
+static int
+V4lPutVideo(ScrnInfoPtr pScrn,
+ short vid_x, short vid_y, short drw_x, short drw_y,
+ short vid_w, short vid_h, short drw_w, short drw_h,
+ RegionPtr clipBoxes, pointer data)
+{
+ PortPrivPtr pPPriv = (PortPrivPtr) data;
+ struct video_clip *clip;
+ BoxPtr pBox;
+ unsigned int i,dx,dy,dw,dh;
+ int one=1;
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/PV\n"));
+ /* FIXME: vid-* is ignored for now */
+
+ V4lQueryBestSize(pScrn, 0, vid_w, vid_h, drw_w, drw_h, &dw, &dh, data);
+ /* if the window is too big, center the video */
+ dx = drw_x + (drw_w - dw)/2;
+ dy = drw_y + (drw_h - dh)/2;
+ /* bttv prefeares aligned addresses */
+ dx &= ~3;
+ if (dx < drw_x) dx += 4;
+ if (dx+dw > drw_x+drw_w) dw -= 4;
+
+ /* window */
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, " win: %dx%d+%d+%d\n",
+ drw_w,drw_h,drw_x,drw_y));
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, " use: %dx%d+%d+%d\n",
+ dw,dh,dx,dy));
+ pPPriv->ov_win.x = dx;
+ pPPriv->ov_win.y = dy;
+ pPPriv->ov_win.width = dw;
+ pPPriv->ov_win.height = dh;
+ pPPriv->ov_win.flags = 0;
+
+ /* clipping */
+ if (pPPriv->ov_win.clips) {
+ xfree(pPPriv->ov_win.clips);
+ pPPriv->ov_win.clips = NULL;
+ }
+ pPPriv->ov_win.clipcount = REGION_NUM_RECTS(clipBoxes);
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2," clip: have #%d\n",
+ pPPriv->ov_win.clipcount));
+ if (0 != pPPriv->ov_win.clipcount) {
+ pPPriv->ov_win.clips = xalloc(pPPriv->ov_win.clipcount*sizeof(struct video_clip));
+ memset(pPPriv->ov_win.clips,0,pPPriv->ov_win.clipcount*sizeof(struct video_clip));
+ pBox = REGION_RECTS(clipBoxes);
+ clip = pPPriv->ov_win.clips;
+ for (i = 0; i < REGION_NUM_RECTS(clipBoxes); i++, pBox++, clip++) {
+ clip->x = pBox->x1 - dx;
+ clip->y = pBox->y1 - dy;
+ clip->width = pBox->x2 - pBox->x1;
+ clip->height = pBox->y2 - pBox->y1;
+ }
+ }
+
+ /* Open a file handle to the device */
+
+ if (!pPPriv->VideoOn) {
+ V4lOpenDevice(pPPriv, pScrn);
+ pPPriv->VideoOn = 1;
+ }
+
+ /* start */
+
+ if (-1 == ioctl(pPPriv->fd,VIDIOCSWIN,&(pPPriv->ov_win)))
+ perror("ioctl VIDIOCSWIN");
+ if (-1 == ioctl(pPPriv->fd, VIDIOCCAPTURE, &one))
+ perror("ioctl VIDIOCCAPTURE(1)");
+
+ return Success;
+}
+
+static int
+V4lPutStill(ScrnInfoPtr pScrn,
+ short vid_x, short vid_y, short drw_x, short drw_y,
+ short vid_w, short vid_h, short drw_w, short drw_h,
+ RegionPtr clipBoxes, pointer data)
+{
+ PortPrivPtr pPPriv = (PortPrivPtr) data;
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/PS\n"));
+
+ /* FIXME */
+ return Success;
+}
+
+static void
+V4lStopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit)
+{
+ PortPrivPtr pPPriv = (PortPrivPtr) data;
+ int zero=0;
+
+ if (!pPPriv->VideoOn) {
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2,
+ "Xv/StopVideo called with video already off\n"));
+ return;
+ }
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/StopVideo\n"));
+
+ if (-1 == ioctl(pPPriv->fd, VIDIOCCAPTURE, &zero))
+ perror("ioctl VIDIOCCAPTURE(0)");
+
+ V4lCloseDevice(pPPriv);
+ pPPriv->VideoOn = 0;
+}
+
+/* v4l uses range 0 - 65535; Xv uses -1000 - 1000 */
+static int
+v4l_to_xv(int val) {
+ val = val * 2000 / 65536 - 1000;
+ if (val < -1000) val = -1000;
+ if (val > 1000) val = 1000;
+ return val;
+}
+static int
+xv_to_v4l(int val) {
+ val = val * 65536 / 2000 + 32768;
+ if (val < -0) val = 0;
+ if (val > 65535) val = 65535;
+ return val;
+}
+
+static int
+V4lSetPortAttribute(ScrnInfoPtr pScrn,
+ Atom attribute, INT32 value, pointer data)
+{
+ PortPrivPtr pPPriv = (PortPrivPtr) data;
+ struct video_channel chan;
+ int ret = Success;
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/SPA %d, %d\n",
+ attribute, value));
+
+ V4lOpenDevice(pPPriv, pScrn);
+
+ if (-1 == pPPriv->fd) {
+ ret = Success /* FIXME: EBUSY/ENODEV ?? */;
+ } else if (attribute == xvEncoding) {
+ if (value >= 0 && value < pPPriv->nenc) {
+ pPPriv->cenc = value;
+ chan.channel = value/3;
+ chan.norm = value%3;
+ if (-1 == ioctl(pPPriv->fd,VIDIOCSCHAN,&chan))
+ perror("ioctl VIDIOCSCHAN");
+ } else {
+ ret = BadValue;
+ }
+ } else if (attribute == xvBrightness ||
+ attribute == xvContrast ||
+ attribute == xvSaturation ||
+ attribute == xvHue) {
+ ioctl(pPPriv->fd,VIDIOCGPICT,&pPPriv->pict);
+ if (attribute == xvBrightness) pPPriv->pict.brightness = xv_to_v4l(value);
+ if (attribute == xvContrast) pPPriv->pict.contrast = xv_to_v4l(value);
+ if (attribute == xvSaturation) pPPriv->pict.colour = xv_to_v4l(value);
+ if (attribute == xvHue) pPPriv->pict.hue = xv_to_v4l(value);
+ if (-1 == ioctl(pPPriv->fd,VIDIOCSPICT,&pPPriv->pict))
+ perror("ioctl VIDIOCSPICT");
+ } else if (attribute == xvMute ||
+ attribute == xvVolume) {
+ ioctl(pPPriv->fd,VIDIOCGAUDIO,&pPPriv->audio);
+ if (attribute == xvMute) {
+ if (value)
+ pPPriv->audio.flags |= VIDEO_AUDIO_MUTE;
+ else
+ pPPriv->audio.flags &= ~VIDEO_AUDIO_MUTE;
+ } else if (attribute == xvVolume && (pPPriv->audio.flags & VIDEO_AUDIO_VOLUME)) {
+ pPPriv->audio.volume = xv_to_v4l(value);
+ } else {
+ ret = BadValue;
+ }
+ if (ret != BadValue)
+ if (-1 == ioctl(pPPriv->fd,VIDIOCSAUDIO,&pPPriv->audio))
+ perror("ioctl VIDIOCSAUDIO");
+ } else if (attribute == xvFreq) {
+ if (-1 == ioctl(pPPriv->fd,VIDIOCSFREQ,&value))
+ perror("ioctl VIDIOCSFREQ");
+ } else {
+ ret = BadValue;
+ }
+
+ V4lCloseDevice(pPPriv);
+ return ret;
+}
+
+static int
+V4lGetPortAttribute(ScrnInfoPtr pScrn,
+ Atom attribute, INT32 *value, pointer data)
+{
+ PortPrivPtr pPPriv = (PortPrivPtr) data;
+ int ret = Success;
+
+ V4lOpenDevice(pPPriv, pScrn);
+
+ if (-1 == pPPriv->fd) {
+ ret = Success /* FIXME: EBUSY/ENODEV ?? */;
+ } else if (attribute == xvEncoding) {
+ *value = pPPriv->cenc;
+ } else if (attribute == xvBrightness ||
+ attribute == xvContrast ||
+ attribute == xvSaturation ||
+ attribute == xvHue) {
+ ioctl(pPPriv->fd,VIDIOCGPICT,&pPPriv->pict);
+ if (attribute == xvBrightness) *value = v4l_to_xv(pPPriv->pict.brightness);
+ if (attribute == xvContrast) *value = v4l_to_xv(pPPriv->pict.contrast);
+ if (attribute == xvSaturation) *value = v4l_to_xv(pPPriv->pict.colour);
+ if (attribute == xvHue) *value = v4l_to_xv(pPPriv->pict.hue);
+ } else if (attribute == xvMute ||
+ attribute == xvVolume) {
+ ioctl(pPPriv->fd,VIDIOCGAUDIO,&pPPriv->audio);
+ if (attribute == xvMute) {
+ *value = (pPPriv->audio.flags & VIDEO_AUDIO_MUTE) ? 1 : 0;
+ } else if (attribute == xvVolume && (pPPriv->audio.flags & VIDEO_AUDIO_VOLUME)) {
+ *value = v4l_to_xv(pPPriv->audio.volume);
+ } else {
+ ret = BadValue;
+ }
+ } else if (attribute == xvFreq) {
+ ioctl(pPPriv->fd,VIDIOCGFREQ,value);
+ } else {
+ ret = BadValue;
+ }
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/GPA %d, %d\n",
+ attribute, *value));
+
+ V4lCloseDevice(pPPriv);
+ return ret;
+}
+
+static void
+V4lQueryBestSize(ScrnInfoPtr pScrn, Bool motion,
+ short vid_w, short vid_h, short drw_w, short drw_h,
+ unsigned int *p_w, unsigned int *p_h, pointer data)
+{
+ PortPrivPtr pPPriv = (PortPrivPtr) data;
+ int maxx = pPPriv->enc[pPPriv->cenc].width;
+ int maxy = pPPriv->enc[pPPriv->cenc].height;
+
+ *p_w = (drw_w < maxx) ? drw_w : maxx;
+ *p_h = (drw_h < maxy) ? drw_h : maxy;
+
+ DEBUG(xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "Xv/BS %d %dx%d %dx%d\n",
+ pPPriv->cenc,drw_w,drw_h,*p_w,*p_h));
+}
+
+
+static void
+V4LIdentify(int flags)
+{
+ xf86Msg(X_INFO, "v4l driver for Video4Linux\n");
+}
+
+static char*
+fixname(char *str)
+{
+ int s,d;
+ for (s=0, d=0;; s++) {
+ if (str[s] == '-')
+ continue;
+ str[d++] = tolower(str[s]);
+ if (0 == str[s])
+ break;
+ }
+ return str;
+}
+
+static XF86VideoEncodingPtr
+V4LBuildEncodings(int fd, int *count)
+{
+ static struct video_capability cap;
+ static struct video_channel channel;
+ XF86VideoEncodingPtr enc;
+ int i;
+
+ if (-1 == ioctl(fd,VIDIOCGCAP,&cap))
+ return NULL;
+
+ enc = xalloc(sizeof(XF86VideoEncodingRec)*3*cap.channels);
+ memset(enc,0,sizeof(XF86VideoEncodingRec)*3*cap.channels);
+
+ for (i = 0; i < 3*cap.channels; ) {
+ channel.channel = i/3;
+ if (-1 == ioctl(fd,VIDIOCGCHAN,&channel)) {
+ perror("ioctl VIDIOCGCHAN");
+ return NULL;
+ }
+
+ /* one for PAL ... */
+ enc[i].id = i;
+ enc[i].name = malloc(strlen(channel.name)+8);
+ enc[i].width = 768;
+ enc[i].height = 576;
+ enc[i].rate.numerator = 1;
+ enc[i].rate.denominator = 50;
+ sprintf(enc[i].name,"pal-%s",fixname(channel.name));
+ i++;
+
+ /* NTSC */
+ enc[i].id = i;
+ enc[i].name = malloc(strlen(channel.name)+8);
+ enc[i].width = 640;
+ enc[i].height = 480;
+ enc[i].rate.numerator = 1001;
+ enc[i].rate.denominator = 60000;
+ sprintf(enc[i].name,"ntsc-%s",fixname(channel.name));
+ i++;
+
+ /* SECAM */
+ enc[i].id = i;
+ enc[i].name = malloc(strlen(channel.name)+8);
+ enc[i].width = 768;
+ enc[i].height = 576;
+ enc[i].rate.numerator = 1;
+ enc[i].rate.denominator = 50;
+ sprintf(enc[i].name,"secam-%s",fixname(channel.name));
+ i++;
+ }
+ *count = i;
+ return enc;
+}
+
+
+static char *AttributeNames[8] = {
+ XV_ENCODING,
+ XV_BRIGHTNESS,
+ XV_CONTRAST,
+ XV_SATURATION,
+ XV_HUE,
+ XV_FREQ,
+ XV_MUTE,
+ XV_VOLUME
+};
+
+static int AttributeFlags[8] = {
+ XvGettable | XvSettable,
+ XvGettable | XvSettable,
+ XvGettable | XvSettable,
+ XvGettable | XvSettable,
+ XvGettable | XvSettable,
+ XvGettable | XvSettable,
+ XvGettable | XvSettable,
+ XvGettable | XvSettable,
+};
+
+
+static Bool
+V4LProbe(DriverPtr drv, int flags)
+{
+ PortPrivPtr pPPriv;
+ DevUnion *Private;
+ XF86VideoAdaptorPtr VAR[4];
+ XF86VideoEncodingPtr enc;
+ char dev[16];
+ int fd,i,nenc;
+
+ DEBUG(xf86Msg(X_INFO, "v4l: init start\n"));
+
+ for (i = 0; i < 4; i++) {
+ sprintf(dev,"/dev/video%d",i);
+ fd = open(dev, O_RDWR, 0);
+ if (fd == -1)
+ break;
+ if (NULL == (enc = V4LBuildEncodings(fd,&nenc)))
+ break;
+
+ DEBUG(xf86Msg(X_INFO, "v4l: %s ok\n",dev));
+
+ /* our private data */
+ pPPriv = xalloc(sizeof(PortPrivRec));
+ if (!pPPriv)
+ return FALSE;
+ memset(pPPriv,0,sizeof(PortPrivRec));
+ pPPriv->fd = -1;
+ strncpy(pPPriv->devname, dev, 16);
+ pPPriv->useCount=0;
+ pPPriv->enc = enc;
+ pPPriv->nenc = nenc;
+
+ /* alloc VideoAdaptorRec */
+ VAR[i] = xalloc(sizeof(XF86VideoAdaptorRec));
+ if (!VAR[i])
+ return FALSE;
+ memset(VAR[i],0,sizeof(XF86VideoAdaptorRec));
+
+ /* add attribute lists */
+ VAR[i]->pAttributes = xalloc(sizeof(XF86AttributeListRec));
+ if (!VAR[i]->pAttributes)
+ return FALSE;
+ VAR[i]->pAttributes[0].number = 8;
+ VAR[i]->pAttributes[0].flags = AttributeFlags;
+ VAR[i]->pAttributes[0].names = AttributeNames;
+
+ /* hook in private data */
+ Private = xalloc(sizeof(DevUnion));
+ if (!Private)
+ return FALSE;
+ memset(Private,0,sizeof(DevUnion));
+ Private->ptr = (pointer)pPPriv;
+ VAR[i]->pPortPrivates = Private;
+ VAR[i]->nPorts = 1;
+
+ /* init VideoAdaptorRec */
+ VAR[i]->type = XvInputMask;
+ VAR[i]->name = "video4linux";
+ VAR[i]->flags = VIDEO_INVERT_CLIPLIST;
+
+ VAR[i]->PutVideo = V4lPutVideo;
+ VAR[i]->PutStill = V4lPutStill;
+ VAR[i]->StopVideo = V4lStopVideo;
+ VAR[i]->SetPortAttribute = V4lSetPortAttribute;
+ VAR[i]->GetPortAttribute = V4lGetPortAttribute;
+ VAR[i]->QueryBestSize = V4lQueryBestSize;
+
+ VAR[i]->nEncodings = nenc;
+ VAR[i]->pEncodings = enc;
+ VAR[i]->nFormats =
+ sizeof(InputVideoFormats) / sizeof(InputVideoFormats[0]);
+ VAR[i]->pFormats = InputVideoFormats;
+ if (fd != -1)
+ close(fd);
+ }
+
+ xvEncoding = MAKE_ATOM(XV_ENCODING);
+ xvHue = MAKE_ATOM(XV_HUE);
+ xvSaturation = MAKE_ATOM(XV_SATURATION);
+ xvBrightness = MAKE_ATOM(XV_BRIGHTNESS);
+ xvContrast = MAKE_ATOM(XV_CONTRAST);
+
+ xvFreq = MAKE_ATOM(XV_FREQ);
+ xvMute = MAKE_ATOM(XV_MUTE);
+ xvVolume = MAKE_ATOM(XV_VOLUME);
+
+ DEBUG(xf86Msg(X_INFO, "v4l: init done, %d found\n",i));
+ if (i) {
+ xf86XVRegisterGenericAdaptor(VAR, i);
+ drv->refCount++;
+ }
+ return (VAR != NULL);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/v4l/videodev.h b/xc/programs/Xserver/hw/xfree86/drivers/v4l/videodev.h
new file mode 100644
index 000000000..460ebcd27
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/v4l/videodev.h
@@ -0,0 +1,255 @@
+#ifndef __LINUX_VIDEODEV_H
+#define __LINUX_VIDEODEV_H
+
+/* Linux V4L API, Version 1
+ * videodev.h from v4l driver in Linux 2.2.3
+ *
+ * Used here with the explicit permission of the original author, Alan Cox.
+ * <alan@lxorguk.ukuu.org.uk>
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/v4l/videodev.h,v 1.7 1999/05/15 15:31:57 dawes Exp $ */
+
+#include <Xmd.h>
+
+#define VID_TYPE_CAPTURE 1 /* Can capture */
+#define VID_TYPE_TUNER 2 /* Can tune */
+#define VID_TYPE_TELETEXT 4 /* Does teletext */
+#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
+#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
+#define VID_TYPE_CLIPPING 32 /* Can clip */
+#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
+#define VID_TYPE_SCALES 128 /* Scalable */
+#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
+#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
+
+struct video_capability
+{
+ char name[32];
+ int type;
+ int channels; /* Num channels */
+ int audios; /* Num audio devices */
+ int maxwidth; /* Supported width */
+ int maxheight; /* And height */
+ int minwidth; /* Supported width */
+ int minheight; /* And height */
+};
+
+
+struct video_channel
+{
+ int channel;
+ char name[32];
+ int tuners;
+ CARD32 flags;
+#define VIDEO_VC_TUNER 1 /* Channel has a tuner */
+#define VIDEO_VC_AUDIO 2 /* Channel has audio */
+ CARD16 type;
+#define VIDEO_TYPE_TV 1
+#define VIDEO_TYPE_CAMERA 2
+ CARD16 norm; /* Norm set by channel */
+};
+
+struct video_tuner
+{
+ int tuner;
+ char name[32];
+ unsigned long rangelow, rangehigh; /* Tuner range */
+ CARD32 flags;
+#define VIDEO_TUNER_PAL 1
+#define VIDEO_TUNER_NTSC 2
+#define VIDEO_TUNER_SECAM 4
+#define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */
+#define VIDEO_TUNER_NORM 16 /* Tuner can set norm */
+#define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */
+ CARD16 mode; /* PAL/NTSC/SECAM/OTHER */
+#define VIDEO_MODE_PAL 0
+#define VIDEO_MODE_NTSC 1
+#define VIDEO_MODE_SECAM 2
+#define VIDEO_MODE_AUTO 3
+ CARD16 signal; /* Signal strength 16bit scale */
+};
+
+struct video_picture
+{
+ CARD16 brightness;
+ CARD16 hue;
+ CARD16 colour;
+ CARD16 contrast;
+ CARD16 whiteness; /* Black and white only */
+ CARD16 depth; /* Capture depth */
+ CARD16 palette; /* Palette in use */
+#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */
+#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */
+#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */
+#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */
+#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */
+#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */
+#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */
+#define VIDEO_PALETTE_YUYV 8
+#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */
+#define VIDEO_PALETTE_YUV420 10
+#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */
+#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */
+#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */
+#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */
+#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */
+#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */
+#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */
+#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */
+};
+
+struct video_audio
+{
+ int audio; /* Audio channel */
+ CARD16 volume; /* If settable */
+ CARD16 bass, treble;
+ CARD32 flags;
+#define VIDEO_AUDIO_MUTE 1
+#define VIDEO_AUDIO_MUTABLE 2
+#define VIDEO_AUDIO_VOLUME 4
+#define VIDEO_AUDIO_BASS 8
+#define VIDEO_AUDIO_TREBLE 16
+ char name[16];
+#define VIDEO_SOUND_MONO 1
+#define VIDEO_SOUND_STEREO 2
+#define VIDEO_SOUND_LANG1 4
+#define VIDEO_SOUND_LANG2 8
+ CARD16 mode;
+ CARD16 balance; /* Stereo balance */
+ CARD16 step; /* Step actual volume uses */
+};
+
+struct video_clip
+{
+ INT32 x,y;
+ INT32 width, height;
+ struct video_clip *next; /* For user use/driver use only */
+};
+
+struct video_window
+{
+ CARD32 x,y; /* Position of window */
+ CARD32 width,height; /* Its size */
+ CARD32 chromakey;
+ CARD32 flags;
+ struct video_clip *clips; /* Set only */
+ int clipcount;
+#define VIDEO_WINDOW_INTERLACE 1
+#define VIDEO_CLIP_BITMAP -1
+/* bitmap is 1024x625, a '1' bit represents a clipped pixel */
+#define VIDEO_CLIPMAP_SIZE (128 * 625)
+};
+
+struct video_capture
+{
+ CARD32 x,y; /* Offsets into image */
+ CARD32 width, height; /* Area to capture */
+ CARD16 decimation; /* Decimation divder */
+ CARD16 flags; /* Flags for capture */
+#define VIDEO_CAPTURE_ODD 0 /* Temporal */
+#define VIDEO_CAPTURE_EVEN 1
+};
+
+struct video_buffer
+{
+ void *base;
+ int height,width;
+ int depth;
+ int bytesperline;
+};
+
+struct video_mmap
+{
+ unsigned int frame; /* Frame (0 - n) for double buffer */
+ int height,width;
+ unsigned int format; /* should be VIDEO_PALETTE_* */
+};
+
+struct video_key
+{
+ CARD8 key[8];
+ CARD32 flags;
+};
+
+
+#define VIDEO_MAX_FRAME 32
+
+struct video_mbuf
+{
+ int size; /* Total memory to map */
+ int frames; /* Frames */
+ int offsets[VIDEO_MAX_FRAME];
+};
+
+
+#define VIDEO_NO_UNIT (-1)
+
+
+struct video_unit
+{
+ int video; /* Video minor */
+ int vbi; /* VBI minor */
+ int radio; /* Radio minor */
+ int audio; /* Audio minor */
+ int teletext; /* Teletext minor */
+};
+
+#define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */
+#define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */
+#define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */
+#define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */
+#define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */
+#define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */
+#define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */
+#define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */
+#define VIDIOCGWIN _IOR('v',9, struct video_window) /* Set the video overlay window */
+#define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */
+#define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */
+#define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */
+#define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */
+#define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */
+#define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */
+#define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */
+#define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */
+#define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */
+#define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */
+#define VIDIOCGMBUF _IOR('v', 20, struct video_mbuf) /* Memory map buffer info */
+#define VIDIOCGUNIT _IOR('v', 21, struct video_unit) /* Get attached units */
+#define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get frame buffer */
+#define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set frame buffer - root only */
+
+#define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */
+
+
+#define VID_HARDWARE_BT848 1
+#define VID_HARDWARE_QCAM_BW 2
+#define VID_HARDWARE_PMS 3
+#define VID_HARDWARE_QCAM_C 4
+#define VID_HARDWARE_PSEUDO 5
+#define VID_HARDWARE_SAA5249 6
+#define VID_HARDWARE_AZTECH 7
+#define VID_HARDWARE_SF16MI 8
+#define VID_HARDWARE_RTRACK 9
+#define VID_HARDWARE_ZOLTRIX 10
+#define VID_HARDWARE_SAA7146 11
+#define VID_HARDWARE_VIDEUM 12 /* Reserved for Winnov videum */
+#define VID_HARDWARE_RTRACK2 13
+#define VID_HARDWARE_PERMEDIA2 14 /* Reserved for Permedia2 */
+#define VID_HARDWARE_RIVA128 15 /* Reserved for RIVA 128 */
+#define VID_HARDWARE_PLANB 16 /* PowerMac motherboard video-in */
+#define VID_HARDWARE_BROADWAY 17 /* Broadway project */
+#define VID_HARDWARE_GEMTEK 18
+#define VID_HARDWARE_TYPHOON 19
+#define VID_HARDWARE_VINO 20 /* Reserved for SGI Indy Vino */
+
+/*
+ * Initialiser list
+ */
+
+struct video_init
+{
+ char *name;
+ int (*init)(struct video_init *);
+};
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/vga/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/vga/Imakefile
new file mode 100644
index 000000000..037b5d464
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/vga/Imakefile
@@ -0,0 +1,51 @@
+XCOMM $XConsortium: Imakefile /main/6 1996/09/28 17:29:38 rws $
+
+
+
+
+
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vga/Imakefile,v 1.10 1999/08/26 08:16:18 dawes Exp $
+
+
+
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = generic.c
+
+OBJS = generic.o
+
+#if defined(XF86DriverSDK)
+INCLUDES = -I. -I../../include
+#else
+INCLUDES = -I. -I$(SERVERSRC)/cfb -I$(XF86SRC)/xf4bpp -I$(XF86SRC)/xf1bpp \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi -I$(XF86SRC)/vgahw \
+ -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(FONTINCSRC) -I$(XINCLUDESRC)\
+ -I$(XF86SRC)/rac -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \
+ -I$(XF86SRC)/shadowfb
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget(vga,$(OBJS))
+
+InstallObjectModule(vga,$(MODULEDIR),drivers)
+
+#if !defined(XF86DriverSDK)
+CppManTarget(vga,)
+InstallModuleManPage(vga)
+#endif
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/vga)
+InstallDriverSDKNonExecFile(generic.c,$(DRIVERSDKDIR)/drivers/vga)
+
+InstallDriverSDKObjectModule(vga,$(DRIVERSDKMODULEDIR),drivers)
+
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/vga/generic.c b/xc/programs/Xserver/hw/xfree86/drivers/vga/generic.c
new file mode 100644
index 000000000..07a75e10d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/vga/generic.c
@@ -0,0 +1,1191 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vga/generic.c,v 1.30 1999/06/20 05:23:44 dawes Exp $ */
+/*
+ * Copyright (C) 1998 The XFree86 Project, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * XFREE86 PROJECT 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 XFree86 Project 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
+ * XFree86 Project.
+ */
+
+/*
+ * This is essentially a merge of two different drivers: a VGA planar driver
+ * (originally by David Dawes <dawes@xfree86.org>) and a 256-colour VGA driver
+ * by Harm Hanemaayer <hhanemaa@cs.ruu.nl>.
+ *
+ * The port of this driver to XFree86 4.0 was done by:
+ * David Dawes <dawes@xfree86.org>
+ * Dirk H. Hohndel <hohndel@xfree86.org>
+ * Marc Aurele La France <tsi@ualberta.ca>
+ */
+
+#define DEBUG(x)
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "compiler.h"
+#include "vgaHW.h"
+#include "xf86PciInfo.h"
+
+#undef PSZ
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+
+#include "xf4bpp.h"
+#include "xf1bpp.h"
+
+#include "shadowfb.h"
+
+#include "mipointer.h"
+#include "micmap.h"
+
+#include "xf86RAC.h"
+#include "xf86Resources.h"
+
+/* Some systems define VGA for their own purposes */
+#undef VGA
+
+/* A few things all drivers should have */
+#define VGA_NAME "VGA"
+#define VGA_DRIVER_NAME "vga"
+#define VGA_VERSION_NAME "4.0"
+#define VGA_VERSION_MAJOR 4
+#define VGA_VERSION_MINOR 0
+#define VGA_PATCHLEVEL 0
+#define VGA_VERSION_CURRENT ((VGA_VERSION_MAJOR << 24) | \
+ (VGA_VERSION_MINOR << 16) | VGA_PATCHLEVEL)
+
+
+/* Forward definitions */
+static void GenericIdentify(int);
+static Bool GenericProbe(DriverPtr, int);
+static Bool GenericPreInit(ScrnInfoPtr, int);
+static Bool GenericScreenInit(int, ScreenPtr, int, char **);
+static Bool GenericSwitchMode(int, DisplayModePtr, int);
+static void GenericAdjustFrame(int, int, int, int);
+static Bool GenericEnterVT(int, int);
+static void GenericLeaveVT(int, int);
+static void GenericFreeScreen(int, int);
+static int VGAFindIsaDevice(GDevPtr dev);
+
+static int GenericValidMode(int, DisplayModePtr, Bool, int);
+
+/* The root of all evil... */
+DriverRec VGA =
+{
+ VGA_VERSION_CURRENT,
+ "Generic VGA driver",
+ GenericIdentify,
+ GenericProbe,
+ NULL,
+ 0
+};
+
+typedef enum {
+ OPTION_SHADOW_FB
+} GenericOpts;
+
+static OptionInfoRec GenericOptions[] = {
+ { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+static const char *vgahwSymbols[] = {
+ "vgaHWGetHWRec",
+ "vgaHWUnlock",
+ "vgaHWInit",
+ "vgaHWProtect",
+ "vgaHWGetIOBase",
+ "vgaHWMapMem",
+ "vgaHWLock",
+ "vgaHWFreeHWRec",
+ "vgaHWSaveScreen",
+ NULL
+};
+
+static const char *fbSymbols[] = {
+ "xf1bppScreenInit",
+ "xf4bppScreenInit",
+ "cfbScreenInit",
+ "mfbScreenInit",
+ NULL
+};
+
+static const char *shadowfbSymbols[] = {
+ "ShadowFBInit",
+ NULL
+};
+
+#ifdef XFree86LOADER
+
+/* Module loader interface */
+
+static MODULESETUPPROTO(GenericSetup);
+
+static XF86ModuleVersionInfo GenericVersionRec =
+{
+ VGA_DRIVER_NAME,
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ VGA_VERSION_MAJOR, VGA_VERSION_MINOR, VGA_PATCHLEVEL,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0, 0, 0, 0}
+};
+
+/*
+ * This data is accessed by the loader. The name must be the module name
+ * followed by "ModuleInit".
+ */
+XF86ModuleData vgaModuleData = { &GenericVersionRec, GenericSetup, NULL };
+
+static pointer
+GenericSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor)
+{
+ static Bool Initialised = FALSE;
+
+ if (!Initialised)
+ {
+ Initialised = TRUE;
+ xf86AddDriver(&VGA, Module, 0);
+ LoaderRefSymLists(vgahwSymbols, fbSymbols, shadowfbSymbols,
+ NULL);
+ return (pointer)TRUE;
+ }
+
+ if (ErrorMajor)
+ *ErrorMajor = LDR_ONCEONLY;
+ return NULL;
+}
+
+#endif
+
+
+enum GenericTypes
+{
+ CHIP_VGA_GENERIC
+};
+
+/* Supported chipsets */
+static SymTabRec GenericChipsets[] =
+{
+ {CHIP_VGA_GENERIC, "generic"},
+ {-1, NULL}
+};
+
+static PciChipsets GenericPCIchipsets[] = {
+ { CHIP_VGA_GENERIC, PCI_CHIP_VGA, RES_SHARED_VGA },
+ { -1, -1, RES_UNDEFINED },
+};
+
+static IsaChipsets GenericISAchipsets[] = {
+ {CHIP_VGA_GENERIC, RES_EXCLUSIVE_VGA},
+ {-1, 0 }
+};
+
+static void
+GenericIdentify(int flags)
+{
+ xf86PrintChipsets(VGA_NAME,
+ "Generic VGA driver (version " VGA_VERSION_NAME ") for chipsets",
+ GenericChipsets);
+}
+
+
+/*
+ * This function is called once, at the start of the first server generation to
+ * do a minimal probe for supported hardware.
+ */
+
+static Bool
+GenericProbe(DriverPtr drv, int flags)
+{
+ Bool foundScreen = FALSE;
+ int numDevSections, numUsed;
+ GDevPtr *devSections;
+ int *usedChips;
+ int i;
+
+ /*
+ * Find the config file Device sections that match this
+ * driver, and return if there are none.
+ */
+ if ((numDevSections = xf86MatchDevice(VGA_NAME,
+ &devSections)) <= 0) {
+ return FALSE;
+ }
+
+ /* PCI BUS */
+ if (xf86GetPciVideoInfo() ) {
+ numUsed = xf86MatchPciInstances(VGA_NAME, PCI_VENDOR_GENERIC,
+ GenericChipsets, GenericPCIchipsets,
+ devSections,numDevSections,
+ drv, &usedChips);
+ if (numUsed > 0){
+ for (i = 0; i < numUsed; i++) {
+ /* Allocate a ScrnInfoRec */
+ ScrnInfoPtr pScrn = xf86AllocateScreen(drv,0);
+ pScrn->driverVersion = VGA_VERSION_CURRENT;
+ pScrn->driverName = VGA_DRIVER_NAME;
+ pScrn->name = VGA_NAME;
+ pScrn->Probe = GenericProbe;
+ pScrn->PreInit = GenericPreInit;
+ pScrn->ScreenInit = GenericScreenInit;
+ pScrn->SwitchMode = GenericSwitchMode;
+ pScrn->AdjustFrame = GenericAdjustFrame;
+ pScrn->EnterVT = GenericEnterVT;
+ pScrn->LeaveVT = GenericLeaveVT;
+ pScrn->FreeScreen = GenericFreeScreen;
+ pScrn->ValidMode = GenericValidMode;
+ foundScreen = TRUE;
+ xf86ConfigActivePciEntity(pScrn,usedChips[i],GenericPCIchipsets,
+ NULL,NULL,NULL,NULL,NULL);
+ }
+ }
+ }
+ /* Isa Bus */
+ numUsed = xf86MatchIsaInstances(VGA_NAME,GenericChipsets,
+ GenericISAchipsets,drv,
+ VGAFindIsaDevice,devSections,
+ numDevSections,&usedChips);
+ if(numUsed >= 0)
+ for (i = 0; i < numUsed; i++) {
+ ScrnInfoPtr pScrn = xf86AllocateScreen(drv,0);
+
+ pScrn->driverVersion = VGA_VERSION_CURRENT;
+ pScrn->driverName = VGA_DRIVER_NAME;
+ pScrn->name = VGA_NAME;
+ pScrn->Probe = GenericProbe;
+ pScrn->PreInit = GenericPreInit;
+ pScrn->ScreenInit = GenericScreenInit;
+ pScrn->SwitchMode = GenericSwitchMode;
+ pScrn->AdjustFrame = GenericAdjustFrame;
+ pScrn->EnterVT = GenericEnterVT;
+ pScrn->LeaveVT = GenericLeaveVT;
+ pScrn->FreeScreen = GenericFreeScreen;
+ pScrn->ValidMode = GenericValidMode;
+ foundScreen = TRUE;
+ xf86ConfigActiveIsaEntity(pScrn,usedChips[i],GenericISAchipsets,
+ NULL,NULL,NULL,NULL,NULL);
+ }
+ xfree(devSections);
+ return foundScreen;
+}
+
+static int
+VGAFindIsaDevice(GDevPtr dev)
+{
+#ifndef PC98_EGC
+ CARD16 GenericIOBase = VGAHW_GET_IOBASE();
+ CARD8 CurrentValue, TestValue;
+
+ /* There's no need to unlock VGA CRTC registers here */
+
+ /* VGA has one more read/write attribute register than EGA */
+ (void) inb(GenericIOBase + 0x0AU); /* Reset flip-flop */
+ outb(0x3C0, 0x14 | 0x20);
+ CurrentValue = inb(0x3C1);
+ outb(0x3C0, CurrentValue ^ 0x0F);
+ outb(0x3C0, 0x14 | 0x20);
+ TestValue = inb(0x3C1);
+ outb(0x3C0, CurrentValue);
+
+ /* Quit now if no VGA is present */
+ if ((CurrentValue ^ 0x0F) != TestValue)
+ return -1;
+#endif
+ return (int)CHIP_VGA_GENERIC;
+}
+
+static Bool
+GenericClockSelect(ScrnInfoPtr pScreenInfo, int ClockNumber)
+{
+# ifndef PC98_EGC
+ static CARD8 save_misc;
+
+ switch (ClockNumber)
+ {
+ case CLK_REG_SAVE:
+ save_misc = inb(0x3CC);
+ break;
+
+ case CLK_REG_RESTORE:
+ outb(0x3C2, save_misc);
+ break;
+
+ default:
+ outb(0x3C2, (save_misc & 0xF3) | ((ClockNumber << 2) & 0x0C));
+ break;
+ }
+# endif
+
+ return TRUE;
+}
+
+
+/*
+ * This structure is used to wrap the screen's CloseScreen vector.
+ */
+typedef struct _GenericRec
+{
+ Bool ShadowFB;
+ CARD8 * ShadowPtr;
+ CARD32 ShadowPitch;
+ CloseScreenProcPtr CloseScreen;
+} GenericRec, *GenericPtr;
+
+
+static GenericPtr
+GenericGetRec(ScrnInfoPtr pScreenInfo)
+{
+ if (!pScreenInfo->driverPrivate)
+ pScreenInfo->driverPrivate = xcalloc(sizeof(GenericRec), 1);
+
+ return (GenericPtr)pScreenInfo->driverPrivate;
+}
+
+
+static void
+GenericFreeRec(ScrnInfoPtr pScreenInfo)
+{
+ vgaHWFreeHWRec(pScreenInfo);
+ xfree(pScreenInfo->driverPrivate);
+ pScreenInfo->driverPrivate = NULL;
+}
+
+
+static void
+GenericProtect(ScrnInfoPtr pScreenInfo, Bool On)
+{
+ vgaHWProtect(pScreenInfo, On);
+}
+
+
+static Bool
+GenericSaveScreen(ScreenPtr pScreen, Bool Unblank)
+{
+ return vgaHWSaveScreen(pScreen, Unblank);
+}
+
+static void
+GenericBlankScreen(ScrnInfoPtr pScreenInfo, Bool Unblank)
+{
+ vgaHWBlankScreen(pScreenInfo, Unblank);
+}
+
+
+/* The default mode */
+static DisplayModeRec GenericDefaultMode =
+{
+ NULL, NULL, /* prev & next */
+ "Generic 320x200 default mode",
+ MODE_OK, /* Mode status */
+ M_T_CRTC_C, /* Mode type */
+ 12588, /* Pixel clock */
+ 320, 336, 384, 400, /* HTiming */
+ 0, /* HSkew */
+ 200, 206, 207, 224, /* VTiming */
+ 2, /* VScan */
+ V_CLKDIV2 | V_NHSYNC | V_PVSYNC, /* Flags */
+ 0, 25176, /* ClockIndex & SynthClock */
+ 0, 0, 0, 0, 0, 0, /* Crtc timings set by ... */
+ 0, /* ... xf86SetCrtcForModes() */
+ 0, 0, 0, 0, 0, 0,
+ FALSE, FALSE, /* These are unadjusted timings */
+ 0, NULL /* PrivSize & Private */
+};
+
+
+/*
+ * This function is called once for each screen at the start of the first
+ * server generation to initialise the screen for all server generations.
+ */
+static Bool
+GenericPreInit(ScrnInfoPtr pScreenInfo, int flags)
+{
+ static rgb defaultWeight = {0, 0, 0};
+ static ClockRange GenericClockRange = {NULL, 0, 80000, 0, FALSE, TRUE, 1, 1, 0};
+ MessageType From;
+ int i, videoRam, Rounding, nModes = 0;
+ char *Module;
+ const char *Sym;
+ vgaHWPtr pvgaHW;
+ GenericPtr pGenericPriv;
+ EntityInfoPtr pEnt;
+
+ /* Set the monitor */
+ pScreenInfo->monitor = pScreenInfo->confScreen->monitor;
+
+ if (pScreenInfo->numEntities > 1)
+ return FALSE;
+ pEnt = xf86GetEntityInfo(*pScreenInfo->entityList);
+ if (pEnt->resources)
+ return FALSE;
+
+ {
+ resRange unusedmem[] = { {ResShrMemBlock,0xB0000,0xB7FFF},
+ {ResShrMemBlock,0xB8000,0xBFFFF},
+ _END };
+
+ /* XXX Should this be "disabled" or "unused"? */
+ xf86SetOperatingState(unusedmem, pEnt->index, ResUnusedOpr);
+ }
+
+ /* Determine depth, bpp, etc. */
+ if (!xf86SetDepthBpp(pScreenInfo, 4, 0, 4, NoDepth24Support))
+ return FALSE;
+ pScreenInfo->chipset = (char *)xf86TokenToString(GenericChipsets,
+ pEnt->chipset);
+
+ switch (pScreenInfo->depth)
+ {
+ case 1: Module = "xf1bpp"; Sym = "xf1bppScreenInit"; break;
+ case 4: Module = "xf4bpp"; Sym = "xf4bppScreenInit"; break;
+ case 8: Module = "cfb"; Sym = "cfbScreenInit"; break;
+
+ default:
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Given depth (%d) is not supported by this driver.\n",
+ pScreenInfo->depth);
+ return FALSE;
+ }
+ xf86PrintDepthBpp(pScreenInfo);
+
+ /* Determine colour weights */
+ pScreenInfo->rgbBits = 6;
+ if (!xf86SetWeight(pScreenInfo, defaultWeight, defaultWeight))
+ return FALSE;
+
+ /* XXX: Check that returned weight is supported */
+
+ /* Determine default visual */
+ if (!xf86SetDefaultVisual(pScreenInfo, -1))
+ return FALSE;
+
+ /* The gamma fields must be initialised when using the new cmap code */
+ if (pScreenInfo->depth > 1) {
+ Gamma zeros = {0.0, 0.0, 0.0};
+
+ if (!xf86SetGamma(pScreenInfo, zeros))
+ return FALSE;
+ }
+
+ /*
+ * Determine videoRam. For mode validation purposes, this needs to be
+ * limited to VGA specifications.
+ */
+ if ((videoRam = pEnt->device->videoRam))
+ {
+ pScreenInfo->videoRam = videoRam;
+ if (pScreenInfo->depth == 8)
+ {
+ if (videoRam > 64)
+ pScreenInfo->videoRam = 64;
+ }
+ else
+ {
+ if (videoRam > 256)
+ pScreenInfo->videoRam = 256;
+ }
+ From = X_CONFIG;
+ }
+ else
+ {
+ if (pScreenInfo->depth == 8)
+ videoRam = 64;
+ else
+ videoRam = 256;
+ pScreenInfo->videoRam = videoRam;
+ From = X_DEFAULT; /* Instead of X_PROBED */
+ }
+ if (pScreenInfo->depth == 1)
+ pScreenInfo->videoRam >>= 2;
+ xf86DrvMsg(pScreenInfo->scrnIndex, From, "videoRam: %d kBytes", videoRam);
+ if (videoRam != pScreenInfo->videoRam)
+ xf86ErrorF(" (using %d kBytes)", pScreenInfo->videoRam);
+ xf86ErrorF(".\n");
+
+ if (xf86RegisterResources(pEnt->index,NULL,ResNone))
+ return FALSE;
+
+ /* Ensure vgahw entry points are available for the clock probe */
+ if (!xf86LoadSubModule(pScreenInfo, "vgahw"))
+ return FALSE;
+
+ xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+ /* Allocate driver private structure */
+ if (!(pGenericPriv = GenericGetRec(pScreenInfo)))
+ return FALSE;
+
+ /* Ensure vgahw private structure is allocated */
+ if (!vgaHWGetHWRec(pScreenInfo))
+ return FALSE;
+
+
+ pvgaHW = VGAHWPTR(pScreenInfo);
+ pvgaHW->MapSize = 0x00010000; /* Standard 64kB VGA window */
+ vgaHWGetIOBase(pvgaHW); /* Get VGA I/O base */
+
+#ifndef __NOT_YET__
+ if (pScreenInfo->depth == 8)
+ {
+ pScreenInfo->numClocks = 1;
+ pScreenInfo->clock[0] = 25175;
+ goto SetDefaultMode;
+ }
+#endif
+
+ /*
+ * Determine clocks. Limit them to the first four because that's all that
+ * can be addressed.
+ */
+ if ((pScreenInfo->numClocks = pEnt->device->numclocks))
+ {
+ if (pScreenInfo->numClocks > 4)
+ pScreenInfo->numClocks = 4;
+ for (i = 0; i < pScreenInfo->numClocks; i++)
+ pScreenInfo->clock[i] = pEnt->device->clock[i];
+ From = X_CONFIG;
+ }
+ else
+ {
+ xf86GetClocks(pScreenInfo, 4, GenericClockSelect, GenericProtect,
+ GenericBlankScreen, VGAHW_GET_IOBASE() + 0x0A, 0x08, 1, 28322);
+ From = X_PROBED;
+ }
+ xf86ShowClocks(pScreenInfo, From);
+
+ if (pScreenInfo->display->modes && pScreenInfo->display->modes[0])
+ {
+ /* Set the virtual X rounding (in bits) */
+ if (pScreenInfo->depth == 8)
+ Rounding = 16 * 8;
+ else
+ Rounding = 16;
+
+ /*
+ * Validate the modes. Note that the limits passed to
+ * xf86ValidateModes() are VGA CRTC architectural limits.
+ */
+ pScreenInfo->maxHValue = 2080;
+ pScreenInfo->maxVValue = 1025;
+ nModes = xf86ValidateModes(pScreenInfo,
+ pScreenInfo->monitor->Modes, pScreenInfo->display->modes,
+ &GenericClockRange, NULL, 8, 2040, Rounding, 1, 1024,
+ pScreenInfo->display->virtualX, pScreenInfo->display->virtualY,
+ 0x10000, LOOKUP_CLOSEST_CLOCK | LOOKUP_CLKDIV2);
+
+ if (nModes < 0)
+ return FALSE;
+
+ /* Remove invalid modes */
+ xf86PruneDriverModes(pScreenInfo);
+ }
+
+ if (!nModes || !pScreenInfo->modes)
+ {
+#ifndef __NOT_YET__
+ SetDefaultMode:
+#endif
+ /* Set a default mode, overridding any virtual settings */
+ pScreenInfo->virtualX = pScreenInfo->displayWidth = 320;
+ pScreenInfo->virtualY = 200;
+ pScreenInfo->modes = xalloc(sizeof(DisplayModeRec));
+ if (!pScreenInfo->modes)
+ return FALSE;
+ *pScreenInfo->modes = GenericDefaultMode;
+ pScreenInfo->modes->prev = pScreenInfo->modes;
+ pScreenInfo->modes->next = pScreenInfo->modes;
+
+ pScreenInfo->virtualFrom = X_DEFAULT;
+ }
+
+ /* Set CRTC values for the modes */
+ xf86SetCrtcForModes(pScreenInfo, 0);
+
+ /* Set current mode to the first in list */
+ pScreenInfo->currentMode = pScreenInfo->modes;
+
+ /* Print mode list */
+ xf86PrintModes(pScreenInfo);
+
+ /* Set display resolution */
+ xf86SetDpi(pScreenInfo, 0, 0);
+
+ /* Deal with options */
+ xf86CollectOptions(pScreenInfo, NULL);
+ xf86ProcessOptions(pScreenInfo->scrnIndex, pScreenInfo->options,
+ GenericOptions);
+
+ if (xf86ReturnOptValBool(GenericOptions,OPTION_SHADOW_FB,FALSE)) {
+ pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
+ pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+ pGenericPriv->ShadowFB = TRUE;
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG,
+ "Using \"Shadow Framebuffer\"\n");
+ switch (pScreenInfo->depth)
+ {
+ case 1: Module = "mfb"; Sym = "mfbScreenInit"; break;
+ case 4: Module = "cfb"; Sym = "cfbScreenInit"; break;
+ }
+ if (!xf86LoadSubModule(pScreenInfo, "shadowfb"))
+ return FALSE;
+ xf86LoaderReqSymLists(shadowfbSymbols, NULL);
+ }
+
+ /* Ensure depth-specific entry points are available */
+ if (!xf86LoadSubModule(pScreenInfo, Module))
+ return FALSE;
+
+ xf86LoaderReqSymbols(Sym, NULL);
+
+ /* Only one chipset here */
+ if (!pScreenInfo->chipset)
+ pScreenInfo->chipset = (char *)GenericChipsets[0].name;
+
+ return TRUE; /* Tada! */
+}
+
+
+/* Save mode on server entry */
+static void
+GenericSave(ScrnInfoPtr pScreenInfo)
+{
+ vgaHWSave(pScreenInfo, &VGAHWPTR(pScreenInfo)->SavedReg, VGA_SR_ALL);
+}
+
+
+/* Restore the mode that was saved on server entry */
+static void
+GenericRestore(ScrnInfoPtr pScreenInfo)
+{
+ vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo);
+
+ vgaHWProtect(pScreenInfo, TRUE);
+ vgaHWRestore(pScreenInfo, &pvgaHW->SavedReg, VGA_SR_ALL);
+ vgaHWProtect(pScreenInfo, FALSE);
+}
+
+
+/* Set a graphics mode */
+static Bool
+GenericSetMode(ScrnInfoPtr pScreenInfo, DisplayModePtr pMode)
+{
+ vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo);
+
+ if (!vgaHWInit(pScreenInfo, pMode))
+ return FALSE;
+ pScreenInfo->vtSema = TRUE;
+
+#ifndef __NOT_YET__
+ if (pScreenInfo->depth == 8)
+ {
+ int i;
+
+ static const CARD8 CRTC[24] =
+ {
+#ifndef DEBUGOVERSCAN
+ 0x5F, 0x4F, 0x4F, 0x80, 0x54, 0x00, 0xBE, 0x1F,
+ 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9C, 0x0E, 0x8F, 0x28, 0x40, 0x8F, 0xBF, 0xA3
+#else
+ /* These values make some of the overscan area visible */
+ 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F,
+ 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9C, 0x8E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3
+#endif
+ };
+
+ /* Override vgaHW's CRTC timings */
+ for (i = 0; i < 24; i++)
+ pvgaHW->ModeReg.CRTC[i] = CRTC[i];
+
+ /* Clobber any CLKDIV2 */
+ pvgaHW->ModeReg.Sequencer[1] = 0x01;
+ }
+#endif
+
+ /* Programme the registers */
+ vgaHWProtect(pScreenInfo, TRUE);
+ vgaHWRestore(pScreenInfo, &pvgaHW->ModeReg, VGA_SR_MODE | VGA_SR_CMAP);
+ vgaHWProtect(pScreenInfo, FALSE);
+
+ return TRUE;
+}
+
+
+static Bool
+GenericEnterGraphics(ScreenPtr pScreen, ScrnInfoPtr pScreenInfo)
+{
+ vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo);
+
+ /* Map VGA aperture */
+ if (!vgaHWMapMem(pScreenInfo))
+ return FALSE;
+
+ /* Unlock VGA registers */
+ vgaHWUnlock(pvgaHW);
+
+ /* Save the current state and setup the current mode */
+ GenericSave(pScreenInfo);
+ if (!GenericSetMode(pScreenInfo, pScreenInfo->currentMode))
+ return FALSE;
+
+ /* Possibly blank the screen */
+ if (pScreen)
+ GenericSaveScreen(pScreen, FALSE);
+
+ (*pScreenInfo->AdjustFrame)(pScreenInfo->scrnIndex,
+ pScreenInfo->frameX0, pScreenInfo->frameY0, 0);
+
+ return TRUE;
+}
+
+
+static void
+GenericLeaveGraphics(ScrnInfoPtr pScreenInfo)
+{
+ GenericRestore(pScreenInfo);
+ vgaHWLock(VGAHWPTR(pScreenInfo));
+ vgaHWUnmapMem(pScreenInfo);
+}
+
+
+/* Unravel the screen */
+static Bool
+GenericCloseScreen(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex];
+ GenericPtr pGenericPriv = GenericGetRec(pScreenInfo);
+ Bool Closed = TRUE;
+
+ if(pGenericPriv->ShadowPtr)
+ xfree(pGenericPriv->ShadowPtr);
+
+ if (pGenericPriv && (pScreen->CloseScreen = pGenericPriv->CloseScreen))
+ {
+ pGenericPriv->CloseScreen = NULL;
+ Closed = (*pScreen->CloseScreen)(scrnIndex, pScreen);
+ }
+
+ GenericLeaveGraphics(pScreenInfo);
+ pScreenInfo->vtSema = FALSE;
+
+ return Closed;
+}
+
+
+#ifdef DPMSExtension
+static void
+GenericDPMSSet(ScrnInfoPtr pScreen, int mode, int flags)
+{
+ vgaHWDPMSSet(pScreen, mode, flags);
+}
+#endif
+
+
+static void
+GenericRefreshArea1bpp(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ GenericPtr pPriv = GenericGetRec(pScrn);
+ vgaHWPtr pvgaHW = VGAHWPTR(pScrn);
+ int width, height, FBPitch, left, i, j, phase;
+ CARD8 *dst, *dstPtr, *src, *srcPtr;
+
+ FBPitch = pScrn->displayWidth >> 3;
+
+ while(num--) {
+ left = pbox->x1 & ~7;
+ width = ((pbox->x2 - left) + 7) >> 3;
+ height = pbox->y2 - pbox->y1;
+ src = pPriv->ShadowPtr + (pbox->y1 * pPriv->ShadowPitch) + (left >> 3);
+ dst = (CARD8*)pvgaHW->Base + (pbox->y1 * FBPitch) + (left >> 3);
+
+ if((phase = (long)dst & 3L)) {
+ phase = 4 - phase;
+ if(phase > width) phase = width;
+ width -= phase;
+ }
+
+ while(height--) {
+ dstPtr = dst;
+ srcPtr = src;
+ i = width;
+ j = phase;
+ while(j--)
+ *dstPtr++ = byte_reversed[*srcPtr++];
+ while(i >= 4) {
+ *((CARD32*)dstPtr) = byte_reversed[srcPtr[0]] |
+ (byte_reversed[srcPtr[1]] << 8) |
+ (byte_reversed[srcPtr[2]] << 16) |
+ (byte_reversed[srcPtr[3]] << 24);
+ srcPtr += 4;
+ dstPtr += 4;
+ i -= 4;
+ }
+ while(i--)
+ *dstPtr++ = byte_reversed[*srcPtr++];
+ dst += FBPitch;
+ src += pPriv->ShadowPitch;
+ }
+
+ pbox++;
+ }
+
+}
+
+static void
+GenericRefreshArea4bpp(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+{
+ GenericPtr pPriv = GenericGetRec(pScrn);
+ vgaHWPtr pvgaHW = VGAHWPTR(pScrn);
+ int width, height, FBPitch, left, i, j, SRCPitch, phase;
+ register CARD32 m;
+ CARD8 s1, s2, s3, s4;
+ CARD32 *src, *srcPtr;
+ CARD8 *dst, *dstPtr;
+
+ FBPitch = pScrn->displayWidth >> 3;
+ SRCPitch = pPriv->ShadowPitch >> 2;
+
+ pvgaHW->writeGr(pvgaHW, 0x05, 0x00);
+ pvgaHW->writeGr(pvgaHW, 0x01, 0x00);
+ pvgaHW->writeGr(pvgaHW, 0x08, 0xFF);
+
+ while(num--) {
+ left = pbox->x1 & ~7;
+ width = ((pbox->x2 - left) + 7) >> 3;
+ height = pbox->y2 - pbox->y1;
+ src = (CARD32*)pPriv->ShadowPtr + (pbox->y1 * SRCPitch) + (left >> 2);
+ dst = (CARD8*)pvgaHW->Base + (pbox->y1 * FBPitch) + (left >> 3);
+
+ if((phase = (long)dst & 3L)) {
+ phase = 4 - phase;
+ if(phase > width) phase = width;
+ width -= phase;
+ }
+
+ while(height--) {
+ pvgaHW->writeSeq(pvgaHW, 0x02, 1);
+ dstPtr = dst;
+ srcPtr = src;
+ i = width;
+ j = phase;
+ while(j--) {
+ m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4);
+ *dstPtr++ = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
+ srcPtr += 2;
+ }
+ while(i >= 4) {
+ m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4);
+ s1 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
+ m = (srcPtr[3] & 0x01010101) | ((srcPtr[2] & 0x01010101) << 4);
+ s2 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
+ m = (srcPtr[5] & 0x01010101) | ((srcPtr[4] & 0x01010101) << 4);
+ s3 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
+ m = (srcPtr[7] & 0x01010101) | ((srcPtr[6] & 0x01010101) << 4);
+ s4 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
+ *((CARD32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24);
+ srcPtr += 8;
+ dstPtr += 4;
+ i -= 4;
+ }
+ while(i--) {
+ m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4);
+ *dstPtr++ = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3);
+ srcPtr += 2;
+ }
+
+ pvgaHW->writeSeq(pvgaHW, 0x02, 1 << 1);
+ dstPtr = dst;
+ srcPtr = src;
+ i = width;
+ j = phase;
+ while(j--) {
+ m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4);
+ *dstPtr++ = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
+ srcPtr += 2;
+ }
+ while(i >= 4) {
+ m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4);
+ s1 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
+ m = (srcPtr[3] & 0x02020202) | ((srcPtr[2] & 0x02020202) << 4);
+ s2 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
+ m = (srcPtr[5] & 0x02020202) | ((srcPtr[4] & 0x02020202) << 4);
+ s3 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
+ m = (srcPtr[7] & 0x02020202) | ((srcPtr[6] & 0x02020202) << 4);
+ s4 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
+ *((CARD32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24);
+ srcPtr += 8;
+ dstPtr += 4;
+ i -= 4;
+ }
+ while(i--) {
+ m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4);
+ *dstPtr++ = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2);
+ srcPtr += 2;
+ }
+
+ pvgaHW->writeSeq(pvgaHW, 0x02, 1 << 2);
+ dstPtr = dst;
+ srcPtr = src;
+ i = width;
+ j = phase;
+ while(j--) {
+ m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4);
+ *dstPtr++ = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
+ srcPtr += 2;
+ }
+ while(i >= 4) {
+ m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4);
+ s1 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
+ m = (srcPtr[3] & 0x04040404) | ((srcPtr[2] & 0x04040404) << 4);
+ s2 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
+ m = (srcPtr[5] & 0x04040404) | ((srcPtr[4] & 0x04040404) << 4);
+ s3 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
+ m = (srcPtr[7] & 0x04040404) | ((srcPtr[6] & 0x04040404) << 4);
+ s4 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
+ *((CARD32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24);
+ srcPtr += 8;
+ dstPtr += 4;
+ i -= 4;
+ }
+ while(i--) {
+ m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4);
+ *dstPtr++ = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1);
+ srcPtr += 2;
+ }
+
+ pvgaHW->writeSeq(pvgaHW, 0x02, 1 << 3);
+ dstPtr = dst;
+ srcPtr = src;
+ i = width;
+ j = phase;
+ while(j--) {
+ m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4);
+ *dstPtr++ = (m >> 27) | (m >> 18) | (m >> 9) | m;
+ srcPtr += 2;
+ }
+ while(i >= 4) {
+ m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4);
+ s1 = (m >> 27) | (m >> 18) | (m >> 9) | m;
+ m = (srcPtr[3] & 0x08080808) | ((srcPtr[2] & 0x08080808) << 4);
+ s2 = (m >> 27) | (m >> 18) | (m >> 9) | m;
+ m = (srcPtr[5] & 0x08080808) | ((srcPtr[4] & 0x08080808) << 4);
+ s3 = (m >> 27) | (m >> 18) | (m >> 9) | m;
+ m = (srcPtr[7] & 0x08080808) | ((srcPtr[6] & 0x08080808) << 4);
+ s4 = (m >> 27) | (m >> 18) | (m >> 9) | m;
+ *((CARD32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24);
+ srcPtr += 8;
+ dstPtr += 4;
+ i -= 4;
+ }
+ while(i--) {
+ m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4);
+ *dstPtr++ = (m >> 27) | (m >> 18) | (m >> 9) | m;
+ srcPtr += 2;
+ }
+
+ dst += FBPitch;
+ src += SRCPitch;
+ }
+
+ pbox++;
+ }
+
+}
+
+static Bool
+GenericScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex];
+
+ vgaHWPtr pvgaHW;
+ GenericPtr pGenericPriv;
+ Bool Inited = FALSE;
+
+ /* Get driver private */
+ pGenericPriv = GenericGetRec(pScreenInfo);
+
+
+ /* Initialise graphics mode */
+ if (!GenericEnterGraphics(pScreen, pScreenInfo))
+ return FALSE;
+
+ /* Get vgahw private */
+ pvgaHW = VGAHWPTR(pScreenInfo);
+
+ miClearVisualTypes();
+
+ if (!miSetVisualTypes(pScreenInfo->depth,
+ miGetDefaultVisualMask(pScreenInfo->depth),
+ pScreenInfo->rgbBits, pScreenInfo->defaultVisual))
+ return FALSE;
+
+ /* Initialise the framebuffer */
+ switch (pScreenInfo->depth)
+ {
+ case 1:
+ if (pGenericPriv->ShadowFB) {
+ pGenericPriv->ShadowPitch =
+ ((pScreenInfo->virtualX + 31) >> 3) & ~3L;
+ pGenericPriv->ShadowPtr = xalloc(pGenericPriv->ShadowPitch *
+ pScreenInfo->virtualY);
+ if(pGenericPriv->ShadowPtr == NULL)
+ return FALSE;
+ Inited = mfbScreenInit(pScreen, pGenericPriv->ShadowPtr,
+ pScreenInfo->virtualX,
+ pScreenInfo->virtualY,
+ pScreenInfo->xDpi, pScreenInfo->yDpi,
+ pScreenInfo->displayWidth);
+ ShadowFBInit(pScreen, GenericRefreshArea1bpp);
+ } else {
+ Inited = xf1bppScreenInit(pScreen, pvgaHW->Base,
+ pScreenInfo->virtualX,
+ pScreenInfo->virtualY,
+ pScreenInfo->xDpi, pScreenInfo->yDpi,
+ pScreenInfo->displayWidth);
+ }
+ break;
+ case 4:
+ if (pGenericPriv->ShadowFB) {
+ /* in order to use ShadowFB we do depth 4 / bpp 8 */
+ pScreenInfo->bitsPerPixel = 8;
+ pGenericPriv->ShadowPitch = (pScreenInfo->virtualX + 3) & ~3L;
+ pGenericPriv->ShadowPtr = xalloc(pGenericPriv->ShadowPitch *
+ pScreenInfo->virtualY);
+ if(pGenericPriv->ShadowPtr == NULL)
+ return FALSE;
+ Inited = cfbScreenInit(pScreen, pGenericPriv->ShadowPtr,
+ pScreenInfo->virtualX,
+ pScreenInfo->virtualY,
+ pScreenInfo->xDpi, pScreenInfo->yDpi,
+ pScreenInfo->displayWidth);
+ ShadowFBInit(pScreen, GenericRefreshArea4bpp);
+ } else {
+ Inited = xf4bppScreenInit(pScreen, pvgaHW->Base,
+ pScreenInfo->virtualX,
+ pScreenInfo->virtualY,
+ pScreenInfo->xDpi, pScreenInfo->yDpi,
+ pScreenInfo->displayWidth);
+ }
+ break;
+ case 8:
+ Inited = cfbScreenInit(pScreen, pvgaHW->Base,
+ pScreenInfo->virtualX, pScreenInfo->virtualY,
+ pScreenInfo->xDpi, pScreenInfo->yDpi,
+ pScreenInfo->displayWidth);
+ break;
+ }
+
+ if (!Inited)
+ return FALSE;
+
+ miInitializeBackingStore(pScreen);
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ /* Initialise cursor */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ /* Setup default colourmap */
+ Inited = miCreateDefColormap(pScreen);
+
+ /* Try the new code based on the new colormap layer */
+ if (pScreenInfo->depth > 1)
+ vgaHWHandleColormaps(pScreen);
+
+#ifdef DPMSExtension
+ xf86DPMSInit(pScreen, GenericDPMSSet, 0);
+#endif
+
+ /* Wrap the screen's CloseScreen vector and set its SaveScreen vector */
+ pGenericPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = GenericCloseScreen;
+ pScreen->SaveScreen = GenericSaveScreen;
+
+ if (!Inited)
+ GenericCloseScreen(scrnIndex, pScreen);
+
+ pScreenInfo->racIoFlags = RAC_COLORMAP | RAC_VIEWPORT;
+ if (pScreenInfo->depth < 8)
+ pScreenInfo->racIoFlags |= RAC_FB;
+ pScreenInfo->racMemFlags = RAC_FB;
+ if (serverGeneration == 1)
+ xf86ShowUnusedOptions(pScreenInfo->scrnIndex, pScreenInfo->options);
+
+ return Inited;
+}
+
+
+static Bool
+GenericSwitchMode(int scrnIndex, DisplayModePtr pMode, int flags)
+{
+ return GenericSetMode(xf86Screens[scrnIndex], pMode);
+}
+
+
+static void
+GenericAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+# ifndef PC98_EGC
+ ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex];
+ vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo);
+ int Base = (y * pScreenInfo->displayWidth + x) >> 3;
+
+ outw(pvgaHW->IOBase + 4, (Base & 0x00FF00) | 0x0C);
+ outw(pvgaHW->IOBase + 4, ((Base & 0x0000FF) << 8) | 0x0D);
+# endif
+}
+
+
+static Bool
+GenericEnterVT(int scrnIndex, int flags)
+{
+ return GenericEnterGraphics(NULL, xf86Screens[scrnIndex]);
+}
+
+
+static void
+GenericLeaveVT(int scrnIndex, int flags)
+{
+ GenericLeaveGraphics(xf86Screens[scrnIndex]);
+}
+
+
+static void
+GenericFreeScreen(int scrnIndex, int flags)
+{
+ GenericFreeRec(xf86Screens[scrnIndex]);
+}
+
+
+static int
+GenericValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags)
+{
+ if (pMode->Flags & V_INTERLACE)
+ return MODE_NO_INTERLACE;
+
+ return MODE_OK;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/vga/vga.cpp b/xc/programs/Xserver/hw/xfree86/drivers/vga/vga.cpp
new file mode 100644
index 000000000..7eb5749cc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/drivers/vga/vga.cpp
@@ -0,0 +1,66 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vga/vga.cpp,v 1.2 1999/08/28 09:01:08 dawes Exp $
+.TH VGA __drivermansuffix__ "Version 3.9.16" "XFree86"
+.SH NAME
+vga \- Generic VGA video driver
+.SH SYNOPSIS
+.B "Section ""Device"""
+.br
+.BI " Identifier """ devname """"
+.br
+.B " Driver ""vga"""
+.br
+\ \ ...
+.br
+.B EndSection
+.SH DESCRIPTION
+.B vga
+is an XFree86 driver for generic VGA video cards. It can drive most
+VGA-compatible video cards, but only makes use of the basic standard
+VGA core that is common to these cards. The driver supports depths 1, 4
+and 8. All relevant visual types are supported at each depth.
+Multi-head configurations
+are supported in combination with some other drivers, but only when the
+.B vga
+driver is driving the primary head.
+.SH SUPPORTED HARDWARE
+The
+.B vga
+driver supports most VGA-compatible video cards. There are some known
+exceptions, and those should be listed here.
+.SH CONFIGURATION DETAILS
+Please refer to XF86Config(__filemansuffix__) for general configuration
+details. This section only covers configuration details specific to this
+driver.
+.PP
+The driver auto-detects the presence of VGA-compatible hardware. The
+.B ChipSet
+name may optionally be specified in the config file
+.B """Device"""
+section, and will override the auto-detection:
+.PP
+.RS 4
+"generic"
+.RE
+.PP
+The driver will only use 64k of video memory for depth 1 and depth 8 operation,
+and 256k of video memory for depth 4 (this is the standard VGA limit).
+.PP
+When operating at depth 8, only a single built-in 320x200 video mode is
+available. At other depths there is more flexibility regarding mode choice.
+.PP
+The following driver
+.B Options
+are supported:
+.TP
+.BI "Option ""ShadowFB"" """ boolean """
+Enable or disable use of the shadow framebuffer layer. See
+shadowfb(__drivermansuffix__) for further information. Default: off.
+
+This option is recommended for performance reasons when running at depths
+1 and 4, especially when using modern PCI-based hardware. It is required
+when using those depths in a multi-head configuration where one or more
+of the other screens is operating at a different depth.
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(1)
+.SH AUTHORS
+Authors include: Marc La France, David Dawes, and Dirk Hohndel.
diff --git a/xc/programs/Xserver/hw/xfree86/etc/2key.c b/xc/programs/Xserver/hw/xfree86/etc/2key.c
new file mode 100644
index 000000000..6c5d27796
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/2key.c
@@ -0,0 +1,52 @@
+/*
+ * $XFree86: xc/programs/Xserver/hw/xfree86/etc/2key.c,v 3.5 1999/05/07 02:56:17 dawes Exp $
+ *
+ * Enable/disable the 2-key VT switching sequences for Esix SVR4
+ * Note that is program *only* works for Esix SVR4. To use this program
+ * to turn off the 2-key switching for the VT the X server is running on,
+ * add the line 'VTInit "2key off"' to your XF86Config file.
+ *
+ * Usage:
+ * 2key on|off
+ *
+ * David Dawes <dawes@xfree86.org> October 1992
+ *
+ */
+/* $XConsortium: 2key.c /main/3 1996/02/21 17:47:02 kaleb $ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/kd.h>
+
+extern int errno;
+
+main(argc, argv)
+
+int argc;
+char *argv[];
+
+{
+ if (argc == 2)
+ {
+ if (!strcmp(argv[1], "on"))
+ {
+ if (ioctl(0, KDENA2KEYSW) < 0)
+ {
+ fprintf(stderr, "%s: KDENA2KEYSW error (errno=%d)\n", argv[0], errno);
+ exit(1);
+ }
+ exit(0);
+ }
+ if (!strcmp(argv[1], "off"))
+ {
+ if (ioctl(0, KDDIS2KEYSW) < 0)
+ {
+ fprintf(stderr, "%s: KDDIS2KEYSW error (errno=%d)r\n", argv[0], errno);
+ exit(1);
+ }
+ exit(0);
+ }
+ }
+ fprintf(stderr, "usage: %s on|off\n", argv[0]);
+ exit(2);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/etc/BM-Lynx.shar b/xc/programs/Xserver/hw/xfree86/etc/BM-Lynx.shar
new file mode 100644
index 000000000..5a792dce9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/BM-Lynx.shar
@@ -0,0 +1,2255 @@
+#!/bin/bash
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/BM-Lynx.shar,v 3.4 1997/06/03 14:12:27 hohndel Exp $
+# This is a shell archive (produced by GNU sharutils 4.1).
+# To extract the files from this archive, save it to some FILE, remove
+# everything before the `!/bin/bash' line above, then type `bash FILE'.
+#
+# Made on 1996-07-16 11:54 MET DST by <tm@systrix.de>.
+# Source directory was `/export/home/tm/MICE'.
+#
+# Existing files will *not* be overwritten unless `-c' is specified.
+#
+# $XConsortium: BM-Lynx.shar /main/5 1996/10/19 18:04:56 kaleb $
+#
+# This shar contains:
+# length mode name
+# ------ ---------- ------------------------------------------
+# 2459 -rw-r--r-- README.Mouse
+# 4329 -rw-r--r-- usr/include/busmouse.h
+# 751 -rw-r--r-- sys/devices/bmouseinfo.c
+# 145 -rw-r--r-- sys/dheaders/bmouseinfo.h
+# 759 -rw-r--r-- sys/drivers/bmouse/Makefile
+# 5357 -rw-r--r-- sys/drivers/bmouse/atixlmouse.c
+# 2908 -rw-r----- sys/drivers/bmouse/bmouse.h
+# 2135 -rw-r--r-- sys/drivers/bmouse/inline.h
+# 6236 -rw-r--r-- sys/drivers/bmouse/logibmouse.c
+# 3222 -rw-r--r-- sys/drivers/bmouse/mouse.c
+# 6202 -rw-r--r-- sys/drivers/bmouse/msbmouse.c
+# 8843 -rw-r--r-- sys/drivers/bmouse/ps2mouse.c
+# 244 -rw-r--r-- sys/lynx.os/bmouse.cfg
+#
+touch -am 1231235999 $$.touch >/dev/null 2>&1
+if test ! -f 1231235999 && test -f $$.touch; then
+ shar_touch=touch
+else
+ shar_touch=:
+ echo
+ echo 'WARNING: not restoring timestamps. Consider getting and'
+ echo "installing GNU \`touch', distributed in GNU File Utilities..."
+ echo
+fi
+rm -f 1231235999 $$.touch
+#
+# ============= README.Mouse ==============
+if test -f 'README.Mouse' && test X"$1" != X"-c"; then
+ echo 'x - skipping README.Mouse (file already exists)'
+else
+ echo 'x - extracting README.Mouse (text)'
+ sed 's/^X//' << 'SHAR_EOF' > 'README.Mouse' &&
+PS/2 and Bus mouse driver for LynxOS AT
+=======================================
+X
+This package includes LynxOS AT device drivers for PC pointing devices
+which are not connected to the serial port. These include devices
+connected to the PC's auxiliary keyboard port (aka PS/2 mouse) and
+others ususally connected to a separate ISA adapter board (so called
+Bus mice).
+X
+The drivers are a port from Linux and were developed and tested using
+X
+X - LynxOS AT V2.2, V2.2.1, V2.3, V2.4 and V2.5
+X - several Notebook computers with PS/2 mouse interface
+X - Microsoft Inport Mouse
+X - ATI Graphics Vantage graphics card with ATI mouse port
+X
+- Package Installation
+X
+1. As super-user (root) unpack the tar file (or the shar archive for XFree86)
+X
+X # cd /
+X # tar xvf BMOUSE.tar
+X
+2. Edit /sys/devices/bmouseinfo.c according tou your hardware. If you
+X don't have a PS/2 mouse port you must uncomment the
+X
+X /*
+X * #define DONT_HAVE_PS2
+X */
+X
+X macro definition (this is because a PS/2 mouse port cannot be
+X probed at startup time). You may also have to edit the
+X initialization of the mouseinfo array according to the I/O port and
+X IRQ used by your mouse adapter card. Bus mice usually use either
+X I/O port 0x23c or 0x238, PS/2 devices always use I/O port 0x60. The
+X IRQ number is usually configured by jumpers or by MS-DOS software
+X for Bus mice, PS/2 mice usually use IRQ 12.
+X
+3. Compile bmouseinfo.o
+X
+X # cd /sys/devices
+X # make bmouseinfo.o
+X On LynxOS versions earlier than 2.5.0:
+X # libr rv /sys/devlib.a bmouseinfo.o
+X Others:
+X # ar rv /sys/lib/devices.a bmouseinfo.o
+X # ranlib /sys/lib/devices.a
+X
+4. Compile driver
+X
+X # cd /sys/drivers/bmouse
+X On LynxOS versions earlier than 2.5.0:
+X # make install-2.4.0
+X Others:
+X # make install
+X
+5. Generate new kernel
+X
+X Edit /sys/lynx.os/CONFIG.TBL to include the Bus mouse driver. Add a
+X line containing
+X
+X I:bmouse.cfg
+X
+X to the end of the CONFIG.TBL file. You may now generate and install
+X a new kernel and reboot the machine using
+X
+X # cd /sys/lynx.os
+X On LynxOS versions after 2.4.0:
+X # mv bmouse.cfg ../cfg
+X
+X # make install
+X # reboot -N
+X
+6. Test Mouse driver
+X
+X After the system rebooted you may test the driver using one of the
+X following commands:
+X
+X # od -x /dev/bmouseps2 for a PS/2 mouse
+X # od -x /dev/bmousems for a Microsoft Inport Bus mouse
+X # od -x /dev/bmouseatixl for a ATI/XL bus mouse
+X # od -x /dev/bmousemslogitec for a Logitec bus mouse
+X
+SHAR_EOF
+ $shar_touch -am 0716115396 'README.Mouse' &&
+ chmod 0644 'README.Mouse' ||
+ echo 'restore of README.Mouse failed'
+ shar_count="`wc -c < 'README.Mouse'`"
+ test 2459 -eq "$shar_count" ||
+ echo "README.Mouse: original size 2459, current size $shar_count"
+fi
+# ============= usr/include/busmouse.h ==============
+if test ! -d 'usr'; then
+ echo 'x - creating directory usr'
+ mkdir 'usr'
+fi
+if test ! -d 'usr/include'; then
+ echo 'x - creating directory usr/include'
+ mkdir 'usr/include'
+fi
+if test -f 'usr/include/busmouse.h' && test X"$1" != X"-c"; then
+ echo 'x - skipping usr/include/busmouse.h (file already exists)'
+else
+ echo 'x - extracting usr/include/busmouse.h (text)'
+ sed 's/^X//' << 'SHAR_EOF' > 'usr/include/busmouse.h' &&
+#ifndef _LINUX_BUSMOUSE_H
+#define _LINUX_BUSMOUSE_H
+X
+/*
+X * linux/include/linux/mouse.h: header file for Logitech Bus Mouse driver
+X * by James Banks
+X *
+X * based on information gleamed from various mouse drivers on the net
+X *
+X * Heavily modified by David giller (rafetmad@oxy.edu)
+X *
+X * Minor modifications for Linux 0.96c-pl1 by Nathan Laredo
+X * gt7080a@prism.gatech.edu (13JUL92)
+X *
+X * Microsoft BusMouse support by Teemu Rantanen (tvr@cs.hut.fi) (02AUG92)
+X *
+X * Microsoft Bus Mouse support modified by Derrick Cole (cole@concert.net)
+X * 8/28/92
+X *
+X * Microsoft Bus Mouse support folded into 0.97pl4 code
+X * by Peter Cervasio (pete%q106fm.uucp@wupost.wustl.edu) (08SEP92)
+X * Changes: Logitech and Microsoft support in the same kernel.
+X * Defined new constants in busmouse.h for MS mice.
+X * Added int mse_busmouse_type to distinguish busmouse types
+X * Added a couple of new functions to handle differences in using
+X * MS vs. Logitech (where the int variable wasn't appropriate).
+X *
+X */
+X
+#define MOUSE_IRQ 5
+#define LOGITECH_BUSMOUSE 0 /* Minor device # for Logitech */
+#define MICROSOFT_BUSMOUSE 2 /* Minor device # for Microsoft */
+X
+/*--------- LOGITECH BUSMOUSE ITEMS -------------*/
+X
+#define MSE_DATA_PORT(p) (p)
+#define MSE_SIGNATURE_PORT(p) (p+1)
+#define MSE_CONTROL_PORT(p) (p+2)
+#define MSE_INTERRUPT_PORT(p) (p+2)
+#define MSE_CONFIG_PORT(p) (p+3)
+X
+#define MSE_ENABLE_INTERRUPTS 0x00
+#define MSE_DISABLE_INTERRUPTS 0x10
+X
+#define MSE_READ_X_LOW 0x80
+#define MSE_READ_X_HIGH 0xa0
+#define MSE_READ_Y_LOW 0xc0
+#define MSE_READ_Y_HIGH 0xe0
+X
+/* Magic number used to check if the mouse exists */
+#define MSE_CONFIG_BYTE 0x91
+#define MSE_DEFAULT_MODE 0x90
+#define MSE_SIGNATURE_BYTE 0xa5
+X
+/* useful Logitech Mouse macros */
+X
+#define MSE_INT_OFF(p) outb(MSE_DISABLE_INTERRUPTS, MSE_CONTROL_PORT(p))
+#define MSE_INT_ON(p) outb(MSE_ENABLE_INTERRUPTS, MSE_CONTROL_PORT(p))
+X
+/*--------- MICROSOFT BUSMOUSE ITEMS -------------*/
+X
+#define MS_MSE_CONTROL_PORT(p) (p)
+#define MS_MSE_DATA_PORT(p) (p+1)
+#define MS_MSE_SIGNATURE_PORT(p) (p+2)
+#define MS_MSE_CONFIG_PORT (p+3)
+X
+#define MS_MSE_ENABLE_INTERRUPTS 0x11
+#define MS_MSE_DISABLE_INTERRUPTS 0x10
+X
+#define MS_MSE_READ_BUTTONS 0x00
+#define MS_MSE_READ_X 0x01
+#define MS_MSE_READ_Y 0x02
+X
+#define MS_MSE_START 0x80
+#define MS_MSE_COMMAND_MODE 0x07
+X
+/* useful microsoft busmouse macros */
+X
+#define MS_MSE_INT_OFF(p) {outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT(p)); \
+X outb(MS_MSE_DISABLE_INTERRUPTS, MS_MSE_DATA_PORT(p));}
+#define MS_MSE_INT_ON(p) {outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT(p)); \
+X outb(MS_MSE_ENABLE_INTERRUPTS, MS_MSE_DATA_PORT(p));}
+X
+/*--------- ATI/XL BUSMOUSE ITEMS -------------*/
+X
+#define ATIXL_MSE_DATA_PORT(p) (p+1)
+#define ATIXL_MSE_SIGNATURE_PORT(p) (p+2)
+#define ATIXL_MSE_CONTROL_PORT(p) (p)
+X
+#define ATIXL_MSE_READ_BUTTONS 0x00
+#define ATIXL_MSE_READ_X 0x01
+#define ATIXL_MSE_READ_Y 0x02
+X
+/* Some nice ATI XL macros */
+X
+/* Select IR7, HOLD UPDATES (INT ENABLED), save X,Y */
+#define ATIXL_MSE_DISABLE_UPDATE(p) { outb( 0x07, ATIXL_MSE_CONTROL_PORT(p) ); \
+X outb( (0x20 | inb( ATIXL_MSE_DATA_PORT(p) )), ATIXL_MSE_DATA_PORT(p) ); }
+X
+/* Select IR7, Enable updates (INT ENABLED) */
+#define ATIXL_MSE_ENABLE_UPDATE(p) { outb( 0x07, ATIXL_MSE_CONTROL_PORT(p) ); \
+X outb( (0xdf & inb( ATIXL_MSE_DATA_PORT(p) )), ATIXL_MSE_DATA_PORT(p) ); }
+X
+/* Select IR7 - Mode Register, NO INTERRUPTS */
+#define ATIXL_MSE_INT_OFF(p) { outb( 0x07, ATIXL_MSE_CONTROL_PORT(p) ); \
+X outb( (0xe7 & inb( ATIXL_MSE_DATA_PORT(p) )), ATIXL_MSE_DATA_PORT(p) ); }
+X
+/* Select IR7 - Mode Register, DATA INTERRUPTS ENABLED */
+#define ATIXL_MSE_INT_ON(p) { outb( 0x07, ATIXL_MSE_CONTROL_PORT(p) ); \
+X outb( (0x08 | inb( ATIXL_MSE_DATA_PORT(p) )), ATIXL_MSE_DATA_PORT(p) ); }
+X
+X
+struct mouse_status
+{
+X unsigned char buttons;
+X unsigned char latch_buttons;
+X int dx;
+X int dy;
+X int present;
+X int ready;
+X int active;
+#ifdef Lynx
+X int wait;
+#else
+X struct wait_queue *wait;
+#endif
+};
+X
+/* Function Prototypes */
+#ifdef __STDC__
+extern long mouse_init(long);
+#else
+extern long mouse_init();
+#endif
+X
+#define BUSMOUSE_MINOR 0
+#define PS2MOUSE_MINOR 1
+#define MSMOUSE_MINOR 2
+#define ATIMOUSE_MINOR 3
+X
+#define NUM_MICE 4
+X
+#endif
+X
+SHAR_EOF
+ $shar_touch -am 0623101295 'usr/include/busmouse.h' &&
+ chmod 0644 'usr/include/busmouse.h' ||
+ echo 'restore of usr/include/busmouse.h failed'
+ shar_count="`wc -c < 'usr/include/busmouse.h'`"
+ test 4329 -eq "$shar_count" ||
+ echo "usr/include/busmouse.h: original size 4329, current size $shar_count"
+fi
+# ============= sys/devices/bmouseinfo.c ==============
+if test ! -d 'sys'; then
+ echo 'x - creating directory sys'
+ mkdir 'sys'
+fi
+if test ! -d 'sys/devices'; then
+ echo 'x - creating directory sys/devices'
+ mkdir 'sys/devices'
+fi
+if test -f 'sys/devices/bmouseinfo.c' && test X"$1" != X"-c"; then
+ echo 'x - skipping sys/devices/bmouseinfo.c (file already exists)'
+else
+ echo 'x - extracting sys/devices/bmouseinfo.c (text)'
+ sed 's/^X//' << 'SHAR_EOF' > 'sys/devices/bmouseinfo.c' &&
+#include <busmouse.h>
+X
+#ifdef DLDD
+#include "bmouseinfo.h"
+#else
+#include "../dheaders/bmouseinfo.h"
+#endif
+X
+/* 1. all devices but PS/2 are probed automatically
+X * 2. resource definitions must match hardware settings
+X * primary setting usually I/O 0x23c
+X * secondary setting usually I/O 0x238
+X * 3. PS/2 (aux) device cannot be probed, if you do
+X * not have such a device uncomment the
+X * #define DONT_HAVE_PS2 below
+X */
+X
+/*
+X * #define DONT_HAVE_PS2
+X */
+X
+struct mouseinfo mouseinfo[NUM_MICE] =
+{
+X { 32 + 9, 0x23c }, /* LOGITECH bus mouse */
+#ifdef DONT_HAVE_PS2
+X { 0, 0 }, /* PS/2 mouse */
+#else
+X { 32 + 12, 0x60 }, /* PS/2 mouse */
+#endif
+X { 32 + 9, 0x23c }, /* MICROSOFT bus mouse */
+X { 32 + 9, 0x23c }, /* ATI/XL inport */
+};
+SHAR_EOF
+ $shar_touch -am 0711152595 'sys/devices/bmouseinfo.c' &&
+ chmod 0644 'sys/devices/bmouseinfo.c' ||
+ echo 'restore of sys/devices/bmouseinfo.c failed'
+ shar_count="`wc -c < 'sys/devices/bmouseinfo.c'`"
+ test 751 -eq "$shar_count" ||
+ echo "sys/devices/bmouseinfo.c: original size 751, current size $shar_count"
+fi
+# ============= sys/dheaders/bmouseinfo.h ==============
+if test ! -d 'sys/dheaders'; then
+ echo 'x - creating directory sys/dheaders'
+ mkdir 'sys/dheaders'
+fi
+if test -f 'sys/dheaders/bmouseinfo.h' && test X"$1" != X"-c"; then
+ echo 'x - skipping sys/dheaders/bmouseinfo.h (file already exists)'
+else
+ echo 'x - extracting sys/dheaders/bmouseinfo.h (text)'
+ sed 's/^X//' << 'SHAR_EOF' > 'sys/dheaders/bmouseinfo.h' &&
+#ifndef _mouseinfo_h
+#define _mouseinfo_h
+X
+/* generic info structure for mouse drivers */
+X
+struct mouseinfo
+{
+X int vector;
+X int port;
+};
+X
+#endif
+SHAR_EOF
+ $shar_touch -am 0623101295 'sys/dheaders/bmouseinfo.h' &&
+ chmod 0644 'sys/dheaders/bmouseinfo.h' ||
+ echo 'restore of sys/dheaders/bmouseinfo.h failed'
+ shar_count="`wc -c < 'sys/dheaders/bmouseinfo.h'`"
+ test 145 -eq "$shar_count" ||
+ echo "sys/dheaders/bmouseinfo.h: original size 145, current size $shar_count"
+fi
+# ============= sys/drivers/bmouse/Makefile ==============
+if test ! -d 'sys/drivers'; then
+ echo 'x - creating directory sys/drivers'
+ mkdir 'sys/drivers'
+fi
+if test ! -d 'sys/drivers/bmouse'; then
+ echo 'x - creating directory sys/drivers/bmouse'
+ mkdir 'sys/drivers/bmouse'
+fi
+if test -f 'sys/drivers/bmouse/Makefile' && test X"$1" != X"-c"; then
+ echo 'x - skipping sys/drivers/bmouse/Makefile (file already exists)'
+else
+ echo 'x - extracting sys/drivers/bmouse/Makefile (text)'
+ sed 's/^X//' << 'SHAR_EOF' > 'sys/drivers/bmouse/Makefile' &&
+#
+# Makefile for bmouse driver
+#
+X
+CC=/bin/gcc
+CFLAGS=-O -I.
+X
+DRIVERS=mouse.o msbmouse.o logibmouse.o atixlmouse.o ps2mouse.o
+X
+all : mousedrvr.o
+X
+clean :
+X rm -f *.o *~ *.bak core
+X
+mousedrvr.o : $(DRIVERS)
+X /bin/ld -r -o mousedrvr.o $(DRIVERS)
+X
+install-2.4.0: mousedrvr.o
+X libr rv ../../drivlib.a mousedrvr.o
+X
+install: mousedrvr.o
+X ar rv ../../lib/drivers.a mousedrvr.o
+X ranlib ../../lib/drivers.a
+X
+depend :
+X makedepend *.c
+X
+ps2mouse.o :
+X if [ "`uname -r`" = "2.4.0" ]; then \
+X make _ps2mouse.o NEW_GCC=/cygnus/94q4-lynxos-x86/bin/gcc; \
+X else \
+X make _ps2mouse.o NEW_GCC=/bin/gcc; \
+X fi; \
+X ln -s _ps2mouse.o ps2mouse.o
+X
+_ps2mouse.o : ps2mouse.c
+X $(NEW_GCC) -c $(CFLAGS) ps2mouse.c -o _ps2mouse.o
+X
+X
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+SHAR_EOF
+ $shar_touch -am 0716115396 'sys/drivers/bmouse/Makefile' &&
+ chmod 0644 'sys/drivers/bmouse/Makefile' ||
+ echo 'restore of sys/drivers/bmouse/Makefile failed'
+ shar_count="`wc -c < 'sys/drivers/bmouse/Makefile'`"
+ test 759 -eq "$shar_count" ||
+ echo "sys/drivers/bmouse/Makefile: original size 759, current size $shar_count"
+fi
+# ============= sys/drivers/bmouse/atixlmouse.c ==============
+if test -f 'sys/drivers/bmouse/atixlmouse.c' && test X"$1" != X"-c"; then
+ echo 'x - skipping sys/drivers/bmouse/atixlmouse.c (file already exists)'
+else
+ echo 'x - extracting sys/drivers/bmouse/atixlmouse.c (text)'
+ sed 's/^X//' << 'SHAR_EOF' > 'sys/drivers/bmouse/atixlmouse.c' &&
+/* this LynxOS driver relies heavily on a Linux driver, see below
+X * for copyrights and credits.
+X *
+X * LynxOS work by:
+X *
+X * Thomas Mueller
+X * SYSTRIX CS GmbH, Hindenburgring 31, 89077 Ulm (Germany)
+X * tm@systrix.de, lynx@systrix.de
+X *
+X * September 1994
+X */
+X
+/*
+X * ATI XL Bus Mouse Driver for Linux
+X * by Bob Harris (rth@sparta.com)
+X *
+X * Uses VFS interface for linux 0.98 (01OCT92)
+X *
+X * Modified by Chris Colohan (colohan@eecg.toronto.edu)
+X *
+X * version 0.3
+X */
+X
+#include <conf.h>
+#include <kernel.h>
+#include <file.h>
+#include <errno.h>
+#include <signal.h>
+#include <io.h>
+#include "inline.h"
+X
+#include <busmouse.h>
+X
+#ifdef DLDD
+#include "bmouseinfo.h"
+#else
+#include "../../dheaders/bmouseinfo.h"
+#endif
+X
+struct stuff
+{
+X int port; /* i/o port address */
+X int vector; /* interrupt vector + 32 */
+X
+X int *sel_sem; /* select semaphore */
+X
+X struct mouse_status mouse; /* mouse/driver status */
+};
+X
+static void ati_mou_interrupt(s)
+struct stuff *s;
+{
+X char dx, dy;
+X unsigned char buttons;
+X
+X ATIXL_MSE_DISABLE_UPDATE(s->port);
+X /* Select IR1 - X movement */
+X outb(ATIXL_MSE_READ_X, ATIXL_MSE_CONTROL_PORT(s->port));
+X dx = inb(ATIXL_MSE_DATA_PORT(s->port));
+X /* Select IR2 - Y movement */
+X outb(ATIXL_MSE_READ_Y, ATIXL_MSE_CONTROL_PORT(s->port));
+X dy = inb(ATIXL_MSE_DATA_PORT(s->port));
+X /* Select IR0 - Button Status */
+X outb(ATIXL_MSE_READ_BUTTONS, ATIXL_MSE_CONTROL_PORT(s->port));
+X buttons = inb(ATIXL_MSE_DATA_PORT(s->port));
+X if (dx != 0 || dy != 0 || buttons != s->mouse.latch_buttons)
+X {
+X s->mouse.latch_buttons |= buttons;
+X s->mouse.dx += dx;
+X s->mouse.dy += dy;
+X s->mouse.ready = 1;
+X if (s->sel_sem)
+X ssignal(s->sel_sem);
+X ssignal(&s->mouse.wait);
+X }
+X ATIXL_MSE_ENABLE_UPDATE(s->port);
+}
+X
+static struct mouse_status *ati_mou_init(s)
+struct stuff *s;
+{
+X static struct mouse_status mouse;
+X unsigned char a,b,c;
+X
+X a = inb(ATIXL_MSE_SIGNATURE_PORT(s->port)); /* Get signature */
+X b = inb(ATIXL_MSE_SIGNATURE_PORT(s->port));
+X c = inb(ATIXL_MSE_SIGNATURE_PORT(s->port));
+X if (!(a != b && a == c))
+X {
+X mouse.present = 0;
+X return NULL;
+X }
+X /* Reset the Inport device */
+X outb(0x80, ATIXL_MSE_CONTROL_PORT(s->port));
+X /* Select Internal Register 7 */
+X outb(0x07, ATIXL_MSE_CONTROL_PORT(s->port));
+X /* Data Interrupts 8+, 1=30hz, 2=50hz, 3=100hz, 4=200hz rate */
+X outb(0x0a, ATIXL_MSE_DATA_PORT(s->port));
+X mouse.present = 1;
+X mouse.active = 0;
+X mouse.ready = 0;
+X mouse.buttons = mouse.latch_buttons = 0;
+X mouse.dx = mouse.dy = 0;
+X mouse.wait = 0;
+X return &mouse;
+}
+X
+static char *ati_mou_install(info)
+struct mouseinfo *info;
+{
+X extern char *sysbrk();
+X struct stuff *s;
+X struct mouse_status *mouse;
+X
+X s = (struct stuff *) sysbrk((long)sizeof(struct stuff));
+X if (!s)
+X {
+X pseterr(ENOMEM);
+X return (char *)SYSERR;
+X }
+X bzero(s, sizeof(struct stuff));
+X s->port = info->port;
+X s->vector = info->vector;
+X if ((mouse = ati_mou_init(s)) == NULL)
+X {
+X cprintf("ATI Inport Bus mouse *not* detected.\n");
+X pseterr(ENXIO);
+X return (char *) SYSERR;
+X }
+X s->mouse = *mouse;
+X cprintf("ATI Inport Bus mouse detected and installed.\n");
+X return (char *) s;
+}
+X
+static ati_mou_uninstall(s)
+struct stuff *s;
+{
+X sysfree(s, (long) sizeof(struct stuff));
+X return OK;
+}
+X
+static ati_mou_open(s, d, f)
+struct stuff *s;
+int d;
+struct file *f;
+{
+X if (s->mouse.present == 0)
+X {
+X pseterr(ENXIO);
+X return SYSERR;
+X }
+X if (s->mouse.active)
+X {
+X pseterr(EBUSY);
+X return SYSERR;
+X }
+X s->mouse.active = 1;
+X s->mouse.ready = s->mouse.dx = s->mouse.dy = 0;
+X s->mouse.buttons = s->mouse.latch_buttons = 0;
+X s->mouse.wait = 0;
+X iointset(s->vector, ati_mou_interrupt, s);
+X ATIXL_MSE_INT_ON(s->port);
+X return OK;
+}
+X
+static ati_mou_close(s, f)
+struct stuff *s;
+struct file *f;
+{
+X ATIXL_MSE_INT_OFF(s->port);
+X s->mouse.active = s->mouse.ready = 0;
+X iointclr(s->vector);
+X return OK;
+}
+X
+static ati_mou_select(s, f, which, ffs)
+struct stuff *s;
+struct file *f;
+struct sel *ffs;
+{
+X if (which == SREAD)
+X {
+X ffs->iosem = &s->mouse.wait;
+X ffs->sel_sem = &s->sel_sem;
+X }
+X return OK;
+}
+X
+static ati_mou_inval(s, f, buffer, count)
+struct stuff *s;
+struct file *f;
+char *buffer;
+{
+X pseterr(EINVAL);
+X return SYSERR;
+}
+X
+static ati_mou_read(s, f, buffer, count)
+struct stuff *s;
+struct file *f;
+char *buffer;
+{
+X int i, dx, dy;
+X
+X if (count < 3)
+X {
+X pseterr(EINVAL);
+X return SYSERR;
+X }
+X if (f->access_mode & FNDELAY)
+X {
+X if (!s->mouse.ready)
+X {
+X pseterr(EAGAIN);
+X return SYSERR;
+X }
+X }
+X else
+X swait(&s->mouse.wait, SEM_SIGABORT);
+X
+X ATIXL_MSE_DISABLE_UPDATE(s->port);
+X /* Allowed ints to occur during data gathering - shouldn't hurt */
+X buffer[0] = (~s->mouse.latch_buttons & 7) | 0x80;
+X if (s->mouse.dx < -127)
+X s->mouse.dx = -127;
+X if (s->mouse.dx > 127)
+X s->mouse.dx = 127;
+X buffer[1] = s->mouse.dx;
+X if (s->mouse.dy < -127)
+X s->mouse.dy = -127;
+X if (s->mouse.dy > 127)
+X s->mouse.dy = 127;
+X buffer[2] = s->mouse.dy;
+X bzero(buffer + 3, count - 3);
+X s->mouse.dx = 0;
+X s->mouse.dy = 0;
+X s->mouse.latch_buttons = s->mouse.buttons;
+X s->mouse.ready = 0;
+X s->mouse.wait = 0;
+X ATIXL_MSE_ENABLE_UPDATE(s->port);
+X
+X return count;
+}
+X
+#include <dldd.h>
+X
+static struct dldd entry_points =
+{
+X ati_mou_open, /* OPEN */
+X ati_mou_close, /* CLOSE */
+X ati_mou_read, /* READ */
+X ati_mou_inval, /* WRITE */
+X ati_mou_select, /* SELECT */
+X ati_mou_inval, /* IOCTL */
+X ati_mou_install, /* INSTALL */
+X ati_mou_uninstall, /* UNINSTALL */
+};
+X
+struct dldd *ati_entry_points = &entry_points;
+SHAR_EOF
+ $shar_touch -am 0623101295 'sys/drivers/bmouse/atixlmouse.c' &&
+ chmod 0644 'sys/drivers/bmouse/atixlmouse.c' ||
+ echo 'restore of sys/drivers/bmouse/atixlmouse.c failed'
+ shar_count="`wc -c < 'sys/drivers/bmouse/atixlmouse.c'`"
+ test 5357 -eq "$shar_count" ||
+ echo "sys/drivers/bmouse/atixlmouse.c: original size 5357, current size $shar_count"
+fi
+# ============= sys/drivers/bmouse/bmouse.h ==============
+if test -f 'sys/drivers/bmouse/bmouse.h' && test X"$1" != X"-c"; then
+ echo 'x - skipping sys/drivers/bmouse/bmouse.h (file already exists)'
+else
+ echo 'x - extracting sys/drivers/bmouse/bmouse.h (text)'
+ sed 's/^X//' << 'SHAR_EOF' > 'sys/drivers/bmouse/bmouse.h' &&
+/*
+X * Copyrighted as an unpublished work.
+X * (c) Copyright 1987 INTERACTIVE Systems Corporation
+X * All rights reserved.
+X *
+X * RESTRICTED RIGHTS
+X *
+X * These programs are supplied under a license. They may be used,
+X * disclosed, and/or copied only as permitted under such license
+X * agreement. Any copy must contain the above copyright notice and
+X * this restricted rights notice. Use, copying, and/or disclosure
+X * of the programs is strictly prohibited unless otherwise provided
+X * in the license agreement.
+X *
+X */
+X
+X
+/* Definitions for Microsoft Mouse */
+X
+/* Base I/O addresses for primary and secondary InPort */
+#define MOUSE1 0x23c
+#define MOUSE2 0x238
+X
+/* Offsets of I/O registers from base */
+#define ADDRREG 0 /* Address register */
+#define DATAREG 1 /* Data register */
+#define IDENTREG 2 /* Identification register */
+#define TESTREG 3 /* Test register */
+X
+/* Address register definitions */
+#define REGSEL 7 /* Mask for register select bits */
+#define MSTATUS 0 /* Select mouse status register */
+#define DATA1 1 /* Select data register 1 */
+#define DATA2 2 /* Select data register 2 */
+#define DATA3 3 /* Select data register 3 */
+#define DATA4 4 /* Select data register 4 */
+#define ISTATUS 5 /* Select interface status register */
+#define ICNTRL 6 /* Select interface control register */
+#define MODE 7 /* Select mode register */
+#define TESTEN 0x40 /* Enable test register */
+#define RESET 0x80 /* Reset InPort chip */
+X
+/* Identification register definitions */
+#define SIGN 0xde /* InPort chip signature */
+#define VERS(x) (((x)>>4)&15) /* InPort chip version number */
+#define REV(x) ((x)&15) /* InPort chip revision number */
+X
+/* Mouse status register definitions */
+#define BUTSTATMASK 7
+#define BUT3STAT 1
+#define BUT2STAT 2
+#define BUT1STAT 4
+#define BUTCHNGMASK 0x38
+#define BUT3CHNG 8
+#define BUT2CHNG 0x10
+#define BUT1CHNG 0x20
+#define MOVEMENT 0x40
+#define PACKETDONE 0x80
+X
+/* Interface status/control register definitions */
+#define SW3 1
+#define SW2 2
+#define SW1 4
+#define XA 0x10
+#define XB 0x20
+#define YA 0x40
+#define YB 0x80
+X
+/* Mode register definitions */
+#define RATEMASK 7
+#define HZ0NOINTR 0
+#define HZ30 1
+#define HZ50 2
+#define HZ100 3
+#define HZ200 4
+#define HZ0INTR 6
+#define HZEXT 7
+#define DATAINT 8
+#define TIMERINT 0x10
+#define HOLD 0x20
+#define MODEMASK 0xc0
+#define QUADMODE 0
+#define SYNCHMODE 0x40
+#define ASYNMODE 0x80
+#define DIRMODE 0xc0
+X
+struct mouseinfo
+{ unsigned char status;
+X char xmotion, ymotion;
+};
+X
+/* Ioctl definitions */
+#define MOUSEIOC ('M'<<8)
+#define MOUSEIOCREAD (MOUSEIOC|60)
+X
+SHAR_EOF
+ $shar_touch -am 0623101295 'sys/drivers/bmouse/bmouse.h' &&
+ chmod 0640 'sys/drivers/bmouse/bmouse.h' ||
+ echo 'restore of sys/drivers/bmouse/bmouse.h failed'
+ shar_count="`wc -c < 'sys/drivers/bmouse/bmouse.h'`"
+ test 2908 -eq "$shar_count" ||
+ echo "sys/drivers/bmouse/bmouse.h: original size 2908, current size $shar_count"
+fi
+# ============= sys/drivers/bmouse/inline.h ==============
+if test -f 'sys/drivers/bmouse/inline.h' && test X"$1" != X"-c"; then
+ echo 'x - skipping sys/drivers/bmouse/inline.h (file already exists)'
+else
+ echo 'x - extracting sys/drivers/bmouse/inline.h (text)'
+ sed 's/^X//' << 'SHAR_EOF' > 'sys/drivers/bmouse/inline.h' &&
+X
+#ifndef _COMPILER_H
+#define _COMPILER_H
+X
+#ifdef Lynx
+#define GCCUSESGAS
+#endif
+X
+#ifndef __STDC__
+# ifdef signed
+# undef signed
+# endif
+# ifdef volatile
+# undef volatile
+# endif
+# ifdef const
+# undef const
+# endif
+# define signed /**/
+# ifdef __GNUC__
+# define volatile __volatile__
+# define const __const__
+# else
+# define const /**/
+# endif /* __GNUC__ */
+#endif /* !__STDC__ */
+X
+X
+#ifdef __GNUC__
+X
+#ifdef GCCUSESGAS
+X
+/*
+X * If gcc uses gas rather than the native assembler, the syntax of these
+X * inlines has to be different. DHD
+X */
+X
+static __inline__ void
+outb(val, port)
+short port;
+char val;
+{
+X __asm__ __volatile__("outb %0,%1" : :"a" (val), "d" (port));
+}
+X
+X
+static __inline__ void
+outw(val, port)
+short port;
+short val;
+{
+X __asm__ __volatile__("outw %0,%1" : :"a" (val), "d" (port));
+}
+X
+static __inline__ unsigned int
+inb(port)
+short port;
+{
+X unsigned char ret;
+X __asm__ __volatile__("inb %1,%0" :
+X "=a" (ret) :
+X "d" (port));
+X return ret;
+}
+X
+static __inline__ unsigned int
+inw(port)
+short port;
+{
+X unsigned short ret;
+X __asm__ __volatile__("inw %1,%0" :
+X "=a" (ret) :
+X "d" (port));
+X return ret;
+}
+X
+#else /* GCCUSESGAS */
+X
+static __inline__ void
+outb(val, port)
+X short port;
+X char val;
+{
+X __asm__ __volatile__("out%B0 (%1)" : :"a" (val), "d" (port));
+}
+X
+static __inline__ void
+outw(val, port)
+X short port;
+X short val;
+{
+X __asm__ __volatile__("out%W0 (%1)" : :"a" (val), "d" (port));
+}
+X
+static __inline__ unsigned int
+inb(port)
+X short port;
+{
+X unsigned char ret;
+X __asm__ __volatile__("in%B0 (%1)" :
+X "=a" (ret) :
+X "d" (port));
+X return ret;
+}
+X
+static __inline__ unsigned int
+inw(port)
+X short port;
+{
+X unsigned short ret;
+X __asm__ __volatile__("in%W0 (%1)" :
+X "=a" (ret) :
+X "d" (port));
+X return ret;
+}
+X
+#endif /* GCCUSESGAS */
+X
+#else /* __GNUC__ */
+X
+/* what an idiocy, first param value, then port ?!?!?@?!@? */
+X
+static void outb(value, port)
+{
+X asm
+X {
+X mov EDX,port[EBP]
+X mov EAX,value[EBP]
+X out DX,AL
+X }
+}
+X
+static int inb(port)
+{
+X asm
+X {
+X mov EDX,port[EBP]
+X in AL,DX
+X and EAX,0xff
+X }
+}
+X
+#endif
+X
+#endif /* _COMPILER_H */
+X
+SHAR_EOF
+ $shar_touch -am 0623101295 'sys/drivers/bmouse/inline.h' &&
+ chmod 0644 'sys/drivers/bmouse/inline.h' ||
+ echo 'restore of sys/drivers/bmouse/inline.h failed'
+ shar_count="`wc -c < 'sys/drivers/bmouse/inline.h'`"
+ test 2135 -eq "$shar_count" ||
+ echo "sys/drivers/bmouse/inline.h: original size 2135, current size $shar_count"
+fi
+# ============= sys/drivers/bmouse/logibmouse.c ==============
+if test -f 'sys/drivers/bmouse/logibmouse.c' && test X"$1" != X"-c"; then
+ echo 'x - skipping sys/drivers/bmouse/logibmouse.c (file already exists)'
+else
+ echo 'x - extracting sys/drivers/bmouse/logibmouse.c (text)'
+ sed 's/^X//' << 'SHAR_EOF' > 'sys/drivers/bmouse/logibmouse.c' &&
+/* this LynxOS driver relies heavily on a Linux driver, see below
+X * for copyrights and credits.
+X *
+X * LynxOS work by:
+X *
+X * Thomas Mueller
+X * SYSTRIX CS GmbH, Hindenburgring 31, 89077 Ulm (Germany)
+X * tm@systrix.de, lynx@systrix.de
+X *
+X * September 1994
+X */
+X
+/*
+X * Logitech Bus Mouse Driver for Linux
+X * by James Banks
+X *
+X * Mods by Matthew Dillon
+X * calls verify_area()
+X * tracks better when X is busy or paging
+X *
+X * Heavily modified by David Giller
+X * changed from queue- to counter- driven
+X * hacked out a (probably incorrect) mouse_select
+X *
+X * Modified again by Nathan Laredo to interface with
+X * 0.96c-pl1 IRQ handling changes (13JUL92)
+X * didn't bother touching select code.
+X *
+X * Modified the select() code blindly to conform to the VFS
+X * requirements. 92.07.14 - Linus. Somebody should test it out.
+X *
+X * Modified by Johan Myreen to make room for other mice (9AUG92)
+X * removed assignment chr_fops[10] = &mouse_fops; see mouse.c
+X * renamed mouse_fops => bus_mouse_fops, made bus_mouse_fops public.
+X * renamed this file mouse.c => busmouse.c
+X */
+X
+#include <conf.h>
+#include <kernel.h>
+#include <file.h>
+#include <errno.h>
+#include <signal.h>
+#include <io.h>
+#include "inline.h"
+X
+#include <busmouse.h>
+X
+#ifdef DLDD
+#include "bmouseinfo.h"
+#else
+#include "../../dheaders/bmouseinfo.h"
+#endif
+X
+struct stuff
+{
+X int port; /* i/o port address */
+X int vector; /* interrupt vector + 32 */
+X
+X int *sel_sem; /* select semaphore */
+X
+X struct mouse_status mouse; /* mouse/driver status */
+};
+X
+static void logi_mou_interrupt(s)
+struct stuff *s;
+{
+X char dx, dy;
+X unsigned char buttons;
+X
+X MSE_INT_OFF(s->port);
+X outb(MSE_READ_X_LOW, MSE_CONTROL_PORT(s->port));
+X dx = (inb(MSE_DATA_PORT(s->port)) & 0xf);
+X outb(MSE_READ_X_HIGH, MSE_CONTROL_PORT(s->port));
+X dx |= (inb(MSE_DATA_PORT(s->port)) & 0xf) << 4;
+X outb(MSE_READ_Y_LOW, MSE_CONTROL_PORT(s->port));
+X dy = (inb(MSE_DATA_PORT(s->port)) & 0xf);
+X outb(MSE_READ_Y_HIGH, MSE_CONTROL_PORT(s->port));
+X buttons = inb(MSE_DATA_PORT(s->port));
+X dy |= (buttons & 0xf) << 4;
+X buttons = ((buttons >> 5) & 0x07);
+X if (dx != 0 || dy != 0 || buttons != s->mouse.buttons)
+X {
+X s->mouse.buttons = buttons;
+X s->mouse.dx += dx;
+X s->mouse.dy -= dy;
+X s->mouse.ready = 1;
+X
+X /*
+X * keep dx/dy reasonable, but still able to track when X (or
+X * whatever) must page or is busy (i.e. long waits between
+X * reads)
+X */
+X if (s->mouse.dx < -2048)
+X s->mouse.dx = -2048;
+X if (s->mouse.dx > 2048)
+X s->mouse.dx = 2048;
+X
+X if (s->mouse.dy < -2048)
+X s->mouse.dy = -2048;
+X if (s->mouse.dy > 2048)
+X s->mouse.dy = 2048;
+X
+X if (s->sel_sem)
+X ssignal(s->sel_sem);
+X ssignal(&s->mouse.wait);
+X }
+X MSE_INT_ON(s->port);
+}
+X
+static struct mouse_status *logi_mou_init(s)
+struct stuff *s;
+{
+X static struct mouse_status mouse;
+X int i;
+X
+X outb(MSE_CONFIG_BYTE, MSE_CONFIG_PORT(s->port));
+X outb(MSE_SIGNATURE_BYTE, MSE_SIGNATURE_PORT(s->port));
+X for (i = 0; i < 800000; i++)
+X /* busy loop */;
+X if (inb(MSE_SIGNATURE_PORT(s->port)) != MSE_SIGNATURE_BYTE)
+X {
+X mouse.present = 0;
+X return NULL;
+X }
+X outb(MSE_DEFAULT_MODE, MSE_CONFIG_PORT(s->port));
+X MSE_INT_OFF(s->port);
+X mouse.present = 1;
+X mouse.active = 0;
+X mouse.ready = 0;
+X mouse.buttons = 0x87;
+X mouse.dx = 0;
+X mouse.dy = 0;
+X mouse.wait = NULL;
+X return &mouse;
+}
+X
+static char *logi_mou_install(info)
+struct mouseinfo *info;
+{
+X extern char *sysbrk();
+X struct stuff *s;
+X struct mouse_status *mouse;
+X
+X s = (struct stuff *) sysbrk((long)sizeof(struct stuff));
+X if (!s)
+X {
+X pseterr(ENOMEM);
+X return (char *)SYSERR;
+X }
+X bzero(s, sizeof(struct stuff));
+X s->port = info->port;
+X s->vector = info->vector;
+X if ((mouse = logi_mou_init(s)) == NULL)
+X {
+X cprintf("Logitech Bus mouse *not* detected.\n");
+X pseterr(ENXIO);
+X return (char *) SYSERR;
+X }
+X s->mouse = *mouse;
+X cprintf("Logitech Bus mouse detected and installed.\n");
+X return (char *) s;
+}
+X
+static logi_mou_uninstall(s)
+struct stuff *s;
+{
+X sysfree(s, (long) sizeof(struct stuff));
+X return OK;
+}
+X
+static logi_mou_open(s, d, f)
+struct stuff *s;
+int d;
+struct file *f;
+{
+X if (s->mouse.present == 0)
+X {
+X pseterr(ENXIO);
+X return SYSERR;
+X }
+X if (s->mouse.active)
+X {
+X pseterr(EBUSY);
+X return SYSERR;
+X }
+X s->mouse.active = 1;
+X s->mouse.ready = s->mouse.dx = s->mouse.dy = 0;
+X s->mouse.buttons = 0x87;
+X s->mouse.wait = 0;
+X iointset(s->vector, logi_mou_interrupt, s);
+X MSE_INT_ON(s->port);
+X return OK;
+}
+X
+static logi_mou_close(s, f)
+struct stuff *s;
+struct file *f;
+{
+X MSE_INT_OFF(s->port);
+X s->mouse.active = s->mouse.ready = 0;
+X iointclr(s->vector);
+X return OK;
+}
+X
+static logi_mou_select(s, f, which, ffs)
+struct stuff *s;
+struct file *f;
+struct sel *ffs;
+{
+X if (which == SREAD)
+X {
+X ffs->iosem = &s->mouse.wait;
+X ffs->sel_sem = &s->sel_sem;
+X }
+X return OK;
+}
+X
+static logi_mou_inval(s, f, buffer, count)
+struct stuff *s;
+struct file *f;
+char *buffer;
+{
+X pseterr(EINVAL);
+X return SYSERR;
+}
+X
+static logi_mou_read(s, f, buffer, count)
+struct stuff *s;
+struct file *f;
+char *buffer;
+{
+X int i, dx, dy, buttons;
+X
+X if (count < 3)
+X {
+X pseterr(EINVAL);
+X return SYSERR;
+X }
+X if (f->access_mode & FNDELAY)
+X {
+X if (!s->mouse.ready)
+X {
+X pseterr(EAGAIN);
+X return SYSERR;
+X }
+X }
+X else
+X swait(&s->mouse.wait, SEM_SIGABORT);
+X
+X /*
+X * Obtain the current mouse parameters and limit as appropriate for
+X * the return data format. Interrupts are only disabled while
+X * obtaining the parameters, NOT during the puts_fs_byte() calls,
+X * so paging in put_fs_byte() does not effect mouse tracking.
+X */
+X
+X MSE_INT_OFF(s->port);
+X dx = s->mouse.dx;
+X dy = s->mouse.dy;
+X if (dx < -127)
+X dx = -127;
+X if (dx > 127)
+X dx = 127;
+X if (dy < -127)
+X dy = -127;
+X if (dy > 127)
+X dy = 127;
+X buttons = s->mouse.buttons;
+X s->mouse.dx -= dx;
+X s->mouse.dy -= dy;
+X s->mouse.ready = 0;
+X sreset(&s->mouse.wait);
+X MSE_INT_ON(s->port);
+X
+X buffer[0] = buttons | 0x80;
+X buffer[1] = dx;
+X buffer[2] = dy;
+X bzero(buffer + 3, count - 3);
+X return count;
+}
+X
+#include <dldd.h>
+X
+static struct dldd entry_points =
+{
+X logi_mou_open, /* OPEN */
+X logi_mou_close, /* CLOSE */
+X logi_mou_read, /* READ */
+X logi_mou_inval, /* WRITE */
+X logi_mou_select, /* SELECT */
+X logi_mou_inval, /* IOCTL */
+X logi_mou_install, /* INSTALL */
+X logi_mou_uninstall, /* UNINSTALL */
+};
+X
+struct dldd *logi_entry_points = &entry_points;
+SHAR_EOF
+ $shar_touch -am 0623101295 'sys/drivers/bmouse/logibmouse.c' &&
+ chmod 0644 'sys/drivers/bmouse/logibmouse.c' ||
+ echo 'restore of sys/drivers/bmouse/logibmouse.c failed'
+ shar_count="`wc -c < 'sys/drivers/bmouse/logibmouse.c'`"
+ test 6236 -eq "$shar_count" ||
+ echo "sys/drivers/bmouse/logibmouse.c: original size 6236, current size $shar_count"
+fi
+# ============= sys/drivers/bmouse/mouse.c ==============
+if test -f 'sys/drivers/bmouse/mouse.c' && test X"$1" != X"-c"; then
+ echo 'x - skipping sys/drivers/bmouse/mouse.c (file already exists)'
+else
+ echo 'x - extracting sys/drivers/bmouse/mouse.c (text)'
+ sed 's/^X//' << 'SHAR_EOF' > 'sys/drivers/bmouse/mouse.c' &&
+/* LynxOS bus and ps/2 mouse driver
+X * one driver for all pointer devices
+X *
+X * Thomas Mueller
+X * SYSTRIX CS GmbH, Hindenburgring 31, 89077 Ulm (Germany)
+X * tm@systrix.de, lynx@systrix.de
+X *
+X * September 1994
+X */
+X
+X
+#include <conf.h>
+#include <kernel.h>
+#include <file.h>
+#include <errno.h>
+#include <signal.h>
+#include <io.h>
+#include <dldd.h>
+X
+#include <busmouse.h>
+#ifdef DLDD
+#include "bmouseinfo.h"
+#else
+#include "../../dheaders/bmouseinfo.h"
+#endif
+X
+#define CHCK_MINOR(d) \
+X minor_dev = minor(d); \
+X if (minor_dev < 0 || minor_dev > NUM_MICE) \
+X { pseterr(ENXIO); return SYSERR; } \
+X else
+X
+extern struct dldd *ms_entry_points;
+extern struct dldd *ps2_entry_points;
+extern struct dldd *ati_entry_points;
+extern struct dldd *logi_entry_points;
+X
+struct stuff
+{
+X struct dldd *drv_funcs[NUM_MICE];
+X char *stuff_ptr[NUM_MICE];
+};
+X
+char *mou_install(info)
+struct mouseinfo *info; /* Array for 4 drivers */
+{
+X extern char *sysbrk();
+X struct stuff *s;
+X char *p;
+X int i;
+X int inited = 0;
+X
+X s = (struct stuff *) sysbrk((long)sizeof(struct stuff));
+X if (!s)
+X {
+X pseterr(ENOMEM);
+X return (char *)SYSERR;
+X }
+X bzero(s, sizeof(struct stuff));
+X
+X s->drv_funcs[BUSMOUSE_MINOR] = logi_entry_points;
+X s->drv_funcs[PS2MOUSE_MINOR] = ps2_entry_points;
+X s->drv_funcs[MSMOUSE_MINOR] = ms_entry_points;
+X s->drv_funcs[ATIMOUSE_MINOR] = ati_entry_points;
+X for (i = 0; i < NUM_MICE; i++)
+X {
+X p = (*s->drv_funcs[i]->dldd_install)(&info[i]);
+X if (p != (char *) SYSERR)
+X {
+X ++inited;
+X s->stuff_ptr[i] = p;
+X }
+X }
+X
+X return (char *) s;
+}
+X
+mou_uninstall(s)
+struct stuff *s;
+{
+X int i;
+X
+X for (i = 0; i < NUM_MICE; i++)
+X (*s->drv_funcs[i]->dldd_uninstall)(s->stuff_ptr[i]);
+X sysfree(s, (long) sizeof(struct stuff));
+X return OK;
+}
+X
+mou_open(s, dev, f)
+struct stuff *s;
+int dev;
+struct file *f;
+{
+X int minor_dev;
+X
+X CHCK_MINOR(dev);
+X return (*s->drv_funcs[minor_dev]->dldd_open)(s->stuff_ptr[minor_dev], dev, f);
+}
+X
+mou_close(s, f)
+struct stuff *s;
+struct file *f;
+{
+X int minor_dev;
+X
+X CHCK_MINOR(f->dev);
+X return (*s->drv_funcs[minor_dev]->dldd_close)(s->stuff_ptr[minor_dev], f);
+}
+X
+mou_select(s, f, which, ffs)
+struct stuff *s;
+struct file *f;
+struct sel *ffs;
+{
+X int minor_dev;
+X
+X CHCK_MINOR(f->dev);
+X return (*s->drv_funcs[minor_dev]->dldd_select)(s->stuff_ptr[minor_dev], f, which, ffs);
+}
+X
+mou_write(s, f, buffer, count)
+struct stuff *s;
+struct file *f;
+char *buffer;
+{
+X int minor_dev;
+X
+X CHCK_MINOR(f->dev);
+X return (*s->drv_funcs[minor_dev]->dldd_write)(s->stuff_ptr[minor_dev], f, buffer, count);
+}
+X
+mou_read(s, f, buffer, count)
+struct stuff *s;
+struct file *f;
+char *buffer;
+{
+X int minor_dev;
+X
+X CHCK_MINOR(f->dev);
+X return (*s->drv_funcs[minor_dev]->dldd_read)(s->stuff_ptr[minor_dev], f, buffer, count);
+}
+X
+mou_ioctl(s, f, cmd, arg)
+struct stuff *s;
+struct file *f;
+unsigned int cmd;
+unsigned int arg;
+{
+X int minor_dev;
+X
+X CHCK_MINOR(f->dev);
+X return (*s->drv_funcs[minor_dev]->dldd_ioctl)(s->stuff_ptr[minor_dev], f, cmd, arg);
+}
+X
+#ifdef DLDD
+#include <dldd.h>
+X
+static struct dldd entry_points =
+{
+X mou_open, /* OPEN */
+X mou_close, /* CLOSE */
+X mou_read, /* READ */
+X mou_write, /* WRITE */
+X mou_select, /* SELECT */
+X mou_ioctl, /* IOCTL */
+X mou_install, /* INSTALL */
+X mou_uninstall, /* UNINSTALL */
+};
+#endif
+SHAR_EOF
+ $shar_touch -am 0623101295 'sys/drivers/bmouse/mouse.c' &&
+ chmod 0644 'sys/drivers/bmouse/mouse.c' ||
+ echo 'restore of sys/drivers/bmouse/mouse.c failed'
+ shar_count="`wc -c < 'sys/drivers/bmouse/mouse.c'`"
+ test 3222 -eq "$shar_count" ||
+ echo "sys/drivers/bmouse/mouse.c: original size 3222, current size $shar_count"
+fi
+# ============= sys/drivers/bmouse/msbmouse.c ==============
+if test -f 'sys/drivers/bmouse/msbmouse.c' && test X"$1" != X"-c"; then
+ echo 'x - skipping sys/drivers/bmouse/msbmouse.c (file already exists)'
+else
+ echo 'x - extracting sys/drivers/bmouse/msbmouse.c (text)'
+ sed 's/^X//' << 'SHAR_EOF' > 'sys/drivers/bmouse/msbmouse.c' &&
+/* this LynxOS driver relies heavily on a Linux driver, see below
+X * for copyrights and credits.
+X *
+X * LynxOS work by:
+X *
+X * Thomas Mueller
+X * SYSTRIX CS GmbH, Hindenburgring 31, 89077 Ulm (Germany)
+X * tm@systrix.de, lynx@systrix.de
+X *
+X * September 1994
+X */
+X
+/*
+X * Microsoft busmouse driver based on Logitech driver (see busmouse.c)
+X *
+X * Microsoft BusMouse support by Teemu Rantanen (tvr@cs.hut.fi) (02AUG92)
+X *
+X * Microsoft Bus Mouse support modified by Derrick Cole (cole@concert.net)
+X * 8/28/92
+X *
+X * Microsoft Bus Mouse support folded into 0.97pl4 code
+X * by Peter Cervasio (pete%q106fm.uucp@wupost.wustl.edu) (08SEP92)
+X * Changes: Logitech and Microsoft support in the same kernel.
+X * Defined new constants in busmouse.h for MS mice.
+X * Added int mse_busmouse_type to distinguish busmouse types
+X * Added a couple of new functions to handle differences in using
+X * MS vs. Logitech (where the int variable wasn't appropriate).
+X *
+X * Modified by Peter Cervasio (address above) (26SEP92)
+X * Changes: Included code to (properly?) detect when a Microsoft mouse is
+X * really attached to the machine. Don't know what this does to
+X * Logitech bus mice, but all it does is read ports.
+X *
+X * Modified by Christoph Niemann (niemann@rubdv15.etdv.ruhr-uni-bochum.de)
+X * Changes: Better interrupt-handler (like in busmouse.c).
+X * Some changes to reduce code-size.
+X * Changed dectection code to use inb_p() instead of doing empty
+X * loops to delay i/o.
+X *
+X * version 0.3a
+X */
+X
+#include <conf.h>
+#include <kernel.h>
+#include <file.h>
+#include <errno.h>
+#include <signal.h>
+#include <io.h>
+#include "inline.h"
+X
+#include <busmouse.h>
+X
+#ifdef DLDD
+#include "bmouseinfo.h"
+#else
+#include "../../dheaders/bmouseinfo.h"
+#endif
+X
+struct stuff
+{
+X int port; /* i/o port address */
+X int vector; /* interrupt vector + 32 */
+X
+X int *sel_sem; /* select semaphore */
+X
+X struct mouse_status mouse; /* mouse/driver status */
+};
+X
+static void ms_mou_interrupt(s)
+struct stuff *s;
+{
+X char dx, dy;
+X unsigned char buttons;
+X
+X outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT(s->port));
+X outb((inb(MS_MSE_DATA_PORT(s->port)) | 0x20), MS_MSE_DATA_PORT(s->port));
+X
+X outb(MS_MSE_READ_X, MS_MSE_CONTROL_PORT(s->port));
+X dx = inb(MS_MSE_DATA_PORT(s->port));
+X
+X outb(MS_MSE_READ_Y, MS_MSE_CONTROL_PORT(s->port));
+X dy = inb(MS_MSE_DATA_PORT(s->port));
+X
+X outb(MS_MSE_READ_BUTTONS, MS_MSE_CONTROL_PORT(s->port));
+X buttons = ~(inb(MS_MSE_DATA_PORT(s->port))) & 0x07;
+X
+X outb(MS_MSE_COMMAND_MODE, MS_MSE_CONTROL_PORT(s->port));
+X outb((inb(MS_MSE_DATA_PORT(s->port)) & 0xdf), MS_MSE_DATA_PORT(s->port));
+X
+X if ( dx != 0 || dy != 0
+X || buttons != s->mouse.buttons || ((~buttons) & 0x07))
+X {
+X s->mouse.buttons = buttons;
+X s->mouse.dx += dx;
+X s->mouse.dy += dy;
+X s->mouse.ready = 1;
+X if (s->sel_sem)
+X ssignal(s->sel_sem);
+X ssignal(&s->mouse.wait);
+X }
+}
+X
+static struct mouse_status *ms_mou_init(s)
+struct stuff *s;
+{
+X static struct mouse_status mouse;
+X int mse_byte, i;
+X
+X mouse.present = mouse.active = mouse.ready = 0;
+X mouse.buttons = 0x80;
+X mouse.dx = mouse.dy = 0;
+X mouse.wait = 0;
+X if (inb(MS_MSE_SIGNATURE_PORT(s->port)) == 0xde)
+X {
+X mse_byte = inb(MS_MSE_SIGNATURE_PORT(s->port));
+X
+X for (i = 0; i < 4; i++) {
+X if (inb(MS_MSE_SIGNATURE_PORT(s->port)) == 0xde) {
+X if (inb(MS_MSE_SIGNATURE_PORT(s->port)) == mse_byte)
+X mouse.present = 1;
+X else
+X mouse.present = 0;
+X } else
+X mouse.present = 0;
+X }
+X }
+X if (mouse.present == 0)
+X return NULL;
+X MS_MSE_INT_OFF(s->port);
+X return &mouse;
+}
+X
+static char *ms_mou_install(info)
+struct mouseinfo *info;
+{
+X extern char *sysbrk();
+X struct stuff *s;
+X struct mouse_status *mouse;
+X
+X s = (struct stuff *) sysbrk((long)sizeof(struct stuff));
+X if (!s)
+X {
+X pseterr(ENOMEM);
+X return (char *)SYSERR;
+X }
+X bzero(s, sizeof(struct stuff));
+X s->port = info->port;
+X s->vector = info->vector;
+X if ((mouse = ms_mou_init(s)) == NULL)
+X {
+X cprintf("Microsoft BusMouse *not* detected.\n");
+X pseterr(ENXIO);
+X return (char *) SYSERR;
+X }
+X s->mouse = *mouse;
+X cprintf("Microsoft BusMouse detected and installed.\n");
+X return (char *) s;
+}
+X
+static ms_mou_uninstall(s)
+struct stuff *s;
+{
+X sysfree(s, (long) sizeof(struct stuff));
+X return OK;
+}
+X
+static ms_mou_open(s, d, f)
+struct stuff *s;
+int d;
+struct file *f;
+{
+X if (s->mouse.present == 0)
+X {
+X pseterr(ENXIO);
+X return SYSERR;
+X }
+X if (s->mouse.active)
+X {
+X pseterr(EBUSY);
+X return SYSERR;
+X }
+X s->mouse.active = 1;
+X s->mouse.ready = s->mouse.dx = s->mouse.dy = 0;
+X s->mouse.buttons = 0x80;
+X s->mouse.wait = 0;
+X iointset(s->vector, ms_mou_interrupt, s);
+X outb(MS_MSE_START, MS_MSE_CONTROL_PORT(s->port));
+X MS_MSE_INT_ON(s->port);
+X return OK;
+}
+X
+static ms_mou_close(s, f)
+struct stuff *s;
+struct file *f;
+{
+X MS_MSE_INT_OFF(s->port);
+X s->mouse.active = s->mouse.ready = 0;
+X iointclr(s->vector);
+X return OK;
+}
+X
+static ms_mou_select(s, f, which, ffs)
+struct stuff *s;
+struct file *f;
+struct sel *ffs;
+{
+X if (which == SREAD)
+X {
+X ffs->iosem = &s->mouse.wait;
+X ffs->sel_sem = &s->sel_sem;
+X }
+X return OK;
+}
+X
+static ms_mou_inval(s, f, buffer, count)
+struct stuff *s;
+struct file *f;
+char *buffer;
+{
+X pseterr(EINVAL);
+X return SYSERR;
+}
+X
+static ms_mou_read(s, f, buffer, count)
+struct stuff *s;
+struct file *f;
+char *buffer;
+{
+X int i, dx, dy;
+X
+X if (count < 3)
+X {
+X pseterr(EINVAL);
+X return SYSERR;
+X }
+X if (f->access_mode & FNDELAY)
+X {
+X if (!s->mouse.ready)
+X {
+X pseterr(EAGAIN);
+X return SYSERR;
+X }
+X }
+X else
+X swait(&s->mouse.wait, SEM_SIGABORT);
+X
+X buffer[0] = s->mouse.buttons | 0x80;
+X dx = s->mouse.dx < -127 ?
+X -127 : (s->mouse.dx > 127 ? 127 : s->mouse.dx);
+X dy = s->mouse.dy < -127 ?
+X 127 : (s->mouse.dy > 127 ? -127 : -s->mouse.dy);
+X buffer[1] = dx;
+X buffer[2] = dy;
+X bzero(buffer + 3, count - 3);
+X
+X s->mouse.dx -= dx;
+X s->mouse.dy += dy;
+X s->mouse.ready = 0;
+X sreset(&s->mouse.wait);
+X return count;
+}
+X
+#include <dldd.h>
+X
+static struct dldd entry_points =
+{
+X ms_mou_open, /* OPEN */
+X ms_mou_close, /* CLOSE */
+X ms_mou_read, /* READ */
+X ms_mou_inval, /* WRITE */
+X ms_mou_select, /* SELECT */
+X ms_mou_inval, /* IOCTL */
+X ms_mou_install, /* INSTALL */
+X ms_mou_uninstall, /* UNINSTALL */
+};
+X
+struct dldd *ms_entry_points = &entry_points;
+SHAR_EOF
+ $shar_touch -am 0623101295 'sys/drivers/bmouse/msbmouse.c' &&
+ chmod 0644 'sys/drivers/bmouse/msbmouse.c' ||
+ echo 'restore of sys/drivers/bmouse/msbmouse.c failed'
+ shar_count="`wc -c < 'sys/drivers/bmouse/msbmouse.c'`"
+ test 6202 -eq "$shar_count" ||
+ echo "sys/drivers/bmouse/msbmouse.c: original size 6202, current size $shar_count"
+fi
+# ============= sys/drivers/bmouse/ps2mouse.c ==============
+if test -f 'sys/drivers/bmouse/ps2mouse.c' && test X"$1" != X"-c"; then
+ echo 'x - skipping sys/drivers/bmouse/ps2mouse.c (file already exists)'
+else
+ echo 'x - extracting sys/drivers/bmouse/ps2mouse.c (text)'
+ sed 's/^X//' << 'SHAR_EOF' > 'sys/drivers/bmouse/ps2mouse.c' &&
+/* this LynxOS driver relies heavily on a Linux driver, see below
+X * for copyrights and credits.
+X *
+X * LynxOS work by:
+X *
+X * Thomas Mueller
+X * SYSTRIX CS GmbH, Hindenburgring 31, 89077 Ulm (Germany)
+X * tm@systrix.de, lynx@systrix.de
+X *
+X * September 1994
+X */
+X
+/*
+X * linux/kernel/chr_drv/psaux.c
+X *
+X * Driver for PS/2 type mouse by Johan Myreen.
+X *
+X * Supports pointing devices attached to a PS/2 type
+X * Keyboard and Auxiliary Device Controller.
+X */
+#include <conf.h>
+#include <kernel.h>
+#include <file.h>
+#include <errno.h>
+#include <signal.h>
+#include <io.h>
+#include "inline.h"
+X
+#include <busmouse.h>
+X
+#ifdef DLDD
+#include "bmouseinfo.h"
+#else
+#include "../../dheaders/bmouseinfo.h"
+#endif
+X
+/* aux controller ports */
+#define AUX_INPUT_PORT(p) (p) /* Aux device output buffer */
+#define AUX_OUTPUT_PORT(p) (p) /* Aux device input buffer */
+#define AUX_COMMAND(p) (p+4) /* Aux device command buffer */
+#define AUX_STATUS(p) (p+4) /* Aux device status reg */
+X
+/* aux controller status bits */
+#define AUX_OBUF_FULL 0x21 /* output buffer (from device) full */
+#define AUX_IBUF_FULL 0x02 /* input buffer (to device) full */
+X
+/* aux controller commands */
+#define AUX_CMD_WRITE 0x60 /* value to write to controller */
+#define AUX_MAGIC_WRITE 0xd4 /* value to send aux device data */
+X
+#define AUX_INTS_ON 0x47 /* enable controller interrupts */
+#define AUX_INTS_OFF 0x65 /* disable controller interrupts */
+X
+#define AUX_DISABLE 0xa7 /* disable aux */
+#define AUX_ENABLE 0xa8 /* enable aux */
+X
+/* aux device commands */
+#define AUX_SET_RES 0xe8 /* set resolution */
+#define AUX_SET_SCALE11 0xe6 /* set 1:1 scaling */
+#define AUX_SET_SCALE21 0xe7 /* set 2:1 scaling */
+#define AUX_GET_SCALE 0xe9 /* get scaling factor */
+#define AUX_SET_STREAM 0xea /* set stream mode */
+#define AUX_SET_SAMPLE 0xf3 /* set sample rate */
+#define AUX_ENABLE_DEV 0xf4 /* enable aux device */
+#define AUX_DISABLE_DEV 0xf5 /* disable aux device */
+#define AUX_RESET 0xff /* reset aux device */
+X
+#define MAX_RETRIES 60 /* some aux operations take long time*/
+#define AUX_IRQ 12
+#define AUX_BUF_SIZE 2048
+X
+struct aux_queue
+{
+X unsigned long head;
+X unsigned long tail;
+X unsigned char buf[AUX_BUF_SIZE];
+X int sema;
+};
+X
+struct stuff
+{
+X int port; /* i/o port address */
+X int vector; /* interrupt vector + 32 */
+X
+X int *sel_sem; /* select semaphore */
+X
+X struct mouse_status mouse; /* mouse/driver status */
+X struct aux_queue q;
+};
+X
+static int ps2_mou_interrupt();
+static int _poll_status();
+#define poll_status(s) _poll_status(s,0)
+#define ppoll_status(s) _poll_status(s,1)
+static void _aux_write_cmd();
+#define aux_write_cmd(s,x) _aux_write_cmd(s,x,0)
+#define paux_write_cmd(s,x) _aux_write_cmd(s,x,1)
+X
+/*
+X * Write to aux device
+X */
+static void aux_write_dev(s, val)
+struct stuff *s;
+{
+X poll_status(s);
+X outb(AUX_MAGIC_WRITE,AUX_COMMAND(s->port)); /* write magic cookie */
+X poll_status(s);
+X outb(val,AUX_OUTPUT_PORT(s->port)); /* write data */
+}
+X
+X
+/*
+X * Write aux device command
+X */
+X
+static void _aux_write_cmd(s, val, poll)
+struct stuff *s;
+{
+X _poll_status(s, poll);
+X outb(AUX_CMD_WRITE,AUX_COMMAND(s->port));
+X _poll_status(s, poll);
+X outb(val,AUX_OUTPUT_PORT(s->port));
+}
+X
+static int _poll_status(s, poll)
+struct stuff *s;
+{
+X extern int ssignal();
+X
+X static int to;
+X int retries = 0;
+X
+X while ((inb(AUX_STATUS(s->port)) & 0x03) && retries++ < 2*MAX_RETRIES)
+X {
+X if (inb(AUX_STATUS(s->port)) & 0x01)
+X inb(AUX_INPUT_PORT(s->port));
+X if (poll)
+X {
+X int i;
+X
+X for (i = 0; i < 40000; i++)
+X ;
+X }
+X else
+X {
+X to = 0;
+X if (timeout(ssignal, &to, 5) > 0)
+X swait(&to, SEM_SIGIGNORE);
+X }
+X }
+X return !(retries==2*MAX_RETRIES);
+}
+X
+X
+static struct mouse_status *ps2_mou_init(s)
+struct stuff *s;
+{
+X static struct mouse_status mouse;
+X
+X mouse.present = mouse.active = mouse.ready = 0;
+X mouse.buttons = 0x80;
+X mouse.dx = mouse.dy = 0;
+X mouse.wait = 0;
+#if 0
+X if (inb(MS_MSE_SIGNATURE_PORT(s->port)) == 0xde)
+X {
+X mse_byte = inb(MS_MSE_SIGNATURE_PORT(s->port));
+X
+X for (i = 0; i < 4; i++) {
+X if (inb(MS_MSE_SIGNATURE_PORT(s->port)) == 0xde) {
+X if (inb(MS_MSE_SIGNATURE_PORT(s->port)) == mse_byte)
+X mouse.present = 1;
+X else
+X mouse.present = 0;
+X } else
+X mouse.present = 0;
+X }
+X }
+#else
+X mouse.present = 1;
+#endif
+X if (mouse.present == 0)
+X return NULL;
+#if 0
+X MS_MSE_INT_OFF(s->port);
+#endif
+X return &mouse;
+}
+X
+X
+static char *ps2_mou_install(info)
+struct mouseinfo *info;
+{
+X extern char *sysbrk();
+X struct stuff *s;
+X struct mouse_status *mouse;
+X
+X if (!info->vector || !info->port)
+X {
+X pseterr(ENODEV);
+X return (char *) SYSERR;
+X }
+X s = (struct stuff *) sysbrk((long)sizeof(struct stuff));
+X if (!s)
+X {
+X pseterr(ENOMEM);
+X return (char *)SYSERR;
+X }
+X bzero(s, sizeof(struct stuff));
+X s->port = info->port;
+X s->vector = info->vector;
+X if ((mouse = ps2_mou_init(s)) == NULL)
+X {
+X cprintf("PS/2 Mouse port *not* detected.\n");
+X pseterr(ENXIO);
+X return (char *) SYSERR;
+X }
+X s->mouse = *mouse;
+X cprintf("PS/2 Mouse detected and installed.\n");
+X
+X ppoll_status(s);
+X outb(AUX_DISABLE,AUX_COMMAND(s->port)); /* Disable Aux device */
+X paux_write_cmd(s, AUX_INTS_OFF); /* disable controller ints */
+X
+X return (char *) s;
+}
+X
+static ps2_mou_uninstall(s)
+struct stuff *s;
+{
+X sysfree(s, (long) sizeof(struct stuff));
+X return OK;
+}
+X
+static ps2_mou_open(s, d, f)
+struct stuff *s;
+int d;
+struct file *f;
+{
+X if (s->mouse.present == 0)
+X {
+X pseterr(ENXIO);
+X return SYSERR;
+X }
+X if (s->mouse.active)
+X {
+X pseterr(EBUSY);
+X return SYSERR;
+X }
+X if (!poll_status(s))
+X {
+X pseterr(EBUSY);
+X return SYSERR;
+X }
+X
+X s->mouse.active = 1;
+X s->mouse.ready = s->mouse.dx = s->mouse.dy = 0;
+X s->mouse.buttons = 0x80;
+X s->mouse.wait = 0;
+X s->q.head = s->q.tail = 0; /* Flush input queue */
+X s->q.sema = 0;
+X s->sel_sem = NULL;
+X
+X iointset(s->vector, ps2_mou_interrupt, s);
+#if 0
+X outb(MS_MSE_START, MS_MSE_CONTROL_PORT(s->port));
+X MS_MSE_INT_ON(s->port);
+#endif
+X aux_write_dev(s, AUX_ENABLE_DEV); /* enable aux device */
+X aux_write_cmd(s, AUX_INTS_ON); /* enable controller ints */
+X poll_status(s);
+X outb(AUX_ENABLE,AUX_COMMAND(s->port)); /* Enable Aux */
+X
+X return OK;
+}
+X
+static ps2_mou_close(s, f)
+struct stuff *s;
+struct file *f;
+{
+#if 0
+X MS_MSE_INT_OFF(s->port);
+#endif
+X aux_write_dev(s, AUX_DISABLE_DEV); /* disable aux device */
+X poll_status(s);
+X outb(AUX_DISABLE,AUX_COMMAND(s->port)); /* Disable Aux device */
+X aux_write_cmd(s, AUX_INTS_OFF); /* disable controller ints */
+X
+X s->mouse.active = s->mouse.ready = 0;
+X iointclr(s->vector);
+X return OK;
+}
+X
+static ps2_mou_select(s, f, which, ffs)
+struct stuff *s;
+struct file *f;
+struct sel *ffs;
+{
+X if (which == SREAD)
+X {
+X ffs->iosem = &s->q.sema;
+X ffs->sel_sem = &s->sel_sem;
+X }
+X return OK;
+}
+X
+static ps2_mou_inval(s, f, buffer, count)
+struct stuff *s;
+struct file *f;
+char *buffer;
+{
+X pseterr(EINVAL);
+X return SYSERR;
+}
+X
+/*
+X * Interrupt from the auxiliary device: a character
+X * is waiting in the keyboard/aux controller.
+X */
+X
+static int ps2_mou_interrupt(s)
+struct stuff *s;
+{
+X int ps;
+X int head, tail;
+X
+X disable(ps);
+X tail = s->q.tail ? (s->q.tail - 1) : (AUX_BUF_SIZE - 1);
+X head = s->q.head;
+X s->q.buf[head] = inb(AUX_INPUT_PORT(s->port));
+X if (head != tail)
+X {
+X s->q.head = (head + 1) & (AUX_BUF_SIZE - 1);
+X ssignal(&s->q.sema);
+X if (s->sel_sem)
+X ssignal(s->sel_sem);
+X }
+X restore(ps);
+}
+X
+static unsigned int get_from_queue(queue)
+struct aux_queue *queue;
+{
+X int ps;
+X unsigned int result;
+X unsigned long flags;
+X
+X disable(ps);
+X result = queue->buf[queue->tail];
+X queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
+X restore(ps);
+X return result;
+}
+X
+X
+static int queue_empty(queue)
+struct aux_queue *queue;
+{
+X int ps;
+X unsigned int result;
+X
+X disable(ps);
+X result = queue->head == queue->tail;
+X restore(ps);
+X return result;
+}
+X
+static ps2_mou_read(s, f, buffer, count)
+struct stuff *s;
+struct file *f;
+char *buffer;
+{
+X int i;
+X
+X if (queue_empty(&s->q) && (f->access_mode & FNDELAY))
+X {
+X pseterr(EAGAIN);
+X return SYSERR;
+X }
+X
+X i = 0;
+#if 0
+X if (minor(f->dev) == 1)
+X {
+X /* compatibility mode for our jurassic X386
+X * X Server mouse interface
+X */
+X int ps;
+X
+X if (count < 3)
+X return 0;
+X
+X disable(ps);
+X if (s->q.sema >= 3)
+X {
+X swait(&s->q.sema, SEM_SIGABORT);
+X *buffer++ = get_from_queue(&s->q);
+X swait(&s->q.sema, SEM_SIGABORT);
+X *buffer++ = get_from_queue(&s->q);
+X swait(&s->q.sema, SEM_SIGABORT);
+X *buffer++ = get_from_queue(&s->q);
+X i = 3;
+X }
+X restore(ps);
+X return i;
+X }
+#endif
+X
+X do
+X {
+X swait(&s->q.sema, SEM_SIGABORT);
+X *buffer++ = get_from_queue(&s->q);
+X i++;
+X }
+X while (i < count && !queue_empty(&s->q));
+X return i;
+}
+X
+#include <dldd.h>
+X
+static struct dldd entry_points =
+{
+X ps2_mou_open, /* OPEN */
+X ps2_mou_close, /* CLOSE */
+X ps2_mou_read, /* READ */
+X ps2_mou_inval, /* WRITE */
+X ps2_mou_select, /* SELECT */
+X ps2_mou_inval, /* IOCTL */
+X ps2_mou_install, /* INSTALL */
+X ps2_mou_uninstall, /* UNINSTALL */
+};
+X
+struct dldd *ps2_entry_points = &entry_points;
+SHAR_EOF
+ $shar_touch -am 0711143395 'sys/drivers/bmouse/ps2mouse.c' &&
+ chmod 0644 'sys/drivers/bmouse/ps2mouse.c' ||
+ echo 'restore of sys/drivers/bmouse/ps2mouse.c failed'
+ shar_count="`wc -c < 'sys/drivers/bmouse/ps2mouse.c'`"
+ test 8843 -eq "$shar_count" ||
+ echo "sys/drivers/bmouse/ps2mouse.c: original size 8843, current size $shar_count"
+fi
+# ============= sys/lynx.os/bmouse.cfg ==============
+if test ! -d 'sys/lynx.os'; then
+ echo 'x - creating directory sys/lynx.os'
+ mkdir 'sys/lynx.os'
+fi
+if test -f 'sys/lynx.os/bmouse.cfg' && test X"$1" != X"-c"; then
+ echo 'x - skipping sys/lynx.os/bmouse.cfg (file already exists)'
+else
+ echo 'x - extracting sys/lynx.os/bmouse.cfg (text)'
+ sed 's/^X//' << 'SHAR_EOF' > 'sys/lynx.os/bmouse.cfg' &&
+#
+# PS/2 and other Bus mice
+#
+C:mouse: \
+X :mou_open:mou_close:mou_read:mou_write: \
+X :mou_select:mou_ioctl:mou_install:mou_uninstall
+#
+D:Mouse devices:mouseinfo::
+N:bmouselogitec:0:0666
+N:bmouseps2:1:0666
+N:bmousems:2:0666
+N:bmouseatixl:3:0666
+SHAR_EOF
+ $shar_touch -am 0711152595 'sys/lynx.os/bmouse.cfg' &&
+ chmod 0644 'sys/lynx.os/bmouse.cfg' ||
+ echo 'restore of sys/lynx.os/bmouse.cfg failed'
+ shar_count="`wc -c < 'sys/lynx.os/bmouse.cfg'`"
+ test 244 -eq "$shar_count" ||
+ echo "sys/lynx.os/bmouse.cfg: original size 244, current size $shar_count"
+fi
+exit 0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/Imakefile b/xc/programs/Xserver/hw/xfree86/etc/Imakefile
new file mode 100644
index 000000000..02a115021
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/Imakefile
@@ -0,0 +1,139 @@
+XCOMM $XConsortium: Imakefile /main/24 1996/10/28 04:24:12 kaleb $
+
+
+
+
+
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/etc/Imakefile,v 3.28 1999/04/29 09:13:46 dawes Exp $
+#include <Server.tmpl>
+
+#if SystemV
+ CONFIGFILES = ldterm.sdevice ptem.sdevice ptm.sdevice pts.node \
+ pts.sdevice sp.node sp.sdevice
+ INSTPROG = install.sv3
+#ifdef i386ScoArchitecture
+ MISCFILES = dmmap.shar
+#else
+ MISCFILES = mmapSVR3.shar
+#endif
+#endif
+
+#if SystemV4
+ INSTPROG = install.sv4
+ XDMCONF = XdmConf.svr4
+#ifdef SunArchitecture
+ MISCFILES = apSolx86.shar xcode.xfree86
+#else
+ MISCFILES = 2key.c xcode.xfree86
+#endif
+#endif
+
+#ifdef LynxOSArchitecture
+#undef Lynx
+ CONFIGFILES = pty.cfg
+ MISCFILES = BM-Lynx.shar
+#endif
+
+/* Are these really needed? */
+#if 0
+# ifdef FreeBSDArchitecture
+ INSTPROG = inst.freebsd
+# endif
+# ifdef NetBSDArchitecture
+ INSTPROG = inst.netbsd
+# endif
+#endif
+
+#if !BuildServersOnly
+#ifdef SunArchitecture
+ TERMFILES = xterm.termcap xterm.terminfo
+#else
+ TERMFILES = sun.termcap sun.terminfo xterm.termcap xterm.terminfo
+#endif
+#endif
+
+PREINST = preinst.sh
+POSTINST = postinst.sh
+
+ FILES = $(CONFIGFILES) $(TERMFILES) \
+ $(PATCHFILES) $(XDMCONF) \
+ et4000clock.c xmodmap.std $(MISCFILES) $(POSTINST) $(PREINST)
+ INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC)
+
+all:: $(FILES)
+
+#if defined(FreeBSDArchitecture) || defined(NetBSDArchitecture) || defined(OpenBSDArchitecture)
+ SRCS1 = kbd_mode.c
+ DEFINES = XFree86ConsoleDefines
+
+AllTarget(kbd_mode)
+
+SingleProgramTarget(kbd_mode,kbd_mode.o,NullParameter,NullParameter)
+
+InstallProgram(kbd_mode,$(BINDIR))
+InstallManPage(kbd_mode,$(MANDIR))
+#endif
+
+#if BuildScanpci
+ SRCS2 = scanpci.c
+
+#if defined(OpenBSDArchitecture) || defined(NetBSDArchitecture) \
+ && ((OSMajorVersion == 1 && OSMinorVersion >= 1) || OSMajorVersion >= 2)
+DEFINES = -DUSE_I386_IOPL
+SYS_LIBRARIES = -li386
+#endif
+
+AllTarget(ProgramTargetName(scanpci))
+
+NormalProgramTarget(scanpci,scanpci.o,NullParameter,NullParameter,NullParameter)
+InstallProgram(scanpci,$(BINDIR))
+#endif
+
+#if JoystickSupport || Joystick2Support
+ SRCS3 = joycal.c
+
+AllTarget(ProgramTargetName(joycal))
+
+NormalProgramTarget(joycal,joycal.o,NullParameter,NullParameter,NullParameter)
+InstallProgram(joycal,$(BINDIR))
+#endif
+
+ SRCS4 = pcitweak.c
+
+AllTarget(ProgramTargetName(pcitweak))
+NormalProgramTarget(pcitweak,pcitweak.o,NullParameter,-L../os-support -lxf86_os,NullParameter)
+InstallProgram(pcitweak,$(BINDIR))
+
+ SRCS = $(SRCS1) $(SRCS2) $(SRCS3) $(SRCS4)
+
+#if (SystemV && !defined(i386ScoArchitecture)) || SystemV4
+InstallNamedProg($(INSTPROG),xf86install,$(LIBDIR)/etc)
+#endif
+
+InstallMultipleDestFlags(install,$(FILES),$(LIBDIR)/etc,$(INSTDATFLAGS))
+
+#if SystemV
+InstallNamedProg(svr3_patch,svr3_patch,$(LIBDIR)/etc)
+InstallNamedProg(svr3_rem_pch,svr3_patch_rem,$(LIBDIR)/etc)
+#endif
+#if SystemV4 && !defined(SunArchitecture)
+InstallNamedProg(svr4_patch,svr4_patch,$(LIBDIR)/etc)
+InstallNamedProg(svr4_rem_pch,svr4_patch_rem,$(LIBDIR)/etc)
+#endif
+#if defined(LynxOSArchitecture) && (OSMajorVersion == 2 && OSMinorVersion < 3)
+NormalProgramTarget(ld-wrapper,ld-wrapper.o,NullParameter,NullParameter,NullParameter)
+InstallProgram(ld-wrapper,$(LIBDIR)/etc)
+#endif
+
+#if !BuildServersOnly
+LinkFile(xterm.termcap,$(PROGRAMSRC)/xterm/termcap)
+LinkFile(xterm.terminfo,$(PROGRAMSRC)/xterm/terminfo)
+#endif
+
+LinkFile(sun.termcap,sun.tcap)
+LinkFile(sun.terminfo,sun.tinfo)
+
+NormalLibraryObjectRule()
+DependTarget()
+
diff --git a/xc/programs/Xserver/hw/xfree86/etc/XdmConf.svr4 b/xc/programs/Xserver/hw/xfree86/etc/XdmConf.svr4
new file mode 100644
index 000000000..cf0e745ac
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/XdmConf.svr4
@@ -0,0 +1,777 @@
+#!/bin/sh
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/XdmConf.svr4,v 3.3 1996/12/23 06:47:05 dawes Exp $
+# This is a shell archive (produced by shar 3.49)
+# To extract the files from this archive, save it to a file, remove
+# everything above the "!/bin/sh" line above, and type "sh file_name".
+#
+# made 06/05/1994 05:08 UTC by root@gamma
+# Source directory /home5/x/XdmConf.svr4
+#
+# $XConsortium: XdmConf.svr4 /main/3 1996/02/21 17:47:15 kaleb $
+#
+# existing files will NOT be overwritten unless -c is specified
+#
+# This shar contains:
+# length mode name
+# ------ ---------- ------------------------------------------
+# 2194 -rw-r--r-- README
+# 1598 -rwxr-xr-x XFilePaths
+# 2762 -rwxr-xr-x Xdm
+# 29 -rwxr-xr-x Xreset_0
+# 994 -rw-r--r-- Xresources
+# 430 -rw-r--r-- Xservers
+# 1075 -rwxr-xr-x Xsession
+# 91 -rwxr-xr-x Xsetup_0
+# 29 -rwxr-xr-x Xstartup_0
+# 2029 -rw-r--r-- profile
+# 960 -rw-r--r-- xdm-config
+# 2861 -rwxr-xr-x xsession
+#
+# ============= README ==============
+if test -f 'README' -a X"$1" != X"-c"; then
+ echo 'x - skipping README (File already exists)'
+else
+echo 'x - extracting README (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'README' &&
+Sample xdm configuration files for XFree86 3.1 / SVR4
+-----------------------------------------------------
+X
+X
+File Install Path Comments
+------------------------------------------------
+XXdm /etc/init.d See the comments at the top for
+X info on links you need to set up.
+X Heed the note about using the "vtXX"
+X option when starting the server in
+X xdm's Xservers file (which is done
+X in the sample).
+X
+XXFilePaths /usr/X11R6/lib/X11 Sets up $XFILESEARCHPATH and
+X $XUSERFILESEARCHPATH, for Xt. This
+X is sourced by Xsession for xdm and
+X by .profile for startx.
+X
+XXresources /usr/X11R6/lib/X11/xdm Basically the same as the distributed
+X one. The greeting is a little more
+X friendly :->
+X
+XXservers /usr/X11R6/lib/X11/xdm Specifies the local server. Note
+X the 'vt06' option. Specify whichever
+X Virtual Terminal you want XFree86 to
+X use.
+X
+XXsession /usr/X11R6/lib/X11/xdm Does a much better job of setting up
+X the environment than the distributed
+X one. See the comments in the file.
+X
+XXsetup_0 /usr/X11R6/lib/X11/xdm Use this to start up an xconsole, and
+X anything else you want on the screen
+X with the login prompt (e.g. a clock).
+X
+XXstartup_0 /usr/X11R6/lib/X11/xdm Use this to put an entry in the utmp
+X file corresponding to the xdm session.
+X
+XXreset_0 /usr/X11R6/lib/X11/xdm Use this to remove the utmp entry
+X added by Xstartup_0
+X
+xdm-config /usr/X11R6/lib/X11/xdm Sets up paths better suited to having
+X a vendor X package installed in
+X addition to XFree86. Also gets the
+X server permissions right so xconsole
+X can start up.
+X
+profile ${HOME}/.profile A sample profile that coordinates well
+X with Xsession and .xsession/.xinitrc
+X See the comments in the file.
+X
+xsession ${HOME}/.session Also link it to ${HOME}/.xinitrc
+X See the comments in the file. It's
+X set up to let you use one startup file
+X for both startx and xdm.
+X
+Version 1.0 - 6/12/92
+X David E. Wexelblat <dwex@goblin.org>, <dwex@aib.com>
+X
+Version 1.1 - 6/24/92
+X Add XFilePaths
+X
+Version 1.2 - 7/13/92
+X Add Xstartup_0, Xreset_0, change xdm-config
+X
+Version 1.3 - 6/5/94
+X Update for X11R6/XFree86 3.1
+SHAR_EOF
+chmod 0644 README ||
+echo 'restore of README failed'
+Wc_c="`wc -c < 'README'`"
+test 2194 -eq "$Wc_c" ||
+ echo 'README: original size 2194, current size' "$Wc_c"
+fi
+# ============= XFilePaths ==============
+if test -f 'XFilePaths' -a X"$1" != X"-c"; then
+ echo 'x - skipping XFilePaths (File already exists)'
+else
+echo 'x - extracting XFilePaths (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'XFilePaths' &&
+#
+# XFilePaths - set up default X search paths and user search paths.
+# This file should be sourced rather than executed.
+#
+# Version 1.1 - 6/5/94
+# David E. Wexelblat <dwex@goblin.org>
+#
+XXFILESEARCHPATH=/usr/X11R6/lib/X11/%L/%T/%N%C%S
+XXFILESEARCHPATH=${XFILESEARCHPATH}:/usr/X11R6/lib/X11/%L/%T/%N%S
+XXFILESEARCHPATH=${XFILESEARCHPATH}:/usr/X11R6/lib/X11/%l/%T/%N%C%S
+XXFILESEARCHPATH=${XFILESEARCHPATH}:/usr/X11R6/lib/X11/%l/%T/%N%S
+XXFILESEARCHPATH=${XFILESEARCHPATH}:/usr/X11R6/lib/X11/%T/%N%C%S
+XXFILESEARCHPATH=${XFILESEARCHPATH}:/usr/X11R6/lib/X11/%T/%N%S
+XXFILESEARCHPATH=${XFILESEARCHPATH}:/usr/X386/lib/X11/%L/%T/%N%C%S
+XXFILESEARCHPATH=${XFILESEARCHPATH}:/usr/X386/lib/X11/%L/%T/%N%S
+XXFILESEARCHPATH=${XFILESEARCHPATH}:/usr/X386/lib/X11/%l/%T/%N%C%S
+XXFILESEARCHPATH=${XFILESEARCHPATH}:/usr/X386/lib/X11/%l/%T/%N%S
+XXFILESEARCHPATH=${XFILESEARCHPATH}:/usr/X386/lib/X11/%T/%N%C%S
+XXFILESEARCHPATH=${XFILESEARCHPATH}:/usr/X386/lib/X11/%T/%N%S
+XXFILESEARCHPATH=${XFILESEARCHPATH}:/usr/lib/X11/%L/%T/%N%S
+XXFILESEARCHPATH=${XFILESEARCHPATH}:/usr/lib/X11/%l/%T/%N%S
+XXFILESEARCHPATH=${XFILESEARCHPATH}:/usr/lib/X11/%T/%N%S
+XXFILESEARCHPATH=${XFILESEARCHPATH}:/usr/lib/X11/locale/%L/%T/%N%S
+XXFILESEARCHPATH=${XFILESEARCHPATH}:/usr/lib/X11/locale/%l/%T/%N%S
+XXFILESEARCHPATH=${XFILESEARCHPATH}:/usr/lib/X11/locale/%T/%N%S
+export XFILESEARCHPATH
+X
+XXUSERFILESEARCHPATH=${HOME}/lib/app-defaults/%N%C
+XXUSERFILESEARCHPATH=${XUSERFILESEARCHPATH}:${HOME}/lib/app-defaults/%N
+XXUSERFILESEARCHPATH=${XUSERFILESEARCHPATH}:${HOME}/%N%C
+XXUSERFILESEARCHPATH=${XUSERFILESEARCHPATH}:${HOME}/%N
+export XUSERFILESEARCHPATH
+SHAR_EOF
+chmod 0755 XFilePaths ||
+echo 'restore of XFilePaths failed'
+Wc_c="`wc -c < 'XFilePaths'`"
+test 1598 -eq "$Wc_c" ||
+ echo 'XFilePaths: original size 1598, current size' "$Wc_c"
+fi
+# ============= Xdm ==============
+if test -f 'Xdm' -a X"$1" != X"-c"; then
+ echo 'x - skipping Xdm (File already exists)'
+else
+echo 'x - extracting Xdm (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'Xdm' &&
+#
+# Xdm - startup script for xdm under SVR4
+#
+# Install this file as /etc/init.d/Xdm. Create the following links to
+# cause xdm to be started & stopped when booting and shutting down:
+#
+# ln /etc/init.d/Xdm /etc/rc0.d/K88xdm
+# ln /etc/init.d/Xdm /etc/rc2.d/S90xdm
+#
+# WARNING:
+# If you are using the xqueue driver in your Xconfig file, you must
+# specify the 'vtXX' option to the server in your Xservers file. See
+# the XFree86(1) and xdm(1) manual pages.
+#
+# Version 1.0 - 6/12/92
+# David E. Wexelblat <dwex@goblin.org>
+#
+# Version 1.1 - 7/15/92
+# Read /etc/default/login, set ulimit, TZ, HZ
+#
+# Version 1.2 - 6/5/94
+# Update for X11R6
+#
+X
+#
+# Root of the X tree
+#
+XXPATH=/usr/X11R6
+X
+case $1 in
+'start')
+X #
+X # First nuke an old streams pipe that may have been left lying
+X # around.
+X #
+X rm -f /dev/X/server.0
+X
+X #
+X # Verify that xdm was previously shut down cleanly. This will avoid
+X # a loop if xdm caused a crash.
+X #
+X if [ -f ${XPATH}/lib/X11/xdm/.badexit ]
+X then
+X echo "Not starting xdm - abnormal exit"
+X exit 1
+X fi
+X
+X #
+X # If the xdm binary exists...
+X #
+X if [ -x ${XPATH}/bin/xdm ]
+X then
+X #
+X # Create a pseudo-lock file, so that if the system crashes
+X # xdm won't start up on the next boot (safer when debugging
+X # X servers or xdm)
+X #
+X touch ${XPATH}/lib/X11/xdm/.badexit
+X #
+X # Read /etc/default/login to set some parameters
+X #
+X DEF_LOGIN=/etc/default/login
+X if [ -r $DEF_LOGIN ]; then
+X line=`grep '^TIMEZONE=' $DEF_LOGIN`
+X if [ "$line" ]; then
+X TZ=`expr $line : 'TIMEZONE=\(.*\)'`
+X export TZ
+X fi
+X line=`grep '^HZ=' $DEF_LOGIN`
+X if [ "$line" ]; then
+X HZ=`expr "$line" : 'HZ=\(.*\)'`
+X export HZ
+X fi
+X line=`grep '^ULIMIT=' $DEF_LOGIN`
+X if [ "$line" ]; then
+X ulimit `expr "$line" : 'ULIMIT=\(.*\)'`
+X fi
+X fi
+X #
+X # Wait a few seconds before kicking off the server; the
+X # thrashing that goes on with finishing the boot after this
+X # script gets run can cause XFree86 to not be able to determine
+X # clocks correctly, delaying start up even more than this
+X # sleep will cause.
+X #
+X (sleep 5; ${XPATH}/bin/xdm) &
+X echo "Started xdm"
+X else
+X echo "${XPATH}/bin/xdm not found!"
+X fi
+X ;;
+'stop')
+X #
+X # See if xdm is running or not. If xdm has already been killed
+X # by some other means, this will just clean things up.
+X #
+X if [ -f ${XPATH}/lib/X11/xdm/xdm-pid ]
+X then
+X i=`cat ${XPATH}/lib/X11/xdm/xdm-pid`
+X kill $i 2>/dev/null
+X ps -p $i > /dev/null 2>&1
+X if [ "$?" = "0" ]
+X then
+X #
+X # Some times xdm doesn't die right away, so try
+X # again.
+X #
+X sleep 3
+X kill $i 2>/dev/null
+X fi
+X #
+X # Remove existing pseudo-lock files.
+X #
+X rm -f ${XPATH}/lib/X11/xdm/xdm-pid
+X rm -f ${XPATH}/lib/X11/xdm/.badexit
+X echo "Killed xdm"
+X fi
+X ;;
+*)
+X echo "usage: /etc/init.d/Xdm {start|stop}"
+X ;;
+esac
+SHAR_EOF
+chmod 0755 Xdm ||
+echo 'restore of Xdm failed'
+Wc_c="`wc -c < 'Xdm'`"
+test 2762 -eq "$Wc_c" ||
+ echo 'Xdm: original size 2762, current size' "$Wc_c"
+fi
+# ============= Xreset_0 ==============
+if test -f 'Xreset_0' -a X"$1" != X"-c"; then
+ echo 'x - skipping Xreset_0 (File already exists)'
+else
+echo 'x - extracting Xreset_0 (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'Xreset_0' &&
+sessreg -d -l $DISPLAY $USER
+SHAR_EOF
+chmod 0755 Xreset_0 ||
+echo 'restore of Xreset_0 failed'
+Wc_c="`wc -c < 'Xreset_0'`"
+test 29 -eq "$Wc_c" ||
+ echo 'Xreset_0: original size 29, current size' "$Wc_c"
+fi
+# ============= Xresources ==============
+if test -f 'Xresources' -a X"$1" != X"-c"; then
+ echo 'x - skipping Xresources (File already exists)'
+else
+echo 'x - extracting Xresources (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'Xresources' &&
+xlogin*login.translations: #override\
+X Ctrl<Key>R: abort-display()\n\
+X <Key>F1: set-session-argument(failsafe) finish-field()\n\
+X Ctrl<Key>Return: set-session-argument(failsafe) finish-field()\n\
+X <Key>Return: set-session-argument() finish-field()
+xlogin*borderWidth: 3
+xlogin*greeting: Welcome to CLIENTHOST
+xlogin*namePrompt: login:\
+xlogin*fail: Login incorrect
+#ifdef COLOR
+xlogin*greetColor: CadetBlue
+xlogin*failColor: red
+*Foreground: black
+*Background: #fffff0
+#else
+xlogin*Foreground: black
+xlogin*Background: white
+#endif
+X
+XXConsole.text.geometry: 480x130
+XXConsole.verbose: true
+XXConsole*iconic: true
+XXConsole*font: fixed
+X
+Chooser*geometry: 700x500+300+200
+Chooser*allowShellResize: false
+Chooser*viewport.forceBars: true
+Chooser*label.font: *-new century schoolbook-bold-i-normal-*-240-*
+Chooser*label.label: XDMCP Host Menu from CLIENTHOST
+Chooser*list.font: -*-*-medium-r-normal-*-*-230-*-*-c-*-iso8859-1
+Chooser*Command.font: *-new century schoolbook-bold-r-normal-*-180-*
+SHAR_EOF
+chmod 0644 Xresources ||
+echo 'restore of Xresources failed'
+Wc_c="`wc -c < 'Xresources'`"
+test 994 -eq "$Wc_c" ||
+ echo 'Xresources: original size 994, current size' "$Wc_c"
+fi
+# ============= Xservers ==============
+if test -f 'Xservers' -a X"$1" != X"-c"; then
+ echo 'x - skipping Xservers (File already exists)'
+else
+echo 'x - extracting Xservers (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'Xservers' &&
+#
+# Xservers file, workstation prototype
+#
+# This file should contain an entry to start the server on the
+# local display; if you have more than one display (not screen),
+# you can add entries to the list (one per line). If you also
+# have some X terminals connected which do not support XDMCP,
+# you can add them here as well. Each X terminal line should
+# look like:
+# XTerminalName:0 foreign
+#
+:0 local /usr/X11R6/bin/X vt06
+SHAR_EOF
+chmod 0644 Xservers ||
+echo 'restore of Xservers failed'
+Wc_c="`wc -c < 'Xservers'`"
+test 430 -eq "$Wc_c" ||
+ echo 'Xservers: original size 430, current size' "$Wc_c"
+fi
+# ============= Xsession ==============
+if test -f 'Xsession' -a X"$1" != X"-c"; then
+ echo 'x - skipping Xsession (File already exists)'
+else
+echo 'x - extracting Xsession (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'Xsession' &&
+#!/bin/sh
+# $XConsortium: XdmConf.svr4 /main/3 1996/02/21 17:47:15 kaleb $
+#
+# Xsession
+#
+# This is the program that is run as the client
+# for the display manager. This example is
+# quite friendly as it attempts to run a per-user
+# .xsession file instead of forcing a particular
+# session layout
+#
+X
+# redirect errors to a file in user's home directory if we can
+for errfile in "$HOME/.xsession-errors" "/tmp/xses-$USER"
+do
+X if ( cp /dev/null "$errfile" 2> /dev/null )
+X then
+X chmod 600 "$errfile"
+X exec > "$errfile" 2>&1
+X break
+X fi
+done
+X
+. /etc/profile
+X
+#
+# Get file search paths
+#
+if [ -f /usr/X11R6/lib/X11/XFilePaths ]
+then
+X . /usr/X11R6/lib/X11/XFilePaths
+fi
+X
+#
+# Set up user's environment variables.
+#
+if [ -f $HOME/.login_env ]
+then
+X . $HOME/.login_env
+fi
+X
+case $# in
+1)
+X case $1 in
+X failsafe)
+X exec xterm -geometry 80x24+0+0
+X ;;
+X esac
+esac
+X
+startup=$HOME/.xsession
+resources=$HOME/.Xdefaults
+X
+if [ -f $startup ]; then
+X exec $startup
+X exec /bin/sh $startup
+else
+X if [ -f $resources ]; then
+X xrdb -load $resources
+X fi
+X twm &
+X exec xterm -geometry 80x24+10+10 -ls
+fi
+SHAR_EOF
+chmod 0755 Xsession ||
+echo 'restore of Xsession failed'
+Wc_c="`wc -c < 'Xsession'`"
+test 1075 -eq "$Wc_c" ||
+ echo 'Xsession: original size 1075, current size' "$Wc_c"
+fi
+# ============= Xsetup_0 ==============
+if test -f 'Xsetup_0' -a X"$1" != X"-c"; then
+ echo 'x - skipping Xsetup_0 (File already exists)'
+else
+echo 'x - extracting Xsetup_0 (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'Xsetup_0' &&
+#!/bin/sh
+xconsole -geometry 480x130+0+0 -daemon -notify -verbose -fn 8x13bold -exitOnFail
+SHAR_EOF
+chmod 0755 Xsetup_0 ||
+echo 'restore of Xsetup_0 failed'
+Wc_c="`wc -c < 'Xsetup_0'`"
+test 91 -eq "$Wc_c" ||
+ echo 'Xsetup_0: original size 91, current size' "$Wc_c"
+fi
+# ============= Xstartup_0 ==============
+if test -f 'Xstartup_0' -a X"$1" != X"-c"; then
+ echo 'x - skipping Xstartup_0 (File already exists)'
+else
+echo 'x - extracting Xstartup_0 (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'Xstartup_0' &&
+sessreg -a -l $DISPLAY $USER
+SHAR_EOF
+chmod 0755 Xstartup_0 ||
+echo 'restore of Xstartup_0 failed'
+Wc_c="`wc -c < 'Xstartup_0'`"
+test 29 -eq "$Wc_c" ||
+ echo 'Xstartup_0: original size 29, current size' "$Wc_c"
+fi
+# ============= profile ==============
+if test -f 'profile' -a X"$1" != X"-c"; then
+ echo 'x - skipping profile (File already exists)'
+else
+echo 'x - extracting profile (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'profile' &&
+#
+# .profile - sample file
+#
+# Version 1.0 - 6/12/92
+# David E. Wexelblat <dwex@goblin.org>
+#
+# Version 1.1 - 6/24/92
+# Add XFilePaths file
+#
+X
+#
+# ${HOME}/.login_env contains all of the environment settings that you
+# want to make available whether running from xdm or from a normal login.
+#
+if [ -f ${HOME}/.login_env ]
+then
+X . ${HOME}/.login_env
+else
+X MAIL=/usr/mail/${LOGNAME:?}; export MAIL
+X ENV=${HOME}/.kshrc; export ENV
+fi
+X
+#
+# This variable lets you use the same file for .xsession (xdm) and
+# .xinitrc (startx) (i.e. link them together). You can check this
+# variable and you will know which login method was used.
+#
+DOTPROFILE=1; export DOTPROFILE
+X
+t=`tty`
+if [ "$t" = "/dev/console" ]
+then
+X #
+X # Logged in on the console - check if xdm is running. If not,
+X # see if the user wants to start up X.
+X #
+X if [ ! -f /usr/X11R6/lib/X11/xdm/xdm-pid ]
+X then
+X WINSYSTEM=2
+X XDT=0
+X OLWM=0
+X echo "Choose window system:"
+X echo " None - 0"
+X echo " Open Look - 1"
+X echo " Motif - 2"
+X echo " MIT/XFree86 - 3"
+X echo " X.desktop - 4 [default=$WINSYSTEM]: \c"
+X read t
+X if [ "$t" != "" ]
+X then
+X WINSYSTEM=$t
+X fi
+X
+X case $WINSYSTEM in
+X 0)
+X WM=none
+X ;;
+X 1)
+X . $HOME/.olsetup #!@ Do not edit this line !@
+X WM=/usr/X/bin/olwsm
+X OLWM=1
+X ;;
+X 2)
+X WM=/usr/X/bin/mwm
+X ;;
+X 3)
+X WM=/usr/X11R6/bin/twm
+X ;;
+X 4)
+X XDT=1
+X ;;
+X esac
+X export WM XDT OLWM
+X if [ "$WM" != "none" ]
+X then
+X PATH=$PATH:/usr/X11R6/bin:/usr/X386/bin:/usr/bin/X11
+X
+X #
+X # Get file search paths
+X #
+X if [ -f /usr/X11R6/lib/X11/XFilePaths ]
+X then
+X . /usr/X11R6/lib/X11/XFilePaths
+X fi
+X
+X startx &
+X fi
+X fi
+elif [ "${t##/dev/vt}" = "$t" -a "${t##/dev/pts}" = "$t" ]
+then
+X #
+X # Not /dev/console, not /dev/vt??, and not /dev/pts???
+X #
+X echo "TERM=($TERM): \c"
+X read t
+X if [ "$t" != "" ]
+X then
+X TERM=$t
+X fi
+X export TERM
+fi
+X
+SHAR_EOF
+chmod 0644 profile ||
+echo 'restore of profile failed'
+Wc_c="`wc -c < 'profile'`"
+test 2029 -eq "$Wc_c" ||
+ echo 'profile: original size 2029, current size' "$Wc_c"
+fi
+# ============= xdm-config ==============
+if test -f 'xdm-config' -a X"$1" != X"-c"; then
+ echo 'x - skipping xdm-config (File already exists)'
+else
+echo 'x - extracting xdm-config (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'xdm-config' &&
+DisplayManager.errorLogFile: /usr/X11R6/lib/X11/xdm/xdm-errors
+DisplayManager.pidFile: /usr/X11R6/lib/X11/xdm/xdm-pid
+DisplayManager.keyFile: /usr/X11R6/lib/X11/xdm/xdm-keys
+DisplayManager.servers: /usr/X11R6/lib/X11/xdm/Xservers
+DisplayManager.accessFile: /usr/X11R6/lib/X11/xdm/Xaccess
+DisplayManager._0.authorize: true
+DisplayManager._0.grabServer: false
+DisplayManager._0.setup: /usr/X11R6/lib/X11/xdm/Xsetup_0
+DisplayManager._0.startup: /usr/X11R6/lib/X11/xdm/Xstartup_0
+DisplayManager._0.reset: /usr/X11R6/lib/X11/xdm/Xreset_0
+DisplayManager._0.userPath: /usr/local/bin:/usr/bin:/usr/sbin:/usr/ucb:/usr/X11R6/bin:/usr/X386/bin:/usr/bin/X11
+DisplayManager._0.systemPath: /sbin:/usr/sbin:/etc:/usr/bin:/usr/ucb:/usr/local/bin:/usr/X11R6/bin:/usr/X386/bin:/usr/bin/X11
+DisplayManager*resources: /usr/X11R6/lib/X11/xdm/Xresources
+DisplayManager*session: /usr/X11R6/lib/X11/xdm/Xsession
+DisplayManager*authComplain: false
+DisplayManager.exportList: TZ HZ
+SHAR_EOF
+chmod 0644 xdm-config ||
+echo 'restore of xdm-config failed'
+Wc_c="`wc -c < 'xdm-config'`"
+test 960 -eq "$Wc_c" ||
+ echo 'xdm-config: original size 960, current size' "$Wc_c"
+fi
+# ============= xsession ==============
+if test -f 'xsession' -a X"$1" != X"-c"; then
+ echo 'x - skipping xsession (File already exists)'
+else
+echo 'x - extracting xsession (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'xsession' &&
+#
+# .xsession/.xinitrc - sample file
+#
+# Version 1.0 - 6/12/92
+# David E. Wexelblat <dwex@goblin.org>
+#
+# Version 1.1 - 6/30/92
+# Added support for all standard xdm authentication formats
+#
+# Version 1.2 - 8/26/92
+# Added xrdb line for resources to be loaded
+#
+# Version 1.3 - 10/7/93
+# Clean up authentication stuff
+#
+X
+if [ -f ${HOME}/.Xdefaults ]
+then
+X xrdb -merge ${HOME}/.Xdefaults
+fi
+X
+#
+# ${HOME}/.profile will set DOTPROFILE=1 and export it. This allows
+# the same file to be used for both .xsession and .xinitrc.
+#
+if [ "$DOTPROFILE" != "1" ]
+then
+X #
+X # Default window manager
+X #
+X WM=/usr/X11R6/bin/twm
+X
+X #
+X # Kill off the xconsole that's run by the xdm setup. This will be
+X # a no-op if there's no xconsole running.
+X #
+X /usr/X11R6/bin/xkill\
+X -id `/usr/X11R6/bin/xwininfo -tree -root | grep xconsole |\
+X awk '{print $1}'` > /dev/null 2>&1
+X
+X #
+X # Prompt for a window manager. The xmessage client is part of
+X # the contributed software, not the core clients.
+X #
+X /usr/X11R6/bin/xmessage -geometry +400+250\
+X -buttons "MWM:1,OLWM:2,TWM:3,XDT:4"\
+X "Select Window Manager"
+X case "$?" in
+X 1)
+X WM=/usr/bin/X11/mwm
+X ;;
+X 2)
+X . $HOME/.olsetup
+X WM=/usr/X/bin/olwsm
+X OLWM=1
+X ;;
+X 3)
+X WM=/usr/X11R6/bin/twm
+X ;;
+X 4)
+X XDT=1
+X ;;
+X esac
+else
+X XMERGE=vga
+X export XMERGE
+fi
+X
+#
+# Add .Xauthority entries for display :1, for use with xscope
+#
+MYHOST=`uname -n`
+for i in MIT-MAGIC-COOKIE-1 XDM-AUTHORIZATION-1 SUN-DES-1
+do
+X xauth list | grep $i >/dev/null 2>&1
+X if [ "$?" = "0" ]
+X then
+X KEY=`xauth -q list | grep $i | awk '{print $3; exit}'`
+X if [ "$KEY" != "" ]
+X then
+X xauth -q add ${MYHOST}:1 $i $KEY 2>/dev/null
+X xauth -q add ${MYHOST}/unix:1 $i $KEY 2>/dev/null
+X fi
+X fi
+done
+X
+#
+# Now do things based on window-manager selection made above
+#
+if [ "$XDT" = "1" ]
+then
+X #
+X # Run X.desktop 3.0
+X #
+X /usr/X/bin/mwm -xrm "Mwm*configFile: /home/dwex/.xdtmwmrc" &
+X /usr/X/bin/xdt3 -xrm "XDesktop3*isRoot: True"
+else
+X if [ "$OLWM" = "1" ]
+X then
+X #
+X # Goddam Open Look session manager stomps on .Xdefaults,
+X # whether you tell it to or not!
+X #
+X xrdb -load .Xdefaults
+X cp .Xdefaults .SaveXdefaults
+X cp .OLXdefaults .Xdefaults
+X fi
+X xsetroot -solid gray60
+X xterm -geometry +0+100 &
+X xterm -geometry +360+100 -iconic&
+X xterm -geometry +360+425&
+X xterm -geometry +0+425 -iconic&
+X xconsole -geometry +0+0 -verbose &
+X xclock -geometry +425+0 &
+X xpostme -geometry +522+0 &
+X $WM
+X if [ "$OLWM" = "1" ]
+X then
+X #
+X # Undo Open Look stupidity
+X #
+X cp .Xdefaults .OLXdefaults
+X cp .SaveXdefaults .Xdefaults
+X fi
+fi
+X
+#
+# Remove .Xauthority entries for display :1
+#
+for i in MIT-MAGIC-COOKIE-1 XDM-AUTHORIZATION-1 SUN-DES-1
+do
+X xauth list | grep $i >/dev/null 2>&1
+X if [ "$?" = "0" ]
+X then
+X KEY=`xauth -q list | grep $i | awk '{print $3; exit}'`
+X if [ "$KEY" != "" ]
+X then
+X xauth -q remove ${MYHOST}:1
+X xauth -q remove ${MYHOST}/unix:1
+X fi
+X fi
+done
+SHAR_EOF
+chmod 0755 xsession ||
+echo 'restore of xsession failed'
+Wc_c="`wc -c < 'xsession'`"
+test 2861 -eq "$Wc_c" ||
+ echo 'xsession: original size 2861, current size' "$Wc_c"
+fi
+exit 0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/apNetBSD.shar b/xc/programs/Xserver/hw/xfree86/etc/apNetBSD.shar
new file mode 100644
index 000000000..7b82f7df7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/apNetBSD.shar
@@ -0,0 +1,473 @@
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/apNetBSD.shar,v 3.9 1999/08/28 09:01:09 dawes Exp $
+#
+# This is a shell archive. Save it in a file, remove anything before
+# this line, and then unpack it by entering "sh file". Note, it may
+# create directories; files and directories will be owned by you and
+# have default permissions.
+#
+# This archive contains:
+#
+# README
+# Makefile
+# aperture.c
+# apinstall
+# aptest.c
+# lkm.c
+# version.c
+# version.h
+#
+# $XConsortium: apNetBSD.shar /main/8 1996/10/25 11:37:37 kaleb $
+#
+echo x - README
+sed 's/^X//' >README << 'END-of-README'
+X
+X XFree86 Framebuffer aperture driver for NetBSD.
+X -----------------------------------------------
+X
+XThis module was written to help work around the security feature of
+XNetBSD 0.9C and later that prevents read/write access to /dev/mem.
+X
+XXFree86 can take advantage of having direct access to video
+Xmemory (especially with VLB and PCI cards) and even requires it for
+Xthe P9000 server.
+X
+XThis driver works like the standard /dev/mem driver. It just allows
+Xmapping of the VGA framebuffer even if kernel security level is > 0.
+XThe driver only implements the open(), close() and mmap() calls. In
+Xorder not to defeat kernel security, only one open() at a time is
+Xallowed and only a process with effective user id of 0 can perform
+Xit. So while you're running XFree86, no other process will be allowed
+Xto open /dev/xf86.
+X
+XThis work is heavily inspired from the Solaris x86 aperture driver by
+XDoug Anson (danson@lgc.com) and David Holland (davidh@use.com).
+X
+X
+XInstallation:
+X-------------
+X
+X1. Edit the Makefile if you want to modify the default installation
+X directory.
+X
+X2. run make depend && make; then as root, run make install.
+X
+X3. add these lines somehere at the end of /etc/rc.local (before the
+X sysctl that raises the security level):
+X
+X KERNDIR=/usr/X11R6/lib/X11/kernel
+X if [ -f ${KERNDIR}/ap.o ]; then
+X modload -o ${KERNDIR}/ap -e ap -p ${KERNDIR}/apinstall ${KERNDIR}/ap.o
+X fi
+X
+X to load the driver at bootime.
+X
+X4. Reboot your system.
+X
+X5. If you're running a version prior to NetBSD 1.0, modload does not
+X execute post-install scripts. So you have to create the device manually.
+X If you're running NetBSD 1.0 or later, skip this.
+X
+X WARNING: be sure to understand what you'll do before proceeding
+X
+X a) find out what major device number will be allocated to you by
+X modload. Modload allocates major numbers beginning at 29. So if
+X 'ap' is your only device driver module, it will have major
+X number 29. If it's the third, it will be 31...
+X
+X b) goto the /dev directory and type ``mknod xf86 c 29 0'' (replace
+X 29 by the appropriate value if you load more than one device
+X driver module.
+X
+X Make sure that rc.local loads the module every time at the same
+X position as it did now.
+X
+X6. Test the module by running 'aptest' as root. The outpout will look like:
+X
+X# ./aptest
+XNOTICE: VGA mapped [0xa0000 ,size=4096) to addr=0x10073000...
+X
+XDONE displaying memory contents (80 bytes)
+XUNMAPPING [0xa0000 ,size=4096) to addr=0x10073000... and closing...DONE.
+XExiting successful...
+X
+X7. If you're running XFree86 3.1 or higher, just make sure that
+X HasNetBSDApertureDriver is set to YES in xf86site.def before building
+X your server. The netBSD binary distribution has the aperture driver
+X code enabled.
+X
+XBug reports, comments, suggestions can be sent to matthieu@laas.fr
+X
+X--Matthieu Herrb
+X
+X----------------------------------------------------------------------
+X
+X Copyright (c) 1994 The XFree86 Project Inc.
+X
+END-of-README
+echo x - Makefile
+sed 's/^X//' >Makefile << 'END-of-Makefile'
+X#
+X# Loadable Kernel Module for NetBSD Aperture Driver
+X#
+X# Copyright (c) 1994 The XFree86 Project Inc.
+X#
+X
+X# Change KERNDIR to the directory into which you want to install kernel modules
+XKERNDIR = /usr/X11R6/lib/X11/kernel
+X
+X# You can add -DAP_DEBUG to CFLAGS to add debugging prints
+XCFLAGS = -O -D_KERNEL -I/sys $(PC98)
+X
+XMODULE = ap
+XPOSTINSTALL = apinstall
+X
+XSRCS = aperture.c lkm.c version.c
+XOBJS = $(SRCS:.c=.o)
+X
+Xall: $(MODULE).o aptest
+X
+X$(MODULE).o: $(OBJS)
+X $(LD) -r -o $(MODULE).o $(OBJS)
+X
+Xaptest: aptest.c
+X $(CC) -g -o aptest aptest.c
+X
+Xclean:
+X rm -f $(MODULE).o $(OBJS) aptest
+X
+Xload:
+X modload -v -o$(MODULE) -e$(MODULE) -p$(POSTINSTALL) $(MODULE).o
+X
+Xunload:
+X modunload -n $(MODULE)
+X
+Xinstall: $(MODULE).o
+X install -d -o root -g wheel -m 755 $(KERNDIR)
+X install -c -o root -g wheel -m 644 $(MODULE).o $(KERNDIR)
+X install -c -o root -g wheel -m 755 $(POSTINSTALL) $(KERNDIR)
+X
+Xshar:
+X shar README Makefile aperture.c apinstall aptest.c lkm.c \
+X version.c version.h > apNetBSD.shar
+X
+X.c.o:
+X $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
+X
+X.include <bsd.dep.mk>
+END-of-Makefile
+echo x - aperture.c
+sed 's/^X//' >aperture.c << 'END-of-aperture.c'
+X/*
+X * Copyright 1994 the XFree86 Project Inc.
+X */
+X
+X/*
+X * linear framebuffer aperture driver for NetBSD
+X */
+X
+X#include <sys/param.h>
+X#include <sys/systm.h>
+X#include <sys/proc.h>
+X#include <sys/errno.h>
+X
+X#define VGA_START 0xA0000
+X#define VGA_END 0xFFFFF
+X#ifdef PC98
+X#define HOLE16M_START 0xF00000
+X#define HOLE16M_END 0xFFFFFF
+X#endif
+X
+X/* open counter */
+Xstatic int ap_open_count = 0;
+X
+X/*
+X * Open the device
+X */
+Xint
+Xapopen(dev_t dev, int oflags, int devtype, struct proc *p)
+X{
+X
+X if (suser(p->p_ucred, &p->p_acflag) != 0) {
+X return(EPERM);
+X }
+X /* authorize only one simultaneous open() */
+X if (ap_open_count > 0) {
+X return(EPERM);
+X }
+X ap_open_count++;
+X
+X return(0);
+X}
+X
+X/*
+X * Close the device
+X */
+Xint
+Xapclose(dev_t dev, int cflags, int devtype, struct proc *p)
+X{
+X
+X ap_open_count--;
+X return(0);
+X}
+X
+X/*
+X * mmap() physical memory sections
+X *
+X * allow only section in the vga framebuffer and above main memory
+X * to be mapped
+X */
+Xint
+Xapmmap(dev_t dev, int offset, int length)
+X{
+X
+X#ifdef AP_DEBUG
+X printf("apmmap: addr 0x%x\n", offset);
+X#endif
+X if ((minor(dev) == 0)
+X && ((offset >= VGA_START && offset <= VGA_END )
+X || (unsigned)offset > (unsigned)ctob(physmem)
+X#ifdef PC98
+X || ((unsigned)offset >=HOLE16M_START
+X && (unsigned)offset <= HOLE16M_END)
+X#endif
+X )) {
+X return i386_btop(offset);
+X } else {
+X return(-1);
+X }
+X}
+X
+END-of-aperture.c
+echo x - apinstall
+sed 's/^X//' >apinstall << 'END-of-apinstall'
+X#! /bin/sh
+X#
+X# Postinstall script for NetBSD Aperture Driver
+X#
+X# Copyright (C) 1994 The XFree86 Project Inc.
+X#
+Xif [ $# -ne 3 ]; then
+X echo "$0: should be called by modload(8) with 3 arguments"
+X exit 1
+Xfi
+X
+Xecho "Major device number: $3"
+Xrm -f /dev/xf86
+Xmknod /dev/xf86 c $3 0
+Xexit 0
+END-of-apinstall
+echo x - aptest.c
+sed 's/^X//' >aptest.c << 'END-of-aptest.c'
+X/*
+X * Copyright 1994 Doug Anson, danson@lgc.com & David Holland, davidh@use.com
+X *
+X * Author: Doug Anson (danson@lgc.com)
+X * Date : 2/21/94
+X * Modifed: David Holland (davidh@use.com)
+X * Log:
+X * DWH - Changed names/added comments 2/23/94
+X * DWH - Removed annoying delays. 2/23/94
+X *
+X * This program test the fb aperture driver by 'cheating'
+X * it uses the aperture driver to access/read the main
+X * system BIOS header
+X *
+X * Copyright notice:
+X * Permission to use, copy, modify, distribute, and sell this software and its
+X * documentation for any purpose is hereby granted without fee, provided that
+X * the above copyright notice appear in all copies and that both that
+X * copyright notice and this permission notice appear in supporting
+X * documentation, and that the name of Doug Anson, and David Holland be used in
+X * advertising or publicity pertaining to distribution of the software
+X * Doug Anson, and David Holland make no * representations about the
+X * suitability of this software for any purpose.
+X * It is provided "as is" without express or implied warranty.
+X *
+X * Disclaimer:
+X * DOUG ANSON, AND DAVID HOLLAND DISCLAIMS ALL WARRIENTS WITH REGARD TO THIS
+X * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS,
+X * IN NO EVENT SHALL DOUG ANSON, OR DAVID HOLLAND BE LIABLE FOR ANY SPECIAL,
+X * INDIRECT, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM
+X * USAGE OF THIS SOFTWARE.
+X */
+X
+X/*
+X * linear framebuffer aperture driver test program
+X */
+X
+X/*
+X * $Id
+X */
+X
+X
+X#include <stdio.h>
+X#include <sys/types.h>
+X#include <sys/mman.h>
+X#include <sys/stat.h>
+X#include <fcntl.h>
+X#include <errno.h>
+X
+X#if !defined(sun)
+Xextern void exit(int);
+Xextern caddr_t mmap();
+Xextern int close();
+Xextern int munmap();
+X#endif
+X
+X/* framebuffer access defines */
+X#define AP_DEV "/dev/xf86" /* framebuffer apperture device */
+X#define PADDR 0xa0000 /* offset from fbmem base */
+X#define BUF_LENGTH 0x1000 /* length in bytes -- ignored */
+X
+X/* debug testing defines */
+X#define START_INDEX 0 /* display starting index(>=0)*/
+X#define STOP_INDEX 80 /* display stopping index */
+X#define INCR 1 /* display increment */
+X
+X/* main program */
+Xint main(int argc,char **argv)
+X{
+X caddr_t addr = (caddr_t)0;
+X int fb_dev;
+X long start = START_INDEX;
+X long stop = STOP_INDEX;
+X int i;
+X
+X /* open the framebuffer device */
+X fb_dev = open (AP_DEV,O_RDWR);
+X if (fb_dev < 0)
+X {
+X /* failed to open framebuffer driver */
+X printf("ERROR: failed to open %s\n",AP_DEV);
+X perror("ERROR: open()");
+X exit(1);
+X }
+X
+X /* memory map the framebuffer */
+X addr = (caddr_t)mmap((caddr_t)0,BUF_LENGTH,PROT_READ|PROT_WRITE,MAP_SHARED,
+X fb_dev,(off_t)PADDR);
+X if (addr == (caddr_t)-1)
+X {
+X /* failed to memory map framebuffer driver */
+X printf("ERROR: failed to mmap [0x%x ,size=%d bytes)\n",
+X PADDR,BUF_LENGTH);
+X perror("ERROR: mmap()");
+X close(fb_dev);
+X exit(1);
+X }
+X else
+X {
+X /* frame buffer mapped */
+X close(fb_dev);
+X printf("NOTICE: BIOS mapped [0x%x ,size=%d) to addr=0x%x...\n",
+X PADDR,BUF_LENGTH,(int)addr);
+X
+X /* display the buffer */
+X for(i=start;i<stop;i=i+INCR)
+X printf("%c",addr[i]);
+X /* printf("addr[%d]=%c\n",i,addr[i]);
+X */
+X printf("\nDONE displaying memory contents (%d bytes)\n",stop);
+X
+X /* unmap and close */
+X printf("UNMAPPING [0x%x ,size=%d) to addr=0x%x... and closing...",
+X PADDR,BUF_LENGTH,(int)addr);
+X munmap(addr,BUF_LENGTH);
+X printf("DONE.\n");
+X printf("Exiting successful...\n");
+X exit(0);
+X }
+X return 1;
+X}
+END-of-aptest.c
+echo x - lkm.c
+sed 's/^X//' >lkm.c << 'END-of-lkm.c'
+X/*
+X * Copyright (c) 1994 The XFree86 Project Inc.
+X */
+X
+X#include <sys/param.h>
+X#include <sys/systm.h>
+X#include <sys/conf.h>
+X#include <sys/uio.h>
+X#include <sys/exec.h>
+X#include <sys/lkm.h>
+X#include <errno.h>
+X#include "version.h"
+X
+X#if NetBSD <= 1994100 && NetBSD >= 1990000
+X/* cdevsw-specific types */
+X#define dev_type_read(n) int n __P((dev_t, struct uio *, int))
+X#define dev_type_write(n) int n __P((dev_t, struct uio *, int))
+X#define dev_type_ioctl(n) \
+X int n __P((dev_t, int, caddr_t, int, struct proc *))
+X#define dev_type_stop(n) int n __P((struct tty *, int))
+X#define dev_type_reset(n) int n __P((int))
+X#define dev_type_select(n) int n __P((dev_t, int, struct proc *))
+X#define dev_type_mmap(n) int n __P(())
+X#endif
+X
+Xextern int apopen(dev_t dev, int oflags, int devtype, struct proc *p);
+Xextern int apclose(dev_t dev, int fflags, int devtype, struct proc *p);
+Xextern int apmmap(dev_t dev, int offset, int length);
+X
+Xstatic struct cdevsw newdev = {
+X apopen, apclose,
+X (dev_type_read((*))) enodev, (dev_type_write((*))) enodev,
+X (dev_type_ioctl((*))) enodev,
+X (dev_type_stop((*))) enodev,
+X#if NetBSD <= 1994100 && NetBSD >= 1990000
+X (dev_type_reset((*))) nullop, (struct tty **) 0,
+X#else
+X 0,
+X#endif
+X seltrue, (dev_type_mmap((*))) apmmap, 0};
+X
+XMOD_DEV("ap", LM_DT_CHAR, -1, &newdev)
+X
+Xstatic int
+Xap_load(struct lkm_table *lkmtp, int cmd)
+X{
+X if (cmd == LKM_E_LOAD) {
+X printf("\n Aperture driver for XFree86 version %s.%s\n",
+X ap_major_version, ap_minor_version);
+X }
+X return(0);
+X}
+X
+X#if NetBSD <= 1994100 && NetBSD >= 1990000
+Xint
+Xap(struct lkm_table *lkmtp, int cmd, int ver)
+X{
+X DISPATCH(lkmtp, cmd, ver, ap_load, nosys, nosys)
+X}
+X#else
+Xint
+Xap(struct lkm_table *lkmtp, int cmd, int ver)
+X{
+X DISPATCH(lkmtp, cmd, ver, ap_load, lkm_nofunc, lkm_nofunc)
+X}
+X#endif
+END-of-lkm.c
+echo x - version.c
+sed 's/^X//' >version.c << 'END-of-version.c'
+X/*
+X * Loadable Kernel Module for XFree86 Aperture driver
+X *
+X * Copyright (c) 1994,1996 The XFree86 Project Inc.
+X */
+Xchar *ap_major_version = "1";
+Xchar *ap_minor_version = "7";
+END-of-version.c
+echo x - version.h
+sed 's/^X//' >version.h << 'END-of-version.h'
+X/*
+X * Loadable Kernel Module for XFree86 Aperture driver
+X *
+X * Copyright (c) 1994 Matthieu Herrb
+X */
+Xextern char *ap_major_version;
+Xextern char *ap_minor_version;
+END-of-version.h
+exit
+
diff --git a/xc/programs/Xserver/hw/xfree86/etc/apSolx86.shar b/xc/programs/Xserver/hw/xfree86/etc/apSolx86.shar
new file mode 100644
index 000000000..a870210d4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/apSolx86.shar
@@ -0,0 +1,1339 @@
+#!/bin/sh
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/apSolx86.shar,v 3.4 1996/12/23 06:47:07 dawes Exp $
+# This is a shell archive (produced by shar 3.49)
+# To extract the files from this archive, save it to a file, remove
+# everything above the "!/bin/sh" line above, and type "sh file_name".
+#
+# made 09/25/1994 14:29 UTC by davidh@barite
+# Source directory /usr10/davidh/aperture
+#
+# $XConsortium: apSolx86.shar /main/4 1996/02/21 17:47:22 kaleb $
+#
+# existing files will NOT be overwritten unless -c is specified
+#
+# This shar contains:
+# length mode name
+# ------ ---------- ------------------------------------------
+# 1342 -rw-r--r-- aperture/Makefile
+# 4042 -rw-r--r-- aperture/aperture.h
+# 95 -rw-r--r-- aperture/devlink.tab
+# 2914 -rw-r--r-- aperture/README
+# 20528 -rw-r--r-- aperture/aperture.c
+# 518 -rw-r--r-- aperture/aperture.conf
+# 3530 -rw-r--r-- aperture/aptest.c
+# 2174 -rw-r--r-- aperture/DISCLAIMER
+#
+# ============= aperture/Makefile ==============
+if test ! -d 'aperture'; then
+ echo 'x - creating directory aperture'
+ mkdir 'aperture'
+fi
+if test -f 'aperture/Makefile' -a X"$1" != X"-c"; then
+ echo 'x - skipping aperture/Makefile (File already exists)'
+else
+echo 'x - extracting aperture/Makefile (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'aperture/Makefile' &&
+#
+# File: makefile for aperture Framebuffer Driver
+# Author: Doug Anson (danson@lgc.com)
+# Date: 2/15/94
+# Modified: David Holland (davidh@use.com)
+# Date: 2/23/94
+# - Changed name, and debugging structure
+#
+# $Id
+#
+# Debug flags may be set to the following values:
+#
+# APERTURE_DEBUG = 1 -- basic log reporting (mininal)
+# APERTURE_DEBUG = 2 -- more log reporting (mmap results)
+# APERTURE_DEBUG = 3 -- verbose log reporting (kernel entry points)
+#
+X
+#
+# GNU gcc compiler (2.4.5 or 2.5.8)
+CC=gcc
+CFLGS=-fno-builtin
+X
+#
+# Proworks compiler (untested!)
+#CC= /opt/SUNWspro/bin/cc
+#CFLGS=-Xa
+X
+#
+# location of lint program (untested!)
+LINT= /usr/opt/SUNWspro/bin/lint
+X
+#
+# Debug error reporting
+#DEBUG_FLG=
+#DEBUG_FLG=-DAPERTURE_DEBUG=1
+#DEBUG_FLG=-DAPERTURE_DEBUG=2
+DEBUG_FLG=-DAPERTURE_DEBUG=3
+X
+#
+# Files and object declarations
+KERNEL_FLGS=-D_KERNEL -DSUNDDI -I.
+CFLAGS= $(CFLGS) $(KERNEL_FLGS) $(DEBUG_FLG)
+CFILES= aperture.c
+HEADERS= aperture.h
+OBJS= aperture.o
+DRIVER= aperture
+APTEST= aptest
+APTESTOBJ= aptest.o
+X
+#
+# Make rules
+all: aperture aptest
+X
+aperture: $(OBJS)
+X ld -r -o aperture aperture.o
+X
+install: aperture aptest
+X cp aperture aperture.conf /kernel/drv
+X
+aptest: $(APTESTOBJ)
+X $(CC) -o $(APTEST) $(APTESTOBJ)
+X
+clean:
+X rm -f *% *.BAK $(OBJS) $(APTESTOBJ) $(APTEST) $(DRIVER) core
+X
+lint:
+X $(LINT) -D_KERNEL -x -u $(CFILES)
+SHAR_EOF
+chmod 0644 aperture/Makefile ||
+echo 'restore of aperture/Makefile failed'
+Wc_c="`wc -c < 'aperture/Makefile'`"
+test 1342 -eq "$Wc_c" ||
+ echo 'aperture/Makefile: original size 1342, current size' "$Wc_c"
+fi
+# ============= aperture/aperture.h ==============
+if test -f 'aperture/aperture.h' -a X"$1" != X"-c"; then
+ echo 'x - skipping aperture/aperture.h (File already exists)'
+else
+echo 'x - extracting aperture/aperture.h (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'aperture/aperture.h' &&
+/*
+X * Copyright 1994 Doug Anson, danson@lgc.com & David Holland, davidh@use.com
+X *
+X * File: aperture.h
+X * Author: Doug Anson
+X * Date: 1/31/94
+X *
+X * Modified: David Holland (davidh@use.com)
+X * Log: Modified for new name 2/23/9
+X *
+X * Purpose: This header is the master header for the Solaris 2.1 x86
+X * framebuffer mmap driver. Portions of this driver are taken
+X * from mmapio.h 1.4 copyright 93/06/03 Sun Microsystems, Inc.
+X *
+X * Disclamer:
+X *
+X * This code is based largely upon the sample device drivers provided
+X * by Sun Microsystems Inc.
+X *
+X * Original copyright notice:
+X * @(#)mmapio.h 1.4 copyright 93/06/03 Sun Microsystems, Inc.
+X *
+X * Our copyright notice:
+X * Permission to use, copy, modify, distribute, and sell this software and its
+X * documentation for any purpose is hereby granted without fee, provided that
+X * the above copyright notice appear in all copies and that both that
+X * copyright notice and this permission notice appear in supporting
+X * documentation, and that the name of Doug Anson, and David Holland be used in
+X * advertising or publicity pertaining to distribution of the software
+X * Doug Anson, and David Holland make no * representations about the
+X * suitability of this software for any purpose.
+X * It is provided "as is" without express or implied warranty.
+X *
+X * Original disclamer from Sun Microsystems, Inc.:
+X * This is a package of sample device drivers for Solaris 2.x (SunOS
+X * 5.x). You may use, modify and distribute these drivers and/or binaries
+X * derived from them. However please note that:
+X *
+X * These examples are provided with no warranties of any kind, including
+X * without limitation accuracy and usefulness, and Sun expressly disclaims
+X * all implied warranties of merchantability, fitness for a particular
+X * purpose and non-infringement. In no event shall Sun be liable for any
+X * damages, including without limitation, direct, special, indirect, or
+X * consequential damages arising out of, or relating to, use of these
+X * examples by customer or any third party. Sun is under no obligation to
+X * provide support to customer for this software.
+X *
+X * Our disclaimer:
+X * DOUG ANSON, AND DAVID HOLLAND DISCLAIMS ALL WARRIENTS WITH REGARD TO THIS
+X * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS,
+X * IN NO EVENT SHALL DOUG ANSON, OR DAVID HOLLAND BE LIABLE FOR ANY SPECIAL,
+X * INDIRECT, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM
+X * USAGE OF THIS SOFTWARE.
+X */
+X
+/*
+X * linear framebuffer aperture driver header file
+X *
+X * $Id
+X */
+X
+#ifndef APERTURE_H
+#define APERTURE_H
+X
+/*
+X * Framebuffer identification definitions
+X */
+#define APERTURE_NAME "aperture"
+#define DEV_BANNER_STRING "SVGA Framebuffer Driver v0.99"
+#define DEV_IDENT_STRING APERTURE_NAME
+X
+/*
+X * driver.conf(4) "reg" property definition for aperture driver:
+X * FORMAT: reg=AP_REGNUM,AP_ADDR,AP_SIZE
+X */
+#define AP_REGNUM 0 /* register number is 1st number in "reg" prop */
+#define AP_ADDR 1 /* fb base address is 2nd number in "reg" prop */
+#define AP_SIZE 2 /* fb length value is 3rd number in "reg" prop */
+#define AP_MAX 3 /* number of values in "reg" property */
+X
+/*
+X * How big a chunk of register we map with each ddi_map_regs(9F)
+X */
+#define AP_MEM_CHUNK sizeof(int)
+X
+/*
+X * Error value for mmap(2) failure status
+X */
+#define AP_MEM_FAILURE -1
+X
+/*
+X * Main memory map structure for the Framebuffer mmap driver
+X */
+struct mmap
+{
+X u_int regnum; /* registers number */
+X volatile caddr_t regbase; /* base address of device to mmap */
+X off_t regsize; /* length of region to mmap(2) */
+X off_t reglength; /* map length for ddi_map_regs(9F) */
+X volatile caddr_t kaddr; /* kernel address of mapped device */
+X off_t off; /* offset from mmap(2) call */
+X volatile off_t mapaddr; /* base address of mmap(2) region */
+X kmutex_t map_lock; /* device map mutex lock */
+X dev_info_t *dip; /* device information pointer */
+};
+typedef struct mmap Mmap;
+X
+#endif /* APERTURE_H */
+SHAR_EOF
+chmod 0644 aperture/aperture.h ||
+echo 'restore of aperture/aperture.h failed'
+Wc_c="`wc -c < 'aperture/aperture.h'`"
+test 4042 -eq "$Wc_c" ||
+ echo 'aperture/aperture.h: original size 4042, current size' "$Wc_c"
+fi
+# ============= aperture/devlink.tab ==============
+if test -f 'aperture/devlink.tab' -a X"$1" != X"-c"; then
+ echo 'x - skipping aperture/devlink.tab (File already exists)'
+else
+echo 'x - extracting aperture/devlink.tab (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'aperture/devlink.tab' &&
+# The following entry is for the SVGA framebuffer driver
+type=ddi_pseudo;name=aperture fbs/\M0
+SHAR_EOF
+chmod 0644 aperture/devlink.tab ||
+echo 'restore of aperture/devlink.tab failed'
+Wc_c="`wc -c < 'aperture/devlink.tab'`"
+test 95 -eq "$Wc_c" ||
+ echo 'aperture/devlink.tab: original size 95, current size' "$Wc_c"
+fi
+# ============= aperture/README ==============
+if test -f 'aperture/README' -a X"$1" != X"-c"; then
+ echo 'x - skipping aperture/README (File already exists)'
+else
+echo 'x - extracting aperture/README (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'aperture/README' &&
+Framebuffer apperture driver.
+X
+(Note, see the DISCLAIMER file before using this driver!
+X - Sorry, we've gotta cover ourselves)
+X
+This driver was written to help work around one particular limitation in the
+x86 /dev/mem driver.
+X
+1) No Solaris x86 device we've found allows access to memory regions that
+X exist above the amount of RAM in the machine. So one could not
+X access the linear frame buffer of a Mach32 VLB board that decodes
+X is memory aperture at the 124Megabyte mark.
+X
+This driver attempts to work around some of those problems. All it simply
+does is allow a user to mmap() any physical address less than 128Megs
+back into user address space.
+X
+It is the corroborative work of Doug Anson (danson@lgc.com), and
+David Holland (davidh@use.com).
+X
+Many thanks to the XFree86[tm] Alpha, and Beta teams, for without
+all their hard work, there wouldn't be any need for this driver.
+X
+Installation instructions:
+X
+1) Check the Makefile, for appropriate CC, and CFLAGS defintions.
+X Compiling with APERTURE_DEBUG defined (via -DAPERTURE_DEBUG=?) means
+X the driver will generate reams of debugging output. You'll probably
+X want to leave this off, or set to zero..
+X
+2) type 'make'. The driver and test program should compile with out any
+X problems. There also should not be any warning messages.
+X
+3) Become 'root'.
+X
+4) type 'make install' and run 'add_drv /kernel/drv/aperture'.
+X The screen should look something like this:
+X
+X # make install
+X cp aperture aperture.conf /kernel/drv
+X # add_drv /kernel/drv/aperture
+X
+X This installs the driver in the system.
+X
+5) While as root modify the file /etc/devlink.tab, adding these lines:
+X
+# The following entry is for the SVGA framebuffer driver
+type=ddi_pseudo;name=aperture fbs/\M0
+X
+X Add that line exactly as shown. You may also simply add the
+X contents of the devlink.tab file supplied to /etc/devlink.tab.
+X It contains the lines as well. (Yes, that is a tab between
+X aperture, and fbs, not spaces - very important)
+X
+6) Perform a reconfiguration boot of the system.
+X
+X # touch /reconfigure
+X # init 6
+X
+7) Login as root and run the aptest program. It tests that the
+X mmap driver is working properly, by mmaping the main bios
+X into user address space. If you happen to have AMI bios the
+X output will look something like so:
+X
+# ./aptest
+NOTICE: BIOS mapped [0xf0000 ,size=4096) to addr=0x8000b000...
+0123AAAAMMMMIIII05/05/91(C)1990 American Megatrends Inc., All Rights Reserved
+DONE displaying memory contents (80 bytes)
+UNMAPPING [0xf0000 ,size=4096) to addr=0x8000b000... and closing...DONE.
+Exiting successful...
+#
+X
+X
+8) Nope, there are not any man pages, I don't know nroff. As for programming
+X suggestions, take a look at aptest.c a working example is obviously
+X in there.
+X
+Bug reports, questions, suggestions, etc can be sent to
+X
+Doug Anson
+danson@lgc.com
+X
+X or
+X
+David Holland
+davidh@use.com
+X
+Flames can be sent to
+/dev/null
+SHAR_EOF
+chmod 0644 aperture/README ||
+echo 'restore of aperture/README failed'
+Wc_c="`wc -c < 'aperture/README'`"
+test 2914 -eq "$Wc_c" ||
+ echo 'aperture/README: original size 2914, current size' "$Wc_c"
+fi
+# ============= aperture/aperture.c ==============
+if test -f 'aperture/aperture.c' -a X"$1" != X"-c"; then
+ echo 'x - skipping aperture/aperture.c (File already exists)'
+else
+echo 'x - extracting aperture/aperture.c (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'aperture/aperture.c' &&
+/*
+X * Copyright 1994 Doug Anson, danson@lgc.com & David Holland, davidh@use.com
+X *
+X * File: aperture.c
+X * Author: Doug Anson (danson@lgc.com)
+X * Date: 1/31/94
+X *
+X * Modified: David Holland (davidh@use.com)
+X * Date: 2/23/94
+X * Changes: Changed general name of driver
+X * Debugging flags
+X * Removed a few extraneous erorr messages.
+X *
+X *
+X * Purpose: This file is the master device file for the Solaris 2.1 x86
+X * framebuffer aperture driver. Portions of this driver are taken
+X * from mmap.c 1.4 copyright 93/06/03 Sun Microsystems, Inc.
+X * (Sample memory mapped driver for Solaris 2.0/Sun OS 5.0)
+X *
+X * This driver allows accelerated SVGA graphics cards that are
+X * attached vi 32-bit paths (VESA/EISA/MC) and that have
+X * linear framebuffer capabilities to have their framebuffer
+X * memory mapped into the user process space.
+X *
+X * Disclamer:
+X *
+X * This code is based largely upon the sample device drivers provided
+X * by Sun Microsystems Inc.
+X *
+X * Original copyright notice:
+X * @(#)mmap.c 1.3 copyright 93/06/03 Sun Microsystems, Inc.
+X *
+X * Our copyright notice:
+X * Permission to use, copy, modify, distribute, and sell this software and its
+X * documentation for any purpose is hereby granted without fee, provided that
+X * the above copyright notice appear in all copies and that both that
+X * copyright notice and this permission notice appear in supporting
+X * documentation, and that the name of Doug Anson, and David Holland be used in
+X * advertising or publicity pertaining to distribution of the software
+X * Doug Anson, and David Holland make no * representations about the
+X * suitability of this software for any purpose.
+X * It is provided "as is" without express or implied warranty.
+X *
+X * Original disclamer from Sun Microsystems, Inc.:
+X * This is a package of sample device drivers for Solaris 2.x (SunOS
+X * 5.x). You may use, modify and distribute these drivers and/or binaries
+X * derived from them. However please note that:
+X *
+X * These examples are provided with no warranties of any kind, including
+X * without limitation accuracy and usefulness, and Sun expressly disclaims
+X * all implied warranties of merchantability, fitness for a particular
+X * purpose and non-infringement. In no event shall Sun be liable for any
+X * damages, including without limitation, direct, special, indirect, or
+X * consequential damages arising out of, or relating to, use of these
+X * examples by customer or any third party. Sun is under no obligation to
+X * provide support to customer for this software.
+X *
+X * Our disclaimer:
+X * DOUG ANSON, AND DAVID HOLLAND DISCLAIMS ALL WARRIENTS WITH REGARD TO THIS
+X * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS,
+X * IN NO EVENT SHALL DOUG ANSON, OR DAVID HOLLAND BE LIABLE FOR ANY SPECIAL,
+X * INDIRECT, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM
+X * USAGE OF THIS SOFTWARE.
+X */
+X
+/*
+X * linear framebuffer aperture driver
+X *
+X * $Id
+X */
+X
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/file.h>
+#include <sys/conf.h>
+#include <sys/uio.h>
+#include <sys/map.h>
+#include <sys/debug.h>
+#include <sys/modctl.h>
+#include <sys/kmem.h>
+#include <sys/cmn_err.h>
+#include <sys/open.h>
+#include <sys/stat.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+X
+#include "aperture.h"
+X
+/* opaque handle top of state structs */
+static void *state_head = NULL;
+X
+/*
+X * Solaris DDI/DKI driver entry points
+X */
+#if defined(__STDC__)
+static int aperture_getinfo(dev_info_t *, ddi_info_cmd_t, void *,void **);
+static int aperture_identify(dev_info_t *dip);
+static int aperture_probe(dev_info_t *dip);
+static int aperture_attach(dev_info_t *, ddi_attach_cmd_t);
+static int aperture_open(dev_t *, int, int, cred_t *);
+static int aperture_close(dev_t, int, int, cred_t *);
+static int aperture_detach(dev_info_t *, ddi_detach_cmd_t);
+static int aperture_mmap(dev_t, off_t, int);
+#else
+static int aperture_getinfo();
+static int aperture_identify();
+static int aperture_probe();
+static int aperture_attach();
+static int aperture_open();
+static int aperture_close();
+static int aperture_detach();
+static int aperture_mmap();
+#endif /* __STDC__ */
+X
+/*
+X * Solaris DDI/DKI module linkeage structure declarations
+X */
+static struct cb_ops aperture_cb_ops =
+{
+X aperture_open, /* XXopen routine */
+X aperture_close, /* XXclose routine */
+X nodev, /* XXstrategy routine */
+X nodev, /* XXprint routine */
+X nodev, /* XXdump routine */
+X nodev, /* XXread routine */
+X nodev, /* XXwrite routine */
+X nodev, /* XXioctl routine */
+X nodev, /* XXdevmap routine */
+X aperture_mmap, /* XXmmap routine */
+X ddi_segmap, /* XXsegmap routine */
+X nochpoll, /* XXchpoll routine */
+X ddi_prop_op, /* XXprop_op routine */
+X (struct streamtab *)0, /* not a STREAMS driver */
+X D_NEW | D_MP, /* safe for multi-thread/multi-processor*/
+};
+X
+static struct dev_ops aperture_ops =
+{
+X DEVO_REV, /* DEVO_REV indicated by manual */
+X 0, /* device reference count */
+X aperture_getinfo, /* devo_getinfo routine */
+X aperture_identify, /* devo_identiry routine */
+X aperture_probe, /* device probe for non-self-id */
+X aperture_attach, /* devo_attach routine */
+X aperture_detach, /* devo_detach routine */
+X nodev, /* device reset routine */
+X &aperture_cb_ops, /* cb_ops structure pointer */
+X (struct bus_ops *)0, /* bus operations */
+};
+X
+extern struct mod_ops mod_driverops;
+static struct modldrv modldrv =
+{
+X &mod_driverops, /* mod_ops structure pointer */
+X DEV_BANNER_STRING, /* device banner string */
+X &aperture_ops, /* dev_ops structure pointer */
+};
+X
+static struct modlinkage modlinkage =
+{
+X MODREV_1, /* as indicated indicated by manual */
+X (void *)&modldrv, /* module driver structure pointer */
+X NULL, /* termination of list of linkage structures */
+};
+X
+/*
+X * Function: _init()
+X * Purpose: Solaris DDI/DKI _init(9E) entry point
+X * Author: Doug Anson
+X * Calls:
+X * Log: DMA -- Origional Version
+X * DWH - Removed extra cmn_err() calls 2/23/94
+X * DWH - Changed debugging 2/23/94
+X */
+#if defined(__STDC__)
+int _init(void)
+#else
+int _init()
+#endif /* __STDC__ */
+{
+X register int error;
+X
+#if APERTURE_DEBUG >= 3
+X
+X /* enterance announcement */
+X cmn_err(CE_CONT,"%s: entering _init(aperture)\n", DEV_IDENT_STRING);
+X
+#endif
+X
+X if ((error = ddi_soft_state_init(&state_head, sizeof (Mmap), 1)) != 0)
+X {
+X /* failed to get state structure */
+X return (error);
+X }
+X
+X if ((error = mod_install(&modlinkage)) != 0)
+X ddi_soft_state_fini(&state_head);
+X
+X return (error);
+}
+X
+/*
+X * Function: _info()
+X * Purpose: Solaris DDI/DKI _info(9E) entry point
+X * Author: Doug Anson
+X * Calls:
+X * Modified: David Holland (davidh@use.com)
+X * Log: DMA -- Origional Version
+X * DWH - Changed debugging 2/23/94
+X */
+#if defined(__STDC__)
+int _info(struct modinfo *modinfop)
+#else
+int _info(modinfop)
+struct modinfo *modinfop;
+#endif /* __STDC__ */
+{
+X
+#if APERTURE_DEBUG >= 3
+X
+X /* entrance announcement */
+X cmn_err(CE_CONT,"%s: entering _info(aperture)\n", DEV_IDENT_STRING);
+X
+#endif /* APERTURE_DEBUG >= 3 */
+X
+X return (mod_info(&modlinkage, modinfop));
+}
+X
+/*
+X * Function: _fini()
+X * Purpose: Solaris DDI/DKI _fini(9E) entry point
+X * Author: Doug Anson
+X * Calls:
+X * Modified: David Holland (davidh@use.com)
+X * Log: DMA -- Origional Version
+X * DWH - Changed debugging
+X */
+#if defined(__STDC__)
+int _fini(void)
+#else
+int _fini()
+#endif /* __STDC__ */
+{
+X int status;
+X
+#if APERTURE_DEBUG >= 3
+X
+/* entrance announcement */
+cmn_err(CE_CONT,"%s: entering _fini(aperture)\n", DEV_IDENT_STRING);
+X
+#endif /* APERTURE_DEBUG >= 3*/
+X
+X if ((status = mod_remove(&modlinkage)) != 0)
+X return (status);
+X
+X ddi_soft_state_fini(&state_head);
+X
+X return (status);
+}
+X
+/*
+X * Function: aperture_getinfo()
+X * Purpose: This function provides the getinfo(9E) functionality
+X * Author: Doug Anson
+X * Calls:
+X * Modified: David Holland (davidh@use.com)
+X * Log: DMA -- Origional Version
+X * DWH - Changed function name/variables/debugging 2/23/94
+X */
+#if defined(__STDC__)
+static int aperture_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd,
+X void *arg, void **result)
+#else
+static int aperture_getinfo(dip,infocmd,arg,result)
+dev_info_t *dip;
+ddi_info_cmd_t infocmd;
+void *arg;
+void **result;
+#endif /* __STDC__ */
+{
+X register int error;
+X register Mmap *aperture_p = NULL;
+X
+#if APERTURE_DEBUG >= 3
+X
+X /* enterance announcement */
+X cmn_err(CE_CONT,"%s: entering aperture_getinfo()\n", DEV_IDENT_STRING);
+X
+#endif
+X
+X switch (infocmd)
+X {
+X case DDI_INFO_DEVT2DEVINFO:
+X aperture_p = (Mmap *)ddi_get_soft_state(state_head, getminor((dev_t)arg));
+X if (aperture_p == NULL)
+X {
+X /* could not get state structure */
+X *result = NULL;
+X error = DDI_FAILURE;
+X }
+X else
+X {
+X /* got state structure */
+X *result = aperture_p->dip;
+X error = DDI_SUCCESS;
+X }
+X break;
+X case DDI_INFO_DEVT2INSTANCE:
+X *result = (void *)getminor((dev_t)arg);
+X error = DDI_SUCCESS;
+X break;
+X default:
+X *result = NULL;
+X error = DDI_FAILURE;
+X break;
+X }
+X return (error);
+}
+X
+/*
+X * Function: aperture_identify()
+X * Purpose: This function implements the identify(9E) functionality
+X * Author: Doug Anson
+X * Calls:
+X * Modified: David Holland (davidh@use.com)
+X * Log: DMA -- Origional Version
+X * DWH - Changed function name/debugging/variables 2/23/94
+X */
+#if defined(__STDC__)
+static int aperture_identify(dev_info_t *dip)
+#else
+static int aperture_identify(dip)
+dev_info_t *dip;
+#endif /* __STDC__ */
+{
+#if APERTURE_DEBUG >= 3
+X
+X /* entrance announcement */
+X cmn_err(CE_CONT,"%s: entering aperture_identify()\n", DEV_IDENT_STRING);
+X
+#endif
+X
+X /* check the driver name and respond */
+X if (strcmp(ddi_get_name(dip), APERTURE_NAME) == 0)
+X return (DDI_IDENTIFIED); /* device driver is identified */
+X else
+X return (DDI_NOT_IDENTIFIED); /* device driver not identified */
+}
+X
+/*
+X * Function: aperture_probe()
+X * Purpose: This function implements the probe(9E) functionality.
+X * Currently this function returns a "dont care" result
+X * as nothing is probed.
+X * Author: Doug Anson
+X * Calls:
+X * Modfied: David Holland (davidh@use.com)
+X * Log: DMA -- Origional Version
+X * DWH - changed function name/variables/debugging 2/23/94
+X */
+#if defined(__STDC__)
+static int aperture_probe(dev_info_t *dip)
+#else
+static int aperture_probe(dip)
+dev_info_t *dip;
+#endif /* __STDC__ */
+{
+X
+#if APERTURE_DEBUG >= 3
+X
+X /* enterance announcement */
+X cmn_err(CE_CONT,"%s: entering aperture_probe()\n", DEV_IDENT_STRING);
+X
+#endif
+X
+X /* return success as we really aren't probing for anything */
+X return (DDI_PROBE_SUCCESS);
+}
+X
+/*
+X * Function: aperture_attach()
+X * Purpose: This function implements the attach(9E) functionality
+X * Author: Doug Anson
+X * Calls:
+X * Modified: David Holland (davidh@use.com)
+X * Log: DMA -- Origional Version
+X * DWH - changed function name/variables/debugging 2/23/94
+X */
+#if defined(__STDC__)
+static int aperture_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
+#else
+static int aperture_attach(dip,cmd)
+dev_info_t *dip;
+ddi_attach_cmd_t cmd;
+#endif /* __STDC__ */
+{
+X register Mmap *aperture_p = NULL;
+X int buf[AP_MAX];
+X int length;
+X int instance;
+X
+#if APERTURE_DEBUG >= 3
+X
+X /* entrance announcement */
+X cmn_err(CE_CONT,"%s: entering aperture_attach()\n", DEV_IDENT_STRING);
+X
+#endif
+X
+X /* only continue if doing a DDI_ATTACH */
+X if (cmd == DDI_ATTACH)
+X {
+X /* get and initialize our state structure */
+X instance = ddi_get_instance(dip);
+X if (ddi_soft_state_zalloc(state_head, instance) != DDI_SUCCESS)
+X {
+X /* could not allocate state structure */
+X return (DDI_FAILURE);
+X }
+X
+X /* get the state structure */
+X aperture_p = (Mmap *)ddi_get_soft_state(state_head, instance);
+X
+X if (aperture_p == NULL)
+X {
+X /* failed to get the soft state */
+X return (DDI_FAILURE);
+X }
+X
+X /* initialize the mutex driver (ATOMIC) */
+X mutex_init(&aperture_p->map_lock, "apperture mmap lock", MUTEX_DRIVER, 0);
+X
+X /* ENTER the critical region */
+X mutex_enter(&aperture_p->map_lock);
+X
+X /* get the "reg" property from the .conf file */
+X length = sizeof(buf);
+X if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "reg", (caddr_t)buf, &length) != DDI_PROP_SUCCESS)
+X {
+X /* could not get the framebuffer properties */
+X return (DDI_FAILURE);
+X }
+X
+X /* remember our register configuration */
+X aperture_p->regnum = (u_int)buf[AP_REGNUM];
+X aperture_p->regbase = (caddr_t)buf[AP_ADDR];
+X aperture_p->regsize = (off_t)buf[AP_SIZE];
+X
+X /* initialize the mmap state info */
+X aperture_p->reglength = (off_t)AP_MEM_CHUNK;
+X aperture_p->kaddr = (caddr_t)0;
+X aperture_p->off = (off_t)0;
+X aperture_p->mapaddr = AP_MEM_FAILURE;
+X
+X /* initialize internal accounting */
+X aperture_p->dip = dip;
+X
+X /* EXIT the critical region */
+X mutex_exit(&aperture_p->map_lock);
+X
+X /* create the device node */
+X /* DDI_PSEUDO, CLONE_DEV */
+X if (ddi_create_minor_node(dip, ddi_get_name(dip), S_IFCHR, instance, NULL, (int)NULL) == DDI_FAILURE)
+X {
+X /* failed to make the device leaf or in error state */
+X mutex_destroy(&aperture_p->map_lock);
+X ddi_soft_state_free(state_head, instance);
+X return (DDI_FAILURE);
+X }
+X
+X /* device driver attached successfully */
+X ddi_report_dev(aperture_p->dip);
+X return (DDI_SUCCESS);
+X }
+X else
+X {
+X /* command not DDI_ATTACH -- return failure */
+X return (DDI_FAILURE);
+X }
+}
+X
+/*
+X * Function: aperture_detach()
+X * Purpose: This function implements the detach(9E) functionality
+X * Author: Doug Anson
+X * Calls:
+X * Modified: David Holland (davidh@use.com)
+X * Log: DMA -- Origional Version
+X * DWH - changed function name/variables/debugging 2/23/94
+X */
+#if defined(__STDC__)
+static int aperture_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
+#else
+static int aperture_detach(dip,cmd)
+dev_info_t *dip;
+ddi_detach_cmd_t cmd;
+#endif /* __STDC__ */
+{
+X register Mmap *aperture_p = NULL;
+X int instance;
+X
+#if APERTURE_DEBUG >= 3
+X
+X /* entrance announcement */
+X cmn_err(CE_CONT,"%s: entering aperture_detach()\n", DEV_IDENT_STRING);
+X
+#endif
+X
+X /* check the parameter list */
+X if (cmd != DDI_DETACH)
+X {
+X return (DDI_FAILURE);
+X }
+X
+X /* get the instance info and state structure */
+X instance = ddi_get_instance(dip);
+X aperture_p = (Mmap *)ddi_get_soft_state(state_head, instance);
+X if (aperture_p == NULL)
+X {
+X /* failed to get the soft state */
+X return (DDI_FAILURE);
+X }
+X
+X /* clean up the driver */
+X mutex_destroy(&aperture_p->map_lock);
+X ddi_remove_minor_node(dip, NULL);
+X ddi_soft_state_free(state_head, instance);
+X
+X /* device driver detached successfully */
+X return (DDI_SUCCESS);
+}
+X
+/*
+X * Function: aperture_open()
+X * Purpose: This function is called in response to the open(2) system call
+X * Author: Doug Anson
+X * Calls:
+X * Modified: David Holland (davidh@use.com)
+X * Log: DMA -- Origional Version
+X * DWH - Changed function name/variables/debugging
+X */
+#if defined(__STDC__)
+static int aperture_open(dev_t *dev, int openflags, int otyp, cred_t *credp)
+#else
+static int aperture_open(dev, openflags, otyp, credp)
+dev_t *dev;
+int openflags;
+int otyp;
+cred_t *credp;
+#endif /* __STDC__ */
+{
+X register Mmap *aperture_p = NULL;
+X
+#if APERTURE_DEBUG >= 3
+X
+X /* entrance announcement */
+X cmn_err(CE_CONT,"%s: entering aperture_open()\n", DEV_IDENT_STRING);
+X
+#endif
+X
+X /* get the state structure */
+X aperture_p = (Mmap *)ddi_get_soft_state(state_head, getminor(*dev));
+X if (aperture_p == NULL)
+X {
+X /* failed to get the soft state */
+X return (ENXIO);
+X }
+X
+X /* check the parameter list for correctness */
+X if (otyp != OTYP_CHR)
+X {
+X /* invalid parameter list */
+X return (EINVAL);
+X }
+X
+X return (0);
+}
+X
+/*
+X * Function: aperture_close()
+X * Purpose: This function is called after the last process that has
+X * the device open calls close(2)
+X * Author: Doug Anson
+X * Calls:
+X * Modified: David Holland (davidh@use.com)
+X * Log: DMA -- Origional Version
+X * DWH - changed function name/variables/debugging 2/23/94
+X */
+#if defined(__STDC__)
+static int aperture_close(dev_t dev, int closeflags, int otyp, cred_t *credp)
+#else
+static int aperture_close(dev, closeflags, otyp, credp)
+dev_t dev;
+int closeflags;
+int otyp;
+cred_t *credp;
+#endif /* __STDC__ */
+{
+X register Mmap *aperture_p = NULL;
+X
+#if APERTURE_DEBUG >= 3
+X
+X /* enterance announcement */
+X cmn_err(CE_CONT,"%s: entering aperture_close()\n", DEV_IDENT_STRING);
+X
+#endif
+X
+X /* get the state structure */
+X aperture_p = (Mmap *)ddi_get_soft_state(state_head, getminor(dev));
+X if (aperture_p == NULL)
+X {
+X /* failed to get the soft state */
+X return (ENXIO);
+X }
+X
+X /* check the paramter list for correctness */
+X if (otyp != OTYP_CHR)
+X {
+X /* invalid parameter */
+X return (EINVAL);
+X }
+X
+X /* do nothing but return successful */
+X return (0);
+}
+X
+/*
+X * Function: aperture_mmap()
+X * Purpose: This function gets called when the user process tries to mmap
+X * the framebuffer device using mmap(2).
+X * Author: Doug Anson
+X * Calls:
+X * Modified: David Holland (davidh@use.com)
+X * Log: DMA -- Origional Version
+X * DWH - changed function name/variables/debugging 2/23/94
+X */
+#if defined(__STDC__)
+static int aperture_mmap(dev_t dev, off_t off, int prot)
+#else
+static int aperture_mmap(dev, off, prot)
+dev_t dev;
+off_t off;
+int prot;
+#endif /* __STDC__ */
+{
+X register Mmap *aperture_p = NULL;
+X
+#if APERTURE_DEBUG >= 3
+X
+X /* enterance announcement */
+X cmn_err(CE_CONT,"%s: entering aperture_mmap()\n", DEV_IDENT_STRING);
+X
+#endif
+X
+X /* get the state structure */
+X aperture_p = (Mmap *)ddi_get_soft_state(state_head, getminor(dev));
+X if (aperture_p == NULL)
+X {
+X /* failed to get the soft state */
+X return (AP_MEM_FAILURE);
+X }
+X
+X /* check that we dont mmap out of bounds */
+X if (off > aperture_p->regsize)
+X {
+X /* offset is out of range for register length */
+X return (AP_MEM_FAILURE);
+X }
+X
+X /* check that READ/WRITE only priv only */
+X if (!((prot & PROT_READ) || (prot & PROT_WRITE)))
+X {
+X /* invalid prot parameter in mmap(2) call */
+X return (AP_MEM_FAILURE);
+X }
+X
+X /* ENTER the critical region */
+X mutex_enter(&aperture_p->map_lock);
+X
+X /* map the registers CRITICAL REGION ASSIGNMENT */
+X
+X aperture_p->off = off;
+X if (ddi_map_regs(aperture_p->dip, aperture_p->regnum, (caddr_t *)&(aperture_p->kaddr),
+X aperture_p->off, aperture_p->reglength) == DDI_FAILURE)
+X {
+X
+#if APERTURE_DEBUG >= 2
+X
+X /* report error */
+X cmn_err(CE_CONT, "%s: ERROR: mmap failed (map regs). kaddr=0x%x off=0x%x\n",
+X DEV_IDENT_STRING,aperture_p->kaddr,aperture_p->off);
+X
+#endif
+X
+X aperture_p->mapaddr = (off_t)AP_MEM_FAILURE;
+X }
+X else
+X {
+X /* fill in our state structure CRITICAL REGION ASSIGNMENT */
+X aperture_p->mapaddr = (off_t)hat_getkpfnum((caddr_t)aperture_p->kaddr);
+X if ((u_int)aperture_p->mapaddr == (u_int)AP_MEM_FAILURE)
+X {
+X
+#if APERTURE_DEBUG >= 2
+X
+X /* report error */
+X cmn_err(CE_CONT, "%s: ERROR: mmap failed (kpf). kaddr=0x%x off=0x%x\n",
+X DEV_IDENT_STRING,aperture_p->kaddr,aperture_p->off);
+#endif
+X
+X }
+X
+X /* now unmap the region CRITICAL REGION ASSIGNMENT */
+X
+X ddi_unmap_regs(aperture_p->dip, aperture_p->regnum, (caddr_t *)&(aperture_p->kaddr),
+X aperture_p->off, aperture_p->reglength);
+X
+#if APERTURE_DEBUG >= 2
+X /* report register mmaping status */
+X if (aperture_p->mapaddr != AP_MEM_FAILURE)
+X {
+X /* mmap successful */
+X cmn_err(CE_CONT,"%s: mmap [off=0x%x,length=0x%x) successful\n",
+X DEV_IDENT_STRING,aperture_p->off,aperture_p->regsize);
+X
+X cmn_err(CE_CONT,"%s: configuration:\n",DEV_IDENT_STRING);
+X cmn_err(CE_CONT," REG(%d): regbase=0x%x regsize=0x%x\n",
+X aperture_p->regnum, aperture_p->regbase, aperture_p->regsize);
+X
+X cmn_err(CE_CONT," kaddr=0x%x mmap off=0x%x mmap addr=0x%x\n",
+X aperture_p->kaddr, aperture_p->off, aperture_p->mapaddr);
+X }
+X else
+X {
+X /* error in mmap routine */
+X cmn_err(CE_CONT,"%s: mmap not established due to errors", DEV_IDENT_STRING);
+X }
+#endif
+X
+X }
+X
+X /* EXIT the critical region */
+X mutex_exit(&aperture_p->map_lock);
+X
+X /* return the page frame number (PFN) */
+X
+#if APERTURE_DEBUG >= 3
+X
+X /* report exit - determining where the long delay is... */
+X cmn_err(CE_CONT, "%s: _mmap routine exiting\n", DEV_IDENT_STRING);
+X
+#endif
+X
+X return ((int)(aperture_p->mapaddr));
+}
+SHAR_EOF
+chmod 0644 aperture/aperture.c ||
+echo 'restore of aperture/aperture.c failed'
+Wc_c="`wc -c < 'aperture/aperture.c'`"
+test 20528 -eq "$Wc_c" ||
+ echo 'aperture/aperture.c: original size 20528, current size' "$Wc_c"
+fi
+# ============= aperture/aperture.conf ==============
+if test -f 'aperture/aperture.conf' -a X"$1" != X"-c"; then
+ echo 'x - skipping aperture/aperture.conf (File already exists)'
+else
+echo 'x - extracting aperture/aperture.conf (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'aperture/aperture.conf' &&
+#
+# Copyright 1994 Doug Anson, danson@lgc.com & David Holland, davidh@use.com
+#
+# File: aperture.conf
+# Author: Doug Anson (danson@lgc.com)
+#
+# Modified: David Holland (davidh@use.com)
+# Log: Change comments 2/23/94
+# Log: Change defaults/comments 9/25/94
+#
+# Purpose: This conf file is used by the aperture Framebuffer aperture
+# driver. Do NOT! change the first two numbers of of
+# the 'reg' property. They should be 0, and 0x0,
+# respectivly.
+#
+name="aperture" class="sysbus" reg=0,0x0,0x7fffffff;
+SHAR_EOF
+chmod 0644 aperture/aperture.conf ||
+echo 'restore of aperture/aperture.conf failed'
+Wc_c="`wc -c < 'aperture/aperture.conf'`"
+test 518 -eq "$Wc_c" ||
+ echo 'aperture/aperture.conf: original size 518, current size' "$Wc_c"
+fi
+# ============= aperture/aptest.c ==============
+if test -f 'aperture/aptest.c' -a X"$1" != X"-c"; then
+ echo 'x - skipping aperture/aptest.c (File already exists)'
+else
+echo 'x - extracting aperture/aptest.c (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'aperture/aptest.c' &&
+/*
+X * Copyright 1994 Doug Anson, danson@lgc.com & David Holland, davidh@use.com
+X *
+X * Author: Doug Anson (danson@lgc.com)
+X * Date : 2/21/94
+X * Modifed: David Holland (davidh@use.com)
+X * Log:
+X * DWH - Changed names/added comments 2/23/94
+X * DWH - Removed annoying delays. 2/23/94
+X *
+X * This program test the fb aperture driver by 'cheating'
+X * it uses the aperture driver to access/read the main
+X * system BIOS header
+X *
+X * Copyright notice:
+X * Permission to use, copy, modify, distribute, and sell this software and its
+X * documentation for any purpose is hereby granted without fee, provided that
+X * the above copyright notice appear in all copies and that both that
+X * copyright notice and this permission notice appear in supporting
+X * documentation, and that the name of Doug Anson, and David Holland be used in
+X * advertising or publicity pertaining to distribution of the software
+X * Doug Anson, and David Holland make no * representations about the
+X * suitability of this software for any purpose.
+X * It is provided "as is" without express or implied warranty.
+X *
+X * Disclaimer:
+X * DOUG ANSON, AND DAVID HOLLAND DISCLAIMS ALL WARRIENTS WITH REGARD TO THIS
+X * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS,
+X * IN NO EVENT SHALL DOUG ANSON, OR DAVID HOLLAND BE LIABLE FOR ANY SPECIAL,
+X * INDIRECT, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM
+X * USAGE OF THIS SOFTWARE.
+X */
+X
+/*
+X * linear framebuffer aperture driver test program
+X */
+X
+/*
+X * $Id
+X */
+X
+X
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+X
+#if !defined(sun)
+extern void exit(int);
+extern caddr_t mmap();
+extern int close();
+extern int munmap();
+#endif
+X
+/* framebuffer access defines */
+#define AP_DEV "/dev/fbs/aperture" /* framebuffer apperture device */
+#define PADDR 0xf0000 /* offset from fbmem base */
+#define BUF_LENGTH 0x1000 /* length in bytes -- ignored */
+X
+/* debug testing defines */
+#define START_INDEX 0 /* display starting index(>=0)*/
+#define STOP_INDEX 80 /* display stopping index */
+#define INCR 1 /* display increment */
+X
+/* main program */
+int main(int argc,char **argv)
+{
+X caddr_t addr = (caddr_t)0;
+X int fb_dev;
+X long start = START_INDEX;
+X long stop = STOP_INDEX;
+X int i;
+X
+X /* open the framebuffer device */
+X fb_dev = open (AP_DEV,O_RDWR);
+X if (fb_dev < 0)
+X {
+X /* failed to open framebuffer driver */
+X printf("ERROR: failed to open %s\n",AP_DEV);
+X perror("ERROR: open()");
+X exit(1);
+X }
+X
+X /* memory map the framebuffer */
+X addr = (caddr_t)mmap((caddr_t)0,BUF_LENGTH,PROT_READ|PROT_WRITE,MAP_SHARED,
+X fb_dev,(off_t)PADDR);
+X if (addr == (caddr_t)-1)
+X {
+X /* failed to memory map framebuffer driver */
+X printf("ERROR: failed to mmap [0x%x ,size=%d bytes)\n",
+X PADDR,BUF_LENGTH);
+X perror("ERROR: mmap()");
+X close(fb_dev);
+X exit(1);
+X }
+X else
+X {
+X /* frame buffer mapped */
+X close(fb_dev);
+X printf("NOTICE: BIOS mapped [0x%x ,size=%d) to addr=0x%x...\n",
+X PADDR,BUF_LENGTH,(int)addr);
+X
+X /* display the buffer */
+X for(i=start;i<stop;i=i+INCR)
+X printf("%c",addr[i]);
+X /* printf("addr[%d]=%c\n",i,addr[i]);
+X */
+X printf("\nDONE displaying memory contents (%d bytes)\n",stop);
+X
+X /* unmap and close */
+X printf("UNMAPPING [0x%x ,size=%d) to addr=0x%x... and closing...",
+X PADDR,BUF_LENGTH,(int)addr);
+X munmap(addr,BUF_LENGTH);
+X printf("DONE.\n");
+X printf("Exiting successful...\n");
+X exit(0);
+X }
+X return 1;
+}
+SHAR_EOF
+chmod 0644 aperture/aptest.c ||
+echo 'restore of aperture/aptest.c failed'
+Wc_c="`wc -c < 'aperture/aptest.c'`"
+test 3530 -eq "$Wc_c" ||
+ echo 'aperture/aptest.c: original size 3530, current size' "$Wc_c"
+fi
+# ============= aperture/DISCLAIMER ==============
+if test -f 'aperture/DISCLAIMER' -a X"$1" != X"-c"; then
+ echo 'x - skipping aperture/DISCLAIMER (File already exists)'
+else
+echo 'x - extracting aperture/DISCLAIMER (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'aperture/DISCLAIMER' &&
+/*
+X * Copyright 1994 Doug Anson (danson@lgc.com) & David Holland (davidh@use.com)
+X *
+X * This code is based largely upon the sample device drivers provided
+X * by Sun Microsystems Inc.
+X *
+X * Original copyright notice:
+X * @(#)mmap.c 1.3 copyright 93/06/03 Sun Microsystems, Inc.
+X *
+X * Our copyright notice:
+X * Permission to use, copy, modify, distribute, and sell this software and its
+X * documentation for any purpose is hereby granted without fee, provided that
+X * the above copyright notice appear in all copies and that both that
+X * copyright notice and this permission notice appear in supporting
+X * documentation, and that the name of Doug Anson, and David Holland be used in
+X * advertising or publicity pertaining to distribution of the software
+X * Doug Anson, and David Holland make no * representations about the
+X * suitability of this software for any purpose.
+X * It is provided "as is" without express or implied warranty.
+X *
+X * Original disclamer from Sun Microsystems, Inc.:
+X * This is a package of sample device drivers for Solaris 2.x (SunOS
+X * 5.x). You may use, modify and distribute these drivers and/or binaries
+X * derived from them. However please note that:
+X *
+X * These examples are provided with no warranties of any kind, including
+X * without limitation accuracy and usefulness, and Sun expressly disclaims
+X * all implied warranties of merchantability, fitness for a particular
+X * purpose and non-infringement. In no event shall Sun be liable for any
+X * damages, including without limitation, direct, special, indirect, or
+X * consequential damages arising out of, or relating to, use of these
+X * examples by customer or any third party. Sun is under no obligation to
+X * provide support to customer for this software.
+X *
+X * Our disclaimer:
+X * DOUG ANSON, AND DAVID HOLLAND DISCLAIMS ALL WARRIENTS WITH REGARD TO THIS
+X * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS,
+X * IN NO EVENT SHALL DOUG ANSON, OR DAVID HOLLAND BE LIABLE FOR ANY SPECIAL,
+X * INDIRECT, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM
+X * USAGE OF THIS SOFTWARE.
+X */
+X
+/*
+X * linear framebuffer aperture driver
+X *
+X * $Id
+X */
+SHAR_EOF
+chmod 0644 aperture/DISCLAIMER ||
+echo 'restore of aperture/DISCLAIMER failed'
+Wc_c="`wc -c < 'aperture/DISCLAIMER'`"
+test 2174 -eq "$Wc_c" ||
+ echo 'aperture/DISCLAIMER: original size 2174, current size' "$Wc_c"
+fi
+exit 0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/8514-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/8514-list
new file mode 100644
index 000000000..66f089e22
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/8514-list
@@ -0,0 +1 @@
+bin/XF86_8514
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9480-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9480-list
new file mode 100644
index 000000000..8b87b0bb0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9480-list
@@ -0,0 +1 @@
+bin/XF98_NEC480
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9EGC-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9EGC-list
new file mode 100644
index 000000000..f6a3d7074
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9EGC-list
@@ -0,0 +1 @@
+bin/XF98_EGC
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9GA9-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9GA9-list
new file mode 100644
index 000000000..3a65c75b8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9GA9-list
@@ -0,0 +1 @@
+bin/XF98_GA968
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9GAN-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9GAN-list
new file mode 100644
index 000000000..5649527d6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9GAN-list
@@ -0,0 +1 @@
+bin/XF98_GANBWAP
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9LPW-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9LPW-list
new file mode 100644
index 000000000..1fbadfd30
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9LPW-list
@@ -0,0 +1 @@
+bin/XF98_PWLB
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9NKV-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9NKV-list
new file mode 100644
index 000000000..459b09119
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9NKV-list
@@ -0,0 +1 @@
+bin/XF98_NKVNEC
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9NS3-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9NS3-list
new file mode 100644
index 000000000..33e814e46
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9NS3-list
@@ -0,0 +1 @@
+bin/XF98_NECS3
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9SPW-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9SPW-list
new file mode 100644
index 000000000..60b73a1cd
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9SPW-list
@@ -0,0 +1 @@
+bin/XF98_PWSKB
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9TGU-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9TGU-list
new file mode 100644
index 000000000..0d282078d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9TGU-list
@@ -0,0 +1 @@
+bin/XF98_TGUI
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9WEP-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9WEP-list
new file mode 100644
index 000000000..04181bd73
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9WEP-list
@@ -0,0 +1 @@
+bin/XF98_WABEP
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9WS-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9WS-list
new file mode 100644
index 000000000..76f479ba6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9WS-list
@@ -0,0 +1 @@
+bin/XF98_WABS
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9WSN-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9WSN-list
new file mode 100644
index 000000000..9d345cc85
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/9WSN-list
@@ -0,0 +1 @@
+bin/XF98_WSNA
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/AGX-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/AGX-list
new file mode 100644
index 000000000..6f41acb86
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/AGX-list
@@ -0,0 +1 @@
+bin/XF86_AGX
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/I128-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/I128-list
new file mode 100644
index 000000000..2a8ba145b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/I128-list
@@ -0,0 +1 @@
+bin/XF86_I128
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Load-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Load-list
new file mode 100644
index 000000000..828581fdf
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Load-list
@@ -0,0 +1 @@
+bin/XF86_LOADER
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Ma32-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Ma32-list
new file mode 100644
index 000000000..12323fb0d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Ma32-list
@@ -0,0 +1 @@
+bin/XF86_Mach32
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Ma64-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Ma64-list
new file mode 100644
index 000000000..7f7501533
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Ma64-list
@@ -0,0 +1 @@
+bin/XF86_Mach64
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Ma8-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Ma8-list
new file mode 100644
index 000000000..6a6a6f443
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Ma8-list
@@ -0,0 +1 @@
+bin/XF86_Mach8
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Mono-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Mono-list
new file mode 100644
index 000000000..06ef98d26
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/Mono-list
@@ -0,0 +1 @@
+bin/XF86_Mono
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/P9K-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/P9K-list
new file mode 100644
index 000000000..be9adab58
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/P9K-list
@@ -0,0 +1 @@
+bin/XF86_P9000
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/S3-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/S3-list
new file mode 100644
index 000000000..2ff889fc6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/S3-list
@@ -0,0 +1 @@
+bin/XF86_S3
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/S3V-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/S3V-list
new file mode 100644
index 000000000..8a7161906
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/S3V-list
@@ -0,0 +1 @@
+bin/XF86_S3V
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/SVGA-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/SVGA-list
new file mode 100644
index 000000000..bf3b71150
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/SVGA-list
@@ -0,0 +1 @@
+bin/XF86_SVGA
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/VG16-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/VG16-list
new file mode 100644
index 000000000..7d2e6163f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/VG16-list
@@ -0,0 +1 @@
+bin/XF86_VGA16
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/bin-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/bin-excl
new file mode 100644
index 000000000..c007d9590
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/bin-excl
@@ -0,0 +1,9 @@
+bin/XF86_*
+bin/XF98_*
+bin/XF86Setup
+bin/Xnest
+bin/Xprt
+bin/Xvfb
+bin/X
+bin/xfs
+bin/xmseconfig
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/bin-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/bin-list
new file mode 100644
index 000000000..1f6cca63c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/bin-list
@@ -0,0 +1,15 @@
+bin
+lib/libICE.so.6.3
+lib/libPEX5.so.6.0
+lib/libSM.so.6.0
+lib/libX11.so.6.1
+lib/libXIE.so.6.0
+lib/libXaw.so.6.1
+lib/libXext.so.6.3
+lib/libXi.so.6.0
+lib/libXmu.so.6.0
+lib/libXp.so.6.2
+lib/libXt.so.6.0
+lib/libXtst.so.6.1
+lib/liboldX.so.6.0
+lib/X11/app-defaults
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/dir b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/dir
new file mode 100644
index 000000000..11c5b9da7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/dir
@@ -0,0 +1 @@
+usr/X11R6
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/fsrv-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/fsrv-list
new file mode 100644
index 000000000..c1f479b23
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/fsrv-list
@@ -0,0 +1,3 @@
+bin/xfs
+lib/X11/fs
+man/man1/xfs.1.gz
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/host.def b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/host.def
new file mode 100644
index 000000000..ea725aae1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/host.def
@@ -0,0 +1,3 @@
+/*
+ * Host.def for building FreeBSD bindists
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/lib-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/lib-excl
new file mode 100644
index 000000000..3572f4206
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/lib-excl
@@ -0,0 +1,12 @@
+lib/X11/XF86Setup
+lib/X11/app-defaults
+lib/X11/config
+lib/X11/fonts
+lib/X11/fs
+lib/X11/xdm/GiveConsole
+lib/X11/xdm/TakeConsole
+lib/X11/xdm/X*
+lib/X11/xdm/xdm-*
+lib/X11/xinit
+lib/X11/doc
+lib/X11/XF86Setup
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/lib-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/lib-list
new file mode 100644
index 000000000..9673fea05
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/lib-list
@@ -0,0 +1,2 @@
+lib/X11
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/lkit-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/lkit-excl
new file mode 100644
index 000000000..6d7357c7b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/lkit-excl
@@ -0,0 +1,4 @@
+lib/Server/cnec480.sh
+lib/Server/ctgui.sh
+lib/Server/drivers98
+lib/Server/lib98
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/lkit-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/lkit-list
new file mode 100644
index 000000000..d1b39d97e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/lkit-list
@@ -0,0 +1 @@
+lib/Server
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/man-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/man-excl
new file mode 100644
index 000000000..13ac91d5f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/man-excl
@@ -0,0 +1,3 @@
+man/man1/XF86Setup.1.gz
+man/man1/xfs.1.gz
+man/man1/xmseconfig.1.gz
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/man-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/man-list
new file mode 100644
index 000000000..2a3700c15
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/man-list
@@ -0,0 +1 @@
+man
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/mod-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/mod-list
new file mode 100644
index 000000000..7054fc153
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/mod-list
@@ -0,0 +1 @@
+lib/modules
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/nest-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/nest-list
new file mode 100644
index 000000000..eff754d76
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/nest-list
@@ -0,0 +1 @@
+bin/Xnest
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/prog-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/prog-excl
new file mode 100644
index 000000000..113d220ef
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/prog-excl
@@ -0,0 +1,5 @@
+lib/Server
+lib/X11
+lib/lib*.so*
+lib/modules
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/prog-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/prog-list
new file mode 100644
index 000000000..059b71061
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/prog-list
@@ -0,0 +1,3 @@
+lib
+include
+lib/X11/config
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/prt-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/prt-list
new file mode 100644
index 000000000..0646e7927
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/prt-list
@@ -0,0 +1 @@
+bin/Xprt
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/set-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/set-list
new file mode 100644
index 000000000..3bb030a3f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/set-list
@@ -0,0 +1,5 @@
+bin/XF86Setup
+bin/xmseconfig
+lib/X11/XF86Setup
+man/man1/XF86Setup.1.gz
+man/man1/xmseconfig.1.gz
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/vfb-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/vfb-list
new file mode 100644
index 000000000..e2d161bbc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/FreeBSD/vfb-list
@@ -0,0 +1 @@
+bin/Xvfb
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin-excl
new file mode 100644
index 000000000..85a119884
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin-excl
@@ -0,0 +1,13 @@
+bin/XFree86
+bin/x*
+bin/XF86Setup
+bin/Xnest
+bin/Xprt
+bin/Xvfb
+bin/X
+bin/xfs
+bin/xdm
+bin/xmseconfig
+bin/*.Xaw3d
+bin/*.XawXPM
+lib/X11/app-defaults/Chooser
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin-list
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin-list
@@ -0,0 +1 @@
+bin
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin1-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin1-excl
new file mode 100644
index 000000000..a6d02a6c6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin1-excl
@@ -0,0 +1,14 @@
+bin/[A-Za-w]*
+bin/XF86_*
+bin/XF98_*
+bin/XF86Setup
+bin/Xnest
+bin/Xprt
+bin/Xvfb
+bin/X
+bin/xfs
+bin/xdm
+bin/xmseconfig
+bin/*.Xaw3d
+bin/*.XawXPM
+lib/X11/app-defaults/Chooser
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin1-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin1-list
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin1-list
@@ -0,0 +1 @@
+bin
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin2-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin2-excl
new file mode 100644
index 000000000..7e3259a3c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin2-excl
@@ -0,0 +1,13 @@
+bin/XF86_*
+bin/XF98_*
+bin/XF86Setup
+bin/Xnest
+bin/Xprt
+bin/Xvfb
+bin/X
+bin/xfs
+bin/xdm
+bin/xmseconfig
+bin/*.Xaw3d
+bin/*.XawXPM
+lib/X11/app-defaults/Chooser
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin2-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin2-list
new file mode 100644
index 000000000..7d6f8f8c3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/bin2-list
@@ -0,0 +1 @@
+lib/X11/app-defaults
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/dir b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/dir
new file mode 100644
index 000000000..11c5b9da7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/dir
@@ -0,0 +1 @@
+usr/X11R6
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/fsrv-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/fsrv-list
new file mode 100644
index 000000000..0752dba18
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/fsrv-list
@@ -0,0 +1,3 @@
+bin/xfs
+lib/X11/fs
+man/man1/xfs.1x.Z
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/lib-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/lib-excl
new file mode 100644
index 000000000..8c23da458
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/lib-excl
@@ -0,0 +1,9 @@
+lib/X11/XF86Setup
+lib/X11/app-defaults
+lib/X11/config
+lib/X11/fonts
+lib/X11/fs
+lib/X11/xdm
+lib/X11/xinit
+lib/X11/doc
+lib/X11/XF86Setup
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/lib-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/lib-list
new file mode 100644
index 000000000..9673fea05
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/lib-list
@@ -0,0 +1,2 @@
+lib/X11
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/man-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/man-excl
new file mode 100644
index 000000000..5fe5d4c01
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/man-excl
@@ -0,0 +1,3 @@
+man/man1/XF86Setup.1x.Z
+man/man1/xfs.1x.Z
+man/man1/xmseconfig.1x.Z
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/man-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/man-list
new file mode 100644
index 000000000..2a3700c15
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/man-list
@@ -0,0 +1 @@
+man
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/mod-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/mod-list
new file mode 100644
index 000000000..7054fc153
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/mod-list
@@ -0,0 +1 @@
+lib/modules
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/nest-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/nest-list
new file mode 100644
index 000000000..eff754d76
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/nest-list
@@ -0,0 +1 @@
+bin/Xnest
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/prog-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/prog-excl
new file mode 100644
index 000000000..d719810ec
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/prog-excl
@@ -0,0 +1,5 @@
+lib/X11
+lib/Server
+lib/lib*.so*
+lib/modules
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/prog-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/prog-list
new file mode 100644
index 000000000..059b71061
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/prog-list
@@ -0,0 +1,3 @@
+lib
+include
+lib/X11/config
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/prt-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/prt-list
new file mode 100644
index 000000000..0646e7927
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/prt-list
@@ -0,0 +1 @@
+bin/Xprt
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/set-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/set-list
new file mode 100644
index 000000000..23509474a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/set-list
@@ -0,0 +1,5 @@
+bin/XF86Setup
+bin/xmseconfig
+lib/X11/XF86Setup
+man/man1/XF86Setup.1x.Z
+man/man1/xmseconfig.1x.Z
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/vfb-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/vfb-list
new file mode 100644
index 000000000..e2d161bbc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/vfb-list
@@ -0,0 +1 @@
+bin/Xvfb
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/xdm-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/xdm-excl
new file mode 100644
index 000000000..a3a3efdbb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/xdm-excl
@@ -0,0 +1,2 @@
+lib/X11/xdm/xdm-errors
+lib/X11/xdm/xdm-pid
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/xdm-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/xdm-list
new file mode 100644
index 000000000..8fa75b158
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/xdm-list
@@ -0,0 +1,3 @@
+bin/xdm
+lib/X11/app-defaults/Chooser
+lib/X11/xdm
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/xserv-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/xserv-list
new file mode 100644
index 000000000..0035b6c30
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Interactive/xserv-list
@@ -0,0 +1 @@
+bin/XFree86
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/Load-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/Load-list
new file mode 100644
index 000000000..828581fdf
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/Load-list
@@ -0,0 +1 @@
+bin/XF86_LOADER
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/Ma64-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/Ma64-list
new file mode 100644
index 000000000..7f7501533
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/Ma64-list
@@ -0,0 +1 @@
+bin/XF86_Mach64
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/Mono-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/Mono-list
new file mode 100644
index 000000000..06ef98d26
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/Mono-list
@@ -0,0 +1 @@
+bin/XF86_Mono
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/P9K-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/P9K-list
new file mode 100644
index 000000000..be9adab58
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/P9K-list
@@ -0,0 +1 @@
+bin/XF86_P9000
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/S3-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/S3-list
new file mode 100644
index 000000000..2ff889fc6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/S3-list
@@ -0,0 +1 @@
+bin/XF86_S3
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/S3V-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/S3V-list
new file mode 100644
index 000000000..8a7161906
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/S3V-list
@@ -0,0 +1 @@
+bin/XF86_S3V
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/SVGA-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/SVGA-list
new file mode 100644
index 000000000..bf3b71150
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/SVGA-list
@@ -0,0 +1 @@
+bin/XF86_SVGA
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/TGA-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/TGA-list
new file mode 100644
index 000000000..8fa673b86
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/TGA-list
@@ -0,0 +1 @@
+bin/XF86_TGA
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/bin-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/bin-excl
new file mode 100644
index 000000000..c007d9590
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/bin-excl
@@ -0,0 +1,9 @@
+bin/XF86_*
+bin/XF98_*
+bin/XF86Setup
+bin/Xnest
+bin/Xprt
+bin/Xvfb
+bin/X
+bin/xfs
+bin/xmseconfig
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/bin-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/bin-list
new file mode 100644
index 000000000..32ff7414b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/bin-list
@@ -0,0 +1,38 @@
+bin
+lib/libICE.so.6.3
+lib/libICE.so.6
+lib/libICE.so
+lib/libPEX5.so.6.0
+lib/libPEX5.so.6
+lib/libPEX5.so
+lib/libSM.so.6.0
+lib/libSM.so.6
+lib/libSM.so
+lib/libX11.so.6.1
+lib/libX11.so.6
+lib/libX11.so
+lib/libXIE.so.6.0
+lib/libXIE.so.6
+lib/libXIE.so
+lib/libXaw.so.6.1
+lib/libXaw.so.6
+lib/libXaw.so
+lib/libXext.so.6.3
+lib/libXext.so.6
+lib/libXext.so
+lib/libXi.so.6.0
+lib/libXi.so.6
+lib/libXi.so
+lib/libXmu.so.6.0
+lib/libXmu.so.6
+lib/libXmu.so
+lib/libXp.so.6.2
+lib/libXp.so.6
+lib/libXp.so
+lib/libXt.so.6.0
+lib/libXt.so.6
+lib/libXt.so
+lib/libXtst.so.6.1
+lib/libXtst.so.6
+lib/libXtst.so
+lib/X11/app-defaults
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/dir b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/dir
new file mode 100644
index 000000000..11c5b9da7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/dir
@@ -0,0 +1 @@
+usr/X11R6
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/fsrv-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/fsrv-list
new file mode 100644
index 000000000..c70da7456
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/fsrv-list
@@ -0,0 +1,3 @@
+bin/xfs
+lib/X11/fs
+man/man1/xfs.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/host.def b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/host.def
new file mode 100644
index 000000000..ea725aae1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/host.def
@@ -0,0 +1,3 @@
+/*
+ * Host.def for building FreeBSD bindists
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/lib-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/lib-excl
new file mode 100644
index 000000000..3572f4206
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/lib-excl
@@ -0,0 +1,12 @@
+lib/X11/XF86Setup
+lib/X11/app-defaults
+lib/X11/config
+lib/X11/fonts
+lib/X11/fs
+lib/X11/xdm/GiveConsole
+lib/X11/xdm/TakeConsole
+lib/X11/xdm/X*
+lib/X11/xdm/xdm-*
+lib/X11/xinit
+lib/X11/doc
+lib/X11/XF86Setup
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/lib-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/lib-list
new file mode 100644
index 000000000..9673fea05
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/lib-list
@@ -0,0 +1,2 @@
+lib/X11
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/lkit-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/lkit-excl
new file mode 100644
index 000000000..6d7357c7b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/lkit-excl
@@ -0,0 +1,4 @@
+lib/Server/cnec480.sh
+lib/Server/ctgui.sh
+lib/Server/drivers98
+lib/Server/lib98
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/lkit-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/lkit-list
new file mode 100644
index 000000000..d1b39d97e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/lkit-list
@@ -0,0 +1 @@
+lib/Server
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/man-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/man-excl
new file mode 100644
index 000000000..81792cce1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/man-excl
@@ -0,0 +1,3 @@
+man/man1/XF86Setup.1x
+man/man1/xfs.1x
+man/man1/xmseconfig.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/man-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/man-list
new file mode 100644
index 000000000..2a3700c15
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/man-list
@@ -0,0 +1 @@
+man
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/mod-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/mod-list
new file mode 100644
index 000000000..7054fc153
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/mod-list
@@ -0,0 +1 @@
+lib/modules
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/nest-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/nest-list
new file mode 100644
index 000000000..eff754d76
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/nest-list
@@ -0,0 +1 @@
+bin/Xnest
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/prog-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/prog-excl
new file mode 100644
index 000000000..113d220ef
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/prog-excl
@@ -0,0 +1,5 @@
+lib/Server
+lib/X11
+lib/lib*.so*
+lib/modules
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/prog-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/prog-list
new file mode 100644
index 000000000..059b71061
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/prog-list
@@ -0,0 +1,3 @@
+lib
+include
+lib/X11/config
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/prt-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/prt-list
new file mode 100644
index 000000000..0646e7927
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/prt-list
@@ -0,0 +1 @@
+bin/Xprt
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/set-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/set-list
new file mode 100644
index 000000000..83d032807
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/set-list
@@ -0,0 +1,5 @@
+bin/XF86Setup
+bin/xmseconfig
+lib/X11/XF86Setup
+man/man1/XF86Setup.1x
+man/man1/xmseconfig.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/vfb-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/vfb-list
new file mode 100644
index 000000000..e2d161bbc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-axp/vfb-list
@@ -0,0 +1 @@
+bin/Xvfb
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/bin-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/bin-excl
new file mode 100644
index 000000000..4f85588ab
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/bin-excl
@@ -0,0 +1,8 @@
+bin/XFree86
+bin/XF86Setup
+bin/Xnest
+bin/Xprt
+bin/Xvfb
+bin/X
+bin/xfs
+bin/xmseconfig
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/bin-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/bin-list
new file mode 100644
index 000000000..f3a45ec7b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/bin-list
@@ -0,0 +1,52 @@
+bin
+lib/libICE.so.6.3
+lib/libICE.so.6
+lib/libICE.so
+lib/libPEX5.so.6.0
+lib/libPEX5.so.6
+lib/libPEX5.so
+lib/libSM.so.6.0
+lib/libSM.so.6
+lib/libSM.so
+lib/libX11.so.6.1
+lib/libX11.so.6
+lib/libX11.so
+lib/libXIE.so.6.0
+lib/libXIE.so.6
+lib/libXIE.so
+lib/libXaw.so.6.1
+lib/libXaw.so.6
+lib/libXaw.so
+lib/libXaw.so.7
+lib/libXaw.so.7.0
+lib/libXext.so.6.4
+lib/libXext.so.6
+lib/libXext.so
+lib/libXi.so.6.0
+lib/libXi.so.6
+lib/libXi.so
+lib/libXmu.so.6.0
+lib/libXmu.so.6
+lib/libXmu.so
+lib/libXp.so.6.2
+lib/libXp.so.6
+lib/libXp.so
+lib/libXt.so.6.0
+lib/libXt.so.6
+lib/libXt.so
+lib/libXtst.so.6.1
+lib/libXtst.so.6
+lib/libXtst.so
+lib/libGL.so
+lib/libGL.so.1
+lib/libGL.so.1.2
+lib/libXfont.so
+lib/libXfont.so.1
+lib/libXfont.so.1.0
+lib/libxrx.so
+lib/libxrx.so.6
+lib/libxrx.so.6.3
+lib/libXpm.so
+lib/libXpm.so.4
+lib/libXpm.so.4.11
+lib/X11/app-defaults
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/dir b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/dir
new file mode 100644
index 000000000..11c5b9da7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/dir
@@ -0,0 +1 @@
+usr/X11R6
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/fsrv-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/fsrv-list
new file mode 100644
index 000000000..c70da7456
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/fsrv-list
@@ -0,0 +1,3 @@
+bin/xfs
+lib/X11/fs
+man/man1/xfs.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/host.def b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/host.def
new file mode 100644
index 000000000..ea725aae1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/host.def
@@ -0,0 +1,3 @@
+/*
+ * Host.def for building FreeBSD bindists
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/lib-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/lib-excl
new file mode 100644
index 000000000..3572f4206
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/lib-excl
@@ -0,0 +1,12 @@
+lib/X11/XF86Setup
+lib/X11/app-defaults
+lib/X11/config
+lib/X11/fonts
+lib/X11/fs
+lib/X11/xdm/GiveConsole
+lib/X11/xdm/TakeConsole
+lib/X11/xdm/X*
+lib/X11/xdm/xdm-*
+lib/X11/xinit
+lib/X11/doc
+lib/X11/XF86Setup
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/lib-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/lib-list
new file mode 100644
index 000000000..9673fea05
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/lib-list
@@ -0,0 +1,2 @@
+lib/X11
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/man-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/man-excl
new file mode 100644
index 000000000..81792cce1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/man-excl
@@ -0,0 +1,3 @@
+man/man1/XF86Setup.1x
+man/man1/xfs.1x
+man/man1/xmseconfig.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/man-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/man-list
new file mode 100644
index 000000000..2a3700c15
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/man-list
@@ -0,0 +1 @@
+man
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/mod-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/mod-list
new file mode 100644
index 000000000..7054fc153
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/mod-list
@@ -0,0 +1 @@
+lib/modules
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/nest-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/nest-list
new file mode 100644
index 000000000..eff754d76
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/nest-list
@@ -0,0 +1 @@
+bin/Xnest
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/prog-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/prog-excl
new file mode 100644
index 000000000..113d220ef
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/prog-excl
@@ -0,0 +1,5 @@
+lib/Server
+lib/X11
+lib/lib*.so*
+lib/modules
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/prog-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/prog-list
new file mode 100644
index 000000000..059b71061
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/prog-list
@@ -0,0 +1,3 @@
+lib
+include
+lib/X11/config
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/prt-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/prt-list
new file mode 100644
index 000000000..0646e7927
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/prt-list
@@ -0,0 +1 @@
+bin/Xprt
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/sdk-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/sdk-list
new file mode 100644
index 000000000..d1b39d97e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/sdk-list
@@ -0,0 +1 @@
+lib/Server
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/set-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/set-list
new file mode 100644
index 000000000..83d032807
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/set-list
@@ -0,0 +1,5 @@
+bin/XF86Setup
+bin/xmseconfig
+lib/X11/XF86Setup
+man/man1/XF86Setup.1x
+man/man1/xmseconfig.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/vfb-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/vfb-list
new file mode 100644
index 000000000..e2d161bbc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/vfb-list
@@ -0,0 +1 @@
+bin/Xvfb
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/xserv-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/xserv-list
new file mode 100644
index 000000000..0035b6c30
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-ix86/xserv-list
@@ -0,0 +1 @@
+bin/XFree86
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/68FB-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/68FB-list
new file mode 100644
index 000000000..033141848
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/68FB-list
@@ -0,0 +1 @@
+bin/XF68_FBDev
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/bin-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/bin-excl
new file mode 100644
index 000000000..f1b0e119d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/bin-excl
@@ -0,0 +1,10 @@
+bin/XF68_*
+bin/XF86_*
+bin/XF98_*
+bin/XF86Setup
+bin/Xnest
+bin/Xprt
+bin/Xvfb
+bin/X
+bin/xfs
+bin/xmseconfig
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/bin-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/bin-list
new file mode 100644
index 000000000..46bf7d3d0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/bin-list
@@ -0,0 +1,39 @@
+bin
+lib/libICE.so.6.3
+lib/libICE.so.6
+lib/libICE.so
+lib/libPEX5.so.6.0
+lib/libPEX5.so.6
+lib/libPEX5.so
+lib/libSM.so.6.0
+lib/libSM.so.6
+lib/libSM.so
+lib/libX11.so.6.1
+lib/libX11.so.6
+lib/libX11.so
+lib/libXIE.so.6.0
+lib/libXIE.so.6
+lib/libXIE.so
+lib/libXaw.so.6.1
+lib/libXaw.so.6
+lib/libXaw.so
+lib/libXext.so.6.3
+lib/libXext.so.6
+lib/libXext.so
+lib/libXi.so.6.0
+lib/libXi.so.6
+lib/libXi.so
+lib/libXmu.so.6.0
+lib/libXmu.so.6
+lib/libXmu.so
+lib/libXp.so.6.2
+lib/libXp.so.6
+lib/libXp.so
+lib/libXt.so.6.0
+lib/libXt.so.6
+lib/libXt.so
+lib/libXtst.so.6.1
+lib/libXtst.so.6
+lib/libXtst.so
+lib/modules
+lib/X11/app-defaults
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/dir b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/dir
new file mode 100644
index 000000000..11c5b9da7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/dir
@@ -0,0 +1 @@
+usr/X11R6
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/fsrv-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/fsrv-list
new file mode 100644
index 000000000..c70da7456
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/fsrv-list
@@ -0,0 +1,3 @@
+bin/xfs
+lib/X11/fs
+man/man1/xfs.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/lib-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/lib-excl
new file mode 100644
index 000000000..3572f4206
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/lib-excl
@@ -0,0 +1,12 @@
+lib/X11/XF86Setup
+lib/X11/app-defaults
+lib/X11/config
+lib/X11/fonts
+lib/X11/fs
+lib/X11/xdm/GiveConsole
+lib/X11/xdm/TakeConsole
+lib/X11/xdm/X*
+lib/X11/xdm/xdm-*
+lib/X11/xinit
+lib/X11/doc
+lib/X11/XF86Setup
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/lib-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/lib-list
new file mode 100644
index 000000000..9673fea05
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/lib-list
@@ -0,0 +1,2 @@
+lib/X11
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/man-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/man-excl
new file mode 100644
index 000000000..81792cce1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/man-excl
@@ -0,0 +1,3 @@
+man/man1/XF86Setup.1x
+man/man1/xfs.1x
+man/man1/xmseconfig.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/man-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/man-list
new file mode 100644
index 000000000..2a3700c15
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/man-list
@@ -0,0 +1 @@
+man
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/nest-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/nest-list
new file mode 100644
index 000000000..eff754d76
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/nest-list
@@ -0,0 +1 @@
+bin/Xnest
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/prog-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/prog-excl
new file mode 100644
index 000000000..63d85c02e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/prog-excl
@@ -0,0 +1,4 @@
+lib/X11
+lib/lib*.so*
+lib/modules
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/prog-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/prog-list
new file mode 100644
index 000000000..059b71061
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/prog-list
@@ -0,0 +1,3 @@
+lib
+include
+lib/X11/config
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/prt-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/prt-list
new file mode 100644
index 000000000..0646e7927
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/prt-list
@@ -0,0 +1 @@
+bin/Xprt
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/vfb-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/vfb-list
new file mode 100644
index 000000000..e2d161bbc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Linux-m68k/vfb-list
@@ -0,0 +1 @@
+bin/Xvfb
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/8514-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/8514-list
new file mode 100644
index 000000000..66f089e22
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/8514-list
@@ -0,0 +1 @@
+bin/XF86_8514
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/AGX-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/AGX-list
new file mode 100644
index 000000000..6f41acb86
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/AGX-list
@@ -0,0 +1 @@
+bin/XF86_AGX
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/I128-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/I128-list
new file mode 100644
index 000000000..2a8ba145b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/I128-list
@@ -0,0 +1 @@
+bin/XF86_I128
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/Ma32-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/Ma32-list
new file mode 100644
index 000000000..12323fb0d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/Ma32-list
@@ -0,0 +1 @@
+bin/XF86_Mach32
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/Ma64-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/Ma64-list
new file mode 100644
index 000000000..7f7501533
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/Ma64-list
@@ -0,0 +1 @@
+bin/XF86_Mach64
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/Ma8-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/Ma8-list
new file mode 100644
index 000000000..6a6a6f443
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/Ma8-list
@@ -0,0 +1 @@
+bin/XF86_Mach8
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/Mono-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/Mono-list
new file mode 100644
index 000000000..06ef98d26
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/Mono-list
@@ -0,0 +1 @@
+bin/XF86_Mono
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/P9K-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/P9K-list
new file mode 100644
index 000000000..be9adab58
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/P9K-list
@@ -0,0 +1 @@
+bin/XF86_P9000
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/S3-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/S3-list
new file mode 100644
index 000000000..2ff889fc6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/S3-list
@@ -0,0 +1 @@
+bin/XF86_S3
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/S3V-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/S3V-list
new file mode 100644
index 000000000..8a7161906
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/S3V-list
@@ -0,0 +1 @@
+bin/XF86_S3V
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/SVGA-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/SVGA-list
new file mode 100644
index 000000000..bf3b71150
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/SVGA-list
@@ -0,0 +1 @@
+bin/XF86_SVGA
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/VG16-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/VG16-list
new file mode 100644
index 000000000..7d2e6163f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/VG16-list
@@ -0,0 +1 @@
+bin/XF86_VGA16
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/bin-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/bin-excl
new file mode 100644
index 000000000..08f6677d5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/bin-excl
@@ -0,0 +1,8 @@
+bin/XF86_*
+bin/XF86Setup
+bin/Xnest
+bin/Xprt
+bin/Xvfb
+bin/X
+bin/xfs
+bin/xmseconfig
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/bin-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/bin-list
new file mode 100644
index 000000000..083c3d1b5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/bin-list
@@ -0,0 +1,3 @@
+bin
+lib/modules
+lib/X11/app-defaults
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/dir b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/dir
new file mode 100644
index 000000000..11c5b9da7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/dir
@@ -0,0 +1 @@
+usr/X11R6
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/fsrv-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/fsrv-list
new file mode 100644
index 000000000..54f143c91
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/fsrv-list
@@ -0,0 +1,3 @@
+bin/xfs
+lib/X11/fs
+man/cat1/xfs.1
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/host.def b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/host.def
new file mode 100644
index 000000000..8ea3f7d55
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/host.def
@@ -0,0 +1,11 @@
+/*
+ * host.def for building LynxOS binary dists
+ *
+ * $XFree86: xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/host.def,v 1.2 1997/07/10 08:17:33 hohndel Exp $
+ */
+
+#define InstallEmptyHostDef
+
+#define HasTk YES
+#define HasTcl YES
+
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/lib-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/lib-excl
new file mode 100644
index 000000000..3572f4206
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/lib-excl
@@ -0,0 +1,12 @@
+lib/X11/XF86Setup
+lib/X11/app-defaults
+lib/X11/config
+lib/X11/fonts
+lib/X11/fs
+lib/X11/xdm/GiveConsole
+lib/X11/xdm/TakeConsole
+lib/X11/xdm/X*
+lib/X11/xdm/xdm-*
+lib/X11/xinit
+lib/X11/doc
+lib/X11/XF86Setup
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/lib-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/lib-list
new file mode 100644
index 000000000..9673fea05
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/lib-list
@@ -0,0 +1,2 @@
+lib/X11
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/lkit-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/lkit-excl
new file mode 100644
index 000000000..6d7357c7b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/lkit-excl
@@ -0,0 +1,4 @@
+lib/Server/cnec480.sh
+lib/Server/ctgui.sh
+lib/Server/drivers98
+lib/Server/lib98
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/lkit-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/lkit-list
new file mode 100644
index 000000000..d1b39d97e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/lkit-list
@@ -0,0 +1 @@
+lib/Server
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/man-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/man-excl
new file mode 100644
index 000000000..e91cc3e61
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/man-excl
@@ -0,0 +1,3 @@
+man/cat1/XF86Setup.1
+man/cat1/xfs.1
+man/cat1/xmseconfig.1
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/man-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/man-list
new file mode 100644
index 000000000..2a3700c15
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/man-list
@@ -0,0 +1 @@
+man
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/nest-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/nest-list
new file mode 100644
index 000000000..eff754d76
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/nest-list
@@ -0,0 +1 @@
+bin/Xnest
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/prog-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/prog-excl
new file mode 100644
index 000000000..9adb266a2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/prog-excl
@@ -0,0 +1,4 @@
+lib/Server
+lib/X11
+lib/modules
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/prog-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/prog-list
new file mode 100644
index 000000000..059b71061
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/prog-list
@@ -0,0 +1,3 @@
+lib
+include
+lib/X11/config
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/prt-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/prt-list
new file mode 100644
index 000000000..0646e7927
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/prt-list
@@ -0,0 +1 @@
+bin/Xprt
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/set-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/set-list
new file mode 100644
index 000000000..6d5d8a24f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/set-list
@@ -0,0 +1,5 @@
+bin/XF86Setup
+bin/xmseconfig
+lib/X11/XF86Setup
+man/cat1/XF86Setup.1
+man/cat1/xmseconfig.1
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/vfb-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/vfb-list
new file mode 100644
index 000000000..e2d161bbc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/LynxOS/vfb-list
@@ -0,0 +1 @@
+bin/Xvfb
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/8514-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/8514-list
new file mode 100644
index 000000000..66f089e22
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/8514-list
@@ -0,0 +1 @@
+bin/XF86_8514
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9480-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9480-list
new file mode 100644
index 000000000..8b87b0bb0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9480-list
@@ -0,0 +1 @@
+bin/XF98_NEC480
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9EGC-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9EGC-list
new file mode 100644
index 000000000..f6a3d7074
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9EGC-list
@@ -0,0 +1 @@
+bin/XF98_EGC
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9GA9-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9GA9-list
new file mode 100644
index 000000000..3a65c75b8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9GA9-list
@@ -0,0 +1 @@
+bin/XF98_GA968
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9GAN-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9GAN-list
new file mode 100644
index 000000000..5649527d6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9GAN-list
@@ -0,0 +1 @@
+bin/XF98_GANBWAP
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9LPW-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9LPW-list
new file mode 100644
index 000000000..1fbadfd30
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9LPW-list
@@ -0,0 +1 @@
+bin/XF98_PWLB
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9NKV-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9NKV-list
new file mode 100644
index 000000000..459b09119
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9NKV-list
@@ -0,0 +1 @@
+bin/XF98_NKVNEC
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9NS3-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9NS3-list
new file mode 100644
index 000000000..33e814e46
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9NS3-list
@@ -0,0 +1 @@
+bin/XF98_NECS3
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9SPW-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9SPW-list
new file mode 100644
index 000000000..60b73a1cd
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9SPW-list
@@ -0,0 +1 @@
+bin/XF98_PWSKB
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9TGU-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9TGU-list
new file mode 100644
index 000000000..0d282078d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9TGU-list
@@ -0,0 +1 @@
+bin/XF98_TGUI
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9WEP-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9WEP-list
new file mode 100644
index 000000000..04181bd73
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9WEP-list
@@ -0,0 +1 @@
+bin/XF98_WABEP
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9WS-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9WS-list
new file mode 100644
index 000000000..76f479ba6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9WS-list
@@ -0,0 +1 @@
+bin/XF98_WABS
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9WSN-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9WSN-list
new file mode 100644
index 000000000..9d345cc85
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/9WSN-list
@@ -0,0 +1 @@
+bin/XF98_WSNA
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/AGX-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/AGX-list
new file mode 100644
index 000000000..6f41acb86
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/AGX-list
@@ -0,0 +1 @@
+bin/XF86_AGX
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/I128-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/I128-list
new file mode 100644
index 000000000..2a8ba145b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/I128-list
@@ -0,0 +1 @@
+bin/XF86_I128
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Load-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Load-list
new file mode 100644
index 000000000..828581fdf
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Load-list
@@ -0,0 +1 @@
+bin/XF86_LOADER
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Ma32-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Ma32-list
new file mode 100644
index 000000000..12323fb0d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Ma32-list
@@ -0,0 +1 @@
+bin/XF86_Mach32
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Ma64-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Ma64-list
new file mode 100644
index 000000000..7f7501533
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Ma64-list
@@ -0,0 +1 @@
+bin/XF86_Mach64
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Ma8-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Ma8-list
new file mode 100644
index 000000000..6a6a6f443
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Ma8-list
@@ -0,0 +1 @@
+bin/XF86_Mach8
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Mono-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Mono-list
new file mode 100644
index 000000000..06ef98d26
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/Mono-list
@@ -0,0 +1 @@
+bin/XF86_Mono
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/P9K-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/P9K-list
new file mode 100644
index 000000000..be9adab58
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/P9K-list
@@ -0,0 +1 @@
+bin/XF86_P9000
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/S3-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/S3-list
new file mode 100644
index 000000000..2ff889fc6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/S3-list
@@ -0,0 +1 @@
+bin/XF86_S3
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/S3V-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/S3V-list
new file mode 100644
index 000000000..8a7161906
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/S3V-list
@@ -0,0 +1 @@
+bin/XF86_S3V
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/SVGA-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/SVGA-list
new file mode 100644
index 000000000..bf3b71150
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/SVGA-list
@@ -0,0 +1 @@
+bin/XF86_SVGA
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/VG16-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/VG16-list
new file mode 100644
index 000000000..7d2e6163f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/VG16-list
@@ -0,0 +1 @@
+bin/XF86_VGA16
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/bin-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/bin-excl
new file mode 100644
index 000000000..c007d9590
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/bin-excl
@@ -0,0 +1,9 @@
+bin/XF86_*
+bin/XF98_*
+bin/XF86Setup
+bin/Xnest
+bin/Xprt
+bin/Xvfb
+bin/X
+bin/xfs
+bin/xmseconfig
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/bin-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/bin-list
new file mode 100644
index 000000000..1f6cca63c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/bin-list
@@ -0,0 +1,15 @@
+bin
+lib/libICE.so.6.3
+lib/libPEX5.so.6.0
+lib/libSM.so.6.0
+lib/libX11.so.6.1
+lib/libXIE.so.6.0
+lib/libXaw.so.6.1
+lib/libXext.so.6.3
+lib/libXi.so.6.0
+lib/libXmu.so.6.0
+lib/libXp.so.6.2
+lib/libXt.so.6.0
+lib/libXtst.so.6.1
+lib/liboldX.so.6.0
+lib/X11/app-defaults
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/dir b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/dir
new file mode 100644
index 000000000..11c5b9da7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/dir
@@ -0,0 +1 @@
+usr/X11R6
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/fsrv-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/fsrv-list
new file mode 100644
index 000000000..c1f479b23
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/fsrv-list
@@ -0,0 +1,3 @@
+bin/xfs
+lib/X11/fs
+man/man1/xfs.1.gz
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/host.def b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/host.def
new file mode 100644
index 000000000..ea725aae1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/host.def
@@ -0,0 +1,3 @@
+/*
+ * Host.def for building FreeBSD bindists
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/lib-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/lib-excl
new file mode 100644
index 000000000..3572f4206
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/lib-excl
@@ -0,0 +1,12 @@
+lib/X11/XF86Setup
+lib/X11/app-defaults
+lib/X11/config
+lib/X11/fonts
+lib/X11/fs
+lib/X11/xdm/GiveConsole
+lib/X11/xdm/TakeConsole
+lib/X11/xdm/X*
+lib/X11/xdm/xdm-*
+lib/X11/xinit
+lib/X11/doc
+lib/X11/XF86Setup
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/lib-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/lib-list
new file mode 100644
index 000000000..9673fea05
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/lib-list
@@ -0,0 +1,2 @@
+lib/X11
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/lkit-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/lkit-excl
new file mode 100644
index 000000000..6d7357c7b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/lkit-excl
@@ -0,0 +1,4 @@
+lib/Server/cnec480.sh
+lib/Server/ctgui.sh
+lib/Server/drivers98
+lib/Server/lib98
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/lkit-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/lkit-list
new file mode 100644
index 000000000..d1b39d97e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/lkit-list
@@ -0,0 +1 @@
+lib/Server
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/man-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/man-excl
new file mode 100644
index 000000000..13ac91d5f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/man-excl
@@ -0,0 +1,3 @@
+man/man1/XF86Setup.1.gz
+man/man1/xfs.1.gz
+man/man1/xmseconfig.1.gz
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/man-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/man-list
new file mode 100644
index 000000000..2a3700c15
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/man-list
@@ -0,0 +1 @@
+man
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/mod-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/mod-list
new file mode 100644
index 000000000..7054fc153
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/mod-list
@@ -0,0 +1 @@
+lib/modules
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/nest-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/nest-list
new file mode 100644
index 000000000..eff754d76
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/nest-list
@@ -0,0 +1 @@
+bin/Xnest
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/prog-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/prog-excl
new file mode 100644
index 000000000..113d220ef
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/prog-excl
@@ -0,0 +1,5 @@
+lib/Server
+lib/X11
+lib/lib*.so*
+lib/modules
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/prog-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/prog-list
new file mode 100644
index 000000000..059b71061
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/prog-list
@@ -0,0 +1,3 @@
+lib
+include
+lib/X11/config
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/prt-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/prt-list
new file mode 100644
index 000000000..0646e7927
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/prt-list
@@ -0,0 +1 @@
+bin/Xprt
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/set-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/set-list
new file mode 100644
index 000000000..3bb030a3f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/set-list
@@ -0,0 +1,5 @@
+bin/XF86Setup
+bin/xmseconfig
+lib/X11/XF86Setup
+man/man1/XF86Setup.1.gz
+man/man1/xmseconfig.1.gz
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/vfb-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/vfb-list
new file mode 100644
index 000000000..e2d161bbc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/NetBSD-ix86/vfb-list
@@ -0,0 +1 @@
+bin/Xvfb
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/8514-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/8514-list
new file mode 100644
index 000000000..66f089e22
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/8514-list
@@ -0,0 +1 @@
+bin/XF86_8514
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/AGX-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/AGX-list
new file mode 100644
index 000000000..6f41acb86
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/AGX-list
@@ -0,0 +1 @@
+bin/XF86_AGX
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/I128-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/I128-list
new file mode 100644
index 000000000..2a8ba145b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/I128-list
@@ -0,0 +1 @@
+bin/XF86_I128
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/Ma32-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/Ma32-list
new file mode 100644
index 000000000..12323fb0d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/Ma32-list
@@ -0,0 +1 @@
+bin/XF86_Mach32
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/Ma64-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/Ma64-list
new file mode 100644
index 000000000..7f7501533
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/Ma64-list
@@ -0,0 +1 @@
+bin/XF86_Mach64
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/Ma8-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/Ma8-list
new file mode 100644
index 000000000..6a6a6f443
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/Ma8-list
@@ -0,0 +1 @@
+bin/XF86_Mach8
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/Mono-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/Mono-list
new file mode 100644
index 000000000..06ef98d26
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/Mono-list
@@ -0,0 +1 @@
+bin/XF86_Mono
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/P9K-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/P9K-list
new file mode 100644
index 000000000..be9adab58
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/P9K-list
@@ -0,0 +1 @@
+bin/XF86_P9000
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/S3-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/S3-list
new file mode 100644
index 000000000..2ff889fc6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/S3-list
@@ -0,0 +1 @@
+bin/XF86_S3
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/S3V-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/S3V-list
new file mode 100644
index 000000000..8a7161906
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/S3V-list
@@ -0,0 +1 @@
+bin/XF86_S3V
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/SVGA-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/SVGA-list
new file mode 100644
index 000000000..bf3b71150
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/SVGA-list
@@ -0,0 +1 @@
+bin/XF86_SVGA
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/VG16-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/VG16-list
new file mode 100644
index 000000000..7d2e6163f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/VG16-list
@@ -0,0 +1 @@
+bin/XF86_VGA16
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/bin-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/bin-excl
new file mode 100644
index 000000000..c007d9590
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/bin-excl
@@ -0,0 +1,9 @@
+bin/XF86_*
+bin/XF98_*
+bin/XF86Setup
+bin/Xnest
+bin/Xprt
+bin/Xvfb
+bin/X
+bin/xfs
+bin/xmseconfig
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/bin-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/bin-list
new file mode 100644
index 000000000..e5d1a9397
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/bin-list
@@ -0,0 +1,16 @@
+bin
+lib/libICE.so.6.3
+lib/libPEX5.so.6.0
+lib/libSM.so.6.0
+lib/libX11.so.6.1
+lib/libXIE.so.6.0
+lib/libXaw.so.6.1
+lib/libXext.so.6.3
+lib/libXi.so.6.0
+lib/libXmu.so.6.0
+lib/libXp.so.6.2
+lib/libXt.so.6.0
+lib/libXtst.so.6.1
+lib/liboldX.so.6.0
+lib/modules
+lib/X11/app-defaults
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/dir b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/dir
new file mode 100644
index 000000000..11c5b9da7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/dir
@@ -0,0 +1 @@
+usr/X11R6
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/fsrv-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/fsrv-list
new file mode 100644
index 000000000..46aa7cd6a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/fsrv-list
@@ -0,0 +1,3 @@
+bin/xfs
+lib/X11/fs
+man/cat1/xfs.0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/host.def b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/host.def
new file mode 100644
index 000000000..bc6940165
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/host.def
@@ -0,0 +1,16 @@
+/*
+ * Host.def for building OpenBSD bindists
+ *
+ * $XFree86: xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/host.def,v 1.2 1997/08/26 10:53:22 hohndel Exp $
+ */
+
+#define InstallEmptyHostDef
+
+#define ForceNormalLib YES
+
+#define HasTcl YES
+#define HasTk YES
+#define TkLibName tk41
+#define TclLibName tcl75
+
+#define JoystickSupport YES
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/lib-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/lib-excl
new file mode 100644
index 000000000..3572f4206
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/lib-excl
@@ -0,0 +1,12 @@
+lib/X11/XF86Setup
+lib/X11/app-defaults
+lib/X11/config
+lib/X11/fonts
+lib/X11/fs
+lib/X11/xdm/GiveConsole
+lib/X11/xdm/TakeConsole
+lib/X11/xdm/X*
+lib/X11/xdm/xdm-*
+lib/X11/xinit
+lib/X11/doc
+lib/X11/XF86Setup
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/lib-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/lib-list
new file mode 100644
index 000000000..9673fea05
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/lib-list
@@ -0,0 +1,2 @@
+lib/X11
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/lkit-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/lkit-list
new file mode 100644
index 000000000..d1b39d97e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/lkit-list
@@ -0,0 +1 @@
+lib/Server
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/man-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/man-excl
new file mode 100644
index 000000000..1ea82551a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/man-excl
@@ -0,0 +1,3 @@
+man/cat1/XF86Setup.0
+man/cat1/xfs.0
+man/cat1/xmseconfig.0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/man-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/man-list
new file mode 100644
index 000000000..2a3700c15
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/man-list
@@ -0,0 +1 @@
+man
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/nest-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/nest-list
new file mode 100644
index 000000000..eff754d76
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/nest-list
@@ -0,0 +1 @@
+bin/Xnest
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/prog-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/prog-excl
new file mode 100644
index 000000000..113d220ef
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/prog-excl
@@ -0,0 +1,5 @@
+lib/Server
+lib/X11
+lib/lib*.so*
+lib/modules
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/prog-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/prog-list
new file mode 100644
index 000000000..059b71061
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/prog-list
@@ -0,0 +1,3 @@
+lib
+include
+lib/X11/config
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/prt-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/prt-list
new file mode 100644
index 000000000..0646e7927
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/prt-list
@@ -0,0 +1 @@
+bin/Xprt
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/set-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/set-list
new file mode 100644
index 000000000..ac2d180b8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/set-list
@@ -0,0 +1,5 @@
+bin/XF86Setup
+bin/xmseconfig
+lib/X11/XF86Setup
+man/cat1/XF86Setup.0
+man/cat1/xmseconfig.0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/vfb-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/vfb-list
new file mode 100644
index 000000000..e2d161bbc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-ix86/vfb-list
@@ -0,0 +1 @@
+bin/Xvfb
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/Mono-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/Mono-list
new file mode 100644
index 000000000..d228fc27b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/Mono-list
@@ -0,0 +1 @@
+bin/XsunMono
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/Sun24-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/Sun24-list
new file mode 100644
index 000000000..f4238f4fd
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/Sun24-list
@@ -0,0 +1 @@
+bin/Xsun24
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/bin-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/bin-excl
new file mode 100644
index 000000000..9eb44e897
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/bin-excl
@@ -0,0 +1,8 @@
+bin/Xsun
+bin/Xsun24
+bin/XsunMono
+bin/Xnest
+bin/Xprt
+bin/Xvfb
+bin/X
+bin/xfs
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/bin-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/bin-list
new file mode 100644
index 000000000..e5d1a9397
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/bin-list
@@ -0,0 +1,16 @@
+bin
+lib/libICE.so.6.3
+lib/libPEX5.so.6.0
+lib/libSM.so.6.0
+lib/libX11.so.6.1
+lib/libXIE.so.6.0
+lib/libXaw.so.6.1
+lib/libXext.so.6.3
+lib/libXi.so.6.0
+lib/libXmu.so.6.0
+lib/libXp.so.6.2
+lib/libXt.so.6.0
+lib/libXtst.so.6.1
+lib/liboldX.so.6.0
+lib/modules
+lib/X11/app-defaults
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/dir b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/dir
new file mode 100644
index 000000000..11c5b9da7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/dir
@@ -0,0 +1 @@
+usr/X11R6
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/fsrv-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/fsrv-list
new file mode 100644
index 000000000..46aa7cd6a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/fsrv-list
@@ -0,0 +1,3 @@
+bin/xfs
+lib/X11/fs
+man/cat1/xfs.0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/host.def b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/host.def
new file mode 100644
index 000000000..9c3edb8c7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/host.def
@@ -0,0 +1,14 @@
+/*
+ * Host.def for building OpenBSD bindists
+ *
+ * $XFree86: xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/host.def,v 1.1 1997/10/25 13:50:40 hohndel Exp $
+ */
+
+#define InstallEmptyHostDef
+
+#define ForceNormalLib YES
+
+#define HasTcl YES
+#define HasTk YES
+#define TkLibName tk41
+#define TclLibName tcl75
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/lib-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/lib-excl
new file mode 100644
index 000000000..3572f4206
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/lib-excl
@@ -0,0 +1,12 @@
+lib/X11/XF86Setup
+lib/X11/app-defaults
+lib/X11/config
+lib/X11/fonts
+lib/X11/fs
+lib/X11/xdm/GiveConsole
+lib/X11/xdm/TakeConsole
+lib/X11/xdm/X*
+lib/X11/xdm/xdm-*
+lib/X11/xinit
+lib/X11/doc
+lib/X11/XF86Setup
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/lib-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/lib-list
new file mode 100644
index 000000000..9673fea05
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/lib-list
@@ -0,0 +1,2 @@
+lib/X11
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/man-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/man-excl
new file mode 100644
index 000000000..1ea82551a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/man-excl
@@ -0,0 +1,3 @@
+man/cat1/XF86Setup.0
+man/cat1/xfs.0
+man/cat1/xmseconfig.0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/man-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/man-list
new file mode 100644
index 000000000..2a3700c15
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/man-list
@@ -0,0 +1 @@
+man
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/nest-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/nest-list
new file mode 100644
index 000000000..eff754d76
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/nest-list
@@ -0,0 +1 @@
+bin/Xnest
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/prog-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/prog-excl
new file mode 100644
index 000000000..113d220ef
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/prog-excl
@@ -0,0 +1,5 @@
+lib/Server
+lib/X11
+lib/lib*.so*
+lib/modules
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/prog-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/prog-list
new file mode 100644
index 000000000..059b71061
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/prog-list
@@ -0,0 +1,3 @@
+lib
+include
+lib/X11/config
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/prt-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/prt-list
new file mode 100644
index 000000000..0646e7927
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/prt-list
@@ -0,0 +1 @@
+bin/Xprt
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/sun-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/sun-list
new file mode 100644
index 000000000..ea5f79a7e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/OpenBSD-sparc/sun-list
@@ -0,0 +1 @@
+bin/Xsun
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/8514-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/8514-list
new file mode 100644
index 000000000..66f089e22
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/8514-list
@@ -0,0 +1 @@
+bin/XF86_8514
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/AGX-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/AGX-list
new file mode 100644
index 000000000..6f41acb86
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/AGX-list
@@ -0,0 +1 @@
+bin/XF86_AGX
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/I128-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/I128-list
new file mode 100644
index 000000000..2a8ba145b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/I128-list
@@ -0,0 +1 @@
+bin/XF86_I128
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Load-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Load-list
new file mode 100644
index 000000000..828581fdf
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Load-list
@@ -0,0 +1 @@
+bin/XF86_LOADER
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Ma32-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Ma32-list
new file mode 100644
index 000000000..12323fb0d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Ma32-list
@@ -0,0 +1 @@
+bin/XF86_Mach32
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Ma64-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Ma64-list
new file mode 100644
index 000000000..7f7501533
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Ma64-list
@@ -0,0 +1 @@
+bin/XF86_Mach64
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Ma8-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Ma8-list
new file mode 100644
index 000000000..6a6a6f443
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Ma8-list
@@ -0,0 +1 @@
+bin/XF86_Mach8
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Mono-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Mono-list
new file mode 100644
index 000000000..06ef98d26
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/Mono-list
@@ -0,0 +1 @@
+bin/XF86_Mono
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/P9K-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/P9K-list
new file mode 100644
index 000000000..be9adab58
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/P9K-list
@@ -0,0 +1 @@
+bin/XF86_P9000
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/S3-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/S3-list
new file mode 100644
index 000000000..2ff889fc6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/S3-list
@@ -0,0 +1 @@
+bin/XF86_S3
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/S3V-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/S3V-list
new file mode 100644
index 000000000..8a7161906
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/S3V-list
@@ -0,0 +1 @@
+bin/XF86_S3V
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/SVGA-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/SVGA-list
new file mode 100644
index 000000000..bf3b71150
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/SVGA-list
@@ -0,0 +1 @@
+bin/XF86_SVGA
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/VG16-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/VG16-list
new file mode 100644
index 000000000..7d2e6163f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/VG16-list
@@ -0,0 +1 @@
+bin/XF86_VGA16
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/bin-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/bin-excl
new file mode 100644
index 000000000..c007d9590
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/bin-excl
@@ -0,0 +1,9 @@
+bin/XF86_*
+bin/XF98_*
+bin/XF86Setup
+bin/Xnest
+bin/Xprt
+bin/Xvfb
+bin/X
+bin/xfs
+bin/xmseconfig
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/bin-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/bin-list
new file mode 100644
index 000000000..a25d9c515
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/bin-list
@@ -0,0 +1,28 @@
+bin
+lib/libICE.so.6.3
+lib/libPEX5.so.6.0
+lib/libSM.so.6.0
+lib/libX11.so.6.1
+lib/libXIE.so.6.0
+lib/libXaw.so.6.1
+lib/libXext.so.6.3
+lib/libXi.so.6.0
+lib/libXmu.so.6.0
+lib/libXp.so.6.2
+lib/libXt.so.6.0
+lib/libXtst.so.6.1
+lib/liboldX.so.6.0
+lib/libICE.so
+lib/libPEX5.so
+lib/libSM.so
+lib/libX11.so
+lib/libXIE.so
+lib/libXaw.so
+lib/libXext.so
+lib/libXi.so
+lib/libXmu.so
+lib/libXp.so
+lib/libXt.so
+lib/libXtst.so
+lib/liboldX.so
+lib/X11/app-defaults
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/dir b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/dir
new file mode 100644
index 000000000..11c5b9da7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/dir
@@ -0,0 +1 @@
+usr/X11R6
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/fsrv-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/fsrv-list
new file mode 100644
index 000000000..c70da7456
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/fsrv-list
@@ -0,0 +1,3 @@
+bin/xfs
+lib/X11/fs
+man/man1/xfs.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/host.def b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/host.def
new file mode 100644
index 000000000..ea725aae1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/host.def
@@ -0,0 +1,3 @@
+/*
+ * Host.def for building FreeBSD bindists
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/lib-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/lib-excl
new file mode 100644
index 000000000..3572f4206
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/lib-excl
@@ -0,0 +1,12 @@
+lib/X11/XF86Setup
+lib/X11/app-defaults
+lib/X11/config
+lib/X11/fonts
+lib/X11/fs
+lib/X11/xdm/GiveConsole
+lib/X11/xdm/TakeConsole
+lib/X11/xdm/X*
+lib/X11/xdm/xdm-*
+lib/X11/xinit
+lib/X11/doc
+lib/X11/XF86Setup
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/lib-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/lib-list
new file mode 100644
index 000000000..9673fea05
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/lib-list
@@ -0,0 +1,2 @@
+lib/X11
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/man-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/man-excl
new file mode 100644
index 000000000..81792cce1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/man-excl
@@ -0,0 +1,3 @@
+man/man1/XF86Setup.1x
+man/man1/xfs.1x
+man/man1/xmseconfig.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/man-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/man-list
new file mode 100644
index 000000000..2a3700c15
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/man-list
@@ -0,0 +1 @@
+man
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/mod-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/mod-list
new file mode 100644
index 000000000..7054fc153
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/mod-list
@@ -0,0 +1 @@
+lib/modules
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/nest-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/nest-list
new file mode 100644
index 000000000..eff754d76
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/nest-list
@@ -0,0 +1 @@
+bin/Xnest
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/prog-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/prog-excl
new file mode 100644
index 000000000..113d220ef
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/prog-excl
@@ -0,0 +1,5 @@
+lib/Server
+lib/X11
+lib/lib*.so*
+lib/modules
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/prog-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/prog-list
new file mode 100644
index 000000000..059b71061
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/prog-list
@@ -0,0 +1,3 @@
+lib
+include
+lib/X11/config
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/prt-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/prt-list
new file mode 100644
index 000000000..0646e7927
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/prt-list
@@ -0,0 +1 @@
+bin/Xprt
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/set-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/set-list
new file mode 100644
index 000000000..83d032807
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/set-list
@@ -0,0 +1,5 @@
+bin/XF86Setup
+bin/xmseconfig
+lib/X11/XF86Setup
+man/man1/XF86Setup.1x
+man/man1/xmseconfig.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/vfb-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/vfb-list
new file mode 100644
index 000000000..e2d161bbc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/SVR4.0/vfb-list
@@ -0,0 +1 @@
+bin/Xvfb
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/8514-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/8514-list
new file mode 100644
index 000000000..66f089e22
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/8514-list
@@ -0,0 +1 @@
+bin/XF86_8514
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/AGX-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/AGX-list
new file mode 100644
index 000000000..6f41acb86
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/AGX-list
@@ -0,0 +1 @@
+bin/XF86_AGX
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/I128-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/I128-list
new file mode 100644
index 000000000..2a8ba145b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/I128-list
@@ -0,0 +1 @@
+bin/XF86_I128
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Load-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Load-list
new file mode 100644
index 000000000..828581fdf
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Load-list
@@ -0,0 +1 @@
+bin/XF86_LOADER
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Ma32-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Ma32-list
new file mode 100644
index 000000000..12323fb0d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Ma32-list
@@ -0,0 +1 @@
+bin/XF86_Mach32
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Ma64-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Ma64-list
new file mode 100644
index 000000000..7f7501533
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Ma64-list
@@ -0,0 +1 @@
+bin/XF86_Mach64
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Ma8-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Ma8-list
new file mode 100644
index 000000000..6a6a6f443
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Ma8-list
@@ -0,0 +1 @@
+bin/XF86_Mach8
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Mono-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Mono-list
new file mode 100644
index 000000000..06ef98d26
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/Mono-list
@@ -0,0 +1 @@
+bin/XF86_Mono
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/P9K-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/P9K-list
new file mode 100644
index 000000000..be9adab58
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/P9K-list
@@ -0,0 +1 @@
+bin/XF86_P9000
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/S3-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/S3-list
new file mode 100644
index 000000000..2ff889fc6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/S3-list
@@ -0,0 +1 @@
+bin/XF86_S3
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/S3V-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/S3V-list
new file mode 100644
index 000000000..8a7161906
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/S3V-list
@@ -0,0 +1 @@
+bin/XF86_S3V
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/SVGA-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/SVGA-list
new file mode 100644
index 000000000..bf3b71150
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/SVGA-list
@@ -0,0 +1 @@
+bin/XF86_SVGA
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/VG16-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/VG16-list
new file mode 100644
index 000000000..7d2e6163f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/VG16-list
@@ -0,0 +1 @@
+bin/XF86_VGA16
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/bin-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/bin-excl
new file mode 100644
index 000000000..c007d9590
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/bin-excl
@@ -0,0 +1,9 @@
+bin/XF86_*
+bin/XF98_*
+bin/XF86Setup
+bin/Xnest
+bin/Xprt
+bin/Xvfb
+bin/X
+bin/xfs
+bin/xmseconfig
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/bin-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/bin-list
new file mode 100644
index 000000000..a25d9c515
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/bin-list
@@ -0,0 +1,28 @@
+bin
+lib/libICE.so.6.3
+lib/libPEX5.so.6.0
+lib/libSM.so.6.0
+lib/libX11.so.6.1
+lib/libXIE.so.6.0
+lib/libXaw.so.6.1
+lib/libXext.so.6.3
+lib/libXi.so.6.0
+lib/libXmu.so.6.0
+lib/libXp.so.6.2
+lib/libXt.so.6.0
+lib/libXtst.so.6.1
+lib/liboldX.so.6.0
+lib/libICE.so
+lib/libPEX5.so
+lib/libSM.so
+lib/libX11.so
+lib/libXIE.so
+lib/libXaw.so
+lib/libXext.so
+lib/libXi.so
+lib/libXmu.so
+lib/libXp.so
+lib/libXt.so
+lib/libXtst.so
+lib/liboldX.so
+lib/X11/app-defaults
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/dir b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/dir
new file mode 100644
index 000000000..11c5b9da7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/dir
@@ -0,0 +1 @@
+usr/X11R6
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/fsrv-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/fsrv-list
new file mode 100644
index 000000000..c70da7456
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/fsrv-list
@@ -0,0 +1,3 @@
+bin/xfs
+lib/X11/fs
+man/man1/xfs.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/host.def b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/host.def
new file mode 100644
index 000000000..ea725aae1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/host.def
@@ -0,0 +1,3 @@
+/*
+ * Host.def for building FreeBSD bindists
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/lib-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/lib-excl
new file mode 100644
index 000000000..3572f4206
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/lib-excl
@@ -0,0 +1,12 @@
+lib/X11/XF86Setup
+lib/X11/app-defaults
+lib/X11/config
+lib/X11/fonts
+lib/X11/fs
+lib/X11/xdm/GiveConsole
+lib/X11/xdm/TakeConsole
+lib/X11/xdm/X*
+lib/X11/xdm/xdm-*
+lib/X11/xinit
+lib/X11/doc
+lib/X11/XF86Setup
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/lib-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/lib-list
new file mode 100644
index 000000000..9673fea05
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/lib-list
@@ -0,0 +1,2 @@
+lib/X11
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/man-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/man-excl
new file mode 100644
index 000000000..81792cce1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/man-excl
@@ -0,0 +1,3 @@
+man/man1/XF86Setup.1x
+man/man1/xfs.1x
+man/man1/xmseconfig.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/man-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/man-list
new file mode 100644
index 000000000..2a3700c15
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/man-list
@@ -0,0 +1 @@
+man
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/mod-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/mod-list
new file mode 100644
index 000000000..7054fc153
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/mod-list
@@ -0,0 +1 @@
+lib/modules
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/nest-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/nest-list
new file mode 100644
index 000000000..eff754d76
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/nest-list
@@ -0,0 +1 @@
+bin/Xnest
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/prog-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/prog-excl
new file mode 100644
index 000000000..113d220ef
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/prog-excl
@@ -0,0 +1,5 @@
+lib/Server
+lib/X11
+lib/lib*.so*
+lib/modules
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/prog-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/prog-list
new file mode 100644
index 000000000..059b71061
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/prog-list
@@ -0,0 +1,3 @@
+lib
+include
+lib/X11/config
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/prt-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/prt-list
new file mode 100644
index 000000000..0646e7927
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/prt-list
@@ -0,0 +1 @@
+bin/Xprt
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/set-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/set-list
new file mode 100644
index 000000000..83d032807
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/set-list
@@ -0,0 +1,5 @@
+bin/XF86Setup
+bin/xmseconfig
+lib/X11/XF86Setup
+man/man1/XF86Setup.1x
+man/man1/xmseconfig.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/vfb-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/vfb-list
new file mode 100644
index 000000000..e2d161bbc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/Solaris/vfb-list
@@ -0,0 +1 @@
+bin/Xvfb
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/8514-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/8514-list
new file mode 100644
index 000000000..66f089e22
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/8514-list
@@ -0,0 +1 @@
+bin/XF86_8514
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/AGX-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/AGX-list
new file mode 100644
index 000000000..6f41acb86
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/AGX-list
@@ -0,0 +1 @@
+bin/XF86_AGX
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/I128-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/I128-list
new file mode 100644
index 000000000..2a8ba145b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/I128-list
@@ -0,0 +1 @@
+bin/XF86_I128
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Load-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Load-list
new file mode 100644
index 000000000..828581fdf
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Load-list
@@ -0,0 +1 @@
+bin/XF86_LOADER
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Ma32-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Ma32-list
new file mode 100644
index 000000000..12323fb0d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Ma32-list
@@ -0,0 +1 @@
+bin/XF86_Mach32
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Ma64-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Ma64-list
new file mode 100644
index 000000000..7f7501533
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Ma64-list
@@ -0,0 +1 @@
+bin/XF86_Mach64
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Ma8-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Ma8-list
new file mode 100644
index 000000000..6a6a6f443
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Ma8-list
@@ -0,0 +1 @@
+bin/XF86_Mach8
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Mono-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Mono-list
new file mode 100644
index 000000000..06ef98d26
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/Mono-list
@@ -0,0 +1 @@
+bin/XF86_Mono
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/P9K-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/P9K-list
new file mode 100644
index 000000000..be9adab58
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/P9K-list
@@ -0,0 +1 @@
+bin/XF86_P9000
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/S3-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/S3-list
new file mode 100644
index 000000000..2ff889fc6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/S3-list
@@ -0,0 +1 @@
+bin/XF86_S3
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/S3V-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/S3V-list
new file mode 100644
index 000000000..8a7161906
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/S3V-list
@@ -0,0 +1 @@
+bin/XF86_S3V
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/SVGA-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/SVGA-list
new file mode 100644
index 000000000..bf3b71150
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/SVGA-list
@@ -0,0 +1 @@
+bin/XF86_SVGA
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/VG16-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/VG16-list
new file mode 100644
index 000000000..7d2e6163f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/VG16-list
@@ -0,0 +1 @@
+bin/XF86_VGA16
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/bin-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/bin-excl
new file mode 100644
index 000000000..c007d9590
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/bin-excl
@@ -0,0 +1,9 @@
+bin/XF86_*
+bin/XF98_*
+bin/XF86Setup
+bin/Xnest
+bin/Xprt
+bin/Xvfb
+bin/X
+bin/xfs
+bin/xmseconfig
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/bin-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/bin-list
new file mode 100644
index 000000000..a25d9c515
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/bin-list
@@ -0,0 +1,28 @@
+bin
+lib/libICE.so.6.3
+lib/libPEX5.so.6.0
+lib/libSM.so.6.0
+lib/libX11.so.6.1
+lib/libXIE.so.6.0
+lib/libXaw.so.6.1
+lib/libXext.so.6.3
+lib/libXi.so.6.0
+lib/libXmu.so.6.0
+lib/libXp.so.6.2
+lib/libXt.so.6.0
+lib/libXtst.so.6.1
+lib/liboldX.so.6.0
+lib/libICE.so
+lib/libPEX5.so
+lib/libSM.so
+lib/libX11.so
+lib/libXIE.so
+lib/libXaw.so
+lib/libXext.so
+lib/libXi.so
+lib/libXmu.so
+lib/libXp.so
+lib/libXt.so
+lib/libXtst.so
+lib/liboldX.so
+lib/X11/app-defaults
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/dir b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/dir
new file mode 100644
index 000000000..11c5b9da7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/dir
@@ -0,0 +1 @@
+usr/X11R6
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/fsrv-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/fsrv-list
new file mode 100644
index 000000000..c70da7456
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/fsrv-list
@@ -0,0 +1,3 @@
+bin/xfs
+lib/X11/fs
+man/man1/xfs.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/host.def b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/host.def
new file mode 100644
index 000000000..ea725aae1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/host.def
@@ -0,0 +1,3 @@
+/*
+ * Host.def for building FreeBSD bindists
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/lib-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/lib-excl
new file mode 100644
index 000000000..3572f4206
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/lib-excl
@@ -0,0 +1,12 @@
+lib/X11/XF86Setup
+lib/X11/app-defaults
+lib/X11/config
+lib/X11/fonts
+lib/X11/fs
+lib/X11/xdm/GiveConsole
+lib/X11/xdm/TakeConsole
+lib/X11/xdm/X*
+lib/X11/xdm/xdm-*
+lib/X11/xinit
+lib/X11/doc
+lib/X11/XF86Setup
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/lib-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/lib-list
new file mode 100644
index 000000000..9673fea05
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/lib-list
@@ -0,0 +1,2 @@
+lib/X11
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/man-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/man-excl
new file mode 100644
index 000000000..81792cce1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/man-excl
@@ -0,0 +1,3 @@
+man/man1/XF86Setup.1x
+man/man1/xfs.1x
+man/man1/xmseconfig.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/man-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/man-list
new file mode 100644
index 000000000..2a3700c15
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/man-list
@@ -0,0 +1 @@
+man
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/mod-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/mod-list
new file mode 100644
index 000000000..7054fc153
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/mod-list
@@ -0,0 +1 @@
+lib/modules
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/nest-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/nest-list
new file mode 100644
index 000000000..eff754d76
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/nest-list
@@ -0,0 +1 @@
+bin/Xnest
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/prog-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/prog-excl
new file mode 100644
index 000000000..113d220ef
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/prog-excl
@@ -0,0 +1,5 @@
+lib/Server
+lib/X11
+lib/lib*.so*
+lib/modules
+include/X11/bitmaps
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/prog-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/prog-list
new file mode 100644
index 000000000..059b71061
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/prog-list
@@ -0,0 +1,3 @@
+lib
+include
+lib/X11/config
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/prt-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/prt-list
new file mode 100644
index 000000000..0646e7927
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/prt-list
@@ -0,0 +1 @@
+bin/Xprt
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/set-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/set-list
new file mode 100644
index 000000000..83d032807
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/set-list
@@ -0,0 +1,5 @@
+bin/XF86Setup
+bin/xmseconfig
+lib/X11/XF86Setup
+man/man1/XF86Setup.1x
+man/man1/xmseconfig.1x
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/vfb-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/vfb-list
new file mode 100644
index 000000000..e2d161bbc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/UnixWare/vfb-list
@@ -0,0 +1 @@
+bin/Xvfb
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/build-bindist b/xc/programs/Xserver/hw/xfree86/etc/bindist/build-bindist
new file mode 100755
index 000000000..ab2a24c77
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/build-bindist
@@ -0,0 +1,118 @@
+#!/bin/sh
+#
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/bindist/build-bindist,v 1.1 1997/05/27 03:47:02 dawes Exp $
+#
+
+Usage()
+{
+ echo `basename $0` [-l] version from-dir to-dir
+ exit 1
+}
+
+listonly=NO
+
+case $1 in
+ -l)
+ listonly=YES
+ shift
+ ;;
+esac
+
+if [ $# != 3 ]; then
+ Usage
+fi
+
+VERS=$1
+FROMDIR=$2
+TODIR=$3
+
+if [ ! -d $FROMDIR ]; then
+ echo No such dir $FROMDIR
+ exit 2
+fi
+
+if [ ! -d $TODIR ]; then
+ echo No such dir $TODIR
+ exit 2
+fi
+
+cd $TODIR
+SUBDIRS="`find . -type d ! -name bindist -print`"
+
+DIRFILE=dir
+BINDIR=bindist
+EXTRASFILE=extras
+TAR="gnu-tar"
+TAROPTS="-c -v -z"
+TARLOPTS="-t -v -z -i"
+CKSUM=md5
+SUMFILE=SUMS.md5
+LISTFILE=FILES
+
+GenList()
+{
+ (cd $TODIR/$BINDIR
+ rm -f $SUMFILE $LISTFILE
+ for i in *.tgz; do
+ echo $i
+ $CKSUM $i >> $SUMFILE
+ echo $i >> $LISTFILE
+ echo "------------" >> $LISTFILE
+ $TAR $TARLOPTS -f $i >> $LISTFILE
+ echo "" >> $LISTFILE
+ done
+ if [ -f $TODIR/$EXTRASFILE ]; then
+ for i in `cat $TODIR/$EXTRASFILE`; do
+ $CKSUM `basename $i` >> $SUMFILE
+ done
+ fi
+ )
+}
+
+if [ ! -d $TODIR/$BINDIR ]; then
+ mkdir $TODIR/$BINDIR
+fi
+
+if [ $listonly = YES ]; then
+ GenList
+ exit 0;
+fi
+
+for d in $SUBDIRS; do
+ if [ ! -d $TODIR/$d ]; then
+ echo No such dir $TODIR/$d
+ exit 2
+ fi
+ (cd $TODIR/$d;
+ if [ ! -f $DIRFILE ]; then
+ echo No file $DIRFILE in $TODIR/$d
+# exit 3
+ else
+ PREFIX=`cat $DIRFILE`
+ for i in *-list; do
+ name=`basename $i -list`
+ tarball=$VERS$name.tgz
+ echo creating $tarball
+ lfile="-T $TODIR/$d/$i"
+ if [ -f $name-excl ]; then
+ xfile="-X $TODIR/$d/$name-excl"
+ else
+ xfile=""
+ fi
+ (cd $FROMDIR/$PREFIX
+ $TAR $TAROPTS -f $TODIR/$BINDIR/$tarball $lfile $xfile
+ )
+ done
+ fi
+ if [ -f $EXTRASFILE ]; then
+ for i in `cat $EXTRASFILE`; do
+ rm -f $TODIR/$BINDIR/`basename $i`
+ cp $FROMDIR/$PREFIX/$i $TODIR/$BINDIR
+ done
+ fi
+ )
+done
+
+GenList
+
+exit 0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/common/cfg-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/cfg-excl
new file mode 100644
index 000000000..fdc9e7e90
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/cfg-excl
@@ -0,0 +1,2 @@
+lib/X11/xdm/lib*
+lib/X11/xdm/chooser*
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/common/cfg-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/cfg-list
new file mode 100644
index 000000000..16c476a83
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/cfg-list
@@ -0,0 +1,2 @@
+lib/X11/xdm
+lib/X11/xinit/xinitrc
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/common/dir b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/dir
new file mode 100644
index 000000000..11c5b9da7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/dir
@@ -0,0 +1 @@
+usr/X11R6
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/common/doc-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/doc-excl
new file mode 100644
index 000000000..17b47088a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/doc-excl
@@ -0,0 +1,3 @@
+lib/X11/doc/PostScript
+lib/X11/doc/html
+lib/X11/doc/Japanese
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/common/doc-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/doc-list
new file mode 100644
index 000000000..233972349
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/doc-list
@@ -0,0 +1 @@
+lib/X11/doc
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/common/extras b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/extras
new file mode 100644
index 000000000..a8968c86f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/extras
@@ -0,0 +1,5 @@
+lib/X11/doc/BetaReport
+lib/X11/doc/RELNOTES
+lib/X11/doc/README
+lib/X11/etc/postinst.sh
+lib/X11/etc/preinst.sh
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/common/f100-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/f100-list
new file mode 100644
index 000000000..858c8fc60
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/f100-list
@@ -0,0 +1 @@
+lib/X11/fonts/100dpi
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fcyr-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fcyr-list
new file mode 100644
index 000000000..f3d2dba22
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fcyr-list
@@ -0,0 +1 @@
+lib/X11/fonts/cyrillic
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fenc-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fenc-list
new file mode 100644
index 000000000..5414b05b5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fenc-list
@@ -0,0 +1 @@
+lib/X11/fonts/encodings
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/common/flat2-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/flat2-list
new file mode 100644
index 000000000..354ddf5ac
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/flat2-list
@@ -0,0 +1 @@
+lib/X11/fonts/latin2
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fnon-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fnon-list
new file mode 100644
index 000000000..7da919b6e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fnon-list
@@ -0,0 +1,11 @@
+lib/X11/fonts/misc/gb16fs.pcf.gz
+lib/X11/fonts/misc/gb16st.pcf.gz
+lib/X11/fonts/misc/gb24st.pcf.gz
+lib/X11/fonts/misc/hanglg16.pcf.gz
+lib/X11/fonts/misc/hanglm16.pcf.gz
+lib/X11/fonts/misc/hanglm24.pcf.gz
+lib/X11/fonts/misc/heb6x13.pcf.gz
+lib/X11/fonts/misc/heb8x13.pcf.gz
+lib/X11/fonts/misc/jiskan16.pcf.gz
+lib/X11/fonts/misc/jiskan24.pcf.gz
+lib/X11/fonts/misc/k14.pcf.gz
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fnts-excl b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fnts-excl
new file mode 100644
index 000000000..411016a48
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fnts-excl
@@ -0,0 +1,5 @@
+lib/X11/fonts/misc/gb*
+lib/X11/fonts/misc/hang*
+lib/X11/fonts/misc/heb*
+lib/X11/fonts/misc/jiskan*
+lib/X11/fonts/misc/k14*
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fnts-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fnts-list
new file mode 100644
index 000000000..28f12daf4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fnts-list
@@ -0,0 +1,5 @@
+lib/X11/fonts/75dpi
+lib/X11/fonts/misc
+lib/X11/fonts/PEX
+lib/X11/fonts/CID
+lib/X11/fonts/local
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fscl-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fscl-list
new file mode 100644
index 000000000..133a8f9a5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/fscl-list
@@ -0,0 +1,2 @@
+lib/X11/fonts/Speedo
+lib/X11/fonts/Type1
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/common/html-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/html-list
new file mode 100644
index 000000000..09b626eba
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/html-list
@@ -0,0 +1 @@
+lib/X11/doc/html
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/common/jdoc-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/jdoc-list
new file mode 100644
index 000000000..91d9432e0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/jdoc-list
@@ -0,0 +1 @@
+lib/X11/doc/Japanese
diff --git a/xc/programs/Xserver/hw/xfree86/etc/bindist/common/ps-list b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/ps-list
new file mode 100644
index 000000000..34e9a9045
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/bindist/common/ps-list
@@ -0,0 +1 @@
+lib/X11/doc/PostScript
diff --git a/xc/programs/Xserver/hw/xfree86/etc/dmmap.shar b/xc/programs/Xserver/hw/xfree86/etc/dmmap.shar
new file mode 100644
index 000000000..4f323798a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/dmmap.shar
@@ -0,0 +1,601 @@
+#!/bin/sh
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/dmmap.shar,v 3.2 1996/12/23 06:47:08 dawes Exp $
+# This is a shell archive (produced by shar 3.49)
+# To extract the files from this archive, save it to a file, remove
+# everything above the "!/bin/sh" line above, and type "sh file_name".
+#
+# made 10/02/1993 09:11 UTC by root@gamma
+# Source directory /home1/tmp/x11r5
+#
+# $XConsortium: dmmap.shar /main/4 1996/02/21 17:47:27 kaleb $
+#
+# existing files will NOT be overwritten unless -c is specified
+#
+# This shar contains:
+# length mode name
+# ------ ---------- ------------------------------------------
+# 822 -r--r----- dmmap-1.0/Makefile
+# 2560 -r--r----- dmmap-1.0/README
+# 1139 -r--r----- dmmap-1.0/COPYING
+# 273 -r--r----- dmmap-1.0/version.h
+# 2413 -r--r----- dmmap-1.0/dmmap.c
+# 24 -r--r----- dmmap-1.0/conf/System
+# 29 -r--r----- dmmap-1.0/conf/Master
+# 16 -r--r----- dmmap-1.0/conf/Node
+# 631 -r-xr-xr-x dmmap-1.0/conf/install
+# 85 -r--r----- dmmap-1.0/test/Makefile
+# 2384 -r--r----- dmmap-1.0/test/tst_dmmap.c
+#
+# ============= dmmap-1.0/Makefile ==============
+if test ! -d 'dmmap-1.0'; then
+ echo 'x - creating directory dmmap-1.0'
+ mkdir 'dmmap-1.0'
+fi
+if test -f 'dmmap-1.0/Makefile' -a X"$1" != X"-c"; then
+ echo 'x - skipping dmmap-1.0/Makefile (File already exists)'
+else
+echo 'x - extracting dmmap-1.0/Makefile (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'dmmap-1.0/Makefile' &&
+X
+DISTDIR = dmmap-1.0
+BINDIST = $(DISTDIR).btz
+SRCDIST = $(DISTDIR).stz
+DRIVER = dmmap.o
+TEST = test/tst_dmmap
+DISTFIL = README COPYING conf/install conf/System conf/Master conf/Node $(TEST)
+DISTSRC = Makefile README COPYING version.h dmmap.c conf \
+X test/Makefile test/tst_dmmap.c
+X
+CFLAGS = -D_INKERNEL=1 -D_COMPAT322=1
+X
+all: $(DRIVER) $(TEST)
+X
+install: $(DISTDIR)
+X cd $(DISTDIR); ./install
+X
+dist: bin-dist src-dist
+X
+bin-dist: $(DISTDIR)
+X tar cvf - $(DISTDIR) | gzip -9 > $(BINDIST)
+X
+src-dist:
+X tar cvf - $(DISTSRC) | gzip -9 > $(SRCDIST)
+X
+clean:
+X rm -f *.o
+X rm -f $(BINDIST)
+X rm -f $(SRCDIST)
+X rm -rf $(DISTDIR)
+X cd test; make clean
+X
+$(TEST): $(TEST).c
+X cd test; $(MAKE) $(MAKEARGS)
+X
+$(DISTDIR): $(DRIVER) $(DISTFIL)
+X rm -rf $(DISTDIR)
+X mkdir $(DISTDIR)
+X cp $(DISTFIL) $(DISTDIR)
+X cp $(DRIVER) $(DISTDIR)/Driver.o
+X
+SHAR_EOF
+chmod 0440 dmmap-1.0/Makefile ||
+echo 'restore of dmmap-1.0/Makefile failed'
+Wc_c="`wc -c < 'dmmap-1.0/Makefile'`"
+test 822 -eq "$Wc_c" ||
+ echo 'dmmap-1.0/Makefile: original size 822, current size' "$Wc_c"
+fi
+# ============= dmmap-1.0/README ==============
+if test -f 'dmmap-1.0/README' -a X"$1" != X"-c"; then
+ echo 'x - skipping dmmap-1.0/README (File already exists)'
+else
+echo 'x - extracting dmmap-1.0/README (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'dmmap-1.0/README' &&
+X The DMMAP Driver
+X
+Contents:
+1. General.
+2. Installation.
+3. Removal.
+4. Testing.
+5. Using the driver.
+6. Limitations.
+X
+X
+1. General
+X
+The "dmmap" driver is a generic video mapping driver for SCO unix. It differs
+from the standard SCO video mapping in that it allows you to map memory above
+1Mb and memory not usually associated with the current video card. This
+allows the user to map linear frame buffers into user space. It can only
+be accessed by root to limit security problems.
+X
+The distribution comes in two files,
+X
+X dmmap-XX.btz, the binary files required to install and test dmmap
+X dmmap-XX.stz, the source for dmmap and test program(s)
+X
+To extract one of these files use the following command,
+X
+X gunzip < dmmap-XX.?tz | tar xvf -
+X
+For information on copyright and copying see the file COPYING that appears in
+this package.
+X
+2. Installation
+X
+To install the dmmap driver, extract the dmmap.tar file somewhere
+convenient, then run "install" as root. The "install" script will take it
+from there. If building from source, type 'make install' as root.
+X
+3. Removal
+X
+To remove the dmmap driver follow these steps:
+X
+X login as root
+X cd /etc/conf/bin
+X ./idinstall -d dmmap
+X ./idbuild
+X
+4. Testing
+X
+A simple test program, "tst_dmmap" is provided with the driver. After the
+kernel is built and you have rebooted confirm the installation of the
+driver by running "tst_dmmap". It will do a simple test by mapping in the
+bios rom and checksumming it. If you have a bios at address 0xf0000 it
+will display the first 20 characters from the bios.
+X
+5. Using the driver
+X
+dmmap accepts two ioctls, KDMAPDISP and KDUNMAPDISP, both of which require
+as an argument a pointer to a completed "kd_memloc" stucture. A special
+ioctl of '-1' will return the version number of scmap you are running.
+A sample of code to map and unmap some memory follows below. For more
+detail see "test/tst_dmmap.c".
+X
+X .
+X .
+X .
+X
+X struct kd_memloc memloc;
+X
+X if ((fd = open("/dev/dmmap", O_RDWR)) < 0)
+X exit(0);
+X
+X memloc.vaddr = NULL;
+X memloc.physaddr = 0xf0000;
+X memloc.length = 0x10000
+X
+X if (ioctl(fd, KDMAPDISP, &memloc) < 0) {
+X perror("KDMAPDISP");
+X exit(1);
+X }
+X
+X printf("The first byte of 0x%x is 0x%02x\n", memloc.vaddr, *memloc.vaddr);
+X
+X if (ioctl(fd, KDUNMAPDISP, &memloc) < 0) {
+X perror("KDMAPDISP");
+X exit(1);
+X }
+X
+X .
+X .
+X .
+X
+6. Limitations
+X
+Currently this driver can only map in at most 4Mb of memory. This is not
+about to change as vasmalloc can only handle that much. It may be possible
+to rewrite vasmalloc but thats not going to happen any time soon.
+X
+SHAR_EOF
+chmod 0440 dmmap-1.0/README ||
+echo 'restore of dmmap-1.0/README failed'
+Wc_c="`wc -c < 'dmmap-1.0/README'`"
+test 2560 -eq "$Wc_c" ||
+ echo 'dmmap-1.0/README: original size 2560, current size' "$Wc_c"
+fi
+# ============= dmmap-1.0/COPYING ==============
+if test -f 'dmmap-1.0/COPYING' -a X"$1" != X"-c"; then
+ echo 'x - skipping dmmap-1.0/COPYING (File already exists)'
+else
+echo 'x - extracting dmmap-1.0/COPYING (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'dmmap-1.0/COPYING' &&
+X
+Copyright 1993 by David McCullough <davidm@stallion.oz.au>
+X
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of David McCullough not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission. David McCullough makes no representations
+about the suitability of this software for any purpose. It is provided "as is"
+without express or implied warranty.
+X
+DAVID MCCULLOUGH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+SHALL DAVID MCCULLOUGH 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.
+X
+SHAR_EOF
+chmod 0440 dmmap-1.0/COPYING ||
+echo 'restore of dmmap-1.0/COPYING failed'
+Wc_c="`wc -c < 'dmmap-1.0/COPYING'`"
+test 1139 -eq "$Wc_c" ||
+ echo 'dmmap-1.0/COPYING: original size 1139, current size' "$Wc_c"
+fi
+# ============= dmmap-1.0/version.h ==============
+if test -f 'dmmap-1.0/version.h' -a X"$1" != X"-c"; then
+ echo 'x - skipping dmmap-1.0/version.h (File already exists)'
+else
+echo 'x - extracting dmmap-1.0/version.h (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'dmmap-1.0/version.h' &&
+#ifndef DMMAP_VERSION_H
+#define DMMAP_VERSION_H 1
+/******************************************************************************/
+X
+#define DMMAP_VERSION 0x0100
+X
+/******************************************************************************/
+#endif /* DMMAP_VERSION_H */
+SHAR_EOF
+chmod 0440 dmmap-1.0/version.h ||
+echo 'restore of dmmap-1.0/version.h failed'
+Wc_c="`wc -c < 'dmmap-1.0/version.h'`"
+test 273 -eq "$Wc_c" ||
+ echo 'dmmap-1.0/version.h: original size 273, current size' "$Wc_c"
+fi
+# ============= dmmap-1.0/dmmap.c ==============
+if test -f 'dmmap-1.0/dmmap.c' -a X"$1" != X"-c"; then
+ echo 'x - skipping dmmap-1.0/dmmap.c (File already exists)'
+else
+echo 'x - extracting dmmap-1.0/dmmap.c (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'dmmap-1.0/dmmap.c' &&
+/******************************************************************************/
+/*
+X * Copyright 1993 by David McCullough <davidm@stallion.oz.au>
+X * see file COPYING for more details.
+X */
+/******************************************************************************/
+X
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+#include <sys/vtkd.h>
+#include <sys/immu.h>
+X
+#include "version.h"
+X
+/******************************************************************************/
+X
+extern int vasbind(paddr_t, caddr_t, unsigned int);
+extern caddr_t vasmalloc(paddr_t, unsigned int);
+extern caddr_t vasmapped(paddr_t, unsigned int);
+extern int vasunbind(caddr_t, unsigned int);
+X
+/******************************************************************************/
+X
+int dmapioctl(dev, cmd, arg)
+X int dev;
+X int cmd;
+X int arg;
+{
+X struct kd_memloc memloc;
+X
+X if (!suser()) {
+X u.u_error = EPERM;
+X return(0);
+X }
+X
+X switch (cmd) {
+X default:
+X u.u_error = EINVAL;
+X break;
+X
+X case -1: /* saves anyone using header files that aren't part of the OS */
+X u.u_rval1 = DMMAP_VERSION;
+X break;
+X
+X case KDMAPDISP:
+X if (copyin((caddr_t) arg, &memloc, sizeof(memloc)) == -1) {
+X u.u_error = EFAULT;
+X break;
+X }
+/*
+X * arg checking.
+X * mapping to a provided memory addr not supported yet 8)
+X * when it is, vaddr must be below KVBASE, and we don't do the
+X * vasmalloc or the vasmapped checks quite the same way.
+X */
+X if (memloc.vaddr || memloc.length <= 0 || !memloc.physaddr) {
+X u.u_error = EINVAL;
+X break;
+X }
+X
+X if (memloc.vaddr = vasmapped((paddr_t) memloc.physaddr, memloc.length))
+X break;
+X
+X if (!(memloc.vaddr = vasmalloc((paddr_t)memloc.physaddr,memloc.length)))
+X break;
+X
+X if (vasbind((paddr_t) memloc.physaddr,memloc.vaddr,memloc.length) == -1)
+X break;
+X
+X if (copyout(&memloc, arg, sizeof(memloc)) == -1) {
+X u.u_error = EFAULT;
+X break;
+X }
+X break;
+X
+X case KDUNMAPDISP:
+X if (copyin((caddr_t) arg, &memloc, sizeof(memloc)) == -1) {
+X u.u_error = EFAULT;
+X break;
+X }
+X
+X if (!memloc.vaddr || memloc.length <= 0 || !memloc.physaddr) {
+X u.u_error = EINVAL;
+X break;
+X }
+X
+X if (memloc.vaddr != vasmapped((paddr_t)memloc.physaddr,memloc.length)) {
+X u.u_error = ENXIO;
+X break;
+X }
+X
+X if (vasunbind(memloc.vaddr, memloc.length) == -1)
+X break;
+X break;
+X }
+}
+X
+/******************************************************************************/
+SHAR_EOF
+chmod 0440 dmmap-1.0/dmmap.c ||
+echo 'restore of dmmap-1.0/dmmap.c failed'
+Wc_c="`wc -c < 'dmmap-1.0/dmmap.c'`"
+test 2413 -eq "$Wc_c" ||
+ echo 'dmmap-1.0/dmmap.c: original size 2413, current size' "$Wc_c"
+fi
+# ============= dmmap-1.0/conf/System ==============
+if test ! -d 'dmmap-1.0/conf'; then
+ echo 'x - creating directory dmmap-1.0/conf'
+ mkdir 'dmmap-1.0/conf'
+fi
+if test -f 'dmmap-1.0/conf/System' -a X"$1" != X"-c"; then
+ echo 'x - skipping dmmap-1.0/conf/System (File already exists)'
+else
+echo 'x - extracting dmmap-1.0/conf/System (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'dmmap-1.0/conf/System' &&
+dmmap Y 0 0 0 0 0 0 0 0
+SHAR_EOF
+chmod 0440 dmmap-1.0/conf/System ||
+echo 'restore of dmmap-1.0/conf/System failed'
+Wc_c="`wc -c < 'dmmap-1.0/conf/System'`"
+test 24 -eq "$Wc_c" ||
+ echo 'dmmap-1.0/conf/System: original size 24, current size' "$Wc_c"
+fi
+# ============= dmmap-1.0/conf/Master ==============
+if test -f 'dmmap-1.0/conf/Master' -a X"$1" != X"-c"; then
+ echo 'x - skipping dmmap-1.0/conf/Master (File already exists)'
+else
+echo 'x - extracting dmmap-1.0/conf/Master (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'dmmap-1.0/conf/Master' &&
+dmmap i ico dmap 0 0 0 1 -1
+SHAR_EOF
+chmod 0440 dmmap-1.0/conf/Master ||
+echo 'restore of dmmap-1.0/conf/Master failed'
+Wc_c="`wc -c < 'dmmap-1.0/conf/Master'`"
+test 29 -eq "$Wc_c" ||
+ echo 'dmmap-1.0/conf/Master: original size 29, current size' "$Wc_c"
+fi
+# ============= dmmap-1.0/conf/Node ==============
+if test -f 'dmmap-1.0/conf/Node' -a X"$1" != X"-c"; then
+ echo 'x - skipping dmmap-1.0/conf/Node (File already exists)'
+else
+echo 'x - extracting dmmap-1.0/conf/Node (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'dmmap-1.0/conf/Node' &&
+dmmap dmmap c 0
+SHAR_EOF
+chmod 0440 dmmap-1.0/conf/Node ||
+echo 'restore of dmmap-1.0/conf/Node failed'
+Wc_c="`wc -c < 'dmmap-1.0/conf/Node'`"
+test 16 -eq "$Wc_c" ||
+ echo 'dmmap-1.0/conf/Node: original size 16, current size' "$Wc_c"
+fi
+# ============= dmmap-1.0/conf/install ==============
+if test -f 'dmmap-1.0/conf/install' -a X"$1" != X"-c"; then
+ echo 'x - skipping dmmap-1.0/conf/install (File already exists)'
+else
+echo 'x - extracting dmmap-1.0/conf/install (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'dmmap-1.0/conf/install' &&
+: !/bin/sh
+#
+# installation script for dmmap driver
+#
+X
+if id | grep root > /dev/null 2>&1
+then
+X :
+else
+X echo "Please run this script as root" >&2
+X exit 1
+fi
+X
+if /etc/conf/bin/idinstall -s -g dmmap > /dev/null 2>&1
+then
+X echo "Updating existing dmmap driver ..."
+X /etc/conf/bin/idinstall -k -u dmmap
+else
+X echo "Installing dmmap driver ..."
+X /etc/conf/bin/idinstall -k -a dmmap
+fi
+X
+echo "Do you wish to re-link the kernel now (y/n)[y]: \c"
+read t
+case ${t:-y} in
+[yY]|[yY][eE][sS])
+X cd /etc/conf/bin;
+X ./idbuild
+X ;;
+*)
+X echo "\n\nWarning!"
+X echo "\nYou must re-link the the kernel in order to use the dmmap driver"
+X ;;
+esac
+X
+Xexit 0
+SHAR_EOF
+chmod 0555 dmmap-1.0/conf/install ||
+echo 'restore of dmmap-1.0/conf/install failed'
+Wc_c="`wc -c < 'dmmap-1.0/conf/install'`"
+test 631 -eq "$Wc_c" ||
+ echo 'dmmap-1.0/conf/install: original size 631, current size' "$Wc_c"
+fi
+# ============= dmmap-1.0/test/Makefile ==============
+if test ! -d 'dmmap-1.0/test'; then
+ echo 'x - creating directory dmmap-1.0/test'
+ mkdir 'dmmap-1.0/test'
+fi
+if test -f 'dmmap-1.0/test/Makefile' -a X"$1" != X"-c"; then
+ echo 'x - skipping dmmap-1.0/test/Makefile (File already exists)'
+else
+echo 'x - extracting dmmap-1.0/test/Makefile (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'dmmap-1.0/test/Makefile' &&
+X
+CFLAGS = -D_INKERNEL=1 -D_COMPAT322=1
+X
+all: tst_dmmap
+X
+clean:
+X rm -f *.o tst_dmmap
+X
+SHAR_EOF
+chmod 0440 dmmap-1.0/test/Makefile ||
+echo 'restore of dmmap-1.0/test/Makefile failed'
+Wc_c="`wc -c < 'dmmap-1.0/test/Makefile'`"
+test 85 -eq "$Wc_c" ||
+ echo 'dmmap-1.0/test/Makefile: original size 85, current size' "$Wc_c"
+fi
+# ============= dmmap-1.0/test/tst_dmmap.c ==============
+if test -f 'dmmap-1.0/test/tst_dmmap.c' -a X"$1" != X"-c"; then
+ echo 'x - skipping dmmap-1.0/test/tst_dmmap.c (File already exists)'
+else
+echo 'x - extracting dmmap-1.0/test/tst_dmmap.c (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'dmmap-1.0/test/tst_dmmap.c' &&
+/******************************************************************************/
+/*
+X * Copyright 1993 by David McCullough <davidm@stallion.oz.au>
+X * see file COPYING for more details.
+X */
+/******************************************************************************/
+X
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/vtkd.h>
+X
+/******************************************************************************/
+X
+hex_dump(s, n)
+X unsigned char *s;
+X unsigned int n;
+{
+X int i, j;
+X
+X for (i = 0; i < n; i += 16) {
+X printf("%08x: ", s + i);
+X for (j = 0; j < 8; j++)
+X if (i + j < n)
+X printf("%02x ", s[i + j]);
+X else
+X printf(" ");
+X printf(" ");
+X for (; j < 16; j++)
+X if (i + j < n)
+X printf("%02x ", s[i + j]);
+X else
+X printf(" ");
+X printf(" ");
+X for (j = 0; j < 16; j++)
+X printf("%c", (i+j < n && isprint(s[i + j])) ? s[i+j] : '.');
+X printf("\n");
+X }
+}
+X
+/******************************************************************************/
+X
+main(argc, argv)
+X int argc;
+X char *argv[];
+{
+X int fd, ver;
+X struct kd_memloc memloc;
+X
+X if (argc != 1 && argc != 3) {
+X fprintf(stderr, "usage: %s [physaddr length]\n", argv[0]);
+X exit(1);
+X }
+X
+X if ((fd = open("/dev/dmmap", O_RDWR)) < 0) {
+X fprintf(stderr, "Cannot open /dev/dmmap : %s\n", sys_errlist[errno]);
+X exit(1);
+X }
+X
+X if ((ver = ioctl(fd, -1)) < 0) {
+X perror("Failed to get version");
+X exit(1);
+X }
+X
+X printf("dmmap version 0x%04x\n", ver);
+X
+X memloc.vaddr = NULL; /* this must be NULL for now */
+X if (argc == 1) {
+X memloc.physaddr = (char *) 0xf0000; /* common bios location */
+X memloc.length = 32; /* map only 32 bytes by default */
+X } else {
+X if (sscanf(argv[1], "%i", &memloc.physaddr) != 1) {
+X fprintf(stderr, "physaddr is not a valid number!\n");
+X exit(1);
+X }
+X if (sscanf(argv[2], "%i", &memloc.length) != 1) {
+X fprintf(stderr, "length is not a valid number!\n");
+X exit(1);
+X }
+X }
+X
+X printf("mapping %d bytes at physical address 0x%x\n", memloc.length,
+X memloc.physaddr);
+X
+X if (ioctl(fd, KDMAPDISP, &memloc) < 0) {
+X perror("KDMAPDISP failed");
+X exit(1);
+X }
+X
+X hex_dump(memloc.vaddr, memloc.length);
+X
+X if (ioctl(fd, KDUNMAPDISP, &memloc) < 0) {
+X perror("KDUNMAPDISP failed");
+X exit(1);
+X }
+X
+X close(fd);
+X exit(0);
+}
+X
+/******************************************************************************/
+SHAR_EOF
+chmod 0440 dmmap-1.0/test/tst_dmmap.c ||
+echo 'restore of dmmap-1.0/test/tst_dmmap.c failed'
+Wc_c="`wc -c < 'dmmap-1.0/test/tst_dmmap.c'`"
+test 2384 -eq "$Wc_c" ||
+ echo 'dmmap-1.0/test/tst_dmmap.c: original size 2384, current size' "$Wc_c"
+fi
+exit 0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/et4000clock.c b/xc/programs/Xserver/hw/xfree86/etc/et4000clock.c
new file mode 100644
index 000000000..832bebf32
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/et4000clock.c
@@ -0,0 +1,134 @@
+/*
+ * $XFree86: xc/programs/Xserver/hw/xfree86/etc/et4000clock.c,v 3.6 1999/05/07 02:56:17 dawes Exp $
+ *
+ * This is a sample clock setting program. It will not work with all
+ * ET4000 cards. To work correctly the clocks line in XF86Config must
+ * have the values in the correct order.
+ *
+ * usage: et4000clock freq index
+ *
+ * This program ignores 'freq' and relies entirely on 'index'
+ *
+ * David Dawes <dawes@xfree86.org>
+ * 19 December 1992
+ */
+/* $XConsortium: et4000clock.c /main/7 1996/10/25 11:37:41 kaleb $ */
+
+#include <stdio.h>
+
+/* The following inlines are from compiler.h in the XFree86 source dist */
+
+#if defined(CSRG_BASED) || defined(MACH) || defined(MACH386) || defined(linux)
+#define GCCUSESGAS
+#endif
+
+#ifdef __GNUC__
+#ifdef GCCUSESGAS
+
+static __inline__ void
+outb(port, val)
+short port;
+char val;
+{
+ __asm__ __volatile__("outb %0,%1" : :"a" (val), "d" (port));
+}
+
+static __inline__ void
+outw(port, val)
+short port;
+short val;
+{
+ __asm__ __volatile__("outw %0,%1" : :"a" (val), "d" (port));
+}
+
+static __inline__ unsigned int
+inb(port)
+short port;
+{
+ unsigned char ret;
+ __asm__ __volatile__("inb %1,%0" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+#else /* !GCCUSESGAS */
+
+static __inline__ void
+outb(port, val)
+ short port;
+ char val;
+{
+ __asm__ __volatile__("out%B0 (%1)" : :"a" (val), "d" (port));
+}
+
+static __inline__ void
+outw(port, val)
+ short port;
+ short val;
+{
+ __asm__ __volatile__("out%W0 (%1)" : :"a" (val), "d" (port));
+}
+
+static __inline__ unsigned int
+inb(port)
+ short port;
+{
+ unsigned int ret;
+ __asm__ __volatile__("in%B0 (%1)" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+#endif /* GCCUSESGAS */
+#else /* !__GNUC__ */
+
+#if defined(__STDC__) && (__STDC__ == 1)
+#define asm __asm
+#endif
+
+#ifdef SVR4
+#include <sys/types.h>
+#ifndef __USLC__
+#define __USLC__
+#endif
+#endif
+
+#ifndef SCO325
+# include <sys/inline.h>
+#else
+# include "../common/scoasm.h"
+#endif
+#endif /* __GNUC__ */
+
+
+/* Now, the actual program */
+
+main(argc, argv)
+
+int argc;
+char *argv[];
+
+{
+ int index, vgaIOBase;
+ unsigned char tmp;
+
+ if (argc < 3)
+ {
+ fprintf(stderr, "usage: %s freq index\n", argv[0]);
+ exit(1);
+ }
+ index = atoi(argv[2]);
+ if (index < 0 || index > 7)
+ {
+ fprintf(stderr, "%s: Index %d out of range\n", argv[0], index);
+ exit(2);
+ }
+ tmp = inb(0x3CC);
+ vgaIOBase = (tmp & 0x01) ? 0x3D0 : 0x3B0;
+ outb(0x3C2, (tmp & 0xF3) | ((index & 0x03) << 2));
+ outw(vgaIOBase + 4, 0x34 | ((index & 0x04) << 7));
+ fprintf(stderr, "%s: clock set to number %d\n", argv[0], index);
+ exit(0);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/etc/install.sv3 b/xc/programs/Xserver/hw/xfree86/etc/install.sv3
new file mode 100644
index 000000000..842150ad3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/install.sv3
@@ -0,0 +1,652 @@
+#!/bin/sh
+#
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/install.sv3,v 3.8 1999/03/28 15:32:51 dawes Exp $
+#
+# Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of Thomas Roell not be used in
+# advertising or publicity pertaining to distribution of the software without
+# specific, written prior permission. Thomas Roell makes no representations
+# about the suitability of this software for any purpose. It is provided
+# "as is" without express or implied warranty.
+#
+# THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+# EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+#
+# Author: Thomas Roell, roell@informatik.tu-muenchen.de
+#
+
+# Changed for XFree86 by Thomas Wolfram,
+# (thomas@aeon.in-berlin.de, wolf@prz.tu-berlin.de)
+# Changed for XFree86 3.1 to coexist with Interactive X11 by Michael Rohleder
+# (michael.rohleder@stadt-frankfurt.de)
+#
+# Changed interface handling (now Menu) via helper functions
+# Changed tunable parameters
+# Changed Device generation for more flexibility
+# (michael.rohleder@stadt-frankfurt.de)
+
+# $XConsortium: install.sv3 /main/4 1996/02/21 17:47:34 kaleb $
+
+#
+# XFree86 version
+#
+#VERSION=4.0
+#this assumes: the current X can be found via PATH
+VERSION=`X -version 2>&1 |
+ grep 'XFree86 Version' | sed -e 's/^.*Version //' -e 's/ .*$//'`
+
+VERSION_STRING="X11R6 XFree86 Version $VERSION"
+#
+# Path/Files
+#
+XFREE86_NAME=xfree86.name
+INSTALLED=/usr/lib/installed
+REMOVEDIR=$INSTALLED/Remove
+REMOVESRC=$REMOVEDIR/$XFREE86_NAME
+
+OPTIONS=/usr/options
+KC_NAME=$OPTIONS/kc.name
+ST_NAME=$OPTIONS/st.name
+XF86_NAME=$OPTIONS/$XFREE86_NAME
+XU_NAME=$OPTIONS/xu.name
+
+XHOME=/usr/X11R6
+PRGHOME=$XHOME/lib/X11/etc
+
+KCONF=/etc/conf
+NODED=$KCONF/node.d
+SDEVD=$KCONF/sdevice.d
+CFD=$KCONF/cf.d
+
+MTUNE=$CFD/mtune
+STUNE=$CFD/stune
+MDEVICE=$CFD/mdevice
+IDTUNE=$KCONF/bin/idtune
+
+NODED_LIST="$NODED/pts $NODED/sp $NODED/pty $NODED/ptx"
+SDEVD_LIST="$SDEVD/pts $SDEVD/sp $SDEVD/pty $SDEVD/ptx $SDEVD/ldterm $SDEVD/ptem $SDEVD/ptm"
+FILE_LIST="$MDEVICE $NODED_LIST $SDEVD_LIST"
+
+SAVE_NAME=`uname`.$$.cpio
+
+MAX_PTYS=128
+
+#
+# trap
+#
+trap goodbye 1 2 9 15
+
+#
+# Functions ....
+#
+Head() {
+clear
+echo
+echo $VERSION_STRING
+echo -------------------------------------------------------------------------------
+echo
+echo
+echo
+}
+
+Wait() {
+echo
+echo
+echo -n "[PRESS RETURN TO GO ON]"
+read anykey
+}
+
+#
+# Save current Kernel Files
+#
+mk_save() {
+echo "Saving to: $SAVE_NAME"
+find $FILE_LIST -print | cpio -ovc > $SAVE_NAME
+}
+
+show_save() {
+find $FILE_LIST -print
+}
+
+#
+# dependencies
+#
+dependencies() {
+if [ ! -s $KC_NAME ]
+then
+ echo "Please make first sure that the Kernel Configuration is installed"
+ echo "correctly. Then try a reinstall of XFree86 $VERSION."
+ exit 1
+else
+echo "OK ::: $KC_NAME: `sed 's/-.*Version//' $KC_NAME`"
+fi
+echo
+if [ ! -s $ST_NAME ]
+then
+ echo "Please make first sure that the STREAMS Facilities are installed"
+ echo "correctly. Then try a reinstall of XFree86 $VERSION."
+ exit 1
+else
+echo "OK ::: $ST_NAME: `sed 's/-.*Version//' $ST_NAME`"
+fi
+echo
+echo
+echo
+echo "Your dependecies are correct :-)"
+}
+
+#
+# Make a X11 label, so that following commercial products can be installed
+#
+mk_label() {
+if [ ! -s $XF86_NAME ]
+then
+ echo $VERSION_STRING > $XF86_NAME
+else
+ echo "The following XFree86 Version is installed:"
+ echo
+ cat $XF86_NAME
+ echo
+ echo -n "Should I Update this to $VERSION ?(y/n)"
+ read yesno
+ [ "$yesno" = "y" -o "$yesno" = "Y" ] && {
+ echo $VERSION_STRING > $XF86_NAME
+ echo
+ echo "Updated !!!"
+ }
+fi
+echo
+echo -n "Current Version: "
+cat $XF86_NAME
+echo
+
+if [ ! -s $XU_NAME ]
+then
+ echo "There's no Interactive X11 installed"
+ echo "Generating links, so following commercial products can be installed"
+ ln $XF86_NAME $XU_NAME
+ echo
+fi
+
+}
+
+#
+# Install remove script
+#
+mk_remove() {
+if [ ! -s $REMOVESRC ]
+then
+ echo "Install remove script"
+ echo -n 'echo "Removing XFree86 Version ' >$REMOVESRC
+ echo -n $VERSION >>$REMOVESRC
+ echo '"' >>$REMOVESRC
+ echo '/bin/rm -rf /usr/X11R6' >>$REMOVESRC
+ echo '/bin/rm -f /usr/options/xfree86.name' >>$REMOVESRC
+ echo "Installed !!!"
+else
+ echo -n "Would you like to update your remove script ? (j/n)"
+ read yesno
+ [ "$yesno" = "y" -o "$yesno" = "Y" ] && {
+ echo -n 'echo "Removing XFree86 Version ' >$REMOVESRC
+ echo -n $VERSION >>$REMOVESRC
+ echo '"' >>$REMOVESRC
+ echo '/bin/rm -rf /usr/X11R6' >>$REMOVESRC
+ echo '/bin/rm -f /usr/options/xfree86.name' >>$REMOVESRC
+ echo "Updated !!!"
+ }
+fi
+}
+
+
+#
+# Tune PTS Devices
+# call with number of entries to create e.g. mk_dev_pts 128
+#
+mk_dev_pts() {
+nawk ' { max_pts=$4; print }
+ END { for (i=max_pts+1;i<'$1';i++)
+ printf("pts pts%03d c %d\n", i , i );
+ }
+ ' < $NODED/pts > pts.node.neu
+tail -1 $NODED/pts
+tail -1 pts.node.neu
+echo -n "Should I install the new pts File ?(y/n)"
+read yesno
+case $yesno in
+ y|Y ) echo "Do install .... "
+ mv pts.node.neu $NODED/pts
+ ;;
+ n|N ) echo "Dont install .. "
+ ;;
+esac
+rm -f pts.node.neu
+}
+
+#
+# Set up node and sdevice
+#
+mk_node_sdevice() {
+echo -n "Setting up node and sdevice(y/n)"
+read yesno
+[ "$yesno" = "y" -o "$yesno" = "Y" ] && {
+OWD=`pwd`
+cd $PRGHOME
+[ -s $NODED/pts ] || {
+ echo "Installed: $NODED/pts"
+ cp pts.node $NODED/pts 2>/dev/null
+ }
+tail -1 $NODED/pts
+mk_dev_pts $MAX_PTYS
+[ -s $NODED/sp ] || {
+ echo "Installed: $NODED/sp"
+ cp sp.node $NODED/sp 2>/dev/null
+ }
+tail -1 $NODED/sp
+[ -s $SDEVD/ldterm ] || {
+ echo "Installed: $SDEVD/ldterm"
+ cp ldterm.sdevice $SDEVD/ldterm 2>/dev/null
+ }
+tail -1 $SDEVD/ldterm
+[ -s $SDEVD/ptem ] || {
+ echo "Installed: $SDEVD/ptem"
+ cp ptem.sdevice $SDEVD/ptem 2>/dev/null
+ }
+tail -1 $SDEVD/ptem
+change_sdevice ptem
+[ -s $SDEVD/ptm ] || {
+ echo "Installed: $SDEVD/ptm"
+ cp ptm.sdevice $SDEVD/ptm 2>/dev/null
+ }
+tail -1 $SDEVD/ptm
+change_sdevice ptm
+change_mdevice "pt[em]"
+[ -s $SDEVD/pts ] || {
+ echo "Installed: $SDEVD/pts"
+ cp pts.sdevice $SDEVD/pts 2>/dev/null
+ }
+tail -1 $SDEVD/pts
+[ -s $SDEVD/sp ] || {
+ echo "Installed: $SDEVD/sp"
+ cp sp.sdevice $SDEVD/sp 2>/dev/null
+ }
+tail -1 $SDEVD/sp
+cd $OWD
+}
+}
+
+#
+# Show current values
+#
+show_node_sdevice() {
+OWD=`pwd`
+cd $PRGHOME
+Head
+echo
+echo pts
+tail -1 pts.node
+tail -1 $NODED/pts
+tail -1 pts.sdevice
+tail -1 $SDEVD/pts
+Wait
+Head
+echo
+echo sp
+tail -1 sp.node
+tail -1 $NODED/sp
+tail -1 sp.sdevice
+tail -1 $SDEVD/sp
+Wait
+Head
+echo
+echo ldterm
+tail -1 ldterm.sdevice
+tail -1 $SDEVD/ldterm
+Wait
+Head
+echo
+echo ptem
+tail -1 ptem.sdevice
+tail -1 $SDEVD/ptem
+Wait
+Head
+echo
+echo ptm
+tail -1 ptm.sdevice
+tail -1 $SDEVD/ptm
+cd $OWD
+}
+#
+# Set some Kernel Variables ...
+#
+mk_kvars() {
+echo "Setup KERNEL Variables to suit the needs..."
+echo "if you don't want this changes - enter s to skip"
+read skip
+[ "$skip" != "s" ] && {
+ /bin/sh /etc/conf/bin/idtune -m NOFILES 100
+ /bin/sh /etc/conf/bin/idtune -m MAXUMEM 131072
+}
+
+
+#
+# Setup STREAMS for maximum performance
+#
+echo "Setup STREAMS for maximum performance..."
+echo "if you allready tuned the STREAMS parameters - enter s to skip"
+read skip
+[ "$skip" != "s" ] && {
+ /bin/sh /etc/conf/bin/idtune -m NSTREAM 512
+ /bin/sh /etc/conf/bin/idtune -m NQUEUE 2048
+ /bin/sh /etc/conf/bin/idtune -m NBLK4096 512
+ /bin/sh /etc/conf/bin/idtune -m NBLK2048 1024
+ /bin/sh /etc/conf/bin/idtune -m NBLK1024 1024
+ /bin/sh /etc/conf/bin/idtune -m NBLK512 1024
+ /bin/sh /etc/conf/bin/idtune -m NBLK256 1024
+ /bin/sh /etc/conf/bin/idtune -m NBLK128 1024
+ /bin/sh /etc/conf/bin/idtune -m NBLK64 1024
+ /bin/sh /etc/conf/bin/idtune -m NBLK16 1024
+ /bin/sh /etc/conf/bin/idtune -m NBLK4 1024
+ /bin/sh /etc/conf/bin/idtune -m SHLBMAX 12
+}
+}
+
+#
+# Show current Kernel Vars
+#
+show_kvars() {
+nawk '
+BEGIN { printf"%-40s%s\n\n", "Variable", "Current Value" }
+/NOFILES|MAXUMEM|NSTREAM|NQUEUE|NBLK|SHLBMAX/ { printf"%-40s%s\n", $1, $NF }
+ ' $STUNE
+}
+
+# increase number of pseudo terminals from 16 to 32
+
+change_sdevice() {
+FILE=$SDEVD/$1
+nawk '{
+ if ($1 == "'"$1"'") {
+ print $1 "\t" $2 "\t" '"$MAX_PTYS"' "\t" $4 "\t" $5 "\t" $6 "\t" $7 "\t" $8 "\t" $9 "\t" $10
+ }
+ else
+ print
+}' < $FILE > $1.sdevice.neu
+tail -1 $FILE
+tail -1 $1.sdevice.neu
+echo -n "Should I install the new $1 File ?(y/n)"
+read yesno
+case $yesno in
+ y|Y ) echo "Do install .... "
+ mv $1.sdevice.neu $FILE
+ ;;
+ n|N ) echo "Dont install .. "
+ ;;
+esac
+rm -f $1.sdevice.neu
+}
+
+#
+# Change mdevice
+#
+change_mdevice() {
+nawk '{
+ if ($1 ~ "'"$1"'") {
+ print $1 "\t" $2 "\t" $3 "\t\t" $4 "\t" $5 "\t" $6 "\t" $7 "\t" '"$MAX_PTYS"' "\t" $9
+ }
+ else
+ print
+ }' < $MDEVICE > mdevice.neu
+
+grep "$1" $MDEVICE
+grep "$1" mdevice.neu
+echo -n "Should I install the new $MDEVICE File ?(y/n)"
+read yesno
+case $yesno in
+ y|Y ) echo "Do install .... "
+ mv mdevice.neu $MDEVICE
+ ;;
+ n|N ) echo "Dont install .. "
+ ;;
+esac
+rm -f mdevice.neu
+}
+
+#
+# Generate PTY Files
+#
+mk_ptys() {
+echo "Adjust kernel configuration files for $MAX_PTYS pseudo terminals..."
+
+if [ `grep pty $SDEVD/pty | cut -f3` -ge $MAX_PTYS ] ; then
+ echo "There are already more then $MAX_PTYS pty's."
+else
+
+change_sdevice pty
+#mv /etc/conf/sdevice.d/pty /etc/conf/sdevice.d/pty.old
+#nawk '{
+# if ($1 == "pty") {
+# print $1 "\t" $2 "\t" 32 "\t" $4 "\t" $5 "\t" $6 "\t" $7 "\t" $8 "\t" $9 "\t" $10
+# }
+# else
+# print
+#}' </etc/conf/sdevice.d/pty.old >/etc/conf/sdevice.d/pty
+#rm /etc/conf/sdevice.d/pty.old
+
+change_sdevice ptx
+#mv /etc/conf/sdevice.d/ptx /etc/conf/sdevice.d/ptx.old
+#nawk '{
+# if ($1 == "ptx") {
+# print $1 "\t" $2 "\t" 32 "\t" $4 "\t" $5 "\t" $6 "\t" $7 "\t" $8 "\t" $9 "\t" $10
+# }
+# else
+# print
+#}' </etc/conf/sdevice.d/ptx.old >/etc/conf/sdevice.d/ptx
+#rm /etc/conf/sdevice.d/ptx.old
+
+change_mdevice "pt[y|x]"
+#mv /etc/conf/cf.d/mdevice /etc/conf/cf.d/mdevice.old
+#nawk '{
+# if ($1 ~ "pt[y|x]") {
+# print $1 "\t" $2 "\t" $3 "\t\t" $4 "\t" $5 "\t" $6 "\t" $7 "\t" 32 "\t" $9
+# }
+# else
+# print
+# }' </etc/conf/cf.d/mdevice.old >/etc/conf/cf.d/mdevice
+#rm /etc/conf/cf.d/mdevice.old
+
+CHECK_PTY=`expr $MAX_PTYS - 1`
+HAS_PTC=`grep "PTC_UNITS > $MAX_PTYS" /etc/conf/node.d/pty`
+[ "$HAS_PTC" = "" ] && \
+HAS_PTC=`grep "PTC_UNITS > $CHECK_PTYS" /etc/conf/node.d/pty`
+[ "$HAS_PTC" = "" ] && {
+echo "pty ptyq0 c 16
+pty ptyq1 c 17
+pty ptyq2 c 18
+pty ptyq3 c 19
+pty ptyq4 c 20
+pty ptyq5 c 21
+pty ptyq6 c 22
+pty ptyq7 c 23
+pty ptyq8 c 24
+pty ptyq9 c 25
+pty ptyqa c 26
+pty ptyqb c 27
+pty ptyqc c 28
+pty ptyqd c 29
+pty ptyqe c 30
+pty ptyqf c 31" >>/etc/conf/node.d/pty
+}
+
+HAS_PTX=`grep "PTX_UNITS > $MAX_PTYS" /etc/conf/node.d/ptx`
+[ "$HAS_PTX" = "" ] && \
+HAS_PTX=`grep "PTX_UNITS > $CHECK_PTYS" /etc/conf/node.d/ptx`
+[ "$HAS_PTX" = "" ] && {
+echo "ptx ttyq0 c 16
+ptx ttyq1 c 17
+ptx ttyq2 c 18
+ptx ttyq3 c 19
+ptx ttyq4 c 20
+ptx ttyq5 c 21
+ptx ttyq6 c 22
+ptx ttyq7 c 23
+ptx ttyq8 c 24
+ptx ttyq9 c 25
+ptx ttyqa c 26
+ptx ttyqb c 27
+ptx ttyqc c 28
+ptx ttyqd c 29
+ptx ttyqe c 30
+ptx ttyqf c 31" >>/etc/conf/node.d/ptx
+}
+
+fi
+}
+
+#
+# notify the user to build a new kernel
+#
+notify() {
+echo "*** New Installation ***"
+echo "If this is a new installation of XFree86 $VERSION use \"kconfig\" to build a new"
+echo "kernel. XFree86 won't run without this new kernel."
+echo ""
+#echo "<press return>"
+#read answer
+}
+
+#
+# install additional termcap & terminfo entries
+#
+mk_term() {
+echo -n "Do you want me to Install additional termcap & terminfo entries...[y/n]"
+read answer
+[ "$answer" = "y" -o "$answer" = "Y" ] && {
+grep xterm /etc/termcap >/dev/null || cat xterm.termcap >>/etc/termcap
+grep sun-cmd /etc/termcap >/dev/null || cat sun.termcap >>/etc/termcap
+
+tic sun.terminfo 2>/dev/null
+tic xterm.terminfo 2>/dev/null
+}
+}
+
+#
+# install vga font
+#
+mk_vgafont() {
+if [ -s /usr/lib/loadfont/vga437.bdf ]
+then
+ echo -n "Convert VGA font for using under X11...(y/n)"
+ read answer
+ [ "$answer" = "y" -o "$answer" = "Y" ] && {
+ sed -e 's/FONT 8x16/FONT vga/' </usr/lib/loadfont/vga437.bdf \
+ | bdftopcf -t >/usr/X11R6/lib/X11/fonts/misc/vga.pcf
+ chmod 644 /usr/X11R6/lib/X11/fonts/misc/fonts.dir
+ mkfontdir /usr/X11R6/lib/X11/fonts/misc
+ }
+fi
+}
+
+#
+# Exit
+#
+goodbye() {
+Head
+echo
+echo
+echo -n "Thats all folks ;-) Current XFree86 Version: "
+cat /usr/options/xfree86.name
+echo
+echo
+echo
+echo
+exit
+}
+
+while [ 1 ]
+do
+ Head
+ echo
+ echo " Check dependencies: 1"
+ echo " Make XFree86 Label 2"
+ echo " Install Remove script 3"
+ echo " Setup node.d + sdevice.d Files 4"
+ echo " Tune Kernel Variables 5"
+ echo " Tune PseudoTerminals 6"
+ echo " Install xterm terminal entries 7"
+ echo " Install VGA font 8"
+ echo " Save current KernelConfig 9"
+ echo
+ echo " Exit X"
+
+ echo
+ echo
+ echo -n "Your Choice [1-9]?<enter>: "
+ read in
+
+ Head
+ case $in in
+ 1 ) echo
+ dependencies
+ ;;
+ 1?|?1 ) echo "1 HELP"
+ ;;
+ 2 ) echo
+ mk_label
+ ;;
+ 2?|?2 ) echo "2 HELP"
+ ;;
+ 3 ) echo
+ mk_remove
+ ;;
+ 3?|?3 ) echo "3 HELP"
+ ;;
+ 4 ) echo
+ mk_node_sdevice
+ ;;
+ 4?|?4 )
+ show_node_sdevice
+ ;;
+ 5 ) echo
+ mk_kvars
+ ;;
+ 5?|?5 ) echo
+ show_kvars
+ ;;
+ 6 ) echo
+ mk_ptys
+ ;;
+ 6?|?6 ) echo
+ change_sdevice pty
+ change_sdevice ptx
+ ;;
+ 7 ) echo "7"
+ ;;
+ 7?|?7 ) echo "7 HELP"
+ ;;
+ 8 ) echo
+ mk_vgafont
+ ;;
+ 8?|?8 ) echo "8 HELP"
+ ;;
+ 9 ) echo
+ mk_save
+ ;;
+ 9?|?9 ) echo
+ show_save
+ ;;
+ q|Q|X|x ) echo
+ goodbye
+ ;;
+ esac
+ Wait
+done
diff --git a/xc/programs/Xserver/hw/xfree86/etc/install.sv4 b/xc/programs/Xserver/hw/xfree86/etc/install.sv4
new file mode 100644
index 000000000..e38b59cce
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/install.sv4
@@ -0,0 +1,37 @@
+#!/bin/sh
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/install.sv4,v 3.3 1996/12/23 06:47:11 dawes Exp $
+#
+# Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of Thomas Roell not be used in
+# advertising or publicity pertaining to distribution of the software without
+# specific, written prior permission. Thomas Roell makes no representations
+# about the suitability of this software for any purpose. It is provided
+# "as is" without express or implied warranty.
+#
+# THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+# EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+#
+# Author: Thomas Roell, roell@informatik.tu-muenchen.de
+#
+
+# $XConsortium: install.sv4 /main/3 1996/02/21 17:47:37 kaleb $
+
+#
+# install addtional termcap & terminfo entries
+#
+grep xterm /etc/termcap >/dev/null || cat xterm.termcap >>/etc/termcap
+grep sun-cmd /etc/termcap >/dev/null || cat sun.termcap >>/etc/termcap
+
+tic sun.terminfo 2>/dev/null
+tic xterm.terminfo 2>/dev/null
+
diff --git a/xc/programs/Xserver/hw/xfree86/etc/joycal.c b/xc/programs/Xserver/hw/xfree86/etc/joycal.c
new file mode 100644
index 000000000..7222565ed
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/joycal.c
@@ -0,0 +1,88 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/etc/joycal.c,v 3.4 1997/11/22 00:00:18 hohndel Exp $ */
+
+/* A simple program to get the Joystick calibration coordinates */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+#if defined (__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#include <machine/joystick.h>
+#define JS_RETURN sizeof(struct joystick)
+#define JS_DATA_TYPE joystick
+#define button_down(j) (j.b1 | j.b2)
+#endif
+#ifdef linux
+#define inline __inline__
+#include <linux/joystick.h>
+#define button_down(j) (j.buttons)
+#if defined(JSIOCGTIMELIMIT)
+/* make 2.1.x joystick.h backward compatable */
+#define JS_DATA_TYPE js_status
+#endif
+
+#endif
+#include <fcntl.h>
+#include <stdio.h>
+
+extern int errno;
+
+#define TIMEOUT_JS 50000
+
+main(int argc, char *argv[])
+{
+ int fd;
+ int cx, cy, minx, miny, maxx, maxy;
+ int xdiff, ydiff;
+ struct JS_DATA_TYPE js;
+ char l[8];
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s device\n", argv[0]);
+ exit(1);
+ }
+
+ if ((fd = open(argv[1], O_RDWR | O_NDELAY)) < 0) {
+ fprintf(stderr, "%s: cannot open joystick device %s\n", argv[0], argv[1]);
+ exit(1);
+ }
+
+ fprintf(stderr, "Center the joystick, then press a button\n");
+ do {
+ read(fd, &js, JS_RETURN);
+ usleep(TIMEOUT_JS);
+ } while (!button_down(js));
+ cx = js.x; cy = js.y;
+ printf("Center coordinates: %d, %d\n", js.x, js.y);
+ sleep(1);
+ fprintf(stderr, "Position the joystick at upper left, then press a button\n");
+ do {
+ read(fd, &js, JS_RETURN);
+ usleep(TIMEOUT_JS);
+ } while (!button_down(js));
+ minx = js.x; miny = js.y;
+ printf("Upper left coordinates: %d, %d\n", js.x, js.y);
+ sleep(1);
+ fprintf(stderr, "Position the joystick at lower right, then press a"
+ " button\n");
+ do {
+ read(fd, &js, JS_RETURN);
+ usleep(TIMEOUT_JS);
+ } while (!button_down(js));
+ printf("Lower right coordinates: %d, %d\n", js.x, js.y);
+ maxx = js.x; maxy = js.y;
+ xdiff = (maxx - minx) / 2;
+ ydiff = (maxy - miny) / 2;
+ maxx = cx + xdiff;
+ minx = cx - xdiff;
+ maxy = cy + ydiff;
+ miny = cy - ydiff;
+ printf("\n");
+ printf("CenterX %d\n", cx);
+ printf("CenterY %d\n", cy);
+ printf("MinimumXPosition %d\n", minx);
+ printf("MaximumXPosition %d\n", maxx);
+ printf("MinimumYPosition %d\n", miny);
+ printf("MaximumYPosition %d\n", maxy);
+ close(fd);
+ exit(0);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/etc/kbd_mode.c b/xc/programs/Xserver/hw/xfree86/etc/kbd_mode.c
new file mode 100644
index 000000000..f7d07eb79
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/kbd_mode.c
@@ -0,0 +1,97 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/etc/kbd_mode.c,v 3.6 1998/07/26 09:56:17 dawes Exp $ */
+
+
+/* Keyboard mode control program for 386BSD */
+
+
+/* $XConsortium: kbd_mode.c /main/7 1996/03/11 10:46:12 kaleb $ */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "X.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+static int fd;
+
+void
+msg (char* s)
+{
+ perror (s);
+ close (fd);
+ exit (-1);
+}
+
+int
+main(int argc, char** argv)
+{
+#if defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT)
+ vtmode_t vtmode;
+#endif
+ Bool syscons = FALSE;
+
+ if ((fd = open("/dev/vga",O_RDONLY,0)) <0)
+ msg ("Cannot open /dev/vga");
+
+#if defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT)
+ /* Check if syscons */
+ if (ioctl(fd, VT_GETMODE, &vtmode) >= 0)
+ syscons = TRUE;
+#endif
+
+ if (0 == strcmp (argv[1], "-u"))
+ {
+ if (syscons)
+ {
+#if defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT)
+ ioctl (fd, KDSKBMODE, K_RAW);
+#endif
+ }
+ else
+ {
+ if (ioctl (fd, CONSOLE_X_MODE_ON, 0) < 0)
+ {
+ close (fd);
+ exit (0); /* Assume codrv, so nothing to do */
+ }
+ }
+ }
+ else if (0 == strcmp (argv[1], "-a"))
+ {
+ if (syscons)
+ {
+#if defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT)
+ ioctl (fd, KDSKBMODE, K_XLATE);
+#endif
+ }
+ else
+ {
+ if (ioctl (fd, CONSOLE_X_MODE_OFF, 0) < 0)
+ {
+ close (fd);
+ exit (0); /* Assume codrv, so nothing to do */
+ }
+ }
+ }
+ else
+ {
+ close (fd);
+ fprintf (stderr,"Usage: %s [-u|-a]\n",argv[0]);
+ fprintf (stderr,"-u for sending up down key events in x mode.\n");
+ fprintf (stderr,"-a for sending ascii keys in normal use.\n");
+ exit (-1);
+ }
+ close (fd);
+ exit (0);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/etc/kbd_mode.man b/xc/programs/Xserver/hw/xfree86/etc/kbd_mode.man
new file mode 100644
index 000000000..ca4767d09
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/kbd_mode.man
@@ -0,0 +1,36 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/etc/kbd_mode.man,v 3.4 1998/04/05 02:28:42 dawes Exp $
+.TH KBD_MODE 1 "Release 6.3 (XFree86 3.2)" "X Version 11"
+.SH NAME
+kbd_mode \- recover the PC console keyboard
+.SH SYNOPSIS
+.B kbd_mode
+[ -a -u ]
+.SH DESCRIPTION
+.I Kbd_mode
+resets the PC console keyboard to a rational state.
+.SH OPTIONS
+The following options are supported:
+.TP 8
+.B \-a
+Set the keyboard so that ASCII characters are read from the console.
+.TP 8
+.B \-u
+Set the keyboard so that undecoded keyboard values are read from the
+console.
+.SH EXAMPLES
+If the server crashes or otherwise fails to put the keyboard back in
+ascii mode when it exits, it can leave your keyboard dead. If you are
+able to login remotely, you can reset it typing:
+.sp
+ kbd_mode -a
+.sp
+.PP
+Conversely, changing the keyboard to ascii mode while the server is
+running will make the keyboard appear to be dead while the the mouse
+continues to work. Again, if you are able to login remotely, you can
+reset it typing:
+.sp
+ kbd_mode -u
+.sp
+
+.\" $TOG: kbd_mode.man /main/6 1997/07/19 10:37:14 kaleb $
diff --git a/xc/programs/Xserver/hw/xfree86/etc/ld-wrapper.c b/xc/programs/Xserver/hw/xfree86/etc/ld-wrapper.c
new file mode 100644
index 000000000..e3975202d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/ld-wrapper.c
@@ -0,0 +1,169 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/etc/ld-wrapper.c,v 3.3 1996/12/23 06:47:15 dawes Exp $ */
+/*
+ * Copyright 1993 by Thomas Mueller
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Mueller not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Mueller makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS MUELLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS MUELLER 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.
+ *
+ */
+
+/* $XConsortium: ld-wrapper.c /main/4 1996/02/21 17:47:57 kaleb $ */
+
+/* LynxOS V2.2.x /bin/ld wrapper to emulate -L option */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <limits.h>
+
+extern char *strdup();
+
+/* check for '-L dir' arguments and collect them... */
+/* check for '-llib' and check if these libs are in */
+/* the so far collected '-L dir' places... */
+/* if found, replace -llib with the complete path */
+
+#define MAX_L 32 /* maximum of -L options... */
+#define MAX_LIB 512 /* maximum of -l options... */
+
+#ifdef DEBUG
+#define dbg(x) x
+#else
+#define dbg(x)
+#endif
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+ int i, j, l;
+ char buf[MAXPATHLEN];
+
+ char *L[MAX_L];
+ int L_num = 0;
+
+ char *lib[MAX_LIB];
+ int lib_num = 0;
+ int verbose = 0;
+
+ char *opt;
+
+ char **myargv;
+
+ for (i = 1; i < argc; i++)
+ {
+ if (!strncmp(argv[i], "-v", 2))
+ {
+ ++verbose;
+ continue;
+ }
+ }
+
+ myargv = (char **) calloc(argc + 10, sizeof(char *));
+ if (!myargv)
+ {
+ fprintf(stderr, "out of memory, can't alloc %d char pointers\n", argc + 10);
+ exit(1);
+ }
+
+ myargv[0] = "/bin/ld.org";
+ if (argc > 1)
+ for (i = j = 1; i < argc;)
+ {
+ dbg((printf("argc %d = \"%s\"\n", i, argv[i])));
+ if (*argv[i] != '-')
+ {
+ dbg((printf("copy: myargc %d = \"%s\"\n", j, argv[i])));
+ myargv[j++] = argv[i++];
+ }
+ else
+ {
+ int found;
+
+ switch (argv[i][1])
+ {
+ case 'L':
+ dbg((printf("got -L")));
+ if (strlen(argv[i]) == 2)
+ {
+ dbg((printf("(with argument)")));
+ ++i; /* skip argument to -L */
+ L[L_num++] = strdup(argv[i]);
+ }
+ else
+ L[L_num++] = strdup(&argv[i][2]);
+ ++i;
+ dbg((printf("-L directory %s\n", L[L_num - 1])));
+ break;
+
+ case 'l':
+ dbg((printf("got -l >%s<", argv[i])));
+ if (strlen(argv[i]) == 2)
+ {
+ fprintf(stderr, "spurious -l option\n");
+ ++i;
+ break;
+ }
+
+ /* do the job.... */
+ for (l = found = 0; !found && l < L_num; l++)
+ {
+ sprintf(buf, "%s/lib%s.a", L[l], &argv[i][2]);
+ dbg((printf("..checking >%s< ", buf)));
+ if (access(buf, R_OK) == 0)
+ {
+ dbg((printf("FOUND!!\nmyargc = %d = \"%s\"\n", j, buf)));
+ /* gotcha! */
+ myargv[j++] = strdup(buf);
+ found = 1;
+ i++;/* next argument */
+ }
+ else
+ dbg((printf("not found\n")));
+ }
+ if (!found)
+ {
+ dbg((printf("%s not found in -L list, copying\n", argv[i])));
+ dbg((printf("copy: myargc %d = \"%s\"\n", j, argv[i])));
+ myargv[j++] = argv[i++];
+ }
+ break;
+ default:
+ dbg((printf("copy: myargc %d = \"%s\"\n", j, argv[i])));
+ myargv[j++] = argv[i++];
+ break;
+ }
+ }
+ }
+
+ if (verbose)
+ {
+ for (i = 0; i < j; i++)
+ printf("%d\t%s\n", i, myargv[i] ? myargv[i] : "(null)");
+ fflush(stdout);
+ }
+
+ if (execvp("/bin/ld.org", myargv) < 0)
+ {
+ perror("execvp");
+ exit(1);
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/etc/ldterm.sdevice b/xc/programs/Xserver/hw/xfree86/etc/ldterm.sdevice
new file mode 100644
index 000000000..6fb05059a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/ldterm.sdevice
@@ -0,0 +1 @@
+ldterm Y 16 0 0 0 0 0 0 0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/mmapSVR3.shar b/xc/programs/Xserver/hw/xfree86/etc/mmapSVR3.shar
new file mode 100644
index 000000000..ee36eecda
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/mmapSVR3.shar
@@ -0,0 +1,2479 @@
+#!/bin/sh
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/mmapSVR3.shar,v 3.2 1996/12/23 06:47:16 dawes Exp $
+# This is a shell archive (produced by shar 3.49)
+# To extract the files from this archive, save it to a file, remove
+# everything above the "!/bin/sh" line above, and type "sh file_name".
+#
+# made 02/26/1994 03:10 UTC by root@gamma
+# Source directory /home1/tmp/x11r5
+#
+# $XConsortium: mmapSVR3.shar /main/4 1996/02/21 17:48:01 kaleb $
+#
+# existing files will NOT be overwritten unless -c is specified
+#
+# This shar contains:
+# length mode name
+# ------ ---------- ------------------------------------------
+# 1061 -rw-r--r-- mmap-2.2.3/CHANGELOG
+# 1633 -rw-r--r-- mmap-2.2.3/COPYRIGHT
+# 73 -rw-r--r-- mmap-2.2.3/DrivDesc
+# 7870 -rw-r--r-- mmap-2.2.3/Makefile
+# 28 -rw-r--r-- mmap-2.2.3/Master
+# 75 -rw-r--r-- mmap-2.2.3/Mtune
+# 25 -rw-r--r-- mmap-2.2.3/Name
+# 14 -rw-r--r-- mmap-2.2.3/Node
+# 3816 -rw-r--r-- mmap-2.2.3/README
+# 622 -rw-r--r-- mmap-2.2.3/Space.c
+# 23 -rw-r--r-- mmap-2.2.3/System
+# 65 -rw-r--r-- mmap-2.2.3/description
+# 12533 -rw-r--r-- mmap-2.2.3/mmap.7
+# 15554 -rw-r--r-- mmap-2.2.3/mmap.c
+# 1422 -rw-r--r-- mmap-2.2.3/mmap.h
+# 7901 -rw-r--r-- mmap-2.2.3/mmap.man
+# 1495 -rw-r--r-- mmap-2.2.3/mmaprm.1
+# 3346 -rw-r--r-- mmap-2.2.3/mmaprm.c
+# 843 -rw-r--r-- mmap-2.2.3/mmaprm.man
+# 1453 -rw-r--r-- mmap-2.2.3/mmapstat.1
+# 2531 -rw-r--r-- mmap-2.2.3/mmapstat.c
+# 808 -rw-r--r-- mmap-2.2.3/mmapstat.man
+# 2539 -rw-r--r-- mmap-2.2.3/tstmap.c
+#
+# ============= mmap-2.2.3/CHANGELOG ==============
+if test ! -d 'mmap-2.2.3'; then
+ echo 'x - creating directory mmap-2.2.3'
+ mkdir 'mmap-2.2.3'
+fi
+if test -f 'mmap-2.2.3/CHANGELOG' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/CHANGELOG (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/CHANGELOG (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/CHANGELOG' &&
+X
+MMAP 2.2.3 (22 November 1993)
+Workaround a problem when the page daemon (vhand) steals a mmap
+region which isn't used any longer by any processes the page tables
+(see mmap.c).
+X
+MMAP 2.2.2 (24 September 1993)
+UNMAP/UNMAPRM didn't decrement the number of attached shared
+memory regions after detaching. Thanks to Steve Forsythe,
+<forsse@meaddata.com> for pointing to it.
+X
+MMAP 2.2.1 (13 September 1993)
+Ioctl GETVERSION added.
+X
+MMAP 2.2 (12 September 1993)
+New ioctl UNMAPRM added. Allows removing of regions from the
+drivers list and the system. Also added a utility "mmaprm"
+which does it.
+X
+MMAP 2.1 (8 September 1993)
+Two ioctl's (GETNMMREG & GETMMREG) added to provide an interface
+to a utility "mmapstat", which prints some internal information from
+the MMAP driver. Some other cleanups.
+X
+MMAP 2.0 (7 September 1993)
+Completly rewritten. The need address space is allocated by the
+driver itself now.
+X
+MMAP 1.0 (4 August 1993)
+Used kernel function mappages(). Required previous malloc() in the
+calling process to allocate the needed virtuell address space.
+X
+SHAR_EOF
+chmod 0644 mmap-2.2.3/CHANGELOG ||
+echo 'restore of mmap-2.2.3/CHANGELOG failed'
+Wc_c="`wc -c < 'mmap-2.2.3/CHANGELOG'`"
+test 1061 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/CHANGELOG: original size 1061, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/COPYRIGHT ==============
+if test -f 'mmap-2.2.3/COPYRIGHT' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/COPYRIGHT (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/COPYRIGHT (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/COPYRIGHT' &&
+/*
+X * Copyright (c) 1993 by Thomas Wolfram, Berlin, Germany.
+X *
+X * Permission to use, copy, modify, distribute, and sell this software and its
+X * documentation for any purpose is hereby granted without fee, provided that
+X * the above copyright notice appear in all copies and that both that
+X * copyright notice and this permission notice appear in supporting
+X * documentation, and that the name of Thomas Wolfram be used in
+X * advertising or publicity pertaining to distribution of the software without
+X * specific, written prior permission. Thomas Wolfram makes no
+X * representations about the suitability of this software for any purpose.
+X * It is provided "as is" without express or implied warranty.
+X *
+X * THOMAS WOLFRAM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+X * EVENT SHALL THOMAS WOLFRAM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+X * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+X * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+X * PERFORMANCE OF THIS SOFTWARE.
+X *
+X * Author: Thomas Wolfram, thomas@aeon.in-berlin.de, wolf@prz.tu-berlin.de
+X *
+X * SCO changes made by
+X * S. Kent Hamilton <kenth@gwydion.hns.st-louis.mo.us>
+X * and
+X * David McCullough <davidm@stallion.oz.au>
+X */
+X
+/* The MMAP driver is not based on any AT&T source code. It is
+X * based on informations from various literature, drivers and articles
+X * posted to Usenet News and by far at most on own observations, approaches
+X * and a lot debugging.
+X */
+X
+X
+SHAR_EOF
+chmod 0644 mmap-2.2.3/COPYRIGHT ||
+echo 'restore of mmap-2.2.3/COPYRIGHT failed'
+Wc_c="`wc -c < 'mmap-2.2.3/COPYRIGHT'`"
+test 1633 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/COPYRIGHT: original size 1633, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/DrivDesc ==============
+if test -f 'mmap-2.2.3/DrivDesc' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/DrivDesc (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/DrivDesc (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/DrivDesc' &&
+DRIVER=mmap
+CLASS=io
+HARDWARE=FALSE
+DESCRIPTION=Memory Mapped I/O Driver
+SHAR_EOF
+chmod 0644 mmap-2.2.3/DrivDesc ||
+echo 'restore of mmap-2.2.3/DrivDesc failed'
+Wc_c="`wc -c < 'mmap-2.2.3/DrivDesc'`"
+test 73 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/DrivDesc: original size 73, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/Makefile ==============
+if test -f 'mmap-2.2.3/Makefile' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/Makefile (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/Makefile (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/Makefile' &&
+#/*
+# * Copyright (c) 1993 by Thomas Wolfram, Berlin, Germany.
+# *
+# * Permission to use, copy, modify, distribute, and sell this software and its
+# * documentation for any purpose is hereby granted without fee, provided that
+# * the above copyright notice appear in all copies and that both that
+# * copyright notice and this permission notice appear in supporting
+# * documentation, and that the name of Thomas Wolfram be used in
+# * advertising or publicity pertaining to distribution of the software without
+# * specific, written prior permission. Thomas Wolfram makes no
+# * representations about the suitability of this software for any purpose.
+# * It is provided "as is" without express or implied warranty.
+# *
+# * THOMAS WOLFRAM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+# * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+# * EVENT SHALL THOMAS WOLFRAM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+# * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+# * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+# * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# * PERFORMANCE OF THIS SOFTWARE.
+# *
+# * Author: Thomas Wolfram, thomas@aeon.in-berlin.de, wolf@prz.tu-berlin.de
+# */
+X
+X SHELL = /bin/sh
+X
+####################################################################
+# For ISC x.x.x uncomment the following
+X OSDEF = -DISC # Currently not used in the code
+#
+# ISC's install
+X INSTALL = /etc/install -i -n $(BINDIR) -u
+#
+####################################################################
+# For SCO Unix 3.2v2.x and 3.2v4.x uncomment the following
+# OSDEF = -DSCO
+#
+# If you have GNU fileutils use this one.
+# INSTALL = /usr/local/bin/install -o
+#
+# If not and you have X installed try this.
+# INSTALL = /usr/X386/bin/bsdinst -o
+# No to that one? <sigh> (Get GNU fileutils!) Install mmapstat
+# and mmaprm by hand... sorry.
+#
+####################################################################
+X
+# If you don't want the new tunable parameter 'NMMAPREG' be added to
+# /etc/conf/cf.d/mtune, comment this out.
+ADDTUNABLE = addtunable
+X
+# Directory where mmapstat and mmaprm will go
+X BINDIR = /usr/local/bin
+# and where you want the manual pages to go.
+X CATMANDIR = /usr/local/catman/p_man
+X
+# Do you want compressed manual pages? If not, uncomment 'true'.
+# COMPRESS = true
+# COMPRESS = compress
+# COMPRESS = pack
+X COMPRESS = gzip --suffix .z
+X
+# It's not tested with gcc, you should use the system's native C compiler.
+X CC = cc
+# Link utilities with shared C library.
+X LIBS = -lc_s
+X
+####################################################################
+# Normally you need not change anything below...
+X
+X DCFLAGS = -O -DINKERNEL $(LKDEFINES) $(OSDEF) #-DDEBUG
+X CFLAGS = -O $(OSDEF)
+X LKDEFINES = `test -r /etc/conf/cf.d/defines && cat /etc/conf/cf.d/defines; exit 0`
+X
+X CONFNAME = mmap
+X DRVRNAME = Driver.o
+MY1TUNABLE = NMMAPREG
+X
+X INCLSYS = /usr/include/sys
+X LKBINDIR = /etc/conf/bin
+X LKCFDIR = /etc/conf/cf.d
+LKSCONFDIR = /etc/conf/sdevice.d
+LKNCONFDIR = /etc/conf/node.d
+LKDRVRDIR = /etc/conf/pack.d/mmap
+X
+# ISC specific
+LKKCONFDIR = /etc/conf/kconfig.d
+X ISC30KC = /etc/KC
+X
+X
+all: Driver.o mmapstat mmaprm tstmap
+X
+$(INCLSYS)/mmap.h: mmap.h
+X cp mmap.h $(INCLSYS)/mmap.h
+X
+Driver.o: mmap.c $(INCLSYS)/mmap.h Makefile
+X $(CC) -c $(DCFLAGS) mmap.c
+X mv mmap.o Driver.o
+X
+mmapstat: mmapstat.c $(INCLSYS)/mmap.h Makefile
+X $(CC) $(CFLAGS) -o mmapstat mmapstat.c $(LIBS)
+X
+mmaprm: mmaprm.c $(INCLSYS)/mmap.h Makefile
+X $(CC) $(CFLAGS) -o mmaprm mmaprm.c $(LIBS)
+X
+tstmap: tstmap.c $(INCLSYS)/mmap.h Makefile
+X $(CC) $(CFLAGS) -o tstmap tstmap.c $(LIBS)
+X
+install:
+X @echo Type:
+X @echo " make install.isc2.0 For installing on ISC 2.0"
+X @echo " make install.isc2.2 For installing on ISC 2.2"
+X @echo " make install.isc3.0 For installing on ISC 3.0"
+X @echo " make install.isc4.0 For installing on ISC 4.0"
+X @echo " make install.sco322 For installing on SCO 3.2v2"
+X @echo " make install.sco324 For installing on SCO 3.2v4"
+X @echo ""
+X
+X
+install.isc2.0: Driver.o Space.c System Master Node Name # $(ADDTUNABLE) install.utils description
+X @echo Installing device driver files in /etc/conf...
+X @if [ ! -d $(LKDRVRDIR) ] ; then echo It\'s a new installation... ; \
+$(LKBINDIR)/idinstall -k -a $(CONFNAME) ; else \
+echo It\'s an update installation... ; $(LKBINDIR)/idinstall -k -u $(CONFNAME) \
+X ; fi
+X @echo Updating $(LKKCONFDIR)/description...
+X @grep $(CONFNAME) $(LKKCONFDIR)/description >/dev/null || cat description >> $(LKKCONFDIR)/description
+X @echo DONE.
+X
+install.isc2.2: install.isc2.0
+X
+install.isc3.0: Driver.o Space.c System Master Node DrivDesc $(ADDTUNABLE) install.utils
+X @echo Installing device driver files in /etc/conf...
+X @if [ ! -d $(LKDRVRDIR) ] ; then echo It\'s a new installation... ; \
+$(LKBINDIR)/idinstall -k -a $(CONFNAME) ; else \
+echo It\'s an update installation... ; $(LKBINDIR)/idinstall -k -u $(CONFNAME) \
+X ; fi
+X @cp DrivDesc $(LKDRVRDIR)/DrivDesc
+X @chmod 644 $(LKDRVRDIR)/DrivDesc
+X @echo DONE.
+X
+install.isc4.0: install.isc3.0
+X $(_NULL_)
+X
+install.sco324: Driver.o Space.c System Master Node Name $(ADDTUNABLE) install.utils
+X @echo Installing device driver files in /etc/conf...
+X @if [ ! -d $(LKDRVRDIR) ] ; then echo It\'s a new installation... ; \
+$(LKBINDIR)/idinstall -k -a $(CONFNAME) ; else \
+echo It\'s an update installation... ; $(LKBINDIR)/idinstall -k -u $(CONFNAME) \
+X ; fi
+X
+install.sco322: install.sco324
+X
+# add tunable NMMAPREG to mtune
+addtunable: Mtune
+X @echo Updating $(LKCFDIR)/mtune...
+X @grep $(MY1TUNABLE) $(LKCFDIR)/mtune >/dev/null || cat Mtune >> $(LKCFDIR)/mtune
+X @if [ -f $(ISC30KC)/DEVICE -a -f $(ISC30KC)/ALL ]; then \
+echo Updating $(ISC30KC)/DEVICE for kconfig...; \
+grep $(MY1TUNABLE) $(ISC30KC)/DEVICE >/dev/null || \
+(if [ -f $(ISC30KC)/DEVICE ] ; \
+X then mv $(ISC30KC)/DEVICE $(ISC30KC)/DEVICE.Orig; \
+X (sed -e '/^$$/d' $(ISC30KC)/DEVICE.Orig; echo $(MY1TUNABLE)) \
+X >$(ISC30KC)/DEVICE; \
+X fi) ; \
+echo Updating $(ISC30KC)/ALL for kconfig...; \
+grep $(MY1TUNABLE) $(ISC30KC)/ALL >/dev/null || \
+(if [ -f $(ISC30KC)/ALL ] ; then mv $(ISC30KC)/ALL $(ISC30KC)/ALL.Orig; \
+X (sed -e '/^$$/d' $(ISC30KC)/ALL.Orig; echo $(MY1TUNABLE)) >$(ISC30KC)/ALL; \
+fi) ; \
+X fi
+X
+X
+# mmapstat must be setuid root, mmaprm should only executable for superuser
+install.utils: mmapstat mmaprm
+X $(INSTALL) root -g bin -m 4755 mmapstat $(BINDIR)
+X strip $(BINDIR)/mmapstat
+X mcs -d $(BINDIR)/mmapstat
+X $(INSTALL) root -g sys -m 4750 mmaprm $(BINDIR)
+X strip $(BINDIR)/mmaprm
+X mcs -d $(BINDIR)/mmaprm
+X
+install.catman:
+X -mkdir $(CATMANDIR)/man7
+X -mkdir $(CATMANDIR)/man1
+X -rm $(CATMANDIR)/man7/$(CONFNAME).7*
+X nroff -man $(CONFNAME).man >$(CATMANDIR)/man7/$(CONFNAME).7
+X $(COMPRESS) $(CATMANDIR)/man7/$(CONFNAME).7
+X -rm $(CATMANDIR)/man1/mmapstat.1*
+X nroff -man mmapstat.man >$(CATMANDIR)/man1/mmapstat.1
+X $(COMPRESS) $(CATMANDIR)/man1/mmapstat.1
+X -rm $(CATMANDIR)/man1/mmaprm.1*
+X nroff -man mmaprm.man >$(CATMANDIR)/man1/mmaprm.1
+X $(COMPRESS) $(CATMANDIR)/man1/mmaprm.1
+X
+install.form-catman:
+X -mkdir $(CATMANDIR)/man7
+X -mkdir $(CATMANDIR)/man1
+X -rm $(CATMANDIR)/man7/$(CONFNAME).7*
+X cp $(CONFNAME).7 $(CATMANDIR)/man7/$(CONFNAME).7
+X chmod 644 $(CATMANDIR)/man7/$(CONFNAME).7
+X $(COMPRESS) $(CATMANDIR)/man7/$(CONFNAME).7
+X -rm $(CATMANDIR)/man1/mmapstat.1*
+X cp mmapstat.1 $(CATMANDIR)/man1/mmapstat.1
+X chmod 644 $(CATMANDIR)/man1/mmapstat.1
+X $(COMPRESS) $(CATMANDIR)/man1/mmapstat.1
+X -rm $(CATMANDIR)/man1/mmaprm.1*
+X cp mmaprm.1 $(CATMANDIR)/man1/mmaprm.1
+X chmod 644 $(CATMANDIR)/man1/mmaprm.1
+X $(COMPRESS) $(CATMANDIR)/man1/mmaprm.1
+X
+fman: mmap.man mmapstat.man mmaprm.man
+X nroff -man mmap.man >mmap.7
+X nroff -man mmapstat.man >mmapstat.1
+X nroff -man mmaprm.man >mmaprm.1
+X
+clean:
+X rm -f Driver.o mmapstat mmaprm tstmap core
+X
+clobber: clean
+X
+SHAR_EOF
+chmod 0644 mmap-2.2.3/Makefile ||
+echo 'restore of mmap-2.2.3/Makefile failed'
+Wc_c="`wc -c < 'mmap-2.2.3/Makefile'`"
+test 7870 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/Makefile: original size 7870, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/Master ==============
+if test -f 'mmap-2.2.3/Master' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/Master (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/Master (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/Master' &&
+mmap Ii ic mmap 0 0 1 1 -1
+SHAR_EOF
+chmod 0644 mmap-2.2.3/Master ||
+echo 'restore of mmap-2.2.3/Master failed'
+Wc_c="`wc -c < 'mmap-2.2.3/Master'`"
+test 28 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/Master: original size 28, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/Mtune ==============
+if test -f 'mmap-2.2.3/Mtune' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/Mtune (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/Mtune (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/Mtune' &&
+* Memory Mapped I/O Parameters ------
+NMMAPREG 64 8 1024
+SHAR_EOF
+chmod 0644 mmap-2.2.3/Mtune ||
+echo 'restore of mmap-2.2.3/Mtune failed'
+Wc_c="`wc -c < 'mmap-2.2.3/Mtune'`"
+test 75 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/Mtune: original size 75, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/Name ==============
+if test -f 'mmap-2.2.3/Name' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/Name (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/Name (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/Name' &&
+Memory Mapped I/O Driver
+SHAR_EOF
+chmod 0644 mmap-2.2.3/Name ||
+echo 'restore of mmap-2.2.3/Name failed'
+Wc_c="`wc -c < 'mmap-2.2.3/Name'`"
+test 25 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/Name: original size 25, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/Node ==============
+if test -f 'mmap-2.2.3/Node' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/Node (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/Node (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/Node' &&
+mmap mmap c 0
+SHAR_EOF
+chmod 0644 mmap-2.2.3/Node ||
+echo 'restore of mmap-2.2.3/Node failed'
+Wc_c="`wc -c < 'mmap-2.2.3/Node'`"
+test 14 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/Node: original size 14, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/README ==============
+if test -f 'mmap-2.2.3/README' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/README (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/README (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/README' &&
+X
+MMAP - Memory Mapped I/O Driver v2.2.3
+Installation
+------------------------------------------------------------------------
+MMAP is a pseudo device driver which provides memory mapped I/O for user
+processes, i.e. direct mapping of physical memory ranges into the user's
+virtual address space for fast access. It is especially useful for accessing
+the linear frame buffers of certain graphics hardware from the user level.
+X
+Note, the driver is currently tested only under ISC 2.0.2, ISC 2.2.1,
+ISC 3.0 and ISC 4.0 although it should work on any SVR3.2 based system.
+It should also work on SCO, but page locking is not tested yet with SCO
+and for this reason disabled for SCO. (look into mmap.c). But if mapping of
+ranges less or equal 4MB is enough for your needs it could be easier to use
+the "dmmap" driver by David McCullough <davidm@stallion.oz.au> which uses
+the vas*() functions already provided by the SCO kernel.
+A description of the driver itself and how to use it you'll find in the
+accompanied manual page.
+X
+0. Login as root.
+X
+1. Unpack the archive with:
+X
+X # gzcat mmap-2.2.3.t.z | tar xovf -
+X
+2. Edit the Makefile for your system. Change BINDIR, CATMANDIR, COMPRESS
+X if you like.
+X Comment out ADDTUNABLE if you don't want the new tunable system
+X parameter NMMAPREG be added to /etc/conf/cf.d/mtune.
+X
+3. Compile the driver, the mmapstat, mmaprm and tstmap utilities:
+X
+X # make
+X
+3. Install the driver, the mmapstat and mmaprm utilities:
+X
+X # make install.<system>
+X
+X Where <system> is currently only isc3.0, isc4.0, sco322 or sco324.
+X A list on which system the installation procedure is supported
+X you can get with:
+X
+X # make install
+X
+X The driver adds a new tunable system parameter "NMMAPREG" in
+X /etc/conf/cf.d/mtune (if you didn't disable it in the Makefile
+X before). For the ISC 3.0/4.0 systems also files in /etc/KC are
+X updated to provide access to NMMAPREG in the ISC 3.0/4.0 style
+X kconfig tool as well as a ISC 3.0/4.0 style "DrivDesc" file is
+X provided too.
+X
+4. If you are on ISC, run kconfig. Adjust the new system tunable
+X parameter NMMAPREG if you think it is needed. You can also adjust
+X SHMSEG if you like. See the new manual page mmap(7L) for their meaning.
+X
+X If you are on SCO or another SVR3.2, you can adjust NMMAPREG to
+X (e.g.) 128, with:
+X
+X # /etc/conf/bin/idtune NMMAPREG 128
+X
+X (BTW, this would also work for ISC.)
+X
+X If you didn't add the tunable parameter NMMAPREG to the system but
+X you want to change it, you must edit /etc/conf/pack.d/mmap/space.c
+X or /usr/include/sys/mmap.h.
+X
+5. Build a new kernel and install it.
+X
+5. Run the test program:
+X
+X # tstmap
+X
+X It maps the main bios in the process' address space. If you have
+X e.g. a AMI bios you will see a string like:
+X
+X 0123AAAAMMMMIIII05/05/91(C)1990 American Megatrends Inc., All Rights
+X Reserved
+X
+X After unmapping the program should dump core when it wants to access
+X the previous mapped range again.
+X
+X Under ISC you can check the output of the tstmap, e.g. with:
+X
+X # hd -s 0xF0000 /dev/mem | more
+X
+X Another option to do this is:
+X
+X # tail +983040c /dev/mem | more
+X
+X
+6. Run the mmapstat utility hereafter, which should give following output:
+X
+X # mmapstat
+X Currently memory mapped I/O regions as of Wed Sep 8 17:51:48 1993
+X # Physical Address Size Reference Count
+X 0 0x000F0000 64k 0
+X
+7. Installing the manual pages for mmap(7L), mmapstat(1L), mmaprm(1L) if you
+X like.
+X If you have nroff type (for getting SVR3 style "cat"man pages)
+X
+X # make install.catman
+X
+X If you don't have nroff, you can use the accompanied pre-formatted
+X man pages, type:
+X
+X # make install.form-catman
+X
+If you have any bug reports, questions or hints then you can send them to:
+X
+Thomas Wolfram
+wolf@prz.tu-berlin.de or thomas@aeon.in-berlin.de
+X
+SHAR_EOF
+chmod 0644 mmap-2.2.3/README ||
+echo 'restore of mmap-2.2.3/README failed'
+Wc_c="`wc -c < 'mmap-2.2.3/README'`"
+test 3816 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/README: original size 3816, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/Space.c ==============
+if test -f 'mmap-2.2.3/Space.c' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/Space.c (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/Space.c (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/Space.c' &&
+X
+/* Configuration file for the MMAP driver
+X *
+X * Copyright (c) 1993 by Thomas Wolfram, Berlin, Germany.
+X *
+X * Author: Thomas Wolfram, thomas@aeon.in-berlin.de, wolf@prz.tu-berlin.de
+X */
+X
+#if !defined (M_I286)
+#ident "@(#)space.c - MMAP v2.2.3, Copyright (c) Thomas Wolfram 1993"
+#endif
+X
+#include "sys/types.h"
+#include "sys/sysmacros.h"
+#include "sys/immu.h"
+#include "sys/region.h"
+X
+#include "sys/mmap.h"
+X
+#include "config.h" /* to get tunable parameter NMMAPREG */
+X
+X
+/* I/O regions memory mapped by the driver
+X */
+mmapreg_t mmapreg[NMMAPREG];
+X
+/* size of this array for use by the driver
+X */
+uint nmmapreg = NMMAPREG;
+SHAR_EOF
+chmod 0644 mmap-2.2.3/Space.c ||
+echo 'restore of mmap-2.2.3/Space.c failed'
+Wc_c="`wc -c < 'mmap-2.2.3/Space.c'`"
+test 622 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/Space.c: original size 622, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/System ==============
+if test -f 'mmap-2.2.3/System' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/System (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/System (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/System' &&
+mmap Y 1 0 0 0 0 0 0 0
+SHAR_EOF
+chmod 0644 mmap-2.2.3/System ||
+echo 'restore of mmap-2.2.3/System failed'
+Wc_c="`wc -c < 'mmap-2.2.3/System'`"
+test 23 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/System: original size 23, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/description ==============
+if test -f 'mmap-2.2.3/description' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/description (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/description (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/description' &&
+mmap - - io - Memory Mapped I/O Driver
+SHAR_EOF
+chmod 0644 mmap-2.2.3/description ||
+echo 'restore of mmap-2.2.3/description failed'
+Wc_c="`wc -c < 'mmap-2.2.3/description'`"
+test 65 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/description: original size 65, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/mmap.7 ==============
+if test -f 'mmap-2.2.3/mmap.7' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/mmap.7 (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/mmap.7 (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmap.7' &&
+X
+X
+X
+X mmap(7L) 386/ix mmap(7L)
+X
+X
+X
+X NAME
+X mmap - MMMMMMMMAAAAPPPP ioctl commands (memory mapped I/O support)
+X
+X SYNOPSIS
+X #include <sys/types.h>
+X #ifndef SCO
+X #include <sys/at_ansi.h>
+X #include <sys/kd.h>
+X #else
+X #include <sys/vtkd.h>
+X #endif
+X #include <sys/sysmacros.h>
+X #include <sys/immu.h>
+X #include <sys/region.h>
+X #include <sys/mmap.h>
+X
+X int ioctl(fildes, command, arg);
+X int fildes, command;
+X
+X DESCRIPTION
+X _M_M_A_P is a pseudo device driver which provides memory mapped
+X I/O for user processes, i.e. direct mapping of physical
+X memory ranges into the user's virtual address space for fast
+X access. It is especially useful for accessing the linear
+X frame buffers of certain graphic hardware from the user
+X level.
+X
+X To executing the _M_M_A_P _i_o_c_t_l commands _f_i_l_d_e_s must be an open
+X file descriptor [see _o_p_e_n(_2)] that refers to the special
+X character device /_d_e_v/_m_m_a_p. The effective user ID of the
+X calling process must be superuser.
+X The driver uses shared memory type regions for mapping. So
+X the maximum number of regions the driver can attach to a
+X process is limited by the maximum number of shared memory
+X regions which can be attached to the process [see _s_h_m_g_e_t(_2),
+X _s_h_m_o_p(_2), _s_h_m_c_t_l(_2)]. This number is a tunable system param-
+X eter (_S_H_M_S_E_G) [see _k_c_o_n_f_i_g(_1), _i_d_t_u_n_e(_1_M)].
+X The number of regions which the driver is able to map
+X system-wide (i.e. to all running processes) is limited too.
+X This number is also a tunable system parameter (_N_M_M_A_P_R_E_G).
+X
+X Note, the _M_M_A_P driver grows the virtual address space of the
+X calling process by itself. Allocating address space before
+X with _m_a_l_l_o_c(_3) isn't necessary and will not work.
+X The mapping regions allocated by the driver will always be
+X sharable, never private to a process. Regions can be of type
+X read/write or read/only. This depends from the _m_o_d_e
+X /_d_e_v/_m_m_a_p is opened [see _o_p_e_n(_2)]. Once a region is allo-
+X cated and mapped to a process it will normally remain in the
+X system (until reboot) even if the last process which pointed
+X at it detaches it from its address space. (This is not much
+X waste since the _M_M_A_P driver allocates no physical pages for
+X the mapping region.) But with the _U_N_M_A_P_R_M ioctl removing
+X
+X
+X Rev. 2.2.3, 22 November 1993 Page 1
+X
+X
+X
+X
+X
+X
+X mmap(7L) 386/ix mmap(7L)
+X
+X
+X
+X after unmapping can be requested [see below and _m_m_a_p_r_m(_1_L)].
+X If a process wants to map in the same memory range like
+X another one (e.g. if it's the same program which is running
+X again) it will be attached with the already existing region
+X by the driver. Same applies if the processes which requests
+X the same mapping are running simultaneously.
+X
+X Ioctl Calls
+X The following ioctl commands can be used:
+X
+X MMMMAAAAPPPP
+X This call maps physical memory into the virtual address
+X space of the user process. The following structure,
+X defined in <sys/kd.h> [see _d_i_s_p_l_a_y(_7)], is pointed to by
+X the argument _a_r_g to the ioctl:
+X
+X struct kd_memloc {
+X char *vaddr; /* virtual address to map to */
+X char *physaddr; /* physical address to map from */
+X long length; /* size in bytes to map */
+X long ioflg; /* not used by the _M_M_A_P driver */
+X };
+X
+X The _v_a_d_d_r argument is the linear address in the process
+X where the physical memory range will appear. This address
+X must be on a boundary specified by the machine dependant
+X constant _M_M_A_P_L_B_A, defined in <sys/mmap.h>. If _v_a_d_d_r is
+X equal to zero the address is selected by the driver
+X itself.
+X The _p_h_y_s_a_d_d_r argument is the physical address of the
+X memory range that will be mapped in. It must be on a page
+X boundary.
+X The _l_e_n_g_t_h argument is the size of the memory range that
+X will be mapped in. It will be rounded up to a multiple of
+X the size of a page by the driver.
+X On success the ioctl will return the virtual address where
+X the memory is mapped in. It will fail if one or more of
+X the following is true:
+X
+X [EPERM] The effective user ID of the calling pro-
+X cess is not superuser.
+X
+X [EFAULT] The user address pointed to by _a_r_g is
+X illegal.
+X
+X [EINVAL] The _v_a_d_d_r argument is not equal to zero,
+X and the value is an illegal address (not
+X on a MMAPLBA boundary, already used in
+X the process or not below _M_A_X_U_V_A_D_R, as
+X defined in <sys/immu.h>).
+X
+X [EINVAL] The _p_h_y_s_a_d_d_r argument is not on a page
+X boundary.
+X
+X
+X Rev. 2.2.3, 22 November 1993 Page 2
+X
+X
+X
+X
+X
+X
+X mmap(7L) 386/ix mmap(7L)
+X
+X
+X
+X [ENOMEM] The _v_a_d_d_r argument is equal to zero and
+X the driver is not able to find a proper
+X region in the user's address space where
+X the memory range would fit in.
+X
+X [ENOMEM] The size of the user's virtual address
+X space would exceed the system-imposed
+X limit.
+X
+X [ENOMEM] Not enough system internal space avail-
+X able to grow the user's virtual address
+X space.
+X
+X [EMFILE] The number of shared memory segments
+X attached to the calling process would
+X exceed the system-imposed limit.
+X
+X [EMFILE] The number of all memory mapped regions
+X in the system would exceed the driver-
+X imposed limit.
+X
+X UUUUNNNNMMMMAAAAPPPP
+X This call unmaps previously mapped physical memory from
+X the calling process. The argument _a_r_g to the ioctl must
+X be the virtual address as returned by the previous _M_A_P
+X ioctl.
+X It will fail if one or more of the following is true:
+X
+X [EPERM] The effective user ID of the calling pro-
+X cess is not superuser.
+X
+X [EINVAL] If _a_r_g is not the start address of a
+X region mapped by the driver to the cal-
+X ling process.
+X
+X UUUUNNNNMMMMAAAAPPPPRRRRMMMM
+X Same like _U_N_M_A_P but removes the concerning region from the
+X systems internal list, if no other process is still using
+X it [see _m_m_a_p_r_m(_1_L)].
+X
+X GGGGEEEETTTTNNNNMMMMMMMMRRRREEEEGGGG
+X This call returns the number of the memory mapped I/O
+X regions which exists currently in the system [_s_e_e
+X _m_m_a_p_s_t_a_t(_1_L)]. It requires no argument. It will fail if
+X one or more of the following is true:
+X
+X [EPERM] The effective user ID of the calling pro-
+X cess is not superuser.
+X
+X GGGGEEEETTTTMMMMMMMMRRRREEEEGGGG
+X This call returns the current status of the _M_M_A_P driver.
+X The argument _a_r_g must be a pointer to an array of elements
+X of the following type (defined in <sys/mmap.h>):
+X
+X
+X Rev. 2.2.3, 22 November 1993 Page 3
+X
+X
+X
+X
+X
+X
+X mmap(7L) 386/ix mmap(7L)
+X
+X
+X
+X typedef struct mmapinfo {
+X paddr_t physaddr; /* physical address */
+X long length; /* size in bytes */
+X short refcnt; /* number of users */
+X /* pointing currently at this region */
+X } mmapinfo_t;
+X
+X which is filled by the driver for every region currently
+X exists. The array must have as much elements as the
+X number returned by the _G_E_T_N_M_M_R_E_G ioctl states [see
+X _m_m_a_p_s_t_a_t(_1_L)]. The command will fail if one or more of
+X the following is true:
+X
+X [EPERM] The effective user ID of the calling pro-
+X cess is not superuser.
+X
+X [EFAULT] The user address pointed to by _a_r_g is
+X illegal.
+X
+X
+X
+X GGGGEEEETTTTVVVVEEEERRRRSSSSIIIIOOOONNNN
+X Returns version number of driver, e.g. version 2.2.1 would
+X be returned as 0x0221.
+X
+X FILES
+X /_d_e_v/_m_m_a_p
+X Character device interface to the driver.
+X
+X SEE ALSO
+X open(2), ioctl(2), display(7), shmget(2), shmop(2),
+X shmctl(2), kconfig(1), idtune(1M), intro(2), mmapstat(1L),
+X mmaprm(1L).
+X
+X DIAGNOSTICS
+X Upon sucessful completion, the return value is as follows:
+X
+X The _M_A_P ioctl returns the user's address where the phy-
+X sical memory is mapped in.
+X
+X The _U_N_M_A_P and _U_N_M_A_P_R_M ioctl's return a value of 0.
+X
+X The _G_E_T_N_M_M_R_E_G ioctl returns the number of memory mapped
+X I/O regions which exists currently in the system.
+X
+X The _G_E_T_M_M_R_E_G ioctl returns a value of 0.
+X
+X The _G_E_T_V_E_R_S_I_O_N ioctl returns the version number.
+X
+X Otherwise, a value of -1 is returned, and _e_r_r_n_o [see
+X _i_n_t_r_o(_2)] is set to indicate the error.
+X
+X BUGS
+X
+X
+X Rev. 2.2.3, 22 November 1993 Page 4
+X
+X
+X
+X
+X
+X
+X mmap(7L) 386/ix mmap(7L)
+X
+X
+X
+X Please report bugs to: wwwwoooollllffff@@@@pppprrrrzzzz....ttttuuuu----bbbbeeeerrrrlllliiiinnnn....ddddeeee or
+X tttthhhhoooommmmaaaassss@@@@aaaaeeeeoooonnnn....iiiinnnn----bbbbeeeerrrrlllliiiinnnn....ddddeeee.
+X
+X COPYING
+X Copyright (c) 1993 Thomas Wolfram
+X
+X AUTHOR
+X Thomas Wolfram
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X Rev. 2.2.3, 22 November 1993 Page 5
+X
+X
+X
+SHAR_EOF
+chmod 0644 mmap-2.2.3/mmap.7 ||
+echo 'restore of mmap-2.2.3/mmap.7 failed'
+Wc_c="`wc -c < 'mmap-2.2.3/mmap.7'`"
+test 12533 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/mmap.7: original size 12533, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/mmap.c ==============
+if test -f 'mmap-2.2.3/mmap.c' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/mmap.c (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/mmap.c (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmap.c' &&
+/*
+X * Copyright (c) 1993 by Thomas Wolfram, Berlin, Germany.
+X *
+X * Permission to use, copy, modify, distribute, and sell this software and its
+X * documentation for any purpose is hereby granted without fee, provided that
+X * the above copyright notice appear in all copies and that both that
+X * copyright notice and this permission notice appear in supporting
+X * documentation, and that the name of Thomas Wolfram be used in
+X * advertising or publicity pertaining to distribution of the software without
+X * specific, written prior permission. Thomas Wolfram makes no
+X * representations about the suitability of this software for any purpose.
+X * It is provided "as is" without express or implied warranty.
+X *
+X * THOMAS WOLFRAM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+X * EVENT SHALL THOMAS WOLFRAM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+X * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+X * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+X * PERFORMANCE OF THIS SOFTWARE.
+X *
+X * Author: Thomas Wolfram, thomas@aeon.in-berlin.de, wolf@prz.tu-berlin.de
+X */
+X
+#if !defined (M_I286)
+#ident "@(#)mmap.c - MMAP v2.2.3, Copyright (c) Thomas Wolfram 1993"
+#endif
+X
+#define MMAP_MAJ 2
+#define MMAP_MIN 2
+#define MMAP_PL 3
+#define MMAPVERSION MMAP_MAJ*256 + MMAP_MIN*16 + MMAP_PL
+X
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/signal.h>
+#include <sys/user.h>
+X
+#include <sys/errno.h>
+X
+#ifndef SCO
+#include <sys/at_ansi.h> /* get typedef needed in kd.h */
+#include <sys/kd.h> /* get struct kd_memloc */
+#else
+#include <sys/vtkd.h>
+#endif
+X
+#include <sys/sysmacros.h>
+#include <sys/immu.h>
+#include <sys/region.h>
+#include <sys/proc.h>
+X
+#include <sys/ipc.h> /* get typedef needed in shm.h */
+#include <sys/shm.h> /* get shminfo */
+X
+#include <sys/mmap.h>
+X
+/* For SCO, page locking is done not per-page table entry, but
+X * per-pfdat.
+X */
+#ifndef PG_LOCK
+#define PG_LOCK 0
+#endif
+X
+#define False 0
+#define True 1
+X
+/* Move address x to previous and next low boundary address.
+X */
+#define prev_ba(x) (caddr_t)((uint)x & ~(MMAPLBA-1))
+#define next_ba(x) (caddr_t)(((uint)x + MMAPLBA) & ~(MMAPLBA-1))
+X
+/* Nowhere else declared. */
+extern dbd_t *finddbd();
+X
+/* System's shared memory info structure.
+X */
+extern struct shminfo shminfo;
+X
+/* Physical addresses of I/O regions memory mapped by the driver.
+X * Defined in space.c.
+X */
+extern mmapreg_t mmapreg[];
+X
+/* Size of this array for use by the driver. Defined in space.c.
+X */
+extern uint nmmapreg;
+X
+int mmapinit();
+int mmapioctl();
+X
+static caddr_t FindVirtAddr();
+X
+X
+/* Number of I/O regions memory mapped currently by the driver. */
+static map_cnt = 0;
+X
+static struct kd_memloc memDesc;
+static mmapinfo_t ibuf;
+X
+X
+int mmapinit()
+{
+X printf("Memory Mapped I/O Driver v%d.%d.%d installed.\n",
+X MMAP_MAJ, MMAP_MIN, MMAP_PL);
+X printf("Copyright (c) 1993 Thomas Wolfram\n\n");
+X
+}
+X
+int mmapioctl(dev, cmd, arg, mode)
+X int dev;
+X int cmd;
+X int arg;
+X int mode;
+{
+X /* Don't put this much variables at the kernel stack. Although it
+X * wouldn't matter, probably...
+X */
+X static reg_t *Reg_p;
+X static preg_t *PReg_p;
+X static pde_t *pte; /* page table entry */
+X static dbd_t *dbdte; /* disk block descriptor entry */
+X static unsigned char accmode;
+X static int FreeReg;
+X register uint i, off;
+X register paddr_t pmem;
+X
+X
+X /* Only superuser is allowed to do that. U.u_error is set to
+X * EPERM if not superuser.
+X */
+X if(!suser())
+X return;
+X
+X /* Default for unmapping is don't freeing the region */
+X FreeReg = False;
+X
+X switch(cmd) {
+X
+X /* Map physical memory into process address space.
+X */
+X case MAP:
+X
+X /* Get the memory description block from user space.
+X */
+X if(copyin((caddr_t)arg, &memDesc, sizeof(memDesc)) == -1) {
+X u.u_error = EFAULT;
+X break;
+X }
+X
+X /* Physical address must be page aligned.
+X */
+X if(poff(memDesc.physaddr) != 0) {
+X u.u_error = EINVAL;
+X break;
+X }
+X
+X /* Check whether we already reached the limit of
+X * attachable shared memory regions of this process.
+X */
+X if(!(u.u_nshmseg < shminfo.shmseg)) {
+X u.u_error = EMFILE;
+X break;
+X }
+X
+X /* If no mapping address given by the user try to find one.
+X */
+X if(memDesc.vaddr == (caddr_t)0) {
+X if((memDesc.vaddr = FindVirtAddr(memDesc.length)) == NULL) {
+X u.u_error = ENOMEM;
+X break;
+X }
+X }
+X
+X /* Check whether this physical range is already mapped to
+X * a region. If so use it and don't allocate a new region.
+X */
+X Reg_p = NULL;
+X for(i = 0; i < map_cnt; i++) {
+X if((paddr_t)memDesc.physaddr == mmapreg[i].physaddr &&
+X btoc(memDesc.length) == mmapreg[i].Reg_p->r_pgsz) {
+X Reg_p = mmapreg[i].Reg_p;
+X break;
+X }
+X }
+X
+X
+X if(Reg_p != NULL) {
+X
+X /* If we have still such a region lock it.
+X */
+X reglock(Reg_p);
+X
+X /* XXXX This is a ugly hack.
+X * If our region isn't any longer referenced by a process
+X * it's possible that vhand steals the page tables of our
+X * region. Attaching such a region with swapped-out page
+X * tables doesn't work, because the page directory entries
+X * of the process get a present-bit set to 1 and valid re-
+X * ferences to page tables but which contain entries of in-
+X * valid non-present pages. And the related dbd tables still
+X * contain the type DBD_IOMAP.
+X * I.e. the effect is there won't occur a page fault to
+X * read the swapped-out page tables in, as I expected. The
+X * page fault will instead occur in the second level (i.e. in
+X * the page tables) when attempting to read the non-present
+X * pages from disk or elsewhere. The kernel will look in the
+X * dbd table and find the type DBD_IOMAP, but which is invalid
+X * for a non-present page. Hence it would panic then with:
+X * "vfault - bad dbd_type".
+X *
+X * Also I have no idea how I could the swapped-out page tables
+X * read in "by hand". The "pseudo page directory" of the re-
+X * gion (addressed by Reg_p->r_list) contains obviously only
+X * the base addresses and not the page state flags. Also
+X * I don't know how to find the dbd's of the page table's
+X * pages.
+X *
+X * Probably I did something wrong here. If you've an idea
+X * please let me know. Thanks.
+X *
+X * Anyway, until then I simply throw away the region if
+X * the page tables of it are swapped out and then I reallocate
+X * the same region.
+X */
+X if(Reg_p->r_flags & RG_SWAP) {
+X
+X /* Freereg takes only effect if no users pointing
+X * at it.
+X */
+X if(Reg_p->r_refcnt == 0) {
+X Reg_p->r_flags &= ~RG_NOFREE;
+X freereg(Reg_p);
+X
+X /* Free the old slot and force allocating a
+X * new region.
+X */
+X for(i = i; i < map_cnt; i++)
+X mmapreg[i] = mmapreg[i+1];
+X map_cnt--;
+X
+X Reg_p = NULL;
+X
+#ifdef DEBUG
+X printf("MMAP: Info - reallocate region [a=0x%x, l=%dk]\n", memDesc.physaddr, memDesc.length/1024);
+#endif
+X }
+X else {
+X /* I hope this point here will never be reached!
+X * Or - better - page tables are read in correctly
+X * by the system. So we don't panic in the hope
+X * it works.
+X */
+X printf("MMAP: Warning - region [a=%x, l=%dk] still used but page tables are swapped out!\n", memDesc.physaddr, memDesc.length/1024);
+X printf("MMAP: Cannot reallocate this region!\n");
+X printf("MMAP: Please email Thomas Wolfram <thomas@aeon.in-berlin.de> or\n <wolf@prz.tu-berlin.de>. Thanks.\n");
+X
+X /* panic("MMAP: PANIC\n");
+X */
+X }
+X }
+X }
+X
+X
+X /* If necessary allocate a new region, type is shared memory.
+X */
+X if(Reg_p == NULL) {
+X
+X /* Check whether we are at the limit of regions we can map.
+X */
+X if(map_cnt > nmmapreg) {
+X u.u_error = EMFILE;
+X break;
+X }
+X
+X /* Allocate new region which will be locked.
+X */
+X if((Reg_p = allocreg(NULL, RT_SHMEM, 0)) == NULL)
+X break;
+X }
+X
+X
+X /* If the region is already initialized, check whether it is
+X * allowed to grow the virtuell address space of the process by
+X * btoc(memDesc.length) pages, before attaching it.
+X */
+X
+X if(Reg_p->r_pgsz > 0) {
+X
+X if(chkpgrowth(btoc(memDesc.length)) < 0) {
+X regrele(Reg_p);
+X u.u_error = ENOMEM;
+X break;
+X }
+X }
+X
+X /* Attach region to process, R/O or R/W. Will fail if vaddr is
+X * not a multiple of SHMLBA (= MMAPLBA, 4MB on a i386).
+X */
+X if(mode & FWRITE)
+X accmode = SEG_RW;
+X else
+X accmode = SEG_RO;
+X
+X if((PReg_p = attachreg(Reg_p, &u, memDesc.vaddr, PT_SHMEM, accmode))
+X == NULL) {
+X
+X /* If attaching failed and region is already initialized,
+X * release it. Otherwise free it again.
+X */
+X if(Reg_p->r_pgsz > 0)
+X regrele(Reg_p);
+X else
+X freereg(Reg_p);
+X break;
+X }
+X
+X
+X /* If region is new allocated, grow region without allocating
+X * swapable memory (DBD_NONE prevents decrementing of availsmem
+X * and availrmem), i.e. allocate only page tables and dbd tables.
+X * Then map the physical memory into it.
+X * But check whether it is allowed to grow the virtuell address
+X * space of the process by btoc(memDesc.length) pages before.
+X */
+X if(Reg_p->r_pgsz == 0) {
+X
+X if(chkpgrowth(btoc(memDesc.length)) < 0) {
+X detachreg(PReg_p, &u);
+X u.u_error = ENOMEM;
+X break;
+X }
+X
+X if(growreg(PReg_p, btoc(memDesc.length), DBD_NONE) < 0) {
+X detachreg(PReg_p, &u);
+X u.u_error = ENOMEM;
+X break;
+X }
+X
+X
+X /* Map physical memory into virtuell address space of process,
+X * i.e. modify page tables and dbd tables.
+X * I could also use mappages() here, but so I don't have the
+X * overhead of it and know what I do.
+X *
+X * Linear address:
+X * +----------+----------+------------+
+X * | ptnum | pnum | byte off. |
+X * +----------+----------+------------+
+X * 10 10 12
+X */
+X pmem = (paddr_t)memDesc.physaddr;
+X
+X for(off = 0; off < memDesc.length; off += NBPP) {
+X
+X pte = (pde_t *)((uint)Reg_p->r_list[ptnum(off)] & PG_ADDR)
+X + pnum(off);
+X pte->pgi.pg_pde = (pmem & PG_ADDR) |
+X PG_LOCK | PTE_RW | PG_P;
+X /*
+X * SCO does page locking per-pfdat, not per-page table entry
+X * according to SCO's <sys/immu.h>. Also pg_setlock(),
+X * pg_clrlock(), and pg_islocked() are not macros, but
+X * functions on SCO now. Assumed they changed not the
+X * parameter of the original macro (I don't believe it,
+X * would had a lot more changes in the kernel required...),
+X * following would lock the page in core:
+#ifdef SCO
+X pg_setlock(pte);
+#endif
+X * It's uncommented because it's not tested yet.
+X */
+X
+X dbdte = finddbd(Reg_p, pte);
+X dbdte->dbd_type = DBD_IOMAP;
+X
+X /* Move to next physical page. */
+X pmem += NBPP;
+X }
+X
+X /* Region is initialized. Don't free region on last detach.
+X */
+X Reg_p->r_flags |= RG_DONE | RG_NOFREE;
+X Reg_p->r_dbdnone = 0;
+X
+X mmapreg[map_cnt].physaddr = (paddr_t)memDesc.physaddr;
+X mmapreg[map_cnt++].Reg_p = Reg_p;
+X
+X } /* Region size still zero */
+X
+X /* Increase number of attached shared memory regions.
+X */
+X u.u_nshmseg++;
+X
+X /* Only count up this to prevent swapping. Maybe it's not
+X * necessary.
+X */
+X Reg_p->r_noswapcnt++;
+X
+X /* Release region and return.
+X */
+X regrele(Reg_p);
+X u.u_rval1 = (int)memDesc.vaddr;
+X break;
+X
+X
+X /* Unmap region from physical address space and try to free
+X * it.
+X */
+X case UNMAPRM:
+X FreeReg = True;
+X
+X /* Unmap region from physical address space.
+X */
+X case UNMAP:
+X
+X /* Check whether the given vaddr is a valid virtuell address
+X * of a shared memory region of this process, i.e. look for it
+X * in the process table of pregions.
+X */
+X PReg_p = u.u_procp->p_region;
+X
+X while(PReg_p->p_reg != NULL) {
+X
+X if(PReg_p->p_type == PT_SHMEM &&
+X PReg_p->p_regva == (caddr_t)arg)
+X break;
+X PReg_p++;
+X }
+X
+X if(PReg_p->p_reg == NULL) {
+X u.u_error = EINVAL;
+X break;
+X }
+X
+X /* Check whether the this is really one of our I/O regions,
+X * i.e. region must be known to us.
+X */
+X
+X for(i = 0; i < map_cnt; i++) {
+X if(PReg_p->p_reg == mmapreg[i].Reg_p)
+X break;
+X }
+X if(i == map_cnt) {
+X u.u_error = EINVAL;
+X break;
+X }
+X
+X Reg_p = PReg_p->p_reg;
+X reglock(Reg_p);
+X detachreg(PReg_p, &u);
+X u.u_nshmseg--;
+X
+X /* If FREEREG is requested and no other user is pointing
+X * at the region free it and remove it from the internal
+X * list.
+X */
+X if(FreeReg && (Reg_p->r_refcnt == 0)) {
+X reglock(Reg_p);
+X Reg_p->r_flags &= ~RG_NOFREE;
+X freereg(Reg_p);
+X for(i = i; i < map_cnt; i++)
+X mmapreg[i] = mmapreg[i+1];
+X map_cnt--;
+X }
+X break;
+X
+X
+X /* Return number of currently memory mapped I/O regions.
+X */
+X case GETNMMREG:
+X u.u_rval1 = map_cnt;
+X break;
+X
+X /* Return information block about currently memory mapped I/O
+X * regions.
+X */
+X case GETMMREG:
+X
+X for(i = 0; i < map_cnt; i++) {
+X ibuf.physaddr = mmapreg[i].physaddr;
+X ibuf.length = ctob(mmapreg[i].Reg_p->r_pgsz);
+X ibuf.refcnt = mmapreg[i].Reg_p->r_refcnt;
+X if(copyout(&ibuf, arg, sizeof(ibuf)) == -1) {
+X u.u_error = EFAULT;
+X return;
+X }
+X arg += sizeof(ibuf);
+X }
+X break;
+X
+X
+X /* Return version number
+X */
+X case GETVERSION:
+X u.u_rval1 = MMAPVERSION;
+X break;
+X
+X
+X default:
+X u.u_error = EINVAL;
+X break;
+X
+X }
+}
+X
+X
+/* Find a virtual mapping address.
+X */
+static caddr_t FindVirtAddr(size)
+X uint size;
+{
+X register caddr_t vregaddr;
+X register caddr_t vmapaddr = (caddr_t)UVMMAP;
+X register preg_t *preg_p = u.u_procp->p_region;
+X
+X /* Go through the process regions table...
+X */
+X while(preg_p->p_reg != NULL) {
+X
+#ifdef DEBUG
+X printf("MMAP: Try vmapaddr %x\n", vmapaddr);
+#endif
+X /* If region grows down, use previous MMAPLBA boundary address as
+X * starting address. Round up the 0x????3fffc aligned (ending) address
+X * before.
+X */
+X if((preg_p->p_reg)->r_flags & RG_DOWN)
+X vregaddr = prev_ba(next_ba(preg_p->p_regva) -
+X ctob((preg_p->p_reg)->r_pgsz));
+X else
+X vregaddr = preg_p->p_regva;
+#ifdef DEBUG
+X printf("MMAP: vregaddr = %x\n", vregaddr);
+#endif
+X
+X /* Search for process region with address above the desired
+X * mapping address.
+X */
+X if(vmapaddr > vregaddr) {
+X preg_p++;
+X continue;
+X }
+X
+X /* If address is already in use try next address at MMAPLBA boundary
+X * after end of this region.
+X */
+X if(vmapaddr == vregaddr) {
+X vmapaddr = next_ba(vregaddr + ctob((preg_p->p_reg)->r_pgsz));
+X preg_p++;
+X continue;
+X }
+X
+X /* If desired start and end addresses are below this region
+X * use this address for mapping, otherwise try next address at
+X * MMAPLBA boundary after end of this region.
+X */
+X if((vmapaddr + size - 1) < vregaddr) {
+#ifdef DEBUG
+X printf("MMAP: Take %x\n", vmapaddr);
+#endif
+X return vmapaddr;
+X }
+X vmapaddr = next_ba(vregaddr + ctob((preg_p->p_reg)->r_pgsz));
+X preg_p++;
+X }
+X
+X /* If no hole between process regions found, but current vmapaddr
+X * (end address) is still below the maximal possible user virtual
+X * address, then use it.
+X */
+X if((vmapaddr + size - 1) < (caddr_t)MAXUVADR)
+X return vmapaddr;
+X
+X /* Found no hole... */
+X return NULL;
+}
+X
+SHAR_EOF
+chmod 0644 mmap-2.2.3/mmap.c ||
+echo 'restore of mmap-2.2.3/mmap.c failed'
+Wc_c="`wc -c < 'mmap-2.2.3/mmap.c'`"
+test 15554 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/mmap.c: original size 15554, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/mmap.h ==============
+if test -f 'mmap-2.2.3/mmap.h' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/mmap.h (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/mmap.h (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmap.h' &&
+X
+/* This file contains various defines for the MMAP driver.
+X *
+X * Copyright (c) 1993 by Thomas Wolfram, Berlin, Germany.
+X *
+X * Author: Thomas Wolfram, thomas@aeon.in-berlin.de, wolf@prz.tu-berlin.de
+X */
+X
+#if !defined (M_I286)
+#ident "@(#)mmap.h - MMAP v2.2.3, Copyright (c) Thomas Wolfram 1993"
+#endif
+X
+#define MMAPLBA ctob(stoc(1)) /* segment low boundary address multiple */
+X /* (MMAPLBA must be a power of 2) */
+X /* MMAPLBA = 4MB on a i386 */
+X
+/* base of memory mapped I/O regions, this is 256MB beyond UVSHM */
+#define UVMMAP ((unsigned)0x90000000L)
+X
+/* Maximal number of memory mapped I/O regions. Can be overwritten
+X * by /etc/conf/cf.d/stune.
+X */
+#ifndef NMMAPREG
+#define NMMAPREG 64
+#endif
+X
+/* Ioctl's
+X */
+#define MMAP_IOCTL ('M'<<8)
+#define MAP (MMAP_IOCTL|0)
+#define UNMAP (MMAP_IOCTL|1)
+#define GETNMMREG (MMAP_IOCTL|2)
+#define GETMMREG (MMAP_IOCTL|3)
+#define UNMAPRM (MMAP_IOCTL|4)
+#define GETVERSION (MMAP_IOCTL|5)
+X
+/* Memory mapped I/O region description.
+X */
+typedef struct {
+X paddr_t physaddr; /* physical address of region */
+X reg_t *Reg_p; /* pointer to region structure */
+} mmapreg_t;
+X
+/* Memory mapped I/O region description for GETMMREG ioctl.
+X */
+typedef struct mmapinfo {
+X paddr_t physaddr; /* physical address of region */
+X long length; /* size of region in bytes */
+X short refcnt; /* number of users pointing at region */
+} mmapinfo_t;
+X
+SHAR_EOF
+chmod 0644 mmap-2.2.3/mmap.h ||
+echo 'restore of mmap-2.2.3/mmap.h failed'
+Wc_c="`wc -c < 'mmap-2.2.3/mmap.h'`"
+test 1422 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/mmap.h: original size 1422, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/mmap.man ==============
+if test -f 'mmap-2.2.3/mmap.man' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/mmap.man (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/mmap.man (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmap.man' &&
+.\" Copyright (c) 1993 by Thomas Wolfram
+.TH mmap 7L "2.2.3, 22 November 1993" "Version 2.2.3"
+.de BP
+.sp
+.ti -.2i
+\(**
+..
+.SH NAME
+mmap \- \fBMMAP\fP ioctl commands (memory mapped I/O support)
+.SH SYNOPSIS
+.br
+#include <sys/types.h>
+.br
+#ifndef SCO
+.br
+#include <sys/at_ansi.h>
+.br
+#include <sys/kd.h>
+.br
+#else
+.br
+#include <sys/vtkd.h>
+.br
+#endif
+.br
+#include <sys/sysmacros.h>
+.br
+#include <sys/immu.h>
+.br
+#include <sys/region.h>
+.br
+#include <sys/mmap.h>
+.P
+int ioctl(fildes, command, arg);
+.br
+int fildes, command;
+.SH DESCRIPTION
+.I MMAP
+is a pseudo device driver which provides memory mapped I/O for user processes,
+i.e. direct mapping of physical memory ranges into the user's virtual address
+space for fast access. It is especially useful for accessing the linear frame
+buffers of certain graphic hardware from the user level.
+.P
+To execute the \fIMMAP ioctl\fR commands \fIfildes\fR must be an open file
+descriptor [see \fIopen(2)\fR] that refers to the special character device
+\fI/dev/mmap\fR. The effective user ID of the calling process must be
+superuser.
+.br
+The driver uses shared memory type regions for mapping. So the maximum
+number of regions the driver can attach to a process is limited by
+the maximum number of shared memory regions which can be attached to
+the process [see \fIshmget(2), shmop(2), shmctl(2)\fR]. This number
+is a tunable system parameter (\fISHMSEG\fR) [see \fIkconfig(1),
+idtune(1M)\fR].
+.br
+The number of regions which the driver is able to map system-wide (i.e. to
+all running processes) is limited too. This number is also a tunable
+system parameter (\fINMMAPREG\fR).
+.P
+Note, the \fIMMAP\fR driver grows the virtual address space of the calling
+process by itself. Allocating address space before with \fImalloc(3)\fR
+isn't necessary and will not work.
+.br
+The mapping regions allocated by the driver will always be sharable, never
+private to a process. Regions can be of type read/write or read/only.
+This depends from the \fImode\fR \fI/dev/mmap\fR is opened [see \fIopen(2)\fR].
+Once a region is allocated and mapped to a process it will normally remain
+in the system (until reboot) even if the last process which pointed at it
+detaches it from its address space. (This is not much waste since
+the \fIMMAP\fR driver allocates no physical pages for the mapping region.)
+But with the \fIUNMAPRM\fR ioctl removing after unmapping can be
+requested [see below and \fImmaprm(1L)\fR].
+If a process wants to map in the same memory range like another one (e.g. if
+it's the same program which is running again) it will be attached with the
+already existing region by the driver. Same applies if the processes which
+requests the same mapping are running simultaneously.
+.SS Ioctl Calls
+The following ioctl commands can be used:
+.IP \fBMAP\fP 2
+This call maps physical memory into the virtual address space of the
+user process. The following structure, defined in <sys/kd.h> [see
+\fIdisplay(7)\fR], is pointed to by the argument \fIarg\fR to the ioctl:
+.IP
+struct kd_memloc {
+.br
+X char *vaddr; /* virtual address to map to */
+.br
+X char *physaddr; /* physical address to map from */
+.br
+X long length; /* size in bytes to map */
+.br
+X long ioflg; /* not used by the \fIMMAP\fR driver */
+.br
+};
+.IP "" 2
+The \fIvaddr\fR argument is the linear address in the process where the
+physical memory range will appear. This address must be on a boundary
+specified by the machine dependant constant \fIMMAPLBA\fR, defined in
+<sys/mmap.h>. If \fIvaddr\fR is equal to zero the address is selected by
+the driver itself.
+.br
+The \fIphysaddr\fR argument is the physical address of the memory range
+that will be mapped in. It must be on a page boundary.
+.br
+The \fIlength\fR argument is the size of the memory range that will be
+mapped in. It will be rounded up to a multiple of the size of a page
+by the driver.
+.br
+On success the ioctl will return the virtual address where the memory
+is mapped in. It will fail if one or more of the following is true:
+.RS 4
+.IP [EPERM] 15
+The effective user ID of the calling process is not superuser.
+.IP [EFAULT] 15
+The user address pointed to by \fIarg\fR is illegal.
+.IP [EINVAL] 15
+The \fIvaddr\fR argument is not equal to zero, and the value is an illegal
+address (not on a MMAPLBA boundary, already used in the process or not
+below \fIMAXUVADR\fR, as defined in <sys/immu.h>).
+.IP [EINVAL] 15
+The \fIphysaddr\fR argument is not on a page boundary.
+.IP [ENOMEM] 15
+The \fIvaddr\fR argument is equal to zero and the driver is not able
+to find a proper region in the user's address space where the memory
+range would fit in.
+.IP [ENOMEM] 15
+The size of the user's virtual address space would exceed the system-imposed
+limit.
+.IP [ENOMEM] 15
+Not enough system internal space available to grow the user's virtual
+address space.
+.IP [EMFILE] 15
+The number of shared memory segments attached to the calling process would
+exceed the system-imposed limit.
+.IP [EMFILE] 15
+The number of all memory mapped regions in the system would exceed the
+driver-imposed limit.
+.RE 1
+.IP \fBUNMAP\fP 2
+This call unmaps previously mapped physical memory from the calling process.
+The argument \fIarg\fR to the ioctl must be the virtual address as
+returned by the previous \fIMAP\fR ioctl.
+.br
+It will fail if one or more of the following is true:
+.RS 4
+.IP [EPERM] 15
+The effective user ID of the calling process is not superuser.
+.IP [EINVAL] 15
+If \fIarg\fR is not the start address of a region mapped by the driver to
+the calling process.
+.RE 1
+.IP \fBUNMAPRM\fP 2
+Same like \fIUNMAP\fR but removes the concerning region from the systems
+internal list, if no other process is still using it [see \fImmaprm(1L)\fR].
+.IP \fBGETNMMREG\fP 2
+This call returns the number of the memory mapped I/O regions which
+exists currently in the system [\fIsee mmapstat(1L)\fR]. It requires no
+argument. It will fail if one or more of the following is true:
+.RS 4
+.IP [EPERM] 15
+The effective user ID of the calling process is not superuser.
+.RE 1
+.IP \fBGETMMREG\fP 2
+This call returns the current status of the \fIMMAP\fR driver. The
+argument \fIarg\fR must be a pointer to an array of elements of
+the following type (defined in <sys/mmap.h>):
+.IP
+typedef struct mmapinfo {
+.br
+X paddr_t physaddr; /* physical address */
+.br
+X long length; /* size in bytes */
+.br
+X short refcnt; /* number of users */
+.br
+X /* pointing currently at this region */
+.br
+} mmapinfo_t;
+.IP "" 2
+which is filled by the driver for every region currently exists.
+The array must have as much elements as the number returned by the
+\fIGETNMMREG\fR ioctl states [see \fImmapstat(1L)\fR].
+The command will fail if one or more of the following is true:
+.RS 4
+.IP [EPERM] 15
+The effective user ID of the calling process is not superuser.
+.IP [EFAULT] 15
+The user address pointed to by \fIarg\fR is illegal.
+.IP "" 2
+.RE 1
+.IP \fBGETVERSION\fP 2
+Returns version number of driver, e.g. version 2.2.1 would be returned
+as 0x0221.
+.SH FILES
+.IP \fI/dev/mmap\fR 2
+Character device interface to the driver.
+.SH "SEE ALSO"
+open(2), ioctl(2), display(7), shmget(2), shmop(2), shmctl(2), kconfig(1),
+idtune(1M), intro(2), mmapstat(1L), mmaprm(1L).
+.SH DIAGNOSTICS
+Upon sucessful completion, the return value is as follows:
+.RS 5
+.P
+The \fIMAP\fR ioctl returns the user's address where the physical memory
+is mapped in.
+.P
+The \fIUNMAP\fR and \fIUNMAPRM\fR ioctl's return a value of 0.
+.P
+The \fIGETNMMREG\fR ioctl returns the number of memory mapped I/O regions
+which exists currently in the system.
+.P
+The \fIGETMMREG\fR ioctl returns a value of 0.
+.P
+The \fIGETVERSION\fR ioctl returns the version number.
+.RE 1
+.P
+Otherwise, a value of -1 is returned, and \fIerrno\fR [see \fIintro(2)\fR]
+is set to indicate the error.
+.SH BUGS
+Please report bugs to:
+.B wolf@prz.tu-berlin.de
+or
+.BR thomas@aeon.in-berlin.de .
+.SH COPYING
+Copyright (c) 1993 Thomas Wolfram
+.SH AUTHOR
+Thomas Wolfram
+SHAR_EOF
+chmod 0644 mmap-2.2.3/mmap.man ||
+echo 'restore of mmap-2.2.3/mmap.man failed'
+Wc_c="`wc -c < 'mmap-2.2.3/mmap.man'`"
+test 7901 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/mmap.man: original size 7901, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/mmaprm.1 ==============
+if test -f 'mmap-2.2.3/mmaprm.1' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/mmaprm.1 (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/mmaprm.1 (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmaprm.1' &&
+X
+X
+X
+X mmaprm(1L) 386/ix mmaprm(1L)
+X
+X
+X
+X NAME
+X mmaprm - remove a memory mapped I/O region of the MMMMMMMMAAAAPPPP
+X driver
+X
+X SYNOPSIS
+X mmaprm #
+X
+X DESCRIPTION
+X The _m_m_a_p_r_m removes a memory mapped I/O region number # from
+X the _M_M_A_P driver's [see _m_m_a_p(_7)] internal list and frees also
+X the concerning system resource. The command will fail if the
+X region is still used by other processes. The number # is
+X the number as returned by the _m_m_a_p_s_t_a_t(_1_L) command.
+X
+X FILES
+X /_d_e_v/_m_m_a_p
+X Character device interface to the _M_M_A_P driver.
+X
+X SEE ALSO
+X mmap(7L), mmapstat(1L).
+X
+X BUGS
+X Please report bugs to: wwwwoooollllffff@@@@pppprrrrzzzz....ttttuuuu----bbbbeeeerrrrlllliiiinnnn....ddddeeee or
+X tttthhhhoooommmmaaaassss@@@@aaaaeeeeoooonnnn....iiiinnnn----bbbbeeeerrrrlllliiiinnnn....ddddeeee.
+X
+X COPYING
+X Copyright (c) 1993 Thomas Wolfram
+X
+X AUTHOR
+X Thomas Wolfram
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X Rev. 2.2.3, 22 November 1993 Page 1
+X
+X
+X
+SHAR_EOF
+chmod 0644 mmap-2.2.3/mmaprm.1 ||
+echo 'restore of mmap-2.2.3/mmaprm.1 failed'
+Wc_c="`wc -c < 'mmap-2.2.3/mmaprm.1'`"
+test 1495 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/mmaprm.1: original size 1495, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/mmaprm.c ==============
+if test -f 'mmap-2.2.3/mmaprm.c' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/mmaprm.c (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/mmaprm.c (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmaprm.c' &&
+/*
+X * Copyright (c) 1993 by Thomas Wolfram, Berlin, Germany.
+X *
+X * Permission to use, copy, modify, distribute, and sell this software and its
+X * documentation for any purpose is hereby granted without fee, provided that
+X * the above copyright notice appear in all copies and that both that
+X * copyright notice and this permission notice appear in supporting
+X * documentation, and that the name of Thomas Wolfram be used in
+X * advertising or publicity pertaining to distribution of the software without
+X * specific, written prior permission. Thomas Wolfram makes no
+X * representations about the suitability of this software for any purpose.
+X * It is provided "as is" without express or implied warranty.
+X *
+X * THOMAS WOLFRAM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+X * EVENT SHALL THOMAS WOLFRAM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+X * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+X * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+X * PERFORMANCE OF THIS SOFTWARE.
+X *
+X * Author: Thomas Wolfram, thomas@aeon.in-berlin.de, wolf@prz.tu-berlin.de
+X */
+X
+/* mmaprm
+X * ------
+X * Free mmap I/O regions from drivers internal list.
+X */
+X
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+X
+#ifndef SCO
+#include <sys/at_ansi.h>
+#include <sys/kd.h>
+#else
+#include <sys/vtkd.h>
+#endif
+#include <sys/sysmacros.h>
+#include <sys/immu.h>
+#include <sys/region.h>
+X
+#include <sys/mmap.h>
+X
+X
+void ErrorExit(s)
+X char *s;
+{
+X perror(s);
+X exit(1);
+}
+X
+X
+main(argc, argv)
+X int argc;
+X char **argv;
+{
+X int mmap, regnr, nmmreg;
+X unsigned char eoi;
+X mmapinfo_t *ibuf;
+X caddr_t mapaddr;
+X struct kd_memloc memDesc;
+X
+X if(argc != 2) {
+X fprintf(stderr, "usage: %s n1\n", argv[0]);
+X exit(1);
+X }
+X
+X
+X if((mmap = open("/dev/mmap", O_RDONLY)) == -1)
+X ErrorExit(argv[0]);
+X
+X if(ioctl(mmap, GETVERSION) < 0x0221) {
+X fprintf(stderr, "%s: MMAP 2.2.1 or above required.\n", argv[0]);
+X exit(1);
+X }
+X
+X if((nmmreg = ioctl(mmap, GETNMMREG)) == -1)
+X ErrorExit(argv[0]);
+X
+X if(nmmreg == 0) {
+X fprintf(stderr, "%s: No physical memory mapped currently.\n", argv[0]);
+X exit(1);
+X }
+X
+X if(!sscanf(argv[1], "%d%c\n", &regnr, &eoi)) {
+X fprintf(stderr, "%s: Invalid region number\n", argv[0]);
+X exit(1);
+X }
+X
+X if(eoi != '\0' || regnr < 0 || regnr >= nmmreg) {
+X fprintf(stderr, "%s: Invalid region number\n", argv[0]);
+X exit(1);
+X }
+X
+X if((ibuf = (mmapinfo_t *)malloc(nmmreg*sizeof(mmapinfo_t))) == NULL)
+X ErrorExit(argv[0]);
+X
+X
+X if(ioctl(mmap, GETMMREG, ibuf) == -1)
+X ErrorExit(argv[0]);
+X
+X
+X memDesc.physaddr = (caddr_t)ibuf[regnr].physaddr;
+X memDesc.length = ibuf[regnr].length;
+X memDesc.vaddr = (caddr_t)0;
+X
+X printf("Try removing memory mapped I/O region %d from system...\n", regnr);
+X printf("[%d] Physical Address = 0x%08X\n", regnr, memDesc.physaddr);
+X printf("[%d] Size = %dk\n", regnr, memDesc.length/1024);
+X
+X if(ibuf[regnr].refcnt > 0) {
+X fprintf(stderr, "Region %d still in use. Cannot remove.\n", regnr);
+X exit(1);
+X }
+X
+X if((mapaddr = (caddr_t)ioctl(mmap, MAP, &memDesc)) == (caddr_t)-1)
+X ErrorExit(argv[0]);
+X
+X ioctl(mmap, UNMAPRM, mapaddr);
+X printf("Removed.\n");
+X
+}
+X
+SHAR_EOF
+chmod 0644 mmap-2.2.3/mmaprm.c ||
+echo 'restore of mmap-2.2.3/mmaprm.c failed'
+Wc_c="`wc -c < 'mmap-2.2.3/mmaprm.c'`"
+test 3346 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/mmaprm.c: original size 3346, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/mmaprm.man ==============
+if test -f 'mmap-2.2.3/mmaprm.man' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/mmaprm.man (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/mmaprm.man (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmaprm.man' &&
+.\" Copyright (c) 1993 by Thomas Wolfram
+.TH mmaprm 1L "2.2.3, 22 November 1993" "Version 2.2.3"
+.de BP
+.sp
+.ti -.2i
+\(**
+..
+.SH NAME
+mmaprm \- remove a memory mapped I/O region of the \fBMMAP\fP driver
+.SH SYNOPSIS
+mmaprm #
+.SH DESCRIPTION
+The \fImmaprm\fR removes a memory mapped I/O region number # from
+the \fIMMAP\fR driver's [see \fImmap(7)\fR] internal list and frees
+also the concerning system resource. The command will fail if the
+region is still used by other processes.
+The number # is the number as returned by the \fImmapstat(1L)\fR command.
+.SH FILES
+.IP \fI/dev/mmap\fR 2
+Character device interface to the \fIMMAP\fR driver.
+.SH "SEE ALSO"
+mmap(7L), mmapstat(1L).
+.SH BUGS
+Please report bugs to:
+.B wolf@prz.tu-berlin.de
+or
+.BR thomas@aeon.in-berlin.de .
+.SH COPYING
+Copyright (c) 1993 Thomas Wolfram
+.SH AUTHOR
+Thomas Wolfram
+SHAR_EOF
+chmod 0644 mmap-2.2.3/mmaprm.man ||
+echo 'restore of mmap-2.2.3/mmaprm.man failed'
+Wc_c="`wc -c < 'mmap-2.2.3/mmaprm.man'`"
+test 843 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/mmaprm.man: original size 843, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/mmapstat.1 ==============
+if test -f 'mmap-2.2.3/mmapstat.1' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/mmapstat.1 (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/mmapstat.1 (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmapstat.1' &&
+X
+X
+X
+X mmapstat(1L) 386/ix mmapstat(1L)
+X
+X
+X
+X NAME
+X mmapstat - print status of the MMMMMMMMAAAAPPPP driver
+X
+X SYNOPSIS
+X mmapstat
+X
+X DESCRIPTION
+X The _m_m_a_p_s_t_a_t command prints the current status of the _M_M_A_P
+X driver [see _m_m_a_p(_7)].
+X For every memory mapped I/O region which exists currently in
+X the system _m_m_a_p_s_t_a_t prints the physical address, the size in
+X kByte and the number of processes which currently uses this
+X region.
+X
+X FILES
+X /_d_e_v/_m_m_a_p
+X Character device interface to the _M_M_A_P driver.
+X
+X SEE ALSO
+X mmap(7L), mmaprm(1L).
+X
+X BUGS
+X Please report bugs to: wwwwoooollllffff@@@@pppprrrrzzzz....ttttuuuu----bbbbeeeerrrrlllliiiinnnn....ddddeeee or
+X tttthhhhoooommmmaaaassss@@@@aaaaeeeeoooonnnn....iiiinnnn----bbbbeeeerrrrlllliiiinnnn....ddddeeee.
+X
+X COPYING
+X Copyright (c) 1993 Thomas Wolfram
+X
+X AUTHOR
+X Thomas Wolfram
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X
+X Rev. 2.2.3, 22 November 1993 Page 1
+X
+X
+X
+SHAR_EOF
+chmod 0644 mmap-2.2.3/mmapstat.1 ||
+echo 'restore of mmap-2.2.3/mmapstat.1 failed'
+Wc_c="`wc -c < 'mmap-2.2.3/mmapstat.1'`"
+test 1453 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/mmapstat.1: original size 1453, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/mmapstat.c ==============
+if test -f 'mmap-2.2.3/mmapstat.c' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/mmapstat.c (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/mmapstat.c (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmapstat.c' &&
+/*
+X * Copyright (c) 1993 by Thomas Wolfram, Berlin, Germany.
+X *
+X * Permission to use, copy, modify, distribute, and sell this software and its
+X * documentation for any purpose is hereby granted without fee, provided that
+X * the above copyright notice appear in all copies and that both that
+X * copyright notice and this permission notice appear in supporting
+X * documentation, and that the name of Thomas Wolfram be used in
+X * advertising or publicity pertaining to distribution of the software without
+X * specific, written prior permission. Thomas Wolfram makes no
+X * representations about the suitability of this software for any purpose.
+X * It is provided "as is" without express or implied warranty.
+X *
+X * THOMAS WOLFRAM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+X * EVENT SHALL THOMAS WOLFRAM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+X * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+X * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+X * PERFORMANCE OF THIS SOFTWARE.
+X *
+X * Author: Thomas Wolfram, thomas@aeon.in-berlin.de, wolf@prz.tu-berlin.de
+X */
+X
+/* mmapinfo
+X * --------
+X * Gets the status of the MMAP driver.
+X */
+X
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <time.h>
+X
+#ifndef SCO
+#include <sys/at_ansi.h>
+#include <sys/kd.h>
+#else
+#include <sys/vtkd.h>
+#endif
+#include <sys/sysmacros.h>
+#include <sys/immu.h>
+#include <sys/region.h>
+X
+#include <sys/mmap.h>
+X
+X
+void ErrorExit(s)
+X char *s;
+{
+X perror(s);
+X exit(1);
+}
+X
+X
+main(argc, argv)
+X int argc;
+X char **argv;
+{
+X int mmap, nmmreg, i;
+X mmapinfo_t *ibuf;
+X time_t clock;
+X
+X
+X if((mmap = open("/dev/mmap", O_RDONLY)) == -1)
+X ErrorExit(argv[0]);
+X
+X if((nmmreg = ioctl(mmap, GETNMMREG)) == -1)
+X ErrorExit(argv[0]);
+X
+X time(&clock);
+X
+X printf("Currently memory mapped I/O regions as of %s", ctime(&clock));
+X printf("# Physical Address Size Reference Count\n");
+X
+X if(nmmreg == 0) {
+X printf("\nNo physical memory mapped currently.\n\n");
+X exit(1);
+X }
+X
+X
+X if((ibuf = (mmapinfo_t *)malloc(nmmreg*sizeof(mmapinfo_t))) == NULL)
+X ErrorExit(argv[0]);
+X
+X if(ioctl(mmap, GETMMREG, ibuf) == -1)
+X ErrorExit(argv[0]);
+X
+X for(i = 0; i < nmmreg; i++)
+X printf("%-4d 0x%08X %5dk %5d\n",
+X i, ibuf[i].physaddr, ibuf[i].length/1024, ibuf[i].refcnt);
+X printf("\n");
+X
+}
+X
+SHAR_EOF
+chmod 0644 mmap-2.2.3/mmapstat.c ||
+echo 'restore of mmap-2.2.3/mmapstat.c failed'
+Wc_c="`wc -c < 'mmap-2.2.3/mmapstat.c'`"
+test 2531 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/mmapstat.c: original size 2531, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/mmapstat.man ==============
+if test -f 'mmap-2.2.3/mmapstat.man' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/mmapstat.man (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/mmapstat.man (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/mmapstat.man' &&
+.\" Copyright (c) 1993 by Thomas Wolfram
+.TH mmapstat 1L "2.2.3, 22 November 1993" "Version 2.2.3"
+.de BP
+.sp
+.ti -.2i
+\(**
+..
+.SH NAME
+mmapstat \- print status of the \fBMMAP\fP driver
+.SH SYNOPSIS
+mmapstat
+.SH DESCRIPTION
+The \fImmapstat\fR command prints the current status of the \fIMMAP\fR
+driver [see \fImmap(7)\fR].
+.br
+For every memory mapped I/O region which exists currently in the system
+\fImmapstat\fR prints the physical address, the size in kByte and
+the number of processes which currently uses this region.
+.SH FILES
+.IP \fI/dev/mmap\fR 2
+Character device interface to the \fIMMAP\fR driver.
+.SH "SEE ALSO"
+mmap(7L), mmaprm(1L).
+.SH BUGS
+Please report bugs to:
+.B wolf@prz.tu-berlin.de
+or
+.BR thomas@aeon.in-berlin.de .
+.SH COPYING
+Copyright (c) 1993 Thomas Wolfram
+.SH AUTHOR
+Thomas Wolfram
+SHAR_EOF
+chmod 0644 mmap-2.2.3/mmapstat.man ||
+echo 'restore of mmap-2.2.3/mmapstat.man failed'
+Wc_c="`wc -c < 'mmap-2.2.3/mmapstat.man'`"
+test 808 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/mmapstat.man: original size 808, current size' "$Wc_c"
+fi
+# ============= mmap-2.2.3/tstmap.c ==============
+if test -f 'mmap-2.2.3/tstmap.c' -a X"$1" != X"-c"; then
+ echo 'x - skipping mmap-2.2.3/tstmap.c (File already exists)'
+else
+echo 'x - extracting mmap-2.2.3/tstmap.c (Text)'
+sed 's/^X//' << 'SHAR_EOF' > 'mmap-2.2.3/tstmap.c' &&
+/*
+X * Copyright (c) 1993 by Thomas Wolfram, Berlin, Germany.
+X *
+X * Permission to use, copy, modify, distribute, and sell this software and its
+X * documentation for any purpose is hereby granted without fee, provided that
+X * the above copyright notice appear in all copies and that both that
+X * copyright notice and this permission notice appear in supporting
+X * documentation, and that the name of Thomas Wolfram be used in
+X * advertising or publicity pertaining to distribution of the software without
+X * specific, written prior permission. Thomas Wolfram makes no
+X * representations about the suitability of this software for any purpose.
+X * It is provided "as is" without express or implied warranty.
+X *
+X * THOMAS WOLFRAM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+X * EVENT SHALL THOMAS WOLFRAM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+X * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+X * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+X * PERFORMANCE OF THIS SOFTWARE.
+X *
+X * Author: Thomas Wolfram, thomas@aeon.in-berlin.de, wolf@prz.tu-berlin.de
+X */
+X
+/* Test program for MMAP driver, maps the main bios into the process'
+X * address space.
+X */
+X
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <errno.h>
+X
+#ifndef SCO
+#include <sys/at_ansi.h>
+#include <sys/kd.h>
+#else
+#include <sys/vtkd.h>
+#endif
+#include <sys/sysmacros.h>
+#include <sys/immu.h>
+#include <sys/region.h>
+X
+#include <sys/mmap.h>
+X
+#define MAP_SIZE 64*1024 /* 64k */
+#define PHYS_ADDR 0xF0000 /* Main BIOS */
+#define VIRT_ADDR 0
+X
+main(argc, argv)
+X int argc;
+X char **argv;
+{
+X int i;
+X int fm;
+X caddr_t mapaddr;
+X struct kd_memloc memDesc;
+X
+X memDesc.vaddr = (caddr_t)VIRT_ADDR;
+X memDesc.physaddr = (caddr_t)PHYS_ADDR;
+X memDesc.length = MAP_SIZE;
+X
+X if((fm = open("/dev/mmap", O_RDONLY)) == -1) {
+X perror(argv[0]);
+X exit(1);
+X }
+X
+X printf("MAP main BIOS...\n");
+X if((mapaddr = (caddr_t)ioctl(fm, MAP, &memDesc)) == (caddr_t)-1) {
+X perror(argv[0]);
+X exit(1);
+X }
+X
+X printf("Mapping addr = %x\n", mapaddr);
+X
+X for(i=0; i < 80; i++)
+X printf("%c", mapaddr[i]);
+X printf("\n");
+X
+X printf("UNMAP main BIOS...\n");
+X if(ioctl(fm, UNMAP, mapaddr) == -1) {
+X perror(argv[0]);
+X exit(1);
+X }
+X printf("Trying access after unmapping, should dump core...\n");
+X printf("*mapaddr = %02x\n", *(unsigned char *)mapaddr);
+X
+}
+X
+SHAR_EOF
+chmod 0644 mmap-2.2.3/tstmap.c ||
+echo 'restore of mmap-2.2.3/tstmap.c failed'
+Wc_c="`wc -c < 'mmap-2.2.3/tstmap.c'`"
+test 2539 -eq "$Wc_c" ||
+ echo 'mmap-2.2.3/tstmap.c: original size 2539, current size' "$Wc_c"
+fi
+exit 0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/pcitweak.c b/xc/programs/Xserver/hw/xfree86/etc/pcitweak.c
new file mode 100644
index 000000000..a64c91c78
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/pcitweak.c
@@ -0,0 +1,418 @@
+/*
+ * pcitweak.c
+ *
+ * Copyright 1999 by The XFree86 Project, Inc.
+ *
+ * Author: David Dawes <dawes@xfree86.org>
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/etc/pcitweak.c,v 1.10 1999/08/22 11:59:49 dawes Exp $ */
+
+#include "X.h"
+#include "os.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSproc.h"
+#include "xf86Pci.h"
+int xf86getpagesize(void);
+
+#include <stdarg.h>
+#include <stdlib.h>
+#ifdef __linux__
+/* to get getopt on Linux */
+#ifndef __USE_POSIX2
+#define __USE_POSIX2
+#endif
+#endif
+#include <unistd.h>
+#if defined(ISC) || defined(Lynx)
+extern char *optarg;
+extern int optind, opterr;
+#endif
+
+int xf86Verbose = 1;
+
+static void usage(void);
+static Bool parsePciBusString(const char *id, int *bus, int *device, int *func);
+static char *myname = NULL;
+
+int
+main(int argc, char *argv[])
+{
+ char c;
+ PCITAG tag;
+ int bus, device, func;
+ Bool list = FALSE, rd = FALSE, wr = FALSE;
+ Bool byte = FALSE, halfword = FALSE;
+ int offset = 0;
+ CARD32 value = 0;
+ char *id = NULL, *end;
+
+ myname = argv[0];
+ while ((c = getopt(argc, argv, "bhlr:w:")) != -1) {
+ switch (c) {
+ case 'b':
+ byte = TRUE;
+ break;
+ case 'h':
+ halfword = TRUE;
+ break;
+ case 'l':
+ list = TRUE;
+ break;
+ case 'r':
+ rd = TRUE;
+ id = optarg;
+ break;
+ case 'w':
+ wr = TRUE;
+ id = optarg;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (list) {
+ xf86Verbose = 2;
+ xf86EnableIO();
+ xf86scanpci(0);
+ xf86DisableIO();
+ exit(0);
+ }
+
+ if (rd && wr)
+ usage();
+ if (wr && argc != 2)
+ usage();
+ if (rd && argc != 1)
+ usage();
+ if (byte && halfword)
+ usage();
+
+ if (rd || wr) {
+ if (!parsePciBusString(id, &bus, &device, &func)) {
+ fprintf(stderr, "%s: Bad PCI ID string\n", myname);
+ usage();
+ }
+ offset = strtoul(argv[0], &end, 0);
+ if (*end != '\0') {
+ fprintf(stderr, "%s: Bad offset\n", myname);
+ usage();
+ }
+ if (halfword) {
+ if (offset % 2) {
+ fprintf(stderr, "%s: offset must be a multiple of two\n",
+ myname);
+ exit(1);
+ }
+ } else if (!byte) {
+ if (offset % 4) {
+ fprintf(stderr, "%s: offset must be a multiple of four\n",
+ myname);
+ exit(1);
+ }
+ }
+ } else {
+ usage();
+ }
+
+ if (wr) {
+ value = strtoul(argv[1], &end, 0);
+ if (*end != '\0') {
+ fprintf(stderr, "%s: Bad value\n", myname);
+ usage();
+ }
+ }
+
+ xf86EnableIO();
+
+ /*
+ * This is needed to setup all the buses. Otherwise secondary buses
+ * can't be accessed.
+ */
+ xf86scanpci(0);
+
+ tag = pciTag(bus, device, func);
+ if (rd) {
+ if (byte) {
+ printf("0x%02x\n", (unsigned int)pciReadByte(tag, offset) & 0xFF);
+ } else if (halfword) {
+ printf("0x%04x\n", (unsigned int)pciReadWord(tag, offset) & 0xFFFF);
+ } else {
+ printf("0x%08lx\n", (unsigned long)pciReadLong(tag, offset));
+ }
+ } else if (wr) {
+ if (byte) {
+ pciWriteByte(tag, offset, value & 0xFF);
+ } else if (halfword) {
+ pciWriteWord(tag, offset, value & 0xFFFF);
+ } else {
+ pciWriteLong(tag, offset, value);
+ }
+ }
+
+ xf86DisableIO();
+ exit(0);
+}
+
+static void
+usage()
+{
+ fprintf(stderr, "usage:\tpcitweak -l\n"
+ "\tpcitweak -r ID [-b | -h] offset\n"
+ "\tpcitweak -w ID [-b | -h] offset value\n"
+ "\n"
+ "\t\t-l -- list\n"
+ "\t\t-r -- read\n"
+ "\t\t-w -- write\n"
+ "\t\t-b -- read/write a single byte\n"
+ "\t\t-h -- read/write a single halfword (16 bit)\n"
+ "\t\tID -- PCI ID string in form bus:dev:func "
+ "(all in hex)\n");
+
+ exit(1);
+}
+
+Bool
+parsePciBusString(const char *busID, int *bus, int *device, int *func)
+{
+ /*
+ * The format is assumed to be "bus:device:func", where bus, device
+ * and func are hexadecimal integers. func may be omitted and assumed to
+ * be zero, although it doing this isn't encouraged.
+ */
+
+ char *p, *s, *end;
+
+ s = strdup(busID);
+ p = strtok(s, ":");
+ if (p == NULL || *p == 0)
+ return FALSE;
+ *bus = strtoul(p, &end, 16);
+ if (*end != '\0')
+ return FALSE;
+ p = strtok(NULL, ":");
+ if (p == NULL || *p == 0)
+ return FALSE;
+ *device = strtoul(p, &end, 16);
+ if (*end != '\0')
+ return FALSE;
+ *func = 0;
+ p = strtok(NULL, ":");
+ if (p == NULL || *p == 0)
+ return TRUE;
+ *func = strtoul(p, &end, 16);
+ if (*end != '\0')
+ return FALSE;
+ return TRUE;
+}
+
+
+
+/* Dummy variables */
+xf86InfoRec xf86Info;
+ScrnInfoPtr *xf86Screens;
+
+/*
+ * Utility functions required by libxf86_os. It would be nice to have
+ * a library with these somewhere.
+ */
+
+void
+VErrorF(const char *f, va_list args)
+{
+ vfprintf(stderr, f, args);
+}
+
+void
+FatalError(const char *f, ...)
+{
+ va_list args;
+
+ va_start(args, f);
+ fprintf(stderr, "%s: Fatal Error:\n", myname);
+ vfprintf(stderr, f, args);
+ va_end(args);
+ exit(1);
+}
+
+static void
+VErrorFVerb(int verb, const char *format, va_list ap)
+{
+ if (xf86Verbose >= verb)
+ VErrorF(format, ap);
+}
+
+void
+xf86ErrorFVerb(int verb, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ VErrorFVerb(verb, format, ap);
+ va_end(ap);
+}
+
+void
+xf86MsgVerb(MessageType type, int verb, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ VErrorFVerb(verb, format, ap);
+ va_end(ap);
+}
+
+void
+xf86DrvMsgVerb(int i, MessageType type, int verb, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ VErrorFVerb(verb, format, ap);
+ va_end(ap);
+}
+
+void
+xf86Msg(MessageType type, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ VErrorFVerb(1, format, ap);
+ va_end(ap);
+}
+
+void
+xf86DrvMsg(int i, MessageType type, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ VErrorFVerb(1, format, ap);
+ va_end(ap);
+}
+
+void
+xf86ErrorF(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ VErrorFVerb(1, format, ap);
+ va_end(ap);
+}
+
+
+pointer
+Xalloc(unsigned long n)
+{
+ if (!n)
+ n = 1;
+ return malloc(n);
+}
+
+pointer
+Xrealloc(pointer p, unsigned long n)
+{
+ if (!n)
+ n = 1;
+ return realloc(p, n);
+}
+
+pointer
+Xcalloc(unsigned long n)
+{
+ pointer r;
+
+ r = Xalloc(n);
+ memset(r, 0, n);
+ return r;
+}
+
+pointer
+XNFalloc(unsigned long n)
+{
+ pointer r;
+
+ r = Xalloc(n);
+ if (!r)
+ FatalError("XNFalloc failed\n");
+ return r;
+
+}
+
+pointer
+XNFrealloc(pointer p, unsigned long n)
+{
+ pointer r;
+
+ r = Xrealloc(p, n);
+ if (!r)
+ FatalError("XNFrealloc failed\n");
+ return r;
+
+}
+
+pointer
+XNFcalloc(unsigned long n)
+{
+ pointer r;
+
+ r = Xcalloc(n);
+ if (!r)
+ FatalError("XNFcalloc failed\n");
+ return r;
+
+}
+
+void
+Xfree(pointer p)
+{
+ free(p);
+}
+
+int
+xf86AllocateScrnInfoPrivateIndex()
+{
+ return -1;
+}
+
+int
+xf86GetVerbosity()
+{
+ return xf86Verbose;
+}
+
+void
+xf86ProcessOptions(int i, pointer p, OptionInfoPtr o)
+{
+}
+
+Bool
+xf86GetOptValBool(OptionInfoPtr o, int i, Bool *b)
+{
+ return FALSE;
+}
+
+Bool
+xf86ServerIsInitialising()
+{
+ return FALSE;
+}
+
+int
+xf86getpagesize(void)
+{
+ return 4096; /* not used */
+}
+
+memType
+getValidBIOSBase(PCITAG tag, int num)
+{
+ return 0;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/etc/postinst.sh b/xc/programs/Xserver/hw/xfree86/etc/postinst.sh
new file mode 100644
index 000000000..a6836b6ce
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/postinst.sh
@@ -0,0 +1,141 @@
+#!/bin/sh
+
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/postinst.sh,v 3.15 1997/05/22 14:22:26 dawes Exp $
+#
+# postinst.sh (for XFree86 3.2A)
+#
+# This script should be run after installing a new version of XFree86.
+#
+
+RUNDIR=/usr/X11R6
+
+if [ ! -d $RUNDIR/. ]; then
+ echo $RUNDIR does not exist
+ exit 1
+fi
+
+# Since the misc fonts are distributed in two parts, make sure that the
+# fonts.dir file is correct if only one part has been installed.
+if [ -d $RUNDIR/lib/X11/fonts/misc ]; then
+ echo ""
+ echo "Updating the fonts.dir file in $RUNDIR/lib/X11/fonts/misc"
+ echo "This might take a while ..."
+ $RUNDIR/bin/mkfontdir $RUNDIR/lib/X11/fonts/misc
+fi
+
+# Check if the system has a termcap file
+TERMCAP1DIR=/usr/share
+TERMCAP2=/etc/termcap
+if [ -d $TERMCAP1DIR ]; then
+ TERMCAP1=`find $TERMCAP1DIR -type f -name termcap -print 2> /dev/null`
+ if [ x"$TERMCAP1" != x ]; then
+ TERMCAPFILE="$TERMCAP1"
+ fi
+fi
+if [ x"$TERMCAPFILE" = x ]; then
+ if [ -f $TERMCAP2 ]; then
+ TERMCAPFILE="$TERMCAP2"
+ fi
+fi
+if [ x"$TERMCAPFILE" != x ]; then
+ echo ""
+ echo "You appear to have a termcap file: $TERMCAPFILE"
+ echo "This should be edited manually to replace the xterm entries"
+ echo "with those in $RUNDIR/lib/X11/etc/xterm.termcap"
+ echo ""
+ echo "Note: the new xterm entries are required to take full advantage"
+ echo "of new features, but they may cause problems when used with"
+ echo "older versions of xterm. A terminal type 'xterm-r6' is included"
+ echo "for compatibility with the standard X11R6 version of xterm."
+fi
+
+# Check for terminfo, and update the xterm entry
+TINFODIR=/usr/lib/terminfo
+OLDTINFO=" \
+ x/xterm \
+ x/xterms \
+ x/xterm-24 \
+ x/xterm-vi \
+ x/xterm-65 \
+ x/xterm-bold \
+ x/xtermm \
+ x/xterm-boldso \
+ x/xterm-ic \
+ x/xterm-r6 \
+ x/xterm-old \
+ x/xterm-r5 \
+ v/vs100"
+
+if [ -d $TINFODIR ]; then
+ echo ""
+ echo "You appear to have a terminfo directory: $TINFODIR"
+ echo "New xterm terminfo entries can be installed now."
+ echo ""
+ echo "Note: the new xterm entries are required to take full advantage"
+ echo "of new features, but they may cause problems when used with"
+ echo "older versions of xterm. A terminal type 'xterm-r6' is included"
+ echo "for compatibility with the standard X11R6 version of xterm."
+ echo ""
+ echo "Do you wish to have the new xterm terminfo entries installed now (y/n)?"
+ read Resp
+ case "$Resp" in
+ [yY]*)
+ echo ""
+ for t in $OLDTINFO; do
+ if [ -f $TINFODIR/$t ]; then
+ echo "Moving old terminfo file $TINFODIR/$t to $TINFODIR/$t.bak"
+ rm -f $TINFODIR/$t.bak
+ mv -f $TINFODIR/$t $TINFODIR/$t.bak
+ fi
+ done
+ echo ""
+ echo "Installing new terminfo entries for xterm."
+ echo ""
+ echo "On some systems you may get warnings from tic about 'meml'"
+ echo "and 'memu'. These warnings can safely be ignored."
+ echo ""
+ tic /usr/X11R6/lib/X11/etc/xterm.terminfo
+ ;;
+ *)
+ echo ""
+ echo "Not installing new terminfo entries for xterm."
+ echo "They can be installed later by running:"
+ echo ""
+ echo " tic /usr/X11R6/lib/X11/etc/xterm.terminfo"
+ ;;
+ esac
+fi
+
+if [ -f /usr/X11R6/bin/rstartd ]; then
+ echo ""
+ echo "If you are going to use rstart and /usr/X11R6/bin isn't in the"
+ echo "default path for commands run remotely via rsh, you will need"
+ echo "a link to rstartd installed in /usr/bin."
+ echo ""
+ echo "Do you wish to have this link installed (y/n)?"
+ read Resp
+ case "$Resp" in
+ [yY]*)
+ echo "Creating link from /usr/X11R6/bin/rstartd to /usr/bin/rstartd"
+ rm -f /usr/bin/rstartd
+ ln -s /usr/X11R6/bin/rstartd /usr/bin/rstartd
+ ;;
+ esac
+fi
+
+case `uname` in
+ FreeBSD|NetBSD|OpenBSD)
+ echo ""
+ echo "Running ldconfig"
+ /sbin/ldconfig -m /usr/X11R6/lib
+ ;;
+ Linux)
+ echo ""
+ echo "You may need to reboot (or run ldconfig) before the"
+ echo "newly installed shared libraries can be used."
+ echo "Some releases of Linux don't run ldconfig automatically"
+ echo "at boot time, so you may need to run it manually."
+ ;;
+esac
+
+exit 0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/preinst.sh b/xc/programs/Xserver/hw/xfree86/etc/preinst.sh
new file mode 100644
index 000000000..0bbae04f2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/preinst.sh
@@ -0,0 +1,141 @@
+#!/bin/sh
+
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/preinst.sh,v 3.10 1997/05/24 13:46:35 dawes Exp $
+#
+# preinst.sh (for XFree86 3.2A)
+#
+# This script should be run before installing a new version.
+#
+# It removes parts of an existing installation that can cause problems
+# when extracting the new version. This includes symbolic links to old
+# beta versions, shared lib symlinks, and old files.
+#
+# $XConsortium: preinst.sh /main/5 1996/10/28 05:43:40 kaleb $
+#
+
+RUNDIR=/usr/X11R6
+LIBLIST=" \
+ libICE.so \
+ libPEX5.so \
+ libSM.so \
+ libX11.so \
+ libXIE.so \
+ libXaw.so \
+ libXext.so \
+ libXi.so \
+ libXmu.so \
+ libXp.so \
+ libXt.so \
+ libXtst.so \
+ liboldX.so \
+ libICE.so.6 \
+ libPEX5.so.6 \
+ libSM.so.6 \
+ libX11.so.6 \
+ libXIE.so.6 \
+ libXaw.so.6 \
+ libXext.so.6 \
+ libXi.so.6 \
+ libXmu.so.6 \
+ libXp.so.6 \
+ libXt.so.6 \
+ libXtst.so.6 \
+ liboldX.so.6 \
+ "
+
+OLDFILES=" \
+ lib/X11/doc/LbxproxyOnly \
+ lib/X11/xkb/keycodes/sgi \
+ lib/X11/xkb/symbols/de_nodead \
+ "
+
+# First, do some checks for Linux/ELF
+
+if [ "`uname`" = Linux ]; then
+ if file -L /bin/sh | grep ELF >/dev/null 2>&1; then
+ echo ""
+ echo "You appear to have an ELF system."
+ echo "Make sure you are installing the ELF binary dist"
+ # Check ldconfig
+ LDSO=`/sbin/ldconfig -v -n | awk '{ print $3 }'`
+ LDSOMIN=`echo $LDSO | awk -F. '{ print $3 }'`
+ LDSOMID=`echo $LDSO | awk -F. '{ print $2 }'`
+ LDSOMAJ=`echo $LDSO | awk -F. '{ print $1 }'`
+ if [ "$LDSOMAJ" -gt 1 ]; then
+ : OK
+ else
+ if [ "$LDSOMID" -gt 7 ]; then
+ : OK
+ else
+ if [ "$LDSOMIN" -ge 14 ]; then
+ : OK
+ else
+ echo ""
+ echo "Before continuing you will need to get a current version of ld.so."
+ echo "Version 1.7.14 or newer will do."
+ NEEDSOMETHING=YES
+ fi
+ fi
+ fi
+ else
+ case "`arch`" in
+ i*86)
+ echo ""
+ echo "You appear to have an a.out system."
+ echo "a.out binaries are not available for this release"
+ exit 1
+ ;;
+ esac
+ fi
+fi
+
+if [ X"$NEEDSOMETHING" != X ]; then
+ echo ""
+ echo "When you've made the required updates, re-run this script"
+ echo "before continuing with the installation"
+ exit 1
+fi
+
+
+# If there is no previous installation, there is nothing more to do
+
+if [ ! -d $RUNDIR/. ]; then
+ echo ""
+ echo Done
+ exit 0
+fi
+
+echo ""
+echo "You are strongly advised to backup your /usr/X11R6 directory before"
+echo "proceeding with this installation. This installation will overwrite"
+echo "existing files."
+echo ""
+echo "Do you want to continue? (y/n) "
+read response
+case "$response" in
+ [yY]*)
+ ;;
+ *)
+ echo Aborting
+ exit 1
+ ;;
+esac
+
+for i in $LIBLIST; do
+ if [ -h $RUNDIR/lib/$i ]; then
+ echo Removing old library link $RUNDIR/lib/$i
+ rm -f $RUNDIR/lib/$i
+ fi
+done
+
+for i in $OLDFILES; do
+ if [ -f $RUNDIR/$i ]; then
+ echo Removing old file $RUNDIR/$i
+ rm -f $RUNDIR/$i
+ fi
+done
+
+echo ""
+echo Done
+
+exit 0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/ptem.sdevice b/xc/programs/Xserver/hw/xfree86/etc/ptem.sdevice
new file mode 100644
index 000000000..17ee97007
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/ptem.sdevice
@@ -0,0 +1 @@
+ptem Y 32 0 0 0 0 0 0 0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/ptm.sdevice b/xc/programs/Xserver/hw/xfree86/etc/ptm.sdevice
new file mode 100644
index 000000000..0ad289d9e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/ptm.sdevice
@@ -0,0 +1 @@
+ptm Y 32 0 0 0 0 0 0 0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/pts.node b/xc/programs/Xserver/hw/xfree86/etc/pts.node
new file mode 100644
index 000000000..d27e6ab2f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/pts.node
@@ -0,0 +1,32 @@
+pts pts000 c 0
+pts pts001 c 1
+pts pts002 c 2
+pts pts003 c 3
+pts pts004 c 4
+pts pts005 c 5
+pts pts006 c 6
+pts pts007 c 7
+pts pts008 c 8
+pts pts009 c 9
+pts pts010 c 10
+pts pts011 c 11
+pts pts012 c 12
+pts pts013 c 13
+pts pts014 c 14
+pts pts015 c 15
+pts pts016 c 16
+pts pts017 c 17
+pts pts018 c 18
+pts pts019 c 19
+pts pts020 c 20
+pts pts021 c 21
+pts pts022 c 22
+pts pts023 c 23
+pts pts024 c 24
+pts pts025 c 25
+pts pts026 c 26
+pts pts027 c 27
+pts pts028 c 28
+pts pts029 c 29
+pts pts030 c 30
+pts pts031 c 31
diff --git a/xc/programs/Xserver/hw/xfree86/etc/pts.sdevice b/xc/programs/Xserver/hw/xfree86/etc/pts.sdevice
new file mode 100644
index 000000000..270c2ff1a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/pts.sdevice
@@ -0,0 +1 @@
+pts Y 1 0 0 0 0 0 0 0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/pty.cfg b/xc/programs/Xserver/hw/xfree86/etc/pty.cfg
new file mode 100644
index 000000000..4a37ccb24
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/pty.cfg
@@ -0,0 +1,61 @@
+#
+# Pseudo tty driver
+#
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/pty.cfg,v 3.2 1996/12/23 06:47:17 dawes Exp $
+#
+#
+#
+#
+# $XConsortium: pty.cfg /main/4 1996/02/21 17:48:08 kaleb $
+#
+C:pty:ptyopen:ptyclose:ptyread:ptywrite:ptyselect:ptyioctl:ptyinstall:ptyuninstall
+D:pty 0:ptyinfo::
+N:ptyp0:0:0666
+N:ttyp0:1:0666
+D:pty 1:ptyinfo::
+N:ptyp1:0:0666
+N:ttyp1:1:0666
+D:pty 2:ptyinfo::
+N:ptyp2:0:0666
+N:ttyp2:1:0666
+D:pty 3:ptyinfo::
+N:ptyp3:0:0666
+N:ttyp3:1:0666
+D:pty 4:ptyinfo::
+N:ptyp4:0:0666
+N:ttyp4:1:0666
+D:pty 5:ptyinfo::
+N:ptyp5:0:0666
+N:ttyp5:1:0666
+D:pty 6:ptyinfo::
+N:ptyp6:0:0666
+N:ttyp6:1:0666
+D:pty 7:ptyinfo::
+N:ptyp7:0:0666
+N:ttyp7:1:0666
+#
+D:pty 8:ptyinfo::
+N:ptyp8:0:0666
+N:ttyp8:1:0666
+D:pty 9:ptyinfo::
+N:ptyp9:0:0666
+N:ttyp9:1:0666
+D:pty a:ptyinfo::
+N:ptypa:0:0666
+N:ttypa:1:0666
+D:pty b:ptyinfo::
+N:ptypb:0:0666
+N:ttypb:1:0666
+D:pty c:ptyinfo::
+N:ptypc:0:0666
+N:ttypc:1:0666
+D:pty d:ptyinfo::
+N:ptypd:0:0666
+N:ttypd:1:0666
+D:pty e:ptyinfo::
+N:ptype:0:0666
+N:ttype:1:0666
+D:pty f:ptyinfo::
+N:ptypf:0:0666
+N:ttypf:1:0666
+
diff --git a/xc/programs/Xserver/hw/xfree86/etc/scanpci.c b/xc/programs/Xserver/hw/xfree86/etc/scanpci.c
new file mode 100644
index 000000000..85c8f88d4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/scanpci.c
@@ -0,0 +1,2004 @@
+/* $XConsortium: scanpci.c /main/25 1996/10/27 11:48:40 kaleb $ */
+/*
+ * name: scanpci.c
+ *
+ * purpose: This program will scan for and print details of
+ * devices on the PCI bus.
+
+ * author: Robin Cutshaw (robin@xfree86.org)
+ *
+ * supported O/S's: SVR4, UnixWare, SCO, Solaris,
+ * FreeBSD, NetBSD, 386BSD, BSDI BSD/386,
+ * Linux, Mach/386, ISC, DGUX
+ * DOS (WATCOM 9.5 compiler)
+ *
+ * compiling: [g]cc scanpci.c -o scanpci
+ * for SVR4 (not Solaris), UnixWare use:
+ * [g]cc -DSVR4 scanpci.c -o scanpci
+ * for DOS, watcom 9.5:
+ * wcc386p -zq -omaxet -7 -4s -s -w3 -d2 name.c
+ * and link with PharLap or other dos extender for exe
+ * case Intel DG/ux: gcc -DDGUX scanpci.c -o scanpci (with gcc-DG-2.7.2.88)
+ *
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.67 1999/08/01 07:57:31 dawes Exp $ */
+
+/*
+ * Copyright 1995 by Robin Cutshaw <robin@XFree86.Org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of the above listed copyright holder(s)
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. The above listed
+ * copyright holder(s) make(s) no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+ *
+ */
+
+#if !defined(DGUX)
+#if defined(__SVR4)
+#if !defined(SVR4)
+#define SVR4
+#endif
+#endif
+#endif
+
+
+#ifdef __EMX__
+#define INCL_DOSFILEMGR
+#include <os2.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#if defined(SVR4) && !defined(DGUX)
+#include <sys/proc.h>
+#include <sys/tss.h>
+#if defined(NCR)
+#define __STDC
+#include <sys/sysi86.h>
+#undef __STDC
+#else
+#include <sys/sysi86.h>
+#endif
+#if defined(__SUNPRO_C) || defined(sun) || defined(__sun)
+#include <sys/psw.h>
+#else
+#include <sys/seg.h>
+#endif
+#if defined(sun) && defined (i386) && defined (SVR4) /* Solaris? */
+# if !defined(V86SC_IOPL) /* Solaris 7? */
+#include <sys/v86.h> /* Nope */
+# else
+/* Do nothing what so ever */ /* Yup */
+#endif /* V86SC_IOPL */
+#else
+# include <sys/v86.h> /* Not solaris */
+#endif /* sun/i386/svr4 */
+#endif
+#if defined(__FreeBSD__) || defined(__386BSD__)
+#include <sys/file.h>
+#include <machine/console.h>
+#ifndef GCCUSESGAS
+#define GCCUSESGAS
+#endif
+#endif
+#if defined(__NetBSD__)
+#include <sys/param.h>
+#include <sys/file.h>
+#include <machine/sysarch.h>
+#ifndef GCCUSESGAS
+#define GCCUSESGAS
+#endif
+#endif
+#if defined(__bsdi__)
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <i386/isa/pcconsioctl.h>
+#ifndef GCCUSESGAS
+#define GCCUSESGAS
+#endif
+#endif
+#if defined(DGUX)
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/proc.h>
+#include <sys/param.h>
+#include <sys/kd.h>
+#endif
+#if defined(SCO) || defined(ISC)
+#ifndef ISC
+#include <sys/console.h>
+#endif
+#include <sys/param.h>
+#include <sys/immu.h>
+#include <sys/region.h>
+#include <sys/proc.h>
+#include <sys/tss.h>
+#include <sys/sysi86.h>
+#include <sys/v86.h>
+#endif
+#if defined(Lynx_22)
+#ifndef GCCUSESGAS
+#define GCCUSESGAS
+#endif
+#endif
+
+
+#if defined(__WATCOMC__)
+
+#include <stdlib.h>
+void outl(unsigned port, unsigned data);
+#pragma aux outl = "out dx, eax" parm [dx] [eax];
+void outb(unsigned port, unsigned data);
+#pragma aux outb = "out dx, al" parm [dx] [eax];
+unsigned inl(unsigned port);
+#pragma aux inl = "in eax, dx" parm [dx];
+unsigned inb(unsigned port);
+#pragma aux inb = "xor eax,eax" "in al, dx" parm [dx];
+
+#else /* __WATCOMC__ */
+
+#if defined(__GNUC__)
+
+#if !defined(__alpha__) && !defined(__powerpc__) && !defined(__sparc__)
+#if defined(GCCUSESGAS)
+#define OUTB_GCC "outb %0,%1"
+#define OUTL_GCC "outl %0,%1"
+#define INB_GCC "inb %1,%0"
+#define INL_GCC "inl %1,%0"
+#else
+#define OUTB_GCC "out%B0 (%1)"
+#define OUTL_GCC "out%L0 (%1)"
+#define INB_GCC "in%B0 (%1)"
+#define INL_GCC "in%L0 (%1)"
+#endif /* GCCUSESGAS */
+
+static void outb(unsigned short port, unsigned char val) {
+ __asm__ __volatile__(OUTB_GCC : :"a" (val), "d" (port)); }
+static void outl(unsigned short port, unsigned long val) {
+ __asm__ __volatile__(OUTL_GCC : :"a" (val), "d" (port)); }
+static unsigned char inb(unsigned short port) { unsigned char ret;
+ __asm__ __volatile__(INB_GCC : "=a" (ret) : "d" (port)); return ret; }
+static unsigned long inl(unsigned short port) { unsigned long ret;
+ __asm__ __volatile__(INL_GCC : "=a" (ret) : "d" (port)); return ret; }
+
+#endif /* !defined(__alpha__) && !defined(__powerpc__) && !defined(__sparc__) */
+#else /* __GNUC__ */
+
+#if defined(__STDC__) && (__STDC__ == 1)
+# if !defined(NCR)
+# define asm __asm
+# endif
+#endif
+
+#if defined(__SUNPRO_C)
+/*
+ * This section is a gross hack in if you tell anyone that I wrote it,
+ * I'll deny it. :-)
+ * The leave/ret instructions are the big hack to leave %eax alone on return.
+ */
+ unsigned char inb(int port) {
+ asm(" movl 8(%esp),%edx");
+ asm(" subl %eax,%eax");
+ asm(" inb (%dx)");
+ asm(" leave");
+ asm(" ret");
+ }
+
+ unsigned short inw(int port) {
+ asm(" movl 8(%esp),%edx");
+ asm(" subl %eax,%eax");
+ asm(" inw (%dx)");
+ asm(" leave");
+ asm(" ret");
+ }
+
+ unsigned long inl(int port) {
+ asm(" movl 8(%esp),%edx");
+ asm(" inl (%dx)");
+ asm(" leave");
+ asm(" ret");
+ }
+
+ void outb(int port, unsigned char value) {
+ asm(" movl 8(%esp),%edx");
+ asm(" movl 12(%esp),%eax");
+ asm(" outb (%dx)");
+ }
+
+ void outw(int port, unsigned short value) {
+ asm(" movl 8(%esp),%edx");
+ asm(" movl 12(%esp),%eax");
+ asm(" outw (%dx)");
+ }
+
+ void outl(int port, unsigned long value) {
+ asm(" movl 8(%esp),%edx");
+ asm(" movl 12(%esp),%eax");
+ asm(" outl (%dx)");
+ }
+#else
+
+#if defined(SVR4) && !defined(DGUX)
+# if !defined(__USLC__)
+# define __USLC__
+# endif
+#endif
+
+#if defined(DGUX)
+# if !defined(_USL)
+# define _USL
+# endif
+#endif
+
+#ifndef SCO325
+# include <sys/inline.h>
+#else
+# include "scoasm.h"
+#endif
+
+#endif /* SUNPRO_C */
+
+#endif /* __GNUC__ */
+#endif /* __WATCOMC__ */
+
+
+#if defined(__alpha__) || defined(__sparc__)
+#if defined(linux)
+#include <asm/unistd.h>
+#if defined(__sparc__)
+#if !defined(__NR_pciconfig_read)
+#define __NR_pciconfig_read 148
+#define __NR_pciconfig_write 149
+#endif
+#endif
+#define BUS(tag) (((tag)>>16)&0xff)
+#define DFN(tag) (((tag)>>8)&0xff)
+int pciconfig_read(
+ unsigned char bus,
+ unsigned char dfn,
+ unsigned char off,
+ unsigned char len,
+ void * buf)
+{
+ return syscall(__NR_pciconfig_read, bus, dfn, off, len, buf);
+}
+int pciconfig_write(
+ unsigned char bus,
+ unsigned char dfn,
+ unsigned char off,
+ unsigned char len,
+ void * buf)
+{
+ return syscall(__NR_pciconfig_write, bus, dfn, off, len, buf);
+}
+#else
+Generate compiler error - scanpci unsupported on non-linux alpha and sparc platforms
+#endif /* linux */
+#endif /* __alpha__ || __sparc__ */
+#if defined(Lynx) && defined(__powerpc__)
+/* let's mimick the Linux Alpha stuff for LynxOS so we don't have
+ * to change too much code
+ */
+#include <smem.h>
+
+unsigned char *pciConfBase;
+
+static __inline__ unsigned long
+swapl(unsigned long val)
+{
+ unsigned char *p = (unsigned char *)&val;
+ return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | (p[0] << 0));
+}
+
+
+#define BUS(tag) (((tag)>>16)&0xff)
+#define DFN(tag) (((tag)>>8)&0xff)
+
+#define PCIBIOS_DEVICE_NOT_FOUND 0x86
+#define PCIBIOS_SUCCESSFUL 0x00
+
+int pciconfig_read(
+ unsigned char bus,
+ unsigned char dev,
+ unsigned char offset,
+ int len, /* unused, alway 4 */
+ unsigned long *val)
+{
+ unsigned long _val;
+ unsigned long *ptr;
+
+ dev >>= 3;
+ if (bus || dev >= 16) {
+ *val = 0xFFFFFFFF;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ } else {
+ ptr = (unsigned long *)(pciConfBase + ((1<<dev) | offset));
+ _val = swapl(*ptr);
+ }
+ *val = _val;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int pciconfig_write(
+ unsigned char bus,
+ unsigned char dev,
+ unsigned char offset,
+ int len, /* unused, alway 4 */
+ unsigned long val)
+{
+ unsigned long _val;
+ unsigned long *ptr;
+
+ dev >>= 3;
+ _val = swapl(val);
+ if (bus || dev >= 16) {
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ } else {
+ ptr = (unsigned long *)(pciConfBase + ((1<<dev) | offset));
+ *ptr = _val;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+#endif
+
+#if !defined(__powerpc__) && !defined(__sparc__)
+struct pci_config_reg {
+ /* start of official PCI config space header */
+ union {
+ unsigned long device_vendor;
+ struct {
+ unsigned short vendor;
+ unsigned short device;
+ } dv;
+ } dv_id;
+#define _device_vendor dv_id.device_vendor
+#define _vendor dv_id.dv.vendor
+#define _device dv_id.dv.device
+ union {
+ unsigned long status_command;
+ struct {
+ unsigned short command;
+ unsigned short status;
+ } sc;
+ } stat_cmd;
+#define _status_command stat_cmd.status_command
+#define _command stat_cmd.sc.command
+#define _status stat_cmd.sc.status
+ union {
+ unsigned long class_revision;
+ struct {
+ unsigned char rev_id;
+ unsigned char prog_if;
+ unsigned char sub_class;
+ unsigned char base_class;
+ } cr;
+ } class_rev;
+#define _class_revision class_rev.class_revision
+#define _rev_id class_rev.cr.rev_id
+#define _prog_if class_rev.cr.prog_if
+#define _sub_class class_rev.cr.sub_class
+#define _base_class class_rev.cr.base_class
+ union {
+ unsigned long bist_header_latency_cache;
+ struct {
+ unsigned char cache_line_size;
+ unsigned char latency_timer;
+ unsigned char header_type;
+ unsigned char bist;
+ } bhlc;
+ } bhlc;
+#define _bist_header_latency_cache bhlc.bist_header_latency_cache
+#define _cache_line_size bhlc.bhlc.cache_line_size
+#define _latency_timer bhlc.bhlc.latency_timer
+#define _header_type bhlc.bhlc.header_type
+#define _bist bhlc.bhlc.bist
+ union {
+ struct {
+ unsigned long dv_base0;
+ unsigned long dv_base1;
+ unsigned long dv_base2;
+ unsigned long dv_base3;
+ unsigned long dv_base4;
+ unsigned long dv_base5;
+ } dv;
+ struct {
+ unsigned long bg_rsrvd[2];
+ unsigned char primary_bus_number;
+ unsigned char secondary_bus_number;
+ unsigned char subordinate_bus_number;
+ unsigned char secondary_latency_timer;
+ unsigned char io_base;
+ unsigned char io_limit;
+ unsigned short secondary_status;
+ unsigned short mem_base;
+ unsigned short mem_limit;
+ unsigned short prefetch_mem_base;
+ unsigned short prefetch_mem_limit;
+ } bg;
+ } bc;
+#define _base0 bc.dv.dv_base0
+#define _base1 bc.dv.dv_base1
+#define _base2 bc.dv.dv_base2
+#define _base3 bc.dv.dv_base3
+#define _base4 bc.dv.dv_base4
+#define _base5 bc.dv.dv_base5
+#define _primary_bus_number bc.bg.primary_bus_number
+#define _secondary_bus_number bc.bg.secondary_bus_number
+#define _subordinate_bus_number bc.bg.subordinate_bus_number
+#define _secondary_latency_timer bc.bg.secondary_latency_timer
+#define _io_base bc.bg.io_base
+#define _io_limit bc.bg.io_limit
+#define _secondary_status bc.bg.secondary_status
+#define _mem_base bc.bg.mem_base
+#define _mem_limit bc.bg.mem_limit
+#define _prefetch_mem_base bc.bg.prefetch_mem_base
+#define _prefetch_mem_limit bc.bg.prefetch_mem_limit
+ unsigned long rsvd1;
+ union { /* Offset 0x2c - 0x2f */
+ unsigned long subsys_card_vendor;
+ unsigned long rsvd2;
+ struct {
+ unsigned short subsys_vendor;
+ unsigned short subsys_card;
+ } ssys;
+ } ssys_id;
+#define _subsys_card_vendor ssys_id.subsys_card_vendor
+#define _subsys_vendor ssys_id.ssys.subsys_vendor
+#define _subsys_card ssys_id.ssys.subsys_card
+ unsigned long _baserom;
+ unsigned long rsvd3;
+ unsigned long rsvd4;
+ union {
+ union {
+ unsigned long max_min_ipin_iline;
+ struct {
+ unsigned char int_line;
+ unsigned char int_pin;
+ unsigned char min_gnt;
+ unsigned char max_lat;
+ } mmii;
+ } mmii;
+ struct {
+ unsigned char res1;
+ unsigned char res2;
+ unsigned char bridge_control;
+ unsigned char res3;
+ } bctrl;
+ } bm;
+#define _max_min_ipin_iline bm.mmii.max_min_ipin_iline
+#define _int_line bm.mmii.mmii.int_line
+#define _int_pin bm.mmii.mmii.int_pin
+#define _min_gnt bm.mmii.mmii.min_gnt
+#define _max_lat bm.mmii.mmii.max_lat
+#define _b_ctrl bm.bctrl.bridge_control
+ /* I don't know how accurate or standard this is (DHD) */
+ union {
+ unsigned long user_config;
+ struct {
+ unsigned char user_config_0;
+ unsigned char user_config_1;
+ unsigned char user_config_2;
+ unsigned char user_config_3;
+ } uc;
+ } uc;
+#define _user_config uc.user_config
+#define _user_config_0 uc.uc.user_config_0
+#define _user_config_1 uc.uc.user_config_1
+#define _user_config_2 uc.uc.user_config_2
+#define _user_config_3 uc.uc.user_config_3
+ /* end of official PCI config space header */
+ unsigned long _pcibusidx;
+ unsigned long _pcinumbus;
+ unsigned long _pcibuses[16];
+ unsigned short _configtype; /* config type found */
+ unsigned short _ioaddr; /* config type 1 - private I/O addr */
+ unsigned long _cardnum; /* config type 2 - private card number */
+};
+#else
+/* ppc and sparc are big endian, swapping bytes is not quite enough
+ * to interpret the PCI config registers...
+ */
+struct pci_config_reg {
+ /* start of official PCI config space header */
+ union {
+ unsigned long device_vendor;
+ struct {
+ unsigned short device;
+ unsigned short vendor;
+ } dv;
+ } dv_id;
+#define _device_vendor dv_id.device_vendor
+#define _vendor dv_id.dv.vendor
+#define _device dv_id.dv.device
+ union {
+ unsigned long status_command;
+ struct {
+ unsigned short status;
+ unsigned short command;
+ } sc;
+ } stat_cmd;
+#define _status_command stat_cmd.status_command
+#define _command stat_cmd.sc.command
+#define _status stat_cmd.sc.status
+ union {
+ unsigned long class_revision;
+ struct {
+ unsigned char base_class;
+ unsigned char sub_class;
+ unsigned char prog_if;
+ unsigned char rev_id;
+ } cr;
+ } class_rev;
+#define _class_revision class_rev.class_revision
+#define _rev_id class_rev.cr.rev_id
+#define _prog_if class_rev.cr.prog_if
+#define _sub_class class_rev.cr.sub_class
+#define _base_class class_rev.cr.base_class
+ union {
+ unsigned long bist_header_latency_cache;
+ struct {
+ unsigned char bist;
+ unsigned char header_type;
+ unsigned char latency_timer;
+ unsigned char cache_line_size;
+ } bhlc;
+ } bhlc;
+#define _bist_header_latency_cache bhlc.bist_header_latency_cache
+#define _cache_line_size bhlc.bhlc.cache_line_size
+#define _latency_timer bhlc.bhlc.latency_timer
+#define _header_type bhlc.bhlc.header_type
+#define _bist bhlc.bhlc.bist
+ union {
+ struct {
+ unsigned long dv_base0;
+ unsigned long dv_base1;
+ unsigned long dv_base2;
+ unsigned long dv_base3;
+ unsigned long dv_base4;
+ unsigned long dv_base5;
+ } dv;
+/* ?? */
+ struct {
+ unsigned long bg_rsrvd[2];
+
+ unsigned char secondary_latency_timer;
+ unsigned char subordinate_bus_number;
+ unsigned char secondary_bus_number;
+ unsigned char primary_bus_number;
+
+ unsigned short secondary_status;
+ unsigned char io_limit;
+ unsigned char io_base;
+
+ unsigned short mem_limit;
+ unsigned short mem_base;
+
+ unsigned short prefetch_mem_limit;
+ unsigned short prefetch_mem_base;
+ } bg;
+ } bc;
+#define _base0 bc.dv.dv_base0
+#define _base1 bc.dv.dv_base1
+#define _base2 bc.dv.dv_base2
+#define _base3 bc.dv.dv_base3
+#define _base4 bc.dv.dv_base4
+#define _base5 bc.dv.dv_base5
+#define _primary_bus_number bc.bg.primary_bus_number
+#define _secondary_bus_number bc.bg.secondary_bus_number
+#define _subordinate_bus_number bc.bg.subordinate_bus_number
+#define _secondary_latency_timer bc.bg.secondary_latency_timer
+#define _io_base bc.bg.io_base
+#define _io_limit bc.bg.io_limit
+#define _secondary_status bc.bg.secondary_status
+#define _mem_base bc.bg.mem_base
+#define _mem_limit bc.bg.mem_limit
+#define _prefetch_mem_base bc.bg.prefetch_mem_base
+#define _prefetch_mem_limit bc.bg.prefetch_mem_limit
+ unsigned long rsvd1;
+ union { /* Offset 0x2c - 0x2f */
+ unsigned long subsys_card_vendor;
+ unsigned long rsvd2;
+ struct {
+ unsigned short subsys_card;
+ unsigned short subsys_vendor;
+ } ssys;
+ } ssys_id;
+#define _subsys_card_vendor ssys_id.subsys_card_vendor
+#define _subsys_vendor ssys_id.ssys.subsys_vendor
+#define _subsys_card ssys_id.ssys.subsys_card
+ unsigned long _baserom;
+ unsigned long rsvd3;
+ unsigned long rsvd4;
+ union {
+ union {
+ unsigned long max_min_ipin_iline;
+ struct {
+ unsigned char max_lat;
+ unsigned char min_gnt;
+ unsigned char int_pin;
+ unsigned char int_line;
+ } mmii;
+ } mmii;
+ struct {
+ unsigned char res1;
+ unsigned char bridge_control;
+ unsigned char res2;
+ unsigned char res3;
+ } bctrl;
+ } bm;
+#define _max_min_ipin_iline bm.mmii.max_min_ipin_iline
+#define _int_line bm.mmii.mmii.int_line
+#define _int_pin bm.mmii.mmii.int_pin
+#define _min_gnt bm.mmii.mmii.min_gnt
+#define _max_lat bm.mmii.mmii.max_lat
+#define _b_ctrl bm.bctrl.bridge_control
+ /* I don't know how accurate or standard this is (DHD) */
+ union {
+ unsigned long user_config;
+ struct {
+ unsigned char user_config_3;
+ unsigned char user_config_2;
+ unsigned char user_config_1;
+ unsigned char user_config_0;
+ } uc;
+ } uc;
+#define _user_config uc.user_config
+#define _user_config_0 uc.uc.user_config_0
+#define _user_config_1 uc.uc.user_config_1
+#define _user_config_2 uc.uc.user_config_2
+#define _user_config_3 uc.uc.user_config_3
+ /* end of official PCI config space header */
+ unsigned long _pcibusidx;
+ unsigned long _pcinumbus;
+ unsigned long _pcibuses[16];
+ unsigned short _ioaddr; /* config type 1 - private I/O addr */
+ unsigned short _configtype; /* config type found */
+ unsigned long _cardnum; /* config type 2 - private card number */
+};
+#endif
+
+extern void identify_card(struct pci_config_reg *, int);
+extern void print_default_class(struct pci_config_reg *pcr);
+extern void print_bridge_pci_class(struct pci_config_reg *pcr);
+extern void print_bridge_class(struct pci_config_reg *pcr);
+extern void print_i128(struct pci_config_reg *);
+extern void print_mach64(struct pci_config_reg *);
+extern void print_pcibridge(struct pci_config_reg *);
+extern void enable_os_io();
+extern void disable_os_io();
+
+#define MAX_DEV_PER_VENDOR_CFG1 32
+#define MAX_DEV_PER_VENDOR_CFG2 16
+#define MAX_PCI_DEVICES 64
+#define NF ((void (*)())NULL)
+#define PCI_MULTIFUNC_DEV 0x80
+#if defined(__alpha__) || defined(__powerpc__) || defined(__sparc__)
+#define PCI_ID_REG 0x00
+#define PCI_CMD_STAT_REG 0x04
+#define PCI_CLASS_REG 0x08
+#define PCI_HEADER_MISC 0x0C
+#define PCI_MAP_REG_START 0x10
+#define PCI_MAP_ROM_REG 0x30
+#define PCI_INTERRUPT_REG 0x3C
+#define PCI_REG_USERCONFIG 0x40
+#endif
+
+struct pci_vendor_device {
+ unsigned short vendor_id;
+ char *vendorname;
+ struct pci_device {
+ unsigned short device_id;
+ char *devicename;
+ void (*print_func)(struct pci_config_reg *);
+ } device[MAX_DEV_PER_VENDOR_CFG1];
+} pvd[] = {
+ { 0x0e11, "Compaq", {
+ { 0x3033, "QVision 1280/p", NF },
+ { 0xae10, "Smart-2/P RAID Controller", NF },
+ { 0xae32, "Netellignet 10/100", NF },
+ { 0xae34, "Netellignet 10", NF },
+ { 0xae35, "NetFlex 3", NF },
+ { 0xae40, "Netellignet 10/100 Dual", NF },
+ { 0xae43, "Netellignet 10/100 ProLiant", NF },
+ { 0xb011, "Netellignet 10/100 Integrated", NF },
+ { 0xf130, "ThunderLAN", NF },
+ { 0xf150, "NetFlex 3 BNC", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1000, "NCR", {
+ { 0x0001, "53C810", NF },
+ { 0x0002, "53C820", NF },
+ { 0x0003, "53C825", NF },
+ { 0x0004, "53C815", NF },
+ { 0x0005, "53C810AP", NF },
+ { 0x0006, "53C860", NF },
+ { 0x000B, "53C896", NF },
+ { 0x000C, "53C895", NF },
+ { 0x000D, "53C885", NF },
+ { 0x000F, "53C875", NF },
+ { 0x008F, "53C875J", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1002, "ATI", {
+ { 0x4158, "Mach32", NF },
+ { 0x4354, "Mach64 CT", print_mach64 },
+ { 0x4358, "Mach64 CX", print_mach64 },
+ { 0x4554, "Mach64 ET", print_mach64 },
+ { 0x4742, "Mach64 GB", print_mach64 },
+ { 0x4744, "Mach64 GD", print_mach64 },
+ { 0x4749, "Mach64 GI", print_mach64 },
+ { 0x474D, "Mach64 GM", print_mach64 },
+ { 0x474E, "Mach64 GN", print_mach64 },
+ { 0x474F, "Mach64 GO", print_mach64 },
+ { 0x4750, "Mach64 GP", print_mach64 },
+ { 0x4751, "Mach64 GQ", print_mach64 },
+ { 0x4752, "Mach64 GR", print_mach64 },
+ { 0x4753, "Mach64 GS", print_mach64 },
+ { 0x4754, "Mach64 GT", print_mach64 },
+ { 0x4755, "Mach64 GU", print_mach64 },
+ { 0x4756, "Mach64 GV", print_mach64 },
+ { 0x4757, "Mach64 GW", print_mach64 },
+ { 0x4758, "Mach64 GX", print_mach64 },
+ { 0x475A, "Mach64 GZ", print_mach64 },
+ { 0x4C42, "Mach64 LB", print_mach64 },
+ { 0x4C44, "Mach64 LD", print_mach64 },
+ { 0x4C47, "Mach64 LG", print_mach64 },
+ { 0x4C49, "Mach64 LI", print_mach64 },
+ { 0x4C50, "Mach64 LP", print_mach64 },
+ { 0x5654, "Mach64 VT", print_mach64 },
+ { 0x5655, "Mach64 VU", print_mach64 },
+ { 0x5656, "Mach64 VV", print_mach64 },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1004, "VLSI", {
+ { 0x0005, "82C592-FC1", NF },
+ { 0x0006, "82C593-FC1", NF },
+ { 0x0007, "82C594-AFC2", NF },
+ { 0x0009, "82C597-AFC2", NF },
+ { 0x000C, "82C541 Lynx", NF },
+ { 0x000D, "82C543 Lynx ISA", NF },
+ { 0x0702, "VAS96011", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1005, "Avance Logic", {
+ { 0x2301, "ALG2301", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x100B, "NS", {
+ { 0x0002, "87415", NF },
+ { 0xD001, "87410", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x100C, "Tseng Labs", {
+ { 0x3202, "ET4000w32p rev A", NF },
+ { 0x3205, "ET4000w32p rev B", NF },
+ { 0x3206, "ET4000w32p rev D", NF },
+ { 0x3207, "ET4000w32p rev C", NF },
+ { 0x3208, "ET6000/6100", NF },
+ { 0x4702, "ET6300", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x100E, "Weitek", {
+ { 0x9001, "P9000", NF },
+ { 0x9100, "P9100", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1011, "Digital Equipment Corporation", {
+ { 0x0001, "DC21050 PCI-PCI Bridge",print_pcibridge},
+ { 0x0002, "DC21040 10Mb/s Ethernet", NF },
+ { 0x0004, "TGA", NF },
+ { 0x0009, "DC21140 10/100 Mb/s Ethernet", NF },
+ { 0x000D, "TGA2", NF },
+ { 0x000F, "DEFPA (FDDI PCI)", NF },
+ { 0x0014, "DC21041 10Mb/s Ethernet Plus", NF },
+ { 0x0019, "DC21142 10/100 Mb/s Ethernet", NF },
+ { 0x0021, "DC21052", NF },
+ { 0x0024, "DC21152", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1013, "Cirrus Logic", {
+ { 0x0038, "GD 7548", NF },
+ { 0x00A0, "GD 5430", NF },
+ { 0x00A4, "GD 5434-4", NF },
+ { 0x00A8, "GD 5434-8", NF },
+ { 0x00AC, "GD 5436", NF },
+ { 0x00B8, "GD 5446", NF },
+ { 0x00BC, "GD 5480", NF },
+ { 0x00D0, "GD 5462", NF },
+ { 0x00D4, "GD 5464", NF },
+ { 0x00D6, "GD 5465", NF },
+ { 0x1100, "CL 6729", NF },
+ { 0x1110, "CL 6832", NF },
+ { 0x1200, "GD 7542", NF },
+ { 0x1202, "GD 7543", NF },
+ { 0x1204, "GD 7541", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1014, "IBM", {
+ { 0x000A, "Fire Coral", NF },
+ { 0x0018, "Token Ring", NF },
+ { 0x001D, "82G2675", NF },
+ { 0x0022, "82351 pci-pci bridge", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x101A, "NCR", {
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x101C, "WD*", {
+ { 0x3296, "WD 7197", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1022, "AMD", {
+ { 0x2000, "79C970 Lance", NF },
+ { 0x2020, "53C974 SCSI", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1023, "Trident", {
+ { 0x9320, "TGUI 9320", NF },
+ { 0x9420, "TGUI 9420", NF },
+ { 0x9440, "TGUI 9440", NF },
+ { 0x9660, "TGUI 9660/9680/9682", NF },
+#if 0
+ { 0x9680, "TGUI 9680", NF },
+ { 0x9682, "TGUI 9682", NF },
+#endif
+ { 0x9388, "TGUI 9388", NF },
+ { 0x9397, "TGUI 9397", NF },
+ { 0x9750, "TGUI 9750", NF },
+ { 0x9850, "TGUI 9850", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1025, "ALI", {
+ { 0x1435, "M1435", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x102B, "Matrox", {
+ { 0x0518, "MGA-2 Atlas PX2085", NF },
+ { 0x0519, "MGA Millennium", NF },
+ { 0x051a, "MGA Mystique", NF },
+ { 0x051b, "MGA Millennium II", NF },
+ { 0x051f, "MGA Millennium II AGP", NF },
+ { 0x0520, "MGA Millennium G200 PCI", NF },
+ { 0x0521, "MGA Millennium G200 AGP", NF },
+ { 0x0D10, "MGA Impression", NF },
+ { 0x1000, "MGA Productiva G100 PCI", NF },
+ { 0x1001, "MGA Productiva G100 AGP", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x102C, "CT", {
+ { 0x00D8, "65545", NF },
+ { 0x00DC, "65548", NF },
+ { 0x00E0, "65550", NF },
+ { 0x00E4, "65554", NF },
+ { 0x00E5, "65555", NF },
+ { 0x00F4, "68554", NF },
+ { 0x00C0, "69000", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1031, "Miro", {
+ { 0x5601, "ZR36050", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1033, "NEC", {
+ { 0x0046, "PowerVR PCX2", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1036, "FD", {
+ { 0x0000, "TMC-18C30 (36C70)", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1039, "SIS", {
+ { 0x0001, "86C201", NF },
+ { 0x0002, "86C202", NF },
+ { 0x0008, "85C503", NF },
+ { 0x0205, "86C205", NF },
+ { 0x0406, "85C501", NF },
+ { 0x0496, "85C496", NF },
+ { 0x0601, "85C601", NF },
+ { 0x5107, "5107", NF },
+ { 0x5511, "85C5511", NF },
+ { 0x5513, "85C5513", NF },
+ { 0x5571, "5571", NF },
+ { 0x5597, "5597", NF },
+ { 0x7001, "7001", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x103C, "HP", {
+ { 0x1030, "J2585A", NF },
+ { 0x1031, "J2585B", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1042, "SMC/PCTECH", {
+ { 0x1000, "FDC 37C665/RZ1000", NF },
+ { 0x1001, "FDC /RZ1001", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1044, "DPT", {
+ { 0xA400, "SmartCache/Raid", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1045, "Opti", {
+ { 0xC178, "92C178", NF },
+ { 0xC557, "82C557 Viper-M", NF },
+ { 0xC558, "82C558 Viper-M ISA+IDE", NF },
+ { 0xC621, "82C621", NF },
+ { 0xC700, "82C700", NF },
+ { 0xC701, "82C701 FireStar Plus", NF },
+ { 0xC814, "82C814 Firebridge 1", NF },
+ { 0xC822, "82C822", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x104A, "SGS Thomson", {
+ { 0x0008, "STG2000", NF },
+ { 0x0009, "STG1764", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x104B, "BusLogic", {
+ { 0x0140, "946C 01", NF },
+ { 0x1040, "946C 10", NF },
+ { 0x8130, "FlashPoint", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x104C, "Texas Instruments", {
+ { 0x3d04, "3DLabs Permedia", NF },
+ { 0x3d07, "3DLabs Permedia 2", NF },
+ { 0xAC12, "PCI1130", NF },
+ { 0xAC15, "PCI1131", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x104E, "Oak", {
+ { 0x0107, "OTI107", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1050, "Windbond", {
+ { 0x0940, "89C940 NE2000-PCI", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1057, "Motorola", {
+ { 0x0001, "MPC105 Eagle", NF },
+ { 0x0002, "MPC105 Grackle", NF },
+ { 0x4801, "Raven", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x105A, "Promise", {
+ { 0x4D33, "IDE UltraDMA/33", NF },
+ { 0x5300, "DC5030", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x105D, "Number Nine", {
+ { 0x2309, "Imagine-128", print_i128 },
+ { 0x2339, "Imagine-128-II", print_i128 },
+ { 0x493D, "Imagine-128-T2R", print_i128 },
+ { 0x5348, "Imagine-128-T2R4", print_i128 },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1060, "UMC", {
+ { 0x0101, "UM8673F", NF },
+ { 0x673A, "UM8886BF", NF },
+ { 0x886A, "UM8886A", NF },
+ { 0x8881, "UM8881F", NF },
+ { 0x8886, "UM8886F", NF },
+ { 0x8891, "UM8891A", NF },
+ { 0x9017, "UM9017F", NF },
+ { 0xE886, "UM8886N", NF },
+ { 0xE891, "UM8891N", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1061, "X", {
+ { 0x0001, "ITT AGX016", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1066, "PICOP", {
+ { 0x0001, "PT86C52x Vesuvius", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1069, "Mylex", {
+ { 0x0010, "AccelRAID 250", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x106B, "Apple", {
+ { 0x0001, "Bandit", NF },
+ { 0x0002, "Grand Central", NF },
+ { 0x000E, "Hydra", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1074, "Nexgen", {
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1077, "QLogic", {
+ { 0x1020, "ISP1020", NF },
+ { 0x1022, "ISP1022", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1078, "Cyrix", {
+ { 0x0000, "5510", NF },
+ { 0x0001, "PCI Master", NF },
+ { 0x0002, "5520", NF },
+ { 0x0100, "5530 Kahlua Legacy", NF },
+ { 0x0101, "5530 Kahlua SMI", NF },
+ { 0x0102, "5530 Kahlua IDE", NF },
+ { 0x0103, "5530 Kahlua Audio", NF },
+ { 0x0104, "5530 Kahlua Video", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x107D, "Leadtek", {
+ { 0x0000, "S3 805", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1080, "Contaq", {
+ { 0x0600, "82C599", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1083, "FOREX", {
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x108D, "Olicom", {
+ { 0x0001, "OC-3136", NF },
+ { 0x0011, "OC-2315", NF },
+ { 0x0012, "OC-2325", NF },
+ { 0x0013, "OC-2183", NF },
+ { 0x0014, "OC-2326", NF },
+ { 0x0021, "OC-6151", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x108E, "Sun", {
+ { 0x1000, "EBUS", NF },
+ { 0x1001, "Happy Meal", NF },
+ { 0x5000, "Simba Bus Module", NF },
+ { 0x8000, "PCI Bus Module", NF },
+ { 0xa000, "Sabre Bus Module", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1095, "CMD", {
+ { 0x0640, "640A", NF },
+ { 0x0643, "643", NF },
+ { 0x0646, "646", NF },
+ { 0x0670, "670", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1098, "Vision", {
+ { 0x0001, "QD 8500", NF },
+ { 0x0002, "QD 8580", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x109E, "Brooktree", {
+ { 0x0350, "Bt848", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10A8, "Sierra", {
+ { 0x0000, "STB Horizon 64", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10AA, "ACC", {
+ { 0x0000, "2056", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10AD, "Winbond", {
+ { 0x0001, "W83769F", NF },
+ { 0x0105, "SL82C105", NF },
+ { 0x0565, "W83C553", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10B3, "Databook", {
+ { 0xB106, "DB87144", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10B7, "3COM", {
+ { 0x5900, "3C590 10bT", NF },
+ { 0x5950, "3C595 100bTX", NF },
+ { 0x5951, "3C595 100bT4", NF },
+ { 0x5952, "3C595 10b-MII", NF },
+ { 0x9000, "3C900 10bTPO", NF },
+ { 0x9001, "3C900 10b Combo", NF },
+ { 0x9050, "3C905 100bTX", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10B8, "SMC", {
+ { 0x0005, "9432 TX", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10B9, "ALI", {
+ { 0x1445, "M1445", NF },
+ { 0x1449, "M1449", NF },
+ { 0x1451, "M1451", NF },
+ { 0x1461, "M1461", NF },
+ { 0x1489, "M1489", NF },
+ { 0x1511, "M1511", NF },
+ { 0x1513, "M1513", NF },
+ { 0x1521, "M1521", NF },
+ { 0x1523, "M1523", NF },
+ { 0x1531, "M1531 Aladdin IV", NF },
+ { 0x1533, "M1533 Aladdin IV", NF },
+ { 0x5215, "M4803", NF },
+ { 0x5219, "M5219", NF },
+ { 0x5229, "M5229 TXpro", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10BA, "Mitsubishi", {
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10BD, "Surecom", {
+ { 0x0E34, "NE-34PCI Lan", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10C8, "Neomagic", {
+ { 0x0001, "Magicgraph NM2070", NF },
+ { 0x0002, "Magicgraph 128V", NF },
+ { 0x0003, "Magicgraph 128ZV", NF },
+ { 0x0004, "Magicgraph NM2160", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10CD, "Advanced System Products", {
+ { 0x1200, "ABP940", NF },
+ { 0x1300, "ABP940U", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10DC, "CERN", {
+ { 0x0001, "STAR/RD24 SCI-PCI (PMC)", NF },
+ { 0x0002, "STAR/RD24 SCI-PCI (PMC)", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10DE, "NVidia", {
+ { 0x0008, "NV1", NF },
+ { 0x0009, "DAC64", NF },
+ { 0x0020, "Riva TNT", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10E0, "IMS", {
+ { 0x8849, "8849", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10E1, "Tekram", {
+ { 0x690C, "DC690C", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10E3, "Tundra", {
+ { 0x0000, "CA91C042 Universe", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10E8, "AMCC", {
+ { 0x8043, "Myrinet PCI (M2-PCI-32)", NF },
+ { 0x807D, "S5933 PCI44", NF },
+ { 0x809C, "S5933 Traquair HEPC3", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10EA, "Intergraphics", {
+ { 0x1680, "IGA-1680", NF },
+ { 0x1682, "IGA-1682", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10EC, "Realtek", {
+ { 0x8029, "8029", NF },
+ { 0x8129, "8129", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x10FA, "Truevision", {
+ { 0x000C, "Targa 1000", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1101, "Initio Corp", {
+ { 0x9100, "320 P", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1106, "VIA", {
+ { 0x0505, "VT 82C505", NF },
+ { 0x0561, "VT 82C505", NF },
+ { 0x0576, "VT 82C576 3V", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1119, "Vortex", {
+ { 0x0001, "GDT 6000b", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x111A, "EF", {
+ { 0x0000, "155P-MF1", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1127, "Fore Systems", {
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x112F, "Imaging Technology", {
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x113C, "PLX", {
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1142, "Alliance", {
+ { 0x3210, "ProMotion 6410", NF },
+ { 0x6422, "ProMotion 6422", NF },
+ { 0x6424, "ProMotion AT24", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x114A, "VMIC", {
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x114F, "DIGI*", {
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1159, "Mutech", {
+ { 0x0001, "MV1000", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1163, "Rendition", {
+ { 0x0001, "V1000", NF },
+ { 0x2000, "V2100", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1179, "Toshiba", {
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1193, "Zeinet", {
+ { 0x0001, "1221", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x11CB, "Specialix", {
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x11FE, "Control", {
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x120E, "Cyclades", {
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x121A, "3Dfx Interactive", {
+ { 0x0001, "Voodoo Graphics", NF },
+ { 0x0003, "Banshee", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1236, "Sigma Designs", {
+ { 0x6401, "REALmagic64/GX (SD 6425)", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1281, "YOKOGAWA", {
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1292, "TriTech Microelectronics", {
+ { 0xfc02, "Pyramid3D TR25202", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x12D2, "NVidia/SGS-Thomson", {
+ { 0x0018, "Riva128", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1C1C, "Symphony", {
+ { 0x0001, "82C101", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1DE1, "Tekram", {
+ { 0xDC29, "DC290", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x3D3D, "3Dlabs", {
+ { 0x0001, "GLINT 300SX", NF },
+ { 0x0002, "GLINT 500TX", NF },
+ { 0x0003, "GLINT Delta", NF },
+ { 0x0004, "GLINT Permedia", NF },
+ { 0x0006, "GLINT MX", NF },
+ { 0x0007, "GLINT Permedia 2", NF },
+ { 0x0008, "GLINT Gamma", NF },
+ { 0x0009, "GLINT Permedia 2v", NF },
+ { 0x0000, (char *)NULL, NF } } } ,
+ { 0x4005, "Avance", {
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x5333, "S3", {
+ { 0x0551, "Plato/PX", NF },
+ { 0x5631, "ViRGE", NF },
+ { 0x8811, "Trio32/64", NF },
+ { 0x8812, "Aurora64V+", NF },
+ { 0x8814, "Trio64UV+", NF },
+ { 0x883D, "ViRGE/VX", NF },
+ { 0x8880, "868", NF },
+ { 0x88B0, "928", NF },
+ { 0x88C0, "864-0", NF },
+ { 0x88C1, "864-1", NF },
+ { 0x88D0, "964-0", NF },
+ { 0x88D1, "964-1", NF },
+ { 0x88F0, "968", NF },
+ { 0x8901, "Trio64V2/DX or /GX", NF },
+ { 0x8902, "PLATO/PX", NF },
+ { 0x8904, "Trio3D", NF },
+ { 0x8A01, "ViRGE/DX or /GX", NF },
+ { 0x8A10, "ViRGE/GX2", NF },
+ { 0x8A20, "Savage3D (86E391)", NF },
+ { 0x8A21, "Savage3D (86E390)", NF },
+ { 0x8C01, "ViRGE/MX", NF },
+ { 0x8C02, "ViRGE/MX+", NF },
+ { 0x8C03, "ViRGE/MX+MV", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x8086, "Intel", {
+ { 0x0482, "82375EB pci-eisa bridge", NF },
+ { 0x0483, "82424ZX cache dram controller", NF },
+ { 0x0484, "82378IB/ZB pci-isa bridge", NF },
+ { 0x0486, "82430ZX Aries", NF },
+ { 0x04A3, "82434LX/NX pci cache mem controller", NF },
+ { 0x0960, "960RD processor/bridge", NF },
+ { 0x1230, "82371 bus-master IDE controller", NF },
+ { 0x1223, "SAA7116", NF },
+ { 0x1229, "82557/8 10/100MBit network controller",NF},
+ { 0x122D, "82437 Triton", NF },
+ { 0x122E, "82471 Triton", NF },
+ { 0x1230, "82438", NF },
+ { 0x1250, "82439", NF },
+ { 0x7000, "82371 pci-isa bridge", NF },
+ { 0x7010, "82371 bus-master IDE controller", NF },
+ { 0x7100, "82439 TX", NF },
+ { 0x7110, "82371AB PIIX4 ISA", NF },
+ { 0x7111, "82371AB PIIX4 IDE", NF },
+ { 0x7112, "82371AB PIIX4 USB", NF },
+ { 0x7113, "82371AB PIIX4 ACPI", NF },
+ { 0x7180, "82443LX PAC Host", NF },
+ { 0x7181, "82443LX PAC AGP", NF },
+ { 0x7190, "82443BX Host", NF },
+ { 0x7191, "82443BX AGP", NF },
+ { 0x7192, "82443BX Host (no AGP)", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x9004, "Adaptec", {
+ { 0x0010, "2940U2", NF },
+ { 0x1078, "7810", NF },
+ { 0x5078, "7850", NF },
+ { 0x5578, "7855", NF },
+ { 0x6078, "7860", NF },
+ { 0x6178, "2940AU", NF },
+ { 0x7078, "7870", NF },
+ { 0x7178, "2940", NF },
+ { 0x7278, "7872", NF },
+ { 0x7378, "398X", NF },
+ { 0x7478, "2944", NF },
+ { 0x7895, "7895", NF },
+ { 0x8078, "7880", NF },
+ { 0x8178, "2940U/UW", NF },
+ { 0x8278, "3940U/UW", NF },
+ { 0x8378, "389XU", NF },
+ { 0x8478, "2944U", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x9005, "Adaptec", {
+ { 0x001F, "7890/7891", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x907F, "Atronics", {
+ { 0x2015, "IDE-2015PL", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0xEDD8, "ARK Logic", {
+ { 0xA091, "1000PV", NF },
+ { 0xA099, "2000PV", NF },
+ { 0xA0A1, "2000MT", NF },
+ { 0xA0A9, "2000MI", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x1274, "Ensoniq", {
+ { 0x5000, "AudioPCI", NF },
+ { 0x0000, (char *)NULL, NF } } },
+ { 0x0000, (char *)NULL, {
+ { 0x0000, (char *)NULL, NF } } }
+};
+
+#if defined(__alpha__) || defined(__sparc__)
+#define PCI_EN 0x00000000
+#else
+#define PCI_EN 0x80000000
+#endif
+
+#define PCI_MODE1_ADDRESS_REG 0xCF8
+#define PCI_MODE1_DATA_REG 0xCFC
+
+#define PCI_MODE2_ENABLE_REG 0xCF8
+#ifdef PC98
+#define PCI_MODE2_FORWARD_REG 0xCF9
+#else
+#define PCI_MODE2_FORWARD_REG 0xCFA
+#endif
+
+
+main(int argc, unsigned char *argv[])
+{
+ unsigned long tmplong1, tmplong2, config_cmd;
+ unsigned char tmp1, tmp2;
+ unsigned int idx;
+ struct pci_config_reg pcr;
+ int ch, verbose = 0, do_mode1_scan = 0, do_mode2_scan = 0;
+ int func, hostbridges=0;
+
+ while((ch = getopt(argc, argv, "v12")) != EOF) {
+ switch((char)ch) {
+ case '1':
+ do_mode1_scan = 1;
+ break;
+ case '2':
+ do_mode2_scan = 1;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ default :
+ printf("Usage: %s [-v12] \n", argv[0]);
+ exit(1);
+ }
+ }
+#if !defined(MSDOS)
+ if (getuid()) {
+ printf("This program must be run as root\n");
+ exit(1);
+ }
+#endif
+
+#if defined(DGUX)
+ printf("Scanpci for Intel ix86 DG/ux R4.20MU04...MUxx\n\n");
+#endif
+
+ enable_os_io();
+
+#if !defined(__alpha__) && !defined(__powerpc__) && !defined(__sparc__)
+ pcr._configtype = 0;
+
+ outb(PCI_MODE2_ENABLE_REG, 0x00);
+ outb(PCI_MODE2_FORWARD_REG, 0x00);
+ tmp1 = inb(PCI_MODE2_ENABLE_REG);
+ tmp2 = inb(PCI_MODE2_FORWARD_REG);
+ if ((tmp1 == 0x00) && (tmp2 == 0x00)) {
+ pcr._configtype = 2;
+ printf("PCI says configuration type 2\n");
+ } else {
+ tmplong1 = inl(PCI_MODE1_ADDRESS_REG);
+ outl(PCI_MODE1_ADDRESS_REG, PCI_EN);
+ tmplong2 = inl(PCI_MODE1_ADDRESS_REG);
+ outl(PCI_MODE1_ADDRESS_REG, tmplong1);
+ if (tmplong2 == PCI_EN) {
+ pcr._configtype = 1;
+ printf("PCI says configuration type 1\n");
+ } else {
+ printf("No PCI !\n");
+ disable_os_io();
+ exit(1);
+ }
+ }
+#else
+ pcr._configtype = 1;
+#endif
+
+ /* Try pci config 1 probe first */
+
+ if ((pcr._configtype == 1) || do_mode1_scan) {
+ printf("\nPCI probing configuration type 1\n");
+
+ pcr._ioaddr = 0xFFFF;
+
+ pcr._pcibuses[0] = 0;
+ pcr._pcinumbus = 1;
+ pcr._pcibusidx = 0;
+ idx = 0;
+
+ do {
+ printf("Probing for devices on PCI bus %d:\n\n", pcr._pcibusidx);
+
+ for (pcr._cardnum = 0x0; pcr._cardnum < MAX_DEV_PER_VENDOR_CFG1;
+ pcr._cardnum += 0x1) {
+ func = 0;
+ do { /* loop over the different functions, if present */
+#if !defined(__alpha__) && !defined(__powerpc__) && !defined(__sparc__)
+ config_cmd = PCI_EN | (pcr._pcibuses[pcr._pcibusidx]<<16) |
+ (pcr._cardnum<<11) | (func<<8);
+
+ outl(PCI_MODE1_ADDRESS_REG, config_cmd); /* ioreg 0 */
+ pcr._device_vendor = inl(PCI_MODE1_DATA_REG);
+#else
+ pciconfig_read(pcr._pcibuses[pcr._pcibusidx], (pcr._cardnum<<3)|func,
+ PCI_ID_REG, 4, &pcr._device_vendor);
+#endif
+
+ if ((pcr._vendor == 0xFFFF) || (pcr._device == 0xFFFF))
+ break; /* nothing there */
+
+ printf("\npci bus 0x%x cardnum 0x%02x function 0x%04x: vendor 0x%04x device 0x%04x\n",
+ pcr._pcibuses[pcr._pcibusidx], pcr._cardnum, func,
+ pcr._vendor, pcr._device);
+
+#if !defined(__alpha__) && !defined(__powerpc__) && !defined(__sparc__)
+ outl(PCI_MODE1_ADDRESS_REG, config_cmd | 0x04);
+ pcr._status_command = inl(PCI_MODE1_DATA_REG);
+ outl(PCI_MODE1_ADDRESS_REG, config_cmd | 0x08);
+ pcr._class_revision = inl(PCI_MODE1_DATA_REG);
+ outl(PCI_MODE1_ADDRESS_REG, config_cmd | 0x0C);
+ pcr._bist_header_latency_cache = inl(PCI_MODE1_DATA_REG);
+ outl(PCI_MODE1_ADDRESS_REG, config_cmd | 0x10);
+ pcr._base0 = inl(PCI_MODE1_DATA_REG);
+ outl(PCI_MODE1_ADDRESS_REG, config_cmd | 0x14);
+ pcr._base1 = inl(PCI_MODE1_DATA_REG);
+ outl(PCI_MODE1_ADDRESS_REG, config_cmd | 0x18);
+ pcr._base2 = inl(PCI_MODE1_DATA_REG);
+ outl(PCI_MODE1_ADDRESS_REG, config_cmd | 0x1C);
+ pcr._base3 = inl(PCI_MODE1_DATA_REG);
+ outl(PCI_MODE1_ADDRESS_REG, config_cmd | 0x20);
+ pcr._base4 = inl(PCI_MODE1_DATA_REG);
+ outl(PCI_MODE1_ADDRESS_REG, config_cmd | 0x24);
+ pcr._base5 = inl(PCI_MODE1_DATA_REG);
+ outl(PCI_MODE1_ADDRESS_REG, config_cmd | 0x2c);
+ pcr._subsys_card_vendor = inl(PCI_MODE1_DATA_REG);
+ outl(PCI_MODE1_ADDRESS_REG, config_cmd | 0x30);
+ pcr._baserom = inl(PCI_MODE1_DATA_REG);
+ outl(PCI_MODE1_ADDRESS_REG, config_cmd | 0x3C);
+ pcr._max_min_ipin_iline = inl(PCI_MODE1_DATA_REG);
+ outl(PCI_MODE1_ADDRESS_REG, config_cmd | 0x40);
+ pcr._user_config = inl(PCI_MODE1_DATA_REG);
+#else
+ pciconfig_read(pcr._pcibuses[pcr._pcibusidx], (pcr._cardnum<<3)|func,
+ PCI_CMD_STAT_REG, 4, &pcr._status_command);
+ pciconfig_read(pcr._pcibuses[pcr._pcibusidx], (pcr._cardnum<<3)|func,
+ PCI_CLASS_REG, 4, &pcr._class_revision);
+ pciconfig_read(pcr._pcibuses[pcr._pcibusidx], (pcr._cardnum<<3)|func,
+ PCI_HEADER_MISC, 4, &pcr._bist_header_latency_cache);
+ pciconfig_read(pcr._pcibuses[pcr._pcibusidx], (pcr._cardnum<<3)|func,
+ PCI_MAP_REG_START, 4, &pcr._base0);
+ pciconfig_read(pcr._pcibuses[pcr._pcibusidx], (pcr._cardnum<<3)|func,
+ PCI_MAP_REG_START + 0x04, 4, &pcr._base1);
+ pciconfig_read(pcr._pcibuses[pcr._pcibusidx], (pcr._cardnum<<3)|func,
+ PCI_MAP_REG_START + 0x08, 4, &pcr._base2);
+ pciconfig_read(pcr._pcibuses[pcr._pcibusidx], (pcr._cardnum<<3)|func,
+ PCI_MAP_REG_START + 0x0C, 4, &pcr._base3);
+ pciconfig_read(pcr._pcibuses[pcr._pcibusidx], (pcr._cardnum<<3)|func,
+ PCI_MAP_REG_START + 0x10, 4, &pcr._base4);
+ pciconfig_read(pcr._pcibuses[pcr._pcibusidx], (pcr._cardnum<<3)|func,
+ PCI_MAP_REG_START + 0x14, 4, &pcr._base5);
+ pciconfig_read(pcr._pcibuses[pcr._pcibusidx], (pcr._cardnum<<3)|func,
+ PCI_MAP_REG_START + 0x1c, 4, &pcr._subsys_card_vendor);
+ pciconfig_read(pcr._pcibuses[pcr._pcibusidx], (pcr._cardnum<<3)|func,
+ PCI_MAP_ROM_REG, 4, &pcr._baserom);
+ pciconfig_read(pcr._pcibuses[pcr._pcibusidx], (pcr._cardnum<<3)|func,
+ PCI_INTERRUPT_REG, 4, &pcr._max_min_ipin_iline);
+ pciconfig_read(pcr._pcibuses[pcr._pcibusidx], (pcr._cardnum<<3)|func,
+ PCI_REG_USERCONFIG, 4, &pcr._user_config);
+#endif
+
+ /* check for pci-pci bridges */
+#define PCI_CLASS_MASK 0xff000000
+#define PCI_SUBCLASS_MASK 0x00ff0000
+#define PCI_CLASS_BRIDGE 0x06000000
+#define PCI_SUBCLASS_BRIDGE_PCI 0x00040000
+ switch(pcr._class_revision & (PCI_CLASS_MASK|PCI_SUBCLASS_MASK)) {
+ case PCI_CLASS_BRIDGE|PCI_SUBCLASS_BRIDGE_PCI:
+ if (pcr._secondary_bus_number > 0) {
+ pcr._pcibuses[pcr._pcinumbus++] = pcr._secondary_bus_number;
+ }
+ break;
+ case PCI_CLASS_BRIDGE:
+ if ( ++hostbridges > 1) {
+ pcr._pcibuses[pcr._pcinumbus] = pcr._pcinumbus;
+ pcr._pcinumbus++;
+ }
+ break;
+ default:
+ break;
+ }
+ if((func==0) && ((pcr._header_type & PCI_MULTIFUNC_DEV) == 0)) {
+ /* not a multi function device */
+ func = 8;
+ } else {
+ func++;
+ }
+
+ if (idx++ >= MAX_PCI_DEVICES)
+ continue;
+
+ identify_card(&pcr, verbose);
+ } while( func < 8 );
+ }
+ } while (++pcr._pcibusidx < pcr._pcinumbus);
+ }
+
+#if !defined(__alpha__) && !defined(__powerpc__) && !defined(__sparc__)
+ /* Now try pci config 2 probe (deprecated) */
+
+ if ((pcr._configtype == 2) || do_mode2_scan) {
+ outb(PCI_MODE2_ENABLE_REG, 0xF1);
+ outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */
+
+ printf("\nPCI probing configuration type 2\n");
+
+ pcr._pcibuses[0] = 0;
+ pcr._pcinumbus = 1;
+ pcr._pcibusidx = 0;
+ idx = 0;
+
+ do {
+ for (pcr._ioaddr = 0xC000; pcr._ioaddr < 0xD000; pcr._ioaddr += 0x0100){
+ outb(PCI_MODE2_FORWARD_REG, pcr._pcibuses[pcr._pcibusidx]); /* bus 0 for now */
+ pcr._device_vendor = inl(pcr._ioaddr);
+ outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */
+
+ if ((pcr._vendor == 0xFFFF) || (pcr._device == 0xFFFF))
+ continue;
+ if ((pcr._vendor == 0xF0F0) || (pcr._device == 0xF0F0))
+ continue; /* catch ASUS P55TP4XE motherboards */
+
+ printf("\npci bus 0x%x slot at 0x%04x, vendor 0x%04x device 0x%04x\n",
+ pcr._pcibuses[pcr._pcibusidx], pcr._ioaddr, pcr._vendor,
+ pcr._device);
+
+ outb(PCI_MODE2_FORWARD_REG, pcr._pcibuses[pcr._pcibusidx]); /* bus 0 for now */
+ pcr._status_command = inl(pcr._ioaddr + 0x04);
+ pcr._class_revision = inl(pcr._ioaddr + 0x08);
+ pcr._bist_header_latency_cache = inl(pcr._ioaddr + 0x0C);
+ pcr._base0 = inl(pcr._ioaddr + 0x10);
+ pcr._base1 = inl(pcr._ioaddr + 0x14);
+ pcr._base2 = inl(pcr._ioaddr + 0x18);
+ pcr._base3 = inl(pcr._ioaddr + 0x1C);
+ pcr._base4 = inl(pcr._ioaddr + 0x20);
+ pcr._base5 = inl(pcr._ioaddr + 0x24);
+ pcr._subsys_card_vendor = inl(pcr._ioaddr + 0x2c);
+ pcr._baserom = inl(pcr._ioaddr + 0x30);
+ pcr._max_min_ipin_iline = inl(pcr._ioaddr + 0x3C);
+ pcr._user_config = inl(pcr._ioaddr + 0x40);
+ outb(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */
+
+ /* check for pci-pci bridges (currently we only know Digital) */
+ if ((pcr._vendor == 0x1011) && (pcr._device == 0x0001))
+ if (pcr._secondary_bus_number > 0)
+ pcr._pcibuses[pcr._pcinumbus++] = pcr._secondary_bus_number;
+
+ if (idx++ >= MAX_PCI_DEVICES)
+ continue;
+
+ identify_card(&pcr, verbose);
+ }
+ } while (++pcr._pcibusidx < pcr._pcinumbus);
+
+ outb(PCI_MODE2_ENABLE_REG, 0x00);
+ }
+
+#endif /* __alpha__ */
+
+ disable_os_io();
+}
+
+
+void
+identify_card(struct pci_config_reg *pcr, int verbose)
+{
+
+ int i = 0, j, foundit = 0;
+
+ while (pvd[i].vendorname != (char *)NULL) {
+ if (pvd[i].vendor_id == pcr->_vendor) {
+ j = 0;
+ printf(" %s ", pvd[i].vendorname);
+ while (pvd[i].device[j].devicename != (char *)NULL) {
+ if (pvd[i].device[j].device_id == pcr->_device) {
+ printf("%s", pvd[i].device[j].devicename);
+ foundit = 1;
+ break;
+ }
+ j++;
+ }
+ }
+ if (foundit)
+ break;
+ i++;
+ }
+
+ if (!foundit)
+ printf(" Device unknown\n");
+ else {
+ printf("\n");
+ if (verbose) {
+ if (pvd[i].device[j].print_func != (void (*)())NULL) {
+ pvd[i].device[j].print_func(pcr);
+ return;
+ }
+ }
+ }
+
+ if (verbose) {
+ printf(" CardVendor 0x%04x card 0x%04x\n",
+ pcr->_subsys_vendor, pcr->_subsys_card);
+ if (pcr->_status_command)
+ printf(" STATUS 0x%04x COMMAND 0x%04x\n",
+ pcr->_status, pcr->_command);
+ if (pcr->_class_revision)
+ printf(" CLASS 0x%02x 0x%02x 0x%02x REVISION 0x%02x\n",
+ pcr->_base_class, pcr->_sub_class, pcr->_prog_if,
+ pcr->_rev_id);
+ switch (pcr->_class_revision & PCI_CLASS_MASK) {
+ case PCI_CLASS_BRIDGE:
+ switch (pcr->_class_revision & PCI_SUBCLASS_MASK) {
+ case PCI_SUBCLASS_BRIDGE_PCI:
+ print_bridge_pci_class(pcr);
+ break;
+ default:
+ print_bridge_class(pcr);
+ break;
+ }
+ break;
+ default:
+ print_default_class(pcr);
+ break;
+ }
+ }
+}
+
+void
+print_default_class(struct pci_config_reg *pcr)
+{
+ if (pcr->_bist_header_latency_cache)
+ printf(" BIST 0x%02x HEADER 0x%02x LATENCY 0x%02x CACHE 0x%02x\n",
+ pcr->_bist, pcr->_header_type, pcr->_latency_timer,
+ pcr->_cache_line_size);
+ if (pcr->_base0)
+ printf(" BASE0 0x%08x addr 0x%08x %s\n",
+ pcr->_base0, pcr->_base0 & (pcr->_base0 & 0x1 ?
+ 0xFFFFFFFC : 0xFFFFFFF0),
+ pcr->_base0 & 0x1 ? "I/O" : "MEM");
+ if (pcr->_base1)
+ printf(" BASE1 0x%08x addr 0x%08x %s\n",
+ pcr->_base1, pcr->_base1 & (pcr->_base1 & 0x1 ?
+ 0xFFFFFFFC : 0xFFFFFFF0),
+ pcr->_base1 & 0x1 ? "I/O" : "MEM");
+ if (pcr->_base2)
+ printf(" BASE2 0x%08x addr 0x%08x %s\n",
+ pcr->_base2, pcr->_base2 & (pcr->_base2 & 0x1 ?
+ 0xFFFFFFFC : 0xFFFFFFF0),
+ pcr->_base2 & 0x1 ? "I/O" : "MEM");
+ if (pcr->_base3)
+ printf(" BASE3 0x%08x addr 0x%08x %s\n",
+ pcr->_base3, pcr->_base3 & (pcr->_base3 & 0x1 ?
+ 0xFFFFFFFC : 0xFFFFFFF0),
+ pcr->_base3 & 0x1 ? "I/O" : "MEM");
+ if (pcr->_base4)
+ printf(" BASE4 0x%08x addr 0x%08x %s\n",
+ pcr->_base4, pcr->_base4 & (pcr->_base4 & 0x1 ?
+ 0xFFFFFFFC : 0xFFFFFFF0),
+ pcr->_base4 & 0x1 ? "I/O" : "MEM");
+ if (pcr->_base5)
+ printf(" BASE5 0x%08x addr 0x%08x %s\n",
+ pcr->_base5, pcr->_base5 & (pcr->_base5 & 0x1 ?
+ 0xFFFFFFFC : 0xFFFFFFF0),
+ pcr->_base5 & 0x1 ? "I/O" : "MEM");
+ if (pcr->_baserom)
+ printf(" BASEROM 0x%08x addr 0x%08x %sdecode-enabled\n",
+ pcr->_baserom, pcr->_baserom & 0xFFFF8000,
+ pcr->_baserom & 0x1 ? "" : "not-");
+ if (pcr->_max_min_ipin_iline)
+ printf(" MAX_LAT 0x%02x MIN_GNT 0x%02x INT_PIN 0x%02x INT_LINE 0x%02x\n",
+ pcr->_max_lat, pcr->_min_gnt,
+ pcr->_int_pin, pcr->_int_line);
+ if (pcr->_user_config)
+ printf(" BYTE_0 0x%02x BYTE_1 0x%02x BYTE_2 0x%02x BYTE_3 0x%02x\n",
+ pcr->_user_config_0, pcr->_user_config_1,
+ pcr->_user_config_2, pcr->_user_config_3);
+}
+
+#define PCI_B_FAST_B_B 0x80
+#define PCI_B_SB_RESET 0x40
+#define PCI_B_M_ABORT 0x20
+#define PCI_B_VGA_EN 0x08
+#define PCI_B_ISA_EN 0x04
+#define PCI_B_P_ERR 0x01
+void
+print_bridge_pci_class(struct pci_config_reg *pcr)
+{
+ if (pcr->_bist_header_latency_cache)
+ printf(" HEADER 0x%02x LATENCY 0x%02x\n",
+ pcr->_header_type, pcr->_latency_timer);
+ printf(" PRIBUS 0x%02x SECBUS 0x%02x SUBBUS 0x%02x SECLT 0x%02x\n",
+ pcr->_primary_bus_number, pcr->_secondary_bus_number,
+ pcr->_subordinate_bus_number, pcr->_secondary_latency_timer);
+ printf(" IOBASE 0x%02x IOLIM 0x%02x SECSTATUS 0x%04x\n",
+ pcr->_io_base << 8, (pcr->_io_limit << 8) | 0xfff,
+ pcr->_secondary_status);
+ printf(" NOPREFETCH_MEMBASE 0x%08x MEMLIM 0x%08x\n",
+ pcr->_mem_base << 16, (pcr->_mem_limit << 16) | 0xfffff);
+ printf(" PREFETCH_MEMBASE 0x%08x MEMLIM 0x%08x\n",
+ pcr->_prefetch_mem_base << 16,
+ (pcr->_prefetch_mem_limit << 16) | 0xfffff);
+ printf(" %sFAST_B2B %sSEC_BUS_RST %sM_ABRT %sVGA_EN %sISA_EN"
+ " %sPERR_EN\n",
+ (pcr->_b_ctrl & PCI_B_FAST_B_B) ? "" : "NO_",
+ (pcr->_b_ctrl & PCI_B_SB_RESET) ? "" : "NO_",
+ (pcr->_b_ctrl & PCI_B_M_ABORT) ? "" : "NO_",
+ (pcr->_b_ctrl & PCI_B_VGA_EN) ? "" : "NO_",
+ (pcr->_b_ctrl & PCI_B_ISA_EN) ? "" : "NO_",
+ (pcr->_b_ctrl & PCI_B_P_ERR) ? "" : "NO_");
+}
+
+void
+print_bridge_class(struct pci_config_reg *pcr)
+{
+ if (pcr->_bist_header_latency_cache)
+ printf(" HEADER 0x%02x LATENCY 0x%02x\n",
+ pcr->_header_type, pcr->_latency_timer);
+}
+
+
+void
+print_mach64(struct pci_config_reg *pcr)
+{
+ unsigned long sparse_io = 0;
+
+ if (pcr->_status_command)
+ printf(" STATUS 0x%04x COMMAND 0x%04x\n",
+ pcr->_status, pcr->_command);
+ if (pcr->_class_revision)
+ printf(" CLASS 0x%02x 0x%02x 0x%02x REVISION 0x%02x\n",
+ pcr->_base_class, pcr->_sub_class, pcr->_prog_if, pcr->_rev_id);
+ if (pcr->_bist_header_latency_cache)
+ printf(" BIST 0x%02x HEADER 0x%02x LATENCY 0x%02x CACHE 0x%02x\n",
+ pcr->_bist, pcr->_header_type, pcr->_latency_timer,
+ pcr->_cache_line_size);
+ if (pcr->_base0)
+ printf(" APBASE 0x%08x addr 0x%08x\n",
+ pcr->_base0, pcr->_base0 & (pcr->_base0 & 0x1 ?
+ 0xFFFFFFFC : 0xFFFFFFF0));
+ if (pcr->_base1)
+ printf(" BLOCKIO 0x%08x addr 0x%08x\n",
+ pcr->_base1, pcr->_base1 & (pcr->_base1 & 0x1 ?
+ 0xFFFFFFFC : 0xFFFFFFF0));
+ if (pcr->_base2)
+ printf(" REGBASE 0x%08x addr 0x%08x\n",
+ pcr->_base2, pcr->_base2 & (pcr->_base2 & 0x1 ?
+ 0xFFFFFFFC : 0xFFFFFFF0));
+ if (pcr->_baserom)
+ printf(" BASEROM 0x%08x addr 0x%08x %sdecode-enabled\n",
+ pcr->_baserom, pcr->_baserom & 0xFFFF8000,
+ pcr->_baserom & 0x1 ? "" : "not-");
+ if (pcr->_max_min_ipin_iline)
+ printf(" MAX_LAT 0x%02x MIN_GNT 0x%02x INT_PIN 0x%02x INT_LINE 0x%02x\n",
+ pcr->_max_lat, pcr->_min_gnt, pcr->_int_pin, pcr->_int_line);
+ switch (pcr->_user_config_0 & 0x03) {
+ case 0:
+ sparse_io = 0x2ec;
+ break;
+ case 1:
+ sparse_io = 0x1cc;
+ break;
+ case 2:
+ sparse_io = 0x1c8;
+ break;
+ }
+ printf(" SPARSEIO 0x%03x %s %s\n",
+ sparse_io, pcr->_user_config_0 & 0x04 ? "Block IO enabled" :
+ "Sparse IO enabled",
+ pcr->_user_config_0 & 0x08 ? "Disable 0x46E8" : "Enable 0x46E8");
+}
+
+void
+print_i128(struct pci_config_reg *pcr)
+{
+ if (pcr->_status_command)
+ printf(" STATUS 0x%04x COMMAND 0x%04x\n",
+ pcr->_status, pcr->_command);
+ if (pcr->_class_revision)
+ printf(" CLASS 0x%02x 0x%02x 0x%02x REVISION 0x%02x\n",
+ pcr->_base_class, pcr->_sub_class, pcr->_prog_if, pcr->_rev_id);
+ if (pcr->_bist_header_latency_cache)
+ printf(" BIST 0x%02x HEADER 0x%02x LATENCY 0x%02x CACHE 0x%02x\n",
+ pcr->_bist, pcr->_header_type, pcr->_latency_timer,
+ pcr->_cache_line_size);
+ printf(" MW0_AD 0x%08x addr 0x%08x %spre-fetchable\n",
+ pcr->_base0, pcr->_base0 & 0xFFC00000,
+ pcr->_base0 & 0x8 ? "" : "not-");
+ printf(" MW1_AD 0x%08x addr 0x%08x %spre-fetchable\n",
+ pcr->_base1, pcr->_base1 & 0xFFC00000,
+ pcr->_base1 & 0x8 ? "" : "not-");
+ printf(" XYW_AD(A) 0x%08x addr 0x%08x\n",
+ pcr->_base2, pcr->_base2 & 0xFFC00000);
+ printf(" XYW_AD(B) 0x%08x addr 0x%08x\n",
+ pcr->_base3, pcr->_base3 & 0xFFC00000);
+ printf(" RBASE_G 0x%08x addr 0x%08x\n",
+ pcr->_base4, pcr->_base4 & 0xFFFF0000);
+ printf(" IO 0x%08x addr 0x%08x\n",
+ pcr->_base5, pcr->_base5 & 0xFFFFFF00);
+ printf(" RBASE_E 0x%08x addr 0x%08x %sdecode-enabled\n",
+ pcr->_baserom, pcr->_baserom & 0xFFFF8000,
+ pcr->_baserom & 0x1 ? "" : "not-");
+ if (pcr->_max_min_ipin_iline)
+ printf(" MAX_LAT 0x%02x MIN_GNT 0x%02x INT_PIN 0x%02x INT_LINE 0x%02x\n",
+ pcr->_max_lat, pcr->_min_gnt, pcr->_int_pin, pcr->_int_line);
+}
+
+void
+print_pcibridge(struct pci_config_reg *pcr)
+{
+ if (pcr->_status_command)
+ printf(" STATUS 0x%04x COMMAND 0x%04x\n",
+ pcr->_status, pcr->_command);
+ if (pcr->_class_revision)
+ printf(" CLASS 0x%02x 0x%02x 0x%02x REVISION 0x%02x\n",
+ pcr->_base_class, pcr->_sub_class, pcr->_prog_if, pcr->_rev_id);
+ if (pcr->_bist_header_latency_cache)
+ printf(" BIST 0x%02x HEADER 0x%02x LATENCY 0x%02x CACHE 0x%02x\n",
+ pcr->_bist, pcr->_header_type, pcr->_latency_timer,
+ pcr->_cache_line_size);
+ printf(" PRIBUS 0x%02x SECBUS 0x%02x SUBBUS 0x%02x SECLT 0x%02x\n",
+ pcr->_primary_bus_number, pcr->_secondary_bus_number,
+ pcr->_subordinate_bus_number, pcr->_secondary_latency_timer);
+ printf(" IOBASE 0x%02x IOLIM 0x%02x SECSTATUS 0x%04x\n",
+ pcr->_io_base << 8, (pcr->_io_limit << 8) | 0xfff,
+ pcr->_secondary_status);
+ printf(" NOPREFETCH_MEMBASE 0x%08x MEMLIM 0x%08x\n",
+ pcr->_mem_base << 16, (pcr->_mem_limit << 16) | 0xfffff);
+ printf(" PREFETCH_MEMBASE 0x%08x MEMLIM 0x%08x\n",
+ pcr->_prefetch_mem_base << 16,
+ (pcr->_prefetch_mem_limit << 16) | 0xfffff);
+ printf(" RBASE_E 0x%08x addr 0x%08x %sdecode-enabled\n",
+ pcr->_baserom, pcr->_baserom & 0xFFFF8000,
+ pcr->_baserom & 0x1 ? "" : "not-");
+ if (pcr->_max_min_ipin_iline)
+ printf(" MAX_LAT 0x%02x MIN_GNT 0x%02x INT_PIN 0x%02x INT_LINE 0x%02x\n",
+ pcr->_max_lat, pcr->_min_gnt, pcr->_int_pin, pcr->_int_line);
+}
+
+static int io_fd;
+#ifdef __EMX__
+USHORT callgate[3] = {0,0,0};
+#endif
+
+void
+enable_os_io()
+{
+#if (defined(SVR4) || defined(SCO) || defined(ISC)) && !defined(DGUX)
+#if defined(SI86IOPL)
+ sysi86(SI86IOPL, 3);
+#else
+ sysi86(SI86V86, V86SC_IOPL, PS_IOPL);
+#endif
+#endif
+#if defined(linux) && !defined(__sparc__)
+ iopl(3);
+#endif
+#if defined(__FreeBSD__) || defined(__386BSD__) || defined(__bsdi__) || defined(DGUX)
+ if ((io_fd = open("/dev/console", O_RDWR, 0)) < 0) {
+ perror("/dev/console");
+ exit(1);
+ }
+#if defined(__FreeBSD__) || defined(__386BSD__) || defined(DGUX)
+ if (ioctl(io_fd, KDENABIO, 0) < 0) {
+ perror("ioctl(KDENABIO)");
+ exit(1);
+ }
+#endif
+#if defined(__bsdi__)
+ if (ioctl(io_fd, PCCONENABIOPL, 0) < 0) {
+ perror("ioctl(PCCONENABIOPL)");
+ exit(1);
+ }
+#endif
+#endif
+#if defined(__NetBSD__)
+#if !defined(USE_I386_IOPL)
+ if ((io_fd = open("/dev/io", O_RDWR, 0)) < 0) {
+ perror("/dev/io");
+ exit(1);
+ }
+#else
+ if (i386_iopl(1) < 0) {
+ perror("i386_iopl");
+ exit(1);
+ }
+#endif /* USE_I386_IOPL */
+#endif /* __NetBSD__ */
+#if defined(__OpenBSD__)
+ if (i386_iopl(1) < 0) {
+ perror("i386_iopl");
+ exit(1);
+ }
+#endif /* __OpenBSD__ */
+#if defined(MACH386)
+ if ((io_fd = open("/dev/iopl", O_RDWR, 0)) < 0) {
+ perror("/dev/iopl");
+ exit(1);
+ }
+#endif
+#ifdef __EMX__
+ {
+ HFILE hfd;
+ ULONG dlen,action;
+ APIRET rc;
+ static char *ioDrvPath = "/dev/fastio$";
+
+ if (DosOpen((PSZ)ioDrvPath, (PHFILE)&hfd, (PULONG)&action,
+ (ULONG)0, FILE_SYSTEM, FILE_OPEN,
+ OPEN_SHARE_DENYNONE|OPEN_FLAGS_NOINHERIT|OPEN_ACCESS_READONLY,
+ (ULONG)0) != 0) {
+ fprintf(stderr,"Error opening fastio$ driver...\n");
+ fprintf(stderr,"Please install xf86sup.sys in config.sys!\n");
+ exit(42);
+ }
+ callgate[0] = callgate[1] = 0;
+
+/* Get callgate from driver for fast io to ports and other stuff */
+
+ rc = DosDevIOCtl(hfd, (ULONG)0x76, (ULONG)0x64,
+ NULL, 0, NULL,
+ (ULONG*)&callgate[2], sizeof(USHORT), &dlen);
+ if (rc) {
+ fprintf(stderr,"xf86-OS/2: EnableIOPorts failed, rc=%d, dlen=%d; emergency exit\n",
+ rc,dlen);
+ DosClose(hfd);
+ exit(42);
+ }
+
+/* Calling callgate with function 13 sets IOPL for the program */
+
+ asm volatile ("movl $13,%%ebx;.byte 0xff,0x1d;.long _callgate"
+ : /*no outputs */
+ : /*no inputs */
+ : "eax","ebx","ecx","edx","cc");
+
+ DosClose(hfd);
+ }
+#endif
+#if defined(Lynx) && defined(__powerpc__)
+ pciConfBase = (unsigned char *) smem_create("PCI-CONF",
+ (char *)0x80800000, 64*1024, SM_READ|SM_WRITE);
+ if (pciConfBase == (void *) -1)
+ exit(1);
+#endif
+}
+
+
+void
+disable_os_io()
+{
+#if (defined(SVR4) || defined(SCO) || defined(ISC)) && !defined(DGUX)
+#if defined(SI86IOPL)
+ sysi86(SI86IOPL, 0);
+#else
+ sysi86(SI86V86, V86SC_IOPL, 0);
+#endif
+#endif
+#if defined(linux) && !defined(__sparc__)
+ iopl(0);
+#endif
+#if defined(__FreeBSD__) || defined(__386BSD__) || defined(DGUX)
+ if (ioctl(io_fd, KDDISABIO, 0) < 0) {
+ perror("ioctl(KDDISABIO)");
+ close(io_fd);
+ exit(1);
+ }
+ close(io_fd);
+#endif
+#if defined(__NetBSD__)
+#if !defined(USE_I386_IOPL)
+ close(io_fd);
+#else
+ if (i386_iopl(0) < 0) {
+ perror("i386_iopl");
+ exit(1);
+ }
+#endif /* NetBSD1_1 */
+#endif /* __NetBSD__ */
+#if defined(__bsdi__)
+ if (ioctl(io_fd, PCCONDISABIOPL, 0) < 0) {
+ perror("ioctl(PCCONDISABIOPL)");
+ close(io_fd);
+ exit(1);
+ }
+ close(io_fd);
+#endif
+#if defined(MACH386)
+ close(io_fd);
+#endif
+#if defined(Lynx) && defined(__powerpc__)
+ smem_create(NULL, (char *) pciConfBase, 0, SM_DETACH);
+ smem_remove("PCI-CONF");
+ pciConfBase = NULL;
+#endif
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/etc/sp.node b/xc/programs/Xserver/hw/xfree86/etc/sp.node
new file mode 100644
index 000000000..d3b4d3e62
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/sp.node
@@ -0,0 +1 @@
+clone spx c sp
diff --git a/xc/programs/Xserver/hw/xfree86/etc/sp.sdevice b/xc/programs/Xserver/hw/xfree86/etc/sp.sdevice
new file mode 100644
index 000000000..3ac680aff
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/sp.sdevice
@@ -0,0 +1 @@
+sp Y 1 0 0 0 0 0 0 0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/sun.tcap b/xc/programs/Xserver/hw/xfree86/etc/sun.tcap
new file mode 100644
index 000000000..5616672ae
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/sun.tcap
@@ -0,0 +1,32 @@
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/sun.tcap,v 3.3 1996/12/23 06:47:19 dawes Exp $
+#
+#
+#
+#
+# $XConsortium: sun.tcap /main/3 1996/02/21 17:48:19 kaleb $
+#
+Mu|sun|Sun Microsystems Workstation console:\
+ :am:bs:km:mi:ms:pt:li#34:co#80:cl=^L:cm=\E[%i%d;%dH:\
+ :ce=\E[K:cd=\E[J:so=\E[7m:se=\E[m:rs=\E[s:\
+ :al=\E[L:dl=\E[M:im=:ei=:ic=\E[@:dc=\E[P:\
+ :up=\E[A:nd=\E[C:ku=\E[A:kd=\E[B:kr=\E[C:kl=\E[D:\
+ :k1=\E[224z:k2=\E[225z:k3=\E[226z:k4=\E[227z:k5=\E[228z:\
+ :k6=\E[229z:k7=\E[230z:k8=\E[231z:k9=\E[232z:\
+
+M+|sun-cmd|Sun Microsystems Workstation console with scrollable history:\
+ :te=\E[>4h:ti=\E[>4l:tc=sun:\
+
+M-|sun-e|sun-nic|sune|Sun Microsystems Workstation without insert character:\
+ :ic@:im@:ei@:tc=sun:
+Mu|sun-s|Sun Microsystems Workstation window with status line:\
+ :hs:ts=\E]l:fs=\E\\:ds=\E]l\E\\:tc=sun:
+Mu|sun-e-s|sun-s-e|Sun Microsystems Workstation with status hacked for emacs:\
+ :hs:ts=\E]l:fs=\E\\:ds=\E]l\E\\:tc=sun-e:
+M0|sun-48|Sun 48-line window:\
+ :li#48:co#80:tc=sun:
+M1|sun-34|Sun 34-line window:\
+ :li#34:co#80:tc=sun:
+M2|sun-24|Sun 24-line window:\
+ :li#24:co#80:tc=sun:
+M3|sun-17|Sun 17-line window:\
+ :li#17:co#80:tc=sun:
diff --git a/xc/programs/Xserver/hw/xfree86/etc/sun.tinfo b/xc/programs/Xserver/hw/xfree86/etc/sun.tinfo
new file mode 100644
index 000000000..9e4744405
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/sun.tinfo
@@ -0,0 +1,56 @@
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/sun.tinfo,v 3.3 1996/12/23 06:47:20 dawes Exp $
+#
+#
+#
+#
+# $XConsortium: sun.tinfo /main/3 1996/02/21 17:48:23 kaleb $
+#
+sun|Sun Microsystems Workstation console,
+ am, km, mir, msgr, xon,
+ cols#80, lines#34,
+ bel=^G, clear=\f, cr=\r, cub1=\b, cud1=\n, cuf1=\E[C,
+ cup=\E[%i%p1%d;%p2%dH, cuu1=\E[A, dch1=\E[P, dl1=\E[M,
+ ed=\E[J, el=\E[K, ht=\t, ich1=\E[@, il1=\E[L, ind=\n,
+ kcub1=\E[D, kcud1=\E[B, kcuf1=\E[C, kcuu1=\E[A,
+ kf1=\E[224z, kf2=\E[225z, kf3=\E[226z, kf4=\E[227z,
+ kf5=\E[228z, kf6=\E[229z, kf7=\E[230z, kf8=\E[231z,
+ kf9=\E[232z, rmso=\E[m, rs2=\E[s, smso=\E[7m,
+
+sun-cmd|Sun Microsystems Workstation console with scrollable history,
+ rmcup=\E[>4h, smcup=\E[>4l,
+ use=sun,
+
+sun-e|sun-nic|sune|Sun Microsystems Workstation without insert character,
+ ich1@,
+ use=sun,
+sun|Sun Microsystems Workstation console,
+ am, km, mir, msgr, xon,
+ cols#80, lines#34,
+ bel=^G, clear=\f, cr=\r, cub1=\b, cud1=\n, cuf1=\E[C,
+ cup=\E[%i%p1%d;%p2%dH, cuu1=\E[A, dch1=\E[P, dl1=\E[M,
+ ed=\E[J, el=\E[K, ht=\t, ich1=\E[@, il1=\E[L, ind=\n,
+ kcub1=\E[D, kcud1=\E[B, kcuf1=\E[C, kcuu1=\E[A,
+ kf1=\E[224z, kf2=\E[225z, kf3=\E[226z, kf4=\E[227z,
+ kf5=\E[228z, kf6=\E[229z, kf7=\E[230z, kf8=\E[231z,
+ kf9=\E[232z, rmso=\E[m, rs2=\E[s, smso=\E[7m,
+sun|Sun Microsystems Workstation console,
+ am, km, mir, msgr, xon,
+ cols#80, lines#34,
+ bel=^G, clear=\f, cr=\r, cub1=\b, cud1=\n, cuf1=\E[C,
+ cup=\E[%i%p1%d;%p2%dH, cuu1=\E[A, dch1=\E[P, dl1=\E[M,
+ ed=\E[J, el=\E[K, ht=\t, ich1=\E[@, il1=\E[L, ind=\n,
+ kcub1=\E[D, kcud1=\E[B, kcuf1=\E[C, kcuu1=\E[A,
+ kf1=\E[224z, kf2=\E[225z, kf3=\E[226z, kf4=\E[227z,
+ kf5=\E[228z, kf6=\E[229z, kf7=\E[230z, kf8=\E[231z,
+ kf9=\E[232z, rmso=\E[m, rs2=\E[s, smso=\E[7m,
+sun-48|Sun 48-line window,
+ lines#48,
+ use=sun,
+sun-34|Sun 34-line window,
+ use=sun,
+sun-24|Sun 24-line window,
+ lines#24,
+ use=sun,
+sun-17|Sun 17-line window,
+ lines#17,
+ use=sun,
diff --git a/xc/programs/Xserver/hw/xfree86/etc/svr3_patch b/xc/programs/Xserver/hw/xfree86/etc/svr3_patch
new file mode 100644
index 000000000..6b2f3c8b9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/svr3_patch
@@ -0,0 +1,863 @@
+#!/bin/sh
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/svr3_patch,v 3.2 1996/12/23 06:47:21 dawes Exp $
+#
+# Apply patch to kernel to prevent losing IOPL on signals.
+#
+# Version 1.0 - 10/8/93
+# adapted for svr3 by Steve Forsythe (forsse@meaddata.com) from initial
+# svr4 version by David Wexelblat (dwex@goblin.org, dwex@aib.com)
+#
+# $XConsortium: svr3_patch /main/4 1996/02/21 17:48:28 kaleb $
+#
+
+PATH=/bin:/usr/bin:/usr/local/bin
+
+N=`basename $0`
+
+#
+# Make sure we're running on SVR3!
+#
+uname -r | grep '3.2' > /dev/null
+if [ "$?" != "0" ]
+then
+ echo "$N: This only applies to SVR3!"
+ exit 1
+fi
+
+#
+# Next make sure we are running as root
+#
+id | grep 'uid=0' > /dev/null
+if [ "$?" != "0" ]
+then
+ echo "$N: Must be run as root!"
+ exit 1
+fi
+
+#
+# Now make temp directory
+#
+TMPDIR=/tmp/xf86_pt.$$
+mkdir ${TMPDIR}
+if [ ! -d ${TMPDIR} ]
+then
+ echo "$N: Failed to make temp directory"
+ exit 1
+fi
+
+#
+# Go to temp directory
+#
+OWD=${PWD}
+cd ${TMPDIR}
+
+#
+# Checksums for programs
+#
+CHECKER_SUM="52302 7 checker"
+PATCHER_SUM="39651 17 patcher"
+
+#
+# Extract programs
+#
+cat > checker.uu <<\!EOF!
+begin 775 checker
+M3`$'`"O#M"P``````````!P`#P$+`0``T`(``"P$````````K`$``$@!```8
+M!$``+G1E>'0```!(`0``2`$``-`"``!(`0``````````````````(````"YD
+M871A````&`1``!@$0``L!```&`0``````````````````$`````N8G-S````
+M`$0(0`!$"$````````````````````````````"`````+F9K83`P,`````"@
+M````H)A+````````````````````````(@```"YF:V$P-#````!`H```0*`H
+M!@```````````````````````$(````N8V]M;65N=```````````N@0``$0(
+M`````````````````````@``+FQI8@`````!`````````!@```#^#```````
+M``````````````@``%6+[%93:@"0QP4T`$"@Y`,``,<%,`!`H$0(0`#'!3@`
+M0*`8!$``D)"+](O<@SPD`'0=D)"#PP2#.P!U^.L1D)"0D)"0D)"0D(/#_(L#
+M_]`[WG7UC67X6UZ+Y5W#:@"0D,.0D)"#[`B+[(M%"(U4A1")%1@$0`!2C54,
+M4E#H?____VH`Z#`!``"#Q`3H<````(/$#%#HYP$``&H`N`$```":``````<`
+M],.0D)!5B^R+Y5W#B_2+W(,\)`!T%I"0D(/#!(,[`'7XZPF0D(/#_(L#_]`[
+MWG7UC67X6UZ+Y5W#58OLZPN0D)"0D)"0D)"0D(OE7<.0D)"0D)"0D)"0D)!5
+MB^R#[`1H*`(``&H0Z!C__Y^#Q`AH`#```&H$:D?H@0```(/$#&A@$@``Z%``
+M``"#Q`2)1?QJ$.AD``"@B\!0Z&W^_Y^#Q`AH8!(``.@N````@\0$B47\:@#H
+M(0$``(/$!)"0D)"0D)"0D)"0D)"0B^5=PY"0D)"0D)"0D)"0D%6+[(/L"(M5
+M"(E5^&:+3?B+T>R)1?R+1?SK!9"0D)"0B^5=P[@R````F@`````'``^"#/W_
+MG\.058OL@>R$`@``5U:^_____X-]"`!U,6@D!D``Z++]_Y]9A<")10AT"8M%
+M"(H`A,!U%H`](`9```!T!C/`7E_)P\=%""T&0`#&!2`&0```:#,&0`"-18!0
+MZ#3^_Y^#Q`C_=0B-18Y0Z"7^_Y^#Q`AJ`(U%@%#HL_W_GX/$"(7`B_A\/F@"
+M`@``C85^_?__4%?HL?W_GX/$##T"`@``=1MH`@(``(V%?OW__U!H'`1``.AI
+M_?^?@\0,,_97Z*7\_Y]9B\9>7\G#D)#H%P```(M4)`2X`0```)H`````!P`/
+M@B?\_Y_#PY"0D+A$!D``BT@$B]'!X@*#P@CC"(/J!/\T`N+X_Q#,Z^&058OL
+M5E.0D)#_____````````````("`@("`@("`@*"@H*"@@("`@("`@("`@("`@
+M("`@("!($!`0$!`0$!`0$!`0$!`0A(2$A(2$A(2$A!`0$!`0$!"!@8&!@8$!
+M`0$!`0$!`0$!`0$!`0$!`0$!`1`0$!`0$(*"@H*"@@("`@("`@("`@("`@("
+M`@("`@("$!`0$"``````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````0(#!`4&!P@)"@L,#0X/$!$2$Q05%A<8&1H;'!T>'R`A(B,D)28G
+M*"DJ*RPM+B\P,3(S-#4V-S@Y.CL\/3X_0&%B8V1E9F=H:6IK;&UN;W!Q<G-T
+M=79W>'EZ6UQ=7E]@04)#1$5&1TA)2DM,34Y/4%%24U155E=865I[?'U^?P``
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```````````````````````````````````````````````````!````0TA2
+M0TQ!4U,`87-C:6D`+VQI8B]C:')C;&%S<R\`````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`$`H(RD@<V0Z8W)T,2YO("`S.#8O:7@@5F5R<VEO;B`R+C`N,```0"@C*71Y
+M<&5S+F@),BXS("T@.#@O,#4O,C<`0"@C*7!A<F%M+F@),BXS("T@.#@O,#4O
+M,C<`0"@C*7,U<&%R86TN:`DR+C,@+2`X."\P-2\R-P!`*",I:6UM=2YH"3(N
+M,R`M(#@X+S`U+S(W`$`H(RER96=I;VXN:`DR+C,@+2`X."\P-2\R-P!`*",I
+M<')O8RYH"3(N,R`M(#@X+S`U+S(W`$`H(RES>7-I.#8N:`DR+C8@+2`X."\Q
+M,"\P-`!`*",I='-S+F@),BXS("T@.#@O,#4O,C<`0"@C*78X-BYH"3(N-"`M
+M(#@X+S`X+S$P`$`H(RES:6=N86PN:`DR+C,@+2`X."\P-2\R-P!`*",I<VEG
+M;F%L+F@),BXS("T@.#@O,#4O,C<`0"@C*7-T9&EO+F@),BXS("T@.#@O,#4O
+M,C<`0"@C*6QI8F,M:3,X-CIL:6)C+6DS.#8O<WES+W-Y<VDX-BYS"3$N,@``
+M``!`*",I8W1Y<&4N8PDS+C,@+2`X."\P-2\R-P!`*",I9F-N=&PN:`DR+C,@
+M+2`X."\P-2\R-P!`*",I9F-N=&PN:`DR+C,@+2`X."\P-2\R-P!`*",I8W1Y
+M<&4N:`DR+C,@+2`X."\P-2\R-P!`*",I;&EB8RUI,S@V.FQI8F,M:3,X-B]S
+M>7,O8VQO<V4N<PDQ+C(`0"@C*6=E=&5N=BYC"3,N,R`M(#@X+S`U+S(W`$`H
+M(RES:&QI8BYH"3,N,R`M(#@X+S`U+S(W``!`*",I;&EB8RUI,S@V.FQI8F,M
+M:3,X-B]G96XO;65M8W!Y+G,),2XR`````$`H(REL:6)C+6DS.#8Z;&EB8RUI
+M,S@V+W-Y<R]O<&5N+G,),2XR``!`*",I;&EB8RUI,S@V.FQI8F,M:3,X-B]S
+M>7,O<F5A9"YS"3$N,@``0"@C*6QI8F,M:3,X-CIL:6)C+6DS.#8O9V5N+W-T
+M<F-P>2YS"3$N,@````!`*",I;&EB8RUI,S@V.FQI8F,M:3,X-B]S>7,O<VEG
+M;F%L+G,),2XS`````$`H(REL:6)C+6DS.#8Z;&EB8RUI,S@V+W-Y<R]K:6QL
+M+G,),2XR``!`*",I;&EB8RUI,S@V.FQI8F,M:3,X-B]S>7,O9V5T<&ED+G,)
+M,2XR`````$`H(REL:6)C+6DS.#8Z;&EB8RUI,S@V+V-R="]C97)R;W(N<PDQ
+M+C(`````0"@C*6=E;E]D968N8PDS+C,@+2`X."\P-2\R-P````!`*",I<W!E
+M8PDR+C,@+2`X."\P-2\R-P!`*",I;&EB8RUI,S@V.FQI8F,M:3,X-B]G96XO
+M8W5E>&ET+G,),2XR`````$`H(REL:6)C+6DS.#8Z;&EB8RUI,S@V+V=E;B]F
+M86MC=2YS"3$N,@!`*",I;&EB8RUI,S@V.FQI8F,M:3,X-B]G96XO:3,X-E]D
+M871A+G,),2XR`$`H(RD@<V0Z;&EB9RYA("`S.#8O:7@@5F5R<VEO;B`R+C`N
+M,```0"@C*2!S9#IC<G1N+F\@(#,X-B]I>"!697)S:6]N(#(N,"XP```&````
+4`@```"]S:&QI8B]L:6)C7W,````X
+`
+end
+!EOF!
+uudecode checker.uu
+rm -f checker.uu
+if [ "`sum checker`" != "${CHECKER_SUM}" ]
+then
+ echo "$N: Program 'checker' extracted incorrectly!"
+ cd ${OWD}
+ rm -fr ${BKUP}
+ exit 1
+fi
+chmod 700 checker
+
+cat > patcher.uu <<\!EOF!
+begin 775 patcher
+M3`$'`'_#M"P``````````!P`#P$+`0``F`@``-P*``#X"0``%`(``$@!``#@
+M"4``+G1E>'0```!(`0``2`$``)@(``!(`0``````````````````(````"YD
+M871A````X`E``.`)0`#<"@``X`D``````````````````$`````N8G-S````
+M`+P40`"\%$``^`D```````````````````````"`````+F9K83`P,`````"@
+M````H)A+````````````````````````(@```"YF:V$P-#````!`H```0*`H
+M!@```````````````````````$(````N8V]M;65N=```````````Y@L``+P4
+M`````````````````````@``+FQI8@`````!`````````!@```"B(```````
+M``````````````@``%6+[%93:@"0QP4$`$"@U`M``)"0QP48`$"@O!1``,<%
+M'`!`H,080`#'!2``0*#,'$``QP4D`$"@_`U``,<%*`!`H+P10`#'!2P`0*#`
+M$4``QP4T`$"@#P``H,<%,`!`H+0>0`#'!3@`0*#@"4``D)#'!0@`0*`)`0"@
+MD)#'!1``0*"J``"@QP44`$"@M!)``(OTB]R#/"0`=!V0D(/#!(,[`'7XZQ&0
+MD)"0D)"0D)"0@\/\BP/_T#O>=?6-9?A;7HOE7<-J`)"0PY"0D(/L"(OLBT4(
+MC52%$(D5X`E``%*-50Q24.@7____:@#HE`8``(/$!.A0````@\0,4.A+!P``
+M:@"X`0```)H`````!P#TPY"0D%6+[(OE7<.+](O<@SPD`'06D)"0@\,$@SL`
+M=?CK"9"0@\/\BP/_T#O>=?6-9?A;7HOE7<-5B^R![)````!3QX5\____````
+M`,>%>/___P````!H,`I``(M=#%.+70A3Z!?^_Y^#Q`R+P(O0B56`@_K_#X3]
+M````BT6`/6,```!T,SUC````?Q@]/P````^$H0```.G,````D)"0D)"0D)`]
+M=0```'1-Z;@```"0D)"0D)"0D(.]>/___P!T)XM%#(L84V@S"D``:!P.0`#H
+M:/W_GX/$#&H!Z%P&``"#Q`20D)"0D,>%?/___P$```#K=)"0D)"#O7S___\`
+M=">+10R+&%-H4PI``&@<#D``Z"C]_Y^#Q`QJ`>@<!@``@\0$D)"0D)#'A7C_
+M__\!````ZS20D)"0BT4,BQA3:',*0`!H'`Y``.CQ_/^?@\0,:@'HY04``(/$
+M!)"0D)"0D)"0D)"0D)"0Z>G^__^0D)"0D)"0D)"0D(.]?/___P!U%XM%""L%
+M0`!`H#T"````=2?K!9"0D)"0@[U\____`'1'BT4(*P5``$"@/0$```!U!^LU
+MD)"0D)"+10R+&%-HFPI``&@<#D``Z''\_Y^#Q`QJ`>AE!0``@\0$D)"0D)"0
+MD)"0D)"0D)"A0`!`H(O0C025`````(M5#(L<`HE=]/\%0`!`H&H`BUWT4^C$
+M_/^?@\0(B\"+T(E5_(72?2J+'4P`0*!3BUWT4VC#"D``:!P.0`#H!OS_GX/$
+M$&H!Z/H$``"#Q`20D)"-1;Q0BUW\4^@1_/^?@\0(B\"%P'TJBQU,`$"@4XM=
+M]%-HX@I``&@<#D``Z,;[_Y^#Q!!J`>BZ!```@\0$D)"0BUW,B5W@BUW@4^@:
+M_/^?@\0$B46XBUW@4XM=N%.+7?Q3Z#_\_Y^#Q`R+P#E%X'0PBQU,`$"@4XM=
+M]%.+7>!3:`$+0`!H'`Y``.AH^_^?@\04:@'H7`0``(/$!)"0D)"0BUW\4^@;
+M^_^?@\0$QT7D`````(-]Y`$/AV,"``"+1>2+'(4@"D``B5W<BUW<4XM%Y(O(
+MB]'!X@0KT(O"`\*-D.0)0`!2C46$4.B/^_^?@\0,@[U\____`'4:@[UX____
+M`'41ZR.0D)"0D)"0D)"0D)"0D)"+1>2-582+V@,<A2@*0`"+P\8`_Y#'1>P`
+M````QT7H`````(M%Z#E%W'9QBT7L.47@=FF+1;@#1>R-582+R@--Z(H`.`%T
+M-8M%[$"+V"M=Z(E=[,=%Z`````"+1>PY1>!S"NL8D)"0D)"0D)#KQ9"0D)"0
+MD)"0D)"0D)"0BT7L0(O0B57LBT7H0(O0B57HZY.0D)"0D)"0D)"0D)"+1>@Y
+M1=P/A50!``"+7=PI7>R#O7S___\`=1V#O7C___\`=13IOP```)"0D)"0D)"0
+MD)"0D)"0D(M%Y(M5[`,4A2@*0`"+P@-%N(`X_W0I:/\```!H+`M``&@<#D``
+MZ./Y_Y^#Q`QJ`>C7`@``@\0$D)"0D)"0D)"#O7S___\`=!=J`.B\`@``@\0$
+MD)"0D)"0D)"0D)"0D(M%Y(M5[`,4A2@*0`"+P@-%N,8`SXM%Y(M5[`,4A2@*
+M0`"-0@%0:$8+0`#H&?K_GX/$".F@````D)"0D.F'````D)"0D)"0D)"0D)"0
+MD)"0BT7DBU7L`Q2%*`I``(O"`T6X@#C/="EHSP```&A*"T``:!P.0`#H,_G_
+MGX/$#&H!Z"<"``"#Q`20D)"0D)"0D(M%Y(M5[`,4A2@*0`"+P@-%N,8`_XM%
+MY(M5[`,4A2@*0`"-0@%0:&0+0`#HB?G_GX/$".L3D)"0BT7D0(O0B57DZ97]
+M__^0D(-]Y`)U*H.]?/___P!U$FAH"T``:!P.0`#HN/C_GX/$"&H!Z*P!``"#
+MQ`20D)"0D*%``$"@B]"-!)4`````BU4,BQP"B5WP:+8!``!H`@$``(M=\%/H
+M$OG_GX/$#(O`B]")5?B%TGTHBQU,`$"@4XM=\%-HB0M``&@<#D``Z%3X_Y^#
+MQ!!J`>A(`0``@\0$D(M=X%.+7;A3BUWX4^AK^?^?@\0,B\`Y1>!T-8L=3`!`
+MH%.+7?!3BUW@4VBH"T``:!P.0`#H#?C_GX/$%&H!Z`$!``"#Q`20D)"0D)"0
+MD)"0BUWX4^B[]_^?@\0$:@#HX0```(/$!)"0D)"0D)"0D)"+G6S___^+Y5W#
+MD)!5B^R![(0"``!75K[_____@WT(`'4Q:-P-0`#HYO?_GUF%P(E%"'0)BT4(
+MB@"$P'46@#W8#4```'0&,\!>7\G#QT4(Y0U``,8%V`U```!HZPU``(U%@%#H
+M:/C_GX/$"/]U"(U%CE#H6?C_GX/$"&H`C46`4.CG]_^?@\0(A<"+^'P^:`("
+M``"-A7[]__]05^CE]_^?@\0,/0("``!U&V@"`@``C85^_?__4&C4"T``Z)WW
+M_Y^#Q`PS]E?HV?;_GUF+QEY?R<.0D.AV]O^?BU0D!+@!````F@`````'``^"
+M6_;_G\.XO!)``(M(!(O1P>("@\((XPB#Z@3_-`+B^/\0S.OAD%6+[%93D)"0
+M_____P``````````BU0D!(%B0/_/__^!2D```@``````````````````@6=`
+M_\___X%/0``"``"!3SP$````````````````$@```!4````(````!````&-U
+M`"5S.B!O;FQY(&]N92!O9B`M8RP@+74@86QL;W=E9`H`)7,Z(&]N;'D@;VYE
+M(&]F("UC+"`M=2!A;&QO=V5D"@!U<V%G93H@)7,@6RUC('P@+75=(&EN+69I
+M;&4@6V]U="UF:6QE70H`=7-A9V4Z("5S(%LM8R!\("UU72!I;BUF:6QE(%MO
+M=70M9FEL95T*`&9A:6QE9"!T;R!O<&5N*"D@)7,L(&5R<FYO/25D"@!#;W5L
+M9"!N;W0@<W1A="@I("5S+"!E<G)N;STE9`H`9F%I;&5D('1O(')E860H*2`E
+M9"!B>71E<R!T;R`E<RP@97)R;F\])60*`#\_/R`P>"4P,G@@;F]T(&9O=6YD
+M(#\_/PH`)60*`#\_/R`P>"4P,G@@;F]T(&9O=6YD(#\_/PH`)60*`&1I9"!N
+M;W0@9FEN9"!A;GD@;6%T8V@@<W1R:6YG<R$*`&9A:6QE9"!T;R!O<&5N*"D@
+M)7,L(&5R<FYO/25D"@!F86EL960@=&\@=W)I=&4H*2`E9"!B>71E<R!T;R`E
+M<RP@97)R;F\])60*```@("`@("`@("`H*"@H*"`@("`@("`@("`@("`@("`@
+M($@0$!`0$!`0$!`0$!`0$!"$A(2$A(2$A(2$$!`0$!`0$(&!@8&!@0$!`0$!
+M`0$!`0$!`0$!`0$!`0$!$!`0$!`0@H*"@H*"`@("`@("`@("`@("`@("`@("
+M`@(0$!`0(```````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M```!`@,$!08'"`D*"PP-#@\0$1(3%!46%Q@9&AL<'1X?("$B(R0E)B<H*2HK
+M+"TN+S`Q,C,T-38W.#DZ.SP]/C]`86)C9&5F9VAI:FML;6YO<'%R<W1U=G=X
+M>7I;7%U>7V!!0D-$149'2$E*2TQ-3D]045)35%565UA96GM\?7Y_````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M``````````````````````````````````````````````$```!#2%)#3$%3
+M4P!A<V-I:0`O;&EB+V-H<F-L87-S+P````````````````````$`````````
+M```````````"`0```````-P<0`#<'$``!@(`````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````````+P10```
+M`````````.0<0```````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M`````````````````````````````````````````````````````````$`H
+M(RD@<V0Z8W)T,2YO("`S.#8O:7@@5F5R<VEO;B`R+C`N,```0"@C*7-T9&EO
+M+F@),BXS("T@.#@O,#4O,C<`0"@C*69C;G1L+F@),BXS("T@.#@O,#4O,C<`
+M0"@C*69C;G1L+F@),BXS("T@.#@O,#4O,C<`0"@C*71Y<&5S+F@),BXS("T@
+M.#@O,#4O,C<`0"@C*7-T870N:`DR+C,@+2`X."\P-2\R-P!`*",I97)R;F\N
+M:`DR+C,@+2`X."\P-2\R-P!`*",I97)R;F\N:`DR+C,@+2`X."\P-2\R-P!`
+M*",I;6%L;&]C+F@),BXS("T@.#@O,#4O,C<`0"@C*6=E=&]P="YC"3,N,R`M
+M(#@X+S`U+S(W`$`H(RES:&QI8BYH"3,N,R`M(#@X+S`U+S(W``!`*",I;W!T
+M7V1A=&$N8PDS+C,@+2`X."\P-2\R-P```$`H(REP<FEN=&8N8PDS+C,@+2`X
+M."\P-2\R-P!`*",I<VAL:6(N:`DS+C,@+2`X."\P-2\R-P!`*",I<W1D:6\N
+M:`DR+C,@+2`X."\P-2\R-P!`*",I=F%R87)G<RYH"3(N,R`M(#@X+S`U+S(W
+M``!`*",I9G!R:6YT9BYC"3,N,R`M(#@X+S`U+S(W`$`H(RES:&QI8BYH"3,N
+M,R`M(#@X+S`U+S(W`$`H(RES=&1I;RYH"3(N,R`M(#@X+S`U+S(W`$`H(REV
+M87)A<F=S+F@),BXS("T@.#@O,#4O,C<`0"@C*7-T<F-H<BYC"3,N,R`M(#@X
+M+S`U+S(W`$`H(REL:6)C+6DS.#8Z;&EB8RUI,S@V+V=E;B]S=')C;7`N<PDQ
+M+C(N,2XQ`````$`H(REM86QL;V,N8PDS+C,@+2`X."\P-2\R-P!`*",I<VAL
+M:6(N:`DS+C,@+2`X."\P-2\R-P!`*",I=F%L=65S+F@),BXS("T@.#@O,#4O
+M,C<`0"@C*6%S<V5R="YH"3(N,R`M(#@X+S`U+S(W``!`*",I;&EB8RUI,S@V
+M.FQI8F,M:3,X-B]S>7,O<V)R:RYS"3$N,P``0"@C*6QI8F,M:3,X-CIL:6)C
+M+6DS.#8O<WES+V9S=&%T+G,),2XR`$`H(RED;W!R;G0N8PDS+C,@+2`X."\P
+M-2\R-P!`*",I<VAL:6(N:`DS+C,@+2`X."\P-2\R-P!`*",I<W1D:6\N:`DR
+M+C,@+2`X."\P-2\R-P!`*",I8W1Y<&4N:`DR+C,@+2`X."\P-2\R-P!`*",I
+M=F%R87)G<RYH"3(N,R`M(#@X+S`U+S(W`$`H(REV86QU97,N:`DR+C,@+2`X
+M."\P-2\R-P!`*",I;F%N+F@),BXS("T@.#@O,#4O,C<`0"@C*7!R:6YT+F@)
+M,RXS("T@.#@O,#4O,C<```!`*",I8W1Y<&5?9&5F+F,),RXS("T@.#@O,#4O
+M,C<``$`H(RES<&5C"3(N,R`M(#@X+S`U+S(W`$`H(REC='EP92YC"3,N,R`M
+M(#@X+S`U+S(W`$`H(REF8VYT;"YH"3(N,R`M(#@X+S`U+S(W`$`H(REF8VYT
+M;"YH"3(N,R`M(#@X+S`U+S(W`$`H(REC='EP92YH"3(N,R`M(#@X+S`U+S(W
+M`$`H(REE8W9T+F,),RXS("T@.#@O,#4O,C<`0"@C*7-H;&EB+F@),RXS("T@
+M.#@O,#4O,C<`0"@C*6UA=&@N:`DR+C,@+2`X."\P-2\R-P!`*",I;F%N+F@)
+M,BXS("T@.#@O,#4O,C<`0"@C*79A;'5E<RYH"3(N,R`M(#@X+S`U+S(W`$`H
+M(RED=&]P+F,),RXS("T@.#@O,#4O,C<`0"@C*65R<FYO+F@),BXS("T@.#@O
+M,#4O,C<`0"@C*65R<FYO+F@),BXS("T@.#@O,#4O,C<`0"@C*6UA=&@N:`DR
+M+C,@+2`X."\P-2\R-P!`*",I=F%L=65S+F@),BXS("T@.#@O,#4O,C<```!`
+M*",I;&EB8RUI,S@V.F=E;B]B:6=L:71P;W<N<PDQ+C$```!`*",I9G)E>'`N
+M8PDS+C,@+2`X."\P-2\R-P!`*",I<VAL:6(N:`DS+C,@+2`X."\P-2\R-P!`
+M*",I;F%N+F@),BXS("T@.#@O,#4O,C<``$`H(REL:6)C+6DS.#8Z;&EB8RUI
+M,S@V+V-R="]F<')E86PN<PDQ+C$N,BXQ`````$`H(REF=W)I=&4N8PDS+C,@
+M+2`X."\P-2\R-P!`*",I<VAL:6(N:`DS+C,@+2`X."\P-2\R-P!`*",I<W1D
+M:6\N:`DR+C,@+2`X."\P-2\R-P!`*",I<W1D:6]M+F@),RXS("T@.#@O,#4O
+M,C<`0"@C*71Y<&5S+F@),BXS("T@.#@O,#4O,C<`````0"@C*69L<V)U9BYC
+M"3,N-"`M(#@X+S`X+S`Y`$`H(RES:&QI8BYH"3,N,R`M(#@X+S`U+S(W`$`H
+M(RES=&1I;RYH"3(N,R`M(#@X+S`U+S(W`$`H(RES=&1I;VTN:`DS+C,@+2`X
+M."\P-2\R-P!`*",I97)R;F\N:`DR+C,@+2`X."\P-2\R-P````!`*",I;&EB
+M8RUI,S@V.FQI8F,M:3,X-B]S>7,O8VQO<V4N<PDQ+C(`0"@C*6=E=&5N=BYC
+M"3,N,R`M(#@X+S`U+S(W`$`H(RES:&QI8BYH"3,N,R`M(#@X+S`U+S(W``!`
+M*",I:7-A='1Y+F,),RXS("T@.#@O,#4O,C<`0"@C*7-H;&EB+F@),RXS("T@
+M.#@O,#4O,C<`0"@C*71E<FUI;RYH"3(N-"`M(#@X+S$P+S$R``!`*",I;&EB
+M8RUI,S@V.FQI8F,M:3,X-B]G96XO:3,X-E]D871A+G,),2XR`$`H(REL:6)C
+M+6DS.#8Z;&EB8RUI,S@V+W-Y<R]I;V-T;"YS"3$N,@!`*",I;'1O<W1R+F,)
+M,RXS("T@.#@O,#4O,C<`0"@C*6UE;6-H<BYC"3,N,R`M(#@X+S`U+S(W`$`H
+M(REL:6)C+6DS.#8Z;&EB8RUI,S@V+V=E;B]M96UC<'DN<PDQ+C(`````0"@C
+M*6UE;7-E="YC"3,N,R`M(#@X+S`U+S(W`$`H(REL:6)C+6DS.#8Z;&EB8RUI
+M,S@V+W-Y<R]O<&5N+G,),2XR``!`*",I;&EB8RUI,S@V.FQI8F,M:3,X-B]S
+M>7,O<F5A9"YS"3$N,@``0"@C*7-T9&EO7V1E9BYC"3,N,R`M(#@X+S`U+S(W
+M`$`H(RES=&1I;RYH"3(N,R`M(#@X+S`U+S(W````0"@C*7-P96,),BXS("T@
+M.#@O,#4O,C<`0"@C*61A=&$N8PDS+C,@+2`X."\P-2\R-P!`*",I<W1D:6\N
+M:`DR+C,@+2`X."\P-2\R-P````!`*",I;&EB8RUI,S@V.FQI8F,M:3,X-B]G
+M96XO<W1R8W!Y+G,),2XR`````$`H(REL:6)C+6DS.#8Z;&EB8RUI,S@V+V=E
+M;B]S=')L96XN<PDQ+C(`````0"@C*6QI8F,M:3,X-CIL:6)C+6DS.#8O<WES
+M+W=R:71E+G,),2XR`$`H(REL:6)C+6DS.#8Z;&EB8RUI,S@V+V-R="]C97)R
+M;W(N<PDQ+C(`````0"@C*6=E;E]D968N8PDS+C,@+2`X."\P-2\R-P````!`
+M*",I<W!E8PDR+C,@+2`X."\P-2\R-P!`*",I;6%L;%]D968N8PDS+C,@+2`X
+M."\P-2\R-P```$`H(RES<&5C"3(N,R`M(#@X+S`U+S(W`$`H(REF<F5E7V1E
+M9BYC"3,N,R`M(#@X+S`U+S(W````0"@C*7-P96,),BXS("T@.#@O,#4O,C<`
+M0"@C*6QI8F,M:3,X-CIL:6)C+6DS.#8O9V5N+V-U97AI="YS"3$N,@````!`
+M*",I;&EB8RUI,S@V.FQI8F,M:3,X-B]G96XO;6%L;%]D871A+G,),2XR`$`H
+M(RD@<V0Z;&EB9RYA("`S.#8O:7@@5F5R<VEO;B`R+C`N,```0"@C*2!S9#IC
+M<G1N+F\@(#,X-B]I>"!697)S:6]N(#(N,"XP```&`````@```"]S:&QI8B]L
+(:6)C7W,````X
+`
+end
+!EOF!
+uudecode patcher.uu
+rm -f patcher.uu
+if [ "`sum patcher`" != "${PATCHER_SUM}" ]
+then
+ echo "$N: Program 'patcher' extracted incorrectly!"
+ cd ${OWD}
+ rm -fr ${BKUP}
+ exit 1
+fi
+chmod 700 patcher
+
+echo "$N: The programs we need have been extracted successfully"
+
+#
+# OK. Now we have the programs we need. Run checker to see if the patch
+# is needed.
+#
+rm -f core
+(./checker; exit $? ) > /dev/null 2>&1
+if [ "$?" != "0" ]
+then
+ if [ ! -f core ]
+ then
+ echo "$N: Check failed, but no core file??? Aborting."
+ cd ${OWD}
+ rm -fr ${TMPDIR}
+ exit 1
+ else
+ rm -f core
+ echo "$N: The bug exists. Will proceed with the patch"
+ fi
+else
+ echo "$N: Patch is not needed; bug not present."
+ cd ${OWD}
+ rm -fr ${TMPDIR}
+ exit 0
+fi
+
+#
+# OK. We need to do the patch. Make a directory in /etc/conf/pack.d/kernel
+# to hold our stuff (we'll store a backup os.o there, and put the programs
+# there, and their source as well).
+#
+PACK=/etc/conf/pack.d/kernel
+BKUP=${PACK}/.xfree86
+if [ -d ${BKUP} ]
+then
+ echo "$N: Backup directory ${BKUP} exists"
+ echo " but bug not fixed. Aborting"
+ cd ${OWD}
+ rm -fr ${TMPDIR}
+ exit 1
+fi
+
+mkdir ${BKUP}
+if [ ! -d ${BKUP} ]
+then
+ echo "$N: Failed to make backup directory ${BKUP}"
+ cd ${OWD}
+ rm -fr ${TMPDIR}
+ exit 1
+fi
+cp ${TMPDIR}/* ${BKUP}
+cd ${BKUP}
+rm -fr ${TMPDIR}
+./patcher -c ../os.o
+if [ "$?" = "0" ]
+then
+ echo "$N: Patch already applied, but bug not fixed. Aborting"
+ cd ${OWD}
+ rm -fr ${BKUP}
+ exit 1
+fi
+
+#
+# Stash the backup
+#
+cp ../os.o ./os.o.SAV
+echo "$N: A copy of os.o has been saved in ${BKUP}"
+LOC=`./patcher ../os.o ./Nos.o`
+if [ "$?" != "0" ]
+then
+ echo "$N: Patch failed!!!"
+ cd ${OWD}
+ rm -fr ${BKUP}
+ exit 1
+fi
+LOC1=`cmp -l ../os.o ./Nos.o | awk '{print $1; exit}'`
+if [ "$LOC" != "$LOC1" ]
+then
+ echo "$N: Patch sanity check failed!!!"
+ cd ${OWD}
+ rm -fr ${BKUP}
+ exit 1
+fi
+echo "$N: Patch successfully applied. Installing it."
+mv ./Nos.o ../os.o
+
+#
+# OK. Patch is installed. Now do an idbuild
+#
+echo "$N: Building the new kernel."
+/etc/conf/bin/idbuild 2>/tmp/idb.$$
+if [ "$?" != "0" ]
+then
+ echo "$N: Kernel build failed! Errors are in /tmp/idb.$$"
+ cd ${OWD}
+ exit 1
+fi
+rm -f /tmp/idb.$$
+
+#
+# Kernel is now rebuilt.
+#
+echo "$N: Kernel successfully rebuilt."
+
+#
+# Stash the source files
+#
+echo "$N: Copies of the source for my programs"
+echo " will be in ${BKUP}"
+cat >> checker.c <<\!EOF!
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/immu.h>
+#include <sys/region.h>
+#include <sys/proc.h>
+#include <sys/sysi86.h>
+#include <sys/tss.h>
+#include <sys/v86.h>
+#include <signal.h>
+#include <stdio.h>
+
+#ifdef __GNUC__
+static __inline__ unsigned int
+inb(port)
+ short port;
+{
+ unsigned int ret;
+ __asm__ __volatile__("in%B0 (%1)" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+#else
+#include <sys/inline.h>
+#endif
+
+
+#define PORT 0x1260
+
+void sighand(signo)
+int signo;
+
+{
+ return;
+}
+
+main()
+{
+ int i;
+
+ sigset(SIGUSR1, sighand);
+ sysi86(SI86V86, V86SC_IOPL, PS_IOPL);
+ i = inb(PORT);
+ kill(getpid(), SIGUSR1);
+ i = inb(PORT);
+ exit(0);
+}
+!EOF!
+cat > patcher.c <<\!EOF!
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#ifdef __STDC__
+# include <stdlib.h>
+#else
+# include <malloc.h>
+#endif
+
+#define NUM_PATTERNS 2
+unsigned char match_buf[NUM_PATTERNS][30] = {
+ {
+ /* SVR4 */
+ 0x8b,0x54,0x24,0x04, /* movl 4(%esp),%edx */
+ 0x81,0x62,0x40,0xff,0xcf,0xff,0xff, /* andl $0xffffcfff,64(%edx) */
+ 0x81,0x4a,0x40,0x00,0x02,0x00,0x00, /* orl $0x200,64(%edx) */
+ },
+ {
+ /* SVR3 */
+ 0x81,0x67,0x40,0xff,0xcf,0xff,0xff, /* andl $0xffffcfff,64(%edi) */
+ 0x81,0x4f,0x40,0x00,0x02,0x00,0x00, /* orl $0x200,64(%edi) */
+ 0x81,0x4f,0x3c,0x04,0x00,0x00,0x00, /* orl $0x4,60(%edi) */
+ },
+};
+
+int match_lengths[] = {18,21};
+int match_offset[] = {8,4};
+#define EXPECT 0xcf
+#define CHANGE 0xff
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ int ifd, ofd;
+ char *ifname, *ofname;
+ unsigned int i, j, k;
+ unsigned int file_len, match_len;
+ struct stat stat_buf;
+ unsigned char *file_buf, hold_buf[50];
+ int c, check=0, undo=0;
+ char *infname, *outfname;
+ extern int optind;
+
+
+ while ((c=getopt(argc, argv, "cu")) != EOF) {
+ switch (c) {
+ case 'c':
+ if (undo) {
+ fprintf(stderr,
+ "%s: only one of -c, -u allowed\n",
+ argv[0]);
+ exit(1);
+ }
+ check = 1;
+ break;
+ case 'u':
+ if (check) {
+ fprintf(stderr,
+ "%s: only one of -c, -u allowed\n",
+ argv[0]);
+ exit(1);
+ }
+ undo = 1;
+ break;
+ case '?':
+ fprintf(stderr,
+ "usage: %s [-c | -u] in-file [out-file]\n",
+ argv[0]);
+ exit(1);
+ }
+ }
+
+ if ((!check && (argc-optind != 2)) || (check && (argc-optind != 1))) {
+ fprintf(stderr, "usage: %s [-c | -u] in-file [out-file]\n",
+ argv[0]);
+ exit(1);
+ }
+
+ ifname = argv[optind++];
+ if ((ifd = open(ifname, O_RDONLY)) < 0) {
+ fprintf(stderr, "failed to open() %s, errno=%d\n",
+ ifname, errno);
+ exit(1);
+ }
+ if (fstat(ifd, &stat_buf) < 0) {
+ fprintf(stderr, "Could not stat() %s, errno=%d\n",
+ ifname, errno);
+ exit(1);
+ }
+ file_len = stat_buf.st_size;
+ file_buf = malloc(file_len);
+ if (read(ifd, file_buf, file_len) != file_len) {
+ fprintf(stderr, "failed to read() %d bytes to %s, errno=%d\n",
+ file_len, ifname, errno);
+ exit(1);
+ }
+ close(ifd);
+
+ for (k=0; k < NUM_PATTERNS; k++) {
+ match_len = match_lengths[k];
+ memcpy(hold_buf, match_buf[k], match_len);
+ if (check || undo)
+ hold_buf[match_offset[k]] = CHANGE;
+ for (i=0, j=0; j < match_len && i < file_len; i++, j++) {
+ while (file_buf[i] != hold_buf[j]) {
+ i -= j-1;
+ j = 0;
+ if (i > file_len)
+ break;
+ }
+ }
+ if (j == match_len) {
+ /*
+ * Here, i is pointing to the end of the match
+ * string. Move it back to the beginning.
+ */
+ i -= match_len;
+ if (check || undo) {
+ /*
+ * Sanity check.
+ */
+ if (file_buf[i+match_offset[k]] != CHANGE) {
+ fprintf(stderr,
+ "??? 0x%02x not found ???\n",
+ CHANGE);
+ exit(1);
+ }
+ if (check)
+ exit(0);
+
+ file_buf[i+match_offset[k]] = EXPECT;
+ /*
+ * Print out the byte offset of the change. We
+ * can double-check this with 'cmp -l'.
+ */
+ printf("%d\n", i + match_offset[k] + 1);
+ break;
+ }
+ else {
+ /*
+ * Sanity check.
+ */
+ if (file_buf[i+match_offset[k]] != EXPECT) {
+ fprintf(stderr,
+ "??? 0x%02x not found ???\n",
+ EXPECT);
+ exit(1);
+ }
+ file_buf[i+match_offset[k]] = CHANGE;
+ /*
+ * Print out the byte offset of the change. We
+ * can double-check this with 'cmp -l'.
+ */
+ printf("%d\n", i + match_offset[k] + 1);
+ break;
+ }
+ }
+ }
+
+ if (k == NUM_PATTERNS) {
+ if (!check)
+ fprintf(stderr, "did not find any match strings!\n");
+ exit(1);
+ }
+
+ ofname = argv[optind];
+ if ((ofd = open(ofname, O_RDWR|O_CREAT, 0666)) < 0) {
+ fprintf(stderr, "failed to open() %s, errno=%d\n",
+ ofname, errno);
+ exit(1);
+ }
+ if (write(ofd, file_buf, file_len) != file_len) {
+ fprintf(stderr, "failed to write() %d bytes to %s, errno=%d\n",
+ file_len, ofname, errno);
+ exit(1);
+ }
+ close(ofd);
+ exit(0);
+}
+!EOF!
+
+#
+# Now store the removal script.
+#
+cat > ${N}_rem <<\!EOF!
+#!/bin/sh
+######################################################################
+#
+# Back out the patch to kernel that prevents losing IOPL on signals.
+#
+# Version 1.0 - 10/08/93
+# adapted for svr3 by Steve Forsythe (forsse@meaddata.com) from initial
+# svr4 version by David Wexelblat (dwex@goblin.org, dwex@aib.com)
+#
+
+N=`basename $0`
+
+#
+# Make sure we're running on SVR3!
+#
+uname -r | grep '3.2' > /dev/null
+if [ "$?" != "0" ]
+then
+ echo "$N: This only applies to SVR3!"
+ exit 1
+fi
+
+#
+# Next make sure we are running as root
+#
+id | grep 'uid=0' > /dev/null
+if [ "$?" != "0" ]
+then
+ echo "$N: Must be run as root!"
+ exit 1
+fi
+
+#
+# OK. Now undo the patch.
+#
+PACK=/etc/conf/pack.d/kernel
+BKUP=${PACK}/.xfree86
+if [ ! -d ${BKUP} ]
+then
+ echo "$N: Backup directory ${BKUP} does not exist!"
+ exit 1
+fi
+OWD=${PWD}
+cd ${BKUP}
+
+./patcher -c ../os.o
+if [ "$?" != "0" ]
+then
+ echo "$N: Patch not applied. Aborting"
+ cd ${OWD}
+ exit 1
+fi
+
+LOC=`./patcher -u ../os.o ./Nos.o`
+if [ "$?" != "0" ]
+then
+ echo "$N: Patch removal failed!!!"
+ cd ${OWD}
+ exit 1
+fi
+LOC1=`cmp -l ../os.o ./Nos.o | awk '{print $1; exit}'`
+if [ "$LOC" != "$LOC1" ]
+then
+ echo "$N: Patch sanity check failed!!!"
+ cd ${OWD}
+ exit 1
+fi
+echo "$N: Patch successfully removed. Installing unpatched module."
+mv ./Nos.o ../os.o
+
+#
+# OK. Patch is removed. Now do an idbuild
+#
+echo "$N: Building the new kernel."
+/etc/conf/bin/idbuild 2>/tmp/idb.$$
+if [ "$?" != "0" ]
+then
+ echo "$N: Kernel build failed! Errors are in /tmp/idb.$$"
+ cd ${OWD}
+ exit 1
+fi
+rm -f /tmp/idb.$$
+
+#
+# Kernel is now rebuilt.
+#
+echo "$N: Kernel successfully rebuilt."
+cd ${OWD}
+rm -fr ${BKUP}
+
+#
+# Kernel is now rebuilt. Check if we should reboot now.
+#
+REBOOT=0
+echo "$N: You must reboot before patch takes effect. Reboot now? \c"
+read RESP
+case ${RESP} in
+ [yY]*)
+ REBOOT=1
+ ;;
+ *)
+ echo "$N: OK. But remember to reboot later"
+ ;;
+esac
+
+cd ${OWD}
+rm -fr ${BKUP}
+#
+# All done. Reboot if necessary
+#
+if [ ${REBOOT} = "1" ]
+then
+ cd /
+ sync
+ /etc/shutdown -i6 -g15 -y &
+fi
+exit 0
+######################################################################
+!EOF!
+chmod 700 ${N}_rem
+
+#
+# Give the user some info that he will surely forget
+#
+echo ""
+echo "$N: To back out this patch, execute the script ${N}_rem,"
+echo " a copy of which can be found in the save directory"
+echo " ${BKUP}. To verify that the patch"
+echo " was successful, after rebooting with the new kernel,"
+echo " you can execute the program 'checker' (as root), which"
+echo " is also located in the save directory. This program"
+echo ' should exit with an exit code of 0 (i.e. $? == 0).'
+echo ""
+
+#
+# Check if we should reboot now.
+#
+REBOOT=0
+echo "$N: You must reboot before patch takes effect. Reboot now? \c"
+read RESP
+case ${RESP} in
+ [yY]*)
+ REBOOT=1
+ ;;
+ *)
+ echo "$N: OK. But remember to reboot later"
+ ;;
+esac
+
+#
+# All done. Reboot if necessary
+#
+if [ ${REBOOT} = "1" ]
+then
+ cd /
+ sync
+ /etc/shutdown -i6 -g15 -y &
+fi
+exit 0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/svr3_rem_pch b/xc/programs/Xserver/hw/xfree86/etc/svr3_rem_pch
new file mode 100644
index 000000000..e4abeb991
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/svr3_rem_pch
@@ -0,0 +1,122 @@
+#!/bin/sh
+######################################################################
+#
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/svr3_rem_pch,v 3.3 1996/12/23 06:47:22 dawes Exp $
+#
+# Back out the patch to kernel that prevents losing IOPL on signals.
+#
+# Version 1.0 - 10/08/93
+# adapted for svr3 by Steve Forsythe (forsse@meaddata.com) from initial
+# svr4 version by David Wexelblat (dwex@goblin.org, dwex@aib.com)
+#
+# $XConsortium: svr3_rem_pch /main/3 1996/02/21 17:48:32 kaleb $
+#
+
+N=`basename $0`
+
+#
+# Make sure we're running on SVR3!
+#
+uname -r | grep '3.2' > /dev/null
+if [ "$?" != "0" ]
+then
+ echo "$N: This only applies to SVR3!"
+ exit 1
+fi
+
+#
+# Next make sure we are running as root
+#
+id | grep 'uid=0' > /dev/null
+if [ "$?" != "0" ]
+then
+ echo "$N: Must be run as root!"
+ exit 1
+fi
+
+#
+# OK. Now undo the patch.
+#
+PACK=/etc/conf/pack.d/kernel
+BKUP=${PACK}/.xfree86
+if [ ! -d ${BKUP} ]
+then
+ echo "$N: Backup directory ${BKUP} does not exist!"
+ exit 1
+fi
+OWD=${PWD}
+cd ${BKUP}
+
+./patcher -c ../os.o
+if [ "$?" != "0" ]
+then
+ echo "$N: Patch not applied. Aborting"
+ cd ${OWD}
+ exit 1
+fi
+
+LOC=`./patcher -u ../os.o ./Nos.o`
+if [ "$?" != "0" ]
+then
+ echo "$N: Patch removal failed!!!"
+ cd ${OWD}
+ exit 1
+fi
+LOC1=`cmp -l ../os.o ./Nos.o | awk '{print $1; exit}'`
+if [ "$LOC" != "$LOC1" ]
+then
+ echo "$N: Patch sanity check failed!!!"
+ cd ${OWD}
+ exit 1
+fi
+echo "$N: Patch successfully removed. Installing unpatched module."
+mv ./Nos.o ../os.o
+
+#
+# OK. Patch is removed. Now do an idbuild
+#
+echo "$N: Building the new kernel."
+/etc/conf/bin/idbuild 2>/tmp/idb.$$
+if [ "$?" != "0" ]
+then
+ echo "$N: Kernel build failed! Errors are in /tmp/idb.$$"
+ cd ${OWD}
+ exit 1
+fi
+rm -f /tmp/idb.$$
+
+#
+# Kernel is now rebuilt.
+#
+echo "$N: Kernel successfully rebuilt."
+cd ${OWD}
+rm -fr ${BKUP}
+
+#
+# Kernel is now rebuilt. Check if we should reboot now.
+#
+REBOOT=0
+echo "$N: You must reboot before patch takes effect. Reboot now? \c"
+read RESP
+case ${RESP} in
+ [yY]*)
+ REBOOT=1
+ ;;
+ *)
+ echo "$N: OK. But remember to reboot later"
+ ;;
+esac
+
+cd ${OWD}
+rm -fr ${BKUP}
+#
+# All done. Reboot if necessary
+#
+if [ ${REBOOT} = "1" ]
+then
+ cd /
+ sync
+ /etc/shutdown -i6 -g15 -y &
+fi
+exit 0
+######################################################################
diff --git a/xc/programs/Xserver/hw/xfree86/etc/svr4_patch b/xc/programs/Xserver/hw/xfree86/etc/svr4_patch
new file mode 100644
index 000000000..a04bb3429
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/svr4_patch
@@ -0,0 +1,749 @@
+#!/bin/sh
+#
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/svr4_patch,v 3.2 1996/12/23 06:47:23 dawes Exp $
+#
+# Apply patch to kernel to prevent losing IOPL on signals.
+#
+# Version 1.0 - 11/18/92
+# initial version - dwex@goblin.org, dwex@aib.com
+#
+# $XConsortium: svr4_patch /main/4 1996/02/21 17:48:36 kaleb $
+#
+
+PATH=/sbin:/usr/sbin:/usr/bin
+
+N=`basename $0`
+
+#
+# Make sure we're running on SVR4!
+#
+uname -r | grep '4' > /dev/null
+if [ "$?" != "0" ]
+then
+ echo "$N: This only applies to SVR4!"
+ exit 1
+fi
+
+#
+# Next make sure we are running as root
+#
+id | grep 'uid=0' > /dev/null
+if [ "$?" != "0" ]
+then
+ echo "$N: Must be run as root!"
+ exit 1
+fi
+
+#
+# Now make temp directory
+#
+TMPDIR=/tmp/xf86_pt.$$
+mkdir ${TMPDIR}
+if [ ! -d ${TMPDIR} ]
+then
+ echo "$N: Failed to make temp directory"
+ exit 1
+fi
+
+#
+# Go to temp directory
+#
+OWD=${PWD}
+cd ${TMPDIR}
+
+#
+# Checksums for programs
+#
+CHECKER_SUM="34037 5 checker"
+PATCHER_SUM="10505 10 patcher"
+
+#
+# Extract programs
+#
+cat > checker.uu <<\!EOF!
+begin 777 checker
+M?T5,1@$! 0 ( P ! X(,$"#0 #X!0 #0 ( %
+M "@ $ / 8 T -( $" "@ H 4 P -0
+M !, ! ! - #2 ! @ I 0
+M *0$ % ! $ #8! V)0$" "< H < $
+M @ 0% $E00( ' !P O=7-R+VQI8B]L:6)C
+M+G-O+C$ !$ 1 #P @ - X ! P L
+M # ! D !P
+M $ !@ "
+M 4 * ! <(,$"!P 2
+M "@ 'B5! @ $0#Q_P\ # @P0( !( 6 V)0$" 0
+M 1 L 'P -B$! @ $0#Q_R8 " @P0(0 !( M T(,$
+M" 2 ,@ '25! @ $0#Q_SD "@@P0( !( ^
+M=)4$" 0 1 X 1 -2$! @$ $0 * %$ "0@P0( !( !;
+M W)0$" 1 /'_<0 25! @ $0#Q_WH "P@P0( !(
+M "! Q80$" 2 @ %]C;&5A;G5P %]E;F0 9V5T<&ED %]E;G9I
+M<F]N %]E=&5X= !A=&5X:70 :VEL; !?961A=&$ 97AI= !E<G)N;P!?;&EB
+M7W9E<G-I;VX 7U]F<'-T87)T %]'3$]"04Q?3T9&4T547U1!0DQ%7P!?1%E.
+M04U)0P!S:6=S970 7V-E<G)O<@ O=7-R+VQI8B]L:6)C+G-O+C$ Z)0$" <!
+M #LE 0(!P8 /"4! @'# ])0$" <) #XE 0(!P\ /R4! @' P )4$
+M" <' #" _S7@E 0(_R7DE 0( /\EZ)0$"&@ Z>#_____)>R4
+M! AH" .G0_____R7PE 0(:! #IP/____\E])0$"&@8 Z;#_____
+M)?B4! AH( .F@_____R7\E 0(:"@ #ID/____\E )4$"&@P Z8#_
+M__]J &H B^Q2N'"#! B%P'0-:'"#! CHAO___X/$!+@$E00(A<!T!>AU____
+M:-"$! CH:____XM%"(U4A1")%=B4! A2C54,4E#H+____^A>____Z"4 "#
+MQ Q0Z&#___]J +@! F@ ' /3#ZP3K ,G#58OLZ_>0ZTYH4(0$"&H0
+MZ$;___^#Q AH # &H$:D?H-P (/$#"O 9KI@$NR)1?QJ$.@Q____4.@[
+M____@\0(*\!FNF 2[(E%_&H Z/?^__]9R<-5B^Q0ZZRX,@ )H !P /
+M@@$ ##HW25! BX_____\/" $E00( !V@P0(
+MAH,$"):#! BF@P0(MH,$",:#! C6@P0( 0 (D , 7(,$" T #0
+MA 0(! .B ! @% B(($" 8 !X@00("@ )P + $ !4
+M P -R4! @" . !0 1 %P "2#! @
+M N:6YT97)P "YH87-H "YD>6YS>6T +F1Y;G-T<@ N<F5L+G!L= N:6YI
+M= N<&QT "YT97AT "YF:6YI "YR;V1A=&$ +F1A=&$ +F=O= N9'EN86UI
+M8P N8G-S "YS>6UT86( +G-T<G1A8@ N<VAS=')T86( +F-O;6UE;G0
+M ! 0
+M ( #4@ 0(U !, $ "0 4 "
+MZ( $".@ "0 P $ ! \ + @ 'B!! AX
+M 0 $ $ 0 ! ! ! 7 P ( "(@@0(B ( )P
+M $ 'P D " )(,$""0# X P
+M < $ " "@ ! !@ %R#! A< P P
+M! N 0 8 !@@P0(8 , ( 0 $
+M ,P $ & X(,$". # #P $ #D
+M ! !@ -"$! C0! P ! _ 0
+M ( #4A 0(U 0 0 0 1P $ #
+MV)0$"-@$ $ $ $T ! P -R4! C<
+M! * ! 0 !2 !@ , $E00(! 4 '
+M $ 0 ( 6P @ # =)4$"'0% $
+M $ ' # !T!0 @P
+( 0
+
+end
+!EOF!
+uudecode checker.uu
+rm -f checker.uu
+if [ "`sum checker`" != "${CHECKER_SUM}" ]
+then
+ echo "$N: Program 'checker' extracted incorrectly!"
+ cd ${OWD}
+ rm -rf ${BKUP}
+ exit 1
+fi
+chmod 700 checker
+
+cat > patcher.uu <<\!EOF!
+begin 777 patcher
+M?T5,1@$! 0 ( P ! 9(8$"#0 !<#P #0 ( %
+M "@ $0 0 8 T -( $" "@ H 4 P -0
+M !, ! ! - #2 ! @ ? T
+M 'P- % ! $ "P#0 L)T$" @ 0 Y 0 < $
+M @ & . !@G@0( ' !P O=7-R+VQI8B]L:6)C
+M+G-O+C$ !$ @ % P ; &0 !X : !4
+M < & !T % \ ? "P !
+M ! @ D
+M ( 0 & !, # $@ !8
+M #@ < #0 !$ * %P
+M ! T)X$", # 1 \ !P /2%! @ $@ P 4A@0(
+M !( 1 !(8$" P" 2 & )2%! @ $@ !\ #0G@0(
+MP , "$ #P D 5(4$"!P 2 +0 )2B! @ $0#Q_S( ,
+MG@0(! !$ # [ L(T$" 1 /'_0@ &2%! A $@ $D
+M #0G@0( !$ \?]0 I(4$" 2 6 "2&! @ $@
+M %X "$A00( !( !C Q(4$" 2 :P %2&! @
+M$@ '$ G@0(! !$ # !X D*($" 0 1 \ ?@ 2>! @$
+M $0 , (4 #\BP0(! !$ "@"2 M(4$" 2 F@ -2%
+M! B0 $@ *( !TA00( !( "L _)T$" 0 1 P LP
+M B>! @$ $0 , +H 0G@0( !$ \?_0 -(8$" 2
+MUP $2&! B, $@ -X !@G@0( !$ \?_G Y(4$"(0" 2
+M %]?:6]B &]P96X <F5A9 !M86QL;V, 7WAS=&%T %]I;V( 7V-L96%N
+M=7 7V5N9 !?96YV:7)O;@!?971E>'0 871E>&ET %]E9&%T80!?;'AS=&%T
+M &-L;W-E &5X:70 7WAM:VYO9 !W<FET90!O<'1I;F0 97)R;F\ ;W!T;W!T
+M %]L:6)?=F5R<VEO;@!?9GAS=&%T &9P<FEN=&8 7U]F<'-T87)T &]P=&5R
+M<@!O<'1A<F< 7T=,3T)!3%]/1D93151?5$%"3$5? &UE;6-P>0!P<FEN=&8
+M7T193D%-24, 9V5T;W!T "]U<W(O;&EB+VQI8F,N<V\N,0 <G@0(!P<
+M "">! @'"P ))X$" <8 HG@0(!P\ "R>! @'!0 ,)X$" <- TG@0(
+M!Q8 #B>! @'$ /)X$" <7 ! G@0(!Q\ $2>! @' @ 2)X$" <$ !,
+MG@0(!P, %">! @'#@ 5)X$" << !8G@0(!QT %R>! @'$0 P@ /\U
+M%)X$"/\E&)X$" #_)1R>! AH .G@_____R4@G@0(: @ #IT/__
+M__\E))X$"&@0 Z<#_____)2B>! AH& .FP_____R4LG@0(:" #I
+MH/____\E,)X$"&@H Z9#_____)32>! AH, .F _____R4XG@0(:#@
+M #I</____\E/)X$"&A Z6#_____)4">! AH2 .E0_____R5$G@0(
+M:% #I0/____\E2)X$"&A8 Z3#_____)4R>! AH8 .D@_____R50
+MG@0(:&@ #I$/____\E5)X$"&AP Z0#_____)5B>! AH> .GP_O__
+M_R5<G@0(:( #IX/[__VH :@"+[%*X5(4$"(7 = UH5(4$".CF_O__@\0$
+MN&">! B%P'0%Z-7^__]H^(L$".C+_O__BT4(C52%$(D5#)X$"%*-50Q24.B/
+M_O__Z+[^___HK0 (/$#%#HP/[__VH N $ ": < ],/K&O]U#/]U
+M"&H"Z+'^__^#Q R)1?R+1?SK ,G#58OL4.O@B\#K&O]U#/]U"&H"Z)W^__^#
+MQ R)1?R+1?SK ,G#58OL4.O@B\#K&O]U#/]U"&H"Z(G^__^#Q R)1?R+1?SK
+M ,G#58OL4.O@B\#K'?]U$/]U#/]U"&H"Z'+^__^#Q!")1?R+1?SK ,G#58OL
+M4.O=C4 Z7H$ #'A2#___\ QX4<____ .FG Z8D "#O1S_
+M__\ =!^+10S_,&@ C 0(:/">! CH+/[__X/$#&H!Z-+]__]9QX4@____ 0
+M .MN@[T@____ '0?BT4,_S!H((P$"&CPG@0(Z/C]__^#Q QJ >B>_?__6<>%
+M'/___P$ #K.HM%#/\P:$",! AH\)X$".C-_?__@\0,:@'H<_W__UGK&8N%
+M)/___X/X/W34@_AC#X1C____@_AU=))H:(P$"/]U#/]U".BG_?__@\0,B84D
+M____@_C_#X4W____@[T@____ '4.BT4(*P4 G@0(@_@"=1>#O2#___\ ="V+
+M10@K!0">! B#^ %T'XM%#/\P:&R,! AH\)X$".A#_?__@\0,:@'HZ?S__UF+
+M10R+%0">! C_!0">! B+!)")1?1J /]U].@Y_?__@\0(B47\A<!](_\UD*($
+M"/]U]&B4C 0(:/">! CH]_S__X/$$&H!Z)W\__]9C85@____4/]U_.@E_O__
+M@\0(A<!](_\UD*($"/]U]&BTC 0(:/">! CHOOS__X/$$&H!Z&3\__]9BUV0
+M4^C:_/__68F%7/___U/_M5S_____=?SHU/S__X/$##O#="3_-9"B! C_=?13
+M:-2,! AH\)X$".AT_/__@\04:@'H&OS__UG_=?SHL?S__UG'1>P Z98!
+M "+1>R+!(7LG00(B47H_W7H:T7L'HV L)T$"%"-A2C___]0Z(W\__^#Q R#
+MO2#___\ =0F#O1S___\ =!*+1>R+!(7TG00(QH0%*/____\S_S/VZR/K#8U&
+M_ROX,_8[^W8"ZQ*+A5S___^*!#@ZA#4H____=>%'1CMUZ',$._MRU#MUZ ^%
+M"@$ "M]Z(.](/___P!U#8.]'/___P /A($ "+QXM5[ ,$E?2=! B+E5S_
+M__\/M@00/?\ !T'VC_ : "-! AH\)X$".B!^___@\0,:@'H)_O__UF#
+MO2#___\ = AJ .@6^___68O'BU7L P25])T$"(N57/___\8$$,^+1>R+!(7T
+MG00(C40' 5!H'(T$".BF^___@\0(ZWV+QXM5[ ,$E?2=! B+E5S___\/M@00
+M/<\ !T'VC/ :""-! AH\)X$".@ ^___@\0,:@'HIOK__UF+QXM5[ ,$
+ME?2=! B+E5S____&!!#_BT7LBP2%])T$"(U$!P%0:#R-! CH-OO__X/$".L-
+M_T7L@WWL @^"8/[__X-][ )U(X.](/___P!U$FA C00(:/">! CHEOK__X/$
+M"&H!Z#SZ__]9BT4,BQ4 G@0(BP20B47P:+8! !H @$ /]U\.B*^O__@\0,
+MB47XA<!](_\UD*($"/]U\&ADC00(:/">! CH2/K__X/$$&H!Z.[Y__]94_^U
+M7/____]U^.BN^O__@\0,.\-T)/\UD*($"/]U\%-HA(T$"&CPG@0(Z [Z__^#
+MQ!1J >BT^?__6?]U^.A+^O__66H Z*/Y__]96UY?R<-5B^R![.P !75E/I
+M=?O__\( )7,Z(&]N;'D@;VYE(&]F("UC+" M=2!A;&QO=V5D"@ E
+M<SH@;VYL>2!O;F4@;V8@+6,L("UU(&%L;&]W960* '5S86=E.B E<R!;+6,@
+M?" M=5T@:6XM9FEL92!;;W5T+69I;&5="@!C=0 =7-A9V4Z("5S(%LM8R!\
+M("UU72!I;BUF:6QE(%MO=70M9FEL95T* &9A:6QE9"!T;R!O<&5N*"D@)7,L
+M(&5R<FYO/25D"@ 0V]U;&0@;F]T('-T870H*2 E<RP@97)R;F\])60* !F
+M86EL960@=&\@<F5A9"@I("5D(&)Y=&5S('1O("5S+"!E<G)N;STE9 H #\_
+M/R P>"4P,G@@;F]T(&9O=6YD(#\_/PH E9 H /S\_(#!X)3 R>"!N;W0@
+M9F]U;F0@/S\_"@ "5D"@!D:60@;F]T(&9I;F0@86YY(&UA=&-H('-T<FEN
+M9W,A"@ !F86EL960@=&\@;W!E;B@I("5S+"!E<G)N;STE9 H &9A:6QE
+M9"!T;R!W<FET92@I("5D(&)Y=&5S('1O("5S+"!E<G)N;STE9 H BU0D!(%B
+M0/_/__^!2D @ @6= _\___X%/0 " "!3SP$
+M $@ !4 ( ! $ !
+M8)X$" 6H4$"&J%! AZA00(BH4$")J%! BJA00(NH4$",J%! C:
+MA00(ZH4$"/J%! @*A@0(&H8$""J&! @ZA@0(2H8$"%J&! @! [@ P
+M ! A00(#0 /B+! @$ Z( $" 4 "T@P0(!@ +2!! @* 0$
+M L 0 %0 # $)X$" ( "( % !$ 7
+MN(0$" "YI;G1E<G +FAA<V@ +F1Y;G-Y;0 N9'EN<W1R "YR
+M96PN<&QT "YI;FET "YP;'0 +G1E>'0 +F9I;FD +G)O9&%T80 N<F]D871A
+M,0 N9&%T80 N9V]T "YD>6YA;6EC "YB<W, +G-Y;71A8@ N<W1R=&%B "YS
+M:'-T<G1A8@ N8V]M;65N=
+M 0 $ " U( $"-0 3 !
+M D % @ .B ! CH S , ! 0
+M / "P ( "T@00(M $ " $ 0 0 0 %P
+M , " M(,$"+0# ! 0 ! !\ )
+M @ +B$! BX! B , ' ! @ H 0 8 !
+MA00(0 4 , 0 +@ $ & 1(4$"$0%
+M @ 0 $ ! #, ! !@ &2&! AD!@ E 4
+M ! Y 0 8 #XBP0(^ L ,
+M 0 /P $ " _(L$"/P+ $ $
+M $< ! @ ",! @ # L $ !
+M !0 0 , "PG00(L T & 0 5@
+M $ # $)X$"! . !0 $ ! %L &
+M P &">! A@#@ < 0 ! @ !D " , #0
+MG@0(T X ,0# 0 >0 , - .
+6 ", !
+
+end
+!EOF!
+uudecode patcher.uu
+rm -f patcher.uu
+if [ "`sum patcher`" != "${PATCHER_SUM}" ]
+then
+ echo "$N: Program 'patcher' extracted incorrectly!"
+ cd ${OWD}
+ rm -rf ${BKUP}
+ exit 1
+fi
+chmod 700 patcher
+
+echo "$N: The programs we need have been extracted successfully"
+
+#
+# OK. Now we have the programs we need. Run checker to see if the patch
+# is needed.
+#
+rm -f core
+(./checker; exit $? ) > /dev/null 2>&1
+if [ "$?" != "0" ]
+then
+ if [ ! -f core ]
+ then
+ echo "$N: Check failed, but no core file??? Aborting."
+ cd ${OWD}
+ rm -rf ${TMPDIR}
+ exit 1
+ else
+ rm -f core
+ echo "$N: The bug exists. Will proceed with the patch"
+ fi
+else
+ echo "$N: Patch is not needed; bug not present."
+ cd ${OWD}
+ rm -rf ${TMPDIR}
+ exit 0
+fi
+
+#
+# OK. We need to do the patch. Make a directory in /etc/conf/pack.d/kernel
+# to hold our stuff (we'll store a backup os.o there, and put the programs
+# there, and their source as well).
+#
+PACK=/etc/conf/pack.d/kernel
+BKUP=${PACK}/.xfree86
+if [ -d ${BKUP} ]
+then
+ echo "$N: Backup directory ${BKUP} exists"
+ echo " but bug not fixed. Aborting"
+ cd ${OWD}
+ rm -rf ${TMPDIR}
+ exit 1
+fi
+
+mkdir ${BKUP}
+if [ ! -d ${BKUP} ]
+then
+ echo "$N: Failed to make backup directory ${BKUP}"
+ cd ${OWD}
+ rm -rf ${TMPDIR}
+ exit 1
+fi
+cp ${TMPDIR}/* ${BKUP}
+cd ${BKUP}
+rm -rf ${TMPDIR}
+./patcher -c ../os.o
+if [ "$?" = "0" ]
+then
+ echo "$N: Patch already applied, but bug not fixed. Aborting"
+ cd ${OWD}
+ rm -rf ${BKUP}
+ exit 1
+fi
+
+#
+# Stash the backup
+#
+cp ../os.o ./os.o.SAV
+echo "$N: A copy of os.o has been saved in ${BKUP}"
+LOC=`./patcher ../os.o ./Nos.o`
+if [ "$?" != "0" ]
+then
+ echo "$N: Patch failed!!!"
+ cd ${OWD}
+ rm -rf ${BKUP}
+ exit 1
+fi
+LOC1=`cmp -l ../os.o ./Nos.o | awk '{print $1; exit}'`
+if [ "$LOC" != "$LOC1" ]
+then
+ echo "$N: Patch sanity check failed!!!"
+ cd ${OWD}
+ rm -rf ${BKUP}
+ exit 1
+fi
+echo "$N: Patch successfully applied. Installing it."
+mv ./Nos.o ../os.o
+
+#
+# OK. Patch is installed. Now do an idbuild
+#
+echo "$N: Building the new kernel."
+/etc/conf/bin/idbuild 2>/tmp/idb.$$
+if [ "$?" != "0" ]
+then
+ echo "$N: Kernel build failed! Errors are in /tmp/idb.$$"
+ cd ${OWD}
+ exit 1
+fi
+rm -f /tmp/idb.$$
+
+#
+# Kernel is now rebuilt.
+#
+echo "$N: Kernel successfully rebuilt."
+
+#
+# Stash the source files
+#
+echo "$N: Copies of the source for my programs"
+echo " will be in ${BKUP}"
+cat >> checker.c <<\!EOF!
+#include <sys/types.h>
+#include <sys/proc.h>
+#include <sys/sysi86.h>
+#include <sys/tss.h>
+#include <sys/v86.h>
+#include <signal.h>
+#include <stdio.h>
+
+#ifdef __GNUC__
+static __inline__ unsigned int
+inb(port)
+ short port;
+{
+ unsigned int ret;
+ __asm__ __volatile__("in%B0 (%1)" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+#else
+#include <sys/inline.h>
+#endif
+
+
+#define PORT 0x1260
+
+void sighand(signo)
+int signo;
+
+{
+ return;
+}
+
+main()
+{
+ int i;
+
+ sigset(SIGUSR1, sighand);
+ sysi86(SI86V86, V86SC_IOPL, PS_IOPL);
+ i = inb(PORT);
+ kill(getpid(), SIGUSR1);
+ i = inb(PORT);
+ exit(0);
+}
+!EOF!
+cat > patcher.c <<\!EOF!
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#ifdef __STDC__
+# include <stdlib.h>
+#else
+# include <malloc.h>
+#endif
+
+#define NUM_PATTERNS 2
+unsigned char match_buf[NUM_PATTERNS][30] = {
+ {
+ /* SVR4 */
+ 0x8b,0x54,0x24,0x04, /* movl 4(%esp),%edx */
+ 0x81,0x62,0x40,0xff,0xcf,0xff,0xff, /* andl $0xffffcfff,64(%edx) */
+ 0x81,0x4a,0x40,0x00,0x02,0x00,0x00, /* orl $0x200,64(%edx) */
+ },
+ {
+ /* SVR3 */
+ 0x81,0x67,0x40,0xff,0xcf,0xff,0xff, /* andl $0xffffcfff,64(%edi) */
+ 0x81,0x4f,0x40,0x00,0x02,0x00,0x00, /* orl $0x200,64(%edi) */
+ 0x81,0x4f,0x3c,0x04,0x00,0x00,0x00, /* orl $0x4,60(%edi) */
+ },
+};
+
+int match_lengths[] = {18,21};
+int match_offset[] = {8,4};
+#define EXPECT 0xcf
+#define CHANGE 0xff
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ int ifd, ofd;
+ char *ifname, *ofname;
+ unsigned int i, j, k;
+ unsigned int file_len, match_len;
+ struct stat stat_buf;
+ unsigned char *file_buf, hold_buf[50];
+ int c, check=0, undo=0;
+ char *infname, *outfname;
+ extern int optind;
+
+
+ while ((c=getopt(argc, argv, "cu")) != EOF) {
+ switch (c) {
+ case 'c':
+ if (undo) {
+ fprintf(stderr,
+ "%s: only one of -c, -u allowed\n",
+ argv[0]);
+ exit(1);
+ }
+ check = 1;
+ break;
+ case 'u':
+ if (check) {
+ fprintf(stderr,
+ "%s: only one of -c, -u allowed\n",
+ argv[0]);
+ exit(1);
+ }
+ undo = 1;
+ break;
+ case '?':
+ fprintf(stderr,
+ "usage: %s [-c | -u] in-file [out-file]\n",
+ argv[0]);
+ exit(1);
+ }
+ }
+
+ if ((!check && (argc-optind != 2)) || (check && (argc-optind != 1))) {
+ fprintf(stderr, "usage: %s [-c | -u] in-file [out-file]\n",
+ argv[0]);
+ exit(1);
+ }
+
+ ifname = argv[optind++];
+ if ((ifd = open(ifname, O_RDONLY)) < 0) {
+ fprintf(stderr, "failed to open() %s, errno=%d\n",
+ ifname, errno);
+ exit(1);
+ }
+ if (fstat(ifd, &stat_buf) < 0) {
+ fprintf(stderr, "Could not stat() %s, errno=%d\n",
+ ifname, errno);
+ exit(1);
+ }
+ file_len = stat_buf.st_size;
+ file_buf = malloc(file_len);
+ if (read(ifd, file_buf, file_len) != file_len) {
+ fprintf(stderr, "failed to read() %d bytes to %s, errno=%d\n",
+ file_len, ifname, errno);
+ exit(1);
+ }
+ close(ifd);
+
+ for (k=0; k < NUM_PATTERNS; k++) {
+ match_len = match_lengths[k];
+ memcpy(hold_buf, match_buf[k], match_len);
+ if (check || undo)
+ hold_buf[match_offset[k]] = CHANGE;
+ for (i=0, j=0; j < match_len && i < file_len; i++, j++) {
+ while (file_buf[i] != hold_buf[j]) {
+ i -= j-1;
+ j = 0;
+ if (i > file_len)
+ break;
+ }
+ }
+ if (j == match_len) {
+ /*
+ * Here, i is pointing to the end of the match
+ * string. Move it back to the beginning.
+ */
+ i -= match_len;
+ if (check || undo) {
+ /*
+ * Sanity check.
+ */
+ if (file_buf[i+match_offset[k]] != CHANGE) {
+ fprintf(stderr,
+ "??? 0x%02x not found ???\n",
+ CHANGE);
+ exit(1);
+ }
+ if (check)
+ exit(0);
+
+ file_buf[i+match_offset[k]] = EXPECT;
+ /*
+ * Print out the byte offset of the change. We
+ * can double-check this with 'cmp -l'.
+ */
+ printf("%d\n", i + match_offset[k] + 1);
+ break;
+ }
+ else {
+ /*
+ * Sanity check.
+ */
+ if (file_buf[i+match_offset[k]] != EXPECT) {
+ fprintf(stderr,
+ "??? 0x%02x not found ???\n",
+ EXPECT);
+ exit(1);
+ }
+ file_buf[i+match_offset[k]] = CHANGE;
+ /*
+ * Print out the byte offset of the change. We
+ * can double-check this with 'cmp -l'.
+ */
+ printf("%d\n", i + match_offset[k] + 1);
+ break;
+ }
+ }
+ }
+
+ if (k == NUM_PATTERNS) {
+ if (!check)
+ fprintf(stderr, "did not find any match strings!\n");
+ exit(1);
+ }
+
+ ofname = argv[optind];
+ if ((ofd = open(ofname, O_RDWR|O_CREAT, 0666)) < 0) {
+ fprintf(stderr, "failed to open() %s, errno=%d\n",
+ ofname, errno);
+ exit(1);
+ }
+ if (write(ofd, file_buf, file_len) != file_len) {
+ fprintf(stderr, "failed to write() %d bytes to %s, errno=%d\n",
+ file_len, ofname, errno);
+ exit(1);
+ }
+ close(ofd);
+ exit(0);
+}
+!EOF!
+
+#
+# Now store the removal script.
+#
+cat > ${N}_rem <<\!EOF!
+#!/bin/sh
+######################################################################
+#
+# Back out the patch to kernel that prevents losing IOPL on signals.
+#
+# Version 1.0 - 11/18/92
+# initial version - dwex@goblin.org, dwex@aib.com
+#
+
+N=`basename $0`
+
+#
+# Make sure we're running on SVR4!
+#
+uname -r | grep '4' > /dev/null
+if [ "$?" != "0" ]
+then
+ echo "$N: This only applies to SVR4!"
+ exit 1
+fi
+
+#
+# Next make sure we are running as root
+#
+id | grep 'uid=0' > /dev/null
+if [ "$?" != "0" ]
+then
+ echo "$N: Must be run as root!"
+ exit 1
+fi
+
+#
+# OK. Now undo the patch.
+#
+PACK=/etc/conf/pack.d/kernel
+BKUP=${PACK}/.xfree86
+if [ ! -d ${BKUP} ]
+then
+ echo "$N: Backup directory ${BKUP} does not exist!"
+ exit 1
+fi
+OWD=${PWD}
+cd ${BKUP}
+
+./patcher -c ../os.o
+if [ "$?" != "0" ]
+then
+ echo "$N: Patch not applied. Aborting"
+ cd ${OWD}
+ exit 1
+fi
+
+LOC=`./patcher -u ../os.o ./Nos.o`
+if [ "$?" != "0" ]
+then
+ echo "$N: Patch removal failed!!!"
+ cd ${OWD}
+ exit 1
+fi
+LOC1=`cmp -l ../os.o ./Nos.o | awk '{print $1; exit}'`
+if [ "$LOC" != "$LOC1" ]
+then
+ echo "$N: Patch sanity check failed!!!"
+ cd ${OWD}
+ exit 1
+fi
+echo "$N: Patch successfully removed. Installing unpatched module."
+mv ./Nos.o ../os.o
+
+#
+# OK. Patch is removed. Now do an idbuild
+#
+echo "$N: Building the new kernel."
+/etc/conf/bin/idbuild 2>/tmp/idb.$$
+if [ "$?" != "0" ]
+then
+ echo "$N: Kernel build failed! Errors are in /tmp/idb.$$"
+ cd ${OWD}
+ exit 1
+fi
+rm -f /tmp/idb.$$
+
+#
+# Kernel is now rebuilt.
+#
+echo "$N: Kernel successfully rebuilt."
+cd ${OWD}
+rm -rf ${BKUP}
+
+#
+# Kernel is now rebuilt. Check if we should reboot now.
+#
+REBOOT=0
+echo "$N: You must reboot before patch takes effect. Reboot now? \c"
+read RESP
+case ${RESP} in
+ [yY]*)
+ REBOOT=1
+ ;;
+ *)
+ echo "$N: OK. But remember to reboot later"
+ ;;
+esac
+
+cd ${OWD}
+rm -rf ${BKUP}
+#
+# All done. Reboot if necessary
+#
+if [ ${REBOOT} = "1" ]
+then
+ cd /
+ sync
+ /usr/sbin/shutdown -i6 -g15 -y &
+fi
+exit 0
+######################################################################
+!EOF!
+chmod 700 ${N}_rem
+
+#
+# Give the user some info that he will surely forget
+#
+echo ""
+echo "$N: To back out this patch, execute the script ${N}_rem,"
+echo " a copy of which can be found in the save directory"
+echo " ${BKUP}. To verify that the patch"
+echo " was successful, after rebooting with the new kernel,"
+echo " you can execute the program 'checker' (as root), which"
+echo " is also located in the save directory. This program"
+echo ' should exit with an exit code of 0 (i.e. $? == 0).'
+echo ""
+
+#
+# Check if we should reboot now.
+#
+REBOOT=0
+echo "$N: You must reboot before patch takes effect. Reboot now? \c"
+read RESP
+case ${RESP} in
+ [yY]*)
+ REBOOT=1
+ ;;
+ *)
+ echo "$N: OK. But remember to reboot later"
+ ;;
+esac
+
+#
+# All done. Reboot if necessary
+#
+if [ ${REBOOT} = "1" ]
+then
+ cd /
+ sync
+ /usr/sbin/shutdown -i6 -g15 -y &
+fi
+exit 0
diff --git a/xc/programs/Xserver/hw/xfree86/etc/svr4_rem_pch b/xc/programs/Xserver/hw/xfree86/etc/svr4_rem_pch
new file mode 100644
index 000000000..e45c7cd5d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/svr4_rem_pch
@@ -0,0 +1,121 @@
+#!/bin/sh
+######################################################################
+#
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/svr4_rem_pch,v 3.3 1996/12/23 06:47:24 dawes Exp $
+#
+# Back out the patch to kernel that prevents losing IOPL on signals.
+#
+# Version 1.0 - 11/18/92
+# initial version - dwex@goblin.org, dwex@aib.com
+#
+# $XConsortium: svr4_rem_pch /main/3 1996/02/21 17:48:40 kaleb $
+#
+
+N=`basename $0`
+
+#
+# Make sure we're running on SVR4!
+#
+uname -r | grep '4' > /dev/null
+if [ "$?" != "0" ]
+then
+ echo "$N: This only applies to SVR4!"
+ exit 1
+fi
+
+#
+# Next make sure we are running as root
+#
+id | grep 'uid=0' > /dev/null
+if [ "$?" != "0" ]
+then
+ echo "$N: Must be run as root!"
+ exit 1
+fi
+
+#
+# OK. Now undo the patch.
+#
+PACK=/etc/conf/pack.d/kernel
+BKUP=${PACK}/.xfree86
+if [ ! -d ${BKUP} ]
+then
+ echo "$N: Backup directory ${BKUP} does not exist!"
+ exit 1
+fi
+OWD=${PWD}
+cd ${BKUP}
+
+./patcher -c ../os.o
+if [ "$?" != "0" ]
+then
+ echo "$N: Patch not applied. Aborting"
+ cd ${OWD}
+ exit 1
+fi
+
+LOC=`./patcher -u ../os.o ./Nos.o`
+if [ "$?" != "0" ]
+then
+ echo "$N: Patch removal failed!!!"
+ cd ${OWD}
+ exit 1
+fi
+LOC1=`cmp -l ../os.o ./Nos.o | awk '{print $1; exit}'`
+if [ "$LOC" != "$LOC1" ]
+then
+ echo "$N: Patch sanity check failed!!!"
+ cd ${OWD}
+ exit 1
+fi
+echo "$N: Patch successfully removed. Installing unpatched module."
+mv ./Nos.o ../os.o
+
+#
+# OK. Patch is removed. Now do an idbuild
+#
+echo "$N: Building the new kernel."
+/etc/conf/bin/idbuild 2>/tmp/idb.$$
+if [ "$?" != "0" ]
+then
+ echo "$N: Kernel build failed! Errors are in /tmp/idb.$$"
+ cd ${OWD}
+ exit 1
+fi
+rm -f /tmp/idb.$$
+
+#
+# Kernel is now rebuilt.
+#
+echo "$N: Kernel successfully rebuilt."
+cd ${OWD}
+rm -rf ${BKUP}
+
+#
+# Kernel is now rebuilt. Check if we should reboot now.
+#
+REBOOT=0
+echo "$N: You must reboot before patch takes effect. Reboot now? \c"
+read RESP
+case ${RESP} in
+ [yY]*)
+ REBOOT=1
+ ;;
+ *)
+ echo "$N: OK. But remember to reboot later"
+ ;;
+esac
+
+cd ${OWD}
+rm -rf ${BKUP}
+#
+# All done. Reboot if necessary
+#
+if [ ${REBOOT} = "1" ]
+then
+ cd /
+ sync
+ /usr/sbin/shutdown -i6 -g15 -y &
+fi
+exit 0
+######################################################################
diff --git a/xc/programs/Xserver/hw/xfree86/etc/vesamodes b/xc/programs/Xserver/hw/xfree86/etc/vesamodes
new file mode 100644
index 000000000..9448b16ac
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/vesamodes
@@ -0,0 +1,109 @@
+//
+// Default modes from the late 1998 revision of the VESA standard
+//
+// $XFree86: xc/programs/Xserver/hw/xfree86/etc/vesamodes,v 1.2 1999/03/29 13:17:08 dawes Exp $
+
+
+# 640x350 @ 85Hz (VESA) hsync: 37.9kHz
+ModeLine "640x350" 31.5 640 672 736 832 350 382 385 445
+
+# 640x400 @ 85Hz (VESA) hsync: 37.9kHz
+ModeLine "640x400" 31.5 640 672 736 832 400 401 404 445
+
+# 720x400 @ 85Hz (VESA) hsync: 37.9kHz
+ModeLine "720x400" 35.5 720 756 828 936 400 401 404 446
+
+# 640x480 @ 60Hz (Industry standard) hsync: 31.5kHz
+ModeLine "640x480" 25.2 640 656 752 800 480 490 492 525
+
+# 640x480 @ 72Hz (VESA) hsync: 37.9kHz
+ModeLine "640x480" 31.5 640 664 704 832 480 489 491 520
+
+# 640x480 @ 75Hz (VESA) hsync: 37.5kHz
+ModeLine "640x480" 31.5 640 656 720 840 480 481 484 500
+
+# 640x480 @ 85Hz (VESA) hsync: 43.3kHz
+ModeLine "640x480" 36.0 640 696 752 832 480 481 484 509
+
+# 800x600 @ 56Hz (VESA) hsync: 35.2kHz
+ModeLine "800x600" 36.0 800 824 896 1024 600 601 603 625
+
+# 800x600 @ 60Hz (VESA) hsync: 37.9kHz
+ModeLine "800x600" 40.0 800 840 968 1056 600 601 605 628
+
+# 800x600 @ 72Hz (VESA) hsync: 48.1kHz
+ModeLine "800x600" 50.0 800 856 976 1040 600 637 643 666
+
+# 800x600 @ 75Hz (VESA) hsync: 46.9kHz
+ModeLine "800x600" 49.5 800 816 896 1056 600 601 604 625
+
+# 800x600 @ 85Hz (VESA) hsync: 53.7kHz
+ModeLine "800x600" 56.3 800 832 896 1048 600 601 604 631
+
+# 1024x768i @ 43Hz (industry standard) hsync: 35.5kHz
+ModeLine "1024x768" 44.9 1024 1032 1208 1264 768 768 776 817 Interlace
+
+# 1024x768 @ 60Hz (VESA) hsync: 48.4kHz
+ModeLine "1024x768" 65.0 1024 1048 1184 1344 768 771 777 806
+
+# 1024x768 @ 70Hz (VESA) hsync: 56.5kHz
+ModeLine "1024x768" 75.0 1024 1048 1184 1328 768 771 777 806
+
+# 1024x768 @ 75Hz (VESA) hsync: 60.0kHz
+ModeLine "1024x768" 78.8 1024 1040 1136 1312 768 769 772 800
+
+# 1024x768 @ 85Hz (VESA) hsync: 68.7kHz
+ModeLine "1024x768" 94.5 1024 1072 1168 1376 768 769 772 808
+
+# 1152x864 @ 75Hz (VESA) hsync: 67.5kHz
+ModeLine "1152x864" 108.0 1152 1216 1344 1600 864 865 868 900
+
+# 1280x960 @ 60Hz (VESA) hsync: 60.0kHz
+ModeLine "1280x960" 108.0 1280 1376 1488 1800 960 961 964 1000
+
+# 1280x960 @ 85Hz (VESA) hsync: 85.9kHz
+ModeLine "1280x960" 148.5 1280 1344 1504 1728 960 961 964 1011
+
+# 1280x1024 @ 60Hz (VESA) hsync: 64.0kHz
+ModeLine "1280x1024" 108.0 1280 1328 1440 1688 1024 1025 1028 1066
+
+# 1280x1024 @ 75Hz (VESA) hsync: 80.0kHz
+ModeLine "1280x1024" 135.0 1280 1296 1440 1688 1024 1025 1028 1066
+
+# 1280x1024 @ 85Hz (VESA) hsync: 91.1kHz
+ModeLine "1280x1024" 157.5 1280 1344 1504 1728 1024 1025 1028 1072
+
+# 1600x1200 @ 60Hz (VESA) hsync: 75.0kHz
+ModeLine "1600x1200" 162.0 1600 1664 1856 2160 1200 1201 1204 1250
+
+# 1600x1200 @ 65Hz (VESA) hsync: 81.3kHz
+ModeLine "1600x1200" 175.5 1600 1664 1856 2160 1200 1201 1204 1250
+
+# 1600x1200 @ 70Hz (VESA) hsync: 87.5kHz
+ModeLine "1600x1200" 189.0 1600 1664 1856 2160 1200 1201 1204 1250
+
+# 1600x1200 @ 75Hz (VESA) hsync: 93.8kHz
+ModeLine "1600x1200" 202.5 1600 1664 1856 2160 1200 1201 1204 1250
+
+# 1600x1200 @ 85Hz (VESA) hsync: 106.3kHz
+ModeLine "1600x1200" 229.5 1600 1664 1856 2160 1200 1201 1204 1250
+
+# 1792x1344 @ 60Hz (VESA) hsync: 83.6kHz
+ModeLine "1792x1344" 204.8 1792 1920 2120 2448 1344 1345 1348 1394
+
+# 1792x1344 @ 75Hz (VESA) hsync: 106.3kHz
+ModeLine "1792x1344" 261.0 1792 1888 2104 2456 1344 1345 1348 1417
+
+# 1856x1392 @ 60Hz (VESA) hsync: 86.3kHz
+ModeLine "1856x1392" 218.3 1856 1952 2176 2528 1392 1393 1396 1439
+
+# 1856x1392 @ 75Hz (VESA) hsync: 112.5kHz
+ModeLine "1856x1392" 288.0 1856 1984 2208 2560 1392 1393 1396 1500
+
+# 1920x1440 @ 60Hz (VESA) hsync: 90.0kHz
+ModeLine "1920x1444" 234.0 1920 2048 2256 2600 1440 1441 1444 1500
+
+# 1920x1440 @ 75Hz (VESA) hsync: 112.5kHz
+ModeLine "1920x1444" 297.0 1920 2064 2288 2640 1440 1441 1444 1500
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/etc/vga.bdf b/xc/programs/Xserver/hw/xfree86/etc/vga.bdf
new file mode 100644
index 000000000..1a20c6e12
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/vga.bdf
@@ -0,0 +1,5906 @@
+COMMENT $XFree86: xc/programs/Xserver/hw/xfree86/etc/vga.bdf,v 3.2 1996/12/23 06:47:25 dawes Exp $
+COMMENT
+COMMENT
+COMMENT vga
+COMMENT
+COMMENT
+COMMENT $XConsortium: vga.bdf /main/4 1996/02/21 17:48:43 kaleb $
+STARTFONT 2.1
+FONT vga
+SIZE 16 75 75
+FONTBOUNDINGBOX 8 16 0 -4
+STARTPROPERTIES 3
+FONT_DESCENT 4
+FONT_ASCENT 12
+DEFAULT_CHAR 0
+ENDPROPERTIES
+CHARS 256
+STARTCHAR C0000
+ENCODING 0
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+7c
+c6
+c6
+de
+de
+de
+dc
+c0
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0001
+ENCODING 1
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+7e
+81
+a5
+81
+81
+a5
+99
+81
+81
+7e
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0002
+ENCODING 2
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+7e
+ff
+db
+ff
+ff
+db
+e7
+ff
+ff
+7e
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0003
+ENCODING 3
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+6c
+fe
+fe
+fe
+fe
+7c
+38
+10
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0004
+ENCODING 4
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+10
+38
+7c
+fe
+7c
+38
+10
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0005
+ENCODING 5
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+18
+3c
+3c
+e7
+e7
+e7
+18
+18
+3c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0006
+ENCODING 6
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+18
+3c
+7e
+ff
+ff
+7e
+18
+18
+3c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0007
+ENCODING 7
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+18
+3c
+3c
+18
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0008
+ENCODING 8
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+ff
+ff
+ff
+ff
+ff
+ff
+e7
+c3
+c3
+e7
+ff
+ff
+ff
+ff
+ff
+ff
+ENDCHAR
+STARTCHAR C0009
+ENCODING 9
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+3c
+66
+42
+42
+66
+3c
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C000a
+ENCODING 10
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+ff
+ff
+ff
+ff
+ff
+c3
+99
+bd
+bd
+99
+c3
+ff
+ff
+ff
+ff
+ff
+ENDCHAR
+STARTCHAR C000b
+ENCODING 11
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+1e
+06
+0e
+1a
+78
+cc
+cc
+cc
+cc
+78
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C000c
+ENCODING 12
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+3c
+66
+66
+66
+66
+3c
+18
+7e
+18
+18
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C000d
+ENCODING 13
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+3f
+33
+3f
+30
+30
+30
+30
+70
+f0
+e0
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C000e
+ENCODING 14
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+7f
+63
+7f
+63
+63
+63
+63
+67
+e7
+e6
+c0
+00
+00
+00
+ENDCHAR
+STARTCHAR C000f
+ENCODING 15
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+18
+18
+db
+3c
+e7
+3c
+db
+18
+18
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0010
+ENCODING 16
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+80
+c0
+e0
+f0
+f8
+fe
+f8
+f0
+e0
+c0
+80
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0011
+ENCODING 17
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+02
+06
+0e
+1e
+3e
+fe
+3e
+1e
+0e
+06
+02
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0012
+ENCODING 18
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+18
+3c
+7e
+18
+18
+18
+7e
+3c
+18
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0013
+ENCODING 19
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+66
+66
+66
+66
+66
+66
+66
+00
+66
+66
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0014
+ENCODING 20
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+7f
+db
+db
+db
+7b
+1b
+1b
+1b
+1b
+1b
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0015
+ENCODING 21
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+7c
+c6
+60
+38
+6c
+c6
+c6
+6c
+38
+0c
+c6
+7c
+00
+00
+00
+ENDCHAR
+STARTCHAR C0016
+ENCODING 22
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+00
+00
+fe
+fe
+fe
+fe
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0017
+ENCODING 23
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+18
+3c
+7e
+18
+18
+18
+7e
+3c
+18
+7e
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0018
+ENCODING 24
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+18
+3c
+7e
+18
+18
+18
+18
+18
+18
+18
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0019
+ENCODING 25
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+18
+18
+18
+18
+18
+18
+18
+7e
+3c
+18
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C001a
+ENCODING 26
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+18
+0c
+fe
+0c
+18
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C001b
+ENCODING 27
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+30
+60
+fe
+60
+30
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C001c
+ENCODING 28
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+c0
+c0
+c0
+fe
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C001d
+ENCODING 29
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+28
+6c
+fe
+6c
+28
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C001e
+ENCODING 30
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+10
+38
+38
+7c
+7c
+fe
+fe
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C001f
+ENCODING 31
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+fe
+fe
+7c
+7c
+38
+38
+10
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0020
+ENCODING 32
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0021
+ENCODING 33
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+18
+3c
+3c
+3c
+18
+18
+18
+00
+18
+18
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0022
+ENCODING 34
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+66
+66
+66
+24
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0023
+ENCODING 35
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+6c
+6c
+fe
+6c
+6c
+6c
+fe
+6c
+6c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0024
+ENCODING 36
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+18
+18
+7c
+c6
+c2
+c0
+7c
+06
+06
+86
+c6
+7c
+18
+18
+00
+00
+ENDCHAR
+STARTCHAR C0025
+ENCODING 37
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+c2
+c6
+0c
+18
+30
+60
+c6
+86
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0026
+ENCODING 38
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+38
+6c
+6c
+38
+76
+dc
+cc
+cc
+cc
+76
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0027
+ENCODING 39
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+30
+30
+30
+60
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0028
+ENCODING 40
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+0c
+18
+30
+30
+30
+30
+30
+30
+18
+0c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0029
+ENCODING 41
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+30
+18
+0c
+0c
+0c
+0c
+0c
+0c
+18
+30
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C002a
+ENCODING 42
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+66
+3c
+ff
+3c
+66
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C002b
+ENCODING 43
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+18
+18
+7e
+18
+18
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C002c
+ENCODING 44
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+00
+00
+00
+18
+18
+18
+30
+00
+00
+00
+ENDCHAR
+STARTCHAR C002d
+ENCODING 45
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+00
+fe
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C002e
+ENCODING 46
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+18
+18
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C002f
+ENCODING 47
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+02
+06
+0c
+18
+30
+60
+c0
+80
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0030
+ENCODING 48
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+38
+6c
+c6
+c6
+d6
+d6
+c6
+c6
+6c
+38
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0031
+ENCODING 49
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+18
+38
+78
+18
+18
+18
+18
+18
+18
+7e
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0032
+ENCODING 50
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+7c
+c6
+06
+0c
+18
+30
+60
+c0
+c6
+fe
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0033
+ENCODING 51
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+7c
+c6
+06
+06
+3c
+06
+06
+06
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0034
+ENCODING 52
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+0c
+1c
+3c
+6c
+cc
+fe
+0c
+0c
+0c
+1e
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0035
+ENCODING 53
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+fe
+c0
+c0
+c0
+fc
+06
+06
+06
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0036
+ENCODING 54
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+38
+60
+c0
+c0
+fc
+c6
+c6
+c6
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0037
+ENCODING 55
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+fe
+c6
+06
+06
+0c
+18
+30
+30
+30
+30
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0038
+ENCODING 56
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+7c
+c6
+c6
+c6
+7c
+c6
+c6
+c6
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0039
+ENCODING 57
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+7c
+c6
+c6
+c6
+7e
+06
+06
+06
+0c
+78
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C003a
+ENCODING 58
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+18
+18
+00
+00
+00
+18
+18
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C003b
+ENCODING 59
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+18
+18
+00
+00
+00
+18
+18
+30
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C003c
+ENCODING 60
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+06
+0c
+18
+30
+60
+30
+18
+0c
+06
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C003d
+ENCODING 61
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+7e
+00
+00
+7e
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C003e
+ENCODING 62
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+60
+30
+18
+0c
+06
+0c
+18
+30
+60
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C003f
+ENCODING 63
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+7c
+c6
+c6
+0c
+18
+18
+18
+00
+18
+18
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0040
+ENCODING 64
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+7c
+c6
+c6
+de
+de
+de
+dc
+c0
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0041
+ENCODING 65
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+10
+38
+6c
+c6
+c6
+fe
+c6
+c6
+c6
+c6
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0042
+ENCODING 66
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+fc
+66
+66
+66
+7c
+66
+66
+66
+66
+fc
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0043
+ENCODING 67
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+3c
+66
+c2
+c0
+c0
+c0
+c0
+c2
+66
+3c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0044
+ENCODING 68
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+f8
+6c
+66
+66
+66
+66
+66
+66
+6c
+f8
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0045
+ENCODING 69
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+fe
+66
+62
+68
+78
+68
+60
+62
+66
+fe
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0046
+ENCODING 70
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+fe
+66
+62
+68
+78
+68
+60
+60
+60
+f0
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0047
+ENCODING 71
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+3c
+66
+c2
+c0
+c0
+de
+c6
+c6
+66
+3a
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0048
+ENCODING 72
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+c6
+c6
+c6
+c6
+fe
+c6
+c6
+c6
+c6
+c6
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0049
+ENCODING 73
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+3c
+18
+18
+18
+18
+18
+18
+18
+18
+3c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C004a
+ENCODING 74
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+1e
+0c
+0c
+0c
+0c
+0c
+cc
+cc
+cc
+78
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C004b
+ENCODING 75
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+e6
+66
+66
+6c
+78
+78
+6c
+66
+66
+e6
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C004c
+ENCODING 76
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+f0
+60
+60
+60
+60
+60
+60
+62
+66
+fe
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C004d
+ENCODING 77
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+c6
+ee
+fe
+fe
+d6
+c6
+c6
+c6
+c6
+c6
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C004e
+ENCODING 78
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+c6
+e6
+f6
+fe
+de
+ce
+c6
+c6
+c6
+c6
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C004f
+ENCODING 79
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+7c
+c6
+c6
+c6
+c6
+c6
+c6
+c6
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0050
+ENCODING 80
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+fc
+66
+66
+66
+7c
+60
+60
+60
+60
+f0
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0051
+ENCODING 81
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+7c
+c6
+c6
+c6
+c6
+c6
+c6
+d6
+de
+7c
+0c
+0e
+00
+00
+ENDCHAR
+STARTCHAR C0052
+ENCODING 82
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+fc
+66
+66
+66
+7c
+6c
+66
+66
+66
+e6
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0053
+ENCODING 83
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+7c
+c6
+c6
+60
+38
+0c
+06
+c6
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0054
+ENCODING 84
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+7e
+7e
+5a
+18
+18
+18
+18
+18
+18
+3c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0055
+ENCODING 85
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+c6
+c6
+c6
+c6
+c6
+c6
+c6
+c6
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0056
+ENCODING 86
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+c6
+c6
+c6
+c6
+c6
+c6
+c6
+6c
+38
+10
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0057
+ENCODING 87
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+c6
+c6
+c6
+c6
+d6
+d6
+d6
+fe
+ee
+6c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0058
+ENCODING 88
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+c6
+c6
+6c
+7c
+38
+38
+7c
+6c
+c6
+c6
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0059
+ENCODING 89
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+66
+66
+66
+66
+3c
+18
+18
+18
+18
+3c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C005a
+ENCODING 90
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+fe
+c6
+86
+0c
+18
+30
+60
+c2
+c6
+fe
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C005b
+ENCODING 91
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+3c
+30
+30
+30
+30
+30
+30
+30
+30
+3c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C005c
+ENCODING 92
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+80
+c0
+e0
+70
+38
+1c
+0e
+06
+02
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C005d
+ENCODING 93
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+3c
+0c
+0c
+0c
+0c
+0c
+0c
+0c
+0c
+3c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C005e
+ENCODING 94
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+10
+38
+6c
+c6
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C005f
+ENCODING 95
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+ff
+00
+00
+ENDCHAR
+STARTCHAR C0060
+ENCODING 96
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+30
+30
+18
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0061
+ENCODING 97
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+78
+0c
+7c
+cc
+cc
+cc
+76
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0062
+ENCODING 98
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+e0
+60
+60
+78
+6c
+66
+66
+66
+66
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0063
+ENCODING 99
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+7c
+c6
+c0
+c0
+c0
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0064
+ENCODING 100
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+1c
+0c
+0c
+3c
+6c
+cc
+cc
+cc
+cc
+76
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0065
+ENCODING 101
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+7c
+c6
+fe
+c0
+c0
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0066
+ENCODING 102
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+38
+6c
+64
+60
+f0
+60
+60
+60
+60
+f0
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0067
+ENCODING 103
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+76
+cc
+cc
+cc
+cc
+cc
+7c
+0c
+cc
+78
+00
+ENDCHAR
+STARTCHAR C0068
+ENCODING 104
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+e0
+60
+60
+6c
+76
+66
+66
+66
+66
+e6
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0069
+ENCODING 105
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+18
+18
+00
+38
+18
+18
+18
+18
+18
+3c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C006a
+ENCODING 106
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+06
+06
+00
+0e
+06
+06
+06
+06
+06
+06
+66
+66
+3c
+00
+ENDCHAR
+STARTCHAR C006b
+ENCODING 107
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+e0
+60
+60
+66
+6c
+78
+78
+6c
+66
+e6
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C006c
+ENCODING 108
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+38
+18
+18
+18
+18
+18
+18
+18
+18
+3c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C006d
+ENCODING 109
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+ec
+fe
+d6
+d6
+d6
+d6
+c6
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C006e
+ENCODING 110
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+dc
+66
+66
+66
+66
+66
+66
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C006f
+ENCODING 111
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+7c
+c6
+c6
+c6
+c6
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0070
+ENCODING 112
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+dc
+66
+66
+66
+66
+66
+7c
+60
+60
+f0
+00
+ENDCHAR
+STARTCHAR C0071
+ENCODING 113
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+76
+cc
+cc
+cc
+cc
+cc
+7c
+0c
+0c
+1e
+00
+ENDCHAR
+STARTCHAR C0072
+ENCODING 114
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+dc
+76
+66
+60
+60
+60
+f0
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0073
+ENCODING 115
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+7c
+c6
+60
+38
+0c
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0074
+ENCODING 116
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+10
+30
+30
+fc
+30
+30
+30
+30
+36
+1c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0075
+ENCODING 117
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+cc
+cc
+cc
+cc
+cc
+cc
+76
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0076
+ENCODING 118
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+66
+66
+66
+66
+66
+3c
+18
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0077
+ENCODING 119
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+c6
+c6
+d6
+d6
+d6
+fe
+6c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0078
+ENCODING 120
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+c6
+6c
+38
+38
+38
+6c
+c6
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0079
+ENCODING 121
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+c6
+c6
+c6
+c6
+c6
+c6
+7e
+06
+0c
+f8
+00
+ENDCHAR
+STARTCHAR C007a
+ENCODING 122
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+fe
+cc
+18
+30
+60
+c6
+fe
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C007b
+ENCODING 123
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+0e
+18
+18
+18
+70
+18
+18
+18
+18
+0e
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C007c
+ENCODING 124
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+18
+18
+18
+18
+00
+18
+18
+18
+18
+18
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C007d
+ENCODING 125
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+70
+18
+18
+18
+0e
+18
+18
+18
+18
+70
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C007e
+ENCODING 126
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+76
+dc
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C007f
+ENCODING 127
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+10
+38
+6c
+c6
+c6
+c6
+fe
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0080
+ENCODING 128
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+3c
+66
+c2
+c0
+c0
+c0
+c2
+66
+3c
+0c
+06
+7c
+00
+00
+ENDCHAR
+STARTCHAR C0081
+ENCODING 129
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+cc
+00
+00
+cc
+cc
+cc
+cc
+cc
+cc
+76
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0082
+ENCODING 130
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+0c
+18
+30
+00
+7c
+c6
+fe
+c0
+c0
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0083
+ENCODING 131
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+10
+38
+6c
+00
+78
+0c
+7c
+cc
+cc
+cc
+76
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0084
+ENCODING 132
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+cc
+00
+00
+78
+0c
+7c
+cc
+cc
+cc
+76
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0085
+ENCODING 133
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+60
+30
+18
+00
+78
+0c
+7c
+cc
+cc
+cc
+76
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0086
+ENCODING 134
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+38
+6c
+38
+00
+78
+0c
+7c
+cc
+cc
+cc
+76
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0087
+ENCODING 135
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+3c
+66
+60
+60
+66
+3c
+0c
+06
+3c
+00
+00
+00
+ENDCHAR
+STARTCHAR C0088
+ENCODING 136
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+10
+38
+6c
+00
+7c
+c6
+fe
+c0
+c0
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0089
+ENCODING 137
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+c6
+00
+00
+7c
+c6
+fe
+c0
+c0
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C008a
+ENCODING 138
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+60
+30
+18
+00
+7c
+c6
+fe
+c0
+c0
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C008b
+ENCODING 139
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+66
+00
+00
+38
+18
+18
+18
+18
+18
+3c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C008c
+ENCODING 140
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+18
+3c
+66
+00
+38
+18
+18
+18
+18
+18
+3c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C008d
+ENCODING 141
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+60
+30
+18
+00
+38
+18
+18
+18
+18
+18
+3c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C008e
+ENCODING 142
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+c6
+00
+10
+38
+6c
+c6
+c6
+fe
+c6
+c6
+c6
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C008f
+ENCODING 143
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+38
+6c
+38
+00
+38
+6c
+c6
+c6
+fe
+c6
+c6
+c6
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0090
+ENCODING 144
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+18
+30
+60
+00
+fe
+66
+60
+7c
+60
+60
+66
+fe
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0091
+ENCODING 145
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+cc
+76
+36
+7e
+d8
+d8
+6e
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0092
+ENCODING 146
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+3e
+6c
+cc
+cc
+fe
+cc
+cc
+cc
+cc
+ce
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0093
+ENCODING 147
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+10
+38
+6c
+00
+7c
+c6
+c6
+c6
+c6
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0094
+ENCODING 148
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+c6
+00
+00
+7c
+c6
+c6
+c6
+c6
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0095
+ENCODING 149
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+60
+30
+18
+00
+7c
+c6
+c6
+c6
+c6
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0096
+ENCODING 150
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+30
+78
+cc
+00
+cc
+cc
+cc
+cc
+cc
+cc
+76
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0097
+ENCODING 151
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+60
+30
+18
+00
+cc
+cc
+cc
+cc
+cc
+cc
+76
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C0098
+ENCODING 152
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+c6
+00
+00
+c6
+c6
+c6
+c6
+c6
+c6
+7e
+06
+0c
+78
+00
+ENDCHAR
+STARTCHAR C0099
+ENCODING 153
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+c6
+00
+7c
+c6
+c6
+c6
+c6
+c6
+c6
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C009a
+ENCODING 154
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+c6
+00
+c6
+c6
+c6
+c6
+c6
+c6
+c6
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C009b
+ENCODING 155
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+18
+18
+3c
+66
+60
+60
+60
+66
+3c
+18
+18
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C009c
+ENCODING 156
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+38
+6c
+64
+60
+f0
+60
+60
+60
+60
+e6
+fc
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C009d
+ENCODING 157
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+66
+66
+3c
+18
+7e
+18
+7e
+18
+18
+18
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C009e
+ENCODING 158
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+f8
+cc
+cc
+f8
+c4
+cc
+de
+cc
+cc
+cc
+c6
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C009f
+ENCODING 159
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+0e
+1b
+18
+18
+18
+7e
+18
+18
+18
+18
+18
+d8
+70
+00
+00
+ENDCHAR
+STARTCHAR C00a0
+ENCODING 160
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+18
+30
+60
+00
+78
+0c
+7c
+cc
+cc
+cc
+76
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00a1
+ENCODING 161
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+0c
+18
+30
+00
+38
+18
+18
+18
+18
+18
+3c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00a2
+ENCODING 162
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+18
+30
+60
+00
+7c
+c6
+c6
+c6
+c6
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00a3
+ENCODING 163
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+18
+30
+60
+00
+cc
+cc
+cc
+cc
+cc
+cc
+76
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00a4
+ENCODING 164
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+76
+dc
+00
+dc
+66
+66
+66
+66
+66
+66
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00a5
+ENCODING 165
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+76
+dc
+00
+c6
+e6
+f6
+fe
+de
+ce
+c6
+c6
+c6
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00a6
+ENCODING 166
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+3c
+6c
+6c
+3e
+00
+7e
+00
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00a7
+ENCODING 167
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+38
+6c
+6c
+38
+00
+7c
+00
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00a8
+ENCODING 168
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+30
+30
+00
+30
+30
+60
+c0
+c6
+c6
+7c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00a9
+ENCODING 169
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+fe
+c0
+c0
+c0
+c0
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00aa
+ENCODING 170
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+fe
+06
+06
+06
+06
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00ab
+ENCODING 171
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+c0
+c0
+c2
+c6
+cc
+18
+30
+60
+dc
+86
+0c
+18
+3e
+00
+00
+ENDCHAR
+STARTCHAR C00ac
+ENCODING 172
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+c0
+c0
+c2
+c6
+cc
+18
+30
+66
+ce
+9e
+3e
+06
+06
+00
+00
+ENDCHAR
+STARTCHAR C00ad
+ENCODING 173
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+18
+18
+00
+18
+18
+18
+3c
+3c
+3c
+18
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00ae
+ENCODING 174
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+36
+6c
+d8
+6c
+36
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00af
+ENCODING 175
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+d8
+6c
+36
+6c
+d8
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00b0
+ENCODING 176
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+11
+44
+11
+44
+11
+44
+11
+44
+11
+44
+11
+44
+11
+44
+11
+44
+ENDCHAR
+STARTCHAR C00b1
+ENCODING 177
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+55
+aa
+55
+aa
+55
+aa
+55
+aa
+55
+aa
+55
+aa
+55
+aa
+55
+aa
+ENDCHAR
+STARTCHAR C00b2
+ENCODING 178
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+dd
+77
+dd
+77
+dd
+77
+dd
+77
+dd
+77
+dd
+77
+dd
+77
+dd
+77
+ENDCHAR
+STARTCHAR C00b3
+ENCODING 179
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+18
+18
+18
+18
+18
+18
+18
+18
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR C00b4
+ENCODING 180
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+18
+18
+18
+18
+18
+18
+18
+f8
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR C00b5
+ENCODING 181
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+18
+18
+18
+18
+18
+f8
+18
+f8
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR C00b6
+ENCODING 182
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+36
+36
+36
+36
+36
+36
+36
+f6
+36
+36
+36
+36
+36
+36
+36
+36
+ENDCHAR
+STARTCHAR C00b7
+ENCODING 183
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+00
+fe
+36
+36
+36
+36
+36
+36
+36
+36
+ENDCHAR
+STARTCHAR C00b8
+ENCODING 184
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+f8
+18
+f8
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR C00b9
+ENCODING 185
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+36
+36
+36
+36
+36
+f6
+06
+f6
+36
+36
+36
+36
+36
+36
+36
+36
+ENDCHAR
+STARTCHAR C00ba
+ENCODING 186
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+36
+36
+36
+36
+36
+36
+36
+36
+36
+36
+36
+36
+36
+36
+36
+36
+ENDCHAR
+STARTCHAR C00bb
+ENCODING 187
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+fe
+06
+f6
+36
+36
+36
+36
+36
+36
+36
+36
+ENDCHAR
+STARTCHAR C00bc
+ENCODING 188
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+36
+36
+36
+36
+36
+f6
+06
+fe
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00bd
+ENCODING 189
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+36
+36
+36
+36
+36
+36
+36
+fe
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00be
+ENCODING 190
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+18
+18
+18
+18
+18
+f8
+18
+f8
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00bf
+ENCODING 191
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+00
+f8
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR C00c0
+ENCODING 192
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+18
+18
+18
+18
+18
+18
+18
+1f
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00c1
+ENCODING 193
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+18
+18
+18
+18
+18
+18
+18
+ff
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00c2
+ENCODING 194
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+00
+ff
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR C00c3
+ENCODING 195
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+18
+18
+18
+18
+18
+18
+18
+1f
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR C00c4
+ENCODING 196
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+00
+ff
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00c5
+ENCODING 197
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+18
+18
+18
+18
+18
+18
+18
+ff
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR C00c6
+ENCODING 198
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+18
+18
+18
+18
+18
+1f
+18
+1f
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR C00c7
+ENCODING 199
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+36
+36
+36
+36
+36
+36
+36
+37
+36
+36
+36
+36
+36
+36
+36
+36
+ENDCHAR
+STARTCHAR C00c8
+ENCODING 200
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+36
+36
+36
+36
+36
+37
+30
+3f
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00c9
+ENCODING 201
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+3f
+30
+37
+36
+36
+36
+36
+36
+36
+36
+36
+ENDCHAR
+STARTCHAR C00ca
+ENCODING 202
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+36
+36
+36
+36
+36
+f7
+00
+ff
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00cb
+ENCODING 203
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+ff
+00
+f7
+36
+36
+36
+36
+36
+36
+36
+36
+ENDCHAR
+STARTCHAR C00cc
+ENCODING 204
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+36
+36
+36
+36
+36
+37
+30
+37
+36
+36
+36
+36
+36
+36
+36
+36
+ENDCHAR
+STARTCHAR C00cd
+ENCODING 205
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+ff
+00
+ff
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00ce
+ENCODING 206
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+36
+36
+36
+36
+36
+f7
+00
+f7
+36
+36
+36
+36
+36
+36
+36
+36
+ENDCHAR
+STARTCHAR C00cf
+ENCODING 207
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+18
+18
+18
+18
+18
+ff
+00
+ff
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00d0
+ENCODING 208
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+36
+36
+36
+36
+36
+36
+36
+ff
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00d1
+ENCODING 209
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+ff
+00
+ff
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR C00d2
+ENCODING 210
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+00
+ff
+36
+36
+36
+36
+36
+36
+36
+36
+ENDCHAR
+STARTCHAR C00d3
+ENCODING 211
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+36
+36
+36
+36
+36
+36
+36
+3f
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00d4
+ENCODING 212
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+18
+18
+18
+18
+18
+1f
+18
+1f
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00d5
+ENCODING 213
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+1f
+18
+1f
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR C00d6
+ENCODING 214
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+00
+3f
+36
+36
+36
+36
+36
+36
+36
+36
+ENDCHAR
+STARTCHAR C00d7
+ENCODING 215
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+36
+36
+36
+36
+36
+36
+36
+ff
+36
+36
+36
+36
+36
+36
+36
+36
+ENDCHAR
+STARTCHAR C00d8
+ENCODING 216
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+18
+18
+18
+18
+18
+ff
+18
+ff
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR C00d9
+ENCODING 217
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+18
+18
+18
+18
+18
+18
+18
+f8
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00da
+ENCODING 218
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+00
+1f
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR C00db
+ENCODING 219
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+ff
+ff
+ff
+ff
+ff
+ff
+ff
+ff
+ff
+ff
+ff
+ff
+ff
+ff
+ff
+ff
+ENDCHAR
+STARTCHAR C00dc
+ENCODING 220
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+00
+ff
+ff
+ff
+ff
+ff
+ff
+ff
+ff
+ff
+ENDCHAR
+STARTCHAR C00dd
+ENCODING 221
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+f0
+f0
+f0
+f0
+f0
+f0
+f0
+f0
+f0
+f0
+f0
+f0
+f0
+f0
+f0
+f0
+ENDCHAR
+STARTCHAR C00de
+ENCODING 222
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+0f
+0f
+0f
+0f
+0f
+0f
+0f
+0f
+0f
+0f
+0f
+0f
+0f
+0f
+0f
+0f
+ENDCHAR
+STARTCHAR C00df
+ENCODING 223
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+ff
+ff
+ff
+ff
+ff
+ff
+ff
+00
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00e0
+ENCODING 224
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+76
+dc
+d8
+d8
+d8
+dc
+76
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00e1
+ENCODING 225
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+78
+cc
+cc
+cc
+d8
+cc
+c6
+c6
+c6
+cc
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00e2
+ENCODING 226
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+fe
+c6
+c6
+c0
+c0
+c0
+c0
+c0
+c0
+c0
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00e3
+ENCODING 227
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+fe
+6c
+6c
+6c
+6c
+6c
+6c
+6c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00e4
+ENCODING 228
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+fe
+c6
+60
+30
+18
+30
+60
+c6
+fe
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00e5
+ENCODING 229
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+7e
+d8
+d8
+d8
+d8
+d8
+70
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00e6
+ENCODING 230
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+66
+66
+66
+66
+66
+7c
+60
+60
+c0
+00
+00
+00
+ENDCHAR
+STARTCHAR C00e7
+ENCODING 231
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+76
+dc
+18
+18
+18
+18
+18
+18
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00e8
+ENCODING 232
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+7e
+18
+3c
+66
+66
+66
+3c
+18
+7e
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00e9
+ENCODING 233
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+38
+6c
+c6
+c6
+fe
+c6
+c6
+6c
+38
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00ea
+ENCODING 234
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+38
+6c
+c6
+c6
+c6
+6c
+6c
+6c
+6c
+ee
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00eb
+ENCODING 235
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+1e
+30
+18
+0c
+3e
+66
+66
+66
+66
+3c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00ec
+ENCODING 236
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+7e
+db
+db
+db
+7e
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00ed
+ENCODING 237
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+03
+06
+7e
+db
+db
+f3
+7e
+60
+c0
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00ee
+ENCODING 238
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+1c
+30
+60
+60
+7c
+60
+60
+60
+30
+1c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00ef
+ENCODING 239
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+7c
+c6
+c6
+c6
+c6
+c6
+c6
+c6
+c6
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00f0
+ENCODING 240
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+fe
+00
+00
+fe
+00
+00
+fe
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00f1
+ENCODING 241
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+18
+18
+7e
+18
+18
+00
+00
+ff
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00f2
+ENCODING 242
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+30
+18
+0c
+06
+0c
+18
+30
+00
+7e
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00f3
+ENCODING 243
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+0c
+18
+30
+60
+30
+18
+0c
+00
+7e
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00f4
+ENCODING 244
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+0e
+1b
+1b
+18
+18
+18
+18
+18
+18
+18
+18
+18
+18
+18
+ENDCHAR
+STARTCHAR C00f5
+ENCODING 245
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+18
+18
+18
+18
+18
+18
+18
+18
+d8
+d8
+d8
+70
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00f6
+ENCODING 246
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+18
+18
+00
+7e
+00
+18
+18
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00f7
+ENCODING 247
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+76
+dc
+00
+76
+dc
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00f8
+ENCODING 248
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+38
+6c
+6c
+38
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00f9
+ENCODING 249
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+00
+18
+18
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00fa
+ENCODING 250
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+00
+00
+18
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00fb
+ENCODING 251
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+0f
+0c
+0c
+0c
+0c
+0c
+ec
+6c
+6c
+3c
+1c
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00fc
+ENCODING 252
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+d8
+6c
+6c
+6c
+6c
+6c
+00
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00fd
+ENCODING 253
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+70
+d8
+30
+60
+c8
+f8
+00
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00fe
+ENCODING 254
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+7c
+7c
+7c
+7c
+7c
+7c
+7c
+00
+00
+00
+00
+00
+ENDCHAR
+STARTCHAR C00ff
+ENCODING 255
+SWIDTH 666 0
+DWIDTH 8 0
+BBX 8 16 0 -4
+BITMAP
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+00
+ENDCHAR
+ENDFONT
diff --git a/xc/programs/Xserver/hw/xfree86/etc/xcode.xfree86 b/xc/programs/Xserver/hw/xfree86/etc/xcode.xfree86
new file mode 100644
index 000000000..a8b6f1ec4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/xcode.xfree86
@@ -0,0 +1,219 @@
+# SCCSID(@(#)xcode.table 1.2 LCC) Modified 12:29:54 6/6/91
+#
+# MODIFIED FOR XFREE86 - David Wexelblat <dwex@goblin.org>, May 15, 1993
+#
+# $XFree86: xc/programs/Xserver/hw/xfree86/etc/xcode.xfree86,v 3.2 1996/12/23 06:47:26 dawes Exp $
+#
+# Keycode to keynumber table for use by XCRT.
+# This table is for use with the Xsight X-Window server.
+#
+# There must be a different version of this table for each supported
+# X-server.
+#
+# $XConsortium: xcode.xfree86 /main/4 1996/02/21 17:48:48 kaleb $
+#
+# Keycodes are the internal key identifiers that the X server uses.
+# Keynumbers are the internal key identifiers that Merge uses, and they
+# are the same as the key numbering scheme in the the PC keyboard Tech
+# Reference with one exception. This exception is key number 42. This
+# key is electrically the same as key 29, so we only use number 29.
+#
+# In this table only the first two fields, the keycode and keynumber
+# fields, are used by Merge.
+#
+# The other two fields, the keysym and keylabel fields, are not used
+# and are only given as an aid to the person reading the list.
+# The keysym is what you get with the US English keyboard when no shifts
+# are active, when using the SCO Xsight server. The keylabel field has
+# the name of the corresponding U.S. English keyboard keys.
+#
+# Note: This table is based on the 101/102 key keyboard.
+# On 101 key keyboards, keynumber 45 is not used.
+# The English keyboard is the 101 type. Non-English use the 102 type.
+#
+# Keynumbers range from 1 to 126, although only 102 are used.
+# These are the 24 key numbers that are not used:
+# 14, 42, 56, 59, 63, 65, 66, 67, 68, 69,
+# 70, 71, 72, 73, 74, 77, 78, 82, 87, 88,
+# 94, 107, 109, 111
+# Keycodes can range from 8 to 255, although not all are used.
+#
+# At the end of this file is a picture of the keyboard showing
+# the keynumbers.
+#
+### START OF TABLE ###########################################################
+#
+#keycode
+# keynumber
+# # keysym(hex)
+# # # keylabel
+#### #### ###### #####################
+9. 110. ff1bh esc
+10. 2. 0031h 1
+11. 3. 0032h 2
+12. 4. 0033h 3
+13. 5. 0034h 4
+14. 6. 0035h 5
+15. 7. 0036h 6
+16. 8. 0037h 7
+17. 9. 0038h 8
+18. 10. 0039h 9
+19. 11. 0030h 0
+20. 12. 002dh -
+21. 13. 003dh =
+22. 15. ff08h backspace
+23. 16. ff09h tab
+24. 17. 0071h q
+25. 18. 0077h w
+26. 19. 0065h e
+27. 20. 0072h r
+28. 21. 0074h t
+29. 22. 0079h y
+30. 23. 0075h u
+31. 24. 0069h i
+32. 25. 006fh o
+33. 26. 0070h p
+34. 27. 005bh [
+35. 28. 005dh ]
+36. 43. ff0dh enter
+37. 58. ffe3h leftctrl
+38. 31. 0061h a
+39. 32. 0073h s
+40. 33. 0064h d
+41. 34. 0066h f
+42. 35. 0067h g
+43. 36. 0068h h
+44. 37. 006ah j
+45. 38. 006bh k
+46. 39. 006ch l
+47. 40. 003bh ;
+48. 41. 0027h '
+49. 1. 0060h `
+50. 44. ffe1h leftshift
+51. 29. 005ch backslash
+52. 46. 007ah z
+53. 47. 0078h x
+54. 48. 0063h c
+55. 49. 0076h v
+56. 50. 0062h b
+57. 51. 006eh n
+58. 52. 006dh m
+59. 53. 002ch ,
+60. 54. 002eh .
+61. 55. 002fh /
+62. 57. ffe2h rightshift
+63. 100. ffaah keypad_*
+64. 60. ffe9h leftalt
+65. 61. 0020h space
+66. 30. ffe5h capslock
+67. 112. ffbeh f1
+68. 113. ffbfh f2
+69. 114. ffc0h f3
+70. 115. ffc1h f4
+71. 116. ffc2h f5
+72. 117. ffc3h f6
+73. 118. ffc4h f8
+74. 119. ffc5h f8
+75. 120. ffc6h f9
+76. 121. ffc7h f10
+77. 90. ff7fh numlock
+78. 125. ff13h scrolllock
+79. 91. ffb7h keypad_7_home
+80. 96. ffb8h keypad_8_uparrow
+81. 101. ffb9h keypad_9_pgup
+82. 105. ffadh keypad_-
+83. 92. ffb4h keypad_4_leftarrow
+84. 97. ffb5h keypad_5_center
+85. 102. ffb6h keypad_6_rightarrow
+86. 106. ffabh keypad_+
+87. 93. ffb1h keypad_1_end
+88. 98. ffb2h keypad_2_downarrow
+89. 103. ffb3h keypad_3_pgdown
+90. 99. ffb0h keypad_0_insert
+91. 104. ffaeh keypad_.
+92. 45. 0000h (102nd key. Not used on English keyboard)
+95. 122. ffc8h f11
+96. 123. ffc9h f12
+97. 80. ff50h home
+98. 83. ff52h uparrow
+99. 85. ff55h pageup
+100. 79. ff51h leftarrow
+102. 89. ff53h rightarrow
+103. 81. ff57h end
+104. 84. ff54h downarrow
+105. 86. ff56h pagedown
+106. 75. ff63h insert
+107. 76. ffffh delete
+108. 108. ff8dh keypad_enter
+109. 64. ffe4h rightctrl
+110. 126. ff13h pause_break
+111. 124. ff61h printscreen_sysreq
+112. 95. ffafh keypad_/
+113. 62. ffeah rightalt
+### END OF TABLE ###########################################################
+#
+# The figure below shows the key numbering scheme used by Merge. It is
+# the same numbering scheme used in IBM documentation for the 101 and
+# 102 key keyboards. The key layout in the figure is based on the real
+# IBM keyboard layout. Other keyboards may have the some of the keys
+# in different positions, but the keys operate the same regardless of
+# the actual position.
+#
+# Note: The 101 key keyboards don't use key 45. Key 44 is wider than
+# shown to fill the space where key 45 would be. English keyboards
+# use 101 the type, other languages use the 102 type.
+#
+# Note: Key number 29 is located in only one of the two places shown.
+# When it is above key number 43 (enter), then key 43 is extra wide.
+# When it is to the left key 43, then key 43 is extra tall.
+# In IBM documentation, when key number 29 is to the left of key 43
+# it is listed as key number "42". It is electrically the same
+# regardless of position, so we call it "29" in both cases.
+#
+# ###################################################################
+# #
+# # +---+ +---+---+---+---+ +---+---+---+---+ +---+---+---+---+
+# # |110| |112|113|114|115| |116|117|118|119| |120|121|122|123|
+# # +---+ +---+---+---+---+ +---+---+---+---+ +---+---+---+---+
+# #
+# # +---+---+---+---+---+---+---+---+---+---+---+---+---+-------+
+# # | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| 12| 13| 15 |
+# # +---+---+---+---+---+---+---+---+---+---+---+---+---+-------+
+# # +----+---+---+---+---+---+---+---+---+---+---+---+---+------+
+# # | 16 | 17| 18| 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29 |
+# # +----+---+---+---+---+---+---+---+---+---+---+---+---+------+
+# # +-----+---+---+---+---+---+---+---+---+---+---+---+---+-----+
+# # | 30 | 31| 32| 33| 34| 35| 36| 37| 38| 39| 40| 41| 29| 43 |
+# # +-----+---+---+---+---+---+---+---+---+---+---+---+---+-----+
+# # +----+---+---+---+---+---+---+---+---+---+---+---+----------+
+# # | 44 | 45| 46| 47| 48| 49| 50| 51| 52| 53| 54| 55| 57 |
+# # +----+---+---+---+---+---+---+---+---+---+---+---+----------+
+# # +----+ +-----+---------------------------+-----+ +----+
+# # | 58 | | 60 | 61 | 62 | | 64 |
+# # +----+ +-----+---------------------------+-----+ +----+
+# #
+# ###################################################################
+#
+# #######################################
+# #
+# +---+---+---+ #
+# |124|125|126| #
+# +---+---+---+ #
+# #
+# +---+---+---+ +---+---+---+---+ #
+# | 75| 80| 85| | 90| 95|100|105| #
+# +---+---+---+ +---+---+---+---+ #
+# +---+---+---+ +---+---+---+---+ #
+# | 76| 81| 86| | 91| 96|101|106| #
+# +---+---+---+ +---+---+---| | #
+# +---+---+---| | #
+# | 92| 97|102| | #
+# +---+---+---+---+ #
+# +---+ +---+---+---+---+ #
+# | 83| | 93| 98|103|107| #
+# +---+ +---+---+---| | #
+# +---+---+---+ +---+---+---| | #
+# | 79| 84| 89| | 99 |104| | #
+# +---+---+---+ +-------+---+---+ #
+# #
+# #######################################
diff --git a/xc/programs/Xserver/hw/xfree86/etc/xmodmap.std b/xc/programs/Xserver/hw/xfree86/etc/xmodmap.std
new file mode 100644
index 000000000..c497e0dfd
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/etc/xmodmap.std
@@ -0,0 +1,211 @@
+!
+! $XFree86: xc/programs/Xserver/hw/xfree86/etc/xmodmap.std,v 3.5 1996/12/23 06:47:28 dawes Exp $
+!
+! Standard key mapping for XFree86 (for US keyboards).
+!
+! This file can be fed to xmodmap to restore the default mapping.
+!
+! $XConsortium: xmodmap.std /main/7 1996/02/21 17:48:55 kaleb $
+!
+! First, clear the modifiers
+!
+clear shift
+clear lock
+clear control
+clear mod1
+clear mod2
+clear mod3
+clear mod4
+clear mod5
+!
+! Set the mapping for each key
+!
+keycode 8 =
+keycode 9 = Escape
+keycode 10 = 1 exclam
+keycode 11 = 2 at
+keycode 12 = 3 numbersign
+keycode 13 = 4 dollar
+keycode 14 = 5 percent
+keycode 15 = 6 asciicircum
+keycode 16 = 7 ampersand
+keycode 17 = 8 asterisk
+keycode 18 = 9 parenleft
+keycode 19 = 0 parenright
+keycode 20 = minus underscore
+keycode 21 = equal plus
+keycode 22 = BackSpace
+keycode 23 = Tab
+keycode 24 = q Q
+keycode 25 = w W
+keycode 26 = e E
+keycode 27 = r R
+keycode 28 = t T
+keycode 29 = y Y
+keycode 30 = u U
+keycode 31 = i I
+keycode 32 = o O
+keycode 33 = p P
+keycode 34 = bracketleft braceleft
+keycode 35 = bracketright braceright
+keycode 36 = Return
+keycode 37 = Control_L
+keycode 38 = a A
+keycode 39 = s S
+keycode 40 = d D
+keycode 41 = f F
+keycode 42 = g G
+keycode 43 = h H
+keycode 44 = j J
+keycode 45 = k K
+keycode 46 = l L
+keycode 47 = semicolon colon
+keycode 48 = apostrophe quotedbl
+keycode 49 = grave asciitilde
+keycode 50 = Shift_L
+keycode 51 = backslash bar
+keycode 52 = z Z
+keycode 53 = x X
+keycode 54 = c C
+keycode 55 = v V
+keycode 56 = b B
+keycode 57 = n N
+keycode 58 = m M
+keycode 59 = comma less
+keycode 60 = period greater
+keycode 61 = slash question
+keycode 62 = Shift_R
+keycode 63 = KP_Multiply
+keycode 64 = Alt_L Meta_L
+keycode 65 = space
+keycode 66 = Caps_Lock
+keycode 67 = F1
+keycode 68 = F2
+keycode 69 = F3
+keycode 70 = F4
+keycode 71 = F5
+keycode 72 = F6
+keycode 73 = F7
+keycode 74 = F8
+keycode 75 = F9
+keycode 76 = F10
+keycode 77 = Num_Lock
+keycode 78 = Multi_key
+keycode 79 = KP_Home KP_7
+keycode 80 = KP_Up KP_8
+keycode 81 = KP_Prior KP_9
+keycode 82 = KP_Subtract
+keycode 83 = KP_Left KP_4
+keycode 84 = NoSymbol KP_5
+keycode 85 = KP_Right KP_6
+keycode 86 = KP_Add
+keycode 87 = KP_End KP_1
+keycode 88 = KP_Down KP_2
+keycode 89 = KP_Next KP_3
+keycode 90 = KP_Insert KP_0
+keycode 91 = KP_Delete KP_Decimal
+!keycode 92 = X386Sys_Req
+keycode 93 =
+keycode 94 =
+keycode 95 = F11
+keycode 96 = F12
+! keycodes 97-107 are not available on 84-key keyboards
+keycode 97 = Home
+keycode 98 = Up
+keycode 99 = Prior
+keycode 100 = Left
+keycode 101 = Begin
+keycode 102 = Right
+keycode 103 = End
+keycode 104 = Down
+keycode 105 = Next
+keycode 106 = Insert
+keycode 107 = Delete
+keycode 108 = KP_Enter
+keycode 109 = Control_R
+keycode 110 = Pause
+keycode 111 = Print
+keycode 112 = KP_Divide
+keycode 113 = Alt_R Meta_R
+keycode 114 = Break
+! keycodes 115-117 are only available on some extended keyboards
+! (e.g., Microsoft's ergonomic keyboard).
+keycode 115 = Meta_L
+keycode 116 = Meta_R
+keycode 117 = Menu
+!
+! Set the modifiers
+!
+add shift = Shift_L Shift_R
+add lock = Caps_Lock
+add control = Control_L Control_R
+add mod1 = Alt_L Alt_R
+! If you have ServerNumlock set in your XF86Config, you can comment out
+add mod2 = Num_Lock
+!
+!
+!
+! If you use any of the special default key mappings in Xconfig, they should be
+! duplicated in this file. Mappings should be added before the section above
+! which sets the modifiers.
+!
+! For the key specs:
+! LeftAlt => keycode 64
+! RightAlt => keycode 113
+! AltGr => keycode 113
+! ScrollLock => keycode 78
+! RightCtl => keycode 109
+!
+! For the mappings:
+! Meta => Alt_L Meta_L
+! Alt_R Meta_R
+! Compose => Multi_key
+! ModeShift => Mode_switch
+! ModeLock => Mode_switch X386Mode_Lock
+! ScrollLock => Scroll_Lock
+! Control => Control_R
+!
+! If you use ModeShift or ModeLock, the following modifier must be set:
+!
+!add mod5 = Mode_switch
+!
+! For example, to get the equivalent of:
+!
+! ScrollLock ModeLock
+! RightAlt ModeShift
+! LeftAlt Meta
+! RightCtl Compose
+!
+! use the following:
+!
+!keycode 78 = Mode_switch X386Mode_Lock
+!keycode 113 = Mode_switch
+!keycode 64 = Alt_L Meta_L
+!keycode 109 = Multi_key
+!
+!add mod5 = Mode_switch
+
+! When using ServerNumLock in your XF86Config, the following codes/symbols
+! are available in place of 79-81, 83-85, 87-91
+!keycode 136 = KP_7
+!keycode 137 = KP_8
+!keycode 138 = KP_9
+!keycode 139 = KP_4
+!keycode 140 = KP_5
+!keycode 141 = KP_6
+!keycode 142 = KP_1
+!keycode 143 = KP_2
+!keycode 144 = KP_3
+!keycode 145 = KP_0
+!keycode 146 = KP_Decimal
+!keycode 147 = Home
+!keycode 148 = Up
+!keycode 149 = Prior
+!keycode 150 = Left
+!keycode 151 = Begin
+!keycode 152 = Right
+!keycode 153 = End
+!keycode 154 = Down
+!keycode 155 = Next
+!keycode 156 = Insert
+!keycode 157 = Delete
diff --git a/xc/programs/Xserver/hw/xfree86/fbdevhw/Imakefile b/xc/programs/Xserver/hw/xfree86/fbdevhw/Imakefile
new file mode 100644
index 000000000..b8f3f6265
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/fbdevhw/Imakefile
@@ -0,0 +1,39 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/fbdevhw/Imakefile,v 1.6 1999/08/14 10:49:58 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#if LinuxFBDevSupport
+SRCS = fbdevhw.c
+OBJS = fbdevhw.o
+#else
+SRCS = fbdevhwstub.c
+OBJS = fbdevhwstub.o
+#endif
+
+ INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/Xext \
+ -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c
+
+ LINTLIBS = ../../../dix/llib-ldix.ln ../../../os/llib-los.ln \
+ ../../mfb/llib-lmfb.ln ../../mi/llib-lmi.ln
+
+ModuleObjectRule()
+LibraryModuleTarget(fbdevhw,$(OBJS))
+NormalLintTarget($(SRCS))
+
+#ifdef LinuxArchitecture
+InstallLibraryModule(fbdevhw,$(MODULEDIR),linux)
+CppManTarget(fbdevhw,)
+InstallModuleManPage(fbdevhw)
+#endif
+
+#ifndef OS2Architecture
+DependTarget()
+#endif
+
+
+InstallDriverSDKLibraryModule(fbdevhw,$(DRIVERSDKMODULEDIR),linux)
+
+InstallDriverSDKNonExecFile(fbdevhw.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/xc/programs/Xserver/hw/xfree86/fbdevhw/README b/xc/programs/Xserver/hw/xfree86/fbdevhw/README
new file mode 100644
index 000000000..27cc337d4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/fbdevhw/README
@@ -0,0 +1,16 @@
+
+This is a submodule to access linux framebuffer devices.
+It is supported to work as helper module (like vgahw)
+for the chipset drivers. There are functions for
+saving/restoring/setting video modes, set palette entries,
+and a few more helper functions. Some of them can be
+hooked directly into ScrnInfoRec.
+
+In ../drivers/fbdev is a "chipset" driver. It is a simple,
+non-accelerated and hardware-independent driver which works
+on top of this fbdevhw submodule.
+
+ Gerd
+
+--
+Gerd Knorr <kraxel@goldbach.in-berlin.de>
diff --git a/xc/programs/Xserver/hw/xfree86/fbdevhw/fb.h b/xc/programs/Xserver/hw/xfree86/fbdevhw/fb.h
new file mode 100644
index 000000000..56e7c7252
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/fbdevhw/fb.h
@@ -0,0 +1,254 @@
+/*
+ * copyed from from linux kernel 2.2.4
+ * removed internal stuff (#ifdef __KERNEL__)
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/fbdevhw/fb.h,v 1.2 1999/04/05 12:43:16 hohndel Exp $ */
+
+#ifndef _LINUX_FB_H
+#define _LINUX_FB_H
+
+#include <asm/types.h>
+
+/* Definitions of frame buffers */
+
+#define FB_MAJOR 29
+
+#define FB_MODES_SHIFT 5 /* 32 modes per framebuffer */
+#define FB_NUM_MINORS 256 /* 256 Minors */
+#define FB_MAX (FB_NUM_MINORS / (1 << FB_MODES_SHIFT))
+#define GET_FB_IDX(node) (MINOR(node) >> FB_MODES_SHIFT)
+
+/* ioctls
+ 0x46 is 'F' */
+#define FBIOGET_VSCREENINFO 0x4600
+#define FBIOPUT_VSCREENINFO 0x4601
+#define FBIOGET_FSCREENINFO 0x4602
+#define FBIOGETCMAP 0x4604
+#define FBIOPUTCMAP 0x4605
+#define FBIOPAN_DISPLAY 0x4606
+/* 0x4607-0x460B are defined below */
+/* #define FBIOGET_MONITORSPEC 0x460C */
+/* #define FBIOPUT_MONITORSPEC 0x460D */
+/* #define FBIOSWITCH_MONIBIT 0x460E */
+#define FBIOGET_CON2FBMAP 0x460F
+#define FBIOPUT_CON2FBMAP 0x4610
+
+#define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
+#define FB_TYPE_PLANES 1 /* Non interleaved planes */
+#define FB_TYPE_INTERLEAVED_PLANES 2 /* Interleaved planes */
+#define FB_TYPE_TEXT 3 /* Text/attributes */
+
+#define FB_AUX_TEXT_MDA 0 /* Monochrome text */
+#define FB_AUX_TEXT_CGA 1 /* CGA/EGA/VGA Color text */
+#define FB_AUX_TEXT_S3_MMIO 2 /* S3 MMIO fasttext */
+#define FB_AUX_TEXT_MGA_STEP16 3 /* MGA Millenium I: text, attr, 14 reserved bytes */
+#define FB_AUX_TEXT_MGA_STEP8 4 /* other MGAs: text, attr, 6 reserved bytes */
+
+#define FB_VISUAL_MONO01 0 /* Monochr. 1=Black 0=White */
+#define FB_VISUAL_MONO10 1 /* Monochr. 1=White 0=Black */
+#define FB_VISUAL_TRUECOLOR 2 /* True color */
+#define FB_VISUAL_PSEUDOCOLOR 3 /* Pseudo color (like atari) */
+#define FB_VISUAL_DIRECTCOLOR 4 /* Direct color */
+#define FB_VISUAL_STATIC_PSEUDOCOLOR 5 /* Pseudo color readonly */
+
+#define FB_ACCEL_NONE 0 /* no hardware accelerator */
+#define FB_ACCEL_ATARIBLITT 1 /* Atari Blitter */
+#define FB_ACCEL_AMIGABLITT 2 /* Amiga Blitter */
+#define FB_ACCEL_S3_TRIO64 3 /* Cybervision64 (S3 Trio64) */
+#define FB_ACCEL_NCR_77C32BLT 4 /* RetinaZ3 (NCR 77C32BLT) */
+#define FB_ACCEL_S3_VIRGE 5 /* Cybervision64/3D (S3 ViRGE) */
+#define FB_ACCEL_ATI_MACH64GX 6 /* ATI Mach 64GX family */
+#define FB_ACCEL_DEC_TGA 7 /* DEC 21030 TGA */
+#define FB_ACCEL_ATI_MACH64CT 8 /* ATI Mach 64CT family */
+#define FB_ACCEL_ATI_MACH64VT 9 /* ATI Mach 64CT family VT class */
+#define FB_ACCEL_ATI_MACH64GT 10 /* ATI Mach 64CT family GT class */
+#define FB_ACCEL_SUN_CREATOR 11 /* Sun Creator/Creator3D */
+#define FB_ACCEL_SUN_CGSIX 12 /* Sun cg6 */
+#define FB_ACCEL_SUN_LEO 13 /* Sun leo/zx */
+#define FB_ACCEL_IMS_TWINTURBO 14 /* IMS Twin Turbo */
+#define FB_ACCEL_3DLABS_PERMEDIA2 15 /* 3Dlabs Permedia 2 */
+#define FB_ACCEL_MATROX_MGA2064W 16 /* Matrox MGA2064W (Millenium) */
+#define FB_ACCEL_MATROX_MGA1064SG 17 /* Matrox MGA1064SG (Mystique) */
+#define FB_ACCEL_MATROX_MGA2164W 18 /* Matrox MGA2164W (Millenium II) */
+#define FB_ACCEL_MATROX_MGA2164W_AGP 19 /* Matrox MGA2164W (Millenium II) */
+#define FB_ACCEL_MATROX_MGAG100 20 /* Matrox G100 (Productiva G100) */
+#define FB_ACCEL_MATROX_MGAG200 21 /* Matrox G200 (Myst, Mill, ...) */
+#define FB_ACCEL_SUN_CG14 22 /* Sun cgfourteen */
+#define FB_ACCEL_SUN_BWTWO 23 /* Sun bwtwo */
+#define FB_ACCEL_SUN_CGTHREE 24 /* Sun cgthree */
+#define FB_ACCEL_SUN_TCX 25 /* Sun tcx */
+
+struct fb_fix_screeninfo {
+ char id[16]; /* identification string eg "TT Builtin" */
+ char *smem_start; /* Start of frame buffer mem */
+ /* (physical address) */
+ __u32 smem_len; /* Length of frame buffer mem */
+ __u32 type; /* see FB_TYPE_* */
+ __u32 type_aux; /* Interleave for interleaved Planes */
+ __u32 visual; /* see FB_VISUAL_* */
+ __u16 xpanstep; /* zero if no hardware panning */
+ __u16 ypanstep; /* zero if no hardware panning */
+ __u16 ywrapstep; /* zero if no hardware ywrap */
+ __u32 line_length; /* length of a line in bytes */
+ char *mmio_start; /* Start of Memory Mapped I/O */
+ /* (physical address) */
+ __u32 mmio_len; /* Length of Memory Mapped I/O */
+ __u32 accel; /* Type of acceleration available */
+ __u16 reserved[3]; /* Reserved for future compatibility */
+};
+
+/* Interpretation of offset for color fields: All offsets are from the right,
+ * inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
+ * can use the offset as right argument to <<). A pixel afterwards is a bit
+ * stream and is written to video memory as that unmodified. This implies
+ * big-endian byte order if bits_per_pixel is greater than 8.
+ */
+struct fb_bitfield {
+ __u32 offset; /* beginning of bitfield */
+ __u32 length; /* length of bitfield */
+ __u32 msb_right; /* != 0 : Most significant bit is */
+ /* right */
+};
+
+#define FB_NONSTD_HAM 1 /* Hold-And-Modify (HAM) */
+
+#define FB_ACTIVATE_NOW 0 /* set values immediately (or vbl)*/
+#define FB_ACTIVATE_NXTOPEN 1 /* activate on next open */
+#define FB_ACTIVATE_TEST 2 /* don't set, round up impossible */
+#define FB_ACTIVATE_MASK 15
+ /* values */
+#define FB_ACTIVATE_VBL 16 /* activate values on next vbl */
+#define FB_CHANGE_CMAP_VBL 32 /* change colormap on vbl */
+#define FB_ACTIVATE_ALL 64 /* change all VCs on this fb */
+
+#define FB_ACCELF_TEXT 1 /* text mode acceleration */
+
+#define FB_SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */
+#define FB_SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */
+#define FB_SYNC_EXT 4 /* external sync */
+#define FB_SYNC_COMP_HIGH_ACT 8 /* composite sync high active */
+#define FB_SYNC_BROADCAST 16 /* broadcast video timings */
+ /* vtotal = 144d/288n/576i => PAL */
+ /* vtotal = 121d/242n/484i => NTSC */
+#define FB_SYNC_ON_GREEN 32 /* sync on green */
+
+#define FB_VMODE_NONINTERLACED 0 /* non interlaced */
+#define FB_VMODE_INTERLACED 1 /* interlaced */
+#define FB_VMODE_DOUBLE 2 /* double scan */
+#define FB_VMODE_MASK 255
+
+#define FB_VMODE_YWRAP 256 /* ywrap instead of panning */
+#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */
+#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */
+
+struct fb_var_screeninfo {
+ __u32 xres; /* visible resolution */
+ __u32 yres;
+ __u32 xres_virtual; /* virtual resolution */
+ __u32 yres_virtual;
+ __u32 xoffset; /* offset from virtual to visible */
+ __u32 yoffset; /* resolution */
+
+ __u32 bits_per_pixel; /* guess what */
+ __u32 grayscale; /* != 0 Graylevels instead of colors */
+
+ struct fb_bitfield red; /* bitfield in fb mem if true color, */
+ struct fb_bitfield green; /* else only length is significant */
+ struct fb_bitfield blue;
+ struct fb_bitfield transp; /* transparency */
+
+ __u32 nonstd; /* != 0 Non standard pixel format */
+
+ __u32 activate; /* see FB_ACTIVATE_* */
+
+ __u32 height; /* height of picture in mm */
+ __u32 width; /* width of picture in mm */
+
+ __u32 accel_flags; /* acceleration flags (hints) */
+
+ /* Timing: All values in pixclocks, except pixclock (of course) */
+ __u32 pixclock; /* pixel clock in ps (pico seconds) */
+ __u32 left_margin; /* time from sync to picture */
+ __u32 right_margin; /* time from picture to sync */
+ __u32 upper_margin; /* time from sync to picture */
+ __u32 lower_margin;
+ __u32 hsync_len; /* length of horizontal sync */
+ __u32 vsync_len; /* length of vertical sync */
+ __u32 sync; /* see FB_SYNC_* */
+ __u32 vmode; /* see FB_VMODE_* */
+ __u32 reserved[6]; /* Reserved for future compatibility */
+};
+
+struct fb_cmap {
+ __u32 start; /* First entry */
+ __u32 len; /* Number of entries */
+ __u16 *red; /* Red values */
+ __u16 *green;
+ __u16 *blue;
+ __u16 *transp; /* transparency, can be NULL */
+};
+
+struct fb_con2fbmap {
+ __u32 console;
+ __u32 framebuffer;
+};
+
+struct fb_monspecs {
+ __u32 hfmin; /* hfreq lower limit (Hz) */
+ __u32 hfmax; /* hfreq upper limit (Hz) */
+ __u16 vfmin; /* vfreq lower limit (Hz) */
+ __u16 vfmax; /* vfreq upper limit (Hz) */
+ unsigned dpms : 1; /* supports DPMS */
+};
+
+#if 1
+
+#define FBCMD_GET_CURRENTPAR 0xDEAD0005
+#define FBCMD_SET_CURRENTPAR 0xDEAD8005
+
+#endif
+
+
+#if 1 /* Preliminary */
+
+ /*
+ * Hardware Cursor
+ */
+
+#define FBIOGET_FCURSORINFO 0x4607
+#define FBIOGET_VCURSORINFO 0x4608
+#define FBIOPUT_VCURSORINFO 0x4609
+#define FBIOGET_CURSORSTATE 0x460A
+#define FBIOPUT_CURSORSTATE 0x460B
+
+
+struct fb_fix_cursorinfo {
+ __u16 crsr_width; /* width and height of the cursor in */
+ __u16 crsr_height; /* pixels (zero if no cursor) */
+ __u16 crsr_xsize; /* cursor size in display pixels */
+ __u16 crsr_ysize;
+ __u16 crsr_color1; /* colormap entry for cursor color1 */
+ __u16 crsr_color2; /* colormap entry for cursor color2 */
+};
+
+struct fb_var_cursorinfo {
+ __u16 width;
+ __u16 height;
+ __u16 xspot;
+ __u16 yspot;
+ __u8 data[1]; /* field with [height][width] */
+};
+
+struct fb_cursorstate {
+ __s16 xoffset;
+ __s16 yoffset;
+ __u16 mode;
+};
+
+#define FB_CURSOR_OFF 0
+#define FB_CURSOR_ON 1
+#define FB_CURSOR_FLASH 2
+
+#endif /* Preliminary */
+
+#endif /* _LINUX_FB_H */
diff --git a/xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.c b/xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.c
new file mode 100644
index 000000000..b6b5981d0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.c
@@ -0,0 +1,730 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.c,v 1.9 1999/07/18 03:27:01 dawes Exp $ */
+
+/* all driver need this */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+/* pci stuff */
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "xf86cmap.h"
+
+#include "fbdevhw.h"
+#include "fb.h"
+
+#include "asm/page.h" /* #define for PAGE_* */
+
+#define DEBUG 0
+
+#if DEBUG
+# define TRACE_ENTER(str) ErrorF("fbdevHW: " str " %d\n",pScrn->scrnIndex)
+#else
+# define TRACE_ENTER(str)
+#endif
+
+/* -------------------------------------------------------------------- */
+
+#ifdef XFree86LOADER
+
+static MODULESETUPPROTO(fbdevhwSetup);
+
+static XF86ModuleVersionInfo fbdevHWVersRec =
+{
+ "fbdevhw",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 0, 0, 1,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0}
+};
+
+XF86ModuleData fbdevhwModuleData = { &fbdevHWVersRec, fbdevhwSetup, NULL };
+
+static pointer
+fbdevhwSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ const char *osname;
+
+ /* Check that we're being loaded on a Linux system */
+ LoaderGetOS(&osname, NULL, NULL, NULL);
+ if (!osname || strcmp(osname, "linux") != 0) {
+ if (errmaj)
+ *errmaj = LDR_BADOS;
+ if (errmin)
+ *errmin = 0;
+ return NULL;
+ } else {
+ /* OK */
+ return (pointer)1;
+ }
+}
+
+#else /* XFree86LOADER */
+
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/mman.h>
+
+#endif /* XFree86LOADER */
+
+/* -------------------------------------------------------------------- */
+/* our private data, and two functions to allocate/free this */
+
+#define FBDEVHWPTRLVAL(p) (p)->privates[fbdevHWPrivateIndex].ptr
+#define FBDEVHWPTR(p) ((fbdevHWPtr)(FBDEVHWPTRLVAL(p)))
+
+static int fbdevHWPrivateIndex = -1;
+
+typedef struct {
+ /* framebuffer device: filename (/dev/fb*), handle, more */
+ char* device;
+ int fd;
+ void* fbmem;
+ int fboff;
+ void* mmio;
+
+ /* current hardware state */
+ struct fb_fix_screeninfo fix;
+ struct fb_var_screeninfo var;
+
+ /* saved video mode */
+ struct fb_var_screeninfo saved_var;
+ struct fb_cmap saved_cmap;
+ unsigned short *saved_red;
+ unsigned short *saved_green;
+ unsigned short *saved_blue;
+
+ /* buildin video mode */
+ DisplayModeRec buildin;
+
+} fbdevHWRec, *fbdevHWPtr;
+
+Bool
+fbdevHWGetRec(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr;
+
+ if (fbdevHWPrivateIndex < 0)
+ fbdevHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
+
+ if (FBDEVHWPTR(pScrn) != NULL)
+ return TRUE;
+
+ fPtr = FBDEVHWPTRLVAL(pScrn) = xnfcalloc(sizeof(fbdevHWRec), 1);
+ return TRUE;
+}
+
+void
+fbdevHWFreeRec(ScrnInfoPtr pScrn)
+{
+ if (fbdevHWPrivateIndex < 0)
+ return;
+ if (FBDEVHWPTR(pScrn) == NULL)
+ return;
+ xfree(FBDEVHWPTR(pScrn));
+ FBDEVHWPTRLVAL(pScrn) = NULL;
+}
+
+/* -------------------------------------------------------------------- */
+/* some helpers for printing debug informations */
+
+#if DEBUG
+static void
+print_fbdev_mode(char *txt, struct fb_var_screeninfo *var)
+{
+ ErrorF( "fbdev %s mode:\t%d %d %d %d %d %d %d %d %d %d %d:%d:%d\n",
+ txt,var->pixclock,
+ var->xres, var->right_margin, var->hsync_len, var->left_margin,
+ var->yres, var->lower_margin, var->vsync_len, var->upper_margin,
+ var->bits_per_pixel,
+ var->red.length, var->green.length, var->blue.length);
+}
+
+static void
+print_xfree_mode(char *txt, DisplayModePtr mode)
+{
+ ErrorF( "xfree %s mode:\t%d %d %d %d %d %d %d %d %d\n",
+ txt,mode->Clock,
+ mode->HDisplay, mode->HSyncStart, mode->HSyncEnd, mode->HTotal,
+ mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, mode->VTotal);
+}
+#endif
+
+/* -------------------------------------------------------------------- */
+/* Convert timings between the XFree and the Frame Buffer Device */
+
+static void
+xfree2fbdev_fblayout(ScrnInfoPtr pScrn, struct fb_var_screeninfo *var)
+{
+ var->xres_virtual = pScrn->virtualX;
+ var->yres_virtual = pScrn->virtualY;
+ var->bits_per_pixel = pScrn->bitsPerPixel;
+ var->red.length = 0;
+ var->red.offset = 0;
+ var->green.length = 0;
+ var->green.offset = 0;
+ var->blue.length = 0;
+ var->blue.offset = 0;
+}
+
+static void
+xfree2fbdev_timing(DisplayModePtr mode, struct fb_var_screeninfo *var)
+{
+ var->xres = mode->HDisplay;
+ var->yres = mode->VDisplay;
+ if (var->xres_virtual < var->xres)
+ var->xres_virtual = var->xres;
+ if (var->yres_virtual < var->yres)
+ var->yres_virtual = var->yres;
+ var->xoffset = var->yoffset = 0;
+ var->pixclock = mode->Clock ? 1000000000/mode->Clock : 0;
+ var->right_margin = mode->HSyncStart-mode->HDisplay;
+ var->hsync_len = mode->HSyncEnd-mode->HSyncStart;
+ var->left_margin = mode->HTotal-mode->HSyncEnd;
+ var->lower_margin = mode->VSyncStart-mode->VDisplay;
+ var->vsync_len = mode->VSyncEnd-mode->VSyncStart;
+ var->upper_margin = mode->VTotal-mode->VSyncEnd;
+ var->sync = 0;
+ if (mode->Flags & V_PHSYNC)
+ var->sync |= FB_SYNC_HOR_HIGH_ACT;
+ if (mode->Flags & V_PVSYNC)
+ var->sync |= FB_SYNC_VERT_HIGH_ACT;
+ if (mode->Flags & V_PCSYNC)
+ var->sync |= FB_SYNC_COMP_HIGH_ACT;
+#if 0
+ if (mode->Flags & V_BCAST)
+ var->sync |= FB_SYNC_BROADCAST;
+#endif
+ if (mode->Flags & V_INTERLACE)
+ var->vmode = FB_VMODE_INTERLACED;
+ else if (mode->Flags & V_DBLSCAN)
+ var->vmode = FB_VMODE_DOUBLE;
+ else
+ var->vmode = FB_VMODE_NONINTERLACED;
+}
+
+static void
+fbdev2xfree_timing(struct fb_var_screeninfo *var, DisplayModePtr mode)
+{
+ mode->Clock = var->pixclock ? 1000000000/var->pixclock : 28000000;
+ mode->HDisplay = var->xres;
+ mode->HSyncStart = mode->HDisplay+var->right_margin;
+ mode->HSyncEnd = mode->HSyncStart+var->hsync_len;
+ mode->HTotal = mode->HSyncEnd+var->left_margin;
+ mode->VDisplay = var->yres;
+ mode->VSyncStart = mode->VDisplay+var->lower_margin;
+ mode->VSyncEnd = mode->VSyncStart+var->vsync_len;
+ mode->VTotal = mode->VSyncEnd+var->upper_margin;
+ mode->Flags = 0;
+ mode->Flags |= var->sync & FB_SYNC_HOR_HIGH_ACT ? V_PHSYNC : V_NHSYNC;
+ mode->Flags |= var->sync & FB_SYNC_VERT_HIGH_ACT ? V_PVSYNC : V_NVSYNC;
+ mode->Flags |= var->sync & FB_SYNC_COMP_HIGH_ACT ? V_PCSYNC : V_NCSYNC;
+#if 0
+ if (var->sync & FB_SYNC_BROADCAST)
+ mode->Flags |= V_BCAST;
+#endif
+ if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
+ mode->Flags |= V_INTERLACE;
+ else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
+ mode->Flags |= V_DBLSCAN;
+ mode->SynthClock = mode->Clock;
+ mode->CrtcHDisplay = mode->HDisplay;
+ mode->CrtcHSyncStart = mode->HSyncStart;
+ mode->CrtcHSyncEnd = mode->HSyncEnd;
+ mode->CrtcHTotal = mode->HTotal;
+ mode->CrtcVDisplay = mode->VDisplay;
+ mode->CrtcVSyncStart = mode->VSyncStart;
+ mode->CrtcVSyncEnd = mode->VSyncEnd;
+ mode->CrtcVTotal = mode->VTotal;
+ mode->CrtcHAdjusted = FALSE;
+ mode->CrtcVAdjusted = FALSE;
+}
+
+
+/* -------------------------------------------------------------------- */
+/* open correct framebuffer device */
+
+static struct fb2pci_entry {
+ CARD32 id;
+ CARD32 vendor;
+ CARD32 chip;
+} fb2pci_map[] = {
+ { FB_ACCEL_MATROX_MGA2064W, PCI_VENDOR_MATROX, PCI_CHIP_MGA2064 },
+ { FB_ACCEL_MATROX_MGA1064SG, PCI_VENDOR_MATROX, PCI_CHIP_MGA1064 },
+ { FB_ACCEL_MATROX_MGA2164W, PCI_VENDOR_MATROX, PCI_CHIP_MGA2164 },
+ { FB_ACCEL_MATROX_MGA2164W_AGP, PCI_VENDOR_MATROX, PCI_CHIP_MGA2164_AGP },
+ { FB_ACCEL_MATROX_MGAG100, PCI_VENDOR_MATROX, PCI_CHIP_MGAG100 },
+ { FB_ACCEL_MATROX_MGAG200, PCI_VENDOR_MATROX, PCI_CHIP_MGAG200 },
+};
+#define FB2PCICOUNT (sizeof(fb2pci_map)/sizeof(struct fb2pci_entry))
+
+/* try to find the framebuffer device for a given PCI device */
+static int
+fbdev_open_pci(pciVideoPtr pPci)
+{
+ struct fb_fix_screeninfo fix;
+ char filename[16];
+ int fd,i,j;
+
+ for (i = 0; i < 4; i++) {
+ sprintf(filename,"/dev/fb%d",i);
+ if (-1 == (fd = open(filename,O_RDWR,0))) {
+ continue;
+ }
+ if (-1 == ioctl(fd,FBIOGET_FSCREENINFO,(void*)&fix)) {
+ close(fd);
+ continue;
+ }
+ /* FIXME: better ask the fbdev driver for bus/device/func,
+ but there is no way to to this yet. */
+ for (j = 0; j < FB2PCICOUNT; j++) {
+ if (pPci->vendor == fb2pci_map[j].vendor &&
+ pPci->chipType == fb2pci_map[j].chip &&
+ fix.accel == fb2pci_map[j].id)
+ break;
+ }
+ if (j == FB2PCICOUNT) {
+ close(fd);
+ continue;
+ }
+ return fd;
+ }
+ return -1;
+}
+
+static int
+fbdev_open(char *dev)
+{
+ struct fb_con2fbmap c2m;
+ char fbdev[16];
+ int fd;
+
+ /* try argument (from XF86Config) first */
+ if (NULL != dev)
+ return open(dev,O_RDWR,0);
+
+ /* second: environment variable */
+ dev = getenv("FRAMEBUFFER");
+ if (NULL != dev)
+ return open(dev,O_RDWR,0);
+
+ /* last try: default device */
+ if (-1 == (fd = open("/dev/fb0",O_RDWR,0)))
+ return -1;
+
+ return fd;
+}
+
+/* -------------------------------------------------------------------- */
+
+Bool
+fbdevHWProbe(pciVideoPtr pPci, char *device)
+{
+ int fd;
+
+ if (pPci)
+ fd = fbdev_open_pci(pPci);
+ else
+ fd = fbdev_open(device);
+
+ if (-1 == fd)
+ return FALSE;
+ close(fd);
+ return TRUE;
+}
+
+Bool
+fbdevHWInit(ScrnInfoPtr pScrn, pciVideoPtr pPci, char *device)
+{
+ fbdevHWPtr fPtr;
+
+ TRACE_ENTER("Init");
+
+ fbdevHWGetRec(pScrn);
+ fPtr = FBDEVHWPTR(pScrn);
+
+ /* open device */
+ if (pPci)
+ fPtr->fd = fbdev_open_pci(pPci);
+ else
+ fPtr->fd = fbdev_open(device);
+ if (-1 == fPtr->fd)
+ return FALSE;
+
+ /* get current fb device settings */
+ if (-1 == ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ioctl FBIOGET_FSCREENINFO: %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+ if (-1 == ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ioctl FBIOGET_VSCREENINFO: %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+
+ /* we can use the current settings as "buildin mode" */
+ fbdev2xfree_timing(&fPtr->var, &fPtr->buildin);
+ fPtr->buildin.name = "current";
+ fPtr->buildin.next = &fPtr->buildin;
+ fPtr->buildin.prev = &fPtr->buildin;
+ fPtr->buildin.type |= M_T_BUILTIN;
+
+ return TRUE;
+}
+
+char*
+fbdevHWGetName(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ return fPtr->fix.id;
+}
+
+int
+fbdevHWGetDepth(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ return fPtr->var.bits_per_pixel;
+}
+
+int
+fbdevHWGetType(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ return fPtr->fix.type;
+}
+
+int
+fbdevHWGetVidmem(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ return fPtr->fix.smem_len;
+}
+
+void
+fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ int virtX = pScrn->display->virtualX;
+ int virtY = pScrn->display->virtualY;
+ struct fb_var_screeninfo var;
+ char **modename;
+ DisplayModePtr mode,this,last = NULL;
+
+ TRACE_ENTER("VerifyModes");
+ if (NULL == pScrn->display->modes)
+ return;
+
+ for (modename = pScrn->display->modes; *modename != NULL; modename++) {
+ for (mode = pScrn->monitor->Modes; mode != NULL; mode = mode->next)
+ if (0 == strcmp(mode->name,*modename))
+ break;
+ if (NULL == mode) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "\tmode \"%s\" not found\n", *modename);
+ continue;
+ }
+ memset(&var,0,sizeof(var));
+ xfree2fbdev_timing(mode,&var);
+ var.xres_virtual = virtX;
+ var.yres_virtual = virtY;
+ var.bits_per_pixel = pScrn->depth;
+ var.activate = FB_ACTIVATE_TEST;
+ if (var.xres_virtual < var.xres) var.xres_virtual = var.xres;
+ if (var.yres_virtual < var.yres) var.yres_virtual = var.yres;
+ if (-1 == ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&var))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "\tmode \"%s\" test failed\n", *modename);
+ continue;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "\tmode \"%s\" ok\n", *modename);
+ if (virtX < var.xres) virtX = var.xres;
+ if (virtY < var.yres) virtY = var.yres;
+ if (NULL == pScrn->modes) {
+ pScrn->modes = xnfalloc(sizeof(DisplayModeRec));
+ this = pScrn->modes;
+ memcpy(this,mode,sizeof(DisplayModeRec));
+ this->next = this;
+ this->prev = this;
+ } else {
+ this = xnfalloc(sizeof(DisplayModeRec));
+ memcpy(this,mode,sizeof(DisplayModeRec));
+ this->next = pScrn->modes;
+ this->prev = last;
+ last->next = this;
+ pScrn->modes->prev = this;
+ }
+ last = this;
+ }
+ pScrn->virtualX = virtX;
+ pScrn->virtualY = virtY;
+}
+
+DisplayModePtr
+fbdevHWGetBuildinMode(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ return &fPtr->buildin;
+}
+
+void
+fbdevHWUseBuildinMode(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("UseBuildinMode");
+ pScrn->modes = &fPtr->buildin;
+ pScrn->virtualX = pScrn->display->virtualX;
+ pScrn->virtualY = pScrn->display->virtualY;
+ if (pScrn->virtualX < fPtr->buildin.HDisplay)
+ pScrn->virtualX = fPtr->buildin.HDisplay;
+ if (pScrn->virtualY < fPtr->buildin.VDisplay)
+ pScrn->virtualY = fPtr->buildin.VDisplay;
+}
+
+/* -------------------------------------------------------------------- */
+
+void*
+fbdevHWMapVidmem(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("MapVidmem");
+ if (NULL == fPtr->fbmem) {
+ fPtr->fboff = fPtr->fix.smem_len & (PAGE_SIZE-1);
+ fPtr->fbmem = mmap(NULL, fPtr->fix.smem_len, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fPtr->fd, 0);
+ if (-1 == (int)fPtr->fbmem) {
+ perror("mmap fbmem");
+ fPtr->fbmem = NULL;
+ }
+ }
+ pScrn->memPhysBase = (unsigned long)fPtr->fix.smem_start & (unsigned long)(PAGE_MASK);
+ pScrn->fbOffset = (unsigned long)fPtr->fix.smem_start & (unsigned long)(~PAGE_MASK);
+ return fPtr->fbmem;
+}
+
+int
+fbdevHWLinearOffset(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("LinearOffset");
+ return fPtr->fboff;
+}
+
+Bool
+fbdevHWUnmapVidmem(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("UnmapVidmem");
+ if (NULL != fPtr->fbmem) {
+ if (-1 == munmap(fPtr->fbmem, fPtr->fix.smem_len))
+ perror("munmap fbmem");
+ fPtr->fbmem = NULL;
+ }
+ return TRUE;
+}
+
+void*
+fbdevHWMapMMIO(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("MapMMIO");
+ if (NULL == fPtr->mmio) {
+ /* tell the kernel not to use accels to speed up console scrolling */
+ fPtr->var.accel_flags = 0;
+ if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
+ perror("FBIOPUT_VSCREENINFO");
+ return FALSE;
+ }
+ fPtr->mmio = mmap(NULL, fPtr->fix.mmio_len, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fPtr->fd, fPtr->fix.smem_len);
+ if (-1 == (int)fPtr->mmio) {
+ perror("mmap mmio");
+ fPtr->mmio = NULL;
+ }
+ }
+ return fPtr->mmio;
+}
+
+Bool
+fbdevHWUnmapMMIO(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("UnmapMMIO");
+ if (NULL != fPtr->mmio) {
+ if (-1 == munmap(fPtr->mmio, fPtr->fix.mmio_len))
+ perror("munmap mmio");
+ fPtr->mmio = NULL;
+ }
+ return TRUE;
+}
+
+/* -------------------------------------------------------------------- */
+
+Bool
+fbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("ModeInit");
+ xfree2fbdev_fblayout(pScrn, &fPtr->var);
+ xfree2fbdev_timing(mode, &fPtr->var);
+#if DEBUG
+ print_xfree_mode("init",mode);
+ print_fbdev_mode("init",&fPtr->var);
+#endif
+ pScrn->vtSema = TRUE;
+
+ /* set */
+ if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
+ perror("FBIOPUT_VSCREENINFO");
+ return FALSE;
+ }
+ /* read back */
+ if (0 != ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) {
+ perror("FBIOGET_FSCREENINFO");
+ return FALSE;
+ }
+ if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) {
+ perror("FBIOGET_VSCREENINFO");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* -------------------------------------------------------------------- */
+/* video mode save/restore */
+
+/* TODO: colormap */
+void
+fbdevHWSave(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("Save");
+ if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->saved_var)))
+ perror("FBIOGET_VSCREENINFO");
+}
+
+void
+fbdevHWRestore(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("Restore");
+ if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->saved_var)))
+ perror("FBIOPUT_VSCREENINFO");
+}
+
+/* -------------------------------------------------------------------- */
+/* callback for xf86HandleColormaps */
+
+void
+fbdevHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ struct fb_cmap cmap;
+ unsigned short red,green,blue;
+ int i;
+
+ TRACE_ENTER("ModeInit");
+ cmap.len = 1;
+ cmap.red = &red;
+ cmap.green = &green;
+ cmap.blue = &blue;
+ cmap.transp = NULL;
+ for (i = 0; i < numColors; i++) {
+ cmap.start = indices[i];
+ red = colors[indices[i]].red << 8;
+ green = colors[indices[i]].green << 8;
+ blue = colors[indices[i]].blue << 8;
+ if (-1 == ioctl(fPtr->fd,FBIOPUTCMAP,(void*)&cmap))
+ perror("ioctl FBIOPUTCMAP");
+ }
+}
+
+/* -------------------------------------------------------------------- */
+/* these can be hooked directly into ScrnInfoRec */
+
+int
+fbdevHWValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ struct fb_var_screeninfo var;
+
+ TRACE_ENTER("ValidMode");
+ memcpy(&var,&fPtr->var,sizeof(var));
+ xfree2fbdev_timing(mode, &var);
+ var.activate = FB_ACTIVATE_TEST;
+ if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
+ perror("FBIOPUT_VSCREENINFO");
+ return MODE_BAD;
+ }
+ return MODE_OK;
+}
+
+Bool
+fbdevHWSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("SwitchMode");
+ xfree2fbdev_timing(mode, &fPtr->var);
+ if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
+ perror("FBIOPUT_VSCREENINFO");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void
+fbdevHWAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("AdjustFrame");
+ fPtr->var.xoffset = x;
+ fPtr->var.yoffset = y;
+ if (-1 == ioctl(fPtr->fd,FBIOPAN_DISPLAY,(void*)&fPtr->var))
+ perror("ioctl FBIOPAN_DISPLAY");
+}
+
+Bool
+fbdevHWEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ TRACE_ENTER("EnterVT");
+ if (!fbdevHWModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ fbdevHWAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ return TRUE;
+}
+
+void
+fbdevHWLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ TRACE_ENTER("LeaveVT");
+ fbdevHWRestore(pScrn);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.cpp b/xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.cpp
new file mode 100644
index 000000000..c0807fe6a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.cpp
@@ -0,0 +1,21 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.cpp,v 1.1 1999/04/04 08:46:22 dawes Exp $
+.TH FBDEVHW __drivermansuffix__ "Version 4.0" "XFree86"
+.SH NAME
+fbdevhw \- os-specific submodule for framebuffer device access
+.SH DESCRIPTION
+.B fbdevhw
+provides functions for talking to a framebuffer device. It is
+os-specific. It is a submodule used by other video drivers.
+A
+.B fbdevhw
+module is currently available for linux framebuffer devices.
+.PP
+fbdev(__drivermansuffix__) is a non-accelerated driver which runs on top of the
+fbdevhw module. fbdevhw can be used by other drivers too, this
+is usually activated with `Option "UseFBDev"' in the device section.
+.SH "SEE ALSO"
+XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(1),
+fbdev(__drivermansuffix__)
+.SH AUTHORS
+Authors include: Gerd Knorr, based on the XF68_FBDev Server code
+(Martin Schaller, Geert Uytterhoeven).
diff --git a/xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.h b/xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.h
new file mode 100644
index 000000000..37c305b90
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.h
@@ -0,0 +1,40 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhw.h,v 1.5 1999/07/18 03:27:01 dawes Exp $ */
+
+#define FBDEVHW_PACKED_PIXELS 0 /* Packed Pixels */
+#define FBDEVHW_PLANES 1 /* Non interleaved planes */
+#define FBDEVHW_INTERLEAVED_PLANES 2 /* Interleaved planes */
+#define FBDEVHW_TEXT 3 /* Text/attributes */
+#define FBDEVHW_VGA_PLANES 4 /* EGA/VGA planes */
+
+Bool fbdevHWGetRec(ScrnInfoPtr pScrn);
+void fbdevHWFreeRec(ScrnInfoPtr pScrn);
+
+Bool fbdevHWProbe(pciVideoPtr pPci, char *device);
+Bool fbdevHWInit(ScrnInfoPtr pScrn, pciVideoPtr pPci, char *device);
+
+char* fbdevHWGetName(ScrnInfoPtr pScrn);
+int fbdevHWGetDepth(ScrnInfoPtr pScrn);
+int fbdevHWGetType(ScrnInfoPtr pScrn);
+int fbdevHWGetVidmem(ScrnInfoPtr pScrn);
+
+void* fbdevHWMapVidmem(ScrnInfoPtr pScrn);
+int fbdevHWLinearOffset(ScrnInfoPtr pScrn);
+Bool fbdevHWUnmapVidmem(ScrnInfoPtr pScrn);
+void* fbdevHWMapMMIO(ScrnInfoPtr pScrn);
+Bool fbdevHWUnmapMMIO(ScrnInfoPtr pScrn);
+
+void fbdevHWSetVideoModes(ScrnInfoPtr pScrn);
+DisplayModePtr fbdevHWGetBuildinMode(ScrnInfoPtr pScrn);
+void fbdevHWUseBuildinMode(ScrnInfoPtr pScrn);
+Bool fbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+void fbdevHWSave(ScrnInfoPtr pScrn);
+void fbdevHWRestore(ScrnInfoPtr pScrn);
+
+void fbdevHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual);
+
+int fbdevHWValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags);
+Bool fbdevHWSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
+void fbdevHWAdjustFrame(int scrnIndex, int x, int y, int flags);
+Bool fbdevHWEnterVT(int scrnIndex, int flags);
+void fbdevHWLeaveVT(int scrnIndex, int flags);
diff --git a/xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhwstub.c b/xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhwstub.c
new file mode 100644
index 000000000..6f8d3eccf
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhwstub.c
@@ -0,0 +1,154 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/fbdevhw/fbdevhwstub.c,v 1.6 1999/07/18 08:14:33 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86cmap.h"
+#include "fbdevhw.h"
+
+/* Stubs for the static server on platforms that don't support fbdev */
+
+
+Bool
+fbdevHWGetRec(ScrnInfoPtr pScrn)
+{
+ return FALSE;
+}
+
+void
+fbdevHWFreeRec(ScrnInfoPtr pScrn)
+{
+}
+
+
+Bool
+fbdevHWProbe(pciVideoPtr pPci, char *device)
+{
+ return FALSE;
+}
+
+Bool
+fbdevHWInit(ScrnInfoPtr pScrn, pciVideoPtr pPci, char *device)
+{
+ xf86Msg(X_ERROR, "fbdevhw is not available on this platform\n");
+ return FALSE;
+}
+
+char*
+fbdevHWGetName(ScrnInfoPtr pScrn)
+{
+ return NULL;
+}
+
+int
+fbdevHWGetDepth(ScrnInfoPtr pScrn)
+{
+ return -1;
+}
+
+int
+fbdevHWGetType(ScrnInfoPtr pScrn)
+{
+ return -1;
+}
+
+int
+fbdevHWGetVidmem(ScrnInfoPtr pScrn)
+{
+ return -1;
+}
+
+void
+fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
+{
+}
+
+DisplayModePtr
+fbdevHWGetBuildinMode(ScrnInfoPtr pScrn)
+{
+ return NULL;
+}
+
+void
+fbdevHWUseBuildinMode(ScrnInfoPtr pScrn)
+{
+}
+
+void*
+fbdevHWMapVidmem(ScrnInfoPtr pScrn)
+{
+ return NULL;
+}
+
+int
+fbdevHWLinearOffset(ScrnInfoPtr pScrn)
+{
+ return 0;
+}
+
+Bool
+fbdevHWUnmapVidmem(ScrnInfoPtr pScrn)
+{
+ return FALSE;
+}
+
+void*
+fbdevHWMapMMIO(ScrnInfoPtr pScrn)
+{
+ return NULL;
+}
+
+Bool
+fbdevHWUnmapMMIO(ScrnInfoPtr pScrn)
+{
+ return FALSE;
+}
+
+Bool
+fbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ return FALSE;
+}
+
+void
+fbdevHWSave(ScrnInfoPtr pScrn)
+{
+}
+
+void
+fbdevHWRestore(ScrnInfoPtr pScrn)
+{
+}
+
+void
+fbdevHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual)
+{
+}
+
+int
+fbdevHWValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ return MODE_ERROR;
+}
+
+Bool
+fbdevHWSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ return FALSE;
+}
+
+void
+fbdevHWAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+}
+
+Bool
+fbdevHWEnterVT(int scrnIndex, int flags)
+{
+ return FALSE;
+}
+
+void
+fbdevHWLeaveVT(int scrnIndex, int flags)
+{
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/i2c/Imakefile b/xc/programs/Xserver/hw/xfree86/i2c/Imakefile
new file mode 100644
index 000000000..2e5645fac
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/i2c/Imakefile
@@ -0,0 +1,28 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/i2c/Imakefile,v 1.4 1999/08/14 10:49:58 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#if DoLoadableServer
+MODSRC = xf86i2cmodule.c
+MODOBJ = xf86i2cmodule.o
+#endif
+
+SRCS = xf86i2c.c $(MODSRC)
+OBJS = xf86i2c.o $(MODOBJ)
+
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC)
+
+ModuleObjectRule()
+
+LibraryModuleTarget(i2c, $(OBJS))
+
+InstallLibraryModule(i2c,$(MODULEDIR),.)
+
+DependTarget()
+
+
+InstallDriverSDKLibraryModule(i2c,$(DRIVERSDKMODULEDIR),.)
+
+InstallDriverSDKNonExecFile(xf86i2c.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/xc/programs/Xserver/hw/xfree86/i2c/xf86i2c.c b/xc/programs/Xserver/hw/xfree86/i2c/xf86i2c.c
new file mode 100644
index 000000000..5cd25bd60
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/i2c/xf86i2c.c
@@ -0,0 +1,840 @@
+/*
+ * Copyright (C) 1998 Itai Nahshon, Michael Schimek
+ *
+ * The original code was derived from and inspired by
+ * the I2C driver from the Linux kernel.
+ * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/i2c/xf86i2c.c,v 1.6 1999/06/12 15:37:08 dawes Exp $ */
+
+#if 1
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "Xproto.h"
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "validate.h"
+#include "resource.h"
+#include "gcstruct.h"
+#include "dixstruct.h"
+#else
+typedef int Bool;
+typedef void *Pointer;
+#define NULL ((void *)0)
+#define X_DEFAULT 0
+#define TRUE 1
+#define FALSE 0
+#endif
+
+#include "xf86i2c.h"
+
+#define I2C_TIMEOUT(x) /* (x) */ /* Report timeouts */
+#define I2C_TRACE(x) /* (x) */ /* Report progress */
+
+/* This is the default I2CUDelay function if not supplied by the driver.
+ * High level I2C interfaces implementing the bus protocol in hardware
+ * should supply this function too.
+ *
+ * Delay execution at least usec microseconds.
+ * All values 0 to 1e6 inclusive must be expected.
+ *
+ * This is temporary until a better, portable
+ * way is found. Adjust bogo_usec to match CPU speed.
+ */
+
+static int bogo_usec = 500;
+
+static void
+I2CUDelay(I2CBusPtr b, int usec)
+{
+ volatile long i;
+
+ if (usec > 0)
+ for (i = usec * bogo_usec; i > 0; i--)
+ /* (perhaps hw delay action) */;
+}
+
+/* Most drivers will register just with GetBits/PutBits functions.
+ * The following functions implement a software I2C protocol
+ * by using the promitive functions given by the driver.
+ * ================================================================
+ *
+ * It is assumed that there is just one master on the I2C bus, therefore
+ * there is no explicit test for conflits.
+ */
+
+#define RISEFALLTIME 1 /* usec, actually 300 to 1000 ns according to the i2c specs */
+
+/* Some devices will hold SCL low to slow down the bus or until
+ * ready for transmission.
+ *
+ * This condition will be noticed when the master tries to raise
+ * the SCL line. You can set the timeout to zero if the slave device
+ * does not support this clock synchronization.
+ */
+
+static Bool
+I2CRaiseSCL(I2CBusPtr b, int sda, int timeout)
+{
+ int i, scl;
+
+ b->I2CPutBits(b, 1, sda);
+ b->I2CUDelay(b, RISEFALLTIME);
+
+ for (i = timeout; i > 0; i -= RISEFALLTIME) {
+ b->I2CGetBits(b, &scl, &sda);
+ if (scl) break;
+ b->I2CUDelay(b, RISEFALLTIME);
+ }
+
+ if (i <= 0) {
+ I2C_TIMEOUT(ErrorF("[I2CRaiseSCL(<%s>, %d, %d) timeout]", b->BusName, sda, timeout));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Send a start signal on the I2C bus. The start signal notifies
+ * devices that a new transaction is initiated by the bus master.
+ *
+ * The start signal is always followed by a slave address.
+ * Slave addresses are 8+ bits. The first 7 bits identify the
+ * device and the last bit signals if this is a read (1) or
+ * write (0) operation.
+ *
+ * There may be more than one start signal on one transaction.
+ * This happens for example on some devices that allow reading
+ * of registers. First send a start bit followed by the device
+ * address (with the last bit 0) and the register number. Then send
+ * a new start bit with the device address (with the last bit 1)
+ * and then read the value from the device.
+ *
+ * Note this is function does not implement a multiple master
+ * arbitration procedure.
+ */
+
+static Bool
+I2CStart(I2CBusPtr b, int timeout)
+{
+ int i, scl, sda;
+
+ b->I2CPutBits(b, 1, 1);
+ b->I2CUDelay(b, RISEFALLTIME);
+
+ for (i = timeout; i > 0; i -= RISEFALLTIME) {
+ b->I2CGetBits(b, &scl, &sda);
+ if (scl) break;
+ b->I2CUDelay(b, RISEFALLTIME);
+ }
+
+ if (i <= 0) {
+ I2C_TIMEOUT(ErrorF("\ni2c: <[I2CStart(<%s>, %d) timeout]", b->BusName, timeout));
+ return FALSE;
+ }
+
+ b->I2CPutBits(b, 1, 0);
+ b->I2CUDelay(b, b->HoldTime);
+ b->I2CPutBits(b, 0, 0);
+ b->I2CUDelay(b, b->HoldTime);
+
+ I2C_TRACE(ErrorF("\ni2c: <"));
+
+ return TRUE;
+}
+
+/* This is the default I2CStop function if not supplied by the driver.
+ *
+ * Signal devices on the I2C bus that a transaction on the
+ * bus has finished. There may be more than one start signal
+ * on a transaction but only one stop signal.
+ */
+
+static void
+I2CStop(I2CDevPtr d)
+{
+ I2CBusPtr b = d->pI2CBus;
+
+ b->I2CPutBits(b, 0, 0);
+ b->I2CUDelay(b, RISEFALLTIME);
+
+ b->I2CPutBits(b, 1, 0);
+ b->I2CUDelay(b, b->HoldTime);
+ b->I2CPutBits(b, 1, 1);
+ b->I2CUDelay(b, b->HoldTime);
+
+ I2C_TRACE(ErrorF(">\n"));
+}
+
+/* Write/Read a single bit to/from a device.
+ * Return FALSE if a timeout occurs.
+ */
+
+static Bool
+I2CWriteBit(I2CBusPtr b, int sda, int timeout)
+{
+ Bool r;
+
+ b->I2CPutBits(b, 0, sda);
+ b->I2CUDelay(b, RISEFALLTIME);
+
+ r = I2CRaiseSCL(b, sda, timeout);
+ b->I2CUDelay(b, b->HoldTime);
+
+ b->I2CPutBits(b, 0, sda);
+ b->I2CUDelay(b, b->HoldTime);
+
+ return r;
+}
+
+static Bool
+I2CReadBit(I2CBusPtr b, int *psda, int timeout)
+{
+ Bool r;
+ int scl;
+
+ r = I2CRaiseSCL(b, 1, timeout);
+ b->I2CUDelay(b, b->HoldTime);
+
+ b->I2CGetBits(b, &scl, psda);
+
+ b->I2CPutBits(b, 0, 1);
+ b->I2CUDelay(b, b->HoldTime);
+
+ return r;
+}
+
+/* This is the default I2CPutByte function if not supplied by the driver.
+ *
+ * A single byte is sent to the device.
+ * The function returns FALSE if a timeout occurs, you should send
+ * a stop condition afterwards to reset the bus.
+ *
+ * A timeout occurs,
+ * if the slave pulls SCL to slow down the bus more than ByteTimeout usecs,
+ * or slows down the bus for more than BitTimeout usecs for each bit,
+ * or does not send an ACK bit (0) to acknowledge the transmission within
+ * AcknTimeout usecs, but a NACK (1) bit.
+ *
+ * AcknTimeout must be at least b->HoldTime, the other timeouts can be
+ * zero according to the comment on I2CRaiseSCL.
+ */
+
+static Bool
+I2CPutByte(I2CDevPtr d, I2CByte data)
+{
+ Bool r;
+ int i, scl, sda;
+ I2CBusPtr b = d->pI2CBus;
+
+ if (!I2CWriteBit(b, (data >> 7) & 1, d->ByteTimeout))
+ return FALSE;
+
+ for (i = 6; i >= 0; i--)
+ if (!I2CWriteBit(b, (data >> i) & 1, d->BitTimeout))
+ return FALSE;
+
+ b->I2CPutBits(b, 0, 1);
+ b->I2CUDelay(b, RISEFALLTIME);
+
+ r = I2CRaiseSCL(b, 1, b->HoldTime);
+
+ if (r) {
+ for (i = d->AcknTimeout; i > 0; i -= b->HoldTime) {
+ b->I2CUDelay(b, b->HoldTime);
+ b->I2CGetBits(b, &scl, &sda);
+ if (sda == 0) break;
+ }
+
+ if (i <= 0) {
+ I2C_TIMEOUT(ErrorF("[I2CPutByte(<%s>, 0x%02x, %d, %d, %d) timeout]",
+ b->BusName, data, d->BitTimeout,
+ d->ByteTimeout, d->AcknTimeout));
+ r = FALSE;
+ }
+
+ I2C_TRACE(ErrorF("W%02x%c ", (int) data, sda ? '-' : '+'));
+ }
+
+ b->I2CPutBits(b, 0, 1);
+ b->I2CUDelay(b, b->HoldTime);
+
+ return r;
+}
+
+/* This is the default I2CGetByte function if not supplied by the driver.
+ *
+ * A single byte is read from the device.
+ * The function returns FALSE if a timeout occurs, you should send
+ * a stop condition afterwards to reset the bus.
+ *
+ * A timeout occurs,
+ * if the slave pulls SCL to slow down the bus more than ByteTimeout usecs,
+ * or slows down the bus for more than b->BitTimeout usecs for each bit.
+ *
+ * ByteTimeout must be at least b->HoldTime, the other timeouts can be
+ * zero according to the comment on I2CRaiseSCL.
+ *
+ * For the <last> byte in a sequence the acknowledge bit NACK (1),
+ * otherwise ACK (0) will be sent.
+ */
+
+static Bool
+I2CGetByte(I2CDevPtr d, I2CByte *data, Bool last)
+{
+ int i, sda;
+ I2CBusPtr b = d->pI2CBus;
+
+ b->I2CPutBits(b, 0, 1);
+ b->I2CUDelay(b, RISEFALLTIME);
+
+ if (!I2CReadBit(b, &sda, d->ByteTimeout))
+ return FALSE;
+
+ *data = (sda > 0) << 7;
+
+ for (i = 6; i >= 0; i--)
+ if (!I2CReadBit(b, &sda, d->BitTimeout))
+ return FALSE;
+ else
+ *data |= (sda > 0) << i;
+
+ if (!I2CWriteBit(b, last ? 1 : 0, d->BitTimeout))
+ return FALSE;
+
+ I2C_TRACE(ErrorF("R%02x%c ", (int) *data, last ? '+' : '-'));
+
+ return TRUE;
+}
+
+/* This is the default I2CAddress function if not supplied by the driver.
+ *
+ * It creates the start condition, followed by the d->SlaveAddr.
+ * Higher level functions must call this routine rather than
+ * I2CStart/PutByte because a hardware I2C master may not be able
+ * to send a slave address without a start condition.
+ *
+ * The same timeouts apply as with I2CPutByte and additional a
+ * StartTimeout, similar to the ByteTimeout but for the start
+ * condition.
+ *
+ * In case of a timeout, the bus is left in a clean idle condition.
+ * I. e. you *must not* send a Stop. If this function succeeds, you *must*.
+ *
+ * The slave address format is 16 bit, with the legacy _8_bit_ slave address
+ * in the least significant byte. This is, the slave address must include the
+ * R/_W flag as least significant bit.
+ *
+ * The most significant byte of the address will be sent _after_ the LSB,
+ * but only if the LSB indicates:
+ * a) an 11 bit address, this is LSB = 1111 0xxx.
+ * b) a 'general call address', this is LSB = 0000 000x - see the I2C specs
+ * for more.
+ */
+
+static Bool
+I2CAddress(I2CDevPtr d, I2CSlaveAddr addr)
+{
+ if (I2CStart(d->pI2CBus, d->StartTimeout)) {
+ if (I2CPutByte(d, addr & 0xFF)) {
+ if ((addr & 0xF8) != 0xF0 &&
+ (addr & 0xFE) != 0x00)
+ return TRUE;
+
+ if (I2CPutByte(d, (addr >> 8) & 0xFF))
+ return TRUE;
+ }
+
+ I2CStop(d);
+ }
+
+ return FALSE;
+}
+
+/* These are the hardware independent I2C helper functions.
+ * ========================================================
+ */
+
+/* Function for probing. Just send the slave address
+ * and return true if the device responds. The slave address
+ * must have the lsb set to reflect a read (1) or write (0) access.
+ * Don't expect a read- or write-only device will respond otherwise.
+ */
+
+Bool
+xf86I2CProbeAddress(I2CBusPtr b, I2CSlaveAddr addr)
+{
+ int r;
+ I2CDevRec d;
+
+ d.DevName = "Probing";
+ d.BitTimeout = b->BitTimeout;
+ d.ByteTimeout = b->ByteTimeout;
+ d.AcknTimeout = b->AcknTimeout;
+ d.StartTimeout = b->StartTimeout;
+ d.SlaveAddr = addr;
+ d.pI2CBus = b;
+ d.NextDev = NULL;
+
+ r = b->I2CAddress(&d, addr);
+
+ if (r) b->I2CStop(&d);
+
+ return r;
+}
+
+/* All functions below are related to devices and take the
+ * slave address and timeout values from an I2CDevRec. They
+ * return FALSE in case of an error (presumably a timeout).
+ */
+
+/* General purpose read and write function.
+ *
+ * 1st, if nWrite > 0
+ * Send a start condition
+ * Send the slave address (1 or 2 bytes) with write flag
+ * Write n bytes from WriteBuffer
+ * 2nd, if nRead > 0
+ * Send a start condition [again]
+ * Send the slave address (1 or 2 bytes) with read flag
+ * Read n bytes to ReadBuffer
+ * 3rd, if a Start condition has been successfully sent,
+ * Send a Stop condition.
+ *
+ * The functions exits immediately when an error occures,
+ * not proceeding any data left. However, step 3 will
+ * be executed anyway to leave the bus in clean idle state.
+ */
+
+Bool
+xf86I2CWriteRead(I2CDevPtr d,
+ I2CByte *WriteBuffer, int nWrite,
+ I2CByte *ReadBuffer, int nRead)
+{
+ Bool r = TRUE;
+ I2CBusPtr b = d->pI2CBus;
+ int s = 0;
+
+ if (r && nWrite > 0) {
+ r = b->I2CAddress(d, d->SlaveAddr & ~1);
+ if (r) {
+ for (; nWrite > 0; WriteBuffer++, nWrite--)
+ if (!(r = b->I2CPutByte(d, *WriteBuffer)))
+ break;
+ s++;
+ }
+ }
+
+ if (r && nRead > 0) {
+ r = b->I2CAddress(d, d->SlaveAddr | 1);
+ if (r) {
+ for (; nRead > 0; ReadBuffer++, nRead--)
+ if (!(r = b->I2CGetByte(d, ReadBuffer, nRead == 1)))
+ break;
+ s++;
+ }
+ }
+
+ if (s) b->I2CStop(d);
+
+ return r;
+}
+
+/* Read a byte, the only readable register of a device.
+ */
+
+Bool
+xf86I2CReadStatus(I2CDevPtr d, I2CByte *pbyte)
+{
+ return xf86I2CWriteRead(d, NULL, 0, pbyte, 1);
+}
+
+/* Read a byte from one of the registers determined by its sub-address.
+ */
+
+Bool
+xf86I2CReadByte(I2CDevPtr d, I2CByte subaddr, I2CByte *pbyte)
+{
+ return xf86I2CWriteRead(d, &subaddr, 1, pbyte, 1);
+}
+
+/* Read bytes from subsequent registers determined by the
+ * sub-address of the first register.
+ */
+
+Bool
+xf86I2CReadBytes(I2CDevPtr d, I2CByte subaddr, I2CByte *pbyte, int n)
+{
+ return xf86I2CWriteRead(d, &subaddr, 1, pbyte, n);
+}
+
+/* Read a word (high byte, then low byte) from one of the registers
+ * determined by its sub-address.
+ */
+
+Bool
+xf86I2CReadWord(I2CDevPtr d, I2CByte subaddr, unsigned short *pword)
+{
+ I2CByte rb[2];
+
+ if (!xf86I2CWriteRead(d, &subaddr, 1, rb, 2)) return FALSE;
+
+ *pword = (rb[0] << 8) | rb[1];
+
+ return TRUE;
+}
+
+/* Write a byte to one of the registers determined by its sub-address.
+ */
+
+Bool
+xf86I2CWriteByte(I2CDevPtr d, I2CByte subaddr, I2CByte byte)
+{
+ I2CByte wb[2];
+
+ wb[0] = subaddr;
+ wb[1] = byte;
+
+ return xf86I2CWriteRead(d, wb, 2, NULL, 0);
+}
+
+/* Write bytes to subsequent registers determined by the
+ * sub-address of the first register.
+ */
+
+Bool
+xf86I2CWriteBytes(I2CDevPtr d, I2CByte subaddr,
+ I2CByte *WriteBuffer, int nWrite)
+{
+ I2CBusPtr b = d->pI2CBus;
+ Bool r = TRUE;
+
+ if (nWrite > 0) {
+ r = b->I2CAddress(d, d->SlaveAddr & ~1);
+ if (r){
+ if ((r = b->I2CPutByte(d, subaddr)))
+ for (; nWrite > 0; WriteBuffer++, nWrite--)
+ if (!(r = b->I2CPutByte(d, *WriteBuffer)))
+ break;
+
+ b->I2CStop(d);
+ }
+ }
+
+ return r;
+}
+
+/* Write a word (high byte, then low byte) to one of the registers
+ * determined by its sub-address.
+ */
+
+Bool
+xf86I2CWriteWord(I2CDevPtr d, I2CByte subaddr, unsigned short word)
+{
+ I2CByte wb[3];
+
+ wb[0] = subaddr;
+ wb[1] = word >> 8;
+ wb[2] = word & 0xFF;
+
+ return xf86I2CWriteRead(d, wb, 3, NULL, 0);
+}
+
+/* Write a vector of bytes to not adjacent registers. This vector is,
+ * 1st byte sub-address, 2nd byte value, 3rd byte sub-address asf.
+ * This function is intended to initialize devices. Note this function
+ * exits immediately when an error occurs, some registers may
+ * remain uninitialized.
+ */
+
+Bool
+xf86I2CWriteVec(I2CDevPtr d, I2CByte *vec, int nValues)
+{
+ I2CBusPtr b = d->pI2CBus;
+ Bool r = TRUE;
+ int s = 0;
+
+ if (nValues > 0) {
+ for (; nValues > 0; nValues--, vec += 2) {
+ if (!(r = b->I2CAddress(d, d->SlaveAddr & ~1)))
+ break;
+
+ s++;
+
+ if (!(r = b->I2CPutByte(d, vec[0])))
+ break;
+
+ if (!(r = b->I2CPutByte(d, vec[1])))
+ break;
+ }
+
+ if (s > 0) b->I2CStop(d);
+ }
+
+ return r;
+}
+
+/* Administrative functions.
+ * =========================
+ */
+
+/* Allocates an I2CDevRec for you and initializes with propper defaults
+ * you may modify before calling xf86I2CDevInit. Your I2CDevRec must
+ * contain at least a SlaveAddr, and a pI2CBus pointer to the bus this
+ * device shall be linked to.
+ *
+ * See function I2CAddress for the slave address format. Always set
+ * the least significant bit, indicating a read or write access, to zero.
+ */
+
+I2CDevPtr
+xf86CreateI2CDevRec(void)
+{
+ return xcalloc(1, sizeof(I2CDevRec));
+}
+
+/* Unlink an I2C device. If you got the I2CDevRec from xf86CreateI2CDevRec
+ * you should set <unalloc> to free it.
+ */
+
+void
+xf86DestroyI2CDevRec(I2CDevPtr d, Bool unalloc)
+{
+ if (d) {
+ I2CDevPtr *p;
+
+ /* Remove this from the list of active I2C devices. */
+
+ for (p = &d->pI2CBus->FirstDev; *p != NULL; p = &(*p)->NextDev)
+ if (*p == d) {
+ *p = (*p)->NextDev;
+ break;
+ }
+
+ if (d->pI2CBus->scrnIndex >= 0)
+ xf86DrvMsg(d->pI2CBus->scrnIndex, X_INFO,
+ "I2C device \"%s:%s\" removed.\n",
+ d->pI2CBus->BusName, d->DevName);
+ else
+ xf86Msg(X_INFO, "I2C device \"%s:%s\" removed.\n",
+ d->pI2CBus->BusName, d->DevName);
+
+ if (unalloc) xfree(d);
+ }
+}
+
+/* I2C transmissions are related to an I2CDevRec you must link to a
+ * previously registered bus (see xf86I2CBusInit) before attempting
+ * to read and write data. You may call xf86I2CProbeAddress first to
+ * see if the device in question is present on this bus.
+ *
+ * xf86I2CDevInit will not allocate an I2CBusRec for you, instead you
+ * may enter a pointer to a statically allocated I2CDevRec or the (modified)
+ * result of xf86CreateI2CDevRec.
+ *
+ * If you don't specify timeouts for the device (n <= 0), it will inherit
+ * the bus-wide defaults. The function returns TRUE on success.
+ */
+
+Bool
+xf86I2CDevInit(I2CDevPtr d)
+{
+ I2CBusPtr b;
+
+ if (d == NULL ||
+ (b = d->pI2CBus) == NULL ||
+ (d->SlaveAddr & 1) ||
+ xf86I2CFindDev(b, d->SlaveAddr) != NULL)
+ return FALSE;
+
+ if (d->BitTimeout <= 0) d->BitTimeout = b->BitTimeout;
+ if (d->ByteTimeout <= 0) d->ByteTimeout = b->ByteTimeout;
+ if (d->AcknTimeout <= 0) d->AcknTimeout = b->AcknTimeout;
+ if (d->StartTimeout <= 0) d->StartTimeout = b->StartTimeout;
+
+ d->NextDev = b->FirstDev;
+ b->FirstDev = d;
+
+ if(b->scrnIndex >= 0)
+ xf86DrvMsg(b->scrnIndex, X_INFO, "I2C device \"%s:%s\" registered.\n",
+ b->BusName, d->DevName);
+ else
+ xf86Msg(X_INFO, "I2C device \"%s:%s\" registered.\n",
+ b->BusName, d->DevName);
+
+ return TRUE;
+}
+
+I2CDevPtr
+xf86I2CFindDev(I2CBusPtr b, I2CSlaveAddr addr)
+{
+ I2CDevPtr d;
+
+ if (b) {
+ for (d = b->FirstDev; d != NULL; d = d->NextDev)
+ if (d->SlaveAddr == addr)
+ return d;
+ }
+
+ return NULL;
+}
+
+static I2CBusPtr I2CBusList;
+
+/* Allocates an I2CBusRec for you and initializes with propper defaults
+ * you may modify before calling xf86I2CBusInit. Your I2CBusRec must
+ * contain at least a BusName, a scrnIndex (or -1), and a complete set
+ * of either high or low level I2C function pointers. You may pass
+ * bus-wide timeouts, otherwise inplausible values will be replaced
+ * with safe defaults.
+ */
+
+I2CBusPtr
+xf86CreateI2CBusRec(void)
+{
+ I2CBusPtr b;
+
+ b = (I2CBusPtr) xcalloc(1, sizeof(I2CBusRec));
+
+ if (b != NULL) {
+ b->scrnIndex = -1;
+ b->HoldTime = 5; /* 100 kHz bus */
+ b->BitTimeout = 5;
+ b->ByteTimeout = 5;
+ b->AcknTimeout = 5;
+ b->StartTimeout = 5;
+ }
+
+ return b;
+}
+
+/* Unregister an I2C bus. If you got the I2CBusRec from xf86CreateI2CBusRec
+ * you should set <unalloc> to free it. If you set <devs_too>, the function
+ * xf86DestroyI2CDevRec will be called for all devices linked to the bus
+ * first, passing down the <unalloc> option.
+ */
+
+void
+xf86DestroyI2CBusRec(I2CBusPtr b, Bool unalloc, Bool devs_too)
+{
+ if (b) {
+ I2CBusPtr *p;
+
+ /* Remove this from the list of active I2C busses. */
+
+ for (p = &I2CBusList; *p != NULL; p = &(*p)->NextBus)
+ if (*p == b) {
+ *p = (*p)->NextBus;
+ break;
+ }
+
+ if (b->FirstDev != NULL) {
+ if (devs_too) {
+ I2CDevPtr d;
+
+ while ((d = b->FirstDev) != NULL)
+ xf86DestroyI2CDevRec(d, unalloc);
+ } else {
+ if (unalloc) {
+ xf86Msg(X_ERROR, "i2c bug: Attempt to remove I2C bus \"%s\", "
+ "but device list is not empty.\n",
+ b->BusName);
+ return;
+ }
+ }
+ }
+
+ if (b->scrnIndex >= 0)
+ xf86DrvMsg(b->scrnIndex, X_INFO, "I2C bus \"%s\" removed.\n",
+ b->BusName);
+ else
+ xf86Msg(X_INFO, "I2C bus \"%s\" removed.\n", b->BusName);
+
+ if (unalloc) xfree(b);
+ }
+}
+
+/* I2C masters have to register themselves using this function.
+ * It will not allocate an I2CBusRec for you, instead you may enter
+ * a pointer to a statically allocated I2CBusRec or the (modified)
+ * result of xf86CreateI2CBusRec. Returns TRUE on success.
+ *
+ * At this point there won't be any traffic on the I2C bus.
+ */
+
+Bool
+xf86I2CBusInit(I2CBusPtr b)
+{
+ /* I2C busses must be identified by a unique scrnIndex
+ * and name. If scrnIndex is unspecified (a negative value),
+ * then the name must be unique throughout the server.
+ */
+
+ if (b->BusName == NULL ||
+ xf86I2CFindBus(b->scrnIndex, b->BusName) != NULL)
+ return FALSE;
+
+ /* If the high level functions are not
+ * supplied, use the generic functions.
+ * In this case we need the low-level
+ * function.
+ */
+
+ if (b->I2CPutBits == NULL ||
+ b->I2CGetBits == NULL)
+ {
+ if (b->I2CPutByte == NULL ||
+ b->I2CGetByte == NULL ||
+ b->I2CAddress == NULL ||
+ b->I2CStop == NULL)
+ return FALSE;
+ } else {
+ b->I2CPutByte = I2CPutByte;
+ b->I2CGetByte = I2CGetByte;
+ b->I2CAddress = I2CAddress;
+ b->I2CStop = I2CStop;
+ }
+
+ if (b->I2CUDelay == NULL)
+ b->I2CUDelay = I2CUDelay;
+
+ if (b->HoldTime < 2) b->HoldTime = 5;
+ if (b->BitTimeout <= 0) b->BitTimeout = b->HoldTime;
+ if (b->ByteTimeout <= 0) b->ByteTimeout = b->HoldTime;
+ if (b->AcknTimeout <= 0) b->AcknTimeout = b->HoldTime;
+ if (b->StartTimeout <= 0) b->StartTimeout = b->HoldTime;
+
+ /* Put new bus on list. */
+
+ b->NextBus = I2CBusList;
+ I2CBusList = b;
+
+ if (b->scrnIndex >= 0)
+ xf86DrvMsg(b->scrnIndex, X_INFO, "I2C bus \"%s\" initialized.\n",
+ b->BusName);
+ else
+ xf86Msg(X_INFO, "I2C bus \"%s\" initialized.\n", b->BusName);
+
+ return TRUE;
+}
+
+I2CBusPtr
+xf86I2CFindBus(int scrnIndex, char *name)
+{
+ I2CBusPtr p;
+
+ if (name != NULL)
+ for (p = I2CBusList; p != NULL; p = p->NextBus)
+ if (scrnIndex < 0 || p->scrnIndex == scrnIndex)
+ if (!strcmp(p->BusName, name))
+ return p;
+
+ return NULL;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/i2c/xf86i2c.h b/xc/programs/Xserver/hw/xfree86/i2c/xf86i2c.h
new file mode 100644
index 000000000..1bb60562d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/i2c/xf86i2c.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 1998 Itai Nahshon, Michael Schimek
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/i2c/xf86i2c.h,v 1.4 1999/04/11 13:11:01 dawes Exp $ */
+#ifndef _XF86I2C_H
+#define _XF86I2C_H
+
+typedef unsigned char I2CByte;
+typedef unsigned short I2CSlaveAddr;
+
+typedef struct _I2CBusRec *I2CBusPtr;
+typedef struct _I2CDevRec *I2CDevPtr;
+
+/* I2C masters have to register themselves */
+
+typedef struct _I2CBusRec {
+ char * BusName;
+ int scrnIndex;
+
+ void (*I2CUDelay) (I2CBusPtr b, int usec);
+
+ void (*I2CPutBits)(I2CBusPtr b, int scl, int sda);
+ void (*I2CGetBits)(I2CBusPtr b, int *scl, int *sda);
+
+ /* Look at the generic routines to see how these functions should behave. */
+
+ Bool (*I2CAddress)(I2CDevPtr d, I2CSlaveAddr);
+ void (*I2CStop) (I2CDevPtr d);
+ Bool (*I2CPutByte)(I2CDevPtr d, I2CByte data);
+ Bool (*I2CGetByte)(I2CDevPtr d, I2CByte *data, Bool);
+
+ DevUnion DriverPrivate;
+
+ int HoldTime; /* 1 / bus clock frequency, 5 or 2 usec */
+
+ int BitTimeout; /* usec */
+ int ByteTimeout; /* usec */
+ int AcknTimeout; /* usec */
+ int StartTimeout; /* usec */
+
+ I2CDevPtr FirstDev;
+ I2CBusPtr NextBus;
+} I2CBusRec;
+
+I2CBusPtr xf86CreateI2CBusRec(void);
+void xf86DestroyI2CBusRec(I2CBusPtr pI2CBus, Bool unalloc, Bool devs_too);
+Bool xf86I2CBusInit(I2CBusPtr pI2CBus);
+I2CBusPtr xf86I2CFindBus(int scrnIndex, char *name);
+
+/* I2C slave devices */
+
+typedef struct _I2CDevRec {
+ char * DevName;
+
+ int BitTimeout; /* usec */
+ int ByteTimeout; /* usec */
+ int AcknTimeout; /* usec */
+ int StartTimeout; /* usec */
+
+ I2CSlaveAddr SlaveAddr;
+ I2CBusPtr pI2CBus;
+ I2CDevPtr NextDev;
+} I2CDevRec;
+
+I2CDevPtr xf86CreateI2CDevRec(void);
+void xf86DestroyI2CDevRec(I2CDevPtr pI2CDev, Bool unalloc);
+Bool xf86I2CDevInit(I2CDevPtr pI2CDev);
+I2CDevPtr xf86I2CFindDev(I2CBusPtr, I2CSlaveAddr);
+
+/* See descriptions of these functions in xf86i2c.c */
+
+Bool xf86I2CProbeAddress(I2CBusPtr pI2CBus, I2CSlaveAddr);
+Bool xf86I2CWriteRead(I2CDevPtr d, I2CByte *WriteBuffer, int nWrite,
+ I2CByte *ReadBuffer, int nRead);
+#define xf86I2CRead(d, rb, nr) xf86I2CWriteRead(d, NULL, 0, rb, nr)
+Bool xf86I2CReadStatus(I2CDevPtr d, I2CByte *pbyte);
+Bool xf86I2CReadByte(I2CDevPtr d, I2CByte subaddr, I2CByte *pbyte);
+Bool xf86I2CReadBytes(I2CDevPtr d, I2CByte subaddr, I2CByte *pbyte, int n);
+Bool xf86I2CReadWord(I2CDevPtr d, I2CByte subaddr, unsigned short *pword);
+#define xf86I2CWrite(d, wb, nw) xf86I2CWriteRead(d, wb, nw, NULL, 0)
+Bool xf86I2CWriteByte(I2CDevPtr d, I2CByte subaddr, I2CByte byte);
+Bool xf86I2CWriteBytes(I2CDevPtr d, I2CByte subaddr, I2CByte *WriteBuffer, int nWrite);
+Bool xf86I2CWriteWord(I2CDevPtr d, I2CByte subaddr, unsigned short word);
+Bool xf86I2CWriteVec(I2CDevPtr d, I2CByte *vec, int nValues);
+
+#endif /*_XF86I2C_H */
diff --git a/xc/programs/Xserver/hw/xfree86/i2c/xf86i2cmodule.c b/xc/programs/Xserver/hw/xfree86/i2c/xf86i2cmodule.c
new file mode 100644
index 000000000..de923b2f0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/i2c/xf86i2cmodule.c
@@ -0,0 +1,34 @@
+/* (c) Itai Nahshon
+ *
+ * This code is derived from and inspired by the I2C driver
+ * from the Linux kernel.
+ * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/i2c/xf86i2cmodule.c,v 1.7 1999/04/11 13:11:02 dawes Exp $ */
+
+#include "xf86Module.h"
+
+static MODULESETUPPROTO(i2cSetup);
+
+static XF86ModuleVersionInfo i2cVersRec =
+{
+ "i2c",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 2, 0,
+ ABI_CLASS_VIDEODRV, /* This needs the video driver ABI */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0}
+};
+
+XF86ModuleData i2cModuleData = { &i2cVersRec, i2cSetup, NULL };
+
+static pointer
+i2cSetup(pointer module, pointer opts, int *errmaj, int *errmin) {
+/* ErrorF("i2cSetup\n"); */
+ return (pointer)1;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/input/Imakefile b/xc/programs/Xserver/hw/xfree86/input/Imakefile
new file mode 100644
index 000000000..e4639afef
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/Imakefile
@@ -0,0 +1,59 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/Imakefile,v 1.11 1999/06/12 15:37:09 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+#define IHaveSubdirs
+
+#if JoystickSupport
+JOYSTICKDIR = joystick
+#endif
+
+#if NewInput
+MOUSEDIR = mouse
+#endif
+
+SUBDIRS = $(MOUSEDIR) XInputDrivers $(JOYSTICKDIR)
+#if !NewInput
+DRIVERS = XInputDrivers $(JOYSTICKDIR)
+#else
+DRIVERS = mouse XInputDrivers
+#endif
+
+#ifndef OS2Architecture
+OBJS = `cat idriver.list`
+#else
+OBJS = ??
+#endif
+
+#if DoLoadableServer
+MakeSubdirs($(SUBDIRS))
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+DONES = $(SUBDIRS:%=%/DONE)
+#if HasGnuMake || HasBsdMake
+$(DONES): $(SUBDIRS)
+#endif
+#if !DoLoadableServer
+NormalDepLibraryTarget(idriver,$(SUBDIRS) $(DONES) idriver.list,$(OBJS))
+#endif
+#else
+#if !DoLoadableServer
+NormalDepLibraryTarget(idriver,$(SUBDIRS) idriver.list,$(OBJS))
+#endif
+#endif
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/include \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC)
+
+#if !DoLoadableServer
+ConfigTargetNoDepend(drvConf,$(ICONFIGFILES),confdrv.SHsuf,$(DRIVERS))
+DriverObjectList($(DRIVERS),idriver.list)
+#endif
+
+NormalLibraryObjectRule()
+
+ForceSubdirs($(SUBDIRS))
+
+DependSubdirs($(SUBDIRS))
+
diff --git a/xc/programs/Xserver/hw/xfree86/input/acecad/Imakefile b/xc/programs/Xserver/hw/xfree86/input/acecad/Imakefile
new file mode 100644
index 000000000..4390a8d9d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/acecad/Imakefile
@@ -0,0 +1,26 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/acecad/Imakefile,v 1.4 1999/08/14 10:49:59 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = xf86AceCad.c
+OBJS = xf86AceCad.o
+
+DRIVER = xf86AceCad
+
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86SRC)/loader -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget($(DRIVER),$(OBJS))
+
+InstallObjectModule($(DRIVER),$(MODULEDIR),input)
+
+DependTarget()
+
+InstallDriverSDKObjectModule($(DRIVER),$(DRIVERSDKMODULEDIR),input)
diff --git a/xc/programs/Xserver/hw/xfree86/input/acecad/xf86AceCad.c b/xc/programs/Xserver/hw/xfree86/input/acecad/xf86AceCad.c
new file mode 100644
index 000000000..b96a28a8d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/acecad/xf86AceCad.c
@@ -0,0 +1,1037 @@
+/*
+ * Copyright 1996 by Steven Lang <tiger@tyger.org>
+ * Modified for the AceCad Tablet,
+ * by Shane Watts <shane@bofh.asn.au>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Steven Lang not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. Steven Lang makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * STEVEN LANG DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL STEVEN LANG 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 ACTIONS, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/acecad/xf86AceCad.c,v 1.3 1999/06/13 05:18:54 dawes Exp $ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "XI.h"
+#include "XIproto.h"
+
+#if defined(sun) && !defined(i386)
+#define POSIX_TTY
+#include <errno.h>
+#include <termio.h>
+#include <fcntl.h>
+#include <ctype.h>
+
+#include "extio.h"
+#else
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSproc.h"
+#ifdef XFree86LOADER
+#include "xf86_ansic.h"
+#endif
+#include "xf86Config.h"
+#include "xf86Xinput.h"
+#include "atKeynames.h"
+#include "xf86Version.h"
+#endif
+
+#if !defined(sun) || defined(i386)
+#include "osdep.h"
+#include "exevents.h"
+
+#include "extnsionst.h"
+#include "extinit.h"
+#endif
+
+/*
+** Debugging macros
+*/
+#ifdef DBG
+#undef DBG
+#endif
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+static int debug_level = 0;
+#define DEBUG 1
+#if DEBUG
+#define DBG(lvl, f) {if ((lvl) <= debug_level) f;}
+#else
+#define DBG(lvl, f)
+#endif
+
+/*
+** Device records
+*/
+#define ABSOLUTE_FLAG 1
+#define STYLUS_FLAG 2
+
+typedef struct
+{
+ char *acecadDevice; /* device file name */
+ int acecadInc; /* increment between transmits */
+ int acecadButTrans; /* button translation flags */
+ int acecadOldX; /* previous X position */
+ int acecadOldY; /* previous Y position */
+ int acecadOldProximity; /* previous proximity */
+ int acecadOldButtons; /* previous buttons state */
+ int acecadMaxX; /* max X value */
+ int acecadMaxY; /* max Y value */
+ int acecadXLeft; /* screen left */
+ int acecadXRight; /* screen right */
+ int acecadYtop; /* screen top */
+ int acecadYbot; /* screen bottom */
+ int acecadRes; /* resolution in lines per inch */
+ int flags; /* various flags */
+ int acecadIndex; /* number of bytes read */
+ unsigned char acecadData[5]; /* data read on the device */
+} AceCadDeviceRec, *AceCadDevicePtr;
+
+/*
+** Configuration data
+*/
+#define ACECAD_SECTION_NAME "AceCad"
+#define PORT 1
+#define DEVICENAME 2
+#define THE_MODE 3
+#define CURSOR 4
+#define INCREMENT 5
+#define BORDER 6
+#define DEBUG_LEVEL 7
+#define HISTORY_SIZE 8
+#define ALWAYS_CORE 9
+
+#if !defined(sun) || defined(i386)
+static SymTabRec AceCadTab[] = {
+ {ENDSUBSECTION, "endsubsection"},
+ {PORT, "port"},
+ {DEVICENAME, "devicename"},
+ {THE_MODE, "mode"},
+ {CURSOR, "cursor"},
+ {INCREMENT, "increment"},
+ {BORDER, "border"},
+ {DEBUG_LEVEL, "debuglevel"},
+ {HISTORY_SIZE, "historysize"},
+ { ALWAYS_CORE, "alwayscore" },
+ {-1, ""}
+};
+
+#define RELATIVE 1
+#define ABSOLUTE 2
+
+static SymTabRec AceCadModeTabRec[] = {
+ {RELATIVE, "relative"},
+ {ABSOLUTE, "absolute"},
+ {-1, ""}
+};
+
+#define PUCK 1
+#define STYLUS 2
+
+static SymTabRec AceCadPointTabRec[] = {
+ {PUCK, "puck"},
+ {STYLUS, "stylus"},
+ {-1, ""}
+};
+
+#endif
+
+/*
+** Contants and macro
+*/
+#define BUFFER_SIZE 256 /* size of reception buffer */
+#define XI_NAME "ACECAD" /* X device name for the stylus */
+
+#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
+
+#define ACECAD_CONFIG "a" /* Send configuration (max coords) */
+
+#define ACECAD_ABSOLUTE 'F' /* Absolute mode */
+#define ACECAD_RELATIVE 'E' /* Relative mode */
+
+#define ACECAD_UPPER_ORIGIN "b" /* Origin upper left */
+
+#define ACECAD_PROMPT_MODE "B" /* Prompt mode */
+#define ACECAD_STREAM_MODE "@" /* Stream mode */
+#define ACECAD_INCREMENT 'I' /* Set increment */
+#define ACECAD_BINARY_FMT "zb" /* Binary reporting */
+
+#define ACECAD_PROMPT "P" /* Prompt for current position */
+
+static const char * acecad_initstr = ACECAD_BINARY_FMT ACECAD_STREAM_MODE;
+
+#define PHASING_BIT 0x80
+#define PROXIMITY_BIT 0x40
+#define TABID_BIT 0x20
+#define XSIGN_BIT 0x10
+#define YSIGN_BIT 0x08
+#define BUTTON_BITS 0x07
+#define COORD_BITS 0x7f
+
+/*
+** External declarations
+*/
+#if defined(sun) && !defined(i386)
+#define ENQUEUE suneqEnqueue
+#else
+#define ENQUEUE xf86eqEnqueue
+
+extern void xf86eqEnqueue(
+#if NeedFunctionPrototypes
+ xEventPtr /*e*/
+#endif
+);
+#endif
+
+extern void miPointerDeltaCursor(
+#if NeedFunctionPrototypes
+ int /*dx*/,
+ int /*dy*/,
+ unsigned long /*time*/
+#endif
+);
+
+#if !defined(sun) || defined(i386)
+/*
+** xf86AceCadConfig
+** Reads the AceCad section from the XF86Config file
+*/
+static Bool
+xf86AceCadConfig(LocalDevicePtr *array, int inx, int max, LexPtr val)
+{
+ LocalDevicePtr dev = array[inx];
+ AceCadDevicePtr priv = (AceCadDevicePtr)(dev->private);
+ int token;
+ int mtoken;
+
+ DBG(1, ErrorF("xf86AceCadConfig\n"));
+
+ while ((token = xf86GetToken(AceCadTab)) != ENDSUBSECTION) {
+ switch(token) {
+ case DEVICENAME:
+ if (xf86GetToken(NULL) != STRING)
+ xf86ConfigError("Option string expected");
+ else {
+ dev->name = strdup(val->str);
+ if (xf86Verbose)
+ ErrorF("%s AceCad X device name is %s\n", XCONFIG_GIVEN,
+ dev->name);
+ }
+ break;
+
+ case PORT:
+ if (xf86GetToken(NULL) != STRING)
+ xf86ConfigError("Option string expected");
+ else {
+ priv->acecadDevice = strdup(val->str);
+ if (xf86Verbose)
+ ErrorF("%s AceCad port is %s\n", XCONFIG_GIVEN,
+ priv->acecadDevice);
+ }
+ break;
+
+ case THE_MODE:
+ mtoken = xf86GetToken(AceCadModeTabRec);
+ if ((mtoken == EOF) || (mtoken == STRING) || (mtoken == NUMBER))
+ xf86ConfigError("Mode type token expected");
+ else {
+ switch (mtoken) {
+ case ABSOLUTE:
+ priv->flags |= ABSOLUTE_FLAG;
+ break;
+ case RELATIVE:
+ priv->flags &= ~ABSOLUTE_FLAG;
+ break;
+ default:
+ xf86ConfigError("Illegal Mode type");
+ break;
+ }
+ }
+ break;
+
+ case CURSOR:
+ mtoken = xf86GetToken(AceCadPointTabRec);
+ if ((mtoken == EOF) || (mtoken == STRING) || (mtoken == NUMBER))
+ xf86ConfigError("Cursor token expected");
+ else {
+ switch (mtoken) {
+ case STYLUS:
+ priv->flags |= STYLUS_FLAG;
+ break;
+ case PUCK:
+ priv->flags &= ~STYLUS_FLAG;
+ break;
+ default:
+ xf86ConfigError("Illegal cursor type");
+ break;
+ }
+ }
+ break;
+
+ case INCREMENT:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ priv->acecadInc = val->num;
+ if (xf86Verbose)
+ ErrorF("%s AceCad increment value is %d\n", XCONFIG_GIVEN,
+ priv->acecadInc);
+ break;
+
+ case DEBUG_LEVEL:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ debug_level = val->num;
+ if (xf86Verbose) {
+#if DEBUG
+ ErrorF("%s AceCad debug level sets to %d\n", XCONFIG_GIVEN,
+ debug_level);
+#else
+ ErrorF("%s AceCad debug level not sets to %d because"
+ " debugging is not compiled\n", XCONFIG_GIVEN,
+ debug_level);
+#endif
+ }
+ break;
+
+ case HISTORY_SIZE:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ dev->history_size = val->num;
+ if (xf86Verbose)
+ ErrorF("%s AceCad Motion history size is %d\n", XCONFIG_GIVEN,
+ dev->history_size);
+ break;
+
+ case ALWAYS_CORE:
+ xf86AlwaysCore(dev, TRUE);
+ if (xf86Verbose)
+ ErrorF("%s AceCad device always stays core pointer\n",
+ XCONFIG_GIVEN);
+ break;
+
+ case EOF:
+ FatalError("Unexpected EOF (missing EndSubSection)");
+ break;
+
+ default:
+ xf86ConfigError("AceCad subsection keyword expected");
+ break;
+ }
+ }
+
+ DBG(1, ErrorF("xf86AceCadConfig name=%s\n", priv->acecadDevice));
+
+ return Success;
+}
+#endif
+
+/*
+** xf86AceCadReadInput
+** Reads from the AceCad and posts any new events to the server.
+*/
+static void
+xf86AceCadReadInput(LocalDevicePtr local)
+{
+ AceCadDevicePtr priv = (AceCadDevicePtr) local->private;
+ int len, loop;
+ int is_core_pointer, is_absolute;
+ int x, y, buttons, prox;
+ DeviceIntPtr device;
+ unsigned char buffer[BUFFER_SIZE];
+
+ DBG(7, ErrorF("xf86AceCadReadInput BEGIN device=%s fd=%d\n",
+ priv->acecadDevice, local->fd));
+
+ SYSCALL(len = read(local->fd, buffer, sizeof(buffer)));
+
+ if (len <= 0) {
+ Error("error reading AceCad device");
+ return;
+ }
+
+ for(loop=0; loop<len; loop++) {
+
+/* Format of 5 bytes data packet for AceCad Tablets
+ Byte 1
+ bit 7 Phasing bit always 1
+ bit 6 Proximity bit
+ bit 5 Tablet ID
+ bit 4 X sign (Always 1 for absolute)
+ bit 3 Y sign (Always 1 for absolute)
+ bit 2-0 Button status
+
+ Byte 2
+ bit 7 Always 0
+ bits 6-0 = X6 - X0
+
+ Byte 3 (Absolute mode only)
+ bit 7 Always 0
+ bits 6-0 = X13 - X7
+
+ Byte 4
+ bit 7 Always 0
+ bits 6-0 = Y6 - Y0
+
+ Byte 5 (Absolute mode only)
+ bit 7 Always 0
+ bits 6-0 = Y13 - Y7
+*/
+
+ if ((priv->acecadIndex == 0) && !(buffer[loop] & PHASING_BIT)) { /* magic bit is not OK */
+ DBG(6, ErrorF("xf86AceCadReadInput bad magic number 0x%x\n", buffer[loop]));;
+ continue;
+ }
+
+ priv->acecadData[priv->acecadIndex++] = buffer[loop];
+
+ if (priv->acecadIndex == (priv->flags & ABSOLUTE_FLAG? 5: 3)) {
+/* the packet is OK */
+/* reset char count for next read */
+ priv->acecadIndex = 0;
+
+ if (priv->flags & ABSOLUTE_FLAG) {
+ x = (int)priv->acecadData[1] + ((int)priv->acecadData[2] << 7);
+ y = (int)priv->acecadData[3] + ((int)priv->acecadData[4] << 7);
+ } else {
+ x = priv->acecadData[0] & XSIGN_BIT? priv->acecadData[1]: -priv->acecadData[1];
+ y = priv->acecadData[0] & YSIGN_BIT? priv->acecadData[2]: -priv->acecadData[2];
+ }
+
+/* x = priv->acecadMaxX - x; /**/
+ y = priv->acecadMaxY - y; /**/
+
+ prox = (priv->acecadData[0] & PROXIMITY_BIT)? 0: 1;
+
+ buttons = (priv->acecadData[0] & BUTTON_BITS);
+
+ device = local->dev;
+
+ DBG(6, ErrorF("prox=%s\tx=%d\ty=%d\tbuttons=%d\n",
+ prox ? "true" : "false", x, y, buttons));
+
+ is_absolute = (priv->flags & ABSOLUTE_FLAG);
+ is_core_pointer = xf86IsCorePointer(device);
+
+ if (is_core_pointer) {
+ x = x * screenInfo.screens[0]->width / priv->acecadMaxX;
+ y = y * screenInfo.screens[0]->height / priv->acecadMaxY;
+ DBG(6, ErrorF("Adjusted coords x=%d y=%d\n", x, y));
+ }
+
+/* coordonates are ready we can send events */
+ if (prox) {
+ if (!(priv->acecadOldProximity))
+ if (!is_core_pointer)
+ xf86PostProximityEvent(device, 1, 0, 2, x, y);
+
+ if ((is_absolute && ((priv->acecadOldX != x) || (priv->acecadOldY != y)))
+ || (!is_absolute && (x || y))) {
+ if (is_absolute || priv->acecadOldProximity) {
+ xf86PostMotionEvent(device, is_absolute, 0, 2, x, y);
+ }
+ }
+
+ if (priv->acecadOldButtons != buttons) {
+ int delta;
+ int button;
+
+ delta = buttons - priv->acecadOldButtons;
+ button = (delta > 0)? delta: ((delta == 0)?
+ priv->acecadOldButtons : -delta);
+
+ if (priv->acecadOldButtons != buttons) {
+ DBG(6, ErrorF("xf86AceCadReadInput button=%d\n", button));
+
+ xf86PostButtonEvent(device, is_absolute, button,
+ (delta >0), 0, 2, x, y);
+ }
+
+ }
+
+ priv->acecadOldButtons = buttons;
+ priv->acecadOldX = x;
+ priv->acecadOldY = y;
+ priv->acecadOldProximity = prox;
+ } else { /* !PROXIMITY */
+/* Any changes in buttons are ignored when !proximity */
+ if (!is_core_pointer)
+ if (priv->acecadOldProximity)
+ xf86PostProximityEvent(device, 0, 0, 2, x, y);
+ priv->acecadOldProximity = 0;
+ }
+ }
+ }
+ DBG(7, ErrorF("xf86AceCadReadInput END device=0x%x priv=0x%x\n",
+ local->dev, priv));
+}
+
+/*
+** xf86AceCadControlProc
+** It really does do something. Honest!
+*/
+static void
+xf86AceCadControlProc(DeviceIntPtr device, PtrCtrl *ctrl)
+{
+ DBG(2, ErrorF("xf86AceCadControlProc\n"));
+}
+
+/*
+** write_and_read
+** Write data, and get the response.
+*/
+static char *
+write_and_read(int fd, char *data, char *buffer, int len, int cr_term)
+{
+ int err, numread = 0;
+ fd_set readfds;
+ struct timeval timeout;
+
+ SYSCALL(err = write(fd, data, strlen(data)));
+ if (err == -1) {
+ Error("AceCad write");
+ return NULL;
+ }
+
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+ while (numread < len) {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 200000;
+
+ SYSCALL(err = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout));
+ if (err == -1) {
+ Error("AceCad select");
+ return NULL;
+ }
+ if (!err) {
+ ErrorF("Timeout while reading AceCad tablet. No tablet connected ???\n");
+ return NULL;
+ }
+
+ SYSCALL(err = read(fd, buffer + numread++, 1));
+ if (err == -1) {
+ Error("AceCad read");
+ return NULL;
+ }
+ if (!err) {
+ --numread;
+ break;
+ }
+ if (cr_term && buffer[numread - 1] == '\r') {
+ break;
+ buffer[numread - 1] = 0;
+ }
+ }
+ buffer[numread] = 0;
+ return buffer;
+}
+
+/*
+** xf86AceCadOpen
+** Open and initialize the tablet, as well as probe for any needed data.
+*/
+static Bool
+xf86AceCadOpen(LocalDevicePtr local)
+{
+ struct termios termios_tty;
+ struct timeval timeout;
+ char buffer[256];
+ int err;
+ AceCadDevicePtr priv = (AceCadDevicePtr)local->private;
+
+ DBG(1, ErrorF("opening %s\n", priv->acecadDevice));
+
+ SYSCALL(local->fd = open(priv->acecadDevice, O_RDWR|O_NDELAY, 0));
+ if (local->fd == -1) {
+ Error(priv->acecadDevice);
+ return !Success;
+ }
+ DBG(2, ErrorF("%s opened as fd %d\n", priv->acecadDevice, local->fd));
+
+#ifdef POSIX_TTY
+ err = tcgetattr(local->fd, &termios_tty);
+ if (err == -1) {
+ Error("AceCad tcgetattr");
+ return !Success;
+ }
+ termios_tty.c_iflag = IXOFF;
+ termios_tty.c_cflag = B9600|CS8|CREAD|CLOCAL|HUPCL|PARENB|PARODD;
+ termios_tty.c_lflag = 0;
+
+/* I wonder what these all do, anyway */
+ termios_tty.c_cc[VINTR] = 0;
+ termios_tty.c_cc[VQUIT] = 0;
+ termios_tty.c_cc[VERASE] = 0;
+#ifdef VWERASE
+ termios_tty.c_cc[VWERASE] = 0;
+#endif
+#ifdef VREPRINT
+ termios_tty.c_cc[VREPRINT] = 0;
+#endif
+ termios_tty.c_cc[VKILL] = 0;
+ termios_tty.c_cc[VEOF] = 0;
+ termios_tty.c_cc[VEOL] = 0;
+#ifdef VEOL2
+ termios_tty.c_cc[VEOL2] = 0;
+#endif
+ termios_tty.c_cc[VSUSP] = 0;
+#ifdef VDISCARD
+ termios_tty.c_cc[VDISCARD] = 0;
+#endif
+#ifdef VLNEXT
+ termios_tty.c_cc[VLNEXT] = 0;
+#endif
+
+ termios_tty.c_cc[VMIN] = 1 ;
+ termios_tty.c_cc[VTIME] = 10 ;
+
+ err = tcsetattr(local->fd, TCSANOW, &termios_tty);
+ if (err == -1) {
+ Error("AceCad tcsetattr TCSANOW");
+ return !Success;
+ }
+#else
+ Code for someone else to write to handle OSs without POSIX tty functions
+#endif
+
+ DBG(1, ErrorF("initializing AceCad tablet\n"));
+
+/* Send reset (NULL) to the tablet */
+ SYSCALL(err = write(local->fd, "\0", 1));
+ if (err == -1) {
+ Error("AceCad write");
+ return !Success;
+ }
+
+/* wait 200 mSecs, just in case */
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 200000;
+ SYSCALL(err = select(0, NULL, NULL, NULL, &timeout));
+ if (err == -1) {
+ Error("AceCad select");
+ return !Success;
+ }
+
+/* Put it in prompt mode so it doens't say anything before we're ready */
+ SYSCALL(err = write(local->fd, ACECAD_PROMPT_MODE, strlen(ACECAD_PROMPT_MODE)));
+ if (err == -1) {
+ Error("AceCad write");
+ return !Success;
+ }
+/* Clear any pending input */
+ tcflush(local->fd, TCIFLUSH);
+
+/* DBG(2, ErrorF("Reading Firmware ID\n")); */
+/* if (!write_and_read(local->fd, ACECAD_PROMPT, buffer, 5, 1)) */
+/* return !Success; */
+
+/* DBG(2, ErrorF("%s\n", buffer)); */
+
+/* if (xf86Verbose) */
+/* ErrorF("%s AceCad firmware ID : %s\n", XCONFIG_PROBED, buffer); */
+
+ DBG(2, ErrorF("reading max coordinates\n"));
+ if (!write_and_read(local->fd, ACECAD_CONFIG, buffer, 5, 0))
+ return !Success;
+ priv->acecadMaxX = (int)buffer[1] + ((int)buffer[2] << 7);
+ priv->acecadMaxY = (int)buffer[3] + ((int)buffer[4] << 7);
+
+/* priv->acecadMaxX = 6000; */
+/* priv->acecadMaxY = 6000; */
+
+ if (xf86Verbose)
+ ErrorF("%s AceCad tablet size is %d.%1dinx%d.%1din, %dx%d "
+ "lines of resolution\n", XCONFIG_PROBED,
+ priv->acecadMaxX / 500, (priv->acecadMaxX / 50) % 10,
+ priv->acecadMaxY / 500, (priv->acecadMaxY / 50) % 10,
+ priv->acecadMaxX, priv->acecadMaxY);
+
+ if (priv->acecadInc > 95)
+ priv->acecadInc = 95;
+ if (priv->acecadInc < 1) {
+/* Make a guess as to the best increment value given video mode */
+ if (priv->acecadMaxX / screenInfo.screens[0]->width <
+ priv->acecadMaxY / screenInfo.screens[0]->height)
+ priv->acecadInc = priv->acecadMaxX / screenInfo.screens[0]->width;
+ else
+ priv->acecadInc = priv->acecadMaxY / screenInfo.screens[0]->height;
+ if (priv->acecadInc < 1)
+ priv->acecadInc = 1;
+ if (xf86Verbose)
+ ErrorF("%s Using increment value of %d\n", XCONFIG_PROBED,
+ priv->acecadInc);
+ }
+
+/* Sets up the tablet mode to increment, stream, and such */
+ sprintf(buffer, "%s%c%c%c", acecad_initstr, ACECAD_INCREMENT, 32 + priv->acecadInc,
+ (priv->flags & ABSOLUTE_FLAG)? ACECAD_ABSOLUTE: ACECAD_RELATIVE);
+
+ SYSCALL(err = write(local->fd, buffer, strlen(buffer)))
+ if (err == -1) {
+ Error("AceCad write");
+ return !Success;
+ }
+
+ if (err <= 0) {
+ SYSCALL(close(local->fd));
+ return !Success;
+ }
+
+ return Success;
+}
+
+/*
+** xf86AceCadOpenDevice
+** Opens and initializes the device driver stuff or sumpthin.
+*/
+static int
+xf86AceCadOpenDevice(DeviceIntPtr pAceCad)
+{
+ LocalDevicePtr local = (LocalDevicePtr)pAceCad->public.devicePrivate;
+ AceCadDevicePtr priv = (AceCadDevicePtr)XI_PRIVATE(pAceCad);
+
+ if (xf86AceCadOpen(local) != Success) {
+ if (local->fd >= 0) {
+ SYSCALL(close(local->fd));
+ }
+ local->fd = -1;
+ }
+
+/* Set the real values */
+ InitValuatorAxisStruct(pAceCad,
+ 0,
+ 0, /* min val */
+ priv->acecadMaxX, /* max val */
+ 500000, /* resolution */
+ 0, /* min_res */
+ 500000); /* max_res */
+ InitValuatorAxisStruct(pAceCad,
+ 1,
+ 0, /* min val */
+ priv->acecadMaxY, /* max val */
+ 500000, /* resolution */
+ 0, /* min_res */
+ 500000); /* max_res */
+ return (local->fd != -1);
+}
+
+/*
+** xf86AceCadProc
+** Handle requests to do stuff to the driver.
+*/
+static int
+xf86AceCadProc(DeviceIntPtr pAceCad, int what)
+{
+ CARD8 map[25];
+ int nbaxes;
+ int nbbuttons;
+ int loop;
+ LocalDevicePtr local = (LocalDevicePtr)pAceCad->public.devicePrivate;
+ AceCadDevicePtr priv = (AceCadDevicePtr)PRIVATE(pAceCad);
+
+ DBG(2, ErrorF("BEGIN xf86AceCadProc dev=0x%x priv=0x%x what=%d\n", pAceCad, priv, what));
+
+ switch (what) {
+ case DEVICE_INIT:
+ DBG(1, ErrorF("xf86AceCadProc pAceCad=0x%x what=INIT\n", pAceCad));
+
+ nbaxes = 2; /* X, Y */
+ nbbuttons = (priv->flags & STYLUS_FLAG)? 2: 4;
+
+ for(loop=1; loop<=nbbuttons; loop++) map[loop] = loop;
+
+ if (InitButtonClassDeviceStruct(pAceCad,
+ nbbuttons,
+ map) == FALSE) {
+ ErrorF("unable to allocate Button class device\n");
+ return !Success;
+ }
+
+ if (InitFocusClassDeviceStruct(pAceCad) == FALSE) {
+ ErrorF("unable to init Focus class device\n");
+ return !Success;
+ }
+
+ if (InitPtrFeedbackClassDeviceStruct(pAceCad,
+ xf86AceCadControlProc) == FALSE) {
+ ErrorF("unable to init ptr feedback\n");
+ return !Success;
+ }
+
+ if (InitProximityClassDeviceStruct(pAceCad) == FALSE) {
+ ErrorF("unable to init proximity class device\n");
+ return !Success;
+ }
+
+ if (InitValuatorClassDeviceStruct(pAceCad,
+ nbaxes,
+ xf86GetMotionEvents,
+ local->history_size,
+ (priv->flags & ABSOLUTE_FLAG)? Absolute: Relative)
+ == FALSE) {
+ ErrorF("unable to allocate Valuator class device\n");
+ return !Success;
+ }
+/* allocate the motion history buffer if needed */
+ xf86MotionHistoryAllocate(local);
+
+ AssignTypeAndName(pAceCad, local->atom, local->name);
+/* open the device to gather informations */
+ xf86AceCadOpenDevice(pAceCad);
+ break;
+
+ case DEVICE_ON:
+ DBG(1, ErrorF("xf86AceCadProc pAceCad=0x%x what=ON\n", pAceCad));
+
+ if ((local->fd < 0) && (!xf86AceCadOpenDevice(pAceCad))) {
+ return !Success;
+ }
+/* SYSCALL(write(local->fd, ACECAD_PROMPT, strlen(ACECAD_PROMPT))); */
+ AddEnabledDevice(local->fd);
+ pAceCad->public.on = TRUE;
+ break;
+
+ case DEVICE_OFF:
+ DBG(1, ErrorF("xf86AceCadProc pAceCad=0x%x what=%s\n", pAceCad,
+ (what == DEVICE_CLOSE) ? "CLOSE" : "OFF"));
+ if (local->fd >= 0)
+ RemoveEnabledDevice(local->fd);
+ pAceCad->public.on = FALSE;
+ break;
+
+ case DEVICE_CLOSE:
+ DBG(1, ErrorF("xf86AceCadProc pAceCad=0x%x what=%s\n", pAceCad,
+ (what == DEVICE_CLOSE) ? "CLOSE" : "OFF"));
+ SYSCALL(close(local->fd));
+ local->fd = -1;
+ break;
+
+ default:
+ ErrorF("unsupported mode=%d\n", what);
+ return !Success;
+ break;
+ }
+ DBG(2, ErrorF("END xf86AceCadProc Success what=%d dev=0x%x priv=0x%x\n",
+ what, pAceCad, priv));
+ return Success;
+}
+
+/*
+** xf86AceCadClose
+** It... Uh... Closes the physical device?
+*/
+static void
+xf86AceCadClose(LocalDevicePtr local)
+{
+ if (local->fd >= 0) {
+ SYSCALL(close(local->fd));
+ }
+ local->fd = -1;
+}
+
+/*
+** xf86AceCadChangeControl
+** When I figure out what it does, it will do it.
+*/
+static int
+xf86AceCadChangeControl(LocalDevicePtr local, pointer control)
+{
+ xDeviceResolutionCtl *res;
+
+ res = (xDeviceResolutionCtl *)control;
+
+ if ((res->control != DEVICE_RESOLUTION) ||
+ (res->num_valuators < 1))
+ return (BadMatch);
+
+ return(Success);
+}
+
+/*
+** xf86AceCadSwitchMode
+** Switches the mode. For now just absolute or relative, hopefully
+** more on the way.
+*/
+static int
+xf86AceCadSwitchMode(ClientPtr client, DeviceIntPtr dev, int mode)
+{
+ LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
+ AceCadDevicePtr priv = (AceCadDevicePtr)(local->private);
+ char newmode;
+
+ DBG(3, ErrorF("xf86AceCadSwitchMode dev=0x%x mode=%d\n", dev, mode));
+
+ switch(mode) {
+ case Absolute:
+ priv->flags |= ABSOLUTE_FLAG;
+ newmode = ACECAD_ABSOLUTE;
+ break;
+
+ case Relative:
+ priv->flags &= ~ABSOLUTE_FLAG;
+ newmode = ACECAD_RELATIVE;
+ break;
+
+ default:
+ DBG(1, ErrorF("xf86AceCadSwitchMode dev=0x%x invalid mode=%d\n",
+ dev, mode));
+ return BadMatch;
+ }
+ SYSCALL(write(local->fd, &newmode, 1));
+ return Success;
+}
+
+/*
+** xf86AceCadAllocate
+** Allocates the device structures for the AceCad.
+*/
+static LocalDevicePtr
+xf86AceCadAllocate()
+{
+ LocalDevicePtr local = xalloc(sizeof(LocalDeviceRec));
+ AceCadDevicePtr priv = xalloc(sizeof(AceCadDeviceRec));
+#if defined (sun) && !defined(i386)
+ char *dev_name = getenv("ACECAD_DEV");
+#endif
+
+ local->name = XI_NAME;
+ local->type_name = "AceCad Tablet";
+ local->flags = 0;
+#if !defined(sun) || defined(i386)
+ local->device_config = xf86AceCadConfig;
+#endif
+ local->device_control = xf86AceCadProc;
+ local->read_input = xf86AceCadReadInput;
+ local->control_proc = xf86AceCadChangeControl;
+ local->close_proc = xf86AceCadClose;
+ local->switch_mode = xf86AceCadSwitchMode;
+ local->fd = -1;
+ local->atom = 0;
+ local->dev = NULL;
+ local->private = priv;
+ local->private_flags = 0;
+ local->history_size = 0;
+
+#if defined(sun) && !defined(i386)
+ if (def_name) {
+ priv->acecadDevice = xalloc(strlen(dev_name) + 1);
+ strcpy(priv->acecadDevice, device_name);
+ ErrorF("xf86AceCadOpen port changed to '%s'\n", priv->acecadDevice);
+ } else {
+ priv->acecadDevice = "";
+ }
+#else
+ priv->acecadDevice = ""; /* device file name */
+#endif
+ priv->acecadInc = -1; /* re-transmit position on increment */
+ priv->acecadOldX = -1; /* previous X position */
+ priv->acecadOldY = -1; /* previous Y position */
+ priv->acecadOldProximity = 0; /* previous proximity */
+ priv->acecadOldButtons = 0; /* previous buttons state */
+ priv->acecadMaxX = -1; /* max X value */
+ priv->acecadMaxY = -1; /* max Y value */
+ priv->flags = 0; /* various flags */
+ priv->acecadIndex = 0; /* number of bytes read */
+
+ return local;
+}
+
+
+/*
+** AceCad device association
+** Device section name and allocation function.
+*/
+DeviceAssocRec acecad_assoc =
+{
+ ACECAD_SECTION_NAME, /* config_section_name */
+ xf86AceCadAllocate /* device_allocate */
+};
+
+#ifdef DYNAMIC_MODULE
+/*
+** init_module
+** Entry point for dynamic module.
+*/
+int
+#ifndef DLSYM_BUG
+init_module(unsigned long server_version)
+#else
+init_xf86AceCad(unsigned long server_version)
+#endif
+{
+ xf86AddDeviceAssoc(&acecad_assoc);
+
+ if (server_version != XF86_VERSION_CURRENT) {
+ ErrorF("Warning: AceCad module compiled for version%s\n",
+ XF86_VERSION);
+ return 0;
+ } else {
+ return 1;
+ }
+}
+#endif
+
+#ifdef XFree86LOADER
+/*
+ * Entry point for the loader code
+ */
+XF86ModuleVersionInfo xf86AceCadVersion = {
+ "xf86AceCad",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 0x00010000,
+ {0,0,0,0}
+};
+
+void
+xf86AceCadModuleInit(data, magic)
+ pointer *data;
+ INT32 *magic;
+{
+ static int cnt = 0;
+
+ switch (cnt) {
+ case 0:
+ *magic = MAGIC_VERSION;
+ *data = &xf86AceCadVersion;
+ cnt++;
+ break;
+
+ case 1:
+ *magic = MAGIC_ADD_XINPUT_DEVICE;
+ *data = &acecad_assoc;
+ cnt++;
+ break;
+
+ default:
+ *magic = MAGIC_DONE;
+ *data = NULL;
+ break;
+ }
+}
+#endif
+
diff --git a/xc/programs/Xserver/hw/xfree86/input/confdrv.sh b/xc/programs/Xserver/hw/xfree86/input/confdrv.sh
new file mode 100644
index 000000000..cd93512b9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/confdrv.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+# $XFree86: xc/programs/Xserver/hw/xfree86/input/confdrv.sh,v 1.5 1999/06/12 15:37:09 dawes Exp $
+#
+# This script generates drvConf.c
+#
+# usage: confdrv.sh driver1 driver2 ...
+#
+
+DRVCONF=./drvConf.c
+BUILTIN="xf86KEYBOARD"
+
+cat > $DRVCONF <<EOF
+/*
+ * This file is generated automatically -- DO NOT EDIT
+ */
+
+#include "xf86.h"
+#include "xf86Xinput.h"
+
+extern InputDriverRec
+EOF
+Args="$BUILTIN `echo $* | tr '[a-z]' '[A-Z]'`"
+set - $Args
+while [ $# -gt 1 ]; do
+ echo "#undef $1" >> $DRVCONF
+ echo " $1," >> $DRVCONF
+ shift
+done
+echo "#undef $1" >> $DRVCONF
+echo " $1;" >> $DRVCONF
+cat >> $DRVCONF <<EOF
+
+InputDriverPtr xf86InputDriverList[] =
+{
+EOF
+for i in $Args; do
+ echo " &$i," >> $DRVCONF
+done
+cat >> $DRVCONF <<EOF
+};
+
+int xf86NumInputDrivers = sizeof(xf86InputDriverList) / sizeof(xf86InputDriverList[0]);
+
+EOF
diff --git a/xc/programs/Xserver/hw/xfree86/input/dynapro/Imakefile b/xc/programs/Xserver/hw/xfree86/input/dynapro/Imakefile
new file mode 100644
index 000000000..537e4d716
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/dynapro/Imakefile
@@ -0,0 +1,26 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/dynapro/Imakefile,v 1.2 1999/08/14 10:49:59 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = xf86Dyna.c
+OBJS = xf86Dyna.o
+
+DRIVER = dynapro
+
+INCLUDES = -I. -I$(XF86COMSRC) -I../../loader -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget($(DRIVER),$(OBJS))
+
+InstallObjectModule($(DRIVER),$(MODULEDIR),input)
+
+DependTarget()
+
+InstallDriverSDKObjectModule($(DRIVER),$(DRIVERSDKMODULEDIR),input)
diff --git a/xc/programs/Xserver/hw/xfree86/input/dynapro/xf86Dyna.c b/xc/programs/Xserver/hw/xfree86/input/dynapro/xf86Dyna.c
new file mode 100644
index 000000000..818f56861
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/dynapro/xf86Dyna.c
@@ -0,0 +1,619 @@
+/*
+ * Copyright (c) 1999 Machine Vision Holdings Incorporated
+ * Author: David Woodhouse <David.Woodhouse@mvhi.com>
+ *
+ * Template driver used: Copyright (c) 1998 Metro Link Incorporated
+ *
+ * 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, cpy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/dynapro/xf86Dyna.c,v 1.2 1999/08/22 05:57:37 dawes Exp $ */
+
+#define _DYNAPRO_C_
+
+#include <misc.h>
+#include <xf86.h>
+#define NEED_XF86_TYPES
+#include <xf86_ansic.h>
+#include <xf86_OSproc.h>
+#include <xf86Xinput.h>
+#include <xisb.h>
+#include <exevents.h>
+
+#include "xf86Dyna.h"
+
+InputDriverRec DYNAPRO = {
+ 1,
+ "dynapro",
+ NULL,
+ DynaproPreInit,
+ /*DynaproUnInit*/NULL,
+ NULL,
+ 0
+};
+
+
+
+#ifdef XFree86LOADER
+
+static XF86ModuleVersionInfo VersionRec =
+{
+ "dynapro",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_XINPUT,
+ ABI_XINPUT_VERSION,
+ MOD_CLASS_XINPUT,
+ {0, 0, 0, 0} /* signature, to be patched into the file by
+ * a tool */
+};
+
+
+static const char *reqSymbols[] = {
+ "AddEnabledDevice",
+ "ErrorF",
+ "InitButtonClassDeviceStruct",
+ "InitProximityClassDeviceStruct",
+ "InitValuatorAxisStruct",
+ "InitValuatorClassDeviceStruct",
+ "InitPtrFeedbackClassDeviceStruct",
+ "RemoveEnabledDevice",
+ "Xcalloc",
+ "Xfree",
+ "XisbBlockDuration",
+ "XisbFree",
+ "XisbNew",
+ "XisbRead",
+ "XisbTrace",
+ "screenInfo",
+ "xf86AddInputDriver",
+ "xf86AllocateInput",
+ "xf86CloseSerial",
+ "xf86CollectInputOptions",
+ "xf86ErrorFVerb",
+ "xf86FindOptionValue",
+ "xf86GetMotionEvents",
+ "xf86GetVerbosity",
+ "xf86MotionHistoryAllocate",
+ "xf86NameCmp",
+ "xf86OpenSerial",
+ "xf86CloseSerial",
+ "xf86OptionListCreate",
+ "xf86OptionListMerge",
+ "xf86OptionListReport",
+ "xf86PostButtonEvent",
+ "xf86PostMotionEvent",
+ "xf86PostProximityEvent",
+ "xf86ProcessCommonOptions",
+ "xf86RemoveLocalDevice",
+ "xf86ScaleAxis",
+ "xf86SetIntOption",
+ "xf86SetStrOption",
+ "xf86XInputSetScreen",
+ "xf86XInputSetSendCoreEvents",
+ NULL
+};
+
+
+static pointer
+DynaproSetupProc( pointer module,
+ pointer options,
+ int *errmaj,
+ int *errmin )
+{
+ xf86LoaderReqSymLists(reqSymbols, NULL);
+ xf86AddInputDriver(&DYNAPRO, module, 0);
+ return (pointer) 1;
+}
+
+XF86ModuleData dynaproModuleData = { &VersionRec, DynaproSetupProc, NULL };
+
+
+#endif /* XFree86LOADER */
+
+
+/*
+ * Be sure to set vmin appropriately for your device's protocol. You want to
+ * read a full packet before returning
+ */
+static const char *default_options[] =
+{
+ /* "Device", "/dev/ttyS1",*/
+ "BaudRate", "2400",
+ "StopBits", "1",
+ "DataBits", "8",
+ "Parity", "None",
+ "Vmin", "3",
+ "Vtime", "1",
+ "FlowControl", "None",
+ NULL,
+};
+
+
+/*****************************************************************************
+ * Function Definitions
+ ****************************************************************************/
+
+
+
+static InputInfoPtr
+DynaproPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
+{
+ InputInfoPtr pInfo;
+ DynaproPrivatePtr priv = xcalloc (1, sizeof (DynaproPrivateRec));
+ char *s;
+
+ if (!(pInfo = xf86AllocateInput(drv, 0)))
+ return NULL;
+
+ if ((!drv) || (!priv))
+ goto SetupProc_fail;
+
+ priv->min_x = 1000;
+ priv->max_x = 0;
+ priv->min_y = 0;
+ priv->max_y = 1000;
+ priv->screen_num = 0;
+ priv->screen_width = -1;
+ priv->screen_height = -1;
+ priv->lex_mode = Dynapro_byte0;
+ priv->swap_xy = 0;
+ priv->button_down = FALSE;
+ priv->button_number = 1;
+ priv->proximity = FALSE;
+
+ pInfo->type_name = XI_TOUCHSCREEN;
+ pInfo->device_control = DeviceControl;
+ pInfo->read_input = ReadInput;
+ pInfo->control_proc = ControlProc;
+ pInfo->close_proc = CloseProc;
+ pInfo->switch_mode = SwitchMode;
+ pInfo->conversion_proc = ConvertProc;
+ pInfo->dev = NULL;
+ pInfo->private = priv;
+ pInfo->private_flags = 0;
+ pInfo->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
+ pInfo->conf_idev = dev;
+
+ xf86CollectInputOptions(pInfo, default_options, NULL);
+
+ xf86OptionListReport( pInfo->options );
+
+ pInfo->fd = xf86OpenSerial (pInfo->options);
+ if (pInfo->fd == -1)
+ {
+ ErrorF ("Dynapro driver unable to open device\n");
+ goto SetupProc_fail;
+ }
+ xf86CloseSerial(pInfo->fd);
+ /*
+ * Process the options for your device like this
+ */
+ priv->min_x = xf86SetIntOption( pInfo->options, "MinX", 1000 );
+ priv->max_x = xf86SetIntOption( pInfo->options, "MaxX", 0 );
+ priv->min_y = xf86SetIntOption( pInfo->options, "MinY", 0 );
+ priv->max_y = xf86SetIntOption( pInfo->options, "MaxY", 1000 );
+ priv->screen_num = xf86SetIntOption( pInfo->options, "ScreenNumber", 0 );
+ priv->button_number = xf86SetIntOption( pInfo->options, "ButtonNumber", 1 );
+ priv->swap_xy = xf86SetIntOption( pInfo->options, "SwapXY", 1 );
+ priv->buffer = NULL;
+ s = xf86FindOptionValue (pInfo->options, "ReportingMode");
+ if ((s) && (xf86NameCmp (s, "raw") == 0))
+ priv->reporting_mode = TS_Raw;
+ else
+ priv->reporting_mode = TS_Scaled;
+
+ priv->proximity = FALSE;
+ priv->button_down = FALSE;
+ priv->lex_mode = Dynapro_byte0;
+
+
+ if (QueryHardware (priv) != Success)
+ {
+ ErrorF ("Unable to query/initialize Dynapro hardware.\n");
+ goto SetupProc_fail;
+ }
+
+ /* this results in an xstrdup that must be freed later */
+ pInfo->name = xf86SetStrOption( pInfo->options, "DeviceName", "Dynapro");
+ xf86ProcessCommonOptions(pInfo, pInfo->options);
+
+ pInfo->flags |= XI86_CONFIGURED;
+ return (pInfo);
+
+ SetupProc_fail:
+ if ((pInfo) && (pInfo->fd))
+ xf86CloseSerial (pInfo->fd);
+ if ((pInfo) && (pInfo->name))
+ xfree (pInfo->name);
+ if (pInfo)
+ xfree (pInfo);
+
+ if ((priv) && (priv->buffer))
+ XisbFree (priv->buffer);
+ if (priv)
+ xfree (priv);
+ return (NULL);
+}
+
+static Bool
+DeviceControl (DeviceIntPtr dev, int mode)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ DynaproPrivatePtr priv = (DynaproPrivatePtr) (pInfo->private);
+ unsigned char map[] =
+ {0, 1};
+
+ switch (mode)
+ {
+ case DEVICE_INIT:
+ /*
+ * these have to be here instead of in the SetupProc, because when the
+ * SetupProc is run at server startup, screenInfo is not setup yet
+ */
+ priv->screen_width = screenInfo.screens[priv->screen_num]->width;
+ priv->screen_height = screenInfo.screens[priv->screen_num]->height;
+
+ /*
+ * Device reports button press for 1 button.
+ */
+ if (InitButtonClassDeviceStruct (dev, 1, map) == FALSE)
+ {
+ ErrorF ("Unable to allocate Dynapro ButtonClassDeviceStruct\n");
+ return !Success;
+ }
+
+ /*
+ * Device reports motions on 2 axes in absolute coordinates.
+ * Axes min and max values are reported in raw coordinates.
+ */
+ if (InitValuatorClassDeviceStruct (dev, 2, xf86GetMotionEvents,
+ pInfo->history_size, Absolute) == FALSE)
+ {
+ ErrorF ("Unable to allocate Dynapro ValuatorClassDeviceStruct\n");
+ return !Success;
+ }
+ else
+ {
+ InitValuatorAxisStruct (dev, 0, priv->min_x, priv->max_x,
+ 9500,
+ 0 /* min_res */ ,
+ 9500 /* max_res */ );
+ InitValuatorAxisStruct (dev, 1, priv->min_y, priv->max_y,
+ 10500,
+ 0 /* min_res */ ,
+ 10500 /* max_res */ );
+ }
+
+ if (InitProximityClassDeviceStruct (dev) == FALSE)
+ {
+ ErrorF ("unable to allocate Dynapro ProximityClassDeviceStruct\n");
+ return !Success;
+ }
+
+ if (InitPtrFeedbackClassDeviceStruct(dev, DynaproPtrCtrl) == FALSE)
+ {
+ ErrorF ("unable to allocate Dynapro PtrFeedbackClassDeviceStruct\n");
+ return !Success;
+ }
+
+ /*
+ * Allocate the motion events buffer.
+ */
+ xf86MotionHistoryAllocate (pInfo);
+ return (Success);
+
+ case DEVICE_ON:
+ pInfo->fd = xf86OpenSerial(pInfo->options);
+ if (pInfo->fd == -1)
+ {
+ xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
+ return (!Success);
+ }
+ else
+ {
+ priv->buffer = XisbNew(pInfo->fd, 64);
+ if (!priv->buffer)
+ {
+ xf86CloseSerial(pInfo->fd);
+ pInfo->fd = -1;
+ return (!Success);
+ }
+ }
+
+ xf86FlushInput(pInfo->fd);
+ AddEnabledDevice (pInfo->fd);
+ dev->public.on = TRUE;
+ return (Success);
+
+ case DEVICE_OFF:
+ case DEVICE_CLOSE:
+ if (pInfo->fd != -1)
+ {
+ RemoveEnabledDevice (pInfo->fd);
+ if (priv->buffer)
+ {
+ XisbFree(priv->buffer);
+ priv->buffer = NULL;
+ }
+ xf86CloseSerial(pInfo->fd);
+ }
+ dev->public.on = FALSE;
+ return (Success);
+ default:
+ return (BadValue);
+ }
+
+}
+
+
+/*
+ * The ReadInput function will have to be tailored to your device
+ */
+static void
+ReadInput (InputInfoPtr pInfo)
+{
+ DynaproPrivatePtr priv = (DynaproPrivatePtr) (pInfo->private);
+ int x,y;
+
+ /*
+ * set blocking to -1 on the first call because we know there is data to
+ * read. Xisb automatically clears it after one successful read so that
+ * succeeding reads are preceeded buy a select with a 0 timeout to prevent
+ * read from blocking indefinately.
+ */
+ XisbBlockDuration (priv->buffer, -1);
+ while (DynaproGetPacket (priv) == Success)
+ {
+ if (priv->swap_xy) {
+ y = priv->packet[1] | ((priv->packet[0] & 0x38) << 4);
+ x = priv->packet[2] | ((priv->packet[0] & 0x07) << 7);
+ } else {
+ x = priv->packet[1] | ((priv->packet[0] & 0x38) << 4);
+ y = priv->packet[2] | ((priv->packet[0] & 0x07) << 7);
+ }
+
+ if (priv->reporting_mode == TS_Scaled)
+ {
+ x = xf86ScaleAxis (x, 0, priv->screen_width, priv->min_x,
+ priv->max_x);
+ y = xf86ScaleAxis (y, 0, priv->screen_height, priv->min_y,
+ priv->max_y);
+ }
+
+ xf86XInputSetScreen (pInfo, priv->screen_num, x, y);
+
+ if ((priv->proximity == FALSE) && (priv->packet[0] & 0x40))
+ {
+ priv->proximity = TRUE;
+ xf86PostProximityEvent (pInfo->dev, 1, 0, 2, x, y);
+ }
+
+ /*
+ * Send events.
+ *
+ * We *must* generate a motion before a button change if pointer
+ * location has changed as DIX assumes this. This is why we always
+ * emit a motion, regardless of the kind of packet processed.
+ */
+
+ xf86PostMotionEvent (pInfo->dev, TRUE, 0, 2, x, y);
+
+ /*
+ * Emit a button press or release.
+ */
+ if ((priv->button_down == FALSE) && (priv->packet[0] & 0x40))
+
+ {
+ xf86PostButtonEvent (pInfo->dev, TRUE,
+ priv->button_number, 1, 0, 2, x, y);
+ priv->button_down = TRUE;
+ }
+ if ((priv->button_down == TRUE) && !(priv->packet[0] & 0x40))
+ {
+ xf86PostButtonEvent (pInfo->dev, TRUE,
+ priv->button_number, 0, 0, 2, x, y);
+ priv->button_down = FALSE;
+ }
+ /*
+ * the untouch should always come after the button release
+ */
+ if ((priv->proximity == TRUE) && !(priv->packet[0] & 0x40))
+ {
+ priv->proximity = FALSE;
+ xf86PostProximityEvent (pInfo->dev, 0, 0, 2, x, y);
+ }
+ }
+}
+
+/*
+ * The ControlProc function may need to be tailored for your device
+ */
+static int
+ControlProc (InputInfoPtr pInfo, xDeviceCtl * control)
+{
+ xDeviceTSCalibrationCtl *c = (xDeviceTSCalibrationCtl *) control;
+ DynaproPrivatePtr priv = (DynaproPrivatePtr) (pInfo->private);
+
+ priv->min_x = c->min_x;
+ priv->max_x = c->max_x;
+ priv->min_y = c->min_y;
+ priv->max_y = c->max_y;
+
+ return (Success);
+}
+
+/*
+ * the CloseProc should not need to be tailored to your device
+ */
+static void
+CloseProc (InputInfoPtr pInfo)
+{
+
+}
+
+/*
+ * The SwitchMode function may need to be tailored for your device
+ */
+static int
+SwitchMode (ClientPtr client, DeviceIntPtr dev, int mode)
+{
+ InputInfoPtr pInfo = dev->public.devicePrivate;
+ DynaproPrivatePtr priv = (DynaproPrivatePtr) (pInfo->private);
+
+
+ if ((mode == TS_Raw) || (mode == TS_Scaled))
+ {
+ priv->reporting_mode = mode;
+ return (Success);
+ }
+ else if ((mode == SendCoreEvents) || (mode == DontSendCoreEvents))
+ {
+ xf86XInputSetSendCoreEvents (pInfo, (mode == SendCoreEvents));
+ return (Success);
+ }
+ else
+ return (!Success);
+}
+
+/*
+ * The ConvertProc function may need to be tailored for your device.
+ * This function converts the device's valuator outputs to x and y coordinates
+ * to simulate mouse events.
+ */
+static Bool
+ConvertProc (InputInfoPtr pInfo,
+ int first,
+ int num,
+ int v0,
+ int v1,
+ int v2,
+ int v3,
+ int v4,
+ int v5,
+ int *x,
+ int *y)
+{
+ DynaproPrivatePtr priv = (DynaproPrivatePtr) (pInfo->private);
+
+ if (priv->reporting_mode == TS_Raw)
+ {
+ *x = xf86ScaleAxis (v0, 0, priv->screen_width, priv->min_x,
+ priv->max_x);
+ *y = xf86ScaleAxis (v1, 0, priv->screen_height, priv->min_y,
+ priv->max_y);
+ }
+ else
+ {
+ *x = v0;
+ *y = v1;
+ }
+ return (TRUE);
+}
+
+/*
+ * the QueryHardware fuction should be tailored to your device to
+ * verify the device is attached and functional and perform any
+ * needed initialization.
+ */
+static Bool
+QueryHardware (DynaproPrivatePtr priv)
+{
+ /* Maybe once we get the hardware to actually respond correctly to its
+ configuration 'packets' */
+
+ return (Success);
+}
+
+/*
+ * This function should be renamed for your device and tailored to handle
+ * your device's protocol.
+ */
+static Bool
+DynaproGetPacket (DynaproPrivatePtr priv)
+{
+ int count = 0;
+ int c;
+
+ while ((c = XisbRead (priv->buffer)) >= 0)
+ {
+ /*
+ * fail after 500 bytes so the server doesn't hang forever if a
+ * device sends bad data.
+ */
+ if (count++ > 500)
+ return (!Success);
+
+ switch (priv->lex_mode)
+ {
+ case Dynapro_byte0:
+ if (c & 0x80) {
+ priv->packet[0] = (unsigned char) c;
+ priv->lex_mode = Dynapro_byte1;
+ }
+ else
+ xf86ErrorFVerb (4, "Dynapro: Non-start byte received (0x%2.2X\n", c);
+ break;
+
+ case Dynapro_byte1:
+ if (!(c & 0x80)) {
+ priv->packet[1] = (unsigned char) c;
+ priv->lex_mode = Dynapro_byte2;
+ }
+ else {
+ xf86ErrorFVerb (4, "Dynapro: Start byte received in middle of packet (0x%2.2X)\n", c);
+ priv->lex_mode = Dynapro_byte1;
+ priv->packet[0] = (unsigned char) c;
+ }
+ break;
+
+ case Dynapro_byte2:
+ if (!(c & 0x80)) {
+ priv->packet[2] = (unsigned char) c;
+ priv->lex_mode = Dynapro_byte0;
+ return (Success);
+ }
+ else {
+ xf86ErrorFVerb (4, "Dynapro: Start byte received in middle of packet (0x%2.2X)\n", c);
+ priv->lex_mode = Dynapro_byte1;
+ priv->packet[0] = (unsigned char) c;
+ }
+ break;
+ }
+ }
+ return (!Success);
+}
+
+
+static void
+DynaproPtrCtrl(DeviceIntPtr device, PtrCtrl *ctrl)
+{
+ /* I have no clue what this does, except that registering it stops the
+ X server segfaulting in ProcGetPointerMapping()
+ Ho Hum.
+ */
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/input/dynapro/xf86Dyna.h b/xc/programs/Xserver/hw/xfree86/input/dynapro/xf86Dyna.h
new file mode 100644
index 000000000..294c650bf
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/dynapro/xf86Dyna.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 1999 Machine Vision Holdings Incorporated
+ * Author: David Woodhouse <David.Woodhouse@mvhi.com>
+ *
+ * Template driver used: Copyright (c) 1998 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/dynapro/xf86Dyna.h,v 1.2 1999/08/22 05:57:37 dawes Exp $ */
+
+#ifndef _DYNAPRO_H_
+#define _DYNAPRO_H_
+
+/******************************************************************************
+ * Definitions
+ * structs, typedefs, #defines, enums
+ *****************************************************************************/
+
+#define DYNAPRO_PACKET_SIZE 3
+
+typedef enum
+{
+ Dynapro_byte0, Dynapro_byte1, Dynapro_byte2
+}
+DynaproState;
+
+
+typedef struct _DynaproPrivateRec
+{
+ int min_x; /* Minimum x reported by calibration */
+ int max_x; /* Maximum x */
+ int min_y; /* Minimum y reported by calibration */
+ int max_y; /* Maximum y */
+ Bool button_down; /* is the "button" currently down */
+ int button_number; /* which button to report */
+ int reporting_mode; /* TS_Raw or TS_Scaled */
+
+ int screen_num; /* Screen associated with the device */
+ int screen_width; /* Width of the associated X screen */
+ int screen_height; /* Height of the screen */
+ int proximity;
+ int swap_xy;
+ XISBuffer *buffer;
+ unsigned char packet[DYNAPRO_PACKET_SIZE]; /* packet being/just read */
+ DynaproState lex_mode;
+}
+DynaproPrivateRec, *DynaproPrivatePtr;
+
+
+/******************************************************************************
+ * Declarations
+ *****************************************************************************/
+
+static Bool DeviceControl (DeviceIntPtr, int);
+static void ReadInput (InputInfoPtr);
+static int ControlProc (InputInfoPtr, xDeviceCtl *);
+static void CloseProc (InputInfoPtr);
+static int SwitchMode (ClientPtr, DeviceIntPtr, int);
+static Bool ConvertProc (InputInfoPtr, int, int, int, int, int, int, int, int, int *, int *);
+static Bool QueryHardware (DynaproPrivatePtr);
+static Bool DynaproGetPacket (DynaproPrivatePtr priv);
+
+static InputInfoPtr
+DynaproPreInit(InputDriverPtr drv, IDevPtr dev, int flags);
+
+static void
+DynaproPtrCtrl(DeviceIntPtr device, PtrCtrl *ctrl);
+
+
+#endif /* _DYNAPRO_H_ */
diff --git a/xc/programs/Xserver/hw/xfree86/input/elo2300/Imakefile b/xc/programs/Xserver/hw/xfree86/input/elo2300/Imakefile
new file mode 100644
index 000000000..d8e56b6ef
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/elo2300/Imakefile
@@ -0,0 +1,26 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/elo2300/Imakefile,v 1.4 1999/08/14 10:49:59 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = elo.c
+OBJS = elo.o
+
+DRIVER = elo2300
+
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86SRC)/loader -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget($(DRIVER),$(OBJS))
+
+InstallObjectModule($(DRIVER),$(MODULEDIR),input)
+
+DependTarget()
+
+InstallDriverSDKObjectModule($(DRIVER),$(DRIVERSDKMODULEDIR),input)
diff --git a/xc/programs/Xserver/hw/xfree86/input/elo2300/elo.c b/xc/programs/Xserver/hw/xfree86/input/elo2300/elo.c
new file mode 100644
index 000000000..b91bd8459
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/elo2300/elo.c
@@ -0,0 +1,907 @@
+/*
+ * Copyright (c) 1998 Metro Link Incorporated
+ *
+ * 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, cpy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/*
+ * Based, in part, on code with the following copyright notice:
+ *
+ * Copyright 1995 by Patrick Lecoanet, France. <lecoanet@cenaath.cena.dgac.fr>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Patrick Lecoanet not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Patrick Lecoanet makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * PATRICK LECOANET DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL PATRICK LECOANET BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/elo2300/elo.c,v 1.9 1999/06/05 15:55:24 dawes Exp $ */
+
+#define _elo_C_
+/*****************************************************************************
+ * Standard Headers
+ ****************************************************************************/
+
+#include <misc.h>
+#include <xf86.h>
+#define NEED_XF86_TYPES
+#include <xf86_ansic.h>
+#include <xf86_OSproc.h>
+#include <xf86Xinput.h>
+#include <xisb.h>
+#include <exevents.h> /* Needed for InitValuator/Proximity stuff */
+
+/*****************************************************************************
+ * Local Headers
+ ****************************************************************************/
+#include "elo.h"
+
+/*****************************************************************************
+ * Variables without includable headers
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Local Variables
+ ****************************************************************************/
+static XF86ModuleVersionInfo VersionRec =
+{
+ "elo2300",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_XINPUT,
+ ABI_XINPUT_VERSION,
+ MOD_CLASS_XINPUT,
+ {0, 0, 0, 0} /* signature, to be patched into the file by
+ * a tool */
+};
+
+static const char *default_options[] =
+{
+ "BaudRate", "9600",
+ "StopBits", "1",
+ "DataBits", "8",
+ "Parity", "None",
+ "Vmin", "10",
+ "Vtime", "1",
+ "FlowControl", "None"
+};
+
+XF86ModuleData elo2300ModuleData = { &VersionRec, SetupProc, TearDownProc };
+
+/*****************************************************************************
+ * Function Definitions
+ ****************************************************************************/
+
+static void
+TearDownProc( pointer p )
+{
+ LocalDevicePtr local = (LocalDevicePtr) p;
+ EloPrivatePtr priv = (EloPrivatePtr) local->private;
+
+ DeviceOff (local->dev);
+
+ xf86RemoveLocalDevice (local);
+
+ xf86CloseSerial (local->fd);
+ XisbFree (priv->buffer);
+ xfree (priv);
+ xfree (local->name);
+ xfree (local);
+}
+
+static pointer
+SetupProc( pointer module,
+ pointer options,
+ int *errmaj,
+ int *errmin )
+{
+ LocalDevicePtr local = xcalloc (1, sizeof (LocalDeviceRec));
+ EloPrivatePtr priv = xcalloc (1, sizeof (EloPrivateRec));
+ pointer defaults,
+ merged;
+ char *s;
+
+
+ if ((!local) || (!priv))
+ goto SetupProc_fail;
+
+ defaults = xf86OptionListCreate( default_options,
+ (sizeof (default_options) / sizeof (default_options[0])), 0);
+
+ merged = xf86OptionListMerge( defaults, options );
+
+ xf86OptionListReport( merged );
+
+ local->fd = xf86OpenSerial (merged);
+ if (local->fd == -1)
+ {
+ xf86ErrorF ("ELO 2300 driver unable to open device\n");
+ *errmaj = LDR_NOPORTOPEN;
+ *errmin = xf86GetErrno ();
+ goto SetupProc_fail;
+ }
+ xf86ErrorFVerb( 6, "tty port opened successfully\n" );
+
+ priv->min_x = xf86SetIntOption( merged, "MinX", 0 );
+ priv->max_x = xf86SetIntOption( merged, "MaxX", 1000 );
+ priv->min_y = xf86SetIntOption( merged, "MinY", 0 );
+ priv->max_y = xf86SetIntOption( merged, "MaxY", 1000 );
+ priv->untouch_delay = xf86SetIntOption( merged, "UntouchDelay", ELO_UNTOUCH_DELAY );
+ priv->report_delay = xf86SetIntOption( merged, "ReportDelay", ELO_REPORT_DELAY );
+ priv->screen_num = xf86SetIntOption( merged, "ScreenNumber", 0 );
+ priv->button_number = xf86SetIntOption( merged, "ButtonNumber", 1 );
+ priv->button_threshold = xf86SetIntOption( merged, "ButtonThreshold", 128 );
+
+ s = xf86FindOptionValue (merged, "ReportingMode");
+ if ((s) && (xf86NameCmp (s, "raw") == 0))
+ priv->reporting_mode = TS_Raw;
+ else
+ priv->reporting_mode = TS_Scaled;
+
+ priv->buffer = XisbNew (local->fd, 200);
+ priv->button_down = FALSE;
+
+ DBG (9, XisbTrace (priv->buffer, 1));
+
+ EloNewPacket (priv);
+ if (QueryHardware (priv, errmaj, errmin) != Success)
+ {
+ xf86ErrorF ("Unable to query/initialize Elographics 2300 hardware.\n");
+ goto SetupProc_fail;
+ }
+
+ /* this results in an xstrdup that must be freed later */
+ local->name = xf86SetStrOption( merged, "DeviceName", "ELOGraphics 2300 TouchScreen" );
+ local->type_name = XI_TOUCHSCREEN;
+ local->device_control = DeviceControl;
+ local->read_input = ReadInput;
+ local->control_proc = ControlProc;
+ local->close_proc = CloseProc;
+ local->switch_mode = SwitchMode;
+ local->conversion_proc = ConvertProc;
+ local->dev = NULL;
+ local->private = priv;
+ local->private_flags = 0;
+ local->history_size = xf86SetIntOption( merged, "HistorySize", 0 );
+
+ xf86AddLocalDevice (local, merged);
+
+ /* prepare to process touch packets */
+ EloNewPacket (priv);
+ return (local);
+
+ SetupProc_fail:
+ if ((local) && (local->fd))
+ xf86CloseSerial (local->fd);
+ if ((local) && (local->name))
+ xfree (local->name);
+ if (local)
+ xfree (local);
+
+ if ((priv) && (priv->buffer))
+ XisbFree (priv->buffer);
+ if (priv)
+ xfree (priv);
+ return (NULL);
+}
+
+static Bool
+DeviceControl( DeviceIntPtr dev,
+ int mode )
+{
+ Bool RetValue;
+
+ switch (mode)
+ {
+ case DEVICE_INIT:
+ DeviceInit (dev);
+ RetValue = Success;
+ break;
+ case DEVICE_ON:
+ RetValue = DeviceOn( dev );
+ break;
+ case DEVICE_OFF:
+ RetValue = DeviceOff( dev );
+ break;
+ case DEVICE_CLOSE:
+ RetValue = DeviceClose( dev );
+ break;
+ default:
+ RetValue = BadValue;
+ }
+
+ return( RetValue );
+}
+
+static Bool
+DeviceOn( DeviceIntPtr dev )
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+
+ AddEnabledDevice (local->fd);
+ dev->public.on = TRUE;
+ return (Success);
+}
+
+static Bool
+DeviceOff( DeviceIntPtr dev )
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+
+ RemoveEnabledDevice (local->fd);
+ dev->public.on = FALSE;
+ return (Success);
+}
+
+static Bool
+DeviceClose( DeviceIntPtr dev )
+{
+ return (Success);
+}
+
+static Bool
+DeviceInit( DeviceIntPtr dev )
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ EloPrivatePtr priv = (EloPrivatePtr) (local->private);
+ unsigned char map[] =
+ {0, 1};
+
+ /*
+ * these have to be here instead of in the SetupProc, because when the
+ * SetupProc is run and server startup, screenInfo is not setup yet
+ */
+ priv->screen_width = screenInfo.screens[priv->screen_num]->width;
+ priv->screen_height = screenInfo.screens[priv->screen_num]->height;
+
+ /*
+ * Device reports button press for up to 1 button.
+ */
+ if (InitButtonClassDeviceStruct (dev, 1, map) == FALSE)
+ {
+ ErrorF ("Unable to allocate Elographics touchscreen ButtonClassDeviceStruct\n");
+ return !Success;
+ }
+
+ /*
+ * Device reports motions on 2 axes in absolute coordinates.
+ * Device may reports touch pressure on the 3rd axis.
+ */
+ if (InitValuatorClassDeviceStruct (dev, priv->axes, xf86GetMotionEvents,
+ local->history_size, Absolute) == FALSE)
+ {
+ ErrorF ("Unable to allocate Elographics touchscreen ValuatorClassDeviceStruct\n");
+ return !Success;
+ }
+ else
+ {
+ InitValuatorAxisStruct (dev, 0, priv->min_x, priv->max_x,
+ 9500,
+ 0 /* min_res */ ,
+ 9500 /* max_res */ );
+ InitValuatorAxisStruct (dev, 1, priv->min_y, priv->max_y,
+ 10500,
+ 0 /* min_res */ ,
+ 10500 /* max_res */ );
+ /* 3rd axis is pressure */
+ if (priv->axes == 3)
+ {
+ InitValuatorAxisStruct (dev, 2, 0, 255,
+ 255,
+ 0 /* min_res */ ,
+ 255 /* max_res */ );
+ }
+ }
+
+ if (InitProximityClassDeviceStruct (dev) == FALSE)
+ {
+ ErrorF ("Unable to allocate Elographics touchscreen ProximityClassDeviceStruct\n");
+ return !Success;
+ }
+
+ /*
+ * Allocate the motion events buffer.
+ */
+ xf86MotionHistoryAllocate (local);
+ return (Success);
+}
+
+static void
+ReadInput( LocalDevicePtr local )
+{
+ int x, y, z;
+ int state;
+ EloPrivatePtr priv = (EloPrivatePtr) (local->private);
+
+ /*
+ * set blocking to -1 on the first call because we know there is data to
+ * read. Xisb automatically clears it after one successful read so that
+ * succeeding reads are preceeded buy a select with a 0 timeout to prevent
+ * read from blocking indefinately.
+ */
+ XisbBlockDuration (priv->buffer, -1);
+ while (EloGetPacket (priv) == Success)
+ {
+ if (priv->packet[1] == ELO_TOUCH)
+ {
+ x = WORD_ASSEMBLY (priv->packet[3], priv->packet[4]);
+ y = WORD_ASSEMBLY (priv->packet[5], priv->packet[6]);
+ z = WORD_ASSEMBLY (priv->packet[7], priv->packet[8]);
+ state = priv->packet[2] & 0x07;
+
+ if (priv->reporting_mode == TS_Scaled)
+ {
+ x = xf86ScaleAxis (x, 0, priv->screen_width, priv->min_x,
+ priv->max_x);
+ y = xf86ScaleAxis (y, 0, priv->screen_height, priv->min_y,
+ priv->max_y);
+ }
+ xf86XInputSetScreen (local, priv->screen_num, x, y);
+ if (state == ELO_PRESS)
+ {
+ if (priv->axes == 3)
+ xf86PostProximityEvent (local->dev, 1, 0, 3, x, y, z);
+ else
+ xf86PostProximityEvent (local->dev, 1, 0, 2, x, y);
+ }
+
+ /*
+ * Send events.
+ *
+ * We *must* generate a motion before a button change if pointer
+ * location has changed as DIX assumes this. This is why we always
+ * emit a motion, regardless of the kind of packet processed.
+ */
+ if (priv->axes == 3)
+ xf86PostMotionEvent (local->dev, TRUE, 0, 3, x, y, z);
+ else
+ xf86PostMotionEvent (local->dev, TRUE, 0, 2, x, y);
+
+ /*
+ * Emit a button press or release.
+ */
+ if ((z > priv->button_threshold) && (!priv->button_down))
+ {
+ if (priv->axes == 3)
+ {
+ xf86PostButtonEvent (local->dev, TRUE,
+ priv->button_number, 1, 0, 3, x, y, z);
+ }
+ else
+ {
+ xf86PostButtonEvent (local->dev, TRUE,
+ priv->button_number, 1, 0, 2, x, y);
+ }
+ priv->button_down = TRUE;
+ }
+ /*
+ * if button_threshold is 0, there may never be a STREAMING
+ * event with a z <= 0 before there is an untouch (RELEASE)
+ * event
+ */
+ if (((z <= priv->button_threshold) || (state == ELO_RELEASE))
+ && (priv->button_down))
+ {
+ if (priv->axes == 3)
+ {
+ xf86PostButtonEvent (local->dev, TRUE,
+ priv->button_number, 0, 0, 3, x, y, z);
+ }
+ else
+ {
+ xf86PostButtonEvent (local->dev, TRUE,
+ priv->button_number, 0, 0, 2, x, y);
+ }
+ priv->button_down = FALSE;
+ }
+ /*
+ * the untouch should always come after the button release
+ */
+ if (state == ELO_RELEASE)
+ {
+ if (priv->axes == 3)
+ xf86PostProximityEvent (local->dev, 0, 0, 3, x, y, z);
+ else
+ xf86PostProximityEvent (local->dev, 0, 0, 2, x, y);
+ }
+
+ xf86ErrorFVerb (3, "TouchScreen: x(%d), y(%d), %s\n",
+ x, y,
+ (state == ELO_PRESS) ? "Press" :
+ ((state == ELO_RELEASE) ? "Release" : "Stream"));
+ }
+ }
+}
+
+static int
+ControlProc( LocalDevicePtr local,
+ xDeviceCtl * control )
+{
+ xDeviceTSCalibrationCtl *c = (xDeviceTSCalibrationCtl *) control;
+ EloPrivatePtr priv = (EloPrivatePtr) (local->private);
+
+ priv->min_x = c->min_x;
+ priv->max_x = c->max_x;
+ priv->min_y = c->min_y;
+ priv->max_y = c->max_y;
+ /*
+ * if we have real Z values, set the threshold, otherwise stick with
+ * the built-in default.
+ */
+ if (priv->axes == 3)
+ priv->button_threshold = c->button_threshold;
+ return (Success);
+}
+
+static void
+CloseProc( LocalDevicePtr local )
+{
+}
+
+static int
+SwitchMode( ClientPtr client,
+ DeviceIntPtr dev,
+ int mode )
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ EloPrivatePtr priv = (EloPrivatePtr) (local->private);
+ if ((mode == TS_Raw) || (mode == TS_Scaled))
+ {
+ priv->reporting_mode = mode;
+ return (Success);
+ }
+ else if ((mode == SendCoreEvents) || (mode == DontSendCoreEvents))
+ {
+ xf86XInputSetSendCoreEvents (local, (mode == SendCoreEvents));
+ return (Success);
+ }
+ else
+ return (!Success);
+}
+
+static Bool
+ConvertProc( LocalDevicePtr local,
+ int first,
+ int num,
+ int v0,
+ int v1,
+ int v2,
+ int v3,
+ int v4,
+ int v5,
+ int *x,
+ int *y )
+{
+ EloPrivatePtr priv = (EloPrivatePtr) (local->private);
+
+ if (priv->reporting_mode == TS_Raw)
+ {
+ *x = xf86ScaleAxis (v0, 0, priv->screen_width, priv->min_x,
+ priv->max_x);
+ *y = xf86ScaleAxis (v1, 0, priv->screen_height, priv->min_y,
+ priv->max_y);
+ }
+ else
+ {
+ *x = v0;
+ *y = v1;
+ }
+ return (TRUE);
+}
+
+static Bool
+QueryHardware( EloPrivatePtr priv,
+ int *errmaj,
+ int *errmin )
+{
+ unsigned char req[ELO_PACKET_SIZE];
+
+ memset (req, 0, ELO_PACKET_SIZE);
+ req[1] = tolower (ELO_ID);
+ if (EloSendQuery (req, priv) == Success)
+ {
+ /*
+ * indicates hardware reports actual z (pressure) values
+ */
+ if (priv->packet[4] & 0x80)
+ priv->axes = 3;
+ else
+ priv->axes = 2;
+
+ EloPrintIdent( priv->packet );
+ if (EloWaitAck (priv) != Success)
+ {
+ *errmaj = LDR_NOHARDWARE;
+ return (!Success);
+ }
+ }
+ else
+ {
+ *errmaj = LDR_NOHARDWARE;
+ return (!Success);
+ }
+ /*
+ * Set the operating mode: Stream, no scaling, no calibration,
+ * no range checking, no trim, tracking enabled.
+ */
+ memset (req, 0, ELO_PACKET_SIZE);
+ req[1] = ELO_MODE;
+ req[3] = ELO_TOUCH_MODE | ELO_STREAM_MODE | ELO_UNTOUCH_MODE |
+ ELO_ENABLE_Z_MODE;
+ req[4] = ELO_TRACKING_MODE;
+ if (EloSendControl (req, priv) != Success)
+ {
+ ErrorF ("Unable to change Elographics touchscreen modes\n");
+ *errmaj = LDR_NOHARDWARE;
+ return (!Success);
+ }
+
+ /*
+ * Set the touch reports timings from configuration data.
+ */
+ memset (req, 0, ELO_PACKET_SIZE);
+ req[1] = ELO_REPORT;
+ req[2] = priv->untouch_delay;
+ req[3] = priv->report_delay;
+ if (EloSendControl (req, priv) != Success)
+ {
+ ErrorF ("Unable to change Elographics touchscreen reports timings\n");
+ *errmaj = LDR_NOHARDWARE;
+ return (!Success);
+
+ }
+ return (Success);
+}
+
+/*
+ ***************************************************************************
+ *
+ * EloSendControl --
+ * Emit a control command to the controller and wait for acknowledge.
+ *
+ * Returns Success if acknowledge received and reported no error.
+ *
+ ***************************************************************************
+ */
+static Bool
+EloSendControl( unsigned char *control,
+ EloPrivatePtr priv )
+{
+ if (EloSendPacket (control, priv->buffer) == Success)
+ {
+ return EloWaitAck (priv);
+ }
+ else
+ return !Success;
+}
+
+/*
+ ***************************************************************************
+ *
+ * EloSendQuery --
+ * Emit a query to the controller and blocks until the reply and
+ * the acknowledge are read.
+ *
+ * The reply is left in reply. The function returns Success if the
+ * reply is valid and !Success otherwise.
+ *
+ ***************************************************************************
+ */
+static Bool
+EloSendQuery( unsigned char *request,
+ EloPrivatePtr priv )
+{
+ Bool ok;
+
+ if (EloSendPacket (request, priv->buffer) == Success)
+ {
+ ok = EloWaitReply (toupper (request[1]), priv);
+ return ok;
+ }
+ else
+ return !Success;
+}
+
+/*
+ ***************************************************************************
+ *
+ * EloSendPacket --
+ * Emit an height bytes packet to the controller.
+ * The function expects a valid buffer containing the
+ * command to be sent to the controller. It fills it with the
+ * leading sync character an the trailing checksum byte.
+ *
+ ***************************************************************************
+ */
+static Bool
+EloSendPacket( unsigned char *packet,
+ XISBuffer * b )
+{
+ int i, result;
+ int sum = ELO_INIT_CHECKSUM;
+
+ packet[0] = ELO_SYNC_BYTE;
+ for (i = 0; i < ELO_PACKET_SIZE - 1; i++)
+ {
+ sum += packet[i];
+ sum &= 0xFF;
+ }
+ packet[ELO_PACKET_SIZE - 1] = sum;
+
+ result = XisbWrite (b, packet, ELO_PACKET_SIZE);
+ if (result != ELO_PACKET_SIZE)
+ {
+ ErrorF ("System error while sending to Elographics touchscreen.\n");
+ return !Success;
+ }
+ else
+ return Success;
+}
+
+/*
+ ***************************************************************************
+ *
+ * EloWaitReply --
+ * It is assumed that the reply will be in the few next bytes
+ * read and will be available very soon after the query post. if
+ * these two asumptions are not met, there are chances that the server
+ * will be stuck for a while.
+ * The reply type need to match parameter 'type'.
+ * The reply is left in reply. The function returns Success if the
+ * reply is valid and !Success otherwise.
+ *
+ ***************************************************************************
+ */
+
+static Bool
+EloWaitReply( unsigned char type,
+ EloPrivatePtr priv )
+{
+ Bool ok;
+ int wrong, empty;
+
+ xf86ErrorFVerb( 4, "Waiting for a '%c' reply\n", type );
+ wrong = ELO_MAX_WRONG_PACKETS;
+ empty = ELO_MAX_EMPTY_PACKETS;
+ do
+ {
+ ok = !Success;
+
+ /*
+ * Wait half a second for the reply. The fuse counts down each
+ * timeout and each wrong packet.
+ */
+ xf86ErrorFVerb( 4, "Waiting %d ms for data from port\n",
+ ELO_MAX_WAIT / 1000 );
+ EloNewPacket (priv);
+ XisbBlockDuration (priv->buffer, ELO_MAX_WAIT);
+ ok = EloGetPacket (priv);
+ if (ok != Success)
+ empty--;
+ if ((ok == Success) && (priv->packet[1] != type))
+ {
+ xf86ErrorFVerb( 2, "Wrong reply received\n" );
+ ok = !Success;
+ wrong--;
+ }
+ }
+ while (ok != Success && wrong && empty);
+
+ return ok;
+}
+/*
+ * prepare to read a new packet regardless of the state of the packet in
+ * progress
+ */
+static void
+EloNewPacket( EloPrivatePtr priv )
+{
+ priv->packeti = 0;
+ priv->lex_mode = elo_normal;
+ priv->checksum = 0;
+}
+
+/*
+ ***************************************************************************
+ *
+ * EloGetPacket --
+ * Read a packet from the port. Try to synchronize with start of
+ * packet and compute checksum.
+ * The packet structure read by this function is as follow:
+ * Byte 0 : ELO_SYNC_BYTE
+ * Byte 1
+ * ...
+ * Byte 8 : packet data
+ * Byte 9 : checksum of bytes 0 to 8
+ *
+ * This function returns if a valid packet has been assembled in
+ * buffer or if no more data is available.
+ *
+ * Returns Success if a packet is successfully assembled including
+ * testing checksum. If a packet checksum is incorrect, it is discarded.
+ * Bytes preceding the ELO_SYNC_BYTE are also discarded.
+ * Returns !Success if out of data while reading. The start of the
+ * partially assembled packet is left in packet, buffer_p and
+ * checksum reflect the current state of assembly.
+ *
+ ***************************************************************************
+ */
+static Bool
+EloGetPacket( EloPrivatePtr priv )
+{
+ int count = 0;
+ int c;
+
+ while ((c = XisbRead (priv->buffer)) >= 0)
+ {
+ if (priv->lex_mode != elo_checksum)
+ priv->checksum += c;
+ if (count++ > 50)
+ {
+ EloNewPacket (priv);
+ return (!Success);
+ }
+
+ switch (priv->lex_mode)
+ {
+ case elo_normal:
+ if (c == ELO_SYNC_BYTE)
+ {
+ priv->packet[priv->packeti++] = (unsigned char) c;
+ priv->checksum = ELO_INIT_CHECKSUM + c;
+ priv->lex_mode = elo_body;
+ }
+ break;
+
+ case elo_body:
+ if (priv->packeti < 9)
+ priv->packet[priv->packeti++] = (unsigned char) c;
+ if (priv->packeti == 9)
+ priv->lex_mode = elo_checksum;
+ break;
+
+ case elo_checksum:
+
+ if (c != priv->checksum)
+ {
+ xf86ErrorFVerb( 4, "Checksum mismatch. Read %d calculated %d\nPacket discarded.\n",
+ c, priv->checksum );
+ EloNewPacket (priv);
+ }
+ else
+ {
+ EloNewPacket (priv);
+ xf86ErrorFVerb( 5, "got a good packet from ELO touchscreen\n" );
+ return (Success);
+ }
+ break;
+ }
+ }
+ return (!Success);
+}
+
+/*
+ ***************************************************************************
+ *
+ * EloWaitAck --
+ * Wait for an acknowledge from the controller. Returns Success if
+ * acknowledge received and reported no errors.
+ *
+ ***************************************************************************
+ */
+static Bool
+EloWaitAck( EloPrivatePtr priv )
+{
+ int i, nb_errors;
+
+ if (EloWaitReply (ELO_ACK, priv) == Success)
+ {
+ for (i = 0, nb_errors = 0; i < 4; i++)
+ if (priv->packet[2 + i] != '0')
+ nb_errors++;
+ if (nb_errors != 0)
+ {
+ xf86ErrorFVerb( 2, "Elographics acknowledge packet reports %d errors\n",
+ nb_errors );
+ }
+ return Success;
+ /* return (nb_errors < 4) ? Success : !Success; */
+ }
+ else
+ return !Success;
+}
+
+/*
+ ***************************************************************************
+ *
+ * EloPrintIdent --
+ * Print type of touchscreen and features on controller board.
+ *
+ ***************************************************************************
+ */
+static void
+EloPrintIdent( unsigned char *packet )
+{
+ xf86Msg( X_PROBED, " Elographics touchscreen is a " );
+ switch (packet[2])
+ {
+ case '0':
+ xf86ErrorF( "AccuTouch" );
+ break;
+ case '1':
+ xf86ErrorF( "DuraTouch" );
+ break;
+ case '2':
+ xf86ErrorF( "Intellitouch" );
+ break;
+ }
+ xf86ErrorF( ", connected through a " );
+ switch (packet[3])
+ {
+ case '0':
+ xf86ErrorF( "serial link.\n" );
+ break;
+ case '1':
+ xf86ErrorF( "ISA-Bus card.\n" );
+ break;
+ case '2':
+ xf86ErrorF( "Micro Channel card.\n");
+ break;
+ }
+ xf86Msg( X_PROBED, " The controller is a model " );
+ if (packet[8] & 1)
+ xf86ErrorF( "E271-2210" );
+ else
+ xf86ErrorF( "E271-2200" );
+ xf86ErrorF( ", firmware revision %d.%d.\n", packet[6], packet[5] );
+
+ if( packet[4] )
+ {
+ xf86Msg( X_PROBED, " Additional features:\n" );
+ if (packet[4] & 0x10)
+ xf86Msg( X_PROBED, " External A/D converter\n" );
+ if (packet[4] & 0x20)
+ xf86Msg( X_PROBED, " 32K RAM\n" );
+ if (packet[4] & 0x40)
+ xf86Msg( X_PROBED, " RAM onboard\n" );
+ if (packet[4] & 0x80)
+ xf86Msg( X_PROBED, " Z axis active\n" );
+ xf86ErrorF( "\n" );
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/input/elo2300/elo.h b/xc/programs/Xserver/hw/xfree86/input/elo2300/elo.h
new file mode 100644
index 000000000..dcdd6ffe9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/elo2300/elo.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 1998 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/elo2300/elo.h,v 1.2 1999/02/01 12:12:59 dawes Exp $ */
+
+#ifndef _elo_H_
+#define _elo_H_
+
+/******************************************************************************
+ * Definitions
+ * structs, typedefs, #defines, enums
+ *****************************************************************************/
+#define ELO_PACKET_SIZE 10
+
+ /* Note: some of them are not supported by the E281-2310 *//* JPM */
+
+#define ELO_SYNC_BYTE 'U' /* Sync byte. First of a packet. */
+#define ELO_TOUCH 'T' /* Report of touchs and motions. */
+#define ELO_OWNER 'O' /* Report vendor name. */
+#define ELO_ID 'I' /* Report of type and features. */
+#define ELO_MODE 'M' /* Set current operating mode. */
+#define ELO_PARAMETER 'P' /* Set the serial parameters. */
+#define ELO_REPORT 'B' /* Set touch reports timings. */
+#define ELO_CALIBRATION 'C' /* Calibration command. */
+#define ELO_ACK 'A' /* Acknowledge packet */
+#define ELO_SERIAL_IO '0' /* Indicator byte for PARAMETER command */
+
+#define ELO_INIT_CHECKSUM 0xAA /* Initial value of checksum. */
+
+#define ELO_PRESS 0x01 /* Flags in ELO_TOUCH status byte */
+#define ELO_STREAM 0x02
+#define ELO_RELEASE 0x04
+
+#define ELO_TOUCH_MODE 0x01 /* Flags in ELO_MODE command */
+#define ELO_STREAM_MODE 0x02
+#define ELO_UNTOUCH_MODE 0x04
+#define ELO_RANGE_CHECK_MODE 0x40
+#define ELO_ENABLE_Z_MODE 0x80
+#define ELO_TRIM_MODE 0x02
+#define ELO_CALIB_MODE 0x04
+#define ELO_SCALING_MODE 0x08
+#define ELO_TRACKING_MODE 0x40
+
+#define ELO_SERIAL_SPEED 0x06 /* Flags for high speed serial
+ * (19200) */
+#define ELO_SERIAL_MASK 0xF8
+
+#define ELO_MAX_WRONG_PACKETS 200 /* Number of wrong packets to accept
+ * before giving up when looking for
+ * a specific packet type */
+#define ELO_MAX_EMPTY_PACKETS 3 /* Number of empty reads to accept before
+ * giving up when looking for a reply */
+#define ELO_MAX_WAIT 100000 /* Max wait time for a reply (microsec) */
+
+#define ELO_UNTOUCH_DELAY 10 /* 100 ms */
+#define ELO_REPORT_DELAY 4 /* 40 ms or 25 motion reports/s */
+
+typedef enum
+{
+ elo_normal, elo_body, elo_checksum
+}
+ELOState;
+
+#define WORD_ASSEMBLY(byte1, byte2) (((byte2) << 8) | (byte1))
+
+typedef struct _EloPrivateRec
+{
+ int min_x; /* Minimum x reported by calibration */
+ int max_x; /* Maximum x */
+ int min_y; /* Minimum y reported by calibration */
+ int max_y; /* Maximum y */
+ int button_threshold; /* Z > button threshold = button click */
+ int axes;
+ Bool button_down; /* is the "button" currently down */
+ int button_number; /* which button to report */
+ int reporting_mode; /* TS_Raw or TS_Scaled */
+
+ int untouch_delay; /* Delay before reporting an untouch (in ms) */
+ int report_delay; /* Delay between touch report packets */
+
+ int screen_num; /* Screen associated with the device */
+ int screen_width; /* Width of the associated X screen */
+ int screen_height; /* Height of the screen */
+ XISBuffer *buffer;
+ unsigned char packet[ELO_PACKET_SIZE]; /* packet being/just read */
+ int packeti; /* index into packet */
+ unsigned char checksum; /* Current checksum of data in assembly *
+ * buffer */
+ ELOState lex_mode;
+}
+EloPrivateRec, *EloPrivatePtr;
+
+/******************************************************************************
+ * Declarations
+ * variables: use elo_LOC in front
+ * of globals.
+ * put locals in the .c file.
+ *****************************************************************************/
+static MODULESETUPPROTO( SetupProc );
+static void TearDownProc (pointer p);
+static Bool DeviceControl (DeviceIntPtr dev, int mode);
+static Bool DeviceOn (DeviceIntPtr dev);
+static Bool DeviceOff (DeviceIntPtr dev);
+static Bool DeviceClose (DeviceIntPtr dev);
+static Bool DeviceInit (DeviceIntPtr dev);
+static void ReadInput (LocalDevicePtr local);
+static int ControlProc (LocalDevicePtr local, xDeviceCtl * control);
+static void CloseProc (LocalDevicePtr local);
+static int SwitchMode (ClientPtr client, DeviceIntPtr dev, int mode);
+static Bool ConvertProc (LocalDevicePtr local, int first, int num, int v0, int v1, int v2, int v3, int v4, int v5, int *x, int *y);
+static Bool QueryHardware (EloPrivatePtr priv, int *errmaj, int *errmin);
+static Bool EloSendControl (unsigned char *control, EloPrivatePtr priv);
+static Bool EloSendQuery (unsigned char *request, EloPrivatePtr priv);
+static Bool EloSendPacket (unsigned char *packet, XISBuffer * b);
+static Bool EloWaitReply (unsigned char type, EloPrivatePtr priv);
+static void EloNewPacket (EloPrivatePtr priv);
+static Bool EloGetPacket (EloPrivatePtr priv);
+static Bool EloWaitAck (EloPrivatePtr priv);
+static void EloPrintIdent (unsigned char *packet);
+
+/*
+ * DO NOT PUT ANYTHING AFTER THIS ENDIF
+ */
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/input/elographics/Imakefile b/xc/programs/Xserver/hw/xfree86/input/elographics/Imakefile
new file mode 100644
index 000000000..514197c3e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/elographics/Imakefile
@@ -0,0 +1,26 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/elographics/Imakefile,v 1.2 1999/08/14 10:50:00 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = xf86Elo.c
+OBJS = xf86Elo.o
+
+DRIVER = elographics
+
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86SRC)/loader -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget($(DRIVER),$(OBJS))
+
+InstallObjectModule($(DRIVER),$(MODULEDIR),input)
+
+DependTarget()
+
+InstallDriverSDKObjectModule($(DRIVER),$(DRIVERSDKMODULEDIR),input)
diff --git a/xc/programs/Xserver/hw/xfree86/input/elographics/xf86Elo.c b/xc/programs/Xserver/hw/xfree86/input/elographics/xf86Elo.c
new file mode 100644
index 000000000..aea4d3d2c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/elographics/xf86Elo.c
@@ -0,0 +1,1613 @@
+/* $XConsortium: xf86Elo.c /main/13 1996/10/25 14:11:31 kaleb $ */
+/*
+ * Copyright 1995, 1999 by Patrick Lecoanet, France. <lecoanet@cena.dgac.fr>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Patrick Lecoanet not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Patrick Lecoanet makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * PATRICK LECOANET DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL PATRICK LECOANET BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/elographics/xf86Elo.c,v 1.4 1999/06/13 05:18:54 dawes Exp $ */
+
+/*
+ *******************************************************************************
+ *******************************************************************************
+ *
+ * This driver is able to deal with Elographics SmartSet serial controllers.
+ * It uses only a subset of the functions provided through the protocol.
+ *
+ * SUPPORT FOR E281-2310 and compatible controllers added with help of:
+ * 1996/01/17 Juergen P. Meier (jpm@mailserv.rz.fh-muenchen.de) and
+ * 1998/03/25 G.Felkel@edelmann.de
+ *
+ * The E281-2310 is a somewhat lobotomized 2210.
+ * It does not support the c,g,h,k,l,p,q,s and t commands.
+ * Especially the P command, which is used to check the baud rate.
+ * The E281-2310 however semms to use always 9600bps, 8bit, 1stop
+ * no parity, Hardwarehandshake (RTS-CTS) (which are the drivers
+ * default values)
+ *
+ *******************************************************************************
+ *******************************************************************************
+ */
+
+#include <xf86Version.h>
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(3,9,0,0,0)
+#define XFREE86_V4
+#endif
+
+#ifdef XFREE86_V4
+#include <misc.h>
+#include <xf86.h>
+#include <xf86_ansic.h>
+#include <xf86_OSproc.h>
+#include <xf86Xinput.h>
+#include <exevents.h>
+
+#else /* XFREE86_V4 */
+
+#include "Xos.h"
+#include <signal.h>
+#include <stdio.h>
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "XI.h"
+#include "XIproto.h"
+
+#if defined(sun) && !defined(i386)
+#include <errno.h>
+#include <termio.h>
+#include <fcntl.h>
+#include <ctype.h>
+
+#include "extio.h"
+#else /* defined(sun) && !defined(i386) */
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Procs.h"
+#include "xf86_OSlib.h"
+#include "xf86_Config.h"
+#include "xf86Xinput.h"
+#include "xf86Version.h"
+#endif /* defined(sun) && !defined(i386) */
+
+#if !defined(sun) || defined(i386)
+#include "os.h"
+#include "osdep.h"
+#include "exevents.h"
+
+#include "extnsionst.h"
+#include "extinit.h"
+#endif /* !defined(sun) || defined(i386) */
+
+#endif /* XFREE86_V4 */
+
+
+#ifndef XFREE86_V4
+#if !defined(sun) || defined(i386)
+/*
+ ***************************************************************************
+ *
+ * Configuration descriptor.
+ *
+ ***************************************************************************
+ */
+
+#define PORT 1
+#define ELO_DEVICE_NAME 2
+#define SCREEN_NO 3
+#define UNTOUCH_DELAY 4
+#define REPORT_DELAY 5
+#define MAXX 6
+#define MAXY 7
+#define MINX 8
+#define MINY 9
+#define DEBUG_LEVEL 10
+#define HISTORY_SIZE 11
+#define LINK_SPEED 12
+#define ALWAYS_CORE 13
+
+static SymTabRec EloTab[] = {
+ { ENDSUBSECTION, "endsubsection" },
+ { PORT, "port" },
+ { ELO_DEVICE_NAME, "devicename" },
+ { SCREEN_NO, "screenno" },
+ { UNTOUCH_DELAY, "untouchdelay" },
+ { REPORT_DELAY, "reportdelay"},
+ { MAXX, "maximumxposition" },
+ { MAXY, "maximumyposition" },
+ { MINX, "minimumxposition" },
+ { MINY, "minimumyposition" },
+ { DEBUG_LEVEL, "debuglevel" },
+ { HISTORY_SIZE, "historysize" },
+ { LINK_SPEED, "linkspeed" },
+ { ALWAYS_CORE, "alwayscore" },
+ { -1, "" },
+};
+
+#define LS300 1
+#define LS1200 2
+#define LS2400 3
+#define LS9600 4
+#define LS19200 5
+
+static SymTabRec LinkSpeedTab[] = {
+ { LS300, "b300" },
+ { LS1200, "b1200" },
+ { LS2400, "b2400" },
+ { LS9600, "b9600" },
+ { LS19200, "b19200" }
+};
+#endif /* !defined(sun) || defined(i386) */
+
+/*
+ * This struct connects a line speed with
+ * a compatible motion packet delay. The
+ * driver will attempt to enforce a correct
+ * delay (according to this table) in order to
+ * avoid losing data in the touchscreen controller.
+ * LinkSpeedValues should be kept in sync with
+ * LinkSpeedTab.
+ */
+typedef struct {
+ int speed;
+ int delay;
+} LinkParameterStruct;
+
+static LinkParameterStruct LinkSpeedValues[] = {
+ { B300, 64 },
+ { B1200, 16 },
+ { B2400, 8 },
+ { B9600, 4 },
+ { B19200, 2 }
+};
+#endif /* XFREE86_V4 */
+
+
+/*
+ ***************************************************************************
+ *
+ * Default constants.
+ *
+ ***************************************************************************
+ */
+#define ELO_MAX_TRIALS 3 /* Number of timeouts waiting for a */
+ /* pending reply. */
+#define ELO_MAX_WAIT 100000 /* Max wait time for a reply (microsec) */
+#define ELO_UNTOUCH_DELAY 10 /* 100 ms */
+#define ELO_REPORT_DELAY 4 /* 40 ms or 25 motion reports/s */
+#define ELO_LINK_SPEED B9600 /* 9600 Bauds */
+#define ELO_PORT "/dev/ttyS1"
+
+#define DEFAULT_MAX_X 3000
+#define DEFAULT_MIN_X 600
+#define DEFAULT_MAX_Y 3000
+#define DEFAULT_MIN_Y 600
+
+
+/*
+ ***************************************************************************
+ *
+ * Protocol constants.
+ *
+ ***************************************************************************
+ */
+#define ELO_PACKET_SIZE 10
+
+#define ELO_SYNC_BYTE 'U' /* Sync byte. First of a packet. */
+#define ELO_TOUCH 'T' /* Report of touchs and motions. Not *
+ * used by 2310. */
+#define ELO_OWNER 'O' /* Report vendor name. */
+#define ELO_ID 'I' /* Report of type and features. */
+#define ELO_MODE 'M' /* Set current operating mode. */
+#define ELO_PARAMETER 'P' /* Set the serial parameters. */
+#define ELO_REPORT 'B' /* Set touch reports timings. */
+#define ELO_ACK 'A' /* Acknowledge packet */
+
+#define ELO_INIT_CHECKSUM 0xAA /* Initial value of checksum. */
+
+#define ELO_PRESS 0x01 /* Flags in ELO_TOUCH status byte */
+#define ELO_STREAM 0x02
+#define ELO_RELEASE 0x04
+
+#define ELO_TOUCH_MODE 0x01 /* Flags in ELO_MODE command */
+#define ELO_STREAM_MODE 0x02
+#define ELO_UNTOUCH_MODE 0x04
+#define ELO_RANGE_CHECK_MODE 0x40
+#define ELO_TRIM_MODE 0x02
+#define ELO_CALIB_MODE 0x04
+#define ELO_SCALING_MODE 0x08
+#define ELO_TRACKING_MODE 0x40
+
+#define ELO_SERIAL_SPEED 0x06 /* Flags for high speed serial (19200) */
+#define ELO_SERIAL_MASK 0xF8
+
+#define ELO_SERIAL_IO '0' /* Indicator byte for PARAMETER command */
+
+
+/*
+ ***************************************************************************
+ *
+ * Usefull macros.
+ *
+ ***************************************************************************
+ */
+#define WORD_ASSEMBLY(byte1, byte2) (((byte2) << 8) | (byte1))
+#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
+
+/* This one is handy, thanx Fred ! */
+#ifdef DBG
+#undef DBG
+#endif
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+static int debug_level = 0;
+#define DEBUG 1
+#if DEBUG
+#define DBG(lvl, f) {if ((lvl) <= debug_level) f;}
+#else
+#define DBG(lvl, f)
+#endif
+
+#ifdef XFREE86_V4
+#undef SYSCALL
+#undef read
+#undef write
+#undef close
+#define SYSCALL(call) call
+#define read(fd, ptr, num) xf86ReadSerial(fd, ptr, num)
+#define write(fd, ptr, num) xf86WriteSerial(fd, ptr, num)
+#define close(fd) xf86CloseSerial(fd)
+#endif
+
+
+/*
+ ***************************************************************************
+ *
+ * Device private records.
+ *
+ ***************************************************************************
+ */
+typedef struct _EloPrivateRec {
+ char *input_dev; /* The touchscreen input tty */
+ int min_x; /* Minimum x reported by calibration */
+ int max_x; /* Maximum x */
+ int min_y; /* Minimum y reported by calibration */
+ int max_y; /* Maximum y */
+ int untouch_delay; /* Delay before reporting an untouch (in ms) */
+ int report_delay; /* Delay between touch report packets */
+#ifndef XFREE86_V4
+ int link_speed; /* Speed of the RS232 link connecting the ts. */
+#endif
+ int screen_no; /* Screen associated with the device */
+ int screen_width; /* Width of the associated X screen */
+ int screen_height; /* Height of the screen */
+ Bool inited; /* The controller has already been configured ? */
+ Bool is_a_2310; /* Set if the smartset is a 2310. */
+ int checksum; /* Current checksum of data in assembly buffer */
+ int packet_buf_p; /* Assembly buffer pointer */
+ unsigned char packet_buf[ELO_PACKET_SIZE]; /* Assembly buffer */
+} EloPrivateRec, *EloPrivatePtr;
+
+
+#ifndef XFREE86_V4
+#if !defined(sun) || defined(i386)
+/*
+ ***************************************************************************
+ *
+ * xf86EloConfig --
+ * Configure the driver from the configuration data.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86EloConfig(LocalDevicePtr *array,
+ int inx,
+ int max,
+ LexPtr val)
+{
+ LocalDevicePtr local = array[inx];
+ EloPrivatePtr priv = (EloPrivatePtr)(local->private);
+ int token;
+
+ while ((token = xf86GetToken(EloTab)) != ENDSUBSECTION) {
+ switch(token) {
+
+ case PORT:
+ if (xf86GetToken(NULL) != STRING) {
+ xf86ConfigError("Elographics input port expected");
+ }
+ priv->input_dev = strdup(val->str);
+ if (xf86Verbose) {
+ ErrorF("%s Elographics input port: %s\n",
+ XCONFIG_GIVEN, priv->input_dev);
+ }
+ break;
+
+ case ELO_DEVICE_NAME:
+ if (xf86GetToken(NULL) != STRING) {
+ xf86ConfigError("Elographics device name expected");
+ }
+ local->name = strdup(val->str);
+ if (xf86Verbose) {
+ ErrorF("%s Elographics X device name: %s\n",
+ XCONFIG_GIVEN, local->name);
+ }
+ break;
+
+ case SCREEN_NO:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("Elographics screen number expected");
+ }
+ priv->screen_no = val->num;
+ if (xf86Verbose) {
+ ErrorF("%s Elographics associated screen: %d\n",
+ XCONFIG_GIVEN, priv->screen_no);
+ }
+ break;
+
+ case UNTOUCH_DELAY:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("Elographics untouch delay expected");
+ }
+ priv->untouch_delay = val->num;
+ if (xf86Verbose) {
+ ErrorF("%s Elographics untouch delay: %d ms\n",
+ XCONFIG_GIVEN, priv->untouch_delay*10);
+ }
+ break;
+
+ case REPORT_DELAY:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("Elographics report delay expected");
+ }
+ priv->report_delay = val->num;
+ if (xf86Verbose) {
+ ErrorF("%s Elographics report delay: %d ms\n",
+ XCONFIG_GIVEN, priv->report_delay*10);
+ }
+ break;
+
+ case LINK_SPEED:
+ {
+ int ltoken = xf86GetToken(LinkSpeedTab);
+ if (ltoken == EOF ||
+ ltoken == STRING ||
+ ltoken == NUMBER) {
+ xf86ConfigError("Elographics link speed expected");
+ }
+ priv->link_speed = LinkSpeedValues[ltoken-1].speed;
+ if (xf86Verbose) {
+ ErrorF("%s Elographics link speed: %s bps\n",
+ XCONFIG_GIVEN, (LinkSpeedTab[ltoken-1].name)+1);
+ }
+ }
+ break;
+
+ case MAXX:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("Elographics maximum x position expected");
+ }
+ priv->max_x = val->num;
+ if (xf86Verbose) {
+ ErrorF("%s Elographics maximum x position: %d\n",
+ XCONFIG_GIVEN, priv->max_x);
+ }
+ break;
+
+ case MAXY:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("Elographics maximum y position expected");
+ }
+ priv->max_y = val->num;
+ if (xf86Verbose) {
+ ErrorF("%s Elographics maximum y position: %d\n",
+ XCONFIG_GIVEN, priv->max_y);
+ }
+ break;
+
+ case MINX:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("Elographics minimum x position expected");
+ }
+ priv->min_x = val->num;
+ if (xf86Verbose) {
+ ErrorF("%s Elographics minimum x position: %d\n",
+ XCONFIG_GIVEN, priv->min_x);
+ }
+ break;
+
+ case MINY:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("Elographics minimum y position expected");
+ }
+ priv->min_y = val->num;
+ if (xf86Verbose) {
+ ErrorF("%s Elographics minimum y position: %d\n",
+ XCONFIG_GIVEN, priv->min_y);
+ }
+ break;
+
+ case DEBUG_LEVEL:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("Elographics driver debug level expected");
+ }
+ debug_level = val->num;
+ if (xf86Verbose) {
+#if DEBUG
+ ErrorF("%s Elographics debug level sets to %d\n", XCONFIG_GIVEN,
+ debug_level);
+#else
+ ErrorF("%s Elographics debug not available\n",
+ XCONFIG_GIVEN, debug_level);
+#endif
+ }
+ break;
+
+ case HISTORY_SIZE:
+ if (xf86GetToken(NULL) != NUMBER) {
+ xf86ConfigError("Elographics motion history size expected");
+ }
+ local->history_size = val->num;
+ if (xf86Verbose) {
+ ErrorF("%s EloGraphics motion history size is %d\n", XCONFIG_GIVEN,
+ local->history_size);
+ }
+ break;
+
+ case ALWAYS_CORE:
+ xf86AlwaysCore(local, TRUE);
+ if (xf86Verbose) {
+ ErrorF("%s Elographics device will always stays core pointer\n",
+ XCONFIG_GIVEN);
+ }
+ break;
+
+ case EOF:
+ FatalError("Unexpected EOF (missing EndSubSection)");
+ break;
+
+ default:
+ xf86ConfigError("Elographics subsection keyword expected");
+ break;
+ }
+ }
+
+ if (priv->max_x - priv->min_x <= 0) {
+ ErrorF("%s Elographics: swap x mode (minimum x position >= maximum x position)\n",
+ XCONFIG_GIVEN);
+ }
+ if (priv->max_y - priv->min_y <= 0) {
+ ErrorF("%s Elographics: swap y mode (minimum y position >= maximum y position)\n",
+ XCONFIG_GIVEN, priv->max_y, priv->min_y);
+ }
+
+ DBG(2, ErrorF("xf86EloConfig port name=%s\n", priv->input_dev))
+
+ return Success;
+}
+#endif
+#endif
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86EloGetPacket --
+ * Read a packet from the port. Try to synchronize with start of
+ * packet and compute checksum.
+ * The packet structure read by this function is as follow:
+ * Byte 0 : ELO_SYNC_BYTE
+ * Byte 1
+ * ...
+ * Byte 8 : packet data
+ * Byte 9 : checksum of bytes 0 to 8
+ *
+ * This function returns if a valid packet has been assembled in
+ * buffer or if no more data is available.
+ *
+ * Returns Success if a packet is successfully assembled including
+ * testing checksum. If a packet checksum is incorrect, it is discarded.
+ * Bytes preceding the ELO_SYNC_BYTE are also discarded.
+ * Returns !Success if out of data while reading. The start of the
+ * partially assembled packet is left in buffer, buffer_p and
+ * checksum reflect the current state of assembly.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86EloGetPacket(unsigned char *buffer,
+ int *buffer_p,
+ int *checksum,
+ int fd)
+{
+ int num_bytes;
+ Bool ok;
+
+ DBG(4, ErrorF("Entering xf86EloGetPacket with checksum == %d and buffer_p == %d\n",
+ *checksum, *buffer_p));
+
+ /*
+ * Try to read enough bytes to fill up the packet buffer.
+ */
+ DBG(4, ErrorF("buffer_p is %d, Trying to read %d bytes from link\n",
+ *buffer_p, ELO_PACKET_SIZE - *buffer_p));
+ SYSCALL(num_bytes = read(fd,
+ (char *) (buffer + *buffer_p),
+ ELO_PACKET_SIZE - *buffer_p));
+
+ /*
+ * Okay, give up.
+ */
+ if (num_bytes < 0) {
+ Error("System error while reading from Elographics touchscreen.");
+ return !Success;
+ }
+ DBG(4, ErrorF("Read %d bytes\n", num_bytes));
+
+ while (num_bytes) {
+ /*
+ * Sync with the start of a packet.
+ */
+ if ((*buffer_p == 0) && (buffer[0] != ELO_SYNC_BYTE)) {
+ /*
+ * No match, shift data one byte toward the start of the buffer.
+ */
+ DBG(4, ErrorF("Dropping one byte in an attempt to synchronize: '%c' 0x%X\n",
+ buffer[0], buffer[0]));
+ memcpy(&buffer[0], &buffer[1], num_bytes-1);
+ }
+ else {
+ /*
+ * Compute checksum in assembly buffer.
+ */
+ if (*buffer_p < ELO_PACKET_SIZE-1) {
+ *checksum = *checksum + buffer[*buffer_p];
+ *checksum = *checksum % 256;
+ DBG(4, ErrorF(" 0x%X-->0x%X ", buffer[*buffer_p], *checksum));
+ }
+ (*buffer_p)++;
+ }
+ num_bytes--;
+ }
+
+ if (*buffer_p == ELO_PACKET_SIZE) {
+ /*
+ * Got a packet, validate checksum and reset state.
+ */
+ ok = (*checksum == buffer[ELO_PACKET_SIZE-1]);
+ DBG(3, ErrorF("Expecting checksum %d, got %d\n", *checksum, buffer[ELO_PACKET_SIZE-1]));
+ *checksum = ELO_INIT_CHECKSUM;
+ *buffer_p = 0;
+
+ if (!ok) {
+ ErrorF("Checksum error on Elographics touchscreen link\n");
+ return !Success;
+ }
+
+ /*
+ * Valid packet received report it.
+ */
+ return Success;
+ }
+ else {
+ return !Success;
+ }
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86EloConvert --
+ * Convert extended valuators to x and y suitable for core motion
+ * events. Return True if ok and False if the requested conversion
+ * can't be done for the specified valuators.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86EloConvert(LocalDevicePtr local,
+ int first,
+ int num,
+ int v0,
+ int v1,
+ int v2,
+ int v3,
+ int v4,
+ int v5,
+ int *x,
+ int *y)
+{
+ EloPrivatePtr priv = (EloPrivatePtr) local->private;
+ int width = priv->max_x - priv->min_x;
+ int height = priv->max_y - priv->min_y;
+
+ if (first != 0 || num != 2) {
+ return FALSE;
+ }
+
+ DBG(3, ErrorF("EloConvert: v0(%d), v1(%d)\n", v0, v1));
+
+ *x = (priv->screen_width * (v0 - priv->min_x)) / width;
+ *y = (priv->screen_height -
+ (priv->screen_height * (v1 - priv->min_y)) / height);
+
+#ifdef XFREE86_V4
+ /*
+ * Need to check if still on the correct screen.
+ * This call is here so that this work can be done after
+ * calib and before posting the event.
+ */
+ xf86XInputSetScreen(local, priv->screen_no, *x, *y);
+#endif
+
+ DBG(3, ErrorF("EloConvert: x(%d), y(%d)\n", *x, *y));
+
+ return TRUE;
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86EloReadInput --
+ * Read all pending report packets from the touchscreen and enqueue
+ * them.
+ * If a packet is not fully received it is deferred until the next
+ * call to the function.
+ * Packets recognized by this function comply with the format:
+ *
+ * Byte 1 : ELO_TOUCH
+ * Byte 2 : Packet type
+ * Bit 2 : Pen Up (Release)
+ * Bit 1 : Position (Stream)
+ * Bit 0 : Pen Down (Press)
+ * Byte 3 : X coordinate (lower bits)
+ * Byte 4 : X coordinate (upper bits)
+ * Byte 5 : Y coordinate (lower bits)
+ * Byte 6 : Y coordinate (upper bits)
+ * Byte 7 : Z coordinate (lower bits)
+ * Byte 8 : Z coordinates (upper bits)
+ *
+ *
+ ***************************************************************************
+ */
+static void
+xf86EloReadInput(LocalDevicePtr local)
+{
+ EloPrivatePtr priv = (EloPrivatePtr)(local->private);
+ int cur_x, cur_y;
+ int state;
+
+ DBG(4, ErrorF("Entering ReadInput\n"));
+ /*
+ * Try to get a packet.
+ */
+ if (xf86EloGetPacket(priv->packet_buf,
+ &priv->packet_buf_p,
+ &priv->checksum,
+ local->fd) != Success) {
+ return;
+ }
+
+ /*
+ * Process only ELO_TOUCHs here.
+ */
+ if (priv->packet_buf[1] == ELO_TOUCH) {
+ /*
+ * First stick together the various pieces.
+ */
+ cur_x = WORD_ASSEMBLY(priv->packet_buf[3], priv->packet_buf[4]);
+ cur_y = WORD_ASSEMBLY(priv->packet_buf[5], priv->packet_buf[6]);
+ state = priv->packet_buf[2] & 0x07;
+
+ /*
+ * Send events.
+ *
+ * We *must* generate a motion before a button change if pointer
+ * location has changed as DIX assumes this. This is why we always
+ * emit a motion, regardless of the kind of packet processed.
+ */
+ xf86PostMotionEvent(local->dev, TRUE, 0, 2, cur_x, cur_y);
+
+ /*
+ * Emit a button press or release.
+ */
+ if (state == ELO_PRESS || state == ELO_RELEASE) {
+ xf86PostButtonEvent(local->dev, TRUE, 1, state == ELO_PRESS, 0, 2, cur_x, cur_y);
+ }
+
+ DBG(3, ErrorF("TouchScreen: x(%d), y(%d), %s\n",
+ cur_x, cur_y,
+ (state == ELO_PRESS) ? "Press" : ((state == ELO_RELEASE) ? "Release" : "Stream")));
+ }
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86EloSendPacket --
+ * Emit an height bytes packet to the controller.
+ * The function expects a valid buffer containing the
+ * command to be sent to the controller. It fills it with the
+ * leading sync character an the trailing checksum byte.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86EloSendPacket(unsigned char *packet,
+ int fd)
+{
+ int i, result;
+ int sum = ELO_INIT_CHECKSUM;
+
+ packet[0] = ELO_SYNC_BYTE;
+ for (i = 0; i < ELO_PACKET_SIZE-1; i++) {
+ sum += packet[i];
+ sum &= 0xFF;
+ }
+ packet[ELO_PACKET_SIZE-1] = sum;
+
+ DBG(4, ErrorF("Sending packet : 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X \n",
+ packet[0], packet[1], packet[2], packet[3], packet[4],
+ packet[5], packet[6], packet[7], packet[8], packet[9]));
+ SYSCALL(result = write(fd, packet, ELO_PACKET_SIZE));
+ if (result != ELO_PACKET_SIZE) {
+ DBG(5, ErrorF("System error while sending to Elographics touchscreen.\n"));
+ return !Success;
+ }
+ else {
+ return Success;
+ }
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86EloWaitReply --
+ * It is assumed that the reply will be in the few next bytes
+ * read and will be available very soon after the query post. if
+ * these two asumptions are not met, there are chances that the server
+ * will be stuck for a while.
+ * The reply type need to match parameter 'type'.
+ * The reply is left in reply. The function returns Success if the
+ * reply is valid and !Success otherwise.
+ *
+ ***************************************************************************
+ */
+#ifndef XFREE86_V4
+static int
+xf86WaitForInput(int fd,
+ int timeout)
+{
+ fd_set readfds;
+ struct timeval to;
+ int r;
+
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+ to.tv_sec = 0;
+ to.tv_usec = timeout;
+
+ SYSCALL(r = select(FD_SETSIZE, &readfds, NULL, NULL, &to));
+ return r;
+}
+#endif
+
+static Bool
+xf86EloWaitReply(unsigned char type,
+ unsigned char *reply,
+ int fd)
+{
+ Bool ok;
+ int i, result;
+ int reply_p = 0;
+ int sum = ELO_INIT_CHECKSUM;
+
+ DBG(4, ErrorF("Waiting a '%c' reply\n", type));
+ i = ELO_MAX_TRIALS;
+ do {
+ ok = !Success;
+
+ /*
+ * Wait half a second for the reply. The fuse counts down each
+ * timeout and each wrong packet.
+ */
+ DBG(4, ErrorF("Waiting %d ms for data from port\n", ELO_MAX_WAIT / 1000));
+ result = xf86WaitForInput(fd, ELO_MAX_WAIT);
+ if (result > 0) {
+ ok = xf86EloGetPacket(reply, &reply_p, &sum, fd);
+ /*
+ * Do not report an error on a 'P' query as the controller
+ * might be a 2310.
+ */
+ if (ok == Success && reply[1] != type && type != ELO_PARAMETER) {
+ DBG(3, ErrorF("Wrong reply received\n"));
+ ok = !Success;
+ }
+ }
+ else {
+ DBG(3, ErrorF("No answer from link : %d\n", result));
+ }
+
+ if (result == 0) {
+ i--;
+ }
+ } while(ok != Success && i);
+
+ return ok;
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86EloWaitAck --
+ * Wait for an acknowledge from the controller. Returns Success if
+ * acknowledge received and reported no errors.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86EloWaitAck(int fd)
+{
+ unsigned char packet[ELO_PACKET_SIZE];
+ int i, nb_errors;
+
+ if (xf86EloWaitReply(ELO_ACK, packet, fd) == Success) {
+ for (i = 0, nb_errors = 0; i < 4; i++) {
+ if (packet[2 + i] != '0') {
+ nb_errors++;
+ }
+ }
+ if (nb_errors != 0) {
+ DBG(2, ErrorF("Elographics acknowledge packet reports %d errors\n",
+ nb_errors));
+ }
+ return Success;
+ /* return (nb_errors < 4) ? Success : !Success;*/
+ }
+ else {
+ return !Success;
+ }
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86EloSendQuery --
+ * Emit a query to the controller and blocks until the reply and
+ * the acknowledge are read.
+ *
+ * The reply is left in reply. The function returns Success if the
+ * reply is valid and !Success otherwise.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86EloSendQuery(unsigned char *request,
+ unsigned char *reply,
+ int fd)
+{
+ Bool ok;
+
+ if (xf86EloSendPacket(request, fd) == Success) {
+ ok = xf86EloWaitReply(toupper(request[1]), reply, fd);
+ if (ok == Success) {
+ ok = xf86EloWaitAck(fd);
+ }
+ return ok;
+ }
+ else {
+ return !Success;
+ }
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86EloSendControl --
+ * Emit a control command to the controller and wait for acknowledge.
+ *
+ * Returns Success if acknowledge received and reported no error.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86EloSendControl(unsigned char *control,
+ int fd)
+{
+ if (xf86EloSendPacket(control, fd) == Success) {
+ return xf86EloWaitAck(fd);
+ }
+ else {
+ return !Success;
+ }
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86EloPrintIdent --
+ * Print type of touchscreen and features on controller board.
+ *
+ ***************************************************************************
+ */
+static void
+xf86EloPrintIdent(unsigned char *packet,
+ EloPrivatePtr priv)
+{
+#ifdef XFREE86_V4
+ xf86Msg(X_PROBED, "Elographics touchscreen is a ");
+ switch(packet[2]) {
+ case '0':
+ xf86Msg(X_NONE, "AccuTouch");
+ break;
+ case '1':
+ xf86Msg(X_NONE, "DuraTouch");
+ break;
+ case '2':
+ xf86Msg(X_NONE, "Intellitouch");
+ break;
+ }
+ xf86Msg(X_NONE, ", connected through a ");
+ switch(packet[3]) {
+ case '0':
+ xf86Msg(X_NONE, "serial link.\n");
+ break;
+ case '1':
+ xf86Msg(X_NONE, "PC-Bus port.\n");
+ break;
+ case '2':
+ xf86Msg(X_NONE, "Micro Channel port.\n");
+ break;
+ }
+ xf86Msg(X_PROBED, "The controller is a model ");
+ if (packet[8] & 1) {
+ if (priv->is_a_2310) {
+ xf86Msg(X_NONE, "E281-2310");
+ }
+ else {
+ xf86Msg(X_NONE, "E271-2210");
+ }
+ }
+ else {
+ xf86Msg(X_NONE, "E271-2200");
+ }
+ xf86Msg(X_NONE, ", firmware revision %d.%d.\n", packet[6], packet[5]);
+
+ if (packet[4]) {
+ xf86Msg(X_PROBED, " Additional features:\n");
+ if (packet[4] & 0x10) {
+ xf86Msg(X_PROBED, " External A/D converter\n");
+ }
+ if (packet[4] & 0x20) {
+ xf86Msg(X_PROBED, " 32Ko RAM\n");
+ }
+ if (packet[4] & 0x40) {
+ xf86Msg(X_PROBED, " RAM onboard\n");
+ }
+ if (packet[4] & 0x80) {
+ xf86Msg(X_PROBED, " Z axis active\n");
+ }
+ xf86Msg(X_NONE, "\n");
+ }
+#else
+ ErrorF("%s Elographics touchscreen is a ", XCONFIG_PROBED);
+ switch(packet[2]) {
+ case '0':
+ ErrorF("AccuTouch");
+ break;
+ case '1':
+ ErrorF("DuraTouch");
+ break;
+ case '2':
+ ErrorF("Intellitouch");
+ break;
+ }
+ ErrorF(", connected through a ");
+ switch(packet[3]) {
+ case '0':
+ ErrorF("serial link.\n");
+ break;
+ case '1':
+ ErrorF("PC-Bus port.\n");
+ break;
+ case '2':
+ ErrorF("Micro Channel port.\n");
+ break;
+ }
+ ErrorF("%s The controller is a model ", XCONFIG_PROBED);
+ if (packet[8] & 1) {
+ if (priv->is_a_2310) {
+ ErrorF("E281-2310");
+ }
+ else {
+ ErrorF("E271-2210");
+ }
+ }
+ else {
+ ErrorF("E271-2200");
+ }
+ ErrorF(", firmware revision %d.%d.\n", packet[6], packet[5]);
+
+ if (packet[4]) {
+ ErrorF("%s Additional features:\n", XCONFIG_PROBED);
+ if (packet[4] & 0x10) {
+ ErrorF("%s External A/D converter\n", XCONFIG_PROBED);
+ }
+ if (packet[4] & 0x20) {
+ ErrorF("%s 32Ko RAM\n", XCONFIG_PROBED);
+ }
+ if (packet[4] & 0x40) {
+ ErrorF("%s RAM onboard\n", XCONFIG_PROBED);
+ }
+ if (packet[4] & 0x80) {
+ ErrorF("%s Z axis active\n", XCONFIG_PROBED);
+ }
+ ErrorF("\n");
+ }
+#endif
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86EloPtrControl --
+ *
+ ***************************************************************************
+ */
+#if 0
+static void
+xf86EloPtrControl(DeviceIntPtr dev,
+ PtrCtrl *ctrl)
+{
+}
+#endif
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86EloControl --
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86EloControl(DeviceIntPtr dev,
+ int mode)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ EloPrivatePtr priv = (EloPrivatePtr)(local->private);
+ unsigned char map[] = { 0, 1 };
+ unsigned char req[ELO_PACKET_SIZE];
+ unsigned char reply[ELO_PACKET_SIZE];
+
+ switch(mode) {
+
+ case DEVICE_INIT:
+ {
+#if defined(sun) && !defined(i386)
+ char *name = (char *) getenv("ELO_DEV");
+ char *calib = (char *) getenv("ELO_CALIB");
+ char *speed = (char *) getenv("ELO_SPEED");
+ char *delays = (char *) getenv("ELO_DELAYS");
+#endif
+
+ DBG(2, ErrorF("Elographics touchscreen init...\n"));
+
+#if defined(sun) && !defined(i386)
+ if (name) {
+ priv->input_dev = strdup(name);
+ ErrorF("Elographics touchscreen port changed to '%s'\n",
+ priv->input_dev);
+ }
+ if (calib) {
+ if (sscanf(calib, "%d %d %d %d",
+ &priv->min_x, &priv->max_x,
+ &priv->min_y, &priv->max_y) != 4) {
+ ErrorF("Incorrect syntax in ELO_CALIB\n");
+ return !Success;
+ }
+ else if (priv->max_x <= priv->min_x ||
+ priv->max_y <= priv->min_y) {
+ ErrorF("Bogus calibration data in ELO_CALIB\n");
+ return !Success;
+ }
+ else {
+ ErrorF("Calibration will be done with:\n");
+ ErrorF("x_min=%d, x_max=%d, y_min=%d, y_max=%d\n",
+ priv->min_x, priv->max_x, priv->min_y, priv->max_y);
+ }
+ }
+ if (speed) {
+ /* These tests should be kept in sync with the LinkSpeedValues
+ * array. */
+ if (strcmp(speed, "B9600") == 0) {
+ priv->link_speed = B9600;
+ }
+ else if (strcmp(speed, "B19200") == 0) {
+ priv->link_speed = B19200;
+ }
+ else if (strcmp(speed, "B2400") == 0) {
+ priv->link_speed = B2400;
+ }
+ else if (strcmp(speed, "B1200") == 0) {
+ priv->link_speed = B1200;
+ }
+ else if (strcmp(speed, "B300") == 0) {
+ priv->link_speed = B300;
+ }
+ else {
+ ErrorF("Bogus speed value in ELO_SPEED\n");
+ return !Success;
+ }
+ }
+ if (delays) {
+ if (sscanf(delays, "%d %d",
+ &priv->untouch_delay,
+ &priv->report_delay) != 2) {
+ ErrorF("Bogus delays data in ELO_DELAYS\n");
+ }
+ else {
+ ErrorF("Untouch delay will be: %d\n", priv->untouch_delay);
+ ErrorF("Report delay will be: %d\n", priv->report_delay);
+ }
+ }
+#endif
+
+ if (priv->screen_no >= screenInfo.numScreens ||
+ priv->screen_no < 0) {
+ priv->screen_no = 0;
+ }
+ priv->screen_width = screenInfo.screens[priv->screen_no]->width;
+ priv->screen_height = screenInfo.screens[priv->screen_no]->height;
+
+ /*
+ * Device reports button press for up to 1 button.
+ */
+ if (InitButtonClassDeviceStruct(dev, 1, map) == FALSE) {
+ ErrorF("Unable to allocate Elographics touchscreen ButtonClassDeviceStruct\n");
+ return !Success;
+ }
+
+ /*
+ * Device reports motions on 2 axes in absolute coordinates.
+ * Axes min and max values are reported in raw coordinates.
+ * Resolution is computed roughly by the difference between
+ * max and min values scaled from the approximate size of the
+ * screen to fit one meter.
+ */
+ if (InitValuatorClassDeviceStruct(dev, 2, xf86GetMotionEvents,
+ local->history_size, Absolute) == FALSE) {
+ ErrorF("Unable to allocate Elographics touchscreen ValuatorClassDeviceStruct\n");
+ return !Success;
+ }
+ else {
+ InitValuatorAxisStruct(dev, 0, priv->min_x, priv->max_x,
+ 9500,
+ 0 /* min_res */,
+ 9500 /* max_res */);
+ InitValuatorAxisStruct(dev, 1, priv->min_y, priv->max_y,
+ 10500,
+ 0 /* min_res */,
+ 10500 /* max_res */);
+ }
+
+ if (InitFocusClassDeviceStruct(dev) == FALSE) {
+ ErrorF("Unable to allocate Elographics touchscreen FocusClassDeviceStruct\n");
+ }
+
+ /*
+ * Allocate the motion events buffer.
+ */
+ xf86MotionHistoryAllocate(local);
+
+ /*
+ * This once has caused the server to crash after doing an xalloc & strcpy ??
+ */
+#ifndef XFREE86_V4
+ AssignTypeAndName(dev, local->atom, local->name);
+#endif
+
+ DBG(2, ErrorF("Done.\n"));
+ return Success;
+ }
+
+ case DEVICE_ON:
+ DBG(2, ErrorF("Elographics touchscreen on...\n"));
+
+ if (local->fd < 0) {
+#ifndef XFREE86_V4
+ struct termios termios_tty;
+ int i, result;
+#endif
+
+ DBG(2, ErrorF("Elographics touchscreen opening : %s\n", priv->input_dev));
+#ifdef XFREE86_V4
+ local->fd = xf86OpenSerial(local->options);
+ if (local->fd < 0) {
+ Error("Unable to open Elographics touchscreen device");
+ return !Success;
+ }
+#else
+ SYSCALL(local->fd = open(priv->input_dev, O_RDWR|O_NDELAY, 0));
+ if (local->fd < 0) {
+ Error("Unable to open Elographics touchscreen device");
+ return !Success;
+ }
+
+ DBG(3, ErrorF("Try to see if the link is at the specified rate\n"));
+ memset(&termios_tty, 0, sizeof(termios_tty));
+ termios_tty.c_cflag = priv->link_speed | CS8 | CREAD | CLOCAL;
+ termios_tty.c_cc[VMIN] = 1;
+ SYSCALL(result = tcsetattr(local->fd, TCSANOW, &termios_tty));
+ if (result < 0) {
+ Error("Unable to configure Elographics touchscreen port");
+ goto not_success;
+ }
+#endif
+ /*
+ * Try to see if the link is at the specified rate and
+ * ask the controller to report various infos.
+ */
+ memset(req, 0, ELO_PACKET_SIZE);
+ req[1] = tolower(ELO_PARAMETER);
+ if (xf86EloSendQuery(req, reply, local->fd) != Success) {
+ priv->is_a_2310 = 1;
+ ErrorF("Not at the specified rate or model 2310, will continue\n");
+ }
+
+ /*
+ * Ask the controller to report various infos.
+ */
+ memset(req, 0, ELO_PACKET_SIZE);
+ req[1] = tolower(ELO_ID);
+ if (xf86EloSendQuery(req, reply, local->fd) == Success) {
+ xf86EloPrintIdent(reply, priv);
+ }
+ else {
+ ErrorF("Unable to ask Elographics touchscreen identification\n");
+ goto not_success;
+ }
+
+ /*
+ * Set the operating mode: Stream, no scaling, no calibration,
+ * no range checking, no trim, tracking enabled.
+ */
+ memset(req, 0, ELO_PACKET_SIZE);
+ req[1] = ELO_MODE;
+ req[3] = ELO_TOUCH_MODE | ELO_STREAM_MODE | ELO_UNTOUCH_MODE;
+ req[4] = ELO_TRACKING_MODE;
+ if (xf86EloSendControl(req, local->fd) != Success) {
+ ErrorF("Unable to change Elographics touchscreen operating mode\n");
+ goto not_success;
+ }
+
+#ifndef XFREE86_V4
+ /*
+ * Check if the report delay is compatible with the selected
+ * link speed and reset it otherwise.
+ */
+ for (i = 0; i < sizeof(LinkSpeedValues)/sizeof(LinkParameterStruct); i++) {
+ if (LinkSpeedValues[i].speed == priv->link_speed) {
+ if (LinkSpeedValues[i].delay > priv->report_delay) {
+ ErrorF("Changing report delay from %d ms to %d ms to comply with link speed\n",
+ priv->report_delay*10, LinkSpeedValues[i].delay*10);
+ priv->report_delay = LinkSpeedValues[i].delay;
+ }
+ }
+ }
+#endif
+ /*
+ * Set the touch reports timings from configuration data.
+ */
+ memset(req, 0, ELO_PACKET_SIZE);
+ req[1] = ELO_REPORT;
+ req[2] = priv->untouch_delay;
+ req[3] = priv->report_delay;
+ if (xf86EloSendControl(req, local->fd) != Success) {
+ ErrorF("Unable to change Elographics touchscreen reports timings\n");
+
+ not_success:
+ SYSCALL(close(local->fd));
+ local->fd = -1;
+ return !Success;
+ }
+
+ AddEnabledDevice(local->fd);
+ dev->public.on = TRUE;
+ }
+
+ DBG(2, ErrorF("Done\n"));
+ return Success;
+
+ /*
+ * Deactivate the device. After this, the device will not emit
+ * events until a subsequent DEVICE_ON. Thus, we can momentarily
+ * close the port.
+ */
+ case DEVICE_OFF:
+ DBG(2, ErrorF("Elographics touchscreen off...\n"));
+ dev->public.on = FALSE;
+ if (local->fd >= 0) {
+ RemoveEnabledDevice(local->fd);
+ }
+ SYSCALL(close(local->fd));
+ local->fd = -1;
+ DBG(2, ErrorF("Done\n"));
+ return Success;
+
+ /*
+ * Final close before server exit. This is used during server shutdown.
+ * Close the port and free all the resources.
+ */
+ case DEVICE_CLOSE:
+ DBG(2, ErrorF("Elographics touchscreen close...\n"));
+ dev->public.on = FALSE;
+ if (local->fd >= 0) {
+ RemoveEnabledDevice(local->fd);
+ }
+ SYSCALL(close(local->fd));
+ local->fd = -1;
+ DBG(2, ErrorF("Done\n"));
+ return Success;
+
+ default:
+ ErrorF("unsupported mode=%d\n", mode);
+ return !Success;
+ }
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86EloAllocate --
+ *
+ ***************************************************************************
+ */
+static LocalDevicePtr
+xf86EloAllocate(void)
+{
+ LocalDevicePtr local = (LocalDevicePtr) xalloc(sizeof(LocalDeviceRec));
+ EloPrivatePtr priv = (EloPrivatePtr) xalloc(sizeof(EloPrivateRec));
+
+ if (!local) {
+ if (priv) {
+ xfree(priv);
+ }
+ return NULL;
+ }
+ if (!priv) {
+ if (local) {
+ xfree(local);
+ }
+ return NULL;
+ }
+
+#ifdef XFREE86_V4
+ priv->input_dev = strdup(ELO_PORT);
+#else
+ priv->input_dev = ELO_PORT;
+ priv->link_speed = ELO_LINK_SPEED;
+#endif
+ priv->min_x = 0;
+ priv->max_x = 3000;
+ priv->min_y = 0;
+ priv->max_y = 3000;
+ priv->untouch_delay = ELO_UNTOUCH_DELAY;
+ priv->report_delay = ELO_REPORT_DELAY;
+ priv->screen_no = 0;
+ priv->screen_width = -1;
+ priv->screen_height = -1;
+ priv->inited = 0;
+ priv->is_a_2310 = 0;
+ priv->checksum = ELO_INIT_CHECKSUM;
+ priv->packet_buf_p = 0;
+
+ local->name = XI_TOUCHSCREEN;
+ local->flags = 0;
+#ifndef XFREE86_V4
+#if !defined(sun) || defined(i386)
+ local->device_config = xf86EloConfig;
+#endif
+#endif
+ local->device_control = xf86EloControl;
+ local->read_input = xf86EloReadInput;
+ local->control_proc = NULL;
+ local->close_proc = NULL;
+ local->switch_mode = NULL;
+ local->conversion_proc = xf86EloConvert;
+ local->reverse_conversion_proc = NULL;
+ local->fd = -1;
+ local->atom = 0;
+ local->dev = NULL;
+ local->private = priv;
+ local->type_name = "Elographics TouchScreen";
+ local->history_size = 0;
+
+ return local;
+}
+
+#ifndef XFREE86_V4
+/*
+ ***************************************************************************
+ *
+ * Elographics device association --
+ *
+ ***************************************************************************
+ */
+DeviceAssocRec elographics_assoc =
+{
+ "elographics", /* config_section_name */
+ xf86EloAllocate /* device_allocate */
+};
+
+#ifdef DYNAMIC_MODULE
+/*
+ ***************************************************************************
+ *
+ * entry point of dynamic loading
+ *
+ ***************************************************************************
+ */
+int
+#ifndef DLSYM_BUG
+init_module(unsigned long server_version)
+#else
+init_xf86Elo(unsigned long server_version)
+#endif
+{
+ xf86AddDeviceAssoc(&elographics_assoc);
+
+ if (server_version != XF86_VERSION_CURRENT) {
+ ErrorF("Warning: Elographics module compiled for version%s\n", XF86_VERSION);
+ return 0;
+ }
+ else {
+ return 1;
+ }
+}
+#endif
+
+#else /* XFREE86_V4 */
+static const char *default_options[] = {
+ "BaudRate", "9600",
+ "StopBits", "1",
+ "DataBits", "8",
+ "Parity", "None",
+ "Vmin", "10",
+ "Vtime", "1",
+ "FlowControl", "None"
+};
+
+static pointer
+Plug(pointer module,
+ pointer options,
+ int *errmaj,
+ int *errmin)
+{
+ LocalDevicePtr local;
+ EloPrivatePtr priv;
+ pointer defaults, merged;
+ char *dev;
+
+ local = xf86EloAllocate();
+ if (!local) {
+ *errmaj = LDR_NOMEM;
+ return NULL;
+ }
+ priv = local->private;
+
+ defaults = xf86OptionListCreate(default_options,
+ sizeof(default_options)/sizeof(default_options[0]), 0);
+ merged = xf86OptionListMerge(defaults, options);
+ xf86OptionListReport(merged);
+
+ dev = xf86FindOptionValue(merged, "Device");
+ if (dev) {
+ xfree(priv->input_dev);
+ priv->input_dev = strdup(dev);
+ }
+
+ local->name = xf86SetStrOption(merged, "DeviceName", XI_TOUCHSCREEN);
+ xf86Msg(X_CONFIG, "Elographics X device name: %s\n", local->name);
+ priv->screen_no = xf86SetIntOption(merged, "ScreenNo", 0);
+ xf86Msg(X_CONFIG, "Elographics associated screen: %d\n", priv->screen_no);
+ priv->untouch_delay = xf86SetIntOption(merged, "UntouchDelay", ELO_UNTOUCH_DELAY);
+ xf86Msg(X_CONFIG, "Elographics untouch delay: %d ms\n", priv->untouch_delay*10);
+ priv->report_delay = xf86SetIntOption(merged, "ReportDelay", ELO_REPORT_DELAY);
+ xf86Msg(X_CONFIG, "Elographics report delay: %d ms\n", priv->report_delay*10);
+ priv->max_x = xf86SetIntOption(merged, "MaximumXPosition", 3000);
+ xf86Msg(X_CONFIG, "Elographics maximum x position: %d\n", priv->max_x);
+ priv->min_x = xf86SetIntOption(merged, "MinimumXPosition", 0);
+ xf86Msg(X_CONFIG, "Elographics minimum x position: %d\n", priv->min_x);
+ priv->max_y = xf86SetIntOption(merged, "MaximumYPosition", 3000);
+ xf86Msg(X_CONFIG, "Elographics maximum y position: %d\n", priv->max_y);
+ priv->min_y = xf86SetIntOption(merged, "MinimumYPosition", 0);
+ xf86Msg(X_CONFIG, "Elographics minimum y position: %d\n", priv->min_y);
+ debug_level = xf86SetIntOption(merged, "DebugLevel", 0);
+ if (debug_level) {
+#if DEBUG
+ xf86Msg(X_CONFIG, "Elographics debug level sets to %d\n", debug_level);
+#else
+ xf86Msg(X_INFO, "Elographics debug not available\n");
+#endif
+ }
+
+ if (priv->max_x - priv->min_x <= 0) {
+ xf86Msg(X_INFO, "Elographics: swap x mode (minimum x position >= maximum x position)\n");
+ }
+ if (priv->max_y - priv->min_y <= 0) {
+ xf86Msg(X_INFO, "Elographics: swap y mode (minimum y position >= maximum y position)\n");
+ }
+
+ xf86AddLocalDevice(local, merged);
+
+ return local;
+}
+
+static void
+Unplug(pointer p)
+{
+ LocalDevicePtr local = (LocalDevicePtr) p;
+ EloPrivatePtr priv = (EloPrivatePtr) local->private;
+
+ xf86EloControl(local->dev, DEVICE_OFF);
+ xf86RemoveLocalDevice(local);
+
+ xfree(priv->input_dev);
+ xfree(priv);
+ xfree(local->name);
+ xfree(local);
+}
+
+static XF86ModuleVersionInfo version_rec = {
+ "elographics",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_XINPUT,
+ ABI_XINPUT_VERSION,
+ MOD_CLASS_XINPUT,
+ { 0, 0, 0, 0 }
+};
+
+/*
+ * This is the entry point in the module. The name
+ * is setup after the pattern <module_name>ModuleData.
+ * Do not change it.
+ */
+XF86ModuleData elographicsModuleData = { &version_rec, Plug, Unplug };
+
+#endif /* XFREE86_V4 */
diff --git a/xc/programs/Xserver/hw/xfree86/input/joystick/Imakefile b/xc/programs/Xserver/hw/xfree86/input/joystick/Imakefile
new file mode 100644
index 000000000..0a7bd34c5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/joystick/Imakefile
@@ -0,0 +1,34 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/joystick/Imakefile,v 1.5 1999/08/14 10:50:00 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = xf86Jstk.c
+OBJS = xf86Jstk.o $(ARCH_JSTK)
+
+DRIVER = joystick
+
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86SRC)/loader -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+#ifdef LinuxArchitecture
+ ARCH_JSTK = ../os-support/linux/lnx_jstk.o
+#endif
+
+#if defined(FreeBSDArchitecture) || defined(NetBSDArchitecture) || defined(OpenBSDArchitecture)
+ ARCH_JSTK = ../os-support/bsd/bsd_jstk.o
+#endif
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget($(DRIVER),$(OBJS))
+
+InstallObjectModule($(DRIVER),$(MODULEDIR),input)
+
+DependTarget()
+
+InstallDriverSDKObjectModule($(DRIVER),$(DRIVERSDKMODULEDIR),input)
diff --git a/xc/programs/Xserver/hw/xfree86/input/joystick/xf86Jstk.c b/xc/programs/Xserver/hw/xfree86/input/joystick/xf86Jstk.c
new file mode 100644
index 000000000..d51f4fa96
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/joystick/xf86Jstk.c
@@ -0,0 +1,793 @@
+/* $XConsortium: xf86Jstk.c /main/14 1996/10/25 14:11:36 kaleb $ */
+/*
+ * Copyright 1995-1999 by Frederic Lepied, France. <Lepied@XFree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Frederic Lepied not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Frederic Lepied makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * FREDERIC LEPIED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL FREDERIC LEPIED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/joystick/xf86Jstk.c,v 1.4 1999/06/13 05:18:55 dawes Exp $ */
+
+#include <xf86Version.h>
+
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(3,9,0,0,0)
+#define XFREE86_V4 1
+#endif
+
+#ifdef XFREE86_V4
+/* post 3.9 headers */
+
+#include <misc.h>
+#include <xf86.h>
+#include <xf86_ansic.h>
+#include <xf86_OSproc.h>
+#include <xf86Xinput.h>
+#include <xisb.h>
+#include <exevents.h> /* Needed for InitValuator/Proximity stuff */
+#include <keysym.h>
+
+#ifdef XFree86LOADER
+#include <xf86Module.h>
+#endif
+
+#define sleep(t) xf86WaitForInput(-1, 1000 * (t))
+#define wait_for_fd(fd) xf86WaitForInput((fd), 1000)
+#define tcflush(fd, n) xf86FlushInput((fd))
+#undef read
+#define read(a,b,c) xf86ReadSerial((a),(b),(c))
+#undef write
+#define write(a,b,c) xf86WriteSerial((a),(char*)(b),(c))
+#define XCONFIG_PROBED "(==)"
+#define XCONFIG_GIVEN "(**)"
+#define xf86Verbose 1
+
+#else /* pre 3.9 headers */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "XI.h"
+#include "XIproto.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86Xinput.h"
+#include "xf86_OSlib.h"
+#include "atKeynames.h"
+#include "xf86Version.h"
+
+#include "osdep.h"
+
+#endif /* pre 3.9 headers */
+
+/******************************************************************************
+ * debugging macro
+ *****************************************************************************/
+#ifdef DBG
+#undef DBG
+#endif
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+static int debug_level = 0;
+#define DEBUG 1
+#if DEBUG
+#define DBG(lvl, f) {if ((lvl) <= debug_level) f;}
+#else
+#define DBG(lvl, f)
+#endif
+
+/******************************************************************************
+ * device records
+ *****************************************************************************/
+
+typedef struct
+{
+ int jstkFd; /* Joystick File Descriptor */
+ OsTimerPtr jstkTimer; /* timer object */
+ int jstkTimeout; /* timeout to poll device */
+ char *jstkDevice; /* device file name */
+ int jstkOldX; /* previous X position */
+ int jstkOldY; /* previous Y position */
+ int jstkOldButtons; /* previous buttons state */
+ int jstkMaxX; /* max X value */
+ int jstkMaxY; /* max Y value */
+ int jstkMinX; /* min X value */
+ int jstkMinY; /* min Y value */
+ int jstkCenterX; /* X center value */
+ int jstkCenterY; /* Y center value */
+ int jstkDelta; /* delta cursor */
+} JoystickDevRec, *JoystickDevPtr;
+
+#ifndef XFREE86_V4
+/******************************************************************************
+ * configuration stuff
+ *****************************************************************************/
+#define DEVICENAME 1
+#define TIMEOUT 2
+#define MAXX 3
+#define MAXY 4
+#define MINX 5
+#define MINY 6
+#define CENTERX 7
+#define CENTERY 8
+#define DELTA 9
+#define PORT 10
+#define DEBUG_LEVEL 11
+#define HISTORY_SIZE 12
+#define ALWAYS_CORE 13
+
+static SymTabRec JstkTab[] = {
+ { ENDSUBSECTION, "endsubsection" },
+ { DEVICENAME, "devicename" },
+ { TIMEOUT, "timeout" },
+ { MAXX, "maximumxposition" },
+ { MAXY, "maximumyposition" },
+ { MINX, "minimumxposition" },
+ { MINY, "minimumyposition" },
+ { CENTERX, "centerx" },
+ { CENTERY, "centery" },
+ { DELTA, "delta" },
+ { PORT, "port" },
+ { DEBUG_LEVEL, "debuglevel" },
+ { HISTORY_SIZE, "historysize" },
+ { ALWAYS_CORE, "alwayscore" },
+ { -1, "" },
+};
+
+/******************************************************************************
+ * external declarations
+ *****************************************************************************/
+
+extern void xf86eqEnqueue(
+ xEventPtr /*e*/
+);
+
+extern void miPointerDeltaCursor(
+ int /*dx*/,
+ int /*dy*/,
+ unsigned long /*time*/
+);
+
+#endif /* ! XFREE86_V4 */
+
+extern int xf86JoystickGetState(
+ int /*fd*/,
+ int * /*x*/,
+ int * /*y*/,
+ int * /*buttons*/
+ );
+
+extern void xf86JoystickInit(void);
+
+extern int xf86JoystickOff(
+int * /*fd*/,
+int /*doclose*/
+);
+
+extern int xf86JoystickOn(
+char * /*name*/,
+int * /*timeout*/,
+int * /*centerX*/,
+int * /*centerY*/
+);
+
+#ifndef XFREE86_V4
+/*
+ * xf86JstkConfig --
+ * Configure the device.
+ */
+static Bool
+xf86JstkConfig(LocalDevicePtr *array,
+ int index,
+ int max,
+ LexPtr val)
+{
+ LocalDevicePtr dev = array[index];
+ JoystickDevPtr priv = (JoystickDevPtr)(dev->private);
+ int token;
+
+ DBG(1, ErrorF("xf86JstkConfig\n"));
+
+ /* Set defaults */
+ priv->jstkOldX = -1;
+ priv->jstkOldY = -1;
+ priv->jstkOldButtons = -1;
+ priv->jstkFd = -1;
+ priv->jstkTimeout = 0;
+
+ while ((token = xf86GetToken(JstkTab)) != ENDSUBSECTION) {
+ switch(token) {
+ case DEVICENAME:
+ if (xf86GetToken(NULL) != STRING) xf86ConfigError("Option string expected");
+ dev->name = strdup(val->str);
+ break;
+
+ case PORT:
+ if (xf86GetToken(NULL) != STRING) xf86ConfigError("Option string expected");
+ priv->jstkDevice = strdup(val->str);
+ break;
+
+ case TIMEOUT:
+ if (xf86GetToken(NULL) != NUMBER) xf86ConfigError("Joystick Timeout expected");
+ priv->jstkTimeout = val->num;
+ break;
+
+ case MAXX:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Joystick MaximumXPosition expected");
+ priv->jstkMaxX = val->num;
+ break;
+
+ case MAXY:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Joystick MaximumYPosition expected");
+ priv->jstkMaxY = val->num;
+ break;
+
+ case MINX:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Joystick MinimumXPosition expected");
+ priv->jstkMinX = val->num;
+ break;
+
+ case MINY:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Joystick MinimumYPosition expected");
+ priv->jstkMinY = val->num;
+ break;
+
+ case CENTERX:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Joystick CenterX expected");
+ priv->jstkCenterX = val->num;
+ break;
+
+ case CENTERY:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Joystick CenterY expected");
+ priv->jstkCenterY = val->num;
+ break;
+
+ case DELTA:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Joystick Delta expected");
+ priv->jstkDelta = val->num;
+ break;
+
+ case DEBUG_LEVEL:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ debug_level = val->num;
+ if (xf86Verbose) {
+#if DEBUG
+ ErrorF("%s Joystick debug level sets to %d\n", XCONFIG_GIVEN,
+ debug_level);
+#else
+ ErrorF("%s Joystick debug level not sets to %d because debugging is not compiled\n",
+ XCONFIG_GIVEN, debug_level);
+#endif
+ }
+ break;
+
+ case HISTORY_SIZE:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ dev->history_size = val->num;
+ if (xf86Verbose)
+ ErrorF("%s Joystick Motion history size is %d\n", XCONFIG_GIVEN,
+ dev->history_size);
+ break;
+
+ case ALWAYS_CORE:
+ xf86AlwaysCore(dev, TRUE);
+ if (xf86Verbose)
+ ErrorF("%s Joystick device always stays core pointer\n",
+ XCONFIG_GIVEN);
+ break;
+
+ case EOF:
+ FatalError("Unexpected EOF (missing EndSubSection)");
+ break; /* :-) */
+
+ default:
+ xf86ConfigError("Joystick subsection keyword expected");
+ break;
+ }
+ }
+
+ DBG(1, ErrorF("xf86JstkConfig timeout=%d name=%s maxx=%d maxy=%d minx=%d miny=%d "
+ "centerx=%d centery=%d delta=%d\n",
+ priv->jstkTimeout, priv->jstkDevice, priv->jstkMaxX, priv->jstkMaxY,
+ priv->jstkMinX, priv->jstkMinY, priv->jstkCenterX, priv->jstkCenterY,
+ priv->jstkDelta));
+
+ if (xf86Verbose) {
+ ErrorF("%s %s: timeout=%d port=%s maxx=%d maxy=%d minx=%d miny=%d\n"
+ "\tcenterx=%d centery=%d delta=%d\n", XCONFIG_GIVEN, dev->name,
+ priv->jstkTimeout, priv->jstkDevice, priv->jstkMaxX, priv->jstkMaxY,
+ priv->jstkMinX, priv->jstkMinY, priv->jstkCenterX, priv->jstkCenterY,
+ priv->jstkDelta);
+ }
+ return Success;
+}
+#endif
+
+/*
+ ***************************************************************************
+ *
+ * xf86JstkConvert --
+ * Convert valuators to X and Y.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86JstkConvert(LocalDevicePtr local,
+ int first,
+ int num,
+ int v0,
+ int v1,
+ int v2,
+ int v3,
+ int v4,
+ int v5,
+ int* x,
+ int* y)
+{
+ if (first != 0 || num != 2)
+ return FALSE;
+
+ *x = v0;
+ *y = v1;
+
+ return TRUE;
+}
+
+/*
+ * xf86JstkEvents --
+ * Read the new events from the device, and enqueue them.
+ */
+static CARD32
+xf86JstkEvents(OsTimerPtr timer,
+ CARD32 atime,
+ pointer arg)
+{
+ DeviceIntPtr device = (DeviceIntPtr)arg;
+ JoystickDevPtr priv = (JoystickDevPtr) PRIVATE(device);
+ int timeout = priv->jstkTimeout;
+ int x, y, buttons;
+
+ DBG(5, ErrorF("xf86JstkEvents BEGIN device=0x%x priv=0x%x"
+ " timeout=%d timer=0x%x\n",
+ device, priv, timeout, priv->jstkTimer));
+
+ if (xf86JoystickGetState(priv->jstkFd, &x, &y, &buttons)) {
+ int loop;
+ int length = priv->jstkMaxX - priv->jstkMinX;
+ int height = priv->jstkMaxY - priv->jstkMinY;
+ int v0 = ((x - priv->jstkMinX) * priv->jstkDelta) / length -
+ (priv->jstkDelta / 2);
+ int v1 = ((y - priv->jstkMinY) * priv->jstkDelta) / height -
+ (priv->jstkDelta / 2);
+
+ DBG(4, ErrorF("xf86JoystickGetState x=%d y=%d centerX=%d centerY=%d v0=%d "
+ "v1=%d buttons=%d\n",
+ x, y, priv->jstkCenterX, priv->jstkCenterY,
+ v0, v1, buttons));
+
+ if ((abs(v0) > (priv->jstkDelta / 20)) ||
+ (abs(v1) > (priv->jstkDelta / 20)))
+ {
+ xf86PostMotionEvent(device, 0, 0, 2, v0, v1);
+
+ priv->jstkOldX = x;
+ priv->jstkOldY = y;
+ }
+ for(loop=1; loop<3; loop++)
+ {
+ if ((priv->jstkOldButtons & loop) != (buttons & loop))
+ {
+ xf86PostButtonEvent(device, 0, loop, ((buttons & loop) == loop),
+ 0, 2, v0, v1);
+ }
+ }
+ priv->jstkOldButtons = buttons;
+ }
+
+ DBG(3, ErrorF("xf86JstkEvents END device=0x%x priv=0x%x"
+ " timeout=%d timer=0x%x\n",
+ device, priv, timeout, priv->jstkTimer));
+
+ return timeout;
+}
+
+static void
+xf86JstkControlProc(DeviceIntPtr device,
+ PtrCtrl *ctrl)
+{
+ DBG(2, ErrorF("xf86JstkControlProc\n"));
+}
+
+/*
+ * xf86JstkProc --
+ * Handle the initialization, etc. of a joystick
+ */
+static int
+xf86JstkProc(DeviceIntPtr pJstk,
+ int what)
+{
+ CARD8 map[5];
+ int nbaxes;
+ int nbbuttons;
+ int jstkfd;
+ LocalDevicePtr local = (LocalDevicePtr)pJstk->public.devicePrivate;
+ JoystickDevPtr priv = (JoystickDevPtr)PRIVATE(pJstk);
+
+ DBG(2, ErrorF("BEGIN xf86JstkProc dev=0x%x priv=0x%x xf86JstkEvents=0x%x\n",
+ pJstk, priv, xf86JstkEvents));
+
+ switch (what)
+ {
+ case DEVICE_INIT:
+ DBG(1, ErrorF("xf86JstkProc pJstk=0x%x what=INIT\n", pJstk));
+
+ map[1] = 1;
+ map[2] = 2;
+
+ nbaxes = 2;
+ nbbuttons = 2;
+
+ if (InitButtonClassDeviceStruct(pJstk,
+ nbbuttons,
+ map) == FALSE)
+ {
+ ErrorF("unable to allocate Button class device\n");
+ return !Success;
+ }
+
+ if (InitFocusClassDeviceStruct(pJstk) == FALSE)
+ {
+ ErrorF("unable to init Focus class device\n");
+ return !Success;
+ }
+
+ if (InitPtrFeedbackClassDeviceStruct(pJstk,
+ xf86JstkControlProc) == FALSE)
+ {
+ ErrorF("unable to init ptr feedback\n");
+ return !Success;
+ }
+
+ if (InitValuatorClassDeviceStruct(pJstk,
+ nbaxes,
+ xf86GetMotionEvents,
+ local->history_size,
+ Relative) /* relatif ou absolute */
+ == FALSE)
+ {
+ ErrorF("unable to allocate Valuator class device\n");
+ return !Success;
+ }
+ else
+ {
+ InitValuatorAxisStruct(pJstk,
+ 0,
+ 0, /* min val */
+ screenInfo.screens[0]->width, /* max val */
+ 1, /* resolution */
+ 0, /* min_res */
+ 1); /* max_res */
+ InitValuatorAxisStruct(pJstk,
+ 1,
+ 0, /* min val */
+ screenInfo.screens[0]->height, /* max val */
+ 1, /* resolution */
+ 0, /* min_res */
+ 1); /* max_res */
+
+ /* allocate the motion history buffer if needed */
+ xf86MotionHistoryAllocate(local);
+
+ xf86JoystickInit();
+#ifndef XFREE86_V4
+ AssignTypeAndName(pJstk, local->atom, local->name);
+#endif
+ }
+
+ break;
+
+ case DEVICE_ON:
+ priv->jstkFd = jstkfd = xf86JoystickOn(priv->jstkDevice,
+ &(priv->jstkTimeout),
+ &(priv->jstkCenterX),
+ &(priv->jstkCenterY));
+
+ DBG(1, ErrorF("xf86JstkProc pJstk=0x%x what=ON name=%s\n", pJstk,
+ priv->jstkDevice));
+
+ if (jstkfd != -1)
+ {
+ priv->jstkTimer = TimerSet(NULL, 0, /*TimerAbsolute,*/
+ priv->jstkTimeout,
+ xf86JstkEvents,
+ (pointer)pJstk);
+ pJstk->public.on = TRUE;
+ DBG(2, ErrorF("priv->jstkTimer=0x%x\n", priv->jstkTimer));
+ }
+ else
+ return !Success;
+ break;
+
+ case DEVICE_OFF:
+ case DEVICE_CLOSE:
+ DBG(1, ErrorF("xf86JstkProc pJstk=0x%x what=%s\n", pJstk,
+ (what == DEVICE_CLOSE) ? "CLOSE" : "OFF"));
+
+ jstkfd = xf86JoystickOff(&(priv->jstkFd), (what == DEVICE_CLOSE));
+ pJstk->public.on = FALSE;
+ break;
+
+ default:
+ ErrorF("unsupported mode=%d\n", what);
+ return !Success;
+ break;
+ }
+ DBG(2, ErrorF("END xf86JstkProc dev=0x%x priv=0x%x xf86JstkEvents=0x%x\n",
+ pJstk, priv, xf86JstkEvents));
+ return Success;
+}
+
+/*
+ * xf86JstkAllocate --
+ * Allocate Joystick device structures.
+ */
+static LocalDevicePtr
+xf86JstkAllocate(void)
+{
+ LocalDevicePtr local = xalloc(sizeof(LocalDeviceRec));
+ JoystickDevPtr priv = xalloc(sizeof(JoystickDevRec));
+
+ local->name = "JOYSTICK";
+ local->flags = 0;
+#ifndef XFREE86_V4
+ local->device_config = xf86JstkConfig;
+#endif
+ local->device_control = xf86JstkProc;
+ local->read_input = NULL;
+ local->close_proc = NULL;
+ local->control_proc = NULL;
+ local->switch_mode = NULL;
+ local->conversion_proc = xf86JstkConvert;
+ local->fd = -1;
+ local->atom = 0;
+ local->dev = NULL;
+ local->private = priv;
+ local->type_name = "Joystick";
+ local->history_size = 0;
+
+ priv->jstkFd = -1;
+ priv->jstkTimer = NULL;
+ priv->jstkTimeout = 0;
+ priv->jstkDevice = NULL;
+ priv->jstkOldX = -1;
+ priv->jstkOldY = -1;
+ priv->jstkOldButtons = -1;
+ priv->jstkMaxX = 1000;
+ priv->jstkMaxY = 1000;
+ priv->jstkMinX = 0;
+ priv->jstkMinY = 0;
+ priv->jstkCenterX = -1;
+ priv->jstkCenterY = -1;
+ priv->jstkDelta = 100;
+
+ return local;
+}
+
+/*
+ * joystick association
+ */
+DeviceAssocRec joystick_assoc =
+{
+ "joystick", /* config_section_name */
+ xf86JstkAllocate /* device_allocate */
+};
+
+#ifndef XFREE86_V4
+
+#ifdef DYNAMIC_MODULE
+/*
+ * entry point of dynamic loading
+ */
+int
+#ifndef DLSYM_BUG
+init_module(unsigned long server_version)
+#else
+init_xf86Jstk(unsigned long server_version)
+#endif
+{
+ xf86AddDeviceAssoc(&joystick_assoc);
+
+ if (server_version != XF86_VERSION_CURRENT) {
+ ErrorF("Warning: Joystick module compiled for version%s\n", XF86_VERSION);
+ return 0;
+ } else {
+ return 1;
+ }
+}
+#endif
+
+#else /* ! XFREE86_V4 */
+
+/*
+ ***************************************************************************
+ *
+ * Dynamic loading functions
+ *
+ ***************************************************************************
+ */
+#ifdef XFree86LOADER
+
+/*
+ * xf86JstckUnplug --
+ *
+ * called when the module subsection is found in XF86Config
+ */
+static void
+xf86JstkUnplug(pointer p)
+{
+ LocalDevicePtr local = (LocalDevicePtr) p;
+ JoystickDevPtr priv = (JoystickDevPtr) local->private;
+
+ ErrorF("xf86JstckUnplug\n");
+
+ xf86JstkProc(local->dev, DEVICE_OFF);
+
+ xf86RemoveLocalDevice(local);
+
+ xfree (priv);
+ xfree (local);
+}
+
+/*
+ * xf86JstckPlug --
+ *
+ * called when the module subsection is found in XF86Config
+ */
+static pointer
+xf86JstkPlug(pointer module,
+ pointer options,
+ int *errmaj,
+ int *errmin )
+{
+ LocalDevicePtr local = NULL;
+ JoystickDevPtr priv = NULL;
+ char *s;
+
+ local = xf86JstkAllocate();
+
+ if (!local || !priv) {
+ *errmaj = LDR_NOMEM;
+ goto SetupProc_fail;
+ }
+
+ priv = (JoystickDevPtr) local->private;
+
+ /* Joytsick device is mandatory */
+ priv->jstkDevice = xf86FindOptionValue(options, "Device");
+
+ if (!priv->jstkDevice) {
+ xf86Msg (X_ERROR, "WACOM: No Device specified.\n");
+ *errmaj = LDR_BADUSAGE;
+ goto SetupProc_fail;
+ }
+
+ /* Optional configuration */
+
+ s = xf86SetStrOption(options, "DeviceName", NULL);
+ if (s != NULL)
+ local->name = s;
+
+ xf86Msg(X_CONFIG, "%s name is %s\n", local->type_name, local->name);
+ xf86Msg(X_CONFIG, "JOYSTICK device is %s\n", priv->jstkDevice);
+
+ debug_level = xf86SetIntOption(options, "DebugLevel", 0);
+ if (debug_level > 0) {
+ xf86Msg(X_CONFIG, "JOYSTICK: debug level set to %d\n", debug_level);
+ }
+
+ priv->jstkMaxX = xf86SetIntOption(options, "MaxX", 1000);
+ if (priv->jstkMaxX != 1000) {
+ xf86Msg(X_CONFIG, "JOYSTICK: max x = %d\n", priv->jstkMaxX);
+ }
+ priv->jstkMaxY = xf86SetIntOption(options, "MaxY", 1000);
+ if (priv->jstkMaxY != 1000) {
+ xf86Msg(X_CONFIG, "JOYSTICK: max y = %d\n", priv->jstkMaxY);
+ }
+ priv->jstkMinX = xf86SetIntOption(options, "MinX", 0);
+ if (priv->jstkMinX != 0) {
+ xf86Msg(X_CONFIG, "JOYSTICK: min x = %d\n", priv->jstkMinX);
+ }
+ priv->jstkMinY = xf86SetIntOption(options, "MinY", 0);
+ if (priv->jstkMinY != 0) {
+ xf86Msg(X_CONFIG, "JOYSTICK: min y = %d\n", priv->jstkMinY);
+ }
+
+ priv->jstkCenterX = xf86SetIntOption(options, "CenterX", -1);
+ if (priv->jstkCenterX != -1) {
+ xf86Msg(X_CONFIG, "JOYSTICK: center x = %d\n", priv->jstkCenterX);
+ }
+ priv->jstkCenterY = xf86SetIntOption(options, "CenterY", -1);
+ if (priv->jstkCenterY != 0) {
+ xf86Msg(X_CONFIG, "JOYSTICK: center y = %d\n", priv->jstkCenterY);
+ }
+
+ priv->jstkTimeout = xf86SetIntOption(options, "Timeout", -1);
+ if (priv->jstkTimeout != -1) {
+ xf86Msg(X_CONFIG, "JOYSTICK: timeout = %d\n", priv->jstkTimeout);
+ }
+
+ priv->jstkDelta = xf86SetIntOption(options, "Delta", 0);
+ if (priv->jstkDelta != 0) {
+ xf86Msg(X_CONFIG, "JOYSTICK: delta = %d\n", priv->jstkDelta);
+ }
+
+ /* Register the device into XFree86 XInput layer */
+ xf86AddLocalDevice(local, options);
+
+ /* return the LocalDevice */
+ return (local);
+
+ SetupProc_fail:
+ if (priv)
+ xfree(priv);
+ if (local)
+ xfree(local);
+ return NULL;
+}
+
+static XF86ModuleVersionInfo xf86JstkVersionRec =
+{
+ "joystick",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_XINPUT,
+ ABI_XINPUT_VERSION,
+ MOD_CLASS_XINPUT,
+ {0, 0, 0, 0} /* signature, to be patched into the file by */
+ /* a tool */
+};
+
+XF86ModuleData joystickModuleData = {&xf86JstkVersionRec,
+ xf86JstkPlug,
+ xf86JstkUnplug};
+#endif /* XFree86LOADER */
+
+#endif /* ! XFREE86_V4 */
+
+
+/* end of xf86Jstk.c */
diff --git a/xc/programs/Xserver/hw/xfree86/input/magellan/Imakefile b/xc/programs/Xserver/hw/xfree86/input/magellan/Imakefile
new file mode 100644
index 000000000..bbb95a877
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/magellan/Imakefile
@@ -0,0 +1,26 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/magellan/Imakefile,v 1.4 1999/08/14 10:50:01 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = magellan.c
+OBJS = magellan.o
+
+DRIVER = magellan
+
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86SRC)/loader -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget($(DRIVER),$(OBJS))
+
+InstallObjectModule($(DRIVER),$(MODULEDIR),input)
+
+DependTarget()
+
+InstallDriverSDKObjectModule($(DRIVER),$(DRIVERSDKMODULEDIR),input)
diff --git a/xc/programs/Xserver/hw/xfree86/input/magellan/magellan.c b/xc/programs/Xserver/hw/xfree86/input/magellan/magellan.c
new file mode 100644
index 000000000..bc89ae065
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/magellan/magellan.c
@@ -0,0 +1,543 @@
+/*
+ * Copyright (c) 1998 Metro Link Incorporated
+ *
+ * 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, cpy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/magellan/magellan.c,v 1.9 1999/06/05 15:55:25 dawes Exp $ */
+
+#define _MAGELLAN_C_
+/*****************************************************************************
+ * Standard Headers
+ ****************************************************************************/
+
+#include <misc.h>
+#include <xf86.h>
+#define NEED_XF86_TYPES
+#include <xf86_ansic.h>
+#include <xf86_OSproc.h>
+#include <xf86Xinput.h>
+#include <xisb.h>
+#include <exevents.h> /* Needed for InitValuator/Proximity stuff */
+
+/*****************************************************************************
+ * Local Headers
+ ****************************************************************************/
+#include "magellan.h"
+
+/*****************************************************************************
+ * Variables without includable headers
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Local Variables
+ ****************************************************************************/
+static XF86ModuleVersionInfo VersionRec =
+{
+ "magellan",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_XINPUT,
+ ABI_XINPUT_VERSION,
+ MOD_CLASS_XINPUT,
+ {0, 0, 0, 0} /* signature, to be patched into the file by
+ * a tool */
+};
+
+/*
+ * Be sure to set vmin appropriately for your device's protocol. You want to
+ * read a full packet before returning
+ */
+static const char *default_options[] =
+{
+ "BaudRate", "9600",
+ "StopBits", "2",
+ "DataBits", "8",
+ "Parity", "None",
+ "Vmin", "26",
+ "Vtime", "1",
+ "FlowControl", "None"
+};
+
+XF86ModuleData magellanModuleData = { &VersionRec, SetupProc, TearDownProc };
+
+/*****************************************************************************
+ * Function Definitions
+ ****************************************************************************/
+
+
+/*
+ * The TearDownProc may have to be tailored to your device
+ */
+static void
+TearDownProc( pointer p )
+{
+ LocalDevicePtr local = (LocalDevicePtr) p;
+ MagellanPrivatePtr priv = (MagellanPrivatePtr) local->private;
+
+ DeviceOff (local->dev);
+
+ xf86RemoveLocalDevice (local);
+
+ xf86CloseSerial (local->fd);
+ XisbFree (priv->buffer);
+ xfree (priv);
+ xfree (local->name);
+ xfree (local);
+}
+
+static pointer
+SetupProc( pointer module,
+ pointer options,
+ int *errmaj,
+ int *errmin )
+{
+ LocalDevicePtr local = xcalloc (1, sizeof (LocalDeviceRec));
+ MagellanPrivatePtr priv = xcalloc (1, sizeof (MagellanPrivateRec));
+ pointer defaults,
+ merged;
+
+ if ((!local) || (!priv))
+ goto SetupProc_fail;
+
+ defaults = xf86OptionListCreate (default_options,
+ (sizeof (default_options) / sizeof (default_options[0])), 0);
+ merged = xf86OptionListMerge( defaults, options );
+
+ xf86OptionListReport( merged );
+
+ local->fd = xf86OpenSerial (merged);
+ if (local->fd == -1)
+ {
+ ErrorF ("Magellan driver unable to open device\n");
+ *errmaj = LDR_NOPORTOPEN;
+ *errmin = xf86GetErrno ();
+ goto SetupProc_fail;
+ }
+
+ priv->buffer = XisbNew (local->fd, 200);
+
+ DBG (9, XisbTrace (priv->buffer, 1));
+
+ /*
+ * Verify that hardware is attached and fuctional
+ */
+ if (QueryHardware (priv, errmaj, errmin) != Success)
+ {
+ ErrorF ("Unable to query/initialize Magellan hardware.\n");
+ goto SetupProc_fail;
+ }
+
+ /* this results in an xstrdup that must be freed later */
+ local->name = xf86SetStrOption( merged, "DeviceName", "Magellan Space Mouse" );
+
+ local->type_name = XI_SPACEBALL;
+ /*
+ * Standard setup for the local device record
+ */
+ local->device_control = DeviceControl;
+ local->read_input = ReadInput;
+ local->control_proc = ControlProc;
+ local->close_proc = CloseProc;
+ local->switch_mode = SwitchMode;
+ local->conversion_proc = ConvertProc;
+ local->dev = NULL;
+ local->private = priv;
+ local->private_flags = 0;
+ local->history_size = xf86SetIntOption( merged, "HistorySize", 0);
+
+ xf86AddLocalDevice (local, merged);
+
+ /* return the LocalDevice */
+ return (local);
+
+ /*
+ * If something went wrong, cleanup and return NULL
+ */
+ SetupProc_fail:
+ if ((local) && (local->fd))
+ xf86CloseSerial (local->fd);
+ if ((local) && (local->name))
+ xfree (local->name);
+ if (local)
+ xfree (local);
+
+ if ((priv) && (priv->buffer))
+ XisbFree (priv->buffer);
+ if (priv)
+ xfree (priv);
+ return (NULL);
+}
+
+static Bool
+DeviceControl (DeviceIntPtr dev, int mode)
+{
+ Bool RetValue;
+
+ switch (mode)
+ {
+ case DEVICE_INIT:
+ DeviceInit (dev);
+ RetValue = Success;
+ break;
+ case DEVICE_ON:
+ RetValue = DeviceOn( dev );
+ break;
+ case DEVICE_OFF:
+ RetValue = DeviceOff( dev );
+ break;
+ case DEVICE_CLOSE:
+ RetValue = DeviceClose( dev );
+ break;
+ default:
+ RetValue = BadValue;
+ }
+
+ return( RetValue );
+}
+
+static Bool
+DeviceOn (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+
+ AddEnabledDevice (local->fd);
+ dev->public.on = TRUE;
+ return (Success);
+}
+
+static Bool
+DeviceOff (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+
+ RemoveEnabledDevice (local->fd);
+ dev->public.on = FALSE;
+ return (Success);
+}
+
+static Bool
+DeviceClose (DeviceIntPtr dev)
+{
+ return (Success);
+}
+
+static Bool
+DeviceInit (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ unsigned char map[] =
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ int i;
+
+ if (InitButtonClassDeviceStruct (dev, 9, map) == FALSE)
+ {
+ ErrorF ("Unable to allocate Magellan ButtonClassDeviceStruct\n");
+ return !Success;
+ }
+
+ if (InitFocusClassDeviceStruct (dev) == FALSE)
+ {
+ ErrorF("Unable to allocate Magellan FocusClassDeviceStruct\n");
+ return !Success;
+ }
+
+ if (InitValuatorClassDeviceStruct (dev, 6, xf86GetMotionEvents,
+ local->history_size, Absolute) == FALSE)
+ {
+ ErrorF ("Unable to allocate Magellan ValuatorClassDeviceStruct\n");
+ return !Success;
+ }
+ else
+ {
+ for (i = 0; i <= 6; i++)
+ {
+ InitValuatorAxisStruct(dev, i, MAGELLAN_MIN, MAGELLAN_MAX,
+ MAGELLAN_RES, 0, MAGELLAN_RES);
+ }
+ }
+
+#ifdef BELL_FEEDBACK_SUPPORT
+ /*
+ The InitBellFeedbackClassDeviceStruct function is not exported in the
+ 4.3.0 or 4.3.1 Xmetro loader. We'll leave this out to stay compatible
+ */
+
+ if (InitBellFeedbackClassDeviceStruct (dev, MagellanBellSound,
+ MagellanBellCtrl) == FALSE)
+ {
+ ErrorF ("Unable to allocate Magellan BellFeedbackClassDeviceStruct\n");
+ return !Success;
+ }
+#endif
+
+ /*
+ * Allocate the motion events buffer.
+ */
+ xf86MotionHistoryAllocate (local);
+ return (Success);
+}
+
+static void
+ReadInput (LocalDevicePtr local)
+{
+ int x, y, z;
+ int a, b, c;
+ int i, buttons;
+ MagellanPrivatePtr priv = (MagellanPrivatePtr) (local->private);
+
+ /*
+ * set blocking to -1 on the first call because we know there is data to
+ * read. Xisb automatically clears it after one successful read so that
+ * succeeding reads are preceeded buy a select with a 0 timeout to prevent
+ * read from blocking indefinately.
+ */
+ XisbBlockDuration (priv->buffer, -1);
+ while (MagellanGetPacket (priv) == Success)
+ {
+ /*
+ * Examine priv->packet and call these functions as appropriate:
+ *
+ xf86PostMotionEvent
+ xf86PostButtonEvent
+ */
+
+ switch (priv->packet[0])
+ {
+ case 'd': /* motion packet */
+ if (strlen (priv->packet) == 26)
+ {
+ x =
+ MagellanNibble( priv->packet[1] ) * 4096 +
+ MagellanNibble( priv->packet[2] ) * 256 +
+ MagellanNibble( priv->packet[3] ) * 16 +
+ MagellanNibble( priv->packet[4] ) - 32768;
+ y =
+ MagellanNibble( priv->packet[5] ) * 4096 +
+ MagellanNibble( priv->packet[6] ) * 256 +
+ MagellanNibble( priv->packet[7] ) * 16 +
+ MagellanNibble( priv->packet[8] ) - 32768;
+ z =
+ MagellanNibble( priv->packet[9] ) * 4096 +
+ MagellanNibble( priv->packet[10] ) * 256 +
+ MagellanNibble( priv->packet[11] ) * 16 +
+ MagellanNibble( priv->packet[12] ) - 32768;
+
+ a =
+ MagellanNibble( priv->packet[13] ) * 4096 +
+ MagellanNibble( priv->packet[14] ) * 256 +
+ MagellanNibble( priv->packet[15] ) * 16 +
+ MagellanNibble( priv->packet[16] ) - 32768;
+ b =
+ MagellanNibble( priv->packet[17] ) * 4096 +
+ MagellanNibble( priv->packet[18] ) * 256 +
+ MagellanNibble( priv->packet[19] ) * 16 +
+ MagellanNibble( priv->packet[20] ) - 32768;
+ c =
+ MagellanNibble( priv->packet[21] ) * 4096 +
+ MagellanNibble( priv->packet[22] ) * 256 +
+ MagellanNibble( priv->packet[23] ) * 16 +
+ MagellanNibble( priv->packet[24] ) - 32768;
+
+ xf86ErrorFVerb( 5, "Magellan motion %d %d %d -- %d %d %d\n",
+ x, y, z, a, b, c );
+ xf86PostMotionEvent(local->dev, TRUE, 0, 6,
+ x, y, z, a, b, c);
+ }
+ else
+ ErrorF ("Magellan recieved a short \'d\'packet\n");
+ break;
+
+ case 'k': /* button packet */
+ if (strlen (priv->packet) == 5)
+ {
+ buttons = MagellanNibble( priv->packet[1] ) * 1 +
+ MagellanNibble( priv->packet[2] ) * 16 +
+ MagellanNibble( priv->packet[3] ) * 256;
+ if (priv->old_buttons != buttons)
+ for (i = 0; i < 9; i++)
+ {
+ if ((priv->old_buttons&(1<<i)) != (buttons&(1<<i)))
+ {
+ xf86PostButtonEvent(local->dev, FALSE, i+1,
+ (buttons&(1<<i)), 0, 0);
+ xf86ErrorFVerb( 5, "Magellan setting button %d to %d\n",
+ i+1, (buttons&(1<<i)) );
+ }
+ }
+ priv->old_buttons = buttons;
+ }
+ else
+ ErrorF ("Magellan recieved a short \'k\'packet\n");
+ break;
+ }
+ }
+}
+
+static int
+ControlProc (LocalDevicePtr local, xDeviceCtl * control)
+{
+ return (Success);
+}
+
+#ifdef BELL_FEEDBACK_SUPPORT
+/*
+The bell functions are stubbed out for now because they can't be used with the
+4.3.0 and 4.3.1 Xmetro binaries. The device can only control the duration of
+the beep.
+*/
+static void
+MagellanBellCtrl(DeviceIntPtr dev, BellCtrl *ctrl)
+{
+}
+
+static void
+MagellanBellSound(int percent, DeviceIntPtr dev, pointer ctrl, int unknown)
+{
+}
+#endif
+
+static void
+CloseProc (LocalDevicePtr local)
+{
+}
+
+static int
+SwitchMode (ClientPtr client, DeviceIntPtr dev, int mode)
+{
+ return (Success);
+}
+
+/*
+ * The ConvertProc function may need to be tailored for your device.
+ * This function converts the device's valuator outputs to x and y coordinates
+ * to simulate mouse events.
+ */
+static Bool
+ConvertProc (LocalDevicePtr local,
+ int first,
+ int num,
+ int v0,
+ int v1,
+ int v2,
+ int v3,
+ int v4,
+ int v5,
+ int *x,
+ int *y)
+{
+
+ *x = v3;
+ *y = v4;
+ return (Success);
+}
+
+#define WriteString(str)\
+XisbWrite (priv->buffer, (unsigned char *)(str), strlen(str)); \
+ XisbBlockDuration (priv->buffer, 1000000); \
+ if ((MagellanGetPacket (priv) != Success) || \
+ (strcmp (priv->packet, (str)) != 0)) \
+ return (!Success);
+
+
+static Bool
+QueryHardware (MagellanPrivatePtr priv, int *errmaj, int *errmin)
+{
+ *errmaj = LDR_NOHARDWARE;
+
+ /* the device resets when the port is opened. Give it time to finish */
+ milisleep (1000);
+
+ XisbWrite (priv->buffer, (unsigned char *)MagellanAttention, strlen(MagellanAttention));
+ WriteString (MagellanInitString);
+ WriteString (MagellanInitString);
+ WriteString (MagellanSensitivity);
+ WriteString (MagellanPeriod);
+ WriteString (MagellanMode);
+ WriteString (MagellanNullRadius);
+
+ XisbWrite (priv->buffer, (unsigned char *)MagellanVersion, strlen(MagellanVersion));
+ /* block for up to 1 second while trying to read the response */
+ XisbBlockDuration (priv->buffer, 1000000);
+ NewPacket (priv);
+
+ if ((MagellanGetPacket (priv) == Success) && (priv->packet[0] == 'v'))
+ {
+ priv->packet[strlen(priv->packet) - 1] = '\0';
+ xf86MsgVerb( X_PROBED, 3, " initialized: %s\n", &(priv->packet[3]) );
+ }
+ else
+ return (!Success);
+
+ return (Success);
+}
+
+static void
+NewPacket (MagellanPrivatePtr priv)
+{
+ priv->lex_mode = magellan_normal;
+ priv->packeti = 0;
+}
+
+static Bool
+MagellanGetPacket (MagellanPrivatePtr priv)
+{
+ int count = 0;
+ int c;
+
+ while ((c = XisbRead (priv->buffer)) >= 0)
+ {
+ /*
+ * fail after 500 bytes so the server doesn't hang forever if a
+ * device sends bad data.
+ */
+ if (count++ > 500)
+ {
+ NewPacket (priv);
+ return (!Success);
+ }
+
+ switch (priv->lex_mode)
+ {
+ case magellan_normal:
+ if (priv->packeti > MAGELLAN_PACKET_SIZE)
+ {
+ NewPacket (priv);
+ return (!Success);
+ }
+ priv->packet[priv->packeti] = c;
+ priv->packeti++;
+ if (c == '\r')
+ {
+ priv->packet[priv->packeti] = '\0';
+ NewPacket (priv);
+ return (Success);
+ }
+ break;
+ }
+ }
+ return (!Success);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/input/magellan/magellan.h b/xc/programs/Xserver/hw/xfree86/input/magellan/magellan.h
new file mode 100644
index 000000000..e16c19295
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/magellan/magellan.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1998 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/magellan/magellan.h,v 1.3 1999/05/15 12:10:30 dawes Exp $ */
+
+#ifndef _MAGELLAN_H_
+#define _MAGELLAN_H_
+
+/******************************************************************************
+ * Definitions
+ * structs, typedefs, #defines, enums
+ *****************************************************************************/
+#define MAGELLAN_PACKET_SIZE 256
+#define MAGELLAN_RES 200
+/*
+These numbers are difficult to pick because the user can change a
+multiplier using the buttons which changes the output range. However, many
+programs use this range to perform operations of their own and the XInput
+extension expects these to be constant for a given device. Hence, I've picked
+values that are slightly higher than any reported by my test device in default
+(no multiplier) mode. The documentation says the range is roughly +/- 400 but
+I have seen numbers close to 500. Some programs (GLUT) get upset if the device
+reports a value greater than XInput reported it could.
+*/
+#define MAGELLAN_MIN -500
+#define MAGELLAN_MAX +500
+
+#define MagellanAttention "\r\r" /* get device's attention */
+#define MagellanInitString "z\r" /* switch in 3D mode */
+#define MagellanShortBeep "b9\r" /* a short beep */
+#define MagellanMode "m3\r" /* translation and rotation data ON */
+#define MagellanPeriod "pAA\r" /* transmit every 60 ms data */
+#define MagellanNullRadius "nH\r" /* null radius to value 8 */
+#define MagellanZero "z\r" /* detect zero position */
+#define MagellanSensitivity "q00\r" /* no extra sensitivity */
+#define MagellanVersion "vQ\r" /* get version string */
+
+
+typedef enum
+{
+ magellan_normal
+}
+MagellanState;
+
+#define MagellanNibble(Value) (Value&0x0F)
+
+#define milisleep(ms) xf86usleep (ms * 1000)
+
+typedef struct _MagellanPrivateRec
+{
+ XISBuffer *buffer;
+ unsigned char packet_type;
+ char packet[MAGELLAN_PACKET_SIZE]; /* packet being/just read */
+ int packeti; /* index into packet */
+ int old_buttons;
+ MagellanState lex_mode;
+}
+MagellanPrivateRec, *MagellanPrivatePtr;
+
+/******************************************************************************
+ * Declarations
+ *****************************************************************************/
+static MODULESETUPPROTO( SetupProc );
+static void TearDownProc (void *);
+static Bool DeviceControl (DeviceIntPtr, int);
+static Bool DeviceOn (DeviceIntPtr);
+static Bool DeviceOff (DeviceIntPtr);
+static Bool DeviceClose (DeviceIntPtr);
+static Bool DeviceInit (DeviceIntPtr);
+static void ReadInput (LocalDevicePtr);
+static int ControlProc (LocalDevicePtr, xDeviceCtl *);
+static void CloseProc (LocalDevicePtr);
+static int SwitchMode (ClientPtr, DeviceIntPtr, int);
+static Bool ConvertProc (LocalDevicePtr, int, int, int, int, int, int, int, int, int *, int *);
+static Bool QueryHardware (MagellanPrivatePtr, int *, int *);
+static void NewPacket (MagellanPrivatePtr priv);
+static Bool MagellanGetPacket (MagellanPrivatePtr priv);
+#ifdef BELL_FEEDBACK_SUPPORT
+static void MagellanBellCtrl( DeviceIntPtr, BellCtrl *);
+static void MagellanBellSound(int percent, DeviceIntPtr dev, pointer ctrl, int
+unknown);
+#endif
+/*
+ * DO NOT PUT ANYTHING AFTER THIS ENDIF
+ */
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/input/microtouch/Imakefile b/xc/programs/Xserver/hw/xfree86/input/microtouch/Imakefile
new file mode 100644
index 000000000..66e66c6ae
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/microtouch/Imakefile
@@ -0,0 +1,26 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/microtouch/Imakefile,v 1.4 1999/08/14 10:50:01 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = microtouch.c
+OBJS = microtouch.o
+
+DRIVER = microtouch
+
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86SRC)/loader -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget($(DRIVER),$(OBJS))
+
+InstallObjectModule($(DRIVER),$(MODULEDIR),input)
+
+DependTarget()
+
+InstallDriverSDKObjectModule($(DRIVER),$(DRIVERSDKMODULEDIR),input)
diff --git a/xc/programs/Xserver/hw/xfree86/input/microtouch/microtouch.c b/xc/programs/Xserver/hw/xfree86/input/microtouch/microtouch.c
new file mode 100644
index 000000000..18d6a337c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/microtouch/microtouch.c
@@ -0,0 +1,984 @@
+/*
+ * Copyright (c) 1998 Metro Link Incorporated
+ *
+ * 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, cpy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/*
+ * Based, in part, on code with the following copyright notice:
+ *
+ * Copyright 1996 by Patrick Lecoanet, France. <lecoanet@cenaath.cena.dgac.fr>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Patrick Lecoanet not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Patrick Lecoanet makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * PATRICK LECOANET DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL PATRICK LECOANET BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/microtouch/microtouch.c,v 1.11 1999/08/28 10:43:36 dawes Exp $ */
+
+#define _microtouch_C_
+/*****************************************************************************
+ * Standard Headers
+ ****************************************************************************/
+
+#include <misc.h>
+#include <xf86.h>
+#define NEED_XF86_TYPES
+#include <xf86_ansic.h>
+#include <xf86_OSproc.h>
+#include <xf86Xinput.h>
+#include <xisb.h>
+#include <exevents.h> /* Needed for InitValuator/Proximity stuff */
+
+/*****************************************************************************
+ * Local Headers
+ ****************************************************************************/
+#include "microtouch.h"
+
+/*****************************************************************************
+ * Variables without includable headers
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Local Variables
+ ****************************************************************************/
+
+static InputInfoPtr
+MuTouchPreInit(InputDriverPtr drv, IDevPtr dev, int flags);
+
+
+InputDriverRec MICROTOUCH = {
+ 1,
+ "microtouch",
+ NULL,
+ MuTouchPreInit,
+ /*MuTouchUnInit*/ NULL,
+ NULL,
+ 0
+};
+
+#ifdef XFree86LOADER
+
+static XF86ModuleVersionInfo VersionRec =
+{
+ "microtouch",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_XINPUT,
+ ABI_XINPUT_VERSION,
+ MOD_CLASS_XINPUT,
+ {0, 0, 0, 0} /* signature, to be patched into the file by
+ * a tool */
+};
+
+static const char *reqSymbols[] = {
+ "AddEnabledDevice",
+ "ErrorF",
+ "InitButtonClassDeviceStruct",
+ "InitProximityClassDeviceStruct",
+ "InitValuatorAxisStruct",
+ "InitValuatorClassDeviceStruct",
+ "RemoveEnabledDevice",
+ "Xcalloc",
+ "Xfree",
+ "XisbBlockDuration",
+ "XisbFree",
+ "XisbNew",
+ "XisbRead",
+ "XisbTrace",
+ "XisbWrite",
+ "screenInfo",
+ "xf86AddInputDriver",
+ "xf86AllocateInput",
+ "xf86CloseSerial",
+ "xf86CollectInputOptions",
+ "xf86ErrorF",
+ "xf86ErrorFVerb",
+ "xf86FindOptionValue",
+ "xf86FlushInput",
+ "xf86GetMotionEvents",
+ "xf86GetVerbosity",
+ "xf86LoaderReqSymLists",
+ "xf86MotionHistoryAllocate",
+ "xf86Msg",
+ "xf86NameCmp",
+ "xf86OpenSerial",
+ "xf86OptionListCreate",
+ "xf86OptionListFree",
+ "xf86OptionListReport",
+ "xf86PostButtonEvent",
+ "xf86PostMotionEvent",
+ "xf86PostProximityEvent",
+ "xf86ProcessCommonOptions",
+ "xf86ScaleAxis",
+ "xf86SetIntOption",
+ "xf86SetSerial",
+ "xf86SetStrOption",
+ "xf86XInputSetScreen",
+ "xf86XInputSetSendCoreEvents",
+ "xf86memset",
+ "xf86sscanf",
+ "xf86strcmp",
+ "xf86strlen",
+ "xf86strncmp",
+ "xf86strncpy",
+ NULL
+};
+
+static pointer
+SetupProc( pointer module,
+ pointer options,
+ int *errmaj,
+ int *errmin )
+{
+ xf86LoaderReqSymLists(reqSymbols, NULL);
+ xf86AddInputDriver(&MICROTOUCH, module, 0);
+ return (pointer) 1;
+}
+
+XF86ModuleData microtouchModuleData = {&VersionRec, &SetupProc, NULL };
+
+#endif /* XFree86LOADER */
+
+
+static const char *default_options[] =
+{
+ "BaudRate", "9600",
+ "StopBits", "1",
+ "DataBits", "8",
+ "Parity", "None",
+ "Vmin", "5",
+ "Vtime", "1",
+ "FlowControl", "None"
+};
+static const char *fallback_options[] =
+{
+ "BaudRate", "9600",
+ "StopBits", "2",
+ "DataBits", "7",
+ "Parity", "None",
+ "Vmin", "1",
+ "Vtime", "1",
+ "FlowControl", "None"
+};
+
+
+/*****************************************************************************
+ * Function Definitions
+ ****************************************************************************/
+
+
+
+static InputInfoPtr
+MuTouchPreInit(InputDriverPtr drv, IDevPtr dev, int flags)
+{
+ LocalDevicePtr local = xf86AllocateInput(drv, 0);
+ MuTPrivatePtr priv = xcalloc (1, sizeof (MuTPrivateRec));
+
+ char *s;
+
+ if ((!local) || (!priv))
+ goto SetupProc_fail;
+
+ local->type_name = XI_TOUCHSCREEN;
+ local->device_control = DeviceControl;
+ local->read_input = ReadInput;
+ local->control_proc = ControlProc;
+ local->close_proc = CloseProc;
+ local->switch_mode = SwitchMode;
+ local->conversion_proc = ConvertProc;
+ local->dev = NULL;
+ local->private = priv;
+ local->private_flags = 0;
+ local->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
+ local->conf_idev = dev;
+
+ xf86CollectInputOptions(local, default_options, NULL);
+
+ xf86OptionListReport(local->options);
+
+ local->fd = xf86OpenSerial (local->options);
+ if (local->fd == -1)
+ {
+ ErrorF ("MicroTouch driver unable to open device\n");
+ goto SetupProc_fail;
+ }
+ xf86ErrorFVerb( 6, "tty port opened successfully\n" );
+
+ priv->min_x = xf86SetIntOption( local->options, "MinX", 0 );
+ priv->max_x = xf86SetIntOption( local->options, "MaxX", 1000 );
+ priv->min_y = xf86SetIntOption( local->options, "MinY", 0 );
+ priv->max_y = xf86SetIntOption( local->options, "MaxY", 1000 );
+ priv->screen_num = xf86SetIntOption( local->options, "ScreenNumber", 0 );
+ priv->button_number = xf86SetIntOption( local->options, "ButtonNumber", 1 );
+
+ s = xf86FindOptionValue (local->options, "ReportingMode");
+ if ((s) && (xf86NameCmp (s, "raw") == 0))
+ priv->reporting_mode = TS_Raw;
+ else
+ priv->reporting_mode = TS_Scaled;
+
+ priv->buffer = XisbNew (local->fd, 200);
+ priv->proximity = FALSE;
+ priv->button_down = FALSE;
+
+ DBG (9, XisbTrace (priv->buffer, 1));
+
+ MuTNewPacket (priv);
+ if (QueryHardware(local) != Success)
+ {
+ ErrorF ("Unable to query/initialize MicroTouch hardware.\n");
+ goto SetupProc_fail;
+ }
+
+ local->history_size = xf86SetIntOption( local->options, "HistorySize", 0 );
+
+
+ /* prepare to process touch packets */
+ MuTNewPacket (priv);
+
+ /* this results in an xstrdup that must be freed later */
+ local->name = xf86SetStrOption( local->options, "DeviceName", "MicroTouch TouchScreen" );
+ xf86ProcessCommonOptions(local, local->options);
+ local->flags |= XI86_CONFIGURED;
+
+ if (local->fd != -1)
+ {
+ RemoveEnabledDevice (local->fd);
+ if (priv->buffer)
+ {
+ XisbFree(priv->buffer);
+ priv->buffer = NULL;
+ }
+ xf86CloseSerial(local->fd);
+ }
+ RemoveEnabledDevice (local->fd);
+ local->fd = -1;
+ return (local);
+
+ SetupProc_fail:
+ if ((local) && (local->fd))
+ xf86CloseSerial (local->fd);
+ if ((local) && (local->name))
+ xfree (local->name);
+ if (local)
+ xfree (local);
+
+ if ((priv) && (priv->buffer))
+ XisbFree (priv->buffer);
+ if (priv)
+ xfree (priv);
+ return (NULL);
+}
+
+static Bool
+DeviceControl (DeviceIntPtr dev,
+ int mode)
+{
+ Bool RetValue;
+
+ switch (mode)
+ {
+ case DEVICE_INIT:
+ DeviceInit (dev);
+ RetValue = Success;
+ break;
+ case DEVICE_ON:
+ RetValue = DeviceOn( dev );
+ break;
+ case DEVICE_OFF:
+ case DEVICE_CLOSE:
+ RetValue = DeviceOff( dev );
+ break;
+ default:
+ RetValue = BadValue;
+ }
+
+ return( RetValue );
+}
+
+static Bool
+DeviceOn (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ MuTPrivatePtr priv = (MuTPrivatePtr) (local->private);
+
+ local->fd = xf86OpenSerial(local->options);
+ if (local->fd == -1)
+ {
+ xf86Msg(X_WARNING, "%s: cannot open input device\n", local->name);
+ return (!Success);
+ }
+
+ priv->buffer = XisbNew(local->fd, 64);
+ if (!priv->buffer)
+ {
+ xf86CloseSerial(local->fd);
+ local->fd = -1;
+ return (!Success);
+ }
+
+ xf86FlushInput(local->fd);
+ AddEnabledDevice (local->fd);
+ dev->public.on = TRUE;
+ return (Success);
+}
+
+static Bool
+DeviceOff (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ MuTPrivatePtr priv = (MuTPrivatePtr) (local->private);
+
+ if (local->fd != -1)
+ {
+ RemoveEnabledDevice (local->fd);
+ if (priv->buffer)
+ {
+ XisbFree(priv->buffer);
+ priv->buffer = NULL;
+}
+ xf86CloseSerial(local->fd);
+ }
+
+ RemoveEnabledDevice (local->fd);
+ dev->public.on = FALSE;
+ return (Success);
+}
+
+static Bool
+DeviceInit (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ MuTPrivatePtr priv = (MuTPrivatePtr) (local->private);
+ unsigned char map[] =
+ {0, 1};
+
+ /*
+ * these have to be here instead of in the SetupProc, because when the
+ * SetupProc is run at server startup, screenInfo is not setup yet
+ */
+ priv->screen_width = screenInfo.screens[priv->screen_num]->width;
+ priv->screen_height = screenInfo.screens[priv->screen_num]->height;
+
+ /*
+ * Device reports button press for 1 button.
+ */
+ if (InitButtonClassDeviceStruct (dev, 1, map) == FALSE)
+ {
+ ErrorF ("Unable to allocate MicroTouch touchscreen ButtonClassDeviceStruct\n");
+ return !Success;
+ }
+
+ /*
+ * Device reports motions on 2 axes in absolute coordinates.
+ * Axes min and max values are reported in raw coordinates.
+ */
+ if (InitValuatorClassDeviceStruct (dev, 2, xf86GetMotionEvents,
+ local->history_size, Absolute) == FALSE)
+ {
+ ErrorF ("Unable to allocate MicroTouch touchscreen ValuatorClassDeviceStruct\n");
+ return !Success;
+ }
+ else
+ {
+ InitValuatorAxisStruct (dev, 0, priv->min_x, priv->max_x,
+ 9500,
+ 0 /* min_res */ ,
+ 9500 /* max_res */ );
+ InitValuatorAxisStruct (dev, 1, priv->min_y, priv->max_y,
+ 10500,
+ 0 /* min_res */ ,
+ 10500 /* max_res */ );
+ }
+
+ if (InitProximityClassDeviceStruct (dev) == FALSE)
+ {
+ ErrorF ("Unable to allocate MicroTouch touchscreen ProximityClassDeviceStruct\n");
+ return !Success;
+ }
+
+ /*
+ * Allocate the motion events buffer.
+ */
+ xf86MotionHistoryAllocate (local);
+ return (Success);
+}
+
+#define WORD_ASSEMBLY(byte1, byte2) (((byte2) << 7) | (byte1))
+
+static void
+ReadInput (LocalDevicePtr local)
+{
+ int x, y;
+ int type;
+ MuTPrivatePtr priv = (MuTPrivatePtr) (local->private);
+
+ /*
+ * set blocking to -1 on the first call because we know there is data to
+ * read. Xisb automatically clears it after one successful read so that
+ * succeeding reads are preceeded buy a select with a 0 timeout to prevent
+ * read from blocking indefinately.
+ */
+ XisbBlockDuration (priv->buffer, -1);
+ while (MuTGetPacket (priv) == Success)
+ {
+ type = priv->packet[0];
+ x = WORD_ASSEMBLY (priv->packet[1], priv->packet[2]);
+ y = WORD_ASSEMBLY (priv->packet[3], priv->packet[4]);
+
+ if (priv->reporting_mode == TS_Scaled)
+ {
+ x = xf86ScaleAxis (x, 0, priv->screen_width, priv->min_x,
+ priv->max_x);
+ y = xf86ScaleAxis (y, 0, priv->screen_height, priv->min_y,
+ priv->max_y);
+ }
+
+ xf86XInputSetScreen (local, priv->screen_num, x, y);
+
+ if ((priv->proximity == FALSE) && (type & MuT_CONTACT))
+ {
+ priv->proximity = TRUE;
+ xf86PostProximityEvent (local->dev, 1, 0, 2, x, y);
+ }
+
+ /*
+ * Send events.
+ *
+ * We *must* generate a motion before a button change if pointer
+ * location has changed as DIX assumes this. This is why we always
+ * emit a motion, regardless of the kind of packet processed.
+ */
+ xf86PostMotionEvent (local->dev, TRUE, 0, 2, x, y);
+
+ /*
+ * Emit a button press or release.
+ */
+ if ((priv->button_down == FALSE) && (type & MuT_CONTACT))
+
+ {
+ xf86PostButtonEvent (local->dev, TRUE,
+ priv->button_number, 1, 0, 2, x, y);
+ priv->button_down = TRUE;
+ }
+ if ((priv->button_down == TRUE) && !(type & MuT_CONTACT))
+ {
+ xf86PostButtonEvent (local->dev, TRUE,
+ priv->button_number, 0, 0, 2, x, y);
+ priv->button_down = FALSE;
+ }
+ /*
+ * the untouch should always come after the button release
+ */
+ if ((priv->proximity == TRUE) && !(type & MuT_CONTACT))
+
+ {
+ priv->proximity = FALSE;
+ xf86PostProximityEvent (local->dev, 0, 0, 2, x, y);
+ }
+
+ xf86ErrorFVerb( 3, "TouchScreen: x(%d), y(%d), %d %d %s\n",
+ x, y, type, type & MuT_CONTACT,
+ (type & MuT_CONTACT) ? "Press" : "Release" );
+ }
+}
+
+static int
+ControlProc (LocalDevicePtr local, xDeviceCtl * control)
+{
+ xDeviceTSCalibrationCtl *c = (xDeviceTSCalibrationCtl *) control;
+ MuTPrivatePtr priv = (MuTPrivatePtr) (local->private);
+
+ priv->min_x = c->min_x;
+ priv->max_x = c->max_x;
+ priv->min_y = c->min_y;
+ priv->max_y = c->max_y;
+ return (Success);
+}
+
+static void
+CloseProc (LocalDevicePtr local)
+{
+}
+
+static int
+SwitchMode (ClientPtr client, DeviceIntPtr dev, int mode)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ MuTPrivatePtr priv = (MuTPrivatePtr) (local->private);
+ if ((mode == TS_Raw) || (mode == TS_Scaled))
+ {
+ priv->reporting_mode = mode;
+ return (Success);
+ }
+ else if ((mode == SendCoreEvents) || (mode == DontSendCoreEvents))
+ {
+ xf86XInputSetSendCoreEvents (local, (mode == SendCoreEvents));
+ return (Success);
+ }
+ else
+ return (!Success);
+}
+
+static Bool
+ConvertProc (LocalDevicePtr local,
+ int first,
+ int num,
+ int v0,
+ int v1,
+ int v2,
+ int v3,
+ int v4,
+ int v5,
+ int *x,
+ int *y)
+{
+ MuTPrivatePtr priv = (MuTPrivatePtr) (local->private);
+
+ if (priv->reporting_mode == TS_Raw)
+ {
+ *x = xf86ScaleAxis (v0, 0, priv->screen_width, priv->min_x,
+ priv->max_x);
+ *y = xf86ScaleAxis (v1, 0, priv->screen_height, priv->min_y,
+ priv->max_y);
+ }
+ else
+ {
+ *x = v0;
+ *y = v1;
+ }
+ return (TRUE);
+}
+
+static Bool
+xf86MuTSendCommand (unsigned char *type, MuTPrivatePtr priv)
+{
+ int r;
+ int retries = MuT_RETRIES;
+
+ while (retries--)
+ {
+ if (xf86MuTSendPacket (type, strlen ( (char *)type), priv) != Success)
+ continue;
+ r = xf86MuTWaitReply ( (unsigned char *)MuT_OK, priv);
+ if (r == ACK)
+ return (TRUE);
+ else if (r == NACK)
+ return (FALSE);
+ }
+ return (FALSE);
+}
+
+/*
+ * The microtouch SMT3 factory default is 72N, but the recommended operating
+ * mode is 81N. This code first tries 81N, but if that fails it switches to
+ * 72N and puts the controller in 81N before proceeding
+ */
+static Bool
+QueryHardware (LocalDevicePtr local)
+{
+ MuTPrivatePtr priv = (MuTPrivatePtr) local->private;
+ pointer fallback;
+ Bool ret = Success;
+ int cs7 = FALSE;
+
+ fallback = xf86OptionListCreate (fallback_options,
+ (sizeof (fallback_options) / sizeof (fallback_options[0])), 0);
+
+ priv->cs7flag = TRUE;
+ if (!xf86MuTSendCommand ( (unsigned char *)MuT_RESET, priv))
+ {
+ xf86ErrorFVerb( 5,
+ "Switching Com Parameters to CS7, 2 stop bits, no parity\n" );
+ xf86SetSerial (priv->buffer->fd, fallback);
+ cs7 = TRUE;
+ if (!xf86MuTSendCommand ( (unsigned char *)MuT_RESET, priv))
+ {
+ ret = !Success;
+ goto done;
+ }
+ }
+ if (!xf86MuTSendCommand ( (unsigned char *)MuT_ABDISABLE, priv))
+ {
+ ret = !Success;
+ goto done;
+ }
+ if (!xf86MuTSendCommand ( (unsigned char *)MuT_SETRATE, priv))
+ {
+ ret = !Success;
+ goto done;
+ }
+ if (cs7)
+ {
+ xf86ErrorFVerb( 5,
+ "Switching Com Parameters back to CS8, 1 stop bit, no parity\n" );
+ xf86SetSerial (priv->buffer->fd, local->options);
+ }
+ priv->cs7flag = FALSE;
+ if (!xf86MuTSendCommand ( (unsigned char *)MuT_FORMAT_TABLET, priv))
+ {
+ ret = !Success;
+ goto done;
+ }
+ if (!xf86MuTSendCommand ( (unsigned char *)MuT_MODE_STREAM, priv))
+ {
+ ret = !Success;
+ goto done;
+ }
+ if (!xf86MuTSendCommand ( (unsigned char *)MuT_PARAM_LOCK, priv))
+ {
+ ret = !Success;
+ goto done;
+ }
+ if( 1 ) /* Was: if (xf86Verbose), but can't do that in 3.9N... */
+ {
+ if (xf86MuTSendPacket ( (unsigned char *)MuT_OUTPUT_IDENT, strlen (MuT_OUTPUT_IDENT),
+ priv) == Success)
+ {
+ if (MuTGetPacket (priv) == Success)
+ xf86MuTPrintIdent (priv->packet);
+ }
+
+ /* some microtouch controllers support one command, some support the
+ * * other. If the first one get's a NACK, try the second. They both
+ * * return the same packet. */
+ if (xf86MuTSendPacket ( (unsigned char *)MuT_UNIT_VERIFY, strlen (MuT_UNIT_VERIFY),
+ priv) == Success)
+ {
+ if ((MuTGetPacket (priv) == Success) &&
+ (strcmp ( (char *)&(priv->packet[1]), MuT_ERROR) == 0))
+ {
+ if (xf86MuTSendPacket ( (unsigned char *)MuT_UNIT_TYPE,
+ strlen (MuT_UNIT_TYPE), priv) == Success)
+ {
+ if ((MuTGetPacket (priv) != Success))
+ {
+ ret = !Success;
+ goto done;
+ }
+ }
+ }
+ ret = xf86MuTPrintHwStatus (priv->packet);
+ }
+ }
+
+ done:
+ xf86OptionListFree (fallback);
+
+ return (ret);
+}
+
+static void
+MuTNewPacket (MuTPrivatePtr priv)
+{
+ priv->lex_mode = microtouch_normal;
+ priv->packeti = 0;
+ priv->binary_pkt = FALSE;
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86MuTSendPacket --
+ * Emit a variable length packet to the controller.
+ * The function expects a valid buffer containing the
+ * command to be sent to the controller. The command
+ * size is in len
+ * The buffer is filled with the leading and trailing
+ * character before sending.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86MuTSendPacket (unsigned char *type, int len, MuTPrivatePtr priv)
+{
+ int result;
+ unsigned char req[MuT_PACKET_SIZE];
+
+ memset (req, 0, MuT_PACKET_SIZE);
+ strncpy ((char *) &req[1], (char *)type, strlen ( (char *)type));
+ req[0] = MuT_LEAD_BYTE;
+ req[len + 1] = MuT_TRAIL_BYTE;
+
+ result = XisbWrite (priv->buffer, req, len + 2);
+ if (result != len + 2)
+ {
+ xf86ErrorFVerb( 5, "System error while sending to MicroTouch touchscreen.\n" );
+ return !Success;
+ }
+ else
+ return Success;
+}
+
+/*
+ ***************************************************************************
+ * 0 ACK
+ * -1 NACK
+ * -2 timeout
+ * -3 wrong packet type
+ ***************************************************************************
+ */
+static int
+xf86MuTWaitReply (unsigned char *type, MuTPrivatePtr priv)
+{
+ Bool ok;
+ int wrong, empty;
+
+ wrong = MuT_MAX_WRONG_PACKETS;
+ empty = MuT_MAX_EMPTY_PACKETS;
+ do
+ {
+ ok = !Success;
+
+ /*
+ * Wait half a second for the reply. The fuse counts down each
+ * timeout and each wrong packet.
+ */
+ xf86ErrorFVerb( 4, "Waiting %d ms for data from port\n", MuT_MAX_WAIT / 1000 );
+ MuTNewPacket (priv);
+ XisbBlockDuration (priv->buffer, MuT_MAX_WAIT);
+ ok = MuTGetPacket (priv);
+ /*
+ * type is a NULL terminated string of 0 - 2 characters. An empty
+ * string for type indicates that any reply type is acceptable.
+ */
+ if (ok != Success)
+ {
+ xf86ErrorFVerb( 4, "Recieved empty packet.\n" );
+ empty--;
+ continue;
+ }
+ if (ok == Success)
+ {
+ /*
+ * this bit of weirdness attempts to detect an ACK from the
+ * controller when it is in 7bit mode and the computer is in 8bit
+ * mode. If we see this pattern and send a NACK here the next
+ * level up will switch to 7 bit mode and try again
+ */
+ if (priv->cs7flag && (priv->packet[1] == MuT_OK7) &&
+ (priv->packet[2] == '\0'))
+ {
+ xf86ErrorFVerb( 4, "Detected the 7 bit ACK in 8bit mode.\n" );
+ return (NACK);
+ }
+ if (strcmp ( (char *)&(priv->packet[1]), (char *)type) == 0)
+ {
+ xf86ErrorFVerb( 5, "\t\tgot an ACK\n" );
+ return (ACK);
+ }
+ else if (strcmp ( (char *)&(priv->packet[1]), MuT_ERROR) == 0)
+ {
+ xf86ErrorFVerb( 5, "\t\tgot a NACK\n" );
+ return (NACK);
+ }
+ else
+ {
+ xf86ErrorFVerb( 2, "Wrong reply received\n" );
+ ok = !Success;
+ wrong--;
+ }
+ }
+ }
+ while (ok != Success && wrong && empty);
+
+ if (wrong)
+ return (TIMEOUT);
+ else
+ return (WRONG_PACKET);
+}
+
+static Bool
+MuTGetPacket (MuTPrivatePtr priv)
+{
+ int count = 0;
+ int c;
+
+ while ((c = XisbRead (priv->buffer)) >= 0)
+ {
+ if (count++ > 100)
+ {
+ MuTNewPacket (priv);
+ return (!Success);
+ }
+
+ switch (priv->lex_mode)
+ {
+ case microtouch_normal:
+ if ((c == MuT_LEAD_BYTE) ||
+ (priv->cs7flag && ((c & 0x7f) == MuT_LEAD_BYTE)))
+ {
+ xf86ErrorFVerb( 8, "Saw MuT_LEAD_BYTE\n" );
+ priv->packet[priv->packeti++] = (unsigned char) c;
+ priv->lex_mode = microtouch_body;
+ }
+ /*
+ * binary touch packets do not have LEAD_BYTE or TRAIL_BYTE
+ * Instead, only the first byte has the 8th bit set.
+ */
+ if (c & 0x80)
+ {
+ xf86ErrorFVerb( 8, "Saw BINARY start\n" );
+ priv->packet[priv->packeti++] = (unsigned char) c;
+ priv->lex_mode = mtouch_binary;
+ priv->bin_byte = 0;
+ }
+ break;
+
+ case mtouch_binary:
+ priv->packet[priv->packeti++] = (unsigned char) c;
+ priv->bin_byte++;
+ if (priv->bin_byte == 4)
+ {
+ xf86ErrorFVerb( 8, "got a good BINARY packet\n" );
+ MuTNewPacket (priv);
+ priv->binary_pkt = TRUE;
+ return (Success);
+ }
+ break;
+
+ case microtouch_body:
+ /*
+ * apparently a new packet can start in the middle of another
+ * packet if they host sends something at the right time to
+ * trigger it.
+ */
+ if ((c == MuT_LEAD_BYTE) ||
+ (priv->cs7flag && ((c & 0x7f) == MuT_LEAD_BYTE)))
+ {
+ priv->packeti = 0;
+ }
+ if ((c == MuT_TRAIL_BYTE) ||
+ (priv->cs7flag && ((c & 0x7f) == MuT_TRAIL_BYTE)))
+ {
+ /* null terminate the packet */
+ priv->packet[priv->packeti++] = '\0';
+ xf86ErrorFVerb( 8, "got a good packet\n" );
+ MuTNewPacket (priv);
+ return (Success);
+ }
+ else
+ priv->packet[priv->packeti++] = (unsigned char) c;
+ break;
+
+ }
+ }
+ return (!Success);
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86MuTPrintIdent --
+ * Print type of touchscreen and features on controller board.
+ *
+ ***************************************************************************
+ */
+static void
+xf86MuTPrintIdent (unsigned char *packet)
+{
+ int vers, rev;
+
+ if (strlen ( (char *)packet) < 6)
+ return;
+ xf86Msg( X_PROBED, " MicroTouch touchscreen is " );
+ if (strncmp ((char *) &packet[1], MuT_TOUCH_PEN_IDENT, 2) == 0)
+ xf86ErrorF( "a TouchPen.\n" );
+ else if (strncmp ((char *) &packet[1], MuT_SMT3_IDENT, 2) == 0)
+ xf86ErrorF( "a Serial/SMT3.\n" );
+ else if (strncmp ((char *) &packet[1], MuT_GENERAL_IDENT, 2) == 0)
+ xf86ErrorF( "an SMT2, SMT3V or SMT3RV.\n" );
+ else
+ xf86ErrorF( "Unknown Type %c%c.\n", packet[1], packet[2] );
+ sscanf ((char *) &packet[3], "%2d%2d", &vers, &rev);
+ xf86Msg( X_PROBED, " MicroTouch controller firmware revision is %d.%d.\n", vers, rev);
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86MuTPrintHwStatus --
+ * Print status of hardware. That is if the controller report errors,
+ * decode and display them.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86MuTPrintHwStatus (unsigned char *packet)
+{
+ int i;
+ int err;
+
+ for (i = 3; i < 7; i++)
+ {
+ if (packet[i] == 'R')
+ {
+ xf86Msg( X_PROBED,
+ " MicroTouch controller is a resistive type.\n" );
+ }
+
+ }
+ if (packet[7] == '1')
+ {
+ xf86Msg( X_PROBED,
+ " MicroTouch controller reports the following errors:\n" );
+ err = packet[8];
+ if (err & 0x01)
+ xf86ErrorF( "\tReserved\n" );
+ if (err & 0x02)
+ xf86ErrorF( "\tROM error. Firmware checksum verification error.\n" );
+ if (err & 0x04)
+ xf86ErrorF( "\tPWM error. Unable to establish PWM operating range at power-up.\n" );
+ if (err & 0x08)
+ xf86ErrorF( "\tNOVRAM error. The operating parameters in the controller NOVRAM are invalid.\n" );
+ if (err & 0x10)
+ xf86ErrorF( "\tHWD error. The controller hardware failed.\n" );
+ if (err & 0x20)
+ xf86ErrorF( "\tReserved\n" );
+ if (err & 0x40)
+ xf86ErrorF( "\tCable NOVRAM error. The linearization data in the cable NOVRAM is invalid.\n" );
+ if (err & 0x80)
+ xf86ErrorF( "\tNOVRAM2 error. The linearization data in the controller NOVRAM is invalid.\n" );
+ return (!Success);
+ }
+
+ return (Success);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/input/microtouch/microtouch.h b/xc/programs/Xserver/hw/xfree86/input/microtouch/microtouch.h
new file mode 100644
index 000000000..a3b14adf9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/microtouch/microtouch.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 1998 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/microtouch/microtouch.h,v 1.3 1999/08/28 09:01:17 dawes Exp $ */
+
+#ifndef _microtouch_H_
+#define _microtouch_H_
+
+/******************************************************************************
+ * Definitions
+ * structs, typedefs, #defines, enums
+ *****************************************************************************/
+#define MuT_REPORT_SIZE 5 /* Size of a report packet. */
+#define MuT_BUFFER_SIZE 256 /* Size of input buffer. */
+#define MuT_PACKET_SIZE 10 /* Maximum size of a command/reply
+ * *including* */
+#define MuT_MAX_WRONG_PACKETS 20 /* Number of wrong packets to accept
+ * before giving up when looking for a
+ * specific packet type */
+#define MuT_MAX_EMPTY_PACKETS 5 /* Number of empty reads to accept before
+ * giving up when looking for a reply */
+#define MuT_RETRIES 3
+#define MuT_MAX_WAIT 100000 /* Max wait time for a reply
+ * (microsec) */
+
+ /* the leading and trailing bytes. */
+#define MuT_LEAD_BYTE 0x01 /* First byte of a command/reply packet.
+ * */
+#define MuT_TRAIL_BYTE 0x0D /* Last byte of a command/reply packet.
+ * */
+
+/*
+ * Commands.
+ */
+#define MuT_RESET "R" /* Reset the controller. */
+#define MuT_OUTPUT_IDENT "OI" /* Ask some infos about the firmware. */
+#define MuT_UNIT_TYPE "UT" /* Ask some more infos about the *
+ * firmware. */
+#define MuT_UNIT_VERIFY "UV" /* Ask some more infos about the *
+ * firmware. some hardware only supports
+ * * this version */
+#define MuT_ABDISABLE "AD" /* disable auto baud detection */
+#define MuT_SETRATE "PN812" /* set com parameters to
+ * 8,1,none,9600 */
+#define MuT_FORMAT_TABLET "FT" /* Report events using tablet format. */
+#define MuT_FINGER_ONLY "FO" /* Always send reports. */
+#define MuT_MODE_STREAM "MS" /* Receive reports in stream mode */
+#define MuT_PARAM_LOCK "PL" /* write settings to nvram */
+
+#define MuT_OK "0" /* Report success. */
+#define MuT_OK7 0xb0 /* 7bit Report success as seen in 8bit mode */
+#define MuT_ERROR "1" /* Report error. */
+#define MuT_ANY "" /* Accept any reply */
+
+#define MuT_TOUCH_PEN_IDENT "P5"
+#define MuT_SMT3_IDENT "Q1"
+#define MuT_GENERAL_IDENT "A3"
+
+#define MuT_CONTACT 0x40 /* Report touch/untouch with touchscreen. */
+
+#define ACK 0
+#define NACK -1
+#define TIMEOUT -2
+#define WRONG_PACKET -3
+
+typedef enum
+{
+ microtouch_normal, microtouch_body, mtouch_binary
+}
+MuTState;
+
+typedef struct _MuTPrivateRec
+{
+ int min_x; /* Minimum x reported by calibration */
+ int max_x; /* Maximum x */
+ int min_y; /* Minimum y reported by calibration */
+ int max_y; /* Maximum y */
+ Bool proximity; /* is the stylus in proximity */
+ Bool button_down; /* is the "button" currently down */
+ int button_number; /* which button to report */
+ int reporting_mode; /* TS_Raw or TS_Scaled */
+
+ int screen_num; /* Screen associated with the device */
+ int screen_width; /* Width of the associated X screen */
+ int screen_height; /* Height of the screen */
+ XISBuffer *buffer;
+ unsigned char packet[MuT_BUFFER_SIZE]; /* packet being/just read */
+ int packeti; /* index into packet */
+ Bool cs7flag;
+ Bool binary_pkt; /* indicates packet was a binary touch */
+
+ MuTState lex_mode;
+ int bin_byte; /* bytes recieved in binary packet */
+}
+MuTPrivateRec, *MuTPrivatePtr;
+
+/******************************************************************************
+ * Declarations
+ *****************************************************************************/
+static MODULESETUPPROTO( SetupProc );
+static void TearDownProc( pointer p );
+/*int DumpOpts (XF86OptionPtr opts); */
+static Bool DeviceControl (DeviceIntPtr dev, int mode);
+static Bool DeviceOn (DeviceIntPtr dev);
+static Bool DeviceOff (DeviceIntPtr dev);
+static Bool DeviceInit (DeviceIntPtr dev);
+static void ReadInput (LocalDevicePtr local);
+static int ControlProc (LocalDevicePtr local, xDeviceCtl * control);
+static void CloseProc (LocalDevicePtr local);
+static int SwitchMode (ClientPtr client, DeviceIntPtr dev, int mode);
+static Bool ConvertProc (LocalDevicePtr local, int first, int num, int v0, int v1, int v2, int v3, int v4, int v5, int *x, int *y);
+static Bool xf86MuTSendCommand (unsigned char *type, MuTPrivatePtr priv);
+static Bool QueryHardware (LocalDevicePtr local);
+static void MuTNewPacket (MuTPrivatePtr priv);
+static Bool xf86MuTSendPacket (unsigned char *type, int len, MuTPrivatePtr priv);
+static int xf86MuTWaitReply (unsigned char *type, MuTPrivatePtr priv);
+static Bool MuTGetPacket (MuTPrivatePtr priv);
+static void xf86MuTPrintIdent (unsigned char *packet);
+static Bool xf86MuTPrintHwStatus (unsigned char *packet);
+/*
+ * DO NOT PUT ANYTHING AFTER THIS ENDIF
+ */
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/input/mouse/Imakefile b/xc/programs/Xserver/hw/xfree86/input/mouse/Imakefile
new file mode 100644
index 000000000..6c49d210c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/mouse/Imakefile
@@ -0,0 +1,29 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/mouse/Imakefile,v 1.3 1999/08/14 10:50:02 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = mouse.c pnp.c
+OBJS = mouse.o pnp.o
+
+DRIVER = mouse
+
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86SRC)/loader -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/mi -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(EXTINCSRC)
+
+DEFINES = -DPNP_MOUSE
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget($(DRIVER),$(OBJS))
+
+InstallObjectModule($(DRIVER),$(MODULEDIR),input)
+
+DependTarget()
+
+InstallDriverSDKObjectModule($(DRIVER),$(DRIVERSDKMODULEDIR),input)
diff --git a/xc/programs/Xserver/hw/xfree86/input/mouse/mouse.c b/xc/programs/Xserver/hw/xfree86/input/mouse/mouse.c
new file mode 100644
index 000000000..29a350bfb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/mouse/mouse.c
@@ -0,0 +1,1714 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/mouse/mouse.c,v 1.17 1999/08/01 07:57:32 dawes Exp $ */
+/*
+ *
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ * Copyright 1994-1999 by The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of copyright holders not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. The copyright holders
+ * make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/* Patch for PS/2 Intellimouse - Tim Goodwin 1997-11-06. */
+
+/*
+ * [JCH-96/01/21] Added fourth button support for PROT_GLIDEPOINT mouse
+ * protocol.
+ */
+
+/*
+ * [TVO-97/03/05] Added microsoft IntelliMouse support
+ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+
+#include "compiler.h"
+
+#ifndef NEW_INPUT
+#define NEW_INPUT
+#endif
+
+#include "xf86.h"
+
+#ifdef XINPUT
+#include "XI.h"
+#include "XIproto.h"
+#include "extnsionst.h"
+#include "extinit.h"
+#else
+#include "inputstr.h"
+#endif
+
+#include "xf86Xinput.h"
+#include "xf86_OSproc.h"
+#include "xf86OSmouse.h"
+#define NEED_XF86_TYPES /* for xisb.h when !XFree86LOADER */
+#include "xf86_ansic.h"
+#include "xisb.h"
+#include "mouse.h"
+#include "mipointer.h"
+
+static InputInfoPtr MousePreInit(InputDriverPtr drv, IDevPtr dev, int flags);
+#if 0
+static void MouseUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags);
+#endif
+
+static int MouseProc(DeviceIntPtr device, int what);
+static void MouseReadInput(InputInfoPtr pInfo);
+static Bool MouseConvert(LocalDevicePtr local, int first, int num, int v0,
+ int v1, int v2, int v3, int v4, int v5, int *x,
+ int *y);
+
+static void MouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl);
+static void MousePostEvent(InputInfoPtr pInfo, int buttons,
+ int dx, int dy, int dz);
+/* XXX This is temporary. */
+const char * xf86ProtocolIDToName(ProtocolID id);
+
+#undef MOUSE
+InputDriverRec MOUSE = {
+ 1,
+ "mouse",
+ NULL,
+ MousePreInit,
+ /*MouseUnInit,*/NULL,
+ NULL,
+ 0
+};
+
+/*
+ * Microsoft (all serial models), Logitech MouseMan, First Mouse, etc,
+ * ALPS GlidePoint, Thinking Mouse.
+ */
+static const char *msDefaults[] = {
+ "BaudRate", "1200",
+ "DataBits", "7",
+ "StopBits", "1",
+ "Parity", "None",
+ "FlowControl", "None",
+ "VTime", "0",
+ "VMin", "1",
+ NULL
+};
+/* MouseSystems */
+static const char *mscDefaults[] = {
+ "BaudRate", "1200",
+ "DataBits", "8",
+ "StopBits", "2",
+ "Parity", "None",
+ "FlowControl", "None",
+ "VTime", "0",
+ "VMin", "1",
+ NULL
+};
+/* MMSeries */
+static const char *mmDefaults[] = {
+ "BaudRate", "1200",
+ "DataBits", "8",
+ "StopBits", "1",
+ "Parity", "Odd",
+ "FlowControl", "None",
+ "VTime", "0",
+ "VMin", "1",
+ NULL
+};
+/* Logitech series 9 */
+static const char *logiDefaults[] = {
+ "BaudRate", "1200",
+ "DataBits", "8",
+ "StopBits", "2",
+ "Parity", "None",
+ "FlowControl", "None",
+ "VTime", "0",
+ "VMin", "1",
+ NULL
+};
+/* Hitachi Tablet */
+static const char *mmhitDefaults[] = {
+ "BaudRate", "1200",
+ "DataBits", "8",
+ "StopBits", "1",
+ "Parity", "None",
+ "FlowControl", "None",
+ "VTime", "0",
+ "VMin", "1",
+ NULL
+};
+/* AceCad Tablet */
+static const char *acecadDefaults[] = {
+ "BaudRate", "9600",
+ "DataBits", "8",
+ "StopBits", "1",
+ "Parity", "Odd",
+ "FlowControl", "None",
+ "VTime", "0",
+ "VMin", "1",
+ NULL
+};
+
+static MouseProtocolRec mouseProtocols[] = {
+
+ /* Serial protocols */
+ { "Microsoft", MSE_SERIAL, msDefaults, PROT_MS },
+ { "MouseSystems", MSE_SERIAL, mscDefaults, PROT_MSC },
+ { "MMSeries", MSE_SERIAL, mmDefaults, PROT_MM },
+ { "Logitech", MSE_SERIAL, logiDefaults, PROT_LOGI },
+ { "MouseMan", MSE_SERIAL, msDefaults, PROT_LOGIMAN },
+ { "MMHitTab", MSE_SERIAL, mmhitDefaults, PROT_MMHIT },
+ { "GlidePoint", MSE_SERIAL, msDefaults, PROT_GLIDE },
+ { "IntelliMouse", MSE_SERIAL, msDefaults, PROT_IMSERIAL },
+ { "ThinkingMouse", MSE_SERIAL, msDefaults, PROT_THINKING },
+ { "AceCad", MSE_SERIAL, acecadDefaults, PROT_ACECAD },
+
+ /* Standard PS/2 */
+ { "PS/2", MSE_PS2, NULL, PROT_PS2 },
+
+ /* Extended PS/2 */
+ { "ImPS/2", MSE_XPS2, NULL, PROT_IMPS2 },
+ { "ThinkingMousePS/2", MSE_XPS2, NULL, PROT_THINKPS2 },
+ { "MouseManPlusPS/2", MSE_XPS2, NULL, PROT_MMPS2 },
+ { "GlidePointPS/2", MSE_XPS2, NULL, PROT_GLIDEPS2 },
+ { "NetMousePS/2", MSE_XPS2, NULL, PROT_NETPS2 },
+ { "NetScrollPS/2", MSE_XPS2, NULL, PROT_NETSCPS2 },
+
+ /* Bus Mouse */
+ { "BusMouse", MSE_BUS, NULL, PROT_BM },
+
+ /* Auto-detect (PnP) */
+ { "Auto", MSE_AUTO, NULL, PROT_AUTO },
+
+ /* Misc (usually OS-specific) */
+ { "SysMouse", MSE_MISC, mscDefaults, PROT_SYSMOUSE },
+
+ /* end of list */
+ { NULL, MSE_NONE, NULL, PROT_UNKNOWN }
+};
+
+static ProtocolID
+ProtocolNameToID(const char *name)
+{
+ int i;
+
+ for (i = 0; mouseProtocols[i].name; i++)
+ if (xf86NameCmp(name, mouseProtocols[i].name) == 0)
+ return mouseProtocols[i].id;
+ return PROT_UNKNOWN;
+}
+
+static const char *
+ProtocolIDToName(ProtocolID id)
+{
+ int i;
+
+ switch (id) {
+ case PROT_UNKNOWN:
+ return "Unknown";
+ break;
+ case PROT_UNSUP:
+ return "Unsupported";
+ break;
+ default:
+ for (i = 0; mouseProtocols[i].name; i++)
+ if (id == mouseProtocols[i].id)
+ return mouseProtocols[i].name;
+ return "Invalid";
+ }
+}
+
+const char *
+xf86ProtocolIDToName(ProtocolID id)
+{
+ return ProtocolIDToName(id);
+}
+
+static int
+ProtocolIDToClass(ProtocolID id)
+{
+ int i;
+
+ switch (id) {
+ case PROT_UNKNOWN:
+ case PROT_UNSUP:
+ return MSE_NONE;
+ break;
+ default:
+ for (i = 0; mouseProtocols[i].name; i++)
+ if (id == mouseProtocols[i].id)
+ return mouseProtocols[i].class;
+ return MSE_NONE;
+ }
+}
+
+static MouseProtocolPtr
+GetProtocol(ProtocolID id) {
+ int i;
+
+ switch (id) {
+ case PROT_UNKNOWN:
+ case PROT_UNSUP:
+ return NULL;
+ break;
+ default:
+ for (i = 0; mouseProtocols[i].name; i++)
+ if (id == mouseProtocols[i].id)
+ return &mouseProtocols[i];
+ return NULL;
+ }
+}
+
+static OSMouseInfoPtr osInfo = NULL;
+
+static Bool
+InitProtocols(void)
+{
+ int classes;
+ int i;
+ const char *osname = NULL;
+
+ if (osInfo)
+ return TRUE;
+
+ osInfo = xf86OSMouseInit(0);
+ if (!osInfo)
+ return FALSE;
+ if (!osInfo->SupportedInterfaces)
+ return FALSE;
+
+ classes = osInfo->SupportedInterfaces();
+ if (!classes)
+ return FALSE;
+
+ /* Mark unsupported interface classes. */
+ for (i = 0; mouseProtocols[i].name; i++)
+ if (!(mouseProtocols[i].class & classes))
+ mouseProtocols[i].id = PROT_UNSUP;
+
+ for (i = 0; mouseProtocols[i].name; i++)
+ if (mouseProtocols[i].class & MSE_MISC)
+ if (!osInfo->CheckProtocol ||
+ !osInfo->CheckProtocol(mouseProtocols[i].name))
+ mouseProtocols[i].id = PROT_UNSUP;
+
+ /* NetBSD uses PROT_BM for "PS/2". */
+ xf86GetOS(&osname, NULL, NULL, NULL);
+ if (osname && xf86NameCmp(osname, "netbsd") == 0)
+ for (i = 0; mouseProtocols[i].name; i++)
+ if (mouseProtocols[i].id == PROT_PS2)
+ mouseProtocols[i].id = PROT_BM;
+
+ return TRUE;
+}
+
+/* Process options common to all mouse types. */
+static void
+MouseCommonOptions(InputInfoPtr pInfo)
+{
+ MouseDevPtr pMse;
+ MessageType from = X_DEFAULT;
+ char *s;
+
+ pMse = pInfo->private;
+
+ pMse->buttons = xf86SetIntOption(pInfo->options, "Buttons", 0);
+ from = X_CONFIG;
+ if (!pMse->buttons) {
+ pMse->buttons = MSE_DFLTBUTTONS;
+ from = X_DEFAULT;
+ }
+ xf86Msg(from, "%s: Buttons: %d\n", pInfo->name, pMse->buttons);
+
+ pMse->emulate3Buttons = xf86SetBoolOption(pInfo->options,
+ "Emulate3Buttons", FALSE);
+ pMse->emulate3Timeout = xf86SetIntOption(pInfo->options, "Emulate3Timeout",
+ 50);
+ if (pMse->emulate3Buttons) {
+ xf86Msg(X_CONFIG, "%s: Emulate3Buttons, Emulate3Timeout: %d\n",
+ pInfo->name, pMse->emulate3Timeout);
+ }
+
+ pMse->chordMiddle = xf86SetBoolOption(pInfo->options, "ChordMiddle", FALSE);
+ if (pMse->chordMiddle)
+ xf86Msg(X_CONFIG, "%s: ChordMiddle\n", pInfo->name);
+
+ s = xf86SetStrOption(pInfo->options, "ZAxisMapping", NULL);
+ if (s) {
+ int b1 = 0, b2 = 0;
+ char *msg = NULL;
+
+ if (!xf86NameCmp(s, "x")) {
+ pMse->negativeZ = pMse->positiveZ = MSE_MAPTOX;
+ msg = xstrdup("X axis");
+ } else if (!xf86NameCmp(s, "y")) {
+ pMse->negativeZ = pMse->positiveZ = MSE_MAPTOY;
+ msg = xstrdup("Y axis");
+ } else if (sscanf(s, "%d %d", &b1, &b2) == 2 &&
+ b1 > 0 && b1 <= MSE_MAXBUTTONS &&
+ b2 > 0 && b2 <= MSE_MAXBUTTONS) {
+ pMse->negativeZ = 1 << (b1-1);
+ pMse->positiveZ = 1 << (b2-1);
+ if ( b1 > pMse->buttons ) pMse->buttons = b1;
+ if ( b2 > pMse->buttons ) pMse->buttons = b2;
+ msg = xstrdup("buttons XX and YY");
+ if (msg)
+ sprintf(msg, "buttons %d and %d", b1, b2);
+ } else {
+ pMse->negativeZ = pMse->positiveZ = MSE_NOZMAP;
+ }
+ if (msg) {
+ xf86Msg(X_CONFIG, "%s: ZAxisMapping: %s\n", pInfo->name, msg);
+ xfree(msg);
+ } else {
+ xf86Msg(X_WARNING, "%s: Invalid ZAxisMapping value: \"%s\"\n",
+ pInfo->name, s);
+ }
+ }
+}
+
+static InputInfoPtr
+MousePreInit(InputDriverPtr drv, IDevPtr dev, int flags)
+{
+ InputInfoPtr pInfo;
+ MouseDevPtr pMse;
+ MessageType from = X_DEFAULT;
+ const char *protocol;
+ ProtocolID protocolID;
+ MouseProtocolPtr pProto;
+
+ if (!InitProtocols())
+ return NULL;
+
+ if (!(pInfo = xf86AllocateInput(drv, 0)))
+ return NULL;
+
+ /* Initialise the InputInfoRec. */
+ pInfo->name = dev->identifier;
+ pInfo->type_name = XI_MOUSE;
+ pInfo->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
+ pInfo->device_control = MouseProc;
+ pInfo->read_input = MouseReadInput;
+ pInfo->motion_history_proc = xf86GetMotionEvents;
+ pInfo->history_size = 0;
+ pInfo->control_proc = NULL;
+ pInfo->close_proc = NULL;
+ pInfo->switch_mode = NULL;
+ pInfo->conversion_proc = MouseConvert;
+ pInfo->reverse_conversion_proc = NULL;
+ pInfo->fd = -1;
+ pInfo->dev = NULL;
+ pInfo->private_flags = 0;
+ pInfo->always_core_feedback = 0;
+ pInfo->conf_idev = dev;
+
+ /* Allocate the MouseDevRec and initialise it. */
+ if (!(pMse = xcalloc(sizeof(MouseDevRec), 1)))
+ return pInfo;
+ pInfo->private = pMse;
+ pMse->Ctrl = MouseCtrl;
+ pMse->PostEvent = MousePostEvent;
+ pMse->CommonOptions = MouseCommonOptions;
+
+ /* Find the protocol type. */
+ protocol = xf86SetStrOption(dev->commonOptions, "Protocol", NULL);
+ if (protocol) {
+ from = X_CONFIG;
+ } else if (osInfo->DefaultProtocol) {
+ protocol = osInfo->DefaultProtocol();
+ from = X_DEFAULT;
+ }
+ if (!protocol) {
+ xf86Msg(X_ERROR, "%s: No Protocol specified\n", pInfo->name);
+ return pInfo;
+ }
+ protocolID = ProtocolNameToID(protocol);
+ switch (protocolID) {
+ case PROT_UNKNOWN:
+ /* Check for a builtin OS-specific protocol, and call its PreInit. */
+ if (osInfo->CheckProtocol && osInfo->CheckProtocol(protocol)) {
+ if (osInfo->PreInit) {
+ osInfo->PreInit(pInfo, protocol, 0);
+ }
+ return pInfo;
+ }
+ xf86Msg(X_ERROR, "%s: Unknown protocol \"%s\"\n", pInfo->name,
+ protocol);
+ return pInfo;
+ break;
+ case PROT_UNSUP:
+ xf86Msg(X_ERROR,
+ "%s: Protocol \"%s\" is not supported on this platform\n",
+ pInfo->name, protocol);
+ return pInfo;
+ break;
+ default:
+ xf86Msg(from, "%s: Protocol: \"%s\"\n", pInfo->name, protocol);
+ }
+
+ if (!(pProto = GetProtocol(protocolID)))
+ return pInfo;
+
+ pMse->protocol = protocol;
+ pMse->protocolID = protocolID;
+ pMse->class = ProtocolIDToClass(protocolID);
+ pMse->automatic = (protocolID == PROT_AUTO);
+
+ /* Collect the options, and process the common options. */
+ xf86CollectInputOptions(pInfo, pProto->defaults, NULL);
+ xf86ProcessCommonOptions(pInfo, pInfo->options);
+
+ /* Check if the device can be opened. */
+ pInfo->fd = xf86OpenSerial(pInfo->options);
+ if (pInfo->fd == -1) {
+ if (xf86GetAllowMouseOpenFail())
+ xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
+ else {
+ xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name);
+ xfree(pMse);
+ pInfo->private = NULL;
+ return pInfo;
+ }
+ }
+ xf86CloseSerial(pInfo->fd);
+ pInfo->fd = -1;
+
+ pMse->CommonOptions(pInfo);
+
+ pMse->sampleRate = xf86SetIntOption(pInfo->options, "SampleRate", 0);
+ if (pMse->sampleRate) {
+ xf86Msg(X_CONFIG, "%s: SampleRate: %d\n", pInfo->name,
+ pMse->sampleRate);
+ }
+
+ pMse->resolution = xf86SetIntOption(pInfo->options, "Resolution", 0);
+ if (pMse->resolution) {
+ xf86Msg(X_CONFIG, "%s: Resolution: %d\n", pInfo->name,
+ pMse->resolution);
+ }
+
+ pMse->clearDTR = xf86SetBoolOption(pInfo->options, "ClearDTR", FALSE);
+ pMse->clearRTS = xf86SetBoolOption(pInfo->options, "ClearRTS", FALSE);
+ if (pMse->clearDTR || pMse->clearRTS) {
+ xf86Msg(X_CONFIG, "%s: ", pInfo->name);
+ if (pMse->clearDTR) {
+ xf86ErrorF("ClearDTR");
+ if (pMse->clearRTS)
+ xf86ErrorF(", ");
+ }
+ if (pMse->clearRTS) {
+ xf86ErrorF("ClearRTS");
+ }
+ xf86ErrorF("\n");
+ }
+
+ pInfo->flags |= XI86_CONFIGURED;
+ return pInfo;
+}
+
+/*
+ * This array is indexed by the ProtocolID values, so the order of the entries
+ * must match that of the ProtocolID enum in mouse.h.
+ */
+static unsigned char proto[PROT_NUMPROTOS][8] = {
+ /* --header-- ---data--- packet -4th-byte- mouse */
+ /* mask id mask id bytes mask id flags */
+ /* Serial mice */
+ { 0x40, 0x40, 0x40, 0x00, 3, ~0x23, 0x00, MPF_NONE }, /* MicroSoft */
+ { 0xf8, 0x80, 0x00, 0x00, 5, 0x00, 0xff, MPF_SAFE }, /* MouseSystems */
+ { 0xe0, 0x80, 0x80, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* MMSeries */
+ { 0xe0, 0x80, 0x80, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* Logitech */
+ { 0x40, 0x40, 0x40, 0x00, 3, ~0x23, 0x00, MPF_NONE }, /* MouseMan */
+ { 0xe0, 0x80, 0x80, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* MM_HitTablet */
+ { 0x40, 0x40, 0x40, 0x00, 3, ~0x33, 0x00, MPF_NONE }, /* GlidePoint */
+ { 0x40, 0x40, 0x40, 0x00, 3, ~0x3f, 0x00, MPF_NONE }, /* IntelliMouse */
+ { 0x40, 0x40, 0x40, 0x00, 3, ~0x33, 0x00, MPF_NONE }, /* ThinkingMouse */
+ { 0x80, 0x80, 0x80, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* ACECAD */
+ /* PS/2 variants */
+ { 0xc0, 0x00, 0x00, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* PS/2 mouse */
+ { 0xc0, 0x00, 0x00, 0x00, 4, 0x00, 0xff, MPF_NONE }, /* IntelliMouse */
+ { 0x80, 0x80, 0x00, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* ThinkingMouse */
+ { 0x08, 0x08, 0x00, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* MouseMan+ */
+ { 0xc0, 0x00, 0x00, 0x00, 3, 0x00, 0xff, MPF_NONE }, /* GlidePoint */
+ { 0xc0, 0x00, 0x00, 0x00, 4, 0x00, 0xff, MPF_NONE }, /* NetMouse */
+ { 0xc0, 0x00, 0x00, 0x00, 6, 0x00, 0xff, MPF_NONE }, /* NetScroll */
+ /* Bus Mouse */
+ { 0xf8, 0x80, 0x00, 0x00, 5, 0x00, 0xff, MPF_NONE }, /* BusMouse */
+ /* Auto */
+ { 0xf8, 0x80, 0x00, 0x00, 5, 0x00, 0xff, MPF_NONE }, /* dummy entry */
+};
+
+/*
+ * SetupMouse --
+ * Sets up the mouse parameters
+ */
+static Bool
+SetupMouse(InputInfoPtr pInfo)
+{
+ /*
+ ** The following lines take care of the Logitech MouseMan protocols.
+ ** The "Logitech" protocol is for the old "series 9" Logitech products.
+ ** All products since then use the "MouseMan" protocol. Some models
+ ** were programmable, but most (all?) of the current models are not.
+ **
+ ** NOTE: There are different versions of both MouseMan and TrackMan!
+ ** Hence I add another protocol PROT_LOGIMAN, which the user can
+ ** specify as MouseMan in his XF86Config file. This entry was
+ ** formerly handled as a special case of PROT_MS. However, people
+ ** who don't have the middle button problem, can still specify
+ ** Microsoft and use PROT_MS.
+ **
+ ** By default, these mice should use a 3 byte Microsoft protocol
+ ** plus a 4th byte for the middle button. However, the mouse might
+ ** have switched to a different protocol before we use it, so I send
+ ** the proper sequence just in case.
+ **
+ ** NOTE: - all commands to (at least the European) MouseMan have to
+ ** be sent at 1200 Baud.
+ ** - each command starts with a '*'.
+ ** - whenever the MouseMan receives a '*', it will switch back
+ ** to 1200 Baud. Hence I have to select the desired protocol
+ ** first, then select the baud rate.
+ **
+ ** The protocols supported by the (European) MouseMan are:
+ ** - 5 byte packed binary protocol, as with the Mouse Systems
+ ** mouse. Selected by sequence "*U".
+ ** - 2 button 3 byte MicroSoft compatible protocol. Selected
+ ** by sequence "*V".
+ ** - 3 button 3+1 byte MicroSoft compatible protocol (default).
+ ** Selected by sequence "*X".
+ **
+ ** The following baud rates are supported:
+ ** - 1200 Baud (default). Selected by sequence "*n".
+ ** - 9600 Baud. Selected by sequence "*q".
+ **
+ ** Selecting a sample rate is no longer supported with the MouseMan!
+ ** [CHRIS-211092]
+ */
+
+ MouseDevPtr pMse;
+ unsigned char *param;
+ int paramlen;
+ int i;
+ int speed;
+ int protoPara[8] = {-1, -1, -1, -1, -1, -1, -1, -1};
+ const char *name = NULL;
+ const char *s;
+ unsigned char c;
+ ProtocolID protocolID = PROT_UNKNOWN;
+ pointer options;
+
+ pMse = pInfo->private;
+
+ /* Handle the "Auto" protocol. */
+ if (pMse->automatic) {
+ /* Check if the OS has a detection mechanism. */
+ if (osInfo->SetupAuto) {
+ name = osInfo->SetupAuto(pInfo, protoPara);
+ if (name) {
+ protocolID = ProtocolNameToID(name);
+ switch (protocolID) {
+ case PROT_UNKNOWN:
+ /* Check for a builtin OS-specific protocol. */
+ if (osInfo->CheckProtocol && osInfo->CheckProtocol(name)) {
+ /* XXX need to handle auto-detected builtin protocols */
+ } else
+ name = NULL;
+ break;
+ case PROT_UNSUP:
+ name = NULL;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+#ifdef PNP_MOUSE
+ if (!name) {
+ /* A PnP serial mouse? */
+ protocolID = MouseGetPnpProtocol(pInfo);
+ if (protocolID >= 0 && protocolID < PROT_NUMPROTOS) {
+ name = ProtocolIDToName(protocolID);
+ xf86Msg(X_PROBED, "%s: PnP-detected protocol: \"%s\"\n",
+ pInfo->name, name);
+ }
+ }
+#endif
+ if (name) {
+ pMse->protocol = name;
+ pMse->protocolID = protocolID;
+ }
+ }
+ memcpy(pMse->protoPara, proto[pMse->protocolID], sizeof(pMse->protoPara));
+ if (pMse->automatic && name) {
+ /* Possible protoPara overrides from SetupAuto. */
+ for (i = 0; i < sizeof(pMse->protoPara); i++)
+ if (protoPara[i] != -1)
+ pMse->protoPara[i] = protoPara[i];
+ }
+
+ if (pMse->automatic && !name) {
+ xf86Msg(X_ERROR, "%s: cannot determine the mouse protocol\n",
+ pInfo->name);
+ return FALSE;
+ }
+
+ /* Set the port parameters. */
+ xf86SetSerial(pInfo->fd, pInfo->options);
+ param = NULL;
+ paramlen = 0;
+ switch (pMse->protocolID) {
+ case PROT_LOGI: /* Logitech Mice */
+ /*
+ * The baud rate selection command must be sent at the current
+ * baud rate; try all likely settings.
+ */
+ speed = xf86SetIntOption(pInfo->options, "BaudRate", 0);
+ switch (speed) {
+ case 9600:
+ s = "*q";
+ break;
+ case 4800:
+ s = "*p";
+ break;
+ case 2400:
+ s = "*o";
+ break;
+ case 1200:
+ s = "*n";
+ break;
+ default:
+ /* Fallback value */
+ speed = 1200;
+ s = "*n";
+ }
+ xf86SetSerialSpeed(pInfo->fd, 9600);
+ xf86WriteSerial(pInfo->fd, s, 2);
+ usleep(100000);
+ xf86SetSerialSpeed(pInfo->fd, 4800);
+ xf86WriteSerial(pInfo->fd, s, 2);
+ usleep(100000);
+ xf86SetSerialSpeed(pInfo->fd, 2400);
+ xf86WriteSerial(pInfo->fd, s, 2);
+ usleep(100000);
+ xf86SetSerialSpeed(pInfo->fd, 1200);
+ xf86WriteSerial(pInfo->fd, s, 2);
+ usleep(100000);
+ xf86SetSerialSpeed(pInfo->fd, speed);
+
+ /* Select MM series data format. */
+ xf86WriteSerial(pInfo->fd, "S", 1);
+ usleep(100000);
+ /* Set the parameters up for the MM series protocol. */
+ options = pInfo->options;
+ xf86CollectInputOptions(pInfo, mmDefaults, NULL);
+ xf86SetSerial(pInfo->fd, pInfo->options);
+ pInfo->options = options;
+
+ /* Select report rate/frequency. */
+ if (pMse->sampleRate <= 0) c = 'O';
+ else if (pMse->sampleRate <= 15) c = 'J';
+ else if (pMse->sampleRate <= 27) c = 'K';
+ else if (pMse->sampleRate <= 42) c = 'L';
+ else if (pMse->sampleRate <= 60) c = 'R';
+ else if (pMse->sampleRate <= 85) c = 'M';
+ else if (pMse->sampleRate <= 125) c = 'Q';
+ else c = 'N';
+ xf86WriteSerial(pInfo->fd, &c, 1);
+ break;
+
+ case PROT_LOGIMAN:
+ speed = xf86SetIntOption(pInfo->options, "BaudRate", 0);
+ switch (speed) {
+ case 9600:
+ s = "*q";
+ break;
+ case 1200:
+ s = "*n";
+ break;
+ default:
+ /* Fallback value */
+ speed = 1200;
+ s = "*n";
+ }
+ xf86SetSerialSpeed(pInfo->fd, 1200);
+ xf86WriteSerial(pInfo->fd, "*n", 2);
+ xf86WriteSerial(pInfo->fd, "*X", 2);
+ xf86WriteSerial(pInfo->fd, s, 2);
+ usleep(100000);
+ xf86SetSerialSpeed(pInfo->fd, speed);
+ break;
+
+ case PROT_MMHIT: /* MM_HitTablet */
+ /*
+ * Initialize Hitachi PUMA Plus - Model 1212E to desired settings.
+ * The tablet must be configured to be in MM mode, NO parity,
+ * Binary Format. pMse->sampleRate controls the sensitivity
+ * of the tablet. We only use this tablet for it's 4-button puck
+ * so we don't run in "Absolute Mode".
+ */
+ xf86WriteSerial(pInfo->fd, "z8", 2); /* Set Parity = "NONE" */
+ usleep(50000);
+ xf86WriteSerial(pInfo->fd, "zb", 2); /* Set Format = "Binary" */
+ usleep(50000);
+ xf86WriteSerial(pInfo->fd, "@", 1); /* Set Report Mode = "Stream" */
+ usleep(50000);
+ xf86WriteSerial(pInfo->fd, "R", 1); /* Set Output Rate = "45 rps" */
+ usleep(50000);
+ xf86WriteSerial(pInfo->fd, "I\x20", 2); /* Set Incrememtal Mode "20" */
+ usleep(50000);
+ xf86WriteSerial(pInfo->fd, "E", 1); /* Set Data Type = "Relative */
+ usleep(50000);
+ /*
+ * These sample rates translate to 'lines per inch' on the Hitachi
+ * tablet.
+ */
+ if (pMse->sampleRate <= 40) c = 'g';
+ else if (pMse->sampleRate <= 100) c = 'd';
+ else if (pMse->sampleRate <= 200) c = 'e';
+ else if (pMse->sampleRate <= 500) c = 'h';
+ else if (pMse->sampleRate <= 1000) c = 'j';
+ else c = 'd';
+ xf86WriteSerial(pInfo->fd, &c, 1);
+ usleep(50000);
+ xf86WriteSerial(pInfo->fd, "\021", 1); /* Resume DATA output */
+ break;
+
+ case PROT_THINKING: /* ThinkingMouse */
+ /* This mouse may send a PnP ID string, ignore it. */
+ usleep(200000);
+ xf86FlushInput(pInfo->fd);
+ /* Send the command to initialize the beast. */
+ for (s = "E5E5"; *s; ++s) {
+ xf86WriteSerial(pInfo->fd, s, 1);
+ if ((xf86WaitForInput(pInfo->fd, 1000000) <= 0))
+ break;
+ xf86ReadSerial(pInfo->fd, &c, 1);
+ if (c != *s)
+ break;
+ }
+ break;
+
+ case PROT_MSC: /* MouseSystems Corp */
+ usleep(100000);
+ xf86FlushInput(pInfo->fd);
+ break;
+
+ case PROT_ACECAD:
+ /* initialize */
+ /* A nul character resets. */
+ xf86WriteSerial(pInfo->fd, "", 1);
+ usleep(50000);
+ /* Stream out relative mode high resolution increments of 1. */
+ xf86WriteSerial(pInfo->fd, "@EeI!", 5);
+ break;
+
+ case PROT_BM: /* bus/InPort mouse */
+ if (osInfo->SetBMRes)
+ osInfo->SetBMRes(pInfo, pMse->protocol, pMse->sampleRate,
+ pMse->resolution);
+ break;
+
+ case PROT_IMPS2: /* IntelliMouse */
+ {
+ static unsigned char s[] = { 243, 200, 243, 100, 243, 80, };
+
+ param = s;
+ paramlen = sizeof(s);
+ }
+ break;
+
+ case PROT_NETPS2: /* NetMouse, NetMouse Pro, Mie Mouse */
+ case PROT_NETSCPS2: /* NetScroll */
+ {
+ static unsigned char s[] = { 232, 3, 230, 230, 230, };
+
+ param = s;
+ paramlen = sizeof(s);
+ }
+ break;
+
+ case PROT_MMPS2: /* MouseMan+, FirstMouse+ */
+ {
+ static unsigned char s[] = { 230, 232, 0, 232, 3, 232, 2, 232, 1,
+ 230, 232, 3, 232, 1, 232, 2, 232, 3, };
+ param = s;
+ paramlen = sizeof(s);
+ }
+ break;
+
+ case PROT_THINKPS2: /* ThinkingMouse */
+ {
+ static unsigned char s[] = { 243, 10, 232, 0, 243, 20, 243, 60,
+ 243, 40, 243, 20, 243, 20, 243, 60,
+ 243, 40, 243, 20, 243, 20, };
+ param = s;
+ paramlen = sizeof(s);
+ }
+
+ case PROT_SYSMOUSE:
+ if (osInfo->SetMiscRes)
+ osInfo->SetMiscRes(pInfo, pMse->protocol, pMse->sampleRate,
+ pMse->resolution);
+ break;
+
+ default:
+ /* Nothing to do. */
+ break;
+ }
+
+ if (paramlen > 0) {
+#ifdef EXTMOUSEDEBUG
+ for (i = 0; i < paramlen; ++i) {
+ if (xf86WriteSerial(pInfo->fd, &param[i], 1) != 1)
+ ErrorF("SetupMouse: Write to mouse failed (%s)\n",
+ strerror(errno));
+ usleep(30000);
+ xf86ReadSerial(pInfo->fd, &c, 1);
+ ErrorF("SetupMouse: got %02x\n", c);
+ }
+#else
+ if (xf86WriteSerial(pInfo->fd, param, paramlen) != paramlen)
+ xf86Msg(X_ERROR, "%s: Write to mouse failed\n", pInfo->name);
+#endif
+ usleep(30000);
+ xf86FlushInput(pInfo->fd);
+ }
+ if (pMse->class & (MSE_PS2 | MSE_XPS2)) {
+ if (osInfo->SetPS2Res) {
+ osInfo->SetPS2Res(pInfo, pMse->protocol, pMse->sampleRate,
+ pMse->resolution);
+ } else {
+ unsigned char c2[2];
+
+ c = 230; /* 1:1 scaling */
+ xf86WriteSerial(pInfo->fd, &c, 1);
+ c = 244; /* enable mouse */
+ xf86WriteSerial(pInfo->fd, &c, 1);
+ c2[0] = 243; /* set sampling rate */
+ if (pMse->sampleRate > 0) {
+ if (pMse->sampleRate >= 200)
+ c2[1] = 200;
+ else if (pMse->sampleRate >= 100)
+ c2[1] = 100;
+ else if (pMse->sampleRate >= 60)
+ c2[1] = 60;
+ else if (pMse->sampleRate >= 40)
+ c2[1] = 40;
+ else
+ c2[1] = 20;
+ } else {
+ c2[1] = 100;
+ }
+ xf86WriteSerial(pInfo->fd, c2, 2);
+ c2[0] = 232; /* set device resolution */
+ if (pMse->resolution > 0) {
+ if (pMse->resolution >= 200)
+ c2[1] = 3;
+ else if (pMse->resolution >= 100)
+ c2[1] = 2;
+ else if (pMse->resolution >= 50)
+ c2[1] = 1;
+ else
+ c2[1] = 0;
+ } else {
+ c2[1] = 2;
+ }
+ xf86WriteSerial(pInfo->fd, c2, 2);
+ usleep(30000);
+ xf86FlushInput(pInfo->fd);
+ }
+ }
+
+ pMse->protoBufTail = 0;
+ pMse->inSync = 0;
+
+ return TRUE;
+}
+
+static void
+MouseReadInput(InputInfoPtr pInfo)
+{
+ MouseDevPtr pMse;
+ int j, buttons, dx, dy, dz, baddata;
+ int pBufP;
+ int c;
+ unsigned char *pBuf, u;
+
+ pMse = pInfo->private;
+ pBufP = pMse->protoBufTail;
+ pBuf = pMse->protoBuf;
+
+ /*
+ * Set blocking to -1 on the first call because we know there is data to
+ * read. Xisb automatically clears it after one successful read so that
+ * succeeding reads are preceeded by a select with a 0 timeout to prevent
+ * read from blocking indefinitely.
+ */
+ XisbBlockDuration(pMse->buffer, -1);
+
+#ifdef EXTMOUSEDEBUG2
+ ErrorF("received %d bytes",nBytes);
+ for ( i=0; i < nBytes; i++)
+ ErrorF(" %02x",pMse->buffer[i]);
+ ErrorF("\n");
+#endif
+ while ((c = XisbRead(pMse->buffer)) >= 0) {
+ u = (unsigned char)c;
+ if (pBufP >= pMse->protoPara[4]) {
+ /*
+ * Buffer contains a full packet, which has already been processed:
+ * Empty the buffer and check for optional 4th byte, which will be
+ * processed directly, without being put into the buffer first.
+ */
+ pBufP = 0;
+
+ if ((u & pMse->protoPara[0]) != pMse->protoPara[1] &&
+ (u & pMse->protoPara[5]) == pMse->protoPara[6]) {
+ /*
+ * Hack for Logitech MouseMan Mouse - Middle button
+ *
+ * Unfortunately this mouse has variable length packets: the
+ * standard Microsoft 3 byte packet plus an optional 4th byte
+ * whenever the middle button status changes.
+ *
+ * We have already processed the standard packet with the
+ * movement and button info. Now post an event message with
+ * the old status of the left and right buttons and the
+ * updated middle button.
+ */
+ /*
+ * Even worse, different MouseMen and TrackMen differ in the
+ * 4th byte: some will send 0x00/0x20, others 0x01/0x21, or
+ * even 0x02/0x22, so I have to strip off the lower bits.
+ * [CHRIS-211092]
+ *
+ * [JCH-96/01/21]
+ * HACK for ALPS "fourth button". (It's bit 0x10 of the
+ * "fourth byte" and it is activated by tapping the glidepad
+ * with the finger! 8^) We map it to bit bit3, and the
+ * reverse map in xf86Events just has to be extended so that
+ * it is identified as Button 4. The lower half of the
+ * reverse-map may remain unchanged.
+ */
+ /*
+ * [KAZU-030897]
+ * Receive the fourth byte only when preceeding three bytes
+ * have been detected (pBufP >= pMse->protoPara[4]). In the
+ * previous versions, the test was pBufP == 0; we may have
+ * mistakingly received a byte even if we didn't see anything
+ * preceeding the byte.
+ */
+
+#ifdef EXTMOUSEDEBUG
+ ErrorF("mouse 4th byte %02x",u);
+#endif
+ dx = dy = dz = 0;
+ buttons = 0;
+ switch (pMse->protocolID) {
+
+ /*
+ * [KAZU-221197]
+ * IntelliMouse, NetMouse (including NetMouse Pro) and Mie
+ * Mouse always send the fourth byte, whereas the fourth byte
+ * is optional for GlidePoint and ThinkingMouse. The fourth
+ * byte is also optional for MouseMan+ and FirstMouse+ in
+ * their native mode. It is always sent if they are in the
+ * IntelliMouse compatible mode.
+ */
+ case PROT_IMSERIAL: /* IntelliMouse, NetMouse, Mie Mouse,
+ MouseMan+ */
+ dz = (u & 0x08) ?
+ (u & 0x0f) - 16 : (u & 0x0f);
+ buttons |= ((int)(u & 0x10) >> 3)
+ | ((int)(u & 0x20) >> 2)
+ | (pMse->lastButtons & 0x05);
+ break;
+
+ case PROT_GLIDE:
+ case PROT_THINKING:
+ buttons |= ((int)(u & 0x10) >> 1);
+ /* fall through */
+
+ default:
+ buttons |= ((int)(u & 0x20) >> 4) |
+ (pMse->lastButtons & 0x05);
+ break;
+ }
+ goto post_event;
+ }
+ }
+ /* End of packet buffer flush and 4th byte hack. */
+
+ /*
+ * Append next byte to buffer (which is empty or contains an
+ * incomplete packet); iterate if packet (still) not complete.
+ */
+ pBuf[pBufP++] = u;
+ if (pBufP != pMse->protoPara[4]) continue;
+
+ /*
+ * Hack for resyncing: We check here for a package that is:
+ * a) illegal (detected by wrong data-package header)
+ * b) invalid (0x80 == -128 and that might be wrong for MouseSystems)
+ * c) bad header-package
+ *
+ * NOTE: b) is a violation of the MouseSystems-Protocol, since values
+ * of -128 are allowed, but since they are very seldom we can
+ * easily use them as package-header with no button pressed.
+ * NOTE/2: On a PS/2 mouse any byte is valid as a data byte.
+ * Furthermore, 0x80 is not valid as a header byte. For a PS/2
+ * mouse we skip checking data bytes. For resyncing a PS/2
+ * mouse we require the two most significant bits in the header
+ * byte to be 0. These are the overflow bits, and in case of
+ * an overflow we actually lose sync. Overflows are very rare,
+ * however, and we quickly gain sync again after an overflow
+ * condition. This is the best we can do. (Actually, we could
+ * use bit 0x08 in the header byte for resyncing, since that
+ * bit is supposed to be always on, but nobody told Microsoft...)
+ */
+
+ /*
+ * [KAZU,OYVIND-120398]
+ * The above hack is wrong! Because of b) above, we shall see
+ * erroneous mouse events so often when the MouseSystem mouse is
+ * moved quickly. As for the PS/2 and its variants, we don't need
+ * to treat them as special cases, because protoPara[2] and
+ * protoPara[3] are both 0x00 for them, thus, any data bytes will
+ * never be discarded. 0x80 is rejected for MMSeries, Logitech
+ * and MMHittab protocols, because protoPara[2] and protoPara[3]
+ * are 0x80 and 0x00 respectively. The other protocols are 7-bit
+ * protocols; there is no use checking 0x80.
+ *
+ * All in all we should check the condition a) only.
+ */
+
+ /*
+ * [OYVIND-120498]
+ * Check packet for valid data:
+ * If driver is in sync with datastream, the packet is considered
+ * bad if any byte (header and/or data) contains an invalid value.
+ *
+ * If packet is bad, we discard the first byte and shift the buffer.
+ * Next iteration will then check the new situation for validity.
+ *
+ * If flag MF_SAFE is set in proto[7] and the driver
+ * is out of sync, the packet is also considered bad if
+ * any of the data bytes contains a valid header byte value.
+ * This situation could occur if the buffer contains
+ * the tail of one packet and the header of the next.
+ *
+ * Note: The driver starts in out-of-sync mode (pMse->inSync = 0).
+ */
+
+ baddata = 0;
+
+ /* All databytes must be valid. */
+ for (j = 1; j < pBufP; j++ )
+ if ((pBuf[j] & pMse->protoPara[2]) != pMse->protoPara[3])
+ baddata = 1;
+
+ /* If out of sync, don't mistake a header byte for data. */
+ if ((pMse->protoPara[7] & MPF_SAFE) && !pMse->inSync)
+ for (j = 1; j < pBufP; j++ )
+ if ((pBuf[j] & pMse->protoPara[0]) == pMse->protoPara[1])
+ baddata = 1;
+
+ /* Accept or reject the packet ? */
+ if ((pBuf[0] & pMse->protoPara[0]) != pMse->protoPara[1] || baddata) {
+#ifdef EXTMOUSEDEBUG
+ if (pMse->inSync)
+ ErrorF("mouse driver lost sync\n");
+ ErrorF("skipping byte %02x\n",*pBuf);
+#endif
+ pMse->protoBufTail = --pBufP;
+ for (j = 0; j < pBufP; j++)
+ pBuf[j] = pBuf[j+1];
+ pMse->inSync = 0;
+ continue;
+ }
+
+ if (!pMse->inSync) {
+#ifdef EXTMOUSEDEBUG
+ ErrorF("mouse driver back in sync\n");
+#endif
+ pMse->inSync = 1;
+ }
+
+ /*
+ * Packet complete and verified, now process it ...
+ */
+
+ dz = 0;
+ switch (pMse->protocolID) {
+ case PROT_LOGIMAN: /* MouseMan / TrackMan [CHRIS-211092] */
+ case PROT_MS: /* Microsoft */
+ if (pMse->chordMiddle)
+ buttons = (((int) pBuf[0] & 0x30) == 0x30) ? 2 :
+ ((int)(pBuf[0] & 0x20) >> 3)
+ | ((int)(pBuf[0] & 0x10) >> 4);
+ else
+ buttons = (pMse->lastButtons & 2)
+ | ((int)(pBuf[0] & 0x20) >> 3)
+ | ((int)(pBuf[0] & 0x10) >> 4);
+ dx = (char)(((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F));
+ dy = (char)(((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F));
+ break;
+
+ case PROT_GLIDE: /* ALPS GlidePoint */
+ case PROT_THINKING: /* ThinkingMouse */
+ case PROT_IMSERIAL: /* IntelliMouse, NetMouse, Mie Mouse, MouseMan+ */
+ buttons = (pMse->lastButtons & (8 + 2))
+ | ((int)(pBuf[0] & 0x20) >> 3)
+ | ((int)(pBuf[0] & 0x10) >> 4);
+ dx = (char)(((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F));
+ dy = (char)(((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F));
+ break;
+
+ case PROT_MSC: /* Mouse Systems Corp */
+ buttons = (~pBuf[0]) & 0x07;
+ dx = (char)(pBuf[1]) + (char)(pBuf[3]);
+ dy = - ((char)(pBuf[2]) + (char)(pBuf[4]));
+ break;
+
+ case PROT_MMHIT: /* MM_HitTablet */
+ buttons = pBuf[0] & 0x07;
+ if (buttons != 0)
+ buttons = 1 << (buttons - 1);
+ dx = (pBuf[0] & 0x10) ? pBuf[1] : - pBuf[1];
+ dy = (pBuf[0] & 0x08) ? - pBuf[2] : pBuf[2];
+ break;
+
+ case PROT_ACECAD: /* ACECAD */
+ /* ACECAD is almost exactly like MM but the buttons are different */
+ buttons = (pBuf[0] & 0x02) | ((pBuf[0] & 0x04) >> 2) |
+ ((pBuf[0] & 1) << 2);
+ dx = (pBuf[0] & 0x10) ? pBuf[1] : - pBuf[1];
+ dy = (pBuf[0] & 0x08) ? - pBuf[2] : pBuf[2];
+ break;
+
+ case PROT_MM: /* MM Series */
+ case PROT_LOGI: /* Logitech Mice */
+ buttons = pBuf[0] & 0x07;
+ dx = (pBuf[0] & 0x10) ? pBuf[1] : - pBuf[1];
+ dy = (pBuf[0] & 0x08) ? - pBuf[2] : pBuf[2];
+ break;
+
+ case PROT_BM: /* BusMouse */
+ buttons = (~pBuf[0]) & 0x07;
+ dx = (char)pBuf[1];
+ dy = - (char)pBuf[2];
+ break;
+
+ case PROT_PS2: /* PS/2 mouse */
+ buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */
+ (pBuf[0] & 0x02) >> 1 | /* Right */
+ (pBuf[0] & 0x01) << 2; /* Left */
+ dx = (pBuf[0] & 0x10) ? (int)pBuf[1]-256 : (int)pBuf[1];
+ dy = (pBuf[0] & 0x20) ? -((int)pBuf[2]-256) : -(int)pBuf[2];
+ break;
+
+ /* PS/2 mouse variants */
+ case PROT_IMPS2: /* IntelliMouse PS/2 */
+ case PROT_NETPS2: /* NetMouse PS/2 */
+ buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */
+ (pBuf[0] & 0x02) >> 1 | /* Right */
+ (pBuf[0] & 0x01) << 2; /* Left */
+ dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1];
+ dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2];
+ dz = (char)pBuf[3];
+ break;
+
+ case PROT_MMPS2: /* MouseMan+ PS/2 */
+ buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */
+ (pBuf[0] & 0x02) >> 1 | /* Right */
+ (pBuf[0] & 0x01) << 2; /* Left */
+ dx = (pBuf[0] & 0x10) ? pBuf[1] - 256 : pBuf[1];
+ if (((pBuf[0] & 0x48) == 0x48) &&
+ (abs(dx) > 191) &&
+ ((((pBuf[2] & 0x03) << 2) | 0x02) == (pBuf[1] & 0x0f))) {
+ /* extended data packet */
+ switch ((((pBuf[0] & 0x30) >> 2) | ((pBuf[1] & 0x30) >> 4))) {
+ case 1: /* wheel data packet */
+ buttons |= ((pBuf[2] & 0x10) ? 0x08 : 0) | /* 4th button */
+ ((pBuf[2] & 0x20) ? 0x10 : 0); /* 5th button */
+ dx = dy = 0;
+ dz = (pBuf[2] & 0x08) ? (pBuf[2] & 0x0f) - 16 :
+ (pBuf[2] & 0x0f);
+ break;
+ case 0: /* device type packet - shouldn't happen */
+ case 2: /* reserved packet - shouldn't happen */
+ default:
+ buttons |= (pMse->lastButtons & ~0x07);
+ dx = dy = 0;
+ dz = 0;
+ break;
+ }
+ } else {
+ buttons |= (pMse->lastButtons & ~0x07);
+ dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1];
+ dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2];
+ }
+ break;
+
+ case PROT_GLIDEPS2: /* GlidePoint PS/2 */
+ buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */
+ (pBuf[0] & 0x02) >> 1 | /* Right */
+ (pBuf[0] & 0x01) << 2 | /* Left */
+ ((pBuf[0] & 0x08) ? 0 : 0x08);/* fourth button */
+ dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1];
+ dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2];
+ break;
+
+ case PROT_NETSCPS2: /* NetScroll PS/2 */
+ buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */
+ (pBuf[0] & 0x02) >> 1 | /* Right */
+ (pBuf[0] & 0x01) << 2 | /* Left */
+ ((pBuf[3] & 0x02) ? 0x08 : 0);/* fourth button */
+ dx = (pBuf[0] & 0x10) ? pBuf[1]-256 : pBuf[1];
+ dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2];
+ dz = (pBuf[3] & 0x10) ? pBuf[4] - 256 : pBuf[4];
+ break;
+
+ case PROT_THINKPS2: /* ThinkingMouse PS/2 */
+ buttons = (pBuf[0] & 0x04) >> 1 | /* Middle */
+ (pBuf[0] & 0x02) >> 1 | /* Right */
+ (pBuf[0] & 0x01) << 2 | /* Left */
+ ((pBuf[0] & 0x08) ? 0x08 : 0);/* fourth button */
+ pBuf[1] |= (pBuf[0] & 0x40) ? 0x80 : 0x00;
+ dx = (pBuf[0] & 0x10) ? pBuf[1] : pBuf[1];
+ dy = (pBuf[0] & 0x20) ? -(pBuf[2]-256) : -pBuf[2];
+ break;
+
+ case PROT_SYSMOUSE: /* sysmouse */
+ buttons = (~pBuf[0]) & 0x07;
+ dx = (char)(pBuf[1]) + (char)(pBuf[3]);
+ dy = - ((char)(pBuf[2]) + (char)(pBuf[4]));
+ /* FreeBSD sysmouse sends additional data bytes */
+ if (pMse->protoPara[4] >= 8) {
+ dz = ((char)(pBuf[5] << 1) + (char)(pBuf[6] << 1)) / 2;
+ buttons |= (int)(~pBuf[7] & 0x07) << 3;
+ }
+ break;
+
+ default: /* There's a table error */
+#ifdef EXTMOUSEDEBUG
+ ErrorF("mouse table error\n");
+#endif
+ continue;
+ }
+
+#ifdef EXTMOUSEDEBUG
+ ErrorF("packet");
+ for ( j=0; j < pBufP; j++)
+ ErrorF(" %02x",pBuf[j]);
+#endif
+
+post_event:
+ /* post an event */
+ pMse->PostEvent(pInfo, buttons, dx, dy, dz);
+
+ /*
+ * We don't reset pBufP here yet, as there may be an additional data
+ * byte in some protocols. See above.
+ */
+ }
+ pMse->protoBufTail = pBufP;
+}
+
+/*
+ * MouseCtrl --
+ * Alter the control parameters for the mouse. Note that all special
+ * protocol values are handled by dix.
+ */
+
+static void
+MouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl)
+{
+ InputInfoPtr pInfo;
+ MouseDevPtr pMse;
+
+ pInfo = device->public.devicePrivate;
+ pMse = pInfo->private;
+
+#ifdef EXTMOUSEDEBUG
+ ErrorF("MouseCtrl pMse=%p\n", pMse);
+#endif
+
+ pMse->num = ctrl->num;
+ pMse->den = ctrl->den;
+ pMse->threshold = ctrl->threshold;
+}
+
+/*
+ ***************************************************************************
+ *
+ * MouseProc --
+ *
+ ***************************************************************************
+ */
+static int
+MouseProc(DeviceIntPtr device, int what)
+{
+ InputInfoPtr pInfo;
+ MouseDevPtr pMse;
+ unsigned char map[MSE_MAXBUTTONS + 1];
+ int i;
+
+ pInfo = device->public.devicePrivate;
+ pMse = pInfo->private;
+ pMse->device = device;
+
+ switch (what)
+ {
+ case DEVICE_INIT:
+ device->public.on = FALSE;
+ /*
+ * [KAZU-241097] We don't know exactly how many buttons the
+ * device has, so setup the map with the maximum number.
+ */
+ for (i = 0; i < MSE_MAXBUTTONS; i++)
+ map[i + 1] = i + 1;
+
+ InitPointerDeviceStruct((DevicePtr)device, map,
+ min(pMse->buttons, MSE_MAXBUTTONS),
+ miPointerGetMotionEvents, pMse->Ctrl,
+ miPointerGetMotionBufferSize());
+
+ /* X valuator */
+ xf86InitValuatorAxisStruct(device, 0, 0, -1, 1, 0, 1);
+ xf86InitValuatorDefaults(device, 0);
+ /* Y valuator */
+ xf86InitValuatorAxisStruct(device, 1, 0, -1, 1, 0, 1);
+ xf86InitValuatorDefaults(device, 1);
+ xf86MotionHistoryAllocate(pInfo);
+
+#ifdef EXTMOUSEDEBUG
+ ErrorF("assigning %p atom=%d name=%s\n", device, pInfo->atom,
+ pInfo->name);
+#endif
+ break;
+
+ case DEVICE_ON:
+ pInfo->fd = xf86OpenSerial(pInfo->options);
+ if (pInfo->fd == -1)
+ xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
+ else {
+ pMse->buffer = XisbNew(pInfo->fd, 64);
+ if (!pMse->buffer) {
+ xf86CloseSerial(pInfo->fd);
+ pInfo->fd = -1;
+ } else {
+ if (!SetupMouse(pInfo)) {
+ xf86CloseSerial(pInfo->fd);
+ pInfo->fd = -1;
+ XisbFree(pMse->buffer);
+ pMse->buffer = NULL;
+ } else {
+ xf86FlushInput(pInfo->fd);
+ if (pMse->protocolID == PROT_PS2)
+ xf86WriteSerial(pInfo->fd, "\364", 1);
+ AddEnabledDevice(pInfo->fd);
+ }
+ }
+ }
+ pMse->lastButtons = 0;
+ pMse->emulateState = 0;
+ device->public.on = TRUE;
+ break;
+
+ case DEVICE_OFF:
+ case DEVICE_CLOSE:
+ if (pInfo->fd != -1) {
+ RemoveEnabledDevice(pInfo->fd);
+ if (pMse->buffer) {
+ XisbFree(pMse->buffer);
+ pMse->buffer = NULL;
+ }
+ xf86CloseSerial(pInfo->fd);
+ pInfo->fd = -1;
+ }
+ device->public.on = FALSE;
+ usleep(300000);
+ break;
+ }
+ return Success;
+}
+
+/*
+ ***************************************************************************
+ *
+ * MouseConvert --
+ * Convert valuators to X and Y.
+ *
+ ***************************************************************************
+ */
+static Bool
+MouseConvert(InputInfoPtr pInfo, int first, int num, int v0, int v1, int v2,
+ int v3, int v4, int v5, int *x, int *y)
+{
+ if (first != 0 || num != 2)
+ return FALSE;
+
+ *x = v0;
+ *y = v1;
+
+ return TRUE;
+}
+
+static CARD32
+buttonTimer(OsTimerPtr timer, CARD32 now, pointer arg)
+{
+ InputInfoPtr pInfo;
+ MouseDevPtr pMse;
+
+ pInfo = arg;
+ pMse = pInfo->private;
+
+ pMse->PostEvent(pInfo, pMse->truebuttons, 0, 0, 0);
+ return 0;
+}
+
+/*
+ * Lets create a simple finite-state machine:
+ *
+ * state[?][0]: action1
+ * state[?][1]: action2
+ * state[?][2]: next state
+ *
+ * action > 0: ButtonPress
+ * action = 0: nothing
+ * action < 0: ButtonRelease
+ *
+ * Why this stuff ??? Normally you cannot press both mousebuttons together, so
+ * the mouse reports both pressed at the same time ...
+ */
+
+static signed char stateTab[48][3] = {
+
+/* nothing pressed */
+ { 0, 0, 0 },
+ { 0, 0, 8 }, /* 1 right -> delayed right */
+ { 0, 0, 0 }, /* 2 nothing */
+ { 0, 0, 8 }, /* 3 right -> delayed right */
+ { 0, 0, 16 }, /* 4 left -> delayed left */
+ { 2, 0, 24 }, /* 5 left & right (middle press) -> middle pressed */
+ { 0, 0, 16 }, /* 6 left -> delayed left */
+ { 2, 0, 24 }, /* 7 left & right (middle press) -> middle pressed */
+
+/* delayed right */
+ { 1, -1, 0 }, /* 8 nothing (right event) -> init */
+ { 1, 0, 32 }, /* 9 right (right press) -> right pressed */
+ { 1, -1, 0 }, /* 10 nothing (right event) -> init */
+ { 1, 0, 32 }, /* 11 right (right press) -> right pressed */
+ { 1, -1, 16 }, /* 12 left (right event) -> delayed left */
+ { 2, 0, 24 }, /* 13 left & right (middle press) -> middle pressed */
+ { 1, -1, 16 }, /* 14 left (right event) -> delayed left */
+ { 2, 0, 24 }, /* 15 left & right (middle press) -> middle pressed */
+
+/* delayed left */
+ { 3, -3, 0 }, /* 16 nothing (left event) -> init */
+ { 3, -3, 8 }, /* 17 right (left event) -> delayed right */
+ { 3, -3, 0 }, /* 18 nothing (left event) -> init */
+ { 3, -3, 8 }, /* 19 right (left event) -> delayed right */
+ { 3, 0, 40 }, /* 20 left (left press) -> pressed left */
+ { 2, 0, 24 }, /* 21 left & right (middle press) -> pressed middle */
+ { 3, 0, 40 }, /* 22 left (left press) -> pressed left */
+ { 2, 0, 24 }, /* 23 left & right (middle press) -> pressed middle */
+
+/* pressed middle */
+ { -2, 0, 0 }, /* 24 nothing (middle release) -> init */
+ { -2, 0, 0 }, /* 25 right (middle release) -> init */
+ { -2, 0, 0 }, /* 26 nothing (middle release) -> init */
+ { -2, 0, 0 }, /* 27 right (middle release) -> init */
+ { -2, 0, 0 }, /* 28 left (middle release) -> init */
+ { 0, 0, 24 }, /* 29 left & right -> pressed middle */
+ { -2, 0, 0 }, /* 30 left (middle release) -> init */
+ { 0, 0, 24 }, /* 31 left & right -> pressed middle */
+
+/* pressed right */
+ { -1, 0, 0 }, /* 32 nothing (right release) -> init */
+ { 0, 0, 32 }, /* 33 right -> pressed right */
+ { -1, 0, 0 }, /* 34 nothing (right release) -> init */
+ { 0, 0, 32 }, /* 35 right -> pressed right */
+ { -1, 0, 16 }, /* 36 left (right release) -> delayed left */
+ { -1, 2, 24 }, /* 37 left & right (r rel, m prs) -> middle pressed */
+ { -1, 0, 16 }, /* 38 left (right release) -> delayed left */
+ { -1, 2, 24 }, /* 39 left & right (r rel, m prs) -> middle pressed */
+
+/* pressed left */
+ { -3, 0, 0 }, /* 40 nothing (left release) -> init */
+ { -3, 0, 8 }, /* 41 right (left release) -> delayed right */
+ { -3, 0, 0 }, /* 42 nothing (left release) -> init */
+ { -3, 0, 8 }, /* 43 right (left release) -> delayed right */
+ { 0, 0, 40 }, /* 44 left -> left pressed */
+ { -3, 2, 24 }, /* 45 left & right (l rel, mprs) -> middle pressed */
+ { 0, 0, 40 }, /* 46 left -> left pressed */
+ { -3, 2, 24 }, /* 47 left & right (l rel, mprs) -> middle pressed */
+};
+
+
+/*
+ * Table to allow quick reversal of natural button mapping to correct mapping
+ */
+
+/*
+ * [JCH-96/01/21] The ALPS GlidePoint pad extends the MS protocol
+ * with a fourth button activated by tapping the PAD.
+ * The 2nd line corresponds to 4th button on; the drv sends
+ * the buttons in the following map (MSBit described first) :
+ * 0 | 4th | 1st | 2nd | 3rd
+ * And we remap them (MSBit described first) :
+ * 0 | 4th | 3rd | 2nd | 1st
+ */
+static char reverseMap[32] = { 0, 4, 2, 6, 1, 5, 3, 7,
+ 8, 12, 10, 14, 9, 13, 11, 15,
+ 16, 20, 18, 22, 17, 21, 19, 23,
+ 24, 28, 26, 30, 25, 29, 27, 31};
+
+
+static char hitachMap[16] = { 0, 2, 1, 3,
+ 8, 10, 9, 11,
+ 4, 6, 5, 7,
+ 12, 14, 13, 15 };
+
+#define reverseBits(map, b) (((b) & ~0x0f) | map[(b) & 0x0f])
+
+static void
+MouseDoPostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy)
+{
+ static OsTimerPtr timer = NULL;
+ MouseDevPtr pMse;
+ int truebuttons;
+ int id, change;
+
+ pMse = pInfo->private;
+
+ truebuttons = buttons;
+ if (pMse->protocolID == PROT_MMHIT)
+ buttons = reverseBits(hitachMap, buttons);
+ else
+ buttons = reverseBits(reverseMap, buttons);
+
+ if (dx || dy)
+ xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy);
+
+ if (pMse->emulate3Buttons) {
+ /*
+ * Hack to operate the middle button even with Emulate3Buttons set.
+ * Modifying the state table to keep track of the middle button state
+ * would nearly double its size, so I'll stick with this fix. - TJW
+ */
+ if (pMse->protocolID == PROT_MMHIT)
+ change = buttons ^ reverseBits(hitachMap, pMse->lastButtons);
+ else
+ change = buttons ^ reverseBits(reverseMap, pMse->lastButtons);
+ if (change & 02)
+ xf86PostButtonEvent(pInfo->dev, 0, 2, (buttons & 02), 0, 0);
+
+ /*
+ * emulate the third button by the other two
+ */
+ if ((id = stateTab[(buttons & 0x07) + pMse->emulateState][0]) != 0)
+ xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0);
+
+ if ((id = stateTab[(buttons & 0x07) + pMse->emulateState][1]) != 0)
+ xf86PostButtonEvent(pInfo->dev, 0, abs(id), (id >= 0), 0, 0);
+
+ pMse->emulateState = stateTab[(buttons & 0x07) + pMse->emulateState][2];
+ if (stateTab[(buttons & 0x07) + pMse->emulateState][0] ||
+ stateTab[(buttons & 0x07) + pMse->emulateState][1]) {
+ pMse->truebuttons = truebuttons;
+ timer = TimerSet(timer, 0, pMse->emulate3Timeout, buttonTimer,
+ pInfo);
+ } else {
+ if (timer) {
+ TimerFree(timer);
+ timer = NULL;
+ }
+ }
+ } else {
+ /*
+ * real three button event
+ * Note that pMse.lastButtons has the hardware button mapping which
+ * is the reverse of the button mapping reported to the server.
+ */
+ if (pMse->protocolID == PROT_MMHIT)
+ change = buttons ^ reverseBits(hitachMap, pMse->lastButtons);
+ else
+ change = buttons ^ reverseBits(reverseMap, pMse->lastButtons);
+ while (change) {
+ id = ffs(change);
+ change &= ~(1 << (id - 1));
+ xf86PostButtonEvent(pInfo->dev, 0, id,
+ (buttons & (1 << (id - 1))), 0, 0);
+ }
+ }
+ pMse->lastButtons = truebuttons;
+
+}
+
+static void
+MousePostEvent(InputInfoPtr pInfo, int buttons, int dx, int dy, int dz)
+{
+ MouseDevPtr pMse;
+ int zbutton = 0;
+
+
+ pMse = pInfo->private;
+
+ /* Map the Z axis movement. */
+ /* XXX Could this go in the conversion_proc? */
+ switch (pMse->negativeZ) {
+ case MSE_NOZMAP: /* do nothing */
+ break;
+ case MSE_MAPTOX:
+ if (dz != 0) {
+ dx = dz;
+ dz = 0;
+ }
+ break;
+ case MSE_MAPTOY:
+ if (dz != 0) {
+ dy = dz;
+ dz = 0;
+ }
+ break;
+ default: /* buttons */
+ buttons &= ~(pMse->negativeZ | pMse->positiveZ);
+ if (dz < 0)
+ zbutton = pMse->negativeZ;
+ else if (dz > 0)
+ zbutton = pMse->positiveZ;
+ buttons |= zbutton;
+ dz = 0;
+ break;
+ }
+
+ MouseDoPostEvent(pInfo, buttons, dx, dy);
+
+ /*
+ * If dz has been mapped to a button `down' event, we need to cook up
+ * a corresponding button `up' event.
+ */
+ if (zbutton) {
+ buttons &= ~zbutton;
+ MouseDoPostEvent(pInfo, buttons, 0, 0);
+ }
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/input/mouse/mouse.h b/xc/programs/Xserver/hw/xfree86/input/mouse/mouse.h
new file mode 100644
index 000000000..c70211958
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/mouse/mouse.h
@@ -0,0 +1,53 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/mouse/mouse.h,v 1.7 1999/06/05 15:55:27 dawes Exp $ */
+
+/*
+ * Copyright (c) 1997-1999 by The XFree86 Project, Inc.
+ */
+
+#ifndef _X_MOUSE_H
+#define _X_MOUSE_H
+
+/* Private interface for the mouse driver. */
+
+/* Protocol IDs. These are for internal use only. */
+typedef enum {
+ PROT_UNKNOWN = -2,
+ PROT_UNSUP = -1, /* protocol is not supported */
+ PROT_MS = 0,
+ PROT_MSC,
+ PROT_MM,
+ PROT_LOGI,
+ PROT_LOGIMAN,
+ PROT_MMHIT,
+ PROT_GLIDE,
+ PROT_IMSERIAL,
+ PROT_THINKING,
+ PROT_ACECAD,
+ PROT_PS2,
+ PROT_IMPS2,
+ PROT_THINKPS2,
+ PROT_MMPS2,
+ PROT_GLIDEPS2,
+ PROT_NETPS2,
+ PROT_NETSCPS2,
+ PROT_BM,
+ PROT_AUTO,
+ PROT_SYSMOUSE,
+ PROT_NUMPROTOS /* This must always be last. */
+} ProtocolID;
+
+typedef struct {
+ const char * name;
+ int class;
+ const char ** defaults;
+ ProtocolID id;
+} MouseProtocolRec, *MouseProtocolPtr;
+
+/* mouse proto flags */
+#define MPF_NONE 0x00
+#define MPF_SAFE 0x01
+
+/* pnp.c */
+int MouseGetPnpProtocol(InputInfoPtr pInfo);
+
+#endif /* _X_MOUSE_H */
diff --git a/xc/programs/Xserver/hw/xfree86/input/mouse/pnp.c b/xc/programs/Xserver/hw/xfree86/input/mouse/pnp.c
new file mode 100644
index 000000000..ba1b241f5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/mouse/pnp.c
@@ -0,0 +1,476 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/mouse/pnp.c,v 1.6 1999/07/10 12:17:37 dawes Exp $ */
+
+/*
+ * Copyright 1998 by Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Kazutaka YOKOTA not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Kazutaka YOKOTA makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * KAZUTAKA YOKOTA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KAZUTAKA YOKOTA 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_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86Xinput.h"
+#include "xf86OSmouse.h"
+#include "mouse.h"
+
+/* serial PnP ID string */
+typedef struct {
+ int revision; /* PnP revision, 100 for 1.00 */
+ char *eisaid; /* EISA ID including mfr ID and product ID */
+ char *serial; /* serial No, optional */
+ char *class; /* device class, optional */
+ char *compat; /* list of compatible drivers, optional */
+ char *description; /* product description, optional */
+ int neisaid; /* length of the above fields... */
+ int nserial;
+ int nclass;
+ int ncompat;
+ int ndescription;
+} pnpid_t;
+
+/* symbol table entry */
+typedef struct {
+ char *name;
+ int val;
+} symtab_t;
+
+/* PnP EISA/product IDs */
+static symtab_t pnpprod[] = {
+ { "KML0001", PROT_THINKING }, /* Kensignton ThinkingMouse */
+ { "MSH0001", PROT_IMSERIAL }, /* MS IntelliMouse */
+ { "MSH0004", PROT_IMSERIAL }, /* MS IntelliMouse TrackBall */
+ { "KYEEZ00", PROT_MS }, /* Genius EZScroll */
+ { "KYE0001", PROT_MS }, /* Genius PnP Mouse */
+ { "KYE0003", PROT_IMSERIAL }, /* Genius NetMouse */
+ { "LGI800C", PROT_IMSERIAL }, /* Logitech MouseMan (4 button model) */
+ { "LGI8050", PROT_IMSERIAL }, /* Logitech MouseMan+ */
+ { "LGI8051", PROT_IMSERIAL }, /* Logitech FirstMouse+ */
+ { "LGI8001", PROT_LOGIMAN }, /* Logitech serial */
+
+ { "PNP0F00", PROT_BM }, /* MS bus */
+ { "PNP0F01", PROT_MS }, /* MS serial */
+ { "PNP0F02", PROT_BM }, /* MS InPort */
+ { "PNP0F03", PROT_PS2 }, /* MS PS/2 */
+ /*
+ * EzScroll returns PNP0F04 in the compatible device field; but it
+ * doesn't look compatible... XXX
+ */
+ { "PNP0F04", PROT_MSC }, /* MouseSystems */
+ { "PNP0F05", PROT_MSC }, /* MouseSystems */
+#ifdef notyet
+ { "PNP0F06", PROT_??? }, /* Genius Mouse */
+ { "PNP0F07", PROT_??? }, /* Genius Mouse */
+#endif
+ { "PNP0F08", PROT_LOGIMAN }, /* Logitech serial */
+ { "PNP0F09", PROT_MS }, /* MS BallPoint serial */
+ { "PNP0F0A", PROT_MS }, /* MS PnP serial */
+ { "PNP0F0B", PROT_MS }, /* MS PnP BallPoint serial */
+ { "PNP0F0C", PROT_MS }, /* MS serial comatible */
+ { "PNP0F0D", PROT_BM }, /* MS InPort comatible */
+ { "PNP0F0E", PROT_PS2 }, /* MS PS/2 comatible */
+ { "PNP0F0F", PROT_MS }, /* MS BallPoint comatible */
+#ifdef notyet
+ { "PNP0F10", PROT_??? }, /* TI QuickPort */
+#endif
+ { "PNP0F11", PROT_BM }, /* MS bus comatible */
+ { "PNP0F12", PROT_PS2 }, /* Logitech PS/2 */
+ { "PNP0F13", PROT_PS2 }, /* PS/2 */
+#ifdef notyet
+ { "PNP0F14", PROT_??? }, /* MS Kids Mouse */
+#endif
+ { "PNP0F15", PROT_BM }, /* Logitech bus */
+#ifdef notyet
+ { "PNP0F16", PROT_??? }, /* Logitech SWIFT */
+#endif
+ { "PNP0F17", PROT_LOGIMAN }, /* Logitech serial compat */
+ { "PNP0F18", PROT_BM }, /* Logitech bus compatible */
+ { "PNP0F19", PROT_PS2 }, /* Logitech PS/2 compatible */
+#ifdef notyet
+ { "PNP0F1A", PROT_??? }, /* Logitech SWIFT compatible */
+ { "PNP0F1B", PROT_??? }, /* HP Omnibook */
+ { "PNP0F1C", PROT_??? }, /* Compaq LTE TrackBall PS/2 */
+ { "PNP0F1D", PROT_??? }, /* Compaq LTE TrackBall serial */
+ { "PNP0F1E", PROT_??? }, /* MS Kids Trackball */
+#endif
+ { NULL, -1 },
+};
+
+static const char *pnpSerial[] = {
+ "BaudRate", "1200",
+ "DataBits", "7",
+ "StopBits", "1",
+ "Parity", "None",
+ "FlowControl", "None",
+ "VTime", "0",
+ "VMin", "1",
+ NULL
+};
+
+static int pnpgets(InputInfoPtr, char *);
+static int pnpparse(InputInfoPtr, pnpid_t *, char *, int);
+static symtab_t *pnpproto(pnpid_t *);
+static symtab_t *gettoken(symtab_t *, char *, int);
+
+int
+MouseGetPnpProtocol(InputInfoPtr pInfo)
+{
+ char buf[256]; /* PnP ID string may be up to 256 bytes long */
+ pnpid_t pnpid;
+ symtab_t *t;
+ int len;
+
+ if (((len = pnpgets(pInfo, buf)) <= 0) ||
+ !pnpparse(pInfo, &pnpid, buf, len))
+ return -1;
+ if ((t = pnpproto(&pnpid)) == NULL)
+ return -1;
+ xf86MsgVerb(X_INFO, 2, "%s: PnP-detected protocol ID: %d\n",
+ pInfo->name, t->val);
+ return (t->val);
+}
+
+/*
+ * Try to elicit a PnP ID as described in
+ * Microsoft, Hayes: "Plug and Play External COM Device Specification,
+ * rev 1.00", 1995.
+ *
+ * The routine does not fully implement the COM Enumerator as per Section
+ * 2.1 of the document. In particular, we don't have idle state in which
+ * the driver software monitors the com port for dynamic connection or
+ * removal of a device at the port, because `moused' simply quits if no
+ * device is found.
+ *
+ * In addition, as PnP COM device enumeration procedure slightly has
+ * changed since its first publication, devices which follow earlier
+ * revisions of the above spec. may fail to respond if the rev 1.0
+ * procedure is used. XXX
+ */
+static int
+pnpgets(InputInfoPtr pInfo, char *buf)
+{
+ int i;
+ char c;
+ pointer pnpOpts;
+
+#if 0
+ /*
+ * This is the procedure described in rev 1.0 of PnP COM device spec.
+ * Unfortunately, some devices which comform to earlier revisions of
+ * the spec gets confused and do not return the ID string...
+ */
+
+ /* port initialization (2.1.2) */
+ if ((i = xf86GetSerialModemState(pInfo->fd)) == -1)
+ return 0;
+ i |= XF86_M_DTR; /* DTR = 1 */
+ i &= ~XF86_M_RTS; /* RTS = 0 */
+ if (xf86SetSerialModemState(pInfo->fd, i) == -1)
+ goto disconnect_idle;
+ usleep(200000);
+ if ((i = xf86GetSerialModemState(pInfo->fd)) == -1 ||
+ (i & XF86_M_DSR) == 0)
+ goto disconnect_idle;
+
+ /* port setup, 1st phase (2.1.3) */
+ pnpOpts = xf86OptionListCreate(pnpSerial, -1, 1);
+ xf86SetSerial(pInfo->fd, pnpOpts);
+ i = TIOCM_DTR | TIOCM_RTS; /* DTR = 0, RTS = 0 */
+ xf86SerialModemClearBits(pInfo->fd, i);
+ usleep(200000);
+ i = TIOCM_DTR; /* DTR = 1, RTS = 0 */
+ xf86SerialModemSetBits(pInfo->fd, i);
+ usleep(200000);
+
+ /* wait for response, 1st phase (2.1.4) */
+ xf86FlushInput(pInfo->fd);
+ i = TIOCM_RTS; /* DTR = 1, RTS = 1 */
+ xf86SerialModemSetBits(pInfo->fd, i);
+
+ /* try to read something */
+ if (xf86WaitForInput(pInfo->fd, 200000) <= 0) {
+
+ /* port setup, 2nd phase (2.1.5) */
+ i = TIOCM_DTR | TIOCM_RTS; /* DTR = 0, RTS = 0 */
+ xf86SerialModemClearBits(pInfo->fd, i);
+ usleep(200000);
+
+ /* wait for respose, 2nd phase (2.1.6) */
+ xf86FlushInput(pInfo->fd);
+ i = TIOCM_DTR | TIOCM_RTS; /* DTR = 1, RTS = 1 */
+ xf86SerialModemSetBits(pInfo->fd, i);
+
+ /* try to read something */
+ if (xf86WaitForInput(pInfo->fd, 200000) <= 0)
+ goto connect_idle;
+ }
+#else
+ /*
+ * This is a simplified procedure; it simply toggles RTS.
+ */
+
+ if ((i = xf86GetSerialModemState(pInfo->fd)) == -1)
+ return 0;
+ i |= XF86_M_DTR; /* DTR = 1 */
+ i &= ~XF86_M_RTS; /* RTS = 0 */
+ if (xf86SetSerialModemState(pInfo->fd, i) == -1)
+ goto disconnect_idle;
+ usleep(200000);
+
+ pnpOpts = xf86OptionListCreate(pnpSerial, -1, 1);
+ xf86SetSerial(pInfo->fd, pnpOpts);
+
+ /* wait for respose */
+ xf86FlushInput(pInfo->fd);
+ i = XF86_M_DTR | XF86_M_RTS; /* DTR = 1, RTS = 1 */
+ xf86SerialModemSetBits(pInfo->fd, i);
+
+ /* try to read something */
+ if (xf86WaitForInput(pInfo->fd, 200000) <= 0)
+ goto connect_idle;
+#endif
+
+ /* collect PnP COM device ID (2.1.7) */
+ i = 0;
+ usleep(200000); /* the mouse must send `Begin ID' within 200msec */
+ while (xf86ReadSerial(pInfo->fd, &c, 1) == 1) {
+ /* we may see "M", or "M3..." before `Begin ID' */
+ if ((c == 0x08) || (c == 0x28)) { /* Begin ID */
+ buf[i++] = c;
+ break;
+ }
+ if (xf86WaitForInput(pInfo->fd, 200000) <= 0)
+ break;
+ }
+ if (i <= 0) {
+ /* we haven't seen `Begin ID' in time... */
+ goto connect_idle;
+ }
+
+ ++c; /* make it `End ID' */
+ for (;;) {
+ if (xf86WaitForInput(pInfo->fd, 200000) <= 0)
+ break;
+
+ xf86ReadSerial(pInfo->fd, &buf[i], 1);
+ if (buf[i++] == c) /* End ID */
+ break;
+ if (i >= 256)
+ break;
+ }
+ if (buf[i - 1] != c)
+ goto connect_idle;
+ return i;
+
+ /*
+ * According to PnP spec, we should set DTR = 1 and RTS = 0 while
+ * in idle state. But, `moused' shall set DTR = RTS = 1 and proceed,
+ * assuming there is something at the port even if it didn't
+ * respond to the PnP enumeration procedure.
+ */
+disconnect_idle:
+ i = XF86_M_DTR | XF86_M_RTS; /* DTR = 1, RTS = 1 */
+ xf86SerialModemSetBits(pInfo->fd, i);
+connect_idle:
+ return 0;
+}
+
+static int
+pnpparse(InputInfoPtr pInfo, pnpid_t *id, char *buf, int len)
+{
+ char s[3];
+ int offset;
+ int sum = 0;
+ int i, j;
+
+ id->revision = 0;
+ id->eisaid = NULL;
+ id->serial = NULL;
+ id->class = NULL;
+ id->compat = NULL;
+ id->description = NULL;
+ id->neisaid = 0;
+ id->nserial = 0;
+ id->nclass = 0;
+ id->ncompat = 0;
+ id->ndescription = 0;
+
+ offset = 0x28 - buf[0];
+
+ /* calculate checksum */
+ for (i = 0; i < len - 3; ++i) {
+ sum += buf[i];
+ buf[i] += offset;
+ }
+ sum += buf[len - 1];
+ for (; i < len; ++i)
+ buf[i] += offset;
+ xf86MsgVerb(X_INFO, 2, "%s: PnP ID string: `%*.*s'\n", pInfo->name,
+ len, len, buf);
+
+ /* revision */
+ buf[1] -= offset;
+ buf[2] -= offset;
+ id->revision = ((buf[1] & 0x3f) << 6) | (buf[2] & 0x3f);
+ xf86MsgVerb(X_INFO, 2, "%s: PnP rev %d.%02d\n", pInfo->name,
+ id->revision / 100, id->revision % 100);
+
+ /* EISA vender and product ID */
+ id->eisaid = &buf[3];
+ id->neisaid = 7;
+
+ /* option strings */
+ i = 10;
+ if (buf[i] == '\\') {
+ /* device serial # */
+ for (j = ++i; i < len; ++i) {
+ if (buf[i] == '\\')
+ break;
+ }
+ if (i >= len)
+ i -= 3;
+ if (i - j == 8) {
+ id->serial = &buf[j];
+ id->nserial = 8;
+ }
+ }
+ if (buf[i] == '\\') {
+ /* PnP class */
+ for (j = ++i; i < len; ++i) {
+ if (buf[i] == '\\')
+ break;
+ }
+ if (i >= len)
+ i -= 3;
+ if (i > j + 1) {
+ id->class = &buf[j];
+ id->nclass = i - j;
+ }
+ }
+ if (buf[i] == '\\') {
+ /* compatible driver */
+ for (j = ++i; i < len; ++i) {
+ if (buf[i] == '\\')
+ break;
+ }
+ /*
+ * PnP COM spec prior to v0.96 allowed '*' in this field,
+ * it's not allowed now; just ignore it.
+ */
+ if (buf[j] == '*')
+ ++j;
+ if (i >= len)
+ i -= 3;
+ if (i > j + 1) {
+ id->compat = &buf[j];
+ id->ncompat = i - j;
+ }
+ }
+ if (buf[i] == '\\') {
+ /* product description */
+ for (j = ++i; i < len; ++i) {
+ if (buf[i] == ';')
+ break;
+ }
+ if (i >= len)
+ i -= 3;
+ if (i > j + 1) {
+ id->description = &buf[j];
+ id->ndescription = i - j;
+ }
+ }
+
+ /* checksum exists if there are any optional fields */
+ if ((id->nserial > 0) || (id->nclass > 0)
+ || (id->ncompat > 0) || (id->ndescription > 0)) {
+ xf86MsgVerb(X_INFO, 4, "PnP checksum: 0x%02X\n", pInfo->name, sum);
+ sprintf(s, "%02X", sum & 0x0ff);
+ if (strncmp(s, &buf[len - 3], 2) != 0) {
+#if 0
+ /*
+ * Checksum error!!
+ * I found some mice do not comply with the PnP COM device
+ * spec regarding checksum... XXX
+ */
+ return FALSE;
+#endif
+ }
+ }
+
+ return TRUE;
+}
+
+static symtab_t *
+pnpproto(pnpid_t *id)
+{
+ symtab_t *t;
+ int i, j;
+
+ if (id->nclass > 0)
+ if (strncmp(id->class, "MOUSE", id->nclass) != 0)
+ /* this is not a mouse! */
+ return NULL;
+
+ if (id->neisaid > 0) {
+ t = gettoken(pnpprod, id->eisaid, id->neisaid);
+ if (t->val != -1)
+ return t;
+ }
+
+ /*
+ * The 'Compatible drivers' field may contain more than one
+ * ID separated by ','.
+ */
+ if (id->ncompat <= 0)
+ return NULL;
+ for (i = 0; i < id->ncompat; ++i) {
+ for (j = i; id->compat[i] != ','; ++i)
+ if (i >= id->ncompat)
+ break;
+ if (i > j) {
+ t = gettoken(pnpprod, id->compat + j, i - j);
+ if (t->val != -1)
+ return t;
+ }
+ }
+
+ return NULL;
+}
+
+/* name/val mapping */
+
+static symtab_t *
+gettoken(tab, s, len)
+symtab_t *tab;
+char *s;
+int len;
+{
+ int i;
+
+ for (i = 0; tab[i].name != NULL; ++i) {
+ if (strncmp(tab[i].name, s, len) == 0)
+ break;
+ }
+ return &tab[i];
+}
diff --git a/xc/programs/Xserver/hw/xfree86/input/mutouch/Imakefile b/xc/programs/Xserver/hw/xfree86/input/mutouch/Imakefile
new file mode 100644
index 000000000..073ef10dc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/mutouch/Imakefile
@@ -0,0 +1,26 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/mutouch/Imakefile,v 1.2 1999/08/14 10:50:02 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = xf86MuTouch.c
+OBJS = xf86MuTouch.o
+
+DRIVER = mutouch
+
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86SRC)/loader -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(SERVERSRC)/mi -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget($(DRIVER),$(OBJS))
+
+InstallObjectModule($(DRIVER),$(MODULEDIR),input)
+
+DependTarget()
+
+InstallDriverSDKObjectModule($(DRIVER),$(DRIVERSDKMODULEDIR),input)
diff --git a/xc/programs/Xserver/hw/xfree86/input/mutouch/xf86MuTouch.c b/xc/programs/Xserver/hw/xfree86/input/mutouch/xf86MuTouch.c
new file mode 100644
index 000000000..aeb623e90
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/mutouch/xf86MuTouch.c
@@ -0,0 +1,1626 @@
+/*
+ * Copyright 1996, 1999 by Patrick Lecoanet, France. <lecoanet@cena.dgac.fr>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Patrick Lecoanet not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Patrick Lecoanet makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * PATRICK LECOANET DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL PATRICK LECOANET BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/mutouch/xf86MuTouch.c,v 1.6 1999/06/13 05:18:55 dawes Exp $ */
+
+/*
+ *******************************************************************************
+ *******************************************************************************
+ *
+ * This driver is able to deal with MicrotTouch serial controllers using
+ * firmware set 2. This includes (but may not be limited to) Serial/SMT3
+ * and TouchPen controllers. The only data format supported is Mode Tablet
+ * as it is the only available with these controllers. Anyway this is not a big
+ * lost as it is the most efficient (by far) and is supported by all controllers.
+ *
+ * The code has been lifted from the Elographics driver in xf86Elo.c.
+ *
+ *******************************************************************************
+ *******************************************************************************
+ */
+
+#include <xf86Version.h>
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(3,9,0,0,0)
+#define XFREE86_V4
+#endif
+
+#ifdef XFREE86_V4
+#include <misc.h>
+#include <xf86.h>
+#include <xf86_ansic.h>
+#include <xf86_OSproc.h>
+#include <xf86Xinput.h>
+#include <exevents.h>
+
+#else /* XFREE86_V4 */
+
+#include "Xos.h"
+#include <signal.h>
+#include <stdio.h>
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "XI.h"
+#include "XIproto.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Procs.h"
+#include "xf86_OSlib.h"
+#include "xf86_Config.h"
+#include "xf86Xinput.h"
+#include "xf86Version.h"
+
+#include "os.h"
+#include "osdep.h"
+#include "exevents.h"
+
+#include "extnsionst.h"
+#include "extinit.h"
+
+#endif /* XFREE86_V4 */
+
+
+#ifndef XFREE86_V4
+/*
+ ***************************************************************************
+ *
+ * Configuration descriptor.
+ *
+ ***************************************************************************
+ */
+#define FINGER_SECTION_NAME "microtouchfinger"
+#define STYLUS_SECTION_NAME "microtouchstylus"
+
+#define PORT 1
+#define DEVICENAME 2
+#define SCREEN_NO 3
+#define MAXX 5
+#define MAXY 6
+#define MINX 7
+#define MINY 8
+#define DEBUG_LEVEL 9
+#define HISTORY_SIZE 10
+#define LINK_SPEED 11
+#define ALWAYS_CORE 12
+
+static SymTabRec MuTTab[] = {
+ { ENDSUBSECTION, "endsubsection" },
+ { PORT, "port" },
+ { DEVICENAME, "devicename" },
+ { SCREEN_NO, "screenno" },
+ { MAXX, "maximumxposition" },
+ { MAXY, "maximumyposition" },
+ { MINX, "minimumxposition" },
+ { MINY, "minimumyposition" },
+ { DEBUG_LEVEL, "debuglevel" },
+ { HISTORY_SIZE, "historysize" },
+ { LINK_SPEED, "linkspeed" },
+ { ALWAYS_CORE, "alwayscore" },
+ { -1, "" },
+};
+
+#define LS300 1
+#define LS1200 2
+#define LS2400 3
+#define LS9600 4
+#define LS19200 5
+
+static SymTabRec LinkSpeedTab[] = {
+ { LS300, "b300" },
+ { LS1200, "b1200" },
+ { LS2400, "b2400" },
+ { LS9600, "b9600" },
+ { LS19200, "b19200" }
+};
+
+
+/*
+ * This struct connects a line speed with
+ * a compatible motion packet delay. The
+ * driver will attempt to enforce a correct
+ * delay (according to this table) in order to
+ * avoid losing data in the touchscreen controller.
+ * LinkSpeedValues should be kept in sync with
+ * LinkSpeedTab.
+ */
+typedef struct {
+ int speed;
+ int delay;
+} LinkParameterStruct;
+
+static LinkParameterStruct LinkSpeedValues[] = {
+ { B300, 64 },
+ { B1200, 16 },
+ { B2400, 8 },
+ { B9600, 4 },
+ { B19200, 2 }
+};
+#endif /* XFREE86_V4 */
+
+
+/*
+ ***************************************************************************
+ *
+ * Default constants.
+ *
+ ***************************************************************************
+ */
+#define MuT_MAX_TRIALS 5 /* Number of timeouts waiting for a */
+ /* pending reply. */
+#define MuT_MAX_WAIT 300000 /* Max wait time for a reply (microsec) */
+#define MuT_LINK_SPEED B9600 /* 9600 Bauds */
+#define MuT_PORT "/dev/ttyS1"
+
+#define DEFAULT_MAX_X 3000
+#define DEFAULT_MIN_X 600
+#define DEFAULT_MAX_Y 3000
+#define DEFAULT_MIN_Y 600
+
+#define XI_FINGER "FINGER" /* X device name for the finger device */
+#define XI_STYLUS "STYLUS" /* X device name for the stylus device */
+
+
+/*
+ ***************************************************************************
+ *
+ * Protocol constants.
+ *
+ ***************************************************************************
+ */
+#define MuT_REPORT_SIZE 5 /* Size of a report packet. */
+#define MuT_BUFFER_SIZE 256 /* Size of input buffer. */
+#define MuT_PACKET_SIZE 10 /* Maximum size of a command/reply *including* */
+ /* the leading and trailing bytes. */
+
+#define MuT_LEAD_BYTE 0x01 /* First byte of a command/reply packet. */
+#define MuT_TRAIL_BYTE 0x0D /* Last byte of a command/reply packet. */
+
+/*
+ * Commands.
+ */
+#define MuT_RESET "R" /* Reset the controller. */
+#define MuT_RESTORE_DEFAULTS "RD" /* Restore factory settings. */
+#define MuT_FORMAT_TABLET "FT" /* Report events using tablet format. */
+#define MuT_FORMAT_RAW "FR" /* Report events in raw mode (no corrections). */
+#define MuT_CALIBRATE_RAW "CR" /* Calibration in raw mode. */
+#define MuT_CALIBRATE_EXT "CX" /* Calibration in extended mode (cooked). */
+#define MuT_OUTPUT_IDENT "OI" /* Ask some infos about the firmware. */
+#define MuT_UNIT_TYPE "UT" /* Ask some more infos about the firmware. */
+#define MuT_FINGER_ONLY "FO" /* Send reports only if a finger is touching. */
+#define MuT_PEN_ONLY "PO" /* Send reports only if a pen is touching. */
+#define MuT_PEN_FINGER "PF" /* Always send reports. */
+#define MuT_MODE_STREAM "MS" /* Receive reports in stream mode (continuous). */
+
+/*
+ * Command reply values.
+ */
+#define MuT_OK '0' /* Report success. */
+#define MuT_ERROR '1' /* Report error. */
+
+/*
+ * Offsets in status byte of touch and motion reports.
+ */
+#define MuT_SW1 0x01 /* State of switch 1 (TouchPen only). */
+#define MuT_SW2 0x02 /* State of switch 2 (TouchPen only). */
+#define MuT_WHICH_DEVICE 0x20 /* If report is from pen or from finger. */
+#define MuT_CONTACT 0x40 /* Report touch/untouch with touchscreen. */
+
+/*
+ * Identity and friends.
+ */
+#define MuT_TOUCH_PEN_IDENT "P5"
+#define MuT_SMT3_IDENT "Q1"
+
+
+/*
+ ***************************************************************************
+ *
+ * Usefull macros.
+ *
+ ***************************************************************************
+ */
+#define WORD_ASSEMBLY(byte1, byte2) (((byte2) << 7) | (byte1))
+#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
+
+/* This one is handy, thanx Fred ! */
+#ifdef DBG
+#undef DBG
+#endif
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+static int debug_level = 0;
+#define DEBUG 1
+#if DEBUG
+#define DBG(lvl, f) {if ((lvl) <= debug_level) f;}
+#else
+#define DBG(lvl, f)
+#endif
+
+#ifdef XFREE86_V4
+#undef SYSCALL
+#undef read
+#undef write
+#undef close
+#define SYSCALL(call) call
+#define read(fd, ptr, num) xf86ReadSerial(fd, ptr, num)
+#define write(fd, ptr, num) xf86WriteSerial(fd, ptr, num)
+#define close(fd) xf86CloseSerial(fd)
+#endif
+
+
+/*
+ ***************************************************************************
+ *
+ * Device private records.
+ *
+ ***************************************************************************
+ */
+#define FINGER_ID 1
+#define STYLUS_ID 2
+#define DEVICE_ID(flags) ((flags) & 0x03)
+
+typedef struct _MuTPrivateRec {
+ char *input_dev; /* The touchscreen input tty */
+ int min_x; /* Minimum x reported by calibration */
+ int max_x; /* Maximum x */
+ int min_y; /* Minimum y reported by calibration */
+ int max_y; /* Maximum y */
+#ifndef XFREE86_V4
+ int link_speed; /* Speed of the RS232 link connecting the ts. */
+#endif
+ int screen_no; /* Screen associated with the device */
+ int screen_width; /* Width of the associated X screen */
+ int screen_height; /* Height of the screen */
+ Bool inited; /* The controller has already been configured ? */
+ char state; /* Current state of report flags. */
+ int num_old_bytes; /* Number of bytes left in receive buffer. */
+ LocalDevicePtr finger; /* Finger device ptr associated with the hw. */
+ LocalDevicePtr stylus; /* Stylus device ptr associated with the hw. */
+ unsigned char rec_buf[MuT_BUFFER_SIZE]; /* Receive buffer. */
+} MuTPrivateRec, *MuTPrivatePtr;
+
+
+#ifndef XFREE86_V4
+/*
+ ***************************************************************************
+ *
+ * xf86MuTConfig --
+ * Configure the driver from the configuration data.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86MuTConfig(LocalDevicePtr *array,
+ int inx,
+ int max,
+ LexPtr val)
+{
+ LocalDevicePtr local = array[inx];
+ MuTPrivatePtr priv = (MuTPrivatePtr)(local->private);
+ int token;
+
+ while ((token = xf86GetToken(MuTTab)) != ENDSUBSECTION) {
+ switch(token) {
+
+ case PORT:
+ if (xf86GetToken(NULL) != STRING)
+ xf86ConfigError("MicroTouch input port expected");
+ else {
+ /*
+ * See if another X device share the same physical
+ * device and set up the links so that they share
+ * the same private structure (the one that controls
+ * the physical device).
+ */
+ int i;
+ for (i = 0; i < max; i++) {
+ if (i == inx)
+ continue;
+ if (array[i]->device_config == xf86MuTConfig &&
+ (strcmp(((MuTPrivatePtr) array[i]->private)->input_dev,
+ val->str) == 0)) {
+ ErrorF("%s MicroTouch config detected a device share between %s and %s\n",
+ XCONFIG_GIVEN, local->type_name, array[i]->name);
+ xfree(priv);
+ priv = local->private = array[i]->private;
+ switch (DEVICE_ID(local->private_flags)) {
+ case FINGER_ID:
+ priv->finger = local;
+ break;
+ case STYLUS_ID:
+ priv->stylus = local;
+ break;
+ }
+ break;
+ }
+ }
+ if (i == max) {
+ priv->input_dev = strdup(val->str);
+ if (xf86Verbose)
+ ErrorF("%s MicroTouch %s input port: %s\n",
+ XCONFIG_GIVEN, local->type_name, priv->input_dev);
+ }
+ }
+ break;
+
+ case DEVICENAME:
+ if (xf86GetToken(NULL) != STRING)
+ xf86ConfigError("MicroTouch device name expected");
+ local->name = strdup(val->str);
+ if (xf86Verbose)
+ ErrorF("%s MicroTouch %s X device name: %s\n",
+ XCONFIG_GIVEN, local->type_name, local->name);
+ break;
+
+ case SCREEN_NO:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("MicroTouch screen number expected");
+ priv->screen_no = val->num;
+ if (xf86Verbose)
+ ErrorF("%s MicroTouch %s associated screen: %d\n",
+ XCONFIG_GIVEN, local->type_name, priv->screen_no);
+ break;
+
+ case LINK_SPEED:
+ {
+ int ltoken = xf86GetToken(LinkSpeedTab);
+ if (ltoken == EOF ||
+ ltoken == STRING ||
+ ltoken == NUMBER)
+ xf86ConfigError("MicroTouch link speed expected");
+ priv->link_speed = LinkSpeedValues[ltoken-1].speed;
+ if (xf86Verbose)
+ ErrorF("%s MicroTouch %s link speed: %s bps\n",
+ XCONFIG_GIVEN, local->type_name, (LinkSpeedTab[ltoken-1].name)+1);
+ }
+ break;
+
+ case MAXX:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("MicroTouch maximum x position expected");
+ priv->max_x = val->num;
+ if (xf86Verbose)
+ ErrorF("%s MicroTouch %s maximum x position: %d\n",
+ XCONFIG_GIVEN, local->type_name, priv->max_x);
+ break;
+
+ case MAXY:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("MicroTouch maximum y position expected");
+ priv->max_y = val->num;
+ if (xf86Verbose)
+ ErrorF("%s Microtouch %s maximum y position: %d\n",
+ XCONFIG_GIVEN, local->type_name, priv->max_y);
+ break;
+
+ case MINX:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("MicroTouch minimum x position expected");
+ priv->min_x = val->num;
+ if (xf86Verbose)
+ ErrorF("%s MicroTouch %s minimum x position: %d\n",
+ XCONFIG_GIVEN, local->type_name, priv->min_x);
+ break;
+
+ case MINY:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("MicroTouch minimum y position expected");
+ priv->min_y = val->num;
+ if (xf86Verbose)
+ ErrorF("%s MicroTouch %s minimum y position: %d\n",
+ XCONFIG_GIVEN, local->type_name, priv->min_y);
+ break;
+
+ case DEBUG_LEVEL:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("MicroTouch driver debug expected");
+ debug_level = val->num;
+ if (xf86Verbose) {
+#if DEBUG
+ ErrorF("%s MicroTouch %s debug level sets to %d\n", XCONFIG_GIVEN,
+ local->type_name, debug_level);
+#else
+ ErrorF("%s MicroTouch %s debug not available\n",
+ XCONFIG_GIVEN, local->type_name, debug_level);
+#endif
+ }
+ break;
+
+ case HISTORY_SIZE:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("MicroTouch motion history size expected");
+ local->history_size = val->num;
+ if (xf86Verbose)
+ ErrorF("%s MicroTouch %s motion history size is %d\n", XCONFIG_GIVEN,
+ local->type_name, local->history_size);
+ break;
+
+ case ALWAYS_CORE:
+ xf86AlwaysCore(local, TRUE);
+ if (xf86Verbose)
+ ErrorF("%s MicroTouch %s device will always stays core pointer\n",
+ local->type_name, XCONFIG_GIVEN);
+ break;
+
+ case EOF:
+ FatalError("Unexpected EOF (missing EndSubSection)");
+ break;
+
+ default:
+ xf86ConfigError("MicroTouch subsection keyword expected");
+ break;
+ }
+ }
+
+ if (priv->max_x - priv->min_x <=0) {
+ priv->max_x = DEFAULT_MAX_X;
+ priv->min_x = DEFAULT_MIN_X;
+ ErrorF("%s MicroTouch: Incorrect Maximum/Minimum x position, using: %d, %d\n",
+ XCONFIG_GIVEN, priv->max_x, priv->min_x);
+ }
+ if (priv->max_y - priv->min_y <=0) {
+ priv->max_y = DEFAULT_MAX_Y;
+ priv->min_y = DEFAULT_MIN_Y;
+ ErrorF("%s MicroTouch: Incorrect Maximum/Minimum y position, using: %d, %d\n",
+ XCONFIG_GIVEN, priv->max_y, priv->min_y);
+ }
+
+ DBG(2, ErrorF("xf86MuTConfig port name=%s\n", priv->input_dev))
+
+ return Success;
+}
+#endif
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86MuTConvert --
+ * Convert extended valuators to x and y suitable for core motion
+ * events. Return True if ok and False if the requested conversion
+ * can't be done for the specified valuators.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86MuTConvert(LocalDevicePtr local,
+ int first,
+ int num,
+ int v0,
+ int v1,
+ int v2,
+ int v3,
+ int v4,
+ int v5,
+ int *x,
+ int *y)
+{
+ MuTPrivatePtr priv = (MuTPrivatePtr) local->private;
+ int width = priv->max_x - priv->min_x;
+ int height = priv->max_y - priv->min_y;
+
+ if (first != 0 || num != 2)
+ return FALSE;
+
+ *x = (priv->screen_width * (v0 - priv->min_x)) / width;
+ *y = (priv->screen_height -
+ (priv->screen_height * (v1 - priv->min_y)) / height);
+
+#ifdef XFREE86_V4
+ /*
+ * Need to check if still on the correct screen.
+ * This call is here so that this work can be done after
+ * calib and before posting the event.
+ */
+ xf86XInputSetScreen(local, priv->screen_no, *x, *y);
+#endif
+
+ return TRUE;
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86MuTReadInput --
+ * Read a buffer full of input from the touchscreen and enqueue
+ * all report packets found in it.
+ * If a packet is not fully received it is deferred until the next
+ * call to the function.
+ * Packet recognized by this function comply with the format :
+ *
+ * Byte 1 : Status flags with MSB set to 1
+ * Byte 2 : X coordinate (lower bits)
+ * Byte 3 : X coordinate (upper bits)
+ * Byte 4 : Y coordinate (lower bits)
+ * Byte 5 : Y coordinate (upper bits)
+ *
+ * The routine can work with any of the two X device structs associated
+ * with the touchscreen. It is always possible to find the relevant
+ * informations and to emit the events for both devices if provided
+ * with one of the two structs. This point is relevant only if the
+ * two devices are actives at the same time.
+ *
+
+ ***************************************************************************
+ */
+static void
+xf86MuTReadInput(LocalDevicePtr local)
+{
+ MuTPrivatePtr priv = (MuTPrivatePtr)(local->private);
+ int cur_x, cur_y;
+ int state;
+ int num_bytes;
+ int bytes_in_packet;
+ unsigned char *ptr, *start_ptr;
+
+ DBG(4, ErrorF("Entering ReadInput\n"));
+
+ /*
+ * Try to get a buffer full of report packets.
+ */
+ DBG(4, ErrorF("num_old_bytes is %d, Trying to read %d bytes from port\n",
+ priv->num_old_bytes, MuT_BUFFER_SIZE - priv->num_old_bytes));
+ SYSCALL(num_bytes = read(local->fd,
+ (char *) (priv->rec_buf + priv->num_old_bytes),
+ MuT_BUFFER_SIZE - priv->num_old_bytes));
+ if (num_bytes < 0) {
+ Error("System error while reading from MicroTouch touchscreen.");
+ return;
+ }
+
+ DBG(4, ErrorF("Read %d bytes of reports\n", num_bytes));
+ num_bytes += priv->num_old_bytes;
+ ptr = priv->rec_buf;
+ bytes_in_packet = 0;
+ start_ptr = ptr;
+
+ while (num_bytes >= (MuT_REPORT_SIZE-bytes_in_packet)) {
+ /*
+ * Skip bytes until a status byte (MSB set to 1).
+ */
+ if (bytes_in_packet == 0) {
+ if ((ptr[0] & 0x80) == 0) {
+ DBG(3, ErrorF("Dropping a byte in an attempt to synchronize a report packet: 0x%X\n",
+ ptr[0]));
+ start_ptr++;
+ }
+ else {
+ bytes_in_packet++;
+ }
+ num_bytes--;
+ ptr++;
+ }
+ else if (bytes_in_packet != 5) {
+ if ((ptr[0] & 0x80) == 0) {
+ bytes_in_packet++;
+ }
+ else {
+ /*
+ * Reset the start of packet, we have most certainly
+ * lost some data.
+ */
+ DBG(3, ErrorF("Reseting start of report packet data has been lost\n"));
+ bytes_in_packet = 1;
+ start_ptr = ptr;
+ }
+ ptr++;
+ num_bytes--;
+ }
+
+ if (bytes_in_packet == 5) {
+ LocalDevicePtr local_to_use;
+
+ /*
+ * First stick together the various pieces.
+ */
+ state = start_ptr[0] & 0x7F;
+ cur_x = WORD_ASSEMBLY(start_ptr[1], start_ptr[2]);
+ cur_y = WORD_ASSEMBLY(start_ptr[3], start_ptr[4]);
+
+ DBG(3, ErrorF("Packet: 0x%X 0x%X 0x%X 0x%X 0x%X\n",
+ start_ptr[0], start_ptr[1], start_ptr[2], start_ptr[3], start_ptr[4]));
+ start_ptr = ptr;
+ bytes_in_packet = 0;
+
+ /*
+ * Send events.
+ *
+ * We *must* generate a motion before a button change if pointer
+ * location has changed as DIX assumes this. This is why we always
+ * emit a motion, regardless of the kind of packet processed.
+ */
+ local_to_use = (state & MuT_WHICH_DEVICE) ? priv->stylus : priv->finger;
+
+ /*
+ * Emit a motion. If in core pointer mode we need to calibrate
+ * or we will feed X with quite bogus event positions.
+ */
+ xf86PostMotionEvent(local_to_use->dev, TRUE, 0, 2, cur_x, cur_y);
+
+ /*
+ * Emit a button press or release.
+ */
+ if ((state & MuT_CONTACT) != (priv->state & MuT_CONTACT)) {
+ xf86PostButtonEvent(local_to_use->dev, TRUE, 1, state & MuT_CONTACT,
+ 0, 2, cur_x, cur_y);
+ }
+
+ DBG(3, ErrorF("TouchScreen %s: x(%d), y(%d), %s\n",
+ ((state & MuT_WHICH_DEVICE) ? "Stylus" : "Finger"),
+ cur_x, cur_y,
+ (((state & MuT_CONTACT) != (priv->state & MuT_CONTACT)) ?
+ ((state & MuT_CONTACT) ? "Press" : "Release") : "Stream")));
+
+ priv->state = state;
+ }
+ }
+
+ /*
+ * If some bytes are left in the buffer, pack them at the
+ * beginning for the next turn.
+ */
+ if (num_bytes != 0) {
+ memcpy(priv->rec_buf, ptr, num_bytes);
+ priv->num_old_bytes = num_bytes;
+ }
+ else {
+ priv->num_old_bytes = 0;
+ }
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86MuTSendPacket --
+ * Emit a variable length packet to the controller.
+ * The function expects a valid buffer containing the
+ * command to be sent to the controller. The command
+ * size is in len
+ * The buffer is filled with the leading and trailing
+ * character before sending.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86MuTSendPacket(unsigned char *packet,
+ int len,
+ int fd)
+{
+ int result;
+
+ packet[0] = MuT_LEAD_BYTE;
+ packet[len+1] = MuT_TRAIL_BYTE;
+
+ DBG(4, ErrorF("Sending packet : 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X \n",
+ packet[0], packet[1], packet[2], packet[3], packet[4],
+ packet[5], packet[6], packet[7], packet[8], packet[9]));
+ SYSCALL(result = write(fd, packet, len+2));
+ if (result != len+2) {
+ DBG(5, ErrorF("System error while sending to MicroTouch touchscreen.\n"));
+ return !Success;
+ }
+ else {
+ return Success;
+ }
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86MuTGetReply --
+ * Read a reply packet from the port. Synchronize with start and stop
+ * of packet.
+ * The packet structure read by this function is as follow:
+ * Byte 0 : MuT_LEAD_BYTE
+ * Byte 1
+ * ...
+ * Byte n : packet data
+ * Byte n+1 : MuT_TRAIL_BYTE
+ *
+ * This function returns if a valid packet has been assembled in
+ * buffer or if no more data is available to do so.
+ *
+ * Returns Success if a packet is successfully assembled.
+ * Bytes preceding the MuT_LEAD_BYTE are discarded.
+ * Returns !Success if out of data while reading. The start of the
+ * partially assembled packet is left in buffer, buffer_p reflects
+ * the current state of assembly. Buffer should at least have room
+ * for MuT_BUFFER_SIZE bytes.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86MuTGetReply(unsigned char *buffer,
+ int *buffer_p,
+ int fd)
+{
+ int num_bytes;
+
+ DBG(4, ErrorF("Entering xf86MuTGetReply with buffer_p == %d\n", *buffer_p));
+
+ /*
+ * Try to read enough bytes to fill up the packet buffer.
+ */
+ DBG(4, ErrorF("buffer_p is %d, Trying to read %d bytes from port\n",
+ *buffer_p, MuT_BUFFER_SIZE - *buffer_p));
+ SYSCALL(num_bytes = read(fd,
+ (char *) (buffer + *buffer_p),
+ MuT_BUFFER_SIZE - *buffer_p));
+
+ /*
+ * Okay, give up.
+ */
+ if (num_bytes < 0) {
+ Error("System error while reading from MicroTouch touchscreen.");
+ return !Success;
+ }
+ DBG(4, ErrorF("Read %d bytes of reply\n", num_bytes));
+
+ while (num_bytes) {
+ /*
+ * Sync with the start of a packet.
+ */
+ if ((*buffer_p == 0) && (buffer[0] != MuT_LEAD_BYTE)) {
+ /*
+ * No match, shift data one byte toward the start of the buffer.
+ */
+ DBG(4, ErrorF("Dropping one byte in an attempt to synchronize: '%c' 0x%X\n",
+ buffer[0], buffer[0]));
+ memcpy(&buffer[0], &buffer[1], num_bytes-1);
+ num_bytes--;
+ }
+ else if (buffer[*buffer_p] == MuT_TRAIL_BYTE) {
+ /*
+ * Got a packet, report it.
+ */
+ *buffer_p = 0;
+ return Success;
+ }
+ else {
+ num_bytes--;
+ (*buffer_p)++;
+ }
+ }
+
+ return !Success;
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86MuTWaitReply --
+ * It is assumed that the reply will be in the few next bytes
+ * read and will be available very soon after the command post. if
+ * these two asumptions are not met, there are chances that the server
+ * will be stuck for a while.
+ * The reply is left in reply. The function returns Success if a valid
+ * reply was found and !Success otherwise. Reply should at least
+ * have room for MuT_BUFFER_SIZE bytes.
+ *
+ ***************************************************************************
+ */
+#ifndef XFREE86_V4
+static int
+xf86WaitForInput(int fd,
+ int timeout)
+{
+ fd_set readfds;
+ struct timeval to;
+ int r;
+
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+ to.tv_sec = 0;
+ to.tv_usec = timeout;
+
+ SYSCALL(r = select(FD_SETSIZE, &readfds, NULL, NULL, &to));
+ return r;
+}
+#endif
+
+static Bool
+xf86MuTWaitReply(unsigned char *reply,
+ int fd)
+{
+ Bool ok;
+ int i, result;
+ int reply_p = 0;
+ unsigned char local_reply[3];
+
+ DBG(4, ErrorF("Waiting a reply\n"));
+ i = MuT_MAX_TRIALS;
+ do {
+ ok = !Success;
+
+ /*
+ * Wait half a second for the reply. The fuse counts down each
+ * timeout and each wrong packet.
+ */
+ DBG(4, ErrorF("Waiting %d ms for data from port\n", MuT_MAX_WAIT / 1000));
+ result = xf86WaitForInput(fd, MuT_MAX_WAIT);
+ if (result > 0) {
+ if (reply) {
+ ok = xf86MuTGetReply(reply, &reply_p, fd);
+ }
+ else {
+ ok = xf86MuTGetReply(local_reply, &reply_p, fd);
+ if (ok && local_reply[1] != MuT_OK) {
+ DBG(3, ErrorF("Error reported by firmware\n"));
+ ok = !Success;
+ }
+ }
+ }
+ else {
+ DBG(3, ErrorF("No answer from port : %d\n", result));
+ }
+
+ if (result == 0)
+ i--;
+ } while(ok != Success && i);
+
+ return ok;
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86MuTSendCommand --
+ * Emit a command to the controller and blocks until the reply is
+ * read.
+ *
+ * The reply is left in reply. The function returns Success if the
+ * reply is valid and !Success otherwise. Reply should at least
+ * have room for MuT_BUFFER_SIZE bytes.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86MuTSendCommand(unsigned char *request,
+ int len,
+ unsigned char *reply,
+ int fd)
+{
+ Bool ok;
+
+ if (xf86MuTSendPacket(request, len, fd) == Success) {
+ ok = xf86MuTWaitReply(reply, fd);
+ return ok;
+ }
+ else {
+ return !Success;
+ }
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86MuTPrintIdent --
+ * Print type of touchscreen and features on controller board.
+ *
+ ***************************************************************************
+ */
+static void
+xf86MuTPrintIdent(unsigned char *packet)
+{
+ int vers, rev;
+
+#ifdef XFREE86_V4
+ xf86Msg(X_PROBED, "MicroTouch touchscreen is a ");
+ if (strncmp((char *) &packet[1], MuT_TOUCH_PEN_IDENT, 2) == 0) {
+ xf86Msg(X_NONE, "TouchPen");
+ }
+ else if (strncmp((char *) &packet[1], MuT_SMT3_IDENT, 2) == 0) {
+ xf86Msg(X_NONE, "Serial/SMT3");
+ }
+ xf86Msg(X_NONE, ", connected through a serial port.\n");
+ sscanf((char *) &packet[3], "%2d%2d", &vers, &rev);
+ xf86Msg(X_PROBED, "MicroTouch controller firmware revision is %d.%d.\n", vers, rev);
+#else
+ ErrorF("%s MicroTouch touchscreen is a ", XCONFIG_PROBED);
+ if (strncmp((char *) &packet[1], MuT_TOUCH_PEN_IDENT, 2) == 0) {
+ ErrorF("TouchPen");
+ }
+ else if (strncmp((char *) &packet[1], MuT_SMT3_IDENT, 2) == 0) {
+ ErrorF("Serial/SMT3");
+ }
+ ErrorF(", connected through a serial port.\n");
+ sscanf((char *) &packet[3], "%2d%2d", &vers, &rev);
+ ErrorF("%s MicroTouch controller firmware revision is %d.%d.\n", XCONFIG_PROBED, vers, rev);
+#endif
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86MuTPrintHwStatus --
+ * Print status of hardware. That is if the controller report errors,
+ * decode and display them.
+ *
+ ***************************************************************************
+ */
+static void
+xf86MuTPrintHwStatus(unsigned char *packet)
+{
+#ifdef XFREE86_V4
+ xf86Msg(X_PROBED, "MicroTouch status of errors: %c%c.\n", packet[7], packet[8]);
+#else
+ ErrorF("%s MicroTouch status of errors: %c%c.\n", XCONFIG_PROBED, packet[7], packet[8]);
+#endif
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86MuTPtrControl --
+ *
+ ***************************************************************************
+ */
+#if 0
+static void
+xf86MuTPtrControl(DeviceIntPtr dev,
+ PtrCtrl *ctrl)
+{
+}
+#endif
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86MuTControl --
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86MuTControl(DeviceIntPtr dev,
+ int mode)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ MuTPrivatePtr priv = (MuTPrivatePtr)(local->private);
+ unsigned char map[] = { 0, 1 };
+ unsigned char req[MuT_PACKET_SIZE];
+ unsigned char reply[MuT_BUFFER_SIZE];
+ char *id_string = DEVICE_ID(local->private_flags) == FINGER_ID ? "finger" : "stylus";
+
+ switch(mode) {
+
+ case DEVICE_INIT:
+ {
+ DBG(2, ErrorF("MicroTouch %s init...\n", id_string));
+
+ if (priv->screen_no >= screenInfo.numScreens ||
+ priv->screen_no < 0) {
+ priv->screen_no = 0;
+ }
+ priv->screen_width = screenInfo.screens[priv->screen_no]->width;
+ priv->screen_height = screenInfo.screens[priv->screen_no]->height;
+
+ /*
+ * Device reports button press for up to 1 button.
+ */
+ if (InitButtonClassDeviceStruct(dev, 1, map) == FALSE) {
+ ErrorF("Unable to allocate ButtonClassDeviceStruct\n");
+ return !Success;
+ }
+
+ /*
+ * Device reports motions on 2 axes in absolute coordinates.
+ * Axes min and max values are reported in raw coordinates.
+ * Resolution is computed roughly by the difference between
+ * max and min values scaled from the approximate size of the
+ * screen to fit one meter.
+ */
+ if (InitValuatorClassDeviceStruct(dev, 2, xf86GetMotionEvents,
+ local->history_size, Absolute) == FALSE) {
+ ErrorF("Unable to allocate ValuatorClassDeviceStruct\n");
+ return !Success;
+ }
+ else {
+ InitValuatorAxisStruct(dev, 0, priv->min_x, priv->max_x,
+ 9500,
+ 0 /* min_res */,
+ 9500 /* max_res */);
+ InitValuatorAxisStruct(dev, 1, priv->min_y, priv->max_y,
+ 10500,
+ 0 /* min_res */,
+ 10500 /* max_res */);
+ }
+
+ if (InitFocusClassDeviceStruct(dev) == FALSE) {
+ ErrorF("Unable to allocate FocusClassDeviceStruct\n");
+ }
+
+ /*
+ * Allocate the motion events buffer.
+ */
+ xf86MotionHistoryAllocate(local);
+
+ /*
+ * This once has caused the server to crash after doing an xalloc & strcpy ??
+ */
+#ifndef XFREE86_V4
+ AssignTypeAndName(dev, local->atom, local->name);
+#endif
+
+ DBG(2, ErrorF("Done.\n"));
+ return Success;
+ }
+
+ case DEVICE_ON:
+ {
+ Bool already_open = FALSE;
+ char *report_what = "";
+
+ DBG(2, ErrorF("MicroTouch %s on...\n", id_string));
+
+ /*
+ * Try to see if the port has already been opened either
+ * for this device or for the other one.
+ */
+ if (local->fd >= 0) {
+ already_open = TRUE;
+ }
+ else {
+ switch (DEVICE_ID(local->private_flags)) {
+ case FINGER_ID:
+ if (priv->stylus && priv->stylus->fd >= 0) {
+ already_open = TRUE;
+ local->fd = priv->stylus->fd;
+ }
+ break;
+ case STYLUS_ID:
+ if (priv->finger && priv->finger->fd >= 0) {
+ already_open = TRUE;
+ local->fd = priv->finger->fd;
+ }
+ break;
+ }
+ }
+ if (!already_open) {
+#ifndef XFREE86_V4
+ struct termios termios_tty;
+ int result;
+#endif
+
+ DBG(2, ErrorF("MicroTouch touchscreen opening : %s\n", priv->input_dev));
+#ifdef XFREE86_V4
+ local->fd = xf86OpenSerial(local->options);
+ if (local->fd < 0) {
+ Error("Unable to open MicroTouch touchscreen device");
+ return !Success;
+ }
+#else
+ SYSCALL(local->fd = open(priv->input_dev, O_RDWR|O_NDELAY, 0));
+ if (local->fd < 0) {
+ Error("Unable to open MicroTouch touchscreen device");
+ return !Success;
+ }
+
+ /*
+ * Try to see if the link is at the specified rate and
+ * reset the controller. The wait time needed by the
+ * controller after reset should be compensated by the
+ * timeouts in the receive section.
+ */
+ DBG(3, ErrorF("Try to see if the link is at the specified rate\n"));
+ memset(&termios_tty, 0, sizeof(termios_tty));
+ termios_tty.c_cflag = priv->link_speed | CS8 | CREAD | CLOCAL;
+#ifdef CRTSCTS
+ termios_tty.c_cflag &= ~CRTSCTS;
+#endif
+ termios_tty.c_cc[VMIN] = 1;
+ SYSCALL(result = tcsetattr(local->fd, TCSANOW, &termios_tty));
+ if (result < 0) {
+ Error("Unable to configure MicroTouch touchscreen port");
+ goto not_success;
+ }
+#endif
+ memset(req, 0, MuT_PACKET_SIZE);
+ strncpy((char *) &req[1], MuT_RESET, strlen(MuT_RESET));
+ if (xf86MuTSendCommand(req, strlen(MuT_RESET), NULL, local->fd) != Success) {
+ DBG(3, ErrorF("Not at the specified rate, giving up\n"));
+ goto not_success;
+ }
+
+ /*
+ * ask the controller to report identity and status.
+ */
+ memset(req, 0, MuT_PACKET_SIZE);
+ strncpy((char *) &req[1], MuT_OUTPUT_IDENT, strlen(MuT_OUTPUT_IDENT));
+ if (xf86MuTSendCommand(req, strlen(MuT_OUTPUT_IDENT),
+ reply, local->fd) != Success) {
+ ErrorF("Unable to ask MicroTouch touchscreen identification\n");
+ goto not_success;
+ }
+ xf86MuTPrintIdent(reply);
+ memset(req, 0, MuT_PACKET_SIZE);
+ strncpy((char *) &req[1], MuT_UNIT_TYPE, strlen(MuT_UNIT_TYPE));
+ if (xf86MuTSendCommand(req, strlen(MuT_UNIT_TYPE),
+ reply, local->fd) != Success) {
+ ErrorF("Unable to ask MicroTouch touchscreen status\n");
+ goto not_success;
+ }
+ xf86MuTPrintHwStatus(reply);
+
+ /*
+ * Set the operating mode: Format Tablet, Mode stream, Pen.
+ */
+ memset(req, 0, MuT_PACKET_SIZE);
+ strncpy((char *) &req[1], MuT_FORMAT_TABLET, strlen(MuT_FORMAT_TABLET));
+ if (xf86MuTSendCommand(req, strlen(MuT_FORMAT_TABLET),
+ NULL, local->fd) != Success) {
+ ErrorF("Unable to switch MicroTouch touchscreen to Tablet Format\n");
+ goto not_success;
+ }
+ memset(req, 0, MuT_PACKET_SIZE);
+ strncpy((char *) &req[1], MuT_MODE_STREAM, strlen(MuT_MODE_STREAM));
+ if (xf86MuTSendCommand(req, strlen(MuT_MODE_STREAM),
+ NULL, local->fd) != Success) {
+ ErrorF("Unable to switch MicroTouch touchscreen to Stream Mode\n");
+ goto not_success;
+ }
+
+ memset(req, 0, MuT_PACKET_SIZE);
+ strncpy((char *) &req[1], MuT_PEN_ONLY, strlen(MuT_PEN_ONLY));
+ if (xf86MuTSendCommand(req, strlen(MuT_PEN_ONLY),
+ NULL, local->fd) != Success) {
+ ErrorF("Unable to change MicroTouch touchscreen to pen mode\n");
+ goto not_success;
+ }
+ /* goto not_success;*/
+
+ AddEnabledDevice(local->fd);
+ }
+
+ /*
+ * Select Pen / Finger reports depending on which devices are
+ * currently on.
+ */
+ switch (DEVICE_ID(local->private_flags)) {
+ case FINGER_ID:
+ if (priv->stylus && priv->stylus->dev->public.on) {
+ report_what = MuT_PEN_FINGER;
+ }
+ else {
+ report_what = MuT_FINGER_ONLY;
+ }
+ break;
+ case STYLUS_ID:
+ if (priv->finger && priv->finger->dev->public.on) {
+ report_what = MuT_PEN_FINGER;
+ }
+ else {
+ report_what = MuT_PEN_ONLY;
+ }
+ break;
+ }
+ memset(req, 0, MuT_PACKET_SIZE);
+ strncpy((char *) &req[1], report_what, strlen(report_what));
+ if (xf86MuTSendCommand(req, strlen(report_what), NULL, local->fd) != Success) {
+ ErrorF("Unable to change MicroTouch touchscreen to %s\n",
+ (strcmp(report_what, MuT_PEN_FINGER) == 0) ? "Pen & Finger" :
+ ((strcmp(report_what, MuT_PEN_ONLY) == 0) ? "Pen Only" : "Finger Only"));
+ goto not_success;
+ }
+ dev->public.on = TRUE;
+
+ DBG(2, ErrorF("Done\n"));
+ return Success;
+
+ not_success:
+ SYSCALL(close(local->fd));
+ local->fd = -1;
+ return !Success;
+ }
+
+ /*
+ * Deactivate the device.
+ */
+ case DEVICE_OFF:
+ DBG(2, ErrorF("MicroTouch %s off...\n", id_string));
+ dev->public.on = FALSE;
+ DBG(2, ErrorF("Done\n"));
+ return Success;
+
+ /*
+ * Final close before server exit. This is used during server shutdown.
+ * Close the port and free all the resources.
+ */
+ case DEVICE_CLOSE:
+ DBG(2, ErrorF("MicroTouch %s close...\n", id_string));
+ dev->public.on = FALSE;
+ if (local->fd >= 0) {
+ RemoveEnabledDevice(local->fd);
+ SYSCALL(close(local->fd));
+ local->fd = -1;
+ /*
+ * Need some care to close the port only once.
+ */
+ switch (DEVICE_ID(local->private_flags)) {
+ case FINGER_ID:
+ if (priv->stylus) {
+ priv->stylus->fd = -1;
+ }
+ break;
+ case STYLUS_ID:
+ if (priv->finger) {
+ priv->finger->fd = -1;
+ }
+ }
+ }
+ DBG(2, ErrorF("Done\n"));
+ return Success;
+
+ default:
+ ErrorF("unsupported mode=%d\n", mode);
+ return !Success;
+ }
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86MuTAllocate --
+ *
+ ***************************************************************************
+ */
+static LocalDevicePtr
+xf86MuTAllocate(char *name,
+ char *type_name,
+ int flag)
+{
+ LocalDevicePtr local = (LocalDevicePtr) xalloc(sizeof(LocalDeviceRec));
+ MuTPrivatePtr priv = (MuTPrivatePtr) xalloc(sizeof(MuTPrivateRec));
+
+ if (!local) {
+ if (priv) {
+ xfree(priv);
+ }
+ return NULL;
+ }
+ if (!priv) {
+ if (local) {
+ xfree(local);
+ }
+ return NULL;
+ }
+
+ priv->input_dev = strdup(MuT_PORT);
+#ifndef XFREE86_V4
+ priv->link_speed = MuT_LINK_SPEED;
+#endif
+ priv->min_x = 0;
+ priv->max_x = 0;
+ priv->min_y = 0;
+ priv->max_y = 0;
+ priv->screen_no = 0;
+ priv->screen_width = -1;
+ priv->screen_height = -1;
+ priv->inited = 0;
+ priv->state = 0;
+ priv->num_old_bytes = 0;
+ priv->stylus = NULL;
+ priv->finger = NULL;
+
+ local->name = name;
+ local->flags = 0;
+#ifndef XFREE86_V4
+ local->device_config = xf86MuTConfig;
+#endif
+ local->device_control = xf86MuTControl;
+ local->read_input = xf86MuTReadInput;
+ local->control_proc = NULL;
+ local->close_proc = NULL;
+ local->switch_mode = NULL;
+ local->conversion_proc = xf86MuTConvert;
+ local->reverse_conversion_proc = NULL;
+ local->fd = -1;
+ local->atom = 0;
+ local->dev = NULL;
+ local->private = priv;
+ local->private_flags = flag;
+ local->type_name = type_name;
+ local->history_size = 0;
+
+ return local;
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86MuTAllocateFinger --
+ *
+ ***************************************************************************
+ */
+static LocalDevicePtr
+xf86MuTAllocateFinger(void)
+{
+ LocalDevicePtr local = xf86MuTAllocate(XI_FINGER, "MicroTouch Finger", FINGER_ID);
+
+ if (local) {
+ ((MuTPrivatePtr) local->private)->finger = local;
+ }
+ return local;
+}
+
+
+/*
+ ***************************************************************************
+ *
+ * xf86MuTAllocateStylus --
+ *
+ ***************************************************************************
+ */
+static LocalDevicePtr
+xf86MuTAllocateStylus(void)
+{
+ LocalDevicePtr local = xf86MuTAllocate(XI_STYLUS, "MicroTouch Stylus", STYLUS_ID);
+
+ if (local) {
+ ((MuTPrivatePtr) local->private)->stylus = local;
+ }
+ return local;
+}
+
+
+#ifndef XFREE86_V4
+/*
+ ***************************************************************************
+ *
+ * MicroTouch finger device association --
+ *
+ ***************************************************************************
+ */
+DeviceAssocRec MuT_finger_assoc =
+{
+ FINGER_SECTION_NAME, /* config_section_name */
+ xf86MuTAllocateFinger /* device_allocate */
+};
+
+/*
+ ***************************************************************************
+ *
+ * MicroTouch stylus device association --
+ *
+ ***************************************************************************
+ */
+DeviceAssocRec MuT_stylus_assoc =
+{
+ STYLUS_SECTION_NAME, /* config_section_name */
+ xf86MuTAllocateStylus /* device_allocate */
+};
+
+
+#ifdef DYNAMIC_MODULE
+/*
+ ***************************************************************************
+ *
+ * entry point of dynamic loading
+ *
+ ***************************************************************************
+ */
+int
+#ifndef DLSYM_BUG
+init_module(unsigned long server_version)
+#else
+init_xf86MuTouch(unsigned long server_version)
+#endif
+{
+ xf86AddDeviceAssoc(&MuT_finger_assoc);
+ xf86AddDeviceAssoc(&MuT_stylus_assoc);
+
+ if (server_version != XF86_VERSION_CURRENT) {
+ ErrorF("Warning: MicroTouch module compiled for version%s\n", XF86_VERSION);
+ return 0;
+ }
+ else {
+ return 1;
+ }
+}
+#endif
+
+#else /* XFREE86_V4 */
+static const char *default_options[] = {
+ "BaudRate", "9600",
+ "StopBits", "1",
+ "DataBits", "8",
+ "Parity", "None",
+ "Vmin", "10",
+ "Vtime", "1",
+ "FlowControl", "None"
+};
+
+static pointer
+Plug(pointer module,
+ pointer options,
+ int *errmaj,
+ int *errmin)
+{
+ LocalDevicePtr local, current;
+ MuTPrivatePtr priv;
+ pointer defaults, merged;
+ char *type, *dev, *tmp;
+
+ defaults = xf86OptionListCreate(default_options,
+ sizeof(default_options)/sizeof(default_options[0]), 0);
+ merged = xf86OptionListMerge(defaults, options);
+ xf86OptionListReport(merged);
+
+ type = xf86FindOptionValue(merged, "Type");
+ if (!type) {
+ xf86Msg(X_ERROR, "Type field missing in Microtouch module config\n");
+ *errmaj = LDR_BADUSAGE;
+ return NULL;
+ }
+ if (xf86NameCmp(type, "finger") == 0) {
+ local = xf86MuTAllocateFinger();
+ }
+ else if (xf86NameCmp(type, "stylus") == 0) {
+ local = xf86MuTAllocateStylus();
+ }
+ else {
+ xf86Msg(X_ERROR, "Microtouch module Type field must be set to Finger or Stylus\n");
+ *errmaj = LDR_BADUSAGE;
+ return NULL;
+ }
+ if (!local) {
+ *errmaj = LDR_NOMEM;
+ return NULL;
+ }
+ priv = local->private;
+ dev = xf86FindOptionValue(merged, "Device");
+ if (dev) {
+ xfree(priv->input_dev);
+ priv->input_dev = strdup(dev);
+ }
+
+ /*
+ * See if another X device share the same physical
+ * device and set up the links so that they share
+ * the same private structure (the one that controls
+ * the physical device).
+ */
+ current = xf86FirstLocalDevice();
+ while (current) {
+ /* xf86Msg(X_NONE, "On y passe\n");*/
+ if ((current->device_control == xf86MuTControl) &&
+ (strcmp(((MuTPrivatePtr) (current->private))->input_dev, priv->input_dev) == 0)) {
+ xf86Msg(X_CONFIG, "MicroTouch config detected a device share between %s and %s\n",
+ local->type_name, current->name);
+ xfree(priv->input_dev);
+ xfree(priv);
+ priv = local->private = current->private;
+ switch (DEVICE_ID(local->private_flags)) {
+ case FINGER_ID:
+ priv->finger = local;
+ break;
+ case STYLUS_ID:
+ priv->stylus = local;
+ break;
+ }
+ break;
+ }
+ current = current->next;
+ }
+ if (!current) {
+ xf86Msg(X_CONFIG, "MicroTouch %s input port: %s\n", local->type_name, priv->input_dev);
+ }
+
+ tmp = xf86FindOptionValue(merged, "DeviceName");
+ if (tmp) {
+ local->name = strdup(tmp);
+ }
+ xf86Msg(X_CONFIG, "Microtouch X device name: %s\n", local->name);
+ priv->screen_no = xf86SetIntOption(merged, "ScreenNo", 0);
+ xf86Msg(X_CONFIG, "Microtouch associated screen: %d\n", priv->screen_no);
+ priv->max_x = xf86SetIntOption(merged, "MaximumXPosition", 3000);
+ xf86Msg(X_CONFIG, "Microtouch maximum x position: %d\n", priv->max_x);
+ priv->min_x = xf86SetIntOption(merged, "MinimumXPosition", 0);
+ xf86Msg(X_CONFIG, "Microtouch minimum x position: %d\n", priv->min_x);
+ priv->max_y = xf86SetIntOption(merged, "MaximumYPosition", 3000);
+ xf86Msg(X_CONFIG, "Microtouch maximum y position: %d\n", priv->max_y);
+ priv->min_y = xf86SetIntOption(merged, "MinimumYPosition", 0);
+ xf86Msg(X_CONFIG, "Microtouch minimum y position: %d\n", priv->min_y);
+ debug_level = xf86SetIntOption(merged, "DebugLevel", 0);
+ if (debug_level) {
+#if DEBUG
+ xf86Msg(X_CONFIG, "Microtouch debug level sets to %d\n", debug_level);
+#else
+ xf86Msg(X_INFO, "Microtouch debug not available\n");
+#endif
+ }
+
+ if (priv->max_x - priv->min_x <= 0) {
+ priv->max_x = DEFAULT_MAX_X;
+ priv->min_x = DEFAULT_MIN_X;
+ xf86Msg(X_CONFIG, "MicroTouch: Incorrect Maximum/Minimum x position, using: %d, %d\n",
+ priv->max_x, priv->min_x);
+ }
+ if (priv->max_y - priv->min_y <= 0) {
+ priv->max_y = DEFAULT_MAX_Y;
+ priv->min_y = DEFAULT_MIN_Y;
+ xf86Msg(X_CONFIG, "MicroTouch: Incorrect Maximum/Minimum y position, using: %d, %d\n",
+ priv->max_y, priv->min_y);
+ }
+
+ xf86AddLocalDevice(local, merged);
+
+ return local;
+}
+
+static void
+Unplug(pointer p)
+{
+ LocalDevicePtr local = (LocalDevicePtr) p;
+ MuTPrivatePtr priv = (MuTPrivatePtr) local->private;
+
+ xf86MuTControl(local->dev, DEVICE_OFF);
+ xf86RemoveLocalDevice(local);
+
+ if (priv) {
+ priv->stylus->private = NULL;
+ priv->finger->private = NULL;
+ xfree(priv->input_dev);
+ xfree(priv);
+ }
+ xfree(local->name);
+ xfree(local);
+}
+
+static XF86ModuleVersionInfo version_rec = {
+ "mutouch",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_XINPUT,
+ ABI_XINPUT_VERSION,
+ MOD_CLASS_XINPUT,
+ { 0, 0, 0, 0 }
+};
+
+/*
+ * This is the entry point in the module. The name
+ * is setup after the pattern <module_name>ModuleData.
+ * Do not change it.
+ */
+XF86ModuleData mutouchModuleData = { &version_rec, Plug, Unplug };
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/input/sample/Imakefile b/xc/programs/Xserver/hw/xfree86/input/sample/Imakefile
new file mode 100644
index 000000000..be0f808e6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/sample/Imakefile
@@ -0,0 +1,26 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/sample/Imakefile,v 1.4 1999/08/14 10:50:02 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = sample.c
+OBJS = sample.o
+
+DRIVER = sample
+
+INCLUDES = -I. -I$(XF86COMSRC) -I../../loader -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget($(DRIVER),$(OBJS))
+
+InstallObjectModule($(DRIVER),$(MODULEDIR),input)
+
+DependTarget()
+
+InstallDriverSDKObjectModule($(DRIVER),$(DRIVERSDKMODULEDIR),input)
diff --git a/xc/programs/Xserver/hw/xfree86/input/sample/sample.c b/xc/programs/Xserver/hw/xfree86/input/sample/sample.c
new file mode 100644
index 000000000..ae58b440a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/sample/sample.c
@@ -0,0 +1,525 @@
+/*
+ * Copyright (c) 1998 Metro Link Incorporated
+ *
+ * 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, cpy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/sample/sample.c,v 1.8 1999/06/05 15:55:28 dawes Exp $ */
+
+#define _SAMPLE_C_
+/*****************************************************************************
+ * Standard Headers
+ ****************************************************************************/
+
+#include <misc.h>
+#include <xf86.h>
+#define NEED_XF86_TYPES
+#include <xf86_ansic.h>
+#include <xf86_OSproc.h>
+#include <xf86Xinput.h>
+#include <xisb.h>
+#include <exevents.h> /* Needed for InitValuator/Proximity stuff */
+
+/*****************************************************************************
+ * Local Headers
+ ****************************************************************************/
+#include "sample.h"
+
+/*****************************************************************************
+ * Variables without includable headers
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Local Variables
+ ****************************************************************************/
+static XF86ModuleVersionInfo VersionRec =
+{
+ "sample",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_XINPUT,
+ ABI_XINPUT_VERSION,
+ MOD_CLASS_XINPUT,
+ {0, 0, 0, 0} /* signature, to be patched into the file by
+ * a tool */
+};
+
+/*
+ * Be sure to set vmin appropriately for your device's protocol. You want to
+ * read a full packet before returning
+ */
+static char *default_options[] =
+{
+ "BaudRate", "9600",
+ "StopBits", "1",
+ "DataBits", "8",
+ "Parity", "None",
+ "Vmin", "10",
+ "Vtime", "1",
+ "FlowControl", "None"
+};
+
+XF86ModuleData sampleModuleData = { &VersionRec, SetupProc, TearDownProc };
+
+/*****************************************************************************
+ * Function Definitions
+ ****************************************************************************/
+
+
+/*
+ * The TearDownProc may have to be tailored to your device
+ */
+static void
+TearDownProc( pointer p )
+{
+ LocalDevicePtr local = (LocalDevicePtr) p;
+ SAMPLEPrivatePtr priv = (SAMPLEPrivatePtr) local->private;
+
+ ErrorF ("Sample TearDownProc Called\n");
+
+ DeviceOff (local->dev);
+
+ xf86RemoveLocalDevice (local);
+
+ xf86CloseSerial (local->fd);
+ XisbFree (priv->buffer);
+ xfree (priv);
+ xfree (local->name);
+ xfree (local);
+}
+
+/*
+ * The Setup Proc will have to be tailored to your device
+ */
+static pointer
+SetupProc( pointer module,
+ pointer options,
+ int *errmaj,
+ int *errmin )
+{
+ LocalDevicePtr local = xcalloc (1, sizeof (LocalDeviceRec));
+ SAMPLEPrivatePtr priv = xcalloc (1, sizeof (SAMPLEPrivateRec));
+ pointer defaults,
+ merged;
+ char *s;
+
+ ErrorF ("Sample SetupProc called\n");
+ if ((!local) || (!priv))
+ goto SetupProc_fail;
+
+ defaults = xf86OptionListCreate (default_options,
+ (sizeof (default_options) / sizeof (default_options[0])), 0);
+ merged = xf86OptionListMerge (defaults, options);
+
+ xf86OptionListReport( merged );
+
+ local->fd = xf86OpenSerial (merged);
+ if (local->fd == -1)
+ {
+ ErrorF ("SAMPLE driver unable to open device\n");
+ *errmaj = LDR_NOPORTOPEN;
+ *errmin = xf86GetErrno ();
+ goto SetupProc_fail;
+ }
+
+ /*
+ * Process the options for your device like this
+ */
+ priv->min_x = xf86SetIntOption( merged, "MinX", 0 );
+ priv->max_x = xf86SetIntOption( merged, "MaxX", 1000 );
+ priv->min_y = xf86SetIntOption( merged, "MinY", 0 );
+ priv->max_y = xf86SetIntOption( merged, "MaxY", 1000 );
+ priv->untouch_delay = xf86SetIntOption( merged, "UntouchDelay", 10 );
+ priv->report_delay = xf86SetIntOption( merged, "ReportDelay", 40 );
+ priv->screen_num = xf86SetIntOption( merged, "ScreenNumber", 0 );
+ priv->button_number = xf86SetIntOption( merged, "ButtonNumber", 1 );
+ priv->button_threshold = xf86SetIntOption( merged, "ButtonThreshold", 128 );
+
+ s = xf86FindOptionValue (merged, "ReportingMode");
+ if ((s) && (StrCaseCmp (s, "raw") == 0))
+ priv->reporting_mode = TS_Raw;
+ else
+ priv->reporting_mode = TS_Scaled;
+
+ priv->checksum = 0;
+
+ /*
+ * Create an X Input Serial Buffer if your device attaches to a serial
+ * port.
+ */
+ priv->buffer = XisbNew (local->fd, 200);
+
+ DBG (9, XisbTrace (priv->buffer, 1));
+
+ /*
+ * Verify that your hardware is attached and fuctional if you can
+ */
+ if (QueryHardware (priv, errmaj, errmin) != Success)
+ {
+ ErrorF ("Unable to query/initialize SAMPLE hardware.\n");
+ goto SetupProc_fail;
+ }
+
+ /* this results in an xstrdup that must be freed later */
+ local->name = xf86SetStrOption( merged, "DeviceName", "SAMPLE XInput Device");
+
+ /* Set the type that's appropriate for your device
+ * XI_KEYBOARD
+ * XI_MOUSE
+ * XI_TABLET
+ * XI_TOUCHSCREEN
+ * XI_TOUCHPAD
+ * XI_BARCODE
+ * XI_BUTTONBOX
+ * XI_KNOB_BOX
+ * XI_ONE_KNOB
+ * XI_NINE_KNOB
+ * XI_TRACKBALL
+ * XI_QUADRATURE
+ * XI_ID_MODULE
+ * XI_SPACEBALL
+ * XI_DATAGLOVE
+ * XI_EYETRACKER
+ * XI_CURSORKEYS
+ * XI_FOOTMOUSE
+ */
+ local->type_name = XI_TOUCHSCREEN;
+ /*
+ * Standard setup for the local device record
+ */
+ local->device_control = DeviceControl;
+ local->read_input = ReadInput;
+ local->control_proc = ControlProc;
+ local->close_proc = CloseProc;
+ local->switch_mode = SwitchMode;
+ local->conversion_proc = ConvertProc;
+ local->dev = NULL;
+ local->private = priv;
+ local->private_flags = 0;
+ local->history_size = xf86SetIntOption( merged, "HistorySize", 0 );
+
+ xf86AddLocalDevice( local, merged );
+
+ /* return the LocalDevice */
+ return (local);
+
+ /*
+ * If something went wrong, cleanup and return NULL
+ */
+ SetupProc_fail:
+ if ((local) && (local->fd))
+ xf86CloseSerial (local->fd);
+ if ((local) && (local->name))
+ xfree (local->name);
+ if (local)
+ xfree (local);
+
+ if ((priv) && (priv->buffer))
+ XisbFree (priv->buffer);
+ if (priv)
+ xfree (priv);
+ ErrorF ("SetupProc returning NULL\n");
+ return (NULL);
+}
+
+/*
+ * The DeviceControl function should not need to be changed
+ * except to remove ErrorFs
+ */
+static Bool
+DeviceControl (DeviceIntPtr dev, int mode)
+{
+ Bool RetValue;
+
+ ErrorF ("DeviceControl called mode = %d\n", mode);
+ switch (mode)
+ {
+ case DEVICE_INIT:
+ ErrorF ("\tINIT\n");
+ DeviceInit (dev);
+ RetValue = Success;
+ break;
+ case DEVICE_ON:
+ ErrorF ("\tON\n");
+ RetValue = DeviceOn( dev );
+ break;
+ case DEVICE_OFF:
+ ErrorF ("\tOFF\n");
+ RetValue = DeviceOff( dev );
+ break;
+ case DEVICE_CLOSE:
+ ErrorF ("\tCLOSE\n");
+ RetValue = DeviceClose( dev );
+ break;
+ default:
+ ErrorF ("\tBAD MODE\n");
+ RetValue = BadValue;
+ }
+
+ return( RetValue );
+}
+
+/*
+ * The DeviceOn function should not need to be changed
+ */
+static Bool
+DeviceOn (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+
+ AddEnabledDevice (local->fd);
+ dev->public.on = TRUE;
+ return (Success);
+}
+
+/*
+ * The DeviceOff function should not need to be changed
+ */
+static Bool
+DeviceOff (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+
+ RemoveEnabledDevice (local->fd);
+ dev->public.on = FALSE;
+ return (Success);
+}
+
+/*
+ * The DeviceClose function should not need to be changed
+ */
+static Bool
+DeviceClose (DeviceIntPtr dev)
+{
+ return (Success);
+}
+
+/*
+ * The DeviceInit function will need to be tailored to your device
+ */
+static Bool
+DeviceInit (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ SAMPLEPrivatePtr priv = (SAMPLEPrivatePtr) (local->private);
+ Atom atom;
+ unsigned char map[] =
+ {0, 1};
+
+ /*
+ * Set up buttons, valuators etc for your device
+ */
+ if (InitButtonClassDeviceStruct (dev, 1, map) == FALSE)
+ {
+ ErrorF ("Unable to allocate SAMPLE ButtonClassDeviceStruct\n");
+ return !Success;
+ }
+
+ /*
+ * this example device reports motions on 2 axes in absolute coordinates.
+ * Device may reports touch pressure on the 3rd axis.
+ */
+ if (InitValuatorClassDeviceStruct (dev, 2, xf86GetMotionEvents,
+ local->history_size, Absolute) == FALSE)
+ {
+ ErrorF ("Unable to allocate SAMPLE ValuatorClassDeviceStruct\n");
+ return !Success;
+ }
+ else
+ {
+ InitValuatorAxisStruct (dev, 0, priv->min_x, priv->max_x,
+ 9500,
+ 0 /* min_res */ ,
+ 9500 /* max_res */ );
+ InitValuatorAxisStruct (dev, 1, priv->min_y, priv->max_y,
+ 10500,
+ 0 /* min_res */ ,
+ 10500 /* max_res */ );
+ }
+
+ if (InitProximityClassDeviceStruct (dev) == FALSE)
+ {
+ ErrorF ("unable to allocate SAMPLE ProximityClassDeviceStruct\n");
+ return !Success;
+ }
+
+ /*
+ * Allocate the motion events buffer.
+ */
+ xf86MotionHistoryAllocate (local);
+ return (Success);
+}
+
+/*
+ * The ReadInput function will have to be tailored to your device
+ */
+static void
+ReadInput (LocalDevicePtr local)
+{
+ int x, y, z;
+ int state;
+ SAMPLEPrivatePtr priv = (SAMPLEPrivatePtr) (local->private);
+
+ /*
+ * set blocking to -1 on the first call because we know there is data to
+ * read. Xisb automatically clears it after one successful read so that
+ * succeeding reads are preceeded buy a select with a 0 timeout to prevent
+ * read from blocking indefinately.
+ */
+ XisbBlockDuration (priv->buffer, -1);
+ while (SAMPLEGetPacket (priv) == Success)
+ {
+ /*
+ * Examine priv->packet and call these functions as appropriate:
+ *
+ xf86PostProximityEvent
+ xf86PostMotionEvent
+ xf86PostButtonEvent
+ */
+ }
+}
+
+/*
+ * The ControlProc function may need to be tailored for your device
+ */
+static int
+ControlProc (LocalDevicePtr local, xDeviceCtl * control)
+{
+ return (Success);
+}
+
+/*
+ * the CloseProc should not need to be tailored to your device
+ */
+static void
+CloseProc (LocalDevicePtr local)
+{
+}
+
+/*
+ * The SwitchMode function may need to be tailored for your device
+ */
+static int
+SwitchMode (ClientPtr client, DeviceIntPtr dev, int mode)
+{
+ return (Success);
+}
+
+/*
+ * The ConvertProc function may need to be tailored for your device.
+ * This function converts the device's valuator outputs to x and y coordinates
+ * to simulate mouse events.
+ */
+static Bool
+ConvertProc (LocalDevicePtr local,
+ int first,
+ int num,
+ int v0,
+ int v1,
+ int v2,
+ int v3,
+ int v4,
+ int v5,
+ int *x,
+ int *y)
+{
+ *x = v0;
+ *y = v1;
+ return (Success);
+}
+
+/*
+ * the QueryHardware fuction should be tailored to your device to
+ * verify the device is attached and functional and perform any
+ * needed initialization.
+ */
+static Bool
+QueryHardware (SAMPLEPrivatePtr priv, int *errmaj, int *errmin)
+{
+ return (Success);
+}
+
+/*
+ * This function should be renamed for your device and tailored to handle
+ * your device's protocol.
+ */
+static Bool
+SAMPLEGetPacket (SAMPLEPrivatePtr priv)
+{
+ int count = 0;
+ int c;
+
+ while ((c = XisbRead (priv->buffer)) >= 0)
+ {
+ /*
+ * your checksum calculation may be different or your device's
+ * protocol may not have one.
+ */
+ if (priv->lex_mode != SAMPLE_checksum)
+ priv->checksum += c;
+ /*
+ * fail after 500 bytes so the server doesn't hang forever if a
+ * device sends bad data.
+ */
+ if (count++ > 500)
+ return (!Success);
+
+ switch (priv->lex_mode)
+ {
+ case SAMPLE_normal:
+ if (c == SAMPLE_SYNC_BYTE)
+ {
+ priv->packet[priv->packeti++] = (unsigned char) c;
+ priv->checksum = SAMPLE_INIT_CHECKSUM + c;
+ priv->lex_mode = SAMPLE_body;
+ }
+ break;
+
+ case SAMPLE_body:
+ if (priv->packeti < SAMPLE_BODY_LEN)
+ priv->packet[priv->packeti++] = (unsigned char) c;
+ if (priv->packeti == SAMPLE_BODY_LEN)
+ priv->lex_mode = SAMPLE_checksum;
+ break;
+
+ case SAMPLE_checksum:
+
+ if (c != priv->checksum)
+ {
+ xf86ErrorFVerb( 4,
+ "Checksum mismatch. Read %d calculated %d\nPacket discarded.\n",
+ c, priv->checksum );
+ }
+ else
+ {
+ ErrorF ("got a good packet\n");
+ return (Success);
+ }
+ break;
+ }
+ }
+ return (!Success);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/input/sample/sample.h b/xc/programs/Xserver/hw/xfree86/input/sample/sample.h
new file mode 100644
index 000000000..f6c81467b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/sample/sample.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 1998 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/sample/sample.h,v 1.2 1999/02/01 12:13:00 dawes Exp $ */
+
+#ifndef _SAMPLE_H_
+#define _SAMPLE_H_
+
+/******************************************************************************
+ * Definitions
+ * structs, typedefs, #defines, enums
+ *****************************************************************************/
+#define SAMPLE_PACKET_SIZE 10
+#define SAMPLE_SYNC_BYTE 'T'
+#define SAMPLE_INIT_CHECKSUM 0
+#define SAMPLE_BODY_LEN 9
+
+typedef enum
+{
+ SAMPLE_normal, SAMPLE_type, SAMPLE_body, SAMPLE_checksum
+}
+SAMPLEState;
+
+#define WORD_ASSEMBLY(byte1, byte2) (((byte2) << 8) | (byte1))
+
+typedef struct _SAMPLEPrivateRec
+{
+ int min_x; /* Minimum x reported by calibration */
+ int max_x; /* Maximum x */
+ int min_y; /* Minimum y reported by calibration */
+ int max_y; /* Maximum y */
+ int button_threshold; /* Z > button threshold = button click */
+ int axes;
+ Bool button_down; /* is the "button" currently down */
+ int button_number; /* which button to report */
+ int reporting_mode; /* TS_Raw or TS_Scaled */
+
+ int untouch_delay; /* Delay before reporting an untouch (in ms) */
+ int report_delay; /* Delay between touch report packets */
+
+ int screen_num; /* Screen associated with the device */
+ int screen_width; /* Width of the associated X screen */
+ int screen_height; /* Height of the screen */
+ XISBuffer *buffer;
+ unsigned char packet[SAMPLE_PACKET_SIZE]; /* packet being/just read */
+ int packeti; /* index into packet */
+ unsigned char checksum; /* Current checksum of data in assembly *
+ * buffer */
+ SAMPLEState lex_mode;
+}
+SAMPLEPrivateRec, *SAMPLEPrivatePtr;
+
+/******************************************************************************
+ * Declarations
+ *****************************************************************************/
+static MODULESETUPPROTO( sampleSetupProc );
+static void TearDownProc (pointer p);
+static Bool DeviceControl (DeviceIntPtr, int);
+static Bool DeviceOn (DeviceIntPtr);
+static Bool DeviceOff (DeviceIntPtr);
+static Bool DeviceClose (DeviceIntPtr);
+static Bool DeviceInit (DeviceIntPtr);
+static void ReadInput (LocalDevicePtr);
+static int ControlProc (LocalDevicePtr, xDeviceCtl *);
+static void CloseProc (LocalDevicePtr);
+static int SwitchMode (ClientPtr, DeviceIntPtr, int);
+static Bool ConvertProc (LocalDevicePtr, int, int, int, int, int, int, int, int, int *, int *);
+static Bool QueryHardware (SAMPLEPrivatePtr, int *, int *);
+static Bool SAMPLEGetPacket (SAMPLEPrivatePtr priv);
+/*
+ * DO NOT PUT ANYTHING AFTER THIS ENDIF
+ */
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/input/spaceorb/Imakefile b/xc/programs/Xserver/hw/xfree86/input/spaceorb/Imakefile
new file mode 100644
index 000000000..494516dfd
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/spaceorb/Imakefile
@@ -0,0 +1,26 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/spaceorb/Imakefile,v 1.4 1999/08/14 10:50:03 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = spaceorb.c
+OBJS = spaceorb.o
+
+DRIVER = spaceorb
+
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86SRC)/loader -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget($(DRIVER),$(OBJS))
+
+InstallObjectModule($(DRIVER),$(MODULEDIR),input)
+
+DependTarget()
+
+InstallDriverSDKObjectModule($(DRIVER),$(DRIVERSDKMODULEDIR),input)
diff --git a/xc/programs/Xserver/hw/xfree86/input/spaceorb/spaceorb.c b/xc/programs/Xserver/hw/xfree86/input/spaceorb/spaceorb.c
new file mode 100644
index 000000000..4e751a2aa
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/spaceorb/spaceorb.c
@@ -0,0 +1,507 @@
+/*
+ * Copyright (c) 1998 Metro Link Incorporated
+ *
+ * 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, cpy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/spaceorb/spaceorb.c,v 1.9 1999/06/05 15:55:29 dawes Exp $ */
+
+#define _SPACEORB_C_
+/*****************************************************************************
+ * Standard Headers
+ ****************************************************************************/
+
+#include <misc.h>
+#include <xf86.h>
+#define NEED_XF86_TYPES
+#include <xf86_ansic.h>
+#include <xf86_OSproc.h>
+#include <xf86Xinput.h>
+#include <xisb.h>
+#include <exevents.h> /* Needed for InitValuator/Proximity stuff */
+
+/*****************************************************************************
+ * Local Headers
+ ****************************************************************************/
+#include "spaceorb.h"
+
+/*****************************************************************************
+ * Variables without includable headers
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Local Variables
+ ****************************************************************************/
+static XF86ModuleVersionInfo VersionRec =
+{
+ "spaceorb",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_XINPUT,
+ ABI_XINPUT_VERSION,
+ MOD_CLASS_XINPUT,
+ {0, 0, 0, 0} /* signature, to be patched into the file by
+ * a tool */
+};
+
+/*
+ * Be sure to set vmin appropriately for your device's protocol. You want to
+ * read a full packet before returning
+ */
+static const char *default_options[] =
+{
+ "BaudRate", "9600",
+ "StopBits", "1",
+ "DataBits", "8",
+ "Parity", "None",
+ "Vmin", "5",
+ "Vtime", "1",
+ "FlowControl", "None"
+};
+
+static char spaceware[] = "0SpaceWare!";
+
+XF86ModuleData spaceorbModuleData = { &VersionRec, SetupProc, TearDownProc };
+
+/*****************************************************************************
+ * Function Definitions
+ ****************************************************************************/
+
+
+static void
+TearDownProc( pointer p )
+{
+ LocalDevicePtr local = (LocalDevicePtr) p;
+ SPACEORBPrivatePtr priv = (SPACEORBPrivatePtr) local->private;
+
+ DeviceOff (local->dev);
+
+ xf86RemoveLocalDevice (local);
+
+ xf86CloseSerial (local->fd);
+ XisbFree (priv->buffer);
+ xfree (priv);
+ xfree (local->name);
+ xfree (local);
+}
+
+static pointer
+SetupProc( pointer module,
+ pointer options,
+ int *errmaj,
+ int *errmin )
+{
+ LocalDevicePtr local =
+ xcalloc (1, sizeof (LocalDeviceRec));
+ SPACEORBPrivatePtr priv =
+ xcalloc (1, sizeof (SPACEORBPrivateRec));
+ pointer defaults,
+ merged;
+
+ if ((!local) || (!priv))
+ goto SetupProc_fail;
+
+ defaults = xf86OptionListCreate (default_options,
+ (sizeof (default_options) / sizeof (default_options[0])), 0);
+ merged = xf86OptionListMerge (defaults, options);
+
+ xf86OptionListReport( merged );
+
+ local->fd = xf86OpenSerial (merged);
+ if (local->fd == -1)
+ {
+ ErrorF ("SPACEORB driver unable to open device\n");
+ *errmaj = LDR_NOPORTOPEN;
+ *errmin = xf86GetErrno ();
+ goto SetupProc_fail;
+ }
+
+ priv->buffer = XisbNew (local->fd, 200);
+
+ DBG (9, XisbTrace (priv->buffer, 1));
+
+ /*
+ * Verify the hardware is attached and functional
+ */
+ if (QueryHardware (priv, errmaj, errmin) != Success)
+ {
+ ErrorF ("Unable to query/initialize SpaceOrb hardware.\n");
+ goto SetupProc_fail;
+ }
+
+ /* this results in an xstrdup that must be freed later */
+ local->name = xf86SetStrOption( merged, "DeviceName", "SpaceOrb XInput Device" );
+
+ local->type_name = XI_SPACEBALL;
+ /*
+ * Standard setup for the local device record
+ */
+ local->device_control = DeviceControl;
+ local->read_input = ReadInput;
+ local->control_proc = ControlProc;
+ local->close_proc = CloseProc;
+ local->switch_mode = SwitchMode;
+ local->conversion_proc = ConvertProc;
+ local->dev = NULL;
+ local->private = priv;
+ local->private_flags = 0;
+ local->history_size = xf86SetIntOption( merged, "HistorySize", 0 );
+
+ xf86AddLocalDevice( local, merged );
+
+ /* return the LocalDevice */
+ return (local);
+
+ /*
+ * If something went wrong, cleanup and return NULL
+ */
+ SetupProc_fail:
+ if ((local) && (local->fd))
+ xf86CloseSerial (local->fd);
+ if ((local) && (local->name))
+ xfree (local->name);
+ if (local)
+ xfree (local);
+
+ if ((priv) && (priv->buffer))
+ XisbFree (priv->buffer);
+ if (priv)
+ xfree (priv);
+ return (NULL);
+}
+
+static Bool
+DeviceControl (DeviceIntPtr dev, int mode)
+{
+ Bool RetValue;
+
+ switch (mode)
+ {
+ case DEVICE_INIT:
+ DeviceInit (dev);
+ RetValue = Success;
+ break;
+ case DEVICE_ON:
+ RetValue = DeviceOn( dev );
+ break;
+ case DEVICE_OFF:
+ RetValue = DeviceOff( dev );
+ break;
+ case DEVICE_CLOSE:
+ RetValue = DeviceClose( dev );
+ break;
+ default:
+ RetValue = BadValue;
+ }
+
+ return( RetValue );
+}
+
+static Bool
+DeviceOn (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+
+ AddEnabledDevice (local->fd);
+ dev->public.on = TRUE;
+ return (Success);
+}
+
+static Bool
+DeviceOff (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+
+ RemoveEnabledDevice (local->fd);
+ dev->public.on = FALSE;
+ return (Success);
+}
+
+static Bool
+DeviceClose (DeviceIntPtr dev)
+{
+ return (Success);
+}
+
+static Bool
+DeviceInit (DeviceIntPtr dev)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+ unsigned char map[] =
+ {0, 1, 2, 3, 4, 5, 6, 7};
+
+ if (InitButtonClassDeviceStruct (dev, 7, map) == FALSE)
+ {
+ ErrorF ("Unable to allocate SPACEORB ButtonClassDeviceStruct\n");
+ return !Success;
+ }
+
+ if (InitFocusClassDeviceStruct (dev) == FALSE)
+ {
+ ErrorF("Unable to allocate SPACEORB FocusClassDeviceStruct\n");
+ return !Success;
+ }
+
+
+
+ if (InitValuatorClassDeviceStruct (dev, 6, xf86GetMotionEvents,
+ local->history_size, Absolute) == FALSE)
+ {
+ ErrorF ("Unable to allocate SPACEORB ValuatorClassDeviceStruct\n");
+ return !Success;
+ }
+ else
+ {
+ InitValuatorAxisStruct(dev, 0, -512, 511, 9600,0,9600);
+ InitValuatorAxisStruct(dev, 1, -512, 511, 9600,0,9600);
+ InitValuatorAxisStruct(dev, 2, -512, 511, 9600,0,9600);
+ InitValuatorAxisStruct(dev, 3, -512, 511, 9600,0,9600);
+ InitValuatorAxisStruct(dev, 4, -512, 511, 9600,0,9600);
+ InitValuatorAxisStruct(dev, 5, -512, 511, 9600,0,9600);
+ }
+
+ /*
+ * Allocate the motion events buffer.
+ */
+ xf86MotionHistoryAllocate (local);
+ return (Success);
+}
+
+static void
+ReadInput (LocalDevicePtr local)
+{
+ int x, y, z, u, v, r;
+ int buttons;
+ int i;
+ SPACEORBPrivatePtr priv = (SPACEORBPrivatePtr) (local->private);
+
+ /*
+ * set blocking to -1 on the first call because we know there is data to
+ * read. Xisb automatically clears it after one successful read so that
+ * succeeding reads are preceeded buy a select with a 0 timeout to prevent
+ * read from blocking indefinately.
+ */
+ XisbBlockDuration (priv->buffer, -1);
+ while (SPACEORBGetPacket (priv) == Success)
+ {
+ /*
+ * Examine priv->packet and call these functions as appropriate:
+ *
+ xf86PostMotionEvent
+ xf86PostButtonEvent
+ */
+ switch (priv->packet_type)
+ {
+ case SPACEORB_D_PACKET:
+ /* Turn chars into 10 bit integers */
+ x = ((priv->packet[1] & 0177)<<3)|((priv->packet[2] & 0160)>>4);
+ y = ((priv->packet[2] & 0017)<<6)|((priv->packet[3] & 0176)>>1);
+ z = ((priv->packet[3] & 0001)<<9)|((priv->packet[4] & 0177)<<2)|((priv->packet[5] & 0140)>>5);
+ u = ((priv->packet[5] & 0037)<<5)|((priv->packet[6] & 0174)>>2);
+ v = ((priv->packet[6] & 0003)<<8)|((priv->packet[7] & 0177)<<1)|((priv->packet[8] & 0100)>>6);
+ r = ((priv->packet[8] & 0077)<<4)|((priv->packet[9] & 0170)>>3);
+
+ /* Get the sign right. */
+ if (x > 511) x -= 1024;
+ if (y > 511) y -= 1024;
+ if (z > 511) z -= 1024;
+ if (u > 511) u -= 1024;
+ if (v > 511) v -= 1024;
+ if (r > 511) r -= 1024;
+
+ xf86ErrorFVerb( 9, "SpaceOrb motion %d %d %d -- %d %d %d\n",
+ x, y, z, u, v, r );
+ xf86PostMotionEvent(local->dev, TRUE, 0, 6, x, y, z, u, v, r);
+ break;
+
+ case SPACEORB_K_PACKET:
+ buttons = priv->packet[1];
+ if (priv->old_buttons != buttons)
+ for (i = 0; i < 7; i++)
+ {
+ if ((priv->old_buttons&(1<<i)) != (buttons&(1<<i)))
+ {
+ xf86PostButtonEvent(local->dev, FALSE, i+1,
+ (buttons&(1<<i)), 0, 0);
+ xf86ErrorFVerb( 9, "SpaceOrb setting button %d to %d\n",
+ i+1, (buttons&(1<<i)) );
+ }
+ }
+ priv->old_buttons = buttons;
+ break;
+ }
+ }
+}
+
+static int
+ControlProc (LocalDevicePtr local, xDeviceCtl * control)
+{
+ return (Success);
+}
+
+static void
+CloseProc (LocalDevicePtr local)
+{
+}
+
+static int
+SwitchMode (ClientPtr client, DeviceIntPtr dev, int mode)
+{
+ return (Success);
+}
+
+/*
+ * this probably doesn't make much sense for a spaceorb
+ */
+static Bool
+ConvertProc (LocalDevicePtr local,
+ int first,
+ int num,
+ int v0,
+ int v1,
+ int v2,
+ int v3,
+ int v4,
+ int v5,
+ int *x,
+ int *y)
+{
+ *x = v0;
+ *y = v1;
+ return (Success);
+}
+
+static Bool
+QueryHardware (SPACEORBPrivatePtr priv, int *errmaj, int *errmin)
+{
+ /*
+ * When you open the serial port, the spaceorb sends a greeting packet
+ * make sure we got it to verify that the device is present.
+ * block for up to a second to make sure the data is there.
+ */
+ XisbBlockDuration (priv->buffer, 1000000);
+ if ((SPACEORBGetPacket (priv) == Success) &&
+ (priv->packet_type == SPACEORB_R_PACKET))
+ return (Success);
+ else
+ {
+ ErrorF ("No response from SpaceOrb hardware.\n");
+ *errmaj = LDR_NOHARDWARE;
+ return (!Success);
+ }
+}
+
+static void
+NewPacket (SPACEORBPrivatePtr priv)
+{
+ priv->lex_mode = SPACEORB_normal;
+ priv->packeti = 0;
+}
+
+static Bool
+SPACEORBGetPacket (SPACEORBPrivatePtr priv)
+{
+ int count = 0;
+ int c;
+
+ while ((c = XisbRead (priv->buffer)) >= 0)
+ {
+ /*
+ * fail after 500 bytes so the server doesn't hang forever if a
+ * device sends bad data.
+ */
+ if (count++ > 500)
+ {
+ NewPacket (priv);
+ return (!Success);
+ }
+ if (c == '\r')
+ continue;
+
+ switch (priv->lex_mode)
+ {
+ case SPACEORB_normal:
+ if (c == SPACEORB_R_PACKET)
+ {
+ xf86ErrorFVerb( 9, "SpaceOrb got an R packet\n" );
+ priv->packet_type = SPACEORB_R_PACKET;
+ priv->lex_mode = SPACEORB_body;
+ priv->expected_len = SPACEORB_R_BODY_LEN;
+ }
+ else if (c == 'K')
+ {
+ priv->packet_type = SPACEORB_K_PACKET;
+ priv->lex_mode = SPACEORB_body;
+ priv->expected_len = SPACEORB_K_BODY_LEN;
+ }
+ else if (c == 'D')
+ {
+ xf86ErrorFVerb( 9, "SpaceOrb got a D packet\n" );
+ priv->packet_type = SPACEORB_D_PACKET;
+ priv->lex_mode = SPACEORB_Dbody;
+ priv->expected_len = SPACEORB_D_BODY_LEN;
+ }
+ break;
+ case SPACEORB_Dbody:
+ if (priv->packeti < priv->expected_len)
+ {
+ xf86ErrorFVerb( 9, "\t%d = %c data = %c %d\n",
+ priv->packeti, spaceware[priv->packeti],
+ (c & 0x7F), (c & 0x7F) );
+ priv->packet[priv->packeti] =
+ (unsigned char) (c & 0x7F) ^ spaceware[priv->packeti];
+ priv->packeti++;
+ }
+ if (priv->packeti == priv->expected_len)
+ {
+#ifdef DEBUG
+ErrorF ("returning packet <");
+{
+ int i;
+ for (i = 0; i < priv->expected_len; i++)
+ ErrorF ("%c", priv->packet[i]);
+ErrorF (">\n");
+}
+#endif
+ NewPacket (priv);
+ return (Success);
+ }
+ break;
+
+ case SPACEORB_body:
+ if (priv->packeti < priv->expected_len)
+ priv->packet[priv->packeti++] = (unsigned char) c & 0x7F;
+ if (priv->packeti == priv->expected_len)
+ {
+ NewPacket (priv);
+ return (Success);
+ }
+ break;
+
+ }
+ }
+ return (!Success);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/input/spaceorb/spaceorb.h b/xc/programs/Xserver/hw/xfree86/input/spaceorb/spaceorb.h
new file mode 100644
index 000000000..c41c5bc69
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/spaceorb/spaceorb.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1998 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/spaceorb/spaceorb.h,v 1.2 1999/02/01 12:13:00 dawes Exp $ */
+
+#ifndef _SPACEORB_H_
+#define _SPACEORB_H_
+
+#include <xf86Module.h>
+
+/******************************************************************************
+ * Definitions
+ * structs, typedefs, #defines, enums
+ *****************************************************************************/
+#define SPACEORB_PACKET_SIZE 60
+#define SPACEORB_R_BODY_LEN 50
+#define SPACEORB_K_BODY_LEN 4
+#define SPACEORB_D_BODY_LEN 11
+#define SPACEORB_R_PACKET 'R'
+#define SPACEORB_K_PACKET 'K'
+#define SPACEORB_D_PACKET 'D'
+
+typedef enum
+{
+ SPACEORB_normal, SPACEORB_body, SPACEORB_Dbody
+}
+SPACEORBState;
+
+#define WORD_ASSEMBLY(byte1, byte2) (((byte2) << 8) | (byte1))
+
+typedef struct _SPACEORBPrivateRec
+{
+ XISBuffer *buffer;
+ unsigned char packet_type;
+ unsigned char packet[SPACEORB_PACKET_SIZE]; /* packet being/just read */
+ int packeti; /* index into packet */
+ int expected_len;
+ SPACEORBState lex_mode;
+ int old_buttons;
+}
+SPACEORBPrivateRec, *SPACEORBPrivatePtr;
+
+/******************************************************************************
+ * Declarations
+ *****************************************************************************/
+static MODULESETUPPROTO( SetupProc );
+static void TearDownProc (pointer p);
+static Bool DeviceControl (DeviceIntPtr, int);
+static Bool DeviceOn (DeviceIntPtr);
+static Bool DeviceOff (DeviceIntPtr);
+static Bool DeviceClose (DeviceIntPtr);
+static Bool DeviceInit (DeviceIntPtr);
+static void ReadInput (LocalDevicePtr);
+static int ControlProc (LocalDevicePtr, xDeviceCtl *);
+static void CloseProc (LocalDevicePtr);
+static int SwitchMode (ClientPtr, DeviceIntPtr, int);
+static Bool ConvertProc (LocalDevicePtr, int, int, int, int, int, int, int, int, int *, int *);
+static Bool QueryHardware (SPACEORBPrivatePtr, int *, int *);
+static Bool SPACEORBGetPacket (SPACEORBPrivatePtr priv);
+/*
+ * DO NOT PUT ANYTHING AFTER THIS ENDIF
+ */
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/input/summa/Imakefile b/xc/programs/Xserver/hw/xfree86/input/summa/Imakefile
new file mode 100644
index 000000000..2c0b914e2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/summa/Imakefile
@@ -0,0 +1,26 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/summa/Imakefile,v 1.4 1999/08/14 10:50:03 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = xf86Summa.c
+OBJS = xf86Summa.o
+
+DRIVER = xf86Summa
+
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86SRC)/loader -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget($(DRIVER),$(OBJS))
+
+InstallObjectModule($(DRIVER),$(MODULEDIR),input)
+
+DependTarget()
+
+InstallDriverSDKObjectModule($(DRIVER),$(DRIVERSDKMODULEDIR),input)
diff --git a/xc/programs/Xserver/hw/xfree86/input/summa/xf86Summa.c b/xc/programs/Xserver/hw/xfree86/input/summa/xf86Summa.c
new file mode 100644
index 000000000..d094da201
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/summa/xf86Summa.c
@@ -0,0 +1,1133 @@
+/*
+ * Copyright 1996 by Steven Lang <tiger@tyger.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Steven Lang not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. Steven Lang makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * STEVEN LANG DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL STEVEN LANG 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 ACTIONS, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/summa/xf86Summa.c,v 1.3 1999/06/13 05:18:56 dawes Exp $ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "XI.h"
+#include "XIproto.h"
+
+#if defined(sun) && !defined(i386)
+#define POSIX_TTY
+#include <errno.h>
+#include <termio.h>
+#include <fcntl.h>
+#include <ctype.h>
+
+#include "extio.h"
+#else
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSproc.h"
+#ifdef XFree86LOADER
+#include "xf86_ansic.h"
+#endif
+#include "xf86Config.h"
+#include "xf86Xinput.h"
+#include "atKeynames.h"
+#include "xf86Version.h"
+#endif
+
+#if !defined(sun) || defined(i386)
+#include "osdep.h"
+#include "exevents.h"
+
+#include "extnsionst.h"
+#include "extinit.h"
+#endif
+
+/*
+** Debugging macros
+*/
+#ifdef DBG
+#undef DBG
+#endif
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+static int debug_level = 0;
+#define DEBUG 1
+#if DEBUG
+#define DBG(lvl, f) {if ((lvl) <= debug_level) f;}
+#else
+#define DBG(lvl, f)
+#endif
+
+/*
+** Device records
+*/
+#define ABSOLUTE_FLAG 1
+#define STYLUS_FLAG 2
+
+typedef struct
+{
+ char *sumDevice; /* device file name */
+ int sumInc; /* increment between transmits */
+ int sumButTrans; /* button translation flags */
+ int sumOldX; /* previous X position */
+ int sumOldY; /* previous Y position */
+ int sumOldProximity; /* previous proximity */
+ int sumOldButtons; /* previous buttons state */
+ int sumMaxX; /* max X value */
+ int sumMaxY; /* max Y value */
+ int sumXSize; /* active area X size */
+ int sumXOffset; /* active area X offset */
+ int sumYSize; /* active area Y size */
+ int sumYOffset; /* active area Y offset */
+ int sumRes; /* resolution in lines per inch */
+ int flags; /* various flags */
+ int sumIndex; /* number of bytes read */
+ unsigned char sumData[5]; /* data read on the device */
+} SummaDeviceRec, *SummaDevicePtr;
+
+/*
+** Configuration data
+*/
+#define SUMMA_SECTION_NAME "SummaSketch"
+#define PORT 1
+#define DEVICENAME 2
+#define THE_MODE 3
+#define CURSOR 4
+#define INCREMENT 5
+#define BORDER 6
+#define DEBUG_LEVEL 7
+#define HISTORY_SIZE 8
+#define ALWAYS_CORE 9
+#define ACTIVE_AREA 10
+#define ACTIVE_OFFSET 11
+
+#if !defined(sun) || defined(i386)
+static SymTabRec SumTab[] = {
+ {ENDSUBSECTION, "endsubsection"},
+ {PORT, "port"},
+ {DEVICENAME, "devicename"},
+ {THE_MODE, "mode"},
+ {CURSOR, "cursor"},
+ {INCREMENT, "increment"},
+ {BORDER, "border"},
+ {DEBUG_LEVEL, "debuglevel"},
+ {HISTORY_SIZE, "historysize"},
+ {ALWAYS_CORE, "alwayscore"},
+ {ACTIVE_AREA, "activearea"},
+ {ACTIVE_OFFSET, "activeoffset"},
+ {-1, ""}
+};
+
+#define RELATIVE 1
+#define ABSOLUTE 2
+
+static SymTabRec SumModeTabRec[] = {
+ {RELATIVE, "relative"},
+ {ABSOLUTE, "absolute"},
+ {-1, ""}
+};
+
+#define PUCK 1
+#define STYLUS 2
+
+static SymTabRec SumPointTabRec[] = {
+ {PUCK, "puck"},
+ {STYLUS, "stylus"},
+ {-1, ""}
+};
+
+#endif
+
+/*
+** Contants and macro
+*/
+#define BUFFER_SIZE 256 /* size of reception buffer */
+#define XI_NAME "SUMMA" /* X device name for the stylus */
+
+#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
+
+#define SS_TABID0 "0" /* Tablet ID 0 */
+#define SS_FIRMID "z?" /* Request firmware ID string */
+#define SS_CONFIG "a" /* Send configuration (max coords) */
+
+#define SS_ABSOLUTE 'F' /* Absolute mode */
+#define SS_RELATIVE 'E' /* Relative mode */
+
+#define SS_UPPER_ORIGIN "b" /* Origin upper left */
+#define SS_500LPI "h" /* 500 lines per inch */
+
+#define SS_PROMPT_MODE "B" /* Prompt mode */
+#define SS_STREAM_MODE "@" /* Stream mode */
+#define SS_INCREMENT 'I' /* Set increment */
+#define SS_BINARY_FMT "zb" /* Binary reporting */
+
+#define SS_PROMPT "P" /* Prompt for current position */
+
+static const char * ss_initstr = SS_TABID0 SS_UPPER_ORIGIN SS_BINARY_FMT SS_STREAM_MODE;
+
+#define PHASING_BIT 0x80
+#define PROXIMITY_BIT 0x40
+#define TABID_BIT 0x20
+#define XSIGN_BIT 0x10
+#define YSIGN_BIT 0x08
+#define BUTTON_BITS 0x07
+#define COORD_BITS 0x7f
+
+/*
+** External declarations
+*/
+#if defined(sun) && !defined(i386)
+#define ENQUEUE suneqEnqueue
+#else
+#define ENQUEUE xf86eqEnqueue
+
+extern void xf86eqEnqueue(
+#if NeedFunctionPrototypes
+ xEventPtr /*e*/
+#endif
+);
+#endif
+
+extern void miPointerDeltaCursor(
+#if NeedFunctionPrototypes
+ int /*dx*/,
+ int /*dy*/,
+ unsigned long /*time*/
+#endif
+);
+
+#if !defined(sun) || defined(i386)
+/*
+** xf86SumConfig
+** Reads the SummaSketch section from the XF86Config file
+*/
+static Bool
+xf86SumConfig(LocalDevicePtr *array, int inx, int max, LexPtr val)
+{
+ LocalDevicePtr dev = array[inx];
+ SummaDevicePtr priv = (SummaDevicePtr)(dev->private);
+ int token;
+ int mtoken;
+
+ DBG(1, ErrorF("xf86SumConfig\n"));
+
+ while ((token = xf86GetToken(SumTab)) != ENDSUBSECTION) {
+ switch(token) {
+ case DEVICENAME:
+ if (xf86GetToken(NULL) != STRING)
+ xf86ConfigError("Option string expected");
+ else {
+ dev->name = strdup(val->str);
+ if (xf86Verbose)
+ ErrorF("%s SummaSketch X device name is %s\n", XCONFIG_GIVEN,
+ dev->name);
+ }
+ break;
+
+ case PORT:
+ if (xf86GetToken(NULL) != STRING)
+ xf86ConfigError("Option string expected");
+ else {
+ priv->sumDevice = strdup(val->str);
+ if (xf86Verbose)
+ ErrorF("%s SummaSketch port is %s\n", XCONFIG_GIVEN,
+ priv->sumDevice);
+ }
+ break;
+
+ case THE_MODE:
+ mtoken = xf86GetToken(SumModeTabRec);
+ if ((mtoken == EOF) || (mtoken == STRING) || (mtoken == NUMBER))
+ xf86ConfigError("Mode type token expected");
+ else {
+ switch (mtoken) {
+ case ABSOLUTE:
+ priv->flags |= ABSOLUTE_FLAG;
+ break;
+ case RELATIVE:
+ priv->flags &= ~ABSOLUTE_FLAG;
+ break;
+ default:
+ xf86ConfigError("Illegal Mode type");
+ break;
+ }
+ }
+ break;
+
+ case CURSOR:
+ mtoken = xf86GetToken(SumPointTabRec);
+ if ((mtoken == EOF) || (mtoken == STRING) || (mtoken == NUMBER))
+ xf86ConfigError("Cursor token expected");
+ else {
+ switch (mtoken) {
+ case STYLUS:
+ priv->flags |= STYLUS_FLAG;
+ break;
+ case PUCK:
+ priv->flags &= ~STYLUS_FLAG;
+ break;
+ default:
+ xf86ConfigError("Illegal cursor type");
+ break;
+ }
+ }
+ break;
+
+ case INCREMENT:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ priv->sumInc = val->num;
+ if (xf86Verbose)
+ ErrorF("%s SummaSketch increment value is %d\n", XCONFIG_GIVEN,
+ priv->sumInc);
+ break;
+
+ case DEBUG_LEVEL:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ debug_level = val->num;
+ if (xf86Verbose) {
+#if DEBUG
+ ErrorF("%s SummaSketch debug level sets to %d\n", XCONFIG_GIVEN,
+ debug_level);
+#else
+ ErrorF("%s SummaSketch debug level not sets to %d because"
+ " debugging is not compiled\n", XCONFIG_GIVEN,
+ debug_level);
+#endif
+ }
+ break;
+
+ case HISTORY_SIZE:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ dev->history_size = val->num;
+ if (xf86Verbose)
+ ErrorF("%s SummaSketch Motion history size is %d\n", XCONFIG_GIVEN,
+ dev->history_size);
+ break;
+
+ case ALWAYS_CORE:
+ xf86AlwaysCore(dev, TRUE);
+ if (xf86Verbose)
+ ErrorF("%s SummaSketch device always stays core pointer\n",
+ XCONFIG_GIVEN);
+ break;
+
+ case ACTIVE_AREA:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ priv->sumXSize = val->num;
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ priv->sumYSize = val->num;
+ if (xf86Verbose)
+ ErrorF("%s SummaSketch active area set to %d.%1dx%d.%1d"
+ " inches\n", XCONFIG_GIVEN, priv->sumXSize / 10,
+ priv->sumXSize % 10, priv->sumYSize / 10,
+ priv->sumYSize % 10);
+ break;
+
+ case ACTIVE_OFFSET:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ priv->sumXOffset = val->num;
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ priv->sumYOffset = val->num;
+ if (xf86Verbose)
+ ErrorF("%s SummaSketch active area offset set to %d.%1dx%d.%1d"
+ " inches\n", XCONFIG_GIVEN, priv->sumXOffset / 10,
+ priv->sumXOffset % 10, priv->sumYOffset / 10,
+ priv->sumYOffset % 10);
+ break;
+
+ case EOF:
+ FatalError("Unexpected EOF (missing EndSubSection)");
+ break;
+
+ default:
+ xf86ConfigError("SummaSketch subsection keyword expected");
+ break;
+ }
+ }
+
+ DBG(1, ErrorF("xf86SumConfig name=%s\n", priv->sumDevice));
+
+ return Success;
+}
+#endif
+
+/*
+** xf86SumConvert
+** Convert valuators to X and Y.
+*/
+static Bool
+xf86SumConvert(LocalDevicePtr local,
+ int first,
+ int num,
+ int v0,
+ int v1,
+ int v2,
+ int v3,
+ int v4,
+ int v5,
+ int* x,
+ int* y)
+{
+ SummaDevicePtr priv = (SummaDevicePtr) local->private;
+
+ if (first != 0 || num == 1)
+ return FALSE;
+
+ *x = (v0 - priv->sumXOffset) * screenInfo.screens[0]->width / priv->sumXSize;
+ *y = (v1 - priv->sumYOffset) * screenInfo.screens[0]->height / priv->sumYSize;
+ if (*x < 0)
+ *x = 0;
+ if (*y < 0)
+ *y = 0;
+ if (*x > screenInfo.screens[0]->width)
+ *x = screenInfo.screens[0]->width;
+ if (*y > screenInfo.screens[0]->height)
+ *y = screenInfo.screens[0]->height;
+
+ DBG(6, ErrorF("Adjusted coords x=%d y=%d\n", *x, *y));
+
+ return TRUE;
+}
+
+/*
+** xf86SumReadInput
+** Reads from the SummaSketch and posts any new events to the server.
+*/
+static void
+xf86SumReadInput(LocalDevicePtr local)
+{
+ SummaDevicePtr priv = (SummaDevicePtr) local->private;
+ int len, loop;
+ int is_absolute;
+ int x, y, buttons, prox;
+ DeviceIntPtr device;
+ unsigned char buffer[BUFFER_SIZE];
+
+ DBG(7, ErrorF("xf86SumReadInput BEGIN device=%s fd=%d\n",
+ priv->sumDevice, local->fd));
+
+ SYSCALL(len = read(local->fd, buffer, sizeof(buffer)));
+
+ if (len <= 0) {
+ Error("error reading SummaSketch device");
+ return;
+ }
+
+ for(loop=0; loop<len; loop++) {
+
+/* Format of 5 bytes data packet for SummaSketch Tablets
+ Byte 1
+ bit 7 Phasing bit always 1
+ bit 6 Proximity bit
+ bit 5 Tablet ID
+ bit 4 X sign (Always 1 for absolute)
+ bit 3 Y sign (Always 1 for absolute)
+ bit 2-0 Button status
+
+ Byte 2
+ bit 7 Always 0
+ bits 6-0 = X6 - X0
+
+ Byte 3 (Absolute mode only)
+ bit 7 Always 0
+ bits 6-0 = X13 - X7
+
+ Byte 4
+ bit 7 Always 0
+ bits 6-0 = Y6 - Y0
+
+ Byte 5 (Absolute mode only)
+ bit 7 Always 0
+ bits 6-0 = Y13 - Y7
+*/
+
+ if ((priv->sumIndex == 0) && !(buffer[loop] & PHASING_BIT)) { /* magic bit is not OK */
+ DBG(6, ErrorF("xf86SumReadInput bad magic number 0x%x\n", buffer[loop]));;
+ continue;
+ }
+
+ priv->sumData[priv->sumIndex++] = buffer[loop];
+
+ if (priv->sumIndex == (priv->flags & ABSOLUTE_FLAG? 5: 3)) {
+/* the packet is OK */
+/* reset char count for next read */
+ priv->sumIndex = 0;
+
+ if (priv->flags & ABSOLUTE_FLAG) {
+ x = (int)priv->sumData[1] + ((int)priv->sumData[2] << 7);
+ y = (int)priv->sumData[3] + ((int)priv->sumData[4] << 7);
+ } else {
+ x = priv->sumData[0] & XSIGN_BIT? priv->sumData[1]: -priv->sumData[1];
+ y = priv->sumData[0] & YSIGN_BIT? priv->sumData[2]: -priv->sumData[2];
+ }
+ prox = (priv->sumData[0] & PROXIMITY_BIT)? 0: 1;
+
+ buttons = (priv->sumData[0] & BUTTON_BITS);
+
+ device = local->dev;
+
+ DBG(6, ErrorF("prox=%s\tx=%d\ty=%d\tbuttons=%d\n",
+ prox ? "true" : "false", x, y, buttons));
+
+ is_absolute = (priv->flags & ABSOLUTE_FLAG);
+
+/* coordonates are ready we can send events */
+ if (prox) {
+ if (!(priv->sumOldProximity))
+ xf86PostProximityEvent(device, 1, 0, 2, x, y);
+
+ if ((is_absolute && ((priv->sumOldX != x) || (priv->sumOldY != y)))
+ || (!is_absolute && (x || y))) {
+ if (is_absolute || priv->sumOldProximity) {
+ xf86PostMotionEvent(device, is_absolute, 0, 2, x, y);
+ }
+ }
+ if (priv->sumOldButtons != buttons) {
+ int delta;
+ int button;
+
+ delta = buttons - priv->sumOldButtons;
+ button = (delta > 0)? delta: ((delta == 0)?
+ priv->sumOldButtons : -delta);
+
+ if (priv->sumOldButtons != buttons) {
+ DBG(6, ErrorF("xf86SumReadInput button=%d delta=%d\n", button,
+ delta));
+
+ xf86PostButtonEvent(device, is_absolute, button,
+ (delta > 0), 0, 2, x, y);
+ }
+ }
+ priv->sumOldButtons = buttons;
+ priv->sumOldX = x;
+ priv->sumOldY = y;
+ priv->sumOldProximity = prox;
+ } else { /* !PROXIMITY */
+/* Any changes in buttons are ignored when !proximity */
+ if (priv->sumOldProximity)
+ xf86PostProximityEvent(device, 0, 0, 2, x, y);
+ priv->sumOldProximity = 0;
+ }
+ }
+ }
+ DBG(7, ErrorF("xf86SumReadInput END device=0x%x priv=0x%x\n",
+ local->dev, priv));
+}
+
+/*
+** xf86SumControlProc
+** It really does do something. Honest!
+*/
+static void
+xf86SumControlProc(DeviceIntPtr device, PtrCtrl *ctrl)
+{
+ DBG(2, ErrorF("xf86SumControlProc\n"));
+}
+
+/*
+** xf86SumWriteAndRead
+** Write data, and get the response.
+*/
+static char *
+xf86SumWriteAndRead(int fd, char *data, char *buffer, int len, int cr_term)
+{
+ int err, numread = 0;
+ fd_set readfds;
+ struct timeval timeout;
+
+ SYSCALL(err = write(fd, data, strlen(data)));
+ if (err == -1) {
+ Error("SummaSketch write");
+ return NULL;
+ }
+
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+ while (numread < len) {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 200000;
+
+ SYSCALL(err = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout));
+ if (err == -1) {
+ Error("SummaSketch select");
+ return NULL;
+ }
+ if (!err) {
+ ErrorF("Timeout while reading SummaSketch tablet. No tablet connected ???\n");
+ return NULL;
+ }
+
+ SYSCALL(err = read(fd, buffer + numread++, 1));
+ if (err == -1) {
+ Error("SummaSketch read");
+ return NULL;
+ }
+ if (!err) {
+ --numread;
+ break;
+ }
+ if (cr_term && buffer[numread - 1] == '\r') {
+ buffer[numread - 1] = 0;
+ break;
+ }
+ }
+ buffer[numread] = 0;
+ return buffer;
+}
+
+/*
+** xf86SumOpen
+** Open and initialize the tablet, as well as probe for any needed data.
+*/
+static Bool
+xf86SumOpen(LocalDevicePtr local)
+{
+ struct termios termios_tty;
+ struct timeval timeout;
+ char buffer[256];
+ int err, idx;
+ SummaDevicePtr priv = (SummaDevicePtr)local->private;
+
+ DBG(1, ErrorF("opening %s\n", priv->sumDevice));
+
+ SYSCALL(local->fd = open(priv->sumDevice, O_RDWR|O_NDELAY, 0));
+ if (local->fd == -1) {
+ Error(priv->sumDevice);
+ return !Success;
+ }
+ DBG(2, ErrorF("%s opened as fd %d\n", priv->sumDevice, local->fd));
+
+#ifdef POSIX_TTY
+ err = tcgetattr(local->fd, &termios_tty);
+ if (err == -1) {
+ Error("SummaSketch tcgetattr");
+ return !Success;
+ }
+ termios_tty.c_iflag = IXOFF;
+ termios_tty.c_cflag = B9600|CS8|CREAD|CLOCAL|HUPCL|PARENB|PARODD;
+ termios_tty.c_lflag = 0;
+
+/* I wonder what these all do, anyway */
+ termios_tty.c_cc[VINTR] = 0;
+ termios_tty.c_cc[VQUIT] = 0;
+ termios_tty.c_cc[VERASE] = 0;
+#ifdef VWERASE
+ termios_tty.c_cc[VWERASE] = 0;
+#endif
+#ifdef VREPRINT
+ termios_tty.c_cc[VREPRINT] = 0;
+#endif
+ termios_tty.c_cc[VKILL] = 0;
+ termios_tty.c_cc[VEOF] = 0;
+ termios_tty.c_cc[VEOL] = 0;
+#ifdef VEOL2
+ termios_tty.c_cc[VEOL2] = 0;
+#endif
+ termios_tty.c_cc[VSUSP] = 0;
+#ifdef VDISCARD
+ termios_tty.c_cc[VDISCARD] = 0;
+#endif
+#ifdef VLNEXT
+ termios_tty.c_cc[VLNEXT] = 0;
+#endif
+
+ termios_tty.c_cc[VMIN] = 1 ;
+ termios_tty.c_cc[VTIME] = 10 ;
+
+ err = tcsetattr(local->fd, TCSANOW, &termios_tty);
+ if (err == -1) {
+ Error("SummaSketch tcsetattr TCSANOW");
+ return !Success;
+ }
+#else
+ Code for someone else to write to handle OSs without POSIX tty functions
+#endif
+
+ DBG(1, ErrorF("initializing SummaSketch tablet\n"));
+
+/* Send reset (NULL) to the tablet */
+ SYSCALL(err = write(local->fd, "", 1));
+ if (err == -1) {
+ Error("SummaSketch write");
+ return !Success;
+ }
+
+/* wait 200 mSecs, just in case */
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 200000;
+ SYSCALL(err = select(0, NULL, NULL, NULL, &timeout));
+ if (err == -1) {
+ Error("SummaSketch select");
+ return !Success;
+ }
+
+/* Put it in prompt mode so it doens't say anything before we're ready */
+ SYSCALL(err = write(local->fd, SS_PROMPT_MODE, strlen(SS_PROMPT_MODE)));
+ if (err == -1) {
+ Error("SummaSketch write");
+ return !Success;
+ }
+/* Clear any pending input */
+ tcflush(local->fd, TCIFLUSH);
+
+ DBG(2, ErrorF("reading firmware ID\n"));
+ if (!xf86SumWriteAndRead(local->fd, SS_FIRMID, buffer, 255, 1))
+ return !Success;
+
+ DBG(2, ErrorF("%s\n", buffer));
+
+ if (xf86Verbose)
+ ErrorF("%s SummaSketch firmware ID : %s\n", XCONFIG_PROBED, buffer);
+
+ DBG(2, ErrorF("reading max coordinates\n"));
+ if (!xf86SumWriteAndRead(local->fd, SS_500LPI SS_CONFIG, buffer, 5, 0))
+ return !Success;
+ priv->sumMaxX = (int)buffer[1] + ((int)buffer[2] << 7);
+ priv->sumMaxY = (int)buffer[3] + ((int)buffer[4] << 7);
+
+ if (xf86Verbose)
+ ErrorF("%s SummaSketch tablet size is %d.%1dinx%d.%1din, %dx%d "
+ "lines of resolution\n", XCONFIG_PROBED,
+ priv->sumMaxX / 500, (priv->sumMaxX / 50) % 10,
+ priv->sumMaxY / 500, (priv->sumMaxY / 50) % 10,
+ priv->sumMaxX, priv->sumMaxY);
+
+ if (priv->sumXSize > 0 && priv->sumYSize > 0) {
+ if (priv->sumXSize * 50 < priv->sumMaxX &&
+ priv->sumYSize * 50 < priv->sumMaxY) {
+ priv->sumXSize *= 50;
+ priv->sumYSize *= 50;
+ } else {
+ ErrorF("%s SummaSketch active area bigger than tablet, "
+ "assuming maximum\n", XCONFIG_PROBED);
+ priv->sumXSize = priv->sumMaxX;
+ priv->sumYSize = priv->sumMaxX;
+ }
+ } else {
+ priv->sumXSize = priv->sumMaxX;
+ priv->sumYSize = priv->sumMaxY;
+ }
+
+ if (priv->sumXOffset > 0 && priv->sumYOffset > 0) {
+ if (priv->sumXSize * 50 < priv->sumMaxX - priv->sumXOffset &&
+ priv->sumYSize * 50 < priv->sumMaxY - priv->sumYOffset) {
+ priv->sumXOffset *= 50;
+ priv->sumYOffset *= 50;
+ } else {
+ ErrorF("%s SummaSketch offset sets active area off tablet, "
+ "centering\n", XCONFIG_PROBED);
+ priv->sumXOffset = (priv->sumMaxX - priv->sumXSize) / 2;
+ priv->sumYOffset = (priv->sumMaxY - priv->sumYSize) / 2;
+ }
+ } else {
+ priv->sumXOffset = (priv->sumMaxX - priv->sumXSize) / 2;
+ priv->sumYOffset = (priv->sumMaxY - priv->sumYSize) / 2;
+ }
+
+ if (priv->sumInc > 95)
+ priv->sumInc = 95;
+ if (priv->sumInc < 1) {
+/* Make a guess as to the best increment value given video mode */
+ if (priv->sumXSize / screenInfo.screens[0]->width <
+ priv->sumYSize / screenInfo.screens[0]->height)
+ priv->sumInc = priv->sumXSize / screenInfo.screens[0]->width;
+ else
+ priv->sumInc = priv->sumYSize / screenInfo.screens[0]->height;
+ if (priv->sumInc < 1)
+ priv->sumInc = 1;
+ if (xf86Verbose)
+ ErrorF("%s Using increment value of %d\n", XCONFIG_PROBED,
+ priv->sumInc);
+ }
+
+/* Sets up the tablet mode to increment, stream, and such */
+ for (idx = 0; ss_initstr[idx]; idx++) {
+ buffer[idx] = ss_initstr[idx];
+ }
+ buffer[idx++] = SS_INCREMENT;
+ buffer[idx++] = 32 + priv->sumInc;
+ buffer[idx++] = (priv->flags & ABSOLUTE_FLAG)?
+ SS_ABSOLUTE: SS_RELATIVE;
+ buffer[idx] = 0;
+
+ SYSCALL(err = write(local->fd, buffer, idx));
+ if (err == -1) {
+ Error("SummaSketch write");
+ return !Success;
+ }
+
+ if (err <= 0) {
+ SYSCALL(close(local->fd));
+ return !Success;
+ }
+
+ return Success;
+}
+
+/*
+** xf86SumOpenDevice
+** Opens and initializes the device driver stuff or sumpthin.
+*/
+static int
+xf86SumOpenDevice(DeviceIntPtr pSum)
+{
+ LocalDevicePtr local = (LocalDevicePtr)pSum->public.devicePrivate;
+ SummaDevicePtr priv = (SummaDevicePtr)XI_PRIVATE(pSum);
+
+ if (xf86SumOpen(local) != Success) {
+ if (local->fd >= 0) {
+ SYSCALL(close(local->fd));
+ }
+ local->fd = -1;
+ }
+
+/* Set the real values */
+ InitValuatorAxisStruct(pSum,
+ 0,
+ 0, /* min val */
+ priv->sumMaxX, /* max val */
+ 500000, /* resolution */
+ 0, /* min_res */
+ 500000); /* max_res */
+ InitValuatorAxisStruct(pSum,
+ 1,
+ 0, /* min val */
+ priv->sumMaxY, /* max val */
+ 500000, /* resolution */
+ 0, /* min_res */
+ 500000); /* max_res */
+ return (local->fd != -1);
+}
+
+/*
+** xf86SumProc
+** Handle requests to do stuff to the driver.
+*/
+static int
+xf86SumProc(DeviceIntPtr pSum, int what)
+{
+ CARD8 map[25];
+ int nbaxes;
+ int nbbuttons;
+ int loop;
+ LocalDevicePtr local = (LocalDevicePtr)pSum->public.devicePrivate;
+ SummaDevicePtr priv = (SummaDevicePtr)PRIVATE(pSum);
+
+ DBG(2, ErrorF("BEGIN xf86SumProc dev=0x%x priv=0x%x what=%d\n", pSum, priv, what));
+
+ switch (what) {
+ case DEVICE_INIT:
+ DBG(1, ErrorF("xf86SumProc pSum=0x%x what=INIT\n", pSum));
+
+ nbaxes = 2; /* X, Y */
+ nbbuttons = (priv->flags & STYLUS_FLAG)? 2: 4;
+
+ for(loop=1; loop<=nbbuttons; loop++) map[loop] = loop;
+
+ if (InitButtonClassDeviceStruct(pSum,
+ nbbuttons,
+ map) == FALSE) {
+ ErrorF("unable to allocate Button class device\n");
+ return !Success;
+ }
+
+ if (InitFocusClassDeviceStruct(pSum) == FALSE) {
+ ErrorF("unable to init Focus class device\n");
+ return !Success;
+ }
+
+ if (InitPtrFeedbackClassDeviceStruct(pSum,
+ xf86SumControlProc) == FALSE) {
+ ErrorF("unable to init ptr feedback\n");
+ return !Success;
+ }
+
+ if (InitProximityClassDeviceStruct(pSum) == FALSE) {
+ ErrorF("unable to init proximity class device\n");
+ return !Success;
+ }
+
+ if (InitValuatorClassDeviceStruct(pSum,
+ nbaxes,
+ xf86GetMotionEvents,
+ local->history_size,
+ (priv->flags & ABSOLUTE_FLAG)? Absolute: Relative)
+ == FALSE) {
+ ErrorF("unable to allocate Valuator class device\n");
+ return !Success;
+ }
+/* allocate the motion history buffer if needed */
+ xf86MotionHistoryAllocate(local);
+
+ AssignTypeAndName(pSum, local->atom, local->name);
+/* open the device to gather informations */
+ xf86SumOpenDevice(pSum);
+ break;
+
+ case DEVICE_ON:
+ DBG(1, ErrorF("xf86SumProc pSum=0x%x what=ON\n", pSum));
+
+ if ((local->fd < 0) && (!xf86SumOpenDevice(pSum))) {
+ return !Success;
+ }
+ SYSCALL(write(local->fd, SS_PROMPT, strlen(SS_PROMPT)));
+ AddEnabledDevice(local->fd);
+ pSum->public.on = TRUE;
+ break;
+
+ case DEVICE_OFF:
+ DBG(1, ErrorF("xf86SumProc pSum=0x%x what=%s\n", pSum,
+ (what == DEVICE_CLOSE) ? "CLOSE" : "OFF"));
+ if (local->fd >= 0)
+ RemoveEnabledDevice(local->fd);
+ pSum->public.on = FALSE;
+ break;
+
+ case DEVICE_CLOSE:
+ DBG(1, ErrorF("xf86SumProc pSum=0x%x what=%s\n", pSum,
+ (what == DEVICE_CLOSE) ? "CLOSE" : "OFF"));
+ SYSCALL(close(local->fd));
+ local->fd = -1;
+ break;
+
+ default:
+ ErrorF("unsupported mode=%d\n", what);
+ return !Success;
+ break;
+ }
+ DBG(2, ErrorF("END xf86SumProc Success what=%d dev=0x%x priv=0x%x\n",
+ what, pSum, priv));
+ return Success;
+}
+
+/*
+** xf86SumClose
+** It... Uh... Closes the physical device?
+*/
+static void
+xf86SumClose(LocalDevicePtr local)
+{
+ if (local->fd >= 0) {
+ SYSCALL(close(local->fd));
+ }
+ local->fd = -1;
+}
+
+/*
+** xf86SumChangeControl
+** When I figure out what it does, it will do it.
+*/
+static int
+xf86SumChangeControl(LocalDevicePtr local, pointer control)
+{
+ xDeviceResolutionCtl *res;
+
+ res = (xDeviceResolutionCtl *)control;
+
+ if ((res->control != DEVICE_RESOLUTION) ||
+ (res->num_valuators < 1))
+ return (BadMatch);
+
+ return(Success);
+}
+
+/*
+** xf86SumSwitchMode
+** Switches the mode. For now just absolute or relative, hopefully
+** more on the way.
+*/
+static int
+xf86SumSwitchMode(ClientPtr client, DeviceIntPtr dev, int mode)
+{
+ LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
+ SummaDevicePtr priv = (SummaDevicePtr)(local->private);
+ char newmode;
+
+ DBG(3, ErrorF("xf86SumSwitchMode dev=0x%x mode=%d\n", dev, mode));
+
+ switch(mode) {
+ case Absolute:
+ priv->flags |= ABSOLUTE_FLAG;
+ newmode = SS_ABSOLUTE;
+ break;
+
+ case Relative:
+ priv->flags &= ~ABSOLUTE_FLAG;
+ newmode = SS_RELATIVE;
+ break;
+
+ default:
+ DBG(1, ErrorF("xf86SumSwitchMode dev=0x%x invalid mode=%d\n",
+ dev, mode));
+ return BadMatch;
+ }
+ SYSCALL(write(local->fd, &newmode, 1));
+ return Success;
+}
+
+/*
+** xf86SumAllocate
+** Allocates the device structures for the SummaSketch.
+*/
+static LocalDevicePtr
+xf86SumAllocate()
+{
+ LocalDevicePtr local = xalloc(sizeof(LocalDeviceRec));
+ SummaDevicePtr priv = xalloc(sizeof(SummaDeviceRec));
+#if defined (sun) && !defined(i386)
+ char *dev_name = getenv("SUMMASKETCH_DEV");
+#endif
+
+ local->name = XI_NAME;
+ local->type_name = "SummaSketch Tablet";
+ local->flags = 0;
+#if !defined(sun) || defined(i386)
+ local->device_config = xf86SumConfig;
+#endif
+ local->device_control = xf86SumProc;
+ local->read_input = xf86SumReadInput;
+ local->control_proc = xf86SumChangeControl;
+ local->close_proc = xf86SumClose;
+ local->switch_mode = xf86SumSwitchMode;
+ local->conversion_proc = xf86SumConvert;
+ local->fd = -1;
+ local->atom = 0;
+ local->dev = NULL;
+ local->private = priv;
+ local->private_flags = 0;
+ local->history_size = 0;
+
+#if defined(sun) && !defined(i386)
+ if (def_name) {
+ priv->sumDevice = xalloc(strlen(dev_name) + 1);
+ strcpy(priv->sumDevice, device_name);
+ ErrorF("xf86SumOpen port changed to '%s'\n", priv->sumDevice);
+ } else {
+ priv->sumDevice = "";
+ }
+#else
+ priv->sumDevice = ""; /* device file name */
+#endif
+ priv->sumInc = -1; /* re-transmit position on increment */
+ priv->sumOldX = -1; /* previous X position */
+ priv->sumOldY = -1; /* previous Y position */
+ priv->sumOldProximity = 0; /* previous proximity */
+ priv->sumOldButtons = 0; /* previous buttons state */
+ priv->sumMaxX = -1; /* max X value */
+ priv->sumMaxY = -1; /* max Y value */
+ priv->sumXSize = -1; /* active area X */
+ priv->sumXOffset = -1; /* active area X offset */
+ priv->sumYSize = -1; /* active area Y */
+ priv->sumYOffset = -1; /* active area U offset */
+ priv->flags = 0; /* various flags */
+ priv->sumIndex = 0; /* number of bytes read */
+
+ return local;
+}
+
+
+/*
+** SummaSketch device association
+** Device section name and allocation function.
+*/
+DeviceAssocRec summasketch_assoc =
+{
+ SUMMA_SECTION_NAME, /* config_section_name */
+ xf86SumAllocate /* device_allocate */
+};
+
+#ifdef DYNAMIC_MODULE
+/*
+** init_module
+** Entry point for dynamic module.
+*/
+int
+#ifndef DLSYM_BUG
+init_module(unsigned long server_version)
+#else
+init_xf86Summa(unsigned long server_version)
+#endif
+{
+ xf86AddDeviceAssoc(&summasketch_assoc);
+
+ if (server_version != XF86_VERSION_CURRENT) {
+ ErrorF("Warning: SummaKetch module compiled for version%s\n",
+ XF86_VERSION);
+ return 0;
+ } else {
+ return 1;
+ }
+}
+#endif
+
+#ifdef XFree86LOADER
+/*
+ * Entry point for the loader code
+ */
+XF86ModuleVersionInfo xf86SummaVersion = {
+ "xf86Summa",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 0x00010000,
+ {0,0,0,0}
+};
+
+void
+xf86SummaModuleInit(data, magic)
+ pointer *data;
+ INT32 *magic;
+{
+ static int cnt = 0;
+
+ switch (cnt) {
+ case 0:
+ *magic = MAGIC_VERSION;
+ *data = &xf86SummaVersion;
+ cnt++;
+ break;
+
+ case 1:
+ *magic = MAGIC_ADD_XINPUT_DEVICE;
+ *data = &summasketch_assoc;
+ cnt++;
+ break;
+
+ default:
+ *magic = MAGIC_DONE;
+ *data = NULL;
+ break;
+ }
+}
+#endif
+/* end of xf86Summa.c */
diff --git a/xc/programs/Xserver/hw/xfree86/input/wacom/Imakefile b/xc/programs/Xserver/hw/xfree86/input/wacom/Imakefile
new file mode 100644
index 000000000..17ffb40b4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/wacom/Imakefile
@@ -0,0 +1,26 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/input/wacom/Imakefile,v 1.5 1999/08/14 10:50:04 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS = xf86Wacom.c
+OBJS = xf86Wacom.o
+
+DRIVER = wacom
+
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86SRC)/loader -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(SERVERSRC)/mi -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+#if MakeHasPosixVariableSubstitutions
+SubdirLibraryRule($(OBJS))
+#endif
+
+ModuleObjectRule()
+
+ObjectModuleTarget($(DRIVER),$(OBJS))
+
+InstallObjectModule($(DRIVER),$(MODULEDIR),input)
+
+DependTarget()
+
+InstallDriverSDKObjectModule($(DRIVER),$(DRIVERSDKMODULEDIR),input)
diff --git a/xc/programs/Xserver/hw/xfree86/input/wacom/xf86Wacom.c b/xc/programs/Xserver/hw/xfree86/input/wacom/xf86Wacom.c
new file mode 100644
index 000000000..d14117181
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/input/wacom/xf86Wacom.c
@@ -0,0 +1,3116 @@
+/* $XConsortium: xf86Wacom.c /main/20 1996/10/27 11:05:20 kaleb $ */
+/*
+ * Copyright 1995-1999 by Frederic Lepied, France. <Lepied@XFree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Frederic Lepied not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Frederic Lepied makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * FREDERIC LEPIED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL FREDERIC LEPIED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/input/wacom/xf86Wacom.c,v 1.13 1999/07/12 05:10:46 dawes Exp $ */
+
+/*
+ * This driver is only able to handle the Wacom IV and Wacom V protocols.
+ *
+ * Wacom V protocol work done by Raph Levien <raph@gtk.org> and
+ * Frédéric Lepied <lepied@xfree86.org>.
+ *
+ * Many thanks to Dave Fleck from Wacom for the help provided to
+ * build this driver.
+ */
+
+/*
+ * Bugs fixed by Steve Day (Updated: Apr 5 1999)
+ *
+ * MaxX and MaxY values that the Wacom returns are now converted from
+ * 1270lpi to the actual X and Y resolutions that the tablet is using.
+ *
+ * Buffer bug fixed when reading X and Y resolutions from config
+ * string, now receives the true X and Y resolutions. This has the
+ * side effect of being more compatible with other models of Wacom
+ * that have varying lengths of headers.
+ *
+ * <steve@lineardesigns.co.uk>
+ *
+ */
+
+static const char identification[] = "$Identification: 8 $";
+
+#include <xf86Version.h>
+
+#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(3,9,0,0,0)
+#define XFREE86_V4 1
+#endif
+
+#ifdef XFREE86_V4
+/* post 3.9 headers */
+
+#ifndef XFree86LOADER
+#include <unistd.h>
+#include <errno.h>
+#endif
+
+#include <misc.h>
+#include <xf86.h>
+#define NEED_XF86_TYPES
+#include <xf86_ansic.h>
+#include <xf86_OSproc.h>
+#include <xf86Xinput.h>
+#include <xisb.h>
+#include <exevents.h> /* Needed for InitValuator/Proximity stuff */
+#include <keysym.h>
+#include <mipointer.h>
+
+#ifdef XFree86LOADER
+#include <xf86Module.h>
+#endif
+
+#undef memset
+#define memset xf86memset
+#undef sleep
+#define sleep(t) xf86WaitForInput(-1, 1000 * (t))
+#define wait_for_fd(fd) xf86WaitForInput((fd), 1000)
+#define tcflush(fd, n) xf86FlushInput((fd))
+#undef read
+#define read(a,b,c) xf86ReadSerial((a),(b),(c))
+#undef write
+#define write(a,b,c) xf86WriteSerial((a),(char*)(b),(c))
+#undef close
+#define close(a) xf86CloseSerial((a))
+#define XCONFIG_PROBED "(==)"
+#define XCONFIG_GIVEN "(**)"
+#define xf86Verbose 1
+#undef PRIVATE
+#define PRIVATE(x) XI_PRIVATE(x)
+
+/*
+ * Be sure to set vmin appropriately for your device's protocol. You want to
+ * read a full packet before returning
+ */
+static const char *default_options[] =
+{
+ "BaudRate", "9600",
+ "StopBits", "1",
+ "DataBits", "8",
+ "Parity", "None",
+ "Vmin", "1",
+ "Vtime", "10",
+ "FlowControl", "None",
+ NULL
+};
+
+static const char *b19200_options[] =
+{
+ "BaudRate", "19200",
+ "StopBits", "1",
+ "DataBits", "8",
+ "Parity", "None",
+ "Vmin", "1",
+ "Vtime", "10",
+ "FlowControl", "None",
+ NULL
+};
+
+static InputDriverPtr wcmDrv;
+
+#else /* pre 3.9 headers */
+
+#include "Xos.h"
+#include <signal.h>
+#include <stdio.h>
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "XI.h"
+#include "XIproto.h"
+#include "keysym.h"
+
+#if defined(sun) && !defined(i386)
+#define POSIX_TTY
+#include <errno.h>
+#include <termio.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <stdio.h>
+
+#include "extio.h"
+#else
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Procs.h"
+#include "xf86_OSlib.h"
+#include "xf86_Config.h"
+#include "xf86Xinput.h"
+#include "atKeynames.h"
+#include "xf86Version.h"
+#endif
+
+#if !defined(sun) || defined(i386)
+#include "osdep.h"
+#include "exevents.h"
+
+#include "extnsionst.h"
+#include "extinit.h"
+#endif
+
+#endif /* Pre 3.9 headers */
+
+/******************************************************************************
+ * debugging macro
+ *****************************************************************************/
+#ifdef DBG
+#undef DBG
+#endif
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+static int debug_level = 0;
+#define DEBUG 1
+#if DEBUG
+#define DBG(lvl, f) {if ((lvl) <= debug_level) f;}
+#else
+#define DBG(lvl, f)
+#endif
+
+/******************************************************************************
+ * WacomDeviceRec flags
+ *****************************************************************************/
+#define DEVICE_ID(flags) ((flags) & 0x07)
+
+#define STYLUS_ID 1
+#define CURSOR_ID 2
+#define ERASER_ID 4
+#define ABSOLUTE_FLAG 8
+#define FIRST_TOUCH_FLAG 16
+#define KEEP_SHAPE_FLAG 32
+#define BAUD_19200_FLAG 64
+
+/******************************************************************************
+ * WacomCommonRec flags
+ *****************************************************************************/
+#define TILT_FLAG 1
+
+typedef struct
+{
+ int state;
+ int coord[3];
+ int tilt[3];
+} WacomFilterState;
+
+typedef struct
+{
+ int device_id;
+ int device_type;
+ unsigned int serial_num;
+ int x;
+ int y;
+ int buttons;
+ int pressure;
+ int tiltx;
+ int tilty;
+ int rotation;
+ int wheel;
+ int discard_first;
+ int proximity;
+ WacomFilterState x_filter;
+ WacomFilterState y_filter;
+} WacomDeviceState;
+
+#define PEN(ds) (((ds->device_id) & 0x07ff) == 0x0022)
+#define AIRBRUSH(ds) (((ds->device_id) & 0x07ff) == 0x0112)
+#define MOUSE_4D(ds) (((ds->device_id) & 0x07ff) == 0x0094)
+#define LENS_CURSOR(ds) (((ds->device_id) & 0x07ff) == 0x0096)
+#define INKING_PEN(ds) (((ds->device_id) & 0x07ff) == 0x0012)
+
+typedef struct
+{
+ /* configuration fields */
+ unsigned char flags; /* various flags (device type, absolute, first touch...) */
+ int topX; /* X top */
+ int topY; /* Y top */
+ int bottomX; /* X bottom */
+ int bottomY; /* Y bottom */
+ double factorX; /* X factor */
+ double factorY; /* Y factor */
+ unsigned int serial; /* device serial number */
+
+ struct _WacomCommonRec *common; /* common info pointer */
+
+ /* state fields */
+ int oldX; /* previous X position */
+ int oldY; /* previous Y position */
+ int oldZ; /* previous pressure */
+ int oldTiltX; /* previous tilt in x direction */
+ int oldTiltY; /* previous tilt in y direction */
+ int oldWheel; /* previous wheel value */
+ int oldButtons; /* previous buttons state */
+ int oldProximity; /* previous proximity */
+} WacomDeviceRec, *WacomDevicePtr;
+
+typedef struct _WacomCommonRec
+{
+ char *wcmDevice; /* device file name */
+ int wcmSuppress; /* transmit position if increment is superior */
+ unsigned char wcmFlags; /* various flags (handle tilt) */
+ int wcmMaxX; /* max X value */
+ int wcmMaxY; /* max Y value */
+ int wcmMaxZ; /* max Z value */
+ int wcmResolX; /* X resolution in points/inch */
+ int wcmResolY; /* Y resolution in points/inch */
+ int wcmResolZ; /* Z resolution in points/inch */
+ LocalDevicePtr *wcmDevices; /* array of all devices sharing the same port */
+ int wcmNumDevices; /* number of devices */
+ int wcmIndex; /* number of bytes read */
+ int wcmPktLength; /* length of a packet */
+ unsigned char wcmData[9]; /* data read on the device */
+ Bool wcmHasEraser; /* True if an eraser has been configured */
+ Bool wcmStylusSide; /* eraser or stylus ? */
+ Bool wcmStylusProximity; /* the stylus is in proximity ? */
+ int wcmProtocolLevel; /* 4 for Wacom IV, 5 for Wacom V */
+ int wcmThreshold; /* Threshold for counting pressure as a button */
+ WacomDeviceState wcmDevStat[2]; /* device state for each tool */
+} WacomCommonRec, *WacomCommonPtr;
+
+/******************************************************************************
+ * configuration stuff
+ *****************************************************************************/
+#define CURSOR_SECTION_NAME "wacomcursor"
+#define STYLUS_SECTION_NAME "wacomstylus"
+#define ERASER_SECTION_NAME "wacomeraser"
+
+#ifndef XFREE86_V4
+
+#define PORT 1
+#define DEVICENAME 2
+#define THE_MODE 3
+#define SUPPRESS 4
+#define DEBUG_LEVEL 5
+#define TILT_MODE 6
+#define HISTORY_SIZE 7
+#define ALWAYS_CORE 8
+#define KEEP_SHAPE 9
+#define TOP_X 10
+#define TOP_Y 11
+#define BOTTOM_X 12
+#define BOTTOM_Y 13
+#define SERIAL 14
+#define BAUD_RATE 15
+
+#if !defined(sun) || defined(i386)
+static SymTabRec WcmTab[] = {
+ { ENDSUBSECTION, "endsubsection" },
+ { PORT, "port" },
+ { DEVICENAME, "devicename" },
+ { THE_MODE, "mode" },
+ { SUPPRESS, "suppress" },
+ { DEBUG_LEVEL, "debuglevel" },
+ { TILT_MODE, "tiltmode" },
+ { HISTORY_SIZE, "historysize" },
+ { ALWAYS_CORE, "alwayscore" },
+ { KEEP_SHAPE, "keepshape" },
+ { TOP_X, "topx" },
+ { TOP_Y, "topy" },
+ { BOTTOM_X, "bottomx" },
+ { BOTTOM_Y, "bottomy" },
+ { SERIAL, "serial" },
+ { BAUD_RATE, "baudrate" },
+ { -1, "" }
+};
+
+#define RELATIVE 1
+#define ABSOLUTE 2
+
+static SymTabRec ModeTabRec[] = {
+ { RELATIVE, "relative" },
+ { ABSOLUTE, "absolute" },
+ { -1, "" }
+};
+
+#endif
+
+#endif /* Pre 3.9 headers */
+
+/******************************************************************************
+ * constant and macros declarations
+ *****************************************************************************/
+#define BUFFER_SIZE 256 /* size of reception buffer */
+#define XI_STYLUS "STYLUS" /* X device name for the stylus */
+#define XI_CURSOR "CURSOR" /* X device name for the cursor */
+#define XI_ERASER "ERASER" /* X device name for the eraser */
+#define MAX_VALUE 100 /* number of positions */
+#define MAXTRY 3 /* max number of try to receive magic number */
+#define MAX_COORD_RES 1270.0 /* Resolution of the returned MaxX and MaxY */
+
+#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
+
+#define WC_RESET "\r#" /* reset to wacom IV command set or wacom V reset */
+#define WC_RESET_BAUD "\r$" /* reset baud rate to default (wacom V) or switch to wacom IIs (wacom IV) */
+#define WC_CONFIG "~R\r" /* request a configuration string */
+#define WC_COORD "~C\r" /* request max coordinates */
+#define WC_MODEL "~#\r" /* request model and ROM version */
+
+#define WC_MULTI "MU1\r" /* multi mode input */
+#define WC_UPPER_ORIGIN "OC1\r" /* origin in upper left */
+#define WC_SUPPRESS "SU" /* suppress mode */
+#define WC_ALL_MACRO "~M0\r" /* enable all macro buttons */
+#define WC_NO_MACRO1 "~M1\r" /* disable macro buttons of group 1 */
+#define WC_RATE "IT0\r" /* max transmit rate (unit of 5 ms) */
+#define WC_TILT_MODE "FM1\r" /* enable extra protocol for tilt management */
+#define WC_NO_INCREMENT "IN0\r" /* do not enable increment mode */
+#define WC_STREAM_MODE "SR\r" /* enable continuous mode */
+#define WC_PRESSURE_MODE "PH1\r" /* enable pressure mode */
+#define WC_STOP "\nSP\r" /* stop sending coordinates */
+#define WC_START "ST\r" /* start sending coordinates */
+#define WC_NEW_RESOLUTION "NR" /* change the resolution */
+
+static const char * setup_string = WC_MULTI WC_UPPER_ORIGIN
+ WC_ALL_MACRO WC_NO_MACRO1 WC_RATE WC_NO_INCREMENT WC_STREAM_MODE;
+
+static const char * penpartner_setup_string = WC_PRESSURE_MODE WC_START;
+
+#define WC_V_SINGLE "MT0\r"
+#define WC_V_MULTI "MT1\r"
+#define WC_V_ID "ID1\r"
+#define WC_V_19200 "BA19\r"
+/* #define WC_V_9600 "BA96\r" */
+#define WC_V_9600 "$\r"
+
+#define WC_RESET_19200 "\r$" /* reset to 9600 baud */
+#define WC_RESET_19200_IV "\r#"
+
+static const char * intuos_setup_string = WC_V_MULTI WC_V_ID WC_RATE;
+
+#define COMMAND_SET_MASK 0xc0
+#define BAUD_RATE_MASK 0x0a
+#define PARITY_MASK 0x30
+#define DATA_LENGTH_MASK 0x40
+#define STOP_BIT_MASK 0x80
+
+#define HEADER_BIT 0x80
+#define ZAXIS_SIGN_BIT 0x40
+#define ZAXIS_BIT 0x04
+#define ZAXIS_BITS 0x3f
+#define POINTER_BIT 0x20
+#define PROXIMITY_BIT 0x40
+#define BUTTON_FLAG 0x08
+#define BUTTONS_BITS 0x78
+#define TILT_SIGN_BIT 0x40
+#define TILT_BITS 0x3f
+
+/* defines to discriminate second side button and the eraser */
+#define ERASER_PROX 4
+#define OTHER_PROX 1
+
+#define HANDLE_TILT(comm) ((comm)->wcmPktLength == 9)
+
+#define mils(res) (res * 1000 / 2.54) /* resolution */
+
+/******************************************************************************
+ * Function/Macro keys variables
+ *****************************************************************************/
+static KeySym wacom_map[] =
+{
+ NoSymbol, /* 0x00 */
+ NoSymbol, /* 0x01 */
+ NoSymbol, /* 0x02 */
+ NoSymbol, /* 0x03 */
+ NoSymbol, /* 0x04 */
+ NoSymbol, /* 0x05 */
+ NoSymbol, /* 0x06 */
+ NoSymbol, /* 0x07 */
+ XK_F1, /* 0x08 */
+ XK_F2, /* 0x09 */
+ XK_F3, /* 0x0a */
+ XK_F4, /* 0x0b */
+ XK_F5, /* 0x0c */
+ XK_F6, /* 0x0d */
+ XK_F7, /* 0x0e */
+ XK_F8, /* 0x0f */
+ XK_F8, /* 0x10 */
+ XK_F10, /* 0x11 */
+ XK_F11, /* 0x12 */
+ XK_F12, /* 0x13 */
+ XK_F13, /* 0x14 */
+ XK_F14, /* 0x15 */
+ XK_F15, /* 0x16 */
+ XK_F16, /* 0x17 */
+ XK_F17, /* 0x18 */
+ XK_F18, /* 0x19 */
+ XK_F19, /* 0x1a */
+ XK_F20, /* 0x1b */
+ XK_F21, /* 0x1c */
+ XK_F22, /* 0x1d */
+ XK_F23, /* 0x1e */
+ XK_F24, /* 0x1f */
+ XK_F25, /* 0x20 */
+ XK_F26, /* 0x21 */
+ XK_F27, /* 0x22 */
+ XK_F28, /* 0x23 */
+ XK_F29, /* 0x24 */
+ XK_F30, /* 0x25 */
+ XK_F31, /* 0x26 */
+ XK_F32 /* 0x27 */
+};
+
+/* minKeyCode = 8 because this is the min legal key code */
+static KeySymsRec wacom_keysyms = {
+ /* map minKeyCode maxKC width */
+ wacom_map, 8, 0x27, 1
+};
+
+/******************************************************************************
+ * external declarations
+ *****************************************************************************/
+#ifndef XFREE86_V4
+
+#if defined(sun) && !defined(i386)
+#define ENQUEUE suneqEnqueue
+#else
+#define ENQUEUE xf86eqEnqueue
+
+extern void xf86eqEnqueue(
+#if NeedFunctionPrototypes
+ xEventPtr /*e*/
+#endif
+);
+#endif
+
+extern void miPointerDeltaCursor(
+#if NeedFunctionPrototypes
+ int /*dx*/,
+ int /*dy*/,
+ unsigned long /*time*/
+#endif
+);
+
+#endif /* pre 3.9 declarations */
+
+#if NeedFunctionPrototypes
+static LocalDevicePtr xf86WcmAllocateStylus(void);
+static LocalDevicePtr xf86WcmAllocateCursor(void);
+static LocalDevicePtr xf86WcmAllocateEraser(void);
+#endif
+
+#ifndef XFREE86_V4
+#if !defined(sun) || defined(i386)
+/*
+ ***************************************************************************
+ *
+ * xf86WcmConfig --
+ * Configure the device.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86WcmConfig(LocalDevicePtr *array,
+ int inx,
+ int max,
+ LexPtr val)
+{
+ LocalDevicePtr dev = array[inx];
+ WacomDevicePtr priv = (WacomDevicePtr)(dev->private);
+ WacomCommonPtr common = priv->common;
+ int token;
+ int mtoken;
+
+ DBG(1, ErrorF("xf86WcmConfig\n"));
+
+ if (xf86GetToken(WcmTab) != PORT) {
+ xf86ConfigError("PORT option must be the first option of a Wacom SubSection");
+ }
+
+ if (xf86GetToken(NULL) != STRING)
+ xf86ConfigError("Option string expected");
+ else {
+ int loop;
+
+ /* try to find another wacom device which share the same port */
+ for(loop=0; loop<max; loop++) {
+ if (loop == inx)
+ continue;
+ if ((array[loop]->device_config == xf86WcmConfig) &&
+ (strcmp(((WacomDevicePtr)array[loop]->private)->common->wcmDevice, val->str) == 0)) {
+ DBG(2, ErrorF("xf86WcmConfig wacom port share between"
+ " %s and %s\n",
+ dev->name, array[loop]->name));
+ ((WacomDevicePtr) array[loop]->private)->common->wcmHasEraser |= common->wcmHasEraser;
+ xfree(common->wcmDevices);
+ xfree(common);
+ common = priv->common = ((WacomDevicePtr) array[loop]->private)->common;
+ common->wcmNumDevices++;
+ common->wcmDevices = (LocalDevicePtr *) xrealloc(common->wcmDevices,
+ sizeof(LocalDevicePtr) * common->wcmNumDevices);
+ common->wcmDevices[common->wcmNumDevices - 1] = dev;
+ break;
+ }
+ }
+ if (loop == max) {
+ common->wcmDevice = strdup(val->str);
+ if (xf86Verbose)
+ ErrorF("%s Wacom port is %s\n", XCONFIG_GIVEN,
+ common->wcmDevice);
+ }
+ }
+
+ while ((token = xf86GetToken(WcmTab)) != ENDSUBSECTION) {
+ switch(token) {
+ case DEVICENAME:
+ if (xf86GetToken(NULL) != STRING)
+ xf86ConfigError("Option string expected");
+ dev->name = strdup(val->str);
+ if (xf86Verbose)
+ ErrorF("%s Wacom X device name is %s\n", XCONFIG_GIVEN,
+ dev->name);
+ break;
+
+ case THE_MODE:
+ mtoken = xf86GetToken(ModeTabRec);
+ if ((mtoken == EOF) || (mtoken == STRING) || (mtoken == NUMBER))
+ xf86ConfigError("Mode type token expected");
+ else {
+ switch (mtoken) {
+ case ABSOLUTE:
+ priv->flags = priv->flags | ABSOLUTE_FLAG;
+ break;
+ case RELATIVE:
+ priv->flags = priv->flags & ~ABSOLUTE_FLAG;
+ break;
+ default:
+ xf86ConfigError("Illegal Mode type");
+ break;
+ }
+ }
+ break;
+
+ case SUPPRESS:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ common->wcmSuppress = val->num;
+ if (xf86Verbose)
+ ErrorF("%s Wacom suppress value is %d\n", XCONFIG_GIVEN,
+ common->wcmSuppress);
+ break;
+
+ case DEBUG_LEVEL:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ debug_level = val->num;
+ if (xf86Verbose) {
+#if DEBUG
+ ErrorF("%s Wacom debug level sets to %d\n", XCONFIG_GIVEN,
+ debug_level);
+#else
+ ErrorF("%s Wacom debug level not sets to %d because"
+ " debugging is not compiled\n", XCONFIG_GIVEN,
+ debug_level);
+#endif
+ }
+ break;
+
+ case TILT_MODE:
+ common->wcmFlags |= TILT_FLAG;
+ break;
+
+ case HISTORY_SIZE:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ dev->history_size = val->num;
+ if (xf86Verbose)
+ ErrorF("%s Wacom Motion history size is %d\n", XCONFIG_GIVEN,
+ dev->history_size);
+ break;
+
+ case ALWAYS_CORE:
+ xf86AlwaysCore(dev, TRUE);
+ if (xf86Verbose)
+ ErrorF("%s Wacom device always stays core pointer\n",
+ XCONFIG_GIVEN);
+ break;
+
+ case KEEP_SHAPE:
+ priv->flags |= KEEP_SHAPE_FLAG;
+ if (xf86Verbose)
+ ErrorF("%s Wacom keeps shape\n",
+ XCONFIG_GIVEN);
+ break;
+
+ case TOP_X:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ priv->topX = val->num;
+ if (xf86Verbose)
+ ErrorF("%s Wacom top x = %d\n", XCONFIG_GIVEN, priv->topX);
+ break;
+
+ case TOP_Y:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ priv->topY = val->num;
+ if (xf86Verbose)
+ ErrorF("%s Wacom top y = %d\n", XCONFIG_GIVEN, priv->topY);
+ break;
+
+ case BOTTOM_X:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ priv->bottomX = val->num;
+ if (xf86Verbose)
+ ErrorF("%s Wacom bottom x = %d\n", XCONFIG_GIVEN, priv->bottomX);
+ break;
+
+ case BOTTOM_Y:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ priv->bottomY = val->num;
+ if (xf86Verbose)
+ ErrorF("%s Wacom bottom y = %d\n", XCONFIG_GIVEN, priv->bottomY);
+ break;
+
+ case SERIAL:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ priv->serial = val->num;
+ if (xf86Verbose)
+ ErrorF("%s Wacom serial number = %u\n", XCONFIG_GIVEN,
+ priv->serial);
+ break;
+
+ case BAUD_RATE:
+ if (xf86GetToken(NULL) != NUMBER)
+ xf86ConfigError("Option number expected");
+ switch(val->num) {
+ case 19200:
+ common->wcmFlags = common->wcmFlags | BAUD_19200_FLAG;
+ break;
+ case 9600:
+ common->wcmFlags = common->wcmFlags & ~BAUD_19200_FLAG;
+ break;
+ default:
+ xf86ConfigError("Illegal speed value");
+ break;
+ }
+ if (xf86Verbose)
+ ErrorF("%s Wacom baud rate of %u\n", XCONFIG_GIVEN,
+ val->num);
+ break;
+
+ case EOF:
+ FatalError("Unexpected EOF (missing EndSubSection)");
+ break;
+
+ default:
+ xf86ConfigError("Wacom subsection keyword expected");
+ break;
+ }
+ }
+
+ DBG(1, ErrorF("xf86WcmConfig name=%s\n", common->wcmDevice));
+
+ return Success;
+}
+#endif
+#endif /* Pre 3.9 stuff */
+
+#if 0
+/*
+ ***************************************************************************
+ *
+ * ascii_to_hexa --
+ *
+ ***************************************************************************
+ */
+/*
+ * transform two ascii hexa representation into an unsigned char
+ * most significant byte is the first one
+ */
+static unsigned char
+ascii_to_hexa(char buf[2])
+{
+ unsigned char uc;
+
+ if (buf[0] >= 'A') {
+ uc = buf[0] - 'A' + 10;
+ }
+ else {
+ uc = buf[0] - '0';
+ }
+ uc = uc << 4;
+ if (buf[1] >= 'A') {
+ uc += buf[1] - 'A' + 10;
+ }
+ else {
+ uc += buf[1] - '0';
+ }
+ return uc;
+}
+#endif
+
+#ifndef XFREE86_V4
+/*
+ ***************************************************************************
+ *
+ * set_serial_speed --
+ *
+ * Set speed of the serial port.
+ *
+ ***************************************************************************
+ */
+static int
+set_serial_speed(int fd,
+ int speed_code)
+{
+ struct termios termios_tty;
+ int err;
+
+#ifdef POSIX_TTY
+ SYSCALL(err = tcgetattr(fd, &termios_tty));
+
+ if (err == -1) {
+ ErrorF("Wacom tcgetattr error : %s\n", strerror(errno));
+ return !Success;
+ }
+ termios_tty.c_iflag = IXOFF;
+ termios_tty.c_oflag = 0;
+ termios_tty.c_cflag = speed_code|CS8|CREAD|CLOCAL;
+ termios_tty.c_lflag = 0;
+
+ termios_tty.c_cc[VINTR] = 0;
+ termios_tty.c_cc[VQUIT] = 0;
+ termios_tty.c_cc[VERASE] = 0;
+ termios_tty.c_cc[VEOF] = 0;
+#ifdef VWERASE
+ termios_tty.c_cc[VWERASE] = 0;
+#endif
+#ifdef VREPRINT
+ termios_tty.c_cc[VREPRINT] = 0;
+#endif
+ termios_tty.c_cc[VKILL] = 0;
+ termios_tty.c_cc[VEOF] = 0;
+ termios_tty.c_cc[VEOL] = 0;
+#ifdef VEOL2
+ termios_tty.c_cc[VEOL2] = 0;
+#endif
+ termios_tty.c_cc[VSUSP] = 0;
+#ifdef VDSUSP
+ termios_tty.c_cc[VDSUSP] = 0;
+#endif
+#ifdef VDISCARD
+ termios_tty.c_cc[VDISCARD] = 0;
+#endif
+#ifdef VLNEXT
+ termios_tty.c_cc[VLNEXT] = 0;
+#endif
+
+ /* minimum 1 character in one read call and timeout to 100 ms */
+ termios_tty.c_cc[VMIN] = 1;
+ termios_tty.c_cc[VTIME] = 10;
+
+ SYSCALL(err = tcsetattr(fd, TCSANOW, &termios_tty));
+ if (err == -1) {
+ ErrorF("Wacom tcsetattr TCSANOW error : %s\n", strerror(errno));
+ return !Success;
+ }
+
+#else
+ Code for OSs without POSIX tty functions
+#endif
+
+ return Success;
+}
+
+/*
+ ***************************************************************************
+ *
+ * wait_for_fd --
+ *
+ * Wait one second that the file descriptor becomes readable.
+ *
+ ***************************************************************************
+ */
+static int
+wait_for_fd(int fd)
+{
+ int err;
+ fd_set readfds;
+ struct timeval timeout;
+
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+ SYSCALL(err = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout));
+
+ return err;
+}
+
+/*
+ ***************************************************************************
+ *
+ * flush_input_fd --
+ *
+ * Flush all input pending on the file descriptor.
+ *
+ ***************************************************************************
+ */
+static int
+flush_input_fd(int fd)
+{
+ int err;
+ int n_bytes;
+ fd_set readfds;
+ struct timeval timeout;
+ char dummy[1];
+
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+
+ do {
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ SYSCALL(err = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout));
+
+ if (err > 0) {
+ SYSCALL(err = read(fd, &dummy, 1));
+ DBG(10, ErrorF("flush_input_fd: read %d bytes\n", err));
+ }
+ } while (err > 0);
+ return err;
+}
+#endif /* Pre 3.9 stuff */
+
+/*
+ ***************************************************************************
+ *
+ * send_request --
+ *
+ ***************************************************************************
+ */
+/*
+ * send a request and wait for the answer.
+ * the answer must begin with the first two chars of the request and must end
+ * with \r. The last character in the answer string (\r) is replaced by a \0.
+ */
+static char *
+send_request(int fd,
+ char *request,
+ char *answer)
+{
+ int len, nr;
+ int maxtry = MAXTRY;
+
+ /* send request string */
+ do {
+ SYSCALL(len = write(fd, request, strlen(request)));
+ if ((len == -1) && (errno != EAGAIN)) {
+ ErrorF("Wacom write error : %s", strerror(errno));
+ return NULL;
+ }
+ maxtry--;
+ } while ((len == -1) && maxtry);
+
+ if (maxtry == 0) {
+ ErrorF("Wacom unable to write request string '%s' after %d tries\n", request, MAXTRY);
+ return NULL;
+ }
+
+ do {
+ maxtry = MAXTRY;
+
+ /* Read the first byte of the answer which must be equal to the first
+ * byte of the request.
+ */
+ do {
+ if ((nr = wait_for_fd(fd)) > 0) {
+ SYSCALL(nr = read(fd, answer, 1));
+ if ((nr == -1) && (errno != EAGAIN)) {
+ ErrorF("Wacom read error : %s\n", strerror(errno));
+ return NULL;
+ }
+ DBG(10, ErrorF("%c err=%d [0]\n", answer[0], nr));
+ }
+ maxtry--;
+ } while ((answer[0] != request[0]) && maxtry);
+
+ if (maxtry == 0) {
+ ErrorF("Wacom unable to read first byte of request '%c%c' answer after %d tries\n",
+ request[0], request[1], MAXTRY);
+ return NULL;
+ }
+
+ /* Read the second byte of the answer which must be equal to the second
+ * byte of the request.
+ */
+ do {
+ maxtry = MAXTRY;
+ do {
+ if ((nr = wait_for_fd(fd)) > 0) {
+ SYSCALL(nr = read(fd, answer+1, 1));
+ if ((nr == -1) && (errno != EAGAIN)) {
+ ErrorF("Wacom read error : %s\n", strerror(errno));
+ return NULL;
+ }
+ DBG(10, ErrorF("%c err=%d [1]\n", answer[1], nr));
+ }
+ maxtry--;
+ } while ((nr <= 0) && maxtry);
+
+ if (maxtry == 0) {
+ ErrorF("Wacom unable to read second byte of request '%c%c' answer after %d tries\n",
+ request[0], request[1], MAXTRY);
+ return NULL;
+ }
+
+ if (answer[1] != request[1])
+ answer[0] = answer[1];
+
+ } while ((answer[0] == request[0]) &&
+ (answer[1] != request[1]));
+
+ } while ((answer[0] != request[0]) &&
+ (answer[1] != request[1]));
+
+ /* Read until carriage return or timeout (to handle broken protocol
+ * implementations which don't end with a <cr>).
+ */
+ len = 2;
+ maxtry = MAXTRY;
+ do {
+ do {
+ if ((nr = wait_for_fd(fd)) > 0) {
+ SYSCALL(nr = read(fd, answer+len, 1));
+ if ((nr == -1) && (errno != EAGAIN)) {
+ ErrorF("Wacom read error : %s\n", strerror(errno));
+ return NULL;
+ }
+ DBG(10, ErrorF("%c err=%d [%d]\n", answer[len], nr, len));
+ }
+ else {
+ DBG(10, ErrorF("timeout remains %d tries\n", maxtry));
+ maxtry--;
+ }
+ } while ((nr <= 0) && maxtry);
+
+ if (nr > 0) {
+ len += nr;
+ }
+
+ if (maxtry == 0) {
+ ErrorF("Wacom unable to read last byte of request '%c%c' answer after %d tries\n",
+ request[0], request[1], MAXTRY);
+ break;
+ }
+ } while (answer[len-1] != '\r');
+
+ if (len <= 3)
+ return NULL;
+
+ answer[len-1] = '\0';
+
+ return answer;
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmConvert --
+ * Convert valuators to X and Y.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86WcmConvert(LocalDevicePtr local,
+ int first,
+ int num,
+ int v0,
+ int v1,
+ int v2,
+ int v3,
+ int v4,
+ int v5,
+ int* x,
+ int* y)
+{
+ WacomDevicePtr priv = (WacomDevicePtr) local->private;
+
+ DBG(6, ErrorF("xf86WcmConvert\n"));
+
+ if (first != 0 || num == 1)
+ return FALSE;
+
+#ifdef XFREE86_V4
+ priv->factorX = ((double) miPointerCurrentScreen()->width)
+ / (priv->bottomX - priv->topX);
+ priv->factorY = ((double) miPointerCurrentScreen()->height)
+ / (priv->bottomY - priv->topY);
+#endif
+
+ *x = v0 * priv->factorX;
+ *y = v1 * priv->factorY;
+
+ DBG(6, ErrorF("Wacom converted v0=%d v1=%d to x=%d y=%d\n",
+ v0, v1, *x, *y));
+
+ return TRUE;
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmReverseConvert --
+ * Convert X and Y to valuators.
+ *
+ ***************************************************************************
+ */
+static Bool
+xf86WcmReverseConvert(LocalDevicePtr local,
+ int x,
+ int y,
+ int *valuators)
+{
+ WacomDevicePtr priv = (WacomDevicePtr) local->private;
+
+#ifdef XFREE86_V4
+ priv->factorX = ((double) miPointerCurrentScreen()->width)
+ / (priv->bottomX - priv->topX);
+ priv->factorY = ((double) miPointerCurrentScreen()->height)
+ / (priv->bottomY - priv->topY);
+#endif
+
+ valuators[0] = x / priv->factorX;
+ valuators[1] = y / priv->factorY;
+
+ DBG(6, ErrorF("Wacom converted x=%d y=%d to v0=%d v1=%d\n", x, y,
+ valuators[0], valuators[1]));
+
+ return TRUE;
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmSendButtons --
+ * Send button events by comparing the current button mask with the
+ * previous one.
+ *
+ ***************************************************************************
+ */
+static void
+xf86WcmSendButtons(LocalDevicePtr local,
+ int buttons,
+ int rx,
+ int ry,
+ int rz,
+ int rtx,
+ int rty,
+ int rwheel)
+
+{
+ int button;
+ WacomDevicePtr priv = (WacomDevicePtr) local->private;
+
+ for (button=1; button<16; button++) {
+ int mask = 1 << (button-1);
+
+ if ((mask & priv->oldButtons) != (mask & buttons)) {
+ DBG(4, ErrorF("xf86WcmSendButtons button=%d state=%d\n",
+ button, (buttons & mask) != 0));
+ xf86PostButtonEvent(local->dev,
+ (priv->flags & ABSOLUTE_FLAG),
+ button, (buttons & mask) != 0,
+ 0, 6, rx, ry, rz, rtx, rty, rwheel);
+ }
+ }
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmSendEvents --
+ * Send events according to the device state.
+ *
+ ***************************************************************************
+ */
+static void
+xf86WcmSendEvents(LocalDevicePtr local,
+ int type,
+ unsigned int serial,
+ int is_stylus,
+ int is_button,
+ int is_proximity,
+ int x,
+ int y,
+ int z,
+ int buttons,
+ int tx,
+ int ty,
+ int wheel)
+{
+ WacomDevicePtr priv = (WacomDevicePtr) local->private;
+ WacomCommonPtr common = priv->common;
+ int rx, ry, rz, rtx, rty, rwheel;
+ int is_core_pointer, is_absolute;
+
+ if ((DEVICE_ID(priv->flags) != type) ||
+ ((common->wcmProtocolLevel == 5) &&
+ priv->serial && (serial != priv->serial))) {
+ DBG(7,
+ {if (common->wcmProtocolLevel == 5) {
+ ErrorF("xf86WcmSendEvents not the same device id (%u,%u)\n",
+ serial, priv->serial);
+ } else {
+ ErrorF("xf86WcmSendEvents not the same device type (%u,%u)\n",
+ DEVICE_ID(priv->flags), type);}});
+ return;
+ }
+
+ DBG(7, ErrorF("[%s] prox=%s\tx=%d\ty=%d\tz=%d\tbutton=%s\tbuttons=%d\ttx=%d ty=%d\twl=%d\n",
+ (type == STYLUS_ID) ? "stylus" : (type == CURSOR_ID) ? "cursor" : "eraser",
+ is_proximity ? "true" : "false",
+ x, y, z,
+ is_button ? "true" : "false", buttons,
+ tx, ty, wheel));
+
+ /* Translate coordinates according to Top and Bottom points
+ * if we are outside the zone do as a ProximityOut event.
+ */
+
+ if (x > priv->bottomX) {
+ is_proximity = FALSE;
+ buttons = 0;
+ x = priv->bottomX;
+ }
+
+ if (y > priv->bottomY) {
+ is_proximity = FALSE;
+ buttons = 0;
+ y = priv->bottomY;
+ }
+
+ DBG(10, ErrorF("topX=%d topY=%d\n", priv->topX, priv->topY));
+
+ x = x - priv->topX;
+ y = y - priv->topY;
+
+ if (x < 0) {
+ is_proximity = FALSE;
+ buttons = 0;
+ x = 0;
+ }
+
+ if (y < 0) {
+ is_proximity = FALSE;
+ buttons = 0;
+ y = 0;
+ }
+
+ is_absolute = (priv->flags & ABSOLUTE_FLAG);
+ is_core_pointer = xf86IsCorePointer(local->dev);
+
+ DBG(6, ErrorF("[%s] %s prox=%s\tx=%d\ty=%d\tz=%d\tbutton=%s\tbuttons=%d\n",
+ is_stylus ? "stylus" : "cursor",
+ is_absolute ? "abs" : "rel",
+ is_proximity ? "true" : "false",
+ x, y, z,
+ is_button ? "true" : "false", buttons));
+
+ /* sets rx and ry according to the mode */
+ if (is_absolute) {
+ rx = x;
+ ry = y;
+ rz = z;
+ rtx = tx;
+ rty = ty;
+ rwheel = wheel;
+ } else {
+ rx = x - priv->oldX;
+ ry = y - priv->oldY;
+ rz = z - priv->oldZ;
+ rtx = tx - priv->oldTiltX;
+ rty = ty - priv->oldTiltY;
+ rwheel = wheel - priv->oldWheel;
+ }
+
+ /* coordinates are ready we can send events */
+ if (is_proximity) {
+
+ if (!priv->oldProximity) {
+ xf86PostProximityEvent(local->dev, 1, 0, 6, rx, ry, z, tx, ty, rwheel);
+
+ priv->flags |= FIRST_TOUCH_FLAG;
+ DBG(4, ErrorF("xf86WcmSendEvents FIRST_TOUCH_FLAG set\n"));
+
+ if (common->wcmProtocolLevel == 4) {
+ /* handle the two sides switches in the stylus */
+ if (is_stylus && (buttons == 4)) {
+ priv->oldProximity = ERASER_PROX;
+ }
+ else {
+ priv->oldProximity = OTHER_PROX;
+ }
+ }
+ else {
+ priv->oldProximity = OTHER_PROX;
+ }
+ }
+
+ if (common->wcmProtocolLevel == 4) {
+ /* The stylus reports button 4 for the second side
+ * switch and button 4/5 for the eraser tip. We know
+ * how to choose when we come in proximity for the
+ * first time. If we are in proximity and button 4 then
+ * we have the eraser else we have the second side
+ * switch.
+ */
+ if (is_stylus) {
+ if (buttons == 4) {
+ buttons = (priv->oldProximity == ERASER_PROX) ? 0 : 3;
+ }
+ else {
+ if (priv->oldProximity == ERASER_PROX && buttons == 5) {
+ buttons = ((DEVICE_ID(priv->flags) == ERASER_ID) ? 1 : 4);
+ }
+ }
+ }
+ else {
+ /* If the button flag is pressed, but the switch state
+ * is zero, this means that cursor button 16 was pressed
+ */
+ if (buttons == 0) {
+ buttons = 16;
+ }
+ }
+ }
+ DBG(4, ErrorF("xf86WcmSendEvents %s rx=%d ry=%d rz=%d buttons=%d\n",
+ is_stylus ? "stylus" : "cursor", rx, ry, rz, buttons));
+
+ /* Turn button index reported by stylus into a bit mask for WACOM IV.
+ * The WACOM V button report is already a bit mask.
+ */
+ if (is_stylus && common->wcmProtocolLevel == 4) {
+ buttons = 1 << (buttons - 1);
+ }
+
+ if ((priv->oldX != x) ||
+ (priv->oldY != y) ||
+ (priv->oldZ != z) ||
+ (is_stylus && HANDLE_TILT(common) &&
+ (tx != priv->oldTiltX || ty != priv->oldTiltY))) {
+ if (!is_absolute && (priv->flags & FIRST_TOUCH_FLAG)) {
+ priv->flags -= FIRST_TOUCH_FLAG;
+ DBG(4, ErrorF("xf86WcmSendEvents FIRST_TOUCH_FLAG unset\n"));
+ } else {
+ xf86PostMotionEvent(local->dev, is_absolute, 0, 6, rx, ry, rz,
+ rtx, rty, rwheel);
+ }
+ }
+ if (priv->oldButtons != buttons) {
+ xf86WcmSendButtons (local, buttons, rx, ry, rz, rtx, rty, rwheel);
+ }
+ priv->oldButtons = buttons;
+ priv->oldX = x;
+ priv->oldY = y;
+ priv->oldZ = z;
+ priv->oldTiltX = tx;
+ priv->oldTiltY = ty;
+ priv->oldWheel = wheel;
+ }
+ else { /* !PROXIMITY */
+ /* reports button up when the device has been down and becomes out of proximity */
+ if (priv->oldButtons) {
+ xf86WcmSendButtons (local, 0, rx, ry, rz, rtx, rty, rwheel);
+ priv->oldButtons = 0;
+ }
+ if (!is_core_pointer) {
+ /* macro button management */
+ if (common->wcmProtocolLevel == 4 && buttons) {
+ int macro = z / 2;
+
+ DBG(6, ErrorF("macro=%d buttons=%d wacom_map[%d]=%x\n",
+ macro, buttons, macro, wacom_map[macro]));
+
+ /* First available Keycode begins at 8 => macro+7 */
+ xf86PostKeyEvent(local->dev, macro+7, 1,
+ is_absolute, 0, 6,
+ 0, 0, buttons, rtx, rty, rwheel);
+ xf86PostKeyEvent(local->dev, macro+7, 0,
+ is_absolute, 0, 6,
+ 0, 0, buttons, rtx, rty, rwheel);
+ }
+ if (priv->oldProximity) {
+ xf86PostProximityEvent(local->dev, 0, 0, 6, rx, ry, rz,
+ rtx, rty, rwheel);
+ }
+ }
+ priv->oldProximity = 0;
+ }
+}
+
+#define ABS(x) ((x) > 0 ? (x) : -(x))
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmSuppress --
+ * Determine whether device state has changed enough - return 1
+ * if not.
+ *
+ ***************************************************************************
+ */
+static int
+xf86WcmSuppress(int suppress,
+ WacomDeviceState *ds1,
+ WacomDeviceState *ds2)
+{
+ if (ds1->buttons != ds2->buttons) return 0;
+ if (ds1->proximity != ds2->proximity) return 0;
+ if (ABS(ds1->x - ds2->x) >= suppress) return 0;
+ if (ABS(ds1->y - ds2->y) >= suppress) return 0;
+ if (ABS(ds1->pressure - ds2->pressure) >= suppress) return 0;
+ if ((1800 + ds1->rotation - ds2->rotation) % 1800 >= suppress &&
+ (1800 + ds2->rotation - ds1->rotation) % 1800 >= suppress) return 0;
+ if (ABS(ds1->wheel - ds2->wheel) >= suppress) return 0;
+ return 1;
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmIntuosFilter --
+ * Correct some hardware defects we've been seeing in Intuos pads,
+ * but also cuts down quite a bit on jitter.
+ *
+ ***************************************************************************
+ */
+static int
+xf86WcmIntuosFilter(WacomFilterState *state,
+ int coord,
+ int tilt)
+{
+ int tilt_filtered;
+ int ts;
+ int x0_pred;
+ int x0_pred1;
+ int x0, x1, x2, x3;
+ int x;
+
+ tilt_filtered = tilt + state->tilt[1] + state->tilt[2] + state->tilt[3];
+ state->tilt[2] = state->tilt[1];
+ state->tilt[1] = state->tilt[0];
+ state->tilt[0] = tilt;
+
+ x0 = coord;
+ x1 = state->coord[0];
+ x2 = state->coord[1];
+ x3 = state->coord[2];
+ state->coord[0] = x0;
+ state->coord[1] = x1;
+ state->coord[2] = x2;
+
+ ts = tilt_filtered >= 0 ? 1 : -1;
+
+ if (state->state == 0 || state->state == 3) {
+ x0_pred = 2 * x1 - x2;
+ x0_pred1 = 3 * x2 - 2 * x3;
+ if (ts * (x0 - x0_pred) > 12 &&
+ ts * (x0 - x0_pred1) > 12) {
+ /* detected a jump at x0 */
+ state->state = 1;
+ x = x1;
+ }
+ else if (state->state == 0) {
+ x = (7 * x0 + 14 * x1 + 15 * x2 - 4 * x3 + 16) >> 5;
+ }
+ else { /* state->state == 3 */
+ /* a jump at x3 was detected */
+ x = (x0 + 2 * x1 + x2 + 2) >> 2;
+ state->state = 0;
+ }
+ }
+ else if (state->state == 1) {
+ /* a jump at x1 was detected */
+ x = (3 * x0 + 7 * x2 - 2 * x3 + 4) >> 3;
+ state->state = 2;
+ }
+ else { /* state->state == 2 */
+ /* a jump at x2 was detected */
+ x = x1;
+ state->state = 3;
+ }
+
+ return x;
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmReadInput --
+ * Read the new events from the device, and enqueue them.
+ *
+ ***************************************************************************
+ */
+static void
+xf86WcmReadInput(LocalDevicePtr local)
+{
+ WacomDevicePtr priv = (WacomDevicePtr) local->private;
+ WacomCommonPtr common = priv->common;
+ int len, loop, idx;
+ int is_stylus = 1, is_button, is_proximity;
+ int is_absolute = (priv->flags & ABSOLUTE_FLAG);
+ int x, y, z, buttons, tx = 0, ty = 0;
+ unsigned char buffer[BUFFER_SIZE];
+ WacomDeviceState *ds;
+ WacomDeviceState old_ds;
+ int have_data;
+
+ DBG(7, ErrorF("xf86WcmReadInput BEGIN device=%s fd=%d\n",
+ common->wcmDevice, local->fd));
+
+ SYSCALL(len = read(local->fd, buffer, sizeof(buffer)));
+
+ if (len <= 0) {
+ ErrorF("Error reading wacom device : %s\n", strerror(errno));
+ return;
+ } else {
+ DBG(10, ErrorF("xf86WcmReadInput read %d bytes\n", len));
+ }
+
+ for(loop=0; loop<len; loop++) {
+
+ /* Format of 7 bytes data packet for Wacom Tablets
+ Byte 1
+ bit 7 Sync bit always 1
+ bit 6 Pointing device detected
+ bit 5 Cursor = 0 / Stylus = 1
+ bit 4 Reserved
+ bit 3 1 if a button on the pointing device has been pressed
+ bit 2 Reserved
+ bit 1 X15
+ bit 0 X14
+
+ Byte 2
+ bit 7 Always 0
+ bits 6-0 = X13 - X7
+
+ Byte 3
+ bit 7 Always 0
+ bits 6-0 = X6 - X0
+
+ Byte 4
+ bit 7 Always 0
+ bit 6 B3
+ bit 5 B2
+ bit 4 B1
+ bit 3 B0
+ bit 2 P0
+ bit 1 Y15
+ bit 0 Y14
+
+ Byte 5
+ bit 7 Always 0
+ bits 6-0 = Y13 - Y7
+
+ Byte 6
+ bit 7 Always 0
+ bits 6-0 = Y6 - Y0
+
+ Byte 7
+ bit 7 Always 0
+ bit 6 Sign of pressure data
+ bit 5 P6
+ bit 4 P5
+ bit 3 P4
+ bit 2 P3
+ bit 1 P2
+ bit 0 P1
+
+ byte 8 and 9 are optional and present only
+ in tilt mode.
+
+ Byte 8
+ bit 7 Always 0
+ bit 6 Sign of tilt X
+ bit 5 Xt6
+ bit 4 Xt5
+ bit 3 Xt4
+ bit 2 Xt3
+ bit 1 Xt2
+ bit 0 Xt1
+
+ Byte 9
+ bit 7 Always 0
+ bit 6 Sign of tilt Y
+ bit 5 Yt6
+ bit 4 Yt5
+ bit 3 Yt4
+ bit 2 Yt3
+ bit 1 Yt2
+ bit 0 Yt1
+
+ */
+
+ if ((common->wcmIndex == 0) && !(buffer[loop] & HEADER_BIT)) { /* magic bit is not OK */
+ DBG(6, ErrorF("xf86WcmReadInput bad magic number 0x%x (pktlength=%d)\n",
+ buffer[loop], common->wcmPktLength));;
+ continue;
+ }
+
+ common->wcmData[common->wcmIndex++] = buffer[loop];
+
+ if (common->wcmProtocolLevel == 4 &&
+ common->wcmIndex == common->wcmPktLength) {
+ /* the packet is OK */
+
+ /* reset char count for next read */
+ common->wcmIndex = 0;
+
+ x = (((common->wcmData[0] & 0x3) << 14) +
+ (common->wcmData[1] << 7) +
+ common->wcmData[2]);
+ y = (((common->wcmData[3] & 0x3) << 14) +
+ (common->wcmData[4] << 7) +
+ common->wcmData[5]);
+
+ /* check which device we have */
+ is_stylus = (common->wcmData[0] & POINTER_BIT);
+
+ z = ((common->wcmData[6] & ZAXIS_BITS) * 2) +
+ ((common->wcmData[3] & ZAXIS_BIT) >> 2);
+ if (common->wcmData[6] & ZAXIS_SIGN_BIT)
+ z -= 0x80;
+
+ is_button = (common->wcmData[0] & BUTTON_FLAG);
+ is_proximity = (common->wcmData[0] & PROXIMITY_BIT);
+
+ buttons = (common->wcmData[3] & BUTTONS_BITS) >> 3;
+
+ /* The stylus reports button 4 for the second side
+ * switch and button 4/5 for the eraser tip. We know
+ * how to choose when we come in proximity for the
+ * first time. If we are in proximity and button 4 then
+ * we have the eraser else we have the second side
+ * switch.
+ */
+ if (is_stylus) {
+ if (!common->wcmStylusProximity && is_proximity) {
+ common->wcmStylusSide = (buttons != 4);
+ }
+ DBG(8, ErrorF("xf86WcmReadInput %s side\n",
+ common->wcmStylusSide ? "stylus" : "eraser"));
+ common->wcmStylusProximity = is_proximity;
+
+ /* handle tilt values only for stylus */
+ if (HANDLE_TILT(common)) {
+ tx = (common->wcmData[7] & TILT_BITS);
+ ty = (common->wcmData[8] & TILT_BITS);
+ if (common->wcmData[7] & TILT_SIGN_BIT)
+ tx -= (TILT_BITS + 1);
+ if (common->wcmData[8] & TILT_SIGN_BIT)
+ ty -= (TILT_BITS + 1);
+ }
+ }
+
+ for(idx=0; idx<common->wcmNumDevices; idx++) {
+ LocalDevicePtr local_dev = common->wcmDevices[idx];
+ WacomDevicePtr priv = (WacomDevicePtr) local_dev->private;
+ int temp_buttons = buttons;
+ int temp_is_proximity = is_proximity;
+ int curDevice;
+
+ DBG(7, ErrorF("xf86WcmReadInput trying to send to %s\n",
+ local_dev->name));
+
+ /* check for device type (STYLUS, ERASER or CURSOR) */
+
+ if (is_stylus) {
+ /*
+ * The eraser is reported as button 4 and 5 of the stylus.
+ * if we haven't an independent device for the eraser
+ * report the button as button 3 of the stylus.
+ */
+ if (is_proximity) {
+ if ((buttons & 4) && common->wcmHasEraser &&
+ ((!priv->oldProximity ||
+ (priv->oldProximity == ERASER_PROX)))) {
+ curDevice = ERASER_ID;
+ } else {
+ curDevice = STYLUS_ID;
+ }
+
+ } else {
+ /*
+ * When we are out of proximity with the eraser the
+ * button 4 isn't reported so we must check the
+ * previous proximity device.
+ */
+ if (common->wcmHasEraser && (priv->oldProximity == ERASER_PROX)) {
+ curDevice = ERASER_ID;
+ } else {
+ curDevice = STYLUS_ID;
+ }
+ }
+
+ /* We check here to see if we changed between eraser and stylus
+ * without leaving proximity. The most likely cause is that
+ * we were fooled by the second side switch into thinking the
+ * stylus was the eraser. If this happens, we send
+ * a proximity-out for the old device.
+ */
+ if ((DEVICE_ID(priv->flags) == STYLUS_ID ||
+ DEVICE_ID(priv->flags) == ERASER_ID) &&
+ curDevice != DEVICE_ID(priv->flags)) {
+ if (priv->oldProximity) {
+ curDevice = DEVICE_ID(priv->flags);
+ temp_buttons = 0;
+ temp_is_proximity = 0;
+ DBG(10, ErrorF("eraser and stylus mix\n"));
+ } else
+ continue;
+ }
+
+ DBG(10, ErrorF((DEVICE_ID(priv->flags) == ERASER_ID) ?
+ "Eraser\n" :
+ "Stylus\n"));
+ }
+ else {
+ if (DEVICE_ID(priv->flags) != CURSOR_ID)
+ continue;
+ DBG(10, ErrorF("Cursor\n"));
+ curDevice = CURSOR_ID;
+ }
+
+ xf86WcmSendEvents(common->wcmDevices[idx],
+ curDevice, 0,
+ is_stylus,
+ is_button,
+ temp_is_proximity,
+ x, y, z, temp_buttons,
+ tx, ty, 0);
+ }
+ }
+ else if (common->wcmProtocolLevel == 5 &&
+ common->wcmIndex == common->wcmPktLength) {
+ /* the packet is OK */
+ int x, y;
+
+ /* reset count for read of next packet */
+ common->wcmIndex = 0;
+
+ ds = &common->wcmDevStat[common->wcmData[0] & 0x01];
+ old_ds = *ds;
+ have_data = 0;
+
+ DBG(7, ErrorF("packet header = 0x%x\n",
+ (unsigned int)common->wcmData[0]));
+
+ /* Device ID packet */
+ if ((common->wcmData[0] & 0xfc) == 0xc0) {
+ memset(ds, 0, sizeof(*ds));
+ ds->proximity = 1;
+ ds->device_id = (((common->wcmData[1] & 0x7f) << 5) |
+ ((common->wcmData[2] & 0x7c) >> 2));
+ ds->serial_num = (((common->wcmData[2] & 0x03) << 30) |
+ ((common->wcmData[3] & 0x7f) << 23) |
+ ((common->wcmData[4] & 0x7f) << 16) |
+ ((common->wcmData[5] & 0x7f) << 9) |
+ ((common->wcmData[6] & 0x7f) << 23) |
+ ((common->wcmData[7] & 0x60) >> 5));
+ if ((ds->device_id & 0xf06) != 0x802)
+ ds->discard_first = 1;
+
+ if (PEN(ds) || INKING_PEN(ds) || AIRBRUSH(ds))
+ ds->device_type = STYLUS_ID;
+ else if (MOUSE_4D(ds) || LENS_CURSOR(ds))
+ ds->device_type = CURSOR_ID;
+ else
+ ds->device_type = ERASER_ID;
+
+ DBG(6, ErrorF("device_id=0x%x serial_num=%u type=%s\n",
+ ds->device_id, ds->serial_num,
+ (ds->device_type == STYLUS_ID) ? "stylus"
+ : (ds->device_type == CURSOR_ID) ? "cursor"
+ : "eraser"));
+ }
+ /* Out of proximity packet */
+ else if ((common->wcmData[0] & 0xfe) == 0x80) {
+ ds->proximity = 0;
+ have_data = 1;
+ }
+ /* General pen packet or eraser packet or airbrush first packet */
+ else if (((common->wcmData[0] & 0xb8) == 0xa0) ||
+ /* airbrush second packet */
+ ((common->wcmData[0] & 0xbe) == 0xb4)) {
+ is_stylus = 1;
+ ds->x = (((common->wcmData[1] & 0x7f) << 9) |
+ ((common->wcmData[2] & 0x7f) << 2) |
+ ((common->wcmData[3] & 0x60) >> 5));
+ ds->y = (((common->wcmData[3] & 0x1f) << 11) |
+ ((common->wcmData[4] & 0x7f) << 4) |
+ ((common->wcmData[5] & 0x78) >> 3));
+ if ((common->wcmData[0] & 0xb8) == 0xa0) {
+ ds->pressure = (((common->wcmData[5] & 0x07) << 7) |
+ (common->wcmData[6] & 0x7f)) - 512;
+ ds->buttons = (((common->wcmData[0]) & 0x06) |
+ (ds->pressure >= common->wcmThreshold));
+ }
+ else {
+ ds->wheel = (((common->wcmData[5] & 0x07) << 7) |
+ (common->wcmData[6] & 0x7f));
+ }
+ ds->tiltx = (common->wcmData[7] & TILT_BITS);
+ ds->tilty = (common->wcmData[8] & TILT_BITS);
+ if (common->wcmData[7] & TILT_SIGN_BIT)
+ ds->tiltx -= (TILT_BITS + 1);
+ if (common->wcmData[8] & TILT_SIGN_BIT)
+ ds->tilty -= (TILT_BITS + 1);
+ ds->proximity = (common->wcmData[0] & PROXIMITY_BIT);
+ have_data = 1;
+ }
+ /* 4D mouse 1st packet or Lens cursor packet */
+ else if (((common->wcmData[0] & 0xbe) == 0xa8) ||
+ ((common->wcmData[0] & 0xbe) == 0xb0)) {
+ is_stylus = 0;
+ ds->x = (((common->wcmData[1] & 0x7f) << 9) |
+ ((common->wcmData[2] & 0x7f) << 2) |
+ ((common->wcmData[3] & 0x60) >> 5));
+ ds->y = (((common->wcmData[3] & 0x1f) << 11) |
+ ((common->wcmData[4] & 0x7f) << 4) |
+ ((common->wcmData[5] & 0x78) >> 3));
+ ds->tilty = 0;
+ ds->wheel = (((common->wcmData[5] & 0x07) << 7) |
+ (common->wcmData[6] & 0x7f));
+ if (common->wcmData[8] & 0x08) ds->wheel = -ds->wheel;
+ /* 4D mouse */
+ if (MOUSE_4D(ds)) {
+ ds->buttons = (((common->wcmData[8] & 0x70) >> 1) |
+ (common->wcmData[8] & 0x07));
+ have_data = !ds->discard_first;
+ }
+ /* Lens cursor */
+ else {
+ ds->buttons = common->wcmData[8];
+ have_data = 1;
+ }
+ ds->proximity = (common->wcmData[0] & PROXIMITY_BIT);
+ }
+ /* 4D mouse 2nd packet */
+ else if ((common->wcmData[0] & 0xbe) == 0xaa) {
+ is_stylus = 0;
+ ds->x = (((common->wcmData[1] & 0x7f) << 9) |
+ ((common->wcmData[2] & 0x7f) << 2) |
+ ((common->wcmData[3] & 0x60) >> 5));
+ ds->y = (((common->wcmData[3] & 0x1f) << 11) |
+ ((common->wcmData[4] & 0x7f) << 4) |
+ ((common->wcmData[5] & 0x78) >> 3));
+ ds->tilty = 0;
+ ds->rotation = (((common->wcmData[6] & 0x0f) << 7) |
+ (common->wcmData[7] & 0x7f));
+ ds->tiltx = ((900 - ((ds->rotation + 900) % 1800)) >> 1);
+ ds->proximity = (common->wcmData[0] & PROXIMITY_BIT);
+ have_data = 1;
+ ds->discard_first = 0;
+ }
+ else {
+ DBG(10, ErrorF("unknown wacom V packet 0x%x\n",
+ common->wcmData[0]));
+ }
+
+ /* Suppress data */
+ if (have_data &&
+ xf86WcmSuppress(common->wcmSuppress, &old_ds, ds)) {
+ DBG(10, ErrorF("Suppressing data\n"));
+ *ds = old_ds;
+ have_data = 0;
+ }
+
+ if (have_data) {
+ if (is_absolute) {
+ x = xf86WcmIntuosFilter (&ds->x_filter, ds->x, ds->tiltx);
+ y = xf86WcmIntuosFilter (&ds->y_filter, ds->y, ds->tilty);
+ }
+ else {
+ x = ds->x;
+ y = ds->y;
+ }
+ for(idx=0; idx<common->wcmNumDevices; idx++) {
+ DBG(7, ErrorF("xf86WcmReadInput trying to send to %s\n",
+ common->wcmDevices[idx]->name));
+
+ xf86WcmSendEvents(common->wcmDevices[idx],
+ ds->device_type, ds->serial_num,
+ is_stylus,
+ ds->buttons,
+ ds->proximity,
+ x, y,
+ ds->pressure,
+ ds->buttons,
+ ds->tiltx, ds->tilty,
+ ds->wheel);
+ }
+ }
+ }
+ }
+ DBG(7, ErrorF("xf86WcmReadInput END local=0x%x priv=0x%x\n",
+ local, priv));
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmControlProc --
+ *
+ ***************************************************************************
+ */
+static void
+xf86WcmControlProc(DeviceIntPtr device,
+ PtrCtrl *ctrl)
+{
+ DBG(2, ErrorF("xf86WcmControlProc\n"));
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmOpen --
+ *
+ ***************************************************************************
+ */
+#ifdef XFREE86_V4
+#define WAIT(t) \
+ err = xf86WaitForInput(-1, ((t) * 1000)); \
+ if (err == -1) { \
+ ErrorF("Wacom select error : %s\n", strerror(errno)); \
+ return !Success; \
+ }
+#else
+#define WAIT(t) \
+ timeout.tv_sec = 0; \
+ timeout.tv_usec = (t) * 1000; \
+ SYSCALL(err = select(0, NULL, NULL, NULL, &timeout)); \
+ if (err == -1) { \
+ ErrorF("Wacom select error : %s\n", strerror(errno)); \
+ return !Success; \
+ }
+#endif
+
+static Bool
+xf86WcmOpen(LocalDevicePtr local)
+{
+#ifndef XFREE86_V4
+ struct termios termios_tty;
+ struct timeval timeout;
+#endif
+ char buffer[256];
+ char header[64]; /* This is a small buffer for discarding the unwanted header */
+ int err;
+ WacomDevicePtr priv = (WacomDevicePtr)local->private;
+ WacomCommonPtr common = priv->common;
+ int a, b;
+ int loop, idx;
+ float version = 0.0;
+ int is_a_penpartner = 0;
+
+ DBG(1, ErrorF("opening %s\n", common->wcmDevice));
+
+#ifdef XFREE86_V4
+ local->fd = xf86OpenSerial(local->options);
+#else
+ SYSCALL(local->fd = open(common->wcmDevice, O_RDWR|O_NDELAY, 0));
+#endif
+ if (local->fd < 0) {
+ ErrorF("Error opening %s : %s\n", common->wcmDevice, strerror(errno));
+ return !Success;
+ }
+
+ DBG(1, ErrorF("initializing tablet\n"));
+
+ /* Set the speed of the serial link to 19200 */
+#ifdef XFREE86_V4
+ if (xf86SetSerial(local->fd, b19200_options) < 0) {
+ return !Success;
+ }
+#else
+ if (set_serial_speed(local->fd, B19200) == !Success)
+ return !Success;
+#endif
+
+ /* Send reset to the tablet */
+ SYSCALL(err = write(local->fd, WC_RESET_BAUD, strlen(WC_RESET_BAUD)));
+ if (err == -1) {
+ ErrorF("Wacom write error : %s\n", strerror(errno));
+ return !Success;
+ }
+
+ /* Wait 250 mSecs */
+ WAIT(250);
+
+ /* Send reset to the tablet */
+ SYSCALL(err = write(local->fd, WC_RESET, strlen(WC_RESET)));
+ if (err == -1) {
+ ErrorF("Wacom write error : %s\n", strerror(errno));
+ return !Success;
+ }
+
+ /* Wait 75 mSecs */
+ WAIT(75);
+
+ /* Set the speed of the serial link to 9600 */
+#ifdef XFREE86_V4
+ if (xf86SetSerial(local->fd, local->options) < 0) {
+ return !Success;
+ }
+#else
+ if (set_serial_speed(local->fd, B9600) == !Success)
+ return !Success;
+#endif
+
+ /* Send reset to the tablet */
+ SYSCALL(err = write(local->fd, WC_RESET_BAUD, strlen(WC_RESET_BAUD)));
+ if (err == -1) {
+ ErrorF("Wacom write error : %s\n", strerror(errno));
+ return !Success;
+ }
+
+ /* Wait 250 mSecs */
+ WAIT(250);
+
+ SYSCALL(err = write(local->fd, WC_STOP, strlen(WC_STOP)));
+ if (err == -1) {
+ ErrorF("Wacom write error : %s\n", strerror(errno));
+ return !Success;
+ }
+
+ /* Wait 30 mSecs */
+ WAIT(30);
+
+#ifdef XFREE86_V4
+ xf86FlushInput(local->fd);
+#else
+ flush_input_fd(local->fd);
+#endif
+
+ DBG(2, ErrorF("reading model\n"));
+ if (!send_request(local->fd, WC_MODEL, buffer)) {
+ return !Success;
+ }
+ DBG(2, ErrorF("%s\n", buffer));
+
+ if (xf86Verbose) {
+ ErrorF("%s Wacom tablet model : %s\n", XCONFIG_PROBED, buffer+2);
+ }
+
+ /* Answer is in the form ~#Tablet-Model VRom_Version */
+ /* look for the first V from the end of the string */
+ /* this seems to be the better way to find the version of the ROM */
+ for(loop=strlen(buffer); loop>=0 && *(buffer+loop) != 'V'; loop--);
+ for(idx=loop; idx<strlen(buffer) && *(buffer+idx) != '-'; idx++);
+ *(buffer+idx) = '\0';
+
+ /* Extract version numbers */
+ sscanf(buffer+loop+1, "%f", &version);
+
+ if (buffer[2] == 'G' && buffer[3] == 'D') {
+ DBG(2, ErrorF("detected an Intuos model\n"));
+ common->wcmProtocolLevel = 5;
+ common->wcmMaxZ = 1023; /* max Z value */
+ common->wcmResolX = 2540; /* X resolution in points/inch */
+ common->wcmResolY = 2540; /* Y resolution in points/inch */
+ common->wcmResolZ = 2540; /* Z resolution in points/inch */
+ common->wcmPktLength = 9; /* length of a packet */
+ common->wcmThreshold = -480; /* Threshold for counting pressure as a button */
+ }
+
+ /* Tilt works on ROM 1.4 and above */
+ DBG(2, ErrorF("wacom flags=%d ROM version=%f buffer=%s\n",
+ common->wcmFlags, version, buffer+loop+1));
+ if (common->wcmProtocolLevel == 4 &&
+ (common->wcmFlags & TILT_FLAG) && (version >= (float)1.4)) {
+ common->wcmPktLength = 9;
+ }
+
+ /* Check for a PenPartner model which doesn't answer WC_CONFIG request */
+ if (buffer[2] == 'C' && buffer[3] == 'T') {
+ DBG(2, ErrorF("detected a PenPartner model\n"));
+ common->wcmResolX = 1000;
+ common->wcmResolY = 1000;
+ is_a_penpartner = 1;
+ }
+ else if (common->wcmProtocolLevel == 4) {
+ DBG(2, ErrorF("reading config\n"));
+ if (!send_request(local->fd, WC_CONFIG, buffer))
+ return !Success;
+ DBG(2, ErrorF("%s\n", buffer));
+ /* The header string is simply a place to put the unwanted
+ * config header don't use buffer+xx because the header size
+ * varies on different tablets
+ */
+ if (sscanf(buffer, "%[^,],%d,%d,%d,%d", &header, &a, &b, &common->wcmResolX, &common->wcmResolY) == 5) {
+ DBG(6, ErrorF("WC_CONFIG Header = %s\n", header));
+ }
+ else {
+ ErrorF("WACOM: unable to read resolution. Using default.\n");
+ }
+ }
+
+ DBG(2, ErrorF("reading max coordinates\n"));
+ if (!send_request(local->fd, WC_COORD, buffer))
+ return !Success;
+ DBG(2, ErrorF("%s\n", buffer));
+ if (sscanf(buffer+2, "%d,%d", &common->wcmMaxX, &common->wcmMaxY) != 2) {
+ ErrorF("WACOM: unable to read max coordinates. Using default.\n");
+ }
+
+ DBG(2, ErrorF("setup is max X=%d max Y=%d resol X=%d resol Y=%d\n",
+ common->wcmMaxX, common->wcmMaxY, common->wcmResolX,
+ common->wcmResolY));
+
+ if (!is_a_penpartner && common->wcmProtocolLevel == 4) {
+ /* Force the resolution.
+ */
+ if (((float)version) >= 1.2) {
+ common->wcmResolY = common->wcmResolX = 2540;
+ }
+ sprintf(buffer, "%s%d\r", WC_NEW_RESOLUTION, common->wcmResolX);
+ SYSCALL(err = write(local->fd, buffer, strlen(buffer)));
+
+ /* Verify the resolution change.
+ */
+ DBG(2, ErrorF("rereading config\n"));
+ if (!send_request(local->fd, WC_CONFIG, buffer))
+ return !Success;
+ DBG(2, ErrorF("%s\n", buffer));
+ /* The header string is simply a place to put the unwanted
+ * config header don't use buffer+xx because the header size
+ * varies on different tablets
+ */
+ if (sscanf(buffer, "%[^,],%d,%d,%d,%d", &header, &a, &b, &common->wcmResolX, &common->wcmResolY) == 5) {
+ DBG(6, ErrorF("WC_CONFIG Header = %s\n", header));
+ }
+ else {
+ ErrorF("WACOM: unable to reread resolution. Using default.\n");
+ }
+
+ /* The following couple of lines convert the MaxX and MaxY returned by
+ * the Wacom from 1270lpi to the Wacom's active resolution.
+ */
+ common->wcmMaxX = (common->wcmMaxX / MAX_COORD_RES) * common->wcmResolX;
+ common->wcmMaxY = (common->wcmMaxY / MAX_COORD_RES) * common->wcmResolY;
+ }
+
+ DBG(2, ErrorF("setup is max X=%d max Y=%d resol X=%d resol Y=%d\n",
+ common->wcmMaxX, common->wcmMaxY, common->wcmResolX,
+ common->wcmResolY));
+
+ /* Send a setup string to the tablet */
+ if (is_a_penpartner) {
+ SYSCALL(err = write(local->fd, penpartner_setup_string,
+ strlen(penpartner_setup_string)));
+ }
+ else if (common->wcmProtocolLevel == 4) {
+ SYSCALL(err = write(local->fd, WC_RESET, strlen(WC_RESET)));
+ WAIT(75);
+ SYSCALL(err = write(local->fd, setup_string, strlen(setup_string)));
+ }
+ else {
+ SYSCALL(err = write(local->fd, intuos_setup_string,
+ strlen(intuos_setup_string)));
+ }
+
+ if (err == -1) {
+ ErrorF("Wacom write error : %s\n", strerror(errno));
+ return !Success;
+ }
+
+ /* Send the tilt mode command after setup because it must be enabled */
+ /* after multi-mode to take precedence */
+ if (common->wcmProtocolLevel == 4 && HANDLE_TILT(common)) {
+ DBG(2, ErrorF("Sending tilt mode order\n"));
+
+ SYSCALL(err = write(local->fd, WC_TILT_MODE, strlen(WC_TILT_MODE)));
+ if (err == -1) {
+ ErrorF("Wacom write error : %s\n", strerror(errno));
+ return !Success;
+ }
+ }
+
+ if (common->wcmSuppress < 0) {
+ int xratio = common->wcmMaxX/screenInfo.screens[0]->width;
+ int yratio = common->wcmMaxY/screenInfo.screens[0]->height;
+
+ common->wcmSuppress = (xratio > yratio) ? yratio : xratio;
+ }
+
+ if (common->wcmSuppress > 100) {
+ common->wcmSuppress = 99;
+ }
+
+ if (common->wcmProtocolLevel == 4) {
+ char buf[20];
+
+ sprintf(buf, "%s%d\r", WC_SUPPRESS, common->wcmSuppress);
+ SYSCALL(err = write(local->fd, buf, strlen(buf)));
+
+ if (err == -1) {
+ ErrorF("Wacom write error : %s\n", strerror(errno));
+ return !Success;
+ }
+ }
+
+ if (xf86Verbose)
+ ErrorF("%s Wacom %s tablet maximum X=%d maximum Y=%d "
+ "X resolution=%d Y resolution=%d suppress=%d%s\n",
+ XCONFIG_PROBED, common->wcmProtocolLevel == 4 ? "IV" : "V",
+ common->wcmMaxX, common->wcmMaxY,
+ common->wcmResolX, common->wcmResolY, common->wcmSuppress,
+ HANDLE_TILT(common) ? " Tilt" : "");
+
+ if (err <= 0) {
+ SYSCALL(close(local->fd));
+ return !Success;
+ }
+
+ /* change the serial speed if requested */
+ if (common->wcmFlags & BAUD_19200_FLAG) {
+ if (common->wcmProtocolLevel == 5) {
+ DBG(1, ErrorF("Switching serial link to 19200\n"));
+
+ /* Switch the tablet to 19200 */
+ SYSCALL(err = write(local->fd, WC_V_19200, strlen(WC_V_19200)));
+ if (err == -1) {
+ ErrorF("Wacom write error : %s\n", strerror(errno));
+ return !Success;
+ }
+
+ /* Wait 75 mSecs */
+ WAIT(75);
+
+ /* Set the speed of the serial link to 19200 */
+#ifdef XFREE86_V4
+ if (xf86SetSerial(local->fd, b19200_options) < 0) {
+ return !Success;
+ }
+#else
+ if (set_serial_speed(local->fd, B19200) == !Success)
+ return !Success;
+#endif
+ }
+ else {
+ ErrorF("Changing the speed of a wacom IV device is not yet implemented\n");
+ }
+ }
+
+ /* Tell the tablet to start sending coordinates */
+ SYSCALL(err = write(local->fd, WC_START, strlen(WC_START)));
+
+ if (err == -1) {
+ ErrorF("Wacom write error : %s\n", strerror(errno));
+ return !Success;
+ }
+
+ return Success;
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmOpenDevice --
+ * Open the physical device and init information structs.
+ *
+ ***************************************************************************
+ */
+static int
+xf86WcmOpenDevice(DeviceIntPtr pWcm)
+{
+ LocalDevicePtr local = (LocalDevicePtr)pWcm->public.devicePrivate;
+ WacomDevicePtr priv = (WacomDevicePtr)PRIVATE(pWcm);
+ WacomCommonPtr common = priv->common;
+ double screenRatio, tabletRatio;
+ int gap;
+ int loop;
+
+ if (local->fd < 0) {
+ if (xf86WcmOpen(local) != Success) {
+ if (local->fd >= 0) {
+ SYSCALL(close(local->fd));
+ }
+ local->fd = -1;
+ }
+ else {
+ /* report the file descriptor to all devices */
+ for(loop=0; loop<common->wcmNumDevices; loop++) {
+ common->wcmDevices[loop]->fd = local->fd;
+ }
+ }
+ }
+
+ if (local->fd != -1 &&
+ priv->factorX == 0.0) {
+
+ if (priv->bottomX == 0) priv->bottomX = common->wcmMaxX;
+
+ if (priv->bottomY == 0) priv->bottomY = common->wcmMaxY;
+
+ /* Verify Box validity */
+
+ if (priv->topX > common->wcmMaxX ||
+ priv->topX < 0) {
+ ErrorF("Wacom invalid TopX (%d) reseting to 0\n", priv->topX);
+ priv->topX = 0;
+ }
+
+ if (priv->topY > common->wcmMaxY ||
+ priv->topY < 0) {
+ ErrorF("Wacom invalid TopY (%d) reseting to 0\n", priv->topY);
+ priv->topY = 0;
+ }
+
+ if (priv->bottomX > common->wcmMaxX ||
+ priv->bottomX < priv->topX) {
+ ErrorF("Wacom invalid BottomX (%d) reseting to %d\n",
+ priv->bottomX, common->wcmMaxX);
+ priv->bottomX = common->wcmMaxX;
+ }
+
+ if (priv->bottomY > common->wcmMaxY ||
+ priv->bottomY < priv->topY) {
+ ErrorF("Wacom invalid BottomY (%d) reseting to %d\n",
+ priv->bottomY, common->wcmMaxY);
+ priv->bottomY = common->wcmMaxY;
+ }
+
+ /* Calculate the ratio according to KeepShape, TopX and TopY */
+
+ if (priv->flags & KEEP_SHAPE_FLAG) {
+ screenRatio = ((double) screenInfo.screens[0]->width)
+ / screenInfo.screens[0]->height;
+
+ tabletRatio = ((double) (common->wcmMaxX - priv->topX))
+ / (common->wcmMaxY - priv->topY);
+
+ DBG(2, ErrorF("screenRatio = %.3g, tabletRatio = %.3g\n",
+ screenRatio, tabletRatio));
+
+ if (screenRatio > tabletRatio) {
+ gap = common->wcmMaxY * (1 - tabletRatio/screenRatio);
+ priv->bottomX = common->wcmMaxX;
+ priv->bottomY = common->wcmMaxY - gap;
+ } else {
+ gap = common->wcmMaxX * (1 - screenRatio/tabletRatio);
+ priv->bottomX = common->wcmMaxX - gap;
+ priv->bottomY = common->wcmMaxY;
+ }
+ }
+ priv->factorX = ((double) screenInfo.screens[0]->width)
+ / (priv->bottomX - priv->topX);
+ priv->factorY = ((double) screenInfo.screens[0]->height)
+ / (priv->bottomY - priv->topY);
+
+ if (xf86Verbose)
+ ErrorF("%s Wacom tablet top X=%d top Y=%d "
+ "bottom X=%d bottom Y=%d\n",
+ XCONFIG_PROBED, priv->topX, priv->topY,
+ priv->bottomX, priv->bottomY);
+
+ DBG(2, ErrorF("X factor = %.3g, Y factor = %.3g\n",
+ priv->factorX, priv->factorY));
+ }
+
+ /* Set the real values */
+ InitValuatorAxisStruct(pWcm,
+ 0,
+ 0, /* min val */
+ priv->bottomX - priv->topX, /* max val */
+ mils(common->wcmResolX), /* resolution */
+ 0, /* min_res */
+ mils(common->wcmResolX)); /* max_res */
+ InitValuatorAxisStruct(pWcm,
+ 1,
+ 0, /* min val */
+ priv->bottomY - priv->topY, /* max val */
+ mils(common->wcmResolY), /* resolution */
+ 0, /* min_res */
+ mils(common->wcmResolY)); /* max_res */
+ InitValuatorAxisStruct(pWcm,
+ 2,
+ - common->wcmMaxZ / 2, /* min val */
+ common->wcmMaxZ / 2, /* max val */
+ mils(common->wcmResolZ), /* resolution */
+ 0, /* min_res */
+ mils(common->wcmResolZ)); /* max_res */
+ InitValuatorAxisStruct(pWcm,
+ 3,
+ -64, /* min val */
+ 63, /* max val */
+ 128, /* resolution ??? */
+ 0,
+ 128);
+ InitValuatorAxisStruct(pWcm,
+ 4,
+ -64, /* min val */
+ 63, /* max val */
+ 128, /* resolution ??? */
+ 0,
+ 128);
+ InitValuatorAxisStruct(pWcm,
+ 5,
+ 0, /* min val */
+ 1023, /* max val */
+ 128, /* resolution ??? */
+ 0,
+ 128);
+
+ return (local->fd != -1);
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmClose --
+ *
+ ***************************************************************************
+ */
+static void
+xf86WcmClose(LocalDevicePtr local)
+{
+ WacomDevicePtr priv = (WacomDevicePtr)local->private;
+ WacomCommonPtr common = priv->common;
+ int loop;
+ int num = 0;
+
+ for(loop=0; loop<common->wcmNumDevices; loop++) {
+ if (common->wcmDevices[loop]->fd >= 0) {
+ num++;
+ }
+ }
+ DBG(4, ErrorF("Wacom number of open devices = %d\n", num));
+
+ if (num == 1) {
+ SYSCALL(close(local->fd));
+ }
+
+ local->fd = -1;
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmProc --
+ * Handle the initialization, etc. of a wacom
+ *
+ ***************************************************************************
+ */
+static int
+xf86WcmProc(DeviceIntPtr pWcm,
+ int what)
+{
+ CARD8 map[(32 << 4) + 1];
+ int nbaxes;
+ int nbbuttons;
+ int loop;
+ LocalDevicePtr local = (LocalDevicePtr)pWcm->public.devicePrivate;
+ WacomDevicePtr priv = (WacomDevicePtr)PRIVATE(pWcm);
+
+ DBG(2, ErrorF("BEGIN xf86WcmProc dev=0x%x priv=0x%x type=%s flags=%d what=%d\n",
+ pWcm, priv, (DEVICE_ID(priv->flags) == STYLUS_ID) ? "stylus" :
+ (DEVICE_ID(priv->flags) == CURSOR_ID) ? "cursor" : "eraser",
+ priv->flags, what));
+
+ switch (what)
+ {
+ case DEVICE_INIT:
+ DBG(1, ErrorF("xf86WcmProc pWcm=0x%x what=INIT\n", pWcm));
+
+ nbaxes = 6; /* X, Y, Pressure, Tilt-X, Tilt-Y, Wheel */
+
+ switch(DEVICE_ID(priv->flags)) {
+ case ERASER_ID:
+ nbbuttons = 1;
+ break;
+ case STYLUS_ID:
+ nbbuttons = 4;
+ break;
+ default:
+ nbbuttons = 16;
+ break;
+ }
+
+ for(loop=1; loop<=nbbuttons; loop++) map[loop] = loop;
+
+ if (InitButtonClassDeviceStruct(pWcm,
+ nbbuttons,
+ map) == FALSE) {
+ ErrorF("unable to allocate Button class device\n");
+ return !Success;
+ }
+
+ if (InitFocusClassDeviceStruct(pWcm) == FALSE) {
+ ErrorF("unable to init Focus class device\n");
+ return !Success;
+ }
+
+ if (InitPtrFeedbackClassDeviceStruct(pWcm,
+ xf86WcmControlProc) == FALSE) {
+ ErrorF("unable to init ptr feedback\n");
+ return !Success;
+ }
+
+ if (InitProximityClassDeviceStruct(pWcm) == FALSE) {
+ ErrorF("unable to init proximity class device\n");
+ return !Success;
+ }
+
+ if (InitKeyClassDeviceStruct(pWcm, &wacom_keysyms, NULL) == FALSE) {
+ ErrorF("unable to init key class device\n");
+ return !Success;
+ }
+
+ if (InitValuatorClassDeviceStruct(pWcm,
+ nbaxes,
+ xf86GetMotionEvents,
+ local->history_size,
+ ((priv->flags & ABSOLUTE_FLAG)
+ ? Absolute : Relative) |
+ OutOfProximity)
+ == FALSE) {
+ ErrorF("unable to allocate Valuator class device\n");
+ return !Success;
+ }
+ else {
+ /* allocate the motion history buffer if needed */
+ xf86MotionHistoryAllocate(local);
+#ifndef XFREE86_V4
+ AssignTypeAndName(pWcm, local->atom, local->name);
+#endif
+ }
+
+ /* open the device to gather informations */
+ xf86WcmOpenDevice(pWcm);
+
+ break;
+
+ case DEVICE_ON:
+ DBG(1, ErrorF("xf86WcmProc pWcm=0x%x what=ON\n", pWcm));
+
+ if ((local->fd < 0) && (!xf86WcmOpenDevice(pWcm))) {
+ return !Success;
+ }
+ AddEnabledDevice(local->fd);
+ pWcm->public.on = TRUE;
+ break;
+
+ case DEVICE_OFF:
+ DBG(1, ErrorF("xf86WcmProc pWcm=0x%x what=%s\n", pWcm,
+ (what == DEVICE_CLOSE) ? "CLOSE" : "OFF"));
+ if (local->fd >= 0) {
+ RemoveEnabledDevice(local->fd);
+ xf86WcmClose(local);
+ }
+ pWcm->public.on = FALSE;
+ break;
+
+ case DEVICE_CLOSE:
+ DBG(1, ErrorF("xf86WcmProc pWcm=0x%x what=%s\n", pWcm,
+ (what == DEVICE_CLOSE) ? "CLOSE" : "OFF"));
+ xf86WcmClose(local);
+ break;
+
+ default:
+ ErrorF("unsupported mode=%d\n", what);
+ return !Success;
+ break;
+ }
+ DBG(2, ErrorF("END xf86WcmProc Success what=%d dev=0x%x priv=0x%x\n",
+ what, pWcm, priv));
+ return Success;
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmChangeControl --
+ *
+ ***************************************************************************
+ */
+static int
+xf86WcmChangeControl(LocalDevicePtr local,
+ xDeviceCtl *control)
+{
+ xDeviceResolutionCtl *res;
+ int *resolutions;
+ char str[10];
+
+ res = (xDeviceResolutionCtl *)control;
+
+ if ((control->control != DEVICE_RESOLUTION) ||
+ (res->num_valuators < 1))
+ return (BadMatch);
+
+ resolutions = (int *)(res +1);
+
+ DBG(3, ErrorF("xf86WcmChangeControl changing to %d (suppressing under)\n",
+ resolutions[0]));
+
+ sprintf(str, "SU%d\r", resolutions[0]);
+ SYSCALL(write(local->fd, str, strlen(str)));
+
+ return(Success);
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmSwitchMode --
+ *
+ ***************************************************************************
+ */
+static int
+xf86WcmSwitchMode(ClientPtr client,
+ DeviceIntPtr dev,
+ int mode)
+{
+ LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
+ WacomDevicePtr priv = (WacomDevicePtr)local->private;
+
+ DBG(3, ErrorF("xf86WcmSwitchMode dev=0x%x mode=%d\n", dev, mode));
+
+ if (mode == Absolute) {
+ priv->flags = priv->flags | ABSOLUTE_FLAG;
+ }
+ else {
+ if (mode == Relative) {
+ priv->flags = priv->flags & ~ABSOLUTE_FLAG;
+ }
+ else {
+ DBG(1, ErrorF("xf86WcmSwitchMode dev=0x%x invalid mode=%d\n", dev,
+ mode));
+ return BadMatch;
+ }
+ }
+ return Success;
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmAllocate --
+ *
+ ***************************************************************************
+ */
+static LocalDevicePtr
+xf86WcmAllocate(char * name,
+ int flag)
+{
+#ifdef XFREE86_V4
+ LocalDevicePtr local = xf86AllocateInput(wcmDrv, 0);
+#else
+ LocalDevicePtr local = (LocalDevicePtr) xalloc(sizeof(LocalDeviceRec));
+#endif
+ WacomDevicePtr priv = (WacomDevicePtr) xalloc(sizeof(WacomDeviceRec));
+ WacomCommonPtr common = (WacomCommonPtr) xalloc(sizeof(WacomCommonRec));
+#if defined(sun) && !defined(i386)
+ char *dev_name = (char *) getenv("WACOM_DEV");
+#endif
+
+ local->name = name;
+ local->flags = 0;
+#ifndef XFREE86_V4
+#if !defined(sun) || defined(i386)
+ local->device_config = xf86WcmConfig;
+#endif
+#endif
+ local->device_control = xf86WcmProc;
+ local->read_input = xf86WcmReadInput;
+ local->control_proc = xf86WcmChangeControl;
+ local->close_proc = xf86WcmClose;
+ local->switch_mode = xf86WcmSwitchMode;
+ local->conversion_proc = xf86WcmConvert;
+ local->reverse_conversion_proc = xf86WcmReverseConvert;
+ local->fd = -1;
+ local->atom = 0;
+ local->dev = NULL;
+ local->private = priv;
+ local->private_flags = 0;
+ local->history_size = 0;
+ local->old_x = -1;
+ local->old_y = -1;
+
+ priv->flags = flag; /* various flags (device type, absolute, first touch...) */
+ priv->oldX = -1; /* previous X position */
+ priv->oldY = -1; /* previous Y position */
+ priv->oldZ = -1; /* previous pressure */
+ priv->oldTiltX = -1; /* previous tilt in x direction */
+ priv->oldTiltY = -1; /* previous tilt in y direction */
+ priv->oldButtons = 0; /* previous buttons state */
+ priv->oldProximity = 0; /* previous proximity */
+ priv->topX = 0; /* X top */
+ priv->topY = 0; /* Y top */
+ priv->bottomX = 0; /* X bottom */
+ priv->bottomY = 0; /* Y bottom */
+ priv->factorX = 0.0; /* X factor */
+ priv->factorY = 0.0; /* Y factor */
+ priv->common = common; /* common info pointer */
+ priv->oldProximity = 0; /* previous proximity */
+ priv->serial = 0; /* serial number */
+
+ common->wcmDevice = ""; /* device file name */
+#if defined(sun) && !defined(i386)
+ if (dev_name) {
+ common->wcmDevice = (char*) xalloc(strlen(dev_name)+1);
+ strcpy(common->wcmDevice, dev_name);
+ ErrorF("xf86WcmOpen port changed to '%s'\n", common->wcmDevice);
+ }
+#endif
+ common->wcmSuppress = -1; /* transmit position if increment is superior */
+ common->wcmFlags = 0; /* various flags */
+ common->wcmDevices = (LocalDevicePtr*) xalloc(sizeof(LocalDevicePtr));
+ common->wcmDevices[0] = local;
+ common->wcmNumDevices = 1; /* number of devices */
+ common->wcmIndex = 0; /* number of bytes read */
+ common->wcmPktLength = 7; /* length of a packet */
+ common->wcmMaxX = 22860; /* max X value */
+ common->wcmMaxY = 15240; /* max Y value */
+ common->wcmMaxZ = 240; /* max Z value */
+ common->wcmResolX = 1270; /* X resolution in points/inch */
+ common->wcmResolY = 1270; /* Y resolution in points/inch */
+ common->wcmResolZ = 1270; /* Z resolution in points/inch */
+ common->wcmHasEraser = (flag & ERASER_ID) ? TRUE : FALSE; /* True if an eraser has been configured */
+ common->wcmStylusSide = TRUE; /* eraser or stylus ? */
+ common->wcmStylusProximity = FALSE; /* a stylus is in proximity ? */
+ common->wcmProtocolLevel = 4; /* protocol level */
+
+ return local;
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmAllocateStylus --
+ *
+ ***************************************************************************
+ */
+static LocalDevicePtr
+xf86WcmAllocateStylus()
+{
+ LocalDevicePtr local = xf86WcmAllocate(XI_STYLUS, STYLUS_ID);
+
+ local->type_name = "Wacom Stylus";
+ return local;
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmAllocateCursor --
+ *
+ ***************************************************************************
+ */
+static LocalDevicePtr
+xf86WcmAllocateCursor()
+{
+ LocalDevicePtr local = xf86WcmAllocate(XI_CURSOR, CURSOR_ID);
+
+ local->type_name = "Wacom Cursor";
+ return local;
+}
+
+/*
+ ***************************************************************************
+ *
+ * xf86WcmAllocateEraser --
+ *
+ ***************************************************************************
+ */
+static LocalDevicePtr
+xf86WcmAllocateEraser()
+{
+ LocalDevicePtr local = xf86WcmAllocate(XI_ERASER, ABSOLUTE_FLAG|ERASER_ID);
+
+ local->type_name = "Wacom Eraser";
+ return local;
+}
+
+/*
+ ***************************************************************************
+ *
+ * Wacom Stylus device association --
+ *
+ ***************************************************************************
+ */
+DeviceAssocRec wacom_stylus_assoc =
+{
+ STYLUS_SECTION_NAME, /* config_section_name */
+ xf86WcmAllocateStylus /* device_allocate */
+};
+
+/*
+ ***************************************************************************
+ *
+ * Wacom Cursor device association --
+ *
+ ***************************************************************************
+ */
+DeviceAssocRec wacom_cursor_assoc =
+{
+ CURSOR_SECTION_NAME, /* config_section_name */
+ xf86WcmAllocateCursor /* device_allocate */
+};
+
+/*
+ ***************************************************************************
+ *
+ * Wacom Eraser device association --
+ *
+ ***************************************************************************
+ */
+DeviceAssocRec wacom_eraser_assoc =
+{
+ ERASER_SECTION_NAME, /* config_section_name */
+ xf86WcmAllocateEraser /* device_allocate */
+};
+
+#ifndef XFREE86_V4
+#ifdef DYNAMIC_MODULE
+/*
+ ***************************************************************************
+ *
+ * entry point of dynamic loading
+ *
+ ***************************************************************************
+ */
+int
+#ifndef DLSYM_BUG
+init_module(unsigned long server_version)
+#else
+init_xf86Wacom(unsigned long server_version)
+#endif
+{
+ xf86AddDeviceAssoc(&wacom_stylus_assoc);
+ xf86AddDeviceAssoc(&wacom_cursor_assoc);
+ xf86AddDeviceAssoc(&wacom_eraser_assoc);
+
+ if (server_version != XF86_VERSION_CURRENT) {
+ ErrorF("Warning: Wacom module compiled for version%s\n", XF86_VERSION);
+ return 0;
+ } else {
+ return 1;
+ }
+}
+#endif /* DYNAMIC_MODULE */
+
+#else /* XFREE86_V4 */
+
+/*
+ * xf86WcmUnplug --
+ *
+ * called when the driver is unloaded.
+ */
+static void
+xf86WcmUninit(InputDriverPtr drv,
+ LocalDevicePtr local,
+ int flags)
+{
+ WacomDevicePtr priv = (WacomDevicePtr) local->private;
+
+ ErrorF("xf86WcmUnplug\n");
+
+ xf86WcmProc(local->dev, DEVICE_OFF);
+
+ xfree (priv);
+ xf86DeleteInput(local, 0);
+}
+
+/*
+ * xf86WcmPlug --
+ *
+ * called when the module subsection is found in XF86Config
+ */
+static InputInfoPtr
+xf86WcmInit(InputDriverPtr drv,
+ IDevPtr dev,
+ int flags)
+{
+ LocalDevicePtr local = NULL;
+ LocalDevicePtr fakeLocal = NULL;
+ WacomDevicePtr priv = NULL;
+ WacomCommonPtr common = NULL;
+ char *s;
+ LocalDevicePtr localDevices;
+
+ wcmDrv = drv;
+
+ fakeLocal = (LocalDevicePtr) xcalloc(1, sizeof(LocalDeviceRec));
+ fakeLocal->conf_idev = dev;
+
+ /* Force default serial port options to exist because the serial init
+ * phasis is based on those values.
+ */
+ xf86CollectInputOptions(fakeLocal, default_options, NULL);
+
+ /* Type is mandatory */
+ s = xf86FindOptionValue(fakeLocal->options, "Type");
+
+ if (s && (xf86NameCmp(s, "stylus") == 0)) {
+ local = xf86WcmAllocateStylus();
+ }
+ else if (s && (xf86NameCmp(s, "cursor") == 0)) {
+ local = xf86WcmAllocateCursor();
+ }
+ else if (s && (xf86NameCmp(s, "eraser") == 0)) {
+ local = xf86WcmAllocateEraser();
+ }
+ else {
+ xf86Msg(X_ERROR, "%s: No type or invalid type specified.\n"
+ "Must be one of stylus, cursor or eraser\n",
+ dev->identifier);
+ goto SetupProc_fail;
+ }
+
+ if (local)
+ priv = (WacomDevicePtr) local->private;
+ if (priv)
+ common = priv->common;
+
+ if (!local || !priv || !common) {
+ goto SetupProc_fail;
+ }
+
+ local->options = fakeLocal->options;
+ local->conf_idev = fakeLocal->conf_idev;
+ local->name = dev->identifier;
+ xfree(fakeLocal);
+
+ /* Serial Device is mandatory */
+ common->wcmDevice = xf86FindOptionValue(local->options, "Device");
+
+ if (!common->wcmDevice) {
+ xf86Msg (X_ERROR, "%s: No Device specified.\n", dev->identifier);
+ goto SetupProc_fail;
+ }
+
+ /* Lookup to see if there is another wacom device sharing
+ * the same serial line.
+ */
+ localDevices = xf86FirstLocalDevice();
+
+ while(localDevices) {
+ if ((local != localDevices) &&
+ (localDevices->read_input == xf86WcmReadInput) &&
+ (strcmp(((WacomDevicePtr)localDevices->private)->common->wcmDevice,
+ common->wcmDevice) == 0)) {
+ DBG(2, ErrorF("xf86WcmConfig wacom port share between"
+ " %s and %s\n",
+ local->name, localDevices->name));
+ ((WacomDevicePtr) localDevices->private)->common->wcmHasEraser |= common->wcmHasEraser;
+ xfree(common->wcmDevices);
+ xfree(common);
+ common = priv->common = ((WacomDevicePtr) localDevices->private)->common;
+ common->wcmNumDevices++;
+ common->wcmDevices = (LocalDevicePtr *) xrealloc(common->wcmDevices,
+ sizeof(LocalDevicePtr) * common->wcmNumDevices);
+ common->wcmDevices[common->wcmNumDevices - 1] = local;
+ break;
+ }
+ localDevices = localDevices->next;
+ }
+
+ /* Process the common options. */
+ xf86ProcessCommonOptions(local, local->options);
+
+ /* Optional configuration */
+
+ xf86Msg(X_CONFIG, "%s serial device is %s\n", dev->identifier,
+ common->wcmDevice);
+
+ debug_level = xf86SetIntOption(local->options, "DebugLevel", 0);
+ if (debug_level > 0) {
+ xf86Msg(X_CONFIG, "WACOM: debug level set to %d\n", debug_level);
+ }
+
+ s = xf86FindOptionValue(local->options, "Mode");
+
+ if (s && (xf86NameCmp(s, "absolute") == 0)) {
+ priv->flags = priv->flags | ABSOLUTE_FLAG;
+ }
+ else if (s && (xf86NameCmp(s, "relative") == 0)) {
+ priv->flags = priv->flags & ~ABSOLUTE_FLAG;
+ }
+ else if (s) {
+ xf86Msg(X_ERROR, "%s: invalid Mode (should be absolute or relative). Using default.\n",
+ dev->identifier);
+ }
+ xf86Msg(X_CONFIG, "%s is in %s mode\n", local->name,
+ (priv->flags & ABSOLUTE_FLAG) ? "absolute" : "relative");
+
+ common->wcmSuppress = xf86SetIntOption(local->options, "Suppress", -1);
+ if (common->wcmSuppress != -1) {
+ xf86Msg(X_CONFIG, "WACOM: suppress value is %d\n", XCONFIG_GIVEN,
+ common->wcmSuppress);
+ }
+
+ if (xf86SetBoolOption(local->options, "Tilt", 0)) {
+ common->wcmFlags |= TILT_FLAG;
+ }
+
+ if (xf86SetBoolOption(local->options, "KeepShape", 0)) {
+ priv->flags |= KEEP_SHAPE_FLAG;
+ xf86Msg(X_CONFIG, "%s: keeps shape\n", dev->identifier);
+ }
+
+ priv->topX = xf86SetIntOption(local->options, "TopX", 0);
+ if (priv->topX != 0) {
+ xf86Msg(X_CONFIG, "%s: top x = %d\n", dev->identifier, priv->topX);
+ }
+ priv->topY = xf86SetIntOption(local->options, "TopY", 0);
+ if (priv->topY != 0) {
+ xf86Msg(X_CONFIG, "%s: top x = %d\n", dev->identifier, priv->topY);
+ }
+ priv->bottomX = xf86SetIntOption(local->options, "BottomX", 0);
+ if (priv->bottomX != 0) {
+ xf86Msg(X_CONFIG, "%s: bottom x = %d\n", dev->identifier,
+ priv->bottomX);
+ }
+ priv->bottomY = xf86SetIntOption(local->options, "BottomY", 0);
+ if (priv->bottomY != 0) {
+ xf86Msg(X_CONFIG, "%s: bottom x = %d\n", dev->identifier,
+ priv->bottomY);
+ }
+ priv->serial = xf86SetIntOption(local->options, "Serial", 0);
+ if (priv->bottomY != 0) {
+ xf86Msg(X_CONFIG, "%s: serial number = %u\n", dev->identifier,
+ priv->serial);
+ }
+
+ {
+ int val;
+ val = xf86SetIntOption(local->options, "BaudRate", 0);
+
+ switch(val) {
+ case 19200:
+ common->wcmFlags = common->wcmFlags | BAUD_19200_FLAG;
+ break;
+ case 9600:
+ common->wcmFlags = common->wcmFlags & ~BAUD_19200_FLAG;
+ break;
+ default:
+ xf86Msg(X_ERROR, "%s: Illegal speed value (must be 9600 or 19200).", dev->identifier);
+ break;
+ }
+ if (xf86Verbose)
+ xf86Msg(X_CONFIG, "%s: serial speed %u\n", dev->identifier,
+ val);
+ }
+ /* mark the device configured */
+ local->flags |= XI86_CONFIGURED;
+
+ /* return the LocalDevice */
+ return (local);
+
+ SetupProc_fail:
+ if (common)
+ xfree(common);
+ if (priv)
+ xfree(priv);
+ if (local)
+ xfree(local);
+ return NULL;
+}
+
+#ifdef XFree86LOADER
+static
+#endif
+InputDriverRec WACOM = {
+ 1, /* driver version */
+ "wacom", /* driver name */
+ NULL, /* identify */
+ xf86WcmInit, /* pre-init */
+ xf86WcmUninit, /* un-init */
+ NULL, /* module */
+ 0 /* ref count */
+};
+
+/*
+ ***************************************************************************
+ *
+ * Dynamic loading functions
+ *
+ ***************************************************************************
+ */
+#ifdef XFree86LOADER
+/*
+ * xf86WcmUnplug --
+ *
+ * called when the module subsection is found in XF86Config
+ */
+static void
+xf86WcmUnplug(pointer p)
+{
+ DBG(1, ErrorF("xf86WcmUnplug\n"));
+}
+
+/*
+ * xf86WcmPlug --
+ *
+ * called when the module subsection is found in XF86Config
+ */
+static pointer
+xf86WcmPlug(pointer module,
+ pointer options,
+ int *errmaj,
+ int *errmin)
+{
+ DBG(1, ErrorF("xf86WcmPlug\n"));
+
+ xf86AddInputDriver(&WACOM, module, 0);
+
+ return module;
+}
+
+static XF86ModuleVersionInfo xf86WcmVersionRec =
+{
+ "wacom",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_XINPUT,
+ ABI_XINPUT_VERSION,
+ MOD_CLASS_XINPUT,
+ {0, 0, 0, 0} /* signature, to be patched into the file by */
+ /* a tool */
+};
+
+XF86ModuleData wacomModuleData = {&xf86WcmVersionRec,
+ xf86WcmPlug,
+ xf86WcmUnplug};
+
+#endif /* XFree86LOADER */
+#endif /* XFREE86_V4 */
+
+/*
+ * Local variables:
+ * change-log-default-name: "~/xinput.log"
+ * End:
+ */
+/* end of xf86Wacom.c */
diff --git a/xc/programs/Xserver/hw/xfree86/loader/Imakefile b/xc/programs/Xserver/hw/xfree86/loader/Imakefile
new file mode 100644
index 000000000..de07f61c1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/Imakefile
@@ -0,0 +1,54 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/loader/Imakefile,v 1.17 1999/07/04 06:39:09 dawes Exp $ */
+
+
+
+
+#include <Server.tmpl>
+#ifdef LoaderTest
+#define IHaveSubdirs
+SUBDIRS = test
+#endif
+
+#define UseDBMalloc NO
+
+#if UseDBMalloc
+SYS_LIBRARIES=-ldbmalloc
+DBMALLOCDEFINE=-DDBMALLOC
+#endif
+
+#if HasDlopen
+DLOPENDEFINES = -DDLOPEN_SUPPORT
+DLSRC=dlloader.c
+DLOBJ=dlloader.o
+#endif
+
+DEFINES = $(DBMALLOCDEFINE) $(DLOPENDEFINES)
+
+MODULEDEFINES = -DDEFAULT_MODULE_PATH=\"$(MODULEDIR)\"
+
+ INCLUDES = -I. -I.. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/dbe -I$(SERVERSRC)/Xext \
+ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi -I$(SERVERSRC)/include \
+ -I$(SERVERSRC)/os -I$(XINCLUDESRC) -I$(FONTINCSRC) \
+ -I$(FONTLIBSRC)/include -I$(EXTINCSRC)
+
+#ifdef OS2Architecture
+SRCS1 = os2funcs.c
+OBJS1 = os2funcs.o
+#endif
+
+SRCS = aoutloader.c coffloader.c $(DLSRC) elfloader.c hash.c loader.c \
+ loadmod.c loadfont.c os.c dixsym.c misym.c xf86sym.c fontsym.c $(SRCS1)
+OBJS = aoutloader.o coffloader.o $(DLOBJ) elfloader.o hash.o loader.o \
+ loadmod.o loadfont.o os.o dixsym.o misym.o xf86sym.o fontsym.o $(OBJS1)
+
+NormalAsmObjectRule()
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(loader,$(OBJS))
+
+SpecialCObjectRule(loadmod,NullParameter,$(MODULEDEFINES) $(EXT_DEFINES))
+SpecialCObjectRule(xf86sym,NullParameter,$(EXT_DEFINES))
+SpecialCObjectRule(dixsym,NullParameter,$(EXT_DEFINES))
+
+DependTarget()
diff --git a/xc/programs/Xserver/hw/xfree86/loader/README b/xc/programs/Xserver/hw/xfree86/loader/README
new file mode 100644
index 000000000..4fb375fcb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/README
@@ -0,0 +1,107 @@
+
+This README file describes the design and idea behind the loadable module
+code for XFree86. This code is based of code that was developed by Metro Link
+and donated to The XFree86 Project.
+
+<at this point we should include the design document as written by Stuart>
+
+Debugging this code is somewhat dificult as gdb will not be able to step
+through loaded modules in source mode. The functions
+
+LoaderPrintSymbol( address )
+LoaderPrintAddress( symbol )
+
+are provided to allow easy orientation in the loaded module. Most problems
+stem from global functions and variables that are not exported from other
+modules or the main server executable, but are referenced in a module.
+All global variables should be put in ScreenPrivates or other container
+objects, that are driver specific. This will solve the biggest problem
+cleanly and at the same time provide an important step towards multi headed
+servers.
+
+More documentation on the design and implementation should be added here.
+
+Specific comments to some design ideas and the state of the code
+
+- Init Function
+
+every module has its init function, which has the name ModuleInit.
+When loading the module this function is repeatedly called with two pointers
+(one to a magic value, one to a data element) until it returns a magic value
+indicating that it is done. Currently the magic values support several
+actions:
+
+magic data points to
+
+MAGIC_ADD_VIDEO_CHIP_REC the videoChipRec to be added to the list
+ of drivers
+
+MAGIC_LOAD the name of the module to load
+
+MAGIC_CCD_DO_BITBLT the do_bitblt function for the current
+ color depth
+
+MAGIC_CCD_SCREEN_PRIV_IDX the ScreenPrivIdx for the current color depth
+
+MAGIC_CCD_XAA_SCREEN_INIT the XaaScreenInit function for the current
+ color depth
+
+MAGIC_PEX_INIT
+MAGIC_XIE_INIT init functions of extensions
+
+MAGIC_DONT_CHECK_UNRESOLVED checking for unresolved symbols will be delayed
+ for one step until LoaderCheckUnresolved()
+ is called with LD_RESOLV_NOW the same number of
+ times than MAGIC_DONT_CHECK_UNRESOLVED
+ has been passed before.
+
+MAGIC_DONE nothing; side effect is to stop looping
+
+- mixed color depths
+
+the current code has various cross dependencies on cfb8, libvga256, and all
+higher depths cfbs as well as all the xaa modules. These need to be
+straightened out (this has been started but is far from done).
+We basically need a redesigned server to solve these issues cleanly.
+
+- unresolved functions
+
+the current code has one 'minor' flaw. When checking unresolved symbols
+we reference quite a few things from the cfb libraries that we did not
+pull in. Since these functions are never called, this doesn't really
+matter, but it is uggly, obviously.
+
+Changing all this to use function pointers and initializing all of
+them sounds like the clean solution, but I'm wondering if it wasn't
+better to define a default function that is bound to all unresolved
+symbols and prints out that there was a problem with resolving symbols
+and makes the server exit gracefully. This would be a reasonable
+default behaviour and would allow to keep dangling references to
+functions that are known not to be called.
+
+This "elegant hack" has been implemented for the Elf loader, but better
+solutions are welcome.
+
+- OS support
+
+Currently this has been tested on Linux, it should work on SVR4. This
+code needs to be ported to the other operating systems XFree86 supports.
+
+- finding modules
+
+ModulePath can contain several entries of directories that contain modules.
+Modules can be implicitly or explicitly loaded. To load a module explicitly
+you have to include it in the Module Section. Load "name" tries to find
+name, name.o, name_drv.o, or name.a in any of the directories given in the
+ModulePath or in the subdirectories drivers, extensions, internal under these
+directories. Normally the chipset drivers should be implemented in a way that
+they implicitly load all other core modules needed by this driver.
+
+----------------------------------------------------------------------
+
+Last updated Feb 25, 1997, Dirk H. Hohndel <hohndel@XFree86.Org>
+
+
+
+
+$XFree86: xc/programs/Xserver/hw/xfree86/loader/README,v 1.4 1997/04/08 14:54:33 hohndel Exp $
diff --git a/xc/programs/Xserver/hw/xfree86/loader/aout.h b/xc/programs/Xserver/hw/xfree86/loader/aout.h
new file mode 100644
index 000000000..421a2c467
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/aout.h
@@ -0,0 +1,232 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/aout.h,v 1.6 1999/04/29 09:13:47 dawes Exp $ */
+
+/*
+ * Borrowed from NetBSD's exec_aout.h
+ *
+ * Copyright (c) 1993, 1994 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christopher G. Demetriou.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _AOUT_H
+#define _AOUT_H
+
+#include "Xos.h"
+
+/* Get prototype for ntohl. */
+#include <ctype.h>
+
+/* OS/2 EMX has ntohl in this file */
+#ifdef __EMX__
+#include <sys/param.h>
+#endif
+
+#define __LDPGSZ 4096U
+#ifndef AOUT_PAGSIZ
+#define AOUT_PAGSIZ(ex) (__LDPGSZ)
+#endif
+
+/*
+ * a.out header
+ */
+typedef struct AOUT_exec {
+ unsigned long a_midmag; /* htonl(flags<<26 | mid<<16 | magic) */
+ unsigned long a_text; /* text segment size */
+ unsigned long a_data; /* initialized data size */
+ unsigned long a_bss; /* uninitialized data size */
+ unsigned long a_syms; /* symbol table size */
+ unsigned long a_entry; /* entry point */
+ unsigned long a_trsize; /* text relocation size */
+ unsigned long a_drsize; /* data relocation size */
+} AOUTHDR;
+
+/* a_magic */
+#define OMAGIC 0407 /* old impure format */
+#define NMAGIC 0410 /* read-only text */
+#define ZMAGIC 0413 /* demand load format */
+#define QMAGIC 0314 /* "compact" demand load format; deprecated */
+
+/*
+ * a_mid - keep sorted in numerical order for sanity's sake
+ * ensure that: 0 < mid < 0x3ff
+ */
+#define MID_ZERO 0 /* unknown - implementation dependent */
+#define MID_SUN010 1 /* sun 68010/68020 binary */
+#define MID_SUN020 2 /* sun 68020-only binary */
+#define MID_PC386 100 /* 386 PC binary. (so quoth BFD) */
+#define MID_HP200 200 /* hp200 (68010) BSD binary */
+#define MID_I386 134 /* i386 BSD binary */
+#define MID_M68K 135 /* m68k BSD binary with 8K page sizes */
+#define MID_M68K4K 136 /* m68k BSD binary with 4K page sizes */
+#define MID_NS32532 137 /* ns32532 */
+#define MID_SPARC 138 /* sparc */
+#define MID_PMAX 139 /* pmax */
+#define MID_VAX 140 /* vax */
+#define MID_ALPHA 141 /* Alpha BSD binary */
+#define MID_MIPS 142 /* big-endian MIPS */
+#define MID_ARM6 143 /* ARM6 */
+#define MID_HP300 300 /* hp300 (68020+68881) BSD binary */
+#define MID_HPUX 0x20C /* hp200/300 HP-UX binary */
+#define MID_HPUX800 0x20B /* hp800 HP-UX binary */
+
+/*
+ * a_flags
+ */
+#define EX_DYNAMIC 0x20
+#define EX_PIC 0x10
+#define EX_DPMASK 0x30
+/*
+ * Interpretation of the (a_flags & EX_DPMASK) bits:
+ *
+ * 00 traditional executable or object file
+ * 01 object file contains PIC code (set by `as -k')
+ * 10 dynamic executable
+ * 11 position independent executable image
+ * (eg. a shared library)
+ *
+ */
+
+/*
+ * The a.out structure's a_midmag field is a network-byteorder encoding
+ * of this int
+ * FFFFFFmmmmmmmmmmMMMMMMMMMMMMMMMM
+ * Where `F' is 6 bits of flag like EX_DYNAMIC,
+ * `m' is 10 bits of machine-id like MID_I386, and
+ * `M' is 16 bits worth of magic number, ie. ZMAGIC.
+ * The macros below will set/get the needed fields.
+ */
+#define AOUT_GETMAGIC(ex) \
+ ( (((ex)->a_midmag)&0xffff0000U) ? (ntohl(((ex)->a_midmag))&0xffffU) : ((ex)->a_midmag))
+#define AOUT_GETMAGIC2(ex) \
+ ( (((ex)->a_midmag)&0xffff0000U) ? (ntohl(((ex)->a_midmag))&0xffffU) : \
+ (((ex)->a_midmag) | 0x10000) )
+#define AOUT_GETMID(ex) \
+ ( (((ex)->a_midmag)&0xffff0000U) ? ((ntohl(((ex)->a_midmag))>>16)&0x03ffU) : MID_ZERO )
+#define AOUT_GETFLAG(ex) \
+ ( (((ex)->a_midmag)&0xffff0000U) ? ((ntohl(((ex)->a_midmag))>>26)&0x3fU) : 0 )
+#define AOUT_SETMAGIC(ex,mag,mid,flag) \
+ ( (ex)->a_midmag = htonl( (((flag)&0x3fU)<<26) | (((mid)&0x03ffU)<<16) | \
+ (((mag)&0xffffU)) ) )
+
+#define AOUT_ALIGN(ex,x) \
+ (AOUT_GETMAGIC(ex) == ZMAGIC || AOUT_GETMAGIC(ex) == QMAGIC ? \
+ ((x) + __LDPGSZ - 1) & ~(__LDPGSZ - 1) : (x))
+
+/* Valid magic number check. */
+#define AOUT_BADMAG(ex) \
+ (AOUT_GETMAGIC(ex) != NMAGIC && AOUT_GETMAGIC(ex) != OMAGIC && \
+ AOUT_GETMAGIC(ex) != ZMAGIC && AOUT_GETMAGIC(ex) != QMAGIC)
+
+/* Address of the bottom of the text segment. */
+#define AOUT_TXTADDR(ex) (AOUT_GETMAGIC2(ex) == (ZMAGIC|0x10000) ? 0 : __LDPGSZ)
+
+/* Address of the bottom of the data segment. */
+#define AOUT_DATADDR(ex) \
+ (AOUT_GETMAGIC(ex) == OMAGIC ? AOUT_TXTADDR(ex) + (ex)->a_text : \
+ (AOUT_TXTADDR(ex) + (ex)->a_text + __LDPGSZ - 1) & ~(__LDPGSZ - 1))
+
+/* Address of the bottom of the bss segment. */
+#define AOUT_BSSADDR(ex) \
+ (AOUT_DATADDR(ex) + (ex)->a_data)
+
+/* Text segment offset. */
+#define AOUT_TXTOFF(ex) \
+ ( AOUT_GETMAGIC2(ex)==ZMAGIC || AOUT_GETMAGIC2(ex)==(QMAGIC|0x10000) ? \
+ 0 : (AOUT_GETMAGIC2(ex)==(ZMAGIC|0x10000) ? __LDPGSZ : \
+ sizeof(struct AOUT_exec)) )
+
+/* Data segment offset. */
+#define AOUT_DATOFF(ex) \
+ AOUT_ALIGN(ex, AOUT_TXTOFF(ex) + (ex)->a_text)
+
+/* Text relocation table offset. */
+#define AOUT_TRELOFF(ex) \
+ (AOUT_DATOFF(ex) + (ex)->a_data)
+
+/* Data relocation table offset. */
+#define AOUT_DRELOFF(ex) \
+ (AOUT_TRELOFF(ex) + (ex)->a_trsize)
+
+/* Symbol table offset. */
+#define AOUT_SYMOFF(ex) \
+ (AOUT_DRELOFF(ex) + (ex)->a_drsize)
+
+/* String table offset. */
+#define AOUT_STROFF(ex) \
+ (AOUT_SYMOFF(ex) + (ex)->a_syms)
+
+
+/* Relocation format. */
+struct relocation_info_i386 {
+ int r_address; /* offset in text or data segment */
+ unsigned int r_symbolnum : 24, /* ordinal number of add symbol */
+ r_pcrel : 1, /* 1 if value should be pc-relative */
+ r_length : 2, /* log base 2 of value's width */
+ r_extern : 1, /* 1 if need to add symbol to value */
+ r_baserel : 1, /* linkage table relative */
+ r_jmptable : 1, /* relocate to jump table */
+ r_relative : 1, /* load address relative */
+ r_copy : 1; /* run time copy */
+};
+#define relocation_info relocation_info_i386
+
+/*
+ * Symbol table entry format. The #ifdef's are so that programs including
+ * nlist.h can initialize nlist structures statically.
+ */
+typedef struct AOUT_nlist {
+ union {
+ char *n_name; /* symbol name (in memory) */
+ long n_strx; /* file string table offset (on disk) */
+ } n_un;
+
+
+#define AOUT_UNDF 0x00 /* undefined */
+#define AOUT_ABS 0x02 /* absolute address */
+#define AOUT_TEXT 0x04 /* text segment */
+#define AOUT_DATA 0x06 /* data segment */
+#define AOUT_BSS 0x08 /* bss segment */
+#define AOUT_INDR 0x0a /* alias definition */
+#define AOUT_SIZE 0x0c /* pseudo type, defines a symbol's size */
+#define AOUT_COMM 0x12 /* common reference */
+#define AOUT_FN 0x1e /* file name (AOUT_EXT on) */
+#define AOUT_WARN 0x1e /* warning message (AOUT_EXT off) */
+
+#define AOUT_EXT 0x01 /* external (global) bit, OR'ed in */
+#define AOUT_TYPE 0x1e /* mask for all the type bits */
+ unsigned char n_type; /* type defines */
+
+ char n_other; /* spare */
+#define n_hash n_desc /* used internally by ld(1); XXX */
+ short n_desc; /* used by stab entries */
+ unsigned long n_value; /* address/value of the symbol */
+} AOUT_nlist;
+
+#define AOUT_FORMAT "%08x" /* namelist value format; XXX */
+#define AOUT_STAB 0x0e0 /* mask for debugger symbols -- stab(5) */
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/loader/aoutloader.c b/xc/programs/Xserver/hw/xfree86/loader/aoutloader.c
new file mode 100644
index 000000000..0b4a08271
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/aoutloader.c
@@ -0,0 +1,857 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/aoutloader.c,v 1.15 1999/03/14 11:18:05 dawes Exp $ */
+
+/*
+ *
+ * Copyright (c) 1997 Matthieu Herrb
+ * Copyright 1995-1998 Metro Link, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. 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.
+ *
+ * Modified 21/02/97 by Sebastien Marineau to support OS/2 a.out objects
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef QNX
+#include <fcntl.h>
+#else
+#include <sys/fcntl.h>
+#endif
+#include <sys/stat.h>
+
+#ifdef DBMALLOC
+#include <debug/malloc.h>
+#define Xalloc(size) malloc(size)
+#define Xcalloc(size) calloc(1,(size))
+#define Xfree(size) free(size)
+#endif
+
+#include "Xos.h"
+#include "os.h"
+#include "aout.h"
+
+#include "sym.h"
+#include "loader.h"
+#include "aoutloader.h"
+
+/*
+#define AOUTDEBUG ErrorF
+*/
+
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+/*
+ * This structure contains all of the information about a module
+ * that has been loaded.
+ */
+
+typedef struct {
+ int handle;
+ int module;
+ int fd;
+ loader_funcs *funcs;
+ AOUTHDR *header;/* file header */
+ unsigned char *text; /* Start address of the text section */
+ unsigned int textsize; /* Size of the text section */
+ unsigned char *data; /* Start address of the data section */
+ unsigned int datasize; /* Size of the data section */
+ unsigned char *bss; /* Start address of the bss data */
+ unsigned int bsssize; /* Size of the bss section */
+ struct relocation_info *txtrel; /* Start address of the text relocation table */
+ struct relocation_info *datarel; /* Start address of the data relocation table */
+ AOUT_nlist *symtab; /* Start address of the symbol table */
+ unsigned char *strings; /* Start address of the string table */
+ unsigned long strsize; /* size of string table */
+ unsigned char *common; /* Start address of the common data */
+ unsigned long comsize; /* size of common data */
+} AOUTModuleRec, *AOUTModulePtr;
+
+/*
+ * If an relocation is unable to be satisfied, then put it on a list
+ * to try later after more modules have been loaded.
+ */
+typedef struct AOUT_RELOC {
+ AOUTModulePtr file;
+ struct relocation_info *rel;
+ int type; /* AOUT_TEXT or AOUT_DATA */
+ struct AOUT_RELOC *next;
+} AOUTRelocRec;
+
+/*
+ * Symbols with a section number of 0 (N_UNDF) but a value of non-zero
+ * need to have space allocated for them.
+ *
+ * Gather all of these symbols together, and allocate one chunk when we
+ * are done.
+ */
+
+typedef struct AOUT_COMMON {
+ struct AOUT_nlist *sym;
+ int index;
+ struct AOUT_COMMON *next;
+} AOUTCommonRec;
+
+static AOUTCommonPtr listCOMMON = NULL;
+
+/* prototypes for static functions */
+static int AOUTHashCleanOut(void *, itemPtr);
+static char *AOUTGetSymbolName(AOUTModulePtr, struct AOUT_nlist *);
+static void *AOUTGetSymbolValue(AOUTModulePtr, int);
+static AOUTCommonPtr AOUTAddCommon(struct AOUT_nlist *, int);
+static LOOKUP *AOUTCreateCommon(AOUTModulePtr);
+static LOOKUP *AOUT_GetSymbols(AOUTModulePtr);
+static AOUTRelocPtr AOUTDelayRelocation(AOUTModulePtr, int, struct relocation_info_i386 *);
+static AOUTRelocPtr AOUTCollectRelocations(AOUTModulePtr);
+static void AOUT_Relocate(unsigned long *, unsigned long, int);
+static AOUTRelocPtr AOUT_RelocateEntry(AOUTModulePtr, int, struct relocation_info_i386 *);
+
+/*
+ * Return 1 if the symbol in item belongs to aoutfile
+ */
+static int
+AOUTHashCleanOut(void *voidptr, itemPtr item)
+{
+ AOUTModulePtr aoutfile = (AOUTModulePtr) voidptr;
+ return (aoutfile->handle == item->handle);
+}
+
+/*
+ * Manage listResolv
+ */
+static AOUTRelocPtr
+AOUTDelayRelocation(AOUTModulePtr aoutfile, int type,
+ struct relocation_info *rel)
+{
+ AOUTRelocPtr reloc;
+
+ if ((reloc = xf86loadermalloc(sizeof(AOUTRelocRec))) == NULL) {
+ ErrorF("AOUTDelayRelocation() Unable to allocate memory\n");
+ return NULL;
+ }
+ if ((unsigned long)rel < 0x200) {
+ ErrorF("bug");
+ }
+ reloc->file = aoutfile;
+ reloc->type = type;
+ reloc->rel = rel;
+ reloc->next = 0;
+ return reloc;
+}
+
+
+
+/*
+ * Manage listCOMMON
+ */
+
+static AOUTCommonPtr
+AOUTAddCommon(struct AOUT_nlist *sym, int index)
+{
+ AOUTCommonPtr common;
+
+ if ((common = xf86loadermalloc(sizeof (AOUTCommonRec))) == NULL) {
+ ErrorF( "AOUTAddCommon() Unable to allocate memory\n" );
+ return 0;
+ }
+ common->sym = sym;
+ common->index = index;
+ common->next = 0;
+ return common;
+}
+
+static LOOKUP *
+AOUTCreateCommon(AOUTModulePtr aoutfile)
+{
+ int numsyms = 0, size = 0, l = 0;
+ int offset = 0;
+ AOUTCommonPtr common;
+ LOOKUP *lookup;
+
+ if (listCOMMON == NULL)
+ return NULL;
+
+ common = listCOMMON;
+ for (common = listCOMMON; common; common = common->next) {
+ /* Ensure long word alignment */
+ if( (common->sym->n_value & (sizeof(long)-1)) != 0 )
+ common->sym->n_value = (common->sym->n_value + (sizeof(long)-1))
+ & ~(sizeof(long)-1);
+
+ /* accumulate the sizes */
+ size += common->sym->n_value;
+ numsyms++;
+ } /* while */
+
+#ifdef AOUTDEBUG
+ AOUTDEBUG("AOUTCreateCommon() %d entries (%d bytes) of COMMON data\n",
+ numsyms, size );
+#endif
+
+ if ((lookup = xf86loadermalloc((numsyms+1)*sizeof(LOOKUP))) == NULL) {
+ ErrorF( "AOUTCreateCommon() Unable to allocate memory\n" );
+ return NULL;
+ }
+
+ aoutfile->comsize = size;
+ if ((aoutfile->common = xf86loadercalloc(1,size)) == NULL) {
+ ErrorF( "AOUTCreateCommon() Unable to allocate memory\n" );
+ return NULL;
+ }
+
+ while (listCOMMON) {
+ common = listCOMMON;
+ lookup[l].symName= AOUTGetSymbolName(aoutfile, common->sym);
+ lookup[l].offset = (funcptr)(aoutfile->common+offset);
+#ifdef AOUTDEBUG
+ AOUTDEBUG("Adding %x %s\n", lookup[l].offset, lookup[l].symName );
+#endif
+ listCOMMON = common->next;
+ offset += common->sym->n_value;
+ xf86loaderfree(common);
+ l++;
+ } /* while */
+ /* listCOMMON == NULL */
+
+ lookup[l].symName=NULL; /* Terminate the list */
+ return lookup;
+}
+
+/*
+ * Symbol Table
+ */
+
+static char *
+AOUTGetString(AOUTModulePtr aoutfile, int index)
+{
+ char *symname = (char *) &(aoutfile->strings[index]);
+
+ if (symname[0] == '_') {
+ symname++;
+ }
+
+ return symname;
+}
+/*
+ * Return the name of a symbol
+ */
+static char *
+AOUTGetSymbolName(AOUTModulePtr aoutfile, struct AOUT_nlist *sym)
+{
+ char *symname = AOUTGetString(aoutfile,sym->n_un.n_strx);
+ char *name;
+
+ name=xf86loadermalloc(strlen(symname)+1);
+ if (!name)
+ FatalError("AOUTGetSymbolName: Out of memory\n");
+
+ strcpy(name,symname);
+
+ return name;
+}
+
+/*
+ * Return the value of a symbol in the loader's symbol table
+ */
+static void *
+AOUTGetSymbolValue(AOUTModulePtr aoutfile, int index)
+{
+ void *symval = NULL; /* value of the indicated symbol */
+ itemPtr symbol = NULL; /* name/value of symbol */
+ char *name = NULL;
+
+ name = AOUTGetSymbolName(aoutfile, aoutfile->symtab + index);
+
+ if( name )
+ symbol = LoaderHashFind(name);
+
+ if (symbol)
+ symval = (unsigned char *)symbol->address;
+
+ xf86loaderfree(name);
+ return symval;
+}
+
+
+/*
+ * Perform the actual relocation
+ */
+static void
+AOUT_Relocate(unsigned long *destl, unsigned long val, int pcrel)
+{
+#ifdef AOUTDEBUG
+ AOUTDEBUG("AOUT_Relocate %p : %08x %s",
+ destl, *destl, pcrel == 1 ? "rel" : "abs");
+
+#endif
+ if (pcrel) {
+ /* relative to PC */
+ *destl = val - ((unsigned long)destl + sizeof(long));
+ } else {
+ *destl += val;
+ }
+#ifdef AOUTDEBUG
+ AOUTDEBUG(" -> %08x\n", *destl);
+#endif
+}
+
+
+/*
+ * Fix the relocation for text or data section
+ */
+static AOUTRelocPtr
+AOUT_RelocateEntry(AOUTModulePtr aoutfile, int type,
+ struct relocation_info *rel)
+{
+ AOUTHDR *header = aoutfile->header;
+ AOUT_nlist *symtab = aoutfile->symtab;
+ int symnum;
+ void *symval;
+ unsigned long *destl; /* address of the location to be modified */
+
+ symnum = rel->r_symbolnum;
+#ifdef AOUTDEBUG
+ {
+ char *name;
+ if (rel->r_extern) {
+ AOUTDEBUG("AOUT_RelocateEntry: extern %s\n",
+ name=AOUTGetSymbolName(aoutfile, symtab+symnum));
+ xf86loaderfree(name);
+ } else {
+ AOUTDEBUG("AOUT_RelocateEntry: intern\n");
+ }
+ AOUTDEBUG(" pcrel: %d", rel->r_pcrel);
+ AOUTDEBUG(" length: %d", rel->r_length);
+ AOUTDEBUG(" baserel: %d", rel->r_baserel);
+ AOUTDEBUG(" jmptable: %d", rel->r_jmptable);
+ AOUTDEBUG(" relative: %d", rel->r_relative);
+ AOUTDEBUG(" copy: %d\n", rel->r_copy);
+ }
+#endif /* AOUTDEBUG */
+
+ if (rel->r_length != 2) {
+ ErrorF("AOUT_ReloateEntry: length != 2\n");
+ }
+ /*
+ * First find the address to modify
+ */
+ switch (type) {
+ case AOUT_TEXT:
+ /* Check that the relocation offset is in the text segment */
+ if (rel->r_address > header->a_text) {
+ ErrorF("AOUT_RelocateEntry(): "
+ "text relocation out of text section\n");
+ }
+ destl = (unsigned long *)(aoutfile->text + rel->r_address);
+ break;
+ case AOUT_DATA:
+ /* Check that the relocation offset is in the data segment */
+ if (rel->r_address > header->a_data) {
+ ErrorF("AOUT_RelocateEntry():"
+ "data relocation out of data section\n");
+ }
+ destl = (unsigned long *)(aoutfile->data + rel->r_address);
+ break;
+ default:
+ ErrorF("AOUT_RelocateEntry(): unknown section type %d\n", type);
+ return 0;
+ } /* switch */
+
+ /*
+ * Now handle the relocation
+ */
+ if (rel->r_extern) {
+ /* Lookup the symbol in the loader's symbol table */
+ symval = AOUTGetSymbolValue(aoutfile, symnum);
+ if (symval != 0) {
+ /* we've got the value */
+ AOUT_Relocate(destl, (unsigned long) symval, rel->r_pcrel);
+ return 0;
+ } else {
+ /* The symbol should be undefined */
+ switch (symtab[symnum].n_type & AOUT_TYPE) {
+ case AOUT_UNDF:
+#ifdef AOUTDEBUG
+ AOUTDEBUG(" extern AOUT_UNDEF\n");
+#endif
+ /* Add this relocation back to the global list */
+ return AOUTDelayRelocation(aoutfile,type,rel);
+
+ default:
+ ErrorF("AOUT_RelocateEntry():"
+ " impossible intern relocation type: %d\n",
+ symtab[symnum].n_type);
+ return 0;
+ } /* switch */
+ }
+ } else {
+ /* intern */
+ switch (rel->r_symbolnum) {
+ case AOUT_TEXT:
+#ifdef AOUTDEBUG
+ AOUTDEBUG(" AOUT_TEXT\n");
+#endif
+ /* Only absolute intern text relocations need to be handled */
+ if (rel->r_pcrel == 0)
+ AOUT_Relocate(destl, (unsigned long)aoutfile->text,
+ rel->r_pcrel);
+ return 0;
+ case AOUT_DATA:
+#ifdef AOUTDEBUG
+ AOUTDEBUG(" AOUT_DATA\n");
+#endif
+ if (rel->r_pcrel == 0)
+ AOUT_Relocate(destl, (unsigned long)aoutfile->data
+ - header->a_text, rel->r_pcrel);
+ else
+ ErrorF("AOUT_RelocateEntry(): "
+ "don't know how to handle data pc-relative reloc\n");
+
+ return 0;
+ case AOUT_BSS:
+#ifdef AOUTDEBUG
+ AOUTDEBUG(" AOUT_BSS\n");
+#endif
+ if (rel->r_pcrel == 0)
+ AOUT_Relocate(destl, (unsigned long)aoutfile->bss
+ - header->a_text - header->a_data,
+ rel->r_pcrel);
+ else
+ ErrorF("AOUT_RelocateEntry(): "
+ "don't know how to handle bss pc-relative reloc\n");
+
+ return 0;
+ default:
+ ErrorF("AOUT_RelocateEntry():"
+ " unknown intern relocation type: %d\n", rel->r_symbolnum);
+ return 0;
+ } /* switch */
+ }
+} /* AOUT_RelocateEntry */
+
+static AOUTRelocPtr
+AOUTCollectRelocations(AOUTModulePtr aoutfile)
+{
+ AOUTHDR *header = aoutfile->header;
+ int i, nreloc;
+ struct relocation_info *rel;
+ AOUTRelocPtr reloc_head = NULL;
+ AOUTRelocPtr tmp;
+
+ /* Text relocations */
+ if (aoutfile->text != NULL && aoutfile->txtrel != NULL) {
+ nreloc = header->a_trsize/sizeof(struct relocation_info);
+
+ for (i = 0; i < nreloc; i++) {
+ rel = aoutfile->txtrel + i;
+ tmp = AOUTDelayRelocation(aoutfile, AOUT_TEXT, rel);
+ if (tmp) {
+ tmp->next = reloc_head;
+ reloc_head = tmp;
+ }
+ } /* for */
+ }
+ /* Data relocations */
+ if (aoutfile->data != NULL && aoutfile->datarel != NULL) {
+ nreloc = header->a_drsize/sizeof(struct relocation_info);
+
+ for (i = 0; i < nreloc; i++) {
+ rel = aoutfile->datarel + i;
+ tmp = AOUTDelayRelocation(aoutfile, AOUT_DATA, rel);
+ tmp->next = reloc_head;
+ reloc_head = tmp;
+ } /* for */
+ }
+ return reloc_head;
+} /* AOUTCollectRelocations */
+
+/*
+ * AOUT_GetSymbols()
+ *
+ * add the symbols to the loader's symbol table
+ */
+static LOOKUP *
+AOUT_GetSymbols(AOUTModulePtr aoutfile)
+{
+ int fd = aoutfile->fd;
+ AOUTHDR *header = aoutfile->header;
+ int nsyms, soff, i, l;
+ char *symname;
+ AOUT_nlist *s;
+ LOOKUP *lookup, *lookup_common;
+ AOUTCommonPtr tmp;
+
+ aoutfile->symtab = (AOUT_nlist *)_LoaderFileToMem(fd,
+ AOUT_SYMOFF(header),
+ header->a_syms,
+ "symbols");
+ nsyms = header->a_syms/sizeof(AOUT_nlist);
+ lookup = xf86loadermalloc(nsyms * sizeof(LOOKUP));
+ if (lookup == NULL) {
+ ErrorF("AOUT_GetSymbols(): can't allocate memory\n");
+ return NULL;
+ }
+ for (i = 0, l = 0; i < nsyms; i++) {
+ s = aoutfile->symtab + i;
+ soff=s->n_un.n_strx;
+ if (soff == 0 || (s->n_type & AOUT_STAB) != 0)
+ continue;
+ symname=AOUTGetSymbolName(aoutfile,s);
+#ifdef AOUTDEBUG
+ AOUTDEBUG("AOUT_GetSymbols(): %s %02x %02x %08x\n",
+ symname, s->n_type,
+ s->n_other, s->n_value);
+#endif
+ switch (s->n_type & AOUT_TYPE) {
+ case AOUT_UNDF:
+ if (s->n_value != 0) {
+ if (!LoaderHashFind(symname)) {
+#ifdef AOUTDEBUG
+ AOUTDEBUG("Adding common %s\n", symname);
+#endif
+ tmp = AOUTAddCommon(s, i);
+ if (tmp) {
+ tmp->next = listCOMMON;
+ listCOMMON = tmp;
+ }
+ }
+ } else {
+#ifdef AOUTDEBUG
+ AOUTDEBUG("Adding undef %s\n", symname);
+#endif
+ }
+ xf86loaderfree(symname);
+ break;
+ case AOUT_TEXT:
+ if (s->n_type & AOUT_EXT) {
+ lookup[l].symName = symname;
+ /* text symbols start at 0 */
+ lookup[l].offset = (funcptr)(aoutfile->text + s->n_value);
+#ifdef AOUTDEBUG
+ AOUTDEBUG("Adding text %s %08x\n", symname, lookup[l].offset);
+#endif
+ l++;
+ } else {
+ xf86loaderfree(symname);
+ }
+ break;
+ case AOUT_DATA :
+ if (s->n_type & AOUT_EXT) {
+ lookup[l].symName = symname;
+ /* data symbols are following text */
+ lookup[l].offset = (funcptr)(aoutfile->data +
+ s->n_value - header->a_text);
+#ifdef AOUTDEBUG
+ AOUTDEBUG("Adding data %s %08x\n", symname, lookup[l].offset);
+#endif
+ l++;
+ } else {
+ xf86loaderfree(symname);
+ }
+ break;
+ case AOUT_BSS:
+ if (s->n_type & AOUT_EXT) {
+ lookup[l].symName = symname;
+ /* bss symbols follow both text and data */
+ lookup[l].offset = (funcptr)(aoutfile->bss + s->n_value
+ - (header->a_data
+ + header->a_text));
+#ifdef AOUTDEBUG
+ AOUTDEBUG("Adding bss %s %08x\n", symname, lookup[l].offset);
+#endif
+ l++;
+ } else {
+ xf86loaderfree(symname);
+ }
+ break;
+ case AOUT_FN:
+#ifdef AOUTDEBUG
+ if (n->n_type& AOUT_EXT) {
+ AOUTDEBUG("Ignoring AOUT_FN %s\n", symname);
+ } else {
+ AOUTDEBUG("Ignoring AOUT_WARN %s\n", symname);
+ }
+#endif
+ xf86loaderfree(symname);
+ break;
+ default:
+ ErrorF("Unknown symbol type %x\n", s->n_type & AOUT_TYPE);
+ xf86loaderfree(symname);
+ } /* switch */
+ } /* for */
+ lookup[l].symName = NULL;
+
+ lookup_common = AOUTCreateCommon(aoutfile);
+ if (lookup_common) {
+ LOOKUP *p;
+
+ for (i = 0, p = lookup_common; p->symName; i++, p++)
+ ;
+ memcpy(&(lookup[l]), lookup_common, i * sizeof (LOOKUP));
+
+ xf86loaderfree(lookup_common);
+ l += i;
+ lookup[l].symName = NULL;
+ }
+ return lookup;
+} /* AOUT_GetSymbols */
+
+/*
+ * Public API for the a.out implementation of the loader
+ */
+void *
+AOUTLoadModule(loaderPtr modrec,
+ int aoutfd,
+ LOOKUP **ppLookup)
+{
+ AOUTModulePtr aoutfile = NULL;
+ AOUTHDR *header;
+ AOUTRelocPtr reloc, tail;
+ void *v;
+
+#ifdef AOUTDEBUG
+ AOUTDEBUG("AOUTLoadModule(%s, %d, %d)\n",
+ modrec->name, modrec->handle, aoutfd);
+#endif
+ if ((aoutfile=xf86loadercalloc(1,sizeof(AOUTModuleRec))) == NULL ) {
+ ErrorF( "Unable to allocate AOUTModuleRec\n" );
+ return NULL;
+ }
+
+ aoutfile->handle=modrec->handle;
+ aoutfile->module=modrec->module;
+ aoutfile->fd=aoutfd;
+ v=aoutfile->funcs=modrec->funcs;
+
+ /*
+ * Get the a.out header
+ */
+ aoutfile->header=(AOUTHDR *)_LoaderFileToMem(aoutfd,0,sizeof(AOUTHDR),
+ "header");
+ header= (AOUTHDR *)aoutfile->header;
+
+ /*
+ * Load the 6 other sections
+ */
+ /* text */
+ if (header->a_text != 0) {
+ aoutfile->text = _LoaderFileToMem(aoutfile->fd,
+ AOUT_TXTOFF(header),
+ header->a_text, "text");
+ aoutfile->textsize = header->a_text;
+ } else {
+ aoutfile->text = NULL;
+ }
+ /* data */
+ if (header->a_data != 0) {
+ aoutfile->data = _LoaderFileToMem(aoutfile->fd,
+ AOUT_DATOFF(header),
+ header->a_data, "data");
+ aoutfile->datasize = header->a_data;
+ } else {
+ aoutfile->data = NULL;
+ }
+ /* bss */
+ if (header->a_bss != 0) {
+ aoutfile->bss = xf86loadercalloc(1, header->a_bss);
+ aoutfile->bsssize = header->a_bss;
+ } else {
+ aoutfile->bss = NULL;
+ }
+ /* Text Relocations */
+ if (header->a_trsize != 0) {
+ aoutfile->txtrel = _LoaderFileToMem(aoutfile->fd,
+ AOUT_TRELOFF(header),
+ header->a_trsize, "txtrel");
+ } else {
+ aoutfile->txtrel = NULL;
+ }
+ /* Data Relocations */
+ if (header->a_drsize != 0) {
+ aoutfile->datarel = _LoaderFileToMem(aoutfile->fd,
+ AOUT_DRELOFF(header),
+ header->a_drsize, "datarel");
+ } else {
+ aoutfile->datarel = NULL;
+ }
+ /* String table */
+ _LoaderFileRead(aoutfile->fd, AOUT_STROFF(header),
+ &(aoutfile->strsize), sizeof(int));
+ if (aoutfile->strsize != 0) {
+ aoutfile->strings = _LoaderFileToMem(aoutfile->fd,
+ AOUT_STROFF(header),
+ aoutfile->strsize, "strings");
+ } else {
+ aoutfile->strings = NULL;
+ }
+ /* load symbol table */
+ *ppLookup = AOUT_GetSymbols(aoutfile);
+
+ /* Do relocations */
+ reloc = AOUTCollectRelocations(aoutfile);
+
+ if (reloc) {
+ for (tail = reloc; tail->next; tail = tail->next)
+ ;
+ tail->next = _LoaderGetRelocations(v)->aout_reloc;
+ _LoaderGetRelocations(v)->aout_reloc = reloc;
+ }
+
+ return (void *)aoutfile;
+}
+
+void
+AOUTResolveSymbols(mod)
+void *mod;
+{
+ AOUTRelocPtr newlist, p, tmp;
+
+#ifdef AOUTDEBUG
+ AOUTDEBUG("AOUTResolveSymbols()\n");
+#endif
+
+ newlist = 0;
+ for (p = _LoaderGetRelocations(mod)->aout_reloc; p; ) {
+ tmp = AOUT_RelocateEntry(p->file, p->type, p->rel);
+ if (tmp) {
+ /* Failed to relocate. Keep it in the list. */
+ tmp->next = newlist;
+ newlist = tmp;
+ }
+ tmp = p;
+ p = p->next;
+ xf86loaderfree(tmp);
+ }
+ _LoaderGetRelocations(mod)->aout_reloc = newlist;
+} /* AOUTResolveSymbols */
+
+int
+AOUTCheckForUnresolved(mod)
+void *mod;
+{
+ int symnum;
+ AOUTRelocPtr crel;
+ char *name;
+ int fatalsym = 0, flag;
+
+#ifdef AOUTDEBUG
+ AOUTDEBUG("AOUTCheckForUnResolved()\n");
+#endif
+ if ((crel = _LoaderGetRelocations(mod)->aout_reloc) == NULL)
+ return 0;
+
+ while (crel) {
+ if (crel->type == AOUT_TEXT) {
+ /* Attempt to make unresolved text references
+ point to a default function */
+ AOUT_Relocate((unsigned long *)(crel->file->text
+ + crel->rel->r_address) ,
+ (unsigned long)LoaderDefaultFunc,
+ crel->rel->r_pcrel);
+ }
+ symnum = crel->rel->r_symbolnum;
+ name=AOUTGetSymbolName(crel->file, crel->file->symtab + symnum);
+ flag = _LoaderHandleUnresolved(name,
+ _LoaderHandleToName(crel->file->handle));
+ xf86loaderfree(name);
+ if (flag) fatalsym = 1;
+ crel = crel->next;
+ }
+ return fatalsym;
+}
+
+void
+AOUTUnloadModule(void *modptr)
+{
+ AOUTModulePtr aoutfile = (AOUTModulePtr)modptr;
+ AOUTRelocPtr relptr, *prevptr;
+#ifdef AOUTDEBUG
+ AOUTDEBUG("AOUTUnLoadModule(0x%p)\n", modptr);
+#endif
+
+/*
+ * Delete any unresolved relocations
+ */
+
+ relptr=_LoaderGetRelocations(aoutfile->funcs)->aout_reloc;
+ prevptr=&(_LoaderGetRelocations(aoutfile->funcs)->aout_reloc);
+
+ while (relptr) {
+ if (relptr->file == aoutfile) {
+ *prevptr = relptr->next;
+ xf86loaderfree(relptr);
+ relptr = *prevptr;
+ } else {
+ prevptr = &(relptr->next);
+ relptr = relptr->next;
+ }
+ } /* while */
+
+ /* clean the symbols table */
+ LoaderHashTraverse((void *)aoutfile, AOUTHashCleanOut);
+
+#define CheckandFree(ptr,size) if(ptr) _LoaderFreeFileMem((ptr),(size))
+
+ CheckandFree(aoutfile->strings,aoutfile->strsize);
+ CheckandFree(aoutfile->symtab,aoutfile->header->a_syms);
+ CheckandFree(aoutfile->datarel,aoutfile->header->a_drsize);
+ CheckandFree(aoutfile->txtrel,aoutfile->header->a_trsize);
+ CheckandFree(aoutfile->data,aoutfile->header->a_data);
+ CheckandFree(aoutfile->text,aoutfile->header->a_text);
+ /* Free allocated sections */
+ if (aoutfile->bss != NULL) {
+ xf86loaderfree(aoutfile->bss);
+ }
+ if (aoutfile->common != NULL) {
+ xf86loaderfree(aoutfile->common);
+ }
+
+ /* Free header */
+ _LoaderFreeFileMem(aoutfile->header, sizeof(AOUTHDR));
+
+ /* Free the module structure itself */
+ xf86loaderfree(aoutfile);
+
+ return;
+}
+
+char *
+AOUTAddressToSection(void *modptr, unsigned long address)
+{
+ AOUTModulePtr aoutfile = (AOUTModulePtr)modptr;
+
+ if( address >= (unsigned long)aoutfile->text &&
+ address <= (unsigned long)aoutfile->text+aoutfile->textsize ) {
+ return "text";
+ }
+ if( address >= (unsigned long)aoutfile->data &&
+ address <= (unsigned long)aoutfile->data+aoutfile->datasize ) {
+ return "data";
+ }
+ if( address >= (unsigned long)aoutfile->bss &&
+ address <= (unsigned long)aoutfile->bss+aoutfile->bsssize ) {
+ return "bss";
+ }
+
+ return NULL;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/loader/aoutloader.h b/xc/programs/Xserver/hw/xfree86/loader/aoutloader.h
new file mode 100644
index 000000000..2714b140f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/aoutloader.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 1997,1998 Metro Link, Inc.
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/aoutloader.h,v 1.3 1998/09/20 14:41:03 dawes Exp $ */
+
+#ifndef _AOUTLOADER_H
+#define _AOUTLOADER_H
+extern void *AOUTLoadModule(loaderPtr, int, LOOKUP **);
+extern void AOUTResolveSymbols(void *);
+extern int AOUTCheckForUnresolved(void *);
+extern char *AOUTAddressToSection(void *,unsigned long);
+extern void AOUTUnloadModule(void *);
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/loader/ar.h b/xc/programs/Xserver/hw/xfree86/loader/ar.h
new file mode 100644
index 000000000..4dbc97901
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/ar.h
@@ -0,0 +1,77 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/ar.h,v 1.3 1998/07/25 16:56:12 dawes Exp $ */
+
+
+#ifndef _AR_H
+#define _AR_H
+
+#define ARMAG "!<arch>\n"
+#define SARMAG 8
+#define ARFMAG "`\n"
+
+#if !(defined(__powerpc__) && defined(Lynx))
+struct ar_hdr {
+ char ar_name[16],
+ ar_date[12],
+ ar_uid[6],
+ ar_gid[6],
+ ar_mode[8],
+ ar_size[10],
+ ar_fmag[2];
+};
+
+#else
+
+#define AIAMAG "<aiaff>\n"
+#define SAIAMAG 8
+#define AIAFMAG "`\n"
+
+struct fl_hdr /* archive fixed length header - printable ascii */
+{
+ char fl_magic[SAIAMAG]; /* Archive file magic string */
+ char fl_memoff[12]; /* Offset to member table */
+ char fl_gstoff[12]; /* Offset to global symbol table */
+ char fl_fstmoff[12]; /* Offset to first archive member */
+ char fl_lstmoff[12]; /* Offset to last archive member */
+ char fl_freeoff[12]; /* Offset to first mem on free list */
+};
+
+#define FL_HDR struct fl_hdr
+#define FL_HSZ sizeof(FL_HDR)
+
+
+struct ar_hdr /* archive file member header - printable ascii */
+{
+ char ar_size[12]; /* file member size - decimal */
+ char ar_nxtmem[12]; /* pointer to next member - decimal */
+ char ar_prvmem[12]; /* pointer to previous member - decimal */
+ char ar_date[12]; /* file member date - decimal */
+ char ar_uid[12]; /* file member user id - decimal */
+ char ar_gid[12]; /* file member group id - decimal */
+ char ar_mode[12]; /* file member mode - octal */
+ char ar_namlen[4]; /* file member name length - decimal */
+ union
+ {
+ char an_name[2]; /* variable length member name */
+ char an_fmag[2]; /* AIAFMAG - string to end header */
+ } _ar_name; /* and variable length name */
+};
+
+#define ar_name _ar_name.an_name
+
+/*
+ * Note: 'ar_namlen' contains the length of the member name which
+ * may be up to 255 chars. The character string containing
+ * the name begins at '_ar_name.ar_name'. The terminating
+ * string AIAFMAG, is only cosmetic. File member contents begin
+ * at the first even byte boundary past 'header position +
+ * sizeof(struct ar_hdr) + ar_namlen', and continue for
+ * 'ar_size' bytes.
+*/
+
+#define AR_HDR struct ar_hdr
+#define AR_HSZ sizeof(AR_HDR)
+
+#endif /* !__powerpc__ && Lynx */
+
+#endif /* _AR_H */
+
diff --git a/xc/programs/Xserver/hw/xfree86/loader/coff.h b/xc/programs/Xserver/hw/xfree86/loader/coff.h
new file mode 100644
index 000000000..cebf5e179
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/coff.h
@@ -0,0 +1,244 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/coff.h,v 1.5 1998/07/25 16:56:12 dawes Exp $ */
+
+
+/* This file was implemented from the information in the book
+ Understanding and Using COFF
+ Gintaras R. Gircys
+ O'Reilly, 1988
+ and by looking at the Linux kernel code.
+
+ It is therefore most likely free to use...
+
+ If the file format changes in the COFF object, this file should be
+ subsequently updated to reflect the changes.
+
+ The actual loader module only uses a few of the COFF structures.
+ Only those are included here. If you wish more information about
+ COFF, thein check out the book mentioned above.
+*/
+
+#ifndef _COFF_H
+#define _COFF_H
+
+#define E_SYMNMLEN 8 /* Number of characters in a symbol name */
+/*
+ * Intel 386/486
+ */
+
+/*
+ * FILE HEADER
+ */
+
+typedef struct COFF_filehdr
+{
+ unsigned short f_magic; /* magic number */
+ unsigned short f_nscns; /* number of sections */
+ long f_timdat; /* time & date stamp */
+ long f_symptr; /* file pointer to symtab */
+ long f_nsyms; /* number of symtab entries */
+ unsigned short f_opthdr; /* sizeof(optional hdr) */
+ unsigned short f_flags; /* flags */
+} FILHDR;
+
+#define FILHSZ sizeof(FILHDR)
+
+/*
+ * SECTION HEADER
+ */
+
+typedef struct COFF_scnhdr
+{
+ char s_name[8]; /* section name */
+ long s_paddr; /* physical address */
+ long s_vaddr; /* virtual address */
+ long s_size; /* section size */
+ long s_scnptr; /* raw data for section */
+ long s_relptr; /* relocation */
+ long s_lnnoptr; /* line numbers */
+ unsigned short s_nreloc; /* number of relocation entries */
+ unsigned short s_nlnno; /* number of line number entries*/
+ long s_flags; /* flags */
+} SCNHDR;
+
+#define COFF_SCNHDR struct COFF_scnhdr
+#define COFF_SCNHSZ sizeof(COFF_SCNHDR)
+#define SCNHSZ COFF_SCNHSZ
+
+/*
+ * the optional COFF header as used by Linux COFF
+ */
+
+typedef struct
+{
+ char magic[2]; /* type of file */
+ char vstamp[2]; /* version stamp */
+ char tsize[4]; /* text size in bytes */
+ char dsize[4]; /* initialized data */
+ char bsize[4]; /* uninitialized data */
+ char entry[4]; /* entry point */
+ char text_start[4]; /* base of text */
+ char data_start[4]; /* base of data */
+} AOUTHDR;
+
+
+/*
+ * SYMBOLS
+ */
+
+typedef struct COFF_syment
+{
+ union
+ {
+ char _n_name[E_SYMNMLEN]; /* Symbol name (first 8 chars) */
+ struct
+ {
+ long _n_zeroes; /* Leading zeros */
+ long _n_offset; /* Offset for a header section */
+ } _n_n;
+ char *_n_nptr[2]; /* allows for overlaying */
+ } _n;
+
+ long n_value; /* address of the segment */
+ short n_scnum; /* Section number */
+ unsigned short n_type; /* Type of section */
+ char n_sclass; /* Loader class */
+ char n_numaux; /* Number of aux entries following */
+} SYMENT;
+
+#define n_name _n._n_name
+#define n_nptr _n._n_nptr[1]
+#define n_zeroes _n._n_n._n_zeroes
+#define n_offset _n._n_n._n_offset
+
+#define COFF_E_SYMNMLEN 8 /* characters in a short symbol name */
+#define COFF_E_FILNMLEN 14 /* characters in a file name */
+#define COFF_E_DIMNUM 4 /* array dimensions in aux entry */
+#define SYMNMLEN COFF_E_SYMNMLEN
+#define SYMESZ 18 /* not really sizeof(SYMENT) due to padding */
+
+/* Special section number found in the symbol section */
+#define N_UNDEF 0
+#define N_ABS -1
+#define N_DEBUG -2
+
+/* Symbol storage class values */
+#define C_NULL 0
+#define C_EXT 2
+#define C_FILE 103
+#define C_HIDEXT 107
+
+/*
+ * AUX Entries
+ */
+typedef struct COFF_auxent {
+ long x_scnlen;
+ long x_parmhash;
+ unsigned short x_snhash;
+ unsigned char x_smtyp;
+ unsigned char x_smclas;
+ long x_stab;
+ unsigned short x_snstab;
+} AUXENT;
+
+/* Auxillary Symbol type values */
+#define XTY_ER 0 /* Enternal Reference */
+#define XTY_SD 1 /* csect section definition */
+#define XTY_LD 2 /* Label definition */
+#define XTY_CM 3 /* common csect definition */
+
+/* Auxillary Symbol storage mapping class values */
+#define XMC_PR 0 /* Program code */
+#define XMC_RO 1 /* Read-only constant */
+#define XMC_DB 2 /* Debug dictionary */
+#define XMC_TC 3 /* TOC entry */
+#define XMC_UA 4 /* Unclassified */
+#define XMC_RW 5 /* Read/write data */
+#define XMC_GL 6 /* Global linkage */
+#define XMC_XO 7 /* Extended operation */
+#define XMC_SV 8 /* Supervisor call descriptor */
+#define XMC_BS 9 /* BSS class */
+#define XMC_DS 10 /* Function descriptor csect */
+#define XMC_UC 11 /* Unnamed FORTRAN comon */
+#define XMC_TI 12 /* Reserved */
+#define XMC_TB 13 /* Reserved */
+#define XMC_TC0 15 /* TOC anchor */
+#define XMC_TD 16 /* Scalar data entry in TOC */
+
+/*
+ * RELOCATION DIRECTIVES
+ */
+
+typedef struct COFF_reloc
+{
+ long r_vaddr; /* Virtual address of item */
+ long r_symndx; /* Symbol index in the symtab */
+#if defined(__powerpc__)
+ union
+ {
+ unsigned short _r_type; /* old style coff relocation type */
+ struct
+ {
+ char _r_rsize; /* sign and reloc bit len */
+ char _r_rtype; /* toc relocation type */
+ } _r_r;
+ } _r;
+#define r_otype _r._r_type /* old style reloc - original name */
+#define r_rsize _r._r_r._r_rsize /* extract sign and bit len */
+#define r_type _r._r_r._r_rtype /* extract toc relocation type */
+#else
+ unsigned short r_type; /* Relocation type */
+#endif
+} RELOC;
+
+#define COFF_RELOC struct COFF_reloc
+#define COFF_RELSZ 10
+#define RELSZ COFF_RELSZ
+
+/*
+ * x86 Relocation types
+ */
+#define R_ABS 000
+#define R_DIR32 006
+#define R_PCRLONG 024
+
+#if defined(__powerpc__)
+/*
+ * Power PC
+ */
+#define R_LEN 0x1F /* extract bit-length field */
+#define R_SIGN 0x80 /* extract sign of relocation */
+#define R_FIXUP 0x40 /* extract code-fixup bit */
+
+#define RELOC_RLEN(x) ((x)._r._r_r._r_rsize & R_LEN)
+#define RELOC_RSIGN(x) ((x)._r._r_r._r_rsize & R_SIGN)
+#define RELOC_RFIXUP(x) ((x)._r._r_r._r_rsize & R_FIXUP)
+#define RELOC_RTYPE(x) ((x)._r._r_r._r_rtype)
+
+/*
+ * POWER and PowerPC - relocation types
+ */
+#define R_POS 0x00 /* A(sym) Positive Relocation */
+#define R_NEG 0x01 /* -A(sym) Negative Relocation */
+#define R_REL 0x02 /* A(sym-*) Relative to self */
+#define R_TOC 0x03 /* A(sym-TOC) Relative to TOC */
+#define R_TRL 0x12 /* A(sym-TOC) TOC Relative indirect load. */
+ /* modifiable instruction */
+#define R_TRLA 0x13 /* A(sym-TOC) TOC Rel load address. modifiable inst */
+#define R_GL 0x05 /* A(external TOC of sym) Global Linkage */
+#define R_TCL 0x06 /* A(local TOC of sym) Local object TOC address */
+#define R_RL 0x0C /* A(sym) Pos indirect load. modifiable instruction */
+#define R_RLA 0x0D /* A(sym) Pos Load Address. modifiable instruction */
+#define R_REF 0x0F /* AL0(sym) Non relocating ref. No garbage collect */
+#define R_BA 0x08 /* A(sym) Branch absolute. Cannot modify instruction */
+#define R_RBA 0x18 /* A(sym) Branch absolute. modifiable instruction */
+#define R_RBAC 0x19 /* A(sym) Branch absolute constant. modifiable instr */
+#define R_BR 0x0A /* A(sym-*) Branch rel to self. non modifiable */
+#define R_RBR 0x1A /* A(sym-*) Branch rel to self. modifiable instr */
+#define R_RBRC 0x1B /* A(sym-*) Branch absolute const. */
+ /* modifiable to R_RBR */
+#define R_RTB 0x04 /* A((sym-*)/2) RT IAR Rel Branch. non modifiable */
+#define R_RRTBI 0x14 /* A((sym-*)/2) RT IAR Rel Br. modifiable to R_RRTBA */
+#define R_RRTBA 0x15 /* A((sym-*)/2) RT absolute br. modifiable to R_RRTBI */
+#endif /* __powerpc */
+
+#endif /* _COFF_H */
diff --git a/xc/programs/Xserver/hw/xfree86/loader/coffloader.c b/xc/programs/Xserver/hw/xfree86/loader/coffloader.c
new file mode 100644
index 000000000..64fdee4a2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/coffloader.c
@@ -0,0 +1,1361 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/coffloader.c,v 1.11 1999/03/14 11:18:05 dawes Exp $ */
+
+/*
+ *
+ * Copyright 1995,96 by Metro Link, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. 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 <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#ifdef QNX
+#include <fcntl.h>
+#else
+#include <sys/fcntl.h>
+#endif
+#include <sys/stat.h>
+
+#ifdef DBMALLOC
+#include <debug/malloc.h>
+#define Xalloc(size) malloc(size)
+#define Xcalloc(size) calloc(1,(size))
+#define Xfree(size) free(size)
+#endif
+
+#include "Xos.h"
+#include "os.h"
+#include "coff.h"
+
+#include "sym.h"
+#include "loader.h"
+#include "coffloader.h"
+
+/*
+#ifndef LDTEST
+#define COFFDEBUG ErrorF
+#endif
+*/
+
+/*
+ * This structure contains all of the information about a module
+ * that has been loaded.
+ */
+
+typedef struct {
+ int handle;
+ long module; /* Id of the module used to find inter module calls */
+ int fd;
+ loader_funcs *funcs;
+ FILHDR *header; /* file header */
+ AOUTHDR *optheader; /* optional file header */
+ unsigned short numsh;
+ SCNHDR *sections; /* Start address of the section table */
+ int secsize; /* size of the section table */
+ unsigned char **saddr;/* Start addresss of the sections table */
+ unsigned char **reladdr;/* Start addresss of the relocation table */
+ unsigned char *strtab; /* Start address of the string table */
+ int strsize; /* size of the string table */
+ unsigned char *text; /* Start address of the .text section */
+ int txtndx; /* index of the .text section */
+ long txtaddr; /* offset of the .text section */
+ int txtsize; /* size of the .text section */
+ int txtrelsize; /* size of the .rel.text section */
+ unsigned char *data; /* Start address of the .data section */
+ int datndx; /* index of the .data section */
+ long dataddr; /* offset of the .data section */
+ int datsize; /* size of the .data section */
+ int datrelsize; /* size of the .rel.data section */
+ unsigned char *bss; /* Start address of the .bss section */
+ int bssndx; /* index of the .bss section */
+ long bssaddr; /* offset of the .bss section */
+ int bsssize; /* size of the .bss section */
+ SYMENT *symtab; /* Start address of the .symtab section */
+ int symndx; /* index of the .symtab section */
+ int symsize; /* size of the .symtab section */
+ unsigned char *common; /* Start address of the .common section */
+ int comsize; /* size of the .common section */
+ long toc; /* Offset of the TOC csect */
+ unsigned char *tocaddr; /* Address of the TOC csect */
+ } COFFModuleRec, *COFFModulePtr;
+
+/*
+ * If any relocation is unable to be satisfied, then put it on a list
+ * to try later after more modules have been loaded.
+ */
+typedef struct _coff_reloc {
+ COFFModulePtr file;
+ RELOC *rel;
+ int secndx;
+ struct _coff_reloc *next;
+} COFFRelocRec;
+
+/*
+ * Symbols with a section number of 0 (N_UNDEF) but a value of non-zero
+ * need to have space allocated for them.
+ *
+ * Gather all of these symbols together, and allocate one chunk when we
+ * are done.
+ */
+
+typedef struct _coff_COMMON {
+ SYMENT *sym;
+ int index;
+ struct _coff_COMMON *next;
+ } COFFCommonRec;
+
+static COFFCommonPtr listCOMMON = NULL;
+
+/* Prototypes for static functions */
+static int COFFhashCleanOut(void *, itemPtr);
+static char *COFFGetSymbolName(COFFModulePtr, int);
+static COFFCommonPtr COFFAddCOMMON(SYMENT *, int);
+static LOOKUP *COFFCreateCOMMON(COFFModulePtr);
+static COFFRelocPtr COFFDelayRelocation(COFFModulePtr, int, RELOC *);
+static SYMENT *COFFGetSymbol(COFFModulePtr, int);
+static unsigned char *COFFGetSymbolValue(COFFModulePtr, int);
+static COFFRelocPtr COFF_RelocateEntry(COFFModulePtr, int, RELOC *);
+static LOOKUP *COFF_GetSymbols(COFFModulePtr);
+static void COFFCollectSections(COFFModulePtr);
+static COFFRelocPtr COFFCollectRelocations(COFFModulePtr);
+
+/*
+ * Utility Functions
+ */
+
+
+static int
+COFFhashCleanOut(voidptr, item)
+void *voidptr;
+itemPtr item ;
+{
+ COFFModulePtr module = (COFFModulePtr) voidptr;
+ return ( module->handle == item->handle ) ;
+}
+
+
+/*
+ * Manage listResolv
+ */
+static COFFRelocPtr
+COFFDelayRelocation(cofffile,secndx,rel)
+COFFModulePtr cofffile;
+int secndx;
+RELOC *rel;
+{
+ COFFRelocPtr reloc;
+
+ if ((reloc = xf86loadermalloc(sizeof(COFFRelocRec))) == NULL) {
+ ErrorF( "COFFDelayRelocation() Unable to allocate memory!!!!\n" );
+ return 0;
+ }
+
+ reloc->file=cofffile;
+ reloc->secndx=secndx;
+ reloc->rel=rel;
+ reloc->next = 0;
+
+ return reloc;
+}
+
+/*
+ * Manage listCOMMON
+ */
+
+static COFFCommonPtr
+COFFAddCOMMON(sym,index)
+SYMENT *sym;
+int index;
+{
+ COFFCommonPtr common;
+
+ if ((common = xf86loadermalloc(sizeof(COFFCommonRec))) == NULL) {
+ ErrorF( "COFFAddCOMMON() Unable to allocate memory!!!!\n" );
+ return 0;
+ }
+ common->sym=sym;
+ common->index=index;
+ common->next=0;
+
+ return common;
+}
+
+static LOOKUP *
+COFFCreateCOMMON(cofffile)
+COFFModulePtr cofffile;
+{
+ int numsyms=0,size=0,l=0;
+ int offset=0;
+ LOOKUP *lookup;
+ COFFCommonPtr common;
+
+ if (listCOMMON == NULL)
+ return NULL;
+
+ common=listCOMMON;
+ for (common = listCOMMON; common; common = common->next) {
+ /* Ensure long word alignment */
+ if( common->sym->n_value != 2
+ && common->sym->n_value != 1) /* But not for short and char ;-)(mr)*/
+ if( common->sym->n_value%4 != 0 )
+ common->sym->n_value+= 4-(common->sym->n_value%4);
+
+ /* accumulate the sizes */
+ size+=common->sym->n_value;
+ numsyms++;
+ }
+
+#ifdef COFFDEBUG
+ COFFDEBUG("COFFCreateCOMMON() %d entries (%d bytes) of COMMON data\n",
+ numsyms, size );
+#endif
+
+ if ((lookup = xf86loadermalloc((numsyms+1)*sizeof(LOOKUP))) == NULL) {
+ ErrorF( "COFFCreateCOMMON() Unable to allocate memory!!!!\n" );
+ return NULL;
+ }
+
+ cofffile->comsize=size;
+ if ((cofffile->common = xf86loadercalloc(1,size)) == NULL) {
+ ErrorF( "COFFCreateCOMMON() Unable to allocate memory!!!!\n" );
+ return NULL;
+ }
+
+ /* Traverse the common list and create a lookup table with all the
+ * common symbols. Destroy the common list in the process.
+ * See also ResolveSymbols.
+ */
+ while(listCOMMON) {
+ common=listCOMMON;
+ lookup[l].symName=COFFGetSymbolName(cofffile,common->index);
+ lookup[l].offset=(funcptr)(cofffile->common+offset);
+#ifdef COFFDEBUG
+ COFFDEBUG("Adding %x %s\n", lookup[l].offset, lookup[l].symName );
+#endif
+ listCOMMON=common->next;
+ offset+=common->sym->n_value;
+ xf86loaderfree(common);
+ l++;
+ }
+ /* listCOMMON == NULL */
+
+ lookup[l].symName=NULL; /* Terminate the list */
+ return lookup;
+}
+
+/*
+ * Symbol Table
+ */
+
+/*
+ * Get symbol name
+ */
+static char *
+COFFGetSymbolName(cofffile, index)
+COFFModulePtr cofffile;
+int index;
+{
+ char *name;
+ SYMENT *sym;
+
+ sym=(SYMENT *)(((unsigned char *)cofffile->symtab)+(index*SYMESZ));
+
+#ifdef COFFDEBUG
+ COFFDEBUG("COFFGetSymbolName(%x,%x) %x",cofffile, index, sym->n_zeroes );
+#endif
+
+ name = xf86loadermalloc(sym->n_zeroes ? SYMNMLEN + 1
+ : strlen((const char *)&cofffile->strtab[(int)sym->n_offset-4]) + 1);
+ if (!name)
+ FatalError("COFFGetSymbolName: Out of memory\n");
+
+ if( sym->n_zeroes )
+ {
+ strncpy(name,sym->n_name,SYMNMLEN);
+ name[SYMNMLEN]='\000';
+ }
+ else {
+ strcpy(name, (const char *)&cofffile->strtab[(int)sym->n_offset-4]);
+ }
+#ifdef COFFDEBUG
+ COFFDEBUG(" %s\n", name );
+#endif
+ return name;
+}
+
+static SYMENT *
+COFFGetSymbol(file, index)
+COFFModulePtr file;
+int index;
+{
+ return (SYMENT *)(((unsigned char *)file->symtab)+(index*SYMESZ));
+}
+
+static unsigned char *
+COFFGetSymbolValue(cofffile, index)
+COFFModulePtr cofffile;
+int index;
+{
+ unsigned char *symval=0; /* value of the indicated symbol */
+ itemPtr symbol; /* name/value of symbol */
+ char *symname;
+
+ symname=COFFGetSymbolName(cofffile, index);
+
+#ifdef COFFDEBUG
+ COFFDEBUG("COFFGetSymbolValue() for %s=", symname );
+#endif
+
+ symbol = LoaderHashFind(symname);
+
+ if( symbol )
+ symval=(unsigned char *)symbol->address;
+
+#ifdef COFFDEBUG
+ COFFDEBUG("%x\n", symval );
+#endif
+
+ xf86loaderfree(symname);
+ return symval;
+}
+
+#if defined(__powerpc__)
+/*
+ * This function returns the address of the glink routine for a symbol. This
+ * address is used in cases where the function being called is not in the
+ * same module as the calling function.
+ */
+static unsigned char *
+COFFGetSymbolGlinkValue(cofffile, index)
+COFFModulePtr cofffile;
+int index;
+{
+ unsigned char *symval=0; /* value of the indicated symbol */
+ itemPtr symbol; /* name/value of symbol */
+ char *name;
+
+ name=COFFGetSymbolName(cofffile, index);
+
+#ifdef COFFDEBUG
+ COFFDEBUG("COFFGetSymbolGlinkValue() for %s=", name );
+#endif
+
+ symbol = LoaderHashFind(name+1); /* Eat the '.' so we get the
+ Function descriptor instead */
+
+/* Here we are building up a glink function that will change the TOC
+ * pointer before calling a function that resides in a different module.
+ * The following code is being used to implement this.
+
+ 1 00000000 3d80xxxx lis r12,hi16(funcdesc)
+ 2 00000004 618cxxxx ori r12,r12,lo16(funcdesc)
+ 3 00000008 90410014 st r2,20(r1) # save old TOC pointer
+ 4 0000000c 804c0000 l r2,0(r12) # Get address of functions
+ 5 00000010 7c4903a6 mtctr r2 # load destination address
+ 6 00000014 804c0004 l r2,4(r12) # get TOC of function
+ 7 00000018 4e800420 bctr # branch to it
+
+ */
+ if( symbol ) {
+ symval=(unsigned char *)&symbol->code.glink;
+#ifdef COFFDEBUG
+ COFFDEBUG("%x\n", symval );
+ COFFDEBUG("glink_%s=%x\n", name,symval );
+#endif
+ symbol->code.glink[ 0]=0x3d80; /* lis r12 */
+ symbol->code.glink[ 1]=((unsigned long)symbol->address&0xffff0000)>>16;
+ symbol->code.glink[ 2]=0x618c; /* ori r12 */
+ symbol->code.glink[ 3]=((unsigned long)symbol->address&0x0000ffff);
+ symbol->code.glink[ 4]=0x9041; /* st r2,20(r1) */
+ symbol->code.glink[ 5]=0x0014;
+ symbol->code.glink[ 6]=0x804c; /* l r2,0(r12) */
+ symbol->code.glink[ 7]=0x0000;
+ symbol->code.glink[ 8]=0x7c49; /* mtctr r2 */
+ symbol->code.glink[ 9]=0x03a6;
+ symbol->code.glink[10]=0x804c; /* l r2,4(r12) */
+ symbol->code.glink[11]=0x0004;
+ symbol->code.glink[12]=0x4e80; /* bctr */
+ symbol->code.glink[13]=0x0420;
+ ppc_flush_icache(&symbol->code.glink[0]);
+ ppc_flush_icache(&symbol->code.glink[12]);
+ }
+
+ xf86loaderfree(name);
+ return symval;
+}
+#endif /* __powerpc__ */
+
+/*
+ * Fix all of the relocation for the given section.
+ */
+static COFFRelocPtr
+COFF_RelocateEntry(cofffile, secndx, rel)
+COFFModulePtr cofffile;
+int secndx; /* index of the target section */
+RELOC *rel;
+{
+ SYMENT *symbol; /* value of the indicated symbol */
+ unsigned long *dest32; /* address of the place being modified */
+#if defined(__powerpc__)
+ unsigned short *dest16; /* address of the place being modified */
+ itemPtr symitem; /* symbol structure from has table */
+ char *name;
+#endif
+ unsigned char *symval; /* value of the indicated symbol */
+
+/*
+ * Note: Section numbers are 1 biased, while the cofffile->saddr[] array
+ * of pointer is 0 biased, so alway have to account for the difference.
+ */
+
+/*
+ * Reminder: secndx is the section to which the relocation is applied.
+ * symbol->n_scnum is the section in which the symbol value resides.
+ */
+
+#ifdef COFFDEBUG
+ COFFDEBUG("%x %d %o ",
+ rel->r_vaddr,rel->r_symndx,rel->r_type );
+#if defined(__powerpc__)
+ COFFDEBUG("[%x %x %x] ",
+ RELOC_RSIGN(*rel), RELOC_RFIXUP(*rel), RELOC_RLEN(*rel));
+#endif
+#endif
+ symbol=COFFGetSymbol(cofffile,rel->r_symndx);
+#ifdef COFFDEBUG
+ COFFDEBUG("%d %x %d-%d\n", symbol->n_sclass, symbol->n_value, symbol->n_scnum, secndx );
+#endif
+
+/*
+ * Check to see if the relocation offset is part of the .text segment.
+ * If not, we must change the offset to be relative to the .data section
+ * which is NOT contiguous.
+ */
+ switch(secndx+1) { /* change the bias */
+ case N_TEXT:
+ if( (long)rel->r_vaddr < cofffile->txtaddr ||
+ (long)rel->r_vaddr > (long)(cofffile->txtaddr+cofffile->txtsize) ) {
+ FatalError("Relocation against N_TEXT not in .text section\n");
+ }
+ dest32=(unsigned long *)((long)(cofffile->saddr[secndx])+
+ ((unsigned char *)rel->r_vaddr-cofffile->txtaddr));
+ break;
+ case N_DATA:
+ if( (long)rel->r_vaddr < cofffile->dataddr ||
+ (long)rel->r_vaddr > (long)(cofffile->dataddr+cofffile->datsize) ) {
+ FatalError("Relocation against N_DATA not in .data section\n");
+ }
+ dest32=(unsigned long *)((long)(cofffile->saddr[secndx])+
+ ((unsigned char *)rel->r_vaddr-cofffile->dataddr));
+ break;
+ case N_BSS:
+ if( (long)rel->r_vaddr < cofffile->bssaddr ||
+ (long)rel->r_vaddr > (long)(cofffile->bssaddr+cofffile->bsssize) ) {
+ FatalError("Relocation against N_TEXT not in .bss section\n");
+ }
+ dest32=(unsigned long *)((long)(cofffile->saddr[secndx])+
+ ((unsigned char *)rel->r_vaddr-cofffile->bssaddr));
+ break;
+ default:
+ FatalError("Relocation against unknown section %d\n", secndx );
+ }
+
+ if( symbol->n_sclass == 0 )
+ {
+ symval=(unsigned char *)(symbol->n_value+(*dest32)-symbol->n_type);
+#ifdef COFFDEBUG
+ COFFDEBUG( "symbol->n_sclass==0\n" );
+ COFFDEBUG( "dest32=%x\t", dest32 );
+ COFFDEBUG( "symval=%x\t", symval );
+ COFFDEBUG( "*dest32=%8.8x\t", *dest32 );
+#endif
+ *dest32=(unsigned long)symval;
+ return 0;
+ }
+
+ switch( rel->r_type )
+ {
+#if defined(i386)
+ case R_DIR32:
+#ifdef COFFDEBUG
+#endif
+ symval=COFFGetSymbolValue(cofffile, rel->r_symndx);
+ if( symval ) {
+#ifdef COFFDEBUG
+ char *namestr;
+ COFFDEBUG( "R_DIR32 %s\n",
+ namestr=COFFGetSymbolName(cofffile,rel->r_symndx) );
+ xf86loaderfree(namestr);
+ COFFDEBUG( "txtsize=%x\t", cofffile->txtsize );
+ COFFDEBUG( "dest32=%x\t", dest32 );
+ COFFDEBUG( "symval=%x\t", symval );
+ COFFDEBUG( "*dest32=%8.8x\t", *dest32 );
+#endif
+ *dest32=(unsigned long)(symval+(*dest32)-symbol->n_value);
+ } else {
+ switch( symbol->n_scnum ) {
+ case N_UNDEF:
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_DIR32 N_UNDEF\n" );
+#endif
+ return COFFDelayRelocation(cofffile,secndx,rel);
+ case N_ABS:
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_DIR32 N_ABS\n" );
+#endif
+ return 0;
+ case N_DEBUG:
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_DIR32 N_DEBUG\n" );
+#endif
+ return 0;
+ case N_COMMENT:
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_DIR32 N_COMMENT\n" );
+#endif
+ return 0;
+ case N_TEXT:
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_DIR32 N_TEXT\n" );
+ COFFDEBUG( "dest32=%x\t", dest32 );
+ COFFDEBUG( "symval=%x\t", symval );
+ COFFDEBUG( "*dest32=%8.8x\t", *dest32 );
+#endif
+ *dest32=(unsigned long)((*dest32)+
+ (unsigned long)(cofffile->saddr[N_TEXT-1]));
+ break;
+ case N_DATA:
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_DIR32 N_DATA\n" );
+ COFFDEBUG( "txtsize=%x\t", cofffile->txtsize );
+ COFFDEBUG( "dest32=%x\t", dest32 );
+ COFFDEBUG( "symval=%x\t", symval );
+ COFFDEBUG( "*dest32=%8.8x\t", *dest32 );
+#endif
+ *dest32=(unsigned long)((*dest32)+
+ ((unsigned long)(cofffile->saddr[N_DATA-1]))-
+ cofffile->dataddr);
+ break;
+ case N_BSS:
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_DIR32 N_BSS\n" );
+ COFFDEBUG( "dest32=%x\t", dest32 );
+ COFFDEBUG( "symval=%x\t", symval );
+ COFFDEBUG( "*dest32=%8.8x\t", *dest32 );
+#endif
+ *dest32=(unsigned long)((*dest32)+
+ (unsigned long)(cofffile->saddr[N_BSS-1])-
+ (cofffile->bssaddr));
+ break;
+ default:
+ ErrorF("R_DIR32 with unexpected section %d\n",
+ symbol->n_scnum );
+ }
+
+ }
+#ifdef COFFDEBUG
+ COFFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ break;
+ case R_PCRLONG:
+ if( symbol->n_scnum == N_TEXT )
+ break;
+
+ symval=COFFGetSymbolValue(cofffile, rel->r_symndx);
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_PCRLONG ");
+ COFFDEBUG( "dest32=%x\t", dest32 );
+ COFFDEBUG( "symval=%x\t", symval );
+ COFFDEBUG( "*dest32=%8.8x\t", *dest32 );
+#endif
+ if( symval == 0 ) {
+#ifdef COFFDEBUG
+ char *name;
+ COFFDEBUG( "***Unable to resolve symbol %s\n",
+ name=COFFGetSymbolName(cofffile,rel->r_symndx) );
+ xf86loaderfree(name);
+#endif
+ return COFFDelayRelocation(cofffile,secndx,rel);
+ }
+ *dest32=(unsigned long)(symval-((long)dest32+sizeof(long)));
+
+#ifdef COFFDEBUG
+ COFFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ break;
+ case R_ABS:
+ /*
+ * Nothing to really do here.
+ * Usually, a dummy relocation for .file
+ */
+ break;
+#endif /* i386 */
+#if defined(__powerpc__)
+ case R_POS:
+ /*
+ * Positive Relocation
+ */
+ if( RELOC_RLEN(*rel) != 0x1f )
+ FatalError("R_POS with size != 32 bits" );
+ symval=COFFGetSymbolValue(cofffile, rel->r_symndx);
+ if( symval ) {
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_POS ");
+ COFFDEBUG( "dest32=%x\t", dest32 );
+ COFFDEBUG( "symval=%x\t", symval );
+ COFFDEBUG( "*dest32=%8.8x\t", *dest32 );
+#endif
+ *dest32=(unsigned long)(symval+(*dest32)-symbol->n_value);
+ ppc_flush_icache(dest32);
+ } else {
+ switch( symbol->n_scnum ) {
+ case N_UNDEF:
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_POS N_UNDEF\n" );
+#endif
+ return COFFDelayRelocation(cofffile,secndx,rel);
+ case N_ABS:
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_POS N_ABS\n" );
+#endif
+ return 0;
+ case N_DEBUG:
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_POS N_DEBUG\n" );
+#endif
+ return 0;
+ case N_COMMENT:
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_POS N_COMMENT\n" );
+#endif
+ return 0;
+ case N_TEXT:
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_POS N_TEXT\n" );
+ COFFDEBUG( "dest32=%x\t", dest32 );
+ COFFDEBUG( "symval=%x\t", symval );
+ COFFDEBUG( "*dest32=%8.8x\t", *dest32 );
+#endif
+ *dest32=(unsigned long)((*dest32)+
+ ((unsigned long)(cofffile->saddr[N_TEXT-1]))-
+ cofffile->txtaddr);
+ ppc_flush_icache(dest32);
+ break;
+ case N_DATA:
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_POS N_DATA\n" );
+ COFFDEBUG( "txtsize=%x\t", cofffile->txtsize );
+ COFFDEBUG( "dest32=%x\t", dest32 );
+ COFFDEBUG( "symval=%x\t", symval );
+ COFFDEBUG( "*dest32=%8.8x\t", *dest32 );
+#endif
+ *dest32=(unsigned long)((*dest32)+
+ ((unsigned long)(cofffile->saddr[N_DATA-1]))-
+ cofffile->dataddr);
+ ppc_flush_icache(dest32);
+ break;
+ case N_BSS:
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_POS N_BSS\n" );
+ COFFDEBUG( "dest32=%x\t", dest32 );
+ COFFDEBUG( "symval=%x\t", symval );
+ COFFDEBUG( "*dest32=%8.8x\t", *dest32 );
+#endif
+ *dest32=(unsigned long)((*dest32)+
+ (unsigned long)(cofffile->saddr[N_BSS-1])-
+ (cofffile->bssaddr));
+ ppc_flush_icache(dest32);
+ break;
+ default:
+ ErrorF("R_POS with unexpected section %d\n",
+ symbol->n_scnum );
+ }
+ }
+#ifdef COFFDEBUG
+ COFFDEBUG( "*dest32=%8.8x\t", *dest32 );
+ COFFDEBUG( "\n" );
+#endif
+ break;
+ case R_TOC:
+ /*
+ * Relative to TOC
+ */
+ {
+ dest16=(unsigned short *)dest32;
+ if( RELOC_RLEN(*rel) != 0x0f )
+ FatalError("R_TOC with size != 16 bits" );
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_TOC ");
+ COFFDEBUG( "dest16=%x\t", dest16 );
+ COFFDEBUG( "symbol=%x\t", symbol );
+ COFFDEBUG( "symbol->n_value=%x\t", symbol->n_value );
+ COFFDEBUG( "cofffile->toc=%x\t", cofffile->toc );
+ COFFDEBUG( "*dest16=%8.8x\t", *dest16 );
+#endif
+ *dest16=(unsigned long)((symbol->n_value-cofffile->toc));
+ ppc_flush_icache(dest16);
+ }
+#ifdef COFFDEBUG
+ COFFDEBUG( "*dest16=%8.8x\t", *dest16 );
+ COFFDEBUG( "\n" );
+#endif
+ break;
+ case R_BR:
+ /*
+ * Branch relative to self, non-modifiable
+ */
+
+ if( RELOC_RLEN(*rel) != 0x19 )
+ FatalError("R_BR with size != 24 bits" );
+ name = COFFGetSymbolName(cofffile, rel->r_symndx);
+ symitem = LoaderHashFind(name);
+ if( symitem == 0 ) {
+ name++;
+ symitem = LoaderHashFind(name);
+ }
+ if( symitem && cofffile->module != symitem->module ) {
+#ifdef COFFDEBUG
+ COFFDEBUG("Symbol module %d != file module %d\n",
+ symitem->module, cofffile->module );
+#endif
+ symval=COFFGetSymbolGlinkValue(cofffile, rel->r_symndx);
+ }
+ else
+ symval=COFFGetSymbolValue(cofffile, rel->r_symndx);
+ if( symval == 0 ) {
+#ifdef COFFDEBUG
+ char *name;
+ COFFDEBUG( "***Unable to resolve symbol %s\n",
+ name=COFFGetSymbolName(cofffile,rel->r_symndx) );
+ xf86loaderfree(name);
+#endif
+ return COFFDelayRelocation(cofffile,secndx,rel);
+ }
+#ifdef COFFDEBUG
+ COFFDEBUG( "R_BR ");
+ COFFDEBUG( "dest32=%x\t", dest32 );
+ COFFDEBUG( "symval=%x\t", symval );
+ COFFDEBUG( "*dest32=%8.8x\t", *dest32 );
+#endif
+ {
+ unsigned long val;
+ val=((unsigned long)symval-(unsigned long)dest32);
+#ifdef COFFDEBUG
+ COFFDEBUG( "val=%8.8x\n", val );
+#endif
+ val = val>>2;
+ if( (val & 0x3f000000) != 0x3f000000 &&
+ (val & 0x3f000000) != 0x00000000 ) {
+ FatalError( "R_BR offset %x too large\n", val<<2 );
+ break;
+ }
+ val &= 0x00ffffff;
+#ifdef COFFDEBUG
+ COFFDEBUG( "val=%8.8x\n", val );
+#endif
+ /*
+ * The address part contains the offset to the beginning
+ * of the .text section. Disreguard this since we have
+ * calculated the correct offset already.
+ */
+ (*dest32)=((*dest32)&0xfc000003)|(val<<2);
+#ifdef COFFDEBUG
+ COFFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ if( cofffile->module != symitem->module ) {
+ (*++dest32)=0x80410014; /* lwz r2,20(r1) */
+ }
+ ppc_flush_icache(--dest32);
+ }
+
+ break;
+#endif /* __powerpc__ */
+ default:
+#if defined(i386)
+ ErrorF(
+ "COFF_RelocateEntry() Unsupported relocation type %o\n",
+ rel->r_type );
+#endif
+#if defined(__powerpc__)
+ ErrorF(
+ "COFF_RelocateEntry() Unsupported relocation type %o\n",
+ rel->r_type );
+#endif
+ break;
+ }
+ return 0;
+}
+
+static COFFRelocPtr
+COFFCollectRelocations(cofffile)
+COFFModulePtr cofffile;
+{
+ unsigned short i,j;
+ RELOC *rel;
+ SCNHDR *sec;
+ COFFRelocPtr reloc_head = NULL;
+ COFFRelocPtr tmp;
+
+ for(i=0; i<cofffile->numsh; i++ ) {
+ if( cofffile->saddr[i] == NULL )
+ continue; /* Section not loaded!! */
+ sec=&(cofffile->sections[i]);
+ for(j=0;j<sec->s_nreloc;j++) {
+ rel=(RELOC *)(cofffile->reladdr[i]+(j*RELSZ));
+ tmp = COFFDelayRelocation(cofffile,i,rel);
+ tmp->next = reloc_head;
+ reloc_head = tmp;
+ }
+ }
+
+ return reloc_head;
+}
+
+/*
+ * COFF_GetSymbols()
+ *
+ * add the symbols to the symbol table maintained by the loader.
+ */
+
+static LOOKUP *
+COFF_GetSymbols(cofffile)
+COFFModulePtr cofffile;
+{
+ SYMENT *sym;
+ AUXENT *aux=NULL;
+ int i, l, numsyms;
+ LOOKUP *lookup, *lookup_common, *p;
+ char *symname;
+
+/*
+ * Load the symbols into memory
+ */
+ numsyms=cofffile->header->f_nsyms;
+
+#ifdef COFFDEBUG
+ COFFDEBUG("COFF_GetSymbols(): %d symbols\n", numsyms );
+#endif
+
+ cofffile->symsize=(numsyms*SYMESZ);
+ cofffile->symtab=(SYMENT *)_LoaderFileToMem(cofffile->fd,cofffile->header->f_symptr,
+ (numsyms*SYMESZ),"symbols");
+
+ if ((lookup = xf86loadermalloc((numsyms+1)*sizeof(LOOKUP))) == NULL)
+ return NULL;
+
+ for(i=0,l=0; i<numsyms; i++)
+ {
+ sym=(SYMENT *)(((unsigned char *)cofffile->symtab)+(i*SYMESZ));
+ symname=COFFGetSymbolName(cofffile,i);
+ if( sym->n_numaux > 0 )
+ aux=(AUXENT *)(((unsigned char *)cofffile->symtab)+((i+1)*SYMESZ));
+ else
+ aux=NULL;
+#ifdef COFFDEBUG
+ COFFDEBUG("\t%d %d %x %x %d %d %s\n",
+ i, sym->n_scnum, sym->n_value, sym->n_type,
+ sym->n_sclass, sym->n_numaux, symname );
+ if( aux )
+ COFFDEBUG("aux=\t%d %x %x %x %x %x %x\n",
+ aux->x_scnlen, aux->x_parmhash, aux->x_snhash,
+ aux->x_smtyp, aux->x_smclas, aux->x_stab,
+ aux->x_snstab );
+#endif
+ i+=sym->n_numaux;
+ /*
+ * check for TOC csect before discarding C_HIDEXT below
+ */
+ if( aux && aux->x_smclas == XMC_TC0 ) {
+ if( sym->n_scnum != N_DATA )
+ FatalError("TOC not in N_DATA section");
+ cofffile->toc=sym->n_value;
+ cofffile->tocaddr=(cofffile->saddr[sym->n_scnum-1]+
+ sym->n_value-(cofffile->dataddr));
+#ifdef COFFDEBUG
+ COFFDEBUG("TOC=%x\n", cofffile->toc );
+ COFFDEBUG("TOCaddr=%x\n", cofffile->tocaddr );
+#endif
+ continue;
+ }
+ if( sym->n_sclass == C_HIDEXT ) {
+/*
+ && aux && !(aux->x_smclas == XMC_DS
+ && aux->x_smtyp == XTY_SD) ) ) {
+*/
+#ifdef COFFDEBUG
+ COFFDEBUG("Skipping C_HIDEXT class symbol %s\n", symname );
+#endif
+ continue;
+ }
+ switch( sym->n_scnum )
+ {
+ case N_UNDEF:
+ if( sym->n_value != 0 ) {
+ char *name;
+ COFFCommonPtr tmp;
+
+ name = COFFGetSymbolName(cofffile,i);
+#ifdef COFFDEBUG
+ COFFDEBUG("Adding COMMON space for %s\n", name);
+#endif
+ if(!LoaderHashFind(name)) {
+ tmp = COFFAddCOMMON(sym,i);
+ if (tmp) {
+ tmp->next = listCOMMON;
+ listCOMMON = tmp;
+ }
+ }
+ xf86loaderfree(name);
+ }
+ xf86loaderfree(symname);
+ break;
+ case N_ABS:
+ case N_DEBUG:
+ case N_COMMENT:
+#ifdef COFFDEBUG
+ COFFDEBUG("Freeing %s, section %d\n",
+ symname, sym->n_scnum );
+#endif
+ xf86loaderfree(symname);
+ break;
+ case N_TEXT:
+ if( (sym->n_sclass == C_EXT || sym->n_sclass == C_HIDEXT)
+ && cofffile->saddr[sym->n_scnum-1]) {
+ lookup[l].symName=symname;
+ lookup[l].offset=(funcptr)
+ (cofffile->saddr[sym->n_scnum-1]+
+ sym->n_value-cofffile->txtaddr);
+#ifdef COFFDEBUG
+ COFFDEBUG("Adding %x %s\n",
+ lookup[l].offset, lookup[l].symName );
+#endif
+ l++;
+ }
+ else {
+#ifdef COFFDEBUG
+ COFFDEBUG( "TEXT Section not loaded %d\n",
+ sym->n_scnum-1 );
+#endif
+ xf86loaderfree(symname);
+ }
+ break;
+ case N_DATA:
+ /*
+ * Note: COFF expects .data to be contiguous with
+ * .data, so that offsets for .data are relative to
+ * .text. We need to adjust for this, and make them
+ * relative to .data so that the relocation can be
+ * properly applied. This is needed becasue we allocate
+ * .data seperately from .text.
+ */
+ if( (sym->n_sclass == C_EXT || sym->n_sclass == C_HIDEXT)
+ && cofffile->saddr[sym->n_scnum-1]) {
+ lookup[l].symName=symname;
+ lookup[l].offset=(funcptr)
+ (cofffile->saddr[sym->n_scnum-1]+
+ sym->n_value-cofffile->dataddr);
+#ifdef COFFDEBUG
+ COFFDEBUG("Adding %x %s\n",
+ lookup[l].offset, lookup[l].symName );
+#endif
+ l++;
+ }
+ else {
+#ifdef COFFDEBUG
+ COFFDEBUG( "DATA Section not loaded %d\n",
+ sym->n_scnum-1 );
+#endif
+ xf86loaderfree(symname);
+ }
+ break;
+ case N_BSS:
+ /*
+ * Note: COFF expects .bss to be contiguous with
+ * .data, so that offsets for .bss are relative to
+ * .text. We need to adjust for this, and make them
+ * relative to .bss so that the relocation can be
+ * properly applied. This is needed becasue we allocate
+ * .bss seperately from .text and .data.
+ */
+ if( (sym->n_sclass == C_EXT || sym->n_sclass == C_HIDEXT)
+ && cofffile->saddr[sym->n_scnum-1]) {
+ lookup[l].symName=symname;
+ lookup[l].offset=(funcptr)
+ (cofffile->saddr[sym->n_scnum-1]+
+ sym->n_value-cofffile->bssaddr);
+#ifdef COFFDEBUG
+ COFFDEBUG("Adding %x %s\n",
+ lookup[l].offset, lookup[l].symName );
+#endif
+ l++;
+ }
+ else {
+#ifdef COFFDEBUG
+ COFFDEBUG( "BSS Section not loaded %d\n",
+ sym->n_scnum-1 );
+#endif
+ xf86loaderfree(symname);
+ }
+ break;
+ default:
+ ErrorF("Unknown Section number %d\n", sym->n_scnum );
+ xf86loaderfree(symname);
+ break;
+ }
+ }
+
+ lookup[l].symName=NULL; /* Terminate the list */
+
+ lookup_common = COFFCreateCOMMON(cofffile);
+ if (lookup_common) {
+ for (i = 0, p = lookup_common; p->symName; i++, p++)
+ ;
+ memcpy(&(lookup[l]), lookup_common, i * sizeof (LOOKUP));
+
+ xf86loaderfree(lookup_common);
+ l += i;
+ lookup[l].symName = NULL;
+ }
+
+/*
+ * remove the COFF symbols that will show up in every module
+ */
+ for (i = 0, p = lookup; p->symName; i++, p++) {
+ while (p->symName && (!strcmp(lookup[i].symName, ".text")
+ || !strcmp(lookup[i].symName, ".data")
+ || !strcmp(lookup[i].symName, ".bss")
+ )) {
+ memmove(&(lookup[i]), &(lookup[i+1]), (l-- - i) * sizeof (LOOKUP));
+ }
+ }
+
+ return lookup;
+}
+
+#define SecOffset(index) cofffile->sections[index].s_scnptr
+#define SecSize(index) cofffile->sections[index].s_size
+#define SecAddr(index) cofffile->sections[index].s_paddr
+#define RelOffset(index) cofffile->sections[index].s_relptr
+#define RelSize(index) (cofffile->sections[index].s_nreloc*RELSZ)
+
+/*
+ * COFFCollectSections
+ *
+ * Do the work required to load each section into memory.
+ */
+static void
+COFFCollectSections(cofffile)
+COFFModulePtr cofffile;
+{
+ unsigned short i;
+
+/*
+ * Find and identify all of the Sections
+ */
+
+#ifdef COFFDEBUG
+ COFFDEBUG("COFFCollectSections(): %d sections\n", cofffile->numsh );
+#endif
+
+ for( i=0; i<cofffile->numsh; i++) {
+#ifdef COFFDEBUG
+ COFFDEBUG("%d %s\n", i, cofffile->sections[i].s_name );
+#endif
+ /* .text */
+ if( strcmp(cofffile->sections[i].s_name,
+ ".text" ) == 0 ) {
+ cofffile->text=_LoaderFileToMem(cofffile->fd,
+ SecOffset(i),SecSize(i),".text");
+ cofffile->saddr[i]=cofffile->text;
+ cofffile->txtndx=i;
+ cofffile->txtaddr=SecAddr(i);
+ cofffile->txtsize=SecSize(i);
+ cofffile->txtrelsize=RelSize(i);
+ cofffile->reladdr[i]=_LoaderFileToMem(cofffile->fd,
+ RelOffset(i), RelSize(i),".rel.text");
+#ifdef COFFDEBUG
+ COFFDEBUG(".text starts at %x (%x bytes)\n", cofffile->text, cofffile->txtsize );
+#endif
+ continue;
+ }
+ /* .data */
+ if( strcmp(cofffile->sections[i].s_name,
+ ".data" ) == 0 ) {
+ cofffile->data=_LoaderFileToMem(cofffile->fd,
+ SecOffset(i),SecSize(i),".data");
+ cofffile->saddr[i]=cofffile->data;
+ cofffile->datndx=i;
+ cofffile->dataddr=SecAddr(i);
+ cofffile->datsize=SecSize(i);
+ cofffile->datrelsize=RelSize(i);
+ cofffile->reladdr[i]=_LoaderFileToMem(cofffile->fd,
+ RelOffset(i), RelSize(i),".rel.data");
+#ifdef COFFDEBUG
+ COFFDEBUG(".data starts at %x (%x bytes)\n", cofffile->data, cofffile->datsize );
+#endif
+ continue;
+ }
+ /* .bss */
+ if( strcmp(cofffile->sections[i].s_name,
+ ".bss" ) == 0 ) {
+ if( SecSize(i) )
+ cofffile->bss=xf86loadercalloc(1,SecSize(i));
+ else
+ cofffile->bss=NULL;
+ cofffile->saddr[i]=cofffile->bss;
+ cofffile->bssndx=i;
+ cofffile->bssaddr=SecAddr(i);
+ cofffile->bsssize=SecSize(i);
+#ifdef COFFDEBUG
+ COFFDEBUG(".bss starts at %x (%x bytes)\n", cofffile->bss, cofffile->bsssize );
+#endif
+ continue;
+ }
+ /* .comment */
+ if( strncmp(cofffile->sections[i].s_name,
+ ".comment",strlen(".comment") ) == 0 ) {
+ continue;
+ }
+ /* .stab */
+ if( strcmp(cofffile->sections[i].s_name,
+ ".stab" ) == 0 ) {
+ continue;
+ }
+ /* .stabstr */
+ if( strcmp(cofffile->sections[i].s_name,
+ ".stabstr" ) == 0 ) {
+ continue;
+ }
+ ErrorF("Not loading %s\n", cofffile->sections[i].s_name );
+ }
+}
+
+/*
+ * Public API for the COFF implementation of the loader.
+ */
+void *
+COFFLoadModule(modrec, cofffd, ppLookup)
+loaderPtr modrec;
+int cofffd;
+LOOKUP **ppLookup;
+{
+ COFFModulePtr cofffile;
+ FILHDR *header;
+ int stroffset; /* offset of string table */
+ COFFRelocPtr coff_reloc, tail;
+ void *v;
+
+#ifdef COFFDEBUG
+ COFFDEBUG("COFFLoadModule(%s,%x,%x)\n",modrec->name,modrec->handle,cofffd);
+#endif
+
+ if ((cofffile = xf86loadercalloc(1,sizeof(COFFModuleRec))) == NULL) {
+ ErrorF( "Unable to allocate COFFModuleRec\n" );
+ return NULL;
+ }
+
+ cofffile->handle=modrec->handle;
+ cofffile->module=modrec->module;
+ cofffile->fd=cofffd;
+ v=cofffile->funcs=modrec->funcs;
+
+/*
+ * Get the COFF header
+ */
+ cofffile->header=(FILHDR *)_LoaderFileToMem(cofffd,0,sizeof(FILHDR),"header");
+ header=(FILHDR *)cofffile->header;
+
+ if( header->f_symptr == 0 || header->f_nsyms == 0 ) {
+ ErrorF("No symbols found in module\n");
+ _LoaderFreeFileMem(header,sizeof(FILHDR));
+ xf86loaderfree(cofffile);
+ return NULL;
+ }
+/*
+ * Get the section table
+ */
+ cofffile->numsh=header->f_nscns;
+ cofffile->secsize=(header->f_nscns*SCNHSZ);
+ cofffile->sections=(SCNHDR *)_LoaderFileToMem(cofffd,FILHSZ+header->f_opthdr,
+ cofffile->secsize, "sections");
+ cofffile->saddr=xf86loadercalloc(cofffile->numsh, sizeof(unsigned char *));
+ cofffile->reladdr=xf86loadercalloc(cofffile->numsh, sizeof(unsigned char *));
+
+/*
+ * Load the optional header if we need it ?????
+ */
+
+/*
+ * Load the rest of the desired sections
+ */
+ COFFCollectSections(cofffile);
+
+/*
+ * load the string table (must be done before we process symbols).
+ */
+ stroffset=header->f_symptr+(header->f_nsyms*SYMESZ);
+
+ _LoaderFileRead(cofffd,stroffset,&(cofffile->strsize),sizeof(int));
+
+ stroffset+=4; /* Move past the size */
+ cofffile->strsize-=sizeof(int); /* size includes itself, so reduce by 4 */
+ cofffile->strtab=_LoaderFileToMem(cofffd,stroffset,cofffile->strsize,"strings");
+
+/*
+ * add symbols
+ */
+ *ppLookup = COFF_GetSymbols(cofffile);
+
+/*
+ * Do relocations
+ */
+ coff_reloc = COFFCollectRelocations(cofffile);
+ if (coff_reloc) {
+ for (tail = coff_reloc; tail->next; tail = tail->next)
+ ;
+ tail->next = _LoaderGetRelocations(v)->coff_reloc;
+ _LoaderGetRelocations(v)->coff_reloc = coff_reloc;
+ }
+
+ return (void *)cofffile;
+}
+
+void
+COFFResolveSymbols(mod)
+void *mod;
+{
+ COFFRelocPtr newlist, p, tmp;
+
+ /* Try to relocate everything. Build a new list containing entries
+ * which we failed to relocate. Destroy the old list in the process.
+ */
+ newlist = 0;
+ for (p = _LoaderGetRelocations(mod)->coff_reloc; p; ) {
+ tmp = COFF_RelocateEntry(p->file, p->secndx, p->rel);
+ if (tmp) {
+ /* Failed to relocate. Keep it in the list. */
+ tmp->next = newlist;
+ newlist = tmp;
+ }
+ tmp = p;
+ p = p->next;
+ xf86loaderfree(tmp);
+ }
+ _LoaderGetRelocations(mod)->coff_reloc = newlist;
+}
+
+int
+COFFCheckForUnresolved( mod)
+void *mod;
+{
+ char *name;
+ COFFRelocPtr crel;
+ int flag, fatalsym = 0;
+
+ if ((crel = _LoaderGetRelocations(mod)->coff_reloc) == NULL)
+ return 0;
+
+ while( crel )
+ {
+ name = COFFGetSymbolName(crel->file, crel->rel->r_symndx);
+ flag = _LoaderHandleUnresolved(name,
+ _LoaderHandleToName(crel->file->handle));
+ if (flag) fatalsym = 1;
+ xf86loaderfree(name);
+ crel=crel->next;
+ }
+ return fatalsym;
+}
+
+void
+COFFUnloadModule(modptr)
+void *modptr;
+{
+ COFFModulePtr cofffile = (COFFModulePtr)modptr;
+ COFFRelocPtr relptr, reltptr, *brelptr;
+
+/*
+ * Delete any unresolved relocations
+ */
+
+ relptr=_LoaderGetRelocations(cofffile->funcs)->coff_reloc;
+ brelptr=&(_LoaderGetRelocations(cofffile->funcs)->coff_reloc);
+
+ while(relptr) {
+ if( relptr->file == cofffile ) {
+ *brelptr=relptr->next; /* take it out of the list */
+ reltptr=relptr; /* save pointer to this node */
+ relptr=relptr->next; /* advance the pointer */
+ xf86loaderfree(reltptr); /* free the node */
+ }
+ else {
+ brelptr=&(relptr->next);
+ relptr=relptr->next; /* advance the pointer */
+ }
+ }
+
+/*
+ * Delete any symbols in the symbols table.
+ */
+
+ LoaderHashTraverse((void *)cofffile, COFFhashCleanOut);
+
+/*
+ * Free the sections that were allocated.
+ */
+#define CheckandFree(ptr,size) if(ptr) _LoaderFreeFileMem((ptr),(size))
+
+ CheckandFree(cofffile->strtab,cofffile->strsize);
+ CheckandFree(cofffile->symtab,cofffile->symsize);
+ CheckandFree(cofffile->text,cofffile->txtsize);
+ CheckandFree(cofffile->reladdr[cofffile->txtndx],cofffile->txtrelsize);
+ CheckandFree(cofffile->data,cofffile->datsize);
+ CheckandFree(cofffile->reladdr[cofffile->datndx],cofffile->datrelsize);
+ CheckandFree(cofffile->bss,cofffile->bsssize);
+ if( cofffile->common )
+ xf86loaderfree(cofffile->common);
+/*
+ * Free the section table, and section pointer array
+ */
+ _LoaderFreeFileMem(cofffile->sections,cofffile->secsize);
+ xf86loaderfree(cofffile->saddr);
+ xf86loaderfree(cofffile->reladdr);
+ _LoaderFreeFileMem(cofffile->header,sizeof(FILHDR));
+/*
+ * Free the COFFModuleRec
+ */
+ xf86loaderfree(cofffile);
+
+ return;
+}
+
+char *
+COFFAddressToSection(void *modptr, unsigned long address)
+{
+ COFFModulePtr cofffile = (COFFModulePtr)modptr;
+ int i;
+
+ for( i=1; i<cofffile->numsh; i++) {
+ if( address >= (unsigned long)cofffile->saddr[i] &&
+ address <= (unsigned long)cofffile->saddr[i]+SecSize(i) ) {
+ return cofffile->sections[i].s_name;
+ }
+ }
+return NULL;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/loader/coffloader.h b/xc/programs/Xserver/hw/xfree86/loader/coffloader.h
new file mode 100644
index 000000000..35ce4b2c5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/coffloader.h
@@ -0,0 +1,34 @@
+/*
+ *
+ * Copyright 1997,1998 by Metro Link, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/coffloader.h,v 1.3 1998/09/20 14:41:04 dawes Exp $ */
+
+#ifndef _COFFLOADER_H
+#define _COFFLOADER_H
+/* coffloader.c */
+extern void *COFFLoadModule(loaderPtr, int, LOOKUP **);
+extern void COFFResolveSymbols(void *);
+extern int COFFCheckForUnresolved(void *);
+extern char *COFFAddressToSection(void *,unsigned long);
+extern void COFFUnloadModule(void *);
+#endif /* _COFFLOADER_H */
diff --git a/xc/programs/Xserver/hw/xfree86/loader/dixsym.c b/xc/programs/Xserver/hw/xfree86/loader/dixsym.c
new file mode 100644
index 000000000..8d878335f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/dixsym.c
@@ -0,0 +1,304 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/dixsym.c,v 1.23 1999/05/09 12:31:10 dawes Exp $ */
+
+
+/*
+ *
+ * Copyright 1995-1998 by Metro Link, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. 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.
+ */
+
+#undef DBMALLOC
+#include "sym.h"
+#include "colormap.h"
+#include "cursor.h"
+#include "dix.h"
+#include "dixfont.h"
+#include "dixstruct.h"
+#include "misc.h"
+#include "globals.h"
+#include "os.h"
+#include "resource.h"
+#include "servermd.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "extension.h"
+#include "extnsionst.h"
+#include "swaprep.h"
+#include "swapreq.h"
+#include "inputstr.h"
+#include "XIproto.h"
+#include "exevents.h"
+#include "extinit.h"
+#ifdef XV
+#include "xvmodproc.h"
+#endif
+#ifdef XFreeXDGA
+#include "dgaproc.h"
+#endif
+
+/* XXX This should be in a header somewhere */
+extern void ClientSleepUntil(ClientPtr, TimeStamp, void(*)(ClientPtr, pointer),
+ pointer);
+
+/* DIX things */
+
+LOOKUP dixLookupTab[] = {
+
+ /* dix */
+ /* atom.c */
+ SYMFUNC(MakeAtom)
+ SYMFUNC(ValidAtom)
+ /* colormap.c */
+ SYMFUNC(AllocColor)
+ SYMFUNC(CreateColormap)
+ SYMFUNC(FakeAllocColor)
+ SYMFUNC(FakeFreeColor)
+ SYMFUNC(FreeColors)
+ SYMFUNC(StoreColors)
+ SYMFUNC(TellLostMap)
+ SYMFUNC(TellGainedMap)
+ SYMFUNC(QueryColors)
+ /* cursor.c */
+ SYMFUNC(FreeCursor)
+ /* devices.c */
+ SYMFUNC(Ones)
+ SYMFUNC(InitButtonClassDeviceStruct)
+ SYMFUNC(InitFocusClassDeviceStruct)
+ SYMFUNC(InitLedFeedbackClassDeviceStruct)
+ SYMFUNC(InitPtrFeedbackClassDeviceStruct)
+ SYMFUNC(InitValuatorClassDeviceStruct)
+ SYMFUNC(InitKeyClassDeviceStruct)
+ /* dispatch.c */
+ SYMFUNC(SetInputCheck)
+ SYMFUNC(SendErrorToClient)
+ SYMFUNC(UpdateCurrentTime)
+ SYMFUNC(UpdateCurrentTimeIf)
+ SYMVAR(dispatchException)
+ SYMVAR(isItTimeToYield)
+ SYMVAR(ClientStateCallback)
+ /* dixfonts.c */
+ SYMFUNC(CloseFont)
+ SYMFUNC(FontToXError)
+ SYMFUNC(LoadGlyphs)
+ SYMVAR(fpe_functions)
+ /* dixutils.c */
+ SYMFUNC(AddCallback)
+ SYMFUNC(ClientSleep)
+ SYMFUNC(ClientTimeToServerTime)
+ SYMFUNC(ClientWakeup)
+ SYMFUNC(CompareTimeStamps)
+ SYMFUNC(CopyISOLatin1Lowered)
+ SYMFUNC(DeleteCallback)
+ SYMFUNC(LookupClient)
+ SYMFUNC(LookupDrawable)
+ SYMFUNC(LookupWindow)
+ SYMFUNC(NoopDDA)
+ SYMFUNC(RegisterBlockAndWakeupHandlers)
+ SYMFUNC(RemoveBlockAndWakeupHandlers)
+ SYMFUNC(SecurityLookupDrawable)
+ SYMFUNC(SecurityLookupWindow)
+ /* events.c */
+ SYMFUNC(CheckCursorConfinement)
+ SYMFUNC(DeliverEvents)
+ SYMFUNC(NewCurrentScreen)
+ SYMFUNC(PointerConfinedToScreen)
+ SYMFUNC(TryClientEvents)
+ SYMFUNC(WriteEventsToClient)
+ SYMVAR(DeviceEventCallback)
+ SYMVAR(EventCallback)
+ SYMVAR(inputInfo)
+ /* extension.c */
+ SYMFUNC(AddExtension)
+ SYMFUNC(AddExtensionAlias)
+ SYMFUNC(DeclareExtensionSecurity)
+ SYMFUNC(MinorOpcodeOfRequest)
+ SYMFUNC(StandardMinorOpcode)
+ /* gc.c */
+ SYMFUNC(CopyGC)
+ SYMFUNC(CreateGC)
+ SYMFUNC(CreateScratchGC)
+ SYMFUNC(ChangeGC)
+ SYMFUNC(dixChangeGC)
+ SYMFUNC(DoChangeGC)
+ SYMFUNC(FreeGC)
+ SYMFUNC(FreeScratchGC)
+ SYMFUNC(GetScratchGC)
+ SYMFUNC(SetClipRects)
+ SYMFUNC(ValidateGC)
+ SYMFUNC(VerifyRectOrder)
+ SYMFUNC(SetDashes)
+ /* globals.c */
+#ifdef DPMSExtension
+ SYMVAR(DPMSEnabled)
+ SYMVAR(DPMSCapableFlag)
+ SYMVAR(DPMSOffTime)
+ SYMVAR(DPMSPowerLevel)
+ SYMVAR(DPMSStandbyTime)
+ SYMVAR(DPMSSuspendTime)
+ SYMVAR(DPMSEnabledSwitch)
+ SYMVAR(DPMSDisabledSwitch)
+ SYMVAR(defaultDPMSEnabled)
+#endif
+#ifdef XV
+ SYMVAR(XvScreenInitProc)
+ SYMVAR(XvGetScreenIndexProc)
+ SYMVAR(XvGetRTPortProc)
+#endif
+ SYMVAR(ScreenSaverBlanking)
+ SYMVAR(WindowTable)
+ SYMVAR(clients)
+ SYMVAR(currentMaxClients)
+ SYMVAR(currentTime)
+ SYMVAR(defaultColorVisualClass)
+ SYMVAR(globalSerialNumber)
+ SYMVAR(lastDeviceEventTime)
+ SYMVAR(monitorResolution)
+ SYMVAR(permitOldBugs)
+ SYMVAR(screenInfo)
+ SYMVAR(serverClient)
+ SYMVAR(serverGeneration)
+ /* pixmap.c */
+ SYMFUNC(AllocatePixmap)
+ SYMFUNC(GetScratchPixmapHeader)
+ SYMFUNC(FreeScratchPixmapHeader)
+ SYMVAR(PixmapWidthPaddingInfo)
+ /* privates.c */
+ SYMFUNC(AllocateClientPrivate)
+ SYMFUNC(AllocateClientPrivateIndex)
+ SYMFUNC(AllocateGCPrivate)
+ SYMFUNC(AllocateGCPrivateIndex)
+ SYMFUNC(AllocateWindowPrivate)
+ SYMFUNC(AllocateWindowPrivateIndex)
+ SYMFUNC(AllocateScreenPrivateIndex)
+ /* resource.c */
+ SYMFUNC(AddResource)
+ SYMFUNC(ChangeResourceValue)
+ SYMFUNC(CreateNewResourceClass)
+ SYMFUNC(CreateNewResourceType)
+ SYMFUNC(FakeClientID)
+ SYMFUNC(FreeResource)
+ SYMFUNC(FreeResourceByType)
+ SYMFUNC(GetXIDList)
+ SYMFUNC(GetXIDRange)
+ SYMFUNC(LookupIDByType)
+ SYMFUNC(LookupIDByClass)
+ SYMFUNC(LegalNewID)
+ SYMFUNC(SecurityLookupIDByClass)
+ SYMFUNC(SecurityLookupIDByType)
+ /* swaprep.c */
+ SYMFUNC(CopySwap32Write)
+ SYMFUNC(Swap32Write)
+ SYMFUNC(SwapConnSetupInfo)
+ SYMFUNC(SwapConnSetupPrefix)
+ SYMFUNC(SwapShorts)
+ SYMFUNC(SwapLongs)
+ /* swapreq.c */
+ SYMFUNC(SwapColorItem)
+ /* tables.c */
+ SYMVAR(EventSwapVector)
+ /* window.c */
+ SYMFUNC(ChangeWindowAttributes)
+ SYMFUNC(CheckWindowOptionalNeed)
+ SYMFUNC(CreateUnclippedWinSize)
+ SYMFUNC(CreateWindow)
+ SYMFUNC(FindWindowWithOptional)
+ SYMFUNC(GravityTranslate)
+ SYMFUNC(MakeWindowOptional)
+ SYMFUNC(MapWindow)
+ SYMFUNC(MoveWindowInStack)
+ SYMFUNC(NotClippedByChildren)
+ SYMFUNC(ResizeChildrenWinSize)
+ SYMFUNC(SaveScreens)
+ SYMFUNC(SendVisibilityNotify)
+ SYMFUNC(SetWinSize)
+ SYMFUNC(SetBorderSize)
+ SYMFUNC(TraverseTree)
+ SYMFUNC(UnmapWindow)
+ SYMFUNC(WalkTree)
+ SYMFUNC(WindowsRestructured)
+ SYMVAR(deltaSaveUndersViewable)
+ SYMVAR(numSaveUndersViewable)
+ SYMVAR(savedScreenInfo)
+ SYMVAR(screenIsSaved)
+
+ /*os/ */
+ /* access.c */
+ SYMFUNC(LocalClient)
+ /* util.c */
+ SYMFUNC(Error)
+ SYMFUNC(ErrorF)
+ SYMFUNC(FatalError)
+ SYMFUNC(Xstrdup)
+ SYMVAR(Must_have_memory)
+ /* xalloc.c */
+ SYMFUNC(XNFalloc)
+ SYMFUNC(XNFcalloc)
+ SYMFUNC(XNFrealloc)
+ SYMFUNC(Xalloc)
+ SYMFUNC(Xcalloc)
+ SYMFUNC(Xfree)
+ SYMFUNC(Xrealloc)
+ /* WaitFor.c */
+ SYMFUNC(ScreenSaverTime)
+ SYMFUNC(TimerFree)
+ SYMFUNC(TimerSet)
+ SYMFUNC(TimerCancel)
+ /* io.c */
+ SYMFUNC(WriteToClient)
+ SYMFUNC(SetCriticalOutputPending)
+ SYMVAR(FlushCallback)
+ SYMVAR(ReplyCallback)
+ SYMVAR(SkippedRequestsCallback)
+ SYMFUNC(ResetCurrentRequest)
+ /* connection.c */
+ SYMFUNC(IgnoreClient)
+ SYMFUNC(AttendClient)
+ SYMFUNC(AddEnabledDevice)
+ SYMFUNC(RemoveEnabledDevice)
+ SYMVAR(GrabInProgress)
+ /* utils.c */
+ SYMFUNC(AdjustWaitForDelay)
+ SYMVAR(noTestExtensions)
+
+#ifdef XINPUT
+ /* Xi */
+ /* exevents.c */
+ SYMFUNC(InitValuatorAxisStruct)
+ SYMFUNC(InitProximityClassDeviceStruct)
+ /* extinit.c */
+ SYMFUNC(AssignTypeAndName)
+#endif
+
+#ifdef XFreeXDGA
+ /* xf86DGA.c */
+ SYMVAR(XDGAEventBase)
+#endif
+
+ /* libfont.a */
+ SYMFUNC(GetGlyphs)
+ SYMFUNC(QueryGlyphExtents)
+
+ /* libXext.a */
+ SYMFUNC(ClientSleepUntil)
+
+
+ { 0, 0 },
+
+};
diff --git a/xc/programs/Xserver/hw/xfree86/loader/dlloader.c b/xc/programs/Xserver/hw/xfree86/loader/dlloader.c
new file mode 100644
index 000000000..166af54ef
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/dlloader.c
@@ -0,0 +1,190 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/dlloader.c,v 1.10 1999/01/14 13:04:54 dawes Exp $ */
+
+
+/*
+ *
+ * Copyright (c) 1997 The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * XFree86 Project, Inc. not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission. The Xfree86 Project, Inc. makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE XFREE86 PROJECT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE XFREE86 PROJECT, INC. 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 <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+
+#include "Xos.h"
+#include "os.h"
+
+#include "sym.h"
+#include "loader.h"
+#include "dlloader.h"
+
+#ifdef DL_LAZY
+#define DLOPEN_LAZY DL_LAZY
+#else
+#ifdef RTLD_LAZY
+#define DLOPEN_LAZY RTLD_LAZY
+#else
+#ifdef __FreeBSD__
+#define DLOPEN_LAZY 1
+#else
+#define DLOPEN_LAZY 0
+#endif
+#endif
+#endif
+#ifdef LD_GLOBAL
+#define DLOPEN_GLOBAL LD_GLOBAL
+#else
+#ifdef RTLD_GLOBAL
+#define DLOPEN_GLOBAL RTLD_GLOBAL
+#else
+#define DLOPEN_GLOBAL 0
+#endif
+#endif
+
+#define DLOPEN_FLAGS ( DLOPEN_LAZY | DLOPEN_GLOBAL )
+
+#if defined(CSRG_BASED) && !defined(__ELF__)
+#define NEED_UNDERSCORE_FOR_DLLSYM
+#endif
+
+/*
+ * This structure contains all of the information about a module
+ * that has been loaded.
+ */
+typedef struct {
+ int handle;
+ void *dlhandle;
+} DLModuleRec, *DLModulePtr;
+
+/*
+ * a list of loaded modules XXX can be improved
+ */
+typedef struct DLModuleList {
+ DLModulePtr module;
+ struct DLModuleList *next;
+} DLModuleList;
+
+DLModuleList *dlModuleList = NULL;
+
+/*
+ * Search a symbol in the module list
+ */
+void *
+DLFindSymbol(const char *name)
+{
+ DLModuleList *l;
+ void *p;
+
+#ifdef NEED_UNDERSCORE_FOR_DLLSYM
+ char *n;
+
+ n = xf86loadermalloc(strlen(name) + 2);
+ sprintf(n, "_%s", name);
+#endif
+
+ for (l = dlModuleList; l != NULL; l = l->next) {
+#ifdef NEED_UNDERSCORE_FOR_DLLSYM
+ p = dlsym(l->module->dlhandle, n);
+#else
+ p = dlsym(l->module->dlhandle, name);
+#endif
+ if (p != NULL) {
+#ifdef NEED_UNDERSCORE_FOR_DLLSYM
+ xf86loaderfree(n);
+#endif
+ return p;
+ }
+ }
+#ifdef NEED_UNDERSCORE_FOR_DLLSYM
+ xf86loaderfree(n);
+#endif
+
+ return NULL;
+}
+
+/*
+ * public interface
+ */
+void *
+DLLoadModule(loaderPtr modrec, int fd, LOOKUP **ppLookup)
+{
+ DLModulePtr dlfile;
+ DLModuleList *l;
+
+ if ((dlfile=xf86loadercalloc(1,sizeof(DLModuleRec)))==NULL) {
+ ErrorF("Unable to allocate DLModuleRec\n");
+ return NULL;
+ }
+ dlfile->handle = modrec->handle;
+ dlfile->dlhandle = dlopen(modrec->name, DLOPEN_FLAGS);
+ if (dlfile->dlhandle == NULL) {
+ ErrorF("dlopen: %s\n", dlerror());
+ xf86loaderfree(dlfile);
+ return NULL;
+ }
+ /* Add it to the module list */
+ l = xf86loadermalloc(sizeof(DLModuleList));
+ l->module = dlfile;
+ l->next = dlModuleList;
+ dlModuleList = l;
+ *ppLookup = NULL;
+
+ return (void *)dlfile;
+}
+
+void
+DLResolveSymbols(void *mod)
+{
+ return;
+}
+
+int
+DLCheckForUnresolved(void *mod)
+{
+ return 0;
+}
+
+void
+DLUnloadModule(void *modptr)
+{
+ DLModulePtr dlfile = (DLModulePtr)modptr;
+ DLModuleList *l, *p;
+
+ /* remove it from dlModuleList */
+ if (dlModuleList->module == modptr) {
+ l = dlModuleList;
+ dlModuleList = l->next;
+ xf86loaderfree(l);
+ } else {
+ p = dlModuleList;
+ for (l = dlModuleList->next; l != NULL; l = l->next) {
+ if (l->module == modptr) {
+ p->next = l->next;
+ xf86loaderfree(l);
+ break;
+ }
+ p = l;
+ }
+ }
+ dlclose(dlfile->dlhandle);
+ xf86loaderfree(modptr);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/loader/dlloader.h b/xc/programs/Xserver/hw/xfree86/loader/dlloader.h
new file mode 100644
index 000000000..e9468e97b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/dlloader.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 1997 Metro Link, Inc.
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/dlloader.h,v 1.3 1998/09/20 14:41:04 dawes Exp $ */
+
+#ifndef _DLLOADER_H
+#define _DLLOADER_H
+extern void *DLLoadModule(loaderPtr, int, LOOKUP **);
+extern void DLResolveSymbols(void *);
+extern int DLCheckForUnresolved(void *);
+extern void DLUnloadModule(void *);
+extern void *DLFindSymbol(const char *name);
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/loader/elf.h b/xc/programs/Xserver/hw/xfree86/loader/elf.h
new file mode 100644
index 000000000..a25a04650
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/elf.h
@@ -0,0 +1,570 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/elf.h,v 1.7 1999/03/21 07:35:20 dawes Exp $ */
+
+
+typedef unsigned long Elf32_Addr;
+typedef unsigned short Elf32_Half;
+typedef unsigned long Elf32_Off;
+typedef long Elf32_Sword;
+typedef unsigned long Elf32_Word;
+
+typedef unsigned long Elf64_Addr;
+typedef unsigned short Elf64_Half;
+typedef unsigned long Elf64_Off;
+typedef int Elf64_Sword;
+typedef unsigned int Elf64_Word;
+typedef unsigned long Elf64_Xword;
+typedef long Elf64_Sxword;
+
+/* These constants are for the segment types stored in the image headers */
+#define PT_NULL 0
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_LOPROC 0x70000000
+#define PT_HIPROC 0x7fffffff
+
+/* These constants define the different elf file types */
+#define ET_NONE 0
+#define ET_REL 1
+#define ET_EXEC 2
+#define ET_DYN 3
+#define ET_CORE 4
+#define ET_LOPROC 5
+#define ET_HIPROC 6
+
+/* These constants define the various ELF target machines */
+#define EM_NONE 0
+#define EM_M32 1
+#define EM_SPARC 2
+#define EM_386 3
+#define EM_68K 4
+#define EM_88K 5
+#define EM_486 6 /* Perhaps disused */
+#define EM_860 7
+#define EM_MIPS 8
+#define EM_MIPS_RS4_BE 10
+#define EM_PARISC 15
+#define EM_SPARC32PLUS 18
+#define EM_PPC 20
+#define EM_SPARCV9 43
+#define EM_ALPHA 0x9026
+
+/* This is the info that is needed to parse the dynamic section of the file */
+#define DT_NULL 0
+#define DT_NEEDED 1
+#define DT_PLTRELSZ 2
+#define DT_PLTGOT 3
+#define DT_HASH 4
+#define DT_STRTAB 5
+#define DT_SYMTAB 6
+#define DT_RELA 7
+#define DT_RELASZ 8
+#define DT_RELAENT 9
+#define DT_STRSZ 10
+#define DT_SYMENT 11
+#define DT_INIT 12
+#define DT_FINI 13
+#define DT_SONAME 14
+#define DT_RPATH 15
+#define DT_SYMBOLIC 16
+#define DT_REL 17
+#define DT_RELSZ 18
+#define DT_RELENT 19
+#define DT_PLTREL 20
+#define DT_DEBUG 21
+#define DT_TEXTREL 22
+#define DT_JMPREL 23
+#define DT_LOPROC 0x70000000
+#define DT_HIPROC 0x7fffffff
+
+/* This info is needed when parsing the symbol table */
+#define STB_LOCAL 0
+#define STB_GLOBAL 1
+#define STB_WEAK 2
+
+#define STT_NOTYPE 0
+#define STT_OBJECT 1
+#define STT_FUNC 2
+#define STT_SECTION 3
+#define STT_FILE 4
+#define STT_LOPROC 13
+#define STT_HIPROC 15
+
+#define ELF32_ST_BIND(x) ((x) >> 4)
+#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
+
+#define ELF64_ST_BIND(x) ELF32_ST_BIND (x)
+#define ELF64_ST_TYPE(x) ELF32_ST_TYPE (x)
+
+typedef struct dynamic32 {
+ Elf32_Sword d_tag;
+ union{
+ Elf32_Sword d_val;
+ Elf32_Addr d_ptr;
+ } d_un;
+} Elf32_Dyn;
+
+typedef struct dynamic64 {
+ Elf64_Sxword d_tag;
+ union{
+ Elf64_Xword d_val;
+ Elf64_Addr d_ptr;
+ } d_un;
+} Elf64_Dyn;
+
+extern Elf32_Dyn _DYNAMIC [];
+
+/* The following are used with relocations */
+#define ELF32_R_SYM(x) ((x) >> 8)
+#define ELF32_R_TYPE(x) ((x) & 0xff)
+
+#define ELF64_R_SYM(x) ((x) >> 32)
+#define ELF64_R_TYPE(x) ((x) & 0xffffffff)
+
+/* x86 Relocation Types */
+#define R_386_NONE 0
+#define R_386_32 1
+#define R_386_PC32 2
+#define R_386_GOT32 3
+#define R_386_PLT32 4
+#define R_386_COPY 5
+#define R_386_GLOB_DAT 6
+#define R_386_JMP_SLOT 7
+#define R_386_RELATIVE 8
+#define R_386_GOTOFF 9
+#define R_386_GOTPC 10
+#define R_386_NUM 11
+
+/* sparc Relocation Types */
+#define R_SPARC_NONE 0
+#define R_SPARC_8 1
+#define R_SPARC_16 2
+#define R_SPARC_32 3
+#define R_SPARC_DISP8 4
+#define R_SPARC_DISP16 5
+#define R_SPARC_DISP32 6
+#define R_SPARC_WDISP30 7
+#define R_SPARC_WDISP22 8
+#define R_SPARC_HI22 9
+#define R_SPARC_22 10
+#define R_SPARC_13 11
+#define R_SPARC_LO10 12
+#define R_SPARC_GOT10 13
+#define R_SPARC_GOT13 14
+#define R_SPARC_GOT22 15
+#define R_SPARC_PC10 16
+#define R_SPARC_PC22 17
+#define R_SPARC_WPLT30 18
+#define R_SPARC_COPY 19
+#define R_SPARC_GLOB_DAT 20
+#define R_SPARC_JMP_SLOT 21
+#define R_SPARC_RELATIVE 22
+#define R_SPARC_UA32 23
+#define R_SPARC_PLT32 24
+#define R_SPARC_HIPLT22 25
+#define R_SPARC_LOPLT10 26
+#define R_SPARC_PCPLT32 27
+#define R_SPARC_PCPLT22 28
+#define R_SPARC_PCPLT10 29
+#define R_SPARC_10 30
+#define R_SPARC_11 31
+#define R_SPARC_WDISP16 40
+#define R_SPARC_WDISP19 41
+#define R_SPARC_7 43
+#define R_SPARC_5 44
+#define R_SPARC_6 45
+
+/* m68k Relocation Types */
+#define R_68K_NONE 0 /* No reloc */
+#define R_68K_32 1 /* Direct 32 bit */
+#define R_68K_16 2 /* Direct 16 bit */
+#define R_68K_8 3 /* Direct 8 bit */
+#define R_68K_PC32 4 /* PC relative 32 bit */
+#define R_68K_PC16 5 /* PC relative 16 bit */
+#define R_68K_PC8 6 /* PC relative 8 bit */
+#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */
+#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */
+#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */
+#define R_68K_GOT32O 10 /* 32 bit GOT offset */
+#define R_68K_GOT16O 11 /* 16 bit GOT offset */
+#define R_68K_GOT8O 12 /* 8 bit GOT offset */
+#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */
+#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */
+#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */
+#define R_68K_PLT32O 16 /* 32 bit PLT offset */
+#define R_68K_PLT16O 17 /* 16 bit PLT offset */
+#define R_68K_PLT8O 18 /* 8 bit PLT offset */
+#define R_68K_COPY 19 /* Copy symbol at runtime */
+#define R_68K_GLOB_DAT 20 /* Create GOT entry */
+#define R_68K_JMP_SLOT 21 /* Create PLT entry */
+#define R_68K_RELATIVE 22 /* Adjust by program base */
+
+/* Alpha Relocation Types */
+#define R_ALPHA_NONE 0 /* No reloc */
+#define R_ALPHA_REFLONG 1 /* Direct 32 bit */
+#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */
+#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */
+#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */
+#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */
+#define R_ALPHA_GPDISP 6 /* Add displacement to GP */
+#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */
+#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */
+#define R_ALPHA_SREL16 9 /* PC relative 16 bit */
+#define R_ALPHA_SREL32 10 /* PC relative 32 bit */
+#define R_ALPHA_SREL64 11 /* PC relative 64 bit */
+#define R_ALPHA_OP_PUSH 12 /* OP stack push */
+#define R_ALPHA_OP_STORE 13 /* OP stack pop and store */
+#define R_ALPHA_OP_PSUB 14 /* OP stack subtract */
+#define R_ALPHA_OP_PRSHIFT 15 /* OP stack right shift */
+#define R_ALPHA_GPVALUE 16
+#define R_ALPHA_GPRELHIGH 17
+#define R_ALPHA_GPRELLOW 18
+#define R_ALPHA_IMMED_GP_16 19
+#define R_ALPHA_IMMED_GP_HI32 20
+#define R_ALPHA_IMMED_SCN_HI32 21
+#define R_ALPHA_IMMED_BR_HI32 22
+#define R_ALPHA_IMMED_LO32 23
+#define R_ALPHA_COPY 24 /* Copy symbol at runtime */
+#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */
+#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */
+#define R_ALPHA_RELATIVE 27 /* Adjust by program base */
+
+/*
+ * Apparantly, Linux and PowerMAXOS use different version of ELF as the
+ * Relocation types are very different.
+ */
+#if defined(PowerMAX_OS)
+/* PPC Relocation Types */
+#define R_PPC_NONE 0
+#define R_PPC_COPY 1
+#define R_PPC_GOTP_ENT 2
+#define R_PPC_8 4
+#define R_PPC_8S 5
+#define R_PPC_16S 7
+#define R_PPC_14 8
+#define R_PPC_DISP14 9
+#define R_PPC_24 10
+#define R_PPC_DISP24 11
+#define R_PPC_PLT_DISP24 14
+#define R_PPC_BBASED_16HU 15
+#define R_PPC_BBASED_32 16
+#define R_PPC_BBASED_32UA 17
+#define R_PPC_BBASED_16H 18
+#define R_PPC_BBASED_16L 19
+#define R_PPC_ABDIFF_16HU 23
+#define R_PPC_ABDIFF_32 24
+#define R_PPC_ABDIFF_32UA 25
+#define R_PPC_ABDIFF_16H 26
+#define R_PPC_ABDIFF_16L 27
+#define R_PPC_ABDIFF_16 28
+#define R_PPC_16HU 31
+#define R_PPC_32 32
+#define R_PPC_32UA 33
+#define R_PPC_16H 34
+#define R_PPC_16L 35
+#define R_PPC_16 36
+#define R_PPC_GOT_16HU 39
+#define R_PPC_GOT_32 40
+#define R_PPC_GOT_32UA 41
+#define R_PPC_GOT_16H 42
+#define R_PPC_GOT_16L 43
+#define R_PPC_GOT_16 44
+#define R_PPC_GOTP_16HU 47
+#define R_PPC_GOTP_32 48
+#define R_PPC_GOTP_32UA 49
+#define R_PPC_GOTP_16H 50
+#define R_PPC_GOTP_16L 51
+#define R_PPC_GOTP_16 52
+#define R_PPC_PLT_16HU 55
+#define R_PPC_PLT_32 56
+#define R_PPC_PLT_32UA 57
+#define R_PPC_PLT_16H 58
+#define R_PPC_PLT_16L 59
+#define R_PPC_PLT_16 60
+#define R_PPC_ABREL_16HU 63
+#define R_PPC_ABREL_32 64
+#define R_PPC_ABREL_32UA 65
+#define R_PPC_ABREL_16H 66
+#define R_PPC_ABREL_16L 67
+#define R_PPC_ABREL_16 68
+#define R_PPC_GOT_ABREL_16HU 71
+#define R_PPC_GOT_ABREL_32 72
+#define R_PPC_GOT_ABREL_32UA 73
+#define R_PPC_GOT_ABREL_16H 74
+#define R_PPC_GOT_ABREL_16L 75
+#define R_PPC_GOT_ABREL_16 76
+#define R_PPC_GOTP_ABREL_16HU 79
+#define R_PPC_GOTP_ABREL_32 80
+#define R_PPC_GOTP_ABREL_32UA 81
+#define R_PPC_GOTP_ABREL_16H 82
+#define R_PPC_GOTP_ABREL_16L 83
+#define R_PPC_GOTP_ABREL_16 84
+#define R_PPC_PLT_ABREL_16HU 87
+#define R_PPC_PLT_ABREL_32 88
+#define R_PPC_PLT_ABREL_32UA 89
+#define R_PPC_PLT_ABREL_16H 90
+#define R_PPC_PLT_ABREL_16L 91
+#define R_PPC_PLT_ABREL_16 92
+#define R_PPC_SREL_16HU 95
+#define R_PPC_SREL_32 96
+#define R_PPC_SREL_32UA 97
+#define R_PPC_SREL_16H 98
+#define R_PPC_SREL_16L 99
+#else
+/*
+ * The Linux version
+ */
+#define R_PPC_NONE 0
+#define R_PPC_ADDR32 1
+#define R_PPC_ADDR24 2
+#define R_PPC_ADDR16 3
+#define R_PPC_ADDR16_LO 4
+#define R_PPC_ADDR16_HI 5
+#define R_PPC_ADDR16_HA 6
+#define R_PPC_ADDR14 7
+#define R_PPC_ADDR14_BRTAKEN 8
+#define R_PPC_ADDR14_BRNTAKEN 9
+#define R_PPC_REL24 10
+#define R_PPC_REL14 11
+#define R_PPC_REL14_BRTAKEN 12
+#define R_PPC_REL14_BRNTAKEN 13
+#define R_PPC_GOT16 14
+#define R_PPC_GOT16_LO 15
+#define R_PPC_GOT16_HI 16
+#define R_PPC_GOT16_HA 17
+#define R_PPC_PLTREL24 18
+#define R_PPC_COPY 19
+#define R_PPC_GLOB_DAT 20
+#define R_PPC_JMP_SLOT 21
+#define R_PPC_RELATIVE 22
+#define R_PPC_LOCAL24PC 23
+#define R_PPC_UADDR32 24
+#define R_PPC_UADDR16 25
+#define R_PPC_REL32 26
+#define R_PPC_PLT32 27
+#define R_PPC_PLTREL32 28
+#define R_PPC_PLT16_LO 29
+#define R_PPC_PLT16_HI 30
+#define R_PPC_PLT16_HA 31
+#define R_PPC_SDAREL16 32
+#define R_PPC_SECTOFF 33
+#define R_PPC_SECTOFF_LO 34
+#define R_PPC_SECTOFF_HI 35
+#define R_PPC_SECTOFF_HA 36
+#endif
+
+typedef struct elf32_rel {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+} Elf32_Rel;
+
+typedef struct elf64_rel {
+ Elf64_Addr r_offset;
+ Elf64_Xword r_info;
+} Elf64_Rel;
+
+typedef struct elf32_rela{
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+ Elf32_Sword r_addend;
+} Elf32_Rela;
+
+typedef struct elf64_rela{
+ Elf64_Addr r_offset;
+ Elf64_Xword r_info;
+ Elf64_Sxword r_addend;
+} Elf64_Rela;
+
+typedef struct elf32_sym{
+ Elf32_Word st_name;
+ Elf32_Addr st_value;
+ Elf32_Word st_size;
+ unsigned char st_info;
+ unsigned char st_other;
+ Elf32_Half st_shndx;
+} Elf32_Sym;
+
+typedef struct elf64_sym{
+ Elf64_Word st_name;
+ unsigned char st_info;
+ unsigned char st_other;
+ Elf64_Half st_shndx;
+ Elf64_Addr st_value;
+ Elf64_Xword st_size;
+} Elf64_Sym;
+
+#define EI_NIDENT 16
+
+typedef struct elf32hdr{
+ unsigned char e_ident[EI_NIDENT];
+ Elf32_Half e_type;
+ Elf32_Half e_machine;
+ Elf32_Word e_version;
+ Elf32_Addr e_entry; /* Entry point */
+ Elf32_Off e_phoff;
+ Elf32_Off e_shoff;
+ Elf32_Word e_flags;
+ Elf32_Half e_ehsize;
+ Elf32_Half e_phentsize;
+ Elf32_Half e_phnum;
+ Elf32_Half e_shentsize;
+ Elf32_Half e_shnum;
+ Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct elf64hdr {
+ unsigned char e_ident[EI_NIDENT];
+ Elf64_Half e_type;
+ Elf64_Half e_machine;
+ Elf64_Word e_version;
+ Elf64_Addr e_entry;
+ Elf64_Off e_phoff;
+ Elf64_Off e_shoff;
+ Elf64_Word e_flags;
+ Elf64_Half e_ehsize;
+ Elf64_Half e_phentsize;
+ Elf64_Half e_phnum;
+ Elf64_Half e_shentsize;
+ Elf64_Half e_shnum;
+ Elf64_Half e_shstrndx;
+} Elf64_Ehdr;
+
+/* These constants define the permissions on sections in the program
+ header, p_flags. */
+#define PF_R 0x4
+#define PF_W 0x2
+#define PF_X 0x1
+
+typedef struct elf_phdr{
+ Elf32_Word p_type;
+ Elf32_Off p_offset;
+ Elf32_Addr p_vaddr;
+ Elf32_Addr p_paddr;
+ Elf32_Word p_filesz;
+ Elf32_Word p_memsz;
+ Elf32_Word p_flags;
+ Elf32_Word p_align;
+} Elf32_Phdr;
+
+typedef struct
+{
+ Elf64_Word p_type;
+ Elf64_Word p_flags;
+ Elf64_Off p_offset;
+ Elf64_Addr p_vaddr;
+ Elf64_Addr p_paddr;
+ Elf64_Xword p_filesz;
+ Elf64_Xword p_memsz;
+ Elf64_Xword p_align;
+} Elf64_Phdr;
+
+/* sh_type */
+#define SHT_NULL 0
+#define SHT_PROGBITS 1
+#define SHT_SYMTAB 2
+#define SHT_STRTAB 3
+#define SHT_RELA 4
+#define SHT_HASH 5
+#define SHT_DYNAMIC 6
+#define SHT_NOTE 7
+#define SHT_NOBITS 8
+#define SHT_REL 9
+#define SHT_SHLIB 10
+#define SHT_DYNSYM 11
+#define SHT_NUM 12
+#define SHT_LOPROC 0x70000000
+#define SHT_HIPROC 0x7fffffff
+#define SHT_LOUSER 0x80000000
+#define SHT_HIUSER 0xffffffff
+
+/* sh_flags */
+#define SHF_WRITE 0x1
+#define SHF_ALLOC 0x2
+#define SHF_EXECINSTR 0x4
+#define SHF_MASKPROC 0xf0000000
+
+/* special section indexes */
+#define SHN_UNDEF 0
+#define SHN_LORESERVE 0xff00
+#define SHN_LOPROC 0xff00
+#define SHN_HIPROC 0xff1f
+#define SHN_ABS 0xfff1
+#define SHN_COMMON 0xfff2
+#define SHN_HIRESERVE 0xffff
+
+typedef struct {
+ Elf32_Word sh_name;
+ Elf32_Word sh_type;
+ Elf32_Word sh_flags;
+ Elf32_Addr sh_addr;
+ Elf32_Off sh_offset;
+ Elf32_Word sh_size;
+ Elf32_Word sh_link;
+ Elf32_Word sh_info;
+ Elf32_Word sh_addralign;
+ Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+typedef struct
+{
+ Elf64_Word sh_name;
+ Elf64_Word sh_type;
+ Elf64_Xword sh_flags;
+ Elf64_Addr sh_addr;
+ Elf64_Off sh_offset;
+ Elf64_Xword sh_size;
+ Elf64_Word sh_link;
+ Elf64_Word sh_info;
+ Elf64_Xword sh_addralign;
+ Elf64_Xword sh_entsize;
+} Elf64_Shdr;
+
+#define EI_MAG0 0 /* e_ident[] indexes */
+#define EI_MAG1 1
+#define EI_MAG2 2
+#define EI_MAG3 3
+#define EI_CLASS 4
+#define EI_DATA 5
+#define EI_VERSION 6
+#define EI_PAD 7
+
+#define ELFMAG0 0x7f /* EI_MAG */
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+#define ELFMAG "\177ELF"
+#define SELFMAG 4
+
+#define ELFDLMAG 3
+#define ELFDLOFF 16
+
+#define ELFCLASSNONE 0 /* EI_CLASS */
+#define ELFCLASS32 1
+#define ELFCLASS64 2
+#define ELFCLASSNUM 3
+
+#define ELFDATANONE 0 /* e_ident[EI_DATA] */
+#define ELFDATA2LSB 1
+#define ELFDATA2MSB 2
+
+#define EV_NONE 0 /* e_version, EI_VERSION */
+#define EV_CURRENT 1
+#define EV_NUM 2
+
+/* Notes used in ET_CORE */
+#define NT_PRSTATUS 1
+#define NT_PRFPREG 2
+#define NT_PRPSINFO 3
+#define NT_TASKSTRUCT 4
+
+/* Note header in a PT_NOTE section */
+typedef struct elf_note {
+ Elf32_Word n_namesz; /* Name size */
+ Elf32_Word n_descsz; /* Content size */
+ Elf32_Word n_type; /* Content type */
+} Elf32_Nhdr;
+
+#define ELF_START_MMAP 0x80000000
diff --git a/xc/programs/Xserver/hw/xfree86/loader/elfloader.c b/xc/programs/Xserver/hw/xfree86/loader/elfloader.c
new file mode 100644
index 000000000..248e8bcfb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/elfloader.c
@@ -0,0 +1,2320 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/elfloader.c,v 1.22 1999/08/22 05:57:38 dawes Exp $ */
+
+/*
+ *
+ * Copyright 1995-1998 by Metro Link, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. 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 <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#ifdef QNX
+#include <fcntl.h>
+#else
+#include <sys/fcntl.h>
+#endif
+#include <sys/stat.h>
+
+#ifdef DBMALLOC
+#include <debug/malloc.h>
+#define Xalloc(size) malloc(size)
+#define Xcalloc(size) calloc(1,(size))
+#define Xfree(size) free(size)
+#endif
+
+#include "Xos.h"
+#include "os.h"
+#include "elf.h"
+
+#include "sym.h"
+#include "loader.h"
+
+/*
+#ifndef LDTEST
+#define ELFDEBUG ErrorF
+#endif
+*/
+
+#if defined (__alpha__)
+typedef Elf64_Ehdr Elf_Ehdr;
+typedef Elf64_Shdr Elf_Shdr;
+typedef Elf64_Sym Elf_Sym;
+typedef Elf64_Rel Elf_Rel;
+typedef Elf64_Rela Elf_Rela;
+typedef Elf64_Addr Elf_Addr;
+#define ELF_ST_BIND ELF64_ST_BIND
+#define ELF_ST_TYPE ELF64_ST_TYPE
+#define ELF_R_SYM ELF64_R_SYM
+#define ELF_R_TYPE ELF64_R_TYPE
+/*
+ * The GOT is allocated dynamically. We need to keep a list of entries that
+ * have already been added to the GOT.
+ *
+ */
+typedef struct _elf_GOT {
+ Elf_Rela *rel;
+ int offset;
+ struct _elf_GOT *next;
+} ELFGotRec, *ELFGotPtr;
+
+#else
+typedef Elf32_Ehdr Elf_Ehdr;
+typedef Elf32_Shdr Elf_Shdr;
+typedef Elf32_Sym Elf_Sym;
+typedef Elf32_Rel Elf_Rel;
+typedef Elf32_Rela Elf_Rela;
+typedef Elf32_Addr Elf_Addr;
+#define ELF_ST_BIND ELF32_ST_BIND
+#define ELF_ST_TYPE ELF32_ST_TYPE
+#define ELF_R_SYM ELF32_R_SYM
+#define ELF_R_TYPE ELF32_R_TYPE
+#endif
+
+/*
+ * This structure contains all of the information about a module
+ * that has been loaded.
+ */
+
+typedef struct {
+ int handle;
+ int module;
+ int fd;
+ loader_funcs *funcs;
+ Elf_Ehdr *header;/* file header */
+ int numsh;
+ Elf_Shdr *sections;/* Address of the section header table */
+ int secsize; /* size of the section table */
+ unsigned char **saddr;/* Start addresss of the section pointer table */
+ unsigned char *shstraddr; /* Start address of the section header string table */
+ int shstrndx; /* index of the section header string table */
+ int shstrsize; /* size of the section header string table */
+ unsigned char *straddr; /* Start address of the string table */
+ int strndx; /* index of the string table */
+ int strsize; /* size of the string table */
+ unsigned char *text; /* Start address of the .text section */
+ int txtndx; /* index of the .text section */
+ int txtsize; /* size of the .text section */
+ unsigned char *data; /* Start address of the .data section */
+ int datndx; /* index of the .data section */
+ int datsize; /* size of the .data section */
+ unsigned char *data1; /* Start address of the .data1 section */
+ int dat1ndx; /* index of the .data1 section */
+ int dat1size; /* size of the .data1 section */
+ unsigned char *sdata; /* Start address of the .sdata section */
+ int sdatndx; /* index of the .sdata section */
+ int sdatsize; /* size of the .sdata section */
+ unsigned char *bss; /* Start address of the .bss section */
+ int bssndx; /* index of the .bss section */
+ int bsssize; /* size of the .bss section */
+ unsigned char *sbss; /* Start address of the .sbss section */
+ int sbssndx; /* index of the .sbss section */
+ int sbsssize; /* size of the .sbss section */
+ unsigned char *rodata; /* Start address of the .rodata section */
+ int rodatndx; /* index of the .rodata section */
+ int rodatsize; /* size of the .rodata section */
+ unsigned char *rodata1; /* Start address of the .rodata section */
+ int rodat1ndx; /* index of the .rodata section */
+ int rodat1size; /* size of the .rodata section */
+#if defined(__alpha__)
+ unsigned char *got; /* Start address of the .got section */
+ ELFGotPtr got_entries; /* List of entries in the .got section */
+ int gotndx; /* index of the .got section */
+ int gotsize; /* size of the .got section */
+#endif
+ Elf_Sym *symtab; /* Start address of the .symtab section */
+ int symndx; /* index of the .symtab section */
+ int symsize; /* size of the .symtab section */
+ unsigned char *reltext; /* Start address of the .rel.text section */
+ int reltxtndx; /* index of the .rel.text section */
+ int reltxtsize; /* size of the .rel.text section */
+ unsigned char *reldata; /* Start address of the .rel.data section */
+ int reldatndx; /* index of the .rel.data section */
+ int reldatsize; /* size of the .rel.data section */
+ unsigned char *relsdata;/* Start address of the .rel.sdata section */
+ int relsdatndx; /* index of the .rel.sdata section */
+ int relsdatsize; /* size of the .rel.sdata section */
+ unsigned char *relrodata;/* Start address of the .rel.rodata section */
+ int relrodatndx; /* index of the .rel.rodata section */
+ int relrodatsize; /* size of the .rel.rodata section */
+ unsigned char *common; /* Start address of the SHN_COMMON space */
+ int comsize; /* size of the SHN_COMMON space */
+ } ELFModuleRec, *ELFModulePtr;
+
+/*
+ * If a relocation is unable to be satisfied, then put it on a list
+ * to try later after more modules have been loaded.
+ */
+typedef struct _elf_reloc {
+#if defined(i386)
+ Elf_Rel *rel;
+#endif
+#if defined(__powerpc__) || defined(__mc68000__) || defined(__alpha__) || defined(__sparc__)
+ Elf_Rela *rel;
+#endif
+ ELFModulePtr file;
+ unsigned char *secp;
+ struct _elf_reloc *next;
+} ELFRelocRec;
+
+/*
+ * symbols with a st_shndx of COMMON need to have space allocated for them.
+ *
+ * Gather all of these symbols together, and allocate one chunk when we
+ * are done.
+ */
+typedef struct _elf_COMMON {
+ Elf_Sym *sym;
+ struct _elf_COMMON *next;
+} ELFCommonRec;
+
+static ELFCommonPtr listCOMMON=NULL;
+
+/* Prototypes for static functions */
+static int ELFhashCleanOut(void *, itemPtr);
+static char *ElfGetStringIndex(ELFModulePtr, int, int);
+static char *ElfGetString(ELFModulePtr, int);
+static char *ElfGetSectionName(ELFModulePtr, int);
+#if defined(__powerpc__) || defined(__mc68000__) || defined(__alpha__) || defined(__sparc__)
+static ELFRelocPtr ElfDelayRelocation(ELFModulePtr, unsigned char *, Elf_Rela *);
+#else
+static ELFRelocPtr ElfDelayRelocation(ELFModulePtr, unsigned char *, Elf_Rel *);
+#endif
+static ELFCommonPtr ElfAddCOMMON(Elf_Sym *);
+static LOOKUP *ElfCreateCOMMON(ELFModulePtr);
+static char *ElfGetSymbolNameIndex(ELFModulePtr, int, int);
+static char *ElfGetSymbolName(ELFModulePtr, int);
+static Elf_Addr ElfGetSymbolValue(ELFModulePtr, int);
+#if defined(__powerpc__) || defined(__mc68000__) || defined(__alpha__) || defined(__sparc__)
+static ELFRelocPtr Elf_RelocateEntry(ELFModulePtr, unsigned char *, Elf_Rela *, int);
+#else
+static ELFRelocPtr Elf_RelocateEntry(ELFModulePtr, unsigned char *, Elf_Rel *, int);
+#endif
+static ELFRelocPtr ELFCollectRelocations(ELFModulePtr, int);
+static LOOKUP *ELF_GetSymbols(ELFModulePtr);
+static void ELFCollectSections(ELFModulePtr);
+#if defined(__alpha__)
+static void ElfAddGOT(ELFModulePtr, Elf_Rela *);
+void ELFCreateGOT(ELFModulePtr);
+#endif
+
+/*
+ * Utility Functions
+ */
+
+
+static int
+ELFhashCleanOut(voidptr, item)
+void *voidptr;
+itemPtr item ;
+{
+ ELFModulePtr module = (ELFModulePtr) voidptr;
+ return (module->handle == item->handle);
+}
+
+/*
+ * Manage listResolv
+ */
+static ELFRelocPtr
+ElfDelayRelocation(elffile,secp,rel)
+ELFModulePtr elffile;
+unsigned char *secp;
+#if defined(i386)
+Elf_Rel *rel;
+#endif
+#if defined(__powerpc__) || defined(__mc68000__) || defined(__alpha__) || defined(__sparc__)
+Elf_Rela *rel;
+#endif
+{
+ ELFRelocPtr reloc;
+
+ if ((reloc = xf86loadermalloc(sizeof(ELFRelocRec))) == NULL) {
+ ErrorF( "ElfDelayRelocation() Unable to allocate memory!!!!\n" );
+ return 0;
+ }
+ reloc->file=elffile;
+ reloc->secp=secp;
+ reloc->rel=rel;
+ reloc->next=0;
+#ifdef ELFDEBUG
+ ELFDEBUG("ElfDelayRelocation %lx: file %lx, sec %lx, r_offset 0x%x, r_info 0x%x", reloc, elffile, secp, rel->r_offset, rel->r_info);
+#if defined(__powerpc__) || defined(__mc68000__) || defined(__alpha__) || defined(__sparc__)
+ ELFDEBUG(", r_addend 0x%x", rel->r_addend);
+#endif
+ ELFDEBUG("\n" );
+#endif
+ return reloc;
+}
+
+/*
+ * Manage listCOMMON
+ */
+static ELFCommonPtr
+ElfAddCOMMON(sym)
+Elf_Sym *sym;
+{
+ ELFCommonPtr common;
+
+ if ((common = xf86loadermalloc(sizeof(ELFCommonRec))) == NULL) {
+ ErrorF( "ElfAddCOMMON() Unable to allocate memory!!!!\n" );
+ return 0;
+ }
+ common->sym=sym;
+ common->next=0;
+ return common;
+}
+
+static LOOKUP *
+ElfCreateCOMMON(elffile)
+ELFModulePtr elffile;
+{
+ int numsyms=0,size=0,l=0;
+ int offset=0;
+ LOOKUP *lookup;
+ ELFCommonPtr common;
+
+ if (listCOMMON == NULL)
+ return NULL;
+
+ for (common = listCOMMON; common; common = common->next) {
+ size+=common->sym->st_size;
+#if defined(__alpha__)
+ size = (size+7)&~0x7;
+#endif
+ numsyms++;
+ }
+
+#ifdef ELFDEBUG
+ ELFDEBUG("ElfCreateCOMMON() %d entries (%d bytes) of COMMON data\n",
+ numsyms, size );
+#endif
+
+ if((lookup = xf86loadermalloc((numsyms+1)*sizeof(LOOKUP))) == NULL) {
+ ErrorF( "ElfCreateCOMMON() Unable to allocate memory!!!!\n" );
+ return 0;
+ }
+
+ elffile->comsize=size;
+ if((elffile->common = xf86loadercalloc(1,size)) == NULL) {
+ ErrorF( "ElfCreateCOMMON() Unable to allocate memory!!!!\n" );
+ return 0;
+ }
+
+ if (DebuggerPresent)
+ {
+ ldrCommons = xf86loadermalloc(numsyms*sizeof(LDRCommon));
+ nCommons = numsyms;
+ }
+ /* Traverse the common list and create a lookup table with all the
+ * common symbols. Destroy the common list in the process.
+ * See also ResolveSymbols.
+ */
+ while(listCOMMON) {
+ common=listCOMMON;
+ /* this is xstrdup because is should be more efficient. it is freed
+ * with xf86loaderfree
+ */
+ lookup[l].symName = xf86loaderstrdup(ElfGetString(elffile,common->sym->st_name));
+ lookup[l].offset = (funcptr)(elffile->common + offset);
+#ifdef ELFDEBUG
+ ELFDEBUG("Adding common %lx %s\n", lookup[l].offset, lookup[l].symName );
+#endif
+
+ /* Record the symbol address for gdb */
+ if (DebuggerPresent && ldrCommons)
+ {
+ ldrCommons[l].addr = (void *)lookup[l].offset;
+ ldrCommons[l].name = lookup[l].symName;
+ ldrCommons[l].namelen = strlen(lookup[l].symName);
+ }
+ listCOMMON=common->next;
+ offset+=common->sym->st_size;
+#if defined(__alpha__)
+ offset = (offset+7)&~0x7;
+#endif
+ xf86loaderfree(common);
+ l++;
+ }
+ /* listCOMMON == 0 */
+ lookup[l].symName=NULL; /* Terminate the list. */
+ return lookup;
+}
+
+
+/*
+ * String Table
+ */
+static char *
+ElfGetStringIndex(file, offset, index)
+ELFModulePtr file;
+int offset;
+int index;
+{
+ if( !offset || !index )
+ return "";
+
+ return (char *)(file->saddr[index]+offset);
+}
+
+static char *
+ElfGetString(file, offset)
+ELFModulePtr file;
+int offset;
+{
+ return ElfGetStringIndex( file, offset, file->strndx );
+}
+
+static char *
+ElfGetSectionName(file, offset)
+ELFModulePtr file;
+int offset;
+{
+ return (char *)(file->shstraddr+offset);
+}
+
+
+
+/*
+ * Symbol Table
+ */
+
+/*
+ * Get symbol name
+ */
+static char *
+ElfGetSymbolNameIndex(elffile, index, secndx)
+ELFModulePtr elffile;
+int index;
+int secndx;
+{
+ Elf_Sym *syms;
+
+#ifdef ELFDEBUG
+ ELFDEBUG("ElfGetSymbolNameIndex(%x,%x) ",index, secndx );
+#endif
+
+ syms=(Elf_Sym *)elffile->saddr[secndx];
+
+#ifdef ELFDEBUG
+ ELFDEBUG("%s ",ElfGetString(elffile, syms[index].st_name));
+ ELFDEBUG("%x %x ",ELF_ST_BIND(syms[index].st_info),
+ ELF_ST_TYPE(syms[index].st_info));
+ ELFDEBUG("%lx\n",syms[index].st_value);
+#endif
+
+ return ElfGetString(elffile,syms[index].st_name );
+}
+
+static char *
+ElfGetSymbolName(elffile, index)
+ELFModulePtr elffile;
+int index;
+{
+ char *name,*symname;
+ symname=ElfGetSymbolNameIndex( elffile, index, elffile->symndx );
+ if( symname == NULL )
+ return NULL;
+
+ name=xf86loadermalloc(strlen(symname)+1);
+ if (!name)
+ FatalError("ELFGetSymbolName: Out of memory\n");
+
+ strcpy(name,symname);
+
+ return name;
+}
+
+static Elf_Addr
+ElfGetSymbolValue(elffile, index)
+ELFModulePtr elffile;
+int index;
+{
+ Elf_Sym *syms;
+ Elf_Addr symval=0; /* value of the indicated symbol */
+ char *symname = NULL; /* name of symbol in relocation */
+ itemPtr symbol = NULL; /* name/value of symbol */
+
+ syms=(Elf_Sym *)elffile->saddr[elffile->symndx];
+
+ switch( ELF_ST_TYPE(syms[index].st_info) )
+ {
+ case STT_NOTYPE:
+ case STT_OBJECT:
+ case STT_FUNC:
+ switch( ELF_ST_BIND(syms[index].st_info) )
+ {
+ case STB_LOCAL:
+ symval=(Elf_Addr)(
+ elffile->saddr[syms[index].st_shndx]+
+ syms[index].st_value);
+ break;
+ case STB_GLOBAL:
+ case STB_WEAK: /* STB_WEAK seems like a hack to cover for
+ some other problem */
+ symname=
+ ElfGetString(elffile,syms[index].st_name);
+ symbol = LoaderHashFind(symname);
+ if( symbol == 0 ) {
+ return 0;
+ }
+ symval=(Elf_Addr)symbol->address;
+ break;
+ default:
+ symval=0;
+ ErrorF(
+ "ElfGetSymbolValue(), unhandled symbol scope %x\n",
+ ELF_ST_BIND(syms[index].st_info) );
+ break;
+ }
+#ifdef ELFDEBUG
+ ELFDEBUG( "%x\t", symbol );
+ ELFDEBUG( "%lx\t", symval );
+ ELFDEBUG( "%s\n", symname ? symname : "NULL");
+#endif
+ break;
+ case STT_SECTION:
+ symval=(Elf_Addr)elffile->saddr[syms[index].st_shndx];
+#ifdef ELFDEBUG
+ ELFDEBUG( "ST_SECTION %lx\n", symval );
+#endif
+ break;
+ case STT_FILE:
+ case STT_LOPROC:
+ case STT_HIPROC:
+ default:
+ symval=0;
+ ErrorF( "ElfGetSymbolValue(), unhandled symbol type %x\n",
+ ELF_ST_TYPE(syms[index].st_info) );
+ break;
+ }
+ return symval;
+}
+
+#if defined(__powerpc__)
+/*
+ * This function returns the address of a pseudo PLT routine which can
+ * be used to compute a function offset. This is needed because loaded
+ * modules have an offset from the .text section of greater than 24 bits.
+ * The code generated makes the assumption that all function entry points
+ * will be within a 24 bit offset (non-PIC code).
+ */
+static Elf_Addr
+ElfGetPltAddr(elffile, index)
+ELFModulePtr elffile;
+int index;
+{
+ Elf_Sym *syms;
+ Elf_Addr symval=0; /* value of the indicated symbol */
+ char *symname = NULL; /* name of symbol in relocation */
+ itemPtr symbol; /* name/value of symbol */
+
+ syms=(Elf_Sym *)elffile->saddr[elffile->symndx];
+
+ switch( ELF_ST_TYPE(syms[index].st_info) )
+ {
+ case STT_NOTYPE:
+ case STT_OBJECT:
+ case STT_FUNC:
+ switch( ELF_ST_BIND(syms[index].st_info) )
+ {
+ case STB_GLOBAL:
+ symname=
+ ElfGetString(elffile,syms[index].st_name);
+ symbol=LoaderHashFind(symname);
+ if( symbol == 0 )
+ return 0;
+/*
+ * Here we are building up a pseudo Plt function that can make a call to
+ * a function that has an offset greater than 24 bits. The following code
+ * is being used to implement this.
+
+ 1 00000000 .extern realfunc
+ 2 00000000 .global pltfunc
+ 3 00000000 pltfunc:
+ 4 00000000 3d 80 00 00 lis r12,hi16(realfunc)
+ 5 00000004 61 8c 00 00 ori r12,r12,lo16(realfunc)
+ 6 00000008 7d 89 03 a6 mtctr r12
+ 7 0000000c 4e 80 04 20 bctr
+
+ */
+
+ symbol->code.plt[0]=0x3d80; /* lis r12 */
+ symbol->code.plt[1]=(((Elf_Addr)symbol->address)&0xffff0000)>>16;
+ symbol->code.plt[2]=0x618c; /* ori r12,r12 */
+ symbol->code.plt[3]=(((Elf_Addr)symbol->address)&0xffff);
+ symbol->code.plt[4]=0x7d89; /* mtcr r12 */
+ symbol->code.plt[5]=0x03a6;
+ symbol->code.plt[6]=0x4e80; /* bctr */
+ symbol->code.plt[7]=0x0420;
+ symbol->address=(char *)&symbol->code.plt[0];
+ symval=(Elf_Addr)symbol->address;
+ ppc_flush_icache(&symbol->code.plt[0]);
+ ppc_flush_icache(&symbol->code.plt[6]);
+ break;
+ default:
+ symval=0;
+ ErrorF(
+ "ElfGetPltAddr(), unhandled symbol scope %x\n",
+ ELF_ST_BIND(syms[index].st_info) );
+ break;
+ }
+#ifdef ELFDEBUG
+ ELFDEBUG( "ElfGetPlt: symbol=%x\t", symbol );
+ ELFDEBUG( "newval=%x\t", symval );
+ ELFDEBUG( "name=\"%s\"\n", symname ? symname : "NULL");
+#endif
+ break;
+ case STT_SECTION:
+ case STT_FILE:
+ case STT_LOPROC:
+ case STT_HIPROC:
+ default:
+ symval=0;
+ ErrorF( "ElfGetPltAddr(), Unexpected symbol type %x",
+ ELF_ST_TYPE(syms[index].st_info) );
+ ErrorF( "for a Plt request\n" );
+ break;
+ }
+ return symval;
+}
+#endif /* __powerpc__ */
+
+#if defined(__alpha__)
+/*
+ * Manage GOT Entries
+ */
+static void
+ElfAddGOT(elffile,rel)
+ELFModulePtr elffile;
+Elf_Rela *rel;
+{
+ ELFGotPtr gotent;
+
+#ifdef ELFDEBUG
+ {
+ Elf_Sym *sym;
+ char *namestr;
+
+ sym=(Elf_Sym *)&(elffile->symtab[ELF_R_SYM(rel->r_info)]);
+ if( sym->st_name) {
+ ELFDEBUG("ElfAddGOT: Adding GOT entry for %s\n",
+ namestr=ElfGetSymbolName(elffile,ELF_R_SYM(rel->r_info)) );
+ xf86loaderfree(namestr);
+ }
+ else
+ ELFDEBUG("ElfAddGOT: Adding GOT entry for %s\n",
+ ElfGetSectionName(elffile,elffile->sections[sym->st_shndx].sh_name));
+ }
+#endif
+
+ for (gotent=elffile->got_entries;gotent;gotent=gotent->next) {
+ if ( ELF_R_SYM(gotent->rel->r_info) == ELF_R_SYM(rel->r_info) &&
+ gotent->rel->r_addend == rel->r_addend )
+ break;
+ }
+
+ if( gotent ) {
+#ifdef ELFDEBUG
+ ELFDEBUG("Entry already present in GOT\n");
+#endif
+ return;
+ }
+
+ if ((gotent = xf86loadermalloc(sizeof(ELFGotRec))) == NULL) {
+ ErrorF( "ElfAddGOT() Unable to allocate memory!!!!\n" );
+ return;
+ }
+
+#ifdef ELFDEBUG
+ ELFDEBUG("Entry added with offset %x\n",elffile->gotsize);
+#endif
+ gotent->rel=rel;
+ gotent->offset=elffile->gotsize;
+ gotent->next=elffile->got_entries;
+ elffile->got_entries=gotent;
+ elffile->gotsize+=8;
+ return ;
+}
+
+void
+ELFCreateGOT(elffile)
+ELFModulePtr elffile;
+{
+#ifdef ELFDEBUG
+ ELFDEBUG( "ELFCreateGOT: %x entries in the GOT\n", elffile->gotsize/8 );
+#endif
+
+#if ELFDEBUG
+ /*
+ * Hmmm. Someone is getting here without any got entries, but they
+ * may still have R_ALPHA_GPDISP relocations against the got.
+ */
+ if( elffile->gotsize == 0 )
+ ELFDEBUG( "Module %s doesn't have any GOT entries!\n",
+ _LoaderModuleToName(elffile->module) );
+#endif
+ if( elffile->gotsize == 0 ) elffile->gotsize=8;
+
+ if ((elffile->got = xf86loadermalloc(elffile->gotsize)) == NULL) {
+ ErrorF( "ELFCreateGOT() Unable to allocate memory!!!!\n" );
+ return;
+ }
+ elffile->sections[elffile->gotndx].sh_size=elffile->gotsize;
+#ifdef ELFDEBUG
+ ELFDEBUG( "ELFCreateGOT: GOT address %lx\n", elffile->got );
+#endif
+
+ return;
+}
+#endif
+
+/*
+ * Fix all of the relocations for the given section.
+ * If the argument 'force' is non-zero, then the relocation will be
+ * made even if the symbol can't be found (by substituting
+ * LoaderDefaultFunc) otherwise, the relocation will be deferred.
+ */
+static ELFRelocPtr
+Elf_RelocateEntry(elffile, secp, rel, force)
+ELFModulePtr elffile;
+unsigned char *secp; /* Begining of the target section */
+#if defined(i386)
+Elf_Rel *rel;
+#endif
+#if defined(__powerpc__) || defined(__mc68000__) || defined(__alpha__) || defined(__sparc__)
+Elf_Rela *rel;
+#endif
+int force;
+{
+ unsigned int *dest32; /* address of the 32 bit place being modified */
+#if defined(__powerpc__) || defined(__mc68000__) || defined(__sparc__)
+ unsigned short *dest16; /* address of the 16 bit place being modified */
+#endif
+#if defined(__sparc__)
+ unsigned char *dest8; /* address of the 8 bit place being modified */
+#endif
+#if defined(__alpha__)
+ unsigned int *dest32h; /* address of the high 32 bit place being modified */
+ unsigned long *dest64;
+#if 0 /* XXX unused */
+ unsigned long *gp=(unsigned long *)elffile->got+0x8000; /*
+ * location of the got table */
+#endif
+#endif
+ Elf_Addr symval; /* value of the indicated symbol */
+
+#ifdef ELFDEBUG
+#if defined(i386)
+ ELFDEBUG( "%lx %d %d\n", rel->r_offset,
+ ELF_R_SYM(rel->r_info),ELF_R_TYPE(rel->r_info) );
+#endif
+#if defined(__powerpc__) || defined(__mc68000__) || defined(__alpha__) || defined(__sparc__)
+ ELFDEBUG( "%x %d %d %x\n", rel->r_offset,
+ ELF_R_SYM(rel->r_info),ELF_R_TYPE(rel->r_info),
+ rel->r_addend );
+#endif
+#endif
+ if (ELF_R_SYM(rel->r_info)) {
+ symval = ElfGetSymbolValue(elffile, ELF_R_SYM(rel->r_info));
+ if (symval == 0) {
+ if (force) {
+ symval = (Elf_Addr) &LoaderDefaultFunc;
+ } else {
+#ifdef ELFDEBUG
+ char *namestr;
+ namestr = ElfGetSymbolName(elffile,ELF_R_SYM(rel->r_info));
+ ELFDEBUG("***Unable to resolve symbol %s\n", namestr);
+ xf86loaderfree(namestr);
+#endif
+ return ElfDelayRelocation(elffile,secp,rel);
+ }
+ }
+ }
+
+ switch( ELF_R_TYPE(rel->r_info) )
+ {
+#if defined(i386)
+ case R_386_32:
+ dest32=(unsigned int *)(secp+rel->r_offset);
+#ifdef ELFDEBUG
+ ELFDEBUG( "R_386_32\t");
+ ELFDEBUG( "dest32=%x\t", dest32 );
+ ELFDEBUG( "*dest32=%8.8lx\t", *dest32 );
+#endif
+ *dest32=symval+(*dest32); /* S + A */
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest32=%8.8lx\n", *dest32 );
+#endif
+ break;
+ case R_386_PC32:
+ dest32=(unsigned int *)(secp+rel->r_offset);
+#ifdef ELFDEBUG
+ {
+ char *namestr;
+ ELFDEBUG( "R_386_PC32 %s\t",
+ namestr=ElfGetSymbolName(elffile,ELF_R_SYM(rel->r_info)) );
+ xf86loaderfree(namestr);
+ ELFDEBUG( "secp=%x\t", secp );
+ ELFDEBUG( "symval=%lx\t", symval );
+ ELFDEBUG( "dest32=%x\t", dest32 );
+ ELFDEBUG( "*dest32=%8.8lx\t", *dest32 );
+ }
+#endif
+
+ *dest32=symval+(*dest32)-(Elf_Addr)dest32; /* S + A - P */
+
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest32=%8.8lx\n", *dest32 );
+#endif
+
+ break;
+#endif /* i386 */
+#if defined(__alpha__)
+ case R_ALPHA_NONE:
+ case R_ALPHA_LITUSE:
+ break;
+
+ case R_ALPHA_REFQUAD:
+ dest64=(unsigned long *)(secp+rel->r_offset);
+ symval=ElfGetSymbolValue(elffile,
+ ELF_R_SYM(rel->r_info));
+#ifdef ELFDEBUG
+ ELFDEBUG( "R_ALPHA_REFQUAD\t");
+ ELFDEBUG( "dest64=%lx\t", dest64 );
+ ELFDEBUG( "*dest64=%8.8lx\t", *dest64 );
+#endif
+ *dest64=symval+rel->r_addend+(*dest64); /* S + A + P */
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest64=%8.8lx\n", *dest64 );
+#endif
+ break;
+
+ case R_ALPHA_GPREL32:
+ {
+ dest64=(unsigned long *)(secp+rel->r_offset);
+ dest32=(unsigned int *)dest64;
+
+#ifdef ELFDEBUG
+ {
+ char *namestr;
+ ELFDEBUG( "R_ALPHA_GPREL32 %s\t",
+ namestr=ElfGetSymbolName(elffile,ELF_R_SYM(rel->r_info)) );
+ xf86loaderfree(namestr);
+ ELFDEBUG( "secp=%lx\t", secp );
+ ELFDEBUG( "symval=%lx\t", symval );
+ ELFDEBUG( "dest32=%lx\t", dest32 );
+ ELFDEBUG( "*dest32=%8.8x\t", *dest32 );
+ }
+#endif
+ symval += rel->r_addend;
+ symval = ((unsigned char *)symval)-((unsigned char *)elffile->got);
+#ifdef ELFDEBUG
+ ELFDEBUG( "symval=%lx\t", symval );
+#endif
+ if( (symval&0xffffffff00000000) != 0x0000000000000000 &&
+ (symval&0xffffffff00000000) != 0xffffffff00000000 ) {
+ FatalError("R_ALPHA_GPREL32 symval-got is too large for %s\n",
+ ElfGetSymbolName(elffile,ELF_R_SYM(rel->r_info)));
+ }
+
+ *dest32=symval;
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest32=%x\n", *dest32 );
+#endif
+ break;
+ }
+ case R_ALPHA_LITERAL:
+ {
+ ELFGotPtr gotent;
+ dest32=(unsigned int *)(secp+rel->r_offset);
+#ifdef ELFDEBUG
+ {
+ char *namestr;
+ ELFDEBUG( "R_ALPHA_LITERAL %s\t",
+ namestr=ElfGetSymbolName(elffile,ELF_R_SYM(rel->r_info)) );
+ xf86loaderfree(namestr);
+ ELFDEBUG( "secp=%lx\t", secp );
+ ELFDEBUG( "symval=%lx\t", symval );
+ ELFDEBUG( "dest32=%lx\t", dest32 );
+ ELFDEBUG( "*dest32=%8.8x\t", *dest32 );
+ }
+#endif
+
+ for (gotent=elffile->got_entries;gotent;gotent=gotent->next) {
+ if ( ELF_R_SYM(gotent->rel->r_info) == ELF_R_SYM(rel->r_info) &&
+ gotent->rel->r_addend == rel->r_addend )
+ break;
+ }
+
+ /* Set the address in the GOT */
+ if( gotent ) {
+ *(unsigned long *)(elffile->got+gotent->offset) =
+ symval+rel->r_addend;
+#ifdef ELFDEBUG
+ ELFDEBUG("Setting gotent[%x]=%lx\t",
+ gotent->offset, symval+rel->r_addend);
+#endif
+ if ((gotent->offset & 0xffff0000) != 0)
+ FatalError("\nR_ALPHA_LITERAL offset %x too large\n",
+ gotent->offset);
+ (*dest32)|=(gotent->offset); /* The address part is always 0 */
+ }
+ else {
+ unsigned long val;
+
+ /* S + A - P >> 2 */
+ val=((symval+(rel->r_addend)-(Elf_Addr)dest32));
+#ifdef ELFDEBUG
+ ELFDEBUG("S+A-P=%x\t",val);
+#endif
+ if( (val & 0xffff0000) != 0xffff0000 &&
+ (val & 0xffff0000) != 0x00000000 ) {
+ ErrorF("\nR_ALPHA_LITERAL offset %x too large\n", val);
+ break;
+ }
+ val &= 0x0000ffff;
+ (*dest32)|=(val); /* The address part is always 0 */
+ }
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+
+ break;
+ }
+
+ case R_ALPHA_GPDISP:
+ {
+ long offset;
+
+ dest32h=(unsigned int *)(secp+rel->r_offset);
+ dest32=(unsigned int *)((secp+rel->r_offset)+rel->r_addend);
+
+#ifdef ELFDEBUG
+ {
+ char *namestr;
+ ELFDEBUG( "R_ALPHA_GPDISP %s\t",
+ namestr=ElfGetSymbolName(elffile,ELF_R_SYM(rel->r_info)) );
+ xf86loaderfree(namestr);
+ ELFDEBUG( "secp=%lx\t", secp );
+ ELFDEBUG( "got=%lx\t", elffile->got );
+ ELFDEBUG( "gp=%lx\t", gp );
+ ELFDEBUG( "dest32=%lx\t", dest32 );
+ ELFDEBUG( "*dest32=%8.8x\t", *dest32 );
+ ELFDEBUG( "dest32h=%lx\t", dest32h );
+ ELFDEBUG( "*dest32h=%8.8x\t", *dest32h );
+ }
+#endif
+ if ((*dest32h >> 26) != 9 || (*dest32 >> 26) != 8) {
+ char *namestr;
+ ErrorF( "***Bad instructions in relocating %s\n",
+ namestr=ElfGetSymbolName(elffile,ELF_R_SYM(rel->r_info)) );
+ xf86loaderfree(namestr);
+ }
+
+ symval = (*dest32h & 0xffff) << 16 | (*dest32 & 0xffff);
+ symval = (symval ^ 0x80008000) - 0x80008000;
+
+ offset = ((unsigned char *)elffile->got - (unsigned char *)dest32h);
+#ifdef ELFDEBUG
+ ELFDEBUG( "symval=%lx\t", symval );
+ ELFDEBUG( "got-dest32=%lx\t", offset );
+#endif
+
+ if( (offset >= 0x7fff8000L) || (offset < -0x80000000L) ) {
+ FatalError( "Offset overflow for R_ALPHA_GPDISP\n");
+ }
+
+ symval += (unsigned long)offset;
+#ifdef ELFDEBUG
+ ELFDEBUG( "symval=%lx\t", symval );
+#endif
+ *dest32=(*dest32&0xffff0000) | (symval&0xffff);
+ *dest32h=(*dest32h&0xffff0000)|
+ (((symval>>16)+((symval>>15)&1))&0xffff);
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest32=%8.8x\t", *dest32 );
+ ELFDEBUG( "*dest32h=%8.8x\n", *dest32h );
+#endif
+ break;
+ }
+
+ case R_ALPHA_HINT:
+ dest32=(unsigned int *)((secp+rel->r_offset)+rel->r_addend);
+#ifdef ELFDEBUG
+ {
+ char *namestr;
+ ELFDEBUG( "R_ALPHA_HINT %s\t",
+ namestr=ElfGetSymbolName(elffile,ELF_R_SYM(rel->r_info)) );
+ xf86loaderfree(namestr);
+ ELFDEBUG( "secp=%lx\t", secp );
+ ELFDEBUG( "symval=%lx\t", symval );
+ ELFDEBUG( "dest32=%lx\t", dest32 );
+ ELFDEBUG( "*dest32=%8.8x\t", *dest32 );
+ }
+#endif
+
+#ifdef ELFDEBUG
+ ELFDEBUG( "symval=%lx\t", symval );
+#endif
+ symval -= (Elf_Addr)(((unsigned char *)dest32)+4);
+ if (symval % 4 ) {
+ ErrorF( "R_ALPHA_HINT bad alignment of offset\n");
+ }
+ symval=symval>>2;
+
+#ifdef ELFDEBUG
+ ELFDEBUG( "symval=%lx\t", symval );
+#endif
+
+ if( symval & 0xffff8000 ) {
+#ifdef ELFDEBUG
+ ELFDEBUG("R_ALPHA_HINT symval too large\n" );
+#endif
+ }
+
+ *dest32 = (*dest32&~0x3fff) | (symval&0x3fff);
+
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ break;
+
+#endif /* alpha */
+#if defined(__mc68000__)
+ case R_68K_32:
+ dest32=(unsigned long *)(secp+rel->r_offset);
+#ifdef ELFDEBUG
+ELFDEBUG( "R_68K_32\t", dest32 );
+ELFDEBUG( "dest32=%x\t", dest32 );
+ELFDEBUG( "*dest32=%8.8x\t", *dest32 );
+#endif
+ *dest32=symval+(*dest32); /* S + A */
+#ifdef ELFDEBUG
+ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ break;
+ case R_68K_PC32:
+ dest32=(unsigned long *)(secp+rel->r_offset);
+#ifdef ELFDEBUG
+char *namestr;
+ELFDEBUG( "R_68K_PC32 %s\t",
+ namestr=ElfGetSymbolName(elffile,ELF_R_SYM(rel->r_info)) );
+xf86loaderfree(namestr);
+ELFDEBUG( "secp=%x\t", secp );
+ELFDEBUG( "symval=%x\t", symval );
+ELFDEBUG( "dest32=%x\t", dest32 );
+ELFDEBUG( "*dest32=%8.8x\t", *dest32 );
+#endif
+
+ *dest32=symval+(*dest32)-(Elf_Addr)dest32; /* S + A - P */
+
+#ifdef ELFDEBUG
+ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+
+ break;
+#endif /* __mc68000__ */
+#if defined(__powerpc__)
+#if defined(PowerMAX_OS)
+ case R_PPC_DISP24: /* 11 */
+ dest32=(unsigned long *)(secp+rel->r_offset);
+#ifdef ELFDEBUG
+ ELFDEBUG( "R_PPC_DISP24 %s\t", ElfGetSymbolName(elffile,ELF_R_SYM(rel->r_info)) );
+ ELFDEBUG( "secp=%x\t", secp );
+ ELFDEBUG( "symval=%x\t", symval );
+ ELFDEBUG( "dest32=%x\t", dest32 );
+ ELFDEBUG( "*dest32=%8.8x\t", *dest32 );
+#endif
+
+ {
+ unsigned long val;
+
+ /* S + A - P >> 2 */
+ val=((symval+(rel->r_addend)-(Elf_Addr)dest32));
+#ifdef ELFDEBUG
+ ELFDEBUG("S+A-P=%x\t",val);
+#endif
+ val = val>>2;
+ if( (val & 0x3f000000) != 0x3f000000 &&
+ (val & 0x3f000000) != 0x00000000 ) {
+#ifdef ELFDEBUG
+ ELFDEBUG("R_PPC_DISP24 offset %x too large\n", val<<2);
+#endif
+ symval = ElfGetPltAddr(elffile,ELF_R_SYM(rel->r_info));
+ val=((symval+(rel->r_addend)-(Elf_Addr)dest32));
+#ifdef ELFDEBUG
+ ELFDEBUG("PLT offset is %x\n", val);
+#endif
+ val=val>>2;
+ if( (val & 0x3f000000) != 0x3f000000 &&
+ (val & 0x3f000000) != 0x00000000 )
+ FatalError("R_PPC_DISP24 PLT offset %x too large\n", val<<2);
+ }
+ val &= 0x00ffffff;
+ (*dest32)|=(val<<2); /* The address part is always 0 */
+ ppc_flush_icache(dest32);
+ }
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ break;
+ case R_PPC_16HU: /* 31 */
+ dest16=(unsigned short *)(secp+rel->r_offset);
+#ifdef ELFDEBUG
+ dest32=(unsigned long *)(dest16-1);
+
+#endif
+#ifdef ELFDEBUG
+ ELFDEBUG( "R_PPC_16HU\t" );
+ ELFDEBUG( "secp=%x\t", secp );
+ ELFDEBUG( "symval=%x\t", symval );
+ ELFDEBUG( "r_addend=%x\t", rel->r_addend );
+ ELFDEBUG( "dest16=%x\t", dest16 );
+ ELFDEBUG( "*dest16=%8.8x\t", *dest16 );
+ ELFDEBUG( "dest32=%8.8x\t", dest32 );
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ {
+ unsigned short val;
+ /* S + A */
+ val=((symval+(rel->r_addend))&0xffff0000)>>16;
+#ifdef ELFDEBUG
+ ELFDEBUG("uhi16(S+A)=%x\t",val);
+#endif
+ *dest16=val; /* S + A */
+ ppc_flush_icache(dest16);
+ }
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest16=%8.8x\t", *dest16 );
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ break;
+ case R_PPC_32: /* 32 */
+ dest32=(unsigned long *)(secp+rel->r_offset);
+#ifdef ELFDEBUG
+ ELFDEBUG( "R_PPC_32\t" );
+ ELFDEBUG( "secp=%x\t", secp );
+ ELFDEBUG( "symval=%x\t", symval );
+ ELFDEBUG( "r_addend=%x\t", rel->r_addend );
+ ELFDEBUG( "dest32=%8.8x\t", dest32 );
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ {
+ unsigned long val;
+ /* S + A */
+ val=symval+(rel->r_addend);
+#ifdef ELFDEBUG
+ ELFDEBUG("S+A=%x\t",val);
+#endif
+ *dest32=val; /* S + A */
+ ppc_flush_icache(dest32);
+ }
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ break;
+ case R_PPC_32UA: /* 33 */
+ dest32=(unsigned long *)(secp+rel->r_offset);
+#ifdef ELFDEBUG
+ ELFDEBUG( "R_PPC_32UA\t" );
+ ELFDEBUG( "secp=%x\t", secp );
+ ELFDEBUG( "symval=%x\t", symval );
+ ELFDEBUG( "r_addend=%x\t", rel->r_addend );
+ ELFDEBUG( "dest32=%8.8x\t", dest32 );
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ {
+ unsigned long val;
+ unsigned char *dest8 = (unsigned char *)dest32;
+ /* S + A */
+ val=symval+(rel->r_addend);
+#ifdef ELFDEBUG
+ ELFDEBUG("S+A=%x\t",val);
+#endif
+ *dest8++=(val&0xff000000)>>24;
+ *dest8++=(val&0x00ff0000)>>16;
+ *dest8++=(val&0x0000ff00)>> 8;
+ *dest8++=(val&0x000000ff);
+ ppc_flush_icache(dest32);
+ }
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ break;
+ case R_PPC_16H: /* 34 */
+ dest16=(unsigned short *)(secp+rel->r_offset);
+#ifdef ELFDEBUG
+ dest32=(unsigned long *)(dest16-1);
+#endif
+#ifdef ELFDEBUG
+ ELFDEBUG( "R_PPC_16H\t" );
+ ELFDEBUG( "secp=%x\t", secp );
+ ELFDEBUG( "symbol=%s\t", ElfGetSymbolName(elffile,ELF_R_SYM(rel->r_info)) );
+ ELFDEBUG( "symval=%x\t", symval );
+ ELFDEBUG( "r_addend=%x\t", rel->r_addend );
+ ELFDEBUG( "dest16=%x\t", dest16 );
+ ELFDEBUG( "*dest16=%8.8x\t", *dest16 );
+ ELFDEBUG( "dest32=%8.8x\t", dest32 );
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ {
+ unsigned short val;
+ unsigned short loval;
+ /* S + A */
+ val=((symval+(rel->r_addend))&0xffff0000)>>16;
+ loval=(symval+(rel->r_addend))&0xffff;
+ if( loval & 0x8000 ) {
+ /*
+ * This is hi16(), instead of uhi16(). Because of this,
+ * if the lo16() will produce a negative offset, then
+ * we have to increment this part of the address to get
+ * the correct final result.
+ */
+ val++;
+ }
+#ifdef ELFDEBUG
+ ELFDEBUG("hi16(S+A)=%x\t",val);
+#endif
+ *dest16=val; /* S + A */
+ ppc_flush_icache(dest16);
+ }
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest16=%8.8x\t", *dest16 );
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ break;
+ case R_PPC_16L: /* 35 */
+ dest16=(unsigned short *)(secp+rel->r_offset);
+#ifdef ELFDEBUG
+ dest32=(unsigned long *)(dest16-1);
+#endif
+#ifdef ELFDEBUG
+ ELFDEBUG( "R_PPC_16L\t" );
+ ELFDEBUG( "secp=%x\t", secp );
+ ELFDEBUG( "symval=%x\t", symval );
+ ELFDEBUG( "r_addend=%x\t", rel->r_addend );
+ ELFDEBUG( "dest16=%x\t", dest16 );
+ ELFDEBUG( "*dest16=%8.8x\t", *dest16 );
+ ELFDEBUG( "dest32=%8.8x\t", dest32 );
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ {
+ unsigned short val;
+ /* S + A */
+ val=(symval+(rel->r_addend))&0xffff;
+#ifdef ELFDEBUG
+ ELFDEBUG("lo16(S+A)=%x\t",val);
+#endif
+ *dest16=val; /* S + A */
+ ppc_flush_icache(dest16);
+ }
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest16=%8.8x\t", *dest16 );
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ break;
+#else
+ /* Linux PPC */
+ case R_PPC_ADDR32: /* 1 */
+ dest32=(unsigned long *)(secp+rel->r_offset);
+ symval=ElfGetSymbolValue(elffile,ELF_R_SYM(rel->r_info));
+#ifdef ELFDEBUG
+ ELFDEBUG( "R_PPC_ADDR32\t" );
+ ELFDEBUG( "secp=%x\t", secp );
+ ELFDEBUG( "symval=%x\t", symval );
+ ELFDEBUG( "r_addend=%x\t", rel->r_addend );
+ ELFDEBUG( "dest32=%8.8x\t", dest32 );
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ {
+ unsigned long val;
+ /* S + A */
+ val=symval+(rel->r_addend);
+#ifdef ELFDEBUG
+ ELFDEBUG("S+A=%x\t",val);
+#endif
+ *dest32=val; /* S + A */
+ ppc_flush_icache(dest32);
+ }
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ break;
+ case R_PPC_ADDR16_LO: /* 4 */
+ dest16=(unsigned short *)(secp+rel->r_offset);
+#ifdef ELFDEBUG
+ dest32=(unsigned long *)(dest16-1);
+#endif
+#ifdef ELFDEBUG
+ ELFDEBUG( "R_PPC_ADDR16_LO\t" );
+ ELFDEBUG( "secp=%x\t", secp );
+ ELFDEBUG( "symval=%x\t", symval );
+ ELFDEBUG( "r_addend=%x\t", rel->r_addend );
+ ELFDEBUG( "dest16=%x\t", dest16 );
+ ELFDEBUG( "*dest16=%8.8x\t", *dest16 );
+#endif
+ {
+ unsigned short val;
+ /* S + A */
+ val=(symval+(rel->r_addend))&0xffff;
+#ifdef ELFDEBUG
+ ELFDEBUG("lo16(S+A)=%x\t",val);
+#endif
+ *dest16=val; /* S + A */
+ ppc_flush_icache(dest16);
+ }
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest16=%8.8x\t", *dest16 );
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ break;
+ case R_PPC_ADDR16_HA: /* 6 */
+ dest16=(unsigned short *)(secp+rel->r_offset);
+#ifdef ELFDEBUG
+ dest32=(unsigned long *)(dest16-1);
+#endif
+#ifdef ELFDEBUG
+ ELFDEBUG( "R_PPC_ADDR16_HA\t" );
+ ELFDEBUG( "secp=%x\t", secp );
+ ELFDEBUG( "symval=%x\t", symval );
+ ELFDEBUG( "r_addend=%x\t", rel->r_addend );
+ ELFDEBUG( "dest16=%x\t", dest16 );
+ ELFDEBUG( "*dest16=%8.8x\t", *dest16 );
+#endif
+ {
+ unsigned short val;
+ unsigned short loval;
+ /* S + A */
+ val=((symval+(rel->r_addend))&0xffff0000)>>16;
+ loval=(symval+(rel->r_addend))&0xffff;
+ if( loval & 0x8000 ) {
+ /*
+ * This is hi16(), instead of uhi16(). Because of this,
+ * if the lo16() will produce a negative offset, then
+ * we have to increment this part of the address to get
+ * the correct final result.
+ */
+ val++;
+ }
+#ifdef ELFDEBUG
+ ELFDEBUG("hi16(S+A)=%x\t",val);
+#endif
+ *dest16=val; /* S + A */
+ ppc_flush_icache(dest16);
+ }
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest16=%8.8x\t", *dest16 );
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ break;
+ case R_PPC_REL24: /* 10 */
+ dest32=(unsigned long *)(secp+rel->r_offset);
+#ifdef ELFDEBUG
+ ELFDEBUG( "R_PPC_REL24 %s\t", ElfGetSymbolName(elffile,ELF_R_SYM(rel->r_info)) );
+ ELFDEBUG( "secp=%x\t", secp );
+ ELFDEBUG( "symval=%x\t", symval );
+ ELFDEBUG( "dest32=%x\t", dest32 );
+ ELFDEBUG( "*dest32=%8.8x\t", *dest32 );
+#endif
+
+ {
+ unsigned long val;
+
+ /* S + A - P >> 2 */
+ val=((symval+(rel->r_addend)-(Elf_Addr)dest32));
+#ifdef ELFDEBUG
+ ELFDEBUG("S+A-P=%x\t",val);
+#endif
+ val = val>>2;
+ if( (val & 0x3f000000) != 0x3f000000 &&
+ (val & 0x3f000000) != 0x00000000 ) {
+#ifdef ELFDEBUG
+ ELFDEBUG("R_PPC_REL24 offset %x too large\n", val<<2);
+#endif
+ symval = ElfGetPltAddr(elffile,ELF_R_SYM(rel->r_info));
+ val=((symval+(rel->r_addend)-(Elf_Addr)dest32));
+#ifdef ELFDEBUG
+ ELFDEBUG("PLT offset is %x\n", val);
+#endif
+ val=val>>2;
+ if( (val & 0x3f000000) != 0x3f000000 &&
+ (val & 0x3f000000) != 0x00000000 )
+ FatalError("R_PPC_REL24 PLT offset %x too large\n", val<<2);
+ }
+ val &= 0x00ffffff;
+ (*dest32)|=(val<<2); /* The address part is always 0 */
+ ppc_flush_icache(dest32);
+ }
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ break;
+ case R_PPC_REL32: /* 26 */
+ dest32=(unsigned long *)(secp+rel->r_offset);
+#ifdef ELFDEBUG
+ ELFDEBUG( "R_PPC_REL32\t" );
+ ELFDEBUG( "secp=%x\t", secp );
+ ELFDEBUG( "symval=%x\t", symval );
+ ELFDEBUG( "r_addend=%x\t", rel->r_addend );
+ ELFDEBUG( "dest32=%8.8x\t", dest32 );
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ {
+ unsigned long val;
+ /* S + A - P */
+ val=symval+(rel->r_addend);
+ val-=*dest32;
+#ifdef ELFDEBUG
+ ELFDEBUG("S+A=%x\t",val);
+ ELFDEBUG("S+A-P=%x\t",val+(*dest32)-(Elf_Addr)dest32);
+#endif
+ *dest32=val+(*dest32)-(Elf_Addr)dest32; /* S + A - P */
+ ppc_flush_icache(dest32);
+ }
+#ifdef ELFDEBUG
+ ELFDEBUG( "*dest32=%8.8x\n", *dest32 );
+#endif
+ break;
+#endif /* PowerMAX_OS */
+#endif /* __powerpc__ */
+#ifdef __sparc__
+ case R_SPARC_RELATIVE:
+ dest32 = (unsigned int *)(secp + rel->r_offset);
+ *dest32 += (unsigned int)secp + rel->r_addend;
+ break;
+
+ case R_SPARC_GLOB_DAT:
+ case R_SPARC_32:
+ dest32 = (unsigned int *)(secp + rel->r_offset);
+ symval += rel->r_addend;
+ *dest32 = symval;
+ break;
+
+ case R_SPARC_JMP_SLOT:
+ dest32 = (unsigned int *)(secp + rel->r_offset);
+ /* Before we change it the PLT entry looks like:
+ *
+ * pltent: sethi %hi(rela_plt_offset), %g1
+ * b,a PLT0
+ * nop
+ *
+ * We change it into:
+ *
+ * pltent: sethi %hi(rela_plt_offset), %g1
+ * sethi %hi(symval), %g1
+ * jmp %g1 + %lo(symval), %g0
+ */
+ symval += rel->r_addend;
+ dest32[2] = 0x81c06000 | (symval & 0x3ff);
+ __asm __volatile("flush %0 + 0x8" : : "r" (dest32));
+ dest32[1] = 0x03000000 | (symval >> 10);
+ __asm __volatile("flush %0 + 0x4" : : "r" (dest32));
+ break;
+
+ case R_SPARC_8:
+ dest8 = (unsigned char *)(secp + rel->r_offset);
+ symval += rel->r_addend;
+ *dest8 = symval;
+ break;
+
+ case R_SPARC_16:
+ dest16 = (unsigned short *)(secp + rel->r_offset);
+ symval += rel->r_addend;
+ *dest16 = symval;
+ break;
+
+ case R_SPARC_DISP8:
+ dest8 = (unsigned char *)(secp + rel->r_offset);
+ symval += rel->r_addend;
+ *dest8 = (symval - (Elf32_Addr) dest8);
+ break;
+
+ case R_SPARC_DISP16:
+ dest16 = (unsigned short *)(secp + rel->r_offset);
+ symval += rel->r_addend;
+ *dest16 = (symval - (Elf32_Addr) dest16);
+ break;
+
+ case R_SPARC_DISP32:
+ dest32 = (unsigned int *)(secp + rel->r_offset);
+ symval += rel->r_addend;
+ *dest32 = (symval - (Elf32_Addr) dest32);
+ break;
+
+ case R_SPARC_LO10:
+ dest32 = (unsigned int *)(secp + rel->r_offset);
+ symval += rel->r_addend;
+ *dest32 = (*dest32 & ~0x3ff) | (symval & 0x3ff);
+ break;
+
+ case R_SPARC_WDISP30:
+ dest32 = (unsigned int *)(secp + rel->r_offset);
+ symval += rel->r_addend;
+ *dest32 = ((*dest32 & 0xc0000000) |
+ ((symval - (Elf32_Addr) dest32) >> 2));
+ break;
+
+ case R_SPARC_HI22:
+ dest32 = (unsigned int *)(secp + rel->r_offset);
+ symval += rel->r_addend;
+ *dest32 = (*dest32 & 0xffc00000) | (symval >> 10);
+ break;
+
+ case R_SPARC_NONE:
+ break;
+
+ case R_SPARC_COPY:
+ /* Fix your code... I'd rather dish out an error here
+ * so people will not link together PIC and non-PIC
+ * code into a final driver object file.
+ */
+ ErrorF("Elf_RelocateEntry() Copy relocs not supported on Sparc.\n");
+ break;
+#endif
+ default:
+ ErrorF(
+ "Elf_RelocateEntry() Unsupported relocation type %d\n",
+ ELF_R_TYPE(rel->r_info) );
+ break;
+ }
+ return 0;
+}
+
+static ELFRelocPtr
+ELFCollectRelocations(elffile, index)
+ELFModulePtr elffile;
+int index; /* The section to use as relocation data */
+{
+ int i, numrel;
+ Elf_Shdr *sect=&(elffile->sections[index]);
+#if defined(i386)
+ Elf_Rel *rel=(Elf_Rel *)elffile->saddr[index];
+#endif
+#if defined(__powerpc__) || defined(__mc68000__) || defined(__alpha__) || defined(__sparc__)
+ Elf_Rela *rel=(Elf_Rela *)elffile->saddr[index];
+#endif
+ Elf_Sym *syms;
+ unsigned char *secp; /* Begining of the target section */
+ ELFRelocPtr reloc_head = NULL;
+ ELFRelocPtr tmp;
+
+ secp=(unsigned char *)elffile->saddr[sect->sh_info];
+ syms = (Elf_Sym *) elffile->saddr[elffile->symndx];
+
+ numrel=sect->sh_size/sect->sh_entsize;
+
+ for(i=0; i<numrel; i++ ) {
+#if defined(__alpha__)
+ if( ELF_R_TYPE(rel[i].r_info) == R_ALPHA_LITERAL) {
+ ElfAddGOT(elffile,&rel[i]);
+ }
+#endif
+ tmp = ElfDelayRelocation(elffile,secp,&(rel[i]));
+ tmp->next = reloc_head;
+ reloc_head = tmp;
+ }
+
+ return reloc_head;
+}
+
+/*
+ * ELF_GetSymbols()
+ *
+ * add the symbols to the symbol table maintained by the loader.
+ */
+
+static LOOKUP *
+ELF_GetSymbols(elffile)
+ELFModulePtr elffile;
+{
+ Elf_Sym *syms;
+ Elf_Shdr *sect;
+ int i, l, numsyms;
+ LOOKUP *lookup, *lookup_common, *p;
+ ELFCommonPtr tmp;
+
+ syms=elffile->symtab;
+ sect=&(elffile->sections[elffile->symndx]);
+ numsyms=sect->sh_size/sect->sh_entsize;
+
+ if ((lookup = xf86loadermalloc((numsyms+1)*sizeof(LOOKUP))) == NULL)
+ return 0;
+
+ for(i=0,l=0; i<numsyms; i++)
+ {
+#ifdef ELFDEBUG
+ ELFDEBUG("value=%lx\tsize=%lx\tBIND=%x\tTYPE=%x\tndx=%x\t%s\n",
+ syms[i].st_value,syms[i].st_size,
+ ELF_ST_BIND(syms[i].st_info),ELF_ST_TYPE(syms[i].st_info),
+ syms[i].st_shndx,ElfGetString(elffile,syms[i].st_name) );
+#endif
+
+ if( ELF_ST_BIND(syms[i].st_info) == STB_LOCAL )
+ /* Don't add static symbols to the symbol table */
+ continue;
+
+ switch( ELF_ST_TYPE(syms[i].st_info) )
+ {
+ case STT_OBJECT:
+ case STT_FUNC:
+ case STT_SECTION:
+ case STT_NOTYPE:
+ switch(syms[i].st_shndx)
+ {
+ case SHN_ABS:
+ ErrorF("ELF_GetSymbols() Don't know how to handle SHN_ABS\n" );
+ break;
+ case SHN_COMMON:
+#ifdef ELFDEBUG
+ ELFDEBUG("Adding COMMON space for %s\n",
+ ElfGetString(elffile,syms[i].st_name) );
+#endif
+ if (!LoaderHashFind(ElfGetString(elffile,
+ syms[i].st_name))) {
+ tmp = ElfAddCOMMON(&(syms[i]));
+ if (tmp) {
+ tmp->next = listCOMMON;
+ listCOMMON = tmp;
+ }
+ }
+ break;
+ case SHN_UNDEF:
+ /*
+ * UNDEF will get resolved later, so the value
+ * doesn't really matter here.
+ */
+ /* since we don't know the value don't advertise the symbol */
+ break;
+ default:
+ lookup[l].symName=xf86loaderstrdup(ElfGetString(elffile,syms[i].st_name));
+ lookup[l].offset=(funcptr)
+ (elffile->saddr[syms[i].st_shndx]+
+ syms[i].st_value);
+#ifdef ELFDEBUG
+ ELFDEBUG("Adding symbol %lx %s\n",
+ lookup[l].offset, lookup[l].symName );
+#endif
+ l++;
+ break;
+ }
+ break;
+ case STT_FILE:
+ case STT_LOPROC:
+ case STT_HIPROC:
+ /* Skip this type */
+#ifdef ELFDEBUG
+ ELFDEBUG("Skipping TYPE %d %s\n",
+ ELF_ST_TYPE(syms[i].st_info),
+ ElfGetString(elffile,syms[i].st_name));
+#endif
+ break;
+ default:
+ ErrorF("ELF_GetSymbols(): Unepected symbol type %d\n",
+ ELF_ST_TYPE(syms[i].st_info) );
+ break;
+ }
+ }
+
+ lookup[l].symName=NULL; /* Terminate the list */
+
+ lookup_common = ElfCreateCOMMON(elffile);
+ if (lookup_common) {
+ for (i = 0, p = lookup_common; p->symName; i++, p++)
+ ;
+ memcpy(&(lookup[l]), lookup_common, i * sizeof (LOOKUP));
+
+ xf86loaderfree(lookup_common);
+ l += i;
+ lookup[l].symName = NULL;
+ }
+
+
+/*
+ * Remove the ELF symbols that will show up in every object module.
+ */
+ for (i = 0, p = lookup; p->symName; i++, p++) {
+ while (!strcmp(lookup[i].symName, ".text")
+ || !strcmp(lookup[i].symName, ".data")
+ || !strcmp(lookup[i].symName, ".bss")
+ || !strcmp(lookup[i].symName, ".comment")
+ || !strcmp(lookup[i].symName, ".note")
+ ) {
+ memmove(&(lookup[i]), &(lookup[i+1]), (l-- - i) * sizeof (LOOKUP));
+ }
+ }
+ return lookup;
+}
+
+#define SecOffset(index) elffile->sections[index].sh_offset
+#define SecSize(index) elffile->sections[index].sh_size
+
+/*
+ * ELFCollectSections
+ *
+ * Do the work required to load each section into memory.
+ */
+static void
+ELFCollectSections(elffile)
+ELFModulePtr elffile;
+{
+ int i;
+
+/*
+ * Find and identify all of the Sections
+ */
+
+#ifdef ELFDEBUG
+ ELFDEBUG("%d sections\n", elffile->numsh );
+#endif
+
+ for( i=1; i<elffile->numsh; i++) {
+#ifdef ELFDEBUG
+ ELFDEBUG("%d %s\n", i, ElfGetSectionName(elffile, elffile->sections[i].sh_name) );
+#endif
+ /* .text */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".text" ) == 0 ) {
+ elffile->text=_LoaderFileToMem(elffile->fd,
+ SecOffset(i),SecSize(i),".text");
+ elffile->saddr[i]=elffile->text;
+ elffile->txtndx=i;
+ elffile->txtsize=SecSize(i);
+#ifdef ELFDEBUG
+ ELFDEBUG(".text starts at %lx\n", elffile->text );
+#endif
+ continue;
+ }
+ /* .data */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".data" ) == 0 ) {
+ elffile->data=_LoaderFileToMem(elffile->fd,
+ SecOffset(i),SecSize(i),".data");
+ elffile->saddr[i]=elffile->data;
+ elffile->datndx=i;
+ elffile->datsize=SecSize(i);
+#ifdef ELFDEBUG
+ ELFDEBUG(".data starts at %lx\n", elffile->data );
+#endif
+ continue;
+ }
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".data1" ) == 0 ) {
+ elffile->data1=_LoaderFileToMem(elffile->fd,
+ SecOffset(i),SecSize(i),".data1");
+ elffile->saddr[i]=elffile->data1;
+ elffile->dat1ndx=i;
+ elffile->dat1size=SecSize(i);
+#ifdef ELFDEBUG
+ELFDEBUG(".data1 starts at %lx\n", elffile->data1 );
+#endif
+ continue;
+ }
+ /* .sdata */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".sdata" ) == 0 ) {
+ elffile->sdata=_LoaderFileToMem(elffile->fd,
+ SecOffset(i),SecSize(i),".sdata");
+ elffile->saddr[i]=elffile->sdata;
+ elffile->sdatndx=i;
+ elffile->sdatsize=SecSize(i);
+#ifdef ELFDEBUG
+ ELFDEBUG(".sdata starts at %lx\n", elffile->sdata );
+#endif
+ continue;
+ }
+ /* .bss */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".bss" ) == 0 ) {
+ if( SecSize(i) )
+ elffile->bss = xf86loadercalloc(1, SecSize(i));
+ else
+ elffile->bss=NULL;
+ elffile->saddr[i]=elffile->bss;
+ elffile->bssndx=i;
+ elffile->bsssize=SecSize(i);
+#ifdef ELFDEBUG
+ ELFDEBUG(".bss starts at %lx\n", elffile->bss );
+#endif
+ continue;
+ }
+ /* .sbss */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".sbss" ) == 0 ) {
+ if( SecSize(i) )
+ elffile->sbss = xf86loadercalloc(1, SecSize(i));
+ else
+ elffile->sbss=NULL;
+ elffile->saddr[i]=elffile->sbss;
+ elffile->sbssndx=i;
+ elffile->sbsssize=SecSize(i);
+#ifdef ELFDEBUG
+ ELFDEBUG(".sbss starts at %lx\n", elffile->sbss );
+#endif
+ continue;
+ }
+ /* .rodata */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".rodata" ) == 0 ) {
+ elffile->rodata=_LoaderFileToMem(elffile->fd,
+ SecOffset(i),SecSize(i),".rodata");
+ elffile->saddr[i]=elffile->rodata;
+ elffile->rodatndx=i;
+ elffile->rodatsize=SecSize(i);
+#ifdef ELFDEBUG
+ ELFDEBUG(".rodata starts at %lx\n", elffile->rodata );
+#endif
+ continue;
+ }
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".rodata1" ) == 0 ) {
+ elffile->rodata1=_LoaderFileToMem(elffile->fd,
+ SecOffset(i),SecSize(i),".rodata1");
+ elffile->saddr[i]=elffile->rodata1;
+ elffile->rodat1ndx=i;
+ elffile->rodat1size=SecSize(i);
+#ifdef ELFDEBUG
+ELFDEBUG(".rodata1 starts at %lx\n", elffile->rodata1 );
+#endif
+ continue;
+ }
+ /* .symtab */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".symtab" ) == 0 ) {
+ elffile->symtab=(Elf_Sym *)_LoaderFileToMem(elffile->fd,
+ SecOffset(i),SecSize(i),".symtab");
+ elffile->saddr[i]=(unsigned char *)elffile->symtab;
+ elffile->symndx=i;
+ elffile->symsize=SecSize(i);
+#ifdef ELFDEBUG
+ ELFDEBUG(".symtab starts at %lx\n", elffile->symtab );
+#endif
+ continue;
+ }
+ /* .strtab */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".strtab" ) == 0 ) {
+ elffile->straddr=_LoaderFileToMem(elffile->fd,
+ SecOffset(i),SecSize(i),".strtab");
+ elffile->saddr[i]=(unsigned char *)elffile->straddr;
+ elffile->strndx=i;
+ elffile->strsize=SecSize(i);
+#ifdef ELFDEBUG
+ ELFDEBUG(".strtab starts at %lx\n", elffile->straddr );
+#endif
+ continue;
+ }
+#if defined(i386) || defined(__alpha__)
+ /* .rel.text */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".rel.text" ) == 0 ) {
+ elffile->reltext=_LoaderFileToMem(elffile->fd,
+ SecOffset(i),SecSize(i),".rel.text");
+ elffile->saddr[i]=(unsigned char *)elffile->reltext;
+ elffile->reltxtndx=i;
+ elffile->reltxtsize=SecSize(i);
+#ifdef ELFDEBUG
+ ELFDEBUG(".rel.text starts at %lx\n", elffile->reltext );
+#endif
+ continue;
+ }
+ /* .rel.data */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".rel.data" ) == 0 ) {
+ elffile->reldata=_LoaderFileToMem(elffile->fd,
+ SecOffset(i),SecSize(i),".rel.data");
+ elffile->saddr[i]=(unsigned char *)elffile->reldata;
+ elffile->reldatndx=i;
+ elffile->reldatsize=SecSize(i);
+#ifdef ELFDEBUG
+ ELFDEBUG(".rel.data starts at %lx\n", elffile->reldata );
+#endif
+ continue;
+ }
+ /* .rel.rodata */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".rel.rodata" ) == 0 ) {
+ elffile->relrodata=_LoaderFileToMem(elffile->fd,
+ SecOffset(i),SecSize(i),".rel.rodata");
+ elffile->saddr[i]=(unsigned char *)elffile->relrodata;
+ elffile->relrodatndx=i;
+ elffile->relrodatsize=SecSize(i);
+#ifdef ELFDEBUG
+ ELFDEBUG(".rel.rodata starts at %lx\n", elffile->relrodata );
+#endif
+ continue;
+ }
+#endif /* i386/alpha */
+#if defined(__powerpc__) || defined(__mc68000__) || defined(__alpha__) || defined(__sparc__)
+ /* .rela.text */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".rela.text" ) == 0 ) {
+ elffile->reltext=_LoaderFileToMem(elffile->fd,
+ SecOffset(i),SecSize(i),".rela.text");
+ elffile->saddr[i]=(unsigned char *)elffile->reltext;
+ elffile->reltxtndx=i;
+ elffile->reltxtsize=SecSize(i);
+#ifdef ELFDEBUG
+ ELFDEBUG(".rela.text starts at %x\n", elffile->reltext );
+#endif
+ continue;
+ }
+ /* .rela.data */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".rela.data" ) == 0 ) {
+ elffile->reldata=_LoaderFileToMem(elffile->fd,
+ SecOffset(i),SecSize(i),".rela.data");
+ elffile->saddr[i]=(unsigned char *)elffile->reldata;
+ elffile->reldatndx=i;
+ elffile->reldatsize=SecSize(i);
+#ifdef ELFDEBUG
+ ELFDEBUG(".rela.data starts at %x\n", elffile->reldata );
+#endif
+ continue;
+ }
+ /* .rela.sdata */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".rela.sdata" ) == 0 ) {
+ elffile->relsdata=_LoaderFileToMem(elffile->fd,
+ SecOffset(i),SecSize(i),".rela.sdata");
+ elffile->saddr[i]=(unsigned char *)elffile->relsdata;
+ elffile->relsdatndx=i;
+ elffile->relsdatsize=SecSize(i);
+#ifdef ELFDEBUG
+ ELFDEBUG(".rela.sdata starts at %x\n", elffile->relsdata );
+#endif
+ continue;
+ }
+ /* .rela.rodata */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".rela.rodata" ) == 0 ) {
+ elffile->relrodata=_LoaderFileToMem(elffile->fd,
+ SecOffset(i),SecSize(i),".rela.rodata");
+ elffile->saddr[i]=(unsigned char *)elffile->relrodata;
+ elffile->relrodatndx=i;
+ elffile->relrodatsize=SecSize(i);
+#ifdef ELFDEBUG
+ ELFDEBUG(".rela.rodata starts at %x\n", elffile->relrodata );
+#endif
+ continue;
+ }
+#endif /* __powerpc__ || __mc68000__ */
+ /* .shstrtab */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".shstrtab" ) == 0 ) {
+ continue;
+ }
+ /* .comment */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".comment" ) == 0 ) {
+ continue;
+ }
+ /* .debug */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".debug" ) == 0 ) {
+ continue;
+ }
+ /* .line */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".line" ) == 0 ) {
+ continue;
+ }
+ /* .note */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".note" ) == 0 ) {
+ continue;
+ }
+ /* .rel.debug */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".rel.debug" ) == 0 ) {
+ continue;
+ }
+ /* .rel.line */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".rel.line" ) == 0 ) {
+ continue;
+ }
+ /* .stab */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".stab" ) == 0 ) {
+ continue;
+ }
+ /* .rel.stab */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".rel.stab" ) == 0 ) {
+ continue;
+ }
+ /* .rela.stab */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".rela.stab" ) == 0 ) {
+ continue;
+ }
+ /* .stabstr */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".stabstr" ) == 0 ) {
+ continue;
+ }
+#if defined(__powerpc__) || defined(__mc68000__)
+ /* .rela.tdesc */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".rela.tdesc" ) == 0 ) {
+ continue;
+ }
+ /* .rela.debug_line */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".rela.debug_line" ) == 0 ) {
+ continue;
+ }
+ /* .tdesc */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".tdesc" ) == 0 ) {
+ continue;
+ }
+ /* .debug_line */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".debug_line" ) == 0 ) {
+ continue;
+ }
+ /* $0001300 */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ "$0001300" ) == 0 ) {
+ continue;
+ }
+#endif
+#if defined(__alpha__)
+ /* .got */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".got" ) == 0 ) {
+ continue;
+ elffile->got=NULL;
+ elffile->gotsize=0;
+ elffile->got_entries=NULL;
+ }
+ /* .mdebug */
+ if( strcmp(ElfGetSectionName(elffile, elffile->sections[i].sh_name),
+ ".mdebug" ) == 0 ) {
+ continue;
+ }
+#endif
+ ErrorF("Not loading %s\n",
+ ElfGetSectionName(elffile, elffile->sections[i].sh_name) );
+ }
+}
+
+/*
+ * Public API for the ELF implementation of the loader.
+ */
+void *
+ELFLoadModule(modrec, elffd, ppLookup)
+loaderPtr modrec;
+int elffd;
+LOOKUP **ppLookup;
+{
+ ELFModulePtr elffile;
+ Elf_Ehdr *header;
+ ELFRelocPtr elf_reloc, tail;
+ void *v;
+ LDRModulePtr elfmod;
+
+ ldrCommons = 0;
+ nCommons = 0;
+
+ if ((elffile = xf86loadercalloc(1, sizeof(ELFModuleRec))) == NULL) {
+ ErrorF( "Unable to allocate ELFModuleRec\n" );
+ return NULL;
+ }
+
+ elffile->handle=modrec->handle;
+ elffile->module=modrec->module;
+ elffile->fd=elffd;
+ v=elffile->funcs=modrec->funcs;
+
+/*
+ * Get the ELF header
+ */
+ elffile->header=(Elf_Ehdr*)_LoaderFileToMem(elffd,0,sizeof(Elf_Ehdr),"header");
+ header=(Elf_Ehdr *)elffile->header;
+
+/*
+ * Get the section table
+ */
+ elffile->numsh=header->e_shnum;
+ elffile->secsize=(header->e_shentsize*header->e_shnum);
+ elffile->sections=(Elf_Shdr *)_LoaderFileToMem(elffd,header->e_shoff,
+ elffile->secsize, "sections");
+#if defined(__alpha__)
+ /*
+ * Need to allocate space for the .got section which will be
+ * fabricated later
+ */
+ elffile->gotndx=header->e_shnum;
+ header->e_shnum++;
+ elffile->numsh=header->e_shnum;
+ elffile->secsize=(header->e_shentsize*header->e_shnum);
+ elffile->sections=xf86loaderrealloc(elffile->sections,elffile->secsize);
+#endif
+ elffile->saddr=xf86loadercalloc(elffile->numsh, sizeof(unsigned char *));
+
+#if defined(__alpha__)
+ /*
+ * Manually fill in the entry for the .got section so ELFCollectSections()
+ * will be able to find it.
+ */
+ elffile->sections[elffile->gotndx].sh_name=SecSize(header->e_shstrndx)+1;
+ elffile->sections[elffile->gotndx].sh_type=SHT_PROGBITS;
+ elffile->sections[elffile->gotndx].sh_flags=SHF_WRITE|SHF_ALLOC;
+ elffile->sections[elffile->gotndx].sh_size=0;
+ elffile->sections[elffile->gotndx].sh_addralign=8;
+ /* Add room to copy ".got", and maintain alignment */
+ SecSize(header->e_shstrndx)+=8;
+#endif
+
+/*
+ * Get the section header string table
+ */
+ elffile->shstrsize = SecSize(header->e_shstrndx);
+ elffile->shstraddr = _LoaderFileToMem(elffd,SecOffset(header->e_shstrndx),
+ SecSize(header->e_shstrndx),".shstrtab");
+ elffile->shstrndx = header->e_shstrndx;
+#if defined(__alpha__)
+ /*
+ * Add the string for the .got section
+ */
+ strcpy((char*)(elffile->shstraddr+elffile->sections[elffile->gotndx].sh_name),
+ ".got");
+#endif
+
+/*
+ * Load the rest of the desired sections
+ */
+ ELFCollectSections(elffile);
+
+ if( elffile->straddr == NULL || elffile->strsize == 0 ) {
+ ErrorF("No symbols found in this module\n");
+ ELFUnloadModule(elffile);
+ return NULL;
+ }
+
+/*
+ * add symbols
+ */
+ *ppLookup = ELF_GetSymbols(elffile);
+
+/*
+ * Do relocations
+ */
+ if (elffile->reltxtndx) {
+ elf_reloc = ELFCollectRelocations(elffile,elffile->reltxtndx);
+ if (elf_reloc) {
+ for (tail = elf_reloc; tail->next; tail = tail->next)
+ ;
+ tail->next = _LoaderGetRelocations(v)->elf_reloc;
+ _LoaderGetRelocations(v)->elf_reloc = elf_reloc;
+ }
+ }
+ if (elffile->reldatndx) {
+ elf_reloc = ELFCollectRelocations(elffile,elffile->reldatndx);
+ if (elf_reloc) {
+ for (tail = elf_reloc; tail->next; tail = tail->next)
+ ;
+ tail->next = _LoaderGetRelocations(v)->elf_reloc;
+ _LoaderGetRelocations(v)->elf_reloc = elf_reloc;
+ }
+ }
+ if (elffile->relrodatndx) {
+ elf_reloc = ELFCollectRelocations(elffile,elffile->relrodatndx);
+ if (elf_reloc) {
+ for (tail = elf_reloc; tail->next; tail = tail->next)
+ ;
+ tail->next = _LoaderGetRelocations(v)->elf_reloc;
+ _LoaderGetRelocations(v)->elf_reloc = elf_reloc;
+ }
+ }
+ if (elffile->relsdatndx) {
+ elf_reloc = ELFCollectRelocations(elffile,elffile->relsdatndx);
+ if (elf_reloc) {
+ for (tail = elf_reloc; tail->next; tail = tail->next)
+ ;
+ tail->next = _LoaderGetRelocations(v)->elf_reloc;
+ _LoaderGetRelocations(v)->elf_reloc = elf_reloc;
+ }
+ }
+
+#if defined(__alpha__)
+ ELFCreateGOT(elffile);
+#endif
+
+ /* Record info for gdb - if we can't allocate the loader record fail
+ silently (the user will find out soon enough that there's no VM left */
+ if ((elfmod = xf86loadercalloc(1, sizeof(LDRModuleRec))) != NULL) {
+ elfmod->name = strdup(modrec->name);
+ elfmod->namelen = strlen(modrec->name);
+ elfmod->version = 1;
+ elfmod->text = elffile->text;
+ elfmod->data = elffile->data;
+ elfmod->rodata = elffile->rodata;
+ elfmod->bss = elffile->bss;
+ elfmod->next = ModList;
+ elfmod->commons = ldrCommons;
+ elfmod->commonslen = nCommons;
+
+ ModList = elfmod;
+
+ /* Tell GDB something interesting happened */
+ _loader_debug_state();
+ }
+ return (void *)elffile;
+}
+
+void
+ELFResolveSymbols(mod)
+void *mod;
+{
+ ELFRelocPtr newlist, p, tmp;
+
+ /* Try to relocate everything. Build a new list containing entries
+ * which we failed to relocate. Destroy the old list in the process.
+ */
+ newlist = 0;
+ for (p = _LoaderGetRelocations(mod)->elf_reloc; p; ) {
+#ifdef ELFDEBUG
+ ErrorF("ResolveSymbols: file %lx, sec %lx, r_offset 0x%x, r_info 0x%lx\n",
+ p->file, p->secp, p->rel->r_offset, p->rel->r_info);
+#endif
+ tmp = Elf_RelocateEntry(p->file, p->secp, p->rel, FALSE);
+ if (tmp) {
+ /* Failed to relocate. Keep it in the list. */
+ tmp->next = newlist;
+ newlist = tmp;
+ }
+ tmp = p;
+ p = p->next;
+ xf86loaderfree(tmp);
+ }
+ _LoaderGetRelocations(mod)->elf_reloc=newlist;
+}
+
+int
+ELFCheckForUnresolved(mod)
+void *mod;
+{
+ ELFRelocPtr erel;
+ char *name;
+ int flag, fatalsym=0;
+
+ if ((erel = _LoaderGetRelocations(mod)->elf_reloc) == NULL)
+ return 0;
+
+ while( erel ) {
+ Elf_RelocateEntry(erel->file, erel->secp, erel->rel, TRUE);
+ name = ElfGetSymbolName(erel->file, ELF_R_SYM(erel->rel->r_info));
+ flag = _LoaderHandleUnresolved(
+ name, _LoaderHandleToName(erel->file->handle));
+ if(flag) fatalsym = 1;
+ xf86loaderfree(name);
+ erel=erel->next;
+ }
+ return fatalsym;
+}
+
+void
+ELFUnloadModule(modptr)
+void *modptr;
+{
+ ELFModulePtr elffile = (ELFModulePtr)modptr;
+ ELFRelocPtr relptr, reltptr, *brelptr;
+
+/*
+ * Delete any unresolved relocations
+ */
+
+ relptr=_LoaderGetRelocations(elffile->funcs)->elf_reloc;
+ brelptr=&(_LoaderGetRelocations(elffile->funcs)->elf_reloc);
+
+ while(relptr) {
+ if( relptr->file == elffile ) {
+ *brelptr=relptr->next; /* take it out of the list */
+ reltptr=relptr; /* save pointer to this node */
+ relptr=relptr->next; /* advance the pointer */
+ xf86loaderfree(reltptr); /* free the node */
+ }
+ else {
+ brelptr=&(relptr->next);
+ relptr=relptr->next; /* advance the pointer */
+ }
+ }
+
+/*
+ * Delete any symbols in the symbols table.
+ */
+
+ LoaderHashTraverse((void *)elffile, ELFhashCleanOut);
+
+/*
+ * Free the sections that were allocated.
+ */
+#define CheckandFree(ptr,size) if(ptr) _LoaderFreeFileMem((ptr),(size))
+
+ CheckandFree(elffile->straddr,elffile->strsize);
+ CheckandFree(elffile->symtab,elffile->symsize);
+ CheckandFree(elffile->text,elffile->txtsize);
+ CheckandFree(elffile->data,elffile->datsize);
+ CheckandFree(elffile->data1,elffile->dat1size);
+ CheckandFree(elffile->sdata,elffile->sdatsize);
+ CheckandFree(elffile->bss,elffile->bsssize);
+ CheckandFree(elffile->rodata,elffile->rodatsize);
+ CheckandFree(elffile->reltext,elffile->reltxtsize);
+ CheckandFree(elffile->reldata,elffile->reldatsize);
+ CheckandFree(elffile->relrodata,elffile->relrodatsize);
+ CheckandFree(elffile->relsdata,elffile->relsdatsize);
+#if defined(__alpha__)
+ CheckandFree(elffile->got,elffile->gotsize);
+#endif
+ if( elffile->common )
+ xf86loaderfree(elffile->common);
+/*
+ * Free the section table, section pointer array, and section names
+ */
+ _LoaderFreeFileMem(elffile->sections,elffile->secsize);
+ xf86loaderfree(elffile->saddr);
+ _LoaderFreeFileMem(elffile->header,sizeof(Elf_Ehdr));
+ _LoaderFreeFileMem(elffile->shstraddr,elffile->shstrsize);
+
+/*
+ * Free the ELFModuleRec
+ */
+ xf86loaderfree(elffile);
+
+ return;
+}
+
+char *
+ELFAddressToSection(void *modptr, unsigned long address)
+{
+ ELFModulePtr elffile = (ELFModulePtr)modptr;
+ int i;
+
+ for( i=1; i<elffile->numsh; i++) {
+ if( address >= (unsigned long)elffile->saddr[i] &&
+ address <= (unsigned long)elffile->saddr[i]+SecSize(i) ) {
+ return ElfGetSectionName(elffile, elffile->sections[i].sh_name);
+ }
+ }
+return NULL;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/loader/elfloader.h b/xc/programs/Xserver/hw/xfree86/loader/elfloader.h
new file mode 100644
index 000000000..cbd5f118a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/elfloader.h
@@ -0,0 +1,34 @@
+/*
+ *
+ * Copyright 1997,1998 by Metro Link, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/elfloader.h,v 1.3 1998/09/20 14:41:05 dawes Exp $ */
+
+#ifndef _ELFLOADER_H
+#define _ELFLOADER_H
+/* elfloader.c */
+extern void *ELFLoadModule(loaderPtr, int, LOOKUP **);
+extern void ELFResolveSymbols(void *);
+extern int ELFCheckForUnresolved(void *);
+extern char *ELFAddressToSection(void *,unsigned long);
+extern void ELFUnloadModule(void *);
+#endif /* _ELFLOADER_h */
diff --git a/xc/programs/Xserver/hw/xfree86/loader/fontsym.c b/xc/programs/Xserver/hw/xfree86/loader/fontsym.c
new file mode 100644
index 000000000..91d56909b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/fontsym.c
@@ -0,0 +1,46 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/fontsym.c,v 1.5 1999/06/13 13:47:48 dawes Exp $ */
+
+#include "font.h"
+#include "sym.h"
+#include "fntfilst.h"
+#include "fontenc.h"
+#include "fntfilio.h"
+#include "fntfil.h"
+#include "fontutil.h"
+#include "fontxlfd.h"
+
+LOOKUP fontLookupTab[] = {
+
+ SYMFUNC(TwoByteSwap)
+ SYMFUNC(FourByteSwap)
+ SYMFUNC(FontCouldBeTerminal)
+ SYMFUNC(BufFileRead)
+ SYMFUNC(BufFileWrite)
+ SYMFUNC(CheckFSFormat)
+ SYMFUNC(FontFileOpen)
+ SYMFUNC(FontFileRegisterRenderer)
+ SYMFUNC(FontParseXLFDName)
+ SYMFUNC(FontFileCloseFont)
+ SYMFUNC(FontFileOpenBitmap)
+ SYMFUNC(FontFileCompleteXLFD)
+ SYMFUNC(FontFileCountDashes)
+ SYMFUNC(FontFileFindNameInDir)
+ SYMFUNC(FontFileClose)
+ SYMFUNC(FontComputeInfoAccelerators)
+ SYMFUNC(FontDefaultFormat)
+ SYMFUNC(NameForAtom)
+ SYMFUNC(BitOrderInvert)
+ SYMFUNC(FontFileMatchRenderer)
+ SYMFUNC(RepadBitmap)
+ SYMFUNC(font_encoding_name)
+ SYMFUNC(font_encoding_recode)
+ SYMFUNC(font_encoding_find)
+ SYMFUNC(font_encoding_from_xlfd)
+ SYMFUNC(CreateFontRec)
+ SYMFUNC(DestroyFontRec)
+
+ SYMVAR(FontFileBitmapSources)
+
+ { 0, 0 },
+
+};
diff --git a/xc/programs/Xserver/hw/xfree86/loader/hash.c b/xc/programs/Xserver/hw/xfree86/loader/hash.c
new file mode 100644
index 000000000..1ec361cf4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/hash.c
@@ -0,0 +1,350 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/hash.c,v 1.12 1999/03/14 03:22:13 dawes Exp $ */
+
+/*
+ *
+ * Copyright 1995-1998 by Metro Link, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. 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 "os.h"
+#include "Xos.h"
+#ifndef X_NOT_STDC_ENV
+#undef abs
+#include <stdlib.h>
+#else
+extern void free();
+#endif
+#include "sym.h"
+#include "loader.h"
+#include "hash.h"
+
+#if defined(Lynx)
+#define MAXINT 32000
+#else
+#include <limits.h>
+#undef MAXINT
+#define MAXINT INT_MAX
+#endif
+
+/* Prototypes for static functions. */
+static unsigned int hashFunc(const char *);
+static itemPtr LoaderHashFindNearest(
+#if NeedFunctionPrototypes
+unsigned long
+#endif
+);
+
+static itemPtr LoaderhashTable[ HASHSIZE ] ;
+
+#ifdef DEBUG
+static int hashhits[ HASHSIZE ] ;
+
+void
+DumpHashHits(void)
+{
+ int i;
+ int depth=0;
+ int dev=0;
+
+ for(i=0;i<HASHSIZE;i++) {
+ ErrorF("hashhits[%d]=%d\n", i, hashhits[i] );
+ depth += hashhits[i];
+ }
+
+ depth /= HASHSIZE;
+ ErrorF("Average hash depth=%d\n", depth );
+
+ for(i=0;i<HASHSIZE;i++) {
+ if( hashhits[i] < depth )
+ dev += depth-hashhits[i];
+ else
+ dev += hashhits[i]-depth;
+ }
+
+ dev /=HASHSIZE;
+ ErrorF("Average hash deviation=%d\n", dev );
+}
+#endif
+
+
+static unsigned int
+hashFunc(string)
+const char *string;
+{
+ int i=0;
+
+ while ( i < 10 && string[i] )
+ i ++ ;
+
+ if ( i < 5 ) {
+#ifdef DEBUG
+ hashhits[i]++;
+#endif
+ return i ;
+ }
+
+/*
+ * Original has function
+#define HASH ((string[ i-4 ] * string[i-3] + string[i-2] ) & (HASHSIZE-1))
+ */
+
+#define HASH ((string[i-5] * string[ i-4 ] + string[i-3] * string[i-2] ) & (HASHSIZE-1))
+
+#ifdef DEBUG
+ hashhits[HASH]++;
+#endif
+
+ return HASH;
+}
+
+void
+LoaderHashAdd( entry )
+ itemPtr entry ;
+{
+ int bucket = hashFunc( entry->name ) ;
+ itemPtr oentry;
+
+ if ((oentry = LoaderHashFind(entry->name)) != NULL)
+ LoaderDuplicateSymbol(entry->name, oentry->handle);
+
+ entry->next = LoaderhashTable[ bucket ] ;
+ LoaderhashTable[ bucket ] = entry ;
+ return;
+}
+
+void
+LoaderAddSymbols(handle, module, list)
+int handle;
+int module;
+LOOKUP *list ;
+{
+ LOOKUP *l = list;
+ itemPtr i;
+ char *modname;
+
+ if (!list)
+ return;
+ /* Visit every symbol in the lookup table,
+ * and add it to the given namespace.
+ */
+ while ( l->symName ) {
+ i = xf86loadermalloc( sizeof( itemRec )) ;
+ i->name = l->symName ;
+ if( strcmp(i->name,"ModuleInit") == 0
+#if defined(__powerpc__) && defined(Lynx)
+ || strcmp(i->name,".ModuleInit") == 0
+#endif
+ )
+ {
+ char *origname=i->name;
+ /*
+ * special handling for symbol name "ModuleInit"
+ */
+ modname = _LoaderHandleToCanonicalName(handle);
+ if (modname)
+ {
+ i->name = xf86loadermalloc(strlen(modname) +
+ strlen(origname) + 1);
+ if( i->name )
+ {
+ /* XXX Is this right for PPC? */
+ strcpy(i->name,modname);
+ strcat(i->name,origname);
+ }
+ }
+#ifdef DEBUG
+ ErrorF("Add module init function %s at %lx\n",i->name, l->offset);
+#endif
+ }
+ i->address = (char *) l->offset ;
+ i->handle = handle ;
+ i->module = module ;
+ LoaderHashAdd( i );
+ l ++ ;
+ }
+}
+
+itemPtr
+LoaderHashDelete(string)
+const char *string;
+{
+ int bucket = hashFunc( string ) ;
+ itemPtr entry;
+ itemPtr *entry2;
+
+ entry = LoaderhashTable[ bucket ] ;
+ entry2= &(LoaderhashTable[ bucket ]);
+ while ( entry ) {
+ if (! strcmp( entry->name, string )) {
+ *entry2=entry->next;
+ xf86loaderfree(entry->name);
+ xf86loaderfree( entry ) ;
+ return 0 ;
+ }
+ entry2 = &(entry->next) ;
+ entry = entry->next ;
+ }
+ return 0 ;
+}
+
+itemPtr
+LoaderHashFind(string)
+const char *string;
+{
+ int bucket = hashFunc( string ) ;
+ itemPtr entry ;
+ entry = LoaderhashTable[ bucket ] ;
+ while ( entry ) {
+ if (!strcmp(entry->name, string)) {
+ return entry;
+ }
+ entry = entry->next;
+ }
+ return 0;
+}
+
+static itemPtr
+LoaderHashFindNearest(address)
+unsigned long address;
+{
+ int i ;
+ itemPtr entry, best_entry = 0 ;
+ long best_difference = MAXINT;
+
+ for ( i = 0 ; i < HASHSIZE ; i ++ ) {
+ entry = LoaderhashTable[ i ] ;
+ while ( entry ) {
+ long difference = (long) address - (long) entry->address ;
+ if ( difference >= 0 ) {
+ if ( best_entry ) {
+ if ( difference < best_difference ) {
+ best_entry = entry ;
+ best_difference = difference ;
+ }
+ }
+ else {
+ best_entry = entry ;
+ best_difference = difference ;
+ }
+ }
+ entry = entry->next ;
+ }
+ }
+ return best_entry ;
+}
+
+void
+LoaderPrintSymbol(address)
+unsigned long address;
+{
+ itemPtr entry;
+ entry=LoaderHashFindNearest(address);
+ if (entry) {
+ const char *module, *section;
+#ifdef __alpha__
+ ErrorF("0x%016lx %s+%lx\n", entry->address, entry->name,
+ address - (unsigned long) entry->address);
+#else
+ ErrorF("0x%x %s+%x\n", entry->address, entry->name,
+ address - (unsigned long) entry->address);
+#endif
+
+ if ( _LoaderAddressToSection(address, &module, &section) )
+ ErrorF("\tModule \"%s\"\n\tSection \"%s\"\n",module, section );
+ } else {
+ ErrorF("(null)\n");
+ }
+}
+
+void
+LoaderPrintItem(itemPtr pItem)
+{
+ if (pItem) {
+ const char *module, *section;
+#ifdef __alpha__
+ ErrorF("0x%016lx %s\n", pItem->address, pItem->name);
+#else
+ ErrorF("0x%lx %s\n", pItem->address, pItem->name);
+#endif
+ if ( _LoaderAddressToSection((unsigned long)pItem->address,
+ &module, &section) )
+ ErrorF("\tModule \"%s\"\n\tSection \"%s\"\n",module, section );
+ } else
+ ErrorF("(null)\n");
+}
+
+void
+LoaderPrintAddress(symbol)
+const char *symbol;
+{
+ itemPtr entry;
+ entry = LoaderHashFind(symbol);
+ LoaderPrintItem(entry);
+}
+
+void
+LoaderHashTraverse(card, fnp)
+ void *card;
+ int (*fnp)(void *, itemPtr);
+{
+ int i ;
+ itemPtr entry, last_entry = 0 ;
+
+ for ( i = 0 ; i < HASHSIZE ; i ++ ) {
+ last_entry = 0 ;
+ entry = LoaderhashTable[ i ] ;
+ while ( entry ) {
+ if (( * fnp )( card, entry )) {
+ if ( last_entry ) {
+ last_entry->next = entry->next ;
+ xf86loaderfree( entry->name ) ;
+ xf86loaderfree( entry ) ;
+ entry = last_entry->next ;
+ }
+ else {
+ LoaderhashTable[ i ] = entry->next ;
+ xf86loaderfree( entry->name ) ;
+ xf86loaderfree( entry ) ;
+ entry = LoaderhashTable[ i ] ;
+ }
+ }
+ else {
+ last_entry = entry ;
+ entry = entry->next ;
+ }
+ }
+ }
+}
+
+void
+LoaderDumpSymbols()
+{
+ itemPtr entry;
+ int j;
+
+ for (j=0; j<HASHSIZE; j++) {
+ entry = LoaderhashTable[j];
+ while (entry) {
+ LoaderPrintItem(entry);
+ entry = entry->next;
+ }
+ }
+
+}
diff --git a/xc/programs/Xserver/hw/xfree86/loader/hash.h b/xc/programs/Xserver/hw/xfree86/loader/hash.h
new file mode 100644
index 000000000..96cd41c02
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/hash.h
@@ -0,0 +1,36 @@
+/*
+ *
+ * Copyright 1995-1998 by Metro Link, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/hash.h,v 1.3 1998/07/25 16:56:16 dawes Exp $ */
+
+#ifndef _HASH_H
+#define _HASH_H
+
+#include "loader.h"
+
+typedef struct _HashIterator {
+ itemPtr pItem;
+ int bucket;
+} HashIteratorRec, *HashIteratorPtr;
+
+#endif /* _HASH_H */
diff --git a/xc/programs/Xserver/hw/xfree86/loader/loader.c b/xc/programs/Xserver/hw/xfree86/loader/loader.c
new file mode 100644
index 000000000..88fb87600
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/loader.c
@@ -0,0 +1,1212 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loader.c,v 1.37 1999/07/06 11:38:47 dawes Exp $ */
+
+/*
+ *
+ * Copyright 1995-1998 by Metro Link, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. 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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#ifdef UseMMAP
+#include <sys/mman.h>
+#endif
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#if defined(linux) && (defined(__alpha__) || defined(__powerpc__))
+#include <malloc.h>
+#endif
+#include <stdarg.h>
+#include "ar.h"
+#include "elf.h"
+#include "coff.h"
+
+#include "os.h"
+#include "sym.h"
+#include "loader.h"
+#include "loaderProcs.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+
+extern LOOKUP miLookupTab[];
+extern LOOKUP xfree86LookupTab[];
+extern LOOKUP dixLookupTab[];
+extern LOOKUP fontLookupTab[];
+
+/*
+#define DEBUG
+#define DEBUGAR
+#define DEBUGLIST
+#define DEBUGMEM
+*/
+
+int check_unresolved_sema = 0;
+
+#if defined(Lynx) && defined(sun)
+/* Cross build machine doesn;t have strerror() */
+#define strerror(err) "strerror unsupported"
+#endif
+
+#ifdef __EMX__
+void * os2loader_calloc(size_t,size_t);
+#endif
+
+#ifdef HANDLE_IN_HASH_ENTRY
+/*
+ * handles are used to identify files that are loaded. Even archives
+ * are counted as a single file.
+ */
+#define MAX_HANDLE 256
+#define HANDLE_FREE 0
+#define HANDLE_USED 1
+static char freeHandles[MAX_HANDLE] ;
+static int refCount[MAX_HANDLE] ;
+#endif
+
+#ifdef __sparc__
+extern LOOKUP SparcLookupTab[];
+#ifdef linux
+extern int sparcUseHWMulDiv(void);
+extern LOOKUP SparcV89LookupTab[];
+#endif
+#endif
+
+/*
+ * modules are used to identify compilation units (ie object modules).
+ * Archives contain multiple modules, each of which is treated seperately.
+ */
+static int moduleseq = 0;
+
+/*
+ * GDB Interface
+ * =============
+ *
+ * Linked list of loaded modules - gdb will traverse this to determine
+ * whether it needs to add the symbols for the loaded module.
+ */
+LDRModulePtr ModList = 0;
+
+/* Flag which gdb sets to let us know we're being debugged */
+char DebuggerPresent = 0;
+
+/* List of common symbols */
+LDRCommonPtr ldrCommons;
+int nCommons;
+
+typedef struct {
+ int num;
+ const char ** list;
+} symlist;
+
+/*
+ * List of symbols that may be referenced, and which are allowed to be
+ * unresolved providing that they don't appear on the "reqired" list.
+ */
+static symlist refList = { 0, NULL };
+
+/* List of symbols that must not be unresolved */
+static symlist reqList = { 0, NULL };
+
+static int fatalReqSym = 0;
+
+/* Prototypes for static functions. */
+static int _GetModuleType(int, long);
+static loaderPtr _LoaderListPush(void);
+static loaderPtr _LoaderListPop(int);
+/*ARGSUSED*/
+static void ARCHIVEResolveSymbols(void *unused) {}
+/*ARGSUSED*/
+static int ARCHIVECheckForUnresolved(void *v) { return 0; }
+/*ARGSUSED*/
+static char *ARCHIVEAddressToSection(void *modptr, unsigned long address)
+{ return NULL; }
+/*ARGSUSED*/
+static void ARCHIVEUnload(void *unused2) {}
+
+/*
+ * Array containing entry points for different formats.
+ */
+
+static loader_funcs funcs[] = {
+ /* LD_ARCHIVE */
+ {ARCHIVELoadModule,
+ ARCHIVEResolveSymbols,
+ ARCHIVECheckForUnresolved,
+ ARCHIVEAddressToSection,
+ ARCHIVEUnload, {0,0,0,0,0}},
+ /* LD_ELFOBJECT */
+ {ELFLoadModule,
+ ELFResolveSymbols,
+ ELFCheckForUnresolved,
+ ELFAddressToSection,
+ ELFUnloadModule, {0,0,0,0,0}},
+ /* LD_COFFOBJECT */
+ {COFFLoadModule,
+ COFFResolveSymbols,
+ COFFCheckForUnresolved,
+ COFFAddressToSection,
+ COFFUnloadModule, {0,0,0,0,0}},
+ /* LD_XCOFFOBJECT */
+ {COFFLoadModule,
+ COFFResolveSymbols,
+ COFFCheckForUnresolved,
+ COFFAddressToSection,
+ COFFUnloadModule, {0,0,0,0,0}},
+ /* LD_AOUTOBJECT */
+ {AOUTLoadModule,
+ AOUTResolveSymbols,
+ AOUTCheckForUnresolved,
+ AOUTAddressToSection,
+ AOUTUnloadModule, {0,0,0,0,0}},
+ /* LD_AOUTDLOBJECT */
+#ifdef DLOPEN_SUPPORT
+ {DLLoadModule,
+ DLResolveSymbols,
+ DLCheckForUnresolved,
+ ARCHIVEAddressToSection,
+ DLUnloadModule, {0,0,0,0,0}},
+#else
+ {AOUTLoadModule,
+ AOUTResolveSymbols,
+ AOUTCheckForUnresolved,
+ AOUTAddressToSection,
+ AOUTUnloadModule, {0,0,0,0,0}},
+#endif
+ /* LD_ELFDLOBJECT */
+#ifdef DLOPEN_SUPPORT
+ {DLLoadModule,
+ DLResolveSymbols,
+ DLCheckForUnresolved,
+ ARCHIVEAddressToSection,
+ DLUnloadModule, {0,0,0,0,0}},
+#else
+ {ELFLoadModule,
+ ELFResolveSymbols,
+ ELFCheckForUnresolved,
+ ELFAddressToSection,
+ ELFUnloadModule, {0,0,0,0,0}},
+#endif
+ };
+
+int numloaders=sizeof(funcs)/sizeof(loader_funcs);
+
+
+void
+LoaderInit(void)
+{
+ const char *osname = NULL;
+
+ LoaderAddSymbols(-1, -1, miLookupTab ) ;
+ LoaderAddSymbols(-1, -1, xfree86LookupTab ) ;
+ LoaderAddSymbols(-1, -1, dixLookupTab ) ;
+ LoaderAddSymbols(-1, -1, fontLookupTab ) ;
+#ifdef __sparc__
+#ifdef linux
+ if (sparcUseHWMulDiv())
+ LoaderAddSymbols(-1, -1, SparcV89LookupTab ) ;
+ else
+#endif
+ LoaderAddSymbols(-1, -1, SparcLookupTab ) ;
+#endif
+
+ xf86MsgVerb(X_INFO, 2, "Module ABI versions:\n");
+ xf86ErrorFVerb(2, "\t%s: %d.%d\n", ABI_CLASS_ANSIC,
+ GET_ABI_MAJOR(LoaderVersionInfo.ansicVersion),
+ GET_ABI_MINOR(LoaderVersionInfo.ansicVersion));
+ xf86ErrorFVerb(2, "\t%s: %d.%d\n", ABI_CLASS_VIDEODRV,
+ GET_ABI_MAJOR(LoaderVersionInfo.videodrvVersion),
+ GET_ABI_MINOR(LoaderVersionInfo.videodrvVersion));
+ xf86ErrorFVerb(2, "\t%s : %d.%d\n", ABI_CLASS_XINPUT,
+ GET_ABI_MAJOR(LoaderVersionInfo.xinputVersion),
+ GET_ABI_MINOR(LoaderVersionInfo.xinputVersion));
+ xf86ErrorFVerb(2, "\t%s : %d.%d\n", ABI_CLASS_EXTENSION,
+ GET_ABI_MAJOR(LoaderVersionInfo.extensionVersion),
+ GET_ABI_MINOR(LoaderVersionInfo.extensionVersion));
+ xf86ErrorFVerb(2, "\t%s : %d.%d\n", ABI_CLASS_FONT,
+ GET_ABI_MAJOR(LoaderVersionInfo.fontVersion),
+ GET_ABI_MINOR(LoaderVersionInfo.fontVersion));
+
+ LoaderGetOS(&osname, NULL, NULL, NULL);
+ if (osname)
+ xf86MsgVerb(X_INFO, 2, "Loader running on %s\n", osname);
+
+#if defined(linux) && (defined(__alpha__) || defined(__powerpc__))
+ /*
+ * The glibc malloc uses mmap for large allocations anyway. This breaks
+ * some relocation types because the offset overflow. See loader.h for more
+ * details. We need to turn off this behavior here.
+ */
+ mallopt(M_MMAP_MAX,0);
+#endif
+}
+
+/*
+ * Determine what type of object is being loaded.
+ * This function is responsible for restoring the offset.
+ * The fd and offset are used here so that when Archive processing
+ * is enabled, individual elements of an archive can be evaluated
+ * so the correct loader_funcs can be determined.
+ */
+static int
+_GetModuleType(int fd, long offset)
+{
+ unsigned char buf[256]; /* long enough for the largest magic type */
+
+ if( read(fd,buf,sizeof(buf)) < 0 ) {
+ return -1;
+ }
+
+#ifdef DEBUG
+ ErrorF("Checking module type %10s\n", buf );
+ ErrorF("Checking module type %x %x %x %x\n", buf[0], buf[1], buf[2], buf[3] );
+#endif
+
+ lseek(fd,offset,SEEK_SET);
+
+ if (strncmp((char *) buf, ARMAG, SARMAG) == 0) {
+ return LD_ARCHIVE;
+ }
+
+#if defined(AIAMAG)
+ /* LynxOS PPC style archives */
+ if (strncmp((char *) buf, AIAMAG, SAIAMAG) == 0) {
+ return LD_ARCHIVE;
+ }
+#endif
+
+ if (strncmp((char *) buf, ELFMAG, SELFMAG) == 0) {
+ if( buf[ELFDLOFF] == ELFDLMAG ) {
+ return LD_ELFDLOBJECT;
+ } else {
+ return LD_ELFOBJECT;
+ }
+ }
+
+ if( buf[0] == 0x4c && buf[1] == 0x01 ) {
+ /* I386MAGIC */
+ return LD_COFFOBJECT;
+ }
+ if( buf[0] == 0x01 && buf[1] == 0xdf ) {
+ /* XCOFFMAGIC */
+ return LD_COFFOBJECT;
+ }
+ if( buf[0] == 0x0d && buf[1] == 0x01 ) {
+ /* ZCOFFMAGIC (LynxOS) */
+ return LD_COFFOBJECT;
+ }
+ if( buf[0] == 0x00 && buf[1] == 0x86 && buf[2] == 0x01 && buf[3] == 0x07) {
+ /* AOUTMAGIC */
+ return LD_AOUTOBJECT;
+ }
+ if (buf[0] == 0x07 && buf[1] == 0x01 && (buf[2] == 0x64 || buf[2] == 0x86))
+ {
+ /* AOUTMAGIC, (Linux OMAGIC, old impure format, also used by OS/2 */
+ return LD_AOUTOBJECT;
+ }
+ if (buf[0] == 0x07 && buf[1] == 0x01 && buf[2] == 0x00 && buf[3] == 0x00)
+ {
+ /* AOUTMAGIC, BSDI */
+ return LD_AOUTOBJECT;
+ }
+ if ((buf[0] == 0xc0 && buf[1] == 0x86) || /* big endian form */
+ (buf[3] == 0xc0 && buf[2] == 0x86)) { /* little endian form */
+ /* i386 shared object */
+ return LD_AOUTDLOBJECT;
+ }
+
+ return LD_UNKNOWN;
+}
+
+
+static int offsetbias=0; /* offset into archive */
+/*
+ * _LoaderFileToMem() loads the contents of a file into memory using
+ * the most efficient method for a platform.
+ */
+void *
+_LoaderFileToMem(int fd, unsigned long offset,int size, char *label)
+{
+#ifdef UseMMAP
+ unsigned long ret;
+#define MMAP_PROT (PROT_READ|PROT_WRITE|PROT_EXEC)
+
+#ifdef DEBUGMEM
+ ErrorF("_LoaderFileToMem(%d,%u(%u),%d,%s)",fd,offset,offsetbias,size,label);
+#endif
+
+ ret = (unsigned long) mmap(0,size,MMAP_PROT,MAP_PRIVATE,
+ fd,offset+offsetbias);
+
+ if(ret == -1)
+ FatalError("mmap() failed: %s\n", strerror(errno) );
+
+ return (void *)ret;
+#else
+ char *ptr;
+
+#ifdef DEBUGMEM
+ ErrorF("_LoaderFileToMem(%d,%u(%u),%d,%s)",fd,offset,offsetbias,size,label);
+#endif
+
+ if(size == 0){
+#ifdef DEBUGMEM
+ ErrorF("=NULL\n",ptr);
+#endif
+ return NULL;
+ }
+
+#ifndef __EMX__
+ if( (ptr=xf86loadercalloc(size,1)) == NULL )
+ FatalError("_LoaderFileToMem() malloc failed\n" );
+#else
+ if( (ptr=os2loader_calloc(size,1)) == NULL )
+ FatalError("_LoaderFileToMem() malloc failed\n" );
+#endif
+
+ if(lseek(fd,offset+offsetbias,SEEK_SET)<0)
+ FatalError("\n_LoaderFileToMem() lseek() failed: %s\n",strerror(errno));
+
+ if(read(fd,ptr,size)!=size)
+ FatalError("\n_LoaderFileToMem() read() failed: %s\n",strerror(errno));
+
+#ifdef DEBUGMEM
+ ErrorF("=%lx\n",ptr);
+#endif
+
+ return (void *)ptr;
+#endif
+}
+
+/*
+ * _LoaderFreeFileMem() free the memory in which a file was loaded.
+ */
+void
+_LoaderFreeFileMem(void *addr, int size)
+{
+#ifdef DEBUGMEM
+ ErrorF("_LoaderFreeFileMem(%x,%d)\n",addr,size);
+#endif
+#ifdef UseMMAP
+ munmap(addr,size);
+#else
+ if(size == 0)
+ return;
+
+ xf86loaderfree(addr);
+#endif
+
+ return;
+}
+
+int
+_LoaderFileRead(int fd, unsigned int offset, void *buf, int size)
+{
+ if(lseek(fd,offset+offsetbias,SEEK_SET)<0)
+ FatalError("_LoaderFileRead() lseek() failed: %s\n", strerror(errno) );
+
+ if(read(fd,buf,size)!=size)
+ FatalError("_LoaderFileRead() read() failed: %s\n", strerror(errno) );
+
+ return size;
+}
+
+static loaderPtr listHead = (loaderPtr) 0 ;
+
+static loaderPtr
+_LoaderListPush()
+{
+ loaderPtr item = xf86loadercalloc(1, sizeof (struct _loader));
+ item->next = listHead ;
+ listHead = item;
+
+ return item;
+}
+
+static loaderPtr
+_LoaderListPop(int handle)
+{
+ loaderPtr item=listHead;
+ loaderPtr *bptr=&listHead; /* pointer to previous node */
+
+ while(item) {
+ if( item->handle == handle ) {
+ *bptr=item->next; /* remove this from the list */
+ return item;
+ }
+ bptr=&(item->next);
+ item=item->next;
+ }
+
+ return 0;
+}
+
+/*
+ * _LoaderHandleToName() will return the name of the first module with a
+ * given handle. This requires getting the last module on the LIFO with
+ * the given handle.
+ */
+char *
+_LoaderHandleToName(int handle)
+{
+ loaderPtr item=listHead;
+ loaderPtr aritem=NULL;
+ loaderPtr lastitem=NULL;
+
+ if ( handle < 0 ) {
+ return "(built-in)";
+ }
+ while(item) {
+ if( item->handle == handle ) {
+ if( strchr(item->name,':') == NULL )
+ aritem=item;
+ else
+ lastitem=item;
+ }
+ item=item->next;
+ }
+
+ if( aritem )
+ return aritem->name;
+
+ if( lastitem )
+ return lastitem->name;
+
+ return 0;
+}
+
+/*
+ * _LoaderHandleToCanonicalName() will return the cname of the first module
+ * with a given handle. This requires getting the last module on the LIFO with
+ * the given handle.
+ */
+char *
+_LoaderHandleToCanonicalName(int handle)
+{
+ loaderPtr item=listHead;
+ loaderPtr lastitem=NULL;
+
+ if ( handle < 0 ) {
+ return "(built-in)";
+ }
+ while(item) {
+ if( item->handle == handle ) {
+ lastitem=item;
+ }
+ item=item->next;
+ }
+
+ if( lastitem )
+ return lastitem->cname;
+
+ return NULL;
+}
+
+/*
+ * _LoaderModuleToName() will return the name of the first module with a
+ * given handle. This requires getting the last module on the LIFO with
+ * the given handle.
+ */
+char *
+_LoaderModuleToName(int module)
+{
+ loaderPtr item=listHead;
+ loaderPtr aritem=NULL;
+ loaderPtr lastitem=NULL;
+
+ if ( module < 0 ) {
+ return "(built-in)";
+ }
+ while(item) {
+ if( item->module == module ) {
+ if( strchr(item->name,':') == NULL )
+ aritem=item;
+ else
+ lastitem=item;
+ }
+ item=item->next;
+ }
+
+ if( aritem )
+ return aritem->name;
+
+ if( lastitem )
+ return lastitem->name;
+
+ return 0;
+}
+
+/*
+ * _LoaderAddressToSection() will return the name of the file & section
+ * that contains the given address.
+ */
+int
+_LoaderAddressToSection(const unsigned long address, const char **module,
+ const char ** section)
+{
+ loaderPtr item=listHead;
+
+ while(item) {
+ if( (*section=item->funcs->AddressToSection(item->private, address)) != NULL ) {
+ *module=_LoaderModuleToName(item->module);
+ return 1;
+ }
+ item=item->next;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Add a list of symbols to the referenced list.
+ */
+
+static void
+AppendSymbol(symlist *list, const char *sym)
+{
+ list->list = xnfrealloc(list->list, (list->num + 1) * sizeof(char **));
+ list->list[list->num] = sym;
+ list->num++;
+}
+
+static void
+AppendSymList(symlist *list, const char **syms)
+{
+ while (*syms) {
+ AppendSymbol(list, *syms);
+ syms++;
+ }
+}
+
+static int
+SymInList(symlist *list, char *sym)
+{
+ int i;
+
+ for (i = 0; i < list->num; i++)
+ if (strcmp(list->list[i], sym) == 0)
+ return 1;
+
+ return 0;
+}
+
+void
+LoaderRefSymbols(const char *sym0, ...)
+{
+ va_list ap;
+ const char *s;
+
+ if (sym0 == NULL)
+ return;
+
+ va_start(ap, sym0);
+ s = sym0;
+ do {
+ AppendSymbol(&refList, s);
+ s = va_arg(ap, const char *);
+ } while (s != NULL);
+ va_end(ap);
+}
+
+void
+LoaderRefSymLists(const char **list0, ...)
+{
+ va_list ap;
+ const char **l;
+
+ if (list0 == NULL)
+ return;
+
+ va_start(ap, list0);
+ l = list0;
+ do {
+ AppendSymList(&refList, l);
+ l = va_arg(ap, const char **);
+ } while (l != NULL);
+ va_end(ap);
+}
+
+void
+LoaderVReqSymLists(const char **list0, va_list args)
+{
+ const char **l;
+
+ if (list0 == NULL)
+ return;
+
+ l = list0;
+ do {
+ AppendSymList(&reqList, l);
+ l = va_arg(args, const char **);
+ } while (l != NULL);
+}
+
+void
+LoaderReqSymLists(const char **list0, ...)
+{
+ va_list ap;
+
+ va_start(ap, list0);
+ LoaderVReqSymLists(list0, ap);
+ va_end(ap);
+}
+
+void
+LoaderVReqSymbols(const char *sym0, va_list args)
+{
+ const char *s;
+
+ if (sym0 == NULL)
+ return;
+
+ s = sym0;
+ do {
+ AppendSymbol(&reqList, s);
+ s = va_arg(args, const char *);
+ } while (s != NULL);
+}
+
+void
+LoaderReqSymbols(const char *sym0, ...)
+{
+ va_list ap;
+
+ va_start(ap, sym0);
+ LoaderVReqSymbols(sym0, ap);
+ va_end(ap);
+}
+
+/*
+ * _LoaderHandleUnresolved() decides what to do with an unresolved
+ * symbol. Symbols that are not on the "referenced" or "required" lists
+ * get a warning if they are unresolved. Symbols that are on the "required"
+ * list generate a fatal error if they are unresolved.
+ */
+
+int
+_LoaderHandleUnresolved(char *symbol, char *module)
+{
+ int fatalsym = 0;
+
+ if (xf86ShowUnresolved && !fatalsym) {
+ if (SymInList(&reqList, symbol)) {
+ fatalReqSym = 1;
+ ErrorF("Required symbol %s from module %s is unresolved!\n",
+ symbol, module);
+ }
+ if (!SymInList(&refList, symbol)) {
+ ErrorF("Symbol %s from module %s is unresolved!\n",
+ symbol, module);
+ }
+ }
+ return(fatalsym);
+}
+
+/*
+ * Handle an archive.
+ */
+void *
+ARCHIVELoadModule(loaderPtr modrec, int arfd, LOOKUP **ppLookup)
+{
+ loaderPtr tmp = NULL;
+ unsigned char magic[SARMAG];
+ struct ar_hdr hdr;
+#if defined(__powerpc__) && defined(Lynx)
+ struct fl_hdr fhdr;
+ char name[255];
+ int namlen;
+#endif
+ unsigned int size;
+ unsigned int offset;
+ int arnamesize, modnamesize;
+ char *slash, *longname;
+ char *nametable = NULL;
+ int nametablelen = 0;
+ LOOKUP *lookup_ret, *p;
+ LOOKUP *myLookup = NULL; /* Does realloc behave if ptr == 0? */
+ int modtype;
+ int i;
+ int numsyms = 0;
+ int resetoff;
+
+ /* lookup_ret = xf86loadermalloc(sizeof (LOOKUP *)); */
+
+ arnamesize=strlen(modrec->name);
+
+#if !(defined(__powerpc__) && defined(Lynx))
+ read(arfd,magic,SARMAG);
+
+ if(strncmp((const char *)magic,ARMAG,SARMAG) != 0 ) {
+ ErrorF("ARCHIVELoadModule: wrong magic!!\n" );
+ return NULL;
+ }
+ resetoff=SARMAG;
+#else
+ read(arfd,&fhdr,FL_HSZ);
+
+ if(strncmp(fhdr.fl_magic,AIAMAG,SAIAMAG) != 0 ) {
+ ErrorF("ARCHIVELoadModule: wrong magic!!\n" );
+ return NULL;
+ }
+ resetoff=FL_HSZ;
+#endif /* __powerpc__ && Lynx */
+
+#ifdef DEBUGAR
+ ErrorF("Looking for archive members starting at offset %o\n", offset );
+#endif
+
+ while( read(arfd,&hdr,sizeof(struct ar_hdr)) ) {
+
+ longname = NULL;
+ sscanf(hdr.ar_size,"%d",&size);
+#if defined(__powerpc__) && defined(Lynx)
+ sscanf(hdr.ar_namlen,"%d",&namlen);
+ name[0]=hdr.ar_name[0];
+ name[1]=hdr.ar_name[1];
+ read(arfd,&name[2],namlen);
+ name[namlen]='\0';
+ offset=lseek(arfd,0,SEEK_CUR);
+ if( offset&0x1 ) /* odd value */
+ offset=lseek(arfd,1,SEEK_CUR); /* make it an even boundary */
+#endif
+ offset=lseek(arfd,0,SEEK_CUR);
+
+ /* Check for a Symbol Table */
+ if( (hdr.ar_name[0] == '/' && hdr.ar_name[1] == ' ') ||
+#if defined(__powerpc__) && defined(Lynx)
+ namlen == 0 ||
+#endif
+ strncmp(hdr.ar_name, "__.SYMDEF", 9) == 0 ) {
+ /* If the file name is NULL, then it is a symbol table */
+#ifdef DEBUGAR
+ ErrorF("Symbol Table Member '%16.16s', size %d, offset %d\n",
+ hdr.ar_name, size, offset );
+ ErrorF("Symbol table size %d\n", size );
+#endif
+ offset=lseek(arfd,offset+size,SEEK_SET);
+ if( offset&0x1 ) /* odd value */
+ offset=lseek(arfd,1,SEEK_CUR); /* make it an even boundary */
+ continue;
+ }
+
+ /* Check for a String Table */
+ if( hdr.ar_name[0] == '/' && hdr.ar_name[1] == '/') {
+ /* If the file name is '/', then it is a string table */
+#ifdef DEBUGAR
+ ErrorF("String Table Member '%16.16s', size %d, offset %d\n",
+ hdr.ar_name, size, offset );
+ ErrorF("String table size %d\n", size );
+#endif
+ nametablelen = size;
+ nametable=(char *)xf86loadermalloc(nametablelen);
+ read(arfd, nametable, size);
+ offset=lseek(arfd,0,SEEK_CUR);
+ /* offset=lseek(arfd,offset+size,SEEK_SET); */
+ if( offset&0x1 ) /* odd value */
+ offset=lseek(arfd,1,SEEK_CUR); /* make it an even boundary */
+ continue;
+ }
+
+ if (hdr.ar_name[0] == '/') {
+ /* SYS V r4 style long member name */
+ int nameoffset = atol(&hdr.ar_name[1]);
+ char *membername;
+ if (!nametable) {
+ ErrorF( "Missing string table whilst processing %s\n",
+ modrec->name ) ;
+ offsetbias = 0;
+ return NULL;
+ }
+ if (nameoffset > nametablelen) {
+ ErrorF( "Invalid string table offset (%s) whilst processing %s\n",
+ hdr.ar_name, modrec->name ) ;
+ offsetbias = 0;
+ xf86loaderfree(nametable);
+ return NULL;
+ }
+ membername = nametable + nameoffset;
+ slash=strchr(membername,'/');
+ if (slash)
+ *slash = '\0';
+ longname = xf86loadermalloc(arnamesize + strlen(membername) + 2);
+ strcpy(longname,modrec->name);
+ strcat(longname,":");
+ strcat(longname,membername);
+ } else if (hdr.ar_name[0] == '#' && hdr.ar_name[1] == '1' &&
+ hdr.ar_name[2] == '/') {
+ /* BSD 4.4 style long member name */
+ if (sscanf(hdr.ar_name+3, "%d", &modnamesize) != 1) {
+ ErrorF("Bad archive member %s\n", hdr.ar_name);
+ offsetbias = 0;
+ return NULL;
+ }
+ /* allocate space for fully qualified name */
+ longname = xf86loadermalloc(arnamesize + modnamesize + 2);
+ strcpy(longname,modrec->name);
+ strcat(longname,":");
+ i = read(arfd, longname+modnamesize+1, modnamesize);
+ if (i != modnamesize) {
+ ErrorF("Bad archive member %d\n", hdr.ar_name);
+ xf86loaderfree(longname);
+ offsetbias = 0;
+ return NULL;
+ }
+ longname[i] = '\0';
+ offset += i;
+ size -= i;
+ } else {
+ /* Regular archive member */
+#ifdef DEBUGAR
+ ErrorF("Member '%16.16s', size %d, offset %x\n",
+#if !(defined(__powerpc__) && defined(Lynx))
+ hdr.ar_name,
+#else
+ name,
+#endif
+ size, offset );
+#endif
+
+ slash=strchr(hdr.ar_name,'/');
+ if (slash == NULL) {
+ /* BSD format without trailing slash */
+ slash = strchr(hdr.ar_name,' ');
+ }
+ /* SM: Make sure we do not overwrite other parts of struct */
+
+ if((slash - hdr.ar_name) > sizeof(hdr.ar_name))
+ slash = hdr.ar_name + sizeof(hdr.ar_name) -1;
+ *slash='\000';
+ }
+ if( (modtype=_GetModuleType(arfd,offset)) < 0 ) {
+ ErrorF( "%s is an unrecognized module type\n", hdr.ar_name ) ;
+ offsetbias=0;
+ if (nametable)
+ xf86loaderfree(nametable);
+ return NULL;
+ }
+
+ tmp=_LoaderListPush();
+
+ tmp->handle = modrec->handle;
+ tmp->module = moduleseq++;
+ tmp->cname = xf86loadermalloc(strlen(modrec->cname) + 1);
+ strcpy(tmp->cname, modrec->cname);
+ tmp->funcs=&funcs[modtype];
+ if (longname == NULL) {
+ modnamesize=strlen(hdr.ar_name);
+ tmp->name=(char *)xf86loadermalloc(arnamesize+modnamesize+2 );
+ strcpy(tmp->name,modrec->name);
+ strcat(tmp->name,":");
+ strcat(tmp->name,hdr.ar_name);
+
+ } else {
+ tmp->name = longname;
+ }
+ offsetbias=offset;
+
+ if((tmp->private = funcs[modtype].LoadModule(tmp, arfd,
+ &lookup_ret))
+ == NULL) {
+ ErrorF( "Failed to load %s\n", hdr.ar_name ) ;
+ offsetbias=0;
+ if (nametable)
+ xf86loaderfree(nametable);
+ return NULL;
+ }
+
+ offset=lseek(arfd,offset+size,SEEK_SET);
+ if( offset&0x1 ) /* odd value */
+ lseek(arfd,1,SEEK_CUR); /* make it an even boundary */
+
+ /* Add the lookup table returned from funcs.LoadModule to the
+ * one we're going to return.
+ */
+ for (i = 0, p = lookup_ret; p && p->symName; i++, p++)
+ ;
+ if (i) {
+ myLookup = xf86loaderrealloc(myLookup, (numsyms + i + 1)
+ * sizeof (LOOKUP));
+ if (!myLookup)
+ continue; /* Oh well! */
+
+ memcpy(&(myLookup[numsyms]), lookup_ret, i * sizeof (LOOKUP));
+ numsyms += i;
+ myLookup[numsyms].symName = 0;
+ }
+ xf86loaderfree(lookup_ret);
+ }
+ /* xf86loaderfree(lookup_ret); */
+ offsetbias=0;
+
+ *ppLookup = myLookup;
+ if (nametable)
+ xf86loaderfree(nametable);
+
+ if (tmp)
+ return tmp->private;
+ else
+ return 0;
+}
+
+/*
+ * Relocation list manipulation routines
+ */
+
+/*
+ * _LoaderGetRelocations() Return the list of outstanding relocations
+ */
+LoaderRelocPtr
+_LoaderGetRelocations(void *mod)
+{
+ loader_funcs *formatrec = (loader_funcs *)mod;
+
+ return &(formatrec->pRelocs);
+}
+
+/*
+ * Public Interface to the loader.
+ */
+
+int
+LoaderOpen(const char *module, const char *cname, int handle,
+ int *errmaj, int *errmin, int *wasLoaded)
+{
+ loaderPtr tmp ;
+ int new_handle, modtype ;
+ int fd;
+ LOOKUP *pLookup;
+
+#if defined(DEBUG)
+ ErrorF("LoaderOpen(%s)\n", module );
+#endif
+
+ /*
+ * Check to see if the module is already loaded.
+ * Only if we are loading it into an existing namespace.
+ * If it is to be loaded into a new namespace, don't check.
+ */
+ if (handle >= 0) {
+ tmp = listHead;
+ while ( tmp ) {
+#ifdef DEBUGLIST
+ ErrorF("strcmp(%x(%s),{%x} %x(%s))\n", module,module,&(tmp->name),
+ tmp->name,tmp->name );
+#endif
+ if ( ! strcmp( module, tmp->name )) {
+ refCount[tmp->handle]++;
+ if (wasLoaded)
+ *wasLoaded = 1;
+ xf86MsgVerb(X_INFO, 2, "Reloading %s\n", module);
+ return tmp->handle;
+ }
+ tmp = tmp->next ;
+ }
+ }
+
+ /*
+ * OK, it's a new one. Add it.
+ */
+ xf86Msg(X_INFO, "Loading %s\n", module ) ;
+ if (wasLoaded)
+ *wasLoaded = 0;
+
+ /*
+ * Find a free handle.
+ */
+ new_handle = 1;
+ while ( freeHandles[new_handle] && new_handle < MAX_HANDLE )
+ new_handle ++ ;
+
+ if ( new_handle == MAX_HANDLE ) {
+ xf86Msg(X_ERROR, "Out of loader space\n" ) ; /* XXX */
+ if(errmaj) *errmaj = LDR_NOSPACE;
+ return -1 ;
+ }
+
+ freeHandles[new_handle] = HANDLE_USED ;
+ refCount[new_handle] = 1;
+
+ if( (fd=open(module, O_RDONLY)) < 0 ) {
+ xf86Msg(X_ERROR, "Unable to open %s\n", module );
+ freeHandles[new_handle] = HANDLE_FREE ;
+ if(errmaj) *errmaj = LDR_NOMODOPEN;
+ if(errmin) *errmin = errno;
+ return -1 ;
+ }
+
+ if( (modtype=_GetModuleType(fd,0)) < 0 ) {
+ xf86Msg(X_ERROR, "%s is an unrecognized module type\n", module ) ;
+ freeHandles[new_handle] = HANDLE_FREE ;
+ if(errmaj) *errmaj = LDR_UNKTYPE;
+ return -1;
+ }
+
+ tmp=_LoaderListPush();
+ tmp->name = xf86loadermalloc(strlen(module) + 1);
+ strcpy(tmp->name, module);
+ tmp->cname = xf86loadermalloc(strlen(cname) + 1);
+ strcpy(tmp->cname, cname);
+ tmp->handle = new_handle;
+ tmp->module = moduleseq++;
+ tmp->funcs=&funcs[modtype];
+
+ if((tmp->private = funcs[modtype].LoadModule(tmp,fd, &pLookup)) == NULL) {
+ xf86Msg(X_ERROR, "Failed to load %s\n", module ) ;
+ _LoaderListPop(new_handle);
+ freeHandles[new_handle] = HANDLE_FREE ;
+ if(errmaj) *errmaj = LDR_NOLOAD;
+ return -1;
+ }
+
+ LoaderAddSymbols(new_handle, tmp->module, pLookup);
+ xf86loaderfree(pLookup);
+
+ close(fd);
+
+ return new_handle;
+}
+
+int
+LoaderHandleOpen(int handle)
+{
+ if (handle < 0 || handle >= MAX_HANDLE)
+ return -1;
+
+ if (freeHandles[handle] != HANDLE_USED)
+ return -1;
+
+ refCount[handle]++;
+ return handle;
+}
+
+void *
+LoaderSymbol(const char *sym)
+{
+ int i;
+ itemPtr item = NULL;
+ for (i = 0; i < numloaders; i++)
+ funcs[i].ResolveSymbols(&funcs[i]);
+
+ item = (itemPtr) LoaderHashFind(sym);
+
+ if ( item )
+ return item->address ;
+ else
+#ifdef DLOPEN_SUPPORT
+ return(DLFindSymbol(sym));
+#else
+ return NULL;
+#endif
+}
+
+int
+LoaderResolveSymbols(void)
+{
+ int i;
+ for(i=0;i<numloaders;i++)
+ funcs[i].ResolveSymbols(&funcs[i]);
+ return 0;
+}
+
+int
+LoaderCheckUnresolved(int delay_flag )
+{
+ int i,ret=0;
+ LoaderResolveOptions delayFlag = delay_flag;
+
+ LoaderResolveSymbols();
+
+ if (delayFlag == LD_RESOLV_NOW) {
+ if (check_unresolved_sema > 0)
+ check_unresolved_sema--;
+ else
+ xf86Msg(X_WARNING, "LoaderCheckUnresolved: not enough "
+ "MAGIC_DONT_CHECK_UNRESOLVED\n");
+ }
+
+ if (!check_unresolved_sema || delayFlag == LD_RESOLV_FORCE)
+ for(i=0;i<numloaders;i++)
+ if (funcs[i].CheckForUnresolved(&funcs[i]))
+ ret=1;
+
+ if (fatalReqSym)
+ FatalError("Some required symbols were unresolved\n");
+
+ return ret;
+}
+
+void
+LoaderDefaultFunc(void)
+{
+ ErrorF("\n\n\tThis should not happen!\n"
+ "\tAn unresolved function was called!\n");
+ FatalError("\n");
+}
+
+int
+LoaderUnload(int handle)
+{
+ loaderRec fakeHead ;
+ loaderPtr tmp = & fakeHead ;
+
+ if ( handle < 0 || handle > MAX_HANDLE )
+ return -1;
+
+ /*
+ * check the reference count, only free it if it goes to zero
+ */
+ if (--refCount[handle])
+ return 0;
+ /*
+ * find the loaderRecs associated with this handle.
+ */
+
+ while( (tmp=_LoaderListPop(handle)) != NULL ) {
+ if( strchr(tmp->name,':') == NULL ) {
+ /* It is not a member of an archive */
+ xf86Msg(X_INFO, "Unloading %s\n", tmp->name ) ;
+ }
+ tmp->funcs->LoaderUnload(tmp->private);
+ xf86loaderfree(tmp->name);
+ xf86loaderfree(tmp->cname);
+ xf86loaderfree(tmp);
+ }
+
+ freeHandles[handle] = HANDLE_FREE ;
+
+return 0;
+}
+
+void
+LoaderDuplicateSymbol(const char *symbol, const int handle)
+{
+ ErrorF("Duplicate symbol %s in %s\n", symbol,
+ listHead ? listHead->name : "(built-in)");
+ ErrorF("Also defined in %s\n", _LoaderHandleToName(handle));
+ FatalError("Module load failure\n");
+}
+
+/* GDB Sync function */
+void _loader_debug_state()
+{
+}
diff --git a/xc/programs/Xserver/hw/xfree86/loader/loader.h b/xc/programs/Xserver/hw/xfree86/loader/loader.h
new file mode 100644
index 000000000..8b7b551a7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/loader.h
@@ -0,0 +1,262 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loader.h,v 1.21 1999/06/14 07:31:55 dawes Exp $ */
+
+/*
+ *
+ * Copyright 1995-1998 by Metro Link, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. 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 _LOADER_H
+#define _LOADER_H
+
+#include "sym.h"
+
+#if defined(Lynx) && defined(sun)
+#define const /**/
+#endif
+
+#if (defined(__i386__) || defined(__ix86)) && !defined(i386)
+#define i386
+#endif
+
+#include <X11/Xosdefs.h>
+#include <X11/Xfuncproto.h>
+#include <X11/Xmd.h>
+
+/* For LOOKUP definition */
+#include "sym.h"
+
+#define LD_UNKNOWN -1
+#define LD_ARCHIVE 0
+#define LD_ELFOBJECT 1
+#define LD_COFFOBJECT 2
+#define LD_XCOFFOBJECT 3
+#define LD_AOUTOBJECT 4
+#define LD_AOUTDLOBJECT 5
+#define LD_ELFDLOBJECT 6
+
+#define LD_PROCESSED_ARCHIVE -1
+
+/* #define UNINIT_SECTION */
+#define HANDLE_IN_HASH_ENTRY
+
+/*
+ * COFF Section nmumbers
+ */
+#define N_TEXT 1
+#define N_DATA 2
+#define N_BSS 3
+#define N_COMMENT 4
+
+#define TestFree(a) if (a) { xfree (a); a = NULL; }
+
+#define HASHDIV 10
+#define HASHSIZE (1<<HASHDIV)
+
+typedef struct _elf_reloc *ELFRelocPtr;
+typedef struct _elf_COMMON *ELFCommonPtr;
+typedef struct _coff_reloc *COFFRelocPtr;
+typedef struct _coff_COMMON *COFFCommonPtr;
+typedef struct AOUT_RELOC *AOUTRelocPtr;
+typedef struct AOUT_COMMON *AOUTCommonPtr;
+
+typedef struct _LoaderReloc {
+ int modtype;
+ struct _LoaderReloc *next;
+ COFFRelocPtr coff_reloc;
+ ELFRelocPtr elf_reloc;
+ AOUTRelocPtr aout_reloc;
+} LoaderRelocRec, *LoaderRelocPtr;
+
+typedef struct _loader_item {
+ char *name ;
+ void *address ;
+ struct _loader_item *next ;
+ int handle ;
+ int module ;
+#if defined(__powerpc__)
+ /*
+ * PowerPC file formats require special routines in some circumstances
+ * to assist in the linking process. See the specific loader for
+ * more details.
+ */
+ union {
+ unsigned short plt[8]; /* ELF */
+ unsigned short glink[14]; /* XCOFF */
+ } code ;
+#endif
+ } itemRec, *itemPtr ;
+
+/* The following structures provide an interface to GDB (note that GDB
+ has copies of the definitions - if you change anything here make
+ sure that the changes are also made to GDB */
+
+typedef struct {
+ char *name; /* Name of this symbol */
+ unsigned int namelen; /* Name of this module */
+ void *addr; /* Start address of the .text section */
+} LDRCommon, *LDRCommonPtr;
+
+typedef struct x_LDRModuleRec{
+ unsigned int version; /* Version of this struct */
+ char *name; /* Name of this module */
+ unsigned int namelen; /* Length of name */
+ void *text; /* Start address of the .text section */
+ void *data; /* Start address of the .data section */
+ void *rodata; /* Start address of the .rodata section */
+ void *bss; /* Start address of the .bss section */
+ LDRCommonPtr commons; /* List of commmon symbols */
+ int commonslen; /* Number of common symbols */
+ struct x_LDRModuleRec *next; /* Next module record in chain */
+} LDRModuleRec, *LDRModulePtr;
+
+extern char DebuggerPresent;
+extern LDRModulePtr ModList;
+extern LDRCommonPtr ldrCommons;
+extern int nCommons;
+
+/*
+ * The loader uses loader specific alloc/calloc/free functions that
+ * are mapped to either to the regular Xserver functions, or in a couple
+ * of special cases, mapped to the C library functions.
+ */
+#if !defined(PowerMAX_OS) && !(defined(linux) && (defined(__alpha__) || defined(__powerpc__))) && 0
+#define xf86loadermalloc(size) xalloc(size)
+#define xf86loaderrealloc(ptr,size) xrealloc(ptr,size)
+#define xf86loadercalloc(num,size) xcalloc(num,size)
+#define xf86loaderfree(ptr) xfree(ptr)
+#define xf86loaderstrdup(ptr) xstrdup(ptr)
+#else
+/*
+ * On Some OSes, xalloc() et al uses mmap to allocate space for large
+ * allocation. This has the effect of placing the text section of some
+ * modules very far away from the rest which are placed on the heap.
+ * Certain relocations are limited in the size of the offsets that can be
+ * handled, and this seperation causes these relocation to overflow. This
+ * is fixed by just using the C library allocation functions for the loader
+ * to ensure that all text sections are located on the heap. OSes that have
+ * this problem are:
+ * PowerMAX_OS/PPC
+ * Linux/Alpha
+ * Linux/PPC
+ */
+#define xf86loadermalloc(size) malloc(size)
+#define xf86loaderrealloc(ptr,size) realloc(ptr,size)
+#define xf86loadercalloc(num,size) calloc(num,size)
+#define xf86loaderfree(ptr) free(ptr)
+#define xf86loaderstrdup(ptr) strdup(ptr)
+#endif
+
+typedef struct _loader *loaderPtr;
+
+/*
+ * _loader_funcs hold the entry points for a module format.
+ */
+
+typedef void * (*LoadModuleProcPtr)(loaderPtr modrec, int fd, LOOKUP **);
+typedef void (*ResolveSymbolsProcPtr)(void *);
+typedef int (*CheckForUnresolvedProcPtr)(void *);
+typedef char * (*AddressToSectionProcPtr)(void *, unsigned long);
+typedef void (*LoaderUnloadProcPtr)(void *);
+
+typedef struct _loader_funcs {
+ LoadModuleProcPtr LoadModule;
+ ResolveSymbolsProcPtr ResolveSymbols;
+ CheckForUnresolvedProcPtr CheckForUnresolved;
+ AddressToSectionProcPtr AddressToSection;
+ LoaderUnloadProcPtr LoaderUnload;
+ LoaderRelocRec pRelocs; /* type specific relocations */
+} loader_funcs;
+
+/* Each module loaded has a loaderRec */
+typedef struct _loader {
+ int handle; /* Unique id used to remove symbols from
+ this module when it is unloaded */
+ int module; /* Unique id to identify compilation units */
+ char *name;
+ char *cname;
+ void *private; /* format specific data */
+ loader_funcs *funcs; /* funcs for operating on this module */
+ loaderPtr next;
+} loaderRec;
+
+/* Compiled-in version information */
+typedef struct {
+ INT32 xf86Version;
+ INT32 ansicVersion;
+ INT32 videodrvVersion;
+ INT32 xinputVersion;
+ INT32 extensionVersion;
+ INT32 fontVersion;
+} ModuleVersions;
+extern ModuleVersions LoaderVersionInfo;
+
+/* Internal Functions */
+
+void LoaderAddSymbols(int, int, LOOKUP *);
+void LoaderDefaultFunc(void);
+void LoaderDuplicateSymbol(const char *, const int);
+void LoaderFixups(void);
+void LoaderResolve(void);
+int LoaderResolveSymbols(void);
+int _LoaderHandleUnresolved(char *, char *);
+void LoaderHashAdd(itemPtr);
+itemPtr LoaderHashDelete(const char *);
+itemPtr LoaderHashFind(const char *);
+void LoaderHashTraverse(void *, int (*)(void *, itemPtr));
+void LoaderPrintAddress(const char *);
+void LoaderPrintItem(itemPtr);
+void LoaderPrintSymbol(unsigned long);
+void LoaderDumpSymbols(void);
+char *_LoaderModuleToName(int);
+int _LoaderAddressToSection(const unsigned long, const char **, const char **);
+int LoaderOpen(const char *, const char *, int, int *, int *, int *);
+int LoaderHandleOpen(int);
+
+/*
+ * File interface functions
+ */
+void *_LoaderFileToMem(int fd, unsigned long offset, int size, char *label);
+void _LoaderFreeFileMem(void *addr, int size);
+int _LoaderFileRead(int fd, unsigned int offset, void *addr, int size);
+
+/*
+ * Relocation list manipulation routines
+ */
+LoaderRelocPtr _LoaderGetRelocations(void *);
+
+/*
+ * object to name lookup routines
+ */
+char * _LoaderHandleToName(int handle);
+char * _LoaderHandleToCanonicalName(int handle);
+
+/*
+ * Entry points for the different loader types
+ */
+#include "aoutloader.h"
+#include "coffloader.h"
+#include "elfloader.h"
+#include "dlloader.h"
+/* LD_ARCHIVE */
+void *ARCHIVELoadModule(loaderPtr, int, LOOKUP **);
+
+extern void _loader_debug_state(void);
+
+#endif /* _LOADER_H */
diff --git a/xc/programs/Xserver/hw/xfree86/loader/loaderProcs.h b/xc/programs/Xserver/hw/xfree86/loader/loaderProcs.h
new file mode 100644
index 000000000..d2d2e3241
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/loaderProcs.h
@@ -0,0 +1,83 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loaderProcs.h,v 1.15 1999/04/18 04:08:47 dawes Exp $ */
+
+/*
+ *
+ * Copyright 1995-1998 by Metro Link, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. 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 _LOADERPROCS_H
+#define _LOADERPROCS_H
+
+#define IN_LOADER
+#include "xf86Module.h"
+#include "fontmod.h"
+
+typedef struct module_desc {
+ struct module_desc *child;
+ struct module_desc *sib;
+ struct module_desc *parent;
+ struct module_desc *demand_next;
+ char *name;
+ char *filename;
+ char *identifier;
+ XID client_id;
+ int in_use;
+ int handle;
+ ModuleSetupProc SetupProc;
+ ModuleTearDownProc TearDownProc;
+ void *TearDownData; /* returned from SetupProc */
+ const char *path;
+} ModuleDesc, *ModuleDescPtr;
+
+
+/*
+ * Extenal API for the loader
+ */
+
+void LoaderInit(void);
+
+ModuleDescPtr LoadDriver(const char *, const char *, int, pointer, int *,
+ int *);
+ModuleDescPtr LoadModule(const char *, const char *, const char **,
+ const char **, pointer, const XF86ModReqInfo *,
+ int *, int *);
+ModuleDescPtr LoadSubModule(ModuleDescPtr, const char *,
+ const char **, const char **, pointer,
+ const XF86ModReqInfo *, int *, int *);
+ModuleDescPtr DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent);
+void LoadFont (FontModule *);
+void UnloadModule (ModuleDescPtr);
+void UnloadSubModule (ModuleDescPtr);
+void UnloadDriver (ModuleDescPtr);
+void FreeModuleDesc (ModuleDescPtr mod);
+ModuleDescPtr NewModuleDesc (const char *);
+ModuleDescPtr AddSibling (ModuleDescPtr head, ModuleDescPtr new);
+void LoaderSetPath(const char *path);
+
+
+void LoaderVReqSymLists(const char **, va_list args);
+void LoaderVReqSymbols(const char *, va_list args);
+
+void LoaderShowStack(void);
+void *LoaderSymbolHandle(const char *, int);
+int LoaderUnload(int);
+
+#endif /* _LOADERPROCS_H */
diff --git a/xc/programs/Xserver/hw/xfree86/loader/loadfont.c b/xc/programs/Xserver/hw/xfree86/loader/loadfont.c
new file mode 100644
index 000000000..8ab5d0d6e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/loadfont.c
@@ -0,0 +1,53 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loadfont.c,v 1.2 1998/12/13 12:42:41 dawes Exp $ */
+
+/* Maybe this file belongs in lib/font/fontfile/module/ ? */
+
+#define LOADERDECLARATIONS
+#include "loaderProcs.h"
+#include "misc.h"
+#include "xf86.h"
+
+FontModule *FontModuleList = NULL;
+static int numFontModules = 0;
+
+
+static FontModule *
+NewFontModule(void)
+{
+ FontModule *save = FontModuleList;
+ int n;
+
+ /* Sanity check */
+ if (!FontModuleList)
+ numFontModules = 0;
+
+ n = numFontModules + 1;
+ FontModuleList = xrealloc(FontModuleList, (n + 1) * sizeof(FontModule));
+ if (FontModuleList == NULL) {
+ FontModuleList = save;
+ return NULL;
+ } else {
+ numFontModules++;
+ FontModuleList[numFontModules].name = NULL;
+ return FontModuleList + (numFontModules - 1);
+ }
+}
+
+void
+LoadFont(FontModule *f)
+{
+ FontModule *newfont;
+
+ if (f == NULL)
+ return;
+
+ if (!(newfont = NewFontModule()))
+ return;
+
+ xf86MsgVerb(X_INFO, 2, "Loading font %s\n", f->name);
+
+ newfont->name = f->name;
+ newfont->initFunc = f->initFunc;
+ newfont->module = f->module;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/loader/loadmod.c b/xc/programs/Xserver/hw/xfree86/loader/loadmod.c
new file mode 100644
index 000000000..993f827fa
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/loadmod.c
@@ -0,0 +1,1266 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/loadmod.c,v 1.47 1999/06/27 09:20:24 dawes Exp $ */
+
+/*
+ *
+ * Copyright 1995-1998 by Metro Link, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* This file is best viewed with tab stops set to 4 spaces */
+
+#include "os.h"
+/* For stat() and related stuff */
+#define NO_OSLIB_PROTOTYPES
+#define NO_COMPILER_H
+#include "xf86_OSlib.h"
+#if defined(SVR4)
+#include <sys/stat.h>
+#endif
+#define LOADERDECLARATIONS
+#include "loaderProcs.h"
+#include "misc.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#ifdef XINPUT
+#include "xf86Xinput.h"
+#endif
+#include "loader.h"
+#include "xf86Optrec.h"
+
+#include <sys/types.h>
+#include <regex.h>
+#include <dirent.h>
+#include <limits.h>
+
+extern int check_unresolved_sema;
+
+typedef struct _pattern {
+ const char * pattern;
+ regex_t rex;
+} PatternRec, *PatternPtr;
+
+/* Prototypes for static functions */
+static char *FindModule (const char *, const char *, const char **, PatternPtr);
+static Bool CheckVersion (const char *, XF86ModuleVersionInfo *,
+ const XF86ModReqInfo *);
+static void UnloadModuleOrDriver (ModuleDescPtr mod);
+static char *LoaderGetCanonicalName(const char *, PatternPtr);
+static void RemoveChild(ModuleDescPtr);
+
+ModuleVersions LoaderVersionInfo = {
+ XF86_VERSION_CURRENT,
+ ABI_ANSIC_VERSION,
+ ABI_VIDEODRV_VERSION,
+ ABI_XINPUT_VERSION,
+ ABI_EXTENSION_VERSION,
+ ABI_FONT_VERSION
+};
+
+void
+LoaderFixups (void)
+{
+ /* Need to call LRS here because the frame buffers get loaded last,
+ * and the drivers depend on them. */
+
+ LoaderResolveSymbols ();
+}
+
+static void
+FreeStringList(char **paths)
+{
+ char **p;
+
+ if (!paths)
+ return;
+
+ for (p = paths; *p; p++)
+ xfree(*p);
+
+ xfree(paths);
+}
+
+static char **defaultPathList = NULL;
+
+/*
+ * Convert a comma-separated path into a NULL-terminated array of path
+ * elements, rejecting any that are not full absolute paths, and appending
+ * a '/' when it isn't already present.
+ */
+static char **
+InitPathList(const char *path)
+{
+ char *fullpath = NULL;
+ char *elem = NULL;
+ char **list = NULL, **save = NULL;
+ int len;
+ int addslash;
+ int n = 0;
+
+ if (!path)
+ return defaultPathList;
+
+ fullpath = xstrdup(path);
+ if (!fullpath)
+ return NULL;
+ elem = strtok(fullpath, ",");
+ while (elem) {
+ /* Only allow fully specified paths */
+#ifndef __EMX__
+ if (*elem == '/')
+#else
+ if (*elem == '/' || (strlen(elem) > 2 && isalpha(elem[0]) &&
+ elem[1] == ':' && elem[2] == '/'))
+#endif
+ {
+ len = strlen(elem);
+ addslash = (elem[len - 1] != '/');
+ if (addslash)
+ len++;
+ save = list;
+ list = xrealloc(list, (n + 2) * sizeof(char *));
+ if (!list) {
+ if (save) {
+ save[n] = NULL;
+ FreeStringList(save);
+ }
+ xfree(fullpath);
+ return NULL;
+ }
+ list[n] = xalloc(len + 1);
+ if (!list[n]) {
+ FreeStringList(list);
+ xfree(fullpath);
+ return NULL;
+ }
+ strcpy(list[n], elem);
+ if (addslash) {
+ list[n][len - 1] = '/';
+ list[n][len] = '\0';
+ }
+ n++;
+ }
+ elem = strtok(NULL, ",");
+ }
+ if (list)
+ list[n] = NULL;
+ return list;
+}
+
+static void
+FreePathList(char **pathlist)
+{
+ if (pathlist && pathlist != defaultPathList)
+ FreeStringList(pathlist);
+}
+
+void
+LoaderSetPath(const char *path)
+{
+ if (!path)
+ return;
+
+ defaultPathList = InitPathList(path);
+}
+
+/* Standard set of module subdirectories to search, in order of preference */
+static const char *stdSubdirs[] =
+{
+ "",
+ "drivers/",
+ "input/",
+ "extensions/",
+ "fonts/",
+ "internal/",
+ NULL
+};
+
+/*
+ * Standard set of module name patterns to check, in order of preference
+ * These are regular expressions (suitable for use with POSIX regex(3)).
+ */
+static PatternRec stdPatterns[] = {
+ { "^lib(.*)\\.so$", },
+ { "^lib(.*)\\.a$", },
+ { "(.*)_drv\\.so$", },
+ { "(.*)_drv\\.o$", },
+ { "(.*)\\.so$", },
+ { "(.*)\\.a$", },
+ { "(.*)\\.o$", },
+ { NULL, }
+};
+
+static PatternPtr
+InitPatterns(const char **patternlist)
+{
+ char errmsg[80];
+ int i, e;
+ PatternPtr patterns = NULL;
+ PatternPtr p = NULL;
+ static int firstTime = 1;
+ const char **s;
+
+ if (firstTime) {
+ /* precompile stdPatterns */
+ firstTime = 0;
+ for (p = stdPatterns; p->pattern; p++)
+ if ((e = regcomp(&p->rex, p->pattern, REG_EXTENDED)) != 0) {
+ regerror(e, &p->rex, errmsg, sizeof(errmsg));
+ FatalError("InitPatterns: regcomp error for `%s': %s\n",
+ p->pattern, errmsg);
+ }
+ }
+
+ if (patternlist) {
+ for (i = 0, s = patternlist; *s; i++, s++)
+ if (*s == DEFAULT_LIST)
+ i += sizeof(stdPatterns) / sizeof(stdPatterns[0]) - 1 - 1;
+ patterns = xalloc((i + 1) * sizeof(PatternRec));
+ if (!patterns) {
+ return NULL;
+ }
+ for (i = 0, s = patternlist; *s; i++, s++)
+ if (*s != DEFAULT_LIST) {
+ p = patterns + i;
+ p->pattern = *s;
+ if ((e = regcomp(&p->rex, p->pattern, REG_EXTENDED)) != 0) {
+ regerror(e, &p->rex, errmsg, sizeof(errmsg));
+ ErrorF("InitPatterns: regcomp error for `%s': %s\n",
+ p->pattern, errmsg);
+ i--;
+ }
+ } else {
+ for (p = stdPatterns; p->pattern; p++, i++)
+ patterns[i] = *p;
+ if (p != stdPatterns)
+ i--;
+ }
+ patterns[i].pattern = NULL;
+ } else
+ patterns = stdPatterns;
+ return patterns;
+}
+
+static void
+FreePatterns(PatternPtr patterns)
+{
+ if (patterns && patterns != stdPatterns)
+ xfree(patterns);
+}
+
+static const char **
+InitSubdirs(const char **subdirlist)
+{
+ int i;
+ char **subdirs = NULL;
+ const char **s, **stmp = NULL;
+ const char *osname;
+ const char *slash;
+ int oslen = 0, len;
+ Bool indefault;
+
+ if (subdirlist == NULL) {
+ subdirlist = xalloc(2 * sizeof(char *));
+ if (subdirlist == NULL)
+ return NULL;
+ subdirlist[0] = DEFAULT_LIST;
+ subdirlist[1] = NULL;
+ }
+
+ LoaderGetOS(&osname, NULL, NULL, NULL);
+ oslen = strlen(osname);
+
+ {
+ /* Count number of entries and check for invalid paths */
+ for (i = 0, s = subdirlist; *s; i++, s++) {
+ if (*s == DEFAULT_LIST) {
+ i += sizeof(stdSubdirs) / sizeof(stdSubdirs[0]) - 1 - 1;
+ } else {
+ /*
+ * Path validity check. Don't allow absolute paths, or
+ * paths containing "..". To catch absolute paths on
+ * platforms that use driver letters, don't allow the ':'
+ * character to appear at all.
+ */
+ if (**s == '/' || **s == '\\' || strchr(*s, ':') ||
+ strstr(*s, "..")) {
+ xf86Msg(X_ERROR, "InitSubdirs: Bad subdir: \"%s\"\n", *s);
+ return NULL;
+ }
+ }
+ }
+ subdirs = xalloc((i * 2 + 1) * sizeof(char *));
+ if (!subdirs)
+ return NULL;
+ i = 0;
+ s = subdirlist;
+ indefault = FALSE;
+ while (*s) {
+ if (*s == DEFAULT_LIST) {
+ /* Divert to the default list */
+ indefault = TRUE;
+ stmp = ++s;
+ s = stdSubdirs;
+ }
+ len = strlen(*s);
+ if (**s && (*s)[len - 1] != '/') {
+ slash = "/";
+ len++;
+ } else
+ slash = "";
+ len += oslen + 2;
+ if (!(subdirs[i] = xalloc(len)))
+ return NULL;
+ /* tack on the OS name */
+ sprintf(subdirs[i], "%s%s%s/", *s, slash, osname);
+ i++;
+ /* path as given */
+ subdirs[i] = xstrdup(*s);
+ i++;
+ s++;
+ if (indefault && !s) {
+ /* revert back to the main list */
+ indefault = FALSE;
+ s = stmp;
+ }
+ }
+ subdirs[i] = NULL;
+ }
+ return (const char **)subdirs;
+}
+
+static void
+FreeSubdirs(const char **subdirs)
+{
+ const char **s;
+
+ if (subdirs) {
+ for (s = subdirs; *s; s++)
+ xfree(*s);
+ xfree(subdirs);
+ }
+}
+
+static char *
+FindModule (const char *module, const char *dir, const char **subdirlist,
+ PatternPtr patterns)
+{
+ char buf[PATH_MAX + 1];
+ char *dirpath = NULL;
+ char *name = NULL;
+ struct stat stat_buf;
+ int len, dirlen;
+ char *fp;
+ DIR *d;
+ const char **subdirs = NULL;
+ PatternPtr p = NULL;
+ const char **s;
+ struct dirent *dp;
+ regmatch_t match[2];
+
+ subdirs = InitSubdirs(subdirlist);
+ if (!subdirs)
+ return NULL;
+
+#ifndef __EMX__
+ dirpath = (char *)dir;
+#else
+ dirpath = xalloc(strlen(dir) + 10);
+ strcpy(dirpath, (char *) __XOS2RedirRoot (dir));
+#endif
+ if (strlen(dirpath) > PATH_MAX)
+ return NULL;
+
+ for (s = subdirs; *s; s++) {
+ if ((dirlen = strlen(dir) + strlen(*s)) > PATH_MAX)
+ continue;
+ strcpy(buf, dirpath);
+ strcat(buf, *s);
+ fp = buf + dirlen;
+ if (stat(buf, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode) &&
+ (d = opendir(buf))) {
+ if (buf[dirlen - 1] != '/') {
+ buf[dirlen++] = '/';
+ fp++;
+ }
+ while ((dp = readdir(d))) {
+ if (dirlen + strlen(dp->d_name) + 1 > PATH_MAX)
+ continue;
+ strcpy(fp, dp->d_name);
+ if (!(stat(buf, &stat_buf) == 0 && S_ISREG(stat_buf.st_mode)))
+ continue;
+ for (p = patterns; p->pattern; p++) {
+ if (regexec(&p->rex, dp->d_name, 2, match, 0) == 0 &&
+ match[1].rm_so != -1) {
+ len = match[1].rm_eo - match[1].rm_so;
+ if (len == strlen(module) &&
+ strncmp(module, dp->d_name + match[1].rm_so, len) == 0) {
+ name = buf;
+ break;
+ }
+ }
+ }
+ if (name)
+ break;
+ }
+ closedir(d);
+ if (name)
+ break;
+ }
+ }
+ FreeSubdirs(subdirs);
+ if (dirpath != dir)
+ xfree(dirpath);
+
+ if (name) {
+ return xstrdup(name);
+ }
+ return NULL;
+}
+
+char **
+LoaderListDirs(const char **subdirlist, const char **patternlist)
+{
+ char buf[PATH_MAX + 1];
+ char **pathlist;
+ char **elem;
+ const char **subdirs;
+ const char **s;
+ PatternPtr patterns;
+ PatternPtr p;
+ DIR *d;
+ struct dirent *dp;
+ regmatch_t match[2];
+ struct stat stat_buf;
+ int len, dirlen;
+ char *fp;
+ char **listing = NULL;
+ char **save;
+ int n = 0;
+
+ if (!(pathlist = InitPathList(NULL)))
+ return NULL;
+ if (!(subdirs = InitSubdirs(subdirlist))) {
+ FreePathList(pathlist);
+ return NULL;
+ }
+ if (!(patterns = InitPatterns(patternlist))) {
+ FreePathList(pathlist);
+ FreeSubdirs(subdirs);
+ return NULL;
+ }
+
+ for (elem = pathlist; *elem; elem++) {
+ for (s = subdirs; *s; s++) {
+ if ((dirlen = strlen(*elem) + strlen(*s)) > PATH_MAX)
+ continue;
+ strcpy(buf, *elem);
+ strcat(buf, *s);
+ fp = buf + dirlen;
+ if (stat(buf, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode) &&
+ (d = opendir(buf))) {
+ if (buf[dirlen - 1] != '/') {
+ buf[dirlen++] = '/';
+ fp++;
+ }
+ while ((dp = readdir(d))) {
+ if (dirlen + strlen(dp->d_name) > PATH_MAX)
+ continue;
+ strcpy(fp, dp->d_name);
+ if (!(stat(buf, &stat_buf) == 0 &&
+ S_ISREG(stat_buf.st_mode)))
+ continue;
+ for (p = patterns; p->pattern; p++) {
+ if (regexec(&p->rex, dp->d_name, 2, match, 0) == 0 &&
+ match[1].rm_so != -1) {
+ len = match[1].rm_eo - match[1].rm_so;
+ save = listing;
+ listing = xrealloc(listing,
+ (n + 2) * sizeof(char *));
+ if (!listing) {
+ if (save) {
+ save[n] = NULL;
+ FreeStringList(save);
+ }
+ FreePathList(pathlist);
+ FreeSubdirs(subdirs);
+ FreePatterns(patterns);
+ return NULL;
+ }
+ listing[n] = xalloc(len + 1);
+ if (!listing[n]) {
+ FreeStringList(listing);
+ FreePathList(pathlist);
+ FreeSubdirs(subdirs);
+ FreePatterns(patterns);
+ return NULL;
+ }
+ strncpy(listing[n], dp->d_name + match[1].rm_so,
+ len);
+ listing[n][len] = '\0';
+ n++;
+ break;
+ }
+ }
+ }
+ closedir(d);
+ }
+ }
+ }
+ if (listing)
+ listing[n] = NULL;
+ return listing;
+}
+
+void
+LoaderFreeDirList(char **list)
+{
+ FreeStringList(list);
+}
+
+
+static Bool
+CheckVersion (const char *module, XF86ModuleVersionInfo *data,
+ const XF86ModReqInfo *req)
+{
+ int vercode[3];
+ char verstr[4];
+ long ver = data->xf86version;
+
+ xf86Msg (X_INFO, "Module %s: vendor=\"%s\"\n",
+ data->modname ? data->modname : "UNKNOWN!",
+ data->vendor ? data->vendor : "UNKNOWN!");
+
+ verstr[1] = verstr[3] = 0;
+ verstr[2] = (ver & 0x1f) ? (ver & 0x1f) + 'a' - 1 : 0;
+ ver >>= 5;
+ verstr[0] = (ver & 0x1f) ? (ver & 0x1f) + 'A' - 1 : 0;
+ ver >>= 5;
+ vercode[2] = ver & 0x7f;
+ ver >>= 7;
+ vercode[1] = ver & 0x7f;
+ ver >>= 7;
+ vercode[0] = ver;
+ xf86ErrorF("\tcompiled for %d.%d", vercode[0], vercode[1]);
+ if (vercode[2] != 0)
+ xf86ErrorF(".%d", vercode[2]);
+ xf86ErrorF("%s%s, module version = %d.%d.%d\n", verstr, verstr + 2,
+ data->majorversion, data->minorversion, data->patchlevel);
+
+ if (data->moduleclass)
+ xf86ErrorFVerb(2, "\tModule class: %s\n", data->moduleclass);
+
+ ver = -1;
+ if (data->abiclass) {
+ int abimaj, abimin;
+ int vermaj, vermin;
+
+ if (!strcmp(data->abiclass, ABI_CLASS_ANSIC))
+ ver = LoaderVersionInfo.ansicVersion;
+ else if (!strcmp(data->abiclass, ABI_CLASS_VIDEODRV))
+ ver = LoaderVersionInfo.videodrvVersion;
+ else if (!strcmp(data->abiclass, ABI_CLASS_XINPUT))
+ ver = LoaderVersionInfo.xinputVersion;
+ else if (!strcmp(data->abiclass, ABI_CLASS_EXTENSION))
+ ver = LoaderVersionInfo.extensionVersion;
+ else if (!strcmp(data->abiclass, ABI_CLASS_FONT))
+ ver = LoaderVersionInfo.fontVersion;
+
+ abimaj = GET_ABI_MAJOR(data->abiversion);
+ abimin = GET_ABI_MINOR(data->abiversion);
+ xf86ErrorFVerb(2, "\tABI class: %s, version %d.%d\n",
+ data->abiclass, abimaj, abimin);
+ if (ver != -1) {
+ vermaj = GET_ABI_MAJOR(ver);
+ vermin = GET_ABI_MINOR(ver);
+ if (abimaj != vermaj) {
+ /* XXX This should be an error condition */
+ xf86MsgVerb(X_WARNING, 0,
+ "module ABI major version (%d) doesn't"
+ " match the server's version (%d)\n",
+ abimaj, vermaj);
+ } else if (abimin > vermin) {
+ /* XXX This should be an error condition */
+ xf86MsgVerb(X_WARNING, 0,
+ "module ABI minor version (%d) is "
+ "newer than the server's version "
+ "(%d)\n", abimin, vermin);
+ }
+ }
+ }
+
+ /* Check against requirements that the caller has specified */
+ if (req) {
+ if (req->majorversion != MAJOR_UNSPEC) {
+ if (data->majorversion != req->majorversion) {
+ xf86MsgVerb(X_WARNING, 2, "module major version (%d) "
+ "doesn't match required major version (%d)\n",
+ data->majorversion, req->majorversion);
+ return FALSE;
+ } else if (req->minorversion != MINOR_UNSPEC) {
+ if (data->minorversion < req->minorversion) {
+ xf86MsgVerb(X_WARNING, 2, "module minor version (%d) "
+ "is less than the required minor version (%d)\n",
+ data->minorversion, req->minorversion);
+ return FALSE;
+ } else if (data->minorversion == req->minorversion &&
+ req->patchlevel != PATCH_UNSPEC) {
+ if (data->patchlevel < req->patchlevel) {
+ xf86MsgVerb(X_WARNING, 2, "module patch level (%d) "
+ "is less than the required patch level (%d)\n",
+ data->patchlevel, req->patchlevel);
+ return FALSE;
+ }
+ }
+ }
+ }
+ if (req->moduleclass) {
+ if (!data->moduleclass ||
+ strcmp(req->moduleclass, data->moduleclass)) {
+ xf86MsgVerb(X_WARNING, 2, "Module class (%s) doesn't match "
+ "the required class (%s)\n",
+ data->moduleclass ? data->moduleclass : "<NONE>",
+ req->moduleclass);
+ return FALSE;
+ }
+ } else if (req->abiclass != ABI_CLASS_NONE) {
+ if (!data->abiclass || strcmp(req->abiclass, data->moduleclass)) {
+ xf86MsgVerb(X_WARNING, 2, "ABI class (%s) doesn't match the "
+ "required ABI class (%s)\n",
+ data->abiclass ? data->abiclass : "<NONE>",
+ req->abiclass);
+ return FALSE;
+ }
+ }
+ if ((req->abiclass != ABI_CLASS_NONE) &&
+ req->abiversion != ABI_VERS_UNSPEC) {
+ int reqmaj, reqmin, maj, min;
+ reqmaj = GET_ABI_MAJOR(req->abiversion);
+ reqmin = GET_ABI_MINOR(req->abiversion);
+ maj = GET_ABI_MAJOR(data->abiversion);
+ min = GET_ABI_MINOR(data->abiversion);
+ if (maj != reqmaj) {
+ xf86MsgVerb(X_WARNING, 2, "ABI major version (%d) doesn't "
+ "match the required ABI major version (%d)\n",
+ maj, reqmaj);
+ return FALSE;
+ }
+ /* XXX Maybe this should be the other way around? */
+ if (min > reqmin) {
+ xf86MsgVerb(X_WARNING, 2, "module ABI minor version (%d) "
+ "is new than that available (%d)\n",
+ min, reqmin);
+ return FALSE;
+ }
+ }
+ }
+
+#ifdef NOTYET
+ if (data->checksum)
+ {
+ /* verify the checksum field */
+ /* TO BE DONE */
+ }
+ else
+ {
+ ErrorF ("\t*** Checksum field is 0 - this module is untrusted!\n");
+ }
+#endif
+ return TRUE;
+}
+
+ModuleDescPtr
+LoadSubModule(ModuleDescPtr parent, const char *module,
+ const char **subdirlist, const char **patternlist,
+ pointer options, const XF86ModReqInfo *modreq,
+ int *errmaj, int *errmin)
+{
+ ModuleDescPtr submod;
+
+ xf86MsgVerb(X_INFO, 3, "Loading sub module \"%s\"\n", module);
+
+ /* Absolute module paths are not allowed here */
+#ifndef __EMX__
+ if (module[0] == '/')
+#else
+ if (isalpha (module[0]) && module[1] == ':' && module[2] == '/')
+#endif
+ {
+ xf86Msg(X_ERROR,
+ "LoadSubModule: Absolute module path not permitted: \"%s\"\n",
+ module);
+ if (errmaj)
+ *errmaj = LDR_BADUSAGE;
+ if (errmin)
+ *errmin = 0;
+ return NULL;
+ }
+
+ submod = LoadModule (module, NULL, subdirlist, patternlist, options,
+ modreq, errmaj, errmin);
+ if (submod) {
+ parent->child = AddSibling (parent->child, submod);
+ submod->parent = parent;
+ }
+ return submod;
+}
+
+void
+LoadExtension (ExtensionModule *e)
+{
+ int i;
+
+ if (e == NULL)
+ return;
+ xf86MsgVerb(X_INFO, 2, "Loading extension %s\n", e->name);
+
+ for (i = 0; extension[i].name != NULL; i++)
+ {
+ if (strcmp (extension[i].name, e->name) == 0)
+ {
+ extension[i].initFunc = e->initFunc;
+ extension[i].disablePtr = e->disablePtr;
+ if (e->setupFunc != NULL)
+ e->setupFunc();
+ break;
+ }
+ }
+ if (extension[i].name == NULL)
+ {
+ xf86MsgVerb(X_WARNING, 0,
+ "Extension \"%s\" is not recognised\n", e->name);
+ }
+}
+
+ModuleDescPtr
+DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent)
+{
+ ModuleDescPtr ret;
+
+ if (!mod)
+ return NULL;
+
+ ret = NewModuleDesc(mod->name);
+ if (ret == NULL)
+ return NULL;
+
+ if (LoaderHandleOpen(mod->handle) == -1)
+ return NULL;
+
+ ret->filename = xstrdup(mod->filename);
+ ret->identifier = mod->identifier;
+ ret->client_id = mod->client_id;
+ ret->in_use = mod->in_use;
+ ret->handle = mod->handle;
+ ret->SetupProc = mod->SetupProc;
+ ret->TearDownProc = mod->TearDownProc;
+ ret->TearDownData = NULL;
+ ret->path = mod->path;
+ ret->child = DuplicateModule(mod->child, ret);
+ ret->sib = DuplicateModule(mod->sib, parent);
+ ret->parent = parent;
+
+ return ret;
+}
+
+/*
+ * LoadModule: load a module
+ *
+ * module The module name. Normally this is not a filename but the
+ * module's "canonical name. A full pathname is, however,
+ * also accepted.
+ * path A comma separated list of module directories.
+ * subdirlist A NULL terminated list of subdirectories to search. When
+ * NULL, the default "stdSubdirs" list is used. The default
+ * list is also substituted for entries with value DEFAULT_LIST.
+ * patternlist A NULL terminated list of regular expressions used to find
+ * module filenames. Each regex should contain exactly one
+ * subexpression that corresponds to the canonical module name.
+ * When NULL, the default "stdPatterns" list is used. The
+ * default list is also substituted for entries with value
+ * DEFAULT_LIST.
+ * options A NULL terminated list of Options that are passed to the
+ * module's SetupProc function.
+ * modreq An optional XF86ModReqInfo* containing
+ * version/ABI/vendor-ABI requirements to check for when
+ * loading the module. The following fields of the
+ * XF86ModReqInfo struct are checked:
+ * majorversion - must match the module's majorversion exactly
+ * minorversion - the module's minorversion must be >= this
+ * patchlevel - the module's minorversion.patchlevel must be
+ * >= this. Patchlevel is ignored when
+ * minorversion is not set.
+ * abiclass - must match the module's abiclass
+ * abiversion - must be consistent with the module's
+ * abiversion (major equal, minor no older)
+ * abivendor - string must match the module's abivendor
+ * string
+ * "don't care" values are ~0 for numbers, and NULL for strings
+ * errmaj Major error return.
+ * errmin Minor error return.
+ *
+ */
+
+ModuleDescPtr
+LoadModule (const char *module, const char *path, const char **subdirlist,
+ const char **patternlist, pointer options,
+ const XF86ModReqInfo * modreq,
+ int *errmaj, int *errmin)
+{
+ XF86ModuleData *initdata = NULL;
+ char **pathlist = NULL;
+ char *found = NULL;
+ char *name = NULL;
+ char **path_elem = NULL;
+ char *p = NULL;
+ ModuleDescPtr ret = NULL;
+ int wasLoaded = 0;
+ PatternPtr patterns = NULL;
+ int noncanonical = 0;
+ char *m = NULL;
+
+ xf86MsgVerb(X_INFO, 3, "LoadModule: \"%s\"", module);
+
+ patterns = InitPatterns(patternlist);
+ name = LoaderGetCanonicalName(module, patterns);
+ noncanonical = (name && strcmp(module, name) != 0);
+ if (noncanonical)
+ {
+ xf86ErrorFVerb(3, " (%s)\n", name);
+ xf86MsgVerb(X_WARNING, 1,
+ "LoadModule: given non-canonical module name \"%s\"\n",
+ module);
+ m = name;
+ }
+ else
+ {
+ xf86ErrorFVerb(3, "\n");
+ m = (char *)module;
+ }
+ if (!name) {
+ if (errmaj)
+ *errmaj = LDR_BADUSAGE;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ ret = NewModuleDesc (name);
+ if (!ret) {
+ if (errmaj)
+ *errmaj = LDR_NOMEM;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+
+ pathlist = InitPathList(path);
+ if (!pathlist) {
+ /* This could be a malloc failure too */
+ if (errmaj)
+ *errmaj = LDR_BADUSAGE;
+ if (errmin)
+ *errmin = 1;
+ goto LoadModule_fail;
+ }
+
+ /*
+ * if the module name is not a full pathname, we need to
+ * check the elements in the path
+ */
+#ifndef __EMX__
+ if (module[0] == '/')
+ found = xstrdup(module);
+#else
+ /* accept a drive name here */
+ if (isalpha (module[0]) && module[1] == ':' && module[2] == '/')
+ found = xstrdup(module);
+#endif
+ path_elem = pathlist;
+ while (!found && *path_elem != NULL)
+ {
+ found = FindModule (m, *path_elem, subdirlist, patterns);
+ path_elem++;
+ /*
+ * When the module name isn't the canonical name, search for the
+ * former if no match was found for the latter.
+ */
+ if (!*path_elem && m == name)
+ {
+ path_elem = pathlist;
+ m = (char *)module;
+ }
+ }
+
+ /*
+ * did we find the module?
+ */
+ if (!found)
+ {
+ xf86Msg (X_WARNING, "Warning, couldn't open module %s\n",
+ module);
+ if (errmaj)
+ *errmaj = LDR_NOENT;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ ret->handle = LoaderOpen (found, name, 0, errmaj, errmin, &wasLoaded);
+ if (ret->handle < 0)
+ goto LoadModule_fail;
+
+ ret->filename = xstrdup(found);
+
+ /*
+ * now check if the special data object <modulename>ModuleData is
+ * present.
+ */
+ p = xalloc (strlen (name) + strlen ("ModuleData") + 1);
+ if (!p) {
+ if (errmaj)
+ *errmaj = LDR_NOMEM;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ strcpy (p, name);
+ strcat (p, "ModuleData");
+ initdata = LoaderSymbol (p);
+ if (initdata)
+ {
+ ModuleSetupProc setup;
+ ModuleTearDownProc teardown;
+ XF86ModuleVersionInfo *vers;
+
+ vers = initdata->vers;
+ setup = initdata->setup;
+ teardown = initdata->teardown;
+
+ if (!wasLoaded) {
+ if (vers) {
+ if (!CheckVersion (module, vers, modreq)) {
+ if (errmaj)
+ *errmaj = LDR_MISMATCH;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ } else {
+ xf86Msg(X_ERROR,
+ "LoadModule: Module %s does not supply"
+ " version information\n", module);
+ if (errmaj)
+ *errmaj = LDR_INVALID;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ }
+ if (setup)
+ ret->SetupProc = setup;
+ if (teardown)
+ ret->TearDownProc = teardown;
+ ret->path = path;
+ }
+ else
+ {
+ /* No initdata is OK for external modules */
+ if (options == EXTERN_MODULE)
+ goto LoadModule_exit;
+
+ /* no initdata, fail the load */
+ xf86Msg (X_ERROR, "LoadModule: Module %s does not have a %s "
+ "data object.\n", module, p);
+ if (errmaj)
+ *errmaj = LDR_INVALID;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ if (ret->SetupProc)
+ {
+ ret->TearDownData = ret->SetupProc (ret, options, errmaj, errmin);
+ if (!ret->TearDownData)
+ {
+ goto LoadModule_fail;
+ }
+ }
+ else if (options)
+ {
+ xf86Msg (X_WARNING, "Module Options present, but no SetupProc "
+ "available for %s\n", module);
+ }
+ goto LoadModule_exit;
+
+ LoadModule_fail:
+ UnloadModule (ret);
+ ret = NULL;
+
+ LoadModule_exit:
+ FreePathList(pathlist);
+ FreePatterns(patterns);
+ TestFree (found);
+ TestFree (name);
+ TestFree (p);
+ return ret;
+}
+
+ModuleDescPtr
+LoadDriver (const char *module, const char *path, int handle, pointer options,
+ int *errmaj, int *errmin)
+{
+return LoadModule (module, path, NULL, NULL, options, NULL, errmaj, errmin);
+}
+
+void
+UnloadModule (ModuleDescPtr mod)
+{
+ UnloadModuleOrDriver (mod);
+}
+
+void
+UnloadDriver (ModuleDescPtr mod)
+{
+ UnloadModuleOrDriver (mod);
+}
+
+static void
+UnloadModuleOrDriver (ModuleDescPtr mod)
+{
+ if (mod == NULL || mod->name == NULL)
+ return;
+
+ xf86MsgVerb(X_INFO, 3, "UnloadModule: \"%s\"\n", mod->name);
+
+ if ((mod->TearDownProc) && (mod->TearDownData))
+ mod->TearDownProc (mod->TearDownData);
+ LoaderUnload (mod->handle);
+
+ if (mod->child)
+ UnloadModuleOrDriver (mod->child);
+ if (mod->sib)
+ UnloadModuleOrDriver (mod->sib);
+ TestFree (mod->name);
+ TestFree (mod->filename);
+ xfree (mod);
+}
+
+void
+UnloadSubModule(ModuleDescPtr mod)
+{
+ if (mod == NULL || mod->name == NULL)
+ return;
+
+ xf86MsgVerb(X_INFO, 3, "UnloadSubModule: \"%s\"\n", mod->name);
+
+ if ((mod->TearDownProc) && (mod->TearDownData))
+ mod->TearDownProc (mod->TearDownData);
+ LoaderUnload (mod->handle);
+
+ RemoveChild(mod);
+
+ if (mod->child)
+ UnloadModuleOrDriver (mod->child);
+
+ TestFree (mod->name);
+ TestFree (mod->filename);
+ xfree (mod);
+}
+
+void
+FreeModuleDesc (ModuleDescPtr head)
+{
+ ModuleDescPtr sibs, prev;
+
+ /*
+ * only free it if it's not marked as in use. In use means that it may
+ * be unloaded someday, and UnloadModule or UnloadDriver will free it
+ */
+ if (head->in_use)
+ return;
+ if (head->child)
+ FreeModuleDesc (head->child);
+ sibs = head;
+ while (sibs)
+ {
+ prev = sibs;
+ sibs = sibs->sib;
+ TestFree (prev->name);
+ xfree (prev);
+ }
+}
+
+ModuleDescPtr
+NewModuleDesc (const char *name)
+{
+ ModuleDescPtr mdp = xalloc (sizeof (ModuleDesc));
+
+ if (mdp)
+ {
+ mdp->child = NULL;
+ mdp->sib = NULL;
+ mdp->parent = NULL;
+ mdp->demand_next = NULL;
+ mdp->name = xstrdup (name);
+ mdp->filename = NULL;
+ mdp->identifier = NULL;
+ mdp->client_id = 0;
+ mdp->in_use = 0;
+ mdp->handle = -1;
+ mdp->SetupProc = NULL;
+ mdp->TearDownProc = NULL;
+ mdp->TearDownData = NULL;
+ }
+
+ return (mdp);
+}
+
+ModuleDescPtr
+AddSibling (ModuleDescPtr head, ModuleDescPtr new)
+{
+ new->sib = head;
+ return (new);
+
+}
+
+static void
+RemoveChild (ModuleDescPtr child)
+{
+ ModuleDescPtr mdp;
+ ModuleDescPtr prevsib;
+ ModuleDescPtr parent;
+
+ if (!child->parent)
+ return;
+
+ parent = child->parent;
+ if (parent->child == child) {
+ parent->child = child->sib;
+ return;
+ }
+
+ prevsib = parent->child;
+ mdp = prevsib->sib;
+ while (mdp && mdp != child) {
+ prevsib = mdp;
+ mdp = mdp->sib;
+ }
+ if (mdp == child)
+ prevsib->sib = child->sib;
+ return;
+}
+
+void
+LoaderErrorMsg(const char *name, const char *modname, int errmaj, int errmin)
+{
+ const char *msg;
+
+ switch (errmaj) {
+ case LDR_NOERROR:
+ msg = "no error";
+ break;
+ case LDR_NOMEM:
+ msg = "out of memory";
+ break;
+ case LDR_NOENT:
+ msg = "module does not exist";
+ break;
+ case LDR_NOSUBENT:
+ msg = "submodule could not be loaded";
+ break;
+ case LDR_NOSPACE:
+ msg = "too many modules";
+ break;
+ case LDR_NOMODOPEN:
+ msg = "open failed";
+ break;
+ case LDR_UNKTYPE:
+ msg = "unknown module type";
+ break;
+ case LDR_NOLOAD:
+ msg = "loader failed";
+ break;
+ case LDR_ONCEONLY:
+ msg = "once-only module";
+ break;
+ case LDR_NOPORTOPEN:
+ msg = "port open failed";
+ break;
+ case LDR_NOHARDWARE:
+ msg = "no hardware found";
+ break;
+ case LDR_MISMATCH:
+ msg = "module requirement mismatch";
+ break;
+ case LDR_BADUSAGE:
+ msg = "invalid argument(s) to LoadModule()";
+ break;
+ case LDR_INVALID:
+ msg = "invalid module";
+ break;
+ case LDR_BADOS:
+ msg = "module doesn't support this OS";
+ break;
+ case LDR_MODSPECIFIC:
+ msg = "module-specific error";
+ break;
+ default:
+ msg = "uknown error";
+ }
+ if (name)
+ xf86Msg(X_ERROR, "%s: Failed to load module \"%s\" (%s, %d)\n",
+ name, modname, msg, errmin);
+ else
+ xf86Msg(X_ERROR, "Failed to load module \"%s\" (%s, %d)\n",
+ modname, msg, errmin);
+}
+
+
+/* Given a module path or file name, return the module's canonical name */
+static char *
+LoaderGetCanonicalName(const char *modname, PatternPtr patterns)
+{
+ char *str;
+ const char *s;
+ int len;
+ PatternPtr p;
+ regmatch_t match[2];
+
+ /* Strip off any leading path */
+ s = strrchr(modname, '/');
+ if (s == NULL)
+ s = modname;
+ else
+ s++;
+
+ /* Find the first regex that is matched */
+ for (p = patterns; p->pattern; p++)
+ if (regexec(&p->rex, s, 2, match, 0) == 0 &&
+ match[1].rm_so != -1) {
+ len = match[1].rm_eo - match[1].rm_so;
+ str = xalloc(len + 1);
+ if (!str)
+ return NULL;
+ strncpy(str, s + match[1].rm_so, len);
+ str[len] = '\0';
+ return str;
+ }
+
+ /* If there is no match, return the whole name minus the leading path */
+ return xstrdup(s);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/loader/misym.c b/xc/programs/Xserver/hw/xfree86/loader/misym.c
new file mode 100644
index 000000000..5d7b4c738
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/misym.c
@@ -0,0 +1,157 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/misym.c,v 1.20 1999/06/14 07:31:55 dawes Exp $ */
+
+/*
+ *
+ * Copyright 1995,96 by Metro Link, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. 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 "sym.h"
+#include "misc.h"
+#include "mi.h"
+#include "mibank.h"
+#include "miwideline.h"
+#include "mibstore.h"
+#include "cursor.h"
+#include "mipointer.h"
+#include "migc.h"
+#include "miline.h"
+#include "mizerarc.h"
+#include "mifillarc.h"
+#include "micmap.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#endif
+
+/* mi things */
+
+extern miPointerSpriteFuncRec miSpritePointerFuncs;
+
+#ifdef PANORAMIX
+extern PanoramiXWindow *PanoramiXWinRoot;
+extern Bool noPanoramiXExtension;
+extern int PanoramiXNumScreens;
+extern PanoramiXPmap *PanoramiXPmapRoot;
+extern PanoramiXData *panoramiXdataPtr;
+#endif
+
+LOOKUP miLookupTab[] = {
+ SYMFUNC(miRectIn)
+ SYMFUNC(miZeroClipLine)
+ SYMFUNC(miZeroDashLine)
+ SYMFUNC(miClearDrawable)
+ SYMFUNC(miPolyPoint)
+ SYMFUNC(miStepDash)
+ SYMFUNC(miEmptyBox)
+ SYMFUNC(miEmptyData)
+ SYMFUNC(miIntersect)
+ SYMFUNC(miRegionCopy)
+ SYMFUNC(miRegionDestroy)
+ SYMFUNC(miTranslateRegion)
+ SYMFUNC(miHandleExposures)
+ SYMFUNC(miPolyFillRect)
+ SYMFUNC(miPolyFillArc)
+ SYMFUNC(miImageGlyphBlt)
+ SYMFUNC(miPolyGlyphBlt)
+ SYMFUNC(miFillPolygon)
+ SYMFUNC(miPolySegment)
+ SYMFUNC(miZeroLine)
+ SYMFUNC(miWideLine)
+ SYMFUNC(miWideDash)
+ SYMFUNC(miZeroPolyArc)
+ SYMFUNC(miPolyArc)
+ SYMFUNC(miCreateGCOps)
+ SYMFUNC(miDestroyGCOps)
+ SYMFUNC(miComputeCompositeClip)
+ SYMFUNC(miChangeGC)
+ SYMFUNC(miCopyGC)
+ SYMFUNC(miDestroyGC)
+ SYMFUNC(miChangeClip)
+ SYMFUNC(miDestroyClip)
+ SYMFUNC(miCopyClip)
+ SYMFUNC(miPolyRectangle)
+ SYMFUNC(miPolyText8)
+ SYMFUNC(miPolyText16)
+ SYMFUNC(miImageText8)
+ SYMFUNC(miImageText16)
+ SYMFUNC(miRegionCreate)
+ SYMFUNC(miPaintWindow)
+ SYMFUNC(miZeroArcSetup)
+ SYMFUNC(miFillArcSetup)
+ SYMFUNC(miFillArcSliceSetup)
+ SYMFUNC(miFindMaxBand)
+ SYMFUNC(miClipSpans)
+ SYMFUNC(miAllocateGCPrivateIndex)
+ SYMFUNC(miScreenInit)
+ SYMFUNC(miGetScreenPixmap)
+ SYMFUNC(miSetScreenPixmap)
+ SYMFUNC(miPointerCurrentScreen)
+ SYMFUNC(miRectAlloc)
+ SYMFUNC(miInitializeBackingStore)
+ SYMFUNC(miInitializeBanking)
+ SYMFUNC(miCopyPlane)
+ SYMFUNC(miCopyArea)
+ SYMFUNC(miCreateScreenResources)
+ SYMFUNC(miGetImage)
+ SYMFUNC(miPutImage)
+ SYMFUNC(miPushPixels)
+ SYMFUNC(miPointerInitialize)
+ SYMFUNC(miPointerPosition)
+ SYMFUNC(miRecolorCursor)
+ SYMFUNC(miPointerWarpCursor)
+ SYMFUNC(miDCInitialize)
+ SYMFUNC(miRectsToRegion)
+ SYMFUNC(miSubtract)
+ SYMFUNC(miUnion)
+ SYMFUNC(miPolyBuildEdge)
+ SYMFUNC(miPolyBuildPoly)
+ SYMFUNC(miRoundJoinClip)
+ SYMFUNC(miRoundCapClip)
+ SYMFUNC(miSetZeroLineBias)
+ SYMFUNC(miResolveColor)
+ SYMFUNC(miInitializeColormap)
+ SYMFUNC(miInstallColormap)
+ SYMFUNC(miUninstallColormap)
+ SYMFUNC(miListInstalledColormaps)
+ SYMFUNC(miExpandDirectColors)
+ SYMFUNC(miCreateDefColormap)
+ SYMFUNC(miClearVisualTypes)
+ SYMFUNC(miSetVisualTypes)
+ SYMFUNC(miGetDefaultVisualMask)
+ SYMFUNC(miInitVisuals)
+ SYMFUNC(miWindowExposures)
+ SYMFUNC(miSegregateChildren)
+ SYMFUNC(miClipNotify)
+ SYMFUNC(miHookInitVisuals)
+ SYMVAR(miZeroLineScreenIndex)
+ SYMVAR(miSpritePointerFuncs)
+ SYMVAR(miPointerScreenIndex)
+ SYMVAR(miInstalledMaps)
+ SYMVAR(miInitVisualsProc)
+#ifdef PANORAMIX
+ SYMVAR(PanoramiXWinRoot)
+ SYMVAR(noPanoramiXExtension)
+ SYMVAR(PanoramiXNumScreens)
+ SYMVAR(PanoramiXPmapRoot)
+ SYMVAR(panoramiXdataPtr)
+#endif
+
+ { 0, 0 },
+
+};
diff --git a/xc/programs/Xserver/hw/xfree86/loader/os.c b/xc/programs/Xserver/hw/xfree86/loader/os.c
new file mode 100644
index 000000000..776ab652c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/os.c
@@ -0,0 +1,49 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/os.c,v 1.1 1999/03/06 13:12:43 dawes Exp $ */
+
+#include "loaderProcs.h"
+
+/*
+ * OSNAME is a standard form of the OS name that may be used by the
+ * loader and by OS-specific modules.
+ */
+
+#if defined(__linux__)
+#define OSNAME "linux"
+#elif defined(__FreeBSD__)
+#define OSNAME "freebsd"
+#elif defined(__NetBSD__)
+#define OSNAME "netbsd"
+#elif defined(__OpenBSD__)
+#define OSNAME "openbsd"
+#elif defined(Lynx)
+#define OSNAME "lynxos"
+#elif defined(__GNU__)
+#define OSNAME "hurd"
+#elif defined(SCO)
+#define OSNAME "sco"
+#elif defined(DGUX)
+#define OSNAME "dgux"
+#elif defined(ISC)
+#define OSNAME "isc"
+#elif defined(SVR4) && defined(sun)
+#define OSNAME "solaris"
+#elif defined(SVR4)
+#define OSNAME "svr4"
+#elif defined(__EMX__)
+#define OSNAME "os2"
+#else
+#define OSNAME "unknown"
+#endif
+
+
+/* Return the OS name, and run-time OS version */
+
+void
+LoaderGetOS(const char **name, int *major, int *minor, int *teeny)
+{
+ if (name)
+ *name = OSNAME;
+
+ /* reporting runtime versions isn't supported yet */
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/loader/os2funcs.c b/xc/programs/Xserver/hw/xfree86/loader/os2funcs.c
new file mode 100644
index 000000000..3e66788b3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/os2funcs.c
@@ -0,0 +1,148 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/os2funcs.c,v 1.4 1997/03/10 10:12:22 hohndel Exp $ */
+/*
+ * (c) Copyright 1997 by Sebastien Marineau
+ * <marineau@genie.uottawa.ca>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * SEBASTIEN MARINEAU BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Sebastien Marineau shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Sebastien Marineau.
+ *
+ */
+
+
+/* Implements some OS/2 memory allocation functions to allow
+ * execute permissions for modules. We allocate some mem using DosAllocMem
+ * and then use the EMX functions to create a heap from which we allocate
+ * the requests. We create a heap of 2 megs, hopefully enough for now.
+ */
+
+#define INCL_DOSMEMMGR
+#include <os2.h>
+#include <sys/types.h>
+#include <umalloc.h>
+#include "os.h"
+
+#define RESERVED_BLOCKS 512 /* reserve 2MB memory for modules */
+
+void *os2loader_AddToHeap(Heap_t, size_t *, int *);
+void os2loader_RemoveFromHeap(Heap_t, void *, size_t);
+
+PVOID os2loader_CommitedTop;
+PVOID os2loader_baseAddress;
+Heap_t os2loader_heapAddress;
+int os2loader_TotalCommitedBlocks;
+
+void *os2loader_calloc(size_t num_elem, size_t size_elem){
+APIRET rc;
+int ret;
+static BOOL FirstTime=TRUE;
+void *allocMem;
+
+if(FirstTime){
+ rc=DosAllocMem(&os2loader_baseAddress,RESERVED_BLOCKS * 4096,
+ PAG_READ | PAG_WRITE | PAG_EXECUTE);
+ if(rc!=0) {
+ ErrorF("OS/2AllocMem: Could not create heap for module loading\n");
+ return(NULL);
+ }
+
+/* Now commit the first 128Kb, the rest will be done dynamically */
+ rc=DosSetMem(os2loader_baseAddress,32*4096, PAG_DEFAULT | PAG_COMMIT);
+ if(rc!=0) {
+ ErrorF("OS/2AllocMem: Could not commit heap memory!\n");
+ DosFreeMem(os2loader_baseAddress);
+ return(NULL);
+ }
+ os2loader_CommitedTop=os2loader_baseAddress + 32*4096;
+ os2loader_TotalCommitedBlocks=32;
+ ErrorF("OS2Alloc: allocated mem for heap, rc=%d, addr=%p\n",rc,os2loader_baseAddress);
+
+ if((os2loader_heapAddress=_ucreate(os2loader_baseAddress,32*4096,_BLOCK_CLEAN,
+ _HEAP_REGULAR,os2loader_AddToHeap, os2loader_RemoveFromHeap))==NULL){
+ ErrorF("OS/2AllocMem: Could not create heap for loadable modules\n");
+ DosFreeMem(os2loader_baseAddress);
+ return(NULL);
+ }
+
+ ret=_uopen(os2loader_heapAddress);
+ if(ret!=0){
+ ErrorF("OS/2AllocMem: Could not open heap for loadable modules\n");
+ ret=_udestroy(os2loader_heapAddress,_FORCE);
+ DosFreeMem(os2loader_baseAddress);
+ return(NULL);
+ }
+ FirstTime=FALSE;
+ ErrorF("OS/2: done creating heap, addr=%p\n",os2loader_heapAddress);
+ }
+
+allocMem=_ucalloc(os2loader_heapAddress,num_elem,size_elem);
+return(allocMem);
+}
+
+
+void *os2loader_AddToHeap(Heap_t H, size_t *new_size, int *PCLEAN)
+{
+PVOID NewBase;
+long adjusted_size;
+long blocks;
+APIRET rc;
+
+ if(H != os2loader_heapAddress){
+ ErrorF("OS/2: Tried to grow an inexistant heap, p=%08x\n",H);
+ return (NULL);
+ }
+ NewBase=os2loader_CommitedTop;
+ adjusted_size = (*new_size/65536) * 65536;
+ if((*new_size % 65536)> 0 ) adjusted_size += 65536;
+ blocks=adjusted_size / 4096;
+ if((os2loader_TotalCommitedBlocks + blocks)>RESERVED_BLOCKS){
+ ErrorF("OS/2 GrowHeap: Could not allocate any more memory for module loading!\n");
+ ErrorF("Total reserved memory of %ld bytes is exhausted\n",RESERVED_BLOCKS * 4096);
+ return(NULL);
+ }
+ rc = DosSetMem(NewBase, adjusted_size, PAG_DEFAULT | PAG_COMMIT);
+ if(rc!=0) {
+ ErrorF("OS/2 GrowHeap: Could not grow heap! Requested size %d, \n", adjusted_size);
+ return(NULL);
+ }
+ os2loader_CommitedTop+=adjusted_size;
+ os2loader_TotalCommitedBlocks += blocks;
+ *PCLEAN = _BLOCK_CLEAN;
+ *new_size=adjusted_size;
+ ErrorF("OS/2: Added %d bytes to heap, addr %08x\n",adjusted_size, NewBase);
+ return(NewBase);
+}
+
+void os2loader_RemoveFromHeap(Heap_t H, void *memory, size_t size)
+{
+ if(H != os2loader_heapAddress){
+ ErrorF("OS/2: Tried to shrink an inexistant heap, p=%08x\n",H);
+ return;
+ }
+/* Currently we do nothing, as we do not keep track of the commited memory */
+ErrorF("OS/2: module heap requests that heap memory be deallocated. Request ignored\n");
+
+/* Only handle it if it is the base address */
+ if(memory == os2loader_baseAddress) {
+ DosFreeMem(os2loader_baseAddress);
+ ErrorF("OS/2: total heap area was deallocated\n");
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/loader/sym.h b/xc/programs/Xserver/hw/xfree86/loader/sym.h
new file mode 100644
index 000000000..5b80e7681
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/sym.h
@@ -0,0 +1,44 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/sym.h,v 1.4 1999/03/14 11:18:06 dawes Exp $ */
+
+/*
+ *
+ * Copyright 1995,96 by Metro Link, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. 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 _SYM_H
+#define _SYM_H
+
+/*
+ * This structure is used to pass in symbol information that is being
+ * added to the symbol table.
+ */
+
+typedef void (*funcptr)(void);
+
+typedef struct {
+ char *symName;
+ funcptr offset;
+} LOOKUP;
+
+#define SYMFUNC( func ) { #func, (funcptr)&func },
+#define SYMVAR( var ) { #var, (funcptr)&var },
+
+#endif /* _SYM_H */
diff --git a/xc/programs/Xserver/hw/xfree86/loader/xf86sym.c b/xc/programs/Xserver/hw/xfree86/loader/xf86sym.c
new file mode 100644
index 000000000..ffc3c3cef
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/loader/xf86sym.c
@@ -0,0 +1,878 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/loader/xf86sym.c,v 1.108 1999/08/22 05:57:38 dawes Exp $ */
+
+/*
+ *
+ * Copyright 1995,96 by Metro Link, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. 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 <fcntl.h>
+#include "sym.h"
+#include "misc.h"
+#include "mi.h"
+#include "cursor.h"
+#include "mipointer.h"
+#include "loaderProcs.h"
+#include "xf86Pci.h"
+#include "xf86.h"
+#include "xf86Resources.h"
+#include "xf86_OSproc.h"
+#define DECLARE_CARD_DATASTRUCTURES
+#include "xf86PciInfo.h"
+#include "xf86Parser.h"
+#include "xf86Config.h"
+#ifdef XINPUT
+#include "xf86Xinput.h"
+#endif
+#ifdef NEW_INPUT
+#include "xf86OSmouse.h"
+#endif
+#include "xf86xv.h"
+#include "xf86cmap.h"
+#include "xf86fbman.h"
+#include "dgaproc.h"
+#include "vidmodeproc.h"
+#include "xf86miscproc.h"
+#include "loader.h"
+#define DONT_DEFINE_WRAPPERS
+#include "xf86_ansic.h"
+#include "xisb.h"
+#include "xf86Priv.h"
+
+/* XXX Should get all of these from elsewhere */
+#if defined (PowerMAX_OS)
+#undef inb
+#undef inw
+#undef inl
+#undef outb
+#undef outw
+#undef outl
+
+extern void outb(unsigned int a, unsigned char b);
+extern void outw(unsigned int a, unsigned short w);
+extern void outl(unsigned int a, unsigned long l);
+extern unsigned char inb(unsigned int a);
+extern unsigned short inw(unsigned int a);
+extern unsigned long inl(unsigned int a);
+#endif
+
+#if defined(__alpha__)
+extern void _outb(char val, unsigned short port);
+extern void _outw(short val, unsigned short port);
+extern void _outl(int val, unsigned short port);
+extern unsigned int _inb(unsigned short port);
+extern unsigned int _inw(unsigned short port);
+extern unsigned int _inl(unsigned short port);
+
+extern void xf86WriteSparse16(int, pointer, unsigned long);
+
+extern void* __divl(long, long);
+extern void* __reml(long, long);
+extern void* __divlu(long, long);
+extern void* __remlu(long, long);
+extern void* __divq(long, long);
+extern void* __divqu(long, long);
+extern void* __remq(long, long);
+extern void* __remqu(long, long);
+#endif
+
+#if defined(__sparc__) && defined(__GNUC__)
+#define SYMFUNCDOT(func) { "." #func, (funcptr)&__sparc_dot_ ## func },
+#define SYMFUNCDOT89(func) { "." #func, (funcptr)&func ## _sparcv89 },
+#define DEFFUNCDOT(func) \
+extern void __sparc_dot_ ## func (void) __asm__ ("." #func); \
+extern void func ## _sparcv89 (void);
+DEFFUNCDOT(rem)
+DEFFUNCDOT(urem)
+DEFFUNCDOT(mul)
+DEFFUNCDOT(umul)
+DEFFUNCDOT(div)
+DEFFUNCDOT(udiv)
+LOOKUP SparcV89LookupTab[] = {
+ SYMFUNCDOT89(rem)
+ SYMFUNCDOT89(urem)
+ SYMFUNCDOT89(mul)
+ SYMFUNCDOT89(umul)
+ SYMFUNCDOT89(div)
+ SYMFUNCDOT89(udiv)
+ { 0, 0 }
+};
+LOOKUP SparcLookupTab[] = {
+ SYMFUNCDOT(rem)
+ SYMFUNCDOT(urem)
+ SYMFUNCDOT(mul)
+ SYMFUNCDOT(umul)
+ SYMFUNCDOT(div)
+ SYMFUNCDOT(udiv)
+ { 0, 0 }
+};
+#endif
+
+#if defined(__powerpc__) && (defined(Lynx) || defined(linux))
+void eieio();
+void _restf17();
+void _restf23();
+void _restf24();
+void _restf25();
+void _restf26();
+void _restf27();
+void _restf28();
+void _restf29();
+void _savef17();
+void _savef23();
+void _savef24();
+void _savef25();
+void _savef26();
+void _savef27();
+void _savef28();
+void _savef29();
+
+/* even if we compile without -DNO_INLINE we still provide
+ * the usual port i/o functions for module use
+ */
+
+extern volatile unsigned char *ioBase;
+
+/* XXX Should get all of these from elsewhere */
+
+extern void outb(unsigned short, unsigned char);
+extern void outw(unsigned short, unsigned short);
+extern void outl(unsigned short, unsigned int);
+extern unsigned int inb(unsigned short);
+extern unsigned int inw(unsigned short);
+extern unsigned int inl(unsigned short);
+extern unsigned long ldq_u(void *);
+extern unsigned long ldl_u(void *);
+extern unsigned short ldw_u(void *);
+extern void stl_u(unsigned long, void *);
+extern void stq_u(unsigned long, void *);
+extern void stw_u(unsigned short, void *);
+extern void mem_barrier(void);
+extern void write_mem_barrier(void);
+extern void stl_brx(unsigned long, volatile unsigned char *, int);
+extern void stw_brx(unsigned short, volatile unsigned char *, int);
+extern unsigned long ldl_brx(volatile unsigned char *, int);
+extern unsigned short ldw_brx(volatile unsigned char *, int);
+extern unsigned char rdinx(unsigned short, unsigned char);
+extern void wrinx(unsigned short, unsigned char, unsigned char);
+extern void modinx(unsigned short, unsigned char, unsigned char, unsigned char);
+extern int testrg(unsigned short, unsigned char);
+extern int testinx2(unsigned short, unsigned char, unsigned char);
+extern int testinx(unsigned short, unsigned char);
+#endif
+
+/* XXX This needs to be cleaned up for the new design */
+
+#ifdef DPMSExtension
+extern void DPMSSet(CARD16);
+#endif
+
+/* XFree86 things */
+
+LOOKUP xfree86LookupTab[] = {
+
+ /* Public OSlib functions */
+ SYMFUNC(xf86ReadBIOS)
+ SYMFUNC(xf86EnableIO)
+ SYMFUNC(xf86DisableIO)
+ SYMFUNC(xf86DisableInterrupts)
+ SYMFUNC(xf86EnableInterrupts)
+ SYMFUNC(xf86LinearVidMem)
+ SYMFUNC(xf86MapVidMem)
+ SYMFUNC(xf86UnMapVidMem)
+ SYMFUNC(xf86MapReadSideEffects)
+ SYMFUNC(xf86IODelay)
+ SYMFUNC(xf86SlowBcopy)
+#ifdef __alpha__
+ SYMFUNC(xf86SlowBCopyToBus)
+ SYMFUNC(xf86SlowBCopyFromBus)
+#endif
+ SYMFUNC(xf86BusToMem)
+ SYMFUNC(xf86MemToBus)
+ SYMFUNC(xf86OpenSerial)
+ SYMFUNC(xf86SetSerial)
+ SYMFUNC(xf86SetSerialSpeed)
+ SYMFUNC(xf86ReadSerial)
+ SYMFUNC(xf86WriteSerial)
+ SYMFUNC(xf86CloseSerial)
+ SYMFUNC(xf86GetErrno)
+ SYMFUNC(xf86WaitForInput)
+ SYMFUNC(xf86SerialSendBreak)
+ SYMFUNC(xf86FlushInput)
+ SYMFUNC(xf86SetSerialModemState)
+ SYMFUNC(xf86GetSerialModemState)
+ SYMFUNC(xf86SerialModemSetBits)
+ SYMFUNC(xf86SerialModemClearBits)
+#ifdef NEW_INPUT
+ SYMFUNC(xf86OSMouseInit)
+#endif
+
+#ifdef XINPUT
+/* XISB routines (Merged from Metrolink tree) */
+ SYMFUNC(XisbNew)
+ SYMFUNC(XisbFree)
+ SYMFUNC(XisbRead)
+ SYMFUNC(XisbWrite)
+ SYMFUNC(XisbTrace)
+ SYMFUNC(XisbBlockDuration)
+#endif
+
+ /* xf86Bus.c */
+ SYMFUNC(xf86CheckPciSlot)
+ SYMFUNC(xf86ClaimPciSlot)
+ SYMFUNC(xf86GetPciVideoInfo)
+ SYMFUNC(xf86GetPciConfigInfo)
+ SYMFUNC(xf86SetPciVideo)
+ SYMFUNC(xf86ClaimIsaSlot)
+ SYMFUNC(xf86ParsePciBusString)
+ SYMFUNC(xf86ComparePciBusString)
+ SYMFUNC(xf86ParseIsaBusString)
+ SYMFUNC(xf86EnableAccess)
+ SYMFUNC(xf86IsPrimaryPci)
+ SYMFUNC(xf86IsPrimaryIsa)
+ SYMFUNC(xf86CheckPciGAType)
+ SYMFUNC(xf86PrintResList)
+ SYMFUNC(xf86ClaimFixedResources)
+ SYMFUNC(xf86AddEntityToScreen)
+ SYMFUNC(xf86RemoveEntityFromScreen)
+ SYMFUNC(xf86GetEntityInfo)
+ SYMFUNC(xf86GetPciInfoForEntity)
+ SYMFUNC(xf86SetEntityFuncs)
+ SYMFUNC(xf86DeallocateResourcesForEntity)
+ SYMFUNC(xf86RegisterResources)
+ SYMFUNC(xf86CheckPciMemBase)
+ SYMFUNC(xf86SetAccessFuncs)
+ SYMFUNC(xf86IsEntityPrimary)
+ SYMFUNC(xf86FixPciResource)
+ SYMFUNC(xf86SetOperatingState)
+ SYMFUNC(xf86EnterServerState)
+ SYMFUNC(xf86GetBlock)
+ SYMFUNC(xf86GetSparse)
+ SYMFUNC(xf86ReallocatePciResources)
+ SYMFUNC(xf86ChkConflict)
+
+ /* xf86Cursor.c XXX not all of these should be exported */
+ SYMFUNC(xf86LockZoom)
+ SYMFUNC(xf86SetScreenLayout)
+ SYMFUNC(xf86SetViewport)
+ SYMFUNC(xf86ZoomLocked)
+ SYMFUNC(xf86ZoomViewport)
+ SYMFUNC(xf86GetPointerScreenFuncs)
+
+ /* xf86DGA.c */
+ /* For drivers */
+ SYMFUNC(DGAInit)
+ /* For extmod */
+ SYMFUNC(DGAAvailable)
+ SYMFUNC(DGAActive)
+ SYMFUNC(DGASetMode)
+ SYMFUNC(DGASelectInput)
+ SYMFUNC(DGAGetViewportStatus)
+ SYMFUNC(DGASetViewport)
+ SYMFUNC(DGAInstallCmap)
+ SYMFUNC(DGASync)
+ SYMFUNC(DGAFillRect)
+ SYMFUNC(DGABlitRect)
+ SYMFUNC(DGABlitTransRect)
+ SYMFUNC(DGAGetModes)
+ SYMFUNC(DGAGetOldDGAMode)
+ SYMFUNC(DGAGetModeInfo)
+ SYMFUNC(DGAChangePixmapMode)
+ SYMFUNC(DGACreateColormap)
+ SYMFUNC(DGAOpenFramebuffer)
+ SYMFUNC(DGACloseFramebuffer)
+
+ /* xf86DPMS.c */
+ SYMFUNC(xf86DPMSInit)
+
+ /* xf86Events.c */
+ SYMFUNC(SetTimeSinceLastInputEvent)
+ SYMFUNC(xf86AddInputHandler)
+ SYMFUNC(xf86RemoveInputHandler)
+ SYMFUNC(xf86DisableInputHandler)
+ SYMFUNC(xf86EnableInputHandler)
+
+ /* xf86Helper.c */
+ SYMFUNC(xf86AddDriver)
+ SYMFUNC(xf86AddInputDriver)
+ SYMFUNC(xf86DeleteDriver)
+ SYMFUNC(xf86DeleteInput)
+ SYMFUNC(xf86AllocateInput)
+ SYMFUNC(xf86AllocateScreen)
+ SYMFUNC(xf86DeleteScreen)
+ SYMFUNC(xf86AllocateScrnInfoPrivateIndex)
+ SYMFUNC(xf86AddPixFormat)
+ SYMFUNC(xf86SetDepthBpp)
+ SYMFUNC(xf86PrintDepthBpp)
+ SYMFUNC(xf86SetWeight)
+ SYMFUNC(xf86SetDefaultVisual)
+ SYMFUNC(xf86SetGamma)
+ SYMFUNC(xf86SetDpi)
+ SYMFUNC(xf86SetBlackWhitePixels)
+ SYMFUNC(xf86SaveRestoreImage)
+ SYMFUNC(xf86VDrvMsgVerb)
+ SYMFUNC(xf86DrvMsgVerb)
+ SYMFUNC(xf86DrvMsg)
+ SYMFUNC(xf86MsgVerb)
+ SYMFUNC(xf86Msg)
+ SYMFUNC(xf86ErrorFVerb)
+ SYMFUNC(xf86ErrorF)
+ SYMFUNC(xf86TokenToString)
+ SYMFUNC(xf86StringToToken)
+ SYMFUNC(xf86ShowClocks)
+ SYMFUNC(xf86PrintChipsets)
+ SYMFUNC(xf86MatchDevice)
+ SYMFUNC(xf86MatchPciInstances)
+ SYMFUNC(xf86MatchIsaInstances)
+ SYMFUNC(xf86GetVerbosity)
+ SYMFUNC(xf86GetVisualName)
+ SYMFUNC(xf86GetPix24)
+ SYMFUNC(xf86GetDepth)
+ SYMFUNC(xf86GetWeight)
+ SYMFUNC(xf86GetGamma)
+ SYMFUNC(xf86GetFlipPixels)
+ SYMFUNC(xf86GetServerName)
+ SYMFUNC(xf86ServerIsExiting)
+ SYMFUNC(xf86ServerIsOnlyProbing)
+ SYMFUNC(xf86ServerIsResetting)
+ SYMFUNC(xf86CaughtSignal)
+ SYMFUNC(xf86GetVidModeAllowNonLocal)
+ SYMFUNC(xf86GetVidModeEnabled)
+ SYMFUNC(xf86GetModInDevAllowNonLocal)
+ SYMFUNC(xf86GetModInDevEnabled)
+ SYMFUNC(xf86GetAllowMouseOpenFail)
+ SYMFUNC(xf86IsPc98)
+ SYMFUNC(xf86GetClocks)
+ SYMFUNC(xf86LoadSubModule)
+ SYMFUNC(xf86LoaderReqSymLists)
+ SYMFUNC(xf86LoaderReqSymbols)
+ SYMFUNC(xf86Break1)
+ SYMFUNC(xf86Break2)
+ SYMFUNC(xf86Break3)
+ SYMFUNC(xf86SetBackingStore)
+ SYMFUNC(xf86NewSerialNumber)
+ SYMFUNC(xf86FindXvOptions)
+ SYMFUNC(xf86GetOS)
+ SYMFUNC(xf86ConfigActivePciEntity)
+ SYMFUNC(xf86ConfigActiveIsaEntity)
+ SYMFUNC(xf86ConfigPciEntityInactive)
+ SYMFUNC(xf86ConfigIsaEntityInactive)
+ SYMFUNC(xf86IsScreenPrimary)
+
+ /* xf86Init.c */
+ SYMFUNC(xf86GetPixFormat)
+ SYMFUNC(xf86GetBppFromDepth)
+
+ /* xf86Mode.c */
+ SYMFUNC(xf86GetNearestClock)
+ SYMFUNC(xf86ModeStatusToString)
+ SYMFUNC(xf86LookupMode)
+ SYMFUNC(xf86CheckModeForMonitor)
+ SYMFUNC(xf86InitialCheckModeForDriver)
+ SYMFUNC(xf86CheckModeForDriver)
+ SYMFUNC(xf86ValidateModes)
+ SYMFUNC(xf86DeleteMode)
+ SYMFUNC(xf86PruneDriverModes)
+ SYMFUNC(xf86PruneMonitorModes)
+ SYMFUNC(xf86SetCrtcForModes)
+ SYMFUNC(xf86PrintModes)
+ SYMFUNC(xf86ShowClockRanges)
+
+ /* xf86Option.c */
+ SYMFUNC(xf86CollectOptions)
+ SYMFUNC(xf86CollectInputOptions)
+ /* Merging of XInput stuff */
+ SYMFUNC(xf86AddNewOption)
+ SYMFUNC(xf86SetBoolOption)
+ SYMFUNC(xf86NewOption)
+ SYMFUNC(xf86NextOption)
+ SYMFUNC(xf86OptionListCreate)
+ SYMFUNC(xf86OptionListMerge)
+ SYMFUNC(xf86OptionListFree)
+ SYMFUNC(xf86OptionName)
+ SYMFUNC(xf86OptionValue)
+ SYMFUNC(xf86OptionListReport)
+ SYMFUNC(xf86SetIntOption)
+ SYMFUNC(xf86SetStrOption)
+ SYMFUNC(xf86FindOption)
+ SYMFUNC(xf86FindOptionValue)
+ SYMFUNC(xf86MarkOptionUsed)
+ SYMFUNC(xf86MarkOptionUsedByName)
+ SYMFUNC(xf86CheckIfOptionUsed)
+ SYMFUNC(xf86CheckIfOptionUsedByName)
+ SYMFUNC(xf86ShowUnusedOptions)
+ SYMFUNC(xf86ProcessOptions)
+ SYMFUNC(xf86TokenToOptinfo)
+ SYMFUNC(xf86TokenToOptName)
+ SYMFUNC(xf86IsOptionSet)
+ SYMFUNC(xf86GetOptValString)
+ SYMFUNC(xf86GetOptValInteger)
+ SYMFUNC(xf86GetOptValULong)
+ SYMFUNC(xf86GetOptValReal)
+ SYMFUNC(xf86GetOptValFreq)
+ SYMFUNC(xf86GetOptValBool)
+ SYMFUNC(xf86ReturnOptValBool)
+ SYMFUNC(xf86NameCmp)
+
+ /* xf86fbman.c */
+ SYMFUNC(xf86InitFBManager)
+ SYMFUNC(xf86RegisterFreeBoxCallback)
+ SYMFUNC(xf86FreeOffscreenArea)
+ SYMFUNC(xf86AllocateOffscreenArea)
+ SYMFUNC(xf86AllocateLinearOffscreenArea)
+ SYMFUNC(xf86ResizeOffscreenArea)
+ SYMFUNC(xf86FBManagerRunning)
+
+ /* xf86cmap.c */
+ SYMFUNC(xf86HandleColormaps)
+
+ /* xf86xv.c */
+ SYMFUNC(xf86XVScreenInit)
+ SYMFUNC(xf86XVRegisterGenericAdaptor)
+ SYMFUNC(xf86XVListGenericAdaptors)
+
+ /* xf86VidMode.c */
+ SYMFUNC(VidModeExtensionInit)
+#ifdef XF86VIDMODE
+ SYMFUNC(VidModeGetCurrentModeline)
+ SYMFUNC(VidModeGetFirstModeline)
+ SYMFUNC(VidModeGetNextModeline)
+ SYMFUNC(VidModeDeleteModeline)
+ SYMFUNC(VidModeZoomViewport)
+ SYMFUNC(VidModeGetViewPort)
+ SYMFUNC(VidModeSetViewPort)
+ SYMFUNC(VidModeSwitchMode)
+ SYMFUNC(VidModeLockZoom)
+ SYMFUNC(VidModeGetMonitor)
+ SYMFUNC(VidModeCheckModeClock)
+ SYMFUNC(VidModeGetNumOfClocks)
+ SYMFUNC(VidModeGetClocks)
+ SYMFUNC(VidModeCheckModeForMonitor)
+ SYMFUNC(VidModeCheckModeForDriver)
+ SYMFUNC(VidModeSetCrtcForMode)
+ SYMFUNC(VidModeAddModeline)
+ SYMFUNC(VidModeGetDotClock)
+ SYMFUNC(VidModeGetNumOfModes)
+ SYMFUNC(VidModeSetGamma)
+ SYMFUNC(VidModeGetGamma)
+ SYMFUNC(VidModeCreateMode)
+ SYMFUNC(VidModeCopyMode)
+ SYMFUNC(VidModeGetModeValue)
+ SYMFUNC(VidModeSetModeValue)
+ SYMFUNC(VidModeGetMonitorValue)
+#endif
+
+ /* xf86MiscExt.c */
+#ifdef XF86MISC
+ SYMFUNC(MiscExtGetMouseSettings)
+ SYMFUNC(MiscExtGetMouseValue)
+ SYMFUNC(MiscExtSetMouseValue)
+ SYMFUNC(MiscExtGetKbdSettings)
+ SYMFUNC(MiscExtGetKbdValue)
+ SYMFUNC(MiscExtSetKbdValue)
+ SYMFUNC(MiscExtCreateStruct)
+ SYMFUNC(MiscExtApply)
+#endif
+
+ /* Misc */
+ SYMFUNC(GetTimeInMillis)
+
+ /* xf86Xinput.c */
+ SYMFUNC(xf86ProcessCommonOptions)
+#ifdef XINPUT
+ SYMFUNC(xf86IsCorePointer)
+ SYMFUNC(xf86PostMotionEvent)
+ SYMFUNC(xf86PostProximityEvent)
+ SYMFUNC(xf86PostButtonEvent)
+ SYMFUNC(xf86PostKeyEvent)
+ SYMFUNC(xf86GetMotionEvents)
+ SYMFUNC(xf86MotionHistoryAllocate)
+ SYMFUNC(xf86FirstLocalDevice)
+/* The following segment merged from Metrolink tree */
+ SYMFUNC(xf86XInputSetScreen)
+ SYMFUNC(xf86ScaleAxis)
+ SYMFUNC(xf86XInputSetSendCoreEvents)
+/* End merged segment */
+#endif
+#ifdef DPMSExtension
+ SYMFUNC(DPMSSet)
+#endif
+
+#if 0 /* we want to move the hw stuff in a module */
+ SYMFUNC(xf86dactopel)
+ SYMFUNC(xf86dactocomm)
+ SYMFUNC(xf86getdaccomm)
+ SYMFUNC(xf86setdaccomm)
+ SYMFUNC(xf86setdaccommbit)
+ SYMFUNC(xf86clrdaccommbit)
+ SYMFUNC(s3IBMRGB_Probe)
+ SYMFUNC(s3IBMRGB_Init)
+ SYMFUNC(s3InIBMRGBIndReg)
+ SYMFUNC(Ti3025SetClock)
+ SYMFUNC(Ti3026SetClock)
+ SYMFUNC(Ti3030SetClock)
+ SYMFUNC(AltICD2061SetClock)
+ SYMFUNC(SC11412SetClock)
+ SYMFUNC(ICS2595SetClock)
+ SYMFUNC(Att409SetClock)
+ SYMFUNC(Chrontel8391SetClock)
+ SYMFUNC(IBMRGBSetClock)
+ SYMFUNC(ICS5342SetClock)
+ SYMFUNC(S3TrioSetClock)
+ SYMFUNC(S3Trio64V2SetClock)
+ SYMFUNC(S3gendacSetClock)
+ SYMFUNC(STG1703SetClock)
+ SYMFUNC(ET6000SetClock)
+ SYMFUNC(S3AuroraSetClock)
+ SYMFUNC(commonCalcClock)
+ SYMFUNC(xf86writepci)
+ SYMFUNC(dacOutTi3026IndReg)
+ SYMFUNC(dacInTi3026IndReg)
+ SYMFUNC(s3OutIBMRGBIndReg)
+ SYMFUNC(CirrusFindClock)
+ SYMFUNC(CirrusSetClock)
+ SYMFUNC(STG1703getIndex)
+ SYMFUNC(STG1703setIndex)
+ SYMFUNC(STG1703magic)
+ SYMFUNC(gendacMNToClock)
+ SYMFUNC(Et4000AltICD2061SetClock)
+ SYMFUNC(ET4000stg1703SetClock)
+ SYMFUNC(ET4000gendacSetClock)
+
+#endif
+
+ SYMFUNC(pciFindFirst)
+ SYMFUNC(pciFindNext)
+ SYMFUNC(pciWriteByte)
+ SYMFUNC(pciWriteWord)
+ SYMFUNC(pciWriteLong)
+ SYMFUNC(pciReadByte)
+ SYMFUNC(pciReadWord)
+ SYMFUNC(pciReadLong)
+ SYMFUNC(pciSetBitsLong)
+ SYMFUNC(pciTag)
+ SYMFUNC(pciBusAddrToHostAddr)
+ SYMFUNC(pciHostAddrToBusAddr)
+ SYMFUNC(xf86MapPciMem)
+ SYMFUNC(xf86scanpci)
+ SYMFUNC(xf86ReadPciBIOS)
+ SYMFUNC(AllocatePixmapPrivateIndex)
+ SYMFUNC(AllocatePixmapPrivate)
+
+ /* Loader functions */
+ SYMFUNC(LoaderDefaultFunc)
+ SYMFUNC(LoadSubModule)
+ SYMFUNC(DuplicateModule)
+ SYMFUNC(LoaderErrorMsg)
+ SYMFUNC(LoaderCheckUnresolved)
+ SYMFUNC(LoadExtension)
+ SYMFUNC(LoadFont)
+ SYMFUNC(LoaderReqSymbols)
+ SYMFUNC(LoaderReqSymLists)
+ SYMFUNC(LoaderRefSymbols)
+ SYMFUNC(LoaderRefSymLists)
+ SYMFUNC(UnloadSubModule)
+ SYMFUNC(LoaderSymbol)
+ SYMFUNC(LoaderListDirs)
+ SYMFUNC(LoaderFreeDirList)
+ SYMFUNC(LoaderGetOS)
+
+ /*
+ * these here are our own interfaces to libc functions
+ */
+ SYMFUNC(xf86abort)
+ SYMFUNC(xf86abs)
+ SYMFUNC(xf86acos)
+ SYMFUNC(xf86asin)
+ SYMFUNC(xf86atan)
+ SYMFUNC(xf86atan2)
+ SYMFUNC(xf86atof)
+ SYMFUNC(xf86atoi)
+ SYMFUNC(xf86atol)
+ SYMFUNC(xf86bsearch)
+ SYMFUNC(xf86ceil)
+ SYMFUNC(xf86calloc)
+ SYMFUNC(xf86clearerr)
+ SYMFUNC(xf86close)
+ SYMFUNC(xf86cos)
+ SYMFUNC(xf86exit)
+ SYMFUNC(xf86exp)
+ SYMFUNC(xf86fabs)
+ SYMFUNC(xf86fclose)
+ SYMFUNC(xf86feof)
+ SYMFUNC(xf86ferror)
+ SYMFUNC(xf86fflush)
+ SYMFUNC(xf86fgetc)
+ SYMFUNC(xf86fgetpos)
+ SYMFUNC(xf86fgets)
+ SYMFUNC(xf86floor)
+ SYMFUNC(xf86fmod)
+ SYMFUNC(xf86fopen)
+ SYMFUNC(xf86fprintf)
+ SYMFUNC(xf86fputc)
+ SYMFUNC(xf86fputs)
+ SYMFUNC(xf86fread)
+ SYMFUNC(xf86free)
+ SYMFUNC(xf86freopen)
+ SYMFUNC(xf86fscanf)
+ SYMFUNC(xf86fseek)
+ SYMFUNC(xf86fsetpos)
+ SYMFUNC(xf86ftell)
+ SYMFUNC(xf86fwrite)
+ SYMFUNC(xf86getc)
+ SYMFUNC(xf86getenv)
+ SYMFUNC(xf86hypot)
+ SYMFUNC(xf86ioctl)
+ SYMFUNC(xf86isalnum)
+ SYMFUNC(xf86isalpha)
+ SYMFUNC(xf86iscntrl)
+ SYMFUNC(xf86isdigit)
+ SYMFUNC(xf86isgraph)
+ SYMFUNC(xf86islower)
+ SYMFUNC(xf86isprint)
+ SYMFUNC(xf86ispunct)
+ SYMFUNC(xf86isspace)
+ SYMFUNC(xf86isupper)
+ SYMFUNC(xf86isxdigit)
+ SYMFUNC(xf86labs)
+ SYMFUNC(xf86log)
+ SYMFUNC(xf86log10)
+ SYMFUNC(xf86lseek)
+ SYMFUNC(xf86malloc)
+ SYMFUNC(xf86memchr)
+ SYMFUNC(xf86memcmp)
+ SYMFUNC(xf86memcpy)
+#if (defined(__powerpc__) && (defined(Lynx) || defined(linux))) || defined(__sparc__)
+ /*
+ * These PPC and SPARC compilers generate calls to memcpy to handle
+ * structure copies. This causes a problem both here and in shared
+ * libraries as there is no way to map the name of the call to the
+ * correct function.
+ */
+ SYMFUNC(memcpy)
+ /*
+ * Thes PPC and SPARC compilers generate calls to memset to handle
+ * aggregate initializations.
+ */
+ SYMFUNC(memset)
+#endif
+ SYMFUNC(xf86memmove)
+ SYMFUNC(xf86memset)
+ SYMFUNC(xf86mmap)
+ SYMFUNC(xf86modf)
+ SYMFUNC(xf86munmap)
+ SYMFUNC(xf86open)
+ SYMFUNC(xf86perror)
+ SYMFUNC(xf86pow)
+ SYMFUNC(xf86printf)
+ SYMFUNC(xf86read)
+ SYMFUNC(xf86realloc)
+ SYMFUNC(xf86remove)
+ SYMFUNC(xf86rename)
+ SYMFUNC(xf86rewind)
+ SYMFUNC(xf86setbuf)
+ SYMFUNC(xf86setvbuf)
+ SYMFUNC(xf86sin)
+ SYMFUNC(xf86snprintf)
+ SYMFUNC(xf86sprintf)
+ SYMFUNC(xf86sqrt)
+ SYMFUNC(xf86sscanf)
+ SYMFUNC(xf86strcat)
+ SYMFUNC(xf86strcmp)
+ SYMFUNC(xf86strcasecmp)
+ SYMFUNC(xf86strcpy)
+ SYMFUNC(xf86strcspn)
+ SYMFUNC(xf86strerror)
+ SYMFUNC(xf86strlen)
+ SYMFUNC(xf86strncmp)
+ SYMFUNC(xf86strncasecmp)
+ SYMFUNC(xf86strncpy)
+ SYMFUNC(xf86strpbrk)
+ SYMFUNC(xf86strchr)
+ SYMFUNC(xf86strrchr)
+ SYMFUNC(xf86strspn)
+ SYMFUNC(xf86strstr)
+ SYMFUNC(xf86strtod)
+ SYMFUNC(xf86strtok)
+ SYMFUNC(xf86strtol)
+ SYMFUNC(xf86strtoul)
+ SYMFUNC(xf86tan)
+ SYMFUNC(xf86tmpfile)
+ SYMFUNC(xf86tolower)
+ SYMFUNC(xf86toupper)
+ SYMFUNC(xf86ungetc)
+ SYMFUNC(xf86vfprintf)
+ SYMFUNC(xf86vsnprintf)
+ SYMFUNC(xf86vsprintf)
+
+/* non-ANSI C functions */
+ SYMFUNC(xf86opendir)
+ SYMFUNC(xf86closedir)
+ SYMFUNC(xf86readdir)
+ SYMFUNC(xf86rewinddir)
+ SYMFUNC(xf86ffs)
+ SYMFUNC(xf86strdup)
+ SYMFUNC(xf86bzero)
+ SYMFUNC(xf86usleep)
+ SYMFUNC(xf86execl)
+
+ SYMFUNC(xf86getsecs)
+ SYMFUNC(xf86fpossize) /* for returning sizeof(fpos_t) */
+
+ /* These provide for DRI support. */
+ SYMFUNC(xf86stat)
+ SYMFUNC(xf86fstat)
+ SYMFUNC(xf86access)
+ SYMFUNC(xf86geteuid)
+ SYMFUNC(xf86mknod)
+ SYMFUNC(xf86chmod)
+ SYMFUNC(xf86chown)
+ SYMFUNC(xf86sleep)
+#ifdef XF86DRI
+ /* These may have more general uses, but
+ for now, they are only used by the DRI.
+ Loading them only when the DRI is built
+ may make porting (the non-DRI portions
+ of the X server) easier. */
+ SYMFUNC(xf86InstallSIGIOHandler)
+ SYMFUNC(xf86RemoveSIGIOHandler)
+#endif
+
+#if defined(__alpha__)
+ SYMFUNC(__divl)
+ SYMFUNC(__reml)
+ SYMFUNC(__divlu)
+ SYMFUNC(__remlu)
+ SYMFUNC(__divq)
+ SYMFUNC(__divqu)
+ SYMFUNC(__remq)
+ SYMFUNC(__remqu)
+
+ SYMFUNC(_outw)
+ SYMFUNC(_outb)
+ SYMFUNC(_outl)
+ SYMFUNC(_inb)
+ SYMFUNC(_inw)
+ SYMFUNC(_inl)
+ SYMFUNC(xf86ReadSparse32)
+ SYMFUNC(xf86ReadSparse16)
+ SYMFUNC(xf86ReadSparse8)
+ SYMFUNC(xf86WriteSparse32)
+ SYMFUNC(xf86WriteSparse16)
+ SYMFUNC(xf86WriteSparse8)
+ SYMFUNC(memcpy)
+#endif
+#if defined(__powerpc__)
+ SYMFUNC(inb)
+ SYMFUNC(inw)
+ SYMFUNC(inl)
+ SYMFUNC(outb)
+ SYMFUNC(outw)
+ SYMFUNC(outl)
+#if defined(NO_INLINE) || defined(Lynx)
+ SYMFUNC(mem_barrier)
+ SYMFUNC(ldl_u)
+ SYMFUNC(eieio)
+ SYMFUNC(ldl_brx)
+ SYMFUNC(ldw_brx)
+ SYMFUNC(stl_brx)
+ SYMFUNC(stw_brx)
+ SYMFUNC(ldq_u)
+ SYMFUNC(ldw_u)
+ SYMFUNC(stl_u)
+ SYMFUNC(stq_u)
+ SYMFUNC(stw_u)
+ SYMFUNC(write_mem_barrier)
+#endif
+ SYMFUNC(rdinx)
+ SYMFUNC(wrinx)
+ SYMFUNC(modinx)
+ SYMFUNC(testrg)
+ SYMFUNC(testinx2)
+ SYMFUNC(testinx)
+#if defined(Lynx)
+ SYMFUNC(_restf17)
+ SYMFUNC(_restf23)
+ SYMFUNC(_restf24)
+ SYMFUNC(_restf25)
+ SYMFUNC(_restf26)
+ SYMFUNC(_restf27)
+ SYMFUNC(_restf28)
+ SYMFUNC(_restf29)
+ SYMFUNC(_savef17)
+ SYMFUNC(_savef23)
+ SYMFUNC(_savef24)
+ SYMFUNC(_savef25)
+ SYMFUNC(_savef26)
+ SYMFUNC(_savef27)
+ SYMFUNC(_savef28)
+ SYMFUNC(_savef29)
+#endif
+#if PPCIO_DEBUG
+ SYMFUNC(debug_inb)
+ SYMFUNC(debug_inw)
+ SYMFUNC(debug_inl)
+ SYMFUNC(debug_outb)
+ SYMFUNC(debug_outw)
+ SYMFUNC(debug_outl)
+#endif
+#endif
+
+/*
+ * and now some variables
+ */
+
+ SYMVAR(xf86stdin)
+ SYMVAR(xf86stdout)
+ SYMVAR(xf86stderr)
+ SYMVAR(xf86errno)
+ SYMVAR(xf86HUGE_VAL)
+
+ /* General variables (from xf86.h) */
+ SYMVAR(xf86ScreenIndex)
+ SYMVAR(xf86PixmapIndex)
+ SYMVAR(xf86Screens)
+ SYMVAR(byte_reversed)
+
+ /* variables for PCI devices and cards from xf86Bus.c */
+ SYMVAR(xf86PCICardInfo)
+ SYMVAR(xf86PCIVendorInfo)
+ SYMVAR(xf86PCIVendorNameInfo)
+
+ /* predefined resource lists from xf86Bus.h */
+ SYMVAR(resVgaExclusive)
+ SYMVAR(resVgaShared)
+ SYMVAR(resVgaUnusedExclusive)
+ SYMVAR(resVgaUnusedShared)
+ SYMVAR(resVgaSparseExclusive)
+ SYMVAR(resVgaSparseShared)
+ SYMVAR(res8514Exclusive)
+ SYMVAR(res8514Shared)
+ SYMVAR(PciAvoid)
+
+#if defined(__powerpc__) && (!defined(NO_INLINE) || defined(Lynx))
+ SYMVAR(ioBase)
+#endif
+
+ /* Globals from xf86Globals.c and xf86Priv.h */
+ SYMVAR(xf86ConfigDRI)
+
+ { 0, 0 },
+
+};
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/Imakefile
new file mode 100644
index 000000000..89e248d7b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/Imakefile
@@ -0,0 +1,121 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/Imakefile,v 3.29 1999/08/14 10:50:04 dawes Exp $
+
+
+
+
+
+XCOMM $XConsortium: Imakefile /main/9 1996/10/25 15:38:46 kaleb $
+
+#include <Server.tmpl>
+
+#define IHaveSubdirs
+
+#if defined(i386Architecture) || \
+ (defined(LinuxArchitecture) && defined(AlphaArchitecture)) || \
+ defined(PpcArchitecture) || defined(SparcArchitecture)
+BUS_SUBDIR = bus
+#endif
+
+#if defined(ArcArchitecture)
+OS_SUBDIR = bsd
+#endif
+
+#if defined(SVR3Architecture)
+# if defined(i386ScoArchitecture)
+OS_SUBDIR = sco
+# else
+OS_SUBDIR = sysv
+# endif
+#endif
+
+#if defined(SVR4Architecture)
+# if defined(SunArchitecture)
+OS_SUBDIR = solx86
+# elif defined(PmaxOSArchitecture)
+OS_SUBDIR = pmax
+# elif defined(DguxArchitecture)
+OS_SUBDIR = dgux
+# else
+OS_SUBDIR = sysv
+# endif
+#endif
+
+#if defined(LinuxArchitecture)
+OS_SUBDIR = linux
+#endif
+
+#if defined(LynxOSArchitecture)
+OS_SUBDIR = lynxos
+#endif
+
+#if defined(i386BsdArchitecture)
+# if defined(BSD386Architecture)
+OS_SUBDIR = bsdi
+# else
+OS_SUBDIR = bsd
+# endif
+#endif
+
+#if defined(NetBSDArchitecture) && defined(Arm32Architecture)
+OS_SUBDIR = bsd
+#endif
+
+#if defined(i386MachArchitecture) || defined(OsfArchitecture)
+#if defined(GNUMachArchitecture)
+OS_SUBDIR = hurd
+#else
+OS_SUBDIR = mach
+#endif
+#endif
+
+#if defined(AmoebaArchitecture)
+OS_SUBDIR = amoeba
+#endif
+
+#if defined(MinixArchitecture)
+OS_SUBDIR = minix
+#endif
+
+#if defined(OS2Architecture)
+OS_SUBDIR = os2
+#endif
+
+#if defined(i386Sco325Architecture)
+OS_SUBDIR = sco
+#endif
+
+#if BuildXF86DRI && !DoLoadableServer
+DRM_SRC = $(OS_SUBDIR)/drm/?*.o
+DRM_OBJ = $(OS_SUBDIR)/drm/?*.o
+#endif
+
+SUBDIRS = $(OS_SUBDIR) $(BUS_SUBDIR) misc
+
+SRCS = $(OS_SUBDIR)/?*.c $(BUS_SUBDIR)/?*.c misc/?*.c $(DRM_SRC)
+OBJS = $(OS_SUBDIR)/?*.o $(BUS_SUBDIR)/?*.o misc/?*.o $(DRM_OBJ)
+
+DONES = $(OS_SUBDIR)/DONE $(BUS_SUBDIR)/DONE misc/DONE
+
+#if HasParallelMake
+MakeMutex($(SUBDIRS) $(OBJS) $(DONES))
+#endif
+
+#if HasGnuMake || HasBsdMake
+$(DONES): $(SUBDIRS)
+#endif
+
+NormalDepLibraryTarget(xf86_os,$(SUBDIRS) $(DONES),$(OBJS))
+
+#if !HasSnprintf
+LinkSourceFile(snprintf.c,$(LIBSRC)/misc)
+#endif
+
+ForceSubdirs($(SUBDIRS))
+
+DependSubdirs($(SUBDIRS))
+
+
+InstallDriverSDKNonExecFile(xf86_OSproc.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(xf86_ansic.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(xf86_libc.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(xf86drm.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/README.OS-lib b/xc/programs/Xserver/hw/xfree86/os-support/README.OS-lib
new file mode 100644
index 000000000..16dece64a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/README.OS-lib
@@ -0,0 +1,511 @@
+
+ README for XFree86 OS-support Layer
+ -----------------------------------
+
+Contents
+--------
+ 1) Overview
+ 2) Directory Layout
+ 3) Adding a new OS
+ 4) OS Support API
+
+1 - Overview
+------------
+ This directory contains the OS support layer functions for the XFree86
+servers. In addition, some miscellaneous server support functions (not
+OS-dependent) are included here, to take advantage of the fact that this
+library comes last in the linking order.
+
+Most of the functionality required to support a new OS is encapsulated in
+this library. It is hoped that all OS-specific details can be encapsulated,
+but that is not likely ever to be completely possible. Hence some minor
+changes will wind up being made in other parts of the server. The major
+design principles for this library are maintainability, readability, and
+portability. Sometimes these goals conflict; some somewhat arbitrary choices
+have been made in implementation.
+
+2 - Directory Layout
+--------------------
+ os-support/ Contains headers and documentation; no code
+ misc/ Non-OS-specific miscellaneous functions that
+ fit best into the link architecture this way.
+ shared/ Contains files with functions used by more than one
+ OS. These are symlinked into the OS subdirectories
+ at build time via Imakefile rules. This is alway
+ preferable to reproducing functions in more than one
+ OS library.
+ amoeba/ OS support for the Amoeba operating system.
+ bsd/ OS support for the 386BSD/NetBSD/FreeBSD operating
+ systems.
+ bsdi/ OS support for the BSD/386 operating system.
+ linux/ OS support for the Linux operating system.
+ mach/ OS support for the Mach and OSF/1 operating systems.
+ minix/ OS support for the Minix operating system.
+ os2/ OS support for OS/2 2.11 and OS/2 Warp
+ sco/ OS support for the SCO SVR3.x operating system.
+ solx86/ OS support for the Solaris x86 operating system.
+ sysv/ OS support for all SVR4.0 and SVR4.2, and for
+ ISC and AT&T SVR3.2 operating systems.
+
+3 - Adding A New OS
+-------------------
+ Adding a support for a new operating system entails implementing all of
+the functions described in the API below. Many of these functions are no-ops
+for many operating systems, and appropriate files with dummy declarations are
+available in the 'shared' subdirectory.
+
+If your OS is sufficiently similar to an existing OS, you can make use of
+the existing subdirectory. One of the reasons for implementing this OS
+library was the unmaintainability of the spagetti-#ifdef code that existed
+before. You should try to avoid cluttering the code with #ifdef's. If
+you find that the subdirectory is getting cluttered, split off into a
+seperate subdirectory (e.g. as was done for SCO, rather than cluttering
+the 'sysv' subdirectory). You can split functions out of an existing
+subdirectory into the 'shared' subdirectory, if that is appropriate. Just
+remember to update the Imakefile for the old subdirectory.
+
+You will still likely have to make some small changes to other parts of
+the server. You should not put OS-specific #define's or #include's anywhere
+else in the server. These should all go in the "xf86_OSlib.h" header file
+in this directory.
+
+4 - OS Support API
+-----------------
+void xf86OpenConsole(void)
+{
+ /*
+ * Open console device, activate VTs, etc, etc. Fill in requisite
+ * pieces of x386Info. Most of this code comes from x386Init.c
+ */
+}
+
+void xf86CloseConsole(void)
+{
+ /*
+ * Close console at server exit.
+ */
+}
+
+Bool xf86VTSwitchPending(void)
+{
+ /*
+ * Returns TRUE iff there is a VT switch operation pending for
+ * the server. In the USL VT model, this is indicated via a
+ * signal handler. Should return FALSE always for OSs without
+ * VTs.
+ */
+}
+
+Bool xf86VTSwitchAway(void)
+{
+ /*
+ * Handles the OS-specific action for switching away from the active
+ * VT. Returns FALSE if the switch away fails. Should return
+ * FALSE always for OSs without VTs (then again, this function
+ * should never be called in that case).
+ */
+}
+
+Bool xf86VTSwitchTo(void)
+{
+ /*
+ * Handles the OS-specific action for switching to the active VT.
+ * Returns FALSE if the switch to fails. Should return TRUE
+ * always for OSs without VTs (then again, this function should
+ * never be called in that case).
+ */
+}
+
+Bool xf86LinearVidMem(void)
+{
+ /*
+ * Returns TRUE if the OS supports mapping linear frame buffers
+ * (ie memory at addresses above physical memory).
+ */
+}
+
+pointer xf86MapVidMem(int ScreenNum, int Region, pointer Base,
+ unsigned long Size)
+{
+ /*
+ * Handle mapping the video memory. Returns (pointer *)0 for
+ * failure; causes server exit. It is allowable to call FatalError()
+ * from inside this function and exit directly.
+ */
+}
+
+void xf86UnMapVidMem(int ScreenNum, int Region, pointer Base,
+ unsigned long Size)
+{
+ /*
+ * Handle unmapping the video memory. This should undo what
+ * xf86MapVidMem() does. Base is a pointer obtained from
+ * a previous call to xf86MapVidMem().
+ */
+}
+
+void xf86MapDisplay(int ScreenNum, int Region)
+{
+ /*
+ * For OSs that require the screen be mapped when entering a VT.
+ * A dummy function will be defined for OSs that don't require
+ * this (or don't have VTs at all).
+ */
+}
+
+void xf86UnMapDisplay(int ScreenNum, int Region)
+{
+ /*
+ * For Os that require that the screen be unmapped when leaving a
+ * VT. A dummy function will be defined for OSs that don't require
+ * this (or don't have VTs at all).
+ */
+}
+
+int xf86ReadBIOS(unsigned long Base, unsigned long Offset,
+ unsigned char *Buf, int Len)
+{
+ /*
+ * Read Len bytes from the BIOS at address Base, offset Offset,
+ * into buffer Buf. Returns -1 for failure or if the OS does
+ * not support reading the BIOS. This causes a driver probe
+ * to fail, but does not cause the server to abort.
+ */
+}
+
+
+void xf86EnableIOPorts(int ScreenNum)
+{
+ /*
+ * Enables I/O permissions. The OS layer should
+ * enable all I/O port access.
+ */
+}
+
+void xf86DisableIOPorts(int ScreenNum)
+{
+ /*
+ * Disables I/O permissions.
+ */
+}
+
+Bool xf86DisableInterrupts(void)
+{
+ /*
+ * Disable interrupts if allowed for this OS. Returns FALSE if
+ * this is not allowed or if the attempt fails for some reason.
+ */
+}
+
+void xf86EnableInterrupts(void)
+{
+ /*
+ * Reenable interrupts
+ */
+}
+
+int xf86ProcessArgument(int argc, char *argv[], int i)
+{
+ /*
+ * Process OS-specific command-line arguments. See
+ * ddxProcessArgument() for more info.
+ */
+}
+
+void xf86UseMsg(void)
+{
+ /*
+ * Print list of OS-specific command-line arguments. See
+ * ddxUseMsg() for more info.
+ */
+}
+
+void xf86SoundKbdBell(int loudness, int pitch, int duration)
+{
+ /*
+ * Sound the keyboard bell. pitch is in Hz, duration in ms,
+ * loudness is in the range 0-100 (0 -> off). For systems
+ * where the loudness can't be controlled, scale the duration
+ * by loudness/50.
+ */
+}
+
+void xf86SetKbdLeds(int leds)
+{
+ /*
+ * Set the keyboard LEDs to the state indicated in leds
+ */
+}
+
+int xf86GetKbdLeds(void)
+{
+ /*
+ * Return the state of the keyboard LEDs. If the OS doesn't
+ * support this, return 0.
+ */
+}
+
+void xf86SetKbdRepeat(char rad)
+{
+ /*
+ * Set the keyboard repeat rate and delay according the
+ * the rad value. The lower 5 bits determine the repeat
+ * rate (lower value -> higher rate). The next 2 bits
+ * determine the delay.
+ * This should possibly be changed to take separate rate and
+ * delay parameters.
+ */
+}
+
+void xf86KbdInit(void)
+{
+ /*
+ * Save initial keyboard state. This is called at the start of
+ * each server generation.
+ */
+}
+
+int xf86KbdOn(void)
+{
+ /*
+ * Set the keyboard up for use with X. This is called whenever
+ * the server becomes active (ie at the start of each generation and
+ * whenever its VT becomes active). Return the file descriptor
+ * for keyboard input. Return -1 if there is no file descriptor
+ * to add as an input device. If there are errors encountered,
+ * call FatalError(). A return value of -1 is not considered an
+ * error condition.
+ */
+}
+
+int xf86KbdOff(void)
+{
+ /*
+ * Return the keyboard to the state saved by xf86KbdInit(). This is
+ * called at the end of a server generation, and also when the
+ * server's VT ceases being active. Returns the keyboard file
+ * descriptor. Returns -1 if there is no file descriptor to be
+ * removed as an input device. Errors should be handled the same
+ * way as in xf86KbdOn().
+ */
+}
+
+void xf86KbdEvents(void)
+{
+ /*
+ * Read characters from the keyboard device, and post the events
+ * by calling x386PostKbdEvent(). Read as much as is available
+ * without waiting.
+ */
+}
+
+void xf86SetMouseSpeed(int old, int new, unsigned cflag)
+{
+ /*
+ * Set the speed of the mouse port. old is the previous speed,
+ * new is the new speed, and cflag is the value of the termio[s]
+ * c_cflag field. For mice that have programmable speed operation,
+ * this should send the appropriate commands to the mouse.
+ */
+}
+
+void xf86MouseInit(void)
+{
+ /*
+ * This is called at the start of each server generation. In most
+ * cases this is a noop. If the mouse must not be opened/closed
+ * when VT switching, the open should be done here.
+ */
+}
+
+int xf86MousedOn(void)
+{
+ /*
+ * Set the mouse up for use with X. This is called whenever
+ * the server becomes active (ie at the start of each generation and
+ * whenever its VT becomes active). This function normally opens
+ * the mouse device, and may call xf86SetupMouse() to initialise
+ * the mouse parameters. Return the file descriptor for mouse input.
+ * Return -1 if there is no file descriptor to add as an input
+ * device. If there are errors encountered, call FatalError().
+ * A return value of -1 is not considered an error condition.
+ */
+}
+
+int xf86MouseOff(Bool doclose)
+{
+ /*
+ * Release the mouse from use with X. This is called at the end
+ * of a server generation (with doclose==TRUE), and also when the
+ * server's VT ceases being active (with doclose==FALSE). If the
+ * mouse should not be opened/closed when VT switching, the close
+ * should be done here when doclose==TRUE. For other systems, the
+ * mouse device should be closed regardless of the doclose value.
+ * Returns the mouse file descriptor. Returns -1 if there is no
+ * file descriptor to be removed as an input device. Errors
+ * should be handled the same way as in xf86MouseOn().
+ */
+}
+
+void xf86MouseEvents(void)
+{
+ /*
+ * Read characters from the mouse device, and post the events
+ * by calling x386PostMseEvent(). Read as much as is available
+ * without waiting. If the OS doesn't handle the mouse protocol
+ * translation, xf86MouseProtocol() may be called to do the
+ * translation and event posting. If the OS does handle the protocol
+ * translation, MOUSE_PROTOCOL_IN_KERNEL should be #define'd in
+ * xf86_OSlib.h.
+ */
+}
+
+int xf86OsMouseProc(DevicePtr pPointer, int what)
+{
+ /*
+ * Implements the device-proc for the pointer device when an
+ * OS-based mouse driver is being used (as opposed to the
+ * server's internal mouse driver). Implemented as any other
+ * device-proc in the server.
+ *
+ * This function only needs to be implemented if USE_OSMOUSE is
+ * defined for the OS.
+ */
+}
+
+int xf86OsMouseEvents(void)
+{
+ /*
+ * When supporting an OS-based mouse driver (as opposed to the
+ * server's internal mouse driver), read some events from the device
+ * and post them to the DIX layer through x386PostMseEvent().
+ *
+ * This function only needs to be implemented if USE_OSMOUSE is
+ * defined for the OS.
+ */
+}
+
+void xf86OsMouseOption(int token, pointer lex_ptr)
+{
+ /*
+ * Used in parsing an OsMouse keyword from the Xconfig file.
+ * Passed the token type and a pointer to the token value.
+ * The function should do whatever is appropriate for the OS's
+ * mouse driver.
+ *
+ * This function only needs to be implemented if USE_OSMOUSE is
+ * defined for the OS.
+ */
+}
+
+/*
+ * The following functions are simply wrappers around the OS specific
+ * libc functions
+ */
+
+void *
+xf86memmove(void * dest, const void * src, INT32 n)
+{
+ return(memmove(dest,src,n));
+}
+
+void *
+xf86memset(void * s, int c, INT32 n)
+{
+ return(memset(s,c,n));
+}
+
+void *
+xf86memcpy(void * dest, const void * src, INT32 n)
+{
+ return(memcpy(dest,src,n));
+}
+
+int
+xf86memcmp(const void * s1, const void * s2, INT32 n)
+{
+ return(memcmp(s1,s2,n));
+}
+
+char *
+xf86strcat(char * dest, const char * src)
+{
+ return(strcat(dest,src));
+}
+
+char *
+xf86strcpy(char * dest, const char * src)
+{
+ return(strcpy(dest,src));
+}
+
+int
+xf86strcmp(const char * s1, const char * s2)
+{
+ return(strcmp(s1,s2));
+}
+
+int
+xf86strncmp(const char * s1, const char * s2, INT32 n)
+{
+ return(strncmp(s1,s2,n));
+}
+
+size_t
+xf86strlen(const char * s)
+{
+ return(strlen(s));
+}
+
+void
+xf86getsecs(INT32 * secs, INT32 * usecs)
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ *secs = tv.tv_sec;
+ *usecs= tv.tv_usec;
+
+ return;
+}
+
+double
+xf86exp(double x)
+{
+ return(exp(x));
+}
+
+double
+xf86log(double x)
+{
+ return(log(x));
+}
+
+double
+xf86pow(double x, double y)
+{
+ return(pow(x,y));
+}
+
+double
+xf86sqrt(double x)
+{
+ return(sqrt(x));
+}
+
+double
+xf86cos(double x)
+{
+ return(cos(x));
+}
+
+
+
+
+$XFree86: xc/programs/Xserver/hw/xfree86/os-support/README.OS-lib,v 3.6 1997/08/26 10:01:33 hohndel Exp $
+
+
+
+
+
+$XConsortium: README.OS-lib /main/5 1996/02/21 17:50:28 kaleb $
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/amoeba/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/amoeba/Imakefile
new file mode 100644
index 000000000..e4deae416
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/amoeba/Imakefile
@@ -0,0 +1,35 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/amoeba/Imakefile,v 3.2 1999/07/10 07:24:47 dawes Exp $
+
+
+
+
+XCOMM $XConsortium: Imakefile /main/4 1996/09/28 17:23:26 rws $
+
+#include <Server.tmpl>
+
+#if AckToolset
+IOSRC = inout.S
+IOOBJ = inout.o
+#endif
+
+SRCS = am_init.c am_video.c am_io.c mapVT_noop.c ioperm_noop.c \
+ VTsw_noop.c $(IOSRC)
+OBJS = am_init.o am_video.o am_io.o mapVT_noop.o ioperm_noop.o \
+ VTsw_noop.o $(IOOBJ)
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC)
+
+SubdirLibraryRule($(OBJS))
+NormalLibraryObjectRule()
+NormalAsmObjectRule()
+
+ObjectFromSpecialSource(mapVT_noop,../shared/mapVT_noop,/**/)
+ObjectFromSpecialSource(ioperm_noop,../shared/ioperm_noop,/**/)
+ObjectFromSpecialSource(VTsw_noop,../shared/VTsw_noop,/**/)
+#if AckToolset
+ObjectFromSpecialAsmSource(inout,../shared/inout,/**/)
+#endif
+
+DependTarget()
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/amoeba/am_init.c b/xc/programs/Xserver/hw/xfree86/os-support/amoeba/am_init.c
new file mode 100644
index 000000000..57cdb87da
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/amoeba/am_init.c
@@ -0,0 +1,105 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/amoeba/am_init.c,v 3.6 1998/07/25 16:56:31 dawes Exp $ */
+/*
+ * Copyright 1993 by Vrije Universiteit, The Netherlands
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of the Vrije Universiteit and David
+ * Wexelblat not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * The Vrije Universiteit and David Wexelblat make no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE VRIJE UNIVERSITEIT AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE VRIJE UNIVERSITEIT OR
+ * DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: am_init.c /main/5 1996/02/21 17:50:35 kaleb $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+static capability vgaMemCap;
+
+void xf86OpenConsole()
+{
+ char *findhole();
+ segid seg;
+ int nbytes;
+ errstat err;
+
+ if (serverGeneration == 1)
+ {
+ /*
+ * Get segment capability for video memory, and map it in.
+ * We do it this early since a side effect is that the I/O
+ * space is also mapped in.
+ */
+ if ((err = iop_map_mem(&iopcap, &vgaMemCap)) != STD_OK)
+ {
+ FatalError("xf86OpenConsole: iop_map_mem failed (%s)\n",
+ err_why(err));
+ }
+
+ /* Map in aligned screen memory */
+ nbytes = 0x10000; /* 64 Kb */
+ xf86Info.screenPtr =
+ (pointer)(((unsigned) findhole(2 * nbytes) & ~0xFFF) + 0x1000);
+ if ((seg = seg_map(&vgaMemCap,xf86Info.screenPtr, nbytes,
+ MAP_TYPEDATA|MAP_READWRITE|MAP_INPLACE)) < 0)
+ {
+ FatalError("xf86OpenConsole: Map segment failed: %s\n",
+ err_why(ERR_CONVERT(seg)));
+ }
+ }
+ return;
+}
+
+void xf86CloseConsole()
+{
+ static am_port_t nullport;
+ errstat err;
+
+ if (!NULLPORT(&vgaMemCap.cap_port)) {
+ /* Unmap video's memory segment */
+ if ((err = iop_unmap_mem(&iopcap, &vgaMemCap)) != STD_OK)
+ {
+ xf86FatalError("xf86CloseConsole: iop_map_mem failed (%s)\n",
+ err_why(err));
+ }
+ vgaMemCap.cap_port = nullport;
+ }
+ return;
+}
+
+/* ARGSUSED */
+int xf86ProcessArgument (argc, argv, i)
+int argc;
+char *argv[];
+int i;
+{
+ return(0);
+}
+
+void xf86UseMsg()
+{
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/amoeba/am_io.c b/xc/programs/Xserver/hw/xfree86/os-support/amoeba/am_io.c
new file mode 100644
index 000000000..9a2ade17b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/amoeba/am_io.c
@@ -0,0 +1,192 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/amoeba/am_io.c,v 3.11 1999/05/07 02:56:18 dawes Exp $ */
+/*
+ * Copyright 1993 by Vrije Universiteit, The Netherlands
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of the Vrije Universiteit and David
+ * Dawes not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * The Vrije Universiteit and David Dawes make no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE VRIJE UNIVERSITEIT AND DAVID DAWES DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE VRIJE UNIVERSITEIT OR
+ * DAVID DAWES 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.
+ *
+ */
+/* $XConsortium: am_io.c /main/9 1996/10/19 18:05:55 kaleb $ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86Config.h"
+
+Bool xf86SupportedMouseTypes[] =
+{
+ TRUE, /* Microsoft */
+ TRUE, /* MouseSystems */
+ TRUE, /* MMSeries */
+ TRUE, /* Logitech */
+ TRUE, /* BusMouse */
+ TRUE, /* MouseMan */
+ TRUE, /* PS/2 */
+ FALSE, /* Hitachi Tablet */
+};
+
+int xf86NumMouseTypes = sizeof(xf86SupportedMouseTypes) /
+ sizeof(xf86SupportedMouseTypes[0]);
+
+void xf86SoundKbdBell(loudness, pitch, duration)
+int loudness;
+int pitch;
+int duration;
+{
+ if (loudness)
+ {
+ errstat err;
+
+ if ((err = iop_ringbell(&iopcap, loudness, pitch, duration))
+ != STD_OK)
+ {
+ FatalError("iop_ringbell failed (%s)\n", err_why(err));
+ }
+ }
+}
+
+void xf86SetKbdLeds(leds)
+int leds;
+{
+ errstat err;
+
+ if ((err = iop_setleds(&iopcap, (int)leds)) != STD_OK)
+ {
+ FatalError("iop_set_leds failed (%s)\n", err_why(err));
+ }
+}
+
+int xf86GetKbdLeds()
+{
+ int cur_leds;
+ errstat err;
+
+ err = iop_getleds(&iopcap, &cur_leds);
+ if (err != STD_OK)
+ {
+ FatalError("iop_get_leds failed (%s)\n", err_why(err));
+ }
+ return cur_leds;
+}
+
+#if NeedFunctionPrototypes
+void xf86SetKbdRepeat(char rad)
+#else
+void xf86SetKbdRepeat(rad)
+char rad;
+#endif
+{
+ return;
+}
+
+void xf86KbdInit()
+{
+ return;
+}
+
+int xf86KbdOn()
+{
+ return(-1);
+}
+
+int xf86KbdOff()
+{
+ return(-1);
+}
+
+/* Amoeba doesn't use this */
+void xf86KbdEvents()
+{
+ return;
+}
+
+void xf86SetMouseSpeed(mouse, old, new, cflag)
+MouseDevPtr mouse;
+int old;
+int new;
+unsigned cflag;
+{
+ return;
+}
+
+void xf86MouseInit(mouse)
+MouseDevPtr mouse;
+{
+ return;
+}
+
+/* Xserver/iopsvr mouse type translation table: */
+static int mtypes[] = {
+ IOP_MOUSE_MS, /* P_MS */
+ IOP_MOUSE_MM, /* P_MSC */
+ IOP_MOUSE_MMS, /* P_MM */
+ IOP_MOUSE_LOGI, /* P_LOGI */
+ IOP_MOUSE_LB, /* P_BM */
+ IOP_MOUSE_LOGIMAN, /* P_LOGIMAN */
+ IOP_MOUSE_PS2 /* P_PS2 */
+};
+
+int xf86MouseOn(mouse)
+MouseDevPtr mouse;
+{
+ int msetype;
+ errstat err;
+
+ msetype = mouse->mseType;
+ if (msetype >= 0 && msetype < (sizeof(mtypes) / sizeof(mtypes[0]))) {
+ /* translate */
+ msetype = mtypes[msetype];
+ }
+
+ if ((err = iop_mousecontrol(&iopcap, msetype, mouse->baudRate,
+ mouse->sampleRate)) != STD_OK)
+ {
+ if (xf86Info.allowMouseOpenFail) {
+ ErrorF("iop_mousecontrol failed (%s) - Continuing...\n",
+ err_why(err));
+ return(-2);
+ }
+ FatalError("iop_mousecontrol failed (%s)\n", err_why(err));
+ }
+ return(-1);
+}
+
+int xf86MouseOff(mouse, doclose)
+MouseDevPtr mouse;
+Bool doclose;
+{
+ return -1;
+}
+
+/* Amoeba doesn't use this */
+void xf86MouseEvents(device)
+DeviceIntPtr device;
+{
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/amoeba/am_video.c b/xc/programs/Xserver/hw/xfree86/os-support/amoeba/am_video.c
new file mode 100644
index 000000000..26254ad7f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/amoeba/am_video.c
@@ -0,0 +1,102 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/amoeba/am_video.c,v 3.1 1996/12/23 06:49:13 dawes Exp $ */
+/*
+ * Copyright 1993 by Vrije Universiteit, The Netherlands
+ * Copyright 1993 by David Wexelblat <dwex@XFree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of the Vrije Universiteit and David
+ * Wexelblat not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * The Vrije Universiteit and David Wexelblat make no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE VRIJE UNIVERSITEIT AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE VRIJE UNIVERSITEIT OR
+ * DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: am_video.c /main/3 1996/02/21 17:50:46 kaleb $ */
+
+#include "X.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+/***************************************************************************/
+/* Video Memory Mapping section */
+/***************************************************************************/
+
+/* ARGSUSED */
+pointer xf86MapVidMem(ScreenNum, Region, Base, Size)
+int ScreenNum;
+int Region;
+pointer Base;
+unsigned long Size;
+{
+ return((pointer)xf86Info.screenPtr);
+}
+
+/* ARGSUSED */
+void xf86UnMapVidMem(ScreenNum, Region, Base, Size)
+int ScreenNum;
+int Region;
+pointer Base;
+unsigned long Size;
+{
+ return;
+}
+
+Bool xf86LinearVidMem()
+{
+ return(FALSE);
+}
+
+/***************************************************************************/
+/* BIOS Reading section */
+/***************************************************************************/
+
+/*
+ * Amoeba does not support reading the BIOS
+ */
+
+/* ARGSUSED */
+int xf86ReadBIOS(Base, Offset, Buf, Len)
+unsigned long Base;
+unsigned long Offset;
+unsigned char *Buf;
+int Len;
+{
+ return(-1);
+}
+
+/***************************************************************************/
+/* Interrupt Handling section */
+/***************************************************************************/
+
+Bool xf86DisableInterrupts()
+{
+ extern void iop_intr_disable();
+
+ iop_intr_disable(&iopcap);
+ return(TRUE);
+}
+
+void xf86EnableInterrupts()
+{
+ extern void iop_intr_enable();
+
+ iop_intr_enable(&iopcap);
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/assyntax.h b/xc/programs/Xserver/hw/xfree86/os-support/assyntax.h
new file mode 100644
index 000000000..26554e0b1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/assyntax.h
@@ -0,0 +1,725 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/assyntax.h,v 3.11 1998/09/05 06:37:01 dawes Exp $ */
+#ifndef __ASSYNTAX_H__
+#define __ASSYNTAX_H__
+
+/*
+ * Copyright 1992 Vrije Universiteit, The Netherlands
+ *
+ * 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 the Vrije Universiteit not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The Vrije Universiteit makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * The Vrije Universiteit DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL The Vrije Universiteit 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.
+ */
+/* $XConsortium: assyntax.h /main/5 1996/02/21 17:50:49 kaleb $ */
+
+ /*
+ * assyntax.h
+ *
+ * Select the syntax appropriate to the 386 assembler being used
+ * To add support for more assemblers add more columns to the CHOICE
+ * macro. Note that register names must also have uppercase names
+ * to avoid macro recursion. e.g., #define ah %ah recurses!
+ *
+ * NB 1. Some of the macros for certain assemblers imply that the code is to
+ * run in protected mode!! Caveat emptor.
+ *
+ * NB 2. 486 specific instructions are not included. This is to discourage
+ * their accidental use in code that is intended to run on 386 and 486
+ * systems.
+ *
+ * Supported assemblers:
+ *
+ * (a) AT&T SysVr4 as(1): default
+ * (b) GNU Assembler gas: define USE_GAS or GNU_ASSEMBLER
+ * (c) Amsterdam Compiler kit: define ACK_ASSEMBLER
+ *
+ * The following naming conventions have been used to identify the various
+ * data types:
+ * _SR = segment register version
+ * Integer:
+ * _Q = quadword = 64 bits
+ * _L = long = 32 bits
+ * _W = short = 16 bits
+ * _B = byte = 8 bits
+ * Floating-point:
+ * _X = m80real = 80 bits
+ * _D = double = 64 bits
+ * _S = single = 32 bits
+ *
+ * Author: Gregory J. Sharp, Sept 1992
+ * Vrije Universiteit, Amsterdam, The Netherlands
+ */
+
+#if defined(USE_GAS) && !defined(GNU_ASSEMBLER)
+#define GNU_ASSEMBLER
+#endif
+
+#if (defined(__STDC__) && !defined(UNIXCPP)) || (defined (sun) && defined (i386) && defined (SVR4) && defined (__STDC__) && !defined (__GNUC__))
+#define CONCAT(x, y) x ## y
+#else
+#define CONCAT(x, y) x/**/y
+#endif
+
+#ifdef ACK_ASSEMBLER
+
+/* Assume we write code for 32-bit protected mode! */
+
+/* Redefine register names for GAS & AT&T assemblers */
+#define AL al
+#define AH ah
+#define AX ax
+#define EAX ax
+#define BL bl
+#define BH bh
+#define BX bx
+#define EBX bx
+#define CL cl
+#define CH ch
+#define CX cx
+#define ECX cx
+#define DL dl
+#define DH dh
+#define DX dx
+#define EDX dx
+#define BP bp
+#define EBP bp
+#define SI si
+#define ESI si
+#define DI di
+#define EDI di
+#define SP sp
+#define ESP sp
+#define CS cs
+#define SS ss
+#define DS ds
+#define ES es
+#define FS fs
+#define GS gs
+/* Control Registers */
+#define CR0 cr0
+#define CR1 cr1
+#define CR2 cr2
+#define CR3 cr3
+/* Debug Registers */
+#define DR0 dr0
+#define DR1 dr1
+#define DR2 dr2
+#define DR3 dr3
+#define DR4 dr4
+#define DR5 dr5
+#define DR6 dr6
+#define DR7 dr7
+/* Floating-point Stack */
+#define ST st
+
+#define AS_BEGIN .sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
+
+
+#define _WTOG o16 /* word toggle for _W instructions */
+#define _LTOG /* long toggle for _L instructions */
+#define ADDR_TOGGLE a16
+#define OPSZ_TOGGLE o16
+#define USE16 .use16
+#define USE32 .use32
+
+#define CHOICE(a,b,c) c
+
+#else /* AT&T or GAS */
+
+/* Redefine register names for GAS & AT&T assemblers */
+#define AL %al
+#define AH %ah
+#define AX %ax
+#define EAX %eax
+#define BL %bl
+#define BH %bh
+#define BX %bx
+#define EBX %ebx
+#define CL %cl
+#define CH %ch
+#define CX %cx
+#define ECX %ecx
+#define DL %dl
+#define DH %dh
+#define DX %dx
+#define EDX %edx
+#define BP %bp
+#define EBP %ebp
+#define SI %si
+#define ESI %esi
+#define DI %di
+#define EDI %edi
+#define SP %sp
+#define ESP %esp
+#define CS %cs
+#define SS %ss
+#define DS %ds
+#define ES %es
+#define FS %fs
+#define GS %gs
+/* Control Registers */
+#define CR0 %cr0
+#define CR1 %cr1
+#define CR2 %cr2
+#define CR3 %cr3
+/* Debug Registers */
+#define DR0 %db0
+#define DR1 %db1
+#define DR2 %db2
+#define DR3 %db3
+#define DR4 %db4
+#define DR5 %db5
+#define DR6 %db6
+#define DR7 %db7
+/* Floating-point Stack */
+#define ST %st
+
+#define AS_BEGIN
+#define USE16
+#define USE32
+
+#ifdef GNU_ASSEMBLER
+
+#define ADDR_TOGGLE aword
+#define OPSZ_TOGGLE word
+
+#define CHOICE(a,b,c) b
+
+#else
+/*
+ * AT&T ASSEMBLER SYNTAX
+ * *********************
+ */
+#define CHOICE(a,b,c) a
+
+#define ADDR_TOGGLE addr16
+#define OPSZ_TOGGLE data16
+
+#endif /* GNU_ASSEMBLER */
+#endif /* ACK_ASSEMBLER */
+
+
+#if defined(Lynx) || (defined(SYSV) || defined(SVR4)) && !defined(ACK_ASSEMBLER) || defined(__ELF__) || defined(__GNU__)
+#define GLNAME(a) a
+#else
+#define GLNAME(a) CONCAT(_,a)
+#endif
+
+
+ /****************************************/
+ /* */
+ /* Select the various choices */
+ /* */
+ /****************************************/
+
+
+/* Redefine assembler directives */
+/*********************************/
+#define GLOBL CHOICE(.globl, .globl, .extern)
+#define ALIGNTEXT4 CHOICE(.align 4, .align ARG2(2,0x90), .align 4)
+#define ALIGNTEXT2 CHOICE(.align 2, .align ARG2(1,0x90), .align 2)
+/* ALIGNTEXT4ifNOP is the same as ALIGNTEXT4, but only if the space is
+ * guaranteed to be filled with NOPs. Otherwise it does nothing.
+ */
+#define ALIGNTEXT4ifNOP CHOICE(.align 4, .align ARG2(2,0x90), /*can't do it*/)
+#define ALIGNDATA4 CHOICE(.align 4, .align ARG2(2,0x0), .align 4)
+#define ALIGNDATA2 CHOICE(.align 2, .align ARG2(1,0x0), .align 2)
+#define FILE(s) CHOICE(.file s, .file s, .file s)
+#define STRING(s) CHOICE(.string s, .asciz s, .asciz s)
+#define D_LONG CHOICE(.long, .long, .data4)
+#define D_WORD CHOICE(.value, .short, .data2)
+#define D_BYTE CHOICE(.byte, .byte, .data1)
+#define SPACE CHOICE(.comm, .space, .space)
+#define COMM CHOICE(.comm, .comm, .comm)
+#define SEG_DATA CHOICE(.data, .data, .sect .data)
+#define SEG_TEXT CHOICE(.text, .text, .sect .text)
+#define SEG_BSS CHOICE(.bss, .bss, .sect .bss)
+
+#ifdef GNU_ASSEMBLER
+#define D_SPACE(n) . = . + n
+#else
+#define D_SPACE(n) .space n
+#endif
+
+/* Addressing Modes */
+/* Immediate Mode */
+#define ADDR(a) CHOICE(CONCAT($,a), CONCAT($,a), a)
+#define CONST(a) CHOICE(CONCAT($,a), CONCAT($,a), a)
+
+/* Indirect Mode */
+#define CONTENT(a) CHOICE(a, a, (a)) /* take contents of variable */
+#define REGIND(a) CHOICE((a), (a), (a)) /* Register a indirect */
+/* Register b indirect plus displacement a */
+#define REGOFF(a, b) CHOICE(a(b), a(b), a(b))
+/* Reg indirect Base + Index + Displacement - this is mainly for 16-bit mode
+ * which has no scaling
+ */
+#define REGBID(b,i,d) CHOICE(d(b,i), d(b,i), d(b)(i))
+/* Reg indirect Base + (Index * Scale) + Displacement */
+#define REGBISD(b,i,s,d) CHOICE(d(b,i,s), d(b,i,s), d(b)(i*s))
+/* Displaced Scaled Index: */
+#define REGDIS(d,i,s) CHOICE(d(,i,s), d(,i,s), d(i * s))
+/* Indexed Base: */
+#define REGBI(b,i) CHOICE((b,i), (b,i), (b)(i))
+/* Displaced Base: */
+#define REGDB(d,b) CHOICE(d(b), d(b), d(b))
+/* Variable indirect: */
+#define VARINDIRECT(var) CHOICE(*var, *var, (var))
+/* Use register contents as jump/call target: */
+#define CODEPTR(reg) CHOICE(*reg, *reg, reg)
+
+/* For expressions requiring bracketing
+ * eg. (CRT0_PM | CRT_EM)
+ */
+
+#define EXPR(a) CHOICE([a], (a), [a])
+#define ENOT(a) CHOICE(0!a, ~a, ~a)
+#define EMUL(a,b) CHOICE(a\*b, a*b, a*b)
+#define EDIV(a,b) CHOICE(a\/b, a/b, a/b)
+
+/*
+ * We have to beat the problem of commas within arguments to choice.
+ * eg. choice (add a,b, add b,a) will get argument mismatch. Luckily ANSI
+ * and other known cpp definitions evaluate arguments before substitution
+ * so the following works.
+ */
+#define ARG2(a, b) a,b
+#define ARG3(a,b,c) a,b,c
+
+/* Redefine assembler commands */
+#define AAA CHOICE(aaa, aaa, aaa)
+#define AAD CHOICE(aad, aad, aad)
+#define AAM CHOICE(aam, aam, aam)
+#define AAS CHOICE(aas, aas, aas)
+#define ADC_L(a, b) CHOICE(adcl ARG2(a,b), adcl ARG2(a,b), _LTOG adc ARG2(b,a))
+#define ADC_W(a, b) CHOICE(adcw ARG2(a,b), adcw ARG2(a,b), _WTOG adc ARG2(b,a))
+#define ADC_B(a, b) CHOICE(adcb ARG2(a,b), adcb ARG2(a,b), adcb ARG2(b,a))
+#define ADD_L(a, b) CHOICE(addl ARG2(a,b), addl ARG2(a,b), _LTOG add ARG2(b,a))
+#define ADD_W(a, b) CHOICE(addw ARG2(a,b), addw ARG2(a,b), _WTOG add ARG2(b,a))
+#define ADD_B(a, b) CHOICE(addb ARG2(a,b), addb ARG2(a,b), addb ARG2(b,a))
+#define AND_L(a, b) CHOICE(andl ARG2(a,b), andl ARG2(a,b), _LTOG and ARG2(b,a))
+#define AND_W(a, b) CHOICE(andw ARG2(a,b), andw ARG2(a,b), _WTOG and ARG2(b,a))
+#define AND_B(a, b) CHOICE(andb ARG2(a,b), andb ARG2(a,b), andb ARG2(b,a))
+#define ARPL(a,b) CHOICE(arpl ARG2(a,b), arpl ARG2(a,b), arpl ARG2(b,a))
+#define BOUND_L(a, b) CHOICE(boundl ARG2(a,b), boundl ARG2(b,a), _LTOG bound ARG2(b,a))
+#define BOUND_W(a, b) CHOICE(boundw ARG2(a,b), boundw ARG2(b,a), _WTOG bound ARG2(b,a))
+#define BSF_L(a, b) CHOICE(bsfl ARG2(a,b), bsfl ARG2(a,b), _LTOG bsf ARG2(b,a))
+#define BSF_W(a, b) CHOICE(bsfw ARG2(a,b), bsfw ARG2(a,b), _WTOG bsf ARG2(b,a))
+#define BSR_L(a, b) CHOICE(bsrl ARG2(a,b), bsrl ARG2(a,b), _LTOG bsr ARG2(b,a))
+#define BSR_W(a, b) CHOICE(bsrw ARG2(a,b), bsrw ARG2(a,b), _WTOG bsr ARG2(b,a))
+#define BT_L(a, b) CHOICE(btl ARG2(a,b), btl ARG2(a,b), _LTOG bt ARG2(b,a))
+#define BT_W(a, b) CHOICE(btw ARG2(a,b), btw ARG2(a,b), _WTOG bt ARG2(b,a))
+#define BTC_L(a, b) CHOICE(btcl ARG2(a,b), btcl ARG2(a,b), _LTOG btc ARG2(b,a))
+#define BTC_W(a, b) CHOICE(btcw ARG2(a,b), btcw ARG2(a,b), _WTOG btc ARG2(b,a))
+#define BTR_L(a, b) CHOICE(btrl ARG2(a,b), btrl ARG2(a,b), _LTOG btr ARG2(b,a))
+#define BTR_W(a, b) CHOICE(btrw ARG2(a,b), btrw ARG2(a,b), _WTOG btr ARG2(b,a))
+#define BTS_L(a, b) CHOICE(btsl ARG2(a,b), btsl ARG2(a,b), _LTOG bts ARG2(b,a))
+#define BTS_W(a, b) CHOICE(btsw ARG2(a,b), btsw ARG2(a,b), _WTOG bts ARG2(b,a))
+#define CALL(a) CHOICE(call a, call a, call a)
+#define CALLF(s,a) CHOICE(lcall ARG2(s,a), lcall ARG2(s,a), callf s:a)
+#define CBW CHOICE(cbtw, cbw, cbw)
+#define CWDE CHOICE(cwtd, cwde, cwde)
+#define CLC CHOICE(clc, clc, clc)
+#define CLD CHOICE(cld, cld, cld)
+#define CLI CHOICE(cli, cli, cli)
+#define CLTS CHOICE(clts, clts, clts)
+#define CMC CHOICE(cmc, cmc, cmc)
+#define CMP_L(a, b) CHOICE(cmpl ARG2(a,b), cmpl ARG2(a,b), _LTOG cmp ARG2(b,a))
+#define CMP_W(a, b) CHOICE(cmpw ARG2(a,b), cmpw ARG2(a,b), _WTOG cmp ARG2(b,a))
+#define CMP_B(a, b) CHOICE(cmpb ARG2(a,b), cmpb ARG2(a,b), cmpb ARG2(b,a))
+#define CMPS_L CHOICE(cmpsl, cmpsl, _LTOG cmps)
+#define CMPS_W CHOICE(cmpsw, cmpsw, _WTOG cmps)
+#define CMPS_B CHOICE(cmpsb, cmpsb, cmpsb)
+#define CWD CHOICE(cwtl, cwd, cwd)
+#define CDQ CHOICE(cltd, cdq, cdq)
+#define DAA CHOICE(daa, daa, daa)
+#define DAS CHOICE(das, das, das)
+#define DEC_L(a) CHOICE(decl a, decl a, _LTOG dec a)
+#define DEC_W(a) CHOICE(decw a, decw a, _WTOG dec a)
+#define DEC_B(a) CHOICE(decb a, decb a, decb a)
+#define DIV_L(a) CHOICE(divl a, divl a, div a)
+#define DIV_W(a) CHOICE(divw a, divw a, div a)
+#define DIV_B(a) CHOICE(divb a, divb a, divb a)
+#define ENTER(a,b) CHOICE(enter ARG2(a,b), enter ARG2(a,b), enter ARG2(b,a))
+#define HLT CHOICE(hlt, hlt, hlt)
+#define IDIV_L(a) CHOICE(idivl a, idivl a, _LTOG idiv a)
+#define IDIV_W(a) CHOICE(idivw a, idivw a, _WTOG idiv a)
+#define IDIV_B(a) CHOICE(idivb a, idivb a, idivb a)
+/* More forms than this for imul!! */
+#define IMUL_L(a, b) CHOICE(imull ARG2(a,b), imull ARG2(a,b), _LTOG imul ARG2(b,a))
+#define IMUL_W(a, b) CHOICE(imulw ARG2(a,b), imulw ARG2(a,b), _WTOG imul ARG2(b,a))
+#define IMUL_B(a) CHOICE(imulb a, imulb a, imulb a)
+#define IN_L CHOICE(inl (DX), inl ARG2(DX,EAX), _LTOG in DX)
+#define IN_W CHOICE(inw (DX), inw ARG2(DX,AX), _WTOG in DX)
+#define IN_B CHOICE(inb (DX), inb ARG2(DX,AL), inb DX)
+/* Please AS code writer: use the following ONLY, if you refer to ports<256
+ * directly, but not in IN1_W(DX), for instance, even if IN1_ looks nicer
+ */
+#if defined (sun)
+#define IN1_L(a) CHOICE(inl (a), inl ARG2(a,EAX), _LTOG in a)
+#define IN1_W(a) CHOICE(inw (a), inw ARG2(a,AX), _WTOG in a)
+#define IN1_B(a) CHOICE(inb (a), inb ARG2(a,AL), inb a)
+#else
+#define IN1_L(a) CHOICE(inl a, inl ARG2(a,EAX), _LTOG in a)
+#define IN1_W(a) CHOICE(inw a, inw ARG2(a,AX), _WTOG in a)
+#define IN1_B(a) CHOICE(inb a, inb ARG2(a,AL), inb a)
+#endif
+#define INC_L(a) CHOICE(incl a, incl a, _LTOG inc a)
+#define INC_W(a) CHOICE(incw a, incw a, _WTOG inc a)
+#define INC_B(a) CHOICE(incb a, incb a, incb a)
+#define INS_L CHOICE(insl, insl, _LTOG ins)
+#define INS_W CHOICE(insw, insw, _WTOG ins)
+#define INS_B CHOICE(insb, insb, insb)
+#define INT(a) CHOICE(int a, int a, int a)
+#define INT3 CHOICE(int CONST(3), int3, int CONST(3))
+#define INTO CHOICE(into, into, into)
+#define IRET CHOICE(iret, iret, iret)
+#define IRETD CHOICE(iret, iret, iretd)
+#define JA(a) CHOICE(ja a, ja a, ja a)
+#define JAE(a) CHOICE(jae a, jae a, jae a)
+#define JB(a) CHOICE(jb a, jb a, jb a)
+#define JBE(a) CHOICE(jbe a, jbe a, jbe a)
+#define JC(a) CHOICE(jc a, jc a, jc a)
+#define JE(a) CHOICE(je a, je a, je a)
+#define JG(a) CHOICE(jg a, jg a, jg a)
+#define JGE(a) CHOICE(jge a, jge a, jge a)
+#define JL(a) CHOICE(jl a, jl a, jl a)
+#define JLE(a) CHOICE(jle a, jle a, jle a)
+#define JNA(a) CHOICE(jna a, jna a, jna a)
+#define JNAE(a) CHOICE(jnae a, jnae a, jnae a)
+#define JNB(a) CHOICE(jnb a, jnb a, jnb a)
+#define JNBE(a) CHOICE(jnbe a, jnbe a, jnbe a)
+#define JNC(a) CHOICE(jnc a, jnc a, jnc a)
+#define JNE(a) CHOICE(jne a, jne a, jne a)
+#define JNG(a) CHOICE(jng a, jng a, jng a)
+#define JNGE(a) CHOICE(jnge a, jnge a, jnge a)
+#define JNL(a) CHOICE(jnl a, jnl a, jnl a)
+#define JNLE(a) CHOICE(jnle a, jnle a, jnle a)
+#define JNO(a) CHOICE(jno a, jno a, jno a)
+#define JNP(a) CHOICE(jnp a, jnp a, jnp a)
+#define JNS(a) CHOICE(jns a, jns a, jns a)
+#define JNZ(a) CHOICE(jnz a, jnz a, jnz a)
+#define JO(a) CHOICE(jo a, jo a, jo a)
+#define JP(a) CHOICE(jp a, jp a, jp a)
+#define JPE(a) CHOICE(jpe a, jpe a, jpe a)
+#define JPO(a) CHOICE(jpo a, jpo a, jpo a)
+#define JS(a) CHOICE(js a, js a, js a)
+#define JZ(a) CHOICE(jz a, jz a, jz a)
+#define JMP(a) CHOICE(jmp a, jmp a, jmp a)
+#define JMPF(s,a) CHOICE(ljmp ARG2(s,a), ljmp ARG2(s,a), jmpf s:a)
+#define LAHF CHOICE(lahf, lahf, lahf)
+#if !defined(_REAL_MODE) && !defined(_V86_MODE)
+#define LAR(a, b) CHOICE(lar ARG2(a, b), lar ARG2(a, b), lar ARG2(b, a))
+#endif
+#define LEA_L(a, b) CHOICE(leal ARG2(a,b), leal ARG2(a,b), _LTOG lea ARG2(b,a))
+#define LEA_W(a, b) CHOICE(leaw ARG2(a,b), leaw ARG2(a,b), _WTOG lea ARG2(b,a))
+#define LEAVE CHOICE(leave, leave, leave)
+#define LGDT(a) CHOICE(lgdt a, lgdt a, lgdt a)
+#define LIDT(a) CHOICE(lidt a, lidt a, lidt a)
+#define LDS(a, b) CHOICE(ldsl ARG2(a,b), lds ARG2(a,b), lds ARG2(b,a))
+#define LES(a, b) CHOICE(lesl ARG2(a,b), les ARG2(a,b), les ARG2(b,a))
+#define LFS(a, b) CHOICE(lfsl ARG2(a,b), lfs ARG2(a,b), lfs ARG2(b,a))
+#define LGS(a, b) CHOICE(lgsl ARG2(a,b), lgs ARG2(a,b), lgs ARG2(b,a))
+#define LSS(a, b) CHOICE(lssl ARG2(a,b), lss ARG2(a,b), lss ARG2(b,a))
+#define LLDT(a) CHOICE(lldt a, lldt a, lldt a)
+#define LMSW(a) CHOICE(lmsw a, lmsw a, lmsw a)
+#define LOCK CHOICE(lock, lock, lock)
+#define LODS_L CHOICE(lodsl, lodsl, _LTOG lods)
+#define LODS_W CHOICE(lodsw, lodsw, _WTOG lods)
+#define LODS_B CHOICE(lodsb, lodsb, lodsb)
+#define LOOP(a) CHOICE(loop a, loop a, loop a)
+#define LOOPE(a) CHOICE(loope a, loope a, loope a)
+#define LOOPZ(a) CHOICE(loopz a, loopz a, loopz a)
+#define LOOPNE(a) CHOICE(loopne a, loopne a, loopne a)
+#define LOOPNZ(a) CHOICE(loopnz a, loopnz a, loopnz a)
+#if !defined(_REAL_MODE) && !defined(_V86_MODE)
+#define LSL(a, b) CHOICE(lsl ARG2(a,b), lsl ARG2(a,b), lsl ARG2(b,a))
+#endif
+#define LTR(a) CHOICE(ltr a, ltr a, ltr a)
+#define MOV_SR(a, b) CHOICE(movw ARG2(a,b), mov ARG2(a,b), mov ARG2(b,a))
+#define MOV_L(a, b) CHOICE(movl ARG2(a,b), movl ARG2(a,b), _LTOG mov ARG2(b,a))
+#define MOV_W(a, b) CHOICE(movw ARG2(a,b), movw ARG2(a,b), _WTOG mov ARG2(b,a))
+#define MOV_B(a, b) CHOICE(movb ARG2(a,b), movb ARG2(a,b), movb ARG2(b,a))
+#define MOVS_L CHOICE(movsl, movsl, _LTOG movs)
+#define MOVS_W CHOICE(movsw, movsw, _WTOG movs)
+#define MOVS_B CHOICE(movsb, movsb, movsb)
+#define MOVSX_BL(a, b) CHOICE(movsbl ARG2(a,b), movsbl ARG2(a,b), movsx ARG2(b,a))
+#define MOVSX_BW(a, b) CHOICE(movsbw ARG2(a,b), movsbw ARG2(a,b), movsx ARG2(b,a))
+#define MOVSX_WL(a, b) CHOICE(movswl ARG2(a,b), movswl ARG2(a,b), movsx ARG2(b,a))
+#define MOVZX_BL(a, b) CHOICE(movzbl ARG2(a,b), movzbl ARG2(a,b), movzx ARG2(b,a))
+#define MOVZX_BW(a, b) CHOICE(movzbw ARG2(a,b), movzbw ARG2(a,b), movzx ARG2(b,a))
+#define MOVZX_WL(a, b) CHOICE(movzwl ARG2(a,b), movzwl ARG2(a,b), movzx ARG2(b,a))
+#define MUL_L(a) CHOICE(mull a, mull a, _LTOG mul a)
+#define MUL_W(a) CHOICE(mulw a, mulw a, _WTOG mul a)
+#define MUL_B(a) CHOICE(mulb a, mulb a, mulb a)
+#define NEG_L(a) CHOICE(negl a, negl a, _LTOG neg a)
+#define NEG_W(a) CHOICE(negw a, negw a, _WTOG neg a)
+#define NEG_B(a) CHOICE(negb a, negb a, negb a)
+#define NOP CHOICE(nop, nop, nop)
+#define NOT_L(a) CHOICE(notl a, notl a, _LTOG not a)
+#define NOT_W(a) CHOICE(notw a, notw a, _WTOG not a)
+#define NOT_B(a) CHOICE(notb a, notb a, notb a)
+#define OR_L(a,b) CHOICE(orl ARG2(a,b), orl ARG2(a,b), _LTOG or ARG2(b,a))
+#define OR_W(a,b) CHOICE(orw ARG2(a,b), orw ARG2(a,b), _WTOG or ARG2(b,a))
+#define OR_B(a,b) CHOICE(orb ARG2(a,b), orb ARG2(a,b), orb ARG2(b,a))
+#define OUT_L CHOICE(outl (DX), outl ARG2(EAX,DX), _LTOG out DX)
+#define OUT_W CHOICE(outw (DX), outw ARG2(AX,DX), _WTOG out DX)
+#define OUT_B CHOICE(outb (DX), outb ARG2(AL,DX), outb DX)
+/* Please AS code writer: use the following ONLY, if you refer to ports<256
+ * directly, but not in OUT1_W(DX), for instance, even if OUT1_ looks nicer
+ */
+#define OUT1_L(a) CHOICE(outl (a), outl ARG2(EAX,a), _LTOG out a)
+#define OUT1_W(a) CHOICE(outw (a), outw ARG2(AX,a), _WTOG out a)
+#define OUT1_B(a) CHOICE(outb (a), outb ARG2(AL,a), outb a)
+#define OUTS_L CHOICE(outsl, outsl, _LTOG outs)
+#define OUTS_W CHOICE(outsw, outsw, _WTOG outs)
+#define OUTS_B CHOICE(outsb, outsb, outsb)
+#define POP_SR(a) CHOICE(pop a, pop a, pop a)
+#define POP_L(a) CHOICE(popl a, popl a, _LTOG pop a)
+#define POP_W(a) CHOICE(popw a, popw a, _WTOG pop a)
+#define POPA_L CHOICE(popal, popal, _LTOG popa)
+#define POPA_W CHOICE(popaw, popaw, _WTOG popa)
+#define POPF_L CHOICE(popfl, popfl, _LTOG popf)
+#define POPF_W CHOICE(popfw, popfw, _WTOG popf)
+#define PUSH_SR(a) CHOICE(push a, push a, push a)
+#define PUSH_L(a) CHOICE(pushl a, pushl a, _LTOG push a)
+#define PUSH_W(a) CHOICE(pushw a, pushw a, _WTOG push a)
+#define PUSH_B(a) CHOICE(push a, pushb a, push a)
+#define PUSHA_L CHOICE(pushal, pushal, _LTOG pusha)
+#define PUSHA_W CHOICE(pushaw, pushaw, _WTOG pusha)
+#define PUSHF_L CHOICE(pushfl, pushfl, _LTOG pushf)
+#define PUSHF_W CHOICE(pushfw, pushfw, _WTOG pushf)
+#define RCL_L(a, b) CHOICE(rcll ARG2(a,b), rcll ARG2(a,b), _LTOG rcl ARG2(b,a))
+#define RCL_W(a, b) CHOICE(rclw ARG2(a,b), rclw ARG2(a,b), _WTOG rcl ARG2(b,a))
+#define RCL_B(a, b) CHOICE(rclb ARG2(a,b), rclb ARG2(a,b), rclb ARG2(b,a))
+#define RCR_L(a, b) CHOICE(rcrl ARG2(a,b), rcrl ARG2(a,b), _LTOG rcr ARG2(b,a))
+#define RCR_W(a, b) CHOICE(rcrw ARG2(a,b), rcrw ARG2(a,b), _WTOG rcr ARG2(b,a))
+#define RCR_B(a, b) CHOICE(rcrb ARG2(a,b), rcrb ARG2(a,b), rcrb ARG2(b,a))
+#define ROL_L(a, b) CHOICE(roll ARG2(a,b), roll ARG2(a,b), _LTOG rol ARG2(b,a))
+#define ROL_W(a, b) CHOICE(rolw ARG2(a,b), rolw ARG2(a,b), _WTOG rol ARG2(b,a))
+#define ROL_B(a, b) CHOICE(rolb ARG2(a,b), rolb ARG2(a,b), rolb ARG2(b,a))
+#define ROR_L(a, b) CHOICE(rorl ARG2(a,b), rorl ARG2(a,b), _LTOG ror ARG2(b,a))
+#define ROR_W(a, b) CHOICE(rorw ARG2(a,b), rorw ARG2(a,b), _WTOG ror ARG2(b,a))
+#define ROR_B(a, b) CHOICE(rorb ARG2(a,b), rorb ARG2(a,b), rorb ARG2(b,a))
+#define REP CHOICE(rep ;, rep ;, repe)
+#define REPE CHOICE(repz ;, repe ;, repe)
+#define REPNE CHOICE(repnz ;, repne ;, repne)
+#define REPNZ REPNE
+#define REPZ REPE
+#define RET CHOICE(ret, ret, ret)
+#define SAHF CHOICE(sahf, sahf, sahf)
+#define SAL_L(a, b) CHOICE(sall ARG2(a,b), sall ARG2(a,b), _LTOG sal ARG2(b,a))
+#define SAL_W(a, b) CHOICE(salw ARG2(a,b), salw ARG2(a,b), _WTOG sal ARG2(b,a))
+#define SAL_B(a, b) CHOICE(salb ARG2(a,b), salb ARG2(a,b), salb ARG2(b,a))
+#define SAR_L(a, b) CHOICE(sarl ARG2(a,b), sarl ARG2(a,b), _LTOG sar ARG2(b,a))
+#define SAR_W(a, b) CHOICE(sarw ARG2(a,b), sarw ARG2(a,b), _WTOG sar ARG2(b,a))
+#define SAR_B(a, b) CHOICE(sarb ARG2(a,b), sarb ARG2(a,b), sarb ARG2(b,a))
+#define SBB_L(a, b) CHOICE(sbbl ARG2(a,b), sbbl ARG2(a,b), _LTOG sbb ARG2(b,a))
+#define SBB_W(a, b) CHOICE(sbbw ARG2(a,b), sbbw ARG2(a,b), _WTOG sbb ARG2(b,a))
+#define SBB_B(a, b) CHOICE(sbbb ARG2(a,b), sbbb ARG2(a,b), sbbb ARG2(b,a))
+#define SCAS_L CHOICE(scasl, scasl, _LTOG scas)
+#define SCAS_W CHOICE(scasw, scasw, _WTOG scas)
+#define SCAS_B CHOICE(scasb, scasb, scasb)
+#define SETA(a) CHOICE(seta a, seta a, seta a)
+#define SETAE(a) CHOICE(setae a, setae a, setae a)
+#define SETB(a) CHOICE(setb a, setb a, setb a)
+#define SETBE(a) CHOICE(setbe a, setbe a, setbe a)
+#define SETC(a) CHOICE(setc a, setb a, setb a)
+#define SETE(a) CHOICE(sete a, sete a, sete a)
+#define SETG(a) CHOICE(setg a, setg a, setg a)
+#define SETGE(a) CHOICE(setge a, setge a, setge a)
+#define SETL(a) CHOICE(setl a, setl a, setl a)
+#define SETLE(a) CHOICE(setle a, setle a, setle a)
+#define SETNA(a) CHOICE(setna a, setna a, setna a)
+#define SETNAE(a) CHOICE(setnae a, setnae a, setnae a)
+#define SETNB(a) CHOICE(setnb a, setnb a, setnb a)
+#define SETNBE(a) CHOICE(setnbe a, setnbe a, setnbe a)
+#define SETNC(a) CHOICE(setnc a, setnb a, setnb a)
+#define SETNE(a) CHOICE(setne a, setne a, setne a)
+#define SETNG(a) CHOICE(setng a, setng a, setng a)
+#define SETNGE(a) CHOICE(setnge a, setnge a, setnge a)
+#define SETNL(a) CHOICE(setnl a, setnl a, setnl a)
+#define SETNLE(a) CHOICE(setnle a, setnle a, setnle a)
+#define SETNO(a) CHOICE(setno a, setno a, setno a)
+#define SETNP(a) CHOICE(setnp a, setnp a, setnp a)
+#define SETNS(a) CHOICE(setns a, setns a, setna a)
+#define SETNZ(a) CHOICE(setnz a, setnz a, setnz a)
+#define SETO(a) CHOICE(seto a, seto a, seto a)
+#define SETP(a) CHOICE(setp a, setp a, setp a)
+#define SETPE(a) CHOICE(setpe a, setpe a, setpe a)
+#define SETPO(a) CHOICE(setpo a, setpo a, setpo a)
+#define SETS(a) CHOICE(sets a, sets a, seta a)
+#define SETZ(a) CHOICE(setz a, setz a, setz a)
+#define SGDT(a) CHOICE(sgdt a, sgdt a, sgdt a)
+#define SIDT(a) CHOICE(sidt a, sidt a, sidt a)
+#define SHL_L(a, b) CHOICE(shll ARG2(a,b), shll ARG2(a,b), _LTOG shl ARG2(b,a))
+#define SHL_W(a, b) CHOICE(shlw ARG2(a,b), shlw ARG2(a,b), _WTOG shl ARG2(b,a))
+#define SHL_B(a, b) CHOICE(shlb ARG2(a,b), shlb ARG2(a,b), shlb ARG2(b,a))
+#define SHLD_L(a,b,c) CHOICE(shldl ARG3(a,b,c), shldl ARG3(a,b,c), _LTOG shld ARG3(c,b,a))
+#define SHLD2_L(a,b) CHOICE(shldl ARG2(a,b), shldl ARG3(CL,a,b), _LTOG shld ARG3(b,a,CL))
+#define SHLD_W(a,b,c) CHOICE(shldw ARG3(a,b,c), shldw ARG3(a,b,c), _WTOG shld ARG3(c,b,a))
+#define SHLD2_W(a,b) CHOICE(shldw ARG2(a,b), shldw ARG3(CL,a,b), _WTOG shld ARG3(b,a,CL))
+#define SHR_L(a, b) CHOICE(shrl ARG2(a,b), shrl ARG2(a,b), _LTOG shr ARG2(b,a))
+#define SHR_W(a, b) CHOICE(shrw ARG2(a,b), shrw ARG2(a,b), _WTOG shr ARG2(b,a))
+#define SHR_B(a, b) CHOICE(shrb ARG2(a,b), shrb ARG2(a,b), shrb ARG2(b,a))
+#define SHRD_L(a,b,c) CHOICE(shrdl ARG3(a,b,c), shrdl ARG3(a,b,c), _LTOG shrd ARG3(c,b,a))
+#define SHRD2_L(a,b) CHOICE(shrdl ARG2(a,b), shrdl ARG3(CL,a,b), _LTOG shrd ARG3(b,a,CL))
+#define SHRD_W(a,b,c) CHOICE(shrdw ARG3(a,b,c), shrdw ARG3(a,b,c), _WTOG shrd ARG3(c,b,a))
+#define SHRD2_W(a,b) CHOICE(shrdw ARG2(a,b), shrdw ARG3(CL,a,b), _WTOG shrd ARG3(b,a,CL))
+#define SLDT(a) CHOICE(sldt a, sldt a, sldt a)
+#define SMSW(a) CHOICE(smsw a, smsw a, smsw a)
+#define STC CHOICE(stc, stc, stc)
+#define STD CHOICE(std, std, std)
+#define STI CHOICE(sti, sti, sti)
+#define STOS_L CHOICE(stosl, stosl, _LTOG stos)
+#define STOS_W CHOICE(stosw, stosw, _WTOG stos)
+#define STOS_B CHOICE(stosb, stosb, stosb)
+#define STR(a) CHOICE(str a, str a, str a)
+#define SUB_L(a, b) CHOICE(subl ARG2(a,b), subl ARG2(a,b), _LTOG sub ARG2(b,a))
+#define SUB_W(a, b) CHOICE(subw ARG2(a,b), subw ARG2(a,b), _WTOG sub ARG2(b,a))
+#define SUB_B(a, b) CHOICE(subb ARG2(a,b), subb ARG2(a,b), subb ARG2(b,a))
+#define TEST_L(a, b) CHOICE(testl ARG2(a,b), testl ARG2(a,b), _LTOG test ARG2(b,a))
+#define TEST_W(a, b) CHOICE(testw ARG2(a,b), testw ARG2(a,b), _WTOG test ARG2(b,a))
+#define TEST_B(a, b) CHOICE(testb ARG2(a,b), testb ARG2(a,b), testb ARG2(b,a))
+#define VERR(a) CHOICE(verr a, verr a, verr a)
+#define VERW(a) CHOICE(verw a, verw a, verw a)
+#define WAIT CHOICE(wait, wait, wait)
+#define XCHG_L(a, b) CHOICE(xchgl ARG2(a,b), xchgl ARG2(a,b), _LTOG xchg ARG2(b,a))
+#define XCHG_W(a, b) CHOICE(xchgw ARG2(a,b), xchgw ARG2(a,b), _WTOG xchg ARG2(b,a))
+#define XCHG_B(a, b) CHOICE(xchgb ARG2(a,b), xchgb ARG2(a,b), xchgb ARG2(b,a))
+#define XLAT CHOICE(xlat, xlat, xlat)
+#define XOR_L(a, b) CHOICE(xorl ARG2(a,b), xorl ARG2(a,b), _LTOG xor ARG2(b,a))
+#define XOR_W(a, b) CHOICE(xorw ARG2(a,b), xorw ARG2(a,b), _WTOG xor ARG2(b,a))
+#define XOR_B(a, b) CHOICE(xorb ARG2(a,b), xorb ARG2(a,b), xorb ARG2(b,a))
+
+
+/* Floating Point Instructions */
+#define F2XM1 CHOICE(f2xm1, f2xm1, f2xm1)
+#define FABS CHOICE(fabs, fabs, fabs)
+#define FADD_D(a) CHOICE(faddl a, faddl a, faddd a)
+#define FADD_S(a) CHOICE(fadds a, fadds a, fadds a)
+#define FADD2(a, b) CHOICE(fadd ARG2(a,b), fadd ARG2(a,b), fadd ARG2(b,a))
+#define FADDP(a, b) CHOICE(faddp ARG2(a,b), faddp ARG2(a,b), faddp ARG2(b,a))
+#define FIADD_L(a) CHOICE(fiaddl a, fiaddl a, fiaddl a)
+#define FIADD_W(a) CHOICE(fiadd a, fiadds a, fiadds a)
+#define FBLD(a) CHOICE(fbld a, fbld a, fbld a)
+#define FBSTP(a) CHOICE(fbstp a, fbstp a, fbstp a)
+#define FCHS CHOICE(fchs, fchs, fchs)
+#define FCLEX CHOICE(fclex, wait; fnclex, wait; fclex)
+#define FNCLEX CHOICE(fnclex, fnclex, fclex)
+#define FCOM(a) CHOICE(fcom a, fcom a, fcom a)
+#define FCOM_D(a) CHOICE(fcoml a, fcoml a, fcomd a)
+#define FCOM_S(a) CHOICE(fcoms a, fcoms a, fcoms a)
+#define FCOMP(a) CHOICE(fcomp a, fcomp a, fcomp a)
+#define FCOMP_D(a) CHOICE(fcompl a, fcompl a, fcompd a)
+#define FCOMP_S(a) CHOICE(fcomps a, fcomps a, fcomps a)
+#define FCOMPP CHOICE(fcompp, fcompp, fcompp)
+#define FCOS CHOICE(fcos, fcos, fcos)
+#define FDECSTP CHOICE(fdecstp, fdecstp, fdecstp)
+#define FDIV_D(a) CHOICE(fdivl a, fdivl a, fdivd a)
+#define FDIV_S(a) CHOICE(fdivs a, fdivs a, fdivs a)
+#define FDIV2(a, b) CHOICE(fdiv ARG2(a,b), fdiv ARG2(a,b), fdiv ARG2(b,a))
+#define FDIVP(a, b) CHOICE(fdivp ARG2(a,b), fdivp ARG2(a,b), fdivp ARG2(b,a))
+#define FIDIV_L(a) CHOICE(fidivl a, fidivl a, fidivl a)
+#define FIDIV_W(a) CHOICE(fidiv a, fidivs a, fidivs a)
+#define FDIVR_D(a) CHOICE(fdivrl a, fdivrl a, fdivrd a)
+#define FDIVR_S(a) CHOICE(fdivrs a, fdivrs a, fdivrs a)
+#define FDIVR2(a, b) CHOICE(fdivr ARG2(a,b), fdivr ARG2(a,b), fdivr ARG2(b,a))
+#define FDIVRP(a, b) CHOICE(fdivrp ARG2(a,b), fdivrp ARG2(a,b), fdivrp ARG2(b,a))
+#define FIDIVR_L(a) CHOICE(fidivrl a, fidivrl a, fidivrl a)
+#define FIDIVR_W(a) CHOICE(fidivr a, fidivrs a, fidivrs a)
+#define FFREE(a) CHOICE(ffree a, ffree a, ffree a)
+#define FICOM_L(a) CHOICE(ficoml a, ficoml a, ficoml a)
+#define FICOM_W(a) CHOICE(ficom a, ficoms a, ficoms a)
+#define FICOMP_L(a) CHOICE(ficompl a, ficompl a, ficompl a)
+#define FICOMP_W(a) CHOICE(ficomp a, ficomps a, ficomps a)
+#define FILD_Q(a) CHOICE(fildll a, fildq a, fildq a)
+#define FILD_L(a) CHOICE(fildl a, fildl a, fildl a)
+#define FILD_W(a) CHOICE(fild a, filds a, filds a)
+#define FINCSTP CHOICE(fincstp, fincstp, fincstp)
+#define FINIT CHOICE(finit, wait; fninit, wait; finit)
+#define FNINIT CHOICE(fninit, fninit, finit)
+#define FIST_L(a) CHOICE(fistl a, fistl a, fistl a)
+#define FIST_W(a) CHOICE(fist a, fists a, fists a)
+#define FISTP_Q(a) CHOICE(fistpll a, fistpq a, fistpq a)
+#define FISTP_L(a) CHOICE(fistpl a, fistpl a, fistpl a)
+#define FISTP_W(a) CHOICE(fistp a, fistps a, fistps a)
+#define FLD_X(a) CHOICE(fldt a, fldt a, fldx a) /* 80 bit data type! */
+#define FLD_D(a) CHOICE(fldl a, fldl a, fldd a)
+#define FLD_S(a) CHOICE(flds a, flds a, flds a)
+#define FLD1 CHOICE(fld1, fld1, fld1)
+#define FLDL2T CHOICE(fldl2t, fldl2t, fldl2t)
+#define FLDL2E CHOICE(fldl2e, fldl2e, fldl2e)
+#define FLDPI CHOICE(fldpi, fldpi, fldpi)
+#define FLDLG2 CHOICE(fldlg2, fldlg2, fldlg2)
+#define FLDLN2 CHOICE(fldln2, fldln2, fldln2)
+#define FLDZ CHOICE(fldz, fldz, fldz)
+#define FLDCW(a) CHOICE(fldcw a, fldcw a, fldcw a)
+#define FLDENV(a) CHOICE(fldenv a, fldenv a, fldenv a)
+#define FMUL_S(a) CHOICE(fmuls a, fmuls a, fmuls a)
+#define FMUL_D(a) CHOICE(fmull a, fmull a, fmuld a)
+#define FMUL2(a, b) CHOICE(fmul ARG2(a,b), fmul ARG2(a,b), fmul ARG2(b,a))
+#define FMULP(a, b) CHOICE(fmulp ARG2(a,b), fmulp ARG2(a,b), fmulp ARG2(b,a))
+#define FIMUL_L(a) CHOICE(fimull a, fimull a, fimull a)
+#define FIMUL_W(a) CHOICE(fimul a, fimuls a, fimuls a)
+#define FNOP CHOICE(fnop, fnop, fnop)
+#define FPATAN CHOICE(fpatan, fpatan, fpatan)
+#define FPREM CHOICE(fprem, fprem, fprem)
+#define FPREM1 CHOICE(fprem1, fprem1, fprem1)
+#define FPTAN CHOICE(fptan, fptan, fptan)
+#define FRNDINT CHOICE(frndint, frndint, frndint)
+#define FRSTOR(a) CHOICE(frstor a, frstor a, frstor a)
+#define FSAVE(a) CHOICE(fsave a, wait; fnsave a, wait; fsave a)
+#define FNSAVE(a) CHOICE(fnsave a, fnsave a, fsave a)
+#define FSCALE CHOICE(fscale, fscale, fscale)
+#define FSIN CHOICE(fsin, fsin, fsin)
+#define FSINCOS CHOICE(fsincos, fsincos, fsincos)
+#define FSQRT CHOICE(fsqrt, fsqrt, fsqrt)
+#define FST_D(a) CHOICE(fstl a, fstl a, fstd a)
+#define FST_S(a) CHOICE(fsts a, fsts a, fsts a)
+#define FSTP_X(a) CHOICE(fstpt a, fstpt a, fstpx a)
+#define FSTP_D(a) CHOICE(fstpl a, fstpl a, fstpd a)
+#define FSTP_S(a) CHOICE(fstps a, fstps a, fstps a)
+#define FSTCW(a) CHOICE(fstcw a, wait; fnstcw a, wait; fstcw a)
+#define FNSTCW(a) CHOICE(fnstcw a, fnstcw a, fstcw a)
+#define FSTENV(a) CHOICE(fstenv a, wait; fnstenv a, fstenv a)
+#define FNSTENV(a) CHOICE(fnstenv a, fnstenv a, fstenv a)
+#define FSTSW(a) CHOICE(fstsw a, wait; fnstsw a, wait; fstsw a)
+#define FNSTSW(a) CHOICE(fnstsw a, fnstsw a, fstsw a)
+#define FSUB_S(a) CHOICE(fsubs a, fsubs a, fsubs a)
+#define FSUB_D(a) CHOICE(fsubl a, fsubl a, fsubd a)
+#define FSUB2(a, b) CHOICE(fsub ARG2(a,b), fsub ARG2(a,b), fsub ARG2(b,a))
+#define FSUBP(a, b) CHOICE(fsubp ARG2(a,b), fsubp ARG2(a,b), fsubp ARG2(b,a))
+#define FISUB_L(a) CHOICE(fisubl a, fisubl a, fisubl a)
+#define FISUB_W(a) CHOICE(fisub a, fisubs a, fisubs a)
+#define FSUBR_S(a) CHOICE(fsubrs a, fsubrs a, fsubrs a)
+#define FSUBR_D(a) CHOICE(fsubrl a, fsubrl a, fsubrd a)
+#define FSUBR2(a, b) CHOICE(fsubr ARG2(a,b), fsubr ARG2(a,b), fsubr ARG2(b,a))
+#define FSUBRP(a, b) CHOICE(fsubrp ARG2(a,b), fsubrp ARG2(a,b), fsubrp ARG2(b,a))
+#define FISUBR_L(a) CHOICE(fisubrl a, fisubrl a, fisubrl a)
+#define FISUBR_W(a) CHOICE(fisubr a, fisubrs a, fisubrs a)
+#define FTST CHOICE(ftst, ftst, ftst)
+#define FUCOM(a) CHOICE(fucom a, fucom a, fucom a)
+#define FUCOMP(a) CHOICE(fucomp a, fucomp a, fucomp a)
+#define FUCOMPP CHOICE(fucompp, fucompp, fucompp)
+#define FWAIT CHOICE(wait, wait, wait)
+#define FXAM CHOICE(fxam, fxam, fxam)
+#define FXCH(a) CHOICE(fxch a, fxch a, fxch a)
+#define FXTRACT CHOICE(fxtract, fxtract, fxtract)
+#define FYL2X CHOICE(fyl2x, fyl2x, fyl2x)
+#define FYL2XP1 CHOICE(fyl2xp1, fyl2xp1, fyl2xp1)
+
+#endif /* __ASSYNTAX_H__ */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/bsd/Imakefile
new file mode 100644
index 000000000..76b4260ae
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/Imakefile
@@ -0,0 +1,104 @@
+XCOMM $XConsortium: Imakefile /main/12 1996/10/27 11:06:35 kaleb $
+
+
+
+
+
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/Imakefile,v 3.30 1999/08/22 11:59:50 dawes Exp $
+
+#include <Server.tmpl>
+
+#if defined(FreeBSDArchitecture) || defined(NetBSDArchitecture) || defined(OpenBSDArchitecture)
+#if BuildXInputExt
+# if JoystickSupport
+ JOYSTICK_SRC = bsd_jstk.c
+# endif
+# if DoLoadableServer
+SHARED_CFLAGS = PositionIndependentCFlags
+# else
+# if JoystickSupport
+ JOYSTICK_OBJ = bsd_jstk.o
+# endif
+# endif
+#endif
+#endif
+
+#if defined(OpenBSDArchitecture) || defined(NetBSDArchitecture) \
+ && ((OSMajorVersion == 1 && OSMinorVersion >= 1) || OSMajorVersion >= 2)
+# if defined(ArcArchitecture)
+ IOPERMDEFINES = -DUSE_ARC_MMAP
+# elif defined(Arm32Architecture)
+ IOPERMDEFINES = -DUSE_ARM32_MMAP
+# else
+ IOPERMDEFINES = -DUSE_I386_IOPL
+# endif
+#elif defined(FreeBSDArchitecture)
+ IOPERMDEFINES = -DUSE_DEV_IO
+#else
+IOPERM_SRC = ioperm_noop.c
+IOPERM_OBJ = ioperm_noop.o
+#endif
+
+#if NewInput
+MOUSESRC = bsd_mouse.c
+MOUSEOBJ = bsd_mouse.o
+#else
+MOUSESRC = std_mouse.c std_mseEv.c
+MOUSEOBJ = std_mouse.o std_mseEv.o
+#endif
+
+#if HasMTRRSupport
+MTRRDEFINES = -DHAS_MTRR_SUPPORT
+#endif
+
+SRCS = bsd_init.c bsd_video.c bsd_io.c bsd_VTsw.c \
+ libc_wrapper.c $(IOPERM_SRC) std_kbdEv.c posix_tty.c $(MOUSESRC) \
+ stdResource.c vidmem.c $(JOYSTICK_SRC)
+
+OBJS = bsd_init.o bsd_video.o bsd_io.o bsd_VTsw.o \
+ libc_wrapper.o $(IOPERM_OBJ) std_kbdEv.o posix_tty.o $(MOUSEOBJ) \
+ stdResource.o vidmem.o $(JOYSTICK_OBJ)
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC) -I$(EXTINCSRC) -I$(SERVERSRC)/mi
+
+CONSDEFINES = XFree86ConsoleDefines
+RESDEFINES = -DUSESTDRES
+
+#if HasNetBSDApertureDriver
+APDEFINES = -DHAS_APERTURE_DRV
+#endif
+
+DEFINES = $(CONSDEFINES) $(APDEFINES) $(IOPERMDEFINES) $(RESDEFINES) \
+ $(MTRRDEFINES)
+
+SubdirLibraryRule($(OBJS))
+NormalLibraryObjectRule()
+
+#if BuildXInputExt
+# if DoLoadableServer
+# if JoystickSupport
+AllTarget(bsd_jstk.o)
+#if 0
+InstallDynamicModule(bsd_jstk.o,$(MODULEDIR))
+#endif
+# endif
+# endif
+#endif
+
+LinkSourceFile(ioperm_noop.c,../shared)
+LinkSourceFile(std_kbdEv.c,../shared)
+LinkSourceFile(posix_tty.c,../shared)
+#if !NewInput
+LinkSourceFile(std_mouse.c,../shared)
+LinkSourceFile(std_mseEv.c,../shared)
+#endif
+LinkSourceFile(libc_wrapper.c,../shared)
+LinkSourceFile(stdResource.c,../shared)
+LinkSourceFile(vidmem.c,../shared)
+
+DependTarget()
+
+#if 0
+InstallDriverSDKDynamicModule(bsd_jstk.o,$(DRIVERSDKMODULEDIR))
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_VTsw.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_VTsw.c
new file mode 100644
index 000000000..adb101dc5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_VTsw.c
@@ -0,0 +1,92 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_VTsw.c,v 3.6 1998/07/25 16:56:33 dawes Exp $ */
+/*
+ * Derived from VTsw_usl.c which is
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ * by S_ren Schmidt (sos@login.dkuug.dk)
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of David Wexelblat not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Wexelblat makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: bsd_VTsw.c /main/4 1996/02/21 17:50:57 kaleb $ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+/*
+ * Handle the VT-switching interface for OSs that use USL-style ioctl()s
+ * (the bsd, sysv, sco, and linux subdirs).
+ */
+
+/*
+ * This function is the signal handler for the VT-switching signal. It
+ * is only referenced inside the OS-support layer.
+ */
+void
+xf86VTRequest(int sig)
+{
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ if (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT) {
+ xf86Info.vtRequestsPending = TRUE;
+ }
+#endif
+ return;
+}
+
+Bool
+xf86VTSwitchPending()
+{
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ if (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT) {
+ return(xf86Info.vtRequestsPending ? TRUE : FALSE);
+ }
+#endif
+ return FALSE;
+}
+
+Bool
+xf86VTSwitchAway()
+{
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ if (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT) {
+ xf86Info.vtRequestsPending = FALSE;
+ if (ioctl(xf86Info.consoleFd, VT_RELDISP, 1) < 0)
+ return(FALSE);
+ else
+ return(TRUE);
+ }
+#endif
+ return FALSE;
+}
+
+Bool
+xf86VTSwitchTo()
+{
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ if (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT) {
+ xf86Info.vtRequestsPending = FALSE;
+ if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ) < 0)
+ return(FALSE);
+ else
+ return(TRUE);
+ }
+#endif
+ return(TRUE);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_init.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_init.c
new file mode 100644
index 000000000..f2d289367
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_init.c
@@ -0,0 +1,642 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_init.c,v 3.13 1999/04/28 05:36:16 dawes Exp $ */
+/*
+ * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Rich Murphey and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Rich Murphey and
+ * David Wexelblat make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RICH MURPHEY OR DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: bsd_init.c /main/8 1996/10/23 13:13:05 kaleb $ */
+
+#include "X.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+static Bool KeepTty = FALSE;
+static int devConsoleFd = -1;
+static int VTnum = -1;
+static int initialVT = -1;
+
+#ifdef PCCONS_SUPPORT
+/* Stock 0.1 386bsd pccons console driver interface */
+#ifndef __OpenBSD__
+# define PCCONS_CONSOLE_DEV1 "/dev/ttyv0"
+#else
+# define PCCONS_CONSOLE_DEV1 "/dev/ttyC0"
+#endif
+#define PCCONS_CONSOLE_DEV2 "/dev/vga"
+#define PCCONS_CONSOLE_MODE O_RDWR|O_NDELAY
+#endif
+
+#ifdef SYSCONS_SUPPORT
+/* The FreeBSD 1.1 version syscons driver uses /dev/ttyv0 */
+#define SYSCONS_CONSOLE_DEV1 "/dev/ttyv0"
+#define SYSCONS_CONSOLE_DEV2 "/dev/vga"
+#define SYSCONS_CONSOLE_MODE O_RDWR|O_NDELAY
+#endif
+
+#ifdef PCVT_SUPPORT
+/* Hellmuth Michaelis' pcvt driver */
+#ifndef __OpenBSD__
+# define PCVT_CONSOLE_DEV "/dev/ttyv0"
+#else
+# define PCVT_CONSOLE_DEV "/dev/ttyC0"
+#endif
+#define PCVT_CONSOLE_MODE O_RDWR|O_NDELAY
+#endif
+
+#ifdef WSCONS_SUPPORT
+/* NetBSD's new console driver */
+#define WSCONS_PCVT_COMPAT_CONSOLE_DEV "/dev/ttyE0"
+#endif
+
+#define CHECK_DRIVER_MSG \
+ "Check your kernel's console driver configuration and /dev entries"
+
+static char *supported_drivers[] = {
+#ifdef PCCONS_SUPPORT
+ "pccons (with X support)",
+#endif
+#ifdef SYSCONS_SUPPORT
+ "syscons",
+#endif
+#ifdef PCVT_SUPPORT
+ "pcvt",
+#endif
+};
+
+
+/*
+ * Functions to probe for the existance of a supported console driver.
+ * Any function returns either a valid file descriptor (driver probed
+ * succesfully), -1 (driver not found), or uses FatalError() if the
+ * driver was found but proved to not support the required mode to run
+ * an X server.
+ */
+
+typedef int (*xf86ConsOpen_t)(void);
+
+#ifdef PCCONS_SUPPORT
+static int xf86OpenPccons(void);
+#endif /* PCCONS_SUPPORT */
+
+#ifdef SYSCONS_SUPPORT
+static int xf86OpenSyscons(void);
+#endif /* SYSCONS_SUPPORT */
+
+#ifdef PCVT_SUPPORT
+static int xf86OpenPcvt(void);
+#endif /* PCVT_SUPPORT */
+
+/*
+ * The sequence of the driver probes is important; start with the
+ * driver that is best distinguishable, and end with the most generic
+ * driver. (Otherwise, pcvt would also probe as syscons, and either
+ * pcvt or syscons might succesfully probe as pccons.)
+ */
+static xf86ConsOpen_t xf86ConsTab[] = {
+#ifdef PCVT_SUPPORT
+ xf86OpenPcvt,
+#endif
+#ifdef SYSCONS_SUPPORT
+ xf86OpenSyscons,
+#endif
+#ifdef PCCONS_SUPPORT
+ xf86OpenPccons,
+#endif
+ (xf86ConsOpen_t)NULL
+};
+
+
+void
+xf86OpenConsole()
+{
+ int i, fd = -1;
+ xf86ConsOpen_t *driver;
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ vtmode_t vtmode;
+#endif
+
+ if (serverGeneration == 1)
+ {
+ /* check if we are run with euid==0 */
+ if (geteuid() != 0)
+ {
+ FatalError("xf86OpenConsole: Server must be suid root\n");
+ }
+
+ if (!KeepTty)
+ {
+ /*
+ * detaching the controlling tty solves problems of kbd character
+ * loss. This is not interesting for CO driver, because it is
+ * exclusive.
+ */
+ setpgrp(0, getpid());
+ if ((i = open("/dev/tty",O_RDWR)) >= 0)
+ {
+ ioctl(i,TIOCNOTTY,(char *)0);
+ close(i);
+ }
+ }
+
+ /* detect which driver we are running on */
+ for (driver = xf86ConsTab; *driver; driver++)
+ {
+ if ((fd = (*driver)()) >= 0)
+ break;
+ }
+
+ /* Check that a supported console driver was found */
+ if (fd < 0)
+ {
+ char cons_drivers[80] = {0, };
+ for (i = 0; i < sizeof(supported_drivers) / sizeof(char *); i++)
+ {
+ if (i)
+ {
+ strcat(cons_drivers, ", ");
+ }
+ strcat(cons_drivers, supported_drivers[i]);
+ }
+ FatalError(
+ "%s: No console driver found\n\tSupported drivers: %s\n\t%s\n",
+ "xf86OpenConsole", cons_drivers, CHECK_DRIVER_MSG);
+ }
+#if 0 /* stdin is already closed in OsInit() */
+ fclose(stdin);
+#endif
+ xf86Info.consoleFd = fd;
+ xf86Info.screenFd = fd;
+
+ switch (xf86Info.consType)
+ {
+#ifdef PCCONS_SUPPORT
+ case PCCONS:
+ if (ioctl (xf86Info.consoleFd, CONSOLE_X_MODE_ON, 0) < 0)
+ {
+ FatalError("%s: CONSOLE_X_MODE_ON failed (%s)\n%s\n",
+ "xf86OpenConsole", strerror(errno),
+ CHECK_DRIVER_MSG);
+ }
+ /*
+ * Hack to prevent keyboard hanging when syslogd closes
+ * /dev/console
+ */
+ if ((devConsoleFd = open("/dev/console", O_WRONLY,0)) < 0)
+ {
+ xf86Msg(X_WARNING,
+ "xf86OpenConsole: couldn't open /dev/console (%s)\n",
+ strerror(errno));
+ }
+ break;
+#endif
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ case SYSCONS:
+ case PCVT:
+ /*
+ * First activate the #1 VT. This is a hack to allow a server
+ * to be started while another one is active. There should be
+ * a better way.
+ */
+ if (initialVT != 1) {
+
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, 1) != 0)
+ {
+ xf86Msg(X_WARNING,
+ "xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+ sleep(1);
+ }
+
+ /*
+ * now get the VT
+ */
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
+ }
+
+ signal(SIGUSR1, xf86VTRequest);
+
+ vtmode.mode = VT_PROCESS;
+ vtmode.relsig = SIGUSR1;
+ vtmode.acqsig = SIGUSR1;
+ vtmode.frsig = SIGUSR1;
+ if (ioctl(xf86Info.consoleFd, VT_SETMODE, &vtmode) < 0)
+ {
+ FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n");
+ }
+#if !defined(USE_DEV_IO) && !defined(USE_I386_IOPL)
+ if (ioctl(xf86Info.consoleFd, KDENABIO, 0) < 0)
+ {
+ FatalError("xf86OpenConsole: KDENABIO failed (%s)\n",
+ strerror(errno));
+ }
+#endif
+ if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0)
+ {
+ FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed\n");
+ }
+ break;
+#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */
+ }
+ }
+ else
+ {
+ /* serverGeneration != 1 */
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ if (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT)
+ {
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+ }
+#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */
+ }
+ return;
+}
+
+
+#ifdef PCCONS_SUPPORT
+
+static int
+xf86OpenPccons()
+{
+ int fd = -1;
+
+ if ((fd = open(PCCONS_CONSOLE_DEV1, PCCONS_CONSOLE_MODE, 0))
+ >= 0 ||
+ (fd = open(PCCONS_CONSOLE_DEV2, PCCONS_CONSOLE_MODE, 0))
+ >= 0)
+ {
+ if (ioctl(fd, CONSOLE_X_MODE_OFF, 0) < 0)
+ {
+ FatalError(
+ "%s: CONSOLE_X_MODE_OFF failed (%s)\n%s\n%s\n",
+ "xf86OpenPccons",
+ strerror(errno),
+ "Was expecting pccons driver with X support",
+ CHECK_DRIVER_MSG);
+ }
+ xf86Info.consType = PCCONS;
+ xf86Msg(X_PROBED, "Using pccons driver with X support\n");
+ }
+ return fd;
+}
+
+#endif /* PCCONS_SUPPORT */
+
+#ifdef SYSCONS_SUPPORT
+
+static int
+xf86OpenSyscons()
+{
+ int fd = -1;
+ vtmode_t vtmode;
+ char vtname[12];
+ struct stat status;
+ long syscons_version;
+ MessageType from;
+
+ /* Check for syscons */
+ if ((fd = open(SYSCONS_CONSOLE_DEV1, SYSCONS_CONSOLE_MODE, 0)) >= 0
+ || (fd = open(SYSCONS_CONSOLE_DEV2, SYSCONS_CONSOLE_MODE, 0)) >= 0)
+ {
+ if (ioctl(fd, VT_GETMODE, &vtmode) >= 0)
+ {
+ /* Get syscons version */
+ if (ioctl(fd, CONS_GETVERS, &syscons_version) < 0)
+ {
+ syscons_version = 0;
+ }
+
+ xf86Info.vtno = VTnum;
+ from = X_CMDLINE;
+
+#ifdef VT_GETACTIVE
+ if (ioctl(fd, VT_GETACTIVE, &initialVT) < 0)
+ initialVT = -1;
+#endif
+ if (xf86Info.vtno == -1)
+ {
+ /*
+ * For old syscons versions (<0x100), VT_OPENQRY returns
+ * the current VT rather than the next free VT. In this
+ * case, the server gets started on the current VT instead
+ * of the next free VT.
+ */
+
+#if 0
+ /* check for the fixed VT_OPENQRY */
+ if (syscons_version >= 0x100)
+ {
+#endif
+ if (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0)
+ {
+ /* No free VTs */
+ xf86Info.vtno = -1;
+ }
+#if 0
+ }
+#endif
+
+ if (xf86Info.vtno == -1)
+ {
+ /*
+ * All VTs are in use. If initialVT was found, use it.
+ * Otherwise, if stdin is a VT, use that one.
+ * XXX stdin is already closed, so this won't work.
+ */
+ if (initialVT != -1)
+ {
+ xf86Info.vtno = initialVT;
+ }
+ else if ((fstat(0, &status) >= 0)
+ && S_ISCHR(status.st_mode)
+ && (ioctl(0, VT_GETMODE, &vtmode) >= 0))
+ {
+ /* stdin is a VT */
+ xf86Info.vtno = minor(status.st_rdev) + 1;
+ }
+ else
+ {
+ if (syscons_version >= 0x100)
+ {
+ FatalError("%s: Cannot find a free VT\n",
+ "xf86OpenSyscons");
+ }
+ /* Should no longer reach here */
+ FatalError("%s: %s %s\n\t%s %s\n",
+ "xf86OpenSyscons",
+ "syscons versions prior to 1.0 require",
+ "either the",
+ "server's stdin be a VT",
+ "or the use of the vtxx server option");
+ }
+ }
+ from = X_PROBED;
+ }
+
+ close(fd);
+#ifndef __OpenBSD__
+ sprintf(vtname, "/dev/ttyv%01x", xf86Info.vtno - 1);
+#else
+ sprintf(vtname, "/dev/ttyC%01x", xf86Info.vtno - 1);
+#endif
+ if ((fd = open(vtname, SYSCONS_CONSOLE_MODE, 0)) < 0)
+ {
+ FatalError("xf86OpenSyscons: Cannot open %s (%s)\n",
+ vtname, strerror(errno));
+ }
+ if (ioctl(fd, VT_GETMODE, &vtmode) < 0)
+ {
+ FatalError("xf86OpenSyscons: VT_GETMODE failed\n");
+ }
+ xf86Info.consType = SYSCONS;
+ xf86Msg(X_PROBED, "Using syscons driver with X support");
+ if (syscons_version >= 0x100)
+ {
+ xf86ErrorF(" (version %d.%d)\n", syscons_version >> 8,
+ syscons_version & 0xFF);
+ }
+ else
+ {
+ xf86ErrorF(" (version 0.x)\n");
+ }
+ xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
+ }
+ else
+ {
+ /* VT_GETMODE failed, probably not syscons */
+ close(fd);
+ fd = -1;
+ }
+ }
+ return fd;
+}
+
+#endif /* SYSCONS_SUPPORT */
+
+
+#ifdef PCVT_SUPPORT
+
+static int
+xf86OpenPcvt()
+{
+ /* This looks much like syscons, since pcvt is API compatible */
+ int fd = -1;
+ vtmode_t vtmode;
+ char vtname[12], *vtprefix;
+ struct stat status;
+ struct pcvtid pcvt_version;
+
+#ifndef __OpenBSD__
+ vtprefix = "/dev/ttyv";
+#else
+ vtprefix = "/dev/ttyC";
+#endif
+
+ fd = open(PCVT_CONSOLE_DEV, PCVT_CONSOLE_MODE, 0);
+#ifdef WSCONS_SUPPORT
+ if (fd < 0)
+ {
+ fd = open(WSCONS_PCVT_COMPAT_CONSOLE_DEV, PCVT_CONSOLE_MODE, 0);
+ vtprefix = "/dev/ttyE";
+ }
+#endif
+ if (fd >= 0)
+ {
+ if (ioctl(fd, VGAPCVTID, &pcvt_version) >= 0)
+ {
+ if(ioctl(fd, VT_GETMODE, &vtmode) < 0)
+ {
+ FatalError("%s: VT_GETMODE failed\n%s%s\n%s\n",
+ "xf86OpenPcvt",
+ "Found pcvt driver but X11 seems to be",
+ " not supported.", CHECK_DRIVER_MSG);
+ }
+
+ xf86Info.vtno = VTnum;
+
+ if (ioctl(fd, VT_GETACTIVE, &initialVT) < 0)
+ initialVT = -1;
+
+ if (xf86Info.vtno == -1)
+ {
+ if (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0)
+ {
+ /* No free VTs */
+ xf86Info.vtno = -1;
+ }
+
+ if (xf86Info.vtno == -1)
+ {
+ /*
+ * All VTs are in use. If initialVT was found, use it.
+ * Otherwise, if stdin is a VT, use that one.
+ * XXX stdin is already closed, so this won't work.
+ */
+ if (initialVT != -1)
+ {
+ xf86Info.vtno = initialVT;
+ }
+ else if ((fstat(0, &status) >= 0)
+ && S_ISCHR(status.st_mode)
+ && (ioctl(0, VT_GETMODE, &vtmode) >= 0))
+ {
+ /* stdin is a VT */
+ xf86Info.vtno = minor(status.st_rdev) + 1;
+ }
+ else
+ {
+ FatalError("%s: Cannot find a free VT\n",
+ "xf86OpenPcvt");
+ }
+ }
+ }
+
+ close(fd);
+ sprintf(vtname, "%s%01x", vtprefix, xf86Info.vtno - 1);
+ if ((fd = open(vtname, PCVT_CONSOLE_MODE, 0)) < 0)
+ {
+ FatalError("xf86OpenPcvt: Cannot open %s (%s)\n",
+ vtname, strerror(errno));
+ }
+ if (ioctl(fd, VT_GETMODE, &vtmode) < 0)
+ {
+ FatalError("xf86OpenPcvt: VT_GETMODE failed\n");
+ }
+ xf86Info.consType = PCVT;
+ xf86Msg(X_PROBED, "Using pcvt driver (version %d.%d)\n",
+ pcvt_version.rmajor, pcvt_version.rminor);
+ }
+ else
+ {
+ /* Not pcvt */
+ close(fd);
+ fd = -1;
+ }
+ }
+ return fd;
+}
+
+#endif /* PCVT_SUPPORT */
+
+
+void
+xf86CloseConsole()
+{
+#if defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT)
+ struct vt_mode VT;
+#endif
+
+ switch (xf86Info.consType)
+ {
+#ifdef PCCONS_SUPPORT
+ case PCCONS:
+ ioctl (xf86Info.consoleFd, CONSOLE_X_MODE_OFF, 0);
+ break;
+#endif /* PCCONS_SUPPORT */
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ case SYSCONS:
+ case PCVT:
+ ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); /* Back to text mode */
+ if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1)
+ {
+ VT.mode = VT_AUTO;
+ ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* dflt vt handling */
+ }
+#if !defined(USE_DEV_IO) && !defined(USE_I386_IOPL)
+ if (ioctl(xf86Info.consoleFd, KDDISABIO, 0) < 0)
+ {
+ xf86FatalError("xf86CloseConsole: KDDISABIO failed (%s)\n",
+ strerror(errno));
+ }
+#endif
+ if (initialVT != -1)
+ ioctl(xf86Info.consoleFd, VT_ACTIVATE, initialVT);
+ break;
+#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */
+ }
+
+ if (xf86Info.screenFd != xf86Info.consoleFd)
+ {
+ close(xf86Info.screenFd);
+ close(xf86Info.consoleFd);
+ if ((xf86Info.consoleFd = open("/dev/console",O_RDONLY,0)) <0)
+ {
+ xf86FatalError("xf86CloseConsole: Cannot open /dev/console (%s)\n",
+ strerror(errno));
+ }
+ }
+ close(xf86Info.consoleFd);
+ if (devConsoleFd >= 0)
+ close(devConsoleFd);
+ return;
+}
+
+int
+xf86ProcessArgument(int argc, char *argv[], int i)
+{
+ /*
+ * Keep server from detaching from controlling tty. This is useful
+ * when debugging (so the server can receive keyboard signals.
+ */
+ if (!strcmp(argv[i], "-keeptty"))
+ {
+ KeepTty = TRUE;
+ return(1);
+ }
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
+ {
+ if (sscanf(argv[i], "vt%2d", &VTnum) == 0 ||
+ VTnum < 1 || VTnum > 12)
+ {
+ UseMsg();
+ VTnum = -1;
+ return(0);
+ }
+ return(1);
+ }
+#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */
+ return(0);
+}
+
+void
+xf86UseMsg()
+{
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ ErrorF("vtXX use the specified VT number (1-12)\n");
+#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */
+ ErrorF("-keeptty ");
+ ErrorF("don't detach controlling tty (for debugging only)\n");
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_io.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_io.c
new file mode 100644
index 000000000..e5d173e3d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_io.c
@@ -0,0 +1,214 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_io.c,v 3.16 1999/05/09 06:06:29 dawes Exp $ */
+/*
+ * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Rich Murphey and David Dawes
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Rich Murphey and
+ * David Dawes make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * RICH MURPHEY AND DAVID DAWES DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RICH MURPHEY OR DAVID DAWES 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.
+ *
+ */
+/* $XConsortium: bsd_io.c /main/11 1996/10/19 18:06:07 kaleb $ */
+
+#define NEED_EVENTS
+#include "X.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+void
+xf86SoundKbdBell(int loudness, int pitch, int duration)
+{
+ if (loudness && pitch)
+ {
+#ifdef PCCONS_SUPPORT
+ int data[2];
+#endif
+
+ switch (xf86Info.consType) {
+
+#ifdef PCCONS_SUPPORT
+ case PCCONS:
+ data[0] = pitch;
+ data[1] = (duration * loudness) / 50;
+ ioctl(xf86Info.consoleFd, CONSOLE_X_BELL, data);
+ break;
+#endif
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ case SYSCONS:
+ case PCVT:
+ ioctl(xf86Info.consoleFd, KDMKTONE,
+ ((1193190 / pitch) & 0xffff) |
+ (((unsigned long)duration*loudness/50)<<16));
+ break;
+#endif
+ }
+ }
+}
+
+void
+xf86SetKbdLeds(int leds)
+{
+ switch (xf86Info.consType) {
+
+ case PCCONS:
+ break;
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ case SYSCONS:
+ case PCVT:
+ ioctl(xf86Info.consoleFd, KDSETLED, leds);
+ break;
+#endif
+ }
+}
+
+int
+xf86GetKbdLeds()
+{
+ int leds = 0;
+
+ switch (xf86Info.consType) {
+
+ case PCCONS:
+ break;
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ case SYSCONS:
+ case PCVT:
+ ioctl(xf86Info.consoleFd, KDGETLED, &leds);
+ break;
+#endif
+ }
+ return(leds);
+}
+
+void
+xf86SetKbdRepeat(char rad)
+{
+ switch (xf86Info.consType) {
+
+ case PCCONS:
+ break;
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ case SYSCONS:
+ case PCVT:
+ ioctl(xf86Info.consoleFd, KDSETRAD, rad);
+ break;
+#endif
+ }
+}
+
+static struct termio kbdtty;
+
+void
+xf86KbdInit()
+{
+ switch (xf86Info.consType) {
+
+#if defined(PCCONS_SUPPORT) || defined(SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ case PCCONS:
+ case SYSCONS:
+ case PCVT:
+ tcgetattr(xf86Info.consoleFd, &kbdtty);
+ break;
+#endif
+ }
+}
+
+int
+xf86KbdOn()
+{
+ struct termios nTty;
+
+ switch (xf86Info.consType) {
+
+#if defined(SYSCONS_SUPPORT) || defined(PCCONS_SUPPORT) || defined(PCVT_SUPPORT)
+ case SYSCONS:
+ case PCCONS:
+ case PCVT:
+ nTty = kbdtty;
+ nTty.c_iflag = IGNPAR | IGNBRK;
+ nTty.c_oflag = 0;
+ nTty.c_cflag = CREAD | CS8;
+ nTty.c_lflag = 0;
+ nTty.c_cc[VTIME] = 0;
+ nTty.c_cc[VMIN] = 1;
+ cfsetispeed(&nTty, 9600);
+ cfsetospeed(&nTty, 9600);
+ tcsetattr(xf86Info.consoleFd, TCSANOW, &nTty);
+
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ ioctl(xf86Info.consoleFd, KDSKBMODE, K_RAW);
+#endif
+ break;
+#endif
+ }
+ return(xf86Info.consoleFd);
+}
+
+int
+xf86KbdOff()
+{
+ switch (xf86Info.consType) {
+
+#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)
+ case SYSCONS:
+ case PCVT:
+ ioctl(xf86Info.consoleFd, KDSKBMODE, K_XLATE);
+ /* FALL THROUGH */
+#endif
+#if defined(SYSCONS_SUPPORT) || defined(PCCONS_SUPPORT) || defined(PCVT_SUPPORT)
+ case PCCONS:
+ tcsetattr(xf86Info.consoleFd, TCSANOW, &kbdtty);
+ break;
+#endif
+ }
+ return(xf86Info.consoleFd);
+}
+
+#ifndef NEW_INPUT
+void
+xf86MouseInit(MouseDevPtr mouse)
+{
+ return;
+}
+
+int
+xf86MouseOn(MouseDevPtr mouse)
+{
+ if ((mouse->mseFd = open(mouse->mseDevice, O_RDWR | O_NDELAY)) < 0)
+ {
+ if (xf86Info.allowMouseOpenFail) {
+ xf86Msg(X_WARNING,
+ "Cannot open mouse (%s) - Continuing...\n",
+ strerror(errno));
+ return(-2);
+ }
+ FatalError("Cannot open mouse (%s)\n", strerror(errno));
+ }
+
+ xf86SetupMouse(mouse);
+
+ /* Flush any pending input */
+ tcflush(mouse->mseFd, TCIFLUSH);
+
+ return(mouse->mseFd);
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_jstk.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_jstk.c
new file mode 100644
index 000000000..270f549c4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_jstk.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright 1995 by Frederic Lepied, France. <fred@sugix.frmug.fr.net>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Frederic Lepied not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Frederic Lepied makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * FREDERIC LEPIED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL FREDERIC LEPIED 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.
+ *
+ */
+
+/* Modified for FreeBSD by David Dawes <dawes@XFree86.org> */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_jstk.c,v 3.7 1998/07/25 16:56:34 dawes Exp $ */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <machine/joystick.h>
+#include <fcntl.h>
+
+#ifdef XFree86LOADER
+#include "misc.h"
+#include "xf86_libc.h"
+#endif
+#include "xf86.h"
+
+#define JS_RETURN sizeof(struct joystick)
+
+/***********************************************************************
+ *
+ * xf86JoystickOn --
+ *
+ * open the device and init timeout according to the device value.
+ *
+ ***********************************************************************
+ */
+
+int
+xf86JoystickOn(char * name, int *timeout, int *centerX, int *centerY)
+{
+ int status;
+ int changed = 0;
+ int timeinmicros;
+ struct joystick js;
+
+#ifdef DEBUG
+ ErrorF("xf86JoystickOn: %s\n", name);
+#endif
+
+ if ((status = open(name, O_RDWR | O_NDELAY, 0)) < 0)
+ {
+ xf86Msg(X_WARNING, "xf86JoystickOn: Cannot open joystick '%s' (%s)\n",
+ name, strerror(errno));
+ return -1;
+ }
+
+ if (*timeout <= 0) {
+ /* Use the current setting */
+ ioctl(status, JOY_GETTIMEOUT, (char *)&timeinmicros);
+ *timeout = timeinmicros / 1000;
+ if (*timeout == 0)
+ *timeout = 1;
+ changed = 1;
+ }
+ /* Maximum allowed timeout in the FreeBSD driver is 10ms */
+ if (*timeout > 10) {
+ *timeout = 10;
+ changed = 1;
+ }
+
+ if (changed)
+ xf86Msg(X_PROBED, "Joystick: timeout value = %d\n", *timeout);
+
+ timeinmicros = *timeout * 1000;
+
+ /* Assume the joystick is centred when this is called */
+ read(status, &js, JS_RETURN);
+ if (*centerX < 0) {
+ *centerX = js.x;
+ xf86Msg(X_PROBED, "Joystick: CenterX set to %d\n", *centerX);
+ }
+ if (*centerY < 0) {
+ *centerY = js.y;
+ xf86Msg(X_PROBED, "Joystick: CenterY set to %d\n", *centerY);
+ }
+ }
+
+ return status;
+}
+
+/***********************************************************************
+ *
+ * xf86JoystickInit --
+ *
+ * called when X device is initialized.
+ *
+ ***********************************************************************
+ */
+
+void
+xf86JoystickInit()
+{
+ return;
+}
+
+/***********************************************************************
+ *
+ * xf86JoystickOff --
+ *
+ * close the handle.
+ *
+ ***********************************************************************
+ */
+
+int
+xf86JoystickOff(int *fd, int doclose)
+{
+ int oldfd;
+
+ if (((oldfd = *fd) >= 0) && doclose) {
+ close(*fd);
+ *fd = -1;
+ }
+ return oldfd;
+}
+
+/***********************************************************************
+ *
+ * xf86JoystickGetState --
+ *
+ * return the state of buttons and the position of the joystick.
+ *
+ ***********************************************************************
+ */
+
+int
+xf86JoystickGetState(int fd, int *x, int *y, int *buttons)
+{
+ struct joystick js;
+ int status;
+
+ status = read(fd, &js, JS_RETURN);
+
+ if (status != JS_RETURN)
+ {
+ Error("Joystick read");
+ return 0;
+ }
+
+ *x = js.x;
+ *y = js.y;
+ *buttons = js.b1 | (js.b2 << 1);
+#ifdef DEBUG
+ ErrorF("xf86JoystickGetState: x = %d, y = %d, buttons = %d\n", *x, *y,
+ *buttons);
+#endif
+
+ return 1;
+}
+
+#ifdef XFree86LOADER
+/*
+ * Entry point for XFree86 Loader
+ */
+void
+bsd_jstkModuleInit(pointer *data, INT32 *magic)
+{
+ *magic = MAGIC_DONE;
+ *data = NULL;
+}
+#endif
+/* end of bsd_jstk.c */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_mouse.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_mouse.c
new file mode 100644
index 000000000..4b50211af
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_mouse.c
@@ -0,0 +1,341 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_mouse.c,v 1.9 1999/07/18 08:14:35 dawes Exp $ */
+
+/*
+ * Copyright 1999 by The XFree86 Project, Inc.
+ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86_OSlib.h"
+#include "xf86Xinput.h"
+#include "xf86OSmouse.h"
+#include "xisb.h"
+#include "mipointer.h"
+#ifdef WSCONS_SUPPORT
+#include <dev/wscons/wsconsio.h>
+#endif
+
+static int
+SupportedInterfaces(void)
+{
+#if defined(__NetBSD__)
+ return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO;
+#elif defined(__FreeBSD__)
+ return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO | MSE_MISC;
+#else
+ return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO;
+#endif
+}
+
+/* Names of protocols that are handled internally here. */
+static const char *internalNames[] = {
+#if defined(WSCONS_SUPPORT)
+ "WSMouse",
+#endif
+ NULL
+};
+
+/*
+ * Names of MSC_MISC protocols that the OS supports. These are decoded by
+ * main "mouse" driver.
+ */
+static const char *miscNames[] = {
+#if defined(__FreeBSD__)
+ "SysMouse",
+#endif
+ NULL
+};
+
+static const char **
+BuiltinNames(void)
+{
+ return internalNames;
+}
+
+static Bool
+CheckProtocol(const char *protocol)
+{
+ int i;
+
+ for (i = 0; internalNames[i]; i++)
+ if (xf86NameCmp(protocol, internalNames[i]) == 0)
+ return TRUE;
+ for (i = 0; miscNames[i]; i++)
+ if (xf86NameCmp(protocol, miscNames[i]) == 0)
+ return TRUE;
+ return FALSE;
+}
+
+static const char *
+DefaultProtocol(void)
+{
+#if defined(__FreeBSD__)
+ return "Auto";
+#else
+ return NULL;
+#endif
+}
+
+#if defined(__FreeBSD__) && defined(MOUSE_PROTO_SYSMOUSE)
+static struct {
+ int dproto;
+ const char *name;
+} devproto[] = {
+ { MOUSE_PROTO_MS, "Microsoft" },
+ { MOUSE_PROTO_MSC, "MouseSystems" },
+ { MOUSE_PROTO_LOGI, "Logitech" },
+ { MOUSE_PROTO_MM, "MMSeries" },
+ { MOUSE_PROTO_LOGIMOUSEMAN, "MouseMan" },
+ { MOUSE_PROTO_BUS, "BusMouse" },
+ { MOUSE_PROTO_INPORT, "BusMouse" },
+ { MOUSE_PROTO_PS2, "PS/2" },
+ { MOUSE_PROTO_HITTAB, "MMHitTab" },
+ { MOUSE_PROTO_GLIDEPOINT, "GlidePoint" },
+ { MOUSE_PROTO_INTELLI, "Intellimouse" },
+ { MOUSE_PROTO_THINK, "ThinkingMouse" },
+ { MOUSE_PROTO_SYSMOUSE, "SysMouse" }
+};
+
+static const char *
+SetupAuto(InputInfoPtr pInfo, int *protoPara)
+{
+ int i;
+ mousehw_t hw;
+ mousemode_t mode;
+
+ if (pInfo->fd == -1)
+ return NULL;
+
+ /* set the driver operation level, if applicable */
+ i = 1;
+ ioctl(pInfo->fd, MOUSE_SETLEVEL, &i);
+
+ /* interrogate the driver and get some intelligence on the device. */
+ hw.iftype = MOUSE_IF_UNKNOWN;
+ hw.model = MOUSE_MODEL_GENERIC;
+ ioctl(pInfo->fd, MOUSE_GETHWINFO, &hw);
+ if (ioctl(pInfo->fd, MOUSE_GETMODE, &mode) == 0) {
+ for (i = 0; i < sizeof(devproto)/sizeof(devproto[0]); ++i) {
+ if (mode.protocol == devproto[i].dproto) {
+ /* override some parameters */
+ if (protoPara) {
+ protoPara[4] = mode.packetsize;
+ protoPara[0] = mode.syncmask[0];
+ protoPara[1] = mode.syncmask[1];
+ }
+ return devproto[i].name;
+ }
+ }
+ }
+ return NULL;
+}
+
+static void
+SetSysMouseRes(InputInfoPtr pInfo, const char *protocol, int rate, int res)
+{
+ mousemode_t mode;
+
+ mode.rate = rate > 0 ? rate : -1;
+ mode.resolution = res > 0 ? res : -1;
+ mode.accelfactor = -1;
+ mode.level = -1;
+ ioctl(pInfo->fd, MOUSE_SETMODE, &mode);
+}
+#endif
+
+#if defined(WSCONS_SUPPORT)
+#define NUMEVENTS 64
+
+static int
+wsconsMouseProc(DeviceIntPtr pPointer, int what)
+{
+ InputInfoPtr pInfo;
+ MouseDevPtr pMse;
+ unsigned char map[MSE_MAXBUTTONS + 1];
+ int nbuttons;
+
+ pInfo = pPointer->public.devicePrivate;
+ pMse = pInfo->private;
+ pMse->device = pPointer;
+
+ switch (what) {
+ case DEVICE_INIT:
+ pPointer->public.on = FALSE;
+
+ for (nbuttons = 0; nbuttons < MSE_MAXBUTTONS; ++nbuttons)
+ map[nbuttons + 1] = nbuttons + 1;
+
+ InitPointerDeviceStruct((DevicePtr)pPointer,
+ map,
+ min(pMse->buttons, MSE_MAXBUTTONS),
+ miPointerGetMotionEvents,
+ pMse->Ctrl,
+ miPointerGetMotionBufferSize());
+
+ /* X valuator */
+ xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1);
+ xf86InitValuatorDefaults(pPointer, 0);
+ /* Y valuator */
+ xf86InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1);
+ xf86InitValuatorDefaults(pPointer, 1);
+ xf86MotionHistoryAllocate(pInfo);
+ break;
+
+ case DEVICE_ON:
+ pInfo->fd = xf86OpenSerial(pInfo->options);
+ if (pInfo->fd == -1)
+ xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
+ else {
+ pMse->buffer = XisbNew(pInfo->fd,
+ NUMEVENTS * sizeof(struct wscons_event));
+ if (!pMse->buffer) {
+ xfree(pMse);
+ xf86CloseSerial(pInfo->fd);
+ pInfo->fd = -1;
+ } else {
+ xf86FlushInput(pInfo->fd);
+ AddEnabledDevice(pInfo->fd);
+ }
+ }
+ pMse->lastButtons = 0;
+ pMse->emulateState = 0;
+ pPointer->public.on = TRUE;
+ break;
+
+ case DEVICE_OFF:
+ case DEVICE_CLOSE:
+ if (pInfo->fd != -1) {
+ RemoveEnabledDevice(pInfo->fd);
+ if (pMse->buffer) {
+ XisbFree(pMse->buffer);
+ pMse->buffer = NULL;
+ }
+ xf86CloseSerial(pInfo->fd);
+ pInfo->fd = -1;
+ }
+ pPointer->public.on = FALSE;
+ usleep(300000);
+ break;
+ }
+ return Success;
+}
+
+
+static void
+wsconsReadInput(InputInfoPtr pInfo)
+{
+ MouseDevPtr pMse;
+ static struct wscons_event eventList[NUMEVENTS];
+ int n, c;
+ struct wscons_event *event = eventList;
+ unsigned char *pBuf;
+
+ pMse = pInfo->private;
+
+ XisbBlockDuration(pMse->buffer, -1);
+ pBuf = (unsigned char *)eventList;
+ n = 0;
+ while ((c = XisbRead(pMse->buffer)) >= 0 && n < sizeof(eventList)) {
+ pBuf[n++] = (unsigned char)c;
+ }
+
+ if (n == 0)
+ return;
+
+ n /= sizeof(struct wscons_event);
+ while( n-- ) {
+ int buttons = pMse->lastButtons;
+ int dx = 0, dy = 0, dz = 0;
+ switch (event->type) {
+ case WSCONS_EVENT_MOUSE_UP:
+#define BUTBIT (1 << (event->value <= 2 ? 2 - event->value : event->value))
+ buttons &= ~BUTBIT;
+ break;
+ case WSCONS_EVENT_MOUSE_DOWN:
+ buttons |= BUTBIT;
+ break;
+ case WSCONS_EVENT_MOUSE_DELTA_X:
+ dx = event->value;
+ break;
+ case WSCONS_EVENT_MOUSE_DELTA_Y:
+ dy = -event->value;
+ break;
+#ifdef WSCONS_EVENT_MOUSE_DELTA_Z
+ case WSCONS_EVENT_MOUSE_DELTA_Z:
+ dz = event->value;
+ break;
+#endif
+ default:
+ xf86Msg(X_WARNING, "%s: bad wsmouse event type=%d\n", pInfo->name,
+ event->type);
+ continue;
+ }
+
+ pMse->PostEvent(pInfo, buttons, dx, dy, dz);
+ ++event;
+ }
+ return;
+}
+
+/* This function is called when the protocol is "wsmouse". */
+static Bool
+wsconsPreInit(InputInfoPtr pInfo, const char *protocol, int flags)
+{
+ MouseDevPtr pMse = pInfo->private;
+
+ pMse->protocol = protocol;
+ xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol);
+
+ /* Collect the options, and process the common options. */
+ xf86CollectInputOptions(pInfo, NULL, NULL);
+ xf86ProcessCommonOptions(pInfo, pInfo->options);
+
+ /* Check if the device can be opened. */
+ pInfo->fd = xf86OpenSerial(pInfo->options);
+ if (pInfo->fd == -1) {
+ if (xf86GetAllowMouseOpenFail())
+ xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
+ else {
+ xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name);
+ xfree(pMse);
+ return FALSE;
+ }
+ }
+ xf86CloseSerial(pInfo->fd);
+ pInfo->fd = -1;
+
+ /* Process common mouse options (like Emulate3Buttons, etc). */
+ pMse->CommonOptions(pInfo);
+
+ /* Setup the local procs. */
+ pInfo->device_control = wsconsMouseProc;
+ pInfo->read_input = wsconsReadInput;
+
+ pInfo->flags |= XI86_CONFIGURED;
+ return TRUE;
+}
+#endif
+
+OSMouseInfoPtr
+xf86OSMouseInit(int flags)
+{
+ OSMouseInfoPtr p;
+
+ p = xcalloc(sizeof(OSMouseInfoRec), 1);
+ if (!p)
+ return NULL;
+ p->SupportedInterfaces = SupportedInterfaces;
+ p->BuiltinNames = BuiltinNames;
+ p->DefaultProtocol = DefaultProtocol;
+ p->CheckProtocol = CheckProtocol;
+#if defined(__FreeBSD__) && defined(MOUSE_PROTO_SYSMOUSE)
+ p->SetupAuto = SetupAuto;
+ p->SetPS2Res = SetSysMouseRes;
+ p->SetBMRes = SetSysMouseRes;
+ p->SetMiscRes = SetSysMouseRes;
+#endif
+#if defined(WSCONS_SUPPORT)
+ p->PreInit = wsconsPreInit;
+#endif
+ return p;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_video.c b/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_video.c
new file mode 100644
index 000000000..7811df5c0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_video.c
@@ -0,0 +1,1203 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_video.c,v 3.29 1999/08/28 09:01:17 dawes Exp $ */
+/*
+ * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Rich Murphey and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Rich Murphey and
+ * David Wexelblat make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RICH MURPHEY OR DAVID WEXELBLAT BE LIABLE FOR
+ * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/*
+ * The ARM32 code here carries the following copyright:
+ *
+ * Copyright 1997
+ * Digital Equipment Corporation. All rights reserved.
+ * This software is furnished under license and may be used and copied only in
+ * accordance with the following terms and conditions. Subject to these
+ * conditions, you may download, copy, install, use, modify and distribute
+ * this software in source and/or binary form. No title or ownership is
+ * transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce and retain
+ * this copyright notice and list of conditions as they appear in the
+ * source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or logo of Digital
+ * Equipment Corporation. Neither the "Digital Equipment Corporation"
+ * name nor any trademark or logo of Digital Equipment Corporation may be
+ * used to endorse or promote products derived from this software without
+ * the prior written permission of Digital Equipment Corporation.
+ *
+ * 3) This software is provided "AS-IS" and any express or implied warranties,
+ * including but not limited to, any implied warranties of merchantability,
+ * fitness for a particular purpose, or non-infringement are disclaimed.
+ * In no event shall DIGITAL be liable for any damages whatsoever, and in
+ * particular, DIGITAL shall not be liable for special, indirect,
+ * consequential, or incidental damages or damages for lost profits, loss
+ * of revenue or loss of use, whether such damages arise in contract,
+ * negligence, tort, under statute, in equity, at law or otherwise, even
+ * if advised of the possibility of such damage.
+ *
+ */
+
+/* $XConsortium: bsd_video.c /main/10 1996/10/25 11:37:57 kaleb $ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86OSpriv.h"
+
+#ifdef HAS_MTRR_SUPPORT
+#include <sys/memrange.h>
+#define X_MTRR_ID "XFree86"
+#endif
+
+#ifdef __arm32__
+#include "machine/devmap.h"
+struct memAccess
+{
+ int ioctl;
+ struct map_info memInfo;
+ pointer regionVirtBase;
+ Bool Checked;
+ Bool OK;
+};
+
+static pointer xf86MapInfoMap();
+static void xf86MapInfoUnmap();
+static struct memAccess *checkMapInfo();
+extern int vgaPhysLinearBase;
+
+/* A memAccess structure is needed for each possible region */
+struct memAccess vgaMemInfo = { CONSOLE_GET_MEM_INFO, NULL, NULL,
+ FALSE, FALSE };
+struct memAccess linearMemInfo = { CONSOLE_GET_LINEAR_INFO, NULL, NULL,
+ FALSE, FALSE };
+struct memAccess ioMemInfo = { CONSOLE_GET_IO_INFO, NULL, NULL,
+ FALSE, FALSE };
+#endif /* __arm32__ */
+
+#if defined(__NetBSD__) && !defined(MAP_FILE)
+#define MAP_FLAGS MAP_SHARED
+#else
+#define MAP_FLAGS (MAP_FILE | MAP_SHARED)
+#endif
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((caddr_t)-1)
+#endif
+
+/***************************************************************************/
+/* Video Memory Mapping section */
+/***************************************************************************/
+
+static Bool useDevMem = FALSE;
+static int devMemFd = -1;
+
+#ifdef HAS_APERTURE_DRV
+#define DEV_APERTURE "/dev/xf86"
+#endif
+#define DEV_MEM "/dev/mem"
+
+static pointer mapVidMem(int, unsigned long, unsigned long);
+static void unmapVidMem(int, pointer, unsigned long);
+#ifdef HAS_MTRR_SUPPORT
+static pointer setWC(int, unsigned long, unsigned long, Bool, MessageType);
+static void undoWC(int, pointer);
+static Bool cleanMTRR(void);
+#endif
+
+/*
+ * Check if /dev/mem can be mmap'd. If it can't print a warning when
+ * "warn" is TRUE.
+ */
+static void
+checkDevMem(Bool warn)
+{
+ static Bool devMemChecked = FALSE;
+ int fd;
+ pointer base;
+
+ if (devMemChecked)
+ return;
+ devMemChecked = TRUE;
+
+ if ((fd = open(DEV_MEM, O_RDWR)) >= 0)
+ {
+ /* Try to map a page at the VGA address */
+ base = mmap((caddr_t)0, 4096, PROT_READ|PROT_WRITE,
+ MAP_FLAGS, fd, (off_t)0xA0000);
+
+ if (base != MAP_FAILED)
+ {
+ munmap((caddr_t)base, 4096);
+ devMemFd = fd;
+ useDevMem = TRUE;
+ return;
+ } else {
+ /* This should not happen */
+ if (warn)
+ {
+ xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n",
+ DEV_MEM, strerror(errno));
+ }
+ useDevMem = FALSE;
+ return;
+ }
+ }
+#ifndef HAS_APERTURE_DRV
+ if (warn)
+ {
+ xf86Msg(X_WARNING, "checkDevMem: failed to open %s (%s)\n",
+ DEV_MEM, strerror(errno));
+ xf86ErrorF("\tlinear framebuffer access unavailable\n");
+ }
+ useDevMem = FALSE;
+ return;
+#else
+ /* Failed to open /dev/mem, try the aperture driver */
+ if ((fd = open(DEV_APERTURE, O_RDWR)) >= 0)
+ {
+ /* Try to map a page at the VGA address */
+ base = mmap((caddr_t)0, 4096, PROT_READ|PROT_WRITE,
+ MAP_FLAGS, fd, (off_t)0xA0000);
+
+ if (base != MAP_FAILED)
+ {
+ munmap((caddr_t)base, 4096);
+ devMemFd = fd;
+ useDevMem = TRUE;
+ xf86Msg(X_INFO, "checkDevMem: using aperture driver %s\n",
+ DEV_APERTURE);
+ return;
+ } else {
+
+ if (warn)
+ {
+ xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n",
+ DEV_APERTURE, strerror(errno));
+ }
+ }
+ } else {
+ if (warn)
+ {
+ xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n"
+ "\t(%s)\n", DEV_MEM, DEV_APERTURE, strerror(errno));
+ }
+ }
+
+ if (warn)
+ {
+ xf86ErrorF("\tlinear framebuffer access unavailable\n");
+ }
+ useDevMem = FALSE;
+ return;
+
+#endif
+}
+
+
+void
+xf86OSInitVidMem(VidMemInfoPtr pVidMem)
+{
+ checkDevMem(TRUE);
+ pVidMem->linearSupported = useDevMem;
+#ifndef __arm32__
+ pVidMem->mapMem = mapVidMem;
+ pVidMem->unmapMem = unmapVidMem;
+#else
+ pVidMem->mapMem = armMapVidMem;
+ pVidMem->unmapVidMem = armUnmapVidMem;
+#endif
+#ifdef HAS_MTRR_SUPPORT
+ if (useDevMem) {
+ if (cleanMTRR()) {
+ pVidMem->setWC = setWC;
+ pVidMem->undoWC = undoWC;
+ }
+ }
+#endif
+ pVidMem->initialised = TRUE;
+}
+
+static pointer
+mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size)
+{
+ pointer base;
+
+ checkDevMem(FALSE);
+
+ if (useDevMem)
+ {
+ if (devMemFd < 0)
+ {
+ FatalError("xf86MapVidMem: failed to open %s (%s)\n",
+ DEV_MEM, strerror(errno));
+ }
+ base = mmap((caddr_t)0, Size, PROT_READ|PROT_WRITE,
+ MAP_FLAGS, devMemFd, (off_t)Base);
+ if (base == MAP_FAILED)
+ {
+ FatalError("%s: could not mmap %s [s=%x,a=%x] (%s)\n",
+ "xf86MapVidMem", DEV_MEM, Size, Base,
+ strerror(errno));
+ }
+ return(base);
+ }
+
+ /* else, mmap /dev/vga */
+#ifndef PC98
+ if ((unsigned long)Base < 0xA0000 || (unsigned long)Base >= 0xC0000)
+#else
+ if ((unsigned long)Base < 0xA0000 || (unsigned long)Base >= 0xE8000)
+#endif
+ {
+ FatalError("%s: Address 0x%x outside allowable range\n",
+ "xf86MapVidMem", Base);
+ }
+ base = mmap(0, Size, PROT_READ|PROT_WRITE, MAP_FLAGS,
+ xf86Info.screenFd,
+#ifdef __mips__
+ (unsigned long)Base);
+#else
+ (unsigned long)Base - 0xA0000);
+#endif
+ if (base == MAP_FAILED)
+ {
+ FatalError("xf86MapVidMem: Could not mmap /dev/vga (%s)\n",
+ strerror(errno));
+ }
+ return(base);
+}
+
+static void
+unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+{
+ munmap((caddr_t)Base, Size);
+}
+
+/*
+ * Read BIOS via mmap()ing DEV_MEM
+ */
+
+int
+xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf,
+ int Len)
+{
+ unsigned char *ptr;
+ int psize;
+ int mlen;
+
+ checkDevMem(TRUE);
+ if (devMemFd == -1) {
+ return(-1);
+ }
+
+ psize = xf86getpagesize();
+ mlen = (Offset + Len + psize - 1) & ~psize;
+ /* Base is assumed to be page-aligned. */
+ ptr = (unsigned char *)mmap((caddr_t)0, mlen, PROT_READ,
+ MAP_SHARED, devMemFd, (off_t)Base);
+ if ((int)ptr == -1)
+ {
+ xf86Msg(X_WARNING, "xf86ReadBIOS: %s mmap failed (%s)\n",
+ DEV_MEM, strerror(errno));
+ return(-1);
+ }
+#ifdef DEBUG
+ ErrorF("xf86ReadBIOS: BIOS at 0x%08x has signature 0x%04x\n",
+ Base, ptr[0] | (ptr[1] << 8));
+#endif
+ (void)memcpy(Buf, (void *)(ptr + Offset), Len);
+ (void)munmap((caddr_t)ptr, mlen);
+ return(Len);
+}
+
+#ifdef __arm32__
+
+/* XXX This needs to be updated for the ND */
+
+/*
+** Find out whether the console driver provides memory mapping information
+** for the specified region and return the map_info pointer. Print a warning if required.
+*/
+static struct memAccess *
+checkMapInfo(Bool warn, int Region)
+{
+ struct memAccess *memAccP;
+
+ switch (Region)
+ {
+ case VGA_REGION:
+ memAccP = &vgaMemInfo;
+ break;
+
+ case LINEAR_REGION:
+ memAccP = &linearMemInfo;
+ break;
+
+ case MMIO_REGION:
+ memAccP = &ioMemInfo;
+ break;
+
+ default:
+ return NULL;
+ break;
+ }
+
+ if(!memAccP->Checked)
+ {
+ if(ioctl(xf86Info.screenFd, memAccP->ioctl, &(memAccP->memInfo)) == -1)
+ {
+ if(warn)
+ {
+ xf86Msg(X_WARNING,
+ "checkMapInfo: failed to get map info for region %d\n\t(%s)\n",
+ Region, strerror(errno));
+ }
+ }
+ else
+ {
+ if(memAccP->memInfo.u.map_info_mmap.map_offset
+ != MAP_INFO_UNKNOWN)
+ memAccP->OK = TRUE;
+ }
+ memAccP->Checked = TRUE;
+ }
+ if (memAccP->OK)
+ {
+ return memAccP;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+static pointer
+xf86MapInfoMap(struct memAccess *memInfoP, pointer Base, unsigned long Size)
+{
+ struct map_info *mapInfoP = &(memInfoP->memInfo);
+
+ if (mapInfoP->u.map_info_mmap.map_size == MAP_INFO_UNKNOWN)
+ {
+ Size = (unsigned long)Base + Size;
+ }
+ else
+ {
+ Size = mapInfoP->u.map_info_mmap.map_size;
+ }
+
+ switch(mapInfoP->method)
+ {
+ case MAP_MMAP:
+ /* Need to remap if size is unknown because we may not have
+ mapped the whole region initially */
+ if(memInfoP->regionVirtBase == NULL ||
+ mapInfoP->u.map_info_mmap.map_size == MAP_INFO_UNKNOWN)
+ {
+ if((memInfoP->regionVirtBase =
+ mmap((caddr_t)0,
+ Size,
+ PROT_READ|PROT_WRITE,
+ MAP_SHARED,
+ xf86Info.screenFd,
+ (unsigned long)mapInfoP->u.map_info_mmap.map_offset))
+ == (pointer)-1)
+ {
+ FatalError("xf86MapInfoMap: Failed to map memory at 0x%x\n\t%s\n",
+ mapInfoP->u.map_info_mmap.map_offset, strerror(errno));
+ }
+ if(mapInfoP->u.map_info_mmap.internal_offset > 0)
+ memInfoP->regionVirtBase +=
+ mapInfoP->u.map_info_mmap.internal_offset;
+ }
+ break;
+
+ default:
+ FatalError("xf86MapInfoMap: Unsuported mapping method\n");
+ break;
+ }
+
+ return (pointer)((int)memInfoP->regionVirtBase + (int)Base);
+}
+
+static void
+xf86MapInfoUnmap(struct memAccess *memInfoP, unsigned long Size)
+{
+ struct map_info *mapInfoP = &(memInfoP->memInfo);
+
+ switch(mapInfoP->method)
+ {
+ case MAP_MMAP:
+ if(memInfoP->regionVirtBase != NULL)
+ {
+ if(mapInfoP->u.map_info_mmap.map_size != MAP_INFO_UNKNOWN)
+ Size = mapInfoP->u.map_info_mmap.map_size;
+ munmap((caddr_t)memInfoP->regionVirtBase, Size);
+ memInfoP->regionVirtBase = NULL;
+ }
+ break;
+ default:
+ FatalError("xf86MapInfoMap: Unsuported mapping method\n");
+ break;
+ }
+}
+
+static pointer
+armMapVidMem(int ScreenNum, unsigned long Base, unsigned long Size)
+{
+ struct memAccess *memInfoP;
+
+ if((memInfoP = checkMapInfo(FALSE, Region)) != NULL)
+ {
+ /*
+ ** xf86 passes in a physical address offset from the start
+ ** of physical memory, but xf86MapInfoMap expects an
+ ** offset from the start of the specified region - it gets
+ ** the physical address of the region from the display driver.
+ */
+ switch(Region)
+ {
+ case LINEAR_REGION:
+ if (vgaPhysLinearBase)
+ {
+ Base -= vgaPhysLinearBase;
+ }
+ break;
+ case VGA_REGION:
+ Base -= 0xA0000;
+ break;
+ }
+
+ base = xf86MapInfoMap(memInfoP, Base, Size);
+ return (base);
+ }
+ return mapVidMem(ScreenNum, Base, Size);
+}
+
+static void
+armUnmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+{
+ struct memAccess *memInfoP;
+
+ if((memInfoP = checkMapInfo(FALSE, Region)) != NULL)
+ {
+ xf86MapInfoUnmap(memInfoP, Base, Size);
+ }
+ unmapVidMem(ScreenNum, Base, Size);
+}
+#endif /* __arm32__ */
+
+#ifdef USE_I386_IOPL
+/***************************************************************************/
+/* I/O Permissions section */
+/***************************************************************************/
+
+static Bool ExtendedEnabled = FALSE;
+
+void
+xf86EnableIO()
+{
+ if (ExtendedEnabled)
+ return;
+
+ if (i386_iopl(TRUE) < 0)
+ {
+ FatalError("%s: Failed to set IOPL for extended I/O\n",
+ "xf86EnableIO");
+ }
+ ExtendedEnabled = TRUE;
+
+ return;
+}
+
+void
+xf86DisableIO()
+{
+ if (!ExtendedEnabled)
+ return;
+
+ i386_iopl(FALSE);
+ ExtendedEnabled = FALSE;
+
+ return;
+}
+
+#endif /* USE_I386_IOPL */
+
+#ifdef USE_DEV_IO
+static int IoFd = -1;
+
+void
+xf86EnableIO()
+{
+ if (IoFd >= 0)
+ return;
+
+ if ((IoFd = open("/dev/io", O_RDWR)) == -1)
+ {
+ FatalError("xf86EnableIO: "
+ "Failed to open /dev/io for extended I/O\n");
+ }
+ return;
+}
+
+void
+xf86DisableIO()
+{
+ if (IoFd < 0)
+ return;
+
+ close(IoFd);
+ IoFd = -1;
+ return;
+}
+
+#endif
+
+#if defined(USE_ARC_MMAP) || defined(__arm32__)
+
+void
+xf86EnableIO()
+{
+ int fd;
+ pointer base;
+
+ if (ExtendedEnabled)
+ return;
+
+ if ((fd = open("/dev/ttyC0", O_RDWR)) >= 0) {
+ /* Try to map a page at the pccons I/O space */
+ base = (pointer)mmap((caddr_t)0, 65536, PROT_READ|PROT_WRITE,
+ MAP_FLAGS, fd, (off_t)0x0000);
+
+ if (base != (pointer)-1) {
+ IOPortBase = base;
+ }
+ else {
+ FatalError("EnableIO: failed to mmap %s (%s)\n",
+ "/dev/ttyC0", strerror(errno));
+ }
+ }
+ else {
+ FatalError("EnableIO: failed to open %s (%s)\n",
+ "/dev/ttyC0", strerror(errno));
+ }
+
+ ExtendedEnabled = TRUE;
+
+ return;
+}
+
+void
+xf86DisableIO()
+{
+ return;
+}
+
+#endif /* USE_ARC_MMAP */
+
+/***************************************************************************/
+/* Interrupt Handling section */
+/***************************************************************************/
+
+Bool
+xf86DisableInterrupts()
+{
+
+#if !defined(__mips__) && !defined(__arm32__)
+#ifdef __GNUC__
+ __asm__ __volatile__("cli");
+#else
+ asm("cli");
+#endif /* __GNUC__ */
+#endif /* __mips__ */
+
+ return(TRUE);
+}
+
+void
+xf86EnableInterrupts()
+{
+
+#if !defined(__mips__) && !defined(__arm32__)
+#ifdef __GNUC__
+ __asm__ __volatile__("sti");
+#else
+ asm("sti");
+#endif /* __GNUC__ */
+#endif /* __mips__ */
+
+ return;
+}
+
+#ifdef __NetBSD__
+/***************************************************************************/
+/* Set TV output mode */
+/***************************************************************************/
+void
+xf86SetTVOut(int mode)
+{
+ switch (xf86Info.consType)
+ {
+#ifdef PCCONS_SUPPORT
+ case PCCONS:{
+
+ if (ioctl (xf86Info.consoleFd, CONSOLE_X_TV_ON, &mode) < 0)
+ {
+ xf86Msg(X_WARNING,
+ "xf86SetTVOut: Could not set console to TV output, %s\n",
+ strerror(errno));
+ }
+ }
+ break;
+#endif /* PCCONS_SUPPORT */
+
+ default:
+ FatalError("Xf86SetTVOut: Unsupported console\n");
+ break;
+ }
+ return;
+}
+
+void
+xf86SetRGBOut()
+{
+ switch (xf86Info.consType)
+ {
+#ifdef PCCONS_SUPPORT
+ case PCCONS:{
+
+ if (ioctl (xf86Info.consoleFd, CONSOLE_X_TV_OFF, 0) < 0)
+ {
+ xf86Msg(X_WARNING,
+ "xf86SetTVOut: Could not set console to RGB output, %s\n",
+ strerror(errno));
+ }
+ }
+ break;
+#endif /* PCCONS_SUPPORT */
+
+ default:
+ FatalError("Xf86SetTVOut: Unsupported console\n");
+ break;
+ }
+ return;
+}
+#endif
+
+
+#if 0
+/*
+ * XXX This is here for reference. It needs to be handled differently for the
+ * ND.
+ */
+#if defined(USE_ARC_MMAP) || defined(__arm32__)
+
+#ifdef USE_ARM32_MMAP
+#define DEV_MEM_IOBASE 0x43000000
+#endif
+
+static Bool ScreenEnabled[MAXSCREENS];
+static Bool ExtendedEnabled = FALSE;
+static Bool InitDone = FALSE;
+
+void
+xf86EnableIOPorts(ScreenNum)
+int ScreenNum;
+{
+ int i;
+ int fd;
+ pointer base;
+
+#ifdef __arm32__
+ struct memAccess *memInfoP;
+ int *Size;
+#endif
+
+ ScreenEnabled[ScreenNum] = TRUE;
+
+ if (ExtendedEnabled)
+ return;
+
+#ifdef USE_ARC_MMAP
+ if ((fd = open("/dev/ttyC0", O_RDWR)) >= 0) {
+ /* Try to map a page at the pccons I/O space */
+ base = (pointer)mmap((caddr_t)0, 65536, PROT_READ|PROT_WRITE,
+ MAP_FLAGS, fd, (off_t)0x0000);
+
+ if (base != (pointer)-1) {
+ IOPortBase = base;
+ }
+ else {
+ xf86Msg(X_ERROR,
+ "EnableIOPorts: failed to mmap %s (%s)\n",
+ "/dev/ttyC0", strerror(errno));
+ }
+ }
+ else {
+ xf86Msg(X_ERROR, "EnableIOPorts: failed to open %s (%s)\n",
+ "/dev/ttyC0", strerror(errno));
+ }
+#endif
+
+#ifdef __arm32__
+ IOPortBase = (unsigned int)-1;
+
+ if((memInfoP = checkMapInfo(TRUE, MMIO_REGION)) != NULL)
+ {
+ /*
+ * xf86MapInfoMap maps an offset from the start of video IO
+ * space (e.g. 0x3B0), but IOPortBase is expected to map to
+ * physical address 0x000, so subtract the start of video I/O
+ * space from the result. This is safe for now becase we
+ * actually mmap the start of the page, then the start of video
+ * I/O space is added as an internal offset.
+ */
+ IOPortBase = (unsigned int)xf86MapInfoMap(memInfoP,
+ (caddr_t)0x0, 0L)
+ - memInfoP->memInfo.u.map_info_mmap.internal_offset;
+ ExtendedEnabled = TRUE;
+ return;
+ }
+#ifdef USE_ARM32_MMAP
+ checkDevMem(TRUE);
+
+ if (devMemFd >= 0 && useDevMem)
+ {
+ base = (pointer)mmap((caddr_t)0, 0x400, PROT_READ|PROT_WRITE,
+ MAP_FLAGS, devMemFd, (off_t)DEV_MEM_IOBASE);
+
+ if (base != (pointer)-1)
+ IOPortBase = (unsigned int)base;
+ }
+
+ if (IOPortBase == (unsigned int)-1)
+ {
+ FatalError("xf86EnableIOPorts: failed to open mem device or map IO base. \n\
+Make sure you have the Aperture Driver installed, or a kernel built with the INSECURE option\n");
+ }
+#else
+ /* We don't have the IOBASE, so we can't map the address */
+ FatalError("xf86EnableIOPorts: failed to open mem device or map IO base. \n\
+Try building the server with USE_ARM32_MMAP defined\n");
+#endif
+#endif
+
+ ExtendedEnabled = TRUE;
+
+ return;
+}
+
+void
+xf86DisableIOPorts(ScreenNum)
+int ScreenNum;
+{
+ int i;
+#ifdef __arm32__
+ struct memAccess *memInfoP;
+#endif
+
+ ScreenEnabled[ScreenNum] = FALSE;
+
+#ifdef __arm32__
+ if((memInfoP = checkMapInfo(FALSE, MMIO_REGION)) != NULL)
+ {
+ xf86MapInfoUnmap(memInfoP, 0);
+ }
+#endif
+
+#ifdef USE_ARM32_MMAP
+ if (!ExtendedEnabled)
+ return;
+
+ for (i = 0; i < MAXSCREENS; i++)
+ if (ScreenEnabled[i])
+ return;
+
+ munmap((caddr_t)IOPortBase, 0x400);
+ IOPortBase = (unsigned int)-1;
+ ExtendedEnabled = FALSE;
+#endif
+
+ return;
+}
+
+#endif /* USE_ARC_MMAP || USE_ARM32_MMAP */
+#endif
+
+
+#ifdef HAS_MTRR_SUPPORT
+/* memory range (MTRR) support for FreeBSD */
+
+/*
+ * This code is experimental. Some parts may be overkill, and other parts
+ * may be incomplete.
+ */
+
+/*
+ * getAllRanges returns the full list of memory ranges with attributes set.
+ */
+
+static struct mem_range_desc *
+getAllRanges(int *nmr)
+{
+ struct mem_range_desc *mrd;
+ struct mem_range_op mro;
+
+ /*
+ * Find how many ranges there are. If this fails, then the kernel
+ * probably doesn't have MTRR support.
+ */
+ mro.mo_arg[0] = 0;
+ if (ioctl(devMemFd, MEMRANGE_GET, &mro))
+ return NULL;
+ *nmr = mro.mo_arg[0];
+ mrd = xnfalloc(*nmr * sizeof(struct mem_range_desc));
+ mro.mo_arg[0] = *nmr;
+ mro.mo_desc = mrd;
+ if (ioctl(devMemFd, MEMRANGE_GET, &mro)) {
+ xfree(mrd);
+ return NULL;
+ }
+ return mrd;
+}
+
+/*
+ * cleanMTRR removes any memory attribute that may be left by a previous
+ * X server. Normally there won't be any, but this takes care of the
+ * case where a server crashed without being able finish cleaning up.
+ */
+
+static Bool
+cleanMTRR()
+{
+ struct mem_range_desc *mrd;
+ struct mem_range_op mro;
+ int nmr, i;
+
+ /* This shouldn't happen */
+ if (devMemFd < 0)
+ return FALSE;
+
+ if (!(mrd = getAllRanges(&nmr)))
+ return FALSE;
+
+ for (i = 0; i < nmr; i++) {
+ if (strcmp(mrd[i].mr_owner, X_MTRR_ID) == 0 &&
+ (mrd[i].mr_flags & MDF_ACTIVE)) {
+#ifdef DEBUG
+ ErrorF("Clean for (0x%lx,0x%lx)\n",
+ (unsigned long)mrd[i].mr_base,
+ (unsigned long)rd[i].mr_len);
+#endif
+ if (mrd[i].mr_flags & MDF_FIXACTIVE) {
+ mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
+ mrd[i].mr_flags = MDF_UNCACHEABLE;
+ } else {
+ mro.mo_arg[0] = MEMRANGE_SET_REMOVE;
+ }
+ mro.mo_desc = mrd + i;
+ ioctl(devMemFd, MEMRANGE_SET, &mro);
+ }
+ }
+#ifdef DEBUG
+ sleep(10);
+#endif
+ xfree(mrd);
+ return TRUE;
+}
+
+typedef struct x_RangeRec {
+ struct mem_range_desc mrd;
+ Bool wasWC;
+ struct x_RangeRec * next;
+} RangeRec, *RangePtr;
+
+static void
+freeRangeList(RangePtr range)
+{
+ RangePtr rp;
+
+ while (range) {
+ rp = range;
+ range = rp->next;
+ xfree(rp);
+ }
+}
+
+static RangePtr
+dupRangeList(RangePtr list)
+{
+ RangePtr new = NULL, rp, p;
+
+ rp = list;
+ while (rp) {
+ p = xnfalloc(sizeof(RangeRec));
+ *p = *rp;
+ p->next = new;
+ new = p;
+ rp = rp->next;
+ }
+ return new;
+}
+
+static RangePtr
+sortRangeList(RangePtr list)
+{
+ RangePtr rp1, rp2, copy, sorted = NULL, minp, prev, minprev;
+ unsigned long minBase;
+
+ /* Sort by base address */
+ rp1 = copy = dupRangeList(list);
+ while (rp1) {
+ minBase = rp1->mrd.mr_base;
+ minp = rp1;
+ minprev = NULL;
+ prev = rp1;
+ rp2 = rp1->next;
+ while (rp2) {
+ if (rp2->mrd.mr_base < minBase) {
+ minBase = rp2->mrd.mr_base;
+ minp = rp2;
+ minprev = prev;
+ }
+ prev = rp2;
+ rp2 = rp2->next;
+ }
+ if (minprev) {
+ minprev->next = minp->next;
+ rp1 = copy;
+ } else {
+ rp1 = minp->next;
+ }
+ minp->next = sorted;
+ sorted = minp;
+ }
+ return sorted;
+}
+
+/*
+ * findRanges returns a list of ranges that overlap the specified range.
+ */
+
+static void
+findRanges(unsigned long base, unsigned long size, RangePtr *ucp, RangePtr *wcp)
+{
+ struct mem_range_desc *mrd;
+ int nmr, i;
+ RangePtr rp, *p;
+
+ if (!(mrd = getAllRanges(&nmr)))
+ return;
+
+ for (i = 0; i < nmr; i++) {
+ if ((mrd[i].mr_flags & MDF_ACTIVE) &&
+ mrd[i].mr_base < base + size &&
+ mrd[i].mr_base + mrd[i].mr_len > base) {
+ if (mrd[i].mr_flags & MDF_WRITECOMBINE)
+ p = wcp;
+ else if (mrd[i].mr_flags & MDF_UNCACHEABLE)
+ p = ucp;
+ else
+ continue;
+ rp = xnfalloc(sizeof(RangeRec));
+ rp->mrd = mrd[i];
+ rp->next = *p;
+ *p = rp;
+ }
+ }
+ xfree(mrd);
+}
+
+/*
+ * This checks if the existing overlapping ranges fully cover the requested
+ * range. Is this overkill?
+ */
+
+static Bool
+fullCoverage(unsigned long base, unsigned long size, RangePtr overlap)
+{
+ RangePtr rp1, sorted = NULL;
+ unsigned long end;
+
+ sorted = sortRangeList(overlap);
+ /* Look for gaps */
+ rp1 = sorted;
+ end = base + size;
+ while (rp1) {
+ if (rp1->mrd.mr_base > base) {
+ freeRangeList(sorted);
+ return FALSE;
+ } else {
+ base = rp1->mrd.mr_base + rp1->mrd.mr_len;
+ }
+ if (base >= end) {
+ freeRangeList(sorted);
+ return TRUE;
+ }
+ rp1 = rp1->next;
+ }
+ freeRangeList(sorted);
+ return FALSE;
+}
+
+static pointer
+addWC(int screenNum, unsigned long base, unsigned long size, MessageType from)
+{
+ RangePtr uc = NULL, wc = NULL, retlist = NULL;
+ struct mem_range_desc mrd;
+ struct mem_range_op mro;
+
+ findRanges(base, size, &uc, &wc);
+
+ /* See of the full range is already WC */
+ if (!uc && fullCoverage(base, size, wc)) {
+ xf86DrvMsg(screenNum, from,
+ "Write-combining range (0x%lx,0x%lx) was already set\n",
+ base, size);
+ return NULL;
+ }
+
+ /* Otherwise, try to add the new range */
+ mrd.mr_base = base;
+ mrd.mr_len = size;
+ strcpy(mrd.mr_owner, X_MTRR_ID);
+ mrd.mr_flags = MDF_WRITECOMBINE;
+ mro.mo_desc = &mrd;
+ mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
+ if (ioctl(devMemFd, MEMRANGE_SET, &mro)) {
+ xf86DrvMsg(screenNum, X_WARNING,
+ "Failed to set write-combining range "
+ "(0x%lx,0x%lx)\n", base, size);
+ return NULL;
+ } else {
+ xf86DrvMsg(screenNum, from,
+ "Write-combining range (0x%lx,0x%lx)\n", base, size);
+ retlist = xnfalloc(sizeof(RangeRec));
+ retlist->mrd = mrd;
+ retlist->wasWC = FALSE;
+ retlist->next = NULL;
+ return retlist;
+ }
+}
+
+static pointer
+delWC(int screenNum, unsigned long base, unsigned long size, MessageType from)
+{
+ RangePtr uc = NULL, wc = NULL, retlist = NULL;
+ struct mem_range_desc mrd;
+ struct mem_range_op mro;
+
+ findRanges(base, size, &uc, &wc);
+
+ /*
+ * See of the full range is already not WC, or if there is full
+ * coverage from UC ranges.
+ */
+ if (!wc || fullCoverage(base, size, uc)) {
+ xf86DrvMsg(screenNum, from,
+ "Write-combining range (0x%lx,0x%lx) was already clear\n",
+ base, size);
+ return NULL;
+ }
+
+ /* Otherwise, try to add the new range */
+ mrd.mr_base = base;
+ mrd.mr_len = size;
+ strcpy(mrd.mr_owner, X_MTRR_ID);
+ mrd.mr_flags = MDF_UNCACHEABLE;
+ mro.mo_desc = &mrd;
+ mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
+ if (ioctl(devMemFd, MEMRANGE_SET, &mro)) {
+ xf86DrvMsg(screenNum, X_WARNING,
+ "Failed to remove write-combining range "
+ "(0x%lx,0x%lx)\n", base, size);
+ /* XXX Should then remove all of the overlapping WC ranges */
+ return NULL;
+ } else {
+ xf86DrvMsg(screenNum, from,
+ "Removed Write-combining range (0x%lx,0x%lx)\n",
+ base, size);
+ retlist = xnfalloc(sizeof(RangeRec));
+ retlist->mrd = mrd;
+ retlist->wasWC = TRUE;
+ retlist->next = NULL;
+ return retlist;
+ }
+}
+
+static pointer
+setWC(int screenNum, unsigned long base, unsigned long size, Bool enable,
+ MessageType from)
+{
+ if (enable)
+ return addWC(screenNum, base, size, from);
+ else
+ return delWC(screenNum, base, size, from);
+}
+
+static void
+undoWC(int screenNum, pointer list)
+{
+ RangePtr rp;
+ struct mem_range_op mro;
+ Bool failed;
+
+ rp = list;
+ while (rp) {
+#ifdef DEBUG
+ ErrorF("Undo for (0x%lx,0x%lx), %d\n",
+ (unsigned long)rp->mrd.mr_base,
+ (unsigned long)rp->mrd.mr_len, rp->wasWC);
+#endif
+ failed = FALSE;
+ if (rp->wasWC) {
+ mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
+ rp->mrd.mr_flags = MDF_WRITECOMBINE;
+ strcpy(rp->mrd.mr_owner, "unknown");
+ } else {
+ mro.mo_arg[0] = MEMRANGE_SET_REMOVE;
+ }
+ mro.mo_desc = &rp->mrd;
+
+ if (ioctl(devMemFd, MEMRANGE_SET, &mro)) {
+ if (!rp->wasWC) {
+ mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
+ rp->mrd.mr_flags = MDF_UNCACHEABLE;
+ strcpy(rp->mrd.mr_owner, "unknown");
+ if (ioctl(devMemFd, MEMRANGE_SET, &mro))
+ failed = TRUE;
+ } else
+ failed = TRUE;
+ }
+ if (failed) {
+ xf86DrvMsg(screenNum, X_WARNING,
+ "Failed to restore MTRR range (0x%lx,0x%lx)\n",
+ (unsigned long)rp->mrd.mr_base,
+ (unsigned long)rp->mrd.mr_len);
+ }
+ rp = rp->next;
+ }
+}
+
+#endif /* HAS_MTRR_SUPPORT */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsdi/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/bsdi/Imakefile
new file mode 100644
index 000000000..f30431d12
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsdi/Imakefile
@@ -0,0 +1,49 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsdi/Imakefile,v 3.6 1999/05/22 08:40:08 dawes Exp $
+
+
+
+
+XCOMM $XConsortium: Imakefile /main/4 1996/09/28 17:23:38 rws $
+
+#include <Server.tmpl>
+
+#if NewInput
+MOUSESRC = bsdi_mouse.c
+MOUSEOBJ = bsdi_mouse.o
+#else
+MOUSESRC = std_mouse.c std_mseEv.c
+MOUSEOBJ = std_mouse.o std_mseEv.o
+#endif
+
+SRCS = bsdi_init.c bsdi_video.c bsdi_io.c bios_devmem.c \
+ mapVT_noop.c VTsw_noop.c std_kbdEv.c posix_tty.c $(MOUSESRC) \
+ libc_wrapper.c stdResource.c
+
+OBJS = bsdi_init.o bsdi_video.o bsdi_io.o bios_devmem.o \
+ mapVT_noop.o VTsw_noop.o std_kbdEv.o posix_tty.o $(MOUSEOBJ) \
+ libc_wrapper.o stdResource.o
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+RESDEFINES = -DUSESTDRES
+
+DEFINES = $(RESDEFINES)
+
+SubdirLibraryRule($(OBJS))
+NormalLibraryObjectRule()
+
+LinkSourceFile(bios_devmem.c,../shared)
+LinkSourceFile(mapVT_noop.c,../shared)
+LinkSourceFile(VTsw_noop.c,../shared)
+LinkSourceFile(std_kbdEv.c,../shared)
+LinkSourceFile(posix_tty.c,../shared)
+#if !NewInput
+LinkSourceFile(std_mouse.c,../shared)
+LinkSourceFile(std_mseEv.c,../shared)
+#endif
+LinkSourceFile(libc_wrapper.c,../shared)
+LinkSourceFile(stdResource.c,../shared)
+
+DependTarget()
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_init.c b/xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_init.c
new file mode 100644
index 000000000..61e1b7c3e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_init.c
@@ -0,0 +1,152 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_init.c,v 3.6 1998/07/25 16:56:38 dawes Exp $ */
+/*
+ * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Rich Murphey and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Rich Murphey and
+ * David Wexelblat make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RICH MURPHEY OR DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: bsdi_init.c /main/5 1996/02/21 17:51:15 kaleb $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "compiler.h"
+
+#include <sys/param.h>
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+extern Bool RunFromSmartParent;
+
+static Bool KeepTty = FALSE;
+
+#if BSD >= 199306
+static void
+NonBlockConsoleOff()
+{
+ register int i;
+
+ i = fcntl(2, F_GETFL, 0);
+ if (i >= 0)
+ (void) fcntl(2, F_SETFL, i & ~FNDELAY);
+}
+#endif
+
+void
+xf86OpenConsole()
+{
+ int i, fd;
+
+ if (serverGeneration == 1)
+ {
+ /* check if we're run with euid==0 */
+ if (geteuid() != 0)
+ {
+ FatalError("xf86OpenConsole: Server must be suid root\n");
+ }
+
+ if (!KeepTty)
+ {
+#if BSD >= 199306
+ if (RunFromSmartParent) {
+ if (atexit(NonBlockConsoleOff))
+ xf86Msg(X_WARNING,
+ "InitOutput: can't register NBIO exit handler\n");
+ i = fcntl(2, F_GETFL, 0);
+ if (i >= 0)
+ i = fcntl(2, F_SETFL, i | FNDELAY);
+ if (i < 0)
+ xf86Msg(X_WARNING,
+ "InitOutput: can't put stderr in non-block mode\n");
+ }
+#else
+ /*
+ * detaching the controlling tty solves problems of kbd character
+ * loss. This is not interesting for CO driver, because it is
+ * exclusive.
+ */
+ setpgrp(0, getpid());
+ if ((i = open("/dev/tty",O_RDWR)) >= 0)
+ {
+ ioctl(i,TIOCNOTTY,(char *)0);
+ close(i);
+ }
+#endif
+ }
+
+ if ((xf86Info.consoleFd = open("/dev/kbd", O_RDWR|O_NDELAY,0)) < 0)
+ {
+ FatalError("xf86OpenConsole: Cannot open /dev/kbd (%s)\n",
+ strerror(errno));
+ }
+ if ((xf86Info.screenFd = open("/dev/vga", O_RDWR|O_NDELAY,0)) < 0)
+ {
+ FatalError("xf86OpenConsole: Cannot open /dev/vga (%s)\n",
+ strerror(errno));
+ }
+
+ if (ioctl(xf86Info.consoleFd, PCCONIOCRAW, 0) < 0)
+ {
+ FatalError("%s: PCCONIOCRAW failed (%s)\n",
+ "xf86OpenConsole", strerror(errno));
+ }
+ }
+ return;
+}
+
+void
+xf86CloseConsole()
+{
+ ioctl (xf86Info.consoleFd, PCCONIOCCOOK, 0);
+
+ if (xf86Info.screenFd != xf86Info.consoleFd)
+ {
+ close(xf86Info.screenFd);
+ }
+ close(xf86Info.consoleFd);
+ return;
+}
+
+int
+xf86ProcessArgument (int argc, char *argv[], int i)
+{
+ /*
+ * Keep server from detaching from controlling tty. This is useful
+ * when debugging (so the server can receive keyboard signals.
+ */
+ if (!strcmp(argv[i], "-keeptty"))
+ {
+ KeepTty = TRUE;
+ return(1);
+ }
+ return(0);
+}
+
+void
+xf86UseMsg()
+{
+ ErrorF("-keeptty ");
+ ErrorF("don't detach controlling tty (for debugging only)\n");
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_io.c b/xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_io.c
new file mode 100644
index 000000000..62a1d1ada
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_io.c
@@ -0,0 +1,128 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_io.c,v 3.11 1999/05/22 08:40:10 dawes Exp $ */
+/*
+ * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Rich Murphey and David Dawes
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Rich Murphey and
+ * David Dawes make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * RICH MURPHEY AND DAVID DAWES DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RICH MURPHEY OR DAVID DAWES 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.
+ *
+ */
+/* $XConsortium: bsdi_io.c /main/10 1996/10/19 18:06:13 kaleb $ */
+
+#include "X.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+void
+xf86SoundKbdBell(int loudness, int pitch, int duration)
+{
+ if (loudness && pitch)
+ {
+ int data[2];
+
+ data[0] = pitch;
+ data[1] = (duration * loudness) / 50;
+ ioctl(xf86Info.consoleFd, PCCONIOCBEEP, data);
+ }
+}
+
+void
+xf86SetKbdLeds(int leds)
+{
+ ioctl(xf86Info.consoleFd, PCCONIOCSETLED, &leds);
+}
+
+int
+xf86GetKbdLeds()
+{
+ return(0);
+}
+
+void
+xf86SetKbdRepeat(char rad)
+{
+ return;
+}
+
+static struct termio kbdtty;
+
+void
+xf86KbdInit()
+{
+ tcgetattr(xf86Info.consoleFd, &kbdtty);
+}
+
+int
+xf86KbdOn()
+{
+ struct termios nTty;
+
+ nTty = kbdtty;
+ nTty.c_iflag = IGNPAR | IGNBRK;
+ nTty.c_oflag = 0;
+ nTty.c_cflag = CREAD | CS8;
+ nTty.c_lflag = 0;
+ nTty.c_cc[VTIME] = 0;
+ nTty.c_cc[VMIN] = 1;
+ cfsetispeed(&nTty, 9600);
+ cfsetospeed(&nTty, 9600);
+ tcsetattr(xf86Info.consoleFd, TCSANOW, &nTty);
+ return(xf86Info.consoleFd);
+}
+
+int
+xf86KbdOff()
+{
+ tcsetattr(xf86Info.consoleFd, TCSANOW, &kbdtty);
+ return(xf86Info.consoleFd);
+}
+
+#ifndef NEW_INPUT
+void
+xf86MouseInit(MouseDevPtr mouse)
+{
+ return;
+}
+
+int
+xf86MouseOn(MouseDevPtr mouse)
+{
+ if ((mouse->mseFd = open(mouse->mseDevice, O_RDWR | O_NDELAY)) < 0)
+ {
+ if (xf86Info.allowMouseOpenFail) {
+ xf86Msg(X_WARNING,
+ "Cannot open mouse (%s) - Continuing...\n",
+ strerror(errno));
+ return(-2);
+ }
+ FatalError("Cannot open mouse (%s)\n", strerror(errno));
+ }
+
+ xf86SetupMouse(mouse);
+
+ /* Flush any pending input */
+ tcflush(mouse->mseFd, TCIFLUSH);
+
+ return(mouse->mseFd);
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_mouse.c b/xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_mouse.c
new file mode 100644
index 000000000..23afd09dc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_mouse.c
@@ -0,0 +1,30 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_mouse.c,v 1.1 1999/05/22 08:40:10 dawes Exp $ */
+
+/*
+ * Copyright 1999 by The XFree86 Project, Inc.
+ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Xinput.h"
+#include "xf86OSmouse.h"
+
+static int
+SupportedInterfaces(void)
+{
+ /* XXX This needs to be checked. */
+ return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO;
+}
+
+OSMouseInfoPtr
+xf86OSMouseInit(int flags)
+{
+ OSMouseInfoPtr p;
+
+ p = xcalloc(sizeof(OSMouseInfoRec), 1);
+ if (!p)
+ return NULL;
+ p->SupportedInterfaces = SupportedInterfaces;
+ return p;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_video.c b/xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_video.c
new file mode 100644
index 000000000..f578f8c38
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_video.c
@@ -0,0 +1,175 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsdi/bsdi_video.c,v 3.8 1999/04/29 12:24:51 dawes Exp $ */
+/*
+ * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Rich Murphey and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Rich Murphey and
+ * David Wexelblat make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RICH MURPHEY OR DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: bsdi_video.c /main/4 1996/02/21 17:51:22 kaleb $ */
+
+#include "X.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+/***************************************************************************/
+/* Video Memory Mapping section */
+/***************************************************************************/
+
+pointer
+xf86MapVidMem(int ScreenNum, int Flags, unsigned long Base, unsigned long Size)
+{
+ pointer base;
+
+ if (Base >= 0xA0000)
+ {
+ base = mmap(0, Size, PROT_READ|PROT_WRITE, MAP_FILE,
+ xf86Info.screenFd,
+ Base - 0xA0000);
+ if (base == MAP_FAILED)
+ {
+ FatalError("xf86MapVidMem: Could not mmap /dev/vga (%s)\n",
+ strerror(errno));
+ }
+ return(base);
+ }
+ else /* Base < 0xA0000 */
+ {
+ FatalError("xf86MapVidMem: cannot mmap /dev/vga below 0xA0000\n");
+ }
+}
+
+void
+xf86UnMapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+{
+ munmap((caddr_t)Base, Size);
+}
+
+Bool
+xf86LinearVidMem()
+{
+ return(TRUE);
+}
+
+/***************************************************************************/
+/* I/O Permissions section */
+/***************************************************************************/
+
+/*
+ * BSDI has a single system-wide TSS I/O bitmap that covers ports up to
+ * 0xFFFF. By default, the TSS has ports 0x3B0-0x3DF enabled.
+ *
+ * It also allows the IOPL to be enabled or disabled on a per-process
+ * basis. Here, we use the IOPL only.
+ */
+
+static Bool ExtendedEnabled = FALSE;
+
+void
+xf86EnableIO()
+{
+ if (ExtendedEnabled)
+ return;
+
+ if (ioctl(xf86Info.consoleFd, PCCONENABIOPL, 0) < 0)
+ {
+ FatalError("%s: Failed to set IOPL for extended I/O\n",
+ "xf86EnableIOPorts");
+ }
+ ExtendedEnabled = TRUE;
+}
+
+void
+xf86DisableIO()
+{
+ if (!ExtendedEnabled)
+ return;
+
+ ioctl(xf86Info.consoleFd, PCCONDISABIOPL, 0);
+ ExtendedEnabled = FALSE;
+}
+
+
+/***************************************************************************/
+/* Interrupt Handling section */
+/***************************************************************************/
+
+Bool
+xf86DisableInterrupts()
+{
+ if (!ExtendedEnabled)
+ {
+ if (ioctl(xf86Info.consoleFd, PCCONENABIOPL, 0) < 0)
+ {
+ return(FALSE);
+ }
+ }
+
+#ifdef __GNUC__
+ __asm__ __volatile__("cli");
+#else
+ asm("cli");
+#endif /* __GNUC__ */
+
+ if (!ExtendedEnabled)
+ {
+ ioctl(xf86Info.consoleFd, PCCONDISABIOPL, 0);
+ }
+
+ return(TRUE);
+}
+
+void
+xf86EnableInterrupts()
+{
+ if (!ExtendedEnabled)
+ {
+ ioctl(xf86Info.consoleFd, PCCONENABIOPL, 0);
+ }
+
+#ifdef __GNUC__
+ __asm__ __volatile__("sti");
+#else
+ asm("sti");
+#endif /* __GNUC__ */
+
+ if (!ExtendedEnabled)
+ {
+ ioctl(xf86Info.consoleFd, PCCONDISABIOPL, 0);
+ }
+
+ return;
+}
+
+
+void
+xf86MapReadSideEffects(int ScreenNum, int Flags, pointer Base,
+ unsigned long Size)
+{
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bus/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/bus/Imakefile
new file mode 100644
index 000000000..8a328d752
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bus/Imakefile
@@ -0,0 +1,61 @@
+XCOMM $XConsortium: Imakefile /main/16 1996/10/27 18:07:43 kaleb $
+
+
+
+
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/Imakefile,v 1.6 1999/04/17 09:08:42 dawes Exp $
+
+#include <Server.tmpl>
+
+#if defined(LinuxArchitecture) && defined(AlphaArchitecture)
+
+XCOMM Alpha (Linux) PCI driver
+
+PCIDRVRSRC = axpPci.c
+PCIDRVROBJ = axpPci.o
+
+#elif defined(LinuxArchitecture) && defined(SparcArchitecture)
+
+XCOMM Sparc (Linux) PCI driver
+
+PCIDRVRSRC = sparcPci.c
+PCIDRVROBJ = sparcPci.o
+
+#elif defined(LinuxArchitecture) && defined(PpcArchitecture)
+
+XCOMM generic linux PCI driver (using /proc/bus/pci, requires kernel 2.2)
+
+PCIDRVRSRC = linuxPci.c
+PCIDRVROBJ = linuxPci.o
+
+#elif defined(PpcArchitecture)
+
+XCOMM PowerPC PCI drivers
+
+PCIDRVRSRC = ppcPci.c
+PCIDRVROBJ = ppcPci.o
+
+#elif defined(i386Architecture)
+
+XCOMM ix86 PCI driver
+
+PCIDRVRSRC = ix86Pci.c
+PCIDRVROBJ = ix86Pci.o
+XCOMM PCIDRVRSRC = linuxPci.c
+XCOMM PCIDRVROBJ = linuxPci.o
+
+#else
+XCOMM no PCI driver -- shouldn't get here
+#endif
+
+SRCS = Pci.c $(PCIDRVRSRC)
+OBJS = Pci.o $(PCIDRVROBJ)
+
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC)
+
+NormalLibraryObjectRule()
+SubdirLibraryRule($(OBJS))
+
+DependTarget()
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c b/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c
new file mode 100644
index 000000000..394b69e4f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c
@@ -0,0 +1,1081 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c,v 1.22 1999/08/21 13:48:40 dawes Exp $ */
+/*
+ * Pci.c - New server PCI access functions
+ *
+ * The XFree86 server PCI access functions have been reimplemented as a
+ * framework that allows each supported platform/OS to have their own
+ * platform/OS specific pci driver.
+ *
+ * All of the public PCI access functions exported to the other parts of
+ * the server are declared in Pci.h and defined herein. These include:
+ * pciInit() - Initialize PCI access functions
+ * pciFindFirst() - Find a PCI device by dev/vend id
+ * pciFindNext() - Find another PCI device by dev/vend id
+ * pciReadLong() - Read a 32 bit value from a PCI devices cfg space
+ * pciReadWord() - Read a 16 bit value from a PCI devices cfg space
+ * pciReadByte() - Read an 8 bit value from a PCI devices cfg space
+ * pciWriteLong() - Write a 32 bit value to a PCI devices cfg space
+ * pciWriteWord() - Write a 16 bit value to a PCI devices cfg space
+ * pciWriteByte() - Write an 8 bit value to a PCI devices cfg space
+ * pciSetBitsLong() - Write a 32 bit value against a mask
+ * pciSetBitsByte() - Write an 8 bit value against a mask
+ * pciLongFunc() - Return pointer to the requested low level function
+ * pciTag() - Return tag for a given PCI bus, device, & function
+ * pciBusAddrToHostAddr() - Convert a PCI address to a host address
+ * pciHostAddrToBusAddr() - Convert a host address to a PCI address
+ * pciGetBaseSize - Returns the number of bits in a PCI base addr mapping
+ * xf86MapPciMem() - Like xf86MapVidMem() expect function expects
+ * a PCI address and PCITAG (identifies PCI domain)
+ * xf86ReadPciBIOS() - Like xf86ReadBIOS, except that it handles PCI/host
+ * address translation and BIOS decode enabling.
+ * xf86scanpci() - Return info about all PCI devices
+ *
+ * The actual PCI backend driver is selected by the pciInit() function
+ * (see below) using either compile time definitions, run-time checks,
+ * or both.
+ *
+ * Certain generic functions are provided that make the implementation
+ * of certain well behaved platforms (e.g. those supporting PCI config
+ * mechanism 1 or some thing close to it) very easy.
+ *
+ * Less well behaved platforms/OS's can roll their own functions.
+ *
+ * To add support for another platform/OS, add a call to fooPciInit() within
+ * pciInit() below under the correct compile time definition or run-time
+ * conditional.
+ *
+ *
+ * The fooPciInit() procedure must do three things:
+ * 1) Initialize the pciBusTable[] for all primary PCI buses including
+ * the per domain PCI access functions (readLong, writeLong,
+ * addrBusToHost, and addrHostToBus).
+ *
+ * 2) Add entries to pciBusTable[] for configured secondary buses. This
+ * step may be skipped if a platform is using the generic findFirst/
+ * findNext functions because these procedures will automatically
+ * discover and add secondary buses dynamically.
+ *
+ * 3) Overide default settings for global PCI access functions if
+ * required. These include pciFindFirstFP, pciFindNextFP,
+ * Of course, if you choose not to use one of the generic
+ * functions, you will need to provide a platform specifc replacement.
+ *
+ * See xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_pci.c for an example
+ * of how to extend this framework to other platforms/OSes.
+ *
+ * Gary Barton
+ * Concurrent Computer Corporation
+ * garyb@gate.net
+ *
+ */
+
+/*
+ * Copyright 1998 by Concurrent Computer Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Concurrent Computer
+ * Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Concurrent Computer Corporation makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Copyright 1998 by Metro Link Incorporated
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Metro Link
+ * Incorporated not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Metro Link Incorporated makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * This software is derived from the original XFree86 PCI code
+ * which includes the following copyright notices as well:
+ *
+ * Copyright 1995 by Robin Cutshaw <robin@XFree86.Org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of the above listed copyright holder(s)
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. The above listed
+ * copyright holder(s) make(s) no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * This code is also based heavily on the code in FreeBSD-current, which was
+ * written by Wolfgang Stanglmeier, and contains the following copyright:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <errno.h>
+#include <signal.h>
+#include "Xarch.h"
+#include "compiler.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSproc.h"
+#include "Pci.h"
+
+#define PCI_MFDEV_SUPPORT 1 /* Include PCI multifunction device support */
+#define PCI_BRIDGE_SUPPORT 1 /* Include support for PCI-to-PCI bridges */
+
+#ifdef PC98
+#define outb(port,data) _outb(port,data)
+#define outl(port,data) _outl(port,data)
+#define inb(port) _inb(port)
+#define inl(port) _inl(port)
+#endif
+
+/*
+ * Global data
+ */
+static int pciInitialized = 0;
+
+CARD32 pciDevid; /* Requested device/vendor ID (after mask) */
+CARD32 pciDevidMask; /* Bit mask applied (AND) before comparison */
+ /* of real devid's with requested */
+
+int pciBusNum; /* Bus Number of current device */
+int pciDevNum; /* Device number of current device */
+int pciFuncNum; /* Function number of current device */
+PCITAG pciDeviceTag; /* Tag for current device */
+
+pciBusFuncs_t pciNOOPFuncs = {
+ pciReadLongNULL,
+ pciWriteLongNULL,
+ pciSetBitsLongNULL,
+ pciAddrNOOP,
+ pciAddrNOOP
+};
+
+pciBusInfo_t *pciBusInfo[MAX_PCI_BUSES];
+int pciNumBuses = 0; /* Actual number of PCI buses */
+
+static pciConfigPtr pci_devp[MAX_PCI_DEVICES + 1] = {NULL, };
+#ifdef INCLUDE_LOCKPCI
+static pciConfigPtr pci_locked_devp[MAX_PCI_DEVICES + 1] = {NULL, };
+#endif
+
+/*
+ * Platform specific PCI function pointers.
+ *
+ * NOTE: A platform/OS specific pci init procedure can override these defaults
+ * by setting them to the appropriate platform dependent functions.
+ */
+PCITAG (*pciFindFirstFP)(void) = pciGenFindFirst;
+PCITAG (*pciFindNextFP)(void) = pciGenFindNext;
+
+/*
+ * pciInit - choose correct platform/OS specific PCI init routine
+ */
+void
+pciInit()
+{
+ if (pciInitialized)
+ return;
+
+ pciInitialized = 1;
+
+ /* XXX */
+#if defined(DEBUGPCI)
+ if (DEBUGPCI >= xf86Verbose)
+ xf86Verbose = DEBUGPCI;
+#endif
+
+ ARCH_PCI_INIT();
+}
+
+
+PCITAG
+pciFindFirst(CARD32 id, CARD32 mask)
+{
+#ifdef DEBUGPCI
+ErrorF("pciFindFirst(0x%lx, 0x%lx), pciInit = %d\n", id, mask, pciInitialized);
+#endif
+ if (!pciInitialized)
+ pciInit();
+
+ pciDevid = id & mask;
+ pciDevidMask = mask;
+
+ return((*pciFindFirstFP)());
+}
+
+PCITAG
+pciFindNext(void)
+{
+#ifdef DEBUGPCI
+ErrorF("pciFindNext(), pciInit = %d\n", pciInitialized);
+#endif
+ if (!pciInitialized)
+ pciInit();
+
+ return((*pciFindNextFP)());
+}
+
+CARD32
+pciReadLong(PCITAG tag, int offset)
+{
+ int bus = PCI_BUS_FROM_TAG(tag);
+
+#ifdef DEBUGPCI
+ErrorF("pciReadLong(0x%lx, %d)\n", tag, offset);
+#endif
+ if (!pciInitialized)
+ pciInit();
+
+ if (bus < pciNumBuses && pciBusInfo[bus] &&
+ pciBusInfo[bus]->funcs.pciReadLong) {
+ CARD32 rv = (*pciBusInfo[bus]->funcs.pciReadLong)(tag, offset);
+
+ PCITRACE(1, ("pciReadLong: tag=0x%x [b=%d,d=%d,f=%d] returns 0x%08x\n",
+ tag, bus, PCI_DEV_FROM_TAG(tag), PCI_FUNC_FROM_TAG(tag), rv));
+ return(rv);
+ }
+
+ return(PCI_NOT_FOUND);
+}
+
+CARD16
+pciReadWord(PCITAG tag, int offset)
+{
+ CARD32 tmp;
+ int shift = (offset & 3) * 8;
+ int aligned_offset = offset & ~3;
+
+ if (shift != 0 && shift != 16)
+ FatalError("pciReadWord: Alignment error: Cannot read 16 bits "
+ "at offset %d\n", offset);
+
+ tmp = pciReadLong(tag, aligned_offset);
+
+ return((CARD16)((tmp >> shift) & 0xffff));
+}
+
+CARD8
+pciReadByte(PCITAG tag, int offset)
+{
+ CARD32 tmp;
+ int shift = (offset & 3) * 8;
+ int aligned_offset = offset & ~3;
+
+ tmp = pciReadLong(tag, aligned_offset);
+
+ return((CARD8)((tmp >> shift) & 0xff));
+}
+
+void
+pciWriteLong(PCITAG tag, int offset, CARD32 val)
+{
+ int bus = PCI_BUS_FROM_TAG(tag);
+
+ if (!pciInitialized)
+ pciInit();
+
+ if (bus < pciNumBuses && pciBusInfo[bus] &&
+ pciBusInfo[bus]->funcs.pciWriteLong)
+ (*pciBusInfo[bus]->funcs.pciWriteLong)(tag, offset, val);
+}
+
+void
+pciWriteWord(PCITAG tag, int offset, CARD16 val)
+{
+ CARD32 tmp;
+ int aligned_offset = offset & ~3;
+ int shift = (offset & 3) * 8;
+
+ if (shift != 0 && shift != 16)
+ FatalError("pciWriteWord: Alignment Error: Cannot read 16 bits "
+ "from offset %d\n", offset);
+
+ tmp = pciReadLong(tag, aligned_offset);
+
+ tmp &= ~(0xffffL << shift);
+ tmp |= (((CARD32)val) << shift);
+
+ pciWriteLong(tag, aligned_offset, tmp);
+}
+
+void
+pciWriteByte(PCITAG tag, int offset, CARD8 val)
+{
+ CARD32 tmp;
+ int aligned_offset = offset & ~3;
+ int shift = (offset & 3) *8 ;
+
+ tmp = pciReadLong(tag, aligned_offset);
+
+ tmp &= ~(0xffL << shift);
+ tmp |= (((CARD32)val) << shift);
+
+ pciWriteLong(tag, aligned_offset, tmp);
+}
+
+void
+pciSetBitsLong(PCITAG tag, int offset, CARD32 mask, CARD32 val)
+{
+ int bus = PCI_BUS_FROM_TAG(tag);
+
+#ifdef DEBUGPCI
+ ErrorF("pciReadLong(0x%lx, %d)\n", tag, offset);
+#endif
+ if (!pciInitialized)
+ pciInit();
+
+ if (bus < pciNumBuses && pciBusInfo[bus] &&
+ pciBusInfo[bus]->funcs.pciReadLong) {
+ (*pciBusInfo[bus]->funcs.pciSetBitsLong)(tag, offset, mask, val);
+ }
+}
+
+void
+pciSetBitsByte(PCITAG tag, int offset, CARD8 mask, CARD8 val)
+{
+ CARD32 tmp_mask, tmp_val;
+ int aligned_offset = offset & ~3;
+ int shift = (offset & 3) *8 ;
+
+
+ tmp_mask = mask << shift;
+ tmp_val = val << shift;
+ pciSetBitsLong(tag, aligned_offset, tmp_mask, tmp_val);
+}
+
+pointer
+pciLongFunc(PCITAG tag, pciFunc func)
+{
+ int bus = PCI_BUS_FROM_TAG(tag);
+
+ if (!pciInitialized)
+ pciInit();
+
+ if (bus > pciNumBuses || !pciBusInfo[bus] ||
+ !pciBusInfo[bus]->funcs.pciReadLong) return NULL;
+
+ switch (func) {
+ case WRITE:
+ return (void *)pciBusInfo[bus]->funcs.pciWriteLong;
+ case READ:
+ return (void *)pciBusInfo[bus]->funcs.pciReadLong;
+ case SET_BITS:
+ return (void *)pciBusInfo[bus]->funcs.pciSetBitsLong;
+ }
+ return NULL;
+}
+
+ADDRESS
+pciBusAddrToHostAddr(PCITAG tag, ADDRESS addr)
+{
+ int bus = PCI_BUS_FROM_TAG(tag);
+
+ if (!pciInitialized)
+ pciInit();
+
+ if (bus < pciNumBuses && pciBusInfo[bus] &&
+ pciBusInfo[bus]->funcs.pciAddrBusToHost)
+ return (*pciBusInfo[bus]->funcs.pciAddrBusToHost)(tag, addr);
+ else
+ return(addr);
+}
+
+ADDRESS
+pciHostAddrToBusAddr(PCITAG tag, ADDRESS addr)
+{
+ int bus = PCI_BUS_FROM_TAG(tag);
+
+ if (!pciInitialized)
+ pciInit();
+
+ if (bus < pciNumBuses && pciBusInfo[bus] &&
+ pciBusInfo[bus]->funcs.pciAddrHostToBus)
+ return (*pciBusInfo[bus]->funcs.pciAddrHostToBus)(tag, addr);
+ else
+ return(addr);
+}
+
+
+/*
+ * pciGetBaseSize() returns the size of a PCI base address mapping in bits.
+ * The index identifies the base register: 0-5 are the six standard registers,
+ * and 6 is the ROM base register. If destructive is TRUE, it will write
+ * to the base address register to get an accurate result. Otherwise it
+ * makes a conservative guess based on the alignment of the already allocated
+ * address. If the result is accurate (ie, not an over-estimate), this is
+ * indicated by setting *min to TRUE (when min is non-NULL). This currently
+ * only happens when the destructive flag is set, but in future it may be
+ * possible to get the information from the OS when supported.
+ */
+
+int
+pciGetBaseSize(PCITAG tag, int index, Bool destructive, Bool *min)
+{
+ int offset;
+ CARD32 addr1;
+ CARD32 addr2;
+ CARD32 mask1;
+ CARD32 mask2;
+ int bits = 0;
+
+ /*
+ * Eventually a function for this should be added to pciBusFuncs_t, but for
+ * now we'll just use a simple method based on the alignment of the already
+ * allocated address.
+ */
+
+ /*
+ * silently ignore bogus index values. Valid values are 0-6. 0-5 are
+ * the 6 base address registers, and 6 is the ROM base address register.
+ */
+ if (index < 0 || index > 6)
+ return 0;
+
+ if (!pciInitialized)
+ pciInit();
+
+ if (min)
+ *min = destructive;
+
+ /* Get the PCI offset */
+ if (index == 6)
+ offset = PCI_MAP_ROM_REG;
+ else
+ offset = PCI_MAP_REG_START + (index << 2);
+
+ addr1 = pciReadLong(tag, offset);
+ /*
+ * Check if this is the second part of a 64 bit address.
+ * XXX need to check how endianness affects 64 bit addresses.
+ */
+ if (index > 0 && index < 6) {
+ addr2 = pciReadLong(tag, offset - 4);
+ if (PCI_MAP_IS_MEM(addr2) && PCI_MAP_IS64BITMEM(addr2))
+ return 0;
+ }
+
+ if (destructive) {
+ pciWriteLong(tag, offset, 0xffffffff);
+ mask1 = pciReadLong(tag, offset);
+ pciWriteLong(tag, offset, addr1);
+ } else {
+ mask1 = addr1;
+ }
+
+ /* Check if this is the first part of a 64 bit address. */
+ if (index < 5 && PCI_MAP_IS_MEM(mask1) && PCI_MAP_IS64BITMEM(mask1)) {
+ if (PCIGETMEMORY(mask1) == 0) {
+ addr2 = pciReadLong(tag, offset + 4);
+ if (destructive) {
+ pciWriteLong(tag, offset + 4, 0xffffffff);
+ mask2 = pciReadLong(tag, offset + 4);
+ pciWriteLong(tag, offset + 4, addr2);
+ } else {
+ mask2 = addr2;
+ }
+ if (mask2 == 0)
+ return 0;
+ bits = 32;
+ while ((mask2 & 1) == 0) {
+ bits++;
+ mask2 >>= 1;
+ }
+ return bits;
+ }
+ }
+ if (index < 6)
+ if (PCI_MAP_IS_MEM(mask1))
+ mask1 = PCIGETMEMORY(mask1);
+ else
+ mask1 = PCIGETIO(mask1);
+ else
+ mask1 = PCIGETROM(mask1);
+ if (mask1 == 0)
+ return 0;
+ bits = 0;
+ while ((mask1 & 1) == 0) {
+ bits++;
+ mask1 >>= 1;
+ }
+ /* I/O maps can be no larger than 8 bits */
+ if (PCI_MAP_IS_IO(addr1) && bits > 8)
+ bits = 8;
+ /* ROM maps can be no larger than 24 bits */
+ if (index == 6 && bits > 24)
+ bits = 24;
+ return bits;
+}
+
+PCITAG
+pciTag(int busnum, int devnum, int funcnum)
+{
+ return(PCI_MAKE_TAG(busnum,devnum,funcnum));
+}
+
+Bool
+pciMfDev(int busnum, int devnum)
+{
+ PCITAG tag0, tag1;
+ unsigned long id0, id1;
+
+ /* Detect a multi-function device that complies to the PCI 2.0 spec */
+
+ tag0 = PCI_MAKE_TAG(busnum, devnum, 0);
+ id0 = pciReadLong(tag0, PCI_ID_REG);
+ if (id0 == 0xffffffff)
+ return FALSE;
+
+ if (pciReadLong(tag0, PCI_HEADER_MISC) & PCI_HEADER_MULTIFUNCTION)
+ return TRUE;
+
+ /*
+ * Now, to find non-compliant devices...
+ * If there is a valid ID for function 1 and the ID for func 0 and 1
+ * are different, or the base0 values of func 0 and 1 are differend,
+ * then assume there is a multi-function device.
+ */
+ tag1 = PCI_MAKE_TAG(busnum, devnum, 1);
+ id1 = pciReadLong(tag1, PCI_ID_REG);
+ if (id1 == 0xffffffff || id1 == 0x00000000)
+ return FALSE;
+
+ if ((id0 != id1) ||
+ (pciReadLong(tag0, PCI_MAP_REG_START) !=
+ pciReadLong(tag1, PCI_MAP_REG_START)))
+ return TRUE;
+
+ return FALSE;
+}
+
+/*
+ * Generic find/read/write functions
+ */
+PCITAG
+pciGenFindNext(void)
+{
+ unsigned long devid, tmp;
+ unsigned char base_class, sub_class, sec_bus, pri_bus;
+
+#ifdef DEBUGPCI
+ErrorF("pciGenFindNext\n");
+#endif
+
+ for (;;) {
+
+#ifdef DEBUGPCI
+ErrorF("pciGenFindNext: pciBusNum %d\n", pciBusNum);
+#endif
+ if (pciBusNum == -1) {
+ /*
+ * Start at top of the order
+ */
+ if (pciNumBuses == 0)
+ return(PCI_NOT_FOUND);
+
+ pciBusNum = 0;
+ pciFuncNum = 0;
+ pciDevNum = 0;
+ }
+ else {
+#ifdef PCI_MFDEV_SUPPORT
+#ifdef DEBUGPCI
+ErrorF("pciGenFindNext: pciFuncNum %d\n", pciFuncNum);
+#endif
+ /*
+ * Somewhere in middle of order. Determine who's
+ * next up
+ */
+ if (pciFuncNum == 0) {
+ /*
+ * Is current dev a multifunction device?
+ */
+ if (pciMfDev(pciBusNum, pciDevNum))
+ /* Probe for other functions */
+ pciFuncNum = 1;
+ else
+ /*
+ * No more functions this device. Next
+ * device please
+ */
+ pciDevNum ++;
+ }
+ else if (++pciFuncNum >= 8) {
+ /* No more functions for this device. Next device please */
+ pciFuncNum = 0;
+ pciDevNum ++;
+ }
+#else
+ pciDevNum ++;
+#endif
+ if (pciDevNum >= 32 ||
+ !pciBusInfo[pciBusNum] ||
+ pciDevNum >= pciBusInfo[pciBusNum]->numDevices) {
+#ifdef DEBUGPCI
+ErrorF("pciGenFindNext: next bus\n");
+#endif
+ /*
+ * No more devices for this bus. Next bus please
+ */
+ if (++pciBusNum >= pciNumBuses) {
+#ifdef DEBUGPCI
+ErrorF("pciGenFindNext: out of buses\n");
+#endif
+ /* No more buses. All done for now */
+ return(PCI_NOT_FOUND);
+ }
+
+ pciDevNum = 0;
+ }
+ }
+
+#ifdef DEBUGPCI
+ErrorF("pciGenFindNext: pciBusInfo[%d] = 0x%lx\n", pciBusNum, pciBusInfo[pciBusNum]);
+#endif
+ if (!pciBusInfo[pciBusNum])
+ continue; /* Bus not defined, next please */
+
+ /*
+ * At this point, pciBusNum, pciDevNum, and pciFuncNum have been
+ * advanced to the next device. Compute the tag, and read the
+ * device/vendor ID field.
+ */
+#ifdef DEBUGPCI
+ErrorF("pciGenFindNext: [%d, %d, %d]\n", pciBusNum, pciDevNum, pciFuncNum);
+#endif
+ pciDeviceTag = PCI_MAKE_TAG(pciBusNum, pciDevNum, pciFuncNum);
+ devid = pciReadLong(pciDeviceTag, 0);
+#ifdef DEBUGPCI
+ErrorF("pciGenFindNext: pciDeviceTag = 0x%lx, devid = 0x%lx\n", pciDeviceTag, devid);
+#endif
+ if (devid == 0xffffffff)
+ continue; /* Nobody home. Next device please */
+
+ /*
+ * Before checking for a specific devid, look for enabled
+ * PCI to PCI bridge devices. If one is found, create and
+ * initialize a bus info record (if one does not already exist).
+ */
+#ifdef PCI_BRIDGE_SUPPORT
+ tmp = pciReadLong(pciDeviceTag, PCI_CLASS_REG);
+ base_class = PCI_CLASS_EXTRACT(tmp);
+ sub_class = PCI_SUBCLASS_EXTRACT(tmp);
+ if (base_class == PCI_CLASS_BRIDGE && sub_class == PCI_SUBCLASS_BRIDGE_PCI) {
+ tmp = pciReadLong(pciDeviceTag, PCI_PCI_BRIDGE_BUS_REG);
+ sec_bus = PCI_SECONDARY_BUS_EXTRACT(tmp);
+ pri_bus = PCI_PRIMARY_BUS_EXTRACT(tmp);
+#ifdef DEBUGPCI
+ErrorF("pciGenFindNext: pri_bus %d sec_bus %d\n", pri_bus, sec_bus);
+#endif
+ if (sec_bus > 0 && sec_bus < MAX_PCI_BUSES && pciBusInfo[pri_bus]) {
+ /*
+ * Found a secondary PCI bus
+ */
+ if (!pciBusInfo[sec_bus]) {
+ pciBusInfo[sec_bus] =
+ xnfalloc(sizeof(pciBusInfo_t));
+
+ }
+
+ /* Copy parents settings... */
+ *pciBusInfo[sec_bus] = *pciBusInfo[pri_bus];
+
+ /* ...but not everything same as parent */
+ pciBusInfo[sec_bus]->primary_bus = pri_bus;
+ pciBusInfo[sec_bus]->secondary = TRUE;
+ pciBusInfo[sec_bus]->numDevices = 32;
+
+ if (pciNumBuses <= sec_bus)
+ pciNumBuses = sec_bus+1;
+ }
+ }
+#endif
+
+ /*
+ * Does this device match the requested devid after
+ * applying mask?
+ */
+#ifdef DEBUGPCI
+ErrorF("pciGenFindNext: pciDevidMask = 0x%lx, pciDevid = 0x%lx\n", pciDevidMask, pciDevid);
+#endif
+ if ((devid & pciDevidMask) == pciDevid)
+ /* Yes - Return it. Otherwise, next device */
+ return(pciDeviceTag); /* got a match */
+
+ } /* for */
+ /*NOTREACHED*/
+}
+
+PCITAG
+pciGenFindFirst(void)
+{
+ /* Reset PCI bus number to start from top */
+ pciBusNum = -1;
+
+ return pciGenFindNext();
+}
+
+#if defined (__powerpc__)
+static int buserr_detected;
+
+static
+void buserr(int sig)
+{
+ buserr_detected = 1;
+}
+#endif
+
+CARD32
+pciCfgMech1Read(PCITAG tag, int offset)
+{
+ unsigned long rv = 0xffffffff;
+
+#if defined(__powerpc__)
+ signal(SIGBUS, buserr);
+ buserr_detected = 0;
+#endif
+
+ outl(0xCF8, PCI_EN | tag | (offset & 0xfc));
+ rv = inl(0xCFC);
+
+#if defined(__powerpc__)
+ signal(SIGBUS,SIG_DFL);
+ if (buserr_detected)
+ return(0xffffffff);
+ else
+#endif
+ return(rv);
+}
+
+void
+pciCfgMech1Write(PCITAG tag, int offset, CARD32 val)
+{
+#if defined(__powerpc__)
+ signal(SIGBUS, SIG_IGN);
+#endif
+
+ outl(0xCF8, PCI_EN | tag | (offset & 0xfc));
+#if defined(Lynx) && defined(__powerpc__)
+ outb(0x80, 0x00); /* wo this the next access fails
+ * on my Powerstack system when we use
+ * assembler inlines for outl */
+#endif
+ outl(0xCFC, val);
+
+#if defined(__powerpc__)
+ signal(SIGBUS, SIG_DFL);
+#endif
+}
+
+void
+pciCfgMech1SetBits(PCITAG tag, int offset, CARD32 mask, CARD32 val)
+{
+ unsigned long rv = 0xffffffff;
+
+#if defined(__powerpc__)
+ signal(SIGBUS, buserr);
+#endif
+
+ outl(0xCF8, PCI_EN | tag | (offset & 0xfc));
+ rv = inl(0xCFC);
+ rv = (rv & ~mask) | val;
+ outl(0xCFC, rv);
+
+#if defined(__powerpc__)
+ signal(SIGBUS,SIG_DFL);
+#endif
+}
+
+CARD32
+pciByteSwap(CARD32 u)
+{
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+# if defined(__powerpc__) && defined(PowerMAX_OS)
+ CARD32 tmp;
+
+ __inst_stwbrx(u, &tmp, 0);
+
+ return(tmp);
+
+# else /* !PowerMAX_OS */
+
+ return lswapl(u);
+
+# endif /* !PowerMAX_OS */
+
+#else /* !BIG_ENDIAN */
+
+ return(u);
+
+#endif
+}
+
+/*
+ * Dummy functions to noop the PCI services
+ */
+CARD32
+pciReadLongNULL(PCITAG tag, int offset)
+{
+ return(0xffffffff);
+}
+
+void
+pciWriteLongNULL(PCITAG tag, int offset, CARD32 val)
+{
+}
+
+void
+pciSetBitsLongNULL(PCITAG tag, int offset, CARD32 mask, CARD32 val)
+{
+}
+
+ADDRESS
+pciAddrNOOP(PCITAG tag, ADDRESS addr)
+{
+ return(addr);
+}
+
+pciConfigPtr *
+xf86scanpci(int flags)
+{
+ int idx = 0;
+ PCITAG tag;
+
+ if (pci_devp[0])
+ return pci_devp;
+
+ pciInit();
+
+ tag = pciFindFirst(0,0); /* 0 mask means match any valid device */
+ /* Check if no devices, return now */
+ if (tag == PCI_NOT_FOUND)
+ return NULL;
+
+#ifdef DEBUGPCI
+ErrorF("xf86scanpci: tag = 0x%lx\n", tag);
+#endif
+#ifndef OLD_FORMAT
+ xf86MsgVerb(X_INFO, 2, "PCI: PCI scan (all values are in hex)\n");
+#endif
+ while (idx < MAX_PCI_DEVICES && tag != PCI_NOT_FOUND) {
+ pciConfigPtr devp;
+ int i;
+
+ devp = xalloc(sizeof(pciDevice));
+ if (!devp) {
+ xf86Msg(X_ERROR,
+ "xf86scanpci: Out of memory after %d devices!!\n",
+ idx);
+ return (pciConfigPtr *)NULL;
+ }
+
+ /* Identify pci device by bus, dev, func, and tag */
+ devp->tag = tag;
+ devp->busnum = PCI_BUS_FROM_TAG(tag);
+ devp->devnum = PCI_DEV_FROM_TAG(tag);
+ devp->funcnum = PCI_FUNC_FROM_TAG(tag);
+
+ /* Read config space for this device */
+ for (i = 0; i < 17; i++) /* PCI hdr plus 1st dev spec dword */
+ devp->cfgspc.dwords[i] =
+ pciReadLong(tag, i * sizeof(CARD32));
+
+ /* Get base address sizes for type 0 headers */
+ if ((devp->pci_header_type & 0x7f) == 0)
+ for (i = 0; i < 7; i++)
+ devp->basesize[i] = pciGetBaseSize(tag, i, FALSE, NULL);
+
+#ifdef OLD_FORMAT
+ xf86MsgVerb(X_INFO, 2, "PCI: BusID 0x%02x,0x%02x,0x%1x "
+ "ID 0x%04x,0x%04x Rev 0x%02x Class 0x%02x,0x%02x\n",
+ devp->busnum, devp->devnum, devp->funcnum,
+ devp->pci_vendor, devp->pci_device, devp->pci_rev_id,
+ devp->pci_base_class, devp->pci_sub_class);
+#else
+ xf86MsgVerb(X_INFO, 2, "PCI: %02x:%02x:%1x: chip %04x,%04x"
+ " card %04x,%04x rev %02x class %02x,%02x,%02x"
+ " hdr %02x\n",
+ devp->busnum, devp->devnum, devp->funcnum,
+ devp->pci_vendor, devp->pci_device,
+ devp->pci_subsys_vendor, devp->pci_subsys_card,
+ devp->pci_rev_id, devp->pci_base_class,
+ devp->pci_sub_class, devp->pci_prog_if,
+ devp->pci_header_type);
+#endif
+
+ pci_devp[idx++] = devp;
+ tag = pciFindNext();
+#ifdef DEBUGPCI
+ErrorF("xf86scanpci: tag = pciFindNext = 0x%lx\n", tag);
+#endif
+ }
+#ifndef OLD_FORMAT
+ xf86MsgVerb(X_INFO, 2, "PCI: End of PCI scan\n");
+#endif
+
+ return pci_devp;
+}
+
+#if defined(INCLUDE_XF86_MAP_PCI_MEM)
+
+pointer
+xf86MapPciMem(int ScreenNum, int Flags, PCITAG Tag, unsigned long Base,
+ unsigned long Size)
+{
+ unsigned long hostbase = pciBusAddrToHostAddr(Tag, Base);
+ pointer base;
+ CARD32 save = 0;
+
+ /*
+ * If there are possible read side-effects, disable memory while
+ * doing the mapping.
+ */
+ if (Flags & VIDMEM_READSIDEEFFECT) {
+ save = pciReadLong(Tag, PCI_CMD_STAT_REG);
+ pciWriteLong(Tag, PCI_CMD_STAT_REG,
+ save & ~PCI_CMD_MEM_ENABLE);
+ }
+ base = xf86MapVidMem(ScreenNum, Flags, hostbase, Size);
+ if (!base) {
+ FatalError("xf86MapPciMem: Could not mmap PCI memory "
+ "[base=0x%x,hostbase=0x%x,size=%x] (%s)\n",
+ Base, hostbase, Size, strerror(errno));
+ }
+ /*
+ * If read side-effects, do whatever might be needed to prevent
+ * unintended reads, then restore PCI_CMD_STAT_REG.
+ */
+ if (Flags & VIDMEM_READSIDEEFFECT) {
+ xf86MapReadSideEffects(ScreenNum, Flags, base, Size);
+ pciWriteLong(Tag, PCI_CMD_STAT_REG, save);
+ }
+ return((pointer)base);
+}
+
+
+int
+xf86ReadPciBIOS(unsigned long Offset, PCITAG Tag, int basereg,
+ unsigned char *Buf, int Len)
+{
+ ADDRESS hostbase;
+ CARD32 romaddr, savebase = 0, romsave = 0, newbase = 0;
+ int ret;
+
+ /* XXX This assumes that memory access is enabled */
+
+ /*
+ * Check if the rom base address is assigned. If it isn't, and if
+ * a basereg was supplied, temporarily map the rom at that base
+ * address.
+ */
+ romsave = pciReadLong(Tag, PCI_MAP_ROM_REG);
+ romaddr = PCIGETROM(romsave);
+ if ((newbase = getValidBIOSBase(Tag,basereg)) != romaddr) {
+ romaddr = PCIGETROM(newbase);
+ if (romaddr != 0 && romaddr == newbase) {
+#if 0
+ savebase = pciReadLong(Tag, PCI_MAP_REG_START + (basereg << 2));
+ if (PCIGETROM(savebase) == romaddr)
+ pciWriteLong(Tag, PCI_MAP_REG_START + (basereg << 2), 0);
+ else
+ savebase = 0;
+#endif
+ pciWriteLong(Tag, PCI_MAP_ROM_REG, romaddr);
+ } else
+ romaddr = 0;
+ }
+ if (romaddr == 0) {
+ xf86Msg(X_WARNING, "xf86ReadPciBIOS: cannot locate a BIOS address\n");
+ return -1;
+ }
+ hostbase = pciBusAddrToHostAddr(Tag, PCIGETROM(romaddr));
+
+ /* Enable ROM address decoding */
+ pciWriteLong(Tag, PCI_MAP_ROM_REG, romaddr | PCI_MAP_ROM_DECODE_ENABLE);
+
+ ret = xf86ReadBIOS(hostbase, Offset, Buf, Len);
+
+ /* Restore ROM address decoding */
+ pciWriteLong(Tag, PCI_MAP_ROM_REG, romsave);
+
+ /* Restore the base register if it was changed. */
+ if (savebase)
+ pciWriteLong(Tag, PCI_MAP_REG_START + (basereg << 2), savebase);
+
+ return ret;
+}
+
+#elif defined(__sparc__)
+
+pointer
+xf86MapPciMem(int ScreenNum, int Flags, PCITAG Tag, pointer Base,
+ unsigned long Size)
+{
+ FatalError("xf86MapPciMem: Unsupported on SPARC\n");
+ return((pointer)-1);
+}
+
+int
+xf86ReadPciBIOS(unsigned long Offset, PCITAG Tag, int basereg,
+ unsigned char *Buf, int Len)
+{
+ FatalError("xf86ReadPciBIOS: Unsupported on SPARC\n");
+ return -1;
+}
+
+#endif /* INCLUDE_XF86_MAP_PCI_MEM */
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.h b/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.h
new file mode 100644
index 000000000..9e362ad2b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.h
@@ -0,0 +1,221 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.h,v 1.6 1999/03/28 15:32:56 dawes Exp $ */
+/*
+ * Copyright 1998 by Concurrent Computer Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Concurrent Computer
+ * Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Concurrent Computer Corporation makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Copyright 1998 by Metro Link Incorporated
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Metro Link
+ * Incorporated not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Metro Link Incorporated makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * This file is derived in part from the original xf86_PCI.h that included
+ * following copyright message:
+ *
+ * Copyright 1995 by Robin Cutshaw <robin@XFree86.Org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of the above listed copyright holder(s)
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. The above listed
+ * copyright holder(s) make(s) no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/*
+ * This file has the private Pci definitions. The public ones are imported
+ * from xf86Pci.h. Drivers should not use this file.
+ */
+#ifndef _PCI_H
+#define _PCI_H 1
+#include "Xarch.h"
+#include "Xfuncproto.h"
+#include "xf86Pci.h"
+
+/*
+ * Global Definitions
+ */
+#define MAX_PCI_DEVICES 64 /* Max number of devices accomodated */
+ /* by xf86scanpci */
+#define MAX_PCI_BUSES 32 /* Max number of PCI buses */
+
+#define PCI_NOT_FOUND 0xffffffff
+
+/*
+ *
+ */
+#define PCI_MAKE_TAG(b,d,f) ((((b) & 0xff) << 16) | \
+ (((d) & 0x1f) << 11) | \
+ (((f) & 0x7) << 8))
+
+#define PCI_BUS_FROM_TAG(tag) (((tag) & 0x00ff0000) >> 16)
+#define PCI_DEV_FROM_TAG(tag) (((tag) & 0x0000f800) >> 11)
+#define PCI_FUNC_FROM_TAG(tag) (((tag) & 0x00000700) >> 8)
+
+#define PCI_DFN_FROM_TAG(tag) (((tag) & 0x0000ff00) >> 8)
+
+/*
+ * Debug Macros/Definitions
+ */
+/* #define DEBUGPCI 2 */ /* Disable/enable trace in PCI code */
+
+#if defined(DEBUGPCI)
+
+# define PCITRACE(lvl,printfargs) \
+ if (lvl > xf86Verbose) { \
+ ErrorF printfargs; \
+ }
+
+#else /* !defined(DEBUGPCI) */
+
+# define PCITRACE(lvl,printfargs)
+
+#endif /* !defined(DEBUGPCI) */
+
+/*
+ * PCI Config mechanism definitions
+ */
+#define PCI_EN 0x80000000
+
+#define PCI_CFGMECH1_ADDRESS_REG 0xCF8
+#define PCI_CFGMECH1_DATA_REG 0xCFC
+
+#define PCI_CFGMECH1_MAXDEV 32
+
+#define PCI_CFGMECH1_TYPE1_CFGADDR(b,d,f,o) (PCI_EN | PCI_MAKE_TAG(b,d,f) | ((o) & 0xff) | 1)
+#define PCI_CFGMECH1_TYPE0_CFGADDR(d,f,o) (PCI_EN | PCI_MAKE_TAG(0,d,f) | ((o) & 0xff))
+
+/*
+ * Select architecture specific PCI init function
+ */
+#if defined(__powerpc__) && defined(linux)
+# define ARCH_PCI_INIT linuxPciInit
+# define INCLUDE_XF86_MAP_PCI_MEM
+#elif defined(__powerpc__)
+# define ARCH_PCI_INIT ppcPciInit
+# if !defined(PowerMAX_OS)
+# define INCLUDE_XF86_MAP_PCI_MEM
+# endif
+#elif defined(__sparc__) && defined(linux)
+# define ARCH_PCI_INIT sparcPciInit
+#elif defined(__alpha__)
+# define ARCH_PCI_INIT axpPciInit
+# define INCLUDE_XF86_MAP_PCI_MEM
+#else
+# define ARCH_PCI_INIT ix86PciInit
+# define INCLUDE_XF86_MAP_PCI_MEM
+#endif
+extern void ARCH_PCI_INIT(void);
+
+/*
+ * Table of functions used to access a specific PCI bus domain
+ * (e.g. a primary PCI bus and all of its secondaries)
+ */
+typedef struct pci_bus_funcs {
+ CARD32 (*pciReadLong)(PCITAG, int);
+ void (*pciWriteLong)(PCITAG, int, CARD32);
+ void (*pciSetBitsLong)(PCITAG, int, CARD32, CARD32);
+ ADDRESS (*pciAddrHostToBus)(PCITAG, ADDRESS);
+ ADDRESS (*pciAddrBusToHost)(PCITAG, ADDRESS);
+} pciBusFuncs_t;
+
+/*
+ * pciBusInfo_t - One structure per defined PCI bus
+ */
+typedef struct pci_bus_info {
+ unsigned char configMech; /* PCI config type to use */
+ unsigned char numDevices; /* Range of valid devnums */
+ unsigned char secondary; /* Boolean: bus is a secondary */
+ unsigned char primary_bus; /* Top level (primary) parent */
+ unsigned long ppc_io_base; /* PowerPC I/O spc membase */
+ unsigned long ppc_io_size; /* PowerPC I/O spc size */
+ pciBusFuncs_t funcs; /* PCI access functions */
+ void *pciBusPriv; /* Implementation private data */
+} pciBusInfo_t;
+
+/* configMech values */
+#define PCI_CFG_MECH_UNKNOWN 0 /* Not yet known */
+#define PCI_CFG_MECH_1 1 /* Most machines */
+#define PCI_CFG_MECH_2 2 /* Older PC's */
+#define PCI_CFG_MECH_OTHER 3 /* Something else */
+
+/* Generic PCI service functions and helpers */
+PCITAG pciGenFindFirst(void);
+PCITAG pciGenFindNext(void);
+CARD32 pciCfgMech1Read(PCITAG tag, int offset);
+void pciCfgMech1Write(PCITAG tag, int offset, CARD32 val);
+void pciCfgMech1SetBits(PCITAG tag, int offset, CARD32 mask,
+ CARD32 val);
+CARD32 pciByteSwap(CARD32);
+Bool pciMfDev(int, int);
+CARD32 pciReadLongNULL(PCITAG tag, int offset);
+void pciWriteLongNULL(PCITAG tag, int offset, CARD32 val);
+void pciSetBitsLongNULL(PCITAG tag, int offset, CARD32 mask,
+ CARD32 val);
+ADDRESS pciAddrNOOP(PCITAG tag, ADDRESS);
+
+extern PCITAG (*pciFindFirstFP)(void);
+extern PCITAG (*pciFindNextFP)(void);
+
+extern CARD32 pciDevid;
+extern CARD32 pciDevidMask;
+
+extern int pciBusNum;
+extern int pciDevNum;
+extern int pciFuncNum;
+extern PCITAG pciDeviceTag;
+
+extern pciBusInfo_t *pciBusInfo[];
+extern int pciNumBuses;
+
+extern pciBusFuncs_t pciNOOPFuncs;
+
+#endif /* _PCI_H */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bus/axpPci.c b/xc/programs/Xserver/hw/xfree86/os-support/bus/axpPci.c
new file mode 100644
index 000000000..3a4be455f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bus/axpPci.c
@@ -0,0 +1,134 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/axpPci.c,v 1.6 1998/11/15 04:30:37 dawes Exp $ */
+/*
+ * Copyright 1998 by Concurrent Computer Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Concurrent Computer
+ * Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Concurrent Computer Corporation makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Copyright 1998 by Metro Link Incorporated
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Metro Link
+ * Incorporated not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Metro Link Incorporated makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED 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 <stdio.h>
+#include "compiler.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "Pci.h"
+
+#include <asm/unistd.h>
+
+/*
+ * Alpha platform specific PCI access functions
+ */
+CARD32 axpPciCfgRead(PCITAG tag, int off);
+void axpPciCfgWrite(PCITAG, int off, CARD32 val);
+void axpPciCfgSetBits(PCITAG tag, int off, CARD32 mask, CARD32 bits);
+
+pciBusInfo_t axpPci0 = {
+/* configMech */ PCI_CFG_MECH_OTHER,
+/* numDevices */ 32,
+/* secondary */ FALSE,
+/* primary_bus */ 0,
+/* ppc_io_base */ 0,
+/* ppc_io_size */ 0,
+/* funcs */ {
+ axpPciCfgRead,
+ axpPciCfgWrite,
+ axpPciCfgSetBits,
+ pciAddrNOOP,
+ pciAddrNOOP
+ },
+/* pciBusPriv */ NULL
+};
+
+void
+axpPciInit()
+{
+ pciNumBuses = 1;
+ pciBusInfo[0] = &axpPci0;
+ pciFindFirstFP = pciGenFindFirst;
+ pciFindNextFP = pciGenFindNext;
+}
+
+
+#if defined(linux)
+/*
+ * These funtions will work for Linux, but other OS's
+ * are likely have a different mechanism for getting at
+ * PCI configuration space
+ */
+CARD32
+axpPciCfgRead(PCITAG tag, int off)
+{
+ int bus, dfn, len;
+ CARD32 val = 0xffffffff;
+
+ bus = PCI_BUS_FROM_TAG(tag);
+ dfn = PCI_DFN_FROM_TAG(tag);
+
+ syscall(__NR_pciconfig_read, bus, dfn, off, 4, &val);
+ return(val);
+}
+
+void
+axpPciCfgWrite(PCITAG tag, int off, CARD32 val)
+{
+ int bus, dfn, len;
+
+ bus = PCI_BUS_FROM_TAG(tag);
+ dfn = PCI_DFN_FROM_TAG(tag);
+
+ syscall(__NR_pciconfig_write, bus, dfn, off, 4, &val);
+}
+
+void
+axpPciCfgSetBits(PCITAG tag, int off, CARD32 mask, CARD32 bits)
+{
+ int bus, dfn, len;
+ CARD32 val = 0xffffffff;
+
+ bus = PCI_BUS_FROM_TAG(tag);
+ dfn = PCI_DFN_FROM_TAG(tag);
+
+ syscall(__NR_pciconfig_read, bus, dfn, off, 4, &val);
+ val = (val & ~mask) | (bits & mask);
+ syscall(__NR_pciconfig_write, bus, dfn, off, 4, &val);
+}
+#endif /* Linux */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bus/ix86Pci.c b/xc/programs/Xserver/hw/xfree86/os-support/bus/ix86Pci.c
new file mode 100644
index 000000000..5bfc959b4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bus/ix86Pci.c
@@ -0,0 +1,617 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/ix86Pci.c,v 1.7 1999/07/04 06:39:14 dawes Exp $ */
+/*
+ * ix86Pci.c - x86 PCI driver
+ *
+ * The Xfree server PCI access functions have been reimplemented as a
+ * framework that allows each supported platform/OS to have their own
+ * platform/OS specific PCI driver.
+ *
+ * Most of the code of these functions was simply lifted from the
+ * Intel architecture specifric portion of the original Xfree86
+ * PCI code in hw/xfree86/common_hw/xf86_PCI.C...
+ *
+ * Gary Barton
+ * Concurrent Computer Corporation
+ * garyb@gate.net
+ */
+
+/*
+ * Copyright 1998 by Concurrent Computer Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Concurrent Computer
+ * Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Concurrent Computer Corporation makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Copyright 1998 by Metro Link Incorporated
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Metro Link
+ * Incorporated not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Metro Link Incorporated makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * This software is derived from the original XFree86 PCI code
+ * which includes the following copyright notices as well:
+ *
+ * Copyright 1995 by Robin Cutshaw <robin@XFree86.Org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of the above listed copyright holder(s)
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. The above listed
+ * copyright holder(s) make(s) no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * This code is also based heavily on the code in FreeBSD-current, which was
+ * written by Wolfgang Stanglmeier, and contains the following copyright:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include "compiler.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "Pci.h"
+
+#ifdef PC98
+#define outb(port,data) _outb(port,data)
+#define outl(port,data) _outl(port,data)
+#define inb(port) _inb(port)
+#define inl(port) _inl(port)
+#endif
+
+#define PCI_CFGMECH2_ENABLE_REG 0xCF8
+#ifdef PC98
+#define PCI_CFGMECH2_FORWARD_REG 0xCF9
+#else
+#define PCI_CFGMECH2_FORWARD_REG 0xCFA
+#endif
+
+#define PCI_CFGMECH2_MAXDEV 16
+
+#define PCI_ADDR_FROM_TAG_CFG1(tag,reg) (PCI_EN | tag | (reg & 0xfc))
+#define PCI_FORWARD_FROM_TAG(tag) PCI_BUS_FROM_TAG(tag)
+#define PCI_ENABLE_FROM_TAG(tag) (0xf0 | (((tag) & 0x00000700) >> 7))
+#define PCI_ADDR_FROM_TAG_CFG2(tag,reg) (0xc000 | (((tag) & 0x0000f800) >> 3) \
+ | (reg & 0xfc))
+
+/*
+ * Intel x86 platform specific PCI access functions
+ */
+CARD32 ix86PciReadLongSetup(PCITAG tag, int off);
+void ix86PciWriteLongSetup(PCITAG, int off, CARD32 val);
+void ix86PciSetBitsLongSetup(PCITAG, int off, CARD32 mask, CARD32 val);
+CARD32 ix86PciReadLongCFG1(PCITAG tag, int off);
+void ix86PciWriteLongCFG1(PCITAG, int off, CARD32 val);
+void ix86PciSetBitsLongCFG1(PCITAG, int off, CARD32 mask, CARD32 val);
+CARD32 ix86PciReadLongCFG2(PCITAG tag, int off);
+void ix86PciWriteLongCFG2(PCITAG, int off, CARD32 val);
+void ix86PciSetBitsLongCFG2(PCITAG, int off, CARD32 mask, CARD32 val);
+
+pciBusInfo_t ix86Pci0 = {
+/* configMech */ PCI_CFG_MECH_UNKNOWN, /* Set by ix86PciInit() */
+/* numDevices */ 0, /* Set by ix86PciInit() */
+/* secondary */ FALSE,
+/* primary_bus */ 0,
+/* ppc_io_base */ 0,
+/* ppc_io_size */ 0,
+/* funcs */ {
+ ix86PciReadLongSetup,
+ ix86PciWriteLongSetup,
+ ix86PciSetBitsLongSetup,
+ pciAddrNOOP,
+ pciAddrNOOP
+ },
+/* pciBusPriv */ NULL
+};
+
+static Bool
+ix86PciBusCheck(void)
+{
+ CARD8 device;
+
+ for (device = 0; device < ix86Pci0.numDevices; device++) {
+ CARD32 id;
+ id = (*ix86Pci0.funcs.pciReadLong)(PCI_MAKE_TAG(0, device, 0), 0);
+ if (id && id != 0xffffffff) {
+ return TRUE;
+ }
+ }
+ return 0;
+}
+
+static
+void ix86PciSelectCfgmech(void)
+{
+ static Bool beenhere = FALSE;
+ CARD32 mode1Res1 = 0, mode1Res2 = 0, oldVal1 = 0;
+ CARD8 mode2Res1 = 0, mode2Res2 = 0, oldVal2 = 0;
+ int stages = 0;
+
+ if (beenhere)
+ return; /* Been there, done that */
+
+ beenhere = TRUE;
+
+ /*
+ * Determine if motherboard chipset supports PCI Config Mech 1 or 2
+ * We rely on xf86Info.pciFlags to tell which mechanisms to try....
+ */
+ switch (xf86Info.pciFlags) {
+
+ case PCIProbe1: /* { */
+
+ xf86MsgVerb(X_INFO, 2, "PCI: Probing config type using method 1\n");
+ oldVal1 = inl(PCI_CFGMECH1_ADDRESS_REG);
+
+#ifdef DEBUGPCI
+ if (xf86Verbose > 2) {
+ ErrorF("Checking config type 1:\n"
+ "\tinitial value of MODE1_ADDR_REG is 0x%08x\n", oldVal1);
+ ErrorF("\tChecking that all bits in mask 0x7f000000 are clear\n");
+ }
+#endif
+
+ /* Assuming config type 1 to start with */
+ if ((oldVal1 & 0x7f000000) == 0) {
+
+ stages |= 0x01;
+
+#ifdef DEBUGPCI
+ if (xf86Verbose > 2) {
+ ErrorF("\tValue indicates possibly config type 1\n");
+ ErrorF("\tWriting 32-bit value 0x%08x to MODE1_ADDR_REG\n", PCI_EN);
+#if 0
+ ErrorF("\tWriting 8-bit value 0x00 to MODE1_ADDR_REG + 3\n");
+#endif
+ }
+#endif
+
+ ix86Pci0.configMech = PCI_CFG_MECH_1;
+ ix86Pci0.numDevices = PCI_CFGMECH1_MAXDEV;
+ ix86Pci0.funcs.pciReadLong = ix86PciReadLongCFG1;
+ ix86Pci0.funcs.pciWriteLong = ix86PciWriteLongCFG1;
+ ix86Pci0.funcs.pciSetBitsLong = ix86PciSetBitsLongCFG1;
+
+ outl(PCI_CFGMECH1_ADDRESS_REG, PCI_EN);
+
+#if 0
+ /*
+ * This seems to cause some Neptune-based PCI machines to switch
+ * from config type 1 to config type 2
+ */
+ outb(PCI_CFGMECH1_ADDRESS_REG + 3, 0);
+#endif
+ mode1Res1 = inl(PCI_CFGMECH1_ADDRESS_REG);
+
+#ifdef DEBUGPCI
+ if (xf86Verbose > 2) {
+ ErrorF("\tValue read back from MODE1_ADDR_REG is 0x%08x\n",
+ mode1Res1);
+ ErrorF("\tRestoring original contents of MODE1_ADDR_REG\n");
+ }
+#endif
+
+ outl(PCI_CFGMECH1_ADDRESS_REG, oldVal1);
+
+ if (mode1Res1) {
+
+ stages |= 0x02;
+
+#ifdef DEBUGPCI
+ if (xf86Verbose > 2) {
+ ErrorF("\tValue read back is non-zero, and indicates possible"
+ " config type 1\n");
+ }
+#endif
+
+ if (ix86PciBusCheck()) {
+
+#ifdef DEBUGPCI
+ if (xf86Verbose > 2)
+ ErrorF("\tBus check Confirms this: ");
+#endif
+
+ xf86MsgVerb(X_INFO, 2, "PCI: Config type is 1\n");
+ xf86MsgVerb(X_INFO, 3,
+ "PCI: stages = 0x%02x, oldVal1 = 0x%08x, mode1Res1"
+ " = 0x%08x\n", stages, oldVal1, mode1Res1);
+ return;
+ }
+
+#ifdef DEBUGPCI
+ if (xf86Verbose > 2) {
+ ErrorF("\tBus check fails to confirm this, continuing type 1"
+ " check ...\n");
+ }
+#endif
+
+ }
+
+ stages |= 0x04;
+
+#ifdef DEBUGPCI
+ if (xf86Verbose > 2) {
+ ErrorF("\tWriting 0xff000001 to MODE1_ADDR_REG\n");
+ }
+#endif
+ outl(PCI_CFGMECH1_ADDRESS_REG, 0xff000001);
+ mode1Res2 = inl(PCI_CFGMECH1_ADDRESS_REG);
+
+#ifdef DEBUGPCI
+ if (xf86Verbose > 2) {
+ ErrorF("\tValue read back from MODE1_ADDR_REG is 0x%08x\n",
+ mode1Res2);
+ ErrorF("\tRestoring original contents of MODE1_ADDR_REG\n");
+ }
+#endif
+
+ outl(PCI_CFGMECH1_ADDRESS_REG, oldVal1);
+
+ if ((mode1Res2 & 0x80000001) == 0x80000000) {
+
+ stages |= 0x08;
+
+#ifdef DEBUGPCI
+ if (xf86Verbose > 2) {
+ ErrorF("\tValue read back has only the msb set\n"
+ "\tThis indicates possible config type 1\n");
+ }
+#endif
+
+ if (ix86PciBusCheck()) {
+
+#ifdef DEBUGPCI
+ if (xf86Verbose > 2)
+ ErrorF("\tBus check Confirms this: ");
+#endif
+
+ xf86MsgVerb(X_INFO, 2, "PCI: Config type is 1\n");
+ xf86MsgVerb(X_INFO, 3,
+ "PCI: stages = 0x%02x, oldVal1 = 0x%08x,\n"
+ "\tmode1Res1 = 0x%08x, mode1Res2 = 0x%08x\n",
+ stages, oldVal1, mode1Res1, mode1Res2);
+ return;
+ }
+
+#ifdef DEBUGPCI
+ if (xf86Verbose > 2) {
+ ErrorF("\tBus check fails to confirm this.\n");
+ }
+#endif
+
+ }
+ }
+
+ xf86MsgVerb(X_INFO, 3, "PCI: Standard check for type 1 failed.\n");
+ xf86MsgVerb(X_INFO, 3, "PCI: stages = 0x%02x, oldVal1 = 0x%08x,\n"
+ "\tmode1Res1 = 0x%08x, mode1Res2 = 0x%08x\n",
+ stages, oldVal1, mode1Res1, mode1Res2);
+
+ /* Try config type 2 */
+ oldVal2 = inb(PCI_CFGMECH2_ENABLE_REG);
+ if ((oldVal2 & 0xf0) == 0) {
+ ix86Pci0.configMech = PCI_CFG_MECH_2;
+ ix86Pci0.numDevices = PCI_CFGMECH2_MAXDEV;
+ ix86Pci0.funcs.pciReadLong = ix86PciReadLongCFG2;
+ ix86Pci0.funcs.pciWriteLong = ix86PciWriteLongCFG2;
+ ix86Pci0.funcs.pciSetBitsLong = ix86PciSetBitsLongCFG2;
+
+ outb(PCI_CFGMECH2_ENABLE_REG, 0x0e);
+ mode2Res1 = inb(PCI_CFGMECH2_ENABLE_REG);
+ outb(PCI_CFGMECH2_ENABLE_REG, oldVal2);
+
+ if (mode2Res1 == 0x0e) {
+ if (ix86PciBusCheck()) {
+ xf86MsgVerb(X_INFO, 2, "PCI: Config type is 2\n");
+ return;
+ }
+ }
+ }
+ break; /* } */
+
+ case PCIProbe2: /* { */
+
+ /* The scanpci-style detection method */
+
+ xf86MsgVerb(X_INFO, 2, "PCI: Probing config type using method 2\n");
+
+ outb(PCI_CFGMECH2_ENABLE_REG, 0x00);
+ outb(PCI_CFGMECH2_FORWARD_REG, 0x00);
+ mode2Res1 = inb(PCI_CFGMECH2_ENABLE_REG);
+ mode2Res2 = inb(PCI_CFGMECH2_FORWARD_REG);
+
+ if (mode2Res1 == 0 && mode2Res2 == 0) {
+ xf86MsgVerb(X_INFO, 2, "PCI: Config type is 2\n");
+ ix86Pci0.configMech = PCI_CFG_MECH_2;
+ ix86Pci0.numDevices = PCI_CFGMECH2_MAXDEV;
+ ix86Pci0.funcs.pciReadLong = ix86PciReadLongCFG2;
+ ix86Pci0.funcs.pciWriteLong = ix86PciWriteLongCFG2;
+ ix86Pci0.funcs.pciSetBitsLong = ix86PciSetBitsLongCFG2;
+ return;
+ }
+
+ oldVal1 = inl(PCI_CFGMECH1_ADDRESS_REG);
+ outl(PCI_CFGMECH1_ADDRESS_REG, PCI_EN);
+ mode1Res1 = inl(PCI_CFGMECH1_ADDRESS_REG);
+ outl(PCI_CFGMECH1_ADDRESS_REG, oldVal1);
+ if (mode1Res1 == PCI_EN) {
+ xf86MsgVerb(X_INFO, 2, "PCI: Config type is 1\n");
+ ix86Pci0.configMech = PCI_CFG_MECH_1;
+ ix86Pci0.numDevices = PCI_CFGMECH1_MAXDEV;
+ ix86Pci0.funcs.pciReadLong = ix86PciReadLongCFG1;
+ ix86Pci0.funcs.pciWriteLong = ix86PciWriteLongCFG1;
+ ix86Pci0.funcs.pciSetBitsLong = ix86PciSetBitsLongCFG1;
+ return;
+ }
+ break; /* } */
+
+ case PCIForceConfig1:
+
+ xf86MsgVerb(X_INFO, 2, "PCI: Forcing config type 1\n");
+
+ ix86Pci0.configMech = PCI_CFG_MECH_1;
+ ix86Pci0.numDevices = PCI_CFGMECH1_MAXDEV;
+ ix86Pci0.funcs.pciReadLong = ix86PciReadLongCFG1;
+ ix86Pci0.funcs.pciWriteLong = ix86PciWriteLongCFG1;
+ ix86Pci0.funcs.pciSetBitsLong = ix86PciSetBitsLongCFG1;
+ return;
+
+ case PCIForceConfig2:
+
+ xf86MsgVerb(X_INFO, 2, "PCI: Forcing config type 2\n");
+
+ ix86Pci0.configMech = PCI_CFG_MECH_2;
+ ix86Pci0.numDevices = PCI_CFGMECH2_MAXDEV;
+ ix86Pci0.funcs.pciReadLong = ix86PciReadLongCFG2;
+ ix86Pci0.funcs.pciWriteLong = ix86PciWriteLongCFG2;
+ ix86Pci0.funcs.pciSetBitsLong = ix86PciSetBitsLongCFG2;
+ return;
+
+ }
+
+ /* No PCI found */
+ xf86MsgVerb(X_INFO, 2, "PCI: No PCI bus found\n");
+}
+
+#if 0
+static pciTagRec
+ix86PcibusTag(CARD8 bus, CARD8 cardnum, CARD8 func)
+{
+ pciTagRec tag;
+
+ tag.cfg1 = 0;
+
+ if (func > 7 || cardnum >= pciBusInfo[bus]->numDevices)
+ return tag;
+
+ switch (ix86Pci0.configMech) {
+ case PCI_CFG_MECH_1:
+ tag.cfg1 = PCI_EN | ((CARD32)bus << 16) |
+ ((CARD32)cardnum << 11) |
+ ((CARD32)func << 8);
+ break;
+
+ case PCI_CFG_MECH_2:
+ tag.cfg2.port = 0xc000 | ((CARD16)cardnum << 8);
+ tag.cfg2.enable = 0xf0 | (func << 1);
+ tag.cfg2.forward = bus;
+ break;
+ }
+
+ return tag;
+}
+#endif
+CARD32
+ix86PciReadLongSetup(PCITAG Tag, int reg)
+{
+ ix86PciSelectCfgmech();
+ return (*ix86Pci0.funcs.pciReadLong)(Tag,reg);
+}
+
+CARD32
+ix86PciReadLongCFG1(PCITAG Tag, int reg)
+{
+ CARD32 addr, data = 0;
+
+#ifdef DEBUGPCI
+ErrorF("ix86PciReadLong 0x%lx, %d\n", Tag, reg);
+#endif
+
+ addr = PCI_ADDR_FROM_TAG_CFG1(Tag,reg);
+ outl(PCI_CFGMECH1_ADDRESS_REG, addr);
+ data = inl(PCI_CFGMECH1_DATA_REG);
+ outl(PCI_CFGMECH1_ADDRESS_REG, 0);
+
+#ifdef DEBUGPCI
+ErrorF("ix86PciReadLong 0x%lx\n", data);
+#endif
+
+ return data;
+}
+
+CARD32
+ix86PciReadLongCFG2(PCITAG Tag, int reg)
+{
+ CARD32 addr, data = 0;
+ CARD8 forward, enable;
+#ifdef DEBUGPCI
+ErrorF("ix86PciReadLong 0x%lx, %d\n", Tag, reg);
+#endif
+ forward = PCI_FORWARD_FROM_TAG(Tag);
+ enable = PCI_ENABLE_FROM_TAG(Tag);
+ addr = PCI_ADDR_FROM_TAG_CFG2(Tag,reg);
+
+ outb(PCI_CFGMECH2_ENABLE_REG, enable);
+ outb(PCI_CFGMECH2_FORWARD_REG, forward);
+ data = inl((CARD16)addr);
+ outb(PCI_CFGMECH2_ENABLE_REG, 0);
+ outb(PCI_CFGMECH2_FORWARD_REG, 0);
+
+#ifdef DEBUGPCI
+ErrorF("ix86PciReadLong 0x%lx\n", data);
+#endif
+
+ return data;
+}
+
+void
+ix86PciWriteLongSetup(PCITAG Tag, int reg, CARD32 data)
+{
+ ix86PciSelectCfgmech();
+ (*ix86Pci0.funcs.pciWriteLong)(Tag,reg,data);
+}
+
+void
+ix86PciWriteLongCFG1(PCITAG Tag, int reg, CARD32 data)
+{
+ CARD32 addr;
+
+ addr = PCI_ADDR_FROM_TAG_CFG1(Tag,reg);
+ outl(PCI_CFGMECH1_ADDRESS_REG, addr);
+ outl(PCI_CFGMECH1_DATA_REG, data);
+ outl(PCI_CFGMECH1_ADDRESS_REG, 0);
+}
+
+void
+ix86PciWriteLongCFG2(PCITAG Tag, int reg, CARD32 data)
+{
+ CARD32 addr;
+ CARD8 forward, enable;
+
+ forward = PCI_FORWARD_FROM_TAG(Tag);
+ enable = PCI_ENABLE_FROM_TAG(Tag);
+ addr = PCI_ADDR_FROM_TAG_CFG2(Tag,reg);
+
+ outb(PCI_CFGMECH2_ENABLE_REG, enable);
+ outb(PCI_CFGMECH2_FORWARD_REG, forward);
+ outl((CARD16)addr, data);
+ outb(PCI_CFGMECH2_ENABLE_REG, 0);
+ outb(PCI_CFGMECH2_FORWARD_REG, 0);
+}
+
+void
+ix86PciSetBitsLongSetup(PCITAG Tag, int reg, CARD32 mask, CARD32 val)
+{
+ ix86PciSelectCfgmech();
+ (*ix86Pci0.funcs.pciSetBitsLong)(Tag,reg,mask,val);
+}
+
+void
+ix86PciSetBitsLongCFG1(PCITAG Tag, int reg, CARD32 mask, CARD32 val)
+{
+ CARD32 addr, data = 0;
+
+#ifdef DEBUGPCI
+ ErrorF("ix86PciSetBitsLong 0x%lx, %d\n", Tag, reg);
+#endif
+
+ addr = PCI_ADDR_FROM_TAG_CFG1(Tag,reg);
+ outl(PCI_CFGMECH1_ADDRESS_REG, addr);
+ data = inl(PCI_CFGMECH1_DATA_REG);
+ data = (data & ~mask) | (val & mask);
+ outl(PCI_CFGMECH1_DATA_REG, data);
+ outl(PCI_CFGMECH1_ADDRESS_REG, 0);
+}
+
+void
+ix86PciSetBitsLongCFG2(PCITAG Tag, int reg, CARD32 mask, CARD32 val)
+{
+ CARD32 addr, data = 0;
+ CARD8 enable, forward;
+
+#ifdef DEBUGPCI
+ ErrorF("ix86PciSetBitsLong 0x%lx, %d\n", Tag, reg);
+#endif
+
+ forward = PCI_FORWARD_FROM_TAG(Tag);
+ enable = PCI_ENABLE_FROM_TAG(Tag);
+ addr = PCI_ADDR_FROM_TAG_CFG2(Tag,reg);
+
+ outb(PCI_CFGMECH2_ENABLE_REG, enable);
+ outb(PCI_CFGMECH2_FORWARD_REG, forward);
+ data = inl((CARD16)addr);
+ data = (data & ~mask) | (val & mask);
+ outl((CARD16)addr, data);
+ outb(PCI_CFGMECH2_ENABLE_REG, 0);
+ outb(PCI_CFGMECH2_FORWARD_REG, 0);
+}
+
+void
+ix86PciInit()
+{
+ /* Initialize pciBusInfo[] array and function pointers */
+ pciNumBuses = 1;
+ pciBusInfo[0] = &ix86Pci0;
+ pciFindFirstFP = pciGenFindFirst;
+ pciFindNextFP = pciGenFindNext;
+
+ /* Make sure that there is a PCI bus present. */
+ ix86PciSelectCfgmech();
+ if (ix86Pci0.configMech == PCI_CFG_MECH_UNKNOWN) {
+ pciNumBuses = 0;
+ pciBusInfo[0] = NULL;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bus/linuxPci.c b/xc/programs/Xserver/hw/xfree86/os-support/bus/linuxPci.c
new file mode 100644
index 000000000..130b0e1e4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bus/linuxPci.c
@@ -0,0 +1,180 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/linuxPci.c,v 1.3 1999/03/28 15:32:57 dawes Exp $ */
+/*
+ * Copyright 1998 by Concurrent Computer Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Concurrent Computer
+ * Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Concurrent Computer Corporation makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Copyright 1998 by Metro Link Incorporated
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Metro Link
+ * Incorporated not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Metro Link Incorporated makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED 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 <stdio.h>
+#include "compiler.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "Pci.h"
+
+#include <asm/unistd.h>
+
+/*
+ * linux platform specific PCI access functions -- using /proc/bus/pci
+ * needs kernel version 2.2.x
+ */
+CARD32 linuxPciCfgRead(PCITAG tag, int off);
+void linuxPciCfgWrite(PCITAG, int off, CARD32 val);
+void linuxPciCfgSetBits(PCITAG tag, int off, CARD32 mask, CARD32 bits);
+
+pciBusInfo_t linuxPci0 = {
+/* configMech */ PCI_CFG_MECH_OTHER,
+/* numDevices */ 32,
+/* secondary */ FALSE,
+/* primary_bus */ 0,
+/* ppc_io_base */ 0,
+/* ppc_io_size */ 0,
+/* funcs */ {
+ linuxPciCfgRead,
+ linuxPciCfgWrite,
+ linuxPciCfgSetBits,
+ pciAddrNOOP,
+ pciAddrNOOP
+ },
+/* pciBusPriv */ NULL
+};
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+#ifdef __sparc__
+#ifndef ASI_PL
+#define ASI_PL 0x88
+#endif
+#define PCI_CPU(val) ({ \
+int __ret; \
+__asm__ __volatile__("lduwa [%1] %2, %0" : "=r" (__ret) : "r" (&val), "i" (ASI_PL)); \
+__ret; \
+})
+#else
+#define PCI_CPU(val) (((val >> 24) & 0x000000ff) | \
+ ((val >> 8) & 0x0000ff00) | \
+ ((val << 8) & 0x00ff0000) | \
+ ((val << 24) & 0xff000000))
+#endif
+#else
+#define PCI_CPU(val) (val)
+#endif
+
+void
+linuxPciInit()
+{
+ struct stat st;
+ if (-1 == stat("/proc/bus/pci",&st)) {
+ /* when using this as default for all linux architectures,
+ we'll need a fallback for 2.0 kernels here */
+ return;
+ }
+ pciNumBuses = 1;
+ pciBusInfo[0] = &linuxPci0;
+ pciFindFirstFP = pciGenFindFirst;
+ pciFindNextFP = pciGenFindNext;
+}
+
+static int
+linuxPciOpenFile(PCITAG tag)
+{
+ static int lbus,ldev,lfunc,fd = -1;
+ int bus, dev, func;
+ char file[32];
+
+ bus = PCI_BUS_FROM_TAG(tag);
+ dev = PCI_DEV_FROM_TAG(tag);
+ func = PCI_FUNC_FROM_TAG(tag);
+ if (fd == -1 || bus != lbus || dev != ldev || func != lfunc) {
+ if (fd != -1)
+ close(fd);
+ sprintf(file,"/proc/bus/pci/%02x/%02x.%1x",bus,dev,func);
+ fd = open(file,O_RDWR);
+ lbus = bus;
+ ldev = dev;
+ lfunc = func;
+ }
+ return fd;
+}
+
+CARD32
+linuxPciCfgRead(PCITAG tag, int off)
+{
+ int fd;
+ CARD32 val = 0xffffffff;
+
+ if (-1 != (fd = linuxPciOpenFile(tag))) {
+ lseek(fd,off,SEEK_SET);
+ read(fd,&val,4);
+ }
+ return PCI_CPU(val);
+}
+
+void
+linuxPciCfgWrite(PCITAG tag, int off, CARD32 val)
+{
+ int fd;
+
+ if (-1 != (fd = linuxPciOpenFile(tag))) {
+ lseek(fd,off,SEEK_SET);
+ val = PCI_CPU(val);
+ write(fd,&val,4);
+ }
+}
+
+void
+linuxPciCfgSetBits(PCITAG tag, int off, CARD32 mask, CARD32 bits)
+{
+ int fd;
+ CARD32 val = 0xffffffff;
+
+ return;
+ if (-1 != (fd = linuxPciOpenFile(tag))) {
+ lseek(fd,off,SEEK_SET);
+ read(fd,&val,4);
+ val = PCI_CPU(val);
+ val = (val & ~mask) | (bits & mask);
+ val = PCI_CPU(val);
+ lseek(fd,off,SEEK_SET);
+ write(fd,&val,4);
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bus/ppcPci.c b/xc/programs/Xserver/hw/xfree86/os-support/bus/ppcPci.c
new file mode 100644
index 000000000..3b49b3674
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bus/ppcPci.c
@@ -0,0 +1,195 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/ppcPci.c,v 1.4 1998/09/19 12:14:59 dawes Exp $ */
+/*
+ * ppcPci.c - PowerPC PCI access functions
+ *
+ * PCI driver functions supporting Motorola PowerPC platforms
+ * including Powerstack(RiscPC/RiscPC+), PowerStackII, MTX, and
+ * MVME 160x/260x/360x/460x VME boards
+ *
+ * Gary Barton
+ * Concurrent Computer Corporation
+ * garyb@gate.net
+ *
+ */
+
+/*
+ * Copyright 1998 by Concurrent Computer Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Concurrent Computer
+ * Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Concurrent Computer Corporation makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Copyright 1998 by Metro Link Incorporated
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Metro Link
+ * Incorporated not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Metro Link Incorporated makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED 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 <stdio.h>
+#include "compiler.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "Pci.h"
+
+#ifndef MAP_FAILED
+#define MAP_FAILED (pointer)(-1)
+#endif
+
+void
+ppcPciInit()
+{
+#if defined(PowerMAX_OS)
+ extern void pmaxPciInit(void);
+
+ pmaxPciInit();
+
+#else
+
+ extern void motoppcPciInit(void);
+
+ motoppcPciInit();
+
+#endif
+}
+
+/*
+ * Motorola PowerPC platform support
+ *
+ * The following code should support the MVME 1600 & 2600 VME boards
+ * as well as the various PowerStack and RiscPC models. All of these
+ * machines support PCI config mechanism #1 and use the std config
+ * address and data regs locations:
+ * cfg address reg = 0xcf8 (PCI I/O)
+ * cfg data reg = 0xcfc (PCI I/O)
+ *
+ * The moto machines do have different address maps on either side
+ * of the PCI-host bridge though.
+ */
+ADDRESS motoppcBusAddrToHostAddr(PCITAG, ADDRESS);
+ADDRESS motoppcHostAddrToBusAddr(PCITAG, ADDRESS);
+
+pciBusInfo_t motoppcPci0 = {
+/* configMech */ PCI_CFG_MECH_1,
+/* numDevices */ 32,
+/* secondary */ FALSE,
+/* primary_bus */ 0,
+/* ppc_io_base */ 0x80000000,
+/* ppc_io_size */ 64 * 1024,
+/* funcs */ {
+ pciCfgMech1Read,
+ pciCfgMech1Write,
+ pciCfgMech1SetBits, /* XXX not implemented yet */
+ motoppcHostAddrToBusAddr,
+ motoppcBusAddrToHostAddr
+ },
+/* pciBusPriv */ NULL
+};
+
+extern volatile unsigned char *ioBase;
+
+void
+motoppcPciInit()
+{
+ pciNumBuses = 1;
+ pciBusInfo[0] = &motoppcPci0;
+ pciFindFirstFP = pciGenFindFirst;
+ pciFindNextFP = pciGenFindNext;
+
+ if (ioBase == MAP_FAILED) {
+ ppcPciIoMap(0); /* Make inb/outb et al work for pci0 and its secondaries */
+
+ if (ioBase == MAP_FAILED) {
+ FatalError("motoppcPciInit: Cannot map pci0 I/O segment!!!\n");
+ /*NOTREACHED*/
+ }
+ }
+}
+
+extern unsigned long motoPciMemBase = 0;
+extern unsigned long motoPciMemLen = 0x3f000000;
+extern unsigned long motoPciMemBaseCPU = 0xc0000000;
+
+ADDRESS
+motoppcBusAddrToHostAddr(PCITAG tag, ADDRESS addr)
+{
+ unsigned long addr_l = (unsigned long)addr;
+
+ if (addr_l >= motoPciMemBase && addr_l < motoPciMemLen)
+ /*
+ * PCI memory space addresses [0-0x3effffff] are
+ * are seen at [0xc0000000,0xfeffffff] on moto host
+ */
+ return((ADDRESS)((motoPciMemBaseCPU - motoPciMemBase) + addr_l));
+
+ else if (addr_l >= 0x80000000)
+ /*
+ * Moto host memory [0,0x7fffffff] is seen at
+ * [0x80000000,0xffffffff] on PCI bus
+ */
+ return((ADDRESS)(addr_l & 0x7fffffff));
+ else
+ FatalError("motoppcBusAddrToHostAddr: PCI addr 0x%x is not accessible to host!!!\n",
+ addr_l);
+
+ /*NOTREACHED*/
+}
+
+ADDRESS
+motoppcHostAddrToBusAddr(PCITAG tag, ADDRESS addr)
+{
+ unsigned long addr_l = (unsigned long)addr;
+
+ if (addr_l < 0x80000000)
+ /*
+ * Moto host memory [0,0x7fffffff] is seen at
+ * [0x80000000,0xffffffff] on PCI bus
+ */
+ return((ADDRESS)(0x80000000 | addr_l));
+
+ else if (addr_l >= motoPciMemBaseCPU && addr_l < motoPciMemBaseCPU + motoPciMemLen)
+ /*
+ * PCI memory space addresses [0-0x3effffff] are
+ * are seen at [0xc0000000,0xfeffffff] on moto host
+ */
+ return((ADDRESS)(addr_l - (motoPciMemBaseCPU - motoPciMemBase)));
+
+ else
+ FatalError("motoppcHostAddrToBusAddr: Host addr 0x%x is not accessible to PCI!!!\n",
+ addr_l);
+
+ /*NOTREACHED*/
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bus/sparcPci.c b/xc/programs/Xserver/hw/xfree86/os-support/bus/sparcPci.c
new file mode 100644
index 000000000..49d01331b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bus/sparcPci.c
@@ -0,0 +1,179 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/sparcPci.c,v 1.1 1999/03/28 15:32:57 dawes Exp $ */
+/*
+ * Copyright 1998 by Concurrent Computer Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Concurrent Computer
+ * Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Concurrent Computer Corporation makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Copyright 1998 by Metro Link Incorporated
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Metro Link
+ * Incorporated not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Metro Link Incorporated makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED 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 <stdio.h>
+#include "compiler.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "Pci.h"
+
+#include <asm/unistd.h>
+#ifndef __NR_pciconfig_read
+#define __NR_pciconfig_read 148
+#define __NR_pciconfig_write 149
+#endif
+
+/*
+ * UltraSPARC platform specific PCI access functions
+ */
+CARD32 sparcPciCfgRead(PCITAG tag, int off);
+void sparcPciCfgWrite(PCITAG, int off, CARD32 val);
+void sparcPciCfgSetBits(PCITAG tag, int off, CARD32 mask, CARD32 bits);
+
+pciBusInfo_t sparcPci0 = {
+/* configMech */ PCI_CFG_MECH_OTHER,
+/* numDevices */ 32,
+/* secondary */ FALSE,
+/* primary_bus */ 0,
+/* ppc_io_base */ 0,
+/* ppc_io_size */ 0,
+/* funcs */ {
+ sparcPciCfgRead,
+ sparcPciCfgWrite,
+ sparcPciCfgSetBits,
+ pciAddrNOOP,
+ pciAddrNOOP
+ },
+/* pciBusPriv */ NULL
+};
+
+void
+sparcPciInit()
+{
+ pciNumBuses = 1;
+ pciBusInfo[0] = &sparcPci0;
+ pciFindFirstFP = pciGenFindFirst;
+ pciFindNextFP = pciGenFindNext;
+}
+
+
+#if defined(linux)
+/*
+ * These funtions will work for Linux, but other OS's
+ * are likely have a different mechanism for getting at
+ * PCI configuration space
+ */
+CARD32
+sparcPciCfgRead(PCITAG tag, int off)
+{
+ int bus, dfn, len;
+ CARD32 val = 0xffffffff;
+
+ bus = PCI_BUS_FROM_TAG(tag);
+ dfn = PCI_DFN_FROM_TAG(tag);
+
+ syscall(__NR_pciconfig_read, bus, dfn, off, 4, &val);
+ return(val);
+}
+
+void
+sparcPciCfgWrite(PCITAG tag, int off, CARD32 val)
+{
+ int bus, dfn, len;
+
+ bus = PCI_BUS_FROM_TAG(tag);
+ dfn = PCI_DFN_FROM_TAG(tag);
+
+ syscall(__NR_pciconfig_write, bus, dfn, off, 4, &val);
+}
+
+void
+sparcPciCfgSetBits(PCITAG tag, int off, CARD32 mask, CARD32 bits)
+{
+ int bus, dfn, len;
+ CARD32 val = 0xffffffff;
+
+ bus = PCI_BUS_FROM_TAG(tag);
+ dfn = PCI_DFN_FROM_TAG(tag);
+
+ syscall(__NR_pciconfig_read, bus, dfn, off, 4, &val);
+ val = (val & ~mask) | (bits & mask);
+ syscall(__NR_pciconfig_write, bus, dfn, off, 4, &val);
+}
+
+int sparcUseHWMulDiv(void);
+
+#if defined(__GNUC__) && defined(__GLIBC__)
+#define HWCAP_SPARC_MULDIV 8
+extern unsigned long int _dl_hwcap;
+#endif
+
+int
+sparcUseHWMulDiv(void)
+{
+ FILE *f;
+ char buffer[1024];
+ char *p;
+#if defined(__GNUC__) && defined(__GLIBC__)
+ unsigned long *hwcap;
+ __asm(".weak _dl_hwcap");
+
+ hwcap = &_dl_hwcap;
+ __asm("" : "=r" (hwcap) : "0" (hwcap));
+ if (hwcap) {
+ if (*hwcap & HWCAP_SPARC_MULDIV)
+ return 1;
+ else
+ return 0;
+ }
+#endif
+ f = fopen("/proc/cpuinfo","r");
+ if (!f) return 0;
+ while (fgets(buffer, 1024, f) != NULL) {
+ if (!strncmp (buffer, "type", 4)) {
+ p = strstr (buffer, "sun4");
+ if (p && (p[4] == 'u' || p[4] == 'd' || p[4] == 'm')) {
+ fclose(f);
+ return 1;
+ }
+ }
+ }
+ fclose(f);
+ return 0;
+}
+#endif /* Linux */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h b/xc/programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h
new file mode 100644
index 000000000..ceb243422
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h
@@ -0,0 +1,622 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h,v 1.20 1999/07/06 11:38:52 dawes Exp $ */
+/*
+ * Copyright 1998 by Concurrent Computer Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Concurrent Computer
+ * Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Concurrent Computer Corporation makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Copyright 1998 by Metro Link Incorporated
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Metro Link
+ * Incorporated not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Metro Link Incorporated makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * This file is derived in part from the original xf86_PCI.h that included
+ * following copyright message:
+ *
+ * Copyright 1995 by Robin Cutshaw <robin@XFree86.Org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of the above listed copyright holder(s)
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. The above listed
+ * copyright holder(s) make(s) no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/*
+ * This file contains just the public interface to the PCI code.
+ * Drivers should use this file rather than Pci.h.
+ */
+
+#ifndef _XF86PCI_H
+#define _XF86PCI_H 1
+#include "Xarch.h"
+#include "Xfuncproto.h"
+#include "misc.h"
+
+/*
+ * PCI cfg space definitions (e.g. stuff right out of the PCI spec
+ */
+/* Device identification register */
+#define PCI_ID_REG 0x00
+
+/* Command and status register */
+#define PCI_CMD_STAT_REG 0x04
+#define PCI_CMD_BASE_REG 0x10
+#define PCI_CMD_BIOS_REG 0x30
+#define PCI_CMD_MASK 0xffff
+#define PCI_CMD_IO_ENABLE 0x01
+#define PCI_CMD_MEM_ENABLE 0x02
+#define PCI_CMD_MASTER_ENABLE 0x04
+#define PCI_CMD_SPECIAL_ENABLE 0x08
+#define PCI_CMD_INVALIDATE_ENABLE 0x10
+#define PCI_CMD_PALETTE_ENABLE 0x20
+#define PCI_CMD_PARITY_ENABLE 0x40
+#define PCI_CMD_STEPPING_ENABLE 0x80
+#define PCI_CMD_SERR_ENABLE 0x100
+#define PCI_CMD_BACKTOBACK_ENABLE 0x200
+#define PCI_CMD_BIOS_ENABLE 0x01
+
+/* base class */
+#define PCI_CLASS_REG 0x08
+#define PCI_CLASS_MASK 0xff000000
+#define PCI_CLASS_SHIFT 24
+#define PCI_CLASS_EXTRACT(x) (((x) & PCI_CLASS_MASK) >> PCI_CLASS_SHIFT)
+
+/* base class values */
+#define PCI_CLASS_PREHISTORIC 0x00
+#define PCI_CLASS_MASS_STORAGE 0x01
+#define PCI_CLASS_NETWORK 0x02
+#define PCI_CLASS_DISPLAY 0x03
+#define PCI_CLASS_MULTIMEDIA 0x04
+#define PCI_CLASS_MEMORY 0x05
+#define PCI_CLASS_BRIDGE 0x06
+#define PCI_CLASS_COMMUNICATIONS 0x07
+#define PCI_CLASS_SYSPERIPH 0x08
+#define PCI_CLASS_INPUT 0x09
+#define PCI_CLASS_DOCKING 0x0a
+#define PCI_CLASS_PROCESSOR 0x0b
+#define PCI_CLASS_SERIALBUS 0x0c
+#define PCI_CLASS_WIRELESS 0x0d
+#define PCI_CLASS_I2O 0x0e
+#define PCI_CLASS_SATELLITE 0x0f
+#define PCI_CLASS_CRYPT 0x10
+#define PCI_CLASS_DATA_ACQUISTION 0x11
+#define PCI_CLASS_UNDEFINED 0xff
+
+/* sub class */
+#define PCI_SUBCLASS_MASK 0x00ff0000
+#define PCI_SUBCLASS_SHIFT 16
+#define PCI_SUBCLASS_EXTRACT(x) (((x) & PCI_SUBCLASS_MASK) >> PCI_SUBCLASS_SHIFT)
+
+/* Sub class values */
+/* 0x00 prehistoric subclasses */
+#define PCI_SUBCLASS_PREHISTORIC_MISC 0x00
+#define PCI_SUBCLASS_PREHISTORIC_VGA 0x01
+
+/* 0x01 mass storage subclasses */
+#define PCI_SUBCLASS_MASS_STORAGE_SCSI 0x00
+#define PCI_SUBCLASS_MASS_STORAGE_IDE 0x01
+#define PCI_SUBCLASS_MASS_STORAGE_FLOPPY 0x02
+#define PCI_SUBCLASS_MASS_STORAGE_IPI 0x03
+#define PCI_SUBCLASS_MASS_STORAGE_MISC 0x80
+
+/* 0x02 network subclasses */
+#define PCI_SUBCLASS_NETWORK_ETHERNET 0x00
+#define PCI_SUBCLASS_NETWORK_TOKENRING 0x01
+#define PCI_SUBCLASS_NETWORK_FDDI 0x02
+#define PCI_SUBCLASS_NETWORK_MISC 0x80
+
+/* 0x03 display subclasses */
+#define PCI_SUBCLASS_DISPLAY_VGA 0x00
+#define PCI_SUBCLASS_DISPLAY_XGA 0x01
+#define PCI_SUBCLASS_DISPLAY_MISC 0x80
+
+/* 0x04 multimedia subclasses */
+#define PCI_SUBCLASS_MULTIMEDIA_VIDEO 0x00
+#define PCI_SUBCLASS_MULTIMEDIA_AUDIO 0x01
+#define PCI_SUBCLASS_MULTIMEDIA_MISC 0x80
+
+/* 0x05 memory subclasses */
+#define PCI_SUBCLASS_MEMORY_RAM 0x00
+#define PCI_SUBCLASS_MEMORY_FLASH 0x01
+#define PCI_SUBCLASS_MEMORY_MISC 0x80
+
+/* 0x06 bridge subclasses */
+#define PCI_SUBCLASS_BRIDGE_HOST 0x00
+#define PCI_SUBCLASS_BRIDGE_ISA 0x01
+#define PCI_SUBCLASS_BRIDGE_EISA 0x02
+#define PCI_SUBCLASS_BRIDGE_MC 0x03
+#define PCI_SUBCLASS_BRIDGE_PCI 0x04
+#define PCI_SUBCLASS_BRIDGE_PCMCIA 0x05
+#define PCI_SUBCLASS_BRIDGE_NUBUS 0x06
+#define PCI_SUBCLASS_BRIDGE_CARDBUS 0x07
+#define PCI_SUBCLASS_BRIDGE_RACEWAY 0x08
+#define PCI_SUBCLASS_BRIDGE_MISC 0x80
+
+/* 0x07 communications controller subclasses */
+#define PCI_SUBCLASS_COMMUNICATIONS_SERIAL 0x00
+#define PCI_SUBCLASS_COMMUNICATIONS_PARALLEL 0x01
+#define PCI_SUBCLASS_COMMUNICATIONS_MULTISERIAL 0x02
+#define PCI_SUBCLASS_COMMUNICATIONS_MODEM 0x03
+#define PCI_SUBCLASS_COMMUNICATIONS_MISC 0x80
+
+/* 0x08 generic system peripherals subclasses */
+#define PCI_SUBCLASS_SYSPERIPH_PIC 0x00
+#define PCI_SUBCLASS_SYSPERIPH_DMA 0x01
+#define PCI_SUBCLASS_SYSPERIPH_TIMER 0x02
+#define PCI_SUBCLASS_SYSPERIPH_RTC 0x03
+#define PCI_SUBCLASS_SYSPERIPH_HOTPCI 0x04
+#define PCI_SUBCLASS_SYSPERIPH_MISC 0x80
+
+/* 0x09 input device subclasses */
+#define PCI_SUBCLASS_INPUT_KEYBOARD 0x00
+#define PCI_SUBCLASS_INPUT_DIGITIZER 0x01
+#define PCI_SUBCLASS_INPUT_MOUSE 0x02
+#define PCI_SUBCLASS_INPUT_SCANNER 0x03
+#define PCI_SUBCLASS_INPUT_GAMEPORT 0x04
+#define PCI_SUBCLASS_INPUT_MISC 0x80
+
+/* 0x0a docking station subclasses */
+#define PCI_SUBCLASS_DOCKING_GENERIC 0x00
+#define PCI_SUBCLASS_DOCKING_MISC 0x80
+
+/* 0x0b processor subclasses */
+#define PCI_SUBCLASS_PROCESSOR_386 0x00
+#define PCI_SUBCLASS_PROCESSOR_486 0x01
+#define PCI_SUBCLASS_PROCESSOR_PENTIUM 0x02
+#define PCI_SUBCLASS_PROCESSOR_ALPHA 0x10
+#define PCI_SUBCLASS_PROCESSOR_POWERPC 0x20
+#define PCI_SUBCLASS_PROCESSOR_MIPS 0x30
+#define PCI_SUBCLASS_PROCESSOR_COPROC 0x40
+
+/* 0x0c serial bus controller subclasses */
+#define PCI_SUBCLASS_SERIAL_FIREWIRE 0x00
+#define PCI_SUBCLASS_SERIAL_ACCESS 0x01
+#define PCI_SUBCLASS_SERIAL_SSA 0x02
+#define PCI_SUBCLASS_SERIAL_USB 0x03
+#define PCI_SUBCLASS_SERIAL_FIBRECHANNEL 0x04
+#define PCI_SUBCLASS_SERIAL_SMBUS 0x05
+
+/* 0x0d wireless controller subclasses */
+#define PCI_SUBCLASS_WIRELESS_IRDA 0x00
+#define PCI_SUBCLASS_WIRELESS_CONSUMER_IR 0x01
+#define PCI_SUBCLASS_WIRELESS_RF 0x02
+#define PCI_SUBCLASS_WIRELESS_MISC 0x80
+
+/* 0x0e intelligent I/O controller subclasses */
+#define PCI_SUBCLASS_I2O_I2O 0x00
+
+/* 0x0f satellite communications controller subclasses */
+#define PCI_SUBCLASS_SATELLITE_TV 0x01
+#define PCI_SUBCLASS_SATELLITE_AUDIO 0x02
+#define PCI_SUBCLASS_SATELLITE_VOICE 0x03
+#define PCI_SUBCLASS_SATELLITE_DATA 0x04
+
+/* 0x10 encryption/decryption controller subclasses */
+#define PCI_SUBCLASS_CRYPT_NET_COMPUTING 0x00
+#define PCI_SUBCLASS_CRYPT_ENTERTAINMENT 0x10
+#define PCI_SUBCLASS_CRYPT_MISC 0x80
+
+/* 0x11 data acquisition and signal processing controller subclasses */
+#define PCI_SUBCLASS_DATAACQ_DPIO 0x00
+#define PCI_SUBCLASS_DATAACQ_MISC 0x80
+
+
+/* Header */
+#define PCI_HEADER_MISC 0x0c
+#define PCI_HEADER_MULTIFUNCTION 0x00800000
+
+/* Interrupt configration register */
+#define PCI_INTERRUPT_REG 0x3c
+#define PCI_INTERRUPT_PIN_MASK 0x0000ff00
+#define PCI_INTERRUPT_PIN_EXTRACT(x) ((((x) & PCI_INTERRUPT_PIN_MASK) >> 8) & 0xff)
+#define PCI_INTERRUPT_PIN_NONE 0x00
+#define PCI_INTERRUPT_PIN_A 0x01
+#define PCI_INTERRUPT_PIN_B 0x02
+#define PCI_INTERRUPT_PIN_C 0x03
+#define PCI_INTERRUPT_PIN_D 0x04
+
+#define PCI_INTERRUPT_LINE_MASK 0x000000ff
+#define PCI_INTERRUPT_LINE_EXTRACT(x) ((((x) & PCI_INTERRUPT_LINE_MASK) >> 0) & 0xff)
+#define PCI_INTERRUPT_LINE_INSERT(x,v) (((x) & ~PCI_INTERRUPT_LINE_MASK) | ((v) << 0))
+
+/* Base registers */
+#define PCI_MAP_REG_START 0x10
+#define PCI_MAP_REG_END 0x28
+#define PCI_MAP_ROM_REG 0x30
+
+#define PCI_MAP_MEMORY 0x00000000
+#define PCI_MAP_IO 0x00000001
+
+#define PCI_MAP_MEMORY_TYPE 0x00000007
+#define PCI_MAP_IO_TYPE 0x00000003
+
+#define PCI_MAP_MEMORY_TYPE_32BIT 0x00000000
+#define PCI_MAP_MEMORY_TYPE_32BIT_1M 0x00000002
+#define PCI_MAP_MEMORY_TYPE_64BIT 0x00000004
+#define PCI_MAP_MEMORY_TYPE_MASK 0x00000006
+#define PCI_MAP_MEMORY_CACHABLE 0x00000008
+#define PCI_MAP_MEMORY_ATTR_MASK 0x0000000e
+#define PCI_MAP_MEMORY_ADDRESS_MASK 0xfffffff0
+
+#define PCI_MAP_IO_ATTR_MASK 0x00000000
+
+#define PCI_MAP_IS_IO(b) ((b) & PCI_MAP_IO)
+#define PCI_MAP_IS_MEM(b) (!PCI_MAP_IS_IO(b))
+
+#define PCI_MAP_IS64BITMEM(b) \
+ (((b) & PCI_MAP_MEMORY_TYPE_MASK) == PCI_MAP_MEMORY_TYPE_64BIT)
+
+#define PCIGETMEMORY(b) ((b) & PCI_MAP_MEMORY_ADDRESS_MASK)
+
+#define PCI_MAP_IO_ADDRESS_MASK 0xfffffffc
+
+#define PCIGETIO(b) ((b) & PCI_MAP_IO_ADDRESS_MASK)
+
+#define PCI_MAP_ROM_DECODE_ENABLE 0x00000001
+#define PCI_MAP_ROM_ADDRESS_MASK 0xfffff800
+
+#define PCIGETROM(b) ((b) & PCI_MAP_ROM_ADDRESS_MASK)
+
+/* PCI-PCI bridge mapping registers */
+#define PCI_PCI_BRIDGE_BUS_REG 0x18
+#define PCI_SUBORDINATE_BUS_MASK 0x00ff0000
+#define PCI_SECONDARY_BUS_MASK 0x0000ff00
+#define PCI_PRIMARY_BUS_MASK 0x000000ff
+
+#define PCI_SUBORDINATE_BUS_EXTRACT(x) (((x) >> 16) & 0xff)
+#define PCI_SECONDARY_BUS_EXTRACT(x) (((x) >> 8) & 0xff)
+#define PCI_PRIMARY_BUS_EXTRACT(x) (((x) ) & 0xff)
+
+#define PCI_PRIMARY_BUS_INSERT(x, y) (((x) & ~PCI_PRIMARY_BUS_MASK) | ((y) << 0))
+#define PCI_SECONDARY_BUS_INSERT(x, y) (((x) & ~PCI_SECONDARY_BUS_MASK) | ((y) << 8))
+#define PCI_SUBORDINATE_BUS_INSERT(x, y) (((x) & ~PCI_SUBORDINATE_BUS_MASK) | (( y) << 16))
+
+#define PCI_PCI_BRIDGE_IO_REG 0x1c
+#define PCI_PCI_BRIDGE_MEM_REG 0x20
+#define PCI_PCI_BRIDGE_PMEM_REG 0x24
+
+#define PCI_PPB_IOBASE_EXTRACT(x) (((x) << 8) & 0xFF00)
+#define PCI_PPB_IOLIMIT_EXTRACT(x) (((x) << 0) & 0xFF00)
+
+#define PCI_PPB_MEMBASE_EXTRACT(x) (((x) << 16) & 0xFFFF0000)
+#define PCI_PPB_MEMLIMIT_EXTRACT(x) (((x) << 0) & 0xFFFF0000)
+
+#define PCI_PCI_BRIDGE_CONTROL_REG 0x3E
+#define PCI_PCI_BRIDGE_VGA_EN 0x08
+
+/* Subsystem identification register */
+#define PCI_SUBSYSTEM_ID_REG 0x2c
+
+/* User defined cfg space regs */
+#define PCI_REG_USERCONFIG 0x40
+#define PCI_OPTION_REG 0x40
+
+/*
+ * Typedefs, etc...
+ */
+
+/* Primitive Types */
+typedef unsigned long ADDRESS; /* Memory/PCI address */
+typedef unsigned long PCITAG;
+
+/*
+ * PCI configuration space
+ */
+typedef struct pci_cfg_regs {
+ /* start of official PCI config space header */
+ union { /* Offset 0x0 - 0x3 */
+ CARD32 device_vendor;
+ struct {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ CARD16 device;
+ CARD16 vendor;
+#else
+ CARD16 vendor;
+ CARD16 device;
+#endif
+ } dv;
+ } dv_id;
+
+ union { /* Offset 0x4 - 0x8 */
+ CARD32 status_command;
+ struct {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ CARD16 status;
+ CARD16 command;
+#else
+ CARD16 command;
+ CARD16 status;
+#endif
+ } sc;
+ } stat_cmd;
+
+ union { /* Offset 0x8 - 0xb */
+ CARD32 class_revision;
+ struct {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ CARD8 base_class;
+ CARD8 sub_class;
+ CARD8 prog_if;
+ CARD8 rev_id;
+#else
+ CARD8 rev_id;
+ CARD8 prog_if;
+ CARD8 sub_class;
+ CARD8 base_class;
+#endif
+ } cr;
+ } class_rev;
+
+ union { /* Offset 0xc - 0xf */
+ CARD32 bist_header_latency_cache;
+ struct {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ CARD8 bist;
+ CARD8 header_type;
+ CARD8 latency_timer;
+ CARD8 cache_line_size;
+#else
+ CARD8 cache_line_size;
+ CARD8 latency_timer;
+ CARD8 header_type;
+ CARD8 bist;
+#endif
+ } bhlc;
+ } bhlc;
+
+ union { /* Offset 0x10 - 0x27 */
+ struct { /* header type 0 */
+ CARD32 dv_base0;
+ CARD32 dv_base1;
+ CARD32 dv_base2;
+ CARD32 dv_base3;
+ CARD32 dv_base4;
+ CARD32 dv_base5;
+ } dv;
+ struct { /* header type 1 */
+ CARD32 bg_rsrvd[2];
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ CARD8 secondary_latency_timer;
+ CARD8 subordinate_bus_number;
+ CARD8 secondary_bus_number;
+ CARD8 primary_bus_number;
+
+ CARD16 secondary_status;
+ CARD8 io_limit;
+ CARD8 io_base;
+
+ CARD16 mem_limit;
+ CARD16 mem_base;
+
+ CARD16 prefetch_mem_limit;
+ CARD16 prefetch_mem_base;
+#else
+ CARD8 primary_bus_number;
+ CARD8 secondary_bus_number;
+ CARD8 subordinate_bus_number;
+ CARD8 secondary_latency_timer;
+
+ CARD8 io_base;
+ CARD8 io_limit;
+ CARD16 secondary_status;
+
+ CARD16 mem_base;
+ CARD16 mem_limit;
+
+ CARD16 prefetch_mem_base;
+ CARD16 prefetch_mem_limit;
+#endif
+ } bg;
+ } bc;
+ union { /* Offset 0x28 - 0x2b */
+ CARD32 rsvd1;
+ CARD32 cardbus_cis_ptr;
+ } c_cis;
+ union { /* Offset 0x2c - 0x2f */
+ CARD32 subsys_card_vendor;
+ CARD32 rsvd2;
+ struct {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ CARD16 subsys_card;
+ CARD16 subsys_vendor;
+#else
+ CARD16 subsys_vendor;
+ CARD16 subsys_card;
+#endif
+ } ssys;
+ } ssys_id;
+ CARD32 baserom; /* Offset 0x30 - 0x33 */
+ CARD32 rsvd3; /* Offset 0x34 - 0x37 */
+ CARD32 rsvd4; /* Offset 0x38 - 0x3b */
+ union { /* Offset 0x3c - 0x3f */
+ union { /* header type 0 */
+ CARD32 max_min_ipin_iline;
+ struct {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ CARD8 max_lat;
+ CARD8 min_gnt;
+ CARD8 int_pin;
+ CARD8 int_line;
+#else
+ CARD8 int_line;
+ CARD8 int_pin;
+ CARD8 min_gnt;
+ CARD8 max_lat;
+#endif
+ } mmii;
+ } mmii;
+ struct { /* header type 1 */
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ CARD8 rsvd4;
+ CARD8 bridge_control;
+ CARD8 rsvd2;
+ CARD8 rsvd1;
+#else
+ CARD8 rsvd1;
+ CARD8 rsvd2;
+ CARD8 bridge_control;
+ CARD8 rsvd4;
+#endif
+ } bctrl;
+ } bm;
+ union { /* Offset 0x40 - 0xff */
+ CARD32 dwords[48];
+ CARD32 bytes[192];
+ } devspf;
+} pciCfgRegs;
+
+typedef union pci_cfg_spc {
+ pciCfgRegs regs;
+ CARD32 dwords[256/sizeof(CARD32)];
+ CARD8 bytes[256/sizeof(CARD8)];
+} pciCfgSpc;
+
+/*
+ * Data structure returned by xf86scanpci including contents of
+ * PCI config space header
+ */
+typedef struct pci_device {
+ PCITAG tag;
+ int busnum;
+ int devnum;
+ int funcnum;
+ pciCfgSpc cfgspc;
+ int basesize[7]; /* number of bits in base addr allocations */
+} pciDevice, *pciConfigPtr;
+
+typedef enum {
+ WRITE,
+ READ,
+ SET_BITS
+} pciFunc;
+
+#define pci_device_vendor cfgspc.regs.dv_id.device_vendor
+#define pci_vendor cfgspc.regs.dv_id.dv.vendor
+#define pci_device cfgspc.regs.dv_id.dv.device
+#define pci_status_command cfgspc.regs.stat_cmd.status_command
+#define pci_command cfgspc.regs.stat_cmd.sc.command
+#define pci_status cfgspc.regs.stat_cmd.sc.status
+#define pci_class_revision cfgspc.regs.class_rev.class_revision
+#define pci_rev_id cfgspc.regs.class_rev.cr.rev_id
+#define pci_prog_if cfgspc.regs.class_rev.cr.prog_if
+#define pci_sub_class cfgspc.regs.class_rev.cr.sub_class
+#define pci_base_class cfgspc.regs.class_rev.cr.base_class
+#define pci_bist_header_latency_cache cfgspc.regs.bhlc.bist_header_latency_cache
+#define pci_cache_line_size cfgspc.regs.bhlc.bhlc.cache_line_size
+#define pci_latency_timer cfgspc.regs.bhlc.bhlc.latency_timer
+#define pci_header_type cfgspc.regs.bhlc.bhlc.header_type
+#define pci_bist cfgspc.regs.bhlc.bhlc.bist
+#define pci_base0 cfgspc.regs.bc.dv.dv_base0
+#define pci_base1 cfgspc.regs.bc.dv.dv_base1
+#define pci_base2 cfgspc.regs.bc.dv.dv_base2
+#define pci_base3 cfgspc.regs.bc.dv.dv_base3
+#define pci_base4 cfgspc.regs.bc.dv.dv_base4
+#define pci_base5 cfgspc.regs.bc.dv.dv_base5
+#define pci_cardbus_cis_ptr cfgspc.regs.c_cis.cardbus_cis_ptr
+#define pci_subsys_card_vendor cfgspc.regs.ssys_id.subsys_card_vendor
+#define pci_subsys_vendor cfgspc.regs.ssys_id.ssys.subsys_vendor
+#define pci_subsys_card cfgspc.regs.ssys_id.ssys.subsys_card
+#define pci_baserom cfgspc.regs.baserom
+#define pci_primary_bus_number cfgspc.regs.bc.bg.primary_bus_number
+#define pci_secondary_bus_number cfgspc.regs.bc.bg.secondary_bus_number
+#define pci_subordinate_bus_number cfgspc.regs.bc.bg.subordinate_bus_number
+#define pci_secondary_latency_timer cfgspc.regs.bc.bg.secondary_latency_timer
+#define pci_io_base cfgspc.regs.bc.bg.io_base
+#define pci_io_limit cfgspc.regs.bc.bg.io_limit
+#define pci_secondary_status cfgspc.regs.bc.bg.secondary_status
+#define pci_mem_base cfgspc.regs.bc.bg.mem_base
+#define pci_mem_limit cfgspc.regs.bc.bg.mem_limit
+#define pci_prefetch_mem_base cfgspc.regs.bc.bg.prefetch_mem_base
+#define pci_prefetch_mem_limit cfgspc.regs.bc.bg.prefetch_mem_limit
+#define pci_rsvd1 cfgspc.regs.c_cis.rsvd1;
+#define pci_rsvd2 cfgspc.regs.ssys_id.rsvd2;
+#define pci_int_line cfgspc.regs.bm.mmii.mmii.int_line
+#define pci_int_pin cfgspc.regs.bm.mmii.mmii.int_pin
+#define pci_min_gnt cfgspc.regs.bm.mmii.mmii.min_gnt
+#define pci_max_lat cfgspc.regs.bm.mmii.mmii.max_lat
+#define pci_max_min_ipin_iline cfgspc.regs.bm.mmii.max_min_ipin_iline
+#define pci_bridge_control cfgspc.regs.bm.bctrl.bridge_control
+#define pci_user_config cfgspc.regs.devspf.dwords[0]
+#define pci_user_config_0 cfgspc.regs.devspf.bytes[0]
+#define pci_user_config_1 cfgspc.regs.devspf.bytes[1]
+#define pci_user_config_2 cfgspc.regs.devspf.bytes[2]
+#define pci_user_config_3 cfgspc.regs.devspf.bytes[3]
+
+/* Public PCI access functions */
+void pciInit(void);
+PCITAG pciFindFirst(CARD32 id, CARD32 mask);
+PCITAG pciFindNext(void);
+CARD32 pciReadLong(PCITAG tag, int offset);
+CARD16 pciReadWord(PCITAG tag, int offset);
+CARD8 pciReadByte(PCITAG tag, int offset);
+void pciWriteLong(PCITAG tag, int offset, CARD32 val);
+void pciWriteWord(PCITAG tag, int offset, CARD16 val);
+void pciWriteByte(PCITAG tag, int offset, CARD8 val);
+void pciSetBitsLong(PCITAG tag, int offset, CARD32 mask, CARD32 val);
+void pciSetBitsByte(PCITAG tag, int offset, CARD8 mask, CARD8 val);
+pointer pciLongFunc(PCITAG tag, pciFunc func);
+ADDRESS pciBusAddrToHostAddr(PCITAG tag, ADDRESS addr);
+ADDRESS pciHostAddrToBusAddr(PCITAG tag, ADDRESS addr);
+PCITAG pciTag(int busnum, int devnum, int funcnum);
+int pciGetBaseSize(PCITAG tag, int indx, Bool destructive, Bool *min);
+pointer xf86MapPciMem(int ScreenNum, int Flags, PCITAG Tag,
+ unsigned long Base, unsigned long Size);
+int xf86ReadPciBIOS(unsigned long Offset, PCITAG Tag, int basereg,
+ unsigned char *Buf, int Len);
+pciConfigPtr *xf86scanpci(int flags);
+
+/* Old sytle PCI access functions (for compatibility) */
+#if 0
+void xf86writepci(int, int, int, int, int, CARD32, CARD32);
+#endif
+
+#endif /* _XF86PCI_H */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/dgux/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/dgux/Imakefile
new file mode 100644
index 000000000..d62452b9b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/dgux/Imakefile
@@ -0,0 +1,30 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/dgux/Imakefile,v 1.2 1999/04/04 00:20:56 dawes Exp $
+#include <Server.tmpl>
+
+BIOS_MOD = bios_DGmmap
+
+SRCS = dgux_init.c dgux_video.c IO_utils.c dgux_io.c $(BIOS_MOD).c VTsw_noop.c \
+ dgux_kbd.c dgux_kbdEv.c dgux_tty.c std_mouse.c std_mseEv.c \
+ stdResource.c
+
+OBJS = dgux_init.o dgux_video.o IO_utils.o dgux_io.o $(BIOS_MOD).o VTsw_noop.o \
+ dgux_kbd.o dgux_kbdEv.o dgux_tty.o std_mouse.o std_mseEv.o \
+ stdResource.o
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+RESDEFINES = -DUSESTDRES
+
+DEFINES = $(RESDEFINES)
+
+SubdirLibraryRule($(OBJS))
+NormalLibraryObjectRule()
+
+LinkSourceFile(VTsw_noop,../shared)
+LinkSourceFile(IO_utils,../shared)
+LinkSourceFile(std_mouse,../shared)
+LinkSourceFile(std_mseEv,../shared)
+LinkSourceFile(stdResource.c,../shared)
+
+DependTarget()
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/dgux/bios_DGmmap.c b/xc/programs/Xserver/hw/xfree86/os-support/dgux/bios_DGmmap.c
new file mode 100644
index 000000000..33fd295b3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/dgux/bios_DGmmap.c
@@ -0,0 +1,65 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/dgux/bios_DGmmap.c,v 1.2 1999/07/18 08:14:35 dawes Exp $ */
+/*
+ * INTEL DG/UX RELEASE 4.20 MU03
+ * Copyright 1997 Takis Psarogiannakopoulos Cambridge,UK
+ * <takis@dpmms.cam.ac.uk>
+ *
+ * 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.
+ * XCONSORTIUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FITNESS, IN NO EVENT SHALL XCONSORTIUM 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 "input.h"
+#include "scrnintstr.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+/*
+ * Read the BIOS via mmap() to the device /dev/mem.
+ */
+int xf86ReadBIOS(Base, Offset, Buf, Len)
+unsigned long Base;
+unsigned long Offset;
+unsigned char *Buf;
+int Len;
+{
+ int fd;
+ unsigned char *ptr;
+ int psize;
+ int mlen;
+
+ if ((fd = open(DEV_MEM, O_RDONLY)) < 0)
+ {
+ ErrorF("xf86ReadBios: Failed to open %s (%s)\n", DEV_MEM,
+ strerror(errno));
+ return(-1);
+ }
+ psize = xf86getpagesize();
+ mlen = (Offset + Len + psize - 1) & ~psize;
+ /* Base is assumed to be page-aligned. */
+ ptr = (unsigned char *)mmap((caddr_t)0, mlen, PROT_READ, MAP_SHARED,
+ fd, (off_t)Base);
+ if ((int)ptr == -1)
+ {
+ ErrorF("xf86ReadBios: %s mmap failed\n", DEV_MEM);
+ close(fd);
+ return(-1);
+ }
+ (void)memcpy(Buf, (void *)(ptr + Offset), Len);
+ (void)munmap((caddr_t)ptr, mlen);
+ (void)close(fd);
+ return(Len);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_init.c b/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_init.c
new file mode 100644
index 000000000..d5344f7dc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_init.c
@@ -0,0 +1,180 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_init.c,v 1.1 1998/12/13 07:37:46 dawes Exp $ */
+/*
+ * INTEL DG/UX RELEASE 4.20 MU03
+ * Copyright 1997 Takis Psarogiannakopoulos Cambridge,UK
+ * <takis@dpmms.cam.ac.uk>
+ *
+ * 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.
+ * XCONSORTIUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FITNESS, IN NO EVENT SHALL XCONSORTIUM 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 "Xmd.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Procs.h"
+#include "xf86_OSlib.h"
+
+static Bool KeepTty = FALSE;
+static Bool Protect0 = FALSE;
+static int VTnum = -1;
+
+extern void xf86VTRequest(
+#if NeedFunctionPrototypes
+ int
+#endif
+);
+
+void xf86OpenConsole()
+{
+ int i;
+ int fd;
+ char vtname[14];
+
+ if (serverGeneration == 1)
+ {
+ /* check if we're run with euid==0 */
+ if (geteuid() != 0)
+ {
+ FatalError("xf86OpenConsole: Server must be suid root\n");
+ }
+ if (Protect0)
+ {
+ int fd = -1;
+
+ if ((fd = open("/dev/zero", O_RDONLY, 0)) < 0)
+ {
+ ErrorF("xf86OpenConsole: cannot open /dev/zero (%s)\n",
+ strerror(errno));
+ }
+ else
+ {
+ if ((int)mmap(0, 0x1000, PROT_NONE,
+ MAP_FIXED | MAP_SHARED, fd, 0) == -1)
+ {
+ ErrorF("xf86OpenConsole: failed to protect page 0 (%s)\n",
+ strerror(errno));
+ }
+ close(fd);
+ }
+ }
+ if (VTnum != -1)
+ {
+ xf86Info.vtno = VTnum;
+ }
+ else
+ {
+ if ((fd = open("/dev/console",O_WRONLY,0)) < 0)
+ {
+ FatalError(
+ "xf86OpenConsole: Cannot open system tty (/dev/console), (%s)\n",
+ strerror(errno));
+ }
+ close(fd);
+ }
+ xf86Info.vtno=0;
+ ErrorF(" (Intel DG/ux: using VT number: systty%d)\n\n", xf86Info.vtno);
+
+ sprintf(vtname,"/dev/console");
+
+ xf86Config(FALSE); /* Read XF86Config */
+
+ if (!KeepTty)
+ {
+ setpgrp();
+ }
+
+ if ((xf86Info.consoleFd = open("/dev/console", O_RDWR|O_NDELAY, 0)) < 0)
+ {
+ FatalError("xf86OpenConsole: Cannot open %s (%s)\n",
+ vtname, strerror(errno));
+ }
+
+
+
+ if ((xf86Info.kbdFd = open("/dev/keybd", O_RDONLY|O_NDELAY, 0)) < 0)
+ {
+ FatalError("xf86OpenConsole: Cannot open keyboard (/dev/keybd), (%s)\n", strerror(errno));
+ }
+ /* change ownerships and Grab all other system consoles */
+ chown(vtname, getuid(), getgid());
+ chown("/dev/syscon", getuid(), getgid());
+ chown("/dev/systty", getuid(), getgid());
+ if (!KeepTty)
+ {
+ /*
+ * Detach from the controlling tty to avoid char loss
+ */
+ if ((i = open("/dev/tty",O_RDWR)) >= 0)
+ {
+ ioctl(i, TIOCNOTTY, 0);
+ close(i);
+ }
+ }
+ }
+ else
+ {
+ /* serverGeneration != 1 */
+ if (!xf86VTSema)
+ sleep(5);
+ }
+ return;
+}
+
+void xf86CloseConsole()
+{
+ close(xf86Info.kbdFd); /* Close the keyboard */
+ close(xf86Info.consoleFd); /* Close the system console */
+ return;
+}
+
+int xf86ProcessArgument(argc, argv, i)
+int argc;
+char *argv[];
+int i;
+{
+ if (!strcmp(argv[i], "-keeptty"))
+ {
+ KeepTty = TRUE;
+ return(1);
+ }
+ if (!strcmp(argv[i], "-protect0"))
+ {
+ Protect0 = TRUE;
+ return(1);
+ }
+ if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
+ {
+ if (sscanf(argv[i], "vt%2d", &VTnum) == 0)
+ {
+ UseMsg();
+ VTnum = -1;
+ return(0);
+ }
+ return(1);
+ }
+ return(0);
+}
+
+void xf86UseMsg()
+{
+ ErrorF("-keeptty ");
+ ErrorF("don't detach controlling tty (for debugging only)\n");
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_io.c b/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_io.c
new file mode 100644
index 000000000..6269f2630
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_io.c
@@ -0,0 +1,84 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_io.c,v 1.2 1999/01/26 10:40:38 dawes Exp $ */
+/*
+ * INTEL DG/UX RELEASE 4.20 MU03
+ * Copyright 1997 Takis Psarogiannakopoulos Cambridge,UK
+ * <takis@dpmms.cam.ac.uk>
+ *
+ * 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.
+ * XCONSORTIUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FITNESS, IN NO EVENT SHALL XCONSORTIUM 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_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+
+#include "compiler.h"
+
+#include "xf86Procs.h"
+#include "xf86_OSlib.h"
+
+
+
+void xf86SoundKbdBell(loudness, pitch, duration)
+int loudness;
+int pitch;
+int duration;
+{
+ if (loudness && pitch)
+ {
+
+ /*
+ * We use KBD_TONE_HIGH to avoid putting the server
+ * to sleep
+ */
+ ioctl(xf86Info.kbdFd, KBD_TONE_HIGH,
+ ((1193190 / pitch) & 0xffff) |
+ (((unsigned long)duration *
+ loudness / 50) << 16));
+
+ }
+}
+
+
+
+void xf86MouseInit(mouse)
+MouseDevPtr mouse;
+{
+ return;
+}
+
+
+
+/* Added for DG/ux: only RDONLY will not crash the Xserver */
+int xf86MouseOn(mouse)
+MouseDevPtr mouse;
+{
+ if ((mouse->mseFd = open(mouse->mseDevice, O_RDONLY|O_NDELAY)) < 0)
+ {
+ if (xf86Info.allowMouseOpenFail) {
+ ErrorF("Cannot open mouse (%s) - Continuing...\n",
+ strerror(errno));
+ return(-2);
+ }
+ FatalError("Cannot open mouse (%s)\n", strerror(errno));
+ }
+
+ xf86SetupMouse(mouse);
+
+ /* Flush any pending input */
+ ioctl(mouse->mseFd, TCFLSH, 0);
+ return(mouse->mseFd);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_kbd.c b/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_kbd.c
new file mode 100644
index 000000000..f2023b25d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_kbd.c
@@ -0,0 +1,121 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_kbd.c,v 1.1 1998/12/13 07:37:46 dawes Exp $ */
+/*
+ * INTEL DG/UX RELEASE 4.20 MU03
+ * Copyright 1997 Takis Psarogiannakopoulos Cambridge,UK
+ * <takis@dpmms.cam.ac.uk>
+ *
+ * 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.
+ * XCONSORTIUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FITNESS, IN NO EVENT SHALL XCONSORTIUM 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.
+ *
+ */
+
+/* *Contents*
+
+ 1 xf86KbdSetLeds
+ 2 xf86KbdGetLeds
+ 3 xf86SetKbdRepeat
+ 4 xf86KbdInit()
+ 5 xf86KbdOn()
+ 6 xf86KbdOff()
+
+*/
+
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+
+#include "compiler.h"
+
+#include "xf86Procs.h"
+#include "xf86_OSlib.h"
+
+
+static struct termios kbdtty;
+
+
+/* ADDED FOR INTEL DGUX */
+void xf86SetKbdLeds(leds)
+int leds;
+{
+ ioctl(xf86Info.kbdFd, KBD_SET_LED, leds);
+}
+
+
+
+/* ADDED FOR INTEL DGUX */
+int xf86GetKbdLeds()
+{
+ int leds;
+
+ ioctl(xf86Info.kbdFd, KBD_GET_STATE, &leds);
+ return(leds);
+}
+
+/* ADDED FOR INTEL DGUX */
+#if NeedFunctionPrototypes
+void xf86SetKbdRepeat(char rad)
+#else
+void xf86SetKbdRepeat(rad)
+char rad;
+#endif
+{
+ return;
+}
+
+
+
+
+/* ADDED FOR INTEL DGUX */
+
+void xf86KbdInit()
+{
+ tcgetattr(xf86Info.kbdFd, &kbdtty);
+}
+
+
+
+
+
+/* ADDED FOR INTEL DGUX */
+
+int xf86KbdOn()
+{
+ struct termios nTty;
+
+ nTty = kbdtty;
+ nTty.c_iflag = IGNPAR | IGNBRK;
+ nTty.c_oflag = 0;
+ nTty.c_cflag = CREAD | CS8;
+ nTty.c_lflag = 0;
+ nTty.c_cc[VTIME] = 0;
+ nTty.c_cc[VMIN] = 1;
+ cfsetispeed(&nTty, 9600);
+ cfsetospeed(&nTty, 9600);
+ tcsetattr(xf86Info.kbdFd, TCSANOW, &nTty);
+ return(xf86Info.kbdFd);
+}
+
+
+
+
+
+/* Intel DG/ux */
+int xf86KbdOff()
+{
+ tcsetattr(xf86Info.kbdFd, TCSANOW, &kbdtty);
+ return(xf86Info.kbdFd);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_kbdEv.c b/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_kbdEv.c
new file mode 100644
index 000000000..d847bd9a4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_kbdEv.c
@@ -0,0 +1,43 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_kbdEv.c,v 1.1 1998/12/13 07:37:47 dawes Exp $ */
+/*
+ * INTEL DG/UX RELEASE 4.20 MU02
+ * Copyright 1997 Takis Psarogiannakopoulos Cambridge,UK
+ * <takis@dpmms.cam.ac.uk>
+ *
+ * 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.
+ * XCONSORTIUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FITNESS, IN NO EVENT SHALL XCONSORTIUM 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_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+
+#include "xf86Procs.h"
+#include "xf86_OSlib.h"
+
+void xf86KbdEvents()
+{
+ unsigned char rBuf[64];
+ int nBytes, i;
+
+ if ((nBytes = read( xf86Info.kbdFd, (char *)rBuf, sizeof(rBuf))) > 0)
+ {
+ for (i = 0; i < nBytes; i++)
+ xf86PostKbdEvent(rBuf[i]);
+ }
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_tty.c b/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_tty.c
new file mode 100644
index 000000000..600c918ca
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_tty.c
@@ -0,0 +1,171 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_tty.c,v 1.2 1999/01/26 10:40:38 dawes Exp $ */
+/*
+ * INTEL DG/UX RELEASE 4.20 MU03
+ * Copyright 1997 Takis Psarogiannakopoulos Cambridge,UK
+ * <takis@dpmms.cam.ac.uk>
+ *
+ * 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.
+ * XCONSORTIUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FITNESS, IN NO EVENT SHALL XCONSORTIUM 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.
+ *
+ */
+/* BSD (POSIX) Flavor tty for ix86 DG/ux R4.20MU03 */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+
+#include "xf86Procs.h"
+#include "xf86_OSlib.h"
+#include "xf86_Config.h"
+
+static Bool not_a_tty = FALSE;
+
+void xf86SetMouseSpeed(mouse, old, new, cflag)
+MouseDevPtr mouse;
+int old;
+int new;
+unsigned cflag;
+{
+ struct termios tty;
+ char *c;
+
+ if (not_a_tty)
+ return;
+
+ if (tcgetattr(mouse->mseFd, &tty) < 0)
+ {
+ not_a_tty = TRUE;
+ ErrorF("Warning: %s unable to get status of mouse fd (%s)\n",
+ mouse->mseDevice, strerror(errno));
+ return;
+ }
+
+ /* this will query the initial baudrate only once */
+ if (mouse->oldBaudRate < 0) {
+ switch (cfgetispeed(&tty))
+ {
+ case B9600:
+ mouse->oldBaudRate = 9600;
+ break;
+ case B4800:
+ mouse->oldBaudRate = 4800;
+ break;
+ case B2400:
+ mouse->oldBaudRate = 2400;
+ break;
+ case B1200:
+ default:
+ mouse->oldBaudRate = 1200;
+ break;
+ }
+ }
+
+ tty.c_iflag = IGNBRK | IGNPAR;
+ tty.c_oflag = 0;
+ tty.c_lflag = 0;
+ tty.c_cflag = (tcflag_t)cflag;
+ tty.c_cc[VTIME] = 0;
+ tty.c_cc[VMIN] = 1;
+
+ switch (old)
+ {
+ case 9600:
+ cfsetispeed(&tty, B9600);
+ cfsetospeed(&tty, B9600);
+ break;
+ case 4800:
+ cfsetispeed(&tty, B4800);
+ cfsetospeed(&tty, B4800);
+ break;
+ case 2400:
+ cfsetispeed(&tty, B2400);
+ cfsetospeed(&tty, B2400);
+ break;
+ case 1200:
+ default:
+ cfsetispeed(&tty, B1200);
+ cfsetospeed(&tty, B1200);
+ }
+
+ if (tcsetattr(mouse->mseFd, TCSADRAIN, &tty) < 0)
+ {
+ if (xf86Info.allowMouseOpenFail) {
+ ErrorF("Unable to set status of mouse fd (%s) - Continuing...\n",
+ strerror(errno));
+ return;
+ }
+ xf86FatalError("Unable to set status of mouse fd (%s)\n",
+ strerror(errno));
+ }
+
+ switch (new)
+ {
+ case 9600:
+ c = "*q";
+ cfsetispeed(&tty, B9600);
+ cfsetospeed(&tty, B9600);
+ break;
+ case 4800:
+ c = "*p";
+ cfsetispeed(&tty, B4800);
+ cfsetospeed(&tty, B4800);
+ break;
+ case 2400:
+ c = "*o";
+ cfsetispeed(&tty, B2400);
+ cfsetospeed(&tty, B2400);
+ break;
+ case 1200:
+ default:
+ c = "*n";
+ cfsetispeed(&tty, B1200);
+ cfsetospeed(&tty, B1200);
+ }
+
+ if (mouse->mseType == P_LOGIMAN || mouse->mseType == P_LOGI)
+ {
+ if (write(mouse->mseFd, c, 2) != 2)
+ {
+ if (xf86AllowMouseOpenFail) {
+ ErrorF("Unable to write to mouse fd (%s) - Continuing...\n",
+ strerror(errno));
+ return;
+ }
+ xf86FatalError("Unable to write to mouse fd (%s)\n",
+ strerror(errno));
+ }
+ }
+ usleep(100000);
+
+ if (tcsetattr(mouse->mseFd, TCSADRAIN, &tty) < 0)
+ {
+ if (xf86AllowMouseOpenFail) {
+ ErrorF("Unable to set status of mouse fd (%s) - Continuing...\n",
+ strerror(errno));
+ return;
+ }
+ xf86FatalError("Unable to set status of mouse fd (%s)\n",
+ strerror(errno));
+ }
+}
+
+/* ADDED FOR X 3.3.2.3 */
+int
+xf86FlushInput(fd)
+int fd;
+{
+ return tcflush(fd, TCIFLUSH);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_video.c b/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_video.c
new file mode 100644
index 000000000..600a51481
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_video.c
@@ -0,0 +1,544 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/dgux/dgux_video.c,v 1.4 1999/04/29 12:24:52 dawes Exp $ */
+/*
+ * INTEL DG/UX RELEASE 4.20 MU03
+ * Copyright 1997 Takis Psarogiannakopoulos Cambridge,UK
+ * <takis@dpmms.cam.ac.uk>
+ *
+ *
+ * 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.
+ * XFREE86 PROJECT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FITNESS, IN NO EVENT SHALL XCONSORTIUM 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 "input.h"
+#include "scrnintstr.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+/* Stuff for the SET_IOPL() ,RESET_IOPL() */
+/* #include <fcntl.h> */
+static int io_takis;
+int set_takis;
+
+
+/***************************************************************************/
+/* SET_IOPL() and RESET_IOPL() section for ix86 DG/ux 4.20MU03 */
+/***************************************************************************/
+
+
+int SET_IOPL()
+{
+ io_takis=open("/dev/console", O_RDWR,0);
+ if ((io_takis) < 0)
+ {
+ return(-1);
+ }
+ set_takis = ioctl(io_takis,KDENABIO,0);
+
+ if (set_takis < 0)
+ {
+ return(-1);
+ }
+ return(1);
+}
+
+
+
+
+void RESET_IOPL()
+{
+
+ ioctl(io_takis,KDDISABIO,0);
+ close(io_takis);
+ return;
+
+}
+
+/***************************************************************************/
+/* DG/ux Video Memory Mapping part */
+/***************************************************************************/
+
+#undef HAS_SVR3_MMAPDRV /* ix86 DG/ux is a typical SVR4 without SVR3_MMAPDRV */
+
+Bool xf86LinearVidMem()
+{
+ return(TRUE);
+}
+
+
+
+pointer AllocAddress[MAXSCREENS][NUM_REGIONS];
+#ifndef SVR4
+static int mmapFd = -2;
+#endif
+
+
+
+#if 0
+/* For DGA support?? */
+static struct xf86memMap {
+ int offset;
+ int memSize;
+} xf86memMaps[MAXSCREENS];
+#endif
+
+
+
+pointer
+xf86MapVidMem(int ScreenNum, int Region, unsigned long Base, unsigned long Size)
+{
+ pointer base;
+ int fd;
+
+#if defined(DGUX)
+ if ((fd = open(DEV_MEM, O_RDWR)) < 0)
+ {
+ FatalError("xf86MapVidMem: failed to open %s (%s)\n",
+ DEV_MEM, strerror(errno));
+ }
+ base = mmap((caddr_t)0, Size, PROT_READ|PROT_WRITE,
+ MAP_SHARED, fd, (off_t)Base);
+ close(fd);
+ if (base == MAP_FAILED)
+ {
+ FatalError("%s: Could not mmap framebuffer [s=%x,a=%x] (%s)\n",
+ "xf86MapVidMem", Size, Base, strerror(errno));
+ }
+#else /* HAS SVR#_MMAPDRV */
+#ifdef HAS_SVR3_MMAPDRV
+ if (mmapFd == -2)
+ {
+ mmapFd = open("/dev/mmap", O_RDWR);
+ }
+#endif
+ if (mmapFd >= 0)
+ {
+ /* To force the MMAP driver to provide the address */
+ base = (pointer)0;
+ }
+ else
+ {
+ AllocAddress[ScreenNum][Region] = xalloc(Size + 0x1000);
+ if (AllocAddress[ScreenNum][Region] == (pointer)0)
+ {
+ FatalError("xf86MapVidMem: can't alloc framebuffer space\n");
+ /* NOTREACHED */
+ }
+ base = (pointer)(((unsigned int)AllocAddress[ScreenNum][Region]
+ & ~0xFFF) + 0x1000);
+ }
+
+
+#ifdef HAS_SVR3_MMAPDRV
+ if(mmapFd >= 0)
+ {
+ if((base = (pointer)ioctl(mmapFd, MAP,
+ &(MapDSC[ScreenNum][Region]))) == MAP_FAILED)
+ {
+ FatalError("%s: Could not mmap framebuffer [s=%x,a=%x] (%s)\n",
+ "xf86MapVidMem", Size, Base, strerror(errno));
+ /* NOTREACHED */
+ }
+
+#if 0
+/* inserted for DGA support */
+ xf86memMaps[ScreenNum].offset = Base;
+ xf86memMaps[ScreenNum].memSize = Size;
+#endif
+ return((pointer)base);
+ }
+#endif
+#endif /* DGUX */
+#if 0
+ xf86memMaps[ScreenNum].offset = Base;
+ xf86memMaps[ScreenNum].memSize = Size;
+#endif
+ return(base);
+}
+
+
+
+
+
+
+#if 0
+void xf86GetVidMemData(ScreenNum, Base, Size)
+int ScreenNum;
+int *Base;
+int *Size;
+{
+ *Base = xf86memMaps[ScreenNum].offset;
+ *Size = xf86memMaps[ScreenNum].memSize;
+}
+#endif
+
+
+
+
+void xf86UnMapVidMem(ScreenNum, Region, Base, Size)
+int ScreenNum;
+int Region;
+pointer Base;
+unsigned long Size;
+{
+ munmap(Base, Size);
+}
+
+
+
+
+
+/* NULL for DG/ux */
+void xf86MapDisplay(ScreenNum, Region)
+int ScreenNum;
+int Region;
+{
+ return;
+}
+
+
+
+
+/* NULL for DG/ux */
+void xf86UnMapDisplay(ScreenNum, Region)
+int ScreenNum;
+int Region;
+{
+ return;
+}
+
+/***************************************************************************/
+/* I/O Permissions section */
+/***************************************************************************/
+
+#define ALWAYS_USE_EXTENDED
+#ifdef ALWAYS_USE_EXTENDED
+
+static Bool ScreenEnabled[MAXSCREENS];
+static Bool ExtendedEnabled = FALSE;
+static Bool InitDone = FALSE;
+
+void
+xf86ClearIOPortList(ScreenNum)
+int ScreenNum;
+{
+ if (!InitDone)
+ {
+ int i;
+ for (i = 0; i < MAXSCREENS; i++)
+ ScreenEnabled[i] = FALSE;
+ InitDone = TRUE;
+ }
+ return;
+}
+
+void
+xf86AddIOPorts(ScreenNum, NumPorts, Ports)
+int ScreenNum;
+int NumPorts;
+unsigned *Ports;
+{
+ return;
+}
+
+void
+xf86EnableIOPorts(ScreenNum)
+int ScreenNum;
+{
+ int i;
+
+ ScreenEnabled[ScreenNum] = TRUE;
+
+ if (ExtendedEnabled)
+ return;
+
+ if (SET_IOPL() < 0)
+ {
+ FatalError("%s: Failed to set IOPL for extended I/O\n",
+ "xf86EnableIOPorts");
+ }
+ ExtendedEnabled = TRUE;
+
+ return;
+}
+
+void
+xf86DisableIOPorts(ScreenNum)
+int ScreenNum;
+{
+ int i;
+
+ ScreenEnabled[ScreenNum] = FALSE;
+
+ if (!ExtendedEnabled)
+ return;
+
+ for (i = 0; i < MAXSCREENS; i++)
+ if (ScreenEnabled[i])
+ return;
+
+ RESET_IOPL();
+ ExtendedEnabled = FALSE;
+
+ return;
+}
+
+#else /* !ALWAYS_USE_EXTENDED */
+
+#define DISABLED 0
+#define NON_EXTENDED 1
+#define EXTENDED 2
+
+static unsigned *EnabledPorts[MAXSCREENS];
+static int NumEnabledPorts[MAXSCREENS];
+static Bool ScreenEnabled[MAXSCREENS];
+static Bool ExtendedPorts[MAXSCREENS];
+static Bool ExtendedEnabled = FALSE;
+static Bool InitDone = FALSE;
+static struct kd_disparam OrigParams;
+
+void xf86ClearIOPortList(ScreenNum)
+int ScreenNum;
+{
+ if (!InitDone)
+ {
+ xf86InitPortLists(EnabledPorts, NumEnabledPorts, ScreenEnabled,
+ ExtendedPorts, MAXSCREENS);
+ if (ioctl(xf86Info.consoleFd, KDDISPTYPE, &OrigParams) < 0)
+ {
+ FatalError("%s: Could not get display parameters\n",
+ "xf86ClearIOPortList");
+ }
+ InitDone = TRUE;
+ return;
+ }
+ ExtendedPorts[ScreenNum] = FALSE;
+ if (EnabledPorts[ScreenNum] != (unsigned *)NULL)
+ xfree(EnabledPorts[ScreenNum]);
+ EnabledPorts[ScreenNum] = (unsigned *)NULL;
+ NumEnabledPorts[ScreenNum] = 0;
+}
+
+void xf86AddIOPorts(ScreenNum, NumPorts, Ports)
+int ScreenNum;
+int NumPorts;
+unsigned *Ports;
+{
+ int i;
+
+ if (!InitDone)
+ {
+ FatalError("xf86AddIOPorts: I/O control lists not initialised\n");
+ }
+ EnabledPorts[ScreenNum] = xrealloc(EnabledPorts[ScreenNum],
+ (NumEnabledPorts[ScreenNum]+NumPorts)*sizeof(unsigned));
+ for (i = 0; i < NumPorts; i++)
+ {
+ EnabledPorts[ScreenNum][NumEnabledPorts[ScreenNum] + i] =
+ Ports[i];
+ if (Ports[i] > 0x3FF)
+ ExtendedPorts[ScreenNum] = TRUE;
+ }
+ NumEnabledPorts[ScreenNum] += NumPorts;
+}
+
+void xf86EnableIOPorts(ScreenNum)
+int ScreenNum;
+{
+ struct kd_disparam param;
+ int i, j;
+
+ if (ScreenEnabled[ScreenNum])
+ return;
+
+ for (i = 0; i < MAXSCREENS; i++)
+ {
+ if (ExtendedPorts[i] && (ScreenEnabled[i] || i == ScreenNum))
+ {
+ if (SET_IOPL() < 0)
+ {
+ FatalError("%s: Failed to set IOPL for extended I/O\n",
+ "xf86EnableIOPorts");
+ }
+ ExtendedEnabled = TRUE;
+ break;
+ }
+ }
+ if (ExtendedEnabled && i == MAXSCREENS)
+ {
+ RESET_IOPL();
+ ExtendedEnabled = FALSE;
+ }
+ if (ioctl(xf86Info.consoleFd, KDDISPTYPE, &param) < 0)
+ {
+ FatalError("%s: Could not get display parameters\n",
+ "xf86EnableIOPorts");
+ }
+ for (i = 0; i < NumEnabledPorts[ScreenNum]; i++)
+ {
+ unsigned port = EnabledPorts[ScreenNum][i];
+
+ if (port > 0x3FF)
+ continue;
+
+ if (!xf86CheckPorts(port, EnabledPorts, NumEnabledPorts,
+ ScreenEnabled, MAXSCREENS))
+ {
+ continue;
+ }
+ for (j=0; j < MKDIOADDR; j++)
+ {
+ if (param.ioaddr[j] == port)
+ {
+ break;
+ }
+ }
+ if (j == MKDIOADDR)
+ {
+ if (ioctl(xf86Info.consoleFd, KDADDIO, port) < 0)
+ {
+ FatalError("%s: Failed to enable port 0x%x\n",
+ "xf86EnableIOPorts", port);
+ }
+ }
+ }
+ if (ioctl(xf86Info.consoleFd, KDENABIO, 0) < 0)
+ {
+ FatalError("xf86EnableIOPorts: I/O port enable failed (%s)\n",
+ strerror(errno));
+ }
+ ScreenEnabled[ScreenNum] = TRUE;
+ return;
+}
+
+void xf86DisableIOPorts(ScreenNum)
+int ScreenNum;
+{
+ struct kd_disparam param;
+ int i, j;
+
+ if (!ScreenEnabled[ScreenNum])
+ return;
+
+ ScreenEnabled[ScreenNum] = FALSE;
+ for (i = 0; i < MAXSCREENS; i++)
+ {
+ if (ScreenEnabled[i] && ExtendedPorts[i])
+ break;
+ }
+ if (ExtendedEnabled && i == MAXSCREENS)
+ {
+ RESET_IOPL();
+ ExtendedEnabled = FALSE;
+ }
+ /* Turn off I/O before changing the access list */
+ ioctl(xf86Info.consoleFd, KDDISABIO, 0);
+ if (ioctl(xf86Info.consoleFd, KDDISPTYPE, &param) < 0)
+ {
+ ErrorF("%s: Could not get display parameters\n",
+ "xf86DisableIOPorts");
+ return;
+ }
+
+ for (i=0; i < MKDIOADDR; i++)
+ {
+ if (param.ioaddr[i] == 0)
+ {
+ break;
+ }
+ if (!xf86CheckPorts(param.ioaddr[i], EnabledPorts,
+ NumEnabledPorts, ScreenEnabled, MAXSCREENS))
+ {
+ continue;
+ }
+ for (j=0; j < MKDIOADDR; j++)
+ {
+ if (param.ioaddr[i] == OrigParams.ioaddr[j])
+ {
+ /*
+ * Port was one of the original ones; don't
+ * touch it.
+ */
+ break;
+ }
+ }
+ if (j == MKDIOADDR)
+ {
+ /*
+ * We added this port, so remove it.
+ */
+ ioctl(xf86Info.consoleFd, KDDELIO, param.ioaddr[i]);
+ }
+ }
+ for (i = 0; i < MAXSCREENS; i++)
+ {
+ if (ScreenEnabled[i])
+ {
+ ioctl(xf86Info.consoleFd, KDENABIO, 0);
+ break;
+ }
+ }
+ return;
+}
+#endif
+
+void xf86DisableIOPrivs()
+{
+ if (ExtendedEnabled)
+ RESET_IOPL();
+ return;
+}
+
+/***************************************************************************/
+/* Interrupt Handling section */
+/***************************************************************************/
+
+
+Bool xf86DisableInterrupts()
+{
+
+#ifdef __GNUC__
+ __asm__ __volatile__("cli");
+#else
+ asm("cli");
+#endif /* __GNUC__ */
+
+ return(TRUE);
+}
+
+void xf86EnableInterrupts()
+{
+
+#ifdef __GNUC__
+ __asm__ __volatile__("sti");
+#else
+ asm("sti");
+#endif /* __GNUC__ */
+
+ return;
+}
+
+
+void
+xf86MapReadSideEffects(int ScreenNum, int Flags, pointer Base,
+ unsigned long Size)
+{
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/hurd/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/hurd/Imakefile
new file mode 100644
index 000000000..27d8575dd
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/hurd/Imakefile
@@ -0,0 +1,46 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/hurd/Imakefile,v 1.5 1999/05/22 08:40:11 dawes Exp $
+
+#include <Server.tmpl>
+
+BIOS_MOD = bios_mmap
+
+#if NewInput
+MOUSESRC = hurd_mouse.c
+MOUSEOBJ = hurd_mouse.o
+#else
+MOUSESRC = std_mouse.c std_mseEv.c
+MOUSEOBJ = std_mouse.o std_mseEv.o
+#endif
+
+SRCS = hurd_init.c hurd_video.c hurd_io.c libc_wrapper.c $(BIOS_MOD).c \
+ mapVT_noop.c VTsw_noop.c posix_tty.c std_kbdEv.c $(MOUSESRC) \
+ stdResource.c
+
+OBJS = hurd_init.o hurd_video.o hurd_io.o libc_wrapper.o $(BIOS_MOD).o \
+ mapVT_noop.o VTsw_noop.o posix_tty.o std_kbdEv.o $(MOUSEOBJ) \
+ stdResource.o
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC) -I$(EXTINCSRC) -I$(SERVERSRC)/mi
+
+RESDEFINES = -DUSESTDRES
+
+DEFINES = $(RESDEFINES)
+
+SubdirLibraryRule($(OBJS))
+NormalLibraryObjectRule()
+
+
+LinkSourceFile(VTsw_noop.c,../shared)
+LinkSourceFile(mapVT_noop.c,../shared)
+LinkSourceFile(posix_tty.c,../shared)
+#if !NewInput
+LinkSourceFile(std_mouse.c,../shared)
+LinkSourceFile(std_mseEv.c,../shared)
+#endif
+LinkSourceFile(std_kbdEv.c,../shared)
+LinkSourceFile(libc_wrapper.c,../shared)
+LinkSourceFile(stdResource.c,../shared)
+
+DependTarget()
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/hurd/bios_mmap.c b/xc/programs/Xserver/hw/xfree86/os-support/hurd/bios_mmap.c
new file mode 100644
index 000000000..8029754aa
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/hurd/bios_mmap.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright 1997 by UCHIYAMA Yasushi
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of UCHIYAMA Yasushi not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. UCHIYAMA Yasushi makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * UCHIYAMA YASUSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL UCHIYAMA YASUSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/hurd/bios_mmap.c,v 1.1 1998/08/16 10:25:47 dawes Exp $ */
+#include<mach.h>
+#include<device/device.h>
+
+#include "X.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#define BIOS_SIZE 0x20000
+
+int
+xf86ReadBIOS(unsigned long Base,unsigned long Offset,unsigned char *Buf,int Len)
+{
+ mach_port_t device,iopl_dev;
+ memory_object_t iopl_mem;
+ vm_address_t addr = (vm_address_t)0; /* serach starting address */
+ kern_return_t err;
+
+
+ err = get_privileged_ports (NULL, &device);
+ if( err )
+ {
+ errno = err;
+ FatalError("xf86ReadBIOS() can't get_privileged_ports. (%s)\n",strerror(errno));
+ }
+ err = device_open(device,D_READ|D_WRITE,"iopl",&iopl_dev);
+ mach_port_deallocate (mach_task_self (), device);
+ if( err )
+ {
+ errno = err;
+ FatalError("xf86ReadBIOS() can't device_open. (%s)\n",strerror(errno));
+ }
+ err = device_map(iopl_dev,VM_PROT_READ|VM_PROT_WRITE, Base , BIOS_SIZE ,&iopl_mem,0);
+ if( err )
+ {
+ errno = err;
+ FatalError("xf86ReadBIOS() can't device_map. (%s)\n",strerror(errno));
+ }
+ err = vm_map(mach_task_self(),
+ &addr,
+ BIOS_SIZE,
+ 0,
+ TRUE,
+ iopl_mem,
+ Base,
+ FALSE,
+ VM_PROT_READ|VM_PROT_WRITE,
+ VM_PROT_READ|VM_PROT_WRITE,
+ VM_INHERIT_SHARE);
+ mach_port_deallocate(mach_task_self(),iopl_mem);
+ if( err )
+ {
+ errno = err;
+ FatalError("xf86ReadBIOS() can't vm_map. (%s)\n",strerror(errno));
+ }
+
+ memcpy(Buf,(void*)((int)addr + Offset), Len);
+
+ err = vm_deallocate(mach_task_self(), addr, BIOS_SIZE);
+ if( err )
+ {
+ errno = err;
+ FatalError("xf86ReadBIOS() can't vm_deallocate. (%s)\n",strerror(errno));
+ }
+
+ return Len;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_init.c b/xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_init.c
new file mode 100644
index 000000000..38e58cdf5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_init.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright 1997,1998 by UCHIYAMA Yasushi
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of UCHIYAMA Yasushi not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. UCHIYAMA Yasushi makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * UCHIYAMA YASUSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL UCHIYAMA YASUSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_init.c,v 1.2 1999/03/07 14:05:09 dawes Exp $ */
+
+#include "X.h"
+
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <assert.h>
+#include <mach.h>
+
+int
+xf86ProcessArgument( int argc,char **argv, int i )
+{
+ return 0;
+}
+void
+xf86UseMsg()
+{
+ return;
+}
+
+
+void
+xf86OpenConsole()
+{
+ if( serverGeneration == 1 )
+ {
+ kern_return_t err;
+ mach_port_t device;
+ int fd;
+ err = get_privileged_ports( NULL, &device );
+ if( err )
+ {
+ errno = err;
+ FatalError( "xf86KbdInit can't get_privileged_ports. (%s)\n" , strerror(errno) );
+ }
+ mach_port_deallocate (mach_task_self (), device);
+
+ if( ( fd = open( "/dev/kbd" , O_RDONLY|O_NONBLOCK ) ) < 0 )
+ {
+ fprintf( stderr , "Cannot open keyboard (%s)\n",strerror(errno) );
+ exit(1);
+ }
+ xf86Info.consoleFd = fd;
+ }
+ return;
+}
+
+void
+xf86CloseConsole()
+{
+ close( xf86Info.consoleFd );
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_io.c b/xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_io.c
new file mode 100644
index 000000000..94ea862bc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_io.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright 1997,1998 by UCHIYAMA Yasushi
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of UCHIYAMA Yasushi not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. UCHIYAMA Yasushi makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * UCHIYAMA YASUSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL UCHIYAMA YASUSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_io.c,v 1.5 1999/05/22 08:40:11 dawes Exp $ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "mipointer.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <assert.h>
+#include <mach.h>
+#include <sys/ioctl.h>
+
+typedef unsigned short kev_type; /* kd event type */
+typedef unsigned char Scancode;
+
+struct mouse_motion {
+ short mm_deltaX; /* units? */
+ short mm_deltaY;
+};
+
+typedef struct {
+ kev_type type; /* see below */
+ struct timeval time; /* timestamp */
+ union { /* value associated with event */
+ boolean_t up; /* MOUSE_LEFT .. MOUSE_RIGHT */
+ Scancode sc; /* KEYBD_EVENT */
+ struct mouse_motion mmotion; /* MOUSE_MOTION */
+ } value;
+} kd_event;
+
+/*
+ * kd_event ID's.
+ */
+#define MOUSE_LEFT 1 /* mouse left button up/down */
+#define MOUSE_MIDDLE 2
+#define MOUSE_RIGHT 3
+#define MOUSE_MOTION 4 /* mouse motion */
+#define KEYBD_EVENT 5 /* key up/down */
+
+#ifndef NEW_INPUT
+/*
+ * xf86OsMouseProc --
+ * Handle the initialization, etc. of a mouse
+ */
+int
+xf86OsMouseProc( DeviceIntPtr pPointer , int what )
+{
+ unsigned char map[MSE_MAXBUTTONS + 1];
+ int nbuttons;
+ int mousefd;
+
+ switch( what )
+ {
+ case DEVICE_INIT:
+ pPointer->public.on = FALSE;
+
+ for (nbuttons = 0; nbuttons < MSE_MAXBUTTONS; ++nbuttons)
+ map[nbuttons + 1] = nbuttons + 1;
+
+ InitPointerDeviceStruct((DevicePtr)pPointer,
+ map,
+ min(xf86Info.mouseDev->buttons, MSE_MAXBUTTONS),
+ miPointerGetMotionEvents,
+ (PtrCtrlProcPtr)xf86MseCtrl,
+ 0);
+#ifdef XINPUT
+ InitValuatorAxisStruct(pPointer,
+ 0,
+ 0, /* min val */
+ screenInfo.screens[0]->width, /* max val */
+ 1, /* resolution */
+ 0, /* min_res */
+ 1); /* max_res */
+ InitValuatorAxisStruct(pPointer,
+ 1,
+ 0, /* min val */
+ screenInfo.screens[0]->height, /* max val */
+ 1, /* resolution */
+ 0, /* min_res */
+ 1); /* max_res */
+ /* Initialize valuator values in synch
+ * with dix/event.c DefineInitialRootWindow
+ */
+ *pPointer->valuator->axisVal = screenInfo.screens[0]->width / 2;
+ *(pPointer->valuator->axisVal+1) = screenInfo.screens[0]->height / 2;
+#endif
+ break;
+ case DEVICE_ON:
+ if ( (xf86Info.mouseDev->mseFd = open(xf86Info.mouseDev->mseDevice,O_RDONLY|O_NONBLOCK) ) == -1 )
+ return !Success;
+ AddEnabledDevice( xf86Info.mouseDev->mseFd );
+ xf86Info.mouseDev->lastButtons = 0;
+ xf86Info.mouseDev->emulateState = 0;
+ pPointer->public.on = TRUE;
+ break;
+ case DEVICE_OFF:
+ case DEVICE_CLOSE:
+ if( close( xf86Info.mouseDev->mseFd ) != -1 )
+ RemoveEnabledDevice(mousefd);
+ pPointer->public.on = FALSE;
+ usleep(300000);
+ break;
+ }
+ return Success;
+}
+/*
+ * xf86OsMouseEvents --
+ * Get some events from our queue. Process all outstanding events now.
+ */
+void
+xf86OsMouseEvents()
+{
+ static kd_event eventList[64];
+ int n;
+ kd_event *event = eventList;
+
+ if( (n = read( xf86Info.mouseDev->mseFd , eventList, sizeof eventList )) <= 0 )
+ return;
+ n /= sizeof( kd_event );
+ while( n-- )
+ {
+ int buttons = xf86Info.mouseDev->lastButtons;
+ int dx =0, dy = 0;
+ switch( event->type )
+ {
+ case MOUSE_RIGHT:
+ buttons = buttons & 6 |(event->value.up ? 0 : 1);
+ break;
+ case MOUSE_MIDDLE:
+ buttons = buttons & 5 |(event->value.up ? 0 : 2);
+ break;
+ case MOUSE_LEFT:
+ buttons = buttons & 3 |(event->value.up ? 0 : 4) ;
+ break;
+ case MOUSE_MOTION:
+ dx = event->value.mmotion.mm_deltaX;
+ dy = - event->value.mmotion.mm_deltaY;
+ break;
+ default:
+ ErrorF("Bad mouse event (%d)\n",event->type);
+ continue;
+ }
+ xf86PostMseEvent(xf86Info.pMouse,buttons, dx, dy );
+ ++event;
+ }
+ return;
+}
+
+void
+xf86MouseInit( MouseDevPtr mouse )
+{
+}
+int
+xf86MouseOn( MouseDevPtr mouse)
+{
+ if ((mouse->mseFd = open(mouse->mseDevice, O_RDWR | O_NONBLOCK)) < 0)
+ {
+ if (xf86AllowMouseOpenFail) {
+ ErrorF("Cannot open mouse (%s) - Continuing...\n",
+ strerror(errno));
+ return(-2);
+ }
+ FatalError("Cannot open mouse (%s)\n", strerror(errno));
+ }
+
+ xf86SetupMouse(mouse);
+
+ /* Flush any pending input */
+ tcflush(mouse->mseFd, TCIFLUSH);
+
+ return mouse->mseFd;
+}
+#endif
+
+/***********************************************************************
+ * Keyboard
+ **********************************************************************/
+void
+xf86SoundKbdBell(int loudness,int pitch,int duration)
+{
+ return;
+}
+
+void
+xf86SetKbdLeds(int leds)
+{
+ return;
+}
+
+int
+xf86GetKbdLeds()
+{
+ return 0;
+}
+
+void
+xf86SetKbdRepeat(char rad)
+{
+ return;
+}
+
+void
+xf86KbdInit()
+{
+ return;
+}
+int
+xf86KbdOn()
+{
+ int data = 1;
+ if( ioctl( xf86Info.consoleFd, _IOW('k', 1, int),&data) < 0)
+ FatalError("Cannot set event mode on keyboard (%s)\n",strerror(errno));
+ return xf86Info.consoleFd;
+}
+int
+xf86KbdOff()
+{
+ int data = 2;
+ if( ioctl( xf86Info.consoleFd, _IOW('k', 1, int),&data) < 0)
+ FatalError("can't reset keyboard mode (%s)\n",strerror(errno));
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_mouse.c b/xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_mouse.c
new file mode 100644
index 000000000..af915a318
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_mouse.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright 1997,1998 by UCHIYAMA Yasushi
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of UCHIYAMA Yasushi not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. UCHIYAMA Yasushi makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * UCHIYAMA YASUSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL UCHIYAMA YASUSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_mouse.c,v 1.6 1999/05/29 14:41:51 dawes Exp $ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "mipointer.h"
+
+#include "xf86.h"
+#include "xf86Xinput.h"
+#include "xf86OSmouse.h"
+#include "xf86_OSlib.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <assert.h>
+#include <mach.h>
+#include <sys/ioctl.h>
+
+typedef unsigned short kev_type; /* kd event type */
+typedef unsigned char Scancode;
+
+struct mouse_motion {
+ short mm_deltaX; /* units? */
+ short mm_deltaY;
+};
+
+typedef struct {
+ kev_type type; /* see below */
+ struct timeval time; /* timestamp */
+ union { /* value associated with event */
+ boolean_t up; /* MOUSE_LEFT .. MOUSE_RIGHT */
+ Scancode sc; /* KEYBD_EVENT */
+ struct mouse_motion mmotion; /* MOUSE_MOTION */
+ } value;
+} kd_event;
+
+/*
+ * kd_event ID's.
+ */
+#define MOUSE_LEFT 1 /* mouse left button up/down */
+#define MOUSE_MIDDLE 2
+#define MOUSE_RIGHT 3
+#define MOUSE_MOTION 4 /* mouse motion */
+#define KEYBD_EVENT 5 /* key up/down */
+
+#define NUMEVENTS 64
+
+/*
+ * OsMouseProc --
+ * Handle the initialization, etc. of a mouse
+ */
+static int
+OsMouseProc(DeviceIntPtr pPointer, int what)
+{
+ InputInfoPtr pInfo;
+ MouseDevPtr pMse;
+ unsigned char map[MSE_MAXBUTTONS + 1];
+ int nbuttons;
+
+ pInfo = pPointer->public.devicePrivate;
+ pMse = pInfo->private;
+ pMse->device = pPointer;
+
+ switch (what) {
+ case DEVICE_INIT:
+ pPointer->public.on = FALSE;
+
+ for (nbuttons = 0; nbuttons < MSE_MAXBUTTONS; ++nbuttons)
+ map[nbuttons + 1] = nbuttons + 1;
+
+ InitPointerDeviceStruct((DevicePtr)pPointer,
+ map,
+ min(pMse->buttons, MSE_MAXBUTTONS),
+ miPointerGetMotionEvents,
+ pMse->Ctrl,
+ miPointerGetMotionBufferSize());
+
+ /* X valuator */
+ xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1);
+ xf86InitValuatorDefaults(pPointer, 0);
+ /* Y valuator */
+ xf86InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1);
+ xf86InitValuatorDefaults(pPointer, 1);
+ xf86MotionHistoryAllocate(pInfo);
+ break;
+
+ case DEVICE_ON:
+ pInfo->fd = xf86OpenSerial(pInfo->options);
+ if (pInfo->fd == -1)
+ xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
+ else {
+ pMse->buffer = XisbNew(pInfo->fd,
+ NUMEVENTS * sizeof(kd_event));
+ if (!pMse->buffer) {
+ xfree(pMse);
+ xf86CloseSerial(pInfo->fd);
+ pInfo->fd = -1;
+ } else {
+ xf86FlushInput(pInfo->fd);
+ AddEnabledDevice(pInfo->fd);
+ }
+ }
+ pMse->lastButtons = 0;
+ pMse->emulateState = 0;
+ pPointer->public.on = TRUE;
+ break;
+
+ case DEVICE_OFF:
+ case DEVICE_CLOSE:
+ if (pInfo->fd != -1) {
+ RemoveEnabledDevice(pInfo->fd);
+ if (pMse->buffer) {
+ XisbFree(pMse->buffer);
+ pMse->buffer = NULL;
+ }
+ xf86CloseSerial(pInfo->fd);
+ pInfo->fd = -1;
+ }
+ pPointer->public.on = FALSE;
+ usleep(300000);
+ break;
+ }
+ return Success;
+}
+
+/*
+ * OsMouseReadInput --
+ * Get some events from our queue. Process all outstanding events now.
+ */
+static void
+OsMouseReadInput(InputInfoPtr pInfo)
+{
+ MouseDevPtr pMse;
+ static kd_event eventList[NUMEVENTS];
+ int n, c;
+ kd_event *event = eventList;
+ unsigned char *pBuf;
+
+ pMse = pInfo->private;
+
+ XisbBlockDuration(pMse->buffer, -1);
+ pBuf = (unsigned char *)eventList;
+ n = 0;
+ while ((c = XisbRead(pMse->buffer)) >= 0 && n < sizeof(eventList))
+ pBuf[n] = (unsigned char)c;
+
+ if (n == 0)
+ return;
+
+ n /= sizeof(kd_event);
+ while( n-- ) {
+ int buttons = pMse->lastButtons;
+ int dx = 0, dy = 0;
+ switch (event->type) {
+ case MOUSE_RIGHT:
+ buttons = buttons & 6 |(event->value.up ? 0 : 1);
+ break;
+ case MOUSE_MIDDLE:
+ buttons = buttons & 5 |(event->value.up ? 0 : 2);
+ break;
+ case MOUSE_LEFT:
+ buttons = buttons & 3 |(event->value.up ? 0 : 4) ;
+ break;
+ case MOUSE_MOTION:
+ dx = event->value.mmotion.mm_deltaX;
+ dy = - event->value.mmotion.mm_deltaY;
+ break;
+ default:
+ ErrorF("Bad mouse event (%d)\n",event->type);
+ continue;
+ }
+ pMse->PostEvent(pInfo, buttons, dx, dy, 0);
+ ++event;
+ }
+ return;
+}
+
+static Bool
+OsMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags)
+{
+ MouseDevPtr pMse;
+
+ /* This is called when the protocol is "OSMouse". */
+
+ pMse = pInfo->private;
+ pMse->protocol = protocol;
+ xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol);
+
+ /* Collect the options, and process the common options. */
+ xf86CollectInputOptions(pInfo, NULL, NULL);
+ xf86ProcessCommonOptions(pInfo, pInfo->options);
+
+ /* Check if the device can be opened. */
+ pInfo->fd = xf86OpenSerial(pInfo->options);
+ if (pInfo->fd == -1) {
+ if (xf86GetAllowMouseOpenFail())
+ xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name);
+ else {
+ xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name);
+ xfree(pMse);
+ return FALSE;
+ }
+ }
+ xf86CloseSerial(pInfo->fd);
+ pInfo->fd = -1;
+
+ /* Process common mouse options (like Emulate3Buttons, etc). */
+ pMse->CommonOptions(pInfo);
+
+ /* Setup the local procs. */
+ pInfo->device_control = OsMouseProc;
+ pInfo->read_input = OsMouseReadInput;
+
+ pInfo->flags |= XI86_CONFIGURED;
+ return TRUE;
+}
+
+static int
+SupportedInterfaces(void)
+{
+ /* XXX Need to check this. */
+ return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO;
+}
+
+static const char *internalNames[] = {
+ "OSMouse",
+ NULL
+};
+
+static const char **
+BuiltinNames(void)
+{
+ return internalNames;
+}
+
+static Bool
+CheckProtocol(const char *protocol)
+{
+ int i;
+
+ for (i = 0; internalNames[i]; i++)
+ if (xf86NameCmp(protocol, internalNames[i]) == 0)
+ return TRUE;
+ return FALSE;
+}
+
+/* XXX Is this appropriate? If not, this function should be removed. */
+static const char *
+DefaultProtocol(void)
+{
+ return "OSMouse";
+}
+
+OSMouseInfoPtr
+xf86OSMouseInit(int flags)
+{
+ OSMouseInfoPtr p;
+
+ p = xcalloc(sizeof(OSMouseInfoRec), 1);
+ if (!p)
+ return NULL;
+ p->SupportedInterfaces = SupportedInterfaces;
+ p->BuiltinNames = BuiltinNames;
+ p->DefaultProtocol = DefaultProtocol;
+ p->CheckProtocol = CheckProtocol;
+ p->PreInit = OSMousePreInit;
+ return p;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_video.c b/xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_video.c
new file mode 100644
index 000000000..63f77da24
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_video.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright 1997, 1998 by UCHIYAMA Yasushi
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of UCHIYAMA Yasushi not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. UCHIYAMA Yasushi makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * UCHIYAMA YASUSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL UCHIYAMA YASUSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/hurd/hurd_video.c,v 1.3 1999/04/29 12:24:52 dawes Exp $ */
+
+#include <mach.h>
+#include <device/device.h>
+
+#include "X.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+/**************************************************************************
+ * Video Memory Mapping section
+ ***************************************************************************/
+pointer
+xf86MapVidMem(int ScreenNum,int Flags, unsigned long Base, unsigned long Size)
+{
+ mach_port_t device,iopl_dev;
+ memory_object_t iopl_mem;
+ kern_return_t err;
+ vm_address_t addr=(vm_address_t)0;
+
+ err = get_privileged_ports (NULL, &device);
+ if( err )
+ {
+ errno = err;
+ FatalError("xf86MapVidMem() can't get_privileged_ports. (%s)\n",strerror(errno));
+ }
+ err = device_open(device,D_READ|D_WRITE,"iopl",&iopl_dev);
+ mach_port_deallocate (mach_task_self(), device);
+ if( err )
+ {
+ errno = err;
+ FatalError("xf86MapVidMem() can't device_open. (%s)\n",strerror(errno));
+ }
+
+ err = device_map(iopl_dev,VM_PROT_READ|VM_PROT_WRITE, Base , Size ,&iopl_mem,0);
+ if( err )
+ {
+ errno = err;
+ FatalError("xf86MapVidMem() can't device_map. (%s)\n",strerror(errno));
+ }
+ err = vm_map(mach_task_self(),
+ &addr,
+ Size,
+ 0, /* mask */
+ TRUE, /* anywhere */
+ iopl_mem,
+ (vm_offset_t)Base,
+ FALSE, /* copy on write */
+ VM_PROT_READ|VM_PROT_WRITE,
+ VM_PROT_READ|VM_PROT_WRITE,
+ VM_INHERIT_SHARE);
+ mach_port_deallocate(mach_task_self(),iopl_mem);
+ if( err )
+ {
+ errno = err;
+ FatalError("xf86MapVidMem() can't vm_map.(iopl_mem) (%s)\n",strerror(errno));
+ }
+ mach_port_deallocate(mach_task_self(),iopl_dev);
+ if( err )
+ {
+ errno = err;
+ FatalError("xf86MapVidMem() can't mach_port_deallocate.(iopl_dev) (%s)\n",strerror(errno));
+ }
+ return (pointer)addr;
+}
+
+void
+xf86UnMapVidMem(int ScreenNum,pointer Base,unsigned long Size)
+{
+ kern_return_t err = vm_deallocate(mach_task_self(), (int)Base, Size);
+ if( err )
+ {
+ errno = err;
+ ErrorF("xf86UnMapVidMem: can't dealloc framebuffer space (%s)\n",strerror(errno));
+ }
+ return;
+}
+
+Bool
+xf86LinearVidMem()
+{
+ return(TRUE);
+}
+
+/**************************************************************************
+ * I/O Permissions section
+ ***************************************************************************/
+void
+xf86EnableIO()
+{
+ return;
+}
+
+void
+xf86DisableIO()
+{
+ return;
+}
+
+void
+xf86ClearIOPortList(int ScreenNum)
+{
+ return;
+}
+void
+xf86AddIOPorts(int ScreenNum,int NumPorts,unsigned int *Ports)
+{
+ return;
+}
+void
+xf86EnableIOPorts(int ScreenNum)
+{
+ return;
+}
+
+void
+xf86DisableIOPorts(int ScreenNum)
+{
+ return;
+}
+void
+xf86DisableIOPrivs()
+{
+ return;
+}
+/**************************************************************************
+ * Interrupt Handling section
+ **************************************************************************/
+Bool
+xf86DisableInterrupts()
+{
+ return TRUE;
+}
+void
+xf86EnableInterrupts()
+{
+ return;
+}
+
+void
+xf86MapReadSideEffects(int ScreenNum, int Flags, pointer Base,
+ unsigned long Size)
+{
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/linux/Imakefile
new file mode 100644
index 000000000..c5c378e2e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/Imakefile
@@ -0,0 +1,95 @@
+XCOMM $XConsortium: Imakefile /main/10 1996/10/19 18:06:19 kaleb $
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/Imakefile,v 3.23 1999/08/14 10:50:05 dawes Exp $
+XCOMM $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/Imakefile,v 1.9 1999/06/07 13:01:42 faith Exp $
+
+#include <Server.tmpl>
+
+#if BuildXInputExt
+# if JoystickSupport
+ JOYSTICK_SRC = lnx_jstk.c
+# endif
+# if DoLoadableServer
+SHARED_CFLAGS = PositionIndependentCFlags
+# else
+# if JoystickSupport
+ JOYSTICK_OBJ = lnx_jstk.o
+# endif
+# endif
+#endif
+
+#if HasMTRRSupport
+MTRRDEFINES = -DHAS_MTRR_SUPPORT
+#endif
+
+#if BuildXF86DRI
+DRI_SRC = sigio.c
+DRI_OBJ = sigio.o
+#endif
+
+#if NewInput
+MOUSESRC = lnx_mouse.c
+MOUSEOBJ = lnx_mouse.o
+#else
+MOUSESRC = std_mouse.c std_mseEv.c
+MOUSEOBJ = std_mouse.o std_mseEv.o
+#endif
+
+SRCS = lnx_init.c lnx_video.c lnx_io.c libc_wrapper.c bios_mmap.c \
+ mapVT_noop.c VTsw_usl.c std_kbdEv.c posix_tty.c $(MOUSESRC) \
+ stdResource.c vidmem.c $(JOYSTICK_SRC) $(DRI_SRC)
+
+OBJS = lnx_init.o lnx_video.o lnx_io.o libc_wrapper.o bios_mmap.o \
+ mapVT_noop.o VTsw_usl.o std_kbdEv.o posix_tty.o $(MOUSEOBJ) \
+ stdResource.o vidmem.o $(JOYSTICK_OBJ) $(DRI_OBJ)
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+RESDEFINES = -DUSESTDRES
+
+DEFINES = $(MTRRDEFINES) $(RESDEFINES)
+
+SubdirLibraryRule($(OBJS))
+NormalLibraryObjectRule()
+
+#if BuildXF86DRI
+#define IHaveSubdirs
+SUBDIRS = drm
+
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
+
+#if BuildXInputExt
+# if DoLoadableServer
+# if JoystickSupport
+AllTarget(lnx_jstk.o)
+#if 0
+InstallDynamicModule(lnx_jstk.o,$(MODULEDIR))
+#endif
+# endif
+# endif
+#endif
+
+LinkSourceFile(bios_mmap.c,../shared)
+LinkSourceFile(mapVT_noop.c,../shared)
+LinkSourceFile(VTsw_usl.c,../shared)
+LinkSourceFile(std_kbdEv.c,../shared)
+LinkSourceFile(posix_tty.c,../shared)
+#if !NewInput
+LinkSourceFile(std_mouse.c,../shared)
+LinkSourceFile(std_mseEv.c,../shared)
+#endif
+LinkSourceFile(libc_wrapper.c,../shared)
+LinkSourceFile(stdResource.c,../shared)
+LinkSourceFile(vidmem.c,../shared)
+
+#if BuildXF86DRI
+LinkSourceFile(sigio.c,../shared)
+#endif
+
+DependTarget()
+
+#if 0
+InstallDriverSDKDynamicModule(lnx_jstk.o,$(DRIVERSDKMODULEDIR))
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile
new file mode 100644
index 000000000..33968bffc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile
@@ -0,0 +1,43 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile,v 1.3 1999/08/14 10:50:06 dawes Exp $
+XCOMM $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile,v 1.5 1999/06/17 21:45:24 faith Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#if DoLoadableServer
+MSRC = drmmodule.c
+MOBJ = drmmodule.o
+#endif
+
+#if BuildXF86DRI
+#if HasMTRRSupport
+MTRR_DEFINES = -DHAS_MTRR_SUPPORT
+#endif
+
+SRCS = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c $(MSRC)
+OBJS = xf86drm.o xf86drmHash.o xf86drmRandom.o xf86drmSL.o $(MOBJ)
+
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC) -I$(EXTINCSRC) -I../.. -Igeneric
+
+DEFINES = $(MTRR_DEFINES) $(GLX_DEFINES)
+
+ModuleObjectRule()
+LibraryModuleTarget(drm,$(OBJS))
+NormalLintTarget($(SRCS))
+
+#ifdef LinuxArchitecture
+InstallLibraryModule(drm,$(MODULEDIR),linux)
+#endif
+
+#define IHaveSubdirs
+SUBDIRS = generic
+
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+#endif
+
+
+
+InstallDriverSDKLibraryModule(drm,$(DRIVERSDKMODULEDIR),linux)
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/drmmodule.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/drmmodule.c
new file mode 100644
index 000000000..1ddf3f4c1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/drmmodule.c
@@ -0,0 +1,56 @@
+/* drmmodule.c -- Module initialization
+ * Created: Fri Jun 4 09:05:48 1999 by faith@precisioninsight.com
+ * Revised: Fri Jun 4 09:09:22 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/drmmodule.c,v 1.1 1999/06/07 13:01:42 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/drmmodule.c,v 1.1 1999/06/14 07:32:01 dawes Exp $
+ *
+ */
+
+#include "xf86Module.h"
+
+static MODULESETUPPROTO(drmSetup);
+
+static XF86ModuleVersionInfo VersRec =
+{
+ "drm",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_EXTENSION,
+ ABI_EXTENSION_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0}
+};
+
+XF86ModuleData drmModuleData = { &VersRec, drmSetup, NULL };
+
+static pointer
+drmSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ return (void *)1;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/Imakefile
new file mode 100644
index 000000000..ef5adcf40
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/Imakefile
@@ -0,0 +1,28 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/Imakefile,v 1.2 1999/06/27 14:08:20 dawes Exp $
+XCOMM $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/Imakefile,v 1.7 1999/06/22 13:20:42 faith Exp $
+
+#include <Server.tmpl>
+
+LinkSourceFile(xf86drm.c,..)
+LinkSourceFile(xf86drmHash.c,..)
+LinkSourceFile(xf86drmRandom.c,..)
+LinkSourceFile(xf86drmSL.c,..)
+LinkSourceFile(xf86drm.h,$(XF86OSSRC))
+LinkSourceFile(xf86_OSproc.h,$(XF86OSSRC))
+LinkSourceFile(sigio.c,$(XF86OSSRC)/shared)
+
+XCOMM This is a kludge until we determine how best to build the
+XCOMM kernel-specific device driver. This allows us to continue
+XCOMM to maintain the single Makefile.linux with kernel-specific
+XCOMM support. Later, we can move to a different Imakefile.
+
+#if BuildXF86DRI && BuildXF86DRM
+all::
+ $(MAKE) -f Makefile.linux
+#else
+all::
+ echo 'Use "make -f Makefile.linux" to manually build drm.o'
+#endif
+
+clean::
+ $(MAKE) -f Makefile.linux clean
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/Makefile.kernel b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/Makefile.kernel
new file mode 100644
index 000000000..712ac9332
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/Makefile.kernel
@@ -0,0 +1,20 @@
+#
+# Makefile for the drm device driver. This driver provides support for
+# the Direct Rendering Infrastructure (DRI) in XFree86 4.x.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now inherited from the
+# parent makes..
+#
+
+O_TARGET := drm.o
+
+O_OBJS := drm_setup.o drm_ioctl.o drm_proc.o drm_mem.o \
+ gen_ioctl.o gen_dma.o gen_bufs.o
+
+M_OBJS := $(O_TARGET)
+
+include $(TOPDIR)/Rules.make
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/Makefile.linux b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/Makefile.linux
new file mode 100644
index 000000000..87bf9dc17
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/Makefile.linux
@@ -0,0 +1,163 @@
+# Makefile -- For the Direct Rendering Manager module (drm)
+# Created: Mon Jan 4 09:26:53 1999 by faith@precisioninsight.com
+# Revised: Wed Jun 16 08:51:57 1999 by faith@precisioninsight.com
+#
+# Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+# All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+#
+# $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/Makefile.linux,v 1.22 1999/06/16 12:53:14 faith Exp $
+# $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/Makefile.linux,v 1.3 1999/06/27 14:08:21 dawes Exp $
+#
+
+.SUFFIXES:
+
+# **** Start of SMP/MODVERSIONS detection
+
+# *** Setup
+LINUX=/usr/src/linux
+AUTOCONF=$(LINUX)/include/linux/autoconf.h
+
+# ** SMP
+SMP := $(shell \
+ if grep -q '^\#define.*CONFIG_SMP.*1' $(AUTOCONF); \
+ then echo 1; else echo 0; fi)
+# If that doesn't do automatic detection properly on your system,
+# uncomment one of these lines:
+#SMP := 0
+#SMP := 1
+
+# ** MODVERSIONS
+MODVERSIONS := $(shell \
+ if grep -q '^\#define.*CONFIG_MODVERSIONS.*1' $(AUTOCONF); \
+ then echo 1; else echo 0; fi)
+# If that doesn't do automatic detection properly on your system,
+# uncomment one of these lines:
+#MODVERSIONS := 0
+#MODVERSIONS := 1
+
+# **** End of SMP/MODVERSIONS detection
+
+MODS= drm.o
+PROGS= drmstat
+
+DRMOBJS= drm_setup.o drm_ioctl.o drm_proc.o drm_mem.o \
+ gen_ioctl.o gen_dma.o gen_bufs.o
+DRMHEADERS= drm.h drmP.h drm_version.h
+
+PROGOBJS= drmstat.po xf86drm.po xf86drmHash.po xf86drmRandom.po sigio.po
+PROGHEADERS= $(DRMHEADERS) xf86drm.h
+
+INC= /usr/include
+
+CFLAGS= -O2 $(WARNINGS)
+WARNINGS= -Wall -Wwrite-strings -Wpointer-arith -Wcast-align \
+ -Wstrict-prototypes -Wshadow -Wnested-externs \
+ -Winline -Wpointer-arith
+MODCFLAGS= $(CFLAGS) -D__KERNEL__ -DMODULE -fomit-frame-pointer
+PRGCFLAGS= $(CFLAGS) -g -ansi -pedantic -DPOSIX_C_SOURCE=199309L \
+ -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE \
+ -I../../../../../../include -I../../../../../../../../include \
+ -I../../../../../../../../programs/Xserver/hw/xfree86/common
+PRGLIBS=
+
+# **** Handle SMP/MODVERSIONS
+ifeq ($(SMP),1)
+MODCFLAGS += -D__SMP__
+endif
+ifeq ($(MODVERSIONS),1)
+MODCFLAGS += -DMODVERSIONS -include /usr/include/linux/modversions.h
+endif
+
+# **** End of configuration
+
+all: $(MODS) $(PROGS)
+
+drm.o: $(DRMOBJS)
+ $(LD) -r $^ -o $@
+
+drmstat: $(PROGOBJS)
+ $(CC) $(PRGCFLAGS) $^ $(PRGLIBS) -o $@
+
+drm_version.h version:
+ @(MAJOR=0; MINOR=0; PATCHLEVEL=0; \
+ if [ -f drm_version.h ]; then \
+ MAJOR=`awk '/MAJOR/ {print $$3}' < drm_version.h`; \
+ MINOR=`awk '/MINOR/ {print $$3}' < drm_version.h`; \
+ PATCHLEVEL=`awk '/PATCHLEVEL/ {print $$3}' < drm_version.h`; \
+ fi; \
+ PATCHLEVEL=`expr 0$$PATCHLEVEL + 1`; \
+ echo '#define DRM_DATE "'`date '+%Y%m%d'`\" > drm_version.h; \
+ echo "#define DRM_MAJOR $$MAJOR" >> drm_version.h; \
+ echo "#define DRM_MINOR $$MINOR" >> drm_version.h; \
+ echo "#define DRM_PATCHLEVEL $$PATCHLEVEL" >> drm_version.h)
+ @cat drm_version.h
+
+minor: drm_version.h
+ @(MAJOR=0; MINOR=0; PATCHLEVEL=0; \
+ MAJOR=`awk '/MAJOR/ {print $$3}' < drm_version.h`; \
+ MINOR=`awk '/MINOR/ {print $$3}' < drm_version.h`; \
+ MINOR=`expr 0$$MINOR + 1`; \
+ echo '#define DRM_DATE "'`date '+%Y%m%d'`\" > drm_version.h; \
+ echo "#define DRM_MAJOR $$MAJOR" >> drm_version.h; \
+ echo "#define DRM_MINOR $$MINOR" >> drm_version.h; \
+ echo "#define DRM_PATCHLEVEL $$PATCHLEVEL" >> drm_version.h)
+ @cat drm_version.h
+
+major: drm_version.h
+ @(MAJOR=0; MINOR=0; PATCHLEVEL=0; \
+ MAJOR=`awk '/MAJOR/ {print $$3}' < drm_version.h`; \
+ MAJOR=`expr 0$$MAJOR + 1`; \
+ echo '#define DRM_DATE "'`date '+%Y%m%d'`\" > drm_version.h; \
+ echo "#define DRM_MAJOR $$MAJOR" >> drm_version.h; \
+ echo "#define DRM_MINOR $$MINOR" >> drm_version.h; \
+ echo "#define DRM_PATCHLEVEL $$PATCHLEVEL" >> drm_version.h)
+ @cat drm_version.h
+
+.PHONY: ChangeLog
+ChangeLog:
+ @rm -f Changelog
+ @rcs2log -i 2 -r -l \
+ | sed 's,@.*alephnull.com,@precisioninsight.com,' > ChangeLog
+
+
+# .o files are used for modules
+%.o: %.c
+ $(CC) $(MODCFLAGS) -c $< -o $@
+
+# .po files are used for programs
+%.po: %.c
+ $(CC) $(PRGCFLAGS) -DDRM_USE_MALLOC -c $< -o $@
+
+xtest: xtest.c
+ $(CC) -Wall -O2 -L/usr/X11R6/lib -lX11 -o xtest xtest.c
+
+locktest: locktest.c xf86drm.po xf86drmHash.po xf86drmRandom.po sigio.po \
+ xf86drm.h
+ $(CC) $(PRGCFLAGS) xf86drm.po xf86drmHash.po xf86drmRandom.po \
+ sigio.po $< -o $@
+
+$(DRMOBJS): $(DRMHEADERS)
+$(PROGOBJS): $(PROGHEADERS)
+
+clean:
+ rm -f *.o *.po *~ core $(PROGS)
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/README.drm b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/README.drm
new file mode 100644
index 000000000..fc3c680e1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/README.drm
@@ -0,0 +1,39 @@
+
+The Direct Rendering Manager (drm) is a device-independent kernel-level
+device driver that provides support for the XFree86 Direct Rendering
+Infrastructure (DRI).
+
+The DRM supports the Direct Rendering Infrastructure (DRI) in four major
+ways:
+
+ 1. The DRM provides synchronized access to the graphics hardware via
+ the use of an optimized two-tiered lock.
+
+ 2. The DRM enforces the DRI security policy for access to the graphics
+ hardware by only allowing authenticated X11 clients access to
+ restricted regions of memory.
+
+ 3. The DRM provides a generic DMA engine, complete with multiple
+ queues and the ability to detect the need for an OpenGL context
+ switch.
+
+ 4. The DRM is extensible via the use of small device-specific modules
+ that rely extensively on the API exported by the DRM module.
+
+
+Documentation on the DRI is available from:
+ http://precisioninsight.com/piinsights.html
+
+For specific information about kernel-level support, see:
+
+ The Direct Rendering Manager, Kernel Support for the Direct Rendering
+ Infrastructure
+ http://precisioninsight.com/dr/drm.html
+
+ Hardware Locking for the Direct Rendering Infrastructure
+ http://precisioninsight.com/dr/locking.html
+
+ A Security Analysis of the Direct Rendering Infrastructure
+ http://precisioninsight.com/dr/security.html
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm.h
new file mode 100644
index 000000000..3a668b787
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm.h
@@ -0,0 +1,361 @@
+/* drm.h -- Header for Direct Rendering Manager -*- linux-c -*-
+ * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
+ * Revised: Fri Jun 18 09:47:37 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm.h,v 1.41 1999/06/21 14:31:21 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm.h,v 1.2 1999/06/27 14:08:21 dawes Exp $
+ *
+ */
+
+#ifndef _DRM_H_
+#define _DRM_H_
+
+#include <asm/ioctl.h> /* For _IO* macros */
+
+#define DRM_PROC_DEVICES "/proc/devices"
+#define DRM_PROC_MISC "/proc/misc"
+#define DRM_PROC_DRM "/proc/drm"
+#define DRM_DEV_DRM "/dev/drm"
+#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
+#define DRM_DEV_UID 0
+#define DRM_DEV_GID 0
+#define DRM_MISC_NAME "misc"
+
+
+#define DRM_NAME "drm" /* Name in kernel, /dev, and /proc */
+#define DRM_GEN_NAME "generic" /* Name of generic driver */
+#define DRM_DRIVERS "drivers" /* Name for /proc/drm/drivers */
+#define DRM_DEVICES "devices" /* Name for /proc/drm/devices */
+#define DRM_CLIENTS "clients" /* Name for /prov/drm/clients */
+#define DRM_MEM "mem" /* Name for /proc/drm/mem */
+#define DRM_MEMINFO "meminfo" /* Name for /proc/drm/<dev>/meminfo */
+#define DRM_VMAINFO "vmainfo" /* Name for /proc/drm/<dev>/vmainfo */
+#define DRM_HISTO "histo" /* Name for /proc/drm/<dev>/histo */
+#define DRM_QUEUES "queues" /* Name for /proc/drm/<dev>/queues */
+#define DRM_BUFS "bufs" /* Name for /proc/drm/<dev>/bufs */
+#define DRM_MAX_NAMELEN 128 /* Maximum length for driver names */
+#define DRM_MAX_DEVICES 6 /* Support n-2 graphics card drivers */
+#define DRM_DEV_MAJOR 0 /* Default device major number */
+#define DRM_MIN_ORDER 5 /* At least 2^5 bytes = 32 bytes */
+#define DRM_MAX_ORDER 22 /* Up to 2^22 bytes = 4MB */
+#define DRM_RAM_PERCENT 10 /* How much system ram can we lock? */
+
+#define _DRM_LOCK_HELD 0x80000000 /* Hardware lock is held */
+#define _DRM_LOCK_CONT 0x40000000 /* Hardware lock is contended */
+#define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD)
+#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT)
+#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT))
+
+typedef unsigned long drm_handle_t;
+typedef unsigned int drm_context_t;
+typedef unsigned int drm_drawable_t;
+typedef unsigned int drm_magic_t;
+
+
+typedef struct drm_version {
+ int version_major; /* Major version */
+ int version_minor; /* Minor version */
+ int version_patchlevel;/* Patch level */
+ size_t name_len; /* Length of name buffer */
+ char *name; /* Name of driver */
+ size_t date_len; /* Length of date buffer */
+ char *date; /* User-space buffer to hold date */
+ size_t desc_len; /* Length of desc buffer */
+ char *desc; /* User-space buffer to hold desc */
+} drm_version_t;
+
+typedef struct drm_list {
+ int count; /* Length of user-space structures */
+ drm_version_t *version;
+} drm_list_t;
+
+typedef struct drm_request {
+ const char *device_name; /* Requested device name */
+ const char *device_busid;/* Bus id */
+ int device_major;
+ int device_minor;
+} drm_request_t;
+
+typedef struct drm_block {
+ int unused;
+} drm_block_t;
+
+
+ /* These constants MUST MATCH xf86drm.h */
+#define _DRM_INST_LENGTH 5
+
+#define _DRM_M_WRITE 0x00
+#define _DRM_M_WHILE 0x01
+#define _DRM_M_IF 0x02
+#define _DRM_M_GOTO 0x03
+#define _DRM_M_NOOP 0x04
+#define _DRM_M_RETURN 0x05
+#define _DRM_M_DO 0x06
+#define _DRM_M_READ 0x07
+#define _DRM_M_TEST 0x08
+
+#define _DRM_T_IMM 0x00
+#define _DRM_T_LENGTH 0x01
+#define _DRM_T_ADDRESS 0x02
+#define _DRM_T_ACC 0x03
+
+#define _DRM_V_NONE 0x00
+#define _DRM_V_RSHIFT 0x01
+#define _DRM_V_LSHIFT 0x02
+
+#define _DRM_C_EQ 0x01
+#define _DRM_C_LT 0x02
+#define _DRM_C_GT 0x03
+#define _DRM_C_LE 0x04
+#define _DRM_C_GE 0x05
+#define _DRM_C_NE 0x06
+#define _DRM_C_BIT 0x07
+
+#define _DRM_F_NOOP 0x00
+#define _DRM_F_DMA 0x01
+#define _DRM_F_SYNC 0x02
+#define _DRM_F_EXTEN 0x03
+#define _DRM_F_ERROR 0x04
+#define _DRM_F_VERT 0x05
+#define _DRM_F_CLEAR 0x06
+
+#define _DRM_I_CMD(x) ((x) & 0xfff)
+#define _DRM_I_TYPE(x) (((x) & 0x00f) <<12)
+#define _DRM_I_MOD(x) (((x) & 0x00f) <<16)
+#define _DRM_I_MODVAL(x) (((x) & 0x0ff) <<24)
+#define _DRM_I_COND(x) (((x) & 0x00f) <<28)
+
+#define _DRM_E_CMD(x) ((x) &0x00000fff)
+#define _DRM_E_TYPE(x) (((x)&0x0000f000)>>12)
+#define _DRM_E_MOD(x) (((x)&0x000f0000)>>16)
+#define _DRM_E_MODVAL(x) (((x)&0x0ff00000)>>24)
+#define _DRM_E_COND(x) (((x)&0xf0000000)>>28)
+
+typedef enum {
+ _DRM_IH_PRE_INST, /* Before IH installation */
+ _DRM_IH_POST_INST, /* After IH installation */
+ _DRM_IH_SERVICE, /* IH */
+ _DRM_IH_PRE_UNINST, /* Before IH uninstallation */
+ _DRM_IH_POST_UNINST, /* After IH uninstallation */
+ _DRM_DMA_DISPATCH, /* DMA dispatch (including ready) */
+ _DRM_DMA_READY, /* Ready for DMA */
+ _DRM_DMA_IS_READY, /* Tests if hardware ready for another DMA */
+ _DRM_DMA_QUIESCENT, /* HW Sync */
+ _DRM_DESC_MAX
+} drm_desc_t;
+
+typedef struct drm_control {
+ enum {
+ DRM_ADD_COMMAND,
+ DRM_RM_COMMAND,
+ DRM_INST_HANDLER,
+ DRM_UNINST_HANDLER
+ } func;
+ drm_desc_t desc;
+ int irq;
+ int count;
+ int *inst;
+} drm_control_t;
+
+typedef enum drm_map_type {
+ _DRM_FRAME_BUFFER = 0, /* WC (no caching), no core dump */
+ _DRM_REGISTERS = 1, /* no caching, no core dump */
+ _DRM_SHM = 2 /* shared, cached */
+} drm_map_type_t;
+
+typedef enum drm_map_flags {
+ _DRM_RESTRICTED = 0x01, /* Cannot be mapped to user-virtual */
+ _DRM_READ_ONLY = 0x02,
+ _DRM_LOCKED = 0x04, /* shared, cached, locked */
+ _DRM_KERNEL = 0x08, /* kernel requires access */
+ _DRM_WRITE_COMBINING = 0x10, /* use write-combining if available */
+ _DRM_CONTAINS_LOCK = 0x20 /* SHM page that contains lock */
+} drm_map_flags_t;
+
+typedef struct drm_map {
+ unsigned long offset; /* Requested physical address (0 for SAREA)*/
+ unsigned long size; /* Requested physical size (bytes) */
+ drm_map_type_t type; /* Type of memory to map */
+ drm_map_flags_t flags; /* Flags */
+ void *handle; /* User-space: "Handle" to pass to mmap */
+ /* Kernel-space: kernel-virtual address */
+ int mtrr; /* MTRR slot used */
+ /* Private data */
+} drm_map_t;
+
+typedef enum drm_lock_flags {
+ _DRM_LOCK_READY = 0x01, /* Wait until hardware is ready for DMA */
+ _DRM_LOCK_QUIESCENT = 0x02, /* Wait until hardware quiescent */
+ _DRM_LOCK_FLUSH = 0x04, /* Flush this context's DMA queue first */
+ _DRM_LOCK_FLUSH_ALL = 0x08, /* Flush all DMA queues first */
+ /* These *HALT* flags aren't supported yet
+ -- they will be used to support the
+ full-screen DGA-like mode. */
+ _DRM_HALT_ALL_QUEUES = 0x10, /* Halt all current and future queues */
+ _DRM_HALT_CUR_QUEUES = 0x20 /* Halt all current queues */
+} drm_lock_flags_t;
+
+typedef struct drm_lock {
+ int context;
+ drm_lock_flags_t flags;
+} drm_lock_t;
+
+typedef enum drm_dma_flags { /* These values *MUST* match xf86drm.h */
+ /* Flags for DMA buffer dispatch */
+ _DRM_DMA_BLOCK = 0x01, /* Block until buffer dispatched.
+ Note, the buffer may not yet have
+ been processed by the hardware --
+ getting a hardware lock with the
+ hardware quiescent will ensure
+ that the buffer has been
+ processed. */
+ _DRM_DMA_WHILE_LOCKED = 0x02, /* Dispatch while lock held */
+ _DRM_DMA_PRIORITY = 0x04, /* High priority dispatch */
+
+ /* Flags for DMA buffer request */
+ _DRM_DMA_WAIT = 0x10, /* Wait for free buffers */
+ _DRM_DMA_SMALLER_OK = 0x20, /* Smaller-than-requested buffers ok */
+ _DRM_DMA_LARGER_OK = 0x40 /* Larger-than-requested buffers ok */
+} drm_dma_flags_t;
+
+typedef struct drm_buf_desc {
+ int count; /* Number of buffers of this size */
+ int size; /* Size in bytes */
+ int low_mark; /* Low water mark */
+ int high_mark; /* High water mark */
+ enum {
+ DRM_PAGE_ALIGN = 0x01 /* Align on page boundaries for DMA */
+ } flags;
+} drm_buf_desc_t;
+
+typedef struct drm_buf_info {
+ int count; /* Entries in list */
+ drm_buf_desc_t *list;
+} drm_buf_info_t;
+
+typedef struct drm_buf_free {
+ int count;
+ int *list;
+} drm_buf_free_t;
+
+typedef struct drm_buf_pub {
+ int idx; /* Index into master buflist */
+ int total; /* Buffer size */
+ int used; /* Amount of buffer in use (for DMA) */
+ void *address; /* Address of buffer */
+} drm_buf_pub_t;
+
+typedef struct drm_buf_map {
+ int count; /* Length of buflist */
+ void *virtual; /* Mmaped area in user-virtual */
+ drm_buf_pub_t *list; /* Buffer information */
+} drm_buf_map_t;
+
+typedef struct drm_dma {
+ /* Indices here refer to the offset into
+ buflist in drm_buf_get_t. */
+ int context; /* Context handle */
+ int send_count; /* Number of buffers to send */
+ int *send_indices; /* List of handles to buffers */
+ int *send_sizes; /* Lengths of data to send */
+ drm_dma_flags_t flags; /* Flags */
+ int request_count; /* Number of buffers requested */
+ int request_size; /* Desired size for buffers */
+ int *request_indices; /* Buffer information */
+ int *request_sizes;
+ int granted_count; /* Number of buffers granted */
+} drm_dma_t;
+
+typedef enum {
+ _DRM_CONTEXT_PRESERVED = 0x01,
+ _DRM_CONTEXT_2DONLY = 0x02
+} drm_ctx_flags_t;
+
+typedef struct drm_ctx {
+ drm_context_t handle;
+ drm_ctx_flags_t flags;
+} drm_ctx_t;
+
+typedef struct drm_ctx_res {
+ int count;
+ drm_ctx_t *contexts;
+} drm_ctx_res_t;
+
+typedef struct drm_draw {
+ drm_drawable_t handle;
+} drm_draw_t;
+
+typedef struct drm_auth {
+ drm_magic_t magic;
+} drm_auth_t;
+
+typedef struct drm_irq_busid {
+ int irq;
+ int busnum;
+ int devnum;
+ int funcnum;
+} drm_irq_busid_t;
+
+#define DRM_IOCTL_BASE 'd'
+#define DRM_IOCTL_NR(n) _IOC_NR(n)
+#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
+#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size)
+#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size)
+#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size)
+
+
+#define DRM_IOCTL_VERSION DRM_IOR( 0x00, drm_version_t)
+#define DRM_IOCTL_LIST DRM_IOR( 0x01, drm_list_t)
+#define DRM_IOCTL_CREATE DRM_IOWR(0x02, drm_request_t)
+#define DRM_IOCTL_DESTROY DRM_IOWR(0x03, drm_request_t)
+#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x04, drm_irq_busid_t)
+
+#define DRM_IOCTL_BLOCK DRM_IOWR(0x10, drm_block_t)
+#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x11, drm_block_t)
+#define DRM_IOCTL_CONTROL DRM_IOW( 0x12, drm_control_t)
+#define DRM_IOCTL_GET_MAGIC DRM_IOW( 0x13, drm_auth_t)
+#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x14, drm_auth_t)
+#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, drm_map_t)
+#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, drm_buf_desc_t)
+#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, drm_buf_desc_t)
+#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm_buf_info_t)
+#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t)
+#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t)
+
+#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t)
+#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t)
+#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t)
+#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, drm_ctx_t)
+#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, drm_ctx_t)
+#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, drm_ctx_t)
+#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, drm_ctx_res_t)
+#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, drm_draw_t)
+#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, drm_draw_t)
+#define DRM_IOCTL_DMA DRM_IOWR(0x29, drm_dma_t)
+#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, drm_lock_t)
+#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t)
+#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t)
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drmP.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drmP.h
new file mode 100644
index 000000000..ecfae3fed
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drmP.h
@@ -0,0 +1,731 @@
+/* drmP.h -- Private header for Direct Rendering Manager -*- linux-c -*-
+ * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
+ * Revised: Fri Jun 18 09:47:36 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drmP.h,v 1.47 1999/06/21 14:31:21 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drmP.h,v 1.2 1999/06/27 14:08:24 dawes Exp $
+ *
+ */
+
+#ifndef _DRM_P_H_
+#define _DRM_P_H_
+
+#ifdef __KERNEL__
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/file.h>
+#include <linux/pci.h>
+#include <linux/wrapper.h>
+#include <asm/io.h>
+#include <asm/mman.h>
+#include <asm/uaccess.h>
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+#include "drm.h"
+#include "drm_version.h"
+
+#define DRM_DEBUG_CODE 2 /* Include debugging code (if > 1, then
+ also include looping detection. */
+#define DRM_DMA_HISTOGRAM 1 /* Make histogram of DMA latency. */
+
+#define DRM_FLAG_TRACE 0x0001
+#define DRM_FLAG_DEBUG 0x0002
+#define DRM_FLAG_VERB 0x0004
+#define DRM_FLAG_MEM 0x0008
+#define DRM_FLAG_LOCK 0x0010
+#define DRM_FLAG_NOCTX 0x1000
+
+#define DRM_HASH_SIZE 16 /* Size of key hash table */
+#define DRM_KERNEL_CONTEXT 0 /* Change drm_resctx if changed */
+#define DRM_RESERVED_CONTEXTS 1 /* Change drm_resctx if changed */
+#define DRM_LOOPING_LIMIT 5000000
+#define DRM_BSZ 1024 /* Buffer size for /dev/drm? output */
+#define DRM_TIME_SLICE (HZ/20) /* Time slice for GLXContexts */
+#define DRM_LOCK_SLICE 1 /* Time slice for lock, in jiffies */
+
+#define DRM_MEM_DMA 0
+#define DRM_MEM_SAREA 1
+#define DRM_MEM_DRIVER 2
+#define DRM_MEM_MAGIC 3
+#define DRM_MEM_IOCTLS 4
+#define DRM_MEM_MAPS 5
+#define DRM_MEM_VMAS 6
+#define DRM_MEM_BUFS 7
+#define DRM_MEM_SEGS 8
+#define DRM_MEM_PAGES 9
+#define DRM_MEM_FILES 10
+#define DRM_MEM_QUEUES 11
+#define DRM_MEM_CMDS 12
+#define DRM_MEM_MAPPINGS 13
+#define DRM_MEM_BUFLISTS 14
+
+ /* Backward compatibility section */
+#ifndef _PAGE_PWT
+ /* The name of _PAGE_WT was changed to
+ _PAGE_PWT in Linux 2.2.6 */
+#define _PAGE_PWT _PAGE_WT
+#endif
+ /* Wait queue declarations changes in 2.3.1 */
+#ifndef DECLARE_WAITQUEUE
+#define DECLARE_WAITQUEUE(w,c) struct wait_queue w = { c, NULL }
+typedef struct wait_queue *wait_queue_head_t;
+#define init_waitqueue_head(q) *q = NULL;
+#endif
+
+#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)
+#define _DRM_CAS(lock,old,new,__ret) \
+ do { \
+ int __dummy; /* Can't mark eax as clobbered */ \
+ __asm__ __volatile__( \
+ "lock ; cmpxchg %4,%1\n\t" \
+ "setnz %0" \
+ : "=d" (__ret), \
+ "=m" (__drm_dummy_lock(lock)), \
+ "=a" (__dummy) \
+ : "2" (old), \
+ "r" (new)); \
+ } while (0)
+
+
+
+ /* Macros to make printk easier */
+#define DRM_ERROR(fmt, arg...) \
+ printk(KERN_ERR "[" DRM_NAME ":" __FUNCTION__ "] *ERROR* " fmt , ##arg)
+#define DRM_MEM_ERROR(area, fmt, arg...) \
+ printk(KERN_ERR "[" DRM_NAME ":" __FUNCTION__ ":%s] *ERROR* " fmt , \
+ drm_mem_stats[area].name , ##arg)
+#define DRM_INFO(fmt, arg...) printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg)
+#define DRM_MAX(a,b) ((a)>(b)?(a):(b))
+#define DRM_MIN(a,b) ((a)<(b)?(a):(b))
+
+#if DRM_DEBUG_CODE
+#define DRM_TRACE(fmt, arg...) \
+ do { \
+ if (drm_flags&DRM_FLAG_TRACE) \
+ printk(KERN_DEBUG \
+ "[" DRM_NAME ":" __FUNCTION__ "] " fmt , \
+ ##arg); \
+ } while (0)
+#define DRM_DEBUG(fmt, arg...) \
+ do { \
+ if (drm_flags&DRM_FLAG_DEBUG) \
+ printk(KERN_DEBUG \
+ "[" DRM_NAME ":" __FUNCTION__ "] " fmt , \
+ ##arg); \
+ } while (0)
+#define DRM_VERB(fmt, arg...) \
+ do { \
+ if (drm_flags&DRM_FLAG_VERB) \
+ printk(KERN_DEBUG \
+ "[" DRM_NAME ":" __FUNCTION__ "] " fmt , \
+ ##arg); \
+ } while (0)
+#define DRM_LOCK_VERB(fmt, arg...) \
+ do { \
+ if (drm_flags&DRM_FLAG_VERB) \
+ printk(KERN_DEBUG \
+ "[" DRM_NAME ":" __FUNCTION__ "] " fmt , \
+ ##arg); \
+ } while (0)
+#define DRM_MEM_VERB(area, fmt, arg...) \
+ do { \
+ if (drm_flags&DRM_FLAG_MEM) \
+ printk(KERN_DEBUG \
+ "[" DRM_NAME ":" __FUNCTION__ ":%s] " fmt ,\
+ drm_mem_stats[area].name, ##arg); \
+ } while (0)
+#else
+#define DRM_TRACE(fmt, arg...) do { } while (0)
+#define DRM_VERB(fmt, arg...) do { } while (0)
+#define DRM_DEBUG(fmt, arg...) do { } while (0)
+#define DRM_LOCK_VERB(fmt, arg...) do { } while (0)
+#define DRM_MEM_VERB(area, fmt, arg...) do { } while (0)
+#define DRM_MEM_ERROR(area, fmt, arg...) do { } while (0)
+#endif
+
+ /* Internal types and structures */
+#define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
+#define DRM_MIN(a,b) ((a)<(b)?(a):(b))
+
+#define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1))
+#define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x))
+#define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist)
+
+#define DRM_IOCTL_ARGS \
+(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+
+typedef int drm_ioctl_t DRM_IOCTL_ARGS;
+
+typedef struct drm_ioctl_desc {
+ drm_ioctl_t *func;
+ int root_only;
+ enum {
+ DRM_BASE = 0x01, /* Always route via base driver */
+ DRM_NOLOCK = 0x02, /* Don't hold read lock for ioctl */
+ } dispatch;
+} drm_ioctl_desc_t;
+
+typedef struct drm_func_desc {
+ int (*reg)(void); /* Executed at driver registration */
+ int (*unreg)(void); /* Executed at driver unregistration */
+ int (*load)(void); /* Executed when device loaded */
+ int (*unload)(void); /* Executed when device unloaded */
+
+ /* These are similar to struct
+ file_operations, but are called after
+ our routines. */
+ int (*open)(struct inode *inode, struct file *filp);
+ int (*release)(struct inode *inode, struct file *filp);
+} drm_func_desc_t;
+
+typedef struct drm_driver {
+ /* Defined by driver */
+ const char *name;
+ drm_version_t *version;
+ drm_ioctl_desc_t *ioctls;
+ int ioctl_count;
+ drm_func_desc_t *funcs;
+ /* Bookkeeping */
+ struct drm_driver *next;
+ int refcount;
+ int base; /* Base driver, automatically instantiated */
+} drm_driver_t;
+
+typedef struct drm_devstate {
+ pid_t owner; /* X server pid holding x_lock */
+
+} drm_devstate_t;
+
+typedef struct drm_magic_entry {
+ drm_magic_t magic;
+ struct drm_file *priv;
+ struct drm_magic_entry *next;
+} drm_magic_entry_t;
+
+typedef struct drm_magic_head {
+ struct drm_magic_entry *head;
+ struct drm_magic_entry *tail;
+} drm_magic_head_t;
+
+typedef struct drm_vma_entry {
+ struct vm_area_struct *vma;
+ struct drm_vma_entry *next;
+ pid_t pid;
+} drm_vma_entry_t;
+
+typedef struct drm_buf {
+ int idx; /* Index into master buflist */
+ int total; /* Buffer size */
+ int order; /* log-base-2(total) */
+ int used; /* Amount of buffer in use (for DMA) */
+ unsigned long offset; /* Byte offset (used internally) */
+ void *address; /* Address of buffer */
+ struct drm_buf *next; /* Kernel-only: used for free list */
+ __volatile__ int waiting; /* On kernel DMA queue */
+ __volatile__ int pending; /* On hardware DMA queue */
+ wait_queue_head_t dma_wait; /* Processes waiting */
+ pid_t pid; /* PID of holding process */
+ int context; /* Kernel queue for this buffer */
+ int while_locked;/* Dispatch this buffer while locked */
+// int stamp; /* Pending stamp */
+ enum {
+ DRM_LIST_NONE = 0,
+ DRM_LIST_FREE = 1,
+ DRM_LIST_WAIT = 2,
+ DRM_LIST_PEND = 3,
+ DRM_LIST_PRIO = 4,
+ DRM_LIST_RECLAIM = 5
+ } list; /* Which list we're on */
+#if DRM_DMA_HISTOGRAM
+ cycles_t time_queued; /* Queued to kernel DMA queue */
+ cycles_t time_dispatched; /* Dispatched to hardware */
+ cycles_t time_completed; /* Completed by hardware */
+ cycles_t time_freed; /* Back on freelist */
+#endif
+} drm_buf_t;
+
+#if DRM_DMA_HISTOGRAM
+#define DRM_DMA_HISTOGRAM_SLOTS 9
+#define DRM_DMA_HISTOGRAM_INITIAL 10
+#define DRM_DMA_HISTOGRAM_NEXT(current) ((current)*10)
+typedef struct drm_histogram {
+ atomic_t total;
+
+ atomic_t queued_to_dispatched[DRM_DMA_HISTOGRAM_SLOTS];
+ atomic_t dispatched_to_completed[DRM_DMA_HISTOGRAM_SLOTS];
+ atomic_t completed_to_freed[DRM_DMA_HISTOGRAM_SLOTS];
+
+ atomic_t queued_to_completed[DRM_DMA_HISTOGRAM_SLOTS];
+ atomic_t queued_to_freed[DRM_DMA_HISTOGRAM_SLOTS];
+
+ atomic_t dma[DRM_DMA_HISTOGRAM_SLOTS];
+ atomic_t schedule[DRM_DMA_HISTOGRAM_SLOTS];
+ atomic_t ctx[DRM_DMA_HISTOGRAM_SLOTS];
+ atomic_t lacq[DRM_DMA_HISTOGRAM_SLOTS];
+ atomic_t lhld[DRM_DMA_HISTOGRAM_SLOTS];
+} drm_histogram_t;
+#endif
+
+ /* bufs is one longer than it has to be */
+typedef struct drm_waitlist {
+ int count; /* Number of possible buffers */
+ drm_buf_t **bufs; /* List of pointers to buffers */
+ drm_buf_t **rp; /* Read pointer */
+ drm_buf_t **wp; /* Write pointer */
+ drm_buf_t **end; /* End pointer */
+ spinlock_t read_lock;
+ spinlock_t write_lock;
+} drm_waitlist_t;
+
+typedef struct drm_freelist {
+ int initialized; /* Freelist in use */
+ atomic_t count; /* Number of free buffers */
+ drm_buf_t *next; /* End pointer */
+
+ wait_queue_head_t waiting; /* Processes waiting on free bufs */
+ int low_mark; /* Low water mark */
+ int high_mark; /* High water mark */
+ atomic_t wfh; /* If waiting for high mark */
+} drm_freelist_t;
+
+typedef struct drm_buf_entry {
+ int buf_size;
+ int buf_count;
+ drm_buf_t *buflist;
+ int seg_count;
+ int page_order;
+ unsigned long *seglist;
+
+ drm_freelist_t freelist;
+} drm_buf_entry_t;
+
+typedef struct drm_hw_lock {
+ __volatile__ unsigned int lock;
+ char padding[60];
+ /* We'll make this big enough for most
+ current (and future?) architectures:
+ DEC Alpha: 32 bytes
+ Intel Merced: ?
+ Intel P5/PPro/PII/PIII: 32 bytes
+ Intel StrongARM: 32 bytes
+ Intel i386/i486: 16 bytes
+ MIPS: 32 bytes (?)
+ Motorola 68k: 16 bytes
+ Motorola PowerPC: 32 bytes
+ Sun SPARC: 32 bytes
+ */
+} drm_hw_lock_t;
+
+typedef struct drm_file {
+ enum {
+ DRM_AUTH_OK = 0,
+ DRM_AUTH_PENDING,
+ DRM_AUTH_FAILED
+ } auth;
+ int minor;
+ pid_t pid;
+ uid_t uid;
+ drm_magic_t magic;
+ unsigned long ioctl_count;
+ struct drm_file *next;
+ struct drm_file *prev;
+ struct drm_device *dev;
+} drm_file_t;
+
+
+typedef struct drm_queue {
+ atomic_t use_count; /* Outstanding uses (+1) */
+ atomic_t finalization; /* Finalization in progress */
+ atomic_t block_count; /* Count of processes waiting */
+ atomic_t block_read; /* Queue blocked for reads */
+ wait_queue_head_t read_queue; /* Processes waiting on block_read */
+ atomic_t block_write; /* Queue blocked for writes */
+ wait_queue_head_t write_queue; /* Processes waiting on block_write */
+ atomic_t total_queued; /* Total queued statistic */
+ atomic_t total_flushed;/* Total flushes statistic */
+ atomic_t total_locks; /* Total locks statistics */
+ drm_ctx_flags_t flags; /* Context preserving and 2D-only */
+ drm_waitlist_t waitlist; /* Pending buffers */
+ wait_queue_head_t flush_queue; /* Processes waiting until flush */
+} drm_queue_t;
+
+typedef struct drm_device *drm_device_t_dummy_reference;
+
+typedef struct drm_command {
+ int count; /* Number of instructions */
+ int *inst; /* Byte-code instructions */
+ int (*f)(struct drm_device *dev,
+ drm_desc_t command,
+ unsigned long address,
+ unsigned long length); /* Loadable callback */
+} drm_command_t;
+
+typedef struct drm_lock_data {
+ drm_hw_lock_t *hw_lock; /* Hardware lock */
+ pid_t pid; /* PID of lock holder (0=kernel) */
+ wait_queue_head_t lock_queue; /* Queue of blocked processes */
+ unsigned long lock_time; /* Time of last lock in jiffies */
+} drm_lock_data_t;
+
+typedef struct drm_device {
+ dev_t device_minor; /* Minor for this device */
+ drm_driver_t *driver;
+ char *busid;
+ char *devname; /* For /proc/interrupts */
+ int blocked; /* Blocked due to VC switch? */
+ struct proc_dir_entry *root; /* Root for this device's entries */
+
+ /* Locks */
+ spinlock_t count_lock; /* For inuse, open_count, buf_use */
+ rwlock_t queue_lock; /* For queue_count, queuelist */
+ spinlock_t struct_lock; /* For others */
+
+ /* Usage Counters */
+ int inuse; /* Slot is in use */
+ int open_count; /* Outstanding files open */
+ atomic_t ioctl_count; /* Outstanding IOCTLs pending */
+ atomic_t vma_count; /* Outstanding vma areas open */
+ int buf_use; /* Buffers in use -- cannot alloc */
+ atomic_t buf_alloc; /* Buffer allocation in progress */
+
+ /* Performance Counters */
+ atomic_t total_open;
+ atomic_t total_close;
+ atomic_t total_ioctl;
+ atomic_t total_irq; /* Total interruptions */
+ atomic_t total_prio; /* Total DRM_DMA_PRIORITY */
+ atomic_t total_ctx; /* Total context switches */
+ atomic_t total_bytes; /* Total bytes DMA'd */
+ atomic_t total_dmas; /* Total DMA buffers dispatched */
+
+
+ atomic_t total_missed_dma; /* Missed drm_do_dma */
+ atomic_t total_missed_lock; /* Missed lock in drm_do_dma */
+ atomic_t total_missed_free; /* Missed drm_free_this_buffer */
+ atomic_t total_missed_sched;/* Missed drm_dma_schedule */
+
+ atomic_t total_tried; /* Tried next_buffer */
+ atomic_t total_hit; /* Sent next_buffer */
+ atomic_t total_lost; /* Lost interrupt */
+
+ atomic_t total_locks;
+ atomic_t total_unlocks;
+ atomic_t total_contends;
+ atomic_t total_sleeps;
+
+ /* Magic numbers for authentication */
+ drm_magic_head_t magiclist[DRM_HASH_SIZE];
+
+ /* Memory management */
+ drm_map_t **maplist; /* Vector of pointers to regions */
+ int map_count; /* Number of mappable regions */
+
+ drm_vma_entry_t *vmalist; /* List of vmas (for debugging) */
+ drm_lock_data_t lock; /* Information on hardware lock */
+
+ drm_buf_entry_t bufs[DRM_MAX_ORDER+1];
+ int buf_count;
+ drm_buf_t **buflist; /* Vector of pointers info bufs */
+ int seg_count;
+ int page_count;
+ unsigned long *pagelist;
+ unsigned long byte_count;
+
+ /* DMA queues */
+ int queue_count; /* Number of active DMA queues */
+ int queue_reserved; /* Number of reserved DMA queues */
+ int queue_slots; /* Actual length of queuelist */
+ drm_queue_t **queuelist; /* Vector of pointers to DMA queues */
+
+ /* DMA support */
+ drm_command_t cmd[_DRM_DESC_MAX];
+ int irq; /* Interrupt used by board */
+ __volatile__ int context_flag; /* Context swapping flag */
+ __volatile__ int interrupt_flag;/* Interruption handler flag */
+ __volatile__ int dma_flag; /* DMA dispatch flag */
+ int last_context; /* Last context to do DMA */
+ unsigned long last_switch; /* Number of jiffies at last switch*/
+ int last_checked; /* Last context checked for DMA */
+ struct timer_list timer; /* Timer for delaying ctx switch */
+ drm_buf_t *this_buffer; /* Buffer being sent */
+ drm_buf_t *next_buffer; /* Selected buffer to send */
+ drm_queue_t *next_queue; /* Queue from which buffer selected*/
+ wait_queue_head_t waiting; /* Processes waiting on free bufs */
+ wait_queue_head_t context_wait;/* Processes waiting on ctx switch */
+#if DRM_DMA_HISTOGRAM
+ drm_histogram_t histo;
+#endif
+ struct tq_struct tq;
+ cycles_t ctx_start;
+ cycles_t lck_start;
+
+ /* Callback to X server for context switch */
+ char buf[DRM_BSZ]; /* Output buffer */
+ char *buf_rp; /* Read pointer */
+ char *buf_wp; /* Write pointer */
+ char *buf_end; /* End pointer */
+ struct fasync_struct *buf_async;/* Processes waiting for SIGIO */
+ wait_queue_head_t buf_readers; /* Processes waiting to read */
+ wait_queue_head_t buf_writers; /* Processes waiting to ctx switch */
+} drm_device_t;
+
+typedef struct drm_mem_stats {
+ const char *name;
+ int succeed_count;
+ int free_count;
+ int fail_count;
+ unsigned long bytes_allocated;
+ unsigned long bytes_freed;
+} drm_mem_stats_t;
+
+
+ /* Internal global variables */
+
+extern int drm_flags; /* Debugging flags */
+extern int drm_major; /* Major device used */
+extern spinlock_t drm_mem_lock; /* For drm_mem_stats & drm_ram_* */
+extern drm_mem_stats_t drm_mem_stats[]; /* Memory usage statistics */
+extern drm_file_t *drm_file_first; /* List of per-connection info */
+extern drm_file_t *drm_file_last;
+extern unsigned long drm_ram_available; /* Total System RAM */
+extern unsigned long drm_ram_used; /* RAM locked in kernel space */
+
+ /* GLOBAL LOCKS */
+
+ /* drm_meta_lock is used to serialize
+ creation and deletion of drm_drivers,
+ drm_devices, and drm_file_*. */
+extern spinlock_t drm_meta_lock;
+
+
+ /* Drivers can be a linked list, because
+ this never has to be indexed. This list
+ is only searched inefficiently once,
+ when a device is instantiated.*/
+extern drm_driver_t *drm_drivers;
+extern drm_driver_t *drm_drivers_tail;
+
+ /* Devices needs to be indexed for
+ efficient ioctls, so use a vector
+ instead of a linked list. This
+ introduces a hard limit on the number of
+ devices, but the limit is reasonable,
+ since most people won't have more than
+ 2-3 graphics adapters in their machine.
+ Further, the limit decreases ioctl
+ processing time, so the tradeoff is
+ reasonable. */
+extern drm_device_t drm_devices[DRM_MAX_DEVICES];
+extern int drm_device_count;
+
+
+ /* Internal function definitions */
+
+
+ /* Setup/cleanup support */
+extern void __init drm_setup(char *str, int *ints);
+extern int drm_init(void);
+extern void drm_cleanup(void);
+extern void drm_register_driver(const char *name,
+ drm_version_t *version,
+ int ioctl_count,
+ drm_ioctl_desc_t *ioctls,
+ drm_func_desc_t *funcs);
+extern void drm_register_driver_internal(const char *name,
+ drm_version_t *version,
+ int ioctl_count,
+ drm_ioctl_desc_t *ioctls,
+ drm_func_desc_t *funcs,
+ int base);
+extern void drm_unregister_driver(const char *name);
+extern int drm_register_device(const char *name,
+ const char *busid,
+ int allow_base);
+extern int drm_unregister_device(int minor);
+
+ /* Device support */
+extern int drm_open(struct inode *inode, struct file *filp);
+extern int drm_flush(struct file *filp);
+extern int drm_release(struct inode *inode, struct file *filp);
+extern int drm_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg);
+extern ssize_t drm_read(struct file *filp, char *buf, size_t count,
+ loff_t *off);
+extern int drm_fasync(int fd, struct file *filp, int on);
+extern int drm_write_string(drm_device_t *dev, const char *s);
+
+extern int drm_mmap(struct file *filp, struct vm_area_struct *vma);
+extern int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma);
+extern void drm_vm_open(struct vm_area_struct *vma);
+extern void drm_vm_close(struct vm_area_struct *vma);
+extern unsigned long drm_vm_nopage(struct vm_area_struct *vma,
+ unsigned long address,
+ int write_access);
+extern unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma,
+ unsigned long address,
+ int write_access);
+extern unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma,
+ unsigned long address,
+ int write_access);
+
+
+ /* Proc support (drm_proc.c) */
+extern int drm_proc_init(void);
+extern int drm_proc_cleanup(void);
+extern int drm_proc_add_device(drm_device_t *dev);
+extern int drm_proc_del_device(drm_device_t *dev);
+extern int drm_driver_info(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data);
+extern int drm_device_info(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data);
+extern int drm_mem_info(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data);
+extern int drm_meminfo_info(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data);
+extern int drm_clients_info(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data);
+#if DRM_DEBUG_CODE
+extern int drm_vmainfo_info(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data);
+#endif
+#if DRM_DMA_HISTOGRAM
+extern int drm_histo_info(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data);
+#endif
+extern int drm_queues_info(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data);
+extern int drm_bufs_info(char *buf, char **start, off_t offset,
+ int len, int *eof, void *data);
+
+ /* Memory management support (drm_mem.c) */
+
+extern void *drm_alloc(size_t size, int area);
+extern void drm_free(void *pt, size_t size, int area);
+extern char *drm_strdup(const char *s, int area);
+extern void drm_strfree(const char *s, int area);
+extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size,
+ int area);
+extern unsigned long drm_alloc_dma(int order);
+extern void drm_free_dma(unsigned long address, int order);
+extern void *drm_vmalloc(unsigned int size);
+extern void drm_vfree(void *pt, unsigned int size);
+extern void *drm_ioremap(unsigned long offset, unsigned long size);
+extern void drm_ioremapfree(void *pt, unsigned long size);
+
+ /* Buffer list management support
+ (gen_bufs.c) */
+extern int drm_waitlist_create(drm_waitlist_t *bl, int count);
+extern int drm_waitlist_destroy(drm_waitlist_t *bl);
+extern int drm_waitlist_put(drm_waitlist_t *bl, drm_buf_t *buf);
+extern drm_buf_t *drm_waitlist_get(drm_waitlist_t *bl);
+
+extern int drm_freelist_create(drm_freelist_t *bl, int count);
+extern int drm_freelist_destroy(drm_freelist_t *bl);
+extern int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl,
+ drm_buf_t *buf);
+extern drm_buf_t *drm_freelist_get(drm_freelist_t *bl, int block);
+
+extern void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf);
+
+ /* DMA support (gen_dma.c) */
+extern int drm_irq_install(drm_device_t *dev, int irq);
+extern int drm_irq_uninstall(drm_device_t *dev);
+extern int drm_engine(drm_device_t *dev,
+ drm_desc_t command,
+ unsigned long address,
+ unsigned long length);
+extern int drm_dma_schedule(drm_device_t *dev, int locked);
+extern void drm_wakeup(drm_device_t *dev, drm_buf_t *buf);
+extern int drm_do_dma(drm_device_t *dev, int locked);
+extern int drm_context_switch(drm_device_t *dev, int old, int new);
+extern int drm_context_switch_complete(drm_device_t *dev, int new);
+extern void drm_reclaim_buffers(drm_device_t *dev, pid_t pid);
+#if DRM_DMA_HISTOGRAM
+extern void drm_histogram_compute(drm_device_t *dev, drm_buf_t *buf);
+extern int drm_histogram_slot(unsigned long count);
+#endif
+
+
+extern __inline__ int drm_do_command(drm_device_t *dev,
+ drm_desc_t command)
+{
+ if (dev->cmd[command].f)
+ return dev->cmd[command].f(dev, command, 0, 0);
+ return drm_engine(dev, command, 0, 0);
+}
+
+
+ /* BASE IOCTLs */
+extern int drm_version DRM_IOCTL_ARGS;
+extern int drm_list DRM_IOCTL_ARGS;
+extern int drm_create DRM_IOCTL_ARGS;
+extern int drm_destroy DRM_IOCTL_ARGS;
+extern int drm_irq_busid DRM_IOCTL_ARGS;
+
+ /* GENERIC IOCTLs and support functions*/
+extern int drm_order(unsigned long size);
+extern int drm_block DRM_IOCTL_ARGS;
+extern int drm_unblock DRM_IOCTL_ARGS;
+extern int drm_control DRM_IOCTL_ARGS;
+extern int drm_getmagic DRM_IOCTL_ARGS;
+extern int drm_authmagic DRM_IOCTL_ARGS;
+extern int drm_add_magic(drm_device_t *dev, drm_file_t *priv,
+ drm_magic_t magic);
+extern int drm_remove_magic(drm_device_t *dev, drm_magic_t magic);
+extern int drm_addmap DRM_IOCTL_ARGS;
+extern int drm_addbufs DRM_IOCTL_ARGS;
+extern int drm_markbufs DRM_IOCTL_ARGS;
+extern int drm_infobufs DRM_IOCTL_ARGS;
+extern int drm_freebufs DRM_IOCTL_ARGS;
+extern int drm_mapbufs DRM_IOCTL_ARGS;
+extern int drm_dma DRM_IOCTL_ARGS;
+extern int drm_lock DRM_IOCTL_ARGS;
+extern int drm_unlock DRM_IOCTL_ARGS;
+extern int drm_reg( void );
+extern int drm_unreg( void );
+extern int drm_addctx DRM_IOCTL_ARGS;
+extern int drm_resctx DRM_IOCTL_ARGS;
+extern int drm_rmctx DRM_IOCTL_ARGS;
+extern int drm_modctx DRM_IOCTL_ARGS;
+extern int drm_getctx DRM_IOCTL_ARGS;
+extern int drm_newctx DRM_IOCTL_ARGS;
+extern int drm_switchctx DRM_IOCTL_ARGS;
+extern int drm_adddraw DRM_IOCTL_ARGS;
+extern int drm_rmdraw DRM_IOCTL_ARGS;
+extern int drm_auth DRM_IOCTL_ARGS;
+extern int drm_finish DRM_IOCTL_ARGS;
+
+extern int drm_lock_take(__volatile__ unsigned int *lock,
+ unsigned int context);
+extern int drm_lock_free(drm_device_t *dev,
+ __volatile__ unsigned int *lock,
+ unsigned int context);
+#endif
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_ioctl.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_ioctl.c
new file mode 100644
index 000000000..5a72044f8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_ioctl.c
@@ -0,0 +1,261 @@
+/* drm_ioctl.c -- IOCTL processing for DRM -*- linux-c -*-
+ * Created: Fri Jan 8 09:01:26 1999 by faith@precisioninsight.com
+ * Revised: Fri Jun 18 09:49:12 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_ioctl.c,v 1.17 1999/06/21 14:31:21 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_ioctl.c,v 1.2 1999/06/27 14:08:25 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+int drm_version DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_driver_t *drv = dev->driver;
+ drm_version_t version;
+ drm_version_t *vp;
+ int len;
+
+ copy_from_user_ret(&version,
+ (drm_version_t *)arg,
+ sizeof(version),
+ -EFAULT);
+
+
+ /* It is essential to zero the lengths for
+ information that is not returned -- a
+ user-level program may depend on the
+ lengths to allocate the buffers. */
+#define DRM_COPY(name,value) \
+ len = name##_len; \
+ name##_len = value##_len; \
+ if (len > name##_len) len = name##_len; \
+ if (len && value##_len && name) { \
+ copy_to_user_ret(name, value, len, -EFAULT); \
+ }
+
+ vp = drv->version;
+ version.version_major = vp->version_major;
+ version.version_minor = vp->version_minor;
+ version.version_patchlevel = vp->version_patchlevel;
+
+ DRM_COPY(version.name, vp->name);
+ DRM_COPY(version.date, vp->date);
+ DRM_COPY(version.desc, vp->desc);
+
+ copy_to_user_ret((drm_version_t *)arg,
+ &version,
+ sizeof(version),
+ -EFAULT);
+ return 0;
+}
+
+int drm_list DRM_IOCTL_ARGS
+{
+ drm_list_t list;
+ drm_version_t version;
+ int count = 0;
+ drm_driver_t *pt;
+ int len;
+
+ DRM_TRACE("\n");
+ copy_from_user_ret(&list,
+ (drm_list_t *)arg,
+ sizeof(list),
+ -EFAULT);
+
+ for (pt = drm_drivers; pt; pt = pt->next) {
+ if (pt->base) continue;
+ if (count < list.count) {
+ copy_from_user_ret(&version,
+ &list.version[count],
+ sizeof(version),
+ -EFAULT);
+ version.version_major = pt->version->version_major;
+ version.version_minor = pt->version->version_minor;
+ version.version_patchlevel
+ = pt->version->version_patchlevel;
+
+ DRM_COPY(version.name, pt->version->name);
+ DRM_COPY(version.date, pt->version->date);
+ DRM_COPY(version.desc, pt->version->desc);
+ copy_to_user_ret(&list.version[count],
+ &version,
+ sizeof(version),
+ -EFAULT);
+ }
+ ++count;
+ }
+
+ list.count = count;
+
+ copy_to_user_ret((drm_list_t *)arg,
+ &list,
+ sizeof(list),
+ -EFAULT);
+ return 0;
+}
+
+int drm_create DRM_IOCTL_ARGS
+{
+ drm_request_t request;
+ char name[DRM_MAX_NAMELEN+2];
+ char busid[DRM_MAX_NAMELEN+2];
+ int retcode;
+
+ copy_from_user_ret(&request,
+ (drm_request_t *)arg,
+ sizeof(request),
+ -EFAULT);
+
+ if (!request.device_name) return -ENOENT;
+ if (!request.device_busid) return -ENOENT;
+ retcode = strncpy_from_user(name,
+ request.device_name,
+ DRM_MAX_NAMELEN+1);
+ if (retcode < 0) return retcode;
+ if (!retcode) return -ENOENT;
+ if (retcode > DRM_MAX_NAMELEN) return -ENAMETOOLONG;
+
+ retcode = strncpy_from_user(busid,
+ request.device_busid,
+ DRM_MAX_NAMELEN+1);
+ if (retcode < 0) return retcode;
+ if (!retcode) return -ENOENT;
+ if (retcode > DRM_MAX_NAMELEN) return -ENAMETOOLONG;
+
+ name[DRM_MAX_NAMELEN] = '\0';
+ busid[DRM_MAX_NAMELEN] = '\0';
+
+ DRM_TRACE("%s %s\n", name, busid);
+
+ retcode = drm_register_device(name, busid, 0);
+ if (retcode < 0) return retcode;
+ request.device_major = drm_major;
+ request.device_minor = retcode;
+
+ copy_to_user_ret((drm_request_t *)arg,
+ &request,
+ sizeof(request),
+ -EFAULT);
+
+ return 0;
+}
+
+int drm_destroy DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_request_t request;
+ char busid[DRM_MAX_NAMELEN+2];
+ int retcode = 0;
+
+ copy_from_user_ret(&request,
+ (drm_request_t *)arg,
+ sizeof(request),
+ -EFAULT);
+
+ if (!request.device_busid) return -ENOENT;
+
+ retcode = strncpy_from_user(busid,
+ request.device_busid,
+ DRM_MAX_NAMELEN+1);
+ if (retcode < 0) return retcode;
+ if (!retcode) return -ENOENT;
+ if (retcode > DRM_MAX_NAMELEN) return -ENAMETOOLONG;
+
+ busid[DRM_MAX_NAMELEN] = '\0';
+
+ DRM_TRACE("%s (%d,%d)\n",
+ busid, request.device_major, request.device_minor);
+
+ if (request.device_major != drm_major) return -ENOENT;
+
+ if (strcmp(dev->busid, busid)) {
+ DRM_DEBUG("busid = %s != %s\n", dev->busid, busid);
+ retcode = -ENOENT; /* Busid mismatch */
+ }
+ return drm_unregister_device(request.device_minor);
+}
+
+int drm_irq_busid DRM_IOCTL_ARGS
+{
+ drm_irq_busid_t p;
+ struct pci_dev *dev;
+
+ copy_from_user_ret(&p, (drm_irq_busid_t *)arg, sizeof(p), -EFAULT);
+ dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum));
+ if (dev) p.irq = dev->irq;
+ else p.irq = 0;
+ DRM_TRACE("%d:%d:%d => IRQ %d\n",
+ p.busnum, p.devnum, p.funcnum, p.irq);
+ copy_to_user_ret((drm_irq_busid_t *)arg, &p, sizeof(p), -EFAULT);
+ return 0;
+}
+
+
+/* drm_ioctl is called whenever a process performs an ioctl on /dev/drm. */
+
+int drm_ioctl DRM_IOCTL_ARGS
+{
+ int nr = DRM_IOCTL_NR(cmd);
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_driver_t *drv = dev->driver;
+ int retcode = 0;
+ drm_ioctl_desc_t *ioctl;
+ drm_ioctl_t *func;
+
+ atomic_inc(&dev->ioctl_count);
+ atomic_inc(&dev->total_ioctl);
+ ++priv->ioctl_count;
+
+ DRM_TRACE("cmd = 0x%02x, nr = 0x%02x, dev (%d,%d), auth = %d\n",
+ cmd, nr, MAJOR(inode->i_rdev), dev->device_minor,
+ priv->auth);
+
+ if (priv->auth && cmd != DRM_IOCTL_GET_MAGIC) {
+ retcode = -EACCES;
+ } else if (nr >= drv->ioctl_count) {
+ retcode = -EINVAL;
+ } else {
+ ioctl = &drv->ioctls[nr];
+ func = ioctl->func;
+
+ if (!func) {
+ retcode = -EINVAL;
+ } else if (ioctl->root_only && !capable(CAP_SYS_ADMIN)) {
+ retcode = -EACCES;
+ } else {
+ retcode = (func)(inode, filp, cmd, arg);
+ }
+ }
+
+ atomic_dec(&dev->ioctl_count);
+ return retcode;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_mem.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_mem.c
new file mode 100644
index 000000000..e394e72b6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_mem.c
@@ -0,0 +1,271 @@
+/* drm_mem.c --
+ * Created: Thu Feb 4 14:00:34 1999 by faith@precisioninsight.com
+ * Revised: Fri Jun 18 10:27:56 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_mem.c,v 1.15 1999/06/21 14:25:37 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_mem.c,v 1.2 1999/06/27 14:08:25 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+#define FUDGE 0 /* For debugging (0 for production code) */
+
+void *drm_alloc(size_t size, int area)
+{
+ void *pt;
+
+ if (!size) {
+ DRM_MEM_ERROR(area, "Allocating 0 bytes\n");
+ return NULL;
+ }
+
+ spin_lock(&drm_mem_lock);
+
+ if (!(pt = kmalloc(size + FUDGE, GFP_KERNEL))) {
+ ++drm_mem_stats[area].fail_count;
+ spin_unlock(&drm_mem_lock);
+ return NULL;
+ }
+ ++drm_mem_stats[area].succeed_count;
+ drm_mem_stats[area].bytes_allocated += size;
+ spin_unlock(&drm_mem_lock);
+
+ DRM_MEM_VERB(area, "alloc(%d) = %p\n", size, pt);
+ return pt;
+}
+
+void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
+{
+ void *pt;
+
+ if (!(pt = drm_alloc(size, area))) return NULL;
+ if (oldpt && oldsize) {
+ memcpy(pt, oldpt, oldsize);
+ drm_free(oldpt, oldsize, area);
+ }
+ return pt;
+}
+
+char *drm_strdup(const char *s, int area)
+{
+ char *pt;
+ int length = s ? strlen(s) : 0;
+
+ if (!(pt = drm_alloc(length+1, area))) return NULL;
+ strcpy(pt, s);
+ return pt;
+}
+
+void drm_strfree(const char *s, int area)
+{
+ unsigned int size;
+
+ if (!s) return;
+
+ size = 1 + (s ? strlen(s) : 0);
+ drm_free((void *)s, size, area);
+}
+
+void drm_free(void *pt, size_t size, int area)
+{
+ int alloc_count;
+ int free_count;
+
+ DRM_MEM_VERB(area, "free(0x%p)\n", pt);
+ if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
+ else kfree_s(pt, size);
+ spin_lock(&drm_mem_lock);
+ drm_mem_stats[area].bytes_freed += size;
+ free_count = ++drm_mem_stats[area].free_count;
+ alloc_count = drm_mem_stats[area].succeed_count;
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+ spin_unlock(&drm_mem_lock);
+}
+
+unsigned long drm_alloc_dma(int order)
+{
+ unsigned long address;
+ unsigned long bytes = PAGE_SIZE << order;
+ unsigned long addr;
+ unsigned int sz;
+
+ spin_lock(&drm_mem_lock);
+ if (drm_ram_used > +(DRM_RAM_PERCENT * drm_ram_available) / 100) {
+ spin_unlock(&drm_mem_lock);
+ return 0;
+ }
+ address = __get_free_pages(GFP_KERNEL, order);
+ if (!address) {
+ ++drm_mem_stats[DRM_MEM_DMA].fail_count;
+ spin_unlock(&drm_mem_lock);
+ return 0;
+ }
+ ++drm_mem_stats[DRM_MEM_DMA].succeed_count;
+ drm_mem_stats[DRM_MEM_DMA].bytes_allocated += bytes;
+ drm_ram_used += bytes;
+ spin_unlock(&drm_mem_lock);
+
+
+ /* Zero outside the lock */
+ memset((void *)address, 0, bytes);
+
+ /* Reserve */
+ for (addr = address, sz = bytes;
+ sz > 0;
+ addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+ mem_map_reserve(MAP_NR(addr));
+ }
+
+ DRM_MEM_VERB(DRM_MEM_DMA, "alloc(2^%d) = %lu\n", order, address);
+ return address;
+}
+
+void drm_free_dma(unsigned long address, int order)
+{
+ unsigned long bytes = PAGE_SIZE << order;
+ int alloc_count;
+ int free_count;
+ unsigned long addr;
+ unsigned int sz;
+
+ DRM_MEM_VERB(DRM_MEM_DMA, "free(0x%08lx, %d)\n", address, order);
+ if (!address) {
+ DRM_MEM_ERROR(DRM_MEM_DMA, "Attempt to free address 0\n");
+ } else {
+ /* Unreserve */
+ for (addr = address, sz = bytes;
+ sz > 0;
+ addr += PAGE_SIZE, sz -= PAGE_SIZE) {
+ mem_map_unreserve(MAP_NR(addr));
+ }
+ free_pages(address, order);
+ }
+
+ spin_lock(&drm_mem_lock);
+ free_count = ++drm_mem_stats[DRM_MEM_DMA].free_count;
+ alloc_count = drm_mem_stats[DRM_MEM_DMA].succeed_count;
+ drm_mem_stats[DRM_MEM_DMA].bytes_freed += bytes;
+ drm_ram_used -= bytes;
+ spin_unlock(&drm_mem_lock);
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(DRM_MEM_DMA, "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+}
+
+void *drm_vmalloc(unsigned int size)
+{
+ void *pt;
+
+ if (!size) {
+ DRM_MEM_ERROR(DRM_MEM_SAREA, "Allocating 0 bytes in kernel-virtual\n");
+ return NULL;
+ }
+
+ spin_lock(&drm_mem_lock);
+ if (!(pt = vmalloc(size))) {
+ ++drm_mem_stats[DRM_MEM_SAREA].fail_count;
+ spin_unlock(&drm_mem_lock);
+ return NULL;
+ }
+ ++drm_mem_stats[DRM_MEM_SAREA].succeed_count;
+ drm_mem_stats[DRM_MEM_SAREA].bytes_allocated += size;
+ spin_unlock(&drm_mem_lock);
+
+ /* Zero outside the lock */
+ memset(pt, 0, size);
+ DRM_MEM_VERB(DRM_MEM_SAREA, "alloc(%u) = %p\n", size, pt);
+ return pt;
+}
+
+void drm_vfree(void *pt, unsigned int size)
+{
+ int alloc_count;
+ int free_count;
+
+ DRM_MEM_VERB(DRM_MEM_SAREA, "free(0x%p)\n", pt);
+ if (!pt) {
+ DRM_MEM_ERROR(DRM_MEM_SAREA, "Attempt to free NULL pointer\n");
+ } else {
+ vfree(pt);
+ }
+
+ spin_lock(&drm_mem_lock);
+ drm_mem_stats[DRM_MEM_SAREA].bytes_freed += size;
+ free_count = ++drm_mem_stats[DRM_MEM_SAREA].free_count;
+ alloc_count = drm_mem_stats[DRM_MEM_SAREA].succeed_count;
+ spin_unlock(&drm_mem_lock);
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(DRM_MEM_SAREA, "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+}
+
+void *drm_ioremap(unsigned long offset, unsigned long size)
+{
+ void *pt;
+
+ if (!size) {
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+ "Mapping 0 bytes at 0x%08lx\n", offset);
+ return NULL;
+ }
+
+ spin_lock(&drm_mem_lock);
+ if (!(pt = ioremap(offset, size))) {
+ ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count;
+ spin_unlock(&drm_mem_lock);
+ return NULL;
+ }
+ ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
+ drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size;
+ spin_unlock(&drm_mem_lock);
+ DRM_MEM_VERB(DRM_MEM_MAPPINGS, "map(%lu,%lu) = %p\n", offset, size, pt);
+ return pt;
+}
+
+void drm_ioremapfree(void *pt, unsigned long size)
+{
+ int alloc_count;
+ int free_count;
+
+ DRM_MEM_VERB(DRM_MEM_MAPPINGS, "free(0x%p)\n", pt);
+ if (!pt) DRM_MEM_ERROR(DRM_MEM_MAPPINGS, "Attempt to free NULL pointer\n");
+ else iounmap(pt);
+ spin_lock(&drm_mem_lock);
+ drm_mem_stats[DRM_MEM_MAPPINGS].bytes_freed += size;
+ free_count = ++drm_mem_stats[DRM_MEM_MAPPINGS].free_count;
+ alloc_count = drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
+ spin_unlock(&drm_mem_lock);
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS, "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_proc.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_proc.c
new file mode 100644
index 000000000..d95ec1907
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_proc.c
@@ -0,0 +1,727 @@
+/* drm_proc.c -- /proc support for DRM -*- linux-c -*-
+ * Created: Mon Jan 11 09:48:47 1999 by faith@precisioninsight.com
+ * Revised: Wed Jun 23 09:04:32 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_proc.c,v 1.31 1999/06/23 13:04:58 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_proc.c,v 1.2 1999/06/27 14:08:25 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+static struct proc_dir_entry *drm_root = NULL;
+
+#define DRM_PROC_LIMIT (PAGE_SIZE-80)
+
+#define DRM_PROC_PRINT(fmt, arg...) \
+ len += sprintf(&buf[len], fmt , ##arg); \
+ if (len > DRM_PROC_LIMIT) return len;
+
+#define DRM_PROC_PRINT_RET(ret, fmt, arg...) \
+ len += sprintf(&buf[len], fmt , ##arg); \
+ if (len > DRM_PROC_LIMIT) { ret; return len; }
+
+/* drm_proc_init is called from drm_init at module initialization time. */
+
+int drm_proc_init(void)
+{
+ struct proc_dir_entry *ent;
+
+ drm_root = create_proc_entry(DRM_NAME, S_IFDIR, NULL);
+ if (!drm_root) {
+ DRM_ERROR("Cannot create /proc/%s entry\n", DRM_NAME);
+ return -1;
+ }
+
+ ent = create_proc_entry(DRM_DRIVERS, S_IFREG|S_IRUGO, drm_root);
+ if (!ent) {
+ DRM_ERROR("Cannot create /proc/%s/%s entry\n",
+ DRM_NAME, DRM_DRIVERS);
+ remove_proc_entry(DRM_NAME, NULL);
+ return -1;
+ }
+ ent->read_proc = drm_driver_info;
+
+ ent = create_proc_entry(DRM_DEVICES, S_IFREG|S_IRUGO, drm_root);
+ if (!ent) {
+ DRM_ERROR("Cannot create /proc/%s/%s entry\n",
+ DRM_NAME, DRM_DEVICES);
+ remove_proc_entry(DRM_DRIVERS, drm_root);
+ remove_proc_entry(DRM_NAME, NULL);
+ return -1;
+ }
+ ent->read_proc = drm_device_info;
+
+ ent = create_proc_entry(DRM_MEM, S_IFREG|S_IRUGO, drm_root);
+ if (!ent) {
+ DRM_ERROR("Cannot create /proc/%s/%s entry\n",
+ DRM_NAME, DRM_MEM);
+ remove_proc_entry(DRM_DEVICES, drm_root);
+ remove_proc_entry(DRM_DRIVERS, drm_root);
+ remove_proc_entry(DRM_NAME, NULL);
+ return -1;
+ }
+ ent->read_proc = drm_mem_info;
+
+ ent = create_proc_entry(DRM_CLIENTS, S_IFREG|S_IRUGO, drm_root);
+ if (!ent) {
+ DRM_ERROR("Cannot create /proc/%s/%s entry\n",
+ DRM_NAME, DRM_CLIENTS);
+ remove_proc_entry(DRM_MEM, drm_root);
+ remove_proc_entry(DRM_DEVICES, drm_root);
+ remove_proc_entry(DRM_DRIVERS, drm_root);
+ remove_proc_entry(DRM_NAME, NULL);
+ return -1;
+ }
+ ent->read_proc = drm_clients_info;
+
+ return 0;
+}
+
+/* drm_proc_add_device is called from drm_register_device. */
+
+int drm_proc_add_device(drm_device_t *dev)
+{
+ char buf[32];
+ struct proc_dir_entry *ent;
+
+ sprintf(buf, "%d", dev->device_minor);
+ dev->root = create_proc_entry(buf, S_IFDIR, drm_root);
+ if (!dev->root) {
+ DRM_ERROR("Cannot create /proc/%s/%s entry\n",
+ DRM_NAME, buf);
+ return -1;
+ }
+
+ ent = create_proc_entry(DRM_MEMINFO, S_IFREG|S_IRUGO, dev->root);
+ if (!ent) {
+ DRM_ERROR("Cannot create /proc/%s/%s/%s entry\n",
+ DRM_NAME, buf, DRM_MEMINFO);
+ remove_proc_entry(buf, dev->root);
+ dev->root = NULL;
+ return -1;
+ }
+ ent->read_proc = drm_meminfo_info;
+ ent->data = dev;
+
+ ent = create_proc_entry(DRM_QUEUES, S_IFREG|S_IRUGO, dev->root);
+ if (!ent) {
+ DRM_ERROR("Cannot create /proc/%s/%s/%s entry\n",
+ DRM_NAME, buf, DRM_QUEUES);
+ remove_proc_entry(buf, dev->root);
+ dev->root = NULL;
+ return -1;
+ }
+ ent->read_proc = drm_queues_info;
+ ent->data = dev;
+
+ ent = create_proc_entry(DRM_BUFS, S_IFREG|S_IRUGO, dev->root);
+ if (!ent) {
+ DRM_ERROR("Cannot create /proc/%s/%s/%s entry\n",
+ DRM_NAME, buf, DRM_BUFS);
+ remove_proc_entry(buf, dev->root);
+ dev->root = NULL;
+ return -1;
+ }
+ ent->read_proc = drm_bufs_info;
+ ent->data = dev;
+
+#if DRM_DEBUG_CODE
+ ent = create_proc_entry(DRM_VMAINFO, S_IFREG|S_IRUGO, dev->root);
+ if (!ent) {
+ DRM_ERROR("Cannot create /proc/%s/%s/%s entry\n",
+ DRM_NAME, buf, DRM_VMAINFO);
+ remove_proc_entry(buf, dev->root);
+ dev->root = NULL;
+ return -1;
+ }
+ ent->read_proc = drm_vmainfo_info;
+ ent->data = dev;
+#endif
+
+#if DRM_DMA_HISTOGRAM
+ ent = create_proc_entry(DRM_HISTO, S_IFREG|S_IRUGO, dev->root);
+ if (!ent) {
+ DRM_ERROR("Cannot create /proc/%s/%s/%s entry\n",
+ DRM_NAME, buf, DRM_HISTO);
+ remove_proc_entry(buf, dev->root);
+ dev->root = NULL;
+ return -1;
+ }
+ ent->read_proc = drm_histo_info;
+ ent->data = dev;
+#endif
+
+ return 0;
+}
+
+/* drm_proc_del_device is called from drm_unregister_device. */
+
+int drm_proc_del_device(drm_device_t *dev)
+{
+ char buf[32];
+
+ if (dev->root && drm_root) {
+#if DRM_DMA_HISTOGRAM
+ remove_proc_entry(DRM_HISTO, dev->root);
+#endif
+#if DRM_DEBUG_CODE
+ remove_proc_entry(DRM_VMAINFO, dev->root);
+#endif
+ remove_proc_entry(DRM_BUFS, dev->root);
+ remove_proc_entry(DRM_QUEUES, dev->root);
+ remove_proc_entry(DRM_MEMINFO, dev->root);
+ sprintf(buf, "%d", dev->device_minor);
+ remove_proc_entry(buf, drm_root);
+ dev->root = NULL;
+ }
+ return 0;
+}
+
+/* drm_proc_cleanup is called from drm_cleanup at module cleanup time. */
+
+int drm_proc_cleanup(void)
+{
+ if (drm_root) {
+ remove_proc_entry(DRM_CLIENTS, drm_root);
+ remove_proc_entry(DRM_MEM, drm_root);
+ remove_proc_entry(DRM_DRIVERS, drm_root);
+ remove_proc_entry(DRM_DEVICES, drm_root);
+ remove_proc_entry(DRM_NAME, NULL);
+ }
+ drm_root = NULL;
+
+ return 0;
+}
+
+/* drm_driver_info is called whenever a process reads /dev/drm/drivers. */
+
+static int _drm_driver_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_driver_t *pt;
+
+ if (offset > 0) return 0; /* no partial requests */
+ len = 0;
+ *eof = 1;
+
+ DRM_PROC_PRINT("b name major minor patch date desc\n\n");
+ for (pt = drm_drivers; pt; pt = pt->next) {
+ DRM_PROC_PRINT("%c %-10s %5d %5d %5d \"%s\" \"%s\"\n",
+ pt->base ? '*' : ' ',
+ pt->name ?: "?",
+ pt->version->version_major,
+ pt->version->version_minor,
+ pt->version->version_patchlevel,
+ pt->version->date ?: "",
+ pt->version->desc ?: "");
+ }
+
+ return len;
+}
+
+int drm_driver_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ int ret;
+
+ spin_lock(&drm_meta_lock);
+ ret = _drm_driver_info(buf, start, offset, len, eof, data);
+ spin_unlock(&drm_meta_lock);
+ return ret;
+}
+
+/* drm_device_info is called whenever a process reads /dev/drm/devices.
+ This doesn't need a lock because .inuse is checked. */
+
+int drm_device_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ int i;
+
+ if (offset > 0) return 0; /* no partial requests */
+ len = 0;
+ *eof = 1;
+
+ for (i = 0; i < DRM_MAX_DEVICES; i++) {
+ if (!drm_devices[i].inuse) continue;
+ DRM_PROC_PRINT("%3d %s %s\n",
+ i,
+ drm_devices[i].driver->name,
+ drm_devices[i].busid);
+ }
+
+ return len;
+}
+
+/* drm_mem_info is called whenever a process reads /dev/drm/mem. */
+
+static int _drm_mem_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_mem_stats_t *pt;
+
+ if (offset > 0) return 0; /* no partial requests */
+ len = 0;
+ *eof = 1;
+ DRM_PROC_PRINT(" total counts "
+ " | outstanding \n");
+ DRM_PROC_PRINT("type alloc freed fail bytes freed"
+ " | allocs bytes\n\n");
+ DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu |\n",
+ "system", 0, 0, 0, drm_ram_available);
+ DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu |\n",
+ "locked", 0, 0, 0, drm_ram_used);
+ DRM_PROC_PRINT("\n");
+ for (pt = drm_mem_stats; pt->name; pt++) {
+ DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
+ pt->name,
+ pt->succeed_count,
+ pt->free_count,
+ pt->fail_count,
+ pt->bytes_allocated,
+ pt->bytes_freed,
+ pt->succeed_count - pt->free_count,
+ (long)pt->bytes_allocated
+ - (long)pt->bytes_freed);
+ }
+
+ return len;
+}
+
+int drm_mem_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ int ret;
+
+ spin_lock(&drm_mem_lock);
+ ret = _drm_mem_info(buf, start, offset, len, eof, data);
+ spin_unlock(&drm_mem_lock);
+ return ret;
+}
+
+/* drm_meminfo_info is called whenever a process reads
+ /dev/drm/<dev>/meminfo. */
+
+int _drm_meminfo_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ drm_map_t *map;
+ const char *types[] = { "FB", "REG", "SHM" };
+ const char *type;
+ int i;
+
+ if (offset > 0) return 0; /* no partial requests */
+ len = 0;
+ *eof = 1;
+ DRM_PROC_PRINT("vma use count: %d\n", dev->vma_count.counter);
+ DRM_PROC_PRINT("kB used for dma buffers: %lu\n",
+ dev->byte_count / 1024);
+ for (i = 0; i < DRM_MAX_ORDER+1; i++) {
+ if (dev->bufs[i].seg_count) {
+ DRM_PROC_PRINT("order: %2d; size: %6d;"
+ " bufs: %4d; segs: %4d;"
+ " pages: %4d; kB: %4lu\n",
+ i,
+ dev->bufs[i].buf_size,
+ dev->bufs[i].buf_count,
+ dev->bufs[i].seg_count,
+ dev->bufs[i].seg_count
+ *(1 << dev->bufs[i].page_order),
+ (dev->bufs[i].seg_count
+ * (1 << dev->bufs[i].page_order))
+ * PAGE_SIZE / 1024);
+ }
+ }
+ DRM_PROC_PRINT("\nslot offset size type flags "
+ "address mtrr\n\n");
+ for (i = 0; i < dev->map_count; i++) {
+ map = dev->maplist[i];
+ if (map->type < 0 || map->type > 2) type = "??";
+ else type = types[map->type];
+ DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
+ i,
+ map->offset,
+ map->size,
+ type,
+ map->flags,
+ (unsigned long)map->handle);
+ if (map->mtrr < 0) {
+ DRM_PROC_PRINT("none\n");
+ } else {
+ DRM_PROC_PRINT("%4d\n", map->mtrr);
+ }
+ }
+
+ return len;
+}
+
+int drm_meminfo_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ int ret;
+
+ spin_lock(&dev->struct_lock);
+ ret = _drm_meminfo_info(buf, start, offset, len, eof, data);
+ spin_unlock(&dev->struct_lock);
+ return ret;
+}
+
+/* drm_queues_info is called whenever a process reads
+ /dev/drm/<dev>/queues. */
+
+int drm_queues_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ int i;
+ drm_queue_t *q;
+
+ if (offset > 0) return 0; /* no partial requests */
+ len = 0;
+ *eof = 1;
+ DRM_PROC_PRINT(" ctx/flags use fin"
+ " blk/rw/rwf wait flushed queued"
+ " locks\n\n");
+ for (i = 0; i < dev->queue_count; i++) {
+ q = dev->queuelist[i];
+ atomic_inc(&q->use_count);
+ DRM_PROC_PRINT_RET(atomic_dec(&q->use_count),
+ "%5d/0x%03x %5d %5d"
+ " %5d/%c%c/%c%c%c %5d %10d %10d %10d\n",
+ i,
+ q->flags,
+ atomic_read(&q->use_count),
+ atomic_read(&q->finalization),
+ atomic_read(&q->block_count),
+ atomic_read(&q->block_read) ? 'r' : '-',
+ atomic_read(&q->block_write) ? 'w' : '-',
+ waitqueue_active(&q->read_queue) ? 'r':'-',
+ waitqueue_active(&q->write_queue) ? 'w':'-',
+ waitqueue_active(&q->flush_queue) ? 'f':'-',
+ DRM_BUFCOUNT(&q->waitlist),
+ atomic_read(&q->total_flushed),
+ atomic_read(&q->total_queued),
+ atomic_read(&q->total_locks));
+ atomic_dec(&q->use_count);
+ }
+
+ return len;
+}
+
+/* drm_bufs_info is called whenever a process reads
+ /dev/drm/<dev>/bufs. */
+
+static int _drm_bufs_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ int i;
+
+ if (offset > 0) return 0; /* no partial requests */
+ len = 0;
+ *eof = 1;
+ DRM_PROC_PRINT(" o size count free\n\n");
+ for (i = 0; i <= DRM_MAX_ORDER; i++) {
+ if (dev->bufs[i].buf_count)
+ DRM_PROC_PRINT("%2d %8d %5d %5d\n",
+ i,
+ dev->bufs[i].buf_size,
+ dev->bufs[i].buf_count,
+ atomic_read(&dev->bufs[i]
+ .freelist.count));
+ }
+ DRM_PROC_PRINT("\n");
+ for (i = 0; i < dev->buf_count; i++) {
+ if (i && !(i%32)) DRM_PROC_PRINT("\n");
+ DRM_PROC_PRINT(" %d", dev->buflist[i]->list);
+ }
+ DRM_PROC_PRINT("\n");
+
+ return len;
+}
+
+int drm_bufs_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ int ret;
+
+ spin_lock(&dev->struct_lock);
+ ret = _drm_bufs_info(buf, start, offset, len, eof, data);
+ spin_unlock(&dev->struct_lock);
+ return ret;
+}
+
+/* drm_clients_info is called whenever a process reads
+ /dev/drm/<dev>/clients. */
+
+static int _drm_clients_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_file_t *priv;
+ const char auths[] = { 'a', 'p', 'u' };
+
+ if (offset > 0) return 0; /* no partial requests */
+ len = 0;
+ *eof = 1;
+ DRM_PROC_PRINT("a dev pid uid magic ioctls\n\n");
+ for (priv = drm_file_first; priv; priv = priv->next) {
+ DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
+ priv->auth > 2 ? '?' : auths[priv->auth],
+ priv->minor,
+ priv->pid,
+ priv->uid,
+ priv->magic,
+ priv->ioctl_count);
+ }
+
+ return len;
+}
+
+int drm_clients_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ int ret;
+
+ spin_lock(&drm_meta_lock);
+ ret = _drm_clients_info(buf, start, offset, len, eof, data);
+ spin_unlock(&drm_meta_lock);
+ return ret;
+}
+
+#if DRM_DEBUG_CODE
+/* drm_vmainfo_info is called whenever a process reads
+ /dev/drm/<dev>/vmainfo. */
+
+static int _drm_vmainfo_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ drm_vma_entry_t *pt;
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *pte;
+ unsigned long i;
+ struct vm_area_struct *vma;
+ unsigned long address;
+#if defined(__i386__)
+ unsigned int pgprot;
+#endif
+
+ if (offset > 0) return 0; /* no partial requests */
+ len = 0;
+ *eof = 1;
+ DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
+ atomic_read(&dev->vma_count),
+ high_memory, virt_to_phys(high_memory));
+ for (pt = dev->vmalist; pt; pt = pt->next) {
+ if (!(vma = pt->vma)) continue;
+ DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
+ pt->pid,
+ vma->vm_start,
+ vma->vm_end,
+ vma->vm_flags & VM_READ ? 'r' : '-',
+ vma->vm_flags & VM_WRITE ? 'w' : '-',
+ vma->vm_flags & VM_EXEC ? 'x' : '-',
+ vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
+ vma->vm_flags & VM_LOCKED ? 'l' : '-',
+ vma->vm_flags & VM_IO ? 'i' : '-',
+ vma->vm_offset );
+#if defined(__i386__)
+ pgprot = pgprot_val(vma->vm_page_prot);
+ DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
+ pgprot & _PAGE_PRESENT ? 'p' : '-',
+ pgprot & _PAGE_RW ? 'w' : 'r',
+ pgprot & _PAGE_USER ? 'u' : 's',
+ pgprot & _PAGE_PWT ? 't' : 'b',
+ pgprot & _PAGE_PCD ? 'u' : 'c',
+ pgprot & _PAGE_ACCESSED ? 'a' : '-',
+ pgprot & _PAGE_DIRTY ? 'd' : '-',
+ pgprot & _PAGE_4M ? 'm' : 'k',
+ pgprot & _PAGE_GLOBAL ? 'g' : 'l' );
+#endif
+ DRM_PROC_PRINT("\n");
+ for (i = vma->vm_start; i < vma->vm_end; i += PAGE_SIZE) {
+ pgd = pgd_offset(vma->vm_mm, i);
+ pmd = pmd_offset(pgd, i);
+ pte = pte_offset(pmd, i);
+ if (pte_present(*pte)) {
+ address = __pa(pte_page(*pte))
+ + (i & (PAGE_SIZE-1));
+ DRM_PROC_PRINT(" 0x%08lx -> 0x%08lx"
+ " %c%c%c%c%c\n",
+ i,
+ address,
+ pte_read(*pte) ? 'r' : '-',
+ pte_write(*pte) ? 'w' : '-',
+ pte_exec(*pte) ? 'x' : '-',
+ pte_dirty(*pte) ? 'd' : '-',
+ pte_young(*pte) ? 'a' : '-' );
+ } else {
+ DRM_PROC_PRINT(" 0x%08lx\n", i);
+ }
+ }
+ }
+
+ return len;
+}
+
+int drm_vmainfo_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ int ret;
+
+ spin_lock(&dev->struct_lock);
+ ret = _drm_vmainfo_info(buf, start, offset, len, eof, data);
+ spin_unlock(&dev->struct_lock);
+ return ret;
+}
+#endif
+
+
+#if DRM_DMA_HISTOGRAM
+static int _drm_histo_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ int i;
+ unsigned long slot_value = DRM_DMA_HISTOGRAM_INITIAL;
+ unsigned long prev_value = 0;
+ drm_buf_t *buffer;
+
+ if (offset > 0) return 0; /* no partial requests */
+ len = 0;
+ *eof = 1;
+
+ DRM_PROC_PRINT("total %10u\n", atomic_read(&dev->histo.total));
+ DRM_PROC_PRINT("open %10u\n", atomic_read(&dev->total_open));
+ DRM_PROC_PRINT("close %10u\n", atomic_read(&dev->total_close));
+ DRM_PROC_PRINT("ioctl %10u\n", atomic_read(&dev->total_ioctl));
+ DRM_PROC_PRINT("irq %10u\n", atomic_read(&dev->total_irq));
+ DRM_PROC_PRINT("prio %10u\n", atomic_read(&dev->total_prio));
+ DRM_PROC_PRINT("ctx %10u\n", atomic_read(&dev->total_ctx));
+ DRM_PROC_PRINT("bytes %10u\n", atomic_read(&dev->total_bytes));
+ DRM_PROC_PRINT("dmas %10u\n", atomic_read(&dev->total_dmas));
+
+ DRM_PROC_PRINT("\nmissed:\n");
+ DRM_PROC_PRINT(" dma %10u\n", atomic_read(&dev->total_missed_dma));
+ DRM_PROC_PRINT(" lock %10u\n", atomic_read(&dev->total_missed_lock));
+ DRM_PROC_PRINT(" free %10u\n", atomic_read(&dev->total_missed_free));
+ DRM_PROC_PRINT(" sched %10u\n", atomic_read(&dev->total_missed_sched));
+
+ DRM_PROC_PRINT("tried %10u\n", atomic_read(&dev->total_tried));
+ DRM_PROC_PRINT("hit %10u\n", atomic_read(&dev->total_hit));
+ DRM_PROC_PRINT("lost %10u\n", atomic_read(&dev->total_lost));
+
+ DRM_PROC_PRINT("\nlock statistics:\n");
+ DRM_PROC_PRINT("locks %10u\n", atomic_read(&dev->total_locks));
+ DRM_PROC_PRINT("unlocks %10u\n", atomic_read(&dev->total_unlocks));
+ DRM_PROC_PRINT("contends %10u\n", atomic_read(&dev->total_contends));
+ DRM_PROC_PRINT("sleeps %10u\n", atomic_read(&dev->total_sleeps));
+
+
+ if (!dev->device_minor) return len;
+
+ DRM_PROC_PRINT("\n");
+ DRM_PROC_PRINT("lock 0x%08x\n", dev->lock.hw_lock->lock);
+ DRM_PROC_PRINT("context_flag 0x%08x\n", dev->context_flag);
+ DRM_PROC_PRINT("interrupt_flag 0x%08x\n", dev->interrupt_flag);
+ DRM_PROC_PRINT("dma_flag 0x%08x\n", dev->dma_flag);
+
+ buffer = dev->next_buffer;
+ if (buffer) {
+ DRM_PROC_PRINT("next_buffer %10d\n", buffer->idx);
+ } else {
+ DRM_PROC_PRINT("next_buffer none\n");
+ }
+ buffer = dev->this_buffer;
+ if (buffer) {
+ DRM_PROC_PRINT("this_buffer %10d\n", buffer->idx);
+ } else {
+ DRM_PROC_PRINT("this_buffer none\n");
+ }
+
+
+ DRM_PROC_PRINT("queue_count %10d\n", dev->queue_count);
+ DRM_PROC_PRINT("last_context %10d\n", dev->last_context);
+ DRM_PROC_PRINT("last_switch %10lu\n", dev->last_switch);
+ DRM_PROC_PRINT("last_checked %10d\n", dev->last_checked);
+
+
+ DRM_PROC_PRINT("\n q2d d2c c2f"
+ " q2c q2f dma sch"
+ " ctx lacq lhld\n\n");
+ for (i = 0; i < DRM_DMA_HISTOGRAM_SLOTS; i++) {
+ DRM_PROC_PRINT("%s %10lu %10u %10u %10u %10u %10u"
+ " %10u %10u %10u %10u %10u\n",
+ i == DRM_DMA_HISTOGRAM_SLOTS - 1 ? ">=" : "< ",
+ i == DRM_DMA_HISTOGRAM_SLOTS - 1
+ ? prev_value : slot_value ,
+
+ atomic_read(&dev->histo
+ .queued_to_dispatched[i]),
+ atomic_read(&dev->histo
+ .dispatched_to_completed[i]),
+ atomic_read(&dev->histo
+ .completed_to_freed[i]),
+
+ atomic_read(&dev->histo
+ .queued_to_completed[i]),
+ atomic_read(&dev->histo
+ .queued_to_freed[i]),
+ atomic_read(&dev->histo.dma[i]),
+ atomic_read(&dev->histo.schedule[i]),
+ atomic_read(&dev->histo.ctx[i]),
+ atomic_read(&dev->histo.lacq[i]),
+ atomic_read(&dev->histo.lhld[i]));
+ prev_value = slot_value;
+ slot_value = DRM_DMA_HISTOGRAM_NEXT(slot_value);
+ }
+ return len;
+}
+
+int drm_histo_info(char *buf, char **start, off_t offset, int len,
+ int *eof, void *data)
+{
+ drm_device_t *dev = (drm_device_t *)data;
+ int ret;
+
+ /* This prevents the structure from being
+ deleted while we-re using it. All
+ updates to contents are already atomic,
+ so they don't need to be locked (i.e.,
+ we don't need locking in
+ drm_histogram_compute). */
+ spin_lock(&dev->struct_lock);
+ ret = _drm_histo_info(buf, start, offset, len, eof, data);
+ spin_unlock(&dev->struct_lock);
+ return ret;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_setup.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_setup.c
new file mode 100644
index 000000000..ccab8c261
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_setup.c
@@ -0,0 +1,1296 @@
+/* drm_setup.c -- Setup/Cleanup for DRM -*- linux-c -*-
+ * Created: Mon Jan 4 08:58:31 1999 by faith@precisioninsight.com
+ * Revised: Thu Jun 24 15:49:09 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_setup.c,v 1.52 1999/06/24 20:29:42 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_setup.c,v 1.2 1999/06/27 14:08:26 dawes Exp $
+ *
+ */
+
+#define EXPORT_SYMTAB
+#include "drmP.h"
+EXPORT_SYMBOL(drm_init);
+EXPORT_SYMBOL(drm_cleanup);
+EXPORT_SYMBOL(drm_register_driver);
+EXPORT_SYMBOL(drm_unregister_driver);
+
+#define DRM_DESC "DRM Driver Base"
+#define DRM_GEN_DESC "Generic DRM Driver"
+
+int drm_flags = 0;
+int drm_major = DRM_DEV_MAJOR;
+int drm_base_minor = 0;
+drm_driver_t *drm_drivers = NULL;
+drm_driver_t *drm_drivers_tail = NULL;
+drm_device_t drm_devices[DRM_MAX_DEVICES];
+spinlock_t drm_meta_lock = SPIN_LOCK_UNLOCKED;
+spinlock_t drm_mem_lock = SPIN_LOCK_UNLOCKED;
+drm_file_t *drm_file_first = NULL;
+drm_file_t *drm_file_last = NULL;
+unsigned long drm_ram_available = 0;
+unsigned long drm_ram_used = 0;
+
+drm_mem_stats_t drm_mem_stats[] = {
+ [DRM_MEM_DMA] = { "dmabufs" },
+ [DRM_MEM_SAREA] = { "sareas" },
+ [DRM_MEM_DRIVER] = { "driver" },
+ [DRM_MEM_MAGIC] = { "magic" },
+ [DRM_MEM_IOCTLS] = { "ioctltab" },
+ [DRM_MEM_MAPS] = { "maplist" },
+ [DRM_MEM_VMAS] = { "vmalist" },
+ [DRM_MEM_BUFS] = { "buflist" },
+ [DRM_MEM_SEGS] = { "seglist" },
+ [DRM_MEM_PAGES] = { "pagelist" },
+ [DRM_MEM_FILES] = { "files" },
+ [DRM_MEM_QUEUES] = { "queues" },
+ [DRM_MEM_CMDS] = { "commands" },
+ [DRM_MEM_MAPPINGS] = { "mappings" },
+ [DRM_MEM_BUFLISTS] = { "buflists" },
+ { NULL, 0, } /* Last entry must be null */
+};
+
+struct vm_operations_struct drm_vm_ops = {
+ nopage: drm_vm_nopage,
+ open: drm_vm_open,
+ close: drm_vm_close,
+};
+
+struct vm_operations_struct drm_vm_shm_ops = {
+ nopage: drm_vm_shm_nopage,
+ open: drm_vm_open,
+ close: drm_vm_close,
+};
+
+struct vm_operations_struct drm_vm_dma_ops = {
+ nopage: drm_vm_dma_nopage,
+ open: drm_vm_open,
+ close: drm_vm_close,
+};
+
+static struct file_operations drm_fops = {
+ open: drm_open,
+ flush: drm_flush,
+ release: drm_release,
+ ioctl: drm_ioctl,
+ mmap: drm_mmap,
+ read: drm_read,
+ fasync: drm_fasync,
+};
+
+static drm_version_t drm_base_version = {
+ DRM_MAJOR,
+ DRM_MINOR,
+ DRM_PATCHLEVEL,
+ sizeof(DRM_NAME),
+ (char *)DRM_NAME,
+ sizeof(DRM_DATE),
+ (char *)DRM_DATE,
+ sizeof(DRM_DESC),
+ (char *)DRM_DESC
+};
+
+ /* All of these values must be consecutive
+ small integers < DRM_BASE_IOCTL_COUNT. */
+static drm_ioctl_desc_t drm_base_ioctls[] = {
+ [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = {drm_version, 0, DRM_BASE},
+ [DRM_IOCTL_NR(DRM_IOCTL_LIST)] = {drm_list, 0, DRM_BASE},
+ [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = {drm_irq_busid, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_CREATE)] = {drm_create, 1,DRM_BASE|DRM_NOLOCK},
+ [DRM_IOCTL_NR(DRM_IOCTL_DESTROY)]= {drm_destroy,1,DRM_BASE|DRM_NOLOCK},
+};
+#define DRM_BASE_IOCTL_COUNT DRM_ARRAY_SIZE(drm_base_ioctls)
+
+static drm_version_t drm_gen_version = {
+ DRM_MAJOR,
+ DRM_MINOR,
+ DRM_PATCHLEVEL,
+ sizeof(DRM_GEN_NAME),
+ (char *)DRM_GEN_NAME,
+ sizeof(DRM_DATE),
+ (char *)DRM_DATE,
+ sizeof(DRM_GEN_DESC),
+ (char *)DRM_GEN_DESC
+};
+
+static drm_ioctl_desc_t drm_gen_ioctls[] = {
+ [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_block, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_CONTROL)] = { drm_control, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic,1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { drm_addbufs, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { drm_markbufs, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { drm_infobufs, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { drm_mapbufs, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { drm_freebufs, 0, 0 },
+
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { drm_addctx, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { drm_rmctx, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { drm_modctx, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { drm_getctx, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { drm_switchctx,1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { drm_newctx, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { drm_resctx, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { drm_dma, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { drm_lock, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { drm_unlock, 0, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 0, 0 },
+};
+#define DRM_GEN_IOCTL_COUNT DRM_ARRAY_SIZE(drm_gen_ioctls)
+
+static drm_func_desc_t drm_gen_funcs = {
+ reg: drm_reg,
+ unreg: drm_unreg,
+};
+
+
+#ifdef MODULE
+int init_module(void);
+void cleanup_module(void);
+static char *drm = NULL;
+
+MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas.");
+MODULE_DESCRIPTION("Direct Rendering Manager");
+MODULE_PARM(drm, "s");
+
+/* init_module is called when insmod is used to load the module */
+
+int init_module(void)
+{
+ return drm_init();
+}
+
+/* cleanup_module is called when rmmod is used to unload the module */
+
+void cleanup_module(void)
+{
+ drm_cleanup();
+}
+#endif
+
+/* drm_parse_option parses a single option. See description for
+ drm_parse_drm for details. */
+
+static void drm_parse_option(char *s)
+{
+ char *c, *r;
+
+ DRM_TRACE("\"%s\"\n", s);
+ if (!s || !*s) return;
+ for (c = s; *c && *c != ':'; c++); /* find : or \0 */
+ if (*c) r = c + 1; else r = NULL; /* remember remainder */
+ *c = '\0'; /* terminate */
+ if (!strcmp(s, "device")) {
+ for (c = r; c && *c && *c != ':'; c++); /* find : or \0 */
+ if (!c || !*c) {
+ DRM_ERROR("Usage: device:<major>\n");
+ return;
+ }
+ *c++ = '\0';
+ drm_major = simple_strtoul(r, NULL, 0);
+ DRM_DEBUG("Using device major %d\n", drm_major);
+ return;
+ }
+ if (!strcmp(s, "noctx")) {
+ drm_flags |= DRM_FLAG_NOCTX;
+ return;
+ }
+ if (!strcmp(s, "debug")) {
+ char *h, *t, *n;
+
+ if (!r) {
+ DRM_ERROR("Usage: debug:<flag>[:<flag>]*\n");
+ return;
+ }
+
+ for (h = t = n = r; h && *h; h = t = n) {
+ for (; *t && *t != ':'; t++); /* find : or \0 */
+ if (*t) n = t + 1; else n = NULL; /* remember next */
+ *t = '\0'; /* terminate */
+ if (!strcmp(h, "on")) {
+ drm_flags |= DRM_FLAG_DEBUG;
+ continue;
+ }
+ if (!strcmp(h, "off")) {
+ drm_flags = 0;
+ continue;
+ }
+ if (!strcmp(h, "trace")) {
+ drm_flags |= DRM_FLAG_TRACE;
+ continue;
+ }
+ if (!strcmp(h, "verb")) {
+ drm_flags |= DRM_FLAG_VERB;
+ continue;
+ }
+ if (!strcmp(h, "mem")) {
+ drm_flags |= DRM_FLAG_MEM;
+ continue;
+ }
+ if (!strcmp(h, "lock")) {
+ drm_flags |= DRM_FLAG_LOCK;
+ continue;
+ }
+ if (!strcmp(h, "all")) {
+ drm_flags |= ~0;
+ continue;
+ }
+ DRM_ERROR("\"%s\" is not a valid debug flag\n", h);
+ }
+ DRM_DEBUG("Debug mask = 0x%08x\n", drm_flags);
+ return;
+ }
+ DRM_ERROR("\"%s\" is not a valid option\n", s);
+ return;
+}
+
+/* drm_parse_drm parse the insmod "drm=" options, or the command-line
+ * options passed to the kernel via LILO. The grammar of the format is as
+ * follows:
+ *
+ * drm ::= 'drm=' option_list
+ * option_list ::= option [ ';' option_list ]
+ * option ::= 'device:' major
+ * | 'debug:' debug_list
+ * | 'noctx'
+ * major ::= INTEGER
+ * debug_list ::= debug_option [ ':' debug_list ]
+ * debug_option ::= 'on' | 'off' | 'trace' | 'verb' | 'mem' | 'lock' | 'all'
+ *
+ * Note that 's' contains option_list without the 'drm=' part.
+ *
+ * device=major,minor specifies the device number used for /dev/drm
+ * if major == 0 then the misc device is used
+ * if major == 0 and minor == 0 then dynamic misc allocation is used
+ * debug=on specifies that debugging messages will be printk'd
+ * debug=trace specifies that each function call will be logged via printk
+ * debug=off turns off all debugging options
+ *
+ */
+
+static void drm_parse_drm(char *s)
+{
+ char *h, *t, *n;
+
+ DRM_TRACE("\"%s\"\n", s ?: "");
+ if (!s || !*s) return;
+
+ for (h = t = n = s; h && *h; h = n) {
+ for (; *t && *t != ';'; t++); /* find ; or \0 */
+ if (*t) n = t + 1; else n = NULL; /* remember next */
+ *t = '\0'; /* terminate */
+ drm_parse_option(h); /* parse */
+ }
+}
+
+#ifndef MODULE
+/* drm_setup is called by the kernel to parse command-line options passed
+ * via the boot-loader (e.g., LILO). It calls the insmod option routine,
+ * drm_parse_drm.
+ *
+ * This is not currently supported, since it requires changes to
+ * linux/init/main.c. */
+
+
+void __init drm_setup(char *str, int *ints)
+{
+ DRM_TRACE("\n");
+ if (ints[0] != 0) {
+ DRM_ERROR("Illegal command line format, ignored\n");
+ return;
+ }
+ drm_parse_drm(str);
+}
+#endif
+
+/* drm_init is called via init_module at module load time, or via
+ * linux/init/main.c (this is not currently supported). */
+
+int drm_init(void)
+{
+ int retcode;
+ struct sysinfo si;
+ drm_mem_stats_t *mem;
+
+ DRM_TRACE("\n");
+
+#ifdef MODULE
+ drm_parse_drm(drm);
+#endif
+
+ retcode = register_chrdev(drm_major, DRM_NAME, &drm_fops);
+ if (retcode < 0) {
+ DRM_ERROR("Cannot register /dev/%s on major %d\n",
+ DRM_NAME, drm_major);
+ return retcode;
+ }
+ if (!drm_major) drm_major = retcode;
+
+ for (mem = drm_mem_stats; mem->name; ++mem) {
+ mem->succeed_count = 0;
+ mem->free_count = 0;
+ mem->fail_count = 0;
+ mem->bytes_allocated = 0;
+ mem->bytes_freed = 0;
+ }
+
+ drm_proc_init();
+ drm_register_driver_internal(DRM_NAME,
+ &drm_base_version,
+ DRM_BASE_IOCTL_COUNT,
+ drm_base_ioctls,
+ NULL,
+ 1);
+ drm_register_driver(DRM_GEN_NAME,
+ &drm_gen_version,
+ DRM_GEN_IOCTL_COUNT,
+ drm_gen_ioctls,
+ &drm_gen_funcs);
+
+ drm_base_minor = drm_register_device(DRM_NAME, DRM_NAME, 1);
+ if (drm_base_minor < 0) {
+ DRM_ERROR("Cannot install %s: %d\n", DRM_NAME, drm_base_minor);
+ drm_cleanup();
+ return drm_base_minor;
+ }
+
+ si_meminfo(&si);
+ drm_ram_available = si.totalram;
+ drm_ram_used = 0;
+
+ DRM_INFO("Initialized\n");
+
+ return 0;
+}
+
+/* drm_cleanup is called via cleanup_module at module unload time. */
+
+void drm_cleanup(void)
+{
+ int i;
+ drm_driver_t *pt;
+
+ DRM_TRACE("\n");
+
+ for (i = DRM_MAX_DEVICES-1; i >= 0; --i) drm_unregister_device(i);
+
+ drm_proc_cleanup();
+
+ for (pt = drm_drivers; pt; pt = pt->next) {
+ drm_unregister_driver(pt->name);
+ }
+
+ if (unregister_chrdev(drm_major, DRM_NAME)) {
+ DRM_ERROR("Cannot unload device driver\n");
+ } else {
+ DRM_INFO("Module unloaded\n");
+ }
+}
+
+/* drm_open is called whenever a process opens /dev/drm. */
+
+int drm_open(struct inode *inode, struct file *filp)
+{
+ kdev_t minor = MINOR(inode->i_rdev);
+ drm_device_t *dev;
+ drm_driver_t *drv;
+ drm_file_t *priv;
+
+ if (minor >= DRM_MAX_DEVICES) return -EINVAL;
+ if (filp->f_flags & O_EXCL) return -EBUSY; /* No exclusive opens */
+
+ dev = &drm_devices[minor];
+ drv = dev->driver;
+
+ spin_lock(&dev->count_lock);
+ if (!dev->inuse) {
+ spin_unlock(&dev->count_lock);
+ return -EINVAL;
+ }
+ ++dev->open_count;
+ spin_unlock(&dev->count_lock);
+ atomic_inc(&dev->total_open);
+ MOD_INC_USE_COUNT;
+
+ DRM_TRACE("pid = %d, minor = %d, open_count = %d, ioctl_count = %d\n",
+ current->pid, minor, dev->open_count,
+ atomic_read(&dev->ioctl_count));
+
+ priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
+ memset(priv, 0, sizeof(*priv));
+ filp->private_data = priv;
+ priv->uid = current->euid;
+ priv->pid = current->pid;
+ priv->minor = minor;
+ priv->dev = dev;
+ priv->ioctl_count = 0;
+
+ if (!minor || capable(CAP_SYS_ADMIN)) priv->auth = DRM_AUTH_OK;
+ else priv->auth = DRM_AUTH_PENDING;
+
+ spin_lock(&drm_meta_lock);
+ if (!drm_file_last) {
+ priv->next = NULL;
+ priv->prev = NULL;
+ drm_file_first = priv;
+ drm_file_last = priv;
+ } else {
+ priv->next = NULL;
+ priv->prev = drm_file_last;
+ drm_file_last->next = priv;
+ drm_file_last = priv;
+ }
+ spin_unlock(&drm_meta_lock);
+
+ /* Callback */
+ if (drv->funcs && drv->funcs->open) (drv->funcs->open)(inode, filp);
+ return 0;
+}
+
+/* The drm_read and drm_write_string code (especially that which manages
+ the circular buffer), is based on Alessandro Rubini's LINUX DEVICE
+ DRIVERS (Cambridge: O'Reilly, 1998), pages 111-113. */
+
+ssize_t drm_read(struct file *filp, char *buf, size_t count, loff_t *off)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ int left;
+ int avail;
+ int send;
+ int cur;
+
+ DRM_TRACE("%p, %p\n", dev->buf_rp, dev->buf_wp);
+
+ while (dev->buf_rp == dev->buf_wp) {
+ DRM_DEBUG(" sleeping\n");
+ if (filp->f_flags & O_NONBLOCK) {
+ return -EAGAIN;
+ }
+ interruptible_sleep_on(&dev->buf_readers);
+ if (signal_pending(current)) {
+ DRM_DEBUG(" interrupted\n");
+ return -ERESTARTSYS;
+ }
+ DRM_DEBUG(" awake\n");
+ }
+
+ left = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ;
+ avail = DRM_BSZ - left;
+ send = DRM_MIN(avail, count);
+
+ while (send) {
+ if (dev->buf_wp > dev->buf_rp) {
+ cur = DRM_MIN(send, dev->buf_wp - dev->buf_rp);
+ } else {
+ cur = DRM_MIN(send, dev->buf_end - dev->buf_rp);
+ }
+ copy_to_user_ret(buf, dev->buf_rp, cur, -EINVAL);
+ dev->buf_rp += cur;
+ if (dev->buf_rp == dev->buf_end) dev->buf_rp = dev->buf;
+ send -= cur;
+ }
+
+ wake_up_interruptible(&dev->buf_writers);
+ return DRM_MIN(avail, count);;
+}
+
+int drm_write_string(drm_device_t *dev, const char *s)
+{
+ int left = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ;
+ int send = strlen(s);
+ int count;
+
+ DRM_TRACE("%d left, %d to send (%p, %p)\n",
+ left, send, dev->buf_rp, dev->buf_wp);
+
+ if (left == 1 || dev->buf_wp != dev->buf_rp) {
+ DRM_ERROR("Buffer not empty (%d left, wp = %p, rp = %p)\n",
+ left,
+ dev->buf_wp,
+ dev->buf_rp);
+ }
+
+ while (send) {
+ if (dev->buf_wp >= dev->buf_rp) {
+ count = DRM_MIN(send, dev->buf_end - dev->buf_wp);
+ if (count == left) --count; /* Leave a hole */
+ } else {
+ count = DRM_MIN(send, dev->buf_rp - dev->buf_wp - 1);
+ }
+ strncpy(dev->buf_wp, s, count);
+ dev->buf_wp += count;
+ if (dev->buf_wp == dev->buf_end) dev->buf_wp = dev->buf;
+ send -= count;
+ }
+
+ if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO);
+ DRM_DEBUG("waking\n");
+ wake_up_interruptible(&dev->buf_readers);
+ return 0;
+}
+
+int drm_flush(struct file *filp)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+
+ DRM_TRACE("pid = %d, minor = %d, open_count = %d\n",
+ current->pid, dev->device_minor, dev->open_count);
+ return 0;
+}
+
+/* drm_release is called whenever a process closes /dev/drm*. Linux calls
+ this only if any mappings have been closed. */
+
+int drm_release(struct inode *inode, struct file *filp)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_driver_t *drv = dev->driver;
+
+ DRM_TRACE("pid = %d, minor = %d, open_count = %d\n",
+ current->pid, dev->device_minor, dev->open_count);
+
+ drm_reclaim_buffers(dev, priv->pid);
+
+ drm_fasync(-1, filp, 0);
+
+ spin_lock(&drm_meta_lock);
+ if (priv->prev) priv->prev->next = priv->next;
+ else drm_file_first = priv->next;
+ if (priv->next) priv->next->prev = priv->prev;
+ else drm_file_last = priv->prev;
+ spin_unlock(&drm_meta_lock);
+
+ drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
+
+ /* Callback */
+ if (drv->funcs && drv->funcs->release) {
+ DRM_DEBUG("Release callback at %p\n", drv->funcs->release);
+ (drv->funcs->release)(inode, filp);
+ }
+
+ MOD_DEC_USE_COUNT;
+ atomic_inc(&dev->total_close);
+ spin_lock(&dev->count_lock);
+ --dev->open_count;
+ spin_unlock(&dev->count_lock);
+
+ return 0;
+}
+
+int drm_fasync(int fd, struct file *filp, int on)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ int retcode;
+
+ DRM_TRACE("fd = %d, minor = %d\n", fd, dev->device_minor);
+ retcode = fasync_helper(fd, filp, on, &dev->buf_async);
+ if (retcode < 0) return retcode;
+ return 0;
+}
+
+unsigned long drm_vm_nopage(struct vm_area_struct *vma,
+ unsigned long address,
+ int write_access)
+{
+ DRM_TRACE("0x%08lx, %d\n", address, write_access);
+
+ return 0; /* Disallow mremap */
+}
+
+#ifdef MODULE
+static struct mm_struct *drm_get_init_mm(void)
+{
+ /* This routine is based on the
+ retrieve_init_mm_ptr routine on p. 288
+ of Alessandro Rubini's Linux Device
+ Drivers (Cambridge: O'Reilly, 1998).
+ This will no longer be necessary if the
+ kernel ever exports init_mm for use by
+ modules.
+
+ We should also get the tasklist_lock,
+ but we can't since it isn't
+ exported... */
+ struct task_struct *pt;
+
+ /* read_lock(&tasklist_lock); */
+ for (pt = current->next_task; pt != current; pt = pt->next_task) {
+ if (pt->pid == 0) {
+ /* read_unlock(&tasklist_lock); */
+ return pt->mm;
+ }
+ }
+ /* read_unlock(&tasklist_lock); */
+ return NULL;
+}
+#endif
+
+unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma,
+ unsigned long address,
+ int write_access)
+{
+ static struct mm_struct *drm_init_mm = NULL;
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *pte;
+ unsigned long physical;
+ unsigned long kernel_virtual;
+
+#ifdef MODULE
+ if (!drm_init_mm) drm_init_mm = drm_get_init_mm();
+#else
+ if (!drm_init_mm) drm_init_mm = &init_mm;
+#endif
+
+ if (!drm_init_mm) {
+ DRM_ERROR("Cannot access kernel page tables\n");
+ return 0; /* This will cause a user-space SIGBUS */
+ }
+
+ if (address > vma->vm_end) return 0; /* Disallow mremap */
+
+ kernel_virtual = vma->vm_offset + (address - vma->vm_start);
+
+ kernel_virtual = VMALLOC_VMADDR(kernel_virtual);
+ pgd = pgd_offset(drm_init_mm, kernel_virtual);
+ pmd = pmd_offset(pgd, kernel_virtual);
+ pte = pte_offset(pmd, kernel_virtual);
+ if (pte_present(*pte)) {
+ physical = pte_page(*pte);
+ atomic_inc(&mem_map[MAP_NR(physical)].count);
+ } else {
+ physical = 0; /* Something bad happened; generate SIGBUS */
+ }
+
+ DRM_TRACE("0x%08lx => 0x%08lx => 0x%08lx\n",
+ address, kernel_virtual, physical);
+ return physical;
+}
+
+unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma,
+ unsigned long address,
+ int write_access)
+{
+ drm_file_t *priv = vma->vm_file->private_data;
+ drm_device_t *dev = priv->dev;
+ unsigned long physical;
+ unsigned long offset;
+ unsigned long page;
+
+ if (address > vma->vm_end) return 0; /* Disallow mremap */
+ if (!dev->pagelist) return 0; /* Nothing allocated */
+
+ offset = address - vma->vm_start; /* vm_offset should be 0 */
+ page = offset >> PAGE_SHIFT;
+ physical = dev->pagelist[page] + (offset & (~PAGE_MASK));
+ atomic_inc(&mem_map[MAP_NR(physical)].count); /* Dec. by kernel */
+
+ DRM_TRACE("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical);
+ return physical;
+}
+
+void drm_vm_open(struct vm_area_struct *vma)
+{
+ drm_file_t *priv = vma->vm_file->private_data;
+ drm_device_t *dev = priv->dev;
+#if DRM_DEBUG_CODE
+ drm_vma_entry_t *vma_entry;
+#endif
+
+ DRM_TRACE("0x%08lx,0x%08lx\n",
+ vma->vm_start, vma->vm_end - vma->vm_start);
+ atomic_inc(&dev->vma_count);
+ MOD_INC_USE_COUNT;
+
+#if DRM_DEBUG_CODE
+ vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS);
+ if (vma_entry) {
+ spin_lock(&dev->struct_lock);
+ vma_entry->vma = vma;
+ vma_entry->next = dev->vmalist;
+ vma_entry->pid = current->pid;
+ dev->vmalist = vma_entry;
+ spin_unlock(&dev->struct_lock);
+ }
+#endif
+}
+
+void drm_vm_close(struct vm_area_struct *vma)
+{
+ drm_file_t *priv = vma->vm_file->private_data;
+ drm_device_t *dev = priv->dev;
+#if DRM_DEBUG_CODE
+ drm_vma_entry_t *pt, *prev;
+#endif
+
+ DRM_TRACE("0x%08lx,0x%08lx\n",
+ vma->vm_start, vma->vm_end - vma->vm_start);
+ MOD_DEC_USE_COUNT;
+ atomic_dec(&dev->vma_count);
+
+#if DRM_DEBUG_CODE
+ spin_lock(&dev->struct_lock);
+ for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
+ if (pt->vma == vma) {
+ if (prev) {
+ prev->next = pt->next;
+ } else {
+ dev->vmalist = pt->next;
+ }
+ drm_free(pt, sizeof(*pt), DRM_MEM_VMAS);
+ break;
+ }
+ }
+ spin_unlock(&dev->struct_lock);
+#endif
+}
+
+int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ unsigned long length = vma->vm_end - vma->vm_start;
+
+ DRM_TRACE("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
+ vma->vm_start, vma->vm_end, vma->vm_offset);
+
+ /* Length must match exact page count */
+ if ((length >> PAGE_SHIFT) != dev->page_count) return -EINVAL;
+
+ vma->vm_ops = &drm_vm_dma_ops;
+ vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
+
+#if LINUX_VERSION_CODE < 0x020203 /* KERNEL_VERSION(2,2,3) */
+ /* In Linux 2.2.3 and above, this is
+ handled in do_mmap() in mm/mmap.c. */
+ ++filp->f_count;
+#endif
+ vma->vm_file = filp; /* Needed for drm_vm_open() */
+ drm_vm_open(vma);
+ return 0;
+}
+
+int drm_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_map_t *map = NULL;
+ int i;
+
+ DRM_TRACE("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
+ vma->vm_start, vma->vm_end, vma->vm_offset);
+
+ if (!vma->vm_offset) return drm_mmap_dma(filp, vma);
+
+ /* A sequential search of a linked list is
+ fine here because: 1) there will only be
+ about 5-10 entries in the list and, 2) a
+ DRI client only has to do this mapping
+ once, so it doesn't have to be optimized
+ for performance, even if the list was a
+ bit longer. */
+ for (i = 0; i < dev->map_count; i++) {
+ map = dev->maplist[i];
+ if (map->offset == vma->vm_offset) break;
+ }
+
+ if (i >= dev->map_count) return -EINVAL;
+ if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
+ return -EPERM;
+
+ /* Check for valid size. */
+ if (map->size != vma->vm_end - vma->vm_start) return -EINVAL;
+
+
+ switch (map->type) {
+ case _DRM_FRAME_BUFFER:
+ case _DRM_REGISTERS:
+ if (vma->vm_offset >= __pa(high_memory)) {
+#if defined(__i386__)
+ if (boot_cpu_data.x86 > 3) {
+ pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
+ pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
+ }
+#endif
+ vma->vm_flags |= VM_IO; /* not in core dump */
+ }
+ if (remap_page_range(vma->vm_start,
+ vma->vm_offset,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot))
+ return -EAGAIN;
+ vma->vm_ops = &drm_vm_ops;
+ break;
+ case _DRM_SHM:
+ vma->vm_ops = &drm_vm_shm_ops;
+ /* Don't let this area swap. Change when
+ DRM_KERNEL advisory is supported. */
+ vma->vm_flags |= VM_LOCKED;
+ break;
+ default:
+ return -EINVAL; /* This should never happen. */
+ }
+ vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
+ if (map->flags & _DRM_READ_ONLY) {
+ pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
+ }
+
+
+#if LINUX_VERSION_CODE < 0x020203 /* KERNEL_VERSION(2,2,3) */
+ /* In Linux 2.2.3 and above, this is
+ handled in do_mmap() in mm/mmap.c. */
+ ++filp->f_count;
+#endif
+ vma->vm_file = filp; /* Needed for drm_vm_open() */
+ drm_vm_open(vma);
+ return 0;
+}
+
+
+void drm_register_driver_internal(const char *name,
+ drm_version_t *version,
+ int ioctl_count,
+ drm_ioctl_desc_t *ioctls,
+ drm_func_desc_t *funcs,
+ int base)
+{
+ drm_driver_t *pt;
+ int i;
+
+ DRM_TRACE("\n");
+ if (!(pt = drm_alloc(sizeof(*pt), DRM_MEM_DRIVER))) {
+ DRM_ERROR("Cannot register driver\n");
+ return;
+ }
+
+ pt->name = name;
+ pt->version = version;
+ pt->funcs = funcs;
+ pt->next = NULL;
+ pt->refcount = 0;
+ pt->base = base;
+
+
+ pt->ioctl_count = DRM_MAX(ioctl_count, DRM_BASE_IOCTL_COUNT);
+ pt->ioctls = drm_alloc(pt->ioctl_count * sizeof(*pt->ioctls),
+ DRM_MEM_IOCTLS);
+ memset(pt->ioctls, 0, pt->ioctl_count * sizeof(*pt->ioctls));
+ for (i = 0; i < ioctl_count; i++) {
+ if (i < DRM_BASE_IOCTL_COUNT
+ && (drm_base_ioctls[i].dispatch & DRM_BASE)) { /* force */
+ pt->ioctls[i].func = drm_base_ioctls[i].func;
+ pt->ioctls[i].root_only = drm_base_ioctls[i].root_only;
+ pt->ioctls[i].dispatch = drm_base_ioctls[i].dispatch;
+ } else if (i < ioctl_count
+ && ioctls[i].func) { /* from driver */
+ pt->ioctls[i].func = ioctls[i].func;
+ pt->ioctls[i].root_only = ioctls[i].root_only;
+ pt->ioctls[i].dispatch = ioctls[i].dispatch;
+ } else if (i < DRM_BASE_IOCTL_COUNT) { /* fallback */
+ pt->ioctls[i].func = drm_base_ioctls[i].func;
+ pt->ioctls[i].root_only = drm_base_ioctls[i].root_only;
+ pt->ioctls[i].dispatch = drm_base_ioctls[i].dispatch;
+ }
+ }
+
+ spin_lock(&drm_meta_lock);
+ if (drm_drivers && drm_drivers_tail) {
+ drm_drivers_tail->next = pt;
+ drm_drivers_tail = pt;
+ } else {
+ drm_drivers = drm_drivers_tail = pt;
+ }
+ spin_unlock(&drm_meta_lock);
+
+ /* Callback */
+ if (funcs && funcs->load) (funcs->load)();
+}
+
+
+void drm_register_driver(const char *name,
+ drm_version_t *version,
+ int ioctl_count,
+ drm_ioctl_desc_t *ioctls,
+ drm_func_desc_t *funcs)
+{
+ drm_register_driver_internal( name, version, ioctl_count,
+ ioctls, funcs, 0);
+}
+
+
+void drm_unregister_driver(const char *name)
+{
+ drm_driver_t *pt;
+ drm_driver_t *prev;
+
+ DRM_TRACE("\n");
+
+ spin_lock(&drm_meta_lock);
+
+ for (prev = NULL, pt = drm_drivers; pt; prev = pt, pt = pt->next) {
+ if (!strcmp(pt->name, name)) {
+ if (drm_drivers == pt) {
+ /* At head */
+ drm_drivers = pt->next;
+ } else {
+ /* Not at head */
+ prev->next = pt->next;
+ }
+ if (drm_drivers_tail == pt)
+ drm_drivers_tail = pt->next;
+ spin_unlock(&drm_meta_lock);
+
+ /* Callback */
+ if (pt->funcs && pt->funcs->unload)
+ (pt->funcs->unload)();
+ drm_free(pt, sizeof(*pt), DRM_MEM_DRIVER);
+ return;
+ }
+ }
+ spin_unlock(&drm_meta_lock);
+ DRM_ERROR("Cannot unregister driver \"%s\"\n", name);
+}
+
+static void drm_dma_schedule_wrapper(unsigned long data)
+{
+ drm_dma_schedule((drm_device_t *)data, 0);
+}
+
+/* drm_register_device registers a device on the next available minor
+ number. If the device can be registered, the minor number is returned.
+ Otherwise a value < 0 is returned. */
+
+int drm_register_device(const char *name,
+ const char *busid,
+ int allow_base)
+{
+ drm_driver_t *drv;
+ drm_device_t *dev = NULL;
+ int minor;
+ char *buf;
+ unsigned int buflen;
+
+ spin_lock(&drm_meta_lock);
+
+ /* Use first available slot by default */
+ for (minor = 0; minor < DRM_MAX_DEVICES; minor++) {
+ spin_lock(&drm_devices[minor].count_lock);
+ if (!drm_devices[minor].inuse) {
+ dev = &drm_devices[minor];
+ memset(dev, 0, sizeof(*dev));
+ ++dev->inuse;
+ spin_unlock(&drm_devices[minor].count_lock);
+ break;
+ }
+ spin_unlock(&drm_devices[minor].count_lock);
+ }
+
+ if (!dev) {
+ DRM_ERROR("Cannot load more then %d devices\n",
+ DRM_MAX_DEVICES );
+ spin_unlock(&drm_meta_lock);
+ return -EBUSY;
+ }
+
+
+ DRM_TRACE("%s %s using minor %d (%d)\n",
+ name, busid, minor, dev->inuse);
+
+ for (drv = drm_drivers; drv; drv = drv->next) {
+ if (!allow_base && drv->base) {
+ continue; /* don't allow base to load */
+ }
+ if (!strcmp(drv->version->name, name)) {
+ if (drv->refcount) {
+ /* FIXME: Allow more than one device with
+ the same name for 1) multihead support,
+ and 2) support for recycling the server
+ when a client refuses to die quickly
+ (see drm_unregister_device). */
+ dev->inuse = 0;
+ spin_unlock(&drm_meta_lock);
+ DRM_ERROR("Cannot load %s twice -- FIXME\n",
+ name);
+ return -EBUSY;
+ }
+ buflen = (5 + strlen(DRM_NAME)
+ + strlen(name)
+ + strlen(busid));
+ buf = drm_alloc(buflen, DRM_MEM_DRIVER);
+ sprintf(buf, "%s %s %s", DRM_NAME, name, busid);
+
+ dev->device_minor = minor;
+ dev->driver = drv;
+ dev->busid = drm_strdup(busid, DRM_MEM_DRIVER);
+ dev->devname = drm_strdup(buf, DRM_MEM_DRIVER);
+ dev->count_lock = SPIN_LOCK_UNLOCKED;
+ dev->struct_lock = SPIN_LOCK_UNLOCKED;
+ dev->buf_rp = dev->buf;
+ dev->buf_wp = dev->buf;
+ dev->buf_end = dev->buf + DRM_BSZ;
+
+ init_timer(&dev->timer);
+ dev->timer.function = drm_dma_schedule_wrapper;
+ dev->timer.data = (unsigned long)dev;
+
+ drm_free(buf, buflen, DRM_MEM_DRIVER);
+ buf = NULL;
+
+ init_waitqueue_head(&dev->waiting);
+ init_waitqueue_head(&dev->context_wait);
+ init_waitqueue_head(&dev->buf_readers);
+ init_waitqueue_head(&dev->buf_writers);
+ init_waitqueue_head(&dev->lock.lock_queue);
+
+ /* The kernel's context could be created
+ here, but is now created in
+ drm_dma_enqueue. This is more
+ resource-efficient for hardware that
+ does not do DMA, but may mean that
+ drm_select_queue fails between the time
+ the interrupt is initialized and the
+ time the queues are initialized. */
+
+ drm_proc_add_device(dev);
+
+ ++drv->refcount;
+
+ /* Callback */
+ if (drv->funcs && drv->funcs->reg) {
+ int retcode = (drv->funcs->reg)();
+ if (retcode) {
+ spin_unlock(&drm_meta_lock);
+ return retcode;
+ }
+ }
+ spin_unlock(&drm_meta_lock);
+ return minor;
+ }
+ }
+
+ dev->inuse = 0;
+ spin_unlock(&drm_meta_lock);
+ DRM_ERROR("Cannot load device \"%s\" \"%s\"\n", name, busid);
+ return -EINVAL;
+}
+
+/* drm_unregister_device unregisters a device, base on minor number. If
+ the device can be unregistered, 0 is returned. Otherwise a value < 0 is
+ returned. */
+
+int drm_unregister_device(int minor)
+{
+ drm_driver_t *drv;
+ drm_device_t *dev;
+ int i, j;
+ drm_magic_entry_t *pt, *next;
+ drm_map_t *map;
+ drm_vma_entry_t *vma, *vma_next;
+
+ spin_lock(&drm_meta_lock);
+
+ DRM_TRACE("minor = %d\n", minor);
+ if (minor < 0 || minor >= DRM_MAX_DEVICES) {
+ DRM_ERROR("Cannot unload device (%d,%d)"
+ " -- only %d devices possible\n",
+ drm_major, minor, DRM_MAX_DEVICES);
+ spin_unlock(&drm_meta_lock);
+ return -EINVAL;
+ }
+
+ dev = &drm_devices[minor];
+ drv = drm_devices[minor].driver;
+
+ DRM_DEBUG("inuse = %d, open_count = %d, blocked = %d\n",
+ dev->inuse, dev->open_count, dev->blocked );
+
+ spin_lock(&dev->count_lock);
+ if (!dev->inuse) {
+ spin_unlock(&dev->count_lock);
+ spin_unlock(&drm_meta_lock);
+ return -EINVAL;
+ }
+ if (dev->open_count || atomic_read(&dev->ioctl_count) || dev->blocked){
+ /* FIXME: Allow flagging for deletion so
+ that the server can recycle even if a
+ client refuses to die quickly. See
+ comment in drm_register_device. */
+ spin_unlock(&dev->count_lock);
+ spin_unlock(&drm_meta_lock);
+ DRM_ERROR("Device busy: %s at busid %s (%d, %d, %d)\n",
+ dev->driver->name,
+ dev->busid,
+ dev->open_count,
+ atomic_read(&dev->ioctl_count),
+ dev->blocked);
+ return -EBUSY;
+ }
+ dev->inuse = 0;
+ spin_unlock(&dev->count_lock);
+
+ --drv->refcount;
+ drm_proc_del_device(dev);
+
+ /* Unhook interrupt handler */
+ if (dev->irq) drm_irq_uninstall(dev);
+
+ /* Delete timer, if any */
+ del_timer(&dev->timer);
+
+ /* Free busid */
+ drm_strfree(dev->busid, DRM_MEM_DRIVER);
+ dev->busid = NULL;
+
+ /* Free devname */
+ drm_strfree(dev->devname, DRM_MEM_DRIVER);
+ dev->devname = NULL;
+
+ /* Clear pid list */
+ DRM_DEBUG("pidlist\n");
+ for (i = 0; i < DRM_HASH_SIZE; i++) {
+ for (pt = dev->magiclist[i].head; pt; pt = next) {
+ next = pt->next;
+ drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
+ }
+ dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
+ }
+
+ /* Clear vma list (only built for debugging) */
+ DRM_DEBUG("vmalist\n");
+ for (vma = dev->vmalist; vma; vma = vma_next) {
+ vma_next = vma->next;
+ drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
+ }
+
+
+ /* Clear map area and mtrr information */
+ DRM_DEBUG("maplist = %p, %d\n", dev->maplist, dev->map_count);
+ if (dev->maplist) {
+ for (i = 0; i < dev->map_count; i++) {
+ map = dev->maplist[i];
+ switch (map->type) {
+ case _DRM_REGISTERS:
+ case _DRM_FRAME_BUFFER:
+#ifdef CONFIG_MTRR
+ if (map->mtrr >= 0) {
+ int retcode;
+ retcode = mtrr_del(map->mtrr,
+ map->offset,
+ map->size);
+ DRM_DEBUG("mtrr_del = %d\n", retcode);
+ }
+#endif
+ drm_ioremapfree(map->handle, map->size);
+ break;
+ case _DRM_SHM:
+ drm_vfree(map->handle, map->size);
+ break;
+ }
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ }
+ drm_free(dev->maplist,
+ dev->map_count * sizeof(*dev->maplist),
+ DRM_MEM_MAPS);
+ }
+
+ /* Clear dma buffers */
+ for (i = 0; i <= DRM_MAX_ORDER; i++) {
+ if (dev->bufs[i].seg_count) {
+ DRM_DEBUG("order %d: buf_count = %d,"
+ " seg_count = %d\n",
+ i,
+ dev->bufs[i].buf_count,
+ dev->bufs[i].seg_count);
+ for (j = 0; j < dev->bufs[i].seg_count; j++) {
+ drm_free_dma(dev->bufs[i].seglist[j],
+ dev->bufs[i].page_order);
+ }
+ drm_free(dev->bufs[i].buflist,
+ sizeof(*dev->bufs[0].buflist),
+ DRM_MEM_BUFS);
+ drm_free(dev->bufs[i].seglist,
+ sizeof(*dev->bufs[0].seglist),
+ DRM_MEM_SEGS);
+ drm_freelist_destroy(&dev->bufs[i].freelist);
+ }
+ dev->bufs[i].buf_count = 0;
+ dev->bufs[i].seg_count = 0;
+ }
+ if (dev->buflist) {
+ drm_free(dev->buflist,
+ dev->buf_count * sizeof(*dev->buflist),
+ DRM_MEM_BUFS);
+ }
+ if (dev->pagelist) {
+ drm_free(dev->pagelist,
+ dev->page_count * sizeof(*dev->pagelist),
+ DRM_MEM_PAGES);
+ }
+ if (dev->queuelist) {
+ for (i = 0; i < dev->queue_count; i++) {
+ drm_waitlist_destroy(&dev->queuelist[i]->waitlist);
+ if (dev->queuelist[i])
+ drm_free(dev->queuelist[i],
+ sizeof(*dev->queuelist[0]),
+ DRM_MEM_QUEUES);
+ }
+ drm_free(dev->queuelist,
+ dev->queue_slots * sizeof(*dev->queuelist),
+ DRM_MEM_QUEUES);
+ }
+ for (i = 0; i < _DRM_DESC_MAX; i++) {
+ if (dev->cmd[i].inst) {
+ drm_free(dev->cmd[i].inst,
+ dev->cmd[i].count
+ * _DRM_INST_LENGTH
+ * sizeof(*dev->cmd[i].inst),
+ DRM_MEM_CMDS);
+ }
+ }
+
+ dev->buf_count = 0;
+ dev->seg_count = 0;
+ dev->page_count = 0;
+ dev->byte_count = 0;
+ dev->buflist = NULL;
+ dev->pagelist = NULL;
+ dev->lock.hw_lock = NULL; /* SHM removed */
+ dev->lock.pid = 0;
+ wake_up_interruptible(&dev->lock.lock_queue);
+
+ /* callback */
+ DRM_DEBUG("callbacks\n");
+ if (drv->funcs && drv->funcs->unreg) (drv->funcs->unreg)();
+
+ spin_unlock(&drm_meta_lock);
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_version.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_version.h
new file mode 100644
index 000000000..1c43a3061
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm_version.h
@@ -0,0 +1,4 @@
+#define DRM_DATE "19990623"
+#define DRM_MAJOR 1
+#define DRM_MINOR 0
+#define DRM_PATCHLEVEL 0
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drmstat.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drmstat.c
new file mode 100644
index 000000000..19650eba8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drmstat.c
@@ -0,0 +1,462 @@
+/* drmstat.c -- DRM device status and testing program
+ * Created: Tue Jan 5 08:19:24 1999 by faith@precisioninsight.com
+ * Revised: Thu Jun 24 14:53:46 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drmstat.c,v 1.26 1999/06/24 18:54:56 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drmstat.c,v 1.2 1999/06/27 14:08:26 dawes Exp $
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/mman.h>
+#include <getopt.h>
+#include <strings.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include "xf86drm.h"
+
+int sigio_fd;
+
+static double usec(struct timeval *end, struct timeval *start)
+{
+ double e = end->tv_sec * 1000000 + end->tv_usec;
+ double s = start->tv_sec * 1000000 + start->tv_usec;
+
+ return e - s;
+}
+
+static void getversion(int fd)
+{
+ drmVersionPtr version;
+
+ version = drmGetVersion(fd);
+ if (version) {
+ printf( "Name: %s\n", version->name ? version->name : "?" );
+ printf( " Version: %d.%d.%d\n",
+ version->version_major,
+ version->version_minor,
+ version->version_patchlevel );
+ printf( " Date: %s\n", version->date ? version->date : "?" );
+ printf( " Desc: %s\n", version->desc ? version->desc : "?" );
+ drmFreeVersion(version);
+ } else {
+ printf( "No driver available\n" );
+ }
+}
+
+static int getinfo(const char *label)
+{
+ int fd;
+ drmListPtr list;
+ int i;
+
+ if (!drmAvailable()) {
+ printf( "The drm device driver is not installed\n" );
+ return 0;
+ }
+
+ if ((fd = drmOpenDRM()) < 0) return drmError(fd, label);
+ printf( "Using fd = %d\n", fd );
+
+ getversion(fd);
+
+ list = drmGetVersionList(fd);
+ if (list) {
+ printf( "%d sub-drivers available:\n", list->count );
+ for (i = 0; i < list->count; i++) {
+ printf( " Name: %s\n",
+ list->version[i].name ? list->version[i].name : "?" );
+ printf( " Version: %d.%d.%d\n",
+ list->version[i].version_major,
+ list->version[i].version_minor,
+ list->version[i].version_patchlevel );
+ printf( " Date: %s\n",
+ list->version[i].date ? list->version[i].date : "?" );
+ printf( " Desc: %s\n",
+ list->version[i].desc ? list->version[i].desc : "?" );
+ }
+ drmFreeVersionList(list);
+ }
+
+ drmCloseDRM(fd);
+ return 0;
+}
+
+void handler(int fd, void *oldctx, void *newctx)
+{
+ printf("Got fd %d\n", fd);
+}
+
+void process_sigio(char *device)
+{
+ int fd;
+
+ if ((fd = open(device, 0)) < 0) {
+ drmError(-errno, __FUNCTION__);
+ exit(1);
+ }
+
+ sigio_fd = fd;
+ drmInstallSIGIOHandler(fd, handler);
+ for (;;) sleep(60);
+}
+
+int main(int argc, char **argv)
+{
+ int c;
+ int r = 0;
+ int fd = -1;
+ drmHandle handle;
+ void *address;
+ char *pt;
+ unsigned long count;
+ unsigned long offset;
+ unsigned long size;
+ drmContext context;
+ int loops;
+ char buf[1024];
+ int i;
+ drmBufInfoPtr info;
+ drmBufMapPtr bufs;
+ drmLockPtr lock;
+ int fdDRM;
+ int secs;
+
+ fdDRM = drmOpenDRM();
+
+ while ((c = getopt(argc, argv,
+ "lc:d:vo:f:s:w:W:b:r:R:P:L:C:XS:B:F:")) != EOF)
+ switch (c) {
+ case 'F':
+ count = strtoul(optarg, NULL, 0);
+ if (!fork()) {
+ dup(fd);
+ sleep(count);
+ }
+ close(fd);
+ close(fdDRM);
+ break;
+ case 'l': r = getinfo(argv[0]); break;
+ case 'v': getversion(fd); break;
+ case 'X':
+ if ((r = drmCreateContext(fd, &context))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ printf( "Got %d\n", context);
+ break;
+ case 'S':
+ process_sigio(optarg);
+ break;
+ case 'C':
+ if ((r = drmSwitchToContext(fd, strtoul(optarg, NULL, 0)))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ break;
+ case 'c':
+ if ((r = drmCreateSub(fdDRM,optarg,optarg))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ break;
+ case 'd':
+ if ((r = drmDestroySub(fdDRM,optarg))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ break;
+ case 'o':
+ if ((fd = drmOpenSub(optarg)) < 0) {
+ drmError(fd, argv[0]);
+ return 1;
+ }
+ break;
+ case 'B': /* Test buffer allocation */
+ count = strtoul(optarg, &pt, 0);
+ size = strtoul(pt+1, &pt, 0);
+ secs = strtoul(pt+1, NULL, 0);
+ {
+ drmDMAReq dma;
+ int *indices, *sizes;
+
+ indices = alloca(sizeof(*indices) * count);
+ sizes = alloca(sizeof(*sizes) * count);
+ dma.context = context;
+ dma.send_count = 0;
+ dma.request_count = count;
+ dma.request_size = size;
+ dma.request_list = indices;
+ dma.request_sizes = sizes;
+ dma.flags = DRM_DMA_WAIT;
+ if ((r = drmDMA(fd, &dma))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ for (i = 0; i < dma.granted_count; i++) {
+ printf("%5d: index = %d, size = %d\n",
+ i, dma.request_list[i], dma.request_sizes[i]);
+ }
+ sleep(secs);
+ drmFreeBufs(fd, dma.granted_count, indices);
+ }
+ break;
+ case 'b':
+ count = strtoul(optarg, &pt, 0);
+ size = strtoul(pt+1, NULL, 0);
+ if ((r = drmAddBufs(fd, count, size, 0)) < 0) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ if (!(info = drmGetBufInfo(fd))) {
+ drmError(0, argv[0]);
+ return 1;
+ }
+ for (i = 0; i < info->count; i++) {
+ printf("%5d buffers of size %6d (low = %d, high = %d)\n",
+ info->list[i].count,
+ info->list[i].size,
+ info->list[i].low_mark,
+ info->list[i].high_mark);
+ }
+ if ((r = drmMarkBufs(fd, 0.50, 0.80))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ if (!(info = drmGetBufInfo(fd))) {
+ drmError(0, argv[0]);
+ return 1;
+ }
+ for (i = 0; i < info->count; i++) {
+ printf("%5d buffers of size %6d (low = %d, high = %d)\n",
+ info->list[i].count,
+ info->list[i].size,
+ info->list[i].low_mark,
+ info->list[i].high_mark);
+ }
+ printf("===== /proc/drm/1/meminfo =====\n");
+ sprintf(buf, "cat /proc/drm/1/meminfo");
+ system(buf);
+#if 1
+ if (!(bufs = drmMapBufs(fd))) {
+ drmError(0, argv[0]);
+ return 1;
+ }
+ printf("===============================\n");
+ printf( "%d bufs\n", bufs->count);
+ for (i = 0; i < bufs->count; i++) {
+ printf( " %4d: %8d bytes at %p\n",
+ i,
+ bufs->list[i].total,
+ bufs->list[i].address);
+ }
+ printf("===== /proc/drm/1/vmainfo =====\n");
+ sprintf(buf, "cat /proc/drm/1/vmainfo");
+ system(buf);
+#endif
+ break;
+ case 'f':
+ offset = strtoul(optarg, &pt, 0);
+ size = strtoul(pt+1, NULL, 0);
+ handle = 0;
+ if ((r = drmAddMap(fd, offset, size,
+ DRM_FRAME_BUFFER, 0, &handle))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ printf("0x%08lx:0x%04lx added\n", offset, size);
+ printf("===== /proc/drm/1/meminfo =====\n");
+ sprintf(buf, "cat /proc/drm/1/meminfo");
+ system(buf);
+ break;
+ case 'r':
+ case 'R':
+ offset = strtoul(optarg, &pt, 0);
+ size = strtoul(pt+1, NULL, 0);
+ handle = 0;
+ if ((r = drmAddMap(fd, offset, size,
+ DRM_REGISTERS,
+ c == 'R' ? DRM_READ_ONLY : 0,
+ &handle))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ printf("0x%08lx:0x%04lx added\n", offset, size);
+ printf("===== /proc/drm/1/meminfo =====\n");
+ sprintf(buf, "cat /proc/drm/1/meminfo");
+ system(buf);
+ break;
+ case 's':
+ size = strtoul(optarg, &pt, 0);
+ handle = 0;
+ if ((r = drmAddMap(fd, 0, size,
+ DRM_SHM, DRM_CONTAINS_LOCK,
+ &handle))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ printf("0x%04lx byte shm added at 0x%08lx\n", size, handle);
+ sprintf(buf, "cat /proc/drm/1/meminfo");
+ system(buf);
+ break;
+ case 'P':
+ offset = strtoul(optarg, &pt, 0);
+ size = strtoul(pt+1, NULL, 0);
+ address = NULL;
+ if ((r = drmMap(fd, offset, size, &address))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ printf("0x%08lx:0x%04lx mapped at %p for pid %d\n",
+ offset, size, address, getpid());
+ printf("===== /proc/drm/1/vmainfo =====\n");
+ sprintf(buf, "cat /proc/drm/1/vmainfo");
+ system(buf);
+ mprotect((void *)offset, size, PROT_READ);
+ printf("===== /proc/drm/1/vmainfo =====\n");
+ sprintf(buf, "cat /proc/drm/1/vmainfo");
+ system(buf);
+ break;
+ case 'w':
+ case 'W':
+ offset = strtoul(optarg, &pt, 0);
+ size = strtoul(pt+1, NULL, 0);
+ address = NULL;
+ if ((r = drmMap(fd, offset, size, &address))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ printf("0x%08lx:0x%04lx mapped at %p for pid %d\n",
+ offset, size, address, getpid());
+ printf("===== /proc/%d/maps =====\n", getpid());
+ sprintf(buf, "cat /proc/%d/maps", getpid());
+ system(buf);
+ printf("===== /proc/drm/1/meminfo =====\n");
+ sprintf(buf, "cat /proc/drm/1/meminfo");
+ system(buf);
+ printf("===== /proc/drm/1/vmainfo =====\n");
+ sprintf(buf, "cat /proc/drm/1/vmainfo");
+ system(buf);
+ printf("===== READING =====\n");
+ for (i = 0; i < 0x10; i++)
+ printf("%02x ", (unsigned int)((unsigned char *)address)[i]);
+ printf("\n");
+ if (c == 'w') {
+ printf("===== WRITING =====\n");
+ for (i = 0; i < size; i+=2) {
+ ((char *)address)[i] = i & 0xff;
+ ((char *)address)[i+1] = i & 0xff;
+ }
+ }
+ printf("===== READING =====\n");
+ for (i = 0; i < 0x10; i++)
+ printf("%02x ", (unsigned int)((unsigned char *)address)[i]);
+ printf("\n");
+ printf("===== /proc/drm/1/vmainfo =====\n");
+ sprintf(buf, "cat /proc/drm/1/vmainfo");
+ system(buf);
+ break;
+ case 'L':
+ context = strtoul(optarg, &pt, 0);
+ offset = strtoul(pt+1, &pt, 0);
+ size = strtoul(pt+1, &pt, 0);
+ loops = strtoul(pt+1, NULL, 0);
+ address = NULL;
+ if ((r = drmMap(fd, offset, size, &address))) {
+ drmError(r, argv[0]);
+ return 1;
+ }
+ lock = address;
+#if 1
+ {
+ int counter = 0;
+ struct timeval loop_start, loop_end;
+ struct timeval lock_start, lock_end;
+ double wt;
+#define HISTOSIZE 9
+ int histo[HISTOSIZE];
+ int output = 0;
+ int fast = 0;
+
+ if (loops < 0) {
+ loops = -loops;
+ ++output;
+ }
+
+ for (i = 0; i < HISTOSIZE; i++) histo[i] = 0;
+
+ gettimeofday(&loop_start, NULL);
+ for (i = 0; i < loops; i++) {
+ gettimeofday(&lock_start, NULL);
+ DRM_LIGHT_LOCK_COUNT(fd,lock,context,fast);
+ gettimeofday(&lock_end, NULL);
+ DRM_UNLOCK(fd,lock,context);
+ ++counter;
+ wt = usec(&lock_end, &lock_start);
+ if (wt <= 2.5) ++histo[8];
+ if (wt < 5.0) ++histo[0];
+ else if (wt < 50.0) ++histo[1];
+ else if (wt < 500.0) ++histo[2];
+ else if (wt < 5000.0) ++histo[3];
+ else if (wt < 50000.0) ++histo[4];
+ else if (wt < 500000.0) ++histo[5];
+ else if (wt < 5000000.0) ++histo[6];
+ else ++histo[7];
+ if (output) printf( "%.2f uSec, %d fast\n", wt, fast);
+ }
+ gettimeofday(&loop_end, NULL);
+ printf( "Average wait time = %.2f usec, %d fast\n",
+ usec(&loop_end, &loop_start) / counter, fast);
+ printf( "%9d <= 2.5 uS\n", histo[8]);
+ printf( "%9d < 5 uS\n", histo[0]);
+ printf( "%9d < 50 uS\n", histo[1]);
+ printf( "%9d < 500 uS\n", histo[2]);
+ printf( "%9d < 5000 uS\n", histo[3]);
+ printf( "%9d < 50000 uS\n", histo[4]);
+ printf( "%9d < 500000 uS\n", histo[5]);
+ printf( "%9d < 5000000 uS\n", histo[6]);
+ printf( "%9d >= 5000000 uS\n", histo[7]);
+ }
+#else
+ printf( "before lock: 0x%08x\n", lock->lock);
+ printf( "lock: 0x%08x\n", lock->lock);
+ sleep(5);
+ printf( "unlock: 0x%08x\n", lock->lock);
+#endif
+ break;
+ default:
+ fprintf( stderr, "Usage: drmstat [options]\n" );
+ return 1;
+ }
+
+ if (fdDRM >= 0) drmCloseDRM(fdDRM);
+
+ return r;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_bufs.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_bufs.c
new file mode 100644
index 000000000..c6d47b761
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_bufs.c
@@ -0,0 +1,311 @@
+/* gen_bufs.c -- Buffer list handling routines -*- linux-c -*-
+ * Created: Mon Apr 19 20:54:22 1999 by faith@precisioninsight.com
+ * Revised: Mon Jun 14 15:31:24 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_bufs.c,v 1.14 1999/06/14 21:11:28 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_bufs.c,v 1.2 1999/06/27 14:08:27 dawes Exp $
+ *
+ */
+
+#define GEN_BUFS_MAIN 0 /* 1 for stand-alone test */
+
+#if !GEN_BUFS_MAIN
+#define __NO_VERSION__
+#include "drmP.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+typedef struct {
+ int buf_count;
+} drm_device_t;
+typedef struct {
+ int idx;
+} drm_buf_t;
+typedef int spinlock_t;
+#define SPIN_LOCK_UNLOCKED 0
+typedef struct {
+ int count; /* Number of possible buffers */
+ drm_buf_t **bufs; /* List of pointers to buffers */
+ drm_buf_t **rp; /* Read pointer */
+ drm_buf_t **wp; /* Write pointer */
+ drm_buf_t **end; /* End pointer */
+ spinlock_t write_lock; /* Serialize writes */
+} drm_waitlist_t;
+#define spin_lock(x)
+#define spin_unlock(x)
+#define DRM_TRACE(fmt, arg...) printf(fmt , ##arg)
+#define DRM_ERROR(fmt, arg...) printf("*ERROR* " fmt , ##arg)
+#define drm_alloc(size,area) malloc(size)
+#define drm_free(pt,size,area) free(pt)
+#define DRM_LEFTCOUNT(x) ((x->rp + x->count - x->wp) % (x->count + 1))
+#endif
+
+int drm_waitlist_create(drm_waitlist_t *bl, int count)
+{
+ DRM_TRACE("%d\n", count);
+ if (bl->count) return -EINVAL;
+
+ bl->count = count;
+ bl->bufs = drm_alloc((bl->count + 2) * sizeof(*bl->bufs),
+ DRM_MEM_BUFLISTS);
+ bl->rp = bl->bufs;
+ bl->wp = bl->bufs;
+ bl->end = &bl->bufs[bl->count+1];
+ bl->write_lock = SPIN_LOCK_UNLOCKED;
+ bl->read_lock = SPIN_LOCK_UNLOCKED;
+ return 0;
+}
+
+int drm_waitlist_destroy(drm_waitlist_t *bl)
+{
+ DRM_TRACE("\n");
+ if (bl->rp != bl->wp) return -EINVAL;
+ if (bl->bufs) drm_free(bl->bufs,
+ (bl->count + 2) * sizeof(*bl->bufs),
+ DRM_MEM_BUFLISTS);
+ bl->count = 0;
+ bl->bufs = NULL;
+ bl->rp = NULL;
+ bl->wp = NULL;
+ bl->end = NULL;
+ return 0;
+}
+
+int drm_waitlist_put(drm_waitlist_t *bl, drm_buf_t *buf)
+{
+ int left;
+ unsigned long flags;
+
+ left = DRM_LEFTCOUNT(bl);
+ DRM_TRACE("put %d (%d left, rp = %p, wp = %p)\n",
+ buf->idx, left, bl->rp, bl->wp);
+ if (!left) {
+ DRM_ERROR("Overflow while adding buffer %d from pid %d\n",
+ buf->idx, buf->pid);
+ return -EINVAL;
+ }
+#if DRM_DMA_HISTOGRAM
+ buf->time_queued = get_cycles();
+#endif
+ buf->list = DRM_LIST_WAIT;
+
+ spin_lock_irqsave(&bl->write_lock, flags);
+ *bl->wp = buf;
+ if (++bl->wp >= bl->end) bl->wp = bl->bufs;
+ spin_unlock_irqrestore(&bl->write_lock, flags);
+
+ return 0;
+}
+
+drm_buf_t *drm_waitlist_get(drm_waitlist_t *bl)
+{
+ drm_buf_t *buf;
+ unsigned long flags;
+
+ spin_lock_irqsave(&bl->read_lock, flags);
+ buf = *bl->rp;
+ if (bl->rp == bl->wp) {
+ spin_unlock_irqrestore(&bl->read_lock, flags);
+ return NULL;
+ }
+ if (++bl->rp >= bl->end) bl->rp = bl->bufs;
+ spin_unlock_irqrestore(&bl->read_lock, flags);
+
+ DRM_TRACE("get %d\n", buf->idx);
+ return buf;
+}
+
+#if !GEN_BUFS_MAIN
+
+int drm_freelist_create(drm_freelist_t *bl, int count)
+{
+ DRM_TRACE("\n");
+ atomic_set(&bl->count, 0);
+ bl->next = NULL;
+ init_waitqueue_head(&bl->waiting);
+ bl->low_mark = 0;
+ bl->high_mark = 0;
+ atomic_set(&bl->wfh, 0);
+ ++bl->initialized;
+ return 0;
+}
+
+int drm_freelist_destroy(drm_freelist_t *bl)
+{
+ DRM_TRACE("\n");
+ atomic_set(&bl->count, 0);
+ bl->next = NULL;
+ return 0;
+}
+
+int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
+{
+ unsigned int old;
+ unsigned int new;
+ char failed;
+ int count = 0;
+
+ if (buf->waiting || buf->pending || buf->list == DRM_LIST_FREE) {
+ DRM_ERROR("Freed buffer %d: w%d, p%d, l%d\n",
+ buf->idx, buf->waiting, buf->pending, buf->list);
+ }
+ DRM_TRACE("%d, count = %d, wfh = %d, w%d, p%d\n",
+ buf->idx, atomic_read(&bl->count), atomic_read(&bl->wfh),
+ buf->waiting, buf->pending);
+ if (!bl) return 1;
+#if DRM_DMA_HISTOGRAM
+ buf->time_freed = get_cycles();
+ drm_histogram_compute(dev, buf);
+#endif
+ buf->list = DRM_LIST_FREE;
+ do {
+ old = (unsigned long)bl->next;
+ buf->next = (void *)old;
+ new = (unsigned long)buf;
+ _DRM_CAS(&bl->next, old, new, failed);
+ if (++count > DRM_LOOPING_LIMIT) {
+ DRM_ERROR("Looping\n");
+ return 1;
+ }
+ } while (failed);
+ atomic_inc(&bl->count);
+ if (atomic_read(&bl->count) > dev->buf_count) {
+ DRM_ERROR("%d of %d buffers free after addition of %d\n",
+ atomic_read(&bl->count), dev->buf_count, buf->idx);
+ return 1;
+ }
+ /* Check for high water mark */
+ if (atomic_read(&bl->wfh) && atomic_read(&bl->count)>=bl->high_mark) {
+ atomic_set(&bl->wfh, 0);
+ wake_up_interruptible(&bl->waiting);
+ }
+ return 0;
+}
+
+static drm_buf_t *drm_freelist_try(drm_freelist_t *bl)
+{
+ unsigned int old;
+ unsigned int new;
+ char failed;
+ drm_buf_t *buf;
+ int count = 0;
+
+ if (!bl) return NULL;
+
+ /* Get buffer */
+ do {
+ old = (unsigned int)bl->next;
+ if (!old) {
+ return NULL;
+ }
+ new = (unsigned long)bl->next->next;
+ _DRM_CAS(&bl->next, old, new, failed);
+ if (++count > DRM_LOOPING_LIMIT) {
+ DRM_ERROR("Looping\n");
+ return NULL;
+ }
+ } while (failed);
+ atomic_dec(&bl->count);
+
+ buf = (drm_buf_t *)old;
+ buf->next = NULL;
+ buf->list = DRM_LIST_NONE;
+ DRM_TRACE("%d, count = %d, wfh = %d, w%d, p%d\n",
+ buf->idx, atomic_read(&bl->count), atomic_read(&bl->wfh),
+ buf->waiting, buf->pending);
+ if (buf->waiting || buf->pending) {
+ DRM_ERROR("Free buffer %d: w%d, p%d, l%d\n",
+ buf->idx, buf->waiting, buf->pending, buf->list);
+ }
+
+ return buf;
+}
+
+drm_buf_t *drm_freelist_get(drm_freelist_t *bl, int block)
+{
+ drm_buf_t *buf = NULL;
+ DECLARE_WAITQUEUE(entry, current);
+
+ if (!bl || !bl->initialized) return NULL;
+
+ /* Check for low water mark */
+ if (atomic_read(&bl->count) <= bl->low_mark) /* Became low */
+ atomic_set(&bl->wfh, 1);
+ if (atomic_read(&bl->wfh)) {
+ DRM_DEBUG("Block = %d, count = %d, wfh = %d\n",
+ block, atomic_read(&bl->count),
+ atomic_read(&bl->wfh));
+ if (block) {
+ add_wait_queue(&bl->waiting, &entry);
+ current->state = TASK_INTERRUPTIBLE;
+ for (;;) {
+ if (!atomic_read(&bl->wfh)
+ && (buf = drm_freelist_try(bl))) break;
+ schedule();
+ if (signal_pending(current)) break;
+ }
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&bl->waiting, &entry);
+ }
+ return buf;
+ }
+
+ DRM_DEBUG("Count = %d, wfh = %d\n",
+ atomic_read(&bl->count), atomic_read(&bl->wfh));
+ return drm_freelist_try(bl);
+}
+#endif
+
+#if GEN_BUFS_MAIN
+int main(void)
+{
+ drm_waitlist_t bl = { 0, };
+ drm_device_t dev;
+ drm_buf_t buf[10];
+ int i;
+
+ dev.buf_count = 10;
+ for (i = 0; i < 10; i++) buf[i].idx = i;
+
+ drm_waitlist_create(&bl,dev.buf_count);
+ for (i = 0; i < 10; i++) drm_waitlist_put(&bl, &buf[i]);
+ printf("Overflow = %d\n", drm_waitlist_put(&bl, &buf[0]));
+ printf("Overflow = %d\n", drm_waitlist_put(&bl, &buf[0]));
+ for (i = 0; i < 10; i++) drm_waitlist_get(&bl);
+ printf("Underflow = %p\n", drm_waitlist_get(&bl));
+ printf("Underflow = %p\n", drm_waitlist_get(&bl));
+
+ for (i = 0; i < 10; i++) drm_waitlist_put(&bl, &buf[i]);
+ for (i = 0; i < 10; i++) drm_waitlist_get(&bl);
+
+ for (i = 0; i < 5; i++) drm_waitlist_put(&bl, &buf[i]);
+ for (i = 0; i < 2; i++) drm_waitlist_get(&bl);
+ for (i = 5; i < 10; i++) drm_waitlist_put(&bl, &buf[i]);
+ for (i = 2; i < 10; i++) drm_waitlist_get(&bl);
+ drm_waitlist_destroy(&bl);
+ return 0;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_dma.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_dma.c
new file mode 100644
index 000000000..922b24ef6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_dma.c
@@ -0,0 +1,1313 @@
+/* gen_dma.c -- Generic DMA IOCTL and function support -*- linux-c -*-
+ * Created: Fri Mar 19 14:30:16 1999 by faith@dict.org
+ * Revised: Thu Jun 24 15:49:10 1999 by faith@dict.org
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_dma.c,v 1.31 1999/06/24 20:29:42 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_dma.c,v 1.2 1999/06/27 14:08:27 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+
+#include <linux/interrupt.h> /* For task queue support */
+
+#define DRM_ENGINE_VERBOSE 0 /* Make drm_engine trace verbosely */
+
+#if DRM_DEBUG_CODE > 1
+#define CHECK \
+do { \
+ if (++looping > DRM_LOOPING_LIMIT) { \
+ DRM_ERROR("looping = %d, command = %d, inst = %d\n", \
+ looping, command, i/_DRM_INST_LENGTH); \
+ return -EBUSY; \
+ } \
+} while (0)
+#else
+#define CHECK do { } while (0)
+#endif
+
+#define COMPARE(expr) \
+do { \
+ if (expr) i = cmd->inst[i+4] * _DRM_INST_LENGTH; \
+ else i += _DRM_INST_LENGTH; \
+} while (0)
+
+#if DRM_DMA_HISTOGRAM
+ /* This is slow, but is useful for
+ debugging. */
+int drm_histogram_slot(unsigned long count)
+{
+ int value = DRM_DMA_HISTOGRAM_INITIAL;
+ int slot;
+
+ for (slot = 0;
+ slot < DRM_DMA_HISTOGRAM_SLOTS;
+ ++slot, value = DRM_DMA_HISTOGRAM_NEXT(value)) {
+ if (count < value) return slot;
+ }
+ return DRM_DMA_HISTOGRAM_SLOTS - 1;
+}
+
+void drm_histogram_compute(drm_device_t *dev, drm_buf_t *buf)
+{
+ cycles_t queued_to_dispatched;
+ cycles_t dispatched_to_completed;
+ cycles_t completed_to_freed;
+ int q2d, d2c, c2f, q2c, q2f;
+
+ if (buf->time_queued) {
+ queued_to_dispatched = (buf->time_dispatched
+ - buf->time_queued);
+ dispatched_to_completed = (buf->time_completed
+ - buf->time_dispatched);
+ completed_to_freed = (buf->time_freed
+ - buf->time_completed);
+
+ q2d = drm_histogram_slot(queued_to_dispatched);
+ d2c = drm_histogram_slot(dispatched_to_completed);
+ c2f = drm_histogram_slot(completed_to_freed);
+
+ q2c = drm_histogram_slot(queued_to_dispatched
+ + dispatched_to_completed);
+ q2f = drm_histogram_slot(queued_to_dispatched
+ + dispatched_to_completed
+ + completed_to_freed);
+
+ atomic_inc(&dev->histo.total);
+ atomic_inc(&dev->histo.queued_to_dispatched[q2d]);
+ atomic_inc(&dev->histo.dispatched_to_completed[d2c]);
+ atomic_inc(&dev->histo.completed_to_freed[c2f]);
+
+ atomic_inc(&dev->histo.queued_to_completed[q2c]);
+ atomic_inc(&dev->histo.queued_to_freed[q2f]);
+
+ }
+ buf->time_queued = 0;
+ buf->time_dispatched = 0;
+ buf->time_completed = 0;
+ buf->time_freed = 0;
+}
+#endif
+
+void drm_dma_wrapper(void *dev)
+{
+ drm_dma_schedule(dev, 0);
+}
+
+static __inline__ void drm_dma_queue_scheduler(drm_device_t *dev)
+{
+ queue_task(&dev->tq, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+}
+
+void drm_free_buffer(drm_device_t *dev, drm_buf_t *buf)
+{
+ if (!buf) return;
+
+ buf->waiting = 0;
+ buf->pending = 0;
+ buf->pid = 0;
+ buf->used = 0;
+#if DRM_DMA_HISTOGRAM
+ buf->time_completed = get_cycles();
+#endif
+ if (waitqueue_active(&buf->dma_wait)) {
+ wake_up_interruptible(&buf->dma_wait);
+ } else {
+ /* If processes are waiting, the last one
+ to wake will put the buffer on the free
+ list. If no processes are waiting, we
+ put the buffer on the freelist here. */
+ drm_freelist_put(dev, &dev->bufs[buf->order].freelist, buf);
+ }
+}
+
+int drm_free_this_buffer(drm_device_t *dev)
+{
+ if (test_and_set_bit(0, &dev->dma_flag)) {
+ atomic_inc(&dev->total_missed_free);
+ return 1;
+ }
+
+ if (dev->this_buffer) {
+ drm_do_command(dev, _DRM_DMA_READY);
+ drm_free_buffer(dev, dev->this_buffer);
+ dev->this_buffer = NULL;
+ }
+ clear_bit(0, &dev->dma_flag);
+ return 0;
+}
+
+void drm_reclaim_buffers(drm_device_t *dev, pid_t pid)
+{
+ int i;
+
+ for (i = 0; i < dev->buf_count; i++) {
+ if (dev->buflist[i]->pid == pid) {
+ switch (dev->buflist[i]->list) {
+ case DRM_LIST_NONE:
+ drm_free_buffer(dev, dev->buflist[i]);
+ break;
+ case DRM_LIST_WAIT:
+ dev->buflist[i]->list = DRM_LIST_RECLAIM;
+ break;
+ default:
+ /* Nothing to do here, buffer already on
+ hardware. */
+ break;
+ }
+ }
+ }
+}
+
+/* drm_engine executes the script passed from the X server via
+ DRM_IOCTL_CONTROL. For performance reasons, no argument checking is
+ performed. However, we observe that the X server has all of the regions
+ mapped, and that it can write to those regions directly -- there is no
+ violation of the security policy by trusting the information from the X
+ server. */
+
+int drm_engine(drm_device_t *dev,
+ drm_desc_t command,
+ unsigned long address,
+ unsigned long length)
+{
+ int i;
+ unsigned long val;
+ unsigned long accumulator = 0;
+ drm_command_t *cmd = &dev->cmd[command];
+ int retcode = 0;
+#if DRM_DEBUG_CODE > 1
+ int looping = 0;
+#endif
+
+#define BASE ((unsigned long)dev->maplist[cmd->inst[i+1]]->handle)
+#define ADDRESS ((BASE) + cmd->inst[i+2])
+#define DEREF *(__volatile__ int *)ADDRESS
+#define CMD _DRM_E_CMD(cmd->inst[i])
+#define TYPE _DRM_E_TYPE(cmd->inst[i])
+#define MOD _DRM_E_MOD(cmd->inst[i])
+#define MODVAL _DRM_E_MODVAL(cmd->inst[i])
+#define COND _DRM_E_COND(cmd->inst[i])
+
+#if DRM_ENGINE_VERBOSE
+ DRM_TRACE("0x%08lx (0x%08lx bytes); %d instructions for %d\n",
+ address, length, cmd->count, command);
+#endif
+
+ if (!cmd->count || !cmd->inst) return -EINVAL;
+
+ for (i = 0; i < cmd->count * _DRM_INST_LENGTH; /* MUST UPDATE i */) {
+ CHECK;
+ switch (TYPE) {
+ case _DRM_T_LENGTH:
+ val = length;
+ break;
+ case _DRM_T_ADDRESS:
+ val = virt_to_phys((void *)address);
+ break;
+ case _DRM_T_ACC:
+ val = accumulator;
+ break;
+ case _DRM_T_IMM:
+ default:
+ val = cmd->inst[i+3];
+ break;
+ }
+
+ if (MOD == _DRM_V_RSHIFT) val >>= MODVAL;
+ if (MOD == _DRM_V_LSHIFT) val <<= MODVAL;
+
+ switch (CMD) {
+ case _DRM_M_WRITE:
+#if DRM_ENGINE_VERBOSE
+ DRM_VERB(" (%d,0x%04x)=0x%lx <= 0x%08lx\n",
+ cmd->inst[i+1],
+ cmd->inst[i+2],
+ ADDRESS,
+ val);
+#endif
+ DEREF = val;
+ i += _DRM_INST_LENGTH;
+ break;
+ case _DRM_M_READ:
+ accumulator = DEREF;
+ DRM_VERB(" 0x%08lx\n", accumulator);
+ i += _DRM_INST_LENGTH;
+ break;
+ case _DRM_M_WHILE:
+#if DRM_ENGINE_VERBOSE
+ DRM_VERB(" while (%d,0x%04x)=0x%lx %s %lu\n",
+ cmd->inst[i+1],
+ cmd->inst[i+2],
+ ADDRESS,
+ COND == _DRM_C_NE ? "!=" : "?",
+ val);
+#endif
+ switch (COND) {
+ case _DRM_C_EQ: while (DEREF == val) CHECK; break;
+ case _DRM_C_NE: while (DEREF != val) CHECK; break;
+ case _DRM_C_LT: while (DEREF < val) CHECK; break;
+ case _DRM_C_GT: while (DEREF > val) CHECK; break;
+ case _DRM_C_LE: while (DEREF <= val) CHECK; break;
+ case _DRM_C_GE: while (DEREF >= val) CHECK; break;
+ }
+ i += _DRM_INST_LENGTH;
+ break;
+ case _DRM_M_IF:
+#if DRM_ENGINE_VERBOSE
+ DRM_VERB(" if (%d,0x%04x)=0x%lx [%lu %s %u]"
+ " goto %d\n",
+ cmd->inst[i+1],
+ cmd->inst[i+2],
+ ADDRESS,
+ val,
+ COND == _DRM_C_NE ? "!=" : "?",
+ DEREF,
+ cmd->inst[i+4]);
+#endif
+ switch (COND) {
+ case _DRM_C_EQ: COMPARE(DEREF == val); break;
+ case _DRM_C_NE: COMPARE(DEREF != val); break;
+ case _DRM_C_LT: COMPARE(DEREF < val); break;
+ case _DRM_C_GT: COMPARE(DEREF > val); break;
+ case _DRM_C_LE: COMPARE(DEREF <= val); break;
+ case _DRM_C_GE: COMPARE(DEREF >= val); break;
+ case _DRM_C_BIT: COMPARE(DEREF & (1<<val)); break;
+ }
+ break;
+ case _DRM_M_TEST:
+#if DRM_ENGINE_VERBOSE
+ DRM_VERB(" test (%lu) %s %lu goto %d\n",
+ accumulator,
+ COND == _DRM_C_NE ? "!=" : "?",
+ val,
+ cmd->inst[i+4]);
+#endif
+ switch (COND) {
+ case _DRM_C_EQ: COMPARE(accumulator == val); break;
+ case _DRM_C_NE: COMPARE(accumulator != val); break;
+ case _DRM_C_LT: COMPARE(accumulator < val); break;
+ case _DRM_C_GT: COMPARE(accumulator > val); break;
+ case _DRM_C_LE: COMPARE(accumulator <= val); break;
+ case _DRM_C_GE: COMPARE(accumulator >= val); break;
+ case _DRM_C_BIT: COMPARE(accumulator & (1<<val));break;
+ }
+ break;
+ case _DRM_M_GOTO:
+#if DRM_ENGINE_VERBOSE
+ DRM_VERB(" goto %d\n", cmd->inst[i+4]);
+#endif
+ i = cmd->inst[i+4] * _DRM_INST_LENGTH;
+ break;
+ case _DRM_M_NOOP:
+#if DRM_ENGINE_VERBOSE
+ DRM_VERB(" noop\n");
+#endif
+ i += _DRM_INST_LENGTH;
+ break;
+ case _DRM_M_RETURN:
+#if DRM_ENGINE_VERBOSE
+ DRM_VERB(" return %ld\n", val);
+#endif
+ retcode = val;
+ i = cmd->count * _DRM_INST_LENGTH; /* End */
+ break;
+ case _DRM_M_DO:
+#if DRM_ENGINE_VERBOSE
+ DRM_VERB(" do %d\n", cmd->inst[i+4]);
+#endif
+ switch (cmd->inst[i+4]) {
+ case _DRM_F_CLEAR:
+ drm_free_this_buffer(dev);
+ break;
+ case _DRM_F_DMA:
+ drm_dma_queue_scheduler(dev);
+ break;
+ }
+ i += _DRM_INST_LENGTH;
+ break;
+
+
+
+ /* WARNING: If you add any more commands
+ here, be sure to set i to the next
+ instruction value! Otherwise, you will
+ enter an infinite loop. */
+
+ default:
+ DRM_ERROR("Unknown command %d\n", CMD);
+ i += _DRM_INST_LENGTH;
+ break;
+ }
+ }
+#if DRM_ENGINE_VERBOSE
+ DRM_VERB(" exit %d\n", retcode);
+#endif
+ return retcode;
+}
+
+
+int drm_block DRM_IOCTL_ARGS
+{
+ DRM_TRACE("\n");
+ return 0;
+}
+
+int drm_unblock DRM_IOCTL_ARGS
+{
+ DRM_TRACE("\n");
+ return 0;
+}
+
+static void drm_interrupt_handler(int irq, void *dev, struct pt_regs *regs)
+{
+ atomic_inc(&((drm_device_t *)dev)->total_irq);
+ drm_do_command(dev, _DRM_IH_SERVICE);
+}
+
+
+int drm_irq_install(drm_device_t *dev, int irq)
+{
+ int retcode;
+
+ if (!irq) return -EINVAL;
+
+ spin_lock(&dev->struct_lock);
+ if (dev->irq) {
+ spin_unlock(&dev->struct_lock);
+ return -EBUSY;
+ }
+ dev->irq = irq;
+ spin_unlock(&dev->struct_lock);
+
+ DRM_TRACE("%d\n", irq);
+
+ dev->context_flag = 0;
+ dev->interrupt_flag = 0;
+ dev->dma_flag = 0;
+ dev->next_buffer = NULL;
+ dev->next_queue = NULL;
+ dev->this_buffer = NULL;
+
+ dev->tq.next = NULL;
+ dev->tq.sync = 0;
+ dev->tq.routine = drm_dma_wrapper;
+ dev->tq.data = dev;
+
+ drm_do_command(dev, _DRM_IH_PRE_INST); /* Optional */
+ if ((retcode = request_irq(dev->irq,
+ drm_interrupt_handler,
+ 0, // SA_INTERRUPT,
+ dev->devname,
+ dev))) {
+ spin_lock(&dev->struct_lock);
+ dev->irq = 0;
+ spin_unlock(&dev->struct_lock);
+ return retcode;
+ }
+ drm_do_command(dev, _DRM_IH_POST_INST); /* Optional */
+
+ return 0;
+}
+
+int drm_irq_uninstall(drm_device_t *dev)
+{
+ int irq;
+
+ spin_lock(&dev->struct_lock);
+ irq = dev->irq;
+ dev->irq = 0;
+ spin_unlock(&dev->struct_lock);
+
+ if (!irq) return -EINVAL;
+
+ DRM_TRACE("%d\n", irq);
+
+ drm_do_command(dev, _DRM_IH_PRE_UNINST); /* Optional */
+ free_irq(irq, dev);
+ drm_do_command(dev, _DRM_IH_POST_UNINST); /* Optional */
+
+ return 0;
+}
+
+
+int drm_control DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_control_t ctl;
+ drm_command_t *command;
+ int retcode;
+
+ copy_from_user_ret(&ctl, (drm_control_t *)arg, sizeof(ctl), -EFAULT);
+ DRM_TRACE("func = %d\n", ctl.func);
+
+ if (ctl.desc < 0 || ctl.desc >= _DRM_DESC_MAX) {
+ return -EINVAL;
+ }
+ command = &dev->cmd[ctl.desc];
+
+ switch (ctl.func) {
+ case DRM_ADD_COMMAND:
+ if (command->inst) {
+ return -EBUSY;
+ }
+ DRM_DEBUG("count = %d, %d bytes, desc = %d\n",
+ ctl.count,
+ ctl.count
+ * _DRM_INST_LENGTH
+ * sizeof(*command->inst),
+ ctl.desc );
+ command->count = ctl.count;
+ command->inst = drm_alloc(command->count
+ * _DRM_INST_LENGTH
+ * sizeof(*command->inst),
+ DRM_MEM_CMDS);
+ if (copy_from_user(command->inst, ctl.inst,
+ ctl.count
+ * _DRM_INST_LENGTH
+ * sizeof(*command->inst))) {
+ return -EFAULT;
+ }
+ break;
+ case DRM_RM_COMMAND:
+ if (command->inst) {
+ drm_free(command->inst,
+ command->count
+ * _DRM_INST_LENGTH
+ * sizeof(*command->inst),
+ DRM_MEM_CMDS);
+ }
+ command->inst = NULL;
+ command->count = 0;
+ break;
+ case DRM_INST_HANDLER:
+ if ((retcode = drm_irq_install(dev, ctl.irq))) {
+ return retcode;
+ }
+ break;
+ case DRM_UNINST_HANDLER:
+ if ((retcode = drm_irq_uninstall(dev))) {
+ return retcode;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int drm_context_switch(drm_device_t *dev, int old, int new)
+{
+ char buf[64];
+ drm_queue_t *q;
+
+ atomic_inc(&dev->total_ctx);
+
+ if (test_and_set_bit(0, &dev->context_flag)) {
+ DRM_ERROR("Reentering -- FIXME\n");
+ return -EBUSY;
+ }
+
+#if DRM_DMA_HISTOGRAM
+ dev->ctx_start = get_cycles();
+#endif
+
+ DRM_TRACE("Context switch from %d to %d\n", old, new);
+
+ if (new >= dev->queue_count) {
+ clear_bit(0, &dev->context_flag);
+ return -EINVAL;
+ }
+
+ if (new == dev->last_context) {
+ clear_bit(0, &dev->context_flag);
+ return 0;
+ }
+
+ q = dev->queuelist[new];
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) == 1) {
+ atomic_dec(&q->use_count);
+ clear_bit(0, &dev->context_flag);
+ return -EINVAL;
+ }
+
+ if (drm_flags & DRM_FLAG_NOCTX) {
+ drm_context_switch_complete(dev, new);
+ } else {
+ sprintf(buf, "C %d %d\n", old, new);
+ drm_write_string(dev, buf);
+ }
+
+ atomic_dec(&q->use_count);
+
+ return 0;
+}
+
+int drm_context_switch_complete(drm_device_t *dev, int new)
+{
+ dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
+ dev->last_switch = jiffies;
+
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("Lock isn't held after context switch\n");
+ }
+ if (!(dev->next_buffer && dev->next_buffer->while_locked)) {
+ if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ DRM_ERROR("\n");
+ }
+ }
+
+#if DRM_DMA_HISTOGRAM
+ atomic_inc(&dev->histo.ctx[drm_histogram_slot(get_cycles()
+ - dev->ctx_start)]);
+
+#endif
+ clear_bit(0, &dev->context_flag);
+ wake_up_interruptible(&dev->context_wait);
+
+ return 0;
+}
+
+static void drm_clear_next_buffer(drm_device_t *dev)
+{
+ dev->next_buffer = NULL;
+ if (dev->next_queue && !DRM_BUFCOUNT(&dev->next_queue->waitlist)) {
+ wake_up_interruptible(&dev->next_queue->flush_queue);
+ }
+ dev->next_queue = NULL;
+}
+
+
+/* Only called by drm_dma_schedule. */
+int drm_do_dma(drm_device_t *dev, int locked)
+{
+ unsigned long address;
+ unsigned long length;
+ drm_buf_t *buf;
+ int retcode;
+#if DRM_DMA_HISTOGRAM
+ cycles_t dma_start, dma_stop;
+#endif
+
+ DRM_TRACE("\n");
+
+ if (test_and_set_bit(0, &dev->dma_flag)) {
+ atomic_inc(&dev->total_missed_dma);
+ return -EBUSY;
+ }
+
+#if DRM_DMA_HISTOGRAM
+ dma_start = get_cycles();
+#endif
+
+ if (!dev->next_buffer) {
+ DRM_ERROR("No next_buffer\n");
+ clear_bit(0, &dev->dma_flag);
+ return -EINVAL;
+ }
+
+ buf = dev->next_buffer;
+ address = (unsigned long)buf->address;
+ length = buf->used;
+
+ DRM_DEBUG("context %d, buffer %d (%ld bytes)\n",
+ buf->context, buf->idx, length);
+
+ if (buf->list == DRM_LIST_RECLAIM) {
+ drm_clear_next_buffer(dev);
+ drm_free_buffer(dev, buf);
+ clear_bit(0, &dev->dma_flag);
+ return -EINVAL;
+ }
+
+ if (!length) {
+ DRM_ERROR("0 length buffer\n");
+ drm_clear_next_buffer(dev);
+ drm_free_buffer(dev, buf);
+ clear_bit(0, &dev->dma_flag);
+ return 0;
+ }
+
+ if (!drm_do_command(dev, _DRM_DMA_IS_READY)) {
+ clear_bit(0, &dev->dma_flag);
+ return -EBUSY;
+ }
+
+ if (buf->while_locked) {
+ if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+ DRM_ERROR("Dispatching buffer %d from pid %d"
+ " \"while locked\", but no lock held\n",
+ buf->idx, buf->pid);
+ }
+ } else {
+ if (!locked && !drm_lock_take(&dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ atomic_inc(&dev->total_missed_lock);
+ clear_bit(0, &dev->dma_flag);
+ return -EBUSY;
+ }
+ }
+
+ if (dev->last_context != buf->context
+ && !(dev->queuelist[buf->context]->flags
+ & _DRM_CONTEXT_PRESERVED)) {
+ /* PRE: dev->last_context != buf->context */
+ if (drm_context_switch(dev, dev->last_context, buf->context)) {
+ drm_clear_next_buffer(dev);
+ drm_free_buffer(dev, buf);
+ }
+ retcode = -EBUSY;
+ goto cleanup;
+
+ /* POST: we will wait for the context
+ switch and will dispatch on a later call
+ when dev->last_context == buf->context.
+ NOTE WE HOLD THE LOCK THROUGHOUT THIS
+ TIME! */
+ }
+
+ drm_clear_next_buffer(dev);
+ buf->pending = 1;
+ buf->waiting = 0;
+ buf->list = DRM_LIST_PEND;
+#if DRM_DMA_HISTOGRAM
+ buf->time_dispatched = get_cycles();
+#endif
+ if (dev->cmd[_DRM_DMA_DISPATCH].f) {
+ retcode = dev->cmd[_DRM_DMA_DISPATCH].f(dev,
+ _DRM_DMA_DISPATCH,
+ address,
+ length);
+ } else {
+ retcode = drm_engine(dev, _DRM_DMA_DISPATCH, address, length);
+ }
+ drm_free_buffer(dev, dev->this_buffer);
+ dev->this_buffer = buf;
+
+ atomic_add(length, &dev->total_bytes);
+ atomic_inc(&dev->total_dmas);
+
+ if (!buf->while_locked && !dev->context_flag && !locked) {
+ if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ DRM_ERROR("\n");
+ }
+ }
+cleanup:
+
+ clear_bit(0, &dev->dma_flag);
+
+#if DRM_DMA_HISTOGRAM
+ dma_stop = get_cycles();
+ atomic_inc(&dev->histo.dma[drm_histogram_slot(dma_stop - dma_start)]);
+#endif
+
+ return retcode;
+}
+
+static int drm_select_queue(drm_device_t *dev)
+{
+ int i;
+ int candidate = -1;
+ int j = jiffies;
+
+ if (!dev) {
+ DRM_ERROR("No device\n");
+ return -1;
+ }
+ if (!dev->queuelist || !dev->queuelist[DRM_KERNEL_CONTEXT]) {
+ /* This only happens between the time the
+ interrupt is initialized and the time
+ the queues are initialized. */
+ return -1;
+ }
+
+ /* Doing "while locked" DMA? */
+ if (DRM_WAITCOUNT(dev, DRM_KERNEL_CONTEXT)) {
+ return DRM_KERNEL_CONTEXT;
+ }
+
+ /* If there are buffers on the last_context
+ queue, and we have not been executing
+ this context very long, continue to
+ execute this context. */
+ if (dev->last_switch <= j
+ && dev->last_switch + DRM_TIME_SLICE > j
+ && DRM_WAITCOUNT(dev, dev->last_context)) {
+ return dev->last_context;
+ }
+
+ /* Otherwise, find a candidate */
+ for (i = dev->last_checked + 1; i < dev->queue_count; i++) {
+ if (DRM_WAITCOUNT(dev, i)) {
+ candidate = dev->last_checked = i;
+ break;
+ }
+ }
+
+ if (candidate < 0) {
+ for (i = 0; i < dev->queue_count; i++) {
+ if (DRM_WAITCOUNT(dev, i)) {
+ candidate = dev->last_checked = i;
+ break;
+ }
+ }
+ }
+
+ if (candidate >= 0
+ && candidate != dev->last_context
+ && dev->last_switch <= j
+ && dev->last_switch + DRM_TIME_SLICE > j) {
+ if (dev->timer.expires != dev->last_switch + DRM_TIME_SLICE) {
+ del_timer(&dev->timer);
+ dev->timer.expires = dev->last_switch+DRM_TIME_SLICE;
+ add_timer(&dev->timer);
+ }
+ return -1;
+ }
+
+ return candidate;
+}
+
+
+int drm_dma_schedule(drm_device_t *dev, int locked)
+{
+ int next;
+ drm_queue_t *q;
+ drm_buf_t *buf;
+ int retcode = 0;
+ int processed = 0;
+ int missed;
+ int expire = 20;
+#if DRM_DMA_HISTOGRAM
+ cycles_t schedule_start;
+#endif
+
+ if (test_and_set_bit(0, &dev->interrupt_flag)) {
+ /* Not reentrant */
+ atomic_inc(&dev->total_missed_sched);
+ return -EBUSY;
+ }
+ missed = atomic_read(&dev->total_missed_sched);
+
+#if DRM_DMA_HISTOGRAM
+ schedule_start = get_cycles();
+#endif
+
+again:
+ if (dev->context_flag) {
+ clear_bit(0, &dev->interrupt_flag);
+ return -EBUSY;
+ }
+ if (dev->next_buffer) {
+ /* Unsent buffer that was previously
+ selected, but that couldn't be sent
+ because the lock could not be obtained
+ or the DMA engine wasn't ready. Try
+ again. */
+ atomic_inc(&dev->total_tried);
+ if (!(retcode = drm_do_dma(dev, locked))) {
+ atomic_inc(&dev->total_hit);
+ ++processed;
+ }
+ } else {
+ do {
+ next = drm_select_queue(dev);
+ if (next >= 0) {
+ q = dev->queuelist[next];
+ buf = drm_waitlist_get(&q->waitlist);
+ dev->next_buffer = buf;
+ dev->next_queue = q;
+ if (buf && buf->list == DRM_LIST_RECLAIM) {
+ drm_clear_next_buffer(dev);
+ drm_free_buffer(dev, buf);
+ }
+ }
+ } while (next >= 0 && !dev->next_buffer);
+ if (dev->next_buffer) {
+ if (!(retcode = drm_do_dma(dev, locked))) {
+ ++processed;
+ }
+ }
+ }
+
+ if (--expire) {
+ if (missed != atomic_read(&dev->total_missed_sched)) {
+ atomic_inc(&dev->total_lost);
+ if (drm_do_command(dev, _DRM_DMA_IS_READY)) goto again;
+ }
+ if (processed && drm_do_command(dev, _DRM_DMA_IS_READY)) {
+ atomic_inc(&dev->total_lost);
+ processed = 0;
+ goto again;
+ }
+ }
+
+ clear_bit(0, &dev->interrupt_flag);
+
+#if DRM_DMA_HISTOGRAM
+ atomic_inc(&dev->histo.schedule[drm_histogram_slot(get_cycles()
+ - schedule_start)]);
+#endif
+ return retcode;
+}
+
+int drm_dma_enqueue(drm_device_t *dev, drm_dma_t *dma)
+{
+ int i;
+ drm_queue_t *q;
+ drm_buf_t *buf;
+ int idx;
+ int while_locked = 0;
+ DECLARE_WAITQUEUE(entry, current);
+
+ DRM_TRACE("%d\n", dma->send_count);
+
+ if (dma->flags & _DRM_DMA_WHILE_LOCKED) {
+ int context = dev->lock.hw_lock->lock;
+
+ if (!_DRM_LOCK_IS_HELD(context)) {
+ DRM_ERROR("No lock held during \"while locked\""
+ " request\n");
+ return -EINVAL;
+ }
+ if (dma->context != _DRM_LOCKING_CONTEXT(context)
+ && _DRM_LOCKING_CONTEXT(context) != DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("Lock held by %d while %d makes"
+ " \"while locked\" request\n",
+ _DRM_LOCKING_CONTEXT(context),
+ dma->context);
+ return -EINVAL;
+ }
+ q = dev->queuelist[DRM_KERNEL_CONTEXT];
+ while_locked = 1;
+ } else {
+ q = dev->queuelist[dma->context];
+ }
+
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->block_write)) {
+ current->state = TASK_INTERRUPTIBLE;
+ add_wait_queue(&q->write_queue, &entry);
+ atomic_inc(&q->block_count);
+ for (;;) {
+ if (!atomic_read(&q->block_write)) break;
+ schedule();
+ if (signal_pending(current)) {
+ atomic_dec(&q->use_count);
+ return -EINTR;
+ }
+ }
+ atomic_dec(&q->block_count);
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&q->write_queue, &entry);
+ }
+
+ for (i = 0; i < dma->send_count; i++) {
+ idx = dma->send_indices[i];
+ if (idx < 0 || idx >= dev->buf_count) {
+ atomic_dec(&q->use_count);
+ DRM_ERROR("Index %d (of %d max)\n",
+ dma->send_indices[i], dev->buf_count - 1);
+ return -EINVAL;
+ }
+ buf = dev->buflist[ idx ];
+ if (buf->pid != current->pid) {
+ atomic_dec(&q->use_count);
+ DRM_ERROR("Process %d using buffer owned by %d\n",
+ current->pid, buf->pid);
+ return -EINVAL;
+ }
+ if (buf->list != DRM_LIST_NONE) {
+ atomic_dec(&q->use_count);
+ DRM_ERROR("Process %d using buffer %d on list %d\n",
+ current->pid, buf->idx, buf->list);
+ }
+ buf->used = dma->send_sizes[i];
+ buf->while_locked = while_locked;
+ buf->context = dma->context;
+ if (!buf->used) {
+ DRM_ERROR("Queueing 0 length buffer\n");
+ }
+ if (buf->pending) {
+ atomic_dec(&q->use_count);
+ DRM_ERROR("Queueing pending buffer:"
+ " buffer %d, offset %d\n",
+ dma->send_indices[i], i);
+ return -EINVAL;
+ }
+ if (buf->waiting) {
+ atomic_dec(&q->use_count);
+ DRM_ERROR("Queueing waiting buffer:"
+ " buffer %d, offset %d\n",
+ dma->send_indices[i], i);
+ return -EINVAL;
+ }
+ buf->waiting = 1;
+ if (atomic_read(&q->use_count) == 1
+ || atomic_read(&q->finalization)) {
+ drm_free_buffer(dev, buf);
+ } else {
+ drm_waitlist_put(&q->waitlist, buf);
+ atomic_inc(&q->total_queued);
+ }
+ }
+ atomic_dec(&q->use_count);
+
+ return 0;
+}
+
+static int drm_dma_priority(drm_device_t *dev, drm_dma_t *dma)
+{
+ unsigned long address;
+ unsigned long length;
+ int must_free = 0;
+ int retcode = 0;
+ int i;
+ int idx;
+ drm_buf_t *buf;
+ drm_buf_t *last_buf = NULL;
+ DECLARE_WAITQUEUE(entry, current);
+
+ /* Turn off interrupt handling */
+ while (test_and_set_bit(0, &dev->interrupt_flag)) {
+ schedule();
+ if (signal_pending(current)) return -EINTR;
+ }
+ if (!(dma->flags & _DRM_DMA_WHILE_LOCKED)) {
+ while (!drm_lock_take(&dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ schedule();
+ if (signal_pending(current)) {
+ clear_bit(0, &dev->interrupt_flag);
+ return -EINTR;
+ }
+ }
+ ++must_free;
+ }
+ atomic_inc(&dev->total_prio);
+
+ for (i = 0; i < dma->send_count; i++) {
+ idx = dma->send_indices[i];
+ if (idx < 0 || idx >= dev->buf_count) {
+ DRM_ERROR("Index %d (of %d max)\n",
+ dma->send_indices[i], dev->buf_count - 1);
+ continue;
+ }
+ buf = dev->buflist[ idx ];
+ if (buf->pid != current->pid) {
+ DRM_ERROR("Process %d using buffer owned by %d\n",
+ current->pid, buf->pid);
+ retcode = -EINVAL;
+ goto cleanup;
+ }
+ if (buf->list != DRM_LIST_NONE) {
+ DRM_ERROR("Process %d using %d's buffer on list %d\n",
+ current->pid, buf->pid, buf->list);
+ retcode = -EINVAL;
+ goto cleanup;
+ }
+ /* This isn't a race condition on
+ buf->list, since our concern is the
+ buffer reclaim during the time the
+ process closes the /dev/drm? handle, so
+ it can't also be doing DMA. */
+ buf->list = DRM_LIST_PRIO;
+ buf->used = dma->send_sizes[i];
+ buf->context = dma->context;
+ buf->while_locked = dma->flags & _DRM_DMA_WHILE_LOCKED;
+ address = (unsigned long)buf->address;
+ length = buf->used;
+ if (!length) {
+ DRM_ERROR("0 length buffer\n");
+ }
+ if (buf->pending) {
+ DRM_ERROR("Sending pending buffer:"
+ " buffer %d, offset %d\n",
+ dma->send_indices[i], i);
+ retcode = -EINVAL;
+ goto cleanup;
+ }
+ if (buf->waiting) {
+ DRM_ERROR("Sending waiting buffer:"
+ " buffer %d, offset %d\n",
+ dma->send_indices[i], i);
+ retcode = -EINVAL;
+ goto cleanup;
+ }
+ buf->pending = 1;
+
+ if (dev->last_context != buf->context
+ && !(dev->queuelist[buf->context]->flags
+ & _DRM_CONTEXT_PRESERVED)) {
+ add_wait_queue(&dev->context_wait, &entry);
+ current->state = TASK_INTERRUPTIBLE;
+ /* PRE: dev->last_context != buf->context */
+ drm_context_switch(dev, dev->last_context,
+ buf->context);
+ /* POST: we will wait for the context
+ switch and will dispatch on a later call
+ when dev->last_context == buf->context.
+ NOTE WE HOLD THE LOCK THROUGHOUT THIS
+ TIME! */
+ schedule();
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&dev->context_wait, &entry);
+ if (signal_pending(current)) {
+ retcode = -EINTR;
+ goto cleanup;
+ }
+ if (dev->last_context != buf->context) {
+ DRM_ERROR("Context mismatch: %d %d\n",
+ dev->last_context,
+ buf->context);
+ }
+ }
+
+#if DRM_DMA_HISTOGRAM
+ buf->time_queued = get_cycles();
+ buf->time_dispatched = buf->time_queued;
+#endif
+ if (dev->cmd[_DRM_DMA_DISPATCH].f) {
+ retcode = dev
+ ->cmd[_DRM_DMA_DISPATCH].f(dev,
+ _DRM_DMA_DISPATCH,
+ address,
+ length);
+ } else {
+ retcode = drm_engine(dev, _DRM_DMA_DISPATCH,
+ address, length);
+ }
+ atomic_add(length, &dev->total_bytes);
+ atomic_inc(&dev->total_dmas);
+
+ if (last_buf) {
+ drm_free_buffer(dev, last_buf);
+ }
+ last_buf = buf;
+ }
+
+
+cleanup:
+ if (last_buf) {
+ drm_do_command(dev, _DRM_DMA_READY);
+ drm_free_buffer(dev, last_buf);
+ }
+
+ if (must_free && !dev->context_flag) {
+ if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ DRM_ERROR("\n");
+ }
+ }
+ clear_bit(0, &dev->interrupt_flag);
+ return retcode;
+}
+
+static int drm_dma_send_buffers(drm_device_t *dev, drm_dma_t *dma)
+{
+ DECLARE_WAITQUEUE(entry, current);
+ drm_buf_t *last_buf = NULL;
+ int retcode = 0;
+
+ if (dma->flags & _DRM_DMA_BLOCK) {
+ last_buf = dev->buflist[dma->send_indices[dma->send_count-1]];
+ add_wait_queue(&last_buf->dma_wait, &entry);
+ }
+
+ if ((retcode = drm_dma_enqueue(dev, dma))) {
+ if (dma->flags & _DRM_DMA_BLOCK)
+ remove_wait_queue(&last_buf->dma_wait, &entry);
+ return retcode;
+ }
+
+ drm_dma_schedule(dev, 0);
+
+ if (dma->flags & _DRM_DMA_BLOCK) {
+ DRM_DEBUG("%d waiting\n", current->pid);
+ current->state = TASK_INTERRUPTIBLE;
+ for (;;) {
+ if (!last_buf->waiting
+ && !last_buf->pending)
+ break; /* finished */
+ schedule();
+ if (signal_pending(current)) {
+ /* We can't handle a restart of a
+ DMA request, since we have no
+ idea if it has finished or
+ not. */
+ retcode = -EINTR;
+ break;
+ }
+ }
+ current->state = TASK_RUNNING;
+ DRM_DEBUG("%d running\n", current->pid);
+ remove_wait_queue(&last_buf->dma_wait, &entry);
+ if (!retcode
+ || (last_buf->list==DRM_LIST_PEND && !last_buf->pending)) {
+ if (!waitqueue_active(&last_buf->dma_wait)) {
+ drm_free_buffer(dev, last_buf);
+ }
+ }
+ if (retcode) {
+ DRM_ERROR("ctx%d w%d p%d c%d i%d l%d %d/%d\n",
+ dma->context,
+ last_buf->waiting,
+ last_buf->pending,
+ DRM_WAITCOUNT(dev, dma->context),
+ last_buf->idx,
+ last_buf->list,
+ last_buf->pid,
+ current->pid);
+ }
+ }
+ return retcode;
+}
+
+static int drm_dma_get_buffers_of_order(drm_device_t *dev, drm_dma_t *dma,
+ int order)
+{
+ int i;
+ drm_buf_t *buf;
+
+ for (i = dma->granted_count; i < dma->request_count; i++) {
+ buf = drm_freelist_get(&dev->bufs[order].freelist,
+ dma->flags & _DRM_DMA_WAIT);
+ if (!buf) break;
+ if (buf->pending || buf->waiting) {
+ DRM_ERROR("Free buffer %d in use by %d (w%d, p%d)\n",
+ buf->idx,
+ buf->pid,
+ buf->waiting,
+ buf->pending);
+ }
+ buf->pid = current->pid;
+ copy_to_user_ret(&dma->request_indices[i],
+ &buf->idx,
+ sizeof(buf->idx),
+ -EFAULT);
+ copy_to_user_ret(&dma->request_sizes[i],
+ &buf->total,
+ sizeof(buf->total),
+ -EFAULT);
+ ++dma->granted_count;
+ }
+ return 0;
+}
+
+
+static int drm_dma_get_buffers(drm_device_t *dev, drm_dma_t *dma)
+{
+ int order;
+ int retcode = 0;
+ int tmp_order;
+
+ order = drm_order(dma->request_size);
+
+ dma->granted_count = 0;
+ retcode = drm_dma_get_buffers_of_order(dev, dma, order);
+
+ if (dma->granted_count < dma->request_count
+ && (dma->flags & _DRM_DMA_SMALLER_OK)) {
+ for (tmp_order = order - 1;
+ !retcode
+ && dma->granted_count < dma->request_count
+ && tmp_order >= DRM_MIN_ORDER;
+ --tmp_order) {
+
+ retcode = drm_dma_get_buffers_of_order(dev, dma,
+ tmp_order);
+ }
+ }
+
+ if (dma->granted_count < dma->request_count
+ && (dma->flags & _DRM_DMA_LARGER_OK)) {
+ for (tmp_order = order + 1;
+ !retcode
+ && dma->granted_count < dma->request_count
+ && tmp_order <= DRM_MAX_ORDER;
+ ++tmp_order) {
+
+ retcode = drm_dma_get_buffers_of_order(dev, dma,
+ tmp_order);
+ }
+ }
+ return 0;
+}
+
+int drm_dma DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ int retcode = 0;
+ drm_dma_t dma;
+
+ copy_from_user_ret(&dma, (drm_dma_t *)arg, sizeof(dma), -EFAULT);
+ DRM_DEBUG("%d %d: %d send, %d req\n",
+ current->pid, dma.context, dma.send_count,
+ dma.request_count);
+
+ if (dma.context == DRM_KERNEL_CONTEXT
+ || dma.context >= dev->queue_slots) {
+ DRM_ERROR("Process %d using context %d\n",
+ current->pid, dma.context);
+ return -EINVAL;
+ }
+ if (dma.send_count < 0 || dma.send_count > dev->buf_count) {
+ DRM_ERROR("Process %d trying to send %d buffers (of %d max)\n",
+ current->pid, dma.send_count, dev->buf_count);
+ return -EINVAL;
+ }
+ if (dma.request_count < 0 || dma.request_count > dev->buf_count) {
+ DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
+ current->pid, dma.request_count, dev->buf_count);
+ return -EINVAL;
+ }
+
+ if (dma.send_count) {
+ if (dma.flags & _DRM_DMA_PRIORITY)
+ retcode = drm_dma_priority(dev, &dma);
+ else
+ retcode = drm_dma_send_buffers(dev, &dma);
+ }
+
+ dma.granted_count = 0;
+
+ if (!retcode && dma.request_count) {
+ retcode = drm_dma_get_buffers(dev, &dma);
+ }
+
+ DRM_DEBUG("%d returning, granted = %d\n",
+ current->pid, dma.granted_count);
+ copy_to_user_ret((drm_dma_t *)arg, &dma, sizeof(dma), -EFAULT);
+
+ return retcode;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_ioctl.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_ioctl.c
new file mode 100644
index 000000000..7cd3ea2ad
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_ioctl.c
@@ -0,0 +1,1374 @@
+/* gen_ioctl.c -- Generic IOCTL and function support -*- linux-c -*-
+ * Created: Tue Feb 2 08:37:54 1999 by faith@precisioninsight.com
+ * Revised: Fri Jun 25 09:05:55 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_ioctl.c,v 1.44 1999/06/25 13:06:07 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_ioctl.c,v 1.2 1999/06/27 14:08:27 dawes Exp $
+ *
+ */
+
+#define __NO_VERSION__
+#include "drmP.h"
+#include "linux/un.h"
+
+static int drm_gen_registered;
+
+int drm_order(unsigned long size)
+{
+ int order;
+ unsigned long tmp;
+
+ /* FIXME: This can be made much faster.
+ Algorithms are posted on occassion to
+ comp.lang.c.moderated, but the
+ optimization usually depends on assuming
+ a certain word length. */
+ for (order = 0, tmp = size; tmp >>= 1; ++order);
+ if (size & ~(1 << order)) ++order;
+ return order;
+}
+
+static int drm_hash_magic(drm_magic_t magic)
+{
+ return magic & (DRM_HASH_SIZE-1);
+}
+
+static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
+{
+ drm_file_t *retval = NULL;
+ drm_magic_entry_t *pt;
+ int hash = drm_hash_magic(magic);
+
+ spin_lock(&dev->struct_lock);
+ for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
+ if (pt->priv->auth != DRM_AUTH_PENDING) continue;
+ if (pt->magic == magic) {
+ retval = pt->priv;
+ break;
+ }
+ }
+ spin_unlock(&dev->struct_lock);
+ return retval;
+}
+
+int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
+{
+ int hash;
+ drm_magic_entry_t *entry;
+
+ DRM_TRACE("%d\n", magic);
+
+ hash = drm_hash_magic(magic);
+ entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC);
+ if (!entry) return -ENOMEM;
+ entry->magic = magic;
+ entry->priv = priv;
+ entry->next = NULL;
+
+ spin_lock(&dev->struct_lock);
+ if (dev->magiclist[hash].tail) {
+ dev->magiclist[hash].tail->next = entry;
+ dev->magiclist[hash].tail = entry;
+ } else {
+ dev->magiclist[hash].head = entry;
+ dev->magiclist[hash].tail = entry;
+ }
+ spin_unlock(&dev->struct_lock);
+
+ return 0;
+}
+
+int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
+{
+ drm_magic_entry_t *prev = NULL;
+ drm_magic_entry_t *pt;
+ int hash;
+
+ DRM_TRACE("%d\n", magic);
+ hash = drm_hash_magic(magic);
+
+ spin_lock(&dev->struct_lock);
+ for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) {
+ if (pt->magic == magic) {
+ if (dev->magiclist[hash].head == pt) {
+ dev->magiclist[hash].head = pt->next;
+ }
+ if (dev->magiclist[hash].tail == pt) {
+ dev->magiclist[hash].tail = prev;
+ }
+ if (prev) {
+ prev->next = pt->next;
+ }
+ spin_unlock(&dev->struct_lock);
+ return 0;
+ }
+ }
+ spin_unlock(&dev->struct_lock);
+
+ drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
+
+ return -EINVAL;
+}
+
+int drm_getmagic DRM_IOCTL_ARGS
+{
+ static drm_magic_t sequence = 0;
+ static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_auth_t auth;
+
+ /* Find unique magic */
+ if (priv->magic) {
+ auth.magic = priv->magic;
+ } else {
+ spin_lock(&lock);
+ do {
+ if (!sequence) ++sequence; /* reserve 0 */
+ auth.magic = sequence++;
+ } while (drm_find_file(dev, auth.magic));
+ spin_unlock(&lock);
+ priv->magic = auth.magic;
+ drm_add_magic(dev, priv, auth.magic);
+ }
+
+ DRM_TRACE("%u\n", auth.magic);
+ copy_to_user_ret((drm_auth_t *)arg, &auth, sizeof(auth), -EFAULT);
+ return 0;
+}
+
+int drm_authmagic DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_auth_t auth;
+ drm_file_t *file;
+
+ copy_from_user_ret(&auth, (drm_auth_t *)arg, sizeof(auth), -EFAULT);
+ DRM_TRACE("%u\n", auth.magic);
+ if ((file = drm_find_file(dev, auth.magic))) {
+ file->auth = DRM_AUTH_OK;
+ drm_remove_magic(dev, auth.magic);
+ return 0;
+ }
+ return -EINVAL;
+}
+
+int drm_addmap DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_map_t *map;
+
+ DRM_TRACE("TASK_SIZE = 0x%08lx, f_mode = %x\n",
+ TASK_SIZE, filp->f_mode);
+
+ if (!(filp->f_mode & 3)) return -EACCES; /* Require read/write */
+
+ map = drm_alloc(sizeof(*map), DRM_MEM_MAPS);
+ if (!map) return -ENOMEM;
+ if (copy_from_user(map, (drm_map_t *)arg, sizeof(*map))) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ return -EFAULT;
+ }
+
+ /* For now, we'll reject non-page-aligned
+ requests. If this is a problem, we can
+ do some rounding later. */
+ DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n",
+ map->offset, map->size, map->type);
+ if ((map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK))) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ return -EINVAL;
+ }
+ map->mtrr = -1;
+ map->handle = 0;
+
+ switch (map->type) {
+ case _DRM_REGISTERS:
+ case _DRM_FRAME_BUFFER:
+ /* Allow the client to mmap the frame
+ buffer.
+
+ We must provide this mechanism for the
+ client to access the frame buffer and
+ registers because the client is not
+ running as root, and cannot perform a
+ mmap on /dev/mem (in contrast to the X
+ server).
+
+ Registers must be uncached, so we must
+ set the PCD attribute on the page to 1.
+ But some architectures might want
+ write-combining for fast MMIO access.
+
+ Should we allow mappings in the area
+ 0xa0000-0xc0000? Currently we don't,
+ although this may be necessary for some
+ cards. */
+
+ if (map->offset + map->size < map->offset
+ || map->offset < virt_to_phys(high_memory)) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ return -EINVAL;
+ }
+#ifdef CONFIG_MTRR
+ /* Try to make the frame buffer use a
+ write-combinging policy. For this to
+ work, we have to make sure that the PCD
+ and PWT atttributes for the page are not
+ both 1. We'd like to set them both to
+ 0. See 11.5.1 (Precedence of Cache
+ Controls) of Intel's Pentium Pro Family
+ Developer's Manual (Volume 3: Operating
+ System Writer's Manual), 1996, pp. 11-8
+ to 11-10. */
+
+ if (map->type == _DRM_FRAME_BUFFER
+ || (map->flags & _DRM_WRITE_COMBINING)) {
+ map->mtrr = mtrr_add(map->offset, map->size,
+ MTRR_TYPE_WRCOMB, 1);
+ }
+#endif
+ map->handle = drm_ioremap(map->offset, map->size);
+ break;
+
+
+ case _DRM_SHM:
+ /* Create a shared memory mapping between
+ DR clients.
+
+ Why don't we just have the X server and
+ the clients use shm* calls? Because
+ shm* only supports uid/gid-based access.
+ Consider that an X server may have
+ connections from clients with different
+ uids and gids. To allow these clients
+ to access the SAREA, the permissions on
+ the shm segment would have to allow
+ connections from _any_ uid. The problem
+ is that this would allow a rogue
+ process, _without_ a connection to the X
+ server, to do a shmat(2) on the segment
+ and to corrupt or destory the
+ information in the segment.
+
+ By using ioctl and mmap calls on the
+ /dev/drm* devices, we ensure that only
+ processes with an existing connection to
+ the X server can access the SAREA. This
+ is required so that a rogue client is
+ prevented from circumventing standard X
+ authentication mechanisms. */
+
+ /* Right now, we assume DRM_KERNEL is set.
+ However, in the future, we may make a
+ decision on where to map the memory
+ based on the value of DRM_KERNEL. */
+ if (!(map->handle = drm_vmalloc(map->size))) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ return -ENOMEM;
+ }
+ map->offset = (unsigned long)map->handle;
+ if (map->flags & _DRM_CONTAINS_LOCK) {
+ dev->lock.hw_lock = map->handle; /* Pointer to lock */
+ }
+ break;
+ default:
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+ return -EINVAL;
+ }
+
+ spin_lock(&dev->struct_lock);
+ if (dev->maplist) {
+ ++dev->map_count;
+ dev->maplist = drm_realloc(dev->maplist,
+ (dev->map_count-1)
+ * sizeof(*dev->maplist),
+ dev->map_count
+ * sizeof(*dev->maplist),
+ DRM_MEM_MAPS);
+ } else {
+ dev->map_count = 1;
+ dev->maplist = drm_alloc(dev->map_count*sizeof(*dev->maplist),
+ DRM_MEM_MAPS);
+ }
+ dev->maplist[dev->map_count-1] = map;
+ spin_unlock(&dev->struct_lock);
+
+ copy_to_user_ret((drm_map_t *)arg, map, sizeof(*map), -EFAULT);
+ if (map->type != _DRM_SHM) {
+ /* Hide kernel-virtual address */
+ copy_to_user_ret(&((drm_map_t *)arg)->handle,
+ &map->offset,
+ sizeof(map->offset),
+ -EFAULT);
+ }
+ return 0;
+}
+
+int drm_addbufs DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_buf_desc_t request;
+ int count;
+ int order;
+ int size;
+ int total;
+ int page_order;
+ drm_buf_entry_t *entry;
+ unsigned long page;
+ drm_buf_t *buf;
+ int alignment;
+ unsigned long offset;
+ int i;
+ int byte_count;
+ int page_count;
+
+ copy_from_user_ret(&request,
+ (drm_buf_desc_t *)arg,
+ sizeof(request),
+ -EFAULT);
+
+ count = request.count;
+ order = drm_order(request.size);
+ size = 1 << order;
+
+ DRM_TRACE("count = %d, size = %d (%d), order = %d, queue_count = %d\n",
+ request.count, request.size, size, order, dev->queue_count);
+
+ if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
+ if (dev->queue_count) return -EBUSY; /* Not while in use */
+
+ alignment = (request.flags & DRM_PAGE_ALIGN) ? PAGE_ALIGN(size) :size;
+ page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
+ total = PAGE_SIZE << page_order;
+
+ spin_lock(&dev->count_lock);
+ if (dev->buf_use) {
+ spin_unlock(&dev->count_lock);
+ return -EBUSY;
+ }
+ atomic_inc(&dev->buf_alloc);
+ spin_unlock(&dev->count_lock);
+
+ spin_lock(&dev->struct_lock);
+ entry = &dev->bufs[order];
+ if (entry->buf_count) {
+ spin_unlock(&dev->struct_lock);
+ atomic_dec(&dev->buf_alloc);
+ return -ENOMEM; /* May only call once for each order */
+ }
+
+ entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
+ DRM_MEM_BUFS);
+ if (!entry->buflist) {
+ spin_unlock(&dev->struct_lock);
+ atomic_dec(&dev->buf_alloc);
+ return -ENOMEM;
+ }
+ memset(entry->buflist, 0, count * sizeof(*entry->buflist));
+
+ entry->seglist = drm_alloc(count * sizeof(*entry->seglist),
+ DRM_MEM_SEGS);
+ if (!entry->seglist) {
+ drm_free(entry->buflist,
+ sizeof(*entry->buflist),
+ DRM_MEM_BUFS);
+ spin_unlock(&dev->struct_lock);
+ atomic_dec(&dev->buf_alloc);
+ return -ENOMEM;
+ }
+ memset(entry->seglist, 0, count * sizeof(*entry->seglist));
+
+
+ /* We need a sequential list of pages to
+ service the nopage call to "fault" the
+ physical pages into user-virtual memory
+ when they are first accessed. We make
+ this list grow with each call since its
+ final length cannot be predetermined.
+ Allocate before the next loop, since we
+ have to fill in this information on the
+ fly. Our estimate for the length of
+ this list is probably too high, but we
+ cannot do better at this time, since we
+ cannot predict how much memory the
+ kernel will give to us.*/
+ dev->pagelist = drm_realloc(dev->pagelist,
+ dev->page_count * sizeof(*dev->pagelist),
+ (dev->page_count + (count << page_order))
+ * sizeof(*dev->pagelist),
+ DRM_MEM_PAGES);
+ DRM_DEBUG("pagelist: %d entries\n",
+ dev->page_count + (count << page_order));
+
+
+ /* This is the main loop to allocate the
+ segments of contiguous pages. */
+ entry->buf_size = size;
+ entry->page_order = page_order;
+ byte_count = 0;
+ page_count = 0;
+ while (entry->buf_count < count) {
+ if (!(page = drm_alloc_dma(page_order))) break;
+ entry->seglist[entry->seg_count++] = page;
+ for (i = 0; i < (1 << page_order); i++) {
+ DRM_VERB("page %d @ 0x%08lx\n",
+ dev->page_count + page_count,
+ page + PAGE_SIZE * i);
+ dev->pagelist[dev->page_count + page_count++]
+ = page + PAGE_SIZE * i;
+ }
+ for (offset = 0;
+ offset + size <= total && entry->buf_count < count;
+ offset += alignment, ++entry->buf_count) {
+ buf = &entry->buflist[entry->buf_count];
+ buf->idx = dev->buf_count + entry->buf_count;
+ buf->total = alignment;
+ buf->order = order;
+ buf->used = 0;
+ buf->offset = (dev->byte_count + byte_count + offset);
+ buf->address = (void *)(page + offset);
+ buf->next = NULL;
+ buf->waiting = 0;
+ buf->pending = 0;
+ init_waitqueue_head(&buf->dma_wait);
+ buf->pid = 0;
+#if DRM_DMA_HISTOGRAM
+ buf->time_queued = 0;
+ buf->time_dispatched = 0;
+ buf->time_completed = 0;
+ buf->time_freed = 0;
+#endif
+
+ DRM_VERB("buffer %d @ %p\n",
+ entry->buf_count, buf->address);
+ }
+ byte_count += PAGE_SIZE << page_order;
+ }
+
+ /* We need a sequential list of buffer
+ pointers in dev->buflist so that we can
+ have the fastest access time when
+ dispatching DMA buffers. We make this
+ list grow with each call since its final
+ length cannot be predetermined.
+ Allocate after the above loop, since we
+ have an exact count of the number of
+ buffers used. */
+ dev->buflist = drm_realloc(dev->buflist,
+ dev->buf_count * sizeof(*dev->buflist),
+ (dev->buf_count + entry->buf_count)
+ * sizeof(*dev->buflist),
+ DRM_MEM_BUFS);
+ for (i = dev->buf_count; i < dev->buf_count + entry->buf_count; i++)
+ dev->buflist[i] = &entry->buflist[i - dev->buf_count];
+
+ DRM_VERB("%u =? %u\n", page_count, entry->seg_count << page_order);
+
+ dev->buf_count += entry->buf_count;
+ dev->seg_count += entry->seg_count;
+ dev->page_count += entry->seg_count << page_order;
+ dev->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
+
+ drm_freelist_create(&entry->freelist, entry->buf_count);
+ for (i = 0; i < entry->buf_count; i++) {
+ drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]);
+ }
+
+ spin_unlock(&dev->struct_lock);
+
+ request.count = entry->buf_count;
+ request.size = size;
+
+ copy_to_user_ret((drm_buf_desc_t *)arg,
+ &request,
+ sizeof(request),
+ -EFAULT);
+
+ atomic_dec(&dev->buf_alloc);
+ return 0;
+}
+
+int drm_infobufs DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_buf_info_t request;
+ int i;
+ int count;
+
+ spin_lock(&dev->count_lock);
+ if (atomic_read(&dev->buf_alloc)) {
+ spin_unlock(&dev->count_lock);
+ return -EBUSY;
+ }
+ ++dev->buf_use; /* Can't allocate more after this call */
+ spin_unlock(&dev->count_lock);
+
+ copy_from_user_ret(&request,
+ (drm_buf_info_t *)arg,
+ sizeof(request),
+ -EFAULT);
+
+ for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
+ if (dev->bufs[i].buf_count) ++count;
+ }
+
+ DRM_TRACE("count = %d\n", count);
+
+ if (request.count >= count) {
+ for (i = 0, count = 0; i < DRM_MAX_ORDER+1; i++) {
+ if (dev->bufs[i].buf_count) {
+ copy_to_user_ret(&request.list[count].count,
+ &dev->bufs[i].buf_count,
+ sizeof(dev->bufs[0]
+ .buf_count),
+ -EFAULT);
+ copy_to_user_ret(&request.list[count].size,
+ &dev->bufs[i].buf_size,
+ sizeof(dev->bufs[0].buf_size),
+ -EFAULT);
+ copy_to_user_ret(&request.list[count].low_mark,
+ &dev->bufs[i]
+ .freelist.low_mark,
+ sizeof(dev->bufs[0]
+ .freelist.low_mark),
+ -EFAULT);
+ copy_to_user_ret(&request.list[count]
+ .high_mark,
+ &dev->bufs[i]
+ .freelist.high_mark,
+ sizeof(dev->bufs[0]
+ .freelist.high_mark),
+ -EFAULT);
+ DRM_DEBUG("%d %d %d %d %d\n",
+ i,
+ dev->bufs[i].buf_count,
+ dev->bufs[i].buf_size,
+ dev->bufs[i].freelist.low_mark,
+ dev->bufs[i].freelist.high_mark);
+ ++count;
+ }
+ }
+ }
+ request.count = count;
+
+ copy_to_user_ret((drm_buf_info_t *)arg,
+ &request,
+ sizeof(request),
+ -EFAULT);
+
+ return 0;
+}
+
+int drm_markbufs DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_buf_desc_t request;
+ int order;
+ drm_buf_entry_t *entry;
+
+ copy_from_user_ret(&request,
+ (drm_buf_desc_t *)arg,
+ sizeof(request),
+ -EFAULT);
+
+ DRM_TRACE("%d, %d, %d\n",
+ request.size, request.low_mark, request.high_mark);
+ order = drm_order(request.size);
+ if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL;
+ entry = &dev->bufs[order];
+
+ if (request.low_mark < 0 || request.low_mark > entry->buf_count)
+ return -EINVAL;
+ if (request.high_mark < 0 || request.high_mark > entry->buf_count)
+ return -EINVAL;
+
+ entry->freelist.low_mark = request.low_mark;
+ entry->freelist.high_mark = request.high_mark;
+
+ return 0;
+}
+
+int drm_freebufs DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_buf_free_t request;
+ int i;
+ int idx;
+ drm_buf_t *buf;
+
+ copy_from_user_ret(&request,
+ (drm_buf_free_t *)arg,
+ sizeof(request),
+ -EFAULT);
+
+ DRM_TRACE("%d\n", request.count);
+ for (i = 0; i < request.count; i++) {
+ copy_from_user_ret(&idx,
+ &request.list[i],
+ sizeof(idx),
+ -EFAULT);
+ if (idx < 0 || idx >= dev->buf_count) {
+ DRM_ERROR("Index %d (of %d max)\n",
+ idx, dev->buf_count - 1);
+ return -EINVAL;
+ }
+ buf = dev->buflist[idx];
+ if (buf->pid != current->pid) {
+ DRM_ERROR("Process %d freeing buffer owned by %d\n",
+ current->pid, buf->pid);
+ return -EINVAL;
+ }
+ drm_free_buffer(dev, buf);
+ }
+
+ return 0;
+}
+
+int drm_mapbufs DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ int retcode = 0;
+ const int zero = 0;
+ unsigned long virtual;
+ unsigned long address;
+ drm_buf_map_t request;
+ int i;
+
+ DRM_TRACE("\n");
+
+ spin_lock(&dev->count_lock);
+ if (atomic_read(&dev->buf_alloc)) {
+ spin_unlock(&dev->count_lock);
+ return -EBUSY;
+ }
+ ++dev->buf_use; /* Can't allocate more after this call */
+ spin_unlock(&dev->count_lock);
+
+ copy_from_user_ret(&request,
+ (drm_buf_map_t *)arg,
+ sizeof(request),
+ -EFAULT);
+
+ if (request.count >= dev->buf_count) {
+ virtual = do_mmap(filp, 0, dev->byte_count,
+ PROT_READ|PROT_WRITE, MAP_SHARED, 0);
+ if (virtual > -1024UL) {
+ /* Real error */
+ retcode = (signed long)virtual;
+ goto done;
+ }
+ request.virtual = (void *)virtual;
+
+ for (i = 0; i < dev->buf_count; i++) {
+ if (copy_to_user(&request.list[i].idx,
+ &dev->buflist[i]->idx,
+ sizeof(request.list[0].idx))) {
+ retcode = -EFAULT;
+ goto done;
+ }
+ if (copy_to_user(&request.list[i].total,
+ &dev->buflist[i]->total,
+ sizeof(request.list[0].total))) {
+ retcode = -EFAULT;
+ goto done;
+ }
+ if (copy_to_user(&request.list[i].used,
+ &zero,
+ sizeof(zero))) {
+ retcode = -EFAULT;
+ goto done;
+ }
+ address = virtual + dev->buflist[i]->offset;
+ if (copy_to_user(&request.list[i].address,
+ &address,
+ sizeof(address))) {
+ retcode = -EFAULT;
+ goto done;
+ }
+ }
+ }
+done:
+ request.count = dev->buf_count;
+ DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode);
+
+ copy_to_user_ret((drm_buf_map_t *)arg,
+ &request,
+ sizeof(request),
+ -EFAULT);
+
+ return retcode;
+}
+
+int drm_reg( void )
+{
+ DRM_TRACE("\n");
+ if (drm_gen_registered) return -EBUSY;
+ ++drm_gen_registered;
+ return 0;
+}
+
+int drm_unreg( void )
+{
+ DRM_TRACE("\n");
+ if (!drm_gen_registered) return -EBUSY;
+ --drm_gen_registered;
+ return 0;
+}
+
+int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
+{
+ unsigned int old;
+ unsigned int new;
+ char failed;
+
+ DRM_TRACE("%d attempts\n", context);
+ do {
+ old = *lock;
+ if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
+ else new = context | _DRM_LOCK_HELD;
+ _DRM_CAS(lock, old, new, failed);
+ } while (failed);
+ if (_DRM_LOCKING_CONTEXT(old) == context) {
+ if (old & _DRM_LOCK_HELD) {
+ if (context != DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("%d holds heavyweight lock\n",
+ context);
+ }
+ return 0;
+ }
+ }
+ if (new == (context | _DRM_LOCK_HELD)) {
+ /* Have lock */
+ DRM_LOCK_VERB("%d\n", context);
+ return 1;
+ }
+ DRM_LOCK_VERB("%d unable to get lock held by %d\n",
+ context, _DRM_LOCKING_CONTEXT(old));
+ return 0;
+}
+
+/* This takes a lock forcibly and hands it to context. Should ONLY be used
+ inside drm_unlock to give lock to kernel before calling
+ drm_dma_schedule. */
+static int drm_lock_transfer(__volatile__ unsigned int *lock,
+ unsigned int context)
+{
+ unsigned int old;
+ unsigned int new;
+ char failed;
+
+ do {
+ old = *lock;
+ new = context | _DRM_LOCK_HELD;
+ _DRM_CAS(lock, old, new, failed);
+ } while (failed);
+ DRM_LOCK_VERB("%d => %d\n", _DRM_LOCKING_CONTEXT(old), context);
+ return 1;
+}
+
+int drm_lock_free(drm_device_t *dev,
+ __volatile__ unsigned int *lock, unsigned int context)
+{
+ unsigned int old;
+ unsigned int new;
+ char failed;
+
+ DRM_TRACE("%d\n", context);
+ do {
+ old = *lock;
+ new = 0;
+ _DRM_CAS(lock, old, new, failed);
+ } while (failed);
+ if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
+ DRM_ERROR("%d freed heavyweight lock held by %d\n",
+ context,
+ _DRM_LOCKING_CONTEXT(old));
+ return 1;
+ }
+ dev->lock.pid = 0;
+ wake_up_interruptible(&dev->lock.lock_queue);
+ return 0;
+}
+
+static int drm_flush_queue(drm_device_t *dev, int context)
+{
+ DECLARE_WAITQUEUE(entry, current);
+ int ret = 0;
+ drm_queue_t *q = dev->queuelist[context];
+
+ DRM_TRACE("\n");
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) > 1) {
+ atomic_inc(&q->block_write);
+ current->state = TASK_INTERRUPTIBLE;
+ add_wait_queue(&q->flush_queue, &entry);
+ atomic_inc(&q->block_count);
+ for (;;) {
+ if (!DRM_BUFCOUNT(&q->waitlist)) break;
+ schedule();
+ if (signal_pending(current)) {
+ /* This returns -EINTR instead of
+ -ERESTARTSYS so that we can control-c
+ out of the server. */
+ ret = -EINTR;
+ break;
+ }
+ }
+ atomic_dec(&q->block_count);
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&q->flush_queue, &entry);
+ }
+ atomic_dec(&q->use_count);
+ atomic_inc(&q->total_flushed);
+
+ /* NOTE: block_write is still incremented!
+ Use drm_flush_unlock_queue to decrement. */
+ return ret;
+}
+
+static int drm_flush_unblock_queue(drm_device_t *dev, int context)
+{
+ drm_queue_t *q = dev->queuelist[context];
+
+ DRM_TRACE("\n");
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) > 1) {
+ if (atomic_read(&q->block_write)) {
+ atomic_dec(&q->block_write);
+ wake_up_interruptible(&q->write_queue);
+ }
+ }
+ atomic_dec(&q->use_count);
+ return 0;
+}
+
+static int drm_flush_block_and_flush(drm_device_t *dev, int context,
+ drm_lock_flags_t flags)
+{
+ int ret = 0;
+ int i;
+
+ DRM_TRACE("\n");
+
+ if (flags & _DRM_LOCK_FLUSH) {
+ ret = drm_flush_queue(dev, DRM_KERNEL_CONTEXT);
+ if (!ret) ret = drm_flush_queue(dev, context);
+ }
+ if (flags & _DRM_LOCK_FLUSH_ALL) {
+ read_lock(&dev->queue_lock);
+ for (i = 0; !ret && i < dev->queue_count; i++) {
+ ret = drm_flush_queue(dev, i);
+ }
+ read_unlock(&dev->queue_lock);
+ }
+ return ret;
+}
+
+static int drm_flush_unblock(drm_device_t *dev, int context,
+ drm_lock_flags_t flags)
+{
+ int ret = 0;
+ int i;
+
+ DRM_TRACE("\n");
+
+ if (flags & _DRM_LOCK_FLUSH) {
+ ret = drm_flush_unblock_queue(dev, DRM_KERNEL_CONTEXT);
+ if (!ret) ret = drm_flush_unblock_queue(dev, context);
+ }
+ if (flags & _DRM_LOCK_FLUSH_ALL) {
+ read_lock(&dev->queue_lock);
+ for (i = 0; !ret && i < dev->queue_count; i++) {
+ ret = drm_flush_unblock_queue(dev, i);
+ }
+ read_unlock(&dev->queue_lock);
+ }
+
+ return ret;
+}
+
+int drm_lock DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ DECLARE_WAITQUEUE(entry, current);
+ int ret = 0;
+ drm_lock_t lock;
+ drm_queue_t *q;
+#if DRM_DMA_HISTOGRAM
+ cycles_t start;
+
+ dev->lck_start = start = get_cycles();
+#endif
+
+ copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+
+ if (lock.context == DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("Process %d using kernel context %d\n",
+ current->pid, lock.context);
+ return -EINVAL;
+ }
+
+ DRM_TRACE("%d requests lock, flags = 0x%08x\n",
+ lock.context, lock.flags);
+
+ if (lock.context < 0 || lock.context >= dev->queue_count)
+ return -EINVAL;
+ q = dev->queuelist[lock.context];
+
+ ret = drm_flush_block_and_flush(dev, lock.context, lock.flags);
+
+ if (!ret) {
+ if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)
+ != lock.context) {
+ long j = jiffies - dev->lock.lock_time;
+
+ if (j > 0 && j <= DRM_LOCK_SLICE) {
+ /* Can't take lock if we just had it and
+ there is contention. */
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(j);
+ }
+ }
+ add_wait_queue(&dev->lock.lock_queue, &entry);
+ for (;;) {
+ if (!dev->lock.hw_lock) {
+ /* Device has been unregistered */
+ ret = -EINTR;
+ break;
+ }
+ if (drm_lock_take(&dev->lock.hw_lock->lock,
+ lock.context)) {
+ dev->lock.pid = current->pid;
+ dev->lock.lock_time = jiffies;
+ atomic_inc(&dev->total_locks);
+ atomic_inc(&q->total_locks);
+ break; /* Got lock */
+ }
+
+ /* Contention */
+ atomic_inc(&dev->total_sleeps);
+ current->state = TASK_INTERRUPTIBLE;
+ schedule();
+ if (signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ break;
+ }
+ }
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&dev->lock.lock_queue, &entry);
+ }
+
+ /* Ok to unblock here, since we either have
+ the lock now, in which case more DMA
+ won't be sent; or ret != 0, in which
+ case we don't have the lock and we won't
+ be getting the lock. */
+ drm_flush_unblock(dev, lock.context, lock.flags); /* cleanup phase */
+
+ if (!ret) {
+ if (lock.flags & _DRM_LOCK_READY)
+ drm_do_command(dev, _DRM_DMA_READY);
+ if (lock.flags & _DRM_LOCK_QUIESCENT)
+ drm_do_command(dev, _DRM_DMA_QUIESCENT);
+ }
+ DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
+
+#if DRM_DMA_HISTOGRAM
+ atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]);
+#endif
+
+ return ret;
+}
+
+int drm_unlock DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_lock_t lock;
+
+ copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+
+ if (lock.context == DRM_KERNEL_CONTEXT) {
+ DRM_ERROR("Process %d using kernel context %d\n",
+ current->pid, lock.context);
+ return -EINVAL;
+ }
+
+ DRM_TRACE("%d frees lock (%d holds)\n",
+ lock.context,
+ _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
+ atomic_inc(&dev->total_unlocks);
+ if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
+ atomic_inc(&dev->total_contends);
+ drm_lock_transfer(&dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
+ drm_dma_schedule(dev, 1);
+ if (!dev->context_flag) {
+ /* Don't release lock if context switch in
+ progress. */
+ if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
+ DRM_KERNEL_CONTEXT)) {
+ DRM_ERROR("\n");
+ }
+ }
+#if DRM_DMA_HISTOGRAM
+ atomic_inc(&dev->histo.lhld[drm_histogram_slot(get_cycles()
+ - dev->lck_start)]);
+#endif
+
+ return 0;
+}
+
+static int drm_init_queue(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx)
+{
+ DRM_TRACE("\n");
+
+ if (atomic_read(&q->use_count) != 1
+ || atomic_read(&q->finalization)
+ || atomic_read(&q->block_count)) {
+ DRM_ERROR("New queue is already in use: u%d f%d b%d\n",
+ atomic_read(&q->use_count),
+ atomic_read(&q->finalization),
+ atomic_read(&q->block_count));
+ }
+
+ atomic_set(&q->finalization, 0);
+ atomic_set(&q->block_count, 0);
+ atomic_set(&q->block_read, 0);
+ atomic_set(&q->block_write, 0);
+ atomic_set(&q->total_queued, 0);
+ atomic_set(&q->total_flushed, 0);
+ atomic_set(&q->total_locks, 0);
+
+ init_waitqueue_head(&q->write_queue);
+ init_waitqueue_head(&q->read_queue);
+ init_waitqueue_head(&q->flush_queue);
+
+ q->flags = ctx->flags;
+
+ drm_waitlist_create(&q->waitlist, dev->buf_count);
+
+ return 0;
+}
+
+static int drm_alloc_queue(drm_device_t *dev)
+{
+ int i;
+ drm_queue_t *queue;
+ int oldslots;
+ int newslots;
+
+ /* PRE: 1) dev->queuelist[0..dev->queue_count] is allocated and
+ will not disappear (so all deallocation must be done
+ after IOCTLs are off)
+ 2) dev->queue_count < dev->queue_slots
+ 3) dev->queuelist[i].use_count == 0
+ and dev->queuelist[i].finalization == 0 if i not in use
+
+ POST: 1) dev->queuelist[i].use_count == 1
+ 2) dev->queue_count < dev->queue_slots
+ */
+
+ /* Check for a free queue */
+ for (i = 0; i < dev->queue_count; i++) {
+ atomic_inc(&dev->queuelist[i]->use_count);
+ if (atomic_read(&dev->queuelist[i]->use_count) == 1
+ && !atomic_read(&dev->queuelist[i]->finalization)) {
+ DRM_TRACE("%d (free)\n", i);
+ return i;
+ }
+ atomic_dec(&dev->queuelist[i]->use_count);
+ }
+ /* Allocate a new queue */
+ spin_lock(&dev->struct_lock);
+
+ queue = drm_alloc(sizeof(*queue), DRM_MEM_QUEUES);
+ memset(queue, 0, sizeof(*queue));
+ atomic_set(&queue->use_count, 1);
+
+ ++dev->queue_count;
+ if (dev->queue_count >= dev->queue_slots) {
+ oldslots = dev->queue_slots * sizeof(*dev->queuelist);
+ if (!dev->queue_slots) dev->queue_slots = 1;
+ dev->queue_slots *= 2;
+ newslots = dev->queue_slots * sizeof(*dev->queuelist);
+
+ dev->queuelist = drm_realloc(dev->queuelist,
+ oldslots,
+ newslots,
+ DRM_MEM_QUEUES);
+ if (!dev->queuelist) {
+ spin_unlock(&dev->struct_lock);
+ DRM_TRACE("out of memory\n");
+ return -ENOMEM;
+ }
+ }
+ dev->queuelist[dev->queue_count-1] = queue;
+
+ spin_unlock(&dev->struct_lock);
+ DRM_TRACE("%d (new)\n", dev->queue_count - 1);
+ return dev->queue_count - 1;
+}
+
+int drm_resctx DRM_IOCTL_ARGS
+{
+ drm_ctx_res_t res;
+ drm_ctx_t ctx;
+ int i;
+
+ DRM_TRACE("%d\n", DRM_RESERVED_CONTEXTS);
+ copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT);
+ if (res.count >= DRM_RESERVED_CONTEXTS) {
+ memset(&ctx, 0, sizeof(ctx));
+ for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
+ ctx.handle = i;
+ copy_to_user_ret(&res.contexts[i],
+ &i,
+ sizeof(i),
+ -EFAULT);
+ }
+ }
+ res.count = DRM_RESERVED_CONTEXTS;
+ copy_to_user_ret((drm_ctx_res_t *)arg, &res, sizeof(res), -EFAULT);
+ return 0;
+}
+
+
+int drm_addctx DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_t ctx;
+
+ copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+ if ((ctx.handle = drm_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
+ /* Init kernel's context and get a new one. */
+ drm_init_queue(dev, dev->queuelist[ctx.handle], &ctx);
+ ctx.handle = drm_alloc_queue(dev);
+ }
+ drm_init_queue(dev, dev->queuelist[ctx.handle], &ctx);
+ DRM_TRACE("%d\n", ctx.handle);
+ copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT);
+ return 0;
+}
+
+int drm_modctx DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_t ctx;
+ drm_queue_t *q;
+
+ copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+
+ DRM_TRACE("%d\n", ctx.handle);
+
+ if (ctx.handle < 0 || ctx.handle >= dev->queue_count) return -EINVAL;
+ q = dev->queuelist[ctx.handle];
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) == 1) {
+ /* No longer in use */
+ atomic_dec(&q->use_count);
+ return -EINVAL;
+ }
+ /* You have to drm_finish before doing
+ modifications. Otherwise, the DMA
+ engine could become very confused
+ (although, in the intitial
+ implementation, it won't). */
+ if (DRM_BUFCOUNT(&q->waitlist)) {
+ atomic_dec(&q->use_count);
+ return -EBUSY;
+ }
+
+ /* Add other possible modificaitons here. */
+ q->flags = ctx.flags;
+
+ atomic_dec(&q->use_count);
+ return 0;
+}
+
+int drm_getctx DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_t ctx;
+ drm_queue_t *q;
+
+ copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+
+ DRM_TRACE("%d\n", ctx.handle);
+
+ if (ctx.handle >= dev->queue_count) return -EINVAL;
+ q = dev->queuelist[ctx.handle];
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) == 1) {
+ /* No longer in use */
+ atomic_dec(&q->use_count);
+ return -EINVAL;
+ }
+
+ /* Add other possible modificaitons here. */
+ ctx.flags = q->flags;
+ atomic_dec(&q->use_count);
+
+ copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT);
+
+ return 0;
+}
+
+int drm_switchctx DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_t ctx;
+
+ copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+
+ DRM_TRACE("%d\n", ctx.handle);
+
+ /* All the validity checking is done in
+ drm_context_switch. */
+ return drm_context_switch(dev, dev->last_context, ctx.handle);
+}
+
+int drm_newctx DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_t ctx;
+
+ copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+
+ DRM_TRACE("%d\n", ctx.handle);
+ drm_context_switch_complete(dev, ctx.handle);
+
+ return 0;
+}
+
+int drm_rmctx DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_ctx_t ctx;
+ drm_queue_t *q;
+ drm_buf_t *buf;
+
+ copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
+ DRM_DEBUG("%d\n", ctx.handle);
+
+ if (ctx.handle >= dev->queue_count) return -EINVAL;
+ q = dev->queuelist[ctx.handle];
+
+ atomic_inc(&q->use_count);
+ if (atomic_read(&q->use_count) == 1) {
+ /* No longer in use */
+ atomic_dec(&q->use_count);
+ return -EINVAL;
+ }
+
+ atomic_inc(&q->finalization); /* Mark queue in finalization state */
+ atomic_sub(2, &q->use_count); /* Mark queue as unused (pending
+ finalization) */
+
+ /* If there are buffers waiting, then we
+ have a problem, because we guarantee
+ that drm_dma_schedule is the only reader
+ of the waitlist, and that it is not
+ reentrant. While it could check
+ finalization, there is no easy way to
+ prevent a race condition. So, we have
+ to use the (heavy-handed) dma_flag flag.
+ (The freelist allows multiple writers,
+ so it isn't a problem.) */
+
+ while (test_and_set_bit(0, &dev->interrupt_flag)) {
+ schedule();
+ if (signal_pending(current)) {
+ clear_bit(0, &dev->interrupt_flag);
+ return -EINTR;
+ }
+ }
+ /* Remove queued buffers */
+ while ((buf = drm_waitlist_get(&q->waitlist))) {
+ drm_free_buffer(dev, buf);
+ }
+ clear_bit(0, &dev->interrupt_flag);
+
+ /* Wakeup blocked processes */
+ wake_up_interruptible(&q->read_queue);
+ wake_up_interruptible(&q->write_queue);
+ wake_up_interruptible(&q->flush_queue);
+
+ /* Finalization over. Queue is made
+ available when both use_count and
+ finalization become 0, which won't
+ happen until all the waiting processes
+ stop waiting. */
+ atomic_dec(&q->finalization);
+ return 0;
+}
+
+int drm_adddraw DRM_IOCTL_ARGS
+{
+ drm_draw_t draw;
+
+ draw.handle = 0; /* NOOP */
+ DRM_TRACE("%d\n", draw.handle);
+ copy_to_user_ret((drm_draw_t *)arg, &draw, sizeof(draw), -EFAULT);
+ return 0;
+}
+
+int drm_rmdraw DRM_IOCTL_ARGS
+{
+ return 0; /* NOOP */
+}
+
+int drm_finish DRM_IOCTL_ARGS
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ int ret = 0;
+ drm_lock_t lock;
+
+ DRM_TRACE("\n");
+
+ copy_from_user_ret(&lock, (drm_lock_t *)arg, sizeof(lock), -EFAULT);
+ ret = drm_flush_block_and_flush(dev, lock.context, lock.flags);
+ drm_flush_unblock(dev, lock.context, lock.flags);
+ return ret;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/gmx/gmx.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/gmx/gmx.h
new file mode 100644
index 000000000..6949a6ed3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/gmx/gmx.h
@@ -0,0 +1,74 @@
+/* gmx.h -- Example GLINT GMX driver stub -*- linux-c -*-
+ * Created: Wed Jan 13 13:18:05 1999 by faith@precisioninsight.com
+ * Revised: Fri Mar 19 14:31:18 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/gmx/gmx.h,v 1.3 1999/03/26 17:47:01 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/gmx/gmx.h,v 1.1 1999/06/14 07:32:06 dawes Exp $
+ *
+ */
+
+#ifndef _GMX_H_
+#define _GMX_H_
+#ifdef __KERNEL__
+#include "drm.h"
+
+#define GMX_DEBUG_CODE 2 /* Include debugging code (if > 1, then
+ turn on printing by default) */
+#define GMX_NAME "gmx"
+
+#define GMX_FLAG_TRACE 0x0001
+#define GMX_FLAG_DEBUG 0x0002
+
+ /* Macros to make printk easier */
+#define GMX_ERROR(fmt, arg...) printk(KERN_ERR "[" GMX_NAME "] " fmt, ##arg)
+#define GMX_INFO(fmt, arg...) printk(KERN_INFO "[" GMX_NAME "] " fmt, ##arg)
+
+#if GMX_DEBUG_CODE
+#define GMX_TRACE(fmt, arg...) \
+ do { \
+ if (gmx_flags|GMX_FLAG_TRACE) \
+ printk(KERN_DEBUG \
+ "[" GMX_NAME ":" __FUNCTION__ "] " fmt, \
+ ##arg); \
+ } while (0)
+#define GMX_DEBUG(fmt, arg...) \
+ do { \
+ if (gmx_flags|GMX_FLAG_DEBUG) \
+ printk(KERN_DEBUG \
+ "[" GMX_NAME ":" __FUNCTION__ "] " fmt, \
+ ##arg); \
+ } while (0)
+#else
+#define GMX_TRACE(fmt, arg...) do { } while (0)
+#define GMX_DEBUG(fmt, arg...) do { } while (0)
+#endif
+
+extern void __init gmx_setup(char *str, int *ints);
+extern int gmx_init(void);
+extern void gmx_cleanup(void);
+
+
+#endif
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/gmx/gmx_setup.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/gmx/gmx_setup.c
new file mode 100644
index 000000000..a1a715c8f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/gmx/gmx_setup.c
@@ -0,0 +1,255 @@
+/* gmx_setup.c -- Example GLINT GMX driver stub -*- linux-c -*-
+ * Created: Wed Jan 13 13:06:20 1999 by faith@precisioninsight.com
+ * Revised: Fri Mar 19 14:31:27 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/gmx/gmx_setup.c,v 1.5 1999/03/26 17:47:01 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/gmx/gmx_setup.c,v 1.1 1999/06/14 07:32:06 dawes Exp $
+ *
+ */
+
+#define EXPORT_SYMTAB
+#include "gmx.h"
+#include "gmx_version.h"
+EXPORT_SYMBOL(gmx_init);
+EXPORT_SYMBOL(gmx_cleanup);
+
+#define GMX_DESC "Example GLINT GMX Driver"
+
+static int gmx_reg(void);
+static int gmx_unreg(void);
+static int gmx_load(void);
+static int gmx_unload(void);
+static int gmx_open(struct inode *inode, struct file *filp);
+static int gmx_release(struct inode *inode, struct file *filp);
+
+static int gmx_flags = 0;
+static int gmx_registered = 0;
+static drm_version_t gmx_version = {
+ GMX_MAJOR,
+ GMX_MINOR,
+ GMX_PATCHLEVEL,
+ sizeof(GMX_NAME),
+ (char *)GMX_NAME,
+ sizeof(GMX_DATE),
+ (char *)GMX_DATE,
+ sizeof(GMX_DESC),
+ (char *)GMX_DESC
+};
+static drm_func_desc_t gmx_funcs = {
+ reg: gmx_reg,
+ unreg: gmx_unreg,
+ load: gmx_load,
+ unload: gmx_unload,
+ open: gmx_open,
+ release: gmx_release,
+};
+
+#ifdef MODULE
+int init_module(void);
+void cleanup_module(void);
+static char *gmx = NULL;
+
+MODULE_AUTHOR("Precision Insight, Inc., Cedar Park, Texas.");
+MODULE_DESCRIPTION("GLINT GMX Example Module");
+MODULE_PARM(gmx, "s");
+
+/* init_module is called when insmod is used to load the module */
+
+int init_module(void)
+{
+ return gmx_init();
+}
+
+/* cleanup_module is called when rmmod is used to unload the module */
+
+void cleanup_module(void)
+{
+ gmx_cleanup();
+}
+#endif
+
+/* gmx_parse_option parses a single option. See description for
+ gmx_parse_gmx for details. */
+
+static void gmx_parse_option(char *s)
+{
+ char *c, *r;
+
+ GMX_TRACE("\"%s\"\n", s);
+ if (!s || !*s) return;
+ for (c = s; *c && *c != ':'; c++); /* find : or \0 */
+ if (*c) r = c + 1; else r = NULL; /* remember remainder */
+ *c = '\0'; /* terminate */
+ if (!strcmp(s, "debug")) {
+ char *h, *t, *n;
+
+ if (!r) {
+ GMX_ERROR("Usage: debug:<flag>[:<flag>]*\n");
+ return;
+ }
+
+ for (h = t = n = r; h && *h; h = n) {
+ for (; *t && *t != ':'; t++); /* find : or \0 */
+ if (*t) n = t + 1; else n = NULL; /* remember next */
+ *t = '\0'; /* terminate */
+ if (!strcmp(h, "on")) {
+ gmx_flags |= GMX_FLAG_DEBUG;
+ continue;
+ }
+ if (!strcmp(h, "off")) {
+ gmx_flags = 0;
+ continue;
+ }
+ if (!strcmp(h, "trace")) {
+ gmx_flags |= GMX_FLAG_TRACE;
+ continue;
+ }
+ GMX_ERROR("\"%s\" is not a valid debug flag\n", h);
+ }
+ GMX_DEBUG("Debug mask = 0x%08x\n", gmx_flags);
+ return;
+ }
+ GMX_ERROR("\"%s\" is not a valid option\n", s);
+ return;
+}
+
+/* gmx_parse_gmx parse the insmod "gmx=" options, or the command-line
+ * options passed to the kernel via LILO. The grammar of the format is as
+ * follows:
+ *
+ * gmx ::= 'gmx=' option_list
+ * option_list ::= option [ ';' option_list ]
+ * option ::= 'debug:' debug_list
+ * debug_list ::= debug_option [ ':' debug_list ]
+ * debug_option ::= 'on' | 'off' | 'trace'
+ *
+ * Note that 's' contains option_list without the 'gmx=' part.
+ *
+ * debug=on specifies that debugging messages will be printk'd
+ * debug=trace specifies that each function call will be logged via printk
+ * debug=off turns off all debugging options
+ *
+ */
+
+static void gmx_parse_gmx(char *s)
+{
+ char *h, *t, *n;
+
+ GMX_TRACE("\"%s\"\n", s);
+ if (!s || !*s) return;
+
+ for (h = t = n = s; h && *h; h = n) {
+ for (; *t && *t != ';'; t++); /* find ; or \0 */
+ if (*t) n = t + 1; else n = NULL; /* remember next */
+ *t = '\0'; /* terminate */
+ gmx_parse_option(h); /* parse */
+ }
+}
+
+#ifndef MODULE
+/* gmx_setup is called by the kernel to parse command-line options passed
+ * via the boot-loader (e.g., LILO). It calls the insmod option routine,
+ * gmx_parse_gmx.
+ *
+ * This is not currently supported, since it requires changes to
+ * linux/init/main.c. */
+
+
+void __init gmx_setup(char *str, int *ints)
+{
+ GMX_TRACE("\n");
+ if (ints[0] != 0) {
+ GMX_ERROR("Illegal command line format, ignored\n");
+ return;
+ }
+ gmx_parse_gmx(str);
+}
+#endif
+
+/* gmx_init is called via init_module at module load time, or via
+ * linux/init/main.c (this is not currently supported). */
+
+int gmx_init(void)
+{
+ if (GMX_DEBUG_CODE>1) gmx_flags |= GMX_FLAG_TRACE | GMX_FLAG_DEBUG;
+ GMX_TRACE("\n");
+
+ gmx_parse_gmx(gmx);
+ drm_register_driver(GMX_NAME, &gmx_version, 0, NULL, &gmx_funcs, NULL);
+
+ return 0;
+}
+
+/* gmx_cleanup is called via cleanup_module at module unload time. */
+
+void gmx_cleanup(void)
+{
+ GMX_TRACE("\n");
+
+ drm_unregister_driver(GMX_NAME);
+}
+
+static int gmx_reg(void)
+{
+ GMX_TRACE("\n");
+ if (gmx_registered) return -EBUSY;
+ ++gmx_registered;
+ return 0;
+}
+
+static int gmx_unreg(void)
+{
+ GMX_TRACE("\n");
+ if (!gmx_registered) return -EBUSY;
+ --gmx_registered;
+ return 0;
+}
+
+static int gmx_load(void)
+{
+ GMX_TRACE("\n");
+ return 0;
+}
+
+static int gmx_unload(void)
+{
+ GMX_TRACE("\n");
+ return 0;
+}
+
+static int gmx_open(struct inode *inode, struct file *filp)
+{
+ GMX_TRACE("\n");
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int gmx_release(struct inode *inode, struct file *filp)
+{
+ GMX_TRACE("\n");
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/gmx/gmx_version.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/gmx/gmx_version.h
new file mode 100644
index 000000000..f11b53628
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/gmx/gmx_version.h
@@ -0,0 +1,4 @@
+#define GMX_DATE "19990113"
+#define GMX_MAJOR 0
+#define GMX_MINOR 0
+#define GMX_PATCHLEVEL 1
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c
new file mode 100644
index 000000000..50b421af1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c
@@ -0,0 +1,1114 @@
+/* xf86drm.c -- User-level interface to DRM device
+ * Created: Tue Jan 5 08:16:21 1999 by faith@precisioninsight.com
+ * Revised: Fri Jun 18 09:52:23 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.41 1999/06/21 14:31:20 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.3 1999/06/27 14:08:19 dawes Exp $
+ *
+ */
+
+#ifdef XFree86Server
+# include "xf86.h"
+# include "xf86_OSproc.h"
+# include "xf86_ansic.h"
+# include "xf86Priv.h"
+# define _DRM_MALLOC xalloc
+# define _DRM_FREE xfree
+# ifndef XFree86LOADER
+# include <sys/stat.h>
+# include <sys/mman.h>
+# endif
+#else
+# include <stdio.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <ctype.h>
+# include <fcntl.h>
+# include <errno.h>
+# include <signal.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/ioctl.h>
+# include <sys/mman.h>
+# include <sys/time.h>
+# ifdef DRM_USE_MALLOC
+# define _DRM_MALLOC malloc
+# define _DRM_FREE free
+extern int xf86InstallSIGIOHandler(int fd, void (*f)(int));
+extern int xf86RemoveSIGIOHandler(int fd);
+# else
+# include <Xlibint.h>
+# define _DRM_MALLOC Xmalloc
+# define _DRM_FREE Xfree
+# endif
+#endif
+
+/* Not all systems have MAP_FAILED defined */
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#include <sys/sysmacros.h> /* for makedev() */
+#include "xf86drm.h"
+#include "drm.h"
+
+static void *drmHashTable = NULL; /* Context switch callbacks */
+
+typedef struct drmHashEntry {
+ int fd;
+ void (*f)(int, void *, void *);
+ void *tagTable;
+} drmHashEntry;
+
+void *drmMalloc(int size)
+{
+ void *pt;
+ if ((pt = _DRM_MALLOC(size))) memset(pt, 0, size);
+ return pt;
+}
+
+void drmFree(void *pt)
+{
+ if (pt) _DRM_FREE(pt);
+}
+
+static char *drmStrdup(const char *s)
+{
+ return s ? strdup(s) : NULL;
+}
+
+
+/* drm_lookup searches file for a line tagged with name, and returns the
+ value for that tag. If busid is NULL, the file format is that used for
+ /proc/devices and /proc/misc, or the first part of /proc/drm/devices:
+
+ <value> <whitespace> <tag>
+
+ If the busid is non-NULL, the file format is the extended format used
+ for /proc/drm/devices:
+
+ <value> <whitespace> <name> <whitespace> <busid>
+
+ If both name and busid are non-NULL, both must match. If either is
+ NULL, then the other is matched.
+*/
+
+static int drm_lookup(const char *file, const char *name, const char *busid)
+{
+ FILE *str;
+ char buf[128];
+ char *pt;
+ int name_match;
+ int busid_match;
+ char *namept = NULL;
+ char *busidpt = NULL;
+
+ if (!(str = fopen(file, "r"))) return DRM_ERR_NO_DEVICE;
+ while (fgets(buf, sizeof(buf)-1, str)) {
+ buf[sizeof(buf)-1] = '\0';
+ for (pt = buf; *pt && isspace(*pt); ++pt); /* skip whitespace */
+ for (; *pt && !isspace(*pt); ++pt); /* next space or null */
+ if (isspace(pt[0]) && pt[1]) {
+ pt++;
+ for (; *pt && isspace(*pt); ++pt); /* skip whitespace */
+ namept = pt;
+ for (; *pt && !isspace(*pt); ++pt); /* next space or null */
+ if (isspace(pt[0]) && pt[1]) { /* busid present */
+ *pt = '\0'; /* proper termination */
+ pt++;
+ for (; *pt && isspace(*pt); ++pt); /* skip whitespace */
+ busidpt = pt;
+ for (; *pt && !isspace(*pt); ++pt); /* next space or null */
+ }
+ *pt = '\0'; /* proper termination */
+ name_match = name ? 0 : 1; /* match if we don't care */
+ busid_match = busid ? 0 : 1; /* match if we don't care */
+ if (name && namept && !strcmp(name, namept)) ++name_match;
+ if (busid && busidpt && !strcmp(busid, busidpt)) ++busid_match;
+ if (name_match && busid_match) {
+ fclose(str);
+ return atoi(buf); /* stops at whitespace */
+ }
+ }
+ }
+ fclose(str);
+ return DRM_ERR_NO_DEVICE;
+}
+
+static unsigned long drmGetKeyFromFd(int fd)
+{
+#ifdef XFree86LOADER
+ struct xf86stat st;
+#else
+ struct stat st;
+#endif
+
+ st.st_rdev = 0;
+ fstat(fd, &st);
+ return st.st_rdev;
+}
+
+static drmHashEntry *drmGetEntry(int fd)
+{
+ unsigned long key = drmGetKeyFromFd(fd);
+ void *value;
+ drmHashEntry *entry;
+
+ if (!drmHashTable) drmHashTable = drmHashCreate();
+
+ if (drmHashLookup(drmHashTable, key, &value)) {
+ entry = drmMalloc(sizeof(*entry));
+ entry->fd = fd;
+ entry->f = NULL;
+ entry->tagTable = drmHashCreate();
+ drmHashInsert(drmHashTable, key, entry);
+ } else {
+ entry = value;
+ }
+ return entry;
+}
+
+/* drm_open is used to open the /dev/drm device */
+
+static int drm_open(const char *file)
+{
+ int fd = open(file, O_RDWR, 0);
+
+ if (fd >= 0) return fd;
+ return -errno;
+}
+
+/* drmAvailable looks for /proc/drm, and returns 1 if it is present. */
+
+int drmAvailable(void)
+{
+ if (!access(DRM_PROC_DRM, R_OK)) return 1;
+ return 0;
+}
+
+/* drmGetMajor tries to find the major device number for /dev/drm by
+ searching /proc/devices. A negative value is returned on error. */
+
+static int drmGetMajor(void)
+{
+ int major;
+
+ if (!drmAvailable()) return DRM_ERR_NO_DEVICE;
+
+ if ((major = drm_lookup(DRM_PROC_DEVICES, DRM_NAME, NULL)) >= 0)
+ return major;
+
+ return DRM_ERR_NO_DEVICE;
+}
+
+/* drmGetMinor tries to find the minor device number for name by looking in
+ /proc/drm/devices. A negative value is retruned on error. */
+
+static int drmGetMinor(const char *name, const char *busid)
+{
+ int minor;
+ char buf[128];
+
+ if (!drmAvailable()) return DRM_ERR_NO_DEVICE;
+
+ sprintf(buf, "/proc/%s/%s", DRM_NAME, DRM_DEVICES);
+
+ if ((minor = drm_lookup(buf, name, busid))) return minor;
+ return 0;
+}
+
+
+/* drmOpen looks up the specified name and/or busid in /proc/drm/devices,
+ and opens the device found. The entry in /dev is created if necessary
+ (and if root). A file descriptor is returned. On error, the return
+ value is negative. */
+
+static int drmOpen(const char *name, const char *busid)
+{
+#ifdef XFree86LOADER
+ struct xf86stat st;
+#else
+ struct stat st;
+#endif
+ char path[128];
+ int major;
+ int minor;
+ dev_t dev;
+
+ if (!drmAvailable()) return DRM_ERR_NO_DEVICE;
+ if ((major = drmGetMajor()) < 0) return major;
+ if ((minor = drmGetMinor(name,busid)) < 0) return minor;
+ dev = makedev(major, minor);
+
+ if (!minor) {
+ sprintf(path, "/dev/%s", DRM_NAME );
+ } else {
+ sprintf(path, "/dev/%s%d", DRM_NAME, minor-1 );
+ }
+
+ /* Check device major/minor for match */
+ if (!access(path, F_OK)) {
+ if (stat(path, &st)) return DRM_ERR_NO_ACCESS;
+ if (st.st_rdev == dev) {
+#if defined(XFree86Server)
+ chmod(path,
+ xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE);
+ chown(path, DRM_DEV_UID,
+ xf86ConfigDRI.group ? xf86ConfigDRI.group : DRM_DEV_GID);
+#endif
+#if defined(DRM_USE_MALLOC)
+ chmod(path, DRM_DEV_MODE);
+ chown(path, DRM_DEV_UID, DRM_DEV_GID);
+#endif
+ return drm_open(path);
+ }
+ }
+
+ /* Doesn't exist or match failed, so we
+ have to be root to create it. */
+ if (geteuid()) return DRM_ERR_NOT_ROOT;
+ remove(path);
+ if (mknod(path, S_IFCHR | DRM_DEV_MODE, dev)) {
+ remove(path);
+ return DRM_ERR_NOT_ROOT;
+ }
+#if defined(XFree86Server)
+ chmod(path, xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE);
+ chown(path, DRM_DEV_UID,
+ xf86ConfigDRI.group ? xf86ConfigDRI.group : DRM_DEV_GID);
+#endif
+#if defined(DRM_USE_MALLOC)
+ chmod(path, DRM_DEV_MODE);
+ chown(path, DRM_DEV_UID, DRM_DEV_GID);
+#endif
+ return drm_open(path);
+}
+
+/* drmOpenDRM returns a file descriptor for the main /dev/drm control
+ device. The entry in /dev is created if necessary (and if root). A
+ file descriptor is returned. On error, the return value is negative. */
+
+int drmOpenDRM(void)
+{
+ return drmOpen(DRM_NAME, NULL);
+}
+
+
+/* drmClose closes the file descriptor returned from drmOpen. */
+
+int drmCloseDRM(int fd)
+{
+ return close(fd);
+}
+
+void drmFreeVersion(drmVersionPtr v)
+{
+ if (!v) return;
+ if (v->name) drmFree(v->name);
+ if (v->date) drmFree(v->date);
+ if (v->desc) drmFree(v->desc);
+ drmFree(v);
+}
+
+static void drmFreeKernelVersion(drm_version_t *v)
+{
+ if (!v) return;
+ if (v->name) drmFree(v->name);
+ if (v->date) drmFree(v->date);
+ if (v->desc) drmFree(v->desc);
+ drmFree(v);
+}
+
+static void drmCopyVersion(drmVersionPtr d, drm_version_t *s)
+{
+ d->version_major = s->version_major;
+ d->version_minor = s->version_minor;
+ d->version_patchlevel = s->version_patchlevel;
+ d->name_len = s->name_len;
+ d->name = drmStrdup(s->name);
+ d->date_len = s->date_len;
+ d->date = drmStrdup(s->date);
+ d->desc_len = s->desc_len;
+ d->desc = drmStrdup(s->desc);
+}
+
+/* drmVersion obtains the version information via an ioctl. Similar
+ * information is available via /proc/drm. */
+
+drmVersionPtr drmGetVersion(int fd)
+{
+ drmVersionPtr retval;
+ drm_version_t *version = drmMalloc(sizeof(*version));
+
+ /* First, get the lengths */
+ version->name_len = 0;
+ version->name = NULL;
+ version->date_len = 0;
+ version->date = NULL;
+ version->desc_len = 0;
+ version->desc = NULL;
+
+ if (ioctl(fd, DRM_IOCTL_VERSION, version)) {
+ drmFreeKernelVersion(version);
+ return NULL;
+ }
+
+ /* Now, allocate space and get the data */
+ if (version->name_len)
+ version->name = drmMalloc(version->name_len + 1);
+ if (version->date_len)
+ version->date = drmMalloc(version->date_len + 1);
+ if (version->desc_len)
+ version->desc = drmMalloc(version->desc_len + 1);
+
+ if (ioctl(fd, DRM_IOCTL_VERSION, version)) {
+ drmFreeKernelVersion(version);
+ return NULL;
+ }
+
+ /* The results might not be null-terminated
+ strings, so terminate them. */
+
+ if (version->name_len) version->name[version->name_len] = '\0';
+ if (version->date_len) version->date[version->date_len] = '\0';
+ if (version->desc_len) version->desc[version->desc_len] = '\0';
+
+ /* Now, copy it all back into the
+ client-visible data structure... */
+ retval = drmMalloc(sizeof(*retval));
+ drmCopyVersion(retval, version);
+ drmFreeKernelVersion(version);
+ return retval;
+}
+
+void drmFreeVersionList(drmListPtr list)
+{
+ int i;
+
+ if (!list) return;
+ if (list->version) {
+ for (i = 0; i < list->count; i++) {
+ if (list->version[i].name) drmFree(list->version[i].name);
+ if (list->version[i].date) drmFree(list->version[i].date);
+ if (list->version[i].desc) drmFree(list->version[i].desc);
+
+ }
+ drmFree(list->version);
+ }
+ if (list->capability) drmFree(list->capability);
+ drmFree(list);
+}
+
+static void drmFreeKernelVersionList(drm_list_t *list)
+{
+ int i;
+
+ if (!list) return;
+ if (list->version) {
+ for (i = 0; i < list->count; i++) {
+ if (list->version[i].name) drmFree(list->version[i].name);
+ if (list->version[i].date) drmFree(list->version[i].date);
+ if (list->version[i].desc) drmFree(list->version[i].desc);
+
+ }
+ drmFree(list->version);
+ }
+ drmFree(list);
+}
+
+/* drmList obtains a list of all drivers and capabilities via an ioctl. */
+
+drmListPtr drmGetVersionList(int fd)
+{
+ drmListPtr retval;
+ drm_list_t *list = drmMalloc(sizeof(*list));
+ int i;
+
+ list->count = 0;
+
+ /* First, get the count */
+
+ if (ioctl(fd, DRM_IOCTL_LIST, list)) {
+ drmFreeKernelVersionList(list);
+ return NULL;
+ }
+
+ /* Next, get the version sizes */
+ for (i = 0; i < list->count; i++) {
+ list->version
+ = drmMalloc(list->count * sizeof(*list->version));
+ list->version[i].name_len = 0;
+ list->version[i].name = NULL;
+ list->version[i].date_len = 0;
+ list->version[i].date = NULL;
+ list->version[i].desc_len = 0;
+ list->version[i].desc = NULL;
+ }
+
+ if (ioctl(fd, DRM_IOCTL_LIST, list)) {
+ drmFreeKernelVersionList(list);
+ return NULL;
+ }
+
+ /* Now, allocate space and get the data */
+ for (i = 0; i < list->count; i++) {
+ if (list->version[i].name_len)
+ list->version[i].name = drmMalloc(list->version[i].name_len + 1);
+ if (list->version[i].date_len)
+ list->version[i].date = drmMalloc(list->version[i].date_len + 1);
+ if (list->version[i].desc_len)
+ list->version[i].desc = drmMalloc(list->version[i].desc_len + 1);
+ }
+
+ if (ioctl(fd, DRM_IOCTL_LIST, list)) {
+ drmFreeKernelVersionList(list);
+ return NULL;
+ }
+
+ /* The results might not be null-terminated
+ strings, so terminate them. */
+
+ for (i = 0; i < list->count; i++) {
+ if (list->version[i].name_len)
+ list->version[i].name[list->version[i].name_len] = '\0';
+ if (list->version[i].date_len)
+ list->version[i].date[list->version[i].date_len] = '\0';
+ if (list->version[i].desc_len)
+ list->version[i].desc[list->version[i].desc_len] = '\0';
+ }
+
+ /* Now, copy it all back into the
+ client-visible data structure... */
+ retval = drmMalloc(sizeof(*retval));
+ retval->count = list->count;
+ retval->version = drmMalloc(list->count * sizeof(*retval->version));
+ retval->capability = drmMalloc(list->count * sizeof(*retval->capability));
+ for (i = 0; i < list->count; i++) {
+ drmCopyVersion(&retval->version[i], &list->version[i]);
+ }
+ drmFreeKernelVersionList(list);
+ return retval;
+}
+
+int drmCreateSub(int fd, const char *name, const char *busid)
+{
+ drm_request_t request;
+
+ request.device_name = name;
+ request.device_busid = busid;
+ if (ioctl(fd, DRM_IOCTL_CREATE, &request)) {
+ return -errno;
+ }
+ return 0;
+}
+
+int drmDestroySub(int fd, const char *busid)
+{
+ drm_request_t request;
+
+ request.device_busid = busid;
+ request.device_major = drmGetMajor();
+ request.device_minor = drmGetMinor(NULL, busid);
+ if (ioctl(fd, DRM_IOCTL_DESTROY, &request)) {
+ return -errno;
+ }
+ return 0;
+}
+
+int drmGetMagic(int fd, drmMagicPtr magic)
+{
+ drm_auth_t auth;
+
+ *magic = 0;
+ if (ioctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) return -errno;
+ *magic = auth.magic;
+ return 0;
+}
+
+int drmAuthMagic(int fd, drmMagic magic)
+{
+ drm_auth_t auth;
+
+ auth.magic = magic;
+ if (ioctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth)) return -errno;
+ return 0;
+}
+
+int drmAddMap(int fd,
+ drmHandle offset,
+ drmSize size,
+ drmMapType type,
+ drmMapFlags flags,
+ drmHandlePtr handle)
+{
+ drm_map_t map;
+
+ map.offset = offset;
+ map.size = size;
+ map.handle = 0;
+ map.type = type;
+ map.flags = flags;
+ if (ioctl(fd, DRM_IOCTL_ADD_MAP, &map)) return -errno;
+ if (handle) *handle = (drmHandle)map.handle;
+ return 0;
+}
+
+int drmAddBufs(int fd, int count, int size, int flags)
+{
+ drm_buf_desc_t request;
+
+ request.count = count;
+ request.size = size;
+ request.low_mark = 0;
+ request.high_mark = 0;
+ request.flags = flags;
+ if (ioctl(fd, DRM_IOCTL_ADD_BUFS, &request)) return -errno;
+ return request.count;
+}
+
+int drmMarkBufs(int fd, double low, double high)
+{
+ drm_buf_info_t info;
+ int i;
+
+ info.count = 0;
+ info.list = NULL;
+
+ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) return -EINVAL;
+
+ if (!info.count) return -EINVAL;
+
+ if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
+ return -ENOMEM;
+
+ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
+ int retval = -errno;
+ drmFree(info.list);
+ return retval;
+ }
+
+ for (i = 0; i < info.count; i++) {
+ info.list[i].low_mark = low * info.list[i].count;
+ info.list[i].high_mark = high * info.list[i].count;
+ if (ioctl(fd, DRM_IOCTL_MARK_BUFS, &info.list[i])) {
+ int retval = -errno;
+ drmFree(info.list);
+ return retval;
+ }
+ }
+ drmFree(info.list);
+
+ return 0;
+}
+
+int drmFreeBufs(int fd, int count, int *list)
+{
+ drm_buf_free_t request;
+
+ request.count = count;
+ request.list = list;
+ if (ioctl(fd, DRM_IOCTL_FREE_BUFS, &request)) return -errno;
+ return 0;
+}
+
+int drmOpenSub(const char *busid)
+{
+ return drmOpen(NULL, busid);
+}
+
+int drmCloseSub(int fd)
+{
+ unsigned long key = drmGetKeyFromFd(fd);
+ drmHashEntry *entry = drmGetEntry(fd);
+
+ drmHashDestroy(entry->tagTable);
+ entry->fd = 0;
+ entry->f = NULL;
+ entry->tagTable = NULL;
+
+ drmHashDelete(drmHashTable, key);
+ drmFree(entry);
+
+ return close(fd);
+}
+
+int drmMap(int fd,
+ drmHandle handle,
+ drmSize size,
+ drmAddressPtr address)
+{
+ if (fd < 0) return -EINVAL;
+ *address = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle);
+ if (*address == MAP_FAILED) return -errno;
+ return 0;
+}
+
+int drmUnmap(drmAddress address, drmSize size)
+{
+ return munmap(address, size);
+}
+
+drmBufInfoPtr drmGetBufInfo(int fd)
+{
+ drm_buf_info_t info;
+ drmBufInfoPtr retval;
+ int i;
+
+ info.count = 0;
+ info.list = NULL;
+
+ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) return NULL;
+
+ if (info.count) {
+ if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
+ return NULL;
+
+ if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
+ drmFree(info.list);
+ return NULL;
+ }
+ /* Now, copy it all back into the
+ client-visible data structure... */
+ retval = drmMalloc(sizeof(*retval));
+ retval->count = info.count;
+ retval->list = drmMalloc(info.count * sizeof(*retval->list));
+ for (i = 0; i < info.count; i++) {
+ retval->list[i].count = info.list[i].count;
+ retval->list[i].size = info.list[i].size;
+ retval->list[i].low_mark = info.list[i].low_mark;
+ retval->list[i].high_mark = info.list[i].high_mark;
+ }
+ drmFree(info.list);
+ return retval;
+ }
+ return NULL;
+}
+
+drmBufMapPtr drmMapBufs(int fd)
+{
+ drm_buf_map_t bufs;
+ drmBufMapPtr retval;
+ int i;
+
+ bufs.count = 0;
+ bufs.list = NULL;
+ if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) return NULL;
+
+ if (bufs.count) {
+ if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list))))
+ return NULL;
+
+ if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) {
+ drmFree(bufs.list);
+ return NULL;
+ }
+ /* Now, copy it all back into the
+ client-visible data structure... */
+ retval = drmMalloc(sizeof(*retval));
+ retval->count = bufs.count;
+ retval->list = drmMalloc(bufs.count * sizeof(*retval->list));
+ for (i = 0; i < bufs.count; i++) {
+ retval->list[i].idx = bufs.list[i].idx;
+ retval->list[i].total = bufs.list[i].total;
+ retval->list[i].used = 0;
+ retval->list[i].address = bufs.list[i].address;
+ }
+ return retval;
+ }
+ return NULL;
+}
+
+int drmUnmapBufs(drmBufMapPtr bufs)
+{
+ int i;
+
+ for (i = 0; i < bufs->count; i++) {
+ munmap(bufs->list[i].address, bufs->list[i].total);
+ }
+ return 0;
+}
+
+int drmDMA(int fd, drmDMAReqPtr request)
+{
+ drm_dma_t dma;
+
+ /* Copy to hidden structure */
+ dma.context = request->context;
+ dma.send_count = request->send_count;
+ dma.send_indices = request->send_list;
+ dma.send_sizes = request->send_sizes;
+ dma.flags = request->flags;
+ dma.request_count = request->request_count;
+ dma.request_size = request->request_size;
+ dma.request_indices = request->request_list;
+ dma.request_sizes = request->request_sizes;
+ if (ioctl(fd, DRM_IOCTL_DMA, &dma)) return -errno;
+ request->granted_count = dma.granted_count;
+
+ return 0;
+}
+
+int drmGetLock(int fd, drmContext context, drmLockFlags flags)
+{
+ drm_lock_t lock;
+
+ lock.context = context;
+ lock.flags = 0;
+ if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY;
+ if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT;
+ if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH;
+ if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL;
+ if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
+ if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
+
+ while (ioctl(fd, DRM_IOCTL_LOCK, &lock))
+ ;
+ return 0;
+}
+
+int drmUnlock(int fd, drmContext context)
+{
+ drm_lock_t lock;
+
+ lock.context = context;
+ lock.flags = 0;
+ return ioctl(fd, DRM_IOCTL_UNLOCK, &lock);
+}
+
+drmContextPtr drmGetReservedContextList(int fd, int *count)
+{
+ drm_ctx_res_t res;
+ drm_ctx_t *list;
+ drmContextPtr retval;
+ int i;
+
+ res.count = 0;
+ res.contexts = NULL;
+ if (ioctl(fd, DRM_IOCTL_RES_CTX, &res)) return NULL;
+
+ if (!res.count) return NULL;
+
+ if (!(list = drmMalloc(res.count * sizeof(*list)))) return NULL;
+ if (!(retval = drmMalloc(res.count * sizeof(*retval)))) {
+ drmFree(list);
+ return NULL;
+ }
+
+ res.contexts = list;
+ if (ioctl(fd, DRM_IOCTL_RES_CTX, &res)) return NULL;
+
+ for (i = 0; i < res.count; i++) retval[i] = list[i].handle;
+ drmFree(list);
+
+ *count = res.count;
+ return retval;
+}
+
+void drmFreeReservedContextList(drmContextPtr pt)
+{
+ drmFree(pt);
+}
+
+int drmCreateContext(int fd, drmContextPtr handle)
+{
+ drm_ctx_t ctx;
+
+ ctx.flags = 0; /* Modified with functions below */
+ if (ioctl(fd, DRM_IOCTL_ADD_CTX, &ctx)) return -errno;
+ *handle = ctx.handle;
+ return 0;
+}
+
+int drmSwitchToContext(int fd, drmContext context)
+{
+ drm_ctx_t ctx;
+
+ ctx.handle = context;
+ if (ioctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx)) return -errno;
+ return 0;
+}
+
+int drmSetContextFlags(int fd, drmContext context, drmContextFlags flags)
+{
+ drm_ctx_t ctx;
+
+ /* Context preserving means that no context
+ switched are done between DMA buffers
+ from one context and the next. This is
+ suitable for use in the X server (which
+ promises to maintain hardware context,
+ or in the client-side library when
+ buffers are swapped on behalf of two
+ threads. */
+ ctx.handle = context;
+ ctx.flags = 0;
+ if (flags & DRM_CONTEXT_PRESERVED) ctx.flags |= _DRM_CONTEXT_PRESERVED;
+ if (flags & DRM_CONTEXT_2DONLY) ctx.flags |= _DRM_CONTEXT_2DONLY;
+ if (ioctl(fd, DRM_IOCTL_MOD_CTX, &ctx)) return -errno;
+ return 0;
+}
+
+int drmGetContextFlags(int fd, drmContext context, drmContextFlagsPtr flags)
+{
+ drm_ctx_t ctx;
+
+ ctx.handle = context;
+ if (ioctl(fd, DRM_IOCTL_GET_CTX, &ctx)) return -errno;
+ *flags = 0;
+ if (ctx.flags & _DRM_CONTEXT_PRESERVED) *flags |= DRM_CONTEXT_PRESERVED;
+ if (ctx.flags & _DRM_CONTEXT_2DONLY) *flags |= DRM_CONTEXT_2DONLY;
+ return 0;
+}
+
+int drmDestroyContext(int fd, drmContext handle)
+{
+ drm_ctx_t ctx;
+ ctx.handle = handle;
+ if (ioctl(fd, DRM_IOCTL_RM_CTX, &ctx)) return -errno;
+ return 0;
+}
+
+int drmCreateDrawable(int fd, drmDrawablePtr handle)
+{
+ drm_draw_t draw;
+ if (ioctl(fd, DRM_IOCTL_ADD_DRAW, &draw)) return -errno;
+ *handle = draw.handle;
+ return 0;
+}
+
+int drmDestroyDrawable(int fd, drmDrawable handle)
+{
+ drm_draw_t draw;
+ draw.handle = handle;
+ if (ioctl(fd, DRM_IOCTL_RM_DRAW, &draw)) return -errno;
+ return 0;
+}
+
+int drmError(int err, const char *label)
+{
+ switch (err) {
+ case DRM_ERR_NO_DEVICE: fprintf(stderr, "%s: no device\n", label); break;
+ case DRM_ERR_NO_ACCESS: fprintf(stderr, "%s: no access\n", label); break;
+ case DRM_ERR_NOT_ROOT: fprintf(stderr, "%s: not root\n", label); break;
+ case DRM_ERR_INVALID: fprintf(stderr, "%s: invalid args\n", label);break;
+ default:
+ if (err < 0) err = -err;
+ fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) );
+ break;
+ }
+
+ return 1;
+}
+
+int drmCtlAddCommand(int fd, drmCtlDesc desc, int count, int *inst)
+{
+ drm_control_t ctl;
+
+ ctl.func = DRM_ADD_COMMAND;
+ ctl.irq = 0;
+ ctl.count = count;
+ ctl.inst = inst;
+
+ switch (desc) {
+ case DRM_IH_PRE_INST: ctl.desc = _DRM_IH_PRE_INST; break;
+ case DRM_IH_POST_INST: ctl.desc = _DRM_IH_POST_INST; break;
+ case DRM_IH_SERVICE: ctl.desc = _DRM_IH_SERVICE; break;
+ case DRM_IH_PRE_UNINST: ctl.desc = _DRM_IH_PRE_UNINST; break;
+ case DRM_IH_POST_UNINST: ctl.desc = _DRM_IH_POST_UNINST; break;
+ case DRM_DMA_DISPATCH: ctl.desc = _DRM_DMA_DISPATCH; break;
+ case DRM_DMA_READY: ctl.desc = _DRM_DMA_READY; break;
+ case DRM_DMA_IS_READY: ctl.desc = _DRM_DMA_IS_READY; break;
+ case DRM_DMA_QUIESCENT: ctl.desc = _DRM_DMA_QUIESCENT; break;
+ default:
+ return -EINVAL;
+ }
+
+ if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno;
+ return 0;
+}
+
+int drmCtlRemoveCommands(int fd)
+{
+ drm_control_t ctl;
+ drm_desc_t i;
+
+ for (i = 0; i < DRM_DESC_MAX; i++) {
+ ctl.func = DRM_RM_COMMAND;
+ ctl.desc = i;
+ ctl.irq = 0;
+ ctl.count = 0;
+ ctl.inst = NULL;
+ ioctl(fd, DRM_IOCTL_CONTROL, &ctl);
+ }
+ return 0;
+}
+
+int drmCtlInstHandler(int fd, int irq)
+{
+ drm_control_t ctl;
+
+ ctl.func = DRM_INST_HANDLER;
+ ctl.desc = 0; /* unused */
+ ctl.irq = irq;
+ ctl.count = 0;
+ ctl.inst = NULL;
+ if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno;
+ return 0;
+}
+
+int drmCtlUninstHandler(int fd)
+{
+ drm_control_t ctl;
+
+ ctl.func = DRM_UNINST_HANDLER;
+ ctl.desc = 0; /* unused */
+ ctl.irq = 0;
+ ctl.count = 0;
+ ctl.inst = NULL;
+ if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno;
+ return 0;
+}
+
+int drmFinish(int fd, int context, drmLockFlags flags)
+{
+ drm_lock_t lock;
+
+ lock.context = context;
+ lock.flags = 0;
+ if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY;
+ if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT;
+ if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH;
+ if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL;
+ if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
+ if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
+ if (ioctl(fd, DRM_IOCTL_FINISH, &lock)) return -errno;
+ return 0;
+}
+
+int drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum)
+{
+ drm_irq_busid_t p;
+
+ p.busnum = busnum;
+ p.devnum = devnum;
+ p.funcnum = funcnum;
+ if (ioctl(fd, DRM_IOCTL_IRQ_BUSID, &p)) return -errno;
+ return p.irq;
+}
+
+int drmAddContextTag(int fd, drmContext context, void *tag)
+{
+ drmHashEntry *entry = drmGetEntry(fd);
+
+ if (drmHashInsert(entry->tagTable, context, tag)) {
+ drmHashDelete(entry->tagTable, context);
+ drmHashInsert(entry->tagTable, context, tag);
+ }
+ return 0;
+}
+
+int drmDelContextTag(int fd, drmContext context)
+{
+ drmHashEntry *entry = drmGetEntry(fd);
+
+ return drmHashDelete(entry->tagTable, context);
+}
+
+void *drmGetContextTag(int fd, drmContext context)
+{
+ drmHashEntry *entry = drmGetEntry(fd);
+ void *value;
+
+ if (drmHashLookup(entry->tagTable, context, &value)) return NULL;
+
+ return value;
+}
+
+#if defined(XFree86Server) || defined(DRM_USE_MALLOC)
+static void drmSIGIOHandler(int interrupt)
+{
+ unsigned long key;
+ void *value;
+ ssize_t count;
+ drm_ctx_t ctx;
+ typedef void (*_drmCallback)(int, void *, void *);
+ char buf[256];
+ drmContext old;
+ drmContext new;
+ void *oldctx;
+ void *newctx;
+ char *pt;
+ drmHashEntry *entry;
+
+ if (!drmHashTable) return;
+ if (drmHashFirst(drmHashTable, &key, &value)) {
+ entry = value;
+ do {
+#if 0
+ fprintf(stderr, "Trying %d\n", entry->fd);
+#endif
+ if ((count = read(entry->fd, buf, sizeof(buf)))) {
+ buf[count] = '\0';
+#if 0
+ fprintf(stderr, "Got %s\n", buf);
+#endif
+
+ for (pt = buf; *pt != ' '; ++pt); /* Find first space */
+ ++pt;
+ old = strtol(pt, &pt, 0);
+ new = strtol(pt, NULL, 0);
+ oldctx = drmGetContextTag(entry->fd, old);
+ newctx = drmGetContextTag(entry->fd, new);
+#if 0
+ fprintf(stderr, "%d %d %p %p\n", old, new, oldctx, newctx);
+#endif
+ ((_drmCallback)entry->f)(entry->fd, oldctx, newctx);
+ ctx.handle = new;
+ ioctl(entry->fd, DRM_IOCTL_NEW_CTX, &ctx);
+ }
+ } while (drmHashNext(drmHashTable, &key, &value));
+ }
+}
+
+int drmInstallSIGIOHandler(int fd, void (*f)(int, void *, void *))
+{
+ drmHashEntry *entry;
+
+ entry = drmGetEntry(fd);
+ entry->f = f;
+
+ return xf86InstallSIGIOHandler(fd, drmSIGIOHandler);
+}
+
+int drmRemoveSIGIOHandler(int fd)
+{
+ drmHashEntry *entry = drmGetEntry(fd);
+
+ entry->f = NULL;
+
+ return xf86RemoveSIGIOHandler(fd);
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c
new file mode 100644
index 000000000..a3c9481b5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c
@@ -0,0 +1,435 @@
+/* xf86drmHash.c -- Small hash table support for integer -> integer mapping
+ * Created: Sun Apr 18 09:35:45 1999 by faith@precisioninsight.com
+ * Revised: Thu Jun 3 16:11:06 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c,v 1.3 1999/06/07 13:01:42 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmHash.c,v 1.1 1999/06/14 07:32:02 dawes Exp $
+ *
+ * DESCRIPTION
+ *
+ * This file contains a straightforward implementation of a fixed-sized
+ * hash table using self-organizing linked lists [Knuth73, pp. 398-399] for
+ * collision resolution. There are two potentially interesting things
+ * about this implementation:
+ *
+ * 1) The table is power-of-two sized. Prime sized tables are more
+ * traditional, but do not have a significant advantage over power-of-two
+ * sized table, especially when double hashing is not used for collision
+ * resolution.
+ *
+ * 2) The hash computation uses a table of random integers [Hanson97,
+ * pp. 39-41].
+ *
+ * FUTURE ENHANCEMENTS
+ *
+ * With a table size of 512, the current implementation is sufficient for a
+ * few hundred keys. Since this is well above the expected size of the
+ * tables for which this implementation was designed, the implementation of
+ * dynamic hash tables was postponed until the need arises. A common (and
+ * naive) approach to dynamic hash table implementation simply creates a
+ * new hash table when necessary, rehashes all the data into the new table,
+ * and destroys the old table. The approach in [Larson88] is superior in
+ * two ways: 1) only a portion of the table is expanded when needed,
+ * distributing the expansion cost over several insertions, and 2) portions
+ * of the table can be locked, enabling a scalable thread-safe
+ * implementation.
+ *
+ * REFERENCES
+ *
+ * [Hanson97] David R. Hanson. C Interfaces and Implementations:
+ * Techniques for Creating Reusable Software. Reading, Massachusetts:
+ * Addison-Wesley, 1997.
+ *
+ * [Knuth73] Donald E. Knuth. The Art of Computer Programming. Volume 3:
+ * Sorting and Searching. Reading, Massachusetts: Addison-Wesley, 1973.
+ *
+ * [Larson88] Per-Ake Larson. "Dynamic Hash Tables". CACM 31(4), April
+ * 1988, pp. 446-457.
+ *
+ */
+
+#define HASH_MAIN 0
+
+#if HASH_MAIN
+# include <stdio.h>
+# include <stdlib.h>
+#else
+# include "xf86drm.h"
+# ifdef XFree86LOADER
+# include "xf86.h"
+# include "xf86_ansic.h"
+# else
+# include <stdio.h>
+# include <stdlib.h>
+# endif
+#endif
+
+#define N(x) drm##x
+
+#define HASH_MAGIC 0xdeadbeef
+#define HASH_DEBUG 0
+#define HASH_SIZE 512 /* Good for about 100 entries */
+ /* If you change this value, you probably
+ have to change the HashHash hashing
+ function! */
+
+#if HASH_MAIN
+#define HASH_ALLOC malloc
+#define HASH_FREE free
+#define HASH_RANDOM_DECL
+#define HASH_RANDOM_INIT(seed) srandom(seed)
+#define HASH_RANDOM random()
+#else
+#define HASH_ALLOC drmMalloc
+#define HASH_FREE drmFree
+#define HASH_RANDOM_DECL void *state
+#define HASH_RANDOM_INIT(seed) state = drmRandomCreate(seed)
+#define HASH_RANDOM drmRandom(state)
+
+#endif
+
+typedef struct HashBucket {
+ unsigned long key;
+ void *value;
+ struct HashBucket *next;
+} HashBucket, *HashBucketPtr;
+
+typedef struct HashTable {
+ unsigned long magic;
+ unsigned long entries;
+ unsigned long hits; /* At top of linked list */
+ unsigned long partials; /* Not at top of linked list */
+ unsigned long misses; /* Not in table */
+ HashBucketPtr buckets[HASH_SIZE];
+ int p0;
+ HashBucketPtr p1;
+} HashTable, *HashTablePtr;
+
+#if HASH_MAIN
+extern void *N(HashCreate)(void);
+extern int N(HashDestroy)(void *t);
+extern int N(HashLookup)(void *t, unsigned long key, unsigned long *value);
+extern int N(HashInsert)(void *t, unsigned long key, unsigned long value);
+extern int N(HashDelete)(void *t, unsigned long key);
+#endif
+
+static unsigned long HashHash(unsigned long key)
+{
+ unsigned long hash = 0;
+ unsigned long tmp = key;
+ static int init = 0;
+ static unsigned long scatter[256];
+ int i;
+
+ if (!init) {
+ HASH_RANDOM_DECL;
+ HASH_RANDOM_INIT(37);
+ for (i = 0; i < 256; i++) scatter[i] = HASH_RANDOM;
+ ++init;
+ }
+
+ while (tmp) {
+ hash = (hash << 1) + scatter[tmp & 0xff];
+ tmp >>= 8;
+ }
+
+ hash %= HASH_SIZE;
+#if HASH_DEBUG
+ printf( "Hash(%d) = %d\n", key, hash);
+#endif
+ return hash;
+}
+
+void *N(HashCreate)(void)
+{
+ HashTablePtr table;
+ int i;
+
+ table = HASH_ALLOC(sizeof(*table));
+ if (!table) return NULL;
+ table->magic = HASH_MAGIC;
+ table->entries = 0;
+ table->hits = 0;
+ table->partials = 0;
+ table->misses = 0;
+
+ for (i = 0; i < HASH_SIZE; i++) table->buckets[i] = NULL;
+ return table;
+}
+
+int N(HashDestroy)(void *t)
+{
+ HashTablePtr table = (HashTablePtr)t;
+ HashBucketPtr bucket;
+ HashBucketPtr next;
+ int i;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ for (i = 0; i < HASH_SIZE; i++) {
+ for (bucket = table->buckets[i]; bucket;) {
+ next = bucket->next;
+ HASH_FREE(bucket);
+ bucket = next;
+ }
+ }
+ HASH_FREE(table);
+ return 0;
+}
+
+/* Find the bucket and organize the list so that this bucket is at the
+ top. */
+
+static HashBucketPtr HashFind(HashTablePtr table,
+ unsigned long key, unsigned long *h)
+{
+ unsigned long hash = HashHash(key);
+ HashBucketPtr prev = NULL;
+ HashBucketPtr bucket;
+
+ if (h) *h = hash;
+
+ for (bucket = table->buckets[hash]; bucket; bucket = bucket->next) {
+ if (bucket->key == key) {
+ if (prev) {
+ /* Organize */
+ prev->next = bucket->next;
+ bucket->next = table->buckets[hash];
+ table->buckets[hash] = bucket;
+ ++table->partials;
+ } else {
+ ++table->hits;
+ }
+ return bucket;
+ }
+ prev = bucket;
+ }
+ ++table->misses;
+ return NULL;
+}
+
+int N(HashLookup)(void *t, unsigned long key, void **value)
+{
+ HashTablePtr table = (HashTablePtr)t;
+ HashBucketPtr bucket;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ bucket = HashFind(table, key, NULL);
+ if (!bucket) return 1; /* Not found */
+ *value = bucket->value;
+ return 0; /* Found */
+}
+
+int N(HashInsert)(void *t, unsigned long key, void *value)
+{
+ HashTablePtr table = (HashTablePtr)t;
+ HashBucketPtr bucket;
+ unsigned long hash;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ if (HashFind(table, key, &hash)) return 1; /* Already in table */
+
+ bucket = HASH_ALLOC(sizeof(*bucket));
+ if (!bucket) return -1; /* Error */
+ bucket->key = key;
+ bucket->value = value;
+ bucket->next = table->buckets[hash];
+ table->buckets[hash] = bucket;
+#if HASH_DEBUG
+ printf("Inserted %d at %d/%p\n", key, hash, bucket);
+#endif
+ return 0; /* Added to table */
+}
+
+int N(HashDelete)(void *t, unsigned long key)
+{
+ HashTablePtr table = (HashTablePtr)t;
+ unsigned long hash;
+ HashBucketPtr bucket;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ bucket = HashFind(table, key, &hash);
+
+ if (!bucket) return 1; /* Not found */
+
+ table->buckets[hash] = bucket->next;
+ HASH_FREE(bucket);
+ return 0;
+}
+
+int N(HashNext)(void *t, unsigned long *key, void **value)
+{
+ HashTablePtr table = (HashTablePtr)t;
+
+ for (; table->p0 < HASH_SIZE;
+ ++table->p0, table->p1 = table->buckets[table->p0]) {
+ if (table->p1) {
+ *key = table->p1->key;
+ *value = table->p1->value;
+ table->p1 = table->p1->next;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int N(HashFirst)(void *t, unsigned long *key, void **value)
+{
+ HashTablePtr table = (HashTablePtr)t;
+
+ if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
+
+ table->p0 = 0;
+ table->p1 = table->buckets[0];
+ return N(HashNext)(table, key, value);
+}
+
+#if HASH_MAIN
+#define DIST_LIMIT 10
+static int dist[DIST_LIMIT];
+
+static void clear_dist(void) {
+ int i;
+
+ for (i = 0; i < DIST_LIMIT; i++) dist[i] = 0;
+}
+
+static int count_entries(HashBucketPtr bucket)
+{
+ int count = 0;
+
+ for (; bucket; bucket = bucket->next) ++count;
+ return count;
+}
+
+static void update_dist(int count)
+{
+ if (count >= DIST_LIMIT) ++dist[DIST_LIMIT-1];
+ else ++dist[count];
+}
+
+static void compute_dist(HashTablePtr table)
+{
+ int i;
+ HashBucketPtr bucket;
+
+ printf("Entries = %ld, hits = %ld, partials = %ld, misses = %ld\n",
+ table->entries, table->hits, table->partials, table->misses);
+ clear_dist();
+ for (i = 0; i < HASH_SIZE; i++) {
+ bucket = table->buckets[i];
+ update_dist(count_entries(bucket));
+ }
+ for (i = 0; i < DIST_LIMIT; i++) {
+ if (i != DIST_LIMIT-1) printf("%5d %10d\n", i, dist[i]);
+ else printf("other %10d\n", dist[i]);
+ }
+}
+
+static void check_table(HashTablePtr table,
+ unsigned long key, unsigned long value)
+{
+ unsigned long retval = 0;
+ int retcode = N(HashLookup)(table, key, &retval);
+
+ switch (retcode) {
+ case -1:
+ printf("Bad magic = 0x%08lx:"
+ " key = %lu, expected = %lu, returned = %lu\n",
+ table->magic, key, value, retval);
+ break;
+ case 1:
+ printf("Not found: key = %lu, expected = %lu returned = %lu\n",
+ key, value, retval);
+ break;
+ case 0:
+ if (value != retval)
+ printf("Bad value: key = %lu, expected = %lu, returned = %lu\n",
+ key, value, retval);
+ break;
+ default:
+ printf("Bad retcode = %d: key = %lu, expected = %lu, returned = %lu\n",
+ retcode, key, value, retval);
+ break;
+ }
+}
+
+int main(void)
+{
+ HashTablePtr table;
+ int i;
+
+ printf("\n***** 256 consecutive integers ****\n");
+ table = N(HashCreate)();
+ for (i = 0; i < 256; i++) N(HashInsert)(table, i, i);
+ for (i = 0; i < 256; i++) check_table(table, i, i);
+ for (i = 256; i >= 0; i--) check_table(table, i, i);
+ compute_dist(table);
+ N(HashDestroy)(table);
+
+ printf("\n***** 1024 consecutive integers ****\n");
+ table = N(HashCreate)();
+ for (i = 0; i < 1024; i++) N(HashInsert)(table, i, i);
+ for (i = 0; i < 1024; i++) check_table(table, i, i);
+ for (i = 1024; i >= 0; i--) check_table(table, i, i);
+ compute_dist(table);
+ N(HashDestroy)(table);
+
+ printf("\n***** 1024 consecutive page addresses (4k pages) ****\n");
+ table = N(HashCreate)();
+ for (i = 0; i < 1024; i++) N(HashInsert)(table, i*4096, i);
+ for (i = 0; i < 1024; i++) check_table(table, i*4096, i);
+ for (i = 1024; i >= 0; i--) check_table(table, i*4096, i);
+ compute_dist(table);
+ N(HashDestroy)(table);
+
+ printf("\n***** 1024 random integers ****\n");
+ table = N(HashCreate)();
+ srandom(0xbeefbeef);
+ for (i = 0; i < 1024; i++) N(HashInsert)(table, random(), i);
+ srandom(0xbeefbeef);
+ for (i = 0; i < 1024; i++) check_table(table, random(), i);
+ srandom(0xbeefbeef);
+ for (i = 0; i < 1024; i++) check_table(table, random(), i);
+ compute_dist(table);
+ N(HashDestroy)(table);
+
+ printf("\n***** 5000 random integers ****\n");
+ table = N(HashCreate)();
+ srandom(0xbeefbeef);
+ for (i = 0; i < 5000; i++) N(HashInsert)(table, random(), i);
+ srandom(0xbeefbeef);
+ for (i = 0; i < 5000; i++) check_table(table, random(), i);
+ srandom(0xbeefbeef);
+ for (i = 0; i < 5000; i++) check_table(table, random(), i);
+ compute_dist(table);
+ N(HashDestroy)(table);
+
+ return 0;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRandom.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRandom.c
new file mode 100644
index 000000000..dad836d02
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRandom.c
@@ -0,0 +1,219 @@
+/* xf86drmRandom.c -- "Minimal Standard" PRNG Implementation
+ * Created: Mon Apr 19 08:28:13 1999 by faith@precisioninsight.com
+ * Revised: Thu Jun 24 14:53:45 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRandom.c,v 1.4 1999/06/24 18:54:55 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRandom.c,v 1.2 1999/06/27 14:08:20 dawes Exp $
+ *
+ * DESCRIPTION
+ *
+ * This file contains a simple, straightforward implementation of the Park
+ * & Miller "Minimal Standard" PRNG [PM88, PMS93], which is a Lehmer
+ * multiplicative linear congruential generator (MLCG) with a period of
+ * 2^31-1.
+ *
+ * This implementation is intended to provide a reliable, portable PRNG
+ * that is suitable for testing a hash table implementation and for
+ * implementing skip lists.
+ *
+ * FUTURE ENHANCEMENTS
+ *
+ * If initial seeds are not selected randomly, two instances of the PRNG
+ * can be correlated. [Knuth81, pp. 32-33] describes a shuffling technique
+ * that can eliminate this problem.
+ *
+ * If PRNGs are used for simulation, the period of the current
+ * implementation may be too short. [LE88] discusses methods of combining
+ * MLCGs to produce much longer periods, and suggests some alternative
+ * values for A and M. [LE90 and Sch92] also provide information on
+ * long-period PRNGs.
+ *
+ * REFERENCES
+ *
+ * [Knuth81] Donald E. Knuth. The Art of Computer Programming. Volume 2:
+ * Seminumerical Algorithms. Reading, Massachusetts: Addison-Wesley, 1981.
+ *
+ * [LE88] Pierre L'Ecuyer. "Efficient and Portable Combined Random Number
+ * Generators". CACM 31(6), June 1988, pp. 742-774.
+ *
+ * [LE90] Pierre L'Ecuyer. "Random Numbers for Simulation". CACM 33(10,
+ * October 1990, pp. 85-97.
+ *
+ * [PM88] Stephen K. Park and Keith W. Miller. "Random Number Generators:
+ * Good Ones are Hard to Find". CACM 31(10), October 1988, pp. 1192-1201.
+ *
+ * [Sch92] Bruce Schneier. "Pseudo-Ransom Sequence Generator for 32-Bit
+ * CPUs". Dr. Dobb's Journal 17(2), February 1992, pp. 34, 37-38, 40.
+ *
+ * [PMS93] Stephen K. Park, Keith W. Miller, and Paul K. Stockmeyer. In
+ * "Technical Correspondence: Remarks on Choosing and Implementing Random
+ * Number Generators". CACM 36(7), July 1993, pp. 105-110.
+ *
+ */
+
+#define RANDOM_MAIN 0
+
+#if RANDOM_MAIN
+# include <stdio.h>
+# include <stdlib.h>
+#else
+# include "xf86drm.h"
+# ifdef XFree86LOADER
+# include "xf86.h"
+# include "xf86_ansic.h"
+# else
+# include <stdio.h>
+# include <stdlib.h>
+# endif
+#endif
+
+#define N(x) drm##x
+
+#define RANDOM_MAGIC 0xfeedbeef
+#define RANDOM_DEBUG 0
+
+#if RANDOM_MAIN
+#define RANDOM_ALLOC malloc
+#define RANDOM_FREE free
+#else
+#define RANDOM_ALLOC drmMalloc
+#define RANDOM_FREE drmFree
+#endif
+
+typedef struct RandomState {
+ unsigned long magic;
+ unsigned long a;
+ unsigned long m;
+ unsigned long q; /* m div a */
+ unsigned long r; /* m mod a */
+ unsigned long check;
+ long seed;
+} RandomState;
+
+#if RANDOM_MAIN
+extern void *N(RandomCreate)(unsigned long seed);
+extern int N(RandomDestroy)(void *state);
+extern unsigned long N(Random)(void *state);
+extern double N(RandomDouble)(void *state);
+#endif
+
+void *N(RandomCreate)(unsigned long seed)
+{
+ RandomState *state;
+
+ state = RANDOM_ALLOC(sizeof(*state));
+ if (!state) return NULL;
+ state->magic = RANDOM_MAGIC;
+#if 0
+ /* Park & Miller, October 1988 */
+ state->a = 16807;
+ state->m = 2147483647;
+ state->check = 1043618065; /* After 10000 iterations */
+#else
+ /* Park, Miller, and Stockmeyer, July 1993 */
+ state->a = 48271;
+ state->m = 2147483647;
+ state->check = 399268537; /* After 10000 iterations */
+#endif
+ state->q = state->m / state->a;
+ state->r = state->m % state->a;
+
+ state->seed = seed;
+ /* Check for illegal boundary conditions,
+ and choose closest legal value. */
+ if (state->seed <= 0) state->seed = 1;
+ if (state->seed >= state->m) state->seed = state->m - 1;
+
+ return state;
+}
+
+int N(RandomDestroy)(void *state)
+{
+ RANDOM_FREE(state);
+ return 0;
+}
+
+unsigned long N(Random)(void *state)
+{
+ RandomState *s = (RandomState *)state;
+ long hi;
+ long lo;
+
+ hi = s->seed / s->q;
+ lo = s->seed % s->q;
+ s->seed = s->a * lo - s->r * hi;
+ if (s->seed <= 0) s->seed += s->m;
+
+ return s->seed;
+}
+
+double N(RandomDouble)(void *state)
+{
+ RandomState *s = (RandomState *)state;
+
+ return (double)N(Random)(state)/(double)s->m;
+}
+
+#if RANDOM_MAIN
+static void check_period(long seed)
+{
+ unsigned long count = 0;
+ unsigned long initial;
+ void *state;
+
+ state = N(RandomCreate)(seed);
+ initial = N(Random)(state);
+ ++count;
+ while (initial != N(Random)(state)) {
+ if (!++count) break;
+ }
+ printf("With seed of %10ld, period = %10lu (0x%08lx)\n",
+ seed, count, count);
+ N(RandomDestroy)(state);
+}
+
+int main(void)
+{
+ RandomState *state;
+ int i;
+ unsigned long rand;
+
+ state = N(RandomCreate)(1);
+ for (i = 0; i < 10000; i++) {
+ rand = N(Random)(state);
+ }
+ printf("After 10000 iterations: %lu (%lu expected): %s\n",
+ rand, state->check,
+ rand - state->check ? "*INCORRECT*" : "CORRECT");
+ N(RandomDestroy)(state);
+
+ printf("Checking periods...\n");
+ check_period(1);
+ check_period(2);
+ check_period(31415926);
+
+ return 0;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmSL.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmSL.c
new file mode 100644
index 000000000..d5dd63da8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmSL.c
@@ -0,0 +1,490 @@
+/* xf86drmSL.c -- Skip list support
+ * Created: Mon May 10 09:28:13 1999 by faith@precisioninsight.com
+ * Revised: Thu Jun 3 16:13:01 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmSL.c,v 1.2 1999/06/07 13:01:42 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmSL.c,v 1.1 1999/06/14 07:32:02 dawes Exp $
+ *
+ * DESCRIPTION
+ *
+ * This file contains a straightforward skip list implementation.n
+ *
+ * FUTURE ENHANCEMENTS
+ *
+ * REFERENCES
+ *
+ * [Pugh90] William Pugh. Skip Lists: A Probabilistic Alternative to
+ * Balanced Trees. CACM 33(6), June 1990, pp. 668-676.
+ *
+ */
+
+#define SL_MAIN 0
+
+#if SL_MAIN
+# include <stdio.h>
+# include <stdlib.h>
+# include <sys/time.h>
+#else
+# include "xf86drm.h"
+# ifdef XFree86LOADER
+# include "xf86.h"
+# include "xf86_ansic.h"
+# else
+# include <stdio.h>
+# include <stdlib.h>
+# endif
+#endif
+
+#define N(x) drm##x
+
+#define SL_LIST_MAGIC 0xfacade00LU
+#define SL_ENTRY_MAGIC 0x00fab1edLU
+#define SL_FREED_MAGIC 0xdecea5edLU
+#define SL_MAX_LEVEL 16
+#define SL_DEBUG 0
+#define SL_RANDOM_SEED 0xc01055a1LU
+
+#if SL_MAIN
+#define SL_ALLOC malloc
+#define SL_FREE free
+#define SL_RANDOM_DECL static int state = 0;
+#define SL_RANDOM_INIT(seed) if (!state) { srandom(seed); ++state; }
+#define SL_RANDOM random()
+#else
+#define SL_ALLOC drmMalloc
+#define SL_FREE drmFree
+#define SL_RANDOM_DECL static void *state = NULL
+#define SL_RANDOM_INIT(seed) if (!state) state = drmRandomCreate(seed)
+#define SL_RANDOM drmRandom(state)
+
+#endif
+
+typedef struct SLEntry {
+ unsigned long magic; /* SL_ENTRY_MAGIC */
+ unsigned long key;
+ void *value;
+ int levels;
+ struct SLEntry *forward[1]; /* variable sized array */
+} SLEntry, *SLEntryPtr;
+
+typedef struct SkipList {
+ unsigned long magic; /* SL_LIST_MAGIC */
+ int level;
+ int count;
+ SLEntryPtr head;
+ SLEntryPtr p0; /* Position for iteration */
+} SkipList, *SkipListPtr;
+
+#if SL_MAIN
+extern void *N(SLCreate)(void);
+extern int N(SLDestroy)(void *l);
+extern int N(SLLookup)(void *l, unsigned long key, void **value);
+extern int N(SLInsert)(void *l, unsigned long key, void *value);
+extern int N(SLDelete)(void *l, unsigned long key);
+extern int N(SLNext)(void *l, unsigned long *key, void **value);
+extern int N(SLFirst)(void *l, unsigned long *key, void **value);
+extern void N(SLDump)(void *l);
+extern int N(SLLookupNeighbors)(void *l, unsigned long key,
+ unsigned long *prev_key, void **prev_value,
+ unsigned long *next_key, void **next_value);
+#endif
+
+static SLEntryPtr SLCreateEntry(int max_level, unsigned long key, void *value)
+{
+ SLEntryPtr entry;
+
+ if (max_level < 0 || max_level > SL_MAX_LEVEL) max_level = SL_MAX_LEVEL;
+
+ entry = SL_ALLOC(sizeof(*entry)
+ + (max_level + 1) * sizeof(entry->forward[0]));
+ if (!entry) return NULL;
+ entry->magic = SL_ENTRY_MAGIC;
+ entry->key = key;
+ entry->value = value;
+ entry->levels = max_level + 1;
+
+ return entry;
+}
+
+static int SLRandomLevel(void)
+{
+ int level = 1;
+ SL_RANDOM_DECL;
+
+ SL_RANDOM_INIT(SL_RANDOM_SEED);
+
+ while ((SL_RANDOM & 0x01) && level < SL_MAX_LEVEL) ++level;
+ return level;
+}
+
+void *N(SLCreate)(void)
+{
+ SkipListPtr list;
+ int i;
+
+ list = SL_ALLOC(sizeof(*list));
+ if (!list) return NULL;
+ list->magic = SL_LIST_MAGIC;
+ list->level = 0;
+ list->head = SLCreateEntry(SL_MAX_LEVEL, 0, NULL);
+ list->count = 0;
+
+ for (i = 0; i <= SL_MAX_LEVEL; i++) list->head->forward[i] = NULL;
+
+ return list;
+}
+
+int N(SLDestroy)(void *l)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr entry;
+ SLEntryPtr next;
+
+ if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
+
+ for (entry = list->head; entry; entry = next) {
+ if (entry->magic != SL_ENTRY_MAGIC) return -1; /* Bad magic */
+ next = entry->forward[0];
+ entry->magic = SL_FREED_MAGIC;
+ SL_FREE(entry);
+ }
+
+ list->magic = SL_FREED_MAGIC;
+ SL_FREE(list);
+ return 0;
+}
+
+static SLEntryPtr SLLocate(void *l, unsigned long key, SLEntryPtr *update)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr entry;
+ int i;
+
+ if (list->magic != SL_LIST_MAGIC) return NULL;
+
+ for (i = list->level, entry = list->head; i >= 0; i--) {
+ while (entry->forward[i] && entry->forward[i]->key < key)
+ entry = entry->forward[i];
+ update[i] = entry;
+ }
+
+ return entry->forward[0];
+}
+
+int N(SLInsert)(void *l, unsigned long key, void *value)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr entry;
+ SLEntryPtr update[SL_MAX_LEVEL + 1];
+ int level;
+ int i;
+
+ if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
+
+ entry = SLLocate(list, key, update);
+
+ if (entry && entry->key == key) return 1; /* Already in list */
+
+
+ level = SLRandomLevel();
+ if (level > list->level) {
+ level = ++list->level;
+ update[level] = list->head;
+ }
+
+ entry = SLCreateEntry(level, key, value);
+
+ /* Fix up forward pointers */
+ for (i = 0; i <= level; i++) {
+ entry->forward[i] = update[i]->forward[i];
+ update[i]->forward[i] = entry;
+ }
+
+ ++list->count;
+ return 0; /* Added to table */
+}
+
+int N(SLDelete)(void *l, unsigned long key)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr update[SL_MAX_LEVEL + 1];
+ SLEntryPtr entry;
+ int i;
+
+ if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
+
+ entry = SLLocate(list, key, update);
+
+ if (!entry || entry->key != key) return 1; /* Not found */
+
+ /* Fix up forward pointers */
+ for (i = 0; i <= list->level; i++) {
+ if (update[i]->forward[i] == entry)
+ update[i]->forward[i] = entry->forward[i];
+ }
+
+ entry->magic = SL_FREED_MAGIC;
+ SL_FREE(entry);
+
+ while (list->level && !list->head->forward[list->level]) --list->level;
+ --list->count;
+ return 0;
+}
+
+int N(SLLookup)(void *l, unsigned long key, void **value)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr update[SL_MAX_LEVEL + 1];
+ SLEntryPtr entry;
+
+ entry = SLLocate(list, key, update);
+
+ if (entry && entry->key == key) {
+ *value = entry;
+ return 0;
+ }
+ *value = NULL;
+ return -1;
+}
+
+int N(SLLookupNeighbors)(void *l, unsigned long key,
+ unsigned long *prev_key, void **prev_value,
+ unsigned long *next_key, void **next_value)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr update[SL_MAX_LEVEL + 1];
+ SLEntryPtr entry;
+ int retcode = 0;
+
+ entry = SLLocate(list, key, update);
+
+ *prev_key = *next_key = key;
+ *prev_value = *next_value = NULL;
+
+ if (update[0]) {
+ *prev_key = update[0]->key;
+ *prev_value = update[0]->value;
+ ++retcode;
+ if (update[0]->forward[0]) {
+ *next_key = update[0]->forward[0]->key;
+ *next_value = update[0]->forward[0]->value;
+ ++retcode;
+ }
+ }
+ return retcode;
+}
+
+int N(SLNext)(void *l, unsigned long *key, void **value)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr entry;
+
+ if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
+
+ entry = list->p0;
+
+ if (entry) {
+ list->p0 = entry->forward[0];
+ *key = entry->key;
+ *value = entry->value;
+ return 1;
+ }
+ list->p0 = NULL;
+ return 0;
+}
+
+int N(SLFirst)(void *l, unsigned long *key, void **value)
+{
+ SkipListPtr list = (SkipListPtr)l;
+
+ if (list->magic != SL_LIST_MAGIC) return -1; /* Bad magic */
+
+ list->p0 = list->head->forward[0];
+ return N(SLNext)(list, key, value);
+}
+
+/* Dump internal data structures for debugging. */
+void N(SLDump)(void *l)
+{
+ SkipListPtr list = (SkipListPtr)l;
+ SLEntryPtr entry;
+ int i;
+
+ if (list->magic != SL_LIST_MAGIC) {
+ printf("Bad magic: 0x%08lx (expected 0x%08lx)\n",
+ list->magic, SL_LIST_MAGIC);
+ return;
+ }
+
+ printf("Level = %d, count = %d\n", list->level, list->count);
+ for (entry = list->head; entry; entry = entry->forward[0]) {
+ if (entry->magic != SL_ENTRY_MAGIC) {
+ printf("Bad magic: 0x%08lx (expected 0x%08lx)\n",
+ list->magic, SL_ENTRY_MAGIC);
+ }
+ printf("\nEntry %p <0x%08lx, %p> has %2d levels\n",
+ entry, entry->key, entry->value, entry->levels);
+ for (i = 0; i < entry->levels; i++) {
+ if (entry->forward[i]) {
+ printf(" %2d: %p <0x%08lx, %p>\n",
+ i,
+ entry->forward[i],
+ entry->forward[i]->key,
+ entry->forward[i]->value);
+ } else {
+ printf(" %2d: %p\n", i, entry->forward[i]);
+ }
+ }
+ }
+}
+
+#if SL_MAIN
+static void print(SkipListPtr list)
+{
+ unsigned long key;
+ void *value;
+
+ if (N(SLFirst)(list, &key, &value)) {
+ do {
+ printf("key = %5lu, value = %p\n", key, value);
+ } while (N(SLNext)(list, &key, &value));
+ }
+}
+
+static double do_time(int size, int iter)
+{
+ SkipListPtr list;
+ int i, j;
+ unsigned long keys[1000000];
+ unsigned long previous;
+ unsigned long key;
+ void *value;
+ struct timeval start, stop;
+ double usec;
+ SL_RANDOM_DECL;
+
+ SL_RANDOM_INIT(12345);
+
+ list = N(SLCreate)();
+
+ for (i = 0; i < size; i++) {
+ keys[i] = SL_RANDOM;
+ N(SLInsert)(list, keys[i], NULL);
+ }
+
+ previous = 0;
+ if (N(SLFirst)(list, &key, &value)) {
+ do {
+ if (key <= previous) {
+ printf( "%lu !< %lu\n", previous, key);
+ }
+ previous = key;
+ } while (N(SLNext)(list, &key, &value));
+ }
+
+ gettimeofday(&start, NULL);
+ for (j = 0; j < iter; j++) {
+ for (i = 0; i < size; i++) {
+ if (N(SLLookup)(list, keys[i], &value))
+ printf("Error %lu %d\n", keys[i], i);
+ }
+ }
+ gettimeofday(&stop, NULL);
+
+ usec = (double)(stop.tv_sec * 1000000 + stop.tv_usec
+ - start.tv_sec * 1000000 - start.tv_usec) / (size * iter);
+
+ printf("%0.2f microseconds for list length %d\n", usec, size);
+
+ N(SLDestroy)(list);
+
+ return usec;
+}
+
+static void print_neighbors(void *list, unsigned long key)
+{
+ unsigned long prev_key = 0;
+ unsigned long next_key = 0;
+ void *prev_value;
+ void *next_value;
+ int retval;
+
+ retval = drmSLLookupNeighbors(list, key,
+ &prev_key, &prev_value,
+ &next_key, &next_value);
+ printf("Neighbors of %5lu: %d %5lu %5lu\n",
+ key, retval, prev_key, next_key);
+}
+
+int main(void)
+{
+ SkipListPtr list;
+ double usec, usec2, usec3, usec4;
+
+ list = N(SLCreate)();
+ printf( "list at %p\n", list);
+
+ print(list);
+ printf("\n==============================\n\n");
+
+ N(SLInsert)(list, 123, NULL);
+ N(SLInsert)(list, 213, NULL);
+ N(SLInsert)(list, 50, NULL);
+ print(list);
+ printf("\n==============================\n\n");
+
+ print_neighbors(list, 0);
+ print_neighbors(list, 50);
+ print_neighbors(list, 51);
+ print_neighbors(list, 123);
+ print_neighbors(list, 200);
+ print_neighbors(list, 213);
+ print_neighbors(list, 256);
+ printf("\n==============================\n\n");
+
+ N(SLDelete)(list, 50);
+ print(list);
+ printf("\n==============================\n\n");
+
+ N(SLDump)(list);
+ N(SLDestroy)(list);
+ printf("\n==============================\n\n");
+
+ usec = do_time(100, 10000);
+ usec2 = do_time(1000, 500);
+ printf("Table size increased by %0.2f, search time increased by %0.2f\n",
+ 1000.0/100.0, usec2 / usec);
+
+ usec3 = do_time(10000, 50);
+ printf("Table size increased by %0.2f, search time increased by %0.2f\n",
+ 10000.0/100.0, usec3 / usec);
+
+ usec4 = do_time(100000, 4);
+ printf("Table size increased by %0.2f, search time increased by %0.2f\n",
+ 100000.0/100.0, usec4 / usec);
+
+ return 0;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_init.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_init.c
new file mode 100644
index 000000000..17cbaee9b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_init.c
@@ -0,0 +1,264 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_init.c,v 3.10 1998/07/25 16:56:42 dawes Exp $ */
+/*
+ * Copyright 1992 by Orest Zborowski <obz@Kodak.com>
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Orest Zborowski and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Orest Zborowski
+ * and David Wexelblat make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * OREST ZBOROWSKI AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: lnx_init.c /main/7 1996/10/23 18:46:30 kaleb $ */
+
+#include "X.h"
+#include "Xmd.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#ifdef USE_DEV_FB
+extern char *getenv(const char *);
+#include <linux/fb.h>
+char *fb_dev_name;
+#endif
+
+static Bool KeepTty = FALSE;
+static int VTnum = -1;
+static int activeVT = -1;
+
+void
+xf86OpenConsole()
+{
+ int i, fd;
+ struct vt_mode VT;
+ char vtname[11];
+ struct vt_stat vts;
+ MessageType from = X_PROBED;
+#ifdef USE_DEV_FB
+ struct fb_var_screeninfo var;
+ int fbfd;
+#endif
+
+ if (serverGeneration == 1)
+ {
+ /* check if we're run with euid==0 */
+ if (geteuid() != 0)
+ {
+ FatalError("xf86OpenConsole: Server must be suid root\n");
+ }
+
+ /*
+ * setup the virtual terminal manager
+ */
+ if (VTnum != -1)
+ {
+ xf86Info.vtno = VTnum;
+ from = X_CMDLINE;
+ }
+ else
+ {
+ if ((fd = open("/dev/tty0",O_WRONLY,0)) < 0)
+ {
+ FatalError(
+ "xf86OpenConsole: Cannot open /dev/tty0 (%s)\n",
+ strerror(errno));
+ }
+ if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
+ (xf86Info.vtno == -1))
+ {
+ FatalError("xf86OpenConsole: Cannot find a free VT\n");
+ }
+ close(fd);
+ }
+
+#ifdef USE_DEV_FB
+ fb_dev_name=getenv("FRAMEBUFFER");
+ if (!fb_dev_name)
+ fb_dev_name="/dev/fb0current";
+ if ((fbfd = open(fb_dev_name, O_RDONLY)) < 0)
+ FatalError("xf86OpenConsole: Cannot open %s (%s)\n",
+ fb_dev_name, strerror(errno));
+ if (ioctl(fbfd, FBIOGET_VSCREENINFO, &var))
+ FatalError("xf86OpenConsole: Unable to get screen info\n");
+#endif
+ xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
+
+ sprintf(vtname,"/dev/tty%d",xf86Info.vtno); /* /dev/tty1-64 */
+
+ if (!KeepTty)
+ {
+ setpgrp();
+ }
+
+ if ((xf86Info.consoleFd = open(vtname, O_RDWR|O_NDELAY, 0)) < 0)
+ {
+ FatalError("xf86OpenConsole: Cannot open %s (%s)\n",
+ vtname, strerror(errno));
+ }
+
+ /* change ownership of the vt */
+ chown(vtname, getuid(), getgid());
+
+ /*
+ * the current VT device we're running on is not "console", we want
+ * to grab all consoles too
+ *
+ * Why is this needed??
+ */
+ chown("/dev/tty0", getuid(), getgid());
+
+ /*
+ * Linux doesn't switch to an active vt after the last close of a vt,
+ * so we do this ourselves by remembering which is active now.
+ */
+ if (ioctl(xf86Info.consoleFd, VT_GETSTATE, &vts) == 0)
+ {
+ activeVT = vts.v_active;
+ }
+
+ if (!KeepTty)
+ {
+ /*
+ * Detach from the controlling tty to avoid char loss
+ */
+ if ((i = open("/dev/tty",O_RDWR)) >= 0)
+ {
+ ioctl(i, TIOCNOTTY, 0);
+ close(i);
+ }
+ }
+
+ /*
+ * now get the VT
+ */
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
+ {
+ FatalError("xf86OpenConsole: VT_GETMODE failed\n");
+ }
+
+ signal(SIGUSR1, xf86VTRequest);
+
+ VT.mode = VT_PROCESS;
+ VT.relsig = SIGUSR1;
+ VT.acqsig = SIGUSR1;
+ if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
+ {
+ FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0)
+ {
+ FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed\n");
+ }
+#ifdef USE_DEV_FB
+ /* copy info to new console */
+ var.yoffset=0;
+ var.xoffset=0;
+ if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &var))
+ FatalError("Unable to set screen info\n");
+ close(fbfd);
+#endif
+ }
+ else
+ {
+ /* serverGeneration != 1 */
+ /*
+ * now get the VT
+ */
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
+ }
+ }
+ return;
+}
+
+void
+xf86CloseConsole()
+{
+ struct vt_mode VT;
+
+#if 0
+ ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno);
+ ioctl(xf86Info.consoleFd, VT_WAITACTIVE, 0);
+#endif
+ ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); /* Back to text mode ... */
+ if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1)
+ {
+ VT.mode = VT_AUTO;
+ ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* set dflt vt handling */
+ }
+ /*
+ * Perform a switch back to the active VT when we were started
+ */
+ if (activeVT >= 0)
+ {
+ ioctl(xf86Info.consoleFd, VT_ACTIVATE, activeVT);
+ activeVT = -1;
+ }
+ close(xf86Info.consoleFd); /* make the vt-manager happy */
+ return;
+}
+
+int
+xf86ProcessArgument(int argc, char *argv[], int i)
+{
+ /*
+ * Keep server from detaching from controlling tty. This is useful
+ * when debugging (so the server can receive keyboard signals.
+ */
+ if (!strcmp(argv[i], "-keeptty"))
+ {
+ KeepTty = TRUE;
+ return(1);
+ }
+ if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
+ {
+ if (sscanf(argv[i], "vt%2d", &VTnum) == 0)
+ {
+ UseMsg();
+ VTnum = -1;
+ return(0);
+ }
+ return(1);
+ }
+ return(0);
+}
+
+void
+xf86UseMsg()
+{
+ ErrorF("vtXX use the specified VT number\n");
+ ErrorF("-keeptty ");
+ ErrorF("don't detach controlling tty (for debugging only)\n");
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_io.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_io.c
new file mode 100644
index 000000000..a1cb5c37e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_io.c
@@ -0,0 +1,139 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_io.c,v 3.8 1999/07/04 06:39:15 dawes Exp $ */
+/*
+ * Copyright 1992 by Orest Zborowski <obz@Kodak.com>
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Orest Zborowski and David Dawes
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Orest Zborowski
+ * and David Dawes make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * OREST ZBOROWSKI AND DAVID DAWES DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID DAWES 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.
+ *
+ */
+/* $XConsortium: lnx_io.c /main/8 1996/10/19 18:06:28 kaleb $ */
+
+#define NEED_EVENTS
+#include "X.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+void
+xf86SoundKbdBell(int loudness, int pitch, int duration)
+{
+ if (loudness && pitch)
+ {
+ ioctl(xf86Info.consoleFd, KDMKTONE,
+ ((1193190 / pitch) & 0xffff) |
+ (((unsigned long)duration *
+ loudness / 50) << 16));
+ }
+}
+
+void
+xf86SetKbdLeds(int leds)
+{
+ ioctl(xf86Info.consoleFd, KDSETLED, leds);
+}
+
+int
+xf86GetKbdLeds()
+{
+ int leds;
+
+ ioctl(xf86Info.consoleFd, KDGETLED, &leds);
+ return(leds);
+}
+
+void
+xf86SetKbdRepeat(char rad)
+{
+ return;
+}
+
+static int kbdtrans;
+static struct termios kbdtty;
+
+void
+xf86KbdInit()
+{
+ ioctl (xf86Info.consoleFd, KDGKBMODE, &kbdtrans);
+ tcgetattr (xf86Info.consoleFd, &kbdtty);
+}
+
+int
+xf86KbdOn()
+{
+ struct termios nTty;
+
+#ifdef __powerpc__
+ ioctl(xf86Info.consoleFd, KDSKBMODE, K_MEDIUMRAW);
+#else
+ ioctl(xf86Info.consoleFd, KDSKBMODE, K_RAW);
+#endif
+ nTty = kbdtty;
+ nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
+ nTty.c_oflag = 0;
+ nTty.c_cflag = CREAD | CS8;
+ nTty.c_lflag = 0;
+ nTty.c_cc[VTIME]=0;
+ nTty.c_cc[VMIN]=1;
+ cfsetispeed(&nTty, 9600);
+ cfsetospeed(&nTty, 9600);
+ tcsetattr(xf86Info.consoleFd, TCSANOW, &nTty);
+ return(xf86Info.consoleFd);
+}
+
+int
+xf86KbdOff()
+{
+ ioctl(xf86Info.consoleFd, KDSKBMODE, kbdtrans);
+ tcsetattr(xf86Info.consoleFd, TCSANOW, &kbdtty);
+ return(xf86Info.consoleFd);
+}
+
+#ifndef NEW_INPUT
+void
+xf86MouseInit(MouseDevPtr mouse)
+{
+ return;
+}
+
+int
+xf86MouseOn(MouseDevPtr mouse)
+{
+ if ((mouse->mseFd = open(mouse->mseDevice, O_RDWR | O_NDELAY)) < 0)
+ {
+ if (xf86Info.allowMouseOpenFail) {
+ xf86Msg(X_WARNING,
+ "Cannot open mouse (%s) - Continuing...\n",
+ strerror(errno));
+ return(-2);
+ }
+ FatalError("Cannot open mouse (%s)\n", strerror(errno));
+ }
+
+ xf86SetupMouse(mouse);
+
+ /* Flush any pending input */
+ tcflush(mouse->mseFd, TCIFLUSH);
+
+ return(mouse->mseFd);
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_jstk.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_jstk.c
new file mode 100644
index 000000000..2423bd45e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_jstk.c
@@ -0,0 +1,184 @@
+/* $XConsortium: lnx_jstk.c /main/7 1996/02/21 17:51:36 kaleb $ */
+/* Id: lnx_jstk.c,v 1.1 1995/12/20 14:06:09 lepied Exp */
+/*
+ * Copyright 1995 by Frederic Lepied, France. <fred@sugix.frmug.fr.net>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Frederic Lepied not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Frederic Lepied makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * FREDERIC LEPIED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL FREDERIC LEPIED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_jstk.c,v 3.13 1998/07/25 16:56:43 dawes Exp $ */
+
+static const char rcs_id[] = "Id: lnx_jstk.c,v 1.1 1995/12/20 14:06:09 lepied Exp";
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#define inline __inline__
+#include <linux/joystick.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#ifdef XFree86LOADER
+#include "xf86.h"
+#include "xf86_ansic.h"
+#endif
+
+#if !defined(JSIOCGTIMELIMIT)
+/* make 2.1.x joystick.h backward compatable */
+#define JSIOCGTIMELIMIT JS_GET_TIMELIMIT
+#define JSIOCSTIMELIMIT JS_SET_TIMELIMIT
+#define js_status JS_DATA_TYPE
+#endif
+
+
+/***********************************************************************
+ *
+ * xf86JoystickOn --
+ *
+ * open the device and init timeout according to the device value.
+ *
+ ***********************************************************************
+ */
+
+int
+xf86JoystickOn(char *name, int *timeout, int *centerX, int *centerY)
+{
+ int fd;
+ struct js_status js;
+
+#ifdef DEBUG
+ ErrorF("xf86JoystickOn %s\n", name);
+#endif
+
+ if ((fd = open(name, O_RDWR | O_NDELAY, 0)) < 0)
+ {
+ xf86Msg(X_WARNING, "Cannot open joystick '%s' (%s)\n", name,
+ strerror(errno));
+ return -1;
+ }
+
+ if (*timeout == 0) {
+ if (ioctl (fd, JSIOCGTIMELIMIT, timeout) == -1) {
+ Error("joystick JSIOCGTIMELIMIT ioctl");
+ }
+ else {
+ xf86Msg(X_CONFIG, "Joystick: timeout value = %d\n", *timeout);
+ }
+ }
+ else {
+ if (ioctl(fd, JSIOCSTIMELIMIT, timeout) == -1) {
+ Error("joystick JSIOCSTIMELIMIT ioctl");
+ }
+ }
+
+ /* Assume the joystick is centred when this is called */
+ read(fd, &js, JS_RETURN);
+ if (*centerX < 0) {
+ *centerX = js.x;
+ xf86Msg(X_CONFIG, "Joystick: CenterX set to %d\n", *centerX);
+ }
+ if (*centerY < 0) {
+ *centerY = js.y;
+ xf86Msg(X_CONFIG, "Joystick: CenterY set to %d\n", *centerY);
+ }
+
+ return fd;
+}
+
+/***********************************************************************
+ *
+ * xf86JoystickInit --
+ *
+ * called when X device is initialized.
+ *
+ ***********************************************************************
+ */
+
+void
+xf86JoystickInit()
+{
+ return;
+}
+
+/***********************************************************************
+ *
+ * xf86JoystickOff --
+ *
+ * close the handle.
+ *
+ ***********************************************************************
+ */
+
+int
+xf86JoystickOff(int *fd, int doclose)
+{
+ int oldfd;
+
+ if (((oldfd = *fd) >= 0) && doclose) {
+ close(*fd);
+ *fd = -1;
+ }
+ return oldfd;
+}
+
+/***********************************************************************
+ *
+ * xf86JoystickGetState --
+ *
+ * return the state of buttons and the position of the joystick.
+ *
+ ***********************************************************************
+ */
+
+int
+xf86JoystickGetState(int fd, int *x, int *y, int *buttons)
+{
+ struct js_status js;
+ int status;
+
+ status = read(fd, &js, JS_RETURN);
+
+ if (status != JS_RETURN)
+ {
+ Error("Joystick read");
+ return 0;
+ }
+
+ *x = js.x;
+ *y = js.y;
+ *buttons = js.buttons;
+
+ return 1;
+}
+
+#ifdef XFree86LOADER
+/*
+ * Entry point for XFree86 Loader
+ */
+void
+linux_jstkModuleInit(pointer *data, INT32 *magic)
+{
+ *magic = MAGIC_DONE;
+ *data = NULL;
+}
+#endif
+
+/* end of lnx_jstk.c */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_mouse.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_mouse.c
new file mode 100644
index 000000000..8bc7e6331
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_mouse.c
@@ -0,0 +1,29 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_mouse.c,v 1.1 1999/05/17 13:17:18 dawes Exp $ */
+
+/*
+ * Copyright 1999 by The XFree86 Project, Inc.
+ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Xinput.h"
+#include "xf86OSmouse.h"
+
+static int
+SupportedInterfaces(void)
+{
+ return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO;
+}
+
+OSMouseInfoPtr
+xf86OSMouseInit(int flags)
+{
+ OSMouseInfoPtr p;
+
+ p = xcalloc(sizeof(OSMouseInfoRec), 1);
+ if (!p)
+ return NULL;
+ p->SupportedInterfaces = SupportedInterfaces;
+ return p;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c
new file mode 100644
index 000000000..e71607a42
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c
@@ -0,0 +1,626 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c,v 3.24 1999/04/18 04:08:52 dawes Exp $ */
+/*
+ * Copyright 1992 by Orest Zborowski <obz@Kodak.com>
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Orest Zborowski and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Orest Zborowski
+ * and David Wexelblat make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * OREST ZBOROWSKI AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: lnx_video.c /main/9 1996/10/19 18:06:34 kaleb $ */
+
+#include "X.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86OSpriv.h"
+
+#include "compiler.h"
+
+#ifdef HAS_MTRR_SUPPORT
+#include <asm/mtrr.h>
+#endif
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+static Bool ExtendedEnabled = FALSE;
+
+#ifdef __alpha__
+
+/*
+ * The Jensen lacks dense memory, thus we have to address the bus via
+ * the sparse addressing scheme.
+ *
+ * Martin Ostermann (ost@comnets.rwth-aachen.de) - Apr.-Sep. 1996
+ */
+
+#ifdef TEST_JENSEN_CODE /* define to test the Sparse addressing on a non-Jensen */
+#define SPARSE (5)
+#define isJensen (1)
+#else
+#define isJensen (!_bus_base())
+#define SPARSE (7)
+#endif
+
+#define BUS_BASE (isJensen ? _bus_base_sparse() : _bus_base())
+#define JENSEN_SHIFT(x) (isJensen ? ((long)x<<SPARSE) : (long)x)
+#else /* ! __alpha__ */
+#define BUS_BASE 0
+#define JENSEN_SHIFT(x) (x)
+#endif /* ! __alpha__ */
+
+/***************************************************************************/
+/* Video Memory Mapping section */
+/***************************************************************************/
+
+static pointer mapVidMem(int, unsigned long, unsigned long);
+static void unmapVidMem(int, pointer, unsigned long);
+#ifdef __alpha__
+static pointer mapVidMemSparse(int, unsigned long, unsigned long);
+static void unmapVidMemSparse(int, pointer, unsigned long);
+#endif
+
+#ifdef HAS_MTRR_SUPPORT
+static pointer setWC(int, unsigned long, unsigned long, Bool, MessageType);
+static void undoWC(int, pointer);
+
+/* The file desc for /proc/mtrr. Once opened, left opened, and the mtrr
+ driver will clean up when we exit. */
+#define MTRR_FD_UNOPENED (-1) /* We have yet to open /proc/mtrr */
+#define MTRR_FD_PROBLEM (-2) /* We tried to open /proc/mtrr, but had
+ a problem. */
+static int mtrr_fd = MTRR_FD_UNOPENED;
+
+/* Open /proc/mtrr. FALSE on failure. Will always fail on Linux 2.0,
+ and will fail on Linux 2.2 with MTRR support configured out,
+ so verbosity should be chosen appropriately. */
+static Bool
+mtrr_open(int verbosity)
+{
+ /* Only report absence of /proc/mtrr once. */
+ static Bool warned = FALSE;
+
+ char **fn;
+ static char *mtrr_files[] = {
+ "/dev/cpu/mtrr", /* Possible future name */
+ "/proc/mtrr", /* Current name */
+ NULL
+ };
+
+ if (mtrr_fd == MTRR_FD_UNOPENED) {
+ /* So open it. */
+ for (fn = mtrr_files; mtrr_fd < 0 && *fn; fn++)
+ mtrr_fd = open(*fn, O_WRONLY);
+
+ if (mtrr_fd < 0)
+ mtrr_fd = MTRR_FD_PROBLEM;
+ }
+
+ if (mtrr_fd == MTRR_FD_PROBLEM) {
+ /* To make sure we only ever warn once, need to check
+ verbosity outside xf86MsgVerb */
+ if (!warned && verbosity <= xf86GetVerbosity()) {
+ xf86MsgVerb(X_WARNING, verbosity,
+ "System lacks support for changing MTRRs\n");
+ warned = TRUE;
+ }
+
+ return FALSE;
+ }
+ else
+ return TRUE;
+}
+
+/*
+ * We maintain a list of WC regions for each physical mapping so they can
+ * be undone when unmapping.
+ */
+
+struct mtrr_wc_region {
+ struct mtrr_sentry sentry;
+ Bool added; /* added WC or removed it */
+ struct mtrr_wc_region * next;
+};
+
+static struct mtrr_wc_region *
+mtrr_cull_wc_region(int screenNum, unsigned long base, unsigned long size,
+ MessageType from)
+{
+ /* Some BIOS writers thought that setting wc over the mmio
+ region of a graphics devices was a good idea. Try to fix
+ it. */
+
+ struct mtrr_gentry gent;
+ char buf[20];
+ struct mtrr_wc_region *wcreturn = NULL, *wcr;
+
+ /* Linux 2.0 users should not get a warning without -verbose */
+ if (!mtrr_open(2))
+ return NULL;
+
+ for (gent.regnum = 0;
+ ioctl(mtrr_fd, MTRRIOC_GET_ENTRY, &gent) >= 0;
+ gent.regnum++) {
+ if (gent.type != MTRR_TYPE_WRCOMB
+ || gent.base + gent.size <= base
+ || base + size <= gent.base)
+ continue;
+
+ /* Found an overlapping region. Delete it. */
+
+ wcr = xalloc(sizeof(*wcr));
+ if (!wcr)
+ return NULL;
+ wcr->sentry.base = gent.base;
+ wcr->sentry.size = gent.size;
+ wcr->sentry.type = MTRR_TYPE_WRCOMB;
+ wcr->added = FALSE;
+
+ /* There is now a nicer ioctl-based way to do this,
+ but it isn't in current kernels. */
+ snprintf(buf, sizeof(buf), "disable=%u\n", gent.regnum);
+
+ if (write(mtrr_fd, buf, strlen(buf)) >= 0) {
+ xf86DrvMsg(screenNum, from,
+ "Removed MMIO write-combining range "
+ "(0x%lx,0x%lx)\n",
+ gent.base, gent.size);
+ wcr->next = wcreturn;
+ wcreturn = wcr;
+ } else {
+ xfree(wcr);
+ xf86DrvMsgVerb(screenNum, X_WARNING, 0,
+ "Failed to remove MMIO "
+ "write-combining range (0x%lx,0x%lx)\n",
+ gent.base, gent.size);
+ }
+ }
+ return wcreturn;
+}
+
+
+static struct mtrr_wc_region *
+mtrr_add_wc_region(int screenNum, unsigned long base, unsigned long size,
+ MessageType from)
+{
+ struct mtrr_wc_region *wcr;
+
+ /* Linux 2.0 should not warn, unless the user explicitly asks for
+ WC. */
+ if (!mtrr_open(from == X_CONFIG ? 0 : 2))
+ return NULL;
+
+ wcr = xalloc(sizeof(*wcr));
+ if (!wcr)
+ return NULL;
+
+ wcr->sentry.base = base;
+ wcr->sentry.size = size;
+ wcr->sentry.type = MTRR_TYPE_WRCOMB;
+ wcr->added = TRUE;
+ wcr->next = NULL;
+
+ if (ioctl(mtrr_fd, MTRRIOC_ADD_ENTRY, &wcr->sentry) >= 0) {
+ /* Avoid printing on every VT switch */
+ if (xf86ServerIsInitialising()) {
+ xf86DrvMsg(screenNum, from,
+ "Write-combining range (0x%lx,0x%lx)\n",
+ base, size);
+ }
+ return wcr;
+ }
+ else {
+ xfree(wcr);
+
+ /* Don't complain about the VGA region: MTRR fixed
+ regions aren't currently supported, but might be in
+ the future. */
+ if ((unsigned long)base >= 0x100000) {
+ xf86DrvMsgVerb(screenNum, X_WARNING, 0,
+ "Failed to set up write-combining range "
+ "(0x%lx,0x%lx)\n", base, size);
+ }
+ return NULL;
+ }
+}
+
+static void
+mtrr_undo_wc_region(int screenNum, struct mtrr_wc_region *wcr)
+{
+ struct mtrr_wc_region *p, *prev;
+
+ if (mtrr_fd > 0) {
+ p = wcr;
+ while (p) {
+ if (p->added)
+ ioctl(mtrr_fd, MTRRIOC_DEL_ENTRY, &p->sentry);
+ prev = p;
+ p = p->next;
+ xfree(prev);
+ }
+ }
+}
+
+static pointer
+setWC(int screenNum, unsigned long base, unsigned long size, Bool enable,
+ MessageType from)
+{
+ if (enable)
+ return mtrr_add_wc_region(screenNum, base, size, from);
+ else
+ return mtrr_cull_wc_region(screenNum, base, size, from);
+}
+
+static void
+undoWC(int screenNum, pointer regioninfo)
+{
+ mtrr_undo_wc_region(screenNum, regioninfo);
+}
+
+#endif /* HAS_MTRR_SUPPORT */
+
+
+void
+xf86OSInitVidMem(VidMemInfoPtr pVidMem)
+{
+ pVidMem->linearSupported = TRUE;
+ pVidMem->mapMem = mapVidMem;
+ pVidMem->unmapMem = unmapVidMem;
+#ifdef __alpha__
+ pVidMem->mapMemSparse = mapVidMemSparse;
+ pVidMem->unmapMemSparse = unmapVidMemSparse;
+#endif
+#ifdef HAS_MTRR_SUPPORT
+ pVidMem->setWC = setWC;
+ pVidMem->undoWC = undoWC;
+#endif
+ pVidMem->initialised = TRUE;
+}
+
+static pointer
+mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size)
+{
+ pointer base;
+ int fd;
+
+ if ((fd = open("/dev/mem", O_RDWR)) < 0)
+ {
+ FatalError("xf86MapVidMem: failed to open /dev/mem (%s)\n",
+ strerror(errno));
+ }
+ /* This requires linux-0.99.pl10 or above */
+ base = mmap((caddr_t)0, JENSEN_SHIFT(Size),
+ PROT_READ|PROT_WRITE,
+ MAP_SHARED, fd,
+ (off_t)(JENSEN_SHIFT((off_t)Base) + BUS_BASE));
+ close(fd);
+ if (base == MAP_FAILED)
+ {
+ FatalError("xf86MapVidMem: Could not mmap framebuffer (%s)\n",
+ strerror(errno));
+ }
+
+ return base;
+}
+
+static void
+unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+{
+ munmap((caddr_t)JENSEN_SHIFT(Base), JENSEN_SHIFT(Size));
+}
+
+/***************************************************************************/
+/* I/O Permissions section */
+/***************************************************************************/
+
+#if defined(__powerpc__)
+/* FIXME: init this... */
+volatile unsigned char *ioBase = MAP_FAILED;
+
+void
+ppc_flush_icache(char *addr)
+{
+ /* cut+paste from linux glibc */
+ __asm__ volatile (" dcbf 0,3");
+ __asm__ volatile (" icbi 0,3");
+ __asm__ volatile (" addi 3,3,32");
+ __asm__ volatile (" dcbf 0,3");
+ __asm__ volatile (" icbi 0,3");
+}
+#endif
+
+void
+xf86EnableIO(void)
+{
+ if (ExtendedEnabled)
+ return;
+
+#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__)
+ if (iopl(3))
+ FatalError("%s: Failed to set IOPL for I/O\n",
+ "xf86EnableIOPorts");
+#endif
+ ExtendedEnabled = TRUE;
+
+ return;
+}
+
+void
+xf86DisableIO(void)
+{
+ if (!ExtendedEnabled)
+ return;
+
+#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__)
+ iopl(0);
+#endif
+ ExtendedEnabled = FALSE;
+
+ return;
+}
+
+
+/***************************************************************************/
+/* Interrupt Handling section */
+/***************************************************************************/
+
+Bool
+xf86DisableInterrupts()
+{
+ if (!ExtendedEnabled)
+#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__)
+ if (iopl(3))
+ return (FALSE);
+#endif
+#if defined(__alpha__) || defined(__mc68000__) || defined(__powerpc__) || defined(__sparc__)
+#else
+#ifdef __GNUC__
+ __asm__ __volatile__("cli");
+#else
+ asm("cli");
+#endif
+#endif
+#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__)
+ if (!ExtendedEnabled)
+ iopl(0);
+#endif
+ return (TRUE);
+}
+
+void
+xf86EnableInterrupts()
+{
+ if (!ExtendedEnabled)
+#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__)
+ if (iopl(3))
+ return;
+#endif
+#if defined(__alpha__) || defined(__mc68000__) || defined(__powerpc__) || defined(__sparc__)
+#else
+#ifdef __GNUC__
+ __asm__ __volatile__("sti");
+#else
+ asm("sti");
+#endif
+#endif
+#if !defined(__mc68000__) && !defined(__powerpc__) && !defined(__sparc__)
+ if (!ExtendedEnabled)
+ iopl(0);
+#endif
+ return;
+}
+
+#if defined(__alpha__)
+
+static int xf86SparseShift = 5; /* default to all but JENSEN */
+
+static pointer
+mapVidMemSparse(int ScreenNum, unsigned long Base, unsigned long Size)
+{
+ pointer base;
+ int fd;
+
+ if (!_bus_base()) xf86SparseShift = 7; /* Uh, oh, JENSEN... */
+
+ Size <<= xf86SparseShift;
+ Base = Base << xf86SparseShift;
+
+ if ((fd = open("/dev/mem", O_RDWR)) < 0)
+ {
+ FatalError("xf86MapVidMem: failed to open /dev/mem (%s)\n",
+ strerror(errno));
+ }
+ /* This requirers linux-0.99.pl10 or above */
+ base = mmap((caddr_t)0, Size,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd,
+ (off_t)Base + _bus_base_sparse());
+ close(fd);
+ if (base == MAP_FAILED)
+ {
+ FatalError("xf86MapVidMem: Could not mmap framebuffer (%s)\n",
+ strerror(errno));
+ }
+ return base;
+}
+
+static void
+unmapVidMemSparse(int ScreenNum, pointer Base, unsigned long Size)
+{
+ Size <<= xf86SparseShift;
+
+ munmap((caddr_t)Base, Size);
+}
+
+#define vuip volatile unsigned int *
+
+extern void sethae(unsigned long hae);
+
+int
+xf86ReadSparse8(pointer Base, unsigned long Offset)
+{
+ unsigned long result, shift;
+ unsigned long msb = 0;
+
+ shift = (Offset & 0x3) * 8;
+ if (xf86SparseShift != 7) { /* if not JENSEN, we may need HAE */
+ if (Offset >= (1UL << 24)) {
+ msb = Offset & 0xf8000000UL;
+ Offset -= msb;
+ if (msb) {
+ sethae(msb);
+ }
+ }
+ }
+ result = *(vuip) ((unsigned long)Base + (Offset << xf86SparseShift));
+ if (msb)
+ sethae(0);
+ result >>= shift;
+ return 0xffUL & result;
+}
+
+int
+xf86ReadSparse16(pointer Base, unsigned long Offset)
+{
+ unsigned long result, shift;
+ unsigned long msb = 0;
+
+ shift = (Offset & 0x2) * 8;
+ if (xf86SparseShift != 7) { /* if not JENSEN, we may need HAE */
+ if (Offset >= (1UL << 24)) {
+ msb = Offset & 0xf8000000UL;
+ Offset -= msb;
+ if (msb) {
+ sethae(msb);
+ }
+ }
+ }
+ result = *(vuip)((unsigned long)Base+(Offset<<xf86SparseShift)+(1<<(xf86SparseShift-2)));
+ if (msb)
+ sethae(0);
+ result >>= shift;
+ return 0xffffUL & result;
+}
+
+int
+xf86ReadSparse32(pointer Base, unsigned long Offset)
+{
+ unsigned long result;
+ unsigned long msb = 0;
+
+ if (xf86SparseShift != 7) { /* if not JENSEN, we may need HAE */
+ if (Offset >= (1UL << 24)) {
+ msb = Offset & 0xf8000000UL;
+ Offset -= msb;
+ if (msb) {
+ sethae(msb);
+ }
+ }
+ }
+ result = *(vuip)((unsigned long)Base+(Offset<<xf86SparseShift)+(3<<(xf86SparseShift-2)));
+ if (msb)
+ sethae(0);
+ return result;
+}
+
+void
+xf86WriteSparse8(int Value, pointer Base, unsigned long Offset)
+{
+ unsigned long msb = 0;
+ unsigned int b = Value & 0xffU;
+
+ if (xf86SparseShift != 7) { /* not JENSEN */
+ if (Offset >= (1UL << 24)) {
+ msb = Offset & 0xf8000000;
+ Offset -= msb;
+ if (msb) {
+ sethae(msb);
+ }
+ }
+ }
+ *(vuip) ((unsigned long)Base + (Offset << xf86SparseShift)) = b * 0x01010101;
+ if (msb)
+ sethae(0);
+
+#if defined(__alpha__)
+ /* CAUTION: if you make changes inside this block you need to */
+ /* make them to the other two identical blocks in this file */
+ mem_barrier();
+#endif
+
+}
+
+void
+xf86WriteSparse16(int Value, pointer Base, unsigned long Offset)
+{
+ unsigned long msb = 0;
+ unsigned int w = Value & 0xffffU;
+
+ if (xf86SparseShift != 7) { /* not JENSEN */
+ if (Offset >= (1UL << 24)) {
+ msb = Offset & 0xf8000000;
+ Offset -= msb;
+ if (msb) {
+ sethae(msb);
+ }
+ }
+ }
+ *(vuip)((unsigned long)Base+(Offset<<xf86SparseShift)+(1<<(xf86SparseShift-2))) =
+ w * 0x00010001;
+ if (msb)
+ sethae(0);
+
+#if defined(__alpha__)
+ /* CAUTION: if you make changes inside this block you need to */
+ /* make them to the other two identical blocks in this file */
+ mem_barrier();
+#endif
+
+}
+
+void
+xf86WriteSparse32(int Value, pointer Base, unsigned long Offset)
+{
+ unsigned long msb = 0;
+
+ if (xf86SparseShift != 7) { /* not JENSEN */
+ if (Offset >= (1UL << 24)) {
+ msb = Offset & 0xf8000000;
+ Offset -= msb;
+ if (msb) {
+ sethae(msb);
+ }
+ }
+ }
+ *(vuip)((unsigned long)Base+(Offset<<xf86SparseShift)+(3<<(xf86SparseShift-2))) = Value;
+ if (msb)
+ sethae(0);
+
+#if defined(__alpha__)
+ /* CAUTION: if you make changes inside this block you need to */
+ /* make them to the other two identical blocks in this file */
+ mem_barrier();
+#endif
+}
+#endif /* __alpha__ */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/lynxos/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/lynxos/Imakefile
new file mode 100644
index 000000000..adaeb532a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/lynxos/Imakefile
@@ -0,0 +1,57 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/lynxos/Imakefile,v 3.12 1999/07/10 07:24:48 dawes Exp $
+#include <Server.tmpl>
+
+#if !defined(PpcArchitecture)
+IOPERM_SRCS=ioperm_noop.c
+IOPERM_OBJS=ioperm_noop.o
+#endif
+
+#if defined(PpcArchitecture)
+PPC_SRCS=lynx_noinline.c lynx_ppc.S
+PPC_OBJS=lynx_noinline.o lynx_ppc.o
+#endif
+
+#if NewInput
+MOUSESRC = lynx_mouse.c
+MOUSEOBJ = lynx_mouse.o
+#else
+MOUSESRC = std_mouse.c std_mseEv.c
+MOUSEOBJ = std_mouse.o std_mseEv.o
+#endif
+
+SRCS = lynx_init.c lynx_video.c lynx_io.c lynx_mmap.c mapVT_noop.c \
+ VTsw_usl.c std_kbdEv.c posix_tty.c $(MOUSESRC) \
+ $(IOPERM_SRCS) $(PPC_SRCS) libc_wrapper.c stdResource.c \
+ vidmem.c
+
+OBJS = lynx_init.o lynx_video.o lynx_io.o lynx_mmap.o mapVT_noop.o \
+ VTsw_usl.o std_kbdEv.o posix_tty.o $(MOUSEOBJ) \
+ $(IOPERM_OBJS) $(PPC_OBJS) libc_wrapper.o stdResource.o \
+ vidmem.o
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+RESDEFINES = -DUSESTDRES
+
+DEFINES = $(RESDEFINES)
+
+SubdirLibraryRule($(OBJS))
+NormalLibraryObjectRule()
+
+#if !defined(PpcArchitecture)
+LinkSourceFile(ioperm_noop.c,../shared)
+#endif
+LinkSourceFile(mapVT_noop.c,../shared)
+LinkSourceFile(VTsw_usl.c,../shared)
+LinkSourceFile(std_kbdEv.c,../shared)
+LinkSourceFile(posix_tty.c,../shared)
+#if !NewInput
+LinkSourceFile(std_mouse.c,../shared)
+LinkSourceFile(std_mseEv.c,../shared)
+#endif
+LinkSourceFile(libc_wrapper.c,../shared)
+LinkSourceFile(stdResource.c,../shared)
+LinkSourceFile(vidmem.c,../shared)
+
+DependTarget()
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_init.c b/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_init.c
new file mode 100644
index 000000000..8565dcc5c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_init.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright 1993 by Thomas Mueller
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Mueller not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Mueller makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS MUELLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS MUELLER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_init.c,v 3.3 1998/08/29 05:43:58 dawes Exp $ */
+
+#include "X.h"
+#include "Xmd.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+static int VTnum = -1;
+
+void
+xf86OpenConsole()
+{
+ struct vt_mode VT;
+ char vtname1[11];
+ int fd, pgrp;
+ MessageType from = X_PROBED;
+
+ if (serverGeneration == 1)
+ {
+ /* check if we're run with euid==0 */
+ if (geteuid() != 0)
+ {
+ FatalError("xf86OpenConsole: Server must be suid root\n");
+ }
+
+ /*
+ * setup the virtual terminal manager
+ * NOTE:
+ * We use the out-of-the-box atc terminal driver,
+ * not the GE contributed vdt driver.
+ * Also, we do setup signals for VT switching which
+ * is not really necessary because we don't feed the
+ * VT switch keystrokes to the kernel in xf86Events.c
+ * (it bombs occasionally...)
+ */
+ if (VTnum != -1)
+ {
+ xf86Info.vtno = VTnum;
+ from = X_CMDLINE;
+ }
+ else
+ {
+ /* We could use /dev/con which is usually a symlink
+ * to /dev/atc0 but one could configure the system
+ * to use a serial line as console device, so to
+ * be sure we take /dev/atc0.
+ */
+ if ((fd = open("/dev/atc0",O_WRONLY,0)) < 0)
+ {
+ FatalError(
+ "xf86OpenConsole: Cannot open /dev/atc0 (%s)\n",
+ strerror(errno));
+ }
+ if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
+ (xf86Info.vtno == -1))
+ {
+ FatalError("xf86OpenConsole: Cannot find a free VT\n");
+ }
+ close(fd);
+ }
+ xf86Msg(from, "using VT number %d\n", xf86Info.vtno);
+
+ sprintf(vtname1,"/dev/atc%d",xf86Info.vtno);
+
+ pgrp = getpgrp(); /* POSIX version ! */
+ ioctl(xf86Info.consoleFd, TIOCSPGRP, &pgrp);
+
+ if ((xf86Info.consoleFd = open(vtname1,O_RDWR|O_NDELAY,0)) < 0)
+ {
+ FatalError(
+ "xf86OpenConsole: Cannot open %s (%s)\n",
+ vtname1, strerror(errno));
+ }
+ /* change ownership of the vt */
+ chown(vtname1, getuid(), getgid());
+
+ /*
+ * now get the VT
+ */
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
+ {
+ FatalError("xf86OpenConsole: VT_GETMODE failed\n");
+ }
+
+ /* for future use... */
+ signal(SIGUSR1, xf86VTRequest);
+
+ VT.mode = VT_PROCESS;
+ VT.relsig = SIGUSR1;
+ VT.acqsig = SIGUSR1;
+ if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
+ {
+ FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n");
+ }
+ }
+ else
+ {
+ /* serverGeneration != 1 */
+ /*
+ * now get the VT
+ */
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+ /*
+ * If the server doesn't have the VT when the reset occurs,
+ * this is to make sure we don't continue until the activate
+ * signal is received.
+ */
+ if (!xf86Screens[0]->vtSema)
+ sleep(5);
+ }
+ return;
+}
+
+void
+xf86CloseConsole()
+{
+ struct vt_mode VT;
+
+#if 0
+ ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno);
+ ioctl(xf86Info.consoleFd, VT_WAITACTIVE, 0);
+#endif
+ if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1)
+ {
+ VT.mode = VT_AUTO;
+ ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* set dflt vt handling */
+ }
+ close(xf86Info.consoleFd); /* make the vt-manager happy */
+ return;
+}
+
+int
+xf86ProcessArgument(int argc, char *argv[], int i)
+{
+ if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
+ {
+ if (sscanf(argv[i], "vt%2d", &VTnum) == 0)
+ {
+ UseMsg();
+ VTnum = -1;
+ return(0);
+ }
+ return(1);
+ }
+ return(0);
+}
+
+void
+xf86UseMsg()
+{
+ ErrorF("vtXX use the specified VT number\n");
+ return;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_io.c b/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_io.c
new file mode 100644
index 000000000..32f250ff9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_io.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright 1993 by Thomas Mueller
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Mueller not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Mueller makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS MUELLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS MUELLER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_io.c,v 3.7 1999/05/22 08:40:14 dawes Exp $ */
+
+#include "X.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#if defined(KDMKTONE) || defined(KIOCSOUND)
+/* Lynx 2.2.1 has sophisticated atc stuff.... */
+void
+xf86SoundKbdBell(int loudness, int pitch, int duration)
+{
+ if (loudness && pitch)
+ {
+#ifdef KDMKTONE
+ /*
+ * If we have KDMKTONE use it to avoid putting the server
+ * to sleep
+ */
+ ioctl(xf86Info.consoleFd, KDMKTONE,
+ (pitch & 0xffff) |
+ (((unsigned long)duration *
+ loudness / 50) << 16));
+#else
+ ioctl(xf86Info.consoleFd, KIOCSOUND, pitch);
+ usleep(xf86Info.bell_duration * loudness * 20);
+ ioctl(xf86Info.consoleFd, KIOCSOUND, 0);
+#endif
+ }
+}
+
+#else
+
+/* this is pulled from /sys/drivers/vt100/atbeep.c */
+
+#define SPEAKER_CONTROL 0x61
+#define TIMER_CONTROL 0x43
+#define TIMER_DATA 0x42
+#define TIMER_LOAD_CMD 0xb6
+
+#define TIMER_CONSTANT 1193280
+#define FREQ_LO(f) ((TIMER_CONSTANT / (f)) % 256)
+#define FREQ_HI(f) ((TIMER_CONSTANT / (f)) / 256)
+
+void
+xf86SoundKbdBell(int loudness, int pitch, int duration)
+{
+ int flo = FREQ_LO(pitch);
+ int fhi = FREQ_HI(pitch);
+
+ outb(TIMER_CONTROL, TIMER_LOAD_CMD);
+ outb(TIMER_DATA, flo);
+ outb(TIMER_DATA, fhi);
+
+ /* speaker on */
+ outb(SPEAKER_CONTROL, inb(SPEAKER_CONTROL) | 3);
+ usleep(xf86Info.bell_duration * loudness * 20);
+ /* speaker off */
+ outb(SPEAKER_CONTROL, inb(SPEAKER_CONTROL) & ~3);
+}
+#endif
+
+void
+xf86SetKbdLeds(int leds)
+{
+#ifdef KBD_SET_LEDS
+ ioctl(xf86Info.consoleFd, KBD_SET_LEDS, &leds);
+#endif
+}
+
+int
+xf86GetKbdLeds()
+{
+#ifdef KBD_SET_LEDS
+ int leds;
+
+ if (ioctl(xf86Info.consoleFd, KBD_SET_LEDS, &leds) < 0)
+ return 0;
+
+ return leds;
+#endif
+ return 0;
+}
+
+void
+xf86SetKbdRepeat(char rad)
+{
+}
+
+static struct termio kbdtty;
+
+void
+xf86KbdInit()
+{
+ ioctl(xf86Info.consoleFd, TCGETA, &kbdtty);
+}
+
+int
+xf86KbdOn()
+{
+ struct termio nTty;
+
+ /* set CAPS_LOCK to behave as CAPS_LOCK not as CTRL */
+ write(xf86Info.consoleFd, "\033<", 2);
+
+ /* enable scan mode */
+ ioctl(xf86Info.consoleFd, TIO_ENSCANMODE, NULL);
+
+ nTty = kbdtty;
+ nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
+ nTty.c_oflag = 0;
+ nTty.c_cflag = CREAD | CS8;
+ nTty.c_lflag = 0;
+ nTty.c_cc[VTIME]=0;
+ nTty.c_cc[VMIN]=1;
+ ioctl(xf86Info.consoleFd, TCSETA, &nTty);
+
+ return(xf86Info.consoleFd);
+}
+
+int
+xf86KbdOff()
+{
+ /* disable scan mode */
+ ioctl(xf86Info.consoleFd, TIO_DISSCANMODE, NULL);
+ ioctl(xf86Info.consoleFd, TCSETA, &kbdtty);
+ return(xf86Info.consoleFd);
+}
+
+#ifndef NEW_INPUT
+void
+xf86MouseInit(MouseDevPtr mouse)
+{
+ return;
+}
+
+int
+xf86MouseOn(MouseDevPtr mouse)
+{
+ if ((mouse->mseFd = open(mouse->mseDevice, O_RDWR | O_NDELAY)) < 0)
+ {
+ if (xf86Info.allowMouseOpenFail) {
+ xf86Msg(X_WARNING,
+ "Cannot open mouse (%s) - Continuing...\n",
+ strerror(errno));
+ return(-2);
+ }
+ FatalError("Cannot open mouse (%s)\n", strerror(errno));
+ }
+
+ /* assert DTR */
+ ioctl(mouse->mseFd, TIOCSDTR, NULL);
+
+ xf86SetupMouse(mouse);
+
+ return(mouse->mseFd);
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_mmap.c b/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_mmap.c
new file mode 100644
index 000000000..187e7adc0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_mmap.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright 1993 by Thomas Mueller
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Mueller not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Mueller makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS MUELLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS MUELLER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_mmap.c,v 3.5 1998/08/29 05:43:58 dawes Exp $ */
+
+#include "X.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+/*
+ * Read BIOS using smem_create facility
+ */
+
+int
+xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf,
+ int Len)
+{
+#if defined(__powerpc__)
+ xf86Msg(X_WARNING, "xf86ReadBios: no BIOS-probe on PowerPC\n");
+ return(-1);
+#else
+ char *p;
+ int mlen;
+
+ mlen = (Offset + Len + 4095) & ~4096;
+ p = smem_create("BIOS-probe", (char *)Base, mlen, SM_READ);
+ if (p == NULL)
+ {
+ /* check if there is a stale segment around */
+ if (smem_remove("BIOS-probe") == 0) {
+ xf86Msg(X_INFO,
+ "xf86ReadBios: removed stale smem_ segment\n");
+ p = smem_create("BIOS-probe", (char *)Base, mlen, SM_READ);
+ }
+ if (p == NULL) {
+ xf86Msg(X_WARNING, "xf86ReadBios: Failed to smem_create "
+ "Base %x len %x %s \n",
+ Base, mlen, strerror(errno));
+ return(-1);
+ }
+ }
+ memcpy(Buf, p + Offset, Len);
+ smem_create(NULL, p, 0, SM_DETACH);
+ smem_remove("BIOS-probe");
+ return(Len);
+#endif
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_mouse.c b/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_mouse.c
new file mode 100644
index 000000000..1dc5ff8af
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_mouse.c
@@ -0,0 +1,30 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_mouse.c,v 1.1 1999/05/22 08:40:14 dawes Exp $ */
+
+/*
+ * Copyright 1999 by The XFree86 Project, Inc.
+ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Xinput.h"
+#include "xf86OSmouse.h"
+
+static int
+SupportedInterfaces(void)
+{
+ /* XXX Need to check this. */
+ return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO;
+}
+
+OSMouseInfoPtr
+xf86OSMouseInit(int flags)
+{
+ OSMouseInfoPtr p;
+
+ p = xcalloc(sizeof(OSMouseInfoRec), 1);
+ if (!p)
+ return NULL;
+ p->SupportedInterfaces = SupportedInterfaces;
+ return p;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_noinline.c b/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_noinline.c
new file mode 100644
index 000000000..17d215ad0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_noinline.c
@@ -0,0 +1,255 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_noinline.c,v 3.4 1998/08/29 05:43:58 dawes Exp $ */
+/*
+ * Copyright 1998 by Metro Link Incorporated
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Metro Link
+ * Incorporated not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Metro Link Incorporated makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED 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.
+ */
+
+#if /* NO_INLINE && */ defined(__powerpc__)
+
+extern volatile unsigned char *ioBase;
+
+void
+eieio()
+{
+ __asm__ __volatile__ ("eieio");
+}
+
+unsigned long
+ldl_brx(volatile unsigned char *base, int ndx)
+{
+ register unsigned long tmp = *(volatile unsigned long *)(base+ndx);
+ return( ((tmp & 0x000000ff) << 24) |
+ ((tmp & 0x0000ff00) << 8) |
+ ((tmp & 0x00ff0000) >> 8) |
+ ((tmp & 0xff000000) >> 24) );
+}
+
+unsigned short
+ldw_brx(volatile unsigned char *base, int ndx)
+{
+ register unsigned short tmp = *(volatile unsigned short *)(base+ndx);
+ return((tmp << 8) | (tmp >> 8));
+}
+
+void
+stl_brx(unsigned long val, volatile unsigned char *base, int ndx)
+{
+ unsigned char *p = (unsigned char *)&val;
+ unsigned long tmp = (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | (p[0] << 0);
+ *(volatile unsigned long *)(base+ndx) = tmp;
+}
+
+void
+stw_brx(unsigned short val, volatile unsigned char *base, int ndx)
+{
+ unsigned char *p = (unsigned char *)&val;
+ unsigned short tmp = (p[1] << 8) | p[0];
+ *(volatile unsigned short *)(base+ndx) = tmp;
+}
+
+void
+outb(unsigned short port, unsigned char value)
+{
+ *((volatile unsigned char *)(ioBase + port)) = value; eieio();
+}
+
+void
+outw(unsigned short port, unsigned short value)
+{
+ stw_brx(value, ioBase, port); eieio();
+}
+
+void
+outl(unsigned short port, unsigned long value)
+{
+ stl_brx(value, ioBase, port); eieio();
+}
+
+unsigned char
+inb(unsigned short port)
+{
+ unsigned char val;
+
+ val = *((volatile unsigned char *)(ioBase + port)); eieio();
+ return(val);
+}
+
+unsigned short
+inw(unsigned short port)
+{
+ unsigned short val;
+
+ val = ldw_brx(ioBase, port); eieio();
+ return(val);
+}
+
+unsigned long
+inl(unsigned short port)
+{
+ unsigned long val;
+
+ val = ldl_brx(ioBase, port); eieio();
+ return(val);
+}
+
+unsigned long
+ldl_u(void *p)
+{
+ return (((*(unsigned char *)(p)) |
+ (*((unsigned char *)(p)+1)<<8) |
+ (*((unsigned char *)(p)+2)<<16) |
+ (*((unsigned char *)(p)+3)<<24)));
+}
+
+unsigned long
+ldq_u(void *p)
+{
+ return ldl_u(p);
+}
+
+unsigned short
+ldw_u(void *p)
+{
+ return(((*(unsigned char *)(p)) |
+ (*((unsigned char *)(p)+1)<<8)));
+}
+
+void
+stl_u(unsigned long v, void *p)
+{
+
+ (*(unsigned char *)(p)) = (v);
+ (*((unsigned char *)(p)+1)) = ((v) >> 8);
+ (*((unsigned char *)(p)+2)) = ((v) >> 16);
+ (*((unsigned char *)(p)+3)) = ((v) >> 24);
+}
+
+void
+stq_u(unsigned long v, void *p)
+{
+ stl_u(v,p);
+}
+
+void
+stw_u(unsigned short v, void *p)
+{
+ (*(unsigned char *)(p)) = (v);
+ (*((unsigned char *)(p)+1)) = ((v) >> 8);
+}
+
+
+void
+mem_barrier(void)
+{
+ __asm__ __volatile__("eieio");
+}
+
+void
+write_mem_barrier(void)
+{
+ __asm__ __volatile__("eieio");
+}
+
+
+/*
+ * rdinx - read the indexed byte port 'port', index 'ind', and return its value
+ */
+unsigned char
+rdinx(unsigned short int port, unsigned char ind)
+{
+ if (port == 0x3C0) /* reset attribute flip-flop */
+ (void) inb(0x3DA);
+ outb(port, ind);
+ return(inb(port+1));
+}
+
+/*
+ * wrinx - write 'val' to port 'port', index 'ind'
+ */
+void
+wrinx(unsigned short int port, unsigned char ind, unsigned char val)
+{
+ outb(port, ind);
+ outb(port+1, val);
+}
+
+/*
+ * modinx - in register 'port', index 'ind', set the bits in 'mask' as in 'new';
+ * the other bits are unchanged.
+ */
+void
+modinx(unsigned short int port, unsigned char ind,
+ unsigned char mask, unsigned char new)
+{
+ unsigned char tmp;
+
+ tmp = (rdinx(port, ind) & ~mask) | (new & mask);
+ wrinx(port, ind, tmp);
+}
+
+/*
+ * tstrg - returns true iff the bits in 'mask' of register 'port' are
+ * readable & writable.
+ */
+int
+testrg(unsigned short int port, unsigned char mask)
+{
+ unsigned char old, new1, new2;
+
+ old = inb(port);
+ outb(port, old & ~mask);
+ new1 = inb(port) & mask;
+ outb(port, old | mask);
+ new2 = inb(port) & mask;
+ outb(port, old);
+ return((new1 == 0) && (new2 == mask));
+}
+
+/*
+ * testinx2 - returns true iff the bits in 'mask' of register 'port', index
+ * 'ind' are readable & writable.
+ */
+int
+testinx2(unsigned short int port, unsigned char ind, unsigned char mask)
+{
+ unsigned char old, new1, new2;
+
+ old = rdinx(port, ind);
+ wrinx(port, ind, old & ~mask);
+ new1 = rdinx(port, ind) & mask;
+ wrinx(port, ind, old | mask);
+ new2 = rdinx(port, ind) & mask;
+ wrinx(port, ind, old);
+ return((new1 == 0) && (new2 == mask));
+}
+
+/*
+ * testinx - returns true iff all bits of register 'port', index 'ind' are
+ * readable & writable.
+ */
+int
+testinx(unsigned short int port, unsigned char ind)
+{
+ return(testinx2(port, ind, 0xFF));
+}
+
+#endif /* NO_INLINE && __powerpc__ */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_ppc.S b/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_ppc.S
new file mode 100644
index 000000000..3865850d1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_ppc.S
@@ -0,0 +1,70 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_ppc.S,v 1.1 1999/07/10 07:24:49 dawes Exp $ */
+/*
+ * Copyright 1998 by Metro Link Incorporated
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Metro Link
+ * Incorporated not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Metro Link Incorporated makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED 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.
+ */
+
+ .file "ppc.s"
+.toc
+ .csect .text[PR]
+ .balign 4
+ .globl ppc_flush_icache
+ .globl .ppc_flush_icache
+.csect ppc_flush_icache[DS]
+ppc_flush_icache:
+ .long .ppc_flush_icache, TOC[tc0], 0
+.csect .text[PR]
+.ppc_flush_icache:
+ mflr 0
+ stw 31,-4(1)
+ stw 0,8(1)
+ stwu 1,-64(1)
+ mr 31,1
+ stw 3,88(31)
+ li 6, 0 /* __inst_dcbf (addr, 0); */
+ dcbf 3, 6
+ li 5, 32 /* __inst_dcbf (addr, LINESIZE); */
+ dcbf 3, 5
+ sync /* __inst_sync (); */
+ li 4,0 /* __inst_icbi (addr, 0); */
+ icbi 3,4
+ li 7,32 /* __inst_icbi (addr, LINESIZE); */
+ icbi 3,7
+ sync /* __inst_sync (); */
+ isync /* __inst_isync (); */
+L..1:
+ lwz 1,0(1)
+ lwz 0,8(1)
+ mtlr 0
+ lwz 31,-4(1)
+ blr
+LT..ppc_flush_icache:
+ .long 0
+ .byte 0,0,32,97,128,1,1,1
+ .long 0
+ .long LT..ppc_flush_icache-.ppc_flush_icache
+ .short 16
+ .byte "ppc_flush_icache"
+ .byte 31
+_section_.text:
+ .csect .data[RW]
+ .long _section_.text
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_video.c b/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_video.c
new file mode 100644
index 000000000..d2a5d3d11
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_video.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright 1993 by Thomas Mueller
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Mueller not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Mueller makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS MUELLER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS MUELLER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_video.c,v 3.13 1999/05/03 12:16:07 dawes Exp $ */
+
+#include "X.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86OSpriv.h"
+
+#if defined(__powerpc__)
+#include <machine/absolute.h>
+#endif
+
+/***************************************************************************/
+/* Video Memory Mapping section */
+/***************************************************************************/
+
+typedef struct
+{
+ char name[16];
+ unsigned long Base;
+ unsigned long Size;
+ char *ptr;
+ int RefCnt;
+}
+_SMEMS;
+
+#define MAX_SMEMS 16
+
+static _SMEMS smems[MAX_SMEMS];
+
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+static void
+smemCleanup()
+{
+ int i;
+
+ for (i = 0; i < MAX_SMEMS; i++) {
+ if (*smems[i].name && smems[i].ptr) {
+ (void)smem_create(NULL, smems[i].ptr, 0, SM_DETACH);
+ (void)smem_remove(smems[i].name);
+ *smems[i].name = '\0';
+ smems[i].ptr = NULL;
+ smems[i].Base = 0;
+ smems[i].Size = 0;
+ smems[i].RefCnt = 0;
+ }
+ }
+}
+
+static pointer
+MapVidMem(int ScreenNum, unsigned long Base, unsigned long Size)
+{
+ static int once;
+ int free_slot = -1;
+ int i;
+
+ if (!once)
+ {
+ atexit(smemCleanup);
+ once = 1;
+ }
+ for (i = 0; i < MAX_SMEMS; i++)
+ {
+ if (!*smems[i].name && free_slot == -1)
+ free_slot = i;
+ if (smems[i].Base == Base && smems[i].Size == Size
+ && *smems[i].name) {
+ smems[i].RefCnt++;
+ return smems[i].ptr;
+ }
+ }
+ if (i == MAX_SMEMS && free_slot == -1)
+ {
+ FatalError("MapVidMem: failed to smem_create Base %x Size %x (out of SMEMS entries)\n",
+ Base, Size);
+ }
+
+ i = free_slot;
+ sprintf(smems[i].name, "Video-%d", i);
+ smems[i].Base = Base;
+ smems[i].Size = Size;
+
+ xf86MsgVerb(X_INFO, 3, "MapVidMem: Base=0x%x Size=0x%x\n",
+ Base, Size);
+
+#if defined(__powerpc__)
+ if (((unsigned long)Base & PHYS_IO_MEM_START) != PHYS_IO_MEM_START) {
+ Base = Base | PHYS_IO_MEM_START;
+ }
+#endif
+
+ smems[i].ptr = smem_create(smems[i].name, (char *)Base, Size, SM_READ|SM_WRITE);
+ smems[i].RefCnt = 1;
+ if (smems[i].ptr == NULL)
+ {
+ /* check if there is a stale segment around */
+ if (smem_remove(smems[i].name) == 0) {
+ xf86Msg(X_INFO,
+ "MapVidMem: removed stale smem_ segment %s\n",
+ smems[i].name);
+ smems[i].ptr = smem_create(smems[i].name,
+ (char *)Base, Size, SM_READ|SM_WRITE);
+ }
+ if (smems[i].ptr == NULL) {
+ *smems[i].name = '\0';
+ FatalError("MapVidMem: failed to smem_create Base %x Size %x (%s)\n",
+ Base, Size, strerror(errno));
+ }
+ }
+ xf86MsgVerb(X_INFO, 3, "MapVidMem: Base=0x%x Size=0x%x Ptr=0x%x\n",
+ Base, Size, smems[i].ptr);
+ return smems[i].ptr;
+}
+
+static void
+UnMapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+{
+ int i;
+
+ xf86MsgVerb(X_INFO, 3, "UnMapVidMem: Base/Ptr=0x%x Size=0x%x\n",
+ Base, Size);
+ for (i = 0; i < MAX_SMEMS; i++)
+ {
+ if (*smems[i].name && smems[i].ptr == Base
+ && smems[i].Size == Size)
+ {
+ if (--smems[i].RefCnt > 0)
+ return;
+
+ (void)smem_create(NULL, smems[i].ptr, 0, SM_DETACH);
+ xf86MsgVerb(X_INFO, 3,
+ "UnMapVidMem: smem_create(%s, 0x%08x, ... "
+ "SM_DETACH)\n", smems[i].name, smems[i].ptr);
+ (void)smem_remove(smems[i].name);
+ *smems[i].name = '\0';
+ smems[i].RefCnt = 0;
+ return;
+ }
+ }
+ xf86MsgVerb(X_WARNING, 2,
+ "UnMapVidMem: no SMEM found for Base = %lx Size = %lx\n",
+ Base, Size);
+}
+
+
+void
+xf86OSInitVidMem(VidMemInfoPtr pVidMem)
+{
+ pVidMem->linearSupported = TRUE;
+ pVidMem->mapMem = MapVidMem;
+ pVidMem->unmapMem = UnMapVidMem;
+ pVidMem->mapMemSparse = 0;
+ pVidMem->unmapMemSparse = 0;
+ pVidMem->setWC = 0;
+ pVidMem->undoWC = 0;
+ pVidMem->initialised = TRUE;
+}
+
+
+/***************************************************************************/
+/* Interrupt Handling section */
+/***************************************************************************/
+
+Bool
+xf86DisableInterrupts()
+{
+ return(TRUE);
+}
+
+void
+xf86EnableInterrupts()
+{
+ return;
+}
+
+/***************************************************************************/
+/* I/O Permissions section for PowerPC */
+/***************************************************************************/
+
+#if defined(__powerpc__)
+
+volatile unsigned char *ioBase = MAP_FAILED;
+static int IOEnabled;
+
+static void
+removeIOSmem()
+{
+ smem_create(NULL, (char *) ioBase, 0, SM_DETACH);
+ smem_remove("IOBASE");
+ ioBase = MAP_FAILED;
+}
+
+void
+xf86EnableIO()
+{
+ if (IOEnabled++ == 0) {
+ ioBase = (unsigned char *) smem_create("IOBASE",
+ (char *)0x80000000, 64*1024, SM_READ|SM_WRITE);
+ if (ioBase == MAP_FAILED) {
+ --IOEnabled;
+ FatalError("xf86EnableIO: Failed to map I/O\n");
+ } else
+ atexit(removeIOSmem);
+ }
+ return;
+}
+
+void
+xf86DisableIO()
+{
+ if (!IOEnabled)
+ return;
+
+ if (--IOEnabled == 0) {
+ removeIOSmem();
+ }
+ return;
+}
+
+void
+xf86DisableIOPrivs()
+{
+ return;
+}
+
+void *
+ppcPciIoMap(int bus)
+{
+ xf86EnableIO();
+}
+
+#endif
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/mach/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/mach/Imakefile
new file mode 100644
index 000000000..01f2843fc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/mach/Imakefile
@@ -0,0 +1,35 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/mach/Imakefile,v 3.1 1996/12/23 06:50:09 dawes Exp $
+
+
+
+
+XCOMM $XConsortium: Imakefile /main/4 1996/09/28 17:23:58 rws $
+
+#include <Server.tmpl>
+
+#if defined(OsfArchitecture)
+BIOS_MOD = bios_devmem
+#else
+BIOS_MOD = bios_mmap
+#endif
+
+SRCS = mach_init.c mach_video.c mach_io.c $(BIOS_MOD).c mapVT_noop.c \
+ VTsw_noop.c
+
+OBJS = mach_init.o mach_video.o mach_io.o $(BIOS_MOD).o mapVT_noop.o \
+ VTsw_noop.o
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC)
+
+SubdirLibraryRule($(OBJS))
+NormalLibraryObjectRule()
+
+#if defined(OsfArchitecture)
+ObjectFromSpecialSource(bios_devmem,../shared/bios_devmem,/**/)
+#endif
+ObjectFromSpecialSource(mapVT_noop,../shared/mapVT_noop,/**/)
+ObjectFromSpecialSource(VTsw_noop,../shared/VTsw_noop,/**/)
+
+DependTarget()
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/mach/bios_mmap.c b/xc/programs/Xserver/hw/xfree86/os-support/mach/bios_mmap.c
new file mode 100644
index 000000000..bc062f3e4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/mach/bios_mmap.c
@@ -0,0 +1,76 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/mach/bios_mmap.c,v 3.4 1996/12/23 06:50:10 dawes Exp $ */
+/*
+ * Copyright 1992 by Robert Baron <Robert.Baron@ernst.mach.cs.cmu.edu>
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Robert Baron and David Wexelblat not
+ * be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. Robert Baron and
+ * David Wexelblat make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * ROBERT BARON AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL ROBERT BARON OR DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: bios_mmap.c /main/4 1996/02/21 17:51:47 kaleb $ */
+
+#include "X.h"
+#include "misc.h"
+
+#define DevicePtr int
+#include "xf86_OSlib.h"
+
+#define BIOS_SIZE 0x20000
+#define KERN_SUCCESS 0
+
+int xf86ReadBIOS(Base, Offset, Buf, Len)
+unsigned long Base;
+unsigned long Offset;
+unsigned char *Buf;
+int Len;
+{
+ int fd;
+ int screen_addr;
+ int ret;
+
+ if ((fd = open("/dev/iopl", O_RDWR, 0)) < 0)
+ {
+ ErrorF("xf86ReadBIOS: Failed to open /dev/iopl\n");
+ return(-1);
+ }
+ if (KERN_SUCCESS != vm_allocate(task_self(), &screen_addr,
+ BIOS_SIZE, TRUE))
+ {
+ ErrorF("xf86ReadBIOS: Failed vmallocate %x\n", BIOS_SIZE);
+ close(fd);
+ return(-1);
+ }
+ if (mmap(screen_addr, BIOS_SIZE, 3, 1, fd, Base) < 0)
+ {
+ ErrorF("xf86ReadBIOS: Failed to mmap %x at %x\n",
+ BIOS_SIZE, Base);
+ vm_deallocate(task_self(), screen_addr, BIOS_SIZE);
+ close(fd);
+ return(-1);
+ }
+ memcpy(Buf, (unsigned char *)(screen_addr + Offset), Len);
+ if (KERN_SUCCESS != vm_deallocate(task_self(), screen_addr, BIOS_SIZE))
+ {
+ ErrorF("xf86ReadBIOS: Failed vmdeallocate %x\n", BIOS_SIZE);
+ close(fd);
+ return(-1);
+ }
+ close(fd);
+ return(Len);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/mach/mach_init.c b/xc/programs/Xserver/hw/xfree86/os-support/mach/mach_init.c
new file mode 100644
index 000000000..1615f7ec8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/mach/mach_init.c
@@ -0,0 +1,70 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/mach/mach_init.c,v 3.5 1998/07/25 16:56:46 dawes Exp $ */
+/*
+ * Copyright 1992 by Robert Baron <Robert.Baron@ernst.mach.cs.cmu.edu>
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Robert Baron and David Wexelblat not
+ * be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. Robert Baron and
+ * David Wexelblat make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * ROBERT BARON AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL ROBERT BARON OR DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: mach_init.c /main/4 1996/02/21 17:51:50 kaleb $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+void xf86OpenConsole()
+{
+ if (serverGeneration == 1)
+ {
+ if ((xf86Info.consoleFd = open("/dev/console",O_RDWR,0)) < 0)
+ {
+ FatalError("xf86OpenConsole: Can't open /dev/console (%s)\n",
+ strerror(errno));
+ }
+ return;
+ }
+}
+
+void xf86CloseConsole()
+{
+ close(xf86Info.consoleFd);
+ return;
+}
+
+/* ARGSUSED */
+int xf86ProcessArgument (argc, argv, i)
+int argc;
+char *argv[];
+int i;
+{
+ return(0);
+}
+
+void xf86UseMsg()
+{
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/mach/mach_io.c b/xc/programs/Xserver/hw/xfree86/os-support/mach/mach_io.c
new file mode 100644
index 000000000..264f6b446
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/mach/mach_io.c
@@ -0,0 +1,289 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/mach/mach_io.c,v 3.7 1999/05/07 02:56:21 dawes Exp $ */
+/*
+ * Copyright 1992 by Robert Baron <Robert.Baron@ernst.mach.cs.cmu.edu>
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Robert Baron and David Dawes not
+ * be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. Robert Baron and
+ * David Dawes make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * ROBERT BARON AND DAVID DAWES DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL ROBERT BARON OR DAVID DAWES 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.
+ *
+ */
+/* $XConsortium: mach_io.c /main/8 1996/10/19 18:06:45 kaleb $ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+Bool xf86SupportedMouseTypes[] =
+{
+ TRUE, /* Microsoft */
+ FALSE, /* MouseSystems */
+ FALSE, /* MMSeries */
+ TRUE, /* Logitech */
+ FALSE, /* BusMouse */
+ FALSE, /* MouseMan */
+ TRUE, /* PS/2 */
+ FALSE, /* Hitachi Tablet */
+};
+
+int xf86NumMouseTypes = sizeof(xf86SupportedMouseTypes) /
+ sizeof(xf86SupportedMouseTypes[0]);
+
+unsigned short xf86MouseCflags[] =
+{
+ /*
+ * MicroSoft mouse needs 7bit characters.
+ * See special seven_bit_hack code in com.c:comparam()
+ * in the kernel code. Basically we use the
+ * special code RAW | PASS8 to mean the mythical
+ * "PASS7".
+ */
+ -1, /* MicroSoft */
+ RAW, /* MouseSystems */
+ RAW, /* MMSeries */
+ RAW | EVENP | ODDP, /* Logitech */
+ 0, /* BusMouse */
+ -1, /* ??? MouseMan [CHRIS-211092] */
+ 0, /* PS/2 */
+ RAW, /* Hitachi Tablet */
+};
+
+void xf86SoundKbdBell(loudness, pitch, duration)
+int loudness;
+int pitch;
+int duration;
+{
+ if (loudness)
+ {
+#ifdef __OSF__
+ ioctl(xf86Info.consoleFd, KIOCSOUND, 1);
+ usleep(duration * loudness * 20);
+ ioctl(xf86Info.consoleFd, KIOCSOUND, 0);
+#else
+ int i = KD_BELLON;
+ ioctl(xf86Info.consoleFd, KDSETBELL, &i);
+ usleep(duration * loudness * 20);
+ i = KD_BELLOFF;
+ ioctl(xf86Info.consoleFd, KDSETBELL, &i);
+#endif
+ }
+}
+
+void xf86SetKbdLeds(leds)
+int leds;
+{
+#ifdef __OSF__
+ ioctl(xf86Info.kbdFd, KDSETLED, &leds);
+#endif
+}
+
+int xf86GetKbdLeds()
+{
+#ifdef __OSF__
+ int leds;
+
+ ioctl(xf86Info.kbdFd, KDGETLED, &leds);
+ return(leds);
+#else
+ return(0);
+#endif
+}
+
+#if NeedFunctionPrototypes
+void xf86SetKbdRepeat(char rad)
+#else
+void xf86SetKbdRepeat(rad)
+char rad;
+#endif
+{
+ return;
+}
+
+void xf86KbdInit()
+{
+ return;
+}
+
+int xf86KbdOn()
+{
+ int data = KB_EVENT;
+
+ if ((xf86Info.kbdFd = open ("/dev/kbd", O_RDONLY)) < 0)
+ FatalError("can't open /dev/kbd (%s)", strerror(errno));
+
+ /* Set the keyboard into non-blocking event mode. */
+ if (ioctl(xf86Info.kbdFd, KDSKBDMODE, &data) < 0)
+ FatalError("Cannot set event mode on keyboard (%s)\n",
+ strerror(errno));
+ data = 1;
+ if (ioctl (xf86Info.kbdFd, FIONBIO, &data) < 0)
+ FatalError("Cannot keyboard non-blocking (%s)\n",
+ strerror(errno));
+ return(xf86Info.kbdFd);
+}
+
+int xf86KbdOff()
+{
+ int data = KB_ASCII;
+
+ if (ioctl(xf86Info.kbdFd, KDSKBDMODE, &data) < 0)
+ FatalError("can't reset keyboard mode (%s)\n",
+ strerror(errno));
+ return(xf86Info.kbdFd);
+}
+
+void xf86KbdEvents()
+{
+ kd_event ke;
+
+ /* This loop assumes non-blocking keyboard IO. */
+ while (read (xf86Info.kbdFd, &ke, sizeof(ke)) == sizeof(ke))
+ {
+ xf86PostKbdEvent(ke.value.sc);
+ }
+}
+
+void xf86SetMouseSpeed(mouse, old, new, cflag)
+MouseDevPtr mouse;
+int old;
+int new;
+unsigned cflag;
+{
+ return;
+}
+
+void xf86MouseInit(mouse)
+MouseDevPtr mouse;
+{
+ return;
+}
+
+int xf86MouseOn(mouse)
+MouseDevPtr mouse;
+{
+ if ((mouse->mseFd = open(mouse->mseDevice, O_RDONLY, 0)) < 0)
+ {
+ if (xf86Info.allowMouseOpenFail) {
+ ErrorF("Cannot open mouse (%s) - Continuing...\n",
+ strerror(errno));
+ return(-2);
+ }
+ FatalError("Cannot open mouse (%s)\n", strerror(errno));
+ }
+ if (fcntl(mouse->mseFd, F_SETFL, FNDELAY | FASYNC) < 0)
+ {
+ if (xf86AllowMouseOpenFail) {
+ ErrorF("Cannot set up mouse (%s) - Continuing...\n",
+ strerror(errno));
+ return(-2);
+ }
+ FatalError("Cannot set up mouse (%s)\n", strerror(errno));
+ }
+
+ xf86SetupMouse(mouse);
+
+ {
+ int data = 1;
+
+ if (ioctl (mouse->mseFd, FIONBIO, &data) < 0)
+ {
+ if (xf86AllowMouseOpenFail) {
+ ErrorF("Cannot set mouse non-blocking (%s) - Continuing...\n",
+ strerror(errno));
+ return(-2);
+ }
+ FatalError(
+ "Cannot set mouse non-blocking (%s)\n",
+ strerror(errno));
+ }
+ }
+ return(mouse->mseFd);
+}
+
+int xf86MouseOff(mouse, doclose)
+MouseDevPtr mouse;
+Bool doclose;
+{
+ close(mouse->mseFd);
+ return(mouse->mseFd);
+}
+
+#define EVENT_LIST_SIZE 32
+
+void xf86MouseEvents(device)
+DeviceIntPtr device;
+{
+ int total, buttons, dx, dy;
+ static kd_event eventList[EVENT_LIST_SIZE];
+ kd_event *event;
+
+ total = read(mouse->mseFd, eventList, sizeof(eventList));
+ if (total < 0)
+ {
+ if (errno != EWOULDBLOCK)
+ {
+ if (xf86AllowMouseOpenFail) {
+ ErrorF("Cannot read from mouse (%s) - Continuing...\n",
+ strerror(errno));
+ return(-2);
+ }
+ FatalError("Cannot read from mouse (%s)\n",
+ strerror(errno));
+ }
+ return;
+ }
+
+ total /= sizeof(kd_event);
+ event = eventList;
+ while (total--)
+ {
+ buttons = mouse->lastButtons;
+ dx = dy = 0;
+
+ switch (event->type)
+ {
+ case MOUSE_RIGHT:
+ buttons = mouse->lastButtons & 6 |
+ (event->value.up ? 0 : 1);
+ break;
+ case MOUSE_MIDDLE:
+ buttons = mouse->lastButtons & 5 |
+ (event->value.up ? 0 : 2);
+ break;
+ case MOUSE_LEFT:
+ buttons = mouse->lastButtons & 3 |
+ (event->value.up ? 0 : 4);
+ break;
+ case MOUSE_MOTION:
+ dx = event->value.m_deltaX;
+ dy = - event->value.m_deltaY;
+ break;
+ default:
+ ErrorF("Bad mouse event\n");
+ break;
+ }
+ xf86PostMseEvent(device, buttons, dx, dy);
+ ++event;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/mach/mach_video.c b/xc/programs/Xserver/hw/xfree86/os-support/mach/mach_video.c
new file mode 100644
index 000000000..d1c8f7e94
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/mach/mach_video.c
@@ -0,0 +1,195 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/mach/mach_video.c,v 3.2 1997/08/26 10:01:37 hohndel Exp $ */
+/*
+ * Copyright 1992 by Robert Baron <Robert.Baron@ernst.mach.cs.cmu.edu>
+ * Copyright 1993 by David Wexelblat <dwex@XFree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Robert Baron and David Wexelblat not
+ * be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. Robert Baron and
+ * David Wexelblat make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * ROBERT BARON AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL ROBERT BARON OR DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: mach_video.c /main/3 1996/02/21 17:51:57 kaleb $ */
+
+#include "X.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+/***************************************************************************/
+/* Video Memory Mapping section */
+/***************************************************************************/
+
+#define KERN_SUCCESS 0
+
+pointer xf86MapVidMem(ScreenNum, Region, Base, Size)
+int ScreenNum;
+int Region;
+pointer Base;
+unsigned long Size;
+{
+ pointer base;
+ int fd;
+
+ if ((fd = open("/dev/iopl", O_RDWR, 0)) < 0)
+ {
+ FatalError("xf86MapVidMem: Failed to get IOPL\n");
+ }
+ if (KERN_SUCCESS != vm_allocate(task_self(), &base, Size, TRUE))
+ {
+ FatalError("xf86MapVidMem: can't alloc framebuffer space\n");
+ }
+
+ if (mmap(base, Size, 3, 1, fd, Base) < 0)
+ {
+ vm_deallocate(task_self(), base, Size);
+ close(fd);
+ FatalError("xf86MapVidMem: Could not mmap frambuffer\n");
+ }
+ close(fd);
+ return(base);
+}
+
+void xf86UnMapVidMem(ScreenNum, Region, Base, Size)
+int ScreenNum;
+int Region;
+pointer Base;
+unsigned long Size;
+{
+ if (KERN_SUCCESS != vm_deallocate(task_self(), Base, Size))
+ {
+ ErrorF("xf86UnMapVidMem: can't dealloc framebuffer space\n");
+ }
+}
+
+Bool xf86LinearVidMem()
+{
+ return(TRUE);
+}
+
+/***************************************************************************/
+/* I/O Permissions section */
+/***************************************************************************/
+
+/*
+ * Mach disables I/O permissions completely, and OSF/1 doesn't bother
+ * with I/O permissions right now.
+ */
+
+#ifdef MACH386
+static int ioplfd = -1;
+static Bool ScreenEnabled[MAXSCREENS];
+static Bool IOEnabled = FALSE;
+static Bool InitDone = FALSE;
+#endif
+
+
+void xf86EnableIOPorts(ScreenNum)
+int ScreenNum;
+{
+#ifdef MACH386
+ int i;
+
+ if (!InitDone)
+ {
+ for (i = 0; i < MAXSCREENS; i++)
+ ScreenEnabled[i] = FALSE;
+ InitDone = TRUE;
+ }
+ ScreenEnabled[ScreenNum] = TRUE;
+
+ if (IOEnabled)
+ return;
+
+ if ((ioplfd = open("/dev/iopl", 0)) < 0)
+ FatalError("xf86EnablePortIO: Failed to get IOPL for I/O\n");
+ IOEnabled = TRUE;
+#endif /* MACH386 */
+ return;
+}
+
+void xf86DisableIOPorts(ScreenNum)
+int ScreenNum;
+{
+#ifdef MACH386
+ int i;
+
+ ScreenEnabled[ScreenNum] = FALSE;
+
+ if (!IOEnabled)
+ return;
+
+ for (i = 0; i < MAXSCREENS; i++)
+ if (ScreenEnabled[i])
+ return;
+ close(ioplfd);
+ ioplfd = -1;
+ IOEnabled = FALSE;
+#endif /* MACH386 */
+ return;
+}
+
+/***************************************************************************/
+/* Interrupt Handling section */
+/***************************************************************************/
+
+static Bool Mach30()
+{
+#ifdef MACH386
+ if (syscall(-27) != 4)
+ {
+ return(TRUE);
+ }
+ else
+ {
+ return(FALSE);
+ }
+#else /* MACH386 */
+ return(FALSE);
+#endif /* MACH386 */
+}
+
+Bool xf86DisableInterrupts()
+{
+ if (Mach30())
+ {
+ ErrorF("Mach 3.0 does not allow interrupts to be disabled\n");
+ return(FALSE);
+ }
+#ifdef __GNUC__
+ __asm__ __volatile__("cli");
+#else
+ asm("cli");
+#endif /* __GNUC__ */
+
+ return(TRUE);
+}
+
+void xf86EnableInterrupts()
+{
+#ifdef __GNUC__
+ __asm__ __volatile__("sti");
+#else
+ asm("sti");
+#endif /* __GNUC__ */
+
+ return;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/minix/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/minix/Imakefile
new file mode 100644
index 000000000..5022a0ce6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/minix/Imakefile
@@ -0,0 +1,29 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/minix/Imakefile,v 3.4 1996/12/23 06:50:15 dawes Exp $
+
+
+
+
+
+XCOMM $XConsortium: Imakefile /main/5 1996/09/28 17:24:04 rws $
+
+#include <Server.tmpl>
+
+SRCS = mnx_init.c mnx_video.c mnx_io.c bios_devmem.c mapVT_noop.c \
+ ioperm_noop.c VTsw_noop.c std_mouse.c posix_tty.c
+
+OBJS = mnx_init.o mnx_video.o mnx_io.o bios_devmem.o mapVT_noop.o \
+ ioperm_noop.o VTsw_noop.o posix_tty.o
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC)
+
+SubdirLibraryRule($(OBJS))
+NormalLibraryObjectRule()
+NormalAsmObjectRule()
+
+ObjectFromSpecialSource(mapVT_noop,../shared/mapVT_noop,/**/)
+ObjectFromSpecialSource(ioperm_noop,../shared/ioperm_noop,/**/)
+ObjectFromSpecialSource(VTsw_noop,../shared/VTsw_noop,/**/)
+ObjectFromSpecialSource(posix_tty,../shared/posix_tty,/**/)
+
+DependTarget()
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/minix/bios_devmem.c b/xc/programs/Xserver/hw/xfree86/os-support/minix/bios_devmem.c
new file mode 100644
index 000000000..50f905caa
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/minix/bios_devmem.c
@@ -0,0 +1,78 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/minix/bios_devmem.c,v 3.2 1996/12/23 06:50:16 dawes Exp $ */
+/*
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of David Wexelblat not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Wexelblat makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: bios_devmem.c /main/4 1996/02/21 17:52:05 kaleb $ */
+
+#include "X.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+/*
+ * Read BIOS via /dev/mem.
+ */
+
+#ifndef DEV_MEM
+# define DEV_MEM "/dev/mem"
+#endif
+
+int xf86ReadBIOS(Base, Offset, Buf, Len)
+unsigned long Base;
+unsigned long Offset;
+unsigned char *Buf;
+int Len;
+{
+ int fd;
+ uid_t real_uid;
+
+ real_uid= getuid();
+
+ setuid(0);
+ if ((fd = open(DEV_MEM, O_RDONLY)) < 0)
+ {
+ ErrorF("xf86ReadBios: Failed to open %s (%s)\n", DEV_MEM,
+ strerror(errno));
+ setuid(real_uid);
+ return(-1);
+ }
+ setuid(real_uid);
+ if (lseek(fd, (Base+Offset), SEEK_SET) < 0)
+ {
+ ErrorF("xf86ReadBios: %s seek failed (%s)\n", DEV_MEM,
+ strerror(errno));
+ close(fd);
+ return(-1);
+ }
+ if (read(fd, Buf, Len) != Len)
+ {
+ ErrorF("xf86ReadBios: %s read failed (%s)\n", DEV_MEM,
+ strerror(errno));
+ close(fd);
+ return(-1);
+ }
+ close(fd);
+ return(Len);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/minix/local.h b/xc/programs/Xserver/hw/xfree86/os-support/minix/local.h
new file mode 100644
index 000000000..60a23ea1c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/minix/local.h
@@ -0,0 +1,13 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/minix/local.h,v 3.2 1996/12/23 06:50:17 dawes Exp $ */
+
+/*
+local.h
+
+Local definitions for the minix os libary
+
+Created: 19 April, 1994 by Philip Homburg <philip@cs.vu.nl>
+*/
+/* $XConsortium: local.h /main/4 1996/02/21 17:52:08 kaleb $ */
+
+extern char *xf86VideoBaseRaw;
+extern char *xf86VideoBase;
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/minix/mnx_init.c b/xc/programs/Xserver/hw/xfree86/os-support/minix/mnx_init.c
new file mode 100644
index 000000000..844537748
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/minix/mnx_init.c
@@ -0,0 +1,110 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/minix/mnx_init.c,v 3.7 1998/07/25 16:56:47 dawes Exp $ */
+/*
+ * Copyright 1993 by Vrije Universiteit, The Netherlands
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of The Vrije Universiteit and David
+ * Wexelblat not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * The Vrije Universiteit and David Wexelblat make no representations about
+ * the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE VRIJE UNIVERSITEIT AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE VRIJE UNIVERSITEIT OR
+ * DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: mnx_init.c /main/5 1996/02/21 17:52:12 kaleb $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "compiler.h"
+
+#include "local.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#define VIDEO_SIZE 0x20000
+#define VIDEO_ALIGN 0x1000
+
+char *xf86VideoBaseRaw= NULL;
+char *xf86VideoBase= NULL;
+
+void xf86OpenConsole()
+{
+ int fd, r, align_diff;
+ struct mio_map mio_map;
+ uid_t real_uid;
+
+ if (serverGeneration == 1)
+ {
+ real_uid= getuid();
+
+ /* check if we're run with euid==0 */
+ if (setuid(0) != 0)
+ {
+ FatalError("xf86OpenConsole: Server must be suid root\n");
+ }
+ fd = open("/dev/vga", O_RDWR);
+ if (fd == -1)
+ {
+ FatalError("xf86OpenConsole: Can't open /dev/vga: %s\n",
+ strerror(errno));
+ }
+ setuid(real_uid);
+
+ xf86VideoBaseRaw = (char *)xalloc(VIDEO_SIZE+VIDEO_ALIGN);
+ if (xf86VideoBaseRaw == 0)
+ {
+ FatalError("xf86OpenConsole: Out of memory\n");
+ }
+ align_diff = (int)xf86VideoBaseRaw;
+ align_diff = VIDEO_ALIGN-(((align_diff-1) & (VIDEO_ALIGN-1))+1);
+ assert(align_diff >= 0 && align_diff < VIDEO_ALIGN);
+ xf86VideoBase = xf86VideoBaseRaw + align_diff;
+ mio_map.mm_base = (u32_t)xf86VideoBase;
+ mio_map.mm_size = VIDEO_SIZE;
+ r = ioctl(fd, MIOCMAP, &mio_map);
+ if (r == -1)
+ {
+ FatalError("xf86OpenConsole: MIOCMAP failed: %s\n",
+ strerror(errno));
+ }
+ }
+ return;
+}
+
+void xf86CloseConsole()
+{
+ xfree(xf86VideoBaseRaw);
+ xf86VideoBaseRaw = NULL; /* not needed? */
+ return;
+}
+
+/* ARGSUSED */
+int xf86ProcessArgument (argc, argv, i)
+int argc;
+char *argv[];
+int i;
+{
+ return(0);
+}
+
+void xf86UseMsg()
+{
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/minix/mnx_io.c b/xc/programs/Xserver/hw/xfree86/os-support/minix/mnx_io.c
new file mode 100644
index 000000000..89882bf10
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/minix/mnx_io.c
@@ -0,0 +1,277 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/minix/mnx_io.c,v 3.12 1999/05/07 02:56:21 dawes Exp $ */
+/*
+ * Copyright 1993 by Vrije Universiteit, The Netherlands
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of the Vrije Universiteit and David
+ * Dawes not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * The Vrije Universiteit and David Dawes make no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE VRIJE UNIVERSITEIT AND DAVID DAWES DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE VRIJE UNIVERSITEIT OR
+ * DAVID DAWES 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.
+ *
+ */
+/* $XConsortium: mnx_io.c /main/10 1996/10/19 18:07:03 kaleb $ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86Config.h"
+
+#include <sys/nbio.h>
+
+void xf86SoundKbdBell(loudness, pitch, duration)
+int loudness;
+int pitch;
+int duration;
+{
+ kio_bell_t kio_bell;
+ int r;
+
+ kio_bell.kb_pitch = pitch;
+ kio_bell.kb_volume = 1000000 / 100 * loudness;
+ kio_bell.kb_duration.tv_sec = duration / 1000;
+ kio_bell.kb_duration.tv_usec = (duration % 1000) * 1000;
+ r = ioctl(xf86Info.kbdFd, KIOCBELL, &kio_bell);
+ if (r != 0)
+ {
+ ErrorF("(warning) unable to ring keyboard bell: %s\n",
+ strerror(errno));
+ }
+}
+
+void xf86SetKbdLeds(leds)
+int leds;
+{
+ kio_leds_t kio_leds;
+ int r;
+
+ kio_leds.kl_bits= leds;
+ r = ioctl(xf86Info.kbdFd, KIOCSLEDS, &kio_leds);
+ if (r != 0)
+ {
+ ErrorF("(warning) unable to set keyboard leds: %s\n",
+ strerror(errno));
+ }
+}
+
+int xf86GetKbdLeds()
+{
+ return(0);
+}
+
+#if NeedFunctionPrototypes
+void xf86SetKbdRepeat(char rad)
+#else
+void xf86SetKbdRepeat(rad)
+char rad;
+#endif
+{
+ return;
+}
+
+void xf86KbdInit()
+{
+ static int kbd_fd = -1;
+ int flags, r;
+ uid_t real_uid;
+
+ real_uid= getuid();
+
+ /* Open the keyboard device if not already done so */
+ if (kbd_fd < 0)
+ {
+ setuid(0);
+ kbd_fd = open("/dev/kbd", O_RDONLY);
+ if (kbd_fd == -1)
+ FatalError("Unable to open keyboard\n");
+ else
+ xf86Info.kbdFd = kbd_fd;
+ setuid(real_uid);
+
+ /* Mark the keyboard as asynchronous */
+ flags= fcntl(xf86Info.kbdFd, F_GETFD);
+ if (flags == -1)
+ FatalError("Unable to get keyboard flags\n");
+ r = fcntl(xf86Info.kbdFd, F_SETFD, flags | FD_ASYNCHIO);
+ if (r == -1)
+ FatalError("Unable to set keyboard flags\n");
+
+ nbio_register(kbd_fd);
+ }
+}
+
+int xf86KbdOn()
+{
+ char waste[16];
+ int r;
+
+ /* Get rid of old data */
+ for (;;)
+ {
+ r = nbio_read(xf86Info.kbdFd, waste, sizeof(waste));
+ if (r > 0)
+ continue;
+ if (r == -1 && errno == EAGAIN)
+ break;
+ FatalError("unable to read from keyboard (%s)\n",
+ strerror(errno));
+ }
+ return(xf86Info.kbdFd);
+}
+
+int xf86KbdOff()
+{
+ /* Should RemoveEnabledDevice() be done for Minix?? */
+ /* If it shouldn't be done, we should return -1 here */
+ return(xf86Info.kbdFd);
+}
+
+void xf86KbdEvents()
+{
+ unsigned char rBuf[64];
+ int nBytes, i;
+
+ while ((nBytes = nbio_read(xf86Info.kbdFd, (char *)rBuf,
+ sizeof(rBuf))) > 0)
+ {
+ for (i = 0; i < nBytes; i++)
+ xf86PostKbdEvent(rBuf[i]);
+ }
+ if (nBytes == 0)
+ ErrorF("xf86KbdEvents: nbio_read returns EOF");
+ else if (errno != EAGAIN)
+ {
+ ErrorF("xf86KbdEvents: nbio_read error: %s",
+ strerror(errno));
+ }
+}
+
+void xf86MouseInit(mouse)
+MouseDevPtr mouse;
+{
+ static int mseFd= -1;
+ int r, flags;
+ uid_t real_uid;
+
+ if (mseFd < 0)
+ {
+ real_uid= getuid();
+
+ setuid(0);
+ if ((mseFd = mouse->mseFd =
+ open(mouse->mseDevice, O_RDWR)) < 0)
+ {
+ if (xf86Info.allowMouseOpenFail) {
+ ErrorF("Cannot open mouse (%s) - Continuing...\n",
+ strerror(errno));
+ return;
+ }
+ FatalError("Cannot open mouse (%s)\n",
+ strerror(errno));
+ }
+ setuid(real_uid);
+
+ xf86SetupMouse(mouse);
+
+ /* Mark the mouse as asynchronous */
+ flags = fcntl(mouse->mseFd, F_GETFD);
+ if (flags == -1)
+ {
+ if (xf86AllowMouseOpenFail) {
+ ErrorF("Unable to get mouse flags (%s) - Continuing...\n",
+ strerror(errno));
+ return;
+ }
+ FatalError("Unable to get mouse flags (%s)\n",
+ strerror(errno));
+ }
+ r = fcntl(mouse->mseFd, F_SETFD, flags | FD_ASYNCHIO);
+ if (r == -1)
+ {
+ if (xf86AllowMouseOpenFail) {
+ ErrorF("Unable to set mouse flags (%s) - Continuing...\n",
+ strerror(errno));
+ return;
+ }
+ FatalError("Unable to set mouse flags (%s)\n",
+ strerror(errno));
+ }
+ nbio_register(mouse->mseFd);
+ }
+}
+
+int xf86MouseOn(mouse)
+MouseDevPtr mouse;
+{
+ char waste[16];
+ int r;
+
+ /* Get rid of old data */
+ for (;;)
+ {
+ r = nbio_read(mouse->mseFd, waste, sizeof(waste));
+ if (r > 0)
+ continue;
+ if ((r == -1 && errno == EAGAIN) || xf86AllowMouseOpenFail)
+ {
+ break;
+ }
+ if (xf86AllowMouseOpenFail) {
+ ErrorF("Unable to read from mouse (%s) - Continuing...\n",
+ strerror(errno));
+ return -2;
+ }
+ FatalError("unable to read from mouse (%s)\n",
+ strerror(errno));
+ }
+ return(mouse->mseFd);
+}
+
+void xf86MouseEvents(device)
+DeviceIntPtr device;
+{
+ unsigned char rBuf[64];
+ int nBytes;
+
+ while ((nBytes = nbio_read(mouse->mseFd, (char *)rBuf,
+ sizeof(rBuf))) > 0)
+ {
+ xf86MouseProtocol(device, rBuf, nBytes);
+ }
+ if (nBytes == 0)
+ ErrorF("xf86MouseEvents: nbio_read returns EOF");
+ else if (errno != EAGAIN)
+ {
+ ErrorF("xf86MouseEvents: nbio_read error: %s",
+ strerror(errno));
+ }
+}
+
+int xf86MouseOff(mouse, doclose)
+MouseDevPtr mouse;
+Bool doclose;
+{
+ return(mouse->mseFd);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/minix/mnx_video.c b/xc/programs/Xserver/hw/xfree86/os-support/minix/mnx_video.c
new file mode 100644
index 000000000..115f1d2f3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/minix/mnx_video.c
@@ -0,0 +1,98 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/minix/mnx_video.c,v 3.4 1996/12/23 06:50:20 dawes Exp $ */
+/*
+ * Copyright 1993 by Vrije Universiteit, The Netherlands
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of The Vrije Universiteit and David
+ * Wexelblat not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * The Vrije Universiteit and David Wexelblat make no representations about
+ * the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE VRIJE UNIVERSITEIT AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE VRIJE UNIVERSITEIT OR
+ * DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: mnx_video.c /main/5 1996/02/21 17:52:19 kaleb $ */
+
+#include "X.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "local.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+/***************************************************************************/
+/* Video Memory Mapping section */
+/***************************************************************************/
+
+/* ARGSUSED */
+pointer xf86MapVidMem(ScreenNum, Region, Base, Size)
+int ScreenNum;
+int Region;
+pointer Base;
+unsigned long Size;
+{
+ ErrorF("xf86MapVidMem(ScreenNum= %d, Base= %p, Size= 0x%x\n",
+ ScreenNum, Base, Size);
+ return((pointer)xf86VideoBase + ((unsigned)Base-0xA0000));
+}
+
+/* ARGSUSED */
+void xf86UnMapVidMem(ScreenNum, Region, Base, Size)
+int ScreenNum;
+int Region;
+pointer Base;
+unsigned long Size;
+{
+ ErrorF("(warning) xf86UnmapVidMem is not implemented\n");
+ return;
+}
+
+Bool xf86LinearVidMem()
+{
+ return(FALSE);
+}
+
+/***************************************************************************/
+/* Interrupt Handling section */
+/***************************************************************************/
+
+Bool xf86DisableInterrupts()
+{
+#ifdef __GNUC__
+ __asm__ __volatile__("cli");
+#else
+ extern void intr_disable();
+
+ intr_disable();
+#endif /* __GNUC__ */
+
+ return(TRUE);
+}
+
+void xf86EnableInterrupts()
+{
+#ifdef __GNUC__
+ __asm__ __volatile__("sti");
+#else
+ extern void intr_enable();
+
+ intr_enable();
+#endif /* __GNUC__ */
+
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/misc/BUSmemcpy.S b/xc/programs/Xserver/hw/xfree86/os-support/misc/BUSmemcpy.S
new file mode 100644
index 000000000..e4ff36c62
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/misc/BUSmemcpy.S
@@ -0,0 +1,156 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/BUSmemcpy.S,v 1.1 1999/07/10 07:24:49 dawes Exp $ */
+/******************************************************************************
+ Copyright 1993 by Glenn G. Lai
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Glenn G. Lai not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+Glenn G. Lai DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+Glenn G. Lai
+P.O. Box 4314
+Austin, Tx 78765
+(glenn@cs.utexas.edu)
+8/9/93
+******************************************************************************/
+/* $XConsortium: BUSmemcpy.s /main/4 1996/02/21 17:39:34 kaleb $ */
+
+/*
+ * Modified to use long-alignment of video memory rather than word-alignment
+ * to improve performance for LocalBus video cards. Function names changed
+ * from ISAToMem and MemToISA to BusToMem and MemToBus.
+ *
+ * David Dawes <dawes@XFree86.org>, 25 August 1993.
+ */
+
+
+#include "assyntax.h"
+
+ FILE("BUSmemcpy.s")
+
+ AS_BEGIN
+
+/* BusToMem copies from video memory to main memory
+ MemToBus copies from main memory to video memory
+
+ void xf86BusToMem(unsigned char *dst, unsigned char *src, int len);
+ void xf86MemToBus(unsigned char *dst, unsigned char *src, int len);
+*/
+
+#define dst REGOFF(4,ESP)
+#define src REGOFF(8,ESP)
+#define len REGOFF(12,ESP)
+
+ GLOBL GLNAME(xf86BusToMem)
+ GLOBL GLNAME(xf86MemToBus)
+
+ SEG_DATA
+copyright:
+ STRING("Copyright 8/9/1993 by Glenn G. Lai")
+
+ ALIGNDATA4
+tmp: D_LONG 0
+
+ SEG_TEXT
+ ALIGNTEXT4
+GLNAME(xf86BusToMem):
+ CLD
+ MOV_L (ESI, CONTENT(tmp))
+ MOV_L (EDI, EDX)
+
+ MOV_L (src, ESI)
+ MOV_L (dst, EDI)
+ MOV_L (len, ECX)
+
+ CMP_L (CONST(7), ECX)
+ JC (quickBM)
+
+ TEST_L (CONST(1), ESI)
+ JZ (BwM)
+
+ MOVS_B
+ DEC_L (ECX)
+
+BwM:
+ TEST_L (CONST(2), ESI)
+ JZ (BlM)
+
+ MOVS_W
+ DEC_L (ECX)
+ DEC_L (ECX)
+
+BlM:
+ MOV_L (ECX, EAX)
+ AND_L (CONST(3), EAX)
+ SHR_L (CONST(2), ECX)
+ REP
+ MOVS_L
+ MOV_L (EAX, ECX)
+quickBM:
+ OR_L (ECX, ECX)
+ JZ (return)
+ REP
+ MOVS_B
+return:
+ MOV_L (CONTENT(tmp), ESI)
+ MOV_L (EDX, EDI)
+ RET
+/************************/
+
+ ALIGNTEXT4
+GLNAME(xf86MemToBus):
+ CLD
+ MOV_L (ESI, CONTENT(tmp))
+ MOV_L (EDI, EDX)
+
+ MOV_L (src, ESI)
+ MOV_L (dst, EDI)
+ MOV_L (len, ECX)
+
+ CMP_L (CONST(7), ECX)
+ JC (quickMB)
+
+ TEST_L (CONST(1), EDI)
+ JZ (MwB)
+
+ MOVS_B
+ DEC_L (ECX)
+
+MwB:
+ TEST_L (CONST(2), EDI)
+ JZ (MlB)
+
+ MOVS_W
+ DEC_L (ECX)
+ DEC_L (ECX)
+
+MlB:
+ MOV_L (ECX, EAX)
+ AND_L (CONST(3), EAX)
+ SHR_L (CONST(2), ECX)
+ REP
+ MOVS_L
+ MOV_L (EAX, ECX)
+quickMB:
+ OR_L (ECX, ECX)
+ JZ (return)
+ REP
+ MOVS_B
+
+ MOV_L (CONTENT(tmp), ESI)
+ MOV_L (EDX, EDI)
+ RET
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/misc/BUSmemcpy.c b/xc/programs/Xserver/hw/xfree86/os-support/misc/BUSmemcpy.c
new file mode 100644
index 000000000..af57c7059
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/misc/BUSmemcpy.c
@@ -0,0 +1,410 @@
+
+/****************************************************************************
+
+ For Alpha Linux, BusToMem() and MemToBus() can be simply memcpy(), BUT:
+ we need to prevent unaligned operations when accessing DENSE space on the BUS,
+ as the video memory is mmap'd that way. The below code does this.
+
+NOTE: we could simply use the "memcpy()" from LIBC here, but that, currently, is
+ not as fast.
+
+Thanks to Linus Torvalds for contributing this code.
+
+****************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/BUSmemcpy.c,v 1.2 1998/07/25 16:56:48 dawes Exp $ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#ifdef __alpha__
+
+#include "compiler.h"
+
+/*
+ * The Jensen lacks dense memory, thus we have to address the bus via
+ * the sparse addressing scheme. These routines are only used in s3im.c
+ * Non time critical code uses SlowBCopy_{from/to} bus.
+ *
+ * Martin Ostermann (ost@comnets.rwth-aachen.de) - Apr.-Sep. 1996
+ */
+
+#ifdef TEST_JENSEN_CODE /* define to test the Sparse addressing on a non-Jensen */
+#define LWORD_CODING (0x18)
+#define SPARSE (5)
+#else
+#define LWORD_CODING (0x60)
+#define SPARSE (7)
+#endif
+
+void
+xf86JensenMemToBus(char *Base, long dst, long src, int count)
+{
+ if( ((long)src^((long)dst)) & 3) { /* src & dst are NOT aligned to each other */
+
+ unsigned long addr;
+ unsigned long low_word, high_word,last_read;
+ long rm,loop;
+ unsigned long tmp,org,org2,mask,src_org,count_org;
+
+ src_org=src;
+ count_org=count;
+
+ addr = (long)(Base+(dst<<SPARSE) + LWORD_CODING) & ~(3<<SPARSE); /* add EISA longword coding and round off*/
+ rm = (long)dst & 3;
+ count += rm;
+
+ count = count_org + rm;
+ org = *(volatile unsigned int *)addr;
+ __asm__("ldq_u %0,%1":"=r" (low_word):"m" (*(unsigned long *)(src_org)));
+ src = src_org - rm;
+ if( count > 4 ) {
+ last_read = src_org+count_org -1;
+ __asm__("ldq_u %0,%1":"=r" (high_word):"m" (*(unsigned long *)(src+4)));
+ __asm__("extll %1,%2,%0"
+ :"=r" (low_word)
+ :"r" (low_word), "r" ((unsigned long)(src)));
+ __asm__("extlh %1,%2,%0"
+ :"=r" (tmp)
+ :"r" (high_word), "r" ((unsigned long)(src)));
+ tmp |= low_word;
+ src += 4;
+ __asm__("mskqh %1,%2,%0"
+ :"=r" (tmp)
+ :"r" (tmp), "r" (rm));
+ __asm__("mskql %1,%2,%0"
+ :"=r" (org2)
+ :"r" (org), "r" (rm));
+ tmp |= org2;
+
+ loop = (count-4) >> 2; /* loop eqv. count>=4 ; count -= 4 */
+ while (loop) { /* tmp to be stored completly -- need to read next word*/
+ low_word = high_word;
+ *(volatile unsigned int *) (addr) = tmp;
+ __asm__("ldq_u %0,%1":"=r" (high_word):"m" (*(unsigned long*)(src+4)));
+ loop --;
+ __asm__("extll %1,%2,%0"
+ :"=r" (low_word)
+ :"r" (low_word), "r" ((unsigned long)src));
+ __asm__("extlh %1,%2,%0"
+ :"=r" (tmp)
+ :"r" (high_word), "r" ((unsigned long)src));
+ src += 4;
+ tmp |= low_word;
+ addr += 4<<SPARSE;
+ }
+ if ( count & 3 ) { /* Store tmp completly, and possibly read one more word.*/
+ *(volatile unsigned int *) (addr) = tmp;
+ __asm__("ldq_u %0,%1":"=r" (tmp):"m" (*((unsigned long *)(last_read)) ));
+ addr += 4<<SPARSE;
+ __asm__("extll %1,%2,%0"
+ :"=r" (low_word)
+ :"r" (high_word), "r" ((unsigned long)src));
+ __asm__("extlh %1,%2,%0"
+ :"=r" (tmp)
+ :"r" (tmp), "r" ((unsigned long)src));
+ tmp |= low_word;
+ org = *(volatile unsigned int *)addr;
+
+ __asm__("mskql %1,%2,%0"
+ :"=r" (tmp)
+ :"r" (tmp), "r" (count&3));
+ __asm__("mskqh %1,%2,%0"
+ :"=r" (org)
+ :"r" (org), "r" (count&3));
+
+ tmp |= org;
+ }
+ *(volatile unsigned int *) (addr) = tmp;
+ return;
+ }
+
+ else { /* count > 4 */
+ __asm__("ldq_u %0,%1":"=r" (high_word):"m" (*(unsigned long *)(src+4)));
+ __asm__("extll %1,%2,%0"
+ :"=r" (low_word)
+ :"r" (low_word), "r" ((unsigned long)(src)));
+ __asm__("extlh %1,%2,%0"
+ :"=r" (tmp)
+ :"r" (high_word), "r" ((unsigned long)(src)));
+ tmp |= low_word;
+ if( count < 4 ) {
+
+ mask = -1;
+ __asm__("mskqh %1,%2,%0"
+ :"=r" (mask)
+ :"r" (mask), "r" (rm));
+ __asm__("mskql %1,%2,%0"
+ :"=r" (mask)
+ :"r" (mask), "r" (count));
+ tmp = (tmp & mask) | (org & ~mask);
+ *(volatile unsigned int *) (addr) = tmp;
+ return;
+ }
+ else {
+ __asm__("mskqh %1,%2,%0"
+ :"=r" (tmp)
+ :"r" (tmp), "r" (rm));
+ __asm__("mskql %1,%2,%0"
+ :"=r" (org2)
+ :"r" (org), "r" (rm));
+
+ tmp |= org2;
+ *(volatile unsigned int *) (addr) = tmp;
+ return;
+ }
+ }
+ }
+
+ else { /* src & dst are aligned to each other */
+ unsigned long addr;
+ unsigned int tmp,org,rm,mask;
+ unsigned int *src_r;
+
+ addr = (long)(Base+(dst<<SPARSE) + LWORD_CODING) & ~(3<<SPARSE); /* add EISA longword coding and round off*/
+ src_r = (unsigned int*)((long)src & ~3L);
+ rm=(long)src & 3;
+ count += rm;
+
+ tmp = *src_r;
+ org = *(volatile unsigned int *)addr;
+
+ __asm__("mskqh %1,%2,%0"
+ :"=r" (tmp)
+ :"r" (tmp), "r" (rm));
+ __asm__("mskql %1,%2,%0"
+ :"=r" (org)
+ :"r" (org), "r" (rm));
+
+ tmp |= org;
+
+ while (count > 4){
+ *(volatile unsigned int *) addr = tmp;
+ addr += 4<<SPARSE;
+ src_r += 1;
+ tmp = *src_r;
+ count -= 4;
+ }
+
+ org = *(volatile unsigned int *)addr;
+ __asm__("mskql %1,%2,%0"
+ :"=r" (tmp)
+ :"r" (tmp), "r" (count));
+ __asm__("mskqh %1,%2,%0"
+ :"=r" (org)
+ :"r" (org), "r" (count));
+ tmp |= org;
+ *(volatile unsigned int *) (addr) = tmp;
+ }
+}
+
+void
+xf86JensenBusToMem(char *Base, char *dst, unsigned long src, int count)
+{
+#if 0
+ /* Optimization of BusToMem() is left as an exercise to the reader ;-)
+ * Consider that ldq_u/extlh/extll won't work because of the bus being
+ * only 4 bytes wide!
+ */
+#else
+ unsigned long addr;
+ long result;
+
+ addr = (unsigned long)(Base+(src<<SPARSE)) ;
+ while( addr & (3<<SPARSE) ){
+ if(count <= 0) return;
+ result = *(volatile int *) addr;
+ result >>= ((addr>>SPARSE) & 3) * 8;
+ *dst++ = (char) result;
+ addr += 1<<SPARSE;
+ count--;
+ }
+ count -=4;
+ while(count >= 0){
+ int i;
+
+ result = *(volatile int *) (addr+LWORD_CODING);
+ for(i=4;i--;) {
+ *dst++ = (char) result;
+ result >>= 8;
+ }
+ addr += 4<<SPARSE;
+ count -= 4;
+ }
+ count +=4;
+
+ while( count ){
+ result = *(volatile int *) addr;
+ result >>= ((addr>>SPARSE) & 3) * 8;
+ *dst++ = (char) result;
+ addr += 1<<SPARSE;
+ count--;
+ }
+#endif
+}
+
+
+static unsigned long __memcpy(unsigned long dest, unsigned long src, int n);
+
+void
+xf86BusToMem(unsigned char *dst, unsigned char *src, int len)
+{
+ __memcpy((unsigned long)dst, (unsigned long)src, len);
+}
+void
+xf86MemToBus(unsigned char *dst, unsigned char *src, int len)
+{
+ if (len == sizeof(int))
+#ifdef __alpha__
+ if (!(((long)src | (long)dst) & 3))
+ *((unsigned int*)dst) = *((unsigned int*)(src));
+ else {
+ int i;
+ if (((long)src) & 3)
+ i = ldl_u((unsigned int*)src);
+ else
+ i = *(unsigned int*)src;
+ if (((long)dst) & 3)
+ stl_u(i,(unsigned int*)dst);
+ else
+ *(unsigned int*)dst = i;
+ }
+#else
+ *((unsigned int*)dst) = *((unsigned int*)(src));
+#endif
+ else
+ __memcpy((unsigned long)dst, (unsigned long)src, len);
+}
+
+/*
+ * linux/arch/alpha/lib/memcpy.c
+ *
+ * Copyright (C) 1995 Linus Torvalds, used with his permission.
+ */
+
+/*
+ * This is a reasonably optimized memcpy() routine.
+ */
+
+/*
+ * Note that the C code is written to be optimized into good assembly. However,
+ * at this point gcc is unable to sanely compile "if (n >= 0)", resulting in a
+ * explicit compare against 0 (instead of just using the proper "blt reg, xx" or
+ * "bge reg, xx"). I hope alpha-gcc will be fixed to notice this eventually..
+ */
+
+#include <linux/types.h>
+
+/*
+ * This should be done in one go with ldq_u*2/mask/stq_u. Do it
+ * with a macro so that we can fix it up later..
+ */
+#define ALIGN_DEST_TO8(d,s,n) \
+ while (d & 7) { \
+ if (n <= 0) return; \
+ n--; \
+ *(char *) d = *(char *) s; \
+ d++; s++; \
+ }
+
+/*
+ * This should similarly be done with ldq_u*2/mask/stq. The destination
+ * is aligned, but we don't fill in a full quad-word
+ */
+#define DO_REST(d,s,n) \
+ while (n > 0) { \
+ n--; \
+ *(char *) d = *(char *) s; \
+ d++; s++; \
+ }
+
+/*
+ * This should be done with ldq/mask/stq. The source and destination are
+ * aligned, but we don't fill in a full quad-word
+ */
+#define DO_REST_ALIGNED(d,s,n) DO_REST(d,s,n)
+
+/*
+ * This does unaligned memory copies. We want to avoid storing to
+ * an unaligned address, as that would do a read-modify-write cycle.
+ * We also want to avoid double-reading the unaligned reads.
+ *
+ * Note the ordering to try to avoid load (and address generation) latencies.
+ */
+static __inline__ void __memcpy_unaligned(unsigned long d, unsigned long s, long n)
+{
+ ALIGN_DEST_TO8(d,s,n);
+ n -= 8; /* to avoid compare against 8 in the loop */
+ if (n >= 0) {
+ unsigned long low_word, high_word;
+ __asm__("ldq_u %0,%1":"=r" (low_word):"m" (*(unsigned long *) s));
+ do {
+ unsigned long tmp;
+ __asm__("ldq_u %0,%1":"=r" (high_word):"m" (*(unsigned long *)(s+8)));
+ n -= 8;
+ __asm__("extql %1,%2,%0"
+ :"=r" (low_word)
+ :"r" (low_word), "r" (s));
+ __asm__("extqh %1,%2,%0"
+ :"=r" (tmp)
+ :"r" (high_word), "r" (s));
+ s += 8;
+ *(unsigned long *) d = low_word | tmp;
+ d += 8;
+ low_word = high_word;
+ } while (n >= 0);
+ }
+ n += 8;
+ DO_REST(d,s,n);
+}
+
+/*
+ * Hmm.. Strange. The __asm__ here is there to make gcc use a integer register
+ * for the load-store. I don't know why, but it would seem that using a floating
+ * point register for the move seems to slow things down (very small difference,
+ * though).
+ *
+ * Note the ordering to try to avoid load (and address generation) latencies.
+ */
+static __inline__ void __memcpy_aligned(unsigned long d, unsigned long s, long n)
+{
+ ALIGN_DEST_TO8(d,s,n);
+ n -= 8;
+ while (n >= 0) {
+ unsigned long tmp;
+ __asm__("ldq %0,%1":"=r" (tmp):"m" (*(unsigned long *) s));
+ n -= 8;
+ s += 8;
+ *(unsigned long *) d = tmp;
+ d += 8;
+ }
+ n += 8;
+ DO_REST_ALIGNED(d,s,n);
+}
+
+static unsigned long __memcpy(unsigned long dest, unsigned long src, int n)
+{
+ if (!((dest ^ src) & 7)) {
+ __memcpy_aligned(dest, src, n);
+ return dest;
+ }
+ __memcpy_unaligned(dest, src, n);
+ return dest;
+}
+
+#else /* __alpha__ */
+
+void
+xf86BusToMem(unsigned char *dst, unsigned char *src, int len)
+{
+ memcpy(dst, src, len);
+}
+void
+xf86MemToBus(unsigned char *dst, unsigned char *src, int len)
+{
+ memcpy(dst, src, len);
+}
+
+#endif /* __alpha__ */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/misc/IODelay.S b/xc/programs/Xserver/hw/xfree86/os-support/misc/IODelay.S
new file mode 100644
index 000000000..4c6e32f3f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/misc/IODelay.S
@@ -0,0 +1,53 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/IODelay.S,v 1.1 1999/07/10 07:24:50 dawes Exp $ */
+/*******************************************************************************
+ Copyright 1994 by Glenn G. Lai
+
+ 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 copyr notice appear in all copies and that
+both that copyr notice and this permission notice appear in
+supporting documentation, and that the name of Glenn G. Lai not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+Glenn G. Lai DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+Glenn G. Lai
+P.O. Box 4314
+Austin, Tx 78765
+glenn@cs.utexas.edu)
+7/21/94
+*******************************************************************************/
+/* $XConsortium: IODelay.s /main/4 1996/02/21 17:40:21 kaleb $ */
+
+/*
+ * All we really need is a delay of about 40ns for I/O recovery for just
+ * about any occasion, but we'll be more conservative here: On a
+ * 100-MHz CPU, produce at least a delay of 1,000ns.
+ */
+
+#include "assyntax.h"
+
+ FILE("DACDelay.s")
+
+ AS_BEGIN
+
+ GLOBL GLNAME(xf86IODelay)
+
+ SEG_TEXT
+ ALIGNTEXT4
+GLNAME(xf86IODelay):
+ MOV_L (CONST(100), EAX)
+delay_it:
+ DEC_L (EAX)
+ JNE (delay_it)
+ RET
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/misc/IODelay.c b/xc/programs/Xserver/hw/xfree86/os-support/misc/IODelay.c
new file mode 100644
index 000000000..66ba66a40
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/misc/IODelay.c
@@ -0,0 +1,23 @@
+
+/* $XConsortium: IODelay.c /main/1 1996/05/07 17:13:43 kaleb $ */
+/*******************************************************************************
+ Stub for Alpha Linux
+*******************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/IODelay.c,v 1.2 1998/07/25 16:56:49 dawes Exp $ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+/*
+ * All we really need is a delay of about 40ns for I/O recovery for just
+ * about any occasion, but we'll be more conservative here: On a
+ * 100-MHz CPU, produce at least a delay of 1,000ns.
+ */
+void
+xf86IODelay()
+{
+ usleep(1);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/misc/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/misc/Imakefile
new file mode 100644
index 000000000..f227c72b5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/misc/Imakefile
@@ -0,0 +1,42 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/Imakefile,v 3.6 1999/07/10 07:24:50 dawes Exp $
+
+
+
+
+XCOMM $XConsortium: Imakefile /main/4 1996/09/28 17:24:12 rws $
+
+#include <Server.tmpl>
+
+
+#if defined(i386Architecture)
+XSRCS = BUSmemcpy.S IODelay.S SlowBcopy.S
+XOBJS = BUSmemcpy.o IODelay.o SlowBcopy.o
+#elif defined(SparcArchitecture)
+XSRCS = BUSmemcpy.c IODelay.c SlowBcopy.c SparcMulDiv.S
+XOBJS = BUSmemcpy.o IODelay.o SlowBcopy.o SparcMulDiv.o
+#else
+XSRCS = BUSmemcpy.c IODelay.c SlowBcopy.c
+XOBJS = BUSmemcpy.o IODelay.o SlowBcopy.o
+#endif
+
+SRCS = xf86_Util.c xf86_IlHack.c $(XSRCS)
+
+OBJS = xf86_Util.o xf86_IlHack.o $(XOBJS)
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC)
+
+SubdirLibraryRule($(OBJS))
+NormalLibraryObjectRule()
+
+#if defined(i386Architecture)
+ObjectFromAsmSource(BUSmemcpy,NullParameter)
+ObjectFromAsmSource(IODelay,NullParameter)
+ObjectFromAsmSource(SlowBcopy,NullParameter)
+#endif
+#if defined(SparcArchitecture)
+ObjectFromAsmSource(SparcMulDiv,NullParameter)
+#endif
+
+DependTarget()
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/misc/SlowBcopy.S b/xc/programs/Xserver/hw/xfree86/os-support/misc/SlowBcopy.S
new file mode 100644
index 000000000..9b6af1d69
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/misc/SlowBcopy.S
@@ -0,0 +1,108 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/SlowBcopy.S,v 1.1 1999/07/10 07:24:51 dawes Exp $ */
+/*******************************************************************************
+ Copyright 1994 by Glenn G. Lai
+
+ 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 copyr notice appear in all copies and that
+both that copyr notice and this permission notice appear in
+supporting documentation, and that the name of Glenn G. Lai not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+Glenn G. Lai DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+Glenn G. Lai
+P.O. Box 4314
+Austin, Tx 78765
+glenn@cs.utexas.edu)
+7/21/94
+*******************************************************************************/
+/* $XConsortium: SlowBcopy.s /main/4 1996/02/21 17:40:52 kaleb $ */
+
+/*
+ * Modified from the output generated by GCC
+ *
+ * Create a dependency that should be immune from the effect of register
+ * renaming as is commonly seen in superscalar processors. This should
+ * insert a minimum of 100-ns delays between reads/writes at clock rates
+ * up to 100 MHz---GGL
+ *
+ * Slowbcopy(char *src, char *dst, int count)
+ *
+ */
+
+#include "assyntax.h"
+
+ FILE("SlowBcopy.s")
+
+ AS_BEGIN
+
+gcc2_compiled.:
+___gnu_compiled_c:
+
+ GLOBL GLNAME(xf86SlowBcopy)
+
+ SEG_TEXT
+ ALIGNTEXT4
+GLNAME(xf86SlowBcopy):
+ PUSH_L (EBP)
+ MOV_L (ESP,EBP)
+ PUSH_L (ESI)
+ PUSH_L (EBX)
+ MOV_L (REGOFF(8,EBP),ECX)
+ MOV_L (REGOFF(12,EBP),EDX)
+ MOV_L (REGOFF(16,EBP),ESI)
+ XOR_L (EAX,EAX)
+ CMP_L (ESI,EAX)
+ JGE (L3)
+
+ ALIGNTEXT4
+L5:
+ MOV_B (REGIND(ECX),BL)
+
+ MOV_B (BL, BH)
+ MOV_B (BH, BL)
+ MOV_B (BL, BH)
+ MOV_B (BH, BL)
+ MOV_B (BL, BH)
+ MOV_B (BH, BL)
+ MOV_B (BL, BH)
+ MOV_B (BH, BL)
+ MOV_B (BL, BH)
+ MOV_B (BH, BL)
+
+ MOV_B (BL,REGIND(EDX))
+
+ INC_L (ECX)
+ DEC_L (ECX)
+ INC_L (ECX)
+ DEC_L (ECX)
+ INC_L (ECX)
+ DEC_L (ECX)
+ INC_L (ECX)
+ DEC_L (ECX)
+ INC_L (ECX)
+ DEC_L (ECX)
+
+ INC_L (ECX)
+ INC_L (EDX)
+ INC_L (EAX)
+ CMP_L (ESI,EAX)
+ JL (L5)
+L3:
+ LEA_L (REGOFF(-8,EBP),ESP)
+ POP_L (EBX)
+ POP_L (ESI)
+ MOV_L (EBP,ESP)
+ POP_L (EBP)
+ RET
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/misc/SlowBcopy.c b/xc/programs/Xserver/hw/xfree86/os-support/misc/SlowBcopy.c
new file mode 100644
index 000000000..869147417
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/misc/SlowBcopy.c
@@ -0,0 +1,96 @@
+
+/* $XConsortium: SlowBcopy.c /main/1 1996/05/07 17:14:10 kaleb $ */
+/*******************************************************************************
+ for Alpha Linux
+*******************************************************************************/
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/SlowBcopy.c,v 1.3 1999/03/28 15:32:59 dawes Exp $ */
+
+/*
+ * Create a dependency that should be immune from the effect of register
+ * renaming as is commonly seen in superscalar processors. This should
+ * insert a minimum of 100-ns delays between reads/writes at clock rates
+ * up to 100 MHz---GGL
+ *
+ * Slowbcopy(char *src, char *dst, int count)
+ *
+ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "compiler.h"
+
+/* The outb() isn't needed on my machine, but who knows ... -- ost */
+void
+xf86SlowBcopy(unsigned char *src, unsigned char *dst, int len)
+{
+ while(len--)
+ {
+ *dst++ = *src++;
+#ifndef __sparc__
+ outb(0x80, 0x00);
+#endif
+ }
+}
+
+#ifdef __alpha__
+/*
+ * The Jensen lacks dense memory, thus we have to address the bus via
+ * the sparse addressing scheme. Time critical code uses routines from
+ * BUSmemcpy.c
+ *
+ * Martin Ostermann (ost@comnets.rwth-aachen.de) - Apr.-Sep. 1996
+ */
+
+unsigned long _bus_base(void);
+
+#ifdef TEST_JENSEN_CODE /* define to test the Sparse addressing on a non-Jensen */
+#define SPARSE (5)
+#else
+#define SPARSE (7)
+#endif
+
+void
+xf86SlowBCopyFromBus(unsigned char *src, unsigned char *dst, int count)
+{
+ if (!_bus_base()) /* Jensen */
+ {
+ unsigned long addr;
+ long result;
+
+ addr = (unsigned long) src;
+ while( count ){
+ result = *(volatile int *) addr;
+ result >>= ((addr>>SPARSE) & 3) * 8;
+ *dst++ = (unsigned char) (0xffUL & result);
+ addr += 1<<SPARSE;
+ count--;
+ outb(0x80, 0x00);
+ }
+ }
+ else
+ xf86SlowBcopy(src,dst,count);
+}
+
+void
+xf86SlowBCopyToBus(unsigned char *src, unsigned char *dst, int count)
+{
+ if (!_bus_base()) /* Jensen */
+ {
+ unsigned long addr;
+
+ addr = (unsigned long) dst;
+ while(count) {
+ *(volatile unsigned int *) addr = (unsigned short)(*src) * 0x01010101;
+ src++;
+ addr += 1<<SPARSE;
+ count--;
+ outb(0x80, 0x00);
+ }
+ }
+ else
+ xf86SlowBcopy(src,dst,count);
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/misc/SparcMulDiv.S b/xc/programs/Xserver/hw/xfree86/os-support/misc/SparcMulDiv.S
new file mode 100644
index 000000000..11139d192
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/misc/SparcMulDiv.S
@@ -0,0 +1,87 @@
+/*
+ * Hardware integer division and multiplication routines for SPARC v8 and higher.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * JAKUB JELINEK OR DAVID MILLER 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.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/SparcMulDiv.S,v 1.1 1999/07/10 07:24:51 dawes Exp $ */
+
+ .globl urem_sparcv89, umul_sparcv89, udiv_sparcv89
+ .globl rem_sparcv89, mul_sparcv89, div_sparcv89
+
+ .align 32
+urem_sparcv89:
+ wr %g0, 0x0, %y
+ nop
+ nop
+ nop
+ udiv %o0, %o1, %o2
+ umul %o2, %o1, %o2
+ retl
+ sub %o0, %o2, %o0
+
+ .align 32
+umul_sparcv89:
+ umul %o0, %o1, %o0
+ retl
+ rd %y, %o1
+
+ .align 32
+udiv_sparcv89:
+ wr %g0, 0x0, %y
+ nop
+ nop
+ retl
+ udiv %o0, %o1, %o0
+
+ .align 32
+rem_sparcv89:
+ sra %o0, 0x1f, %o4
+ wr %o4, 0x0, %y
+ nop
+ nop
+ nop
+ sdivcc %o0, %o1, %o2
+ bvs,a 1f
+ xnor %o2, %g0, %o2
+1: smul %o2, %o1, %o2
+ retl
+ sub %o0, %o2, %o0
+
+ .align 32
+mul_sparcv89:
+ smul %o0, %o1, %o0
+ retl
+ rd %y, %o1
+ nop
+
+ .align 32
+div_sparcv89:
+ sra %o0, 0x1f, %o2
+ wr %o2, 0x0, %y
+ nop
+ nop
+ nop
+ sdivcc %o0, %o1, %o0
+ bvs,a 1f
+ xnor %o0, %g0, %o0
+1: retl
+ nop
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/misc/xf86_IlHack.c b/xc/programs/Xserver/hw/xfree86/os-support/misc/xf86_IlHack.c
new file mode 100644
index 000000000..019156357
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/misc/xf86_IlHack.c
@@ -0,0 +1,15 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/xf86_IlHack.c,v 3.5 1998/07/25 16:56:51 dawes Exp $ */
+/*
+ * This file is an incredible crock to get the normally-inline functions
+ * built into the server so that things can be debugged properly.
+ *
+ * Note: this doesn't work when using a compiler other than GCC.
+ */
+/* $XConsortium: xf86_IlHack.c /main/4 1996/02/21 17:52:26 kaleb $ */
+
+
+#define static /**/
+#define __inline__ /**/
+#undef NO_INLINE
+#define DO_PROTOTYPES
+#include "compiler.h"
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/misc/xf86_Util.c b/xc/programs/Xserver/hw/xfree86/os-support/misc/xf86_Util.c
new file mode 100644
index 000000000..9f8567a63
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/misc/xf86_Util.c
@@ -0,0 +1,92 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/xf86_Util.c,v 3.7 1999/01/14 13:05:05 dawes Exp $ */
+/*
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of David Wexelblat not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Wexelblat makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: xf86_Util.c /main/5 1996/10/23 13:13:10 kaleb $ */
+
+/*
+ * This file is for utility functions that will be shared by other pieces
+ * of the system. Putting things here ensure that all the linking order
+ * dependencies are dealt with, as this library will be linked in last.
+ */
+
+#include <ctype.h>
+
+/* To prevent empty source file warnings */
+static int _xf86misc;
+
+#if 0
+/* For use only with gcc */
+#ifdef __GNUC__
+
+#include "os.h"
+
+char *
+debug_alloca(char *file, int line, int size)
+{
+ char *ptr;
+
+ ptr = Xalloc(size);
+ ErrorF("Alloc: %s line %d; ptr = 0x%x, length = %d\n", file, line,
+ ptr, size);
+ return ptr;
+}
+
+void
+debug_dealloca(char *file, int line, char *ptr)
+{
+ ErrorF("Dealloc: %s line %d; ptr = 0x%x\n", file, line, ptr);
+ Xfree(ptr);
+}
+#endif
+#endif
+
+#if defined(ISC) || defined(Lynx)
+
+#include <math.h>
+
+/* Needed for apm_driver.c */
+/* These functions are modeled after the functions inside gnu's libc */
+
+static double
+copysign(double x, double y)
+{
+ x = fabs(x);
+ return y < 0 ? - x : x;
+}
+
+double
+RInt(double x)
+{
+ double s,t;
+ const double one = 1.0;
+ const static double L = 4503599627370496.0E0;
+
+ if (x!=x)
+ return(x);
+ if (copysign(x,one) >= L)
+ return(x);
+ s = copysign(L,x);
+ t = x + s;
+ return (t - s);
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/os2/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/os2/Imakefile
new file mode 100644
index 000000000..8d475b755
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/os2/Imakefile
@@ -0,0 +1,37 @@
+XCOMM $XConsortium: Imakefile /main/7 1996/09/28 17:24:18 rws $
+
+
+
+
+
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/Imakefile,v 3.11 1999/04/29 09:13:47 dawes Exp $
+#include <Server.tmpl>
+
+BIOS_MOD = os2_bios
+
+SRCS = os2_init.c os2_video.c os2_io.c $(BIOS_MOD).c mapVT_noop.c \
+ os2_ioperm.c os2_VTsw.c os2_mouse.c os2_KbdEv.c os2_stubs.c \
+ os2_select.c os2_diag.c libc_wrapper.c stdResource.c vidmem.c
+
+OBJS = os2_init.o os2_video.o os2_io.o $(BIOS_MOD).o mapVT_noop.o \
+ os2_ioperm.o os2_VTsw.o os2_mouse.o os2_kbdEv.o os2_stubs.o \
+ os2_select.o os2_diag.o libc_wrapper.o stdResource.o vidmem.o
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC)
+
+RESDEFINES = -DUSESTDRES
+
+DEFINES = $(RESDEFINES)
+
+SubdirLibraryRule($(OBJS))
+NormalLibraryObjectRule()
+NormalAsmObjectRule()
+
+LinkSourceFile(mapVT_noop.c,../shared)
+LinkSourceFile(VTsw_noop.c,../shared)
+LinkSourceFile(libc_wrapper.c,../shared)
+LinkSourceFile(stdResource.c,../shared)
+LinkSourceFile(vidmem.c,../shared)
+
+DependTarget()
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/os2/README b/xc/programs/Xserver/hw/xfree86/os-support/os2/README
new file mode 100644
index 000000000..e740c8050
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/os2/README
@@ -0,0 +1,78 @@
+Information on files in this directory
+--------------------------------------
+\xc\programs\xserver\hw\xfree86\os-support\os2
+
+The files in this directory form the OS-dependent porting layer of
+XFree86 for OS/2. They are the work of:
+
+ Holger Veit <Holger.Veit@gmd.de>
+ Sebastien Marineau <marineau@genie.uottawa.ca>
+
+Some functions which were absent from OS/2,
+such as direct access to IO ports and the mapping of physical memory,
+are implemented in a device-driver written for this purpose by Holger Veit
+<Holger.Veit@gmd.de>. The driver also implements several functions
+necessary for xterm.
+The driver should be installed in the config.sys with a line:
+
+DEVICE=path\XF86SUP.SYS
+
+The following gives a brief overview of the implementation of the
+porting layer, and lists some of the "gotchas" when modifying the source.
+
+BIOS and physical memory mapping: This is handled by the functions in XF86SUP.SYS driver.
+
+IO permission: Handled by a function in the XF86SUP.SYS driver. Essentially, IO permissions
+are granted for the whole Xserver at server initialisation. The device-driver sets the IOPL
+level to ring 3 for the Xserver, which in essence gives it the same IO privileges that a
+device-driver has. Note the danger here: the Xserver can write to any IO port it wishes,
+and can disable interrupts (something which it does), thus can potentially hang the system.
+
+VT switching (switching back and forth to the WPS): This is handled by the keyboard driver,
+i.e. the stardard keyboard sequences (CTRL-ESC etc.) trigger the switch back to PM. The
+Xserver is notified of switches by the VIO function VIOSavRedrawWait(), which is run in
+a separate thread. When a switch to/from PM is requested, this function call unblocks, and
+the Xserver either saves or restores the video buffer and video mode. Note that semaphores
+are used to communicate with the main Xserver thread, and handle cases such as server
+reset while the server has lost focus etc.
+A similar mechanism is used to handle hard-error popups. A thread is run which blocks
+on the VIOModeWait() function. When a hard-error notification occurs, the Xserver attempts
+to recover by resetting the screen. Note that, due to some (probable) bugs in the OS/2
+video drivers, this does not always work as expected. According to the specs, the OS/2
+video drivers are supposed to restore the palette when returning from a hard-error. This
+does not seem to be always the case..... so the palette in X may be screwed up after the
+hard-error.
+
+Keyboard input: because X needs all keyboard event to function (both keypresses, key
+releases, for all keys), the keyboard input was implemented by registering a keyboard
+monitor for the Xserver. The keyboard monitor is run in a separate thread, and sends
+the keystrokes back to the Xserver main thread through a queue. Another thread is
+also started, whose purpose is to "eat" the keystrokes returned by KbdCharIn(). Note that
+the monitor was necessary because the OS/2 keyboard driver does not pass all keystrokes
+to the application calling KbdCharIn().
+
+Mouse input: This was implemented similarly to the keyboard input: mouse events are
+read in a thread, which then passes them to the main Xserver thread through a queue.
+
+Select: this unix and emx function has been reimplemented and optimized for the xserver.
+Because of the need to handle input from pipes, sockets, the mouse and keyboard (which
+select() in unix does but the EMX select does not), it was decided to rewrite it in
+order to minimize CPU usage and maximize responsiveness. Essentially, select() blocks on
+a MuxWait semaphore, and unblocks when input is available from pipes, the mouse and the
+keyboard. The MuxWait semaphore times out every timeslice, so that sockets can be checked
+for activity (unfortunately, sockets are not well-handled in the OS/2 TCPIP and one cannot
+attach a semaphore to a socket). There is also the possibility of using the high-resolution
+timer (found in Merlin) to check sockets more often than every timeslice.
+*** Important: in order to maximize speed, certain shortcuts are utilized in this
+implementation of select(), which makes it unsuitable as a general-purpose function. Also,
+it is imperative that the EMX select() never be called from the Xserver! ***
+
+
+If you wish to modify the source, be aware that there may be very good reasons as
+to why certain things were done this way. Usually, if certain function implementations
+appear unnecessarily complicated, it is probably because there were subtle problems
+with the simpler solutions. Due to the complexity of the Xserver code, and the
+differences between OS/2 and unix, there are many potential pitfalls.
+
+$XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/README,v 3.2 1997/01/27 06:58:06 dawes Exp $
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_VTsw.c b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_VTsw.c
new file mode 100644
index 000000000..a2fc5952c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_VTsw.c
@@ -0,0 +1,262 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_VTsw.c,v 3.9 1999/04/29 09:13:47 dawes Exp $ */
+/*
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ * Modified 1996 by Sebastien Marineau <marineau@genie.uottawa.ca>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of David Wexelblat not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Wexelblat makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: os2_VTsw.c /main/7 1996/05/13 16:37:55 kaleb $ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#define I_NEED_OS2_H
+#define INCL_WINSWITCHLIST
+#define INCL_VIO
+#define INCL_KBD
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSERRORS
+#undef RT_FONT
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "atKeynames.h"
+
+BOOL SwitchedToWPS=FALSE;
+BOOL WaitingForAccess=FALSE;
+void os2PostKbdEvent();
+HEV hevServerHasFocus;
+HEV hevSwitchRequested;
+HEV hevErrorPopupDetected;
+extern HEV hevPopupPending;
+BOOL os2PopupErrorPending=FALSE;
+
+/*
+ * Added OS/2 code to handle switching back to WPS
+ */
+
+
+Bool xf86VTSwitchPending()
+{
+ return(xf86Info.vtRequestsPending ? TRUE : FALSE);
+}
+
+Bool xf86VTSwitchAway()
+{
+ APIRET rc;
+ ULONG drive;
+
+ xf86Info.vtRequestsPending=FALSE;
+ SwitchedToWPS=TRUE;
+
+ rc = DosQuerySysInfo(5,5,&drive,sizeof(drive));
+ rc = DosSuppressPopUps(0x0000L,drive+96); /* Disable popups */
+ DosPostEventSem(hevSwitchRequested);
+ usleep(30000);
+ return(TRUE);
+}
+
+Bool xf86VTSwitchTo()
+{
+ APIRET rc;
+ ULONG drive;
+
+ xf86Info.vtRequestsPending=FALSE;
+ SwitchedToWPS=FALSE;
+ DosPostEventSem(hevSwitchRequested);
+ rc = DosQuerySysInfo(5,5,&drive,sizeof(drive));
+ rc = DosSuppressPopUps(0x0001L,drive+96); /* Disable popups */
+ /* We reset the state of the control key */
+ os2PostKbdEvent(KEY_LCtrl,1);
+ os2PostKbdEvent(KEY_LCtrl,0);
+ return(TRUE);
+}
+
+
+/* This function is run as a thread and will notify of switch-to/switch-away events */
+void os2VideoNotify(arg)
+void * arg;
+{
+ USHORT Indic;
+ USHORT NotifyType;
+ APIRET rc;
+ ULONG postCount;
+ Bool FirstTime=TRUE;
+ int timeout_count;
+
+ rc=DosCreateEventSem(NULL,&hevServerHasFocus,0L,FALSE);
+ rc=DosPostEventSem(hevServerHasFocus);
+ rc=DosCreateEventSem(NULL,&hevSwitchRequested,0L,FALSE);
+ rc=DosPostEventSem(hevSwitchRequested);
+
+
+ while(1) {
+ Indic=0;
+ rc=VioSavRedrawWait(Indic,&NotifyType,(HVIO)0);
+
+/* Here we handle the semaphore used to indicate wether we have screen access */
+ if(NotifyType==0) rc=DosResetEventSem(hevServerHasFocus,&postCount);
+ if(FirstTime){
+ FirstTime=FALSE;
+ if(NotifyType==1) NotifyType=65535; /* In case a redraw is requested on first call */
+ }
+
+/* Sanity check */
+ if(NotifyType==1){
+ if (!SwitchedToWPS) {
+ xf86Msg(X_ERROR,
+ "Abnormal switching back to server detected\n");
+ }
+ }
+
+/* Here we set the semaphore used to indicate switching request */
+
+ if((NotifyType!=65535)&&(!WaitingForAccess)) {
+ rc=DosResetEventSem(hevSwitchRequested,&postCount);
+ xf86Info.vtRequestsPending=TRUE;
+/* Then wait for semaphore to be posted once switch is complete. Wait 20 secs, then kill server */
+ timeout_count=0;
+ rc=DosSetPriority(2,3,0,1);
+ do {
+ rc=DosWaitEventSem(hevSwitchRequested,1000L);
+ if(rc==ERROR_TIMEOUT){
+ timeout_count++;
+ if(timeout_count>25){
+ xf86Msg(X_ERROR,
+ "Server timeout on VT switch request. Server was killed\n");
+ DosExit(1L,0);
+ }
+ if(WaitingForAccess) { /* The server is resetting */
+ DosPostEventSem(hevSwitchRequested);
+ xf86Info.vtRequestsPending=FALSE;
+ }
+ }
+ } while (rc==ERROR_TIMEOUT);
+ rc=DosSetPriority(2,2,0,1);
+ }
+ if(NotifyType==1) rc=DosPostEventSem(hevServerHasFocus);
+ if((NotifyType==0)&&(!SwitchedToWPS))
+ xf86Msg(X_ERROR,
+ "Abnormal switching away from server!\n");
+ } /* endwhile */
+
+/* End of thread */
+}
+
+/* This function is run as a thread and will notify of hard-error events */
+void os2HardErrorNotify(arg)
+void * arg;
+{
+ USHORT Indic;
+ USHORT NotifyType;
+ APIRET rc;
+ ULONG postCount;
+
+ rc=DosCreateEventSem(NULL,&hevErrorPopupDetected,0L,FALSE);
+ rc=DosPostEventSem(hevErrorPopupDetected);
+ os2PopupErrorPending=FALSE;
+
+ while(1) {
+ Indic=0;
+ rc=VioModeWait(Indic,&NotifyType,(HVIO)0);
+ if(NotifyType==0){
+ os2PopupErrorPending=TRUE;
+ rc=DosResetEventSem(hevErrorPopupDetected,&postCount);
+ rc=DosWaitEventSem(hevErrorPopupDetected,20000L);
+ if(rc==ERROR_TIMEOUT) GiveUp(0); /* Shutdown on timeout of semaphore */
+ }
+ } /* endwhile */
+
+/* End of thread */
+}
+
+void os2ServerVideoAccess()
+{
+ APIRET rc;
+ ULONG fgSession;
+ ULONG length=4;
+ CHAR Status;
+
+/* Wait for screen access. This is called at server reset or at server startup */
+/* Here we do some waiting until this session comes in the foreground before *
+ * going any further. This is because we may have been started in the bg */
+
+ if(serverGeneration==1){
+ rc=VioScrLock(0, &Status, (HVIO)0);
+ while(Status != 0){
+ rc=VioScrLock(0, &Status, (HVIO)0);
+ DosSleep(1000);
+ }
+ VioScrUnLock((HVIO)0);
+ return;
+ }
+ WaitingForAccess=TRUE;
+ rc=DosWaitEventSem(hevServerHasFocus,SEM_INDEFINITE_WAIT);
+ WaitingForAccess=FALSE;
+ SwitchedToWPS=FALSE; /* In case server has reset while we were switched to WPS */
+}
+
+/* This next function will attempt to recover from a hard error popup
+ * with an EnterLeave call
+ */
+
+void os2RecoverFromPopup()
+{
+ int j;
+ if (os2PopupErrorPending) {
+#if 0
+ for (j = 0; j < screenInfo.numScreens; j++)
+ (XF86SCRNINFO(screenInfo.screens[j])->EnterLeaveVT)(LEAVE, j);
+ for (j = 0; j < screenInfo.numScreens; j++)
+ (XF86SCRNINFO(screenInfo.screens[j])->EnterLeaveVT)(ENTER, j);
+#endif
+ /* Turn screen saver off when switching back */
+ SaveScreens(SCREEN_SAVER_FORCER,ScreenSaverReset);
+ os2PopupErrorPending=FALSE;
+ DosPostEventSem(hevErrorPopupDetected);
+ }
+}
+
+/* This checks wether a popup event is waiting. The semaphore would be reset
+ * by the XF86VIO.DLL function
+ */
+
+void os2CheckPopupPending()
+{
+ int j;
+ ULONG postCount;
+
+ return; /* For now this is a no-op */
+
+#if 0
+ DosQueryEventSem(hevPopupPending,&postCount);
+ if (postCount==0) { /* We have a popup pending */
+#if 0
+ for (j = 0; j < screenInfo.numScreens; j++)
+ (XF86SCRNINFO(screenInfo.screens[j])->EnterLeaveVT)(LEAVE, j);
+#endif
+ DosPostEventSem(hevPopupPending);
+ }
+#endif
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_bios.c b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_bios.c
new file mode 100644
index 000000000..d932733b1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_bios.c
@@ -0,0 +1,119 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_bios.c,v 3.8 1999/04/29 09:13:48 dawes Exp $ */
+/*
+ * (c) Copyright 1994 by Holger Veit
+ * <Holger.Veit@gmd.de>
+ * Modified 1996 by Sebastien Marineau <marineau@genie.uottawa.ca>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Holger Veit shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Holger Veit.
+ *
+ */
+/* $XConsortium: os2_bios.c /main/5 1996/10/27 11:48:45 kaleb $ */
+
+#include "X.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#define I_NEED_OS2_H
+#define INCL_32
+#define INCL_DOS
+#define INCL_DOSFILEMGR
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+/*
+ * Read BIOS via xf86sup.SYS device driver
+ */
+
+#define Bios_Base 0
+
+int xf86ReadBIOS(Base, Offset, Buf, Len)
+unsigned long Base;
+unsigned long Offset;
+unsigned char *Buf;
+int Len;
+{
+ HFILE fd;
+ struct {
+ ULONG command;
+ ULONG physaddr;
+ USHORT numbytes;
+ } par;
+ UCHAR *dta;
+ ULONG plen,dlen;
+ int i;
+ ULONG action;
+ APIRET rc;
+ ULONG Phys_address;
+
+
+ Phys_address=Base+Offset;
+
+ /* open the special device pmap$ (default with OS/2) */
+ if (DosOpen((PSZ)"PMAP$", (PHFILE)&fd, (PULONG)&action,
+ (ULONG)0, FILE_SYSTEM, FILE_OPEN,
+ OPEN_SHARE_DENYNONE|OPEN_FLAGS_NOINHERIT|OPEN_ACCESS_READONLY,
+ (ULONG)0) != 0) {
+ FatalError("xf86ReadBIOS: install DEVICE=path\\xf86sup.SYS!");
+ return -1;
+ }
+
+ /* prepare parameter and data packets for ioctl */
+ par.command = 0;
+ par.physaddr = (ULONG)Bios_Base+(Phys_address & 0xffff8000);
+ par.numbytes = (Phys_address & 0x7fff) + Len;
+ plen = sizeof(par);
+
+ dta = xalloc(par.numbytes);
+ dlen = par.numbytes;
+
+ /* issue call to get a readonly copy of BIOS ROM */
+ if (rc=DosDevIOCtl(fd, (ULONG)0x76, (ULONG)0x64,
+ (PVOID)&par, (ULONG)plen, (PULONG)&plen,
+ (PVOID)dta, (ULONG)dlen, (PULONG)&dlen)) {
+ FatalError("xf86ReadBIOS: BIOS map failed, addr=%lx, rc=%d\n",
+ Bios_Base+Phys_address,rc);
+ free(dta);
+ DosClose(fd);
+ return -1;
+ }
+
+ /*
+ * Sanity check... No longer fatal, as some PS/1 and PS/2 fail here but still work.
+ * S. Marineau, 10/10/96
+ */
+ if ((Phys_address & 0x7fff) != 0 &&
+ (dta[0] != 0x55 || dta[1] != 0xaa)) {
+ FatalError("BIOS sanity check failed, addr=%x\nPlease report if you encounter problems\n",
+ Bios_Base+Phys_address);
+ }
+
+ /* copy data to buffer */
+ memcpy(Buf,dta + (Phys_address & 0x7fff), Len);
+ xfree(dta);
+
+ /* close device */
+ DosClose(fd);
+
+ return(Len);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_diag.c b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_diag.c
new file mode 100644
index 000000000..af554c6e8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_diag.c
@@ -0,0 +1,254 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_diag.c,v 3.6 1999/04/29 09:13:48 dawes Exp $ */
+/*
+ * (c) Copyright 1997 by Holger Veit
+ * <Holger.Veit@gmd.de>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Holger Veit shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Holger Veit.
+ *
+ */
+/* $XConsortium$ */
+
+/* This file checks whether the user has installed the system correctly,
+ * to avoid the numerous questions why this or that does not work
+ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "compiler.h"
+
+#define I_NEED_OS2_H
+#define INCL_DOSFILEMGR
+#define INCL_KBD
+#define INCL_VIO
+#define INCL_DOSMISC
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSMODULEMGR
+#define INCL_DOSFILEMGR
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+static BOOL diag_checks = FALSE;
+
+/* from Eberhard to check for the right EMX version */
+static void check_emx (void)
+{
+ ULONG rc;
+ HMODULE hmod;
+ char name[CCHMAXPATH];
+ char fail[9];
+
+ if (_emx_rev < 50) {
+ xf86Msg(X_ERROR,"This program requires emx.dll revision 50 (0.9c fix 2) "
+ "or later.\n");
+ rc = DosLoadModule (fail, sizeof (fail), "emx", &hmod);
+ if (rc == 0) {
+ rc = DosQueryModuleName (hmod, sizeof (name), name);
+ if (rc == 0)
+ xf86Msg(X_ERROR,"Please delete or update `%s'.\n", name);
+ DosFreeModule (hmod);
+ }
+ exit (2);
+ }
+}
+
+static void check_bsl(const char *var)
+{
+ char *t1 = strrchr(var,'\\');
+ if (strchr(var,'/')) {
+ xf86Msg(X_WARNING,
+ "\"%s\" must exclusively use backward slashes \"\\\"\n",
+ var);
+ }
+ if (t1 && *(t1+1)=='\0') {
+ xf86Msg(X_WARNING,
+ "\"%s\" mustn't end with \"\\\"\n",var);
+ *t1 = '\0';
+ }
+}
+
+
+static void check_fsl(const char *var)
+{
+ char *t1 = strrchr(var,'/');
+ if (strchr(var,'\\')) {
+ xf86Msg(X_WARNING,
+ "\"%s\" must exclusively use forward slashes \"/\"\n",
+ var);
+ }
+}
+
+
+static void check_long(const char* path)
+{
+ FILE *f;
+ char n[300];
+
+ sprintf(n,"%s\\xf86_test_for_very_long_filename",path);
+ f = fopen(n,"w");
+ if (f==NULL) {
+ xf86Msg(X_WARNING,
+ "\"%s\" does not accept long filenames\nmust reside on HPFS or similar\n",
+ path);
+ } else {
+ fclose(f);
+ unlink(n);
+ }
+}
+
+char *check_env_present(const char *env)
+{
+ char *e = getenv(env);
+ if (!e) {
+ xf86Msg(X_WARNING,
+ "You have no \"%s\" environment variable, but need one\n",
+ env);
+ return 0;
+ }
+ return e;
+}
+
+void os2_checkinstallation(void)
+{
+ char *emxopt, *tmp, *home, *logname, *termcap;
+ char hostname[256], *display, *hostvar, *s, *h;
+ struct hostent *hent;
+ struct in_addr *in;
+ int i;
+
+ if (diag_checks) return;
+ diag_checks = TRUE;
+
+ /* test whether the EMX version is okay */
+ check_emx();
+
+ /* Check a number of environment variables */
+ emxopt = getenv("EMXOPT");
+ if (emxopt) {
+ for (i=0; i<strlen(emxopt); i++) {
+ if (emxopt[i]=='-') {
+ switch (emxopt[++i]) {
+ case 't':
+ xf86Msg(X_ERROR,
+ "Remove -t option from EMXOPT variable!\n");
+ break;
+ case 'r':
+ xf86Msg(X_ERROR,
+ "Remove -r option from EMXOPT variable!\n");
+ }
+ }
+ }
+ }
+
+ tmp = check_env_present("TMP");
+ if (tmp) {
+ check_bsl(tmp);
+ check_long(tmp);
+ }
+
+ home = check_env_present("HOME");
+ if (home) {
+ check_bsl(home);
+ check_long(home);
+ }
+
+ logname = check_env_present("LOGNAME");
+ termcap = check_env_present("TERMCAP");
+ if (termcap)
+ check_fsl(termcap);
+
+ if (gethostname(hostname,sizeof(hostname)) != 0) {
+ xf86Msg(X_ERROR,
+ "gethostname() failed: Check TCP/IP setup!\n");
+ } else {
+ xf86Msg(X_INFO,
+ "gethostname() returns: \"%s\"\n",hostname);
+ }
+
+ display = check_env_present("DISPLAY");
+ if (display)
+ xf86Msg(X_INFO,
+ "DISPLAY to listen is set to: \"%s\"\n",
+ display);
+
+ hostvar = check_env_present("HOSTNAME");
+
+ strcpy(hostname,display);
+ h = strchr(hostname,':');
+ if (!h)
+ xf86Msg(X_WARNING,
+ "Invalid DISPLAY name: expected something like XXX:0.0\n");
+ else
+ *h = 0;
+ h = strchr(hostname,'/');
+ if (h)
+ h++;
+ else
+ h = hostname;
+
+ if (stricmp(h,hostvar)) {
+ xf86Msg(X_WARNING,
+ "HOSTNAME does not match DISPLAY: Do you really mean this?\n");
+ xf86Msg(X_WARNING,
+ " This means that xinit/startx and client access may not work\n");
+ xf86Msg(X_WARNING,
+ " which is intentional usually only when connection to a XDM server\n");
+ }
+
+ hent = gethostbyname(h);
+ if (!hent)
+ xf86Msg(X_ERROR,
+ "gethostbyname() failed: Check TCP/IP setup\n");
+ else {
+ xf86Msg(X_INFO,
+ "gethostbyname() returns the following data:\n");
+ xf86Msg(X_INFO," official host name: \"%s\"\n",hent->h_name);
+ while ((s= *(hent->h_aliases)) != NULL) {
+ xf86Msg(X_INFO,
+ " alias: \"%s\"\n",s);
+ hent->h_aliases++;
+ }
+ xf86Msg(X_INFO,
+ " addr type = %d, addr length = %d\n",
+ hent->h_addrtype, hent->h_length);
+ if (hent->h_addrtype == AF_INET) {
+ while ((in= (struct in_addr*)*(hent->h_addr_list++)) != NULL) {
+ xf86Msg(X_INFO,
+ " IP address: \"%s\"\n",
+ inet_ntoa(*in));
+ }
+ } else {
+ xf86Msg(X_INFO,
+ "Addrtype should be %d: Check network setup and install TCP/IP support correctly\n",
+ AF_INET);
+ }
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_init.c b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_init.c
new file mode 100644
index 000000000..fedee141a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_init.c
@@ -0,0 +1,227 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_init.c,v 3.15 1999/04/29 09:13:48 dawes Exp $ */
+/*
+ * (c) Copyright 1994 by Holger Veit
+ * <Holger.Veit@gmd.de>
+ * Modified 1996 Sebastien Marineau <marineau@genie.uottawa.ca>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Holger Veit shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Holger Veit.
+ *
+ */
+/* $XConsortium: os2_init.c /main/9 1996/10/19 18:07:13 kaleb $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "compiler.h"
+
+#define I_NEED_OS2_H
+#define INCL_DOSFILEMGR
+#define INCL_KBD
+#define INCL_VIO
+#define INCL_DOSMISC
+#define INCL_DOSPROCESS
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSMODULEMGR
+#define INCL_DOSFILEMGR
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+VIOMODEINFO OriginalVideoMode;
+void os2VideoNotify();
+void os2HardErrorNotify();
+void os2KbdMonitorThread();
+void os2KbdBitBucketThread();
+HEV hevPopupPending;
+extern HEV hKbdSem;
+extern BOOL os2HRTimerFlag;
+extern void os2_checkinstallation(); /* os2_diag.c */
+
+void xf86OpenConsole()
+{
+ /* try to catch problems before they become obvious */
+ os2_checkinstallation();
+
+ if (serverGeneration == 1) {
+ HKBD fd;
+ ULONG drive;
+ ULONG dummy;
+ KBDHWID hwid;
+ APIRET rc;
+ int VioTid;
+ ULONG actual_handles;
+ LONG new_handles;
+
+ /* hv 250197 workaround for xkb-Problem: switch to X11ROOT drive */
+ char *x11r = getenv("X11ROOT");
+ /* Make sure X11ROOT is set before we go further sm280297 */
+ if (x11r == NULL){
+ xf86Msg(X_ERROR,
+ "Environment variable X11ROOT is not set! Aborting...\n");
+ exit(1);
+ }
+ if (_chdir2(x11r) < 0) {
+ xf86Msg(X_ERROR,"Cannot change to X11ROOT directory!\n");
+ }
+
+ xf86Msg(X_INFO,"Console opened\n");
+ OriginalVideoMode.cb=sizeof(VIOMODEINFO);
+ rc=VioGetMode(&OriginalVideoMode,(HVIO)0);
+ if(rc!=0)
+ xf86Msg(X_ERROR,
+ "Could not get original video mode. RC=%d\n",rc);
+ xf86Info.consoleFd = -1;
+
+ /* Set the number of handles to higher than the default 20. Set to 80 which should be plenty */
+ new_handles = 0;
+ rc = DosSetRelMaxFH(&new_handles,&actual_handles);
+ if (actual_handles < 80) {
+ new_handles = 80 - actual_handles;
+ rc = DosSetRelMaxFH(&new_handles,&actual_handles);
+ xf86Msg(X_INFO,"Increased number of available handles to %d\n",
+ actual_handles);
+ }
+
+ /* grab the keyboard */
+ rc = KbdGetFocus(0,0);
+ if (rc != 0)
+ FatalError("xf86OpenConsole: cannot grab kbd focus, rc=%d\n",rc);
+
+ /* open the keyboard */
+ rc = KbdOpen(&fd);
+ if (rc != 0)
+ FatalError("xf86OpenConsole: cannot open keyboard, rc=%d\n",rc);
+ xf86Info.consoleFd = fd;
+
+ xf86Msg(X_INFO,"Keyboard opened\n");
+
+ /* assign logical keyboard */
+ KbdFreeFocus(0);
+ rc = KbdGetFocus(0,fd);
+ if (rc != 0)
+ FatalError("xf86OpenConsole: cannot set local kbd focus, rc=%d\n",rc);
+
+/* Create kbd queue semaphore */
+
+ rc = DosCreateEventSem(NULL,&hKbdSem,DC_SEM_SHARED,TRUE);
+ if (rc != 0)
+ FatalError("xf86OpenConsole: cannot create keyboard queue semaphore, rc=%d\n",rc);
+
+/* Create popup semaphore */
+
+ rc = DosCreateEventSem("\\SEM32\\XF86PUP",&hevPopupPending,DC_SEM_SHARED,1);
+ if (rc)
+ xf86Msg(X_ERROR,
+ "Could not create popup semaphore! RC=%d\n",rc);
+#if 0
+ rc=VioRegister("xf86vio","XF86POPUP_SUBCLASS",0x20002004L,0L);
+ if (rc) {
+ FatalError("Could not register XF86VIO.DLL module. Please install in LIBPATH! RC=%d\n",
+ rc);
+ }
+#endif
+
+/* Start up the VIO monitor thread */
+ VioTid=_beginthread(os2VideoNotify,NULL,0x4000,(void *)NULL);
+ xf86Msg(X_INFO,"Started Vio thread, Tid=%d\n",VioTid);
+ rc=DosSetPriority(2,3,0,VioTid);
+
+/* Start up the hard-error VIO monitor thread */
+ VioTid=_beginthread(os2HardErrorNotify,NULL,0x4000,(void *)NULL);
+ xf86Msg(X_INFO,"Started hard error Vio mode monitor thread, Tid=%d\n",
+ VioTid);
+ rc=DosSetPriority(2,3,0,VioTid);
+
+/* Start up the kbd monitor thread */
+ VioTid=_beginthread(os2KbdMonitorThread,NULL,0x4000,(void *)NULL);
+ xf86Msg(X_INFO,"Started Kbd monitor thread, Tid=%d\n",VioTid);
+ rc=DosSetPriority(2,3,0,VioTid);
+
+/* Disable hard-errors through DosError */
+ rc = DosQuerySysInfo(5,5,&drive,sizeof(drive));
+ rc = DosSuppressPopUps(0x0001L,drive+96); /* Disable popups */
+
+ rc = KbdSetCp(0,0,fd);
+ if(rc != 0)
+ FatalError("xf86OpenConsole: cannot set keyboard codepage, rc=%d\n",rc);
+
+ hwid.cb = sizeof(hwid); /* fix crash on P9000 */
+ rc = KbdGetHWID(&hwid, fd);
+ if (rc == 0) {
+ switch (hwid.idKbd) {
+ default:
+ case 0xab54: /* 88/89 key */
+ case 0: /*unknown*/
+ case 1: /*real AT 84 key*/
+ xf86Info.kbdType = KB_84; break;
+ case 0xab85: /* 122 key */
+ FatalError("Unsupported extended 122key keyboard found!\n",0);
+ case 0xab41: /* 101/102 key */
+ xf86Info.kbdType = KB_101; break;
+ }
+ } else
+ xf86Info.kbdType = KB_84; /*defensive*/
+
+/* Start up the Kbd bit-bucket thread. We don't want to leave the kbd events in the driver queue */
+ VioTid=_beginthread(os2KbdBitBucketThread,NULL,0x2000,(void *)NULL);
+ xf86Msg(X_INFO,"Started Kbd bit-bucket thread, Tid=%d\n",VioTid);
+ }
+ return;
+}
+
+void xf86CloseConsole()
+{
+ APIRET rc;
+ ULONG drive;
+
+ if (xf86Info.consoleFd != -1) {
+ KbdClose(xf86Info.consoleFd);
+ }
+ VioSetMode(&OriginalVideoMode,(HVIO)0);
+ rc = DosQuerySysInfo(5,5,&drive,sizeof(drive));
+ rc = DosSuppressPopUps(0x0000L,drive+96); /* Reenable popups */
+ rc = DosCloseEventSem(hevPopupPending);
+ rc = VioDeRegister();
+ return;
+}
+
+/* ARGSUSED */
+int xf86ProcessArgument (argc, argv, i)
+int argc;
+char *argv[];
+int i;
+{
+ if (!strcmp(argv[i], "-os2HRTimer")) {
+ os2HRTimerFlag = TRUE;
+ return 1;
+ }
+ return 0;
+}
+
+void xf86UseMsg()
+{
+ xf86Msg(X_INFO,"-os2HRTimer -use the OS/2 high-resolution timer driver (TIMER0.SYS)\n");
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_io.c b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_io.c
new file mode 100644
index 000000000..550c0a5b1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_io.c
@@ -0,0 +1,216 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_io.c,v 3.13 1999/04/29 09:13:49 dawes Exp $ */
+/*
+ * (c) Copyright 1994,1999 by Holger Veit
+ * <Holger.Veit@gmd.de>
+ * Modified 1996 by Sebastien Marineau <marineau@genie.uottawa.ca>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Holger Veit shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Holger Veit.
+ *
+ */
+/* $XConsortium: os2_io.c /main/9 1996/05/13 16:38:07 kaleb $ */
+
+#include "X.h"
+#include "Xpoll.h"
+#include "compiler.h"
+#include <time.h>
+
+#define I_NEED_OS2_H
+#define INCL_DOSPROCESS
+#define INCL_KBD
+#define INCL_MOU
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+int os2MouseQueueQuery();
+int os2KbdQueueQuery();
+void os2RecoverFromPopup();
+void os2CheckPopupPending();
+extern BOOL os2PopupErrorPending;
+int _select2 (int, fd_set *, fd_set *,fd_set *, struct timeval *);
+
+
+/***************************************************************************/
+
+void xf86SoundKbdBell(loudness, pitch, duration)
+int loudness;
+int pitch;
+int duration;
+{
+ DosBeep((ULONG)pitch, (ULONG)duration);
+}
+
+void xf86SetKbdLeds(leds)
+int leds;
+{
+ KBDINFO kinfo;
+ APIRET rc;
+
+ rc = KbdGetStatus(&kinfo,(HKBD)xf86Info.consoleFd);
+ if (!rc) {
+ kinfo.fsMask = 0x10;
+ kinfo.fsState &= ~0x70;
+ kinfo.fsState |= (leds&0x70);
+ KbdSetStatus(&kinfo,(HKBD)xf86Info.consoleFd);
+ }
+}
+
+int xf86GetKbdLeds()
+{
+ KBDINFO kinfo;
+ APIRET rc;
+
+ rc = KbdGetStatus(&kinfo,(HKBD)xf86Info.consoleFd);
+ return rc ? 0 : kinfo.fsState & 0x70;
+}
+
+#if NeedFunctionPrototypes
+void xf86SetKbdRepeat(char rad)
+#else
+void xf86SetKbdRepeat(rad)
+char rad;
+#endif
+{
+ /*notyet*/
+}
+
+void xf86KbdInit()
+{
+ /*none required*/
+}
+
+
+USHORT OrigKbdState;
+USHORT OrigKbdInterim;
+
+typedef struct {
+ USHORT state;
+ UCHAR makeCode;
+ UCHAR breakCode;
+ USHORT keyID;
+} HOTKEYPARAM;
+
+
+int xf86KbdOn()
+{
+ KBDINFO info;
+ APIRET rc;
+ int i,k;
+ ULONG len;
+
+
+ KbdGetStatus(&info,(HKBD)xf86Info.consoleFd);
+ OrigKbdState=info.fsMask;
+ OrigKbdInterim=info.fsInterim;
+ info.fsMask &= ~0x09;
+ info.fsMask |= 0x136;
+ info.fsInterim &= ~0x20;
+ KbdSetStatus(&info,(HKBD)xf86Info.consoleFd);
+ return -1;
+}
+
+int xf86KbdOff()
+{
+ ULONG len;
+ APIRET rc;
+ KBDINFO info;
+
+ info.fsMask=OrigKbdState;
+ info.fsInterim=OrigKbdInterim;
+ KbdSetStatus(&info,(HKBD)xf86Info.consoleFd);
+ return -1;
+}
+
+void xf86MouseInit(mouse)
+MouseDevPtr mouse;
+{
+ HMOU fd;
+ APIRET rc;
+ USHORT nbut;
+
+ if (serverGeneration == 1) {
+ rc = MouOpen((PSZ)NULL,(PHMOU)&fd);
+ if (rc != 0)
+ FatalError("Cannot open mouse, rc=%d\n", rc);
+ mouse->mseFd = fd;
+ }
+
+ /* flush mouse queue */
+ MouFlushQue(fd);
+
+ /* check buttons */
+ rc = MouGetNumButtons(&nbut,fd);
+ if (rc == 0)
+ xf86Msg(X_INFO,"OsMouse has %d button(s).\n",nbut);
+}
+
+int xf86MouseOn(mouse)
+MouseDevPtr mouse;
+{
+#if 0
+ HMOU fd;
+ APIRET rc;
+ USHORT nbut;
+#endif
+ xf86Msg (X_ERROR,
+ "Calling MouseOn, a bad thing.... Must be some bug in the code!\n");
+
+#if 0
+ if (serverGeneration == 1) {
+ rc = MouOpen((PSZ)NULL,(PHMOU)&fd);
+ if (rc != 0)
+ FatalError("Cannot open mouse, rc=%d\n", rc);
+ mouse->mseFd = fd;
+ }
+
+ /* flush mouse queue */
+ MouFlushQue(fd);
+
+ /* check buttons */
+ rc = MouGetNumButtons(&nbut,fd);
+ if (rc == 0)
+ xf86Msg(X_INFO,"OsMouse has %d button(s).\n",nbut);
+
+ return (mouse->mseFd);
+#endif
+}
+
+/* This table is a bit irritating, because these mouse types are infact
+ * defined in the OS/2 kernel, but I want to force the user to put
+ * ïOsMouseï in the config file, and not worry about the particular mouse
+ * type that is connected.
+ */
+Bool xf86SupportedMouseTypes[] =
+{
+ FALSE, /* Microsoft */
+ FALSE, /* MouseSystems */
+ FALSE, /* MMSeries */
+ FALSE, /* Logitech */
+ FALSE, /* BusMouse */
+ FALSE, /* MouseMan */
+ FALSE, /* PS/2 */
+ FALSE, /* Hitachi Tablet */
+};
+
+int xf86NumMouseTypes = sizeof(xf86SupportedMouseTypes) /
+ sizeof(xf86SupportedMouseTypes[0]);
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_ioperm.c b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_ioperm.c
new file mode 100644
index 000000000..0670f469f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_ioperm.c
@@ -0,0 +1,136 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_ioperm.c,v 3.6 1999/04/29 09:13:49 dawes Exp $ */
+/*
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ * Modified 1996 by Sebastien Marineau <marineau@genie.uottawa.ca>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of David Wexelblat not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Wexelblat makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: os2_ioperm.c /main/4 1996/04/18 16:50:01 kaleb $ */
+
+
+
+#define I_NEED_OS2_H
+#define INCL_32
+#define INCL_DOS
+#define INCL_DOSFILEMGR
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+/*
+ * To access I/O ports under OS/2, we use the xf86sup.sys driver.
+ * For the moment, we use a function which basically grants IO priviledge
+ * to the whole server. NOTE: Once the server is running, we should
+ * change this to use inline IO functions through the callgate returned by
+ * the fastio$ driver.
+ */
+
+int ioEnabled=FALSE;
+ULONG action;
+char *ioDrvPath = "/dev/fastio$";
+USHORT callgate[3]={0,0,0};
+
+
+void xf86EnableIO()
+{
+
+HFILE hfd;
+ ULONG dlen;
+ APIRET rc;
+
+ /* no need to call multiple times */
+ if (ioEnabled) return;
+
+ if (DosOpen((PSZ)ioDrvPath, (PHFILE)&hfd, (PULONG)&action,
+ (ULONG)0, FILE_SYSTEM, FILE_OPEN,
+ OPEN_SHARE_DENYNONE|OPEN_FLAGS_NOINHERIT|OPEN_ACCESS_READONLY,
+ (ULONG)0) != 0) {
+ xf86Msg(X_ERROR,"Error opening fastio$ driver...\n");
+ xf86Msg(X_ERROR,"Please install xf86sup.sys in config.sys!\n");
+ exit(42);
+ }
+ callgate[0] = callgate[1] = 0;
+
+/* Get callgate from driver for fast io to ports and other stuff */
+
+ rc = DosDevIOCtl(hfd, (ULONG)0x76, (ULONG)0x64,
+ NULL, 0, NULL,
+ (ULONG*)&callgate[2], sizeof(USHORT), &dlen);
+ if (rc) {
+ xf86Msg(X_ERROR,
+ "EnableIOPorts failed, rc=%d, dlen=%d; emergency exit\n",
+ rc,dlen);
+ DosClose(hfd);
+ exit(42);
+ }
+
+/* Calling callgate with function 13 sets IOPL for the program */
+
+ asm volatile ("movl $13,%%ebx;.byte 0xff,0x1d;.long _callgate"
+ : /*no outputs */
+ : /*no inputs */
+ : "eax","ebx","ecx","edx","cc");
+
+ ioEnabled = TRUE;
+ DosClose(hfd);
+ return;
+}
+
+void xf86DisableIO()
+{
+HFILE hfd;
+ ULONG dlen;
+ APIRET rc;
+
+ /* no need to call multiple times */
+ if (!ioEnabled) return;
+
+ if (DosOpen((PSZ)ioDrvPath, (PHFILE)&hfd, (PULONG)&action,
+ (ULONG)0, FILE_SYSTEM, FILE_OPEN,
+ OPEN_SHARE_DENYNONE|OPEN_FLAGS_NOINHERIT|OPEN_ACCESS_READONLY,
+ (ULONG)0) != 0) {
+ xf86Msg(X_ERROR,"Error opening fastio$ driver...\n");
+ xf86Msg(X_ERROR,"Please install xf86sup.sys in config.sys!\n");
+ return;
+ }
+ callgate[0] = callgate[1] = 0;
+
+ rc = DosDevIOCtl(hfd, (ULONG)0x76, (ULONG)0x64,
+ NULL, 0, NULL,
+ (ULONG*)&callgate[2], sizeof(USHORT), &dlen);
+ if (rc) {
+ xf86Msg(X_ERROR,"DisableIOPorts failed, rc=%d, dlen=%d\n",
+ rc,dlen);
+ DosClose(hfd);
+ return;
+ }
+
+/* Function 14 of callgate brings program back to ring 3 */
+
+ asm volatile ("movl $14,%%ebx;.byte 0xff,0x1d;.long _callgate"
+ : /*no outputs */
+ : /*no inputs */
+ : "eax","ebx","ecx","edx","cc");
+ ioEnabled=FALSE;
+ DosClose(hfd);
+ return;
+
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_kbdEv.c b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_kbdEv.c
new file mode 100644
index 000000000..6b73c054e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_kbdEv.c
@@ -0,0 +1,506 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_kbdEv.c,v 3.15 1999/04/29 09:30:27 dawes Exp $ */
+/*
+ * (c) Copyright 1994,1996,1999 by Holger Veit
+ * <Holger.Veit@gmd.de>
+ * Modified 1996 Sebastien Marineau <marineau@genie.uottawa.ca>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Holger Veit shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Holger Veit.
+ *
+ */
+/* $XConsortium: os2_kbdEv.c /main/10 1996/10/27 11:48:48 kaleb $ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+
+#define I_NEED_OS2_H
+#define INCL_KBD
+#define INCL_DOSMONITORS
+#define INCL_WINSWITCHLIST
+#define INCL_DOSQUEUES
+#undef RT_FONT /* must discard this */
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "atKeynames.h"
+
+/* Attention! these lines copied from ../../common/xf86Events.c */
+#define XE_POINTER 1
+#define XE_KEYBOARD 2
+
+#ifdef XKB
+extern Bool noXkbExtension;
+#endif
+
+#ifdef XTESTEXT1
+
+#define XTestSERVER_SIDE
+#include "xtestext1.h"
+extern short xtest_mousex;
+extern short xtest_mousey;
+extern int on_steal_input;
+extern Bool XTestStealKeyData();
+extern void XTestStealMotionData();
+
+#ifdef XINPUT
+#define ENQUEUE(ev, code, direction, dev_type) \
+ (ev)->u.u.detail = (code); \
+ (ev)->u.u.type = (direction); \
+ if (!on_steal_input || \
+ XTestStealKeyData((ev)->u.u.detail, (ev)->u.u.type, dev_type, \
+ xtest_mousex, xtest_mousey)) \
+ xf86eqEnqueue((ev))
+#else
+#define ENQUEUE(ev, code, direction, dev_type) \
+ (ev)->u.u.detail = (code); \
+ (ev)->u.u.type = (direction); \
+ if (!on_steal_input || \
+ XTestStealKeyData((ev)->u.u.detail, (ev)->u.u.type, dev_type, \
+ xtest_mousex, xtest_mousey)) \
+ mieqEnqueue((ev))
+#endif
+
+#define MOVEPOINTER(dx, dy, time) \
+ if (on_steal_input) \
+ XTestStealMotionData(dx, dy, XE_POINTER, xtest_mousex, xtest_mousey); \
+ miPointerDeltaCursor (dx, dy, time)
+
+#else /* ! XTESTEXT1 */
+
+#ifdef XINPUT
+#define ENQUEUE(ev, code, direction, dev_type) \
+ (ev)->u.u.detail = (code); \
+ (ev)->u.u.type = (direction); \
+ xf86eqEnqueue((ev))
+#else
+#define ENQUEUE(ev, code, direction, dev_type) \
+ (ev)->u.u.detail = (code); \
+ (ev)->u.u.type = (direction); \
+ mieqEnqueue((ev))
+#endif
+#define MOVEPOINTER(dx, dy, time) \
+ miPointerDeltaCursor (dx, dy, time)
+
+#endif
+/* end of include */
+
+HQUEUE hKbdQueue;
+HEV hKbdSem;
+int last_status;
+int lastStatus;
+int lastShiftState;
+extern BOOL SwitchedToWPS;
+
+void os2PostKbdEvent();
+
+int os2KbdQueueQuery()
+{
+ ULONG numElements,postCount;
+
+ (void)DosQueryQueue(hKbdQueue,&numElements);
+ if (numElements!=0) return 0; /* We have something in queue */
+
+ DosResetEventSem(hKbdSem,&postCount);
+ return 1;
+}
+
+
+void xf86KbdEvents()
+{
+ KBDKEYINFO keybuf;
+ ULONG numElements;
+ REQUESTDATA requestData;
+ ULONG dataLength, postCount;
+ PVOID dummy;
+ BYTE elemPriority;
+ int scan, down;
+ static int last;
+ USHORT ModState;
+ int i;
+
+ while(DosReadQueue(hKbdQueue,
+ &requestData,&dataLength,&dummy,
+ 0L,1L,&elemPriority,hKbdSem) == 0) {
+
+ /* xf86Msg(X_INFO,
+ "Got queue element. data=%d, scancode =%d,up=%d, ddflag %d\n",
+ requestData.ulData,
+ (requestData.ulData&0x7F00)>>8,
+ requestData.ulData&0x8000,
+ requestData.ulData>>16);*/
+
+ scan=(requestData.ulData&0x7F00)>>8;
+
+ /* the separate cursor keys return 0xe0/scan */
+ if ((requestData.ulData & 0x3F0000)==0x20000) scan=0;
+ if (requestData.ulData & 0x800000) {
+ switch (scan) {
+
+/* BUG ALERT: IBM has in its keyboard driver a 122 key keyboard, which
+ * uses the "server generated scancodes" from atKeynames.h as real scan codes.
+ * We wait until some poor guy with such a keyboard will break the whole
+ * card house though...
+ */
+ case KEY_KP_7: scan = KEY_Home; break;
+ case KEY_KP_8: scan = KEY_Up; break;
+ case KEY_KP_9: scan = KEY_PgUp; break;
+ case KEY_KP_4: scan = KEY_Left; break;
+ case KEY_KP_5: scan = KEY_Begin; break;
+ case KEY_KP_6: scan = KEY_Right; break;
+ case KEY_KP_1: scan = KEY_End; break;
+ case KEY_KP_2: scan = KEY_Down; break;
+ case KEY_KP_3: scan = KEY_PgDown; break;
+ case KEY_KP_0: scan = KEY_Insert; break;
+ case KEY_KP_Decimal: scan = KEY_Delete; break;
+ case KEY_Enter: scan = KEY_KP_Enter; break;
+ case KEY_LCtrl: scan = KEY_RCtrl; break;
+ case KEY_KP_Multiply: scan = KEY_Print; break;
+ case KEY_Slash: scan = KEY_KP_Divide; break;
+ case KEY_Alt: scan = KEY_AltLang; break;
+ case KEY_ScrollLock: scan = KEY_Break; break;
+ case 0x5b: scan = KEY_LMeta; break;
+ case 0x5c: scan = KEY_RMeta; break;
+ case 0x5d: scan = KEY_Menu; break;
+ default:
+ /* virtual shifts: ignore */
+ scan = 0; break;
+ }
+ }
+
+ down = (requestData.ulData&0x8000) ? FALSE : TRUE;
+ if (scan!=0) os2PostKbdEvent(scan, down);
+ }
+ (void)DosResetEventSem(hKbdSem,&postCount);
+}
+
+/*
+ * xf86PostKbdEvent --
+ * Translate the raw hardware KbdEvent into an XEvent, and tell DIX
+ * about it. Scancode preprocessing and so on is done ...
+ *
+ * OS/2 specific xf86PostKbdEvent(key) has been moved from common/xf86Events.c
+ * as some things differ, and I didnït want to scatter this routine with
+ * ifdefs further (hv).
+ */
+
+void os2PostKbdEvent(unsigned scanCode, Bool down)
+{
+ KeyClassRec *keyc = ((DeviceIntPtr)xf86Info.pKeyboard)->key;
+ Bool updateLeds = FALSE;
+ Bool UsePrefix = FALSE;
+ Bool Direction = FALSE;
+ xEvent kevent;
+ KeySym *keysym;
+ int keycode;
+ static int lockkeys = 0;
+
+ /*
+ * and now get some special keysequences
+ */
+ if ((ModifierDown(ControlMask | AltMask)) ||
+ (ModifierDown(ControlMask | AltLangMask))) {
+ switch (scanCode) {
+ case KEY_BackSpace:
+ if (!xf86Info.dontZap) GiveUp(0);
+ return;
+ case KEY_KP_Minus: /* Keypad - */
+ if (!xf86Info.dontZoom) {
+ if (down)
+ xf86ZoomViewport(xf86Info.currentScreen, -1);
+ return;
+ }
+ break;
+ case KEY_KP_Plus: /* Keypad + */
+ if (!xf86Info.dontZoom) {
+ if (down)
+ xf86ZoomViewport(xf86Info.currentScreen, 1);
+ return;
+ }
+ break;
+ }
+ }
+
+ /* CTRL-ESC is std OS/2 hotkey for going back to PM and popping up
+ * window list... handled by keyboard driverand PM if you tell it. This is
+ * what we have done, and thus should never detect this key combo */
+ if (ModifierDown(ControlMask) && scanCode==KEY_Escape) {
+ /* eat it */
+ return;
+ } else if (ModifierDown(AltLangMask|AltMask) && scanCode==KEY_Escape) {
+ /* same here */
+ return;
+ }
+
+ /*
+ * Now map the scancodes to real X-keycodes ...
+ */
+ keycode = scanCode + MIN_KEYCODE;
+ keysym = (keyc->curKeySyms.map +
+ keyc->curKeySyms.mapWidth *
+ (keycode - keyc->curKeySyms.minKeyCode));
+#ifdef XKB
+ if (noXkbExtension) {
+#endif
+ /* Filter autorepeated caps/num/scroll lock keycodes. */
+
+#define CAPSFLAG 0x01
+#define NUMFLAG 0x02
+#define SCROLLFLAG 0x04
+#define MODEFLAG 0x08
+ if (down) {
+ switch (keysym[0]) {
+ case XK_Caps_Lock:
+ if (lockkeys & CAPSFLAG)
+ return;
+ else
+ lockkeys |= CAPSFLAG;
+ break;
+ case XK_Num_Lock:
+ if (lockkeys & NUMFLAG)
+ return;
+ else
+ lockkeys |= NUMFLAG;
+ break;
+ case XK_Scroll_Lock:
+ if (lockkeys & SCROLLFLAG)
+ return;
+ else
+ lockkeys |= SCROLLFLAG;
+ break;
+ }
+
+ if (keysym[1] == XF86XK_ModeLock) {
+ if (lockkeys & MODEFLAG)
+ return;
+ else
+ lockkeys |= MODEFLAG;
+ }
+ } else {
+ switch (keysym[0]) {
+ case XK_Caps_Lock:
+ lockkeys &= ~CAPSFLAG;
+ break;
+ case XK_Num_Lock:
+ lockkeys &= ~NUMFLAG;
+ break;
+ case XK_Scroll_Lock:
+ lockkeys &= ~SCROLLFLAG;
+ break;
+ }
+
+ if (keysym[1] == XF86XK_ModeLock)
+ lockkeys &= ~MODEFLAG;
+ }
+
+ /*
+ * LockKey special handling:
+ * ignore releases, toggle on & off on presses.
+ * Don't deal with the Caps_Lock keysym directly,
+ * but check the lock modifier
+ */
+#ifndef PC98
+ if (keyc->modifierMap[keycode] & LockMask ||
+ keysym[0] == XK_Scroll_Lock ||
+ keysym[1] == XF86XK_ModeLock ||
+ keysym[0] == XK_Num_Lock) {
+ Bool flag;
+
+ if (!down) return;
+ flag = !KeyPressed(keycode);
+ if (!flag) down = !down;
+
+ if (keyc->modifierMap[keycode] & LockMask)
+ xf86Info.capsLock = flag;
+ if (keysym[0] == XK_Num_Lock)
+ xf86Info.numLock = flag;
+ if (keysym[0] == XK_Scroll_Lock)
+ xf86Info.scrollLock = flag;
+ if (keysym[1] == XF86XK_ModeLock)
+ xf86Info.modeSwitchLock = flag;
+ updateLeds = TRUE;
+ }
+#endif /* not PC98 */
+
+ /* check for an autorepeat-event */
+ if ((down && KeyPressed(keycode)) &&
+ (xf86Info.autoRepeat != AutoRepeatModeOn || keyc->modifierMap[keycode]))
+ return;
+
+ /* normal, non-keypad keys */
+ if (scanCode < KEY_KP_7 || scanCode > KEY_KP_Decimal) {
+ /* magic ALT_L key on AT84 keyboards for multilingual support */
+ if (xf86Info.kbdType == KB_84 &&
+ ModifierDown(AltMask) &&
+ keysym[2] != NoSymbol) {
+ UsePrefix = TRUE;
+ Direction = TRUE;
+ }
+ }
+
+#ifdef XKB /* Warning: got position wrong first time */
+ }
+#endif
+ xf86Info.lastEventTime =
+ kevent.u.keyButtonPointer.time =
+ GetTimeInMillis();
+
+ /*
+ * And now send these prefixes ...
+ * NOTE: There cannot be multiple Mode_Switch keys !!!!
+ */
+ if (UsePrefix) {
+ ENQUEUE(&kevent,
+ keyc->modifierKeyMap[keyc->maxKeysPerModifier*7],
+ Direction ? KeyPress : KeyRelease,
+ XE_KEYBOARD);
+ ENQUEUE(&kevent,
+ keycode,
+ down ? KeyPress : KeyRelease,
+ XE_KEYBOARD);
+ ENQUEUE(&kevent,
+ keyc->modifierKeyMap[keyc->maxKeysPerModifier*7],
+ Direction ? KeyRelease : KeyPress,
+ XE_KEYBOARD);
+ } else {
+#ifdef XFreeDGA
+ if (((ScrnInfoPtr)(xf86Info.currentScreen->devPrivates[xf86ScreenIndex].ptr))->directMode&XF86DGADirectKeyb) {
+ XF86DirectVideoKeyEvent(&kevent,
+ keycode,
+ down ? KeyPress : KeyRelease);
+ } else
+#endif
+ {
+ ENQUEUE(&kevent,
+ keycode,
+ down ? KeyPress : KeyRelease,
+ XE_KEYBOARD);
+ }
+ }
+
+ if (updateLeds) xf86KbdLeds();
+}
+
+#pragma pack(1)
+struct KeyPacket {
+ unsigned short mnflags;
+ KBDKEYINFO cp;
+ unsigned short ddflags;
+};
+#pragma pack()
+
+/* The next function runs as a thread. It registers a monitor on the kbd
+ * driver, and uses that to get keystrokes. This is because the standard
+ * OS/2 keyboard driver does not send keyboard release events. A queue
+ * is used to communicate with the main thread to send keystrokes */
+
+void os2KbdMonitorThread(void* arg)
+{
+ struct KeyPacket packet;
+ APIRET rc;
+ USHORT length,print_flag;
+ ULONG queueParam;
+ HMONITOR hKbdMonitor;
+ MONIN monInbuf;
+ MONOUT monOutbuf;
+ char queueName[128];
+
+#if 0
+ monInbuf=(MONIN *)_tmalloc(2*sizeof(MONIN));
+ if (monInbuf==NULL) {
+ xf86Msg(X_ERROR,
+ "Could not allocate memory in kbd monitor thread!\n");
+ exit(1);
+ }
+ monOutbuf=(MONOUT *) &monInbuf[1];
+#endif
+
+ monInbuf.cb=sizeof(MONIN);
+ monOutbuf.cb=sizeof(MONOUT);
+
+ rc = DosMonOpen("KBD$",&hKbdMonitor);
+ xf86Msg(X_INFO,"Opened kbd monitor, rc=%d\n",rc);
+ rc = DosMonReg(hKbdMonitor,
+ (PBYTE)&monInbuf,(PBYTE)&monOutbuf,(USHORT)2,(USHORT)-1);
+ xf86Msg(X_INFO,"Kbd monitor registered, rc=%d\n",rc);
+ if (rc) {
+ DosMonClose(hKbdMonitor);
+ exit(1);
+ }
+
+ /* create a queue */
+ sprintf(queueName,"\\QUEUES\\XF86KBD\\%d",getpid());
+ rc = DosCreateQueue(&hKbdQueue,0L,queueName);
+ xf86Msg(X_INFO,"Kbd Queue created, rc=%d\n",rc);
+ (void)DosPurgeQueue(hKbdQueue);
+
+ while (1) {
+ length = sizeof(packet);
+ rc = DosMonRead((PBYTE)&monInbuf,0,(PBYTE)&packet,&length);
+ if (rc) {
+ xf86Msg(X_ERROR,
+ "DosMonRead returned bad RC! rc=%d\n",rc);
+ DosMonClose(hKbdMonitor);
+ exit(1);
+ }
+ queueParam = packet.mnflags+(packet.ddflags<<16);
+ if (packet.mnflags&0x7F00)
+ DosWriteQueue(hKbdQueue,queueParam,0L,NULL,0L);
+ /*xf86Msg(X_INFO,"Wrote a char to queue, rc=%d\n",rc); */
+ print_flag = packet.ddflags & 0x1F;
+
+ /*xf86Msg(X_INFO,"Kbd Monitor: Key press %d, scan code %d, ddflags %d\n",
+ packet.mnflags&0x8000,(packet.mnflags&0x7F00)>>8,packet.ddflags);
+ */
+
+ /* This line will swallow print-screen keypresses */
+ if (print_flag == 0x13 || print_flag == 0x14 ||
+ print_flag == 0x15 || print_flag == 0x16)
+ rc = 0;
+ else
+ rc = DosMonWrite((PBYTE)&monOutbuf,(PBYTE)&packet,length);
+ if (rc) {
+ xf86Msg(X_ERROR,
+ "DosMonWrite returned bad RC! rc=%d\n",rc);
+ DosMonClose(hKbdMonitor);
+ exit(1);
+ }
+ }
+
+ DosCloseQueue(hKbdQueue);
+ DosMonClose(hKbdMonitor);
+}
+
+void os2KbdBitBucketThread(void* arg)
+{
+ KBDKEYINFO key;
+ while (1) {
+ if (xf86Info.consoleFd != -1) {
+ KbdCharIn(&key,1,xf86Info.consoleFd);
+ usleep(100000);
+ } else
+ usleep(500000);
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_mouse.c b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_mouse.c
new file mode 100644
index 000000000..b24a46748
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_mouse.c
@@ -0,0 +1,300 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_mouse.c,v 3.15 1999/04/29 09:13:50 dawes Exp $ */
+/*
+ * (c) Copyright 1994,1999 by Holger Veit
+ * <Holger.Veit@gmd.de>
+ * Modified (c) 1996 Sebastien Marineau <marineau@genie.uottawa.ca>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Holger Veit shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Holger Veit.
+ *
+ */
+/* $XConsortium: os2_mouse.c /main/10 1996/10/27 11:48:51 kaleb $ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+
+#include "compiler.h"
+
+#define I_NEED_OS2_H
+#define INCL_DOSFILEMGR
+#define INCL_DOSQUEUES
+#define INCL_MOU
+#undef RT_FONT
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86Config.h"
+
+extern int miPointerGetMotionEvents(DeviceIntPtr pPtr, xTimecoord *coords,
+ unsigned long start, unsigned long stop,
+ ScreenPtr pScreen);
+
+HMOU hMouse=65535;
+HEV hMouseSem;
+HQUEUE hMouseQueue;
+int MouseTid;
+BOOL HandleValid=FALSE;
+extern BOOL SwitchedToWPS;
+extern CARD32 LastSwitchTime;
+void os2MouseEventThread();
+
+int xf86MouseOff(MouseDevPtr mouse, Bool doclose)
+{
+ return -1;
+}
+
+void xf86SetMouseSpeed(MouseDevPtr mouse, int old, int new, unsigned cflag)
+{
+ /* not required */
+}
+
+void xf86OsMouseOption(token, lex_ptr)
+int token;
+pointer lex_ptr;
+{
+ /* no options, anything seen ignored */
+}
+
+/* almost everything stolen from sco_mouse.c */
+int xf86OsMouseProc(DeviceIntPtr pPointer, int what)
+{
+ APIRET rc = 0;
+ USHORT nbutton, state;
+ unsigned char *map;
+ int i;
+ MouseDevPtr priv = (MouseDevPtr)((DeviceIntPtr)pPointer)->public.devicePrivate;
+
+ switch (what) {
+ case DEVICE_INIT:
+ pPointer->public.on = FALSE;
+ if (hMouse == 65535)
+ rc = MouOpen((PSZ)0, &hMouse);
+ if (rc != 0)
+ FatalError("Cannot open mouse, rc=%d\n", rc);
+ xf86Info.mouseDev->mseFd = -1;
+
+ /* flush mouse queue */
+ MouFlushQue(hMouse);
+
+ /* check buttons */
+ rc = MouGetNumButtons(&nbutton, hMouse);
+ if (rc == 0)
+ xf86Msg(X_INFO,
+ "OsMouse has %d button(s).\n",nbutton);
+ if (nbutton==2) nbutton++;
+ map = xalloc(nbutton + 1);
+ if (map == 0)
+ FatalError("Failed to allocate OsMouse map structure\n");
+
+ for (i = 1; i<=nbutton; i++)
+ map[i] = i;
+
+ InitPointerDeviceStruct((DevicePtr)pPointer, map, nbutton,
+ miPointerGetMotionEvents, (PtrCtrlProcPtr)xf86MseCtrl,
+ miPointerGetMotionBufferSize());
+
+ xfree(map);
+
+#ifdef XINPUT
+ InitValuatorAxisStruct(pPointer,
+ 0,
+ 0, /* min val */
+ screenInfo.screens[0]->width, /* max val */
+ 1, /* resolution */
+ 0, /* min_res */
+ 1); /* max_res */
+ InitValuatorAxisStruct(pPointer,
+ 1,
+ 0, /* min val */
+ screenInfo.screens[0]->height, /* max val */
+ 1, /* resolution */
+ 0, /* min_res */
+ 1); /* max_res */
+ /* Initialize valuator values in synch
+ * with dix/event.c DefineInitialRootWindow
+ */
+ *pPointer->valuator->axisVal = screenInfo.screens[0]->width / 2;
+ *(pPointer->valuator->axisVal+1) = screenInfo.screens[0]->height / 2;
+#endif
+
+ /* OK, we are ready to start up the mouse thread ! */
+ if (!HandleValid) {
+ rc = DosCreateEventSem(NULL,&hMouseSem,DC_SEM_SHARED,TRUE);
+ if (rc != 0)
+ FatalError("xf86OpenMouse: could not create mouse queue semaphore, rc=%d\n",rc);
+ MouseTid = _beginthread(os2MouseEventThread,NULL,0x4000,(void *)NULL);
+ xf86Msg(X_INFO,
+ "Started Mouse event thread, Tid=%d\n",MouseTid);
+ DosSetPriority(2,3,0,MouseTid);
+ }
+ HandleValid=TRUE;
+ break;
+
+ case DEVICE_ON:
+ /*AddEnabledDevice(xf86Info.mouseDev->mseFd);*/
+ if (!HandleValid) return -1;
+ xf86Info.mouseDev->lastButtons = 0;
+ xf86Info.mouseDev->emulateState = 0;
+ pPointer->public.on = TRUE;
+ state = 0x300;
+ rc = MouSetDevStatus(&state,hMouse);
+ state = 0x7f;
+ rc = MouSetEventMask(&state,hMouse);
+ MouFlushQue(hMouse);
+ break;
+
+ case DEVICE_CLOSE:
+ case DEVICE_OFF:
+ if (!HandleValid) return -1;
+ pPointer->public.on = FALSE;
+ state = 0x300;
+ MouSetDevStatus(&state,hMouse);
+ state = 0;
+ MouSetEventMask(&state,hMouse);
+ /*RemoveEnabledDevice(xf86Info.mouseDev->mseFd);*/
+ if (what == DEVICE_CLOSE) {
+/* Comment out for now as this seems to break server */
+#if 0
+ MouClose(hMouse);
+ hMouse = 65535;
+ xf86Info.mouseDev.mseFd = -1;
+ HandleValid = FALSE;
+#endif
+ }
+ break;
+ }
+ return Success;
+}
+
+void xf86OsMouseEvents()
+{
+ APIRET rc;
+ ULONG postCount,dataLength;
+ PVOID dummy;
+ int buttons;
+ int state;
+ int i, col, row;
+ BYTE elemPriority;
+ REQUESTDATA requestData;
+
+ if (!HandleValid) return;
+ while((rc = DosReadQueue(hMouseQueue,
+ &requestData,&dataLength,&dummy,
+ 0L,1L,&elemPriority,hMouseSem)) == 0) {
+ col = requestData.ulData;
+ (void)DosReadQueue(hMouseQueue,
+ &requestData,&dataLength,&dummy,
+ 0L,1L,&elemPriority,hMouseSem);
+ row = requestData.ulData;
+ (void)DosReadQueue(hMouseQueue,
+ &requestData,&dataLength,&dummy,
+ 0L,1L,&elemPriority,hMouseSem);
+ state = requestData.ulData;
+ (void)DosReadQueue(hMouseQueue,
+ &requestData,&dataLength,&dummy,
+ 0L,1L,&elemPriority,hMouseSem);
+ if (requestData.ulData != 0xFFFFFFFF)
+ xf86Msg(X_ERROR,
+ "Unexpected mouse event tag, %d\n",
+ requestData.ulData);
+
+ /* Contrary to other systems, OS/2 has mouse buttons *
+ * in the proper order, so we reverse them before *
+ * sending the event. */
+
+ buttons = ((state & 0x06) ? 4 : 0) |
+ ((state & 0x18) ? 1 : 0) |
+ ((state & 0x60) ? 2 : 0);
+ xf86PostMseEvent(xf86Info.pMouse, buttons, col, row);
+ }
+ DosResetEventSem(hMouseSem,&postCount);
+ xf86Info.inputPending = TRUE;
+}
+
+int os2MouseQueueQuery()
+{
+ /* Now we check for activity on mouse handles */
+ ULONG numElements,postCount;
+
+ if (!HandleValid) return(1);
+ DosResetEventSem(hMouseSem,&postCount);
+ (void)DosQueryQueue(hMouseQueue,&numElements);
+ if (numElements>0) { /* Something in mouse queue! */
+ return 0; /* Will this work? */
+ }
+ return 1;
+}
+
+void os2MouseEventThread(void *arg)
+{
+ APIRET rc;
+ MOUEVENTINFO mev;
+ ULONG queueParam;
+ USHORT waitflg;
+ char queueName[128];
+
+ sprintf(queueName,"\\QUEUES\\XF86MOU\\%d",getpid());
+ rc = DosCreateQueue(&hMouseQueue,0L,queueName);
+ xf86Msg(X_INFO,"Mouse Queue created, rc=%d\n",rc);
+ (void)DosPurgeQueue(hMouseQueue);
+
+ while(1) {
+ waitflg = 1;
+ rc = MouReadEventQue(&mev,&waitflg,hMouse);
+ if (rc) {
+ xf86Msg(X_ERROR,
+ "Bad return code from mouse driver, rc=%d\n",
+ rc);
+ xf86Msg(X_ERROR,"Mouse aborting!\n");
+ break;
+ }
+
+ /* Format of mouse packet is the following:
+ * first queued message is mev.col,
+ * second is mev.row,
+ * third is state and
+ * last is FFFFFFFF for "end-of-record".
+ * We could pack this better but it is a good start...
+ */
+
+ queueParam = mev.col;
+ rc = DosWriteQueue(hMouseQueue,queueParam,0L,NULL,0L);
+ if (rc) break;
+ queueParam = mev.row;
+ rc = DosWriteQueue(hMouseQueue,queueParam,0L,NULL,0L);
+ if (rc) break;
+ queueParam = mev.fs;
+ rc = DosWriteQueue(hMouseQueue,queueParam,0L,NULL,0L);
+ if (rc) break;
+ queueParam = 0xFFFFFFFF;
+ rc = DosWriteQueue(hMouseQueue,queueParam,0L,NULL,0L);
+ if (rc) break;
+ }
+ xf86Msg(X_ERROR,
+ "An unrecoverable error in mouse queue has occured, rc=%d. Mouse is shutting down.\n",
+ rc);
+ DosCloseQueue(hMouseQueue);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_select.c b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_select.c
new file mode 100644
index 000000000..74924c65e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_select.c
@@ -0,0 +1,503 @@
+/* $XConsortium: os2_select.c /main/6 1996/10/27 11:48:55 kaleb $ */
+
+
+
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_select.c,v 3.7 1999/04/29 09:13:50 dawes Exp $ */
+
+/*
+ * (c) Copyright 1996 by Sebastien Marineau
+ * <marineau@genie.uottawa.ca>
+ * Modified 1999 by Holger.Veit@gmd.de
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Sebastien Marineau shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Sebastien Marineau.
+ *
+ */
+
+/* os2_select.c: reimplementation of the xserver select(), optimized for speed */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <memory.h>
+#include <io.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/errno.h>
+#include <emx/io.h>
+
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSPROFILE
+#define INCL_DOSPROCESS
+#define INCL_DOSFILEMGR
+#define INCL_DOSMISC
+#define INCL_DOSMODULEMGR
+#include <os2.h>
+
+#include "os2_select.h"
+
+#include "Xpoll.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+int os2MouseQueueQuery();
+int os2KbdQueueQuery();
+void os2RecoverFromPopup();
+void os2CheckPopupPending();
+void os2HighResTimerThread();
+extern BOOL os2PopupErrorPending;
+
+extern HEV hKbdSem;
+extern HEV hMouseSem;
+extern HEV hevServerHasFocus;
+HEV hPipeSem;
+HEV hHRTSem;
+static HMUX hSelectWait;
+Bool os2HRTimerFlag=FALSE;
+SEMRECORD SelectMuxRecord[5];
+HMODULE hmod_so32dll;
+
+static int (*os2_tcp_select)(int *,int,int,int,long);
+int os2_set_error(ULONG);
+ULONG os2_get_sys_millis();
+extern int _files[];
+
+
+
+/* This is a new implementation of select, for improved efficiency */
+/* This function performs select() on sockets */
+/* but uses OS/2 internal fncts to check mouse */
+/* and keyboard. S. Marineau, 27/4/96 */
+
+/* This is still VERY messy */
+
+/* A few note on optimizations: this select has been tuned for maximum
+* performance, and thus has a different approach than a general-purpose
+* select. It should not be used in another app without modifications. Further,
+* it may need modifications if the Xserver os code is modified
+* Assumptions: this is never called with anything in exceptfds. This is
+* silently ignored. Further, if any pipes are specified in the write mask, it is
+* because they have just been stuffed full by the xserver. There is not much
+* in immediately returning with those bits set. Instead, we block on the
+* semaphore for at least one tick, which will let the client at least start
+* to flush the pipe. */
+
+int os2PseudoSelect(nfds,readfds,writefds,exceptfds,timeout)
+int nfds;
+fd_set *readfds,*writefds,*exceptfds;
+struct timeval *timeout;
+{
+
+static BOOL FirstTime=TRUE;
+
+int i,j,n,ns,np;
+int ready_handles;
+ULONG timeout_ms;
+BOOL any_ready;
+ULONG semKey,postCount,start_millis,now_millis;
+APIRET rc;
+char faildata[16];
+struct timeval dummy_timeout;
+struct select_data sd;
+static int HRT_Tid;
+
+sd.have_read=FALSE; sd.have_write=FALSE;
+sd.socket_nread=0; sd.socket_nwrite=0; sd.socket_ntotal=0;
+sd.max_fds=31; ready_handles=0; any_ready=FALSE;
+sd.pipe_ntotal=0; sd.pipe_have_write=FALSE;
+
+/* Stuff we have to do the first time this is called to set up various parameters */
+
+if(FirstTime){
+ /* First load the so32dll.dll module and get a pointer to the SELECT fn */
+
+ if((rc=DosLoadModule(faildata,sizeof(faildata),"SO32DLL",&hmod_so32dll))!=0){
+ FatalError("Could not load module so32dll.dll, rc = %d. Error note %s\n",rc,faildata);
+ }
+ if((rc = DosQueryProcAddr(hmod_so32dll, 0, "SELECT", (PPFN)&os2_tcp_select))!=0){
+ FatalError("Could not query address of SELECT, rc = %d.\n",rc);
+ }
+ /* Call these a first time to set the semaphore */
+ xf86OsMouseEvents();
+ xf86KbdEvents();
+
+ DosCreateEventSem(NULL, &hHRTSem,DC_SEM_SHARED,FALSE);
+ DosResetEventSem(hHRTSem,&postCount);
+ if (os2HRTimerFlag) {
+ HRT_Tid = _beginthread(os2HighResTimerThread, NULL, 0x2000,(void *) NULL);
+ xf86Msg(X_INFO,
+ "Started high-resolution timer thread, TID=%d\n",HRT_Tid);
+ }
+
+ SelectMuxRecord[0].hsemCur = (HSEM)hMouseSem;
+ SelectMuxRecord[0].ulUser = MOUSE_SEM_KEY;
+ SelectMuxRecord[1].hsemCur = (HSEM)hKbdSem;
+ SelectMuxRecord[1].ulUser = KBD_SEM_KEY;
+ SelectMuxRecord[2].hsemCur = (HSEM)hPipeSem;
+ SelectMuxRecord[2].ulUser = PIPE_SEM_KEY;
+ SelectMuxRecord[3].hsemCur = (HSEM)hHRTSem;
+ SelectMuxRecord[3].ulUser = HRT_SEM_KEY;
+ rc = DosCreateMuxWaitSem(NULL, &hSelectWait, 4, SelectMuxRecord,
+ DC_SEM_SHARED | DCMW_WAIT_ANY);
+ if(rc){
+ xf86Msg(X_ERROR,"Could not create MuxWait semaphore, rc=%d\n",rc);
+ }
+ FirstTime = FALSE;
+}
+
+/* Set up the time delay structs */
+
+ if(timeout!=NULL) {
+ timeout_ms=timeout->tv_sec*1000+timeout->tv_usec/1000;
+ }
+ else { timeout_ms=1000000; } /* This should be large enough... */
+ if(timeout_ms>0) start_millis=os2_get_sys_millis();
+
+/* Zero our local fd_masks */
+ {FD_ZERO(&sd.read_copy);}
+ {FD_ZERO(&sd.write_copy);}
+
+/* Copy the masks for later use */
+ if(readfds!=NULL){ XFD_COPYSET(readfds,&sd.read_copy); sd.have_read=TRUE;}
+ if(writefds!=NULL) {XFD_COPYSET(writefds,&sd.write_copy);sd.have_write=TRUE;}
+
+/* And zero the original masks */
+ if(sd.have_read){ FD_ZERO(readfds);}
+ if(sd.have_write) {FD_ZERO(writefds);}
+ if(exceptfds != NULL) {FD_ZERO(exceptfds);}
+
+/* Now we parse the fd_sets passed to select and separate pipe/sockets */
+ n = os2_parse_select(&sd,nfds);
+
+/* Now check if we have sockets ready! */
+
+ if (sd.socket_ntotal > 0){
+ ns = os2_poll_sockets(&sd,readfds,writefds);
+ if(ns>0){
+ ready_handles+=ns;
+ any_ready = TRUE;
+ }
+ else if (ns == -1) {return(-1);}
+ }
+
+/* And pipes */
+
+ if(sd.pipe_ntotal > 0){
+ np = os2_check_pipes(&sd,readfds,writefds);
+ if(np > 0){
+ ready_handles+=np;
+ any_ready = TRUE;
+ }
+ else if (np == -1) { return(-1); }
+ }
+
+/* ... */
+
+/* And finally poll input devices */
+ if(!os2MouseQueueQuery() || !os2KbdQueueQuery() ) any_ready = TRUE;
+
+ while(!any_ready && timeout_ms){
+ DosResetEventSem(hHRTSem,&postCount);
+ rc = DosWaitMuxWaitSem(hSelectWait, 5, &semKey);
+ if ((rc == 0) && (semKey != HRT_SEM_KEY) && (semKey != PIPE_SEM_KEY)){
+ any_ready = TRUE;
+ }
+ if (os2PopupErrorPending) {
+ os2RecoverFromPopup();
+ any_ready=TRUE;
+ }
+ if(xf86Info.vtRequestsPending) any_ready=TRUE;
+ if (sd.socket_ntotal > 0){
+ ns = os2_poll_sockets(&sd,readfds,writefds,exceptfds);
+ if(ns>0){
+ ready_handles+=ns;
+ any_ready = TRUE;
+ }
+ else if (ns == -1) {return(-1);}
+ }
+
+ rc = DosQueryEventSem(hPipeSem,&postCount);
+ if(postCount && (sd.pipe_ntotal > 0)){
+ np = os2_check_pipes(&sd,readfds,writefds);
+ if(np > 0){
+ ready_handles+=np;
+ any_ready = TRUE;
+ }
+ else if (np == -1) {
+ return(-1); }
+ }
+
+
+ if (i%8 == 0) {
+ now_millis = os2_get_sys_millis();
+ if((now_millis-start_millis) > timeout_ms) timeout_ms = 0;
+ }
+ i++;
+ }
+
+/* The polling of sockets/pipe automatically set the proper bits */
+
+return (ready_handles);
+}
+
+
+int os2_parse_select(sd,nfds)
+struct select_data *sd;
+int nfds;
+{
+ int i;
+/* First we determine up to which descriptor we need to check. */
+/* No need to check up to 256 if we don't have to (and usually we dont...)*/
+/* Note: stuff here is hardcoded for fd_sets which are int[8] as in EMX!!! */
+
+
+ if(nfds > sd->max_fds){
+ for(i=0;i<((FD_SETSIZE+31)/32);i++){
+ if(sd->read_copy.fds_bits[i] ||
+ sd->write_copy.fds_bits[i])
+ sd->max_fds=(i*32) +32;
+ }
+ }
+ else { sd->max_fds = nfds; }
+
+/* Check if this is greater than specified in select() call */
+ if(sd->max_fds > nfds) sd->max_fds = nfds;
+
+ if (sd->have_read)
+ {
+ for (i = 0; i < sd->max_fds; ++i) {
+ if (FD_ISSET (i, &sd->read_copy)){
+ if(_files[i] & F_SOCKET)
+ {
+ sd->tcp_select_mask[sd->socket_ntotal]=_getsockhandle(i);
+ sd->tcp_emx_handles[sd->socket_ntotal]=i;
+ sd->socket_ntotal++; sd->socket_nread++;
+ }
+ else if (_files[i] & F_PIPE)
+ {
+ sd -> pipe_ntotal++;
+ }
+ }
+ }
+ }
+
+ if (sd->have_write)
+ {
+ for (i = 0; i < sd->max_fds; ++i) {
+ if (FD_ISSET (i, &sd->write_copy)){
+ if(_files[i] & F_SOCKET)
+ {
+ sd->tcp_select_mask[sd->socket_ntotal]=_getsockhandle(i);
+ sd->tcp_emx_handles[sd->socket_ntotal]=i;
+ sd->socket_ntotal++; sd->socket_nwrite++;
+ }
+ else if (_files[i] & F_PIPE)
+ {
+ sd -> pipe_ntotal++;
+ sd -> pipe_have_write=TRUE;
+ }
+ }
+ }
+ }
+
+return(sd->socket_ntotal);
+}
+
+
+int os2_poll_sockets(sd,readfds,writefds)
+struct select_data *sd;
+fd_set *readfds,*writefds;
+{
+ int e,i;
+ int j,n;
+ memcpy(sd->tcp_select_copy,sd->tcp_select_mask,
+ sd->socket_ntotal*sizeof(int));
+
+ e = os2_tcp_select(sd->tcp_select_copy,sd->socket_nread,
+ sd->socket_nwrite, 0, 0);
+
+ if(e == 0) return(e);
+/* We have something ready? */
+ if(e>0){
+ j = 0; n = 0;
+ for (i = 0; i < sd->socket_nread; ++i, ++j)
+ if (sd->tcp_select_copy[j] != -1)
+ {
+ FD_SET (sd->tcp_emx_handles[j], readfds);
+ n ++;
+ }
+ for (i = 0; i < sd->socket_nwrite; ++i, ++j)
+ if (sd->tcp_select_copy[j] != -1)
+ {
+ FD_SET (sd->tcp_emx_handles[j], writefds);
+ n ++;
+ }
+ errno = 0;
+
+ return n;
+ }
+ if(e<0){
+ /*Error -- TODO */
+ xf86Msg(X_ERROR,"Error in server select! e=%d\n",e);
+ errno = EBADF;
+ return (-1);
+ }
+ }
+
+/* Check to see if anything is ready on pipes */
+
+int os2_check_pipes(sd,readfds,writefds)
+struct select_data *sd;
+fd_set *readfds,*writefds;
+{
+int i,e;
+ULONG ulPostCount;
+PIPESEMSTATE pipeSemState[128];
+APIRET rc;
+ e = 0;
+ rc = DosResetEventSem(hPipeSem,&ulPostCount);
+ rc = DosQueryNPipeSemState((HSEM) hPipeSem, (PPIPESEMSTATE)&pipeSemState,
+ sizeof(pipeSemState));
+ if(rc) xf86Msg(X_ERROR,"SELECT: rc from QueryNPipeSem: %d\n",rc);
+ i=0;
+ while (pipeSemState[i].fStatus != 0) {
+/* xf86Msg(X_INFO,"SELECT: sem entry, stat=%d, flag=%d, key=%d,avail=%d\n",
+ pipeSemState[i].fStatus,pipeSemState[i].fFlag,pipeSemState[i].usKey,
+ pipeSemState[i].usAvail); */
+ if((pipeSemState[i].fStatus == 1) &&
+ (FD_ISSET(pipeSemState[i].usKey,&sd->read_copy))){
+ FD_SET(pipeSemState[i].usKey,readfds);
+ e++;
+ }
+ else if((pipeSemState[i].fStatus == 2) &&
+ (FD_ISSET(pipeSemState[i].usKey,&sd->write_copy))){
+ FD_SET(pipeSemState[i].usKey,writefds);
+ e++;
+ }
+ else if( (pipeSemState[i].fStatus == 3) &&
+ ( (FD_ISSET(pipeSemState[i].usKey,&sd->read_copy)) ||
+ (FD_ISSET(pipeSemState[i].usKey,&sd->write_copy)) )){
+ errno = EBADF;
+ /* xf86Msg(X_ERROR,"Pipe has closed down, fd=%d\n",pipeSemState[i].usKey); */
+ return (-1);
+ }
+ i++;
+ } /* endwhile */
+
+errno = 0;
+return(e);
+}
+
+
+/* This thread runs with the high-res timer, timer0.sys */
+/* The semaphore hHRTSem gets posted every HRT_DELAY ms */
+/* Temptation may be strong to decrease this delay, but it already */
+/* consumes proportionally quite a bit of cpu and 12 ms seems quite good*/
+
+#define HRT_DELAY 12
+
+void os2HighResTimerThread(void* arg)
+{
+ HFILE hTimer;
+ ULONG ulDelay,ulAction,ulSize,ulPostCount;
+ APIRET rc;
+ char *fmt;
+
+ ulDelay = HRT_DELAY;
+ ulSize=sizeof(ulDelay);
+
+ rc = DosOpen("TIMER0$",&hTimer,&ulAction,
+ 0,0,OPEN_ACTION_OPEN_IF_EXISTS,
+ OPEN_FLAGS_FAIL_ON_ERROR | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,
+ NULL);
+ if (rc) {
+ fmt = "Open TIMER0.SYS failed, rc=%d. No High-resolution available\n";
+ goto errexit2;
+ }
+ hTimer = _imphandle(hTimer);
+ if (hTimer<0) {
+ fmt = "Could not import handle from TIMER0.SYS, rc=%d.\n";
+ goto errexit2;
+ }
+
+ /* Make the thread time critical */
+ DosSetPriority(2L,3L,0L,0L);
+ while (1) {
+ rc = DosDevIOCtl(hTimer,0x80,5,
+ &ulDelay,ulSize,&ulSize,
+ NULL,0,NULL);
+ if (rc != 0) {
+ fmt = "Bad return code from timer0.sys, rc=%d\n";
+ goto errexit1;
+ }
+
+ rc = DosQueryEventSem(hHRTSem,&ulPostCount);
+ if (rc != 0) {
+ fmt = "Bad return code from QueryEventSem, rc=%d\n";
+ goto errexit1;
+ }
+
+ if (ulPostCount == 0) rc = DosPostEventSem(hHRTSem);
+ if (rc != 0 && rc != 299) {
+ fmt = "Bad return code from PostEventSem, rc=%d\n";
+ goto errexit1;
+ }
+
+ rc = DosQueryEventSem(hevServerHasFocus,&ulPostCount);
+ if (rc != 0) {
+ fmt = "Bad return code from QueryEventSem for server focus, rc=%d\n";
+ goto errexit1;
+ }
+
+ /* Disable the HRT timer thread while switched away. */
+ if (ulPostCount == 0)
+ DosWaitEventSem(hevServerHasFocus, SEM_INDEFINITE_WAIT);
+
+ }
+
+ /* XXX reached? */
+ DosClose(hTimer);
+ return;
+
+ /* error catch blocks */
+errexit1:
+ DosClose(hTimer);
+errexit2:
+ xf86Msg(X_ERROR,fmt,rc);
+ DosExitList(0l,0l);
+}
+
+ULONG os2_get_sys_millis()
+{
+ APIRET rc;
+ ULONG milli;
+
+ rc = DosQuerySysInfo(14, 14, &milli, sizeof(milli));
+ if (rc) {
+ xf86Msg(X_ERROR,
+ "Bad return code querying the millisecond counter! rc=%d\n",
+ rc);
+ return 0;
+ }
+ return milli;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_select.h b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_select.h
new file mode 100644
index 000000000..f6a303eac
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_select.h
@@ -0,0 +1,60 @@
+/* $XConsortium: os2_select.h /main/1 1996/05/13 16:38:30 kaleb $ */
+/*
+ * (c) Copyright 1996 by Sebastien Marineau
+ * <marineau@genie.uottawa.ca>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Sebastien Marineau shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Sebastien Marineau.
+ *
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_select.h,v 3.1 1996/12/27 07:04:31 dawes Exp $ */
+
+/* Header file for os2_select.c */
+
+#define MAX_TCP 256
+
+#define MOUSE_SEM_KEY 0x0F01
+#define KBD_SEM_KEY 0x0F02
+#define PIPE_SEM_KEY 0x0F03
+#define HRT_SEM_KEY 0x0F04
+
+
+struct select_data
+{
+ fd_set read_copy;
+ fd_set write_copy;
+ BOOL have_read;
+ BOOL have_write;
+ int tcp_select_mask[MAX_TCP];
+ int tcp_emx_handles[MAX_TCP];
+ int tcp_select_copy[MAX_TCP];
+ int socket_nread;
+ int socket_nwrite;
+ int socket_ntotal;
+ int pipe_ntotal;
+ int pipe_have_write;
+ int max_fds;
+};
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_serial.c b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_serial.c
new file mode 100644
index 000000000..1c2d621bd
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_serial.c
@@ -0,0 +1,339 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_serial.c,v 1.1 1999/04/29 09:13:50 dawes Exp $ */
+/*
+ * (c) Copyright 1999 by Holger Veit
+ * <Holger.Veit@gmd.de>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Holger Veit shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Holger Veit.
+ *
+ */
+/* $XConsortium$ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "compiler.h"
+
+#define I_NEED_OS2_H
+#define INCL_DOSDEVIOCTL
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+static int _set_baudrate(HFILE fd,int baud)
+{
+ USHORT br = baud;
+ ULONG plen;
+ return DosDevIOCtl(fd,IOCTL_ASYNC,ASYNC_SETBAUDRATE,
+ (PULONG)&br,sizeof(br),&plen,NULL,0,NULL);
+}
+
+#pragma pack(1)
+typedef struct _glinectl {
+ UCHAR databits;
+ UCHAR parity;
+ UCHAR stopbits;
+ UCHAR sendbrk;
+} GLINECTL;
+typedef struct _slinectl {
+ UCHAR databits;
+ UCHAR parity;
+ UCHAR stopbits;
+} SLINECTL;
+
+#pragma pack()
+
+static int _get_linectrl(HFILE fd,GLINECTL* linectrl)
+{
+ ULONG dlen;
+ return DosDevIOCtl(fd,IOCTL_ASYNC,ASYNC_GETLINECTRL,
+ NULL,0,NULL,linectrl,sizeof(GLINECTL),&dlen);
+}
+
+static int _set_linectl(HFILE fd,GLINECTL* linectl)
+{
+ ULONG plen;
+ return DosDevIOCtl(fd,IOCTL_ASYNC,ASYNC_SETLINECTRL,
+ (PULONG)&linectl,sizeof(SLINECTL),&plen,NULL,0,NULL);
+}
+
+static int _get_dcb(HFILE fd,DCBINFO* dcb) {
+
+ ULONG dlen;
+ return DosDevIOCtl(fd,IOCTL_ASYNC,ASYNC_GETDCBINFO,
+ NULL,0,NULL,(PULONG)dcb,sizeof(DCBINFO),&dlen);
+}
+
+static int _set_dcb(HFILE fd,DCBINFO* dcb)
+{
+ ULONG plen;
+ return DosDevIOCtl(fd,IOCTL_ASYNC, ASYNC_SETDCBINFO,
+ (PULONG)dcb,sizeof(DCBINFO),&plen,NULL,0,NULL);
+}
+
+#pragma pack(1)
+typedef struct comsize {
+ USHORT nqueued;
+ USHORT qsize;
+} COMSIZE;
+#pragma pack()
+
+static int _get_nread(HFILE fd,ULONG* nread)
+{
+ ULONG dlen;
+ COMSIZE sz;
+ APIRET rc = DosDevIOCtl(fd,IOCTL_ASYNC,ASYNC_GETINQUECOUNT,
+ NULL, 0, NULL, sz,sizeof(COMSIZE),&dlen);
+ *nread = sz.nqueued;
+ return rc ? -1 : 0;
+}
+
+int xf86OpenSerial (pointer options)
+{
+ APIRET rc;
+ HFILE fd, i;
+ ULONG action;
+ GLINECTL linectl;
+
+ char* dev = xf86FindOptionValue (options, "Device");
+ xf86MarkOptionUsedByName (options, "Device");
+ if (!dev) {
+ xf86Msg (X_ERROR, "xf86OpenSerial: No Device specified.\n");
+ return -1;
+ }
+
+ rc = DosOpen(dev, &fd, &action, 0, FILE_NORMAL, FILE_OPEN,
+ OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE, NULL);
+ if (rc) {
+ xf86Msg (X_ERROR,
+ "xf86OpenSerial: Cannot open device %s, rc=%d.\n",
+ dev, rc);
+ return -1;
+ }
+
+ /* check whether it is an async device */
+ if (_get_linectrl(fd,&linectl)) {
+ xf86Msg (X_WARNING,
+ "xf86OpenSerial: Specified device %s is not a tty\n",
+ dev);
+ DosClose(fd);
+ return -1;
+ }
+
+ /* set up default port parameters */
+ _set_baudrate(fd, 9600);
+
+ linectl.databits = 8;
+ linectl.parity = 0;
+ linectl.stopbits = 0;
+ _set_linectl(fd, &linectl);
+
+ if (xf86SetSerial (fd, options) == -1) {
+ DosClose(fd);
+ return -1;
+ }
+
+ return fd;
+}
+
+int xf86SetSerial (int fd, pointer options)
+{
+ APIRET rc;
+ USHORT baud;
+ ULONG plen,dlen;
+ char *s;
+
+ GLINECTL linectl;
+ DCBINFO dcb;
+
+ if ((s = xf86FindOptionValue (options, "BaudRate"))) {
+ xf86MarkOptionUsedByName (options, "BaudRate");
+ if ((rc = _set_baudrate(fd, atoi(s)))) {
+ xf86Msg (X_ERROR,"Set Baudrate: %s, rc=%d\n", s, rc);
+ return -1;
+ }
+ }
+
+ /* get line parameters */
+ if (DosDevIOCtl((HFILE)fd,IOCTL_ASYNC, ASYNC_GETLINECTRL,
+ NULL,0,NULL,
+ (PULONG)&linectl,sizeof(GLINECTL),&dlen)) return -1;
+
+ if ((s = xf86FindOptionValue (options, "StopBits"))) {
+ xf86MarkOptionUsedByName (options, "StopBits");
+ switch (atoi (s)) {
+ case 1: linectl.stopbits = 0;
+ break;
+ case 2: linectl.stopbits = 2;
+ break;
+ default: xf86Msg (X_ERROR,
+ "Invalid Option StopBits value: %s\n", s);
+ return -1;
+ }
+ }
+
+ if ((s = xf86FindOptionValue (options, "DataBits"))) {
+ int db;
+ xf86MarkOptionUsedByName (options, "DataBits");
+ switch (db = atoi (s)) {
+ case 5: case 6: case 7: case 8:
+ linectl.databits = db;
+ break;
+ default: xf86Msg (X_ERROR,
+ "Invalid Option DataBits value: %s\n", s);
+ return -1;
+ }
+ }
+
+ if ((s = xf86FindOptionValue (options, "Parity"))) {
+ xf86MarkOptionUsedByName (options, "Parity");
+ if (xf86NameCmp (s, "Odd") == 0)
+ linectl.parity = 1; /* odd */
+ else if (xf86NameCmp (s, "Even") == 0)
+ linectl.parity = 2; /* even */
+ else if (xf86NameCmp (s, "None") == 0)
+ linectl.parity = 0; /* none */
+ else {
+ xf86Msg (X_ERROR,
+ "Invalid Option Parity value: %s\n", s);
+ return -1;
+ }
+ }
+
+ /* set line parameters */
+ if (_set_linectl(fd,&linectl)) return -1;
+
+ if (xf86FindOptionValue (options, "Vmin"))
+ xf86Msg (X_ERROR, "Vmin unsupported on this OS\n");
+
+ if (xf86FindOptionValue (options, "Vtime"))
+ xf86Msg (X_ERROR, "Vtime unsupported on this OS\n");
+
+ /* get device parameters */
+ if (_get_dcb(fd,&dcb)) return -1;
+
+ if ((s = xf86FindOptionValue (options, "FlowControl"))) {
+ xf86MarkOptionUsedByName (options, "FlowControl");
+ if (xf86NameCmp (s, "Xon") == 0)
+ dcb.fbFlowReplace |= 0x03;
+ else if (xf86NameCmp (s, "None") == 0)
+ dcb.fbFlowReplace &= ~0x03;
+ else {
+ xf86Msg (X_ERROR,
+ "Invalid Option FlowControl value: %s\n", s);
+ return -1;
+ }
+ }
+
+ if ((s = xf86FindOptionValue (options, "ClearDTR"))) {
+ dcb.fbCtlHndShake &= ~0x03; /* DTR=0 */
+ xf86MarkOptionUsedByName (options, "ClearDTR");
+ }
+
+ if ((s = xf86FindOptionValue (options, "ClearRTS"))) {
+ dcb.fbFlowReplace &= ~0xc0; /* RTS=0 */
+ xf86MarkOptionUsedByName (options, "ClearRTS");
+ }
+
+ /* set device parameters */
+ return _set_dcb(fd,&dcb) ? -1 : 0;
+}
+
+int xf86ReadSerial (int fd, void *buf, int count)
+{
+ ULONG nread,nq;
+ APIRET rc;
+
+ /* emulate non-blocking read */
+ if (_get_nread((HFILE)fd,&nq)) return -1;
+ if (nq==0) return 0;
+ if (nq < count) count = nq;
+
+ rc = DosRead((HFILE)fd,(PVOID)buf,(ULONG)count,&nread);
+ return rc ? -1 : (int)nread;
+}
+
+int xf86WriteSerial (int fd, void *buf, int count)
+{
+ ULONG nwrite;
+ APIRET rc = DosWrite((HFILE)fd,(PVOID)buf,(ULONG)count,&nwrite);
+ return rc ? -1 : (int)nwrite;
+}
+
+int xf86CloseSerial (int fd)
+{
+ APIRET rc = DosClose((HFILE)fd);
+ return rc ? -1 : 0;
+}
+
+int xf86WaitForInput (int fd, int timeout)
+{
+ APIRET rc;
+ ULONG dlen,nq;
+
+ do {
+ if (_get_nread((HFILE)fd,&nq)) return -1;
+ if (nq) return 1;
+
+ DosSleep(10);
+ timeout -= 10000; /* 10000 usec */
+ } while (timeout > 0);
+
+ return 0;
+}
+
+int xf86SerialSendBreak (int fd, int duration)
+{
+ USHORT data;
+ ULONG dlen;
+ APIRET rc;
+ rc = DosDevIOCtl((HFILE)fd,IOCTL_ASYNC,ASYNC_SETBREAKON,
+ NULL, 0, NULL,
+ &data, sizeof(data), &dlen);
+ if (rc)
+ return -1;
+ DosSleep(500);
+
+ rc = DosDevIOCtl((HFILE)fd,IOCTL_ASYNC,ASYNC_SETBREAKOFF,
+ NULL, 0, NULL,
+ &data, sizeof(data), &dlen);
+ return rc ? -1 : 0;
+}
+
+int xf86FlushInput(int fd)
+{
+ APIRET rc;
+ UCHAR buf;
+ ULONG nread,nq;
+
+ if (_get_nread((HFILE)fd,&nq)) return -1;
+
+ /* eat all chars in queue */
+ while (nq) {
+ rc = DosRead((HFILE)fd,&buf,1,&nread);
+ if (rc) return -1;
+ nq--;
+ }
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_stubs.c b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_stubs.c
new file mode 100644
index 000000000..c4a831824
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_stubs.c
@@ -0,0 +1,447 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_stubs.c,v 3.3 1996/12/27 07:04:32 dawes Exp $ */
+/*
+ * (c) Copyright 1996 by Holger Veit
+ * <Holger.Veit@gmd.de>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Holger Veit shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Holger Veit.
+ *
+ */
+/* $XConsortium: os2_stubs.c /main/3 1996/10/27 11:48:58 kaleb $ */
+
+#include "X11/X.h"
+#include "X11/Xpoll.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+/* This code is duplicated from XLibInt.c, because the same problems with
+ * the drive letter as in clients also exist in the server
+ * Unfortunately the standalone servers don't link against libX11
+ */
+
+char *__XOS2RedirRoot(char *fname)
+{
+ /* This adds a further redirection by allowing the ProjectRoot
+ * to be prepended by the content of the envvar X11ROOT.
+ * This is for the purpose to move the whole X11 stuff to a different
+ * disk drive.
+ * The feature was added despite various environment variables
+ * because not all file opens respect them.
+ */
+ static char redirname[300]; /* enough for long filenames */
+ char *root;
+
+ /* if name does not start with /, assume it is not root-based */
+ if (fname==0 || !(fname[0]=='/' || fname[0]=='\\'))
+ return fname;
+
+ root = (char*)getenv("X11ROOT");
+ if (root==0 ||
+ (fname[1]==':' && isalpha(fname[0]) ||
+ (strlen(fname)+strlen(root)+2) > 300))
+ return fname;
+ sprintf(redirname,"%s%s",root,fname);
+ return redirname;
+}
+
+char *__XOS2RedirRoot1(char *format, char *arg1, char *arg2, char *arg3)
+{
+ /* this first constructs a name from a format and up to three
+ * components, then adds a path
+ */
+ char buf[300];
+ sprintf(buf,format,arg1,arg2,arg3);
+ return __XOS2RedirRoot(buf);
+}
+
+/*
+ * This declares a missing function in the __EMX__ library, used in
+ * various places
+ */
+void usleep(delay)
+ unsigned long delay;
+{
+ DosSleep(delay ? (delay/1000) : 1l);
+}
+
+/* This is there to resolve a symbol in Xvfb
+ * this version is somewhat crippled compared to the one in os2_io.c
+ */
+#ifdef OS2NULLSELECT
+
+/* This below implements select() for calls in xnest. It has been */
+/* somewhat optimized for improved performance, but assumes a few */
+/* things so it cannot be used as a general select. */
+
+#include <sys/select.h>
+#include <sys/errno.h>
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSNPIPES
+#define INCL_DOSMISC
+#define INCL_DOSMODULEMGR
+#undef BOOL
+#undef BYTE
+#include <os2.h>
+
+HEV hPipeSem;
+HMODULE hmod_so32dll;
+static int (*os2_tcp_select)(int*,int,int,int,long);
+ULONG os2_get_sys_millis();
+extern int _files[];
+
+#define MAX_TCP 256
+/* These lifted from sys/emx.h. Change if that changes there! */
+#define F_SOCKET 0x10000000
+#define F_PIPE 0x20000000
+
+struct select_data
+{
+ fd_set read_copy;
+ fd_set write_copy;
+ BOOL have_read;
+ BOOL have_write;
+ int tcp_select_mask[MAX_TCP];
+ int tcp_emx_handles[MAX_TCP];
+ int tcp_select_copy[MAX_TCP];
+ int socket_nread;
+ int socket_nwrite;
+ int socket_ntotal;
+ int pipe_ntotal;
+ int pipe_have_write;
+ int max_fds;
+};
+
+int os2PseudoSelect(int nfds, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds, struct timeval *timeout)
+{
+static BOOL FirstTime=TRUE;
+static haveTCPIP=TRUE;
+ULONG timeout_ms;
+ULONG postCount, start_millis,now_millis;
+char faildata[16];
+struct select_data sd;
+BOOL any_ready;
+int np,ns, i,ready_handles,n;
+APIRET rc;
+
+sd.have_read=FALSE; sd.have_write=FALSE;
+sd.socket_nread=0; sd.socket_nwrite=0; sd.socket_ntotal=0;
+sd.max_fds=31; ready_handles=0; any_ready=FALSE;
+sd.pipe_ntotal=0; sd.pipe_have_write=FALSE;
+
+if(FirstTime){
+ /* First load the so32dll.dll module and get a pointer to the SELECT function */
+
+ if((rc=DosLoadModule(faildata,sizeof(faildata),"SO32DLL",&hmod_so32dll))!=0){
+ fprintf(stderr, "Could not load module so32dll.dll, rc = %d. Error note %s\n",rc,faildata);
+ haveTCPIP=FALSE;
+ }
+ if((rc = DosQueryProcAddr(hmod_so32dll, 0, "SELECT", (PPFN)&os2_tcp_select))!=0){
+ fprintf(stderr, "Could not query address of SELECT, rc = %d.\n",rc);
+ haveTCPIP=FALSE;
+ }
+ /* Call these a first time to set the semaphore */
+ /* rc = DosCreateEventSem(NULL, &hPipeSem, DC_SEM_SHARED, FALSE);
+ if(rc) {
+ fprintf(stderr, "Could not create event semaphore, rc=%d\n",rc);
+ return(-1);
+ }
+ rc = DosResetEventSem(hPipeSem, &postCount); */ /* Done in xtrans code for servers*/
+
+fprintf(stderr, "Client select() done first-time stuff, sem handle %d.\n",hPipeSem);
+
+ FirstTime = FALSE;
+}
+
+/* Set up the time delay structs */
+
+ if(timeout!=NULL) {
+ timeout_ms=timeout->tv_sec*1000+timeout->tv_usec/1000;
+ }
+ else { timeout_ms=1000000; } /* This should be large enough... */
+ if(timeout_ms>0) start_millis=os2_get_sys_millis();
+
+/* Copy the masks */
+ {FD_ZERO(&sd.read_copy);}
+ {FD_ZERO(&sd.write_copy);}
+ if(readfds!=NULL){ XFD_COPYSET(readfds,&sd.read_copy); sd.have_read=TRUE;}
+ if(writefds!=NULL) {XFD_COPYSET(writefds,&sd.write_copy);sd.have_write=TRUE;}
+
+/* And zero the original masks */
+ if(sd.have_read){ FD_ZERO(readfds);}
+ if(sd.have_write) {FD_ZERO(writefds);}
+ if(exceptfds != NULL) {FD_ZERO(exceptfds);}
+
+/* Now we parse the fd_sets passed to select and separate pipe/sockets */
+ n = os2_parse_select(&sd,nfds);
+ if(n == -1) {
+ errno = EBADF;
+ return (-1);
+ }
+
+/* Now we have three cases: either we have sockets, pipes, or both */
+/* We handle all three cases differently to optimize things */
+
+/* Case 1: only pipes! */
+ if((sd.pipe_ntotal >0) && (!sd.socket_ntotal)){
+ np = os2_check_pipes(&sd,readfds,writefds);
+ if(np > 0){
+ return (np);
+ }
+ else if (np == -1) { return(-1); }
+ while(!any_ready){
+ rc = DosWaitEventSem(hPipeSem, timeout_ms);
+ /* if(rc) fprintf(stderr,"Sem-wait timeout, rc = %d\n",rc); */
+ if(rc == 640) {
+ return(0);
+ }
+ if((rc != 0) && (rc != 95)) {errno= EBADF; return(-1);}
+ np = os2_check_pipes(&sd,readfds,writefds);
+ if (np > 0){
+ return(np);
+ }
+ else if (np < 0){ return(-1); }
+ }
+ }
+
+/* Case 2: only sockets. Just let the os/2 tcp select do the work */
+ if((sd.socket_ntotal > 0) && (!sd.pipe_ntotal)){
+ ns = os2_check_sockets(&sd, readfds, writefds, timeout_ms);
+ return (ns);
+ }
+
+/* Case 3: combination of both */
+ if((sd.socket_ntotal > 0) && (sd.pipe_ntotal)){
+ np = os2_check_pipes(&sd,readfds,writefds);
+ if(np > 0){
+ any_ready=TRUE;
+ ready_handles += np;
+ }
+ else if (np == -1) { return(-1); }
+
+ ns = os2_check_sockets(&sd,readfds,writefds, 0);
+ if(ns>0){
+ ready_handles+=ns;
+ any_ready = TRUE;
+ }
+ else if (ns == -1) {return(-1);}
+
+ while (!any_ready && timeout_ms){
+
+ rc = DosWaitEventSem(hPipeSem, 10L);
+ if(rc == 0){
+ np = os2_check_pipes(&sd,readfds,writefds);
+ if(np > 0){
+ ready_handles+=np;
+ any_ready = TRUE;
+ }
+ else if (np == -1) {
+ return(-1); }
+ }
+
+ ns = os2_check_sockets(&sd,readfds,writefds,exceptfds, 0);
+ if(ns>0){
+ ready_handles+=ns;
+ any_ready = TRUE;
+ }
+ else if (ns == -1) {return(-1);}
+
+ if (i%8 == 0) {
+ now_millis = os2_get_sys_millis();
+ if((now_millis-start_millis) > timeout_ms) timeout_ms = 0;
+ }
+ i++;
+ }
+ }
+
+return(ready_handles);
+}
+
+
+ULONG os2_get_sys_millis()
+{
+ APIRET rc;
+ ULONG milli;
+
+ rc = DosQuerySysInfo(14, 14, &milli, sizeof(milli));
+ if(rc) {
+ fprintf(stderr,"Bad return code querying the millisecond counter! rc=%d\n",rc);
+ return(0);
+ }
+ return(milli);
+}
+
+int os2_parse_select(sd,nfds)
+struct select_data *sd;
+int nfds;
+{
+ int i;
+ APIRET rc;
+/* First we determine up to which descriptor we need to check. */
+/* No need to check up to 256 if we don't have to (and usually we dont...)*/
+/* Note: stuff here is hardcoded for fd_sets which are int[8] as in EMX! */
+
+ if(nfds > sd->max_fds){
+ for(i=0;i<((FD_SETSIZE+31)/32);i++){
+ if(sd->read_copy.fds_bits[i] ||
+ sd->write_copy.fds_bits[i])
+ sd->max_fds=(i*32) +32;
+ }
+ }
+ else { sd->max_fds = nfds; }
+/* Check if result is greater than specified in select() call */
+ if(sd->max_fds > nfds) sd->max_fds = nfds;
+
+ if (sd->have_read)
+ {
+ for (i = 0; i < sd->max_fds; ++i) {
+ if (FD_ISSET (i, &sd->read_copy)){
+ if(_files[i] & F_SOCKET)
+ {
+ sd->tcp_select_mask[sd->socket_ntotal]=_getsockhandle(i);
+ sd->tcp_emx_handles[sd->socket_ntotal]=i;
+ sd->socket_ntotal++; sd->socket_nread++;
+ }
+ else if (_files[i] & F_PIPE)
+ {
+ sd -> pipe_ntotal++;
+ /* rc = DosSetNPipeSem((HPIPE)i, (HSEM) hPipeSem, i);
+ if(rc) { fprintf(stderr,"Error SETNPIPE rc = %d\n",rc); return -1;} */
+ }
+ }
+ }
+ }
+
+ if (sd->have_write)
+ {
+ for (i = 0; i < sd->max_fds; ++i) {
+ if (FD_ISSET (i, &sd->write_copy)){
+ if(_files[i] & F_SOCKET)
+ {
+ sd->tcp_select_mask[sd->socket_ntotal]=_getsockhandle(i);
+ sd->tcp_emx_handles[sd->socket_ntotal]=i;
+ sd->socket_ntotal++; sd->socket_nwrite++;
+ }
+ else if (_files[i] & F_PIPE)
+ {
+ sd -> pipe_ntotal++;
+ /* rc = DosSetNPipeSem((HPIPE)i, (HSEM) hPipeSem, i);
+ if(rc) { fprintf(stderr,"Error SETNPIPE rc = %d\n",rc); return -1;} */
+ sd -> pipe_have_write=TRUE;
+ }
+ }
+ }
+ }
+
+
+return(sd->socket_ntotal);
+}
+
+
+int os2_check_sockets(sd,readfds,writefds)
+struct select_data *sd;
+fd_set *readfds,*writefds;
+{
+ int e,i;
+ int j,n;
+ memcpy(sd->tcp_select_copy,sd->tcp_select_mask,
+ sd->socket_ntotal*sizeof(int));
+
+ e = os2_tcp_select(sd->tcp_select_copy,sd->socket_nread,
+ sd->socket_nwrite, 0, 0);
+
+ if(e == 0) return(e);
+/* We have something ready? */
+ if(e>0){
+ j = 0; n = 0;
+ for (i = 0; i < sd->socket_nread; ++i, ++j)
+ if (sd->tcp_select_copy[j] != -1)
+ {
+ FD_SET (sd->tcp_emx_handles[j], readfds);
+ n ++;
+ }
+ for (i = 0; i < sd->socket_nwrite; ++i, ++j)
+ if (sd->tcp_select_copy[j] != -1)
+ {
+ FD_SET (sd->tcp_emx_handles[j], writefds);
+ n ++;
+ }
+ errno = 0;
+
+ return n;
+ }
+ if(e<0){
+ /*Error -- TODO. EBADF is a good choice for now. */
+ fprintf(stderr,"Error in server select! e=%d\n",e);
+ errno = EBADF;
+ return (-1);
+ }
+ }
+
+/* Check to see if anything is ready on pipes */
+
+int os2_check_pipes(sd,readfds,writefds)
+struct select_data *sd;
+fd_set *readfds,*writefds;
+{
+int i,e;
+ULONG ulPostCount;
+PIPESEMSTATE pipeSemState[128];
+APIRET rc;
+ e = 0;
+ rc = DosResetEventSem(hPipeSem,&ulPostCount);
+ rc = DosQueryNPipeSemState((HSEM) hPipeSem, (PPIPESEMSTATE)&pipeSemState,
+ sizeof(pipeSemState));
+ if(rc) fprintf(stderr,"SELECT: rc from QueryNPipeSem: %d\n",rc);
+ i=0;
+ while (pipeSemState[i].fStatus != 0) {
+ /*fprintf(stderr,"SELECT: sem entry, stat=%d, flag=%d, key=%d,avail=%d\n",
+ pipeSemState[i].fStatus,pipeSemState[i].fFlag,pipeSemState[i].usKey,
+ pipeSemState[i].usAvail); */
+ if((pipeSemState[i].fStatus == 1) &&
+ (FD_ISSET(pipeSemState[i].usKey,&sd->read_copy))){
+ FD_SET(pipeSemState[i].usKey,readfds);
+ e++;
+ }
+ else if((pipeSemState[i].fStatus == 2) &&
+ (FD_ISSET(pipeSemState[i].usKey,&sd->write_copy))){
+ FD_SET(pipeSemState[i].usKey,writefds);
+ e++;
+ }
+ else if( (pipeSemState[i].fStatus == 3) &&
+ ( (FD_ISSET(pipeSemState[i].usKey,&sd->read_copy)) ||
+ (FD_ISSET(pipeSemState[i].usKey,&sd->write_copy)) )){
+ errno = EBADF;
+ /* fprintf(stderr,"Pipe has closed down, fd=%d\n",pipeSemState[i].usKey); */
+ return (-1);
+ }
+ i++;
+ } /* endwhile */
+ /*fprintf(stderr,"Done listing pipe sem entries, total %d entries, total ready entries %d\n",i,e);*/
+errno = 0;
+return(e);
+}
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_video.c b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_video.c
new file mode 100644
index 000000000..bed44c3c0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/os2/os2_video.c
@@ -0,0 +1,226 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_video.c,v 3.12 1999/04/29 09:13:51 dawes Exp $ */
+/*
+ * (c) Copyright 1994,1999 by Holger Veit
+ * <Holger.Veit@gmd.de>
+ * Modified 1996 by Sebastien Marineau <marineau@genie.uottawa.ca>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Holger Veit shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Holger Veit.
+ *
+ */
+/* $XConsortium: os2_video.c /main/8 1996/10/27 11:49:02 kaleb $ */
+
+#include "X.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#define I_NEED_OS2_H
+#define INCL_DOSFILEMGR
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86OSpriv.h"
+
+#include "compiler.h"
+
+/***************************************************************************/
+/* Video Memory Mapping helper functions */
+/***************************************************************************/
+
+/* This section uses the xf86sup.sys driver developed for xfree86.
+ * The driver allows mapping of physical memory
+ * You must install it with a line DEVICE=path\xf86sup.sys in config.sys.
+ */
+
+static HFILE mapdev = -1;
+static ULONG stored_virt_addr;
+static char* mappath = "\\DEV\\PMAP$";
+static HFILE open_mmap()
+{
+ APIRET rc;
+ ULONG action;
+
+ if (mapdev != -1)
+ return mapdev;
+
+ rc = DosOpen((PSZ)mappath, (PHFILE)&mapdev, (PULONG)&action,
+ (ULONG)0, FILE_SYSTEM, FILE_OPEN,
+ OPEN_SHARE_DENYNONE|OPEN_FLAGS_NOINHERIT|OPEN_ACCESS_READONLY,
+ (ULONG)0);
+ if (rc!=0)
+ mapdev = -1;
+ return mapdev;
+}
+
+static void close_mmap()
+{
+ if (mapdev != -1)
+ DosClose(mapdev);
+ mapdev = -1;
+}
+
+/* this structure is used as a parameter packet for the direct access
+ * ioctl of pmap$
+ */
+
+/* Changed here for structure of driver PMAP$ */
+
+typedef struct{
+ ULONG addr;
+ ULONG size;
+} DIOParPkt;
+
+/* This is the data packet for the mapping function */
+
+typedef struct {
+ ULONG addr;
+ USHORT sel;
+} DIODtaPkt;
+
+/***************************************************************************/
+/* Video Memory Mapping section */
+/***************************************************************************/
+
+/* ARGSUSED */
+static pointer
+mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size)
+{
+ DIOParPkt par;
+ ULONG plen;
+ DIODtaPkt dta;
+ ULONG dlen;
+ static BOOL ErrRedir = FALSE;
+ APIRET rc;
+
+ par.addr = (ULONG)Base;
+ par.size = (ULONG)Size;
+ plen = sizeof(par);
+ dlen = sizeof(dta);
+
+ /* First, redirect stderr to file so that video calls do not block */
+ if (!ErrRedir) {
+ /* hv300996 create redirect file on boot drive, instead
+ * anywhere you are just standing
+ */
+ char buf[20],dr[3];
+ ULONG drive;
+ APIRET rc = DosQuerySysInfo(5,5,&drive,sizeof(drive));
+ if (rc) dr[0] = 0;
+ else { dr[0] = drive+96;
+ dr[1] = ':';
+ dr[2] = 0;
+ }
+ sprintf(buf,"%s\\xf86log.os2",dr);
+ freopen(buf,"w",stderr);
+ ErrRedir=TRUE;
+ }
+
+ open_mmap();
+ if (mapdev == -1)
+ FatalError("xf86MapVidMem: install DEVICE=path\\XF86SUP.SYS!");
+
+ if ((rc=DosDevIOCtl(mapdev, (ULONG)0x76, (ULONG)0x44,
+ (PVOID)&par, (ULONG)plen, (PULONG)&plen,
+ (PVOID)&dta, (ULONG)dlen, (PULONG)&dlen)) == 0) {
+ xf86Msg(X_INFO, xf86MapVidMem succeeded: (ScreenNum= %d, Base= 0x%x, Size= 0x%x\n",
+ ScreenNum, Base, Size);
+ if (dlen==sizeof(dta)) {
+ return (pointer)dta.addr;
+ }
+ /*else fail*/
+ }
+
+ /* fail */
+ FatalError("xf86MapVidMem FAILED!!: rc = %d (ScreenNum= %d, Base= 0x%x, Size= 0x%x return len %d\n",
+ rc, ScreenNum, Base, Size,dlen);
+ return (pointer)0;
+}
+
+/* ARGSUSED */
+static void
+unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+{
+ DIOParPkt par;
+ ULONG plen,vmaddr;
+
+/* We need here the VIRTADDR for unmapping, not the physical address */
+/* This should be taken care of either here by keeping track of allocated */
+/* pointers, but this is also already done in the driver... Thus it would */
+/* be a waste to do this tracking twice. Can this be changed when the fn. */
+/* is called? This would require tracking this function in all servers, */
+/* and changing it appropriately to call this with the virtual adress */
+/* If the above mapping function is only called once, then we can store */
+/* the virtual adress and use it here.... */
+
+ par.addr = (ULONG)Base;
+ par.size = 0xffffffff; /* This is the virtual address parameter. Set this to ignore */
+ plen = sizeof(par);
+
+ if (mapdev != -1)
+ DosDevIOCtl(mapdev, (ULONG)0x76, (ULONG)0x46,
+ (PVOID)&par, (ULONG)plen, (PULONG)&plen,
+ &vmaddr, sizeof(ULONG), &plen);
+ xf86Msg(X_INFO,"Unmapping physical memory at base %x, virtual address %x\n",Base,vmaddr);
+
+/* Now if more than one region has been allocated and we close the driver,
+ * the other pointers will immediately become invalid. We avoid closing
+ * driver for now, but this should be fixed for server exit
+ */
+
+ /* close_mmap(); */
+}
+
+/***************************************************************************/
+/* Interrupt Handling section */
+/***************************************************************************/
+
+Bool xf86DisableInterrupts()
+{
+ /* allow interrupt disabling but check for side-effects.
+ * Not a good policy on OS/2...
+ */
+ asm ("cli");
+ return TRUE;
+}
+
+void xf86EnableInterrupts()
+{
+ /*Reenable*/
+ asm ("sti");
+}
+
+/***************************************************************************/
+/* Initialize video memory */
+/***************************************************************************/
+
+void
+xf86OSInitVidMem(VidMemInfoPtr pVidMem)
+{
+ pVidMem->linearSupported = TRUE;
+ pVidMem->mapMem = mapVidMem;
+ pVidMem->unmapMem = unmapVidMem;
+ pVidMem->mapMemSparse = 0;
+ pVidMem->unmapMemSparse = 0;
+ pVidMem->setWC = 0;
+ pVidMem->undoWC = 0;
+ pVidMem->initialised = TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/pmax/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/pmax/Imakefile
new file mode 100644
index 000000000..f165a1397
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/pmax/Imakefile
@@ -0,0 +1,49 @@
+
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/pmax/Imakefile,v 1.4 1999/05/22 08:40:15 dawes Exp $
+
+#include <Server.tmpl>
+
+#if NewInput
+MOUSESRC = bsd_mouse.c
+MOUSEOBJ = bsd_mouse.o
+#else
+MOUSESRC = std_mouse.c std_mseEv.c
+MOUSEOBJ = std_mouse.o std_mseEv.o
+#endif
+
+SRCS = pmax_devs.c pmax_init.c pmax_map.c pmax_pci.c pmax_ppc.c \
+ bios_V4mmap.c VTsw_usl.c sysv_kbd.c std_kbdEv.c \
+ posix_tty.c $(MOUSESRC) xqueue.c ioperm_noop.c \
+ libc_wrapper.c stdResource.c
+
+OBJS = pmax_devs.o pmax_init.o pmax_map.o pmax_pci.o pmax_ppc.o \
+ bios_V4mmap.o VTsw_usl.o sysv_kbd.o std_kbdEv.o \
+ posix_tty.o $(MOUSESRC) xqueue.o ioperm_noop.o \
+ libc_wrapper.o stdResource.o
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(XF86OSSRC)/bus -I. \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(EXTINCSRC) -I../sysv
+
+RESDEFINES = -DUSESTDRES
+
+DEFINES = $(RESDEFINES)
+
+SubdirLibraryRule($(OBJS))
+NormalLibraryObjectRule()
+
+LinkSourceFile(VTsw_usl.c,../shared)
+LinkSourceFile(ioperm_noop.c,../shared)
+LinkSourceFile(sysv_kbd.c,../shared)
+LinkSourceFile(std_kbdEv.c,../shared)
+LinkSourceFile(posix_tty.c,../shared)
+#if !NewInput
+LinkSourceFile(std_mouse.c,../shared)
+LinkSourceFile(std_mseEv.c,../shared)
+#endif
+LinkSourceFile(libc_wrapper.c,../shared)
+LinkSourceFile(stdResource.c,../shared)
+
+LinkSourceFile(bios_V4mmap.c,../sysv)
+LinkSourceFile(xqueue.c,../sysv)
+
+DependTarget()
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_devs.c b/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_devs.c
new file mode 100644
index 000000000..927c38831
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_devs.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright 1998 by Concurrent Computer Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Concurrent Computer
+ * Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Concurrent Computer Corporation makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Copyright 1998 by Metro Link Incorporated
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Metro Link
+ * Incorporated not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Metro Link Incorporated makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * This module was derived in part from the original XFree86
+ * sysv/sysv_io.c which contains the following copyright notice:
+ *
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Thomas Roell and David Dawes
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Thomas Roell and
+ * David Dawes makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THOMAS ROELL AND DAVID DAWES DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID DAWES BE LIABLE FOR
+ * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_devs.c,v 1.5 1999/05/22 08:40:15 dawes Exp $ */
+
+#include "X.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+void
+xf86SoundKbdBell(int loudness, int pitch, int duration)
+{
+ if (loudness && pitch)
+ {
+#ifdef KDMKTONE
+ /*
+ * If we have KDMKTONE use it to avoid putting the server
+ * to sleep
+ */
+ ioctl(xf86Info.consoleFd, KDMKTONE,
+ ((1193190 / pitch) & 0xffff) |
+ (((unsigned long)duration *
+ loudness / 50) << 16));
+#else
+ ioctl(xf86Info.consoleFd, KIOCSOUND, 1193180 / pitch);
+ usleep(xf86Info.bell_duration * loudness * 20);
+ ioctl(xf86Info.consoleFd, KIOCSOUND, 0);
+#endif
+ }
+}
+
+void
+xf86SetKbdLeds(int leds)
+{
+#if 0 /* used to be KBIO_SETMODE */
+ ioctl(xf86Info.consoleFd, KBIO_SETMODE, KBM_AT);
+ ioctl(xf86Info.consoleFd, KDSETLED, leds);
+ ioctl(xf86Info.consoleFd, KBIO_SETMODE, KBM_XT);
+#endif
+
+ ioctl(xf86Info.consoleFd, KDSETLED, leds);
+}
+
+#ifndef NEW_INPUT
+void
+xf86MouseInit(MouseDevPtr mouse)
+{
+ return;
+}
+
+int
+xf86MouseOn(MouseDevPtr mouse)
+{
+ if ((mouse->mseFd = open(mouse->mseDevice, O_RDWR | O_NDELAY)) < 0)
+ {
+ if (xf86Info.allowMouseOpenFail) {
+ xf86Msg(X_WARNING,
+ "Cannot open mouse (%s) - Continuing...\n",
+ strerror(errno));
+ return(-2);
+ }
+ FatalError("Cannot open mouse (%s)\n", strerror(errno));
+ }
+
+ xf86SetupMouse(mouse);
+
+ /* Flush any pending input */
+ ioctl(mouse->mseFd, TCFLSH, 0);
+
+ return(mouse->mseFd);
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_init.c b/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_init.c
new file mode 100644
index 000000000..d0db8f90e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_init.c
@@ -0,0 +1,469 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_init.c,v 1.3 1998/07/25 16:56:55 dawes Exp $ */
+/*
+ * Copyright 1998 by Concurrent Computer Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Concurrent Computer
+ * Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Concurrent Computer Corporation makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Copyright 1998 by Metro Link Incorporated
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Metro Link
+ * Incorporated not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Metro Link Incorporated makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * This file was derived in part from the original XFree86 sysv OS
+ * support which contains the following copyright notice:
+ *
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Thomas Roell and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Thomas Roell and
+ * David Wexelblat makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THOMAS ROELL AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID WEXELBLAT 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 <sys/types.h>
+#include <time.h>
+#include <errno.h>
+
+#include <sys/prosrfs.h>
+#include <sys/cpu.h>
+#include <sys/ipl.h>
+
+#include "X.h"
+#include "Xmd.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+static Bool KeepTty = FALSE;
+static Bool Protect0 = FALSE;
+static Bool pmaxInitialized = FALSE;
+
+#define VT_DEFAULT -2
+#define VT_NONE -1
+
+static int VTnum = VT_DEFAULT;
+
+extern void pmax_init_splmap(void);
+
+int pmax_sys_type; /* Also used by pmax_pci.c */
+
+/*
+ * PowerMAXOS_sys_type()
+ *
+ * Determine type of PowerHawk, PowerStack, PowerMaxion, or NightHawk
+ */
+int
+PowerMAXOS_sys_type(void)
+{
+ int fd;
+ procfile_t procfile;
+
+ fd = open("/system/processor/0",O_RDONLY);
+ if (fd<0) {
+ FatalError("Cannot open '%s'\n", "/system/processor/0");
+ }
+
+ if (read(fd, &procfile, sizeof(procfile)) < 0) {
+ FatalError("Cannot read '%s'\n", "/system/processor/0");
+ }
+ close(fd);
+
+ return(procfile.cpu_model);
+}
+
+void
+pmaxInit(void)
+{
+ char *mach;
+
+ if (pmaxInitialized)
+ return;
+
+ pmaxInitialized = TRUE;
+
+ /*
+ * Determine type of machine
+ */
+ pmax_sys_type = PowerMAXOS_sys_type();
+ switch(pmax_sys_type) {
+
+ case MODEL_NH6400:
+ mach ="PowerMAXION (NH6400)";
+ break;
+
+ case MODEL_NH6408:
+ mach = "PowerMAXION (NH6408)";
+ break;
+
+ case MODEL_NH6800T:
+ mach = "TurboHawk";
+ break;
+
+ case MODEL_MPWR:
+ mach = "PowerStack";
+ break;
+
+ case MODEL_PH610:
+ mach = "PowerHawk 610";
+ break;
+
+ case MODEL_MPWR2:
+ mach = "PowerStack II (utah)";
+ break;
+
+ case MODEL_PH620:
+ mach = "PowerHawk 620";
+ break;
+
+ case MODEL_PH640:
+ mach = "PowerHawk 640";
+ break;
+
+ case MODEL_MMTX:
+ mach = "PowerStack II (MTX)";
+ break;
+
+ default:
+ FatalError("pmaxInit: Unknown/unsupported machine type 0x%x\n",
+ pmax_sys_type);
+ /*NOTREACHED*/
+ }
+
+ xf86Msg(X_INFO, "pmaxInit: Machine type: %s\n", mach);
+
+ /*
+ * Map IPL hardware so that interrupts can be (temporarily) disabled
+ * (see pmax_video.c)
+ */
+ pmax_init_splmap();
+
+ /*
+ * Now that we know the system type, initialize the
+ * pci access routines
+ */
+ pciInit();
+}
+
+void
+xf86OpenConsole()
+{
+ struct vt_mode VT;
+ char vtname[10];
+ MessageType from = X_DEFAULT;
+
+ if (serverGeneration == 1)
+ {
+
+ /* check if we're run with euid==0 */
+ if (geteuid() != 0)
+ {
+ FatalError("xf86OpenConsole: Server must be suid root\n");
+ }
+
+ /* Protect page 0 to help find NULL dereferencing */
+ /* mprotect() doesn't seem to work */
+ if (Protect0)
+ {
+ int fd = -1;
+
+ if ((fd = open("/dev/zero", O_RDONLY, 0)) < 0)
+ {
+ xf86Msg(X_WARNING,
+ "xf86OpenConsole: cannot open /dev/zero (%s)\n",
+ strerror(errno));
+ }
+ else
+ {
+ if ((int)mmap(0, 0x1000, PROT_NONE,
+ MAP_FIXED | MAP_SHARED, fd, 0) == -1)
+ {
+ xf86Msg(X_WARNING,
+ "xf86OpenConsole: failed to protect page 0 (%s)\n",
+ strerror(errno));
+ }
+ close(fd);
+ }
+ }
+
+ pmaxInit(); /* Initialize OS specific functions */
+
+ /*
+ * setup the virtual terminal manager
+ */
+ if (VTnum == VT_DEFAULT) {
+ int fd;
+
+ /*
+ * No specific VT specified, so ask the vtl term mgr
+ * for the next available VT
+ */
+ if ((fd = open("/dev/vt00",O_WRONLY,0)) < 0) {
+ xf86Msg(X_WARNING,
+ "xf86OpenConsole: Could not open /dev/vt00 (%s)\n",
+ strerror(errno));
+ VTnum = VT_NONE;
+ }
+ else {
+ if (ioctl(fd, VT_OPENQRY, &VTnum) < 0)
+ {
+ xf86Msg(X_WARNING,
+ "xf86OpenConsole: Cannot find a free VT\n");
+ VTnum = VT_NONE;
+ }
+ close(fd);
+ }
+ } else {
+ from = X_CMDLINE;
+ }
+
+ xf86Info.vtno = VTnum;
+
+ if (xf86Info.vtno == VT_NONE)
+ strcpy(vtname, "/dev/null");
+ else
+ sprintf(vtname,"/dev/vt%02d",xf86Info.vtno);
+
+ xf86Msg(from, "using VT \"%s\"\n\n", vtname);
+
+ if (!KeepTty)
+ {
+ setpgrp();
+ }
+
+ if ((xf86Info.consoleFd = open(vtname, O_RDWR|O_NDELAY, 0)) < 0)
+ {
+ FatalError("xf86OpenConsole: Cannot open %s (%s)\n",
+ vtname, strerror(errno));
+ }
+
+ if (xf86Info.vtno != VT_NONE)
+ {
+ /* change ownership of the vt */
+ (void) chown(vtname, getuid(), getgid());
+
+ /*
+ * now get the VT
+ */
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
+ {
+ FatalError("xf86OpenConsole: VT_GETMODE failed\n");
+ }
+
+ signal(SIGUSR1, xf86VTRequest);
+
+ VT.mode = VT_PROCESS;
+ VT.relsig = SIGUSR1;
+ VT.acqsig = SIGUSR1;
+ if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
+ {
+ FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0)
+ {
+ FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed\n");
+ }
+ }
+ }
+ else
+ {
+ /* serverGeneration != 1 */
+ /*
+ * now get the VT
+ */
+ if (xf86Info.vtno != VT_NONE)
+ {
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
+ }
+ /*
+ * If the server doesn't have the VT when the reset occurs,
+ * this is to make sure we don't continue until the activate
+ * signal is received.
+ */
+ if (!xf86Screens[0]->vtSema)
+ sleep(5);
+ }
+ }
+ return;
+}
+
+void xf86CloseConsole()
+{
+ struct vt_mode VT;
+
+ if (xf86Info.vtno != VT_NONE)
+ {
+
+#if 0
+ ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno);
+ ioctl(xf86Info.consoleFd, VT_WAITACTIVE, 0);
+#endif
+ ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); /* Back to text mode ... */
+ if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1)
+ {
+ VT.mode = VT_AUTO;
+ ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* set dflt vt handling */
+ }
+ }
+
+ close(xf86Info.consoleFd); /* make the vt-manager happy */
+ return;
+}
+
+int xf86ProcessArgument(argc, argv, i)
+int argc;
+char *argv[];
+int i;
+{
+ /*
+ * Keep server from detaching from controlling tty. This is useful
+ * when debugging (so the server can receive keyboard signals.
+ */
+ if (!strcmp(argv[i], "-keeptty"))
+ {
+ KeepTty = TRUE;
+ return(1);
+ }
+
+ /*
+ * Prevent server from attemping to open a new VT in the "-novt"
+ * flag was specified.
+ */
+ if (!strcmp(argv[i], "-novt"))
+ {
+ VTnum = VT_NONE;
+ return(1);
+ }
+
+ /*
+ * Undocumented flag to protect page 0 from read/write to help
+ * catch NULL pointer dereferences. This is purely a debugging
+ * flag.
+ */
+ if (!strcmp(argv[i], "-protect0"))
+ {
+ Protect0 = TRUE;
+ return(1);
+ }
+
+ if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
+ {
+ if (sscanf(argv[i], "vt%2d", &VTnum) == 0)
+ {
+ UseMsg();
+ VTnum = VT_DEFAULT;
+ return(0);
+ }
+ return(1);
+ }
+ return(0);
+}
+
+void xf86UseMsg()
+{
+ ErrorF("vtXX use the specified VT number\n");
+ ErrorF("-keeptty ");
+ ErrorF("don't detach controlling tty (for debugging only)\n");
+ ErrorF("-novt ");
+ ErrorF("don't allocate and open a new virtual terminal\n");
+ return;
+}
+
+
+void
+xf86_pmax_usleep(unsigned long n)
+{
+ struct timespec requested,remaining;
+ int rv;
+
+ requested.tv_sec = n/1000000;
+ requested.tv_nsec = (n % 1000000) * 1000;
+
+ while ((rv = nanosleep(&requested,&remaining)) < 0) {
+ if (errno != EINTR)
+ break;
+
+ remaining = requested; /* structure assignment */
+ }
+
+ if (rv) {
+ ErrorF("xf86_pmax_usleep: nanosleep() failed: rv=%d, errno=%d\n", rv, errno);
+ }
+}
+
+#ifndef usleep
+
+void
+usleep(unsigned long n)
+{
+ xf86_pmax_usleep(n);
+}
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_map.c b/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_map.c
new file mode 100644
index 000000000..c1986370e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_map.c
@@ -0,0 +1,251 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_map.c,v 1.5 1999/07/18 08:14:36 dawes Exp $ */
+/*
+ * Copyright 1998 by Concurrent Computer Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Concurrent Computer
+ * Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Concurrent Computer Corporation makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Copyright 1998 by Metro Link Incorporated
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Metro Link
+ * Incorporated not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Metro Link Incorporated makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * This file was derived in part from the original XFree86 sysv OS
+ * support which contains the following copyright notice:
+ *
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Thomas Roell and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Thomas Roell and
+ * David Wexelblat makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THOMAS ROELL AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID WEXELBLAT 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 "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#include "Pci.h"
+
+/***************************************************************************/
+/* Video Memory Mapping section */
+/***************************************************************************/
+
+/*
+ * Map an I/O region given its address (host POV)
+ */
+void *
+pmax_iomap(unsigned long base, unsigned long len)
+{
+ int fd;
+ void *rv;
+
+ if ((fd = open("/dev/iomem", O_RDWR)) < 0)
+ {
+ ErrorF("pmax_iomap: failed to open /dev/iomem (%s)\n",
+ strerror(errno));
+ return(MAP_FAILED);
+ }
+
+ rv = (void *)mmap((caddr_t)0, len, PROT_READ|PROT_WRITE,
+ MAP_SHARED, fd, (off_t)base);
+
+ close(fd);
+ return(rv);
+}
+
+Bool
+xf86LinearVidMem()
+{
+ return TRUE;
+}
+
+extern void * pmax_iomap(unsigned long, unsigned long);
+
+pointer
+xf86MapVidMem(int ScreenNum, int Region, pointer Base, unsigned long Size)
+{
+ ErrorF("%s: Not supported on this OS. Drivers should use xf86MapPciMem() instead\n",
+ "xf86MapVidMem");
+ FatalError("%s: Cannot map [s=%x,a=%x]\n", "xf86MapVidMem", Size, Base);
+}
+
+
+pointer
+xf86MapPciMem(int ScreenNum, int Flags, PCITAG Tag, pointer Base,
+ unsigned long Size)
+{
+ pointer hostbase = pciBusAddrToHostAddr(Tag, Base);
+ pointer base;
+
+ base = (pointer) pmax_iomap((unsigned long)hostbase, Size);
+ if (base == MAP_FAILED) {
+ xf86Msg(X_WARNING,
+ "xf86MapPciMem: Could not mmap PCI memory "
+ "[base=0x%x,hostbase=0x%x,size=%x] (%s)\n",
+ Base, hostbase, Size, strerror(errno));
+ }
+ return((pointer)base);
+}
+
+
+/* ARGSUSED */
+void
+xf86UnMapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+{
+ munmap(Base, Size);
+}
+
+#if 0
+/* ARGSUSED */
+void xf86MapDisplay(ScreenNum, Region)
+int ScreenNum;
+int Region;
+{
+ return;
+}
+
+/* ARGSUSED */
+void xf86UnMapDisplay(ScreenNum, Region)
+int ScreenNum;
+int Region;
+{
+ return;
+}
+#endif
+
+/*
+ * Read BIOS via mmap()ing /dev/iomem.
+ */
+/*ARGSUSED*/
+int
+xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf, int Len)
+{
+ ErrorF("%s: Not supported on this OS. Drivers should use xf86ReadPciBIOS() instead\n",
+ "xf86ReadBIOS");
+ FatalError("%s: Cannot read BIOS [base=0x%x,offset=0x%x,size=%d]\n", "xf86ReadBIOS", Base, Offset, Len);
+}
+
+int
+xf86ReadPciBIOS(unsigned long Base, unsigned long Offset, PCITAG Tag,
+ unsigned char *Buf, int Len)
+{
+ pointer hostbase = pciBusAddrToHostAddr(Tag, (void *)Base);
+ char *base;
+ int psize;
+ int mlen;
+
+ psize = xf86getpagesize();
+ mlen = (Offset + Len + psize - 1) & ~psize;
+ base = pmax_iomap((unsigned long)hostbase, mlen);
+ if (base == MAP_FAILED) {
+ xf86Msg(X_WARNING, "xf86ReadPciBIOS: Could not mmap PCI memory"
+ " [base=0x%x,hostbase=0x%x,size=%x] (%s)\n",
+ Base, hostbase, mlen, strerror(errno));
+ return(0);
+ }
+
+ (void)memcpy(Buf, base + Offset, Len);
+ (void)munmap(base, mlen);
+ return(Len);
+}
+
+/***************************************************************************/
+/* Interrupt Handling section */
+/***************************************************************************/
+
+#include <sys/ipl.h>
+
+#ifndef PL_HI
+#define PL_HI PL8
+#endif
+
+#ifndef PL_0
+#define PL_0 PL0
+#endif
+
+static void *spl_map_addr = NULL;
+
+void
+pmax_init_splmap(void)
+{
+ spl_map_addr = spl_map(0);
+ if (!spl_map_addr) {
+ xf86Msg(X_WARNING,
+ "pmax_init_splmap: spl_map() failed. "
+ "Cannot bind to IPL register\n");
+ xf86ErrorF("\tInterrupts cannot be disabled/enabled !!!\n");
+ }
+}
+
+
+Bool
+xf86DisableInterrupts()
+{
+ if (spl_map_addr) {
+ (void)spl_request(PL_HI,spl_map_addr);
+ return(TRUE);
+ }
+
+ return(FALSE);
+}
+
+void xf86EnableInterrupts()
+{
+ if (spl_map_addr) {
+ (void)spl_request(PL_0, spl_map_addr);
+ }
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_mouse.c b/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_mouse.c
new file mode 100644
index 000000000..ea741b243
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_mouse.c
@@ -0,0 +1,58 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_mouse.c,v 1.1 1999/05/22 08:40:15 dawes Exp $ */
+
+/*
+ * Copyright 1999 by The XFree86 Project, Inc.
+ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Xinput.h"
+#include "xf86OSmouse.h"
+#ifdef NEW_INPUT
+#include "xqueue.h"
+#endif
+
+static int
+SupportedInterfaces(void)
+{
+ /* XXX Need to check this. */
+ return MSE_SERIAL | MSE_AUTO;
+}
+
+static const char *internalNames[] = {
+ "Xqueue",
+ NULL
+};
+
+static const char **
+BuiltinNames(void)
+{
+ return internalNames;
+}
+
+static Bool
+CheckProtocol(const char *protocol)
+{
+ int i;
+
+ for (i = 0; internalNames[i]; i++)
+ if (xf86NameCmp(protocol, internalNames[i]) == 0)
+ return TRUE;
+ return FALSE;
+}
+
+OSMouseInfoPtr
+xf86OSMouseInit(int flags)
+{
+ OSMouseInfoPtr p;
+
+ p = xcalloc(sizeof(OSMouseInfoRec), 1);
+ if (!p)
+ return NULL;
+ p->SupportedInterfaces = SupportedInterfaces;
+ p->BuiltinNames = BuiltinNames;
+ p->CheckProtocol = CheckProtocol;
+ p->PreInit = XqueueMousePreInit;
+ return p;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_pci.c b/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_pci.c
new file mode 100644
index 000000000..daa0446d2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_pci.c
@@ -0,0 +1,1071 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_pci.c,v 1.4 1999/01/14 13:05:08 dawes Exp $ */
+/*
+ * Copyright 1998 by Concurrent Computer Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Concurrent Computer
+ * Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Concurrent Computer Corporation makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Copyright 1998 by Metro Link Incorporated
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Metro Link
+ * Incorporated not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Metro Link Incorporated makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED 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 <stdio.h>
+#include "os.h"
+#include "compiler.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "Pci.h"
+
+#include <sys/prosrfs.h>
+#include <sys/cpu.h>
+
+/*
+ * Night Hawk 6400/6408 platform support
+ */
+#undef NH640X_PCI_MFDEV_SUPPORT
+#undef NH640X_PCI_BRIDGE_SUPPORT
+
+void nh640xPciInit(void);
+PCITAG nh640xPciFindNext(void);
+PCITAG nh640xPciFindFirst(void);
+CARD32 nh6400PciReadLong(PCITAG tag, int offset);
+void nh6400PciWriteLong(PCITAG tag, int offset, CARD32 val);
+ADDRESS nh6400BusToHostAddr(PCITAG tag, ADDRESS addr);
+ADDRESS nh6400HostToBusAddr(PCITAG tag, ADDRESS addr);
+CARD32 nh6408PciReadLong(PCITAG tag, int offset);
+void nh6408PciWriteLong(PCITAG tag, int offset, CARD32 val);
+ADDRESS nh6408BusToHostAddr(PCITAG tag, ADDRESS addr);
+ADDRESS nh6408HostToBusAddr(PCITAG tag, ADDRESS addr);
+
+pciBusFuncs_t nh6400_pci_funcs = {
+ nh6400PciReadLong,
+ nh6400PciWriteLong,
+ nh6400HostToBusAddr,
+ nh6400BusToHostAddr
+};
+
+pciBusFuncs_t nh6408_pci_funcs = {
+ nh6408PciReadLong,
+ nh6408PciWriteLong,
+ nh6408HostToBusAddr,
+ nh6408BusToHostAddr
+};
+
+/*
+ * NH640x CFG address and data register offsets from base
+ */
+#define NH6400_PCI_CFG_ADDR_REG_OFF 0
+#define NH6400_PCI_CFG_TYPE0_DATA_REG_OFF 0x40
+#define NH6400_PCI_CFG_TYPE1_DATA_REG_OFF 0x80
+
+#define NH6408_PCI_CFG_ADDR_REG_OFF 0
+#define NH6408_PCI_CFG_DATA_REG_OFF 0x10000
+
+/*
+ * Possible cfg addr values for NH640x GMEM PMC ports
+ */
+unsigned long nh6400_pmc_cfgaddrs[] = {
+ PCI_CFGMECH1_TYPE0_CFGADDR(0,0,0)
+};
+
+/*
+ * Possible cfg addr values for devices on a secondary bus
+ * (e.g. behind DEC 21152 PCI-to-PCI bridge)
+ */
+unsigned long dec_cfgaddrs[] = {
+ PCI_CFGMECH1_TYPE1_CFGADDR(1,0,0,0),
+ PCI_CFGMECH1_TYPE1_CFGADDR(1,1,0,0),
+ PCI_CFGMECH1_TYPE1_CFGADDR(1,2,0,0),
+ PCI_CFGMECH1_TYPE1_CFGADDR(1,3,0,0),
+ PCI_CFGMECH1_TYPE1_CFGADDR(1,4,0,0),
+ PCI_CFGMECH1_TYPE1_CFGADDR(1,5,0,0),
+ PCI_CFGMECH1_TYPE1_CFGADDR(1,6,0,0),
+ PCI_CFGMECH1_TYPE1_CFGADDR(1,7,0,0),
+ PCI_CFGMECH1_TYPE1_CFGADDR(1,8,0,0),
+ PCI_CFGMECH1_TYPE1_CFGADDR(1,9,0,0),
+ PCI_CFGMECH1_TYPE1_CFGADDR(1,10,0,0),
+ PCI_CFGMECH1_TYPE1_CFGADDR(1,11,0,0),
+ PCI_CFGMECH1_TYPE1_CFGADDR(1,12,0,0),
+ PCI_CFGMECH1_TYPE1_CFGADDR(1,13,0,0),
+ PCI_CFGMECH1_TYPE1_CFGADDR(1,14,0,0),
+ PCI_CFGMECH1_TYPE1_CFGADDR(1,15,0,0)
+};
+
+/*
+ * Data structure holding information about various nh640x PCI buses
+ */
+struct nh640x_pci_info {
+ int busnum;
+ int type;
+ unsigned long num_cfg_addrs;
+ unsigned long *cfg_addrs;
+ int primary_bus;
+ unsigned long cfgPhysBase;
+ unsigned long memBase;
+ unsigned long ioBase;
+ unsigned long ioSize;
+ unsigned char *cfgAddrReg; /* After mapping */
+};
+/*type*/
+#define PRIMARY_PCI 0
+#define SECONDARY_PCI 1
+
+struct nh640x_pci_info nh6400_pci_info[] = {
+/* pci4 */ { 4, PRIMARY_PCI, 1, nh6400_pmc_cfgaddrs, 0, 0xa0000000, 0xa1000000, 0, 0xa2000000 },
+/* pci12 */ { 12, SECONDARY_PCI, 16, dec_cfgaddrs, 4 },
+#if 0
+/* pci5 */ { 5, PRIMARY_PCI, 1, nh6400_pmc_cfgaddrs, 0, 0xb0000000, 0xb1000000, 0, 0xb2000000 },
+/* pci13 */ { 13, SECONDARY_PCI, 16, dec_cfgaddrs, 5 },
+#endif
+};
+
+#define NH6400_NUM_PCI_EXPANSION_BUSES (sizeof(nh6400_pci_info)/sizeof(struct nh640x_pci_info))
+
+struct nh640x_pci_info nh6408_pci_info[] = {
+/* pci8 */ { 8, PRIMARY_PCI, 1, nh6400_pmc_cfgaddrs, 0, 0x98040000, 0x9a800000, 65536, 0xa0000000 },
+/* pci12 */ { 12, SECONDARY_PCI, 16, dec_cfgaddrs, 8, },
+#if 0
+/* pci9 */ { 9, PRIMARY_PCI, 1, nh6400_pmc_cfgaddrs, 0, 0x99040000, 0x9b800000, 65536, 0xb0000000 },
+/* pci13 */ { 13, SECONDARY_PCI, 16, dec_cfgaddrs, 9, },
+#endif
+};
+
+#define NH6408_NUM_PCI_EXPANSION_BUSES (sizeof(nh6408_pci_info)/sizeof(struct nh640x_pci_info))
+
+extern unsigned long pmax_sys_type;
+
+#define MOTOPPC_IO_BASE 0x80000000L /* Start of PCI/ISA I/O region */
+
+extern void * pmax_iomap(unsigned long, unsigned long);
+extern unsigned long ioSize;
+extern volatile unsigned char *ioBase;
+
+void
+pmaxPciInit(void)
+{
+ extern void motoppcPciInit(void);
+ extern void nh640xPciInit(void);
+ extern void nh6800tPciInit(void);
+
+ extern unsigned long motoPciMemBase;
+ extern unsigned long motoPciMemLen;
+ extern unsigned long motoPciMemBaseCPU;
+
+ /*
+ * Determine type of machine
+ */
+ switch(pmax_sys_type) {
+ case MODEL_NH6400:
+ case MODEL_NH6408:
+ nh640xPciInit();
+ break;
+
+ case MODEL_NH6800T:
+ nh6800tPciInit();
+ break;
+
+ case MODEL_PH620:
+ case MODEL_PH640:
+ case MODEL_MMTX:
+ motoPciMemBase = 0;
+ motoPciMemLen = 0x20000000;
+ motoPciMemBaseCPU = 0xa0000000;
+ /*FALLTHROUGH*/
+
+ case MODEL_MPWR:
+ case MODEL_PH610:
+ case MODEL_MPWR2:
+ motoppcPciInit();
+ break;
+
+ default:
+ FatalError("pmaxPciInit: Unsupported machine type\n");
+ break;
+ }
+}
+
+void
+ppcPciIoMap(int pcibus)
+{
+ int primary_bus;
+
+ if (ioBase != MAP_FAILED)
+ munmap((void*)ioBase,ioSize);
+
+ if (!pciBusInfo[pcibus])
+ return;
+
+ primary_bus = pciBusInfo[pcibus]->primary_bus;
+
+ if (!pciBusInfo[primary_bus])
+ return;
+
+ ioSize = min(pciBusInfo[primary_bus]->ppc_io_size, 64 * 1024);
+ if (ioSize) {
+ ioBase = (unsigned char *)pmax_iomap(pciBusInfo[primary_bus]->ppc_io_base, ioSize);
+ if (ioBase == MAP_FAILED)
+ ioSize = 0;
+ }
+}
+
+void
+nh640xPciInit(void)
+{
+ int i,n;
+ struct nh640x_pci_info *infop;
+ pciBusFuncs_t *functions;
+
+ switch (pmax_sys_type) {
+ case MODEL_NH6400:
+ n = NH6400_NUM_PCI_EXPANSION_BUSES;
+ infop = nh6400_pci_info;
+ functions = &nh6400_pci_funcs;
+ break;
+ case MODEL_NH6408:
+ n = NH6408_NUM_PCI_EXPANSION_BUSES;
+ infop = nh6408_pci_info;
+ functions = &nh6408_pci_funcs;
+ break;
+ default:
+ FatalError("Unknown Power MAXION system type\n");
+ /*NOTREACHED*/
+ }
+
+ /*
+ * Initialize entries in pciBusInfo[] table for each defined PCI bus.
+ * This table is actually sparse because undefined or inaccessible
+ * pci buses are left as NULL entries. Of course, pciFindNext() is
+ * aware of this convention, and will skip the undefined buses.
+ */
+ for (i=0; i<n; infop++,i++) {
+ int bus = infop->busnum;
+ pciBusInfo_t *busp;
+
+ if (pciBusInfo[bus])
+ busp = pciBusInfo[bus];
+ else
+ busp = xalloc(sizeof(pciBusInfo_t));
+
+ if (!busp)
+ FatalError("nh640xPciInit: xalloc failed\n");
+
+ /* Initialize pci bus info */
+ busp->configMech = PCI_CFG_MECH_OTHER;
+ busp->numDevices = infop->num_cfg_addrs;
+ busp->secondary = (infop->type == SECONDARY_PCI ? TRUE : FALSE);
+ busp->primary_bus = infop->primary_bus;
+ busp->funcs = *functions; /* Structure assignment */
+ busp->pciBusPriv = infop;
+
+ /* Initialize I/O base/size info */
+ if (busp->secondary) {
+ pciBusInfo_t *pri_busp = pciBusInfo[busp->primary_bus];
+ if (pri_busp) {
+ busp->ppc_io_base = pri_busp->ppc_io_base;
+ busp->ppc_io_size = pri_busp->ppc_io_size;
+ }
+ }
+ else if (infop->ioSize) {
+ busp->ppc_io_size = infop->ioSize;
+ busp->ppc_io_base = infop->ioBase;
+ }
+
+ pciBusInfo[bus] = busp;
+
+ /*
+ * Adjust pciNumBuses to reflect the highest defined entry in pciBusInfo
+ */
+ if (pciNumBuses < bus)
+ pciNumBuses = bus + 1;
+ }
+
+ pciFindFirstFP = nh640xPciFindFirst;
+ pciFindNextFP = nh640xPciFindNext;
+}
+
+PCITAG
+nh640xPciFindNext(void)
+{
+ unsigned long devid, tmp;
+ unsigned char base_class, sub_class, sec_bus, pri_bus;
+
+ for (;;) {
+
+ if (pciBusNum == -1) {
+ /*
+ * Start at top of the order
+ */
+ pciBusNum = 0;
+ pciFuncNum = 0;
+ pciDevNum = 0;
+ }
+ else {
+#ifdef NH640X_PCI_MFDEV_SUPPORT
+ /*
+ * Somewhere in middle of order. Determine who's
+ * next up
+ */
+ if (pciFuncNum == 0) {
+ /*
+ * Is current dev a multifunction device?
+ */
+ if (pciMfDev(pciBusNum, pciDevNum))
+ /* Probe for other functions */
+ pciFuncNum = 1;
+ else
+ /* No more functions this device. Next device please */
+ pciDevNum ++;
+ }
+ else if (++pciFuncNum >= 8) {
+ /* No more functions for this device. Next device please */
+ pciFuncNum = 0;
+ pciDevNum ++;
+ }
+#else /* NH640X_PCI_MFDEV_SUPPORT */
+ pciDevNum++;
+#endif /* NH640X_PCI_MFDEV_SUPPORT */
+
+ if (!pciBusInfo[pciBusNum] || pciDevNum >= pciBusInfo[pciBusNum]->numDevices) {
+ /*
+ * No more devices for this bus. Next bus please
+ */
+ if (++pciBusNum >= pciNumBuses)
+ /* No more buses. All done for now */
+ return(PCI_NOT_FOUND);
+
+ pciDevNum = 0;
+ }
+ }
+
+ if (!pciBusInfo[pciBusNum])
+ continue; /* Undefined bus, next bus/device please */
+
+ /*
+ * At this point, pciBusNum, pciDevNum, and pciFuncNum have been
+ * advanced to the next device. Compute the tag, and read the
+ * device/vendor ID field.
+ */
+ pciDeviceTag = PCI_MAKE_TAG(pciBusNum, pciDevNum, pciFuncNum);
+ devid = pciReadLong(pciDeviceTag, 0);
+ if (devid == 0xffffffff)
+ continue; /* Nobody home. Next device please */
+
+#ifdef NH640X_PCI_BRIDGE_SUPPORT
+ /*
+ * Before checking for a specific devid, look for enabled
+ * PCI to PCI bridge devices. If one is found, create and
+ * initialize a bus info record (if one does not already exist).
+ */
+ tmp = pciReadLong(pciDeviceTag, PCI_CLASS_CODE_REG);
+ base_class = PCI_EXTRACT_BASE_CLASS(tmp);
+ sub_class = PCI_EXTRACT_SUBCLASS(tmp);
+ if (base_class == PCI_CLASS_BRIDGE && sub_class == PCI_SUBCLASS_BRIDGE_PCI) {
+ tmp = pciReadLong(pciDeviceTag, PCI_BRIDGE_BUS_REG);
+ sec_bus = PCI_SECONDARY_BUS_EXTRACT(tmp);
+ pri_bus = PCI_PRIMARY_BUS_EXTRACT(tmp);
+ if (sec_bus > 0 && sec_bus < PCI_MAX_BUSES && pcibusInfo[pri_bus]) {
+ /*
+ * Found a secondary PCI bus
+ */
+ if (!pciBusInfo[sec_bus]) {
+ pciBusInfo[sec_bus] = xalloc(sizeof(pciBusInfo_t));
+
+ if (!pciBusInfo[sec_bus])
+ FatalError("nh640xPciFindNext: alloc failed\n!!!");
+ }
+
+ /* Copy parents settings... */
+ *pciBusInfo[sec_bus] = *pcibusInfo[pri_bus];
+
+ /* ...but not everything same as parent */
+ pciBusInfo[sec_bus]->primary_bus = pri_bus;
+ pciBusInfo[sec_bus]->secondary = TRUE;
+ pciBusInfo[sec_bus]->numDevices = 32;
+
+ if (pciNumBuses < sec_num)
+ pciNumBuses = sec_num+1;
+ }
+ }
+#endif /* NH640X_PCI_BRIDGE_SUPPORT */
+
+ /*
+ * Does this device match the requested devid after
+ * applying mask?
+ */
+ if ((devid & pciDevidMask) == pciDevid) {
+ /* Yes - Return it. Otherwise, next device */
+
+ /* However, before returning it, try to map */
+ /* I/O region for this PCI bus */
+ ppcPciIoMap(PCI_BUS_FROM_TAG(pciDeviceTag));
+
+ return(pciDeviceTag); /* got a match */
+ }
+
+ } /* for */
+
+ /*NOTREACHED*/
+}
+
+PCITAG
+nh640xPciFindFirst(void)
+{
+ pciBusNum = -1;
+ return(nh640xPciFindNext());
+}
+
+unsigned long
+nh6400PciReadLong(PCITAG tag, int offset)
+{
+ unsigned long tmp;
+ char *base;
+ int devnum, bus, func, data_reg_offset, ndevs;
+ unsigned long cfgaddr;
+ pciBusInfo_t *busp, *pri_busp;
+ struct nh640x_pci_info *infop, *pri_infop;
+
+ bus = PCI_BUS_FROM_TAG(tag);
+ devnum = PCI_DEV_FROM_TAG(tag);
+ func = PCI_FUNC_FROM_TAG(tag);
+
+ xf86MsgVerb(3, X_INFO,
+ "nh6400PciReadLong: bus=%d, devnum=%d, func=%d, offset=0x%x\n",
+ bus, devnum, func, offset);
+
+ if (bus >= pciNumBuses || !pciBusInfo[bus]) {
+ xf86Msg(X_WARNING, "nh6400PciReadLong: bus pci%d not defined!!!\n",
+ bus);
+ return(0xffffffff);
+ }
+
+ busp = pciBusInfo[bus];
+ infop = (struct nh640x_pci_info *)busp->pciBusPriv;
+
+ if (busp->secondary) {
+ /*
+ * Secondary PCI bus behind a pci-to-pci bridge
+ */
+ pri_busp = pciBusInfo[busp->primary_bus];
+ pri_infop = (struct nh640x_pci_info *)pri_busp->pciBusPriv;
+ ndevs = 16;
+ data_reg_offset = NH6400_PCI_CFG_TYPE1_DATA_REG_OFF; /* For Type 1 cfg cycles */
+
+ if (!pri_busp) {
+ xf86Msg(X_WARNING,
+ "nh6400PciReadLong: pci%d's primary parent [pci%d] "
+ "is not defined!!!\n", bus, busp->primary_bus);
+ return(0xffffffff);
+ }
+ }
+ else {
+ pri_busp = busp;
+ pri_infop = infop;
+ ndevs = infop->num_cfg_addrs;
+ data_reg_offset = NH6400_PCI_CFG_TYPE0_DATA_REG_OFF; /* For Type 0 cfg cycles */
+ }
+
+ if (devnum >= ndevs) {
+ xf86Msg(X_WARNING,
+ "nh6400PciReadLong: devnum %d out of range for bus pci%d\n",
+ devnum, bus);
+ return(0xffffffff);
+ }
+
+ /*
+ * Make sure the cfg address and data registers for this bus are mapped
+ * Secondary buses just use the primary parents addreses
+ */
+ if (!infop->cfgAddrReg) {
+ if (!pri_infop->cfgAddrReg) {
+ pri_infop->cfgAddrReg = pmax_iomap(pri_infop->cfgPhysBase, 0x1000);
+ if (pri_infop->cfgAddrReg == MAP_FAILED) {
+ FatalError("nh6400PciReadLong: Cannot map PCI cfg regs @ 0x%08x\n",
+ pri_infop->cfgPhysBase);
+ /*NOTREACHED*/
+ }
+ }
+ infop->cfgAddrReg = pri_infop->cfgAddrReg;
+ infop->cfgPhysBase = pri_infop->cfgPhysBase;
+ }
+ base = infop->cfgAddrReg;
+
+ if (busp->secondary) {
+ /* cfgaddr = PCI_CFGMECH1_TYPE1_CFGADDR(bus,devnum,func,offset); */
+ cfgaddr = PCI_CFGMECH1_TYPE1_CFGADDR(1,devnum,func,offset); /* Must use bus=1 for now - glb */
+ }
+ else {
+ cfgaddr = infop->cfg_addrs[devnum] + offset;
+ }
+
+ xf86MsgVerb(X_INFO, 3,
+ "nh6400PciReadLong: Writing cfgaddr=0x%x to 0x%x (phys=0x%x)\n",
+ cfgaddr, base, infop->cfgPhysBase);
+
+ xf86DisableInterrupts();
+
+ *((unsigned long *)(base)) = pciByteSwap(cfgaddr); /* Set cfg address */
+ eieio();
+
+ xf86MsgVerb(X_INFO, 3,
+ "nh6400PciReadLong: About to read from 0x%x (phys=0x%x)\n",
+ base + data_reg_offset, infop->cfgPhysBase + data_reg_offset);
+
+ if (!badaddr(base + data_reg_offset, 4, 0)) {
+ tmp = *((unsigned long *)(base + data_reg_offset));
+ eieio();
+ }
+
+ xf86EnableInterrupts();
+
+ xf86MsgVerb(X_INFO, 3, "nh6400PciReadLong: Read value=0x%x\n",
+ pciByteSwap(tmp));
+
+ return(pciByteSwap(tmp));
+}
+
+void
+nh6400PciWriteLong(PCITAG tag, int offset, unsigned long val)
+{
+ char *base;
+ int devnum, bus, func, data_reg_offset, ndevs;
+ unsigned long cfgaddr;
+ pciBusInfo_t *busp, *pri_busp;
+ struct nh640x_pci_info *infop, *pri_infop;
+
+ bus = PCI_BUS_FROM_TAG(tag);
+ devnum = PCI_DEV_FROM_TAG(tag);
+ func = PCI_FUNC_FROM_TAG(tag);
+
+ xf86MsgVerb(X_INFO, 3,
+ "nh6400PciWriteLong: bus=%d, devnum=%d, func=%d, offset=0x%x, "
+ val=0x%x\n", bus, devnum, func, offset, val);
+
+ if (bus >= pciNumBuses || !pciBusInfo[bus]) {
+ xf86Msg(X_WARNING, "nh6400PciWriteLong: bus pci%d not defined!!!\n",
+ bus);
+ return;
+ }
+ busp = pciBusInfo[bus];
+ infop = (struct nh640x_pci_info *)busp->pciBusPriv;
+
+ if (busp->secondary) {
+ /*
+ * Secondary PCI bus behind a pci-to-pci bridge
+ */
+ pri_busp = pciBusInfo[busp->primary_bus];
+ pri_infop = (struct nh640x_pci_info *)pri_busp->pciBusPriv;
+ ndevs = 16;
+ data_reg_offset = NH6400_PCI_CFG_TYPE1_DATA_REG_OFF; /* For Type 1 cfg cycles */
+
+ if (!pri_busp) {
+ xf86Msg(X_WARNING,
+ "nh6400PciWriteLong: pci%d's primary parent [pci%d]"
+ " is not defined!!!\n", bus, busp->primary_bus);
+ return;
+ }
+ }
+ else {
+ pri_busp = busp;
+ pri_infop = infop;
+ ndevs = infop->num_cfg_addrs;
+ data_reg_offset = NH6400_PCI_CFG_TYPE0_DATA_REG_OFF; /* For Type 0 cfg cycles */
+ }
+
+ if (devnum >= ndevs) {
+ xf86Msg(X_WARNING,
+ "nh6400PciWriteLong: devnum %d out of range for bus pci%d\n",
+ devnum, bus);
+ return;
+ }
+
+ /*
+ * Make sure the cfg address and data registers for this bus are mapped
+ * Secondary buses just use the primary parents addreses
+ */
+ if (!infop->cfgAddrReg) {
+ if (!pri_infop->cfgAddrReg) {
+ pri_infop->cfgAddrReg = pmax_iomap(pri_infop->cfgPhysBase, 0x1000);
+ if (pri_infop->cfgAddrReg == MAP_FAILED) {
+ FatalError("nh6400PciWriteLong: Cannot map PCI cfg regs @ 0x%08x\n",
+ pri_infop->cfgPhysBase);
+ /*NOTREACHED*/
+ }
+ }
+ infop->cfgAddrReg = pri_infop->cfgAddrReg;
+ infop->cfgPhysBase = pri_infop->cfgPhysBase;
+ }
+ base = infop->cfgAddrReg;
+
+ if (busp->secondary) {
+ /* cfgaddr = PCI_CFGMECH1_TYPE1_CFGADDR(bus,devnum,func,offset); */
+ cfgaddr = PCI_CFGMECH1_TYPE1_CFGADDR(1,devnum,func,offset); /* Must use bus=1 for now - glb */
+ }
+ else {
+ cfgaddr = infop->cfg_addrs[devnum] + offset;
+ }
+
+ xf86MsgVerb(X_INFO, 3,
+ "nh6400PciWriteLong: Writing cfgaddr=0x%x to 0x%x (phys=0x%x)\n",
+ cfgaddr, base, infop->cfgPhysBase);
+
+ xf86DisableInterrupts();
+
+ *((unsigned long *)(base)) = pciByteSwap(cfgaddr); /* Set cfg address */
+ eieio();
+
+ xf86MsgVerb(X_INFO, 3,
+ "nh6400PciWriteLong: Writing value=0x%x to 0x%x (phys=0x%x)\n",
+ val, base + data_reg_offset,
+ infop->cfgPhysBase + data_reg_offset);
+
+ *((unsigned long *)(base + data_reg_offset)) = pciByteSwap(val);
+ eieio();
+
+ xf86EnableInterrupts();
+}
+
+/*
+ * These next two functions are for debugging purposes only because
+ * the nh6400 does not translate passed to/from a PCI domain. However,
+ * we do do some bounds checking to make sure things are where they
+ * should be.
+ */
+ADDRESS
+nh6400BusToHostAddr(PCITAG tag, ADDRESS addr)
+{
+ unsigned long addr_l = (unsigned long)addr;
+ int bus = PCI_BUS_FROM_TAG(tag);
+ struct nh640x_pci_info *infop;
+ int pri_bus;
+ unsigned long membase;
+
+ if (!pciBusInfo[bus])
+ FatalError("nh6400BusToHostAddr: pci%d not defined!!\n", bus);
+
+ if (pciBusInfo[bus]->secondary) {
+ pri_bus = pciBusInfo[bus]->primary_bus;
+
+ if (!pciBusInfo[pri_bus])
+ FatalError("nh6400BusToHostAddr: Primary bus pci%d not defined!!\n", pri_bus);
+ }
+ else
+ pri_bus = bus;
+
+ infop = (struct nh640x_pci_info *)pciBusInfo[pri_bus]->pciBusPriv;
+ membase = infop->memBase;
+
+ if (addr_l < 0x80000000)
+ /*
+ * NH6400 host memory addresses are 0-0x7fffffff
+ */
+ return(addr);
+
+ else if (addr_l >= membase && addr_l < membase + 0x0e000000)
+ /*
+ * NH6400 host can access PCI memory space addresses
+ * [memBase, memBase+0x0dffffff]
+ */
+ return(addr);
+ else
+ /* Other addresses are not valid */
+ FatalError("nh6400BusToHostAddr: Bus address 0x%x not visible to NH6400 host\n",
+ addr_l);
+
+ /*NOTREACHED*/
+}
+
+ADDRESS
+nh6400HostToBusAddr(PCITAG tag, ADDRESS addr)
+{
+ unsigned long addr_l = (unsigned long) addr;
+ int bus = PCI_BUS_FROM_TAG(tag);
+ struct nh640x_pci_info *infop;
+ int pri_bus;
+ unsigned long membase;
+
+ if (!pciBusInfo[bus])
+ FatalError("nh6400HostToBusAddr: pci%d not defined!!\n", bus);
+
+ if (pciBusInfo[bus]->secondary) {
+ pri_bus = pciBusInfo[bus]->primary_bus;
+
+ if (!pciBusInfo[pri_bus])
+ FatalError("nh6400HostToBusAddr: Primary bus pci%d not defined!!\n", pri_bus);
+ }
+ else
+ pri_bus = bus;
+
+ infop = (struct nh640x_pci_info *)pciBusInfo[pri_bus]->pciBusPriv;
+ membase = infop->memBase;
+
+ if (addr_l < 0x80000000)
+ /*
+ * NH6400 host memory addresses are 0-0x7fffffff
+ */
+ return(addr);
+
+ else if (addr_l >= membase && addr_l < membase + 0x0e000000)
+ /*
+ * NH6400 host can access PCI memory space addresses
+ * [memBase, memBase+0x0dffffff]
+ */
+ return(addr);
+ else
+ /* Other addresses are not valid */
+ FatalError("nh6400HostToBusAddr: Bus address 0x%x not visible to NH6400 host\n",
+ addr_l);
+
+ /*NOTREACHED*/
+}
+
+
+/*
+ * NH6408 platform support
+ */
+unsigned long
+nh6408PciReadLong(PCITAG tag, int offset)
+{
+ unsigned long tmp;
+ char *base;
+ int devnum, bus, func, ndevs;
+ unsigned long cfgaddr;
+ pciBusInfo_t *busp, *pri_busp;
+ struct nh640x_pci_info *infop, *pri_infop;
+
+ bus = PCI_BUS_FROM_TAG(tag);
+ devnum = PCI_DEV_FROM_TAG(tag);
+ func = PCI_FUNC_FROM_TAG(tag);
+
+ xf86MsgVerb(X_INFO,
+ "nh6408PciReadLong: bus=%d, devnum=%d, func=%d, offset=0x%x\n",
+ bus, devnum, func, offset);
+
+ if (bus >= pciNumBuses || !pciBusInfo[bus]) {
+ xf86Msg(X_WARNING, "nh6408PciReadLong: bus pci%d not defined!!!\n",
+ bus);
+ return(0xffffffff);
+ }
+
+ busp = pciBusInfo[bus];
+ infop = (struct nh640x_pci_info *)busp->pciBusPriv;
+
+ if (busp->secondary) {
+ /*
+ * Secondary PCI bus behind a pci-to-pci bridge
+ */
+ pri_busp = pciBusInfo[busp->primary_bus];
+ pri_infop = (struct nh640x_pci_info *)pri_busp->pciBusPriv;
+ ndevs = 16;
+
+ if (!pri_busp) {
+ xf86Msg(X_WARNING,
+ "nh6408PciReadLong: pci%d's primary parent [pci%d] "
+ "is not defined!!!\n", bus, busp->primary_bus);
+ return(0xffffffff);
+ }
+ }
+ else {
+ pri_busp = busp;
+ pri_infop = infop;
+ ndevs = infop->num_cfg_addrs;
+ }
+
+ if (devnum >= ndevs) {
+ xf86Msg(X_WARNING
+ "nh6408PciReadLong: devnum %d out of range for bus pci%d\n",
+ devnum, bus);
+ return(0xffffffff);
+ }
+
+ /*
+ * Make sure the cfg address and data registers for this bus are mapped
+ * Secondary buses just use the primary parents addreses
+ */
+ if (!infop->cfgAddrReg) {
+ if (!pri_infop->cfgAddrReg) {
+ pri_infop->cfgAddrReg = pmax_iomap(pri_infop->cfgPhysBase, 0x11000);
+ if (pri_infop->cfgAddrReg == MAP_FAILED) {
+ FatalError("nh6408PciReadLong: Cannot map PCI cfg regs @ 0x%08x\n",
+ pri_infop->cfgPhysBase);
+ /*NOTREACHED*/
+ }
+ }
+ infop->cfgAddrReg = pri_infop->cfgAddrReg;
+ infop->cfgPhysBase = pri_infop->cfgPhysBase;
+ }
+ base = infop->cfgAddrReg;
+
+ if (busp->secondary) {
+ /* cfgaddr = PCI_CFGMECH1_TYPE1_CFGADDR(bus,devnum,func,offset); */
+ cfgaddr = PCI_CFGMECH1_TYPE1_CFGADDR(1,devnum,func,offset); /* Must use bus=1 for now - glb */
+ }
+ else {
+ cfgaddr = infop->cfg_addrs[devnum] + offset;
+ }
+
+ xf86MsgVerb(X_INFO, 3,
+ "nh6408PciReadLong: Writing cfgaddr=0x%x to 0x%x (phys=0x%x)\n",
+ cfgaddr, base, infop->cfgPhysBase);
+
+ xf86DisableInterrupts();
+
+ *((unsigned long *)(base)) = pciByteSwap(cfgaddr); /* Set cfg address */
+ eieio();
+
+ xf86MsgVerb(X_INFO, 3,
+ "nh6408PciReadLong: About to read from 0x%x (phys=0x%x)\n",
+ base + NH6408_PCI_CFG_DATA_REG_OFF,
+ infop->cfgPhysBase + NH6408_PCI_CFG_DATA_REG_OFF);
+
+ if (!badaddr(base + NH6408_PCI_CFG_DATA_REG_OFF, 4, 0)) {
+ tmp = *((unsigned long *)(base + NH6408_PCI_CFG_DATA_REG_OFF));
+ eieio();
+ }
+
+ xf86EnableInterrupts();
+
+ xf86MsgVerb(X_INFO, 3, "nh6408PciReadLong: Read value=0x%x\n",
+ pciByteSwap(tmp));
+
+ return(pciByteSwap(tmp));
+}
+
+void
+nh6408PciWriteLong(PCITAG tag, int offset, unsigned long val)
+{
+ char *base;
+ int devnum, bus, func, ndevs;
+ unsigned long cfgaddr;
+ pciBusInfo_t *busp, *pri_busp;
+ struct nh640x_pci_info *infop, *pri_infop;
+
+ bus = PCI_BUS_FROM_TAG(tag);
+ devnum = PCI_DEV_FROM_TAG(tag);
+ func = PCI_FUNC_FROM_TAG(tag);
+
+ xf86MsgVerb(X_INFO,
+ "nh6408PciWriteLong: bus=%d, devnum=%d, func=%d, offset=0x%x, "
+ "val=0x%x\n", bus, devnum, func, offset, val);
+
+ if (bus >= pciNumBuses || !pciBusInfo[bus]) {
+ xf86Msg(X_WARNING, "nh6408PciWriteLong: bus pci%d not defined!!!\n",
+ bus);
+ return;
+ }
+
+ busp = pciBusInfo[bus];
+ infop = (struct nh640x_pci_info *)busp->pciBusPriv;
+
+ if (busp->secondary) {
+ /*
+ * Secondary PCI bus behind a pci-to-pci bridge
+ */
+ pri_busp = pciBusInfo[busp->primary_bus];
+ pri_infop = (struct nh640x_pci_info *)pri_busp->pciBusPriv;
+ ndevs = 16;
+
+ if (!pri_busp) {
+ xf86Msg(X_WARNING,
+ "nh6408PciWriteLong: pci%d's primary parent [pci%d] "
+ is not defined!!!\n", bus, busp->primary_bus);
+ return;
+ }
+ }
+ else {
+ pri_busp = busp;
+ pri_infop = infop;
+ ndevs = infop->num_cfg_addrs;
+ }
+
+ if (devnum >= ndevs) {
+ xf86Msg(X_WARNING,
+ "nh6408PciWriteLong: devnum %d out of range for bus pci%d\n",
+ devnum, bus);
+ return;
+ }
+
+ /*
+ * Make sure the cfg address and data registers for this bus are mapped
+ * Secondary buses just use the primary parents addreses
+ */
+ if (!infop->cfgAddrReg) {
+ if (!pri_infop->cfgAddrReg) {
+ pri_infop->cfgAddrReg = pmax_iomap(pri_infop->cfgPhysBase, 0x11000);
+ if (pri_infop->cfgAddrReg == MAP_FAILED) {
+ FatalError("nh6408PciWriteLong: Cannot map PCI cfg regs @ 0x%08x\n",
+ pri_infop->cfgPhysBase);
+ /*NOTREACHED*/
+ }
+ }
+ infop->cfgAddrReg = pri_infop->cfgAddrReg;
+ infop->cfgPhysBase = pri_infop->cfgPhysBase;
+ }
+ base = infop->cfgAddrReg;
+
+ if (busp->secondary) {
+ /* cfgaddr = PCI_CFGMECH1_TYPE1_CFGADDR(bus,devnum,0,offset); */
+ cfgaddr = PCI_CFGMECH1_TYPE1_CFGADDR(1,devnum,0,offset);
+ }
+ else {
+ cfgaddr = infop->cfg_addrs[devnum] + offset;
+ }
+
+ xf86MsgVerb(X_INFO, 3,
+ "nh6408PciWriteLong: Writing cfgaddr=0x%x to 0x%x (phys=0x%x)\n",
+ cfgaddr, base, infop->cfgPhysBase);
+
+ xf86DisableInterrupts();
+
+ *((unsigned long *)(base)) = pciByteSwap(cfgaddr); /* Set cfg address */
+ eieio();
+
+ xf86MsgVerb(X_INFO, 3,
+ "nh6408PciWriteLong: Writing value=0x%x to 0x%x (phys=0x%x)\n",
+ val, base + NH6408_PCI_CFG_DATA_REG_OFF,
+ infop->cfgPhysBase + NH6408_PCI_CFG_DATA_REG_OFF);
+
+
+ *((unsigned long *)(base + NH6408_PCI_CFG_DATA_REG_OFF)) = pciByteSwap(val);
+ eieio();
+
+ xf86EnableInterrupts();
+}
+
+
+ADDRESS
+nh6408BusToHostAddr(PCITAG tag, ADDRESS addr)
+{
+ unsigned long addr_l = (unsigned long)addr;
+ int bus = PCI_BUS_FROM_TAG(tag);
+ int pri_bus;
+ struct nh640x_pci_info *infop;
+ unsigned long membase;
+
+ if (!pciBusInfo[bus])
+ FatalError("nh6408BusToHostAddr: pci%d not defined!!\n", bus);
+
+ if (pciBusInfo[bus]->secondary) {
+ pri_bus = pciBusInfo[bus]->primary_bus;
+
+ if (!pciBusInfo[pri_bus])
+ FatalError("nh6408BusToHostAddr: Primary bus pci%d not defined!!\n", pri_bus);
+ }
+ else
+ pri_bus = bus;
+
+ infop = (struct nh640x_pci_info *)pciBusInfo[pri_bus]->pciBusPriv;
+ membase = infop->memBase;
+
+ if (addr_l < 0x10000000)
+ /*
+ * NH6408 host sees PCI memory space addresses 0-0x0fffffff
+ * at the primary PCI buses "memBase" [memBase, memBase+0x0fffffff]
+ */
+ return((ADDRESS)(membase + addr_l));
+
+ else if (addr_l >= 0x80000000)
+ /*
+ * NH6408 host memory addresses 0-0x7fffffff are seen at
+ * 0x80000000-0xffffffff on PCI
+ */
+ return((ADDRESS)(addr_l & 0x7fffffff));
+
+ else
+ /* Other addresses are not valid */
+ FatalError("nh6408BusToHostAddr: Bus address 0x%x not visible to NH6408 host\n",
+ addr_l);
+
+ /*NOTREACHED*/
+}
+
+ADDRESS
+nh6408HostToBusAddr(PCITAG tag, ADDRESS addr)
+{
+ unsigned long addr_l = (unsigned long)addr;
+ int bus = PCI_BUS_FROM_TAG(tag);
+ int pri_bus;
+ struct nh640x_pci_info *infop;
+ unsigned long membase;
+
+ if (!pciBusInfo[bus])
+ FatalError("nh6408HostToBusAddr: pci%d not defined!!\n", bus);
+
+ if (pciBusInfo[bus]->secondary) {
+ pri_bus = pciBusInfo[bus]->primary_bus;
+
+ if (!pciBusInfo[pri_bus])
+ FatalError("nh6408HostToBusAddr: Primary bus pci%d not defined!!\n", pri_bus);
+ }
+ else
+ pri_bus = bus;
+
+ infop = (struct nh640x_pci_info *)pciBusInfo[pri_bus]->pciBusPriv;
+ membase = infop->memBase;
+
+ if (addr_l < 0x80000000)
+ /*
+ * NH6408 host memory addresses 0-0x7fffffff are seen at
+ * 0x80000000-0xffffffff on PCI
+ */
+ return((ADDRESS)(addr_l | 0x80000000));
+
+ else if (addr_l >= membase && addr_l < (membase + 0x10000000))
+ /*
+ * NH6408 host sees PCI memory space addresses 0-0x0fffffff
+ * at the primary PCI buses "memBase" [memBase, memBase+0x0fffffff]
+ */
+ return((ADDRESS)(addr_l - membase));
+
+ else
+ /* Other addresses are not valid */
+ FatalError("nh6408HostToBusAddr: Host address 0x%x not visible to pci%d\n",
+ addr_l, bus);
+
+ /*NOTREACHED*/
+}
+
+/*
+ * NH6800 (Turbo) support
+ */
+void
+nh6800tPciInit(void)
+{
+ FatalError("nh6800tPciInit: NH6800TURBO not supported (yet)!!!\n");
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_ppc.c b/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_ppc.c
new file mode 100644
index 000000000..886d68133
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_ppc.c
@@ -0,0 +1,247 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/pmax/pmax_ppc.c,v 1.3 1998/07/25 16:56:56 dawes Exp $ */
+/*
+ * Copyright 1998 by Concurrent Computer Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Concurrent Computer
+ * Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Concurrent Computer Corporation makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * CONCURRENT COMPUTER CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CONCURRENT COMPUTER CORPORATION BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Copyright 1998 by Metro Link Incorporated
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Metro Link
+ * Incorporated not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Metro Link Incorporated makes no representations
+ * about the suitability of this software for any purpose. It is
+ * provided "as is" without express or implied warranty.
+ *
+ * METRO LINK INCORPORATED DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL METRO LINK INCORPORATED 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 <sys/types.h>
+#include <errno.h>
+
+#include <sys/prosrfs.h>
+#include <sys/cpu.h>
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+volatile unsigned char *ioBase = MAP_FAILED; /* Also referenced by compiler.h */
+unsigned long ioSize = 0;
+
+#undef outb
+#undef outw
+#undef outl
+#undef inb
+#undef inw
+#undef inl
+
+void
+outb(unsigned int a, unsigned char b)
+{
+ if (ioBase == MAP_FAILED) {
+ ErrorF("outb(0x%04X, 0x%02X) fails. Uninitialized ioBase\n", a, b);
+ return;
+ }
+
+ *((volatile unsigned char *)(ioBase + a)) = b; eieio();
+}
+
+void
+outw(unsigned int a, unsigned short w)
+{
+ if (ioBase == MAP_FAILED) {
+ ErrorF("outw(0x%04X, 0x%04X) fails. Unitialized ioBase\n", a, w);
+ return;
+ }
+
+ stw_brx(w,ioBase,a); eieio();
+}
+
+void
+outl(unsigned int a, unsigned long l)
+{
+ if (ioBase == MAP_FAILED) {
+ ErrorF("outl(0x%04X, 0x%08X) fails. Unitialized ioBase\n", a, l);
+ return;
+ }
+
+ stl_brx(l,ioBase,a); eieio();
+}
+
+unsigned char
+inb(unsigned int a)
+{
+ unsigned char b;
+
+ if (ioBase == MAP_FAILED) {
+ FatalError("%s(0x%04X) fails. Unitialized ioBase\n", "inb", a);
+ /*NOTREACHED*/
+ }
+
+ b = *((volatile unsigned char *)(ioBase + a));
+
+ return(b);
+}
+
+unsigned short
+inw(unsigned int a)
+{
+ unsigned short w;
+
+ if (ioBase == MAP_FAILED) {
+ FatalError("%s(0x%04X) fails. Unitialized ioBase\n", "inw", a);
+ /*NOTREACHED*/
+ }
+
+ w = ldw_brx(ioBase,a);
+ return(w);
+}
+
+unsigned long
+inl(unsigned int a)
+{
+ unsigned long l;
+
+ if (ioBase == MAP_FAILED) {
+ FatalError("%s(0x%04X) fails. Unitialized ioBase\n", "inl", a);
+ /*NOTREACHED*/
+ }
+
+ l = ldl_brx(ioBase, a);
+ return(l);
+}
+
+#ifdef PPCIO_DEBUG
+
+void
+debug_outb(unsigned int a, unsigned char b, int line, char *file)
+{
+ if (xf86Verbose > 3)
+ ErrorF("outb(0x%04X, 0x%02X) at line %d, file \"%s\"\n", a, b, line, file);
+
+ outb(a,b);
+}
+
+void
+debug_outw(unsigned int a, unsigned short w, int line, char *file)
+{
+ if (xf86Verbose > 3)
+ ErrorF("outw(0x%04X, 0x%04X) at line %d, file \"%s\"\n", a, w, line, file);
+
+ outw(a,w);
+}
+
+void
+debug_outl(unsigned int a, unsigned long l, int line, char *file)
+{
+ if (xf86Verbose > 3)
+ ErrorF("outl(0x%04X, 0x%08X) at line %d, file \"%s\"\n", a, l, line, file);
+
+ outl(a,l);
+}
+
+
+unsigned char
+debug_inb(unsigned int a, int line, char *file)
+{
+ unsigned char b;
+
+ if (xf86Verbose > 4)
+ ErrorF("Calling %s(0x%04x) at line %d, file \"%s\" ...\n", "inb", a, line, file);
+
+ b = inb(a);
+
+ if (xf86Verbose > 3)
+ ErrorF("... %s(0x%04X) returns 0x%02X\n", "inb", a, b);
+
+ return(b);
+}
+
+unsigned short
+debug_inw(unsigned int a, int line, char *file)
+{
+ unsigned short w;
+
+ if (xf86Verbose > 4)
+ ErrorF("Calling %s(0x%04x) at line %d, file \"%s\" ...\n", "inw", a, line, file);
+
+ w = inw(a);
+
+ if (xf86Verbose > 3)
+ ErrorF("... %s(0x%04X) returns 0x%04X\n", "inw", a, w);
+
+ return(w);
+}
+
+unsigned long
+debug_inl(unsigned int a, int line, char *file)
+{
+ unsigned long l;
+
+ if (xf86Verbose > 4)
+ ErrorF("Calling %s(0x%04x) at line %d, file \"%s\" ...\n", "inl", a, line, file);
+
+ l = inl(a);
+
+ if (xf86Verbose > 3)
+ ErrorF("... %s(0x%04X) returns 0x%08X\n", "inl", a, l);
+
+ return(l);
+}
+
+#endif /* PPCIO_DEBUG */
+
+/*
+ * This is neccessary on the PPC 604 (and 604e) because they have
+ * separate I and D caches and the caches must be manually synchronized
+ * when applying relocation to the instruction portion of loaded modules.
+ */
+#define LINESIZE 32
+#define CACHE_LINE(a) (((unsigned long)a) & ~(LINESIZE-1))
+
+void
+ppc_flush_icache(char *addr)
+{
+ /* Flush D-cache to memory */
+ __inst_dcbf (addr, 0);
+ __inst_dcbf (addr, LINESIZE);
+ __inst_sync ();
+
+ /* Invalidate I-cache */
+ __inst_icbi (addr, 0);
+ __inst_icbi (addr, LINESIZE);
+ __inst_sync ();
+ __inst_isync ();
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sco/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/sco/Imakefile
new file mode 100644
index 000000000..35a86f41e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sco/Imakefile
@@ -0,0 +1,38 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sco/Imakefile,v 3.4 1999/04/04 00:20:59 dawes Exp $
+
+
+
+
+XCOMM $XConsortium: Imakefile /main/4 1996/09/28 17:24:25 rws $
+
+#include <Server.tmpl>
+
+SRCS = sco_init.c sco_video.c sco_io.c bios_devmem.c mapVT_noop.c VTsw_sco.c \
+ sysv_kbd.c std_kbdEv.c sysv_tty.c std_mseEv.c sco_mouse.c \
+ libc_wrapper.c stdResource.c
+
+OBJS = sco_init.o sco_video.o sco_io.o bios_devmem.o mapVT_noop.o VTsw_sco.o \
+ sysv_kbd.o std_kbdEv.o sysv_tty.o std_mseEv.o sco_mouse.o \
+ libc_wrapper.o stdResource.o
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC)
+
+RESDEFINES = -DUSESTDRES
+
+DEFINES = $(RESDEFINES)
+
+SubdirLibraryRule($(OBJS))
+NormalLibraryObjectRule()
+
+LinkSourceFile(bios_devmem.c,../shared)
+LinkSourceFile(mapVT_noop.c,../shared)
+LinkSourceFile(sysv_kbd.c,../shared)
+LinkSourceFile(std_kbdEv.c,../shared)
+LinkSourceFile(sysv_tty.c,../shared)
+LinkSourceFile(std_mseEv.c,../shared)
+LinkSourceFile(libc_wrapper.c,../shared)
+LinkSourceFile(stdResource.c,../shared)
+
+DependTarget()
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sco/VTsw_sco.c b/xc/programs/Xserver/hw/xfree86/os-support/sco/VTsw_sco.c
new file mode 100644
index 000000000..7f398c601
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sco/VTsw_sco.c
@@ -0,0 +1,95 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sco/VTsw_sco.c,v 1.2 1998/07/25 16:56:57 dawes Exp $ */
+/*
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ * Copyright 1993 by David McCullough <davidm@stallion.oz.au>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of David Wexelblat not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Wexelblat makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: VTsw_sco.c /main/2 1995/11/13 06:08:36 kaleb $ */
+
+#include "X.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+/*
+ * Handle the VT-switching interface for SCO
+ */
+
+/*
+ * This function is the signal handler for the VT-switching signal. It
+ * is only referenced inside the OS-support layer.
+ */
+void
+xf86VTRequest(int sig)
+{
+ signal(sig, (void(*)())xf86VTRequest);
+ xf86Info.vtRequestsPending = TRUE;
+ return;
+}
+
+Bool
+xf86VTSwitchPending()
+{
+ return(xf86Info.vtRequestsPending ? TRUE : FALSE);
+}
+
+Bool
+xf86VTSwitchAway()
+{
+ xf86Info.vtRequestsPending = FALSE;
+ if (ioctl(xf86Info.consoleFd, VT_RELDISP, 1) < 0)
+ {
+ return(FALSE);
+ }
+ else
+ {
+ return(TRUE);
+ }
+}
+
+Bool
+xf86VTSwitchTo()
+{
+ xf86Info.vtRequestsPending = FALSE;
+ if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ) < 0)
+ {
+ return(FALSE);
+ }
+ else
+ {
+ /*
+ * make sure the console driver thinks the console is in
+ * graphics mode. Under mono we have to do the two as the
+ * console driver only allows valid modes for the current
+ * video card and Herc or vga are the only devices currently
+ * supported.
+ */
+ if (ioctl(xf86Info.consoleFd, SW_VGA12, 0) < 0)
+ if (ioctl(xf86Info.consoleFd, SW_HGC_P0, 0) < 0)
+ {
+ ErrorF("Failed to set graphics mode : %s\n",
+ strerror(errno));
+ }
+
+ return(TRUE);
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sco/sco_init.c b/xc/programs/Xserver/hw/xfree86/os-support/sco/sco_init.c
new file mode 100644
index 000000000..bddb49bce
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sco/sco_init.c
@@ -0,0 +1,249 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sco/sco_init.c,v 3.11 1998/07/25 16:56:57 dawes Exp $ */
+/*
+ * Copyright 1993 by David McCullough <davidm@stallion.oz.au>
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of David McCullough and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. David McCullough and
+ * David Wexelblat makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * DAVID MCCULLOUGH AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL DAVID MCCULLOUGH OR DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: sco_init.c /main/7 1996/10/25 11:38:01 kaleb $ */
+
+#include "X.h"
+#include "Xmd.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+static Bool KeepTty = FALSE;
+static int VTnum = -1;
+static int sco_console_mode = -1;
+
+void
+xf86OpenConsole()
+{
+ int fd,wc;
+ struct vt_mode VT;
+ struct stat status;
+ char vtname[11];
+
+ if (serverGeneration == 1)
+ {
+ /* check if we're run with euid==0 */
+ if (geteuid() != 0)
+ {
+ FatalError("xf86OpenConsole: Server must be suid root\n");
+ }
+
+ /*
+ * setup the virtual terminal manager
+ *
+ * SCO vts start at tty01 which is vt00, if you could call them VT's.
+ * We use the numbers 1..X as it fits nicer with the device naming
+ * scheme.
+ *
+ * In os/osinit.c we took the precuation of not closing stdin so that
+ * we can use the current vt if no vt was specified on the command line
+ *
+ * Under SCO VT_OPENQRY does nothing at all
+ * if nothing was specified we try to determine the VT from stdin
+ */
+ if ((VTnum != -1) && (VTnum != 0))
+ {
+ wc = VTnum - 1;
+ }
+ else
+ {
+ if ((fstat(0, &status) >= 0) && (status.st_mode & S_IFCHR))
+ {
+ wc = minor(status.st_rdev);
+ }
+ else
+ {
+ ErrorF("%s: Failed to stat stdin, using tty02 (%s)\n",
+ "xf86OpenConsole", strerror(errno));
+ wc = 1; /* tty02 */
+ }
+ }
+ ErrorF("(using VT number %d)\n\n", wc + 1);
+
+ sprintf(vtname,"/dev/tty%02d", wc+1); /* /dev/tty[01-12] */
+
+ if ((xf86Info.consoleFd = open(vtname, O_RDWR | O_NDELAY, 0)) < 0)
+ {
+ FatalError("xf86OpenConsole: Cannot open %s (%s)\n",
+ vtname, strerror(errno));
+ }
+
+ /* now we can dispose of stdin */
+
+ if (freopen(vtname, "r+", stdin) == (FILE *) NULL)
+ {
+ FatalError("xf86OpenConsole: Cannot reopen stdin as %s (%s)\n",
+ vtname, strerror(errno));
+ }
+
+ /* now we can fixup stdout */
+
+ if (freopen(vtname, "r+", stdout) == (FILE *) NULL)
+ {
+ FatalError("xf86OpenConsole: Cannot reopen stdout as %s (%s)\n",
+ vtname, strerror(errno));
+ }
+
+ /* We activate the console just in case its not the one we are on */
+ xf86Info.vtno = wc;
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, wc) != 0)
+ {
+ ErrorF("xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+
+ if (!KeepTty)
+ {
+ setpgrp();
+ }
+
+ /*
+ * now get the VT
+ */
+ if ((sco_console_mode = ioctl(xf86Info.consoleFd, CONS_GET, 0L)) < 0)
+ {
+ FatalError("xf86OpenConsole: VT_GETMODE failed on console (%s)\n",
+ strerror(errno));
+ }
+ if (ioctl(xf86Info.consoleFd, VGA_IOPRIVL, 1) < 0)
+ {
+ FatalError("xf86OpenConsole: VGA_IOPRIVL failed for VGA acc (%s)\n",
+ strerror(errno));
+ }
+ if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
+ {
+ FatalError("xf86OpenConsole: VT_GETMODE failed (%s)\n",
+ strerror(errno));
+ }
+
+ signal(SIGUSR1, xf86VTRequest);
+
+ VT.mode = VT_PROCESS;
+ VT.relsig = SIGUSR1;
+ VT.acqsig = SIGUSR1;
+ VT.frsig = SIGUSR1;
+ VT.waitv = 0;
+ if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
+ {
+ FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n");
+ }
+ /*
+ * make sure the console driver thinks the console is in graphics
+ * mode. Under mono we have to do the two as the console driver only
+ * allows valid modes for the current video card and Herc or vga are
+ * the only devices currently supported.
+ */
+ if (ioctl(xf86Info.consoleFd, SW_VGA12, 0) < 0)
+ if (ioctl(xf86Info.consoleFd, SW_HGC_P0, 0) < 0)
+ {
+ ErrorF("Failed to set graphics mode (%s)\n",
+ strerror(errno));
+ }
+
+ }
+ else
+ {
+ /* serverGeneration != 1 */
+ /*
+ * now get the VT
+ */
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ {
+ ErrorF("xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+ }
+ return;
+}
+
+void
+xf86CloseConsole()
+{
+ struct vt_mode VT;
+
+ ioctl(xf86Info.consoleFd, VT_RELDISP, 1);
+ if (sco_console_mode != -1)
+ {
+ ioctl(xf86Info.consoleFd, MODESWITCH | sco_console_mode, 0L);
+ }
+ if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1)
+ {
+ VT.mode = VT_AUTO;
+ ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* set dflt vt handling */
+ }
+ close(xf86Info.consoleFd); /* make the vt-manager happy */
+ return;
+}
+
+int
+xf86ProcessArgument(int argc, char *argv[], int i)
+{
+ /*
+ * Keep server from detaching from controlling tty. This is useful
+ * when debugging (so the server can receive keyboard signals.
+ */
+ if (!strcmp(argv[i], "-keeptty"))
+ {
+ KeepTty = TRUE;
+ return(1);
+ }
+ if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
+ {
+ if (sscanf(argv[i], "vt%2d", &VTnum) == 0)
+ {
+ UseMsg();
+ VTnum = -1;
+ return(0);
+ }
+ return(1);
+ }
+ if (!strcmp(argv[i], "-crt"))
+ {
+ if ((++i > argc) ||
+ (sscanf(argv[i], "/dev/tty%2d", &VTnum) == 0))
+ {
+ UseMsg();
+ VTnum = -1;
+ return(0);
+ }
+ else
+ {
+ return(2);
+ }
+ }
+ return(0);
+}
+
+void
+xf86UseMsg()
+{
+ ErrorF("vtXX use the specified VT number\n");
+ ErrorF("-crt /dev/ttyXX use the specified VT number\n");
+ ErrorF("-keeptty ");
+ ErrorF("don't detach controlling tty (for debugging only)\n");
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sco/sco_io.c b/xc/programs/Xserver/hw/xfree86/os-support/sco/sco_io.c
new file mode 100644
index 000000000..591115810
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sco/sco_io.c
@@ -0,0 +1,110 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sco/sco_io.c,v 3.6 1999/05/07 02:56:22 dawes Exp $ */
+/*
+ * Copyright 1993 by David McCullough <davidm@stallion.oz.au>
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of David McCullough and David Dawes
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. David McCullough
+ * and David Dawes makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * DAVID MCCULLOUGH AND DAVID DAWES DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL DAVID MCCULLOUGH OR DAVID DAWES 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.
+ *
+ */
+/* $XConsortium: sco_io.c /main/7 1996/10/19 18:07:31 kaleb $ */
+
+#include "X.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+void
+xf86SoundKbdBell(int loudness, int pitch, int duration)
+{
+ if (loudness && pitch)
+ {
+ ioctl(xf86Info.consoleFd, KIOCSOUND, 1193180 / pitch);
+ usleep(duration * loudness * 20);
+ ioctl(xf86Info.consoleFd, KIOCSOUND, 0);
+ }
+}
+
+void
+xf86SetKbdLeds(int leds)
+{
+ /*
+ * sleep the first time through under SCO. There appears to be a
+ * timing problem in the driver which causes the keyboard to be lost.
+ * This sleep stops it from occurring. The sleep could proably be
+ * a lot shorter as even trace can fix the problem. You may
+ * prefer a usleep(100).
+ */
+ static int once = 1;
+
+ if (once)
+ {
+ sleep(1);
+ once = 0;
+ }
+ ioctl(xf86Info.consoleFd, KDSETLED, leds );
+}
+
+void
+xf86MouseInit(MouseDevPtr mouse)
+{
+ if ((mouse->mseFd = open(mouse->mseDevice, O_RDWR | O_NDELAY)) < 0)
+ {
+ if (xf86Info.allowMouseOpenFail) {
+ ErrorF("Cannot open mouse (%s) - Continuing...\n",
+ strerror(errno));
+ return;
+ }
+ FatalError("Cannot open mouse (%s)\n", strerror(errno));
+ }
+}
+
+int
+xf86MouseOn(MouseDevPtr mouse)
+{
+ xf86SetupMouse(mouse);
+
+ /* Flush any pending input */
+ ioctl(mouse->mseFd, TCFLSH, 0);
+
+ return(mouse->mseFd);
+}
+
+int
+xf86MouseOff(MouseDevPtr mouse, Bool doclose)
+{
+ if (mouse->mseFd >= 0)
+ {
+ if (mouse->mseType == P_LOGI)
+ {
+ write(mouse->mseFd, "U", 1);
+ xf86SetMouseSpeed(mouse, mouse->baudRate,
+ mouse->oldBaudRate,
+ xf86MouseCflags[P_LOGI]);
+ }
+ if (doclose)
+ {
+ close(mouse->mseFd);
+ }
+ }
+ return(mouse->mseFd);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sco/sco_mouse.c b/xc/programs/Xserver/hw/xfree86/os-support/sco/sco_mouse.c
new file mode 100644
index 000000000..355fb838c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sco/sco_mouse.c
@@ -0,0 +1,193 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sco/sco_mouse.c,v 3.11 1999/01/14 13:05:09 dawes Exp $ */
+
+
+
+
+
+/* $XConsortium: sco_mouse.c /main/6 1996/10/23 11:46:17 kaleb $ */
+
+/******************************************************************************/
+
+#include "X.h"
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+/******************************************************************************/
+#ifdef USE_OSMOUSE
+/******************************************************************************/
+
+#include <sys/event.h>
+#include <mouse.h>
+#include "xf86Config.h"
+
+static dmask_t real_mask = (dmask_t) (D_REL | D_BUTTON);
+static int config_buttons = 0;
+
+extern int miPointerGetMotionEvents(DeviceIntPtr pPtr, xTimecoord *coords,
+ unsigned long start, unsigned long stop,
+ ScreenPtr pScreen);
+
+/******************************************************************************/
+/*
+ * Handle any XF86Config options for "OsMouse", How you treat errors
+ * is up to you, they may or may not be Fatal
+ */
+
+void
+xf86OsMouseOption(int lt, pointer lp)
+{
+ if (lt != NUMBER) {
+ ErrorF("%s: Invalid Argument to OsMouse, %s\n",
+ "xf86OsMouseOption", "Number of buttons expected");
+ return;
+ }
+ config_buttons = ((LexPtr)lp)->num;
+}
+
+/******************************************************************************/
+/*
+ * xf86OsMouseProc --
+ * Handle the initialization, etc. of a mouse
+ */
+
+int
+xf86OsMouseProc(DeviceIntPtr pPointer, int what)
+{
+ unchar *map;
+ int i, err, buttons;
+ struct devinfo *dip;
+ dmask_t dmask;
+
+ switch (what) {
+ case DEVICE_INIT:
+
+ pPointer->public.on = FALSE;
+
+ if (ev_init() < 0)
+ ErrorF("ev_init: Failed to initialize event driver\n");
+
+ dmask = real_mask;
+ xf86Info.mouseDev->mseFd = ev_open(&dmask);
+ switch (xf86Info.mouseDev->mseFd) {
+ case -1: FatalError("ev_open: Error in Configuration files\n");
+ case -2: FatalError("ev_open: No mouse devices to attach\n");
+ case -3: FatalError("ev_open: Unable to open a found device\n");
+ case -4: FatalError("ev_open: unable to open an event queue\n");
+ default:
+ if (xf86Info.mouseDev->mseFd < 0)
+ FatalError("ev_open: Failed to open device, reason unkown\n");
+ break;
+ }
+ if (dmask != real_mask)
+ FatalError("Could not attach the mouse device (0x%x)\n", dmask);
+
+ dip = (struct devinfo *) NULL;
+ if ((dip = ev_getdev(D_REL, dip)) == (struct devinfo *) NULL)
+ FatalError("Could not find info on mouse device\n");
+
+ buttons = config_buttons > 0 ? config_buttons : ((int) dip->buttons);
+ buttons = buttons > 0 ? buttons : 3; /* just in case */
+
+#ifdef XCONFIG_GIVEN
+ ErrorF("%s OsMouse has %d buttons\n",
+ buttons == config_buttons ? XCONFIG_GIVEN : XCONFIG_PROBED,
+ buttons);
+#endif
+
+ map = xalloc(buttons + 1);
+ if (map == (unchar *) NULL)
+ FatalError("Failed to allocate OsMouse map structure\n");
+
+ for (i = 1; i <= buttons; i++)
+ map[i] = i;
+
+ InitPointerDeviceStruct((DevicePtr)pPointer,
+ map,
+ buttons,
+ miPointerGetMotionEvents,
+ (PtrCtrlProcPtr)xf86MseCtrl,
+ 0);
+ xfree(map);
+
+#ifdef XINPUT
+ InitValuatorAxisStruct(pPointer,
+ 0,
+ 0, /* min val */
+ screenInfo.screens[0]->width, /* max val */
+ 1, /* resolution */
+ 0, /* min_res */
+ 1); /* max_res */
+ InitValuatorAxisStruct(pPointer,
+ 1,
+ 0, /* min val */
+ screenInfo.screens[0]->height, /* max val */
+ 1, /* resolution */
+ 0, /* min_res */
+ 1); /* max_res */
+ /*
+ * Initialize valuator values in synch
+ * with dix/event.c DefineInitialRootWindow
+ */
+ *pPointer->valuator->axisVal = screenInfo.screens[0]->width / 2;
+ *(pPointer->valuator->axisVal+1) = screenInfo.screens[0]->height / 2;
+#endif
+
+ ev_suspend(); /* suspend device until its turned on */
+ break;
+
+ case DEVICE_ON:
+ ev_resume();
+ AddEnabledDevice(xf86Info.mouseDev->mseFd);
+ xf86Info.mouseDev->lastButtons = 0;
+ xf86Info.mouseDev->emulateState = 0;
+ pPointer->public.on = TRUE;
+ break;
+
+ case DEVICE_CLOSE:
+ case DEVICE_OFF:
+ pPointer->public.on = FALSE;
+ RemoveEnabledDevice(xf86Info.mouseDev->mseFd);
+ if (what == DEVICE_CLOSE) {
+ ev_close();
+ xf86Info.mouseDev->mseFd = -1;
+ } else
+ ev_suspend();
+ break;
+ }
+
+ return Success;
+}
+
+/******************************************************************************/
+/*
+ * xf86OsMouseEvents --
+ * Get some events from our queue. Process all outstanding events now.
+ */
+
+void
+xf86OsMouseEvents()
+{
+ EVENT *evp;
+ static long time = -1;
+
+ while ((evp = ev_read()) != (EVENT *) NULL ) {
+#if DEBUG
+ if (time == -1)
+ time = EV_TIME(*evp);
+ ErrorF("sco_event time(%ld) tag(%d) butts(%d) x(%ld) y(%ld)\n",
+ EV_TIME(*evp) - time, EV_TAG(*evp), EV_BUTTONS(*evp),
+ EV_DX(*evp), EV_DY(*evp));
+#endif
+ xf86PostMseEvent(xf86Info.pMouse,EV_BUTTONS(*evp), EV_DX(*evp), -(EV_DY(*evp)));
+ ev_pop();
+ }
+
+ xf86Info.inputPending = TRUE;
+}
+
+/******************************************************************************/
+#endif /* USE_OSMOUSE */
+/******************************************************************************/
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sco/sco_video.c b/xc/programs/Xserver/hw/xfree86/os-support/sco/sco_video.c
new file mode 100644
index 000000000..01c8cdad1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sco/sco_video.c
@@ -0,0 +1,278 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sco/sco_video.c,v 3.6 1999/04/18 04:08:54 dawes Exp $ */
+/*
+ * Copyright 1993 by David McCullough <davidm@stallion.oz.au>
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of David McCullough and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. David McCullough and
+ * David Wexelblat makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * DAVID MCCULLOUGH AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL DAVID MCCULLOUGH OR DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: sco_video.c /main/4 1996/02/22 10:46:34 kaleb $ */
+
+#include "X.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#define _NEED_SYSI86
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+/***************************************************************************/
+/* Video Memory Mapping section */
+/***************************************************************************/
+
+static struct kd_memloc MapDSC[MAXSCREENS][NUM_REGIONS];
+static int ver_once = 1;
+
+/***************************************************************************/
+/*
+ * To map the video-memory, we use the MAP_CLASS ioctl.
+ * Different drivers may have to do another one of these
+ * for their own special registers (ie., ATI). To find
+ * out which strings are valid look in /etc/conf/pack.d/cn/class.h
+ *
+ * if we fail to find one of these we try for the dmmap driver
+ */
+
+struct {
+ unsigned long base, size;
+ char *class;
+} SCO_Mapping[] = {
+ {0xA0000, 0x10000, "VGA"},
+ {0xA0000, 0x20000, "SVGA"},
+ {0xB0000, 0x08000, "HGA"},
+ {0x0, 0x0, ""},
+};
+
+/* ARGSUSED */
+pointer
+xf86MapVidMem(int ScreenNum, int Flags, unsigned long Base, unsigned long Size)
+{
+ int i;
+ char *class = (char *)NULL;
+ pointer base;
+
+ for (i=0; SCO_Mapping[i].base != 0; i++)
+ {
+ if (((pointer)SCO_Mapping[i].base == Base) &&
+ (SCO_Mapping[i].size == Size))
+ {
+ class = SCO_Mapping[i].class;
+ break;
+ }
+ }
+ if (class == (char *)NULL)
+ {
+ int fd;
+
+#if defined(SVR4) || defined(SCO325)
+ if ((fd = open(DEV_MEM, O_RDWR)) < 0)
+ {
+ FatalError("xf86MapVidMem: failed to open %s (%s)\n",
+ DEV_MEM, strerror(errno));
+ }
+ base = (pointer)mmap((caddr_t)0, Size, PROT_READ|PROT_WRITE,
+ MAP_SHARED, fd, (off_t)Base);
+ close(fd);
+ if ((long)base == -1)
+ {
+ FatalError("%s: Could not mmap framebuffer [s=%x,a=%x] (%s)\n",
+ "xf86MapVidMem", Size, Base, strerror(errno));
+ }
+
+ return(base);
+#else
+ MapDSC[ScreenNum][Region].vaddr = (char *) NULL;
+ MapDSC[ScreenNum][Region].physaddr = (char *) Base;
+ MapDSC[ScreenNum][Region].length = Size;
+ MapDSC[ScreenNum][Region].ioflg = 1;
+ if ((fd = open("/dev/dmmap", O_RDWR)) >= 0) {
+ if (ioctl(fd, KDMAPDISP, &MapDSC[ScreenNum][Region]) == -1)
+ ErrorF("xf86MapVidMem: dmmap KDMAPDISP failed (%s)\n",
+ strerror(errno));
+ else {
+ if (ver_once)
+ ErrorF("Using dmmap version 0x%04x.\n",
+ ioctl(fd, -1));
+ ver_once = 0;
+ close(fd);
+ return(MapDSC[ScreenNum][Region].vaddr);
+ }
+ close(fd);
+ }
+ FatalError("xf86MapVidMem:No class map defined for (%x,%x)\n",
+ Base, Size);
+ /* NOTREACHED */
+#endif
+ }
+
+ base = (pointer)ioctl(xf86Info.consoleFd, MAP_CLASS, class);
+ if ((int)base == -1)
+ {
+ FatalError("xf86MapVidMem:Failed to map video mem class %s\n",
+ class);
+ /* NOTREACHED */
+ }
+ return(base);
+}
+
+/*
+ * Nothing to do here if it wasn't mapped using the dmmap driver
+ */
+/* ARGSUSED */
+void
+xf86UnMapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+{
+ int fd;
+
+#if defined (SVR4) || defined(SCO325)
+ munmap(Base, Size);
+#else /* SVR4 */
+ if (MapDSC[ScreenNum][Region].vaddr) {
+ if ((fd = open("/dev/dmmap", O_RDWR)) < 0) {
+ if (ioctl(fd, KDUNMAPDISP, &MapDSC[ScreenNum][Region]) == -1)
+ ErrorF("xf86UnMapVidMem: dmmap KDUNMAPDISP failed (%s)\n",
+ strerror(errno));
+ close(fd);
+ }
+ MapDSC[ScreenNum][Region].vaddr = (char *) NULL;
+ MapDSC[ScreenNum][Region].physaddr = (char *) NULL;
+ MapDSC[ScreenNum][Region].length = 0;
+ MapDSC[ScreenNum][Region].ioflg = 0;
+ }
+#endif
+ return;
+}
+
+/* ARGSUSED */
+Bool xf86LinearVidMem()
+{
+ int fd, ver;
+
+#if defined(SVR4) || defined(SCO325)
+ return TRUE;
+#else
+ if ((fd = open("/dev/dmmap", O_RDWR)) >= 0) {
+ ver = ioctl(fd, -1);
+ close(fd);
+ if (ver >= 0) {
+ if (ver_once)
+ ErrorF("Using dmmap version 0x%04x.\n", ver);
+ ver_once = 0;
+ return(TRUE);
+ }
+ }
+ return(FALSE);
+#endif
+}
+
+/***************************************************************************/
+/* I/O Permissions section */
+/***************************************************************************/
+
+static Bool ScreenEnabled[MAXSCREENS];
+static Bool IOEnabled = FALSE;
+static Bool InitDone = FALSE;
+
+void xf86ClearIOPortList(ScreenNum)
+int ScreenNum;
+{
+ int i;
+
+ if (!InitDone)
+ {
+ for (i = 0; i < MAXSCREENS; i++)
+ ScreenEnabled[i] = FALSE;
+ InitDone = TRUE;
+ }
+}
+
+/* ARGSUSED */
+void xf86AddIOPorts(ScreenNum, NumPorts, Ports)
+int ScreenNum;
+int NumPorts;
+unsigned *Ports;
+{
+}
+
+void xf86EnableIOPorts(ScreenNum)
+int ScreenNum;
+{
+ ScreenEnabled[ScreenNum] = TRUE;
+
+ if (IOEnabled)
+ return;
+
+ if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0)
+ FatalError("Failed to set IOPL for extended I/O\n");
+ IOEnabled = TRUE;
+ return;
+}
+
+void xf86DisableIOPorts(ScreenNum)
+int ScreenNum;
+{
+ int i;
+
+ ScreenEnabled[ScreenNum] = FALSE;
+
+ if (!IOEnabled)
+ return;
+
+ for (i = 0; i < MAXSCREENS; i++)
+ if (ScreenEnabled[i])
+ return;
+ sysi86(SI86V86, V86SC_IOPL, 0);
+ IOEnabled = FALSE;
+ return;
+}
+
+void xf86DisableIOPrivs()
+{
+ if (IOEnabled)
+ sysi86(SI86V86, V86SC_IOPL, 0);
+ return;
+}
+
+/***************************************************************************/
+/* Interrupt Handling section */
+/***************************************************************************/
+
+Bool xf86DisableInterrupts()
+{
+#ifdef __GNUC__
+ __asm__ __volatile__("cli");
+#else
+ asm("cli");
+#endif /* __GNUC__ */
+
+ return(TRUE);
+}
+
+void xf86EnableInterrupts()
+{
+#ifdef __GNUC__
+ __asm__ __volatile__("sti");
+#else
+ asm("sti");
+#endif /* __GNUC__ */
+
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/VTsw_noop.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/VTsw_noop.c
new file mode 100644
index 000000000..265a45f91
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/VTsw_noop.c
@@ -0,0 +1,52 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/VTsw_noop.c,v 3.2 1998/07/25 16:56:59 dawes Exp $ */
+/*
+ * Copyright 1993 by David Wexelblat <dwex@XFree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of David Wexelblat not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Wexelblat makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: VTsw_noop.c /main/3 1996/02/21 17:53:25 kaleb $ */
+
+#include "X.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+/*
+ * No-op functions for OSs without VTs
+ */
+
+Bool
+xf86VTSwitchPending()
+{
+ return(FALSE);
+}
+
+Bool
+xf86VTSwitchAway()
+{
+ return(FALSE);
+}
+
+Bool
+xf86VTSwitchTo()
+{
+ return(TRUE);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/VTsw_usl.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/VTsw_usl.c
new file mode 100644
index 000000000..5128b7804
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/VTsw_usl.c
@@ -0,0 +1,81 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/VTsw_usl.c,v 3.2 1998/07/25 16:56:59 dawes Exp $ */
+/*
+ * Copyright 1993 by David Wexelblat <dwex@XFree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of David Wexelblat not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Wexelblat makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: VTsw_usl.c /main/3 1996/02/21 17:53:28 kaleb $ */
+
+#include "X.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+/*
+ * Handle the VT-switching interface for OSs that use USL-style ioctl()s
+ * (the sysv, sco, and linux subdirs).
+ */
+
+/*
+ * This function is the signal handler for the VT-switching signal. It
+ * is only referenced inside the OS-support layer.
+ */
+void
+xf86VTRequest(int sig)
+{
+ signal(sig, (void(*)())xf86VTRequest);
+ xf86Info.vtRequestsPending = TRUE;
+ return;
+}
+
+Bool
+xf86VTSwitchPending()
+{
+ return(xf86Info.vtRequestsPending ? TRUE : FALSE);
+}
+
+Bool
+xf86VTSwitchAway()
+{
+ xf86Info.vtRequestsPending = FALSE;
+ if (ioctl(xf86Info.consoleFd, VT_RELDISP, 1) < 0)
+ {
+ return(FALSE);
+ }
+ else
+ {
+ return(TRUE);
+ }
+}
+
+Bool
+xf86VTSwitchTo()
+{
+ xf86Info.vtRequestsPending = FALSE;
+ if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ) < 0)
+ {
+ return(FALSE);
+ }
+ else
+ {
+ return(TRUE);
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/bios_devmem.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/bios_devmem.c
new file mode 100644
index 000000000..bbcc665a7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/bios_devmem.c
@@ -0,0 +1,69 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/bios_devmem.c,v 3.6 1999/07/18 08:14:36 dawes Exp $ */
+/*
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of David Wexelblat not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Wexelblat makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: bios_devmem.c /main/5 1996/10/19 18:07:41 kaleb $ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include <string.h>
+
+/*
+ * Read BIOS via /dev/mem.
+ */
+
+#ifndef DEV_MEM
+# define DEV_MEM "/dev/mem"
+#endif
+
+int
+xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf,
+ int Len)
+{
+ int fd;
+
+ if ((fd = open(DEV_MEM, O_RDONLY)) < 0)
+ {
+ xf86Msg(X_WARNING, "xf86ReadBIOS: Failed to open %s (%s)\n",
+ DEV_MEM, strerror(errno));
+ return(-1);
+ }
+
+ if (lseek(fd, (Base+Offset), SEEK_SET) < 0)
+ {
+ xf86Msg(X_WARNING, "xf86ReadBIOS: %s seek failed (%s)\n",
+ DEV_MEM, strerror(errno));
+ close(fd);
+ return(-1);
+ }
+ if (read(fd, Buf, Len) != Len)
+ {
+ xf86Msg(X_WARNING, "xf86ReadBIOS: %s read failed (%s)\n",
+ DEV_MEM, strerror(errno));
+ close(fd);
+ return(-1);
+ }
+ close(fd);
+ return(Len);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/bios_mmap.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/bios_mmap.c
new file mode 100644
index 000000000..96c072c66
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/bios_mmap.c
@@ -0,0 +1,143 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/bios_mmap.c,v 1.4 1999/07/18 08:14:36 dawes Exp $ */
+/*
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of David Wexelblat not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Wexelblat makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: bios_V4mmap.c /main/4 1996/02/21 17:54:27 kaleb $ */
+
+#include "X.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+/*
+ * Read BIOS via mmap()ing DEV_MEM
+ */
+
+#ifndef __alpha__
+int
+xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf,
+ int Len)
+{
+ int fd;
+ unsigned char *ptr;
+ int psize;
+ int mlen;
+
+ if ((fd = open(DEV_MEM, O_RDONLY)) < 0)
+ {
+ xf86Msg(X_WARNING, "xf86ReadBIOS: Failed to open %s (%s)\n",
+ DEV_MEM, strerror(errno));
+ return(-1);
+ }
+ psize = xf86getpagesize();
+ mlen = (Offset + Len + psize - 1) & ~psize;
+ /* Base is assumed to be page-aligned. */
+ ptr = (unsigned char *)mmap((caddr_t)0, mlen, PROT_READ,
+ MAP_SHARED, fd, (off_t)Base);
+ if ((int)ptr == -1)
+ {
+ xf86Msg(X_WARNING, "xf86ReadBIOS: %s mmap failed (%s)\n",
+ DEV_MEM, strerror(errno));
+ close(fd);
+ return(-1);
+ }
+#ifdef DEBUG
+ ErrorF("xf86ReadBIOS: BIOS at 0x%08x has signature 0x%04x\n",
+ Base, ptr[0] | (ptr[1] << 8));
+#endif
+ (void)memcpy(Buf, (void *)(ptr + Offset), Len);
+ (void)munmap((caddr_t)ptr, mlen);
+ (void)close(fd);
+ return(Len);
+}
+
+#else /* __alpha__ */
+
+ /*
+ * We trick "mmap" into mapping BUS memory for us via BUS_BASE,
+ * which is the KSEG address of the start of the DENSE memory
+ * area.
+ */
+
+ /*
+ * NOTE: there prolly ought to be more validity checks and all
+ * re: boundaries and sizes and such...
+ */
+
+/*
+ * The Jensen lacks dense memory, thus we have to address the bus via
+ * the sparse addressing scheme.
+ *
+ * Martin Ostermann (ost@comnets.rwth-aachen.de) - Apr.-Sep. 1996
+ */
+
+#ifdef TEST_JENSEN_CODE /* define to test the Sparse addressing on a non-Jensen */
+#define SPARSE (5)
+#define isJensen (1)
+#else
+#define isJensen (!_bus_base())
+#define SPARSE (7)
+#endif
+
+extern unsigned long _bus_base(void);
+extern unsigned long _bus_base_sparse(void);
+#define BUS_BASE (isJensen ? _bus_base_sparse() : _bus_base())
+#define JENSEN_SHIFT(x) (isJensen ? ((long)x<<SPARSE) : (long)x)
+
+int
+xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf,
+ int Len)
+{
+ caddr_t base;
+ int fd;
+ int psize;
+ int mlen;
+
+ if ((fd = open(DEV_MEM, O_RDONLY)) < 0)
+ {
+ xf86Msg(X_WARNING, "xf86ReadBIOS: Failed to open %s (%s)\n",
+ DEV_MEM, strerror(errno));
+ return(-1);
+ }
+
+ psize = xf86getpagesize();
+ mlen = (Offset + Len + psize - 1) & ~psize;
+ /* Base is assumed to be page-aligned. */
+ base = mmap((caddr_t)0, JENSEN_SHIFT(mlen), PROT_READ,
+ MAP_SHARED, fd, (off_t)(JENSEN_SHIFT(Base) + BUS_BASE));
+
+ if (base == (caddr_t)-1UL)
+ {
+ xf86Msg(X_WARNING, "xf86ReadBIOS: Failed to mmap %s (%s)\n",
+ DEV_MEM, strerror(errno));
+ return(-1);
+ }
+
+ xf86SlowBCopyFromBus(base+JENSEN_SHIFT(Offset), Buf, Len);
+
+ munmap((caddr_t)JENSEN_SHIFT(base), JENSEN_SHIFT(mlen));
+ close(fd);
+ return(Len);
+}
+
+#endif /* __alpha__ */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/inout.S b/xc/programs/Xserver/hw/xfree86/os-support/shared/inout.S
new file mode 100644
index 000000000..80c47c419
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/inout.S
@@ -0,0 +1,111 @@
+/* $XConsortium: inout.s /main/6 1996/02/21 17:53:35 kaleb $ */
+
+
+
+
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/inout.S,v 1.1 1999/07/10 07:24:52 dawes Exp $ */
+
+#include "assyntax.h"
+
+/*
+ * Make i80386 io primitives available at C-level.
+ */
+
+ FILE("inout.s")
+ AS_BEGIN
+ SEG_TEXT
+
+/*
+ *-----------------------------------------------------------------------
+ * inb ---
+ * Input one byte.
+ *
+ * Results:
+ * Byte in al.
+ *-----------------------------------------------------------------------
+ */
+ GLOBL GLNAME(inb)
+GLNAME(inb):
+ MOV_L (REGOFF(4,ESP),EDX)
+ SUB_L (EAX,EAX)
+ IN_B
+ RET
+
+/*
+ *-----------------------------------------------------------------------
+ * outb ---
+ * Output one byte.
+ *
+ * Results:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+ GLOBL GLNAME(outb)
+GLNAME(outb):
+ MOV_L (REGOFF(4,sp),EDX)
+ MOV_L (REGOFF(8,sp),EAX)
+ OUT_B
+ RET
+/*
+ *-----------------------------------------------------------------------
+ * inw ---
+ * Input one 16-bit word.
+ *
+ * Results:
+ * Word in ax.
+ *-----------------------------------------------------------------------
+ */
+ GLOBL GLNAME(inw)
+GLNAME(inw):
+ MOV_L (REGOFF(4,ESP),EDX)
+ IN_W
+ RET
+
+/*
+ *-----------------------------------------------------------------------
+ * outw ---
+ * Output one 16-bit word.
+ *
+ * Results:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+ GLOBL GLNAME(outw)
+GLNAME(outw):
+ MOV_L (REGOFF(4,ESP),EDX)
+ MOV_L (REGOFF(8,ESP),EAX)
+ OUT_W
+ RET
+
+/*
+ *-----------------------------------------------------------------------
+ * inl ---
+ * Input one 32-bit longword.
+ *
+ * Results:
+ * Word in eax.
+ *-----------------------------------------------------------------------
+ */
+ GLOBL GLNAME(inl)
+GLNAME(inl):
+ MOV_L (REGOFF(4,ESP),EDX)
+ IN_L
+ RET
+
+/*
+ *-----------------------------------------------------------------------
+ * outl ---
+ * Output one 32-bit longword.
+ *
+ * Results:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+ GLOBL GLNAME(outl)
+GLNAME(outl):
+ MOV_L (REGOFF(4,ESP),EDX)
+ MOV_L (REGOFF(8,ESP),EAX)
+ OUT_L
+ RET
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/ioperm_noop.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/ioperm_noop.c
new file mode 100644
index 000000000..2406a99d5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/ioperm_noop.c
@@ -0,0 +1,47 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/ioperm_noop.c,v 3.3 1998/07/25 16:57:00 dawes Exp $ */
+/*
+ * Copyright 1993 by David Wexelblat <dwex@XFree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of David Wexelblat not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Wexelblat makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: ioperm_noop.c /main/3 1996/02/21 17:53:39 kaleb $ */
+
+/*
+ * Amoeba, Minix and 386BSD don't bother with I/O permissions,
+ * or the permissions are implicit with opening/enabling the console.
+ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+void
+xf86EnableIO()
+{
+ return;
+}
+
+void
+xf86DisableIO()
+{
+ return;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/libc_wrapper.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/libc_wrapper.c
new file mode 100644
index 000000000..fff14b70c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/libc_wrapper.c
@@ -0,0 +1,1746 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/libc_wrapper.c,v 1.52 1999/07/18 08:14:37 dawes Exp $ */
+/*
+ * Copyright 1997 by The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Orest Zborowski and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Orest Zborowski
+ * and David Wexelblat make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THE XFREE86 PROJECT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID WEXELBLAT 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 <Xmd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#if defined(__bsdi__)
+#undef _POSIX_SOURCE
+#undef _ANSI_SOURCE
+#endif
+#include <sys/time.h>
+#if defined(__bsdi__)
+#define _POSIX_SOURCE
+#define _ANSI_SOURCE
+#endif
+#include <math.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include "Xfuncproto.h"
+#include "os.h"
+#include <stdarg.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#ifdef __EMX__
+#define NO_MMAP
+#endif
+#ifdef HAS_SVR3_MMAPDRV
+#define NO_MMAP
+#ifdef SELF_CONTAINED_WRAPPER
+#include <sys/at_ansi.h>
+#include <sys/kd.h>
+#include <sys/sysmacros.h>
+#if !defined(_NEED_SYSI86)
+# include <sys/immu.h>
+# include <sys/region.h>
+#endif
+#include <sys/mmap.h>
+struct kd_memloc MapDSC;
+int mmapFd = -2;
+#else
+extern struct kd_memloc MapDSC;
+extern int mmapFd;
+#endif
+#endif
+#ifndef NO_MMAP
+#include <sys/mman.h>
+#ifndef MAP_FAILED
+#define MAP_FAILED ((caddr_t)-1)
+#endif
+#endif
+#if !defined(ISC)
+#include <stdlib.h>
+#endif
+
+#define NEED_XF86_TYPES
+#define DONT_DEFINE_WRAPPERS
+#include "xf86_ansic.h"
+
+#ifndef SELF_CONTAINED_WRAPPER
+#include "xf86.h"
+#include "xf86Priv.h"
+#define NO_OSLIB_PROTOTYPES
+#define XF86_OS_PRIVS
+#define HAVE_WRAPPER_DECLS
+#include "xf86_OSlib.h"
+#else
+void xf86WrapperInit(void);
+#endif
+
+
+#ifndef X_NOT_POSIX
+#include <dirent.h>
+#else
+#ifdef SYSV
+#include <dirent.h>
+#else
+#ifdef USG
+#include <dirent.h>
+#else
+#include <sys/dir.h>
+#ifndef dirent
+#define dirent direct
+#endif
+#endif
+#endif
+#endif
+typedef struct dirent DIRENTRY;
+
+#ifdef __EMX__
+#define _POSIX_SOURCE
+#endif
+#ifdef ISC202
+#include <sys/types.h>
+#define WIFEXITED(a) ((a & 0x00ff) == 0) /* LSB will be 0 */
+#define WEXITSTATUS(a) ((a & 0xff00) >> 8)
+#define WIFSIGNALED(a) ((a & 0xff00) == 0) /* MSB will be 0 */
+#define WTERMSIG(a) (a & 0x00ff)
+#else
+#if defined(ISC) && !defined(_POSIX_SOURCE)
+#define _POSIX_SOURCE
+#include <sys/types.h>
+#include <sys/wait.h>
+#undef _POSIX_SOURCE
+#else
+#if defined(MINIX) || defined(AMOEBA) || (defined(ISC) && defined(_POSIX_SOURCE)) || defined(Lynx) || (defined (__alpha__) && defined(linux))
+#include <sys/types.h>
+#endif
+#include <sys/wait.h>
+#endif
+#endif
+#ifdef Lynx
+#if !defined(S_IFIFO) && defined(S_IFFIFO)
+#define S_IFIFO S_IFFIFO
+#endif
+#endif
+
+/* For xf86getpagesize() */
+#if defined(linux)
+#include <asm/page.h>
+#define HAS_SC_PAGESIZE
+#define HAS_GETPAGESIZE
+#elif defined(CSRG_BASED)
+#define HAS_GETPAGESIZE
+#elif defined(DGUX)
+#define HAS_GETPAGESIZE
+#elif defined(sun) && !defined(SVR4)
+#define HAS_GETPAGESIZE
+#endif
+#ifdef XNO_SYSCONF
+#undef _SC_PAGESIZE
+#endif
+
+
+#if 0
+#define SETBUF_RETURNS_INT
+#endif
+
+double xf86HUGE_VAL;
+
+#ifndef SELF_CONTAINED_WRAPPERS
+extern void xf86DisableIO(void);
+#endif
+
+/*
+ * This file contains the XFree86 wrappers for libc functions that can be
+ * called by loadable modules
+ */
+
+double
+xf86hypot(double x, double y)
+{
+ return(hypot(x,y));
+}
+
+/* string functions */
+
+char*
+xf86strcat(char* dest, const char* src)
+{
+ return(strcat(dest,src));
+}
+
+char*
+xf86strchr(const char* s, int c)
+{
+ return strchr(s,c);
+}
+
+int
+xf86strcmp(const char* s1, const char* s2)
+{
+ return strcmp(s1,s2);
+}
+
+/* Just like the BSD version. It assumes that tolower() is ANSI-compliant */
+int
+xf86strcasecmp(const char* s1, const char* s2)
+{
+ const unsigned char *us1 = (const unsigned char *)s1;
+ const unsigned char *us2 = (const unsigned char *)s2;
+
+ while (tolower(*us1) == tolower(*us2++))
+ if (*us1++ == '\0')
+ return 0;
+
+ return tolower(*us1) - tolower(*--us2);
+}
+
+char*
+xf86strcpy(char* dest, const char* src)
+{
+ return strcpy(dest,src);
+}
+
+xf86size_t
+xf86strcspn(const char* s1, const char* s2)
+{
+ return (xf86size_t)strcspn(s1,s2);
+}
+
+xf86size_t
+xf86strlen(const char* s)
+{
+ return (xf86size_t)strlen(s);
+}
+
+char*
+xf86strncat(char* dest, const char* src, xf86size_t n)
+{
+ return strncat(dest,src,(size_t)n);
+}
+
+int
+xf86strncmp(const char* s1, const char* s2, xf86size_t n)
+{
+ return strncmp(s1,s2,(size_t)n);
+}
+
+/* Just like the BSD version. It assumes that tolower() is ANSI-compliant */
+int
+xf86strncasecmp(const char* s1, const char* s2, xf86size_t n)
+{
+ if (n != 0) {
+ const unsigned char *us1 = (const unsigned char *)s1;
+ const unsigned char *us2 = (const unsigned char *)s2;
+
+ do {
+ if (tolower(*us1) != tolower(*us2++))
+ return tolower(*us1) - tolower(*--us2);
+ if (*us1++ == '\0')
+ break;
+ } while (--n != 0);
+ }
+ return 0;
+}
+
+char*
+xf86strncpy(char* dest, const char* src, xf86size_t n)
+{
+ return strncpy(dest,src,(size_t)n);
+}
+
+char*
+xf86strpbrk(const char* s1, const char* s2)
+{
+ return strpbrk(s1,s2);
+}
+
+char*
+xf86strrchr(const char* s, int c)
+{
+ return strrchr(s,c);
+}
+
+xf86size_t
+xf86strspn(const char* s1, const char* s2)
+{
+ return strspn(s1,s2);
+}
+
+char*
+xf86strstr(const char* s1, const char* s2)
+{
+ return strstr(s1,s2);
+}
+
+char*
+xf86strtok(char* s1, const char* s2)
+{
+ return strtok(s1,s2);
+}
+
+char*
+xf86strdup(const char* s)
+{
+ return xstrdup(s);
+}
+
+int
+xf86sprintf(char *s, const char *format, ...)
+{
+ int ret;
+ va_list args;
+ va_start(args, format);
+ ret = vsprintf(s, format, args);
+ va_end(args);
+ return ret;
+}
+
+int
+xf86snprintf(char *s, xf86size_t len, const char *format, ...)
+{
+ int ret;
+ va_list args;
+ va_start(args, format);
+ ret = vsnprintf(s, len, format, args);
+ va_end(args);
+ return ret;
+}
+
+void
+xf86bzero(void* s, unsigned int n)
+{
+ bzero(s, n);
+}
+
+#ifdef HAVE_VSSCANF
+int
+xf86sscanf(char *s, const char *format, ...)
+#else
+int
+xf86sscanf(char *s, const char *format, char *a0, char *a1, char *a2,
+ char *a3, char *a4, char *a5, char *a6, char *a7, char *a8,
+ char *a9) /* limit of ten args */
+#endif
+{
+#ifdef HAVE_VSSCANF
+ int ret;
+ va_list args;
+ va_start(args, format);
+
+ ret = vsscanf(s,format,args);
+ va_end(args);
+ return ret;
+#else
+ return sscanf(s, format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+#endif
+}
+
+/* Basic I/O */
+
+int xf86errno;
+
+/* XXX This is not complete */
+
+static int
+xfToOsOpenFlags(int xfflags)
+{
+ int flags = 0;
+
+ /* XXX This assumes O_RDONLY is 0 */
+ if (xfflags & XF86_O_WRONLY)
+ flags |= O_WRONLY;
+ if (xfflags & XF86_O_RDWR)
+ flags |= O_RDWR;
+ if (xfflags & XF86_O_CREAT)
+ flags |= O_CREAT;
+
+ return flags;
+}
+
+int
+xf86open(const char *path, int flags, ...)
+{
+ int fd;
+ va_list ap;
+
+ va_start(ap, flags);
+ flags = xfToOsOpenFlags(flags);
+ if (flags & XF86_O_CREAT) {
+ mode_t mode = va_arg(ap, mode_t);
+ fd = open(path, flags, mode);
+ } else {
+ fd = open(path, flags);
+ }
+ va_end(ap);
+ xf86errno = xf86GetErrno();
+ return fd;
+}
+
+int
+xf86close(int fd)
+{
+ int status = close(fd);
+
+ xf86errno = xf86GetErrno();
+ return status;
+}
+
+long
+xf86lseek(int fd, long offset, int whence)
+{
+ switch (whence) {
+ case XF86_SEEK_SET:
+ whence = SEEK_SET;
+ break;
+ case XF86_SEEK_CUR:
+ whence = SEEK_CUR;
+ break;
+ case XF86_SEEK_END:
+ whence = SEEK_END;
+ break;
+ }
+ return (long)lseek(fd, (off_t)offset, whence);
+}
+
+int
+xf86ioctl(int fd, unsigned long request, pointer argp)
+{
+ int status = ioctl(fd, request, argp);
+
+ xf86errno = xf86GetErrno();
+ return status;
+}
+
+xf86ssize_t
+xf86read(int fd, void *buf, xf86size_t nbytes)
+{
+ xf86ssize_t n = read(fd, buf, (size_t)nbytes);
+
+ xf86errno = xf86GetErrno();
+ return n;
+}
+
+xf86ssize_t
+xf86write(int fd, const void *buf, xf86size_t nbytes)
+{
+ xf86ssize_t n = write(fd, buf, (size_t)nbytes);
+
+ xf86errno = xf86GetErrno();
+ return n;
+}
+
+void*
+xf86mmap(void *start, xf86size_t length, int prot,
+ int flags, int fd, xf86size_t /* off_t */ offset)
+{
+#ifndef NO_MMAP
+ int p=0, f=0;
+ void *rc;
+
+ if (flags & XF86_MAP_FIXED) f |= MAP_FIXED;
+ if (flags & XF86_MAP_SHARED) f |= MAP_SHARED;
+ if (flags & XF86_MAP_PRIVATE) f |= MAP_PRIVATE;
+ if (prot & XF86_PROT_EXEC) p |= PROT_EXEC;
+ if (prot & XF86_PROT_READ) p |= PROT_READ;
+ if (prot & XF86_PROT_WRITE) p |= PROT_WRITE;
+ if (prot & XF86_PROT_NONE) p |= PROT_NONE;
+
+ rc = mmap(start,(size_t)length,p,f,fd,(off_t)offset);
+
+ xf86errno = xf86GetErrno();
+ if (rc == MAP_FAILED)
+ return XF86_MAP_FAILED;
+ else
+ return rc;
+#else
+#ifdef HAS_SVR3_MMAPDRV
+ void *rc;
+#ifdef SELF_CONTAINED_WRAPPER
+ if(mmapFd < 0) {
+ if ((mmapFd = open("/dev/mmap", O_RDWR)) == -1) {
+ ErrorF("Warning: failed to open /dev/mmap \n");
+ xf86errno = xf86_ENOSYS;
+ return XF86_MAP_FAILED;
+ }
+ }
+#endif
+ MapDSC.vaddr = (char *)start;
+ MapDSC.physaddr = (char *)offset;
+ MapDSC.length = length;
+ MapDSC.ioflg = 1;
+
+ rc = (pointer)ioctl(mmapFd, MAP, &MapDSC);
+ xf86errno = xf86GetErrno();
+ if (rc == NULL)
+ return XF86_MAP_FAILED;
+ else
+ return rc;
+#else
+ ErrorF("Warning: mmap() is not supported on this platform\n");
+ xf86errno = xf86_ENOSYS;
+ return XF86_MAP_FAILED;
+#endif
+#endif
+}
+
+int
+xf86munmap(void *start, xf86size_t length)
+{
+#ifndef NO_MMAP
+ int rc = munmap(start,(size_t)length);
+
+ xf86errno = xf86GetErrno();
+ return rc;
+#else
+#ifdef HAS_SVR3_MMAPDRV
+ int rc = ioctl(mmapFd, UNMAPRM , start);
+
+ xf86errno = xf86GetErrno();
+ return rc;
+#else
+ ErrorF("Warning: munmap() is not supported on this platform\n");
+ xf86errno = xf86_ENOSYS;
+ return -1;
+#endif
+#endif
+}
+
+int
+xf86stat(const char *file_name, struct xf86stat *xfst)
+{
+ int rc;
+ struct stat st;
+
+ rc = stat(file_name, &st);
+ xf86errno = xf86GetErrno();
+ xfst->st_rdev = st.st_rdev; /* Not much is currently supported */
+ return rc;
+}
+
+int
+xf86fstat(int fd, struct xf86stat *xfst)
+{
+ int rc;
+ struct stat st;
+
+ rc = fstat(fd, &st);
+ xf86errno = xf86GetErrno();
+ xfst->st_rdev = st.st_rdev; /* Not much is currently supported */
+ return rc;
+}
+
+static int
+xfToOsAccessMode(int xfmode)
+{
+ switch(xfmode) {
+ case XF86_R_OK: return R_OK;
+ case XF86_W_OK: return W_OK;
+ case XF86_X_OK: return X_OK;
+ case XF86_F_OK: return F_OK;
+ }
+ return 0;
+}
+
+int
+xf86access(const char *pathname, int mode)
+{
+ int rc;
+
+ mode = xfToOsAccessMode(mode);
+ rc = access(pathname, mode);
+ xf86errno = xf86GetErrno();
+ return rc;
+}
+
+
+
+/* limited stdio support */
+
+#define XF86FILE_magic 0x58464856 /* "XFHV" */
+
+typedef struct _xf86_file_ {
+ INT32 fileno;
+ INT32 magic;
+ FILE* filehnd;
+ char* fname;
+} XF86FILE_priv;
+
+XF86FILE_priv stdhnd[3] = {
+ { 0, XF86FILE_magic, NULL, "$stdinp$" },
+ { 0, XF86FILE_magic, NULL, "$stdout$" },
+ { 0, XF86FILE_magic, NULL, "$stderr$" }
+};
+
+XF86FILE* xf86stdin = (XF86FILE*)&stdhnd[0];
+XF86FILE* xf86stdout = (XF86FILE*)&stdhnd[1];
+XF86FILE* xf86stderr = (XF86FILE*)&stdhnd[2];
+
+void
+xf86WrapperInit()
+{
+ if (stdhnd[0].filehnd == NULL)
+ stdhnd[0].filehnd = stdin;
+ if (stdhnd[1].filehnd == NULL)
+ stdhnd[1].filehnd = stdout;
+ if (stdhnd[2].filehnd == NULL)
+ stdhnd[2].filehnd = stderr;
+ xf86HUGE_VAL = HUGE_VAL;
+}
+
+XF86FILE*
+xf86fopen(const char* fn, const char* mode)
+{
+ XF86FILE_priv* fp;
+ FILE *f = fopen(fn,mode);
+ xf86errno = xf86GetErrno();
+ if (!f) return 0;
+
+ fp = xalloc(sizeof(XF86FILE_priv));
+ fp->magic = XF86FILE_magic;
+ fp->filehnd = f;
+ fp->fileno = fileno(f);
+ fp->fname = xf86strdup(fn);
+#ifdef DEBUG
+ ErrorF("xf86fopen(%s,%s) yields FILE %p XF86FILE %p\n",
+ fn,mode,f,fp);
+#endif
+ return (XF86FILE*)fp;
+}
+
+static void _xf86checkhndl(XF86FILE_priv* f,const char *func)
+{
+ if (!f || f->magic != XF86FILE_magic ||
+ !f->filehnd || !f->fname) {
+ FatalError("libc_wrapper error: passed invalid FILE handle to %s\n",
+ func);
+ exit(42);
+ }
+}
+
+int
+xf86fclose(XF86FILE* f)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+ int ret;
+
+ _xf86checkhndl(fp,"xf86fclose");
+
+ /* somewhat bad check */
+ if (fp->fileno < 3 && fp->fname[0]=='$') {
+ /* assume this is stdin/out/err, don't dispose */
+ ret = fclose(fp->filehnd);
+ } else {
+ ret = fclose(fp->filehnd);
+ fp->magic = 0; /* invalidate */
+ xfree(fp->fname);
+ xfree(fp);
+ }
+ return ret ? -1 : 0;
+}
+
+int
+xf86printf(const char *format, ...)
+{
+ int ret;
+ va_list args;
+ va_start(args, format);
+
+ ret = printf(format,args);
+ va_end(args);
+ return ret;
+}
+
+int
+xf86fprintf(XF86FILE* f, const char *format, ...)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+ int ret;
+ va_list args;
+ va_start(args, format);
+
+#ifdef DEBUG
+ ErrorF("xf86fprintf for XF86FILE %p\n", fp);
+#endif
+ _xf86checkhndl(fp,"xf86fprintf");
+
+ ret = vfprintf(fp->filehnd,format,args);
+ va_end(args);
+ return ret;
+}
+
+int
+xf86vfprintf(XF86FILE* f, const char *format, va_list ap)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+#ifdef DEBUG
+ ErrorF("xf86vfprintf for XF86FILE %p\n", fp);
+#endif
+ _xf86checkhndl(fp,"xf86vfprintf");
+
+ return vfprintf(fp->filehnd,format,ap);
+}
+
+int
+xf86vsprintf(char *s, const char *format, va_list ap)
+{
+ return vsprintf(s, format, ap);
+}
+
+int
+xf86vsnprintf(char *s, xf86size_t len, const char *format, va_list ap)
+{
+ return vsnprintf(s, len, format, ap);
+}
+
+#ifdef HAVE_VFSCANF
+int
+xf86fscanf(XF86FILE* f, const char *format, ...)
+#else
+int
+xf86fscanf(XF86FILE* f, const char *format, char *a0, char *a1, char *a2,
+ char *a3, char *a4, char *a5, char *a6, char *a7, char *a8,
+ char *a9) /* limit of ten args */
+#endif
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+#ifdef HAVE_VFSCANF
+ int ret;
+ va_list args;
+ va_start(args, format);
+
+ _xf86checkhndl(fp,"xf86fscanf");
+
+ ret = vfscanf(fp->filehnd,format,args);
+ va_end(args);
+ return ret;
+#else
+ _xf86checkhndl(fp,"xf86fscanf");
+ return fscanf(fp->filehnd, format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+#endif
+}
+
+char *
+xf86fgets(char *buf, INT32 n, XF86FILE* f)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+ _xf86checkhndl(fp,"xf86fgets");
+ return fgets(buf,(int)n,fp->filehnd);
+}
+
+int
+xf86fputs(const char *buf, XF86FILE* f)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+ _xf86checkhndl(fp,"xf86fputs");
+ return fputs(buf,fp->filehnd);
+}
+
+int
+xf86getc(XF86FILE* f)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+ _xf86checkhndl(fp,"xf86getc");
+ return getc(fp->filehnd);
+}
+
+int
+xf86fgetc(XF86FILE* f)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+ _xf86checkhndl(fp,"xf86fgetc");
+ return fgetc(fp->filehnd);
+}
+
+int
+xf86fputc(int c,XF86FILE* f)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+ _xf86checkhndl(fp,"xf86fputc");
+ return fputc(c,fp->filehnd);
+}
+
+int
+xf86fflush(XF86FILE* f)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+ _xf86checkhndl(fp,"xf86fflush");
+ return fflush(fp->filehnd);
+}
+
+xf86size_t
+xf86fread(void* buf, xf86size_t sz, xf86size_t cnt, XF86FILE* f)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+#ifdef DEBUG
+ ErrorF("xf86fread for XF86FILE %p\n", fp);
+#endif
+ _xf86checkhndl(fp,"xf86fread");
+ return fread(buf,(size_t)sz,(size_t)cnt,fp->filehnd);
+}
+
+xf86size_t
+xf86fwrite(const void* buf, xf86size_t sz, xf86size_t cnt, XF86FILE* f)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+ _xf86checkhndl(fp,"xf86fwrite");
+ return fwrite(buf,(size_t)sz,(size_t)cnt,fp->filehnd);
+}
+
+int
+xf86fseek(XF86FILE* f, long offset, int whence)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+ _xf86checkhndl(fp,"xf86fseek");
+ switch (whence) {
+ case XF86_SEEK_SET:
+ whence = SEEK_SET;
+ break;
+ case XF86_SEEK_CUR:
+ whence = SEEK_CUR;
+ break;
+ case XF86_SEEK_END:
+ whence = SEEK_END;
+ break;
+ }
+ return fseek(fp->filehnd,offset,whence);
+}
+
+long
+xf86ftell(XF86FILE* f)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+ _xf86checkhndl(fp,"xf86ftell");
+ return ftell(fp->filehnd);
+}
+
+char*
+xf86strerror(int n)
+{
+ return strerror(n);
+}
+
+/* required for portable fgetpos/fsetpos,
+ * use as
+ * XF86fpos_t* pos = xalloc(xf86fpossize());
+ */
+long
+xf86fpossize()
+{
+ return sizeof(fpos_t);
+}
+
+int
+xf86fgetpos(XF86FILE* f,XF86fpos_t* pos)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+ fpos_t *ppos = (fpos_t*)pos;
+
+ _xf86checkhndl(fp,"xf86fgetpos");
+#ifndef ISC
+ return fgetpos(fp->filehnd,ppos);
+#else
+ *ppos = ftell(fp->filehnd);
+ if (*ppos < 0L)
+ return(-1);
+ return(0);
+#endif
+}
+
+int
+xf86fsetpos(XF86FILE* f,const XF86fpos_t* pos)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+ fpos_t *ppos = (fpos_t*)pos;
+
+ /* XXX need to handle xf86errno here */
+ _xf86checkhndl(fp,"xf86fsetpos");
+#ifndef ISC
+ return fsetpos(fp->filehnd,ppos);
+#else
+ if (ppos == NULL)
+ {
+ errno = EINVAL;
+ return EOF;
+ }
+ return fseek(fp->filehnd, *ppos, SEEK_SET);
+#endif
+}
+
+void
+xf86perror(const char *s)
+{
+ perror(s);
+}
+
+int
+xf86remove(const char *s)
+{
+#ifdef _POSIX_SOURCE
+ return remove(s);
+#else
+ return unlink(s);
+#endif
+}
+
+int
+xf86rename(const char *old, const char *new)
+{
+#ifdef _POSIX_SOURCE
+ return rename(old,new);
+#else
+ int ret = link(old,new);
+ if (!ret) {
+ ret = unlink(old);
+ if (ret) unlink(new);
+ } else
+ ret = unlink(new);
+ return ret;
+#endif
+}
+
+void
+xf86rewind(XF86FILE* f)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+ _xf86checkhndl(fp,"xf86fsetpos");
+ rewind(fp->filehnd);
+}
+
+void
+xf86clearerr(XF86FILE* f)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+ _xf86checkhndl(fp,"xf86clearerr");
+ clearerr(fp->filehnd);
+}
+
+int
+xf86feof(XF86FILE* f)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+ _xf86checkhndl(fp,"xf86feof");
+ return feof(fp->filehnd);
+}
+
+int
+xf86ferror(XF86FILE* f)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+ _xf86checkhndl(fp,"xf86ferror");
+ return ferror(fp->filehnd);
+}
+
+XF86FILE*
+xf86freopen(const char* fname,const char* mode,XF86FILE* fold)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)fold;
+ FILE *fnew;
+
+ _xf86checkhndl(fp,"xf86freopen");
+ fnew = freopen(fname,mode,fp->filehnd);
+ xf86errno = xf86GetErrno();
+ if (!fnew) {
+ xf86fclose(fold); /* discard old XF86FILE structure */
+ return 0;
+ }
+ /* recycle the old XF86FILE structure */
+ fp->magic = XF86FILE_magic;
+ fp->filehnd = fnew;
+ fp->fileno = fileno(fnew);
+ fp->fname = xf86strdup(fname);
+#ifdef DEBUG
+ ErrorF("xf86freopen(%s,%s,%p) yields FILE %p XF86FILE %p\n",
+ fname,mode,fold,fnew,fp);
+#endif
+ return (XF86FILE*)fp;
+}
+
+int
+xf86setbuf(XF86FILE* f, char *buf)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+ _xf86checkhndl(fp,"xf86fsetbuf");
+#ifdef SETBUF_RETURNS_INT
+ return setbuf(fp->filehnd, buf);
+#else
+ setbuf(fp->filehnd, buf);
+ return 0;
+#endif
+}
+
+int
+xf86setvbuf(XF86FILE* f, char *buf, int mode, xf86size_t size)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+ int vbufmode;
+
+ _xf86checkhndl(fp,"xf86fsetvbuf");
+
+ switch (mode) {
+ case XF86_IONBF:
+ vbufmode = _IONBF;
+ break;
+ case XF86_IOLBF:
+ vbufmode = _IOFBF;
+ break;
+ case XF86_IOFBF:
+ vbufmode = _IOLBF;
+ break;
+ default:
+ FatalError("libc_wrapper error: mode in setvbuf incorrect\n");
+ exit(42);
+ }
+
+ return setvbuf(fp->filehnd,buf,vbufmode,(size_t)size);
+}
+
+XF86FILE*
+xf86tmpfile(void)
+{
+#ifdef NEED_TMPFILE
+ return xf86fopen(tmpnam((char*)0),"w+");
+#else
+ XF86FILE_priv* fp;
+ FILE *f = tmpfile();
+ xf86errno = xf86GetErrno();
+ if (!f) return 0;
+
+ fp = xalloc(sizeof(XF86FILE_priv));
+ fp->magic = XF86FILE_magic;
+ fp->filehnd = f;
+ fp->fileno = fileno(f);
+ fp->fname = xf86strdup("*tmpfile*"); /* so that it can be xfree()'d */
+#ifdef DEBUG
+ ErrorF("xf86tmpfile() yields FILE %p XF86FILE %p\n",f,fp);
+#endif
+ return (XF86FILE*)fp;
+}
+#endif /* HAS_TMPFILE */
+
+
+int
+xf86ungetc(int c,XF86FILE* f)
+{
+ XF86FILE_priv* fp = (XF86FILE_priv*)f;
+
+ _xf86checkhndl(fp,"xf86ungetc");
+ return ungetc(c,fp->filehnd);
+}
+
+/* Misc functions. Some are ANSI C, some are not. */
+
+void
+xf86usleep(usec)
+ unsigned long usec;
+{
+#if (defined(SYSV) || defined(SVR4)) && !defined(sun)
+ syscall(3112, (usec) / 1000 + 1);
+#else
+ usleep(usec);
+#endif
+}
+
+void
+xf86getsecs(CARD32 * secs, CARD32 * usecs)
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ *secs = tv.tv_sec;
+ *usecs= tv.tv_usec;
+
+ return;
+}
+
+int
+xf86ffs(int mask)
+{
+ int n;
+ if (mask == 0) return 0;
+ for (n = 1; (mask & 1)==0; n++)
+ mask >>= 1;
+ return n;
+}
+
+char *
+xf86getenv(const char * a)
+{
+ /* Only allow this when the real and effective uids are the same */
+ if (getuid() != geteuid())
+ return NULL;
+ else
+ return(getenv(a));
+}
+
+void *
+xf86bsearch(const void *key, const void *base, xf86size_t nmemb,
+ xf86size_t size, int (*compar)(const void *, const void *))
+{
+ return bsearch(key, base, (size_t)nmemb, (size_t)size, compar);
+}
+
+/*VARARGS1*/
+int
+xf86execl(const char *pathname, const char *arg, ...)
+{
+#ifndef __EMX__
+ int i;
+ pid_t pid;
+#ifdef MACH386
+ union wait exit_status;
+#else
+ int exit_status;
+#endif
+ char *arglist[5];
+ va_list args;
+ va_start(args, arg);
+ arglist[0] = (char*)&args;
+ i = 1;
+ while (i < 5 && (arglist[i++] = va_arg(args, char *)) != NULL)
+ ;
+ va_end(args);
+
+ if ((pid = fork()) < 0) {
+ ErrorF("Fork failed (%s)\n", strerror(errno));
+ return -1;
+ } else if (pid == 0) { /* child */
+ /*
+ * Make sure that the child doesn't inherit any I/O permissions it
+ * shouldn't have. It's better to put constraints on the development
+ * of a clock program than to give I/O permissions to a bogus program
+ * in someone's XF86Config file
+ */
+#ifndef SELF_CONTAINED_WRAPPER
+ xf86DisableIO();
+#endif
+ setuid(getuid());
+#if !defined(SELF_CONTAINED_WRAPPER) && !defined(AMOEBA) && !defined(MINIX)
+ /* set stdin, stdout to the consoleFD, and leave stderr alone */
+ for (i = 0; i < 2; i++)
+ {
+ if (xf86Info.consoleFd != i)
+ {
+ close(i);
+ dup(xf86Info.consoleFd);
+ }
+ }
+#endif
+
+ execv(pathname, arglist);
+ ErrorF("Exec failed for command \"%s\" (%s)\n",
+ pathname, strerror(errno));
+ exit(255);
+ }
+
+ /* parent */
+ wait(&exit_status);
+ if (WIFEXITED(exit_status))
+ {
+ switch (WEXITSTATUS(exit_status))
+ {
+ case 0: /* OK */
+ return 0;
+ case 255: /* exec() failed */
+ return(255);
+ default: /* bad exit status */
+ ErrorF("Program \"%s\" had bad exit status %d\n",
+ pathname, WEXITSTATUS(exit_status));
+ return(WEXITSTATUS(exit_status));
+ }
+ }
+ else if (WIFSIGNALED(exit_status))
+ {
+ ErrorF("Program \"%s\" died on signal %d\n",
+ pathname, WTERMSIG(exit_status));
+ return(WTERMSIG(exit_status));
+ }
+#ifdef WIFSTOPPED
+ else if (WIFSTOPPED(exit_status))
+ {
+ ErrorF("Program \"%s\" stopped by signal %d\n",
+ pathname, WSTOPSIG(exit_status));
+ return(WSTOPSIG(exit_status));
+ }
+#endif
+ else /* should never get to this point */
+ {
+ ErrorF("Program \"%s\" has unknown exit condition\n",
+ pathname);
+ return(1);
+ }
+#else
+ return(1);
+#endif /* __EMX__ Disable this crazy business for now */
+}
+
+void
+xf86abort(void)
+{
+ ErrorF("Module called abort() function\n");
+ abort();
+}
+
+void
+xf86exit(int ex)
+{
+ ErrorF("Module called exit() function with value=%d\n",ex);
+ exit(ex);
+}
+
+/* directory handling functions */
+#define XF86DIR_magic 0x78666876 /* "xfhv" */
+
+typedef struct _xf86_dir_ {
+ DIR *dir;
+ INT32 magic;
+ XF86DIRENT *dirent;
+} XF86DIR_priv;
+
+static void
+_xf86checkdirhndl(XF86DIR_priv* f,const char *func)
+{
+ if (!f || f->magic != XF86DIR_magic || !f->dir || !f->dirent) {
+ FatalError("libc_wrapper error: passed invalid DIR handle to %s\n",
+ func);
+ exit(42);
+ }
+}
+
+XF86DIR *
+xf86opendir(const char *name)
+{
+ XF86DIR_priv *dp;
+ DIR *dirp;
+
+ dirp = opendir(name);
+ if (!dirp)
+ return (XF86DIR*)0;
+
+ dp = xalloc(sizeof(XF86DIR_priv));
+ dp->magic = XF86DIR_magic; /* This time I have this, Dirk! :-) */
+ dp->dir = dirp;
+ dp->dirent = xalloc(sizeof(struct _xf86dirent));
+
+ return (XF86DIR*)dp;
+}
+
+XF86DIRENT*
+xf86readdir(XF86DIR* dirp)
+{
+ XF86DIR_priv* dp = (XF86DIR_priv*)dirp;
+ DIRENTRY *de;
+ XF86DIRENT* xde;
+ int sz;
+
+ _xf86checkdirhndl(dp,"xf86readdir");
+
+ de = readdir(dp->dir);
+ if (!de)
+ return (XF86DIRENT*)0;
+ xde = dp->dirent;
+ sz = strlen(de->d_name);
+ strncpy(xde->d_name,de->d_name, sz>_XF86NAMELEN ? (_XF86NAMELEN+1) : (sz+1));
+ xde->d_name[_XF86NAMELEN] = '\0'; /* be sure to have a 0 byte */
+ return xde;
+}
+
+void
+xf86rewinddir(XF86DIR* dirp)
+{
+ XF86DIR_priv* dp = (XF86DIR_priv*)dirp;
+
+ _xf86checkdirhndl(dp,"xf86readdir");
+ rewinddir(dp->dir);
+}
+
+int
+xf86closedir(XF86DIR* dir)
+{
+ XF86DIR_priv* dp = (XF86DIR_priv*)dir;
+ int n;
+
+ _xf86checkdirhndl(dp,"xf86readdir");
+
+ n = closedir(dp->dir);
+ dp->magic = 0;
+ xfree(dp->dirent);
+ xfree(dp);
+
+ return n;
+}
+
+static mode_t
+xfToOsChmodMode(xf86mode_t xfmode)
+{
+ mode_t mode = 0;
+
+ if (xfmode & XF86_S_ISUID) mode |= S_ISUID;
+ if (xfmode & XF86_S_ISGID) mode |= S_ISGID;
+ if (xfmode & XF86_S_ISVTX) mode |= S_ISVTX;
+ if (xfmode & XF86_S_IRUSR) mode |= S_IRUSR;
+ if (xfmode & XF86_S_IWUSR) mode |= S_IWUSR;
+ if (xfmode & XF86_S_IXUSR) mode |= S_IXUSR;
+ if (xfmode & XF86_S_IRGRP) mode |= S_IRGRP;
+ if (xfmode & XF86_S_IWGRP) mode |= S_IWGRP;
+ if (xfmode & XF86_S_IXGRP) mode |= S_IXGRP;
+ if (xfmode & XF86_S_IROTH) mode |= S_IROTH;
+ if (xfmode & XF86_S_IWOTH) mode |= S_IWOTH;
+ if (xfmode & XF86_S_IXOTH) mode |= S_IXOTH;
+
+ return mode;
+}
+
+int
+xf86chmod(const char *path, xf86mode_t xfmode)
+{
+ mode_t mode = xfToOsChmodMode(xfmode);
+ int rc = chmod(path, mode);
+
+ xf86errno = xf86GetErrno();
+ return rc;
+}
+
+int
+xf86chown(const char *path, xf86uid_t owner, xf86gid_t group)
+{
+ int rc = chown(path, owner, group);
+ xf86errno = xf86GetErrno();
+ return rc;
+}
+
+xf86uid_t
+xf86geteuid(void)
+{
+ return geteuid();
+}
+
+static mode_t
+xfToOsMknodMode(xf86mode_t xfmode)
+{
+ mode_t mode = xfToOsChmodMode(xfmode);
+
+ if (xfmode & XF86_S_IFREG) mode |= S_IFREG;
+ if (xfmode & XF86_S_IFCHR) mode |= S_IFCHR;
+ if (xfmode & XF86_S_IFBLK) mode |= S_IFBLK;
+ if (xfmode & XF86_S_IFIFO) mode |= S_IFIFO;
+
+ return mode;
+}
+
+int xf86mknod(const char *pathname, xf86mode_t xfmode, xf86dev_t dev)
+{
+ mode_t mode = xfToOsMknodMode(xfmode);
+ int rc = mknod(pathname, mode, dev);
+
+ xf86errno = xf86GetErrno();
+ return rc;
+}
+
+unsigned int xf86sleep(unsigned int seconds)
+{
+ return sleep(seconds);
+}
+
+
+/* Several math functions */
+
+int
+xf86abs(int x)
+{
+ return abs(x);
+}
+
+double
+xf86acos(double x)
+{
+ return acos(x);
+}
+
+double
+xf86asin(double x)
+{
+ return asin(x);
+}
+
+double
+xf86atan(double x)
+{
+ return atan(x);
+}
+
+double
+xf86atan2(double x,double y)
+{
+ return atan2(x,y);
+}
+
+double
+xf86atof(const char* s)
+{
+ return atof(s);
+}
+
+int
+xf86atoi(const char* s)
+{
+ return atoi(s);
+}
+
+long
+xf86atol(const char* s)
+{
+ return atol(s);
+}
+
+double
+xf86ceil(double x)
+{
+ return ceil(x);
+}
+
+double
+xf86cos(double x)
+{
+ return(cos(x));
+}
+
+double
+xf86exp(double x)
+{
+ return(exp(x));
+}
+
+double
+xf86fabs(double x)
+{
+ return(fabs(x));
+}
+
+double
+xf86floor(double x)
+{
+ return floor(x);
+}
+
+double
+xf86fmod(double x,double y)
+{
+ return fmod(x,y);
+}
+
+long
+xf86labs(long x)
+{
+ return labs(x);
+}
+
+double
+xf86log(double x)
+{
+ return(log(x));
+}
+
+double
+xf86log10(double x)
+{
+ return(log10(x));
+}
+
+double
+xf86modf(double x,double* y)
+{
+ return modf(x,y);
+}
+
+double
+xf86pow(double x, double y)
+{
+ return(pow(x,y));
+}
+
+double
+xf86sin(double x)
+{
+ return sin(x);
+}
+
+double
+xf86sqrt(double x)
+{
+ return(sqrt(x));
+}
+
+double
+xf86strtod(const char *s, char **end)
+{
+ return strtod(s,end);
+}
+
+long
+xf86strtol(const char *s, char **end, int radix)
+{
+ return strtol(s,end,radix);
+}
+
+unsigned long
+xf86strtoul(const char *s, char **end,int radix)
+{
+ return strtoul(s,end,radix);
+}
+
+double
+xf86tan(double x)
+{
+ return tan(x);
+}
+
+/* memory functions */
+void*
+xf86memchr(const void* s, int c, xf86size_t n)
+{
+ return memchr(s,c,(size_t)n);
+}
+
+int
+xf86memcmp(const void* s1, const void* s2, xf86size_t n)
+{
+ return(memcmp(s1,s2,(size_t)n));
+}
+
+void*
+xf86memcpy(void* dest, const void* src, xf86size_t n)
+{
+ return(memcpy(dest,src,(size_t)n));
+}
+
+void*
+xf86memmove(void* dest, const void* src, xf86size_t n)
+{
+ return(memmove(dest,src,(size_t)n));
+}
+
+void*
+xf86memset(void* s, int c, xf86size_t n)
+{
+ return(memset(s,c,(size_t)n));
+}
+
+/* ctype functions */
+
+int
+xf86isalnum(int c)
+{
+ return isalnum(c) ? 1 : 0;
+}
+
+int
+xf86isalpha(int c)
+{
+ return isalpha(c) ? 1 : 0;
+}
+
+int
+xf86iscntrl(int c)
+{
+ return iscntrl(c) ? 1 : 0;
+}
+
+int
+xf86isdigit(int c)
+{
+ return isdigit(c) ? 1 : 0;
+}
+
+int
+xf86isgraph(int c)
+{
+ return isgraph(c) ? 1 : 0;
+}
+
+int
+xf86islower(int c)
+{
+ return islower(c) ? 1 : 0;
+}
+
+int
+xf86isprint(int c)
+{
+ return isprint(c) ? 1 : 0;
+}
+
+int
+xf86ispunct(int c)
+{
+ return ispunct(c) ? 1 : 0;
+}
+
+int
+xf86isspace(int c)
+{
+ return isspace(c) ? 1 : 0;
+}
+
+int
+xf86isupper(int c)
+{
+ return isupper(c) ? 1 : 0;
+}
+
+int
+xf86isxdigit(int c)
+{
+ return isxdigit(c) ? 1 : 0;
+}
+
+int
+xf86tolower(int c)
+{
+ return tolower(c);
+}
+
+int
+xf86toupper(int c)
+{
+ return toupper(c);
+}
+
+/* memory allocation functions */
+void*
+xf86calloc(xf86size_t sz,xf86size_t n)
+{
+ return xcalloc(sz, n);
+}
+
+void
+xf86free(void* p)
+{
+ xfree(p);
+}
+
+void*
+xf86malloc(xf86size_t n)
+{
+ return xalloc(n);
+}
+
+void*
+xf86realloc(void* p, xf86size_t n)
+{
+ return xrealloc(p,n);
+}
+
+/*
+ * XXX This probably doesn't belong here.
+ */
+int
+xf86getpagesize()
+{
+ static int pagesize = -1;
+
+ if (pagesize != -1)
+ return pagesize;
+
+#if defined(_SC_PAGESIZE) || defined(HAS_SC_PAGESIZE)
+ pagesize = sysconf(_SC_PAGESIZE);
+#endif
+#ifdef _SC_PAGE_SIZE
+ if (pagesize == -1)
+ pagesize = sysconf(_SC_PAGE_SIZE);
+#endif
+#ifdef HAS_GETPAGESIZE
+ if (pagesize == -1)
+ pagesize = getpagesize();
+#endif
+#ifdef PAGE_SIZE
+ if (pagesize == -1)
+ pagesize = PAGE_SIZE;
+#endif
+ if (pagesize == -1)
+ FatalError("xf86getpagesize: Cannot determine page size\n");
+
+ return pagesize;
+}
+
+
+#define mapnum(e) case (e): return (xf86_##e)
+
+int
+xf86GetErrno ()
+{
+ switch (errno)
+ {
+ case 0: return 0;
+ mapnum (EACCES);
+ mapnum (EAGAIN);
+ mapnum (EBADF);
+ mapnum (EEXIST);
+ mapnum (EFAULT);
+ mapnum (EINTR);
+ mapnum (EINVAL);
+ mapnum (EISDIR);
+ mapnum (ELOOP); /* not POSIX 1 */
+ mapnum (EMFILE);
+ mapnum (ENAMETOOLONG);
+ mapnum (ENFILE);
+ mapnum (ENOENT);
+ mapnum (ENOMEM);
+ mapnum (ENOSPC);
+ mapnum (ENOTDIR);
+ mapnum (EPIPE);
+ mapnum (EROFS);
+#ifndef __EMX__
+ mapnum (ETXTBSY); /* not POSIX 1 */
+#endif
+ mapnum (ENOTTY);
+ mapnum (EBUSY);
+ mapnum (ENODEV);
+ mapnum (EIO);
+
+ default:
+ return (xf86_UNKNOWN);
+ }
+}
+
+#undef mapnum
+
+#ifdef NEED_SNPRINTF
+#include "snprintf.c"
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/mapVT_noop.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/mapVT_noop.c
new file mode 100644
index 000000000..74be8ee6c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/mapVT_noop.c
@@ -0,0 +1,43 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/mapVT_noop.c,v 3.2 1998/07/25 16:57:01 dawes Exp $ */
+/*
+ * Copyright 1993 by David Wexelblat <dwex@XFree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of David Wexelblat not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Wexelblat makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: mapVT_noop.c /main/3 1996/02/21 17:53:42 kaleb $ */
+
+/*
+ * These routines are currently only needed for OSs with true USL-style VTs.
+ * All other OSs get no-ops.
+ */
+
+#if 0
+/* ARGSUSED */
+void xf86MapDisplay(int ScreenNum, int Region)
+{
+ return;
+}
+
+/* ARGSUSED */
+void xf86UnMapDisplay(int ScreenNum, int Region)
+{
+ return;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/posix_tty.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/posix_tty.c
new file mode 100644
index 000000000..759b3842e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/posix_tty.c
@@ -0,0 +1,792 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/posix_tty.c,v 3.22 1999/08/14 10:50:06 dawes Exp $ */
+/*
+ * Copyright 1993-1999 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice 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 XFREE86 PROJECT 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 XFree86 Project 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
+ * XFree86 Project.
+ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/* $XConsortium: posix_tty.c /main/7 1996/10/19 18:07:47 kaleb $ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
+
+#ifndef NEW_INPUT
+static Bool not_a_tty = FALSE;
+
+void
+xf86SetMouseSpeed(MouseDevPtr mouse, int old, int new, unsigned int cflag)
+{
+ struct termios tty;
+ char *c;
+
+ if (not_a_tty)
+ return;
+
+ if (tcgetattr(mouse->mseFd, &tty) < 0)
+ {
+ not_a_tty = TRUE;
+ xf86Msg(X_WARNING,
+ "%s unable to get status of mouse fd (%s)\n",
+ mouse->mseDevice, strerror(errno));
+ return;
+ }
+
+ /* this will query the initial baudrate only once */
+ if (mouse->oldBaudRate < 0) {
+ switch (cfgetispeed(&tty))
+ {
+ case B9600:
+ mouse->oldBaudRate = 9600;
+ break;
+ case B4800:
+ mouse->oldBaudRate = 4800;
+ break;
+ case B2400:
+ mouse->oldBaudRate = 2400;
+ break;
+ case B1200:
+ default:
+ mouse->oldBaudRate = 1200;
+ break;
+ }
+ }
+
+ tty.c_iflag = IGNBRK | IGNPAR;
+ tty.c_oflag = 0;
+ tty.c_lflag = 0;
+ tty.c_cflag = (tcflag_t)cflag;
+ tty.c_cc[VTIME] = 0;
+ tty.c_cc[VMIN] = 1;
+
+ switch (old)
+ {
+ case 9600:
+ cfsetispeed(&tty, B9600);
+ cfsetospeed(&tty, B9600);
+ break;
+ case 4800:
+ cfsetispeed(&tty, B4800);
+ cfsetospeed(&tty, B4800);
+ break;
+ case 2400:
+ cfsetispeed(&tty, B2400);
+ cfsetospeed(&tty, B2400);
+ break;
+ case 1200:
+ default:
+ cfsetispeed(&tty, B1200);
+ cfsetospeed(&tty, B1200);
+ }
+
+ if (tcsetattr(mouse->mseFd, TCSADRAIN, &tty) < 0)
+ {
+ if (xf86Info.allowMouseOpenFail) {
+ xf86Msg(X_WARNING,
+ "Unable to set status of mouse fd (%s) - Continuing...\n",
+ strerror(errno));
+ return;
+ }
+ xf86FatalError("Unable to set status of mouse fd (%s)\n",
+ strerror(errno));
+ }
+
+ switch (new)
+ {
+ case 9600:
+ c = "*q";
+ cfsetispeed(&tty, B9600);
+ cfsetospeed(&tty, B9600);
+ break;
+ case 4800:
+ c = "*p";
+ cfsetispeed(&tty, B4800);
+ cfsetospeed(&tty, B4800);
+ break;
+ case 2400:
+ c = "*o";
+ cfsetispeed(&tty, B2400);
+ cfsetospeed(&tty, B2400);
+ break;
+ case 1200:
+ default:
+ c = "*n";
+ cfsetispeed(&tty, B1200);
+ cfsetospeed(&tty, B1200);
+ }
+
+ if (mouse->mseType == PROT_LOGIMAN || mouse->mseType == PROT_LOGI)
+ {
+ if (write(mouse->mseFd, c, 2) != 2)
+ {
+ if (xf86Info.allowMouseOpenFail) {
+ xf86Msg(X_WARNING,
+ "Unable to write to mouse fd (%s) - Continuing...\n",
+ strerror(errno));
+ return;
+ }
+ xf86FatalError("Unable to write to mouse fd (%s)\n",
+ strerror(errno));
+ }
+ }
+ usleep(100000);
+
+ if (tcsetattr(mouse->mseFd, TCSADRAIN, &tty) < 0)
+ {
+ if (xf86AllowMouseOpenFail) {
+ xf86Msg(X_WARNING,
+ "Unable to set status of mouse fd (%s) - Continuing...\n",
+ strerror(errno));
+ return;
+ }
+ xf86FatalError("Unable to set status of mouse fd (%s)\n",
+ strerror(errno));
+ }
+}
+#endif
+
+static int
+GetBaud (int baudrate)
+{
+#ifdef B300
+ if (baudrate == 300)
+ return B300;
+#endif
+#ifdef B1200
+ if (baudrate == 1200)
+ return B1200;
+#endif
+#ifdef B2400
+ if (baudrate == 2400)
+ return B2400;
+#endif
+#ifdef B4800
+ if (baudrate == 4800)
+ return B4800;
+#endif
+#ifdef B9600
+ if (baudrate == 9600)
+ return B9600;
+#endif
+#ifdef B19200
+ if (baudrate == 19200)
+ return B19200;
+#endif
+#ifdef B38400
+ if (baudrate == 38400)
+ return B38400;
+#endif
+#ifdef B57600
+ if (baudrate == 57600)
+ return B57600;
+#endif
+#ifdef B115200
+ if (baudrate == 115200)
+ return B115200;
+#endif
+#ifdef B230400
+ if (baudrate == 230400)
+ return B230400;
+#endif
+#ifdef B460800
+ if (baudrate == 460800)
+ return B460800;
+#endif
+ return (0);
+}
+
+int
+xf86OpenSerial (pointer options)
+{
+#ifdef Lynx
+ struct sgttyb ms_sgtty;
+#endif
+ struct termios t;
+ int fd, i;
+ char *dev;
+
+ dev = xf86SetStrOption (options, "Device", NULL);
+ if (!dev)
+ {
+ xf86Msg (X_ERROR, "xf86OpenSerial: No Device specified.\n");
+ return (-1);
+ }
+
+#ifndef Lynx
+ SYSCALL (fd = open (dev, O_RDWR | O_NONBLOCK | O_EXCL));
+#else
+ /* O_EXCL yields an EEXIST on LynxOS */
+ SYSCALL (fd = open (dev, O_RDWR | O_NONBLOCK));
+#endif
+ if (fd == -1)
+ {
+ xf86Msg (X_ERROR,
+ "xf86OpenSerial: Cannot open device %s\n\t%s.\n",
+ dev, strerror (errno));
+ return (-1);
+ }
+
+ if (!isatty (fd))
+ {
+#if 1
+ /* Allow non-tty devices to be opened. */
+ return (fd);
+#else
+ xf86Msg (X_WARNING,
+ "xf86OpenSerial: Specified device %s is not a tty\n",
+ dev);
+ SYSCALL (close (fd));
+ errno = EINVAL;
+ return (-1);
+#endif
+ }
+
+#ifdef Lynx
+ /* LynxOS does not assert DTR without this */
+ ioctl (fd, TIOCGETP, (char *) &ms_sgtty);
+ ioctl (fd, TIOCSDTR, (char *) &ms_sgtty);
+#endif
+
+ /* set up default port parameters */
+ SYSCALL (tcgetattr (fd, &t));
+ t.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR\
+ |IGNCR|ICRNL|IXON);
+ t.c_oflag &= ~OPOST;
+ t.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+ t.c_cflag &= ~(CSIZE|PARENB);
+ t.c_cflag |= CS8|CLOCAL;
+
+ cfsetispeed (&t, B9600);
+ cfsetospeed (&t, B9600);
+ t.c_cc[VMIN] = 1;
+ t.c_cc[VTIME] = 0;
+
+ SYSCALL (tcsetattr (fd, TCSANOW, &t));
+
+ if (xf86SetSerial (fd, options) == -1)
+ {
+ SYSCALL (close (fd));
+ return (-1);
+ }
+
+ SYSCALL (i = fcntl (fd, F_GETFL, 0));
+ if (i == -1)
+ {
+ SYSCALL (close (fd));
+ return (-1);
+ }
+ i &= ~O_NONBLOCK;
+ SYSCALL (i = fcntl (fd, F_SETFL, i));
+ if (i == -1)
+ {
+ SYSCALL (close (fd));
+ return (-1);
+ }
+ return (fd);
+}
+
+int
+xf86SetSerial (int fd, pointer options)
+{
+ struct termios t;
+ int val;
+ const char *s;
+ int baud, r;
+
+ if (fd < 0)
+ return -1;
+
+ /* Don't try to set parameters for non-tty devices. */
+ if (!isatty(fd))
+ return 0;
+
+ SYSCALL (tcgetattr (fd, &t));
+
+ if ((val = xf86SetIntOption (options, "BaudRate", 0)))
+ {
+ if ((baud = GetBaud (val)))
+ {
+ cfsetispeed (&t, baud);
+ cfsetospeed (&t, baud);
+ }
+ else
+ {
+ xf86Msg (X_ERROR,
+ "Invalid Option BaudRate value: %d\n", val);
+ return (-1);
+ }
+ }
+
+ if ((val = xf86SetIntOption (options, "StopBits", 0)))
+ {
+ switch (val)
+ {
+ case 1:
+ t.c_cflag &= ~(CSTOPB);
+ break;
+ case 2:
+ t.c_cflag |= CSTOPB;
+ break;
+ default:
+ xf86Msg (X_ERROR,
+ "Invalid Option StopBits value: %d\n", val);
+ return (-1);
+ break;
+ }
+ }
+
+ if ((val = xf86SetIntOption (options, "DataBits", 0)))
+ {
+ switch (val)
+ {
+ case 5:
+ t.c_cflag &= ~(CSIZE);
+ t.c_cflag |= CS5;
+ break;
+ case 6:
+ t.c_cflag &= ~(CSIZE);
+ t.c_cflag |= CS6;
+ break;
+ case 7:
+ t.c_cflag &= ~(CSIZE);
+ t.c_cflag |= CS7;
+ break;
+ case 8:
+ t.c_cflag &= ~(CSIZE);
+ t.c_cflag |= CS8;
+ break;
+ default:
+ xf86Msg (X_ERROR,
+ "Invalid Option DataBits value: %d\n", val);
+ return (-1);
+ break;
+ }
+ }
+
+ if ((s = xf86SetStrOption (options, "Parity", NULL)))
+ {
+ if (xf86NameCmp (s, "Odd") == 0)
+ {
+ t.c_cflag |= PARENB | PARODD;
+ }
+ else if (xf86NameCmp (s, "Even") == 0)
+ {
+ t.c_cflag |= PARENB;
+ t.c_cflag &= ~(PARODD);
+ }
+ else if (xf86NameCmp (s, "None") == 0)
+ {
+ t.c_cflag &= ~(PARENB);
+ }
+ else
+ {
+ xf86Msg (X_ERROR, "Invalid Option Parity value: %s\n",
+ s);
+ return (-1);
+ }
+ }
+
+ if ((val = xf86SetIntOption (options, "Vmin", -1)) != -1)
+ {
+ t.c_cc[VMIN] = val;
+ }
+ if ((val = xf86SetIntOption (options, "Vtime", -1)) != -1)
+ {
+ t.c_cc[VTIME] = val;
+ }
+
+ if ((s = xf86SetStrOption (options, "FlowControl", NULL)))
+ {
+ xf86MarkOptionUsedByName (options, "FlowControl");
+ if (xf86NameCmp (s, "Xon") == 0)
+ {
+ t.c_iflag |= IXON | IXOFF;
+ }
+ else if (xf86NameCmp (s, "None") == 0)
+ {
+ t.c_iflag &= ~(IXON | IXOFF);
+ }
+ else
+ {
+ xf86Msg (X_ERROR,
+ "Invalid Option FlowControl value: %s\n", s);
+ return (-1);
+ }
+ }
+
+ if ((xf86SetBoolOption (options, "ClearDTR", FALSE)))
+ {
+#ifdef CLEARDTR_SUPPORT
+# if !defined(Lynx) || defined(TIOCMBIC)
+ val = TIOCM_DTR;
+ SYSCALL (ioctl(fd, TIOCMBIC, &val));
+# else
+ SYSCALL (ioctl(fd, TIOCCDTR, NULL));
+# endif
+#else
+ xf86Msg (X_WARNING,
+ "Option ClearDTR not supported on this OS\n");
+ return (-1);
+#endif
+ xf86MarkOptionUsedByName (options, "ClearDTR");
+ }
+
+ if ((xf86SetBoolOption (options, "ClearRTS", FALSE)))
+ {
+#ifdef CLEARRTS_SUPPORT
+ val = TIOCM_RTS;
+ SYSCALL (ioctl(fd, TIOCMBIC, &val));
+#else
+ xf86Msg (X_WARNING,
+ "Option ClearRTS not supported on this OS\n");
+ return (-1);
+#endif
+ xf86MarkOptionUsedByName (options, "ClearRTS");
+ }
+
+ SYSCALL (r = tcsetattr (fd, TCSANOW, &t));
+ return (r);
+}
+
+int
+xf86SetSerialSpeed (int fd, int speed)
+{
+ struct termios t;
+ int baud, r;
+
+ if (fd < 0)
+ return -1;
+
+ /* Don't try to set parameters for non-tty devices. */
+ if (!isatty(fd))
+ return 0;
+
+ SYSCALL (tcgetattr (fd, &t));
+
+ if ((baud = GetBaud (speed)))
+ {
+ cfsetispeed (&t, baud);
+ cfsetospeed (&t, baud);
+ }
+ else
+ {
+ xf86Msg (X_ERROR,
+ "Invalid Option BaudRate value: %d\n", speed);
+ return (-1);
+ }
+
+ SYSCALL (r = tcsetattr (fd, TCSANOW, &t));
+ return (r);
+}
+
+int
+xf86ReadSerial (int fd, void *buf, int count)
+{
+ int r;
+
+ SYSCALL (r = read (fd, buf, count));
+ return (r);
+}
+
+int
+xf86WriteSerial (int fd, const void *buf, int count)
+{
+ int r;
+
+ SYSCALL (r = write (fd, buf, count));
+ return (r);
+}
+
+int
+xf86CloseSerial (int fd)
+{
+ int r;
+
+ SYSCALL (r = close (fd));
+ return (r);
+}
+
+int
+xf86WaitForInput (int fd, int timeout)
+{
+ fd_set readfds;
+ struct timeval to;
+ int r;
+
+ FD_ZERO(&readfds);
+
+ if (fd >= 0) {
+ FD_SET(fd, &readfds);
+ }
+
+ to.tv_sec = timeout / 1000000;
+ to.tv_usec = timeout % 1000000;
+
+ if (fd >= 0) {
+ SYSCALL (r = select (FD_SETSIZE, &readfds, NULL, NULL, &to));
+ }
+ else {
+ SYSCALL (r = select (FD_SETSIZE, NULL, NULL, NULL, &to));
+ }
+ if (xf86Verbose >= 9)
+ ErrorF ("select returned %d\n", r);
+ return (r);
+}
+
+int
+xf86SerialSendBreak (int fd, int duration)
+{
+ int r;
+
+ SYSCALL (r = tcsendbreak (fd, duration));
+ return (r);
+
+}
+
+int
+xf86FlushInput(int fd)
+{
+ fd_set fds;
+ struct timeval timeout;
+ char c[4];
+
+ if (tcflush(fd, TCIFLUSH) == 0)
+ return 0;
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ while (select(FD_SETSIZE, &fds, NULL, NULL, &timeout) > 0) {
+ read(fd, &c, sizeof(c));
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ }
+ return 0;
+}
+
+static struct states {
+ int xf;
+ int os;
+} modemStates[] = {
+#ifdef TIOCM_LE
+ { XF86_M_LE, TIOCM_LE },
+#endif
+#ifdef TIOCM_DTR
+ { XF86_M_DTR, TIOCM_DTR },
+#endif
+#ifdef TIOCM_RTS
+ { XF86_M_RTS, TIOCM_RTS },
+#endif
+#ifdef TIOCM_ST
+ { XF86_M_ST, TIOCM_ST },
+#endif
+#ifdef TIOCM_SR
+ { XF86_M_SR, TIOCM_SR },
+#endif
+#ifdef TIOCM_CTS
+ { XF86_M_CTS, TIOCM_CTS },
+#endif
+#ifdef TIOCM_CAR
+ { XF86_M_CAR, TIOCM_CAR },
+#elif defined(TIOCM_CD)
+ { XF86_M_CAR, TIOCM_CD },
+#endif
+#ifdef TIOCM_RNG
+ { XF86_M_RNG, TIOCM_RNG },
+#elif defined(TIOCM_RI)
+ { XF86_M_CAR, TIOCM_RI },
+#endif
+#ifdef TIOCM_DSR
+ { XF86_M_DSR, TIOCM_DSR },
+#endif
+};
+
+static int numStates = sizeof(modemStates) / sizeof(modemStates[0]);
+
+static int
+xf2osState(int state)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < numStates; i++)
+ if (state & modemStates[i].xf)
+ ret |= modemStates[i].os;
+ return ret;
+}
+
+static int
+os2xfState(int state)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < numStates; i++)
+ if (state & modemStates[i].os)
+ ret |= modemStates[i].xf;
+ return ret;
+}
+
+static int
+getOsStateMask(void)
+{
+ int i;
+ int ret = 0;
+ for (i = 0; i < numStates; i++)
+ ret |= modemStates[i].os;
+ return ret;
+}
+
+static int osStateMask = 0;
+
+int
+xf86SetSerialModemState(int fd, int state)
+{
+ int ret;
+ int s;
+
+ if (fd < 0)
+ return -1;
+
+ /* Don't try to set parameters for non-tty devices. */
+ if (!isatty(fd))
+ return 0;
+
+#ifndef TIOCMGET
+ return -1;
+#else
+ if (!osStateMask)
+ osStateMask = getOsStateMask();
+
+ state = xf2osState(state);
+ SYSCALL((ret = ioctl(fd, TIOCMGET, &s)));
+ if (ret < 0)
+ return -1;
+ s &= ~osStateMask;
+ s |= state;
+ SYSCALL((ret = ioctl(fd, TIOCMSET, &s)));
+ if (ret < 0)
+ return -1;
+ else
+ return 0;
+#endif
+}
+
+int
+xf86GetSerialModemState(int fd)
+{
+ int ret;
+ int s;
+
+ if (fd < 0)
+ return -1;
+
+ /* Don't try to set parameters for non-tty devices. */
+ if (!isatty(fd))
+ return 0;
+
+#ifndef TIOCMGET
+ return -1;
+#else
+ SYSCALL((ret = ioctl(fd, TIOCMGET, &s)));
+ if (ret < 0)
+ return -1;
+ return os2xfState(s);
+#endif
+}
+
+int
+xf86SerialModemSetBits(int fd, int bits)
+{
+ int ret;
+ int s;
+
+ if (fd < 0)
+ return -1;
+
+ /* Don't try to set parameters for non-tty devices. */
+ if (!isatty(fd))
+ return 0;
+
+#ifndef TIOCMGET
+ return -1;
+#else
+ s = xf2osState(bits);
+ SYSCALL((ret = ioctl(fd, TIOCMBIS, &s)));
+ return ret;
+#endif
+}
+
+int
+xf86SerialModemClearBits(int fd, int bits)
+{
+ int ret;
+ int s;
+
+ if (fd < 0)
+ return -1;
+
+ /* Don't try to set parameters for non-tty devices. */
+ if (!isatty(fd))
+ return 0;
+
+#ifndef TIOCMGET
+ return -1;
+#else
+ s = xf2osState(bits);
+ SYSCALL((ret = ioctl(fd, TIOCMBIC, &s)));
+ return ret;
+#endif
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/sigio.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/sigio.c
new file mode 100644
index 000000000..660bfa68c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/sigio.c
@@ -0,0 +1,82 @@
+/* sigio.c -- Support for SIGIO handler installation and removal
+ * Created: Thu Jun 3 15:39:18 1999 by faith@precisioninsight.com
+ * Revised: Thu Jun 3 16:16:35 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/shared/sigio.c,v 1.1 1999/06/07 13:01:43 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/sigio.c,v 1.2 1999/06/14 12:02:11 dawes Exp $
+ *
+ */
+
+
+#ifdef XFree86Server
+# include "X.h"
+# include "xf86.h"
+# include "xf86drm.h"
+# include "xf86_OSlib.h"
+# include "xf86drm.h"
+#else
+# include <unistd.h>
+# include <signal.h>
+# include <fcntl.h>
+#endif
+
+/*
+ * Linux libc5 defines FASYNC, but not O_ASYNC. Don't know if it is
+ * functional or not.
+ */
+#if defined(FASYNC) && !defined(O_ASYNC)
+# define O_ASYNC FASYNC
+#endif
+
+int
+xf86InstallSIGIOHandler(int fd, void (*f)(int))
+{
+ struct sigaction sa;
+ struct sigaction osa;
+
+ sigemptyset(&sa.sa_mask);
+ sigaddset(&sa.sa_mask, SIGIO);
+ sa.sa_flags = 0;
+ sa.sa_handler = f;
+ sigaction(SIGIO, &sa, &osa);
+ fcntl(fd, F_SETOWN, getpid());
+ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_ASYNC);
+ return 0;
+}
+
+int
+xf86RemoveSIGIOHandler(int fd)
+{
+ struct sigaction sa;
+ struct sigaction osa;
+
+ sigemptyset(&sa.sa_mask);
+ sigaddset(&sa.sa_mask, SIGIO);
+ sa.sa_flags = 0;
+ sa.sa_handler = SIG_DFL;
+ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_ASYNC);
+ sigaction(SIGIO, &sa, &osa);
+ return 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/stdResource.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/stdResource.c
new file mode 100644
index 000000000..0ff07dbbc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/stdResource.c
@@ -0,0 +1,188 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/stdResource.c,v 1.9 1999/08/21 13:48:41 dawes Exp $ */
+
+/* Standard resource information code */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86Privstr.h"
+#include "xf86Pci.h"
+#define NEED_OS_RAC_PROTOS
+#include "xf86_OSlib.h"
+
+#ifdef USESTDRES
+#define xf86StdAccWindowsFromOS xf86AccWindowsFromOS
+#define xf86StdAccResFromOS xf86AccResFromOS
+#define xf86StdInitOSPciAllocator xf86InitOSPciAllocator
+#endif
+
+resPtr
+xf86StdAccWindowsFromOS(void)
+{
+ /* Fallback is to allow addressing of all memory space */
+ resPtr ret = NULL;
+ resRange range;
+
+ RANGE(range,0,0xffffffff,ResExcMemBlock);
+ ret = xf86AddResToList(ret, &range, -1);
+
+ /* Fallback is to allow addressing of all I/O space */
+ RANGE(range,0,0xffff,ResExcIoBlock);
+ ret = xf86AddResToList(ret, &range, -1);
+ return ret;
+}
+
+resPtr
+xf86StdAccResFromOS(resPtr ret)
+{
+ resRange range;
+
+ /*
+ * Fallback is to claim the following areas:
+ *
+ * 0x00000000 - 0x0009ffff low 640k host memory
+ * 0x000f0000 - 0x000fffff system BIOS
+ * 0x00100000 - 0x3fffffff low 1G - 1MB host memory
+ * 0xfec00000 - 0xfecfffff default I/O APIC config space
+ * 0xfee00000 - 0xfeefffff default Local APIC config space
+ * 0xffe00000 - 0xffffffff high BIOS area (should this be included?)
+ *
+ * reference: Intel 440BX AGP specs
+ */
+
+ /* Fallback is to claim 0x0 - 0x9ffff and 0x100000 - 0x7fffffff */
+ RANGE(range,0,0x9ffff,ResExcMemBlock);
+ ret = xf86AddResToList(ret, &range, -1);
+ RANGE(range,0xf0000,0xfffff,ResExcMemBlock);
+ ret = xf86AddResToList(ret, &range, -1);
+ RANGE(range,0x100000,0x3fffffff,ResExcMemBlock | ResBios);
+ ret = xf86AddResToList(ret, &range, -1);
+ RANGE(range,0xfec00000,0xfecfffff,ResExcMemBlock | ResBios);
+ ret = xf86AddResToList(ret, &range, -1);
+ RANGE(range,0xfee00000,0xfeefffff,ResExcMemBlock | ResBios);
+ ret = xf86AddResToList(ret, &range, -1);
+ RANGE(range,0xffe00000,0xffffffff,ResExcMemBlock | ResBios);
+ ret = xf86AddResToList(ret, &range, -1);
+
+ /* Fallback is to claim well known ports in the 0x0 - 0x3ff range */
+ /* Possibly should claim some of them as sparse ranges */
+
+ RANGE(range,0,0x1ff,ResExcIoBlock);
+ ret = xf86AddResToList(ret, &range, -1);
+ /* XXX add others */
+ return ret;
+}
+
+static resPtr *pSysRes = NULL;
+static resPtr PciRes = NULL;
+
+static PciBusPtr
+xf86FindPciBridgeInfo(const pciConfigPtr *pciInfo)
+{
+ const pciConfigPtr *pcrpp;
+ pciConfigPtr pcrp;
+ resRange range;
+ PciBusPtr PciBus, PciBusBase;
+
+ /* Get the current address ranges for each additional PCI bus */
+ /* Bus zero is a little special */
+ PciBus = PciBusBase = xnfcalloc(1, sizeof(PciBusRec));
+ PciBus->subclass = PCI_SUBCLASS_BRIDGE_HOST;
+ PciBus->primary = -1;
+ PciBus->secondary = 0;
+ /* for the primary host bridge assume: io: 0-0xffff mem: 0-0xffffffff */
+ /* prefetchable range is unknown therefore we don't set it */
+ RANGE(range, 0, 0xFFFF, ResIo | ResBlock | ResExclusive);
+ PciBus->io = xf86AddResToList(NULL, &range, -1);
+ RANGE(range, 0, ~(memType)0, ResMem | ResBlock | ResExclusive);
+ PciBus->mem = xf86AddResToList(NULL, &range, -1);
+ /* Add each PCI-PCI bridge */
+ /* XXX What about secondary host bridges?? */
+ for (pcrpp = pciInfo, pcrp = *pcrpp; pcrp; pcrp = *(++pcrpp)) {
+ if (pcrp->pci_base_class == PCI_CLASS_BRIDGE &&
+ pcrp->pci_sub_class == PCI_SUBCLASS_BRIDGE_PCI) {
+ PciBus->next = xnfcalloc(1, sizeof(PciBusRec));
+ PciBus = PciBus->next;
+ PciBus->secondary = pcrp->pci_secondary_bus_number;
+ PciBus->primary = pcrp->pci_primary_bus_number;
+ PciBus->subordinate = pcrp->pci_subordinate_bus_number;
+ PciBus->brbus = pcrp->busnum;
+ PciBus->brdev = pcrp->devnum;
+ PciBus->brfunc = pcrp->funcnum;
+ PciBus->subclass = pcrp->pci_sub_class;
+ PciBus->brcontrol = pcrp->pci_bridge_control;
+ if (pcrp->pci_io_base <= pcrp->pci_io_limit) {
+ RANGE(range,pcrp->pci_io_base << 8,
+ (pcrp->pci_io_limit << 8) | 0xfff,
+ ResIo | ResBlock | ResExclusive);
+ PciBus->io = xf86AddResToList(NULL, &range, -1);
+ }
+ if (pcrp->pci_mem_base <= pcrp->pci_mem_limit) {
+ RANGE(range,pcrp->pci_mem_base << 16,
+ (pcrp->pci_mem_limit << 16) | 0xfffff,
+ ResMem | ResBlock | ResExclusive);
+ PciBus->mem = xf86AddResToList(NULL, &range, -1);
+ }
+ if (pcrp->pci_prefetch_mem_base <= pcrp->pci_prefetch_mem_limit) {
+ RANGE(range,pcrp->pci_prefetch_mem_base << 16,
+ (pcrp->pci_prefetch_mem_limit << 16) | 0xfffff,
+ ResMem | ResBlock | ResExclusive);
+ PciBus->pmem = xf86AddResToList(NULL, &range, -1);
+ }
+ xf86MsgVerb(X_INFO, 3, "Bus %d: bridge is at (%d:%d:%d), "
+ "(%d,%d,%d), BCTRL: 0x%02x (VGA_EN is %s)\n",
+ PciBus->secondary, PciBus->brbus, PciBus->brdev,
+ PciBus->brfunc, PciBus->primary,
+ PciBus->secondary, PciBus->subordinate,
+ PciBus->brcontrol,
+ (PciBus->brcontrol & PCI_PCI_BRIDGE_VGA_EN)
+ ? "set" : "cleared");
+ xf86MsgVerb(X_INFO, 3, "Bus %d I/O range:\n", PciBus->secondary);
+ xf86PrintResList(3, PciBus->io);
+ xf86MsgVerb(X_INFO, 3,
+ "Bus %d non-prefetchable memory range:\n",
+ PciBus->secondary);
+ xf86PrintResList(3, PciBus->mem);
+ xf86MsgVerb(X_INFO, 3, "Bus %d prefetchable memory range:\n",
+ PciBus->secondary);
+ xf86PrintResList(3, PciBus->pmem);
+ }
+ if (pcrp->pci_base_class == PCI_CLASS_BRIDGE &&
+ pcrp->pci_sub_class == PCI_SUBCLASS_BRIDGE_ISA) {
+ PciBus->next = xnfcalloc(1, sizeof(PciBusRec));
+ PciBus = PciBus->next;
+ PciBus->primary = 0;
+ PciBus->secondary = -1;
+ PciBus->brbus = pcrp->busnum;
+ PciBus->brdev = pcrp->devnum;
+ PciBus->brfunc = pcrp->funcnum;
+ PciBus->subclass = pcrp->pci_sub_class;
+ }
+ }
+ return PciBusBase;
+
+}
+
+PciBusPtr
+xf86StdInitOSPciAllocator(const pciConfigPtr *pciInfo, resPtr *sysRes,
+ const resPtr pciRes)
+{
+ resPtr res, tmp_res;
+
+ /* Initialise the pointers to the system exclusive lists */
+ pSysRes = sysRes;
+
+ if (!pciInfo)
+ return NULL;
+
+ /* Make a local copy of the current non-system PCI allocations */
+ PciRes = xf86DupResList(pciRes);
+
+ /* resources assigned by bios should be avoided */
+ res = xf86DupResList(pciRes);
+ (*sysRes) = xf86JoinResLists(res,(*sysRes));
+
+ return xf86FindPciBridgeInfo(pciInfo);
+}
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/std_kbdEv.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/std_kbdEv.c
new file mode 100644
index 000000000..329346910
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/std_kbdEv.c
@@ -0,0 +1,46 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/std_kbdEv.c,v 3.3 1999/05/07 02:56:23 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Thomas Roell and David Dawes
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Thomas Roell and
+ * David Dawes makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THOMAS ROELL AND DAVID DAWES DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID DAWES 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.
+ *
+ */
+/* $XConsortium: std_kbdEv.c /main/4 1996/03/11 10:47:33 kaleb $ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+void
+xf86KbdEvents()
+{
+ unsigned char rBuf[64];
+ int nBytes, i;
+
+ if ((nBytes = read( xf86Info.consoleFd, (char *)rBuf, sizeof(rBuf)))
+ > 0)
+ {
+ for (i = 0; i < nBytes; i++)
+ xf86PostKbdEvent(rBuf[i]);
+ }
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/std_mouse.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/std_mouse.c
new file mode 100644
index 000000000..218534d09
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/std_mouse.c
@@ -0,0 +1,55 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/std_mouse.c,v 3.7 1998/07/25 16:57:01 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Thomas Roell and David Dawes
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Thomas Roell and
+ * David Dawes makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THOMAS ROELL AND DAVID DAWES DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID DAWES 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.
+ *
+ */
+/* $XConsortium: std_mouse.c /main/5 1996/03/11 10:47:40 kaleb $ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+int
+xf86MouseOff(MouseDevPtr mouse, Bool doclose)
+{
+ int oldfd;
+
+ if ((oldfd = mouse->mseFd) >= 0)
+ {
+ if (mouse->mseType == PROT_LOGI)
+ {
+ write(mouse->mseFd, "U", 1);
+ }
+ if (mouse->oldBaudRate > 0) {
+ xf86SetMouseSpeed(mouse,
+ mouse->baudRate,
+ mouse->oldBaudRate,
+ xf86MouseCflags[mouse->mseType]);
+ }
+ close(mouse->mseFd);
+ oldfd = mouse->mseFd;
+ mouse->mseFd = -1;
+ }
+ return(oldfd);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/std_mseEv.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/std_mseEv.c
new file mode 100644
index 000000000..ad01a3af9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/std_mseEv.c
@@ -0,0 +1,44 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/std_mseEv.c,v 3.5 1999/05/07 02:56:23 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Thomas Roell and David Dawes
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Thomas Roell and
+ * David Dawes makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THOMAS ROELL AND DAVID DAWES DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID DAWES 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.
+ *
+ */
+/* $XConsortium: std_mseEv.c /main/4 1996/03/11 10:47:48 kaleb $ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+void
+xf86MouseEvents(MouseDevPtr mouse)
+{
+ unsigned char rBuf[64];
+ int nBytes;
+
+ if ((nBytes = read(mouse->mseFd, (char *)rBuf, sizeof(rBuf))) > 0)
+ {
+ xf86MouseProtocol(mouse->device, rBuf, nBytes);
+ }
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/sysv_kbd.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/sysv_kbd.c
new file mode 100644
index 000000000..1bb2da386
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/sysv_kbd.c
@@ -0,0 +1,102 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/sysv_kbd.c,v 3.4 1999/01/14 13:05:11 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Dawes <dawes@XFree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Thomas Roell and David Dawes
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Thomas Roell and
+ * David Dawes makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THOMAS ROELL AND DAVID DAWES DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID DAWES 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.
+ *
+ */
+/* $XConsortium: sysv_kbd.c /main/3 1996/02/21 17:53:59 kaleb $ */
+
+#include "X.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+int
+xf86GetKbdLeds()
+{
+ int leds;
+
+ ioctl(xf86Info.consoleFd, KDGETLED, &leds);
+ return(leds);
+}
+
+void
+xf86SetKbdRepeat(char rad)
+{
+#ifdef KDSETRAD
+ ioctl(xf86Info.consoleFd, KDSETRAD, rad);
+#endif
+}
+
+static int kbdtrans;
+static struct termio kbdtty;
+static char *kbdemap = NULL;
+
+void
+xf86KbdInit()
+{
+#ifdef KDGKBMODE
+ ioctl (xf86Info.consoleFd, KDGKBMODE, &kbdtrans);
+#endif
+ ioctl (xf86Info.consoleFd, TCGETA, &kbdtty);
+#if defined(E_TABSZ) && !defined(SCO325)
+ kbdemap = xalloc(E_TABSZ);
+ if (ioctl(xf86Info.consoleFd, LDGMAP, kbdemap) < 0)
+ {
+ xfree(kbdemap);
+ kbdemap = NULL;
+ }
+#endif
+}
+
+int
+xf86KbdOn()
+{
+ struct termio nTty;
+
+ ioctl(xf86Info.consoleFd, KDSKBMODE, K_RAW);
+ ioctl(xf86Info.consoleFd, LDNMAP, 0); /* disable mapping completely */
+ nTty = kbdtty;
+ nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
+ nTty.c_oflag = 0;
+ nTty.c_cflag = CREAD | CS8 | B9600;
+ nTty.c_lflag = 0;
+ nTty.c_cc[VTIME]=0;
+ nTty.c_cc[VMIN]=1;
+ ioctl(xf86Info.consoleFd, TCSETA, &nTty);
+ return(xf86Info.consoleFd);
+}
+
+int
+xf86KbdOff()
+{
+ if (kbdemap)
+ {
+ ioctl(xf86Info.consoleFd, LDSMAP, kbdemap);
+ }
+ ioctl(xf86Info.consoleFd, KDSKBMODE, kbdtrans);
+ ioctl(xf86Info.consoleFd, TCSETA, &kbdtty);
+ return(xf86Info.consoleFd);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/sysv_tty.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/sysv_tty.c
new file mode 100644
index 000000000..40bff4e47
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/sysv_tty.c
@@ -0,0 +1,162 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/sysv_tty.c,v 3.12 1999/05/07 02:56:23 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Thomas Roell and David Dawes
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Thomas Roell and
+ * David Dawes makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THOMAS ROELL AND DAVID DAWES DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID DAWES 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.
+ *
+ */
+/* $XConsortium: sysv_tty.c /main/7 1996/10/19 18:07:52 kaleb $ */
+
+#include "X.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+static Bool not_a_tty = FALSE;
+
+void
+xf86SetMouseSpeed(MouseDevPtr mouse, int old, int new, unsigned cflag)
+{
+ struct termio tty;
+ char *c;
+
+ if (not_a_tty)
+ return;
+
+ if (ioctl(mouse->mseFd, TCGETA, &tty) < 0)
+ {
+ not_a_tty = TRUE;
+ xf86Msg(X_WARNING, "unable to get status of mouse fd (%s)\n",
+ strerror(errno));
+ return;
+ }
+
+ /* this will query the initial baudrate only once */
+ if (mouse->oldBaudRate < 0) {
+ switch (tty.c_cflag & CBAUD)
+ {
+ case B9600:
+ mouse->oldBaudRate = 9600;
+ break;
+ case B4800:
+ mouse->oldBaudRate = 4800;
+ break;
+ case B2400:
+ mouse->oldBaudRate = 2400;
+ break;
+ case B1200:
+ default:
+ mouse->oldBaudRate = 1200;
+ break;
+ }
+ }
+
+ tty.c_iflag = IGNBRK | IGNPAR;
+ tty.c_oflag = 0;
+ tty.c_lflag = 0;
+ tty.c_cflag = cflag;
+ tty.c_line = 0;
+ tty.c_cc[VTIME] = 0;
+ tty.c_cc[VMIN] = 1;
+
+ switch (old)
+ {
+ case 9600:
+ tty.c_cflag |= B9600;
+ break;
+ case 4800:
+ tty.c_cflag |= B4800;
+ break;
+ case 2400:
+ tty.c_cflag |= B2400;
+ break;
+ case 1200:
+ default:
+ tty.c_cflag |= B1200;
+ }
+
+ if (ioctl(mouse->mseFd, TCSETAW, &tty) < 0)
+ {
+ if (xf86Info.allowMouseOpenFail) {
+ xf86Msg(X_WARNING,
+ "Unable to set status of mouse fd (%s) - Continuing...\n",
+ strerror(errno));
+ return;
+ }
+ xf86FatalError("Unable to set status of mouse fd (%s)\n",
+ strerror(errno));
+ }
+
+ switch (new)
+ {
+ case 9600:
+ c = "*q";
+ tty.c_cflag |= B9600;
+ break;
+ case 4800:
+ c = "*p";
+ tty.c_cflag |= B4800;
+ break;
+ case 2400:
+ c = "*o";
+ tty.c_cflag |= B2400;
+ break;
+ case 1200:
+ default:
+ c = "*n";
+ tty.c_cflag |= B1200;
+ }
+
+ if (mouse->mseType == P_LOGIMAN || mouse->mseType == P_LOGI)
+ {
+ if (write(mouse->mseFd, c, 2) != 2)
+ {
+ if (xf86AllowMouseOpenFail) {
+ xf86Msg(X_WARNING,
+ "Unable to write to mouse fd (%s) - Continuing...\n",
+ strerror(errno));
+ return;
+ }
+ xf86FatalError("Unable to write to mouse fd (%s)\n",
+ strerror(errno));
+ }
+ }
+ usleep(100000);
+
+ if (ioctl(mouse->mseFd, TCSETAW, &tty) < 0)
+ {
+ if (xf86AllowMouseOpenFail) {
+ xf86Msg(X_WARNING,
+ "Unable to set status of mouse fd (%s) - Continuing...\n",
+ strerror(errno));
+ return;
+ }
+ xf86FatalError("Unable to set status of mouse fd (%s)\n",
+ strerror(errno));
+ }
+#ifdef TCMOUSE
+ ioctl(mouse->mseFd, TCMOUSE, 1);
+#endif
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/vidmem.c b/xc/programs/Xserver/hw/xfree86/os-support/shared/vidmem.c
new file mode 100644
index 000000000..d18488c90
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/vidmem.c
@@ -0,0 +1,233 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/vidmem.c,v 1.4 1999/04/25 15:39:36 dawes Exp $ */
+/*
+ * Copyright 1993-1999 by The XFree86 Project, Inc
+ *
+ */
+
+#include "X.h"
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86OSpriv.h"
+
+/*
+ * This file contains the common part of the video memory mapping functions
+ */
+
+/*
+ * Get a piece of the ScrnInfoRec. At the moment, this is only used to hold
+ * the MTRR option information, but it is likely to be expanded if we do
+ * auto unmapping of memory at VT switch.
+ *
+ */
+
+typedef struct {
+ unsigned long physBase;
+ unsigned long size;
+ pointer virtBase;
+ pointer mtrrInfo;
+ int flags;
+} MappingRec, *MappingPtr;
+
+typedef struct {
+ int numMappings;
+ MappingPtr * mappings;
+ Bool mtrrEnabled;
+ MessageType mtrrFrom;
+ Bool mtrrOptChecked;
+ ScrnInfoPtr pScrn;
+} VidMapRec, *VidMapPtr;
+
+static int vidMapIndex = -1;
+
+#define VIDMAPPTR(p) ((VidMapPtr)((p)->privates[vidMapIndex].ptr))
+
+static VidMemInfo vidMemInfo = {FALSE, };
+
+static VidMapPtr
+getVidMapRec(int scrnIndex)
+{
+ VidMapPtr vp;
+
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ if (vidMapIndex < 0)
+ vidMapIndex = xf86AllocateScrnInfoPrivateIndex();
+
+ if (VIDMAPPTR(pScrn) != NULL)
+ return VIDMAPPTR(pScrn);
+
+ vp = pScrn->privates[vidMapIndex].ptr = xnfcalloc(sizeof(VidMapRec), 1);
+ vp->mtrrEnabled = TRUE; /* default to enabled */
+ vp->mtrrFrom = X_DEFAULT;
+ vp->mtrrOptChecked = FALSE;
+ vp->pScrn = pScrn;
+ return vp;
+}
+
+static MappingPtr
+newMapping(VidMapPtr vp)
+{
+ vp->mappings = xnfrealloc(vp->mappings, sizeof(MappingPtr) *
+ (vp->numMappings + 1));
+ vp->mappings[vp->numMappings] = xnfcalloc(sizeof(MappingRec), 1);
+ return vp->mappings[vp->numMappings++];
+}
+
+static MappingPtr
+findMapping(VidMapPtr vp, pointer vbase, unsigned long size)
+{
+ int i;
+
+ for (i = 0; i < vp->numMappings; i++) {
+ if (vp->mappings[i]->virtBase == vbase &&
+ vp->mappings[i]->size == size)
+ return vp->mappings[i];
+ }
+ return NULL;
+}
+
+static void
+removeMapping(VidMapPtr vp, MappingPtr mp)
+{
+ int i, found = 0;
+
+ for (i = 0; i < vp->numMappings; i++) {
+ if (vp->mappings[i] == mp) {
+ found = 1;
+ xfree(vp->mappings[i]);
+ } else if (found) {
+ vp->mappings[i - 1] = vp->mappings[i];
+ }
+ }
+ vp->numMappings--;
+ vp->mappings[vp->numMappings] = NULL;
+}
+
+enum { OPTION_MTRR };
+static OptionInfoRec opts[] =
+{
+ { OPTION_MTRR, "mtrr", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+static void
+checkMtrrOption(VidMapPtr vp)
+{
+ if (!vp->mtrrOptChecked && vp->pScrn->options != NULL) {
+ /*
+ * We get called once for each screen, so reset
+ * the OptionInfoRecs.
+ */
+ opts[0].found = FALSE;
+
+ xf86ProcessOptions(vp->pScrn->scrnIndex, vp->pScrn->options,
+ opts);
+ if (xf86GetOptValBool(opts, OPTION_MTRR, &vp->mtrrEnabled))
+ vp->mtrrFrom = X_CONFIG;
+ vp->mtrrOptChecked = TRUE;
+ }
+}
+
+pointer
+xf86MapVidMem(int ScreenNum, int Flags, unsigned long Base, unsigned long Size)
+{
+ pointer vbase;
+ VidMapPtr vp;
+ MappingPtr mp;
+
+ if (!vidMemInfo.initialised) {
+ memset(&vidMemInfo, 0, sizeof(VidMemInfo));
+ xf86OSInitVidMem(&vidMemInfo);
+ }
+ if (!vidMemInfo.initialised || !vidMemInfo.mapMem)
+ return NULL;
+
+ if ((Flags & VIDMEM_SPARSE) && vidMemInfo.mapMemSparse)
+ vbase = vidMemInfo.mapMemSparse(ScreenNum, Base, Size);
+ else
+ vbase = vidMemInfo.mapMem(ScreenNum, Base, Size);
+ if (!vbase || vbase == (pointer)-1)
+ return NULL;
+
+ vp = getVidMapRec(ScreenNum);
+ mp = newMapping(vp);
+ mp->physBase = Base;
+ mp->size = Size;
+ mp->virtBase = vbase;
+ mp->flags = Flags;
+
+ /*
+ * Check the "mtrr" option even when MTRR isn't supported to avoid
+ * warnings about unrecognised options.
+ */
+ checkMtrrOption(vp);
+
+ if (vp->mtrrEnabled && vidMemInfo.setWC) {
+ if (Flags & VIDMEM_MMIO)
+ mp->mtrrInfo =
+ vidMemInfo.setWC(ScreenNum, Base, Size, FALSE,
+ vp->mtrrFrom);
+ else if (Flags & VIDMEM_FRAMEBUFFER)
+ mp->mtrrInfo =
+ vidMemInfo.setWC(ScreenNum, Base, Size, TRUE,
+ vp->mtrrFrom);
+ }
+ return vbase;
+}
+
+void
+xf86UnMapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+{
+ VidMapPtr vp;
+ MappingPtr mp;
+
+ if (!vidMemInfo.initialised || !vidMemInfo.unmapMem) {
+ xf86DrvMsg(ScreenNum, X_WARNING,
+ "xf86UnMapVidMem() called before xf86MapVidMem()\n");
+ return;
+ }
+
+ vp = getVidMapRec(ScreenNum);
+ mp = findMapping(vp, Base, Size);
+ if (!mp) {
+ xf86DrvMsg(ScreenNum, X_WARNING,
+ "xf86UnMapVidMem: cannot find region for [%p,0x%lx]\n",
+ Base, Size);
+ return;
+ }
+ if (vp->mtrrEnabled && vidMemInfo.undoWC && mp)
+ vidMemInfo.undoWC(ScreenNum, mp->mtrrInfo);
+
+ if ((mp->flags & VIDMEM_SPARSE) && vidMemInfo.unmapMemSparse)
+ vidMemInfo.unmapMemSparse(ScreenNum, Base, Size);
+ else
+ vidMemInfo.unmapMem(ScreenNum, Base, Size);
+ removeMapping(vp, mp);
+}
+
+Bool
+xf86LinearVidMem()
+{
+ if (!vidMemInfo.initialised) {
+ memset(&vidMemInfo, 0, sizeof(VidMemInfo));
+ xf86OSInitVidMem(&vidMemInfo);
+ }
+ return vidMemInfo.linearSupported;
+}
+
+void
+xf86MapReadSideEffects(int ScreenNum, int Flags, pointer base,
+ unsigned long Size)
+{
+ if (!(Flags & VIDMEM_READSIDEEFFECT))
+ return;
+
+ if (!vidMemInfo.initialised || !vidMemInfo.readSideEffects)
+ return;
+
+ vidMemInfo.readSideEffects(ScreenNum, base, Size);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/solx86/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/solx86/Imakefile
new file mode 100644
index 000000000..3a10a4f43
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/solx86/Imakefile
@@ -0,0 +1,55 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/solx86/Imakefile,v 3.12 1999/07/18 15:37:25 dawes Exp $
+
+
+
+
+
+XCOMM $XConsortium: Imakefile /main/5 1996/09/28 17:24:30 rws $
+
+#include <Server.tmpl>
+
+#if !HasGcc
+PROWORKS_INOUT_SRC = solx86_iout.s
+PROWORKS_INOUT_OBJ = solx86_iout.o
+#endif
+
+#if NewInput
+MOUSESRC = solx86_mouse.c
+MOUSEOBJ = solx86_mouse.o
+#else
+MOUSESRC = std_mouse.c std_mseEv.c
+MOUSEOBJ = std_mouse.o std_mseEv.o
+#endif
+
+SRCS = solx86_init.c solx86_vid.c solx86_bios.c sysv_io.c \
+ VTsw_usl.c sysv_kbd.c std_kbdEv.c posix_tty.c $(MOUSESRC) \
+ libc_wrapper.c $(PROWORKS_INOUT_SRC) stdResource.c
+
+OBJS = solx86_init.o solx86_vid.o solx86_bios.o sysv_io.o \
+ VTsw_usl.o sysv_kbd.o std_kbdEv.o posix_tty.o $(MOUSEOBJ) \
+ libc_wrapper.o $(PROWORKS_INOUT_OBJ) stdResource.o
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC) -I$(EXTINCSRC)
+
+RESDEFINES = -DUSESTDRES
+
+DEFINES = $(RESDEFINES)
+
+SubdirLibraryRule($(OBJS))
+NormalLibraryObjectRule()
+NormalAsmObjectRule()
+
+LinkSourceFile(VTsw_usl.c,../shared)
+LinkSourceFile(sysv_kbd.c,../shared)
+LinkSourceFile(posix_tty.c,../shared)
+#if !NewInput
+LinkSourceFile(std_mouse.c,../shared)
+LinkSourceFile(std_mseEv.c,../shared)
+#endif
+LinkSourceFile(std_kbdEv.c,../shared)
+LinkSourceFile(sysv_io.c,../sysv)
+LinkSourceFile(libc_wrapper.c,../shared)
+LinkSourceFile(stdResource.c,../shared)
+
+DependTarget()
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_bios.c b/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_bios.c
new file mode 100644
index 000000000..09ac321a8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_bios.c
@@ -0,0 +1,94 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_bios.c,v 1.2 1999/07/18 15:37:25 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Thomas Roell and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Thomas Roell and
+ * David Wexelblat makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THOMAS ROELL AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID WEXELBLAT 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"
+
+#define _NEED_SYSI86
+#include "xf86.h"
+#include "xf86Priv.h"
+#undef usleep
+#include "xf86_OSlib.h"
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+extern char *apertureDevName;
+
+/*
+ * Read BIOS via mmap()ing physical memory.
+ */
+int
+xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf,
+ int Len)
+{
+ int fd;
+ unsigned char *ptr;
+ char solx86_vtname[20];
+ int psize;
+ int mlen;
+
+ /*
+ * Solaris 2.1 x86 SVR4 (10/27/93)
+ * The server must treat the virtual terminal device file
+ * as the standard SVR4 /dev/pmem. By default, then used VT
+ * is considered the "default" file to open.
+ */
+ if (Base < 0xFFFFF)
+ sprintf(solx86_vtname,"/dev/vt%02d",xf86Info.vtno);
+ else
+ {
+ if (!apertureDevName)
+ if (!xf86LinearVidMem())
+ FatalError("xf86ReadBIOS: Could not mmap "
+ "BIOS [a=%x]\n", Base);
+ sprintf(solx86_vtname, apertureDevName);
+ }
+
+ if ((fd = open(solx86_vtname, O_RDONLY)) < 0)
+ {
+ xf86Msg(X_WARNING, "xf86ReadBIOS: Failed to open %s (%s)\n",
+ solx86_vtname, strerror(errno));
+ return(-1);
+ }
+ psize = xf86getpagesize();
+ mlen = (Offset + Len + psize - 1) & ~psize;
+ /* Base is assumed to be page-aligned. */
+ ptr = (unsigned char *)mmap((caddr_t)0, mlen, PROT_READ,
+ MAP_SHARED, fd, (off_t)Base);
+ if (ptr == MAP_FAILED)
+ {
+ xf86Msg(X_WARNING, "xf86ReadBIOS: %s mmap failed\n",
+ solx86_vtname);
+ close(fd);
+ return(-1);
+ }
+ (void)memcpy(Buf, (void *)(ptr + Offset), Len);
+ (void)munmap((caddr_t)ptr, mlen);
+ (void)close(fd);
+ return(Len);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_init.c b/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_init.c
new file mode 100644
index 000000000..1b29819b5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_init.c
@@ -0,0 +1,387 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_init.c,v 3.5 1998/07/25 16:57:04 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Thomas Roell and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Thomas Roell and
+ * David Wexelblat makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THOMAS ROELL AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: solx86_init.c /main/4 1996/02/21 17:54:10 kaleb $ */
+
+#include <signal.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "X.h"
+#include "Xmd.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+static Bool KeepTty = FALSE;
+#ifdef SVR4
+static Bool Protect0 = FALSE;
+#endif
+static int VTnum = -1;
+static int xf86StartVT = -1;
+
+#define MAX_SECONDS 60
+#define USEC_IN_SEC (unsigned long)1000000
+
+int xf86_solx86usleep(unsigned long);
+static void xf86_solx86sleep(int);
+
+void
+xf86OpenConsole()
+{
+ int fd;
+ struct vt_mode VT;
+ struct vt_stat vtinfo;
+ char vtname1[10];
+ int i, FreeVTslot;
+ MessageType from = X_PROBED;
+
+ if (serverGeneration == 1)
+ {
+ /* check if we're run with euid==0 */
+ if (geteuid() != 0)
+ {
+ FatalError("xf86OpenConsole: Server must be suid root\n");
+ }
+
+ /* Protect page 0 to help find NULL dereferencing */
+ /* mprotect() doesn't seem to work */
+ if (Protect0)
+ {
+ int fd = -1;
+
+ if ((fd = open("/dev/zero", O_RDONLY, 0)) < 0)
+ {
+ xf86Msg(X_WARNING,
+ "xf86OpenConsole: cannot open /dev/zero (%s)\n",
+ strerror(errno));
+ }
+ else
+ {
+ if ((int)mmap(0, 0x1000, PROT_NONE,
+ MAP_FIXED | MAP_SHARED, fd, 0) == -1)
+ {
+ xf86Msg(X_WARNING,
+ "xf86OpenConsole: failed to protect page 0 (%s)\n",
+ strerror(errno));
+ }
+ close(fd);
+ }
+ }
+ /*
+ * setup the virtual terminal manager
+ */
+ if (VTnum != -1)
+ {
+ xf86Info.vtno = VTnum;
+ from = X_CMDLINE;
+ }
+ else
+ {
+ if ((fd = open("/dev/vt00",O_RDWR,0)) < 0)
+ {
+ FatalError(
+ "xf86OpenConsole: Cannot open /dev/vt00 (%s)\n",
+ strerror(errno));
+ }
+ if (ioctl(fd, VT_GETSTATE, &vtinfo) < 0)
+ {
+ FatalError("xf86OpenConsole: Cannot determine current VT\n");
+ }
+ xf86StartVT=vtinfo.v_active;
+
+/* There is a SEVERE problem with x86's VT's the VT_OPENQRY ioctl()
+ * will panic the entire system if all 8 (7 VT's+Console) terminals
+ * are used.
+ * The only other way I've found to determine if there is a free
+ * is to try activating all the the available VT's and see if they
+ * all succeed - if they do, there there is not a free VT, and
+ * the Xserver cannot continue with out panic'ing the system.
+ * (Its ugly, however, it seems to work)
+ * Note there is a possible race condition here, btw.
+ *
+ * David Holland 2/23/94
+ */
+
+ FreeVTslot = 0;
+ for(i=7; (i>=0) && (!FreeVTslot); i--)
+ if (ioctl(fd, VT_ACTIVATE, i) != 0)
+ FreeVTslot = 1;
+
+ if(!FreeVTslot)
+ {
+ FatalError("xf86OpenConsole: Cannot find a free VT\n");
+ }
+
+ if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
+ (xf86Info.vtno == -1))
+ {
+ FatalError("xf86OpenConsole: Cannot find a free VT\n");
+ }
+ close(fd);
+ }
+ xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
+
+ sprintf(vtname1,"/dev/vt%02d",xf86Info.vtno); /* Solaris 2.1 x86 */
+
+ if (!KeepTty)
+ {
+ setpgrp();
+ }
+
+ if (((xf86Info.consoleFd = open(vtname1, O_RDWR | O_NDELAY, 0)) < 0))
+ {
+ FatalError("xf86OpenConsole: Cannot open %s (%s)\n",
+ vtname1, strerror(errno));
+ }
+
+ /* change ownership of the vt */
+ chown(vtname1, getuid(), getgid());
+
+ /*
+ * now get the VT
+ */
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
+ {
+ FatalError("xf86OpenConsole: VT_GETMODE failed\n");
+ }
+
+ signal(SIGUSR1, xf86VTRequest);
+
+ VT.mode = VT_PROCESS;
+ VT.relsig = SIGUSR1;
+ VT.acqsig = SIGUSR1;
+
+ if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
+ {
+ FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0)
+ {
+ FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed\n");
+ }
+ }
+ else
+ {
+ /* serverGeneration != 1 */
+ /*
+ * now get the VT
+ */
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
+ }
+ /*
+ * If the server doesn't have the VT when the reset occurs,
+ * this is to make sure we don't continue until the activate
+ * signal is received.
+ */
+ if (!xf86Screens[0]->vtSema)
+ sleep(5);
+ }
+ return;
+}
+
+void xf86CloseConsole()
+{
+ struct vt_mode VT;
+ char *console = "/dev/vt00";
+ int console_fd;
+
+ /*
+ * Solaris 2.1 x86 doesnt seem to "switch" back to the console
+ * when the VT is relinquished and its mode is reset to auto.
+ * Also, Solaris 2.1 also seems to associate vt00 with the
+ * console so I've opened the "console" back up and made it
+ * the active vt again in text mode and then closed it.
+ * There must be a better hack for this but I'm not aware of
+ * one at this time.
+ *
+ * Doug Anson 11/6/93
+ * danson@lgc.com
+ *
+ * Fixed - 12/5/93 - David Holland - davidh@dorite.use.com
+ * Did the whole thing similarly to the way linux does it
+ */
+
+ /* reset the display back to text mode */
+
+ ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); /* Back to text mode ... */
+ if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1)
+ {
+ VT.mode = VT_AUTO;
+ ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* set dflt vt handling */
+ }
+
+ /* Activate the VT that X was started on */
+
+ ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86StartVT);
+ close(xf86Info.consoleFd); /* make the vt-manager happy */
+ return;
+}
+
+int xf86ProcessArgument(argc, argv, i)
+int argc;
+char *argv[];
+int i;
+{
+ /*
+ * Keep server from detaching from controlling tty. This is useful
+ * when debugging (so the server can receive keyboard signals.
+ */
+ if (!strcmp(argv[i], "-keeptty"))
+ {
+ KeepTty = TRUE;
+ return(1);
+ }
+ /*
+ * Undocumented flag to protect page 0 from read/write to help
+ * catch NULL pointer dereferences. This is purely a debugging
+ * flag.
+ */
+ if (!strcmp(argv[i], "-protect0"))
+ {
+ Protect0 = TRUE;
+ return(1);
+ }
+ if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
+ {
+ if (sscanf(argv[i], "vt%2d", &VTnum) == 0)
+ {
+ UseMsg();
+ VTnum = -1;
+ return(0);
+ }
+ return(1);
+ }
+ return(0);
+}
+
+void xf86UseMsg()
+{
+ ErrorF("vtXX use the specified VT number\n");
+ ErrorF("-keeptty ");
+ ErrorF("don't detach controlling tty (for debugging only)\n");
+ return;
+}
+
+/*
+ * xf86_solx86usleep() - Solaris 2.1 x86 does not have a suitable
+ * replacement (SYSV) for usleep. Although
+ * usleep exists in the BSD compatiblity libs
+ * I dont want to use those libs if possible.
+ *
+ * Doug Anson
+ * danson@lgc.com
+ */
+int
+xf86_solx86usleep(unsigned long usec)
+{
+ int retval = 0;
+ struct itimerval naptime;
+ struct itimerval savetime;
+ unsigned long useconds = 0;
+ unsigned long seconds = 0;
+ int i;
+ unsigned long tmp;
+
+/*
+ * WHY DOESN'T THIS SIMPLY DO A select() WITH NO FILE DESCRIPTORS?
+ */
+
+ /* this time will allow a max of MAX_SECONDS seconds sleeping */
+ for(i=MAX_SECONDS;i>=0;--i)
+ {
+ tmp = (unsigned long)((unsigned long)(i)*USEC_IN_SEC);
+ if (tmp <= usec)
+ {
+ seconds = i;
+ if (i == MAX_SECONDS)
+ useconds = 0;
+ else
+ useconds = (unsigned long)(usec - tmp);
+ i = -1;
+ }
+ }
+
+ /* get the current time */
+ if ((retval=getitimer(ITIMER_REAL,&savetime)) == 0)
+ {
+ /* set the itimer to reflect requested time to sleep */
+ naptime.it_value.tv_sec = savetime.it_value.tv_sec + seconds;
+ naptime.it_value.tv_usec = savetime.it_value.tv_usec + useconds;
+
+ /* specify a one-shot clock */
+ naptime.it_interval.tv_usec = 0;
+ naptime.it_interval.tv_sec = 0;
+
+ /* redisposition SIGALRM */
+ signal(SIGALRM,xf86_solx86sleep);
+
+ /* use SIGLARM */
+ if ((retval=setitimer(ITIMER_REAL,&naptime,NULL)) == 0)
+ /* now just pause */
+ retval = pause();
+
+ /* restore the timer */
+ retval = setitimer(ITIMER_REAL,&savetime,NULL);
+
+ /* restore the SIGALRM disposition */
+ signal(SIGALRM,SIG_DFL);
+ }
+
+ /* return the return value */
+ return retval;
+}
+
+/*
+ * xf86_solx86sleep() - This function is a NOP disposition for
+ * the SIGALRM that is used to implement
+ * usleep() in Solaris 2.1 x86.
+ *
+ * Doug Anson
+ * danson@lgc.com
+ */
+static void
+xf86_solx86sleep(int signo)
+{
+ /* do nothing */
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_iout.s b/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_iout.s
new file mode 100644
index 000000000..5484653a9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_iout.s
@@ -0,0 +1,104 @@
+/ $XFree86: xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_iout.s,v 3.1 1996/12/23 06:51:18 dawes Exp $
+/
+/
+/
+/
+/ $XConsortium: solx86_iout.s /main/4 1996/02/21 17:54:14 kaleb $
+/
+/ File: solx86_iout.s
+/
+/ Purpose: Provide inb(), inw(), inl(), outb(), outw(), outl() functions
+/ for Solaris x86 using the ProWorks compiler by SunPro
+/
+/ Author: Installed into XFree86 SuperProbe by Doug Anson (danson@lgc.com)
+/ Portions donated to XFree86 by Steve Dever (Steve.Dever@Eng.Sun.Com)
+/
+/ Synopsis: (c callable external declarations)
+/ extern unsigned char inb(int port);
+/ extern unsigned short inw(int port);
+/ extern unsigned long inl(int port);
+/ extern void outb(int port, unsigned char value);
+/ extern void outw(int port, unsigned short value);
+/ extern void outl(int port, unsigned long value);
+
+
+.file "solx86_iout.s"
+.text
+
+.globl inb
+.globl inw
+.globl inl
+.globl outb
+.globl outw
+.globl outl
+
+/
+/ unsigned char inb(int port);
+/
+.align 4
+inb:
+ movl 4(%esp),%edx
+ subl %eax,%eax
+ inb (%dx)
+ ret
+.type inb,@function
+.size inb,.-inb
+
+/
+/ unsigned short inw(int port);
+/
+.align 4
+inw:
+ movl 4(%esp),%edx
+ subl %eax,%eax
+ inw (%dx)
+ ret
+.type inw,@function
+.size inw,.-inw
+
+/
+/ unsigned long inl(int port);
+/
+.align 4
+inl:
+ movl 4(%esp),%edx
+ inl (%dx)
+ ret
+.type inl,@function
+.size inl,.-inl
+
+/
+/ void outb(int port, unsigned char value);
+/
+.align 4
+outb:
+ movl 4(%esp),%edx
+ movl 8(%esp),%eax
+ outb (%dx)
+ ret
+.type outb,@function
+.size outb,.-outb
+
+/
+/ void outw(int port, unsigned short value);
+/
+.align 4
+outw:
+ movl 4(%esp),%edx
+ movl 8(%esp),%eax
+ outw (%dx)
+ ret
+.type outw,@function
+.size outw,.-outw
+
+/
+/ void outl(int port, unsigned long value);
+/
+.align 4
+outl:
+ movl 4(%esp),%edx
+ movl 8(%esp),%eax
+ outl (%dx)
+ ret
+.type outl,@function
+.size outl,.-outl
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_misc.c b/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_misc.c
new file mode 100644
index 000000000..eb12834fb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_misc.c
@@ -0,0 +1,99 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_misc.c,v 1.2 1998/07/25 16:57:05 dawes Exp $ */
+
+/*
+ * Copyright 1995-1997 by The XFree86 Project, Inc
+ */
+
+#include <signal.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#define MAX_SECONDS 60
+#define USEC_IN_SEC (unsigned long)1000000
+
+int xf86_solx86usleep(unsigned long);
+static void xf86_solx86sleep(int);
+
+/*
+ * xf86_solx86usleep() - Solaris 2.1 x86 does not have a suitable
+ * replacement (SYSV) for usleep. Although
+ * usleep exists in the BSD compatiblity libs
+ * I dont want to use those libs if possible.
+ *
+ * Doug Anson
+ * danson@lgc.com
+ */
+int
+xf86_solx86usleep(unsigned long usec)
+{
+ int retval = 0;
+ struct itimerval naptime;
+ struct itimerval savetime;
+ unsigned long useconds = 0;
+ unsigned long seconds = 0;
+ int i;
+ unsigned long tmp;
+
+/*
+ * WHY DOESN'T THIS SIMPLY DO A select() WITH NO FILE DESCRIPTORS?
+ */
+
+ /* this time will allow a max of MAX_SECONDS seconds sleeping */
+ for(i=MAX_SECONDS;i>=0;--i)
+ {
+ tmp = (unsigned long)((unsigned long)(i)*USEC_IN_SEC);
+ if (tmp <= usec)
+ {
+ seconds = i;
+ if (i == MAX_SECONDS)
+ useconds = 0;
+ else
+ useconds = (unsigned long)(usec - tmp);
+ i = -1;
+ }
+ }
+
+ /* get the current time */
+ if ((retval=getitimer(ITIMER_REAL,&savetime)) == 0)
+ {
+ /* set the itimer to reflect requested time to sleep */
+ naptime.it_value.tv_sec = savetime.it_value.tv_sec + seconds;
+ naptime.it_value.tv_usec = savetime.it_value.tv_usec + useconds;
+
+ /* specify a one-shot clock */
+ naptime.it_interval.tv_usec = 0;
+ naptime.it_interval.tv_sec = 0;
+
+ /* redisposition SIGALRM */
+ signal(SIGALRM,xf86_solx86sleep);
+
+ /* use SIGLARM */
+ if ((retval=setitimer(ITIMER_REAL,&naptime,NULL)) == 0)
+ /* now just pause */
+ retval = pause();
+
+ /* restore the timer */
+ retval = setitimer(ITIMER_REAL,&savetime,NULL);
+
+ /* restore the SIGALRM disposition */
+ signal(SIGALRM,SIG_DFL);
+ }
+
+ /* return the return value */
+ return retval;
+}
+
+/*
+ * xf86_solx86sleep() - This function is a NOP disposition for
+ * the SIGALRM that is used to implement
+ * usleep() in Solaris 2.1 x86.
+ *
+ * Doug Anson
+ * danson@lgc.com
+ */
+static void
+xf86_solx86sleep(int signo)
+{
+ /* do nothing */
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_mouse.c b/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_mouse.c
new file mode 100644
index 000000000..663593467
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_mouse.c
@@ -0,0 +1,30 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_mouse.c,v 1.2 1999/06/12 15:37:12 dawes Exp $ */
+
+/*
+ * Copyright 1999 by The XFree86 Project, Inc.
+ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Xinput.h"
+#include "xf86OSmouse.h"
+
+static int
+SupportedInterfaces(void)
+{
+ /* XXX This needs to be checked. */
+ return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO | MSE_XPS2;
+}
+
+OSMouseInfoPtr
+xf86OSMouseInit(int flags)
+{
+ OSMouseInfoPtr p;
+
+ p = xcalloc(sizeof(OSMouseInfoRec), 1);
+ if (!p)
+ return NULL;
+ p->SupportedInterfaces = SupportedInterfaces;
+ return p;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_vid.c b/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_vid.c
new file mode 100644
index 000000000..cca4e4356
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_vid.c
@@ -0,0 +1,227 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/solx86/solx86_vid.c,v 3.15 1999/07/18 14:50:18 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Thomas Roell and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Thomas Roell and
+ * David Wexelblat makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THOMAS ROELL AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: solx86_vid.c /main/4 1996/02/21 17:54:20 kaleb $ */
+
+#include "X.h"
+
+#define _NEED_SYSI86
+#include "xf86.h"
+#include "xf86Priv.h"
+#undef usleep
+#include "xf86_OSlib.h"
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+/***************************************************************************/
+/* Video Memory Mapping section */
+/***************************************************************************/
+
+char *apertureDevName = NULL;
+
+Bool
+xf86LinearVidMem()
+{
+
+ int mmapFd;
+
+ apertureDevName = "/dev/xsvc";
+ if ((mmapFd = open(apertureDevName, O_RDWR)) < 0)
+ {
+ apertureDevName = "/dev/fbs/aperture";
+ if((mmapFd = open(apertureDevName, O_RDWR)) < 0)
+ {
+ xf86Msg(X_WARNING,
+ "xf86LinearVidMem: failed to open %s (%s)\n",
+ apertureDevName, strerror(errno));
+ xf86Msg(X_WARNING, "xf86LinearVidMem: either /dev/fbs/aperture, or /dev/xsvc device "
+ "driver required\n");
+ xf86Msg(X_WARNING,
+ "xf86LinearVidMem: linear memory access disabled\n");
+ return FALSE;
+ }
+ }
+ close(mmapFd);
+ return TRUE;
+
+}
+
+pointer
+xf86MapVidMem(int ScreenNum, int Flags, unsigned long Base, unsigned long Size)
+{
+ pointer base;
+ int fd;
+ char solx86_vtname[20];
+
+ /*
+ * Solaris 2.1 x86 SVR4 (10/27/93)
+ * The server must treat the virtual terminal device file
+ * as the standard SVR4 /dev/pmem.
+ *
+ * Uning the /dev/vtXX device as /dev/pmem only works for the
+ * A0000-FFFFF region - If we wish you mmap the linear aperture
+ * it requires a device driver.
+ *
+ * So what we'll do is use /dev/vtXX for the A0000-FFFFF stuff, and
+ * try to use the /dev/fbs/aperture or /dev/xsvc driver if the server
+ * tries to mmap anything > FFFFF
+ * its very very unlikely that the server will try to mmap
+ * anything below FFFFF that can't be handled by /dev/vtXX.
+ *
+ * DWH - 2/23/94
+ * DWH - 1/31/99 (Gee has it really been 5 years?)
+ */
+
+ if(Base < 0xFFFFF)
+ sprintf(solx86_vtname,"/dev/vt%02d",xf86Info.vtno);
+ else
+
+ {
+ if (!apertureDevName)
+ if (!xf86LinearVidMem())
+ FatalError("xf86MapVidMem: Could not mmap "
+ "linear framebuffer [s=%x,a=%x]\n",
+ Size, Base);
+
+ sprintf(solx86_vtname, apertureDevName);
+ }
+
+ if ((fd = open(solx86_vtname, O_RDWR,0)) < 0)
+ {
+ FatalError("xf86MapVidMem: failed to open %s (%s)\n",
+ solx86_vtname, strerror(errno));
+ }
+ base = mmap((caddr_t)0, Size, PROT_READ|PROT_WRITE,
+ MAP_SHARED, fd, (off_t)Base);
+ close(fd);
+ if (base == MAP_FAILED)
+ {
+ FatalError("%s: Could not mmap framebuffer [s=%x,a=%x] (%s)\n",
+ "xf86MapVidMem", Size, Base, strerror(errno));
+ }
+ return(base);
+}
+
+/* ARGSUSED */
+void
+xf86UnMapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+{
+ munmap(Base, Size);
+}
+
+/***************************************************************************/
+/* I/O Permissions section */
+/***************************************************************************/
+
+static Bool ExtendedEnabled = FALSE;
+
+void
+xf86EnableIO()
+{
+
+ if (ExtendedEnabled)
+ return;
+
+ if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0)
+ {
+ FatalError("%s: Failed to set IOPL for I/O\n",
+ "xf86EnableIOPorts");
+ }
+
+ ExtendedEnabled = TRUE;
+ return;
+}
+
+void
+xf86DisableIO()
+{
+ if(!ExtendedEnabled)
+ return;
+
+ sysi86(SI86V86, V86SC_IOPL, 0);
+
+ ExtendedEnabled = FALSE;
+ return;
+}
+
+
+/***************************************************************************/
+/* Interrupt Handling section */
+/***************************************************************************/
+
+Bool xf86DisableInterrupts()
+{
+ if (!ExtendedEnabled)
+ {
+ if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0)
+ {
+ return(FALSE);
+ }
+ }
+
+#ifdef __GNUC__
+ __asm__ __volatile__("cli");
+#else
+ asm("cli");
+#endif /* __GNUC__ */
+
+ if (!ExtendedEnabled)
+ {
+ sysi86(SI86V86, V86SC_IOPL, 0);
+ }
+ return(TRUE);
+}
+
+void xf86EnableInterrupts()
+{
+ if (!ExtendedEnabled)
+ {
+ if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0)
+ {
+ return;
+ }
+ }
+
+#ifdef __GNUC__
+ __asm__ __volatile__("sti");
+#else
+ asm("sti");
+#endif /* __GNUC__ */
+
+ if (!ExtendedEnabled)
+ {
+ sysi86(SI86V86, V86SC_IOPL, 0);
+ }
+ return;
+}
+
+void
+xf86MapReadSideEffects(int ScreenNum, int Flags, pointer Base,
+ unsigned long Size)
+{
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sysv/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/sysv/Imakefile
new file mode 100644
index 000000000..9297a77ed
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sysv/Imakefile
@@ -0,0 +1,60 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sysv/Imakefile,v 3.17 1999/05/22 14:52:28 dawes Exp $
+
+
+
+
+
+XCOMM $XConsortium: Imakefile /main/10 1996/10/25 11:38:05 kaleb $
+
+#include <Server.tmpl>
+
+#if defined(SVR4Architecture) || defined(i386Sco325Architecture)
+BIOS_MOD = bios_mmap
+#else
+BIOS_MOD = bios_devmem
+#endif
+
+#if NewInput
+MOUSESRC = sysv_mouse.c
+MOUSEOBJ = sysv_mouse.o
+#else
+MOUSESRC = std_mouse.c std_mseEv.c
+MOUSEOBJ = std_mouse.o std_mseEv.o
+#endif
+
+SRCS = sysv_init.c sysv_video.c sysv_io.c $(BIOS_MOD).c VTsw_usl.c \
+ sysv_kbd.c std_kbdEv.c posix_tty.c $(MOUSESRC) xqueue.c \
+ libc_wrapper.c stdResource.c vidmem.c
+
+OBJS = sysv_init.o sysv_video.o sysv_io.o $(BIOS_MOD).o VTsw_usl.o \
+ sysv_kbd.o std_kbdEv.o posix_tty.o $(MOUSEOBJ) xqueue.o \
+ libc_wrapper.o stdResource.o vidmem.o
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC) -I$(EXTINCSRC) -I$(SERVERSRC)/mi
+
+RESDEFINES = -DUSESTDRES
+
+DEFINES = $(RESDEFINES)
+
+SubdirLibraryRule($(OBJS))
+NormalLibraryObjectRule()
+
+#if !defined(SVR4Architecture)
+LinkSourceFile(bios_devmem.c,../shared)
+#else
+LinkSourceFile(bios_mmap.c,../shared)
+#endif
+LinkSourceFile(VTsw_usl.c,../shared)
+LinkSourceFile(sysv_kbd.c,../shared)
+LinkSourceFile(std_kbdEv.c,../shared)
+LinkSourceFile(posix_tty.c,../shared)
+#if !NewInput
+LinkSourceFile(std_mouse.c,../shared)
+LinkSourceFile(std_mseEv.c,../shared)
+#endif
+LinkSourceFile(libc_wrapper.c,../shared)
+LinkSourceFile(stdResource.c,../shared)
+LinkSourceFile(vidmem.c,../shared)
+
+DependTarget()
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_init.c b/xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_init.c
new file mode 100644
index 000000000..1e9166712
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_init.c
@@ -0,0 +1,250 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_init.c,v 3.5 1998/07/25 16:57:08 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Thomas Roell and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Thomas Roell and
+ * David Wexelblat makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THOMAS ROELL AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: sysv_init.c /main/4 1996/02/21 17:54:31 kaleb $ */
+
+#include "X.h"
+#include "Xmd.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+static Bool KeepTty = FALSE;
+#ifdef SVR4
+static Bool Protect0 = FALSE;
+#endif
+static int VTnum = -1;
+
+
+void
+xf86OpenConsole()
+{
+ int fd;
+ struct vt_mode VT;
+ char vtname1[10],vtname2[10];
+ MessageType from = X_PROBED;
+
+ if (serverGeneration == 1)
+ {
+ /* check if we're run with euid==0 */
+ if (geteuid() != 0)
+ {
+ FatalError("xf86OpenConsole: Server must be suid root\n");
+ }
+
+#ifdef SVR4
+ /* Protect page 0 to help find NULL dereferencing */
+ /* mprotect() doesn't seem to work */
+ if (Protect0)
+ {
+ int fd = -1;
+
+ if ((fd = open("/dev/zero", O_RDONLY, 0)) < 0)
+ {
+ xf86Msg(X_WARNING,
+ "xf86OpenConsole: cannot open /dev/zero (%s)\n",
+ strerror(errno));
+ }
+ else
+ {
+ if ((int)mmap(0, 0x1000, PROT_NONE,
+ MAP_FIXED | MAP_SHARED, fd, 0) == -1)
+ {
+ xf86Msg(X_WARNING,
+ "xf86OpenConsole: failed to protect page 0 (%s)\n",
+ strerror(errno));
+ }
+ close(fd);
+ }
+ }
+#endif
+ /*
+ * setup the virtual terminal manager
+ */
+ if (VTnum != -1)
+ {
+ xf86Info.vtno = VTnum;
+ from = X_CMDLINE;
+ }
+ else
+ {
+ if ((fd = open("/dev/console",O_WRONLY,0)) < 0)
+ {
+ FatalError(
+ "xf86OpenConsole: Cannot open /dev/console (%s)\n",
+ strerror(errno));
+ }
+ if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
+ (xf86Info.vtno == -1))
+ {
+ FatalError("xf86OpenConsole: Cannot find a free VT\n");
+ }
+ close(fd);
+ }
+ xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
+
+ sprintf(vtname1,"/dev/vc%02d",xf86Info.vtno); /* ESIX */
+ sprintf(vtname2,"/dev/vt%02d",xf86Info.vtno); /* rest of the world */
+
+ if (!KeepTty)
+ {
+ setpgrp();
+ }
+
+ if (((xf86Info.consoleFd = open(vtname1, O_RDWR|O_NDELAY, 0)) < 0) &&
+ ((xf86Info.consoleFd = open(vtname2, O_RDWR|O_NDELAY, 0)) < 0))
+ {
+ FatalError("xf86OpenConsole: Cannot open %s (%s) (%s)\n",
+ vtname2, vtname1, strerror(errno));
+ }
+
+ /* change ownership of the vt */
+ if (chown(vtname1, getuid(), getgid()) < 0)
+ {
+ chown(vtname2, getuid(), getgid());
+ }
+
+ /*
+ * now get the VT
+ */
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
+ {
+ FatalError("xf86OpenConsole: VT_GETMODE failed\n");
+ }
+
+ signal(SIGUSR1, xf86VTRequest);
+
+ VT.mode = VT_PROCESS;
+ VT.relsig = SIGUSR1;
+ VT.acqsig = SIGUSR1;
+ if (ioctl(xf86Info.consoleFd, VT_SETMODE, &VT) < 0)
+ {
+ FatalError("xf86OpenConsole: VT_SETMODE VT_PROCESS failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, KDSETMODE, KD_GRAPHICS) < 0)
+ {
+ FatalError("xf86OpenConsole: KDSETMODE KD_GRAPHICS failed\n");
+ }
+ }
+ else
+ {
+ /* serverGeneration != 1 */
+ /*
+ * now get the VT
+ */
+ if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_ACTIVATE failed\n");
+ }
+ if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
+ {
+ xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
+ }
+ /*
+ * If the server doesn't have the VT when the reset occurs,
+ * this is to make sure we don't continue until the activate
+ * signal is received.
+ */
+ if (!xf86Screens[0]->vtSema)
+ sleep(5);
+ }
+ return;
+}
+
+void
+xf86CloseConsole()
+{
+ struct vt_mode VT;
+
+#if 0
+ ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno);
+ ioctl(xf86Info.consoleFd, VT_WAITACTIVE, 0);
+#endif
+ ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); /* Back to text mode ... */
+ if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1)
+ {
+ VT.mode = VT_AUTO;
+ ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); /* set dflt vt handling */
+ }
+ close(xf86Info.consoleFd); /* make the vt-manager happy */
+ return;
+}
+
+int
+xf86ProcessArgument(int argc, char *argv[], int i)
+{
+ /*
+ * Keep server from detaching from controlling tty. This is useful
+ * when debugging (so the server can receive keyboard signals.
+ */
+ if (!strcmp(argv[i], "-keeptty"))
+ {
+ KeepTty = TRUE;
+ return(1);
+ }
+#ifdef SVR4
+ /*
+ * Undocumented flag to protect page 0 from read/write to help
+ * catch NULL pointer dereferences. This is purely a debugging
+ * flag.
+ */
+ if (!strcmp(argv[i], "-protect0"))
+ {
+ Protect0 = TRUE;
+ return(1);
+ }
+#endif
+ if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
+ {
+ if (sscanf(argv[i], "vt%2d", &VTnum) == 0)
+ {
+ UseMsg();
+ VTnum = -1;
+ return(0);
+ }
+ return(1);
+ }
+ return(0);
+}
+
+void
+xf86UseMsg()
+{
+ ErrorF("vtXX use the specified VT number\n");
+ ErrorF("-keeptty ");
+ ErrorF("don't detach controlling tty (for debugging only)\n");
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_io.c b/xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_io.c
new file mode 100644
index 000000000..9a3b95eef
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_io.c
@@ -0,0 +1,95 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_io.c,v 3.8 1999/05/22 08:40:17 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Thomas Roell and David Dawes
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Thomas Roell and
+ * David Dawes makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THOMAS ROELL AND DAVID DAWES DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID DAWES 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.
+ *
+ */
+/* $XConsortium: sysv_io.c /main/8 1996/10/19 18:08:06 kaleb $ */
+
+#include "X.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+void
+xf86SoundKbdBell(int loudness, int pitch, int duration)
+{
+ if (loudness && pitch)
+ {
+#ifdef KDMKTONE
+ /*
+ * If we have KDMKTONE use it to avoid putting the server
+ * to sleep
+ */
+ ioctl(xf86Info.consoleFd, KDMKTONE,
+ ((1193190 / pitch) & 0xffff) |
+ (((unsigned long)duration *
+ loudness / 50) << 16));
+#else
+ ioctl(xf86Info.consoleFd, KIOCSOUND, 1193180 / pitch);
+ usleep(xf86Info.bell_duration * loudness * 20);
+ ioctl(xf86Info.consoleFd, KIOCSOUND, 0);
+#endif
+ }
+}
+
+void
+xf86SetKbdLeds(int leds)
+{
+#ifdef KBIO_SETMODE
+ ioctl(xf86Info.consoleFd, KBIO_SETMODE, KBM_AT);
+ ioctl(xf86Info.consoleFd, KDSETLED, leds);
+ ioctl(xf86Info.consoleFd, KBIO_SETMODE, KBM_XT);
+#endif
+}
+
+#ifndef NEW_INPUT
+void
+xf86MouseInit(MouseDevPtr mouse)
+{
+ return;
+}
+
+int
+xf86MouseOn(MouseDevPtr mouse)
+{
+ if ((mouse->mseFd = open(mouse->mseDevice, O_RDWR | O_NDELAY)) < 0)
+ {
+ if (xf86Info.allowMouseOpenFail) {
+ xf86Msg(X_WARNING, "Cannot open mouse (%s) - Continuing...\n",
+ strerror(errno));
+ return(-2);
+ }
+ FatalError("Cannot open mouse (%s)\n", strerror(errno));
+ }
+
+ xf86SetupMouse(mouse);
+
+ /* Flush any pending input */
+ ioctl(mouse->mseFd, TCFLSH, 0);
+
+ return(mouse->mseFd);
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_mouse.c b/xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_mouse.c
new file mode 100644
index 000000000..451c918ba
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_mouse.c
@@ -0,0 +1,62 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_mouse.c,v 1.2 1999/07/10 12:17:39 dawes Exp $ */
+
+/*
+ * Copyright 1999 by The XFree86 Project, Inc.
+ */
+
+#include "X.h"
+#include "xf86.h"
+#include "xf86Xinput.h"
+#include "xf86OSmouse.h"
+#ifdef NEW_INPUT
+#include "xqueue.h"
+#endif
+
+static int
+SupportedInterfaces(void)
+{
+ /* XXX Need to check this. */
+ return MSE_SERIAL | MSE_AUTO;
+}
+
+#ifndef ISC
+static const char *internalNames[] = {
+ "Xqueue",
+ NULL
+};
+
+static const char **
+BuiltinNames(void)
+{
+ return internalNames;
+}
+
+static Bool
+CheckProtocol(const char *protocol)
+{
+ int i;
+
+ for (i = 0; internalNames[i]; i++)
+ if (xf86NameCmp(protocol, internalNames[i]) == 0)
+ return TRUE;
+ return FALSE;
+}
+#endif
+
+OSMouseInfoPtr
+xf86OSMouseInit(int flags)
+{
+ OSMouseInfoPtr p;
+
+ p = xcalloc(sizeof(OSMouseInfoRec), 1);
+ if (!p)
+ return NULL;
+ p->SupportedInterfaces = SupportedInterfaces;
+#ifndef ISC
+ p->BuiltinNames = BuiltinNames;
+ p->CheckProtocol = CheckProtocol;
+ p->PreInit = XqueueMousePreInit;
+#endif
+ return p;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_video.c b/xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_video.c
new file mode 100644
index 000000000..7bbbb8013
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_video.c
@@ -0,0 +1,361 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_video.c,v 3.19 1999/05/15 14:31:23 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993 by David Wexelblat <dwex@goblin.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Thomas Roell and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Thomas Roell and
+ * David Wexelblat makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THOMAS ROELL AND DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR DAVID WEXELBLAT 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.
+ *
+ */
+/* $XConsortium: sysv_video.c /main/8 1996/10/25 11:38:09 kaleb $ */
+
+#include "X.h"
+
+#define _NEED_SYSI86
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86OSpriv.h"
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#ifndef SI86IOPL
+#define SET_IOPL() sysi86(SI86V86,V86SC_IOPL,PS_IOPL)
+#define RESET_IOPL() sysi86(SI86V86,V86SC_IOPL,0)
+#else
+#define SET_IOPL() sysi86(SI86IOPL,3)
+#define RESET_IOPL() sysi86(SI86IOPL,0)
+#endif
+
+/***************************************************************************/
+/* Video Memory Mapping section */
+/***************************************************************************/
+
+/*
+ * XXX Support for SVR3 will need to be reworked if needed. In particular
+ * the Region parameter is no longer passed, and will need to be dealt
+ * with internally if required.
+ * OK, i'll rework that thing ... (clean it up a lot)
+ * SVR3 Support only with SVR3_MMAPDRV (mr)
+ *
+ */
+
+#ifdef HAS_SVR3_MMAPDRV
+#ifndef MMAP_DEBUG
+#define MMAP_DEBUG 3
+#endif
+
+struct kd_memloc MapDSC;
+int mmapFd = -2;
+
+static int
+mmapStat(pointer Base, unsigned long Size) {
+
+ int nmmreg,i=0,region=-1;
+ mmapinfo_t *ibuf;
+
+ nmmreg = ioctl(mmapFd, GETNMMREG);
+
+ if(nmmreg <= 0)
+ xf86MsgVerb(X_INFO, MMAP_DEBUG,
+ "\nNo physical memory mapped currently.\n\n");
+ else {
+ if((ibuf = (mmapinfo_t *)malloc(nmmreg*sizeof(mmapinfo_t))) == NULL)
+ xf86Msg(X_WARNING,
+ "Couldn't allocate memory 4 mmapinfo_t\n");
+ else {
+ if(ioctl(mmapFd, GETMMREG, ibuf) != -1)
+ {
+ xf86MsgVerb(X_INFO, MMAP_DEBUG,
+ "# mmapStat: [Size=%x,Base=%x]\n", Size, Base);
+ xf86MsgVerb(X_INFO, MMAP_DEBUG,
+ "# Physical Address Size Reference Count\n");
+ for(i = 0; i < nmmreg; i++) {
+ xf86MsgVerb(X_INFO, MMAP_DEBUG,
+ "%-4d 0x%08X %5dk %5d ",
+ i, ibuf[i].physaddr, ibuf[i].length/1024, ibuf[i].refcnt);
+ if (ibuf[i].physaddr == Base || ibuf[i].length == Size ) {
+ xf86MsgVerb(X_INFO, MMAP_DEBUG,"MATCH !!!");
+ if (region==-1) region=i;
+ }
+ xf86ErrorFVerb(MMAP_DEBUG, "\n");
+ }
+ xf86ErrorFVerb(MMAP_DEBUG, "\n");
+ }
+ free(ibuf);
+ }
+ }
+ if (region == -1 && nmmreg > 0) region=region * i;
+ return(region);
+}
+#endif
+
+
+static Bool
+linearVidMem()
+{
+#ifdef SVR4
+ return TRUE;
+#elif defined(HAS_SVR3_MMAPDRV)
+ xf86MsgVerb(X_INFO, MMAP_DEBUG,
+ "# xf86LinearVidMem: MMAP 2.2.2 called\n");
+
+ if(mmapFd >= 0) return TRUE;
+
+ if ((mmapFd = open("/dev/mmap", O_RDWR)) != -1)
+ {
+ if(ioctl(mmapFd, GETVERSION) < 0x0222) {
+ xf86Msg(X_WARNING,
+ "xf86LinearVidMem: MMAP 2.2.2 or above required\n");
+ xf86ErrorF("\tlinear memory access disabled\n");
+ return FALSE;
+ }
+ return TRUE;
+ }
+ xf86Msg(X_WARNING, "xf86LinearVidMem: failed to open /dev/mmap (%s)\n",
+ strerror(errno));
+ xf86ErrorF("\tlinear memory access disabled\n");
+ return FALSE;
+#endif
+}
+
+static pointer
+mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size)
+{
+ pointer base;
+ int fd;
+
+#if defined(SVR4)
+ if ((fd = open(DEV_MEM, O_RDWR)) < 0)
+ {
+ FatalError("xf86MapVidMem: failed to open %s (%s)\n",
+ DEV_MEM, strerror(errno));
+ }
+ base = mmap((caddr_t)0, Size, PROT_READ|PROT_WRITE,
+ MAP_SHARED, fd, (off_t)Base);
+ close(fd);
+ if (base == MAP_FAILED)
+ {
+ FatalError("%s: Could not mmap framebuffer [s=%x,a=%x] (%s)\n",
+ "xf86MapVidMem", Size, Base, strerror(errno));
+ }
+#else /* SVR4 */
+#ifdef HAS_SVR3_MMAPDRV
+
+ xf86MsgVerb(X_INFO, MMAP_DEBUG, "# xf86MapVidMem: MMAP 2.2.2 called\n");
+ xf86MsgVerb(X_INFO, MMAP_DEBUG,
+ "MMAP_VERSION: 0x%x\n",ioctl(mmapFd, GETVERSION));
+ if (ioctl(mmapFd, GETVERSION) == -1)
+ {
+ xf86LinearVidMem();
+ }
+ xf86MsgVerb(X_INFO, MMAP_DEBUG,
+ "MMAP_VERSION: 0x%x\n",ioctl(mmapFd, GETVERSION));
+ xf86MsgVerb(X_INFO, MMAP_DEBUG,
+ "xf86MapVidMem: Screen: %d\n", ScreenNum);
+ mmapStat(Base,Size);
+ /* To force the MMAP driver to provide the address */
+ base = (pointer)0;
+ xf86MsgVerb(X_INFO, MMAP_DEBUG,
+ "xf86MapVidMem: [s=%x,a=%x]\n", Size, Base);
+ MapDSC.vaddr = (char *)base;
+ MapDSC.physaddr = (char *)Base;
+ MapDSC.length = Size;
+ MapDSC.ioflg = 1;
+ if(mmapFd >= 0)
+ {
+ if((base = (pointer)ioctl(mmapFd, MAP, &MapDSC)) == (pointer)-1)
+ {
+ FatalError("%s: Could not mmap framebuffer [s=%x,a=%x] (%s)\n",
+ "xf86MapVidMem", Size, Base, strerror(errno));
+ /* NOTREACHED */
+ }
+
+ /* Next time we want the same address! */
+ MapDSC.vaddr = (char *)base;
+ }
+
+ xf86MsgVerb(X_INFO, MMAP_DEBUG,
+ "MapDSC.vaddr : 0x%x\n", MapDSC.vaddr);
+ xf86MsgVerb(X_INFO, MMAP_DEBUG,
+ "MapDSC.physaddr: 0x%x\n", MapDSC.physaddr);
+ xf86MsgVerb(X_INFO, MMAP_DEBUG,
+ "MapDSC.length : %d\n", MapDSC.length);
+ mmapStat(Base,Size);
+ xf86MsgVerb(X_INFO, MMAP_DEBUG,
+ "xf86MapVidMem: [s=%x,a=%x,b=%x]\n", Size, Base, base);
+ xf86MsgVerb(X_INFO, MMAP_DEBUG,
+ "xf86MapVidMem: SUCCEED Mapping FrameBuffer \n");
+#endif /* HAS_SVR3_MMAPDRV */
+#endif /* SVR4 */
+ return(base);
+}
+
+/* ARGSUSED */
+static void
+unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+{
+#if defined (SVR4)
+ munmap(Base, Size);
+#else /* SVR4 */
+#ifdef HAS_SVR3_MMAPDRV
+ xf86MsgVerb(X_INFO, MMAP_DEBUG,
+ "# xf86UnMapVidMem: UNMapping FrameBuffer\n");
+ mmapStat(Base,Size);
+ ioctl(mmapFd, UNMAPRM , Base);
+ mmapStat(Base,Size);
+ xf86MsgVerb(X_INFO, MMAP_DEBUG,
+ "# xf86UnMapVidMem: Screen: %d [v=%x]\n", ScreenNum, Base);
+#endif /* HAS_SVR3_MMAPDRV */
+#endif /* SVR4 */
+ return;
+}
+
+#if defined(SVR4) && defined(i386) && !defined(sun)
+/*
+ * For some SVR4 versions, a 32-bit read is done for the first location
+ * in each page when the page is first mapped. If this is done while
+ * memory access is enabled for regions that have read side-effects,
+ * this can cause unexpected results, including lockups on some hardware.
+ * This function is called to make sure each page is mapped while it is
+ * safe to do so.
+ */
+
+/*
+ * XXX Should get this the correct way (see os/xalloc.c), but since this is
+ * for one platform I'll be lazy.
+ */
+#define X_PAGE_SIZE 4096
+
+static void
+readSideEffects(int ScreenNum, pointer Base, unsigned long Size)
+{
+ unsigned long base, end, addr;
+ CARD32 val;
+
+ base = (unsigned long)Base;
+ end = base + Size;
+
+ for (addr = base; addr < end; addr += X_PAGE_SIZE)
+ val = *(volatile CARD32 *)addr;
+}
+#endif
+
+void
+xf86OSInitVidMem(VidMemInfoPtr pVidMem)
+{
+ pVidMem->linearSupported = linearVidMem();
+ pVidMem->mapMem = mapVidMem;
+ pVidMem->unmapMem = unmapVidMem;
+#if defined(SVR4) && defined(i386) && !defined(sun)
+ pVidMem->readSideEffects = readSideEffects;
+#endif
+ pVidMem->initialised = TRUE;
+}
+
+/***************************************************************************/
+/* I/O Permissions section */
+/***************************************************************************/
+
+static Bool ExtendedEnabled = FALSE;
+static Bool InitDone = FALSE;
+
+void
+xf86EnableIO()
+{
+ int i;
+
+ if (ExtendedEnabled)
+ return;
+
+ if (SET_IOPL() < 0)
+ {
+ FatalError(
+ "xf86EnableIO: Failed to set IOPL for extended I/O\n");
+ }
+ ExtendedEnabled = TRUE;
+
+ return;
+}
+
+void
+xf86DisableIO()
+{
+ if (!ExtendedEnabled)
+ return;
+
+ RESET_IOPL();
+ ExtendedEnabled = FALSE;
+
+ return;
+}
+
+/***************************************************************************/
+/* Interrupt Handling section */
+/***************************************************************************/
+
+Bool
+xf86DisableInterrupts()
+{
+ if (!ExtendedEnabled)
+ {
+ if (SET_IOPL() < 0)
+ {
+ return(FALSE);
+ }
+ }
+
+#ifdef __GNUC__
+ __asm__ __volatile__("cli");
+#else
+ asm("cli");
+#endif /* __GNUC__ */
+
+ if (!ExtendedEnabled)
+ {
+ RESET_IOPL();
+ }
+ return(TRUE);
+}
+
+void
+xf86EnableInterrupts()
+{
+ if (!ExtendedEnabled)
+ {
+ if (SET_IOPL() < 0)
+ {
+ return;
+ }
+ }
+
+#ifdef __GNUC__
+ __asm__ __volatile__("sti");
+#else
+ asm("sti");
+#endif /* __GNUC__ */
+
+ if (!ExtendedEnabled)
+ {
+ RESET_IOPL();
+ }
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sysv/xqueue.c b/xc/programs/Xserver/hw/xfree86/os-support/sysv/xqueue.c
new file mode 100644
index 000000000..2d7891a7e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sysv/xqueue.c
@@ -0,0 +1,799 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sysv/xqueue.c,v 3.17 1999/05/23 04:26:08 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1993-1999 by The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The copyright holders make no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/* $XConsortium: xqueue.c /main/8 1996/10/19 18:08:11 kaleb $ */
+
+#include "X.h"
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#ifdef NEW_INPUT
+#include "xf86Xinput.h"
+#include "xf86OSmouse.h"
+#include "xqueue.h"
+#endif
+
+#ifdef XQUEUE
+
+static xqEventQueue *XqueQaddr;
+static int xqueFd = -1;
+#ifndef XQUEUE_ASYNC
+static int xquePipe[2];
+#endif
+
+#ifdef XKB
+#include "inputstr.h"
+#include <X11/extensions/XKB.h>
+#include <X11/extensions/XKBstr.h>
+#include <X11/extensions/XKBsrv.h>
+extern Bool noXkbExtension;
+#endif
+
+#include "xf86Xinput.h"
+#include "mipointer.h"
+
+#ifdef NEW_INPUT
+typedef struct {
+ int xquePending;
+ int xqueSema;
+} XqInfoRec, *XqInfoPtr;
+
+InputInfoPtr XqMouse = NULL;
+InputInfoPtr XqKeyboard = NULL;
+#endif
+
+#ifndef XQUEUE_ASYNC
+/*
+ * xf86XqueSignal --
+ * Trap the signal from xqueue and let it be known that events are
+ * ready for collection
+ */
+
+static void
+xf86XqueSignal(int signum)
+{
+#ifndef NEW_INPUT
+ xf86Info.mouseDev->xquePending = 1;
+#else
+ ((XqInfoPtr)(((MouseDevPtr)(XqMouse->private))->mousePriv))->xquePending = 1;
+#endif
+ /*
+ * This is a hack, but it is the only reliable way I can find of letting
+ * the main select() loop know that there is more input waiting. Receiving
+ * a signal will interrupt select(), but there is no way I can find of
+ * dealing with events that come in between the end of processing the
+ * last set and when select() gets called.
+ *
+ * Suggestions for better ways of dealing with this without going back to
+ * asynchronous event processing are welcome.
+ */
+#ifdef DEBUG
+ ErrorF("xf86XqueSignal\n");
+#endif
+ write(xquePipe[1], "X", 1);
+ signal(SIGUSR2, xf86XqueSignal);
+}
+#endif
+
+
+#ifndef NEW_INPUT
+/*
+ * xf86XqueRequest --
+ * Notice an i/o request from the xqueue.
+ */
+
+void
+xf86XqueRequest()
+{
+ xqEvent *XqueEvents;
+ int XqueHead;
+ char buf[100];
+
+ if (xqueFd < 0)
+ return;
+
+ XqueEvents = XqueQaddr->xq_events;
+ XqueHead = XqueQaddr->xq_head;
+
+ while (XqueHead != XqueQaddr->xq_tail)
+ {
+
+ switch(XqueEvents[XqueHead].xq_type) {
+
+ case XQ_BUTTON:
+ xf86PostMseEvent(xf86Info.pMouse,
+ ~(XqueEvents[XqueHead].xq_code) & 0x07, 0, 0);
+ break;
+
+ case XQ_MOTION: {
+ signed char dx, dy;
+
+ dx = (signed char)XqueEvents[XqueHead].xq_x;
+ dy = (signed char)XqueEvents[XqueHead].xq_y;
+ xf86PostMseEvent(xf86Info.pMouse,
+ ~(XqueEvents[XqueHead].xq_code) & 0x07,
+ (int)dx, (int)dy);
+ break;
+ }
+
+ case XQ_KEY:
+ xf86PostKbdEvent(XqueEvents[XqueHead].xq_code);
+ break;
+
+ default:
+ xf86Msg(X_WARNING, "Unknown Xque Event: 0x%02x\n",
+ XqueEvents[XqueHead].xq_type);
+ }
+
+ if ((++XqueHead) == XqueQaddr->xq_size) XqueHead = 0;
+ }
+
+ /* reenable the signal-processing */
+ xf86Info.inputPending = TRUE;
+#ifdef XQUEUE_ASYNC
+ signal(SIGUSR2, (void (*)()) xf86XqueRequest);
+#else
+#if 0
+ signal(SIGUSR2, (void (*)()) xf86XqueSignal);
+#endif
+#endif
+
+#ifndef XQUEUE_ASYNC
+ {
+ int rval;
+
+ while ((rval = read(xquePipe[0], buf, sizeof(buf))) > 0)
+#ifdef DEBUG
+ ErrorF("Read %d bytes from xquePipe[0]\n", rval);
+#else
+ ;
+#endif
+ }
+#endif
+
+ XqueQaddr->xq_head = XqueQaddr->xq_tail;
+ xf86Info.mouseDev->xquePending = 0;
+ XqueQaddr->xq_sigenable = 1; /* UNLOCK */
+}
+
+
+
+/*
+ * xf86XqueEnable --
+ * Enable the handling of the Xque
+ */
+
+static int
+xf86XqueEnable()
+{
+ static struct kd_quemode xqueMode;
+ static Bool was_here = FALSE;
+
+ if (!was_here) {
+ if ((xqueFd = open("/dev/mouse", O_RDONLY|O_NDELAY)) < 0)
+ {
+ if (xf86GetAllowMouseOpenFail()) {
+ xf86Msg(X_WARNING, "Cannot open /dev/mouse (%s) - Continuing...\n",
+ strerror(errno));
+ return (Success);
+ } else {
+ Error ("Cannot open /dev/mouse");
+ return (!Success);
+ }
+ }
+#ifndef XQUEUE_ASYNC
+ pipe(xquePipe);
+ fcntl(xquePipe[0],F_SETFL,fcntl(xquePipe[0],F_GETFL,0)|O_NDELAY);
+ fcntl(xquePipe[1],F_SETFL,fcntl(xquePipe[1],F_GETFL,0)|O_NDELAY);
+#endif
+ was_here = TRUE;
+ }
+
+ if (xf86Info.mouseDev->xqueSema++ == 0)
+ {
+#ifdef XQUEUE_ASYNC
+ (void) signal(SIGUSR2, (void (*)()) xf86XqueRequest);
+#else
+ (void) signal(SIGUSR2, (void (*)()) xf86XqueSignal);
+#endif
+ xqueMode.qsize = 64; /* max events */
+ xqueMode.signo = SIGUSR2;
+ ioctl(xf86Info.consoleFd, KDQUEMODE, NULL);
+
+ if (ioctl(xf86Info.consoleFd, KDQUEMODE, &xqueMode) < 0) {
+ Error ("Cannot set KDQUEMODE");
+ /* CONSTCOND */
+ return (!Success);
+ }
+
+ XqueQaddr = (xqEventQueue *)xqueMode.qaddr;
+ XqueQaddr->xq_sigenable = 1; /* UNLOCK */
+ }
+
+ return(Success);
+}
+
+
+
+/*
+ * xf86XqueDisable --
+ * disable the handling of the Xque
+ */
+
+static int
+xf86XqueDisable()
+{
+ if (xf86Info.mouseDev->xqueSema-- == 1)
+ {
+
+ XqueQaddr->xq_sigenable = 0; /* LOCK */
+
+ if (ioctl(xf86Info.consoleFd, KDQUEMODE, NULL) < 0) {
+ Error ("Cannot unset KDQUEMODE");
+ /* CONSTCOND */
+ return (!Success);
+ }
+ }
+
+ return(Success);
+}
+
+
+
+/*
+ * xf86XqueMseProc --
+ * Handle the initialization, etc. of a mouse
+ */
+
+int
+xf86XqueMseProc(DeviceIntPtr pPointer, int what)
+{
+ MouseDevPtr mouse = MOUSE_DEV(pPointer);
+ unchar map[4];
+ int ret;
+
+ mouse->device = pPointer;
+
+ switch (what)
+ {
+ case DEVICE_INIT:
+
+ pPointer->public.on = FALSE;
+
+ map[1] = 1;
+ map[2] = 2;
+ map[3] = 3;
+ InitPointerDeviceStruct((DevicePtr)pPointer,
+ map,
+ 3,
+ miPointerGetMotionEvents,
+ (PtrCtrlProcPtr)xf86MseCtrl,
+ miPointerGetMotionBufferSize());
+#ifdef XINPUT
+ InitValuatorAxisStruct(pPointer,
+ 0,
+ 0, /* min val */
+ screenInfo.screens[0]->width, /* max val */
+ 1, /* resolution */
+ 0, /* min_res */
+ 1); /* max_res */
+ InitValuatorAxisStruct(pPointer,
+ 1,
+ 0, /* min val */
+ screenInfo.screens[0]->height, /* max val */
+ 1, /* resolution */
+ 0, /* min_res */
+ 1); /* max_res */
+ /*
+ * Initialize valuator values in synch
+ * with dix/event.c DefineInitialRootWindow
+ */
+ *pPointer->valuator->axisVal = screenInfo.screens[0]->width / 2;
+ *(pPointer->valuator->axisVal+1) = screenInfo.screens[0]->height / 2;
+#endif
+
+ break;
+
+ case DEVICE_ON:
+ mouse->lastButtons = 0;
+ mouse->emulateState = 0;
+ pPointer->public.on = TRUE;
+ ret = xf86XqueEnable();
+#ifndef XQUEUE_ASYNC
+ if (xquePipe[0] != -1)
+ AddEnabledDevice(xquePipe[0]);
+#endif
+ return(ret);
+
+ case DEVICE_CLOSE:
+ case DEVICE_OFF:
+ pPointer->public.on = FALSE;
+ ret = xf86XqueDisable();
+#ifndef XQUEUE_ASYNC
+ if (xquePipe[0] != -1)
+ RemoveEnabledDevice(xquePipe[0]);
+#endif
+ return(ret);
+ }
+
+ return Success;
+}
+#endif /* !NEW_INPUT */
+
+
+
+/*
+ * xf86XqueKbdProc --
+ * Handle the initialization, etc. of a keyboard.
+ */
+
+int
+xf86XqueKbdProc(DeviceIntPtr pKeyboard, int what)
+{
+ KeySymsRec keySyms;
+ CARD8 modMap[MAP_LENGTH];
+
+ switch (what) {
+
+ case DEVICE_INIT:
+
+ xf86KbdGetMapping(&keySyms, modMap);
+
+ /*
+ * Get also the initial led settings
+ */
+ ioctl(xf86Info.consoleFd, KDGETLED, &xf86Info.leds);
+
+ /*
+ * Perform final initialization of the system private keyboard
+ * structure and fill in various slots in the device record
+ * itself which couldn't be filled in before.
+ */
+ pKeyboard->public.on = FALSE;
+
+#ifdef XKB
+ if (noXkbExtension) {
+#endif
+ InitKeyboardDeviceStruct((DevicePtr)xf86Info.pKeyboard,
+ &keySyms,
+ modMap,
+ xf86KbdBell,
+ (KbdCtrlProcPtr)xf86KbdCtrl);
+#ifdef XKB
+ } else {
+ XkbComponentNamesRec names;
+ if (XkbInitialMap) {
+ if ((xf86Info.xkbkeymap = strchr(XkbInitialMap, '/')) != NULL)
+ xf86Info.xkbkeymap++;
+ else
+ xf86Info.xkbkeymap = XkbInitialMap;
+ }
+ if (xf86Info.xkbkeymap) {
+ names.keymap = xf86Info.xkbkeymap;
+ names.keycodes = NULL;
+ names.types = NULL;
+ names.compat = NULL;
+ names.symbols = NULL;
+ names.geometry = NULL;
+ } else {
+ names.keymap = NULL;
+ names.keycodes = xf86Info.xkbkeycodes;
+ names.types = xf86Info.xkbtypes;
+ names.compat = xf86Info.xkbcompat;
+ names.symbols = xf86Info.xkbsymbols;
+ names.geometry = xf86Info.xkbgeometry;
+ }
+ if ((xf86Info.xkbkeymap || xf86Info.xkbcomponents_specified)
+ && (xf86Info.xkbmodel == NULL || xf86Info.xkblayout == NULL)) {
+ xf86Info.xkbrules = NULL;
+ }
+ XkbSetRulesDflts(xf86Info.xkbrules, xf86Info.xkbmodel,
+ xf86Info.xkblayout, xf86Info.xkbvariant,
+ xf86Info.xkboptions);
+ XkbInitKeyboardDeviceStruct(pKeyboard,
+ &names,
+ &keySyms,
+ modMap,
+ xf86KbdBell,
+ (KbdCtrlProcPtr)xf86KbdCtrl);
+ }
+#endif
+
+ xf86InitKBD(TRUE);
+ break;
+
+ case DEVICE_ON:
+ pKeyboard->public.on = TRUE;
+ xf86InitKBD(FALSE);
+#ifndef NEW_INPUT
+ return(xf86XqueEnable());
+#endif
+ break;
+
+ case DEVICE_CLOSE:
+ case DEVICE_OFF:
+ pKeyboard->public.on = FALSE;
+#ifndef NEW_INPUT
+ return(xf86XqueDisable());
+#endif
+ break;
+ }
+
+ return (Success);
+}
+
+
+/*
+ * xf86XqueEvents --
+ * Get some events from our queue. Nothing to do here ...
+ */
+
+void
+xf86XqueEvents()
+{
+}
+
+#ifdef NEW_INPUT
+
+#ifdef XQUEUE_ASYNC
+static void XqDoInput(int signum);
+#endif
+
+void
+XqReadInput(InputInfoPtr pInfo)
+{
+ MouseDevPtr pMse;
+ XqInfoPtr pXq;
+ xqEvent *XqueEvents;
+ int XqueHead;
+ char buf[100];
+ signed char dx, dy;
+
+ if (xqueFd < 0)
+ return;
+
+ pMse = pInfo->private;
+ pXq = pMse->mousePriv;
+
+ XqueEvents = XqueQaddr->xq_events;
+ XqueHead = XqueQaddr->xq_head;
+
+ while (XqueHead != XqueQaddr->xq_tail) {
+ switch (XqueEvents[XqueHead].xq_type) {
+ case XQ_BUTTON:
+ pMse->PostEvent(pInfo, ~(XqueEvents[XqueHead].xq_code) & 0x07,
+ 0, 0, 0);
+#ifdef DEBUG
+ ErrorF("xqueue: buttons: %d\n", ~(XqueEvents[XqueHead].xq_code) & 0x07);
+#endif
+ break;
+
+ case XQ_MOTION:
+ dx = (signed char)XqueEvents[XqueHead].xq_x;
+ dy = (signed char)XqueEvents[XqueHead].xq_y;
+ pMse->PostEvent(pInfo, ~(XqueEvents[XqueHead].xq_code) & 0x07,
+ (int)dx, (int)dy, 0);
+#ifdef DEBUG
+ ErrorF("xqueue: Motion: (%d, %d) (buttons: %d)\n", dx, dy, ~(XqueEvents[XqueHead].xq_code) & 0x07);
+#endif
+ break;
+
+ case XQ_KEY:
+ /* XXX Need to deal with the keyboard part nicely. */
+#ifdef DEBUG
+ ErrorF("xqueue: key: %d\n", XqueEvents[XqueHead].xq_code);
+#endif
+ xf86PostKbdEvent(XqueEvents[XqueHead].xq_code);
+ break;
+ default:
+ xf86Msg(X_WARNING, "Unknown Xque Event: 0x%02x\n",
+ XqueEvents[XqueHead].xq_type);
+ }
+
+ if ((++XqueHead) == XqueQaddr->xq_size) XqueHead = 0;
+ xf86Info.inputPending = TRUE;
+ }
+
+ /* reenable the signal-processing */
+#ifdef XQUEUE_ASYNC
+ signal(SIGUSR2, XqDoInput);
+#endif
+
+#ifndef XQUEUE_ASYNC
+ {
+ int rval;
+
+ while ((rval = read(xquePipe[0], buf, sizeof(buf))) > 0)
+#ifdef DEBUG
+ ErrorF("Read %d bytes from xquePipe[0]\n", rval);
+#else
+ ;
+#endif
+ }
+#endif
+
+#ifdef DEBUG
+ ErrorF("Leaving XqReadInput()\n");
+#endif
+ pXq->xquePending = 0;
+ XqueQaddr->xq_head = XqueQaddr->xq_tail;
+ XqueQaddr->xq_sigenable = 1; /* UNLOCK */
+}
+
+#ifdef XQUEUE_ASYNC
+static void
+XqDoInput(int signum)
+{
+ if (XqMouse)
+ XqReadInput(XqMouse);
+}
+#endif
+
+static void
+XqBlock(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
+{
+ InputInfoPtr pInfo;
+ MouseDevPtr pMse;
+ XqInfoPtr pXq;
+ /*
+ * On MP SVR4 boxes, a race condition exists because the XQUEUE does
+ * not have anyway to lock it for exclusive access. This results in one
+ * processor putting something on the queue at the same time the other
+ * processor is taking it something off. The count of items in the queue
+ * can get off by 1. This just goes and checks to see if an extra event
+ * was put in the queue a during this period. The signal for this event
+ * was ignored while processing the previous event.
+ */
+
+ pInfo = blockData;
+ pMse = pInfo->private;
+ pXq = pMse-> mousePriv;
+ if (!pXq->xquePending) {
+#ifdef DEBUG
+ ErrorF("XqBlock: calling XqReadInput()\n");
+#endif
+ XqReadInput((InputInfoPtr)blockData);
+ } else {
+#ifdef DEBUG
+ ErrorF("XqBlock: not calling XqReadInput()\n");
+#endif
+ ;
+ }
+ /*
+ * Make sure that any events that come in here are passed on without.
+ * waiting for the next wakeup.
+ */
+ if (xf86Info.inputPending) {
+#ifdef DEBUG
+ ErrorF("XqBlock: calling ProcessInputEvents()\n");
+#endif
+ ProcessInputEvents();
+ } else {
+#ifdef DEBUG
+ ErrorF("XqBlock: not calling ProcessInputEvents()\n");
+#endif
+ ;
+ }
+}
+
+/*
+ * XqEnable --
+ * Enable the handling of the Xque
+ */
+
+static int
+XqEnable(InputInfoPtr pInfo)
+{
+ MouseDevPtr pMse;
+ XqInfoPtr pXq;
+ static struct kd_quemode xqueMode;
+ static Bool was_here = FALSE;
+
+ pMse = pInfo->private;
+ pXq = pMse->mousePriv;
+
+ if (xqueFd < 0) {
+ if ((xqueFd = open("/dev/mouse", O_RDONLY | O_NDELAY)) < 0) {
+ if (xf86GetAllowMouseOpenFail()) {
+ xf86Msg(X_WARNING,
+ "%s: Cannot open /dev/mouse (%s) - Continuing...\n",
+ pInfo->name, strerror(errno));
+ return Success;
+ } else {
+ xf86Msg(X_ERROR, "%s: Cannot open /dev/mouse (%s)\n",
+ pInfo->name, strerror(errno));
+ return !Success;
+ }
+ }
+ }
+#ifndef XQUEUE_ASYNC
+ if (!was_here) {
+ pipe(xquePipe);
+ fcntl(xquePipe[0], F_SETFL, fcntl(xquePipe[0], F_GETFL, 0) | O_NDELAY);
+ fcntl(xquePipe[1], F_SETFL, fcntl(xquePipe[1], F_GETFL, 0) | O_NDELAY);
+ was_here = TRUE;
+ }
+#endif
+
+ if (pXq->xqueSema++ == 0) {
+#ifdef XQUEUE_ASYNC
+ (void) signal(SIGUSR2, XqDoInput);
+#else
+ (void) signal(SIGUSR2, xf86XqueSignal);
+#endif
+ xqueMode.qsize = 64; /* max events */
+ xqueMode.signo = SIGUSR2;
+ ioctl(xf86Info.consoleFd, KDQUEMODE, NULL);
+
+ if (ioctl(xf86Info.consoleFd, KDQUEMODE, &xqueMode) < 0) {
+ xf86Msg(X_ERROR, "%s: Cannot set KDQUEMODE", pInfo->name);
+ return !Success;
+ }
+ XqueQaddr = (xqEventQueue *)xqueMode.qaddr;
+ XqueQaddr->xq_sigenable = 1; /* UNLOCK */
+ }
+
+ return Success;
+}
+
+
+
+/*
+ * xf86XqueDisable --
+ * disable the handling of the Xque
+ */
+
+static int
+XqDisable(InputInfoPtr pInfo)
+{
+ MouseDevPtr pMse;
+ XqInfoPtr pXq;
+
+ pMse = pInfo->private;
+ pXq = pMse->mousePriv;
+
+ if (pXq->xqueSema-- == 1)
+ {
+ XqueQaddr->xq_sigenable = 0; /* LOCK */
+
+ if (ioctl(xf86Info.consoleFd, KDQUEMODE, NULL) < 0) {
+ xf86Msg(X_ERROR, "%s: Cannot unset KDQUEMODE", pInfo->name);
+ return !Success;
+ }
+ }
+
+ if (xqueFd >= 0) {
+ close(xqueFd);
+ xqueFd = -1;
+ }
+
+ return Success;
+}
+
+/*
+ * XqMouseProc --
+ * Handle the initialization, etc. of a mouse
+ */
+
+static int
+XqMouseProc(DeviceIntPtr pPointer, int what)
+{
+ InputInfoPtr pInfo;
+ MouseDevPtr pMse;
+ unchar map[4];
+ int ret;
+
+ pInfo = pPointer->public.devicePrivate;
+ pMse = pInfo->private;
+ pMse->device = pPointer;
+
+ switch (what) {
+ case DEVICE_INIT:
+ pPointer->public.on = FALSE;
+
+ map[1] = 1;
+ map[2] = 2;
+ map[3] = 3;
+
+ InitPointerDeviceStruct((DevicePtr)pPointer,
+ map,
+ 3,
+ miPointerGetMotionEvents,
+ pMse->Ctrl,
+ miPointerGetMotionBufferSize());
+ /* X valuator */
+ xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1);
+ xf86InitValuatorDefaults(pPointer, 0);
+ /* Y valuator */
+ xf86InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1);
+ xf86InitValuatorDefaults(pPointer, 1);
+ xf86MotionHistoryAllocate(pInfo);
+ RegisterBlockAndWakeupHandlers(XqBlock, (WakeupHandlerProcPtr)NoopDDA,
+ pInfo);
+ break;
+
+ case DEVICE_ON:
+ pMse->lastButtons = 0;
+ pMse->emulateState = 0;
+ pPointer->public.on = TRUE;
+ ret = XqEnable(pInfo);
+#ifndef XQUEUE_ASYNC
+ if (xquePipe[0] != -1) {
+ pInfo->fd = xquePipe[0];
+ AddEnabledDevice(xquePipe[0]);
+ }
+#endif
+ return ret;
+
+ case DEVICE_CLOSE:
+ case DEVICE_OFF:
+ pPointer->public.on = FALSE;
+ ret = XqDisable(pInfo);
+#ifndef XQUEUE_ASYNC
+ if (xquePipe[0] != -1) {
+ RemoveEnabledDevice(xquePipe[0]);
+ pInfo->fd = -1;
+ }
+#endif
+ return ret;
+ }
+ return Success;
+}
+
+Bool
+XqueueMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags)
+{
+ MouseDevPtr pMse;
+ XqInfoPtr pXq;
+
+ pMse->protocol = protocol;
+ xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol);
+ pXq = pMse->mousePriv = xnfcalloc(sizeof(XqInfoRec), 1);
+
+ /* Collect the options, and process the common options. */
+ xf86CollectInputOptions(pInfo, NULL, NULL);
+ xf86ProcessCommonOptions(pInfo, pInfo->options);
+
+ /* Process common mouse options (like Emulate3Buttons, etc). */
+ pMse->CommonOptions(pInfo);
+
+ /* Setup the local procs. */
+ pInfo->device_control = XqMouseProc;
+#ifdef XQUEUE_ASYNC
+ pInfo->read_input = NULL;
+#else
+ pInfo->read_input = XqReadInput;
+#endif
+ pInfo->fd = -1;
+
+ XqMouse = pInfo;
+
+ pInfo->flags |= XI86_CONFIGURED;
+ return TRUE;
+}
+#endif
+
+#endif /* XQUEUE */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/sysv/xqueue.h b/xc/programs/Xserver/hw/xfree86/os-support/sysv/xqueue.h
new file mode 100644
index 000000000..2085a3e70
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/sysv/xqueue.h
@@ -0,0 +1,8 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sysv/xqueue.h,v 1.1 1999/05/22 08:40:18 dawes Exp $ */
+
+#ifndef _XF86_XQUEUE_H_
+#define _XF86_XQUEUE_H_
+
+Bool XqueueMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags);
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h
new file mode 100644
index 000000000..70f47b772
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h
@@ -0,0 +1,143 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h,v 1.6 1999/06/05 15:55:31 dawes Exp $ */
+
+/*
+ * Copyright (c) 1997-1999 by The XFree86 Project, Inc.
+ */
+
+/* Public interface to OS-specific mouse support. */
+
+#ifndef _XF86OSMOUSE_H_
+#define _XF86OSMOUSE_H_
+
+/* Mouse interface classes */
+#define MSE_NONE 0x00
+#define MSE_SERIAL 0x01 /* serial port */
+#define MSE_BUS 0x02 /* old bus mouse */
+#define MSE_PS2 0x04 /* standard read-only PS/2 */
+#define MSE_XPS2 0x08 /* extended PS/2 */
+#define MSE_AUTO 0x10 /* auto-detect (PnP) */
+#define MSE_MISC 0x20 /* The OS layer will identify the
+ * specific protocol names that are
+ * supported for this class. */
+
+typedef int (*GetInterfaceTypesProc)(void);
+typedef const char **(*BuiltinNamesProc)(void);
+typedef Bool (*CheckProtocolProc)(const char *protocol);
+typedef Bool (*BuiltinPreInitProc)(InputInfoPtr pInfo, const char *protocol,
+ int flags);
+typedef const char *(*DefaultProtocolProc)(void);
+typedef const char *(*SetupAutoProc)(InputInfoPtr pInfo, int *protoPara);
+typedef void (*SetResProc)(InputInfoPtr pInfo, const char* protocol, int rate,
+ int res);
+
+/*
+ * OSMouseInfoRec is used to pass information from the OSMouse layer to the
+ * OS-independent mouse driver.
+ */
+typedef struct {
+ GetInterfaceTypesProc SupportedInterfaces;
+ BuiltinNamesProc BuiltinNames;
+ CheckProtocolProc CheckProtocol;
+ BuiltinPreInitProc PreInit;
+ DefaultProtocolProc DefaultProtocol;
+ SetupAutoProc SetupAuto;
+ SetResProc SetPS2Res;
+ SetResProc SetBMRes;
+ SetResProc SetMiscRes;
+} OSMouseInfoRec, *OSMouseInfoPtr;
+
+/*
+ * SupportedInterfaces: Returns the mouse interface types that the OS support.
+ * If MSE_MISC is returned, then the BuiltinNames and
+ * CheckProtocol should be set.
+ *
+ * BuiltinNames: Returns the names of the protocols that are fully handled
+ * in the OS-specific code. These are names that don't appear
+ * directly in the main "mouse" driver.
+ *
+ * CheckProtocol: Checks if the protocol name given is supported by the
+ * OS. It should return TRUE for both "builtin" protocols and
+ * protocols of type MSE_MISC that are supported by the OS.
+ *
+ * PreInit: The PreInit function for protocols that are builtin. This
+ * function is passed the protocol name.
+ *
+ * DefaultProtocol: Returns the name of a default protocol that should be used
+ * for the OS when none has been supplied in the config file.
+ * This should only be set when there is a reasonable default.
+ *
+ * SetupAuto: This function can be used to do OS-specific protocol
+ * auto-detection. It returns the name of the detected protocol,
+ * or NULL when detection fails. It may also adjust one or more
+ * of the "protoPara" values for the detected protocol by setting
+ * then to something other than -1.
+ *
+ * SetPS2Res: Set the resolution and sample rate for MSE_PS2 and MSE_XPS2
+ * protocol types.
+ *
+ * SetBMRes: Set the resolution and sample rate for MSE_BM protocol types.
+ *
+ * SetMiscRes: Set the resolution and sample rate for MSE_MISC protocol types.
+ */
+
+extern OSMouseInfoPtr xf86OSMouseInit(int flags);
+
+/*
+ * Mouse device record. This is shared by the mouse driver and the OSMouse
+ * layer.
+ */
+
+typedef void (*PostMseEventProc)(InputInfoPtr pInfo, int buttons,
+ int dx, int dy, int dz);
+typedef void (*MouseCommonOptProc)(InputInfoPtr pInfo);
+
+typedef struct _MouseDevRec {
+ PtrCtrlProcPtr Ctrl;
+ PostMseEventProc PostEvent;
+ MouseCommonOptProc CommonOptions;
+ DeviceIntPtr device;
+ const char * mseDevice;
+ const char * protocol;
+ int protocolID;
+ int class;
+ Bool automatic;
+ int mseModel;
+ int baudRate;
+ int oldBaudRate;
+ int sampleRate;
+ int lastButtons;
+ int threshold; /* acceleration */
+ int num;
+ int den;
+ int buttons; /* # of buttons */
+ int emulateState; /* automata state for 2 button mode */
+ Bool emulate3Buttons;
+ int emulate3Timeout;/* Timeout for 3 button emulation */
+ Bool chordMiddle;
+ Bool clearDTR;
+ Bool clearRTS;
+ int mouseFlags; /* Flags to Clear after opening
+ * mouse dev */
+ int truebuttons; /* Arg to maintain before
+ * emulate3buttons timer callback */
+ int resolution;
+ int negativeZ;
+ int positiveZ;
+ pointer buffer; /* usually an XISBuffer* */
+ int protoBufTail;
+ unsigned char protoBuf[8];
+ unsigned char protoPara[8];
+ unsigned char inSync; /* driver in sync with datastream */
+ pointer mousePriv; /* private area */
+ InputInfoPtr pInfo;
+} MouseDevRec, *MouseDevPtr;
+
+/* Z axis mapping */
+#define MSE_NOZMAP 0
+#define MSE_MAPTOX -1
+#define MSE_MAPTOY -2
+
+#define MSE_MAXBUTTONS 12
+#define MSE_DFLTBUTTONS 3
+
+#endif /* _XF86OSMOUSE_H_ */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86OSpriv.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86OSpriv.h
new file mode 100644
index 000000000..2cbf6180a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86OSpriv.h
@@ -0,0 +1,29 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86OSpriv.h,v 1.3 1999/04/25 15:39:35 dawes Exp $ */
+
+#ifndef _XF86OSPRIV_H
+#define _XF86OSPRIV_H
+
+typedef pointer (*MapMemProcPtr)(int, unsigned long, unsigned long);
+typedef void (*UnmapMemProcPtr)(int, pointer, unsigned long);
+typedef pointer (*SetWCProcPtr)(int, unsigned long, unsigned long, Bool,
+ MessageType);
+typedef void (*ProtectMemProcPtr)(int, pointer, unsigned long, Bool);
+typedef void (*UndoWCProcPtr)(int, pointer);
+typedef void (*ReadSideEffectsProcPtr)(int, pointer, unsigned long);
+
+typedef struct {
+ Bool initialised;
+ MapMemProcPtr mapMem;
+ UnmapMemProcPtr unmapMem;
+ MapMemProcPtr mapMemSparse;
+ UnmapMemProcPtr unmapMemSparse;
+ ProtectMemProcPtr protectMem;
+ SetWCProcPtr setWC;
+ UndoWCProcPtr undoWC;
+ ReadSideEffectsProcPtr readSideEffects;
+ Bool linearSupported;
+} VidMemInfo, *VidMemInfoPtr;
+
+void xf86OSInitVidMem(VidMemInfoPtr);
+
+#endif /* _XF86OSPRIV_H */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86_OSlib.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86_OSlib.h
new file mode 100644
index 000000000..d774075d8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86_OSlib.h
@@ -0,0 +1,744 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86_OSlib.h,v 3.68 1999/07/18 08:14:34 dawes Exp $ */
+/*
+ * Copyright 1990, 1991 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1992 by David Dawes <dawes@XFree86.org>
+ * Copyright 1992 by Jim Tsillas <jtsilla@damon.ccs.northeastern.edu>
+ * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
+ * Copyright 1992 by Robert Baron <Robert.Baron@ernst.mach.cs.cmu.edu>
+ * Copyright 1992 by Orest Zborowski <obz@eskimo.com>
+ * Copyright 1993 by Vrije Universiteit, The Netherlands
+ * Copyright 1993 by David Wexelblat <dwex@XFree86.org>
+ * Copyright 1994, 1996 by Holger Veit <Holger.Veit@gmd.de>
+ * Copyright 1997 by Takis Psarogiannakopoulos <takis@dpmms.cam.ac.uk>
+ * Copyright 1994-1998 by The XFree86 Project, Inc
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of the above listed copyright holders
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. The above listed
+ * copyright holders make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THE ABOVE LISTED COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/*
+ * The ARM32 code here carries the following copyright:
+ *
+ * Copyright 1997
+ * Digital Equipment Corporation. All rights reserved.
+ * This software is furnished under license and may be used and copied only in
+ * accordance with the following terms and conditions. Subject to these
+ * conditions, you may download, copy, install, use, modify and distribute
+ * this software in source and/or binary form. No title or ownership is
+ * transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce and retain
+ * this copyright notice and list of conditions as they appear in the
+ * source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or logo of Digital
+ * Equipment Corporation. Neither the "Digital Equipment Corporation"
+ * name nor any trademark or logo of Digital Equipment Corporation may be
+ * used to endorse or promote products derived from this software without
+ * the prior written permission of Digital Equipment Corporation.
+ *
+ * 3) This software is provided "AS-IS" and any express or implied warranties,
+ * including but not limited to, any implied warranties of merchantability,
+ * fitness for a particular purpose, or non-infringement are disclaimed.
+ * In no event shall DIGITAL be liable for any damages whatsoever, and in
+ * particular, DIGITAL shall not be liable for special, indirect,
+ * consequential, or incidental damages or damages for lost profits, loss
+ * of revenue or loss of use, whether such damages arise in contract,
+ * negligence, tort, under statute, in equity, at law or otherwise, even
+ * if advised of the possibility of such damage.
+ *
+ */
+
+/* $XConsortium: xf86_OSlib.h /main/22 1996/10/27 11:06:31 kaleb $ */
+
+/*
+ * This is private, and should not be included by any drivers. Drivers
+ * may include xf86_OSprocs.h to get prototypes for public interfaces.
+ */
+
+#ifndef _XF86_OSLIB_H
+#define _XF86_OSLIB_H
+
+#include <X11/Xos.h>
+#include <X11/Xfuncproto.h>
+
+/*
+ * Define some things from the "ANSI" C wrappers that are needed in the
+ * the core server.
+ */
+#ifndef HAVE_WRAPPER_DECLS
+#define HAVE_WRAPPER_DECLS
+#undef usleep
+#define usleep(a) xf86usleep(a)
+extern void xf86usleep(unsigned long);
+extern int xf86getpagesize(void);
+extern int xf86GetErrno(void);
+typedef unsigned long xf86size_t;
+typedef signed long xf86ssize_t;
+#ifdef NEED_SNPRINTF
+extern int snprintf(char *str, size_t size, const char *format, ...);
+extern int vsnprintf(char *str, size_t size, const char *format, va_list ap);
+#endif
+#endif
+
+#ifndef NO_COMPILER_H
+#include "compiler.h"
+#endif
+
+#if defined(MACH386) || defined(__OSF__)
+# undef NULL
+#endif /* MACH386 || __OSF__ */
+
+#include <stdio.h>
+#include <ctype.h>
+
+/**************************************************************************/
+/* SYSV386 (SVR3, SVR4) */
+/**************************************************************************/
+#if (defined(SYSV) || defined(SVR4)) && !defined(DGUX)
+# ifdef SCO325
+# ifndef _SVID3
+# define _SVID3
+# endif
+# ifndef _NO_STATIC
+# define _NO_STATIC
+# endif
+# endif
+# include <sys/ioctl.h>
+# include <signal.h>
+# include <termio.h>
+# include <sys/stat.h>
+# include <sys/types.h>
+# if defined(SCO) || defined(ISC)
+# include <sys/param.h>
+# endif
+
+#ifdef ISC
+#define TIOCMSET (TIOC|26) /* set all modem bits */
+#define TIOCMBIS (TIOC|27) /* bis modem bits */
+#define TIOCMBIC (TIOC|28) /* bic modem bits */
+#define TIOCMGET (TIOC|29) /* get all modem bits */
+#endif
+
+# include <errno.h>
+
+# if defined(PowerMAX_OS)
+# define HAS_USL_VTS
+# include <sys/immu.h>
+# include <sys/sysmacros.h>
+# elif defined(_NEED_SYSI86)
+# include <sys/immu.h>
+# if !(defined (sun) && defined (i386) && defined (SVR4))
+# include <sys/region.h>
+# endif
+# include <sys/proc.h>
+# include <sys/tss.h>
+# include <sys/sysi86.h>
+# if defined(SVR4) && !defined(sun)
+# include <sys/seg.h>
+# endif /* SVR4 && !sun */
+# if defined(sun) && defined (i386) && defined (SVR4) /* Solaris? */
+# if !defined(V86SC_IOPL) /* Solaris 7? */
+# include <sys/v86.h> /* Nope */
+# else
+ /* Do nothing what so ever */ /* Yup */
+# endif /* V86SC_IOPL */
+# else
+# include <sys/v86.h> /* Not solaris */
+# endif /* sun && i386 && SVR4 */
+# if defined(sun) && defined (i386) && defined (SVR4)
+# include <sys/psw.h>
+# endif
+# endif /* _NEED_SYSI86 */
+
+#if defined(HAS_SVR3_MMAPDRV)
+# include <sys/sysmacros.h>
+# if !defined(_NEED_SYSI86)
+# include <sys/immu.h>
+# include <sys/region.h>
+# endif
+# include <sys/mmap.h> /* MMAP driver header */
+#endif
+
+# define HAS_USL_VTS
+# if !defined(sun)
+# include <sys/emap.h>
+# endif
+# if defined(SCO)
+# include <sys/vtkd.h>
+# include <sys/console.h>
+# include <sys/keyboard.h>
+# include <sys/vid.h>
+# define LED_CAP 0x01
+# define LED_NUM 0x02
+# define LED_SCR 0x04
+# else /* SCO */
+# include <sys/at_ansi.h>
+# include <sys/kd.h>
+# include <sys/vt.h>
+# endif /* SCO */
+
+# if !defined(VT_ACKACQ)
+# define VT_ACKACQ 2
+# endif /* !VT_ACKACQ */
+
+# if defined(SCO)
+# include <sys/sysmacros.h>
+# define POSIX_TTY
+# endif /* SCO */
+
+# if defined(SVR4) || defined(SCO325)
+# include <sys/mman.h>
+# if !(defined(sun) && defined (i386) && defined (SVR4))
+# define DEV_MEM "/dev/pmem"
+# elif defined(PowerMAX_OS)
+# define DEV_MEM "/dev/iomem"
+# endif
+# ifdef SCO325
+# undef DEV_MEM
+# define DEV_MEM "/dev/mem"
+# endif
+# define CLEARDTR_SUPPORT
+# define POSIX_TTY
+# endif /* SVR4 */
+
+# ifdef ISC
+# include <termios.h>
+# define POSIX_TTY
+# endif
+
+# if defined(sun) && defined (i386) && defined (SVR4)
+# define USE_VT_SYSREQ
+# define VT_SYSREQ_DEFAULT TRUE
+# endif
+
+# if defined(ATT) && !defined(i386)
+# define i386 /* note defined in ANSI C mode */
+# endif /* ATT && !i386 */
+
+# if (defined(ATT) || defined(SVR4)) && !(defined(sun) && defined (i386) && defined (SVR4)) && !defined(SCO325)
+# ifndef XQUEUE
+# define XQUEUE
+# endif
+# include <sys/xque.h>
+# endif /* ATT || SVR4 */
+
+#if 0
+/* Hack on SVR3 and SVR4 to avoid linking in Xenix or BSD support */
+#if defined (sun) && defined (i386) && defined (SVR4)
+extern int xf86_solx86usleep(unsigned long);
+# define usleep(usec) xf86_solx86usleep(usec)
+#else
+# define usleep(usec) syscall(3112, (usec) / 1000 + 1)
+#endif /* sun && i386 && SVR4 */
+#endif
+
+# ifdef SYSV
+# if !defined(ISC) || defined(ISC202) || defined(ISC22)
+# define NEED_STRERROR
+# endif
+# endif
+
+#ifndef NULL
+# define NULL 0
+#endif
+
+#endif /* (SYSV || SVR4) && !DGUX */
+
+
+/**************************************************************************/
+/* DG/ux R4.20MU03 Intel AViion Machines */
+/**************************************************************************/
+#if defined(DGUX) && defined(SVR4)
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <ctype.h>
+#include <termios.h> /* Use termios for BSD Flavor ttys */
+#include <sys/termios.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <errno.h>
+#include <sys/sysi86.h>
+#include <unistd.h>
+#include <sys/proc.h>
+#include <sys/map.h>
+#include <sys/sysmacros.h>
+#include <sys/mman.h> /* Memory handling */
+#include <sys/kd.h> /* definitios for KDENABIO KDDISABIO needed for IOPL s */
+#include <sys/kbd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/stream.h>
+#include <sys/ptms.h>
+
+#include <sys/socket.h>
+#include <sys/utsname.h>
+#include <sys/stropts.h>
+#include <sys/sockio.h>
+
+
+#define POSIX_TTY
+
+#undef HAS_USL_VTS
+#undef USE_VT_SYSREQ
+#undef VT_ACKACQ
+
+#define LED_CAP KBD_LED_CAPS_LOCK
+#define LED_NUM KBD_LED_NUM_LOCK
+#define LED_SCR KBD_LED_SCROLL_LOCK
+
+#define KDGKBTYPE KBD_GET_LANGUAGE
+
+
+/* General keyboard types */
+# define KB_84 2
+# define KB_101 1 /* Because ioctl(dgkeybdFd,KBD_GET_LANGUAGE,&type) gives 1=US keyboard */
+# define KB_OTHER 3
+
+#define KDSETLED KBD_SET_LED
+#define KDGETLED KBD_GET_STATE
+#undef KDMKTONE
+#define KDMKTONE KBD_TONE_HIGH
+
+
+#undef DEV_MEM
+#define DEV_MEM "/dev/mem"
+#define CLEARDTR_SUPPORT
+
+#undef VT_SYSREQ_DEFAULT
+#define VT_SYSREQ_DEFAULT FALSE /* Make sure that we dont define any VTs since DG/ux has none */
+
+#ifndef NULL
+# define NULL 0
+#endif
+
+#endif /* DGUX && SVR4 */
+
+/**************************************************************************/
+/* Linux */
+/**************************************************************************/
+#if defined(linux)
+# include <sys/ioctl.h>
+# include <signal.h>
+# include <termio.h>
+
+# include <errno.h>
+#ifndef __errno_location
+extern int errno;
+#endif
+
+# include <sys/stat.h>
+
+# define HAS_USL_VTS
+# include <sys/mman.h>
+# include <sys/kd.h>
+# include <sys/vt.h>
+# define LDGMAP GIO_SCRNMAP
+# define LDSMAP PIO_SCRNMAP
+# define LDNMAP LDSMAP
+
+# define CLEARDTR_SUPPORT
+# define USE_VT_SYSREQ
+
+# define POSIX_TTY
+
+#endif /* linux */
+
+/**************************************************************************/
+/* LynxOS AT */
+/**************************************************************************/
+#if defined(Lynx)
+
+# include <termio.h>
+# include <sys/ioctl.h>
+# include <param.h>
+# include <signal.h>
+# include <kd.h>
+# include <vt.h>
+# include <sys/stat.h>
+
+# include <errno.h>
+extern int errno;
+
+/* smem_create et.al. to access physical memory */
+# include <smem.h>
+
+/* keyboard types */
+# define KB_84 1
+# define KB_101 2
+# define KB_OTHER 3
+
+/* atc drivers ignores argument to VT_RELDISP ioctl */
+# define VT_ACKACQ 2
+
+# include <termios.h>
+# define POSIX_TTY
+# define CLEARDTR_SUPPORT
+
+/* LynxOS 2.5.1 has these */
+# ifdef LED_NUMLOCK
+# define LED_CAP LED_CAPSLOCK
+# define LED_NUM LED_NUMLOCK
+# define LED_SCR LED_SCROLLOCK
+# endif
+
+#endif /* Lynx */
+
+/**************************************************************************/
+/* 386BSD and derivatives, BSD/386 */
+/**************************************************************************/
+
+#if defined(__386BSD__) && (defined(__FreeBSD__) || defined(__NetBSD__))
+# undef __386BSD__
+#endif
+
+#ifdef CSRG_BASED
+# include <sys/ioctl.h>
+# include <signal.h>
+
+# include <termios.h>
+# define termio termios
+# define POSIX_TTY
+
+# include <errno.h>
+
+# if !defined(LINKKIT)
+ /* Don't need this stuff for the Link Kit */
+# if defined(__bsdi__)
+# include <i386/isa/pcconsioctl.h>
+# define CONSOLE_X_MODE_ON PCCONIOCRAW
+# define CONSOLE_X_MODE_OFF PCCONIOCCOOK
+# define CONSOLE_X_BELL PCCONIOCBEEP
+# else /* __bsdi__ */
+# if defined(__OpenBSD__)
+# ifdef PCCONS_SUPPORT
+# include <machine/pccons.h>
+# undef CONSOLE_X_MODE_ON
+# undef CONSOLE_X_MODE_OFF
+# undef CONSOLE_X_BELL
+# endif
+# endif
+# ifdef SYSCONS_SUPPORT
+# define COMPAT_SYSCONS
+# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+# include <machine/console.h>
+# else
+# include <sys/console.h>
+# endif /* __FreeBSD__ || __NetBSD__ || defined(__OpenBSD__) */
+# endif /* SYSCONS_SUPPORT */
+# if defined(PCVT_SUPPORT)
+# if !defined(SYSCONS_SUPPORT)
+ /* no syscons, so include pcvt specific header file */
+# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+# include <machine/pcvt_ioctl.h>
+# else
+# include <sys/pcvt_ioctl.h>
+# endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ */
+# else /* pcvt and syscons: hard-code the ID magic */
+# define VGAPCVTID _IOWR('V',113, struct pcvtid)
+ struct pcvtid {
+ char name[16];
+ int rmajor, rminor;
+ };
+# endif /* PCVT_SUPPORT && SYSCONS_SUPPORT */
+# endif /* PCVT_SUPPORT */
+# ifdef WSCONS_SUPPORT
+# include <dev/wscons/wsconsio.h>
+# endif /* WSCONS_SUPPORT */
+# if defined(__FreeBSD__)
+# undef MOUSE_GETINFO
+# include <machine/mouse.h>
+# endif
+ /* Include these definitions in case ioctl_pc.h didn't get included */
+# ifndef CONSOLE_X_MODE_ON
+# define CONSOLE_X_MODE_ON _IO('t',121)
+# endif
+# ifndef CONSOLE_X_MODE_OFF
+# define CONSOLE_X_MODE_OFF _IO('t',122)
+# endif
+# ifndef CONSOLE_X_BELL
+# define CONSOLE_X_BELL _IOW('t',123,int[2])
+# endif
+# ifndef CONSOLE_X_TV_ON
+# define CONSOLE_X_TV_ON _IOW('t',155,int)
+# define XMODE_RGB 0
+# define XMODE_NTSC 1
+# define XMODE_PAL 2
+# define XMODE_SECAM 3
+# endif
+# ifndef CONSOLE_X_TV_OFF
+# define CONSOLE_X_TV_OFF _IO('t',156)
+# endif
+#ifndef CONSOLE_GET_LINEAR_INFO
+# define CONSOLE_GET_LINEAR_INFO _IOR('t',157,struct map_info)
+#endif
+#ifndef CONSOLE_GET_IO_INFO
+# define CONSOLE_GET_IO_INFO _IOR('t',158,struct map_info)
+#endif
+#ifndef CONSOLE_GET_MEM_INFO
+# define CONSOLE_GET_MEM_INFO _IOR('t',159,struct map_info)
+#endif
+# endif /* __bsdi__ */
+# endif /* !LINKKIT */
+
+# include <sys/types.h>
+# include <sys/mman.h>
+# include <sys/stat.h>
+
+# if defined(__bsdi__)
+# include <sys/param.h>
+# if (_BSDI_VERSION < 199510)
+# include <i386/isa/vgaioctl.h>
+# endif
+# endif /* __bsdi__ */
+
+#ifdef USE_I386_IOPL
+#include <machine/sysarch.h>
+#endif
+
+# define CLEARDTR_SUPPORT
+
+# if defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT)
+# define USE_VT_SYSREQ
+# endif
+
+# ifndef NULL
+# define NULL 0
+# endif
+
+#endif /* CSRG_BASED */
+
+/**************************************************************************/
+/* Mach and OSF/1 */
+/**************************************************************************/
+#if defined(MACH386) || defined(__OSF__)
+# include <sys/ioctl.h>
+
+# include <signal.h>
+
+# include <errno.h>
+extern int errno;
+
+# if defined(__OSF__)
+# include <sys/param.h>
+# include <machine/kd.h>
+# else /* __OSF__ */
+# if !defined(__STDC__)
+# define __STDC__ 1
+# include <i386at/kd.h>
+# include <i386at/kd_queue.h>
+# undef __STDC__
+# else /* !__STDC__ */
+# include <i386at/kd.h>
+# include <i386at/kd_queue.h>
+# endif /* !__STDC__ */
+# include <sys/file.h>
+# define SEEK_SET L_SET
+# endif /* __OSF__ */
+
+# ifdef MACH386
+# define NEED_STRERROR
+# endif
+
+# include <sys/mman.h>
+# include <sys/stat.h>
+# define MOUSE_PROTOCOL_IN_KERNEL
+
+#endif /* MACH386 || __OSF__ */
+
+/**************************************************************************/
+/* Minix */
+/**************************************************************************/
+#if defined(MINIX)
+# include <sys/ioctl.h>
+# include <signal.h>
+
+# include <termios.h>
+# define termio termios
+# define POSIX_TTY
+
+# include <errno.h>
+
+# include <assert.h>
+# include <limits.h>
+# include <sys/memio.h>
+# include <sys/kbdio.h>
+
+# include <sys/stat.h>
+
+#endif /* MINIX */
+
+/**************************************************************************/
+/* Amoeba */
+/**************************************************************************/
+#if defined(AMOEBA)
+# define port am_port_t
+# include <amoeba.h>
+# include <cmdreg.h>
+# include <stderr.h>
+# include <ampolicy.h>
+# include <proc.h>
+# include <signal.h>
+# include <server/iop/iop.h>
+# include <errno.h>
+# undef port
+
+# undef _POSIX_SOURCE /* to get the BSD-compatible symbols */
+# include <sys/stat.h>
+
+ /* keyboard types */
+# define KB_84 1
+# define KB_101 2
+# define KB_OTHER 3
+
+extern capability iopcap;
+# define MOUSE_PROTOCOL_IN_KERNEL
+
+#endif /* AMOEBA */
+
+/**************************************************************************/
+/* OS/2 */
+/**************************************************************************/
+/* currently OS/2 with EMX/GCC compiler only */
+#if defined(__EMX__)
+# include <signal.h>
+# include <errno.h>
+# include <sys/stat.h>
+
+/* I would have liked to have this included here always, but
+ * it causes clashes for BYTE and BOOL with Xmd.h, which is too dangerous.
+ * So I'll include it in place where I know it does no harm.
+ */
+#if defined(I_NEED_OS2_H)
+# undef BOOL
+# undef BYTE
+# include <os2.h>
+#endif
+
+ /* keyboard types */
+# define KB_84 1
+# define KB_101 2
+/* could detect more keyboards */
+# define KB_OTHER 3
+
+ /* LEDs */
+# define LED_CAP 0x40
+# define LED_NUM 0x20
+# define LED_SCR 0x10
+
+ /* mouse driver */
+# define OSMOUSE_ONLY
+# define MOUSE_PROTOCOL_IN_KERNEL
+
+extern char* __XOS2RedirRoot(char*);
+
+#endif
+
+/**************************************************************************/
+/* GNU/Hurd */
+/**************************************************************************/
+#if defined(__GNU__)
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <sys/stat.h>
+#include <assert.h>
+
+#define POSIX_TTY
+#define USE_OSMOUSE
+
+#endif /* __GNU__ */
+
+/**************************************************************************/
+/* Generic */
+/**************************************************************************/
+
+#include <sys/wait.h> /* May need to adjust this for other OSs */
+
+/*
+ * Hack originally for ISC 2.2 POSIX headers, but may apply elsewhere,
+ * and it's safe, so just do it.
+ */
+#if !defined(O_NDELAY) && defined(O_NONBLOCK)
+# define O_NDELAY O_NONBLOCK
+#endif /* !O_NDELAY && O_NONBLOCK */
+
+#if !defined(MAXHOSTNAMELEN)
+# define MAXHOSTNAMELEN 32
+#endif /* !MAXHOSTNAMELEN */
+
+#if !defined(X_NOT_POSIX)
+# if defined(_POSIX_SOURCE)
+# include <limits.h>
+# else
+# define _POSIX_SOURCE
+# include <limits.h>
+# undef _POSIX_SOURCE
+# endif /* _POSIX_SOURCE */
+#endif /* !X_NOT_POSIX */
+#if !defined(PATH_MAX)
+# if defined(MAXPATHLEN)
+# define PATH_MAX MAXPATHLEN
+# else
+# define PATH_MAX 1024
+# endif /* MAXPATHLEN */
+#endif /* !PATH_MAX */
+
+#ifdef NEED_STRERROR
+# ifndef strerror
+extern char *sys_errlist[];
+extern int sys_nerr;
+# define strerror(n) \
+ ((n) >= 0 && (n) < sys_nerr) ? sys_errlist[n] : "unknown error"
+# endif /* !strerror */
+#endif /* NEED_STRERROR */
+
+#if defined(ISC) || defined(Lynx)
+#define rint(x) RInt(x)
+double RInt(
+#if NeedFunctionPrototypes
+ double x
+#endif
+);
+#endif
+
+#ifndef DEV_MEM
+#define DEV_MEM "/dev/mem"
+#endif
+
+#ifndef VT_SYSREQ_DEFAULT
+#define VT_SYSREQ_DEFAULT FALSE
+#endif
+
+#ifdef OSMOUSE_ONLY
+# ifndef MOUSE_PROTOCOL_IN_KERNEL
+# define MOUSE_PROTOCOL_IN_KERNEL
+# endif
+#endif
+
+#define XF86_OS_PRIVS
+#include "xf86_OSproc.h"
+
+#endif /* _XF86_OSLIB_H */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86_OSproc.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86_OSproc.h
new file mode 100644
index 000000000..ee6b6d48e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86_OSproc.h
@@ -0,0 +1,237 @@
+/*
+ * Copyright 1990, 1991 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1992 by David Dawes <dawes@XFree86.org>
+ * Copyright 1992 by Jim Tsillas <jtsilla@damon.ccs.northeastern.edu>
+ * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
+ * Copyright 1992 by Robert Baron <Robert.Baron@ernst.mach.cs.cmu.edu>
+ * Copyright 1992 by Orest Zborowski <obz@eskimo.com>
+ * Copyright 1993 by Vrije Universiteit, The Netherlands
+ * Copyright 1993 by David Wexelblat <dwex@XFree86.org>
+ * Copyright 1994, 1996 by Holger Veit <Holger.Veit@gmd.de>
+ * Copyright 1994-1999 by The XFree86 Project, Inc
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of the above listed copyright holders
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. The above listed
+ * copyright holders make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THE ABOVE LISTED COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/*
+ * The ARM32 code here carries the following copyright:
+ *
+ * Copyright 1997
+ * Digital Equipment Corporation. All rights reserved.
+ * This software is furnished under license and may be used and copied only in
+ * accordance with the following terms and conditions. Subject to these
+ * conditions, you may download, copy, install, use, modify and distribute
+ * this software in source and/or binary form. No title or ownership is
+ * transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce and retain
+ * this copyright notice and list of conditions as they appear in the
+ * source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or logo of Digital
+ * Equipment Corporation. Neither the "Digital Equipment Corporation"
+ * name nor any trademark or logo of Digital Equipment Corporation may be
+ * used to endorse or promote products derived from this software without
+ * the prior written permission of Digital Equipment Corporation.
+ *
+ * 3) This software is provided "AS-IS" and any express or implied warranties,
+ * including but not limited to, any implied warranties of merchantability,
+ * fitness for a particular purpose, or non-infringement are disclaimed.
+ * In no event shall DIGITAL be liable for any damages whatsoever, and in
+ * particular, DIGITAL shall not be liable for special, indirect,
+ * consequential, or incidental damages or damages for lost profits, loss
+ * of revenue or loss of use, whether such damages arise in contract,
+ * negligence, tort, under statute, in equity, at law or otherwise, even
+ * if advised of the possibility of such damage.
+ *
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86_OSproc.h,v 3.28 1999/06/14 07:31:57 dawes Exp $ */
+
+#ifndef _XF86_OSPROC_H
+#define _XF86_OSPROC_H
+
+/*
+ * The actual prototypes have been pulled into this seperate file so
+ * that they can can be used without pulling in all of the OS specific
+ * stuff like sys/stat.h, etc. This casues problem for loadable modules.
+ */
+
+/*
+ * Flags for xf86MapVidMem(). Multiple flags can be or'd together. The
+ * flags may be used as hints. For example it would be permissible to
+ * enable write combining for memory marked only for framebuffer use.
+ */
+
+#define VIDMEM_FRAMEBUFFER 0x01 /* memory for framebuffer use */
+#define VIDMEM_MMIO 0x02 /* memory for I/O use */
+#define VIDMEM_SPARSE 0x04 /* sparse mapping required */
+#define VIDMEM_READSIDEEFFECT 0x08 /* reads can have side-effects */
+
+/*
+ * OS-independent modem state flags for xf86SetSerialModemState() and
+ * xf86GetSerialModemState().
+ */
+#define XF86_M_LE 0x001 /* line enable */
+#define XF86_M_DTR 0x002 /* data terminal ready */
+#define XF86_M_RTS 0x004 /* request to send */
+#define XF86_M_ST 0x008 /* secondary transmit */
+#define XF86_M_SR 0x010 /* secondary receive */
+#define XF86_M_CTS 0x020 /* clear to send */
+#define XF86_M_CAR 0x040 /* carrier detect */
+#define XF86_M_RNG 0x080 /* ring */
+#define XF86_M_DSR 0x100 /* data set ready */
+
+#ifdef XF86_OS_PRIVS
+extern void xf86WrapperInit(void);
+#endif
+
+#ifndef NO_OSLIB_PROTOTYPES
+/*
+ * This is to prevent re-entrancy to FatalError() when aborting.
+ * Anything that can be called as a result of AbortDDX() should use this
+ * instead of FatalError(). (xf86Exiting gets set to TRUE the first time
+ * AbortDDX() is called.)
+ */
+
+#define xf86FatalError(a, b) \
+ if (xf86Exiting) { \
+ ErrorF(a, b); \
+ return; \
+ } else FatalError(a, b)
+
+/***************************************************************************/
+/* Prototypes */
+/***************************************************************************/
+
+#include <X11/Xfuncproto.h>
+
+_XFUNCPROTOBEGIN
+
+/* public functions */
+extern Bool xf86LinearVidMem(void);
+extern pointer xf86MapVidMem(int, int, unsigned long, unsigned long);
+extern void xf86UnMapVidMem(int, pointer, unsigned long);
+extern void xf86MapReadSideEffects(int, int, pointer, unsigned long);
+extern int xf86ReadBIOS(unsigned long, unsigned long, unsigned char *, int);
+extern void xf86EnableIO(void);
+extern void xf86DisableIO(void);
+extern Bool xf86DisableInterrupts(void);
+extern void xf86EnableInterrupts(void);
+extern void xf86SetTVOut(int);
+extern void xf86SetRGBOut(void);
+extern void xf86BusToMem(unsigned char *, unsigned char *, int);
+extern void xf86MemToBus(unsigned char *, unsigned char *, int);
+extern void xf86IODelay(void);
+extern void xf86SlowBcopy(unsigned char *, unsigned char *, int);
+extern int xf86OpenSerial(pointer options);
+extern int xf86SetSerial(int fd, pointer options);
+extern int xf86SetSerialSpeed(int fd, int speed);
+extern int xf86ReadSerial(int fd, void *buf, int count);
+extern int xf86WriteSerial(int fd, const void *buf, int count);
+extern int xf86CloseSerial(int fd);
+extern int xf86FlushInput(int fd);
+extern int xf86WaitForInput(int fd, int timeout);
+extern int xf86SerialSendBreak(int fd, int duration);
+extern int xf86SetSerialModemState(int fd, int state);
+extern int xf86GetSerialModemState(int fd);
+extern int xf86SerialModemSetBits(int fd, int bits);
+extern int xf86SerialModemClearBits(int fd, int bits);
+
+
+#if defined(__alpha__)
+/* entry points for SPARSE memory access routines */
+#if 0
+extern pointer xf86MapVidMemSparse(int, int, pointer, unsigned long);
+extern void xf86UnMapVidMemSparse(int, pointer, unsigned long);
+#endif
+extern int xf86ReadSparse8(pointer, unsigned long);
+extern int xf86ReadSparse16(pointer, unsigned long);
+extern int xf86ReadSparse32(pointer, unsigned long);
+extern void xf86WriteSparse8(int, pointer, unsigned long);
+extern void xf86WriteSparse16(int, pointer, unsigned long);
+extern void xf86WriteSparse32(int, pointer, unsigned long);
+extern void xf86JensenMemToBus(char *, long, long, int);
+extern void xf86JensenBusToMem(char *, char *, unsigned long, int);
+extern void xf86SlowBCopyFromBus(unsigned char *, unsigned char *, int);
+extern void xf86SlowBCopyToBus(unsigned char *, unsigned char *, int);
+#endif /* __alpha__ */
+
+/* These routines are in shared/sigio.c and are not loaded as part of the
+ module. These routines are small, and the code if very POSIX-signal (or
+ OS-signal) specific, so it seemed better to provide more complex
+ wrappers than to wrap each individual function called. */
+extern int xf86InstallSIGIOHandler(int fd, void (*f)(int));
+extern int xf86RemoveSIGIOHandler(int fd);
+
+#ifdef XF86_OS_PRIVS
+extern void xf86OpenConsole(void);
+extern void xf86CloseConsole(void);
+extern Bool xf86VTSwitchPending(void);
+extern Bool xf86VTSwitchAway(void);
+extern Bool xf86VTSwitchTo(void);
+extern void xf86VTRequest(int sig);
+extern int xf86ProcessArgument(int, char **, int);
+extern void xf86UseMsg(void);
+extern void xf86SoundKbdBell(int, int, int);
+extern void xf86SetKbdLeds(int);
+extern int xf86GetKbdLeds(void);
+extern void xf86SetKbdRepeat(char);
+extern void xf86KbdInit(void);
+extern int xf86KbdOn(void);
+extern int xf86KbdOff(void);
+extern void xf86KbdEvents(void);
+#ifndef NEW_INPUT
+extern void xf86SetMouseSpeed(MouseDevPtr, int, int, unsigned);
+extern void xf86MouseInit(MouseDevPtr);
+extern int xf86MouseOn(MouseDevPtr);
+extern int xf86MouseOff(MouseDevPtr, Bool);
+extern void xf86MouseEvents(MouseDevPtr);
+extern int xf86XqueMseProc(DeviceIntPtr, int);
+extern int xf86OsMouseProc(DeviceIntPtr, int);
+extern void xf86OsMouseEvents(void);
+extern void xf86OsMouseOption(int, pointer);
+#endif
+extern int xf86XqueKbdProc(DeviceIntPtr, int);
+extern void xf86XqueEvents(void);
+
+#ifdef NEED_OS_RAC_PROTOS
+/* RAC-related privs */
+/* internal to os-support layer */
+resPtr xf86StdAccWindowsFromOS(void);
+resPtr xf86StdAccResFromOS(resPtr ret);
+void xf86StdInitOSPciAllocator(const pciConfigPtr *pciInfo,
+ resPtr *sysRes, const resPtr pciRes);
+
+/* available to the common layer */
+resPtr xf86AccWindowsFromOS(void);
+resPtr xf86AccResFromOS(resPtr ret);
+PciBusPtr xf86InitOSPciAllocator(const pciConfigPtr *pciInfo,
+ resPtr *sysRes, const resPtr pciRes);
+#endif /* NEED_OS_RAC_PROTOS */
+
+#endif /* XF86_OS_PRIVS */
+
+
+_XFUNCPROTOEND
+#endif /* NO_OSLIB_PROTOTYPES */
+
+#endif /* _XF86_OSPROC_H */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86_ansic.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86_ansic.h
new file mode 100644
index 000000000..9cbf33cb4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86_ansic.h
@@ -0,0 +1,291 @@
+/*
+ * Copyright 1997,1998 by The XFree86 Project, Inc
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of the above listed copyright holders
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. The above listed
+ * copyright holders make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THE ABOVE LISTED COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86_ansic.h,v 3.29 1999/07/18 08:14:34 dawes Exp $ */
+
+#ifndef _XF86_ANSIC_H
+#define _XF86_ANSIC_H
+
+#ifndef FONTMODULE
+#include "misc.h"
+#endif
+#include "xf86_libc.h"
+
+/*
+ * The first set of definitions are required both for modules and
+ * libc_wrapper.c.
+ */
+
+#if defined(XFree86LOADER) || defined(NEED_XF86_TYPES)
+
+#if !defined(SYSV) && !defined(SVR4) && !defined(Lynx) || defined(SCO)
+#define HAVE_VSSCANF
+#define HAVE_VFSCANF
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+#ifndef EOF
+#define EOF (-1)
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+/* <limits.h> stuff */
+#define x_BITSPERBYTE 8
+#define x_BITS(type) (x_BITSPERBYTE * (int)sizeof(type))
+#define x_SHORTBITS x_BITS(short)
+#define x_INTBITS x_BITS(int)
+#define x_LONGBITS x_BITS(long)
+#ifndef SHRT_MIN
+#define SHRT_MIN ((short)(1 << (x_SHORTBITS - 1)))
+#endif
+#ifndef SHRT_MAX
+#define SHRT_MAX ((short)~SHRT_MIN)
+#endif
+#ifndef USHRT_MAX
+#define USHRT_MAX ((unsigned short)~0)
+#endif
+#ifndef MINSHORT
+#define MINSHORT SHRT_MIN
+#endif
+#ifndef MAXSHORT
+#define MAXSHORT SHRT_MAX
+#endif
+#ifndef INT_MIN
+#define INT_MIN (1 << (x_INTBITS - 1))
+#endif
+#ifndef INT_MAX
+#define INT_MAX (~INT_MIN)
+#endif
+#ifndef UINT_MAX
+#define UINT_MAX (~0)
+#endif
+#ifndef MININT
+#define MININT INT_MIN
+#endif
+#ifndef MAXINT
+#define MAXINT INT_MAX
+#endif
+#ifndef LONG_MIN
+#define LONG_MIN ((long)(1 << (x_LONGBITS - 1)))
+#endif
+#ifndef LONG_MAX
+#define LONG_MAX ((long)~LONG_MIN)
+#endif
+#ifndef ULONG_MAX
+#define ULONG_MAX ((unsigned long)~0UL)
+#endif
+#ifndef MINLONG
+#define MINLONG LONG_MIN
+#endif
+#ifndef MAXLONG
+#define MAXLONG LONG_MAX
+#endif
+
+#include <stdarg.h>
+
+/*
+ * ANSI C compilers only.
+ */
+
+/* ANSI C emulation library */
+
+extern void xf86abort(void);
+extern int xf86abs(int);
+extern double xf86acos(double);
+extern double xf86asin(double);
+extern double xf86atan(double);
+extern double xf86atan2(double,double);
+extern double xf86atof(const char*);
+extern int xf86atoi(const char*);
+extern long xf86atol(const char*);
+extern void *xf86bsearch(const void *, const void *, xf86size_t, xf86size_t,
+ int (*)(const void *, const void *));
+extern double xf86ceil(double);
+extern void* xf86calloc(xf86size_t,xf86size_t);
+extern void xf86clearerr(XF86FILE*);
+extern double xf86cos(double);
+extern void xf86exit(int);
+extern double xf86exp(double);
+extern double xf86fabs(double);
+extern int xf86fclose(XF86FILE*);
+extern int xf86feof(XF86FILE*);
+extern int xf86ferror(XF86FILE*);
+extern int xf86fflush(XF86FILE*);
+extern int xf86fgetc(XF86FILE*);
+extern int xf86getc(XF86FILE*);
+extern int xf86fgetpos(XF86FILE*,XF86fpos_t*);
+extern char* xf86fgets(char*,INT32,XF86FILE*);
+extern double xf86floor(double);
+extern double xf86fmod(double,double);
+extern XF86FILE* xf86fopen(const char*,const char*);
+extern int xf86printf(const char*,...);
+extern int xf86fprintf(XF86FILE*,const char*,...);
+extern int xf86fputc(int,XF86FILE*);
+extern int xf86fputs(const char*,XF86FILE*);
+extern xf86size_t xf86fread(void*,xf86size_t,xf86size_t,XF86FILE*);
+extern void xf86free(void*);
+extern XF86FILE* xf86freopen(const char*,const char*,XF86FILE*);
+#ifdef HAVE_VFSCANF
+extern int xf86fscanf(XF86FILE*,const char*,...);
+#else
+extern int xf86fscanf(/*XF86FILE*,const char*,char *,char *,char *,char *,
+ char *,char *,char *,char *,char *,char * */);
+#endif
+extern int xf86fseek(XF86FILE*,long,int);
+extern int xf86fsetpos(XF86FILE*,const XF86fpos_t*);
+extern long xf86ftell(XF86FILE*);
+extern xf86size_t xf86fwrite(const void*,xf86size_t,xf86size_t,XF86FILE*);
+extern char* xf86getenv(const char*);
+extern int xf86isalnum(int);
+extern int xf86isalpha(int);
+extern int xf86iscntrl(int);
+extern int xf86isdigit(int);
+extern int xf86isgraph(int);
+extern int xf86islower(int);
+extern int xf86isprint(int);
+extern int xf86ispunct(int);
+extern int xf86isspace(int);
+extern int xf86isupper(int);
+extern int xf86isxdigit(int);
+extern long xf86labs(long);
+extern double xf86log(double);
+extern double xf86log10(double);
+extern void* xf86malloc(xf86size_t);
+extern void* xf86memchr(const void*,int,xf86size_t);
+extern int xf86memcmp(const void*,const void*,xf86size_t);
+extern void* xf86memcpy(void*,const void*,xf86size_t);
+extern void* xf86memmove(void*,const void*,xf86size_t);
+extern void* xf86memset(void*,int,xf86size_t);
+extern double xf86modf(double,double*);
+extern void xf86perror(const char*);
+extern double xf86pow(double,double);
+extern void* xf86realloc(void*,xf86size_t);
+extern int xf86remove(const char*);
+extern int xf86rename(const char*,const char*);
+extern void xf86rewind(XF86FILE*);
+extern int xf86setbuf(XF86FILE*,char*);
+extern int xf86setvbuf(XF86FILE*,char*,int,xf86size_t);
+extern double xf86sin(double);
+extern int xf86sprintf(char*,const char*,...);
+extern int xf86snprintf(char*,xf86size_t,const char*,...);
+extern double xf86sqrt(double);
+#ifdef HAVE_VSSCANF
+extern int xf86sscanf(char*,const char*,...);
+#else
+extern int xf86sscanf(/*char*,const char*,char *,char *,char *,char *,
+ char *,char *,char *,char *,char *,char * */);
+#endif
+extern char* xf86strcat(char*,const char*);
+extern char* xf86strchr(const char*, int c);
+extern int xf86strcmp(const char*,const char*);
+extern int xf86strcasecmp(const char*,const char*);
+extern char* xf86strcpy(char*,const char*);
+extern xf86size_t xf86strcspn(const char*,const char*);
+extern char* xf86strerror(int);
+extern xf86size_t xf86strlen(const char*);
+extern char* xf86strncat(char *, const char *, xf86size_t);
+extern int xf86strncmp(const char*,const char*,xf86size_t);
+extern int xf86strncasecmp(const char*,const char*,xf86size_t);
+extern char* xf86strncpy(char*,const char*,xf86size_t);
+extern char* xf86strpbrk(const char*,const char*);
+extern char* xf86strrchr(const char*,int);
+extern xf86size_t xf86strspn(const char*,const char*);
+extern char* xf86strstr(const char*,const char*);
+extern double xf86strtod(const char*,char**);
+extern char* xf86strtok(char*,const char*);
+extern long xf86strtol(const char*,char**,int);
+extern unsigned long xf86strtoul(const char*,char**,int);
+extern double xf86tan(double);
+extern XF86FILE* xf86tmpfile(void);
+extern char* xf86tmpnam(char*);
+extern int xf86tolower(int);
+extern int xf86toupper(int);
+extern int xf86ungetc(int,XF86FILE*);
+extern int xf86vfprintf(XF86FILE*,const char*,va_list);
+extern int xf86vsprintf(char*,const char*,va_list);
+extern int xf86vsnprintf(char*,xf86size_t,const char*,va_list);
+
+extern int xf86open(const char*, int,...);
+extern int xf86close(int);
+extern long xf86lseek(int, long, int);
+extern int xf86ioctl(int, unsigned long, pointer);
+extern xf86ssize_t xf86read(int, void *, xf86size_t);
+extern xf86ssize_t xf86write(int, const void *, xf86size_t);
+extern void* xf86mmap(void*, xf86size_t, int, int, int, xf86size_t /* off_t */);
+extern int xf86munmap(void*, xf86size_t);
+extern int xf86stat(const char *, struct xf86stat *);
+extern int xf86fstat(int, struct xf86stat *);
+extern int xf86access(const char *, int);
+extern int xf86errno;
+extern int xf86GetErrno(void);
+
+extern double xf86HUGE_VAL;
+
+extern double xf86hypot(double,double);
+
+/* non-ANSI C functions */
+extern XF86DIR* xf86opendir(const char*);
+extern int xf86closedir(XF86DIR*);
+extern XF86DIRENT* xf86readdir(XF86DIR*);
+extern void xf86rewinddir(XF86DIR*);
+extern void xf86bcopy(const void*,void*,xf86size_t);
+extern int xf86ffs(int);
+extern char* xf86strdup(const char*);
+extern void xf86bzero(void*,unsigned int);
+extern void xf86getsecs(CARD32 *, CARD32 *);
+extern int xf86execl(const char *, const char *, ...);
+extern long xf86fpossize(void);
+extern int xf86chmod(const char *, xf86mode_t);
+extern int xf86chown(const char *, xf86uid_t, xf86gid_t);
+extern xf86uid_t xf86geteuid(void);
+extern int xf86mknod(const char *, xf86mode_t, xf86dev_t);
+unsigned int xf86sleep(unsigned int seconds);
+int xf86getpagesize(void);
+
+#else /* XFree86LOADER || NEED_XF86_TYPES */
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <ctype.h>
+#endif /* XFree86LOADER NEED_XF86_TYPES */
+
+/*
+ * These things are always required by drivers (but not by libc_wrapper.c),
+ * even for a static server because some OSs don't provide them.
+ */
+
+extern void xf86usleep(unsigned long);
+#ifndef DONT_DEFINE_WRAPPERS
+#undef usleep
+#define usleep(ul) xf86usleep(ul)
+#endif
+
+#endif /* _XF86_ANSIC_H */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86_libc.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86_libc.h
new file mode 100644
index 000000000..f8e2611e3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86_libc.h
@@ -0,0 +1,415 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86_libc.h,v 3.39 1999/07/06 11:38:51 dawes Exp $ */
+
+
+
+/*
+ * This file is an attempt to make developing code for the new loadable module
+ * architecure simpler. It tries to use macros to hide all libc wrappers so
+ * that all that is needed to "port" a module to this architecture is to
+ * include this one header file
+ *
+ * Revision history:
+ *
+ *
+ * 0.4 Apr 12 1997 add the ANSI defines
+ * 0.3 Feb 24 1997 handle getenv
+ * 0.2 Feb 24 1997 hide few FILE functions
+ * 0.1 Feb 24 1997 hide the trivial functions mem* str*
+ */
+
+#ifndef XF86_LIBC_H
+#define XF86_LIBC_H 1
+
+#include "Xfuncs.h"
+
+/*
+ * The first set of definitions are required both for modules and
+ * libc_wrapper.c.
+ */
+
+#if defined(XFree86LOADER) || defined(NEED_XF86_TYPES)
+
+/*
+ * First, the new data types
+ *
+ * note: if some pointer is declared "opaque" here, pass it between
+ * xf86* functions only, and don't rely on it having a whatever internal
+ * structure, even if some source file might reveal the existence of
+ * such a structure.
+ */
+typedef void XF86FILE; /* opaque FILE replacement */
+extern XF86FILE* xf86stdin;
+extern XF86FILE* xf86stdout;
+extern XF86FILE* xf86stderr;
+
+typedef void XF86fpos_t; /* opaque fpos_t replacement */
+
+#define _XF86NAMELEN 263 /* enough for a larger filename */
+ /* (divisble by 8) */
+typedef void XF86DIR; /* opaque DIR replacement */
+
+/* Note: the following is POSIX! POSIX only requires the d_name member.
+ * Normal Unix has often a number of other members, but don't rely on that
+ */
+struct _xf86dirent { /* types in struct dirent/direct: */
+ char d_name[_XF86NAMELEN+1]; /* char [MAXNAMLEN]; might be smaller or unaligned */
+};
+typedef struct _xf86dirent XF86DIRENT;
+
+typedef unsigned long xf86size_t;
+typedef signed long xf86ssize_t;
+typedef unsigned long xf86dev_t;
+typedef unsigned int xf86mode_t;
+typedef unsigned int xf86uid_t;
+typedef unsigned int xf86gid_t;
+
+struct xf86stat {
+ xf86dev_t st_rdev; /* This is incomplete */
+};
+
+/* for setvbuf */
+#define XF86_IONBF 1
+#define XF86_IOFBF 2
+#define XF86_IOLBF 3
+
+/* for open (XXX not complete) */
+#define XF86_O_RDONLY 0x0000
+#define XF86_O_WRONLY 0x0001
+#define XF86_O_RDWR 0x0002
+#define XF86_O_CREAT 0x0200
+
+/* for mmap */
+#define XF86_PROT_EXEC 0x0001
+#define XF86_PROT_READ 0x0002
+#define XF86_PROT_WRITE 0x0004
+#define XF86_PROT_NONE 0x0008
+#define XF86_MAP_FIXED 0x0001
+#define XF86_MAP_SHARED 0x0002
+#define XF86_MAP_PRIVATE 0x0004
+#define XF86_MAP_FAILED ((void *)-1)
+
+/* for fseek */
+#define XF86_SEEK_SET 0
+#define XF86_SEEK_CUR 1
+#define XF86_SEEK_END 2
+
+/* for access */
+#define XF86_R_OK 0
+#define XF86_W_OK 1
+#define XF86_X_OK 2
+#define XF86_F_OK 3
+
+/* for chmod */
+#define XF86_S_ISUID 04000 /* set user ID on execution */
+#define XF86_S_ISGID 02000 /* set group ID on execution */
+#define XF86_S_ISVTX 01000 /* sticky bit */
+#define XF86_S_IRUSR 00400 /* read by owner */
+#define XF86_S_IWUSR 00200 /* write by owner */
+#define XF86_S_IXUSR 00100 /* execute/search by owner */
+#define XF86_S_IRGRP 00040 /* read by group */
+#define XF86_S_IWGRP 00020 /* write by group */
+#define XF86_S_IXGRP 00010 /* execute/search by group */
+#define XF86_S_IROTH 00004 /* read by others */
+#define XF86_S_IWOTH 00002 /* write by others */
+#define XF86_S_IXOTH 00001 /* execute/search by others */
+
+/* for mknod */
+#define XF86_S_IFREG 0010000
+#define XF86_S_IFCHR 0020000
+#define XF86_S_IFBLK 0040000
+#define XF86_S_IFIFO 0100000
+
+/*
+ * errno values
+ * They start at 1000 just so they don't match real errnos at all
+ */
+#define xf86_UNKNOWN 1000
+#define xf86_EACCES 1001
+#define xf86_EAGAIN 1002
+#define xf86_EBADF 1003
+#define xf86_EEXIST 1004
+#define xf86_EFAULT 1005
+#define xf86_EINTR 1006
+#define xf86_EINVAL 1007
+#define xf86_EISDIR 1008
+#define xf86_ELOOP 1009
+#define xf86_EMFILE 1010
+#define xf86_ENAMETOOLONG 1011
+#define xf86_ENFILE 1012
+#define xf86_ENOENT 1013
+#define xf86_ENOMEM 1014
+#define xf86_ENOSPC 1015
+#define xf86_ENOTDIR 1016
+#define xf86_EPIPE 1017
+#define xf86_EROFS 1018
+#define xf86_ETXTBSY 1019
+#define xf86_ENOTTY 1020
+#define xf86_ENOSYS 1021
+#define xf86_EBUSY 1022
+#define xf86_ENODEV 1023
+#define xf86_EIO 1024
+
+#endif /* defined(XFree86LOADER) || defined(NEED_XF86_TYPES) */
+
+/*
+ * the rest of this file should only be included for code that is supposed
+ * to go into modules
+ */
+
+#if defined(XFree86LOADER) && !defined(DONT_DEFINE_WRAPPERS)
+
+#define abort() xf86abort()
+#undef abs
+#define abs(i) xf86abs(i)
+#define acos(d) xf86acos(d)
+#define asin(d) xf86asin(d)
+#define atan(d) xf86atan(d)
+#define atan2(d1,d2) xf86atan2(d1,d2)
+#define atof(ccp) xf86atof(ccp)
+#define atoi(ccp) xf86atoi(ccp)
+#define atol(ccp) xf86atol(ccp)
+#define bsearch(a,b,c,d,e) xf86bsearch(a,b,c,d,e)
+#define ceil(d) xf86ceil(d)
+#define calloc(I1,I2) xf86calloc(I1,I2)
+#undef clearerr
+#define clearerr(FP) xf86clearerr(FP)
+#define cos(d) xf86cos(d)
+#define exit(i) xf86exit(i)
+#define exp(d) xf86exp(d)
+#define fabs(d) xf86fabs(d)
+#define fclose(FP) xf86fclose(FP)
+#undef feof
+#define feof(FP) xf86feof(FP)
+#undef ferror
+#define ferror(FP) xf86ferror(FP)
+#define fflush(FP) xf86fflush(FP)
+#define fgetc(FP) xf86fgetc(FP)
+#undef getc
+#define getc(FP) xf86getc(FP)
+#define fgetpos(FP,fpp) xf86fgetpos(FP,fpp)
+#define fgets(cp,i,FP) xf86fgets(cp,i,FP)
+#define floor(d) xf86floor(d)
+#define fmod(d1,d2) xf86fmod(d1,d2)
+#define fopen(ccp1,ccp2) xf86fopen(ccp1,ccp2)
+#define printf xf86printf
+#define fprintf xf86fprintf
+#define fputc(i,FP) xf86fputc(i,FP)
+#define fputs(ccp,FP) xf86fputs(ccp,FP)
+#define fread(vp,I1,I2,FP) xf86fread(vp,I1,I2,FP)
+#define free(vp) xf86free(vp)
+#define freopen(ccp1,ccp2,FP) xf86freopen(ccp1,ccp2,FP)
+#define fscanf xf86fscanf
+#define fseek(FP,l,i) xf86fseek(FP,l,i)
+#define fsetpos(FP,cfpp) xf86fsetpos(FP,cfpp)
+#define ftell(FP) xf86ftell(FP)
+#define fwrite(cvp,I1,I2,FP) xf86fwrite(cvp,I1,I2,FP)
+#define getenv(ccp) xf86getenv(ccp)
+#undef isalnum
+#define isalnum(i) xf86isalnum(i)
+#undef isalpha
+#define isalpha(i) xf86isalpha(i)
+#undef iscntrl
+#define iscntrl(i) xf86iscntrl(i)
+#undef isdigit
+#define isdigit(i) xf86isdigit(i)
+#undef isgraph
+#define isgraph(i) xf86isgraph(i)
+#undef islower
+#define islower(i) xf86islower(i)
+#undef isprint
+#define isprint(i) xf86isprint(i)
+#undef ispunct
+#define ispunct(i) xf86ispunct(i)
+#undef isspace
+#define isspace(i) xf86isspace(i)
+#undef isupper
+#define isupper(i) xf86isupper(i)
+#undef isxdigit
+#define isxdigit(i) xf86isxdigit(i)
+#define labs(l) xf86labs(l)
+#define log(d) xf86log(d)
+#define log10(d) xf86log10(d)
+#define malloc(I) xf86malloc(I)
+#define memchr(cvp,i,I) xf86memchr(cvp,i,I)
+#define memcmp(cvp1,cvp2,I) xf86memcmp(cvp1,cvp2,I)
+#define memcpy(vp,cvp,I) xf86memcpy(vp,cvp,I)
+#define memmove(vp,cvp,I) xf86memmove(vp,cvp,I)
+#undef memset
+#define memset(vp,int,I) xf86memset(vp,int,I)
+#define modf(d,dp) xf86modf(d,dp)
+#define perror(ccp) xf86perror(ccp)
+#define pow(d1,d2) xf86pow(d1,d2)
+#define realloc(vp,I) xf86realloc(vp,I)
+#define remove(ccp) xf86remove(ccp)
+#define rename(ccp1,ccp2) xf86rename(ccp1,ccp2)
+#define rewind(FP) xf86rewind(FP)
+#define setbuf(FP,cp) xf86setbuf(FP,cp)
+#define setvbuf(FP,cp,i,I) xf86setvbuf(FP,cp,i,I)
+#define sin(d) xf86sin(d)
+#define snprintf xf86snprintf
+#define sprintf xf86sprintf
+#define sqrt(d) xf86sqrt(d)
+#define sscanf xf86sscanf
+#define strcat(cp,ccp) xf86strcat(cp,ccp)
+#define strcmp(ccp1,ccp2) xf86strcmp(ccp1,ccp2)
+#define strcasecmp(ccp1,ccp2) xf86strcasecmp(ccp1,ccp2)
+#define strcpy(cp,ccp) xf86strcpy(cp,ccp)
+#define strcspn(ccp1,ccp2) xf86strcspn(ccp1,ccp2)
+#define strerror(i) xf86strerror(i)
+#define strlen(ccp) xf86strlen(ccp)
+#define strncmp(ccp1,ccp2,I) xf86strncmp(ccp1,ccp2,I)
+#define strncasecmp(ccp1,ccp2,I) xf86strncasecmp(ccp1,ccp2,I)
+#define strncpy(cp,ccp,I) xf86strncpy(cp,ccp,I)
+#define strpbrk(ccp1,ccp2) xf86strpbrk(ccp1,ccp2)
+#define strchr(ccp,i) xf86strchr(ccp,i)
+#define strrchr(ccp,i) xf86strrchr(ccp,i)
+#define strspn(ccp1,ccp2) xf86strspn(ccp1,ccp2)
+#define strstr(ccp1,ccp2) xf86strstr(ccp1,ccp2)
+#define strtod(ccp,cpp) xf86strtod(ccp,cpp)
+#define strtok(cp,ccp) xf86strtok(cp,ccp)
+#define strtol(ccp,cpp,i) xf86strtol(ccp,cpp,i)
+#define strtoul(ccp,cpp,i) xf86strtoul(ccp,cpp,i)
+#define tan(d) xf86tan(d)
+#define tmpfile() xf86tmpfile()
+#undef tolower
+#define tolower(i) xf86tolower(i)
+#undef toupper
+#define toupper(i) xf86toupper(i)
+#define ungetc(i,FP) xf86ungetc(i,FP)
+#define vfprintf xf86vfprintf
+#define vsnprintf xf86vsnprintf
+#define vsprintf xf86vsprintf
+/* XXX Disable assert as if NDEBUG was defined */
+/* Some X headers defined this away too */
+#undef assert
+#define assert(a) ((void)0)
+#undef HUGE_VAL
+#define HUGE_VAL xf86HUGE_VAL;
+
+#define hypot(x,y) xf86hypot(x,y)
+
+/* non-ANSI C functions */
+#define opendir(cp) xf86opendir(cp)
+#define closedir(DP) xf86closedir(DP)
+#define readdir(DP) xf86readdir(DP)
+#define rewinddir(DP) xf86rewinddir(DP)
+#undef bcopy
+#define bcopy(vp,cvp,I) xf86memmove(cvp,vp,I)
+#define ffs(i) xf86ffs(i)
+#define strdup(ccp) xf86strdup(ccp)
+#undef bzero
+#define bzero(vp,ui) xf86bzero(vp,ui)
+#define execl xf86execl
+#define chmod(a,b) xf86chmod(a,b)
+#define chown(a,b,c) xf86chown(a,b,c)
+#define geteuid xf86geteuid
+#define mknod(a,b,c) xf86mknod(a,b,c)
+#define sleep(a) xf86sleep(a)
+#define S_ISUID XF86_S_ISUID
+#define S_ISGID XF86_S_ISGID
+#define S_ISVTX XF86_S_ISVTX
+#define S_IRUSR XF86_S_IRUSR
+#define S_IWUSR XF86_S_IWUSR
+#define S_IXUSR XF86_S_IXUSR
+#define S_IRGRP XF86_S_IRGRP
+#define S_IWGRP XF86_S_IWGRP
+#define S_IXGRP XF86_S_IXGRP
+#define S_IROTH XF86_S_IROTH
+#define S_IWOTH XF86_S_IWOTH
+#define S_IXOTH XF86_S_IXOTH
+#define S_IFREG XF86_S_IFREG
+#define S_IFCHR XF86_S_IFCHR
+#define S_IFBLK XF86_S_IFBLK
+#define S_IFIFO XF86_S_IFIFO
+
+/* some types */
+#define FILE XF86FILE
+#define fpos_t XF86fpos_t
+#define DIR XF86DIR
+#define DIRENT XF86DIRENT
+#define size_t xf86size_t
+#define ssize_t xf86ssize_t
+#define dev_t xf86dev_t
+#define mode_t xf86mode_t
+#define uid_t xf86uid_t
+#define gid_t xf86gid_t
+
+/*
+ * There should be no need to #undef any of these. If they are already
+ * defined it is because some illegal header has been included.
+ */
+
+/* some vars */
+#define stdin xf86stdin
+#define stdout xf86stdout
+#define stderr xf86stderr
+
+#define SEEK_SET XF86_SEEK_SET
+#define SEEK_CUR XF86_SEEK_CUR
+#define SEEK_END XF86_SEEK_END
+
+/*
+ * XXX Basic I/O functions BAD,BAD,BAD!
+ */
+#define open(a,b,c) xf86open(a,b,c)
+#define close(a) xf86close(a)
+#define lseek(a,b,c) xf86lseek(a,b,c)
+#define ioctl(a,b,c) xf86ioctl(a,b,c)
+#define read(a,b,c) xf86read(a,b,c)
+#define write(a,b,c) xf86write(a,b,c)
+#define mmap(a,b,c,d,e,f) xf86mmap(a,b,c,d,e,f)
+#define munmap(a,b) xf86munmap(a,b)
+#define stat(a,b) xf86stat(a,b)
+#define fstat(a,b) xf86fstat(a,b)
+#define access(a,b) xf86access(a,b)
+#define O_RDONLY XF86_O_RDONLY
+#define O_WRONLY XF86_O_WRONLY
+#define O_RDWR XF86_O_RDWR
+#define O_CREAT XF86_O_CREAT
+#define PROT_EXEC XF86_PROT_EXEC
+#define PROT_READ XF86_PROT_READ
+#define PROT_WRITE XF86_PROT_WRITE
+#define PROT_NONE XF86_PROT_NONE
+#define MAP_FIXED XF86_MAP_FIXED
+#define MAP_SHARED XF86_MAP_SHARED
+#define MAP_PRIVATE XF86_MAP_PRIVATE
+#define MAP_FAILED XF86_MAP_FAILED
+#define R_OK XF86_R_OK
+#define W_OK XF86_W_OK
+#define X_OK XF86_X_OK
+#define F_OK XF86_F_OK
+#ifndef __EMX__
+#define errno xf86errno
+#endif
+
+#define EACCES xf86_EACCES
+#define EAGAIN xf86_EAGAIN
+#define EBADF xf86_EBADF
+#define EEXIST xf86_EEXIST
+#define EFAULT xf86_EFAULT
+#define EINTR xf86_EINTR
+#define EINVAL xf86_EINVAL
+#define EISDIR xf86_EISDIR
+#define ELOOP xf86_ELOOP
+#define EMFILE xf86_EMFILE
+#define ENAMETOOLONG xf86_ENAMETOOLONG
+#define ENFILE xf86_ENFILE
+#define ENOENT xf86_ENOENT
+#define ENOMEM xf86_ENOMEM
+#define ENOSPC xf86_ENOSPC
+#define ENOTDIR xf86_ENOTDIR
+#define EPIPE xf86_EPIPE
+#define EROFS xf86_EROFS
+#define ETXTBSY xf86_ETXTBSY
+#define ENOTTY xf86_ENOTTY
+#define ENOSYS xf86_ENOSYS
+#define EBUSY xf86_EBUSY
+#define ENODEV xf86_ENODEV
+#define EIO xf86_EIO
+
+/* Some ANSI macros */
+#define FILENAME_MAX 1024
+
+#endif /* XFree86LOADER */
+
+#endif /* XF86_LIBC_H */
diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
new file mode 100644
index 000000000..4b53e7861
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h
@@ -0,0 +1,503 @@
+/* xf86drm.h -- OS-independent header for DRM user-level library interface
+ * Created: Tue Jan 5 08:17:23 1999 by faith@precisioninsight.com
+ * Revised: Thu Jun 24 14:18:55 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h,v 1.41 1999/06/24 18:37:13 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drm.h,v 1.3 1999/07/04 06:39:13 dawes Exp $
+ *
+ */
+
+#ifndef _XF86DRM_H_
+#define _XF86DRM_H_
+
+#define DRM_ERR_NO_DEVICE (-1001)
+#define DRM_ERR_NO_ACCESS (-1002)
+#define DRM_ERR_NOT_ROOT (-1003)
+#define DRM_ERR_INVALID (-1004)
+#define DRM_ERR_NO_FD (-1005)
+
+typedef unsigned long drmHandle, *drmHandlePtr; /* To mapped regions */
+typedef unsigned int drmSize, *drmSizePtr; /* For mapped regions */
+typedef void *drmAddress, **drmAddressPtr; /* For mapped regions */
+typedef unsigned int drmContext, *drmContextPtr; /* GLXContext handle */
+typedef unsigned int drmDrawable, *drmDrawablePtr; /* Unused */
+typedef unsigned int drmMagic, *drmMagicPtr; /* Magic for auth */
+
+typedef struct _drmVersion {
+ int version_major; /* Major version */
+ int version_minor; /* Minor version */
+ int version_patchlevel; /* Patch level */
+ int name_len; /* Length of name buffer */
+ char *name; /* Name of driver */
+ int date_len; /* Length of date buffer */
+ char *date; /* User-space buffer to hold date */
+ int desc_len; /* Length of desc buffer */
+ char *desc; /* User-space buffer to hold desc */
+} drmVersion, *drmVersionPtr;
+
+typedef struct _drmCapability {
+ int dummy; /* Driver capabilities */
+} drmCapability, *drmCapabilityPtr;
+
+typedef struct _drmList {
+ int count; /* Length of version */
+ drmVersionPtr version; /* List of versions */
+ drmCapabilityPtr capability; /* List of (possibly null) capabilities */
+} drmList, *drmListPtr;
+
+ /* All of these enums *MUST* match with the
+ kernel implementation -- so do *NOT*
+ change them! (The drmlib implementation
+ will just copy the flags instead of
+ translating them.) */
+typedef enum {
+ DRM_FRAME_BUFFER = 0, /* WC, no caching, no core dump */
+ DRM_REGISTERS = 1, /* no caching, no core dump */
+ DRM_SHM = 2 /* shared, cached */
+} drmMapType;
+
+typedef enum {
+ DRM_RESTRICTED = 0x0001, /* Cannot be mapped to client-virtual */
+ DRM_READ_ONLY = 0x0002, /* Read-only in client-virtual */
+ DRM_LOCKED = 0x0004, /* Physical pages locked */
+ DRM_KERNEL = 0x0008, /* Kernel requires access */
+ DRM_WRITE_COMBINING = 0x0010, /* Use write-combining, if available */
+ DRM_CONTAINS_LOCK = 0x0020 /* SHM page that contains lock */
+} drmMapFlags;
+
+typedef enum { /* These values *MUST* match drm.h */
+ /* Flags for DMA buffer dispatch */
+ DRM_DMA_BLOCK = 0x01, /* Block until buffer dispatched. Note,
+ the buffer may not yet have been
+ processed by the hardware -- getting a
+ hardware lock with the hardware
+ quiescent will ensure that the buffer
+ has been processed. */
+ DRM_DMA_WHILE_LOCKED = 0x02, /* Dispatch while lock held */
+ DRM_DMA_PRIORITY = 0x04, /* High priority dispatch */
+
+ /* Flags for DMA buffer request */
+ DRM_DMA_WAIT = 0x10, /* Wait for free buffers */
+ DRM_DMA_SMALLER_OK = 0x20, /* Smaller-than-requested buffers ok */
+ DRM_DMA_LARGER_OK = 0x40 /* Larger-than-requested buffers ok */
+} drmDMAFlags;
+
+typedef enum {
+ DRM_LOCK_READY = 0x01, /* Wait until hardware is ready for DMA */
+ DRM_LOCK_QUIESCENT = 0x02, /* Wait until hardware quiescent */
+ DRM_LOCK_FLUSH = 0x04, /* Flush this context's DMA queue first */
+ DRM_LOCK_FLUSH_ALL = 0x08, /* Flush all DMA queues first */
+ /* These *HALT* flags aren't supported yet
+ -- they will be used to support the
+ full-screen DGA-like mode. */
+ DRM_HALT_ALL_QUEUES = 0x10, /* Halt all current and future queues */
+ DRM_HALT_CUR_QUEUES = 0x20 /* Halt all current queues */
+} drmLockFlags;
+
+typedef enum {
+ DRM_CONTEXT_PRESERVED = 0x01, /* This context is preserved and
+ never swapped. */
+ DRM_CONTEXT_2DONLY = 0x02 /* This context is for 2D rendering only. */
+} drmContextFlags, *drmContextFlagsPtr;
+
+typedef enum {
+ /* These are present in drm.h, but there
+ is no performance-related reason why
+ they need to match -- it's all done in
+ a case statement in xf86drm.c */
+ DRM_IH_PRE_INST, /* Before IH installation */
+ DRM_IH_POST_INST, /* After IH installation */
+ DRM_IH_SERVICE, /* IH */
+ DRM_IH_PRE_UNINST, /* Before IH uninstallation */
+ DRM_IH_POST_UNINST, /* After IH uninstallation */
+ DRM_DMA_DISPATCH, /* DMA dispatch (including ready) */
+ DRM_DMA_READY, /* Ready for DMA */
+ DRM_DMA_IS_READY, /* Tests if hardware ready for another DMA*/
+ DRM_DMA_QUIESCENT, /* HW Sync */
+ DRM_DESC_MAX
+} drmCtlDesc;
+
+typedef struct _drmBufDesc {
+ int count; /* Number of buffers of this size */
+ int size; /* Size in bytes */
+ int low_mark; /* Low water mark */
+ int high_mark; /* High water mark */
+} drmBufDesc, *drmBufDescPtr;
+
+typedef struct _drmBufInfo {
+ int count; /* Number of buffers described in list */
+ drmBufDescPtr list; /* List of buffer descriptions */
+} drmBufInfo, *drmBufInfoPtr;
+
+typedef struct _drmBuf {
+ int idx; /* Index into master buflist */
+ int total; /* Buffer size */
+ int used; /* Amount of buffer in use (for DMA) */
+ drmAddress address; /* Address */
+} drmBuf, *drmBufPtr;
+
+typedef struct _drmBufMap {
+ int count; /* Number of buffers mapped */
+ drmBufPtr list; /* Buffers */
+} drmBufMap, *drmBufMapPtr;
+
+typedef struct _drmLock {
+ volatile unsigned int lock;
+ char padding[60];
+ /* This is big enough for most current (and future?) architectures:
+ DEC Alpha: 32 bytes
+ Intel Merced: ?
+ Intel P5/PPro/PII/PIII: 32 bytes
+ Intel StrongARM: 32 bytes
+ Intel i386/i486: 16 bytes
+ MIPS: 32 bytes (?)
+ Motorola 68k: 16 bytes
+ Motorola PowerPC: 32 bytes
+ Sun SPARC: 32 bytes
+ */
+} drmLock, *drmLockPtr;
+
+typedef struct _drmDMAReq {
+ /* Indices here refer to the offset into
+ list in drmBufInfo */
+ drmContext context; /* Context handle */
+ int send_count; /* Number of buffers to send */
+ int *send_list; /* List of handles to buffers */
+ int *send_sizes; /* Lengths of data to send, in bytes */
+ drmDMAFlags flags; /* Flags */
+ int request_count; /* Number of buffers requested */
+ int request_size; /* Desired size of buffers requested */
+ int *request_list; /* Buffer information */
+ int *request_sizes; /* Minimum acceptable sizes */
+ int granted_count; /* Number of buffers granted at this size */
+} drmDMAReq, *drmDMAReqPtr;
+
+#if 0
+ /* The kernel does this, but it doesn't
+ seem necessary with recent gcc's. */
+typedef struct { unsigned int a[100]; } __drm_dummy_lock_t;
+#define __drm_dummy_lock(lock) (*(__volatile__ __drm_dummy_lock_t *)lock)
+#else
+#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)
+#endif
+
+#define DRM_LOCK_HELD 0x80000000 /* Hardware lock is held */
+#define DRM_LOCK_CONT 0x40000000 /* Hardware lock is contended */
+
+#if __GNUC__ >= 2 && defined(__i386)
+ /* Reflect changes here to drmP.h */
+#define DRM_CAS(lock,old,new,__ret) \
+ do { \
+ int __dummy; /* Can't mark eax as clobbered */ \
+ __asm__ __volatile__( \
+ "lock ; cmpxchg %4,%1\n\t" \
+ "setnz %0" \
+ : "=d" (__ret), \
+ "=m" (__drm_dummy_lock(lock)), \
+ "=a" (__dummy) \
+ : "2" (old), \
+ "r" (new)); \
+ } while (0)
+#endif
+
+#ifndef DRM_CAS
+#define DRM_CAS(lock,old,new,ret) /* FAST LOCK FAILS */
+#endif
+
+#define DRM_LIGHT_LOCK(fd,lock,context) \
+ do { \
+ char __ret; \
+ DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \
+ if (__ret) drmGetLock(fd,context,0); \
+ } while(0)
+
+ /* This one counts fast locks -- for
+ benchmarking only. */
+#define DRM_LIGHT_LOCK_COUNT(fd,lock,context,count) \
+ do { \
+ char __ret; \
+ DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \
+ if (__ret) drmGetLock(fd,context,0); \
+ else ++count; \
+ } while(0)
+
+#define DRM_LOCK(fd,lock,context,flags) \
+ do { \
+ if (flags) drmGetLock(fd,context,flags); \
+ else DRM_LIGHT_LOCK(fd,lock,context); \
+ } while(0)
+
+#define DRM_UNLOCK(fd,lock,context) \
+ do { \
+ char __ret; \
+ DRM_CAS(lock,DRM_LOCK_HELD|context,context,__ret); \
+ if (__ret) drmUnlock(fd,context); \
+ } while(0)
+
+ /* Simple spin locks */
+#define DRM_SPINLOCK(spin,val) \
+ do { \
+ char __ret; \
+ do { \
+ DRM_CAS(spin,0,val,__ret); \
+ if (__ret) while ((spin)->lock); \
+ } while (__ret); \
+ } while(0)
+
+#define DRM_SPINLOCK_TAKE(spin,val) \
+ do { \
+ char __ret; \
+ int cur; \
+ do { \
+ cur = (*spin).lock; \
+ DRM_CAS(spin,cur,val,__ret); \
+ } while (__ret); \
+ } while(0)
+
+#define DRM_SPINLOCK_COUNT(spin,val,count,__ret) \
+ do { \
+ int __i; \
+ __ret = 1; \
+ for (__i = 0; __ret && __i < count; __i++) { \
+ DRM_CAS(spin,0,val,__ret); \
+ if (__ret) for (;__i < count && (spin)->lock; __i++); \
+ } \
+ } while(0)
+
+#define DRM_SPINUNLOCK(spin,val) \
+ do { \
+ char __ret; \
+ if ((*spin).lock == val) { /* else server stole lock */ \
+ do { \
+ DRM_CAS(spin,val,0,__ret); \
+ } while (__ret); \
+ } \
+ } while(0)
+
+ /* These constants MUST MATCH drm.h */
+#define DRM_INST_LENGTH 5
+
+#define DRM_M_WRITE 0x00
+#define DRM_M_WHILE 0x01
+#define DRM_M_IF 0x02
+#define DRM_M_GOTO 0x03
+#define DRM_M_NOOP 0x04
+#define DRM_M_RETURN 0x05
+#define DRM_M_DO 0x06
+#define DRM_M_READ 0x07
+#define DRM_M_TEST 0x08
+
+#define DRM_T_IMM 0x00 /* MUST BE 0 */
+#define DRM_T_LENGTH 0x01
+#define DRM_T_ADDRESS 0x02
+#define DRM_T_ACC 0x03
+
+#define DRM_V_NONE 0x00 /* MUST BE 0 */
+#define DRM_V_RSHIFT 0x01
+#define DRM_V_LSHIFT 0x02
+
+#define DRM_C_EQ 0x01
+#define DRM_C_LT 0x02
+#define DRM_C_GT 0x03
+#define DRM_C_LE 0x04
+#define DRM_C_GE 0x05
+#define DRM_C_NE 0x06
+#define DRM_C_BIT 0x07
+
+#define DRM_F_NOOP 0x00
+#define DRM_F_DMA 0x01
+#define DRM_F_SYNC 0x02
+#define DRM_F_EXTEN 0x03
+#define DRM_F_ERROR 0x04
+#define DRM_F_VERT 0x05
+#define DRM_F_CLEAR 0x06
+
+#define DRM_I_CMD(x) ((x) & 0xfff)
+#define DRM_I_TYPE(x) (((x) & 0x00f) <<12)
+#define DRM_I_MOD(x) (((x) & 0x00f) <<16)
+#define DRM_I_MODVAL(x) (((x) & 0x0ff) <<24)
+#define DRM_I_COND(x) (((x) & 0x00f) <<28)
+
+#define DRM_E_CMD(x) ((x) &0x00000fff)
+#define DRM_E_TYPE(x) (((x)&0x0000f000)>>12)
+#define DRM_E_MOD(x) (((x)&0x000f0000)>>16)
+#define DRM_E_MODVAL(x) (((x)&0x0ff00000)>>24)
+#define DRM_E_COND(x) (((x)&0xf0000000)>>28)
+
+
+#define DRM_I_WRITE(group,offset,type,value,mod,modval) \
+ DRM_I_CMD(DRM_M_WRITE) | DRM_I_TYPE(type) \
+ | DRM_I_MOD(mod) \
+ | DRM_I_MODVAL(modval) \
+ ,(group), (offset), (value), 0
+
+#define DRM_I_WRITE_IMM(group,offset,value) \
+ DRM_I_CMD(DRM_M_WRITE),(group), (offset), (value), 0
+
+#define DRM_I_WHILE(group,offset,type,value,mod,modval,cond) \
+ DRM_I_CMD(DRM_M_WHILE) | DRM_I_TYPE(type) \
+ | DRM_I_MOD(mod) \
+ | DRM_I_MODVAL(modval) \
+ | DRM_I_COND(cond) \
+ ,(group), (offset), (value), 0
+
+#define DRM_I_WHILE_IMM(group,offset,value,cond) \
+ DRM_I_CMD(DRM_M_WHILE) | DRM_I_COND(cond) \
+ ,(group), (offset), (value), 0
+
+#define DRM_I_IF(group,offset,type,value,mod,modval,cond,inst) \
+ DRM_I_CMD(DRM_M_IF) | DRM_I_TYPE(type) \
+ | DRM_I_MOD(mod) \
+ | DRM_I_MODVAL(modval) \
+ | DRM_I_COND(cond) \
+ ,(group), (offset), (value), (inst)
+
+#define DRM_I_IF_IMM(group,offset,value,cond,inst) \
+ DRM_I_CMD(DRM_M_IF) | DRM_I_COND(cond) \
+ ,(group), (offset), (value), (inst)
+
+#define DRM_I_TEST(type,value,mod,modval,cond,inst) \
+ DRM_I_CMD(DRM_M_TEST) | DRM_I_TYPE(type) \
+ | DRM_I_MOD(mod) \
+ | DRM_I_MODVAL(modval) \
+ | DRM_I_COND(cond) \
+ ,0, 0, (value), (inst)
+
+#define DRM_I_TEST_IMM(value,cond,inst) \
+ DRM_I_CMD(DRM_M_TEST) | DRM_I_COND(cond) \
+ ,0, 0, (value), (inst)
+
+#define DRM_I_GOTO(inst) DRM_I_CMD(DRM_M_GOTO),0, 0, 0, (inst)
+#define DRM_I_NOOP DRM_I_CMD(DRM_M_NOOP), 0, 0, 0, 0
+#define DRM_I_RETURN(value) DRM_I_CMD(DRM_M_RETURN), 0, 0, (value), 0
+#define DRM_I_DO(inst) DRM_I_CMD(DRM_M_DO), 0, 0, 0, (inst)
+#define DRM_I_READ(group,offset) DRM_I_CMD(DRM_M_READ), (group), (offset), 0, 0
+
+
+
+/* General user-level programmer's API: unprivileged */
+extern int drmAvailable(void);
+extern int drmOpenDRM(void);
+extern int drmCloseDRM(int fd);
+extern drmVersionPtr drmGetVersion(int fd);
+extern void drmFreeVersion(drmVersionPtr);
+extern drmListPtr drmGetVersionList(int fd);
+extern void drmFreeVersionList(drmListPtr);
+extern int drmGetInterruptFromBusID(int fd, int busnum, int devnum,
+ int funcnum);
+
+
+/* General user-level programmer's API: X server (root) only */
+extern int drmCreateSub(int fd, const char *name, const char *busid);
+extern int drmDestroySub(int fd, const char *busid);
+extern int drmAuthMagic(int fd, drmMagic magic);
+extern int drmAddMap(int fd,
+ drmHandle offset,
+ drmSize size,
+ drmMapType type,
+ drmMapFlags flags,
+ drmHandlePtr handle);
+extern int drmAddBufs(int fd, int count, int size, int flags);
+extern int drmMarkBufs(int fd, double low, double high);
+extern int drmCreateContext(int fd, drmContextPtr handle);
+extern int drmSetContextFlags(int fd, drmContext context,
+ drmContextFlags flags);
+extern int drmGetContextFlags(int fd, drmContext context,
+ drmContextFlagsPtr flags);
+extern int drmAddContextTag(int fd, drmContext context, void *tag);
+extern int drmDelContextTag(int fd, drmContext context);
+extern void *drmGetContextTag(int fd, drmContext context);
+extern drmContextPtr drmGetReservedContextList(int fd, int *count);
+extern void drmFreeReservedContextList(drmContextPtr);
+extern int drmSwitchToContext(int fd, drmContext context);
+extern int drmDestroyContext(int fd, drmContext handle);
+extern int drmCreateDrawable(int fd, drmDrawablePtr handle);
+extern int drmDestroyDrawable(int fd, drmDrawable handle);
+extern int drmCtlAddCommand(int fd, drmCtlDesc desc,
+ int count, int *inst);
+extern int drmCtlRemoveCommands(int fd);
+extern int drmCtlInstHandler(int fd, int irq);
+extern int drmCtlUninstHandler(int fd);
+extern int drmInstallSIGIOHandler(int fd,
+ void (*f)(int fd,
+ void *oldctx,
+ void *newctx));
+extern int drmRemoveSIGIOHandler(int fd);
+
+/* General user-level programmer's API: authenticated client and/or X */
+extern int drmOpenSub(const char *busid);
+extern int drmCloseSub(int fd);
+extern int drmGetMagic(int fd, drmMagicPtr magic);
+extern int drmMap(int fd,
+ drmHandle handle,
+ drmSize size,
+ drmAddressPtr address);
+extern int drmUnmap(drmAddress address, drmSize size);
+extern drmBufInfoPtr drmGetBufInfo(int fd);
+extern drmBufMapPtr drmMapBufs(int fd);
+extern int drmUnmapBufs(drmBufMapPtr bufs);
+extern int drmDMA(int fd, drmDMAReqPtr request);
+extern int drmFreeBufs(int fd, int count, int *list);
+extern int drmGetLock(int fd,
+ drmContext context,
+ drmLockFlags flags);
+extern int drmUnlock(int fd, drmContext context);
+extern int drmFinish(int fd, int context, drmLockFlags flags);
+
+/* Support routines */
+extern int drmError(int err, const char *label);
+extern void *drmMalloc(int size);
+extern void drmFree(void *pt);
+
+/* Hash table routines */
+extern void *drmHashCreate(void);
+extern int drmHashDestroy(void *t);
+extern int drmHashLookup(void *t, unsigned long key, void **value);
+extern int drmHashInsert(void *t, unsigned long key, void *value);
+extern int drmHashDelete(void *t, unsigned long key);
+extern int drmHashFirst(void *t, unsigned long *key, void **value);
+extern int drmHashNext(void *t, unsigned long *key, void **value);
+
+/* PRNG routines */
+extern void *drmRandomCreate(unsigned long seed);
+extern int drmRandomDestroy(void *state);
+extern unsigned long drmRandom(void *state);
+extern double drmRandomDouble(void *state);
+
+/* Skip list routines */
+
+extern void *drmSLCreate(void);
+extern int drmSLDestroy(void *l);
+extern int drmSLLookup(void *l, unsigned long key, void **value);
+extern int drmSLInsert(void *l, unsigned long key, void *value);
+extern int drmSLDelete(void *l, unsigned long key);
+extern int drmSLNext(void *l, unsigned long *key, void **value);
+extern int drmSLFirst(void *l, unsigned long *key, void **value);
+extern void drmSLDump(void *l);
+extern int drmSLLookupNeighbors(void *l, unsigned long key,
+ unsigned long *prev_key, void **prev_value,
+ unsigned long *next_key, void **next_value);
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/parser/Configint.h b/xc/programs/Xserver/hw/xfree86/parser/Configint.h
new file mode 100644
index 000000000..c55f7c182
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/Configint.h
@@ -0,0 +1,188 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/Configint.h,v 1.13 1999/06/06 15:23:03 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/*
+ * These definitions are used through out the configuration file parser, but
+ * they should not be visible outside of the parser.
+ */
+
+#ifndef _Configint_h_
+#define _Configint_h_
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include "xf86Parser.h"
+
+typedef struct
+{
+ int num; /* returned number */
+ char *str; /* private copy of the return-string */
+ double realnum; /* returned number as a real */
+}
+LexRec, *LexPtr;
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#include "configProcs.h"
+#include <stdlib.h>
+#define xf86confmalloc malloc
+#define xf86confrealloc realloc
+#define xf86confcalloc calloc
+#define xf86conffree free
+
+#define TestFree(a) if (a) { xf86conffree (a); a = NULL; }
+
+#define parsePrologue(typeptr,typerec) int token; typeptr ptr; \
+if( (ptr=(typeptr)xf86confcalloc(1,sizeof(typerec))) == NULL ) { return NULL; } \
+memset(ptr,0,sizeof(typerec));
+
+#define parsePrologueVoid(typeptr,typerec) int token; typeptr ptr; \
+if( (ptr=(typeptr)xf86confcalloc(1,sizeof(typerec))) == NULL ) { return; } \
+memset(ptr,0,sizeof(typerec));
+
+#define HANDLE_RETURN(f,func)\
+if ((ptr->f=func) == NULL)\
+{\
+ CLEANUP (ptr);\
+ return (NULL);\
+}
+
+#define HANDLE_LIST(field,func,type)\
+{\
+type p = func ();\
+if (p == NULL)\
+{\
+ CLEANUP (ptr);\
+ return (NULL);\
+}\
+else\
+{\
+ ptr->field = (type) addListItem ((glp) ptr->field, (glp) p);\
+}\
+}
+
+#define Error(a,b) { xf86ParseError (a, b); CLEANUP (ptr); return NULL; }
+
+/*
+ * These are defines for error messages to promote consistency.
+ * error messages are preceded by the line number, section and file name,
+ * so these messages should be about the specific keyword and syntax in error.
+ * To help limit namespace polution, end each with _MSG.
+ * limit messages to 70 characters if possible.
+ */
+
+#define BAD_OPTION_MSG \
+"The Option keyword requires 1 or 2 quoted strings to follow it."
+#define INVALID_KEYWORD_MSG \
+"\"%s\" is not a valid keyword in this section."
+#define INVALID_SECTION_MSG \
+"\"%s\" is not a valid section name."
+#define UNEXPECTED_EOF_MSG \
+"Unexpected EOF. Missing EndSection keyword?"
+#define QUOTE_MSG \
+"The %s keyword requires a quoted string to follow it."
+#define NUMBER_MSG \
+"The %s keyword requires a number to follow it."
+#define POSITIVE_INT_MSG \
+"The %s keyword requires a positive integer to follow it."
+#define ZAXISMAPPING_MSG \
+"The ZAxisMapping keyword requires 2 positive numbers or X or Y to follow it."
+#define AUTOREPEAT_MSG \
+"The AutoRepeat keyword requires 2 numbers (delay and rate) to follow it."
+#define XLEDS_MSG \
+"The XLeds keyword requries one or more numbers to follow it."
+#define DACSPEED_MSG \
+"The DacSpeed keyword must be followed by a list of up to %d numbers."
+#define DISPLAYSIZE_MSG \
+"The DisplaySize keyword must be followed by the width and height in mm."
+#define HORIZSYNC_MSG \
+"The HorizSync keyword must be followed by a list of numbers or ranges."
+#define VERTREFRESH_MSG \
+"The VertRefresh keyword must be followed by a list of numbers or ranges."
+#define VIEWPORT_MSG \
+"The Viewport keyword must be followed by an X and Y value."
+#define VIRTUAL_MSG \
+"The Virtual keyword must be followed by a width and height value."
+#define WEIGHT_MSG \
+"The Weight keyword must be followed by red, green and blue values."
+#define BLACK_MSG \
+"The Black keyword must be followed by red, green and blue values."
+#define WHITE_MSG \
+"The White keyword must be followed by red, green and blue values."
+#define SCREEN_MSG \
+"The Screen keyword must be followed by an optional number and 1 or 5 \n\tscreen names in quotes."
+#define INPUTDEV_MSG \
+"The InputDevice keyword must be followed by an input device name in quotes."
+#define INACTIVE_MSG \
+"The Inactive keyword must be followed by a Device name in quotes."
+#define UNDEFINED_SCREEN_MSG \
+"Undefined Screen \"%s\" referenced by ServerLayout \"%s\"."
+#define UNDEFINED_MONITOR_MSG \
+"Undefined Monitor \"%s\" referenced by Screen \"%s\"."
+#define UNDEFINED_MODES_MSG \
+"Undefined Modes Section \"%s\" referenced by Monitor \"%s\"."
+#define UNDEFINED_DEVICE_MSG \
+"Undefined Device \"%s\" referenced by Screen \"%s\"."
+#define UNDEFINED_ADAPTOR_MSG \
+"Undefined VideoAdaptor \"%s\" referenced by Screen \"%s\"."
+#define ADAPTOR_REF_TWICE_MSG \
+"VideoAdaptor \"%s\" already referenced by Screen \"%s\"."
+#define UNDEFINED_DEVICE_LAY_MSG \
+"Undefined Device \"%s\" referenced by ServerLayout \"%s\"."
+#define UNDEFINED_INPUT_MSG \
+"Undefined InputDevice \"%s\" referenced by ServerLayout \"%s\"."
+#define NO_IDENT_MSG \
+"This section must have an Identifier line."
+#define ONLY_ONE_MSG \
+"This section must have only one of either %s line."
+#define UNDEFINED_DRIVER_MSG \
+"Device section \"%s\" must have a Driver line."
+#define UNDEFINED_INPUTDRIVER_MSG \
+"InputDevice section \"%s\" must have a Driver line."
+#define INVALID_GAMMA_MSG \
+"gamma correction value(s) expected\n either one value or three r/g/b values."
+
+/* Warning messages */
+#define OBSOLETE_MSG \
+"Ignoring obsolete keyword \"%s\"."
+#define MOVED_TO_FLAGS_MSG \
+"Keyword \"%s\" is now an Option flag in the ServerFlags section."
+
+#endif /* _Configint_h_ */
diff --git a/xc/programs/Xserver/hw/xfree86/parser/DRI.c b/xc/programs/Xserver/hw/xfree86/parser/DRI.c
new file mode 100644
index 000000000..80190fcb1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/DRI.c
@@ -0,0 +1,161 @@
+/* DRI.c -- DRI Section in XF86Config file
+ * Created: Fri Mar 19 08:40:22 1999 by faith@precisioninsight.com
+ * Revised: Thu Jun 17 16:08:05 1999 by faith@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ *
+ * $PI: xc/programs/Xserver/hw/xfree86/parser/DRI.c,v 1.2 1999/06/17 21:45:25 faith Exp $
+ * $XFree86: xc/programs/Xserver/hw/xfree86/parser/DRI.c,v 1.1 1999/06/27 14:08:30 dawes Exp $
+ *
+ */
+
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+
+extern LexRec val;
+
+static xf86ConfigSymTabRec DRITab[] =
+{
+ {ENDSECTION, "endsection"},
+ {GROUP, "group"},
+ {BUFFERS, "buffers"},
+ {MODE, "mode"},
+ {-1, ""},
+};
+
+#define DEBUG
+
+#define CLEANUP freeBuffersList
+
+XF86ConfBuffersPtr
+parseBuffers (void)
+{
+ parsePrologue (XF86ConfBuffersPtr, XF86ConfBuffersRec)
+
+ if (xf86GetToken (NULL) != NUMBER)
+ Error ("Buffers count expected", NULL);
+ ptr->buf_count = val.num;
+
+ if (xf86GetToken (NULL) != NUMBER)
+ Error ("Buffers size expected", NULL);
+ ptr->buf_size = val.num;
+
+ if ((token = xf86GetToken (NULL)) == STRING) {
+ ptr->buf_flags = val.str;
+ } else {
+ ptr->buf_flags = NULL;
+ xf86UnGetToken (token);
+ }
+
+#ifdef DEBUG
+ printf ("Buffers parsed\n");
+#endif
+
+ return ptr;
+}
+
+#undef CLEANUP
+
+#define CLEANUP freeDRI
+
+XF86ConfDRIPtr
+parseDRISection (void)
+{
+ parsePrologue (XF86ConfDRIPtr, XF86ConfDRIRec);
+
+ while ((token = xf86GetToken (DRITab)) != ENDSECTION) {
+ switch (token)
+ {
+ case GROUP:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (QUOTE_MSG, "Group");
+ ptr->dri_group = val.num;
+ break;
+ case MODE:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (QUOTE_MSG, "Mode");
+ ptr->dri_mode = val.num;
+ break;
+ case BUFFERS:
+ HANDLE_LIST (dri_buffers_lst, parseBuffers,
+ XF86ConfBuffersPtr);
+ break;
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ }
+
+#ifdef DEBUG
+ ErrorF("DRI section parsed\n");
+#endif
+
+ return ptr;
+}
+
+#undef CLEANUP
+
+void
+printDRISection (FILE * cf, XF86ConfDRIPtr ptr)
+{
+ XF86ConfBuffersPtr bufs;
+
+ if (ptr == NULL)
+ return;
+
+ if (ptr->dri_group)
+ fprintf (cf, "\tGroup %d\n", ptr->dri_group);
+ for (bufs = ptr->dri_buffers_lst; bufs; bufs = bufs->list.next) {
+ fprintf (cf, "\tBuffers %d %d",
+ bufs->buf_count, bufs->buf_size);
+ if (bufs->buf_flags) fprintf (cf, " \"%s\"", bufs->buf_flags);
+ fprintf (cf, "\n");
+ }
+}
+
+void
+freeDRI (XF86ConfDRIPtr ptr)
+{
+ if (ptr == NULL)
+ return;
+
+ xf86conffree (ptr);
+}
+
+void
+freeBuffersList (XF86ConfBuffersPtr ptr)
+{
+ XF86ConfBuffersPtr prev;
+
+ while (ptr) {
+ TestFree (ptr->buf_flags);
+ prev = ptr;
+ ptr = ptr->list.next;
+ xf86conffree (prev);
+ }
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/parser/Device.c b/xc/programs/Xserver/hw/xfree86/parser/Device.c
new file mode 100644
index 000000000..3503e1f59
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/Device.c
@@ -0,0 +1,375 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/Device.c,v 1.11 1999/06/27 14:08:30 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/* View/edit this file with tab stops set to 4 */
+
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+
+extern LexRec val;
+
+static
+xf86ConfigSymTabRec DeviceTab[] =
+{
+ {ENDSECTION, "endsection"},
+ {IDENTIFIER, "identifier"},
+ {VENDOR, "vendorname"},
+ {BOARD, "boardname"},
+ {CHIPSET, "chipset"},
+ {RAMDAC, "ramdac"},
+ {DACSPEED, "dacspeed"},
+ {CLOCKS, "clocks"},
+ {OPTION, "option"},
+ {VIDEORAM, "videoram"},
+ {BIOSBASE, "biosbase"},
+ {MEMBASE, "membase"},
+ {IOBASE, "iobase"},
+ {CLOCKCHIP, "clockchip"},
+ {CHIPID, "chipid"},
+ {CHIPREV, "chiprev"},
+ {CARD, "card"},
+ {DRIVER, "driver"},
+ {BUSID, "busid"},
+ {TEXTCLOCKFRQ, "textclockfreq"},
+ {IRQ, "irq"},
+ {-1, ""},
+};
+
+#define CLEANUP freeDeviceList
+
+XF86ConfDevicePtr
+parseDeviceSection (void)
+{
+ int i;
+ int has_ident = FALSE;
+ parsePrologue (XF86ConfDevicePtr, XF86ConfDeviceRec)
+
+ /* Zero is a valid value for these */
+ ptr->dev_chipid = -1;
+ ptr->dev_chiprev = -1;
+ while ((token = xf86GetToken (DeviceTab)) != ENDSECTION)
+ {
+ switch (token)
+ {
+ case IDENTIFIER:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Identifier");
+ ptr->dev_identifier = val.str;
+ has_ident = TRUE;
+ break;
+ case VENDOR:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Vendor");
+ ptr->dev_vendor = val.str;
+ break;
+ case BOARD:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Board");
+ ptr->dev_board = val.str;
+ break;
+ case CHIPSET:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Chipset");
+ ptr->dev_chipset = val.str;
+ break;
+ case CARD:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Card");
+ ptr->dev_card = val.str;
+ break;
+ case DRIVER:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Driver");
+ ptr->dev_driver = val.str;
+ break;
+ case RAMDAC:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Ramdac");
+ ptr->dev_ramdac = val.str;
+ break;
+ case DACSPEED:
+ for (i = 0; i < CONF_MAXDACSPEEDS; i++)
+ ptr->dev_dacSpeeds[i] = 0;
+ if (xf86GetToken (NULL) != NUMBER)
+ {
+ Error (DACSPEED_MSG, CONF_MAXDACSPEEDS);
+ }
+ else
+ {
+ ptr->dev_dacSpeeds[0] = (int) (val.realnum * 1000.0 + 0.5);
+ for (i = 1; i < CONF_MAXDACSPEEDS; i++)
+ {
+ if (xf86GetToken (NULL) == NUMBER)
+ ptr->dev_dacSpeeds[i] = (int)
+ (val.realnum * 1000.0 + 0.5);
+ else
+ {
+ xf86UnGetToken (token);
+ break;
+ }
+ }
+ }
+ break;
+ case VIDEORAM:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "VideoRam");
+ ptr->dev_videoram = val.num;
+ break;
+ case BIOSBASE:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "BIOSBase");
+ ptr->dev_bios_base = val.num;
+ break;
+ case MEMBASE:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "MemBase");
+ ptr->dev_mem_base = val.num;
+ break;
+ case IOBASE:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "IOBase");
+ ptr->dev_io_base = val.num;
+ break;
+ case CLOCKCHIP:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "ClockChip");
+ ptr->dev_clockchip = val.str;
+ break;
+ case CHIPID:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "ChipID");
+ ptr->dev_chipid = val.num;
+ break;
+ case CHIPREV:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "ChipRev");
+ ptr->dev_chiprev = val.num;
+ break;
+
+ case CLOCKS:
+ token = xf86GetToken(NULL);
+ for( i = ptr->dev_clocks;
+ token == NUMBER && i < CONF_MAXCLOCKS; i++ ) {
+ ptr->dev_clock[i] = (int)(val.realnum * 1000.0 + 0.5);
+ token = xf86GetToken(NULL);
+ }
+ ptr->dev_clocks = i;
+ xf86UnGetToken (token);
+ break;
+ case TEXTCLOCKFRQ:
+ if ((token = xf86GetToken(NULL)) != NUMBER)
+ Error (NUMBER_MSG, "TextClockFreq");
+ ptr->dev_textclockfreq = (int)(val.realnum * 1000.0 + 0.5);
+ break;
+ case OPTION:
+ {
+ char *name;
+ if ((token = xf86GetToken (NULL)) != STRING)
+ Error (BAD_OPTION_MSG, NULL);
+ name = val.str;
+ if ((token = xf86GetToken (NULL)) == STRING)
+ {
+ ptr->dev_option_lst = addNewOption (ptr->dev_option_lst,
+ name, val.str);
+ }
+ else
+ {
+ ptr->dev_option_lst = addNewOption (ptr->dev_option_lst,
+ name, NULL);
+ xf86UnGetToken (token);
+ }
+ }
+ break;
+ case BUSID:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "BusID");
+ ptr->dev_busid = val.str;
+ break;
+ case IRQ:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (QUOTE_MSG, "IRQ");
+ ptr->dev_irq = val.num;
+ break;
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ }
+
+ if (!has_ident)
+ Error (NO_IDENT_MSG, NULL);
+
+#ifdef DEBUG
+ printf ("Device section parsed\n");
+#endif
+
+ return ptr;
+}
+
+#undef CLEANUP
+
+void
+printDeviceSection (FILE * cf, XF86ConfDevicePtr ptr)
+{
+ XF86OptionPtr optr;
+ int i;
+
+ while (ptr)
+ {
+ fprintf (cf, "Section \"Device\"\n");
+ if (ptr->dev_identifier)
+ fprintf (cf, "\tIdentifier \"%s\"\n", ptr->dev_identifier);
+ if (ptr->dev_driver)
+ fprintf (cf, "\tDriver \"%s\"\n", ptr->dev_driver);
+ if (ptr->dev_vendor)
+ fprintf (cf, "\tVendorName \"%s\"\n", ptr->dev_vendor);
+ if (ptr->dev_board)
+ fprintf (cf, "\tBoardName \"%s\"\n", ptr->dev_board);
+ if (ptr->dev_chipset)
+ fprintf (cf, "\tChipSet \"%s\"\n", ptr->dev_chipset);
+ if (ptr->dev_card)
+ fprintf (cf, "\tCard \"%s\"\n", ptr->dev_card);
+ if (ptr->dev_ramdac)
+ fprintf (cf, "\tRamDac \"%s\"\n", ptr->dev_ramdac);
+ if (ptr->dev_dacSpeeds[0] > 0 ) {
+ fprintf (cf, "\tDacSpeed ");
+ for (i = 0; i < CONF_MAXDACSPEEDS
+ && ptr->dev_dacSpeeds[i] > 0; i++ )
+ fprintf (cf, "%g ", (double) (ptr->dev_dacSpeeds[i])/ 1000.0 );
+ fprintf (cf, "\n");
+ }
+ if (ptr->dev_videoram)
+ fprintf (cf, "\tVideoRam %d\n", ptr->dev_videoram);
+ if (ptr->dev_bios_base)
+ fprintf (cf, "\tBiosBase 0x%lx\n", ptr->dev_bios_base);
+ if (ptr->dev_mem_base)
+ fprintf (cf, "\tMemBase 0x%lx\n", ptr->dev_mem_base);
+ if (ptr->dev_io_base)
+ fprintf (cf, "\tIOBase 0x%lx\n", ptr->dev_io_base);
+ if (ptr->dev_clockchip)
+ fprintf (cf, "\tClockChip \"%s\"\n", ptr->dev_clockchip);
+ if (ptr->dev_chipid != -1)
+ fprintf (cf, "\tChipId %d\n", ptr->dev_chipid);
+ if (ptr->dev_chiprev != -1)
+ fprintf (cf, "\tChipRev %d\n", ptr->dev_chiprev);
+
+ for (optr = ptr->dev_option_lst; optr; optr = optr->list.next)
+ {
+ fprintf (cf, "\tOption \"%s\"", optr->opt_name);
+ if (optr->opt_val)
+ fprintf (cf, " \"%s\"", optr->opt_val);
+ fprintf (cf, "\n");
+ }
+ if (ptr->dev_clocks > 0 ) {
+ fprintf (cf, "\tClocks ");
+ for (i = 0; i < ptr->dev_clocks; i++ )
+ fprintf (cf, "%.1f ", (double)ptr->dev_clock[i] / 1000.0 );
+ fprintf (cf, "\n");
+ }
+ if (ptr->dev_textclockfreq) {
+ fprintf (cf, "\tTextClockFreq %.1f\n",
+ (double)ptr->dev_textclockfreq / 1000.0);
+ }
+ if (ptr->dev_busid)
+ fprintf (cf, "\tBusID \"%s\"\n", ptr->dev_busid);
+ if (ptr->dev_irq >= 0)
+ fprintf (cf, "\tIRQ %d\n", ptr->dev_irq);
+ fprintf (cf, "EndSection\n\n");
+ ptr = ptr->list.next;
+ }
+}
+
+void
+freeDeviceList (XF86ConfDevicePtr ptr)
+{
+ XF86ConfDevicePtr prev;
+
+ while (ptr)
+ {
+ TestFree (ptr->dev_identifier);
+ TestFree (ptr->dev_vendor);
+ TestFree (ptr->dev_board);
+ TestFree (ptr->dev_chipset);
+ TestFree (ptr->dev_card);
+ TestFree (ptr->dev_driver);
+ TestFree (ptr->dev_ramdac);
+ TestFree (ptr->dev_clockchip);
+ OptionListFree (ptr->dev_option_lst);
+
+ prev = ptr;
+ ptr = ptr->list.next;
+ xf86conffree (prev);
+ }
+}
+
+int
+validateDevice (XF86ConfigPtr p)
+{
+ XF86ConfDevicePtr device = p->conf_device_lst;
+
+ if (!device) {
+ xf86ValidationError ("At least one Device section is required.");
+ return (FALSE);
+ }
+
+ while (device) {
+ if (!device->dev_driver) {
+ xf86ValidationError (UNDEFINED_DRIVER_MSG, device->dev_identifier);
+ return (FALSE);
+ }
+ device = device->list.next;
+ }
+ return (TRUE);
+}
+
+XF86ConfDevicePtr
+xf86FindDevice (const char *ident, XF86ConfDevicePtr p)
+{
+ while (p)
+ {
+ if (NameCompare (ident, p->dev_identifier) == 0)
+ return (p);
+
+ p = p->list.next;
+ }
+ return (NULL);
+}
+
+char *
+ConfigStrdup (const char *s)
+{
+ char *tmp = xf86confmalloc (sizeof (char) * (strlen (s) + 1));
+ if (tmp)
+ strcpy (tmp, s);
+ return (tmp);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/parser/Files.c b/xc/programs/Xserver/hw/xfree86/parser/Files.c
new file mode 100644
index 000000000..87832cfc4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/Files.c
@@ -0,0 +1,213 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/Files.c,v 1.6 1999/05/30 14:04:23 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/* View/edit this file with tab stops set to 4 */
+
+#include "X11/Xos.h"
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+
+extern LexRec val;
+
+static xf86ConfigSymTabRec FilesTab[] =
+{
+ {ENDSECTION, "endsection"},
+ {FONTPATH, "fontpath"},
+ {RGBPATH, "rgbpath"},
+ {MODULEPATH, "modulepath"},
+ {LOGFILEPATH, "logfile"},
+ {-1, ""},
+};
+
+static char *
+prependRoot (char *pathname)
+{
+#ifndef __EMX__
+ return pathname;
+#else
+ /* XXXX caveat: multiple path components in line */
+ return (char *) __XOS2RedirRoot (pathname);
+#endif
+}
+
+#define CLEANUP freeFiles
+
+XF86ConfFilesPtr
+parseFilesSection (void)
+{
+ int i, j;
+ int k, l;
+ char *str;
+ parsePrologue (XF86ConfFilesPtr, XF86ConfFilesRec)
+
+ while ((token = xf86GetToken (FilesTab)) != ENDSECTION)
+ {
+ switch (token)
+ {
+ case FONTPATH:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "FontPath");
+ j = FALSE;
+ str = prependRoot (val.str);
+ if (ptr->file_fontpath == NULL)
+ {
+ ptr->file_fontpath = xf86confmalloc (1);
+ ptr->file_fontpath[0] = '\0';
+ i = strlen (str) + 1;
+ }
+ else
+ {
+ i = strlen (ptr->file_fontpath) + strlen (str) + 1;
+ if (ptr->file_fontpath[strlen (ptr->file_fontpath) - 1] != ',')
+ {
+ i++;
+ j = TRUE;
+ }
+ }
+ ptr->file_fontpath =
+ xf86confrealloc (ptr->file_fontpath, i);
+ if (j)
+ strcat (ptr->file_fontpath, ",");
+
+ strcat (ptr->file_fontpath, str);
+ xf86conffree (val.str);
+ break;
+ case RGBPATH:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "RGBPath");
+ ptr->file_rgbpath = val.str;
+ break;
+ case MODULEPATH:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "ModulePath");
+ l = FALSE;
+ str = prependRoot (val.str);
+ if (ptr->file_modulepath == NULL)
+ {
+ ptr->file_modulepath = xf86confmalloc (1);
+ ptr->file_modulepath[0] = '\0';
+ k = strlen (str) + 1;
+ }
+ else
+ {
+ k = strlen (ptr->file_modulepath) + strlen (str) + 1;
+ if (ptr->file_modulepath[strlen (ptr->file_modulepath) - 1] != ',')
+ {
+ k++;
+ l = TRUE;
+ }
+ }
+ ptr->file_modulepath = xf86confrealloc (ptr->file_modulepath, k);
+ if (l)
+ strcat (ptr->file_modulepath, ",");
+
+ strcat (ptr->file_modulepath, str);
+ xf86conffree (val.str);
+ break;
+ case LOGFILEPATH:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "LogFile");
+ ptr->file_logfile = val.str;
+ break;
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ }
+
+#ifdef DEBUG
+ printf ("File section parsed\n");
+#endif
+
+ return ptr;
+}
+
+#undef CLEANUP
+
+void
+printFileSection (FILE * cf, XF86ConfFilesPtr ptr)
+{
+ char *p, *s;
+
+ if (ptr == NULL)
+ return;
+
+ if (ptr->file_logfile)
+ fprintf (cf, "\tLogFile \"%s\"\n", ptr->file_logfile);
+ if (ptr->file_rgbpath)
+ fprintf (cf, "\tRgbPath \"%s\"\n", ptr->file_rgbpath);
+ if (ptr->file_modulepath)
+ {
+ s = ptr->file_modulepath;
+ p = index (s, ',');
+ while (p)
+ {
+ *p = '\000';
+ fprintf (cf, "\tModulePath \"%s\"\n", s);
+ *p = ',';
+ s = p;
+ s++;
+ p = index (s, ',');
+ }
+ fprintf (cf, "\tModulePath \"%s\"\n", s);
+ }
+ if (ptr->file_fontpath)
+ {
+ s = ptr->file_fontpath;
+ p = index (s, ',');
+ while (p)
+ {
+ *p = '\000';
+ fprintf (cf, "\tFontPath \"%s\"\n", s);
+ *p = ',';
+ s = p;
+ s++;
+ p = index (s, ',');
+ }
+ fprintf (cf, "\tFontPath \"%s\"\n", s);
+ }
+}
+
+void
+freeFiles (XF86ConfFilesPtr p)
+{
+ if (p == NULL)
+ return;
+
+ TestFree (p->file_logfile);
+ TestFree (p->file_rgbpath);
+ TestFree (p->file_modulepath);
+ TestFree (p->file_fontpath);
+
+ xf86conffree (p);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/parser/Flags.c b/xc/programs/Xserver/hw/xfree86/parser/Flags.c
new file mode 100644
index 000000000..36077328d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/Flags.c
@@ -0,0 +1,430 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/Flags.c,v 1.9 1999/06/05 15:55:32 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/* View/edit this file with tab stops set to 4 */
+
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+#include <math.h>
+
+extern LexRec val;
+
+static xf86ConfigSymTabRec ServerFlagsTab[] =
+{
+ {ENDSECTION, "endsection"},
+ {NOTRAPSIGNALS, "notrapsignals"},
+ {DONTZAP, "dontzap"},
+ {DONTZOOM, "dontzoom"},
+ {DISABLEVIDMODE, "disablevidmodeextension"},
+ {ALLOWNONLOCAL, "allownonlocalxvidtune"},
+ {DISABLEMODINDEV, "disablemodindev"},
+ {MODINDEVALLOWNONLOCAL, "allownonlocalmodindev"},
+ {ALLOWMOUSEOPENFAIL, "allowmouseopenfail"},
+ {OPTION, "option"},
+ {BLANKTIME, "blanktime"},
+ {STANDBYTIME, "standbytime"},
+ {SUSPENDTIME, "suspendtime"},
+ {OFFTIME, "offtime"},
+ {-1, ""},
+};
+
+#define CLEANUP freeFlags
+
+XF86ConfFlagsPtr
+parseFlagsSection (void)
+{
+ parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec)
+
+ while ((token = xf86GetToken (ServerFlagsTab)) != ENDSECTION)
+ {
+ int hasvalue = FALSE;
+ switch (token)
+ {
+ /*
+ * these old keywords are turned into standard generic options.
+ * we fall through here on purpose
+ */
+ case BLANKTIME:
+ case STANDBYTIME:
+ case SUSPENDTIME:
+ case OFFTIME:
+ hasvalue = TRUE;
+ case NOTRAPSIGNALS:
+ case DONTZAP:
+ case DONTZOOM:
+ case DISABLEVIDMODE:
+ case ALLOWNONLOCAL:
+ case DISABLEMODINDEV:
+ case MODINDEVALLOWNONLOCAL:
+ case ALLOWMOUSEOPENFAIL:
+ {
+ int i = 0;
+ while (ServerFlagsTab[i].token != -1)
+ {
+ char *tmp;
+
+ if (ServerFlagsTab[i].token == token)
+ {
+ char *valstr = NULL;
+ /* can't use strdup because it calls malloc */
+ tmp = ConfigStrdup (ServerFlagsTab[i].name);
+ if (hasvalue)
+ {
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, tmp);
+ valstr = xf86confmalloc(16);
+ if (valstr)
+ sprintf(valstr, "%d", val.num);
+ }
+ ptr->flg_option_lst = addNewOption
+ (ptr->flg_option_lst, tmp, valstr);
+ }
+ i++;
+ }
+ }
+ break;
+ case OPTION:
+ {
+ char *name;
+ if ((token = xf86GetToken (NULL)) != STRING)
+ {
+ Error (BAD_OPTION_MSG, NULL);
+ break;
+ }
+
+ name = val.str;
+ if ((token = xf86GetToken (NULL)) == STRING)
+ {
+ ptr->flg_option_lst = addNewOption (ptr->flg_option_lst,
+ name, val.str);
+ }
+ else
+ {
+ ptr->flg_option_lst = addNewOption (ptr->flg_option_lst,
+ name, NULL);
+ xf86UnGetToken (token);
+ }
+ }
+ break;
+
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ }
+
+#ifdef DEBUG
+ printf ("Flags section parsed\n");
+#endif
+
+ return ptr;
+}
+
+#undef CLEANUP
+
+void
+printServerFlagsSection (FILE * f, XF86ConfFlagsPtr flags)
+{
+ XF86OptionPtr p;
+
+ if ((!flags) || (!flags->flg_option_lst))
+ return;
+ p = flags->flg_option_lst;
+ fprintf (f, "Section \"ServerFlags\"\n");
+ while (p)
+ {
+ if (p->opt_val)
+ fprintf (f, "\tOption \"%s\" \"%s\"\n", p->opt_name, p->opt_val);
+ else
+ fprintf (f, "\tOption \"%s\"\n", p->opt_name);
+ p = p->list.next;
+ }
+ fprintf (f, "EndSection\n\n");
+}
+
+static XF86OptionPtr
+addNewOption2 (XF86OptionPtr head, char *name, char *val, int used)
+{
+ XF86OptionPtr new, old = NULL;
+
+ /* Don't allow duplicates */
+ if (head != NULL && (old = FindOption(head, name)) != NULL)
+ new = old;
+ else
+ new = xf86confmalloc (sizeof (XF86OptionRec));
+ new->opt_name = name;
+ new->opt_val = val;
+ new->opt_used = used;
+ new->list.next = NULL;
+
+ if (old == NULL)
+ return ((XF86OptionPtr) addListItem ((glp) head, (glp) new));
+ else
+ return head;
+}
+
+XF86OptionPtr
+addNewOption (XF86OptionPtr head, char *name, char *val)
+{
+ return addNewOption2(head, name, val, 0);
+}
+
+void
+freeFlags (XF86ConfFlagsPtr flags)
+{
+ if (flags == NULL)
+ return;
+ OptionListFree (flags->flg_option_lst);
+ xf86conffree (flags);
+}
+
+XF86OptionPtr
+OptionListDup (XF86OptionPtr opt)
+{
+ XF86OptionPtr newopt = NULL;
+
+ while (opt)
+ {
+ newopt = addNewOption(newopt, opt->opt_name, opt->opt_val);
+ newopt->opt_used = opt->opt_used;
+ opt = opt->list.next;
+ }
+ return newopt;
+}
+
+void
+OptionListFree (XF86OptionPtr opt)
+{
+ XF86OptionPtr prev;
+
+ while (opt)
+ {
+ TestFree (opt->opt_name);
+ TestFree (opt->opt_val);
+ prev = opt;
+ opt = opt->list.next;
+ xf86conffree (prev);
+ }
+}
+
+char *
+OptionName(XF86OptionPtr opt)
+{
+ if (opt)
+ return opt->opt_name;
+ return 0;
+}
+
+char *
+OptionValue(XF86OptionPtr opt)
+{
+ if (opt)
+ return opt->opt_val;
+ return 0;
+}
+
+XF86OptionPtr
+NewOption(char *name, char *value)
+{
+ XF86OptionPtr opt;
+
+ opt = xf86confmalloc(sizeof (XF86OptionRec));
+ if (!opt)
+ return NULL;
+
+ opt->opt_used = 0;
+ opt->list.next = 0;
+ opt->opt_name = name;
+ opt->opt_val = value;
+
+ return opt;
+}
+
+XF86OptionPtr
+NextOption(XF86OptionPtr list)
+{
+ if (!list)
+ return NULL;
+ return list->list.next;
+}
+
+/*
+ * this function searches the given option list for the named option and
+ * returns a pointer to the option rec if found. If not found, it returns
+ * NULL
+ */
+
+XF86OptionPtr
+FindOption (XF86OptionPtr list, const char *name)
+{
+ while (list)
+ {
+ if (NameCompare (list->opt_name, name) == 0)
+ return (list);
+ list = list->list.next;
+ }
+ return (NULL);
+}
+
+/*
+ * this function searches the given option list for the named option. If
+ * found and the option has a parameter, a pointer to the parameter is
+ * returned. If the option does not have a parameter an empty string is
+ * returned. If the option is not found, a NULL is returned.
+ */
+
+char *
+FindOptionValue (XF86OptionPtr list, const char *name)
+{
+ XF86OptionPtr p = FindOption (list, name);
+
+ if (p)
+ {
+ if (p->opt_val)
+ return (p->opt_val);
+ else
+ return "";
+ }
+ return (NULL);
+}
+
+XF86OptionPtr
+OptionListCreate( const char **options, int count, int used )
+{
+ XF86OptionPtr p = NULL;
+ char *t1, *t2;
+ int i;
+
+ if (count == -1)
+ {
+ for (count = 0; options[count]; count++)
+ ;
+ }
+ if( (count % 2) != 0 )
+ {
+ fprintf( stderr, "OptionListCreate: count must be an even number.\n" );
+ return (NULL);
+ }
+ for (i = 0; i < count; i += 2)
+ {
+ /* can't use strdup because it calls malloc */
+ t1 = xf86confmalloc (sizeof (char) *
+ (strlen (options[i]) + 1));
+ strcpy (t1, options[i]);
+ t2 = xf86confmalloc (sizeof (char) *
+ (strlen (options[i + 1]) + 1));
+ strcpy (t2, options[i + 1]);
+ p = addNewOption2 (p, t1, t2, used);
+ }
+
+ return (p);
+}
+
+/* the 2 given lists are merged. If an option with the same name is present in
+ * both, the option from the user list is used. The end result is a single
+ * valid list of options. Duplicates are freed, and the original lists are no
+ * longer guaranteed to be complete.
+ */
+XF86OptionPtr
+OptionListMerge (XF86OptionPtr head, XF86OptionPtr tail)
+{
+ XF86OptionPtr a, b, ap = NULL, bp = NULL, f = NULL;
+
+ a = head;
+ while (a)
+ {
+ bp = NULL;
+ b = tail;
+ while (b)
+ {
+ if (NameCompare (a->opt_name, b->opt_name) == 0)
+ {
+ if ((a == head) && (b == tail))
+ {
+ head = b;
+ tail = b->list.next;
+ b->list.next = a->list.next;
+ bp = tail;
+ }
+ else if (a == head)
+ {
+ head = b;
+ bp->list.next = b->list.next;
+ b->list.next = a->list.next;
+ }
+ else if (b == tail)
+ {
+ tail = b->list.next;
+ ap->list.next = b;
+ b->list.next = a->list.next;
+ bp = tail;
+ }
+ else
+ {
+ ap->list.next = b;
+ bp->list.next = b->list.next;
+ b->list.next = a->list.next;
+ }
+ a->list.next = f;
+ f = a;
+ a = b;
+ b = bp;
+ continue;
+ }
+ bp = b;
+ b = b->list.next;
+ }
+ ap = a;
+ a = a->list.next;
+ }
+
+ ap->list.next = tail;
+
+ OptionListFree (f);
+ return (head);
+}
+
+char *
+ULongToString(unsigned long i)
+{
+ char *s;
+ int l;
+
+ l = (int)(ceil(log10((double)i) + 2.5));
+ s = xf86confmalloc(l);
+ if (!s)
+ return NULL;
+ sprintf(s, "%lu", i);
+ return s;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/parser/Imakefile b/xc/programs/Xserver/hw/xfree86/parser/Imakefile
new file mode 100644
index 000000000..09075602e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/Imakefile
@@ -0,0 +1,54 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/Imakefile,v 1.9 1999/07/04 06:39:16 dawes Exp $ */
+
+
+
+#define DoNormalLib YES
+#define DoSharedLib NO
+#define DoDebugLib NO
+#define DoProfileLib NO
+#define HasSharedData NO
+#define LibName xf86config
+
+#if NewInput
+INPUTDEFS=-DNEW_INPUT
+#endif
+
+#define UseDBMalloc NO
+
+#if UseDBMalloc
+SYS_LIBRARIES=-ldbmalloc
+DBMALLOCDEFINE=-DDBMALLOC
+#endif
+
+#if defined(OS2Architecture)
+LOCAL_LIBRARIES=-lxf86_os
+#else
+LOCAL_LIBRARIES=
+#endif
+SYS_LIBRARIES = MathLibrary
+
+XCONFIGFILE = XConfigFile
+XCONFIGDIR = XConfigDir
+
+INCLUDES = -I. -I$(XF86OSSRC)
+
+DEFINES = $(INPUTDEFS)
+
+HEADERS = xf86Parser.h xf86Optrec.h
+
+SRCS = Device.c Files.c Flags.c Input.c Keyboard.c Layout.c Module.c \
+ Video.c Monitor.c Pointer.c Screen.c Vendor.c read.c scan.c write.c
+OBJS = Device.o Files.o Flags.o Input.o Keyboard.o Layout.o Module.o \
+ Video.o Monitor.o Pointer.o Screen.o Vendor.o read.o scan.o write.o \
+ DRI.o
+
+CONFIG_DEFINES = -DXCONFIGDIR=\"$(XCONFIGDIR)\" -DXCONFIGFILE=\"$(XCONFIGFILE)\"
+
+#include <Library.tmpl>
+
+SpecialCObjectRule(scan,NullParameter,$(CONFIG_DEFINES) $(MODULEDEFINES) $(EXT_DEFINES))
+
+NormalProgramTarget(cpconfig,cpconfig.o $(OBJS),NullParameter,$(LOCAL_LIBRARIES),NullParameter)
+
+AllTarget(ProgramTargetName(cpconfig))
+DependTarget()
diff --git a/xc/programs/Xserver/hw/xfree86/parser/Input.c b/xc/programs/Xserver/hw/xfree86/parser/Input.c
new file mode 100644
index 000000000..d63416915
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/Input.c
@@ -0,0 +1,199 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/Input.c,v 1.3 1999/05/30 14:04:23 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/* View/edit this file with tab stops set to 4 */
+
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+
+extern LexRec val;
+
+static
+xf86ConfigSymTabRec InputTab[] =
+{
+ {ENDSECTION, "endsection"},
+ {IDENTIFIER, "identifier"},
+ {OPTION, "option"},
+ {DRIVER, "driver"},
+ {-1, ""},
+};
+
+#define CLEANUP freeInputList
+
+XF86ConfInputPtr
+parseInputSection (void)
+{
+ int has_ident = FALSE;
+ parsePrologue (XF86ConfInputPtr, XF86ConfInputRec)
+
+ while ((token = xf86GetToken (InputTab)) != ENDSECTION)
+ {
+ switch (token)
+ {
+ case IDENTIFIER:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Identifier");
+ ptr->inp_identifier = val.str;
+ has_ident = TRUE;
+ break;
+ case DRIVER:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Driver");
+ ptr->inp_driver = val.str;
+ break;
+ case OPTION:
+ {
+ char *name;
+ if ((token = xf86GetToken (NULL)) != STRING)
+ Error (BAD_OPTION_MSG, NULL);
+ name = val.str;
+ if ((token = xf86GetToken (NULL)) == STRING)
+ {
+ ptr->inp_option_lst = addNewOption (ptr->inp_option_lst,
+ name, val.str);
+ }
+ else
+ {
+ ptr->inp_option_lst = addNewOption (ptr->inp_option_lst,
+ name, NULL);
+ xf86UnGetToken (token);
+ }
+ }
+ break;
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ }
+
+ if (!has_ident)
+ Error (NO_IDENT_MSG, NULL);
+
+#ifdef DEBUG
+ printf ("InputDevice section parsed\n");
+#endif
+
+ return ptr;
+}
+
+#undef CLEANUP
+
+void
+printInputSection (FILE * cf, XF86ConfInputPtr ptr)
+{
+ XF86OptionPtr optr;
+
+ while (ptr)
+ {
+ fprintf (cf, "Section \"InputDevice\"\n");
+ if (ptr->inp_identifier)
+ fprintf (cf, "\tIdentifier \"%s\"\n", ptr->inp_identifier);
+ if (ptr->inp_driver)
+ fprintf (cf, "\tDriver \"%s\"\n", ptr->inp_driver);
+ for (optr = ptr->inp_option_lst; optr; optr = optr->list.next)
+ {
+ fprintf (cf, "\tOption \"%s\"", optr->opt_name);
+ if (optr->opt_val)
+ fprintf (cf, " \"%s\"", optr->opt_val);
+ fprintf (cf, "\n");
+ }
+ fprintf (cf, "EndSection\n\n");
+ ptr = ptr->list.next;
+ }
+}
+
+void
+freeInputList (XF86ConfInputPtr ptr)
+{
+ XF86ConfInputPtr prev;
+
+ while (ptr)
+ {
+ TestFree (ptr->inp_identifier);
+ TestFree (ptr->inp_driver);
+ OptionListFree (ptr->inp_option_lst);
+
+ prev = ptr;
+ ptr = ptr->list.next;
+ xf86conffree (prev);
+ }
+}
+
+int
+validateInput (XF86ConfigPtr p)
+{
+ XF86ConfInputPtr input = p->conf_input_lst;
+
+#if 0 /* Enable this later */
+ if (!input) {
+ xf86ValidationError ("At least one InputDevice section is required.");
+ return (FALSE);
+ }
+#endif
+
+ while (input) {
+ if (!input->inp_driver) {
+ xf86ValidationError (UNDEFINED_INPUTDRIVER_MSG, input->inp_identifier);
+ return (FALSE);
+ }
+ input = input->list.next;
+ }
+ return (TRUE);
+}
+
+XF86ConfInputPtr
+xf86FindInput (const char *ident, XF86ConfInputPtr p)
+{
+ while (p)
+ {
+ if (NameCompare (ident, p->inp_identifier) == 0)
+ return (p);
+
+ p = p->list.next;
+ }
+ return (NULL);
+}
+
+XF86ConfInputPtr
+xf86FindInputByDriver (const char *driver, XF86ConfInputPtr p)
+{
+ while (p)
+ {
+ if (NameCompare (driver, p->inp_driver) == 0)
+ return (p);
+
+ p = p->list.next;
+ }
+ return (NULL);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/parser/Keyboard.c b/xc/programs/Xserver/hw/xfree86/parser/Keyboard.c
new file mode 100644
index 000000000..4bb912117
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/Keyboard.c
@@ -0,0 +1,492 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/Keyboard.c,v 1.8 1999/05/30 14:04:23 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/* View/edit this file with tab stops set to 4 */
+
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+#include "ctype.h"
+
+extern LexRec val;
+
+static xf86ConfigSymTabRec KeyboardTab[] =
+{
+ {ENDSECTION, "endsection"},
+ {KPROTOCOL, "protocol"},
+ {AUTOREPEAT, "autorepeat"},
+ {XLEDS, "xleds"},
+ {PANIX106, "panix106"},
+ {XKBKEYMAP, "xkbkeymap"},
+ {XKBCOMPAT, "xkbcompat"},
+ {XKBTYPES, "xkbtypes"},
+ {XKBKEYCODES, "xkbkeycodes"},
+ {XKBGEOMETRY, "xkbgeometry"},
+ {XKBSYMBOLS, "xkbsymbols"},
+ {XKBDISABLE, "xkbdisable"},
+ {XKBRULES, "xkbrules"},
+ {XKBMODEL, "xkbmodel"},
+ {XKBLAYOUT, "xkblayout"},
+ {XKBVARIANT, "xkbvariant"},
+ {XKBOPTIONS, "xkboptions"},
+ /* The next two have become ServerFlags options */
+ {VTINIT, "vtinit"},
+ {VTSYSREQ, "vtsysreq"},
+ /* Obsolete keywords */
+ {SERVERNUM, "servernumlock"},
+ {LEFTALT, "leftalt"},
+ {RIGHTALT, "rightalt"},
+ {RIGHTALT, "altgr"},
+ {SCROLLLOCK_TOK, "scrolllock"},
+ {RIGHTCTL, "rightctl"},
+ {-1, ""},
+};
+
+/* Obsolete */
+static xf86ConfigSymTabRec KeyMapTab[] =
+{
+ {CONF_KM_META, "meta"},
+ {CONF_KM_COMPOSE, "compose"},
+ {CONF_KM_MODESHIFT, "modeshift"},
+ {CONF_KM_MODELOCK, "modelock"},
+ {CONF_KM_SCROLLLOCK, "scrolllock"},
+ {CONF_KM_CONTROL, "control"},
+ {-1, ""},
+};
+
+#ifndef NEW_INPUT
+
+#define CLEANUP freeKeyboard
+
+XF86ConfKeyboardPtr
+parseKeyboardSection (void)
+{
+ int ntoken;
+ parsePrologue (XF86ConfKeyboardPtr, XF86ConfKeyboardRec)
+
+ while ((token = xf86GetToken (KeyboardTab)) != ENDSECTION)
+ {
+ switch (token)
+ {
+ case KPROTOCOL:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Protocol");
+ ptr->keyb_protocol = val.str;
+ break;
+ case AUTOREPEAT:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (AUTOREPEAT_MSG, NULL);
+ ptr->keyb_kbdDelay = val.num;
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (AUTOREPEAT_MSG, NULL);
+ ptr->keyb_kbdRate = val.num;
+ break;
+ case XLEDS:
+ while ((token = xf86GetToken (NULL)) == NUMBER)
+ ptr->keyb_xleds |= 1L << (val.num - 1);
+ xf86UnGetToken (token);
+ break;
+ case SERVERNUM:
+ xf86ParseWarning(OBSOLETE_MSG, xf86TokenString());
+ break;
+ case LEFTALT:
+ case RIGHTALT:
+ case SCROLLLOCK_TOK:
+ case RIGHTCTL:
+ xf86ParseWarning(OBSOLETE_MSG, xf86TokenString());
+ break;
+ ntoken = xf86GetToken (KeyMapTab);
+ switch (ntoken)
+ {
+ case EOF_TOKEN:
+ xf86ParseError (UNEXPECTED_EOF_MSG);
+ CLEANUP (ptr);
+ return (NULL);
+ break;
+
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ break;
+ case VTINIT:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "VTInit");
+ xf86ParseWarning(MOVED_TO_FLAGS_MSG, "VTInit");
+ break;
+ case VTSYSREQ:
+ xf86ParseWarning(MOVED_TO_FLAGS_MSG, "VTSysReq");
+ break;
+ case XKBDISABLE:
+ ptr->keyb_xkbDisable = TRUE;
+ break;
+ case XKBKEYMAP:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBKeymap");
+ ptr->keyb_xkbkeymap = val.str;
+ break;
+ case XKBCOMPAT:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBCompat");
+ ptr->keyb_xkbcompat = val.str;
+ break;
+ case XKBTYPES:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBTypes");
+ ptr->keyb_xkbtypes = val.str;
+ break;
+ case XKBKEYCODES:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBKeycodes");
+ ptr->keyb_xkbkeycodes = val.str;
+ break;
+ case XKBGEOMETRY:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBGeometry");
+ ptr->keyb_xkbgeometry = val.str;
+ break;
+ case XKBSYMBOLS:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBSymbols");
+ ptr->keyb_xkbsymbols = val.str;
+ break;
+ case XKBRULES:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBRules");
+ ptr->keyb_xkbrules = val.str;
+ break;
+ case XKBMODEL:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBModel");
+ ptr->keyb_xkbmodel = val.str;
+ break;
+ case XKBLAYOUT:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBLayout");
+ ptr->keyb_xkblayout = val.str;
+ break;
+ case XKBVARIANT:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBVariant");
+ ptr->keyb_xkbvariant = val.str;
+ break;
+ case XKBOPTIONS:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBOptions");
+ ptr->keyb_xkboptions = val.str;
+ break;
+ case PANIX106:
+ ptr->keyb_panix106 = TRUE;
+ break;
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ }
+
+#ifdef DEBUG
+ printf ("Keyboard section parsed\n");
+#endif
+
+ return ptr;
+}
+
+#undef CLEANUP
+
+void
+printKeyboardSection (FILE * cf, XF86ConfKeyboardPtr ptr)
+{
+ int i;
+
+ if (ptr == NULL)
+ return;
+
+ if (ptr->keyb_protocol)
+ fprintf (cf, "\tProtocol \"%s\"\n", ptr->keyb_protocol);
+ if (ptr->keyb_kbdDelay || ptr->keyb_kbdRate)
+ fprintf (cf, "\tAutoRepeat %d %d\n", ptr->keyb_kbdDelay,
+ ptr->keyb_kbdRate);
+ if (ptr->keyb_xleds) {
+ fprintf (cf, "\tXLeds ");
+ for (i = 1; i < 8*sizeof(ptr->keyb_xleds); i++)
+ if (ptr->keyb_xleds & (1L << (i-1)))
+ fprintf(cf, " %d", i);
+ fprintf (cf, "\n");
+ }
+
+ if (ptr->keyb_xkbDisable)
+ fprintf (cf, "\tXkbDisable\n");
+ if (ptr->keyb_xkbkeycodes)
+ fprintf (cf, "\tXkbKeycodes \"%s\"\n", ptr->keyb_xkbkeycodes);
+ if (ptr->keyb_xkbtypes)
+ fprintf (cf, "\tXkbTypes \"%s\"\n", ptr->keyb_xkbtypes);
+ if (ptr->keyb_xkbcompat)
+ fprintf (cf, "\tXkbCompat \"%s\"\n", ptr->keyb_xkbcompat);
+ if (ptr->keyb_xkbsymbols)
+ fprintf (cf, "\tXkbSymbols \"%s\"\n", ptr->keyb_xkbsymbols);
+ if (ptr->keyb_xkbgeometry)
+ fprintf (cf, "\tXkbGeometry \"%s\"\n", ptr->keyb_xkbgeometry);
+ if (ptr->keyb_xkbkeymap)
+ fprintf (cf, "\tXkbKeymap \"%s\"\n", ptr->keyb_xkbkeymap);
+ if (ptr->keyb_xkbrules)
+ fprintf (cf, "\tXkbRules \"%s\"\n", ptr->keyb_xkbrules);
+ if (ptr->keyb_xkbmodel)
+ fprintf (cf, "\tXkbModel \"%s\"\n", ptr->keyb_xkbmodel);
+ if (ptr->keyb_xkblayout)
+ fprintf (cf, "\tXkbLayout \"%s\"\n", ptr->keyb_xkblayout);
+ if (ptr->keyb_xkbvariant)
+ fprintf (cf, "\tXkbVariant \"%s\"\n", ptr->keyb_xkbvariant);
+ if (ptr->keyb_xkboptions)
+ fprintf (cf, "\tXkbOptions \"%s\"\n", ptr->keyb_xkboptions);
+ if (ptr->keyb_panix106)
+ fprintf (cf, "\tPanix106\n");
+
+}
+
+void
+freeKeyboard (XF86ConfKeyboardPtr ptr)
+{
+ if (ptr == NULL)
+ return;
+
+ TestFree (ptr->keyb_protocol);
+ TestFree (ptr->keyb_xkbkeymap);
+ TestFree (ptr->keyb_xkbkeymap);
+ TestFree (ptr->keyb_xkbcompat);
+ TestFree (ptr->keyb_xkbtypes);
+ TestFree (ptr->keyb_xkbkeycodes);
+ TestFree (ptr->keyb_xkbgeometry);
+ TestFree (ptr->keyb_xkbsymbols);
+ TestFree (ptr->keyb_xkbrules);
+ TestFree (ptr->keyb_xkbmodel);
+ TestFree (ptr->keyb_xkblayout);
+ TestFree (ptr->keyb_xkbvariant);
+ TestFree (ptr->keyb_xkboptions);
+
+ xf86conffree (ptr);
+}
+
+#else /* NEW_INPUT */
+
+#define CLEANUP freeInputList
+
+XF86ConfInputPtr
+parseKeyboardSection (void)
+{
+ char *s, *s1, *s2;
+ int l;
+ int ntoken;
+ parsePrologue (XF86ConfInputPtr, XF86ConfInputRec)
+
+ while ((token = xf86GetToken (KeyboardTab)) != ENDSECTION)
+ {
+ switch (token)
+ {
+ case KPROTOCOL:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Protocol");
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("Protocol"),
+ val.str);
+ break;
+ case AUTOREPEAT:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (AUTOREPEAT_MSG, NULL);
+ s1 = ULongToString(val.num);
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (AUTOREPEAT_MSG, NULL);
+ s2 = ULongToString(val.num);
+ l = strlen(s1) + 1 + strlen(s2) + 1;
+ s = xf86confmalloc(l);
+ sprintf(s, "%s %s", s1, s2);
+ xf86conffree(s1);
+ xf86conffree(s2);
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("AutoRepeat"), s);
+ break;
+ case XLEDS:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (XLEDS_MSG, NULL);
+ s = ULongToString(val.num);
+ l = strlen(s) + 1;
+ while ((token = xf86GetToken (NULL)) == NUMBER)
+ {
+ s1 = ULongToString(val.num);
+ l += (1 + strlen(s1));
+ s = xf86confrealloc(s, l);
+ strcat(s, " ");
+ strcat(s, s1);
+ xf86conffree(s1);
+ }
+ xf86UnGetToken (token);
+ break;
+ case SERVERNUM:
+ xf86ParseWarning(OBSOLETE_MSG, xf86TokenString());
+ break;
+ case LEFTALT:
+ case RIGHTALT:
+ case SCROLLLOCK_TOK:
+ case RIGHTCTL:
+ xf86ParseWarning(OBSOLETE_MSG, xf86TokenString());
+ break;
+ ntoken = xf86GetToken (KeyMapTab);
+ switch (ntoken)
+ {
+ case EOF_TOKEN:
+ xf86ParseError (UNEXPECTED_EOF_MSG);
+ CLEANUP (ptr);
+ return (NULL);
+ break;
+
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ break;
+ case VTINIT:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "VTInit");
+ xf86ParseWarning(MOVED_TO_FLAGS_MSG, "VTInit");
+ break;
+ case VTSYSREQ:
+ xf86ParseWarning(MOVED_TO_FLAGS_MSG, "VTSysReq");
+ break;
+ case XKBDISABLE:
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("XkbDisable"),
+ NULL);
+ break;
+ case XKBKEYMAP:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBKeymap");
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("XkbKeymap"),
+ val.str);
+ break;
+ case XKBCOMPAT:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBCompat");
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("XkbCompat"),
+ val.str);
+ break;
+ case XKBTYPES:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBTypes");
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("XkbTypes"),
+ val.str);
+ break;
+ case XKBKEYCODES:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBKeycodes");
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("XkbKeycodes"),
+ val.str);
+ break;
+ case XKBGEOMETRY:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBGeometry");
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("XkbGeometry"),
+ val.str);
+ break;
+ case XKBSYMBOLS:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBSymbols");
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("XkbSymbols"),
+ val.str);
+ break;
+ case XKBRULES:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBRules");
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("XkbRules"),
+ val.str);
+ break;
+ case XKBMODEL:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBModel");
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("XkbModel"),
+ val.str);
+ break;
+ case XKBLAYOUT:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBLayout");
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("XkbLayout"),
+ val.str);
+ break;
+ case XKBVARIANT:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBVariant");
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("XkbVariant"),
+ val.str);
+ break;
+ case XKBOPTIONS:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "XKBOptions");
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("XkbOptions"),
+ val.str);
+ break;
+ case PANIX106:
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("Panix106"), NULL);
+ break;
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ }
+
+ ptr->inp_identifier = ConfigStrdup(CONF_IMPLICIT_KEYBOARD);
+ ptr->inp_driver = ConfigStrdup("keyboard");
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("CoreKeyboard"), NULL);
+
+#ifdef DEBUG
+ printf ("Keyboard section parsed\n");
+#endif
+
+ return ptr;
+}
+
+
+
+#endif /* NEW_INPUT */
diff --git a/xc/programs/Xserver/hw/xfree86/parser/Layout.c b/xc/programs/Xserver/hw/xfree86/parser/Layout.c
new file mode 100644
index 000000000..421765a10
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/Layout.c
@@ -0,0 +1,388 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/Layout.c,v 1.8 1999/05/30 14:04:24 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/* View/edit this file with tab stops set to 4 */
+
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+#include <string.h>
+
+extern LexRec val;
+
+static xf86ConfigSymTabRec LayoutTab[] =
+{
+ {ENDSECTION, "endsection"},
+ {SCREEN, "screen"},
+ {IDENTIFIER, "identifier"},
+ {INACTIVE, "inactive"},
+ {INPUTDEVICE, "inputdevice"},
+ {OPTION, "option"},
+ {-1, ""},
+};
+
+#define CLEANUP freeLayoutList
+
+XF86ConfLayoutPtr
+parseLayoutSection (void)
+{
+ int has_ident = FALSE;
+ parsePrologue (XF86ConfLayoutPtr, XF86ConfLayoutRec)
+
+ while ((token = xf86GetToken (LayoutTab)) != ENDSECTION)
+ {
+ switch (token)
+ {
+ case IDENTIFIER:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Identifier");
+ ptr->lay_identifier = val.str;
+ has_ident = TRUE;
+ break;
+ case INACTIVE:
+ {
+ XF86ConfInactivePtr iptr;
+
+ iptr = xf86confmalloc (sizeof (XF86ConfInactiveRec));
+ iptr->list.next = NULL;
+ if (xf86GetToken (NULL) != STRING)
+ Error (INACTIVE_MSG, NULL);
+ iptr->inactive_device_str = val.str;
+ ptr->lay_inactive_lst = (XF86ConfInactivePtr)
+ addListItem ((glp) ptr->lay_inactive_lst, (glp) iptr);
+ }
+ break;
+ case SCREEN:
+ {
+ XF86ConfAdjacencyPtr aptr;
+
+ aptr = xf86confmalloc (sizeof (XF86ConfAdjacencyRec));
+ aptr->list.next = NULL;
+ aptr->adj_scrnum = -1;
+ if ((token = xf86GetToken (NULL)) == NUMBER)
+ {
+ aptr->adj_scrnum = val.num;
+ if ((token = xf86GetToken (NULL)) != STRING)
+ Error (SCREEN_MSG, NULL);
+ }
+ else if (token != STRING)
+ Error (SCREEN_MSG, NULL);
+ aptr->adj_screen_str = val.str;
+
+ /* top */
+ if ((token = xf86GetToken (NULL)) != STRING)
+ {
+ /*
+ * if there are no other values after the
+ * first screen name assume "" "" "" ""
+ */
+ xf86UnGetToken (token);
+ aptr->adj_top_str = ConfigStrdup ("");
+ aptr->adj_bottom_str = ConfigStrdup ("");
+ aptr->adj_left_str = ConfigStrdup ("");
+ aptr->adj_right_str = ConfigStrdup ("");
+ }
+ else
+ {
+ aptr->adj_top_str = val.str;
+
+ /* bottom */
+ if (xf86GetToken (NULL) != STRING)
+ Error (SCREEN_MSG, NULL);
+ aptr->adj_bottom_str = val.str;
+
+ /* left */
+ if (xf86GetToken (NULL) != STRING)
+ Error (SCREEN_MSG, NULL);
+ aptr->adj_left_str = val.str;
+
+ /* right */
+ if (xf86GetToken (NULL) != STRING)
+ Error (SCREEN_MSG, NULL);
+ aptr->adj_right_str = val.str;
+
+ }
+ ptr->lay_adjacency_lst = (XF86ConfAdjacencyPtr)
+ addListItem ((glp) ptr->lay_adjacency_lst, (glp) aptr);
+ }
+ break;
+ case INPUTDEVICE:
+ {
+ XF86ConfInputrefPtr iptr;
+
+ iptr = xf86confmalloc (sizeof (XF86ConfInputrefRec));
+ iptr->list.next = NULL;
+ iptr->iref_option_lst = NULL;
+ if (xf86GetToken (NULL) != STRING)
+ Error (INPUTDEV_MSG, NULL);
+ iptr->iref_inputdev_str = val.str;
+ while ((token = xf86GetToken (NULL)) == STRING)
+ {
+ iptr->iref_option_lst =
+ addNewOption (iptr->iref_option_lst, val.str, NULL);
+ }
+ xf86UnGetToken (token);
+ ptr->lay_input_lst = (XF86ConfInputrefPtr)
+ addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
+ }
+ break;
+ case OPTION:
+ {
+ char *name;
+ if ((token = xf86GetToken (NULL)) != STRING)
+ Error (BAD_OPTION_MSG, NULL);
+ name = val.str;
+ if ((token = xf86GetToken (NULL)) == STRING)
+ {
+ ptr->lay_option_lst =
+ addNewOption (ptr->lay_option_lst,
+ name, val.str);
+ }
+ else
+ {
+ ptr->lay_option_lst =
+ addNewOption (ptr->lay_option_lst,
+ name, NULL);
+ xf86UnGetToken (token);
+ }
+ }
+ break;
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ }
+
+ if (!has_ident)
+ Error (NO_IDENT_MSG, NULL);
+
+#ifdef DEBUG
+ printf ("Layout section parsed\n");
+#endif
+
+ return ptr;
+}
+
+#undef CLEANUP
+
+void
+printLayoutSection (FILE * cf, XF86ConfLayoutPtr ptr)
+{
+ XF86ConfAdjacencyPtr aptr;
+ XF86ConfInactivePtr iptr;
+ XF86ConfInputrefPtr inptr;
+ XF86OptionPtr optr;
+
+ while (ptr)
+ {
+ fprintf (cf, "Section \"ServerLayout\"\n");
+ if (ptr->lay_identifier)
+ fprintf (cf, "\tIdentifier \"%s\"\n", ptr->lay_identifier);
+
+ for (aptr = ptr->lay_adjacency_lst; aptr; aptr = aptr->list.next)
+ {
+ fprintf (cf, "\tScreen \"%s\"", aptr->adj_screen_str);
+ fprintf (cf, " \"%s\"", aptr->adj_top_str);
+ fprintf (cf, " \"%s\"", aptr->adj_bottom_str);
+ fprintf (cf, " \"%s\"", aptr->adj_right_str);
+ fprintf (cf, " \"%s\"\n", aptr->adj_left_str);
+ }
+ for (iptr = ptr->lay_inactive_lst; iptr; iptr = iptr->list.next)
+ fprintf (cf, "\tInactive \"%s\"\n", iptr->inactive_device_str);
+ for (inptr = ptr->lay_input_lst; inptr; inptr = inptr->list.next)
+ {
+ fprintf (cf, "\tInputDevice \"%s\"", inptr->iref_inputdev_str);
+ for (optr = inptr->iref_option_lst; optr; optr = optr->list.next)
+ {
+ fprintf(cf, " \"%s\"", optr->opt_name);
+ }
+ fprintf(cf, "\n");
+ }
+ for (optr = ptr->lay_option_lst; optr; optr = optr->list.next)
+ {
+ fprintf (cf, "\tOption \"%s\"", optr->opt_name);
+ if (optr->opt_val)
+ fprintf (cf, " \"%s\"", optr->opt_val);
+ fprintf (cf, "\n");
+ }
+ fprintf (cf, "EndSection\n\n");
+ ptr = ptr->list.next;
+ }
+}
+
+void
+freeLayoutList (XF86ConfLayoutPtr ptr)
+{
+ XF86ConfLayoutPtr prev;
+
+ while (ptr)
+ {
+ TestFree (ptr->lay_identifier);
+ freeAdjacencyList (ptr->lay_adjacency_lst);
+ freeInputrefList (ptr->lay_input_lst);
+ prev = ptr;
+ ptr = ptr->list.next;
+ xf86conffree (prev);
+ }
+}
+
+void
+freeAdjacencyList (XF86ConfAdjacencyPtr ptr)
+{
+ XF86ConfAdjacencyPtr prev;
+
+ while (ptr)
+ {
+ TestFree (ptr->adj_screen_str);
+ TestFree (ptr->adj_top_str);
+ TestFree (ptr->adj_bottom_str);
+ TestFree (ptr->adj_left_str);
+ TestFree (ptr->adj_right_str);
+
+ prev = ptr;
+ ptr = ptr->list.next;
+ xf86conffree (prev);
+ }
+
+}
+
+void
+freeInputrefList (XF86ConfInputrefPtr ptr)
+{
+ XF86ConfInputrefPtr prev;
+
+ while (ptr)
+ {
+ TestFree (ptr->iref_inputdev_str);
+ OptionListFree (ptr->iref_option_lst);
+ prev = ptr;
+ ptr = ptr->list.next;
+ xf86conffree (prev);
+ }
+
+}
+
+#define CheckScreen(str, ptr)\
+if (str[0] != '\0') \
+{ \
+screen = xf86FindScreen (str, p->conf_screen_lst); \
+if (!screen) \
+{ \
+ xf86ValidationError (UNDEFINED_SCREEN_MSG, \
+ str, layout->lay_identifier); \
+ return (FALSE); \
+} \
+else \
+ ptr = screen; \
+}
+
+int
+validateLayout (XF86ConfigPtr p)
+{
+ XF86ConfLayoutPtr layout = p->conf_layout_lst;
+ XF86ConfAdjacencyPtr adj;
+ XF86ConfInactivePtr iptr;
+ XF86ConfInputrefPtr inptr;
+ XF86ConfScreenPtr screen;
+ XF86ConfDevicePtr device;
+ XF86ConfInputPtr input;
+
+ while (layout)
+ {
+ adj = layout->lay_adjacency_lst;
+ while (adj)
+ {
+ /* the first one can't be "" but all others can */
+ screen = xf86FindScreen (adj->adj_screen_str, p->conf_screen_lst);
+ if (!screen)
+ {
+ xf86ValidationError (UNDEFINED_SCREEN_MSG,
+ adj->adj_screen_str, layout->lay_identifier);
+ return (FALSE);
+ }
+ else
+ adj->adj_screen = screen;
+
+ CheckScreen (adj->adj_top_str, adj->adj_top);
+ CheckScreen (adj->adj_bottom_str, adj->adj_bottom);
+ CheckScreen (adj->adj_left_str, adj->adj_left);
+ CheckScreen (adj->adj_right_str, adj->adj_right);
+
+ adj = adj->list.next;
+ }
+ iptr = layout->lay_inactive_lst;
+ while (iptr)
+ {
+ device = xf86FindDevice (iptr->inactive_device_str,
+ p->conf_device_lst);
+ if (!device)
+ {
+ xf86ValidationError (UNDEFINED_DEVICE_LAY_MSG,
+ iptr->inactive_device_str, layout->lay_identifier);
+ return (FALSE);
+ }
+ else
+ iptr->inactive_device = device;
+ iptr = iptr->list.next;
+ }
+ inptr = layout->lay_input_lst;
+ while (inptr)
+ {
+ input = xf86FindInput (inptr->iref_inputdev_str,
+ p->conf_input_lst);
+ if (!input)
+ {
+ xf86ValidationError (UNDEFINED_INPUT_MSG,
+ inptr->iref_inputdev_str, layout->lay_identifier);
+ return (FALSE);
+ }
+ else
+ inptr->iref_inputdev = input;
+ inptr = inptr->list.next;
+ }
+ layout = layout->list.next;
+ }
+ return (TRUE);
+}
+
+XF86ConfLayoutPtr
+xf86FindLayout (const char *name, XF86ConfLayoutPtr list)
+{
+ while (list)
+ {
+ if (NameCompare (list->lay_identifier, name) == 0)
+ return (list);
+ list = list->list.next;
+ }
+ return (NULL);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/parser/Module.c b/xc/programs/Xserver/hw/xfree86/parser/Module.c
new file mode 100644
index 000000000..b558ca652
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/Module.c
@@ -0,0 +1,227 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/Module.c,v 1.4 1999/05/30 14:04:25 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/* View/edit this file with tab stops set to 4 */
+
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+
+extern LexRec val;
+
+static xf86ConfigSymTabRec SubModuleTab[] =
+{
+ {ENDSUBSECTION, "endsubsection"},
+ {OPTION, "option"},
+ {-1, ""},
+};
+
+static xf86ConfigSymTabRec ModuleTab[] =
+{
+ {ENDSECTION, "endsection"},
+ {LOAD, "load"},
+ {LOAD_DRIVER, "loaddriver"},
+ {SUBSECTION, "subsection"},
+ {-1, ""},
+};
+
+#define CLEANUP freeModules
+
+XF86LoadPtr
+parseModuleSubSection (XF86LoadPtr head, char *name)
+{
+ parsePrologue (XF86LoadPtr, XF86LoadRec)
+
+ ptr->load_name = name;
+ ptr->load_type = XF86_LOAD_MODULE;
+ ptr->load_opt = NULL;
+ ptr->list.next = NULL;
+
+ while ((token = xf86GetToken (SubModuleTab)) != ENDSUBSECTION)
+ {
+ switch (token)
+ {
+ case OPTION:
+ {
+ char *name;
+ if ((token = xf86GetToken (NULL)) != STRING)
+ {
+ xf86ParseError (BAD_OPTION_MSG, NULL);
+ xf86conffree(ptr);
+ return NULL;
+ }
+ name = val.str;
+ if ((token = xf86GetToken (NULL)) == STRING)
+ {
+ ptr->load_opt = addNewOption (ptr->load_opt,
+ name, val.str);
+ }
+ else
+ {
+ ptr->load_opt = addNewOption (ptr->load_opt,
+ name, NULL);
+ xf86UnGetToken (token);
+ }
+ }
+ break;
+ case EOF_TOKEN:
+ xf86ParseError (UNEXPECTED_EOF_MSG, NULL);
+ xf86conffree(ptr);
+ return NULL;
+ break;
+ default:
+ xf86ParseError (INVALID_KEYWORD_MSG, xf86TokenString ());
+ xf86conffree(ptr);
+ return NULL;
+ break;
+ }
+
+ }
+
+ return ((XF86LoadPtr) addListItem ((glp) head, (glp) ptr));
+}
+
+XF86ConfModulePtr
+parseModuleSection (void)
+{
+ parsePrologue (XF86ConfModulePtr, XF86ConfModuleRec)
+
+ while ((token = xf86GetToken (ModuleTab)) != ENDSECTION)
+ {
+ switch (token)
+ {
+ case LOAD:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Load");
+ ptr->mod_load_lst =
+ addNewLoadDirective (ptr->mod_load_lst, val.str,
+ XF86_LOAD_MODULE, NULL);
+ break;
+ case LOAD_DRIVER:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "LoadDriver");
+ ptr->mod_load_lst =
+ addNewLoadDirective (ptr->mod_load_lst, val.str,
+ XF86_LOAD_DRIVER, NULL);
+ break;
+ case SUBSECTION:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "SubSection");
+ ptr->mod_load_lst =
+ parseModuleSubSection (ptr->mod_load_lst, val.str);
+ break;
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ }
+
+#ifdef DEBUG
+ printf ("Module section parsed\n");
+#endif
+
+ return ptr;
+}
+
+#undef CLEANUP
+
+void
+printModuleSection (FILE * cf, XF86ConfModulePtr ptr)
+{
+ XF86LoadPtr lptr;
+
+ if (ptr == NULL)
+ return;
+
+ for (lptr = ptr->mod_load_lst; lptr; lptr = lptr->list.next)
+ {
+ switch (lptr->load_type)
+ {
+ case XF86_LOAD_MODULE:
+ if( lptr->load_opt == NULL )
+ fprintf (cf, "\tLoad \"%s\"\n", lptr->load_name);
+ else
+ {
+ XF86OptionPtr optr;
+ fprintf (cf, "\tSubSection \"%s\"\n", lptr->load_name);
+ for(optr=lptr->load_opt;optr;optr=optr->list.next)
+ {
+ fprintf (cf, "\t\tOption \"%s\"", optr->opt_name);
+ if( optr->opt_val)
+ fprintf (cf, " \"%s\"", optr->opt_val);
+ fprintf (cf, "\n" );
+ }
+ fprintf (cf, "\tEndSubSection\n");
+ }
+ break;
+ case XF86_LOAD_DRIVER:
+ fprintf (cf, "\tLoadDriver \"%s\"\n", lptr->load_name);
+ break;
+ default:
+ fprintf (cf, "#\tUnknown type \"%s\"\n", lptr->load_name);
+ break;
+ }
+ }
+}
+
+XF86LoadPtr
+addNewLoadDirective (XF86LoadPtr head, char *name, int type, XF86OptionPtr opts)
+{
+ XF86LoadPtr new;
+
+ new = xf86confmalloc (sizeof (XF86LoadRec));
+ new->load_name = name;
+ new->load_type = type;
+ new->load_opt = opts;
+ new->list.next = NULL;
+
+ return ((XF86LoadPtr) addListItem ((glp) head, (glp) new));
+}
+
+void
+freeModules (XF86ConfModulePtr ptr)
+{
+ XF86LoadPtr lptr;
+ XF86LoadPtr prev;
+
+ if (ptr == NULL)
+ return;
+ lptr = ptr->mod_load_lst;
+ while (lptr)
+ {
+ TestFree (lptr->load_name);
+ prev = lptr;
+ lptr = lptr->list.next;
+ xf86conffree (prev);
+ }
+ xf86conffree (ptr);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/parser/Monitor.c b/xc/programs/Xserver/hw/xfree86/parser/Monitor.c
new file mode 100644
index 000000000..b72d692e4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/Monitor.c
@@ -0,0 +1,859 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/Monitor.c,v 1.10 1999/05/30 14:04:25 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/* View/edit this file with tab stops set to 4 */
+
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+
+extern LexRec val;
+
+static xf86ConfigSymTabRec MonitorTab[] =
+{
+ {ENDSECTION, "endsection"},
+ {IDENTIFIER, "identifier"},
+ {VENDOR, "vendorname"},
+ {MODEL, "modelname"},
+ {USEMODES, "usemodes"},
+ {MODELINE, "modeline"},
+ {DISPLAYSIZE, "displaysize"},
+ {HORIZSYNC, "horizsync"},
+ {VERTREFRESH, "vertrefresh"},
+ {MODE, "mode"},
+ {GAMMA, "gamma"},
+ {OPTION, "option"},
+ {-1, ""},
+};
+
+static xf86ConfigSymTabRec ModesTab[] =
+{
+ {ENDSECTION, "endsection"},
+ {IDENTIFIER, "identifier"},
+ {MODELINE, "modeline"},
+ {MODE, "mode"},
+ {-1, ""},
+};
+
+static xf86ConfigSymTabRec TimingTab[] =
+{
+ {TT_INTERLACE, "interlace"},
+ {TT_PHSYNC, "+hsync"},
+ {TT_NHSYNC, "-hsync"},
+ {TT_PVSYNC, "+vsync"},
+ {TT_NVSYNC, "-vsync"},
+ {TT_CSYNC, "composite"},
+ {TT_PCSYNC, "+csync"},
+ {TT_NCSYNC, "-csync"},
+ {TT_DBLSCAN, "doublescan"},
+ {TT_HSKEW, "hskew"},
+ {TT_VSCAN, "vscan"},
+ {TT_CUSTOM, "CUSTOM"},
+ {-1, ""},
+};
+
+static xf86ConfigSymTabRec ModeTab[] =
+{
+ {DOTCLOCK, "dotclock"},
+ {HTIMINGS, "htimings"},
+ {VTIMINGS, "vtimings"},
+ {FLAGS, "flags"},
+ {HSKEW, "hskew"},
+ {VSCAN, "vscan"},
+ {ENDMODE, "endmode"},
+ {-1, ""},
+};
+
+#define CLEANUP freeModeLineList
+
+XF86ConfModeLinePtr
+parseModeLine (void)
+{
+ parsePrologue (XF86ConfModeLinePtr, XF86ConfModeLineRec)
+
+ /* Identifier */
+ if (xf86GetToken (NULL) != STRING)
+ Error ("ModeLine identifier expected", NULL);
+ ptr->ml_identifier = val.str;
+
+ /* DotClock */
+ if (xf86GetToken (NULL) != NUMBER)
+ Error ("ModeLine dotclock expected", NULL);
+ ptr->ml_clock = (int) (val.realnum * 1000.0 + 0.5);
+
+ /* HDisplay */
+ if (xf86GetToken (NULL) != NUMBER)
+ Error ("ModeLine Hdisplay expected", NULL);
+ ptr->ml_hdisplay = val.num;
+
+ /* HSyncStart */
+ if (xf86GetToken (NULL) != NUMBER)
+ Error ("ModeLine HSyncStart expected", NULL);
+ ptr->ml_hsyncstart = val.num;
+
+ /* HSyncEnd */
+ if (xf86GetToken (NULL) != NUMBER)
+ Error ("ModeLine HSyncEnd expected", NULL);
+ ptr->ml_hsyncend = val.num;
+
+ /* HTotal */
+ if (xf86GetToken (NULL) != NUMBER)
+ Error ("ModeLine HTotal expected", NULL);
+ ptr->ml_htotal = val.num;
+
+ /* VDisplay */
+ if (xf86GetToken (NULL) != NUMBER)
+ Error ("ModeLine Vdisplay expected", NULL);
+ ptr->ml_vdisplay = val.num;
+
+ /* VSyncStart */
+ if (xf86GetToken (NULL) != NUMBER)
+ Error ("ModeLine VSyncStart expected", NULL);
+ ptr->ml_vsyncstart = val.num;
+
+ /* VSyncEnd */
+ if (xf86GetToken (NULL) != NUMBER)
+ Error ("ModeLine VSyncEnd expected", NULL);
+ ptr->ml_vsyncend = val.num;
+
+ /* VTotal */
+ if (xf86GetToken (NULL) != NUMBER)
+ Error ("ModeLine VTotal expected", NULL);
+ ptr->ml_vtotal = val.num;
+
+ token = xf86GetToken (TimingTab);
+ while ((token == TT_INTERLACE) || (token == TT_PHSYNC) ||
+ (token == TT_NHSYNC) || (token == TT_PVSYNC) ||
+ (token == TT_NVSYNC) || (token == TT_CSYNC) ||
+ (token == TT_PCSYNC) || (token == TT_NCSYNC) ||
+ (token == TT_DBLSCAN) || (token == TT_HSKEW) ||
+ (token == TT_VSCAN))
+ {
+ switch (token)
+ {
+
+ case TT_INTERLACE:
+ ptr->ml_flags |= XF86CONF_INTERLACE;
+ break;
+ case TT_PHSYNC:
+ ptr->ml_flags |= XF86CONF_PHSYNC;
+ break;
+ case TT_NHSYNC:
+ ptr->ml_flags |= XF86CONF_NHSYNC;
+ break;
+ case TT_PVSYNC:
+ ptr->ml_flags |= XF86CONF_PVSYNC;
+ break;
+ case TT_NVSYNC:
+ ptr->ml_flags |= XF86CONF_NVSYNC;
+ break;
+ case TT_CSYNC:
+ ptr->ml_flags |= XF86CONF_CSYNC;
+ break;
+ case TT_PCSYNC:
+ ptr->ml_flags |= XF86CONF_PCSYNC;
+ break;
+ case TT_NCSYNC:
+ ptr->ml_flags |= XF86CONF_NCSYNC;
+ break;
+ case TT_DBLSCAN:
+ ptr->ml_flags |= XF86CONF_DBLSCAN;
+ break;
+ case TT_HSKEW:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "Hskew");
+ ptr->ml_hskew = val.num;
+ ptr->ml_flags |= XF86CONF_HSKEW;
+ break;
+ case TT_VSCAN:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "Vscan");
+ ptr->ml_vscan = val.num;
+ break;
+ case TT_CUSTOM:
+ ptr->ml_flags |= XF86CONF_CUSTOM;
+ break;
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ token = xf86GetToken (TimingTab);
+ }
+ xf86UnGetToken (token);
+
+#ifdef DEBUG
+ printf ("ModeLine parsed\n");
+#endif
+ return (ptr);
+}
+
+XF86ConfModeLinePtr
+parseVerboseMode (void)
+{
+ int token2;
+ int had_dotclock = 0, had_htimings = 0, had_vtimings = 0;
+ parsePrologue (XF86ConfModeLinePtr, XF86ConfModeLineRec)
+
+ if (xf86GetToken (NULL) != STRING)
+ Error ("Mode name expected", NULL);
+ ptr->ml_identifier = val.str;
+ while ((token = xf86GetToken (ModeTab)) != ENDMODE)
+ {
+ switch (token)
+ {
+ case DOTCLOCK:
+ if ((token = xf86GetToken (NULL)) != NUMBER)
+ Error (NUMBER_MSG, "DotClock");
+ ptr->ml_clock = (int) (val.realnum * 1000.0 + 0.5);
+ had_dotclock = 1;
+ break;
+ case HTIMINGS:
+ if (xf86GetToken (NULL) == NUMBER)
+ ptr->ml_hdisplay = val.num;
+ else
+ Error ("Horizontal display expected", NULL);
+
+ if (xf86GetToken (NULL) == NUMBER)
+ ptr->ml_hsyncstart = val.num;
+ else
+ Error ("Horizontal sync start expected", NULL);
+
+ if (xf86GetToken (NULL) == NUMBER)
+ ptr->ml_hsyncend = val.num;
+ else
+ Error ("Horizontal sync end expected", NULL);
+
+ if (xf86GetToken (NULL) == NUMBER)
+ ptr->ml_htotal = val.num;
+ else
+ Error ("Horizontal total expected", NULL);
+ had_htimings = 1;
+ break;
+ case VTIMINGS:
+ if (xf86GetToken (NULL) == NUMBER)
+ ptr->ml_vdisplay = val.num;
+ else
+ Error ("Vertical display expected", NULL);
+
+ if (xf86GetToken (NULL) == NUMBER)
+ ptr->ml_vsyncstart = val.num;
+ else
+ Error ("Vertical sync start expected", NULL);
+
+ if (xf86GetToken (NULL) == NUMBER)
+ ptr->ml_vsyncend = val.num;
+ else
+ Error ("Vertical sync end expected", NULL);
+
+ if (xf86GetToken (NULL) == NUMBER)
+ ptr->ml_vtotal = val.num;
+ else
+ Error ("Vertical total expected", NULL);
+ had_vtimings = 1;
+ break;
+ case FLAGS:
+ token = xf86GetToken (NULL);
+ if (token != STRING)
+ Error (QUOTE_MSG, "Flags");
+ while (token == STRING)
+ {
+ token2 = getStringToken (TimingTab);
+ switch (token2)
+ {
+ case TT_INTERLACE:
+ ptr->ml_flags |= XF86CONF_INTERLACE;
+ break;
+ case TT_PHSYNC:
+ ptr->ml_flags |= XF86CONF_PHSYNC;
+ break;
+ case TT_NHSYNC:
+ ptr->ml_flags |= XF86CONF_NHSYNC;
+ break;
+ case TT_PVSYNC:
+ ptr->ml_flags |= XF86CONF_PVSYNC;
+ break;
+ case TT_NVSYNC:
+ ptr->ml_flags |= XF86CONF_NVSYNC;
+ break;
+ case TT_CSYNC:
+ ptr->ml_flags |= XF86CONF_CSYNC;
+ break;
+ case TT_PCSYNC:
+ ptr->ml_flags |= XF86CONF_PCSYNC;
+ break;
+ case TT_NCSYNC:
+ ptr->ml_flags |= XF86CONF_NCSYNC;
+ break;
+ case TT_DBLSCAN:
+ ptr->ml_flags |= XF86CONF_DBLSCAN;
+ break;
+ case TT_CUSTOM:
+ ptr->ml_flags |= XF86CONF_CUSTOM;
+ break;
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error ("Unknown flag string", NULL);
+ break;
+ }
+ token = xf86GetToken (NULL);
+ }
+ xf86UnGetToken (token);
+ break;
+ case HSKEW:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error ("Horizontal skew expected", NULL);
+ ptr->ml_flags |= XF86CONF_HSKEW;
+ ptr->ml_hskew = val.num;
+ break;
+ case VSCAN:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error ("Vertical scan count expected", NULL);
+ ptr->ml_vscan = val.num;
+ break;
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error ("Unexepcted token in verbose \"Mode\" entry\n", NULL);
+ }
+ }
+ if (!had_dotclock)
+ Error ("the dotclock is missing", NULL);
+ if (!had_htimings)
+ Error ("the horizontal timings are missing", NULL);
+ if (!had_vtimings)
+ Error ("the vertical timings are missing", NULL);
+
+#ifdef DEBUG
+ printf ("Verbose Mode parsed\n");
+#endif
+ return (ptr);
+}
+
+#undef CLEANUP
+
+#define CLEANUP freeMonitorList
+
+XF86ConfMonitorPtr
+parseMonitorSection (void)
+{
+ int has_ident = FALSE;
+ parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
+
+ while ((token = xf86GetToken (MonitorTab)) != ENDSECTION)
+ {
+ switch (token)
+ {
+ case IDENTIFIER:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Identifier");
+ ptr->mon_identifier = val.str;
+ has_ident = TRUE;
+ break;
+ case VENDOR:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Vendor");
+ ptr->mon_vendor = val.str;
+ break;
+ case MODEL:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "ModelName");
+ ptr->mon_modelname = val.str;
+ break;
+ case MODE:
+ HANDLE_LIST (mon_modeline_lst, parseVerboseMode,
+ XF86ConfModeLinePtr);
+ break;
+ case MODELINE:
+ HANDLE_LIST (mon_modeline_lst, parseModeLine,
+ XF86ConfModeLinePtr);
+ break;
+ case DISPLAYSIZE:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (DISPLAYSIZE_MSG, NULL);
+ ptr->mon_width = val.realnum;
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (DISPLAYSIZE_MSG, NULL);
+ ptr->mon_height = val.realnum;
+ break;
+
+ case HORIZSYNC:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (HORIZSYNC_MSG, NULL);
+ ptr->mon_hsync[ptr->mon_n_hsync].lo = val.realnum;
+ if (xf86GetToken (NULL) == DASH)
+ {
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (HORIZSYNC_MSG, NULL);
+ ptr->mon_hsync[ptr->mon_n_hsync].hi = val.realnum;
+ }
+ else
+ {
+ xf86UnGetToken (token);
+ ptr->mon_hsync[ptr->mon_n_hsync].hi =
+ ptr->mon_hsync[ptr->mon_n_hsync].lo;
+ }
+ ptr->mon_n_hsync++;
+ while ((token = xf86GetToken (NULL)) == COMMA)
+ {
+ if (ptr->mon_n_hsync == CONF_MAX_HSYNC)
+ Error ("Sorry. Too many horizontal sync intervals.", NULL);
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (HORIZSYNC_MSG, NULL);
+ ptr->mon_hsync[ptr->mon_n_hsync].lo = val.realnum;
+ if (xf86GetToken (NULL) == DASH)
+ {
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (HORIZSYNC_MSG, NULL);
+ ptr->mon_hsync[ptr->mon_n_hsync].hi = val.realnum;
+ }
+ else
+ {
+ xf86UnGetToken (token);
+ ptr->mon_hsync[ptr->mon_n_hsync].hi =
+ ptr->mon_hsync[ptr->mon_n_hsync].lo;
+ }
+ ptr->mon_n_hsync++;
+ }
+ xf86UnGetToken (token);
+ break;
+ case VERTREFRESH:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (VERTREFRESH_MSG, NULL);
+ ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo = val.realnum;
+ if (xf86GetToken (NULL) == DASH)
+ {
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (VERTREFRESH_MSG, NULL);
+ ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi = val.realnum;
+ }
+ else
+ {
+ xf86UnGetToken (token);
+ ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi =
+ ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo;
+ }
+ ptr->mon_n_vrefresh++;
+ while ((token = xf86GetToken (NULL)) == COMMA)
+ {
+ if (ptr->mon_n_vrefresh == CONF_MAX_HSYNC)
+ Error ("Sorry. Too many verticle refresh intervals.", NULL);
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (VERTREFRESH_MSG, NULL);
+ ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo = val.realnum;
+ if (xf86GetToken (NULL) == DASH)
+ {
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (VERTREFRESH_MSG, NULL);
+ ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi = val.realnum;
+ }
+ else
+ {
+ xf86UnGetToken (token);
+ ptr->mon_vrefresh[ptr->mon_n_vrefresh].hi =
+ ptr->mon_vrefresh[ptr->mon_n_vrefresh].lo;
+ }
+ ptr->mon_n_vrefresh++;
+ }
+ xf86UnGetToken (token);
+ break;
+ case GAMMA:
+ if( xf86GetToken (NULL) != NUMBER )
+ {
+ Error (INVALID_GAMMA_MSG, NULL);
+ }
+ else
+ {
+ ptr->mon_gamma_red = ptr->mon_gamma_green =
+ ptr->mon_gamma_blue = val.realnum;
+ if( xf86GetToken (NULL) == NUMBER )
+ {
+ ptr->mon_gamma_green = val.realnum;
+ if( xf86GetToken (NULL) == NUMBER )
+ {
+ ptr->mon_gamma_blue = val.realnum;
+ }
+ else
+ {
+ Error (INVALID_GAMMA_MSG, NULL);
+ }
+ }
+ else
+ xf86UnGetToken (token);
+ }
+ break;
+ case OPTION:
+ {
+ char *name;
+ if ((token = xf86GetToken (NULL)) != STRING)
+ Error (BAD_OPTION_MSG, NULL);
+ name = val.str;
+ if ((token = xf86GetToken (NULL)) == STRING)
+ {
+ ptr->mon_option_lst =
+ addNewOption (ptr->mon_option_lst,
+ name, val.str);
+ }
+ else
+ {
+ ptr->mon_option_lst =
+ addNewOption (ptr->mon_option_lst,
+ name, NULL);
+ xf86UnGetToken (token);
+ }
+ }
+ break;
+ case USEMODES:
+ {
+ XF86ConfModesLinkPtr mptr;
+
+ if ((token = xf86GetToken (NULL)) != STRING)
+ Error (QUOTE_MSG, "UseModes");
+
+ /* add to the end of the list of modes sections
+ referenced here */
+ mptr = xf86confmalloc (sizeof (XF86ConfModesLinkRec));
+ mptr->list.next = NULL;
+ mptr->ml_modes_str = val.str;
+ mptr->ml_modes = NULL;
+ ptr->mon_modes_sect_lst = (XF86ConfModesLinkPtr)
+ addListItem((GenericListPtr)ptr->mon_modes_sect_lst,
+ (GenericListPtr)mptr);
+ }
+ break;
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ xf86ParseError (INVALID_KEYWORD_MSG, xf86TokenString ());
+ CLEANUP (ptr);
+ return NULL;
+ break;
+ }
+ }
+
+ if (!has_ident)
+ Error (NO_IDENT_MSG, NULL);
+
+#ifdef DEBUG
+ printf ("Monitor section parsed\n");
+#endif
+ return ptr;
+}
+
+#undef CLEANUP
+#define CLEANUP freeModesList
+
+XF86ConfModesPtr
+parseModesSection (void)
+{
+ int has_ident = FALSE;
+ parsePrologue (XF86ConfModesPtr, XF86ConfModesRec)
+
+ while ((token = xf86GetToken (ModesTab)) != ENDSECTION)
+ {
+ switch (token)
+ {
+ case IDENTIFIER:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Identifier");
+ ptr->modes_identifier = val.str;
+ has_ident = TRUE;
+ break;
+ case MODE:
+ HANDLE_LIST (mon_modeline_lst, parseVerboseMode,
+ XF86ConfModeLinePtr);
+ break;
+ case MODELINE:
+ HANDLE_LIST (mon_modeline_lst, parseModeLine,
+ XF86ConfModeLinePtr);
+ break;
+ default:
+ xf86ParseError (INVALID_KEYWORD_MSG, xf86TokenString ());
+ CLEANUP (ptr);
+ return NULL;
+ break;
+ }
+ }
+
+ if (!has_ident)
+ Error (NO_IDENT_MSG, NULL);
+
+#ifdef DEBUG
+ printf ("Modes section parsed\n");
+#endif
+ return ptr;
+}
+
+#undef CLEANUP
+
+void
+printMonitorSection (FILE * cf, XF86ConfMonitorPtr ptr)
+{
+ int i;
+ XF86ConfModeLinePtr mlptr;
+ XF86OptionPtr optr;
+
+ while (ptr)
+ {
+ fprintf (cf, "Section \"Monitor\"\n");
+ if (ptr->mon_identifier)
+ fprintf (cf, "\tIdentifier \"%s\"\n", ptr->mon_identifier);
+ if (ptr->mon_vendor)
+ fprintf (cf, "\tVendorName \"%s\"\n", ptr->mon_vendor);
+ if (ptr->mon_modelname)
+ fprintf (cf, "\tModelName \"%s\"\n", ptr->mon_modelname);
+ if (ptr->mon_width)
+ fprintf (cf, "\tDisplaySize %d\t%d\n",
+ ptr->mon_width,
+ ptr->mon_height);
+ for (i = 0; i < ptr->mon_n_hsync; i++)
+ {
+ fprintf (cf, "\tHorizSync %2.1f - %2.1f\n",
+ ptr->mon_hsync[i].lo,
+ ptr->mon_hsync[i].hi);
+ }
+ for (i = 0; i < ptr->mon_n_vrefresh; i++)
+ {
+ fprintf (cf, "\tVertRefresh %2.1f - %2.1f\n",
+ ptr->mon_vrefresh[i].lo,
+ ptr->mon_vrefresh[i].hi);
+ }
+ if (ptr->mon_gamma_red) {
+ if (ptr->mon_gamma_red == ptr->mon_gamma_green
+ && ptr->mon_gamma_red == ptr->mon_gamma_blue)
+ {
+ fprintf (cf, "\tGamma %.4g\n",
+ ptr->mon_gamma_red);
+ } else {
+ fprintf (cf, "\tGamma %.4g %.4g %.4g\n",
+ ptr->mon_gamma_red,
+ ptr->mon_gamma_green,
+ ptr->mon_gamma_blue);
+ }
+ }
+ for (mlptr = ptr->mon_modeline_lst; mlptr; mlptr = mlptr->list.next)
+ {
+ fprintf (cf, "\tModeLine \"%s\" %2.1f ",
+ mlptr->ml_identifier, mlptr->ml_clock / 1000.0);
+ fprintf (cf, "%d %d %d %d %d %d %d %d",
+ mlptr->ml_hdisplay, mlptr->ml_hsyncstart,
+ mlptr->ml_hsyncend, mlptr->ml_htotal,
+ mlptr->ml_vdisplay, mlptr->ml_vsyncstart,
+ mlptr->ml_vsyncend, mlptr->ml_vtotal);
+ if (mlptr->ml_flags & XF86CONF_PHSYNC)
+ fprintf (cf, " +hsync");
+ if (mlptr->ml_flags & XF86CONF_NHSYNC)
+ fprintf (cf, " -hsync");
+ if (mlptr->ml_flags & XF86CONF_PVSYNC)
+ fprintf (cf, " +vsync");
+ if (mlptr->ml_flags & XF86CONF_NVSYNC)
+ fprintf (cf, " -vsync");
+ if (mlptr->ml_flags & XF86CONF_INTERLACE)
+ fprintf (cf, " interlace");
+ if (mlptr->ml_flags & XF86CONF_CSYNC)
+ fprintf (cf, " composite");
+ if (mlptr->ml_flags & XF86CONF_PCSYNC)
+ fprintf (cf, " +csync");
+ if (mlptr->ml_flags & XF86CONF_NCSYNC)
+ fprintf (cf, " -csync");
+ if (mlptr->ml_flags & XF86CONF_DBLSCAN)
+ fprintf (cf, " doublescan");
+ if (mlptr->ml_flags & XF86CONF_HSKEW)
+ fprintf (cf, " hskew %d", mlptr->ml_hskew);
+ fprintf (cf, "\n");
+ }
+ for (optr = ptr->mon_option_lst; optr; optr = optr->list.next)
+ {
+ fprintf (cf, "\tOption \"%s\"", optr->opt_name);
+ if (optr->opt_val)
+ fprintf (cf, " \"%s\"", optr->opt_val);
+ fprintf (cf, "\n");
+ }
+ fprintf (cf, "EndSection\n\n");
+ ptr = ptr->list.next;
+ }
+}
+
+void
+printModesSection (FILE * cf, XF86ConfModesPtr ptr)
+{
+ XF86ConfModeLinePtr mlptr;
+
+ while (ptr)
+ {
+ fprintf (cf, "Section \"Modes\"\n");
+ if (ptr->modes_identifier)
+ fprintf (cf, "\tIdentifier \"%s\"\n", ptr->modes_identifier);
+ for (mlptr = ptr->mon_modeline_lst; mlptr; mlptr = mlptr->list.next)
+ {
+ fprintf (cf, "\tModeLine \"%s\" %2.1f ",
+ mlptr->ml_identifier, mlptr->ml_clock / 1000.0);
+ fprintf (cf, "%d %d %d %d %d %d %d %d",
+ mlptr->ml_hdisplay, mlptr->ml_hsyncstart,
+ mlptr->ml_hsyncend, mlptr->ml_htotal,
+ mlptr->ml_vdisplay, mlptr->ml_vsyncstart,
+ mlptr->ml_vsyncend, mlptr->ml_vtotal);
+ if (mlptr->ml_flags & XF86CONF_PHSYNC)
+ fprintf (cf, " +hsync");
+ if (mlptr->ml_flags & XF86CONF_NHSYNC)
+ fprintf (cf, " -hsync");
+ if (mlptr->ml_flags & XF86CONF_PVSYNC)
+ fprintf (cf, " +vsync");
+ if (mlptr->ml_flags & XF86CONF_NVSYNC)
+ fprintf (cf, " -vsync");
+ if (mlptr->ml_flags & XF86CONF_INTERLACE)
+ fprintf (cf, " interlace");
+ if (mlptr->ml_flags & XF86CONF_CSYNC)
+ fprintf (cf, " composite");
+ if (mlptr->ml_flags & XF86CONF_PCSYNC)
+ fprintf (cf, " +csync");
+ if (mlptr->ml_flags & XF86CONF_NCSYNC)
+ fprintf (cf, " -csync");
+ if (mlptr->ml_flags & XF86CONF_DBLSCAN)
+ fprintf (cf, " doublescan");
+ if (mlptr->ml_flags & XF86CONF_HSKEW)
+ fprintf (cf, " hskew %d", mlptr->ml_hskew);
+ fprintf (cf, "\n");
+ }
+ fprintf (cf, "EndSection\n\n");
+ ptr = ptr->list.next;
+ }
+}
+
+void
+freeMonitorList (XF86ConfMonitorPtr ptr)
+{
+ XF86ConfMonitorPtr prev;
+
+ while (ptr)
+ {
+ TestFree (ptr->mon_identifier);
+ TestFree (ptr->mon_vendor);
+ TestFree (ptr->mon_modelname);
+ OptionListFree (ptr->mon_option_lst);
+ freeModeLineList (ptr->mon_modeline_lst);
+ prev = ptr;
+ ptr = ptr->list.next;
+ xf86conffree (prev);
+ }
+}
+
+void
+freeModesList (XF86ConfModesPtr ptr)
+{
+ XF86ConfModesPtr prev;
+
+ while (ptr)
+ {
+ TestFree (ptr->modes_identifier);
+ freeModeLineList (ptr->mon_modeline_lst);
+ prev = ptr;
+ ptr = ptr->list.next;
+ xf86conffree (prev);
+ }
+}
+
+void
+freeModeLineList (XF86ConfModeLinePtr ptr)
+{
+ XF86ConfModeLinePtr prev;
+ while (ptr)
+ {
+ TestFree (ptr->ml_identifier);
+ prev = ptr;
+ ptr = ptr->list.next;
+ xf86conffree (prev);
+ }
+}
+
+XF86ConfMonitorPtr
+xf86FindMonitor (const char *ident, XF86ConfMonitorPtr p)
+{
+ while (p)
+ {
+ if (NameCompare (ident, p->mon_identifier) == 0)
+ return (p);
+
+ p = p->list.next;
+ }
+ return (NULL);
+}
+
+XF86ConfModesPtr
+xf86FindModes (const char *ident, XF86ConfModesPtr p)
+{
+ while (p)
+ {
+ if (NameCompare (ident, p->modes_identifier) == 0)
+ return (p);
+
+ p = p->list.next;
+ }
+ return (NULL);
+}
+
+XF86ConfModeLinePtr
+xf86FindModeLine (const char *ident, XF86ConfModeLinePtr p)
+{
+ while (p)
+ {
+ if (NameCompare (ident, p->ml_identifier) == 0)
+ return (p);
+
+ p = p->list.next;
+ }
+ return (NULL);
+}
+
+int
+validateMonitor (XF86ConfigPtr p, XF86ConfScreenPtr screen)
+{
+ XF86ConfMonitorPtr monitor = screen->scrn_monitor;
+ XF86ConfModesLinkPtr modeslnk = monitor->mon_modes_sect_lst;
+ XF86ConfModesPtr modes;
+ while(modeslnk)
+ {
+ modes = xf86FindModes (modeslnk->ml_modes_str, p->conf_modes_lst);
+ if (!modes)
+ {
+ xf86ValidationError (UNDEFINED_MODES_MSG,
+ modeslnk->ml_modes_str,
+ screen->scrn_identifier);
+ return (FALSE);
+ }
+ modeslnk = modeslnk->list.next;
+ }
+ return (TRUE);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/parser/Pointer.c b/xc/programs/Xserver/hw/xfree86/parser/Pointer.c
new file mode 100644
index 000000000..b4c30ce7f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/Pointer.c
@@ -0,0 +1,364 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/Pointer.c,v 1.6 1999/05/30 14:04:26 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/* View/edit this file with tab stops set to 4 */
+
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+
+extern LexRec val;
+
+static xf86ConfigSymTabRec PointerTab[] =
+{
+ {PROTOCOL, "protocol"},
+ {EMULATE3, "emulate3buttons"},
+ {EM3TIMEOUT, "emulate3timeout"},
+ {ENDSUBSECTION, "endsubsection"},
+ {ENDSECTION, "endsection"},
+ {PDEVICE, "device"},
+ {PDEVICE, "port"},
+ {BAUDRATE, "baudrate"},
+ {SAMPLERATE, "samplerate"},
+ {CLEARDTR, "cleardtr"},
+ {CLEARRTS, "clearrts"},
+ {CHORDMIDDLE, "chordmiddle"},
+ {PRESOLUTION, "resolution"},
+ {DEVICE_NAME, "devicename"},
+ {ALWAYSCORE, "alwayscore"},
+ {PBUTTONS, "buttons"},
+ {ZAXISMAPPING, "zaxismapping"},
+ {-1, ""},
+};
+
+static xf86ConfigSymTabRec ZMapTab[] =
+{
+ {XAXIS, "x"},
+ {YAXIS, "y"},
+ {-1, ""},
+};
+
+#ifndef NEW_INPUT
+
+#define CLEANUP freePointer
+
+XF86ConfPointerPtr
+parsePointerSection (void)
+{
+ parsePrologue (XF86ConfPointerPtr, XF86ConfPointerRec)
+
+ while ((token = xf86GetToken (PointerTab)) != ENDSECTION)
+ {
+ switch (token)
+ {
+ case PROTOCOL:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Protocol");
+ ptr->pntr_protocol = val.str;
+ break;
+ case PDEVICE:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Device");
+ ptr->pntr_device = val.str;
+ break;
+ case EMULATE3:
+ ptr->pntr_emulate3Buttons = TRUE;
+ break;
+ case EM3TIMEOUT:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "Emulate3Timeout");
+ ptr->pntr_emulate3Timeout = val.num;
+ break;
+ case CHORDMIDDLE:
+ ptr->pntr_chordMiddle = TRUE;
+ break;
+ case PBUTTONS:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "Buttons");
+ ptr->pntr_buttons = val.num;
+ break;
+ case BAUDRATE:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "BaudRate");
+ ptr->pntr_baudrate = val.num;
+ break;
+ case SAMPLERATE:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "SampleRate");
+ ptr->pntr_samplerate = val.num;
+ break;
+ case PRESOLUTION:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "Resolution");
+ ptr->pntr_resolution = val.num;
+ break;
+ case CLEARDTR:
+ ptr->pntr_clearDtr = TRUE;
+ break;
+ case CLEARRTS:
+ ptr->pntr_clearRts = TRUE;
+ break;
+ case ZAXISMAPPING:
+ switch (xf86GetToken(ZMapTab)) {
+ case NUMBER:
+ ptr->pntr_negativeZ = val.num;
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "ZAxisMapping");
+ ptr->pntr_positiveZ = val.num;
+ break;
+ case XAXIS:
+ ptr->pntr_positiveZ = CONF_ZAXIS_MAPTOX;
+ ptr->pntr_negativeZ = CONF_ZAXIS_MAPTOX;
+ break;
+ case YAXIS:
+ ptr->pntr_positiveZ = CONF_ZAXIS_MAPTOY;
+ ptr->pntr_negativeZ = CONF_ZAXIS_MAPTOY;
+ break;
+ default:
+ Error (NUMBER_MSG, "ZAxisMapping");
+ break;
+ }
+ break;
+ case ALWAYSCORE:
+ ptr->pntr_alwaysCore = TRUE;
+ break;
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ }
+
+#ifdef DEBUG
+ printf ("Pointer section parsed\n");
+#endif
+
+ return ptr;
+}
+
+#undef CLEANUP
+
+void
+printPointerSection (FILE * cf, XF86ConfPointerPtr ptr)
+{
+ if (ptr == NULL)
+ return;
+
+ if (ptr->pntr_protocol)
+ fprintf (cf, "\tProtocol \"%s\"\n", ptr->pntr_protocol);
+ if (ptr->pntr_device)
+ fprintf (cf, "\tDevice \"%s\"\n", ptr->pntr_device);
+ if (ptr->pntr_emulate3Buttons)
+ fprintf (cf, "\tEmulate3Buttons\n");
+ if (ptr->pntr_emulate3Timeout)
+ fprintf (cf, "\tEmulate3Timeout %d\n", ptr->pntr_emulate3Timeout);
+ if (ptr->pntr_chordMiddle)
+ fprintf (cf, "\tChordMiddle\n");
+ if (ptr->pntr_buttons)
+ fprintf (cf, "\tButtons %d\n", ptr->pntr_buttons);
+ if (ptr->pntr_baudrate)
+ fprintf (cf, "\tBaudRate %d\n", ptr->pntr_baudrate);
+ if (ptr->pntr_samplerate)
+ fprintf (cf, "\tSampleRate %d\n", ptr->pntr_samplerate);
+ if (ptr->pntr_resolution)
+ fprintf (cf, "\tResolution %d\n", ptr->pntr_resolution);
+ if (ptr->pntr_clearDtr)
+ fprintf (cf, "\tClearDTR\n");
+ if (ptr->pntr_clearRts)
+ fprintf (cf, "\tClearRTS\n");
+ switch (ptr->pntr_positiveZ) {
+ case 0:
+ break;
+ case CONF_ZAXIS_MAPTOX:
+ fprintf (cf, "\tZAxisMapping X\n");
+ break;
+ case CONF_ZAXIS_MAPTOY:
+ fprintf (cf, "\tZAxisMapping Y\n");
+ break;
+ default:
+ fprintf (cf, "\tZAxisMapping %d %d\n",
+ ptr->pntr_negativeZ, ptr->pntr_positiveZ);
+ break;
+ }
+ if (ptr->pntr_alwaysCore)
+ fprintf (cf, "\tAlwaysCore\n");
+}
+
+void
+freePointer (XF86ConfPointerPtr ptr)
+{
+ if (ptr == NULL)
+ return;
+
+ TestFree (ptr->pntr_protocol);
+ TestFree (ptr->pntr_device);
+
+ xf86conffree (ptr);
+}
+
+#else /* NEW_INPUT */
+
+#define CLEANUP freeInputList
+
+XF86ConfInputPtr
+parsePointerSection (void)
+{
+ char *s, *s1, *s2;
+ int l;
+ parsePrologue (XF86ConfInputPtr, XF86ConfInputRec)
+
+ while ((token = xf86GetToken (PointerTab)) != ENDSECTION)
+ {
+ switch (token)
+ {
+ case PROTOCOL:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Protocol");
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("Protocol"),
+ val.str);
+ break;
+ case PDEVICE:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Device");
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("Device"),
+ val.str);
+ break;
+ case EMULATE3:
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("Emulate3Buttons"),
+ NULL);
+ break;
+ case EM3TIMEOUT:
+ if (xf86GetToken (NULL) != NUMBER || val.num < 0)
+ Error (POSITIVE_INT_MSG, "Emulate3Timeout");
+ s = ULongToString(val.num);
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("Emulate3Timeout"),
+ s);
+ break;
+ case CHORDMIDDLE:
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("ChordMiddle"),
+ NULL);
+ break;
+ case PBUTTONS:
+ if (xf86GetToken (NULL) != NUMBER || val.num < 0)
+ Error (POSITIVE_INT_MSG, "Buttons");
+ s = ULongToString(val.num);
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("Buttons"), s);
+ break;
+ case BAUDRATE:
+ if (xf86GetToken (NULL) != NUMBER || val.num < 0)
+ Error (POSITIVE_INT_MSG, "BaudRate");
+ s = ULongToString(val.num);
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("BaudRate"), s);
+ break;
+ case SAMPLERATE:
+ if (xf86GetToken (NULL) != NUMBER || val.num < 0)
+ Error (POSITIVE_INT_MSG, "SampleRate");
+ s = ULongToString(val.num);
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("SampleRate"), s);
+ break;
+ case PRESOLUTION:
+ if (xf86GetToken (NULL) != NUMBER || val.num < 0)
+ Error (POSITIVE_INT_MSG, "Resolution");
+ s = ULongToString(val.num);
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("Resolution"), s);
+ break;
+ case CLEARDTR:
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("ClearDTR"), NULL);
+ break;
+ case CLEARRTS:
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("ClearRTS"), NULL);
+ break;
+ case ZAXISMAPPING:
+ switch (xf86GetToken(ZMapTab)) {
+ case NUMBER:
+ if (val.num < 0)
+ Error (ZAXISMAPPING_MSG, NULL);
+ s1 = ULongToString(val.num);
+ if (xf86GetToken (NULL) != NUMBER || val.num < 0)
+ Error (ZAXISMAPPING_MSG, NULL);
+ s2 = ULongToString(val.num);
+ l = strlen(s1) + 1 + strlen(s2) + 1;
+ s = xf86confmalloc(l);
+ sprintf(s, "%s %s", s1, s2);
+ xf86conffree(s1);
+ xf86conffree(s2);
+ break;
+ case XAXIS:
+ s = ConfigStrdup("x");
+ break;
+ case YAXIS:
+ s = ConfigStrdup("y");
+ break;
+ default:
+ Error (ZAXISMAPPING_MSG, NULL);
+ break;
+ }
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("ZAxisMapping"),
+ s);
+ break;
+ case ALWAYSCORE:
+ break;
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ }
+
+ ptr->inp_identifier = ConfigStrdup(CONF_IMPLICIT_POINTER);
+ ptr->inp_driver = ConfigStrdup("mouse");
+ ptr->inp_option_lst = addNewOption(ptr->inp_option_lst,
+ ConfigStrdup("CorePointer"), NULL);
+
+#ifdef DEBUG
+ printf ("Pointer section parsed\n");
+#endif
+
+ return ptr;
+}
+
+#undef CLEANUP
+
+#endif /* NEW_INPUT */
diff --git a/xc/programs/Xserver/hw/xfree86/parser/Screen.c b/xc/programs/Xserver/hw/xfree86/parser/Screen.c
new file mode 100644
index 000000000..8a4028e5f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/Screen.c
@@ -0,0 +1,573 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/Screen.c,v 1.9 1999/05/30 14:04:26 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/* View/edit this file with tab stops set to 4 */
+
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+
+extern LexRec val;
+
+static xf86ConfigSymTabRec DisplayTab[] =
+{
+ {ENDSUBSECTION, "endsubsection"},
+ {MODES, "modes"},
+ {VIEWPORT, "viewport"},
+ {VIRTUAL, "virtual"},
+ {VISUAL, "visual"},
+ {BLACK_TOK, "black"},
+ {WHITE_TOK, "white"},
+ {DEPTH, "depth"},
+ {BPP, "fbbpp"},
+ {WEIGHT, "weight"},
+ {OPTION, "option"},
+ {-1, ""},
+};
+
+#define CLEANUP freeDisplayList
+
+XF86ConfDisplayPtr
+parseDisplaySubSection (void)
+{
+ parsePrologue (XF86ConfDisplayPtr, XF86ConfDisplayRec)
+
+ while ((token = xf86GetToken (DisplayTab)) != ENDSUBSECTION)
+ {
+ switch (token)
+ {
+ case VIEWPORT:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (VIEWPORT_MSG, NULL);
+ ptr->disp_frameX0 = val.num;
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (VIEWPORT_MSG, NULL);
+ ptr->disp_frameY0 = val.num;
+ break;
+ case VIRTUAL:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (VIRTUAL_MSG, NULL);
+ ptr->disp_virtualX = val.num;
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (VIRTUAL_MSG, NULL);
+ ptr->disp_virtualY = val.num;
+ break;
+ case DEPTH:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "Display");
+ ptr->disp_depth = val.num;
+ break;
+ case BPP:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "Display");
+ ptr->disp_bpp = val.num;
+ break;
+ case VISUAL:
+ if (xf86GetToken (NULL) != STRING)
+ Error (NUMBER_MSG, "Display");
+ ptr->disp_visual = val.str;
+ break;
+ case WEIGHT:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (WEIGHT_MSG, NULL);
+ ptr->disp_weight.red = val.num;
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (WEIGHT_MSG, NULL);
+ ptr->disp_weight.green = val.num;
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (WEIGHT_MSG, NULL);
+ ptr->disp_weight.blue = val.num;
+ break;
+ case BLACK_TOK:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (BLACK_MSG, NULL);
+ ptr->disp_black.red = val.num;
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (BLACK_MSG, NULL);
+ ptr->disp_black.green = val.num;
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (BLACK_MSG, NULL);
+ ptr->disp_black.blue = val.num;
+ break;
+ case WHITE_TOK:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (WHITE_MSG, NULL);
+ ptr->disp_white.red = val.num;
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (WHITE_MSG, NULL);
+ ptr->disp_white.green = val.num;
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (WHITE_MSG, NULL);
+ ptr->disp_white.blue = val.num;
+ break;
+ case MODES:
+ {
+ XF86ModePtr mptr;
+
+ while ((token = xf86GetToken (DisplayTab)) == STRING)
+ {
+ mptr = xf86confmalloc (sizeof (XF86ModeRec));
+ mptr->mode_name = val.str;
+ mptr->list.next = NULL;
+ ptr->disp_mode_lst = (XF86ModePtr)
+ addListItem ((glp) ptr->disp_mode_lst, (glp) mptr);
+ }
+ xf86UnGetToken (token);
+ }
+ break;
+ case OPTION:
+ {
+ char *name;
+ if ((token = xf86GetToken (NULL)) != STRING)
+ Error (BAD_OPTION_MSG, NULL);
+ name = val.str;
+ if ((token = xf86GetToken (NULL)) == STRING)
+ {
+ ptr->disp_option_lst =
+ addNewOption (ptr->disp_option_lst,
+ name, val.str);
+ }
+ else
+ {
+ ptr->disp_option_lst =
+ addNewOption (ptr->disp_option_lst,
+ name, NULL);
+ xf86UnGetToken (token);
+ }
+ }
+ break;
+
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ }
+
+#ifdef DEBUG
+ printf ("Display subsection parsed\n");
+#endif
+
+ return ptr;
+}
+
+#undef CLEANUP
+
+static xf86ConfigSymTabRec ScreenTab[] =
+{
+ {ENDSECTION, "endsection"},
+ {IDENTIFIER, "identifier"},
+ {OBSDRIVER, "driver"},
+ {MDEVICE, "device"},
+ {MONITOR, "monitor"},
+ {VIDEOADAPTOR, "videoadaptor"},
+ {SCREENNO, "screenno"},
+ {SUBSECTION, "subsection"},
+ {DEFAULTDEPTH, "defaultcolordepth"},
+ {DEFAULTDEPTH, "defaultdepth"},
+ {DEFAULTBPP, "defaultbpp"},
+ {DEFAULTFBBPP, "defaultfbbpp"},
+ {OPTION, "option"},
+ {-1, ""},
+};
+
+#define CLEANUP freeScreenList
+XF86ConfScreenPtr
+parseScreenSection (void)
+{
+ int has_ident = FALSE;
+ int has_driver= FALSE;
+
+ parsePrologue (XF86ConfScreenPtr, XF86ConfScreenRec)
+
+ while ((token = xf86GetToken (ScreenTab)) != ENDSECTION)
+ {
+ switch (token)
+ {
+ case IDENTIFIER:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Identifier");
+ ptr->scrn_identifier = val.str;
+ if (has_ident || has_driver)
+ Error (ONLY_ONE_MSG,"Identifier or Driver");
+ has_ident = TRUE;
+ break;
+ case OBSDRIVER:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Driver");
+ ptr->scrn_obso_driver = val.str;
+ if (has_ident || has_driver)
+ Error (ONLY_ONE_MSG,"Identifier or Driver");
+ has_driver = TRUE;
+ break;
+ case DEFAULTDEPTH:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "DefaultDepth");
+ ptr->scrn_defaultdepth = val.num;
+ break;
+ case DEFAULTBPP:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "DefaultBPP");
+ ptr->scrn_defaultbpp = val.num;
+ break;
+ case DEFAULTFBBPP:
+ if (xf86GetToken (NULL) != NUMBER)
+ Error (NUMBER_MSG, "DefaultFbBPP");
+ ptr->scrn_defaultfbbpp = val.num;
+ break;
+ case MDEVICE:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Device");
+ ptr->scrn_device_str = val.str;
+ break;
+ case MONITOR:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Monitor");
+ ptr->scrn_monitor_str = val.str;
+ break;
+ case VIDEOADAPTOR:
+ {
+ XF86ConfAdaptorLinkPtr aptr;
+
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "VideoAdaptor");
+
+ /* Don't allow duplicates */
+ for (aptr = ptr->scrn_adaptor_lst; aptr;
+ aptr = (XF86ConfAdaptorLinkPtr) aptr->list.next)
+ if (NameCompare (val.str, aptr->al_adaptor_str) == 0)
+ break;
+
+ if (aptr == NULL)
+ {
+ aptr = xf86confmalloc (sizeof (XF86ConfAdaptorLinkRec));
+ aptr->list.next = NULL;
+ aptr->al_adaptor_str = val.str;
+ ptr->scrn_adaptor_lst = (XF86ConfAdaptorLinkPtr)
+ addListItem ((glp) ptr->scrn_adaptor_lst, (glp) aptr);
+ }
+ }
+ break;
+ case OPTION:
+ {
+ char *name;
+ if ((token = xf86GetToken (NULL)) != STRING)
+ Error (BAD_OPTION_MSG, NULL);
+ name = val.str;
+ if ((token = xf86GetToken (NULL)) == STRING)
+ {
+ ptr->scrn_option_lst =
+ addNewOption (ptr->scrn_option_lst,
+ name, val.str);
+ }
+ else
+ {
+ ptr->scrn_option_lst =
+ addNewOption (ptr->scrn_option_lst,
+ name, NULL);
+ xf86UnGetToken (token);
+ }
+ }
+ break;
+ case SUBSECTION:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "SubSection");
+ {
+ HANDLE_LIST (scrn_display_lst, parseDisplaySubSection,
+ XF86ConfDisplayPtr);
+ }
+ break;
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ }
+
+ if (!has_ident && !has_driver)
+ Error (NO_IDENT_MSG, NULL);
+
+#ifdef DEBUG
+ printf ("Screen section parsed\n");
+#endif
+
+ return ptr;
+}
+
+void
+printScreenSection (FILE * cf, XF86ConfScreenPtr ptr)
+{
+ XF86ConfAdaptorLinkPtr aptr;
+ XF86ConfDisplayPtr dptr;
+ XF86ModePtr mptr;
+ XF86OptionPtr optr;
+
+ while (ptr)
+ {
+ fprintf (cf, "Section \"Screen\"\n");
+ if (ptr->scrn_identifier)
+ fprintf (cf, "\tIdentifier \"%s\"\n", ptr->scrn_identifier);
+ if (ptr->scrn_obso_driver)
+ fprintf (cf, "\tDriver \"%s\"\n", ptr->scrn_obso_driver);
+ if (ptr->scrn_device_str)
+ fprintf (cf, "\tDevice \"%s\"\n", ptr->scrn_device_str);
+ if (ptr->scrn_monitor_str)
+ fprintf (cf, "\tMonitor \"%s\"\n", ptr->scrn_monitor_str);
+ if (ptr->scrn_defaultdepth)
+ fprintf (cf, "\tDefaultDepth %d\n",
+ ptr->scrn_defaultdepth);
+ if (ptr->scrn_defaultbpp)
+ fprintf (cf, "\tDefaultBPP %d\n",
+ ptr->scrn_defaultbpp);
+ if (ptr->scrn_defaultfbbpp)
+ fprintf (cf, "\tDefaultFbBPP %d\n",
+ ptr->scrn_defaultfbbpp);
+ for (optr = ptr->scrn_option_lst; optr; optr = optr->list.next)
+ {
+ fprintf (cf, "\tOption \"%s\"", optr->opt_name);
+ if (optr->opt_val)
+ fprintf (cf, " \"%s\"", optr->opt_val);
+ fprintf (cf, "\n");
+ }
+ for (aptr = ptr->scrn_adaptor_lst; aptr; aptr = aptr->list.next)
+ {
+ fprintf (cf, "\tVideoAdaptor \"%s\"\n", aptr->al_adaptor_str);
+ }
+ for (dptr = ptr->scrn_display_lst; dptr; dptr = dptr->list.next)
+ {
+ fprintf (cf, "\tSubSection \"Display\"\n");
+ if (dptr->disp_frameX0 != 0 || dptr->disp_frameY0 != 0)
+ {
+ fprintf (cf, "\t\tViewport %d %d\n",
+ dptr->disp_frameX0, dptr->disp_frameY0);
+ }
+ if (dptr->disp_virtualX != 0 || dptr->disp_virtualY != 0)
+ {
+ fprintf (cf, "\t\tVirtual %d %d\n",
+ dptr->disp_virtualX, dptr->disp_virtualY);
+ }
+ if (dptr->disp_depth)
+ {
+ fprintf (cf, "\t\tDepth %d\n", dptr->disp_depth);
+ }
+ if (dptr->disp_bpp)
+ {
+ fprintf (cf, "\t\tFbBPP %d\n", dptr->disp_bpp);
+ }
+ if (dptr->disp_visual)
+ {
+ fprintf (cf, "\t\tVisual \"%s\"\n", dptr->disp_visual);
+ }
+ if (dptr->disp_mode_lst)
+ {
+ fprintf (cf, "\t\tModes");
+ }
+ for (mptr = dptr->disp_mode_lst; mptr; mptr = mptr->list.next)
+ {
+ fprintf (cf, " \"%s\"", mptr->mode_name);
+ }
+ if (dptr->disp_mode_lst)
+ {
+ fprintf (cf, "\n");
+ }
+ for (optr = dptr->disp_option_lst; optr; optr = optr->list.next)
+ {
+ fprintf (cf, "\tOption \"%s\"", optr->opt_name);
+ if (optr->opt_val)
+ fprintf (cf, " \"%s\"", optr->opt_val);
+ fprintf (cf, "\n");
+ }
+ fprintf (cf, "\tEndSubSection\n");
+ }
+ fprintf (cf, "EndSection\n\n");
+ ptr = ptr->list.next;
+ }
+
+}
+
+void
+freeScreenList (XF86ConfScreenPtr ptr)
+{
+ XF86ConfScreenPtr prev;
+
+ while (ptr)
+ {
+ TestFree (ptr->scrn_identifier);
+ TestFree (ptr->scrn_monitor_str);
+ TestFree (ptr->scrn_device_str);
+ OptionListFree (ptr->scrn_option_lst);
+ freeAdaptorLinkList (ptr->scrn_adaptor_lst);
+ freeDisplayList (ptr->scrn_display_lst);
+ prev = ptr;
+ ptr = ptr->list.next;
+ xf86conffree (prev);
+ }
+}
+
+void
+freeAdaptorLinkList (XF86ConfAdaptorLinkPtr ptr)
+{
+ XF86ConfAdaptorLinkPtr prev;
+
+ while (ptr)
+ {
+ TestFree (ptr->al_adaptor_str);
+ prev = ptr;
+ ptr = ptr->list.next;
+ xf86conffree (prev);
+ }
+}
+
+void
+freeDisplayList (XF86ConfDisplayPtr ptr)
+{
+ XF86ConfDisplayPtr prev;
+
+ while (ptr)
+ {
+ freeModeList (ptr->disp_mode_lst);
+ OptionListFree (ptr->disp_option_lst);
+ prev = ptr;
+ ptr = ptr->list.next;
+ xf86conffree (prev);
+ }
+}
+
+void
+freeModeList (XF86ModePtr ptr)
+{
+ XF86ModePtr prev;
+
+ while (ptr)
+ {
+ TestFree (ptr->mode_name);
+ prev = ptr;
+ ptr = ptr->list.next;
+ xf86conffree (prev);
+ }
+}
+
+int
+validateScreen (XF86ConfigPtr p)
+{
+ XF86ConfScreenPtr screen = p->conf_screen_lst;
+ XF86ConfMonitorPtr monitor;
+ XF86ConfDevicePtr device;
+ XF86ConfAdaptorLinkPtr adaptor;
+
+ if (!screen)
+ {
+ xf86ValidationError ("At least one Screen section is required.");
+ return (FALSE);
+ }
+
+ while (screen)
+ {
+ if (screen->scrn_obso_driver && !screen->scrn_identifier)
+ screen->scrn_identifier = screen->scrn_obso_driver;
+
+ monitor = xf86FindMonitor (screen->scrn_monitor_str, p->conf_monitor_lst);
+ if (!monitor)
+ {
+ xf86ValidationError (UNDEFINED_MONITOR_MSG,
+ screen->scrn_monitor_str, screen->scrn_identifier);
+ return (FALSE);
+ }
+ else
+ {
+ screen->scrn_monitor = monitor;
+ if (!validateMonitor(p, screen))
+ return (FALSE);
+ }
+
+ device = xf86FindDevice (screen->scrn_device_str, p->conf_device_lst);
+ if (!device)
+ {
+ xf86ValidationError (UNDEFINED_DEVICE_MSG,
+ screen->scrn_device_str, screen->scrn_identifier);
+ return (FALSE);
+ }
+ else
+ screen->scrn_device = device;
+
+ adaptor = screen->scrn_adaptor_lst;
+ while (adaptor)
+ {
+ adaptor->al_adaptor = xf86FindVideoAdaptor (adaptor->al_adaptor_str, p->conf_videoadaptor_lst);
+ if (!adaptor->al_adaptor)
+ {
+ xf86ValidationError (UNDEFINED_ADAPTOR_MSG, adaptor->al_adaptor_str, screen->scrn_identifier);
+ return (FALSE);
+ }
+ else if (adaptor->al_adaptor->va_fwdref)
+ {
+ xf86ValidationError (ADAPTOR_REF_TWICE_MSG, adaptor->al_adaptor_str,
+ adaptor->al_adaptor->va_fwdref);
+ return (FALSE);
+ }
+
+ adaptor->al_adaptor->va_fwdref = screen->scrn_identifier;
+ adaptor = adaptor->list.next;
+ }
+
+ screen = screen->list.next;
+ }
+
+ return (TRUE);
+}
+
+XF86ConfScreenPtr
+xf86FindScreen (const char *ident, XF86ConfScreenPtr p)
+{
+ while (p)
+ {
+ if (NameCompare (ident, p->scrn_identifier) == 0)
+ return (p);
+
+ p = p->list.next;
+ }
+ return (NULL);
+}
+
+XF86ConfDisplayPtr
+xf86FindDisplay (int depth, XF86ConfDisplayPtr p)
+{
+ while (p)
+ {
+ if (depth == p->disp_depth)
+ return (p);
+
+ p = p->list.next;
+ }
+ return (NULL);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/parser/Vendor.c b/xc/programs/Xserver/hw/xfree86/parser/Vendor.c
new file mode 100644
index 000000000..15b63bc48
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/Vendor.c
@@ -0,0 +1,149 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/Vendor.c,v 1.4 1999/05/30 14:04:26 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/* View/edit this file with tab stops set to 4 */
+
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+
+extern LexRec val;
+
+static xf86ConfigSymTabRec VendorTab[] =
+{
+ {ENDSECTION, "endsection"},
+ {IDENTIFIER, "identifier"},
+ {OPTION, "option"},
+ {-1, ""},
+};
+
+#define CLEANUP freeVendorList
+
+XF86ConfVendorPtr
+parseVendorSection (void)
+{
+ int has_ident = FALSE;
+ parsePrologue (XF86ConfVendorPtr, XF86ConfVendorRec)
+
+ while ((token = xf86GetToken (VendorTab)) != ENDSECTION)
+ {
+ switch (token)
+ {
+ case IDENTIFIER:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Identifier");
+ ptr->vnd_identifier = val.str;
+ has_ident = TRUE;
+ break;
+ case OPTION:
+ {
+ char *name;
+ if ((token = xf86GetToken (NULL)) != STRING)
+ Error (BAD_OPTION_MSG, NULL);
+ name = val.str;
+ if ((token = xf86GetToken (NULL)) == STRING)
+ {
+ ptr->vnd_option_lst = addNewOption (ptr->vnd_option_lst,
+ name, val.str);
+ }
+ else
+ {
+ ptr->vnd_option_lst = addNewOption (ptr->vnd_option_lst,
+ name, NULL);
+ xf86UnGetToken (token);
+ }
+ }
+ break;
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+
+ }
+
+ if (!has_ident)
+ Error (NO_IDENT_MSG, NULL);
+
+#ifdef DEBUG
+ printf ("Vendor section parsed\n");
+#endif
+
+ return ptr;
+}
+
+#undef CLEANUP
+
+void
+printVendorSection (FILE * cf, XF86ConfVendorPtr ptr)
+{
+ XF86OptionPtr optr;
+
+ while (ptr)
+ {
+ fprintf (cf, "Section \"Vendor\"\n");
+ if (ptr->vnd_identifier)
+ fprintf (cf, "\tIdentifier \"%s\"\n", ptr->vnd_identifier);
+
+ for (optr = ptr->vnd_option_lst; optr; optr = optr->list.next)
+ {
+ fprintf (cf, "\tOption \"%s\"", optr->opt_name);
+ if (optr->opt_val)
+ fprintf (cf, " \"%s\"", optr->opt_val);
+ fprintf (cf, "\n");
+ }
+ fprintf (cf, "EndSection\n\n");
+ ptr = ptr->list.next;
+ }
+}
+
+void
+freeVendorList (XF86ConfVendorPtr p)
+{
+ if (p == NULL)
+ return;
+ TestFree (p->vnd_identifier);
+ OptionListFree (p->vnd_option_lst);
+ xf86conffree (p);
+}
+
+XF86ConfVendorPtr
+xf86FindVendor (const char *name, XF86ConfVendorPtr list)
+{
+ while (list)
+ {
+ if (NameCompare (list->vnd_identifier, name) == 0)
+ return (list);
+ list = list->list.next;
+ }
+ return (NULL);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/parser/Video.c b/xc/programs/Xserver/hw/xfree86/parser/Video.c
new file mode 100644
index 000000000..e6c7e9a8a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/Video.c
@@ -0,0 +1,293 @@
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/Video.c,v 1.3 1999/05/30 14:04:26 dawes Exp $ */
+
+/* View/edit this file with tab stops set to 4 */
+
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+
+extern LexRec val;
+
+static xf86ConfigSymTabRec VideoPortTab[] =
+{
+ {ENDSUBSECTION, "endsubsection"},
+ {IDENTIFIER, "identifier"},
+ {OPTION, "option"},
+ {-1, ""},
+};
+
+#define CLEANUP freeVideoPortList
+
+XF86ConfVideoPortPtr
+parseVideoPortSubSection (void)
+{
+ parsePrologue (XF86ConfVideoPortPtr, XF86ConfVideoPortRec)
+
+ while ((token = xf86GetToken (VideoPortTab)) != ENDSUBSECTION)
+ {
+ switch (token)
+ {
+ case IDENTIFIER:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Identifier");
+ ptr->vp_identifier = val.str;
+ break;
+ case OPTION:
+ {
+ char *name;
+ if ((token = xf86GetToken (NULL)) != STRING)
+ Error (BAD_OPTION_MSG, NULL);
+ name = val.str;
+ if ((token = xf86GetToken (NULL)) == STRING)
+ {
+ ptr->vp_option_lst =
+ addNewOption (ptr->vp_option_lst,
+ name, val.str);
+ }
+ else
+ {
+ ptr->vp_option_lst =
+ addNewOption (ptr->vp_option_lst,
+ name, NULL);
+ xf86UnGetToken (token);
+ }
+ }
+ break;
+
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ }
+
+#ifdef DEBUG
+ printf ("VideoPort subsection parsed\n");
+#endif
+
+ return ptr;
+}
+
+#undef CLEANUP
+
+static xf86ConfigSymTabRec VideoAdaptorTab[] =
+{
+ {ENDSECTION, "endsection"},
+ {IDENTIFIER, "identifier"},
+ {VENDOR, "vendorname"},
+ {BOARD, "boardname"},
+ {BUSID, "busid"},
+ {DRIVER, "driver"},
+ {OPTION, "option"},
+ {SUBSECTION, "subsection"},
+ {-1, ""},
+};
+
+#define CLEANUP freeVideoAdaptorList
+
+XF86ConfVideoAdaptorPtr
+parseVideoAdaptorSection (void)
+{
+ int has_ident = FALSE;
+
+ parsePrologue (XF86ConfVideoAdaptorPtr, XF86ConfVideoAdaptorRec)
+
+ while ((token = xf86GetToken (VideoAdaptorTab)) != ENDSECTION)
+ {
+ switch (token)
+ {
+ case IDENTIFIER:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Identifier");
+ ptr->va_identifier = val.str;
+ has_ident = TRUE;
+ break;
+ case VENDOR:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Vendor");
+ ptr->va_vendor = val.str;
+ break;
+ case BOARD:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Board");
+ ptr->va_board = val.str;
+ break;
+ case BUSID:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "BusID");
+ ptr->va_busid = val.str;
+ break;
+ case DRIVER:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "Driver");
+ ptr->va_driver = val.str;
+ break;
+ case OPTION:
+ {
+ char *name;
+ if ((token = xf86GetToken (NULL)) != STRING)
+ Error (BAD_OPTION_MSG, NULL);
+ name = val.str;
+ if ((token = xf86GetToken (NULL)) == STRING)
+ {
+ ptr->va_option_lst = addNewOption (ptr->va_option_lst,
+ name, val.str);
+ }
+ else
+ {
+ ptr->va_option_lst = addNewOption (ptr->va_option_lst,
+ name, NULL);
+ xf86UnGetToken (token);
+ }
+ }
+ break;
+ case SUBSECTION:
+ if (xf86GetToken (NULL) != STRING)
+ Error (QUOTE_MSG, "SubSection");
+ {
+ HANDLE_LIST (va_port_lst, parseVideoPortSubSection,
+ XF86ConfVideoPortPtr);
+ }
+ break;
+
+ case EOF_TOKEN:
+ Error (UNEXPECTED_EOF_MSG, NULL);
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ break;
+ }
+ }
+
+ if (!has_ident)
+ Error (NO_IDENT_MSG, NULL);
+
+#ifdef DEBUG
+ printf ("VideoAdaptor section parsed\n");
+#endif
+
+ return ptr;
+}
+
+void
+printVideoAdaptorSection (FILE * cf, XF86ConfVideoAdaptorPtr ptr)
+{
+ XF86ConfVideoPortPtr pptr;
+ XF86OptionPtr optr;
+
+ while (ptr)
+ {
+ fprintf (cf, "Section \"VideoAdaptor\"\n");
+ if (ptr->va_identifier)
+ fprintf (cf, "\tIdentifier \"%s\"\n", ptr->va_identifier);
+ if (ptr->va_vendor)
+ fprintf (cf, "\tVendorName \"%s\"\n", ptr->va_vendor);
+ if (ptr->va_board)
+ fprintf (cf, "\tBoardName \"%s\"\n", ptr->va_board);
+ if (ptr->va_busid)
+ fprintf (cf, "\tBusID \"%s\"\n", ptr->va_busid);
+ if (ptr->va_driver)
+ fprintf (cf, "\tDriver \"%s\"\n", ptr->va_driver);
+ for (optr = ptr->va_option_lst; optr; optr = optr->list.next)
+ {
+ fprintf (cf, "\tOption \"%s\"", optr->opt_name);
+ if (optr->opt_val)
+ fprintf (cf, " \"%s\"", optr->opt_val);
+ fprintf (cf, "\n");
+ }
+ for (pptr = ptr->va_port_lst; pptr; pptr = pptr->list.next)
+ {
+ fprintf (cf, "\tSubSection \"VideoPort\"\n");
+ if (pptr->vp_identifier)
+ fprintf (cf, "\tIdentifier \"%s\"\n", pptr->vp_identifier);
+ for (optr = pptr->vp_option_lst; optr; optr = optr->list.next)
+ {
+ fprintf (cf, "\tOption \"%s\"", optr->opt_name);
+ if (optr->opt_val)
+ fprintf (cf, " \"%s\"", optr->opt_val);
+ fprintf (cf, "\n");
+ }
+ fprintf (cf, "\tEndSubSection\n");
+ }
+ fprintf (cf, "EndSection\n\n");
+ ptr = ptr->list.next;
+ }
+
+}
+
+void
+freeVideoAdaptorList (XF86ConfVideoAdaptorPtr ptr)
+{
+ XF86ConfVideoAdaptorPtr prev;
+
+ while (ptr)
+ {
+ TestFree (ptr->va_identifier);
+ TestFree (ptr->va_vendor);
+ TestFree (ptr->va_board);
+ TestFree (ptr->va_busid);
+ TestFree (ptr->va_driver);
+ freeVideoPortList (ptr->va_port_lst);
+ OptionListFree (ptr->va_option_lst);
+ prev = ptr;
+ ptr = ptr->list.next;
+ xf86conffree (prev);
+ }
+}
+
+void
+freeVideoPortList (XF86ConfVideoPortPtr ptr)
+{
+ XF86ConfVideoPortPtr prev;
+
+ while (ptr)
+ {
+ TestFree (ptr->vp_identifier);
+ OptionListFree (ptr->vp_option_lst);
+ prev = ptr;
+ ptr = ptr->list.next;
+ xf86conffree (prev);
+ }
+}
+
+XF86ConfVideoAdaptorPtr
+xf86FindVideoAdaptor (const char *ident, XF86ConfVideoAdaptorPtr p)
+{
+ while (p)
+ {
+ if (NameCompare (ident, p->va_identifier) == 0)
+ return (p);
+
+ p = p->list.next;
+ }
+ return (NULL);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/parser/configProcs.h b/xc/programs/Xserver/hw/xfree86/parser/configProcs.h
new file mode 100644
index 000000000..5e7255335
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/configProcs.h
@@ -0,0 +1,103 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/configProcs.h,v 1.11 1999/06/27 14:08:31 dawes Exp $ */
+
+/* Private procs. Public procs are in xf86Parser.h and xf86Optrec.h */
+
+/* Device.c */
+XF86ConfDevicePtr parseDeviceSection(void);
+void printDeviceSection(FILE *cf, XF86ConfDevicePtr ptr);
+void freeDeviceList(XF86ConfDevicePtr ptr);
+int validateDevice(XF86ConfigPtr p);
+/* Files.c */
+XF86ConfFilesPtr parseFilesSection(void);
+void printFileSection(FILE *cf, XF86ConfFilesPtr ptr);
+void freeFiles(XF86ConfFilesPtr p);
+/* Flags.c */
+XF86ConfFlagsPtr parseFlagsSection(void);
+void printServerFlagsSection(FILE *f, XF86ConfFlagsPtr flags);
+void freeFlags(XF86ConfFlagsPtr flags);
+/* Input.c */
+XF86ConfInputPtr parseInputSection(void);
+void printInputSection(FILE *f, XF86ConfInputPtr ptr);
+void freeInputList(XF86ConfInputPtr ptr);
+int validateInput (XF86ConfigPtr p);
+/* Keyboard.c */
+#ifndef NEW_INPUT
+XF86ConfKeyboardPtr parseKeyboardSection(void);
+void printKeyboardSection(FILE *cf, XF86ConfKeyboardPtr ptr);
+void freeKeyboard(XF86ConfKeyboardPtr ptr);
+#else
+XF86ConfInputPtr parseKeyboardSection(void);
+#endif
+/* Layout.c */
+XF86ConfLayoutPtr parseLayoutSection(void);
+void printLayoutSection(FILE *cf, XF86ConfLayoutPtr ptr);
+void freeLayoutList(XF86ConfLayoutPtr ptr);
+void freeAdjacencyList(XF86ConfAdjacencyPtr ptr);
+void freeInputrefList(XF86ConfInputrefPtr ptr);
+int validateLayout(XF86ConfigPtr p);
+/* Module.c */
+XF86LoadPtr parseModuleSubSection(XF86LoadPtr head, char *name);
+XF86ConfModulePtr parseModuleSection(void);
+void printModuleSection(FILE *cf, XF86ConfModulePtr ptr);
+XF86LoadPtr addNewLoadDirective(XF86LoadPtr head, char *name, int type, XF86OptionPtr opts);
+void freeModules(XF86ConfModulePtr ptr);
+/* Monitor.c */
+XF86ConfModeLinePtr parseModeLine(void);
+XF86ConfModeLinePtr parseVerboseMode(void);
+XF86ConfMonitorPtr parseMonitorSection(void);
+XF86ConfModesPtr parseModesSection(void);
+void printMonitorSection(FILE *cf, XF86ConfMonitorPtr ptr);
+void printModesSection(FILE *cf, XF86ConfModesPtr ptr);
+void freeMonitorList(XF86ConfMonitorPtr ptr);
+void freeModesList(XF86ConfModesPtr ptr);
+void freeModeLineList(XF86ConfModeLinePtr ptr);
+int validateMonitor(XF86ConfigPtr p, XF86ConfScreenPtr screen);
+/* Pointer.c */
+#ifndef NEW_INPUT
+XF86ConfPointerPtr parsePointerSection(void);
+void printPointerSection(FILE *cf, XF86ConfPointerPtr ptr);
+void freePointer(XF86ConfPointerPtr ptr);
+#else
+XF86ConfInputPtr parsePointerSection(void);
+#endif
+/* Screen.c */
+XF86ConfDisplayPtr parseDisplaySubSection(void);
+XF86ConfScreenPtr parseScreenSection(void);
+void printScreenSection(FILE *cf, XF86ConfScreenPtr ptr);
+void freeScreenList(XF86ConfScreenPtr ptr);
+void freeAdaptorLinkList(XF86ConfAdaptorLinkPtr ptr);
+void freeDisplayList(XF86ConfDisplayPtr ptr);
+void freeModeList(XF86ModePtr ptr);
+int validateScreen(XF86ConfigPtr p);
+/* Vendor.c */
+XF86ConfVendorPtr parseVendorSection(void);
+void freeVendorList(XF86ConfVendorPtr p);
+void printVendorSection(FILE * cf, XF86ConfVendorPtr ptr);
+/* Video.c */
+XF86ConfVideoPortPtr parseVideoPortSubSection(void);
+XF86ConfVideoAdaptorPtr parseVideoAdaptorSection(void);
+void printVideoAdaptorSection(FILE *cf, XF86ConfVideoAdaptorPtr ptr);
+void freeVideoAdaptorList(XF86ConfVideoAdaptorPtr ptr);
+void freeVideoPortList(XF86ConfVideoPortPtr ptr);
+int validateConfig(XF86ConfigPtr p);
+/* scan.c */
+unsigned int StrToUL(char *str);
+int xf86GetToken(xf86ConfigSymTabRec *tab);
+void xf86UnGetToken(int token);
+char *xf86TokenString(void);
+void xf86ParseError(char *format, ...);
+void xf86ParseWarning(char *format, ...);
+void xf86ValidationError(char *format, ...);
+void SetSection(char *section);
+int getStringToken(xf86ConfigSymTabRec *tab);
+/* write.c */
+/* DRI.c */
+XF86ConfBuffersPtr parseBuffers (void);
+void freeBuffersList (XF86ConfBuffersPtr ptr);
+XF86ConfDRIPtr parseDRISection (void);
+void printDRISection (FILE * cf, XF86ConfDRIPtr ptr);
+void freeDRI (XF86ConfDRIPtr ptr);
+
+/* Externally provided functions */
+void ErrorF(const char *f, ...);
+void VErrorF(const char *f, va_list args);
diff --git a/xc/programs/Xserver/hw/xfree86/parser/cpconfig.c b/xc/programs/Xserver/hw/xfree86/parser/cpconfig.c
new file mode 100644
index 000000000..c2874f059
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/cpconfig.c
@@ -0,0 +1,118 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/cpconfig.c,v 1.5 1999/06/06 15:23:04 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/* View/edit this file with tab stops set to 4 */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include "xf86Parser.h"
+
+#ifdef MALLOC_FUNCTIONS
+void
+xfree (void *p)
+{
+ free (p);
+ return;
+}
+
+void *
+xalloc (int size)
+{
+ return malloc (size);
+}
+
+void *
+xrealloc (void *p, int size)
+{
+ return realloc (p, size);
+}
+
+#endif
+
+#define CONFPATH "%A,%R,/etc/X11/%R,%P/etc/X11/%R,%E,%F,/etc/X11/%F," \
+ "%P/etc/X11/%F,%D/%X,/etc/X11/%X,/etc/%X,%P/etc/X11/%X.%H," \
+ "%P/etc/X11/%X,%P/lib/X11/%X.%H,%P/lib/X11/%X"
+
+int
+main (int argc, char *argv[])
+{
+ const char *filename;
+ char *cmdline = NULL;
+ XF86ConfigPtr conf;
+
+ if (argc > 1)
+ {
+ cmdline = argv[1];
+ }
+ if ((filename = xf86OpenConfigFile (CONFPATH, cmdline, NULL)))
+ {
+ fprintf (stderr, "Opened %s for the config file\n", filename);
+ }
+ else
+ {
+ fprintf (stderr, "Unable to open config file\n");
+ exit (1);
+ }
+
+ if ((conf = xf86ReadConfigFile ()) == NULL)
+ {
+ fprintf (stderr, "Problem when parsing config file\n");
+ }
+ else
+ {
+ fprintf (stderr, "Config file parsed OK\n");
+ }
+ xf86CloseConfigFile ();
+
+ if (argc > 2) {
+ fprintf(stderr, "Writing config file to `%s'\n", argv[2]);
+ xf86WriteConfigFile (argv[2], conf);
+ }
+ exit(0);
+}
+
+/* Functions that the parser requires */
+
+void
+VErrorF(const char *f, va_list args)
+{
+ vfprintf(stderr, f, args);
+}
+
+void
+ErrorF(const char *f, ...)
+{
+ va_list args;
+
+ va_start(args, f);
+ vfprintf(stderr, f, args);
+ va_end(args);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/parser/read.c b/xc/programs/Xserver/hw/xfree86/parser/read.c
new file mode 100644
index 000000000..1a125d11e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/read.c
@@ -0,0 +1,235 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/read.c,v 1.10 1999/06/27 14:08:31 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/* View/edit this file with tab stops set to 4 */
+
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+
+extern LexRec val;
+
+static xf86ConfigSymTabRec TopLevelTab[] =
+{
+ {SECTION, "section"},
+ {-1, ""},
+};
+
+#define CLEANUP XF86FreeConfig
+
+XF86ConfigPtr
+xf86ReadConfigFile (void)
+{
+ int token;
+ XF86ConfigPtr ptr = NULL;
+
+ if ((ptr = xf86confmalloc (sizeof (XF86ConfigRec))) == NULL)
+ {
+ return NULL;
+ }
+ memset (ptr, 0, sizeof (XF86ConfigRec));
+
+ while ((token = xf86GetToken (TopLevelTab)) != EOF_TOKEN)
+ {
+ switch (token)
+ {
+ case SECTION:
+ if (xf86GetToken (NULL) != STRING)
+ {
+ xf86ParseError (QUOTE_MSG, "Section");
+ CLEANUP (ptr);
+ return (NULL);
+ }
+ SetSection (val.str);
+ if (NameCompare (val.str, "files") == 0)
+ {
+ HANDLE_RETURN (conf_files, parseFilesSection ());
+ }
+ else if (NameCompare (val.str, "serverflags") == 0)
+ {
+ HANDLE_RETURN (conf_flags, parseFlagsSection ());
+ }
+#ifndef NEW_INPUT
+ else if (NameCompare (val.str, "keyboard") == 0)
+ {
+ HANDLE_RETURN (conf_keyboard, parseKeyboardSection ());
+ }
+ else if (NameCompare (val.str, "pointer") == 0)
+ {
+ HANDLE_RETURN (conf_pointer, parsePointerSection ());
+ }
+#else
+ else if (NameCompare (val.str, "keyboard") == 0)
+ {
+ HANDLE_LIST (conf_input_lst, parseKeyboardSection,
+ XF86ConfInputPtr);
+ }
+ else if (NameCompare (val.str, "pointer") == 0)
+ {
+ HANDLE_LIST (conf_input_lst, parsePointerSection,
+ XF86ConfInputPtr);
+ }
+#endif
+ else if (NameCompare (val.str, "videoadaptor") == 0)
+ {
+ HANDLE_LIST (conf_videoadaptor_lst, parseVideoAdaptorSection,
+ XF86ConfVideoAdaptorPtr);
+ }
+ else if (NameCompare (val.str, "device") == 0)
+ {
+ HANDLE_LIST (conf_device_lst, parseDeviceSection,
+ XF86ConfDevicePtr);
+ }
+ else if (NameCompare (val.str, "monitor") == 0)
+ {
+ HANDLE_LIST (conf_monitor_lst, parseMonitorSection,
+ XF86ConfMonitorPtr);
+ }
+ else if (NameCompare (val.str, "modes") == 0)
+ {
+ HANDLE_LIST (conf_modes_lst, parseModesSection,
+ XF86ConfModesPtr);
+ }
+ else if (NameCompare (val.str, "screen") == 0)
+ {
+ HANDLE_LIST (conf_screen_lst, parseScreenSection,
+ XF86ConfScreenPtr);
+ }
+ else if (NameCompare(val.str, "inputdevice") == 0)
+ {
+ HANDLE_LIST (conf_input_lst, parseInputSection,
+ XF86ConfInputPtr);
+ }
+ else if (NameCompare (val.str, "module") == 0)
+ {
+ HANDLE_RETURN (conf_modules, parseModuleSection ());
+ }
+ else if (NameCompare (val.str, "serverlayout") == 0)
+ {
+ HANDLE_LIST (conf_layout_lst, parseLayoutSection,
+ XF86ConfLayoutPtr);
+ }
+ else if (NameCompare (val.str, "vendor") == 0)
+ {
+ HANDLE_LIST (conf_vendor_lst, parseVendorSection,
+ XF86ConfVendorPtr);
+ }
+ else if (NameCompare (val.str, "dri") == 0)
+ {
+ HANDLE_RETURN (conf_dri, parseDRISection ());
+ }
+ else
+ {
+ Error (INVALID_SECTION_MSG, xf86TokenString ());
+ }
+ break;
+ default:
+ Error (INVALID_KEYWORD_MSG, xf86TokenString ());
+ }
+ }
+
+ if (validateConfig (ptr))
+ return (ptr);
+ else
+ {
+ CLEANUP (ptr);
+ return (NULL);
+ }
+}
+
+#undef CLEANUP
+
+/*
+ * This function resolves name references and reports errors if the named
+ * objects cannot be found.
+ */
+int
+validateConfig (XF86ConfigPtr p)
+{
+ if (!validateDevice (p))
+ return FALSE;
+ if (!validateScreen (p))
+ return FALSE;
+ if (!validateInput (p))
+ return FALSE;
+ if (!validateLayout (p))
+ return FALSE;
+
+ return (TRUE);
+}
+
+/*
+ * adds an item to the end of the linked list. Any record whose first field
+ * is a GenericListRec can be cast to this type and used with this function.
+ * A pointer to the head of the list is returned to handle the addition of
+ * the first item.
+ */
+GenericListPtr
+addListItem (GenericListPtr head, GenericListPtr new)
+{
+ GenericListPtr p = head;
+ GenericListPtr last = NULL;
+
+ while (p)
+ {
+ last = p;
+ p = p->next;
+ }
+
+ if (last)
+ {
+ last->next = new;
+ return (head);
+ }
+ else
+ return (new);
+}
+
+void
+XF86FreeConfig (XF86ConfigPtr p)
+{
+ if (p == NULL)
+ return;
+
+ freeFiles (p->conf_files);
+ freeModules (p->conf_modules);
+ freeFlags (p->conf_flags);
+#ifndef NEW_INPUT
+ freeKeyboard (p->conf_keyboard);
+ freePointer (p->conf_pointer);
+#endif
+ freeMonitorList (p->conf_monitor_lst);
+ freeVideoAdaptorList (p->conf_videoadaptor_lst);
+ freeDeviceList (p->conf_device_lst);
+ freeScreenList (p->conf_screen_lst);
+ freeLayoutList (p->conf_layout_lst);
+ freeInputList (p->conf_input_lst);
+
+ xf86conffree (p);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/parser/scan.c b/xc/programs/Xserver/hw/xfree86/parser/scan.c
new file mode 100644
index 000000000..0a1441430
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/scan.c
@@ -0,0 +1,930 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/scan.c,v 1.8 1999/06/06 15:23:04 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/* View/edit this file with tab stops set to 4 */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+#if !defined(X_NOT_POSIX)
+#if defined(_POSIX_SOURCE)
+#include <limits.h>
+#else
+#define _POSIX_SOURCE
+#include <limits.h>
+#undef _POSIX_SOURCE
+#endif /* _POSIX_SOURCE */
+#endif /* !X_NOT_POSIX */
+#if !defined(PATH_MAX)
+#if defined(MAXPATHLEN)
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif /* MAXPATHLEN */
+#endif /* !PATH_MAX */
+
+#if !defined(MAXHOSTNAMELEN)
+#define MAXHOSTNAMELEN 32
+#endif /* !MAXHOSTNAMELEN */
+
+#include "Configint.h"
+#include "xf86tokens.h"
+
+#define CONFIG_BUF_LEN 1024
+
+static int StringToToken (char *, xf86ConfigSymTabRec *);
+
+static FILE *configFile = NULL;
+static int configStart = 0; /* start of the current token */
+static int configPos = 0; /* current readers position */
+static int configLineNo = 0; /* linenumber */
+static char *configBuf, *configRBuf; /* buffer for lines */
+static char *configPath; /* path to config file */
+static char *configSection; /* name of current section being parsed */
+static int pushToken = LOCK_TOKEN;
+LexRec val;
+
+#ifdef __EMX__
+extern char *__XOS2RedirRoot(char *path);
+#endif
+
+/*
+ * StrToUL --
+ *
+ * A portable, but restricted, version of strtoul(). It only understands
+ * hex, octal, and decimal. But it's good enough for our needs.
+ */
+unsigned int
+StrToUL (char *str)
+{
+ int base = 10;
+ char *p = str;
+ unsigned int tot = 0;
+
+ if (*p == '0')
+ {
+ p++;
+ if (*p == 'x')
+ {
+ p++;
+ base = 16;
+ }
+ else
+ base = 8;
+ }
+ while (*p)
+ {
+ if ((*p >= '0') && (*p <= ((base == 8) ? '7' : '9')))
+ {
+ tot = tot * base + (*p - '0');
+ }
+ else if ((base == 16) && (*p >= 'a') && (*p <= 'f'))
+ {
+ tot = tot * base + 10 + (*p - 'a');
+ }
+ else if ((base == 16) && (*p >= 'A') && (*p <= 'F'))
+ {
+ tot = tot * base + 10 + (*p - 'A');
+ }
+ else
+ {
+ return (tot);
+ }
+ p++;
+ }
+ return (tot);
+}
+
+/*
+ * xf86GetToken --
+ * Read next Token form the config file. Handle the global variable
+ * pushToken.
+ */
+int
+xf86GetToken (xf86ConfigSymTabRec * tab)
+{
+ int c, i;
+
+ /*
+ * First check whether pushToken has a different value than LOCK_TOKEN.
+ * In this case rBuf[] contains a valid STRING/TOKEN/NUMBER. But in the
+ * oth * case the next token must be read from the input.
+ */
+ if (pushToken == EOF_TOKEN)
+ return (EOF_TOKEN);
+ else if (pushToken == LOCK_TOKEN)
+ {
+
+ c = configBuf[configPos];
+
+ /*
+ * Get start of next Token. EOF is handled,
+ * whitespaces & comments are* skipped.
+ */
+ do
+ {
+ if (!c)
+ {
+ if (fgets (configBuf, CONFIG_BUF_LEN - 1, configFile) == NULL)
+ {
+ return (pushToken = EOF_TOKEN);
+ }
+ configLineNo++;
+ configStart = configPos = 0;
+ }
+#ifndef __EMX__
+ while (((c = configBuf[configPos++]) == ' ') || (c == '\t') || (c == '\n'));
+#else
+ while (((c = configBuf[configPos++]) == ' ') || (c == '\t') || (c == '\n')
+ || (c == '\r'));
+#endif
+ if (c == '#')
+ c = '\0';
+ }
+ while (!c);
+
+ /* GJA -- handle '-' and ',' * Be careful: "-hsync" is a keyword. */
+ if ((c == ',') && !isalpha (configBuf[configPos]))
+ {
+ configStart = configPos;
+ return COMMA;
+ }
+ else if ((c == '-') && !isalpha (configBuf[configPos]))
+ {
+ configStart = configPos;
+ return DASH;
+ }
+
+ configStart = configPos;
+ /*
+ * Numbers are returned immediately ...
+ */
+ if (isdigit (c))
+ {
+ int base;
+
+ if (c == '0')
+ if ((configBuf[configPos] == 'x') ||
+ (configBuf[configPos] == 'X'))
+ base = 16;
+ else
+ base = 8;
+ else
+ base = 10;
+
+ configRBuf[0] = c;
+ i = 1;
+ while (isdigit (c = configBuf[configPos++]) ||
+ (c == '.') || (c == 'x') ||
+ ((base == 16) && (((c >= 'a') && (c <= 'f')) ||
+ ((c >= 'A') && (c <= 'F')))))
+ configRBuf[i++] = c;
+ configPos--; /* GJA -- one too far */
+ configRBuf[i] = '\0';
+ val.num = StrToUL (configRBuf);
+ val.realnum = atof (configRBuf);
+ return (NUMBER);
+ }
+
+ /*
+ * All Strings START with a \" ...
+ */
+ else if (c == '\"')
+ {
+ i = -1;
+ do
+ {
+ configRBuf[++i] = (c = configBuf[configPos++]);
+#ifndef __EMX__
+ }
+ while ((c != '\"') && (c != '\n') && (c != '\0'));
+#else
+ }
+ while ((c != '\"') && (c != '\n') && (c != '\r') && (c != '\0'));
+#endif
+ configRBuf[i] = '\0';
+ val.str = xf86confmalloc (strlen (configRBuf) + 1);
+ strcpy (val.str, configRBuf); /* private copy ! */
+ return (STRING);
+ }
+
+ /*
+ * ... and now we MUST have a valid token. The search is
+ * handled later along with the pushed tokens.
+ */
+ else
+ {
+ configRBuf[0] = c;
+ i = 0;
+ do
+ {
+ configRBuf[++i] = (c = configBuf[configPos++]);;
+#ifndef __EMX__
+ }
+ while ((c != ' ') && (c != '\t') && (c != '\n') && (c != '\0'));
+#else
+ }
+ while ((c != ' ') && (c != '\t') && (c != '\n') && (c != '\r') && (c != '\0'));
+#endif
+ configRBuf[i] = '\0';
+ i = 0;
+ }
+
+ }
+ else
+ {
+
+ /*
+ * Here we deal with pushed tokens. Reinitialize pushToken again. If
+ * the pushed token was NUMBER || STRING return them again ...
+ */
+ int temp = pushToken;
+ pushToken = LOCK_TOKEN;
+
+ if (temp == COMMA || temp == DASH)
+ return (temp);
+ if (temp == NUMBER || temp == STRING)
+ return (temp);
+ }
+
+ /*
+ * Joop, at last we have to lookup the token ...
+ */
+ if (tab)
+ {
+ i = 0;
+ while (tab[i].token != -1)
+ if (NameCompare (configRBuf, tab[i].name) == 0)
+ return (tab[i].token);
+ else
+ i++;
+ }
+
+ return (ERROR_TOKEN); /* Error catcher */
+}
+
+void
+xf86UnGetToken (int token)
+{
+ pushToken = token;
+}
+
+char *
+xf86TokenString (void)
+{
+ return configRBuf;
+}
+
+#if 1
+int
+PathIsAbsolute(const char *path)
+{
+ if (path && path[0] == '/')
+ return 1;
+#ifdef __EMX__
+ if (path && (path[0] == '\\' || (path[1] == ':')))
+ return 0;
+#endif
+ return 0;
+}
+
+/* A path is "safe" if it is relative and if it contains no ".." elements. */
+int
+PathIsSafe(const char *path)
+{
+ if (PathIsAbsolute(path))
+ return 0;
+
+ /* Compare with ".." */
+ if (!strcmp(path, ".."))
+ return 0;
+
+ /* Look for leading "../" */
+ if (!strncmp(path, "../", 3))
+ return 0;
+
+ /* Look for trailing "/.." */
+ if ((strlen(path) > 3) && !strcmp(path + strlen(path) - 3, "/.."))
+ return 0;
+
+ /* Look for "/../" */
+ if (strstr(path, "/../"))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * This function substitutes the following escape sequences:
+ *
+ * %A cmdline argument as an absolute path (must be absolute to match)
+ * %R cmdline argument as a relative path
+ * %S cmdline argument as a "safe" path (relative, and no ".." elements)
+ * %X default config file name ("XF86Config")
+ * %H hostname
+ * %E config file environment ($XF86CONFIG) as an absolute path
+ * %F config file environment ($XF86CONFIG) as a relative path
+ * %G config file environment ($XF86CONFIG) as a safe path
+ * %D $HOME
+ * %P projroot
+ * %% %
+ */
+
+#ifndef XCONFIGFILE
+#define XCONFIGFILE "XF86Config"
+#endif
+#ifndef PROJECTROOT
+#define PROJECTROOT "/usr/X11R6"
+#endif
+#ifndef XCONFENV
+#define XCONFENV "XF86CONFIG"
+#endif
+
+#define BAIL_OUT do { \
+ xf86conffree(result); \
+ return NULL; \
+ } while (0)
+
+#define CHECK_LENGTH do { \
+ if (l > PATH_MAX) { \
+ BAIL_OUT; \
+ } \
+ } while (0)
+
+#define APPEND_STR(s) do { \
+ if (strlen(s) + l > PATH_MAX) { \
+ BAIL_OUT; \
+ } else { \
+ strcpy(result + l, s); \
+ l += strlen(s); \
+ } \
+ } while (0)
+
+static char *
+DoSubstitution(const char *template, const char *cmdline, const char *projroot,
+ int *cmdlineUsed, int *envUsed)
+{
+ char *result;
+ int i, l;
+ static const char *env = NULL, *home = NULL;
+ static char *hostname = NULL;
+
+ if (!template)
+ return NULL;
+
+ if (cmdlineUsed)
+ *cmdlineUsed = 0;
+ if (envUsed)
+ *envUsed = 0;
+
+ result = xf86confmalloc(PATH_MAX + 1);
+ l = 0;
+ for (i = 0; template[i]; i++) {
+ if (template[i] != '%') {
+ result[l++] = template[i];
+ CHECK_LENGTH;
+ } else {
+ switch (template[++i]) {
+ case 'A':
+ if (cmdline && PathIsAbsolute(cmdline)) {
+ APPEND_STR(cmdline);
+ if (cmdlineUsed)
+ *cmdlineUsed = 1;
+ } else
+ BAIL_OUT;
+ break;
+ case 'R':
+ if (cmdline && !PathIsAbsolute(cmdline)) {
+ APPEND_STR(cmdline);
+ if (cmdlineUsed)
+ *cmdlineUsed = 1;
+ } else
+ BAIL_OUT;
+ break;
+ case 'S':
+ if (cmdline && PathIsSafe(cmdline)) {
+ APPEND_STR(cmdline);
+ if (cmdlineUsed)
+ *cmdlineUsed = 1;
+ } else
+ BAIL_OUT;
+ break;
+ case 'X':
+ APPEND_STR(XCONFIGFILE);
+ break;
+ case 'H':
+ if (!hostname) {
+ if ((hostname = xf86confmalloc(MAXHOSTNAMELEN + 1))) {
+ if (gethostname(hostname, MAXHOSTNAMELEN) == 0) {
+ hostname[MAXHOSTNAMELEN] = '\0';
+ } else {
+ xf86conffree(hostname);
+ hostname = NULL;
+ }
+ }
+ }
+ if (hostname)
+ APPEND_STR(hostname);
+ break;
+ case 'E':
+ if (!env)
+ env = getenv(XCONFENV);
+ if (env && PathIsAbsolute(env)) {
+ APPEND_STR(env);
+ if (envUsed)
+ *envUsed = 1;
+ } else
+ BAIL_OUT;
+ break;
+ case 'F':
+ if (!env)
+ env = getenv(XCONFENV);
+ if (env && !PathIsAbsolute(env)) {
+ APPEND_STR(env);
+ if (envUsed)
+ *envUsed = 1;
+ } else
+ BAIL_OUT;
+ break;
+ case 'G':
+ if (!env)
+ env = getenv(XCONFENV);
+ if (env && PathIsSafe(env)) {
+ APPEND_STR(env);
+ if (envUsed)
+ *envUsed = 1;
+ } else
+ BAIL_OUT;
+ break;
+ case 'D':
+ if (!home)
+ home = getenv("HOME");
+ if (home && PathIsAbsolute(home))
+ APPEND_STR(home);
+ else
+ BAIL_OUT;
+ break;
+ case 'P':
+ if (projroot && PathIsAbsolute(projroot))
+ APPEND_STR(projroot);
+ else
+ BAIL_OUT;
+ break;
+ case '%':
+ result[l++] = '%';
+ CHECK_LENGTH;
+ break;
+ default:
+ fprintf(stderr, "invalid escape %%%c found in path template\n",
+ template[i]);
+ BAIL_OUT;
+ break;
+ }
+ }
+ }
+#ifdef DEBUG
+ fprintf(stderr, "Converted `%s' to `%s'\n", template, result);
+#endif
+ return result;
+}
+
+/*
+ * xf86OpenConfigFile --
+ *
+ * This function take a config file search path (optional), a command-line
+ * specified file name (optional) and the ProjectRoot path (optional) and
+ * locates and opens a config file based on that information. If a
+ * command-line file name is specified, then this function fails if none
+ * of the located files.
+ *
+ * The return value is a pointer to the actual name of the file that was
+ * opened. When no file is found, the return value is NULL.
+ *
+ * The escape sequences allowed in the search path are defined above.
+ *
+ */
+
+#ifndef DEFAULT_CONF_PATH
+#define DEFAULT_CONF_PATH "/etc/X11/%S," \
+ "%P/etc/X11/%S," \
+ "/etc/X11/%G," \
+ "%P/etc/X11/%G," \
+ "/etc/X11/%X," \
+ "/etc/%X," \
+ "%P/etc/X11/%X.%H," \
+ "%P/etc/X11/%X," \
+ "%P/lib/X11/%X.%H," \
+ "%P/lib/X11/%X"
+#endif
+
+const char *
+xf86OpenConfigFile(const char *path, const char *cmdline, const char *projroot)
+{
+ char *pathcopy;
+ const char *template;
+ int cmdlineUsed = 0;
+
+ configFile = NULL;
+ configStart = 0; /* start of the current token */
+ configPos = 0; /* current readers position */
+ configLineNo = 0; /* linenumber */
+ pushToken = LOCK_TOKEN;
+
+ if (!path || !path[0])
+ path = DEFAULT_CONF_PATH;
+ pathcopy = xf86confmalloc(strlen(path) + 1);
+ strcpy(pathcopy, path);
+ if (!projroot || !projroot[0])
+ projroot = PROJECTROOT;
+
+ template = strtok(pathcopy, ",");
+
+ /* First, search for a config file. */
+ while (template && !configFile) {
+ if ((configPath = DoSubstitution(template, cmdline, projroot,
+ &cmdlineUsed, NULL))) {
+ if ((configFile = fopen(configPath, "r")) != 0) {
+ if (cmdline && !cmdlineUsed) {
+ fclose(configFile);
+ configFile = NULL;
+ }
+ }
+ }
+ if (configPath && !configFile) {
+ xf86conffree(configPath);
+ configPath = NULL;
+ }
+ template = strtok(NULL, ",");
+ }
+ if (!configFile) {
+ return NULL;
+ }
+
+ configBuf = xf86confmalloc (CONFIG_BUF_LEN);
+ configRBuf = xf86confmalloc (CONFIG_BUF_LEN);
+ configBuf[0] = '\0'; /* sanity ... */
+
+ return configPath;
+}
+#else
+/*
+ * xf86OpenConfigFile --
+ *
+ * Formerly findConfigFile(). This function take a pointer to a location
+ * in which to place the actual name of the file that was opened.
+ * This function uses the global character array xf86ConfigFile
+ * This function returns the following results.
+ *
+ * 0 unable to open the config file
+ * 1 file opened and ready to read
+ *
+ */
+
+int
+xf86OpenConfigFile (char *filename)
+{
+#define MAXPTRIES 6
+ char *home = NULL;
+ char *xconfig = NULL;
+ char *xwinhome = NULL;
+ char *configPaths[MAXPTRIES];
+ int pcount = 0, idx;
+
+/*
+ * First open if necessary the config file.
+ * If the -xf86config flag was used, use the name supplied there (root only).
+ * If $XF86CONFIG is a pathname, use it as the name of the config file (root)
+ * If $XF86CONFIG is set but doesn't contain a '/', append it to 'XF86Config'
+ * and search the standard places (root only).
+ * If $XF86CONFIG is not set, just search the standard places.
+ */
+ configFile = NULL;
+ configStart = 0; /* start of the current token */
+ configPos = 0; /* current readers position */
+ configLineNo = 0; /* linenumber */
+ pushToken = LOCK_TOKEN;
+ while (!configFile)
+ {
+
+ /*
+ * configPaths[0] is used as a buffer for -xf86config
+ * and $XF86CONFIG if it contains a path
+ * configPaths[1...MAXPTRIES-1] is used to store the paths of each of
+ * the other attempts
+ */
+ for (pcount = idx = 0; idx < MAXPTRIES; idx++)
+ configPaths[idx] = NULL;
+
+ /*
+ * First check if the -xf86config option was used.
+ */
+ configPaths[pcount] = xf86confmalloc (PATH_MAX);
+ if (xf86ConfigFile[0])
+ {
+ strcpy (configPaths[pcount], xf86ConfigFile);
+ if ((configFile = fopen (configPaths[pcount], "r")) != 0)
+ break;
+ else
+ return 0;
+ }
+ /*
+ * Check if XF86CONFIG is set.
+ */
+#ifndef __EMX__
+ if (getuid () == 0
+ && (xconfig = getenv ("XF86CONFIG")) != 0
+ && strchr (xconfig, '/'))
+#else
+ /* no root available, and filenames start with drive letter */
+ if ((xconfig = getenv ("XF86CONFIG")) != 0
+ && isalpha (xconfig[0])
+ && xconfig[1] == ':')
+#endif
+ {
+ strcpy (configPaths[pcount], xconfig);
+ if ((configFile = fopen (configPaths[pcount], "r")) != 0)
+ break;
+ else
+ return 0;
+ }
+
+#ifndef __EMX__
+ /*
+ * ~/XF86Config ...
+ */
+ if (getuid () == 0 && (home = getenv ("HOME")) != NULL)
+ {
+ configPaths[++pcount] = xf86confmalloc (PATH_MAX);
+ strcpy (configPaths[pcount], home);
+ strcat (configPaths[pcount], "/" XCONFIGFILE);
+ if (xconfig)
+ strcat (configPaths[pcount], xconfig);
+ if ((configFile = fopen (configPaths[pcount], "r")) != 0)
+ break;
+ }
+
+ /*
+ * /etc/XF86Config
+ */
+ configPaths[++pcount] = xf86confmalloc (PATH_MAX);
+ strcpy (configPaths[pcount], "/etc/" XCONFIGFILE);
+ if (xconfig)
+ strcat (configPaths[pcount], xconfig);
+ if ((configFile = fopen (configPaths[pcount], "r")) != 0)
+ break;
+
+ /*
+ * $(XCONFIGDIR)/XF86Config.<hostname>
+ */
+
+ configPaths[++pcount] = xf86confmalloc (PATH_MAX);
+ if (getuid () == 0 && (xwinhome = getenv ("XWINHOME")) != NULL)
+ sprintf (configPaths[pcount], "%s/lib/X11/" XCONFIGFILE, xwinhome);
+ else
+ strcpy (configPaths[pcount], XCONFIGDIR "/" XCONFIGFILE);
+ if (getuid () == 0 && xconfig)
+ strcat (configPaths[pcount], xconfig);
+ strcat (configPaths[pcount], ".");
+#ifdef AMOEBA
+ {
+ extern char *XServerHostName;
+
+ strcat (configPaths[pcount], XServerHostName);
+ }
+#else
+ gethostname (configPaths[pcount] + strlen (configPaths[pcount]),
+ MAXHOSTNAMELEN);
+#endif
+ if ((configFile = fopen (configPaths[pcount], "r")) != 0)
+ break;
+#endif /* !__EMX__ */
+
+ /*
+ * $(XCONFIGDIR)/XF86Config
+ */
+ configPaths[++pcount] = xf86confmalloc (PATH_MAX);
+#ifndef __EMX__
+ if (getuid () == 0 && xwinhome)
+ sprintf (configPaths[pcount], "%s/lib/X11/" XCONFIGFILE, xwinhome);
+ else
+ strcpy (configPaths[pcount], XCONFIGDIR "/" XCONFIGFILE);
+ if (getuid () == 0 && xconfig)
+ strcat (configPaths[pcount], xconfig);
+#else
+ /*
+ * we explicitly forbid numerous config files everywhere for OS/2;
+ * users should consider them lucky to have one in a standard place
+ * and another one with the -xf86config option
+ */
+ xwinhome = getenv ("X11ROOT"); /* get drive letter */
+ if (!xwinhome) {
+ fprintf (stderr,"X11ROOT environment variable not set\n");
+ exit(2);
+ }
+ strcpy (configPaths[pcount], __XOS2RedirRoot ("/XFree86/lib/X11/XConfig"));
+#endif
+
+ if ((configFile = fopen (configPaths[pcount], "r")) != 0)
+ break;
+
+ return 0;
+ }
+ configBuf = xf86confmalloc (CONFIG_BUF_LEN);
+ configRBuf = xf86confmalloc (CONFIG_BUF_LEN);
+ configPath = xf86confmalloc (PATH_MAX);
+
+ strcpy (configPath, configPaths[pcount]);
+
+ if (filename)
+ strcpy (filename, configPaths[pcount]);
+ for (idx = 0; idx <= pcount; idx++)
+ if (configPaths[idx] != NULL)
+ xf86conffree (configPaths[idx]);
+
+ configBuf[0] = '\0'; /* sanity ... */
+
+ return 1;
+}
+#endif
+
+void
+xf86CloseConfigFile (void)
+{
+ xf86conffree (configPath);
+ xf86conffree (configRBuf);
+ xf86conffree (configBuf);
+
+ fclose (configFile);
+}
+
+void
+xf86ParseError (char *format,...)
+{
+ va_list ap;
+
+#if 0
+ fprintf (stderr, "Parse error on line %d of section %s in file %s\n",
+ configLineNo, configSection, configPath);
+ fprintf (stderr, "\t");
+ va_start (ap, format);
+ vfprintf (stderr, format, ap);
+ va_end (ap);
+
+ fprintf (stderr, "\n");
+#else
+ ErrorF ("Parse error on line %d of section %s in file %s\n\t",
+ configLineNo, configSection, configPath);
+ va_start (ap, format);
+ VErrorF (format, ap);
+ va_end (ap);
+
+ ErrorF ("\n");
+#endif
+
+}
+
+void
+xf86ParseWarning (char *format,...)
+{
+ va_list ap;
+
+#if 0
+ fprintf (stderr, "Parse warning on line %d of section %s in file %s\n",
+ configLineNo, configSection, configPath);
+ fprintf (stderr, "\t");
+ va_start (ap, format);
+ vfprintf (stderr, format, ap);
+ va_end (ap);
+
+ fprintf (stderr, "\n");
+#else
+ ErrorF ("Parse warning on line %d of section %s in file %s\n\t",
+ configLineNo, configSection, configPath);
+ va_start (ap, format);
+ VErrorF (format, ap);
+ va_end (ap);
+
+ ErrorF ("\n");
+#endif
+}
+
+void
+xf86ValidationError (char *format,...)
+{
+ va_list ap;
+
+#if 0
+ fprintf (stderr, "Data incomplete in file %s\n",
+ configPath);
+ fprintf (stderr, "\t");
+ va_start (ap, format);
+ vfprintf (stderr, format, ap);
+ va_end (ap);
+
+ fprintf (stderr, "\n");
+#else
+ ErrorF ("Data incomplete in file %s\n\t", configPath);
+ va_start (ap, format);
+ VErrorF (format, ap);
+ va_end (ap);
+
+ ErrorF ("\n");
+#endif
+}
+
+void
+SetSection (char *section)
+{
+ configSection = section;
+}
+
+/*
+ * xf86GetToken --
+ * Lookup a string if it is actually a token in disguise.
+ */
+int
+getStringToken (xf86ConfigSymTabRec * tab)
+{
+ return StringToToken (val.str, tab);
+}
+
+static int
+StringToToken (char *str, xf86ConfigSymTabRec * tab)
+{
+ int i;
+
+ for (i = 0; tab[i].token != -1; i++)
+ {
+ if (!NameCompare (tab[i].name, str))
+ return tab[i].token;
+ }
+ return (ERROR_TOKEN);
+}
+
+
+/*
+ * Compare two names. The characters '_', ' ', and '\t' are ignored
+ * in the comparison.
+ */
+int
+NameCompare (const char *s1, const char *s2)
+{
+ char c1, c2;
+
+ if (!s1 || *s1 == 0)
+ if (!s2 || *s2 == 0)
+ return (0);
+ else
+ return (1);
+
+ while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
+ s1++;
+ while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
+ s2++;
+ c1 = (isupper (*s1) ? tolower (*s1) : *s1);
+ c2 = (isupper (*s2) ? tolower (*s2) : *s2);
+ while (c1 == c2)
+ {
+ if (c1 == '\0')
+ return (0);
+ s1++;
+ s2++;
+ while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
+ s1++;
+ while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
+ s2++;
+ c1 = (isupper (*s1) ? tolower (*s1) : *s1);
+ c2 = (isupper (*s2) ? tolower (*s2) : *s2);
+ }
+ return (c1 - c2);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/parser/write.c b/xc/programs/Xserver/hw/xfree86/parser/write.c
new file mode 100644
index 000000000..6f7d69ac1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/write.c
@@ -0,0 +1,86 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/write.c,v 1.7 1999/06/27 14:08:31 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/* View/edit this file with tab stops set to 4 */
+
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+
+int
+xf86WriteConfigFile (const char *filename, XF86ConfigPtr cptr)
+{
+ FILE *cf;
+
+ if ((cf = fopen (filename, "w")) == NULL)
+ {
+ return 0;
+ }
+
+ printLayoutSection (cf, cptr->conf_layout_lst);
+
+ fprintf (cf, "Section \"Files\"\n");
+ printFileSection (cf, cptr->conf_files);
+ fprintf (cf, "EndSection\n\n");
+
+ fprintf (cf, "Section \"Module\"\n");
+ printModuleSection (cf, cptr->conf_modules);
+ fprintf (cf, "EndSection\n\n");
+
+ printVendorSection (cf, cptr->conf_vendor_lst);
+
+ printServerFlagsSection (cf, cptr->conf_flags);
+
+#ifndef NEW_INPUT
+ fprintf (cf, "Section \"Keyboard\"\n");
+ printKeyboardSection (cf, cptr->conf_keyboard);
+ fprintf (cf, "EndSection\n\n");
+
+ fprintf (cf, "Section \"Pointer\"\n");
+ printPointerSection (cf, cptr->conf_pointer);
+ fprintf (cf, "EndSection\n\n");
+#endif
+
+ printInputSection (cf, cptr->conf_input_lst);
+
+ printVideoAdaptorSection (cf, cptr->conf_videoadaptor_lst);
+
+ printMonitorSection (cf, cptr->conf_monitor_lst);
+
+ printDeviceSection (cf, cptr->conf_device_lst);
+
+ printScreenSection (cf, cptr->conf_screen_lst);
+
+ fprintf (cf, "Section \"DRI\"\n");
+ printDRISection (cf, cptr->conf_dri);
+ fprintf (cf, "EndSection\n\n");
+
+ fclose(cf);
+ return 1;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/parser/xf86Optrec.h b/xc/programs/Xserver/hw/xfree86/parser/xf86Optrec.h
new file mode 100644
index 000000000..dfb83c83d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/xf86Optrec.h
@@ -0,0 +1,78 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/xf86Optrec.h,v 1.6 1999/06/05 15:55:32 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/*
+ * This file contains the Option Record that is passed between the Parser,
+ * and Module setup procs.
+ */
+#ifndef _xf86Optrec_h_
+#define _xf86Optrec_h_
+
+/*
+ * all records that need to be linked lists should contain a GenericList as
+ * their first field.
+ */
+typedef struct generic_list_rec
+{
+ void *next;
+}
+GenericListRec, *GenericListPtr, *glp;
+
+/*
+ * All options are stored using this data type.
+ */
+typedef struct
+{
+ GenericListRec list;
+ char *opt_name;
+ char *opt_val;
+ int opt_used;
+}
+XF86OptionRec, *XF86OptionPtr;
+
+
+XF86OptionPtr addNewOption(XF86OptionPtr head, char *name, char *val);
+XF86OptionPtr OptionListDup(XF86OptionPtr opt);
+void OptionListFree(XF86OptionPtr opt);
+char *OptionName(XF86OptionPtr opt);
+char *OptionValue(XF86OptionPtr opt);
+XF86OptionPtr NewOption(char *name, char *value);
+XF86OptionPtr NextOption(XF86OptionPtr list);
+XF86OptionPtr FindOption(XF86OptionPtr list, const char *name);
+char *FindOptionValue(XF86OptionPtr list, const char *name);
+XF86OptionPtr OptionListCreate(const char **options, int count, int used);
+XF86OptionPtr OptionListMerge(XF86OptionPtr head, XF86OptionPtr tail);
+int FindOptionBoolean(XF86OptionPtr list, char *name, int default_val);
+char *ConfigStrdup (const char *s);
+int NameCompare (const char *s1, const char *s2);
+char *ULongToString(unsigned long i);
+
+
+
+#endif /* _xf86Optrec_h_ */
diff --git a/xc/programs/Xserver/hw/xfree86/parser/xf86Parser.h b/xc/programs/Xserver/hw/xfree86/parser/xf86Parser.h
new file mode 100644
index 000000000..0787396ad
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/xf86Parser.h
@@ -0,0 +1,448 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/xf86Parser.h,v 1.16 1999/06/27 14:08:32 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/*
+ * This file contains the external interfaces for the XFree86 configuration
+ * file parser.
+ */
+#ifndef _xf86Parser_h_
+#define _xf86Parser_h_
+
+#include "xf86Optrec.h"
+
+#define HAVE_PARSER_DECLS
+
+typedef struct
+{
+ char *file_logfile;
+ char *file_rgbpath;
+ char *file_modulepath;
+ char *file_fontpath;
+}
+XF86ConfFilesRec, *XF86ConfFilesPtr;
+
+/* Values for load_type */
+#define XF86_LOAD_MODULE 0
+#define XF86_LOAD_DRIVER 1
+
+typedef struct
+{
+ GenericListRec list;
+ int load_type;
+ char *load_name;
+ XF86OptionPtr load_opt;
+}
+XF86LoadRec, *XF86LoadPtr;
+
+typedef struct
+{
+ XF86LoadPtr mod_load_lst;
+}
+XF86ConfModuleRec, *XF86ConfModulePtr;
+
+#define CONF_IMPLICIT_KEYBOARD "Implicit Core Keyboard"
+
+#ifndef NEW_INPUT
+/* Device tokens */
+typedef struct
+{
+ char *keyb_protocol;
+ int keyb_kbdDelay;
+ int keyb_kbdRate;
+ long keyb_xleds;
+ int keyb_xkbDisable;
+ char *keyb_xkbkeymap;
+ char *keyb_xkbcompat;
+ char *keyb_xkbtypes;
+ char *keyb_xkbkeycodes;
+ char *keyb_xkbgeometry;
+ char *keyb_xkbsymbols;
+ char *keyb_xkbrules;
+ char *keyb_xkbmodel;
+ char *keyb_xkblayout;
+ char *keyb_xkbvariant;
+ char *keyb_xkboptions;
+ int keyb_panix106;
+}
+XF86ConfKeyboardRec, *XF86ConfKeyboardPtr;
+#endif /* NEW_INPUT */
+
+#define CONF_IMPLICIT_POINTER "Implicit Core Pointer"
+
+#ifndef NEW_INPUT
+#define CONF_ZAXIS_MAPTOX -1
+#define CONF_ZAXIS_MAPTOY -2
+
+typedef struct
+{
+ char *pntr_protocol;
+ char *pntr_device;
+ int pntr_buttons;
+ int pntr_baudrate;
+ int pntr_samplerate;
+ int pntr_resolution;
+ int pntr_emulate3Buttons;
+ int pntr_emulate3Timeout;
+ int pntr_chordMiddle;
+ int pntr_clearDtr;
+ int pntr_clearRts;
+ int pntr_negativeZ;
+ int pntr_positiveZ;
+ int pntr_alwaysCore;
+}
+XF86ConfPointerRec, *XF86ConfPointerPtr;
+#endif /* NEW_INPUT */
+
+#define XF86CONF_PHSYNC 0x0001
+#define XF86CONF_NHSYNC 0x0002
+#define XF86CONF_PVSYNC 0x0004
+#define XF86CONF_NVSYNC 0x0008
+#define XF86CONF_INTERLACE 0x0010
+#define XF86CONF_DBLSCAN 0x0020
+#define XF86CONF_CSYNC 0x0040
+#define XF86CONF_PCSYNC 0x0080
+#define XF86CONF_NCSYNC 0x0100
+#define XF86CONF_HSKEW 0x0200 /* hskew provided */
+#define XF86CONF_CUSTOM 0x0400 /* timing numbers customized by editor */
+
+typedef struct
+{
+ GenericListRec list;
+ char *ml_identifier;
+ int ml_clock;
+ int ml_hdisplay;
+ int ml_hsyncstart;
+ int ml_hsyncend;
+ int ml_htotal;
+ int ml_vdisplay;
+ int ml_vsyncstart;
+ int ml_vsyncend;
+ int ml_vtotal;
+ int ml_vscan;
+ int ml_flags;
+ int ml_hskew;
+}
+XF86ConfModeLineRec, *XF86ConfModeLinePtr;
+
+typedef struct
+{
+ GenericListRec list;
+ char *vp_identifier;
+ XF86OptionPtr vp_option_lst;
+}
+XF86ConfVideoPortRec, *XF86ConfVideoPortPtr;
+
+typedef struct
+{
+ GenericListRec list;
+ char *va_identifier;
+ char *va_vendor;
+ char *va_board;
+ char *va_busid;
+ char *va_driver;
+ XF86OptionPtr va_option_lst;
+ XF86ConfVideoPortPtr va_port_lst;
+ char *va_fwdref;
+}
+XF86ConfVideoAdaptorRec, *XF86ConfVideoAdaptorPtr;
+
+#define CONF_MAX_HSYNC 8
+#define CONF_MAX_VREFRESH 8
+
+typedef struct
+{
+ float hi, lo;
+}
+parser_range;
+
+typedef struct
+{
+ int red, green, blue;
+}
+parser_rgb;
+
+typedef struct
+{
+ GenericListRec list;
+ char *modes_identifier;
+ XF86ConfModeLinePtr mon_modeline_lst;
+}
+XF86ConfModesRec, *XF86ConfModesPtr;
+
+typedef struct
+{
+ GenericListRec list;
+ char *ml_modes_str;
+ XF86ConfModesPtr ml_modes;
+}
+XF86ConfModesLinkRec, *XF86ConfModesLinkPtr;
+
+typedef struct
+{
+ GenericListRec list;
+ char *mon_identifier;
+ char *mon_vendor;
+ char *mon_modelname;
+ int mon_width; /* in mm */
+ int mon_height; /* in mm */
+ XF86ConfModeLinePtr mon_modeline_lst;
+ int mon_n_hsync;
+ parser_range mon_hsync[CONF_MAX_HSYNC];
+ int mon_n_vrefresh;
+ parser_range mon_vrefresh[CONF_MAX_VREFRESH];
+ float mon_gamma_red;
+ float mon_gamma_green;
+ float mon_gamma_blue;
+ XF86OptionPtr mon_option_lst;
+ XF86ConfModesLinkPtr mon_modes_sect_lst;
+}
+XF86ConfMonitorRec, *XF86ConfMonitorPtr;
+
+#define CONF_MAXDACSPEEDS 4
+#define CONF_MAXCLOCKS 128
+
+typedef struct
+{
+ GenericListRec list;
+ char *dev_identifier;
+ char *dev_vendor;
+ char *dev_board;
+ char *dev_chipset;
+ char *dev_busid;
+ char *dev_card;
+ char *dev_driver;
+ char *dev_ramdac;
+ int dev_dacSpeeds[CONF_MAXDACSPEEDS];
+ int dev_videoram;
+ int dev_textclockfreq;
+ unsigned long dev_bios_base;
+ unsigned long dev_mem_base;
+ unsigned long dev_io_base;
+ char *dev_clockchip;
+ int dev_clocks;
+ int dev_clock[CONF_MAXCLOCKS];
+ int dev_chipid;
+ int dev_chiprev;
+ int dev_irq;
+ XF86OptionPtr dev_option_lst;
+}
+XF86ConfDeviceRec, *XF86ConfDevicePtr;
+
+typedef struct
+{
+ GenericListRec list;
+ char *mode_name;
+}
+XF86ModeRec, *XF86ModePtr;
+
+typedef struct
+{
+ GenericListRec list;
+ int disp_frameX0;
+ int disp_frameY0;
+ int disp_virtualX;
+ int disp_virtualY;
+ int disp_depth;
+ int disp_bpp;
+ char *disp_visual;
+ parser_rgb disp_weight;
+ parser_rgb disp_black;
+ parser_rgb disp_white;
+ XF86ModePtr disp_mode_lst;
+ XF86OptionPtr disp_option_lst;
+}
+XF86ConfDisplayRec, *XF86ConfDisplayPtr;
+
+typedef struct
+{
+ XF86OptionPtr flg_option_lst;
+}
+XF86ConfFlagsRec, *XF86ConfFlagsPtr;
+
+typedef struct
+{
+ GenericListRec list;
+ char *al_adaptor_str;
+ XF86ConfVideoAdaptorPtr al_adaptor;
+}
+XF86ConfAdaptorLinkRec, *XF86ConfAdaptorLinkPtr;
+
+typedef struct
+{
+ GenericListRec list;
+ char *scrn_identifier;
+ char *scrn_obso_driver;
+ int scrn_defaultdepth;
+ int scrn_defaultbpp;
+ int scrn_defaultfbbpp;
+ char *scrn_monitor_str;
+ XF86ConfMonitorPtr scrn_monitor;
+ char *scrn_device_str;
+ XF86ConfDevicePtr scrn_device;
+ XF86ConfAdaptorLinkPtr scrn_adaptor_lst;
+ XF86ConfDisplayPtr scrn_display_lst;
+ XF86OptionPtr scrn_option_lst;
+}
+XF86ConfScreenRec, *XF86ConfScreenPtr;
+
+typedef struct
+{
+ GenericListRec list;
+ char *inp_identifier;
+ char *inp_driver;
+ XF86OptionPtr inp_option_lst;
+}
+XF86ConfInputRec, *XF86ConfInputPtr;
+
+typedef struct
+{
+ GenericListRec list;
+ XF86ConfInputPtr iref_inputdev;
+ char *iref_inputdev_str;
+ XF86OptionPtr iref_option_lst;
+}
+XF86ConfInputrefRec, *XF86ConfInputrefPtr;
+
+typedef struct
+{
+ GenericListRec list;
+ int adj_scrnum;
+ XF86ConfScreenPtr adj_screen;
+ char *adj_screen_str;
+ XF86ConfScreenPtr adj_top;
+ char *adj_top_str;
+ XF86ConfScreenPtr adj_bottom;
+ char *adj_bottom_str;
+ XF86ConfScreenPtr adj_left;
+ char *adj_left_str;
+ XF86ConfScreenPtr adj_right;
+ char *adj_right_str;
+}
+XF86ConfAdjacencyRec, *XF86ConfAdjacencyPtr;
+
+typedef struct
+{
+ GenericListRec list;
+ char *inactive_device_str;
+ XF86ConfDevicePtr inactive_device;
+}
+XF86ConfInactiveRec, *XF86ConfInactivePtr;
+
+typedef struct
+{
+ GenericListRec list;
+ char *lay_identifier;
+ XF86ConfAdjacencyPtr lay_adjacency_lst;
+ XF86ConfInactivePtr lay_inactive_lst;
+ XF86ConfInputrefPtr lay_input_lst;
+ XF86OptionPtr lay_option_lst;
+}
+XF86ConfLayoutRec, *XF86ConfLayoutPtr;
+
+typedef struct
+{
+ GenericListRec list;
+ char *vnd_identifier;
+ XF86OptionPtr vnd_option_lst;
+}
+XF86ConfVendorRec, *XF86ConfVendorPtr;
+
+typedef struct
+{
+ GenericListRec list;
+ int buf_count;
+ int buf_size;
+ char *buf_flags;
+}
+XF86ConfBuffersRec, *XF86ConfBuffersPtr;
+
+typedef struct
+{
+ int dri_group;
+ int dri_mode;
+ XF86ConfBuffersPtr dri_buffers_lst;
+}
+XF86ConfDRIRec, *XF86ConfDRIPtr;
+
+typedef struct
+{
+ XF86ConfFilesPtr conf_files;
+ XF86ConfModulePtr conf_modules;
+ XF86ConfFlagsPtr conf_flags;
+#ifndef NEW_INPUT
+ XF86ConfKeyboardPtr conf_keyboard;
+ XF86ConfPointerPtr conf_pointer;
+#endif
+ XF86ConfVideoAdaptorPtr conf_videoadaptor_lst;
+ XF86ConfModesPtr conf_modes_lst;
+ XF86ConfMonitorPtr conf_monitor_lst;
+ XF86ConfDevicePtr conf_device_lst;
+ XF86ConfScreenPtr conf_screen_lst;
+ XF86ConfInputPtr conf_input_lst;
+ XF86ConfLayoutPtr conf_layout_lst;
+ XF86ConfVendorPtr conf_vendor_lst;
+ XF86ConfDRIPtr conf_dri;
+}
+XF86ConfigRec, *XF86ConfigPtr;
+
+typedef struct
+{
+ int token; /* id of the token */
+ char *name; /* pointer to the LOWERCASED name */
+}
+xf86ConfigSymTabRec, *xf86ConfigSymTabPtr;
+
+/*
+ * prototypes for public functions
+ */
+extern const char *xf86OpenConfigFile (const char *, const char *,
+ const char *);
+extern XF86ConfigPtr xf86ReadConfigFile (void);
+extern void xf86CloseConfigFile (void);
+extern void XF86FreeConfig (XF86ConfigPtr p);
+extern int xf86WriteConfigFile (const char *, XF86ConfigPtr);
+XF86ConfDevicePtr xf86FindDevice(const char *ident, XF86ConfDevicePtr p);
+XF86ConfLayoutPtr xf86FindLayout(const char *name, XF86ConfLayoutPtr list);
+XF86ConfMonitorPtr xf86FindMonitor(const char *ident, XF86ConfMonitorPtr p);
+XF86ConfModesPtr xf86FindModes(const char *ident, XF86ConfModesPtr p);
+XF86ConfModeLinePtr xf86FindModeLine(const char *ident, XF86ConfModeLinePtr p);
+XF86ConfScreenPtr xf86FindScreen(const char *ident, XF86ConfScreenPtr p);
+XF86ConfDisplayPtr xf86FindDisplay(int depth, XF86ConfDisplayPtr p);
+XF86ConfInputPtr xf86FindInput(const char *ident, XF86ConfInputPtr p);
+XF86ConfInputPtr xf86FindInputByDriver(const char *driver, XF86ConfInputPtr p);
+XF86ConfVendorPtr xf86FindVendor(const char *name, XF86ConfVendorPtr list);
+XF86ConfVideoAdaptorPtr xf86FindVideoAdaptor(const char *ident,
+ XF86ConfVideoAdaptorPtr p);
+
+GenericListPtr addListItem(GenericListPtr head, GenericListPtr new);
+
+int PathIsAbsolute(const char *path);
+int PathIsSafe(const char *path);
+
+#endif /* _xf86Parser_h_ */
diff --git a/xc/programs/Xserver/hw/xfree86/parser/xf86tokens.h b/xc/programs/Xserver/hw/xfree86/parser/xf86tokens.h
new file mode 100644
index 000000000..72ec85afa
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/parser/xf86tokens.h
@@ -0,0 +1,236 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/xf86tokens.h,v 1.11 1999/06/27 14:08:32 dawes Exp $ */
+/*
+ *
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+#ifndef _xf86_tokens_h
+#define _xf86_tokens_h
+
+/* Undefine symbols that some OSs might define */
+#undef IOBASE
+
+/*
+ * Each token should have a unique value regardless of the section
+ * it is used in.
+ */
+
+typedef enum {
+ /* errno-style tokens */
+ EOF_TOKEN = -4,
+ LOCK_TOKEN = -3,
+ ERROR_TOKEN = -2,
+
+ /* value type tokens */
+ NUMBER = 1,
+ STRING,
+
+ /* Tokens that can appear in many sections */
+ SECTION,
+ SUBSECTION,
+ ENDSECTION,
+ ENDSUBSECTION,
+ IDENTIFIER,
+ VENDOR,
+ DASH,
+ COMMA,
+ OPTION,
+
+ /* Frequency units */
+ HRZ,
+ KHZ,
+ MHZ,
+
+ /* File tokens */
+ FONTPATH,
+ RGBPATH,
+ MODULEPATH,
+ LOGFILEPATH,
+
+ /* Server Flag tokens. These are deprecated in favour of generic Options */
+ NOTRAPSIGNALS,
+ DONTZAP,
+ DONTZOOM,
+ DISABLEVIDMODE,
+ ALLOWNONLOCAL,
+ DISABLEMODINDEV,
+ MODINDEVALLOWNONLOCAL,
+ ALLOWMOUSEOPENFAIL,
+ BLANKTIME,
+ STANDBYTIME,
+ SUSPENDTIME,
+ OFFTIME,
+
+ /* Monitor tokens */
+ MODEL,
+ MODELINE,
+ DISPLAYSIZE,
+ HORIZSYNC,
+ VERTREFRESH,
+ MODE,
+ GAMMA,
+ USEMODES,
+
+ /* Modes tokens */
+ /* no new ones */
+
+ /* Mode tokens */
+ DOTCLOCK,
+ HTIMINGS,
+ VTIMINGS,
+ FLAGS,
+ HSKEW,
+ VSCAN,
+ ENDMODE,
+
+ /* Screen tokens */
+ OBSDRIVER,
+ MDEVICE,
+ MONITOR,
+ SCREENNO,
+ DEFAULTDEPTH,
+ DEFAULTBPP,
+ DEFAULTFBBPP,
+
+ /* VideoAdaptor tokens */
+ VIDEOADAPTOR,
+
+ /* Mode timing tokens */
+ TT_INTERLACE,
+ TT_PHSYNC,
+ TT_NHSYNC,
+ TT_PVSYNC,
+ TT_NVSYNC,
+ TT_CSYNC,
+ TT_PCSYNC,
+ TT_NCSYNC,
+ TT_DBLSCAN,
+ TT_HSKEW,
+ TT_VSCAN,
+ TT_CUSTOM,
+
+ /* Module tokens */
+ LOAD,
+ LOAD_DRIVER,
+
+ /* Device tokens */
+ DRIVER,
+ CHIPSET,
+ CLOCKS,
+ VIDEORAM,
+ BOARD,
+ IOBASE,
+ RAMDAC,
+ DACSPEED,
+ BIOSBASE,
+ MEMBASE,
+ CLOCKCHIP,
+ CHIPID,
+ CHIPREV,
+ CARD,
+ BUSID,
+ TEXTCLOCKFRQ,
+ IRQ,
+
+ /* Keyboard tokens */
+ AUTOREPEAT,
+ XLEDS,
+ KPROTOCOL,
+ XKBKEYMAP,
+ XKBCOMPAT,
+ XKBTYPES,
+ XKBKEYCODES,
+ XKBGEOMETRY,
+ XKBSYMBOLS,
+ XKBDISABLE,
+ PANIX106,
+ XKBRULES,
+ XKBMODEL,
+ XKBLAYOUT,
+ XKBVARIANT,
+ XKBOPTIONS,
+ /* The next two have become ServerFlags options */
+ VTINIT,
+ VTSYSREQ,
+ /* Obsolete keyboard tokens */
+ SERVERNUM,
+ LEFTALT,
+ RIGHTALT,
+ SCROLLLOCK_TOK,
+ RIGHTCTL,
+ /* arguments for the above obsolete tokens */
+ CONF_KM_META,
+ CONF_KM_COMPOSE,
+ CONF_KM_MODESHIFT,
+ CONF_KM_MODELOCK,
+ CONF_KM_SCROLLLOCK,
+ CONF_KM_CONTROL,
+
+ /* Pointer tokens */
+ EMULATE3,
+ BAUDRATE,
+ SAMPLERATE,
+ PRESOLUTION,
+ CLEARDTR,
+ CLEARRTS,
+ CHORDMIDDLE,
+ PROTOCOL,
+ PDEVICE,
+ EM3TIMEOUT,
+ DEVICE_NAME,
+ ALWAYSCORE,
+ PBUTTONS,
+ ZAXISMAPPING,
+
+ /* Pointer Z axis mapping tokens */
+ XAXIS,
+ YAXIS,
+
+ /* Display tokens */
+ MODES,
+ VIEWPORT,
+ VIRTUAL,
+ VISUAL,
+ BLACK_TOK,
+ WHITE_TOK,
+ DEPTH,
+ BPP,
+ WEIGHT,
+
+ /* Layout Tokens */
+ SCREEN,
+ INACTIVE,
+ INPUTDEVICE,
+
+ /* Vendor Tokens */
+ VENDORNAME,
+
+ /* DRI Tokens */
+ GROUP,
+ BUFFERS
+} ParserTokens;
+
+#endif /* _xf86_tokens_h */
diff --git a/xc/programs/Xserver/hw/xfree86/rac/Imakefile b/xc/programs/Xserver/hw/xfree86/rac/Imakefile
new file mode 100644
index 000000000..03563a476
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/rac/Imakefile
@@ -0,0 +1,28 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/rac/Imakefile,v 1.5 1999/08/14 10:50:07 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#if DoLoadableServer
+MODSRC = xf86RACmodule.c
+MODOBJ = xf86RACmodule.o
+#endif
+
+SRCS = xf86RAC.c $(MODSRC)
+OBJS = xf86RAC.o $(MODOBJ)
+
+INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) \
+ -I$(SERVERSRC)/include -I$(SERVERSRC)/mi -I$(XINCLUDESRC)
+
+ModuleObjectRule()
+
+LibraryModuleTarget(rac, $(OBJS))
+
+InstallLibraryModule(rac,$(MODULEDIR),.)
+
+DependTarget()
+
+
+InstallDriverSDKLibraryModule(rac,$(DRIVERSDKMODULEDIR),.)
+
+InstallDriverSDKNonExecFile(xf86RAC.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/xc/programs/Xserver/hw/xfree86/rac/xf86RAC.c b/xc/programs/Xserver/hw/xfree86/rac/xf86RAC.c
new file mode 100644
index 000000000..fbd540017
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/rac/xf86RAC.c
@@ -0,0 +1,1164 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/rac/xf86RAC.c,v 1.5 1999/06/12 17:30:21 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "colormapst.h"
+#include "scrnintstr.h"
+#include "screenint.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "pixmap.h"
+#include "windowstr.h"
+#include "window.h"
+#include "xf86str.h"
+#include "xf86RAC.h"
+#include "mipointer.h"
+#include "mipointrst.h"
+
+#ifdef DEBUG
+#define DPRINT_S(x,y) ErrorF(x ": %i\n",y);
+#define DPRINT(x) ErrorF(x "\n");
+#else
+#define DPRINT_S(x,y)
+#define DPRINT(x)
+#endif
+
+#define WRAP_SCREEN(x,y) {pScreenPriv->x = pScreen->x;\
+ pScreen->x = y;}
+#define WRAP_SCREEN_COND(x,y,cond) \
+ {pScreenPriv->x = pScreen->x;\
+ if (flag & (cond))\
+ pScreen->x = y;}
+#define UNWRAP_SCREEN(x) pScreen->x = pScreenPriv->x
+
+#define SCREEN_PROLOG(x) \
+ pScreen->x = \
+ ((RACScreenPtr) (pScreen)->devPrivates[RACScreenIndex].ptr)->x
+#define SCREEN_EPILOG(x,y) pScreen->x = y;
+
+#define WRAP_SCREEN_INFO(x,y) {pScreenPriv->x = pScrn->x;\
+ pScrn->x = y;}
+#define WRAP_SCREEN_INFO_COND(x,y,cond) \
+ {pScreenPriv->x = pScrn->x;\
+ if (flag & (cond))\
+ pScrn->x = y;}
+#define UNWRAP_SCREEN_INFO(x) pScrn->x = pScreenPriv->x
+
+#define SPRITE_PROLOG miPointerScreenPtr PointPriv = \
+(miPointerScreenPtr)pScreen->devPrivates[miPointerScreenIndex].ptr;\
+ RACScreenPtr pScreenPriv = \
+((RACScreenPtr) (pScreen)->devPrivates[RACScreenIndex].ptr);\
+ PointPriv->spriteFuncs = pScreenPriv->miSprite;
+#define SPRITE_EPILOG pScreenPriv->miSprite = PointPriv->spriteFuncs;\
+ PointPriv->spriteFuncs = &RACSpriteFuncs;
+#define WRAP_SPRITE_COND(cond){pScreenPriv->miSprite = PointPriv->spriteFuncs;\
+ if(flag & (cond))\
+ PointPriv->spriteFuncs = &RACSpriteFuncs;}
+#define UNWRAP_SPRITE PointPriv->spriteFuncs = pScreenPriv->miSprite
+
+
+#define GC_WRAP(x) pGCPriv->wrapOps = (x)->ops;\
+ pGCPriv->wrapFuncs = (x)->funcs;\
+ (x)->ops = &RACGCOps;\
+ (x)->funcs = &RACGCFuncs;
+#define GC_UNWRAP(x)\
+ RACGCPtr pGCPriv = (RACGCPtr) (x)->devPrivates[RACGCIndex].ptr;\
+ (x)->ops = pGCPriv->wrapOps;\
+ (x)->funcs = pGCPriv->wrapFuncs;
+
+#define GC_SCREEN register ScrnInfoPtr pScrn \
+ = xf86Screens[pGC->pScreen->myNum]
+
+#define ENABLE xf86EnableAccess(xf86Screens[pScreen->myNum])
+#define ENABLE_GC xf86EnableAccess(xf86Screens[pGC->pScreen->myNum])
+
+typedef struct _RACScreen {
+ CreateGCProcPtr CreateGC;
+ CloseScreenProcPtr CloseScreen;
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ SourceValidateProcPtr SourceValidate;
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ CopyWindowProcPtr CopyWindow;
+ ClearToBackgroundProcPtr ClearToBackground;
+ BSFuncRec BackingStoreFuncs;
+ CreatePixmapProcPtr CreatePixmap;
+ SaveScreenProcPtr SaveScreen;
+ /* Colormap */
+ StoreColorsProcPtr StoreColors;
+ /* Cursor */
+ DisplayCursorProcPtr DisplayCursor;
+ RealizeCursorProcPtr RealizeCursor;
+ UnrealizeCursorProcPtr UnrealizeCursor;
+ RecolorCursorProcPtr RecolorCursor;
+ SetCursorPositionProcPtr SetCursorPosition;
+ void (*AdjustFrame)(int,int,int,int);
+ Bool (*SwitchMode)(int, DisplayModePtr,int);
+ Bool (*EnterVT)(int, int);
+ void (*LeaveVT)(int, int);
+ void (*FreeScreen)(int, int);
+ miPointerSpriteFuncPtr miSprite;
+} RACScreenRec, *RACScreenPtr;
+
+typedef struct _RACGC {
+ GCOps *wrapOps;
+ GCFuncs *wrapFuncs;
+} RACGCRec, *RACGCPtr;
+
+/* Screen funcs */
+static Bool RACCloseScreen (int i, ScreenPtr pScreen);
+static void RACGetImage (DrawablePtr pDrawable, int sx, int sy,
+ int w, int h, unsigned int format,
+ unsigned long planemask, char *pdstLine);
+static void RACGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
+ int *pwidth, int nspans, char *pdstStart);
+static void RACSourceValidate (DrawablePtr pDrawable,
+ int x, int y, int width, int height );
+static void RACPaintWindowBackground(WindowPtr pWin, RegionPtr prgn, int what);
+static void RACPaintWindowBorder(WindowPtr pWin, RegionPtr prgn, int what);
+static void RACCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc );
+static void RACClearToBackground (WindowPtr pWin, int x, int y,
+ int w, int h, Bool generateExposures );
+static void RACSaveAreas (PixmapPtr pPixmap, RegionPtr prgnSave,
+ int xorg, int yorg, WindowPtr pWin);
+static void RACRestoreAreas (PixmapPtr pPixmap, RegionPtr prgnRestore,
+ int xorg, int yorg, WindowPtr pWin);
+static PixmapPtr RACCreatePixmap(ScreenPtr pScreen, int w, int h, int depth);
+static Bool RACCreateGC(GCPtr pGC);
+static Bool RACSaveScreen(ScreenPtr pScreen, Bool unblank);
+static void RACStoreColors (ColormapPtr pmap, int ndef, xColorItem *pdefs);
+static void RACRecolorCursor (ScreenPtr pScreen, CursorPtr pCurs,
+ Bool displayed);
+static Bool RACRealizeCursor (ScreenPtr pScreen, CursorPtr pCursor);
+static Bool RACUnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor);
+static Bool RACDisplayCursor (ScreenPtr pScreen, CursorPtr pCursor);
+static Bool RACSetCursorPosition (ScreenPtr pScreen, int x, int y,
+ Bool generateEvent);
+static void RACAdjustFrame(int index, int x, int y, int flags);
+static Bool RACSwitchMode(int index, DisplayModePtr mode, int flags);
+static Bool RACEnterVT(int index, int flags);
+static void RACLeaveVT(int index, int flags);
+static void RACFreeScreen(int index, int flags);
+/* GC funcs */
+static void RACValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDraw);
+static void RACChangeGC(GCPtr pGC, unsigned long mask);
+static void RACCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
+static void RACDestroyGC(GCPtr pGC);
+static void RACChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
+static void RACDestroyClip(GCPtr pGC);
+static void RACCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
+/* GC ops */
+static void RACFillSpans( DrawablePtr pDraw, GC *pGC, int nInit,
+ DDXPointPtr pptInit, int *pwidthInit, int fSorted );
+static void RACSetSpans(DrawablePtr pDraw, GCPtr pGC, char *pcharsrc,
+ register DDXPointPtr ppt, int *pwidth, int nspans,
+ int fSorted );
+static void RACPutImage(DrawablePtr pDraw, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad,
+ int format, char *pImage );
+static RegionPtr RACCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
+ GC *pGC, int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty );
+static RegionPtr RACCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
+ GCPtr pGC, int srcx, int srcy,
+ int width, int height, int dstx, int dsty,
+ unsigned long bitPlane );
+static void RACPolyPoint(DrawablePtr pDraw, GCPtr pGC, int mode,
+ int npt, xPoint *pptInit );
+static void RACPolylines(DrawablePtr pDraw, GCPtr pGC, int mode,
+ int npt, DDXPointPtr pptInit );
+static void RACPolySegment(DrawablePtr pDraw, GCPtr pGC, int nseg,
+ xSegment *pSeg );
+static void RACPolyRectangle(DrawablePtr pDraw, GCPtr pGC, int nRectsInit,
+ xRectangle *pRectsInit );
+static void RACPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs,
+ xArc *parcs );
+static void RACFillPolygon(DrawablePtr pDraw, GCPtr pGC, int shape, int mode,
+ int count, DDXPointPtr ptsIn );
+static void RACPolyFillRect( DrawablePtr pDraw, GCPtr pGC, int nrectFill,
+ xRectangle *prectInit );
+static void RACPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs,
+ xArc *parcs );
+static int RACPolyText8(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, char *chars );
+static int RACPolyText16(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars );
+static void RACImageText8(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, char *chars );
+static void RACImageText16(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars );
+static void RACImageGlyphBlt(DrawablePtr pDraw, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase );
+static void RACPolyGlyphBlt(DrawablePtr pDraw, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase );
+static void RACPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDraw,
+ int dx, int dy, int xOrg, int yOrg );
+/* miSpriteFuncs */
+static Bool RACSpriteRealizeCursor(ScreenPtr pScreen, CursorPtr pCur);
+static Bool RACSpriteUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCur);
+static void RACSpriteSetCursor(ScreenPtr pScreen, CursorPtr pCur,
+ int x, int y);
+static void RACSpriteMoveCursor(ScreenPtr pScreen, int x, int y);
+
+GCFuncs RACGCFuncs = {
+ RACValidateGC, RACChangeGC, RACCopyGC, RACDestroyGC,
+ RACChangeClip, RACDestroyClip, RACCopyClip
+};
+
+GCOps RACGCOps = {
+ RACFillSpans, RACSetSpans, RACPutImage, RACCopyArea,
+ RACCopyPlane, RACPolyPoint, RACPolylines, RACPolySegment,
+ RACPolyRectangle, RACPolyArc, RACFillPolygon, RACPolyFillRect,
+ RACPolyFillArc, RACPolyText8, RACPolyText16, RACImageText8,
+ RACImageText16, RACImageGlyphBlt, RACPolyGlyphBlt, RACPushPixels,
+#ifdef NEED_LINEHELPER
+ NULL,
+#endif
+ {NULL} /* devPrivate */
+};
+
+miPointerSpriteFuncRec RACSpriteFuncs = {
+ RACSpriteRealizeCursor, RACSpriteUnrealizeCursor, RACSpriteSetCursor,
+ RACSpriteMoveCursor
+};
+
+int RACScreenIndex = -1;
+int RACGCIndex = -1;
+static unsigned long RACGeneration = 0;
+
+
+Bool
+xf86RACInit(ScreenPtr pScreen, unsigned int flag)
+{
+ ScrnInfoPtr pScrn;
+ RACScreenPtr pScreenPriv;
+ miPointerScreenPtr PointPriv;
+
+ pScrn = xf86Screens[pScreen->myNum];
+ PointPriv = (miPointerScreenPtr)pScreen->devPrivates[miPointerScreenIndex].ptr;
+
+ DPRINT_S("RACInit",pScreen->myNum);
+ if (RACGeneration != serverGeneration) {
+ if ( ((RACScreenIndex = AllocateScreenPrivateIndex()) < 0) ||
+ ((RACGCIndex = AllocateGCPrivateIndex()) < 0))
+ return FALSE;
+
+ RACGeneration = serverGeneration;
+ }
+
+ if (!AllocateGCPrivate(pScreen, RACGCIndex, sizeof(RACGCRec)))
+ return FALSE;
+
+ if (!(pScreenPriv = xalloc(sizeof(RACScreenRec))))
+ return FALSE;
+
+ pScreen->devPrivates[RACScreenIndex].ptr = (pointer)pScreenPriv;
+
+ WRAP_SCREEN(CloseScreen, RACCloseScreen);
+ WRAP_SCREEN(SaveScreen, RACSaveScreen);
+ WRAP_SCREEN_COND(CreateGC, RACCreateGC, RAC_FB);
+ WRAP_SCREEN_COND(GetImage, RACGetImage, RAC_FB);
+ WRAP_SCREEN_COND(GetSpans, RACGetSpans, RAC_FB);
+ WRAP_SCREEN_COND(SourceValidate, RACSourceValidate, RAC_FB);
+ WRAP_SCREEN_COND(PaintWindowBackground, RACPaintWindowBackground, RAC_FB);
+ WRAP_SCREEN_COND(PaintWindowBorder, RACPaintWindowBorder, RAC_FB);
+ WRAP_SCREEN_COND(CopyWindow, RACCopyWindow, RAC_FB);
+ WRAP_SCREEN_COND(ClearToBackground, RACClearToBackground, RAC_FB);
+ WRAP_SCREEN_COND(CreatePixmap, RACCreatePixmap, RAC_FB);
+ WRAP_SCREEN_COND(BackingStoreFuncs.RestoreAreas, RACRestoreAreas, RAC_FB);
+ WRAP_SCREEN_COND(BackingStoreFuncs.SaveAreas, RACSaveAreas, RAC_FB);
+ WRAP_SCREEN_COND(StoreColors, RACStoreColors, RAC_COLORMAP);
+ WRAP_SCREEN_COND(DisplayCursor, RACDisplayCursor, RAC_CURSOR);
+ WRAP_SCREEN_COND(RealizeCursor, RACRealizeCursor, RAC_CURSOR);
+ WRAP_SCREEN_COND(UnrealizeCursor, RACUnrealizeCursor, RAC_CURSOR);
+ WRAP_SCREEN_COND(RecolorCursor, RACRecolorCursor, RAC_CURSOR);
+ WRAP_SCREEN_COND(SetCursorPosition, RACSetCursorPosition, RAC_CURSOR);
+ WRAP_SCREEN_INFO_COND(AdjustFrame, RACAdjustFrame, RAC_VIEWPORT);
+ WRAP_SCREEN_INFO(SwitchMode, RACSwitchMode);
+ WRAP_SCREEN_INFO(EnterVT, RACEnterVT);
+ WRAP_SCREEN_INFO(LeaveVT, RACLeaveVT);
+ WRAP_SCREEN_INFO(FreeScreen, RACFreeScreen);
+ WRAP_SPRITE_COND(RAC_CURSOR);
+
+ return TRUE;
+}
+
+/* Screen funcs */
+static Bool
+RACCloseScreen (int i, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RACScreenPtr pScreenPriv =
+ (RACScreenPtr) pScreen->devPrivates[RACScreenIndex].ptr;
+ miPointerScreenPtr PointPriv
+ = (miPointerScreenPtr)pScreen->devPrivates[miPointerScreenIndex].ptr;
+
+ DPRINT_S("RACCloseScreen",pScreen->myNum);
+ UNWRAP_SCREEN(CreateGC);
+ UNWRAP_SCREEN(CloseScreen);
+ UNWRAP_SCREEN(GetImage);
+ UNWRAP_SCREEN(GetSpans);
+ UNWRAP_SCREEN(SourceValidate);
+ UNWRAP_SCREEN(PaintWindowBackground);
+ UNWRAP_SCREEN(PaintWindowBorder);
+ UNWRAP_SCREEN(CopyWindow);
+ UNWRAP_SCREEN(ClearToBackground);
+ UNWRAP_SCREEN(BackingStoreFuncs.RestoreAreas);
+ UNWRAP_SCREEN(BackingStoreFuncs.SaveAreas);
+ UNWRAP_SCREEN(SaveScreen);
+ UNWRAP_SCREEN(StoreColors);
+ UNWRAP_SCREEN(DisplayCursor);
+ UNWRAP_SCREEN(RealizeCursor);
+ UNWRAP_SCREEN(UnrealizeCursor);
+ UNWRAP_SCREEN(RecolorCursor);
+ UNWRAP_SCREEN(SetCursorPosition);
+ UNWRAP_SCREEN_INFO(AdjustFrame);
+ UNWRAP_SCREEN_INFO(SwitchMode);
+ UNWRAP_SCREEN_INFO(EnterVT);
+ UNWRAP_SCREEN_INFO(LeaveVT);
+ UNWRAP_SCREEN_INFO(FreeScreen);
+ UNWRAP_SPRITE;
+
+ xfree ((pointer) pScreenPriv);
+
+ if (xf86Screens[pScreen->myNum]->vtSema) {
+ xf86EnterServerState(SETUP);
+ ENABLE;
+ }
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+static void
+RACGetImage (
+ DrawablePtr pDrawable,
+ int sx, int sy, int w, int h,
+ unsigned int format,
+ unsigned long planemask,
+ char *pdstLine
+ )
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ DPRINT_S("RACGetImage",pScreen->myNum);
+ SCREEN_PROLOG(GetImage);
+ if (xf86Screens[pScreen->myNum]->vtSema &&
+ (pDrawable->type == DRAWABLE_WINDOW)) {
+ ENABLE;
+ }
+ (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
+ format, planemask, pdstLine);
+ SCREEN_EPILOG (GetImage, RACGetImage);
+}
+
+static void
+RACGetSpans (
+ DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pdstStart
+ )
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+
+ DPRINT_S("RACGetSpans",pScreen->myNum);
+ SCREEN_PROLOG (GetSpans);
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ ENABLE;
+ }
+ (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+ SCREEN_EPILOG (GetSpans, RACGetSpans);
+}
+
+static void
+RACSourceValidate (
+ DrawablePtr pDrawable,
+ int x, int y, int width, int height )
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ DPRINT_S("RACSourceValidate",pScreen->myNum);
+ SCREEN_PROLOG (SourceValidate);
+ ENABLE;
+ if (pScreen->SourceValidate)
+ (*pScreen->SourceValidate) (pDrawable, x, y, width, height);
+ SCREEN_EPILOG (SourceValidate, RACSourceValidate);
+}
+
+static void
+RACPaintWindowBackground(
+ WindowPtr pWin,
+ RegionPtr prgn,
+ int what
+ )
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ DPRINT_S("RACPaintWindowBackground",pScreen->myNum);
+ SCREEN_PROLOG (PaintWindowBackground);
+ ENABLE;
+ (*pScreen->PaintWindowBackground) (pWin, prgn, what);
+ SCREEN_EPILOG (PaintWindowBackground, RACPaintWindowBackground);
+}
+
+static void
+RACPaintWindowBorder(
+ WindowPtr pWin,
+ RegionPtr prgn,
+ int what
+)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ DPRINT_S("RACPaintWindowBorder",pScreen->myNum);
+ SCREEN_PROLOG (PaintWindowBorder);
+ ENABLE;
+ (*pScreen->PaintWindowBorder) (pWin, prgn, what);
+ SCREEN_EPILOG (PaintWindowBorder, RACPaintWindowBorder);
+}
+
+static void
+RACCopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc )
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ DPRINT_S("RACCopyWindow",pScreen->myNum);
+ SCREEN_PROLOG (CopyWindow);
+ ENABLE;
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
+ SCREEN_EPILOG (CopyWindow, RACCopyWindow);
+}
+
+static void
+RACClearToBackground (
+ WindowPtr pWin,
+ int x, int y,
+ int w, int h,
+ Bool generateExposures )
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ DPRINT_S("RACClearToBackground",pScreen->myNum);
+ SCREEN_PROLOG ( ClearToBackground);
+ ENABLE;
+ (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
+ SCREEN_EPILOG (ClearToBackground, RACClearToBackground);
+}
+
+static void
+RACSaveAreas (
+ PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+ )
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ DPRINT_S("RACSaveAreas",pScreen->myNum);
+ SCREEN_PROLOG (BackingStoreFuncs.SaveAreas);
+ ENABLE;
+ (*pScreen->BackingStoreFuncs.SaveAreas) (
+ pPixmap, prgnSave, xorg, yorg, pWin);
+
+ SCREEN_EPILOG (BackingStoreFuncs.SaveAreas, RACSaveAreas);
+}
+
+static void
+RACRestoreAreas (
+ PixmapPtr pPixmap,
+ RegionPtr prgnRestore,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+ )
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+
+ DPRINT_S("RACRestoreAreas",pScreen->myNum);
+ SCREEN_PROLOG (BackingStoreFuncs.RestoreAreas);
+ ENABLE;
+ (*pScreen->BackingStoreFuncs.RestoreAreas) (
+ pPixmap, prgnRestore, xorg, yorg, pWin);
+
+ SCREEN_EPILOG ( BackingStoreFuncs.RestoreAreas, RACRestoreAreas);
+}
+
+static PixmapPtr
+RACCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
+{
+ PixmapPtr pPix;
+
+ DPRINT_S("RACCreatePixmap",pScreen->myNum);
+ SCREEN_PROLOG ( CreatePixmap);
+ ENABLE;
+ pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth);
+ SCREEN_EPILOG (CreatePixmap, RACCreatePixmap);
+
+ return pPix;
+}
+
+static Bool
+RACSaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+ Bool val;
+
+ DPRINT_S("RACSaveScreen",pScreen->myNum);
+ SCREEN_PROLOG (SaveScreen);
+ ENABLE;
+ val = (*pScreen->SaveScreen) (pScreen, unblank);
+ SCREEN_EPILOG (SaveScreen, RACSaveScreen);
+
+ return val;
+}
+
+static void
+RACStoreColors (
+ ColormapPtr pmap,
+ int ndef,
+ xColorItem *pdefs)
+{
+ ScreenPtr pScreen = pmap->pScreen;
+
+ DPRINT_S("RACStoreColors",pScreen->myNum);
+ SCREEN_PROLOG (StoreColors);
+ ENABLE;
+ (*pScreen->StoreColors) (pmap,ndef,pdefs);
+
+ SCREEN_EPILOG ( StoreColors, RACStoreColors);
+}
+
+static void
+RACRecolorCursor (
+ ScreenPtr pScreen,
+ CursorPtr pCurs,
+ Bool displayed
+ )
+{
+ DPRINT_S("RACRecolorCursor",pScreen->myNum);
+ SCREEN_PROLOG (RecolorCursor);
+ ENABLE;
+ (*pScreen->RecolorCursor) (pScreen,pCurs,displayed);
+
+ SCREEN_EPILOG ( RecolorCursor, RACRecolorCursor);
+}
+
+static Bool
+RACRealizeCursor (
+ ScreenPtr pScreen,
+ CursorPtr pCursor
+ )
+{
+ Bool val;
+
+ DPRINT_S("RACRealizeCursor",pScreen->myNum);
+ SCREEN_PROLOG (RealizeCursor);
+ ENABLE;
+ val = (*pScreen->RealizeCursor) (pScreen,pCursor);
+
+ SCREEN_EPILOG ( RealizeCursor, RACRealizeCursor);
+ return val;
+}
+
+static Bool
+RACUnrealizeCursor (
+ ScreenPtr pScreen,
+ CursorPtr pCursor
+ )
+{
+ Bool val;
+
+ DPRINT_S("RACUnrealizeCursor",pScreen->myNum);
+ SCREEN_PROLOG (UnrealizeCursor);
+ ENABLE;
+ val = (*pScreen->UnrealizeCursor) (pScreen,pCursor);
+
+ SCREEN_EPILOG ( UnrealizeCursor, RACUnrealizeCursor);
+ return val;
+}
+
+static Bool
+RACDisplayCursor (
+ ScreenPtr pScreen,
+ CursorPtr pCursor
+ )
+{
+ Bool val;
+
+ DPRINT_S("RACDisplayCursor",pScreen->myNum);
+ SCREEN_PROLOG (DisplayCursor);
+ ENABLE;
+ val = (*pScreen->DisplayCursor) (pScreen,pCursor);
+
+ SCREEN_EPILOG ( DisplayCursor, RACDisplayCursor);
+ return val;
+}
+
+static Bool
+RACSetCursorPosition (
+ ScreenPtr pScreen,
+ int x, int y,
+ Bool generateEvent)
+{
+ Bool val;
+
+ DPRINT_S("RACSetCursorPosition",pScreen->myNum);
+ SCREEN_PROLOG (SetCursorPosition);
+ ENABLE;
+ val = (*pScreen->SetCursorPosition) (pScreen,x,y,generateEvent);
+
+ SCREEN_EPILOG ( SetCursorPosition, RACSetCursorPosition);
+ return val;
+}
+
+static void
+RACAdjustFrame(int index, int x, int y, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ RACScreenPtr pScreenPriv =
+ (RACScreenPtr) pScreen->devPrivates[RACScreenIndex].ptr;
+
+ DPRINT_S("RACAdjustFrame",index);
+ xf86EnableAccess(xf86Screens[index]);
+
+ (*pScreenPriv->AdjustFrame)(index, x, y, flags);
+}
+
+static Bool
+RACSwitchMode(int index, DisplayModePtr mode, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ RACScreenPtr pScreenPriv =
+ (RACScreenPtr) pScreen->devPrivates[RACScreenIndex].ptr;
+
+ DPRINT_S("RACSwitchMode",index);
+ xf86EnableAccess(xf86Screens[index]);
+
+ return (*pScreenPriv->SwitchMode)(index, mode, flags);
+}
+
+static Bool
+RACEnterVT(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ RACScreenPtr pScreenPriv =
+ (RACScreenPtr) pScreen->devPrivates[RACScreenIndex].ptr;
+
+ DPRINT_S("RACEnterVT",index);
+ xf86EnableAccess(xf86Screens[index]);
+
+ return (*pScreenPriv->EnterVT)(index, flags);
+}
+
+static void
+RACLeaveVT(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ RACScreenPtr pScreenPriv =
+ (RACScreenPtr) pScreen->devPrivates[RACScreenIndex].ptr;
+
+ DPRINT_S("RACLeaveVT",index);
+ xf86EnableAccess(xf86Screens[index]);
+
+ (*pScreenPriv->LeaveVT)(index, flags);
+}
+
+static void
+RACFreeScreen(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ RACScreenPtr pScreenPriv =
+ (RACScreenPtr) pScreen->devPrivates[RACScreenIndex].ptr;
+
+ DPRINT_S("RACFreeScreen",index);
+ xf86EnableAccess(xf86Screens[index]);
+
+ (*pScreenPriv->FreeScreen)(index, flags);
+}
+
+static Bool
+RACCreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ RACGCPtr pGCPriv = (RACGCPtr) (pGC)->devPrivates[RACGCIndex].ptr;
+ Bool ret;
+
+ DPRINT_S("RACCreateGC",pScreen->myNum);
+ SCREEN_PROLOG(CreateGC);
+
+ ret = (*pScreen->CreateGC)(pGC);
+
+ GC_WRAP(pGC);
+ SCREEN_EPILOG(CreateGC,RACCreateGC);
+
+ return ret;
+}
+
+/* GC funcs */
+static void
+RACValidateGC(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ GC_UNWRAP(pGC);
+ DPRINT("RACValidateGC");
+ (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
+ GC_WRAP(pGC);
+}
+
+
+static void
+RACDestroyGC(GCPtr pGC)
+{
+ GC_UNWRAP (pGC);
+ DPRINT("RACDestroyGC");
+ (*pGC->funcs->DestroyGC)(pGC);
+ GC_WRAP (pGC);
+}
+
+static void
+RACChangeGC (
+ GCPtr pGC,
+ unsigned long mask)
+{
+ GC_UNWRAP (pGC);
+ DPRINT("RACChangeGC");
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ GC_WRAP (pGC);
+}
+
+static void
+RACCopyGC (
+ GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst)
+{
+ GC_UNWRAP (pGCDst);
+ DPRINT("RACCopyGC");
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ GC_WRAP (pGCDst);
+}
+
+static void
+RACChangeClip (
+ GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects )
+{
+ GC_UNWRAP (pGC);
+ DPRINT("RACChangeClip");
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ GC_WRAP (pGC);
+}
+
+static void
+RACCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ GC_UNWRAP (pgcDst);
+ DPRINT("RACCopyClip");
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ GC_WRAP (pgcDst);
+}
+
+static void
+RACDestroyClip(GCPtr pGC)
+{
+ GC_UNWRAP (pGC);
+ DPRINT("RACDestroyClip");
+ (* pGC->funcs->DestroyClip)(pGC);
+ GC_WRAP (pGC);
+}
+
+/* GC Ops */
+static void
+RACFillSpans(
+ DrawablePtr pDraw,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted )
+{
+ GC_UNWRAP(pGC);
+ DPRINT("RACFillSpans");
+ ENABLE_GC;
+ (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
+ GC_WRAP(pGC);
+}
+
+static void
+RACSetSpans(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ char *pcharsrc,
+ register DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted )
+{
+ GC_UNWRAP(pGC);
+ DPRINT("RACSetSpans");
+ ENABLE_GC;
+ (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
+ GC_WRAP(pGC);
+}
+
+static void
+RACPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage )
+{
+ GC_UNWRAP(pGC);
+ DPRINT("RACPutImage");
+ ENABLE_GC;
+ (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+ GC_WRAP(pGC);
+}
+
+static RegionPtr
+RACCopyArea(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty )
+{
+ RegionPtr ret;
+
+ GC_UNWRAP(pGC);
+ DPRINT("RACCopyArea");
+ if ((pSrc->type == DRAWABLE_WINDOW) || (pDst->type == DRAWABLE_WINDOW)) {
+ ENABLE_GC;
+ }
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ GC_WRAP(pGC);
+ return ret;
+}
+
+static RegionPtr
+RACCopyPlane(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane )
+{
+ RegionPtr ret;
+
+ GC_UNWRAP(pGC);
+ DPRINT("RACCopyPlane");
+ if ((pSrc->type == DRAWABLE_WINDOW) || (pDst->type == DRAWABLE_WINDOW)) {
+ ENABLE_GC;
+ }
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC, srcx, srcy,
+ width, height, dstx, dsty, bitPlane);
+ GC_WRAP(pGC);
+ return ret;
+}
+
+static void
+RACPolyPoint(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit )
+{
+ GC_UNWRAP(pGC);
+ DPRINT("RACPolyPoint");
+ ENABLE_GC;
+ (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
+ GC_WRAP(pGC);
+}
+
+
+static void
+RACPolylines(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit )
+{
+ GC_UNWRAP(pGC);
+ DPRINT("RACPolylines");
+ ENABLE_GC;
+ (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
+ GC_WRAP(pGC);
+}
+
+static void
+RACPolySegment(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg )
+{
+ GC_UNWRAP(pGC);
+ DPRINT("RACPolySegment");
+ ENABLE_GC;
+ (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
+ GC_WRAP(pGC);
+}
+
+static void
+RACPolyRectangle(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit )
+{
+ GC_UNWRAP(pGC);
+ DPRINT("RACPolyRectangle");
+ ENABLE_GC;
+ (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
+ GC_WRAP(pGC);
+}
+
+static void
+RACPolyArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs )
+{
+ GC_UNWRAP(pGC);
+ DPRINT("RACPolyArc");
+ ENABLE_GC;
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
+ GC_WRAP(pGC);
+}
+
+static void
+RACFillPolygon(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn )
+{
+ GC_UNWRAP(pGC);
+ DPRINT("RACFillPolygon");
+ ENABLE_GC;
+ (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
+ GC_WRAP(pGC);
+}
+
+
+static void
+RACPolyFillRect(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit )
+{
+ GC_UNWRAP(pGC);
+ DPRINT("RACPolyFillRect");
+ ENABLE_GC;
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
+ GC_WRAP(pGC);
+}
+
+
+static void
+RACPolyFillArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs )
+{
+ GC_UNWRAP(pGC);
+ DPRINT("RACPolyFillArc");
+ ENABLE_GC;
+ (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
+ GC_WRAP(pGC);
+}
+
+static int
+RACPolyText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars )
+{
+ int ret;
+
+ GC_UNWRAP(pGC);
+ DPRINT("RACPolyText8");
+ ENABLE_GC;
+ ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
+ GC_WRAP(pGC);
+ return ret;
+}
+
+static int
+RACPolyText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars )
+{
+ int ret;
+
+ GC_UNWRAP(pGC);
+ DPRINT("RACPolyText16");
+ ENABLE_GC;
+ ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
+ GC_WRAP(pGC);
+ return ret;
+}
+
+static void
+RACImageText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars )
+{
+ GC_UNWRAP(pGC);
+ DPRINT("RACImageText8");
+ ENABLE_GC;
+ (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
+ GC_WRAP(pGC);
+}
+
+static void
+RACImageText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars )
+{
+ GC_UNWRAP(pGC);
+ DPRINT("RACImageText16");
+ ENABLE_GC;
+ (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
+ GC_WRAP(pGC);
+}
+
+
+static void
+RACImageGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase )
+{
+ GC_UNWRAP(pGC);
+ DPRINT("RACImageGlyphBlt");
+ ENABLE_GC;
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit,
+ nglyph, ppci, pglyphBase);
+ GC_WRAP(pGC);
+}
+
+static void
+RACPolyGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase )
+{
+ GC_UNWRAP(pGC);
+ DPRINT("RACPolyGlyphBlt");
+ ENABLE_GC;
+ (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit,
+ nglyph, ppci, pglyphBase);
+ GC_WRAP(pGC);
+}
+
+static void
+RACPushPixels(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy, int xOrg, int yOrg )
+{
+ GC_UNWRAP(pGC);
+ DPRINT("RACPushPixels");
+ ENABLE_GC;
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+ GC_WRAP(pGC);
+}
+
+
+/* miSpriteFuncs */
+static Bool
+RACSpriteRealizeCursor(ScreenPtr pScreen, CursorPtr pCur)
+{
+ Bool val;
+ SPRITE_PROLOG;
+ DPRINT_S("RACSpriteRealizeCursor",pScreen->myNum);
+ ENABLE;
+ val = PointPriv->spriteFuncs->RealizeCursor(pScreen, pCur);
+ SPRITE_EPILOG;
+ return val;
+}
+
+static Bool
+RACSpriteUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCur)
+{
+ Bool val;
+ SPRITE_PROLOG;
+ DPRINT_S("RACSpriteUnrealizeCursor",pScreen->myNum);
+ ENABLE;
+ val = PointPriv->spriteFuncs->UnrealizeCursor(pScreen, pCur);
+ SPRITE_EPILOG;
+ return val;
+}
+
+static void
+RACSpriteSetCursor(ScreenPtr pScreen, CursorPtr pCur, int x, int y)
+{
+ SPRITE_PROLOG;
+ DPRINT_S("RACSpriteSetCursor",pScreen->myNum);
+ ENABLE;
+ PointPriv->spriteFuncs->SetCursor(pScreen, pCur, x, y);
+ SPRITE_EPILOG;
+}
+
+static void
+RACSpriteMoveCursor(ScreenPtr pScreen, int x, int y)
+{
+ SPRITE_PROLOG;
+ DPRINT_S("RACSpriteMoveCursor",pScreen->myNum);
+ ENABLE;
+ PointPriv->spriteFuncs->MoveCursor(pScreen, x, y);
+ SPRITE_EPILOG;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/rac/xf86RAC.h b/xc/programs/Xserver/hw/xfree86/rac/xf86RAC.h
new file mode 100644
index 000000000..c704bd75e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/rac/xf86RAC.h
@@ -0,0 +1,18 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/rac/xf86RAC.h,v 1.3 1999/06/12 07:19:05 dawes Exp $ */
+
+#ifndef __XF86RAC_H
+#define __XF86RAC_H 1
+
+#include "screenint.h"
+#include "misc.h"
+#include "xf86.h"
+
+Bool xf86RACInit(ScreenPtr pScreen, unsigned int flag);
+
+/* flags */
+#define RAC_FB 0x01
+#define RAC_CURSOR 0x02
+#define RAC_COLORMAP 0x04
+#define RAC_VIEWPORT 0x08
+
+#endif /* __XF86RAC_H */
diff --git a/xc/programs/Xserver/hw/xfree86/rac/xf86RACmodule.c b/xc/programs/Xserver/hw/xfree86/rac/xf86RACmodule.c
new file mode 100644
index 000000000..f0a960a66
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/rac/xf86RACmodule.c
@@ -0,0 +1,21 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/rac/xf86RACmodule.c,v 1.4 1999/01/26 05:54:14 dawes Exp $ */
+
+#include "xf86Module.h"
+
+static XF86ModuleVersionInfo racVersRec =
+{
+ "rac",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_VIDEODRV, /* requires the video driver ABI */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0}
+};
+
+
+XF86ModuleData racModuleData = { &racVersRec, NULL, NULL };
+
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/BT.c b/xc/programs/Xserver/hw/xfree86/ramdac/BT.c
new file mode 100644
index 000000000..b0531c7eb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/BT.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright 1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * BT RAMDAC routines.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/BT.c,v 1.6 1999/01/17 10:54:13 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#define INIT_BT_RAMDAC_INFO
+#include "BTPriv.h"
+#include "xf86RamDacPriv.h"
+
+void
+BTramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
+ RamDacRegRecPtr ramdacReg)
+{
+ int i;
+
+ /* Here we pass a short, so that we can evaluate a mask too */
+ /* So that the mask is the high byte and the data the low byte */
+ /* Just the command/status registers */
+ for (i=0x06;i<0x0A;i++)
+ (*ramdacPtr->WriteDAC)
+ (pScrn, i, (ramdacReg->DacRegs[i] & 0xFF00) >> 8,
+ ramdacReg->DacRegs[i]);
+}
+
+void
+BTramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
+ RamDacRegRecPtr ramdacReg)
+{
+ int i;
+
+ (*ramdacPtr->ReadAddress)(pScrn, 0); /* Start at index 0 */
+ for (i=0;i<768;i++)
+ ramdacReg->DAC[i] = (*ramdacPtr->ReadData)(pScrn);
+
+ /* Just the command/status registers */
+ for (i=0x06;i<0x0A;i++)
+ ramdacReg->DacRegs[i] = (*ramdacPtr->ReadDAC)(pScrn, i);
+}
+
+RamDacHelperRecPtr
+BTramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs/*, RamDacRecPtr ramdacPtr*/)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+ Bool RamDacIsSupported = FALSE;
+ RamDacHelperRecPtr ramdacHelperPtr = NULL;
+ int BTramdac_ID = -1;
+ int i, status, cmd0;
+
+ /* Save COMMAND Register 0 */
+ cmd0 = (*ramdacPtr->ReadDAC)(pScrn, BT_COMMAND_REG_0);
+ /* Ensure were going to access the STATUS Register on next read */
+ (*ramdacPtr->WriteDAC)(pScrn, BT_COMMAND_REG_0, 0x7F, 0x00);
+
+ status = (*ramdacPtr->ReadDAC)(pScrn, BT_STATUS_REG);
+ switch (status) {
+ case 0x40:
+ BTramdac_ID = ATT20C504_RAMDAC;
+ break;
+ case 0xD0:
+ BTramdac_ID = ATT20C505_RAMDAC;
+ break;
+ case 0x80:
+ case 0x90:
+ case 0xA0:
+ case 0xB0:
+ case 0x28: /* This is for the DEC TGA - Questionable ? */
+ BTramdac_ID = BT485_RAMDAC;
+ break;
+ }
+
+ /* Restore COMMAND Register 0 */
+ (*ramdacPtr->WriteDAC)(pScrn, BT_COMMAND_REG_0, 0x00, cmd0);
+
+ if (BTramdac_ID == -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Cannot determine BT RAMDAC type, aborting\n");
+ return NULL;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Attached RAMDAC is %s\n", BTramdacDeviceInfo[BTramdac_ID&0xFFFF]);
+ }
+
+ for (i=0;ramdacs[i].token != -1;i++) {
+ if (ramdacs[i].token == BTramdac_ID)
+ RamDacIsSupported = TRUE;
+ }
+
+ if (!RamDacIsSupported) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "This BT RAMDAC is NOT supported by this driver, aborting\n");
+ return NULL;
+ }
+
+ ramdacHelperPtr = RamDacHelperCreateInfoRec();
+ switch(BTramdac_ID) {
+ case BT485_RAMDAC:
+ ramdacHelperPtr->SetBpp = BTramdacSetBpp;
+ break;
+ }
+ ramdacPtr->RamDacType = BTramdac_ID;
+ ramdacHelperPtr->RamDacType = BTramdac_ID;
+ ramdacHelperPtr->Save = BTramdacSave;
+ ramdacHelperPtr->Restore = BTramdacRestore;
+
+ return ramdacHelperPtr;
+}
+
+void
+BTramdacSetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
+{
+ /* We need to deal with Direct Colour visuals for 8bpp and other
+ * good stuff for colours */
+ switch (pScrn->bitsPerPixel) {
+ case 32:
+ ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x10;
+ break;
+ case 24:
+ ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x10;
+ break;
+ case 16:
+ ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x38;
+ break;
+ case 15:
+ ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x30;
+ break;
+ case 8:
+ ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x40;
+ break;
+ case 4:
+ ramdacReg->DacRegs[BT_COMMAND_REG_1] = 0x60;
+ break;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/BT.h b/xc/programs/Xserver/hw/xfree86/ramdac/BT.h
new file mode 100644
index 000000000..ea1180285
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/BT.h
@@ -0,0 +1,33 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/BT.h,v 1.3 1998/08/20 08:56:03 dawes Exp $ */
+
+#include "xf86RamDac.h"
+
+RamDacHelperRecPtr BTramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs);
+void BTramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr RamDacRec, RamDacRegRecPtr RamDacRegRec);
+void BTramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr RamDacRec, RamDacRegRecPtr RamDacRegRec);
+void BTramdacSetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr RamDacRegRec);
+
+#define ATT20C504_RAMDAC (VENDOR_BT << 16) | 0x00
+#define ATT20C505_RAMDAC (VENDOR_BT << 16) | 0x01
+#define BT485_RAMDAC (VENDOR_BT << 16) | 0x02
+
+/*
+ * BT registers
+ */
+
+#define BT_WRITE_ADDR 0x00
+#define BT_RAMDAC_DATA 0x01
+#define BT_PIXEL_MASK 0x02
+#define BT_READ_ADDR 0x03
+#define BT_CURS_WR_ADDR 0x04
+#define BT_CURS_DATA 0x05
+#define BT_COMMAND_REG_0 0x06
+#define BT_CURS_RD_ADDR 0x07
+#define BT_COMMAND_REG_1 0x08
+#define BT_COMMAND_REG_2 0x09
+#define BT_STATUS_REG 0x0A
+#define BT_CURS_RAM_DATA 0x0B
+#define BT_CURS_X_LOW 0x0C
+#define BT_CURS_X_HIGH 0x0D
+#define BT_CURS_Y_LOW 0x0E
+#define BT_CURS_Y_HIGH 0x0F
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/BTPriv.h b/xc/programs/Xserver/hw/xfree86/ramdac/BTPriv.h
new file mode 100644
index 000000000..bea623b78
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/BTPriv.h
@@ -0,0 +1,17 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/BTPriv.h,v 1.2 1998/07/25 16:57:18 dawes Exp $ */
+
+#include "BT.h"
+
+typedef struct {
+ char *DeviceName;
+} xf86BTramdacInfo;
+
+extern xf86BTramdacInfo BTramdacDeviceInfo[];
+
+#ifdef INIT_BT_RAMDAC_INFO
+xf86BTramdacInfo BTramdacDeviceInfo[] = {
+ {"AT&T 20C504"},
+ {"AT&T 20C505"},
+ {"BT485/484"}
+};
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/CURSOR.NOTES b/xc/programs/Xserver/hw/xfree86/ramdac/CURSOR.NOTES
new file mode 100644
index 000000000..95749aafd
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/CURSOR.NOTES
@@ -0,0 +1,172 @@
+ CURSOR.NOTES
+
+ This file describes how to add hardware cursor support to a chipset
+driver. Though the cursor support itself is in the ramdac module,
+cursor management is separate from the rest of the module.
+
+
+1) CURSOR INITIALIZATION AND SHUTDOWN
+
+ All relevant prototypes and defines are in xf86Cursor.h.
+
+ To initialize the cursor, the driver should allocate an
+xf86CursorInfoRec via xf86CreateCursorInfoRec(), fill it out as described
+later in this document and pass it to xf86InitCursor(). xf86InitCursor()
+must be called _after_ the software cursor initialization (usually
+miDCInitialize).
+
+ When shutting down, the driver should free the xf86CursorInfoRec
+structure in its CloseScreen function via xf86DestroyCursorInfoRec().
+
+
+2) FILLING OUT THE xf86CursorInfoRec
+
+ The driver informs the ramdac module of it's hardware cursor capablities by
+filling out an xf86CursorInfoRec structure and passing it to xf86InitCursor().
+The xf86CursorInfoRec contains the following function pointers:
+
+
+/**** These functions are required ****/
+
+void ShowCursor(ScrnInfoPtr pScrn)
+
+ ShowCursor should display the current cursor.
+
+void HideCursor(ScrnInfoPtr pScrn)
+
+ HideCursor should hide the current cursor.
+
+void SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+
+ Set the cursor position to (x,y). X and/or y may be negative
+ indicating that the cursor image is partially offscreen on
+ the left and/or top edges of the screen. It is up to the
+ driver to trap for this and deal with that situation.
+
+void SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+
+ Set the cursor foreground and background colors. In 8bpp, fg and
+ bg are indicies into the current colormap unless the
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP flag is set. In that case
+ and in all other bpps the fg and bg are in 8-8-8 RGB format.
+
+void LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits)
+
+ LoadCursorImage is how the hardware cursor bits computed by the
+ RealizeCursor function will be passed to the driver when the cursor
+ shape needs to be changed.
+
+
+/**** These functions are optional ****/
+
+
+unsigned char* RealizeCursor(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
+
+ If RealizeCursor is not provided by the driver, one will be provided
+ for you based on the Flags field described below. The driver must
+ provide this function if the hardware cursor format is not one of
+ the common ones supported by this module.
+
+
+Bool UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+
+ If the driver is unable to use a hardware cursor for reasons
+ other than the cursor being larger than the maximum specified
+ in the MaxWidth or MaxHeight field below, it can supply the
+ UseHWCursor function. If UseHWCursor is provided by the driver,
+ it will be called whenever the cursor shape changes or the video
+ mode changes. This is useful for when the hardware cursor cannot
+ be used in interlaced or doublescan modes.
+
+
+/**** The following fields are required ****/
+
+MaxWidth
+MaxHeight
+
+ These indicate the largest sized cursor that can be a hardware
+ cursor. It will fall back to a software cursor when a cursor
+ exceeding this size needs to be used.
+
+
+Flags
+
+ /* Color related flags */
+
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
+
+ This indicates that the colors passed to the SetCursorColors
+ function should not be in 8-8-8 RGB format in 8bpp but rather,
+ they should be the pixel values from the current colormap.
+
+
+ /* Cursor data packing flags */
+
+ Hardware cursor data consists of two pieces, a source and a mask.
+ The mask is a bitmap indicating which parts of the cursor are
+ transparent and which parts are drawn. The source is a bitmap
+ indicating which parts of the non-transparent portion of the the
+ cursor should be painted in the foreground color and which should
+ be painted in the background color.
+
+ HARDWARE_CURSOR_INVERT_MASK
+
+ By default, set bits indicate the opaque part of the mask bitmap
+ and clear bits indicate the transparent part. If your hardware
+ wants this the opposite way, this flag will invert the mask.
+
+ HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK
+
+ By default, RealizeCursor will store the source first and then
+ the mask. If the hardware needs this order reversed then this
+ flag should be set.
+
+ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK
+
+ This flag will have the module logical AND the source with the mask to make
+ sure there are no source bits set if the corresponding mask bits
+ aren't set. Some hardware will not care if source bits are set where
+ there are supposed to be transparent areas, but some hardware will
+ interpret this as a third cursor color or similar. That type of
+ hardware will need this flag set.
+
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
+
+ By default, it is assumed that the least significant bit in each byte
+ corresponds to the leftmost pixel on the screen. If your hardware
+ has this reversed you should set this flag.
+
+ HARDWARE_CURSOR_NIBBLE_SWAPPED
+
+ If your hardware requires byte swapping of the hardware cursor, enable
+ this option.
+
+
+ /* Source-Mask interleaving flags */
+
+ By default the source and mask data are inlined (source first unless
+ the HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK flag is set). Some hardware
+ will require the source and mask to be interleaved, that is, X number
+ of source bits should packed and then X number of mask bits repeating
+ until the entire pattern is stored. The following flags describe the
+ bit interleave.
+
+ HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED
+
+ This one is the default.
+
+ The following are for interleaved cursors.
+
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64
+
+ And once again, if your hardware requires something different than
+ these packing styles, your driver can supply its own RealizeCursor
+ function.
+
+
+
+$XFree86: xc/programs/Xserver/hw/xfree86/ramdac/CURSOR.NOTES,v 1.3 1999/01/31 12:22:05 dawes Exp $
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/IBM.c b/xc/programs/Xserver/hw/xfree86/ramdac/IBM.c
new file mode 100644
index 000000000..281cb561e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/IBM.c
@@ -0,0 +1,624 @@
+/*
+ * Copyright 1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * IBM RAMDAC routines.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/IBM.c,v 1.10 1999/03/28 15:33:01 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86Cursor.h"
+
+#define INIT_IBM_RAMDAC_INFO
+#include "IBMPriv.h"
+#include "xf86RamDacPriv.h"
+
+#define INITIALFREQERR 100000
+
+unsigned long
+IBMramdac640CalculateMNPCForClock(
+ unsigned long RefClock, /* In 100Hz units */
+ unsigned long ReqClock, /* In 100Hz units */
+ char IsPixClock, /* boolean, is this the pixel or the sys clock */
+ unsigned long MinClock, /* Min VCO rating */
+ unsigned long MaxClock, /* Max VCO rating */
+ unsigned long *rM, /* M Out */
+ unsigned long *rN, /* N Out */
+ unsigned long *rP, /* Min P In, P Out */
+ unsigned long *rC /* C Out */
+)
+{
+ unsigned long M, N, P, iP = *rP;
+ unsigned long IntRef, VCO, Clock;
+ long freqErr, lowestFreqErr = INITIALFREQERR;
+ unsigned long ActualClock = 0;
+
+ for (N = 0; N <= 63; N++)
+ {
+ IntRef = RefClock / (N + 1);
+ if (IntRef < 10000)
+ break; /* IntRef needs to be >= 1MHz */
+ for (M = 2; M <= 127; M++)
+ {
+ VCO = IntRef * (M + 1);
+ if ((VCO < MinClock) || (VCO > MaxClock))
+ continue;
+ for (P = iP; P <= 4; P++)
+ {
+ if (P != 0)
+ Clock = (RefClock * (M + 1)) / ((N + 1) * 2 * P);
+ else
+ Clock = (RefClock * (M + 1)) / (N + 1);
+
+ freqErr = (Clock - ReqClock);
+
+ if (freqErr < 0)
+ {
+ /* PixelClock gets rounded up always so monitor reports
+ correct frequency. */
+ if (IsPixClock)
+ continue;
+ freqErr = -freqErr;
+ }
+
+ if (freqErr < lowestFreqErr)
+ {
+ *rM = M;
+ *rN = N;
+ *rP = P;
+ *rC = (VCO <= 1280000 ? 1 : 2);
+ ActualClock = Clock;
+
+ lowestFreqErr = freqErr;
+ /* Return if we found an exact match */
+ if (freqErr == 0)
+ return (ActualClock);
+ }
+ }
+ }
+ }
+
+ return (ActualClock);
+}
+
+unsigned long
+IBMramdac526CalculateMNPCForClock(
+ unsigned long RefClock, /* In 100Hz units */
+ unsigned long ReqClock, /* In 100Hz units */
+ char IsPixClock, /* boolean, is this the pixel or the sys clock */
+ unsigned long MinClock, /* Min VCO rating */
+ unsigned long MaxClock, /* Max VCO rating */
+ unsigned long *rM, /* M Out */
+ unsigned long *rN, /* N Out */
+ unsigned long *rP, /* Min P In, P Out */
+ unsigned long *rC /* C Out */
+)
+{
+ unsigned long M, N, P, iP = *rP;
+ unsigned long IntRef, VCO, Clock;
+ long freqErr, lowestFreqErr = INITIALFREQERR;
+ unsigned long ActualClock = 0;
+
+ for (N = 0; N <= 63; N++)
+ {
+ IntRef = RefClock / (N + 1);
+ if (IntRef < 10000)
+ break; /* IntRef needs to be >= 1MHz */
+ for (M = 0; M <= 63; M++)
+ {
+ VCO = IntRef * (M + 1);
+ if ((VCO < MinClock) || (VCO > MaxClock))
+ continue;
+ for (P = iP; P <= 4; P++)
+ {
+ if (P)
+ Clock = (RefClock * (M + 1)) / ((N + 1) * 2 * P);
+ else
+ Clock = VCO;
+
+ freqErr = (Clock - ReqClock);
+
+ if (freqErr < 0)
+ {
+ /* PixelClock gets rounded up always so monitor reports
+ correct frequency. */
+ if (IsPixClock)
+ continue;
+ freqErr = -freqErr;
+ }
+
+ if (freqErr < lowestFreqErr)
+ {
+ *rM = M;
+ *rN = N;
+ *rP = P;
+ *rC = (VCO <= 1280000 ? 1 : 2);
+ ActualClock = Clock;
+
+ lowestFreqErr = freqErr;
+ /* Return if we found an exact match */
+ if (freqErr == 0)
+ return (ActualClock);
+ }
+ }
+ }
+ }
+
+ return (ActualClock);
+}
+
+void
+IBMramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
+ RamDacRegRecPtr ramdacReg)
+{
+ int i, maxreg, dacreg;
+
+ switch (ramdacPtr->RamDacType) {
+ case IBM640_RAMDAC:
+ maxreg = 0x300;
+ dacreg = 1024;
+ break;
+ default:
+ maxreg = 0x100;
+ dacreg = 768;
+ break;
+ }
+
+ /* Here we pass a short, so that we can evaluate a mask too */
+ /* So that the mask is the high byte and the data the low byte */
+ for (i=0;i<maxreg;i++)
+ (*ramdacPtr->WriteDAC)
+ (pScrn, i, (ramdacReg->DacRegs[i] & 0xFF00) >> 8,
+ ramdacReg->DacRegs[i]);
+
+ (*ramdacPtr->WriteAddress)(pScrn, 0);
+ for (i=0;i<dacreg;i++)
+ (*ramdacPtr->WriteData)(pScrn, ramdacReg->DAC[i]);
+}
+
+void
+IBMramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
+ RamDacRegRecPtr ramdacReg)
+{
+ int i, maxreg, dacreg;
+
+ switch (ramdacPtr->RamDacType) {
+ case IBM640_RAMDAC:
+ maxreg = 0x300;
+ dacreg = 1024;
+ break;
+ default:
+ maxreg = 0x100;
+ dacreg = 768;
+ break;
+ }
+
+ (*ramdacPtr->ReadAddress)(pScrn, 0);
+ for (i=0;i<dacreg;i++)
+ ramdacReg->DAC[i] = (*ramdacPtr->ReadData)(pScrn);
+
+ for (i=0;i<maxreg;i++)
+ ramdacReg->DacRegs[i] = (*ramdacPtr->ReadDAC)(pScrn, i);
+}
+
+RamDacHelperRecPtr
+IBMramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs/* , RamDacRecPtr ramdacPtr*/)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+ RamDacHelperRecPtr ramdacHelperPtr = NULL;
+ Bool RamDacIsSupported = FALSE;
+ int IBMramdac_ID = -1;
+ int i;
+ unsigned char id, rev, id2, rev2;
+
+ /* read ID and revision */
+ rev = (*ramdacPtr->ReadDAC)(pScrn, IBMRGB_rev);
+ id = (*ramdacPtr->ReadDAC)(pScrn, IBMRGB_id);
+
+ /* check if ID and revision are read only */
+ (*ramdacPtr->WriteDAC)(pScrn, ~rev, 0, IBMRGB_rev);
+ (*ramdacPtr->WriteDAC)(pScrn, ~id, 0, IBMRGB_id);
+ rev2 = (*ramdacPtr->ReadDAC)(pScrn, IBMRGB_rev);
+ id2 = (*ramdacPtr->ReadDAC)(pScrn, IBMRGB_id);
+
+ switch (id) {
+ case 0x30:
+ if (rev == 0xc0) IBMramdac_ID = IBM624_RAMDAC;
+ if (rev == 0x80) IBMramdac_ID = IBM624DB_RAMDAC;
+ break;
+ case 0x12:
+ if (rev == 0x1c) IBMramdac_ID = IBM640_RAMDAC;
+ break;
+ case 0x01:
+ IBMramdac_ID = IBM525_RAMDAC;
+ break;
+ case 0x02:
+ if (rev == 0xf0) IBMramdac_ID = IBM524_RAMDAC;
+ if (rev == 0xe0) IBMramdac_ID = IBM524A_RAMDAC;
+ if (rev == 0xc0) IBMramdac_ID = IBM526_RAMDAC;
+ if (rev == 0x80) IBMramdac_ID = IBM526DB_RAMDAC;
+ break;
+ }
+
+ if (id == 1 || id == 2) {
+ if (id == id2 && rev == rev2) { /* IBM RGB52x found */
+ /* check for 128bit VRAM -> RGB528 */
+ if (((*ramdacPtr->ReadDAC)(pScrn, IBMRGB_misc1) & 0x03) == 0x03) {
+ IBMramdac_ID = IBM528_RAMDAC; /* 128bit DAC found */
+ if (rev == 0xe0)
+ IBMramdac_ID = IBM528A_RAMDAC;
+ }
+ }
+ }
+
+ (*ramdacPtr->WriteDAC)(pScrn, rev, 0, IBMRGB_rev);
+ (*ramdacPtr->WriteDAC)(pScrn, id, 0, IBMRGB_id);
+
+ if (IBMramdac_ID == -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Cannot determine IBM RAMDAC type, aborting\n");
+ return NULL;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Attached RAMDAC is %s\n", IBMramdacDeviceInfo[IBMramdac_ID&0xFFFF]);
+ }
+
+ for (i=0;ramdacs[i].token != -1;i++) {
+ if (ramdacs[i].token == IBMramdac_ID)
+ RamDacIsSupported = TRUE;
+ }
+
+ if (!RamDacIsSupported) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "This IBM RAMDAC is NOT supported by this driver, aborting\n");
+ return NULL;
+ }
+
+ ramdacHelperPtr = RamDacHelperCreateInfoRec();
+ switch (IBMramdac_ID) {
+ case IBM526_RAMDAC:
+ case IBM526DB_RAMDAC:
+ ramdacHelperPtr->SetBpp = IBMramdac526SetBpp;
+ ramdacHelperPtr->HWCursorInit = IBMramdac526HWCursorInit;
+ break;
+ case IBM640_RAMDAC:
+ ramdacHelperPtr->SetBpp = IBMramdac640SetBpp;
+ ramdacHelperPtr->HWCursorInit = IBMramdac640HWCursorInit;
+ break;
+ }
+ ramdacPtr->RamDacType = IBMramdac_ID;
+ ramdacHelperPtr->RamDacType = IBMramdac_ID;
+ ramdacHelperPtr->Save = IBMramdacSave;
+ ramdacHelperPtr->Restore = IBMramdacRestore;
+
+ return ramdacHelperPtr;
+}
+
+void
+IBMramdac526SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
+{
+ ramdacReg->DacRegs[IBMRGB_key_control] = 0x00; /* Disable Chroma Key */
+
+ switch (pScrn->bitsPerPixel) {
+ case 32:
+ ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_32BPP;
+ ramdacReg->DacRegs[IBMRGB_32bpp] = B32_DCOL_DIRECT;
+ ramdacReg->DacRegs[IBMRGB_24bpp] = 0;
+ ramdacReg->DacRegs[IBMRGB_16bpp] = 0;
+ ramdacReg->DacRegs[IBMRGB_8bpp] = 0;
+ if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
+ ramdacReg->DacRegs[IBMRGB_key_control] = 0x01; /* Enable Key */
+ ramdacReg->DacRegs[IBMRGB_key] = 0xFF;
+ ramdacReg->DacRegs[IBMRGB_key_mask] = 0xFF;
+ }
+ break;
+ case 24:
+ ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_24BPP;
+ ramdacReg->DacRegs[IBMRGB_32bpp] = 0;
+ ramdacReg->DacRegs[IBMRGB_24bpp] = B24_DCOL_DIRECT;
+ ramdacReg->DacRegs[IBMRGB_16bpp] = 0;
+ ramdacReg->DacRegs[IBMRGB_8bpp] = 0;
+ break;
+ case 16:
+ if (pScrn->depth == 16) {
+ ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_16BPP;
+ ramdacReg->DacRegs[IBMRGB_32bpp] = 0;
+ ramdacReg->DacRegs[IBMRGB_24bpp] = 0;
+ ramdacReg->DacRegs[IBMRGB_16bpp] = B16_DCOL_DIRECT|B16_LINEAR |
+ B16_CONTIGUOUS | B16_565;
+ ramdacReg->DacRegs[IBMRGB_8bpp] = 0;
+ } else {
+ ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_16BPP;
+ ramdacReg->DacRegs[IBMRGB_32bpp] = 0;
+ ramdacReg->DacRegs[IBMRGB_24bpp] = 0;
+ ramdacReg->DacRegs[IBMRGB_16bpp] = B16_DCOL_DIRECT|B16_LINEAR |
+ B16_CONTIGUOUS | B16_555;
+ ramdacReg->DacRegs[IBMRGB_8bpp] = 0;
+ }
+ break;
+ case 8:
+ ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_8BPP;
+ ramdacReg->DacRegs[IBMRGB_32bpp] = 0;
+ ramdacReg->DacRegs[IBMRGB_24bpp] = 0;
+ ramdacReg->DacRegs[IBMRGB_16bpp] = 0;
+ ramdacReg->DacRegs[IBMRGB_8bpp] = B8_DCOL_INDIRECT;
+ break;
+ case 4:
+ ramdacReg->DacRegs[IBMRGB_pix_fmt] = PIXEL_FORMAT_4BPP;
+ ramdacReg->DacRegs[IBMRGB_32bpp] = 0;
+ ramdacReg->DacRegs[IBMRGB_24bpp] = 0;
+ ramdacReg->DacRegs[IBMRGB_16bpp] = 0;
+ ramdacReg->DacRegs[IBMRGB_8bpp] = 0;
+ }
+}
+
+void
+IBMramdac640SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
+{
+ unsigned char bpp = 0x00;
+ unsigned char overlaybpp = 0x00;
+ unsigned char offset = 0x00;
+ unsigned char dispcont = 0x44;
+
+ ramdacReg->DacRegs[RGB640_SER_WID_03_00] = 0x00;
+ ramdacReg->DacRegs[RGB640_SER_WID_07_04] = 0x00;
+ ramdacReg->DacRegs[RGB640_DIAGS] = 0x07;
+
+ switch (pScrn->depth) {
+ case 8:
+ ramdacReg->DacRegs[RGB640_SER_07_00] = 0x00;
+ ramdacReg->DacRegs[RGB640_SER_15_08] = 0x00;
+ ramdacReg->DacRegs[RGB640_SER_23_16] = 0x00;
+ ramdacReg->DacRegs[RGB640_SER_31_24] = 0x00;
+ ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_16_1; /*16:1 Mux*/
+ ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */
+ bpp = 0x03;
+ break;
+ case 16:
+ ramdacReg->DacRegs[RGB640_SER_07_00] = 0x10;
+ ramdacReg->DacRegs[RGB640_SER_15_08] = 0x11;
+ ramdacReg->DacRegs[RGB640_SER_23_16] = 0x00;
+ ramdacReg->DacRegs[RGB640_SER_31_24] = 0x00;
+ ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_8_1; /* 8:1 Mux*/
+ ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */
+ bpp = 0x05;
+ break;
+ case 24:
+ ramdacReg->DacRegs[RGB640_SER_07_00] = 0x30;
+ ramdacReg->DacRegs[RGB640_SER_15_08] = 0x31;
+ ramdacReg->DacRegs[RGB640_SER_23_16] = 0x32;
+ ramdacReg->DacRegs[RGB640_SER_31_24] = 0x33;
+ ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_4_1; /* 4:1 Mux*/
+ ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PCLK_8; /* pll / 8 */
+ bpp = 0x09;
+ if (pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
+ ramdacReg->DacRegs[RGB640_SER_WID_07_04] = 0x04;
+ ramdacReg->DacRegs[RGB640_CHROMA_KEY0] = 0xFF;
+ ramdacReg->DacRegs[RGB640_CHROMA_MASK0] = 0xFF;
+ offset = 0x04;
+ overlaybpp = 0x04;
+ dispcont = 0x48;
+ }
+ break;
+ case 30: /* 10 bit dac */
+ ramdacReg->DacRegs[RGB640_SER_07_00] = 0x30;
+ ramdacReg->DacRegs[RGB640_SER_15_08] = 0x31;
+ ramdacReg->DacRegs[RGB640_SER_23_16] = 0x32;
+ ramdacReg->DacRegs[RGB640_SER_31_24] = 0x33;
+ ramdacReg->DacRegs[RGB640_SER_MODE] = IBM640_SER_4_1; /* 4:1 Mux*/
+ ramdacReg->DacRegs[RGB640_MISC_CONF] = IBM640_PSIZE10 |
+ IBM640_PCLK_8; /* pll / 8 */
+ bpp = 0x0D;
+ break;
+ }
+
+ {
+ int i;
+ for (i=0x100;i<0x140;i+=4) {
+ /* Initialize FrameBuffer Window Attribute Table */
+ ramdacReg->DacRegs[i+0] = bpp;
+ ramdacReg->DacRegs[i+1] = offset;
+ ramdacReg->DacRegs[i+2] = 0x00;
+ ramdacReg->DacRegs[i+3] = 0x00;
+ /* Initialize Overlay Window Attribute Table */
+ ramdacReg->DacRegs[i+0x100] = overlaybpp;
+ ramdacReg->DacRegs[i+0x101] = 0x00;
+ ramdacReg->DacRegs[i+0x102] = 0x00;
+ ramdacReg->DacRegs[i+0x103] = dispcont;
+ }
+ }
+}
+
+void
+IBMramdac526ShowCursor(ScrnInfoPtr pScrn)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+
+ /* Enable cursor - X11 mode */
+ (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs, 0x00, 0x07);
+}
+
+void
+IBMramdac640ShowCursor(ScrnInfoPtr pScrn)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+
+ /* Enable cursor - mode2 (x11 mode) */
+ (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURSOR_CONTROL, 0x00, 0x0B);
+ (*ramdacPtr->WriteDAC)(pScrn, RGB640_CROSSHAIR_CONTROL, 0x00, 0x00);
+}
+
+void
+IBMramdac526HideCursor(ScrnInfoPtr pScrn)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+
+ /* Disable cursor - X11 mode */
+ (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs, 0x00, 0x24);
+}
+
+void
+IBMramdac640HideCursor(ScrnInfoPtr pScrn)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+
+ /* Disable cursor - mode2 (x11 mode) */
+ (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURSOR_CONTROL, 0x00, 0x08);
+}
+
+void
+IBMramdac526SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+
+ x += 64;
+ y += 64;
+
+ (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_hot_x, 0x00, 0x3f);
+ (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_hot_y, 0x00, 0x3f);
+ (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_xl, 0x00, x & 0xff);
+ (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_xh, 0x00, (x>>8) & 0xf);
+ (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_yl, 0x00, y & 0xff);
+ (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_yh, 0x00, (y>>8) & 0xf);
+}
+
+void
+IBMramdac640SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+
+ x += 64;
+ y += 64;
+
+ (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_OFFSETX, 0x00, 0x3f);
+ (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_OFFSETY, 0x00, 0x3f);
+ (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_X_LOW, 0x00, x & 0xff);
+ (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_X_HIGH, 0x00, (x>>8) & 0xf);
+ (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_Y_LOW, 0x00, y & 0xff);
+ (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_Y_HIGH, 0x00, (y>>8) & 0xf);
+}
+
+void
+IBMramdac526SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+
+ (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col1_r, 0x00, bg >> 16);
+ (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col1_g, 0x00, bg >> 8);
+ (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col1_b, 0x00, bg);
+ (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col2_r, 0x00, fg >> 16);
+ (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col2_g, 0x00, fg >> 8);
+ (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_col2_b, 0x00, fg);
+}
+
+void
+IBMramdac640SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+
+ (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_COL0, 0x00, 0);
+ (*ramdacPtr->WriteData)(pScrn, fg>>16);
+ (*ramdacPtr->WriteData)(pScrn, fg>>8);
+ (*ramdacPtr->WriteData)(pScrn, fg);
+ (*ramdacPtr->WriteData)(pScrn, bg>>16);
+ (*ramdacPtr->WriteData)(pScrn, bg>>8);
+ (*ramdacPtr->WriteData)(pScrn, bg);
+ (*ramdacPtr->WriteData)(pScrn, fg>>16);
+ (*ramdacPtr->WriteData)(pScrn, fg>>8);
+ (*ramdacPtr->WriteData)(pScrn, fg);
+ (*ramdacPtr->WriteData)(pScrn, bg>>16);
+ (*ramdacPtr->WriteData)(pScrn, bg>>8);
+ (*ramdacPtr->WriteData)(pScrn, bg);
+}
+
+void
+IBMramdac526LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+ int i;
+ /*
+ * Output the cursor data. The realize function has put the planes into
+ * their correct order, so we can just blast this out.
+ */
+ for (i = 0; i < 1024; i++)
+ (*ramdacPtr->WriteDAC)(pScrn, IBMRGB_curs_array + i, 0x00, (*src++));
+}
+
+void
+IBMramdac640LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+ int i;
+ /*
+ * Output the cursor data. The realize function has put the planes into
+ * their correct order, so we can just blast this out.
+ */
+ for (i = 0; i < 1024; i++)
+ (*ramdacPtr->WriteDAC)(pScrn, RGB640_CURS_WRITE + i, 0x00, (*src++));
+}
+
+static Bool
+IBMramdac526UseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
+{
+ return TRUE;
+}
+
+static Bool
+IBMramdac640UseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
+{
+ return TRUE;
+}
+
+void
+IBMramdac526HWCursorInit(xf86CursorInfoPtr infoPtr)
+{
+ infoPtr->MaxWidth = 64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1;
+ infoPtr->SetCursorColors = IBMramdac526SetCursorColors;
+ infoPtr->SetCursorPosition = IBMramdac526SetCursorPosition;
+ infoPtr->LoadCursorImage = IBMramdac526LoadCursorImage;
+ infoPtr->HideCursor = IBMramdac526HideCursor;
+ infoPtr->ShowCursor = IBMramdac526ShowCursor;
+ infoPtr->UseHWCursor = IBMramdac526UseHWCursor;
+}
+
+void
+IBMramdac640HWCursorInit(xf86CursorInfoPtr infoPtr)
+{
+ infoPtr->MaxWidth = 64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1;
+ infoPtr->SetCursorColors = IBMramdac640SetCursorColors;
+ infoPtr->SetCursorPosition = IBMramdac640SetCursorPosition;
+ infoPtr->LoadCursorImage = IBMramdac640LoadCursorImage;
+ infoPtr->HideCursor = IBMramdac640HideCursor;
+ infoPtr->ShowCursor = IBMramdac640ShowCursor;
+ infoPtr->UseHWCursor = IBMramdac640UseHWCursor;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/IBM.h b/xc/programs/Xserver/hw/xfree86/ramdac/IBM.h
new file mode 100644
index 000000000..5c4d20250
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/IBM.h
@@ -0,0 +1,383 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/IBM.h,v 1.7 1999/02/12 22:52:11 hohndel Exp $ */
+
+#include <xf86RamDac.h>
+
+RamDacHelperRecPtr IBMramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs);
+void IBMramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr RamDacRec, RamDacRegRecPtr RamDacRegRec);
+void IBMramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr RamDacRec, RamDacRegRecPtr RamDacRegRec);
+void IBMramdac526SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr RamDacRegRec);
+void IBMramdac640SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr RamDacRegRec);
+unsigned long IBMramdac526CalculateMNPCForClock(unsigned long RefClock,
+ unsigned long ReqClock, char IsPixClock, unsigned long MinClock,
+ unsigned long MaxClock, unsigned long *rM, unsigned long *rN,
+ unsigned long *rP, unsigned long *rC);
+unsigned long IBMramdac640CalculateMNPCForClock(unsigned long RefClock,
+ unsigned long ReqClock, char IsPixClock, unsigned long MinClock,
+ unsigned long MaxClock, unsigned long *rM, unsigned long *rN,
+ unsigned long *rP, unsigned long *rC);
+void IBMramdac526HWCursorInit(xf86CursorInfoPtr infoPtr);
+void IBMramdac640HWCursorInit(xf86CursorInfoPtr infoPtr);
+
+#define IBM524_RAMDAC (VENDOR_IBM << 16) | 0x00
+#define IBM524A_RAMDAC (VENDOR_IBM << 16) | 0x01
+#define IBM525_RAMDAC (VENDOR_IBM << 16) | 0x02
+#define IBM526_RAMDAC (VENDOR_IBM << 16) | 0x03
+#define IBM526DB_RAMDAC (VENDOR_IBM << 16) | 0x04
+#define IBM528_RAMDAC (VENDOR_IBM << 16) | 0x05
+#define IBM528A_RAMDAC (VENDOR_IBM << 16) | 0x06
+#define IBM624_RAMDAC (VENDOR_IBM << 16) | 0x07
+#define IBM624DB_RAMDAC (VENDOR_IBM << 16) | 0x08
+#define IBM640_RAMDAC (VENDOR_IBM << 16) | 0x09
+
+/*
+ * IBM Ramdac registers
+ */
+
+#define IBMRGB_REF_FREQ_1 14.31818
+#define IBMRGB_REF_FREQ_2 50.00000
+
+#define IBMRGB_rev 0x00
+#define IBMRGB_id 0x01
+#define IBMRGB_misc_clock 0x02
+#define IBMRGB_sync 0x03
+#define IBMRGB_hsync_pos 0x04
+#define IBMRGB_pwr_mgmt 0x05
+#define IBMRGB_dac_op 0x06
+#define IBMRGB_pal_ctrl 0x07
+#define IBMRGB_sysclk 0x08 /* not RGB525 */
+#define IBMRGB_pix_fmt 0x0a
+#define IBMRGB_8bpp 0x0b
+#define IBMRGB_16bpp 0x0c
+#define IBMRGB_24bpp 0x0d
+#define IBMRGB_32bpp 0x0e
+#define IBMRGB_pll_ctrl1 0x10
+#define IBMRGB_pll_ctrl2 0x11
+#define IBMRGB_pll_ref_div_fix 0x14
+#define IBMRGB_sysclk_ref_div 0x15 /* not RGB525 */
+#define IBMRGB_sysclk_vco_div 0x16 /* not RGB525 */
+/* #define IBMRGB_f0 0x20 */
+
+#define IBMRGB_sysclk_n 0x15
+#define IBMRGB_sysclk_m 0x16
+#define IBMRGB_sysclk_p 0x17
+#define IBMRGB_sysclk_c 0x18
+
+#define IBMRGB_m0 0x20
+#define IBMRGB_n0 0x21
+#define IBMRGB_p0 0x22
+#define IBMRGB_c0 0x23
+#define IBMRGB_m1 0x24
+#define IBMRGB_n1 0x25
+#define IBMRGB_p1 0x26
+#define IBMRGB_c1 0x27
+#define IBMRGB_m2 0x28
+#define IBMRGB_n2 0x29
+#define IBMRGB_p2 0x2a
+#define IBMRGB_c2 0x2b
+#define IBMRGB_m3 0x2c
+#define IBMRGB_n3 0x2d
+#define IBMRGB_p3 0x2e
+#define IBMRGB_c3 0x2f
+
+#define IBMRGB_curs 0x30
+#define IBMRGB_curs_xl 0x31
+#define IBMRGB_curs_xh 0x32
+#define IBMRGB_curs_yl 0x33
+#define IBMRGB_curs_yh 0x34
+#define IBMRGB_curs_hot_x 0x35
+#define IBMRGB_curs_hot_y 0x36
+#define IBMRGB_curs_col1_r 0x40
+#define IBMRGB_curs_col1_g 0x41
+#define IBMRGB_curs_col1_b 0x42
+#define IBMRGB_curs_col2_r 0x43
+#define IBMRGB_curs_col2_g 0x44
+#define IBMRGB_curs_col2_b 0x45
+#define IBMRGB_curs_col3_r 0x46
+#define IBMRGB_curs_col3_g 0x47
+#define IBMRGB_curs_col3_b 0x48
+#define IBMRGB_border_col_r 0x60
+#define IBMRGB_border_col_g 0x61
+#define IBMRGB_botder_col_b 0x62
+#define IBMRGB_key 0x68
+#define IBMRGB_key_mask 0x6C
+#define IBMRGB_misc1 0x70
+#define IBMRGB_misc2 0x71
+#define IBMRGB_misc3 0x72
+#define IBMRGB_misc4 0x73 /* not RGB525 */
+#define IBMRGB_key_control 0x78
+#define IBMRGB_dac_sense 0x82
+#define IBMRGB_misr_r 0x84
+#define IBMRGB_misr_g 0x86
+#define IBMRGB_misr_b 0x88
+#define IBMRGB_pll_vco_div_in 0x8e
+#define IBMRGB_pll_ref_div_in 0x8f
+#define IBMRGB_vram_mask_0 0x90
+#define IBMRGB_vram_mask_1 0x91
+#define IBMRGB_vram_mask_2 0x92
+#define IBMRGB_vram_mask_3 0x93
+#define IBMRGB_curs_array 0x100
+
+
+
+/* Constants rgb525.h */
+
+/* RGB525_REVISION_LEVEL */
+#define RGB525_PRODUCT_REV_LEVEL 0xf0
+
+/* RGB525_ID */
+#define RGB525_PRODUCT_ID 0x01
+
+/* RGB525_MISC_CTRL_1 */
+#define MISR_CNTL_ENABLE 0x80
+#define VMSK_CNTL_ENABLE 0x40
+#define PADR_RDMT_RDADDR 0x0
+#define PADR_RDMT_PAL_STATE 0x20
+#define SENS_DSAB_DISABLE 0x10
+#define SENS_SEL_BIT3 0x0
+#define SENS_SEL_BIT7 0x08
+#define VRAM_SIZE_32 0x0
+#define VRAM_SIZE_64 0x01
+
+/* RGB525_MISC_CTRL_2 */
+#define PCLK_SEL_LCLK 0x0
+#define PCLK_SEL_PLL 0x40
+#define PCLK_SEL_EXT 0x80
+#define INTL_MODE_ENABLE 0x20
+#define BLANK_CNTL_ENABLE 0x10
+#define COL_RES_6BIT 0x0
+#define COL_RES_8BIT 0x04
+#define PORT_SEL_VGA 0x0
+#define PORT_SEL_VRAM 0x01
+
+/* RGB525_MISC_CTRL_3 */
+#define SWAP_RB 0x80
+#define SWAP_WORD_LOHI 0x0
+#define SWAP_WORD_HILO 0x10
+#define SWAP_NIB_HILO 0x0
+#define SWAP_NIB_LOHI 0x02
+
+/* RGB525_MISC_CLK_CTRL */
+#define DDOT_CLK_ENABLE 0x0
+#define DDOT_CLK_DISABLE 0x80
+#define SCLK_ENABLE 0x0
+#define SCLK_DISABLE 0x40
+#define B24P_DDOT_PLL 0x0
+#define B24P_DDOT_SCLK 0x20
+#define DDOT_DIV_PLL_1 0x0
+#define DDOT_DIV_PLL_2 0x02
+#define DDOT_DIV_PLL_4 0x04
+#define DDOT_DIV_PLL_8 0x06
+#define DDOT_DIV_PLL_16 0x08
+#define PLL_DISABLE 0x0
+#define PLL_ENABLE 0x01
+
+/* RGB525_SYNC_CTRL */
+#define DLY_CNTL_ADD 0x0
+#define DLY_SYNC_NOADD 0x80
+#define CSYN_INVT_DISABLE 0x0
+#define CSYN_INVT_ENABLE 0x40
+#define VSYN_INVT_DISABLE 0x0
+#define VSYN_INVT_ENABLE 0x20
+#define HSYN_INVT_DISABLE 0x0
+#define HSYN_INVT_ENABLE 0x10
+#define VSYN_CNTL_NORMAL 0x0
+#define VSYN_CNTL_HIGH 0x04
+#define VSYN_CNTL_LOW 0x08
+#define VSYN_CNTL_DISABLE 0x0C
+#define HSYN_CNTL_NORMAL 0x0
+#define HSYN_CNTL_HIGH 0x01
+#define HSYN_CNTL_LOW 0x02
+#define HSYN_CNTL_DISABLE 0x03
+
+/* RGB525_HSYNC_CTRL */
+#define HSYN_POS(n) (n)
+
+/* RGB525_POWER_MANAGEMENT */
+#define SCLK_PWR_NORMAL 0x0
+#define SCLK_PWR_DISABLE 0x10
+#define DDOT_PWR_NORMAL 0x0
+#define DDOT_PWR_DISABLE 0x08
+#define SYNC_PWR_NORMAL 0x0
+#define SYNC_PWR_DISABLE 0x04
+#define ICLK_PWR_NORMAL 0x0
+#define ICLK_PWR_DISABLE 0x02
+#define DAC_PWR_NORMAL 0x0
+#define DAC_PWR_DISABLE 0x01
+
+/* RGB525_DAC_OPERATION */
+#define SOG_DISABLE 0x0
+#define SOG_ENABLE 0x08
+#define BRB_NORMAL 0x0
+#define BRB_ALWAYS 0x04
+#define DSR_DAC_SLOW 0x02
+#define DSR_DAC_FAST 0x0
+#define DPE_DISABLE 0x0
+#define DPE_ENABLE 0x01
+
+/* RGB525_PALETTE_CTRL */
+#define SIXBIT_LINEAR_ENABLE 0x0
+#define SIXBIT_LINEAR_DISABLE 0x80
+#define PALETTE_PARITION(n) (n)
+
+/* RGB525_PIXEL_FORMAT */
+#define PIXEL_FORMAT_4BPP 0x02
+#define PIXEL_FORMAT_8BPP 0x03
+#define PIXEL_FORMAT_16BPP 0x04
+#define PIXEL_FORMAT_24BPP 0x05
+#define PIXEL_FORMAT_32BPP 0x06
+
+/* RGB525_8BPP_CTRL */
+#define B8_DCOL_INDIRECT 0x0
+#define B8_DCOL_DIRECT 0x01
+
+/* RGB525_16BPP_CTRL */
+#define B16_DCOL_INDIRECT 0x0
+#define B16_DCOL_DYNAMIC 0x40
+#define B16_DCOL_DIRECT 0xC0
+#define B16_POL_FORCE_BYPASS 0x0
+#define B16_POL_FORCE_LOOKUP 0x20
+#define B16_ZIB 0x0
+#define B16_LINEAR 0x04
+#define B16_555 0x0
+#define B16_565 0x02
+#define B16_SPARSE 0x0
+#define B16_CONTIGUOUS 0x01
+
+/* RGB525_24BPP_CTRL */
+#define B24_DCOL_INDIRECT 0x0
+#define B24_DCOL_DIRECT 0x01
+
+/* RGB525_32BPP_CTRL */
+#define B32_POL_FORCE_BYPASS 0x0
+#define B32_POL_FORCE_LOOKUP 0x04
+#define B32_DCOL_INDIRECT 0x0
+#define B32_DCOL_DYNAMIC 0x01
+#define B32_DCOL_DIRECT 0x03
+
+/* RGB525_PLL_CTRL_1 */
+#define REF_SRC_REFCLK 0x0
+#define REF_SRC_EXTCLK 0x10
+#define PLL_EXT_FS_3_0 0x0
+#define PLL_EXT_FS_2_0 0x01
+#define PLL_CNTL2_3_0 0x02
+#define PLL_CNTL2_2_0 0x03
+
+/* RGB525_PLL_CTRL_2 */
+#define PLL_INT_FS_3_0(n) (n)
+#define PLL_INT_FS_2_0(n) (n)
+
+/* RGB525_PLL_REF_DIV_COUNT */
+#define REF_DIV_COUNT(n) (n)
+
+/* RGB525_F0 - RGB525_F15 */
+#define VCO_DIV_COUNT(n) (n)
+
+/* RGB525_PLL_REFCLK values */
+#define RGB525_PLL_REFCLK_MHz(n) ((n)/2)
+
+/* RGB525_CURSOR_CONTROL */
+#define SMLC_PART_0 0x0
+#define SMLC_PART_1 0x40
+#define SMLC_PART_2 0x80
+#define SMLC_PART_3 0xC0
+#define PIX_ORDER_RL 0x0
+#define PIX_ORDER_LR 0x20
+#define LOC_READ_LAST 0x0
+#define LOC_READ_ACTUAL 0x10
+#define UPDT_CNTL_DELAYED 0x0
+#define UPDT_CNTL_IMMEDIATE 0x08
+#define CURSOR_SIZE_32 0x0
+#define CURSOR_SIZE_64 0x40
+#define CURSOR_MODE_OFF 0x0
+#define CURSOR_MODE_3_COLOR 0x01
+#define CURSOR_MODE_2_COLOR_HL 0x02
+#define CURSOR_MODE_2_COLOR 0x03
+
+/* RGB525_REVISION_LEVEL */
+#define REVISION_LEVEL 0xF0 /* predefined */
+
+/* RGB525_ID */
+#define ID_CODE 0x01 /* predefined */
+
+/* MISR status */
+#define RGB525_MISR_DONE 0x01
+
+/* the IBMRGB640 is rather different from the rest of the RAMDACs,
+ so we define a completely new set of register names for it */
+#define RGB640_SER_07_00 0x02
+#define RGB640_SER_15_08 0x03
+#define RGB640_SER_23_16 0x04
+#define RGB640_SER_31_24 0x05
+#define RGB640_SER_WID_03_00 0x06
+#define RGB640_SER_WID_07_04 0x07
+#define RGB640_SER_MODE 0x08
+#define IBM640_SER_2_1 0x00
+#define IBM640_SER_4_1 0x01
+#define IBM640_SER_8_1 0x02
+#define IBM640_SER_16_1 0x03
+#define IBM640_SER_16_3 0x05
+#define IBM640_SER_5_1 0x06
+#define RGB640_PIXEL_INTERLEAVE 0x09
+#define RGB640_MISC_CONF 0x0a
+#define IBM640_PCLK 0x00
+#define IBM640_PCLK_2 0x40
+#define IBM640_PCLK_4 0x80
+#define IBM640_PCLK_8 0xc0
+#define IBM640_PSIZE10 0x10
+#define IBM640_LCI 0x08
+#define IBM640_WIDCTL_MASK 0x07
+#define RGB640_VGA_CONTROL 0x0b
+#define IBM640_RDBK 0x04
+#define IBM640_PSIZE8 0x02
+#define IBM640_VRAM 0x01
+#define RGB640_DAC_CONTROL 0x0d
+#define IBM640_MONO 0x08
+#define IBM640_DACENBL 0x04
+#define IBM640_SHUNT 0x02
+#define IBM640_SLOWSLEW 0x01
+#define RGB640_OUTPUT_CONTROL 0x0e
+#define IBM640_RDAI 0x04
+#define IBM640_WDAI 0x02
+#define IBM640_WATCTL 0x01
+#define RGB640_SYNC_CONTROL 0x0f
+#define IBM640_PWR 0x20
+#define IBM640_VSP 0x10
+#define IBM640_HSP 0x08
+#define IBM640_CSE 0x04
+#define IBM640_CSG 0x02
+#define IBM640_BPE 0x01
+#define RGB640_PLL_N 0x10
+#define RGB640_PLL_M 0x11
+#define RGB640_PLL_P 0x12
+#define RGB640_PLL_CTL 0x13
+#define IBM640_PLL_EN 0x04
+#define IBM640_PLL_HIGH 0x10
+#define IBM640_PLL_LOW 0x01
+#define RGB640_AUX_PLL_CTL 0x17
+#define IBM640_AUXPLL 0x04
+#define IBM640_AUX_HI 0x02
+#define IBM640_AUX_LO 0x01
+#define RGB640_CHROMA_KEY0 0x20
+#define RGB640_CHROMA_MASK0 0x21
+#define RGB640_CURS_X_LOW 0x40
+#define RGB640_CURS_X_HIGH 0x41
+#define RGB640_CURS_Y_LOW 0x42
+#define RGB640_CURS_Y_HIGH 0x43
+#define RGB640_CURS_OFFSETX 0x44
+#define RGB640_CURS_OFFSETY 0x45
+#define RGB640_CURSOR_CONTROL 0x4B
+#define IBM640_CURS_OFF 0x00
+#define IBM640_CURS_MODE0 0x01
+#define IBM640_CURS_MODE1 0x02
+#define IBM640_CURS_MODE2 0x03
+#define IBM640_CURS_ADV 0x04
+#define RGB640_CROSSHAIR_CONTROL 0x57
+#define RGB640_VRAM_MASK0 0xf0
+#define RGB640_VRAM_MASK1 0xf1
+#define RGB640_VRAM_MASK2 0xf2
+#define RGB640_DIAGS 0xfa
+#define RGB640_CURS_WRITE 0x1000
+#define RGB640_CURS_COL0 0x4800
+#define RGB640_CURS_COL1 0x4801
+#define RGB640_CURS_COL2 0x4802
+#define RGB640_CURS_COL3 0x4803
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/IBMPriv.h b/xc/programs/Xserver/hw/xfree86/ramdac/IBMPriv.h
new file mode 100644
index 000000000..6fecb7705
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/IBMPriv.h
@@ -0,0 +1,24 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/IBMPriv.h,v 1.2 1998/07/25 16:57:19 dawes Exp $ */
+
+#include "IBM.h"
+
+typedef struct {
+ char *DeviceName;
+} xf86IBMramdacInfo;
+
+extern xf86IBMramdacInfo IBMramdacDeviceInfo[];
+
+#ifdef INIT_IBM_RAMDAC_INFO
+xf86IBMramdacInfo IBMramdacDeviceInfo[] = {
+ {"IBM 524"},
+ {"IBM 524A"},
+ {"IBM 525"},
+ {"IBM 526"},
+ {"IBM 526DB(DoubleBuffer)"},
+ {"IBM 528"},
+ {"IBM 528A"},
+ {"IBM 624"},
+ {"IBM 624DB(DoubleBuffer)"},
+ {"IBM 640"}
+};
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/Imakefile b/xc/programs/Xserver/hw/xfree86/ramdac/Imakefile
new file mode 100644
index 000000000..c4a0c32fe
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/Imakefile
@@ -0,0 +1,45 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/Imakefile,v 1.9 1999/08/14 10:50:07 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#if DoLoadableServer
+MODSRC = xf86RamDacMod.c
+MODOBJ = xf86RamDacMod.o
+#endif
+
+SRCS = $(MODSRC) xf86RamDac.c xf86RamDacCmap.c xf86Cursor.c xf86HWCurs.c \
+ xf86BitOrder.c IBM.c BT.c TI.c
+
+OBJS = $(MODOBJ) xf86RamDac.o xf86RamDacCmap.o xf86Cursor.o xf86HWCurs.o \
+ xf86BitOrder.o IBM.o BT.o TI.o
+
+ INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/Xext \
+ -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(FONTINCSRC)
+ LINTLIBS = ../../../dix/llib-ldix.ln ../../../os/llib-los.ln \
+ ../../mfb/llib-lmfb.ln ../../mi/llib-lmi.ln
+
+DEPEND_DEFINES = -DRAMDAC_MODULE
+
+ModuleObjectRule()
+
+LibraryModuleTarget(ramdac,$(OBJS))
+
+NormalLintTarget($(SRCS))
+
+InstallLibraryModule(ramdac,$(MODULEDIR),.)
+
+ObjectFromSpecialSource(xf86BitOrder, ../xaa/xaaBitOrder, -DXAAReverseBitOrder=xf86ReverseBitOrder -DRAMDAC_MODULE)
+
+#ifndef OS2Architecture
+DependTarget()
+#endif
+
+InstallDriverSDKLibraryModule(ramdac,$(DRIVERSDKMODULEDIR),.)
+
+InstallDriverSDKNonExecFile(BT.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(IBM.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(TI.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(xf86Cursor.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(xf86RamDac.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/TI.c b/xc/programs/Xserver/hw/xfree86/ramdac/TI.c
new file mode 100644
index 000000000..498df080b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/TI.c
@@ -0,0 +1,568 @@
+/*
+ * Copyright 1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Modified from IBM.c to support TI RAMDAC routines
+ * by Jens Owen, <jens@precisioninsight.com>.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/TI.c,v 1.1 1999/06/14 07:32:08 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86Cursor.h"
+
+#define INIT_TI_RAMDAC_INFO
+#include "TIPriv.h"
+#include "xf86RamDacPriv.h"
+
+/* The following values are in kHz */
+#define TI_MIN_VCO_FREQ 110000
+#define TI_MAX_VCO_FREQ 220000
+
+unsigned long
+TIramdacCalculateMNPForClock(
+ unsigned long RefClock, /* In 100Hz units */
+ unsigned long ReqClock, /* In 100Hz units */
+ char IsPixClock, /* boolean, is this the pixel or the sys clock */
+ unsigned long MinClock, /* Min VCO rating */
+ unsigned long MaxClock, /* Max VCO rating */
+ unsigned long *rM, /* M Out */
+ unsigned long *rN, /* N Out */
+ unsigned long *rP /* Min P In, P Out */
+)
+{
+ unsigned long n, p;
+ unsigned long best_m = 0, best_n = 0;
+ double VCO, IntRef = (double)RefClock;
+ double m_err, inc_m, calc_m;
+ unsigned long ActualClock;
+
+ /* Make sure that MinClock <= ReqClock <= MaxClock */
+ if ( ReqClock < MinClock)
+ ReqClock = MinClock;
+ if ( ReqClock > MaxClock )
+ ReqClock = MaxClock;
+
+ /*
+ * ActualClock = VCO / 2 ^ p
+ * Choose p so that TI_MIN_VCO_FREQ <= VCO <= TI_MAX_VCO_FREQ
+ * Note that since TI_MAX_VCO_FREQ = 2 * TI_MIN_VCO_FREQ
+ * we don't have to bother checking for this maximum limit.
+ */
+ VCO = (double)ReqClock;
+ for ( p = *rP; p < 3 && VCO < TI_MIN_VCO_FREQ; ( p )++ )
+ VCO *= 2.0;
+
+ /*
+ * We avoid doing multiplications by ( 65 - n ),
+ * and add an increment instead - this keeps any error small.
+ */
+ inc_m = VCO / ( IntRef * 8.0 );
+
+ /* Initial value of calc_m for the loop */
+ calc_m = inc_m + inc_m + inc_m;
+
+ /* Initial amount of error for an integer - impossibly large */
+ m_err = 2.0;
+
+ /* Search for the closest INTEGER value of ( 65 - m ) */
+ for ( n = 3; n <= 25; ( n )++, calc_m += inc_m ) {
+
+ /* Ignore values of ( 65 - m ) which we can't use */
+ if ( calc_m < 3.0 || calc_m > 64.0 )
+ continue;
+
+ /*
+ * Pick the closest INTEGER (has smallest fractional part).
+ * The optimizer should clean this up for us.
+ */
+ if (( calc_m - ( int ) calc_m ) < m_err ) {
+ m_err = calc_m - ( int ) calc_m;
+ best_m = ( int ) calc_m;
+ best_n = n;
+ }
+ }
+
+ /* 65 - ( 65 - x ) = x */
+ *rM = 65 - best_m;
+ *rN = 65 - best_n;
+ *rP = p;
+
+ /* Now all the calculations can be completed */
+ VCO = 8.0 * IntRef * best_m / best_n;
+ ActualClock = VCO / ( 1 << p );
+
+#ifdef DEBUG
+ ErrorF( "f_out=%ld f_vco=%.1f n=%d m=%d p=%d\n",
+ ActualClock, VCO, *rN, *rM, *rP);
+#endif
+
+ return (ActualClock);
+}
+
+void
+TIramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
+ RamDacRegRecPtr ramdacReg)
+{
+ int i;
+ unsigned long status;
+
+ /* Here we pass a short, so that we can evaluate a mask too
+ * So that the mask is the high byte and the data the low byte
+ * Order is important
+ */
+ TIRESTORE(TIDAC_latch_ctrl);
+ TIRESTORE(TIDAC_true_color_ctrl);
+ TIRESTORE(TIDAC_multiplex_ctrl);
+ TIRESTORE(TIDAC_clock_select);
+ TIRESTORE(TIDAC_palette_page);
+ TIRESTORE(TIDAC_general_ctrl);
+ TIRESTORE(TIDAC_misc_ctrl);
+ /* 0x2A & 0x2B are reserved */
+ TIRESTORE(TIDAC_key_over_low);
+ TIRESTORE(TIDAC_key_over_high);
+ TIRESTORE(TIDAC_key_red_low);
+ TIRESTORE(TIDAC_key_red_high);
+ TIRESTORE(TIDAC_key_green_low);
+ TIRESTORE(TIDAC_key_green_high);
+ TIRESTORE(TIDAC_key_blue_low);
+ TIRESTORE(TIDAC_key_blue_high);
+ TIRESTORE(TIDAC_key_ctrl);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_clock_ctrl, 0, 0x30);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_clock_ctrl, 0, 0x38);
+ TIRESTORE(TIDAC_clock_ctrl);
+ TIRESTORE(TIDAC_sense_test);
+ TIRESTORE(TIDAC_ind_curs_ctrl);
+
+ /* only restore clocks if they were valid to begin with */
+
+ if (ramdacReg->DacRegs[TIDAC_PIXEL_VALID]) {
+ /* Reset pixel clock */
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0, 0x3c);
+
+ /* Restore N, M & P values for pixel clocks */
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0,
+ ramdacReg->DacRegs[TIDAC_PIXEL_N]);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0,
+ ramdacReg->DacRegs[TIDAC_PIXEL_M]);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_pixel_data, 0,
+ ramdacReg->DacRegs[TIDAC_PIXEL_P]);
+
+ /* wait for pixel clock to lock */
+ i = 1000000;
+ do {
+ status = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data);
+ } while ((!(status & 0x40)) && (--i));
+ if (!(status & 0x40)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Pixel clock setup timed out\n");
+ return;
+ }
+ }
+
+ if (ramdacReg->DacRegs[TIDAC_LOOP_VALID]) {
+ /* Reset loop clock */
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0, 0x70);
+
+ /* Restore N, M & P values for pixel clocks */
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0,
+ ramdacReg->DacRegs[TIDAC_LOOP_N]);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0,
+ ramdacReg->DacRegs[TIDAC_LOOP_M]);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_loop_data, 0,
+ ramdacReg->DacRegs[TIDAC_LOOP_P]);
+
+ /* wait for loop clock to lock */
+ i = 1000000;
+ do {
+ status = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data);
+ } while ((!(status & 0x40)) && (--i));
+ if (!(status & 0x40)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Loop clock setup timed out\n");
+ return;
+ }
+ }
+
+ /* restore palette */
+ (*ramdacPtr->WriteAddress)(pScrn, 0);
+#ifndef NOT_DONE
+ for (i=0;i<768;i++)
+ (*ramdacPtr->WriteData)(pScrn, ramdacReg->DAC[i]);
+#else
+ (*ramdacPtr->WriteData)(pScrn, 0);
+ (*ramdacPtr->WriteData)(pScrn, 0);
+ (*ramdacPtr->WriteData)(pScrn, 0);
+ for (i=0;i<765;i++)
+ (*ramdacPtr->WriteData)(pScrn, 0xff);
+#endif
+}
+
+void
+TIramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPtr,
+ RamDacRegRecPtr ramdacReg)
+{
+ int i;
+ unsigned long status;
+
+ (*ramdacPtr->ReadAddress)(pScrn, 0);
+ for (i=0;i<768;i++)
+ ramdacReg->DAC[i] = (*ramdacPtr->ReadData)(pScrn);
+
+ if (ramdacReg->DacRegs[TIDAC_PIXEL_VALID]) {
+ /* Read back N,M and P values for pixel clock */
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0);
+ ramdacReg->DacRegs[TIDAC_PIXEL_N] =
+ (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x11);
+ ramdacReg->DacRegs[TIDAC_PIXEL_M] =
+ (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22);
+ ramdacReg->DacRegs[TIDAC_PIXEL_P] =
+ (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_pixel_data);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x33);
+ }
+ if (ramdacReg->DacRegs[TIDAC_LOOP_VALID]) {
+ /* Read back N,M and P values for loop clock */
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0);
+ ramdacReg->DacRegs[TIDAC_LOOP_N] =
+ (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x11);
+ ramdacReg->DacRegs[TIDAC_LOOP_M] =
+ (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x22);
+ ramdacReg->DacRegs[TIDAC_LOOP_P] =
+ (*ramdacPtr->ReadDAC)(pScrn, TIDAC_pll_loop_data);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_pll_addr, 0, 0x33);
+ }
+
+ /* Order is important */
+ TISAVE(TIDAC_latch_ctrl);
+ TISAVE(TIDAC_true_color_ctrl);
+ TISAVE(TIDAC_multiplex_ctrl);
+ TISAVE(TIDAC_clock_select);
+ TISAVE(TIDAC_palette_page);
+ TISAVE(TIDAC_general_ctrl);
+ TISAVE(TIDAC_misc_ctrl);
+ /* 0x2A & 0x2B are reserved */
+ TISAVE(TIDAC_key_over_low);
+ TISAVE(TIDAC_key_over_high);
+ TISAVE(TIDAC_key_red_low);
+ TISAVE(TIDAC_key_red_high);
+ TISAVE(TIDAC_key_green_low);
+ TISAVE(TIDAC_key_green_high);
+ TISAVE(TIDAC_key_blue_low);
+ TISAVE(TIDAC_key_blue_high);
+ TISAVE(TIDAC_key_ctrl);
+ TISAVE(TIDAC_clock_ctrl);
+ TISAVE(TIDAC_sense_test);
+ TISAVE(TIDAC_ind_curs_ctrl);
+}
+
+RamDacHelperRecPtr
+TIramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs/* , RamDacRecPtr ramdacPtr*/)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+ RamDacHelperRecPtr ramdacHelperPtr = NULL;
+ Bool RamDacIsSupported = FALSE;
+ int TIramdac_ID = -1;
+ int i;
+ unsigned char id, rev, rev2, id2;
+
+ /* read ID and revision */
+ rev = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_rev);
+ id = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_id);
+
+ /* check if ID and revision are read only */
+ (*ramdacPtr->WriteDAC)(pScrn, ~rev, 0, TIDAC_rev);
+ (*ramdacPtr->WriteDAC)(pScrn, ~id, 0, TIDAC_id);
+ rev2 = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_rev);
+ id2 = (*ramdacPtr->ReadDAC)(pScrn, TIDAC_id);
+
+ switch (id) {
+ case TIDAC_TVP_3030_ID:
+ if (id == id2 && rev == rev2) /* check for READ ONLY */
+ TIramdac_ID = TI3030_RAMDAC;
+ break;
+ }
+
+ (*ramdacPtr->WriteDAC)(pScrn, rev, 0, TIDAC_rev);
+ (*ramdacPtr->WriteDAC)(pScrn, id, 0, TIDAC_id);
+
+ if (TIramdac_ID == -1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Cannot determine TI RAMDAC type, aborting\n");
+ return NULL;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "Attached RAMDAC is %s\n", TIramdacDeviceInfo[TIramdac_ID&0xFFFF]);
+ }
+
+ for (i=0;ramdacs[i].token != -1;i++) {
+ if (ramdacs[i].token == TIramdac_ID)
+ RamDacIsSupported = TRUE;
+ }
+
+ if (!RamDacIsSupported) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "This TI RAMDAC is NOT supported by this driver, aborting\n");
+ return NULL;
+ }
+
+ ramdacHelperPtr = RamDacHelperCreateInfoRec();
+ switch (TIramdac_ID) {
+ case TI3030_RAMDAC:
+ ramdacHelperPtr->SetBpp = TIramdac3030SetBpp;
+ ramdacHelperPtr->HWCursorInit = TIramdac3030HWCursorInit;
+ break;
+ }
+ ramdacPtr->RamDacType = TIramdac_ID;
+ ramdacHelperPtr->RamDacType = TIramdac_ID;
+ ramdacHelperPtr->Save = TIramdacSave;
+ ramdacHelperPtr->Restore = TIramdacRestore;
+
+ return ramdacHelperPtr;
+}
+
+void
+TIramdac3030SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr ramdacReg)
+{
+ switch (pScrn->bitsPerPixel) {
+ case 32:
+ /* order is important */
+ ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
+ ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x46;
+ ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x5D;
+ ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
+ ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
+ ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
+ ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
+ /* 0x2A & 0x2B are reserved */
+ ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
+ ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
+ ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
+ if (ramdacReg->Overlay) {
+ ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x06;
+ ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x3C;
+ ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x01;
+ }
+ ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
+ break;
+ case 24:
+ /* order is important */
+ ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
+ ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x56;
+ ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x58;
+ ramdacReg->DacRegs[TIDAC_clock_select] = 0x25;
+ ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
+ ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
+ ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
+ /* 0x2A & 0x2B are reserved */
+ ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
+ ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
+ ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
+ ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
+ break;
+ case 16:
+ /* order is important */
+#ifdef NOT_DONE
+ /* Matrox driver uses this */
+ ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x07;
+#else
+ ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
+#endif
+ if (pScrn->depth == 16) {
+ ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x45;
+ } else {
+ ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x44;
+ }
+#ifdef NOT_DONE
+ /* Matrox driver uses this */
+ ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x50;
+ ramdacReg->DacRegs[TIDAC_clock_select] = 0x15;
+ ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
+ ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
+ ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
+#else
+ ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x55;
+ ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
+ ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
+ ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
+ ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x2C;
+#endif
+ /* 0x2A & 0x2B are reserved */
+ ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
+ ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x10;
+ ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
+ ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
+ break;
+ case 8:
+ /* order is important */
+ ramdacReg->DacRegs[TIDAC_latch_ctrl] = 0x06;
+ ramdacReg->DacRegs[TIDAC_true_color_ctrl] = 0x80;
+#ifdef NOT_DONE
+ ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x48;
+ ramdacReg->DacRegs[TIDAC_clock_select] = 0x25;
+#else
+ ramdacReg->DacRegs[TIDAC_multiplex_ctrl] = 0x4d;
+ ramdacReg->DacRegs[TIDAC_clock_select] = 0x05;
+#endif
+ ramdacReg->DacRegs[TIDAC_palette_page] = 0x00;
+#ifdef NOT_DONE
+ ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x00;
+ ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x0C;
+#else
+ ramdacReg->DacRegs[TIDAC_general_ctrl] = 0x10;
+ ramdacReg->DacRegs[TIDAC_misc_ctrl] = 0x1C;
+#endif
+ /* 0x2A & 0x2B are reserved */
+ ramdacReg->DacRegs[TIDAC_key_over_low] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_over_high] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_red_low] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_red_high] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_green_low] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_green_high] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_blue_low] = 0xFF;
+ ramdacReg->DacRegs[TIDAC_key_blue_high] = 0x00;
+ ramdacReg->DacRegs[TIDAC_key_ctrl] = 0x00;
+ ramdacReg->DacRegs[TIDAC_sense_test] = 0x00;
+ ramdacReg->DacRegs[TIDAC_ind_curs_ctrl] = 0x00;
+ break;
+ }
+}
+
+void
+TIramdac3030ShowCursor(ScrnInfoPtr pScrn)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+
+ /* Enable cursor - X11 mode */
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_ind_curs_ctrl, 0x6c, 0x13);
+}
+
+void
+TIramdac3030HideCursor(ScrnInfoPtr pScrn)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+
+ /* Disable cursor - X11 mode */
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_ind_curs_ctrl, 0xfc, 0x00);
+}
+
+void
+TIramdac3030SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+
+ x += 64;
+ y += 64;
+
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_XLOW, 0, x & 0xff);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_XHIGH, 0, (x >> 8) & 0x0f);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_YLOW, 0, y & 0xff);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_YHIGH, 0, (y >> 8) & 0x0f);
+}
+
+void
+TIramdac3030SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+
+ /* Background color */
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_WRITE_ADDR, 0, 1);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((bg&0x00ff0000) >> 16));
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((bg&0x0000ff00) >> 8));
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, (bg&0x000000ff) );
+
+ /* Foreground color */
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_WRITE_ADDR, 0, 2);
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((fg&0x00ff0000) >> 16));
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, ((fg&0x0000ff00) >> 8));
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_COLOR, 0, (fg&0x000000ff) );
+}
+
+void
+TIramdac3030LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+{
+ RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn);
+ int i = 1024;
+int j = 16;
+
+ /* reset A9,A8 */
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_ind_curs_ctrl, 0xf3, 0x00);
+ /* reset cursor RAM load address A7..A0 */
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_INDEX, 0x00, 0x00);
+
+ while(i--) {
+ /* NOT_DONE: might need a delay here */
+ (*ramdacPtr->WriteDAC)(pScrn, TIDAC_CURS_RAM_DATA, 0, *(src++));
+ }
+}
+
+static Bool
+TIramdac3030UseHWCursor(ScreenPtr pScr, CursorPtr pCurs)
+{
+ return TRUE;
+}
+
+void
+TIramdac3030HWCursorInit(xf86CursorInfoPtr infoPtr)
+{
+ infoPtr->MaxWidth = 64;
+ infoPtr->MaxHeight = 64;
+ infoPtr->Flags = HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED;
+ infoPtr->SetCursorColors = TIramdac3030SetCursorColors;
+ infoPtr->SetCursorPosition = TIramdac3030SetCursorPosition;
+ infoPtr->LoadCursorImage = TIramdac3030LoadCursorImage;
+ infoPtr->HideCursor = TIramdac3030HideCursor;
+ infoPtr->ShowCursor = TIramdac3030ShowCursor;
+ infoPtr->UseHWCursor = TIramdac3030UseHWCursor;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/TI.h b/xc/programs/Xserver/hw/xfree86/ramdac/TI.h
new file mode 100644
index 000000000..555f89e6e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/TI.h
@@ -0,0 +1,83 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/TI.h,v 1.1 1999/06/14 07:32:08 dawes Exp $ */
+
+#include <xf86RamDac.h>
+
+RamDacHelperRecPtr TIramdacProbe(ScrnInfoPtr pScrn, RamDacSupportedInfoRecPtr ramdacs);
+void TIramdacSave(ScrnInfoPtr pScrn, RamDacRecPtr RamDacRec, RamDacRegRecPtr RamDacRegRec);
+void TIramdacRestore(ScrnInfoPtr pScrn, RamDacRecPtr RamDacRec, RamDacRegRecPtr RamDacRegRec);
+void TIramdac3030SetBpp(ScrnInfoPtr pScrn, RamDacRegRecPtr RamDacRegRec);
+unsigned long TIramdac3030CalculateMNPForClock(unsigned long RefClock,
+ unsigned long ReqClock, char IsPixClock, unsigned long MinClock,
+ unsigned long MaxClock, unsigned long *rM, unsigned long *rN,
+ unsigned long *rP);
+void TIramdac3030HWCursorInit(xf86CursorInfoPtr infoPtr);
+
+#define TI3030_RAMDAC (VENDOR_TI << 16) | 0x00
+
+/*
+ * TI Ramdac registers
+ */
+
+#define TIDAC_rev 0x01
+#define TIDAC_ind_curs_ctrl 0x06
+#define TIDAC_byte_router_ctrl 0x07
+#define TIDAC_latch_ctrl 0x0f
+#define TIDAC_true_color_ctrl 0x18
+#define TIDAC_multiplex_ctrl 0x19
+#define TIDAC_clock_select 0x1a
+#define TIDAC_palette_page 0x1c
+#define TIDAC_general_ctrl 0x1d
+#define TIDAC_misc_ctrl 0x1e
+#define TIDAC_pll_addr 0x2c
+#define TIDAC_pll_pixel_data 0x2d
+#define TIDAC_pll_memory_data 0x2e
+#define TIDAC_pll_loop_data 0x2f
+#define TIDAC_key_over_low 0x30
+#define TIDAC_key_over_high 0x31
+#define TIDAC_key_red_low 0x32
+#define TIDAC_key_red_high 0x33
+#define TIDAC_key_green_low 0x34
+#define TIDAC_key_green_high 0x35
+#define TIDAC_key_blue_low 0x36
+#define TIDAC_key_blue_high 0x37
+#define TIDAC_key_ctrl 0x38
+#define TIDAC_clock_ctrl 0x39
+#define TIDAC_sense_test 0x3a
+#define TIDAC_test_mode_data 0x3b
+#define TIDAC_crc_remain_lsb 0x3c
+#define TIDAC_crc_remain_msb 0x3d
+#define TIDAC_crc_bit_select 0x3e
+#define TIDAC_id 0x3f
+
+/* These are pll values that are accessed via TIDAC_pll_pixel_data */
+#define TIDAC_PIXEL_N 0x80
+#define TIDAC_PIXEL_M 0x81
+#define TIDAC_PIXEL_P 0x82
+#define TIDAC_PIXEL_VALID 0x83
+
+/* These are pll values that are accessed via TIDAC_pll_loop_data */
+#define TIDAC_LOOP_N 0x90
+#define TIDAC_LOOP_M 0x91
+#define TIDAC_LOOP_P 0x92
+#define TIDAC_LOOP_VALID 0x93
+
+/* Direct mapping addresses */
+#define TIDAC_INDEX 0xa0
+#define TIDAC_PALETTE_DATA 0xa1
+#define TIDAC_READ_MASK 0xa2
+#define TIDAC_READ_ADDR 0xa3
+#define TIDAC_CURS_WRITE_ADDR 0xa4
+#define TIDAC_CURS_COLOR 0xa5
+#define TIDAC_CURS_READ_ADDR 0xa7
+#define TIDAC_CURS_CTL 0xa9
+#define TIDAC_INDEXED_DATA 0xaa
+#define TIDAC_CURS_RAM_DATA 0xab
+#define TIDAC_CURS_XLOW 0xac
+#define TIDAC_CURS_XHIGH 0xad
+#define TIDAC_CURS_YLOW 0xae
+#define TIDAC_CURS_YHIGH 0xaf
+
+#define TIDAC_sw_reset 0xff
+
+/* Constants */
+#define TIDAC_TVP_3030_ID 0x30
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/TIPriv.h b/xc/programs/Xserver/hw/xfree86/ramdac/TIPriv.h
new file mode 100644
index 000000000..03d36c4cc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/TIPriv.h
@@ -0,0 +1,25 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/TIPriv.h,v 1.1 1999/06/14 07:32:09 dawes Exp $ */
+
+#include "TI.h"
+
+typedef struct {
+ char *DeviceName;
+} xf86TIramdacInfo;
+
+extern xf86TIramdacInfo TIramdacDeviceInfo[];
+
+#ifdef INIT_TI_RAMDAC_INFO
+xf86TIramdacInfo TIramdacDeviceInfo[] = {
+ {"TI TVP3030"}
+};
+#endif
+
+#define TISAVE(_reg) do { \
+ ramdacReg->DacRegs[_reg] = (*ramdacPtr->ReadDAC)(pScrn, _reg); \
+} while (0)
+
+#define TIRESTORE(_reg) do { \
+ (*ramdacPtr->WriteDAC)(pScrn, _reg, \
+ (ramdacReg->DacRegs[_reg] & 0xFF00) >> 8, \
+ ramdacReg->DacRegs[_reg]); \
+} while (0)
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/xf86Cursor.c b/xc/programs/Xserver/hw/xfree86/ramdac/xf86Cursor.c
new file mode 100644
index 000000000..2fbac2eaf
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/xf86Cursor.c
@@ -0,0 +1,389 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86Cursor.c,v 1.4 1999/03/14 11:18:08 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+#include "xf86str.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "cursorstr.h"
+#include "colormapst.h"
+#include "mi.h"
+#include "xf86Cursor.h"
+
+int xf86CursorScreenIndex = -1;
+static unsigned long xf86CursorGeneration = 0;
+
+/* sprite functions */
+
+static Bool xf86CursorRealizeCursor(ScreenPtr, CursorPtr);
+static Bool xf86CursorUnrealizeCursor(ScreenPtr, CursorPtr);
+static void xf86CursorSetCursor(ScreenPtr, CursorPtr, int, int);
+static void xf86CursorMoveCursor(ScreenPtr, int, int);
+
+static miPointerSpriteFuncRec xf86CursorSpriteFuncs = {
+ xf86CursorRealizeCursor,
+ xf86CursorUnrealizeCursor,
+ xf86CursorSetCursor,
+ xf86CursorMoveCursor
+};
+
+/* Screen functions */
+
+static void xf86CursorInstallColormap(ColormapPtr);
+static void xf86CursorRecolorCursor(ScreenPtr, CursorPtr, Bool);
+static Bool xf86CursorCloseScreen(int, ScreenPtr);
+static void xf86CursorQueryBestSize(int, unsigned short*, unsigned short*,
+ ScreenPtr);
+
+/* ScrnInfoRec functions */
+
+static Bool xf86CursorSwitchMode(int, DisplayModePtr,int);
+static Bool xf86CursorEnterVT(int, int);
+static void xf86CursorLeaveVT(int, int);
+static int xf86SetDGAMode(int, int, DGADevicePtr);
+
+
+Bool
+xf86InitCursor(
+ ScreenPtr pScreen,
+ xf86CursorInfoPtr infoPtr
+)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CursorScreenPtr ScreenPriv;
+ miPointerScreenPtr PointPriv;
+
+ if(xf86CursorGeneration != serverGeneration) {
+ if((xf86CursorScreenIndex = AllocateScreenPrivateIndex()) < 0)
+ return FALSE;
+ xf86CursorGeneration = serverGeneration;
+ }
+
+ if(!xf86InitHardwareCursor(pScreen, infoPtr))
+ return FALSE;
+
+ ScreenPriv = xcalloc(1, sizeof(xf86CursorScreenRec));
+ if(!ScreenPriv) return FALSE;
+
+ pScreen->devPrivates[xf86CursorScreenIndex].ptr = (pointer)ScreenPriv;
+
+ ScreenPriv->SWCursor = TRUE;
+ ScreenPriv->isUp = FALSE;
+ ScreenPriv->CurrentCursor = NULL;
+ ScreenPriv->CursorInfoPtr = infoPtr;
+ ScreenPriv->PalettedCursor = FALSE;
+ ScreenPriv->pInstalledMap = NULL;
+
+ ScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = xf86CursorCloseScreen;
+ ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
+ pScreen->QueryBestSize = xf86CursorQueryBestSize;
+ ScreenPriv->RecolorCursor = pScreen->RecolorCursor;
+ pScreen->RecolorCursor = xf86CursorRecolorCursor;
+
+ if((infoPtr->pScrn->bitsPerPixel == 8) &&
+ !(infoPtr->Flags & HARDWARE_CURSOR_TRUECOLOR_AT_8BPP)) {
+ ScreenPriv->InstallColormap = pScreen->InstallColormap;
+ pScreen->InstallColormap = xf86CursorInstallColormap;
+ ScreenPriv->PalettedCursor = TRUE;
+ }
+
+ PointPriv =
+ (miPointerScreenPtr)pScreen->devPrivates[miPointerScreenIndex].ptr;
+
+ ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
+ PointPriv->spriteFuncs = &xf86CursorSpriteFuncs;
+
+ ScreenPriv->SwitchMode = pScrn->SwitchMode;
+ pScrn->SwitchMode = xf86CursorSwitchMode;
+ ScreenPriv->EnterVT = pScrn->EnterVT;
+ pScrn->EnterVT = xf86CursorEnterVT;
+ ScreenPriv->LeaveVT = pScrn->LeaveVT;
+ pScrn->LeaveVT = xf86CursorLeaveVT;
+ ScreenPriv->SetDGAMode = pScrn->SetDGAMode;
+ pScrn->SetDGAMode = xf86SetDGAMode;
+
+ return TRUE;
+}
+
+/***** Screen functions *****/
+
+static Bool
+xf86CursorCloseScreen(int i, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ miPointerScreenPtr PointPriv =
+ (miPointerScreenPtr)pScreen->devPrivates[miPointerScreenIndex].ptr;
+ xf86CursorScreenPtr ScreenPriv =
+ (xf86CursorScreenPtr)pScreen->devPrivates[xf86CursorScreenIndex].ptr;
+
+ pScreen->CloseScreen = ScreenPriv->CloseScreen;
+ pScreen->QueryBestSize = ScreenPriv->QueryBestSize;
+ pScreen->RecolorCursor = ScreenPriv->RecolorCursor;
+ if(ScreenPriv->InstallColormap)
+ pScreen->InstallColormap = ScreenPriv->InstallColormap;
+
+ PointPriv->spriteFuncs = ScreenPriv->spriteFuncs;
+
+ pScrn->SwitchMode = ScreenPriv->SwitchMode;
+ pScrn->EnterVT = ScreenPriv->EnterVT;
+ pScrn->LeaveVT = ScreenPriv->LeaveVT;
+ pScrn->SetDGAMode = ScreenPriv->SetDGAMode;
+
+ xfree ((pointer) ScreenPriv);
+
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+static void
+xf86CursorQueryBestSize(
+ int class,
+ unsigned short *width,
+ unsigned short *height,
+ ScreenPtr pScreen
+){
+ xf86CursorScreenPtr ScreenPriv =
+ (xf86CursorScreenPtr)pScreen->devPrivates[xf86CursorScreenIndex].ptr;
+
+ if(class == CursorShape) {
+ *width = ScreenPriv->CursorInfoPtr->MaxWidth;
+ *height = ScreenPriv->CursorInfoPtr->MaxHeight;
+ } else
+ (*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
+}
+
+static void
+xf86CursorInstallColormap(ColormapPtr pMap)
+{
+ xf86CursorScreenPtr ScreenPriv =
+ (xf86CursorScreenPtr)pMap->pScreen->devPrivates[xf86CursorScreenIndex].ptr;
+
+ ScreenPriv->pInstalledMap = pMap;
+
+ (*ScreenPriv->InstallColormap)(pMap);
+}
+
+
+static void
+xf86CursorRecolorCursor(
+ ScreenPtr pScreen,
+ CursorPtr pCurs,
+ Bool displayed )
+{
+ xf86CursorScreenPtr ScreenPriv =
+ (xf86CursorScreenPtr)pScreen->devPrivates[xf86CursorScreenIndex].ptr;
+
+ if(!displayed) return;
+
+ if(ScreenPriv->SWCursor)
+ (*ScreenPriv->RecolorCursor)(pScreen, pCurs, displayed);
+ else
+ xf86RecolorCursor(pScreen, pCurs, displayed);
+}
+
+/***** ScrnInfoRec functions *********/
+
+static Bool
+xf86CursorSwitchMode(int index, DisplayModePtr mode, int flags)
+{
+ Bool ret;
+ ScreenPtr pScreen = screenInfo.screens[index];
+ xf86CursorScreenPtr ScreenPriv =
+ (xf86CursorScreenPtr)pScreen->devPrivates[xf86CursorScreenIndex].ptr;
+
+ if(ScreenPriv->isUp) {
+ xf86SetCursor(pScreen, 0, ScreenPriv->x, ScreenPriv->y);
+ ScreenPriv->isUp = FALSE;
+ }
+
+ ret = (*ScreenPriv->SwitchMode)(index, mode, flags);
+
+ if(ScreenPriv->CurrentCursor)
+ xf86CursorSetCursor(pScreen, ScreenPriv->CurrentCursor,
+ ScreenPriv->x, ScreenPriv->y);
+
+ return ret;
+}
+
+
+static Bool
+xf86CursorEnterVT(int index, int flags)
+{
+ Bool ret;
+ ScreenPtr pScreen = screenInfo.screens[index];
+ xf86CursorScreenPtr ScreenPriv =
+ (xf86CursorScreenPtr)pScreen->devPrivates[xf86CursorScreenIndex].ptr;
+
+ ret = (*ScreenPriv->EnterVT)(index, flags);
+
+ if(ScreenPriv->CurrentCursor)
+ xf86CursorSetCursor(pScreen, ScreenPriv->CurrentCursor,
+ ScreenPriv->x, ScreenPriv->y);
+ return ret;
+}
+
+static void
+xf86CursorLeaveVT(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ xf86CursorScreenPtr ScreenPriv =
+ (xf86CursorScreenPtr)pScreen->devPrivates[xf86CursorScreenIndex].ptr;
+
+ if(ScreenPriv->isUp) {
+ xf86SetCursor(pScreen, 0, ScreenPriv->x, ScreenPriv->y);
+ ScreenPriv->isUp = FALSE;
+ }
+ ScreenPriv->SWCursor = TRUE;
+
+ (*ScreenPriv->LeaveVT)(index, flags);
+}
+
+
+static int
+xf86SetDGAMode(int index, int num, DGADevicePtr devRet)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ xf86CursorScreenPtr ScreenPriv =
+ (xf86CursorScreenPtr)pScreen->devPrivates[xf86CursorScreenIndex].ptr;
+ int ret;
+
+ if(num && ScreenPriv->isUp) {
+ xf86SetCursor(pScreen, 0, ScreenPriv->x, ScreenPriv->y);
+ ScreenPriv->isUp = FALSE;
+ ScreenPriv->SWCursor = TRUE;
+ }
+
+ ret = (*ScreenPriv->SetDGAMode)(index, num, devRet);
+
+ if(!num && ScreenPriv->CurrentCursor) {
+ xf86CursorSetCursor(pScreen, ScreenPriv->CurrentCursor,
+ ScreenPriv->x, ScreenPriv->y);
+ }
+
+ return ret;
+}
+
+
+/****** miPointerSpriteFunctions *******/
+
+
+static Bool
+xf86CursorRealizeCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ xf86CursorScreenPtr ScreenPriv =
+ (xf86CursorScreenPtr)pScreen->devPrivates[xf86CursorScreenIndex].ptr;
+
+ if(pCurs->refcnt <= 1)
+ pCurs->devPriv[pScreen->myNum] = NULL;
+
+ return((*ScreenPriv->spriteFuncs->RealizeCursor)(pScreen, pCurs));
+}
+
+static Bool
+xf86CursorUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ xf86CursorScreenPtr ScreenPriv =
+ (xf86CursorScreenPtr)pScreen->devPrivates[xf86CursorScreenIndex].ptr;
+
+ if(pCurs->refcnt <= 1) {
+ pointer privData = pCurs->devPriv[pScreen->myNum];
+ if(privData) xfree(privData);
+ pCurs->devPriv[pScreen->myNum] = NULL;
+ }
+
+ return((*ScreenPriv->spriteFuncs->UnrealizeCursor)(pScreen, pCurs));
+}
+
+
+static void
+xf86CursorSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
+{
+ xf86CursorScreenPtr ScreenPriv =
+ (xf86CursorScreenPtr)pScreen->devPrivates[xf86CursorScreenIndex].ptr;
+ xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
+
+ ScreenPriv->CurrentCursor = pCurs;
+ ScreenPriv->x = x;
+ ScreenPriv->y = y;
+
+ if(!pCurs) { /* means we're supposed to remove the cursor */
+ if(ScreenPriv->SWCursor)
+ (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y);
+ else {
+ if(ScreenPriv->isUp) xf86SetCursor(pScreen, 0, x, y);
+ ScreenPriv->isUp = FALSE;
+ }
+ return;
+ }
+
+ ScreenPriv->HotX = pCurs->bits->xhot;
+ ScreenPriv->HotY = pCurs->bits->yhot;
+
+ if( infoPtr->pScrn->vtSema &&
+ (pCurs->bits->height <= infoPtr->MaxHeight) &&
+ (pCurs->bits->width <= infoPtr->MaxWidth) &&
+ (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor)(pScreen, pCurs))){
+
+ if(ScreenPriv->SWCursor) /* remove the SW cursor */
+ (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y);
+
+ xf86SetCursor(pScreen, pCurs, x, y);
+ ScreenPriv->SWCursor = FALSE;
+ ScreenPriv->isUp = TRUE;
+ return;
+ }
+
+ if(ScreenPriv->isUp) {
+ /* remove the HW cursor */
+ xf86SetCursor(pScreen, 0, x, y);
+ ScreenPriv->isUp = FALSE;
+ }
+
+ ScreenPriv->SWCursor = TRUE;
+
+ (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, pCurs, x, y);
+}
+
+static void
+xf86CursorMoveCursor(ScreenPtr pScreen, int x, int y)
+{
+ xf86CursorScreenPtr ScreenPriv =
+ (xf86CursorScreenPtr)pScreen->devPrivates[xf86CursorScreenIndex].ptr;
+
+ ScreenPriv->x = x;
+ ScreenPriv->y = y;
+
+ if(ScreenPriv->SWCursor)
+ (*ScreenPriv->spriteFuncs->MoveCursor)(pScreen, x, y);
+ else if(ScreenPriv->isUp)
+ xf86MoveCursor(pScreen, x, y);
+}
+
+
+
+xf86CursorInfoPtr
+xf86CreateCursorInfoRec(void)
+{
+ return(xcalloc(1,sizeof(xf86CursorInfoRec)));
+}
+
+
+void
+xf86DestroyCursorInfoRec(xf86CursorInfoPtr infoPtr)
+{
+ if(infoPtr) xfree(infoPtr);
+}
+
+
+
+
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/xf86Cursor.h b/xc/programs/Xserver/hw/xfree86/ramdac/xf86Cursor.h
new file mode 100644
index 000000000..ab067f45a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/xf86Cursor.h
@@ -0,0 +1,74 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86Cursor.h,v 1.4 1999/03/14 11:18:08 dawes Exp $ */
+
+#ifndef _XF86CURSOR_H
+#define _XF86CURSOR_H
+
+#include "mipointrst.h"
+
+typedef struct _xf86CursorInfoRec {
+ ScrnInfoPtr pScrn;
+ int Flags;
+ int MaxWidth;
+ int MaxHeight;
+ void (*SetCursorColors)(ScrnInfoPtr pScrn, int bg, int fg);
+ void (*SetCursorPosition)(ScrnInfoPtr pScrn, int x, int y);
+ void (*LoadCursorImage)(ScrnInfoPtr pScrn, unsigned char *bits);
+ void (*HideCursor)(ScrnInfoPtr pScrn);
+ void (*ShowCursor)(ScrnInfoPtr pScrn);
+ unsigned char* (*RealizeCursor)(struct _xf86CursorInfoRec *, CursorPtr);
+ Bool (*UseHWCursor)(ScreenPtr, CursorPtr);
+
+} xf86CursorInfoRec, *xf86CursorInfoPtr;
+
+typedef struct {
+ Bool SWCursor;
+ Bool isUp;
+ short HotX;
+ short HotY;
+ short x;
+ short y;
+ CursorPtr CurrentCursor;
+ xf86CursorInfoPtr CursorInfoPtr;
+ CloseScreenProcPtr CloseScreen;
+ RecolorCursorProcPtr RecolorCursor;
+ InstallColormapProcPtr InstallColormap;
+ QueryBestSizeProcPtr QueryBestSize;
+ miPointerSpriteFuncPtr spriteFuncs;
+ Bool PalettedCursor;
+ ColormapPtr pInstalledMap;
+ Bool (*SwitchMode)(int, DisplayModePtr,int);
+ Bool (*EnterVT)(int, int);
+ void (*LeaveVT)(int, int);
+ int (*SetDGAMode)(int, int, DGADevicePtr);
+} xf86CursorScreenRec, *xf86CursorScreenPtr;
+
+Bool xf86InitCursor(
+ ScreenPtr pScreen,
+ xf86CursorInfoPtr infoPtr
+);
+
+xf86CursorInfoPtr xf86CreateCursorInfoRec(void);
+void xf86DestroyCursorInfoRec(xf86CursorInfoPtr);
+
+
+void xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y);
+void xf86MoveCursor(ScreenPtr pScreen, int x, int y);
+void xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed);
+Bool xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr);
+
+extern int xf86CursorScreenIndex;
+
+#define HARDWARE_CURSOR_INVERT_MASK 0x00000001
+#define HARDWARE_CURSOR_AND_SOURCE_WITH_MASK 0x00000002
+#define HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK 0x00000004
+#define HARDWARE_CURSOR_SOURCE_MASK_NOT_INTERLEAVED 0x00000008
+#define HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 0x00000010
+#define HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 0x00000020
+#define HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 0x00000040
+#define HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 0x00000080
+#define HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 0x00000100
+#define HARDWARE_CURSOR_TRUECOLOR_AT_8BPP 0x00000200
+#define HARDWARE_CURSOR_BIT_ORDER_MSBFIRST 0x00000400
+#define HARDWARE_CURSOR_NIBBLE_SWAPPED 0x00000800
+
+#endif /* _XF86CURSOR_H */
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/xf86CursorPriv.h b/xc/programs/Xserver/hw/xfree86/ramdac/xf86CursorPriv.h
new file mode 100644
index 000000000..8a4ee8b01
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/xf86CursorPriv.h
@@ -0,0 +1,8 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86CursorPriv.h,v 1.1 1998/08/29 14:34:41 dawes Exp $ */
+
+#ifndef _XF86CURSORPRIV_H
+#define _XF86CURSORPRIV_H
+
+CARD32 xf86ReverseBitOrder(CARD32 data);
+
+#endif /* _XF86CURSORPRIV_H */
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/xf86HWCurs.c b/xc/programs/Xserver/hw/xfree86/ramdac/xf86HWCurs.c
new file mode 100644
index 000000000..0c33208a5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/xf86HWCurs.c
@@ -0,0 +1,468 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86HWCurs.c,v 1.5 1999/04/17 07:07:08 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "cursorstr.h"
+#include "mi.h"
+#include "mipointer.h"
+#include "xf86Cursor.h"
+#include "xf86CursorPriv.h"
+
+#include "servermd.h"
+
+#if BITMAP_SCANLINE_PAD == 64
+#define SCANLINE CARD64
+#define REVERSE_BIT_ORDER(w) xf86CARD64ReverseBits(w)
+static CARD64 xf86CARD64ReverseBits(CARD64 w);
+
+static CARD64
+xf86CARD64ReverseBits(CARD64 w)
+{
+ unsigned char *p = (unsigned char *)&w;
+
+ p[0] = byte_reversed[p[0]];
+ p[1] = byte_reversed[p[1]];
+ p[2] = byte_reversed[p[2]];
+ p[3] = byte_reversed[p[3]];
+ p[4] = byte_reversed[p[4]];
+ p[5] = byte_reversed[p[5]];
+ p[6] = byte_reversed[p[6]];
+ p[7] = byte_reversed[p[7]];
+
+ return(w);
+}
+
+#else
+#define SCANLINE CARD32
+#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
+#endif /* BITMAP_SCANLINE_PAD == 64 */
+
+
+
+static unsigned char* RealizeCursorInterleave0(xf86CursorInfoPtr, CursorPtr);
+static unsigned char* RealizeCursorInterleave1(xf86CursorInfoPtr, CursorPtr);
+static unsigned char* RealizeCursorInterleave8(xf86CursorInfoPtr, CursorPtr);
+static unsigned char* RealizeCursorInterleave16(xf86CursorInfoPtr, CursorPtr);
+static unsigned char* RealizeCursorInterleave32(xf86CursorInfoPtr, CursorPtr);
+static unsigned char* RealizeCursorInterleave64(xf86CursorInfoPtr, CursorPtr);
+
+Bool
+xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if((infoPtr->MaxWidth <= 0) || (infoPtr->MaxHeight <= 0))
+ return FALSE;
+
+ if( !infoPtr->SetCursorPosition ||
+ !infoPtr->LoadCursorImage ||
+ !infoPtr->HideCursor ||
+ !infoPtr->ShowCursor ||
+ !infoPtr->SetCursorColors) /* these are required for now */
+ return FALSE;
+
+ if (infoPtr->RealizeCursor) {
+ /* Don't overwrite a driver provided Realize Cursor function */
+ } else
+ if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 & infoPtr->Flags) {
+ infoPtr->RealizeCursor = RealizeCursorInterleave1;
+ } else
+ if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 & infoPtr->Flags) {
+ infoPtr->RealizeCursor = RealizeCursorInterleave8;
+ } else
+ if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 & infoPtr->Flags) {
+ infoPtr->RealizeCursor = RealizeCursorInterleave16;
+ } else
+ if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 & infoPtr->Flags) {
+ infoPtr->RealizeCursor = RealizeCursorInterleave32;
+ } else
+ if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 & infoPtr->Flags) {
+ infoPtr->RealizeCursor = RealizeCursorInterleave64;
+ } else { /* not interleaved */
+ infoPtr->RealizeCursor = RealizeCursorInterleave0;
+ }
+
+ infoPtr->pScrn = pScrn;
+
+ return TRUE;
+}
+
+
+void
+xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
+{
+ xf86CursorScreenPtr ScreenPriv =
+ (xf86CursorScreenPtr)pScreen->devPrivates[xf86CursorScreenIndex].ptr;
+ xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
+ unsigned char *bits;
+
+ if(!pCurs) {
+ (*infoPtr->HideCursor)(infoPtr->pScrn);
+ return;
+ }
+
+ bits = (unsigned char*)pCurs->devPriv[pScreen->myNum];
+
+ x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
+ y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
+
+ if(!bits) {
+ bits = (*infoPtr->RealizeCursor)(infoPtr, pCurs);
+ pCurs->devPriv[pScreen->myNum] = (pointer)bits;
+ }
+
+ (*infoPtr->HideCursor)(infoPtr->pScrn);
+
+ if(bits)
+ (*infoPtr->LoadCursorImage)(infoPtr->pScrn, bits);
+
+ xf86RecolorCursor(pScreen, pCurs, 1);
+
+ (*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);
+
+ (*infoPtr->ShowCursor)(infoPtr->pScrn);
+}
+
+
+void
+xf86MoveCursor(ScreenPtr pScreen, int x, int y)
+{
+ xf86CursorScreenPtr ScreenPriv =
+ (xf86CursorScreenPtr)pScreen->devPrivates[xf86CursorScreenIndex].ptr;
+ xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
+
+ x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
+ y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
+
+ (*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);
+}
+
+void
+xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
+{
+ xf86CursorScreenPtr ScreenPriv =
+ (xf86CursorScreenPtr)pScreen->devPrivates[xf86CursorScreenIndex].ptr;
+ xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
+
+ if(ScreenPriv->PalettedCursor) {
+ xColorItem sourceColor, maskColor;
+ ColormapPtr pmap = ScreenPriv->pInstalledMap;
+
+ if(!pmap) return;
+
+ sourceColor.red = pCurs->foreRed;
+ sourceColor.green = pCurs->foreGreen;
+ sourceColor.blue = pCurs->foreBlue;
+ FakeAllocColor(pmap, &sourceColor);
+ maskColor.red = pCurs->backRed;
+ maskColor.green = pCurs->backGreen;
+ maskColor.blue = pCurs->backBlue;
+ FakeAllocColor(pmap, &maskColor);
+ FakeFreeColor(pmap, sourceColor.pixel);
+ FakeFreeColor(pmap, maskColor.pixel);
+ (*infoPtr->SetCursorColors)(infoPtr->pScrn,
+ maskColor.pixel, sourceColor.pixel);
+ } else { /* Pass colors in 8-8-8 RGB format */
+ (*infoPtr->SetCursorColors)(infoPtr->pScrn,
+ (pCurs->backBlue >> 8) |
+ ((pCurs->backGreen >> 8) << 8) |
+ ((pCurs->backRed >> 8) << 16),
+ (pCurs->foreBlue >> 8) |
+ ((pCurs->foreGreen >> 8) << 8) |
+ ((pCurs->foreRed >> 8) << 16)
+ );
+ }
+}
+
+/* These functions assume that MaxWidth is a multiple of 32 */
+
+static unsigned char*
+RealizeCursorInterleave0(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
+{
+
+ SCANLINE *SrcS, *SrcM, *DstS, *DstM;
+ SCANLINE *pSrc, *pMsk;
+ unsigned char *mem;
+ int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
+ int SrcPitch, DstPitch, y, x;
+ /* how many words are in the source or mask */
+ int words = size / (BITMAP_SCANLINE_PAD / 4);
+
+
+ if(!(mem = xcalloc(1, size)))
+ return NULL;
+
+ /* SrcPitch == the number of scanlines wide the cursor image is */
+ SrcPitch = (pCurs->bits->width + (BITMAP_SCANLINE_PAD - 1)) >>
+ LOG2_BITMAP_PAD;
+
+ /* DstPitch is the width of the hw cursor in scanlines */
+ DstPitch = infoPtr->MaxWidth >> LOG2_BITMAP_PAD;
+
+/* SrcPitch = (pCurs->bits->width + 31) >> 5; */
+/* DstPitch = infoPtr->MaxWidth >> 5; */
+
+ SrcS = (SCANLINE*)pCurs->bits->source;
+ SrcM = (SCANLINE*)pCurs->bits->mask;
+ DstS = (SCANLINE*)mem;
+ DstM = DstS + words;
+
+ if(infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK) {
+ SCANLINE *tmp;
+ tmp = DstS; DstS = DstM; DstM = tmp;
+ }
+
+ for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
+ y--;
+ pSrc+=DstPitch, pMsk+=DstPitch, SrcS+=SrcPitch, SrcM+=SrcPitch) {
+ for(x = 0; x < SrcPitch; x++) {
+ pSrc[x] = SrcS[x];
+ pMsk[x] = SrcM[x];
+ }
+ }
+
+ if(infoPtr->Flags & HARDWARE_CURSOR_AND_SOURCE_WITH_MASK) {
+ int count = words;
+ SCANLINE* pntr = DstS;
+ SCANLINE* pntr2 = DstM;
+ while(count--) {
+ *pntr &= *pntr2;
+ pntr++; pntr2++;
+ }
+ }
+
+ if(infoPtr->Flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) {
+ int count = size;
+ unsigned char* pntr1 = (unsigned char *)DstS;
+ unsigned char* pntr2 = (unsigned char *)DstM;
+ unsigned char a,b;
+ while(count) {
+
+ a = *pntr1;
+ b = *pntr2;
+ *pntr1 = ((a & 0xF0) >> 4) | ((a & 0x0F) << 4);
+ *pntr2 = ((b & 0xF0) >> 4) | ((b & 0x0F) << 4);
+ pntr1++; pntr2++;
+ count-=2;
+ }
+ }
+
+ /*
+ * Must be _after_ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK to avoid wiping
+ * out entire source mask.
+ */
+ if(infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
+ int count = words;
+ SCANLINE* pntr = DstM;
+ while(count--) {
+ *pntr = ~(*pntr);
+ pntr++;
+ }
+ }
+
+ if(infoPtr->Flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) {
+ for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
+ y--;
+ pSrc+=DstPitch, pMsk+=DstPitch) {
+ for(x = 0; x < SrcPitch; x++) {
+ pSrc[x] = REVERSE_BIT_ORDER(pSrc[x]);
+ pMsk[x] = REVERSE_BIT_ORDER(pMsk[x]);
+ }
+ }
+ }
+
+ return mem;
+}
+
+static unsigned char*
+RealizeCursorInterleave1(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
+{
+ unsigned char *DstS, *DstM;
+ unsigned char *pntr;
+ unsigned char *mem, *mem2;
+ int count;
+ int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
+
+ /* Realize the cursor without interleaving */
+ if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
+ return NULL;
+
+ if(!(mem = xcalloc(1, size))) {
+ xfree(mem2);
+ return NULL;
+ }
+
+ /* 1 bit interleave */
+ DstS = (unsigned char *)mem2;
+ DstM = DstS + (size >> 1);
+ pntr = (unsigned char *)mem;
+ count = size;
+ while(count) {
+ *pntr++ = ((*DstS&0x01) ) | ((*DstM&0x01) << 1) |
+ ((*DstS&0x02) << 1) | ((*DstM&0x02) << 2) |
+ ((*DstS&0x04) << 2) | ((*DstM&0x04) << 3) |
+ ((*DstS&0x08) << 3) | ((*DstM&0x08) << 4);
+ *pntr++ = ((*DstS&0x10) >> 4) | ((*DstM&0x10) >> 3) |
+ ((*DstS&0x20) >> 3) | ((*DstM&0x20) >> 2) |
+ ((*DstS&0x40) >> 2) | ((*DstM&0x40) >> 1) |
+ ((*DstS&0x80) >> 1) | ((*DstM&0x80) );
+ DstS++;
+ DstM++;
+ count-=2;
+ }
+
+ /* Free the uninterleaved cursor */
+ xfree(mem2);
+
+ return mem;
+}
+
+static unsigned char*
+RealizeCursorInterleave8(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
+{
+ unsigned char *DstS, *DstM;
+ unsigned char *pntr;
+ unsigned char *mem, *mem2;
+ int count;
+ int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
+
+ /* Realize the cursor without interleaving */
+ if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
+ return NULL;
+
+ if(!(mem = xcalloc(1, size))) {
+ xfree(mem2);
+ return NULL;
+ }
+
+ /* 8 bit interleave */
+ DstS = (unsigned char *)mem2;
+ DstM = DstS + (size >> 1);
+ pntr = (unsigned char *)mem;
+ count = size;
+ while(count) {
+ *pntr++ = *DstS++;
+ *pntr++ = *DstM++;
+ count-=2;
+ }
+
+ /* Free the uninterleaved cursor */
+ xfree(mem2);
+
+ return mem;
+}
+
+static unsigned char*
+RealizeCursorInterleave16(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
+{
+ unsigned short *DstS, *DstM;
+ unsigned short *pntr;
+ unsigned char *mem, *mem2;
+ int count;
+ int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
+
+ /* Realize the cursor without interleaving */
+ if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
+ return NULL;
+
+ if(!(mem = xcalloc(1, size))) {
+ xfree(mem2);
+ return NULL;
+ }
+
+ /* 16 bit interleave */
+ DstS = (unsigned short *)mem2;
+ DstM = DstS + (size >> 2);
+ pntr = (unsigned short *)mem;
+ count = (size >> 1);
+ while(count) {
+ *pntr++ = *DstS++;
+ *pntr++ = *DstM++;
+ count-=2;
+ }
+
+ /* Free the uninterleaved cursor */
+ xfree(mem2);
+
+ return mem;
+}
+
+static unsigned char*
+RealizeCursorInterleave32(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
+{
+ CARD32 *DstS, *DstM;
+ CARD32 *pntr;
+ unsigned char *mem, *mem2;
+ int count;
+ int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
+
+ /* Realize the cursor without interleaving */
+ if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
+ return NULL;
+
+ if(!(mem = xcalloc(1, size))) {
+ xfree(mem2);
+ return NULL;
+ }
+
+ /* 32 bit interleave */
+ DstS = (CARD32*)mem2;
+ DstM = DstS + (size >> 3);
+ pntr = (CARD32*)mem;
+ count = (size >> 2);
+ while(count) {
+ *pntr++ = *DstS++;
+ *pntr++ = *DstM++;
+ count-=2;
+ }
+
+ /* Free the uninterleaved cursor */
+ xfree(mem2);
+
+ return mem;
+}
+
+static unsigned char*
+RealizeCursorInterleave64(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
+{
+ CARD32 *DstS, *DstM;
+ CARD32 *pntr;
+ unsigned char *mem, *mem2;
+ int count;
+ int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
+
+ /* Realize the cursor without interleaving */
+ if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
+ return NULL;
+
+ if(!(mem = xcalloc(1, size))) {
+ xfree(mem2);
+ return NULL;
+ }
+
+ /* 64 bit interleave */
+ DstS = (CARD32*)mem2;
+ DstM = DstS + (size >> 3);
+ pntr = (CARD32*)mem;
+ count = (size >> 2);
+ while(count) {
+ *pntr++ = *DstS++;
+ *pntr++ = *DstS++;
+ *pntr++ = *DstM++;
+ *pntr++ = *DstM++;
+ count-=4;
+ }
+
+ /* Free the uninterleaved cursor */
+ xfree(mem2);
+
+ return mem;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDac.c b/xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDac.c
new file mode 100644
index 000000000..049511410
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDac.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright 1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Generic RAMDAC access routines.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDac.c,v 1.5 1999/01/14 13:05:21 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+
+#include "xf86RamDacPriv.h"
+
+int RamDacHWPrivateIndex = -1;
+int RamDacScreenPrivateIndex = -1;
+
+RamDacRecPtr
+RamDacCreateInfoRec()
+{
+ RamDacRecPtr infoRec;
+
+ infoRec = xcalloc(1, sizeof(RamDacRec));
+
+ return infoRec;
+}
+
+RamDacHelperRecPtr
+RamDacHelperCreateInfoRec()
+{
+ RamDacHelperRecPtr infoRec;
+
+ infoRec = xcalloc(1, sizeof(RamDacHelperRec));
+
+ return infoRec;
+}
+
+void
+RamDacDestroyInfoRec(RamDacRecPtr infoRec)
+{
+ if(!infoRec) return;
+
+ if(infoRec->ReadDAC)
+ xfree(infoRec->ReadDAC);
+
+ if(infoRec->WriteDAC)
+ xfree(infoRec->WriteDAC);
+
+ if(infoRec->WriteAddress)
+ xfree(infoRec->WriteAddress);
+
+ if(infoRec->WriteData)
+ xfree(infoRec->WriteData);
+
+ if(infoRec->ReadAddress)
+ xfree(infoRec->ReadAddress);
+
+ if(infoRec->ReadData)
+ xfree(infoRec->ReadData);
+
+ xfree(infoRec);
+}
+
+void
+RamDacHelperDestroyInfoRec(RamDacHelperRecPtr infoRec)
+{
+ if(!infoRec) return;
+
+ if(infoRec->RamDacType)
+ xfree(infoRec->RamDacType);
+
+ if(infoRec->Save)
+ xfree(infoRec->Save);
+
+ if(infoRec->Restore)
+ xfree(infoRec->Restore);
+
+ if(infoRec->SetBpp)
+ xfree(infoRec->SetBpp);
+
+ xfree(infoRec);
+}
+
+Bool
+RamDacInit(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPriv)
+{
+ RamDacHWRecPtr ramdacHWPtr;
+ RamDacRegRecPtr ramdacReg;
+ RamDacScreenRecPtr ramdacScrPtr;
+
+ /*
+ * make sure the RamDacRec is allocated
+ */
+ if (!RamDacGetRec(pScrn))
+ return FALSE;
+ ramdacHWPtr = RAMDACHWPTR(pScrn);
+ ramdacReg = &ramdacHWPtr->ModeReg;
+ ramdacScrPtr = ((RamDacScreenRecPtr)
+ (pScrn)->privates[RamDacGetScreenIndex()].ptr);
+ ramdacScrPtr->RamDacRec = ramdacPriv;
+
+ return(TRUE);
+}
+
+void
+RamDacGetRecPrivate()
+{
+ if (RamDacHWPrivateIndex < 0)
+ RamDacHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
+ if (RamDacScreenPrivateIndex < 0)
+ RamDacScreenPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
+ return;
+}
+
+Bool
+RamDacGetRec(ScrnInfoPtr scrp)
+{
+ RamDacRegRecPtr regp;
+
+ RamDacGetRecPrivate();
+ /*
+ * New privates are always set to NULL, so we can check if the allocation
+ * has already been done.
+ */
+ if (scrp->privates[RamDacHWPrivateIndex].ptr != NULL)
+ return TRUE;
+ if (scrp->privates[RamDacScreenPrivateIndex].ptr != NULL)
+ return TRUE;
+
+ scrp->privates[RamDacHWPrivateIndex].ptr =
+ xnfcalloc(sizeof(RamDacHWRec), 1);
+ scrp->privates[RamDacScreenPrivateIndex].ptr =
+ xnfcalloc(sizeof(RamDacScreenRec), 1);
+ /* Does this really belong here? */
+ regp = &((RamDacHWRecPtr)scrp->privates[RamDacHWPrivateIndex].ptr)->ModeReg;
+
+ return TRUE;
+}
+
+void
+RamDacFreeRec(ScrnInfoPtr pScrn)
+{
+ RamDacHWRecPtr ramdacHWPtr;
+ RamDacScreenRecPtr ramdacScrPtr;
+
+ if (RamDacHWPrivateIndex < 0)
+ return;
+
+ if (RamDacScreenPrivateIndex < 0)
+ return;
+
+ ramdacHWPtr = RAMDACHWPTR(pScrn);
+ ramdacScrPtr = ((RamDacScreenRecPtr)
+ (pScrn)->privates[RamDacGetScreenIndex()].ptr);
+
+ if (ramdacHWPtr)
+ xfree(ramdacHWPtr);
+ ramdacHWPtr = NULL;
+
+ if (ramdacScrPtr)
+ xfree(ramdacScrPtr);
+ ramdacScrPtr = NULL;
+}
+
+int
+RamDacGetHWIndex()
+{
+ return RamDacHWPrivateIndex;
+}
+
+int
+RamDacGetScreenIndex()
+{
+ return RamDacScreenPrivateIndex;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDac.h b/xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDac.h
new file mode 100644
index 000000000..f417cec18
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDac.h
@@ -0,0 +1,115 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDac.h,v 1.10 1999/06/14 07:32:09 dawes Exp $ */
+
+#ifndef _XF86RAMDAC_H
+#define _XF86RAMDAC_H 1
+
+#include "xf86Cursor.h"
+
+/* Define unique vendor codes for RAMDAC's */
+#define VENDOR_IBM 0x0000
+#define VENDOR_BT 0x0001
+#define VENDOR_TI 0x0002
+
+typedef struct _RamDacRegRec {
+/* This is probably the nastiest assumption, we allocate 1024 slots for
+ * ramdac registers, should be enough. I've checked IBM and TVP series
+ * and they seem o.k
+ * Then we allocate 768 entries for the DAC too. IBM640 needs 1024 -FIXME
+ */
+ unsigned short DacRegs[0x400]; /* register set */
+ unsigned char DAC[0x300]; /* colour map */
+ Bool Overlay;
+} RamDacRegRec, *RamDacRegRecPtr;
+
+typedef struct _RamDacHWRegRec {
+ RamDacRegRec SavedReg;
+ RamDacRegRec ModeReg;
+} RamDacHWRec, *RamDacHWRecPtr;
+
+typedef struct _RamDacRec {
+ CARD32 RamDacType;
+
+ unsigned char (*ReadDAC)(
+ ScrnInfoPtr pScrn,
+ CARD32
+ );
+
+ void (*WriteDAC)(
+ ScrnInfoPtr pScrn,
+ CARD32,
+ unsigned char,
+ unsigned char
+ );
+
+ void (*WriteAddress)(
+ ScrnInfoPtr pScrn,
+ CARD32
+ );
+
+ void (*WriteData)(
+ ScrnInfoPtr pScrn,
+ unsigned char
+ );
+
+ void (*ReadAddress)(
+ ScrnInfoPtr pScrn,
+ CARD32
+ );
+
+ unsigned char (*ReadData)(
+ ScrnInfoPtr pScrn
+ );
+} RamDacRec, *RamDacRecPtr;
+
+typedef struct _RamDacHelperRec {
+ CARD32 RamDacType;
+
+ void (*Restore)(
+ ScrnInfoPtr pScrn,
+ RamDacRecPtr ramdacPtr,
+ RamDacRegRecPtr ramdacReg
+ );
+
+ void (*Save)(
+ ScrnInfoPtr pScrn,
+ RamDacRecPtr ramdacPtr,
+ RamDacRegRecPtr ramdacReg
+ );
+
+ void (*SetBpp)(
+ ScrnInfoPtr pScrn,
+ RamDacRegRecPtr ramdacReg
+ );
+
+ void (*HWCursorInit)(
+ xf86CursorInfoPtr infoPtr
+ );
+} RamDacHelperRec, *RamDacHelperRecPtr;
+
+#define RAMDACHWPTR(p) ((RamDacHWRecPtr)((p)->privates[RamDacGetHWIndex()].ptr))
+
+typedef struct _RamdacScreenRec {
+ RamDacRecPtr RamDacRec;
+} RamDacScreenRec, *RamDacScreenRecPtr;
+#define RAMDACSCRPTR(p) ((RamDacScreenRecPtr)((p)->privates[RamDacGetScreenIndex()].ptr))->RamDacRec
+
+extern int RamDacHWPrivateIndex;
+extern int RamDacScreenPrivateIndex;
+
+typedef struct {
+ int token;
+} RamDacSupportedInfoRec, *RamDacSupportedInfoRecPtr;
+
+RamDacRecPtr RamDacCreateInfoRec(void);
+RamDacHelperRecPtr RamDacHelperCreateInfoRec(void);
+void RamDacDestroyInfoRec(RamDacRecPtr RamDacRec);
+void RamDacHelperDestroyInfoRec(RamDacHelperRecPtr RamDacRec);
+Bool RamDacInit(ScrnInfoPtr pScrn, RamDacRecPtr RamDacRec);
+void RamDacSetGamma(ScrnInfoPtr pScrn, Bool Real8BitDac);
+void RamDacRestoreDACValues(ScrnInfoPtr pScrn);
+Bool RamDacHandleColormaps(ScreenPtr pScreen, int maxColors, int sigRGBbits,
+ unsigned int flags);
+void RamDacFreeRec(ScrnInfoPtr pScrn);
+int RamDacGetHWIndex(void);
+
+#endif /* _XF86RAMDAC_H */
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacCmap.c b/xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacCmap.c
new file mode 100644
index 000000000..097cf57b2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacCmap.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Generic RAMDAC access to colormaps.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacCmap.c,v 1.5 1999/07/18 03:27:01 dawes Exp $ */
+
+#include "X.h"
+#include "Xproto.h"
+#include "windowstr.h"
+#include "compiler.h"
+#include "mipointer.h"
+#include "micmap.h"
+
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "colormapst.h"
+#include "xf86RamDacPriv.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+void
+RamDacLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
+ VisualPtr pVisual)
+{
+ RamDacRecPtr hwp = RAMDACSCRPTR(pScrn);
+ int i, index;
+
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ (*hwp->WriteAddress)(pScrn, index);
+ (*hwp->WriteData)(pScrn, colors[index].red);
+ (*hwp->WriteData)(pScrn, colors[index].green);
+ (*hwp->WriteData)(pScrn, colors[index].blue);
+ }
+}
+
+Bool
+RamDacHandleColormaps(ScreenPtr pScreen, int maxColors, int sigRGBbits,
+ unsigned int flags)
+{
+ return xf86HandleColormaps(pScreen, maxColors, sigRGBbits,
+ RamDacLoadPalette, NULL, flags);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacMod.c b/xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacMod.c
new file mode 100644
index 000000000..754949606
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacMod.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright 1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Generic RAMDAC module.
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacMod.c,v 1.6 1999/01/26 05:54:18 dawes Exp $ */
+
+#include "xf86Module.h"
+
+
+static XF86ModuleVersionInfo VersRec = {
+ "ramdac",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 0, 1, 0,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_NONE,
+ {0, 0, 0, 0}
+};
+
+XF86ModuleData ramdacModuleData = { &VersRec, NULL, NULL };
+
diff --git a/xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacPriv.h b/xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacPriv.h
new file mode 100644
index 000000000..f1eeb3a7d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacPriv.h
@@ -0,0 +1,10 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86RamDacPriv.h,v 1.4 1999/07/18 03:27:02 dawes Exp $ */
+
+#include "xf86RamDac.h"
+#include "xf86cmap.h"
+
+void RamDacGetRecPrivate(void);
+Bool RamDacGetRec(ScrnInfoPtr pScrn);
+int RamDacGetScreenIndex(void);
+void RamDacLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual);
diff --git a/xc/programs/Xserver/hw/xfree86/reconfig/Imakefile b/xc/programs/Xserver/hw/xfree86/reconfig/Imakefile
new file mode 100644
index 000000000..42f6b7076
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/reconfig/Imakefile
@@ -0,0 +1,22 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/reconfig/Imakefile,v 3.6 1996/12/23 06:51:39 dawes Exp $
+
+
+
+
+
+XCOMM $XConsortium: Imakefile /main/4 1996/02/21 17:54:49 kaleb $
+
+ YFLAGS = -d
+ SRCS = reconfig.c lex.c copyright.c
+ OBJS = reconfig.o lex.o copyright.o
+ LOCAL_LIBRARIES = $(LEXLIB)
+ DEPLIBS =
+
+all::
+
+LexFile(lex)
+
+YaccFile(reconfig,$(YFLAGS))
+
+ComplexProgramTarget(reconfig)
+
diff --git a/xc/programs/Xserver/hw/xfree86/reconfig/README b/xc/programs/Xserver/hw/xfree86/reconfig/README
new file mode 100644
index 000000000..4ae2ddaaf
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/reconfig/README
@@ -0,0 +1,5 @@
+$XFree86: xc/programs/Xserver/hw/xfree86/reconfig/README,v 3.3 1996/12/23 06:51:40 dawes Exp $
+There is no documentation. Read the comment in the reconfig.y file.
+The comments at the structures in there indicate how I want to split the
+keywords over the various sections. I hope the code agrees with this.
+$XConsortium: README /main/4 1996/02/21 17:54:53 kaleb $
diff --git a/xc/programs/Xserver/hw/xfree86/reconfig/copyright.c b/xc/programs/Xserver/hw/xfree86/reconfig/copyright.c
new file mode 100644
index 000000000..cb7a43cba
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/reconfig/copyright.c
@@ -0,0 +1,76 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/reconfig/copyright.c,v 3.3 1996/12/23 06:51:41 dawes Exp $ */
+
+
+/* Print the copyright to stdout */
+
+
+/* $XConsortium: copyright.c /main/4 1996/02/21 17:54:56 kaleb $ */
+
+copyright()
+{
+ printf("# Copyright (c) 1994 by The XFree86 Project, Inc.\n");
+
+ printf("#\n");
+
+ printf("# Permission is hereby granted, free of charge, to any person ");
+ printf("obtaining a\n");
+
+ printf("# copy of this software and associated documentation files (the ");
+ printf("\"Software\"),\n");
+
+ printf("# to deal in the Software without restriction, including without ");
+ printf("limitation\n");
+
+ printf("# the rights to use, copy, modify, merge, publish, distribute, ");
+ printf("sublicense,\n");
+
+ printf("# and/or sell copies of the Software, and to permit persons to ");
+ printf("whom the\n");
+
+ printf("# Software is furnished to do so, subject to the following ");
+ printf("conditions:\n");
+
+ printf("#\n");
+
+ printf("# The above copyright notice and this permission notice shall be ");
+ printf("included in\n");
+
+ printf("# all copies or substantial portions of the Software.\n");
+
+ printf("#\n");
+
+ printf("# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY ");
+ printf("KIND, EXPRESS OR\n");
+
+ printf("# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ");
+ printf("MERCHANTABILITY,\n");
+
+ printf("# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO ");
+ printf("EVENT SHALL\n");
+
+ printf("# THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ");
+ printf("LIABILITY,\n");
+
+ printf("# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ");
+ printf("FROM, OUT OF\n");
+
+ printf("# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ");
+ printf("IN THE\n");
+
+ printf("# SOFTWARE.\n");
+
+ printf("#\n");
+
+ printf("# Except as contained in this notice, the name of the XFree86 ");
+ printf("Project shall\n");
+
+ printf("# not be used in advertising or otherwise to promote the sale, ");
+ printf("use or other\n");
+
+ printf("# dealings in this Software without prior written authorization ");
+ printf("from the\n");
+
+ printf("# XFree86 Project.\n");
+
+ printf("#\n\n");
+}
diff --git a/xc/programs/Xserver/hw/xfree86/reconfig/keyword.i b/xc/programs/Xserver/hw/xfree86/reconfig/keyword.i
new file mode 100644
index 000000000..30fc5550a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/reconfig/keyword.i
@@ -0,0 +1,87 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/reconfig/keyword.i,v 3.3 1996/12/23 06:51:41 dawes Exp $ */
+
+
+
+
+/* $XConsortium: keyword.i /main/4 1996/02/21 17:55:00 kaleb $ */
+
+ { FONTPATH, "fontpath" },
+ { RGBPATH, "rgbpath" },
+ { SHAREDMON, "sharedmonitor" },
+ { NOTRAPSIGNALS, "notrapsignals" },
+ { KEYBOARD, "keyboard" },
+ { MICROSOFT, "microsoft" },
+ { MOUSESYS, "mousesystems" },
+ { MMSERIES, "mmseries" },
+ { LOGITECH, "logitech" },
+ { BUSMOUSE, "busmouse" },
+ { LOGIMAN, "mouseman" },
+ { PS_2, "ps/2" },
+ { MMHITTAB, "mmhittab" },
+ { XQUE, "xqueue" },
+ { OSMOUSE, "osmouse" },
+ { VGA256, "vga256" },
+ { VGA2, "vga2" },
+ { MONO, "mono" },
+ { VGA16, "vga16" },
+ { ACCEL, "accel" },
+ { MODEDB, "modedb" },
+ { AUTOREPEAT, "autorepeat" },
+ { DONTZAP, "dontzap" },
+ { SERVERNUM, "servernumlock" },
+ { XLEDS, "xleds" },
+ { VTINIT, "vtinit" },
+ { LEFTALT, "leftalt" },
+ { RIGHTALT, "rightalt" },
+ { RIGHTALT, "altgr" },
+ { SCROLLLOCK, "scrolllock" },
+ { RIGHTCTL, "rightctl" },
+ { VTSYSREQ, "vtsysreq" },
+ { K_META, "meta" },
+ { K_COMPOSE, "compose" },
+ { K_MODESHIFT, "modeshift" },
+ { K_MODELOCK, "modelock" },
+ { K_SCROLLLOCK, "scrolllock" },
+ { K_CONTROL, "control" },
+ { BAUDRATE, "baudrate" },
+ { EMULATE3, "emulate3buttons" },
+ { SAMPLERATE, "samplerate" },
+ { CLEARDTR, "cleardtr" },
+ { CLEARRTS, "clearrts" },
+ { CHORDMIDDLE,"chordmiddle" },
+ { STATICGRAY, "staticgray" },
+ { GRAYSCALE, "grayscale" },
+ { STATICCOLOR,"staticcolor" },
+ { PSEUDOCOLOR,"pseudocolor" },
+ { TRUECOLOR, "truecolor" },
+ { DIRECTCOLOR,"directcolor" },
+ { CHIPSET, "chipset" },
+ { CLOCKS, "clocks" },
+ { DISPLAYSIZE,"displaysize" },
+ { MODES, "modes" },
+ { SCREENNO, "screenno" },
+ { OPTION, "option" },
+ { VIDEORAM, "videoram" },
+ { VIEWPORT, "viewport" },
+ { VIRTUAL, "virtual" },
+ { SPEEDUP, "speedup" },
+ { NOSPEEDUP, "nospeedup" },
+ { CLOCKPROG, "clockprog" },
+ { BIOSBASE, "biosbase" },
+ { BLACK, "black" },
+ { WHITE, "white" },
+ { MEMBASE, "membase" },
+ { INTERLACE, "interlace"},
+ { PHSYNC, "+hsync"},
+ { NHSYNC, "-hsync"},
+ { PVSYNC, "+vsync"},
+ { NVSYNC, "-vsync"},
+ { CSYNC, "composite"},
+/* New keywords: */
+ { RAMDAC, "ramdac"},
+ { DACSPEED, "dacspeed"},
+ { IOBASE, "iobase"},
+ { DACBASE, "dacbase"},
+ { COPBASE, "copbase"},
+ { POSBASE, "posbase"},
+ { INSTANCE, "instance"},
diff --git a/xc/programs/Xserver/hw/xfree86/reconfig/lex.l b/xc/programs/Xserver/hw/xfree86/reconfig/lex.l
new file mode 100644
index 000000000..7d87e7c72
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/reconfig/lex.l
@@ -0,0 +1,88 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/reconfig/lex.l,v 3.7 1996/12/23 06:51:42 dawes Exp $ */
+
+
+
+
+/* $XConsortium: lex.l /main/5 1996/10/25 14:12:13 kaleb $ */
+
+%{
+#include "os.h"
+#include "strlist.h"
+#include "reconfig.h"
+
+struct keyword {
+ int token;
+ char *name;
+};
+
+struct keyword keywords[] = {
+#include "keyword.i"
+ -1, ""
+};
+
+/* strcasecmp */
+int strcscmp(s1,s2)
+char *s1, *s2;
+{
+ int c1, c2;
+
+ while ( *s1 && *s2 ) {
+ c1 = *s1;
+ c2 = *s2;
+ if ( isupper(c1) ) c1 = tolower(c1);
+ if ( isupper(c2) ) c2 = tolower(c2);
+ if ( c1 != c2 ) return c1 - c2;
+ s1++; s2++;
+ }
+ return *s1 - *s2;
+}
+
+int lookup(s)
+char *s;
+{
+ struct keyword *kp;
+
+ for ( kp = keywords; kp->token >= 0 ; kp++ ) {
+ if ( strcscmp(s,kp->name) == 0 ) return kp->token;
+ }
+ return WRONG;
+}
+
+char *sdup(s)
+char *s;
+{
+ char *s2;
+ int n = strlen(s); /* Excluding terminating '\0' */
+
+ s2 = malloc(n+1);
+ strcpy(s2,s);
+ return s2;
+}
+
+int line = 1;
+%}
+
+digit [0-9]
+hexdigit [0-9a-fA-F]
+octdigit [0-7]
+identifier [-+]?[a-zA-Z][a-zA-Z0-9/]*
+hexnum 0[xX]{hexdigit}+
+octnum 0{octdigit}+
+decnum (([1-9]{digit}*)|0)
+flonum {decnum}"."{digit}*
+string \"[^\"\n]*\"
+
+comment \#([^\n]*)
+number ({hexnum}|{octnum}|{decnum}|{flonum})
+white [ \t]+
+
+%%
+
+{identifier} { return lookup(yytext); }
+{number} { yylval.string = sdup(yytext); return NUMBER; }
+{string} { yylval.string = sdup(yytext); return STRING; }
+{comment} break;
+{white} break;
+\n { line++; break; }
+
+%%
diff --git a/xc/programs/Xserver/hw/xfree86/reconfig/os.h b/xc/programs/Xserver/hw/xfree86/reconfig/os.h
new file mode 100644
index 000000000..1a05eeb0e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/reconfig/os.h
@@ -0,0 +1,37 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/reconfig/os.h,v 3.6 1996/12/23 06:51:43 dawes Exp $ */
+
+
+
+
+
+/* $XConsortium: os.h /main/5 1996/10/19 18:08:25 kaleb $ */
+
+/* from <X11/Xosdefs.h> */
+#ifdef NOSTDHDRS
+#define X_NOT_STDC_ENV
+#endif
+#if defined(USL) && defined(SYSV)
+#define X_NOT_STDC_ENV
+#endif
+#if defined(SYSV) && defined(i386)
+#ifndef SCO
+#define X_NOT_STDC_ENV
+#endif
+#endif
+
+/* from <X11/Xlibint.h> */
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#include <string.h>
+#else
+char *malloc(), *realloc(), *calloc();
+#ifdef SYSV
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#endif
+
+#if defined(MACH) || defined(__bsdi__)
+#include <ctype.h>
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/reconfig/reconfig.man b/xc/programs/Xserver/hw/xfree86/reconfig/reconfig.man
new file mode 100644
index 000000000..2dd9b99eb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/reconfig/reconfig.man
@@ -0,0 +1,22 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/reconfig/reconfig.man,v 3.8 1998/04/05 02:28:42 dawes Exp $
+.TH reconfig 1 "Version 3.2" "XFree86"
+.SH NAME
+reconfig \- convert old Xconfig to new XF86Config
+.SH SYNOPSIS
+.B reconfig
+<
+.I Xconfig
+>
+.I XF86Config
+.SH DESCRIPTION
+The \fIreconfig\fP program converts the Xconfig file format used
+in XFree86 versions prior to 3.1 into the XF86Config format currently
+used. The XF86Config format contains more information than the Xconfig
+format, so manual editing is required after converting.
+.SH "SEE ALSO"
+XFree86(1), XF86Config(4/5), xf86config(1)
+.SH AUTHOR
+Gertjan Akkerman.
+.SH BUGS
+Comment lines are stripped out when converting.
+.\" $TOG: reconfig.man /main/9 1997/07/19 10:50:33 kaleb $
diff --git a/xc/programs/Xserver/hw/xfree86/reconfig/reconfig.y b/xc/programs/Xserver/hw/xfree86/reconfig/reconfig.y
new file mode 100644
index 000000000..73d1bf6b2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/reconfig/reconfig.y
@@ -0,0 +1,730 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/reconfig/reconfig.y,v 3.8 1996/12/23 06:51:45 dawes Exp $ */
+
+
+
+
+
+/* $XConsortium: reconfig.y /main/5 1996/02/21 17:55:14 kaleb $ */
+
+%{
+#include <stdio.h>
+#include "os.h"
+#include "strlist.h"
+
+/* Author (of this quick hack): G.J. Akkerman
+ * Usage: reconfig < OldXconfig > NewXconfig
+ *
+ * Notes:
+ * This utility reads an Xconfig file into structures similar to those
+ * in the server: one for server-global items, and one for each screen.
+ * The datastructures used are however trivialized, since we don't want to
+ * interpret data, but only to reshuffle it:
+ * + Keywords without arguments are represented by ints (booleans)
+ * + For keywords with arguments we use strings to represent those arguments
+ * verbatim. (Even the quotes around strings are preserved.) In this way, we
+ * avoid, for instance, round off errors.
+ * After an Xconfig file is successfully read into the structures, we dump
+ * them in the new format. We make up any required database keys, and we
+ * give an arbitrary (and quite possibly wrong) monitor description.
+ * In general, we do little error checking. It is possible that a wrong old
+ * Xconfig file gets translated to a wrong new format Xconfig file.
+ *
+ * This is all the documentation there is. -- GJA.
+ */
+
+#define N_SCREENS 5
+#define iVGA256 0
+#define iVGA2 1
+#define iMONO 2
+#define iVGA16 3
+#define iACCEL 4
+
+#define fINTERLACE (1 << 0)
+#define fPHSYNC (1 << 1)
+#define fNHSYNC (1 << 2)
+#define fPVSYNC (1 << 3)
+#define fNVSYNC (1 << 4)
+#define fCSYNC (1 << 5)
+
+/* Indices for the keymaps */
+#define N_KEYM 4
+#define iLEFTALT 0
+#define iRIGHTALT 1
+#define iSCROLLLOCK 2
+#define iRIGHTCTL 3
+
+struct mode {
+ char *mn;
+ char *d;
+ char *h1,*h2,*h3,*h4;
+ char *v1,*v2,*v3,*v4;
+ int flags;
+} ;
+
+typedef struct {
+ int count;
+ struct mode *datap;
+} mode_list ;
+
+struct general_struct {
+ int Sharedmon; /* ? */
+ string_list *Fontpath; /* files */
+ char *Rgbpath; /* files */
+ int Notrapsignals; /* serverflags */
+
+ /* Keyboard stuff: */
+ char *Autorepeat1, *Autorepeat2; /* keyboard */
+ int Dontzap; /* serverflags */
+ int Servernum; /* keyboard */
+ char *Xleds; /* keyboard */
+ char *Vtinit; /* keyboard */
+ char *keymap[N_KEYM]; /* keyboard */
+ int Vtsysreq; /* keyboard */
+
+ /* Mouse stuff: */
+ char *mouse_name; /* pointer */
+ char *mouse_device; /* pointer */
+ char *Baudrate; /* pointer */
+ char *Samplerate; /* pointer */
+ int Emulate3 ; /* pointer */
+ int Chordmiddle ; /* pointer */
+ int Cleardtr ; /* pointer */
+ int Clearrts ; /* pointer */
+} gen ;
+
+struct screen_struct {
+ int configured;
+ int Staticgray; /* screen.display */
+ int Grayscale ; /* screen.display */
+ int Staticcolor ; /* screen.display */
+ int Pseudocolor ; /* screen.display */
+ int Truecolor ; /* screen.display */
+ int Directcolor; /* screen.display */
+ char *Chipset; /* device */
+ char *Ramdac; /* device */
+ char *Dacspeed; /* device */
+ char *Clockchip; /* device */
+ string_list_list *Clocks; /* device */
+ char *Displaysize1,*Displaysize2 ; /* screen.display */
+ string_list *Modes; /* screen.display */
+ char *Screenno; /* screen */
+ string_list *Option; /* device */
+ char *Videoram; /* device */
+ char *Viewport1,*Viewport2; /* screen.display */
+ char *Virtual1,*Virtual2; /* screen.display */
+ char *Speedup; /* device */
+ int Nospeedup; /* device */
+ char *Clockprog1, *Clockprog2; /* device */
+ /* string + number */
+ char *Biosbase; /* device */
+ char *Membase; /* device */
+ char *Black1, *Black2, *Black3; /* screen.display */
+ char *White1, *White2, *White3; /* screen.display */
+ char *Iobase; /* device */
+ char *Dacbase; /* device */
+ char *Copbase; /* device */
+ char *Posbase; /* device */
+ char *Instance; /* device */
+} screens[N_SCREENS] ;
+
+int scrn_index, kmap_index ; /* Indices */
+int flags; /* Covert data path. */
+char *modename; /* Covert data path. */
+
+/* This is the *external* mode list. */
+mode_list *modelist;
+
+mode_list *add_mode();
+string_list_list *add_list();
+string_list *add_string();
+
+#define SCRN (screens[scrn_index])
+
+%}
+
+%union {
+ char *string;
+ char *number;
+ string_list *stringlist;
+}
+
+%token ACCEL AUTOREPEAT BAUDRATE BIOSBASE BLACK BUSMOUSE
+ CHIPSET CHORDMIDDLE CLEARDTR CLEARRTS CLOCKPROG
+ CLOCKS CSYNC DIRECTCOLOR DISPLAYSIZE DONTZAP EMULATE3
+ FONTPATH GRAYSCALE INTERLACE KEYBOARD K_COMPOSE K_CONTROL
+ K_META K_MODELOCK K_MODESHIFT K_SCROLLLOCK LEFTALT LOGIMAN
+ LOGITECH MEMBASE MICROSOFT MMHITTAB MMSERIES MODEDB MODES
+ MONO MOUSESYS NHSYNC NOSPEEDUP NOTRAPSIGNALS NVSYNC OPTION
+ OSMOUSE PHSYNC PSEUDOCOLOR PS_2 PVSYNC RGBPATH RIGHTALT
+ RIGHTCTL SAMPLERATE SCREENNO SCROLLLOCK SERVERNUM
+ SHAREDMON SPEEDUP STATICCOLOR STATICGRAY TRUECOLOR VGA16 VGA2
+ VGA256 VIDEORAM VIEWPORT VIRTUAL VTINIT VTSYSREQ WHITE XLEDS
+ XQUE
+
+/* Relatively new keywords: */
+%token RAMDAC DACSPEED IOBASE DACBASE COPBASE POSBASE INSTANCE
+
+/* Nowhere used: */
+%token WRONG
+
+%type <string> string
+%type <number> number
+%type <stringlist> clocks strings
+
+%token <string> STRING
+%token <number> NUMBER
+
+%%
+
+file:
+ /* empty */ |
+ file top ;
+
+top :
+ SHAREDMON { gen.Sharedmon = 1; } |
+ FONTPATH string { gen.Fontpath = add_string(gen.Fontpath,$2); } |
+ RGBPATH string { gen.Rgbpath = $2; } |
+ NOTRAPSIGNALS { gen.Notrapsignals = 1; } |
+ KEYBOARD keyboardconfig |
+
+ /* We have only one mouse: */
+ MICROSOFT string mouseconfig
+ { gen.mouse_device = $2;
+ gen.mouse_name = "microsoft"; } |
+ MOUSESYS string mouseconfig
+ { gen.mouse_device = $2;
+ gen.mouse_name = "mousesystems"; } |
+ MMSERIES string mouseconfig
+ { gen.mouse_device = $2;
+ gen.mouse_name = "mmseries"; } |
+ LOGITECH string mouseconfig
+ { gen.mouse_device = $2;
+ gen.mouse_name = "logitech"; } |
+ BUSMOUSE string mouseconfig
+ { gen.mouse_device = $2;
+ gen.mouse_name = "busmouse"; } |
+ LOGIMAN string mouseconfig
+ { gen.mouse_device = $2;
+ gen.mouse_name = "mouseman"; } |
+ PS_2 string mouseconfig
+ { gen.mouse_device = $2;
+ gen.mouse_name = "ps/2"; } |
+ MMHITTAB string mouseconfig
+ { gen.mouse_device = $2;
+ gen.mouse_name = "mmhittab"; } |
+
+ XQUE keyboardconfig mouseconfig
+ { gen.mouse_name = "xqueue"; } |
+
+ OSMOUSE mouseconfig
+ { gen.mouse_name = "osmouse"; } |
+
+ OSMOUSE string mouseconfig
+ { gen.mouse_device = $2;
+ gen.mouse_name = "osmouse"; } |
+
+ /* We might have any graphics section */
+ VGA256 { scrn_index = iVGA256; SCRN.configured = 1; }
+ graphicsconfig |
+ VGA2 { scrn_index = iVGA2; SCRN.configured = 1; }
+ graphicsconfig |
+ MONO { scrn_index = iMONO; SCRN.configured = 1; }
+ graphicsconfig |
+ VGA16 { scrn_index = iVGA16; SCRN.configured = 1; }
+ graphicsconfig |
+ ACCEL { scrn_index = iACCEL; SCRN.configured = 1; }
+ graphicsconfig |
+ MODEDB modedb ;
+
+modedb :
+ /* empty */ { modelist = NULL; } |
+ modedb string { modename = $2; } modes ;
+
+modes :
+ /* empty */ |
+ modes
+ number
+ number number number number
+ number number number number
+ { flags = 0; } flags
+ { modelist = add_mode(modelist, modename,
+ $2, $3,$4,$5,$6, $7,$8,$9,$10, flags); } ;
+
+number : NUMBER { $$ = $1; } ; /* This once had a function */
+
+string : STRING { $$ = $1; } ;
+
+flags :
+ /* empty */ |
+ flags INTERLACE { flags |= fINTERLACE; } |
+ flags PHSYNC { flags |= fPHSYNC; } |
+ flags NHSYNC { flags |= fNHSYNC; } |
+ flags PVSYNC { flags |= fPVSYNC; } |
+ flags NVSYNC { flags |= fNVSYNC; } |
+ flags CSYNC { flags |= fCSYNC; } ;
+
+graphicsconfig :
+ /* empty */ | graphicsconfig gstmt ;
+
+/* Note: we may have more of these. */
+gstmt :
+ STATICGRAY { SCRN.Staticgray = 1; } |
+ GRAYSCALE { SCRN.Grayscale = 1; } |
+ STATICCOLOR { SCRN.Staticcolor = 1; } |
+ PSEUDOCOLOR { SCRN.Pseudocolor = 1; } |
+ TRUECOLOR { SCRN.Truecolor = 1; } |
+ DIRECTCOLOR { SCRN.Directcolor = 1; } |
+ CHIPSET string { SCRN.Chipset = $2; } |
+ RAMDAC string { SCRN.Ramdac = $2; } |
+ DACSPEED number { SCRN.Dacspeed = $2; } |
+ CLOCKS string { SCRN.Clockchip = $2; } |
+ CLOCKS clocks { SCRN.Clocks = add_list(SCRN.Clocks,$2); } |
+ DISPLAYSIZE number number
+ { SCRN.Displaysize1 = $2; SCRN.Displaysize2 = $3; } |
+ MODES strings { SCRN.Modes = $2; } |
+ SCREENNO number { SCRN.Screenno = $2; } |
+ OPTION string { SCRN.Option = add_string(SCRN.Option,$2); } |
+ VIDEORAM number { SCRN.Videoram = $2; } |
+ VIEWPORT number number
+ { SCRN.Viewport1 = $2; SCRN.Viewport2 = $3; } |
+ VIRTUAL number number
+ { SCRN.Virtual1 = $2; SCRN.Virtual2 = $3; } |
+ SPEEDUP string { SCRN.Speedup = $2; } |
+ SPEEDUP number { SCRN.Speedup = $2; } |
+ NOSPEEDUP { SCRN.Nospeedup = 1; } |
+ CLOCKPROG string { SCRN.Clockprog1 = $2; } |
+ CLOCKPROG string number
+ { SCRN.Clockprog1 = $2; SCRN.Clockprog2 = $3; } |
+ BIOSBASE number { SCRN.Biosbase = $2; } |
+ MEMBASE number { SCRN.Membase = $2; } |
+ BLACK number number number
+ { SCRN.Black1 = $2; SCRN.Black2 = $3; SCRN.Black3 = $4; } |
+ WHITE number number number
+ { SCRN.White1 = $2; SCRN.White2 = $3; SCRN.White3 = $4; } |
+ IOBASE number { SCRN.Iobase = $2; } |
+ DACBASE number { SCRN.Dacbase = $2; } |
+ COPBASE number { SCRN.Copbase = $2; } |
+ POSBASE number { SCRN.Posbase = $2; } |
+ INSTANCE number { SCRN.Instance = $2; } ;
+
+clocks :
+ /* empty */ { $$ = NULL; } |
+ clocks number { $$ = add_string($1,$2); } ;
+
+strings :
+ /* empty */ { $$ = NULL; } |
+ strings string { $$ = add_string($1,$2); } ;
+
+
+keyboardconfig :
+ /* empty */ | keyboardconfig keybstmt ;
+
+keybstmt :
+ AUTOREPEAT number number
+ { gen.Autorepeat1 = $2; gen.Autorepeat2 = $3; } |
+ DONTZAP { gen.Dontzap = 1; } |
+ SERVERNUM { gen.Servernum = 1; } |
+ XLEDS number { gen.Xleds = $2; } |
+ VTINIT string { gen.Vtinit = $2; } |
+ LEFTALT { kmap_index = iLEFTALT; } keymap |
+ RIGHTALT { kmap_index = iRIGHTALT; } keymap |
+ SCROLLLOCK { kmap_index = iSCROLLLOCK; } keymap |
+ RIGHTCTL { kmap_index = iRIGHTCTL; } keymap |
+ VTSYSREQ { gen.Vtsysreq = 1; } ;
+
+keymap :
+ K_META { gen.keymap[kmap_index] = "meta"; } |
+ K_COMPOSE { gen.keymap[kmap_index] = "compose"; } |
+ K_MODESHIFT { gen.keymap[kmap_index] = "modeshift"; } |
+ K_MODELOCK { gen.keymap[kmap_index] = "modelock"; } |
+ K_SCROLLLOCK { gen.keymap[kmap_index] = "scrollock"; } |
+ K_CONTROL { gen.keymap[kmap_index] = "control"; } ;
+
+mouseconfig :
+ /* empty */ | mouseconfig mousestmt ;
+
+mousestmt :
+ BAUDRATE number { gen.Baudrate = $2; } |
+ SAMPLERATE number { gen.Samplerate = $2; } |
+ EMULATE3 { gen.Emulate3 = 1; } |
+ CHORDMIDDLE { gen.Chordmiddle = 1; } |
+ CLEARDTR { gen.Cleardtr = 1; } |
+ CLEARRTS { gen.Clearrts = 1; } ;
+
+%%
+
+#define NEW(t) (t *)malloc(sizeof(t))
+#define REALLOC(n,t,d) (t *) realloc(d,n * sizeof(t))
+
+/* Add a string to a list of strings */
+string_list *add_string(sl,s)
+string_list *sl;
+char *s;
+{
+
+ if ( sl == NULL ) {
+ sl = NEW(string_list);
+ sl -> datap = NEW(char *);
+ (sl -> datap)[0] = s;
+ sl -> count = 1;
+ } else {
+ sl->datap = REALLOC((sl->count+1),char *,sl->datap);
+ (sl->datap)[sl->count] = s;
+ sl->count++;
+ }
+ return sl;
+}
+
+/* Add a list to a list of lists */
+string_list_list *add_list(sl,s)
+string_list_list *sl;
+string_list *s;
+{
+
+ if ( sl == NULL ) {
+ sl = NEW(string_list_list);
+ sl -> datap = NEW(string_list *);
+ (sl -> datap)[0] = s;
+ sl -> count = 1;
+ } else {
+ sl->datap = REALLOC((sl->count+1),string_list *,sl->datap);
+ (sl->datap)[sl->count] = s;
+ sl->count++;
+ }
+ return sl;
+}
+
+/* Add a mode to a list of modes */
+mode_list *add_mode(sl,mn,d,h1,h2,h3,h4,v1,v2,v3,v4,flags)
+mode_list *sl;
+char *mn;
+char *d, *h1,*h2,*h3,*h4, *v1,*v2,*v3,*v4;
+int flags;
+{
+ if ( sl == NULL ) {
+ sl = NEW(mode_list);
+ sl -> datap = NEW(struct mode);
+ sl -> datap[0].mn = mn;
+ sl -> datap[0].d = d;
+ sl -> datap[0].h1 = h1;
+ sl -> datap[0].h2 = h2;
+ sl -> datap[0].h3 = h3;
+ sl -> datap[0].h4 = h4;
+ sl -> datap[0].v1 = v1;
+ sl -> datap[0].v2 = v2;
+ sl -> datap[0].v3 = v3;
+ sl -> datap[0].v4 = v4;
+ sl -> datap[0].flags = flags;
+ sl -> count = 1;
+ } else {
+ sl->datap = REALLOC((sl->count+1),struct mode,sl->datap);
+ sl -> datap[sl->count].mn = mn;
+ sl -> datap[sl->count].d = d;
+ sl -> datap[sl->count].h1 = h1;
+ sl -> datap[sl->count].h2 = h2;
+ sl -> datap[sl->count].h3 = h3;
+ sl -> datap[sl->count].h4 = h4;
+ sl -> datap[sl->count].v1 = v1;
+ sl -> datap[sl->count].v2 = v2;
+ sl -> datap[sl->count].v3 = v3;
+ sl -> datap[sl->count].v4 = v4;
+ sl -> datap[sl->count].flags = flags;
+ sl->count++;
+ }
+ return sl;
+}
+
+main()
+{
+ if ( ! yyparse() ) {
+ copyright();
+ printf("# This file was generated by reconfig(1)\n");
+ printf("# Refer to the XF86Config(4/5) man page for a ");
+ printf("description of the format\n\n");
+ dump();
+ fprintf(stderr, "\n*** Note the XF86Config file generated ");
+ fprintf(stderr, "must be edited before use.\n\n");
+ }
+ exit(0);
+}
+
+yyerror(s)
+char *s;
+{
+ extern int line;
+ extern char *yytext;
+
+#if 0
+ fprintf(stderr, "%s on line %d while facing '%s'\n",s,line,yytext);
+#else
+ fprintf(stderr, "%s on line %d\n",s,line);
+#endif
+}
+
+dump()
+{
+ int i,j,k;
+
+ /* Files section */
+ printf("Section \"Files\"\n");
+ if ( gen.Fontpath ) {
+ for ( i = 0 ; i < gen.Fontpath->count ; i++ ) {
+ printf(" FontPath %s\n",
+ gen.Fontpath->datap[i]);
+ }
+ }
+ if ( gen.Rgbpath ) {
+ printf(" RGBPath %s\n",gen.Rgbpath);
+ }
+ printf("EndSection\n\n");
+
+ /* serverflags section */
+ printf("Section \"ServerFlags\"\n");
+ if ( gen.Notrapsignals ) {
+ printf(" NoTrapSignals\n");
+ }
+ if ( gen.Dontzap ) {
+ printf(" DontZap\n");
+ }
+ printf("EndSection\n\n");
+
+ /* Keyboard section */
+ printf("Section \"Keyboard\"\n");
+ if ( strcmp(gen.mouse_name,"xqueue") == 0 ) {
+ printf(" Protocol \"Xqueue\"\n");
+ } else {
+ printf(" Protocol \"Standard\"\n");
+ }
+ if ( gen.Autorepeat1 ) {
+ printf(" AutoRepeat %s %s\n",
+ gen.Autorepeat1, gen.Autorepeat2);
+ }
+ if ( gen.Servernum ) {
+ printf(" ServerNumLock\n");
+ }
+ if ( gen.Xleds ) {
+ printf(" Xleds %s\n", gen.Xleds);
+ }
+ if ( gen.Vtinit ) {
+ printf(" VTInit %s\n", gen.Vtinit);
+ }
+ for ( i = 0 ; i < N_KEYM ; i++ ) {
+ if (gen.keymap[i]) {
+ switch ( i ) {
+ case iLEFTALT: printf(" LEFTALT "); break;
+ case iRIGHTALT: printf(" RIGHTALT "); break;
+ case iSCROLLLOCK: printf(" SCROLLLOCK "); break;
+ case iRIGHTCTL: printf(" RIGHTCTL "); break;
+ }
+ printf("%s\n", gen.keymap[i]);
+ }
+ }
+ if ( gen.Vtsysreq ) {
+ printf(" VTSysReq\n");
+ }
+ printf("EndSection\n\n");
+
+ printf("Section \"Pointer\"\n");
+ if ( gen.mouse_name ) {
+ printf(" Protocol \"%s\"\n",gen.mouse_name);
+ }
+ if ( gen.mouse_device ) {
+ printf(" Device %s\n",gen.mouse_device);
+ }
+ if ( gen.Baudrate ) {
+ printf(" BaudRate %s\n",gen.Baudrate);
+ }
+ if ( gen.Samplerate ) {
+ printf(" SampleRate %s\n",gen.Samplerate);
+ }
+ if ( gen.Emulate3 ) {
+ printf(" Emulate3Buttons\n");
+ }
+ if ( gen.Chordmiddle ) {
+ printf(" ChordMiddle\n");
+ }
+ if ( gen.Cleardtr ) {
+ printf(" ClearDTR\n");
+ }
+ if ( gen.Clearrts ) {
+ printf(" ClearRTS\n");
+ }
+ printf("EndSection\n\n");
+
+ /* Now print monitor, device and screen sections, for each screen */
+ for ( j = 0 ; j < N_SCREENS ; j++ ) {
+ scrn_index = j;
+ if ( !SCRN.configured ) continue;
+
+ printf("Section \"Monitor\"\n");
+ printf(" Identifier \"RandomMonitor-%d\"\n",scrn_index);
+ printf(" VendorName \"Unknown\"\n");
+ printf(" ModelName \"Unknown\"\n");
+ printf(" BandWidth 25.2\t# EDIT THIS!\n");
+ printf(" HorizSync 31.5\t# EDIT THIS!\n");
+ printf(" VertRefresh 60\t# EDIT THIS!\n");
+ if ( modelist ) {
+ for ( i = 0 ; i < modelist->count ; i++ ) {
+ printf(" ModeLine");
+ printf(" %s", modelist->datap[i].mn);
+ printf(" %s", modelist->datap[i].d);
+ printf(" %s", modelist->datap[i].h1);
+ printf(" %s", modelist->datap[i].h2);
+ printf(" %s", modelist->datap[i].h3);
+ printf(" %s", modelist->datap[i].h4);
+ printf(" %s", modelist->datap[i].v1);
+ printf(" %s", modelist->datap[i].v2);
+ printf(" %s", modelist->datap[i].v3);
+ printf(" %s", modelist->datap[i].v4);
+ if ( modelist->datap[i].flags & fINTERLACE )
+ printf(" interlace");
+ if ( modelist->datap[i].flags & fPHSYNC )
+ printf(" +hsync");
+ if ( modelist->datap[i].flags & fNHSYNC )
+ printf(" -hsync");
+ if ( modelist->datap[i].flags & fPVSYNC )
+ printf(" +vsync");
+ if ( modelist->datap[i].flags & fNVSYNC )
+ printf(" -vsync");
+ if ( modelist->datap[i].flags & fCSYNC )
+ printf(" composite");
+ printf("\n");
+ }
+ }
+ printf("EndSection\n\n");
+
+ printf("Section \"Device\"\n");
+ printf(" Identifier \"RandomDevice-%d\"\n",scrn_index);
+ printf(" VendorName \"Unknown\"\n");
+ printf(" BoardName \"Unknown\"\n");
+ if ( SCRN.Chipset ) {
+ printf(" Chipset %s\n",SCRN.Chipset);
+ }
+ if ( SCRN.Ramdac ) {
+ printf(" Ramdac %s\n",SCRN.Ramdac);
+ }
+ if ( SCRN.Dacspeed ) {
+ printf(" Dacspeed %s\n",SCRN.Dacspeed);
+ }
+ if ( SCRN.Clockchip ) {
+ printf(" Clockchip %s\n",SCRN.Clockchip);
+ }
+ if ( SCRN.Clocks ) {
+ /* j is used to go over the screens. */
+ for ( k = 0 ; k < SCRN.Clocks->count ; k++ ) {
+ string_list *clcks = SCRN.Clocks->datap[k];
+
+ if ( clcks ) {
+ printf(" Clocks");
+ for ( i = 0 ; i < clcks->count ; i++ ) {
+ printf(" %s",clcks->datap[i]);
+ }
+ printf("\n");
+ }
+ }
+ }
+ if ( SCRN.Option ) {
+ for ( i = 0 ; i < SCRN.Option->count ; i++ ) {
+ printf(" Option %s\n",SCRN.Option->datap[i]);
+ }
+ }
+ if ( SCRN.Videoram ) {
+ printf(" Videoram %s\n",SCRN.Videoram);
+ }
+ if ( SCRN.Speedup ) {
+ printf(" Speedup %s\n",SCRN.Speedup);
+ }
+ if ( SCRN.Clockprog1 ) {
+ printf(" Clockprog %s",SCRN.Clockprog1);
+ if ( SCRN.Clockprog2 ) {
+ printf(" %s",SCRN.Clockprog2);
+ }
+ printf("\n");
+ }
+ if ( SCRN.Biosbase ) {
+ printf(" Biosbase %s\n",SCRN.Biosbase);
+ }
+ if ( SCRN.Membase ) {
+ printf(" Membase %s\n",SCRN.Membase);
+ }
+ if ( SCRN.Iobase ) {
+ printf(" Iobase %s\n",SCRN.Iobase);
+ }
+ if ( SCRN.Dacbase ) {
+ printf(" Dacbase %s\n",SCRN.Dacbase);
+ }
+ if ( SCRN.Copbase ) {
+ printf(" Copbase %s\n",SCRN.Copbase);
+ }
+ if ( SCRN.Posbase ) {
+ printf(" Speedup %s\n",SCRN.Posbase);
+ }
+ if ( SCRN.Instance ) {
+ printf(" Instance %s\n",SCRN.Instance);
+ }
+ printf("EndSection\n\n");
+
+ /* Screen section */
+ printf("Section \"Screen\"\n");
+ switch ( scrn_index ) {
+ case iVGA256: printf(" Driver \"vga256\"\n"); break;
+ case iVGA2: printf(" Driver \"vga2\"\n"); break;
+ case iMONO: printf(" Driver \"mono\"\n"); break;
+ case iVGA16: printf(" Driver \"vga16\"\n"); break;
+ case iACCEL: printf(" Driver \"accel\"\n"); break;
+ }
+ printf(" Device \"RandomDevice-%d\"\n",scrn_index);
+ printf(" Monitor \"RandomMonitor-%d\"\n",scrn_index);
+ if ( SCRN.Screenno ) {
+ printf(" Screenno %s\n",SCRN.Screenno);
+ }
+ printf(" Subsection \"Display\"\n");
+ if ( SCRN.Staticgray ) {
+ printf(" StaticGray\n");
+ }
+ if ( SCRN.Grayscale ) {
+ printf(" GrayScale\n");
+ }
+ if ( SCRN.Staticcolor ) {
+ printf(" StaticColor\n");
+ }
+ if ( SCRN.Pseudocolor ) {
+ printf(" PseudoColor\n");
+ }
+ if ( SCRN.Truecolor ) {
+ printf(" TrueColor\n");
+ }
+ if ( SCRN.Directcolor ) {
+ printf(" DirectColor\n");
+ }
+ if ( SCRN.Displaysize1 ) {
+ printf(" DisplaySize %s %s\n",
+ SCRN.Displaysize1,SCRN.Displaysize2);
+ }
+ if ( SCRN.Modes ) {
+ printf(" Modes");
+ for ( i = 0 ; i < SCRN.Modes->count ; i++ ) {
+ printf(" %s",SCRN.Modes->datap[i]);
+ }
+ printf("\n");
+ }
+ if ( SCRN.Viewport1 ) {
+ printf(" ViewPort %s %s\n",
+ SCRN.Viewport1,SCRN.Viewport2);
+ }
+ if ( SCRN.Virtual1 ) {
+ printf(" Virtual %s %s\n",
+ SCRN.Virtual1,SCRN.Virtual2);
+ }
+ if ( SCRN.Black1 ) {
+ printf(" Black %s %s %s\n",
+ SCRN.Black1,SCRN.Black2,SCRN.Black3);
+ }
+ if ( SCRN.White1 ) {
+ printf(" White %s %s %s\n",
+ SCRN.White1,SCRN.White2,SCRN.White3);
+ }
+ printf(" EndSubsection\n");
+ printf("EndSection\n\n");
+ } /* screens */
+} /* function */
diff --git a/xc/programs/Xserver/hw/xfree86/reconfig/strlist.h b/xc/programs/Xserver/hw/xfree86/reconfig/strlist.h
new file mode 100644
index 000000000..0f7a08cd8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/reconfig/strlist.h
@@ -0,0 +1,18 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/reconfig/strlist.h,v 3.3 1996/12/23 06:51:46 dawes Exp $ */
+
+
+
+
+
+/* $XConsortium: strlist.h /main/4 1996/02/21 17:55:17 kaleb $ */
+
+/* Used in the %union, therefore to be included in the scanner. */
+typedef struct {
+ int count;
+ char **datap;
+} string_list ;
+
+typedef struct {
+ int count;
+ string_list **datap;
+} string_list_list;
diff --git a/xc/programs/Xserver/hw/xfree86/scanpci/Imakefile b/xc/programs/Xserver/hw/xfree86/scanpci/Imakefile
new file mode 100644
index 000000000..947e02735
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/scanpci/Imakefile
@@ -0,0 +1,30 @@
+
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/scanpci/Imakefile,v 1.6 1999/08/14 10:50:08 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+MODPATHDEFINES = -DDEFAULT_MODULE_PATH=\"$(MODULEDIR)\"
+ INCLUDES = -I$(XF86SRC)/common -I$(XF86OSSRC) -I$(XF86OSSRC)/bus \
+ -I$(SERVERSRC)/include -I$(SERVERSRC)/os \
+ -I$(XINCLUDESRC) -I$(SERVERSRC)/Xext -I$(EXTINCSRC) \
+ -I$(SERVERSRC)/Xi \
+ -I$(FONTLIBSRC)/include -I$(XF86PARSERSRC) \
+ -I$(XF86SRC)/loader $(VGAINCLUDES) -I$(XF86SRC)/rac
+
+SRCS = xf86ScanPci.c xf86PciData.c
+
+ModuleObjectRule()
+
+LibraryModuleTarget(scanpci,xf86ScanPci.o)
+
+InstallLibraryModule(scanpci,$(MODULEDIR),.)
+
+LibraryModuleTarget(pcidata,xf86PciData.o)
+
+InstallLibraryModule(pcidata,$(MODULEDIR),.)
+
+DependTarget()
+
+InstallDriverSDKLibraryModule(scanpci,$(DRIVERSDKMODULEDIR),.)
+InstallDriverSDKLibraryModule(pcidata,$(DRIVERSDKMODULEDIR),.)
diff --git a/xc/programs/Xserver/hw/xfree86/scanpci/xf86PciData.c b/xc/programs/Xserver/hw/xfree86/scanpci/xf86PciData.c
new file mode 100644
index 000000000..aa0a8fc88
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/scanpci/xf86PciData.c
@@ -0,0 +1,46 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/scanpci/xf86PciData.c,v 1.2 1999/02/15 18:47:35 hohndel Exp $ */
+/*
+ * the PCI data structures
+ *
+ * this module only includes the data that is relevant for video boards
+ * the non-video data is included in the scanpci module
+ *
+ * Copyright 1995-1999 by The XFree86 Project, Inc.
+ *
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include "X.h"
+#include "os.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86Pci.h"
+
+#define INIT_PCI_CARD_INFO TRUE
+#define DECLARE_CARD_DATASTRUCTURES TRUE
+#define INIT_PCI_VENDOR_INFO TRUE
+#define INIT_PCI_VENDOR_NAME_INFO TRUE
+#include "xf86PciInfo.h"
+
+#ifdef XFree86LOADER
+
+#include "xf86Module.h"
+
+static XF86ModuleVersionInfo pciDataVersRec = {
+ "pcidata",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 0, 1, 0,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ NULL,
+ {0, 0, 0, 0}
+};
+
+XF86ModuleData pcidataModuleData = { &pciDataVersRec, NULL, NULL };
+
+#endif /* XFree86LOADER */
+
diff --git a/xc/programs/Xserver/hw/xfree86/scanpci/xf86ScanPci.c b/xc/programs/Xserver/hw/xfree86/scanpci/xf86ScanPci.c
new file mode 100644
index 000000000..b519b6b93
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/scanpci/xf86ScanPci.c
@@ -0,0 +1,223 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/scanpci/xf86ScanPci.c,v 1.6 1999/04/04 10:59:50 dawes Exp $ */
+/*
+ * Display the Subsystem Vendor Id and Subsystem Id in order to identify
+ * the cards installed in this computer
+ *
+ * Copyright 1995-1998 by The XFree86 Project, Inc.
+ *
+ * A lot of this comes from Robin Cutshaw's scanpci
+ *
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include "X.h"
+#include "os.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86Pci.h"
+
+#define INIT_PCI_CARD_INFO TRUE
+#define DECLARE_CARD_DATASTRUCTURES TRUE
+#define INIT_PCI_VENDOR_INFO TRUE
+#define INIT_PCI_VENDOR_NAME_INFO TRUE
+#define VENDOR_INCLUDE_NONVIDEO TRUE
+#include "xf86PciInfo.h"
+
+/*
+ * PCI classes that have messages printed always. The others are only
+ * have a message printed when the vendor/dev IDs are recognised.
+ */
+#define PCIALWAYSPRINTCLASSES(b,s) \
+ (((b) == PCI_CLASS_PREHISTORIC && (s) == PCI_SUBCLASS_PREHISTORIC_VGA) || \
+ ((b) == PCI_CLASS_DISPLAY) || \
+ ((b) == PCI_CLASS_MULTIMEDIA && (s) == PCI_SUBCLASS_MULTIMEDIA_VIDEO))
+
+
+void xf86DisplayPCICardInfo(int);
+
+
+#ifdef XFree86LOADER
+
+#include "xf86Module.h"
+
+static XF86ModuleVersionInfo scanPciVersRec = {
+ "scanpci",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 0, 1, 0,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ NULL,
+ {0, 0, 0, 0}
+};
+
+XF86ModuleData scanpciModuleData = { &scanPciVersRec, NULL, NULL };
+
+#else
+
+/*
+ * setup the pci data structures for the static server
+ */
+void
+xf86InitPciData(void)
+{
+ xf86PCIVendorNameInfo = xf86PCIVendorNameInfoData;
+ xf86PCIVendorInfo = xf86PCIVendorInfoData;
+ xf86PCICardInfo = xf86PCICardInfoData;
+}
+
+#endif /* XFree86LOADER */
+
+
+void
+xf86DisplayPCICardInfo(int verbosity)
+{
+ pciConfigPtr pcrp, *pcrpp;
+ int i = 0, j,k;
+ pciVendorCardInfo *info;
+ Bool noCard = FALSE;
+
+ xf86EnableIO();
+ pcrpp = xf86scanpci(0);
+
+ if (pcrpp == NULL) {
+ xf86MsgVerb(X_NONE,0,"No PCI info available\n");
+ return;
+ }
+ xf86MsgVerb(X_NONE,0,"Probing for PCI devices (Bus:Device:Function)\n\n");
+ while ((pcrp = pcrpp[i])) {
+ char *vendorname = NULL, *cardname = NULL;
+ char *chipvendorname = NULL, *chipname = NULL;
+ Bool noCard = FALSE;
+
+ xf86MsgVerb(X_NONE,-verbosity,
+ "(%d:%d:%d) ", pcrp->busnum, pcrp->devnum,
+ pcrp->funcnum);
+
+ /* first let's look for the card itself, but only if information
+ * is available
+ */
+ if ( pcrp->pci_subsys_vendor || pcrp->pci_subsys_card ) {
+ k = 0;
+ while (xf86PCIVendorNameInfo[k].token) {
+ if (xf86PCIVendorNameInfo[k].token == pcrp->pci_subsys_vendor)
+ vendorname = (char*)xf86PCIVendorNameInfo[k].name;
+ k++;
+ }
+ k = 0;
+ while(xf86PCICardInfo[k].VendorID) {
+ if (xf86PCICardInfo[k].VendorID == pcrp->pci_subsys_vendor) {
+ j = 0;
+ while (xf86PCICardInfo[k].Device[j].CardName) {
+ if (xf86PCICardInfo[k].Device[j].SubsystemID ==
+ pcrp->pci_subsys_card) {
+ cardname =
+ xf86PCICardInfo[k].Device[j].CardName;
+ break;
+ }
+ j++;
+ }
+ break;
+ }
+ k++;
+ }
+ if (vendorname)
+ xf86MsgVerb(X_NONE,-verbosity,"%s ", vendorname);
+ if (cardname)
+ xf86MsgVerb(X_NONE,-verbosity,"%s ", cardname);
+ if (vendorname && !cardname)
+ if (pcrp->pci_subsys_card)
+ xf86MsgVerb(X_NONE,-verbosity,"unknown card (0x%04x) ",
+ pcrp->pci_subsys_card);
+ else
+ xf86MsgVerb(X_NONE,-verbosity,"card ",
+ pcrp->pci_subsys_card);
+ }
+ if (!(cardname || vendorname)) {
+ /*
+ * we didn't find text representation of the information
+ * about the card
+ */
+ if ( pcrp->pci_subsys_vendor || pcrp->pci_subsys_card ) {
+ /*
+ * if there was information and we just couldn't interpret
+ * it, print it out as unknown, anyway
+ */
+ xf86MsgVerb(X_NONE,-verbosity,
+ "unknown card (0x%04x/0x%04x) \n\t",
+ pcrp->pci_subsys_vendor, pcrp->pci_subsys_card);
+ }
+ else {
+ /*
+ * if there was no info to begin with, only print in
+ * verbose mode
+ */
+ if (verbosity > 1)
+ xf86MsgVerb(X_NONE,-verbosity,
+ "unknown card (0x%04x/0x%04x) \n\t",
+ pcrp->pci_subsys_vendor, pcrp->pci_subsys_card);
+ else
+ noCard = TRUE;
+ }
+ }
+ /* now check for the chipset used */
+ k = 0;
+ while (xf86PCIVendorNameInfo[k].token) {
+ if (xf86PCIVendorNameInfo[k].token == pcrp->pci_vendor)
+ chipvendorname = (char *)xf86PCIVendorNameInfo[k].name;
+ k++;
+ }
+ k = 0;
+ while(xf86PCIVendorInfo[k].VendorID) {
+ if (xf86PCIVendorInfo[k].VendorID == pcrp->pci_vendor) {
+ j = 0;
+ while (xf86PCIVendorInfo[k].Device[j].DeviceName) {
+ if (xf86PCIVendorInfo[k].Device[j].DeviceID ==
+ pcrp->pci_device) {
+ chipname =
+ xf86PCIVendorInfo[k].Device[j].DeviceName;
+ break;
+ }
+ j++;
+ }
+ break;
+ }
+ k++;
+ }
+ if (noCard) {
+ if (chipvendorname && chipname)
+ xf86MsgVerb(X_NONE,-verbosity,"%s %s",
+ chipvendorname,chipname);
+ else if (chipvendorname)
+ xf86MsgVerb(X_NONE,-verbosity,
+ "unknown chip (DeviceId 0x%04x) from %s",
+ pcrp->pci_device,chipvendorname);
+ else
+ xf86MsgVerb(X_NONE,-verbosity,
+ "unknown chipset(0x%04x/0x%04x)",
+ pcrp->pci_vendor,pcrp->pci_device);
+ xf86MsgVerb(X_NONE,-verbosity,"\n");
+ }
+ else
+ {
+ if (chipvendorname && chipname)
+ xf86MsgVerb(X_NONE,-verbosity,"using a %s %s",
+ chipvendorname,chipname);
+ else if (chipvendorname)
+ xf86MsgVerb(X_NONE,-verbosity,
+ "using an unknown chip (DeviceId 0x%04x) from %s",
+ pcrp->pci_device,chipvendorname);
+ else
+ xf86MsgVerb(X_NONE,-verbosity,
+ "using an unknown chipset(0x%04x/0x%04x)",
+ pcrp->pci_vendor,pcrp->pci_device);
+ xf86MsgVerb(X_NONE,-verbosity,"\n");
+ }
+ i++;
+ }
+}
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/sdk/Imakefile b/xc/programs/Xserver/hw/xfree86/sdk/Imakefile
new file mode 100644
index 000000000..2a9bfbd1e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/sdk/Imakefile
@@ -0,0 +1,10 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/sdk/Imakefile,v 1.1 1999/08/14 10:50:08 dawes Exp $
+
+CppScriptTarget(mkmf,mkmf.cpp,-DCONFIGDIRSPEC=-I$(CONFIGDIR),$(ICONFIGFILES))
+
+InstallDriverSDKNamedNonExec(Imakefile.SDK,Imakefile,$(DRIVERSDKDIR))
+InstallDriverSDKNamedNonExec(site.def.SDK,xf86site.def,$(DRIVERSDKDIR))
+InstallDriverSDKNamedProg(mkmf,mkmf,$(DRIVERSDKDIR))
+#if !HasLinuxDoc
+InstallDriverSDKNonExecFile(README,$(DRIVERSDKDIR))
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/sdk/Imakefile.SDK b/xc/programs/Xserver/hw/xfree86/sdk/Imakefile.SDK
new file mode 100644
index 000000000..d5bca1af1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/sdk/Imakefile.SDK
@@ -0,0 +1,35 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/sdk/Imakefile.SDK,v 1.1 1999/08/14 10:50:08 dawes Exp $
+/*
+ * Server Makefile for Driver SDK
+ */
+
+
+#define IHaveModules
+#include <Server.tmpl>
+#define IHaveSubdirs
+
+SUBDIRS = drivers
+
+MakeSubdirs($(SUBDIRS))
+
+#if MakeHasPosixVariableSubstitutions
+DONES = $(SUBDIRS:%=%/DONE)
+#if HasGnuMake || HasBsdMake
+$(DONES): $(SUBDIRS)
+#endif
+#endif
+
+NormalLibraryObjectRule()
+
+ForceSubdirs($(SUBDIRS))
+
+DependSubdirs($(SUBDIRS))
+
+
+
+
+
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/sdk/README b/xc/programs/Xserver/hw/xfree86/sdk/README
new file mode 100644
index 000000000..862457997
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/sdk/README
@@ -0,0 +1,37 @@
+Write me!!!!!
+
+Build the drivers in the SDK
+----------------------------
+
+% ./mkmf
+% make
+
+Testing the built drivers
+-------------------------
+* edit the ./XF86Config file appropriately, as well as adding the line
+
+ ModulePath "$(DriverSDKDir)/modules"
+
+ to the files section of the XF86Config file, where DriverSDKDir is usually
+ /usr/X11R6/lib/Server. Then run the command
+
+% xinit -- ./XFree86 -xf86config ./XF86config
+
+Basic instructions to add driver "foo" to SDK
+----------------------------------------------
+
+* edit xf86site.def file adding a line like
+
+ #define XF86ExtraCardDrivers foo
+
+* create a directory drivers/foo, and copy the drivers/vga/Imakefile to it
+
+* Replace instances of vga in Imakefile with "foo" and instances of "generic"
+ with another suitable name
+
+* Read the DESIGN document about how to write a driver, and use
+ drivers/vga/generic.c as a basis to write the new driver.
+
+
+
+$XFree86: xc/programs/Xserver/hw/xfree86/sdk/README,v 1.1 1999/08/14 10:50:08 dawes Exp $
diff --git a/xc/programs/Xserver/hw/xfree86/sdk/mkmf.cpp b/xc/programs/Xserver/hw/xfree86/sdk/mkmf.cpp
new file mode 100644
index 000000000..df1dc36c2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/sdk/mkmf.cpp
@@ -0,0 +1,38 @@
+XCOMM!/bin/sh
+XCOMM
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/sdk/mkmf.cpp,v 1.1 1999/08/14 10:50:09 dawes Exp $
+
+XCOMM
+XCOMM Build Makefile for Driver SDK
+XCOMM
+
+if [ ! -x ./mkmf ]; then
+ echo "mkmf cannot be executed from this directory"
+ exit 1
+fi
+
+if [ -d ./config ]; then
+ CONFIG_DIR_SPEC=-I./config/cf
+ IMAKE_COMMAND=./config/imake/imake
+elif [ x"$XWINHOME" != x ]; then
+ CONFIG_DIR_SPEC=-I$XWINHOME/lib/X11/config
+ IMAKE_COMMAND="imake -DUseInstalled"
+else
+ CONFIG_DIR_SPEC=CONFIGDIRSPEC
+ IMAKE_COMMAND="imake -DUseInstalled"
+fi
+
+if [ -f Makefile ]; then
+ (set -x
+ rm -f Makefile.bak
+ mv Makefile Makefile.bak
+ )
+fi
+rm -f Makefile
+(set -x
+ $IMAKE_COMMAND -I. $CONFIG_DIR_SPEC -DXF86DriverSDK=1 -DTOPDIR=. -DCURDIR=.
+ make Makefiles
+XCOMM make clean
+ make depend
+)
+
diff --git a/xc/programs/Xserver/hw/xfree86/sdk/site.def.SDK b/xc/programs/Xserver/hw/xfree86/sdk/site.def.SDK
new file mode 100644
index 000000000..9712b5b5f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/sdk/site.def.SDK
@@ -0,0 +1,17 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/sdk/site.def.SDK,v 1.1 1999/08/14 10:50:09 dawes Exp $
+XCOMM ------------------------------------------------------------------
+XCOMM Site file for the driver SDK. You should add site specific information
+XCOMM here. In particular adding a driver to the SDK requires that you add
+XCOMM a line like
+XCOMM
+XCOMM
+XCOMM to this file
+XCOMM ------------------------------------------------------------------
+
+
+XCOMM
+XCOMM Define XF86ExtraCardDrivers to add new drivers to the SDK
+XCOMM
+#if 0
+#define XF86ExtraCardDrivers foo
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/shadowfb/Imakefile b/xc/programs/Xserver/hw/xfree86/shadowfb/Imakefile
new file mode 100644
index 000000000..4438f87e8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/shadowfb/Imakefile
@@ -0,0 +1,32 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/shadowfb/Imakefile,v 1.3 1999/08/14 10:50:09 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+
+#if DoLoadableServer
+XFMODSRC = sfbmodule.c
+XFMODOBJ = sfbmodule.o
+#endif
+
+SRCS = shadow.c $(XFMODSRC)
+
+
+OBJS = shadow.o $(XFMODOBJ)
+
+INCLUDES = -I. -I$(SERVERSRC)/mi -I$(SERVERSRC)/include \
+ -I$(XF86OSSRC) -I$(XF86COMSRC) -I$(XINCLUDESRC) -I$(FONTINCSRC)
+
+
+ModuleObjectRule()
+LibraryModuleTarget(shadowfb,$(OBJS))
+LintLibraryTarget(shadowfb,$(SRCS))
+NormalLintTarget($(LINTDEFS) $(SRCS))
+
+InstallLibraryModule(shadowfb,$(MODULEDIR),.)
+
+DependTarget()
+
+InstallDriverSDKLibraryModule(shadowfb,$(DRIVERSDKMODULEDIR),.)
+
+InstallDriverSDKNonExecFile(shadowfb.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/xc/programs/Xserver/hw/xfree86/shadowfb/sfbmodule.c b/xc/programs/Xserver/hw/xfree86/shadowfb/sfbmodule.c
new file mode 100644
index 000000000..3bb14b0a9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/shadowfb/sfbmodule.c
@@ -0,0 +1,24 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/shadowfb/sfbmodule.c,v 1.2 1999/02/01 12:08:45 dawes Exp $ */
+
+
+#ifdef XFree86LOADER
+
+#include "xf86Module.h"
+
+static XF86ModuleVersionInfo VersRec =
+{
+ "shadowfb",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_ANSIC, /* Only need the ansic layer */
+ ABI_ANSIC_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0} /* signature, to be patched into the file by a tool */
+};
+
+XF86ModuleData shadowfbModuleData = { &VersRec, NULL, NULL };
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/shadowfb/shadow.c b/xc/programs/Xserver/hw/xfree86/shadowfb/shadow.c
new file mode 100644
index 000000000..45ca734af
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/shadowfb/shadow.c
@@ -0,0 +1,1385 @@
+/*
+ Copyright (C) 1999. The XFree86 Project Inc.
+
+ Written by Mark Vojkovich (mvojkovi@ucsd.edu)
+*/
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/shadowfb/shadow.c,v 1.5 1999/02/07 06:18:48 dawes Exp $ */
+
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "pixmapstr.h"
+#include "input.h"
+#include "font.h"
+#include "mi.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "gcstruct.h"
+#include "dixfontstr.h"
+#include "fontstruct.h"
+#include "xf86.h"
+#include "xf86str.h"
+#include "shadowfb.h"
+
+
+static Bool ShadowCloseScreen (int i, ScreenPtr pScreen);
+static void ShadowRestoreAreas (
+ PixmapPtr pPixmap,
+ RegionPtr prgn,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+);
+static void ShadowPaintWindow (
+ WindowPtr pWin,
+ RegionPtr prgn,
+ int what
+);
+static void ShadowCopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgn
+);
+static Bool ShadowCreateGC(GCPtr pGC);
+
+static Bool ShadowEnterVT(int index, int flags);
+static void ShadowLeaveVT(int index, int flags);
+static Bool ShadowSaveRestoreImage(int index, SaveRestoreFlags what);
+
+
+typedef struct {
+ ScrnInfoPtr pScrn;
+ RefreshAreaFuncPtr refresh;
+ CloseScreenProcPtr CloseScreen;
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ CopyWindowProcPtr CopyWindow;
+ CreateGCProcPtr CreateGC;
+ BackingStoreRestoreAreasProcPtr RestoreAreas;
+ Bool (*EnterVT)(int, int);
+ void (*LeaveVT)(int, int);
+ Bool (*SaveRestoreImage)(int, SaveRestoreFlags);
+ Bool vtSema;
+} ShadowScreenRec, *ShadowScreenPtr;
+
+typedef struct {
+ GCOps *ops;
+ GCFuncs *funcs;
+} ShadowGCRec, *ShadowGCPtr;
+
+
+static int ShadowScreenIndex = -1;
+static int ShadowGCIndex = -1;
+static unsigned long ShadowGeneration = 0;
+
+#define GET_SCREEN_PRIVATE(pScreen) \
+ (ShadowScreenPtr)((pScreen)->devPrivates[ShadowScreenIndex].ptr)
+#define GET_GC_PRIVATE(pGC) \
+ (ShadowGCPtr)((pGC)->devPrivates[ShadowGCIndex].ptr)
+
+#define SHADOW_GC_FUNC_PROLOGUE(pGC)\
+ ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC);\
+ (pGC)->funcs = pGCPriv->funcs;\
+ if(pGCPriv->ops)\
+ (pGC)->ops = pGCPriv->ops
+
+#define SHADOW_GC_FUNC_EPILOGUE(pGC)\
+ pGCPriv->funcs = (pGC)->funcs;\
+ (pGC)->funcs = &ShadowGCFuncs;\
+ if(pGCPriv->ops) {\
+ pGCPriv->ops = (pGC)->ops;\
+ (pGC)->ops = &ShadowGCOps;\
+ }
+
+#define SHADOW_GC_OP_PROLOGUE(pGC)\
+ ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pGC->pScreen); \
+ ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC);\
+ GCFuncs *oldFuncs = pGC->funcs;\
+ pGC->funcs = pGCPriv->funcs;\
+ pGC->ops = pGCPriv->ops
+
+
+#define SHADOW_GC_OP_EPILOGUE(pGC)\
+ pGCPriv->ops = pGC->ops;\
+ pGC->funcs = oldFuncs;\
+ pGC->ops = &ShadowGCOps
+
+#define IS_VISIBLE(pWin) (pPriv->vtSema && \
+ (((WindowPtr)pWin)->visibility != VisibilityFullyObscured))
+
+#define TRIM_BOX(box, pGC) { \
+ BoxPtr extents = &pGC->pCompositeClip->extents;\
+ if(box.x1 < extents->x1) box.x1 = extents->x1; \
+ if(box.x2 > extents->x2) box.x2 = extents->x2; \
+ if(box.y1 < extents->y1) box.y1 = extents->y1; \
+ if(box.y2 > extents->y2) box.y2 = extents->y2; \
+ }
+
+#define TRANSLATE_BOX(box, pDraw) { \
+ box.x1 += pDraw->x; \
+ box.x2 += pDraw->x; \
+ box.y1 += pDraw->y; \
+ box.y2 += pDraw->y; \
+ }
+
+#define TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC) { \
+ TRANSLATE_BOX(box, pDraw); \
+ TRIM_BOX(box, pGC); \
+ }
+
+#define BOX_NOT_EMPTY(box) \
+ (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))
+
+
+
+Bool
+ShadowFBInit (
+ ScreenPtr pScreen,
+ RefreshAreaFuncPtr refreshArea
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ ShadowScreenPtr pPriv;
+
+ if(!refreshArea) return FALSE;
+
+ if (ShadowGeneration != serverGeneration) {
+ if(((ShadowScreenIndex = AllocateScreenPrivateIndex ()) < 0) ||
+ ((ShadowGCIndex = AllocateGCPrivateIndex()) < 0))
+ return FALSE;
+ ShadowGeneration = serverGeneration;
+ }
+
+ if(!AllocateGCPrivate(pScreen, ShadowGCIndex, sizeof(ShadowGCRec)))
+ return FALSE;
+
+ if(!(pPriv = (ShadowScreenPtr)xalloc(sizeof(ShadowScreenRec))))
+ return FALSE;
+
+ pScreen->devPrivates[ShadowScreenIndex].ptr = (pointer)pPriv;
+
+ pPriv->pScrn = pScrn;
+ pPriv->refresh = refreshArea;
+ pPriv->vtSema = TRUE;
+
+ pPriv->CloseScreen = pScreen->CloseScreen;
+ pPriv->PaintWindowBackground = pScreen->PaintWindowBackground;
+ pPriv->PaintWindowBorder = pScreen->PaintWindowBorder;
+ pPriv->CopyWindow = pScreen->CopyWindow;
+ pPriv->CreateGC = pScreen->CreateGC;
+ pPriv->RestoreAreas = pScreen->BackingStoreFuncs.RestoreAreas;
+
+ pPriv->EnterVT = pScrn->EnterVT;
+ pPriv->LeaveVT = pScrn->LeaveVT;
+ pPriv->SaveRestoreImage = pScrn->SaveRestoreImage;
+
+ pScreen->CloseScreen = ShadowCloseScreen;
+ pScreen->PaintWindowBackground = ShadowPaintWindow;
+ pScreen->PaintWindowBorder = ShadowPaintWindow;
+ pScreen->CopyWindow = ShadowCopyWindow;
+ pScreen->CreateGC = ShadowCreateGC;
+ pScreen->BackingStoreFuncs.RestoreAreas = ShadowRestoreAreas;
+
+ pScrn->EnterVT = ShadowEnterVT;
+ pScrn->LeaveVT = ShadowLeaveVT;
+ pScrn->SaveRestoreImage = ShadowSaveRestoreImage;
+
+ return TRUE;
+}
+
+/**********************************************************/
+
+static Bool
+ShadowEnterVT(int index, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScrn->pScreen);
+ BoxRec box;
+
+ if((*pPriv->EnterVT)(index, flags)) {
+ pPriv->vtSema = TRUE;
+
+ box.x1 = box.y1 = 0;
+ box.x2 = pScrn->virtualX - 1;
+ box.y2 = pScrn->virtualY - 1;
+
+ (*pPriv->refresh)(pScrn, 1, &box);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+ShadowLeaveVT(int index, int flags)
+{
+ ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(xf86Screens[index]->pScreen);
+
+ pPriv->vtSema = FALSE;
+
+ (*pPriv->LeaveVT)(index, flags);
+}
+
+static Bool
+ShadowSaveRestoreImage(int index, SaveRestoreFlags what)
+{
+ return TRUE;
+}
+
+
+/**********************************************************/
+
+
+static Bool
+ShadowCloseScreen (int i, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
+
+ pScreen->CloseScreen = pPriv->CloseScreen;
+ pScreen->PaintWindowBackground = pPriv->PaintWindowBackground;
+ pScreen->PaintWindowBorder = pPriv->PaintWindowBorder;
+ pScreen->CopyWindow = pPriv->CopyWindow;
+ pScreen->CreateGC = pPriv->CreateGC;
+ pScreen->BackingStoreFuncs.RestoreAreas = pPriv->RestoreAreas;
+
+ pScrn->EnterVT = pPriv->EnterVT;
+ pScrn->LeaveVT = pPriv->LeaveVT;
+ pScrn->SaveRestoreImage = pPriv->SaveRestoreImage;
+
+ xfree((pointer)pPriv);
+
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+
+static void
+ShadowRestoreAreas (
+ PixmapPtr pPixmap,
+ RegionPtr prgn,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
+ int num;
+
+ pScreen->BackingStoreFuncs.RestoreAreas = pPriv->RestoreAreas;
+ (*pScreen->BackingStoreFuncs.RestoreAreas) (
+ pPixmap, prgn, xorg, yorg, pWin);
+ pScreen->BackingStoreFuncs.RestoreAreas = ShadowRestoreAreas;
+
+ if((num = REGION_NUM_RECTS(prgn)))
+ (*pPriv->refresh)(pPriv->pScrn, num, REGION_RECTS(prgn));
+}
+
+
+static void
+ShadowPaintWindow(
+ WindowPtr pWin,
+ RegionPtr prgn,
+ int what
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
+ int num;
+
+ if(what == PW_BACKGROUND) {
+ pScreen->PaintWindowBackground = pPriv->PaintWindowBackground;
+ (*pScreen->PaintWindowBackground) (pWin, prgn, what);
+ pScreen->PaintWindowBackground = ShadowPaintWindow;
+ } else {
+ pScreen->PaintWindowBorder = pPriv->PaintWindowBorder;
+ (*pScreen->PaintWindowBorder) (pWin, prgn, what);
+ pScreen->PaintWindowBorder = ShadowPaintWindow;
+ }
+
+ if((num = REGION_NUM_RECTS(prgn)))
+ (*pPriv->refresh)(pPriv->pScrn, num, REGION_RECTS(prgn));
+}
+
+
+static void
+ShadowCopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgn
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
+ int num;
+
+ pScreen->CopyWindow = pPriv->CopyWindow;
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, prgn);
+ pScreen->CopyWindow = ShadowCopyWindow;
+
+ /* This is sortof cheating. We rely on the fact that
+ cfb translated prgn for us */
+
+ REGION_INTERSECT(pScreen, prgn, &pWin->borderClip, prgn);
+ if((num = REGION_NUM_RECTS(prgn)))
+ (*pPriv->refresh)(pPriv->pScrn, num, REGION_RECTS(prgn));
+
+}
+
+/**********************************************************/
+
+static void ShadowValidateGC(GCPtr, unsigned long, DrawablePtr);
+static void ShadowChangeGC(GCPtr, unsigned long);
+static void ShadowCopyGC(GCPtr, unsigned long, GCPtr);
+static void ShadowDestroyGC(GCPtr);
+static void ShadowChangeClip(GCPtr, int, pointer, int);
+static void ShadowDestroyClip(GCPtr);
+static void ShadowCopyClip(GCPtr, GCPtr);
+
+GCFuncs ShadowGCFuncs = {
+ ShadowValidateGC, ShadowChangeGC, ShadowCopyGC, ShadowDestroyGC,
+ ShadowChangeClip, ShadowDestroyClip, ShadowCopyClip
+};
+
+
+extern GCOps ShadowGCOps;
+
+static Bool
+ShadowCreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
+ ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC);
+ Bool ret;
+
+ pScreen->CreateGC = pPriv->CreateGC;
+ if((ret = (*pScreen->CreateGC) (pGC))) {
+ pGCPriv->ops = NULL;
+ pGCPriv->funcs = pGC->funcs;
+ pGC->funcs = &ShadowGCFuncs;
+ }
+ pScreen->CreateGC = ShadowCreateGC;
+
+ return ret;
+}
+
+
+static void
+ShadowValidateGC(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+){
+ SHADOW_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
+ if(pDraw->type == DRAWABLE_WINDOW)
+ pGCPriv->ops = pGC->ops; /* just so it's not NULL */
+ else
+ pGCPriv->ops = NULL;
+ SHADOW_GC_FUNC_EPILOGUE (pGC);
+}
+
+
+static void
+ShadowDestroyGC(GCPtr pGC)
+{
+ SHADOW_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->DestroyGC)(pGC);
+ SHADOW_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+ShadowChangeGC (
+ GCPtr pGC,
+ unsigned long mask
+){
+ SHADOW_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ SHADOW_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+ShadowCopyGC (
+ GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst
+){
+ SHADOW_GC_FUNC_PROLOGUE (pGCDst);
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ SHADOW_GC_FUNC_EPILOGUE (pGCDst);
+}
+
+static void
+ShadowChangeClip (
+ GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects
+){
+ SHADOW_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ SHADOW_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+ShadowCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ SHADOW_GC_FUNC_PROLOGUE (pgcDst);
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ SHADOW_GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+ShadowDestroyClip(GCPtr pGC)
+{
+ SHADOW_GC_FUNC_PROLOGUE (pGC);
+ (* pGC->funcs->DestroyClip)(pGC);
+ SHADOW_GC_FUNC_EPILOGUE (pGC);
+}
+
+
+
+
+/**********************************************************/
+
+
+static void
+ShadowFillSpans(
+ DrawablePtr pDraw,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && nInit) {
+ DDXPointPtr ppt = pptInit;
+ int *pwidth = pwidthInit;
+ int i = nInit;
+ BoxRec box;
+
+ box.x1 = ppt->x;
+ box.x2 = box.x1 + *pwidth;
+ box.y2 = box.y1 = ppt->y;
+
+ while(--i) {
+ ppt++;
+ pwidthInit++;
+ if(box.x1 > ppt->x) box.x1 = ppt->x;
+ if(box.x2 < (ppt->x + *pwidth))
+ box.x2 = ppt->x + *pwidth;
+ if(box.y1 > ppt->y) box.y1 = ppt->y;
+ else if(box.y2 < ppt->y) box.y2 = ppt->y;
+ }
+
+ box.y2++;
+
+ (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ } else
+ (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+ShadowSetSpans(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ char *pcharsrc,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int nspans,
+ int fSorted
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && nspans) {
+ DDXPointPtr ppt = pptInit;
+ int *pwidth = pwidthInit;
+ int i = nspans;
+ BoxRec box;
+
+ box.x1 = ppt->x;
+ box.x2 = box.x1 + *pwidth;
+ box.y2 = box.y1 = ppt->y;
+
+ while(--i) {
+ ppt++;
+ pwidth++;
+ if(box.x1 > ppt->x) box.x1 = ppt->x;
+ if(box.x2 < (ppt->x + *pwidth))
+ box.x2 = ppt->x + *pwidth;
+ if(box.y1 > ppt->y) box.y1 = ppt->y;
+ else if(box.y2 < ppt->y) box.y2 = ppt->y;
+ }
+
+ box.y2++;
+
+ (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, pptInit,
+ pwidthInit, nspans, fSorted);
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ } else
+ (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, pptInit,
+ pwidthInit, nspans, fSorted);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+ShadowPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw)) {
+ BoxRec box;
+
+ box.x1 = x + pDraw->x;
+ box.x2 = box.x1 + w;
+ box.y1 = y + pDraw->y;
+ box.y2 = box.y1 + h;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ }
+}
+
+static RegionPtr
+ShadowCopyArea(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+){
+ RegionPtr ret;
+ SHADOW_GC_OP_PROLOGUE(pGC);
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ if(IS_VISIBLE(pDst)) {
+ BoxRec box;
+
+ box.x1 = dstx + pDst->x;
+ box.x2 = box.x1 + width;
+ box.y1 = dsty + pDst->y;
+ box.y2 = box.y1 + height;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ }
+
+ return ret;
+}
+
+static RegionPtr
+ShadowCopyPlane(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+){
+ RegionPtr ret;
+ SHADOW_GC_OP_PROLOGUE(pGC);
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ if(IS_VISIBLE(pDst)) {
+ BoxRec box;
+
+ box.x1 = dstx + pDst->x;
+ box.x2 = box.x1 + width;
+ box.y1 = dsty + pDst->y;
+ box.y2 = box.y1 + height;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ }
+
+ return ret;
+}
+
+static void
+ShadowPolyPoint(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && npt) {
+ BoxRec box;
+
+ box.x2 = box.x1 = pptInit->x;
+ box.y2 = box.y1 = pptInit->y;
+
+ /* this could be slow if the points were spread out */
+
+ while(--npt) {
+ pptInit++;
+ if(box.x1 > pptInit->x) box.x1 = pptInit->x;
+ else if(box.x2 < pptInit->x) box.x2 = pptInit->x;
+ if(box.y1 > pptInit->y) box.y1 = pptInit->y;
+ else if(box.y2 < pptInit->y) box.y2 = pptInit->y;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ }
+}
+
+static void
+ShadowPolylines(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+
+ if(IS_VISIBLE(pDraw) && npt) {
+ BoxRec box;
+ int extra = pGC->lineWidth >> 1;
+
+ box.x2 = box.x1 = pptInit->x;
+ box.y2 = box.y1 = pptInit->y;
+
+ if(npt > 1) {
+ if(pGC->joinStyle == JoinMiter)
+ extra = 6 * pGC->lineWidth;
+ else if(pGC->capStyle == CapProjecting)
+ extra = pGC->lineWidth;
+ }
+
+ if(mode == CoordModePrevious) {
+ int x = box.x1;
+ int y = box.y1;
+ while(--npt) {
+ pptInit++;
+ x += pptInit->x;
+ y += pptInit->y;
+ if(box.x1 > x) box.x1 = x;
+ else if(box.x2 < x) box.x2 = x;
+ if(box.y1 > y) box.y1 = y;
+ else if(box.y2 < y) box.y2 = y;
+ }
+ } else {
+ while(--npt) {
+ pptInit++;
+ if(box.x1 > pptInit->x) box.x1 = pptInit->x;
+ else if(box.x2 < pptInit->x) box.x2 = pptInit->x;
+ if(box.y1 > pptInit->y) box.y1 = pptInit->y;
+ else if(box.y2 < pptInit->y) box.y2 = pptInit->y;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ if(extra) {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ }
+}
+
+static void
+ShadowPolySegment(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && nseg) {
+ BoxRec box;
+ int extra = pGC->lineWidth;
+
+ if(pGC->capStyle != CapProjecting)
+ extra >>= 1;
+
+ if(pSeg->x2 > pSeg->x1) {
+ box.x1 = pSeg->x1;
+ box.x2 = pSeg->x2;
+ } else {
+ box.x2 = pSeg->x1;
+ box.x1 = pSeg->x2;
+ }
+
+ if(pSeg->y2 > pSeg->y1) {
+ box.y1 = pSeg->y1;
+ box.y2 = pSeg->y2;
+ } else {
+ box.y2 = pSeg->y1;
+ box.y1 = pSeg->y2;
+ }
+
+ while(--nseg) {
+ pSeg++;
+ if(pSeg->x2 > pSeg->x1) {
+ if(pSeg->x1 < box.x1) box.x1 = pSeg->x1;
+ if(pSeg->x2 > box.x2) box.x2 = pSeg->x2;
+ } else {
+ if(pSeg->x2 < box.x1) box.x1 = pSeg->x2;
+ if(pSeg->x1 > box.x2) box.x2 = pSeg->x1;
+ }
+ if(pSeg->y2 > pSeg->y1) {
+ if(pSeg->y1 < box.y1) box.y1 = pSeg->y1;
+ if(pSeg->y2 > box.y2) box.y2 = pSeg->y2;
+ } else {
+ if(pSeg->y2 < box.y1) box.y1 = pSeg->y2;
+ if(pSeg->y1 > box.y2) box.y2 = pSeg->y1;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ if(extra) {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ }
+}
+
+static void
+ShadowPolyRectangle(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRects,
+ xRectangle *pRects
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolyRectangle)(pDraw, pGC, nRects, pRects);
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && nRects) {
+ if(nRects >= 32) {
+ int extra = pGC->lineWidth >> 1;
+ BoxRec box;
+
+ box.x1 = pRects->x;
+ box.x2 = box.x1 + pRects->width;
+ box.y1 = pRects->y;
+ box.y2 = box.y1 + pRects->height;
+
+ while(--nRects) {
+ pRects++;
+ if(box.x1 > pRects->x) box.x1 = pRects->x;
+ if(box.x2 < (pRects->x + pRects->width))
+ box.x2 = pRects->x + pRects->width;
+ if(box.y1 > pRects->y) box.y1 = pRects->y;
+ if(box.y2 < (pRects->y + pRects->height))
+ box.y2 = pRects->y + pRects->height;
+ }
+
+ if(extra) {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ } else {
+ BoxPtr pbox, pBoxInit;
+ int offset1, offset2, offset3;
+ int num = 0;
+
+ offset2 = pGC->lineWidth;
+ if(!offset2) offset2 = 1;
+ offset1 = offset2 >> 1;
+ offset3 = offset2 - offset1;
+
+ pBoxInit = (BoxPtr)ALLOCATE_LOCAL(nRects * 4 * sizeof(BoxRec));
+ pbox = pBoxInit;
+
+ while(nRects--) {
+ pbox->x1 = pRects->x - offset1;
+ pbox->y1 = pRects->y - offset1;
+ pbox->x2 = pbox->x1 + pRects->width + offset2;
+ pbox->y2 = pbox->y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC);
+ if(BOX_NOT_EMPTY((*pbox))) {
+ num++;
+ pbox++;
+ }
+
+ pbox->x1 = pRects->x - offset1;
+ pbox->y1 = pRects->y + offset3;
+ pbox->x2 = pbox->x1 + offset2;
+ pbox->y2 = pbox->y1 + pRects->height - offset2;
+ TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC);
+ if(BOX_NOT_EMPTY((*pbox))) {
+ num++;
+ pbox++;
+ }
+
+ pbox->x1 = pRects->x + pRects->width - offset1;
+ pbox->y1 = pRects->y + offset3;
+ pbox->x2 = pbox->x1 + offset2;
+ pbox->y2 = pbox->y1 + pRects->height - offset2;
+ TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC);
+ if(BOX_NOT_EMPTY((*pbox))) {
+ num++;
+ pbox++;
+ }
+
+ pbox->x1 = pRects->x - offset1;
+ pbox->y1 = pRects->y + pRects->height - offset1;
+ pbox->x2 = pbox->x1 + pRects->width + offset2;
+ pbox->y2 = pbox->y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC);
+ if(BOX_NOT_EMPTY((*pbox))) {
+ num++;
+ pbox++;
+ }
+
+ pRects++;
+ }
+
+ if(num)
+ (*pPriv->refresh)(pPriv->pScrn, num, pBoxInit);
+
+ DEALLOCATE_LOCAL(pBoxInit);
+ }
+ }
+ }
+
+static void
+ShadowPolyArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && narcs) {
+ int extra = pGC->lineWidth >> 1;
+ BoxRec box;
+
+ box.x1 = parcs->x;
+ box.x2 = box.x1 + parcs->width;
+ box.y1 = parcs->y;
+ box.y2 = box.y1 + parcs->height;
+
+ /* should I break these up instead ? */
+
+ while(--narcs) {
+ parcs++;
+ if(box.x1 > parcs->x) box.x1 = parcs->x;
+ if(box.x2 < (parcs->x + parcs->width))
+ box.x2 = parcs->x + parcs->width;
+ if(box.y1 > parcs->y) box.y1 = parcs->y;
+ if(box.y2 < (parcs->y + parcs->height))
+ box.y2 = parcs->y + parcs->height;
+ }
+
+ if(extra) {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ }
+}
+
+static void
+ShadowFillPolygon(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr pptInit
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && (count > 2)) {
+ DDXPointPtr ppt = pptInit;
+ int i = count;
+ BoxRec box;
+
+ box.x2 = box.x1 = ppt->x;
+ box.y2 = box.y1 = ppt->y;
+
+ if(mode != CoordModeOrigin) {
+ int x = box.x1;
+ int y = box.y1;
+ while(--i) {
+ ppt++;
+ x += ppt->x;
+ y += ppt->y;
+ if(box.x1 > x) box.x1 = x;
+ else if(box.x2 < x) box.x2 = x;
+ if(box.y1 > y) box.y1 = y;
+ else if(box.y2 < y) box.y2 = y;
+ }
+ } else {
+ while(--i) {
+ ppt++;
+ if(box.x1 > ppt->x) box.x1 = ppt->x;
+ else if(box.x2 < ppt->x) box.x2 = ppt->x;
+ if(box.y1 > ppt->y) box.y1 = ppt->y;
+ else if(box.y2 < ppt->y) box.y2 = ppt->y;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, pptInit);
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ } else
+ (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, pptInit);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+}
+
+
+static void
+ShadowPolyFillRect(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && nRectsInit) {
+ BoxRec box;
+ xRectangle *pRects = pRectsInit;
+ int nRects = nRectsInit;
+
+ box.x1 = pRects->x;
+ box.x2 = box.x1 + pRects->width;
+ box.y1 = pRects->y;
+ box.y2 = box.y1 + pRects->height;
+
+ while(--nRects) {
+ pRects++;
+ if(box.x1 > pRects->x) box.x1 = pRects->x;
+ if(box.x2 < (pRects->x + pRects->width))
+ box.x2 = pRects->x + pRects->width;
+ if(box.y1 > pRects->y) box.y1 = pRects->y;
+ if(box.y2 < (pRects->y + pRects->height))
+ box.y2 = pRects->y + pRects->height;
+ }
+
+ /* cfb messes with the pRectsInit so we have to do our
+ calculations first */
+
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nRectsInit, pRectsInit);
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ } else
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nRectsInit, pRectsInit);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+}
+
+
+static void
+ShadowPolyFillArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && narcs) {
+ BoxRec box;
+
+ box.x1 = parcs->x;
+ box.x2 = box.x1 + parcs->width;
+ box.y1 = parcs->y;
+ box.y2 = box.y1 + parcs->height;
+
+ /* should I break these up instead ? */
+
+ while(--narcs) {
+ parcs++;
+ if(box.x1 > parcs->x) box.x1 = parcs->x;
+ if(box.x2 < (parcs->x + parcs->width))
+ box.x2 = parcs->x + parcs->width;
+ if(box.y1 > parcs->y) box.y1 = parcs->y;
+ if(box.y2 < (parcs->y + parcs->height))
+ box.y2 = parcs->y + parcs->height;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ }
+
+}
+
+static int
+ShadowPolyText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ int width;
+
+ SHADOW_GC_OP_PROLOGUE(pGC);
+ width = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ width -= x;
+
+ if(IS_VISIBLE(pDraw) && (width > 0)) {
+ BoxRec box;
+
+ /* ugh */
+ box.x1 = pDraw->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing);
+ box.x2 = pDraw->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing);
+
+ if(count > 1) {
+ if(width > 0) box.x2 += width;
+ else box.x1 += width;
+ }
+
+ box.y1 = pDraw->y + y - FONTMAXBOUNDS(pGC->font, ascent);
+ box.y2 = pDraw->y + y + FONTMAXBOUNDS(pGC->font, descent);
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ }
+
+ return (width + x);
+}
+
+static int
+ShadowPolyText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ int width;
+
+ SHADOW_GC_OP_PROLOGUE(pGC);
+ width = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ width -= x;
+
+ if(IS_VISIBLE(pDraw) && (width > 0)) {
+ BoxRec box;
+
+ /* ugh */
+ box.x1 = pDraw->x + x + FONTMINBOUNDS(pGC->font, leftSideBearing);
+ box.x2 = pDraw->x + x + FONTMAXBOUNDS(pGC->font, rightSideBearing);
+
+ if(count > 1) {
+ if(width > 0) box.x2 += width;
+ else box.x1 += width;
+ }
+
+ box.y1 = pDraw->y + y - FONTMAXBOUNDS(pGC->font, ascent);
+ box.y2 = pDraw->y + y + FONTMAXBOUNDS(pGC->font, descent);
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ }
+
+ return (width + x);
+}
+
+static void
+ShadowImageText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && count) {
+ int top, bot, Min, Max;
+ BoxRec box;
+
+ top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
+ bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
+
+ Min = count * FONTMINBOUNDS(pGC->font, characterWidth);
+ if(Min > 0) Min = 0;
+ Max = count * FONTMAXBOUNDS(pGC->font, characterWidth);
+ if(Max < 0) Max = 0;
+
+ /* ugh */
+ box.x1 = pDraw->x + x + Min +
+ FONTMINBOUNDS(pGC->font, leftSideBearing);
+ box.x2 = pDraw->x + x + Max +
+ FONTMAXBOUNDS(pGC->font, rightSideBearing);
+
+ box.y1 = pDraw->y + y - top;
+ box.y2 = pDraw->y + y + bot;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ }
+}
+static void
+ShadowImageText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && count) {
+ int top, bot, Min, Max;
+ BoxRec box;
+
+ top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
+ bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
+
+ Min = count * FONTMINBOUNDS(pGC->font, characterWidth);
+ if(Min > 0) Min = 0;
+ Max = count * FONTMAXBOUNDS(pGC->font, characterWidth);
+ if(Max < 0) Max = 0;
+
+ /* ugh */
+ box.x1 = pDraw->x + x + Min +
+ FONTMINBOUNDS(pGC->font, leftSideBearing);
+ box.x2 = pDraw->x + x + Max +
+ FONTMAXBOUNDS(pGC->font, rightSideBearing);
+
+ box.y1 = pDraw->y + y - top;
+ box.y2 = pDraw->y + y + bot;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ }
+}
+
+
+static void
+ShadowImageGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, nglyph,
+ ppci, pglyphBase);
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && nglyph) {
+ int top, bot, width = 0;
+ BoxRec box;
+
+ top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
+ bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
+
+ box.x1 = ppci[0]->metrics.leftSideBearing;
+ if(box.x1 > 0) box.x1 = 0;
+ box.x2 = ppci[nglyph - 1]->metrics.rightSideBearing -
+ ppci[nglyph - 1]->metrics.characterWidth;
+ if(box.x2 < 0) box.x2 = 0;
+
+ box.x2 += pDraw->x + x;
+ box.x1 += pDraw->x + x;
+
+ while(nglyph--) {
+ width += (*ppci)->metrics.characterWidth;
+ ppci++;
+ }
+
+ if(width > 0)
+ box.x2 += width;
+ else
+ box.x1 += width;
+
+ box.y1 = pDraw->y + y - top;
+ box.y2 = pDraw->y + y + bot;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ }
+}
+
+static void
+ShadowPolyGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, x, y, nglyph,
+ ppci, pglyphBase);
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && nglyph) {
+ BoxRec box;
+
+ /* ugh */
+ box.x1 = pDraw->x + x + ppci[0]->metrics.leftSideBearing;
+ box.x2 = pDraw->x + x + ppci[nglyph - 1]->metrics.rightSideBearing;
+
+ if(nglyph > 1) {
+ int width = 0;
+
+ while(--nglyph) {
+ width += (*ppci)->metrics.characterWidth;
+ ppci++;
+ }
+
+ if(width > 0) box.x2 += width;
+ else box.x1 += width;
+ }
+
+ box.y1 = pDraw->y + y - FONTMAXBOUNDS(pGC->font, ascent);
+ box.y2 = pDraw->y + y + FONTMAXBOUNDS(pGC->font, descent);
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ }
+}
+
+static void
+ShadowPushPixels(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy, int xOrg, int yOrg
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw)) {
+ BoxRec box;
+
+ box.x1 = xOrg + pDraw->x;
+ box.x2 = box.x1 + dx;
+ box.y1 = yOrg + pDraw->y;
+ box.y2 = box.y1 + dy;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box))
+ (*pPriv->refresh)(pPriv->pScrn, 1, &box);
+ }
+}
+
+
+GCOps ShadowGCOps = {
+ ShadowFillSpans, ShadowSetSpans,
+ ShadowPutImage, ShadowCopyArea,
+ ShadowCopyPlane, ShadowPolyPoint,
+ ShadowPolylines, ShadowPolySegment,
+ ShadowPolyRectangle, ShadowPolyArc,
+ ShadowFillPolygon, ShadowPolyFillRect,
+ ShadowPolyFillArc, ShadowPolyText8,
+ ShadowPolyText16, ShadowImageText8,
+ ShadowImageText16, ShadowImageGlyphBlt,
+ ShadowPolyGlyphBlt, ShadowPushPixels,
+#ifdef NEED_LINEHELPER
+ NULL,
+#endif
+ {NULL} /* devPrivate */
+};
+
diff --git a/xc/programs/Xserver/hw/xfree86/shadowfb/shadowfb.h b/xc/programs/Xserver/hw/xfree86/shadowfb/shadowfb.h
new file mode 100644
index 000000000..831701a47
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/shadowfb/shadowfb.h
@@ -0,0 +1,18 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/shadowfb/shadowfb.h,v 1.1 1999/01/31 12:22:07 dawes Exp $ */
+
+#ifndef _SHADOWFB_H
+#define _SHADOWFB_H
+
+typedef void (*RefreshAreaFuncPtr)(ScrnInfoPtr, int, BoxPtr);
+
+Bool
+ShadowFBInit (
+ ScreenPtr pScreen,
+ RefreshAreaFuncPtr refreshArea
+);
+
+#endif /* _SHADOWFB_H */
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/Imakefile b/xc/programs/Xserver/hw/xfree86/vgafb/Imakefile
new file mode 100644
index 000000000..0e369c5f7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/Imakefile
@@ -0,0 +1,184 @@
+XCOMM $XConsortium: Imakefile /main/10 1996/10/25 10:34:08 kaleb $
+
+
+
+
+
+
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/Imakefile,v 1.2 1998/07/25 16:58:11 dawes Exp $
+#include <Server.tmpl>
+
+#ifdef i386Architecture
+FSRCS = fBitBlt.s fFillCopy.s fFillOr.s fFillAnd.s \
+ fFillXor.s fFillSet.s vgabres.s vgalineH.s vgalineV.s
+BSRCS = BitBlt.s BitBlt2.s Box.s Line.s VHLine.s vgaBank.s
+
+FOBJS = fBitBlt.o fFillCopy.o fFillOr.o fFillAnd.o \
+ fFillXor.o fFillSet.o vgabres.o vgalineH.o vgalineV.o
+BOBJS = BitBlt.o BitBlt2.o Box.o Line.o VHLine.o vgaBank.o
+#else
+FSRCS = vgaBltFillc.c vgaLinec.c
+BSRCS = vgaBankc.c
+
+FOBJS = vgaBltFillc.o vgaLinec.o
+BOBJS = vgaBankc.o
+#endif
+
+SRCS = vgagc.c vgawindow.c vgascrinit.c \
+ vgapntwin.c vgapwinS.c vgabitblt.c \
+ vgafillsp.c vgasetsp.c vgaimage.c \
+ vgagetsp.c vgafillrct.c vgaBitBlt1.c \
+ vgasolidC.c vgasolidCS.c vgasolidX.c \
+ vgasolidO.c vgasolidA.c vgasolidG.c \
+ vgatile32C.c vgatile32G.c \
+ vgatileoddC.c vgatileoddG.c \
+ vgazerarcC.c vgazerarcX.c vgazerarcG.c \
+ vgafillarcC.c vgafillarcG.c \
+ vgategblt.c vgabstore.c vga8cppl.c \
+ vgabltC.c vgabltCS.c vgabltX.c vgabltO.c vgabltG.c \
+ vgateblt8.c vgateblt8S.c vgaglblt8.c vgaglrop8.c \
+ vgapush8.c vgarctstp8.c vgarctstp8S.c vgapolypnt.c \
+ vgaline.c vgalineS.c vgabresd.c \
+ vgalined.c vgasegd.c vgaseg.c vgasegS.c \
+ vgaply1rctC.c vgaply1rctG.c \
+ SpeedUpBlt.c $(BSRCS) \
+ vgaBanks.c $(FSRCS)
+
+OBJS = vgagc.o vgawindow.o vgascrinit.o \
+ vgagetsp.o vgafillrct.o vgaimage.o \
+ vgasolidC.o vgasolidCS.o vgasolidX.o \
+ vgasolidO.o vgasolidA.o vgasolidG.o \
+ vgatile32C.o vgatile32G.o \
+ vgatileoddC.o vgatileoddG.o \
+ vgafillsp.o vgasetsp.o \
+ vgapntwin.o vgapwinS.o vgaBitBlt1.o \
+ vgazerarcC.o vgazerarcX.o vgazerarcG.o \
+ vgafillarcC.o vgafillarcG.o \
+ vgategblt.o vgabstore.o vga8cppl.o \
+ vgateblt8.o vgateblt8S.o vgaglblt8.o vgaglrop8.o \
+ vgarctstp8.o vgarctstp8S.o vgapolypnt.o \
+ vgaline.o vgalineS.o vgabresd.o \
+ vgalined.o vgasegd.o vgaseg.o vgasegS.o \
+ vgabitblt.o vgabltC.o vgabltCS.o vgabltX.o \
+ vgabltO.o vgabltG.o \
+ vgapush8.o vgaply1rctC.o vgaply1rctG.o $(STIPPLEOBJ) \
+ SpeedUpBlt.o $(BOBJS) \
+ vgaBanks.o $(FOBJS)
+
+ INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(XF86HWSRC) \
+ -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(FONTINCSRC) \
+ -I../../xaa
+ LINTLIBS = ../../../dix/llib-ldix.ln ../../../os/llib-los.ln \
+ ../../mfb/llib-lmfb.ln ../../mi/llib-lmi.ln
+
+#if DirtyStartup
+STARTUPDEFINES = -DDIRTY_STARTUP
+#endif
+
+#if XF86Vga2Banked
+BANKEDDEFINES = -DBANKEDMONOVGA
+#endif
+
+#if MakeDllModules
+
+XCOMM DEFINES is not a good place to put this, but it works
+
+ EXTRA_DEFINES = $(PICFLAGS)
+
+#endif
+
+ DEFINES = $(SPEEDUPDEFINES) $(STARTUPDEFINES) $(BANKEDDEFINES) -DPSZ=8
+
+#ifdef i386Architecture
+SUDEFINE = -DSPEEDUP
+#endif
+
+VGADRIVERS = XF86Vga256Drivers
+
+#if MakeDllModules
+DynamicModuleTarget(vgafb.so,$(OBJS))
+#else
+NormalDepLibraryTarget(vgafb,$(OBJS),$(OBJS))
+NormalLibraryObjectRule()
+#endif
+NormalAsmObjectRule()
+
+NormalLintTarget($(SRCS))
+
+ObjectFromSpecialSource(vgaBanks,enhanced/gBanks,NullParameter)
+#ifdef i386Architecture
+ObjectFromSpecialAsmSource(BitBlt,enhanced/suBitBlt,NullParameter)
+ObjectFromSpecialAsmSource(BitBlt2,enhanced/suBBlt2,NullParameter)
+ObjectFromSpecialAsmSource(Box,enhanced/suBox,NullParameter)
+ObjectFromSpecialAsmSource(Line,enhanced/suLine,NullParameter)
+ObjectFromSpecialAsmSource(VHLine,enhanced/suVHLine,NullParameter)
+ObjectFromSpecialAsmSource(vgabres,enhanced/fLineBres,NullParameter)
+ObjectFromSpecialAsmSource(vgalineH,enhanced/fLineH,NullParameter)
+ObjectFromSpecialAsmSource(vgalineV,enhanced/fLineV,NullParameter)
+LinkSourceFile(fBitBlt.s,enhanced)
+LinkSourceFile(fFill.s,enhanced)
+LinkSourceFile(fFillSet.s,enhanced)
+#else
+LinkSourceFile(vgaBltFillc.c,enhanced)
+LinkSourceFile(vgaLinec.c,enhanced)
+#endif
+LinkFile(vgaBitBlt1.c,enhanced/vgaBitBlt.c)
+LinkSourceFile(SpeedUpBlt.c,enhanced)
+LinkSourceFile(vgaFasm.h,enhanced)
+
+ObjectFromSpecialSource(vgaseg,vgaline,-DPOLYSEGMENT)
+ObjectFromSpecialSource(vgasegd,vgalined,-DPOLYSEGMENT)
+ObjectFromSpecialSource(vgaglrop8,vgaglblt8,-DGLYPHROP)
+SpecialObjectRule(vgaglblt8.o,vgaglblt8.c,$(STIPPLEDEF))
+
+ObjectFromSpecialSource(vgalineS,vgaline,$(SUDEFINE))
+ObjectFromSpecialSource(vgasegS,vgaline,$(SUDEFINE) -DPOLYSEGMENT)
+ObjectFromSpecialSource(vgateblt8S,vgateblt8,$(SUDEFINE))
+ObjectFromSpecialSource(vgarctstp8S,vgarctstp8,$(SUDEFINE))
+
+ObjectFromSpecialSource(vgafillarcC,vgafillarc,-DRROP=GXcopy)
+ObjectFromSpecialSource(vgafillarcG,vgafillarc,-DRROP=GXset)
+
+ObjectFromSpecialSource(vgazerarcC,vgazerarc,-DRROP=GXcopy)
+ObjectFromSpecialSource(vgazerarcX,vgazerarc,-DRROP=GXxor)
+ObjectFromSpecialSource(vgazerarcG,vgazerarc,-DRROP=GXset)
+
+ObjectFromSpecialSource(vgabltCS,vgablt,-DMROP=Mcopy $(SUDEFINE))
+ObjectFromSpecialSource(vgabltX,vgablt,-DMROP=Mxor)
+ObjectFromSpecialSource(vgabltO,vgablt,-DMROP=Mor)
+ObjectFromSpecialSource(vgabltG,vgablt,-DMROP=0)
+
+ObjectFromSpecialSource(vgasolidC,vgasolid,-DRROP=GXcopy)
+ObjectFromSpecialSource(vgasolidCS,vgasolid,-DRROP=GXcopy $(SUDEFINE))
+ObjectFromSpecialSource(vgasolidX,vgasolid,-DRROP=GXxor)
+ObjectFromSpecialSource(vgasolidO,vgasolid,-DRROP=GXor)
+ObjectFromSpecialSource(vgasolidA,vgasolid,-DRROP=GXand)
+ObjectFromSpecialSource(vgasolidG,vgasolid,-DRROP=GXset)
+
+ObjectFromSpecialSource(vgatile32C,vgatile32,-DMROP=Mcopy)
+ObjectFromSpecialSource(vgatile32G,vgatile32,-DMROP=0)
+
+ObjectFromSpecialSource(vgatileoddC,vgatileodd,-DMROP=Mcopy)
+ObjectFromSpecialSource(vgatileoddG,vgatileodd,-DMROP=0)
+
+ObjectFromSpecialSource(vgaply1rctC,vgaply1rct,-DRROP=GXcopy)
+ObjectFromSpecialSource(vgaply1rctG,vgaply1rct,-DRROP=GXset)
+
+#ifdef i386Architecture
+ObjectFromSpecialAsmSource(fFillAnd,fFill,-DRROP=GXAnd)
+ObjectFromSpecialAsmSource(fFillCopy,fFill,-DRROP=GXCopy)
+ObjectFromSpecialAsmSource(fFillOr,fFill,-DRROP=GXOr)
+ObjectFromSpecialAsmSource(fFillXor,fFill,-DRROP=GXXor)
+#endif
+
+InstallLinkKitNonExecFile(vga.h,$(LINKKITDIR)/drivers)
+InstallLinkKitNonExecFile(vga256.h,$(LINKKITDIR)/drivers)
+InstallLinkKitNonExecFile(vgaBank.h,$(LINKKITDIR)/drivers)
+InstallLinkKitNonExecFile(vgaFasm.h,$(LINKKITDIR)/drivers)
+InstallLinkKitNonExecFile(vgaHW.c,$(LINKKITDIR)/VGADriverDoc)
+InstallLinkKitNonExecFile(vgaPCI.h,$(LINKKITDIR)/drivers)
+
+#ifndef OS2Architecture
+DependTarget()
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/README b/xc/programs/Xserver/hw/xfree86/vgafb/README
new file mode 100644
index 000000000..0d3c1ff3b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/README
@@ -0,0 +1,2 @@
+This directory is included for reference only. It may be removed at some
+point.
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/SpeedUpBlt.c b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/SpeedUpBlt.c
new file mode 100644
index 000000000..79b64246a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/SpeedUpBlt.c
@@ -0,0 +1,92 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/enhanced/SpeedUpBlt.c,v 1.2 1998/07/25 16:58:27 dawes Exp $ */
+/*******************************************************************************
+ Copyr 1992 by Glenn G. Lai
+
+ All Rs 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 copyr notice appear in all copies and that
+both that copyr notice and this permission notice appear in
+supporting documentation, and that the name of Glenn G. Lai not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+Glenn G. Lai DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+Glenn G. Lai
+P.O. Box 4314
+Austin, Tx 78765
+glenn@cs.utexas.edu)
+8/17/92
+*******************************************************************************/
+/* $XConsortium: SpeedUpBlt.c /main/4 1996/02/21 18:08:35 kaleb $ */
+
+#include "vgafb.h"
+
+static char copyright[] = "Copyright 8/17/1992 by Glenn G. Lai";
+
+void
+SpeedUpBitBlt(sBase, dBase, widthS, widthD, x, y, x1, y1, w, h, xdir, ydir)
+ unsigned char *sBase, *dBase;
+ int widthS, widthD;
+ int x, y, x1, y1, w, h;
+ int xdir, ydir;
+{
+ if (sBase >= (unsigned char*)VGABASE)
+ if (dBase >= (unsigned char*)VGABASE) {
+ unsigned char *src, *dst;
+
+ if (y == y1 && xdir == -1) {
+ src = sBase + (y+h-1) * widthS + x + w - 1 - VGABASE;
+ dst = dBase + (y1+h-1) * widthD + x1 + w - 1-VGABASE;
+ WinWin(src, dst, h, w, -1, -1, widthS, 1);
+ } else if (ydir == -1) {
+ src = sBase - (y + h - 1) * widthS + x - VGABASE;
+ dst = dBase - (y1 + h - 1) * widthD + x1 - VGABASE;
+ WinWin(src, dst, h, w, xdir, -1, widthS, 0);
+ } else { /* ydir == 1 */
+ src = sBase + y * widthS + x - VGABASE;
+ dst = dBase + y1 * widthD + x1 - VGABASE;
+ WinWin(src, dst, h, w, xdir, 1, widthS, 0);
+ }
+ } else {
+ if (widthS <0)
+ widthS = -widthS;
+ if (widthD <0)
+ widthD = -widthD;
+ WinPix(sBase+(y*widthS)+x,dBase+(y1*widthD)+x1,
+ h, w, widthS, widthD);
+ }
+ else if (dBase >= (unsigned char*)VGABASE) {
+ if (widthS <0)
+ widthS = -widthS;
+ if (widthD <0)
+ widthD = -widthD;
+ PixWin(sBase+(y*widthS)+x,dBase+(y1*widthD)+x1, h, w, widthS, widthD);
+ } else {
+ if (ydir == 1)
+ if ((y == y1) && (xdir == -1))
+ PixPix(sBase+((y+h-1)*widthS)+x+w-1,
+ dBase+((y1+h-1)*widthD)+x1+w-1,
+ h, w, -widthS + w, -widthD + w, -1);
+ else
+ PixPix(sBase+(y*widthS)+x,dBase+(y1*widthD)+x1,
+ h, w, widthS - w, widthD - w, 1);
+ else
+ if (w > 4)
+ PixPix(sBase-((y+h-1)*widthS)+x+w-1,
+ dBase-((y1+h-1)*widthD)+x1+w-1,
+ h, w, widthS + w, widthD + w, -1);
+ else
+ PixPix(sBase-((y+h-1)*widthS)+x,
+ dBase-((y1+h-1)*widthD)+x1,
+ h, w, widthS - w, widthD - w, -1);
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fBitBlt.s b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fBitBlt.s
new file mode 100644
index 000000000..2d08e8b46
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fBitBlt.s
@@ -0,0 +1,694 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fBitBlt.s,v 1.2 1998/07/25 16:58:28 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Roell not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Roell makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Thomas Roell, roell@informatik.tu-muenchen.de
+ */
+/* $XConsortium: fBitBlt.s /main/4 1996/02/21 18:08:39 kaleb $ */
+
+
+/*
+ * Just copy the fastest way you can !!!!
+ * Not questions of style here, please.
+ * Since our dragon is SSOOOOOOOOOOOOOO slow don't compute timings the normal
+ * way.
+ * ----->>>>> a 'movsl' takes about 144(!!!) cycles on my 33MHz 386 <<<<<-----
+ *
+ * But cause of the BRAINDAMAGED 386 you cann't use movsl -- it does only
+ * post-decrement/increment !!!
+ *
+ * (7/28/90 TR)
+ */
+
+#include "assyntax.h"
+
+ FILE("fBitBlt.s")
+ AS_BEGIN
+
+#define tmp EBX
+#define xdir REGOFF(8,EBP)
+#define psrc ESI
+#define pdst EDI
+#define hcount EDX
+#define count REGOFF(24,EBP)
+#define srcPitch REGOFF(28,EBP)
+#define dstPitch REGOFF(32,EBP)
+#define srcPitchReg ECX
+#define dstPitchReg EAX
+#define xSrc REGOFF(-4,EBP)
+#define xDst REGOFF(-8,EBP)
+#define countS REGOFF(-12,EBP)
+#define Shift ECX
+#define low EAX
+#define lowb AH
+#define lowbl AL
+#define loww AX
+#define high EDX
+#define highb DH
+#define highbl DL
+#define highw DX
+#define hcountS REGOFF(20,EBP)
+
+SEG_TEXT
+ ALIGNTEXT4
+GLOBL GLNAME(fastBitBltCopy)
+GLNAME(fastBitBltCopy):
+ PUSH_L (EBP)
+ MOV_L (ESP,EBP)
+ SUB_L (CONST(12),ESP)
+ PUSH_L (EDI)
+ PUSH_L (ESI)
+ PUSH_L (EBX)
+ MOV_L (REGOFF(12,EBP),psrc)
+ MOV_L (REGOFF(16,EBP),pdst)
+ MOV_L (REGOFF(20,EBP),hcount)
+ MOV_L (count,tmp)
+
+ CMP_L (CONST(1),xdir)
+ JE (.fastmove)
+ std
+.fastmove:
+
+ CMP_L (CONST(5),tmp)
+ JG (.BlockSetup)
+ MOV_L (srcPitch,srcPitchReg)
+ MOV_L (dstPitch,dstPitchReg)
+ CMP_L (CONST(1),xdir)
+ JNE (.RightFast)
+
+.LeftFast:
+ ADD_L (tmp,srcPitchReg)
+ ADD_L (tmp,dstPitchReg)
+ CMP_L (CONST(4),tmp)
+ JG (.LeftFiveLoop)
+ JE (.LeftFourLoop)
+ CMP_L (CONST(2),tmp)
+ JG (.LeftThreeLoop)
+ JE (.LeftTwoLoop)
+ JMP (.LeftOneLoop)
+
+ ALIGNTEXT4
+.LeftOneBody:
+ MOV_B (REGIND(psrc),BL)
+ MOV_B (BL,REGIND(pdst))
+ ADD_L (srcPitchReg,psrc)
+ ADD_L (dstPitchReg,pdst)
+.LeftOneLoop:
+ DEC_L (hcount)
+ JNS (.LeftOneBody)
+ JMP (.finish)
+
+ ALIGNTEXT4
+.LeftTwoBody:
+ MOV_W (REGIND(psrc),BX)
+ MOV_W (BX,REGIND(pdst))
+ ADD_L (srcPitchReg,psrc)
+ ADD_L (dstPitchReg,pdst)
+.LeftTwoLoop:
+ DEC_L (hcount)
+ JNS (.LeftTwoBody)
+ JMP (.finish)
+
+ ALIGNTEXT4
+.LeftThreeBody:
+ MOV_W (REGIND(psrc),BX)
+ MOV_W (BX,REGIND(pdst))
+ MOV_B (REGOFF(2,psrc),BL)
+ MOV_B (BL,REGOFF(2,pdst))
+ ADD_L (srcPitchReg,psrc)
+ ADD_L (dstPitchReg,pdst)
+.LeftThreeLoop:
+ DEC_L (hcount)
+ JNS (.LeftThreeBody)
+ JMP (.finish)
+
+ ALIGNTEXT4
+.LeftFourBody:
+ MOV_L (REGIND(psrc),EBX)
+ MOV_L (EBX,REGIND(pdst))
+ ADD_L (srcPitchReg,psrc)
+ ADD_L (dstPitchReg,pdst)
+.LeftFourLoop:
+ DEC_L (hcount)
+ JNS (.LeftFourBody)
+ JMP (.finish)
+
+ ALIGNTEXT4
+.LeftFiveBody:
+ MOV_L (REGIND(psrc),EBX)
+ MOV_L (EBX,REGIND(pdst))
+ MOV_B (REGOFF(4,psrc),BL)
+ MOV_B (BL,REGOFF(4,pdst))
+ ADD_L (srcPitchReg,psrc)
+ ADD_L (dstPitchReg,pdst)
+.LeftFiveLoop:
+ DEC_L (hcount)
+ JNS (.LeftFiveBody)
+ JMP (.finish)
+
+.RightFast:
+ SUB_L (tmp,srcPitchReg)
+ SUB_L (tmp,dstPitchReg)
+ CMP_L (CONST(4),tmp)
+ JG (.RightFiveLoop)
+ JE (.RightFourLoop)
+ CMP_L (CONST(2),tmp)
+ JG (.RightThreeLoop)
+ JE (.RightTwoLoop)
+ JMP (.RightOneLoop)
+
+ ALIGNTEXT4
+.RightOneBody:
+ MOV_B (REGOFF(-1,psrc),BL)
+ MOV_B (BL,REGOFF(-1,pdst))
+ ADD_L (srcPitchReg,psrc)
+ ADD_L (dstPitchReg,pdst)
+.RightOneLoop:
+ DEC_L (hcount)
+ JNS (.RightOneBody)
+ JMP (.finish)
+
+ ALIGNTEXT4
+.RightTwoBody:
+ MOV_W (REGOFF(-2,psrc),BX)
+ MOV_W (BX,REGOFF(-2,pdst))
+ ADD_L (srcPitchReg,psrc)
+ ADD_L (dstPitchReg,pdst)
+.RightTwoLoop:
+ DEC_L (hcount)
+ JNS (.RightTwoBody)
+ JMP (.finish)
+
+ ALIGNTEXT4
+.RightThreeBody:
+ MOV_W (REGOFF(-3,psrc),BX)
+ MOV_W (BX,REGOFF(-3,pdst))
+ MOV_B (REGOFF(-1,psrc),BL)
+ MOV_B (BL,REGOFF(-1,pdst))
+ ADD_L (srcPitchReg,psrc)
+ ADD_L (dstPitchReg,pdst)
+.RightThreeLoop:
+ DEC_L (hcount)
+ JNS (.RightThreeBody)
+ JMP (.finish)
+
+ ALIGNTEXT4
+.RightFourBody:
+ MOV_L (REGOFF(-4,psrc),EBX)
+ MOV_L (EBX,REGOFF(-4,pdst))
+ ADD_L (srcPitchReg,psrc)
+ ADD_L (dstPitchReg,pdst)
+.RightFourLoop:
+ DEC_L (hcount)
+ JNS (.RightFourBody)
+ JMP (.finish)
+
+ ALIGNTEXT4
+.RightFiveBody:
+ MOV_L (REGOFF(-5,psrc),EBX)
+ MOV_L (EBX,REGOFF(-5,pdst))
+ MOV_B (REGOFF(-1,psrc),BL)
+ MOV_B (BL,REGOFF(-1,pdst))
+ ADD_L (srcPitchReg,psrc)
+ ADD_L (dstPitchReg,pdst)
+.RightFiveLoop:
+ DEC_L (hcount)
+ JNS (.RightFiveBody)
+ JMP (.finish)
+
+
+.BlockSetup:
+ MOV_L (psrc,tmp)
+ AND_L (CONST(3),tmp)
+ MOV_L (pdst,Shift)
+ AND_L (CONST(3),Shift)
+ CMP_L (Shift,tmp)
+ JNE (.UnalignedBlock)
+
+ CMP_L (CONST(1),xdir)
+ JE (.LeftBlockLoop)
+ JMP (.RightBlockLoop)
+
+.LeftBlockBody:
+ TEST_L (CONST(1),pdst) /* align to word ? */
+ JZ (.LeftAlignWord)
+ MOVS_B
+ DEC_L (tmp)
+.LeftAlignWord:
+ TEST_L (CONST(2),pdst) /* align to dword ? */
+ JZ (.LeftStartBlock)
+ MOVS_W
+ SUB_L (CONST(2),tmp)
+.LeftStartBlock:
+ MOV_L (tmp,ECX)
+ SHR_L (CONST(2),ECX)
+ REPZ
+ MOVS_L /* tricky: this is really the fastest way !! */
+ TEST_L (CONST(2),tmp) /* finish requires a word ? */
+ JZ (.LeftFixupByte)
+ MOVS_W
+.LeftFixupByte:
+ TEST_L (CONST(1),tmp) /* finish requires a byte ? */
+ JZ (.LeftBlockEnd)
+ MOVS_B
+.LeftBlockEnd:
+ ADD_L (srcPitch,psrc) /* ok, goto next line */
+ ADD_L (dstPitch,pdst)
+.LeftBlockLoop:
+ MOV_L (count,tmp) /* reload linecounter */
+ DEC_L (hcount)
+ JNS (.LeftBlockBody)
+ JMP (.finish)
+
+.RightBlockBody:
+ TEST_L (CONST(1),pdst) /* align to word ? */
+ JZ (.RightAlignWord)
+ DEC_L (psrc)
+ DEC_L (pdst)
+ MOV_B (REGIND(psrc),AL)
+ MOV_B (AL,REGIND(pdst))
+ DEC_L (tmp)
+.RightAlignWord:
+ TEST_L (CONST(2),pdst) /* align to dword ? */
+ JZ (.RightStartBlock)
+ SUB_L (CONST(2),psrc)
+ SUB_L (CONST(2),pdst)
+ MOV_W (REGIND(psrc),AX)
+ MOV_W (AX,REGIND(pdst))
+ SUB_L (CONST(2),tmp)
+.RightStartBlock:
+ MOV_L (tmp,ECX)
+ SHR_L (CONST(2),ECX)
+ SUB_L (CONST(4),psrc)
+ SUB_L (CONST(4),pdst)
+ REPZ
+ MOVS_L /* tricky: this is really the fastest way !! */
+ ADD_L (CONST(4),psrc)
+ ADD_L (CONST(4),pdst)
+ TEST_L (CONST(2),tmp) /* finish requires a word ? */
+ JZ (.RightFixupByte)
+ SUB_L (CONST(2),psrc)
+ SUB_L (CONST(2),pdst)
+ MOV_W (REGIND(psrc),AX)
+ MOV_W (AX,REGIND(pdst))
+.RightFixupByte:
+ TEST_L (CONST(1),tmp) /* finish requires a byte ? */
+ JZ (.RightBlockEnd)
+ DEC_L (psrc)
+ DEC_L (pdst)
+ MOV_B (REGIND(psrc),AL)
+ MOV_B (AL,REGIND(pdst))
+.RightBlockEnd:
+ ADD_L (srcPitch,psrc) /* ok, goto next line */
+ ADD_L (dstPitch,pdst)
+.RightBlockLoop:
+ MOV_L (count,tmp) /* reload linecounter */
+ DEC_L (hcount)
+ JNS (.RightBlockBody)
+ JMP (.finish)
+
+/*
+ * ok, now the cases when Src & Dst are not at the same offset
+ */
+.UnalignedBlock:
+
+ MOV_L (tmp,xSrc)
+ MOV_L (Shift,xDst)
+ CMP_L (CONST(1),xdir)
+ JNE (.rightShiftSetup)
+
+ SUB_L (tmp,Shift)
+ JS (.lsAdjustShift)
+ SUB_L (CONST(4),Shift)
+.lsAdjustShift:
+ NEG_L (Shift)
+ SHL_L (CONST(3),Shift)
+ JMP (.leftShiftLoop)
+
+
+.leftShiftBody:
+ MOV_L (CONST(0),low)
+ MOV_L (CONST(0),high)
+/*
+ * first load (4-xSrc) Pixels, so that psrc is dword-aligned
+ */
+ MOV_L (xSrc,tmp)
+ MOV_L (REGDIS(.lseTab,tmp,4),tmp)
+ JMP (CODEPTR(tmp))
+ SEG_DATA
+ ALIGNDATA4
+.lseTab: D_LONG .lse0, .lse1, .lse2, .lse3
+ SEG_TEXT
+ ALIGNTEXT4
+.lse0: MOV_L (REGIND(psrc),low)
+ ADD_L (CONST(4),psrc)
+ SUB_L (CONST(4),countS)
+ JMP (.lse)
+.lse1: MOV_W (REGOFF(1,psrc),loww)
+ SHL_L (CONST(16),low)
+ MOV_B (REGIND(psrc),lowb)
+ ADD_L (CONST(3),psrc)
+ SUB_L (CONST(3),countS)
+ JMP (.lse)
+.lse2: MOV_W (REGIND(psrc),loww)
+ SHL_L (CONST(16),low)
+ ADD_L (CONST(2),psrc)
+ SUB_L (CONST(2),countS)
+ JMP (.lse)
+.lse3: MOV_B (REGIND(psrc),lowb)
+ SHL_L (CONST(16),low)
+ INC_L (psrc)
+ DEC_L (countS)
+/*
+ * get now the rest of Pixels neccessary to align pdst to a dword
+ * i.e if (4 - xDst) > (4 - xSrc) get 4 additional Pixels
+ * i.e if xDst < xSrc !!!!
+ */
+.lse: MOV_L (xDst,tmp)
+ OR_L (tmp,tmp)
+ JZ (.lsf0)
+ CMP_L (tmp,xSrc)
+ JL (.lsfirst)
+ MOV_L (low,high)
+ MOV_L (REGIND(psrc),low)
+ ADD_L (CONST(4),psrc)
+ SUB_L (CONST(4),countS)
+/*
+ * now store (4- xDst) Pixel
+ */
+.lsfirst:
+ SHRD2_L (low,high)
+ MOV_L (REGDIS(.lsfTab,tmp,4),tmp)
+ JMP (CODEPTR(tmp))
+ SEG_DATA
+ ALIGNDATA4
+.lsfTab: D_LONG .lsf0, .lsf1, .lsf2, .lsf3
+ SEG_TEXT
+ ALIGNTEXT4
+.lsf1: MOV_B (highb,REGIND(pdst))
+ SHR_L (CONST(16),high)
+ MOV_W (highw,REGOFF(1,pdst))
+ ADD_L (CONST(3),pdst)
+ JMP (.lsf0)
+.lsf2: SHR_L (CONST(16),high)
+ MOV_W (highw,REGIND(pdst))
+ ADD_L (CONST(2),pdst)
+ JMP (.lsf0)
+.lsf3: SHR_L (CONST(16),high)
+ MOV_B (highb,REGIND(pdst))
+ INC_L (pdst)
+/*
+ * we have countS Pixel to load. Get them as dword, i.e as 4 Pixel group.
+ * that means we can get (countS >> 2) dwords !
+ * since psrc and pdst are aligned dword, this is the fast case.
+ */
+.lsf0: MOV_L (low,high)
+ MOV_L (countS,tmp)
+ SHR_L (CONST(2),tmp)
+ JMP (.lsdl)
+
+ ALIGNTEXT4
+.lsdb: LODS_L
+ SHRD2_L (low,high)
+ XCHG_L (low,high)
+ STOS_L
+.lsdl: DEC_L (tmp)
+ JNS (.lsdb)
+/*
+ * the are (countS & 3) Pixles to get.
+ * but be carefull, these pixels are now aligned LEFT !!!! ( on the screen)
+ */
+ XOR_L (low,low)
+ MOV_L (countS,tmp)
+ AND_L (CONST(3),tmp)
+ ADD_L (tmp,psrc)
+ MOV_L (REGDIS(.lsaTab,tmp,4),tmp)
+ JMP (CODEPTR(tmp))
+ SEG_DATA
+ ALIGNDATA4
+.lsaTab: D_LONG .lsa0, .lsa1, .lsa2, .lsa3
+ SEG_TEXT
+ ALIGNTEXT4
+.lsa3: MOV_B (REGOFF(-1,psrc),lowbl)
+ SHL_L (CONST(16),low)
+ MOV_W (REGOFF(-3,psrc),loww)
+ JMP (.lsa0)
+.lsa2: MOV_W (REGOFF(-2,psrc),loww)
+ JMP (.lsa0)
+.lsa1: MOV_B (REGOFF(-1,psrc),lowbl)
+
+.lsa0: SHRD2_L (low,high)
+ SHR_L (CL,low)
+/*
+ * at this point we have read all Pixels, but there are still some to store
+ * the number of Pixel in [low,high] seems to be ((countS&3)+(4 - Shift))
+ * that maens we have here to store 1,2,3,4,5,6 Pixel (0 & 7 are impossible)
+ */
+ MOV_L (countS,tmp)
+ AND_L (CONST(3),tmp)
+ ADD_L (CONST(4),tmp)
+ SHL_L (CONST(3),tmp)
+ SUB_L (Shift,tmp)
+ SHR_L (CONST(3),tmp)
+ ADD_L (tmp,pdst)
+ MOV_L (REGDIS(.lsgTab,tmp,4),tmp)
+ JMP (CODEPTR(tmp))
+ SEG_DATA
+ ALIGNDATA4
+.lsgTab: D_LONG .lsg0, .lsg1, .lsg2, .lsg3, .lsg4, .lsg5, .lsg6, .lsg0
+ SEG_TEXT
+ ALIGNTEXT4
+.lsg6: MOV_L (high,REGOFF(-6,pdst))
+ MOV_W (loww,REGOFF(-2,pdst))
+ JMP (.lsg0)
+
+.lsg5: MOV_L (high,REGOFF(-5,pdst))
+ MOV_B (lowbl,REGOFF(-1,pdst))
+ JMP (.lsg0)
+
+.lsg4: MOV_L (high,REGOFF(-4,pdst))
+ JMP (.lsg0)
+
+.lsg3: MOV_W (highw,REGOFF(-3,pdst))
+ SHR_L (CONST(16),high)
+ MOV_B (highbl,REGOFF(-1,pdst))
+ JMP (.lsg0)
+
+.lsg2: MOV_W (highw,REGOFF(-2,pdst))
+ JMP (.lsg0)
+
+.lsg1: MOV_B (highbl,REGOFF(-1,pdst))
+
+.lsg0: MOV_L (countS,tmp)
+ AND_L (CONST(3),tmp)
+ ADD_L (CONST(4),tmp)
+ SHL_L (CONST(3),tmp)
+ SUB_L (Shift,tmp)
+ SHR_L (CONST(3),tmp)
+
+
+ ADD_L (srcPitch,psrc)
+ ADD_L (dstPitch,pdst)
+
+.leftShiftLoop:
+ MOV_L (count,tmp)
+ MOV_L (tmp,countS)
+ DEC_L (hcountS)
+ JNS (.leftShiftBody)
+ JMP (.finish)
+
+/*
+ * now, descending x-direction
+ */
+.rightShiftSetup:
+
+ SUB_L (tmp,Shift)
+ JNS (.rsAdjustShift)
+ ADD_L (CONST(4),Shift)
+.rsAdjustShift:
+ SHL_L (CONST(3),Shift)
+ JMP (.rightShiftLoop)
+
+.rightShiftBody:
+ MOV_L (CONST(0),low)
+ MOV_L (CONST(0),high)
+/*
+ * first load (xSrc) Pixels, so that psrc is dword-aligned
+ */
+ MOV_L (xSrc,tmp)
+ MOV_L (REGDIS(.rseTab,tmp,4),tmp)
+ JMP (CODEPTR(tmp))
+ SEG_DATA
+ ALIGNDATA4
+.rseTab: D_LONG .rse0, .rse1, .rse2, .rse3
+ SEG_TEXT
+ ALIGNTEXT4
+.rse3: SUB_L (CONST(3),psrc)
+ SUB_L (CONST(3),countS)
+ MOV_B (REGOFF(2,psrc),lowbl)
+ SHL_L (CONST(16),low)
+ MOV_W (REGIND(psrc),loww)
+ JMP (.rse0)
+.rse2: SUB_L (CONST(2),psrc)
+ SUB_L (CONST(2),countS)
+ MOV_W (REGIND(psrc),loww)
+ JMP (.rse0)
+.rse1: DEC_L (psrc)
+ DEC_L (countS)
+ MOV_B (REGIND(psrc),lowbl)
+/*
+ * get now the rest of Pixels neccessary to align pdst to a dword
+ * i.e if (xDst > xSrc) get 4 additional Pixels
+ */
+.rse0: MOV_L (xDst,tmp)
+ OR_L (tmp,tmp)
+ JZ (.rsf0)
+ CMP_L (tmp,xSrc)
+ JG (.rsfirst)
+ SUB_L (CONST(4),psrc)
+ SUB_L (CONST(4),countS)
+ MOV_L (low,high)
+ MOV_L (REGIND(psrc),low)
+/*
+ * now store (xDst) Pixels
+ */
+.rsfirst:
+ SHLD2_L (low,high)
+ MOV_L (REGDIS(.rsfTab,tmp,4),tmp)
+ JMP (CODEPTR(tmp))
+ SEG_DATA
+ ALIGNDATA4
+.rsfTab: D_LONG .rsf0, .rsf1, .rsf2, .rsf3
+ SEG_TEXT
+ ALIGNTEXT4
+.rsf3: SUB_L (CONST(3),pdst)
+ MOV_W (highw,REGIND(pdst))
+ SHR_L (CONST(16),high)
+ MOV_B (highbl,REGOFF(2,pdst))
+ JMP (.rsf0)
+.rsf2: SUB_L (CONST(2),pdst)
+ MOV_W (highw,REGIND(pdst))
+ JMP (.rsf0)
+.rsf1: DEC_L (pdst)
+ MOV_B (highbl,REGIND(pdst))
+/*
+ * we have countS Pixel to load. Get them as dword, i.e as 4 Pixel group.
+ * that means we can get (countS >> 2) dwords !
+ * since psrc and pdst are aligned dword, this is the fast case.
+ */
+.rsf0: MOV_L (low,high)
+ MOV_L (countS,tmp)
+ SHR_L (CONST(2),tmp)
+ JMP (.rsdl)
+
+ ALIGNTEXT4
+.rsdb: SUB_L (CONST(4),psrc)
+ SUB_L (CONST(4),pdst)
+ MOV_L (REGIND(psrc),low)
+ SHLD2_L (low,high)
+ MOV_L (high,REGIND(pdst))
+ MOV_L (low,high)
+.rsdl: DEC_L (tmp)
+ JNS (.rsdb)
+/*
+ * the are (countS & 3) Pixles to get.
+ * but be carefull, these pixels are now aligned RIGHT !!!! ( on the screen)
+ */
+ XOR_L (low,low)
+ MOV_L (countS,tmp)
+ AND_L (CONST(3),tmp)
+ SUB_L (tmp,psrc)
+ MOV_L (REGDIS(.rsaTab,tmp,4),tmp)
+ JMP (CODEPTR(tmp))
+ SEG_DATA
+ ALIGNDATA4
+.rsaTab: D_LONG .rsa0, .rsa1, .rsa2, .rsa3
+ SEG_TEXT
+ ALIGNTEXT4
+.rsa3: MOV_W (REGOFF(1,psrc),loww)
+ SHL_L (CONST(16),low)
+ MOV_B (REGIND(psrc),lowb)
+ JMP (.rsa0)
+.rsa2: MOV_W (REGIND(psrc),loww)
+ SHL_L (CONST(16),low)
+ JMP (.rsa0)
+.rsa1: MOV_B (REGIND(psrc),lowb)
+ SHL_L (CONST(16),low)
+.rsa0: SHLD2_L (low,high)
+ SHL_L (CL,low)
+/*
+ * at this point we have read all Pixels, but there are still some to store
+ * the number of Pixel in [low,high] seems to be ((countS&3)+(4 - Shift))
+ * that maens we have here to store 1,2,3,4,5,6 Pixel (0 & 7 are impossible)
+ */
+ MOV_L (countS,tmp)
+ AND_L (CONST(3),tmp)
+ ADD_L (CONST(4),tmp)
+ SHL_L (CONST(3),tmp)
+ SUB_L (Shift,tmp)
+ SHR_L (CONST(3),tmp)
+ SUB_L (tmp,pdst)
+ MOV_L (REGDIS(.rsgTab,tmp,4),tmp)
+ JMP (CODEPTR(tmp))
+ SEG_DATA
+ ALIGNDATA4
+.rsgTab: D_LONG .rsg0, .rsg1, .rsg2, .rsg3, .rsg4, .rsg5, .rsg6, .rsg0
+ SEG_TEXT
+ ALIGNTEXT4
+.rsg6: MOV_L (high,REGOFF(2,pdst))
+ SHR_L (CONST(16),low)
+ MOV_W (loww,REGIND(pdst))
+ JMP (.rsg0)
+.rsg5: MOV_L (high,REGOFF(1,pdst))
+ SHR_L (CONST(16),low)
+ MOV_B (lowb,REGIND(pdst))
+ JMP (.rsg0)
+.rsg4: MOV_L (high,REGIND(pdst))
+ JMP (.rsg0)
+.rsg3: MOV_B (highb,REGIND(pdst))
+ SHR_L (CONST(16),high)
+ MOV_W (highw,REGOFF(1,pdst))
+ JMP (.rsg0)
+.rsg2: SHR_L (CONST(16),high)
+ MOV_W (highw,REGIND(pdst))
+ JMP (.rsg0)
+.rsg1: SHR_L (CONST(16),high)
+ MOV_B (highb,REGIND(pdst))
+
+.rsg0: ADD_L (srcPitch,psrc)
+ ADD_L (dstPitch,pdst)
+
+.rightShiftLoop:
+ MOV_L (count,tmp)
+ MOV_L (tmp,countS)
+ DEC_L (hcountS)
+ JNS (.rightShiftBody)
+ JMP (.finish)
+
+.finish:
+ CLD
+ LEA_L (REGOFF(-24,EBP),ESP)
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fFill.s b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fFill.s
new file mode 100644
index 000000000..20c2f538d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fFill.s
@@ -0,0 +1,234 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fFill.s,v 1.2 1998/07/25 16:58:28 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Roell not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Roell makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Thomas Roell, roell@informatik.tu-muenchen.de
+ *
+ * This file was derived from a similar X11R4 file (X386 1.1) for X11R5
+ * (X386 1.2) by James Tsillas. This file was further derived to its current
+ * form by David Wexelblat (dwex@goblin.org).
+ *
+ */
+/* $XConsortium: fFill.s /main/6 1996/02/21 18:08:43 kaleb $ */
+
+#include "assyntax.h"
+
+#if __STDC__ && !defined(UNIXCPP)
+#define RROP_NAME_CAT(prefix,suffix) prefix##suffix
+#else
+#define RROP_NAME_CAT(prefix,suffix) prefix/**/suffix
+#endif
+
+#define GXAnd 1
+#define GXCopy 2
+#define GXOr 3
+#define GXXor 4
+
+#if RROP == GXAnd
+ FILE("fFillAnd.s")
+# define RROPB AND_B
+# define RROPW AND_W
+# define RROPL AND_L
+# define RROP_NAME(pref) RROP_NAME_CAT(pref,GXand)
+#elif RROP == GXOr
+ FILE("fFillOr.s")
+# define RROPB OR_B
+# define RROPW OR_W
+# define RROPL OR_L
+# define RROP_NAME(pref) RROP_NAME_CAT(pref,GXor)
+#elif RROP == GXXor
+ FILE("fFillXor.s")
+# define RROPB XOR_B
+# define RROPW XOR_W
+# define RROPL XOR_L
+# define RROP_NAME(pref) RROP_NAME_CAT(pref,GXxor)
+#elif RROP == GXCopy
+ FILE("fFillCopy.s")
+# define RROPB MOV_B
+# define RROPW MOV_W
+# define RROPL MOV_L
+# define RROP_NAME(pref) RROP_NAME_CAT(pref,GXcopy)
+#endif
+
+ AS_BEGIN
+
+#define GL_RROP_NAME RROP_NAME(GLNAME(fastFillSolid))
+
+/*
+ *
+ * This routine implements a fast Solid Fill in GXcopy
+ * No segment checking is done.
+ *
+ * SYNTAX:
+ * unchar * fastFillSolid<RROP>(pdst,fill,dummy,hcount,count,width,widthPitch);
+ *
+ * (7/27/90 TR)
+ * (4/92 JT)
+ * (5/92 DW)
+ */
+
+#define pdst EDI
+#define fill EAX
+#define fillw AX
+#define fillb AL
+#define count ESI
+#define hcount ECX
+#define width REGOFF(28,EBP)
+#define widthPitch EBX
+#define tmp EAX
+
+
+ SEG_DATA
+ ALIGNDATA4
+countt:
+ D_LONG 0
+ SEG_TEXT
+ ALIGNTEXT4
+
+#define rrop_name /**/RROP_NAME(fastFillSolid)
+
+GLOBL GL_RROP_NAME
+
+GL_RROP_NAME:
+ PUSH_L (EBP)
+ MOV_L (ESP,EBP)
+ PUSH_L (EDI)
+ PUSH_L (ESI)
+ PUSH_L (EBX)
+ MOV_L (REGOFF(8,EBP),pdst)
+ MOV_L (REGOFF(12,EBP),fill)
+ MOV_L (REGOFF(20,EBP),hcount)
+ MOV_L (REGOFF(24,EBP),count)
+ MOV_L (REGOFF(32,EBP),widthPitch)
+ OR_L (hcount,hcount)
+ JZ (.finish)
+ OR_L (count,count)
+ JZ (.finish)
+ CMP_L (CONST(3),count)
+ JG (.startblockloop)
+ JE (.tribbleloop)
+ CMP_L (CONST(2),count)
+ JE (.wordloop)
+/*
+ * do a fast vertical line
+ */
+ ALIGNTEXT4ifNOP
+.byteloop:
+ RROPB (fillb,REGIND(pdst))
+ LEA_L (REGBID(widthPitch,pdst,1),pdst)
+ DEC_L (ECX)
+ JNZ (.byteloop)
+ JMP (.finish)
+
+ ALIGNTEXT4
+.wordloop:
+ RROPW (fillw,REGIND(pdst))
+ LEA_L (REGBID(widthPitch,pdst,2),pdst)
+ DEC_L (ECX)
+ JNZ (.wordloop)
+ JMP (.finish)
+
+ ALIGNTEXT4
+.tribbleloop:
+ RROPW (fillw,REGIND(pdst))
+ RROPB (fillb,REGOFF(2,pdst))
+ LEA_L (REGBID(widthPitch,pdst,3),pdst)
+ DEC_L (ECX)
+ JNZ (.tribbleloop)
+ JMP (.finish)
+
+#undef count
+#define count ECX
+#undef hcount
+#define hcount ESI
+
+.startblockloop:
+ XCHG_L (ECX, ESI)
+ ALIGNTEXT4ifNOP
+.blockloop:
+ TEST_L (CONST(1),pdst)
+ JZ (.alignword)
+#if RROP == GXCopy
+ STOS_B
+#else
+ RROPB (fillb,REGIND(pdst))
+ INC_L (pdst)
+#endif
+ DEC_L (count)
+.alignword:
+ TEST_L (CONST(2),pdst)
+ JZ (.aligneddword)
+#if RROP == GXCopy
+ STOS_W
+#else
+ RROPW (fillw,REGIND(pdst))
+ ADD_L (CONST(2),pdst)
+#endif
+ LEA_L (REGOFF(-2,count),count)
+.aligneddword:
+ MOV_L (count, CONTENT(countt))
+ AND_L (CONST(3), CONTENT(countt))
+ SHR_L (CONST(2), count)
+#if RROP == GXCopy
+ REPZ
+ STOS_L
+#else
+ OR_L (ECX, ECX)
+ JZ (.endloop)
+ ALIGNTEXT4ifNOP
+.loop0: RROPL (fill,REGIND(pdst))
+ ADD_L (CONST(4),pdst)
+ DEC_L (ECX)
+ JNZ (.loop0)
+.endloop:
+#endif
+ TEST_L (CONST(2),CONTENT(countt))
+ JZ (.fixupbyte)
+#if RROP == GXCopy
+ STOS_W
+#else
+ RROPW (fillw,REGIND(pdst))
+ ADD_L (CONST(2),pdst)
+#endif
+.fixupbyte:
+ TEST_L (CONST(1),CONTENT(countt))
+ JZ (.enditeration)
+#if RROP == GXCopy
+ STOS_B
+#else
+ RROPB (fillb,REGIND(pdst))
+ INC_L (pdst)
+#endif
+.enditeration:
+ LEA_L (REGBI(widthPitch,pdst),pdst)
+ MOV_L (width,count)
+ DEC_L (hcount)
+ JNZ (.blockloop)
+.finish:
+ MOV_L (pdst,EAX)
+ LEA_L (REGOFF(-12,EBP),ESP)
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fFillSet.s b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fFillSet.s
new file mode 100644
index 000000000..f7cf6a547
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fFillSet.s
@@ -0,0 +1,261 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fFillSet.s,v 1.2 1998/07/25 16:58:28 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Roell not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Roell makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Thomas Roell, roell@informatik.tu-muenchen.de
+ *
+ * This file was derived from a similar X11R4 file (X386 1.1) for X11R5
+ * (X386 1.2) by James Tsillas. This file was further derived to its current
+ * form by David Wexelblat (dwex@goblin.org).
+ *
+ */
+/* $XConsortium: fFillSet.s /main/5 1996/02/21 18:08:46 kaleb $ */
+
+#include "assyntax.h"
+
+ FILE("fFillSet.s")
+ AS_BEGIN
+
+/*
+ *
+ * This routine implements a fast Solid Fill in GXset mode.
+ * no segment checking is done.
+ *
+ * SYNTAX:
+ * unchar * fastFillSolidGXset(pdst,fill1,fill2,hcount,count,width,widthPitch);
+ *
+ * (7/27/90 TR)
+ * (4/92 JT)
+ * (5/92 DW)
+ */
+
+#define pdst EBX
+#define lp ECX
+#define count EDX
+#define hcount EDI
+#define width REGOFF(28,EBP)
+#define widthPitch ESI
+#define tmp EAX
+#define tmpw AX
+#define tmpb AL
+#define fill1 REGOFF(12,EBP)
+#define fill2 REGOFF(16,EBP)
+
+ SEG_TEXT
+ ALIGNTEXT4
+GLOBL GLNAME(fastFillSolidGXset)
+
+GLNAME(fastFillSolidGXset):
+ PUSH_L (EBP)
+ MOV_L (ESP,EBP)
+ PUSH_L (EDI)
+ PUSH_L (ESI)
+ PUSH_L (EBX)
+ MOV_L (REGOFF(8,EBP),pdst)
+ MOV_L (REGOFF(20,EBP),hcount)
+ MOV_L (REGOFF(24,EBP),count)
+ MOV_L (REGOFF(32,EBP),widthPitch)
+ OR_L (hcount,hcount)
+ JZ (.finish)
+ OR_L (count,count)
+ JZ (.finish)
+ CMP_L (CONST(3),count)
+ JG (.blockloop)
+ JE (.tribbleloop)
+ CMP_L (CONST(2),count)
+ JE (.wordloop)
+/*
+ * do a fast vertical line
+ */
+ ALIGNTEXT4ifNOP
+.byteloop:
+ MOV_B (fill1,tmpb)
+ AND_B (REGIND(pdst),tmpb)
+ XOR_B (fill2,tmpb)
+ MOV_B (tmpb,REGIND(pdst))
+ LEA_L (REGBID(widthPitch,pdst,1),pdst)
+ DEC_L (hcount)
+ JNZ (.byteloop)
+ JMP (.finish)
+
+ ALIGNTEXT4
+.wordloop:
+ MOV_W (fill1,tmpw)
+ AND_W (REGIND(pdst),tmpw)
+ XOR_W (fill2,tmpw)
+ MOV_W (tmpw,REGIND(pdst))
+ LEA_L (REGBID(widthPitch,pdst,2),pdst)
+ DEC_L (hcount)
+ JNZ (.wordloop)
+ JMP (.finish)
+
+ ALIGNTEXT4
+.tribbleloop:
+ MOV_W (fill1,tmpw)
+ AND_W (REGIND(pdst),tmpw)
+ XOR_W (fill2,tmpw)
+ MOV_W (tmpw,REGIND(pdst))
+ MOV_B (fill1,tmpb)
+ AND_B (REGOFF(2,pdst),tmpb)
+ XOR_B (fill2,tmpb)
+ MOV_B (tmpb,REGOFF(2,pdst))
+ LEA_L (REGBID(widthPitch,pdst,3),pdst)
+ DEC_L (hcount)
+ JNZ (.tribbleloop)
+ JMP (.finish)
+
+ ALIGNTEXT4
+.blockloop:
+ TEST_L (CONST(1),pdst)
+ JZ (.alignword)
+ MOV_B (fill1,tmpb)
+ AND_B (REGIND(pdst),tmpb)
+ XOR_B (fill2,tmpb)
+ MOV_B (tmpb,REGIND(pdst))
+ INC_L (pdst)
+ DEC_L (count)
+.alignword:
+ TEST_L (CONST(2),pdst)
+ JZ (.aligneddword)
+ MOV_W (fill1,tmpw)
+ AND_W (REGIND(pdst),tmpw)
+ XOR_W (fill2,tmpw)
+ MOV_W (tmpw,REGIND(pdst))
+ LEA_L (REGOFF(2,pdst),pdst)
+ LEA_L (REGOFF(-2,count),count)
+.aligneddword:
+ MOV_L (count,lp)
+ SHR_L (CONST(5),lp)
+ JZ (.fixupdword)
+
+ ALIGNTEXT4ifNOP
+.dwordloop:
+ MOV_L (REGOFF(0,pdst),tmp)
+ AND_L (fill1,tmp)
+ XOR_L (fill2,tmp)
+ MOV_L (tmp,REGOFF(0,pdst))
+ MOV_L (REGOFF(4,pdst),tmp)
+ AND_L (fill1,tmp)
+ XOR_L (fill2,tmp)
+ MOV_L (tmp,REGOFF(4,pdst))
+ MOV_L (REGOFF(8,pdst),tmp)
+ AND_L (fill1,tmp)
+ XOR_L (fill2,tmp)
+ MOV_L (tmp,REGOFF(8,pdst))
+ MOV_L (REGOFF(12,pdst),tmp)
+ AND_L (fill1,tmp)
+ XOR_L (fill2,tmp)
+ MOV_L (tmp,REGOFF(12,pdst))
+ MOV_L (REGOFF(16,pdst),tmp)
+ AND_L (fill1,tmp)
+ XOR_L (fill2,tmp)
+ MOV_L (tmp,REGOFF(16,pdst))
+ MOV_L (REGOFF(20,pdst),tmp)
+ AND_L (fill1,tmp)
+ XOR_L (fill2,tmp)
+ MOV_L (tmp,REGOFF(20,pdst))
+ MOV_L (REGOFF(24,pdst),tmp)
+ AND_L (fill1,tmp)
+ XOR_L (fill2,tmp)
+ MOV_L (tmp,REGOFF(24,pdst))
+ MOV_L (REGOFF(28,pdst),tmp)
+ AND_L (fill1,tmp)
+ XOR_L (fill2,tmp)
+ MOV_L (tmp,REGOFF(28,pdst))
+ LEA_L (REGOFF(32,pdst),pdst)
+ DEC_L (lp)
+ JNZ (.dwordloop)
+
+.fixupdword:
+ MOV_L (count,lp)
+ AND_L (CONST(28),lp)
+ LEA_L (REGBI(lp,pdst),pdst)
+ MOV_L (REGDB(.jumptab1,lp),tmp)
+ JMP (CODEPTR(tmp))
+
+ SEG_DATA
+ ALIGNDATA4
+.jumptab1:
+ D_LONG .Lnoop, .L0, .L1, .L2, .L3, .L4, .L5, .L6
+
+ SEG_TEXT
+ ALIGNTEXT4
+.L6: MOV_L (fill1,tmp)
+ AND_L (REGOFF(-28,pdst),tmp)
+ XOR_L (fill2,tmp)
+ MOV_L (tmp,REGOFF(-28,pdst))
+.L5: MOV_L (fill1,tmp)
+ AND_L (REGOFF(-24,pdst),tmp)
+ XOR_L (fill2,tmp)
+ MOV_L (tmp,REGOFF(-24,pdst))
+.L4: MOV_L (fill1,tmp)
+ AND_L (REGOFF(-20,pdst),tmp)
+ XOR_L (fill2,tmp)
+ MOV_L (tmp,REGOFF(-20,pdst))
+.L3: MOV_L (fill1,tmp)
+ AND_L (REGOFF(-16,pdst),tmp)
+ XOR_L (fill2,tmp)
+ MOV_L (tmp,REGOFF(-16,pdst))
+.L2: MOV_L (fill1,tmp)
+ AND_L (REGOFF(-12,pdst),tmp)
+ XOR_L (fill2,tmp)
+ MOV_L (tmp,REGOFF(-12,pdst))
+.L1: MOV_L (fill1,tmp)
+ AND_L (REGOFF(-8,pdst),tmp)
+ XOR_L (fill2,tmp)
+ MOV_L (tmp,REGOFF(-8,pdst))
+.L0: MOV_L (fill1,tmp)
+ AND_L (REGOFF(-4,pdst),tmp)
+ XOR_L (fill2,tmp)
+ MOV_L (tmp,REGOFF(-4,pdst))
+.Lnoop:
+
+ TEST_L (CONST(2),count)
+ JZ (.fixupbyte)
+ MOV_W (fill1,tmpw)
+ AND_W (REGIND(pdst),tmpw)
+ XOR_W (fill2,tmpw)
+ MOV_W (tmpw,REGIND(pdst))
+ LEA_L (REGOFF(2,pdst),pdst)
+.fixupbyte:
+ TEST_L (CONST(1),count)
+ JZ (.enditeration)
+ MOV_B (fill1,tmpb)
+ AND_B (REGIND(pdst),tmpb)
+ XOR_B (fill2,tmpb)
+ MOV_B (tmpb,REGIND(pdst))
+ INC_L (pdst)
+
+.enditeration:
+ LEA_L (REGBI(widthPitch,pdst),pdst)
+ MOV_L (width,count)
+ DEC_L (hcount)
+ JNZ (.blockloop)
+
+.finish:
+ MOV_L (pdst,EAX)
+ LEA_L (REGOFF(-12,EBP),ESP)
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fLineBres.s b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fLineBres.s
new file mode 100644
index 000000000..e41c230f9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fLineBres.s
@@ -0,0 +1,206 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fLineBres.s,v 1.2 1998/07/25 16:58:29 dawes Exp $ */
+/* Copyright 1992 by James Tsillas, Arlington, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation.
+
+JAMES TSILLAS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+*/
+/* $XConsortium: fLineBres.s /main/5 1996/02/21 18:08:50 kaleb $ */
+
+#include "assyntax.h"
+#include "vgaAsm.h"
+
+ FILE("fLineBres.s")
+ AS_BEGIN
+
+#define rop REGOFF(8,EBP)
+#define andv DH
+#define xorv DL
+#define addrl REGOFF(20,EBP)
+#define nlwidth REGOFF(24,EBP)
+#define signdx REGOFF(28,EBP)
+#define signdy REGOFF(32,EBP)
+#define axis REGOFF(36,EBP)
+#define x1 REGOFF(40,EBP)
+#define y1 REGOFF(44,EBP)
+#define e EDI
+#define e1 ESI
+#define e2 REGOFF(56,EBP)
+#define len ECX
+
+#define addrb EBX
+#define tmp EAX
+
+#define GXcopy CONST(3)
+#define Y_AXIS CONST(1)
+
+ SEG_DATA
+ ALIGNDATA4
+e3:
+ D_LONG 0
+
+ SEG_TEXT
+ ALIGNTEXT4
+GLOBL GLNAME(fastvga256BresS)
+
+GLNAME(fastvga256BresS):
+ PUSH_L (EBP)
+ MOV_L (ESP,EBP)
+ PUSH_L (EDI)
+ PUSH_L (ESI)
+ PUSH_L (EBX)
+ MOV_L (REGOFF(60,EBP),len)
+ CMP_L (CONST(0),len) /* check for zero length first */
+ JZ (.allfinish)
+ MOV_B (REGOFF(12,EBP),andv)
+ MOV_B (REGOFF(16,EBP),xorv)
+ MOV_L (REGOFF(48,EBP),e)
+ MOV_L (REGOFF(52,EBP),e1)
+ MOV_L (e2,tmp)
+ SUB_L (e1,tmp)
+ MOV_L (tmp,CONTENT(e3))
+ SHL_L (CONST(2),nlwidth)
+ MOV_L (nlwidth,tmp)
+ IMUL_L (y1,tmp)
+ ADD_L (x1,tmp)
+ ADD_L (addrl,tmp)
+ MOV_L (tmp,addrb)
+ CMP_L (CONST(0),signdy)
+ JGE (.L1)
+ NEG_L (nlwidth)
+.L1: SUB_L (e1,e)
+ CMP_L (Y_AXIS,axis)
+ JNZ (.L2)
+ PUSH_L (nlwidth)
+ PUSH_L (signdx)
+ POP_L (nlwidth)
+ POP_L (signdx)
+.L2: CMP_L (GXcopy,rop)
+ JNZ (.LSet)
+
+.LCopy: CMP_L (VGABASE,addrl)
+ JB (.nocheckloopC)
+ PUSH_L (addrb)
+ CALL (GLNAME(vgaSetWrite))
+ MOV_L (tmp,addrb)
+ ADD_L (CONST(4),ESP)
+
+ ALIGNTEXT4ifNOP
+.writeloopC:
+ MOV_B (xorv,REGIND(addrb))
+ ADD_L (e1,e)
+ JS (.L3)
+ ADD_L (nlwidth,addrb)
+ ADD_L (CONTENT(e3),e)
+.L3: ADD_L (signdx,addrb)
+ CMP_L (CONTENT(GLNAME(vgaWriteBottom)),addrb)
+ /* was JBE */
+ JB (.L4)
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)),addrb)
+ JAE (.L9)
+ DEC_L (ECX)
+ JNZ (.writeloopC)
+ JMP (.allfinish)
+.L9: PUSH_L (addrb)
+ CALL (GLNAME(vgaWriteNext))
+ MOV_L (tmp,addrb)
+ ADD_L (CONST(4),ESP)
+ DEC_L (ECX)
+ JNZ (.writeloopC)
+ JMP (.allfinish)
+.L4: PUSH_L (addrb)
+ CALL (GLNAME(vgaWritePrev))
+ MOV_L (tmp,addrb)
+ ADD_L (CONST(4),ESP)
+ DEC_L (ECX)
+ JNZ (.writeloopC)
+ JMP (.allfinish)
+
+ ALIGNTEXT4
+.nocheckloopC:
+ MOV_B (xorv,REGIND(addrb))
+ ADD_L (e1,e)
+ JS (.L5)
+ ADD_L (nlwidth,addrb)
+ ADD_L (CONTENT(e3),e)
+.L5: ADD_L (signdx,addrb)
+ DEC_L (ECX)
+ JNZ (.nocheckloopC)
+
+ ALIGNTEXT4ifNOP
+.allfinish:
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+
+.LSet: CMP_L (VGABASE,addrl)
+ JB (.nocheckloopS)
+ PUSH_L (addrb)
+ CALL (GLNAME(vgaSetReadWrite))
+ MOV_L (tmp,addrb)
+ ADD_L (CONST(4),ESP)
+
+ ALIGNTEXT4ifNOP
+.writeloopS:
+ MOV_B (REGIND(addrb),AL) /* Minimize slow memory access */
+ AND_B (andv,AL)
+ XOR_B (xorv,AL)
+ MOV_B (AL,REGIND(addrb))
+ ADD_L (e1,e)
+ JS (.L6)
+ ADD_L (nlwidth,addrb)
+ ADD_L (CONTENT(e3),e)
+.L6: ADD_L (signdx,addrb)
+ CMP_L (CONTENT(GLNAME(vgaWriteBottom)),addrb)
+ /* was JBE */
+ JB (.L7)
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)),addrb)
+ JAE (.L10)
+ DEC_L (ECX)
+ JNZ (.writeloopS)
+ JMP (.allfinish)
+.L10: PUSH_L (addrb)
+ CALL (GLNAME(vgaReadWriteNext))
+ MOV_L (tmp,addrb)
+ ADD_L (CONST(4),ESP)
+ DEC_L (ECX)
+ JNZ (.writeloopS)
+ JMP (.allfinish)
+.L7: PUSH_L (addrb)
+ CALL (GLNAME(vgaReadWritePrev))
+ MOV_L (EAX,addrb)
+ ADD_L (CONST(4),ESP)
+ DEC_L (ECX)
+ JNZ (.writeloopS)
+ JMP (.allfinish)
+
+ ALIGNTEXT4
+.nocheckloopS:
+ MOV_B (REGIND(addrb),AL) /* Minimize slow memory access */
+ AND_B (andv,AL)
+ XOR_B (xorv,AL)
+ MOV_B (AL,REGIND(addrb))
+ ADD_L (e1,e)
+ JS (.L8)
+ ADD_L (nlwidth,addrb)
+ ADD_L (CONTENT(e3),e)
+.L8: ADD_L (signdx,addrb)
+ DEC_L (ECX)
+ JNZ (.nocheckloopS)
+ JMP (.allfinish)
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fLineH.s b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fLineH.s
new file mode 100644
index 000000000..8b231a551
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fLineH.s
@@ -0,0 +1,471 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fLineH.s,v 1.2 1998/07/25 16:58:29 dawes Exp $ */
+/* Copyright 1992 by James Tsillas, Arlington, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation.
+
+JAMES TSILLAS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+*/
+/* $XConsortium: fLineH.s /main/5 1996/02/21 18:08:54 kaleb $ */
+
+#include "assyntax.h"
+#include "vgaAsm.h"
+
+ FILE("fLineH.s")
+ AS_BEGIN
+
+#define rop REGOFF(8,EBP)
+#define andv EBX
+#define andvb BL
+#define andvw BX
+#define xorv EDX
+#define xorvb DL
+#define xorvw DX
+#define addrl EDI
+#define nlwidth REGOFF(24,EBP)
+#define x1 REGOFF(28,EBP)
+#define y1 REGOFF(32,EBP)
+#define len ESI
+
+#define count ECX
+#define tmp EAX
+
+#define GXcopy CONST(3)
+#define GXxor CONST(6)
+
+SEG_TEXT
+ ALIGNTEXT4
+GLOBL GLNAME(fastvga256HorzS)
+
+GLNAME(fastvga256HorzS):
+ PUSH_L (EBP)
+ MOV_L (ESP,EBP)
+ PUSH_L (ESI)
+ PUSH_L (EDI)
+ PUSH_L (EBX)
+ MOV_L (REGOFF(16,EBP),xorv)
+ MOV_L (REGOFF(20,EBP),addrl)
+ MOV_L (REGOFF(36,EBP),len)
+ CLD
+ MOV_L (nlwidth,tmp)
+ SHL_L (CONST(2),tmp)
+ IMUL_L (y1,tmp)
+ ADD_L (x1,tmp)
+ ADD_L (tmp,addrl)
+ CMP_L (VGABASE,addrl)
+ JB (.noClongL)
+ PUSH_L (addrl)
+ CALL (GLNAME(vgaSetReadWrite))
+ MOV_L (tmp,addrl)
+ ADD_L (CONST(4),ESP)
+ MOV_L (CONTENT(GLNAME(vgaWriteTop)),tmp)
+ SUB_L (addrl,tmp)
+ CMP_L (len,tmp)
+ JAE (.noClongL)
+
+.ClongL:
+ CMP_L (GXcopy,rop)
+ JNE (.XlongL)
+ CMP_L (CONST(2),len)
+ JE (.L14)
+ JB (.L15)
+.L13: TEST_L (CONST(3),addrl)
+ JZ (.L8)
+ MOV_B (xorvb,REGIND(addrl))
+ INC_L (addrl)
+ DEC_L (len)
+.L14: TEST_L (CONST(3),addrl)
+ JZ (.L8A)
+ MOV_B (xorvb,REGIND(addrl))
+ INC_L (addrl)
+ DEC_L (len)
+.L15: TEST_L (CONST(3),addrl)
+ JZ (.L8A)
+ MOV_B (xorvb,REGIND(addrl))
+ INC_L (addrl)
+ DEC_L (len)
+.L8A: CMP_L (CONTENT(GLNAME(vgaWriteTop)),addrl)
+ JB (.L8)
+ PUSH_L (addrl)
+ CALL (GLNAME(vgaWriteNext))
+ MOV_L (tmp,addrl)
+ ADD_L (CONST(4),ESP)
+.L8: MOV_L (len,count)
+ AND_L (CONST(0xfffffffc),count)
+ MOV_L (CONTENT(GLNAME(vgaWriteTop)),tmp)
+ SUB_L (addrl,tmp)
+ CMP_L (tmp,count)
+ JBE (.L16)
+ MOV_L (tmp,count)
+.L16: SUB_L (count,len)
+ SHR_L (CONST(2),count)
+ JZ (.L10)
+ MOV_L (xorv,tmp)
+ REPZ
+ STOS_L
+ CMP_L (CONST(3),len)
+ JBE (.L17)
+ PUSH_L (addrl)
+ CALL (GLNAME(vgaWriteNext))
+ MOV_L (tmp,addrl)
+ ADD_L (CONST(4),ESP)
+ MOV_L (len,count)
+ AND_L (CONST(0xfffffffc),count)
+ SUB_L (count,len)
+ SHR_L (CONST(2),count)
+ MOV_L (xorv,tmp)
+ REPZ
+ STOS_L
+.L17: CMP_L (CONTENT(GLNAME(vgaWriteTop)),addrl)
+ JB (.L10)
+ PUSH_L (addrl)
+ CALL (GLNAME(vgaWriteNext))
+ MOV_L (tmp,addrl)
+ ADD_L (CONST(4),ESP)
+.L10: CMP_L (CONST(2),len)
+ JA (.L11)
+ JE (.L12)
+ CMP_L (CONST(0),len)
+ JE (.allfinish)
+ MOV_B (xorvb,REGIND(addrl))
+ JMP (.allfinish)
+.L11: MOV_W (xorvw,REGIND(addrl))
+ MOV_B (xorvb,REGOFF(2,addrl)) /**/
+ JMP (.allfinish)
+.L12: MOV_W (xorvw,REGIND(addrl)) /**/
+.allfinish:
+ POP_L (EBX)
+ POP_L (EDI)
+ POP_L (ESI)
+ LEAVE
+ RET
+
+.XlongL:
+ MOV_L (REGOFF(12,EBP),andv)
+ CMP_L (GXxor,rop)
+ JNE (.SlongL)
+ CMP_L (CONST(2),len)
+ JE (.LX14)
+ JB (.LX15)
+.LX13: TEST_L (CONST(3),addrl)
+ JZ (.LX8)
+ XOR_B (xorvb,REGIND(addrl)) /**/
+ INC_L (addrl)
+ DEC_L (len)
+.LX14: TEST_L (CONST(3),addrl)
+ JZ (.LX8A)
+ XOR_B (xorvb,REGIND(addrl)) /**/
+ INC_L (addrl)
+ DEC_L (len)
+.LX15: TEST_L (CONST(3),addrl)
+ JZ (.LX8A)
+ XOR_B (xorvb,REGIND(addrl)) /**/
+ INC_L (addrl)
+ DEC_L (len)
+.LX8A: CMP_L (CONTENT(GLNAME(vgaWriteTop)),addrl)
+ JB (.LX8)
+ PUSH_L (addrl)
+ CALL (GLNAME(vgaReadWriteNext))
+ MOV_L (tmp,addrl)
+ ADD_L (CONST(4),ESP)
+.LX8: MOV_L (len,count)
+ AND_L (CONST(0xfffffffc),count)
+ MOV_L (CONTENT(GLNAME(vgaWriteTop)),tmp)
+ SUB_L (addrl,tmp)
+ CMP_L (tmp,count)
+ JBE (.LX16)
+ MOV_L (tmp,count)
+.LX16: SUB_L (count,len)
+ SHR_L (CONST(2),count)
+ JZ (.LX10)
+.LX9: XOR_L (xorv,REGIND(addrl)) /**/
+ ADD_L (CONST(4),addrl)
+ DEC_L (ECX)
+ JNZ (.LX9)
+ CMP_L (CONST(3),len)
+ JBE (.LX17)
+ PUSH_L (addrl)
+ CALL (GLNAME(vgaReadWriteNext))
+ MOV_L (tmp,addrl)
+ ADD_L (CONST(4),ESP)
+ MOV_L (len,count)
+ AND_L (CONST(0xfffffffc),count)
+ SUB_L (count,len)
+ SHR_L (CONST(2),count)
+.LX18: XOR_L (xorv,REGIND(addrl)) /**/
+ ADD_L (CONST(4),addrl)
+ DEC_L (ECX)
+ JNZ (.LX18)
+.LX17: CMP_L (CONTENT(GLNAME(vgaWriteTop)),addrl)
+ JB (.LX10)
+ PUSH_L (addrl)
+ CALL (GLNAME(vgaReadWriteNext))
+ MOV_L (tmp,addrl)
+ ADD_L (CONST(4),ESP)
+.LX10: CMP_L (CONST(2),len)
+ JA (.LX11)
+ JE (.LX12)
+ CMP_L (CONST(0),len)
+ JE (.allfinish)
+ XOR_B (xorvb,REGIND(addrl)) /**/
+ JMP (.allfinish)
+.LX11: XOR_W (xorvw,REGIND(addrl)) /**/
+ XOR_B (xorvb,REGOFF(2,addrl)) /**/
+ JMP (.allfinish)
+.LX12: XOR_W (xorvw,REGIND(addrl)) /**/
+ JMP (.allfinish)
+
+.SlongL:
+ CMP_L (CONST(2),len)
+ JE (.LS14)
+ JB (.LS15)
+.LS13: TEST_L (CONST(3),addrl)
+ JZ (.LS8)
+ MOV_B (REGIND(addrl),AL)
+ AND_B (andvb,AL)
+ XOR_B (xorvb,AL) /**/
+ STOS_B
+ DEC_L (len)
+.LS14: TEST_L (CONST(3),addrl)
+ JZ (.LS8A)
+ MOV_B (REGIND(addrl),AL)
+ AND_B (andvb,AL)
+ XOR_B (xorvb,AL) /**/
+ STOS_B
+ DEC_L (len)
+.LS15: TEST_L (CONST(3),addrl)
+ JZ (.LS8A)
+ MOV_B (REGIND(addrl),AL)
+ AND_B (andvb,AL)
+ XOR_B (xorvb,AL) /**/
+ STOS_B
+ DEC_L (len)
+.LS8A: CMP_L (CONTENT(GLNAME(vgaWriteTop)),addrl)
+ JB (.LS8)
+ PUSH_L (addrl)
+ CALL (GLNAME(vgaReadWriteNext))
+ MOV_L (tmp,addrl)
+ ADD_L (CONST(4),ESP)
+.LS8: MOV_L (len,count)
+ AND_L (CONST(0xfffffffc),count)
+ MOV_L (CONTENT(GLNAME(vgaWriteTop)),tmp)
+ SUB_L (addrl,tmp)
+ CMP_L (tmp,count)
+ JBE (.LS16)
+ MOV_L (tmp,count)
+.LS16: SUB_L (count,len)
+ SHR_L (CONST(2),count)
+ JZ (.LS10)
+.LS9: MOV_L (REGIND(addrl),tmp)
+ AND_L (andv,tmp)
+ XOR_L (xorv,tmp) /**/
+ STOS_L
+ DEC_L (ECX)
+ JNZ (.LS9)
+ CMP_L (CONST(3),len)
+ JBE (.LS17)
+ PUSH_L (addrl)
+ CALL (GLNAME(vgaReadWriteNext))
+ MOV_L (tmp,addrl)
+ ADD_L (CONST(4),ESP)
+ MOV_L (len,count)
+ AND_L (CONST(0xfffffffc),count)
+ SUB_L (count,len)
+ SHR_L (CONST(2),count)
+.LS18: MOV_L (REGIND(addrl),tmp)
+ AND_L (andv,tmp)
+ XOR_L (xorv,tmp) /**/
+ STOS_L
+ DEC_L (ECX)
+ JNZ (.LS18)
+.LS17: CMP_L (CONTENT(GLNAME(vgaWriteTop)),addrl)
+ JB (.LS10)
+ PUSH_L (addrl)
+ CALL (GLNAME(vgaReadWriteNext))
+ MOV_L (tmp,addrl)
+ ADD_L (CONST(4),ESP)
+.LS10: CMP_L (CONST(2),len)
+ JA (.LS11)
+ JE (.LS12)
+ CMP_L (CONST(0),len)
+ JE (.allfinish)
+ MOV_B (REGIND(addrl),AL)
+ AND_B (andvb,AL)
+ XOR_B (xorvb,AL) /**/
+ MOV_B (AL,REGIND(addrl))
+ JMP (.allfinish)
+.LS11: MOV_W (REGIND(addrl),AX)
+ AND_W (andvw,AX)
+ XOR_W (xorvw,AX) /**/
+ STOS_W
+ MOV_B (REGIND(addrl),AL)
+ AND_B (andvb,AL)
+ XOR_B (xorvb,AL) /**/
+ MOV_B (AL,REGIND(addrl))
+ JMP (.allfinish)
+.LS12: MOV_W (REGIND(addrl),AX)
+ AND_W (andvw,AX)
+ XOR_W (xorvw,AX) /**/
+ MOV_W (AX,REGIND(addrl))
+ JMP (.allfinish)
+
+.noClongL:
+ CMP_L (GXcopy,rop)
+ JNE (.noXlongL)
+ CMP_L (CONST(2),len)
+ JE (.LC6)
+ JB (.LC7)
+.LC5: TEST_L (CONST(3),addrl)
+ JZ (.LC0)
+ MOV_B (xorvb,REGIND(addrl))
+ INC_L (addrl)
+ DEC_L (len)
+.LC6: TEST_L (CONST(3),addrl)
+ JZ (.LC0)
+ MOV_B (xorvb,REGIND(addrl))
+ INC_L (addrl)
+ DEC_L (len)
+.LC7: TEST_L (CONST(3),addrl)
+ JZ (.LC0)
+ MOV_B (xorvb,REGIND(addrl))
+ INC_L (addrl)
+ DEC_L (len)
+.LC0: MOV_L (len,count)
+ AND_L (CONST(0xfffffffc),count)
+ SUB_L (count,len)
+ SHR_L (CONST(2),count)
+ JZ (.LC2)
+ MOV_L (xorv,tmp)
+ CLD
+ REPZ
+ STOS_L
+.LC2: CMP_L (CONST(2),len)
+ JA (.LC3)
+ JE (.LC4)
+ CMP_L (CONST(0),len)
+ JE (.allfinish)
+ MOV_B (xorvb,REGIND(addrl)) /**/
+ JMP (.allfinish)
+.LC3: MOV_W (xorvw,REGIND(addrl)) /**/
+ MOV_B (xorvb,REGOFF(2,addrl)) /**/
+ JMP (.allfinish)
+.LC4: MOV_W (xorvw,REGIND(addrl)) /**/
+ JMP (.allfinish)
+
+
+.noXlongL:
+ MOV_L (REGOFF(12,EBP),andv)
+ CMP_L (GXxor,rop)
+ JNE (.noSlongL)
+ CMP_L (CONST(2),len)
+ JE (.LX6)
+ JB (.LX7)
+.LX5: TEST_L (CONST(3),addrl)
+ JZ (.LX0)
+ XOR_B (xorvb,REGIND(addrl)) /**/
+ INC_L (addrl)
+ DEC_L (len)
+.LX6: TEST_L (CONST(3),addrl)
+ JZ (.LX0)
+ XOR_B (xorvb,REGIND(addrl)) /**/
+ INC_L (addrl)
+ DEC_L (len)
+.LX7: TEST_L (CONST(3),addrl)
+ JZ (.LX0)
+ XOR_B (xorvb,REGIND(addrl)) /**/
+ INC_L (addrl)
+ DEC_L (len)
+.LX0: MOV_L (len,count)
+ AND_L (CONST(0xfffffffc),count)
+ SUB_L (count,len)
+ SHR_L (CONST(2),count)
+ JZ (.LX2)
+.LX1: XOR_L (xorv,REGIND(addrl)) /**/
+ ADD_L (CONST(4),addrl)
+ DEC_L (ECX)
+ JNZ (.LX1)
+.LX2: CMP_L (CONST(2),len)
+ JA (.LX3)
+ JE (.LX4)
+ CMP_L (CONST(0),len)
+ JE (.allfinish)
+ XOR_B (xorvb,REGIND(addrl)) /**/
+ JMP (.allfinish)
+.LX3: XOR_W (xorvw,REGIND(addrl)) /**/
+ XOR_B (xorvb,REGOFF(2,addrl)) /**/
+ JMP (.allfinish)
+.LX4: XOR_W (xorvw,REGIND(addrl)) /**/
+ JMP (.allfinish)
+
+.noSlongL:
+ CMP_L (CONST(2),len)
+ JE (.LS6)
+ JB (.LS7)
+.LS5: TEST_L (CONST(3),addrl)
+ JZ (.LS0)
+ MOV_B (REGIND(addrl),AL)
+ AND_B (andvb,AL)
+ XOR_B (xorvb,AL) /**/
+ STOS_B
+ DEC_L (len)
+.LS6: TEST_L (CONST(3),addrl)
+ JZ (.LS0)
+ MOV_B (REGIND(addrl),AL)
+ AND_B (andvb,AL)
+ XOR_B (xorvb,AL) /**/
+ STOS_B
+ DEC_L (len)
+.LS7: TEST_L (CONST(3),addrl)
+ JZ (.LS0)
+ MOV_B (REGIND(addrl),AL)
+ AND_B (andvb,AL)
+ XOR_B (xorvb,AL) /**/
+ STOS_B
+ DEC_L (len)
+.LS0: MOV_L (len,count)
+ AND_L (CONST(0xfffffffc),count)
+ SUB_L (count,len)
+ SHR_L (CONST(2),count)
+ JZ (.LS2)
+.LS1: MOV_L (REGIND(addrl),tmp)
+ AND_L (andv,tmp)
+ XOR_L (xorv,tmp) /**/
+ STOS_L
+ DEC_L (ECX)
+ JNZ (.LS1)
+.LS2: CMP_L (CONST(2),len)
+ JA (.LS3)
+ JE (.LS4)
+ CMP_L (CONST(0),len)
+ JE (.allfinish)
+ MOV_B (REGIND(addrl),AL)
+ AND_B (andvb,AL)
+ XOR_B (xorvb,AL) /**/
+ MOV_B (AL,REGIND(addrl))
+ JMP (.allfinish)
+.LS3: MOV_W (REGIND(addrl),AX)
+ AND_W (andvw,AX)
+ XOR_W (xorvw,AX) /**/
+ STOS_W
+ MOV_B (REGIND(addrl),AL)
+ AND_B (andvb,AL)
+ XOR_B (xorvb,AL) /**/
+ MOV_B (AL,REGIND(addrl))
+ JMP (.allfinish)
+.LS4: MOV_W (REGIND(addrl),AX)
+ AND_W (andvw,AX)
+ XOR_W (xorvw,AX) /**/
+ MOV_W (AX,REGIND(addrl))
+ JMP (.allfinish)
+
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fLineV.s b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fLineV.s
new file mode 100644
index 000000000..18f4b6fa5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fLineV.s
@@ -0,0 +1,237 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/enhanced/fLineV.s,v 1.2 1998/07/25 16:58:30 dawes Exp $ */
+/* Copyright 1992 by James Tsillas, Arlington, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation.
+
+JAMES TSILLAS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+*/
+/* $XConsortium: fLineV.s /main/5 1996/02/21 18:08:57 kaleb $ */
+
+#include "assyntax.h"
+#include "vgaAsm.h"
+
+ FILE("fLineV.s")
+ AS_BEGIN
+
+#define rop REGOFF(8,EBP)
+#define andv BL
+#define xorv BH
+#define pdst EDI
+#define nlwidth ESI
+#define x1 REGOFF(28,EBP)
+#define y1 REGOFF(32,EBP)
+#define len REGOFF(36,EBP)
+
+#define len0 ECX
+#define tmp EAX
+
+#define GXcopy CONST(3)
+#define GXxor CONST(6)
+
+
+ SEG_TEXT
+GLOBL GLNAME(fastvga256VertS)
+ ALIGNTEXT4
+GLNAME(fastvga256VertS):
+ PUSH_L (EBP)
+ MOV_L (ESP,EBP)
+ PUSH_L (EBX)
+ PUSH_L (ESI)
+ PUSH_L (EDI)
+ MOV_B (REGOFF(12,EBP),andv)
+ MOV_B (REGOFF(16,EBP),xorv)
+ MOV_L (REGOFF(20,EBP),pdst)
+ MOV_L (REGOFF(24,EBP),nlwidth)
+ SHL_L (CONST(2),nlwidth)
+ MOV_L (y1,tmp)
+ IMUL_L (nlwidth,tmp)
+ ADD_L (x1,tmp)
+ ADD_L (tmp,pdst)
+ MOV_L (pdst,REGOFF(20,EBP))
+ CMP_L (GXcopy,rop)
+ JNE (.GXxorloop)
+
+.GXcopyloop:
+ CMP_L (VGABASE,pdst)
+ JB (.nocheckC)
+
+ ALIGNTEXT4ifNOP
+.checkC:
+ PUSH_L (REGOFF(20,EBP))
+ CALL (GLNAME(vgaSetWrite))
+ MOV_L (tmp,pdst)
+ ADD_L (CONST(4),ESP)
+ MOV_L (CONTENT(GLNAME(vgaWriteTop)),tmp)
+ SUB_L (pdst,tmp)
+ XOR_L (EDX,EDX)
+ DIV_L (nlwidth)
+ OR_L (tmp,tmp)
+ JZ (.L3)
+ CMP_L (len,tmp)
+ JAE (.nocheckC)
+ MOV_L (tmp,len0)
+ SUB_L (len0,len)
+ IMUL_L (nlwidth,tmp)
+ ADD_L (tmp,REGOFF(20,EBP))
+.L1: MOV_B (xorv,REGIND(pdst))
+ ADD_L (nlwidth,pdst)
+ DEC_L (ECX)
+ JNZ (.L1) /* len0 is %ecx */
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)),pdst)
+ JAE (.checkC)
+.L3: MOV_B (xorv,REGIND(pdst))
+ DEC_L (len)
+ JZ (.allfinish)
+ ADD_L (nlwidth,REGOFF(20,EBP))
+ JMP (.checkC)
+
+ ALIGNTEXT4
+.nocheckC:
+ CMP_L (CONST(0),len)
+ JZ (.allfinish)
+ MOV_L (len,len0)
+ CMP_L (CONST(8),ECX)
+ JB (.L2)
+ /* Unrolled loop */
+.L10: MOV_B (xorv,REGIND(pdst)) /* line 0 */
+ MOV_B (xorv,REGBI(pdst,nlwidth)) /* line 1 */
+ MOV_B (xorv,REGBISD(pdst,nlwidth,2,0)) /* line 2 */
+ MOV_B (xorv,REGBISD(pdst,nlwidth,4,0)) /* line 4 */
+ ADD_L (nlwidth,pdst)
+ MOV_B (xorv,REGBISD(pdst,nlwidth,2,0)) /* line 3 */
+ MOV_B (xorv,REGBISD(pdst,nlwidth,4,0)) /* line 5 */
+ ADD_L (nlwidth,pdst)
+ MOV_B (xorv,REGBISD(pdst,nlwidth,4,0)) /* line 6 */
+ ADD_L (nlwidth,pdst)
+ LEA_L (REGBISD(pdst,nlwidth,4,0),pdst)
+ MOV_B (xorv,REGIND(pdst)) /* line 7 */
+ ADD_L (nlwidth,pdst)
+ SUB_L (CONST(8),ECX)
+ JZ (.allfinish)
+ CMP_L (CONST(8),ECX)
+ JAE (.L10)
+.L2: MOV_B (xorv,REGIND(pdst))
+ ADD_L (nlwidth,pdst)
+ DEC_L (ECX)
+ JNZ (.L2) /* len0 is %ecx */
+.allfinish:
+ POP_L (EDI)
+ POP_L (ESI)
+ POP_L (EBX)
+ LEAVE
+ RET
+
+.GXxorloop:
+ CMP_L (GXxor,rop)
+ JNE (.GXsetloop)
+ CMP_L (VGABASE,pdst)
+ JB (.nocheckX)
+
+ ALIGNTEXT4ifNOP
+.checkX:
+ PUSH_L (REGOFF(20,EBP))
+ CALL (GLNAME(vgaSetReadWrite))
+ MOV_L (tmp,pdst)
+ ADD_L (CONST(4),ESP)
+ MOV_L (CONTENT(GLNAME(vgaWriteTop)),tmp)
+ SUB_L (pdst,tmp)
+ XOR_L (EDX,EDX)
+ DIV_L (nlwidth)
+ OR_L (tmp,tmp)
+ JZ (.L6)
+ CMP_L (len,tmp)
+ JAE (.nocheckX)
+ MOV_L (tmp,len0)
+ SUB_L (len0,len)
+ IMUL_L (nlwidth,tmp)
+ ADD_L (tmp,REGOFF(20,EBP))
+.L4: XOR_B (xorv,REGIND(pdst))
+ ADD_L (nlwidth,pdst)
+ DEC_L (ECX)
+ JNZ (.L4) /* len0 is %ecx */
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)),pdst)
+ JAE (.checkX)
+.L6: XOR_B (xorv,REGIND(pdst))
+ DEC_L (len)
+ JZ (.allfinish)
+ ADD_L (nlwidth,REGOFF(20,EBP))
+ JMP (.checkX)
+
+ ALIGNTEXT4
+.nocheckX:
+ CMP_L (CONST(0),len)
+ JZ (.allfinish)
+ MOV_L (len,len0)
+.L5: XOR_B (xorv,REGIND(pdst))
+ ADD_L (nlwidth,pdst)
+ DEC_L (ECX)
+ JNZ (.L5) /* len0 is %ecx */
+ JMP (.allfinish)
+
+.GXsetloop:
+ CMP_L (VGABASE,pdst)
+ JB (.nocheckS)
+
+ ALIGNTEXT4ifNOP
+.checkS:
+ PUSH_L (REGOFF(20,EBP))
+ CALL (GLNAME(vgaSetReadWrite))
+ MOV_L (tmp,pdst)
+ ADD_L (CONST(4),ESP)
+ MOV_L (CONTENT(GLNAME(vgaWriteTop)),tmp)
+ SUB_L (pdst,tmp)
+ XOR_L (EDX,EDX)
+ DIV_L (nlwidth)
+ OR_L (tmp,tmp)
+ JZ (.L9)
+ CMP_L (len,tmp)
+ JAE (.nocheckS)
+ MOV_L (tmp,len0)
+ SUB_L (len0,len)
+ IMUL_L (nlwidth,tmp)
+ ADD_L (tmp,REGOFF(20,EBP))
+.L7: MOV_B (REGIND(pdst),AL)
+ AND_B (andv,AL)
+ XOR_B (xorv,AL)
+ MOV_B (AL,REGIND(pdst))
+ ADD_L (nlwidth,pdst)
+ DEC_L (ECX)
+ JNZ (.L7) /* len0 is %ecx */
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)),pdst)
+ JAE (.checkS)
+.L9: MOV_B (REGIND(pdst),AL)
+ AND_B (andv,AL)
+ XOR_B (xorv,AL)
+ MOV_B (AL,REGIND(pdst))
+ DEC_L (len)
+ JZ (.allfinish)
+ ADD_L (nlwidth,REGOFF(20,EBP))
+ JMP (.checkS)
+
+ ALIGNTEXT4
+.nocheckS:
+ CMP_L (CONST(0),len)
+ JZ (.allfinish)
+ MOV_L (len,len0)
+.L8: MOV_B (REGIND(pdst),AL)
+ AND_B (andv,AL)
+ XOR_B (xorv,AL)
+ MOV_B (AL,REGIND(pdst))
+ ADD_L (nlwidth,pdst)
+ DEC_L (ECX)
+ JNZ (.L8) /* len0 is %ecx */
+ JMP (.allfinish)
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/gBanks.c b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/gBanks.c
new file mode 100644
index 000000000..f229317f7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/gBanks.c
@@ -0,0 +1,55 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/enhanced/gBanks.c,v 1.2 1998/07/25 16:58:30 dawes Exp $ */
+/*******************************************************************************
+ Copyright 1992 by Glenn G. Lai
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Glenn G. Lai not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+Glenn G. Lai DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+Glenn G. Lai
+P.O. Box 4314
+Austin, Tx 78765
+(glenn@cs.utexas.edu)
+6/3/92
+*******************************************************************************/
+/* $XConsortium: gBanks.c /main/4 1996/02/21 18:09:02 kaleb $ */
+
+#include "misc.h"
+#include "vgaBank.h"
+unsigned SpeedUpRowsNext[17];
+unsigned SpeedUpRowsPrev[17];
+
+void
+SpeedUpComputeNext(dst, h)
+unsigned dst, h;
+{
+ if (vgaWriteFlag) {
+ register unsigned int i, j = h, k = 0, l = vgaSegmentMask + 1 >> 10;
+
+ i = l - ((dst & vgaSegmentMask) >> 10);
+ do {
+ if (i > j) i = j;
+ j -= i;
+ SpeedUpRowsNext[k++] = i;
+ i = l;
+ } while (j);
+ SpeedUpRowsNext[k] = 0;
+ } else {
+ SpeedUpRowsNext[0] = h;
+ SpeedUpRowsNext[1] = 0;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suBBlt2.s b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suBBlt2.s
new file mode 100644
index 000000000..011e9b70e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suBBlt2.s
@@ -0,0 +1,860 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suBBlt2.s,v 1.2 1998/07/25 16:58:30 dawes Exp $ */
+/*******************************************************************************
+ Copyright 1992 by Glenn G. Lai
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Glenn G. Lai not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+Glenn G. Lai DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+Glenn G. Lai
+P.O. Box 4314
+Austin, Tx 78765
+(glenn@cs.utexas.edu)
+7/27/92
+*******************************************************************************/
+/* $XConsortium: suBBlt2.s /main/4 1996/02/21 18:09:05 kaleb $ */
+
+#include "assyntax.h"
+
+ FILE("suBitBlt2.s")
+ AS_BEGIN
+
+#include "vgaAsm.h"
+
+/* void PixWin(src, dst, height, width, sWidth, dWidth) */
+
+#define src REGOFF(8,EBP)
+#define dst REGOFF(12,EBP)
+#define height REGOFF(16,EBP)
+#define width REGOFF(20,EBP)
+#define sWidth REGOFF(24,EBP)
+#define dWidth REGOFF(28,EBP)
+
+ SEG_DATA
+copyright:
+ STRING("Copyright 7/27/1992 by Glenn G. Lai")
+ ALIGNDATA4
+speedUpTop:
+ D_LONG 0
+sOffset:
+ D_LONG 0
+dOffset:
+ D_LONG 0
+allowance:
+ D_LONG 0
+lCount:
+ D_LONG 0
+mCount:
+ D_LONG 0
+rCount:
+ D_LONG 0
+heightCount:
+ D_LONG 0
+func:
+ D_LONG 0
+sPixWinTable:
+ D_LONG 0, sPixWin1, sPixWin2, sPixWin3, sPixWin4
+pixWinTable:
+ D_LONG pwM, pwMR, pwLM, pwLMR
+segment:
+ D_BYTE 0
+/*************************************/
+ SEG_TEXT
+ ALIGNTEXT4
+ GLOBL GLNAME(PixWin)
+GLNAME(PixWin):
+ MOV_L (REGOFF(12,ESP), EAX)
+ OR_L (REGOFF(16,ESP), EAX)
+ JZ (return)
+
+ CLD
+ PUSH_L (EBP)
+ MOV_L (ESP, EBP)
+ PUSH_L (EDI)
+ PUSH_L (ESI)
+ PUSH_L (EBX)
+
+ MOV_L (dWidth, EAX)
+ MOV_L (width, ECX)
+ SUB_L (ECX, EAX)
+ MOV_L (EAX, CONTENT(dOffset))
+ ADD_L (CONTENT(GLNAME(vgaWriteTop)), EAX)
+ MOV_L (EAX, CONTENT(speedUpTop))
+
+ MOV_L (sWidth, EAX)
+ SUB_L (ECX, EAX)
+ MOV_L (EAX, CONTENT(sOffset))
+
+ MOV_L (src, ESI)
+ MOV_L (dst, EDI)
+ SUB_L (VGABASE, EDI)
+ CMP_L (CONST(5), ECX)
+ JNC (pixWin1)
+ MOV_L (REGDIS(sPixWinTable,ECX,4), EAX)
+ MOV_L (EAX, CONTENT(func))
+ JMP (pixWin2)
+/*************************************/
+ ALIGNTEXT4
+pixWin1:
+ MOV_L (ADDR(pixWinTable), EAX)
+ TEST_L (CONST(1), EDI)
+ JZ (pixWin3)
+ ADD_L (CONST(8), EAX)
+ DEC_L (ECX)
+pixWin3:
+ MOV_L (ECX, EBX)
+ AND_L (CONST(3), EBX)
+ JZ (pixWin4)
+ ADD_L (CONST(4), EAX)
+pixWin4:
+ MOV_L (REGIND(EAX), EAX)
+ MOV_L (EAX, CONTENT(func))
+ MOV_L (EBX, CONTENT(rCount))
+ SHR_L (CONST(2), ECX)
+ MOV_L (ECX, CONTENT(mCount))
+pixWin2:
+ MOV_L (EDI, EAX)
+ SHR_L (CONST(16), EAX)
+ MOV_B (AL, CONTENT(segment))
+
+ AND_L (CONST(0xffff), EDI)
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+ JMP (pwLoop3)
+/*************************************/
+ ALIGNTEXT4
+pwLoop:
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)), EDI)
+ JC (pwLoop1)
+ SUB_L (CONST(0x10000), EDI)
+ MOV_B (CONTENT(segment), AL)
+ INC_B (AL)
+ MOV_B (AL, CONTENT(segment))
+pwLoop3:
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+pwLoop1:
+ MOV_L (CONTENT(speedUpTop), EAX)
+ SUB_L (EDI, EAX)
+ XOR_L (EDX, EDX)
+ DIV_L (dWidth)
+
+ OR_L (EAX, EAX)
+ JZ (pwPartial)
+
+ MOV_L (height, EBX)
+ CMP_L (EBX, EAX)
+ JC (pwLoop2)
+ MOV_L (EBX, EAX)
+pwLoop2:
+ MOV_L (EAX, CONTENT(allowance))
+ MOV_L (EAX, EDX)
+ MOV_L (CONTENT(sOffset), EAX)
+ MOV_L (CONTENT(dOffset), EBX)
+
+ CALL (VARINDIRECT(func))
+
+ MOV_L (height, EAX)
+ SUB_L (CONTENT(allowance), EAX)
+ MOV_L (EAX, height)
+ JNZ (pwLoop)
+
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+return:
+ RET
+/********************************/
+ ALIGNTEXT4
+pwM:
+wpM:
+ MOV_L (CONTENT(mCount), ECX)
+ REP
+ MOVS_L
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (pwM)
+ RET
+/********************************/
+ ALIGNTEXT4
+pwMR:
+wpMR:
+ MOV_L (CONTENT(mCount), ECX)
+ REP
+ MOVS_L
+ MOV_L (CONTENT(rCount), ECX)
+ REP
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (pwMR)
+ RET
+/********************************/
+ ALIGNTEXT4
+pwLM:
+wpLM:
+ MOVS_B
+ MOV_L (CONTENT(mCount), ECX)
+ REP
+ MOVS_L
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (pwLM)
+ RET
+/********************************/
+ ALIGNTEXT4
+pwLMR:
+wpLMR:
+ MOVS_B
+ MOV_L (CONTENT(mCount), ECX)
+ REP
+ MOVS_L
+ MOV_L (CONTENT(rCount), ECX)
+ REP
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (pwLMR)
+ RET
+/********************************/
+pwPartial:
+ SUB_L (CONTENT(dOffset), EDX)
+ MOV_L (EDX, ECX)
+ MOV_L (width, EBX)
+ SUB_L (ECX, EBX)
+
+ TEST_L (CONST(1), EDI)
+ JZ (pwPartial1)
+ MOVS_B
+ DEC_L (ECX)
+ JZ (pwPartial2)
+pwPartial1:
+ SHR_L (CONST(1), ECX)
+ REP
+ MOVS_W
+pwPartial2:
+ SUB_L (CONST(0x10000), EDI)
+ MOV_B (CONTENT(segment), AL)
+ INC_B (AL)
+ MOV_B (AL, CONTENT(segment))
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+
+ MOV_L (EBX, ECX)
+ SHR_L (CONST(1), ECX)
+ JZ (pwPartial3)
+ REP
+ MOVS_W
+ JNC (pwPartial4)
+pwPartial3:
+ MOVS_B
+pwPartial4:
+ ADD_L (CONTENT(sOffset), ESI)
+ ADD_L (CONTENT(dOffset), EDI)
+ DEC_L (height)
+ JNZ (pwLoop1)
+
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/********************************/
+ ALIGNTEXT4
+sPixWin1:
+sWinPix1:
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (sPixWin1)
+ RET
+/********************************/
+ ALIGNTEXT4
+sPixWin2:
+sWinPix2:
+ MOVS_W
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (sPixWin2)
+ RET
+/********************************/
+ ALIGNTEXT4
+sPixWin3:
+sWinPix3:
+ TEST_L (CONST(1), EDI)
+ JNZ (sPixWin31)
+sPixWin32:
+ MOVS_W
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (sPixWin32)
+ RET
+/********************************/
+ ALIGNTEXT4
+sPixWin31:
+sWinPix31:
+ MOVS_B
+ MOVS_W
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (sPixWin31)
+ RET
+/********************************/
+ ALIGNTEXT4
+sPixWin4:
+sWinPix4:
+ MOVS_L
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (sPixWin4)
+ RET
+/********************************/
+ ALIGNTEXT4
+winPixDone:
+pixWinDone:
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+
+/* void WinPix(src, dst, h, w, srcOffset, dstOffset) */
+ SEG_DATA
+ ALIGNDATA4
+sWinPixTable:
+ D_LONG 0, sWinPix1, sWinPix2, sWinPix3, sWinPix4
+winPixTable:
+ D_LONG wpM, wpMR, wpLM, wpLMR
+/********************************/
+ SEG_TEXT
+ ALIGNTEXT4
+ GLOBL GLNAME(WinPix)
+GLNAME(WinPix):
+ MOV_L (REGOFF(12,ESP), EAX)
+ OR_L (REGOFF(16,ESP), EAX)
+ JZ (return)
+
+ CLD
+ PUSH_L (EBP)
+ MOV_L (ESP, EBP)
+ PUSH_L (EDI)
+ PUSH_L (ESI)
+ PUSH_L (EBX)
+
+ MOV_L (sWidth, EAX)
+ MOV_L (width, ECX)
+ SUB_L (ECX, EAX)
+ MOV_L (EAX, CONTENT(sOffset))
+ ADD_L (CONTENT(GLNAME(vgaWriteTop)), EAX)
+ MOV_L (EAX, CONTENT(speedUpTop))
+
+ MOV_L (dWidth, EAX)
+ SUB_L (ECX, EAX)
+ MOV_L (EAX, CONTENT(dOffset))
+
+ MOV_L (src, ESI)
+ MOV_L (dst, EDI)
+ SUB_L (VGABASE, ESI)
+ CMP_L (CONST(5), ECX)
+ JNC (winPix1)
+ MOV_L (REGDIS(sWinPixTable,ECX,4), EAX)
+ MOV_L (EAX, CONTENT(func))
+ JMP (winPix2)
+/********************************/
+ ALIGNTEXT4
+winPix1:
+ MOV_L (ADDR(winPixTable), EAX)
+ TEST_L (CONST(1), ESI)
+ JZ (winPix3)
+ ADD_L (CONST(8), EAX)
+ DEC_L (ECX)
+winPix3:
+ MOV_L (ECX, EBX)
+ AND_L (CONST(3), EBX)
+ JZ (winPix4)
+ ADD_L (CONST(4), EAX)
+winPix4:
+ MOV_L (REGIND(EAX), EAX)
+ MOV_L (EAX, CONTENT(func))
+ MOV_L (EBX, CONTENT(rCount))
+ SHR_L (CONST(2), ECX)
+ MOV_L (ECX, CONTENT(mCount))
+winPix2:
+ MOV_L (ESI, EAX)
+ SHR_L (CONST(16), EAX)
+ SHL_B (CONST(4), AL)
+ MOV_B (AL, CONTENT(segment))
+
+ AND_L (CONST(0xffff), ESI)
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)), ESI)
+ JMP (wpLoop3)
+/********************************/
+ ALIGNTEXT4
+wpLoop:
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)), ESI)
+ JC (wpLoop1)
+ SUB_L (CONST(0x10000), ESI)
+ MOV_B (CONTENT(segment), AL)
+ ADD_B (CONST(16), AL)
+ MOV_B (AL, CONTENT(segment))
+wpLoop3:
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+wpLoop1:
+ MOV_L (CONTENT(speedUpTop), EAX)
+ SUB_L (ESI, EAX)
+ XOR_L (EDX, EDX)
+ DIV_L (sWidth)
+
+ OR_L (EAX, EAX)
+ JZ (wpPartial)
+
+ MOV_L (height, EBX)
+ CMP_L (EBX, EAX)
+ JC (wpLoop2)
+ MOV_L (EBX, EAX)
+wpLoop2:
+ MOV_L (EAX, CONTENT(allowance))
+ MOV_L (EAX, EDX)
+ MOV_L (CONTENT(sOffset), EAX)
+ MOV_L (CONTENT(dOffset), EBX)
+
+ CALL (VARINDIRECT(func))
+
+ MOV_L (height, EAX)
+ SUB_L (CONTENT(allowance), EAX)
+ MOV_L (EAX, height)
+ JNZ (wpLoop)
+
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/********************************/
+wpPartial:
+ SUB_L (CONTENT(sOffset), EDX)
+ MOV_L (EDX, ECX)
+ MOV_L (width, EBX)
+ SUB_L (ECX, EBX)
+
+ TEST_L (CONST(1), ESI)
+ JZ (wpPartial1)
+ MOVS_B
+ DEC_L (ECX)
+ JZ (wpPartial2)
+wpPartial1:
+ SHR_L (CONST(1), ECX)
+ REP
+ MOVS_W
+wpPartial2:
+ SUB_L (CONST(0x10000), ESI)
+ MOV_B (CONTENT(segment), AL)
+ ADD_B (CONST(16), AL)
+ MOV_B (AL, CONTENT(segment))
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+
+ MOV_L (EBX, ECX)
+ SHR_L (CONST(1), ECX)
+ JZ (wpPartial3)
+ REP
+ MOVS_W
+ JNC (wpPartial4)
+wpPartial3:
+ MOVS_B
+wpPartial4:
+ ADD_L (CONTENT(sOffset), ESI)
+ ADD_L (CONTENT(dOffset), EDI)
+ DEC_L (height)
+ JNZ (wpLoop1)
+
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/********************************/
+ SEG_DATA
+ ALIGNDATA4
+sPixPixTable:
+ D_LONG 0, sPixPix1, sPixPix2, sPixPix3, sPixPix4
+/********************************/
+ SEG_TEXT
+ ALIGNTEXT4
+/* void PixPix(src, dst, h, w, srcOffset, dstOffset, ydir) */
+ GLOBL GLNAME(PixPix)
+GLNAME(PixPix):
+ MOV_L (REGOFF(12,ESP), EAX)
+ OR_L (REGOFF(16,ESP), EAX)
+ JZ (return)
+ PUSH_L (EBP)
+ MOV_L (ESP, EBP)
+ PUSH_L (EDI)
+ PUSH_L (ESI)
+ PUSH_L (EBX)
+ MOV_L (REGOFF(8,EBP), ESI)
+ MOV_L (REGOFF(12,EBP), EDI)
+ CMP_L (ESI, EDI)
+ JZ (pixPixDone)
+ MOV_L (REGOFF(20,EBP), EDX)
+ MOV_L (REGOFF(28,EBP), EBX)
+ CMP_L (CONST(4), EDX)
+ JLE (sPixPix)
+ MOV_L (REGOFF(16,EBP), EAX)
+ MOV_L (EAX, CONTENT(heightCount))
+ CMP_L (CONST(1), REGOFF(32,EBP))
+ JNE (pixPixRL)
+ CLD
+ MOV_L (ESI, EAX)
+ ADD_L (CONST(3), EAX)
+ AND_L (CONST(0xfffffffc), EAX)
+ SUB_L (ESI, EAX)
+ MOV_L (EAX, CONTENT(lCount))
+ SUB_L (EAX, EDX)
+ MOV_L (EDX, EAX)
+ SAR_L (CONST(2), EDX)
+ JZ (pixPixLRLR)
+ AND_L (CONST(3), EAX)
+ JZ (pixPixLRLMorM)
+ MOV_L (EAX, CONTENT(rCount))
+ MOV_L (REGOFF(24,EBP), EAX)
+ CMP_L (CONST(0), CONTENT(lCount))
+ JE (pixPixLRMR)
+/********************************/
+pixPixLRLMR:
+ MOV_L (CONTENT(lCount), ECX)
+ REP
+ MOVS_B
+ MOV_L (EDX, ECX)
+ REP
+ MOVS_L
+ MOV_L (CONTENT(rCount), ECX)
+ REP
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(heightCount))
+ JNZ (pixPixLRLMR)
+pixPixDone:
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/********************************/
+ ALIGNTEXT4
+pixPixLRMR:
+ MOV_L (EDX, ECX)
+ REP
+ MOVS_L
+ MOV_L (CONTENT(rCount), ECX)
+ REP
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(heightCount))
+ JNZ (pixPixLRMR)
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/********************************/
+ ALIGNTEXT4
+pixPixLRLMorM:
+ MOV_L (REGOFF(24,EBP), EAX)
+ CMP_L (CONST(0), CONTENT(lCount))
+ JE (pixPixLRM)
+pixPixLRLM:
+ MOV_L (CONTENT(lCount), ECX)
+ REP
+ MOVS_B
+ MOV_L (EDX, ECX)
+ REP
+ MOVS_L
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(heightCount))
+ JNZ (pixPixLRLM)
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/********************************/
+ ALIGNTEXT4
+pixPixLRM:
+ MOV_L (EDX, ECX)
+ REP
+ MOVS_L
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(heightCount))
+ JNZ (pixPixLRM)
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/********************************/
+ ALIGNTEXT4
+pixPixLRLR:
+ MOV_L (REGOFF(24,EBP), EAX)
+ MOV_L (REGOFF(20,EBP), EDX)
+ SUB_L (CONST(4), EDX)
+pixPixLRLR1:
+ MOVS_L
+ MOV_L (EDX, ECX)
+ REP
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(heightCount))
+ JNZ (pixPixLRLR1)
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/********0************************/
+ ALIGNTEXT4
+pixPixRL:
+ STD
+ MOV_L (ESI, EAX)
+ INC_L (EAX)
+ AND_L (CONST(3), EAX)
+ MOV_L (EAX, CONTENT(rCount))
+ SUB_L (EAX, EDX)
+ MOV_L (EDX, EAX)
+ SAR_L (CONST(2), EDX)
+ JZ (pixPixRLLR)
+ AND_L (CONST(3), EAX)
+ JZ (pixPixRLMRorM)
+ MOV_L (EAX, CONTENT(lCount))
+ MOV_L (REGOFF(24,EBP), EAX)
+ CMP_L (CONST(0), CONTENT(rCount))
+ JE (pixPixRLLM)
+pixPixRLLMR:
+ MOV_L (CONTENT(rCount), ECX)
+ REP
+ MOVS_B
+ SUB_L (CONST(3), ESI)
+ SUB_L (CONST(3), EDI)
+ MOV_L (EDX, ECX)
+ REP
+ MOVS_L
+ ADD_L (CONST(3), ESI)
+ ADD_L (CONST(3), EDI)
+ MOV_L (CONTENT(lCount), ECX)
+ REP
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(heightCount))
+ JNZ (pixPixRLLMR)
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ CLD
+ LEAVE
+ RET
+/********************************/
+ ALIGNTEXT4
+pixPixRLLM:
+ SUB_L (CONST(3), ESI)
+ SUB_L (CONST(3), EDI)
+ SUB_L (CONST(3), EAX)
+ SUB_L (CONST(3), EBX)
+pixPixRLLM1:
+ MOV_L (EDX, ECX)
+ REP
+ MOVS_L
+ MOV_L (CONTENT(lCount), ECX)
+ ADD_L (CONST(3), ESI)
+ ADD_L (CONST(3), EDI)
+ REP
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(heightCount))
+ JNZ (pixPixRLLM1)
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ CLD
+ LEAVE
+ RET
+/********************************/
+ ALIGNTEXT4
+pixPixRLMRorM:
+ MOV_L (REGOFF(24,EBP), EAX)
+ CMP_L (CONST(0), CONTENT(rCount))
+ JE (pixPixRLM)
+ ADD_L (CONST(3), EAX)
+ ADD_L (CONST(3), EBX)
+pixPixRLMR:
+ MOV_L (CONTENT(rCount), ECX)
+ REP
+ MOVS_B
+ SUB_L (CONST(3), ESI)
+ SUB_L (CONST(3), EDI)
+ MOV_L (EDX, ECX)
+ REP
+ MOVS_L
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(heightCount))
+ JNZ (pixPixRLMR)
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ CLD
+ LEAVE
+ RET
+/********************************/
+ ALIGNTEXT4
+pixPixRLM:
+ SUB_L (CONST(3), ESI)
+ SUB_L (CONST(3), EDI)
+pixPixRLM1:
+ MOV_L (EDX, ECX)
+ REP
+ MOVS_L
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(heightCount))
+ JNZ (pixPixRLM1)
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ CLD
+ LEAVE
+ RET
+/********************************/
+ ALIGNTEXT4
+pixPixRLLR:
+ MOV_L (REGOFF(24,EBP), EAX)
+ MOV_L (REGOFF(20,EBP), EDX)
+pixPixRLLR1:
+ MOV_L (EDX, ECX)
+ REP
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(heightCount))
+ JNZ (pixPixRLLR1)
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ CLD
+ LEAVE
+ RET
+/********************************/
+ ALIGNTEXT4
+sPixPix:
+ CLD
+ MOV_L (REGOFF(16,EBP), ECX)
+ MOV_L (REGOFF(24,EBP), EAX)
+ JMP (CODEPTR(REGDIS(sPixPixTable,EDX,4)))
+/********************************/
+ ALIGNTEXT4
+sPixPix4:
+ MOVS_L
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (ECX)
+ JNZ (sPixPix4)
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/********************************/
+ ALIGNTEXT4
+sPixPix3:
+ TEST_L (CONST(1), ESI)
+ JNZ (sPixPix3U)
+ INC_L (EAX)
+ INC_L (EBX)
+sPixPix31:
+ MOV_B (REGOFF(2,ESI), DL)
+ MOVS_W
+ MOV_B (DL, REGIND(EDI))
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (ECX)
+ JNZ (sPixPix31)
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/********************************/
+ ALIGNTEXT4
+sPixPix3U:
+ ADD_L (CONST(2), EAX)
+ ADD_L (CONST(2), EBX)
+sPixPix3U1:
+ MOV_W (REGOFF(1,ESI), DX)
+ MOVS_B
+ MOV_W (DX, REGIND(EDI))
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (ECX)
+ JNZ (sPixPix3U1)
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/********************************/
+ ALIGNTEXT4
+sPixPix2:
+ MOVS_W
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (ECX)
+ JNZ (sPixPix2)
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/********************************/
+ ALIGNTEXT4
+sPixPix1:
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (ECX)
+ JNZ (sPixPix1)
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suBitBlt.s b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suBitBlt.s
new file mode 100644
index 000000000..994fb33d2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suBitBlt.s
@@ -0,0 +1,1572 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suBitBlt.s,v 1.2 1998/07/25 16:58:31 dawes Exp $ */
+/*******************************************************************************
+ Copyr 1992 by Glenn G. Lai
+
+ All Rs 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 copyr notice appear in all copies and that
+both that copyr notice and this permission notice appear in
+supporting documentation, and that the name of Glenn G. Lai not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+Glenn G. Lai DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+Glenn G. Lai
+P.O. Box 4314
+Austin, Tx 78765
+(glenn@cs.utexas.edu)
+8/17/92
+*******************************************************************************/
+/* $XConsortium: suBitBlt.s /main/5 1996/02/21 18:09:09 kaleb $ */
+
+#include "assyntax.h"
+
+ FILE("suBitBlt.s")
+ AS_BEGIN
+
+#include "vgaAsm.h"
+
+/* WinWin(src, dst, h, w, xdir, ydir, screen, special) */
+
+#define src REGOFF(8,EBP)
+#define dst REGOFF(12,EBP)
+#define height REGOFF(16,EBP)
+#define width REGOFF(20,EBP)
+#define xdir REGOFF(24,EBP)
+#define ydir REGOFF(28,EBP)
+#define screen REGOFF(32,EBP)
+#define special REGOFF(36,EBP)
+
+ SEG_DATA
+copyright:
+ STRING("Copyright 8/17/1992 by Glenn G. Lai")
+ ALIGNDATA4
+tmp:
+ D_LONG 0
+speedUpBound:
+ D_LONG 0
+sM:
+ D_LONG 0
+dM:
+ D_LONG 0
+sM1:
+ D_LONG 0
+dM1:
+ D_LONG 0
+func:
+ D_LONG 0
+partial:
+ D_LONG 0
+npPartialJump:
+ D_LONG 0
+pPartialJump:
+ D_LONG 0
+pMOffset:
+ D_LONG 0
+pLROffset:
+ D_LONG 0
+allowance:
+ D_LONG 0
+lCount:
+ D_LONG 0
+mCount:
+ D_LONG 0
+rCount:
+ D_LONG 0
+hCount:
+ D_LONG 0
+offset:
+ D_LONG 0
+wwLRTable:
+ D_LONG wBoxLR, wbBoxLR, bwBoxLR, bBoxLR
+wwRLTable:
+ D_LONG bBoxRL, bwBoxRL, wbBoxRL, wBoxRL
+pTable:
+ D_LONG pM, pMR, pLM, pLMR
+pTable1:
+ D_LONG pM, pMRa, pLMa, pLMRa
+lMaskTable:
+ D_WORD 0x0f02, 0x0802, 0x0c02, 0x0e02
+rMaskTable:
+ D_WORD 0x0f02, 0x0102, 0x0302, 0x0702
+lMask:
+ D_WORD 0
+rMask:
+ D_WORD 0
+segment:
+ D_BYTE 0
+
+ SEG_TEXT
+ ALIGNTEXT4
+ GLOBL GLNAME(WinWin)
+#define THRESHOLD CONST(10)
+GLNAME(WinWin):
+ MOV_L (REGOFF(4,ESP), EAX)
+ CMP_L (REGOFF(8,ESP), EAX)
+ JE (return)
+
+ MOV_L (REGOFF(16,ESP), EAX)
+ OR_L (REGOFF(20,ESP), EAX)
+ JZ (return)
+
+ PUSH_L (EBP)
+ MOV_L (ESP, EBP)
+ PUSH_L (EDI)
+ PUSH_L (ESI)
+ PUSH_L (EBX)
+ CLD
+
+ MOV_L (width, ECX)
+ MOV_L (src, ESI)
+ MOV_L (dst, EDI)
+
+ CMP_L (CONST(1), special)
+ JE (nP)
+
+ MOV_L (ESI, EAX)
+ MOV_L (EDI, EBX)
+ SUB_L (EBX, EAX)
+ AND_L (CONST(3), EAX)
+ JNZ (nP)
+
+ CMP_L (THRESHOLD, ECX)
+ JNC (pMode)
+nP:
+ MOV_L (ESI, EAX)
+ SHR_L (CONST(12), EAX)
+ AND_B (CONST(0x0f0), AL)
+ MOV_L (EDI, EBX)
+ SHR_L (CONST(16), EBX)
+ OR_B (BL, AL)
+ MOV_B (AL, CONTENT(segment))
+
+ AND_L (CONST(0xffff), ESI)
+ AND_L (CONST(0xffff), EDI)
+ ADD_L (CONTENT(GLNAME(vgaReadBottom)), ESI)
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+
+ MOV_L (ADDR(wwLRTable), EAX)
+ CMP_L (CONST(1), special)
+ JNE (wwLeftToRight)
+ STD
+ MOV_L (ADDR(wwRLTable), EAX)
+wwLeftToRight:
+ TEST_L (CONST(1), ESI)
+ JZ (ww3)
+ ADD_L (CONST(8), EAX)
+ww3:
+ TEST_L (CONST(1), EDI)
+ JZ (ww4)
+ ADD_L (CONST(4), EAX)
+ww4:
+ CMP_L (CONST(6), ECX)
+ JNC (ww2)
+
+ MOV_L (ADDR(sWW), CONTENT(func))
+ JMP (ww5)
+ ALIGNTEXT4
+ww2:
+ MOV_L (REGIND(EAX), EAX)
+ MOV_L (EAX, CONTENT(func))
+ww5:
+ CMP_L (CONST(1), special)
+ JNE (npUpOrDown)
+npRL:
+ MOV_L (screen, EAX)
+ NEG_L (EAX)
+ ADD_L (ECX, EAX)
+ MOV_L (EAX, CONTENT(offset))
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)), EAX)
+ DEC_L (EAX)
+ MOV_L (EAX, CONTENT(speedUpBound))
+ MOV_B (CONTENT(segment), AL)
+ JMP (npRL2)
+/***************************/
+ ALIGNTEXT4
+npRL5:
+ MOV_B (CONTENT(segment), AL)
+ CMP_L (CONTENT(GLNAME(vgaReadBottom)), ESI)
+ JNC (npRL1)
+ SUB_B (CONST(16), AL)
+ ADD_L (CONST(0x10000), ESI)
+npRL1:
+ CMP_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+ JNC (npRL7)
+ DEC_B (AL)
+ ADD_L (CONST(0x10000), EDI)
+npRL7:
+ MOV_B (AL, CONTENT(segment))
+npRL2:
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+npRL6:
+ MOV_L (ESI, EAX)
+ MOV_L (EDI, EBX)
+ SUB_L (CONTENT(speedUpBound), EAX)
+ SUB_L (CONTENT(speedUpBound), EBX)
+
+ MOV_L (screen, ECX)
+ XOR_L (EDX, EDX)
+ DIV_L (ECX)
+ XCHG_L (EAX, EBX)
+
+ XOR_L (EDX, EDX)
+ DIV_L (ECX)
+
+ CMP_L (EBX, EAX)
+ JC (npRL3)
+
+ MOV_L (EBX, EAX)
+npRL3:
+ OR_L (EAX, EAX)
+ JZ (npRLPartial)
+
+ MOV_L (height, EBX)
+ CMP_L (EBX, EAX)
+ JC (npRL4)
+
+ MOV_L (EBX, EAX)
+npRL4:
+ SUB_L (EAX, EBX)
+ MOV_L (EBX, height)
+
+ MOV_L (CONTENT(offset), EBX)
+ MOV_L (width, ECX)
+ MOV_L (EAX, EDX)
+ CALL (VARINDIRECT(func))
+
+ CMP_L (CONST(0), height)
+ JNE (npRL5)
+
+ CLD
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+return:
+ RET
+/***************************/
+ ALIGNTEXT4
+npRLPartial:
+ MOV_L (width, EBX)
+ MOV_W (CONST(0x3cd), DX)
+npRLPartial5:
+ MOV_L (ESI, EAX)
+ MOV_L (EDI, ECX)
+ SUB_L (CONTENT(GLNAME(vgaReadBottom)), EAX)
+ SUB_L (CONTENT(GLNAME(vgaWriteBottom)), ECX)
+
+ CMP_L (EAX, ECX)
+ JC (npRLPartial1)
+
+ MOV_L (EAX, ECX)
+npRLPartial1:
+ INC_L (ECX)
+ CMP_L (EBX, ECX)
+ JC (npRLPartial2)
+
+ MOV_L (EBX, ECX)
+npRLPartial2:
+ SUB_L (ECX, EBX)
+
+ REP
+ MOVS_B
+
+ MOV_B (CONTENT(segment), AL)
+ CMP_L (CONTENT(GLNAME(vgaReadBottom)), ESI)
+ JNC (npRLPartial3)
+
+ ADD_L (CONST(0x10000), ESI)
+ SUB_B (CONST(16), AL)
+npRLPartial3:
+ CMP_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+ JNC (npRLPartial4)
+
+ ADD_L (CONST(0x10000), EDI)
+ DEC_B (AL)
+npRLPartial4:
+ MOV_B (AL, CONTENT(segment))
+ OUT_B
+
+ OR_L (EBX, EBX)
+ JNZ (npRLPartial5)
+
+ MOV_L (CONTENT(offset), EAX)
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+
+ DEC_L (height)
+ JNZ (npRL5)
+
+ CLD
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/***************************/
+npUpOrDown:
+ CMP_L (CONST(1), ydir)
+ JE (npDown)
+npUp:
+ MOV_L (screen, EAX)
+ MOV_L (EAX, EBX)
+ NEG_L (EBX)
+ MOV_L (EBX, screen)
+ MOV_L (width, ECX)
+ SUB_L (ECX, EAX)
+ MOV_L (EAX, CONTENT(offset))
+ MOV_L (ADDR(npUp3), CONTENT(npPartialJump))
+ MOV_B (CONTENT(segment), AL)
+ JMP (npUp5)
+/***************************/
+ ALIGNTEXT4
+npUp3:
+ MOV_B (CONTENT(segment), AL)
+ CMP_L (CONTENT(GLNAME(vgaReadBottom)), ESI)
+ JNC (npUp4)
+ SUB_B (CONST(16), AL)
+ ADD_L (CONST(0x10000), ESI)
+npUp4:
+ CMP_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+ JNC (npUp6)
+ DEC_B (AL)
+ ADD_L (CONST(0x10000), EDI)
+npUp6:
+ MOV_B (AL, CONTENT(segment))
+npUp5:
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+
+ MOV_L (width, EBX)
+ MOV_L (CONTENT(GLNAME(vgaReadTop)), EAX)
+ SUB_L (ESI, EAX)
+ CMP_L (EBX, EAX)
+ JC (npPartial)
+
+ MOV_L (CONTENT(GLNAME(vgaWriteTop)), EAX)
+ SUB_L (EDI, EAX)
+ CMP_L (EBX, EAX)
+ JC (npPartial)
+
+ MOV_L (ESI, EAX)
+ MOV_L (EDI, EBX)
+ SUB_L (CONTENT(GLNAME(vgaReadBottom)), EAX)
+ SUB_L (CONTENT(GLNAME(vgaWriteBottom)), EBX)
+
+ MOV_L (screen, ECX)
+ XOR_L (EDX, EDX)
+ DIV_L (ECX)
+ XCHG_L (EAX, EBX)
+
+ XOR_L (EDX, EDX)
+ DIV_L (ECX)
+
+ CMP_L (EBX, EAX)
+ JC (npUp1)
+
+ MOV_L (EBX, EAX)
+npUp1:
+ INC_L (EAX)
+ MOV_L (height, EBX)
+ CMP_L (EBX, EAX)
+ JC (npUp2)
+
+ MOV_L (EBX, EAX)
+npUp2:
+ SUB_L (EAX, EBX)
+ MOV_L (EBX, height)
+
+ MOV_L (CONTENT(offset), EBX)
+ MOV_L (width, ECX)
+ MOV_L (EAX, EDX)
+ CALL (VARINDIRECT(func))
+
+ CMP_L (CONST(0), height)
+ JNE (npUp3)
+
+ CLD
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/***************************/
+ ALIGNTEXT4
+npDown:
+ MOV_L (screen, EAX)
+ SUB_L (width, EAX)
+ MOV_L (EAX, CONTENT(offset))
+ ADD_L (CONTENT(GLNAME(vgaWriteTop)), EAX)
+ MOV_L (EAX, CONTENT(speedUpBound))
+ MOV_L (ADDR(npDown3), CONTENT(npPartialJump))
+ MOV_B (CONTENT(segment), AL)
+ JMP (npDown5)
+/***************************/
+ ALIGNTEXT4
+npDown3:
+ MOV_B (CONTENT(segment), AL)
+ CMP_L (CONTENT(GLNAME(vgaReadTop)), ESI)
+ JC (npDown4)
+ ADD_B (CONST(16), AL)
+ SUB_L (CONST(0x10000), ESI)
+npDown4:
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)), EDI)
+ JC (npDown6)
+ INC_B (AL)
+ SUB_L (CONST(0x10000), EDI)
+npDown6:
+ MOV_B (AL, CONTENT(segment))
+npDown5:
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+
+ MOV_L (CONTENT(speedUpBound), EAX)
+ MOV_L (CONTENT(speedUpBound), EBX)
+ SUB_L (ESI, EAX)
+ SUB_L (EDI, EBX)
+
+ MOV_L (screen, ECX)
+ XOR_L (EDX, EDX)
+ DIV_L (ECX)
+ XCHG_L (EAX, EBX)
+
+ XOR_L (EDX, EDX)
+ DIV_L (ECX)
+
+ CMP_L (EBX, EAX)
+ JC (npDown1)
+
+ MOV_L (EBX, EAX)
+npDown1:
+ OR_L (EAX, EAX)
+ JZ (npPartial)
+
+ MOV_L (height, EBX)
+ CMP_L (EBX, EAX)
+ JC (npDown2)
+
+ MOV_L (EBX, EAX)
+npDown2:
+ SUB_L (EAX, EBX)
+ MOV_L (EBX, height)
+
+ MOV_L (CONTENT(offset), EBX)
+ MOV_L (width, ECX)
+ MOV_L (EAX, EDX)
+ CALL (VARINDIRECT(func))
+
+ CMP_L (CONST(0), height)
+ JNE (npDown3)
+
+ CLD
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/***************************/
+ ALIGNTEXT4
+bBoxLR:
+ DEC_L (ECX)
+ MOV_L (ECX, EAX)
+ SHR_L (CONST(1), EAX)
+ AND_L (CONST(1), ECX)
+ JNZ (bBoxLRR)
+bBoxLR1:
+ MOVS_B
+ MOV_L (EAX, ECX)
+ REP
+ MOVS_W
+ ADD_L (EBX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (bBoxLR1)
+ RET
+/***************************/
+ ALIGNTEXT4
+bBoxLRR:
+ MOVS_B
+ MOV_L (EAX, ECX)
+ REP
+ MOVS_W
+ MOVS_B
+ ADD_L (EBX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (bBoxLRR)
+ RET
+/***************************/
+ ALIGNTEXT4
+wBoxLR:
+ MOV_L (ECX, EAX)
+ SHR_L (CONST(1), EAX)
+ AND_L (CONST(1), ECX)
+ JNZ (wBoxLRR)
+wBoxLR1:
+ MOV_L (EAX, ECX)
+ REP
+ MOVS_W
+ ADD_L (EBX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (wBoxLR1)
+ RET
+/***************************/
+ ALIGNTEXT4
+wBoxLRR:
+ MOV_L (EAX, ECX)
+ REP
+ MOVS_W
+ MOVS_B
+ ADD_L (EBX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (wBoxLRR)
+ RET
+/***************************/
+ ALIGNTEXT4
+bwBoxLR:
+ MOV_L (EDX, CONTENT(hCount))
+ DEC_L (ECX)
+ MOV_L (ECX, EAX)
+ SAR_L (CONST(2), ECX)
+ MOV_L (ECX, CONTENT(mCount))
+ AND_L (CONST(3), EAX)
+ JNZ (bwBoxLRR)
+bwBoxLR1:
+ MOV_B (REGIND(ESI), DL)
+ INC_L (ESI)
+ MOV_L (CONTENT(mCount), ECX)
+bwBoxLR2:
+ LODS_L
+ ROL_L (CONST(8), EAX)
+ XCHG_B (AL, DL)
+ STOS_L
+ DEC_L (ECX)
+ JNZ (bwBoxLR2)
+ MOV_B (DL, REGIND(EDI))
+ INC_L (EDI)
+ ADD_L (EBX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(hCount))
+ JNZ (bwBoxLR1)
+ RET
+/***************************/
+ ALIGNTEXT4
+bwBoxLRR:
+ MOV_L (EAX, CONTENT(rCount))
+bwBoxLRR1:
+ MOV_B (REGIND(ESI), DL)
+ INC_L (ESI)
+ MOV_L (CONTENT(mCount), ECX)
+bwBoxLRR2:
+ LODS_L
+ ROL_L (CONST(8), EAX)
+ XCHG_B (AL, DL)
+ STOS_L
+ DEC_L (ECX)
+ JNZ (bwBoxLRR2)
+ MOV_B (DL, REGIND(EDI))
+ INC_L (EDI)
+ MOV_L (CONTENT(rCount), ECX)
+ REP
+ MOVS_B
+ ADD_L (EBX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(hCount))
+ JNZ (bwBoxLRR1)
+ RET
+/***************************/
+ ALIGNTEXT4
+wbBoxLR:
+ MOV_L (EDX, CONTENT(hCount))
+ SUB_L (CONST(2), ECX)
+ MOV_L (ECX, EAX)
+ SHR_L (CONST(2), ECX)
+ MOV_L (ECX, CONTENT(mCount))
+ AND_L (CONST(3), EAX)
+ JNZ (wbBoxLRR)
+wbBoxLR2:
+ LODS_W
+ STOS_B
+ MOV_B (AH, DL)
+ MOV_L (CONTENT(mCount), ECX)
+wbBoxLR1:
+ LODS_L
+ ROL_L (CONST(8), EAX)
+ XCHG_B (AL, DL)
+ STOS_L
+ DEC_L (ECX)
+ JNZ (wbBoxLR1)
+ MOV_B (DL, REGIND(EDI))
+ INC_L (EDI)
+ ADD_L (EBX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(hCount))
+ JNZ (wbBoxLR2)
+ RET
+/***************************/
+ ALIGNTEXT4
+wbBoxLRR:
+ MOV_L (EAX, CONTENT(rCount))
+wbBoxLRR1:
+ LODS_W
+ STOS_B
+ MOV_B (AH, DL)
+ MOV_L (CONTENT(mCount), ECX)
+wbBoxLRR2:
+ LODS_L
+ ROL_L (CONST(8), EAX)
+ XCHG_B (AL, DL)
+ STOS_L
+ DEC_L (ECX)
+ JNZ (wbBoxLRR2)
+ MOV_B (DL, REGIND(EDI))
+ INC_L (EDI)
+ MOV_L (CONTENT(rCount), ECX)
+ REP
+ MOVS_B
+ ADD_L (EBX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(hCount))
+ JNZ (wbBoxLRR1)
+ RET
+/***************************/
+ ALIGNTEXT4
+bBoxRL:
+ DEC_L (ECX)
+ MOV_L (ECX, EAX)
+ SAR_L (CONST(2), EAX)
+ AND_L (CONST(3), ECX)
+ JNZ (bBoxRLL)
+ ADD_L (CONST(3), EBX)
+bBoxRL1:
+ MOVS_B
+ SUB_L (CONST(3), ESI)
+ SUB_L (CONST(3), EDI)
+ MOV_L (EAX, ECX)
+ REP
+ MOVS_L
+ ADD_L (EBX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (bBoxRL1)
+ RET
+/***************************/
+ ALIGNTEXT4
+bBoxRLL:
+ MOV_L (ECX, CONTENT(lCount))
+bBoxRLL1:
+ MOVS_B
+ SUB_L (CONST(3), ESI)
+ SUB_L (CONST(3), EDI)
+ MOV_L (EAX, ECX)
+ REP
+ MOVS_L
+ ADD_L (CONST(3), ESI)
+ ADD_L (CONST(3), EDI)
+ MOV_L (CONTENT(lCount), ECX)
+ REP
+ MOVS_B
+ ADD_L (EBX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (bBoxRLL1)
+ RET
+/***************************/
+ ALIGNTEXT4
+wBoxRL:
+ MOV_L (ECX, EAX)
+ SAR_L (CONST(2), EAX)
+ AND_L (CONST(3), ECX)
+ JNZ (wBoxRLL)
+ ADD_L (CONST(3), EBX)
+wBoxRL1:
+ SUB_L (CONST(3), ESI)
+ SUB_L (CONST(3), EDI)
+ MOV_L (EAX, ECX)
+ REP
+ MOVS_L
+ ADD_L (EBX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (wBoxRL1)
+ RET
+/***************************/
+ ALIGNTEXT4
+wBoxRLL:
+ MOV_L (ECX, CONTENT(lCount))
+wBoxRLL1:
+ SUB_L (CONST(3), ESI)
+ SUB_L (CONST(3), EDI)
+ MOV_L (EAX, ECX)
+ REP
+ MOVS_L
+ ADD_L (CONST(3), ESI)
+ ADD_L (CONST(3), EDI)
+ MOV_L (CONTENT(lCount), ECX)
+ REP
+ MOVS_B
+ ADD_L (EBX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (wBoxRLL1)
+ RET
+/***************************/
+ ALIGNTEXT4
+bwBoxRL:
+ MOV_L (EDX, CONTENT(hCount))
+ DEC_L (ECX)
+ MOV_L (ECX, EAX)
+ SAR_L (CONST(2), ECX)
+ MOV_L (ECX, CONTENT(mCount))
+ AND_L (CONST(3), EAX)
+ JNZ (bwBoxRLL)
+ ADD_L (CONST(3), EBX)
+bwBoxRL1:
+ MOV_B (REGIND(ESI), DL)
+ SUB_L (CONST(4), ESI)
+ SUB_L (CONST(3), EDI)
+ MOV_L (CONTENT(mCount), ECX)
+bwBoxRL2:
+ LODS_L
+ XCHG_B (AL, DL)
+ ROR_L (CONST(8), EAX)
+ STOS_L
+ DEC_L (ECX)
+ JNZ (bwBoxRL2)
+ MOV_B (DL, REGOFF(3,EDI))
+ DEC_L (EDI)
+ ADD_L (EBX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(hCount))
+ JNZ (bwBoxRL1)
+ RET
+/***************************/
+ ALIGNTEXT4
+bwBoxRLL:
+ MOV_L (EAX, CONTENT(lCount))
+bwBoxRLL1:
+ MOV_B (REGIND(ESI), DL)
+ SUB_L (CONST(4), ESI)
+ SUB_L (CONST(3), EDI)
+ MOV_L (CONTENT(mCount), ECX)
+bwBoxRLL2:
+ LODS_L
+ XCHG_B (AL, DL)
+ ROR_L (CONST(8), EAX)
+ STOS_L
+ DEC_L (ECX)
+ JNZ (bwBoxRLL2)
+ MOV_B (DL, REGOFF(3,EDI))
+ ADD_L (CONST(3), ESI)
+ ADD_L (CONST(2), EDI)
+ MOV_L (CONTENT(lCount), ECX)
+ REP
+ MOVS_B
+ ADD_L (EBX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(hCount))
+ JNZ (bwBoxRLL1)
+ RET
+/***************************/
+ ALIGNTEXT4
+wbBoxRL:
+ MOV_L (EDX, CONTENT(hCount))
+ SUB_L (CONST(2), ECX)
+ MOV_L (ECX, EAX)
+ SAR_L (CONST(2), ECX)
+ MOV_L (ECX, CONTENT(mCount))
+ AND_L (CONST(3), EAX)
+ JNZ (wbBoxRLL)
+ ADD_L (CONST(3), EBX)
+wbBoxRL1:
+ DEC_L (ESI)
+ MOV_W (REGIND(ESI), AX)
+ MOV_B (AH, REGIND(EDI))
+ MOV_B (AL, DL)
+ SUB_L (CONST(4), ESI)
+ SUB_L (CONST(4), EDI)
+ MOV_L (CONTENT(mCount), ECX)
+wbBoxRL2:
+ LODS_L
+ XCHG_B (AL, DL)
+ ROR_L (CONST(8), EAX)
+ STOS_L
+ DEC_L (ECX)
+ JNZ (wbBoxRL2)
+ MOV_B (DL, REGOFF(3,EDI))
+ DEC_L (EDI)
+ ADD_L (EBX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(hCount))
+ JNZ (wbBoxRL1)
+ RET
+/***************************/
+ ALIGNTEXT4
+wbBoxRLL:
+ MOV_L (EAX, CONTENT(lCount))
+wbBoxRLL1:
+ DEC_L (ESI)
+ MOV_W (REGIND(ESI), AX)
+ MOV_B (AH, REGIND(EDI))
+ MOV_B (AL, DL)
+ SUB_L (CONST(4), ESI)
+ SUB_L (CONST(4), EDI)
+ MOV_L (CONTENT(mCount), ECX)
+wbBoxRLL2:
+ LODS_L
+ XCHG_B (AL, DL)
+ ROR_L (CONST(8), EAX)
+ STOS_L
+ DEC_L (ECX)
+ JNZ (wbBoxRLL2)
+ MOV_B (DL, REGOFF(3,EDI))
+ ADD_L (CONST(3), ESI)
+ ADD_L (CONST(2), EDI)
+ MOV_L (CONTENT(lCount), ECX)
+ REP
+ MOVS_B
+ ADD_L (EBX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (CONTENT(hCount))
+ JNZ (wbBoxRLL1)
+ RET
+/***************************/
+ ALIGNTEXT4
+npPartial:
+ MOV_L (width, EBX)
+ MOV_W (CONST(0x3cd), DX)
+npPartial5:
+ MOV_L (CONTENT(GLNAME(vgaReadTop)), EAX)
+ MOV_L (CONTENT(GLNAME(vgaWriteTop)), ECX)
+ SUB_L (ESI, EAX)
+ SUB_L (EDI, ECX)
+
+ CMP_L (EAX, ECX)
+ JC (npPartial1)
+
+ MOV_L (EAX, ECX)
+npPartial1:
+ CMP_L (EBX, ECX)
+ JC (npPartial2)
+
+ MOV_L (EBX, ECX)
+npPartial2:
+ SUB_L (ECX, EBX)
+
+ REP
+ MOVS_B
+
+ MOV_B (CONTENT(segment), AL)
+ CMP_L (CONTENT(GLNAME(vgaReadTop)), ESI)
+ JC (npPartial3)
+
+ SUB_L (CONST(0x10000), ESI)
+ ADD_B (CONST(16), AL)
+npPartial3:
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)), EDI)
+ JC (npPartial4)
+
+ SUB_L (CONST(0x10000), EDI)
+ INC_B (AL)
+npPartial4:
+ MOV_B (AL, CONTENT(segment))
+ OUT_B
+
+ OR_L (EBX, EBX)
+ JNZ (npPartial5)
+
+ MOV_L (CONTENT(offset), EAX)
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+
+ DEC_L (height)
+ JZ (npPartial6)
+ JMP (VARINDIRECT(npPartialJump))
+ ALIGNTEXT4
+npPartial6:
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/***************************/
+ ALIGNTEXT4
+sWW:
+ MOV_L (ECX, EAX)
+sWW1:
+ MOV_L (EAX, ECX)
+ REP
+ MOVS_B
+ ADD_L (EBX, ESI)
+ ADD_L (EBX, EDI)
+ DEC_L (EDX)
+ JNZ (sWW1)
+ RET
+/***************************/
+ ALIGNTEXT4
+pMode:
+ MOV_W (CONST(0x0604), AX)
+ MOV_W (CONST(0x3c4), DX)
+ OUT_W
+ MOV_W (CONST(0x4105), AX)
+ MOV_W (CONST(0x3ce), DX)
+ OUT_W
+
+ MOV_L (ESI, EAX)
+ MOV_L (ADDR(pTable), EBX)
+ MOV_L (width, ECX)
+
+ ADD_L (CONST(3), EAX)
+ AND_L (CONST(0xfffffffc), EAX)
+ SUB_L (ESI, EAX)
+ SUB_L (EAX, ECX)
+
+ XOR_L (EDX, EDX)
+ SAL_L (CONST(1), EAX)
+ JZ (pNoL)
+
+ ADD_L (CONST(8), EBX)
+ INC_L (EDX)
+pNoL:
+ MOV_W (lMaskTable(EAX), AX)
+ MOV_W (AX, CONTENT(lMask))
+
+ MOV_L (ECX, EAX)
+ AND_L (CONST(3), EAX)
+
+ SAL_L (CONST(1), EAX)
+ JZ (pNoR)
+
+ ADD_L (CONST(4), EBX)
+ INC_L (EDX)
+pNoR:
+ CMP_L (CONST(1), xdir)
+ JE (pModeLR)
+ ADD_L (CONST(16), EBX)
+pModeLR:
+ MOV_L (REGIND(EBX), EBX)
+ MOV_L (EBX, CONTENT(func))
+
+ MOV_W (rMaskTable(EAX), AX)
+ MOV_W (AX, CONTENT(rMask))
+
+ SHR_L (CONST(2), ECX)
+ MOV_L (ECX, CONTENT(mCount))
+
+ ADD_L (ECX, EDX)
+ MOV_L (EDX, width)
+
+ MOV_L (ESI, EAX)
+ SHR_L (CONST(14), EAX)
+ AND_B (CONST(0xf0), AL)
+ MOV_L (EDI, EBX)
+ SHR_L (CONST(18), EBX)
+ OR_B (BL, AL)
+ MOV_B (AL, CONTENT(segment))
+
+ SHR_L (CONST(2), ESI)
+ AND_L (CONST(0xffff), ESI)
+ ADD_L (CONTENT(GLNAME(vgaReadBottom)), ESI)
+ SHR_L (CONST(2), EDI)
+ AND_L (CONST(0xffff), EDI)
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+
+ MOV_L (screen, EBX)
+ SAR_L (CONST(2), EBX)
+ MOV_L (EBX, EAX)
+
+ DEC_L (EBX)
+ MOV_L (EBX, CONTENT(pLROffset))
+
+ INC_L (EBX)
+ SUB_L (ECX, EBX)
+ MOV_L (EBX, CONTENT(pMOffset))
+/***************************/
+ CMP_L (CONST(1), ydir)
+ JE (pDown)
+pUp:
+ MOV_L (EAX, EBX)
+ NEG_L (EBX)
+ MOV_L (EBX, screen)
+ SUB_L (width, EAX)
+ MOV_L (EAX, CONTENT(offset))
+ MOV_L (ADDR(pUp3), CONTENT(pPartialJump))
+ MOV_B (CONTENT(segment), AL)
+ JMP (pUp5)
+/***************************/
+ ALIGNTEXT4
+pUp3:
+ MOV_B (CONTENT(segment), AL)
+ CMP_L (CONTENT(GLNAME(vgaReadBottom)), ESI)
+ JNC (pUp4)
+ SUB_B (CONST(16), AL)
+ ADD_L (CONST(0x10000), ESI)
+pUp4:
+ CMP_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+ JNC (pUp6)
+ DEC_B (AL)
+ ADD_L (CONST(0x10000), EDI)
+pUp6:
+ MOV_B (AL, CONTENT(segment))
+pUp5:
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+
+ MOV_L (ESI, CONTENT(sM))
+ MOV_L (EDI, CONTENT(dM))
+
+ MOV_L (width, EBX)
+ MOV_L (CONTENT(GLNAME(vgaReadTop)), EAX)
+ SUB_L (ESI, EAX)
+ CMP_L (EBX, EAX)
+ JC (pPartial)
+
+ MOV_L (CONTENT(GLNAME(vgaWriteTop)), EAX)
+ SUB_L (EDI, EAX)
+ CMP_L (EBX, EAX)
+ JC (pPartial)
+
+ MOV_L (ESI, EAX)
+ MOV_L (EDI, EBX)
+ SUB_L (CONTENT(GLNAME(vgaReadBottom)), EAX)
+ SUB_L (CONTENT(GLNAME(vgaWriteBottom)), EBX)
+
+ MOV_L (screen, ECX)
+ XOR_L (EDX, EDX)
+ DIV_L (ECX)
+ XCHG_L (EAX, EBX)
+
+ XOR_L (EDX, EDX)
+ DIV_L (ECX)
+
+ CMP_L (EBX, EAX)
+ JC (pUp1)
+
+ MOV_L (EBX, EAX)
+pUp1:
+ INC_L (EAX)
+ MOV_L (height, EBX)
+ CMP_L (EBX, EAX)
+ JC (pUp2)
+
+ MOV_L (EBX, EAX)
+pUp2:
+ SUB_L (EAX, EBX)
+ MOV_L (EBX, height)
+
+ MOV_L (EAX, CONTENT(allowance))
+ CALL (VARINDIRECT(func))
+
+ CMP_L (CONST(0), height)
+ JNE (pUp3)
+
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONST(0x0f02), AX)
+ OUT_W
+ MOV_W (CONST(0x0c04), AX)
+ OUT_W
+ MOV_W (CONST(0x4005), AX)
+ MOV_W (CONST(0x3ce), DX)
+ OUT_W
+
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/***************************/
+ ALIGNTEXT4
+pDown:
+ MOV_L (EAX, screen)
+ SUB_L (width, EAX)
+ MOV_L (EAX, CONTENT(offset))
+ ADD_L (CONTENT(GLNAME(vgaWriteTop)), EAX)
+ MOV_L (EAX, CONTENT(speedUpBound))
+ MOV_L (ADDR(pDown3), CONTENT(pPartialJump))
+ MOV_B (CONTENT(segment), AL)
+ JMP (pDown5)
+/***************************/
+ ALIGNTEXT4
+pDown3:
+ MOV_B (CONTENT(segment), AL)
+ CMP_L (CONTENT(GLNAME(vgaReadTop)), ESI)
+ JC (pDown4)
+ ADD_B (CONST(16), AL)
+ SUB_L (CONST(0x10000), ESI)
+pDown4:
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)), EDI)
+ JC (pDown6)
+ INC_B (AL)
+ SUB_L (CONST(0x10000), EDI)
+pDown6:
+ MOV_B (AL, CONTENT(segment))
+pDown5:
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+
+ MOV_L (ESI, CONTENT(sM))
+ MOV_L (EDI, CONTENT(dM))
+
+ MOV_L (CONTENT(speedUpBound), EAX)
+ MOV_L (CONTENT(speedUpBound), EBX)
+ SUB_L (ESI, EAX)
+ SUB_L (EDI, EBX)
+
+ MOV_L (screen, ECX)
+ XOR_L (EDX, EDX)
+ DIV_L (ECX)
+ XCHG_L (EAX, EBX)
+
+ XOR_L (EDX, EDX)
+ DIV_L (ECX)
+
+ CMP_L (EBX, EAX)
+ JC (pDown1)
+
+ MOV_L (EBX, EAX)
+pDown1:
+ OR_L (EAX, EAX)
+ JZ (pPartial)
+
+ MOV_L (height, EBX)
+ CMP_L (EBX, EAX)
+ JC (pDown2)
+
+ MOV_L (EBX, EAX)
+pDown2:
+ SUB_L (EAX, EBX)
+ MOV_L (EBX, height)
+
+ MOV_L (EAX, CONTENT(allowance))
+ CALL (VARINDIRECT(func))
+
+ CMP_L (CONST(0), height)
+ JNE (pDown3)
+
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONST(0x0f02), AX)
+ OUT_W
+ MOV_W (CONST(0x0c04), AX)
+ OUT_W
+ MOV_W (CONST(0x4005), AX)
+ MOV_W (CONST(0x3ce), DX)
+ OUT_W
+
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/************************************/
+ ALIGNTEXT4
+pLMR:
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONTENT(lMask), AX)
+ OUT_W
+
+ MOV_L (CONTENT(pLROffset), EAX)
+ MOV_L (CONTENT(allowance), EDX)
+pLMR1:
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+ DEC_L (EDX)
+ JNZ (pLMR1)
+
+ MOV_L (ESI, CONTENT(sM1))
+ MOV_L (EDI, CONTENT(dM1))
+
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONST(0x0f02), AX)
+ OUT_W
+
+ MOV_L (CONTENT(sM), ESI)
+ MOV_L (CONTENT(dM), EDI)
+ INC_L (ESI)
+ INC_L (EDI)
+
+ MOV_L (CONTENT(pMOffset), EAX)
+ MOV_L (CONTENT(mCount), EBX)
+ MOV_L (CONTENT(allowance), EDX)
+pLMR2:
+ MOV_L (EBX, ECX)
+ REP
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+ DEC_L (EDX)
+ JNZ (pLMR2)
+
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONTENT(rMask), AX)
+ OUT_W
+
+ MOV_L (CONTENT(pLROffset), EAX)
+ MOV_L (CONTENT(allowance), EDX)
+
+ MOV_L (CONTENT(sM), ESI)
+ MOV_L (CONTENT(dM), EDI)
+ MOV_L (CONTENT(mCount), ECX)
+ INC_L (ECX)
+ ADD_L (ECX, ESI)
+ ADD_L (ECX, EDI)
+pLMR3:
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+ DEC_L (EDX)
+ JNZ (pLMR3)
+
+ MOV_L (CONTENT(sM1), ESI)
+ MOV_L (CONTENT(dM1), EDI)
+
+ RET
+/************************************/
+ ALIGNTEXT4
+pLMRa:
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONTENT(rMask), AX)
+ OUT_W
+
+ MOV_L (CONTENT(pLROffset), EAX)
+ MOV_L (CONTENT(allowance), EDX)
+
+ MOV_L (CONTENT(mCount), ECX)
+ INC_L (ECX)
+ ADD_L (ECX, ESI)
+ ADD_L (ECX, EDI)
+pLMRa3:
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+ DEC_L (EDX)
+ JNZ (pLMRa3)
+
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONST(0x0f02), AX)
+ OUT_W
+
+ MOV_L (CONTENT(sM), ESI)
+ MOV_L (CONTENT(dM), EDI)
+ INC_L (ESI)
+ INC_L (EDI)
+
+ MOV_L (CONTENT(pMOffset), EAX)
+ MOV_L (CONTENT(mCount), EBX)
+ MOV_L (CONTENT(allowance), EDX)
+pLMRa2:
+ MOV_L (EBX, ECX)
+ REP
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+ DEC_L (EDX)
+ JNZ (pLMRa2)
+
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONTENT(lMask), AX)
+ OUT_W
+
+ MOV_L (CONTENT(pLROffset), EAX)
+ MOV_L (CONTENT(allowance), EDX)
+
+ MOV_L (CONTENT(sM), ESI)
+ MOV_L (CONTENT(dM), EDI)
+pLMRa1:
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+ DEC_L (EDX)
+ JNZ (pLMRa1)
+
+ RET
+/************************************/
+ ALIGNTEXT4
+pLM:
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONTENT(lMask), AX)
+ OUT_W
+
+ MOV_L (CONTENT(pLROffset), EAX)
+ MOV_L (CONTENT(allowance), EDX)
+pLM1:
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+ DEC_L (EDX)
+ JNZ (pLM1)
+
+ MOV_L (ESI, CONTENT(sM1))
+ MOV_L (EDI, CONTENT(dM1))
+
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONST(0x0f02), AX)
+ OUT_W
+
+ MOV_L (CONTENT(sM), ESI)
+ MOV_L (CONTENT(dM), EDI)
+ INC_L (ESI)
+ INC_L (EDI)
+
+ MOV_L (CONTENT(pMOffset), EAX)
+ MOV_L (CONTENT(mCount), EBX)
+ MOV_L (CONTENT(allowance), EDX)
+pLM2:
+ MOV_L (EBX, ECX)
+ REP
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+ DEC_L (EDX)
+ JNZ (pLM2)
+
+ MOV_L (CONTENT(sM1), ESI)
+ MOV_L (CONTENT(dM1), EDI)
+
+ RET
+/************************************/
+ ALIGNTEXT4
+pLMa:
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONST(0x0f02), AX)
+ OUT_W
+
+ INC_L (ESI)
+ INC_L (EDI)
+
+ MOV_L (CONTENT(pMOffset), EAX)
+ MOV_L (CONTENT(mCount), EBX)
+ MOV_L (CONTENT(allowance), EDX)
+pLMa2:
+ MOV_L (EBX, ECX)
+ REP
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+ DEC_L (EDX)
+ JNZ (pLMa2)
+
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONTENT(lMask), AX)
+ OUT_W
+
+ MOV_L (CONTENT(pLROffset), EAX)
+ MOV_L (CONTENT(allowance), EDX)
+
+ MOV_L (CONTENT(sM), ESI)
+ MOV_L (CONTENT(dM), EDI)
+pLMa1:
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+ DEC_L (EDX)
+ JNZ (pLMa1)
+
+ RET
+/************************************/
+ ALIGNTEXT4
+pMR:
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONST(0x0f02), AX)
+ OUT_W
+
+ MOV_L (CONTENT(pMOffset), EAX)
+ MOV_L (CONTENT(mCount), EBX)
+ MOV_L (CONTENT(allowance), EDX)
+pMR2:
+ MOV_L (EBX, ECX)
+ REP
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+ DEC_L (EDX)
+ JNZ (pMR2)
+
+ MOV_L (ESI, CONTENT(sM1))
+ MOV_L (EDI, CONTENT(dM1))
+
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONTENT(rMask), AX)
+ OUT_W
+
+ MOV_L (CONTENT(pLROffset), EAX)
+ MOV_L (CONTENT(allowance), EDX)
+
+ MOV_L (CONTENT(sM), ESI)
+ MOV_L (CONTENT(dM), EDI)
+ MOV_L (CONTENT(mCount), ECX)
+ ADD_L (ECX, ESI)
+ ADD_L (ECX, EDI)
+pMR3:
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+ DEC_L (EDX)
+ JNZ (pMR3)
+
+ MOV_L (CONTENT(sM1), ESI)
+ MOV_L (CONTENT(dM1), EDI)
+
+ RET
+/************************************/
+ ALIGNTEXT4
+pMRa:
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONTENT(rMask), AX)
+ OUT_W
+
+ MOV_L (CONTENT(pLROffset), EAX)
+ MOV_L (CONTENT(allowance), EDX)
+
+ MOV_L (CONTENT(mCount), ECX)
+ ADD_L (ECX, ESI)
+ ADD_L (ECX, EDI)
+pMRa3:
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+ DEC_L (EDX)
+ JNZ (pMRa3)
+
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONST(0x0f02), AX)
+ OUT_W
+
+ MOV_L (CONTENT(sM), ESI)
+ MOV_L (CONTENT(dM), EDI)
+
+ MOV_L (CONTENT(pMOffset), EAX)
+ MOV_L (CONTENT(mCount), EBX)
+ MOV_L (CONTENT(allowance), EDX)
+pMRa2:
+ MOV_L (EBX, ECX)
+ REP
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+ DEC_L (EDX)
+ JNZ (pMRa2)
+
+ RET
+/************************************/
+ ALIGNTEXT4
+pM:
+ MOV_L (CONTENT(pMOffset), EAX)
+ MOV_L (CONTENT(mCount), EBX)
+ MOV_L (CONTENT(allowance), EDX)
+pM2:
+ MOV_L (EBX, ECX)
+ REP
+ MOVS_B
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+ DEC_L (EDX)
+ JNZ (pM2)
+
+ RET
+/************************************/
+ ALIGNTEXT4
+pPartial:
+ MOV_L (CONTENT(mCount), EBX)
+ MOV_L (CONST(0), CONTENT(tmp))
+
+ MOV_W (CONTENT(lMask), AX)
+ CMP_W (CONST(0x0f02), AX)
+ JE (pPartial7)
+pPartial9:
+ MOV_W (CONST(0x3c4), DX)
+ OUT_W
+ MOVS_B
+
+ MOV_W (CONST(0x0f02), AX)
+ OUT_W
+ JMP (pPartial6)
+ ALIGNTEXT4
+pPartial7:
+ MOV_W (CONST(0x3c4), DX)
+ OUT_W
+pPartial5:
+ MOV_L (CONTENT(GLNAME(vgaReadTop)), EAX)
+ MOV_L (CONTENT(GLNAME(vgaWriteTop)), ECX)
+ SUB_L (ESI, EAX)
+ SUB_L (EDI, ECX)
+
+ CMP_L (EAX, ECX)
+ JC (pPartial1)
+
+ MOV_L (EAX, ECX)
+pPartial1:
+ CMP_L (EBX, ECX)
+ JC (pPartial2)
+
+ MOV_L (EBX, ECX)
+pPartial2:
+ SUB_L (ECX, EBX)
+
+ REP
+ MOVS_B
+pPartial6:
+ MOV_B (CONTENT(segment), AL)
+ CMP_L (CONTENT(GLNAME(vgaReadTop)), ESI)
+ JC (pPartial3)
+
+ SUB_L (CONST(0x10000), ESI)
+ ADD_B (CONST(16), AL)
+pPartial3:
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)), EDI)
+ JC (pPartial4)
+
+ SUB_L (CONST(0x10000), EDI)
+ INC_B (AL)
+pPartial4:
+ MOV_B (AL, CONTENT(segment))
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+
+ OR_L (EBX, EBX)
+ JNZ (pPartial5)
+
+ CMP_L (CONST(1), CONTENT(tmp))
+ JE (pPartial8)
+
+ MOV_L (CONST(1), CONTENT(tmp))
+ MOV_W (CONTENT(rMask), AX)
+ CMP_W (CONST(0x0f02), AX)
+ JNE (pPartial9)
+pPartial8:
+ MOV_L (CONTENT(GLNAME(vgaReadTop)), EAX)
+ MOV_L (CONTENT(offset), EAX)
+ ADD_L (EAX, ESI)
+ ADD_L (EAX, EDI)
+
+ DEC_L (height)
+ JZ (pPartial10)
+ JMP (VARINDIRECT(pPartialJump))
+ ALIGNTEXT4
+pPartial10:
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONST(0x0f02), AX)
+ OUT_W
+ MOV_W (CONST(0x0c04), AX)
+ OUT_W
+ MOV_W (CONST(0x4005), AX)
+ MOV_W (CONST(0x3ce), DX)
+ OUT_W
+
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suBox.s b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suBox.s
new file mode 100644
index 000000000..fca2cf9c8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suBox.s
@@ -0,0 +1,702 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suBox.s,v 1.2 1998/07/25 16:58:31 dawes Exp $ */
+/*******************************************************************************
+ Copyright 1992 by Glenn G. Lai
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Glenn G. Lai not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+Glenn G. Lai DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+Glenn G. Lai
+P.O. Box 4314
+Austin, Tx 78765
+(glenn@cs.utexas.edu)
+7/27/92
+*******************************************************************************/
+/* $XConsortium: suBox.s /main/5 1996/02/21 18:09:14 kaleb $ */
+
+#include "assyntax.h"
+
+ FILE("suBox.s")
+ AS_BEGIN
+
+#include "vgaAsm.h"
+
+/*
+ void SpeedUpBox(dst, fill, h, w, screen)
+*/
+
+#define dst REGOFF(8,EBP)
+#define fill REGOFF(12,EBP)
+#define height REGOFF(16,EBP)
+#define width REGOFF(20,EBP)
+#define screen REGOFF(24,EBP)
+
+ SEG_DATA
+copyright:
+ STRING("Copyright 7/27/1992 by Glenn G. Lai")
+ ALIGNDATA4
+pixTable:
+ D_LONG pix0D, pix1D, pix2D, pix3D
+pixMiddle:
+ D_LONG 0
+/****************************************/
+ SEG_TEXT
+ ALIGNTEXT4
+ GLOBL GLNAME(SpeedUpBox)
+GLNAME(SpeedUpBox):
+ MOV_L (REGOFF(12,ESP), EAX)
+ MOV_L (REGOFF(16,ESP), ECX)
+ MOV_L (EAX, EDX)
+ OR_L (ECX, EDX)
+ JZ (return)
+
+ CMP_L (CONST(1), EAX)
+ JNE (notHLine)
+
+ MOV_L (ECX, REGOFF(12,ESP))
+ MOV_L (REGOFF(20,ESP), EAX)
+ MOV_L (EAX, REGOFF(16,ESP))
+ JMP (GLNAME(SpeedUpHLine1))
+ ALIGNTEXT4
+notHLine:
+ CMP_L (CONST(1), ECX)
+ JNE (notVHLine)
+
+ MOV_L (EAX, REGOFF(12,ESP))
+ MOV_L (EAX, ECX)
+ MOV_L (REGOFF(20,ESP), EAX)
+ MOV_L (EAX, REGOFF(16,ESP))
+ JMP (GLNAME(SpeedUpVLine1))
+/****************************************/
+ ALIGNTEXT4
+notVHLine:
+ MOV_L (REGOFF(4,ESP), EAX)
+ CMP_L (VGABASE, EAX)
+ JNC (window)
+
+ PUSH_L (EBP)
+ MOV_L (ESP, EBP)
+ PUSH_L (EDI)
+ PUSH_L (ESI)
+ PUSH_L (EBX)
+pix:
+ MOV_L (fill, EBX)
+ MOV_L (width, ECX)
+ MOV_L (height, EDX)
+ MOV_L (screen, ESI)
+ MOV_L (EAX, EDI)
+
+ ADD_L (CONST(3), EAX)
+ AND_L (CONST(0xfffffffc), EAX)
+ MOV_L (EAX, CONTENT(pixMiddle))
+
+ SUB_L (EDI, EAX)
+ CMP_L (EAX, ECX)
+ JNC (fillLeft)
+ MOV_L (ECX, EAX)
+fillLeft:
+ SUB_L (EAX, ECX)
+ CALL (CODEPTR(REGDIS(pixTable,EAX,4)))
+fillRight:
+ MOV_L (ECX, EAX)
+ AND_L (CONST(3), EAX)
+ JZ (fillMiddle)
+
+ MOV_L (ECX, EDI)
+ AND_L (CONST(0xfffffffc), EDI)
+ ADD_L (CONTENT(pixMiddle), EDI)
+ CALL (CODEPTR(REGDIS(pixTable,EAX,4)))
+fillMiddle:
+ SAR_L (CONST(2), ECX)
+ JZ (done)
+ MOV_L (ECX, CONTENT(tmp))
+ MOV_L (EBX, EAX)
+ MOV_L (CONTENT(pixMiddle), EBX)
+fillMiddle1:
+ MOV_L (CONTENT(tmp), ECX)
+ MOV_L (EBX, EDI)
+ REP
+ STOS_L
+ ADD_L (ESI, EBX)
+ DEC_L (EDX)
+ JNZ (fillMiddle1)
+ JMP (done)
+/****************/
+ ALIGNTEXT4
+pix0D:
+ RET
+/****************/
+ ALIGNTEXT4
+pix1D:
+ MOV_L (EDX, EAX)
+p1D:
+ MOV_B (BL, REGIND(EDI))
+ ADD_L (ESI, EDI)
+ DEC_L (EAX)
+ JNZ (p1D)
+ RET
+/****************/
+ ALIGNTEXT4
+pix2D:
+ MOV_L (EDX, EAX)
+p2D:
+ MOV_W (BX, REGIND(EDI))
+ ADD_L (ESI, EDI)
+ DEC_L (EAX)
+ JNZ (p2D)
+ RET
+/****************/
+ ALIGNTEXT4
+pix3D:
+ MOV_L (EDX, EAX)
+p3D:
+ MOV_B (BL, REGIND(EDI))
+ MOV_W (BX, REGOFF(1,EDI))
+ ADD_L (ESI, EDI)
+ DEC_L (EAX)
+ JNZ (p3D)
+ RET
+/****************************************/
+ SEG_DATA
+ ALIGNDATA4
+npTable:
+ D_LONG npM, npMR, npLM, npLMR
+/****************************************/
+ SEG_TEXT
+ ALIGNTEXT4
+window:
+ SUB_L (VGABASE, EAX)
+ PUSH_L (EBP)
+ MOV_L (ESP,EBP)
+ PUSH_L (EDI)
+ MOV_L (EAX, EDI)
+ PUSH_L (ESI)
+ PUSH_L (EBX)
+
+/* Change THRESHOLD at your own risk!!! */
+#define THRESHOLD CONST(22)
+ CMP_L (THRESHOLD, ECX)
+ JGE (pMode)
+
+ MOV_L (screen, EAX)
+ SUB_L (ECX, EAX)
+ MOV_L (EAX, CONTENT(offset))
+ ADD_L (CONTENT(GLNAME(vgaWriteTop)), EAX)
+ MOV_L (EAX, CONTENT(speedUpTop))
+
+ MOV_L (ADDR(npTable), EAX)
+ TEST_L (CONST(1), EDI)
+ JZ (window1)
+ ADD_L (CONST(8), EAX)
+ DEC_L (ECX)
+window1:
+ SHR_L (CONST(1), ECX)
+ JZ (window2)
+ JNC (window3)
+ ADD_L (CONST(4), EAX)
+ JMP (window3)
+window2:
+ MOV_L (ADDR(npTable), EAX)
+ MOV_L (CONST(1), ECX)
+window3:
+ MOV_L (REGIND(EAX), EAX)
+ MOV_L (EAX, CONTENT(func))
+ MOV_L (ECX, CONTENT(mCount))
+
+ MOV_L (EDI, EAX)
+ SHR_L (CONST(16), EAX)
+ MOV_B (AL, CONTENT(segment))
+
+ AND_L (CONST(0xffff), EDI)
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+ JMP (npLoop3)
+ ALIGNTEXT4
+npLoop:
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)), EDI)
+ JC (npLoop1)
+ SUB_L (CONST(0x10000), EDI)
+ MOV_B (CONTENT(segment), AL)
+ INC_B (AL)
+ MOV_B (AL, CONTENT(segment))
+npLoop3:
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+npLoop1:
+ MOV_L (CONTENT(speedUpTop), EAX)
+ SUB_L (EDI, EAX)
+ XOR_L (EDX, EDX )
+ DIV_L (screen)
+
+ OR_L (EAX, EAX)
+ JZ (npPartial)
+
+ MOV_L (height, EBX)
+ CMP_L (EBX, EAX)
+ JC (npLoop2)
+ MOV_L (EBX, EAX)
+npLoop2:
+ SUB_L (EAX, EBX)
+ MOV_L (EBX, height)
+ MOV_L (EAX, EDX)
+
+ MOV_L (fill, EAX)
+ MOV_L (CONTENT(mCount), EBX)
+ MOV_L (CONTENT(offset), ESI)
+
+ CALL (VARINDIRECT(func))
+
+ CMP_L (CONST(0), height)
+ JNZ (npLoop)
+
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/****************************************/
+ ALIGNTEXT4
+npM:
+ MOV_L (EBX, ECX)
+ REP
+ STOS_W
+ ADD_L (ESI, EDI)
+ DEC_L (EDX)
+ JNZ (npM)
+ RET
+/****************************************/
+ ALIGNTEXT4
+npMR:
+ MOV_L (EBX, ECX)
+ REP
+ STOS_W
+ STOS_B
+ ADD_L (ESI, EDI)
+ DEC_L (EDX)
+ JNZ (npMR)
+ RET
+/****************************************/
+ ALIGNTEXT4
+npLM:
+ MOV_L (EBX, ECX)
+ STOS_B
+ REP
+ STOS_W
+ ADD_L (ESI, EDI)
+ DEC_L (EDX)
+ JNZ (npLM)
+ RET
+/****************************************/
+ ALIGNTEXT4
+npLMR:
+ MOV_L (EBX, ECX)
+ STOS_B
+ REP
+ STOS_W
+ STOS_B
+ ADD_L (ESI, EDI)
+ DEC_L (EDX)
+ JNZ (npLMR)
+ RET
+/****************************************/
+ ALIGNTEXT4
+npPartial:
+ SUB_L (CONTENT(offset), EDX)
+
+ MOV_L (fill, EAX)
+ MOV_L (width, EBX)
+ MOV_L (EDX, ECX)
+ SUB_L (ECX, EBX)
+
+ TEST_L (CONST(1), EDI)
+ JZ (npPartial1)
+ STOS_B
+ DEC_L (ECX)
+ JZ (npPartial2)
+npPartial1:
+ SHR_L (CONST(1), ECX)
+ REP
+ STOS_W
+npPartial2:
+ SUB_L (CONST(0x10000), EDI)
+ MOV_B (CONTENT(segment), AL)
+ INC_B (AL)
+ MOV_B (AL, CONTENT(segment))
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+
+ MOV_L (fill, EAX)
+ MOV_L (EBX, ECX)
+ SHR_L (CONST(1), ECX)
+ JZ (npPartial3)
+ REP
+ STOS_W
+ JNC (npPartial4)
+npPartial3:
+ STOS_B
+npPartial4:
+ ADD_L (CONTENT(offset), EDI)
+ DEC_L (height)
+ JNZ (npLoop1)
+
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/****************************************/
+ SEG_DATA
+ ALIGNDATA4
+lCount:
+ D_LONG 0
+mCount:
+ D_LONG 0
+rCount:
+ D_LONG 0
+offset:
+ D_LONG 0
+allowance:
+ D_LONG 0
+func:
+ D_LONG 0
+speedUpTop:
+ D_LONG 0
+tmp:
+ D_LONG 0
+pCorrect:
+ D_LONG 0
+pTable:
+ D_LONG pM, pMR, pLM, pLMR
+lMaskTable:
+ D_WORD 0x0f02, 0x0802, 0x0c02, 0x0e02
+rMaskTable:
+ D_WORD 0x0f02, 0x0102, 0x0302, 0x0702
+lMask:
+ D_WORD 0
+rMask:
+ D_WORD 0
+segment:
+ D_BYTE 0
+/****************************************/
+ SEG_TEXT
+ ALIGNTEXT4
+pMode:
+ MOV_L (EDI, ESI)
+ ADD_L (CONST(3), ESI)
+ AND_L (CONST(0xfffffffc), ESI)
+ SUB_L (EDI, ESI)
+
+ SUB_L (ESI, ECX)
+ MOV_L (ECX, EAX)
+ AND_L (CONST(3), EAX)
+
+ MOV_L (CONST(0), CONTENT(tmp))
+ MOV_L (ADDR(pTable), EBX)
+ XOR_L (EDX, EDX)
+ SAL_L (CONST(1), ESI)
+ JZ (pNoL)
+
+ ADD_L (CONST(8), EBX)
+ MOV_L (CONST(1), EDX)
+ MOV_L (CONST(1), CONTENT(tmp))
+pNoL:
+ MOV_L (EDX, CONTENT(pCorrect))
+ MOV_W (lMaskTable(ESI), DX)
+ MOV_W (DX, CONTENT(lMask))
+
+ SAR_L (CONST(2), ECX)
+ MOV_L (ECX, CONTENT(mCount))
+
+ SAL_L (CONST(1), EAX)
+ JZ (pNoR)
+ ADD_L (CONST(4), EBX)
+ INC_L (CONTENT(tmp))
+pNoR:
+ MOV_L (REGIND(EBX), EBX)
+ MOV_L (EBX, CONTENT(func))
+ MOV_W (rMaskTable(EAX), DX)
+ MOV_W (DX, CONTENT(rMask))
+
+ MOV_L (screen, EAX)
+ SAR_L (CONST(2), EAX)
+ MOV_L (EAX, screen)
+ SUB_L (ECX, EAX)
+ MOV_L (EAX, CONTENT(offset))
+ SUB_L (CONTENT(tmp), EAX)
+ ADD_L (CONTENT(GLNAME(vgaWriteTop)), EAX)
+ MOV_L (EAX, CONTENT(speedUpTop))
+/***************************/
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONST(0x0604), AX )
+ OUT_W
+ MOV_W (CONST(0x3ce), DX)
+ MOV_W (CONST(0x0001), AX)
+ OUT_W
+ MOV_W (CONST(0x0003), AX)
+ OUT_W
+ MOV_W (CONST(0x4005), AX)
+ OUT_W
+ MOV_W (CONST(0xff08), AX)
+ OUT_W
+/***************************/
+ MOV_L (EDI, EAX)
+ SHR_L (CONST(18), EAX)
+ MOV_B (AL, CONTENT(segment))
+
+ AND_L (CONST(0x3ffff), EDI)
+ SAR_L (CONST(2), EDI)
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+ JMP (pLoop3)
+/***************************/
+ ALIGNTEXT4
+pLoop:
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)), EDI)
+ JC (pLoop1)
+ SUB_L (CONST(0x10000), EDI)
+ MOV_B (CONTENT(segment), AL)
+ INC_B (AL)
+ MOV_B (AL, CONTENT(segment))
+pLoop3:
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+pLoop1:
+ MOV_L (CONTENT(speedUpTop), EAX)
+ SUB_L (EDI, EAX)
+ XOR_L (EDX, EDX)
+ DIV_L (screen)
+
+ OR_L (EAX, EAX)
+ JZ (pPartial)
+
+ MOV_L (height, EBX)
+ CMP_L (EBX, EAX)
+ JC (pLoop2)
+ MOV_L (EBX, EAX)
+pLoop2:
+ MOV_L (EAX, CONTENT(allowance))
+ MOV_L (CONTENT(mCount), EBX)
+ MOV_L (CONTENT(offset), ESI)
+
+ CALL (VARINDIRECT(func))
+
+ SUB_L (CONTENT(pCorrect), EDI)
+pLoop4:
+ MOV_L (height, EBX)
+ SUB_L (CONTENT(allowance), EBX)
+ MOV_L (EBX, height)
+ JNZ (pLoop)
+
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONST(0x0f02), AX)
+ OUT_W
+ MOV_W (CONST(0x0c04), AX)
+ OUT_W
+
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/****************************************/
+ ALIGNTEXT4
+pPartial:
+ MOV_L (CONTENT(GLNAME(vgaWriteTop)), ECX)
+ SUB_L (EDI, ECX)
+
+ MOV_W (CONTENT(lMask), AX)
+ MOV_W (CONST(0x3c4), DX)
+ OUT_W
+
+ MOV_L (fill, EAX)
+ MOV_L (CONTENT(mCount), EBX)
+
+ CMP_L (CONST(0), CONTENT(pCorrect))
+ JE (pPartial1)
+
+ STOS_B
+ DEC_L (ECX)
+ MOV_W (CONST(0x0f02), AX)
+ OUT_W
+ MOV_L (fill, EAX)
+pPartial1:
+ SUB_L (ECX, EBX)
+ OR_L (ECX, ECX)
+ JZ (pPartial2)
+ SHR_L (CONST(1), ECX)
+ JNC (pPartial3)
+ STOS_B
+ JZ (pPartial2)
+pPartial3:
+ REP
+ STOS_W
+pPartial2:
+ SUB_L (CONST(0x10000), EDI)
+ MOV_B (CONTENT(segment), AL)
+ INC_B (AL)
+ MOV_B (AL, CONTENT(segment))
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+
+ MOV_L (fill, EAX)
+ MOV_L (EBX, ECX)
+ OR_L (ECX, ECX)
+ JZ (pPartial4)
+
+ SHR_L (CONST(1), ECX)
+ JZ (pPartial6)
+ REP
+ STOS_W
+ JNC (pPartial4)
+pPartial6:
+ STOS_B
+pPartial4:
+ MOV_W (CONTENT(rMask), AX)
+ CMP_W (CONST(0x0f02), AX)
+ JE (pPartial5)
+ MOV_W (CONST(0x3c4), DX)
+ OUT_W
+ MOV_L (fill, EAX)
+ MOV_B (AL, REGIND(EDI))
+pPartial5:
+ ADD_L (CONTENT(offset), EDI)
+ SUB_L (CONTENT(pCorrect), EDI)
+ DEC_L (height)
+ JNZ (pLoop1)
+
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONST(0x0f02), AX)
+ OUT_W
+ MOV_W (CONST(0x0c04), AX)
+ OUT_W
+done:
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+return:
+ RET
+/****************************/
+ ALIGNTEXT4
+pMR:
+ MOV_W (CONTENT(rMask), AX)
+ MOV_W (CONST(0x3c4), DX)
+ OUT_W
+
+ MOV_L (fill, EAX)
+ MOV_L (CONTENT(allowance), EBX)
+ MOV_L (EDI, EDX)
+ ADD_L (CONTENT(mCount), EDX)
+ MOV_L (screen, ESI)
+pMR1:
+ MOV_B (AL, REGIND(EDX))
+ ADD_L (ESI, EDX)
+ DEC_L (EBX)
+ JNZ (pMR1)
+ JMP (pM)
+/****************************/
+ ALIGNTEXT4
+pLMR:
+ MOV_W (CONTENT(rMask), AX)
+ MOV_W (CONST(0x3c4), DX)
+ OUT_W
+
+ MOV_L (fill, EAX)
+ MOV_L (CONTENT(allowance), EBX)
+ LEA_L (REGOFF(1,EDI), EDX)
+ ADD_L (CONTENT(mCount), EDX)
+ MOV_L (screen, ESI)
+pLMR1:
+ MOV_B (AL, REGIND(EDX))
+ ADD_L (ESI, EDX)
+ DEC_L (EBX)
+ JNZ (pLMR1)
+/****************************/
+pLM:
+ MOV_W (CONTENT(lMask), AX)
+ MOV_W (CONST(0x3c4), DX)
+ OUT_W
+
+ MOV_L (fill, EAX)
+ MOV_L (CONTENT(allowance), EBX)
+ MOV_L (EDI, EDX)
+ MOV_L (screen, ESI)
+pLM1:
+ MOV_B (AL, REGIND(EDX))
+ ADD_L (ESI, EDX)
+ DEC_L (EBX)
+ JNZ (pLM1)
+
+ INC_L (EDI)
+/****************************/
+pM:
+ MOV_W (CONST(0x0f02), AX)
+ MOV_W (CONST(0x3c4), DX)
+ OUT_W
+
+ MOV_L (fill, EAX)
+ MOV_L (CONTENT(mCount), EBX)
+ MOV_L (CONTENT(allowance), EDX)
+ MOV_L (CONTENT(offset), ESI)
+ TEST_L (CONST(1), EDI)
+ JNZ (pM1)
+ SHR_L (CONST(1), EBX)
+ JC (pM2)
+pM3:
+ MOV_L (EBX, ECX)
+ REP
+ STOS_W
+ ADD_L (ESI, EDI)
+ DEC_L (EDX)
+ JNZ (pM3)
+ RET
+/****************************/
+ ALIGNTEXT4
+pM2:
+ MOV_L (EBX, ECX)
+ REP
+ STOS_W
+ STOS_B
+ ADD_L (ESI, EDI)
+ DEC_L (EDX)
+ JNZ (pM2)
+ RET
+/****************************/
+ ALIGNTEXT4
+pM1:
+ DEC_L (EBX)
+ SHR_L (CONST(1), EBX)
+ JC (pM4)
+pM5:
+ STOS_B
+ MOV_L (EBX, ECX)
+ REP
+ STOS_W
+ ADD_L (ESI, EDI)
+ DEC_L (EDX)
+ JNZ (pM5)
+ RET
+/****************************/
+ ALIGNTEXT4
+pM4:
+ STOS_B
+ MOV_L (EBX, ECX)
+ REP
+ STOS_W
+ STOS_B
+ ADD_L (ESI, EDI)
+ DEC_L (EDX)
+ JNZ (pM4)
+ RET
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suLine.s b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suLine.s
new file mode 100644
index 000000000..5eab360c6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suLine.s
@@ -0,0 +1,762 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suLine.s,v 1.2 1998/07/25 16:58:31 dawes Exp $ */
+/*******************************************************************************
+ Copyright 1992, 1993 by Glenn G. Lai
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Glenn G. Lai not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+Glenn G. Lai DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+Glenn G. Lai
+P.O. Box 4314
+Austin, Tx 78765
+(glenn@cs.utexas.edu)
+8/18/92
+7/8/93
+*******************************************************************************/
+/* $XConsortium: suLine.s /main/5 1996/02/21 18:09:18 kaleb $ */
+
+#include "assyntax.h"
+
+ FILE("suLine.s")
+ AS_BEGIN
+
+#include "vgaAsm.h"
+
+/* SpeedUpBresS(rop, and, xor, addrl, nlwidth, signdx, signdy, axis,
+ x1, y1, e, e1, e2, len);
+*/
+
+#define rop REGOFF(8,EBP)
+#define AND REGOFF(12,EBP)
+#define XOR REGOFF(16,EBP)
+#define addrl REGOFF(20,EBP)
+#define nlwidth REGOFF(24,EBP)
+#define signdx REGOFF(28,EBP)
+#define signdy REGOFF(32,EBP)
+#define axis REGOFF(36,EBP)
+#define x1 REGOFF(40,EBP)
+#define y1 REGOFF(44,EBP)
+#define e REGOFF(48,EBP)
+#define e1 REGOFF(52,EBP)
+#define e2 REGOFF(56,EBP)
+#define len REGOFF(60,EBP)
+#define GXcopy CONST(3)
+#define Y_AXIS CONST(1)
+
+ SEG_DATA
+copyright:
+ STRING("Copyright 1992, 7/8/1993 by Glenn G. Lai" )
+
+ ALIGNDATA4
+speedUpBound1:
+ D_LONG 0
+speedUpBound2:
+ D_LONG 0
+jump:
+ D_LONG 0
+e3:
+ D_LONG 0
+allowance:
+ D_LONG 0
+tmp:
+ D_LONG 0
+tmp1:
+ D_LONG 0
+carefulJump:
+ D_LONG 0
+divisor:
+ D_LONG 0
+segment:
+ D_BYTE 0
+/****************************/
+ SEG_TEXT
+ ALIGNTEXT4
+ GLOBL GLNAME(SpeedUpBresS)
+GLNAME(SpeedUpBresS):
+ CMP_L (CONST(0), REGOFF(56,ESP))
+ JZ (return)
+
+ PUSH_L (EBP)
+ MOV_L (ESP, EBP)
+ PUSH_L (EDI)
+ PUSH_L (ESI)
+ PUSH_L (EBX)
+
+ MOV_L (e2, EAX)
+ SUB_L (e1, EAX)
+ MOV_L (EAX, CONTENT(e3))
+
+ MOV_L (nlwidth, EAX)
+ SHL_L (CONST(2), EAX)
+ MOV_L (EAX, nlwidth)
+ MOV_L (EAX, CONTENT(divisor))
+
+ IMUL_L (y1, EAX)
+ ADD_L (addrl, EAX)
+ ADD_L (x1, EAX)
+ MOV_L (EAX, EDI)
+
+ MOV_L (nlwidth, EAX)
+ MOV_L (EAX, EBX)
+
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)), EAX)
+ MOV_L (EAX, CONTENT(speedUpBound2))
+
+ NEG_L (EBX)
+ MOV_L (EBX, EAX)
+ ADD_L (CONTENT(GLNAME(vgaWriteTop)), EBX)
+ INC_L (EBX)
+ MOV_L (EBX, CONTENT(speedUpBound1))
+
+ CMP_L (CONST(0), signdy)
+ JGE (goingDown)
+
+ MOV_L (EAX, nlwidth)
+goingDown:
+ MOV_L (e, EAX)
+ SUB_L (e1, EAX)
+ MOV_L (EAX, e)
+
+ SUB_L (VGABASE, EDI)
+ JC (pixmap)
+/****************************/
+window:
+ MOV_L (EDI, EAX)
+ SHR_L (CONST(16), EAX)
+ MOV_B (AL, AH)
+ SHL_B (CONST(4), AH)
+ OR_B (AH, AL)
+ MOV_B (AL, CONTENT(segment))
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+
+ AND_L (CONST(0xffff), EDI)
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+
+ MOV_L (e, EBX)
+ MOV_L (ADDR(downLoop2), CONTENT(carefulJump))
+
+ CMP_L (CONST(1), signdy)
+ JE (downLoop0)
+
+ MOV_L (ADDR(upLoop2), CONTENT(carefulJump))
+ JMP (upLoop0)
+/****************************/
+ ALIGNTEXT4
+upLoop:
+ CMP_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+ JNC (upLoop0)
+
+ MOV_L (ADDR(upLoop0), CONTENT(jump))
+ JMP (prev)
+ ALIGNTEXT4
+upLoop0:
+ CMP_L (CONTENT(speedUpBound1), EDI)
+ JNC (careful)
+upLoop2:
+ MOV_L (EDI, EAX)
+ INC_L (EAX)
+ SUB_L (CONTENT(GLNAME(vgaWriteBottom)), EAX)
+ XOR_L (EDX, EDX)
+ DIV_L (CONTENT(divisor))
+
+ CMP_L (EDX, EAX)
+ JNC (upLoop3)
+ INC_L (EAX)
+upLoop3:
+ MOV_L (len, ECX)
+ CMP_L (ECX, EAX)
+ JC (upLoop1)
+
+ MOV_L (ECX, EAX)
+upLoop1:
+ SUB_L (EAX, ECX)
+ MOV_L (ECX, len)
+
+ CALL (line)
+
+ CMP_L (CONST(0), len)
+ JNZ (upLoop)
+done:
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+return:
+ RET
+/****************************/
+ ALIGNTEXT4
+downLoop:
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)), EDI)
+ JC (downLoop0)
+
+ MOV_L (ADDR(downLoop0), CONTENT(jump))
+ JMP (next)
+ ALIGNTEXT4
+downLoop0:
+ CMP_L (CONTENT(speedUpBound2), EDI)
+ JC (careful)
+downLoop2:
+ MOV_L (CONTENT(GLNAME(vgaWriteTop)), EAX)
+ SUB_L (EDI, EAX)
+ XOR_L (EDX, EDX)
+ DIV_L (CONTENT(divisor))
+
+ CMP_L (EDX, EAX)
+ JNC (downLoop3)
+ INC_L (EAX)
+downLoop3:
+ MOV_L (len, ECX)
+ CMP_L (ECX, EAX)
+ JC (downLoop1)
+
+ MOV_L (ECX, EAX)
+downLoop1:
+ SUB_L (EAX, ECX)
+ MOV_L (ECX, len)
+
+ CALL (line)
+
+ CMP_L (CONST(0), len)
+ JNZ (downLoop)
+
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+ RET
+/****************************/
+ ALIGNTEXT4
+line:
+ MOV_L (e1, ECX)
+ MOV_L (nlwidth, ESI)
+
+ CMP_L (GXcopy, rop)
+ JNE (wMix)
+/****************************/
+ MOV_L (EAX, EDX)
+ MOV_L (XOR, EAX)
+ CMP_L (Y_AXIS, axis)
+ JE (setY)
+/****************************/
+setX:
+ CMP_L (CONST(1), signdx)
+ JNE (setXLeft)
+ JMP (setXRight)
+/****************************/
+ ALIGNTEXT4
+setXRight:
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (ECX, EBX)
+ JL (setXRight1)
+
+ ADD_L (ESI, EDI)
+ ADD_L (CONTENT(e3), EBX)
+setXRight1:
+ INC_L (EDI)
+ DEC_L (EDX)
+ JNZ (setXRight)
+ RET
+/****************************/
+ ALIGNTEXT4
+setXLeft:
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (ECX, EBX)
+ JL (setXLeft1)
+
+ ADD_L (ESI, EDI)
+ ADD_L (CONTENT(e3), EBX)
+setXLeft1:
+ DEC_L (EDI)
+ DEC_L (EDX)
+ JNZ (setXLeft)
+ RET
+/****************************/
+ ALIGNTEXT4
+setY:
+ CMP_L (CONST(1), signdx)
+ JNE (setYLeft)
+ JMP (setYRight)
+/****************************/
+ ALIGNTEXT4
+setYRight:
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (ECX, EBX)
+ JL (setYRight1)
+
+ INC_L (EDI)
+ ADD_L (CONTENT(e3), EBX)
+setYRight1:
+ ADD_L (ESI, EDI)
+ DEC_L (EDX)
+ JNZ (setYRight)
+ RET
+/****************************/
+ ALIGNTEXT4
+setYLeft:
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (ECX, EBX)
+ JL (setYLeft1)
+
+ DEC_L (EDI)
+ ADD_L (CONTENT(e3), EBX)
+setYLeft1:
+ ADD_L (ESI, EDI)
+ DEC_L (EDX)
+ JNZ (setYLeft)
+ RET
+/****************************/
+ ALIGNTEXT4
+wMix:
+ MOV_L (EAX, CONTENT(allowance))
+ MOV_L (XOR, EAX)
+ MOV_L (AND, EDX)
+ MOV_B (AL, DL)
+
+ CMP_L (Y_AXIS, axis)
+ JE (mixY)
+/****************************/
+mixX:
+ CMP_L (CONST(1), signdx)
+ JNE (mixXLeft)
+ JMP (mixXRight)
+/****************************/
+ ALIGNTEXT4
+mixXRight:
+ MOV_B (REGIND(EDI), AL)
+ AND_B (DH, AL)
+ XOR_B (DL, AL)
+ MOV_B (AL, REGIND(EDI))
+
+ ADD_L (ECX, EBX)
+ JL (mixXRight1)
+
+ ADD_L (ESI, EDI)
+ ADD_L (CONTENT(e3), EBX)
+mixXRight1:
+ INC_L (EDI)
+ DEC_L (CONTENT(allowance))
+ JNZ (mixXRight)
+ RET
+/****************************/
+ ALIGNTEXT4
+mixXLeft:
+ MOV_B (REGIND(EDI), AL)
+ AND_B (DH, AL)
+ XOR_B (DL, AL)
+ MOV_B (AL, REGIND(EDI))
+
+ ADD_L (ECX, EBX)
+ JL (mixXLeft1)
+
+ ADD_L (ESI, EDI)
+ ADD_L (CONTENT(e3), EBX)
+mixXLeft1:
+ DEC_L (EDI)
+ DEC_L (CONTENT(allowance))
+ JNZ (mixXLeft)
+ RET
+/****************************/
+ ALIGNTEXT4
+mixY:
+ CMP_L (CONST(1), signdx)
+ JNE (mixYLeft)
+ JMP (mixYRight)
+/****************************/
+ ALIGNTEXT4
+mixYRight:
+ MOV_B (REGIND(EDI), AL)
+ AND_B (DH, AL)
+ XOR_B (DL, AL)
+ MOV_B (AL, REGIND(EDI))
+
+ ADD_L (ECX, EBX)
+ JL (mixYRight1)
+
+ INC_L (EDI)
+ ADD_L (CONTENT(e3), EBX)
+mixYRight1:
+ ADD_L (ESI, EDI)
+ DEC_L (CONTENT(allowance))
+ JNZ (mixYRight)
+ RET
+/****************************/
+ ALIGNTEXT4
+mixYLeft:
+ MOV_B (REGIND(EDI), AL)
+ AND_B (DH, AL)
+ XOR_B (DL, AL)
+ MOV_B (AL, REGIND(EDI))
+
+ ADD_L (ECX, EBX)
+ JL (mixYLeft1)
+
+ DEC_L (EDI)
+ ADD_L (CONTENT(e3), EBX)
+mixYLeft1:
+ ADD_L (ESI, EDI)
+ DEC_L (CONTENT(allowance))
+ JNZ (mixYLeft)
+ RET
+/****************************/
+ ALIGNTEXT4
+careful:
+ MOV_L (XOR, EAX)
+ MOV_L (e1, ECX)
+ MOV_L (CONST(0), CONTENT(tmp))
+
+ CMP_L (Y_AXIS, axis)
+ JE (carefulY)
+/****************************/
+carefulX:
+ MOV_L (signdx, ESI)
+
+ CMP_L (GXcopy, rop)
+ JNE (cXMix0)
+
+ MOV_L (len, EDX)
+ MOV_L (ADDR(cXSet2), CONTENT(jump))
+ JMP (cXSet)
+/****************************/
+ ALIGNTEXT4
+cXSet:
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (ECX, EBX)
+ JL (cXSet1)
+
+ MOV_L (CONST(1), CONTENT(tmp))
+ ADD_L (nlwidth, EDI)
+ ADD_L (CONTENT(e3), EBX)
+cXSet1:
+ ADD_L (ESI, EDI)
+
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)), EDI)
+ JNC (next)
+
+ CMP_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+ JC (prev)
+cXSet2:
+ DEC_L (EDX)
+ JZ (done)
+
+ CMP_L (CONST(1), CONTENT(tmp))
+ JNE (cXSet)
+
+ MOV_L (EDX, len)
+ JMP (VARINDIRECT(carefulJump))
+/****************************/
+ ALIGNTEXT4
+cXMix0:
+ MOV_L (AND, EDX)
+ MOV_B (AL, DL)
+ MOV_L (ADDR(cXMix2), CONTENT(jump))
+cXMix:
+ MOV_B (REGIND(EDI), AL)
+ AND_B (DH, AL)
+ XOR_B (DL, AL)
+ MOV_B (AL, REGIND(EDI))
+
+ ADD_L (ECX, EBX)
+ JL (cXMix1)
+
+ MOV_L (CONST(1), CONTENT(tmp))
+ ADD_L (nlwidth, EDI)
+ ADD_L (CONTENT(e3), EBX)
+cXMix1:
+ ADD_L (ESI, EDI)
+
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)), EDI)
+ JNC (next)
+
+ CMP_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+ JC (prev)
+cXMix2:
+ DEC_L (len)
+ JZ (done)
+
+ CMP_L (CONST(1), CONTENT(tmp))
+ JNE (cXMix)
+
+ JMP (VARINDIRECT(carefulJump))
+/****************************/
+ ALIGNTEXT4
+carefulY:
+ MOV_L (nlwidth, ESI)
+
+ CMP_L (GXcopy, rop)
+ JNE (cYMix0)
+
+ MOV_L (len, EDX)
+ MOV_L (ADDR(cYSet2), CONTENT(jump))
+ JMP (cYSet)
+/****************************/
+ ALIGNTEXT4
+cYSet:
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (ECX, EBX)
+ JL (cYSet1)
+
+ ADD_L (signdx, EDI)
+ ADD_L (CONTENT(e3), EBX)
+cYSet1:
+ ADD_L (ESI, EDI)
+
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)), EDI)
+ JNC (next)
+
+ CMP_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+ JC (prev)
+cYSet2:
+ DEC_L (EDX)
+ JZ (done)
+
+ MOV_L (EDX, len)
+ JMP (VARINDIRECT(carefulJump))
+/****************************/
+ ALIGNTEXT4
+cYMix0:
+ MOV_L (AND, EDX)
+ MOV_B (AL, DL)
+ MOV_L (ADDR(cYMix2), CONTENT(jump))
+cYMix:
+ MOV_B (REGIND(EDI), AL)
+ AND_B (DH, AL)
+ XOR_B (DL, AL)
+ MOV_B (AL, REGIND(EDI))
+
+ ADD_L (ECX, EBX)
+ JL (cYMix1)
+
+ ADD_L (signdx, EDI)
+ ADD_L (CONTENT(e3), EBX)
+cYMix1:
+ ADD_L (ESI, EDI)
+
+ CMP_L (CONTENT(GLNAME(vgaWriteTop)), EDI)
+ JNC (next)
+
+ CMP_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+ JC (prev)
+cYMix2:
+ DEC_L (len)
+ JZ (done)
+
+ JMP (VARINDIRECT(carefulJump))
+/****************************/
+ ALIGNTEXT4
+next:
+ MOV_L (EDX, CONTENT(tmp1))
+ SUB_L (CONST(0x10000), EDI)
+ MOV_B (CONTENT(segment), AL)
+ ADD_B (CONST(17), AL)
+ MOV_B (AL, CONTENT(segment))
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+ MOV_L (XOR, EAX)
+ MOV_L (CONTENT(tmp1), EDX)
+ JMP (VARINDIRECT(jump))
+/****************************/
+ ALIGNTEXT4
+prev:
+ MOV_L (EDX, CONTENT(tmp1))
+ ADD_L (CONST(0x10000), EDI)
+ MOV_B (CONTENT(segment), AL)
+ SUB_B (CONST(17), AL)
+ MOV_B (AL, CONTENT(segment))
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+ MOV_L (XOR, EAX)
+ MOV_L (CONTENT(tmp1), EDX)
+ JMP (VARINDIRECT(jump))
+/****************************/
+ ALIGNTEXT4
+pixmap:
+ CMP_L (Y_AXIS, axis)
+ JNE (pixmap1)
+
+ MOV_L (nlwidth, EAX)
+ MOV_L (signdx, EBX)
+ MOV_L (EBX, nlwidth)
+ MOV_L (EAX, signdx)
+pixmap1:
+ ADD_L (VGABASE, EDI)
+ MOV_L (len, ECX)
+ CMP_L (GXcopy, rop)
+ JNE (mmLine2)
+mmLine1:
+ MOV_L (ECX, EAX)
+ AND_L (CONST(3), EAX)
+ MOV_L (REGDIS(fsTable,EAX,4), EAX)
+ MOV_L (EAX, CONTENT(jump) )
+ MOV_L (XOR, EAX)
+ MOV_L (e, EBX)
+ MOV_L (e1, EDX)
+ MOV_L (signdx, ESI)
+ SHR_L (CONST(2), ECX)
+ JZ (fs1)
+fs6:
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (EDX, EBX)
+ JL (fs2)
+ ADD_L (nlwidth, EDI)
+ ADD_L (CONTENT(e3), EBX)
+fs2:
+ ADD_L (ESI, EDI)
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (EDX, EBX)
+ JL (fs3)
+ ADD_L (nlwidth, EDI)
+ ADD_L (CONTENT(e3), EBX)
+fs3:
+ ADD_L (ESI, EDI)
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (EDX, EBX)
+ JL (fs4)
+ ADD_L (nlwidth, EDI)
+ ADD_L (CONTENT(e3), EBX)
+fs4:
+ ADD_L (ESI, EDI)
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (EDX, EBX)
+ JL (fs5)
+ ADD_L (nlwidth, EDI)
+ ADD_L (CONTENT(e3), EBX)
+fs5:
+ ADD_L (ESI, EDI)
+ DEC_L (ECX)
+ JNZ (fs6)
+fs1:
+ JMP (VARINDIRECT(jump))
+ SEG_DATA
+ ALIGNDATA4
+fsTable:
+ D_LONG done, fs8, fs9, fs10
+ SEG_TEXT
+ ALIGNTEXT4
+fs10:
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (EDX, EBX)
+ JL (fs11)
+ ADD_L (nlwidth, EDI)
+ ADD_L (CONTENT(e3), EBX)
+fs11:
+ ADD_L (ESI, EDI)
+fs9:
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (EDX, EBX)
+ JL (fs12)
+ ADD_L (nlwidth, EDI)
+ ADD_L (CONTENT(e3), EBX)
+fs12:
+ ADD_L (ESI, EDI)
+fs8:
+ MOV_B (AL, REGIND(EDI))
+ JMP (done)
+/****************************/
+ ALIGNTEXT4
+mmLine2:
+ MOV_L (ECX, EAX)
+ AND_L (CONST(3), EAX)
+ MOV_L (REGDIS(fmTable,EAX,4), EAX)
+ MOV_L (EAX, CONTENT(jump))
+ MOV_L (XOR, EAX)
+ MOV_L (AND, EDX)
+ MOV_B (AL, DL)
+ MOV_L (e, EBX)
+ MOV_L (signdx, ESI)
+ SHR_L (CONST(2), ECX)
+ JZ (fm1)
+fm6:
+ MOV_B (REGIND(EDI), AL)
+ AND_B (DH, AL)
+ XOR_B (DL, AL)
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (e1, EBX)
+ JL (fm2)
+ ADD_L (nlwidth, EDI)
+ ADD_L (CONTENT(e3), EBX)
+fm2:
+ ADD_L (ESI, EDI)
+ MOV_B (REGIND(EDI), AL)
+ AND_B (DH, AL)
+ XOR_B (DL, AL)
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (e1, EBX)
+ JL (fm3)
+ ADD_L (nlwidth, EDI)
+ ADD_L (CONTENT(e3), EBX)
+fm3:
+ ADD_L (ESI, EDI)
+ MOV_B (REGIND(EDI), AL)
+ AND_B (DH, AL)
+ XOR_B (DL, AL)
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (e1, EBX)
+ JL (fm4)
+ ADD_L (nlwidth, EDI)
+ ADD_L (CONTENT(e3), EBX)
+fm4:
+ ADD_L (ESI, EDI)
+ MOV_B (REGIND(EDI), AL)
+ AND_B (DH, AL)
+ XOR_B (DL, AL)
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (e1, EBX)
+ JL (fm5)
+ ADD_L (nlwidth, EDI)
+ ADD_L (CONTENT(e3), EBX)
+fm5:
+ ADD_L (ESI, EDI)
+ DEC_L (ECX)
+ JNZ (fm6)
+fm1:
+ JMP (VARINDIRECT(jump))
+ SEG_DATA
+ ALIGNDATA4
+fmTable:
+ D_LONG done, fm8, fm9, fm10
+ SEG_TEXT
+ ALIGNTEXT4
+fm10:
+ MOV_B (REGIND(EDI), AL)
+ AND_B (DH, AL)
+ XOR_B (DL, AL)
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (e1, EBX)
+ JL (fm11)
+ ADD_L (nlwidth, EDI)
+ ADD_L (CONTENT(e3), EBX)
+fm11:
+ ADD_L (ESI, EDI)
+fm9:
+ MOV_B (REGIND(EDI), AL)
+ AND_B (DH, AL)
+ XOR_B (DL, AL)
+ MOV_B (AL, REGIND(EDI))
+ ADD_L (e1, EBX)
+ JL (fm12)
+ ADD_L (nlwidth, EDI)
+ ADD_L (CONTENT(e3), EBX)
+fm12:
+ ADD_L (ESI, EDI)
+fm8:
+ MOV_B (REGIND(EDI), AL)
+ AND_B (DH, AL)
+ XOR_B (DL, AL)
+ MOV_B (AL, REGIND(EDI))
+ JMP (done)
+
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suVHLine.s b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suVHLine.s
new file mode 100644
index 000000000..c4a0aac00
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suVHLine.s
@@ -0,0 +1,413 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/enhanced/suVHLine.s,v 1.2 1998/07/25 16:58:32 dawes Exp $ */
+/*******************************************************************************
+ Copyright 1992, 1993 by Glenn G. Lai
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Glenn G. Lai not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+Glenn G. Lai DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+Glenn G. Lai
+P.O. Box 4314
+Austin, Tx 78765
+(glenn@cs.utexas.edu)
+8/21/92
+7/10/93
+*******************************************************************************/
+/* $XConsortium: suVHLine.s /main/5 1996/02/21 18:09:22 kaleb $ */
+
+#include "assyntax.h"
+
+ FILE("suVHLine.s")
+ AS_BEGIN
+
+#include "vgaAsm.h"
+
+/*
+ void SpeedUpHLine(dst, fill, len, screen);
+ void SpeedUpVLine(dst, fill, len, screen);
+*/
+
+#define dst REGOFF(8,EBP)
+#define fill REGOFF(12,EBP)
+#define len REGOFF(16,EBP)
+#define screen REGOFF(20,EBP)
+/****************************************/
+ SEG_DATA
+copyright:
+ STRING("Copyright 1992, 7/10/1993 by Glenn G. Lai")
+ ALIGNDATA4
+speedUpTop:
+ D_LONG 0
+lMaskTable:
+ D_WORD 0x0f02
+ D_WORD 0x0802
+ D_WORD 0x0c02
+ D_WORD 0x0e02
+rMaskTable:
+ D_WORD 0x0f02
+ D_WORD 0x0102
+ D_WORD 0x0302
+ D_WORD 0x0702
+segment:
+ D_BYTE 0
+/****************************************/
+ SEG_TEXT
+ ALIGNTEXT4
+ GLOBL GLNAME(SpeedUpVLine)
+ GLOBL GLNAME(SpeedUpVLine1)
+GLNAME(SpeedUpVLine):
+ MOV_L (REGOFF(12,ESP), ECX)
+ OR_L (ECX, ECX)
+ JZ (return)
+GLNAME(SpeedUpVLine1):
+ MOV_L (REGOFF(4,ESP), EAX)
+ CMP_L (VGABASE, EAX)
+ JC (pixmapV)
+windowV:
+ CMP_L (CONST(1), ECX)
+ JNE (moreThanOnePoint)
+ MOV_L (EAX, ECX)
+ SHR_L (CONST(16), EAX)
+ MOV_L (CONST(0x3cd), EDX)
+ OUT_B
+ AND_L (CONST(0xffff), ECX)
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)), ECX)
+ MOV_L (REGOFF(8,ESP), EAX)
+ MOV_B (AL, REGIND(ECX))
+ RET
+/****************************************/
+ ALIGNTEXT4
+moreThanOnePoint:
+ PUSH_L (EBP)
+ MOV_L (ESP, EBP)
+ PUSH_L (EDI)
+ PUSH_L (ESI)
+ PUSH_L (EBX)
+
+ MOV_L (screen, ESI)
+ MOV_L (ESI, EBX)
+ DEC_L (EBX)
+ ADD_L (CONTENT(GLNAME(vgaWriteTop)), EBX)
+ MOV_L (EBX, CONTENT(speedUpTop))
+
+ MOV_L (EAX, EDI)
+ SHR_L (CONST(16), EAX)
+ MOV_B (AL, CONTENT(segment))
+
+ AND_L (CONST(0xffff), EDI)
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+
+ MOV_L (fill, EBX)
+ MOV_L (len, ECX)
+wVLoop:
+ MOV_L (CONST(0x3cd), EDX)
+ OUT_B
+
+ XOR_L (EDX, EDX)
+ MOV_L (CONTENT(speedUpTop), EAX)
+ SUB_L (EDI, EAX)
+ DIV_L (ESI)
+
+ CMP_L (ECX, EAX)
+ JC (wVLoop1)
+ MOV_L (ECX, EAX)
+wVLoop1:
+ SUB_L (EAX, ECX)
+wvLoop2:
+ MOV_B (BL, REGIND(EDI))
+ ADD_L (ESI, EDI)
+ DEC_L (EAX)
+ JNZ (wvLoop2)
+
+ OR_L (ECX, ECX)
+ JZ (npDone)
+
+ SUB_L (CONST(0x10000), EDI)
+ MOV_B (CONTENT(segment), AL)
+ INC_B (AL)
+ MOV_B (AL, CONTENT(segment))
+ JMP (wVLoop)
+/*****************************************/
+ ALIGNTEXT4
+pixmapV:
+ PUSH_L (EDI)
+ PUSH_L (ESI)
+ MOV_L (REGOFF(16,ESP), EDX)
+ MOV_L (REGOFF(24,ESP), ESI)
+ MOV_L (ECX, EDI)
+ AND_L (CONST(3), EDI)
+ MOV_L (REGDIS(pixmapVTable,EDI,4), EDI)
+ SHR_L (CONST(2), ECX)
+ JZ (pixmapV4)
+pixmapV5:
+ MOV_B (DL, REGIND(EAX))
+ ADD_L (ESI, EAX)
+ MOV_B (DL, REGIND(EAX))
+ ADD_L (ESI, EAX)
+ MOV_B (DL, REGIND(EAX))
+ ADD_L (ESI, EAX)
+ MOV_B (DL, REGIND(EAX))
+ ADD_L (ESI, EAX)
+ DEC_L (ECX)
+ JNZ (pixmapV5)
+pixmapV4:
+ JMP (CODEPTR(EDI))
+/*******************/
+ SEG_DATA
+ ALIGNDATA4
+pixmapVTable:
+ D_LONG pixmapV0, pixmapV1, pixmapV2, pixmapV3
+/*******************/
+ SEG_TEXT
+ ALIGNTEXT4
+pixmapV3:
+ MOV_B (DL, REGIND(EAX))
+ ADD_L (ESI, EAX)
+pixmapV2:
+ MOV_B (DL, REGIND(EAX))
+ ADD_L (ESI, EAX)
+pixmapV1:
+ MOV_B (DL, REGIND(EAX))
+pixmapV0:
+ POP_L (ESI)
+ POP_L (EDI)
+ RET
+/*****************************************/
+ GLOBL GLNAME(SpeedUpHLine)
+ GLOBL GLNAME(SpeedUpHLine1)
+ ALIGNTEXT4
+GLNAME(SpeedUpHLine):
+ MOV_L (REGOFF(12,ESP), ECX)
+ OR_L (ECX, ECX)
+ JZ (return)
+GLNAME(SpeedUpHLine1):
+ MOV_L (REGOFF(4,ESP), EAX)
+ SUB_L (VGABASE, EAX)
+ JC (pixmapH)
+windowH:
+ CMP_L (CONST(1), ECX)
+ JNE (windowH1)
+ MOV_L (EAX, ECX)
+ SHR_L (CONST(16), EAX)
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+ AND_L (CONST(0xffff), ECX)
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)), ECX)
+ MOV_L (REGOFF(8,ESP), EAX)
+ MOV_B (AL, REGIND(ECX))
+ RET
+/****************/
+ ALIGNTEXT4
+windowH1:
+/* Change THRESHOLD at YOUR OWN RISK!!! */
+#define THRESHOLD CONST(80)
+ CMP_L (THRESHOLD, ECX)
+ JNC (pMode)
+windowH8:
+ PUSH_L (EDI)
+ MOV_L (EAX, EDI)
+ SHR_L (CONST(16), EAX)
+ MOV_B (AL, CONTENT(segment))
+ MOV_W (CONST(0x3cd), DX)
+ OUT_B
+
+ AND_L (CONST(0xffff), EDI)
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+ MOV_L (CONTENT(GLNAME(vgaWriteTop)), EAX)
+ SUB_L (EDI, EAX)
+
+ XOR_L (EDX, EDX)
+ CMP_L (ECX, EAX)
+ JNC (windowH7)
+
+ MOV_L (ECX, EDX)
+ MOV_L (EAX, ECX)
+ SUB_L (EAX, EDX)
+windowH7:
+ MOV_L (REGOFF(12,ESP), EAX)
+ TEST_L (CONST(1), EDI)
+ JZ (windowH2)
+ STOS_B
+ DEC_L (ECX)
+ JZ (windowH5)
+windowH2:
+ SHR_L (CONST(1), ECX)
+ JZ (windowH3)
+ REP
+ STOS_W
+ JNC (windowH4)
+windowH3:
+ STOS_B
+windowH4:
+ OR_L (EDX, EDX)
+ JNZ (windowH5)
+ POP_L (EDI)
+ RET
+ ALIGNTEXT4
+windowH5:
+ MOV_L (EDX, ECX)
+ MOV_B (CONTENT(segment), AL)
+ INC_B (AL)
+ MOV_L (CONST(0x3cd), EDX)
+ OUT_B
+ MOV_L (REGOFF(12,ESP), EAX)
+ SUB_L (CONST(0x10000), EDI)
+ SHR_L (CONST(1), ECX)
+ JZ (windowH6)
+ REP
+ STOS_W
+ JNC (windowH9)
+windowH6:
+ STOS_B
+windowH9:
+ POP_L (EDI)
+ RET
+/****************************/
+ ALIGNTEXT4
+pixmapH:
+ ADD_L (VGABASE, EAX)
+ CMP_L (CONST(7), ECX)
+ JC (pixmapH0)
+
+ PUSH_L (EDI)
+ MOV_L (EAX, EDI)
+ MOV_L (REGOFF(12,ESP), EAX)
+
+ TEST_L (CONST(1), EDI)
+ JZ (pixmapH1)
+ STOS_B
+ DEC_L (ECX)
+pixmapH1:
+ TEST_L (CONST(2), EDI)
+ JZ (pixmapH2)
+ STOS_W
+ SUB_L (CONST(2), ECX)
+pixmapH2:
+ MOV_L (ECX, EDX)
+ SHR_L (CONST(2), ECX)
+ REP
+ STOS_L
+ TEST_L (CONST(2), EDX)
+ JZ (pixmapH4)
+ STOS_W
+pixmapH4:
+ TEST_L (CONST(1), EDX)
+ JZ (pixmapH5)
+ MOV_B (AL, REGIND(EDI))
+pixmapH5:
+ POP_L (EDI)
+ RET
+/****************/
+ ALIGNTEXT4
+pixmapH0:
+ MOV_L (REGOFF(8,ESP), EDX)
+pixmapH01:
+ MOV_B (DL, REGIND(EAX))
+ INC_L (EAX)
+ DEC_L (ECX)
+ JNZ (pixmapH01)
+ RET
+/****************************/
+ ALIGNTEXT4
+pMode:
+ MOV_L (EAX, EDX)
+ AND_L (CONST(0x3ffff), EDX)
+ SUB_L (CONST(0x40000), EDX)
+ NEG_L (EDX)
+ CMP_L (ECX, EDX)
+ JC (windowH8)
+
+ PUSH_L (EBP)
+ MOV_L (ESP,EBP)
+ PUSH_L (EDI)
+ PUSH_L (ESI)
+ PUSH_L (EBX)
+/***************************/
+ MOV_W (CONST(0x3c4), DX)
+ MOV_W (CONST(0x0604), AX )
+ OUT_W
+ MOV_W (CONST(0x3ce), DX)
+ MOV_W (CONST(0x0001), AX)
+ OUT_W
+ MOV_W (CONST(0x0003), AX)
+ OUT_W
+ MOV_W (CONST(0x4005), AX)
+ OUT_W
+ MOV_W (CONST(0xff08), AX)
+ OUT_W
+/***************************/
+ MOV_L (fill, EBX)
+ MOV_L (dst, EDI)
+ MOV_L (EDI, EAX)
+ SHR_L (CONST(18), EAX)
+ DEC_W (DX)
+ OUT_B
+ MOV_W (CONST(0x3c4), DX)
+
+ AND_L (CONST(0x3ffff), EDI)
+ MOV_L (EDI, EAX)
+ SHR_L (CONST(2), EDI)
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)), EDI)
+
+ MOV_L (EAX, ESI)
+ ADD_L (CONST(3), ESI)
+ AND_L (CONST(0xfffffffc), ESI)
+ SUB_L (EAX, ESI)
+ JZ (pMode1)
+
+ MOV_W (REGDIS(lMaskTable,ESI,2), AX)
+ OUT_W
+ SUB_L (ESI, ECX)
+ MOV_B (BL, REGIND(EDI))
+ INC_L (EDI)
+pMode1:
+ MOV_W (CONST(0x0f02), AX)
+ OUT_W
+
+ MOV_L (EBX, EAX)
+ MOV_L (ECX, ESI)
+ AND_L (CONST(3), ESI)
+ SHR_L (CONST(2), ECX)
+
+ TEST_L (CONST(1), EDI)
+ JZ (pMode2)
+ STOS_B
+ DEC_L (ECX)
+pMode2:
+ SHR_L (CONST(1), ECX)
+ REP
+ STOS_W
+ JNC (pMode3)
+ STOS_B
+pMode3:
+ SHL_L (CONST(1), ESI)
+ JZ (pMode4)
+ MOV_W (rMaskTable(ESI), AX)
+ OUT_W
+ MOV_B (BL, REGIND(EDI))
+ MOV_W (CONST(0x0f02), AX)
+ OUT_W
+pMode4:
+ MOV_W (CONST(0x0c04), AX)
+ OUT_W
+npDone:
+ POP_L (EBX)
+ POP_L (ESI)
+ POP_L (EDI)
+ LEAVE
+return:
+ RET
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaBitBlt.c b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaBitBlt.c
new file mode 100644
index 000000000..35772b19b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaBitBlt.c
@@ -0,0 +1,541 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaBitBlt.c,v 1.2 1998/07/25 16:58:32 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Roell not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Roell makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Thomas Roell, roell@informatik.tu-muenchen.de
+ *
+ */
+/* $XConsortium: vgaBitBlt.c /main/4 1996/02/21 18:09:26 kaleb $ */
+
+#include "vgafb.h"
+#include "fastblt.h"
+#include "mergerop.h"
+
+
+void (*ourvgaBitBlt)();
+
+void
+vgaBitBlt(pdstBase, psrcBase, widthSrc, widthDst, x, y,
+ x1, y1, w, h, xdir, ydir, alu, planemask)
+ unsigned char *psrcBase, *pdstBase; /* start of src and dst bitmaps */
+ int widthSrc, widthDst;
+ int x, y, x1, y1, w, h;
+ int xdir, ydir;
+ int alu;
+ unsigned long planemask;
+
+{
+ unsigned char *psrc, *pdst;
+ int hcount, vcount, count, srcPitch, dstPitch, tmp;
+
+ if (alu == GXcopy && (planemask & 0xFF) == 0xFF) {
+ if (xdir == 1) { /* left to right */
+ if (ydir == 1) /* top to bottom */
+ {
+ psrc = psrcBase+(y*widthSrc)+x;
+ pdst = pdstBase+(y1*widthDst)+x1;
+ }
+ else /* bottom to top */
+ {
+ psrc = psrcBase-((y+h-1)*widthSrc)+x;
+ pdst = pdstBase-((y1+h-1)*widthDst)+x1;
+ }
+ srcPitch = widthSrc - w;
+ dstPitch = widthDst - w;
+
+ } else {/* right to left */
+
+ if (ydir == 1) /* top to bottom */
+ {
+ psrc = psrcBase+(y*widthSrc)+x+w;
+ pdst = pdstBase+(y1 * widthDst)+x1+w;
+ }
+ else /* bottom to top */
+ {
+ psrc = psrcBase-((y+h-1)*widthSrc)+x+w;
+ pdst = pdstBase-((y1+h-1)*widthDst)+x1+w;
+ }
+ srcPitch = widthSrc + w;
+ dstPitch = widthDst + w;
+ }
+
+ psrc = (unsigned char *)vgaSetRead(psrc);
+ pdst = (unsigned char *)vgaSetWrite(pdst);
+
+ vcount = 0;
+ while (h || vcount) {
+ /*
+ * compute here the maximal linecount(hcount) before a
+ * segment switch has to be made
+ */
+ if (!vcount) {
+ if (ydir == 1) {
+ tmp = ((unsigned char *)vgaReadTop - psrc) / widthSrc;
+ if ((xdir == -1) &&
+ ((psrc - (unsigned char *)vgaReadBottom) <= w)) tmp = 0;
+ } else {
+ tmp = (psrc - (unsigned char *)vgaReadBottom) / (-widthSrc);
+ if ((xdir == 1) &&
+ (((unsigned char *)vgaReadTop - psrc) <= w)) tmp = 0;
+ }
+ hcount=min( h, tmp );
+ if(!hcount) vcount = w;
+
+ if (ydir == 1) {
+ tmp = ((unsigned char *)vgaWriteTop - pdst) / widthDst;
+ if ((xdir == -1) &&
+ ((pdst - (unsigned char *)vgaWriteBottom) <= w)) tmp = 0;
+ } else {
+ tmp = (pdst - (unsigned char *)vgaWriteBottom) / (-widthDst);
+ if ((xdir == 1) &&
+ (((unsigned char *)vgaWriteTop - pdst) <= w)) tmp = 0;
+ }
+ hcount=min( hcount, tmp );
+ if(!hcount) vcount = w;
+ }
+
+ /*
+ * if we now have to make a segment switch within a line,
+ * divide this line into small parts.
+ */
+ if (vcount) {
+ count = vcount;
+
+ /* check which segment to switch first */
+ if (xdir == 1) {
+ if (tmp = (unsigned char *)vgaReadTop - psrc)
+ count = min(count, tmp);
+ else
+ psrc = (unsigned char *)vgaReadNext(psrc);
+ } else {
+ if (tmp = psrc - (unsigned char *)vgaReadBottom)
+ count = min(count, tmp);
+ else
+ psrc = (unsigned char *)vgaReadPrev(psrc);
+ }
+
+ if (xdir == 1) {
+ if (tmp = (unsigned char *)vgaWriteTop - pdst)
+ count = min(count, tmp);
+ else
+ pdst = (unsigned char *)vgaWriteNext(pdst);
+ } else {
+ if (tmp = pdst - (unsigned char *)vgaWriteBottom)
+ count = min(count, tmp);
+ else
+ pdst = (unsigned char *)vgaWritePrev(pdst);
+ }
+
+ fastBitBltCopy(xdir,psrc, pdst, 1, count, 0, 0);
+
+ if (!(vcount -= count)) {
+ h--; /* partial line finish */
+ if (xdir == 1) {
+ psrc += (srcPitch + count);
+ pdst += (dstPitch + count);
+ } else {
+ psrc += (srcPitch - count);
+ pdst += (dstPitch - count);
+ }
+
+ if ( psrc >= (unsigned char *)vgaReadTop )
+ psrc = (unsigned char *)vgaReadNext(psrc);
+ if ( psrc < (unsigned char *)vgaReadBottom )
+ psrc = (unsigned char *)vgaReadPrev(psrc);
+
+ if ( pdst >= (unsigned char *)vgaWriteTop )
+ pdst = (unsigned char *)vgaWriteNext(pdst);
+ if ( pdst < (unsigned char *)vgaWriteBottom )
+ pdst = (unsigned char *)vgaWritePrev(pdst);
+
+ } else {
+ if (xdir == 1) {
+ psrc += count;
+ pdst += count;
+ } else {
+ psrc -= count;
+ pdst -= count;
+ }
+ }
+ } else {
+
+ h -= hcount;
+
+ fastBitBltCopy(xdir, psrc, pdst, hcount, w, srcPitch, dstPitch);
+
+ psrc += (hcount*widthSrc);
+ pdst += (hcount*widthDst);
+ }
+ }
+ }
+}
+
+void
+OneBankvgaBitBlt(pdstBase, psrcBase, widthSrc, widthDst, x, y,
+ x1, y1, w, h, xdir, ydir, alu, planemask)
+ unsigned char *psrcBase, *pdstBase; /* start of src and dst bitmaps */
+ int widthSrc, widthDst;
+ int x, y, x1, y1, w, h;
+ int xdir, ydir;
+ int alu;
+ unsigned long planemask;
+
+{
+#define BUFSIZE 4096
+
+ unsigned char buf[BUFSIZE];
+ int m,n,ww;
+
+ if (alu == GXcopy && (planemask & 0xFF) == 0xFF) {
+ if (w == 0)
+ return;
+ if (widthSrc != widthDst)
+ return;
+ ww = widthSrc >= 0 ? widthSrc : -widthSrc;
+ m = BUFSIZE/ww;
+ if (ydir == 1) {
+ while (h) {
+ n = m>h ? h : m;
+ (void)vgaImageRead(buf, psrcBase, widthSrc,ww,x,y,0,0,w,n,xdir,ydir,alu,planemask);
+ (void)vgaImageWrite(pdstBase, buf,ww,widthDst,0,0,x1,y1,w,n,xdir,ydir,alu,planemask);
+ y += n;
+ y1 += n;
+ h -= n;
+ }
+ }
+ else {
+ y += h;
+ y1 += h;
+ while (h) {
+ n = m>h ? h : m;
+ y -= n;
+ y1 -= n;
+ h -= n;
+ (void)vgaImageRead(buf+BUFSIZE-ww,psrcBase,widthSrc,ww,x,y,0,0,w,n,xdir,ydir,alu,planemask);
+ (void)vgaImageWrite(pdstBase,buf+BUFSIZE-ww,ww,widthDst,0,0,x1,y1,w,n,xdir,ydir,alu,planemask);
+ }
+ }
+ }
+}
+
+void
+vgaImageRead(pdstBase, psrcBase, widthSrc, widthDst, x, y,
+ x1, y1, w, h, xdir, ydir, alu, planemask)
+ unsigned char *psrcBase, *pdstBase; /* start of src and dst bitmaps */
+ int widthSrc, widthDst;
+ int x, y, x1, y1, w, h;
+ int xdir, ydir;
+ int alu;
+ unsigned long planemask;
+
+{
+ register unsigned char *psrc, *pdst;
+ int hcount, vcount, count, srcPitch, dstPitch, tmp;
+
+ if (alu == GXcopy && (planemask & 0xFF) == 0xFF) {
+ if (xdir == 1) { /* left to right */
+ if (ydir == 1) /* top to bottom */
+ {
+ psrc = psrcBase+(y*widthSrc)+x;
+ pdst = pdstBase+(y1*widthDst)+x1;
+ }
+ else /* bottom to top */
+ {
+ psrc = psrcBase-((y+h-1)*widthSrc)+x;
+ pdst = pdstBase-((y1+h-1)*widthDst)+x1;
+ }
+ srcPitch = widthSrc - w;
+ dstPitch = widthDst - w;
+
+ } else {/* right to left */
+
+ if (ydir == 1) /* top to bottom */
+ {
+ psrc = psrcBase+(y*widthSrc)+x+w;
+ pdst = pdstBase+(y1 * widthDst)+x1+w;
+ }
+ else /* bottom to top */
+ {
+ psrc = psrcBase-((y+h-1)*widthSrc)+x+w;
+ pdst = pdstBase-((y1+h-1)*widthDst)+x1+w;
+ }
+ srcPitch = widthSrc + w;
+ dstPitch = widthDst + w;
+ }
+
+ psrc = (unsigned char *)vgaSetRead(psrc);
+
+ vcount = 0;
+ while (h || vcount) {
+ /*
+ * compute here the maximal linecount(hcount) before a
+ * segment switch has to be made
+ */
+ if (!vcount) {
+ if (ydir == 1) {
+ tmp = ((unsigned char *)vgaReadTop - psrc) / widthSrc;
+ if ((xdir == -1) &&
+ ((psrc - (unsigned char *)vgaReadBottom) <= w)) tmp = 0;
+ } else {
+ tmp = (psrc - (unsigned char *)vgaReadBottom) / (-widthSrc);
+ if ((xdir == 1) &&
+ (((unsigned char *)vgaReadTop - psrc) <= w)) tmp = 0;
+ }
+ hcount=min( h, tmp );
+ if(!hcount) vcount = w;
+ }
+
+ /*
+ * if we now have to make a segment switch within a line,
+ * divide this line into small parts.
+ */
+ if (vcount) {
+ count = vcount;
+
+ /* check which segment to switch first */
+ if (xdir == 1) {
+ if (tmp = (unsigned char *)vgaReadTop - psrc)
+ count = min(count, tmp);
+ else
+ psrc = (unsigned char *)vgaReadNext(psrc);
+ } else {
+ if (tmp = psrc - (unsigned char *)vgaReadBottom)
+ count = min(count, tmp);
+ else
+ psrc = (unsigned char *)vgaReadPrev(psrc);
+ }
+
+ fastBitBltCopy(xdir,psrc, pdst, 1, count, 0, 0);
+
+ if (!(vcount -= count)) {
+ h--; /* partial line finish */
+ if (xdir == 1) {
+ psrc += (srcPitch + count);
+ pdst += (dstPitch + count);
+ } else {
+ psrc += (srcPitch - count);
+ pdst += (dstPitch - count);
+ }
+
+ if ( psrc >= (unsigned char *)vgaReadTop )
+ psrc = (unsigned char *)vgaReadNext(psrc);
+ if ( psrc < (unsigned char *)vgaReadBottom )
+ psrc = (unsigned char *)vgaReadPrev(psrc);
+
+ } else {
+ if (xdir == 1) {
+ psrc += count;
+ pdst += count;
+ } else {
+ psrc -= count;
+ pdst -= count;
+ }
+ }
+ } else {
+
+ h -= hcount;
+
+ fastBitBltCopy(xdir, psrc, pdst, hcount, w, srcPitch, dstPitch);
+
+ psrc += (hcount*widthSrc);
+ pdst += (hcount*widthDst);
+ }
+ }
+ }
+}
+
+
+void
+vgaImageWrite(pdstBase, psrcBase, widthSrc, widthDst, x, y,
+ x1, y1, w, h, xdir, ydir, alu, planemask)
+ unsigned char *psrcBase, *pdstBase; /* start of src and dst bitmaps */
+ int widthSrc, widthDst;
+ int x, y, x1, y1, w, h;
+ int xdir, ydir;
+ int alu;
+ unsigned long planemask;
+
+{
+ register unsigned char *psrc, *pdst;
+ int hcount, vcount, count, srcPitch, dstPitch, tmp;
+
+ if (alu == GXcopy && (planemask & 0xFF) == 0xFF) {
+ if (xdir == 1) { /* left to right */
+ if (ydir == 1) /* top to bottom */
+ {
+ psrc = psrcBase+(y*widthSrc)+x;
+ pdst = pdstBase+(y1*widthDst)+x1;
+ }
+ else /* bottom to top */
+ {
+ psrc = psrcBase-((y+h-1)*widthSrc)+x;
+ pdst = pdstBase-((y1+h-1)*widthDst)+x1;
+ }
+ srcPitch = widthSrc - w;
+ dstPitch = widthDst - w;
+
+ } else {/* right to left */
+
+ if (ydir == 1) /* top to bottom */
+ {
+ psrc = psrcBase+(y*widthSrc)+x+w;
+ pdst = pdstBase+(y1 * widthDst)+x1+w;
+ }
+ else /* bottom to top */
+ {
+ psrc = psrcBase-((y+h-1)*widthSrc)+x+w;
+ pdst = pdstBase-((y1+h-1)*widthDst)+x1+w;
+ }
+ srcPitch = widthSrc + w;
+ dstPitch = widthDst + w;
+ }
+
+ pdst = (unsigned char *)vgaSetWrite(pdst);
+
+ vcount = 0;
+ while (h || vcount) {
+ /*
+ * compute here the maximal linecount(hcount) before a
+ * segment switch has to be made
+ */
+ if (!vcount) {
+ if (ydir == 1) {
+ tmp = ((unsigned char *)vgaWriteTop - pdst) / widthDst;
+ if ((xdir == -1) &&
+ ((pdst - (unsigned char *)vgaWriteBottom) <= w)) tmp = 0;
+ } else {
+ tmp = (pdst - (unsigned char *)vgaWriteBottom) / (-widthDst);
+ if ((xdir == 1) &&
+ (((unsigned char *)vgaWriteTop - pdst) <= w)) tmp = 0;
+ }
+ hcount=min( h, tmp );
+ if(!hcount) vcount = w;
+ }
+
+ /*
+ * if we now have to make a segment switch within a line,
+ * divide this line into small parts.
+ */
+ if (vcount) {
+ count = vcount;
+
+ /* check which segment to switch first */
+ if (xdir == 1) {
+ if (tmp = (unsigned char *)vgaWriteTop - pdst)
+ count = min(count, tmp);
+ else
+ pdst = (unsigned char *)vgaWriteNext(pdst);
+ } else {
+ if (tmp = pdst - (unsigned char *)vgaWriteBottom)
+ count = min(count, tmp);
+ else
+ pdst = (unsigned char *)vgaWritePrev(pdst);
+ }
+
+ fastBitBltCopy(xdir,psrc, pdst, 1, count, 0, 0);
+
+ if (!(vcount -= count)) {
+ h--; /* partial line finish */
+ if (xdir == 1) {
+ psrc += (srcPitch + count);
+ pdst += (dstPitch + count);
+ } else {
+ psrc += (srcPitch - count);
+ pdst += (dstPitch - count);
+ }
+
+ if ( (void *)pdst >= vgaWriteTop )
+ pdst = (unsigned char *)vgaWriteNext(pdst);
+ if ( (void *)pdst < vgaWriteBottom )
+ pdst = (unsigned char *)vgaWritePrev(pdst);
+
+ } else {
+ if (xdir == 1) {
+ psrc += count;
+ pdst += count;
+ } else {
+ psrc -= count;
+ pdst -= count;
+ }
+ }
+ } else {
+
+ h -= hcount;
+
+ fastBitBltCopy(xdir, psrc, pdst, hcount, w, srcPitch, dstPitch);
+
+ psrc += (hcount*widthSrc);
+ pdst += (hcount*widthDst);
+ }
+ }
+ }
+}
+
+
+void
+vgaPixBitBlt(pdstBase, psrcBase, widthSrc, widthDst, x, y,
+ x1, y1, w, h, xdir, ydir, alu, planemask)
+ unsigned char *psrcBase, *pdstBase; /* start of src and dst bitmaps */
+ int widthSrc, widthDst;
+ int x, y, x1, y1, w, h;
+ int xdir, ydir;
+ int alu;
+ unsigned long planemask;
+
+{
+ register unsigned char *psrc, *pdst;
+ int srcPitch, dstPitch;
+
+ if (alu == GXcopy && (planemask & 0xFF) == 0xFF) {
+ if (xdir == 1) { /* left to right */
+ if (ydir == 1) /* top to bottom */
+ {
+ psrc = psrcBase+(y*widthSrc)+x;
+ pdst = pdstBase+(y1*widthDst)+x1;
+ }
+ else /* bottom to top */
+ {
+ psrc = psrcBase-((y+h-1)*widthSrc)+x;
+ pdst = pdstBase-((y1+h-1)*widthDst)+x1;
+ }
+ srcPitch = widthSrc - w;
+ dstPitch = widthDst - w;
+
+ } else {/* right to left */
+
+ if (ydir == 1) /* top to bottom */
+ {
+ psrc = psrcBase+(y*widthSrc)+x+w;
+ pdst = pdstBase+(y1 * widthDst)+x1+w;
+ }
+ else /* bottom to top */
+ {
+ psrc = psrcBase-((y+h-1)*widthSrc)+x+w;
+ pdst = pdstBase-((y1+h-1)*widthDst)+x1+w;
+ }
+ srcPitch = widthSrc + w;
+ dstPitch = widthDst + w;
+ }
+
+ fastBitBltCopy(xdir, psrc, pdst, h, w, srcPitch, dstPitch);
+
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaBltFillc.c b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaBltFillc.c
new file mode 100644
index 000000000..9192ee3db
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaBltFillc.c
@@ -0,0 +1,835 @@
+/*
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaBltFillc.c,v 1.2 1998/07/25 16:58:33 dawes Exp $ */
+
+#include "X.h"
+#include "misc.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86_HWlib.h"
+
+#include "vga.h"
+#include "cfb.h"
+
+/* fBitBlt.s */
+
+void fastBitBltCopy(
+ int xdir,
+ unsigned char *psrc,
+ unsigned char *pdst,
+ int h,
+ int w,
+ int srcPitch,
+ int dstPitch
+)
+{
+ if (xdir <= 0) {
+ while (h--) {
+ xf86memmove(pdst-w, psrc-w, w);
+ pdst += dstPitch - w;
+ psrc += srcPitch - w;
+ }
+ } else {
+ while (h--) {
+ xf86memcpy(pdst, psrc, w);
+ pdst += dstPitch + w;
+ psrc += srcPitch + w;
+ }
+ }
+}
+
+/* fFillAnd.s */
+
+unsigned char *fastFillSolidGXand(
+ unsigned char *pdst,
+ unsigned long fill1,
+ unsigned long fill2,
+ int hcount,
+ int count,
+ int w,
+ int widthPitch
+)
+{
+ /*
+ * NOTES: original assembly code presumes hcount > 0 to start with
+ * New code assumes that all bytes of fill1, fill2 are
+ * consistent. i.e. 0xefefefef, and not 0x12345678.
+ * This is because the caller of this routine does a PFILL()
+ * of the [fill1, fill2] values before they get here.
+ * For large block cases (count > 3), the original code
+ * assumed that width == count.
+ * Fills hcount trips of count bytes each trip through loop
+ */
+
+ if (count == 0)
+ return pdst;
+
+ while (hcount > 0) {
+ /* No special 'fast' cases here */
+ int cur_count;
+ unsigned char tmpb = fill1;
+ unsigned short tmph = fill1;
+ unsigned int tmpi = fill1;
+
+ cur_count = count;
+
+ /* Fiddle with leading bits up to large block */
+ if (((long)pdst & 0x1) && cur_count >= 1) {
+ /* To next 0mod2 */
+ *(unsigned char *) pdst &= tmpb;
+ pdst++;
+ cur_count--;
+ }
+
+ if (((long)pdst & 0x2) && cur_count >= 2) {
+ /* To next 0mod4 */
+ *(unsigned short *) pdst &= tmph;
+ pdst += 2;
+ cur_count -= 2;
+ }
+
+ if (((long)pdst & 0x4) && cur_count >= 4) {
+ /* To next 0mod8 */
+ *(unsigned int *) pdst &= tmpi;
+ pdst += 4;
+ cur_count -= 4;
+ }
+
+#if defined(__alpha__)
+ /*
+ * Perform bulk copy, knowing 0mod8 alignment
+ * Assumes 64-bit longs.
+ */
+
+ while (cur_count >= 64) {
+
+ /* Hand unrolled x8, assumes scheduler does a good job */
+ *(unsigned long *) ((long) pdst + 0 ) &= fill1;
+ *(unsigned long *) ((long) pdst + 8 ) &= fill1;
+ *(unsigned long *) ((long) pdst + 16) &= fill1;
+ *(unsigned long *) ((long) pdst + 24) &= fill1;
+ *(unsigned long *) ((long) pdst + 32) &= fill1;
+ *(unsigned long *) ((long) pdst + 40) &= fill1;
+ *(unsigned long *) ((long) pdst + 48) &= fill1;
+ *(unsigned long *) ((long) pdst + 56) &= fill1;
+
+ pdst += 64;
+ cur_count -= 64;
+ }
+
+ /* Perform trailing bits cleanup */
+ while (cur_count >= 8) {
+ *(unsigned long *) ((long) pdst + 0) &= fill1;
+ pdst += 8;
+ cur_count -= 8;
+ }
+#else
+ /*
+ * Perform bulk copy, knowing 0mod4 alignment
+ * Assumes 32-bit longs.
+ */
+
+ while (cur_count >= 32) {
+
+ /* Hand unrolled x8, assumes scheduler does a good job */
+ *(unsigned long *) ((long) pdst + 0 ) &= fill1;
+ *(unsigned long *) ((long) pdst + 4 ) &= fill1;
+ *(unsigned long *) ((long) pdst + 8 ) &= fill1;
+ *(unsigned long *) ((long) pdst + 12) &= fill1;
+ *(unsigned long *) ((long) pdst + 16) &= fill1;
+ *(unsigned long *) ((long) pdst + 20) &= fill1;
+ *(unsigned long *) ((long) pdst + 24) &= fill1;
+ *(unsigned long *) ((long) pdst + 28) &= fill1;
+
+ pdst += 32;
+ cur_count -= 32;
+ }
+
+ /* Perform trailing bits cleanup */
+ while (cur_count >= 4) {
+ *(unsigned long *) ((long) pdst + 0) &= fill1;
+ pdst += 4;
+ cur_count -= 4;
+ }
+#endif
+
+ if (cur_count >= 4) {
+ /* On 0mod4 boundary already */
+ *(unsigned int *) pdst &= tmpi;
+ pdst += 4;
+ cur_count -= 4;
+ }
+
+ if (cur_count >= 2) {
+ /* On 0mod2 boundary already */
+ *(unsigned short *) pdst &= tmph;
+ pdst += 2;
+ cur_count -= 2;
+ }
+
+ if (cur_count >= 1) {
+ /* last possible byte */
+ *(unsigned char *) pdst &= tmpb;
+ pdst++;
+ cur_count--;
+ }
+
+ /* Loop epilogue */
+/* assert(cur_count == 0); */
+ pdst += widthPitch;
+ hcount--;
+ }
+
+ return pdst;
+}
+
+/* fFillOr.s */
+
+unsigned char *fastFillSolidGXor(
+ unsigned char *pdst,
+ unsigned long fill1,
+ unsigned long fill2,
+ int hcount,
+ int count,
+ int w,
+ int widthPitch
+)
+{
+ /*
+ * NOTES: original assembly code presumes hcount > 0 to start with
+ * New code assumes that all bytes of fill1, fill2 are
+ * consistent. i.e. 0xefefefef, and not 0x12345678.
+ * This is because the caller of this routine does a PFILL()
+ * of the [fill1, fill2] values before they get here.
+ * For large block cases (count > 3), the original code
+ * assumed that width == count.
+ * Fills hcount trips of count bytes each trip through loop
+ */
+
+ if (count == 0)
+ return pdst;
+
+ while (hcount > 0) {
+ /* No special 'fast' cases here */
+ int cur_count;
+ unsigned char tmpb = fill1;
+ unsigned short tmph = fill1;
+ unsigned int tmpi = fill1;
+
+ cur_count = count;
+
+ /* Fiddle with leading bits up to large block */
+ if (((long)pdst & 0x1) && cur_count >= 1) {
+ /* To next 0mod2 */
+ *(unsigned char *) pdst |= tmpb;
+ pdst++;
+ cur_count--;
+ }
+
+ if (((long)pdst & 0x2) && cur_count >= 2) {
+ /* To next 0mod4 */
+ *(unsigned short *) pdst |= tmph;
+ pdst += 2;
+ cur_count -= 2;
+ }
+
+ if (((long)pdst & 0x4) && cur_count >= 4) {
+ /* To next 0mod8 */
+ *(unsigned int *) pdst |= tmpi;
+ pdst += 4;
+ cur_count -= 4;
+ }
+
+#if defined(__alpha__)
+ /*
+ * Perform bulk copy, knowing 0mod8 alignment
+ * Assumes 64-bit longs.
+ */
+
+ while (cur_count >= 64) {
+
+ /* Hand unrolled x8, assumes scheduler does a good job */
+ *(unsigned long *) ((long) pdst + 0 ) |= fill1;
+ *(unsigned long *) ((long) pdst + 8 ) |= fill1;
+ *(unsigned long *) ((long) pdst + 16) |= fill1;
+ *(unsigned long *) ((long) pdst + 24) |= fill1;
+ *(unsigned long *) ((long) pdst + 32) |= fill1;
+ *(unsigned long *) ((long) pdst + 40) |= fill1;
+ *(unsigned long *) ((long) pdst + 48) |= fill1;
+ *(unsigned long *) ((long) pdst + 56) |= fill1;
+
+ pdst += 64;
+ cur_count -= 64;
+ }
+
+ /* Perform trailing bits cleanup */
+ while (cur_count >= 8) {
+ *(unsigned long *) ((long) pdst + 0) |= fill1;
+ pdst += 8;
+ cur_count -= 8;
+ }
+#else
+ /*
+ * Perform bulk copy, knowing 0mod4 alignment
+ * Assumes 32-bit longs.
+ */
+
+ while (cur_count >= 32) {
+
+ /* Hand unrolled x8, assumes scheduler does a good job */
+ *(unsigned long *) ((long) pdst + 0 ) |= fill1;
+ *(unsigned long *) ((long) pdst + 4 ) |= fill1;
+ *(unsigned long *) ((long) pdst + 8 ) |= fill1;
+ *(unsigned long *) ((long) pdst + 12) |= fill1;
+ *(unsigned long *) ((long) pdst + 16) |= fill1;
+ *(unsigned long *) ((long) pdst + 20) |= fill1;
+ *(unsigned long *) ((long) pdst + 24) |= fill1;
+ *(unsigned long *) ((long) pdst + 28) |= fill1;
+
+ pdst += 32;
+ cur_count -= 32;
+ }
+
+ /* Perform trailing bits cleanup */
+ while (cur_count >= 4) {
+ *(unsigned long *) ((long) pdst + 0) |= fill1;
+ pdst += 4;
+ cur_count -= 4;
+ }
+#endif
+
+ if (cur_count >= 4) {
+ /* On 0mod4 boundary already */
+ *(unsigned int *) pdst |= tmpi;
+ pdst += 4;
+ cur_count -= 4;
+ }
+
+ if (cur_count >= 2) {
+ /* On 0mod2 boundary already */
+ *(unsigned short *) pdst |= tmph;
+ pdst += 2;
+ cur_count -= 2;
+ }
+
+ if (cur_count >= 1) {
+ /* last possible byte */
+ *(unsigned char *) pdst |= tmpb;
+ pdst++;
+ cur_count--;
+ }
+
+ /* Loop epilogue */
+/* assert(cur_count == 0); */
+ pdst += widthPitch;
+ hcount--;
+ }
+
+ return pdst;
+}
+
+/* fFillXor.s */
+
+unsigned char *fastFillSolidGXxor(
+ unsigned char *pdst,
+ unsigned long fill1,
+ unsigned long fill2,
+ int hcount,
+ int count,
+ int w,
+ int widthPitch
+)
+{
+ /*
+ * NOTES: original assembly code presumes hcount > 0 to start with
+ * New code assumes that all bytes of fill1, fill2 are
+ * consistent. i.e. 0xefefefef, and not 0x12345678.
+ * This is because the caller of this routine does a PFILL()
+ * of the [fill1, fill2] values before they get here.
+ * For large block cases (count > 3), the original code
+ * assumed that width == count.
+ * Fills hcount trips of count bytes each trip through loop
+ */
+
+ if (count == 0)
+ return pdst;
+
+ while (hcount > 0) {
+ /* No special 'fast' cases here */
+ int cur_count;
+ unsigned char tmpb = fill1;
+ unsigned short tmph = fill1;
+ unsigned int tmpi = fill1;
+
+ cur_count = count;
+
+ /* Fiddle with leading bits up to large block */
+ if (((long)pdst & 0x1) && cur_count >= 1) {
+ /* To next 0mod2 */
+ *(unsigned char *) pdst ^= tmpb;
+ pdst++;
+ cur_count--;
+ }
+
+ if (((long)pdst & 0x2) && cur_count >= 2) {
+ /* To next 0mod4 */
+ *(unsigned short *) pdst ^= tmph;
+ pdst += 2;
+ cur_count -= 2;
+ }
+
+ if (((long)pdst & 0x4) && cur_count >= 4) {
+ /* To next 0mod8 */
+ *(unsigned int *) pdst ^= tmpi;
+ pdst += 4;
+ cur_count -= 4;
+ }
+
+#if defined(__alpha__)
+ /*
+ * Perform bulk copy, knowing 0mod8 alignment
+ * Assumes 64-bit longs.
+ */
+
+ while (cur_count >= 64) {
+
+ /* Hand unrolled x8, assumes scheduler does a good job */
+ *(unsigned long *) ((long) pdst + 0 ) ^= fill1;
+ *(unsigned long *) ((long) pdst + 8 ) ^= fill1;
+ *(unsigned long *) ((long) pdst + 16) ^= fill1;
+ *(unsigned long *) ((long) pdst + 24) ^= fill1;
+ *(unsigned long *) ((long) pdst + 32) ^= fill1;
+ *(unsigned long *) ((long) pdst + 40) ^= fill1;
+ *(unsigned long *) ((long) pdst + 48) ^= fill1;
+ *(unsigned long *) ((long) pdst + 56) ^= fill1;
+
+ pdst += 64;
+ cur_count -= 64;
+ }
+
+ /* Perform trailing bits cleanup */
+ while (cur_count >= 8) {
+ *(unsigned long *) ((long) pdst + 0) ^= fill1;
+ pdst += 8;
+ cur_count -= 8;
+ }
+#else
+ /*
+ * Perform bulk copy, knowing 0mod4 alignment
+ * Assumes 32-bit longs.
+ */
+
+ while (cur_count >= 32) {
+
+ /* Hand unrolled x8, assumes scheduler does a good job */
+ *(unsigned long *) ((long) pdst + 0 ) ^= fill1;
+ *(unsigned long *) ((long) pdst + 4 ) ^= fill1;
+ *(unsigned long *) ((long) pdst + 8 ) ^= fill1;
+ *(unsigned long *) ((long) pdst + 12) ^= fill1;
+ *(unsigned long *) ((long) pdst + 16) ^= fill1;
+ *(unsigned long *) ((long) pdst + 20) ^= fill1;
+ *(unsigned long *) ((long) pdst + 24) ^= fill1;
+ *(unsigned long *) ((long) pdst + 28) ^= fill1;
+
+ pdst += 32;
+ cur_count -= 32;
+ }
+
+ /* Perform trailing bits cleanup */
+ while (cur_count >= 4) {
+ *(unsigned long *) ((long) pdst + 0) ^= fill1;
+ pdst += 4;
+ cur_count -= 4;
+ }
+#endif
+
+ if (cur_count >= 4) {
+ /* On 0mod4 boundary already */
+ *(unsigned int *) pdst ^= tmpi;
+ pdst += 4;
+ cur_count -= 4;
+ }
+
+ if (cur_count >= 2) {
+ /* On 0mod2 boundary already */
+ *(unsigned short *) pdst ^= tmph;
+ pdst += 2;
+ cur_count -= 2;
+ }
+
+ if (cur_count >= 1) {
+ /* last possible byte */
+ *(unsigned char *) pdst ^= tmpb;
+ pdst++;
+ cur_count--;
+ }
+
+ /* Loop epilogue */
+/* assert(cur_count == 0); */
+ pdst += widthPitch;
+ hcount--;
+ }
+
+ return pdst;
+}
+
+/* fFillCopy.s */
+
+unsigned char *fastFillSolidGXcopy(
+ unsigned char *pdst,
+ unsigned long fill1,
+ unsigned long fill2,
+ int hcount,
+ int count,
+ int w,
+ int widthPitch
+)
+{
+ /*
+ * NOTES: original assembly code presumes hcount > 0 to start with
+ * New code assumes that all bytes of fill1, fill2 are
+ * consistent. i.e. 0xefefefef, and not 0x12345678.
+ * This is because the caller of this routine does a PFILL()
+ * of the [fill1, fill2] values before they get here.
+ * For large block cases (count > 3), the original code
+ * assumed that width == count.
+ * Fills hcount trips of count bytes each trip through loop
+ */
+
+ if (count == 0)
+ return pdst;
+
+ while (hcount > 0) {
+ /* No special 'fast' cases here */
+ int cur_count;
+ unsigned char tmpb = fill1;
+ unsigned short tmph = fill1;
+ unsigned int tmpi = fill1;
+
+ cur_count = count;
+
+ /* Fiddle with leading bits up to large block */
+ if (((long)pdst & 0x1) && cur_count >= 1) {
+ /* To next 0mod2 */
+ *(unsigned char *) pdst = tmpb;
+ pdst++;
+ cur_count--;
+ }
+
+ if (((long)pdst & 0x2) && cur_count >= 2) {
+ /* To next 0mod4 */
+ *(unsigned short *) pdst = tmph;
+ pdst += 2;
+ cur_count -= 2;
+ }
+
+ if (((long)pdst & 0x4) && cur_count >= 4) {
+ /* To next 0mod8 */
+ *(unsigned int *) pdst = tmpi;
+ pdst += 4;
+ cur_count -= 4;
+ }
+
+#if defined(__alpha__)
+ /*
+ * Perform bulk copy, knowing 0mod8 alignment
+ * Assumes 64-bit longs.
+ */
+
+ while (cur_count >= 64) {
+
+ /* Hand unrolled x8, assumes scheduler does a good job */
+ *(unsigned long *) ((long) pdst + 0 ) = fill1;
+ *(unsigned long *) ((long) pdst + 8 ) = fill1;
+ *(unsigned long *) ((long) pdst + 16) = fill1;
+ *(unsigned long *) ((long) pdst + 24) = fill1;
+ *(unsigned long *) ((long) pdst + 32) = fill1;
+ *(unsigned long *) ((long) pdst + 40) = fill1;
+ *(unsigned long *) ((long) pdst + 48) = fill1;
+ *(unsigned long *) ((long) pdst + 56) = fill1;
+
+ pdst += 64;
+ cur_count -= 64;
+ }
+
+ /* Perform trailing bits cleanup */
+ while (cur_count >= 8) {
+ *(unsigned long *) ((long) pdst + 0) = fill1;
+ pdst += 8;
+ cur_count -= 8;
+ }
+#else
+ /*
+ * Perform bulk copy, knowing 0mod4 alignment
+ * Assumes 32-bit longs.
+ */
+
+ while (cur_count >= 32) {
+
+ /* Hand unrolled x8, assumes scheduler does a good job */
+ *(unsigned long *) ((long) pdst + 0 ) = fill1;
+ *(unsigned long *) ((long) pdst + 4 ) = fill1;
+ *(unsigned long *) ((long) pdst + 8 ) = fill1;
+ *(unsigned long *) ((long) pdst + 12) = fill1;
+ *(unsigned long *) ((long) pdst + 16) = fill1;
+ *(unsigned long *) ((long) pdst + 20) = fill1;
+ *(unsigned long *) ((long) pdst + 24) = fill1;
+ *(unsigned long *) ((long) pdst + 28) = fill1;
+
+ pdst += 32;
+ cur_count -= 32;
+ }
+ /* Perform trailing bits cleanup */
+ while (cur_count >= 4) {
+ *(unsigned long *) ((long) pdst + 0) = fill1;
+ pdst += 4;
+ cur_count -= 4;
+ }
+#endif
+
+ if (cur_count >= 4) {
+ /* On 0mod4 boundary already */
+ *(unsigned int *) pdst = tmpi;
+ pdst += 4;
+ cur_count -= 4;
+ }
+
+ if (cur_count >= 2) {
+ /* On 0mod2 boundary already */
+ *(unsigned short *) pdst = tmph;
+ pdst += 2;
+ cur_count -= 2;
+ }
+
+ if (cur_count >= 1) {
+ /* last possible byte */
+ *(unsigned char *) pdst = tmpb;
+ pdst++;
+ cur_count--;
+ }
+
+ /* Loop epilogue */
+/* assert(cur_count == 0); */
+ pdst += widthPitch;
+ hcount--;
+ }
+
+ return pdst;
+}
+
+/*
+ * Reverse engineered version of XFree86 code for fFillSet.s by
+ * Rick Gorton (gorton@tallis.enet.dec.com)
+ * This version should work well on strongly aligned RISC architectures
+ * in general. In particular, the even-odd trip performance problem
+ * with 'tribbleloop' is eliminated.
+ *
+ * Jay, please put the original header back in here...
+ */
+
+unsigned char *fastFillSolidGXset(
+ unsigned char *pdst,
+ unsigned long fill1,
+ unsigned long fill2,
+ int hcount,
+ int count,
+ int w,
+ int widthPitch)
+{
+ /*
+ * NOTES: original assembly code presumes hcount > 0 to start with
+ * New code assumes that all bytes of fill1, fill2 are
+ * consistent. i.e. 0xefefefef, and not 0x12345678.
+ * This is because the caller of this routine does a PFILL()
+ * of the [fill1, fill2] values before they get here.
+ * For large block cases (count > 3), the original code
+ * assumed that width == count.
+ * Fills hcount trips of count bytes each trip through loop
+ */
+
+ if (count == 0)
+ return pdst;
+
+ while (hcount > 0) {
+ /* No special 'fast' cases here */
+ int cur_count;
+ char tmpb;
+ short tmph;
+ int tmpi;
+
+ cur_count = count;
+
+ /* Fiddle with leading bits up to large block */
+ if (((long)pdst & 0x1) && cur_count >= 1) {
+ /* To next 0mod2 */
+ tmpb = *(unsigned char *) pdst;
+ tmpb = (tmpb & fill1) ^ fill2;
+ *(unsigned char *) pdst = tmpb;
+ pdst++;
+ cur_count--;
+ }
+
+ if (((long)pdst & 0x2) && cur_count >= 2) {
+ /* To next 0mod4 */
+ tmph = *(unsigned short *) pdst;
+ tmph = (tmph & fill1) ^ fill2;
+ *(unsigned short *) pdst = tmph;
+ pdst += 2;
+ cur_count -= 2;
+ }
+
+ if (((long)pdst & 0x4) && cur_count >= 4) {
+ /* To next 0mod8 */
+ tmpi = *(unsigned int *) pdst;
+ tmpi = (tmpi & fill1) ^ fill2;
+ *(unsigned int *) pdst = tmpi;
+ pdst += 4;
+ cur_count -= 4;
+ }
+
+#if defined(__alpha__)
+ /*
+ * Perform bulk copy, knowing 0mod8 alignment
+ * Assumes 64-bit longs.
+ */
+
+ while (cur_count >= 64) {
+ unsigned long tmp_1, tmp_2, tmp_3, tmp_4;
+ unsigned long tmp_5, tmp_6, tmp_7, tmp_8;
+
+ /* Hand unrolled x8, assumes scheduler does a good job */
+ tmp_1 = *(unsigned long *) ((long) pdst + 0);
+ tmp_2 = *(unsigned long *) ((long) pdst + 8);
+ tmp_3 = *(unsigned long *) ((long) pdst + 16);
+ tmp_4 = *(unsigned long *) ((long) pdst + 24);
+ tmp_5 = *(unsigned long *) ((long) pdst + 32);
+ tmp_6 = *(unsigned long *) ((long) pdst + 40);
+ tmp_7 = *(unsigned long *) ((long) pdst + 48);
+ tmp_8 = *(unsigned long *) ((long) pdst + 56);
+
+ tmp_1 = (fill1 & tmp_1) ^ fill2;
+ tmp_2 = (fill1 & tmp_2) ^ fill2;
+ tmp_3 = (fill1 & tmp_3) ^ fill2;
+ tmp_4 = (fill1 & tmp_4) ^ fill2;
+ tmp_5 = (fill1 & tmp_5) ^ fill2;
+ tmp_6 = (fill1 & tmp_6) ^ fill2;
+ tmp_7 = (fill1 & tmp_7) ^ fill2;
+ tmp_8 = (fill1 & tmp_8) ^ fill2;
+
+ *(unsigned long *) ((long) pdst + 0) = tmp_1;
+ *(unsigned long *) ((long) pdst + 8) = tmp_2;
+ *(unsigned long *) ((long) pdst + 16) = tmp_3;
+ *(unsigned long *) ((long) pdst + 24) = tmp_4;
+ *(unsigned long *) ((long) pdst + 32) = tmp_5;
+ *(unsigned long *) ((long) pdst + 40) = tmp_6;
+ *(unsigned long *) ((long) pdst + 48) = tmp_7;
+ *(unsigned long *) ((long) pdst + 56) = tmp_8;
+
+ pdst += 64;
+ cur_count -= 64;
+ }
+
+ /* Perform trailing bits cleanup */
+ while (cur_count >= 8) {
+ unsigned long tmpl;
+
+ tmpl = *(unsigned long *) ((long) pdst + 0);
+ tmpl = (tmpl & fill1) ^ fill2;
+ *(unsigned long *) ((long) pdst + 0) = tmpl;
+ pdst += 8;
+ cur_count -= 8;
+ }
+#else
+ /*
+ * Perform bulk copy, knowing 0mod4 alignment
+ * Assumes 32-bit longs.
+ */
+
+ while (cur_count >= 32) {
+ unsigned long tmp_1, tmp_2, tmp_3, tmp_4;
+ unsigned long tmp_5, tmp_6, tmp_7, tmp_8;
+
+ /* Hand unrolled x8, assumes scheduler does a good job */
+ tmp_1 = *(unsigned long *) ((long) pdst + 0);
+ tmp_2 = *(unsigned long *) ((long) pdst + 4);
+ tmp_3 = *(unsigned long *) ((long) pdst + 8 );
+ tmp_4 = *(unsigned long *) ((long) pdst + 12);
+ tmp_5 = *(unsigned long *) ((long) pdst + 16);
+ tmp_6 = *(unsigned long *) ((long) pdst + 20);
+ tmp_7 = *(unsigned long *) ((long) pdst + 24);
+ tmp_8 = *(unsigned long *) ((long) pdst + 28);
+
+ tmp_1 = (fill1 & tmp_1) ^ fill2;
+ tmp_2 = (fill1 & tmp_2) ^ fill2;
+ tmp_3 = (fill1 & tmp_3) ^ fill2;
+ tmp_4 = (fill1 & tmp_4) ^ fill2;
+ tmp_5 = (fill1 & tmp_5) ^ fill2;
+ tmp_6 = (fill1 & tmp_6) ^ fill2;
+ tmp_7 = (fill1 & tmp_7) ^ fill2;
+ tmp_8 = (fill1 & tmp_8) ^ fill2;
+
+ *(unsigned long *) ((long) pdst + 0) = tmp_1;
+ *(unsigned long *) ((long) pdst + 4) = tmp_2;
+ *(unsigned long *) ((long) pdst + 8 ) = tmp_3;
+ *(unsigned long *) ((long) pdst + 12) = tmp_4;
+ *(unsigned long *) ((long) pdst + 16) = tmp_5;
+ *(unsigned long *) ((long) pdst + 20) = tmp_6;
+ *(unsigned long *) ((long) pdst + 24) = tmp_7;
+ *(unsigned long *) ((long) pdst + 28) = tmp_8;
+
+ pdst += 32;
+ cur_count -= 32;
+ }
+ /* Perform trailing bits cleanup */
+ while (cur_count >= 4) {
+ unsigned long tmpl;
+
+ tmpl = *(unsigned long *) ((long) pdst + 0);
+ tmpl = (tmpl & fill1) ^ fill2;
+ *(unsigned long *) ((long) pdst + 0) = tmpl;
+ pdst += 4;
+ cur_count -= 4;
+ }
+#endif
+
+ if (cur_count >= 4) {
+ /* On 0mod4 boundary already */
+ tmpi = *(unsigned int *) pdst;
+ tmpi = (tmpi & fill1) ^ fill2;
+ *(unsigned int *) pdst = tmpi;
+ pdst += 4;
+ cur_count -= 4;
+ }
+
+ if (cur_count >= 2) {
+ /* On 0mod2 boundary already */
+ tmph = *(unsigned short *) pdst;
+ tmph = (tmph & fill1) ^ fill2;
+ *(unsigned short *) pdst = tmph;
+ pdst += 2;
+ cur_count -= 2;
+ }
+
+ if (cur_count >= 1) {
+ /* last possible byte */
+ tmpb = *(unsigned char *) pdst;
+ tmpb = (tmpb & fill1) ^ fill2;
+ *(unsigned char *) pdst = tmpb;
+ pdst++;
+ cur_count--;
+ }
+
+ /* Loop epilogue */
+/* assert(cur_count == 0); */
+ pdst += widthPitch;
+ hcount--;
+ }
+
+ return pdst;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaFasm.h b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaFasm.h
new file mode 100644
index 000000000..eace3032c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaFasm.h
@@ -0,0 +1,318 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaFasm.h,v 1.2 1998/07/25 16:58:33 dawes Exp $ */
+/* Copyright 1992 by James Tsillas, Arlington, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation.
+
+JAMES TSILLAS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+*/
+/* $XConsortium: vgaFasm.h /main/7 1996/10/25 10:34:03 kaleb $ */
+
+#include "fastblt.h"
+
+
+#ifndef RROP_NAME_CAT
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) || (defined (sun) && defined (__STDC__) && !defined (__GNUC__))
+#define RROP_NAME_CAT(prefix,suffix) prefix##suffix
+#else
+#define RROP_NAME_CAT(prefix,suffix) prefix/**/suffix
+#endif
+#endif
+
+#define fCopyAL1_C(psrc, pdst, nl, srcR, widS, psrcS) \
+ while (nl) { \
+ fnl = nl; \
+ if (fnl > srcR) fnl = srcR; \
+ nl -= fnl; srcR -= fnl; \
+ DuffL ( fnl, label00, \
+ *pdst = MROP_SOLID (*psrc, *pdst); \
+ pdst++; psrc++; ) \
+ if (!srcR) { \
+ srcR = widS; \
+ psrc = psrcS; } \
+ }
+#define fCopyAL2_C(psrc, pdst, nl, srcR, widS, psrcS) \
+ while (nl) { \
+ fnl = nl; \
+ if (fnl > srcR) fnl = srcR; \
+ nl -= fnl; srcR -= fnl; \
+ DuffL ( fnl, label01, \
+ *pdst = MROP_SOLID (*psrc, *pdst); \
+ pdst++; psrc++; ) \
+ if (!srcR) { \
+ srcR = widS; \
+ psrc = psrcS; } \
+ }
+#define fCopyAL3_C(psrc, pdst, nl, srcR, widS, psrcS) \
+ while (nl) { \
+ fnl = nl; \
+ if (fnl > srcR) fnl = srcR; \
+ nl -= fnl; srcR -= fnl; \
+ DuffL ( fnl, label02, \
+ *pdst = MROP_SOLID (*psrc, *pdst); \
+ pdst++; psrc++; ) \
+ if (!srcR) { \
+ srcR = widS; \
+ psrc = psrcS; } \
+ }
+#define fCopyUL_C(psrc, pdst, bits, lShift, rShift) \
+ bits1 = BitLeft(bits, (leftShift)); bits = *psrc++; \
+ *pdst = MROP_SOLID (bits1 | \
+ BitRight(bits, (rightShift)), *pdst); \
+ pdst++;
+
+/* The in-line assembler here only works for gcc2 */
+#if __GNUC__ > 1 && defined(__STDC__) && defined(i386)
+#define ESI __asm__ ("esi")
+#define EDI __asm__ ("edi")
+
+#define fBitBltC(xdir, dst, src, w, count, sP, dP) \
+ __asm__ __volatile__ ("pushl %8 \n\
+ pushl %7 \n\
+ pushl %6 \n\
+ pushl %5 \n\
+ pushl %4 \n\
+ call fastBitBltCopy \n\
+ addl $16, %%esp" \
+ : "=D" (/*(unsigned char *)*/ (dst)), \
+ "=S" (/*(unsigned char *)*/ (src)) \
+ : "D0" ((unsigned char *) (dst)), \
+ "S1" ((unsigned char *) (src)), \
+ "g" ((unsigned int) (xdir)), \
+ "g" ((unsigned int) (w)), \
+ "g" ((unsigned int) (count)), \
+ "g" ((unsigned int) (sP)), \
+ "g" ((unsigned int) (dP)) \
+ : "edx", "ecx", "eax");
+
+#if MROP == Mcopy
+#define CLD __asm__ __volatile__ ("cld")
+#define fCopyAL1_X(psrc, pdst, nl, srcR, widS, psrcS, rep) \
+ __asm__ __volatile__ (".label00: orl %6, %6 \n\
+ jz .label02 \n\
+ movl %6, %%ecx \n\
+ cmpl %%ecx, %2 \n\
+ ja .label01 \n\
+ movl %2, %%ecx \n\
+ .label01: subl %%ecx, %6 \n\
+ subl %%ecx, %2 \n"\
+ ##rep## \
+ "movsl \n\
+ orl %2, %2 \n\
+ jnz .label00 \n\
+ movl %7, %2 \n\
+ movl %8, %0 \n\
+ jmp .label00 \n\
+ .label02:" \
+ : "=S" (/*(unsigned long *)*/ (psrc)), \
+ "=D" (/*(unsigned long *)*/ (pdst)), \
+ "=b" (/*(unsigned int)*/ (srcR)) \
+ : "S0" ((unsigned long *) (psrc)), \
+ "D1" ((unsigned long *) (pdst)), \
+ "b2" ((unsigned int) (srcR)), \
+ "d" ((unsigned int) (nl)), \
+ "g" ((unsigned int) (widS)), \
+ "g" ((unsigned long *) (psrcS)) \
+ : "ecx");
+#ifdef GCCUSESGAS
+#define fCopyAL1(psrc, pdst, nl, srcR, widS, psrcS) \
+ fCopyAL1_X((psrc),(pdst),(nl),(srcR),(widS),(psrcS), \
+ "repe\n");
+#else
+#define fCopyAL1(psrc, pdst, nl, srcR, widS, psrcS) \
+ fCopyAL1_X((psrc),(pdst),(nl),(srcR),(widS),(psrcS), \
+ "repz\n");
+#endif
+#define fCopyAL2_X(psrc, pdst, nl, srcR, widS, psrcS, rep) \
+ __asm__ __volatile__ (".label10: orl %6, %6 \n\
+ jz .label12 \n\
+ movl %6, %%ecx \n\
+ cmpl %%ecx, %2 \n\
+ ja .label11 \n\
+ movl %2, %%ecx \n\
+ .label11: subl %%ecx, %6 \n\
+ subl %%ecx, %2 \n"\
+ ##rep## \
+ "movsl \n\
+ orl %2, %2 \n\
+ jnz .label10 \n\
+ movl %7, %2 \n\
+ movl %8, %0 \n\
+ jmp .label10 \n\
+ .label12:" \
+ : "=S" (/*(unsigned long *)*/ (psrc)), \
+ "=D" (/*(unsigned long *)*/ (pdst)), \
+ "=b" (/*(unsigned int)*/ (srcR)) \
+ : "S0" ((unsigned long *) (psrc)), \
+ "D1" ((unsigned long *) (pdst)), \
+ "b2" ((unsigned int) (srcR)), \
+ "d" ((unsigned int) (nl)), \
+ "g" ((unsigned int) (widS)), \
+ "g" ((unsigned long *) (psrcS)) \
+ : "ecx");
+#ifdef GCCUSESGAS
+#define fCopyAL2(psrc, pdst, nl, srcR, widS, psrcS) \
+ fCopyAL2_X((psrc),(pdst),(nl),(srcR),(widS),(psrcS), \
+ "repe\n");
+#else
+#define fCopyAL2(psrc, pdst, nl, srcR, widS, psrcS) \
+ fCopyAL2_X((psrc),(pdst),(nl),(srcR),(widS),(psrcS), \
+ "repz\n");
+#endif
+#define fCopyAL3_X(psrc, pdst, nl, srcR, widS, psrcS, rep) \
+ __asm__ __volatile__ (".label20: orl %6, %6 \n\
+ jz .label22 \n\
+ movl %6, %%ecx \n\
+ cmpl %%ecx, %2 \n\
+ ja .label21 \n\
+ movl %2, %%ecx \n\
+ .label21: subl %%ecx, %6 \n\
+ subl %%ecx, %2 \n"\
+ ##rep## \
+ "movsl \n\
+ orl %2, %2 \n\
+ jnz .label20 \n\
+ movl %7, %2 \n\
+ movl %8, %0 \n\
+ jmp .label20 \n\
+ .label22:" \
+ : "=S" (/*(unsigned long *)*/ (psrc)), \
+ "=D" (/*(unsigned long *)*/ (pdst)), \
+ "=b" (/*(unsigned int)*/ (srcR)) \
+ : "S0" ((unsigned long *) (psrc)), \
+ "D1" ((unsigned long *) (pdst)), \
+ "b2" ((unsigned int) (srcR)), \
+ "d" ((unsigned int) (nl)), \
+ "g" ((unsigned int) (widS)), \
+ "g" ((unsigned long *) (psrcS)) \
+ : "ecx");
+#ifdef GCCUSESGAS
+#define fCopyAL3(psrc, pdst, nl, srcR, widS, psrcS) \
+ fCopyAL3_X((psrc),(pdst),(nl),(srcR),(widS),(psrcS), \
+ "repe\n");
+#else
+#define fCopyAL3(psrc, pdst, nl, srcR, widS, psrcS) \
+ fCopyAL3_X((psrc),(pdst),(nl),(srcR),(widS),(psrcS), \
+ "repz\n");
+#endif
+#define fCopyUL(psrc, pdst, bits, lShift, rShift) \
+ __asm__ __volatile__ (" movl %4, %%edx \n\
+ movl %5, %%ecx \n\
+ shrl %%cl, %%edx \n\
+ lodsl \n\
+ movl %%eax, %4 \n\
+ movl %6, %%ecx \n\
+ shll %%cl, %%eax \n\
+ orl %%edx, %%eax \n\
+ stosl" \
+ : "=S" (/*(unsigned long *)*/ (psrc)), \
+ "=D" (/*(unsigned long *)*/ (pdst)) \
+ : "S0" ((unsigned long *) (psrc)), \
+ "D1" ((unsigned long *) (pdst)), \
+ "g" ((unsigned long) (bits)), \
+ "g" ((unsigned long) (lShift)), \
+ "g" ((unsigned long) (rShift)) \
+ : "edx", "ecx", "eax");
+#elif !defined(RROP)
+#define fCopyAL1(psrc, pdst, nl, srcR, widS, psrcS) \
+ fCopyAL1_C((psrc),(pdst),(nl),(srcR),(widS),(psrcS))
+#define fCopyAL2(psrc, pdst, nl, srcR, widS, psrcS) \
+ fCopyAL2_C((psrc),(pdst),(nl),(srcR),(widS),(psrcS))
+#define fCopyAL3(psrc, pdst, nl, srcR, widS, psrcS) \
+ fCopyAL3_C((psrc),(pdst),(nl),(srcR),(widS),(psrcS))
+#define fCopyUL(psrc, pdst, bits, lShift, rShift) \
+ fCopyUL_C((psrc),(pdst),(bits),(lShift),(rShift))
+#define CLD
+#endif /* Mcopy */
+#if RROP == GXcopy
+#define CLD __asm__ __volatile__ ("cld")
+#define RROP_SOLID_L_X(pdst, nl, fill, rep) \
+ __asm__ __volatile__ ( rep## \
+ "stosl" \
+ : "=D" (/*(unsigned long *)*/ (pdst)) \
+ : "D0" ((unsigned long *) (pdst)), \
+ "c" ((unsigned long) (nl)), \
+ "a" ((unsigned long) (fill)));
+#ifdef GCCUSESGAS
+#define RROP_SOLID_L(pdst, nl, fill) \
+ RROP_SOLID_L_X((pdst),(nl),(fill),"repe\n")
+#else
+#define RROP_SOLID_L(pdst, nl, fill) \
+ RROP_SOLID_L_X((pdst),(nl),(fill),"repz\n")
+#endif
+#define RROP_SPAN_STD(pdst, nlm, dummy) \
+__extension__ ({ \
+ __label__ label1; \
+ if (!vgaWriteFlag) goto label1; \
+ nl = min(nlm, (unsigned long *) vgaWriteTop - \
+ (unsigned long *) pdst); \
+ nlm -= nl; \
+ RROP_SOLID_L(pdst, nl, rrop_xor); \
+ if (nlm) { \
+ pdst = vgaReadWriteNext(pdst); \
+ label1: \
+ RROP_SOLID_L (pdst, nlm, rrop_xor); \
+ } \
+})
+#elif !defined(MROP)
+#define RROP_SOLID_L(pdst, nlm, label) \
+ DuffL(nlm, label, RROP_SOLID(pdst); pdst++;)
+#define RROP_SPAN_STD(pdst, nlm, dummy) \
+__extension__ ({ \
+ __label__ label1, label2, label3; \
+ if (!vgaWriteFlag) goto label1; \
+ nl = min(nlm, (unsigned long *) vgaWriteTop - \
+ (unsigned long *) pdst); \
+ nlm -= nl; \
+ RROP_SOLID_L(pdst, nl, label2); \
+ if (nlm) { \
+ pdst = vgaReadWriteNext(pdst); \
+ label1: \
+ RROP_SOLID_L(pdst, nlm, label3); \
+ } \
+})
+#endif
+
+#else /* __GNUC__ > 1 */
+
+#define ESI
+#define EDI
+#define CLD
+#define fCopyAL1(psrc, pdst, nl, srcR, widS, psrcS) \
+ fCopyAL1_C((psrc),(pdst),(nl),(srcR),(widS),(psrcS))
+#define fCopyAL2(psrc, pdst, nl, srcR, widS, psrcS) \
+ fCopyAL2_C((psrc),(pdst),(nl),(srcR),(widS),(psrcS))
+#define fCopyAL3(psrc, pdst, nl, srcR, widS, psrcS) \
+ fCopyAL3_C((psrc),(pdst),(nl),(srcR),(widS),(psrcS))
+#define fCopyUL(psrc, pdst, bits, lShift, rShift) \
+ fCopyUL_C((psrc),(pdst),(bits),(lShift),(rShift))
+
+#define RROP_SOLID_L(pdst, nlm, label) \
+ DuffL(nlm, label, RROP_SOLID(pdst); pdst++;)
+#define RROP_SPAN_STD(pdst, nlm, dummy) \
+{ \
+ if (!vgaWriteFlag) goto RROP_NAME_CAT(_X_l1,dummy); \
+ nl = min(nlm, (unsigned long *) vgaWriteTop - \
+ (unsigned long *) pdst); \
+ nlm -= nl; \
+ RROP_SOLID_L(pdst, nl, RROP_NAME_CAT(_X_l2,dummy)); \
+ if (nlm) { \
+ pdst = vgaReadWriteNext(pdst); \
+ RROP_NAME_CAT(_X_l1,dummy): \
+ RROP_SOLID_L(pdst, nlm, RROP_NAME_CAT(_X_l3,dummy)); \
+ } \
+}
+
+#endif /* __GNUC__ > 1 */
+
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaLinec.c b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaLinec.c
new file mode 100644
index 000000000..cb487e433
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaLinec.c
@@ -0,0 +1,71 @@
+/*
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/enhanced/vgaLinec.c,v 1.2 1998/07/25 16:58:33 dawes Exp $ */
+
+#include "X.h"
+#include "misc.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86_HWlib.h"
+
+#include "vga.h"
+#include "cfb.h"
+
+/* vgabres.s */
+void fastvga256BresS(
+ int alu,
+ unsigned long and,
+ unsigned long xor,
+ unsigned long *addrl,
+ int nlwidth,
+ register int signdx,
+ int signdy,
+ int axis,
+ int x,
+ int y,
+ register int e,
+ register int e1,
+ int e2,
+ int len
+)
+{
+ SETRW(addrl);
+ cfbBresS(alu,and,xor,addrl,nlwidth,signdx,signdy,axis,x,y,e,e1,e2,len);
+}
+
+/* vgalineH.s */
+int fastvga256HorzS(
+ int alu,
+ unsigned long and,
+ register unsigned long xor,
+ register unsigned long *addrl,
+ int nlwidth,
+ int x,
+ int y,
+ int len
+)
+{
+ SETRW(addrl);
+ cfbHorzS(alu,and,xor,addrl,nlwidth,x,y,len);
+}
+
+/* vgalineV.s */
+int fastvga256VertS(
+ int alu,
+ unsigned long and,
+ unsigned long xor,
+ unsigned long *addrl,
+ int nlwidth,
+ int x,
+ int y,
+ register int len
+)
+{
+ SETRW(addrl);
+ cfbVertS(alu,and,xor,addrl,nlwidth,x,y,len);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vga8cppl.c b/xc/programs/Xserver/hw/xfree86/vgafb/vga8cppl.c
new file mode 100644
index 000000000..eca4a291e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vga8cppl.c
@@ -0,0 +1,232 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vga8cppl.c,v 1.2 1998/07/25 16:58:12 dawes Exp $ */
+/*
+ *
+Copyright (c) 1990 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+/* $XConsortium: vga8cppl.c /main/3 1996/02/21 18:09:56 kaleb $ */
+
+#define NO_CFBMSKBITS
+#include "vgafb.h"
+#undef PSZ
+#undef BitLeft
+#undef BitRight
+#include "maskbits.h"
+#include "mergerop.h"
+
+#if BITMAP_BIT_ORDER == MSBFirst
+#define LeftMost (MFB_PPW-1)
+#define StepBit(bit, inc) ((bit) -= (inc))
+#else
+#define LeftMost 0
+#define StepBit(bit, inc) ((bit) += (inc))
+#endif
+
+#define GetBits(psrc, nBits, curBit, bitPos, bits) {\
+ bits = 0; \
+ while (nBits--) \
+ { \
+ bits |= (PixelType)(((*psrc++ >> bitPos) & 1)) << curBit; \
+ StepBit (curBit, 1); \
+ CHECKRWO(psrc); \
+ } \
+}
+
+void
+vga256CopyImagePlane (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, planemask)
+ DrawablePtr pSrcDrawable;
+ DrawablePtr pDstDrawable;
+ int rop;
+ unsigned long planemask;
+ RegionPtr prgnDst;
+ DDXPointPtr pptSrc;
+{
+ vga256CopyPlane8to1 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc,
+ (unsigned long) ~0L, planemask);
+}
+
+void
+vga256CopyPlane8to1 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, planemask, bitPlane)
+ DrawablePtr pSrcDrawable;
+ DrawablePtr pDstDrawable;
+ int rop;
+ RegionPtr prgnDst;
+ DDXPointPtr pptSrc;
+ unsigned long planemask;
+ unsigned long bitPlane;
+{
+ int srcx, srcy, dstx, dsty, width, height;
+ unsigned char *psrcBase;
+ PixelType *pdstBase;
+ int widthSrc, widthDst;
+ unsigned char *psrcLine;
+ PixelType *pdstLine;
+ register unsigned char *psrc;
+ register int i;
+ register int curBit;
+ register int bitPos;
+ register unsigned long bits;
+ register PixelType *pdst;
+ PixelType startmask, endmask;
+ int niStart, niEnd;
+ int bitStart, bitEnd;
+ int nl, nlMiddle;
+ int nbox;
+ BoxPtr pbox;
+ MROP_DECLARE()
+
+ /*
+ * If nothing is going to touch the frame buffer, then just use
+ * the regular cfb routines. They should be faster.
+ */
+ if ( (pSrcDrawable->type != DRAWABLE_WINDOW) &&
+ (pDstDrawable->type != DRAWABLE_WINDOW))
+ {
+ cfbCopyPlane8to1(pSrcDrawable, pDstDrawable,
+ rop, prgnDst, pptSrc, planemask, bitPlane);
+ return;
+ }
+
+ if (!(planemask & 1))
+ return;
+
+ if (rop != GXcopy)
+ MROP_INITIALIZE (rop, planemask);
+
+ cfbGetByteWidthAndPointer (pSrcDrawable, widthSrc, psrcBase)
+
+ mfbGetPixelWidthAndPointer (pDstDrawable, widthDst, pdstBase)
+
+ BANK_FLAG(psrcBase)
+
+ bitPos = xf86ffs (bitPlane) - 1;
+
+ nbox = REGION_NUM_RECTS(prgnDst);
+ pbox = REGION_RECTS(prgnDst);
+ while (nbox--)
+ {
+ dstx = pbox->x1;
+ dsty = pbox->y1;
+ srcx = pptSrc->x;
+ srcy = pptSrc->y;
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+ pbox++;
+ pptSrc++;
+ psrcLine = psrcBase + srcy * widthSrc + srcx;
+ pdstLine = mfbScanline(pdstBase, dstx, dsty, widthDst);
+ dstx &= MFB_PIM;
+ if (dstx + width <= MFB_PPW)
+ {
+ maskpartialbits(dstx, width, startmask);
+ nlMiddle = 0;
+ endmask = 0;
+ }
+ else
+ {
+ maskbits (dstx, width, startmask, endmask, nlMiddle);
+ }
+ if (startmask)
+ {
+ niStart = min(MFB_PPW - dstx, width);
+ bitStart = LeftMost;
+ StepBit (bitStart, dstx);
+ }
+ if (endmask)
+ {
+ niEnd = (dstx + width) & MFB_PIM;
+ bitEnd = LeftMost;
+ }
+ if (rop == GXcopy)
+ {
+ while (height--)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ psrcLine += widthSrc;
+ mfbScanlineInc(pdstLine, widthDst);
+ SETRW(psrc);
+ if (startmask)
+ {
+ i = niStart;
+ curBit = bitStart;
+ GetBits (psrc, i, curBit, bitPos, bits);
+ *pdst = *pdst & ~startmask | bits;
+ pdst++;
+ }
+ nl = nlMiddle;
+ while (nl--)
+ {
+ i = MFB_PPW;
+ curBit = LeftMost;
+ GetBits (psrc, i, curBit, bitPos, bits);
+ *pdst++ = bits;
+ }
+ if (endmask)
+ {
+ i = niEnd;
+ curBit = bitEnd;
+ GetBits (psrc, i, curBit, bitPos, bits);
+ *pdst = *pdst & ~endmask | bits;
+ }
+ }
+ }
+ else
+ {
+ while (height--)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ psrcLine += widthSrc;
+ mfbScanlineInc(pdstLine, widthDst);
+ SETRW(psrc);
+ if (startmask)
+ {
+ i = niStart;
+ curBit = bitStart;
+ GetBits (psrc, i, curBit, bitPos, bits);
+ *pdst = MROP_MASK(bits, *pdst, startmask);
+ pdst++;
+ }
+ nl = nlMiddle;
+ while (nl--)
+ {
+ i = MFB_PPW;
+ curBit = LeftMost;
+ GetBits (psrc, i, curBit, bitPos, bits);
+ *pdst = MROP_SOLID(bits, *pdst);
+ pdst++;
+ }
+ if (endmask)
+ {
+ i = niEnd;
+ curBit = bitEnd;
+ GetBits (psrc, i, curBit, bitPos, bits);
+ *pdst = MROP_MASK (bits, *pdst, endmask);
+ }
+ }
+ }
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgaAsm.h b/xc/programs/Xserver/hw/xfree86/vgafb/vgaAsm.h
new file mode 100644
index 000000000..d8c71a39c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgaAsm.h
@@ -0,0 +1,16 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgaAsm.h,v 1.2 1998/07/25 16:58:13 dawes Exp $ */
+
+
+
+
+
+/* $XConsortium: vgaAsm.h /main/6 1996/02/21 18:10:00 kaleb $ */
+
+/* Definitions for VGA bank assembler routines */
+
+#ifdef CSRG_BASED
+#define VGABASE CONST(0xFF000000)
+#else
+#define VGABASE CONST(0xF0000000)
+#endif
+
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgaBank.h b/xc/programs/Xserver/hw/xfree86/vgafb/vgaBank.h
new file mode 100644
index 000000000..7757467e0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgaBank.h
@@ -0,0 +1,250 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgaBank.h,v 1.2 1998/07/25 16:58:13 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Roell not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Roell makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Thomas Roell, roell@informatik.tu-muenchen.de
+ *
+ */
+/* $XConsortium: vgaBank.h /main/7 1996/02/21 18:10:03 kaleb $ */
+
+#ifndef VGA_BANK_H
+#define VGA_BANK_H
+
+extern void *vgaReadBottom;
+extern void *vgaReadTop;
+extern void *vgaWriteBottom;
+extern void *vgaWriteTop;
+extern Bool vgaReadFlag, vgaWriteFlag;
+#if defined(__alpha__) || defined(__powerpc__)
+extern unsigned long writeseg;
+#else /* __alpha__ */
+extern void *writeseg;
+#endif /* __alpha__ */
+
+/* vgaBank.s or vgaBankc.c */
+
+void *vgaSetReadWrite(
+#if NeedFunctionPrototypes
+ void *
+#endif
+);
+
+#if !defined(__alpha__) && !defined(__powerpc__)
+void *vga16SetReadWrite(
+#if NeedFunctionPrototypes
+ void *
+#endif
+);
+#endif
+
+void *vgaReadWriteNext(
+#if NeedFunctionPrototypes
+ void *
+#endif
+);
+
+void *vgaReadWritePrev(
+#if NeedFunctionPrototypes
+ void *
+#endif
+);
+
+void *vgaSetRead(
+#if NeedFunctionPrototypes
+ void *
+#endif
+);
+
+#if !defined(__alpha__) && !defined(__powerpc__)
+void *vga16SetRead(
+#if NeedFunctionPrototypes
+ void *
+#endif
+);
+#endif
+
+void *vgaReadNext(
+#if NeedFunctionPrototypes
+ void *
+#endif
+);
+
+void *vgaReadPrev(
+#if NeedFunctionPrototypes
+ void *
+#endif
+);
+
+void *vgaSetWrite(
+#if NeedFunctionPrototypes
+ void *
+#endif
+);
+
+#if !defined(__alpha__) && !defined(__powerpc__)
+void *vga16SetWrite(
+#if NeedFunctionPrototypes
+ void *
+#endif
+);
+#endif
+
+void *vgaWriteNext(
+#if NeedFunctionPrototypes
+ void *
+#endif
+);
+
+void *vgaWritePrev(
+#if NeedFunctionPrototypes
+ void *
+#endif
+);
+
+void vgaSaveBank(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+void vgaRestoreBank(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+void vgaPushRead(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+void vgaPopRead(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+void vgaSetVidPage(
+#if NeedFunctionPrototypes
+ int
+#endif
+);
+
+extern int vgaSegmentMask;
+
+extern void SpeedUpComputeNext(
+#if NeedFunctionPrototypes
+ unsigned,
+ unsigned
+#endif
+);
+
+extern void SpeedUpComputePrev(
+#if NeedFunctionPrototypes
+ unsigned,
+ unsigned
+#endif
+);
+
+extern unsigned SpeedUpRowsNext[];
+extern unsigned SpeedUpRowsPrev[];
+
+
+#ifdef CSRG_BASED
+#define VGABASE 0xFF000000
+#else
+#if defined(__alpha__)
+#define VGABASE 0xFFFFFFFFF0000000UL
+#else /* __alpha__ */
+#define VGABASE 0xF0000000
+#endif /* __alpha__ */
+#endif
+
+/* Clear these first -- since they are defined in mfbcustom.h */
+#undef CHECKSCREEN
+#undef SETRWF
+#undef CHECKRWOF
+#undef CHECKRWUF
+#undef BANK_FLAG
+#undef BANK_FLAG_BOTH
+#undef SETR
+#undef SETW
+#undef SETRW
+#undef CHECKRO
+#undef CHECKWO
+#undef CHECKRWO
+#undef CHECKRU
+#undef CHECKWU
+#undef CHECKRWU
+#undef NEXTR
+#undef NEXTW
+#undef PREVR
+#undef PREVW
+#undef SAVE_BANK
+#undef RESTORE_BANK
+#undef PUSHR
+#undef POPR
+
+#define CHECKSCREEN(x) (((unsigned long)(x) >= VGABASE) ? TRUE : FALSE)
+
+#define SETRWF(f,x) { if(f) x = vgaSetReadWrite(x); }
+#define CHECKRWOF(f,x) { if(f && ((void *)x >= vgaWriteTop)) \
+ x = vgaReadWriteNext(x); }
+#define CHECKRWUF(f,x) { if(f && ((void *)x < vgaWriteBottom)) \
+ x = vgaReadWritePrev(x); }
+#define BANK_FLAG(a) \
+ vgaWriteFlag = CHECKSCREEN((a)); \
+ vgaReadFlag = FALSE;
+
+#define BANK_FLAG_BOTH(a,b) \
+ vgaReadFlag = CHECKSCREEN((a)); \
+ vgaWriteFlag = CHECKSCREEN((b));
+
+#define SETR(x) { if(vgaReadFlag) x = vgaSetRead(x); }
+#define SETW(x) { if(vgaWriteFlag) x = vgaSetWrite(x); }
+#define SETRW(x) { if(vgaWriteFlag) x = vgaSetReadWrite(x); }
+#define CHECKRO(x) { if(vgaReadFlag && ((void *)x >= vgaReadTop)) \
+ x = vgaReadNext(x); }
+#define CHECKRU(x) { if(vgaReadFlag && ((void *)x < vgaReadBottom)) \
+ x = vgaReadPrev(x); }
+#define CHECKWO(x) { if(vgaWriteFlag && ((void *)x >= vgaWriteTop)) \
+ x = vgaWriteNext(x); }
+#define CHECKWU(x) { if(vgaWriteFlag && ((void *)x < vgaWriteBottom)) \
+ x = vgaWritePrev(x); }
+#define CHECKRWO(x) { if(vgaWriteFlag && ((void *)x >= vgaWriteTop)) \
+ x = vgaReadWriteNext(x); }
+#define CHECKRWU(x) { if(vgaWriteFlag && ((void *)x < vgaWriteBottom)) \
+ x = vgaReadWritePrev(x); }
+
+#define NEXTR(x) { x = vgaReadNext(x);}
+#define NEXTW(x) { x = vgaWriteNext(x); }
+#define PREVR(x) { x = vgaReadPrev(x); }
+#define PREVW(x) { x = vgaWritePrev(x); }
+
+#define SAVE_BANK() { if (vgaWriteFlag) vgaSaveBank(); }
+#define RESTORE_BANK() { if (vgaWriteFlag) vgaRestoreBank(); }
+
+#define PUSHR() { if(vgaWriteFlag) vgaPushRead(); }
+#define POPR() { if(vgaWriteFlag) vgaPopRead(); }
+
+
+#endif /* VGA_BANK_H */
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgaBank.s b/xc/programs/Xserver/hw/xfree86/vgafb/vgaBank.s
new file mode 100644
index 000000000..2f82d3687
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgaBank.s
@@ -0,0 +1,650 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgaBank.s,v 1.2 1998/07/25 16:58:13 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Roell not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Roell makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Thomas Roell, roell@informatik.tu-muenchen.de
+ *
+ */
+/* $XConsortium: vgaBank.s /main/7 1996/02/21 18:10:07 kaleb $ */
+
+#include "assyntax.h"
+
+ FILE("vgaBank.s")
+ AS_BEGIN
+
+/*
+ * Because a modern VGA has more than 128kBytes (which are mappable into the
+ * 386' memory some logic is required. The VGA's memory (logical VGA
+ * address space) is devided into smaller parts (called logical segments).
+ * These segments are mapped to logical areas.
+ *
+ * There are there different logical mapping areas:
+ *
+ * Read: an area which can be read from
+ * Write: an area which can be written to
+ * ReadWrite: here is both read an write possible
+ *
+ * It is permissable to use simultaneously a Read and a Write, but you can use
+ * ReadWrite only as a single.
+ * For example the bitblitting code uses a Read area as source and a Write
+ * area as destination. Most other routines use only a ReadWrite.
+ *
+ * A logical mapping area is described by some parameters (here I will for
+ * example describe a Read area:
+ *
+ * ReadBottom lowest accessable byte relative to the beginning of the
+ * VGA boards mapped memory.
+ *
+ * ReadTop highes accessable byte plus one.
+ *
+ * SegmentSize size of such an mapped area (common for all three)
+ *
+ * SegmentShift log2(SegmentSize) (used to compute the logical segment)
+ *
+ * SegmentMask SegmentSize - 1 (used to mask the offset inter an area)
+ *
+ *
+ * All that the following routines are doing is computing for a given offset
+ * into the logical VGA adress space the offset into such an logical area
+ * and the logical segment number. By the way they call also the VGA board's
+ * driver to set up the VGA's physical memory mapping according to the logical
+ * that was requested by the calliie.
+ *
+ * For shake of simplicity Write and ReadWrite share the same Bottom & Top.
+ * NOTE: Read & Write may have differnt starting addresses, or even common.
+ *
+ * There are multible routines present for the same effect. This was made
+ * for effectivly interface lowlevel assembly language best.
+ */
+
+/*
+ * BUGALERT: this should be gotten from vga.h. But since there some C lang.
+ * things, too ...
+ */
+
+#include "vgaAsm.h"
+
+
+ SEG_DATA
+ GLOBL GLNAME(writeseg)
+#ifdef PC98_PEGC
+ GLOBL GLNAME(readseg) /* PC98_PEGC */
+#endif
+GLNAME(writeseg):
+ D_LONG 0
+GLNAME(readseg):
+ D_LONG 0
+GLNAME(saveseg):
+ D_LONG 0
+
+ SEG_TEXT
+/*
+ *-----------------------------------------------------------------------
+ * vgaSetReadWrite ---
+ * select a memory bank of the VGA board for read & write access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ * pointer
+ * vgaSetReadWrite(p)
+ * register pointer p;
+ * {
+ * #ifdef XF86VGA16
+ * writeseg = ((unsigned long)p - vgaBase) >> vgaSegmentShift;
+ * (vgaSetReadWriteFunc)(writeseg);
+ * return (vgaWriteBottom + (((unsigned int)p - vgaBase) & vgaSegmentMask));
+ * #else
+ * writeseg = ((unsigned long)p - VGABASE) >> vgaSegmentShift;
+ * (vgaSetReadWriteFunc)(writeseg);
+ * return (vgaWriteBottom + ((unsigned int)p & vgaSegmentMask));
+ * #endif
+ * }
+ *
+ *
+ * since we now have 1/4/8bpp in the same binary, we need to have
+ * both versions of the function in here
+ */
+ ALIGNTEXT4
+ GLOBL GLNAME(vgaSetReadWrite)
+GLNAME(vgaSetReadWrite):
+ MOV_L (REGOFF(4,ESP),EAX)
+ PUSH_L (ECX)
+ PUSH_L (EDX)
+ SUB_L (VGABASE,EAX)
+ MOV_L (CONTENT(GLNAME(vgaSegmentShift)),ECX)
+ SHR_L (CL,EAX)
+ MOV_L (EAX,CONTENT(GLNAME(writeseg)))
+ MOV_L (CONTENT(GLNAME(vgaSetReadWriteFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ POP_L (EDX)
+ POP_L (ECX)
+ MOV_L (REGOFF(4,ESP),EAX)
+ AND_L (CONTENT(GLNAME(vgaSegmentMask)),EAX)
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)),EAX)
+ RET
+
+ ALIGNTEXT4
+ GLOBL GLNAME(vga16SetReadWrite)
+GLNAME(vga16SetReadWrite):
+ MOV_L (REGOFF(4,ESP),EAX)
+ PUSH_L (ECX)
+ PUSH_L (EDX)
+ SUB_L (CONTENT(GLNAME(vgaBase)),EAX)
+ MOV_L (CONTENT(GLNAME(vgaSegmentShift)),ECX)
+ SHR_L (CL,EAX)
+ MOV_L (EAX,CONTENT(GLNAME(writeseg)))
+ MOV_L (CONTENT(GLNAME(vgaSetReadWriteFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ POP_L (EDX)
+ POP_L (ECX)
+ MOV_L (REGOFF(4,ESP),EAX)
+ SUB_L (CONTENT(GLNAME(vgaBase)),EAX)
+ AND_L (CONTENT(GLNAME(vgaSegmentMask)),EAX)
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)),EAX)
+ RET
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaReadWriteNext ---
+ * switch to next memory bank of the VGA board for read & write access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ *
+ *
+ * pointer
+ * vgaReadWriteNext(p)
+ * register pointer p;
+ * {
+ * (vgaSetReadWriteFunc)(++writeseg);
+ * return (p - vgaSegmentSize);
+ * }
+ */
+ ALIGNTEXT4
+ GLOBL GLNAME(vgaReadWriteNext)
+GLNAME(vgaReadWriteNext):
+ PUSH_L (EDX)
+ MOV_L (CONTENT(GLNAME(writeseg)),EAX)
+ INC_L (EAX)
+ MOV_L (EAX,CONTENT(GLNAME(writeseg)))
+ MOV_L (CONTENT(GLNAME(vgaSetReadWriteFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ POP_L (EDX)
+ MOV_L (REGOFF(4,ESP),EAX)
+ SUB_L (CONTENT(GLNAME(vgaSegmentSize)),EAX)
+ RET
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaReadWritePrev ---
+ * switch to previous memory bank of the VGA board for read & write access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ *
+ * pointer
+ * vgaReadWritePrev(p)
+ * register pointer p;
+ * {
+ * (vgaSetReadWriteFunc)(--writeseg);
+ * return (p + vgaSegmentSize);
+ * }
+ */
+ ALIGNTEXT4
+ GLOBL GLNAME(vgaReadWritePrev)
+GLNAME(vgaReadWritePrev):
+ PUSH_L (EDX)
+ MOV_L (CONTENT(GLNAME(writeseg)),EAX)
+ DEC_L (EAX)
+ MOV_L (EAX,CONTENT(GLNAME(writeseg)))
+ MOV_L (CONTENT(GLNAME(vgaSetReadWriteFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ POP_L (EDX)
+ MOV_L (REGOFF(4,ESP),EAX)
+ ADD_L (CONTENT(GLNAME(vgaSegmentSize)),EAX)
+ RET
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaSetRead ---
+ * select a memory bank of the VGA board for read access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ * pointer
+ * vgaSetRead(p)
+ * register pointer p;
+ * {
+ * #ifdef XF86VGA16
+ * readseg = ((unsigned long)p - vgaBase) >> vgaSegmentShift;
+ * (vgaSetReadFunc)(readseg);
+ * return (vgaReadBottom + (((unsigned int)p - vgaBase) & vgaSegmentMask));
+ * #else
+ * readseg = ((unsigned long)p - VGABASE) >> vgaSegmentShift;
+ * (vgaSetReadFunc)(readseg);
+ * return (vgaReadBottom + ((unsigned int)p & vgaSegmentMask));
+ * #endif
+ * }
+ *
+ * since we now have 1/4/8bpp in the same binary, we need to have
+ * both versions of the function in here
+ *
+ */
+ ALIGNTEXT4
+ GLOBL GLNAME(vgaSetRead)
+GLNAME(vgaSetRead):
+ MOV_L (REGOFF(4,ESP),EAX)
+ PUSH_L (ECX)
+ PUSH_L (EDX)
+ SUB_L (VGABASE,EAX)
+ MOV_L (CONTENT(GLNAME(vgaSegmentShift)),ECX)
+ SHR_L (CL,EAX)
+ MOV_L (EAX,CONTENT(GLNAME(readseg)))
+ MOV_L (CONTENT(GLNAME(vgaSetReadFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ POP_L (EDX)
+ POP_L (ECX)
+ MOV_L (REGOFF(4,ESP),EAX)
+ AND_L (CONTENT(GLNAME(vgaSegmentMask)),EAX)
+ ADD_L (CONTENT(GLNAME(vgaReadBottom)),EAX)
+ RET
+
+ ALIGNTEXT4
+ GLOBL GLNAME(vga16SetRead)
+GLNAME(vga16SetRead):
+ MOV_L (REGOFF(4,ESP),EAX)
+ PUSH_L (ECX)
+ PUSH_L (EDX)
+ SUB_L (CONTENT(GLNAME(vgaBase)),EAX)
+ MOV_L (CONTENT(GLNAME(vgaSegmentShift)),ECX)
+ SHR_L (CL,EAX)
+ MOV_L (EAX,CONTENT(GLNAME(readseg)))
+ MOV_L (CONTENT(GLNAME(vgaSetReadFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ POP_L (EDX)
+ POP_L (ECX)
+ MOV_L (REGOFF(4,ESP),EAX)
+ SUB_L (CONTENT(GLNAME(vgaBase)),EAX)
+ AND_L (CONTENT(GLNAME(vgaSegmentMask)),EAX)
+ ADD_L (CONTENT(GLNAME(vgaReadBottom)),EAX)
+ RET
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaReadNext ---
+ * switch to next memory bank of the VGA board for read access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ *
+ *
+ * pointer
+ * vgaReadNext(p)
+ * register pointer p;
+ * {
+ * (vgaSetReadFunc)(++readseg);
+ * return (p - vgaSegmentSize);
+ * }
+ */
+ ALIGNTEXT4
+ GLOBL GLNAME(vgaReadNext)
+GLNAME(vgaReadNext):
+ PUSH_L (EDX)
+ MOV_L (CONTENT(GLNAME(readseg)),EAX)
+ INC_L (EAX)
+ MOV_L (EAX,CONTENT(GLNAME(readseg)))
+ MOV_L (CONTENT(GLNAME(vgaSetReadFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ POP_L (EDX)
+ MOV_L (REGOFF(4,ESP),EAX)
+ SUB_L (CONTENT(GLNAME(vgaSegmentSize)),EAX)
+ RET
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaReadPrev ---
+ * switch to previous memory bank of the VGA board for read access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ *
+ * pointer
+ * vgaReadPrev(p)
+ * register pointer p;
+ * {
+ * (vgaSetReadFunc)(--readseg);
+ * return (p + vgaSegmentSize);
+ * }
+ */
+ ALIGNTEXT4
+ GLOBL GLNAME(vgaReadPrev)
+GLNAME(vgaReadPrev):
+ PUSH_L (EDX)
+ MOV_L (CONTENT(GLNAME(readseg)),EAX)
+ DEC_L (EAX)
+ MOV_L (EAX,CONTENT(GLNAME(readseg)))
+ MOV_L (CONTENT(GLNAME(vgaSetReadFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ POP_L (EDX)
+ MOV_L (REGOFF(4,ESP),EAX)
+ ADD_L (CONTENT(GLNAME(vgaSegmentSize)),EAX)
+ RET
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaSetWrite ---
+ * select a memory bank of the VGA board for write access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ * pointer
+ * vgaSetWrite(p)
+ * register pointer p;
+ * {
+ * #ifdef XF86VGA16
+ * writeseg = ((unsigned long)p - vgaBase) >> vgaSegmentShift;
+ * (vgaSetWriteFunc)(writeseg);
+ * return (vgaWriteBottom + (((unsigned int)p - vgaBase) & vgaSegmentMask));
+ * #else
+ * writeseg = ((unsigned long)p - VGABASE) >> vgaSegmentShift;
+ * (vgaSetWriteFunc)(writeseg);
+ * return (vgaWriteBottom + ((unsigned int)p & vgaSegmentMask));
+ * #endif
+ * }
+ *
+ * since we now have 1/4/8bpp in the same binary, we need to have
+ * both versions of the function in here
+ *
+ */
+ ALIGNTEXT4
+ GLOBL GLNAME(vgaSetWrite)
+GLNAME(vgaSetWrite):
+ MOV_L (REGOFF(4,ESP),EAX)
+ PUSH_L (ECX)
+ PUSH_L (EDX)
+ SUB_L (VGABASE,EAX)
+ MOV_L (CONTENT(GLNAME(vgaSegmentShift)),ECX)
+ SHR_L (CL,EAX)
+ MOV_L (EAX,CONTENT(GLNAME(writeseg)))
+ MOV_L (CONTENT(GLNAME(vgaSetWriteFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ POP_L (EDX)
+ POP_L (ECX)
+ MOV_L (REGOFF(4,ESP),EAX)
+ AND_L (CONTENT(GLNAME(vgaSegmentMask)),EAX)
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)),EAX)
+ RET
+
+ ALIGNTEXT4
+ GLOBL GLNAME(vga16SetWrite)
+GLNAME(vga16SetWrite):
+ MOV_L (REGOFF(4,ESP),EAX)
+ PUSH_L (ECX)
+ PUSH_L (EDX)
+ SUB_L (CONTENT(GLNAME(vgaBase)),EAX)
+ MOV_L (CONTENT(GLNAME(vgaSegmentShift)),ECX)
+ SHR_L (CL,EAX)
+ MOV_L (EAX,CONTENT(GLNAME(writeseg)))
+ MOV_L (CONTENT(GLNAME(vgaSetWriteFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ POP_L (EDX)
+ POP_L (ECX)
+ MOV_L (REGOFF(4,ESP),EAX)
+ SUB_L (CONTENT(GLNAME(vgaBase)),EAX)
+ AND_L (CONTENT(GLNAME(vgaSegmentMask)),EAX)
+ ADD_L (CONTENT(GLNAME(vgaWriteBottom)),EAX)
+ RET
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaWriteNext ---
+ * switch to next memory bank of the VGA board for write access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ *
+ *
+ * pointer
+ * vgaWriteNext(p)
+ * register pointer p;
+ * {
+ * (vgaSetWriteFunc)(++writeseg);
+ * return (p - vgaSegmentSize);
+ * }
+ */
+ ALIGNTEXT4
+ GLOBL GLNAME(vgaWriteNext)
+GLNAME(vgaWriteNext):
+ PUSH_L (EDX)
+ MOV_L (CONTENT(GLNAME(writeseg)),EAX)
+ INC_L (EAX)
+ MOV_L (EAX,CONTENT(GLNAME(writeseg)))
+ MOV_L (CONTENT(GLNAME(vgaSetWriteFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ POP_L (EDX)
+ MOV_L (REGOFF(4,ESP),EAX)
+ SUB_L (CONTENT(GLNAME(vgaSegmentSize)),EAX)
+ RET
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaWritePrev ---
+ * switch to previous memory bank of the VGA board for write access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ *
+ * pointer
+ * vgaWritePrev(p)
+ * register pointer p;
+ * {
+ * (vgaSetWriteFunc)(--writeseg);
+ * return (p + vgaSegmentSize);
+ * }
+ */
+ ALIGNTEXT4
+ GLOBL GLNAME(vgaWritePrev)
+GLNAME(vgaWritePrev):
+ PUSH_L (EDX)
+ MOV_L (CONTENT(GLNAME(writeseg)),EAX)
+ DEC_L (EAX)
+ MOV_L (EAX,CONTENT(GLNAME(writeseg)))
+ MOV_L (CONTENT(GLNAME(vgaSetWriteFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ POP_L (EDX)
+ MOV_L (REGOFF(4,ESP),EAX)
+ ADD_L (CONTENT(GLNAME(vgaSegmentSize)),EAX)
+ RET
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaSaveBank --
+ * save Banking-state
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ *
+ * void
+ * vgaSaveBank()
+ * {
+ * saveseg = writeseg;
+ * }
+ */
+ ALIGNTEXT4
+ GLOBL GLNAME(vgaSaveBank)
+GLNAME(vgaSaveBank):
+ MOV_L (CONTENT(GLNAME(writeseg)),EAX)
+ MOV_L (EAX,CONTENT(GLNAME(saveseg)))
+ RET
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaRestoreBank --
+ * restore the banking after vgaSaveBank was called
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ *
+ * void
+ * vgaRestoreBank()
+ * {
+ * (vgaSetWriteFunc)(saveseg);
+ * (vgaSetReadFunc)(saveseg);
+ * }
+ */
+ ALIGNTEXT4
+ GLOBL GLNAME(vgaRestoreBank)
+GLNAME(vgaRestoreBank):
+ PUSH_L (EDX)
+ MOV_L (CONTENT(GLNAME(saveseg)),EAX)
+ MOV_L (EAX,CONTENT(GLNAME(writeseg)))
+ MOV_L (CONTENT(GLNAME(vgaSetWriteFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ MOV_L (CONTENT(GLNAME(saveseg)),EAX)
+ MOV_L (EAX,CONTENT(GLNAME(readseg)))
+ MOV_L (CONTENT(GLNAME(vgaSetReadFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ POP_L (EDX)
+ RET
+
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaPushRead ---
+ * make the write-bank also readable. no acces to the former read bank !
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ *
+ * void
+ * vgaPushRead(p)
+ * {
+ * (vgaSetReadWriteFunc)(writeseg);
+ * }
+ */
+ ALIGNTEXT4
+ GLOBL GLNAME(vgaPushRead)
+GLNAME(vgaPushRead):
+ PUSH_L (EDX)
+ MOV_L (CONTENT(GLNAME(writeseg)),EAX)
+ MOV_L (CONTENT(GLNAME(vgaSetReadWriteFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ POP_L (EDX)
+ RET
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaPopRead ---
+ * restore the banking after vgaPushRead was called
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ *
+ * void
+ * vgaPopRead(p)
+ * {
+ * (vgaSetWriteFunc)(writeseg);
+ * (vgaSetReadFunc)(readseg);
+ * }
+ */
+ ALIGNTEXT4
+ GLOBL GLNAME(vgaPopRead)
+GLNAME(vgaPopRead):
+ PUSH_L (EDX)
+ MOV_L (CONTENT(GLNAME(writeseg)),EAX)
+ MOV_L (CONTENT(GLNAME(vgaSetWriteFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ MOV_L (CONTENT(GLNAME(readseg)),EAX)
+ MOV_L (CONTENT(GLNAME(vgaSetReadFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ POP_L (EDX)
+ RET
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaSetVidPage ---
+ * select a memory bank of the VGA board for read & write access
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ * void
+ * vgaSetVidPage(page)
+ * register int page;
+ * {
+ * (vgaSetReadWriteFunc)(page);
+ * return;
+ * }
+ *
+ */
+ ALIGNTEXT4
+ GLOBL GLNAME(vgaSetVidPage)
+GLNAME(vgaSetVidPage):
+ MOV_L (REGOFF(4,ESP),EAX)
+ PUSH_L (EDX)
+ MOV_L (CONTENT(GLNAME(vgaSetReadWriteFunc)),EDX)
+ CALL (CODEPTR(EDX))
+ POP_L (EDX)
+ RET
+
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgaBankc.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgaBankc.c
new file mode 100644
index 000000000..951b9c7d5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgaBankc.c
@@ -0,0 +1,358 @@
+/*
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgaBankc.c,v 1.2 1998/07/25 16:58:14 dawes Exp $ */
+
+/*
+ * Because a modern VGA has more than 128kBytes (which are mappable into the
+ * 386' memory some logic is required. The VGA's memory (logical VGA
+ * address space) is devided into smaller parts (called logical segments).
+ * These segments are mapped to logical areas.
+ *
+ * There are there different logical mapping areas:
+ *
+ * Read: an area which can be read from
+ * Write: an area which can be written to
+ * ReadWrite: here is both read an write possible
+ *
+ * It is permissable to use simultaneously a Read and a Write, but you can use
+ * ReadWrite only as a single.
+ * For example the bitblitting code uses a Read area as source and a Write
+ * area as destination. Most other routines use only a ReadWrite.
+ *
+ * A logical mapping area is described by some parameters (here I will for
+ * example describe a Read area:
+ *
+ * ReadBottom lowest accessable byte relative to the beginning of the
+ * VGA boards mapped memory.
+ *
+ * ReadTop highes accessable byte plus one.
+ *
+ * SegmentSize size of such an mapped area (common for all three)
+ *
+ * SegmentShift log2(SegmentSize) (used to compute the logical segment)
+ *
+ * SegmentMask SegmentSize - 1 (used to mask the offset inter an area)
+ *
+ *
+ * All that the following routines are doing is computing for a given offset
+ * into the logical VGA adress space the offset into such an logical area
+ * and the logical segment number. By the way they call also the VGA board's
+ * driver to set up the VGA's physical memory mapping according to the logical
+ * that was requested by the calliie.
+ *
+ * For shake of simplicity Write and ReadWrite share the same Bottom & Top.
+ * NOTE: Read & Write may have differnt starting addresses, or even common.
+ *
+ * There are multible routines present for the same effect. This was made
+ * for effectivly interface lowlevel assembly language best.
+ */
+
+/*
+ * BUGALERT: this should be gotten from vga.h. But since there some C lang.
+ * things, too ...
+ */
+#include "X.h"
+#include "misc.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86_HWlib.h"
+
+#include "vga.h"
+
+unsigned long readseg, writeseg, saveseg;
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaSetReadWrite ---
+ * select a memory bank of the VGA board for read & write access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+pointer
+vgaSetReadWrite(p)
+ register pointer p;
+{
+ if (xf86bpp == 4) {
+ writeseg = ((unsigned long)p - (unsigned long)vgaBase) >> vgaSegmentShift;
+ (vgaSetReadWriteFunc)(writeseg);
+ return ((pointer)((unsigned long)vgaWriteBottom + (((unsigned long)p - (unsigned long)vgaBase) & vgaSegmentMask)));
+ } else {
+ writeseg = ((unsigned long)p - VGABASE) >> vgaSegmentShift;
+ (vgaSetReadWriteFunc)(writeseg);
+ return (pointer)
+ ((unsigned long)vgaWriteBottom +
+ (((unsigned long)p - VGABASE) & vgaSegmentMask));
+ }
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaReadWriteNext ---
+ * switch to next memory bank of the VGA board for read & write access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+
+pointer
+vgaReadWriteNext(p)
+ register pointer p;
+{
+ (vgaSetReadWriteFunc)(++writeseg);
+ return (pointer)((unsigned long)p - vgaSegmentSize);
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaReadWritePrev ---
+ * switch to previous memory bank of the VGA board for read & write access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+
+pointer
+vgaReadWritePrev(p)
+ register pointer p;
+{
+ (vgaSetReadWriteFunc)(--writeseg);
+ return (pointer)((unsigned long)p + vgaSegmentSize);
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaSetRead ---
+ * select a memory bank of the VGA board for read access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+pointer
+vgaSetRead(p)
+ register pointer p;
+{
+ if (xf86bpp == 4) {
+ readseg = ((unsigned long)p - (unsigned long)vgaBase) >> vgaSegmentShift;
+ (vgaSetReadFunc)(readseg);
+ return ((pointer)((unsigned long)vgaReadBottom + (((unsigned long)p - (unsigned long)vgaBase) & vgaSegmentMask)));
+ } else {
+ readseg = ((unsigned long)p - VGABASE) >> vgaSegmentShift;
+ (vgaSetReadFunc)(readseg);
+ return (pointer)
+ ((unsigned long)vgaReadBottom +
+ (((unsigned long)p - VGABASE) & vgaSegmentMask));
+ }
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaReadNext ---
+ * switch to next memory bank of the VGA board for read access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+
+pointer
+vgaReadNext(p)
+ register pointer p;
+{
+ (vgaSetReadFunc)(++readseg);
+ return (pointer)((unsigned long)p - vgaSegmentSize);
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaReadPrev ---
+ * switch to previous memory bank of the VGA board for read access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+pointer
+vgaReadPrev(p)
+ register pointer p;
+{
+ (vgaSetReadFunc)(--readseg);
+ return (pointer)((unsigned long)p + vgaSegmentSize);
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaSetWrite ---
+ * select a memory bank of the VGA board for write access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+pointer
+vgaSetWrite(p)
+ register pointer p;
+{
+ if (xf86bpp == 4) {
+ writeseg = ((unsigned long)p - (unsigned long)vgaBase) >> vgaSegmentShift;
+ (vgaSetWriteFunc)(writeseg);
+ return ((pointer)((unsigned long)vgaWriteBottom + (((unsigned long)p - (unsigned long)vgaBase) & vgaSegmentMask)));
+ } else {
+ writeseg = ((unsigned long)p - VGABASE) >> vgaSegmentShift;
+ (vgaSetWriteFunc)(writeseg);
+ return (pointer)
+ ((unsigned long)vgaWriteBottom +
+ (((unsigned long)p - VGABASE) & vgaSegmentMask));
+ }
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaWriteNext ---
+ * switch to next memory bank of the VGA board for write access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+pointer
+vgaWriteNext(p)
+ register pointer p;
+{
+ (vgaSetWriteFunc)(++writeseg);
+ return (pointer)((unsigned long)p - vgaSegmentSize);
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaWritePrev ---
+ * switch to previous memory bank of the VGA board for write access
+ * Results:
+ * The adjusted pointer into the memory.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+pointer
+vgaWritePrev(p)
+ register pointer p;
+{
+ (vgaSetWriteFunc)(--writeseg);
+ return (pointer)((unsigned long)p + vgaSegmentSize);
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaSaveBank --
+ * save Banking-state
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+void
+vgaSaveBank()
+{
+ saveseg = writeseg;
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaRestoreBank --
+ * restore the banking after vgaSaveBank was called
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+void
+vgaRestoreBank()
+{
+ (vgaSetWriteFunc)(saveseg);
+ (vgaSetReadFunc)(saveseg);
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaPushRead ---
+ * make the write-bank also readable. no acces to the former read bank !
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+void
+vgaPushRead(void)
+{
+ (vgaSetReadWriteFunc)(writeseg);
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaPopRead ---
+ * restore the banking after vgaPushRead was called
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+void
+vgaPopRead(void)
+{
+ (vgaSetWriteFunc)(writeseg);
+ (vgaSetReadFunc)(readseg);
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * vgaSetVidPage ---
+ * select a memory bank of the VGA board for read & write access
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+void
+vgaSetVidPage(page)
+ register int page;
+{
+ (vgaSetReadWriteFunc)(page);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgabitblt.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgabitblt.c
new file mode 100644
index 000000000..010ccd86b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgabitblt.c
@@ -0,0 +1,792 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgabitblt.c,v 1.3 1998/11/28 10:43:18 dawes Exp $ */
+/*
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+Author: Keith Packard
+
+*/
+/* $XConsortium: vgabitblt.c /main/3 1996/02/21 18:10:26 kaleb $ */
+
+/*
+ * vga256 copy area
+ */
+
+
+#include "vgafb.h"
+#include "fastblt.h"
+#define MFB_CONSTS_ONLY
+#include "maskbits.h"
+
+RegionPtr
+vga256BitBlt(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, doBitBlt, bitPlane)
+ register DrawablePtr pSrcDrawable;
+ register DrawablePtr pDstDrawable;
+ GC *pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+ void (*doBitBlt)(
+#if NeedFunctionPrototypes
+DrawablePtr,
+DrawablePtr,
+int,
+RegionPtr,
+DDXPointPtr,
+unsigned long,
+unsigned long
+#endif
+);
+ unsigned long bitPlane;
+{
+ RegionPtr prgnSrcClip; /* may be a new region, or just a copy */
+ Bool freeSrcClip = FALSE;
+
+ RegionPtr prgnExposed;
+ RegionRec rgnDst;
+ DDXPointPtr pptSrc;
+ register DDXPointPtr ppt;
+ register BoxPtr pbox;
+ int i;
+ register int dx;
+ register int dy;
+ xRectangle origSource;
+ DDXPointRec origDest;
+ int numRects;
+ BoxRec fastBox;
+ int fastClip = 0; /* for fast clipping with pixmap source */
+ int fastExpose = 0; /* for fast exposures with pixmap source */
+
+ origSource.x = srcx;
+ origSource.y = srcy;
+ origSource.width = width;
+ origSource.height = height;
+ origDest.x = dstx;
+ origDest.y = dsty;
+
+ if ((pSrcDrawable != pDstDrawable) &&
+ pSrcDrawable->pScreen->SourceValidate)
+ {
+ (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, srcx, srcy, width, height);
+ }
+
+ srcx += pSrcDrawable->x;
+ srcy += pSrcDrawable->y;
+
+ /* clip the source */
+
+ if (pSrcDrawable->type == DRAWABLE_PIXMAP)
+ {
+ if ((pSrcDrawable == pDstDrawable) &&
+ (pGC->clientClipType == CT_NONE))
+ {
+ prgnSrcClip = cfbGetCompositeClip(pGC);
+ }
+ else
+ {
+ fastClip = 1;
+ }
+ }
+ else
+ {
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ if (!((WindowPtr) pSrcDrawable)->parent)
+ {
+ /*
+ * special case bitblt from root window in
+ * IncludeInferiors mode; just like from a pixmap
+ */
+ fastClip = 1;
+ }
+ else if ((pSrcDrawable == pDstDrawable) &&
+ (pGC->clientClipType == CT_NONE))
+ {
+ prgnSrcClip = cfbGetCompositeClip(pGC);
+ }
+ else
+ {
+ prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
+ freeSrcClip = TRUE;
+ }
+ }
+ else
+ {
+ prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
+ }
+ }
+
+ fastBox.x1 = srcx;
+ fastBox.y1 = srcy;
+ fastBox.x2 = srcx + width;
+ fastBox.y2 = srcy + height;
+
+ /* Don't create a source region if we are doing a fast clip */
+ if (fastClip)
+ {
+ fastExpose = 1;
+ /*
+ * clip the source; if regions extend beyond the source size,
+ * make sure exposure events get sent
+ */
+ if (fastBox.x1 < pSrcDrawable->x)
+ {
+ fastBox.x1 = pSrcDrawable->x;
+ fastExpose = 0;
+ }
+ if (fastBox.y1 < pSrcDrawable->y)
+ {
+ fastBox.y1 = pSrcDrawable->y;
+ fastExpose = 0;
+ }
+ if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
+ {
+ fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
+ fastExpose = 0;
+ }
+ if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
+ {
+ fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
+ fastExpose = 0;
+ }
+ }
+ else
+ {
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+ REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
+ }
+
+ dstx += pDstDrawable->x;
+ dsty += pDstDrawable->y;
+
+ if (pDstDrawable->type == DRAWABLE_WINDOW)
+ {
+ if (!((WindowPtr)pDstDrawable)->realized)
+ {
+ if (!fastClip)
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return NULL;
+ }
+ }
+
+ dx = srcx - dstx;
+ dy = srcy - dsty;
+
+ /* Translate and clip the dst to the destination composite clip */
+ if (fastClip)
+ {
+ RegionPtr cclip;
+
+ /* Translate the region directly */
+ fastBox.x1 -= dx;
+ fastBox.x2 -= dx;
+ fastBox.y1 -= dy;
+ fastBox.y2 -= dy;
+
+ /* If the destination composite clip is one rectangle we can
+ do the clip directly. Otherwise we have to create a full
+ blown region and call intersect */
+
+ /* XXX because CopyPlane uses this routine for 8-to-1 bit
+ * copies, this next line *must* also correctly fetch the
+ * composite clip from an mfb gc
+ */
+
+ cclip = cfbGetCompositeClip(pGC);
+ if (REGION_NUM_RECTS(cclip) == 1)
+ {
+ BoxPtr pBox = REGION_RECTS(cclip);
+
+ if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
+ if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
+ if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
+ if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
+
+ /* Check to see if the region is empty */
+ if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2)
+ {
+ REGION_INIT(pGC->pScreen, &rgnDst, NullBox, 0);
+ }
+ else
+ {
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+ }
+ }
+ else
+ {
+ /* We must turn off fastClip now, since we must create
+ a full blown region. It is intersected with the
+ composite clip below. */
+ fastClip = 0;
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox,1);
+ }
+ }
+ else
+ {
+ REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
+ }
+
+ if (!fastClip)
+ {
+ REGION_INTERSECT(pGC->pScreen, &rgnDst,
+ &rgnDst,
+ cfbGetCompositeClip(pGC));
+ }
+
+ /* Do bit blitting */
+ numRects = REGION_NUM_RECTS(&rgnDst);
+ if (numRects && width && height)
+ {
+ if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects *
+ sizeof(DDXPointRec))))
+ {
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return NULL;
+ }
+ pbox = REGION_RECTS(&rgnDst);
+ ppt = pptSrc;
+ for (i = numRects; --i >= 0; pbox++, ppt++)
+ {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ (*doBitBlt) (pSrcDrawable, pDstDrawable, pGC->alu, &rgnDst, pptSrc, pGC->planemask, bitPlane);
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+
+ prgnExposed = NULL;
+ if (pGC->fExpose)
+ {
+ /* Pixmap sources generate a NoExposed (we return NULL to do this) */
+ if (!fastExpose)
+ prgnExposed =
+ miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
+ origSource.x, origSource.y,
+ (int)origSource.width,
+ (int)origSource.height,
+ origDest.x, origDest.y, bitPlane);
+ }
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return prgnExposed;
+}
+void
+vga256DoBitblt (pSrc, pDst, alu, prgnDst, pptSrc, planemask)
+ DrawablePtr pSrc, pDst;
+ int alu;
+ RegionPtr prgnDst;
+ DDXPointPtr pptSrc;
+ unsigned long planemask;
+{
+ void (*blt)(
+#if NeedFunctionPrototypes
+DrawablePtr,
+DrawablePtr,
+int,
+RegionPtr,
+DDXPointPtr,
+unsigned long,
+unsigned long
+#endif
+) = vga256DoBitbltGeneral;
+ if ((planemask & PMSK) == PMSK) {
+ switch (alu) {
+ case GXcopy:
+ blt = vga256LowlevFuncs.doBitbltCopy;
+ break;
+ case GXxor:
+ blt = vga256DoBitbltXor;
+ break;
+ case GXor:
+ blt = vga256DoBitbltOr;
+ break;
+ }
+ }
+ (*blt) (pSrc, pDst, alu, prgnDst, pptSrc, planemask, ~0L);
+ return;
+}
+
+RegionPtr
+vga256CopyArea(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty)
+ register DrawablePtr pSrcDrawable;
+ register DrawablePtr pDstDrawable;
+ GC *pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+{
+ void (*localDoBitBlt)(
+#if NeedFunctionPrototypes
+DrawablePtr,
+DrawablePtr,
+int,
+RegionPtr,
+DDXPointPtr,
+unsigned long,
+unsigned long
+#endif
+);
+/*
+ localDoBitBlt = doBitBlt ? doBitBlt : vga256LowlevFuncs.doBitbltCopy;
+ doBitBlt = vga256LowlevFuncs.doBitbltCopy;
+
+ if (localDoBitBlt == vga256LowlevFuncs.doBitbltCopy)
+ {
+*/
+ localDoBitBlt = vga256LowlevFuncs.doBitbltCopy;
+ if (pGC->alu != GXcopy || (pGC->planemask & PMSK) != PMSK)
+ {
+ localDoBitBlt = vga256DoBitbltGeneral;
+ if ((pGC->planemask & PMSK) == PMSK)
+ {
+ switch (pGC->alu) {
+ case GXxor:
+ localDoBitBlt = vga256DoBitbltXor;
+ break;
+ case GXor:
+ localDoBitBlt = vga256DoBitbltOr;
+ break;
+ }
+ }
+ }
+/*
+ }
+*/
+
+ return cfbBitBlt (pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, localDoBitBlt, 0L);
+}
+
+void
+vga256CopyPlane1to8 (pSrcDrawable, pDstDrawable, rop, prgnDst, pptSrc, planemask, bitPlane)
+ DrawablePtr pSrcDrawable;
+ DrawablePtr pDstDrawable;
+ int rop;
+ RegionPtr prgnDst;
+ DDXPointPtr pptSrc;
+ unsigned long planemask;
+ unsigned long bitPlane;
+{
+ int srcx, srcy; /* upper left corner of box being copied in source */
+ int dstx, dsty; /* upper left corner of box being copied in dest */
+ int width, height; /* in pixels, unpadded, of box being copied */
+ int xoffSrc; /* bit # in leftmost word of row from which copying starts */
+ int xoffDst; /* byte # in leftmost word of row from which copying starts */
+ unsigned long *psrcBase, *pdstBase; /* start of drawable's pixel data */
+ int widthSrc; /* # of groups of 32 pixels (1 bit/pixel) in src bitmap*/
+ int widthDst; /* # of groups of 4 pixels (8 bits/pixel) in dst */
+ unsigned long *psrcLine, *pdstLine; /* steps a row at a time thru src/dst;
+ * may point into middle of row */
+ register unsigned long *psrc, *pdst; /* steps within the row */
+ register unsigned long bits, tmp; /* bits from source */
+ register int leftShift;
+ register int rightShift;
+ unsigned long startmask; /* left edge pixel mask */
+ unsigned long endmask; /* right edge pixel mask */
+ register int nlMiddle; /* number of words in middle of the row to draw */
+ register int nl;
+ int firstoff;
+ int secondoff;
+ unsigned long src;
+ int nbox; /* number of boxes in region to copy */
+ BoxPtr pbox; /* steps thru boxes in region */
+ int pixelsRemainingOnRightEdge; /* # pixels to be drawn on a row after
+ * the main "middle" loop */
+
+ cfbGetLongWidthAndPointer (pSrcDrawable, widthSrc, psrcBase)
+ cfbGetLongWidthAndPointer (pDstDrawable, widthDst, pdstBase)
+
+ BANK_FLAG(pdstBase)
+
+ nbox = REGION_NUM_RECTS(prgnDst);
+ pbox = REGION_RECTS(prgnDst);
+ while (nbox--)
+ {
+ dstx = pbox->x1;
+ dsty = pbox->y1;
+ srcx = pptSrc->x;
+ srcy = pptSrc->y;
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+ pbox++;
+ pptSrc++;
+
+ psrcLine = psrcBase + srcy * widthSrc + (srcx >> MFB_PWSH);
+ pdstLine = pdstBase + dsty * widthDst + (dstx >> PWSH);
+ xoffSrc = srcx & MFB_PIM; /* finds starting bit in src */
+ xoffDst = dstx & PIM; /* finds starting byte in dst */
+
+ /* compute startmask, endmask, nlMiddle */
+
+ if (xoffDst + width < PPW) /* XXX should this be '<= PPW' ? */
+ { /* the copy only affects one word per row in destination */
+ maskpartialbits(dstx, width, startmask);
+ endmask = 0;
+ nlMiddle = 0;
+ }
+ else
+ { /* the copy will affect multiple words per row in destination */
+ maskbits(dstx, width, startmask, endmask, nlMiddle);
+ }
+
+ /*
+ * compute constants for the first four bits to be
+ * copied. This avoids troubles with partial first
+ * writes, and difficult shift computation
+ */
+ if (startmask)
+ {
+ firstoff = xoffSrc - xoffDst;
+ if (firstoff > (MFB_PPW-PPW))
+ secondoff = MFB_PPW - firstoff;
+ if (xoffDst)
+ {
+ srcx += (PPW-xoffDst);
+ xoffSrc = srcx & MFB_PIM;
+ }
+ }
+ leftShift = xoffSrc;
+ rightShift = MFB_PPW - leftShift;
+
+ pixelsRemainingOnRightEdge = (nlMiddle & 7) * PPW +
+ ((dstx + width) & PIM);
+
+ /* setup is done; now let's move some bits */
+
+ /* caller must call cfb8CheckOpaqueStipple before this function
+ * to set cfb8StippleRRop!
+ */
+
+ if (cfb8StippleRRop == GXcopy)
+ {
+ while (height--)
+ { /* one iteration of this loop copies one row */
+ psrc = psrcLine;
+ pdst = pdstLine;
+ SETRW(pdst);
+ psrcLine += widthSrc;
+ pdstLine += widthDst;
+ bits = *psrc++;
+ if (startmask)
+ {
+ if (firstoff < 0)
+ tmp = BitRight (bits, -firstoff);
+ else
+ {
+ tmp = BitLeft (bits, firstoff);
+ /*
+ * need a more cautious test for partialmask
+ * case...
+ */
+ if (firstoff >= (MFB_PPW-PPW))
+ {
+ bits = *psrc++;
+ if (firstoff != (MFB_PPW-PPW))
+ tmp |= BitRight (bits, secondoff);
+ }
+ }
+ *pdst = (*pdst & ~startmask) | (GetPixelGroup(tmp) & startmask);
+ pdst++;
+ CHECKRWO(pdst);
+ }
+ nl = nlMiddle;
+ while (nl >= 8)
+ {
+ nl -= 8;
+ tmp = BitLeft(bits, leftShift);
+ bits = *psrc++;
+ if (rightShift != MFB_PPW)
+ tmp |= BitRight(bits, rightShift);
+
+#ifdef FAST_CONSTANT_OFFSET_MODE
+# define StorePixels(pdst,o,pixels) (pdst)[o] = (pixels)
+# define EndStep(pdst,o) (pdst) += (o)
+# define StoreRopPixels(pdst,o,and,xor) (pdst)[o] = DoRRop((pdst)[o],and,xor);
+#else
+# define StorePixels(pdst,o,pixels) *(pdst)++ = (pixels); CHECKRWO(pdst)
+# define EndStep(pdst,o)
+# define StoreRopPixels(pdst,o,and,xor) *(pdst) = DoRRop(*(pdst),and,xor); (pdst)++; CHECKRWO(pdst);
+#endif
+
+#define Step(c) NextBitGroup(c);
+#define StoreBitsPlain(o,c) StorePixels(pdst,o,GetPixelGroup(c))
+#define StoreRopBitsPlain(o,c) StoreRopPixels(pdst,o,\
+ cfb8StippleAnd[GetBitGroup(c)], \
+ cfb8StippleXor[GetBitGroup(c)])
+#define StoreBits0(c) StoreBitsPlain(0,c)
+#define StoreRopBits0(c) StoreRopBitsPlain(0,c)
+
+#if (BITMAP_BIT_ORDER == MSBFirst)
+# define StoreBits(o,c) StoreBitsPlain(o,c)
+# define StoreRopBits(o,c) StoreRopBitsPlain(o,c)
+# define FirstStep(c) Step(c)
+#else /* BITMAP_BIT_ORDER == LSBFirst */
+#if PGSZ == 64
+# define StoreBits(o,c) StorePixels(pdst,o, (cfb8Pixels[c & 0xff]))
+# define StoreRopBits(o,c) StoreRopPixels(pdst,o, \
+ (cfb8StippleAnd[c & 0xff]), \
+ (cfb8StippleXor[c & 0xff]))
+# define FirstStep(c) c = BitLeft (c, 8);
+#else
+/* 0x3c is 0xf << 2 (4 bits, long word) */
+# define StoreBits(o,c) StorePixels(pdst,o,*((unsigned long *)\
+ (((char *) cfb8Pixels) + (c & 0x3c))))
+# define StoreRopBits(o,c) StoreRopPixels(pdst,o, \
+ *((unsigned long *) (((char *) cfb8StippleAnd) + (c & 0x3c))), \
+ *((unsigned long *) (((char *) cfb8StippleXor) + (c & 0x3c))))
+# define FirstStep(c) c = BitLeft (c, 2);
+#endif /* PGSZ */
+#endif /* BITMAP_BIT_ORDER */
+
+ StoreBits0(tmp); FirstStep(tmp);
+ StoreBits(1,tmp); Step(tmp);
+ StoreBits(2,tmp); Step(tmp);
+ StoreBits(3,tmp); Step(tmp);
+ StoreBits(4,tmp); Step(tmp);
+ StoreBits(5,tmp); Step(tmp);
+ StoreBits(6,tmp); Step(tmp);
+ StoreBits(7,tmp); EndStep (pdst,8);
+ }
+
+ /* do rest of middle and partial word on right edge */
+
+ if (pixelsRemainingOnRightEdge)
+ {
+ tmp = BitLeft(bits, leftShift);
+
+ if (pixelsRemainingOnRightEdge > rightShift)
+ {
+ bits = *psrc++;
+ tmp |= BitRight (bits, rightShift);
+ }
+ EndStep (pdst, nl);
+ switch (nl)
+ {
+ case 7:
+ StoreBitsPlain(-7,tmp); Step(tmp);
+ case 6:
+ StoreBitsPlain(-6,tmp); Step(tmp);
+ case 5:
+ StoreBitsPlain(-5,tmp); Step(tmp);
+ case 4:
+ StoreBitsPlain(-4,tmp); Step(tmp);
+ case 3:
+ StoreBitsPlain(-3,tmp); Step(tmp);
+ case 2:
+ StoreBitsPlain(-2,tmp); Step(tmp);
+ case 1:
+ StoreBitsPlain(-1,tmp); Step(tmp);
+ }
+ if (endmask)
+ *pdst = (*pdst & ~endmask) | GetPixelGroup(tmp) & endmask;
+ }
+ }
+ }
+ else /* cfb8StippleRRop != GXcopy */
+ {
+ while (height--)
+ { /* one iteration of this loop copies one row */
+ psrc = psrcLine;
+ pdst = pdstLine;
+ SETRW(pdst);
+ psrcLine += widthSrc;
+ pdstLine += widthDst;
+ bits = *psrc++;
+
+ /* do partial word on left edge */
+
+ if (startmask)
+ {
+ if (firstoff < 0)
+ tmp = BitRight (bits, -firstoff);
+ else
+ {
+ tmp = BitLeft (bits, firstoff);
+ if (firstoff >= (MFB_PPW-PPW))
+ {
+ bits = *psrc++;
+ if (firstoff != (MFB_PPW-PPW))
+ tmp |= BitRight (bits, secondoff);
+ }
+ }
+ src = GetBitGroup(tmp);
+ *pdst = MaskRRopPixels (*pdst, src, startmask);
+ pdst++;
+ CHECKRWO(pdst);
+ }
+
+ /* do middle of row */
+
+ nl = nlMiddle;
+ while (nl >= 8)
+ {
+ nl -= 8;
+ tmp = BitLeft(bits, leftShift);
+ bits = *psrc++;
+ if (rightShift != MFB_PPW)
+ tmp |= BitRight(bits, rightShift);
+ StoreRopBits0(tmp); FirstStep(tmp);
+ StoreRopBits(1,tmp); Step(tmp);
+ StoreRopBits(2,tmp); Step(tmp);
+ StoreRopBits(3,tmp); Step(tmp);
+ StoreRopBits(4,tmp); Step(tmp);
+ StoreRopBits(5,tmp); Step(tmp);
+ StoreRopBits(6,tmp); Step(tmp);
+ StoreRopBits(7,tmp); EndStep(pdst,8);
+ }
+
+ /* do rest of middle and partial word on right edge */
+
+ if (pixelsRemainingOnRightEdge)
+ {
+ tmp = BitLeft(bits, leftShift);
+
+ if (pixelsRemainingOnRightEdge > rightShift)
+ {
+ bits = *psrc++;
+ tmp |= BitRight (bits, rightShift);
+ }
+ while (nl--)
+ {
+ src = GetBitGroup (tmp);
+ *pdst = RRopPixels (*pdst, src);
+ pdst++;
+ CHECKRWO(pdst);
+ NextBitGroup(tmp);
+ }
+ if (endmask)
+ {
+ src = GetBitGroup (tmp);
+ *pdst = MaskRRopPixels (*pdst, src, endmask);
+ }
+ }
+ } /* end copy one row */
+ } /* end alu is non-copy-mode case */
+ } /* end iteration over region boxes */
+}
+
+
+RegionPtr vga256CopyPlane(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane)
+ DrawablePtr pSrcDrawable;
+ DrawablePtr pDstDrawable;
+ GCPtr pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+ unsigned long bitPlane;
+{
+ RegionPtr ret;
+
+ /*
+ * If nothing is going to touch the frame buffer, then just use
+ * the regular cfb routines. They should be faster.
+ */
+ if ( (pSrcDrawable->type != DRAWABLE_WINDOW) &&
+ (pDstDrawable->type != DRAWABLE_WINDOW))
+ return cfbCopyPlane(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height,
+ dstx, dsty, bitPlane);
+
+ if (pSrcDrawable->bitsPerPixel == 1 && pDstDrawable->bitsPerPixel == 8)
+ {
+ if (bitPlane == 1)
+ {
+ cfb8CheckOpaqueStipple (pGC->alu,
+ pGC->fgPixel, pGC->bgPixel,
+ pGC->planemask);
+ ret = cfbBitBlt (pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ vga256LowlevFuncs.copyPlane1to8, bitPlane);
+ }
+ else
+ ret = miHandleExposures (pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+ }
+ else if (pSrcDrawable->bitsPerPixel == 8 && pDstDrawable->bitsPerPixel == 1)
+ {
+ extern int InverseAlu[16];
+ int oldalu;
+
+ oldalu = pGC->alu;
+ if ((pGC->fgPixel & 1) == 0 && (pGC->bgPixel&1) == 1)
+ pGC->alu = InverseAlu[pGC->alu];
+ else if ((pGC->fgPixel & 1) == (pGC->bgPixel & 1))
+ pGC->alu = mfbReduceRop(pGC->alu, pGC->fgPixel);
+ ret = cfbBitBlt (pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ vga256CopyPlane8to1, bitPlane);
+ pGC->alu = oldalu;
+ }
+ else if (pSrcDrawable->bitsPerPixel == 8 && pDstDrawable->bitsPerPixel == 8)
+ {
+ PixmapPtr pBitmap;
+ ScreenPtr pScreen = pSrcDrawable->pScreen;
+ GCPtr pGC1;
+
+ pBitmap = (*pScreen->CreatePixmap) (pScreen, width, height, 1);
+ if (!pBitmap)
+ return NULL;
+ pGC1 = GetScratchGC (1, pScreen);
+ if (!pGC1)
+ {
+ (*pScreen->DestroyPixmap) (pBitmap);
+ return NULL;
+ }
+ /*
+ * don't need to set pGC->fgPixel,bgPixel as copyPlane8to1
+ * ignores pixel values, expecting the rop to "do the
+ * right thing", which GXcopy will.
+ */
+ ValidateGC ((DrawablePtr) pBitmap, pGC1);
+ /* no exposures here, scratch GC's don't get graphics expose */
+ cfbBitBlt (pSrcDrawable, (DrawablePtr) pBitmap,
+ pGC1, srcx, srcy, width, height, 0, 0,
+ vga256CopyPlane8to1, bitPlane);
+ cfb8CheckOpaqueStipple (pGC->alu,
+ pGC->fgPixel, pGC->bgPixel,
+ pGC->planemask);
+ /* no exposures here, copy bits from inside a pixmap */
+ cfbBitBlt ((DrawablePtr) pBitmap, pDstDrawable, pGC,
+ 0, 0, width, height, dstx, dsty,
+ vga256LowlevFuncs.copyPlane1to8, 1L);
+ FreeScratchGC (pGC1);
+ (*pScreen->DestroyPixmap) (pBitmap);
+ /* compute resultant exposures */
+ ret = miHandleExposures (pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height,
+ dstx, dsty, bitPlane);
+ }
+ else
+ ErrorF( "vga256CopyPlane(). Unhandled combinations of bitsPerPixel\n");
+ return ret;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgablt.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgablt.c
new file mode 100644
index 000000000..a7deb6de6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgablt.c
@@ -0,0 +1,516 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgablt.c,v 1.2 1998/07/25 16:58:15 dawes Exp $ */
+/*
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+Author: Keith Packard
+
+*/
+/* $XConsortium: vgablt.c /main/4 1996/02/21 18:10:30 kaleb $ */
+/*
+ * cfb copy area
+ */
+
+
+#include "vgafb.h"
+#include "fastblt.h"
+#include "mergerop.h"
+
+#if PGSZ == 32
+#define LEFTSHIFT_AMT (5 - PWSH)
+#else /* PGSZ == 64 */
+#define LEFTSHIFT_AMT (6 - PWSH)
+#endif /* PGSZ */
+
+#ifdef notdef /* XXX fails right now, walks off end of pixmaps */
+#if defined (FAST_UNALIGNED_READS) && (PSZ == 8)
+#define DO_UNALIGNED_BITBLT
+#endif
+#endif
+
+#if (MROP == Mcopy)
+#ifdef SPEEDUP
+void
+speedupvga256DoBitbltCopy(pSrc, pDst, alu, prgnDst, pptSrc, planemask, bitPlane)
+#else
+void
+MROP_NAME(vga256DoBitblt)(pSrc, pDst, alu, prgnDst, pptSrc, planemask, bitPlane)
+#endif
+#else
+void
+MROP_NAME(vga256DoBitblt)(pSrc, pDst, alu, prgnDst, pptSrc, planemask, bitPlane)
+#endif
+ DrawablePtr pSrc, pDst;
+ int alu;
+ RegionPtr prgnDst;
+ DDXPointPtr pptSrc;
+ unsigned long planemask;
+ unsigned long bitPlane;
+{
+ unsigned long *psrcBase, *pdstBase;
+ /* start of src and dst bitmaps */
+ int widthSrc, widthDst; /* add to get to same position in next line */
+
+ BoxPtr pbox;
+ int nbox;
+
+ BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
+ /* temporaries for shuffling rectangles */
+ DDXPointPtr pptTmp, pptNew1, pptNew2;
+ /* shuffling boxes entails shuffling the
+ source points too */
+ int w, h;
+ int xdir; /* 1 = left right, -1 = right left/ */
+ int ydir; /* 1 = top down, -1 = bottom up */
+
+ unsigned long *psrcLine, *pdstLine;
+ /* pointers to line with current src and dst */
+ register unsigned long *psrc;/* pointer to current src longword */
+ register unsigned long *pdst;/* pointer to current dst longword */
+
+ MROP_DECLARE_REG()
+
+ /* following used for looping through a line */
+ unsigned long startmask, endmask; /* masks for writing ends of dst */
+ int nlMiddle; /* whole longwords in dst */
+ int xoffSrc, xoffDst;
+ register int leftShift, rightShift;
+ register unsigned long bits;
+ register unsigned long bits1;
+ register int nl; /* temp copy of nlMiddle */
+
+ /* place to store full source word */
+ int careful;
+
+#ifdef SPEEDUP
+ void SpeedUpBitBlt();
+#endif
+
+#ifndef SPEEDUP
+#if 0
+ /*
+ * If nothing is going to touch the frame buffer, then just use
+ * the regular cfb routines. They should be faster.
+ */
+ /*
+ * Doing this causes a problem saving/restoring the screen on VT switch.
+ */
+ if ( (pSrc->type != DRAWABLE_WINDOW) &&
+ (pDst->type != DRAWABLE_WINDOW))
+ {
+ MROP_NAME(cfbDoBitblt)(pSrc, pDst, alu, prgnDst, pptSrc, planemask);
+ return;
+ }
+#endif
+#endif
+
+ MROP_INITIALIZE(alu,planemask);
+
+ cfbGetLongWidthAndPointer (pSrc, widthSrc, psrcBase)
+
+ cfbGetLongWidthAndPointer (pDst, widthDst, pdstBase)
+
+ BANK_FLAG_BOTH(psrcBase,pdstBase)
+
+ /* XXX we have to err on the side of safety when both are windows,
+ * because we don't know if IncludeInferiors is being used.
+ */
+ careful = ((pSrc == pDst) ||
+ ((pSrc->type == DRAWABLE_WINDOW) &&
+ (pDst->type == DRAWABLE_WINDOW)));
+
+ pbox = REGION_RECTS(prgnDst);
+ nbox = REGION_NUM_RECTS(prgnDst);
+
+ pboxNew1 = NULL;
+ pptNew1 = NULL;
+ pboxNew2 = NULL;
+ pptNew2 = NULL;
+ if (careful && (pptSrc->y < pbox->y1))
+ {
+ /* walk source botttom to top */
+ ydir = -1;
+ widthSrc = -widthSrc;
+ widthDst = -widthDst;
+
+ if (nbox > 1)
+ {
+ /* keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ if(!pboxNew1)
+ return;
+ pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pptNew1)
+ {
+ DEALLOCATE_LOCAL(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox)
+ {
+ while ((pboxNext >= pbox) &&
+ (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp <= pboxBase)
+ {
+ *pboxNew1++ = *pboxTmp++;
+ *pptNew1++ = *pptTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ pptNew1 -= nbox;
+ pptSrc = pptNew1;
+ }
+ }
+ else
+ {
+ /* walk source top to bottom */
+ ydir = 1;
+ }
+
+ if (careful && (pptSrc->x < pbox->x1))
+ {
+ /* walk source right to left */
+ xdir = -1;
+
+ if (nbox > 1)
+ {
+ /* reverse order of rects in each band */
+ pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pboxNew2 || !pptNew2)
+ {
+ if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
+ if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
+ if (pboxNew1)
+ {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox)
+ {
+ while ((pboxNext < pbox+nbox) &&
+ (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp != pboxBase)
+ {
+ *pboxNew2++ = *--pboxTmp;
+ *pptNew2++ = *--pptTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ pptNew2 -= nbox;
+ pptSrc = pptNew2;
+ }
+ }
+ else
+ {
+ /* walk source left to right */
+ xdir = 1;
+ }
+
+ while(nbox--)
+ {
+ w = pbox->x2 - pbox->x1;
+ h = pbox->y2 - pbox->y1;
+
+#if (MROP) == Mcopy && defined(SPEEDUP)
+ if ((planemask&0xFF) == 0xFF) {
+ if (h | w)
+ SpeedUpBitBlt(psrcBase, pdstBase, widthSrc << 2, widthDst << 2,
+ pptSrc->x, pptSrc->y, pbox->x1, pbox->y1,
+ w, h, xdir, ydir);
+ pbox++;
+ pptSrc++;
+ continue;
+ }
+#endif
+
+
+ if (ydir == -1) /* start at last scanline of rectangle */
+ {
+ psrcLine = psrcBase + ((pptSrc->y+h-1) * -widthSrc);
+ pdstLine = pdstBase + ((pbox->y2-1) * -widthDst);
+ }
+ else /* start at first scanline */
+ {
+ psrcLine = psrcBase + (pptSrc->y * widthSrc);
+ pdstLine = pdstBase + (pbox->y1 * widthDst);
+ }
+ if ((pbox->x1 & PIM) + w <= PPW)
+ {
+ maskpartialbits (pbox->x1, w, endmask);
+ startmask = 0;
+ nlMiddle = 0;
+ }
+ else
+ {
+ maskbits(pbox->x1, w, startmask, endmask, nlMiddle);
+ }
+ if (xdir == 1)
+ {
+ xoffSrc = pptSrc->x & PIM;
+ xoffDst = pbox->x1 & PIM;
+ pdstLine += (pbox->x1 >> PWSH);
+ psrcLine += (pptSrc->x >> PWSH);
+ if (xoffSrc == xoffDst)
+ {
+ while (h--)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ SETW(pdst);
+ SETR(psrc);
+ pdstLine += widthDst;
+ psrcLine += widthSrc;
+ if (startmask)
+ {
+ bits = *psrc;
+ PUSHR();
+ *pdst = MROP_MASK(bits, *pdst, startmask);
+ pdst++; CHECKWO(pdst);
+ POPR();
+ psrc++; CHECKRO(psrc);
+ }
+ nl = nlMiddle;
+
+ DuffL(nl, label1,
+ bits = *psrc;
+ PUSHR();
+ *pdst = MROP_SOLID (bits, *pdst);
+ pdst++; CHECKWO(pdst);
+ POPR();
+ psrc++; CHECKRO(psrc); )
+
+ if (endmask)
+ {
+ bits = *psrc;
+ PUSHR();
+ *pdst = MROP_MASK(bits, *pdst, endmask);
+ POPR();
+ }
+ }
+ }
+ else
+ {
+ if (xoffSrc > xoffDst)
+ {
+ leftShift = (xoffSrc - xoffDst) << LEFTSHIFT_AMT;
+ rightShift = PGSZ - leftShift;
+ }
+ else
+ {
+ rightShift = (xoffDst - xoffSrc) << LEFTSHIFT_AMT;
+ leftShift = PGSZ - rightShift;
+ }
+ while (h--)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ SETW(pdst);
+ SETR(psrc);
+ pdstLine += widthDst;
+ psrcLine += widthSrc;
+ bits = 0;
+ if (xoffSrc > xoffDst)
+ {
+ bits = *psrc++;
+ CHECKRO(psrc);
+ }
+ if (startmask)
+ {
+ bits1 = BitLeft(bits,leftShift);
+ bits = *psrc++;
+ CHECKRO(psrc);
+ bits1 |= BitRight(bits,rightShift);
+ PUSHR();
+ *pdst = MROP_MASK(bits1, *pdst, startmask);
+ pdst++;
+ CHECKWO(pdst);
+ POPR();
+ }
+ nl = nlMiddle;
+
+ DuffL (nl,label2,
+ bits1 = BitLeft(bits, leftShift);
+ bits = *psrc++; CHECKRO(psrc);
+ PUSHR();
+ *pdst = MROP_SOLID (bits1 | BitRight(bits, rightShift),
+ *pdst);
+ pdst++; CHECKWO(pdst);
+ POPR();
+ )
+
+ if (endmask)
+ {
+ bits1 = BitLeft(bits, leftShift);
+ if (BitLeft(endmask, rightShift))
+ {
+ bits = *psrc;
+ bits1 |= BitRight(bits, rightShift);
+ }
+ PUSHR();
+ *pdst = MROP_MASK (bits1, *pdst, endmask);
+ POPR();
+ }
+ }
+ }
+ }
+ else /* xdir == -1 */
+ {
+ xoffSrc = (pptSrc->x + w - 1) & PIM;
+ xoffDst = (pbox->x2 - 1) & PIM;
+ pdstLine += ((pbox->x2-1) >> PWSH) + 1;
+ psrcLine += ((pptSrc->x+w - 1) >> PWSH) + 1;
+ if (xoffSrc == xoffDst)
+ {
+ while (h--)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ SETW(pdst);
+ SETR(psrc);
+ pdstLine += widthDst;
+ psrcLine += widthSrc;
+ if (endmask)
+ {
+ psrc--; CHECKRU(psrc);
+ bits = *psrc;
+ PUSHR();
+ pdst--; CHECKRWU(pdst);
+ *pdst = MROP_MASK (bits, *pdst, endmask);
+ POPR();
+ }
+ nl = nlMiddle;
+
+ DuffL(nl,label3,
+ --psrc; CHECKRU(psrc);
+ bits = *psrc;
+ PUSHR();
+ --pdst; CHECKRWU(pdst);
+ *pdst = MROP_SOLID (bits, *pdst);
+ POPR();)
+
+ if (startmask)
+ {
+ --psrc; CHECKRU(psrc);
+ bits = *psrc;
+ PUSHR();
+ --pdst; CHECKRWU(pdst);
+ *pdst = MROP_MASK(bits, *pdst, startmask);
+ POPR();
+ }
+ }
+ }
+ else
+ {
+ if (xoffDst > xoffSrc)
+ {
+ rightShift = (xoffDst - xoffSrc) << LEFTSHIFT_AMT;
+ leftShift = PGSZ - rightShift;
+ }
+ else
+ {
+ leftShift = (xoffSrc - xoffDst) << LEFTSHIFT_AMT;
+ rightShift = PGSZ - leftShift;
+ }
+ while (h--)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ SETW(pdst);
+ SETR(psrc);
+ pdstLine += widthDst;
+ psrcLine += widthSrc;
+ bits = 0;
+ if (xoffDst > xoffSrc) {
+ --psrc; CHECKRU(psrc);
+ bits = *psrc;
+ }
+ if (endmask)
+ {
+ bits1 = BitRight(bits, rightShift);
+ --psrc; CHECKRU(psrc);
+ bits = *psrc;
+ bits1 |= BitLeft(bits, leftShift);
+ PUSHR();
+ pdst--; CHECKRWU(pdst);
+ *pdst = MROP_MASK(bits1, *pdst, endmask);
+ POPR();
+ }
+ nl = nlMiddle;
+
+ DuffL (nl, label4,
+ bits1 = BitRight(bits, rightShift);
+ --psrc; CHECKRU(psrc);
+ bits = *psrc;
+ PUSHR();
+ --pdst; CHECKRWU(pdst);
+ *pdst = MROP_SOLID(bits1 | BitLeft(bits, leftShift),
+ *pdst);
+ POPR();
+ )
+
+ if (startmask)
+ {
+ bits1 = BitRight(bits, rightShift);
+ if (BitRight (startmask, leftShift))
+ {
+ --psrc; CHECKRU(psrc);
+ bits = *psrc;
+ bits1 |= BitLeft(bits, leftShift);
+ }
+ PUSHR();
+ --pdst; CHECKRWU(pdst);
+ *pdst = MROP_MASK(bits1, *pdst, startmask);
+ POPR();
+ }
+ }
+ }
+ }
+ pbox++;
+ pptSrc++;
+ }
+ if (pboxNew2)
+ {
+ DEALLOCATE_LOCAL(pptNew2);
+ DEALLOCATE_LOCAL(pboxNew2);
+ }
+ if (pboxNew1)
+ {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgabltC.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgabltC.c
new file mode 100644
index 000000000..0cba76f63
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgabltC.c
@@ -0,0 +1,245 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgabltC.c,v 1.2 1998/07/25 16:58:15 dawes Exp $ */
+/*
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+Author: Keith Packard
+
+*/
+/* $XConsortium: vgabltC.c /main/4 1996/02/21 18:10:34 kaleb $ */
+
+#include "vgafb.h"
+
+void
+vga256DoBitbltCopy(pSrc, pDst, alu, prgnDst, pptSrc, planemask, bitPlane)
+ DrawablePtr pSrc, pDst;
+ int alu;
+ RegionPtr prgnDst;
+ DDXPointPtr pptSrc;
+ unsigned long planemask;
+ unsigned long bitPlane;
+{
+ unsigned char *psrcBase, *pdstBase;
+ /* start of src and dst bitmaps */
+ int widthSrc, widthDst; /* add to get to same position in next line */
+ register void (*fnp)(
+#if NeedFunctionPrototypes
+ unsigned char*,
+ unsigned char*,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ unsigned long
+#endif
+);
+
+ BoxPtr pbox;
+ int nbox;
+
+ BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
+ /* temporaries for shuffling rectangles */
+ DDXPointPtr pptTmp, pptNew1, pptNew2;
+ /* shuffling boxes entails shuffling the
+ source points too */
+
+ int xdir; /* 1 = left right, -1 = right left/ */
+ int ydir; /* 1 = top down, -1 = bottom up */
+ int careful;
+
+ if (pSrc->type == DRAWABLE_WINDOW)
+ {
+ psrcBase = (unsigned char *)
+ (((PixmapPtr)(pSrc->pScreen->devPrivate))->devPrivate.ptr);
+ widthSrc = (int)((PixmapPtr)(pSrc->pScreen->devPrivate))->devKind;
+ }
+ else
+ {
+ psrcBase = (unsigned char *)(((PixmapPtr)pSrc)->devPrivate.ptr);
+ widthSrc = (int)(((PixmapPtr)pSrc)->devKind);
+ }
+
+ if (pDst->type == DRAWABLE_WINDOW)
+ {
+ pdstBase = (unsigned char *)
+ (((PixmapPtr)(pDst->pScreen->devPrivate))->devPrivate.ptr);
+ widthDst = (int)
+ ((PixmapPtr)(pDst->pScreen->devPrivate))->devKind;
+ }
+ else
+ {
+ pdstBase = (unsigned char *)(((PixmapPtr)pDst)->devPrivate.ptr);
+ widthDst = (int)(((PixmapPtr)pDst)->devKind);
+ }
+
+ if (CHECKSCREEN(psrcBase))
+ if (CHECKSCREEN(pdstBase))
+ fnp = vga256LowlevFuncs.vgaBitblt;
+ else
+ fnp = vgaImageRead;
+ else
+ if (CHECKSCREEN(pdstBase))
+ fnp = vgaImageWrite;
+ else
+ fnp = vgaPixBitBlt;
+
+
+ /* XXX we have to err on the side of safety when both are windows,
+ * because we don't know if IncludeInferiors is being used.
+ */
+ careful = ((pSrc == pDst) ||
+ ((pSrc->type == DRAWABLE_WINDOW) &&
+ (pDst->type == DRAWABLE_WINDOW)));
+
+ pbox = REGION_RECTS(prgnDst);
+ nbox = REGION_NUM_RECTS(prgnDst);
+
+ pboxNew1 = NULL;
+ pptNew1 = NULL;
+ pboxNew2 = NULL;
+ pptNew2 = NULL;
+ if (careful && (pptSrc->y < pbox->y1))
+ {
+ /* walk source botttom to top */
+ ydir = -1;
+ widthSrc = -widthSrc;
+ widthDst = -widthDst;
+
+ if (nbox > 1)
+ {
+ /* keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ if(!pboxNew1)
+ return;
+ pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pptNew1)
+ {
+ DEALLOCATE_LOCAL(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox)
+ {
+ while ((pboxNext >= pbox) &&
+ (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp <= pboxBase)
+ {
+ *pboxNew1++ = *pboxTmp++;
+ *pptNew1++ = *pptTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ pptNew1 -= nbox;
+ pptSrc = pptNew1;
+ }
+ }
+ else
+ {
+ /* walk source top to bottom */
+ ydir = 1;
+ }
+
+ if (careful && (pptSrc->x < pbox->x1))
+ {
+ /* walk source right to left */
+ xdir = -1;
+
+ if (nbox > 1)
+ {
+ /* reverse order of rects in each band */
+ pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pboxNew2 || !pptNew2)
+ {
+ if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
+ if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
+ if (pboxNew1)
+ {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox)
+ {
+ while ((pboxNext < pbox+nbox) &&
+ (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp != pboxBase)
+ {
+ *pboxNew2++ = *--pboxTmp;
+ *pptNew2++ = *--pptTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ pptNew2 -= nbox;
+ pptSrc = pptNew2;
+ }
+ }
+ else
+ {
+ /* walk source left to right */
+ xdir = 1;
+ }
+
+ while(nbox--) {
+ (*fnp)(pdstBase, psrcBase,widthSrc,widthDst,
+ pptSrc->x, pptSrc->y, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ xdir, ydir, alu, planemask);
+ pbox++;
+ pptSrc++;
+ }
+
+ /* free up stuff */
+ if (pboxNew2)
+ {
+ DEALLOCATE_LOCAL(pptNew2);
+ DEALLOCATE_LOCAL(pboxNew2);
+ }
+ if (pboxNew1)
+ {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+}
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgabresd.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgabresd.c
new file mode 100644
index 000000000..11095a164
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgabresd.c
@@ -0,0 +1,178 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgabresd.c,v 1.2 1998/07/25 16:58:16 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: vgabresd.c /main/4 1996/02/21 18:10:38 kaleb $ */
+
+#include "vgafb.h"
+#include "miline.h"
+
+/* Dashed bresenham line */
+
+void
+vga256BresD(rrops,
+ pdashIndex, pDash, numInDashList, pdashOffset, isDoubleDash,
+ addrl, nlwidth,
+ signdx, signdy, axis, x1, y1, e, e1, e2, len)
+cfbRRopPtr rrops;
+int *pdashIndex; /* current dash */
+unsigned char *pDash; /* dash list */
+int numInDashList; /* total length of dash list */
+int *pdashOffset; /* offset into current dash */
+int isDoubleDash;
+unsigned long *addrl; /* pointer to base of bitmap */
+int nlwidth; /* width in longwords of bitmap */
+int signdx, signdy; /* signs of directions */
+int axis; /* major axis (Y_AXIS or X_AXIS) */
+int x1, y1; /* initial point */
+register int e; /* error accumulator */
+register int e1; /* bresenham increments */
+int e2;
+int len; /* length of line */
+{
+ register unsigned char *addrb;
+ register unsigned char Oflag, Uflag;
+ register int e3 = e2-e1;
+ int dashIndex;
+ int dashOffset;
+ int dashRemaining;
+ unsigned long xorFg, andFg, xorBg, andBg;
+ Bool isCopy;
+ int thisDash;
+
+ BANK_FLAG(addrl)
+ Oflag = vgaWriteFlag && (signdx > 0 || signdy > 0);
+ Uflag = vgaWriteFlag && (signdx < 0 || signdy < 0);
+
+ dashOffset = *pdashOffset;
+ dashIndex = *pdashIndex;
+ dashRemaining = pDash[dashIndex] - dashOffset;
+ isCopy = (rrops[0].rop == GXcopy && rrops[1].rop == GXcopy);
+ xorFg = rrops[0].xor;
+ andFg = rrops[0].and;
+ xorBg = rrops[1].xor;
+ andBg = rrops[1].and;
+ if ((thisDash = dashRemaining) >= len)
+ {
+ thisDash = len;
+ dashRemaining -= len;
+ }
+ /* point to first point */
+ nlwidth <<= PWSH;
+ addrb = (unsigned char *)(addrl) + (y1 * nlwidth) + x1;
+ SETRW(addrb);
+ signdy *= nlwidth;
+ if (axis == Y_AXIS)
+ {
+ int t;
+
+ t = signdx;
+ signdx = signdy;
+ signdy = t;
+ }
+ e = e-e1; /* to make looping easier */
+
+#define BresStep(minor,major) {if ((e += e1) >= 0) { e += e3; minor; } major;}
+#define Loop(store) while (thisDash--) {\
+ store; \
+ BresStep(addrb+=signdy,addrb+=signdx) \
+ CHECKRWOF(Oflag,addrb); CHECKRWUF(Uflag,addrb); \
+ }
+
+#define NextDash {\
+ dashIndex++; \
+ if (dashIndex == numInDashList) \
+ dashIndex = 0; \
+ dashRemaining = pDash[dashIndex]; \
+ if ((thisDash = dashRemaining) >= len) \
+ { \
+ dashRemaining -= len; \
+ thisDash = len; \
+ } \
+}
+
+ if (isCopy)
+ {
+ for (;;)
+ {
+ len -= thisDash;
+ if (dashIndex & 1) {
+ if (isDoubleDash) {
+ Loop(*addrb = xorBg)
+ } else {
+ Loop(;)
+ }
+ } else {
+ Loop(*addrb = xorFg)
+ }
+ if (!len)
+ break;
+ NextDash
+ }
+ }
+ else
+ {
+ for (;;)
+ {
+ len -= thisDash;
+ if (dashIndex & 1) {
+ if (isDoubleDash) {
+ Loop(*addrb = DoRRop(*addrb,andBg, xorBg))
+ } else {
+ Loop(;)
+ }
+ } else {
+ Loop(*addrb = DoRRop(*addrb,andFg, xorFg))
+ }
+ if (!len)
+ break;
+ NextDash
+ }
+ }
+ *pdashIndex = dashIndex;
+ *pdashOffset = pDash[dashIndex] - dashRemaining;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgabstore.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgabstore.c
new file mode 100644
index 000000000..6450243d7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgabstore.c
@@ -0,0 +1,137 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgabstore.c,v 1.2 1998/07/25 16:58:16 dawes Exp $ */
+/*
+ * This file was derived from cfbbstore.c.
+ */
+/*-
+ * cfbbstore.c --
+ * Functions required by the backing-store implementation in MI.
+ *
+ * Copyright (c) 1987 by the Regents of the University of California
+ *
+ * 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. The University of California
+ * makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ *
+ *
+ */
+/* $XConsortium: vgabstore.c /main/4 1996/02/21 18:10:42 kaleb $ */
+
+#include "vgafb.h"
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * vga256SaveAreas --
+ * Function called by miSaveAreas to actually fetch the areas to be
+ * saved into the backing pixmap. This is very simple to do, since
+ * cfbDoBitblt is designed for this very thing. The region to save is
+ * already destination-relative and we're given the offset to the
+ * window origin, so we have only to create an array of points of the
+ * u.l. corners of the boxes in the region translated to the screen
+ * coordinate system and fetch the screen pixmap out of its devPrivate
+ * field....
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Data are copied from the screen into the pixmap.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+vga256SaveAreas(pPixmap, prgnSave, xorg, yorg, pWin)
+ PixmapPtr pPixmap; /* Backing pixmap */
+ RegionPtr prgnSave; /* Region to save (pixmap-relative) */
+ int xorg; /* X origin of region */
+ int yorg; /* Y origin of region */
+ WindowPtr pWin;
+{
+ register DDXPointPtr pPt;
+ DDXPointPtr pPtsInit;
+ register BoxPtr pBox;
+ register int i;
+
+ i = REGION_NUM_RECTS(prgnSave);
+ pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(i * sizeof(DDXPointRec));
+ if (!pPtsInit)
+ return;
+
+ pBox = REGION_RECTS(prgnSave);
+ pPt = pPtsInit;
+ while (--i >= 0) {
+ pPt->x = pBox->x1 + xorg;
+ pPt->y = pBox->y1 + yorg;
+ pPt++;
+ pBox++;
+ }
+
+
+ (*vga256LowlevFuncs.doBitbltCopy)((DrawablePtr)pPixmap->drawable.pScreen->devPrivate,
+ (DrawablePtr)pPixmap,
+ GXcopy,
+ prgnSave,
+ pPtsInit, ~0L, ~0L);
+
+ DEALLOCATE_LOCAL (pPtsInit);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * vga256RestoreAreas --
+ * Function called by miRestoreAreas to actually fetch the areas to be
+ * restored from the backing pixmap. This is very simple to do, since
+ * cfbDoBitblt is designed for this very thing. The region to restore is
+ * already destination-relative and we're given the offset to the
+ * window origin, so we have only to create an array of points of the
+ * u.l. corners of the boxes in the region translated to the pixmap
+ * coordinate system and fetch the screen pixmap out of its devPrivate
+ * field....
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Data are copied from the pixmap into the screen.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+vga256RestoreAreas(pPixmap, prgnRestore, xorg, yorg, pWin)
+ PixmapPtr pPixmap; /* Backing pixmap */
+ RegionPtr prgnRestore; /* Region to restore (screen-relative)*/
+ int xorg; /* X origin of window */
+ int yorg; /* Y origin of window */
+ WindowPtr pWin;
+{
+ register DDXPointPtr pPt;
+ DDXPointPtr pPtsInit;
+ register BoxPtr pBox;
+ register int i;
+
+ i = REGION_NUM_RECTS(prgnRestore);
+ pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(i*sizeof(DDXPointRec));
+ if (!pPtsInit)
+ return;
+
+ pBox = REGION_RECTS(prgnRestore);
+ pPt = pPtsInit;
+ while (--i >= 0) {
+ pPt->x = pBox->x1 - xorg;
+ pPt->y = pBox->y1 - yorg;
+ pPt++;
+ pBox++;
+ }
+
+
+ (*vga256LowlevFuncs.doBitbltCopy)((DrawablePtr)pPixmap,
+ (DrawablePtr)pPixmap->drawable.pScreen->devPrivate,
+ GXcopy,
+ prgnRestore,
+ pPtsInit, ~0L, ~0L);
+ DEALLOCATE_LOCAL (pPtsInit);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgafb.h b/xc/programs/Xserver/hw/xfree86/vgafb/vgafb.h
new file mode 100644
index 000000000..0d6b32c98
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgafb.h
@@ -0,0 +1,1314 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgafb.h,v 1.2 1998/07/25 16:58:17 dawes Exp $ */
+
+
+
+
+
+/* $XConsortium: vga256.h /main/5 1996/02/21 18:09:52 kaleb $ */
+
+#ifndef _VGA256_H
+#define VGA256_H
+
+#include "X.h"
+#include "Xmd.h"
+#include "servermd.h"
+#include "gcstruct.h"
+#include "window.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "region.h"
+#include "mistruct.h"
+#include "mibstore.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "cfb.h"
+#ifndef NO_CFBMSKBITS
+#include "cfbmskbits.h"
+#include "cfb8bit.h"
+#endif
+#include "vgaFasm.h"
+#include "vgaBank.h"
+#include "gcstruct.h"
+
+extern GCOps vga256TEOps1Rect, vga256TEOps, vga256NonTEOps1Rect, vga256NonTEOps;
+
+typedef struct _Cfbfunc{
+ void (*vgaBitblt)(
+#if NeedFunctionPrototypes
+ unsigned char*,
+ unsigned char*,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ unsigned long
+#endif
+);
+ void (*doBitbltCopy)(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ DrawablePtr,
+ int,
+ RegionPtr,
+ DDXPointPtr,
+ unsigned long,
+ unsigned long
+#endif
+);
+ void (*fillRectSolidCopy)(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ BoxPtr
+#endif
+);
+ void (*fillRectTransparentStippled32)();
+ void (*fillRectOpaqueStippled32)();
+ void (*segmentSS)(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ xSegment *
+#endif
+);
+ void (*lineSS)(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ int,
+ DDXPointPtr
+#endif
+);
+ void (*fillBoxSolid)(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ int,
+ BoxPtr,
+ unsigned long,
+ unsigned long,
+ int
+#endif
+);
+ void (*teGlyphBlt8)(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ int,
+ unsigned int,
+ CharInfoPtr *,
+ pointer
+#endif
+);
+ void (*copyPlane1to8)(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ DrawablePtr,
+ int,
+ RegionPtr,
+ DDXPointPtr,
+ unsigned long,
+ unsigned long
+#endif
+);
+ void (*fillSolidSpans)( /* Solid spans, any rop. */
+#if NeedFunctionPrototypes /* Must include clipping etc. */
+ DrawablePtr,
+ GCPtr,
+ int,
+ DDXPointPtr,
+ int *,
+ int
+#endif
+);
+} CfbfuncRec, *CfbfuncPtr;
+
+extern CfbfuncRec vga256LowlevFuncs;
+
+/* BitBlt.s */
+
+void WinWin(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ unsigned char *,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int
+#endif
+);
+
+/* BitBlt2.s */
+
+void PixWin(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ unsigned char *,
+ int ,
+ int ,
+ int ,
+ int
+#endif
+);
+
+void WinPix(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ unsigned char *,
+ int ,
+ int ,
+ int ,
+ int
+#endif
+);
+
+void PixPix(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ unsigned char *,
+ int ,
+ int ,
+ int ,
+ int ,
+ int
+#endif
+);
+
+/* Box.s */
+
+void SpeedUpBox(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ int ,
+ int ,
+ int ,
+ int
+#endif
+);
+
+/* Line.s */
+
+void SpeedUpBresS (
+#if NeedFunctionPrototypes
+ int,
+ unsigned,
+ unsigned,
+ unsigned long *,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int
+#endif
+);
+
+/* VHLine.s */
+
+void SpeedUpHLine(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ int ,
+ int ,
+ int
+#endif
+);
+
+void SpeedUpVLine(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ int ,
+ int ,
+ int
+#endif
+);
+
+/* fBitBlt.s */
+
+void fastBitBltCopy(
+#if NeedFunctionPrototypes
+ int ,
+ unsigned char *,
+ unsigned char *,
+ int ,
+ int ,
+ int ,
+ int
+#endif
+);
+
+/* fFillAnd.s */
+
+unsigned char *fastFillSolidGXand(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ unsigned long ,
+ unsigned long ,
+ int ,
+ int ,
+ int ,
+ int
+#endif
+);
+
+/* fFillOr.s */
+
+unsigned char *fastFillSolidGXor(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ unsigned long ,
+ unsigned long ,
+ int ,
+ int ,
+ int ,
+ int
+#endif
+);
+
+/* fFillXor.s */
+
+unsigned char *fastFillSolidGXxor(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ unsigned long ,
+ unsigned long ,
+ int ,
+ int ,
+ int ,
+ int
+#endif
+);
+
+/* fFillCopy.s */
+
+unsigned char *fastFillSolidGXcopy(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ unsigned long ,
+ unsigned long ,
+ int ,
+ int ,
+ int ,
+ int
+#endif
+);
+
+/* fFillSet.s */
+
+unsigned char *fastFillSolidGXset(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ unsigned long ,
+ unsigned long ,
+ int ,
+ int ,
+ int ,
+ int
+#endif
+);
+
+/* vgabres.s */
+void fastvga256BresS(
+#if NeedFunctionPrototypes
+ int ,
+ unsigned long ,
+ unsigned long ,
+ unsigned long *,
+ int ,
+ register int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ register int ,
+ register int ,
+ int ,
+ int
+#endif
+);
+
+/* vgalineH.s */
+int fastvga256HorzS(
+#if NeedFunctionPrototypes
+ int ,
+ unsigned long ,
+ register unsigned long ,
+ register unsigned long *,
+ int ,
+ int ,
+ int ,
+ int
+#endif
+);
+
+/* vgalineV.s */
+void fastvga256VertS(
+#if NeedFunctionPrototypes
+ int ,
+ unsigned long ,
+ unsigned long ,
+ unsigned long *,
+ int ,
+ int ,
+ int ,
+ register int
+#endif
+);
+
+/* vgaBitBlt.c */
+
+void vgaBitBlt(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ unsigned char *,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ unsigned long
+#endif
+);
+void OneBankvgaBitBlt(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ unsigned char *,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ unsigned long
+#endif
+);
+void vgaImageRead(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ unsigned char *,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ unsigned long
+#endif
+);
+void vgaImageWrite(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ unsigned char *,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ unsigned long
+#endif
+);
+void vgaPixBitBlt(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ unsigned char *,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ unsigned long
+#endif
+);
+
+/* vgagc.c */
+Bool vga256CreateGC(
+#if NeedFunctionPrototypes
+ register GCPtr
+#endif
+);
+/* vgawindow.c */
+void vga256CopyWindow(
+#if NeedFunctionPrototypes
+ WindowPtr ,
+ DDXPointRec ,
+ RegionPtr
+#endif
+);
+/* vgascrinit.c */
+int vga256FinishScreenInit(
+#if NeedFunctionPrototypes
+ register ScreenPtr ,
+ pointer ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int
+#endif
+);
+Bool vga256ScreenInit( register ScreenPtr , vgaHwPtr, pointer , int , int , int , int , int );
+
+/* vgagetsp.c */
+void vga256GetSpans(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ int ,
+ register DDXPointPtr ,
+ int *,
+ int ,
+ char *
+#endif
+);
+/* vgafillrct.c */
+void vga256FillBoxTileOdd(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ int ,
+ BoxPtr ,
+ PixmapPtr ,
+ int ,
+ int
+#endif
+);
+void vga256FillRectTileOdd(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ BoxPtr
+#endif
+);
+void vga256PolyFillRect(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ register GCPtr ,
+ int ,
+ xRectangle *
+#endif
+);
+/* vgaimage.c */
+void vga256GetImage(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ int ,
+ int ,
+ int ,
+ int ,
+ unsigned int ,
+ unsigned long ,
+ char *
+#endif
+);
+/* vgasolidC.c */
+void vga256FillRectSolidCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ BoxPtr
+#endif
+);
+void vga256SolidSpansCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ DDXPointPtr ,
+ int *,
+ int
+#endif
+);
+/* vgasolidCS.c */
+void speedupvga256FillRectSolidCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ BoxPtr
+#endif
+);
+/* vgasolidX.c */
+void vga256FillRectSolidXor(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ BoxPtr
+#endif
+);
+void vga256SolidSpansXor(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ DDXPointPtr ,
+ int *,
+ int
+#endif
+);
+/* vgasolidO.c */
+void vga256FillRectSolidOr(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ BoxPtr
+#endif
+);
+void vga256SolidSpansOr(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ DDXPointPtr ,
+ int *,
+ int
+#endif
+);
+/* vgasolidA.c */
+void vga256FillRectSolidAnd(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ BoxPtr
+#endif
+);
+void vga256SolidSpansAnd(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ DDXPointPtr ,
+ int *,
+ int
+#endif
+);
+/* vgasolidG.c */
+void vga256FillRectSolidGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ BoxPtr
+#endif
+);
+void vga256SolidSpansGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ DDXPointPtr ,
+ int *,
+ int
+#endif
+);
+/* vgatile32C.c */
+void vga256FillRectTile32Copy(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ BoxPtr
+#endif
+);
+void vga256Tile32FSCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ DDXPointPtr ,
+ int *,
+ int
+#endif
+);
+/* vgatile32G.c */
+void vga256FillRectTile32General(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ BoxPtr
+#endif
+);
+void vga256Tile32FSGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ DDXPointPtr ,
+ int *,
+ int
+#endif
+);
+/* vgatileoddC.c */
+void vga256FillBoxTileOddCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ int ,
+ register BoxPtr ,
+ PixmapPtr ,
+ int ,
+ int ,
+ int ,
+ unsigned long
+#endif
+);
+void vga256FillSpanTileOddCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ int ,
+ DDXPointPtr ,
+ int *,
+ PixmapPtr ,
+ int ,
+ int ,
+ int ,
+ unsigned long
+#endif
+);
+void vga256FillBoxTile32sCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ int ,
+ BoxPtr ,
+ PixmapPtr ,
+ int ,
+ int ,
+ int ,
+ unsigned long
+#endif
+);
+void vga256FillSpanTile32sCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ int ,
+ DDXPointPtr ,
+ int *,
+ PixmapPtr ,
+ int ,
+ int ,
+ int ,
+ unsigned long
+#endif
+);
+/* vgatileoddG.c */
+void vga256FillBoxTileOddGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ int ,
+ register BoxPtr ,
+ PixmapPtr ,
+ int ,
+ int ,
+ int ,
+ unsigned long
+#endif
+);
+void vga256FillSpanTileOddGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ int ,
+ DDXPointPtr ,
+ int *,
+ PixmapPtr ,
+ int ,
+ int ,
+ int ,
+ unsigned long
+#endif
+);
+void vga256FillBoxTile32sGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ int ,
+ BoxPtr ,
+ PixmapPtr ,
+ int ,
+ int ,
+ int ,
+ unsigned long
+#endif
+);
+void vga256FillSpanTile32sGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ int ,
+ DDXPointPtr ,
+ int *,
+ PixmapPtr ,
+ int ,
+ int ,
+ int ,
+ unsigned long
+#endif
+);
+/* vgafillsp.c */
+void vga256UnnaturalTileFS(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GC *,
+ int ,
+ DDXPointPtr ,
+ int *,
+ int
+#endif
+);
+void vga256UnnaturalStippleFS(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GC *,
+ int ,
+ DDXPointPtr ,
+ int *,
+ int
+#endif
+);
+void vga2568Stipple32FS(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ DDXPointPtr ,
+ int *,
+ int
+#endif
+);
+void vga2568OpaqueStipple32FS(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ DDXPointPtr ,
+ int *,
+ int
+#endif
+);
+/* vgasetsp.c */
+int vga256SetScanline(
+#if NeedFunctionPrototypes
+ int ,
+ int ,
+ int ,
+ int ,
+ register unsigned int *,
+ register int ,
+ int *,
+ int ,
+ unsigned long
+#endif
+);
+void vga256SetSpans(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ char *,
+ register DDXPointPtr ,
+ int *,
+ int ,
+ int
+#endif
+);
+/* vgapntwin.c */
+void vga256PaintWindow(
+#if NeedFunctionPrototypes
+ WindowPtr ,
+ RegionPtr ,
+ int
+#endif
+);
+void vga256FillBoxSolid(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ int ,
+ BoxPtr ,
+ unsigned long ,
+ unsigned long ,
+ int
+#endif
+);
+void vga256FillBoxTile32(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ int ,
+ BoxPtr ,
+ PixmapPtr
+#endif
+);
+/* vgapntwinS.c */
+void speedupvga256FillBoxSolid(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ int ,
+ BoxPtr ,
+ unsigned long ,
+ unsigned long ,
+ int
+#endif
+);
+/* vgazerarcC.c */
+void vga256ZeroPolyArcSS8Copy(
+#if NeedFunctionPrototypes
+ register DrawablePtr ,
+ GCPtr ,
+ int ,
+ xArc *
+#endif
+);
+/* vgazerarcX.c */
+void vga256ZeroPolyArcSS8Xor(
+#if NeedFunctionPrototypes
+ register DrawablePtr ,
+ GCPtr ,
+ int ,
+ xArc *
+#endif
+);
+/* vgazerarcG.c */
+void vga256ZeroPolyArcSS8General(
+#if NeedFunctionPrototypes
+ register DrawablePtr ,
+ GCPtr ,
+ int ,
+ xArc *
+#endif
+);
+/* vgafillarcC.c */
+void vga256PolyFillArcSolidCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ xArc *
+#endif
+);
+/* vgafillarcG.c */
+void vga256PolyFillArcSolidGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ xArc *
+#endif
+);
+/* vgategblt.c */
+void vga256TEGlyphBlt(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GC *,
+ int ,
+ int ,
+ unsigned int ,
+ CharInfoPtr *,
+ pointer
+#endif
+);
+/* vgabstore.c */
+void vga256SaveAreas(
+#if NeedFunctionPrototypes
+ PixmapPtr ,
+ RegionPtr ,
+ int ,
+ int ,
+ WindowPtr
+#endif
+);
+void vga256RestoreAreas(
+#if NeedFunctionPrototypes
+ PixmapPtr ,
+ RegionPtr ,
+ int ,
+ int ,
+ WindowPtr
+#endif
+);
+/* vga8cppl.c */
+void vga256CopyImagePlane(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ DrawablePtr ,
+ int ,
+ RegionPtr ,
+ DDXPointPtr ,
+ unsigned long
+#endif
+);
+void vga256CopyPlane8to1(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ DrawablePtr ,
+ int ,
+ RegionPtr ,
+ DDXPointPtr ,
+ unsigned long ,
+ unsigned long
+#endif
+);
+/* vgateblt8.c */
+void vga256TEGlyphBlt8(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GC *,
+ int ,
+ int ,
+ unsigned int ,
+ CharInfoPtr *,
+ pointer
+#endif
+);
+/* vgateblt8S.c */
+void speedupvga256TEGlyphBlt8(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GC *,
+ int ,
+ int ,
+ unsigned int ,
+ CharInfoPtr *,
+ pointer
+#endif
+);
+/* vgaglblt8.c */
+void vga256PolyGlyphBlt8(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ int ,
+ unsigned int ,
+ CharInfoPtr *,
+ pointer
+#endif
+);
+/* vgaglrop8.c */
+void vga256PolyGlyphRop8(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ int ,
+ unsigned int ,
+ CharInfoPtr *,
+ pointer
+#endif
+);
+/* vgarctstp8.c */
+void vga2568FillRectOpaqueStippled32(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ register BoxPtr
+#endif
+);
+void vga2568FillRectTransparentStippled32(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ BoxPtr
+#endif
+);
+/* vgarctstp8S.c */
+void speedupvga2568FillRectOpaqueStippled32(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ register BoxPtr
+#endif
+);
+void speedupvga2568FillRectTransparentStippled32(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ BoxPtr
+#endif
+);
+void vga2568FillRectStippledUnnatural(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ register BoxPtr
+#endif
+);
+/* vgapolypnt.c */
+void vga256PolyPoint(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ int ,
+ xPoint *
+#endif
+);
+/* vgaline.c */
+void vga256LineSS(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ int ,
+ DDXPointPtr
+#endif
+);
+void vga256LineSD(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ register GCPtr ,
+ int ,
+ int ,
+ DDXPointPtr
+#endif
+);
+/* vgalineS.c */
+void speedupvga256LineSS(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ int ,
+ DDXPointPtr
+#endif
+);
+/* vgabresd.c */
+void vga256BresD(
+#if NeedFunctionPrototypes
+ cfbRRopPtr ,
+ int *,
+ unsigned char *,
+ int ,
+ int *,
+ int ,
+ unsigned long *,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ register int ,
+ register int ,
+ int ,
+ int
+#endif
+);
+/* vgaseg.c */
+void vga256SegmentSS(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ register xSegment *
+#endif
+);
+void vga256SegmentSD(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ register GCPtr ,
+ int ,
+ register xSegment *
+#endif
+);
+/* vgasegS.c */
+void speedupvga256SegmentSS(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ register xSegment *
+#endif
+);
+/* vgabitblt.c */
+void vga256DoBitblt(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ DrawablePtr ,
+ int ,
+ RegionPtr ,
+ DDXPointPtr ,
+ unsigned long
+#endif
+);
+RegionPtr vga256CopyArea(
+#if NeedFunctionPrototypes
+ register DrawablePtr ,
+ register DrawablePtr ,
+ GC *,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int
+#endif
+);
+void vga256CopyPlane1to8(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ DrawablePtr ,
+ int ,
+ RegionPtr ,
+ DDXPointPtr ,
+ unsigned long ,
+ unsigned long
+#endif
+);
+RegionPtr vga256CopyPlane(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ int ,
+ unsigned long
+#endif
+);
+/* vgabltC.c */
+void vga256DoBitbltCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ DrawablePtr ,
+ int ,
+ RegionPtr ,
+ DDXPointPtr ,
+ unsigned long ,
+ unsigned long
+#endif
+);
+/* vgabltCS.c */
+void speedupvga256DoBitbltCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ DrawablePtr ,
+ int ,
+ RegionPtr ,
+ DDXPointPtr ,
+ unsigned long ,
+ unsigned long
+#endif
+);
+/* vgabltX.c */
+void vga256DoBitbltXor(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ DrawablePtr ,
+ int ,
+ RegionPtr ,
+ DDXPointPtr ,
+ unsigned long ,
+ unsigned long
+#endif
+);
+/* vgabltO.c */
+void vga256DoBitbltOr(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ DrawablePtr ,
+ int ,
+ RegionPtr ,
+ DDXPointPtr ,
+ unsigned long ,
+ unsigned long
+#endif
+);
+/* vgabltG.c */
+void vga256DoBitbltGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ DrawablePtr ,
+ int ,
+ RegionPtr ,
+ DDXPointPtr ,
+ unsigned long ,
+ unsigned long
+#endif
+);
+/* vgapush8.c */
+void vga256PushPixels8(
+#if NeedFunctionPrototypes
+ GCPtr ,
+ PixmapPtr ,
+ DrawablePtr ,
+ int ,
+ int ,
+ int ,
+ int
+#endif
+);
+/* vgaply1rctC.c */
+void vga256FillPoly1RectCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ int ,
+ int ,
+ DDXPointPtr
+#endif
+);
+/* vgaply1rctG.c */
+void vga256FillPoly1RectGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr ,
+ GCPtr ,
+ int ,
+ int ,
+ int ,
+ DDXPointPtr
+#endif
+);
+/* vgafuncs.c */
+
+#endif /* _VGA256_H */
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgafillarc.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgafillarc.c
new file mode 100644
index 000000000..50d775444
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgafillarc.c
@@ -0,0 +1,284 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgafillarc.c,v 1.2 1998/07/25 16:58:17 dawes Exp $ */
+/************************************************************
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+********************************************************/
+
+/* $XConsortium: vgafillarc.c /main/3 1996/02/21 18:10:46 kaleb $ */
+
+#include "vgafb.h"
+#include "mifillarc.h"
+#include "cfbrrop.h"
+
+/* gcc 1.35 is stupid */
+#if defined(__GNUC__) && defined(mc68020)
+#define VOLITILE volatile
+#else
+#define VOLITILE
+#endif
+
+static void
+RROP_NAME(vga256FillEllipseSolid) (pDraw, pGC, arc)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ xArc *arc;
+{
+ VOLITILE int x, y, e;
+ VOLITILE int yk, xk, ym, xm, dx, dy, xorg, yorg;
+ miFillArcRec info;
+ unsigned long *addrlt, *addrlb;
+ register unsigned long *addrl EDI;
+ register int n;
+ int nlwidth;
+ RROP_DECLARE
+ register int xpos;
+ register int slw;
+ unsigned long startmask, endmask;
+ int nlmiddle;
+ int nl;
+
+ CLD;
+
+ cfbGetLongWidthAndPointer (pDraw, nlwidth, addrlt)
+
+ BANK_FLAG(addrlt)
+
+ RROP_FETCH_GC(pGC);
+ miFillArcSetup(arc, &info);
+ MIFILLARCSETUP();
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ addrlb = addrlt;
+ addrlt += nlwidth * (yorg - y);
+ addrlb += nlwidth * (yorg + y + dy);
+ while (y)
+ {
+ addrlt += nlwidth;
+ addrlb -= nlwidth;
+ MIFILLARCSTEP(slw);
+ if (!slw)
+ continue;
+ xpos = xorg - x;
+ addrl = addrlt + (xpos >> PWSH);
+ SETRW(addrl);
+ if (((xpos & PIM) + slw) <= PPW)
+ {
+ maskpartialbits(xpos, slw, startmask);
+ RROP_SOLID_MASK(addrl,startmask);
+ if (miFillArcLower(slw))
+ {
+ addrl = addrlb + (xpos >> PWSH);
+ SETRW(addrl);
+ RROP_SOLID_MASK(addrl, startmask);
+ }
+ continue;
+ }
+ maskbits(xpos, slw, startmask, endmask, nlmiddle);
+ if (startmask)
+ {
+ RROP_SOLID_MASK(addrl, startmask);
+ addrl++; CHECKRWO(addrl);
+ }
+ n = nlmiddle;
+ RROP_SPAN_STD(addrl,n,FA_1);
+ CHECKRWO(addrl);
+ if (endmask)
+ RROP_SOLID_MASK(addrl, endmask);
+ if (!miFillArcLower(slw))
+ continue;
+ addrl = addrlb + (xpos >> PWSH);
+ SETRW(addrl);
+ if (startmask)
+ {
+ RROP_SOLID_MASK(addrl, startmask);
+ addrl++; CHECKRWO(addrl);
+ }
+ n = nlmiddle;
+ RROP_SPAN_STD(addrl,n,FA_2);
+ CHECKRWO(addrl);
+ if (endmask)
+ RROP_SOLID_MASK(addrl, endmask);
+ }
+}
+
+#define FILLSPAN(xl,xr,addr,dummy) \
+ if (xr >= xl) \
+ { \
+ n = xr - xl + 1; \
+ addrl = addr + (xl >> PWSH); \
+ SETRW(addrl); \
+ if (((xl & PIM) + n) <= PPW) \
+ { \
+ maskpartialbits(xl, n, startmask); \
+ RROP_SOLID_MASK(addrl, startmask); \
+ } \
+ else \
+ { \
+ maskbits(xl, n, startmask, endmask, n); \
+ if (startmask) \
+ { \
+ RROP_SOLID_MASK(addrl, startmask); \
+ addrl++; CHECKRWO(addrl); \
+ } \
+ RROP_SPAN_STD(addrl,n,dummy); \
+ CHECKRWO(addrl); \
+ if (endmask) \
+ RROP_SOLID_MASK(addrl, endmask); \
+ } \
+ }
+
+/*
+#define FILLSLICESPANS(flip,addr,dummy) \
+ if (!flip) \
+ { \
+ FILLSPAN(xl, xr, addr, RROP_NAME_CAT(FA_d1,dummy)); \
+ } \
+ else \
+ { \
+ xc = xorg - x; \
+ FILLSPAN(xc, xr, addr, RROP_NAME_CAT(FA_d2,dummy)); \
+ xc += slw - 1; \
+ FILLSPAN(xl, xc, addr, RROP_NAME_CAT(FA_d3,dummy)); \
+ }
+*/
+
+static void
+RROP_NAME(vga256FillArcSliceSolid)(pDraw, pGC, arc)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ xArc *arc;
+{
+ int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
+ register int x, y, e;
+ miFillArcRec info;
+ miArcSliceRec slice;
+ int xl, xr, xc;
+ unsigned long *addrlt, *addrlb;
+ register unsigned long *addrl EDI;
+ register int n;
+ int nlwidth;
+ int nl;
+ RROP_DECLARE
+ unsigned long startmask, endmask;
+
+ CLD;
+
+ cfbGetLongWidthAndPointer (pDraw, nlwidth, addrlt)
+
+ BANK_FLAG(addrlt)
+
+ RROP_FETCH_GC(pGC);
+ miFillArcSetup(arc, &info);
+ miFillArcSliceSetup(arc, &slice, pGC);
+ MIFILLARCSETUP();
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ addrlb = addrlt;
+ addrlt += nlwidth * (yorg - y);
+ addrlb += nlwidth * (yorg + y + dy);
+ slice.edge1.x += pDraw->x;
+ slice.edge2.x += pDraw->x;
+ while (y > 0)
+ {
+ addrlt += nlwidth;
+ addrlb -= nlwidth;
+ MIFILLARCSTEP(slw);
+ MIARCSLICESTEP(slice.edge1);
+ MIARCSLICESTEP(slice.edge2);
+ if (miFillSliceUpper(slice))
+ {
+ MIARCSLICEUPPER(xl, xr, slice, slw);
+ if (!slice.flip_top)
+ {
+ FILLSPAN(xl,xr,addrlt,FS_1);
+ }
+ else
+ {
+ xc = xorg - x;
+ FILLSPAN(xc,xr,addrlt,FS_2);
+ xc += slw - 1;
+ FILLSPAN(xl,xc,addrlt,FS_3);
+ }
+/*
+ FILLSLICESPANS(slice.flip_top, addrlt, __LINE__);
+*/
+ }
+ if (miFillSliceLower(slice))
+ {
+ MIARCSLICELOWER(xl, xr, slice, slw);
+ if (!slice.flip_bot)
+ {
+ FILLSPAN(xl,xr,addrlb,FS_4);
+ }
+ else
+ {
+ xc = xorg - x;
+ FILLSPAN(xc,xr,addrlb,FS_5);
+ xc += slw - 1;
+ FILLSPAN(xl,xc,addrlb,FS_6);
+ }
+/*
+ FILLSLICESPANS(slice.flip_bot, addrlb, __LINE__);
+*/
+ }
+ }
+}
+
+void
+RROP_NAME(vga256PolyFillArcSolid) (pDraw, pGC, narcs, parcs)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ register xArc *arc;
+ register int i;
+ BoxRec box;
+ RegionPtr cclip;
+
+ cclip = pGC->pCompositeClip;
+ for (arc = parcs, i = narcs; --i >= 0; arc++)
+ {
+ if (miFillArcEmpty(arc))
+ continue;
+ if (miCanFillArc(arc))
+ {
+ box.x1 = arc->x + pDraw->x;
+ box.y1 = arc->y + pDraw->y;
+ box.x2 = box.x1 + (int)arc->width + 1;
+ box.y2 = box.y1 + (int)arc->height + 1;
+ if ((*pDraw->pScreen->RectIn)(cclip, &box) == rgnIN)
+ {
+ if ((arc->angle2 >= FULLCIRCLE) ||
+ (arc->angle2 <= -FULLCIRCLE))
+ RROP_NAME(vga256FillEllipseSolid)(pDraw, pGC, arc);
+ else
+ RROP_NAME(vga256FillArcSliceSolid)(pDraw, pGC, arc);
+ continue;
+ }
+ }
+ miPolyFillArc(pDraw, pGC, 1, arc);
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgafillrct.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgafillrct.c
new file mode 100644
index 000000000..c6beb964e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgafillrct.c
@@ -0,0 +1,287 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgafillrct.c,v 1.2 1998/07/25 16:58:18 dawes Exp $ */
+/*
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+*/
+
+/* $XConsortium: vgafillrct.c /main/3 1996/02/21 18:10:49 kaleb $ */
+
+/*
+ * Fill rectangles.
+ */
+
+#include "vgafb.h"
+#include "cfbrrop.h"
+
+void
+vga256FillBoxTileOdd (pDrawable, n, rects, tile, xrot, yrot)
+ DrawablePtr pDrawable;
+ int n;
+ BoxPtr rects;
+ PixmapPtr tile;
+ int xrot, yrot;
+{
+ if (tile->drawable.width & PIM)
+ vga256FillBoxTileOddCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0);
+ else
+ vga256FillBoxTile32sCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0);
+}
+
+void
+vga256FillRectTileOdd (pDrawable, pGC, nBox, pBox)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nBox;
+ BoxPtr pBox;
+{
+ int xrot, yrot;
+ void (*fill)();
+
+ xrot = pDrawable->x + pGC->patOrg.x;
+ yrot = pDrawable->y + pGC->patOrg.y;
+ if (pGC->tile.pixmap->drawable.width & PIM)
+ {
+ fill = vga256FillBoxTileOddGeneral;
+ if ((pGC->planemask & PMSK) == PMSK)
+ {
+ if (pGC->alu == GXcopy)
+ fill = vga256FillBoxTileOddCopy;
+ }
+ }
+ else
+ {
+ fill = vga256FillBoxTile32sGeneral;
+ if ((pGC->planemask & PMSK) == PMSK)
+ {
+ if (pGC->alu == GXcopy)
+ fill = vga256FillBoxTile32sCopy;
+ }
+ }
+ (*fill) (pDrawable, nBox, pBox, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask);
+}
+
+#define NUM_STACK_RECTS 1024
+
+void
+vga256PolyFillRect(pDrawable, pGC, nrectFill, prectInit)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int nrectFill; /* number of rectangles to fill */
+ xRectangle *prectInit; /* Pointer to first rectangle to fill */
+{
+ xRectangle *prect;
+ RegionPtr prgnClip;
+ register BoxPtr pbox;
+ register BoxPtr pboxClipped;
+ BoxPtr pboxClippedBase;
+ BoxPtr pextent;
+ BoxRec stackRects[NUM_STACK_RECTS];
+ cfbPrivGC *priv;
+ int numRects;
+ void (*BoxFill)();
+ int n;
+ int xorg, yorg;
+ RROP_DECLARE
+
+ priv = (cfbPrivGC *) pGC->devPrivates[cfbGCPrivateIndex].ptr;
+ prgnClip = pGC->pCompositeClip;
+
+ BoxFill = 0;
+ switch (pGC->fillStyle)
+ {
+ case FillSolid:
+ RROP_FETCH_GCPRIV(priv)
+ switch (priv->rop) {
+ case GXcopy:
+ BoxFill = vga256LowlevFuncs.fillRectSolidCopy;
+ break;
+ case GXxor:
+ BoxFill = vga256FillRectSolidXor;
+ break;
+ case GXand:
+ BoxFill = (rrop_xor == 0) ?
+ vga256FillRectSolidAnd : vga256FillRectSolidGeneral;
+ break;
+ case GXor:
+ BoxFill = (rrop_and == 0) ?
+ vga256FillRectSolidOr : vga256FillRectSolidGeneral;
+ break;
+ default:
+ BoxFill = vga256FillRectSolidGeneral;
+ break;
+ }
+ break;
+ case FillTiled:
+ if (!pGC->pRotatedPixmap)
+ BoxFill = vga256FillRectTileOdd;
+ else
+ {
+ if (pGC->alu == GXcopy && (pGC->planemask & PMSK) == PMSK)
+ BoxFill = vga256FillRectTile32Copy;
+ else
+ BoxFill = vga256FillRectTile32General;
+ }
+ break;
+#if PSZ == 8
+ case FillStippled:
+ if (!pGC->pRotatedPixmap)
+ BoxFill = vga2568FillRectStippledUnnatural;
+ else
+ BoxFill = vga256LowlevFuncs.fillRectTransparentStippled32;
+ break;
+ case FillOpaqueStippled:
+ if (!pGC->pRotatedPixmap)
+ BoxFill = vga2568FillRectStippledUnnatural;
+ else
+ BoxFill = vga256LowlevFuncs.fillRectOpaqueStippled32;
+ break;
+#endif
+ }
+ prect = prectInit;
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+ if (xorg || yorg)
+ {
+ prect = prectInit;
+ n = nrectFill;
+ while(n--)
+ {
+ prect->x += xorg;
+ prect->y += yorg;
+ prect++;
+ }
+ }
+
+ prect = prectInit;
+
+ numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
+ if (numRects > NUM_STACK_RECTS)
+ {
+ pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
+ if (!pboxClippedBase)
+ return;
+ }
+ else
+ pboxClippedBase = stackRects;
+
+ pboxClipped = pboxClippedBase;
+
+ if (REGION_NUM_RECTS(prgnClip) == 1)
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_RECTS(prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ if ((pboxClipped->x1 = prect->x) < x1)
+ pboxClipped->x1 = x1;
+
+ if ((pboxClipped->y1 = prect->y) < y1)
+ pboxClipped->y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ pboxClipped->x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ pboxClipped->y2 = by2;
+
+ prect++;
+ if ((pboxClipped->x1 < pboxClipped->x2) &&
+ (pboxClipped->y1 < pboxClipped->y2))
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ else
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = (*pGC->pScreen->RegionExtents)(prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ BoxRec box;
+
+ if ((box.x1 = prect->x) < x1)
+ box.x1 = x1;
+
+ if ((box.y1 = prect->y) < y1)
+ box.y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ box.x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ box.y2 = by2;
+
+ prect++;
+
+ if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
+ continue;
+
+ n = REGION_NUM_RECTS (prgnClip);
+ pbox = REGION_RECTS(prgnClip);
+
+ /* clip the rectangle to each box in the clip region
+ this is logically equivalent to calling Intersect()
+ */
+ while(n--)
+ {
+ pboxClipped->x1 = max(box.x1, pbox->x1);
+ pboxClipped->y1 = max(box.y1, pbox->y1);
+ pboxClipped->x2 = min(box.x2, pbox->x2);
+ pboxClipped->y2 = min(box.y2, pbox->y2);
+ pbox++;
+
+ /* see if clipping left anything */
+ if(pboxClipped->x1 < pboxClipped->x2 &&
+ pboxClipped->y1 < pboxClipped->y2)
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ }
+ if (pboxClipped != pboxClippedBase)
+ (*BoxFill) (pDrawable, pGC,
+ pboxClipped-pboxClippedBase, pboxClippedBase);
+ if (pboxClippedBase != stackRects)
+ DEALLOCATE_LOCAL(pboxClippedBase);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgafillsp.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgafillsp.c
new file mode 100644
index 000000000..6b45c82d6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgafillsp.c
@@ -0,0 +1,796 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgafillsp.c,v 1.2 1998/07/25 16:58:18 dawes Exp $ */
+/************************************************************
+Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
+
+ 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 no-
+tice appear in all copies and that both that copyright no-
+tice and this permission notice appear in supporting docu-
+mentation, and that the names of Sun or X Consortium
+not be used in advertising or publicity pertaining to
+distribution of the software without specific prior
+written permission. Sun and X Consortium make no
+representations about the suitability of this software for
+any purpose. It is provided "as is" without any express or
+implied warranty.
+
+SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
+NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
+ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: vgafillsp.c /main/4 1996/02/21 18:10:53 kaleb $ */
+
+#include "vgafb.h"
+#include "mergerop.h"
+
+#define MFB_CONSTS_ONLY
+#include "maskbits.h"
+
+#include "mispans.h"
+
+extern void mfbInvertSolidFS(), mfbBlackSolidFS(), mfbWhiteSolidFS();
+
+/* scanline filling for color frame buffer
+ written by drewry, oct 1986 modified by smarks
+ changes for compatibility with Little-endian systems Jul 1987; MIT:yba.
+
+ these routines all clip. they assume that anything that has called
+them has already translated the points (i.e. pGC->miTranslate is
+non-zero, which is howit gets set in cfbCreateGC().)
+
+ the number of new scnalines created by clipping ==
+MaxRectsPerBand * nSpans.
+
+ FillSolid is overloaded to be used for OpaqueStipple as well,
+if fgPixel == bgPixel.
+Note that for solids, PrivGC.rop == PrivGC.ropOpStip
+
+
+ FillTiled is overloaded to be used for OpaqueStipple, if
+fgPixel != bgPixel. based on the fill style, it uses
+{RotatedTile, gc.alu} or {RotatedStipple, PrivGC.ropOpStip}
+*/
+
+/* Fill spans with tiles that aren't 32 bits wide */
+void
+vga256UnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+DrawablePtr pDrawable;
+GC *pGC;
+int nInit; /* number of spans to fill */
+DDXPointPtr pptInit; /* pointer to list of start points */
+int *pwidthInit; /* pointer to list of n widths */
+int fSorted;
+{
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ void (*fill)();
+ int xrot, yrot;
+
+ if (!(pGC->planemask))
+ return;
+
+ if (pGC->tile.pixmap->drawable.width & PIM)
+ {
+ fill = vga256FillSpanTileOddGeneral;
+ if ((pGC->planemask & PMSK) == PMSK)
+ {
+ if (pGC->alu == GXcopy)
+ fill = vga256FillSpanTileOddCopy;
+ }
+ }
+ else
+ {
+ fill = vga256FillSpanTile32sGeneral;
+ if ((pGC->planemask & PMSK) == PMSK)
+ {
+ if (pGC->alu == GXcopy)
+ fill = vga256FillSpanTile32sCopy;
+ }
+ }
+ n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) );
+ if ( n == 0 )
+ return;
+ pwidth = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ ppt = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!ppt || !pwidth)
+ {
+ if (ppt) DEALLOCATE_LOCAL(ppt);
+ if (pwidth) DEALLOCATE_LOCAL(pwidth);
+ return;
+ }
+ n = miClipSpans( cfbGetCompositeClip(pGC),
+ pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ xrot = pDrawable->x + pGC->patOrg.x;
+ yrot = pDrawable->y + pGC->patOrg.y;
+
+ (*fill) (pDrawable, n, ppt, pwidth, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask);
+
+ DEALLOCATE_LOCAL(ppt);
+ DEALLOCATE_LOCAL(pwidth);
+}
+
+void
+vga256UnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+DrawablePtr pDrawable;
+GC *pGC;
+int nInit; /* number of spans to fill */
+DDXPointPtr pptInit; /* pointer to list of start points */
+int *pwidthInit; /* pointer to list of n widths */
+int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ DDXPointPtr ppt; /* pointer to list of start points */
+ int *pwidth; /* pointer to list of n widths */
+ int *pwidthFree;/* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ unsigned long *pdstBase; /* pointer to start of bitmap */
+ int nlwDst; /* width in longwords of bitmap */
+ register unsigned long *pdst; /* pointer to current word in bitmap */
+ PixmapPtr pStipple; /* pointer to stipple we want to fill with */
+ int nlw;
+ int x, y, w, xrem, xSrc, ySrc;
+ int stwidth, stippleWidth;
+ int stippleHeight;
+ register unsigned long bits, inputBits;
+ register int partBitsLeft;
+ int nextPartBits;
+ int bitsLeft, bitsWhole;
+ unsigned long *srcTemp, *srcStart;
+ unsigned long *psrcBase;
+ unsigned long startmask, endmask;
+
+ /*
+ * If nothing is going to actually touch the framebuffer, then
+ * do the work with the cfb routines as they should be slightly faster.
+ */
+
+ if( pDrawable->type != DRAWABLE_WINDOW )
+ {
+ cfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit,
+ pwidthInit, fSorted);
+ return;
+ }
+
+ if (pGC->fillStyle == FillStippled)
+ cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
+ else
+ cfb8CheckOpaqueStipple (pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
+
+ if (cfb8StippleRRop == GXnoop)
+ return;
+
+ n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) );
+ if ( n == 0 )
+ return;
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans( cfbGetCompositeClip(pGC),
+ pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ /*
+ * OK, so what's going on here? We have two Drawables:
+ *
+ * The Stipple:
+ * Depth = 1
+ * Width = stippleWidth
+ * Words per scanline = stwidth
+ * Pointer to pixels = pStipple->devPrivate.ptr
+ */
+
+ pStipple = pGC->stipple;
+
+ stwidth = pStipple->devKind >> PWSH;
+ stippleWidth = pStipple->drawable.width;
+ stippleHeight = pStipple->drawable.height;
+ psrcBase = (unsigned long *) pStipple->devPrivate.ptr;
+
+ /*
+ * The Target:
+ * Depth = PSZ
+ * Width = determined from *pwidth
+ * Words per scanline = nlwDst
+ * Pointer to pixels = addrlBase
+ */
+
+ cfbGetLongWidthAndPointer (pDrawable, nlwDst, pdstBase)
+
+ BANK_FLAG(pdstBase)
+
+ /* this replaces rotating the stipple. Instead we just adjust the offset
+ * at which we start grabbing bits from the stipple.
+ * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
+ * so that iline and xrem always stay within the stipple bounds.
+ */
+
+ modulus (pGC->patOrg.x, stippleWidth, xSrc);
+ xSrc += pDrawable->x - stippleWidth;
+ modulus (pGC->patOrg.y, stippleHeight, ySrc);
+ ySrc += pDrawable->y - stippleHeight;
+
+ bitsWhole = stippleWidth;
+
+ while (n--)
+ {
+ x = ppt->x;
+ y = ppt->y;
+ ppt++;
+ w = *pwidth++;
+ pdst = pdstBase + y * nlwDst + (x >> PWSH);
+ SETRW(pdst);
+ y = (y - ySrc) % stippleHeight;
+ srcStart = psrcBase + y * stwidth;
+ xrem = ((x & ~(PGSZB-1)) - xSrc) % stippleWidth;
+ srcTemp = srcStart + (xrem >> MFB_PWSH);
+ bitsLeft = stippleWidth - (xrem & ~MFB_PIM);
+ xrem &= MFB_PIM;
+ NextUnnaturalStippleWord
+ if (partBitsLeft < xrem)
+ FatalError ("vga256UnnaturalStippleFS bad partBitsLeft %d xrem %d",
+ partBitsLeft, xrem);
+ NextSomeBits (inputBits, xrem);
+ partBitsLeft -= xrem;
+ if (((x & PIM) + w) <= PPW)
+ {
+ maskpartialbits (x, w, startmask)
+ NextUnnaturalStippleBits
+ *pdst = MaskRRopPixels(*pdst,bits,startmask);
+ }
+ else
+ {
+ maskbits (x, w, startmask, endmask, nlw);
+ nextPartBits = (x & (PGSZB-1)) + w;
+ if (nextPartBits < partBitsLeft)
+ {
+ if (startmask)
+ {
+ MaskRRopBitGroup(pdst,GetBitGroup(inputBits),startmask)
+ pdst++; CHECKRWO(pdst);
+ NextBitGroup (inputBits);
+ }
+ while (nlw--)
+ {
+ RRopBitGroup (pdst, GetBitGroup (inputBits));
+ pdst++; CHECKRWO(pdst);
+ NextBitGroup (inputBits);
+ }
+ if (endmask)
+ {
+ MaskRRopBitGroup(pdst,GetBitGroup(inputBits),endmask)
+ }
+ }
+ else if (bitsLeft != bitsWhole && nextPartBits < partBitsLeft + bitsLeft)
+ {
+ NextUnnaturalStippleBitsFast
+ if (startmask)
+ {
+ *pdst = MaskRRopPixels(*pdst,bits,startmask);
+ pdst++; CHECKRWO(pdst);
+ NextUnnaturalStippleBitsFast
+ }
+ while (nlw--)
+ {
+ *pdst = RRopPixels(*pdst,bits);
+ pdst++; CHECKRWO(pdst);
+ NextUnnaturalStippleBitsFast
+ }
+ if (endmask)
+ *pdst = MaskRRopPixels (*pdst,bits,endmask);
+ }
+ else
+ {
+ NextUnnaturalStippleBits
+ if (startmask)
+ {
+ *pdst = MaskRRopPixels(*pdst,bits,startmask);
+ pdst++; CHECKRWO(pdst);
+ NextUnnaturalStippleBits
+ }
+ while (nlw--)
+ {
+ *pdst = RRopPixels(*pdst,bits);
+ pdst++; CHECKRWO(pdst);
+ NextUnnaturalStippleBits
+ }
+ if (endmask)
+ *pdst = MaskRRopPixels(*pdst,bits,endmask);
+ }
+ }
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+void
+vga2568Stipple32FS (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ DDXPointPtr ppt; /* pointer to list of start points */
+ int *pwidth; /* pointer to list of n widths */
+ unsigned long *src; /* pointer to bits in stipple, if needed */
+ int stippleHeight; /* height of the stipple */
+ PixmapPtr stipple;
+
+ int nlwDst; /* width in longwords of the dest pixmap */
+ int x,y,w; /* current span */
+ unsigned long startmask;
+ unsigned long endmask;
+ register unsigned long *dst; /* pointer to bits we're writing */
+ register int nlw;
+ unsigned long *dstTmp;
+ int nlwTmp;
+
+ unsigned long *pbits; /* pointer to start of pixmap */
+ register unsigned long xor;
+ register unsigned long mask;
+ register unsigned long bits; /* bits from stipple */
+ int wEnd;
+
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ cfbPrivGCPtr devPriv;
+
+ /*
+ * If nothing is going to actually touch the framebuffer, then
+ * do the work with the cfb routines as they should be slightly faster.
+ */
+
+ if( pDrawable->type != DRAWABLE_WINDOW )
+ {
+ cfb8Stipple32FS (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
+ return;
+ }
+
+ devPriv = cfbGetGCPrivate(pGC);
+ cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ if ( n == 0 )
+ return;
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ stipple = pGC->pRotatedPixmap;
+ src = (unsigned long *)stipple->devPrivate.ptr;
+ stippleHeight = stipple->drawable.height;
+
+ cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
+
+ BANK_FLAG(pbits)
+
+ while (n--)
+ {
+ w = *pwidth++;
+ x = ppt->x;
+ y = ppt->y;
+ ppt++;
+ dst = pbits + (y * nlwDst) + (x >> PWSH);
+ if (((x & PIM) + w) <= PPW)
+ {
+ maskpartialbits(x, w, startmask);
+ endmask = 0;
+ nlw = 0;
+ }
+ else
+ {
+ maskbits (x, w, startmask, endmask, nlw);
+ }
+ bits = src[y % stippleHeight];
+ RotBitsLeft (bits, (x & ((PGSZ-1) & ~PIM)));
+#if PPW == 4
+ if (cfb8StippleRRop == GXcopy)
+ {
+ SETRW(dst);
+ xor = devPriv->xor;
+ if (w < (PGSZ*2))
+ {
+ if (startmask)
+ {
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ *dst = (*dst & ~(mask & startmask)) |
+ (xor & (mask & startmask));
+ dst++; CHECKRWO(dst);
+ RotBitsLeft (bits, PGSZB);
+ }
+ while (nlw--)
+ {
+ WriteBitGroup (dst,xor,GetBitGroup(bits))
+ dst++; CHECKRWO(dst);
+ RotBitsLeft (bits, PGSZB);
+ }
+ if (endmask)
+ {
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ *dst = (*dst & ~(mask & endmask)) |
+ (xor & (mask & endmask));
+ }
+ }
+ else
+ {
+ wEnd = 7 - (nlw & 7);
+ nlw = (nlw >> 3) + 1;
+ dstTmp = dst;
+ nlwTmp = nlw;
+ if (startmask)
+ {
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ *dstTmp = (*dstTmp & ~(mask & startmask)) |
+ (xor & (mask & startmask));
+ dstTmp++; CHECKRWO(dstTmp);
+ RotBitsLeft (bits, PGSZB);
+ }
+ w = 7 - wEnd;
+ SAVE_BANK();
+ while (w--)
+ {
+ dst = dstTmp;
+ RESTORE_BANK();
+ SAVE_BANK();
+ CHECKRWO(dst);
+ dstTmp++;
+ nlw = nlwTmp;
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ xor = xor & mask;
+ mask = ~mask;
+ while (nlw--)
+ {
+ *dst = (*dst & mask) | xor;
+ dst += 8; CHECKRWO(dst);
+ }
+ xor = devPriv->xor;
+ NextBitGroup (bits);
+ }
+ nlwTmp--;
+ w = wEnd + 1;
+ if (endmask)
+ {
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ dst = dstTmp + (nlwTmp << 3);
+ RESTORE_BANK();
+ SAVE_BANK();
+ CHECKRWO(dst);
+ *dst = (*dst & ~(mask & endmask)) |
+ (xor & (mask & endmask));
+ }
+ while (w--)
+ {
+ nlw = nlwTmp;
+ dst = dstTmp;
+ RESTORE_BANK();
+ SAVE_BANK();
+ CHECKRWO(dst);
+ dstTmp++;
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ xor = xor & mask;
+ mask = ~mask;
+ while (nlw--)
+ {
+ *dst = (*dst & mask) | xor;
+ dst += 8; CHECKRWO(dst);
+ }
+ xor = devPriv->xor;
+ NextBitGroup (bits);
+ }
+ }
+ }
+ else
+#endif /* PPW == 4 */
+ {
+ SETRW(dst);
+ if (startmask)
+ {
+ xor = GetBitGroup(bits);
+ *dst = MaskRRopPixels(*dst, xor, startmask);
+ dst++; CHECKRWO(dst);
+ RotBitsLeft (bits, PGSZB);
+ }
+ while (nlw--)
+ {
+ RRopBitGroup(dst, GetBitGroup(bits));
+ dst++; CHECKRWO(dst);
+ RotBitsLeft (bits, PGSZB);
+ }
+ if (endmask)
+ {
+ xor = GetBitGroup(bits);
+ *dst = MaskRRopPixels(*dst, xor, endmask);
+ }
+ }
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+void
+vga2568OpaqueStipple32FS (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ DDXPointPtr ppt; /* pointer to list of start points */
+ int *pwidth; /* pointer to list of n widths */
+ unsigned long *src; /* pointer to bits in stipple, if needed */
+ int stippleHeight; /* height of the stipple */
+ PixmapPtr stipple;
+
+ int nlwDst; /* width in longwords of the dest pixmap */
+ int x,y,w; /* current span */
+ unsigned long startmask;
+ unsigned long endmask;
+ register unsigned long *dst; /* pointer to bits we're writing */
+ register int nlw;
+ unsigned long *dstTmp;
+ int nlwTmp;
+
+ unsigned long *pbits; /* pointer to start of pixmap */
+ register unsigned long xor;
+ register unsigned long bits; /* bits from stipple */
+ int wEnd;
+
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ cfbPrivGCPtr devPriv;
+
+ /*
+ * If nothing is going to actually touch the framebuffer, then
+ * do the work with the cfb routines as they should be slightly faster.
+ */
+
+ if( pDrawable->type != DRAWABLE_WINDOW )
+ {
+ cfb8OpaqueStipple32FS (pDrawable, pGC, nInit, pptInit,
+ pwidthInit, fSorted);
+ return;
+ }
+
+ devPriv = cfbGetGCPrivate(pGC);
+
+ cfb8CheckOpaqueStipple(pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ if ( n == 0 )
+ return;
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ stipple = pGC->pRotatedPixmap;
+ src = (unsigned long *)stipple->devPrivate.ptr;
+ stippleHeight = stipple->drawable.height;
+
+ cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
+
+ BANK_FLAG(pbits)
+
+ while (n--)
+ {
+ w = *pwidth++;
+ x = ppt->x;
+ y = ppt->y;
+ ppt++;
+ dst = pbits + (y * nlwDst) + (x >> PWSH);
+ if (((x & PIM) + w) <= PPW)
+ {
+ maskpartialbits(x, w, startmask);
+ endmask = 0;
+ nlw = 0;
+ }
+ else
+ {
+ maskbits (x, w, startmask, endmask, nlw);
+ }
+ bits = src[y % stippleHeight];
+ RotBitsLeft (bits, (x & ((PGSZ-1) & ~PIM)));
+#if PPW == 4
+ if (cfb8StippleRRop == GXcopy)
+ {
+ SETRW(dst);
+ xor = devPriv->xor;
+ if (w < PGSZ*2)
+ {
+ if (startmask)
+ {
+ *dst = *dst & ~startmask |
+ GetPixelGroup (bits) & startmask;
+ dst++; CHECKRWO(dst);
+ RotBitsLeft (bits, PGSZB);
+ }
+ while (nlw--)
+ {
+ *dst++ = GetPixelGroup(bits);
+ RotBitsLeft (bits, PGSZB);
+ CHECKRWO(dst);
+ }
+ if (endmask)
+ {
+ *dst = *dst & ~endmask |
+ GetPixelGroup (bits) & endmask;
+ }
+ }
+ else
+ {
+ wEnd = 7 - (nlw & 7);
+ nlw = (nlw >> 3) + 1;
+ dstTmp = dst;
+ nlwTmp = nlw;
+ if (startmask)
+ {
+ *dstTmp = *dstTmp & ~startmask |
+ GetPixelGroup (bits) & startmask;
+ dstTmp++; CHECKRWO(dstTmp);
+ RotBitsLeft (bits, PGSZB);
+ }
+ w = 7 - wEnd;
+ SAVE_BANK();
+ while (w--)
+ {
+ nlw = nlwTmp;
+ dst = dstTmp;
+ RESTORE_BANK();
+ SAVE_BANK();
+ CHECKRWO(dst);
+ dstTmp++;
+ xor = GetPixelGroup (bits);
+ while (nlw--)
+ {
+ *dst = xor;
+ dst += 8; CHECKRWO(dst);
+ }
+ NextBitGroup (bits);
+ }
+ nlwTmp--;
+ w = wEnd + 1;
+ if (endmask)
+ {
+ dst = dstTmp + (nlwTmp << 3);
+ RESTORE_BANK();
+ SAVE_BANK();
+ CHECKRWO(dst);
+ *dst = (*dst & ~endmask) |
+ GetPixelGroup (bits) & endmask;
+ }
+ while (w--)
+ {
+ nlw = nlwTmp;
+ dst = dstTmp;
+ RESTORE_BANK();
+ SAVE_BANK();
+ CHECKRWO(dst);
+ dstTmp++;
+ xor = GetPixelGroup (bits);
+ while (nlw--)
+ {
+ *dst = xor;
+ dst += 8; CHECKRWO(dst);
+ }
+ NextBitGroup (bits);
+ }
+ }
+ }
+ else
+#endif /* PPW == 4 */
+ {
+ SETRW(dst);
+ if (startmask)
+ {
+ xor = GetBitGroup(bits);
+ *dst = MaskRRopPixels(*dst, xor, startmask);
+ dst++; CHECKRWO(dst);
+ RotBitsLeft (bits, PGSZB);
+ }
+ while (nlw--)
+ {
+ RRopBitGroup(dst, GetBitGroup(bits));
+ dst++; CHECKRWO(dst);
+ RotBitsLeft (bits, PGSZB);
+ }
+ if (endmask)
+ {
+ xor = GetBitGroup(bits);
+ *dst = MaskRRopPixels(*dst, xor, endmask);
+ }
+ }
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgagc.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgagc.c
new file mode 100644
index 000000000..68a1f088a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgagc.c
@@ -0,0 +1,657 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgagc.c,v 1.2 1998/07/25 16:58:18 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: vgagc.c /main/6 1996/02/21 18:11:05 kaleb $ */
+
+#include "vgafb.h"
+#include "migc.h"
+
+void vga256ValidateGC();
+
+static GCFuncs vga256Funcs = {
+ vga256ValidateGC,
+ miChangeGC,
+ miCopyGC,
+ miDestroyGC,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip,
+};
+
+GCOps vga256TEOps1Rect = {
+ vga256SolidSpansCopy,
+ vga256SetSpans,
+ cfbPutImage,
+ vga256CopyArea,
+ vga256CopyPlane,
+ vga256PolyPoint,
+ vga256LineSS,
+ vga256SegmentSS,
+ miPolyRectangle,
+ vga256ZeroPolyArcSS8Copy,
+ vga256FillPoly1RectCopy,
+ vga256PolyFillRect,
+ vga256PolyFillArcSolidCopy,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ vga256TEGlyphBlt8,
+ vga256PolyGlyphBlt8,
+ vga256PushPixels8,
+ NULL,
+};
+
+GCOps vga256TEOps = {
+ vga256SolidSpansCopy,
+ vga256SetSpans,
+ cfbPutImage,
+ vga256CopyArea,
+ vga256CopyPlane,
+ vga256PolyPoint,
+ vga256LineSS,
+ vga256SegmentSS,
+ miPolyRectangle,
+ vga256ZeroPolyArcSS8Copy,
+ miFillPolygon,
+ vga256PolyFillRect,
+ vga256PolyFillArcSolidCopy,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ vga256TEGlyphBlt8,
+ vga256PolyGlyphBlt8,
+ vga256PushPixels8,
+ NULL,
+};
+
+GCOps vga256NonTEOps1Rect = {
+ vga256SolidSpansCopy,
+ vga256SetSpans,
+ cfbPutImage,
+ vga256CopyArea,
+ vga256CopyPlane,
+ vga256PolyPoint,
+ vga256LineSS,
+ vga256SegmentSS,
+ miPolyRectangle,
+ vga256ZeroPolyArcSS8Copy,
+ vga256FillPoly1RectCopy,
+ vga256PolyFillRect,
+ vga256PolyFillArcSolidCopy,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ cfbImageGlyphBlt8,
+ vga256PolyGlyphBlt8,
+ vga256PushPixels8,
+ NULL,
+};
+
+GCOps vga256NonTEOps = {
+ vga256SolidSpansCopy,
+ vga256SetSpans,
+ cfbPutImage,
+ vga256CopyArea,
+ vga256CopyPlane,
+ vga256PolyPoint,
+ vga256LineSS,
+ vga256SegmentSS,
+ miPolyRectangle,
+ vga256ZeroPolyArcSS8Copy,
+ miFillPolygon,
+ vga256PolyFillRect,
+ vga256PolyFillArcSolidCopy,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ cfbImageGlyphBlt8,
+ vga256PolyGlyphBlt8,
+ vga256PushPixels8,
+ NULL,
+};
+
+GCOps *
+vga256matchCommon (pGC, devPriv)
+ GCPtr pGC;
+ cfbPrivGCPtr devPriv;
+{
+ if (pGC->lineWidth != 0)
+ return 0;
+ if (pGC->lineStyle != LineSolid)
+ return 0;
+ if (pGC->fillStyle != FillSolid)
+ return 0;
+ if (devPriv->rop != GXcopy)
+ return 0;
+ if (pGC->font &&
+ FONTMAXBOUNDS(pGC->font,rightSideBearing) -
+ FONTMINBOUNDS(pGC->font,leftSideBearing) <= 32 &&
+ FONTMINBOUNDS(pGC->font,characterWidth) >= 0)
+ {
+
+ if (TERMINALFONT(pGC->font)
+ && FONTMAXBOUNDS(pGC->font,characterWidth) >= PGSZB
+ )
+ if (devPriv->oneRect)
+ return &vga256TEOps1Rect;
+ else
+ return &vga256TEOps;
+ else
+ if (devPriv->oneRect)
+ return &vga256NonTEOps1Rect;
+ else
+ return &vga256NonTEOps;
+ }
+ return 0;
+}
+
+Bool
+vga256CreateGC(pGC)
+ register GCPtr pGC;
+{
+ cfbPrivGC *pPriv;
+
+ switch (pGC->depth) {
+ case 1:
+ return (mfbCreateGC(pGC));
+ case PSZ:
+ break;
+ default:
+ ErrorF("vga256CreateGC: unsupported depth: %d\n", pGC->depth);
+ return FALSE;
+ }
+ pGC->clientClip = NULL;
+ pGC->clientClipType = CT_NONE;
+
+ /*
+ * some of the output primitives aren't really necessary, since they
+ * will be filled in ValidateGC because of dix/CreateGC() setting all
+ * the change bits. Others are necessary because although they depend
+ * on being a color frame buffer, they don't change
+ */
+
+ pGC->ops = &vga256NonTEOps;
+ pGC->funcs = &vga256Funcs;
+
+ /* cfb wants to translate before scan conversion */
+ pGC->miTranslate = 1;
+
+ pPriv = (cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr);
+ pPriv->rop = pGC->alu;
+ pPriv->oneRect = FALSE;
+ pGC->fExpose = TRUE;
+ pGC->freeCompClip = FALSE;
+ pGC->pRotatedPixmap = (PixmapPtr) NULL;
+ return TRUE;
+}
+
+/* Clipping conventions
+ if the drawable is a window
+ CT_REGION ==> pCompositeClip really is the composite
+ CT_other ==> pCompositeClip is the window clip region
+ if the drawable is a pixmap
+ CT_REGION ==> pCompositeClip is the translated client region
+ clipped to the pixmap boundary
+ CT_other ==> pCompositeClip is the pixmap bounding box
+*/
+
+void
+vga256ValidateGC(pGC, changes, pDrawable)
+ register GCPtr pGC;
+ Mask changes;
+ DrawablePtr pDrawable;
+{
+ int mask; /* stateChanges */
+ int index; /* used for stepping through bitfields */
+ int new_rrop;
+ int new_line, new_text, new_fillspans, new_fillarea;
+ int new_rotate;
+ int xrot, yrot;
+ /* flags for changing the proc vector */
+ cfbPrivGCPtr devPriv;
+ int oneRect;
+
+ new_rotate = pGC->lastWinOrg.x != pDrawable->x ||
+ pGC->lastWinOrg.y != pDrawable->y;
+
+ pGC->lastWinOrg.x = pDrawable->x;
+ pGC->lastWinOrg.y = pDrawable->y;
+ devPriv = cfbGetGCPrivate(pGC);
+
+ new_rrop = FALSE;
+ new_line = FALSE;
+ new_text = FALSE;
+ new_fillspans = FALSE;
+ new_fillarea = FALSE;
+
+ /*
+ * if the client clip is different or moved OR the subwindowMode has
+ * changed OR the window's clip has changed since the last validation
+ * we need to recompute the composite clip
+ */
+
+ if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
+ (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
+ )
+ {
+ miComputeCompositeClip (pGC, pDrawable);
+#ifdef NO_ONE_RECT
+ devPriv->oneRect = FALSE;
+#else
+ oneRect = REGION_NUM_RECTS(pGC->pCompositeClip) == 1;
+ if (oneRect != devPriv->oneRect)
+ new_line = TRUE;
+ devPriv->oneRect = oneRect;
+#endif
+ }
+
+ mask = changes;
+ while (mask) {
+ index = lowbit (mask);
+ mask &= ~index;
+
+ /*
+ * this switch acculmulates a list of which procedures might have
+ * to change due to changes in the GC. in some cases (e.g.
+ * changing one 16 bit tile for another) we might not really need
+ * a change, but the code is being paranoid. this sort of batching
+ * wins if, for example, the alu and the font have been changed,
+ * or any other pair of items that both change the same thing.
+ */
+ switch (index) {
+ case GCFunction:
+ case GCForeground:
+ new_rrop = TRUE;
+ break;
+ case GCPlaneMask:
+ new_rrop = TRUE;
+ new_text = TRUE;
+ break;
+ case GCBackground:
+ break;
+ case GCLineStyle:
+ case GCLineWidth:
+ new_line = TRUE;
+ break;
+ case GCJoinStyle:
+ case GCCapStyle:
+ break;
+ case GCFillStyle:
+ new_text = TRUE;
+ new_fillspans = TRUE;
+ new_line = TRUE;
+ new_fillarea = TRUE;
+ break;
+ case GCFillRule:
+ break;
+ case GCTile:
+ new_fillspans = TRUE;
+ new_fillarea = TRUE;
+ break;
+
+ case GCStipple:
+ if (pGC->stipple)
+ {
+ int width = pGC->stipple->drawable.width;
+ PixmapPtr nstipple;
+
+ if ((width <= PGSZ) && !(width & (width - 1)) &&
+ (nstipple = cfbCopyPixmap(pGC->stipple)))
+ {
+ cfbPadPixmap(nstipple);
+ (*pGC->pScreen->DestroyPixmap)(pGC->stipple);
+ pGC->stipple = nstipple;
+ }
+ }
+ new_fillspans = TRUE;
+ new_fillarea = TRUE;
+ break;
+
+ case GCTileStipXOrigin:
+ new_rotate = TRUE;
+ break;
+
+ case GCTileStipYOrigin:
+ new_rotate = TRUE;
+ break;
+
+ case GCFont:
+ new_text = TRUE;
+ break;
+ case GCSubwindowMode:
+ break;
+ case GCGraphicsExposures:
+ break;
+ case GCClipXOrigin:
+ break;
+ case GCClipYOrigin:
+ break;
+ case GCClipMask:
+ break;
+ case GCDashOffset:
+ break;
+ case GCDashList:
+ break;
+ case GCArcMode:
+ break;
+ default:
+ break;
+ }
+ }
+
+ /*
+ * If the drawable has changed, check its depth & ensure suitable
+ * entries are in the proc vector.
+ */
+ if (pDrawable->serialNumber != (pGC->serialNumber & (DRAWABLE_SERIAL_BITS))) {
+ new_fillspans = TRUE; /* deal with FillSpans later */
+ }
+
+ if (new_rotate || new_fillspans)
+ {
+ Bool new_pix = FALSE;
+
+ xrot = pGC->patOrg.x + pDrawable->x;
+ yrot = pGC->patOrg.y + pDrawable->y;
+
+ switch (pGC->fillStyle)
+ {
+ case FillTiled:
+ if (!pGC->tileIsPixel)
+ {
+ int width = pGC->tile.pixmap->drawable.width * PSZ;
+
+ if ((width <= PGSZ) && !(width & (width - 1)))
+ {
+ cfbCopyRotatePixmap(pGC->tile.pixmap,
+ &pGC->pRotatedPixmap,
+ xrot, yrot);
+ new_pix = TRUE;
+ }
+ }
+ break;
+ case FillStippled:
+ case FillOpaqueStippled:
+ {
+ int width = pGC->stipple->drawable.width;
+
+ if ((width <= PGSZ) && !(width & (width - 1)))
+ {
+ mfbCopyRotatePixmap(pGC->stipple,
+ &pGC->pRotatedPixmap, xrot, yrot);
+ new_pix = TRUE;
+ }
+ }
+ break;
+ }
+ if (!new_pix && pGC->pRotatedPixmap)
+ {
+ (*pGC->pScreen->DestroyPixmap)(pGC->pRotatedPixmap);
+ pGC->pRotatedPixmap = (PixmapPtr) NULL;
+ }
+ }
+
+ if (new_rrop)
+ {
+ int old_rrop;
+
+ old_rrop = devPriv->rop;
+ devPriv->rop = cfbReduceRasterOp (pGC->alu, pGC->fgPixel,
+ pGC->planemask,
+ &devPriv->and, &devPriv->xor);
+ if (old_rrop == devPriv->rop)
+ new_rrop = FALSE;
+ else
+ {
+ new_line = TRUE;
+ new_text = TRUE;
+ new_fillspans = TRUE;
+ new_fillarea = TRUE;
+ }
+ }
+
+ if (new_rrop || new_fillspans || new_text || new_fillarea || new_line)
+ {
+ GCOps *newops;
+
+ if (newops = vga256matchCommon (pGC, devPriv))
+ {
+ if (pGC->ops->devPrivate.val)
+ miDestroyGCOps (pGC->ops);
+ pGC->ops = newops;
+ new_rrop = new_line = new_fillspans = new_text = new_fillarea = 0;
+ }
+ else
+ {
+ if (!pGC->ops->devPrivate.val)
+ {
+ pGC->ops = miCreateGCOps (pGC->ops);
+ pGC->ops->devPrivate.val = 1;
+ }
+ }
+ }
+
+ /* deal with the changes we've collected */
+ if (new_line)
+ {
+ pGC->ops->FillPolygon = miFillPolygon;
+ if (devPriv->oneRect && pGC->fillStyle == FillSolid)
+ {
+ switch (devPriv->rop) {
+ case GXcopy:
+ pGC->ops->FillPolygon = vga256FillPoly1RectCopy;
+ break;
+ default:
+ pGC->ops->FillPolygon = vga256FillPoly1RectGeneral;
+ break;
+ }
+ }
+ if (pGC->lineWidth == 0)
+ {
+#ifdef PIXEL_ADDR
+ if ((pGC->lineStyle == LineSolid) && (pGC->fillStyle == FillSolid))
+ {
+ switch (devPriv->rop)
+ {
+ case GXxor:
+ pGC->ops->PolyArc = vga256ZeroPolyArcSS8Xor;
+ break;
+ case GXcopy:
+ pGC->ops->PolyArc = vga256ZeroPolyArcSS8Copy;
+ break;
+ default:
+ pGC->ops->PolyArc = vga256ZeroPolyArcSS8General;
+ break;
+ }
+ }
+ else
+#endif
+ pGC->ops->PolyArc = miZeroPolyArc;
+ }
+ else
+ pGC->ops->PolyArc = miPolyArc;
+ pGC->ops->PolySegment = miPolySegment;
+ switch (pGC->lineStyle)
+ {
+ case LineSolid:
+ if(pGC->lineWidth == 0)
+ {
+ if (pGC->fillStyle == FillSolid)
+ {
+ pGC->ops->Polylines = vga256LowlevFuncs.lineSS;
+ pGC->ops->PolySegment = vga256LowlevFuncs.segmentSS;
+ }
+ else
+ pGC->ops->Polylines = miZeroLine;
+ }
+ else
+ pGC->ops->Polylines = miWideLine;
+ break;
+ case LineOnOffDash:
+ case LineDoubleDash:
+ if (pGC->lineWidth == 0 && pGC->fillStyle == FillSolid)
+ {
+ pGC->ops->Polylines = vga256LineSD;
+ pGC->ops->PolySegment = vga256SegmentSD;
+ } else
+ pGC->ops->Polylines = miWideDash;
+ break;
+ }
+ }
+
+ if (new_text && (pGC->font))
+ {
+ if (FONTMAXBOUNDS(pGC->font,rightSideBearing) -
+ FONTMINBOUNDS(pGC->font,leftSideBearing) > 32 ||
+ FONTMINBOUNDS(pGC->font,characterWidth) < 0)
+ {
+ pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
+ pGC->ops->ImageGlyphBlt = miImageGlyphBlt;
+ }
+ else
+ {
+ if (pGC->fillStyle == FillSolid)
+ {
+ if (devPriv->rop == GXcopy)
+ pGC->ops->PolyGlyphBlt = vga256PolyGlyphBlt8;
+ else
+ pGC->ops->PolyGlyphBlt = vga256PolyGlyphRop8;
+ }
+ else
+ pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
+ /* special case ImageGlyphBlt for terminal emulator fonts */
+ if (TERMINALFONT(pGC->font) &&
+ (pGC->planemask & PMSK) == PMSK
+ && FONTMAXBOUNDS(pGC->font,characterWidth) >= PGSZB
+ )
+ {
+ pGC->ops->ImageGlyphBlt = vga256LowlevFuncs.teGlyphBlt8;
+ }
+ else
+ {
+ if (devPriv->rop == GXcopy &&
+ pGC->fillStyle == FillSolid &&
+ (pGC->planemask & PMSK) == PMSK)
+ pGC->ops->ImageGlyphBlt = cfbImageGlyphBlt8;
+ else
+ pGC->ops->ImageGlyphBlt = miImageGlyphBlt;
+ }
+ }
+ }
+
+
+ if (new_fillspans) {
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ if (vga256LowlevFuncs.fillSolidSpans != vga256SolidSpansGeneral) {
+ pGC->ops->FillSpans = vga256LowlevFuncs.fillSolidSpans;
+ break;
+ }
+ switch (devPriv->rop) {
+ case GXcopy:
+ pGC->ops->FillSpans = vga256SolidSpansCopy;
+ break;
+ case GXxor:
+ pGC->ops->FillSpans = vga256SolidSpansXor;
+ break;
+ default:
+ pGC->ops->FillSpans = vga256SolidSpansGeneral;
+ break;
+ }
+ break;
+ case FillTiled:
+ if (pGC->pRotatedPixmap)
+ {
+ if (pGC->alu == GXcopy && (pGC->planemask & PMSK) == PMSK)
+ pGC->ops->FillSpans = vga256Tile32FSCopy;
+ else
+ pGC->ops->FillSpans = vga256Tile32FSGeneral;
+ }
+ else
+ pGC->ops->FillSpans = vga256UnnaturalTileFS;
+ break;
+ case FillStippled:
+ if (pGC->pRotatedPixmap)
+ pGC->ops->FillSpans = vga2568Stipple32FS;
+ else
+ pGC->ops->FillSpans = vga256UnnaturalStippleFS;
+ break;
+ case FillOpaqueStippled:
+ if (pGC->pRotatedPixmap)
+ pGC->ops->FillSpans = vga2568OpaqueStipple32FS;
+ else
+ pGC->ops->FillSpans = vga256UnnaturalStippleFS;
+ break;
+ default:
+ FatalError("vga256ValidateGC: illegal fillStyle\n");
+ }
+ } /* end of new_fillspans */
+
+ if (new_fillarea) {
+ pGC->ops->PushPixels = mfbPushPixels;
+ if (pGC->fillStyle == FillSolid && devPriv->rop == GXcopy)
+ pGC->ops->PushPixels = vga256PushPixels8;
+ pGC->ops->PolyFillArc = miPolyFillArc;
+ if (pGC->fillStyle == FillSolid)
+ {
+ switch (devPriv->rop)
+ {
+ case GXcopy:
+ pGC->ops->PolyFillArc = vga256PolyFillArcSolidCopy;
+ break;
+ default:
+ pGC->ops->PolyFillArc = vga256PolyFillArcSolidGeneral;
+ break;
+ }
+ }
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgagetsp.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgagetsp.c
new file mode 100644
index 000000000..507458772
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgagetsp.c
@@ -0,0 +1,169 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgagetsp.c,v 1.2 1998/07/25 16:58:19 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: vgagetsp.c /main/3 1996/02/21 18:11:09 kaleb $ */
+
+#include "vgafb.h"
+
+/* GetSpans -- for each span, gets bits from drawable starting at ppt[i]
+ * and continuing for pwidth[i] bits
+ * Each scanline returned will be server scanline padded, i.e., it will come
+ * out to an integral number of words.
+ */
+void
+vga256GetSpans(pDrawable, wMax, ppt, pwidth, nspans, pchardstStart)
+ DrawablePtr pDrawable; /* drawable from which to get bits */
+ int wMax; /* largest value of all *pwidths */
+ register DDXPointPtr ppt; /* points to start copying from */
+ int *pwidth; /* list of number of bits to copy */
+ int nspans; /* number of scanlines to copy */
+ char *pchardstStart; /* where to put the bits */
+{
+ PixelGroup *pdstStart = (PixelGroup *)pchardstStart;
+ register PixelGroup *pdst; /* where to put the bits */
+ register PixelGroup *psrc; /* where to get the bits */
+ register PixelGroup tmpSrc; /* scratch buffer for bits */
+ PixelGroup *psrcBase; /* start of src bitmap */
+ int widthSrc; /* width of pixmap in bytes */
+ register DDXPointPtr pptLast; /* one past last point to get */
+ int xEnd; /* last pixel to copy from */
+ register int nstart;
+ int nend;
+ PixelGroup startmask, endmask;
+ int nlMiddle, nl, srcBit;
+ int w;
+ PixelGroup *pdstNext;
+
+ /*
+ * If nothing is going to actually touch the framebuffer, then
+ * do the work with the cfb routines as they should be slightly faster.
+ */
+
+ if( pDrawable->type != DRAWABLE_WINDOW )
+ {
+ cfbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pchardstStart);
+ return;
+ }
+
+ switch (pDrawable->bitsPerPixel) {
+ case 1:
+ mfbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pchardstStart);
+ return;
+ case PSZ:
+ break;
+ default:
+ FatalError("cfbGetSpans: invalid depth\n");
+ }
+
+
+ cfbGetLongWidthAndPointer (pDrawable, widthSrc, psrcBase)
+
+ BANK_FLAG(psrcBase)
+
+#ifdef PIXEL_ADDR
+ if ((nspans == 1) && (*pwidth == 1))
+ {
+ psrc = ((PixelGroup *)(psrcBase + (ppt->y * widthSrc)) + ppt->x);
+ SETRW(psrc);
+ tmpSrc = *psrc;
+#if BITMAP_BIT_ORDER == MSBFirst
+ tmpSrc <<= (sizeof (unsigned long) - sizeof (PixelType)) * 8;
+#endif
+ *pdstStart = tmpSrc;
+ return;
+ }
+#endif
+ pdst = pdstStart;
+ pptLast = ppt + nspans;
+ while(ppt < pptLast)
+ {
+ xEnd = min(ppt->x + *pwidth, widthSrc << PWSH);
+ psrc = psrcBase + ppt->y * widthSrc + (ppt->x >> PWSH);
+ SETRW(psrc);
+ w = xEnd - ppt->x;
+ srcBit = ppt->x & PIM;
+ pdstNext = pdst + ((w + PPW - 1) >> PWSH);
+
+ if (srcBit + w <= PPW)
+ {
+ getbits(psrc, srcBit, w, tmpSrc);
+ putbits(tmpSrc, 0, w, pdst, ~((unsigned long)0));
+ pdst++;
+ }
+ else
+ {
+ maskbits(ppt->x, w, startmask, endmask, nlMiddle);
+ nstart = 0;
+ if (startmask)
+ {
+ nstart = PPW - srcBit;
+ getbits(psrc, srcBit, nstart, tmpSrc);
+ putbits(tmpSrc, 0, nstart, pdst, ~((unsigned long)0));
+ if(srcBit + nstart >= PPW)
+ {psrc++;CHECKRWO(psrc);}
+ }
+ nl = nlMiddle;
+ while (nl--)
+ {
+ tmpSrc = *psrc;
+ putbits(tmpSrc, nstart, PPW, pdst, ~((unsigned long)0));
+ psrc++;CHECKRWO(psrc);
+ pdst++;
+ }
+ if (endmask)
+ {
+ nend = xEnd & PIM;
+ getbits(psrc, 0, nend, tmpSrc);
+ putbits(tmpSrc, nstart, nend, pdst, ~((unsigned long)0));
+ }
+ pdst = pdstNext;
+ }
+ ppt++;
+ pwidth++;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgaglblt8.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgaglblt8.c
new file mode 100644
index 000000000..94a9c1c34
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgaglblt8.c
@@ -0,0 +1,422 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgaglblt8.c,v 1.2 1998/07/25 16:58:19 dawes Exp $ */
+/*
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+*/
+/* $XConsortium: vgaglblt8.c /main/3 1996/02/21 18:11:13 kaleb $ */
+
+/*
+ * Poly glyph blt for 8 bit displays. Accepts
+ * an arbitrary font <= 32 bits wide, in Copy mode only.
+ */
+
+#include "vgafb.h"
+
+#define BOX_OVERLAP(box1, box2, xoffset, yoffset) \
+ ((box1)->x1 <= ((int) (box2)->x2 + (xoffset)) && \
+ ((int) (box2)->x1 + (xoffset)) <= (box1)->x2 && \
+ (box1)->y1 <= ((int) (box2)->y2 + (yoffset)) && \
+ ((int) (box2)->y1 + (yoffset)) <= (box1)->y2)
+
+#define BOX_CONTAINS(box1, box2, xoffset, yoffset) \
+ ((box1)->x1 <= ((int) (box2)->x1 + (xoffset)) && \
+ ((int) (box2)->x2 + (xoffset)) <= (box1)->x2 && \
+ (box1)->y1 <= ((int) (box2)->y1 + (yoffset)) && \
+ ((int) (box2)->y2 + (yoffset)) <= (box1)->y2)
+
+#if GLYPHPADBYTES != 4
+#define USE_LEFTBITS
+#endif
+
+#ifdef USE_LEFTBITS
+typedef unsigned char *glyphPointer;
+extern unsigned long endtab[];
+
+#define GlyphBits(bits,width,dst) getleftbits(bits,width,dst); \
+ (dst) &= widthMask; \
+ (bits) += widthGlyph;
+#define GlyphBitsS(bits,width,dst,off) GlyphBits(bits,width,dst); \
+ dst = BitRight (dst, off);
+#else
+typedef CARD32 *glyphPointer;
+
+#define GlyphBits(bits,width,dst) dst = *bits++;
+#define GlyphBitsS(bits,width,dst,off) dst = BitRight(*bits++, off);
+#endif
+
+#ifdef GLYPHROP
+#define vga256PolyGlyphBlt8 vga256PolyGlyphRop8
+#define vga256PolyGlyphBlt8Clipped vga256PolyGlyphRop8Clipped
+
+#undef WriteBitGroup
+#define WriteBitGroup(dst,pixel,bits) RRopBitGroup(dst,bits)
+
+#endif
+
+static void vga256PolyGlyphBlt8Clipped();
+
+#if defined(HAS_STIPPLE_CODE) && !defined(GLYPHROP) && !defined(USE_LEFTBITS)
+#define USE_STIPPLE_CODE
+#endif
+
+#if defined(__GNUC__) && !defined(GLYPHROP) && (defined(mc68020) || defined(mc68000) || defined(__mc68000__)) && !defined(USE_LEFTBITS)
+#include <stip68kgnu.h>
+#endif
+
+#if PSZ == 24
+#define DST_INC 3
+#else
+#define DST_INC (PGSZB >> PWSH)
+#endif
+
+void
+vga256PolyGlyphBlt8 (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ pointer pglyphBase; /* start of array of glyphs */
+{
+ register unsigned long c;
+#ifndef GLYPHROP
+ register unsigned long pixel;
+#endif
+ register unsigned long *dst;
+ register glyphPointer glyphBits;
+ register int xoff;
+
+ FontPtr pfont = pGC->font;
+ CharInfoPtr pci;
+ unsigned long *dstLine;
+ unsigned long *pdstBase;
+ int hTmp;
+ int bwidthDst;
+ int widthDst;
+ int h;
+ BoxRec bbox; /* for clipping */
+ int w;
+ RegionPtr clip;
+ BoxPtr extents;
+#ifdef USE_LEFTBITS
+ int widthGlyph;
+ unsigned long widthMask;
+#endif
+#ifndef STIPPLE
+#ifdef USE_STIPPLE_CODE
+ void (*stipple)();
+ extern void stipplestack (), stipplestackte ();
+
+ stipple = stipplestack;
+ if (FONTCONSTMETRICS(pfont))
+ stipple = stipplestackte;
+#endif
+#endif
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ /* compute an approximate (but covering) bounding box */
+ bbox.x1 = 0;
+ if ((ppci[0]->metrics.leftSideBearing < 0))
+ bbox.x1 = ppci[0]->metrics.leftSideBearing;
+ h = nglyph - 1;
+ w = ppci[h]->metrics.rightSideBearing;
+ while (--h >= 0)
+ w += ppci[h]->metrics.characterWidth;
+ bbox.x2 = w;
+ bbox.y1 = -FONTMAXBOUNDS(pfont,ascent);
+ bbox.y2 = FONTMAXBOUNDS(pfont,descent);
+
+ clip = cfbGetCompositeClip(pGC);
+ extents = &clip->extents;
+
+ if (!clip->data)
+ {
+ if (!BOX_CONTAINS(extents, &bbox, x, y))
+ {
+ if (BOX_OVERLAP (extents, &bbox, x, y))
+ vga256PolyGlyphBlt8Clipped(pDrawable, pGC, x, y,
+ nglyph, ppci, pglyphBase);
+ return;
+ }
+ }
+ else
+ {
+ /* check to make sure some of the text appears on the screen */
+ if (!BOX_OVERLAP (extents, &bbox, x, y))
+ return;
+
+ bbox.x1 += x;
+ bbox.x2 += x;
+ bbox.y1 += y;
+ bbox.y2 += y;
+
+ switch (RECT_IN_REGION(pGC->pScreen, clip, &bbox))
+ {
+ case rgnPART:
+ vga256PolyGlyphBlt8Clipped(pDrawable, pGC, x, y,
+ nglyph, ppci, pglyphBase);
+ case rgnOUT:
+ return;
+ }
+ }
+
+#ifdef GLYPHROP
+ cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
+#else
+ pixel = cfbGetGCPrivate(pGC)->xor;
+#endif
+
+ cfbGetTypedWidthAndPointer (pDrawable, bwidthDst, pdstBase, char, unsigned long)
+
+ BANK_FLAG(pdstBase)
+
+ widthDst = bwidthDst / PGSZB;
+ while (nglyph--)
+ {
+ pci = *ppci++;
+ glyphBits = (glyphPointer) FONTGLYPHBITS(pglyphBase,pci);
+ xoff = x + pci->metrics.leftSideBearing;
+ dstLine = pdstBase +
+ (y - pci->metrics.ascent) * widthDst + (xoff >> PWSH);
+ x += pci->metrics.characterWidth;
+ if (hTmp = pci->metrics.descent + pci->metrics.ascent)
+ {
+ xoff &= PIM;
+#ifdef STIPPLE
+ STIPPLE(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff);
+#else
+#ifdef USE_STIPPLE_CODE
+ (*stipple)(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff);
+#else
+#ifdef USE_LEFTBITS
+ widthGlyph = GLYPHWIDTHBYTESPADDED (pci);
+ widthMask = endtab[w];
+#endif
+ do {
+ dst = dstLine; SETRW(dst);
+ dstLine = (unsigned long *) (((char *) dstLine) + bwidthDst);
+ GlyphBits(glyphBits, w, c)
+ WriteBitGroup(dst, pixel, GetBitGroup(BitRight(c,xoff)));
+ dst+= DST_INC; CHECKRWO(dst);
+ c = BitLeft(c,PGSZB-xoff);
+ while (c)
+ {
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst+=DST_INC; CHECKRWO(dst);
+ }
+ } while (--hTmp);
+#endif /* USE_STIPPLE_CODE else */
+#endif /* STIPPLE else */
+ }
+ }
+}
+
+static void
+vga256PolyGlyphBlt8Clipped (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ unsigned char *pglyphBase; /* start of array of glyphs */
+{
+ register unsigned long c;
+#ifndef GLYPHROP
+ register unsigned long pixel;
+#endif
+ register unsigned long *dst;
+ register glyphPointer glyphBits;
+ register int xoff;
+
+ CharInfoPtr pci;
+ FontPtr pfont = pGC->font;
+ unsigned long *dstLine;
+ unsigned long *pdstBase;
+ CARD32 *clips;
+ int maxAscent, maxDescent;
+ int minLeftBearing;
+ int hTmp;
+ int widthDst;
+ int bwidthDst;
+ int xG, yG;
+ BoxPtr pBox;
+ int numRects;
+ int w;
+ RegionPtr pRegion;
+ int yBand;
+#ifdef GLYPHROP
+ unsigned long bits;
+#endif
+#ifdef USE_LEFTBITS
+ CARD32 *cTmp;
+ int widthGlyph;
+ unsigned long widthMask;
+#endif
+
+#ifdef GLYPHROP
+ cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
+#else
+ pixel = cfbGetGCPrivate(pGC)->xor;
+#endif
+
+ cfbGetTypedWidthAndPointer (pDrawable, bwidthDst, pdstBase, char, unsigned long)
+
+ BANK_FLAG(pdstBase)
+
+ widthDst = bwidthDst / PGSZB;
+ maxAscent = FONTMAXBOUNDS(pfont,ascent);
+ maxDescent = FONTMAXBOUNDS(pfont,descent);
+ minLeftBearing = FONTMINBOUNDS(pfont,leftSideBearing);
+
+ pRegion = cfbGetCompositeClip(pGC);
+
+ pBox = REGION_RECTS(pRegion);
+ numRects = REGION_NUM_RECTS (pRegion);
+ while (numRects && pBox->y2 <= y - maxAscent)
+ {
+ ++pBox;
+ --numRects;
+ }
+ if (!numRects || pBox->y1 >= y + maxDescent)
+ return;
+ yBand = pBox->y1;
+ while (numRects && pBox->y1 == yBand && pBox->x2 <= x + minLeftBearing)
+ {
+ ++pBox;
+ --numRects;
+ }
+ if (!numRects)
+ return;
+ clips = (CARD32 *)ALLOCATE_LOCAL ((maxAscent + maxDescent) *
+ sizeof (CARD32));
+ while (nglyph--)
+ {
+ pci = *ppci++;
+ glyphBits = (glyphPointer) FONTGLYPHBITS(pglyphBase,pci);
+ w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ xG = x + pci->metrics.leftSideBearing;
+ yG = y - pci->metrics.ascent;
+ x += pci->metrics.characterWidth;
+ if (hTmp = pci->metrics.descent + pci->metrics.ascent)
+ {
+ dstLine = pdstBase + yG * widthDst + (xG >> PWSH);
+ xoff = xG & PIM;
+#ifdef USE_LEFTBITS
+ w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ widthGlyph = PADGLYPHWIDTHBYTES(w);
+ widthMask = endtab[w];
+#endif
+ switch (cfb8ComputeClipMasks32 (pBox, numRects, xG, yG, w, hTmp, clips))
+ {
+ case rgnPART:
+#ifdef USE_LEFTBITS
+ cTmp = clips;
+ do {
+ dst = dstLine; SETRW(dst);
+ dstLine = (unsigned long *) (((char *) dstLine) + bwidthDst);
+ GlyphBits(glyphBits, w, c)
+ c &= *cTmp++;
+ if (c)
+ {
+ WriteBitGroup(dst, pixel, GetBitGroup(BitRight(c,xoff)));
+ c = BitLeft(c,PGSZB - xoff);
+ dst+=DST_INC; CHECKRWO(dst);
+ while (c)
+ {
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst+=DST_INC; CHECKRWO(dst);
+ }
+ }
+ } while (--hTmp);
+ break;
+#else
+ {
+ int h;
+
+ h = hTmp;
+ do
+ {
+ --h;
+ clips[h] = clips[h] & glyphBits[h];
+ } while (h);
+ }
+ glyphBits = clips;
+ /* fall through */
+#endif
+ case rgnIN:
+#ifdef STIPPLE
+ STIPPLE(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff);
+#else
+#ifdef USE_STIPPLE_CODE
+ stipplestackte(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff);
+#else
+ do {
+ dst = dstLine; SETRW(dst);
+ dstLine = (unsigned long *) (((char *) dstLine) + bwidthDst);
+ GlyphBits(glyphBits, w, c)
+ if (c)
+ {
+ /* This code originally could read memory locations
+ * that were not mapped. Hence we have to check the
+ * trailing bits to see whether they are zero and if
+ * then skip them correctly. This is no problem for
+ * the GXcopy case, since there only the pixels that
+ * are non-zero are written ...
+ */
+#ifndef GLYPHROP
+ WriteBitGroup(dst, pixel, GetBitGroup(BitRight(c,xoff)));
+ c = BitLeft(c,PGSZB - xoff);
+ dst+=DST_INC; CHECKRWO(dst);
+#else /* GLYPHROP */
+ if (bits = GetBitGroup(BitRight(c,xoff)))
+ WriteBitGroup(dst, pixel, bits);
+ c = BitLeft(c,PGSZB - xoff);
+ dst+=DST_INC; CHECKRWO(dst);
+
+ while (c && ((bits = GetBitGroup(c)) == 0))
+ {
+ NextBitGroup(c);
+ dst+=DST_INC; CHECKRWO(dst);
+ }
+#endif /* GLYPHROP */
+ while (c)
+ {
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst+=DST_INC; CHECKRWO(dst);
+ }
+ }
+ } while (--hTmp);
+#endif /* USE_STIPPLE_CODE else */
+#endif /* STIPPLE else */
+ break;
+ }
+ }
+ }
+ DEALLOCATE_LOCAL (clips);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgaimage.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgaimage.c
new file mode 100644
index 000000000..6acc0ad41
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgaimage.c
@@ -0,0 +1,115 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgaimage.c,v 1.2 1998/07/25 16:58:20 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: vgaimage.c /main/3 1996/02/21 18:11:16 kaleb $ */
+
+#include "vgafb.h"
+
+void
+vga256GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine)
+ DrawablePtr pDrawable;
+ int sx, sy, w, h;
+ unsigned int format;
+ unsigned long planeMask;
+ char *pdstLine;
+{
+ BoxRec box;
+ DDXPointRec ptSrc;
+ RegionRec rgnDst;
+ ScreenPtr pScreen;
+ PixmapPtr pPixmap;
+
+ if ((w == 0) || (h == 0))
+ return;
+ if (pDrawable->bitsPerPixel == 1)
+ {
+ mfbGetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
+ return;
+ }
+ pScreen = pDrawable->pScreen;
+ if (format == ZPixmap)
+ {
+ pPixmap = GetScratchPixmapHeader(pScreen, w, h,
+ pDrawable->depth, pDrawable->bitsPerPixel,
+ PixmapBytePad(w,pDrawable->depth), (pointer)pdstLine);
+ if (!pPixmap)
+ return;
+ if ((planeMask & PMSK) != PMSK)
+ xf86memset((char *)pdstLine,0, pPixmap->devKind * h);
+ ptSrc.x = sx + pDrawable->x;
+ ptSrc.y = sy + pDrawable->y;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = w;
+ box.y2 = h;
+ REGION_INIT(pScreen, &rgnDst, &box, 1);
+ vga256DoBitblt(pDrawable, (DrawablePtr)pPixmap, GXcopy, &rgnDst,
+ &ptSrc, planeMask);
+ REGION_UNINIT(pScreen, &rgnDst);
+ FreeScratchPixmapHeader(pPixmap);
+ }
+ else
+ {
+ pPixmap = GetScratchPixmapHeader(pScreen, w, h, /*depth*/ 1,
+ /*bpp*/ 1, BitmapBytePad(w), (pointer)pdstLine);
+ if (!pPixmap)
+ return;
+
+ ptSrc.x = sx + pDrawable->x;
+ ptSrc.y = sy + pDrawable->y;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = w;
+ box.y2 = h;
+ REGION_INIT(pScreen, &rgnDst, &box, 1);
+ vga256CopyImagePlane (pDrawable, (DrawablePtr)pPixmap, GXcopy, &rgnDst,
+ &ptSrc, planeMask);
+ REGION_UNINIT(pScreen, &rgnDst);
+ FreeScratchPixmapHeader(pPixmap);
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgaline.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgaline.c
new file mode 100644
index 000000000..f6334fd85
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgaline.c
@@ -0,0 +1,492 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgaline.c,v 1.2 1998/07/25 16:58:20 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: vgaline.c /main/7 1996/02/21 18:11:20 kaleb $ */
+
+#include "vgafb.h"
+#include "miline.h"
+#if 0
+#include "xf86.h" /* for xf86VTSema */
+#else
+extern Bool xf86VTSema;
+#endif
+
+extern Bool vgaUseLinearAddressing;
+extern pointer vgaLinearBase;
+
+void
+#ifdef POLYSEGMENT
+#ifdef SPEEDUP
+speedupvga256SegmentSS (pDrawable, pGC, nseg, pSeg)
+#else
+vga256SegmentSS (pDrawable, pGC, nseg, pSeg)
+#endif
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nseg;
+ register xSegment *pSeg;
+#else
+#ifdef SPEEDUP
+speedupvga256LineSS (pDrawable, pGC, mode, npt, pptInit)
+#else
+vga256LineSS (pDrawable, pGC, mode, npt, pptInit)
+#endif
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt; /* number of points */
+ DDXPointPtr pptInit;
+#endif
+{
+ int nboxInit;
+ register int nbox;
+ BoxPtr pboxInit;
+ register BoxPtr pbox;
+#ifndef POLYSEGMENT
+ register DDXPointPtr ppt; /* pointer to list of translated points */
+#endif
+
+ unsigned int oc1; /* outcode of point 1 */
+ unsigned int oc2; /* outcode of point 2 */
+
+ unsigned long *addrl; /* address of destination pixmap */
+ int nlwidth; /* width in longwords of destination pixmap */
+ int xorg, yorg; /* origin of window */
+
+ int adx; /* abs values of dx and dy */
+ int ady;
+ int signdx; /* sign of dx and dy */
+ int signdy;
+ int e, e1, e2; /* bresenham error and increments */
+ int len; /* length of segment */
+ int axis; /* major axis */
+ int octant;
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+
+ /* a bunch of temporaries */
+ int tmp;
+ register int y1, y2;
+ register int x1, x2;
+ RegionPtr cclip;
+ cfbPrivGCPtr devPriv;
+ unsigned long xor, and;
+ int alu;
+
+ /*
+ * The following check does NOT work when writing to the
+ * virtualized screen when VT-switched away.
+ * The current inconsistent behaviour is to use cfb for off-screen
+ * pixmaps, the fastvga256 routines for on-screen lines, and the
+ * fastvga256 routines also for the off-screen pixmap of the
+ * virtualized screen when VT-switched away.
+ * If SPEEDUP is defined, which would apply to ET4000, the speedup
+ * routines are always used.
+ */
+#ifndef SPEEDUP
+ if( pDrawable->type != DRAWABLE_WINDOW )
+ {
+#ifdef POLYSEGMENT
+ cfbSegmentSS(pDrawable, pGC, nseg, pSeg);
+#else
+ cfbLineSS(pDrawable, pGC, mode, npt, pptInit);
+#endif
+ return;
+ }
+#endif
+
+ devPriv = cfbGetGCPrivate(pGC);
+ cclip = pGC->pCompositeClip;
+ pboxInit = REGION_RECTS(cclip);
+ nboxInit = REGION_NUM_RECTS(cclip);
+
+ cfbGetLongWidthAndPointer (pDrawable, nlwidth, addrl)
+
+ /*
+ * This is a temporary hack to really use the non-bankchecking routines
+ * in the fXF86 functions if linear addressing is enabled.
+ */
+ if (vgaUseLinearAddressing && xf86VTSema)
+ addrl = (unsigned long*)((unsigned char *)vgaLinearBase +
+ (unsigned long)((unsigned char *)addrl - (unsigned long)VGABASE));
+
+ BANK_FLAG(addrl)
+
+ alu = devPriv->rop;
+ xor = devPriv->xor;
+ and = devPriv->and;
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+#ifdef POLYSEGMENT
+ while (nseg--)
+#else
+ ppt = pptInit;
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+ while(--npt)
+#endif
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+
+#ifdef POLYSEGMENT
+ x1 = pSeg->x1 + xorg;
+ y1 = pSeg->y1 + yorg;
+ x2 = pSeg->x2 + xorg;
+ y2 = pSeg->y2 + yorg;
+ pSeg++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious)
+ {
+ xorg = x1;
+ yorg = y1;
+ }
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+#endif
+
+ if (x1 == x2)
+ {
+ /* make the line go top to bottom of screen, keeping
+ endpoint semantics
+ */
+ if (y1 > y2)
+ {
+ register int tmp;
+
+ tmp = y2;
+ y2 = y1 + 1;
+ y1 = tmp + 1;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ y1--;
+#endif
+ }
+#ifdef POLYSEGMENT
+ else if (pGC->capStyle != CapNotLast)
+ y2++;
+#endif
+ /* get to first band that might contain part of line */
+ while ((nbox) && (pbox->y2 <= y1))
+ {
+ pbox++;
+ nbox--;
+ }
+
+ if (nbox)
+ {
+ /* stop when lower edge of box is beyond end of line */
+ while((nbox) && (y2 >= pbox->y1))
+ {
+ if ((x1 >= pbox->x1) && (x1 < pbox->x2))
+ {
+ int y1t;
+ /* this box has part of the line in it */
+ y1t = max(y1, pbox->y1);
+ len = min(y2, pbox->y2) - y1t;
+
+#ifdef SPEEDUP
+if (alu == GXcopy)
+ SpeedUpVLine((unsigned char*)(addrl+y1t*nlwidth) + x1, xor, len,
+ nlwidth << 2);
+else
+#endif
+
+ if (len != 0)
+ {
+ fastvga256VertS (alu, and, xor,
+ addrl, nlwidth,
+ x1, y1t, len);
+ }
+ }
+ nbox--;
+ pbox++;
+ }
+ }
+#ifndef POLYSEGMENT
+ y2 = ppt->y + yorg;
+#endif
+ }
+ else if (y1 == y2)
+ {
+ /* force line from left to right, keeping
+ endpoint semantics
+ */
+ if (x1 > x2)
+ {
+ register int tmp;
+
+ tmp = x2;
+ x2 = x1 + 1;
+ x1 = tmp + 1;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ x1--;
+#endif
+ }
+#ifdef POLYSEGMENT
+ else if (pGC->capStyle != CapNotLast)
+ x2++;
+#endif
+
+ /* find the correct band */
+ while( (nbox) && (pbox->y2 <= y1))
+ {
+ pbox++;
+ nbox--;
+ }
+
+ /* try to draw the line, if we haven't gone beyond it */
+ if ((nbox) && (pbox->y1 <= y1))
+ {
+ /* when we leave this band, we're done */
+ tmp = pbox->y1;
+ while((nbox) && (pbox->y1 == tmp))
+ {
+ int x1t;
+
+ if (pbox->x2 <= x1)
+ {
+ /* skip boxes until one might contain start point */
+ nbox--;
+ pbox++;
+ continue;
+ }
+
+ /* stop if left of box is beyond right of line */
+ if (pbox->x1 >= x2)
+ {
+ nbox = 0;
+ break;
+ }
+
+ x1t = max(x1, pbox->x1);
+ len = min(x2, pbox->x2) - x1t;
+
+#ifdef SPEEDUP
+if (alu == GXcopy)
+ SpeedUpHLine((unsigned char*)(addrl+y1*nlwidth) + x1t, xor, len,
+ nlwidth << 2);
+else
+#endif
+
+ if (len != 0)
+ {
+ fastvga256HorzS (alu, and, xor,
+ addrl, nlwidth,
+ x1t, y1, len);
+ }
+ nbox--;
+ pbox++;
+ }
+ }
+#ifndef POLYSEGMENT
+ x2 = ppt->x + xorg;
+#endif
+ }
+ else /* sloped line */
+ {
+ CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy,
+ 1, 1, octant);
+
+ if (adx > ady)
+ {
+ axis = X_AXIS;
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ }
+ else
+ {
+ axis = Y_AXIS;
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ SetYMajorOctant(octant);
+ }
+
+ FIXUP_ERROR(e, octant, bias);
+
+ /* we have bresenham parameters and two points.
+ all we have to do now is clip and draw.
+ */
+
+ while(nbox--)
+ {
+ oc1 = 0;
+ oc2 = 0;
+ OUTCODES(oc1, x1, y1, pbox);
+ OUTCODES(oc2, x2, y2, pbox);
+ if ((oc1 | oc2) == 0)
+ {
+ if (axis == X_AXIS)
+ len = adx;
+ else
+ len = ady;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ len++;
+#endif
+#ifdef SPEEDUP
+ SpeedUpBresS (alu, and, xor,
+ addrl, nlwidth,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e2, len);
+#else
+ fastvga256BresS (alu, and, xor,
+ addrl, nlwidth,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e2, len);
+#endif
+ break;
+ }
+ else if (oc1 & oc2)
+ {
+ pbox++;
+ }
+ else
+ {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int clipdx, clipdy;
+ int err;
+
+ if (miZeroClipLine (pbox->x1, pbox->y1, pbox->x2-1,
+ pbox->y2-1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pbox++;
+ continue;
+ }
+ if (axis == X_AXIS)
+ len = abs(new_x2 - new_x1);
+ else
+ len = abs(new_y2 - new_y1);
+
+#ifdef POLYSEGMENT
+ if (clip2 != 0 || pGC->capStyle != CapNotLast)
+ len++;
+#else
+ len += (clip2 != 0);
+#endif
+ if (len)
+ {
+ /* unwind bresenham error term to first point */
+ if (clip1)
+ {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ if (axis == X_AXIS)
+ err = e+((clipdy*e2) + ((clipdx-clipdy)*e1));
+ else
+ err = e+((clipdx*e2) + ((clipdy-clipdx)*e1));
+ }
+ else
+ err = e;
+#ifdef SPEEDUP
+ SpeedUpBresS
+ (alu, and, xor,
+ addrl, nlwidth,
+ signdx, signdy, axis, new_x1, new_y1,
+ err, e1, e2, len);
+#else
+ fastvga256BresS
+ (alu, and, xor,
+ addrl, nlwidth,
+ signdx, signdy, axis, new_x1, new_y1,
+ err, e1, e2, len);
+#endif
+ }
+ pbox++;
+ }
+ } /* while (nbox--) */
+ } /* sloped line */
+ } /* while (nline--) */
+
+#ifndef POLYSEGMENT
+ /* paint the last point if the end style isn't CapNotLast.
+ (Assume that a projecting, butt, or round cap that is one
+ pixel wide is the same as the single pixel of the endpoint.)
+ */
+
+ if ((pGC->capStyle != CapNotLast) &&
+ ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
+ (ppt->y + yorg != pptInit->y + pDrawable->y) ||
+ (ppt == pptInit + 1)))
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+ while (nbox--)
+ {
+ if ((x2 >= pbox->x1) &&
+ (y2 >= pbox->y1) &&
+ (x2 < pbox->x2) &&
+ (y2 < pbox->y2))
+ {
+ unsigned long *addrb; /* address of destination pixmap */
+ unsigned long mask;
+ unsigned long scrbits;
+
+ mask = cfbmask[x2 & PIM];
+ addrl += (y2 * nlwidth) + (x2 >> PWSH);
+ addrb = addrl; SETRW(addrb);
+ scrbits = *addrb;
+ *addrb = (scrbits & ~mask) |
+ (DoRRop (scrbits, and, xor) & mask);
+ break;
+ }
+ else
+ pbox++;
+ }
+ }
+#endif
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgalined.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgalined.c
new file mode 100644
index 000000000..86df55f2b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgalined.c
@@ -0,0 +1,360 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgalined.c,v 1.2 1998/07/25 16:58:21 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: vgalined.c /main/4 1996/02/21 18:11:24 kaleb $ */
+
+#include "vgafb.h"
+#include "miline.h"
+
+/*
+ * Draw dashed 1-pixel lines.
+ */
+
+void
+#ifdef POLYSEGMENT
+vga256SegmentSD (pDrawable, pGC, nseg, pSeg)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int nseg;
+ register xSegment *pSeg;
+#else
+vga256LineSD( pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt; /* number of points */
+ DDXPointPtr pptInit;
+#endif
+{
+ int nboxInit;
+ register int nbox;
+ BoxPtr pboxInit;
+ register BoxPtr pbox;
+#ifndef POLYSEGMENT
+ register DDXPointPtr ppt; /* pointer to list of translated points */
+#endif
+
+ register unsigned int oc1; /* outcode of point 1 */
+ register unsigned int oc2; /* outcode of point 2 */
+
+ unsigned long *addrl; /* address of destination pixmap */
+ int nlwidth; /* width in longwords of destination pixmap */
+ int xorg, yorg; /* origin of window */
+
+ int adx; /* abs values of dx and dy */
+ int ady;
+ int signdx; /* sign of dx and dy */
+ int signdy;
+ int e, e1, e2; /* bresenham error and increments */
+ int len; /* length of segment */
+ int axis; /* major axis */
+ int octant;
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ int x1, x2, y1, y2;
+ RegionPtr cclip;
+ cfbRRopRec rrops[2];
+ unsigned char *pDash;
+ int dashOffset;
+ int numInDashList;
+ int dashIndex;
+ int isDoubleDash;
+ int dashIndexTmp, dashOffsetTmp;
+ int unclippedlen;
+ cfbPrivGCPtr devPriv;
+
+ if( pDrawable->type != DRAWABLE_WINDOW )
+ {
+#ifdef POLYSEGMENT
+ cfbSegmentSD(pDrawable, pGC, nseg, pSeg);
+#else
+ cfbLineSD(pDrawable, pGC, mode, npt, pptInit);
+#endif
+ return;
+ }
+
+ devPriv = cfbGetGCPrivate(pGC);
+ cclip = pGC->pCompositeClip;
+ rrops[0].rop = devPriv->rop;
+ rrops[0].and = devPriv->and;
+ rrops[0].xor = devPriv->xor;
+ if (pGC->alu == GXcopy)
+ {
+ rrops[1].rop = GXcopy;
+ rrops[1].and = 0;
+ rrops[1].xor = PFILL (pGC->bgPixel);
+ }
+ else
+ {
+ rrops[1].rop = cfbReduceRasterOp (pGC->alu,
+ pGC->bgPixel, pGC->planemask,
+ &rrops[1].and, &rrops[1].xor);
+ }
+ pboxInit = REGION_RECTS(cclip);
+ nboxInit = REGION_NUM_RECTS(cclip);
+
+ cfbGetLongWidthAndPointer (pDrawable, nlwidth, addrl)
+
+ BANK_FLAG(addrl)
+
+ /* compute initial dash values */
+
+ pDash = (unsigned char *) pGC->dash;
+ numInDashList = pGC->numInDashList;
+ isDoubleDash = (pGC->lineStyle == LineDoubleDash);
+ dashIndex = 0;
+ dashOffset = 0;
+ miStepDash ((int)pGC->dashOffset, &dashIndex, pDash,
+ numInDashList, &dashOffset);
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+#ifdef POLYSEGMENT
+ while (nseg--)
+#else
+ ppt = pptInit;
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+ while(--npt)
+#endif
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+
+#ifdef POLYSEGMENT
+ x1 = pSeg->x1 + xorg;
+ y1 = pSeg->y1 + yorg;
+ x2 = pSeg->x2 + xorg;
+ y2 = pSeg->y2 + yorg;
+ pSeg++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious)
+ {
+ xorg = x1;
+ yorg = y1;
+ }
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+#endif
+
+ CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);
+
+ if (adx > ady)
+ {
+ axis = X_AXIS;
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ unclippedlen = adx;
+ }
+ else
+ {
+ axis = Y_AXIS;
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ unclippedlen = ady;
+ SetYMajorOctant(octant);
+ }
+
+ FIXUP_ERROR(e, octant, bias);
+
+ /* we have bresenham parameters and two points.
+ all we have to do now is clip and draw.
+ */
+
+ while(nbox--)
+ {
+ oc1 = 0;
+ oc2 = 0;
+ OUTCODES(oc1, x1, y1, pbox);
+ OUTCODES(oc2, x2, y2, pbox);
+ if ((oc1 | oc2) == 0)
+ {
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ unclippedlen++;
+ dashIndexTmp = dashIndex;
+ dashOffsetTmp = dashOffset;
+ vga256BresD (rrops,
+ &dashIndexTmp, pDash, numInDashList,
+ &dashOffsetTmp, isDoubleDash,
+ addrl, nlwidth,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e2, unclippedlen);
+ break;
+#else
+ vga256BresD (rrops,
+ &dashIndex, pDash, numInDashList,
+ &dashOffset, isDoubleDash,
+ addrl, nlwidth,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e2, unclippedlen);
+ goto dontStep;
+#endif
+ }
+ else if (oc1 & oc2)
+ {
+ pbox++;
+ }
+ else /* have to clip */
+ {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int clipdx, clipdy;
+ int err;
+
+ if (miZeroClipLine (pbox->x1, pbox->y1, pbox->x2-1,
+ pbox->y2-1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pbox++;
+ continue;
+ }
+ dashIndexTmp = dashIndex;
+ dashOffsetTmp = dashOffset;
+ if (clip1)
+ {
+ int dlen;
+
+ if (axis == X_AXIS)
+ dlen = abs(new_x1 - x1);
+ else
+ dlen = abs(new_y2 - y1);
+ miStepDash (dlen, &dashIndexTmp, pDash,
+ numInDashList, &dashOffsetTmp);
+ }
+ if (axis == X_AXIS)
+ len = abs(new_x2 - new_x1);
+ else
+ len = abs(new_y2 - new_y1);
+
+#ifdef POLYSEGMENT
+ if (clip2 != 0 || pGC->capStyle != CapNotLast)
+ len++;
+#else
+ len += (clip2 != 0);
+#endif
+ if (len)
+ {
+ /* unwind bresenham error term to first point */
+ if (clip1)
+ {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ if (axis == X_AXIS)
+ err = e+((clipdy*e2) + ((clipdx-clipdy)*e1));
+ else
+ err = e+((clipdx*e2) + ((clipdy-clipdx)*e1));
+ }
+ else
+ err = e;
+ vga256BresD (rrops,
+ &dashIndexTmp, pDash, numInDashList,
+ &dashOffsetTmp, isDoubleDash,
+ addrl, nlwidth,
+ signdx, signdy, axis, new_x1, new_y1,
+ err, e1, e2, len);
+ }
+ pbox++;
+ }
+ } /* while (nbox--) */
+#ifndef POLYSEGMENT
+ /*
+ * walk the dash list around to the next line
+ */
+ miStepDash (unclippedlen, &dashIndex, pDash,
+ numInDashList, &dashOffset);
+dontStep: ;
+#endif
+ } /* while (nline--) */
+
+#ifndef POLYSEGMENT
+ /* paint the last point if the end style isn't CapNotLast.
+ (Assume that a projecting, butt, or round cap that is one
+ pixel wide is the same as the single pixel of the endpoint.)
+ */
+
+ if ((pGC->capStyle != CapNotLast) &&
+ ((dashIndex & 1) == 0 || isDoubleDash) &&
+ ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
+ (ppt->y + yorg != pptInit->y + pDrawable->y) ||
+ (ppt == pptInit + 1)))
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+ while (nbox--)
+ {
+ unsigned long *addrb; /* address of destination pixmap */
+ if ((x2 >= pbox->x1) &&
+ (y2 >= pbox->y1) &&
+ (x2 < pbox->x2) &&
+ (y2 < pbox->y2))
+ {
+ unsigned long mask;
+ int pix;
+
+ pix = 0;
+ if (dashIndex & 1)
+ pix = 1;
+ mask = cfbmask[x2 & PIM];
+ addrl += (y2 * nlwidth) + (x2 >> PWSH);
+ addrb = addrl; SETRW(addrb);
+ *addrb = DoMaskRRop (*addrb, rrops[pix].and, rrops[pix].xor, mask);
+ break;
+ }
+ else
+ pbox++;
+ }
+ }
+#endif
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgaply1rct.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgaply1rct.c
new file mode 100644
index 000000000..35b611b8e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgaply1rct.c
@@ -0,0 +1,324 @@
+/*
+ * $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgaply1rct.c,v 1.2 1998/07/25 16:58:21 dawes Exp $
+ *
+Copyright (c) 1990 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+/* $XConsortium: vgaply1rct.c /main/4 1996/02/21 18:11:28 kaleb $ */
+
+#include "vgafb.h"
+#include "cfbrrop.h"
+
+void
+RROP_NAME(vga256FillPoly1Rect) (pDrawable, pGC, shape, mode, count, ptsIn)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int count;
+ DDXPointPtr ptsIn;
+{
+ cfbPrivGCPtr devPriv;
+ int nwidth;
+ unsigned long *addrl, *addr;
+ int maxy;
+ int origin;
+ register int vertex1, vertex2;
+ int c;
+ BoxPtr extents;
+ int clip;
+ int y;
+ int *vertex1p, *vertex2p;
+ int *endp;
+ int x1, x2;
+ int dx1, dx2;
+ int dy1, dy2;
+ int e1, e2;
+ int step1, step2;
+ int sign1, sign2;
+ int h;
+ int l, r;
+ unsigned long mask, bits = ~((unsigned long) 0);
+ int nmiddle;
+ RROP_DECLARE
+
+ if (mode == CoordModePrevious)
+ {
+ miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+
+ devPriv = (cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr);
+#ifdef NO_ONE_RECT
+ if (REGION_NUM_RECTS(pGC->pCompositeClip) != 1)
+ {
+ miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+#endif
+ origin = *((int *) &pDrawable->x);
+#if defined(PC98_WAB) || defined(PC98_WABEP)
+ origin -= (origin & 0x4000) << 1;
+#else
+ origin -= (origin & 0x8000) << 1;
+#endif
+ extents = &pGC->pCompositeClip->extents;
+ RROP_FETCH_GCPRIV(devPriv);
+ vertex1 = *((int *) &extents->x1) - origin;
+ vertex2 = *((int *) &extents->x2) - origin - 0x00010001;
+ clip = 0;
+ y = 32767;
+ maxy = 0;
+ vertex2p = (int *) ptsIn;
+ endp = vertex2p + count;
+ if (shape == Convex)
+ {
+ while (count--)
+ {
+ c = *vertex2p;
+ clip |= (c - vertex1) | (vertex2 - c);
+ c = intToY(c);
+ if (c < y)
+ {
+ y = c;
+ vertex1p = vertex2p;
+ }
+ vertex2p++;
+ if (c > maxy)
+ maxy = c;
+ }
+ }
+ else
+ {
+ int yFlip = 0;
+ dx1 = 1;
+ x2 = -1;
+ x1 = -1;
+ while (count--)
+ {
+ c = *vertex2p;
+ clip |= (c - vertex1) | (vertex2 - c);
+ c = intToY(c);
+ if (c < y)
+ {
+ y = c;
+ vertex1p = vertex2p;
+ }
+ vertex2p++;
+ if (c > maxy)
+ maxy = c;
+ if (c == x1)
+ continue;
+ if (dx1 > 0)
+ {
+ if (x2 < 0)
+ x2 = c;
+ else
+ dx2 = dx1 = (c - x1) >> 31;
+ }
+ else
+ if ((c - x1) >> 31 != dx1)
+ {
+ dx1 = ~dx1;
+ yFlip++;
+ }
+ x1 = c;
+ }
+ x1 = (x2 - c) >> 31;
+ if (x1 != dx1)
+ yFlip++;
+ if (x1 != dx2)
+ yFlip++;
+ if (yFlip != 2)
+#if defined(PC98_WAB) || defined(PC98_WABEP)
+ clip = 0x4000;
+#else
+ clip = 0x8000;
+#endif
+ }
+ if (y == maxy)
+ return;
+
+#if defined(PC98_WAB) || defined(PC98_WABEP)
+ if (clip & 0x40004000)
+#else
+ if (clip & 0x80008000)
+#endif
+ {
+ miFillPolygon (pDrawable, pGC, shape, mode, vertex2p - (int *) ptsIn, ptsIn);
+ return;
+ }
+
+#define AddrYPlus(a,y) (unsigned long *) (((unsigned char *) (a)) + (y) * nwidth)
+
+ cfbGetTypedWidthAndPointer(pDrawable, nwidth, addrl, unsigned char, unsigned long);
+
+ BANK_FLAG(addrl)
+
+ addrl = AddrYPlus(addrl,y + pDrawable->y);
+ origin = intToX(origin);
+ vertex2p = vertex1p;
+ vertex2 = vertex1 = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+#define Setup(c,x,vertex,dx,dy,e,sign,step) {\
+ x = intToX(vertex); \
+ if (dy = intToY(c) - y) { \
+ dx = intToX(c) - x; \
+ step = 0; \
+ if (dx >= 0) \
+ { \
+ e = 0; \
+ sign = 1; \
+ if (dx >= dy) {\
+ step = dx / dy; \
+ dx = dx % dy; \
+ } \
+ } \
+ else \
+ { \
+ e = 1 - dy; \
+ sign = -1; \
+ dx = -dx; \
+ if (dx >= dy) { \
+ step = - (dx / dy); \
+ dx = dx % dy; \
+ } \
+ } \
+ } \
+ x += origin; \
+ vertex = c; \
+}
+
+#define Step(x,dx,dy,e,sign,step) {\
+ x += step; \
+ if ((e += dx) > 0) \
+ { \
+ x += sign; \
+ e -= dy; \
+ } \
+}
+ for (;;)
+ {
+ if (y == intToY(vertex1))
+ {
+ do
+ {
+ if (vertex1p == (int *) ptsIn)
+ vertex1p = endp;
+ c = *--vertex1p;
+ Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1)
+ } while (y >= intToY(vertex1));
+ h = dy1;
+ }
+ else
+ {
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ h = intToY(vertex1) - y;
+ }
+ if (y == intToY(vertex2))
+ {
+ do
+ {
+ c = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+ Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2)
+ } while (y >= intToY(vertex2));
+ if (dy2 < h)
+ h = dy2;
+ }
+ else
+ {
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ if ((c = (intToY(vertex2) - y)) < h)
+ h = c;
+ }
+ /* fill spans for this segment */
+ y += h;
+ for (;;)
+ {
+ l = x1;
+ r = x2;
+ nmiddle = x2 - x1;
+ if (nmiddle < 0)
+ {
+ nmiddle = -nmiddle;
+ l = x2;
+ r = x1;
+ }
+#if PPW > 1
+ c = l & PIM;
+ l -= c;
+#endif
+
+#if PGSZ == 32
+#define LWRD_SHIFT 2
+#else /* PGSZ == 64 */
+#define LWRD_SHIFT 3
+#endif /* PGSZ */
+
+#if PWSH > LWRD_SHIFT
+ l = l >> (PWSH - LWRD_SHIFT);
+#endif
+#if PWSH < LWRD_SHIFT
+ l = l << (LWRD_SHIFT - PWSH);
+#endif
+ addr = (unsigned long *) (((char *) addrl) + l);
+ SETRW(addr);
+#if PPW > 1
+ if (c + nmiddle < PPW)
+ {
+ mask = SCRRIGHT (bits,c) ^ SCRRIGHT (bits,c+nmiddle);
+ RROP_SOLID_MASK(addr,mask);
+ }
+ else
+ {
+ if (c)
+ {
+ mask = SCRRIGHT(bits, c);
+ RROP_SOLID_MASK(addr,mask);
+ nmiddle += c - PPW;
+ addr++; CHECKRWO(addr);
+ }
+#endif
+ nmiddle >>= PWSH;
+ while (--nmiddle >= 0) {
+ RROP_SOLID(addr); addr++; CHECKRWO(addr);
+ }
+#if PPW > 1
+ if (mask = ~SCRRIGHT(bits, r & PIM))
+ RROP_SOLID_MASK(addr,mask);
+ }
+#endif
+ if (!--h)
+ break;
+ addrl = AddrYPlus (addrl, 1);
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ }
+ if (y == maxy)
+ break;
+ addrl = AddrYPlus (addrl, 1);
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgapntwin.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgapntwin.c
new file mode 100644
index 000000000..99caf15fa
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgapntwin.c
@@ -0,0 +1,405 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgapntwin.c,v 1.2 1998/07/25 16:58:21 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: vgapntwin.c /main/3 1996/02/21 18:11:32 kaleb $ */
+
+#include "vgafb.h"
+
+void
+vga256PaintWindow(pWin, pRegion, what)
+ WindowPtr pWin;
+ RegionPtr pRegion;
+ int what;
+{
+ register cfbPrivWin *pPrivWin;
+ WindowPtr pBgWin;
+
+ pPrivWin = cfbGetWindowPrivate(pWin);
+
+ switch (what) {
+ case PW_BACKGROUND:
+ switch (pWin->backgroundState) {
+ case None:
+ return;
+ case ParentRelative:
+ do {
+ pWin = pWin->parent;
+ } while (pWin->backgroundState == ParentRelative);
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
+ what);
+ return;
+ case BackgroundPixmap:
+ if (pPrivWin->fastBackground)
+ {
+ vga256FillBoxTile32 ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pPrivWin->pRotatedBackground);
+ return;
+ }
+ else
+ {
+ vga256FillBoxTileOdd ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->background.pixmap,
+ (int) pWin->drawable.x, (int) pWin->drawable.y);
+ return;
+ }
+ break;
+ case BackgroundPixel:
+ (*vga256LowlevFuncs.fillBoxSolid) ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->background.pixel,
+ 0,
+ GXcopy);
+ return;
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel)
+ {
+ (*vga256LowlevFuncs.fillBoxSolid) ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->border.pixel,
+ 0,
+ GXcopy);
+ return;
+ }
+ else if (pPrivWin->fastBorder)
+ {
+ vga256FillBoxTile32 ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pPrivWin->pRotatedBorder);
+ return;
+ }
+ else
+ {
+ for (pBgWin = pWin;
+ pBgWin->backgroundState == ParentRelative;
+ pBgWin = pBgWin->parent);
+
+ vga256FillBoxTileOdd ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->border.pixmap,
+ (int) pBgWin->drawable.x,
+ (int) pBgWin->drawable.y);
+ }
+ break;
+ }
+}
+
+void
+vga256FillBoxSolid (pDrawable, nBox, pBox, pixel1, pixel2, alu)
+ DrawablePtr pDrawable;
+ int nBox;
+ BoxPtr pBox;
+ unsigned long pixel1;
+ unsigned long pixel2;
+ int alu;
+{
+ unsigned char *pdstBase;
+ unsigned long fill2;
+ unsigned char *pdst;
+ register int hcount, vcount, count;
+ int widthPitch;
+ Bool flag;
+ unsigned char * (* func)(
+#if NeedFunctionPrototypes
+ unsigned char *,
+ unsigned long ,
+ unsigned long ,
+ int ,
+ int ,
+ int ,
+ int
+#endif
+);
+ int widthDst;
+ int h;
+ unsigned long fill1;
+ int w;
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pdstBase = (unsigned char *)
+ (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate.ptr);
+ widthDst = (int)
+ (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind);
+ }
+ else
+ {
+ pdstBase = (unsigned char *)(((PixmapPtr)pDrawable)->devPrivate.ptr);
+ widthDst = (int)(((PixmapPtr)pDrawable)->devKind);
+ }
+
+ flag = CHECKSCREEN(pdstBase);
+ fill1 = PFILL(pixel1);
+ fill2 = PFILL(pixel2);
+
+ switch (alu) {
+ case GXcopy: func = fastFillSolidGXcopy; break;
+ case GXor: func = fastFillSolidGXor; break;
+ case GXand: func = fastFillSolidGXand; break;
+ case GXxor: func = fastFillSolidGXxor; break;
+ case GXset: func = fastFillSolidGXset; break;
+ default: return;
+ }
+
+ for (; nBox; nBox--, pBox++)
+ {
+ pdst = pdstBase + pBox->y1 * widthDst + pBox->x1;
+
+ h = pBox->y2 - pBox->y1;
+ w = pBox->x2 - pBox->x1;
+ widthPitch = widthDst - w;
+
+ SETRWF(flag,pdst);
+ vcount = 0;
+
+ while ( h || vcount ) {
+ if (vcount == 0) {
+ hcount = h;
+ if (flag) {
+ hcount = min( hcount,((unsigned char *)vgaWriteTop - pdst) / widthDst);
+ if (hcount == 0) vcount = w;
+ }
+ }
+ if (vcount != 0) {
+ hcount = 1;
+ if (((count = (unsigned char *)vgaWriteTop - pdst) == 0) ||
+ (count >= vcount)) {
+ count = vcount;
+ vcount = 0;
+ h--;
+ } else {
+ vcount -= count;
+ }
+ } else {
+ count = w;
+ h -= hcount;
+ }
+ if (vcount)
+ pdst = (func)(pdst,fill1,fill2,hcount,count,0,0);
+ else
+ pdst = (func)(pdst,fill1,fill2,hcount,count,w,widthPitch);
+ CHECKRWOF(flag,pdst);
+ }
+ }
+}
+
+/* This can be further optimized but it is tricky */
+void
+vga256FillBoxTile32 (pDrawable, nBox, pBox, tile)
+ DrawablePtr pDrawable;
+ int nBox; /* number of boxes to fill */
+ BoxPtr pBox; /* pointer to list of boxes to fill */
+ PixmapPtr tile; /* rotated, expanded tile */
+{
+ register unsigned long srcpix;
+ unsigned long *psrc; /* pointer to bits in tile, if needed */
+ unsigned long *lpsrc, *fpsrc; /* loop version of psrc */
+ int tileHeight; /* height of the tile */
+
+ int nlwDst; /* width in longwords of the dest pixmap */
+ int w; /* width of current box */
+ register int h; /* height of current box */
+ register unsigned long startmask;
+ register unsigned long endmask; /* masks for reggedy bits at either end of line */
+ register unsigned long notstartmask;
+ register unsigned long notendmask;
+
+ int nlwMiddle; /* number of longwords between sides of boxes */
+ int nlwExtra; /* to get from right of box to left of next span */
+ register unsigned int nlw; /* loop version of nlwMiddle */
+ register unsigned long *p; /* pointer to bits we're writing */
+ int y; /* current scan line */
+ Bool flag;
+
+ unsigned long *pbits;/* pointer to start of pixmap */
+
+ tileHeight = tile->drawable.height;
+ psrc = (unsigned long *)tile->devPrivate.ptr;
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pbits = (unsigned long *)
+ (((PixmapPtr)
+ (pDrawable->pScreen->devPrivate))->devPrivate.ptr);
+ nlwDst = (int)
+ (((PixmapPtr)
+ (pDrawable->pScreen->devPrivate))->devKind) >> PWSH;
+ }
+ else
+ {
+ pbits = (unsigned long *)(((PixmapPtr)pDrawable)->devPrivate.ptr);
+ nlwDst = (int)(((PixmapPtr)pDrawable)->devKind) >> PWSH;
+ }
+
+ flag = CHECKSCREEN(pbits);
+ while (nBox--)
+ {
+ w = pBox->x2 - pBox->x1;
+ h = pBox->y2 - pBox->y1;
+ y = pBox->y1;
+ p = pbits + (pBox->y1 * nlwDst) + (pBox->x1 >> PWSH);
+
+ if(flag)p=vgaSetReadWrite(p);
+
+ lpsrc = &psrc[y % tileHeight];
+ fpsrc = &psrc[tileHeight];
+ if ( ((pBox->x1 & PIM) + w) < PPW)
+ {
+ maskpartialbits(pBox->x1, w, startmask);
+ notstartmask = ~startmask;
+ nlwExtra = nlwDst;
+ while (h--)
+ {
+ srcpix = *lpsrc++;
+ if (lpsrc == fpsrc) lpsrc = psrc;
+ *p = (*p & notstartmask) | (srcpix & startmask);
+ p += nlwExtra;
+ if(flag && (void*)p >= vgaWriteTop)
+ p = vgaReadWriteNext(p);
+ }
+ }
+ else
+ {
+ maskbits(pBox->x1, w, startmask, endmask, nlwMiddle);
+ notstartmask = ~startmask;
+ notendmask = ~endmask;
+ nlwExtra = nlwDst - nlwMiddle;
+
+ if (startmask && endmask)
+ {
+ nlwExtra -= 1;
+ while (h--)
+ {
+ srcpix = *lpsrc++;
+ if (lpsrc == fpsrc) lpsrc = psrc;
+ nlw = nlwMiddle;
+ *p = (*p & notstartmask) | (srcpix & startmask);
+ p++;
+ if(flag && (void*)p >= vgaWriteTop)
+ p = vgaReadWriteNext(p);
+ while (nlw--) {
+ *p++ = srcpix;
+ if(flag && (void*)p >= vgaWriteTop)
+ p = vgaReadWriteNext(p);
+ }
+ *p = (*p & notendmask) | (srcpix & endmask);
+ p += nlwExtra;
+ if(flag && (void*)p >= vgaWriteTop)
+ p = vgaReadWriteNext(p);
+ }
+ }
+ else if (startmask && !endmask)
+ {
+ nlwExtra -= 1;
+ while (h--)
+ {
+ srcpix = *lpsrc++;
+ if (lpsrc == fpsrc) lpsrc = psrc;
+ nlw = nlwMiddle;
+ *p = (*p & notstartmask) | (srcpix & startmask);
+ p++;
+ if(flag && (void*)p >= vgaWriteTop)
+ p = vgaReadWriteNext(p);
+ while (nlw--) {
+ *p++ = srcpix;
+ if(flag && (void*)p >= vgaWriteTop)
+ p = vgaReadWriteNext(p);
+ }
+ p += nlwExtra;
+ if(flag && (void*)p >= vgaWriteTop)
+ p = vgaReadWriteNext(p);
+ }
+ }
+ else if (!startmask && endmask)
+ {
+ while (h--)
+ {
+ srcpix = *lpsrc++;
+ if (lpsrc == fpsrc) lpsrc = psrc;
+ nlw = nlwMiddle;
+ while (nlw--) {
+ *p++ = srcpix;
+ if(flag && (void*)p >= vgaWriteTop)
+ p = vgaReadWriteNext(p);
+ }
+ *p = (*p & notendmask) | (srcpix & endmask);
+ p += nlwExtra;
+ if(flag && (void*)p >= vgaWriteTop)
+ p = vgaReadWriteNext(p);
+ }
+ }
+ else /* no ragged bits at either end */
+ {
+ while (h--)
+ {
+ srcpix = *lpsrc++;
+ if (lpsrc == fpsrc) lpsrc = psrc;
+ nlw = nlwMiddle;
+ while (nlw--) {
+ *p++ = srcpix;
+ if(flag && (void*)p >= vgaWriteTop)
+ p = vgaReadWriteNext(p);
+ }
+ p += nlwExtra;
+ if(flag && (void*)p >= vgaWriteTop)
+ p = vgaReadWriteNext(p);
+ }
+ }
+ }
+ pBox++;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgapolypnt.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgapolypnt.c
new file mode 100644
index 000000000..d815321c5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgapolypnt.c
@@ -0,0 +1,128 @@
+/* $XConsortium: vgapolypnt.c /main/4 1996/02/21 18:11:36 kaleb $ */
+/************************************************************
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+********************************************************/
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgapolypnt.c,v 1.2 1998/07/25 16:58:22 dawes Exp $ */
+
+#include "vgafb.h"
+
+#define isClipped(c,ul,lr) ((((c) - (ul)) | ((lr) - (c))) & ClipMask)
+
+#define PointLoop(fill) { \
+ for (nbox = REGION_NUM_RECTS(cclip), pbox = REGION_RECTS(cclip); \
+ --nbox >= 0; \
+ pbox++) \
+ { \
+ c1 = *((INT32 *) &pbox->x1) - off; \
+ c2 = *((INT32 *) &pbox->x2) - off - 0x00010001; \
+ for (ppt = (INT32 *) pptInit, i = npt; --i >= 0;) \
+ { \
+ pt = *ppt++; \
+ if (!isClipped(pt,c1,c2)) { \
+ fill \
+ } \
+ } \
+ } \
+}
+
+void
+vga256PolyPoint(pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode;
+ int npt;
+ xPoint *pptInit;
+{
+ register INT32 pt;
+ register INT32 c1, c2;
+#if defined(PC98_WAB) || defined(PC98_WABEP)
+ register unsigned long ClipMask = 0x40004000;
+#else
+ register unsigned long ClipMask = 0x80008000;
+#endif
+ register unsigned long xor;
+ register unsigned char *addrb;
+ register int nbwidth;
+ unsigned char *addrbt;
+ register INT32 *ppt;
+ RegionPtr cclip;
+ int nbox;
+ register int i;
+ register BoxPtr pbox;
+ unsigned long and;
+ int rop = pGC->alu;
+ int off;
+ cfbPrivGCPtr devPriv;
+ xPoint *pptPrev;
+
+ devPriv = cfbGetGCPrivate(pGC);
+ rop = devPriv->rop;
+ if (rop == GXnoop)
+ return;
+ cclip = pGC->pCompositeClip;
+ xor = devPriv->xor;
+ if ((mode == CoordModePrevious) && (npt > 1))
+ {
+ for (pptPrev = pptInit + 1, i = npt - 1; --i >= 0; pptPrev++)
+ {
+ pptPrev->x += (pptPrev-1)->x;
+ pptPrev->y += (pptPrev-1)->y;
+ }
+ }
+ off = *((int *) &pDrawable->x);
+#if defined(PC98_WAB) || defined(PC98_WABEP)
+ off -= (off & 0x4000) << 1;
+#else
+ off -= (off & 0x8000) << 1;
+#endif
+ cfbGetByteWidthAndPointer(pDrawable, nbwidth, addrb);
+
+ BANK_FLAG(addrb)
+
+ addrb = addrb + pDrawable->y * nbwidth + pDrawable->x;
+ if (rop == GXcopy)
+ {
+ if (!(nbwidth & (nbwidth - 1)))
+ {
+ nbwidth = xf86ffs(nbwidth) - 1;
+ PointLoop(addrbt = addrb + (intToY(pt) << nbwidth) + intToX(pt);
+ SETRW(addrbt); *addrbt = xor;)
+ }
+ else
+ {
+ PointLoop(addrbt = addrb + intToY(pt) * nbwidth + intToX(pt);
+ SETRW(addrbt); *addrbt = xor;)
+ }
+ }
+ else
+ {
+ and = devPriv->and;
+ PointLoop( addrbt = addrb + intToY(pt) * nbwidth + intToX(pt);
+ SETRW(addrbt);
+ *addrbt = DoRRop (*addrbt, and, xor);)
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgapush8.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgapush8.c
new file mode 100644
index 000000000..5d69fac3f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgapush8.c
@@ -0,0 +1,182 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgapush8.c,v 1.2 1998/07/25 16:58:22 dawes Exp $ */
+/*
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+*/
+/* $XConsortium: vgapush8.c /main/3 1996/02/21 18:11:39 kaleb $ */
+
+/*
+ * Push Pixels for 8 bit displays.
+ */
+
+#include "vgafb.h"
+
+#define MFB_CONSTS_ONLY
+#include "maskbits.h"
+
+void
+vga256PushPixels8 (pGC, pBitmap, pDrawable, dx, dy, xOrg, yOrg)
+ GCPtr pGC;
+ PixmapPtr pBitmap;
+ DrawablePtr pDrawable;
+ int dx, dy, xOrg, yOrg;
+{
+ register unsigned long *src, *dst;
+ register unsigned long pixel;
+ register unsigned long c, bits;
+ unsigned long *pdstLine, *psrcLine;
+ unsigned long *pdstBase;
+ int srcWidth;
+ int dstWidth;
+ int xoff;
+ int nBitmapLongs, nPixmapLongs;
+ int nBitmapTmp, nPixmapTmp;
+ unsigned long rightMask;
+ BoxRec bbox;
+ cfbPrivGCPtr devPriv;
+
+ bbox.x1 = xOrg;
+ bbox.y1 = yOrg;
+ bbox.x2 = bbox.x1 + dx;
+ bbox.y2 = bbox.y1 + dy;
+ devPriv = cfbGetGCPrivate(pGC);
+
+ switch (RECT_IN_REGION(pGC->pScreen, pGC->pCompositeClip, &bbox))
+ {
+ case rgnPART:
+ mfbPushPixels(pGC, pBitmap, pDrawable, dx, dy, xOrg, yOrg);
+ case rgnOUT:
+ return;
+ }
+ /*
+ * If nothing is going to actually touch the framebuffer, then
+ * do the work with the cfb routines as they should be slightly faster.
+ */
+
+ if( pDrawable->type != DRAWABLE_WINDOW )
+ {
+ cfbPushPixels8 (pGC, pBitmap, pDrawable, dx, dy, xOrg, yOrg);
+ return;
+ }
+
+ cfbGetLongWidthAndPointer (pDrawable, dstWidth, pdstBase)
+
+ BANK_FLAG(pdstBase)
+
+ psrcLine = (unsigned long *) pBitmap->devPrivate.ptr;
+ srcWidth = (int) pBitmap->devKind >> PWSH;
+
+ pixel = devPriv->xor;
+ xoff = xOrg & PIM;
+ nBitmapLongs = (dx + xoff) >> MFB_PWSH;
+ nPixmapLongs = (dx + PGSZB + xoff) >> PWSH;
+
+ rightMask = ~cfb8BitLenMasks[((dx + xoff) & MFB_PIM)];
+
+ pdstLine = pdstBase + (yOrg * dstWidth) + (xOrg >> PWSH);
+
+ while (dy--)
+ {
+ c = 0;
+ nPixmapTmp = nPixmapLongs;
+ nBitmapTmp = nBitmapLongs;
+ src = psrcLine;
+ dst = pdstLine;
+ SETRW(dst);
+ while (nBitmapTmp--)
+ {
+ bits = *src++;
+ c |= BitRight (bits, xoff);
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst++; CHECKRWO(dst);
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst++; CHECKRWO(dst);
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst++; CHECKRWO(dst);
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst++; CHECKRWO(dst);
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst++; CHECKRWO(dst);
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst++; CHECKRWO(dst);
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst++; CHECKRWO(dst);
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst++; CHECKRWO(dst);
+ nPixmapTmp -= 8;
+ c = 0;
+ if (xoff)
+ c = BitLeft (bits, PGSZ - xoff);
+ }
+ if (BitLeft (rightMask, xoff))
+ c |= BitRight (*src, xoff);
+ c &= rightMask;
+ switch (nPixmapTmp) {
+ case 8:
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst++; CHECKRWO(dst);
+ case 7:
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst++; CHECKRWO(dst);
+ case 6:
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst++; CHECKRWO(dst);
+ case 5:
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst++; CHECKRWO(dst);
+ case 4:
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst++; CHECKRWO(dst);
+ case 3:
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst++; CHECKRWO(dst);
+ case 2:
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst++; CHECKRWO(dst);
+ case 1:
+ WriteBitGroup(dst, pixel, GetBitGroup(c));
+ NextBitGroup(c);
+ dst++; CHECKRWO(dst);
+ case 0:
+ break;
+ }
+ pdstLine += dstWidth;
+ psrcLine += srcWidth;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgapwinS.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgapwinS.c
new file mode 100644
index 000000000..04ac7836f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgapwinS.c
@@ -0,0 +1,82 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgapwinS.c,v 1.2 1998/07/25 16:58:23 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: vgapwinS.c /main/3 1996/02/21 18:11:43 kaleb $ */
+
+#include "vgafb.h"
+
+void
+speedupvga256FillBoxSolid (pDrawable, nBox, pBox, pixel1, pixel2, alu)
+ DrawablePtr pDrawable;
+ int nBox;
+ BoxPtr pBox;
+ unsigned long pixel1;
+ unsigned long pixel2;
+ int alu;
+{
+ unsigned long *pdstBase;
+ register unsigned char *pdstb;
+ int widthDst;
+ int h;
+ unsigned long fill1;
+ int m;
+ int w;
+
+ cfbGetLongWidthAndPointer(pDrawable, widthDst, pdstBase);
+ fill1 = PFILL(pixel1);
+ for (; nBox; nBox--, pBox++)
+ {
+
+ pdstb = (unsigned char*)(pdstBase+pBox->y1*widthDst)+pBox->x1;
+
+ h = pBox->y2 - pBox->y1;
+ w = pBox->x2 - pBox->x1;
+
+ SpeedUpBox(pdstb, fill1, h, w, widthDst << PWSH);
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgarctstp8.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgarctstp8.c
new file mode 100644
index 000000000..012b092f0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgarctstp8.c
@@ -0,0 +1,626 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgarctstp8.c,v 1.2 1998/07/25 16:58:23 dawes Exp $ */
+/*
+ * Fill 32 bit stippled rectangles for 8 bit frame buffers
+ */
+/*
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+Author: Keith Packard, MIT X Consortium
+
+*/
+/* $XConsortium: vgarctstp8.c /main/4 1996/02/21 18:11:47 kaleb $ */
+
+#include "vgafb.h"
+
+#define MFB_CONSTS_ONLY
+#include "maskbits.h"
+
+void
+#ifdef SPEEDUP
+speedupvga2568FillRectOpaqueStippled32 (pDrawable, pGC, nBox, pBox)
+#else
+vga2568FillRectOpaqueStippled32 (pDrawable, pGC, nBox, pBox)
+#endif
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nBox; /* number of boxes to fill */
+ register BoxPtr pBox; /* pointer to list of boxes to fill */
+{
+ unsigned long *src;
+ int stippleHeight;
+
+ int nlwDst; /* width in longwords of the dest pixmap */
+ int w; /* width of current box */
+ register int h; /* height of current box */
+ unsigned long startmask;
+ unsigned long endmask; /* masks for reggedy bits at either end of line */
+ int nlwMiddle; /* number of longwords between sides of boxes */
+ register int nlw; /* loop version of nlwMiddle */
+ unsigned long *dstLine;
+ register unsigned long *dst; /* pointer to bits we're writing */
+ int y; /* current scan line */
+
+ unsigned long *pbits;/* pointer to start of pixmap */
+ register unsigned long bits; /* bits from stipple */
+ int rot;
+ register unsigned long xor;
+ PixmapPtr stipple;
+#ifdef SPEEDUP
+ unsigned long *dstTmp;
+ int wEnd;
+#endif
+
+ stipple = pGC->pRotatedPixmap;
+
+ cfb8CheckOpaqueStipple(pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
+
+ stippleHeight = stipple->drawable.height;
+ src = (unsigned long *)stipple->devPrivate.ptr;
+
+ cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
+
+ BANK_FLAG(pbits);
+
+ while (nBox--)
+ {
+ w = pBox->x2 - pBox->x1;
+ h = pBox->y2 - pBox->y1;
+ y = pBox->y1;
+ dstLine = pbits + (pBox->y1 * nlwDst) + ((pBox->x1 & ~PIM) >> PWSH);
+ if (((pBox->x1 & PIM) + w) <= PPW)
+ {
+ maskpartialbits(pBox->x1, w, startmask);
+ nlwMiddle = 0;
+ endmask = 0;
+ }
+ else
+ {
+ maskbits (pBox->x1, w, startmask, endmask, nlwMiddle);
+ }
+ rot = (pBox->x1 & ((PGSZ-1) & ~PIM));
+ pBox++;
+ y = y % stippleHeight;
+
+#ifdef SPEEDUP
+ if (cfb8StippleRRop == GXcopy)
+ {
+ if (w < PGSZ*2)
+ {
+ while (h--)
+ {
+ bits = src[y];
+ y++;
+ if (y == stippleHeight)
+ y = 0;
+ if (rot)
+ RotBitsLeft(bits,rot);
+ dst = dstLine;
+ SETRW(dst);
+ dstLine += nlwDst;
+ if (startmask)
+ {
+ *dst = *dst & ~startmask |
+ GetPixelGroup (bits) & startmask;
+ dst++; CHECKRWO(dst);
+ RotBitsLeft (bits, PGSZB);
+ }
+ nlw = nlwMiddle;
+ while (nlw--)
+ {
+ *dst++ = GetPixelGroup(bits);
+ RotBitsLeft (bits, PGSZB);
+ CHECKRWO(dst);
+ }
+ if (endmask)
+ {
+ *dst = *dst & ~endmask |
+ GetPixelGroup (bits) & endmask;
+ }
+ }
+ }
+ else
+ {
+ wEnd = 7 - (nlwMiddle & 7);
+ nlwMiddle = (nlwMiddle >> 3) + 1;
+ while (h--)
+ {
+ bits = src[y];
+ y++;
+ if (y == stippleHeight)
+ y = 0;
+ if (rot != 0)
+ RotBitsLeft (bits, rot);
+ dstTmp = dstLine;
+ SETRW(dstTmp);
+ dstLine += nlwDst;
+ if (startmask)
+ {
+ *dstTmp = *dstTmp & ~startmask |
+ GetPixelGroup (bits) & startmask;
+ dstTmp++; CHECKRWO(dstTmp);
+ RotBitsLeft (bits, PGSZB);
+ }
+ w = 7 - wEnd;
+ SAVE_BANK()
+ while (w--)
+ {
+ nlw = nlwMiddle;
+ dst = dstTmp;
+ RESTORE_BANK()
+ CHECKRWO(dst);
+ SAVE_BANK()
+ dstTmp++;
+ xor = GetPixelGroup (bits);
+ while (nlw--)
+ {
+ *dst = xor;
+ dst += 8; CHECKRWO(dst);
+ }
+ NextBitGroup (bits);
+ }
+ nlwMiddle--;
+ w = wEnd + 1;
+ if (endmask)
+ {
+ dst = dstTmp + (nlwMiddle << 3);
+ RESTORE_BANK()
+ SAVE_BANK()
+ CHECKRWO(dst);
+ *dst = (*dst & ~endmask) |
+ GetPixelGroup (bits) & endmask;
+ }
+ while (w--)
+ {
+ nlw = nlwMiddle;
+ dst = dstTmp;
+ RESTORE_BANK()
+ CHECKRWO(dst);
+ SAVE_BANK()
+ dstTmp++;
+ xor = GetPixelGroup (bits);
+ while (nlw--)
+ {
+ *dst = xor;
+ dst += 8; CHECKRWO(dst);
+ }
+ NextBitGroup (bits);
+ }
+ nlwMiddle++;
+ }
+ }
+ }
+ else
+#endif
+ {
+ while (h--)
+ {
+ bits = src[y];
+ y++;
+ if (y == stippleHeight)
+ y = 0;
+ if (rot)
+ RotBitsLeft(bits,rot);
+ dst = dstLine;
+ SETRW(dst);
+ dstLine += nlwDst;
+ if (startmask)
+ {
+ xor = GetBitGroup(bits);
+ *dst = MaskRRopPixels(*dst, xor, startmask);
+ dst++; CHECKRWO(dst);
+ RotBitsLeft (bits, PGSZB);
+ }
+ nlw = nlwMiddle;
+ while (nlw--)
+ {
+ RRopBitGroup(dst, GetBitGroup(bits));
+ dst++; CHECKRWO(dst);
+ RotBitsLeft (bits, PGSZB);
+ }
+ if (endmask)
+ {
+ xor = GetBitGroup(bits);
+ *dst = MaskRRopPixels(*dst, xor, endmask);
+ }
+ }
+ }
+ }
+}
+
+void
+#ifdef SPEEDUP
+speedupvga2568FillRectTransparentStippled32 (pDrawable, pGC, nBox, pBox)
+#else
+vga2568FillRectTransparentStippled32 (pDrawable, pGC, nBox, pBox)
+#endif
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nBox; /* number of boxes to fill */
+ BoxPtr pBox; /* pointer to list of boxes to fill */
+{
+ int x, y, w, h;
+ int nlwMiddle, nlwDst;
+ unsigned long startmask, endmask;
+ register unsigned long *dst;
+ unsigned long *dstLine, *pbits;
+ unsigned long *src;
+ register unsigned long xor;
+ register unsigned long bits;
+ int rot;
+ cfbPrivGCPtr devPriv;
+ PixmapPtr stipple;
+ int stippleHeight;
+ register int nlw;
+#ifdef SPEEDUP
+ unsigned long *dstTmp;
+ register unsigned long mask;
+ int wEnd;
+#endif
+
+ devPriv = cfbGetGCPrivate(pGC);
+ stipple = pGC->pRotatedPixmap;
+ src = (unsigned long *)stipple->devPrivate.ptr;
+ stippleHeight = stipple->drawable.height;
+
+ cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
+
+ cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
+
+ BANK_FLAG(pbits);
+
+ while (nBox--)
+ {
+ x = pBox->x1;
+ w = pBox->x2 - x;
+ if (((x & PIM) + w) <= PPW)
+ {
+ maskpartialbits(x, w, startmask);
+ endmask = 0;
+ nlwMiddle = 0;
+ }
+ else
+ {
+ maskbits (x, w, startmask, endmask, nlwMiddle);
+ }
+ rot = (x & ((PGSZ-1) & ~PIM));
+ y = pBox->y1;
+ dstLine = pbits + (y * nlwDst) + (x >> PWSH);
+ h = pBox->y2 - y;
+ pBox++;
+ y %= stippleHeight;
+#ifdef SPEEDUP
+ if (cfb8StippleRRop == GXcopy)
+ {
+ xor = devPriv->xor;
+ if (w < PGSZ*2)
+ {
+ while (h--)
+ {
+ bits = src[y];
+ y++;
+ if (y == stippleHeight)
+ y = 0;
+ if (rot != 0)
+ RotBitsLeft (bits, rot);
+ dst = dstLine;
+ SETRW(dst);
+ dstLine += nlwDst;
+ if (startmask)
+ {
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ *dst = (*dst & ~(mask & startmask)) |
+ (xor & (mask & startmask));
+ dst++; CHECKRWO(dst);
+ RotBitsLeft (bits, PGSZB);
+ }
+ nlw = nlwMiddle;
+ while (nlw--)
+ {
+ WriteBitGroup (dst,xor,GetBitGroup(bits))
+ dst++; CHECKRWO(dst);
+ RotBitsLeft (bits, PGSZB);
+ }
+ if (endmask)
+ {
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ *dst = (*dst & ~(mask & endmask)) |
+ (xor & (mask & endmask));
+ }
+ }
+ }
+ else
+ {
+ wEnd = 7 - (nlwMiddle & 7);
+ nlwMiddle = (nlwMiddle >> 3) + 1;
+ while (h--)
+ {
+ bits = src[y];
+ y++;
+ if (y == stippleHeight)
+ y = 0;
+ if (rot != 0)
+ RotBitsLeft (bits, rot);
+ dstTmp = dstLine;
+ SETRW(dstTmp);
+ dstLine += nlwDst;
+ if (startmask)
+ {
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ *dstTmp = (*dstTmp & ~(mask & startmask)) |
+ (xor & (mask & startmask));
+ dstTmp++; CHECKRWO(dstTmp);
+ RotBitsLeft (bits, PGSZB);
+ }
+ w = 7 - wEnd;
+ SAVE_BANK()
+ while (w--)
+ {
+ nlw = nlwMiddle;
+ dst = dstTmp;
+ RESTORE_BANK()
+ CHECKRWO(dst);
+ SAVE_BANK()
+ dstTmp++;
+#if defined(__GNUC__) && defined(mc68020)
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ xor = xor & mask;
+ mask = ~mask;
+ while (nlw--)
+ {
+ *dst = (*dst & mask) | xor;
+ dst += 8;
+ }
+ xor = devPriv->xor;
+#else
+#define SwitchBitsLoop(body) \
+ while (nlw--) \
+ { \
+ body \
+ dst += 8; CHECKRWO(dst); \
+ }
+ SwitchBitGroup(dst, xor, GetBitGroup(bits));
+#undef SwitchBitsLoop
+#endif
+ NextBitGroup (bits);
+ }
+ nlwMiddle--;
+ w = wEnd + 1;
+ if (endmask)
+ {
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ dst = dstTmp + (nlwMiddle << 3);
+ RESTORE_BANK()
+ SAVE_BANK()
+ CHECKRWO(dst);
+ *dst = (*dst & ~(mask & endmask)) |
+ (xor & (mask & endmask));
+ }
+ while (w--)
+ {
+ nlw = nlwMiddle;
+ dst = dstTmp;
+ RESTORE_BANK()
+ CHECKRWO(dst);
+ SAVE_BANK()
+ dstTmp++;
+#if defined(__GNUC__) && defined(mc68020)
+ mask = cfb8PixelMasks[GetBitGroup(bits)];
+ xor = xor & mask;
+ mask = ~mask;
+ while (nlw--)
+ {
+ *dst = (*dst & mask) | xor;
+ dst += 8;
+ }
+ xor = devPriv->xor;
+#else
+#define SwitchBitsLoop(body) \
+ while (nlw--) \
+ { \
+ body \
+ dst += 8; CHECKRWO(dst); \
+ }
+ SwitchBitGroup(dst, xor, GetBitGroup(bits));
+#undef SwitchBitsLoop
+#endif
+ NextBitGroup (bits);
+ }
+ nlwMiddle++;
+ }
+ }
+ }
+ else
+#endif
+ {
+ while (h--)
+ {
+ bits = src[y];
+ y++;
+ if (y == stippleHeight)
+ y = 0;
+ if (rot != 0)
+ RotBitsLeft (bits, rot);
+ dst = dstLine;
+ SETRW(dst);
+ dstLine += nlwDst;
+ if (startmask)
+ {
+ xor = GetBitGroup(bits);
+ *dst = MaskRRopPixels(*dst, xor, startmask);
+ dst++; CHECKRWO(dst);
+ RotBitsLeft (bits, PGSZB);
+ }
+ nlw = nlwMiddle;
+ while (nlw--)
+ {
+ RRopBitGroup(dst, GetBitGroup(bits));
+ dst++; CHECKRWO(dst);
+ RotBitsLeft (bits, PGSZB);
+ }
+ if (endmask)
+ {
+ xor = GetBitGroup(bits);
+ *dst = MaskRRopPixels(*dst, xor, endmask);
+ }
+ }
+ }
+ }
+}
+
+#if defined(SPEEDUP) || defined(__alpha__) || defined(__powerpc__)
+void
+vga2568FillRectStippledUnnatural (pDrawable, pGC, nBox, pBox)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nBox;
+ register BoxPtr pBox;
+{
+ unsigned long *pdstBase; /* pointer to start of bitmap */
+ unsigned long *pdstLine; /* current destination line */
+ int nlwDst; /* width in longwords of bitmap */
+ PixmapPtr pStipple; /* pointer to stipple we want to fill with */
+ int nlwMiddle;
+ register int nlw;
+ int x, y, w, h, xrem, xSrc, ySrc;
+ int stwidth, stippleWidth;
+ int stippleHeight;
+ register unsigned long bits, inputBits;
+ register int partBitsLeft;
+ int nextPartBits;
+ int bitsLeft, bitsWhole;
+ register unsigned long *pdst; /* pointer to current word in bitmap */
+ unsigned long *srcTemp, *srcStart;
+ unsigned long *psrcBase;
+ unsigned long startmask, endmask;
+
+ if (pGC->fillStyle == FillStippled)
+ cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
+ else
+ cfb8CheckOpaqueStipple (pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
+
+ if (cfb8StippleRRop == GXnoop)
+ return;
+
+ /*
+ * OK, so what's going on here? We have two Drawables:
+ *
+ * The Stipple:
+ * Depth = 1
+ * Width = stippleWidth
+ * Words per scanline = stwidth
+ * Pointer to pixels = pStipple->devPrivate.ptr
+ */
+
+ pStipple = pGC->stipple;
+
+ stwidth = pStipple->devKind >> PWSH;
+ stippleWidth = pStipple->drawable.width;
+ stippleHeight = pStipple->drawable.height;
+ psrcBase = (unsigned long *) pStipple->devPrivate.ptr;
+
+ /*
+ * The Target:
+ * Depth = PSZ
+ * Width = determined from *pwidth
+ * Words per scanline = nlwDst
+ * Pointer to pixels = addrlBase
+ */
+
+ xSrc = pDrawable->x;
+ ySrc = pDrawable->y;
+
+ cfbGetLongWidthAndPointer (pDrawable, nlwDst, pdstBase)
+
+ BANK_FLAG(pdstBase)
+
+ /* this replaces rotating the stipple. Instead we just adjust the offset
+ * at which we start grabbing bits from the stipple.
+ * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
+ * so that iline and xrem always stay within the stipple bounds.
+ */
+
+ xSrc += (pGC->patOrg.x % stippleWidth) - stippleWidth;
+ ySrc += (pGC->patOrg.y % stippleHeight) - stippleHeight;
+
+ bitsWhole = stippleWidth;
+
+ while (nBox--)
+ {
+ x = pBox->x1;
+ y = pBox->y1;
+ w = pBox->x2 - x;
+ h = pBox->y2 - y;
+ pBox++;
+ pdstLine = pdstBase + y * nlwDst + (x >> PWSH);
+ y = (y - ySrc) % stippleHeight;
+ srcStart = psrcBase + y * stwidth;
+ xrem = ((x & ~PIM) - xSrc) % stippleWidth;
+ if (((x & PIM) + w) < PPW)
+ {
+ maskpartialbits (x, w, startmask);
+ nlwMiddle = 0;
+ endmask = 0;
+ }
+ else
+ {
+ maskbits (x, w, startmask, endmask, nlwMiddle);
+ }
+ while (h--)
+ {
+ srcTemp = srcStart + (xrem >> MFB_PWSH);
+ bitsLeft = stippleWidth - (xrem & ~MFB_PIM);
+ NextUnnaturalStippleWord
+ NextSomeBits (inputBits, (xrem & MFB_PIM));
+ partBitsLeft -= (xrem & MFB_PIM);
+ NextUnnaturalStippleBits
+ nlw = nlwMiddle;
+ pdst = pdstLine;
+ SETRW(pdst);
+ if (startmask)
+ {
+ *pdst = MaskRRopPixels(*pdst,bits,startmask);
+ pdst++; CHECKRWO(pdst);
+ NextUnnaturalStippleBits
+ }
+ while (nlw--)
+ {
+ *pdst = RRopPixels(*pdst,bits);
+ pdst++; CHECKRWO(pdst);
+ NextUnnaturalStippleBits
+ }
+ if (endmask)
+ *pdst = MaskRRopPixels(*pdst,bits,endmask);
+ pdstLine += nlwDst;
+ y++;
+ srcStart += stwidth;
+ if (y == stippleHeight)
+ {
+ y = 0;
+ srcStart = psrcBase;
+ }
+ }
+ }
+}
+#endif /* SPEEDUP || __alpha__ */
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgascrinit.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgascrinit.c
new file mode 100644
index 000000000..1468426dd
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgascrinit.c
@@ -0,0 +1,153 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgascrinit.c,v 1.2 1998/07/25 16:58:24 dawes Exp $ */
+/************************************************************
+Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
+
+ 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 no-
+tice appear in all copies and that both that copyright no-
+tice and this permission notice appear in supporting docu-
+mentation, and that the names of Sun or X Consortium
+not be used in advertising or publicity pertaining to
+distribution of the software without specific prior
+written permission. Sun and X Consortium make no
+representations about the suitability of this software for
+any purpose. It is provided "as is" without any express or
+implied warranty.
+
+SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
+NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
+ABLE 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.
+
+********************************************************/
+/* $XConsortium: vgascrinit.c /main/4 1996/10/25 06:21:10 kaleb $ */
+
+#include "vgafb.h"
+#include "mibstore.h"
+
+/*
+ * we need some global variables in this module; let's make them module
+ * specific and figure out how to fill them in from the values in the
+ * ScrnInfoRec
+ */
+void *vgaReadBottom = NULL;
+void *vgaReadTop = NULL;
+void *vgaWriteBottom = NULL;
+void *vgaWriteTop = NULL;
+Bool vgaReadFlag, vgaWriteFlag;
+int vgaSegmentShift,vgaSegmentMask,vgaSegmentSize;
+int vgaBase,vgaLinearBase;
+Bool vgaUseLinearAddressing;
+void (*vgaSetReadFunc)(int);
+void (*vgaSetWriteFunc)(int);
+void (*vgaSetReadWriteFunc)(int);
+CfbfuncRec vga256LowlevFuncs;
+
+/*
+ * Most of this code is copied from cfbscrinit.c. It is necessary
+ * to copy the code because of the call to miInitializeBackingStore()
+ * which can't be called twice due to the wrapper mechanism used.
+ *
+ * This code should be kept in sync with Xserver/cfb/cfbscrinit.c.
+ */
+
+BSFuncRec vga256BSFuncRec = {
+ vga256SaveAreas,
+ vga256RestoreAreas,
+ (BackingStoreSetClipmaskRgnProcPtr) 0,
+ (BackingStoreGetImagePixmapProcPtr) 0,
+ (BackingStoreGetSpansPixmapProcPtr) 0,
+};
+
+vga256FinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width)
+ register ScreenPtr pScreen;
+ pointer pbits; /* pointer to screen bitmap */
+ int xsize, ysize; /* in pixels */
+ int dpix, dpiy; /* dots per inch */
+ int width; /* pixel width of frame buffer */
+{
+#ifdef CFB_NEED_SCREEN_PRIVATE
+ pointer oldDevPrivate;
+#endif
+ VisualPtr visuals;
+ DepthPtr depths;
+ int nvisuals;
+ int ndepths;
+ int rootdepth;
+ VisualID defaultVisual;
+ /*
+ * we need to figure out where to get this information from
+ */
+ Bool vgaDAC8BitComponents = FALSE;
+
+ rootdepth = 0;
+ if (!cfbInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
+ &defaultVisual,((unsigned long)1<<(PSZ-1)),
+ vgaDAC8BitComponents ? 8 : 6))
+ return FALSE;
+#ifdef CFB_NEED_SCREEN_PRIVATE
+ oldDevPrivate = pScreen->devPrivate;
+#endif
+ if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
+ rootdepth, ndepths, depths,
+ defaultVisual, nvisuals, visuals))
+ return FALSE;
+ /* overwrite miCloseScreen with our own */
+ pScreen->CloseScreen = cfbCloseScreen;
+ pScreen->BackingStoreFuncs = vga256BSFuncRec;
+#ifdef CFB_NEED_SCREEN_PRIVATE
+ pScreen->CreateScreenResources = cfbCreateScreenResources;
+ pScreen->devPrivates[cfbScreenPrivateIndex].ptr = pScreen->devPrivate;
+ pScreen->devPrivate = oldDevPrivate;
+#endif
+ pScreen->GetScreenPixmap = cfbGetScreenPixmap;
+ pScreen->SetScreenPixmap = cfbSetScreenPixmap;
+ return TRUE;
+}
+
+Bool
+vga256ScreenInit(ScreenPtr pScreen, vgaHWPtr hwp, pointer pbits,
+ int xsize, int ysize, int dpix, int dpiy, int width)
+{
+ /*
+ * first we init our globals from the information that was passed in
+ */
+ vgaReadBottom = hwp->ReadBottom;
+ vgaReadTop = hwp->ReadTop;
+ vgaWriteBottom = hwp->WriteBottom;
+ vgaWriteTop = hwp->WriteTop;
+ vgaSegmentShift = hwp->SegmentShift;
+ vgaSegmentMask = hwp->SegmentMask;
+ vgaSegmentSize = hwp->SegmentSize;
+ vgaBase = hwp->Base;
+ vgaLinearBase = hwp->LinearBase;
+ vgaUseLinearAddressing = hwp->UseLinearAddressing;
+
+ vgaSetReadFunc = hwp->SetReadFunc;
+ vgaSetWriteFunc = hwp->SetWriteFunc;
+ vgaSetReadWriteFunc = hwp->SetReadWriteFunc;
+
+ if (!cfbSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width))
+ return FALSE;
+
+ /* These overrides what was being set in cfbSetupScreen() */
+
+ pScreen->GetImage = vga256GetImage;
+ pScreen->GetSpans = vga256GetSpans;
+ pScreen->PaintWindowBackground = vga256PaintWindow;
+ pScreen->PaintWindowBorder = vga256PaintWindow;
+ pScreen->CopyWindow = vga256CopyWindow;
+ pScreen->CreateGC = vga256CreateGC;
+
+ mfbRegisterCopyPlaneProc (pScreen, vga256CopyPlane);
+
+ return vga256FinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgasetsp.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgasetsp.c
new file mode 100644
index 000000000..6a8cd0bc1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgasetsp.c
@@ -0,0 +1,284 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgasetsp.c,v 1.2 1998/07/25 16:58:24 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: vgasetsp.c /main/3 1996/02/21 18:11:54 kaleb $ */
+
+#include "vgafb.h"
+#include <mergerop.h>
+
+/* cfbSetScanline -- copies the bits from psrc to the drawable starting at
+ * (xStart, y) and continuing to (xEnd, y). xOrigin tells us where psrc
+ * starts on the scanline. (I.e., if this scanline passes through multiple
+ * boxes, we may not want to start grabbing bits at psrc but at some offset
+ * further on.)
+ */
+vga256SetScanline(y, xOrigin, xStart, xEnd, psrc, alu, pdstBase, widthDst, planemask)
+ int y;
+ int xOrigin; /* where this scanline starts */
+ int xStart; /* first bit to use from scanline */
+ int xEnd; /* last bit to use from scanline + 1 */
+ register unsigned int *psrc;
+ register int alu; /* raster op */
+ int *pdstBase; /* start of the drawable */
+ int widthDst; /* width of drawable in words */
+ unsigned long planemask;
+{
+ int w; /* width of scanline in bits */
+ register int *pdst; /* where to put the bits */
+ register int tmpSrc; /* scratch buffer to collect bits in */
+ int dstBit; /* offset in bits from beginning of
+ * word */
+ register int nstart; /* number of bits from first partial */
+ register int nend; /* " " last partial word */
+ int offSrc;
+ int startmask, endmask, nlMiddle, nl;
+ DeclareMergeRop()
+
+ InitializeMergeRop(alu,planemask);
+ pdst = pdstBase + (y * widthDst) + (xStart >> PWSH);
+ SETRW(pdst);
+ psrc += (xStart - xOrigin) >> PWSH;
+ offSrc = (xStart - xOrigin) & PIM;
+ w = xEnd - xStart;
+ dstBit = xStart & PIM;
+
+ if (dstBit + w <= PPW)
+ {
+ maskpartialbits(dstBit, w, startmask);
+ endmask = 0;
+ nlMiddle = 0;
+ }
+ else
+ {
+ maskbits(xStart, w, startmask, endmask, nlMiddle);
+ }
+ if (startmask)
+ nstart = PPW - dstBit;
+ else
+ nstart = 0;
+ if (endmask)
+ nend = xEnd & PIM;
+ else
+ nend = 0;
+ if (startmask)
+ {
+ getbits(psrc, offSrc, nstart, tmpSrc);
+ putbitsmropshort(tmpSrc, dstBit, nstart, pdst);
+ pdst++; CHECKRWO(pdst);
+ offSrc += nstart;
+ if (offSrc > PLST)
+ {
+ psrc++;
+ offSrc -= PPW;
+ }
+ }
+ nl = nlMiddle;
+ while (nl--)
+ {
+ getbits(psrc, offSrc, PPW, tmpSrc);
+ *pdst = DoMergeRop(tmpSrc, *pdst);
+ pdst++; CHECKRWO(pdst);
+ psrc++;
+ }
+ if (endmask)
+ {
+ getbits(psrc, offSrc, nend, tmpSrc);
+ putbitsmropshort(tmpSrc, 0, nend, pdst);
+ }
+}
+
+
+
+/* SetSpans -- for each span copy pwidth[i] bits from psrc to pDrawable at
+ * ppt[i] using the raster op from the GC. If fSorted is TRUE, the scanlines
+ * are in increasing Y order.
+ * Source bit lines are server scanline padded so that they always begin
+ * on a word boundary.
+ */
+void
+vga256SetSpans(pDrawable, pGC, pcharsrc, ppt, pwidth, nspans, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ char *pcharsrc;
+ register DDXPointPtr ppt;
+ int *pwidth;
+ int nspans;
+ int fSorted;
+{
+ unsigned int *psrc = (unsigned int *)pcharsrc;
+ unsigned long *pdstBase; /* start of dst bitmap */
+ int widthDst; /* width of bitmap in words */
+ register BoxPtr pbox, pboxLast, pboxTest;
+ register DDXPointPtr pptLast;
+ int alu;
+ RegionPtr prgnDst;
+ int xStart, xEnd;
+ int yMax;
+
+ /*
+ * If nothing is going to actually touch the framebuffer, then
+ * do the work with the cfb routines as they should be slightly faster.
+ */
+
+ if( pDrawable->type != DRAWABLE_WINDOW )
+ {
+ cfbSetSpans(pDrawable, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
+ return;
+ }
+
+ alu = pGC->alu;
+ prgnDst = cfbGetCompositeClip(pGC);
+ pptLast = ppt + nspans;
+
+ cfbGetLongWidthAndPointer (pDrawable, widthDst, pdstBase)
+
+ BANK_FLAG(pdstBase)
+
+ yMax = (int) pDrawable->y + (int) pDrawable->height;
+
+ pbox = REGION_RECTS(prgnDst);
+ pboxLast = pbox + REGION_NUM_RECTS(prgnDst);
+
+ if(fSorted)
+ {
+ /* scan lines sorted in ascending order. Because they are sorted, we
+ * don't have to check each scanline against each clip box. We can be
+ * sure that this scanline only has to be clipped to boxes at or after the
+ * beginning of this y-band
+ */
+ pboxTest = pbox;
+ while(ppt < pptLast)
+ {
+ pbox = pboxTest;
+ if(ppt->y >= yMax)
+ break;
+ while(pbox < pboxLast)
+ {
+ if(pbox->y1 > ppt->y)
+ {
+ /* scanline is before clip box */
+ break;
+ }
+ else if(pbox->y2 <= ppt->y)
+ {
+ /* clip box is before scanline */
+ pboxTest = ++pbox;
+ continue;
+ }
+ else if(pbox->x1 > ppt->x + *pwidth)
+ {
+ /* clip box is to right of scanline */
+ break;
+ }
+ else if(pbox->x2 <= ppt->x)
+ {
+ /* scanline is to right of clip box */
+ pbox++;
+ continue;
+ }
+
+ /* at least some of the scanline is in the current clip box */
+ xStart = max(pbox->x1, ppt->x);
+ xEnd = min(ppt->x + *pwidth, pbox->x2);
+ cfbSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu,
+ (int *)pdstBase, widthDst, pGC->planemask);
+ if(ppt->x + *pwidth <= pbox->x2)
+ {
+ /* End of the line, as it were */
+ break;
+ }
+ else
+ pbox++;
+ }
+ /* We've tried this line against every box; it must be outside them
+ * all. move on to the next point */
+ ppt++;
+ psrc += PixmapWidthInPadUnits(*pwidth, pDrawable->depth);
+ pwidth++;
+ }
+ }
+ else
+ {
+ /* scan lines not sorted. We must clip each line against all the boxes */
+ while(ppt < pptLast)
+ {
+ if(ppt->y >= 0 && ppt->y < yMax)
+ {
+
+ for(pbox = REGION_RECTS(prgnDst); pbox< pboxLast; pbox++)
+ {
+ if(pbox->y1 > ppt->y)
+ {
+ /* rest of clip region is above this scanline,
+ * skip it */
+ break;
+ }
+ if(pbox->y2 <= ppt->y)
+ {
+ /* clip box is below scanline */
+ pbox++;
+ break;
+ }
+ if(pbox->x1 <= ppt->x + *pwidth &&
+ pbox->x2 > ppt->x)
+ {
+ xStart = max(pbox->x1, ppt->x);
+ xEnd = min(pbox->x2, ppt->x + *pwidth);
+ cfbSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu,
+ (int *)pdstBase, widthDst, pGC->planemask);
+ }
+
+ }
+ }
+ psrc += PixmapWidthInPadUnits(*pwidth, pDrawable->depth);
+ ppt++;
+ pwidth++;
+ }
+ }
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgasolid.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgasolid.c
new file mode 100644
index 000000000..b3a311b30
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgasolid.c
@@ -0,0 +1,189 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgasolid.c,v 1.2 1998/07/25 16:58:24 dawes Exp $ */
+/*
+ *
+Copyright (c) 1990 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+/* $XConsortium: vgasolid.c /main/3 1996/02/21 18:11:58 kaleb $ */
+
+
+#include "vgafb.h"
+#include "cfbrrop.h"
+#include "mispans.h"
+
+void
+#if (RROP == GXcopy)
+#ifdef SPEEDUP
+speedupvga256FillRectSolidCopy (pDrawable, pGC, nBox, pBox)
+#else
+vga256FillRectSolidCopy (pDrawable, pGC, nBox, pBox)
+#endif
+#else
+RROP_NAME(vga256FillRectSolid) (pDrawable, pGC, nBox, pBox)
+#endif
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nBox;
+ BoxPtr pBox;
+{
+ RROP_DECLARE
+#ifdef SPEEDUP
+ unsigned long *pdstBase, *pdstRect;
+ int h;
+ int w;
+ int widthDst;
+
+ cfbGetLongWidthAndPointer (pDrawable, widthDst, pdstBase)
+#endif /* SPEEDUP */
+
+ RROP_FETCH_GC(pGC)
+#ifdef SPEEDUP
+#if (RROP == GXcopy)
+ for (; nBox; nBox--, pBox++)
+ {
+ pdstRect = pdstBase + pBox->y1 * widthDst;
+ h = pBox->y2 - pBox->y1;
+ w = pBox->x2 - pBox->x1;
+
+ SpeedUpBox((unsigned char*)pdstRect + pBox->x1,
+ rrop_xor, h, w, widthDst << PWSH);
+ }
+#endif /* GXcopy */
+#else /* SPEEDUP */
+#if RROP == GXcopy
+ vga256FillBoxSolid (pDrawable, nBox, pBox, rrop_xor, 0, GXcopy);
+#endif /* GXcopy */
+#endif /* SPEEDUP */
+#if RROP == GXxor
+ vga256FillBoxSolid (pDrawable, nBox, pBox, rrop_xor, 0, GXxor);
+#endif /* GXxor */
+#if RROP == GXor
+ vga256FillBoxSolid (pDrawable, nBox, pBox, rrop_or, 0, GXor);
+#endif /* GXor */
+#if RROP == GXand
+ vga256FillBoxSolid (pDrawable, nBox, pBox, rrop_and, 0, GXand);
+#endif /* GXand */
+#if RROP == GXset
+ vga256FillBoxSolid (pDrawable, nBox, pBox, rrop_and, rrop_xor, GXset);
+#endif /* GXset */
+}
+
+#ifndef SPEEDUP
+
+void
+RROP_NAME(vga256SolidSpans) (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ unsigned long *pdstBase;
+ int widthDst;
+
+ RROP_DECLARE
+
+ register unsigned long *pdst EDI;
+ int nlmiddle, nl;
+ register unsigned long startmask, endmask;
+ int w;
+ int x;
+
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ DDXPointPtr ppt; /* pointer to list of start points */
+ int *pwidthFree;/* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ int *pwidth;
+ cfbPrivGCPtr devPriv;
+
+ devPriv = cfbGetGCPrivate(pGC);
+ RROP_FETCH_GCPRIV(devPriv)
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ cfbGetLongWidthAndPointer (pDrawable, widthDst, pdstBase)
+
+ BANK_FLAG(pdstBase)
+
+ CLD;
+
+ while (n--)
+ {
+ x = ppt->x;
+ pdst = pdstBase + (ppt->y * widthDst);
+ ++ppt;
+ w = *pwidth++;
+ if (!w)
+ continue;
+ if (w <= PGSZB)
+ {
+ register char *addrb;
+
+ addrb = ((char *) pdst) + x;
+ SETRW(addrb);
+ while (w--)
+ {
+ RROP_SOLID (addrb);
+ addrb++; CHECKRWO(addrb);
+ }
+ }
+ else
+ {
+ pdst += x >> PWSH;
+ SETRW(pdst);
+ maskbits (x, w, startmask, endmask, nlmiddle);
+ if (startmask)
+ {
+ RROP_SOLID_MASK (pdst, startmask);
+ ++pdst; CHECKRWO(pdst);
+ }
+
+ RROP_SPAN_STD(pdst,nlmiddle,SO_1);
+ CHECKRWO(pdst);
+
+ if (endmask)
+ {
+ CHECKRWO(pdst);
+ RROP_SOLID_MASK (pdst, endmask);
+ }
+ }
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+#endif /* SPEEDUP */
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgateblt8.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgateblt8.c
new file mode 100644
index 000000000..cf180712f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgateblt8.c
@@ -0,0 +1,721 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgateblt8.c,v 1.2 1998/07/25 16:58:25 dawes Exp $ */
+/*
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+*/
+
+/* $XConsortium: vgateblt8.c /main/3 1996/02/21 18:12:01 kaleb $ */
+/*
+ * TEGblt - ImageText expanded glyph fonts only. For
+ * 8 bit displays, in Copy mode with no clipping.
+ */
+
+
+#include "vgafb.h"
+
+#ifdef SPEEDUP
+#define SIMPLER_CHECKRWO(x) {if(vgaWriteFlag) x = vgaReadWriteNext(x);}
+#endif
+
+
+/*
+ * this code supports up to 5 characters at a time. The performance
+ * differences between 4 and 5 is usually small (~7% on PMAX) and
+ * frequently negative (SPARC and Sun3), so this file is compiled
+ * only once for now. If you want to use the other options, you'll
+ * need to hack cfbgc.c as well.
+ */
+
+
+#ifndef NGLYPHS
+#define NGLYPHS 4
+#define DO_COMMON
+#endif
+
+
+#ifdef DO_COMMON
+#ifdef SPEEDUP
+#define CFBTEGBLT8 speedupvga256TEGlyphBlt8
+#else
+#define CFBTEGBLT8 vga256TEGlyphBlt8
+#endif
+#endif
+
+/*
+ * On little-endian machines (or where fonts are padded to 32-bit
+ * boundaries) we can use some magic to avoid the expense of getleftbits
+ */
+
+#if ((BITMAP_BIT_ORDER == LSBFirst && NGLYPHS >= 4) || GLYPHPADBYTES == 4)
+
+#if GLYPHPADBYTES == 1
+typedef unsigned char *glyphPointer;
+#define USE_LEFTBITS
+#endif
+
+#if GLYPHPADBYTES == 2
+typedef unsigned short *glyphPointer;
+#define USE_LEFTBITS
+#endif
+
+#if GLYPHPADBYTES == 4
+typedef unsigned int *glyphPointer;
+#endif
+
+#define GetBitsL c = BitLeft (*leftChar++, lshift)
+
+#define GetBits1S c = BitRight(*char1++, xoff1)
+#define GetBits1L GetBitsL | BitRight(*char1++, xoff1)
+#define GetBits1U c = *char1++
+#define GetBits2S GetBits1S | BitRight(*char2++, xoff2)
+#define GetBits2L GetBits1L | BitRight(*char2++, xoff2)
+#define GetBits2U GetBits1U | BitRight(*char2++, xoff2)
+#define GetBits3S GetBits2S | BitRight(*char3++, xoff3)
+#define GetBits3L GetBits2L | BitRight(*char3++, xoff3)
+#define GetBits3U GetBits2U | BitRight(*char3++, xoff3)
+#define GetBits4S GetBits3S | BitRight(*char4++, xoff4)
+#define GetBits4L GetBits3L | BitRight(*char4++, xoff4)
+#define GetBits4U GetBits3U | BitRight(*char4++, xoff4)
+#define GetBits5S GetBits4S | BitRight(*char5++, xoff5)
+#define GetBits5L GetBits4L | BitRight(*char5++, xoff5)
+#define GetBits5U GetBits4U | BitRight(*char5++, xoff5)
+
+#else
+
+typedef unsigned char *glyphPointer;
+
+#define USE_LEFTBITS
+
+#define GetBitsL WGetBitsL
+#define GetBits1S WGetBits1S
+#define GetBits1L WGetBits1L
+#define GetBits1U WGetBits1U
+
+#define GetBits2S GetBits1S Get1Bits (char2, tmpSrc) \
+ c |= BitRight(tmpSrc, xoff2);
+#define GetBits2L GetBits1L Get1Bits (char2, tmpSrc) \
+ c |= BitRight(tmpSrc, xoff2);
+#define GetBits2U GetBits1U Get1Bits (char2, tmpSrc) \
+ c |= BitRight(tmpSrc, xoff2);
+
+#define GetBits3S GetBits2S Get1Bits (char3, tmpSrc) \
+ c |= BitRight(tmpSrc, xoff3);
+#define GetBits3L GetBits2L Get1Bits (char3, tmpSrc) \
+ c |= BitRight(tmpSrc, xoff3);
+#define GetBits3U GetBits2U Get1Bits (char3, tmpSrc) \
+ c |= BitRight(tmpSrc, xoff3);
+
+#define GetBits4S GetBits3S Get1Bits (char4, tmpSrc) \
+ c |= BitRight(tmpSrc, xoff4);
+#define GetBits4L GetBits3L Get1Bits (char4, tmpSrc) \
+ c |= BitRight(tmpSrc, xoff4);
+#define GetBits4U GetBits3U Get1Bits (char4, tmpSrc) \
+ c |= BitRight(tmpSrc, xoff4);
+
+#define GetBits5S GetBits4S Get1Bits (char5, tmpSrc) \
+ c |= BitRight(tmpSrc, xoff5);
+#define GetBits5L GetBits4L Get1Bits (char5, tmpSrc) \
+ c |= BitRight(tmpSrc, xoff5);
+#define GetBits5U GetBits4U Get1Bits (char5, tmpSrc) \
+ c |= BitRight(tmpSrc, xoff5);
+
+#endif
+
+#ifdef USE_LEFTBITS
+extern unsigned long endtab[];
+
+#define IncChar(c) (c = (glyphPointer) (((char *) c) + glyphBytes))
+
+#define Get1Bits(ch,dst) glyphbits (ch, widthGlyph, glyphMask, dst); \
+ IncChar (ch);
+
+#define glyphbits(bits,width,mask,dst) getleftbits(bits,width,dst); \
+ dst &= mask;
+
+#define WGetBitsL Get1Bits(leftChar,c); \
+ c = BitLeft (c, lshift);
+#define WGetBits1S Get1Bits (char1, c) \
+ c = BitRight (c, xoff1);
+#define WGetBits1L WGetBitsL Get1Bits (char1, tmpSrc) \
+ c |= BitRight (tmpSrc, xoff1);
+#define WGetBits1U Get1Bits (char1, c)
+
+#else
+#define WGetBitsL GetBitsL
+#define WGetBits1S GetBits1S
+#define WGetBits1L GetBits1L
+#define WGetBits1U GetBits1U
+#endif
+
+#if NGLYPHS == 2
+# define GetBitsNS GetBits2S
+# define GetBitsNL GetBits2L
+# define GetBitsNU GetBits2U
+# define LastChar char2
+#ifndef CFBTEGBLT8
+# define CFBTEGBLT8 vga256TEGlyphBlt8x2
+#endif
+#endif
+#if NGLYPHS == 3
+# define GetBitsNS GetBits3S
+# define GetBitsNL GetBits3L
+# define GetBitsNU GetBits3U
+# define LastChar char3
+#ifndef CFBTEGBLT8
+# define CFBTEGBLT8 vga256TEGlyphBlt8x3
+#endif
+#endif
+#if NGLYPHS == 4
+# define GetBitsNS GetBits4S
+# define GetBitsNL GetBits4L
+# define GetBitsNU GetBits4U
+# define LastChar char4
+#ifndef CFBTEGBLT8
+# define CFBTEGBLT8 vga256TEGlyphBlt8x4
+#endif
+#endif
+#if NGLYPHS == 5
+# define GetBitsNS GetBits5S
+# define GetBitsNL GetBits5L
+# define GetBitsNU GetBits5U
+# define LastChar char5
+#ifndef CFBTEGBLT8
+# define CFBTEGBLT8 vga256TEGlyphBlt8x5
+#endif
+#endif
+
+/* another ugly giant macro */
+#ifdef SPEEDUP
+#define SwitchEm hTmp = SpeedUpRowsNext[hGlenn = 0]; \
+ switch (ew) \
+ { \
+ case 0: \
+ break; \
+ case 1: \
+do { \
+ while (hTmp--) { \
+ GetBits; \
+ StoreBits0 \
+ Loop \
+ } \
+ hTmp = SpeedUpRowsNext[++hGlenn]; \
+ SIMPLER_CHECKRWO(dst) \
+} while (hTmp); \
+ break; \
+ case 2: \
+do { \
+ while (hTmp--) { \
+ GetBits; \
+ StoreBits0 FirstStep StoreBits(1) \
+ Loop \
+ } \
+ hTmp = SpeedUpRowsNext[++hGlenn]; \
+ SIMPLER_CHECKRWO(dst) \
+} while (hTmp); \
+ break; \
+ case 3: \
+do { \
+ while (hTmp--) { \
+ GetBits; \
+ StoreBits0 FirstStep StoreBits(1) Step StoreBits(2) \
+ Loop \
+ } \
+ hTmp = SpeedUpRowsNext[++hGlenn]; \
+ SIMPLER_CHECKRWO(dst) \
+} while (hTmp); \
+ break; \
+ case 4: \
+do { \
+ while (hTmp--) { \
+ GetBits; \
+ StoreBits0 FirstStep StoreBits(1) Step \
+ StoreBits(2) Step StoreBits(3) \
+ Loop \
+ } \
+ hTmp = SpeedUpRowsNext[++hGlenn]; \
+ SIMPLER_CHECKRWO(dst) \
+} while (hTmp); \
+ break; \
+ case 5: \
+do { \
+ while (hTmp--) { \
+ GetBits; \
+ StoreBits0 FirstStep StoreBits(1) Step \
+ StoreBits(2) Step StoreBits(3) Step \
+ StoreBits(4) \
+ Loop \
+ } \
+ hTmp = SpeedUpRowsNext[++hGlenn]; \
+ SIMPLER_CHECKRWO(dst) \
+} while (hTmp); \
+ break; \
+ case 6: \
+do { \
+ while (hTmp--) { \
+ GetBits; \
+ StoreBits0 FirstStep StoreBits(1) Step \
+ StoreBits(2) Step StoreBits(3) Step \
+ StoreBits(4) Step StoreBits(5) \
+ Loop \
+ } \
+ hTmp = SpeedUpRowsNext[++hGlenn]; \
+ SIMPLER_CHECKRWO(dst) \
+} while (hTmp); \
+ break; \
+ case 7: \
+do { \
+ while (hTmp--) { \
+ GetBits; \
+ StoreBits0 FirstStep StoreBits(1) Step \
+ StoreBits(2) Step StoreBits(3) Step \
+ StoreBits(4) Step StoreBits(5) Step \
+ StoreBits(6) \
+ Loop \
+ } \
+ hTmp = SpeedUpRowsNext[++hGlenn]; \
+ SIMPLER_CHECKRWO(dst) \
+} while (hTmp); \
+ break; \
+ case 8: \
+do { \
+ while (hTmp--) { \
+ GetBits; \
+ StoreBits0 FirstStep StoreBits(1) Step \
+ StoreBits(2) Step StoreBits(3) Step \
+ StoreBits(4) Step StoreBits(5) Step \
+ StoreBits(6) Step StoreBits(7) \
+ Loop \
+ } \
+ hTmp = SpeedUpRowsNext[++hGlenn]; \
+ SIMPLER_CHECKRWO(dst) \
+} while (hTmp); \
+ break; \
+ }
+
+#else /* SPEEDUP */
+#define SwitchEm switch (ew) \
+ { \
+ case 0: \
+ break; \
+ case 1: \
+ while (hTmp--) { \
+ GetBits; \
+ StoreBits0 \
+ Loop \
+ } \
+ break; \
+ case 2: \
+ while (hTmp--) { \
+ GetBits; \
+ StoreBits0 FirstStep StoreBits(1) \
+ Loop \
+ } \
+ break; \
+ case 3: \
+ while (hTmp--) { \
+ GetBits; \
+ StoreBits0 FirstStep StoreBits(1) Step StoreBits(2) \
+ Loop \
+ } \
+ break; \
+ case 4: \
+ while (hTmp--) { \
+ GetBits; \
+ StoreBits0 FirstStep StoreBits(1) Step \
+ StoreBits(2) Step StoreBits(3) \
+ Loop \
+ } \
+ break; \
+ case 5: \
+ while (hTmp--) { \
+ GetBits; \
+ StoreBits0 FirstStep StoreBits(1) Step \
+ StoreBits(2) Step StoreBits(3) Step \
+ StoreBits(4) \
+ Loop \
+ } \
+ break; \
+ case 6: \
+ while (hTmp--) { \
+ GetBits; \
+ StoreBits0 FirstStep StoreBits(1) Step \
+ StoreBits(2) Step StoreBits(3) Step \
+ StoreBits(4) Step StoreBits(5) \
+ Loop \
+ } \
+ break; \
+ case 7: \
+ while (hTmp--) { \
+ GetBits; \
+ StoreBits0 FirstStep StoreBits(1) Step \
+ StoreBits(2) Step StoreBits(3) Step \
+ StoreBits(4) Step StoreBits(5) Step \
+ StoreBits(6) \
+ Loop \
+ } \
+ break; \
+ case 8: \
+ while (hTmp--) { \
+ GetBits; \
+ StoreBits0 FirstStep StoreBits(1) Step \
+ StoreBits(2) Step StoreBits(3) Step \
+ StoreBits(4) Step StoreBits(5) Step \
+ StoreBits(6) Step StoreBits(7) \
+ Loop \
+ } \
+ break; \
+ }
+#endif /* SPEEDUP */
+
+#ifdef FAST_CONSTANT_OFFSET_MODE
+#define StorePixels(o,p) dst[o] = p
+#define Loop dst += widthDst;
+#else
+#ifdef SPEEDUP
+#define StorePixels(o,p) *dst = (p); dst++;
+#define Loop dst += widthLeft;
+#else
+#define StorePixels(o,p) *dst = (p); dst++; CHECKRWO(dst);
+/* *dst++ = (p); CHECKRWO(dst); */
+#define Loop dst += widthLeft; CHECKRWO(dst);
+#endif
+#endif
+
+#define Step NextBitGroup(c);
+
+#if (BITMAP_BIT_ORDER == MSBFirst)
+#define StoreBits(o) StorePixels(o,GetPixelGroup(c));
+#define FirstStep Step
+#else
+#if PGSZ == 64
+#define StoreBits(o) StorePixels(o,cfb8Pixels[(c) & PGSZBMSK]);
+#define FirstStep Step
+#else /* PGSZ == 32 */
+#define StoreBits(o) StorePixels(o,*((unsigned long *) (((char *) cfb8Pixels) + (c & 0x3c))));
+#define FirstStep c = BitLeft (c, 2);
+#endif /* PGSZ */
+#endif
+
+void
+CFBTEGBLT8 (pDrawable, pGC, xInit, yInit, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int xInit, yInit;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ pointer pglyphBase; /* start of array of glyphs */
+{
+ register unsigned long c;
+ register unsigned long *dst EDI;
+ register unsigned long leftMask, rightMask;
+ register int hTmp;
+ register int xoff1;
+ register int xoff2;
+#if NGLYPHS >= 3
+ register int xoff3;
+#endif
+#if NGLYPHS >= 4
+ register int xoff4;
+#endif
+#if NGLYPHS >= 5
+ register int xoff5;
+#endif
+ register glyphPointer char1;
+ register glyphPointer char2;
+#if NGLYPHS >= 3
+ register glyphPointer char3;
+#endif
+#if NGLYPHS >= 4
+ register glyphPointer char4;
+#endif
+#if NGLYPHS >= 5
+ register glyphPointer char5;
+#endif
+
+
+#ifdef SPEEDUP
+ int hGlenn;
+#endif
+
+
+ FontPtr pfont = pGC->font;
+ unsigned long *dstLine;
+ glyphPointer oldRightChar;
+ unsigned long *pdstBase;
+ glyphPointer leftChar;
+ int widthDst, widthLeft;
+ int widthGlyph;
+ int h;
+ int ew;
+ int x, y;
+ BoxRec bbox; /* for clipping */
+ int lshift;
+ int widthGlyphs;
+#ifdef USE_LEFTBITS
+ register unsigned long glyphMask;
+ register unsigned long tmpSrc;
+ register int glyphBytes;
+#endif
+
+ widthGlyph = FONTMAXBOUNDS(pfont,characterWidth);
+ h = FONTASCENT(pfont) + FONTDESCENT(pfont);
+
+#ifdef SPEEDUP
+ if ((h | widthGlyph) == 0) return;
+#endif
+
+#ifndef SPEEDUP
+ if (!h)
+ return;
+#endif
+
+ x = xInit + FONTMAXBOUNDS(pfont,leftSideBearing) + pDrawable->x;
+ y = yInit - FONTASCENT(pfont) + pDrawable->y;
+ bbox.x1 = x;
+ bbox.x2 = x + (widthGlyph * nglyph);
+ bbox.y1 = y;
+ bbox.y2 = y + h;
+
+ switch (RECT_IN_REGION(pGC->pScreen, cfbGetCompositeClip(pGC), &bbox))
+ {
+ case rgnPART:
+ cfbImageGlyphBlt8(pDrawable, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
+ case rgnOUT:
+ return;
+ }
+
+ if (!cfb8CheckPixels (pGC->fgPixel, pGC->bgPixel))
+ cfb8SetPixels (pGC->fgPixel, pGC->bgPixel);
+
+ leftChar = 0;
+
+ cfbGetLongWidthAndPointer(pDrawable, widthDst, pdstBase)
+
+ BANK_FLAG(pdstBase)
+
+#if NGLYPHS == 2
+ widthGlyphs = widthGlyph << 1;
+#else
+#if NGLYPHS == 4
+ widthGlyphs = widthGlyph << 2;
+#else
+ widthGlyphs = widthGlyph * NGLYPHS;
+#endif
+#endif
+
+#ifdef USE_LEFTBITS
+ glyphMask = endtab[widthGlyph];
+ glyphBytes = GLYPHWIDTHBYTESPADDED(*ppci);
+#endif
+
+ pdstBase += y * widthDst;
+
+
+#ifdef SPEEDUP
+SpeedUpComputeNext((unsigned)pdstBase, h);
+#endif
+
+
+#ifdef DO_COMMON
+ if (widthGlyphs <= 32)
+#endif
+ while (nglyph >= NGLYPHS)
+ {
+ nglyph -= NGLYPHS;
+ hTmp = h;
+ dstLine = pdstBase + (x >> PWSH);
+ xoff1 = x & PIM;
+ char1 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
+ char2 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
+ xoff2 = xoff1 + widthGlyph;
+#if NGLYPHS >= 3
+ char3 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
+ xoff3 = xoff2 + widthGlyph;
+#endif
+#if NGLYPHS >= 4
+ char4 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
+ xoff4 = xoff3 + widthGlyph;
+#endif
+#if NGLYPHS >= 5
+ char5 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
+ xoff5 = xoff4 + widthGlyph;
+#endif
+ oldRightChar = LastChar;
+ dst = dstLine;
+ SETRW(dst);
+ if (xoff1)
+ {
+ ew = ((widthGlyphs - (PGSZB - xoff1)) >> PWSH) + 1;
+#ifndef FAST_CONSTANT_OFFSET_MODE
+ widthLeft = widthDst - ew;
+#endif
+ if (!leftChar)
+ {
+ leftMask = cfbendtab[xoff1];
+ rightMask = cfbstarttab[xoff1];
+
+#define StoreBits0 StorePixels (0,dst[0] & leftMask | \
+ GetPixelGroup(c) & rightMask);
+#define GetBits GetBitsNS
+
+ SwitchEm
+
+#undef GetBits
+#undef StoreBits0
+
+ }
+ else
+ {
+ lshift = widthGlyph - xoff1;
+
+#define StoreBits0 StorePixels (0,GetPixelGroup(c));
+#define GetBits GetBitsNL
+
+ SwitchEm
+
+#undef GetBits
+#undef StoreBits0
+
+ }
+ }
+ else
+ {
+#if NGLYPHS == 4 && PGSZ == 32
+ ew = widthGlyph; /* widthGlyphs >> 2 */
+#else
+ ew = widthGlyphs >> PWSH;
+#endif
+#ifndef FAST_CONSTANT_OFFSET_MODE
+ widthLeft = widthDst - ew;
+#endif
+
+#define StoreBits0 StorePixels (0,GetPixelGroup(c));
+#define GetBits GetBitsNU
+
+ SwitchEm
+
+#undef GetBits
+#undef StoreBits0
+
+ }
+ x += widthGlyphs;
+ leftChar = oldRightChar;
+ }
+ while (nglyph--)
+ {
+ xoff1 = x & PIM;
+ char1 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
+ hTmp = h;
+ dstLine = pdstBase + (x >> PWSH);
+ oldRightChar = char1;
+ dst = dstLine;
+ SETRW(dst);
+ if (xoff1)
+ {
+ ew = ((widthGlyph - (PGSZB - xoff1)) >> PWSH) + 1;
+#ifndef FAST_CONSTANT_OFFSET_MODE
+ widthLeft = widthDst - ew;
+#endif
+ if (!leftChar)
+ {
+ leftMask = cfbendtab[xoff1];
+ rightMask = cfbstarttab[xoff1];
+
+#define StoreBits0 StorePixels (0,dst[0] & leftMask | GetPixelGroup(c) & rightMask);
+#define GetBits WGetBits1S
+
+ SwitchEm
+#undef GetBits
+#undef StoreBits0
+
+ }
+ else
+ {
+ lshift = widthGlyph - xoff1;
+
+#define StoreBits0 StorePixels (0,GetPixelGroup(c));
+#define GetBits WGetBits1L
+
+ SwitchEm
+#undef GetBits
+#undef StoreBits0
+
+ }
+ }
+ else
+ {
+ ew = widthGlyph >> PWSH;
+
+#ifndef FAST_CONSTANT_OFFSET_MODE
+ widthLeft = widthDst - ew;
+#endif
+
+#define StoreBits0 StorePixels (0,GetPixelGroup(c));
+#define GetBits WGetBits1U
+
+ SwitchEm
+
+#undef GetBits
+#undef StoreBits0
+
+ }
+ x += widthGlyph;
+ leftChar = oldRightChar;
+ }
+ /*
+ * draw the tail of the last character
+ */
+ xoff1 = x & PIM;
+ if (xoff1)
+ {
+ rightMask = cfbstarttab[xoff1];
+ leftMask = cfbendtab[xoff1];
+ lshift = widthGlyph - xoff1;
+ dst = pdstBase + (x >> PWSH);
+ SETRW(dst);
+
+#ifndef SPEEDUP
+ hTmp = h;
+#else
+ hTmp = SpeedUpRowsNext[hGlenn = 0];
+ do {
+#endif
+ while (hTmp--)
+ {
+ GetBitsL;
+ *dst = (*dst & rightMask) | (GetPixelGroup(c) & leftMask);
+ dst += widthDst;
+#ifndef SPEEDUP
+ CHECKRWO(dst);
+#endif
+ }
+#ifdef SPEEDUP
+ hTmp = SpeedUpRowsNext[++hGlenn];
+ SIMPLER_CHECKRWO(dst)
+ } while (hTmp);
+#endif
+
+
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgategblt.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgategblt.c
new file mode 100644
index 000000000..ad4d7f757
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgategblt.c
@@ -0,0 +1,198 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgategblt.c,v 1.2 1998/07/25 16:58:25 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: vgategblt.c /main/3 1996/02/21 18:12:05 kaleb $ */
+
+#include "vgafb.h"
+#include "compiler.h"
+
+#define MFB_CONSTS_ONLY
+#include "maskbits.h"
+
+
+/*
+ this works for fonts with glyphs <= 32 bits wide, on an
+ arbitrarily deep display. Use cfbTEGlyphBlt8 for 8 bit displays.
+
+ This should be called only with a terminal-emulator font;
+this means that the FIXED_METRICS flag is set, and that
+glyphbounds == charbounds.
+
+ in theory, this goes faster; even if it doesn't, it reduces the
+flicker caused by writing a string over itself with image text (since
+the background gets repainted per character instead of per string.)
+this seems to be important for some converted X10 applications.
+
+ Image text looks at the bits in the glyph and the fg and bg in the
+GC. it paints a rectangle, as defined in the protocol dcoument,
+and the paints the characters.
+
+*/
+
+void
+vga256TEGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ pointer pglyphBase; /* start of array of glyphs */
+{
+ FontPtr pfont = pGC->font;
+ int widthDst;
+ unsigned long *pdstBase; /* pointer to longword with top row
+ of current glyph */
+
+ int w; /* width of glyph and char */
+ int h; /* height of glyph and char */
+ register int xpos=x; /* current x%32 */
+ int ypos=y; /* current y%32 */
+ register unsigned char *pglyph;
+ int widthGlyph;
+
+ register unsigned long *pdst;/* pointer to current longword in dst */
+ int hTmp; /* counter for height */
+ BoxRec bbox; /* for clipping */
+
+ register int wtmp,xtemp,width;
+ unsigned long bgfill,fgfill,*ptemp,tmpDst1,tmpDst2,*pdtmp;
+ int tmpx;
+
+ xpos += pDrawable->x;
+ ypos += pDrawable->y;
+
+ cfbGetLongWidthAndPointer (pDrawable, widthDst, pdstBase)
+
+ BANK_FLAG(pdstBase)
+
+ wtmp = FONTMAXBOUNDS(pfont,characterWidth);
+ h = FONTASCENT(pfont) + FONTDESCENT(pfont);
+ widthGlyph = GLYPHWIDTHBYTESPADDED(*ppci);
+
+ xpos += FONTMAXBOUNDS(pfont,leftSideBearing);
+ ypos -= FONTASCENT(pfont);
+
+ bbox.x1 = xpos;
+ bbox.x2 = xpos + (wtmp * nglyph);
+ bbox.y1 = ypos;
+ bbox.y2 = ypos + h;
+
+ fgfill = PFILL(pGC->fgPixel);
+ bgfill = PFILL(pGC->bgPixel);
+
+ switch (RECT_IN_REGION(pGC->pScreen, cfbGetCompositeClip(pGC), &bbox))
+ {
+ case rgnOUT:
+ break;
+ case rgnPART:
+ /* this is the WRONG thing to do, but it works.
+ calling the non-terminal text is easy, but slow, given
+ what we know about the font.
+
+ the right thing to do is something like:
+ for each clip rectangle
+ compute at which row the glyph starts to be in it,
+ and at which row the glyph ceases to be in it
+ compute which is the first glyph inside the left
+ edge, and the last one inside the right edge
+ draw a fractional first glyph, using only
+ the rows we know are in
+ draw all the whole glyphs, using the appropriate rows
+ draw any pieces of the last glyph, using the right rows
+
+ this way, the code would take advantage of knowing that
+ all glyphs are the same height and don't overlap.
+
+ one day...
+ */
+ miImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ break;
+ case rgnIN:
+
+ pdtmp = pdstBase + (widthDst * ypos);
+ while(nglyph--)
+ {
+
+ pglyph = FONTGLYPHBITS(pglyphBase, *ppci++);
+ pdst = pdtmp;
+ hTmp = h;
+
+ while (hTmp--)
+ {
+ x = xpos;
+ width = wtmp;
+ xtemp = 0;
+
+ while (width > 0)
+ {
+ tmpx = x & PIM;
+ w = min(width, PPW - tmpx);
+ w = min(w, (PGSZ - xtemp));
+
+ ptemp = (unsigned long *)(pglyph + (xtemp >> MFB_PWSH));
+ getstipplepixels(ptemp,xtemp,w,0,&bgfill,&tmpDst1);
+ getstipplepixels(ptemp,xtemp,w,1,&fgfill,&tmpDst2);
+
+ {
+ unsigned long tmpDst = tmpDst1 | tmpDst2;
+ unsigned long *pdsttmp = pdst + (x >> PWSH);
+ SETRW(pdsttmp);
+ putbits(tmpDst,tmpx,w,pdsttmp,pGC->planemask);
+ }
+ x += w;
+ xtemp += w;
+ width -= w;
+ }
+ pglyph += widthGlyph;
+ pdst += widthDst;
+ }
+ xpos += wtmp;
+ }
+ break;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgatile32.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgatile32.c
new file mode 100644
index 000000000..1508ffdeb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgatile32.c
@@ -0,0 +1,358 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgatile32.c,v 1.2 1998/07/25 16:58:26 dawes Exp $ */
+/*
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+*/
+
+/* $XConsortium: vgatile32.c /main/3 1996/02/21 18:12:09 kaleb $ */
+/*
+ * Fill 32 bit tiled rectangles. Used by both PolyFillRect and PaintWindow.
+ * no depth dependencies.
+ */
+
+#include "vgafb.h"
+#include "mergerop.h"
+#include "mi.h"
+#include "mispans.h"
+
+#ifdef sparc
+#define SHARED_IDCACHE
+#endif
+
+#define STORE(p) (*(p) = MROP_PREBUILT_SOLID(srcpix,*(p)))
+
+#if (MROP == Mcopy) && defined(FAST_CONSTANT_OFFSET_MODE) && defined(SHARED_IDCACHE)
+# define Expand(left,right) {\
+ int part = nlwMiddle & ((PGSZB*2)-1); \
+ nlwMiddle >>= PWSH + 1; \
+ while (h--) { \
+ srcpix = psrc[srcy]; \
+ MROP_PREBUILD(srcpix); \
+ ++srcy; \
+ if (srcy == tileHeight) \
+ srcy = 0; \
+ left \
+ p += part; \
+ switch (part) { \
+ case 7: \
+ STORE(p - 7); \
+ case 6: \
+ STORE(p - 6); \
+ case 5: \
+ STORE(p - 5); \
+ case 4: \
+ STORE(p - 4); \
+ case 3: \
+ STORE(p - 3); \
+ case 2: \
+ STORE(p - 2); \
+ case 1: \
+ STORE(p - 1); \
+ } \
+ nlw = nlwMiddle; \
+ while (nlw) { \
+ STORE (p + 0); \
+ STORE (p + 1); \
+ STORE (p + 2); \
+ STORE (p + 3); \
+ STORE (p + 4); \
+ STORE (p + 5); \
+ STORE (p + 6); \
+ STORE (p + 7); \
+ p += 8; \
+ nlw--; \
+ } \
+ right \
+ p += nlwExtra; \
+ } \
+}
+#else
+#define Expand(left,right) {\
+ while (h--) { \
+ srcpix = psrc[srcy]; \
+ MROP_PREBUILD(srcpix); \
+ ++srcy; \
+ if (srcy == tileHeight) \
+ srcy = 0; \
+ left \
+ nlw = nlwMiddle; \
+ while (nlw--) \
+ { \
+ STORE(p); \
+ p++; CHECKRWO(p); \
+ } \
+ right \
+ p += nlwExtra; CHECKRWO(p); \
+ } \
+}
+#endif
+
+void
+MROP_NAME(vga256FillRectTile32) (pDrawable, pGC, nBox, pBox)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nBox; /* number of boxes to fill */
+ BoxPtr pBox; /* pointer to list of boxes to fill */
+{
+ register unsigned long srcpix;
+ unsigned long *psrc; /* pointer to bits in tile, if needed */
+ int tileHeight; /* height of the tile */
+
+ int nlwDst; /* width in longwords of the dest pixmap */
+ int w; /* width of current box */
+ register int h; /* height of current box */
+ register unsigned long startmask;
+ register unsigned long endmask; /* masks for reggedy bits at either end of line */
+ int nlwMiddle; /* number of longwords between sides of boxes */
+ int nlwExtra; /* to get from right of box to left of next span */
+ register int nlw; /* loop version of nlwMiddle */
+ register unsigned long *p; /* pointer to bits we're writing */
+ int y; /* current scan line */
+ int srcy; /* current tile position */
+
+ unsigned long *pbits;/* pointer to start of pixmap */
+ PixmapPtr tile; /* rotated, expanded tile */
+ MROP_DECLARE_REG()
+ MROP_PREBUILT_DECLARE()
+
+ tile = pGC->pRotatedPixmap;
+ tileHeight = tile->drawable.height;
+ psrc = (unsigned long *)tile->devPrivate.ptr;
+
+ MROP_INITIALIZE(pGC->alu, pGC->planemask);
+
+ cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
+
+ BANK_FLAG(pbits)
+
+ while (nBox--)
+ {
+ w = pBox->x2 - pBox->x1;
+ h = pBox->y2 - pBox->y1;
+ y = pBox->y1;
+ p = pbits + (pBox->y1 * nlwDst) + (pBox->x1 >> PWSH);
+ SETRW(p);
+ srcy = y % tileHeight;
+
+ if ( ((pBox->x1 & PIM) + w) <= PPW)
+ {
+ maskpartialbits(pBox->x1, w, startmask);
+ nlwExtra = nlwDst;
+ while (h--)
+ {
+ srcpix = psrc[srcy];
+ MROP_PREBUILD(srcpix);
+ ++srcy;
+ if (srcy == tileHeight)
+ srcy = 0;
+ *p = MROP_PREBUILT_MASK (srcpix, *p, startmask);
+ p += nlwExtra; CHECKRWO(p);
+ }
+ }
+ else
+ {
+ maskbits(pBox->x1, w, startmask, endmask, nlwMiddle);
+ nlwExtra = nlwDst - nlwMiddle;
+
+ if (startmask)
+ {
+ nlwExtra -= 1;
+ if (endmask)
+ {
+ Expand(*p = MROP_PREBUILT_MASK(srcpix, *p, startmask); p++; CHECKRWO(p); ,
+ *p = MROP_PREBUILT_MASK(srcpix, *p, endmask);)
+ }
+ else
+ {
+ Expand(*p = MROP_PREBUILT_MASK(srcpix, *p, startmask); p++; CHECKRWO(p);,
+ ;)
+ }
+ }
+ else
+ {
+ if (endmask)
+ {
+ Expand(;,
+ *p = MROP_PREBUILT_MASK(srcpix, *p, endmask);)
+ }
+ else
+ {
+ Expand(;,
+ ;)
+ }
+ }
+ }
+ pBox++;
+ }
+}
+
+void
+MROP_NAME(vga256Tile32FS)(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ DDXPointPtr ppt; /* pointer to list of start points */
+ int *pwidth;/* pointer to list of n widths */
+ unsigned long *pbits; /* pointer to start of bitmap */
+ int nlwDst; /* width in longwords of bitmap */
+ register unsigned long *p; /* pointer to current longword in bitmap */
+ register int w; /* current span width */
+ register int nlw;
+ register int x;
+ register unsigned long startmask;
+ register unsigned long endmask;
+ register unsigned long srcpix;
+ int y;
+ int *pwidthFree;/* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ PixmapPtr tile;
+ unsigned long *psrc; /* pointer to bits in tile */
+ int tileHeight;/* height of the tile */
+ MROP_DECLARE_REG ()
+ MROP_PREBUILT_DECLARE()
+
+ /*
+ * If nothing is going to actually touch the framebuffer, then
+ * do the work with the cfb routines as they should be slightly faster.
+ */
+
+ if( pDrawable->type != DRAWABLE_WINDOW )
+ {
+ MROP_NAME(cfbTile32FS)(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
+ return;
+ }
+
+ n = nInit * miFindMaxBand( cfbGetCompositeClip(pGC) );
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans( cfbGetCompositeClip(pGC),
+ pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ tile = pGC->pRotatedPixmap;
+ tileHeight = tile->drawable.height;
+ psrc = (unsigned long *)tile->devPrivate.ptr;
+
+ MROP_INITIALIZE(pGC->alu, pGC->planemask);
+
+ cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
+
+ BANK_FLAG(pbits)
+
+#if MROP == Mcopy
+ if (!(tileHeight & (tileHeight-1)))
+ {
+ tileHeight--;
+ while (n--)
+ {
+ x = ppt->x;
+ y = ppt->y;
+ ++ppt;
+ w = *pwidth++;
+ p = pbits + (y * nlwDst) + (x >> PWSH);
+ SETRW(p);
+ srcpix = psrc[y & tileHeight];
+ MROP_PREBUILD(srcpix);
+
+ if ((x & PIM) + w < PPW)
+ {
+ maskpartialbits(x, w, startmask);
+ *p = MROP_PREBUILT_MASK (srcpix, *p, startmask);
+ }
+ else
+ {
+ maskbits(x, w, startmask, endmask, nlw);
+ if (startmask)
+ {
+ *p = MROP_PREBUILT_MASK(srcpix, *p, startmask);
+ p++; CHECKRWO(p);
+ }
+ while (nlw--)
+ {
+ STORE(p);
+ ++p; CHECKRWO(p);
+ }
+ if (endmask)
+ {
+ *p = MROP_PREBUILT_MASK(srcpix, *p, endmask);
+ }
+ }
+ }
+ }
+ else
+#endif
+ {
+ while (n--)
+ {
+ x = ppt->x;
+ y = ppt->y;
+ ++ppt;
+ w = *pwidth++;
+ p = pbits + (y * nlwDst) + (x >> PWSH);
+ SETRW(p);
+ srcpix = psrc[y % tileHeight];
+ MROP_PREBUILD(srcpix);
+
+ if ((x & PIM) + w < PPW)
+ {
+ maskpartialbits(x, w, startmask);
+ *p = MROP_PREBUILT_MASK (srcpix, *p, startmask);
+ }
+ else
+ {
+ maskbits(x, w, startmask, endmask, nlw);
+ if (startmask)
+ {
+ *p = MROP_PREBUILT_MASK(srcpix, *p, startmask);
+ p++; CHECKRWO(p);
+ }
+ while (nlw--)
+ {
+ STORE(p);
+ ++p; CHECKRWO(p);
+ }
+ if (endmask)
+ {
+ *p = MROP_PREBUILT_MASK(srcpix, *p, endmask);
+ }
+ }
+ }
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgatileodd.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgatileodd.c
new file mode 100644
index 000000000..29de74b67
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgatileodd.c
@@ -0,0 +1,1070 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgatileodd.c,v 1.2 1998/07/25 16:58:26 dawes Exp $ */
+/*
+
+Copyright (c) 1989 X Consortium
+Copyright 1992 by James Tsillas, Arlington, 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, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+*/
+/* $XConsortium: vgatileodd.c /main/3 1996/02/21 18:12:13 kaleb $ */
+
+/*
+ * Fill odd tiled rectangles and spans.
+ * no depth dependencies.
+ */
+
+#include "vgafb.h"
+#include "mergerop.h"
+
+#if PGSZ == 32
+#define LEFTSHIFT_AMT (5 - PWSH)
+#else /* PGSZ == 64 */
+#define LEFTSHIFT_AMT (6 - PWSH)
+#endif /* PGSZ */
+
+#define LastTileBits {\
+ tmp = bits; \
+ if (tileEndPart) \
+ bits = (*pSrc & tileEndMask) | BitRight (*pSrcLine, tileEndLeftShift); \
+ else \
+ bits = *pSrc; \
+}
+
+#define ResetTileBits {\
+ pSrc = pSrcLine; \
+ nlwSrc = widthSrc;\
+ if (tileEndPart) { \
+ if (PPW - xoff + tileEndPart <= PPW) {\
+ bits = *pSrc++; \
+ nlwSrc--; \
+ } else \
+ bits = BitLeft(tmp, tileEndLeftShift) | \
+ BitRight(bits, tileEndRightShift); \
+ xoff = (xoff + xoffStep) & PIM; \
+ leftShift = xoff << LEFTSHIFT_AMT; \
+ rightShift = PGSZ - leftShift; \
+ }\
+}
+
+#define NextTileBits {\
+ if (nlwSrc == 1) {\
+ LastTileBits\
+ } else { \
+ if (nlwSrc == 0) {\
+ ResetTileBits\
+ } \
+ tmp = bits; \
+ bits = *pSrc++; \
+ }\
+ nlwSrc--; \
+}
+
+void
+MROP_NAME(vga256FillBoxTileOdd) (pDrawable, nBox, pBox, tile, xrot, yrot, alu, planemask)
+ DrawablePtr pDrawable;
+ int nBox; /* number of boxes to fill */
+ register BoxPtr pBox; /* pointer to list of boxes to fill */
+ PixmapPtr tile; /* tile */
+ int xrot, yrot;
+ int alu;
+ unsigned long planemask;
+{
+ int tileWidth; /* width of tile in pixels */
+ int tileHeight; /* height of the tile */
+ int widthSrc;
+
+ int widthDst; /* width in longwords of the dest pixmap */
+ int w; /* width of current box */
+ int h; /* height of current box */
+ unsigned long startmask;
+ unsigned long endmask; /* masks for reggedy bits at either end of line */
+ int nlwMiddle; /* number of longwords between sides of boxes */
+ int nlwSrc; /* number of whole longwords in source */
+
+ register int nlw; /* loop version of nlwMiddle */
+ int srcy; /* current tile y position */
+ int srcx; /* current tile x position */
+ int xoffDst, xoffSrc;
+ int leftShift, rightShift;
+
+ MROP_DECLARE_REG()
+
+ unsigned long *pDstBase; /* pointer to start of dest */
+ unsigned long *pDstLine; /* poitner to start of dest box */
+ unsigned long *pSrcBase; /* pointer to start of source */
+ unsigned long *pSrcLine; /* pointer to start of source line */
+ register unsigned long *pDst;
+ register unsigned long *pSrc;
+ register unsigned long bits, tmp;
+ register int nlwPart;
+ int xoffStart, xoff;
+ int leftShiftStart, rightShiftStart, nlwSrcStart;
+ unsigned long tileEndMask;
+ int tileEndLeftShift, tileEndRightShift;
+ int xoffStep;
+ int tileEndPart;
+ int needFirst;
+ unsigned long narrow[2];
+ unsigned long narrowMask;
+ int narrowShift;
+ Bool narrowTile;
+
+ MROP_INITIALIZE (alu, planemask)
+
+ tileHeight = tile->drawable.height;
+ tileWidth = tile->drawable.width;
+ widthSrc = tile->devKind / PGSZB;
+ narrowTile = FALSE;
+ if (widthSrc == 1)
+ {
+ narrowShift = tileWidth;
+ narrowMask = cfbendpartial [tileWidth];
+ tileWidth *= 2;
+ widthSrc = 2;
+ narrowTile = TRUE;
+ }
+ pSrcBase = (unsigned long *)tile->devPrivate.ptr;
+
+ cfbGetLongWidthAndPointer (pDrawable, widthDst, pDstBase)
+
+ BANK_FLAG(pDstBase)
+
+ tileEndPart = tileWidth & PIM;
+ tileEndMask = cfbendpartial[tileEndPart];
+ tileEndLeftShift = (tileEndPart) << LEFTSHIFT_AMT;
+ tileEndRightShift = PGSZ - tileEndLeftShift;
+ xoffStep = PPW - tileEndPart;
+ /*
+ * current assumptions: tile > 32 bits wide.
+ */
+ while (nBox--)
+ {
+ w = pBox->x2 - pBox->x1;
+ h = pBox->y2 - pBox->y1;
+ modulus (pBox->x1 - xrot, tileWidth, srcx);
+ modulus (pBox->y1 - yrot, tileHeight, srcy);
+ xoffDst = pBox->x1 & PIM;
+ if (xoffDst + w < PPW)
+ {
+ maskpartialbits(pBox->x1, w, startmask);
+ endmask = 0;
+ nlwMiddle = 0;
+ }
+ else
+ {
+ maskbits (pBox->x1, w, startmask, endmask, nlwMiddle)
+ }
+ pDstLine = pDstBase + (pBox->y1 * widthDst) + (pBox->x1 >> PWSH);
+ pSrcLine = pSrcBase + (srcy * widthSrc);
+ xoffSrc = srcx & PIM;
+ if (xoffSrc >= xoffDst)
+ {
+ xoffStart = xoffSrc - xoffDst;
+ needFirst = 1;
+ }
+ else
+ {
+ xoffStart = PPW - (xoffDst - xoffSrc);
+ needFirst = 0;
+ }
+ leftShiftStart = (xoffStart) << LEFTSHIFT_AMT;
+ rightShiftStart = PGSZ - leftShiftStart;
+ nlwSrcStart = widthSrc - (srcx >> PWSH);
+ while (h--)
+ {
+ /* XXX only works when narrowShift >= PPW/2 */
+ if (narrowTile)
+ {
+ tmp = pSrcLine[0] & narrowMask;
+ narrow[0] = tmp | SCRRIGHT (tmp, narrowShift);
+ narrow[1] = SCRLEFT (tmp, PPW - narrowShift) |
+ SCRRIGHT(tmp, 2 * narrowShift - PPW);
+ pSrcLine = narrow;
+ }
+ xoff = xoffStart;
+ leftShift = leftShiftStart;
+ rightShift = rightShiftStart;
+ nlwSrc = nlwSrcStart;
+ pSrc = pSrcLine + (srcx >> PWSH);
+ pDst = pDstLine;
+ SETRW(pDst);
+ bits = 0;
+ if (needFirst)
+ {
+ NextTileBits
+ }
+ if (startmask)
+ {
+ NextTileBits
+ tmp = BitLeft(tmp, leftShift);
+ if (rightShift != PGSZ)
+ tmp |= BitRight(bits,rightShift);
+ *pDst = MROP_MASK (tmp, *pDst, startmask);
+ ++pDst; CHECKRWO(pDst);
+ }
+ nlw = nlwMiddle;
+ while (nlw)
+ {
+#if MROP == Mcopy
+ if (nlwSrc > 1)
+ {
+ nlwPart = nlw;
+ if (nlwPart >= nlwSrc)
+ nlwPart = nlwSrc - 1;
+ nlw -= nlwPart;
+ nlwSrc -= nlwPart;
+ if (rightShift != PGSZ)
+ {
+ while (nlwPart--)
+ {
+ tmp = bits;
+ bits = *pSrc++;
+ *pDst = MROP_SOLID(BitLeft(tmp, leftShift) |
+ BitRight (bits, rightShift),
+ *pDst);
+ ++pDst; CHECKRWO(pDst);
+ }
+ }
+ else
+ {
+ if (nlwPart)
+ {
+ *pDst = MROP_SOLID (bits, *pDst);
+ ++pDst; CHECKRWO(pDst);
+ nlwPart--;
+ while (nlwPart--)
+ {
+ *pDst = MROP_SOLID(*pSrc, *pDst);
+ ++pDst; ++pSrc; CHECKRWO(pDst);
+ }
+ bits = *pSrc++;
+ }
+ }
+ }
+ else
+#endif
+ {
+ NextTileBits
+ if (rightShift != PGSZ)
+ {
+ *pDst = MROP_SOLID(BitLeft(tmp, leftShift) |
+ BitRight(bits, rightShift),
+ *pDst);
+ ++pDst; CHECKRWO(pDst);
+ }
+ else
+ {
+ *pDst = MROP_SOLID (tmp, *pDst);
+ ++pDst; CHECKRWO(pDst);
+ }
+ nlw--;
+ }
+ }
+ if (endmask)
+ {
+ NextTileBits
+ if (rightShift == PGSZ)
+ bits = 0;
+ *pDst = MROP_MASK (BitLeft(tmp, leftShift) |
+ BitRight(bits,rightShift),
+ *pDst, endmask);
+ }
+ pDstLine += widthDst;
+ pSrcLine += widthSrc;
+ if (++srcy == tileHeight)
+ {
+ srcy = 0;
+ pSrcLine = pSrcBase;
+ }
+ }
+ pBox++;
+ }
+}
+
+void
+MROP_NAME(vga256FillSpanTileOdd) (pDrawable, n, ppt, pwidth, tile, xrot, yrot, alu, planemask)
+ DrawablePtr pDrawable;
+ int n;
+ DDXPointPtr ppt;
+ int *pwidth;
+ PixmapPtr tile;
+ int xrot, yrot;
+ int alu;
+ unsigned long planemask;
+{
+ int tileWidth; /* width of tile in pixels */
+ int tileHeight; /* height of the tile */
+ int widthSrc;
+
+ int widthDst; /* width in longwords of the dest pixmap */
+ int w; /* width of current span */
+ unsigned long startmask;
+ unsigned long endmask; /* masks for reggedy bits at either end of line */
+ int nlwSrc; /* number of whole longwords in source */
+
+ register int nlw; /* loop version of nlwMiddle */
+ int srcy; /* current tile y position */
+ int srcx; /* current tile x position */
+ int xoffDst, xoffSrc;
+ int leftShift, rightShift;
+
+ MROP_DECLARE_REG()
+
+ unsigned long *pDstBase; /* pointer to start of dest */
+ unsigned long *pDstLine; /* poitner to start of dest box */
+ unsigned long *pSrcBase; /* pointer to start of source */
+ unsigned long *pSrcLine; /* pointer to start of source line */
+ register unsigned long *pDst;
+ register unsigned long *pSrc;
+ register unsigned long bits, tmp;
+ register int nlwPart;
+ int xoffStart, xoff;
+ int leftShiftStart, rightShiftStart, nlwSrcStart;
+ unsigned long tileEndMask;
+ int tileEndLeftShift, tileEndRightShift;
+ int xoffStep;
+ int tileEndPart;
+ int needFirst;
+ unsigned long narrow[2];
+ unsigned long narrowMask;
+ int narrowShift;
+ Bool narrowTile;
+
+ MROP_INITIALIZE (alu, planemask)
+
+ tileHeight = tile->drawable.height;
+ tileWidth = tile->drawable.width;
+ widthSrc = tile->devKind / PGSZB;
+ narrowTile = FALSE;
+ if (widthSrc == 1)
+ {
+ narrowShift = tileWidth;
+ narrowMask = cfbendpartial [tileWidth];
+ tileWidth *= 2;
+ widthSrc = 2;
+ narrowTile = TRUE;
+ }
+ pSrcBase = (unsigned long *)tile->devPrivate.ptr;
+
+ cfbGetLongWidthAndPointer (pDrawable, widthDst, pDstBase)
+
+ BANK_FLAG(pDstBase)
+
+ tileEndPart = tileWidth & PIM;
+ tileEndMask = cfbendpartial[tileEndPart];
+ tileEndLeftShift = (tileEndPart) << LEFTSHIFT_AMT;
+ tileEndRightShift = PGSZ - tileEndLeftShift;
+ xoffStep = PPW - tileEndPart;
+ while (n--)
+ {
+ w = *pwidth++;
+ modulus (ppt->x - xrot, tileWidth, srcx);
+ modulus (ppt->y - yrot, tileHeight, srcy);
+ xoffDst = ppt->x & PIM;
+ if (xoffDst + w < PPW)
+ {
+ maskpartialbits(ppt->x, w, startmask);
+ endmask = 0;
+ nlw = 0;
+ }
+ else
+ {
+ maskbits (ppt->x, w, startmask, endmask, nlw)
+ }
+ pDstLine = pDstBase + (ppt->y * widthDst) + (ppt->x >> PWSH);
+ pSrcLine = pSrcBase + (srcy * widthSrc);
+ xoffSrc = srcx & PIM;
+ if (xoffSrc >= xoffDst)
+ {
+ xoffStart = xoffSrc - xoffDst;
+ needFirst = 1;
+ }
+ else
+ {
+ xoffStart = PPW - (xoffDst - xoffSrc);
+ needFirst = 0;
+ }
+ leftShiftStart = (xoffStart) << LEFTSHIFT_AMT;
+ rightShiftStart = PGSZ - leftShiftStart;
+ nlwSrcStart = widthSrc - (srcx >> PWSH);
+ /* XXX only works when narrowShift >= PPW/2 */
+ if (narrowTile)
+ {
+ tmp = pSrcLine[0] & narrowMask;
+ narrow[0] = tmp | SCRRIGHT (tmp, narrowShift);
+ narrow[1] = SCRLEFT (tmp, PPW - narrowShift) |
+ SCRRIGHT(tmp, 2 * narrowShift - PPW);
+ pSrcLine = narrow;
+ }
+ xoff = xoffStart;
+ leftShift = leftShiftStart;
+ rightShift = rightShiftStart;
+ nlwSrc = nlwSrcStart;
+ pSrc = pSrcLine + (srcx >> PWSH);
+ pDst = pDstLine;
+ SETRW(pDst);
+ bits = 0;
+ if (needFirst)
+ {
+ NextTileBits
+ }
+ if (startmask)
+ {
+ NextTileBits
+ tmp = BitLeft(tmp, leftShift);
+ if (rightShift != PGSZ)
+ tmp |= BitRight(bits,rightShift);
+ *pDst = MROP_MASK (tmp, *pDst, startmask);
+ ++pDst; CHECKRWO(pDst);
+ }
+ while (nlw)
+ {
+#if MROP == Mcopy
+ if (nlwSrc > 1)
+ {
+ nlwPart = nlw;
+ if (nlwPart >= nlwSrc)
+ nlwPart = nlwSrc - 1;
+ nlw -= nlwPart;
+ nlwSrc -= nlwPart;
+ if (rightShift != PGSZ)
+ {
+ while (nlwPart--)
+ {
+ tmp = bits;
+ bits = *pSrc++;
+ *pDst = MROP_SOLID(BitLeft(tmp, leftShift) |
+ BitRight (bits, rightShift),
+ *pDst);
+ ++pDst; CHECKRWO(pDst);
+ }
+ }
+ else
+ {
+ if (nlwPart)
+ {
+ *pDst = MROP_SOLID (bits, *pDst);
+ ++pDst; CHECKRWO(pDst);
+ nlwPart--;
+ while (nlwPart--)
+ {
+ *pDst = MROP_SOLID(*pSrc, *pDst);
+ ++pDst; ++pSrc; CHECKRWO(pDst);
+ }
+ bits = *pSrc++;
+ }
+ }
+ }
+ else
+#endif
+ {
+ NextTileBits
+ if (rightShift != PGSZ)
+ {
+ *pDst = MROP_SOLID(BitLeft(tmp, leftShift) |
+ BitRight(bits, rightShift),
+ *pDst);
+ ++pDst; CHECKRWO(pDst);
+ }
+ else
+ {
+ *pDst = MROP_SOLID (tmp, *pDst);
+ ++pDst; CHECKRWO(pDst);
+ }
+ nlw--;
+ }
+ }
+ if (endmask)
+ {
+ NextTileBits
+ if (rightShift == PGSZ)
+ bits = 0;
+ *pDst = MROP_MASK (BitLeft(tmp, leftShift) |
+ BitRight(bits,rightShift),
+ *pDst, endmask);
+ }
+ ppt++;
+ }
+}
+
+# include "fastblt.h"
+
+#define IncSrcPtr psrc++; if (!--srcRemaining) { srcRemaining = widthSrc; psrc = psrcStart; }
+
+void
+MROP_NAME(vga256FillBoxTile32s) (pDrawable, nBox, pBox, tile, xrot, yrot, alu, planemask)
+ DrawablePtr pDrawable;
+ int nBox; /* number of boxes to fill */
+ BoxPtr pBox; /* pointer to list of boxes to fill */
+ PixmapPtr tile; /* tile */
+ int xrot, yrot;
+ int alu;
+ unsigned long planemask;
+{
+ int tileWidth; /* width of tile */
+ int tileHeight; /* height of the tile */
+ int widthSrc; /* width in longwords of the source tile */
+
+ int widthDst; /* width in longwords of the dest pixmap */
+ int w; /* width of current box */
+ int h; /* height of current box */
+ int maxh;
+ unsigned long startmask;
+ unsigned long endmask; /* masks for reggedy bits at either end of line */
+ int nlMiddle; /* number of longwords between sides of boxes */
+
+ int srcy; /* current tile y position */
+ int srcx; /* current tile x position */
+ int srcRemaining; /* number of longwords remaining in source */
+ int xoffDst, xoffSrc;
+ int srcStart; /* number of longwords source offset at left of box */
+ int leftShift, rightShift;
+
+ MROP_DECLARE_REG()
+
+ unsigned long *pdstBase; /* pointer to start of dest */
+ unsigned long *pdstLine; /* poitner to start of dest box */
+ unsigned long *psrcBase; /* pointer to start of source */
+ unsigned long *psrcLine; /* pointer to fetch point of source */
+ unsigned long *psrcStart; /* pointer to start of source line */
+ register unsigned long *pdst EDI;
+ register unsigned long *psrc ESI;
+ register unsigned long bits, bits1;
+ int nlTemp;
+ int nlTemp2;
+ int fnl;
+ unsigned long *pdstT;
+ MROP_INITIALIZE (alu, planemask)
+
+ psrcBase = (unsigned long *)tile->devPrivate.ptr;
+ tileHeight = tile->drawable.height;
+ tileWidth = tile->drawable.width;
+ widthSrc = tileWidth >> PWSH;
+
+ cfbGetLongWidthAndPointer (pDrawable, widthDst, pdstBase)
+
+ BANK_FLAG(pdstBase)
+
+ CLD;
+
+ while (nBox--)
+ {
+ w = pBox->x2 - pBox->x1;
+ h = pBox->y2 - pBox->y1;
+
+ /* set up source */
+ modulus (pBox->x1 - xrot, tileWidth, srcx);
+ modulus (pBox->y1 - yrot, tileHeight, srcy);
+ xoffSrc = srcx & PIM;
+ srcStart = (srcx >> PWSH);
+ psrcStart = psrcBase + (srcy * widthSrc);
+ psrcLine = psrcStart + srcStart;
+
+ /* set up dest */
+ xoffDst = pBox->x1 & PIM;
+ pdstLine = pdstBase + (pBox->y1 * widthDst) + (pBox->x1 >> PWSH);
+ /* set up masks */
+ if (xoffDst + w < PPW)
+ {
+ maskpartialbits(pBox->x1, w, startmask);
+ endmask = 0;
+ nlMiddle = 0;
+ }
+ else
+ {
+ maskbits (pBox->x1, w, startmask, endmask, nlMiddle)
+ }
+
+ if (xoffSrc == xoffDst)
+ {
+ if (pdstLine < (unsigned long *)VGABASE) {
+ maxh = h;
+ h = 0;
+ goto fastpath1;
+ }
+ pdstT = pdstLine;
+ SETRW(pdstLine);
+ while (h) {
+ maxh = min(h,((long*)vgaWriteTop - (long*)pdstLine) / widthDst);
+ pdstT += (maxh * widthDst);
+ h -= maxh;
+ fastpath1:
+ while (maxh--) { /***/
+ psrc = psrcLine; pdst = pdstLine; /***/
+ srcRemaining = widthSrc - srcStart; /***/
+ if (startmask) { /***/
+ *pdst = MROP_MASK (*psrc, *pdst, startmask); /***/
+ pdst++; IncSrcPtr } /***/
+ nlTemp = nlMiddle;
+ fCopyAL1 (psrc, pdst, nlTemp, srcRemaining,
+ widthSrc, psrcStart);
+ if (endmask) *pdst = MROP_MASK (*psrc, *pdst, endmask); /***/
+ pdstLine += widthDst; psrcLine += widthSrc; /***/
+ psrcStart += widthSrc; /***/
+ if (++srcy == tileHeight) { /***/
+ psrcStart = psrcBase; psrcLine = psrcStart + srcStart; /***/
+ srcy = 0; } /***/
+ } /***/
+ if (h) {
+ h--;
+ psrc = psrcLine; srcRemaining = widthSrc - srcStart;
+ if (pdstLine >= (unsigned long *)vgaWriteTop) {
+ pdstLine = pdstT;
+ SETRW(pdstLine);
+ }
+ pdst = pdstLine;
+ if (startmask) {
+ *pdst = MROP_MASK (*psrc, *pdst, startmask);
+ pdst++; IncSrcPtr
+ if (pdst >= (unsigned long *)vgaWriteTop)
+ pdst = vgaReadWriteNext(pdst);
+ }
+ nlTemp2 = (long*)vgaWriteTop - (long*)pdst;
+ nlTemp = min(nlMiddle, nlTemp2);
+ nlTemp2 = nlMiddle - nlTemp;
+ fCopyAL2 (psrc, pdst, nlTemp, srcRemaining, widthSrc,
+ psrcStart);
+ if (nlTemp2) {
+ pdst = vgaReadWriteNext(pdst);
+ fCopyAL3 (psrc, pdst, nlTemp2, srcRemaining,
+ widthSrc, psrcStart);
+ }
+ if (endmask) {
+ if (pdst >= (unsigned long *)vgaWriteTop)
+ pdst = vgaReadWriteNext(pdst);
+ *pdst = MROP_MASK (*psrc, *pdst, endmask);
+ }
+ pdstT += widthDst; pdstLine += widthDst;
+ if (pdstLine >= (unsigned long *)vgaWriteTop) {
+ pdstLine = pdstT; SETRW(pdstLine);
+ }
+ psrcLine += widthSrc; psrcStart += widthSrc;
+ if (++srcy == tileHeight) {
+ psrcStart = psrcBase; psrcLine = psrcStart + srcStart;
+ srcy = 0; }
+ }
+ }
+ }
+ else
+ {
+ if (xoffSrc > xoffDst) {
+ leftShift = (xoffSrc - xoffDst) << LEFTSHIFT_AMT;
+ rightShift = PGSZ - leftShift;
+ }
+ else {
+ rightShift = (xoffDst - xoffSrc) << LEFTSHIFT_AMT;
+ leftShift = PGSZ - rightShift;
+ }
+ if (pdstLine < (unsigned long *)VGABASE) {
+ maxh = h;
+ h = 0;
+ goto fastpath2;
+ }
+ pdstT = pdstLine;
+ SETRW(pdstLine);
+ while (h) {
+ maxh = min(h, ((long*)vgaWriteTop - (long*)pdstLine) / widthDst);
+ h -= maxh;
+ pdstT += (maxh * widthDst);
+ fastpath2:
+ while (maxh--) {
+ psrc = psrcLine; pdst = pdstLine; bits = 0;
+ srcRemaining = widthSrc - srcStart;
+ if (xoffSrc > xoffDst) {
+ bits = *psrc; IncSrcPtr
+ }
+ if (startmask) {
+ bits1 = BitLeft(bits,leftShift); bits = *psrc; IncSrcPtr
+ bits1 |= BitRight(bits,rightShift);
+ *pdst = MROP_MASK(bits1, *pdst, startmask); pdst++;
+ }
+ nlTemp = nlMiddle;
+ while (nlTemp) {
+ fnl = nlTemp;
+ if (fnl > srcRemaining)
+ fnl = srcRemaining;
+ nlTemp -= fnl; srcRemaining -= fnl;
+ DuffL (fnl, label000,
+ fCopyUL(psrc, pdst, bits, leftShift, rightShift);)
+ if (!srcRemaining) {
+ srcRemaining = widthSrc;
+ psrc = psrcStart;
+ }
+ }
+ if (endmask) {
+ bits1 = BitLeft(bits, leftShift);
+ if (BitLeft(endmask, rightShift)) {
+ bits = *psrc;
+ bits1 |= BitRight(bits, rightShift);
+ }
+ *pdst = MROP_MASK (bits1, *pdst, endmask);
+ }
+ pdstLine += widthDst; psrcLine += widthSrc;
+ psrcStart += widthSrc;
+ if (++srcy == tileHeight) {
+ psrcStart = psrcBase; psrcLine = psrcStart + srcStart;
+ srcy = 0;
+ }
+ }
+ if (h) {
+ h--;
+ psrc = psrcLine; bits = 0;
+ srcRemaining = widthSrc - srcStart;
+ if (pdstLine >= (unsigned long *)vgaWriteTop) {
+ pdstLine = pdstT;
+ SETRW(pdstLine);
+ }
+ pdst = pdstLine;
+ if (xoffSrc > xoffDst) {
+ bits = *psrc; IncSrcPtr
+ }
+ if (startmask) {
+ bits1 = BitLeft(bits,leftShift); bits = *psrc; IncSrcPtr
+ bits1 |= BitRight(bits,rightShift);
+ *pdst = MROP_MASK(bits1, *pdst, startmask); pdst++;
+ if (pdst >= (unsigned long *)vgaWriteTop)
+ pdst = vgaReadWriteNext(pdst);
+ }
+ nlTemp2 = (long*)vgaWriteTop - (long*)pdst;
+ nlTemp = min(nlMiddle, nlTemp2);
+ nlTemp2 = nlMiddle - nlTemp;
+ while (nlTemp) {
+ fnl = nlTemp;
+ if (fnl > srcRemaining)
+ fnl = srcRemaining;
+ nlTemp -= fnl; srcRemaining -= fnl;
+ while (fnl--) {
+ bits1 = BitLeft(bits, leftShift); bits = *psrc++;
+ *pdst = MROP_SOLID (bits1 |
+ BitRight(bits, rightShift), *pdst);
+ pdst++;
+ }
+ if (!srcRemaining) {
+ srcRemaining = widthSrc;
+ psrc = psrcStart;
+ }
+ }
+ if (nlTemp2) {
+ pdst = vgaReadWriteNext(pdst);
+ while (nlTemp2) {
+ fnl = nlTemp2;
+ if (fnl > srcRemaining)
+ fnl = srcRemaining;
+ nlTemp2 -= fnl; srcRemaining -= fnl;
+ while (fnl--) {
+ bits1 = BitLeft(bits, leftShift); bits = *psrc++;
+ *pdst = MROP_SOLID (bits1 |
+ BitRight(bits, rightShift), *pdst);
+ pdst++;
+ }
+ if (!srcRemaining) {
+ srcRemaining = widthSrc;
+ psrc = psrcStart;
+ }
+ }
+ }
+ if (endmask) {
+ if (pdst >= (unsigned long *)vgaWriteTop)
+ pdst = vgaReadWriteNext(pdst);
+ bits1 = BitLeft(bits, leftShift);
+ if (BitLeft(endmask, rightShift)) {
+ bits = *psrc;
+ bits1 |= BitRight(bits, rightShift);
+ }
+ *pdst = MROP_MASK (bits1, *pdst, endmask);
+ }
+ pdstT += widthDst; pdstLine += widthDst;
+ if (pdstLine >= (unsigned long *)vgaWriteTop) {
+ pdstLine = pdstT; SETRW(pdstLine);
+ }
+ psrcLine += widthSrc; psrcStart += widthSrc;
+ if (++srcy == tileHeight) {
+ psrcStart = psrcBase; psrcLine = psrcStart + srcStart;
+ srcy = 0;
+ }
+ }
+ }
+ }
+ pBox++;
+ }
+}
+
+void
+MROP_NAME(vga256FillSpanTile32s) (pDrawable, n, ppt, pwidth, tile, xrot, yrot, alu, planemask)
+ DrawablePtr pDrawable;
+ int n;
+ DDXPointPtr ppt;
+ int *pwidth;
+ PixmapPtr tile;
+ int xrot, yrot;
+ int alu;
+ unsigned long planemask;
+{
+ int tileWidth; /* width of tile */
+ int tileHeight; /* height of the tile */
+ int widthSrc; /* width in longwords of the source tile */
+
+ int widthDst; /* width in longwords of the dest pixmap */
+ int w; /* width of current box */
+ unsigned long startmask;
+ unsigned long endmask; /* masks for reggedy bits at either end of line */
+ int nlMiddle; /* number of longwords between sides of boxes */
+
+ register int nl; /* loop version of nlMiddle */
+ int srcy; /* current tile y position */
+ int srcx; /* current tile x position */
+ int srcRemaining; /* number of longwords remaining in source */
+ int xoffDst, xoffSrc;
+ int srcStart; /* number of longwords source offset at left of box */
+ int leftShift, rightShift;
+
+ MROP_DECLARE_REG()
+
+ unsigned long *pdstBase; /* pointer to start of dest */
+ unsigned long *pdstLine; /* poitner to start of dest box */
+ unsigned long *psrcBase; /* pointer to start of source */
+ unsigned long *psrcLine; /* pointer to fetch point of source */
+ unsigned long *psrcStart; /* pointer to start of source line */
+ register unsigned long *pdst;
+ register unsigned long *psrc;
+ register unsigned long bits, bits1;
+ register int nlTemp;
+
+ MROP_INITIALIZE (alu, planemask)
+
+ psrcBase = (unsigned long *)tile->devPrivate.ptr;
+ tileHeight = tile->drawable.height;
+ tileWidth = tile->drawable.width;
+ widthSrc = tileWidth >> PWSH;
+
+ cfbGetLongWidthAndPointer (pDrawable, widthDst, pdstBase)
+
+ BANK_FLAG(pdstBase)
+
+ while (n--)
+ {
+ w = *pwidth++;
+
+ /* set up source */
+ modulus (ppt->x - xrot, tileWidth, srcx);
+ modulus (ppt->y - yrot, tileHeight, srcy);
+ xoffSrc = srcx & PIM;
+ srcStart = (srcx >> PWSH);
+ psrcStart = psrcBase + (srcy * widthSrc);
+ psrcLine = psrcStart + srcStart;
+
+ /* set up dest */
+ xoffDst = ppt->x & PIM;
+ pdstLine = pdstBase + (ppt->y * widthDst) + (ppt->x >> PWSH);
+ /* set up masks */
+ if (xoffDst + w < PPW)
+ {
+ maskpartialbits(ppt->x, w, startmask);
+ endmask = 0;
+ nlMiddle = 0;
+ }
+ else
+ {
+ maskbits (ppt->x, w, startmask, endmask, nlMiddle)
+ }
+
+ if (xoffSrc == xoffDst)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ SETRW(pdst);
+ srcRemaining = widthSrc - srcStart;
+ if (startmask)
+ {
+ *pdst = MROP_MASK (*psrc, *pdst, startmask);
+ pdst++; CHECKRWO(pdst);
+ IncSrcPtr
+ }
+ nlTemp = nlMiddle;
+ while (nlTemp)
+ {
+ nl = nlTemp;
+ if (nl > srcRemaining)
+ nl = srcRemaining;
+
+ nlTemp -= nl;
+ srcRemaining -= nl;
+
+#ifdef LARGE_INSTRUCTION_CACHE
+#ifdef FAST_CONSTANT_OFFSET_MODE
+
+ psrc += nl & (UNROLL-1);
+ pdst += nl & (UNROLL-1);
+
+#define BodyOdd(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]);
+#define BodyEven(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]);
+
+#define LoopReset \
+pdst += UNROLL; \
+psrc += UNROLL;
+
+#else
+
+#define BodyOdd(n) *pdst = MROP_SOLID (*psrc, *pdst); pdst++; psrc++; CHECKRWO(pdst);
+#define BodyEven(n) BodyOdd(n)
+
+#define LoopReset ;
+
+#endif
+ PackedLoop
+
+#undef BodyOdd
+#undef BodyEven
+#undef LoopReset
+
+#else
+ DuffL(nl, label1,
+ *pdst = MROP_SOLID (*psrc, *pdst);
+ pdst++; psrc++; CHECKRWO(pdst); )
+#endif
+ if (!srcRemaining)
+ {
+ srcRemaining = widthSrc;
+ psrc = psrcStart;
+ }
+ }
+ if (endmask)
+ {
+ *pdst = MROP_MASK (*psrc, *pdst, endmask);
+ }
+ }
+ else
+ {
+ if (xoffSrc > xoffDst)
+ {
+ leftShift = (xoffSrc - xoffDst) << LEFTSHIFT_AMT;
+ rightShift = PGSZ - leftShift;
+ }
+ else
+ {
+ rightShift = (xoffDst - xoffSrc) << LEFTSHIFT_AMT;
+ leftShift = PGSZ - rightShift;
+ }
+ psrc = psrcLine;
+ pdst = pdstLine;
+ SETRW(pdst);
+ bits = 0;
+ srcRemaining = widthSrc - srcStart;
+ if (xoffSrc > xoffDst)
+ {
+ bits = *psrc;
+ IncSrcPtr
+ }
+ if (startmask)
+ {
+ bits1 = BitLeft(bits,leftShift);
+ bits = *psrc;
+ IncSrcPtr
+ bits1 |= BitRight(bits,rightShift);
+ *pdst = MROP_MASK(bits1, *pdst, startmask);
+ pdst++; CHECKRWO(pdst);
+ }
+ nlTemp = nlMiddle;
+ while (nlTemp)
+ {
+ nl = nlTemp;
+ if (nl > srcRemaining)
+ nl = srcRemaining;
+
+ nlTemp -= nl;
+ srcRemaining -= nl;
+
+#ifdef LARGE_INSTRUCTION_CACHE
+ bits1 = bits;
+
+#ifdef FAST_CONSTANT_OFFSET_MODE
+
+ psrc += nl & (UNROLL-1);
+ pdst += nl & (UNROLL-1);
+
+#define BodyOdd(n) \
+bits = psrc[-n]; \
+pdst[-n] = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), pdst[-n]);
+
+#define BodyEven(n) \
+bits1 = psrc[-n]; \
+pdst[-n] = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), pdst[-n]);
+
+#define LoopReset \
+pdst += UNROLL; \
+psrc += UNROLL;
+
+#else
+
+#define BodyOdd(n) \
+bits = *psrc++; \
+*pdst = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), *pdst); \
+pdst++; CHECKRWO(pdst);
+
+#define BodyEven(n) \
+bits1 = *psrc++; \
+*pdst = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), *pdst); \
+pdst++; CHECKRWO(pdst);
+
+#define LoopReset ;
+
+#endif /* !FAST_CONSTANT_OFFSET_MODE */
+
+ PackedLoop
+
+#undef BodyOdd
+#undef BodyEven
+#undef LoopReset
+
+#else
+ DuffL (nl,label2,
+ bits1 = BitLeft(bits, leftShift);
+ bits = *psrc++;
+ *pdst = MROP_SOLID (bits1 | BitRight(bits, rightShift), *pdst);
+ pdst++; CHECKRWO(pdst);
+ )
+#endif
+ if (!srcRemaining)
+ {
+ srcRemaining = widthSrc;
+ psrc = psrcStart;
+ }
+ }
+
+ if (endmask)
+ {
+ bits1 = BitLeft(bits, leftShift);
+ if (BitLeft(endmask, rightShift))
+ {
+ bits = *psrc;
+ bits1 |= BitRight(bits, rightShift);
+ }
+ *pdst = MROP_MASK (bits1, *pdst, endmask);
+ }
+ }
+ ppt++;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgawindow.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgawindow.c
new file mode 100644
index 000000000..63578165a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgawindow.c
@@ -0,0 +1,100 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgawindow.c,v 1.2 1998/07/25 16:58:27 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: vgawindow.c /main/3 1996/02/21 18:12:18 kaleb $ */
+
+#include "vgafb.h"
+
+extern WindowPtr *WindowTable;
+
+void
+vga256CopyWindow(pWin, ptOldOrg, prgnSrc)
+ WindowPtr pWin;
+ DDXPointRec ptOldOrg;
+ RegionPtr prgnSrc;
+{
+ DDXPointPtr pptSrc;
+ register DDXPointPtr ppt;
+ RegionRec rgnDst;
+ register BoxPtr pbox;
+ register int dx, dy;
+ register int i, nbox;
+ WindowPtr pwinRoot;
+
+ pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];
+
+ REGION_INIT(pWin->drawable.pScreen, &rgnDst, NullBox, 0);
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
+ REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc
+);
+
+ pbox = REGION_RECTS(&rgnDst);
+ nbox = REGION_NUM_RECTS(&rgnDst);
+
+ if(!nbox || !(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec))))
+ {
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+ return;
+ }
+ ppt = pptSrc;
+
+ for (i = nbox; --i >= 0; ppt++, pbox++)
+ {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ (*vga256LowlevFuncs.doBitbltCopy)((DrawablePtr)pwinRoot,
+ (DrawablePtr)pwinRoot,
+ GXcopy, &rgnDst, pptSrc, ~0L, ~0L);
+ DEALLOCATE_LOCAL(pptSrc);
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgafb/vgazerarc.c b/xc/programs/Xserver/hw/xfree86/vgafb/vgazerarc.c
new file mode 100644
index 000000000..f7981a46e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgafb/vgazerarc.c
@@ -0,0 +1,201 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgafb/vgazerarc.c,v 1.2 1998/07/25 16:58:27 dawes Exp $ */
+/************************************************************
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+********************************************************/
+
+/* $XConsortium: vgazerarc.c /main/3 1996/02/21 18:12:21 kaleb $ */
+
+/* Derived from:
+ * "Algorithm for drawing ellipses or hyperbolae with a digital plotter"
+ * by M. L. V. Pitteway
+ * The Computer Journal, November 1967, Volume 10, Number 3, pp. 282-289
+ */
+
+#include "vgafb.h"
+#include "mizerarc.h"
+#include "cfbrrop.h"
+
+#define __RROP_SOLID(a) { register unsigned char *addrbt = (a); \
+ SETRW(addrbt); RROP_SOLID(addrbt); }
+#ifdef PIXEL_ADDR
+
+static void
+RROP_NAME(vga256ZeroArcSS8) (pDraw, pGC, arc)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ xArc *arc;
+{
+ miZeroArcRec info;
+ Bool do360;
+ register int x;
+ unsigned char *addrb;
+ register unsigned char *yorgb, *yorgob;
+ RROP_DECLARE
+ register int yoffset;
+ int nbwidth, dyoffset;
+ register int y, a, b, d, mask;
+ register int k1, k3, dx, dy;
+
+ cfbGetByteWidthAndPointer(pDraw,nbwidth, addrb)
+
+ BANK_FLAG(addrb)
+
+ RROP_FETCH_GC (pGC);
+ do360 = miZeroArcSetup(arc, &info, TRUE);
+ yorgb = addrb + ((info.yorg + pDraw->y) * nbwidth);
+ yorgob = addrb + ((info.yorgo + pDraw->y) * nbwidth);
+ info.xorg += pDraw->x;
+ info.xorgo += pDraw->x;
+ MIARCSETUP();
+ yoffset = y ? nbwidth : 0;
+ dyoffset = 0;
+ mask = info.initialMask;
+ if (!(arc->width & 1))
+ {
+ if (mask & 2)
+ __RROP_SOLID((yorgb + info.xorgo));
+ if (mask & 8)
+ __RROP_SOLID((yorgob + info.xorgo));
+ }
+ if (!info.end.x || !info.end.y)
+ {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ if (do360 && (arc->width == arc->height) && !(arc->width & 1))
+ {
+ register int xoffset = nbwidth;
+ unsigned char *yorghb = yorgb + (info.h * nbwidth) + info.xorg;
+ unsigned char *yorgohb = yorghb - info.h;
+
+ yorgb += info.xorg;
+ yorgob += info.xorg;
+ yorghb += info.h;
+ while (1)
+ {
+ __RROP_SOLID(yorgb + yoffset + x);
+ __RROP_SOLID(yorgb + yoffset - x);
+ __RROP_SOLID(yorgob - yoffset - x);
+ __RROP_SOLID(yorgob - yoffset + x);
+ if (a < 0)
+ break;
+ __RROP_SOLID(yorghb - xoffset - y);
+ __RROP_SOLID(yorgohb - xoffset + y);
+ __RROP_SOLID(yorgohb + xoffset + y);
+ __RROP_SOLID(yorghb + xoffset - y);
+ xoffset += nbwidth;
+ MIARCCIRCLESTEP(yoffset += nbwidth;);
+ }
+ yorgb -= info.xorg;
+ yorgob -= info.xorg;
+ x = info.w;
+ yoffset = info.h * nbwidth;
+ }
+ else if (do360)
+ {
+ while (y < info.h || x < info.w)
+ {
+ MIARCOCTANTSHIFT(dyoffset = nbwidth;);
+ __RROP_SOLID(yorgb + yoffset + info.xorg + x);
+ __RROP_SOLID(yorgb + yoffset + info.xorgo - x);
+ __RROP_SOLID(yorgob - yoffset + info.xorgo - x);
+ __RROP_SOLID(yorgob - yoffset + info.xorg + x);
+ MIARCSTEP(yoffset += dyoffset;, yoffset += nbwidth;);
+ }
+ }
+ else
+ {
+ while (y < info.h || x < info.w)
+ {
+ MIARCOCTANTSHIFT(dyoffset = nbwidth;);
+ if ((x == info.start.x) || (y == info.start.y))
+ {
+ mask = info.start.mask;
+ info.start = info.altstart;
+ }
+ if (mask & 1)
+ __RROP_SOLID(yorgb + yoffset + info.xorg + x);
+ if (mask & 2)
+ __RROP_SOLID(yorgb + yoffset + info.xorgo - x);
+ if (mask & 4)
+ __RROP_SOLID(yorgob - yoffset + info.xorgo - x);
+ if (mask & 8)
+ __RROP_SOLID(yorgob - yoffset + info.xorg + x);
+ if ((x == info.end.x) || (y == info.end.y))
+ {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ MIARCSTEP(yoffset += dyoffset;, yoffset += nbwidth;);
+ }
+ }
+ if ((x == info.start.x) || (y == info.start.y))
+ mask = info.start.mask;
+ if (mask & 1)
+ __RROP_SOLID(yorgb + yoffset + info.xorg + x);
+ if (mask & 4)
+ __RROP_SOLID(yorgob - yoffset + info.xorgo - x);
+ if (arc->height & 1)
+ {
+ if (mask & 2)
+ __RROP_SOLID(yorgb + yoffset + info.xorgo - x);
+ if (mask & 8)
+ __RROP_SOLID(yorgob - yoffset + info.xorg + x);
+ }
+}
+
+void
+RROP_NAME (vga256ZeroPolyArcSS8) (pDraw, pGC, narcs, parcs)
+ register DrawablePtr pDraw;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ register xArc *arc;
+ register int i;
+ BoxRec box;
+ RegionPtr cclip;
+
+ cclip = cfbGetCompositeClip(pGC);
+ for (arc = parcs, i = narcs; --i >= 0; arc++)
+ {
+ if (miCanZeroArc(arc))
+ {
+ box.x1 = arc->x + pDraw->x;
+ box.y1 = arc->y + pDraw->y;
+ box.x2 = box.x1 + (int)arc->width + 1;
+ box.y2 = box.y1 + (int)arc->height + 1;
+ if ((*pDraw->pScreen->RectIn)(cclip, &box) == rgnIN)
+ RROP_NAME (vga256ZeroArcSS8) (pDraw, pGC, arc);
+ else
+ miZeroPolyArc(pDraw, pGC, 1, arc);
+ }
+ else
+ miPolyArc(pDraw, pGC, 1, arc);
+ }
+}
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/vgahw/Imakefile b/xc/programs/Xserver/hw/xfree86/vgahw/Imakefile
new file mode 100644
index 000000000..20b618ff8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgahw/Imakefile
@@ -0,0 +1,50 @@
+XCOMM $XConsortium: Imakefile /main/10 1996/10/25 10:34:08 kaleb $
+
+
+
+
+
+
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/vgahw/Imakefile,v 1.9 1999/08/14 10:50:10 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#if DoLoadableServer
+MODSRC = vgaHWmodule.c
+MODOBJ = vgaHWmodule.o
+#endif
+
+SRCS = vgaHW.c /*vgaCmap.c*/ $(MODSRC)
+
+OBJS = vgaHW.o /*vgaCmap.o*/ $(MODOBJ)
+
+ INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/Xext \
+ -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) \
+ -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c
+
+ LINTLIBS = ../../../dix/llib-ldix.ln ../../../os/llib-los.ln \
+ ../../mfb/llib-lmfb.ln ../../mi/llib-lmi.ln
+
+#if DirtyStartup
+STARTUPDEFINES = -DDIRTY_STARTUP
+#endif
+
+ DEFINES = $(STARTUPDEFINES)
+
+ModuleObjectRule()
+
+LibraryModuleTarget(vgahw,$(OBJS))
+
+NormalLintTarget($(SRCS))
+
+InstallLibraryModule(vgahw,$(MODULEDIR),.)
+
+#ifndef OS2Architecture
+DependTarget()
+#endif
+
+InstallDriverSDKLibraryModule(vgahw,$(DRIVERSDKMODULEDIR),.)
+
+InstallDriverSDKNonExecFile(vgaHW.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/xc/programs/Xserver/hw/xfree86/vgahw/vgaCmap.c b/xc/programs/Xserver/hw/xfree86/vgahw/vgaCmap.c
new file mode 100644
index 000000000..20957e1f8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgahw/vgaCmap.c
@@ -0,0 +1,306 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgahw/vgaCmap.c,v 1.5 1998/11/22 10:37:38 dawes Exp $ */
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Roell not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Roell makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS ROELL 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.
+ *
+ */
+/* $XConsortium: vgaCmap.c /main/15 1996/10/28 05:13:44 kaleb $ */
+
+
+#include "X.h"
+#include "Xproto.h"
+#include "windowstr.h"
+#include "compiler.h"
+#include "mipointer.h"
+#include "micmap.h"
+
+#include "xf86.h"
+#include "vgaHW.h"
+#include "xf86_ansic.h"
+
+#ifdef XFreeXDGA
+#define _XF86DGA_SERVER_
+#include "extensions/xf86dgastr.h"
+#include "dgaproc.h"
+#endif
+
+
+#define NOMAPYET (ColormapPtr) 0
+
+int
+vgaListInstalledColormaps(pScreen, pmaps)
+ ScreenPtr pScreen;
+ Colormap *pmaps;
+{
+ /* By the time we are processing requests, we can guarantee that there
+ * is always a colormap installed */
+
+ *pmaps = miInstalledMaps[pScreen->myNum]->mid;
+ return(1);
+}
+
+int
+vgaGetInstalledColormaps(pScreen, pmaps)
+ ScreenPtr pScreen;
+ ColormapPtr *pmaps;
+{
+ /* By the time we are processing requests, we can guarantee that there
+ * is always a colormap installed */
+
+ *pmaps = miInstalledMaps[pScreen->myNum];
+ return(1);
+}
+
+int vgaCheckColorMap(ColormapPtr pmap)
+{
+ return (pmap != miInstalledMaps[pmap->pScreen->myNum]);
+}
+
+
+void
+vgaStoreColors(pmap, ndef, pdefs)
+ ColormapPtr pmap;
+ int ndef;
+ xColorItem *pdefs;
+{
+ int i;
+ unsigned char *cmap, *tmp = NULL;
+ xColorItem directDefs[256];
+ Bool new_overscan = FALSE;
+ Bool writeColormap;
+
+ /* This can get called before the ScrnInfoRec is installed so we
+ can't rely on getting it with XF86SCRNINFO() */
+ int scrnIndex = pmap->pScreen->myNum;
+ ScrnInfoPtr scrninfp = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(scrninfp);
+
+ unsigned char overscan = hwp->ModeReg.Attribute[OVERSCAN];
+ unsigned char tmp_overscan = 0;
+
+ if (vgaCheckColorMap(pmap))
+ return;
+
+ if ((pmap->pVisual->class | DynamicClass) == DirectColor)
+ {
+ ndef = miExpandDirectColors (pmap, ndef, pdefs, directDefs);
+ pdefs = directDefs;
+ }
+
+ writeColormap = scrninfp->vtSema;
+#ifdef XFreeXDGA
+ if (DGAAvailable(scrnIndex))
+ {
+ writeColormap = writeColormap ||
+ (DGAGetDirectMode(scrnIndex) &&
+ !(DGAGetFlags(scrnIndex) & XF86DGADirectColormap)) ||
+ (DGAGetFlags(scrnIndex) & XF86DGAHasColormap);
+ }
+#endif
+
+ if (writeColormap)
+ hwp->enablePalette(hwp);
+
+ for(i = 0; i < ndef; i++)
+ {
+ if (pdefs[i].pixel == overscan)
+ {
+ new_overscan = TRUE;
+ }
+ cmap = &(hwp->ModeReg.DAC[pdefs[i].pixel*3]);
+ if (scrninfp->rgbBits == 8) {
+ cmap[0] = pdefs[i].red >> 8;
+ cmap[1] = pdefs[i].green >> 8;
+ cmap[2] = pdefs[i].blue >> 8;
+ }
+ else {
+ cmap[0] = pdefs[i].red >> 10;
+ cmap[1] = pdefs[i].green >> 10;
+ cmap[2] = pdefs[i].blue >> 10;
+ }
+#if 0
+ if (clgd6225Lcd)
+ {
+ /* The LCD doesn't like white */
+ if (cmap[0] == 63) cmap[0]= 62;
+ if (cmap[1] == 63) cmap[1]= 62;
+ if (cmap[2] == 63) cmap[2]= 62;
+ }
+#endif
+
+ if (writeColormap)
+ {
+ if (hwp->ShowOverscan && i == 255)
+ continue;
+ hwp->writeDacWriteAddr(hwp, pdefs[i].pixel);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, cmap[0]);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, cmap[1]);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, cmap[2]);
+ DACDelay(hwp);
+ }
+ }
+ if (new_overscan && !hwp->ShowOverscan)
+ {
+ new_overscan = FALSE;
+ for(i = 0; i < ndef; i++)
+ {
+ if (pdefs[i].pixel == overscan)
+ {
+ if ((pdefs[i].red != 0) ||
+ (pdefs[i].green != 0) ||
+ (pdefs[i].blue != 0))
+ {
+ new_overscan = TRUE;
+ tmp_overscan = overscan;
+ tmp = &(hwp->ModeReg.DAC[pdefs[i].pixel*3]);
+ }
+ break;
+ }
+ }
+ if (new_overscan)
+ {
+ /*
+ * Find a black pixel, or the nearest match.
+ */
+ for (i=255; i >= 0; i--)
+ {
+ cmap = &(hwp->ModeReg.DAC[i*3]);
+ if ((cmap[0] == 0) && (cmap[1] == 0) && (cmap[2] == 0))
+ {
+ overscan = i;
+ break;
+ }
+ else
+ {
+ if ((cmap[0] < tmp[0]) &&
+ (cmap[1] < tmp[1]) && (cmap[2] < tmp[2]))
+ {
+ tmp = cmap;
+ tmp_overscan = i;
+ }
+ }
+ }
+ if (i < 0)
+ {
+ overscan = tmp_overscan;
+ }
+ hwp->ModeReg.Attribute[OVERSCAN] = overscan;
+ if (writeColormap)
+ {
+ hwp->writeAttr(hwp, OVERSCAN, overscan);
+ }
+ }
+ }
+
+ if (writeColormap)
+ hwp->disablePalette(hwp);
+}
+
+
+void
+vgaInstallColormap(pmap)
+ ColormapPtr pmap;
+{
+ ColormapPtr oldmap = miInstalledMaps[pmap->pScreen->myNum];
+ int entries;
+ Pixel * ppix;
+ xrgb * prgb;
+ xColorItem *defs;
+ int i;
+
+
+ if (pmap == oldmap)
+ return;
+
+ if ((pmap->pVisual->class | DynamicClass) == DirectColor)
+ entries = (pmap->pVisual->redMask |
+ pmap->pVisual->greenMask |
+ pmap->pVisual->blueMask) + 1;
+ else
+ entries = pmap->pVisual->ColormapEntries;
+
+ ppix = (Pixel *)ALLOCATE_LOCAL( entries * sizeof(Pixel));
+ prgb = (xrgb *)ALLOCATE_LOCAL( entries * sizeof(xrgb));
+ defs = (xColorItem *)ALLOCATE_LOCAL(entries * sizeof(xColorItem));
+
+ if ( oldmap != NOMAPYET)
+ WalkTree( pmap->pScreen, TellLostMap, &oldmap->mid);
+
+ miInstalledMaps[pmap->pScreen->myNum] = pmap;
+
+ for ( i=0; i<entries; i++) ppix[i] = i;
+
+ QueryColors( pmap, entries, ppix, prgb);
+
+ for ( i=0; i<entries; i++) /* convert xrgbs to xColorItems */
+ {
+ defs[i].pixel = ppix[i];
+ defs[i].red = prgb[i].red;
+ defs[i].green = prgb[i].green;
+ defs[i].blue = prgb[i].blue;
+ defs[i].flags = DoRed|DoGreen|DoBlue;
+ }
+
+ pmap->pScreen->StoreColors(pmap, entries, defs);
+
+ WalkTree(pmap->pScreen, TellGainedMap, &pmap->mid);
+
+ DEALLOCATE_LOCAL(ppix);
+ DEALLOCATE_LOCAL(prgb);
+ DEALLOCATE_LOCAL(defs);
+}
+
+
+void
+vgaUninstallColormap(pmap)
+ ColormapPtr pmap;
+{
+
+ ColormapPtr defColormap;
+
+ if ( pmap != miInstalledMaps[pmap->pScreen->myNum] )
+ return;
+
+ defColormap = (ColormapPtr) LookupIDByType( pmap->pScreen->defColormap,
+ RT_COLORMAP);
+
+ if (defColormap == miInstalledMaps[pmap->pScreen->myNum])
+ return;
+
+ (*pmap->pScreen->InstallColormap) (defColormap);
+}
+
+
+void
+vgaHandleColormaps(ScreenPtr pScreen, ScrnInfoPtr scrnp)
+{
+ if (scrnp->bitsPerPixel > 1) {
+ if (scrnp->bitsPerPixel <= 8) { /* For 8bpp SVGA and VGA16 */
+ pScreen->InstallColormap = vgaInstallColormap;
+ pScreen->UninstallColormap = vgaUninstallColormap;
+ pScreen->ListInstalledColormaps = vgaListInstalledColormaps;
+ pScreen->StoreColors = vgaStoreColors;
+ }
+ }
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/vgahw/vgaHW.c b/xc/programs/Xserver/hw/xfree86/vgahw/vgaHW.c
new file mode 100644
index 000000000..2da052dbd
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgahw/vgaHW.c
@@ -0,0 +1,1868 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgahw/vgaHW.c,v 1.31 1999/08/21 13:48:42 dawes Exp $ */
+
+/*
+ *
+ * Copyright 1991-1999 by The XFree86 Project, Inc.
+ *
+ * Loosely based on code bearing the following copyright:
+ *
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ */
+
+#if !defined(AMOEBA) && !defined(MINIX)
+#define _NEED_SYSI86
+#endif
+
+#include "X.h"
+#include "misc.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86_ansic.h"
+#include "vgaHW.h"
+
+#include "xf86cmap.h"
+
+/*
+ * XXX The PC98 bits have been removed for now. The structure of the
+ * code here has been reorganised to the point where they need to be
+ * redone anyway. In the meantime the older version can be found in
+ * xfree86/olddrivers/vgahw/.
+ */
+
+
+#ifndef SAVE_FONT1
+#define SAVE_FONT1
+#endif
+
+#if defined(Lynx) || defined(CSRG_BASED) || defined(MACH386) || defined(linux) || defined(AMOEBA) || defined(MINIX)
+#ifndef NEED_SAVED_CMAP
+#define NEED_SAVED_CMAP
+#endif
+#ifndef SAVE_TEXT
+#define SAVE_TEXT
+#endif
+#ifndef SAVE_FONT2
+#define SAVE_FONT2
+#endif
+#endif
+
+/* bytes per plane to save for text */
+#define TEXT_AMOUNT 16384
+
+/* bytes per plane to save for font data */
+#define FONT_AMOUNT 8192
+
+#if 0
+/* Override all of these for now */
+#undef SAVE_FONT1
+#define SAVE_FONT1
+#undef SAVE_FONT2
+#define SAVE_FONT2
+#undef SAVE_TEST
+#define SAVE_TEST
+#undef FONT_AMOUNT
+#define FONT_AMOUNT 65536
+#undef TEXT_AMOUNT
+#define TEXT_AMOUNT 65536
+#endif
+
+/* DAC indices for white and black */
+#define WHITE_VALUE 0x3F
+#define BLACK_VALUE 0x00
+#define OVERSCAN_VALUE 0x01
+
+
+/* Use a private definition of this here */
+#undef VGAHWPTR
+#define VGAHWPTRLVAL(p) (p)->privates[vgaHWPrivateIndex].ptr
+#define VGAHWPTR(p) ((vgaHWPtr)(VGAHWPTRLVAL(p)))
+
+static int vgaHWPrivateIndex = -1;
+
+#define DAC_TEST_MASK 0x3F
+
+#ifdef NEED_SAVED_CMAP
+/* This default colourmap is used only when it can't be read from the VGA */
+
+static CARD8 defaultDAC[768] =
+{
+ 0, 0, 0, 0, 0, 42, 0, 42, 0, 0, 42, 42,
+ 42, 0, 0, 42, 0, 42, 42, 21, 0, 42, 42, 42,
+ 21, 21, 21, 21, 21, 63, 21, 63, 21, 21, 63, 63,
+ 63, 21, 21, 63, 21, 63, 63, 63, 21, 63, 63, 63,
+ 0, 0, 0, 5, 5, 5, 8, 8, 8, 11, 11, 11,
+ 14, 14, 14, 17, 17, 17, 20, 20, 20, 24, 24, 24,
+ 28, 28, 28, 32, 32, 32, 36, 36, 36, 40, 40, 40,
+ 45, 45, 45, 50, 50, 50, 56, 56, 56, 63, 63, 63,
+ 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0, 63,
+ 63, 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16,
+ 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0,
+ 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63, 0,
+ 0, 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47,
+ 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63,
+ 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31, 63,
+ 63, 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39,
+ 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31,
+ 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63, 31,
+ 31, 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55,
+ 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63,
+ 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45, 63,
+ 63, 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49,
+ 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45,
+ 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63, 45,
+ 45, 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58,
+ 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63,
+ 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0, 28,
+ 28, 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7,
+ 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0,
+ 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28, 0,
+ 0, 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21,
+ 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28,
+ 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14, 28,
+ 28, 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17,
+ 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14,
+ 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28, 14,
+ 14, 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24,
+ 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28,
+ 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20, 28,
+ 28, 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22,
+ 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20,
+ 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28, 20,
+ 20, 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26,
+ 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28,
+ 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0, 16,
+ 16, 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4,
+ 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0,
+ 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16, 0,
+ 0, 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12,
+ 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16,
+ 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8, 16,
+ 16, 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10,
+ 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8,
+ 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16, 8,
+ 8, 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14,
+ 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16,
+ 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11, 16,
+ 16, 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12,
+ 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11,
+ 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16, 11,
+ 11, 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15,
+ 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+#endif /* NEED_SAVED_CMAP */
+
+/*
+ * With Intel, the version in os-support/misc/SlowBcopy.s is used.
+ * This avoids port I/O during the copy (which causes problems with
+ * some hardware).
+ */
+#ifdef __alpha__
+#define slowbcopy_tobus(src,dst,count) xf86SlowBCopyToBus(src,dst,count)
+#define slowbcopy_frombus(src,dst,count) xf86SlowBCopyFromBus(src,dst,count)
+#else /* __alpha__ */
+#define slowbcopy_tobus(src,dst,count) xf86SlowBcopy(src,dst,count)
+#define slowbcopy_frombus(src,dst,count) xf86SlowBcopy(src,dst,count)
+#endif /* __alpha__ */
+
+
+/*
+ * Standard VGA versions of the register access functions.
+ */
+static void
+stdWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ outb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
+ outb(hwp->IOBase + VGA_CRTC_DATA_OFFSET, value);
+}
+
+static CARD8
+stdReadCrtc(vgaHWPtr hwp, CARD8 index)
+{
+ outb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
+ return inb(hwp->IOBase + VGA_CRTC_DATA_OFFSET);
+}
+
+static void
+stdWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ outb(VGA_GRAPH_INDEX, index);
+ outb(VGA_GRAPH_DATA, value);
+}
+
+static CARD8
+stdReadGr(vgaHWPtr hwp, CARD8 index)
+{
+ outb(VGA_GRAPH_INDEX, index);
+ return inb(VGA_GRAPH_DATA);
+}
+
+static void
+stdWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ outb(VGA_SEQ_INDEX, index);
+ outb(VGA_SEQ_DATA, value);
+}
+
+static CARD8
+stdReadSeq(vgaHWPtr hwp, CARD8 index)
+{
+ outb(VGA_SEQ_INDEX, index);
+ return inb(VGA_SEQ_DATA);
+}
+
+static CARD8
+stdReadST01(vgaHWPtr hwp)
+{
+ return inb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
+}
+
+static void
+stdWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ CARD8 tmp;
+
+ if (hwp->paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+
+ tmp = inb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
+ outb(VGA_ATTR_INDEX, index);
+ outb(VGA_ATTR_DATA_W, value);
+}
+
+static CARD8
+stdReadAttr(vgaHWPtr hwp, CARD8 index)
+{
+ CARD8 tmp;
+
+ if (hwp->paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+
+ tmp = inb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
+ outb(VGA_ATTR_INDEX, index);
+ return inb(VGA_ATTR_DATA_R);
+}
+
+static void
+stdWriteMiscOut(vgaHWPtr hwp, CARD8 value)
+{
+ outb(VGA_MISC_OUT_W, value);
+}
+
+static CARD8
+stdReadMiscOut(vgaHWPtr hwp)
+{
+ return inb(VGA_MISC_OUT_R);
+}
+
+static void
+stdEnablePalette(vgaHWPtr hwp)
+{
+ CARD8 tmp;
+
+ tmp = inb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
+ outb(VGA_ATTR_INDEX, 0x00);
+ hwp->paletteEnabled = TRUE;
+}
+
+static void
+stdDisablePalette(vgaHWPtr hwp)
+{
+ CARD8 tmp;
+
+ tmp = inb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
+ outb(VGA_ATTR_INDEX, 0x20);
+ hwp->paletteEnabled = FALSE;
+}
+
+static void
+stdWriteDacMask(vgaHWPtr hwp, CARD8 value)
+{
+ outb(VGA_DAC_MASK, value);
+}
+
+static CARD8
+stdReadDacMask(vgaHWPtr hwp)
+{
+ return inb(VGA_DAC_MASK);
+}
+
+static void
+stdWriteDacReadAddr(vgaHWPtr hwp, CARD8 value)
+{
+ outb(VGA_DAC_READ_ADDR, value);
+}
+
+static void
+stdWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value)
+{
+ outb(VGA_DAC_WRITE_ADDR, value);
+}
+
+static void
+stdWriteDacData(vgaHWPtr hwp, CARD8 value)
+{
+ outb(VGA_DAC_DATA, value);
+}
+
+static CARD8
+stdReadDacData(vgaHWPtr hwp)
+{
+ return inb(VGA_DAC_DATA);
+}
+
+void
+vgaHWSetStdFuncs(vgaHWPtr hwp)
+{
+ hwp->writeCrtc = stdWriteCrtc;
+ hwp->readCrtc = stdReadCrtc;
+ hwp->writeGr = stdWriteGr;
+ hwp->readGr = stdReadGr;
+ hwp->readST01 = stdReadST01;
+ hwp->writeAttr = stdWriteAttr;
+ hwp->readAttr = stdReadAttr;
+ hwp->writeSeq = stdWriteSeq;
+ hwp->readSeq = stdReadSeq;
+ hwp->writeMiscOut = stdWriteMiscOut;
+ hwp->readMiscOut = stdReadMiscOut;
+ hwp->enablePalette = stdEnablePalette;
+ hwp->disablePalette = stdDisablePalette;
+ hwp->writeDacMask = stdWriteDacMask;
+ hwp->readDacMask = stdReadDacMask;
+ hwp->writeDacWriteAddr = stdWriteDacWriteAddr;
+ hwp->writeDacReadAddr = stdWriteDacReadAddr;
+ hwp->writeDacData = stdWriteDacData;
+ hwp->readDacData = stdReadDacData;
+}
+
+/*
+ * MMIO versions of the register access functions. These require
+ * hwp->MemBase to be set in such a way that when the standard VGA port
+ * adderss is added the correct memory address results.
+ */
+
+#ifndef __alpha__
+#define minb(p) *(volatile CARD8 *)(hwp->MMIOBase + hwp->MMIOOffset + (p))
+#define moutb(p,v) \
+ *(volatile CARD8 *)(hwp->MMIOBase + hwp->MMIOOffset + (p)) = (v)
+#else
+#define minb(p) xf86ReadSparse8(hwp->MMIOBase, hwp->MMIOOffset + (p))
+#define moutb(p,v) \
+ xf86WriteSparse8((v), hwp->MMIOBase, hwp->MMIOOffset + (p))
+#endif
+
+static void
+mmioWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
+ moutb(hwp->IOBase + VGA_CRTC_DATA_OFFSET, value);
+}
+
+static CARD8
+mmioReadCrtc(vgaHWPtr hwp, CARD8 index)
+{
+ moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
+ return minb(hwp->IOBase + VGA_CRTC_DATA_OFFSET);
+}
+
+static void
+mmioWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ moutb(VGA_GRAPH_INDEX, index);
+ moutb(VGA_GRAPH_DATA, value);
+}
+
+static CARD8
+mmioReadGr(vgaHWPtr hwp, CARD8 index)
+{
+ moutb(VGA_GRAPH_INDEX, index);
+ return minb(VGA_GRAPH_DATA);
+}
+
+static void
+mmioWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ moutb(VGA_SEQ_INDEX, index);
+ moutb(VGA_SEQ_DATA, value);
+}
+
+static CARD8
+mmioReadSeq(vgaHWPtr hwp, CARD8 index)
+{
+ moutb(VGA_SEQ_INDEX, index);
+ return minb(VGA_SEQ_DATA);
+}
+
+static CARD8
+mmioReadST01(vgaHWPtr hwp)
+{
+ return minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
+}
+
+static void
+mmioWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ CARD8 tmp;
+
+ if (hwp->paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+
+ tmp = minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
+ moutb(VGA_ATTR_INDEX, index);
+ moutb(VGA_ATTR_DATA_W, value);
+}
+
+static CARD8
+mmioReadAttr(vgaHWPtr hwp, CARD8 index)
+{
+ CARD8 tmp;
+
+ if (hwp->paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+
+ tmp = minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
+ moutb(VGA_ATTR_INDEX, index);
+ return minb(VGA_ATTR_DATA_R);
+}
+
+static void
+mmioWriteMiscOut(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(VGA_MISC_OUT_W, value);
+}
+
+static CARD8
+mmioReadMiscOut(vgaHWPtr hwp)
+{
+ return minb(VGA_MISC_OUT_R);
+}
+
+static void
+mmioEnablePalette(vgaHWPtr hwp)
+{
+ CARD8 tmp;
+
+ tmp = minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
+ moutb(VGA_ATTR_INDEX, 0x00);
+ hwp->paletteEnabled = TRUE;
+}
+
+static void
+mmioDisablePalette(vgaHWPtr hwp)
+{
+ CARD8 tmp;
+
+ tmp = minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
+ moutb(VGA_ATTR_INDEX, 0x20);
+ hwp->paletteEnabled = FALSE;
+}
+
+static void
+mmioWriteDacMask(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(VGA_DAC_MASK, value);
+}
+
+static CARD8
+mmioReadDacMask(vgaHWPtr hwp)
+{
+ return minb(VGA_DAC_MASK);
+}
+
+static void
+mmioWriteDacReadAddr(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(VGA_DAC_READ_ADDR, value);
+}
+
+static void
+mmioWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(VGA_DAC_WRITE_ADDR, value);
+}
+
+static void
+mmioWriteDacData(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(VGA_DAC_DATA, value);
+}
+
+static CARD8
+mmioReadDacData(vgaHWPtr hwp)
+{
+ return minb(VGA_DAC_DATA);
+}
+
+void
+vgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset)
+{
+ hwp->writeCrtc = mmioWriteCrtc;
+ hwp->readCrtc = mmioReadCrtc;
+ hwp->writeGr = mmioWriteGr;
+ hwp->readGr = mmioReadGr;
+ hwp->readST01 = mmioReadST01;
+ hwp->writeAttr = mmioWriteAttr;
+ hwp->readAttr = mmioReadAttr;
+ hwp->writeSeq = mmioWriteSeq;
+ hwp->readSeq = mmioReadSeq;
+ hwp->writeMiscOut = mmioWriteMiscOut;
+ hwp->readMiscOut = mmioReadMiscOut;
+ hwp->enablePalette = mmioEnablePalette;
+ hwp->disablePalette = mmioDisablePalette;
+ hwp->writeDacMask = mmioWriteDacMask;
+ hwp->readDacMask = mmioReadDacMask;
+ hwp->writeDacWriteAddr = mmioWriteDacWriteAddr;
+ hwp->writeDacReadAddr = mmioWriteDacReadAddr;
+ hwp->writeDacData = mmioWriteDacData;
+ hwp->readDacData = mmioReadDacData;
+ hwp->MMIOBase = base;
+ hwp->MMIOOffset = offset;
+}
+
+/*
+ * vgaHWProtect --
+ * Protect VGA registers and memory from corruption during loads.
+ */
+
+void
+vgaHWProtect(ScrnInfoPtr pScrn, Bool on)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ unsigned char tmp;
+
+ if (pScrn->vtSema) {
+ if (on) {
+ /*
+ * Turn off screen and disable sequencer.
+ */
+ tmp = hwp->readSeq(hwp, 0x01);
+
+ vgaHWSeqReset(hwp, TRUE); /* start synchronous reset */
+ hwp->writeSeq(hwp, 0x01, tmp | 0x20); /* disable the display */
+
+ hwp->enablePalette(hwp);
+ } else {
+ /*
+ * Reenable sequencer, then turn on screen.
+ */
+
+ tmp = hwp->readSeq(hwp, 0x01);
+
+ hwp->writeSeq(hwp, 0x01, tmp & ~0x20); /* reenable display */
+ vgaHWSeqReset(hwp, FALSE); /* clear synchronousreset */
+
+ hwp->disablePalette(hwp);
+ }
+ }
+}
+
+
+/*
+ * vgaHWBlankScreen -- blank the screen.
+ */
+
+void
+vgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ unsigned char scrn;
+
+ scrn = hwp->readSeq(hwp, 0x01);
+
+ if (on) {
+ scrn &= ~0x20; /* enable screen */
+ } else {
+ scrn |= 0x20; /* blank screen */
+ }
+
+ vgaHWSeqReset(hwp, TRUE);
+ hwp->writeSeq(hwp, 0x01, scrn); /* change mode */
+ vgaHWSeqReset(hwp, FALSE);
+}
+
+
+/*
+ * vgaHWSaveScreen -- blank the screen.
+ */
+
+Bool
+vgaHWSaveScreen(ScreenPtr pScreen, Bool on)
+{
+ ScrnInfoPtr pScrn = NULL;
+
+ if (pScreen != NULL)
+ pScrn = xf86Screens[pScreen->myNum];
+
+ if (on)
+ SetTimeSinceLastInputEvent();
+
+ if ((pScrn != NULL) && pScrn->vtSema) {
+ vgaHWBlankScreen(pScrn, on);
+ }
+ return (TRUE);
+}
+
+
+/*
+ * vgaHWDPMSSet -- Sets VESA Display Power Management Signaling (DPMS) Mode
+ *
+ * This generic VGA function can only set the Off and On modes. If the
+ * Standby and Suspend modes are to be supported, a chip specific replacement
+ * for this function must be written.
+ */
+
+void
+vgaHWDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
+{
+#ifdef DPMSExtension
+ unsigned char seq1 = 0, crtc17 = 0;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ if (!pScrn->vtSema) return;
+
+ switch (PowerManagementMode) {
+ case DPMSModeOn:
+ /* Screen: On; HSync: On, VSync: On */
+ seq1 = 0x00;
+ crtc17 = 0x80;
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off; HSync: Off, VSync: On -- Not Supported */
+ seq1 = 0x20;
+ crtc17 = 0x80;
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off; HSync: On, VSync: Off -- Not Supported */
+ seq1 = 0x20;
+ crtc17 = 0x80;
+ break;
+ case DPMSModeOff:
+ /* Screen: Off; HSync: Off, VSync: Off */
+ seq1 = 0x20;
+ crtc17 = 0x00;
+ break;
+ }
+ hwp->writeSeq(hwp, 0x00, 0x01); /* Synchronous Reset */
+ seq1 |= hwp->readSeq(hwp, 0x01) & ~0x20;
+ hwp->writeSeq(hwp, 0x01, seq1);
+ crtc17 |= hwp->readCrtc(hwp, 0x17) & ~0x80;
+ usleep(10000);
+ hwp->writeCrtc(hwp, 0x17, crtc17);
+ hwp->writeSeq(hwp, 0x00, 0x03); /* End Reset */
+#endif
+}
+
+
+/*
+ * vgaHWSeqReset
+ * perform a sequencer reset.
+ */
+
+void
+vgaHWSeqReset(vgaHWPtr hwp, Bool start)
+{
+ if (start)
+ hwp->writeSeq(hwp, 0x00, 0x01); /* Synchronous Reset */
+ else
+ hwp->writeSeq(hwp, 0x00, 0x03); /* End Reset */
+}
+
+
+void
+vgaHWRestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore)
+{
+ vgaHWPtr hwp = VGAHWPTR(scrninfp);
+ int savedIOBase;
+ unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4;
+ Bool doMap = FALSE;
+
+#if defined(SAVE_TEXT) || defined(SAVE_FONT1) || defined(SAVE_FONT2)
+
+ /* If nothing to do, return now */
+ if (!hwp->FontInfo1 && !hwp->FontInfo2 && !hwp->TextInfo)
+ return;
+
+ if (hwp->Base == NULL) {
+ doMap = TRUE;
+ if (!vgaHWMapMem(scrninfp)) {
+ xf86DrvMsg(scrninfp->scrnIndex, X_ERROR,
+ "vgaHWRestoreFonts: vgaHWMapMem() failed\n");
+ return;
+ }
+ }
+
+ /* save the registers that are needed here */
+ miscOut = hwp->readMiscOut(hwp);
+ attr10 = hwp->readAttr(hwp, 0x10);
+ gr1 = hwp->readGr(hwp, 0x01);
+ gr3 = hwp->readGr(hwp, 0x03);
+ gr4 = hwp->readGr(hwp, 0x04);
+ gr5 = hwp->readGr(hwp, 0x05);
+ gr6 = hwp->readGr(hwp, 0x06);
+ gr8 = hwp->readGr(hwp, 0x08);
+ seq2 = hwp->readSeq(hwp, 0x02);
+ seq4 = hwp->readSeq(hwp, 0x04);
+
+ /* save hwp->IOBase and temporarily set it for colour mode */
+ savedIOBase = hwp->IOBase;
+ hwp->IOBase = VGA_IOBASE_COLOR;
+
+ /* Force into colour mode */
+ hwp->writeMiscOut(hwp, miscOut | 0x01);
+
+ vgaHWBlankScreen(scrninfp, FALSE);
+
+ /*
+ * here we temporarily switch to 16 colour planar mode, to simply
+ * copy the font-info and saved text.
+ *
+ * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
+ */
+
+ hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */
+ if (scrninfp->depth == 4) {
+ /* GJA */
+ hwp->writeGr(hwp, 0x03, 0x00); /* don't rotate, write unmodified */
+ hwp->writeGr(hwp, 0x08, 0xFF); /* write all bits in a byte */
+ hwp->writeGr(hwp, 0x01, 0x00); /* all planes come from CPU */
+ }
+
+#ifdef SAVE_FONT1
+ if (hwp->FontInfo1) {
+ hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */
+ hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
+ hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */
+ hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
+ hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
+ slowbcopy_tobus(hwp->FontInfo1, hwp->Base, FONT_AMOUNT);
+ }
+#endif
+
+#ifdef SAVE_FONT2
+ if (hwp->FontInfo2) {
+ hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */
+ hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
+ hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */
+ hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
+ hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
+ slowbcopy_tobus(hwp->FontInfo2, hwp->Base, FONT_AMOUNT);
+ }
+#endif
+
+#ifdef SAVE_TEXT
+ if (hwp->TextInfo) {
+ hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */
+ hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
+ hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */
+ hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
+ hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
+ slowbcopy_tobus(hwp->TextInfo, hwp->Base, TEXT_AMOUNT);
+ hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */
+ hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
+ hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */
+ hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
+ hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
+ slowbcopy_tobus((unsigned char *)hwp->TextInfo + TEXT_AMOUNT,
+ hwp->Base, TEXT_AMOUNT);
+ }
+#endif
+
+ vgaHWBlankScreen(scrninfp, TRUE);
+
+ /* restore the registers that were changed */
+ hwp->writeMiscOut(hwp, miscOut);
+ hwp->writeAttr(hwp, 0x10, attr10);
+ hwp->writeGr(hwp, 0x01, gr1);
+ hwp->writeGr(hwp, 0x03, gr3);
+ hwp->writeGr(hwp, 0x04, gr4);
+ hwp->writeGr(hwp, 0x05, gr5);
+ hwp->writeGr(hwp, 0x06, gr6);
+ hwp->writeGr(hwp, 0x08, gr8);
+ hwp->writeSeq(hwp, 0x02, seq2);
+ hwp->writeSeq(hwp, 0x04, seq4);
+ hwp->IOBase = savedIOBase;
+
+ if (doMap)
+ vgaHWUnmapMem(scrninfp);
+
+#endif /* defined(SAVE_TEXT) || defined(SAVE_FONT1) || defined(SAVE_FONT2) */
+}
+
+
+void
+vgaHWRestoreMode(ScrnInfoPtr scrninfp, vgaRegPtr restore)
+{
+ vgaHWPtr hwp = VGAHWPTR(scrninfp);
+ int i;
+
+ if (restore->MiscOutReg & 0x01)
+ hwp->IOBase = VGA_IOBASE_COLOR;
+ else
+ hwp->IOBase = VGA_IOBASE_MONO;
+
+ hwp->writeMiscOut(hwp, restore->MiscOutReg);
+
+ for (i = 1; i < restore->numSequencer; i++)
+ hwp->writeSeq(hwp, i, restore->Sequencer[i]);
+
+ /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */
+
+ hwp->writeCrtc(hwp, 17, restore->CRTC[17] & ~0x80);
+
+ for (i = 0; i < restore->numCRTC; i++)
+ hwp->writeCrtc(hwp, i, restore->CRTC[i]);
+
+ for (i = 0; i < restore->numGraphics; i++)
+ hwp->writeGr(hwp, i, restore->Graphics[i]);
+
+ hwp->enablePalette(hwp);
+ for (i = 0; i < restore->numAttribute; i++)
+ hwp->writeAttr(hwp, i, restore->Attribute[i]);
+ hwp->disablePalette(hwp);
+}
+
+
+void
+vgaHWRestoreColormap(ScrnInfoPtr scrninfp, vgaRegPtr restore)
+{
+ vgaHWPtr hwp = VGAHWPTR(scrninfp);
+ int i;
+
+#if 0
+ hwp->enablePalette(hwp);
+#endif
+
+ hwp->writeDacMask(hwp, 0xFF);
+ hwp->writeDacWriteAddr(hwp, 0x00);
+ for (i = 0; i < 768; i++) {
+ hwp->writeDacData(hwp, restore->DAC[i]);
+ DACDelay(hwp);
+ }
+
+ hwp->disablePalette(hwp);
+}
+
+
+/*
+ * vgaHWRestore --
+ * restore the VGA state
+ */
+
+void
+vgaHWRestore(ScrnInfoPtr scrninfp, vgaRegPtr restore, int flags)
+{
+ if (flags & VGA_SR_MODE)
+ vgaHWRestoreMode(scrninfp, restore);
+
+ if (flags & VGA_SR_FONTS)
+ vgaHWRestoreFonts(scrninfp, restore);
+
+ if (flags & VGA_SR_CMAP)
+ vgaHWRestoreColormap(scrninfp, restore);
+}
+
+void
+vgaHWSaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save)
+{
+ vgaHWPtr hwp = VGAHWPTR(scrninfp);
+ int savedIOBase;
+ unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4;
+ Bool doMap = FALSE;
+
+#if defined(SAVE_TEXT) || defined(SAVE_FONT1) || defined(SAVE_FONT2)
+
+ if (hwp->Base == NULL) {
+ doMap = TRUE;
+ if (!vgaHWMapMem(scrninfp)) {
+ xf86DrvMsg(scrninfp->scrnIndex, X_ERROR,
+ "vgaHWSaveFonts: vgaHWMapMem() failed\n");
+ return;
+ }
+ }
+
+ /* If in graphics mode, don't save anything */
+ attr10 = hwp->readAttr(hwp, 0x10);
+ if (attr10 & 0x01)
+ return;
+
+ /* save the registers that are needed here */
+ miscOut = hwp->readMiscOut(hwp);
+ gr4 = hwp->readGr(hwp, 0x04);
+ gr5 = hwp->readGr(hwp, 0x05);
+ gr6 = hwp->readGr(hwp, 0x06);
+ seq2 = hwp->readSeq(hwp, 0x02);
+ seq4 = hwp->readSeq(hwp, 0x04);
+
+ /* save hwp->IOBase and temporarily set it for colour mode */
+ savedIOBase = hwp->IOBase;
+ hwp->IOBase = VGA_IOBASE_COLOR;
+
+ /* Force into colour mode */
+ hwp->writeMiscOut(hwp, miscOut | 0x01);
+
+ vgaHWBlankScreen(scrninfp, FALSE);
+
+ /*
+ * get the character sets, and text screen if required
+ */
+ /*
+ * Here we temporarily switch to 16 colour planar mode, to simply
+ * copy the font-info
+ *
+ * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
+ */
+
+ hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */
+
+#ifdef SAVE_FONT1
+ if (hwp->FontInfo1 || (hwp->FontInfo1 = xalloc(FONT_AMOUNT))) {
+ hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */
+ hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
+ hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */
+ hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
+ hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
+ slowbcopy_frombus(hwp->Base, hwp->FontInfo1, FONT_AMOUNT);
+ }
+#endif /* SAVE_FONT1 */
+#ifdef SAVE_FONT2
+ if (hwp->FontInfo2 || (hwp->FontInfo2 = xalloc(FONT_AMOUNT))) {
+ hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */
+ hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
+ hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */
+ hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
+ hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
+ slowbcopy_frombus(hwp->Base, hwp->FontInfo2, FONT_AMOUNT);
+ }
+#endif /* SAVE_FONT2 */
+#ifdef SAVE_TEXT
+ if (hwp->TextInfo || (hwp->TextInfo = xalloc(2 * TEXT_AMOUNT))) {
+ hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */
+ hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
+ hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */
+ hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
+ hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
+ slowbcopy_frombus(hwp->Base, hwp->TextInfo, TEXT_AMOUNT);
+ hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */
+ hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
+ hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */
+ hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
+ hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
+ slowbcopy_frombus(hwp->Base,
+ (unsigned char *)hwp->TextInfo + TEXT_AMOUNT, TEXT_AMOUNT);
+ }
+#endif /* SAVE_TEXT */
+
+ /* Restore clobbered registers */
+ hwp->writeAttr(hwp, 0x10, attr10);
+ hwp->writeSeq(hwp, 0x02, seq2);
+ hwp->writeSeq(hwp, 0x04, seq4);
+ hwp->writeGr(hwp, 0x04, gr4);
+ hwp->writeGr(hwp, 0x05, gr5);
+ hwp->writeGr(hwp, 0x06, gr6);
+ hwp->writeMiscOut(hwp, miscOut);
+ hwp->IOBase = savedIOBase;
+
+ vgaHWBlankScreen(scrninfp, TRUE);
+
+ if (doMap)
+ vgaHWUnmapMem(scrninfp);
+
+#endif /* defined(SAVE_TEXT) || defined(SAVE_FONT1) || defined(SAVE_FONT2) */
+}
+
+void
+vgaHWSaveMode(ScrnInfoPtr scrninfp, vgaRegPtr save)
+{
+ vgaHWPtr hwp = VGAHWPTR(scrninfp);
+ int i;
+
+ save->MiscOutReg = hwp->readMiscOut(hwp);
+ if (save->MiscOutReg & 0x01)
+ hwp->IOBase = VGA_IOBASE_COLOR;
+ else
+ hwp->IOBase = VGA_IOBASE_MONO;
+
+ for (i = 0; i < save->numCRTC; i++) {
+ save->CRTC[i] = hwp->readCrtc(hwp, i);
+#ifdef DEBUG
+ ErrorF("CRTC[0x%02x] = 0x%02x\n", i, save->CRTC[i]);
+#endif
+ }
+
+ hwp->enablePalette(hwp);
+ for (i = 0; i < save->numAttribute; i++) {
+ save->Attribute[i] = hwp->readAttr(hwp, i);
+#ifdef DEBUG
+ ErrorF("Attribute[0x%02x] = 0x%02x\n", i, save->Attribute[i]);
+#endif
+ }
+ hwp->disablePalette(hwp);
+
+ for (i = 0; i < save->numGraphics; i++) {
+ save->Graphics[i] = hwp->readGr(hwp, i);
+#ifdef DEBUG
+ ErrorF("Graphics[0x%02x] = 0x%02x\n", i, save->Graphics[i]);
+#endif
+ }
+
+ for (i = 1; i < save->numSequencer; i++) {
+ save->Sequencer[i] = hwp->readSeq(hwp, i);
+#ifdef DEBUG
+ ErrorF("Sequencer[0x%02x] = 0x%02x\n", i, save->Sequencer[i]);
+#endif
+ }
+}
+
+
+void
+vgaHWSaveColormap(ScrnInfoPtr scrninfp, vgaRegPtr save)
+{
+ vgaHWPtr hwp = VGAHWPTR(scrninfp);
+ Bool readError = FALSE;
+ int i;
+
+#ifdef NEED_SAVED_CMAP
+ /*
+ * Some ET4000 chips from 1991 have a HW bug that prevents the reading
+ * of the color lookup table. Mask rev 9042EAI is known to have this bug.
+ *
+ * If the colourmap is not readable, we set the saved map to a default
+ * map (taken from Ferraro's "Programmer's Guide to the EGA and VGA
+ * Cards" 2nd ed).
+ */
+
+ /* Only save it once */
+ if (hwp->cmapSaved)
+ return;
+
+#if 0
+ hwp->enablePalette(hwp);
+#endif
+
+ hwp->writeDacMask(hwp, 0xFF);
+ /*
+ * check if we can read the lookup table
+ */
+ hwp->writeDacReadAddr(hwp, 0x00);
+ for (i = 0; i < 3; i++) {
+ save->DAC[i] = hwp->readDacData(hwp);
+#ifdef DEBUG
+ switch (i % 3) {
+ case 0:
+ ErrorF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]);
+ break;
+ case 1:
+ ErrorF("0x%02x, ", save->DAC[i]);
+ break;
+ case 2:
+ ErrorF("0x%02x\n", save->DAC[i]);
+ }
+#endif
+ }
+ hwp->writeDacWriteAddr(hwp, 0x00);
+ for (i = 0; i < 3; i++)
+ hwp->writeDacData(hwp, ~save->DAC[i] & DAC_TEST_MASK);
+ hwp->writeDacReadAddr(hwp, 0x00);
+ for (i = 0; i < 3; i++) {
+ if (hwp->readDacData(hwp) != (~save->DAC[i] & DAC_TEST_MASK))
+ readError = TRUE;
+ }
+
+ if (readError) {
+ /*
+ * save the default lookup table
+ */
+ memmove(save->DAC, defaultDAC, 768);
+ xf86DrvMsg(scrninfp->scrnIndex, X_WARNING,
+ "Cannot read colourmap from VGA. Will restore with default\n");
+ } else {
+ /* save the colourmap */
+ hwp->writeDacReadAddr(hwp, 0x01);
+ for (i = 3; i < 768; i++) {
+ save->DAC[i] = hwp->readDacData(hwp);
+ DACDelay(hwp);
+#ifdef DEBUG
+ switch (i % 3) {
+ case 0:
+ ErrorF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]);
+ break;
+ case 1:
+ ErrorF("0x%02x, ", save->DAC[i]);
+ break;
+ case 2:
+ ErrorF("0x%02x\n", save->DAC[i]);
+ }
+#endif
+ }
+ }
+ hwp->disablePalette(hwp);
+ hwp->cmapSaved = TRUE;
+#endif
+}
+
+/*
+ * vgaHWSave --
+ * save the current VGA state
+ */
+
+void
+vgaHWSave(ScrnInfoPtr scrninfp, vgaRegPtr save, int flags)
+{
+ if (save == NULL)
+ return;
+
+ if (flags & VGA_SR_CMAP)
+ vgaHWSaveColormap(scrninfp, save);
+
+ if (flags & VGA_SR_MODE)
+ vgaHWSaveMode(scrninfp, save);
+
+ if (flags & VGA_SR_FONTS)
+ vgaHWSaveFonts(scrninfp, save);
+}
+
+
+/*
+ * vgaHWInit --
+ * Handle the initialization, etc. of a screen.
+ * Return FALSE on failure.
+ */
+
+Bool
+vgaHWInit(ScrnInfoPtr scrninfp, DisplayModePtr mode)
+{
+ unsigned int i;
+ vgaHWPtr hwp;
+ vgaRegPtr regp;
+ int depth = scrninfp->depth;
+
+ /*
+ * make sure the vgaHWRec is allocated
+ */
+ if (!vgaHWGetHWRec(scrninfp))
+ return FALSE;
+ hwp = VGAHWPTR(scrninfp);
+ regp = &hwp->ModeReg;
+
+ /*
+ * compute correct Hsync & Vsync polarity
+ */
+ if ((mode->Flags & (V_PHSYNC | V_NHSYNC))
+ && (mode->Flags & (V_PVSYNC | V_NVSYNC)))
+ {
+ regp->MiscOutReg = 0x23;
+ if (mode->Flags & V_NHSYNC) regp->MiscOutReg |= 0x40;
+ if (mode->Flags & V_NVSYNC) regp->MiscOutReg |= 0x80;
+ }
+ else
+ {
+ int VDisplay = mode->VDisplay;
+ if (mode->Flags & V_DBLSCAN)
+ VDisplay *= 2;
+ if (mode->VScan > 1)
+ VDisplay *= mode->VScan;
+ if (VDisplay < 400)
+ regp->MiscOutReg = 0xA3; /* +hsync -vsync */
+ else if (VDisplay < 480)
+ regp->MiscOutReg = 0x63; /* -hsync +vsync */
+ else if (VDisplay < 768)
+ regp->MiscOutReg = 0xE3; /* -hsync -vsync */
+ else
+ regp->MiscOutReg = 0x23; /* +hsync +vsync */
+ }
+
+ regp->MiscOutReg |= (mode->ClockIndex & 0x03) << 2;
+
+ /*
+ * Time Sequencer
+ */
+ if (depth == 4)
+ regp->Sequencer[0] = 0x02;
+ else
+ regp->Sequencer[0] = 0x00;
+ if (mode->Flags & V_CLKDIV2)
+ regp->Sequencer[1] = 0x09;
+ else
+ regp->Sequencer[1] = 0x01;
+ if (depth == 1)
+ regp->Sequencer[2] = 1 << BIT_PLANE;
+ else
+ regp->Sequencer[2] = 0x0F;
+ regp->Sequencer[3] = 0x00; /* Font select */
+ if (depth < 8)
+ regp->Sequencer[4] = 0x06; /* Misc */
+ else
+ regp->Sequencer[4] = 0x0E; /* Misc */
+
+ /*
+ * CRTC Controller
+ */
+ regp->CRTC[0] = (mode->CrtcHTotal >> 3) - 5;
+ regp->CRTC[1] = (mode->CrtcHDisplay >> 3) - 1;
+ regp->CRTC[2] = (mode->CrtcHBlankStart >> 3) - 1;
+ regp->CRTC[3] = (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
+ i = (((mode->CrtcHSkew << 2) + 0x10) & ~0x1F);
+ if (i < 0x80)
+ regp->CRTC[3] |= i;
+ regp->CRTC[4] = (mode->CrtcHSyncStart >> 3);
+ regp->CRTC[5] = ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2)
+ | (((mode->CrtcHSyncEnd >> 3)) & 0x1F);
+ regp->CRTC[6] = (mode->CrtcVTotal - 2) & 0xFF;
+ regp->CRTC[7] = (((mode->CrtcVTotal - 2) & 0x100) >> 8)
+ | (((mode->CrtcVDisplay - 1) & 0x100) >> 7)
+ | ((mode->CrtcVSyncStart & 0x100) >> 6)
+ | (((mode->CrtcVBlankStart - 1) & 0x100) >> 5)
+ | 0x10
+ | (((mode->CrtcVTotal - 2) & 0x200) >> 4)
+ | (((mode->CrtcVDisplay - 1) & 0x200) >> 3)
+ | ((mode->CrtcVSyncStart & 0x200) >> 2);
+ regp->CRTC[8] = 0x00;
+ regp->CRTC[9] = (((mode->CrtcVBlankStart - 1) & 0x200) >> 4) | 0x40;
+ if (mode->Flags & V_DBLSCAN)
+ regp->CRTC[9] |= 0x80;
+ if (mode->VScan >= 32)
+ regp->CRTC[9] |= 0x1F;
+ else if (mode->VScan > 1)
+ regp->CRTC[9] |= mode->VScan - 1;
+ regp->CRTC[10] = 0x00;
+ regp->CRTC[11] = 0x00;
+ regp->CRTC[12] = 0x00;
+ regp->CRTC[13] = 0x00;
+ regp->CRTC[14] = 0x00;
+ regp->CRTC[15] = 0x00;
+ regp->CRTC[16] = mode->CrtcVSyncStart & 0xFF;
+ regp->CRTC[17] = (mode->CrtcVSyncEnd & 0x0F) | 0x20;
+ regp->CRTC[18] = (mode->CrtcVDisplay - 1) & 0xFF;
+ regp->CRTC[19] = scrninfp->displayWidth >> 4; /* just a guess */
+ regp->CRTC[20] = 0x00;
+ regp->CRTC[21] = (mode->CrtcVBlankStart - 1) & 0xFF;
+ regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF;
+ if (depth < 8)
+ regp->CRTC[23] = 0xE3;
+ else
+ regp->CRTC[23] = 0xC3;
+ regp->CRTC[24] = 0xFF;
+
+ /*
+ * OK, so much for theory. Now, let's deal with the >real< world...
+ *
+ * The above CRTC settings are precise in theory, except that many, if not
+ * most, VGA clones fail to reset the blanking signal when the character or
+ * line counter reaches [HV]Total. In this case, the signal is only
+ * unblanked when the counter reaches [HV]BlankEnd (mod 64, 128 or 256 as
+ * the case may be) at the start of the >next< scanline or frame, which
+ * means only part of the screen shows. This affects how null overscans
+ * are to be implemented on such adapters.
+ *
+ * Henceforth, VGA cores that implement this broken, but unfortunately
+ * common, behaviour are to be designated as KGA's, in honour of Koen
+ * Gadeyne, whose zeal to eliminate overscans (read: fury) set in motion
+ * a series of events that led to the discovery of this problem.
+ *
+ * Some VGA's are KGA's only in the horizontal, or only in the vertical,
+ * some in both, others in neither. Don't let anyone tell you there is
+ * such a thing as a VGA "standard"... And, thank the Creator for the fact
+ * that Hilbert spaces are not yet implemented in this industry.
+ *
+ * The following implements a trick suggested by David Dawes. This sets
+ * [HV]BlankEnd to zero if the blanking interval does not already contain a
+ * 0-point, and decrements it by one otherwise. In the latter case, this
+ * will produce a left and/or top overscan which the colourmap code will
+ * (still) need to ensure is as close to black as possible. This will make
+ * the behaviour consistent across all chipsets, while allowing all
+ * chipsets to display the entire screen. Non-KGA drivers can ignore the
+ * following in their own copy of this code.
+ *
+ * -- TSI @ UQV, 1998.08.21
+ */
+
+ /* First the horizontal case */
+ if ((mode->CrtcHBlankEnd >> 3) == (mode->CrtcHTotal >> 3))
+ {
+ i = (regp->CRTC[3] & 0x1F) | ((regp->CRTC[5] & 0x80) >> 2);
+ if ((i-- > (regp->CRTC[2] & 0x3F)) &&
+ (mode->CrtcHBlankEnd == mode->CrtcHTotal))
+ i = 0;
+ regp->CRTC[3] = (regp->CRTC[3] & ~0x1F) | (i & 0x1F);
+ regp->CRTC[5] = (regp->CRTC[5] & ~0x80) | ((i << 2) & 0x80);
+ }
+
+ /*
+ * The vertical case is a little trickier. Some VGA's ignore bit 0x80 of
+ * CRTC[22]. Also, in some cases, a zero CRTC[22] will still blank the
+ * very first scanline in a double- or multi-scanned mode. This last case
+ * needs further investigation.
+ */
+ if (mode->CrtcVBlankEnd == mode->CrtcVTotal) /* Null top overscan */
+ {
+ i = regp->CRTC[22];
+ if ((i > regp->CRTC[21]) && /* 8-bit case */
+ ((i & 0x7F) > (regp->CRTC[21] & 0x7F)) && /* 7-bit case */
+ !(regp->CRTC[9] & 0x9F)) /* 1 scanline/row */
+ i = 0;
+ else
+ i = (CARD8)(i - 1);
+ regp->CRTC[22] = i;
+ }
+
+ /*
+ * Theory resumes here....
+ */
+
+ /*
+ * Graphics Display Controller
+ */
+ regp->Graphics[0] = 0x00;
+ regp->Graphics[1] = 0x00;
+ regp->Graphics[2] = 0x00;
+ regp->Graphics[3] = 0x00;
+ if (depth == 1) {
+ regp->Graphics[4] = BIT_PLANE;
+ regp->Graphics[5] = 0x00;
+ } else {
+ regp->Graphics[4] = 0x00;
+ if (depth == 4)
+ regp->Graphics[5] = 0x02;
+ else
+ regp->Graphics[5] = 0x40;
+ }
+ regp->Graphics[6] = 0x05; /* only map 64k VGA memory !!!! */
+ regp->Graphics[7] = 0x0F;
+ regp->Graphics[8] = 0xFF;
+
+ if (depth == 1) {
+ /* Initialise the Mono map according to which bit-plane gets used */
+
+ Bool flipPixels = xf86GetFlipPixels();
+
+ for (i=0; i<16; i++)
+ if (((i & (1 << BIT_PLANE)) != 0) != flipPixels)
+ regp->Attribute[i] = WHITE_VALUE;
+ else
+ regp->Attribute[i] = BLACK_VALUE;
+
+ regp->Attribute[16] = 0x01; /* -VGA2- */ /* wrong for the ET4000 */
+ if (!hwp->ShowOverscan)
+ regp->Attribute[OVERSCAN] = OVERSCAN_VALUE; /* -VGA2- */
+ } else {
+ regp->Attribute[0] = 0x00; /* standard colormap translation */
+ regp->Attribute[1] = 0x01;
+ regp->Attribute[2] = 0x02;
+ regp->Attribute[3] = 0x03;
+ regp->Attribute[4] = 0x04;
+ regp->Attribute[5] = 0x05;
+ regp->Attribute[6] = 0x06;
+ regp->Attribute[7] = 0x07;
+ regp->Attribute[8] = 0x08;
+ regp->Attribute[9] = 0x09;
+ regp->Attribute[10] = 0x0A;
+ regp->Attribute[11] = 0x0B;
+ regp->Attribute[12] = 0x0C;
+ regp->Attribute[13] = 0x0D;
+ regp->Attribute[14] = 0x0E;
+ regp->Attribute[15] = 0x0F;
+ if (depth == 4)
+ regp->Attribute[16] = 0x81; /* wrong for the ET4000 */
+ else
+ regp->Attribute[16] = 0x41; /* wrong for the ET4000 */
+ /* Attribute[17] (overscan) initialised in vgaHWGetHWRec() */
+ }
+ regp->Attribute[18] = 0x0F;
+ regp->Attribute[19] = 0x00;
+ regp->Attribute[20] = 0x00;
+
+ return(TRUE);
+}
+
+
+/*
+ * these are some more hardware specific helpers, formerly in vga.c
+ */
+static void
+vgaHWGetHWRecPrivate(void)
+{
+ if (vgaHWPrivateIndex < 0)
+ vgaHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
+ return;
+}
+
+
+static void
+vgaHWFreeRegs(vgaRegPtr regp)
+{
+ if (regp->CRTC)
+ xfree (regp->CRTC);
+
+ regp->CRTC =
+ regp->Sequencer =
+ regp->Graphics =
+ regp->Attribute = NULL;
+
+ regp->numCRTC =
+ regp->numSequencer =
+ regp->numGraphics =
+ regp->numAttribute = 0;
+}
+
+
+
+static Bool
+vgaHWAllocRegs(vgaRegPtr regp)
+{
+ unsigned char *buf;
+
+ if ((regp->numCRTC + regp->numSequencer + regp->numGraphics +
+ regp->numAttribute) == 0)
+ return FALSE;
+
+ buf = xcalloc(regp->numCRTC +
+ regp->numSequencer +
+ regp->numGraphics +
+ regp->numAttribute, 1);
+ if (!buf)
+ return FALSE;
+
+ regp->CRTC = buf;
+ regp->Sequencer = regp->CRTC + regp->numCRTC;
+ regp->Graphics = regp->Sequencer + regp->numSequencer;
+ regp->Attribute = regp->Graphics + regp->numGraphics;
+
+ return TRUE;
+}
+
+
+static Bool
+vgaHWAllocDefaultRegs(vgaRegPtr regp)
+{
+ regp->numCRTC = VGA_NUM_CRTC;
+ regp->numSequencer = VGA_NUM_SEQ;
+ regp->numGraphics = VGA_NUM_GFX;
+ regp->numAttribute = VGA_NUM_ATTR;
+
+ return vgaHWAllocRegs(regp);
+}
+
+
+Bool
+vgaHWSetRegCounts(ScrnInfoPtr scrp, int numCRTC, int numSequencer,
+ int numGraphics, int numAttribute)
+{
+#define VGAHWMINNUM(regtype) \
+ ((newMode.num##regtype < regp->num##regtype) ? \
+ (newMode.num##regtype) : (regp->num##regtype))
+#define VGAHWCOPYREGSET(regtype) \
+ memcpy (newMode.regtype, regp->regtype, VGAHWMINNUM(regtype))
+
+ vgaRegRec newMode, newSaved;
+ vgaRegPtr regp;
+
+ regp = &VGAHWPTR(scrp)->ModeReg;
+ memcpy (&newMode, regp, sizeof(vgaRegRec));
+
+ /* allocate space for new registers */
+
+ regp = &newMode;
+ regp->numCRTC = numCRTC;
+ regp->numSequencer = numSequencer;
+ regp->numGraphics = numGraphics;
+ regp->numAttribute = numAttribute;
+ if (!vgaHWAllocRegs(regp))
+ return FALSE;
+
+ regp = &VGAHWPTR(scrp)->SavedReg;
+ memcpy (&newSaved, regp, sizeof(vgaRegRec));
+
+ regp = &newSaved;
+ regp->numCRTC = numCRTC;
+ regp->numSequencer = numSequencer;
+ regp->numGraphics = numGraphics;
+ regp->numAttribute = numAttribute;
+ if (!vgaHWAllocRegs(regp)) {
+ vgaHWFreeRegs(&newMode);
+ return FALSE;
+ }
+
+ /* allocations succeeded, copy register data into new space */
+
+ regp = &VGAHWPTR(scrp)->ModeReg;
+ VGAHWCOPYREGSET(CRTC);
+ VGAHWCOPYREGSET(Sequencer);
+ VGAHWCOPYREGSET(Graphics);
+ VGAHWCOPYREGSET(Attribute);
+
+ regp = &VGAHWPTR(scrp)->SavedReg;
+ VGAHWCOPYREGSET(CRTC);
+ VGAHWCOPYREGSET(Sequencer);
+ VGAHWCOPYREGSET(Graphics);
+ VGAHWCOPYREGSET(Attribute);
+
+ /* free old register arrays */
+
+ regp = &VGAHWPTR(scrp)->ModeReg;
+ vgaHWFreeRegs(regp);
+ memcpy(regp, &newMode, sizeof(vgaRegRec));
+
+ regp = &VGAHWPTR(scrp)->SavedReg;
+ vgaHWFreeRegs(regp);
+ memcpy(regp, &newSaved, sizeof(vgaRegRec));
+
+ return TRUE;
+
+#undef VGAHWMINNUM
+#undef VGAHWCOPYREGSET
+}
+
+
+Bool
+vgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src)
+{
+ vgaHWFreeRegs(dst);
+
+ memcpy(dst, src, sizeof(vgaRegRec));
+
+ if (!vgaHWAllocRegs(dst))
+ return FALSE;
+
+ memcpy(dst->CRTC, src->CRTC, src->numCRTC);
+ memcpy(dst->Sequencer, src->Sequencer, src->numSequencer);
+ memcpy(dst->Graphics, src->Graphics, src->numGraphics);
+ memcpy(dst->Attribute, src->Attribute, src->numAttribute);
+
+ return TRUE;
+}
+
+
+Bool
+vgaHWGetHWRec(ScrnInfoPtr scrp)
+{
+ vgaRegPtr regp;
+ vgaHWPtr hwp;
+ int i;
+
+ /*
+ * Let's make sure that the private exists and allocate one.
+ */
+ vgaHWGetHWRecPrivate();
+ /*
+ * New privates are always set to NULL, so we can check if the allocation
+ * has already been done.
+ */
+ if (VGAHWPTR(scrp))
+ return TRUE;
+ hwp = VGAHWPTRLVAL(scrp) = xnfcalloc(sizeof(vgaHWRec), 1);
+ regp = &VGAHWPTR(scrp)->ModeReg;
+
+ if ((!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->SavedReg)) ||
+ (!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->ModeReg))) {
+ xfree(hwp);
+ return FALSE;
+ }
+
+ if (scrp->bitsPerPixel == 1) {
+ rgb blackColour = scrp->display->blackColour,
+ whiteColour = scrp->display->whiteColour;
+
+ /* Detect default for black & white */
+ if (!blackColour.red && !blackColour.green && !blackColour.blue &&
+ !whiteColour.red && !whiteColour.green && !whiteColour.blue)
+ whiteColour.red = whiteColour.green = whiteColour.blue = 0x3F;
+
+ /*
+ * initialize default colormap for monochrome
+ */
+ for (i=0; i<3; i++) regp->DAC[i] = 0x00;
+ for (i=3; i<768; i++) regp->DAC[i] = 0x3F;
+ i = BLACK_VALUE * 3;
+ regp->DAC[i++] = blackColour.red;
+ regp->DAC[i++] = blackColour.green;
+ regp->DAC[i] = blackColour.blue;
+ i = WHITE_VALUE * 3;
+ regp->DAC[i++] = whiteColour.red;
+ regp->DAC[i++] = whiteColour.green;
+ regp->DAC[i] = whiteColour.blue;
+ i = OVERSCAN_VALUE * 3;
+ regp->DAC[i++] = 0x00;
+ regp->DAC[i++] = 0x00;
+ regp->DAC[i] = 0x00;
+ } else {
+ /* Set all colours to black */
+ for (i=0; i<768; i++) regp->DAC[i] = 0x00;
+ /* ... and the overscan */
+ if (scrp->depth >= 4)
+ regp->Attribute[OVERSCAN] = 0xFF;
+ }
+ if (xf86FindOption(scrp->confScreen->options, "ShowOverscan")) {
+ xf86MarkOptionUsedByName(scrp->confScreen->options, "ShowOverscan");
+ xf86DrvMsg(scrp->scrnIndex, X_CONFIG, "Showing overscan area\n");
+ regp->DAC[765] = 0x3F;
+ regp->DAC[766] = 0x00;
+ regp->DAC[767] = 0x3F;
+ regp->Attribute[OVERSCAN] = 0xFF;
+ hwp->ShowOverscan = TRUE;
+ } else
+ hwp->ShowOverscan = FALSE;
+
+ hwp->paletteEnabled = FALSE;
+ hwp->cmapSaved = FALSE;
+ hwp->MapSize = 0;
+ hwp->pScrn = scrp;
+
+ /* Initialise the function pointers with the standard VGA versions */
+ vgaHWSetStdFuncs(hwp);
+
+ return TRUE;
+}
+
+
+void
+vgaHWFreeHWRec(ScrnInfoPtr scrp)
+{
+ if (vgaHWPrivateIndex >= 0) {
+ vgaHWPtr hwp = VGAHWPTR(scrp);
+
+ xfree(hwp->FontInfo1);
+ xfree(hwp->FontInfo2);
+ xfree(hwp->TextInfo);
+
+ vgaHWFreeRegs (&hwp->ModeReg);
+ vgaHWFreeRegs (&hwp->SavedReg);
+
+ xfree(hwp);
+ VGAHWPTRLVAL(scrp) = NULL;
+ }
+}
+
+
+Bool
+vgaHWMapMem(ScrnInfoPtr scrp)
+{
+ vgaHWPtr hwp = VGAHWPTR(scrp);
+ int scr_index = scrp->scrnIndex;
+
+ if (hwp->Base)
+ return TRUE;
+
+ /* If not set, initialise with the defaults */
+ if (hwp->MapSize == 0)
+ hwp->MapSize = VGA_DEFAULT_MEM_SIZE;
+ if (hwp->MapPhys == 0)
+ hwp->MapPhys = VGA_DEFAULT_PHYS_ADDR;
+
+ /* Map as VIDMEM_MMIO because WC is bad when there is page flipping */
+ hwp->Base = xf86MapVidMem(scr_index, VIDMEM_MMIO,
+ hwp->MapPhys, hwp->MapSize);
+ return hwp->Base != NULL;
+}
+
+
+void
+vgaHWUnmapMem(ScrnInfoPtr scrp)
+{
+ vgaHWPtr hwp = VGAHWPTR(scrp);
+ int scr_index = scrp->scrnIndex;
+
+ if (hwp->Base == NULL)
+ return;
+
+ xf86UnMapVidMem(scr_index, hwp->Base, hwp->MapSize);
+ hwp->Base = NULL;
+}
+
+int
+vgaHWGetIndex()
+{
+ return vgaHWPrivateIndex;
+}
+
+
+void
+vgaHWGetIOBase(vgaHWPtr hwp)
+{
+ hwp->IOBase = (hwp->readMiscOut(hwp) & 0x01) ?
+ VGA_IOBASE_COLOR : VGA_IOBASE_MONO;
+}
+
+
+void
+vgaHWLock(vgaHWPtr hwp)
+{
+ /* Protect CRTC[0-7] */
+ hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) & ~0x80);
+}
+
+void
+vgaHWUnlock(vgaHWPtr hwp)
+{
+ /* Unprotect CRTC[0-7] */
+ hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) | 0x80);
+}
+
+
+static void
+vgaHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
+ VisualPtr pVisual)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ int i, index;
+
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ hwp->writeDacWriteAddr(hwp, index);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].red);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].green);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].blue);
+ DACDelay(hwp);
+ }
+
+ /* This shouldn't be necessary, but we'll play safe. */
+ hwp->disablePalette(hwp);
+}
+
+
+static void
+vgaHWSetOverscan(ScrnInfoPtr pScrn, int overscan)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ if (overscan < 0 || overscan > 255)
+ return;
+
+ hwp->enablePalette(hwp);
+ hwp->writeAttr(hwp, OVERSCAN, overscan);
+
+#ifdef DEBUGOVERSCAN
+ {
+ int ov = hwp->readAttr(hwp, OVERSCAN);
+ int red, green, blue;
+
+ hwp->writeDacReadAddr(hwp, ov);
+ red = hwp->readDacData(hwp);
+ green = hwp->readDacData(hwp);
+ blue = hwp->readDacData(hwp);
+ ErrorF("Overscan index is 0x%02x, colours are #%02x%02x%02x\n",
+ ov, red, green, blue);
+ }
+#endif
+
+ hwp->disablePalette(hwp);
+}
+
+
+Bool
+vgaHWHandleColormaps(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if (pScrn->depth > 1 && pScrn->depth <= 8) {
+ return xf86HandleColormaps(pScreen, 1 << pScrn->depth,
+ pScrn->rgbBits, vgaHWLoadPalette,
+ pScrn->depth > 4 ? vgaHWSetOverscan : NULL,
+ CMAP_RELOAD_ON_MODE_SWITCH);
+ }
+ return TRUE;
+}
+
+/* ----------------------- DDC support ------------------------*/
+/*
+ * Adjust v_active, v_blank, v_sync, v_sync_end, v_blank_end, v_total
+ * to read out EDID at a faster rate. Allowed maximum is 25kHz with
+ * 20 usec v_sync active. Set positive v_sync polarity, turn off lightpen
+ * readback, enable access to cr00-cr07.
+ */
+
+/* vertical timings */
+#define DISPLAY_END 0x04
+#define BLANK_START DISPLAY_END
+#define SYNC_START BLANK_START
+#define SYNC_END 0x09
+#define BLANK_END SYNC_END
+#define V_TOTAL BLANK_END
+/* this function doesn't have to be reentrant for our purposes */
+struct _vgaDdcSave {
+ unsigned char cr03;
+ unsigned char cr06;
+ unsigned char cr07;
+ unsigned char cr09;
+ unsigned char cr10;
+ unsigned char cr11;
+ unsigned char cr12;
+ unsigned char cr15;
+ unsigned char cr16;
+ unsigned char msr;
+};
+
+void
+vgaHWddc1SetSpeed(ScrnInfoPtr pScrn, xf86ddcSpeed speed)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ unsigned char tmp;
+ struct _vgaDdcSave* save;
+ switch (speed) {
+ case DDC_FAST:
+
+ if (hwp->ddc != NULL) break;
+ hwp->ddc = xnfcalloc(sizeof(struct _vgaDdcSave),1);
+ save = (struct _vgaDdcSave *)hwp->ddc;
+ /* Lightpen register disable - allow access to cr10 & 11; just in case */
+ save->cr03 = hwp->readCrtc(hwp, 0x03);
+ hwp->writeCrtc(hwp,0x03,(save->cr03 |0x80));
+ save->cr12 = hwp->readCrtc(hwp, 0x12);
+ hwp->writeCrtc(hwp,0x12,DISPLAY_END);
+ save->cr15 = hwp->readCrtc(hwp, 0x15);
+ hwp->writeCrtc(hwp,0x15,BLANK_START);
+ save->cr10 = hwp->readCrtc(hwp, 0x10);
+ hwp->writeCrtc(hwp,0x10,SYNC_START);
+ save->cr11 = hwp->readCrtc(hwp, 0x11);
+ /* unprotect group 1 registers; just in case ...*/
+ hwp->writeCrtc(hwp,0x11,((save->cr11 & 0x70) | SYNC_END));
+ save->cr16 = hwp->readCrtc(hwp, 0x16);
+ hwp->writeCrtc(hwp,0x16,BLANK_END);
+ save->cr06 = hwp->readCrtc(hwp, 0x06);
+ hwp->writeCrtc(hwp,0x06,V_TOTAL);
+ /* all values have less than 8 bit - mask out 9th and 10th bits */
+ save->cr09 = hwp->readCrtc(hwp, 0x09);
+ hwp->writeCrtc(hwp,0x09,(save->cr09 &0xDF));
+ save->cr07 = hwp->readCrtc(hwp, 0x07);
+ hwp->writeCrtc(hwp,0x07,(save->cr07 &0x10));
+ /* vsync polarity negativ & ensure a 25MHz clock */
+ save->msr = hwp->readMiscOut(hwp);
+ hwp->writeMiscOut(hwp,((save->msr & 0xF3) | 0x80));
+ break;
+ case DDC_SLOW:
+ if (hwp->ddc == NULL) break;
+ save = (struct _vgaDdcSave *)hwp->ddc;
+ hwp->writeMiscOut(hwp,save->msr);
+ hwp->writeCrtc(hwp,0x07,save->cr07);
+ tmp = hwp->readCrtc(hwp, 0x09);
+ hwp->writeCrtc(hwp,0x09,((save->cr09 & 0x20) | (tmp & 0xDF)));
+ hwp->writeCrtc(hwp,0x06,save->cr06);
+ hwp->writeCrtc(hwp,0x16,save->cr16);
+ hwp->writeCrtc(hwp,0x11,save->cr11);
+ hwp->writeCrtc(hwp,0x10,save->cr10);
+ hwp->writeCrtc(hwp,0x15,save->cr15);
+ hwp->writeCrtc(hwp,0x12,save->cr12);
+ hwp->writeCrtc(hwp,0x03,save->cr03);
+ xfree(save);
+ hwp->ddc = NULL;
+ break;
+ default:
+ break;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/vgahw/vgaHW.h b/xc/programs/Xserver/hw/xfree86/vgahw/vgaHW.h
new file mode 100644
index 000000000..4908b30dd
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgahw/vgaHW.h
@@ -0,0 +1,221 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgahw/vgaHW.h,v 1.20 1999/08/21 13:48:42 dawes Exp $ */
+
+
+/*
+ * Copyright (c) 1997,1998 The XFree86 Project, Inc.
+ *
+ * Loosely based on code bearing the following copyright:
+ *
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * Author: Dirk Hohndel
+ */
+
+#ifndef _VGAHW_H
+#define _VGAHW_H
+
+#include "X.h"
+#include "misc.h"
+#include "input.h"
+#include "scrnintstr.h"
+#include "colormapst.h"
+
+#include "xf86str.h"
+
+#include "xf86DDC.h"
+
+#ifdef DPMSExtension
+#include "globals.h"
+#define DPMS_SERVER
+#include "extensions/dpms.h"
+#endif
+
+extern int vgaHWGetIndex(void);
+
+/*
+ * access macro
+ */
+#define VGAHWPTR(p) ((vgaHWPtr)((p)->privates[vgaHWGetIndex()].ptr))
+
+/* Standard VGA registers */
+#define VGA_ATTR_INDEX 0x3C0
+#define VGA_ATTR_DATA_W 0x3C0
+#define VGA_ATTR_DATA_R 0x3C1
+#define VGA_IN_STAT_0 0x3C2 /* read */
+#define VGA_MISC_OUT_W 0x3C2 /* write */
+#define VGA_ENABLE 0x3C3
+#define VGA_SEQ_INDEX 0x3C4
+#define VGA_SEQ_DATA 0x3C5
+#define VGA_DAC_MASK 0x3C6
+#define VGA_DAC_READ_ADDR 0x3C7
+#define VGA_DAC_WRITE_ADDR 0x3C8
+#define VGA_DAC_DATA 0x3C9
+#define VGA_FEATURE_R 0x3CA /* read */
+#define VGA_MISC_OUT_R 0x3CC /* read */
+#define VGA_GRAPH_INDEX 0x3CE
+#define VGA_GRAPH_DATA 0x3CF
+
+#define VGA_IOBASE_MONO 0x3B0
+#define VGA_IOBASE_COLOR 0x3D0
+
+#define VGA_CRTC_INDEX_OFFSET 0x04
+#define VGA_CRTC_DATA_OFFSET 0x05
+#define VGA_IN_STAT_1_OFFSET 0x0A /* read */
+#define VGA_FEATURE_W_OFFSET 0x0A /* write */
+
+/* default number of VGA registers stored internally */
+#define VGA_NUM_CRTC 25
+#define VGA_NUM_SEQ 5
+#define VGA_NUM_GFX 9
+#define VGA_NUM_ATTR 21
+
+/* Flags for vgaHWSave() and vgaHWRestore() */
+#define VGA_SR_MODE 0x01
+#define VGA_SR_FONTS 0x02
+#define VGA_SR_CMAP 0x04
+#define VGA_SR_ALL (VGA_SR_MODE | VGA_SR_FONTS | VGA_SR_CMAP)
+
+/* Defaults for the VGA memory window */
+#define VGA_DEFAULT_PHYS_ADDR 0xA0000
+#define VGA_DEFAULT_MEM_SIZE (64 * 1024)
+
+/*
+ * vgaRegRec contains settings of standard VGA registers.
+ */
+typedef struct {
+ unsigned char MiscOutReg; /* */
+ unsigned char *CRTC; /* Crtc Controller */
+ unsigned char *Sequencer; /* Video Sequencer */
+ unsigned char *Graphics; /* Video Graphics */
+ unsigned char *Attribute; /* Video Atribute */
+ unsigned char DAC[768]; /* Internal Colorlookuptable */
+ unsigned char numCRTC; /* number of CRTC registers, def=VGA_NUM_CRTC */
+ unsigned char numSequencer; /* number of seq registers, def=VGA_NUM_SEQ */
+ unsigned char numGraphics; /* number of gfx registers, def=VGA_NUM_GFX */
+ unsigned char numAttribute; /* number of attr registers, def=VGA_NUM_ATTR */
+} vgaRegRec, *vgaRegPtr;
+
+typedef struct _vgaHWRec *vgaHWPtr;
+
+typedef void (*vgaHWWriteIndexProcPtr)(vgaHWPtr hwp, CARD8 index, CARD8 value);
+typedef CARD8 (*vgaHWReadIndexProcPtr)(vgaHWPtr hwp, CARD8 index);
+typedef void (*vgaHWWriteProcPtr)(vgaHWPtr hwp, CARD8 value);
+typedef CARD8 (*vgaHWReadProcPtr)(vgaHWPtr hwp);
+typedef void (*vgaHWMiscProcPtr)(vgaHWPtr hwp);
+
+
+/*
+ * vgaHWRec contains per-screen information required by the vgahw module.
+ *
+ * Note, the palette referred to by the paletteEnabled, enablePalette and
+ * disablePalette is the 16-entry (+overscan) EGA-compatible palette accessed
+ * via the first 17 attribute registers and not the main 8-bit palette.
+ */
+typedef struct _vgaHWRec {
+ pointer Base; /* Address of "VGA" memory */
+ int MapSize; /* Size of "VGA" memory */
+ unsigned long MapPhys; /* phys location of VGA mem */
+ int IOBase; /* I/O Base address */
+ CARD8 * MMIOBase; /* Pointer to MMIO start */
+ int MMIOOffset; /* base + offset + vgareg
+ = mmioreg */
+ pointer FontInfo1; /* save area for fonts in
+ plane 2 */
+ pointer FontInfo2; /* save area for fonts in
+ plane 3 */
+ pointer TextInfo; /* save area for text */
+ vgaRegRec SavedReg; /* saved registers */
+ vgaRegRec ModeReg; /* register settings for
+ current mode */
+ Bool ShowOverscan;
+ Bool paletteEnabled;
+ Bool cmapSaved;
+ ScrnInfoPtr pScrn;
+ vgaHWWriteIndexProcPtr writeCrtc;
+ vgaHWReadIndexProcPtr readCrtc;
+ vgaHWWriteIndexProcPtr writeGr;
+ vgaHWReadIndexProcPtr readGr;
+ vgaHWReadProcPtr readST01;
+ vgaHWWriteIndexProcPtr writeAttr;
+ vgaHWReadIndexProcPtr readAttr;
+ vgaHWWriteIndexProcPtr writeSeq;
+ vgaHWReadIndexProcPtr readSeq;
+ vgaHWWriteProcPtr writeMiscOut;
+ vgaHWReadProcPtr readMiscOut;
+ vgaHWMiscProcPtr enablePalette;
+ vgaHWMiscProcPtr disablePalette;
+ vgaHWWriteProcPtr writeDacMask;
+ vgaHWReadProcPtr readDacMask;
+ vgaHWWriteProcPtr writeDacWriteAddr;
+ vgaHWWriteProcPtr writeDacReadAddr;
+ vgaHWWriteProcPtr writeDacData;
+ vgaHWReadProcPtr readDacData;
+ pointer ddc;
+} vgaHWRec;
+
+/* Some macros that VGA drivers can use in their ChipProbe() function */
+#define VGAHW_GET_IOBASE() ((inb(VGA_MISC_OUT_R) & 0x01) ? \
+ VGA_IOBASE_COLOR : VGA_IOBASE_MONO)
+
+#define VGAHW_UNLOCK(base) do { \
+ unsigned char tmp; \
+ outb((base) + VGA_CRTC_INDEX_OFFSET, 0x11); \
+ tmp = inb((base) + VGA_CRTC_DATA_OFFSET); \
+ outb((base) + VGA_CRTC_DATA_OFFSET, \
+ tmp | 0x80); \
+ } while (0)
+#define VGAHW_LOCK(base) do { \
+ unsigned char tmp; \
+ outb((base) + VGA_CRTC_INDEX_OFFSET, 0x11); \
+ tmp = inb((base) + VGA_CRTC_DATA_OFFSET); \
+ outb((base) + VGA_CRTC_DATA_OFFSET, \
+ tmp & ~0x80); \
+ } while (0)
+
+#define OVERSCAN 0x11 /* Index of OverScan register */
+
+#define BIT_PLANE 3 /* Which plane we write to in mono mode */
+#define BITS_PER_GUN 6
+#define COLORMAP_SIZE 256
+
+#define DACDelay(hw) \
+ do { \
+ unsigned char temp = inb((hw)->IOBase + VGA_IN_STAT_1_OFFSET); \
+ temp = inb((hw)->IOBase + VGA_IN_STAT_1_OFFSET); \
+ } while (0)
+
+/* Function Prototypes */
+
+/* vgaHW.c */
+
+void vgaHWSetStdFuncs(vgaHWPtr hwp);
+void vgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset);
+void vgaHWProtect(ScrnInfoPtr pScrn, Bool on);
+Bool vgaHWSaveScreen(ScreenPtr pScreen, Bool on);
+void vgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on);
+void vgaHWSeqReset(vgaHWPtr hwp, Bool start);
+void vgaHWRestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore);
+void vgaHWRestoreMode(ScrnInfoPtr scrninfp, vgaRegPtr restore);
+void vgaHWRestoreColormap(ScrnInfoPtr scrninfp, vgaRegPtr restore);
+void vgaHWRestore(ScrnInfoPtr scrninfp, vgaRegPtr restore, int flags);
+void vgaHWSaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save);
+void vgaHWSaveMode(ScrnInfoPtr scrninfp, vgaRegPtr save);
+void vgaHWSaveColormap(ScrnInfoPtr scrninfp, vgaRegPtr save);
+void vgaHWSave(ScrnInfoPtr scrninfp, vgaRegPtr save, int flags);
+Bool vgaHWInit(ScrnInfoPtr scrnp, DisplayModePtr mode);
+Bool vgaHWSetRegCounts(ScrnInfoPtr scrp, int numCRTC, int numSequencer,
+ int numGraphics, int numAttribute);
+Bool vgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src);
+Bool vgaHWGetHWRec(ScrnInfoPtr scrp);
+void vgaHWFreeHWRec(ScrnInfoPtr scrp);
+Bool vgaHWMapMem(ScrnInfoPtr scrp);
+void vgaHWUnmapMem(ScrnInfoPtr scrp);
+void vgaHWGetIOBase(vgaHWPtr hwp);
+void vgaHWLock(vgaHWPtr hwp);
+void vgaHWUnlock(vgaHWPtr hwp);
+void vgaHWDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
+Bool vgaHWHandleColormaps(ScreenPtr pScreen);
+void vgaHWddc1SetSpeed(ScrnInfoPtr pScrn, xf86ddcSpeed speed);
+
+#endif /* _VGAHW_H */
+
diff --git a/xc/programs/Xserver/hw/xfree86/vgahw/vgaHWmodule.c b/xc/programs/Xserver/hw/xfree86/vgahw/vgaHWmodule.c
new file mode 100644
index 000000000..409e7b511
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/vgahw/vgaHWmodule.c
@@ -0,0 +1,27 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vgahw/vgaHWmodule.c,v 1.6 1999/01/26 05:54:18 dawes Exp $ */
+
+/*
+ * Copyright 1998 by The XFree86 Project, Inc
+ */
+
+#ifdef XFree86LOADER
+
+#include "xf86Module.h"
+
+
+static XF86ModuleVersionInfo VersRec = {
+ "vgahw",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 0, 1, 0,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_NONE,
+ {0, 0, 0, 0}
+};
+
+XF86ModuleData vgahwModuleData = { &VersRec, NULL, NULL };
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/Imakefile b/xc/programs/Xserver/hw/xfree86/xaa/Imakefile
new file mode 100644
index 000000000..5d1a3c535
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/Imakefile
@@ -0,0 +1,64 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/xaa/Imakefile,v 3.37 1999/08/14 10:50:10 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#define IHaveSubdirs
+
+EXPSRCS = lsb_first/?*.c msb_first/?*.c lsb_fixed/?*.c msb_fixed/?*.c
+
+EXPOBJS = lsb_first/lsb_first.o msb_first/msb_first.o \
+ lsb_fixed/lsb_fixed.o msb_fixed/msb_fixed.o
+
+GENSRCS = xaaInit.c xaaGC.c xaaInitAccel.c xaaFallback.c xaaBitBlt.c \
+ xaaCpyArea.c xaaGCmisc.c xaaCpyWin.c xaaCpyPlane.c xaaFillRect.c \
+ xaaTEText.c xaaNonTEText.c xaaPCache.c xaaSpans.c xaaROP.c \
+ xaaImage.c xaaPaintWin.c xaaRect.c xaaLineMisc.c xaaBitOrder.c \
+ xaaFillPoly.c xaaWideLine.c xaaTables.c xaaFillArc.c xaaLine.c \
+ xaaSeg.c xaaDashLine.c xaaDashSeg.c xaaOverlay.c xaaOffscreen.c \
+ xaaOverlayDF.c
+
+GENOBJS = xaaInit.o xaaGC.o xaaInitAccel.o xaaFallback.o xaaBitBlt.o \
+ xaaCpyArea.o xaaGCmisc.o xaaCpyWin.o xaaCpyPlane.o xaaFillRect.o \
+ xaaTEText.o xaaNonTEText.o xaaPCache.o xaaSpans.o xaaROP.o \
+ xaaImage.o xaaPaintWin.o xaaRect.o xaaLineMisc.o xaaBitOrder.o \
+ xaaFillPoly.o xaaWideLine.o xaaTables.o xaaFillArc.o xaaLine.o \
+ xaaSeg.o xaaDashLine.o xaaDashSeg.o xaaOverlay.o xaaOffscreen.o \
+ xaaOverlayDF.o
+
+SRCS = $(GENSRCS)
+OBJS = $(GENOBJS)
+
+SUBDIRS = lsb_first msb_first lsb_fixed msb_fixed
+
+DONES = lsb_first/DONE msb_first/DONE lsb_fixed/DONE msb_fixed/DONE
+
+INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(EXTINCSRC) \
+ -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(FONTINCSRC)
+
+ModuleObjectRule()
+
+#if HasParallelMake
+MakeMutex($(SUBDIRS) $(EXPOBJS) $(DONES))
+#endif
+
+ObjectFromSpecialSource(xaaSeg, xaaLine, -DPOLYSEGMENT)
+ObjectFromSpecialSource(xaaDashSeg, xaaDashLine, -DPOLYSEGMENT)
+
+DepLibraryModuleTarget(xaa, $(OBJS) $(SUBDIRS) $(DONES), $(OBJS) $(EXPOBJS))
+
+InstallLibraryModule(xaa,$(MODULEDIR),.)
+
+DependTarget()
+
+
+ForceSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
+
+
+InstallDriverSDKLibraryModule(xaa,$(DRIVERSDKMODULEDIR),.)
+
+InstallDriverSDKNonExecFile(xaa.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(xaalocal.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(xaarop.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/Imakefile.EXP b/xc/programs/Xserver/hw/xfree86/xaa/Imakefile.EXP
new file mode 100644
index 000000000..a7ed03306
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/Imakefile.EXP
@@ -0,0 +1,40 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/xaa/Imakefile.EXP,v 1.5 1999/07/10 07:24:53 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+INCLUDES = -I.. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(XF86HWSRC) \
+ -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(FONTINCSRC)
+
+DEFINES = EXPDEFINES
+
+GENSRCS = xaaBitmap.c xaaTEGlyph.c xaaBitmap3.c xaaStipple.c
+GENOBJS = xaaBitmap.o xaaTEGlyph.o xaaBitmap3.o xaaStipple.o
+
+#if defined(i386Architecture) && defined(UseAssembler) && !MakeDllModules
+SRCS = $(GENSRCS) xaaTEGlyphBlt.S
+OBJS = $(GENOBJS) xaaTEGlyphBlt.o
+#else
+SRCS = $(GENSRCS)
+OBJS = $(GENOBJS)
+#endif
+
+ModuleObjectRule()
+SubdirLibraryRule($(OBJS))
+
+NormalRelocatableTarget(EXPOBJECTNAME, $(OBJS))
+NormalAsmObjectRule()
+
+LinkSourceFile(xaaBitmap.c, LinkDirectory)
+LinkSourceFile(xaaTEGlyph.c, LinkDirectory)
+LinkSourceFile(xaaNonTEGlyph.c, LinkDirectory)
+LinkSourceFile(xaaStipple.c, LinkDirectory)
+
+#if defined(i386Architecture) && defined(UseAssembler)
+LinkSourceFile(xaaTEGlyphBlt.S, LinkDirectory)
+#endif
+
+ObjectFromSpecialSource(xaaBitmap3, xaaBitmap, -DTRIPLE_BITS)
+
+DependTarget()
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/NOTES b/xc/programs/Xserver/hw/xfree86/xaa/NOTES
new file mode 100644
index 000000000..560a890ea
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/NOTES
@@ -0,0 +1,1904 @@
+
+This document describes the XAA (XFree86 Acceleration Architecture),
+which is the new acceleration interface for the SVGA server (but not
+limited to the SVGA server).
+
+This code is not at all dependent on the SVGA server, but does
+assume linear addressing at > 8bpp. It might be extendable to an
+mi-based set up for configurations that can't use cfb. There are
+still configurations around that need banked support for 16bpp.
+
+To use the new acceleration interface, write low-level functions
+like the sampledrv.c and ark_accel.c and call the ChipInitAccel()
+function before screen initialization (from FbInit in a SVGA
+driver, for example).
+
+You're welcome to comment, test, debug, or add to this code.
+
+Have fun...
+
+Harm Hanemaayer
+H.Hanemaayer@inter.nl.net
+
+Here's a list of known problems (roughly in order of importance). If you
+can confirm a problem using the lastest version, please do so.
+
+- I've seen crashes when using Netscape related to stipple functions.
+ These might be caused by the "fall-back" logic still getting it
+ wrong. It seems to be triggered by a call of
+ vga8256FillRectTransparentStippled32. Fixed by mod 186?
+
+- The "NonTE" text acceleration triggers core dumps (related to an invalid
+ fall-back function scheme in ValidateGC). It might also trigger lock-ups
+ (which would point towards a problem in NonTE text color expansion).
+ These functions are currently disabled.
+
+- Color expanded (monochrome) 8x8 pattern is may not be working correctly
+ yet in all cases (not fully tested).
+
+- The disabled non-terminal emulator font acceleration is suspect, I
+ don't think it handles horizontally overlapping characters correctly
+ (no visible evidence yet) in the xf86DrawNonTETextScanline function.
+ I don't know enough about the X font parameters to correctly
+ implement it.
+
+- The SCANLINE_PAD_BYTE and SCANLINE_NO_PAD text transfer code for CPU
+ to screen color expansion has not been fully tested, nor has the
+ FIXED_BASE support.
+
+- The pattern fill primitives are taken to have the same graphics operation
+ restrictions (planemask, rop etc) as ScreenToScreenCopy.
+
+- The support for TRIPLE_BITS_24BPP has improved, but it has not yet
+ been fully tested.
+
+- For color expansion implementation of stipples the graphics operation
+ restriction of color expansion are not honoured, but instead the
+ CopyArea ones are used. This is now sort-of fixed, but it has not been
+ tested in relevant cases.
+
+- Instead of not accelerating GXinvert operations that would normally
+ access the source, we could instead to a GXinvert FillRectSolid.
+
+When the server crashes, run 'gdb -c core XF86_SVGA' and print a
+back-trace ('backtrace').
+
+Change Log:
+
+218. As well as GXinvert, also avoid GXclear, GXnoop, and GXset.
+217. Don't accelerate functions that use source bitmap data (such as text,
+ stipples, bitmaps) when the raster-op is GXinvert.
+216. Truncate pixel values to pixel depth in ValidateGC.
+
+XFree86 3.2v
+215. Rotate monochrome patterns stored in video memory in opposite
+ direction (David Bateman). I doubt whether this is correct.
+214. Add FullPlanemask field to xf86AccelInfoRec, and use it for planemask
+ checks.
+213. Use GC alu instead of cfb reduced "rrop" when checking raster-op
+ restrictions.
+212. Add secondary restriction flag hack for stippled rectangles to
+ correctly handle different restrictions for pixmap cache and color
+ expansion stipple acceleration.
+211. Move macros for graphics operations restriction checks to from
+ xf86gcmisc.c to xf86local.h.
+210. Fix the check for server resets in xf86initac.c and xf86scrin.c (use
+ serverGeneration instead of xf86Resetting).
+
+XFree86 3.2u
+209. Fix monochrome pattern stored in video memory with PROGRAMMED_ORIGIN
+ and SCREEN_ORIGIN (Corin Anderson).
+
+XFree86 3.2s
+208. Respect CapStyle when using TwoPointLine for a non-clipped segment.
+207. Fix line clipping when hardware clipping is used with multiple
+ clipping regions (Xavier Ducoin).
+206. Add a hack to counter cfb cheating in PolyGlyphBlt when it does not
+ call ValidateGC when changing the foreground color to fill in the
+ background (affecting RGB_EQUAL).
+205. Remove left-over fall-back tile function setting code in xf86gcmisc.c
+ that may have caused problems.
+204. At ValidateGC time, take note of background color changes for
+ evaluation of RGB_EQUAL restrictions.
+203. Add support for a monochrome pattern with PROGRAMMED_BITS that
+ needs to be rotated in software, so that all possible monochrome
+ pattern variations are now supported.
+202. Add NO_TEXT_COLOR_EXPANSION flag.
+201. Fix bitmap (CopyPlane1ToN) color expansion acceleration at 24bpp with
+ TRIPLE_BITS_24BPP defined.
+200. Fix support for ScanlineScreenToScreenColorExpand with
+ TRIPLE_BITS_24BPP defined.
+199. Fix the case of a monochrome 8x8 pattern stored in video memory.
+ The code was not consistently assuming that the patternx
+ coordinate is in units of "bits" (David Bateman).
+198. Invalidate the pixmap cache when VT-switching back (suggested by
+ Andrew Vanderstock).
+197. If color expansion is used for stipples, say so in the start-up
+ messages.
+196. Indicate in start-up messages whether 8x8 pattern fill is actually
+ usable.
+195. Better RGB_EQUAL checks for text acceleration with TRIPLE_BITS_24BPP
+ (David Bateman).
+194. Do not accelerate lines with non-FillSolid fill style. Stippled lines
+ were rendered incorrectly as solid lines.
+
+XFree86 3.2r
+193. Check RGB_EQUAL for text acceleration with TRIPLE_BITS_24BPP
+ (David Bateman).
+192. Honour RGB_EQUAL when deciding CopyPlane1To24 acceleration in
+ xf86plane.c.
+191. Fix bugs in handling of left edge in CPU-to-screen color expansion
+ of bitmaps.
+190. When the server resets, don't execute the start-up benchmarks.
+189. When the server resets, don't execute the main part of the
+ xf86GCInfoRec and xf86AccelInfoRec initialization code, which
+ depends on default values for some fields.
+188. When there is any kind of accelerated stippled rectangle fill, also
+ use it for stippled spans.
+187. Add 10x10 CPU-to-screen color expansion benchmark.
+186. Remove left-over broken fall-back stipple function setting code
+ in xf86gcmisc.c, probably fixing crashes.
+185. Implement "no_pixmap_cache", and new "xaa_benchmark" and
+ "xaa_no_color_exp" server flags.
+184. Only print detailed messages when xf86Verbose is TRUE.
+183. Implement color expansion acceleration of stipple-filled rectangles
+ in xf86stip.c. Requires SCANLINE_PAD_DWORD for CPU-to-screen color
+ expansion, and does not support TRIPLE_BITS_24BPP.
+182. Fix SCANLINE_NO_PAD CPU-to-screen color expansion by not defining
+ the flag definition as zero (Koen Gadeyne).
+181. Add LEFT_EDGE_CLIPPING_NEGATIVE_X color expansion flag.
+180. Fix potential bug in handling of LEFT_EDGE_CLIPPING.
+179. Add new file xf86tables.c with byte expansion tables for
+ TRIPLE_BITS_24BPP.
+178. Support TRIPLE_BITS_24BPP for bitmap color expansion, with the
+ exception of non-DWORD scanline padding of CPU-to-screen color
+ expansion.
+177. Fix a probable bug in CPU-to-screen bitmap color expansion in
+ MSB-first mode without left edge clipping.
+176. When checking for hardware pattern usage for tiles, prefer the
+ color expand (monochrome) pattern.
+175. Improve TRIPLE_BITS_24BPP support with color expansion enabled for
+ text using screen-to-screen color color expansion or CPU-to-screen
+ with SCANLINE_PAD_DWORD.
+174. Add TRANSPARENCY_GXCOPY graphics operation flag, and take it into
+ consideration for ScreenToScreenCopy with transparency.
+
+XFree86 3.2q
+173. Fix infinite loop in CPU_TRANSFER_BASE_FIXED color expansion
+ (Xavier Ducoin).
+172. Fix color expansion benchmark when TRIPLE_BITS_24BPP is defined
+ (David Bateman).
+171. When using the monochrome pattern, use an existing cache entry when
+ the stipple is the same but the colors are different.
+170. Fix bugs in pattern handling code.
+169. Fix a bug in the MSB-first version of the Pentium-optimized text
+ bitmap transfer functions (David Bateman).
+168. Fully implement detection of tiles that only use two colors in order
+ to use a monochrome (color-expand) hardware pattern.
+167. Potentially fix the case of rotated monochrome patterns stored video
+ memory.
+166. Change start-up messages a little.
+165. Add support for 8x8 hardware pattern with SCREEN_ORIGIN in addition
+ to PROGRAMMED_ORIGIN, and take into account the bit order when
+ PROGRAMMED_BITS is defined (Radek).
+164. Mark pixmaps that are found to be unsuitable for caching.
+163. Make caching of transparent stipples possible for chips that don't
+ have ScreenToScreenCopy with transparency but do have a color-expand
+ pattern fill that supports transparency.
+162. Add low-level benchmarks for 10x10 pattern fill.
+161. Use 64-bit access on DEC alpha in CPU-to-framebuffer bandwidth
+ benchmark.
+160. Add the HARDWARE_PATTERN_MONO_TRANSPARENCY flag to further
+ differentiate between mono pattern and regular color expansion.
+159. Use depth instead of bitsperpixel in planemask check for line
+ rectangles.
+158. Reorganize the "cfbGetLongWidthAndPointer" function.
+157. Support the HARDWARE_PATTERN_PROGRAMMED_ORIGIN for non-color
+ expanded patterns (including patterns that must be aligned on a 64
+ pixel boundary) and for color-expanded patterns that are stored
+ in video memory.
+156. Various fixes for the cfb8 (non-vga256) support.
+155. At start-up, display a message when no acceleration primitives
+ are defined.
+154. Add ScratchBufferBase field to support scanline screen-to-screen
+ color expansion without a linear framebuffer.
+153. Support multiple buffers for scanline screen-to-screen color
+ expansion. Adds the PingPongBuffers field.
+
+XFree86 3.2n
+152. Add HARDWARE_PATTERN_BIT_ORDER_MSBFIRST flag to differentiate between
+ mono hardware pattern and regular color expansion.
+151. Fix missing fields in xf86defs.c.
+150. Delay the actual initialization of the pixmap cache until general XAA
+ initialization. A server InfoRec field and pixmap cache memory boundary
+ fields are added to the xf86AccelInfoRec. This also eliminates the
+ dependency of the XAA code on vga256 (the SVGA server).
+149. Lift the SCANLINE_PAD_DWORD requirement in xf86initac.c for the
+ enabling of text color expansion.
+148. Add functions in xf86expblt.c for whole text bitmap transfer in the
+ case of BYTE padding or no padding at the end of scanlines, and
+ support this in xf86text.c.
+147. Add a cfb8-based layer to support stand-alone servers not using
+ vga256.
+146. Enable fixed-base CPU-to-screen color-expansion for bitmap and TE text.
+145. Add FIXEDBASE support to color expansion functions in xf86expblt.c.
+144. Add the HARDWARE_PATTERN_PROGRAMMED_BITS and HARDWARE_PATTERN_
+ PROGRAMMED_ORIGIN flags, and implement 8x8 mono pattern code
+ used when both flags are set.
+143. Don't use scanline-byte-padded CPU to screen color expansion since
+ it doesn't work.
+142. Use MSB-first versions of Pentium-optimized text transfer functions
+ when required.
+141. Finally fix the flawed fall-back function schemes, potentially fixing
+ crashes associated with some span and rectangle fills. Still not stable.
+140. More heavily unroll the CPU to framebuffer benchmark code (mainly
+ for the Cyrix 6x86).
+
+XFree86 3.2g
+139. Enable 24bpp CopyPlane acceleration (Dirk).
+
+Version of 17 December 1996 (XFree86 3.2f)
+138. Enable the Pentium-optimized text transfer functions for 6 and 8-pixel
+ wide fonts.
+137. Fix a problem with accelerated horizontal and vertical lines clashing
+ with framebuffer lines.
+136. In some places, fix the "NO_PLANEMASK" check to only check bits up to
+ the actual depth (rather than PMSK).
+135. Avoid recursive xf86miFillRectStippledFallBack call.
+134. When the new HARDWARE_PATTERN_MOD_64_OFFSET flag is set, do use
+ the hardware pattern when the framebuffer width guarantees
+ corrects alignment.
+133. Avoid unaligned accesses in xf86expblt.c for DEC Alpha. Not tested.
+ What's a mem_barrier? Do we need them?
+132. Do not use 8x8 pattern stipple fill at 24bpp because there's no
+ pixmap-to-pixmap CopyPlane1ToN primitive.
+131. Allow CopyPlane1ToN to be accelerated at 24bpp.
+130. Remove messages printed when xf86miStippleFallBack is called.
+129. Add FillRectSolid graphics operation restriction flags to the line
+ draw restrictions in xf86initac.c, fixing a problem with planemask
+ restrictions not being honoured for some lines.
+128. Add some Pentium-optimized text bitmap transfer functions in
+ xf86txtblt.s, but they are not used yet.
+
+XFree86 3.2e
+127. ImakefileBPP renamed to Imakefile.BPP
+
+Version 0.4f (XFree86 3.2d) (28 November 1996)
+126. Fix typo in xf86frect.c, pixmap-cache re-enabled (Alan).
+125. Disable Non-TE text acceleration.
+124. Add text fall-back functions in xf86gcmisc.c.
+123. Fix ImakefileBPP.
+
+Version 0.4e (XFree86 3.2c) (24 November 1996)
+122. Fix some problems with drawing of Non-TE of text strings.
+121. Fix compilation problem in xf86spans.c (Takaaki Nomura).
+120. Add sanity checks in PolyFillRect and FillSpans for <= 0 specified
+ rects or spans.
+119. Make sure the cfb fall-back text functions are initialized correctly.
+ This problem showed up when non-TE text acceleration was added.
+118. Add the TWO_POINT_LINE_ERROR_TERM flag, but don't implement it yet.
+117. Implement a stipple bitmap scanline function in xf86expblt.c for
+ future use in color expansion stipple acceleration.
+116. Implement color expansion text acceleration for non-terminal emulator
+ fonts. Fix non-TE text scanline function in xf86expblt.c.
+115. Add NO_SYNC_AFTER_CPU_COLOR_EXPAND flag.
+114. When cfb MatchCommon is succesful in ValidateGC, make sure the
+ devPrivate.val is still correct. Fixes memory leak.
+113. Fix bug in xf86PolyFillRect. This does not fix the pixmap cache.
+
+Version 0.4d (XFree86 3.2a) (18 November 1996)
+112. Prepare for integration into source tree (hw/xfree86/xaa/*).
+111. Move the declaration of xf86PixmapIndex into xf86initac.c.
+110. Screeninit functions renamed; vgabpp.h renamed to xf86scrin.h.
+109. Cosmetic changes in preparation for integration into source tree.
+108. Rename xf86gc.h to xf86xaa.h, and modify some long filenames.
+107. In ValidateGC, correctly handle the case of the drawable of an
+ on-screen GC being changed to a pixmap.
+106. Fix a problem with byte-padded CPU to screen color expansion in
+ xf86bitmap.c.
+105. Initialize CPUToScreenColorExpandRange to default value of 64K
+ if it is not defined.
+104. Fix missing cfb stipple function mappings in vga256map.h.
+
+Version 0.4c (15 November 1996)
+103. Really fix the CPU-to-screen color expansion benchmark.
+102. Disable the accidently enabled debugging on-screen pixmap cache.
+
+Version 0.4b (15 November 1996)
+101. Add the UsingVGA256 flag to the xf86AccelInfoRec, and use this
+ to adjust the address pointer for low-level line fall-backs for
+ vga256 so that the non-bank checking versions will be used when
+ linear addressing is enabled (implemented in cfb8GetLongWidthAndPointer
+ in xf86im.c).
+100. Add general line acceleration for chips that can only accelerate
+ horizontal/vertical lines using FillRectSolid and for chips that
+ only have TwoPointLine without fool-proof hardware clipping.
+ 99. Fix crash with line rectangles when the raster-op is not GXcopy.
+ 98. Change the 8x8 pattern benchmark a little.
+ 97. Add an aligned screen copy (scroll) test to the low-level benchmarks,
+ and remove the transparent color expansion tests.
+ 96. Fix related type warnings in xf86bitmap.c (Radek).
+ 95. Really fix the initialization of CPUToScreenColorExpandEndMarker
+ (Radek).
+ 94. Fix the initialization of CPUToScreenColorExpandEndMarker in
+ xf86initacl.c
+ 93. Fix problems with small patterns when using 8x8 hardware pattern fill.
+ 92. Fix for CopyPlane1to32 (resolves olvwm crash at 32bpp).
+ 91. Fix the CPU to screen color expansion benchmark (Radek).
+ 90. Use the accelerated FillPolygonSolid from the GCInfoRec in ValidateGC.
+ 89. In xf86orect.c, use cfbGCGetPrivate().
+ 88. Add monochrome 8x8 tile detection (not used yet).
+ 87. Fix external byte_reversed declaration in xf86expblt.c and
+ xf86pcache.c (fixes problem with 8x8 color expanded pattern).
+ 86. Fix xf86expblt.c inline asm for different OSs (Takaaki Nomura).
+ 85. Support xf86bench.c on different OSs (Akio Morita).
+ 84. Fix a bug in the color expanded 8x8 pattern code.
+ 83. In ReduceTileToSize8, don't give up when not using 8bpp.
+ 82. Cosmetic changes to sampledrv.c.
+ 81. Improve the start-up messages.
+ 80. In the benchmark routines, avoid memset().
+ 79. Lift the LSBFIRST requirement for buffered screen-to-screen color
+ expansion.
+
+Version 0.4a (7 November 1996)
+ 78. Correct xf86AccelInfoRec.BitsPerPixel for 24bpp.
+ 77. Add ONLY_LEFT_TO_RIGHT_BITBLT for chips that only support screen-to-
+ screen BitBLTs with xdir = 1, and support this in CopyArea.
+ 76. Make decisions in InitAccel about whether specified CPU-to-screen
+ color expansion memory range is large enough.
+ 75. Add FramebufferWidth (equivalent to infoRec.displayWidth).
+ 74. Add CPUToScreenColorExpandRange, which is taken into account after
+ each scanline in text and bitmap color-expansion operations
+ (CPUToScreenColorExpandEndMarker is derived from it).
+ 73. Only allow text CPU-to-screen color expansion with SCANLINE_PAD_DWORD
+ defined.
+ 72. If the CPUToScreenColorExpandBase isn't initialized, use the
+ start of the framebuffer as color expansion base address.
+ 71. Fix bug in DrawNonTETextScanline (a function not yet used).
+ 70. Add ONLY_TWO_BITBLT_DIRECTIONS for chips that only support screen-to-
+ screen BitBLTs with xdir = ydir, and support this in CopyArea.
+ 69. Add VIDEO_SOURCE_GRANULARITY_DWORD flag for color expansion.
+ 68. Fix cfbPushPixels8 name mapping for vga256. This was probably causing
+ most of the stability problems.
+
+Version 0.4 (5 November 1996)
+ 67. Add support for color-expanded 8x8 hardware patterns (untested).
+ 66. Fix a bug in FillSpansSolid that caused some spans to be drawn
+ at the wrong position (Radek).
+ 65. In FillSpansSolid, correctly handle the case of no spans remaining
+ after clipping.
+ 64. When doing the raster-op precomputations for cfb in ValidateGC,
+ don't clear the flag indicating that the raster-op has changed
+ since we must still evaluate accelerated functions.
+ 63. Correctly modify devPrivate.val when new GC ops are created in
+ ValidateGC.
+ 62. Reduce tiles to 8x8 pixels if possible.
+ 61. Set the USE_TWO_POINT_LINE flag if appropriate.
+ 60. Reduce stipples to 8x8 pixels if possible.
+ 59. Add start-up benchmark timings for low-level primitives.
+ 58. Reduce stipples and tiles to 8 pixels wide if possible in order to
+ use the 8x8 hardware pattern.
+ 57. Add 8x8 hardware pattern stipples.
+ 56. Provide a mechanism to call non-accelerated CopyPlane1toN
+ directly. Adds CopyPlane1toNFallBack to GCInfoRec.
+ 55. Add the HARDWARE_PATTERN_ALIGN_64 flag (not supported yet).
+ 54. Debug the 8x8 hardware pattern.
+ 53. Guarantee a different transparency color instead of using the GC
+ background color when caching transparent stipples.
+ 52. Add support for 8x8 hardware patterns, and use them for small
+ tiles.
+ 51. Add BitsPerPixel to xf86AccelInfoRec.
+ 50. Assign fall-back function to xf86AccelInfoRec.ImageWrite if
+ necessary for convenience.
+ 49. Lift the VIDEO_SOURCE_GRANULARITY_PIXEL requirement for indirect
+ screen-to-screen text color expansion.
+ 48. Add an extra set of wide slots to the pixmap cache. Disabled.
+ 47. Honour ONE_RECT_CLIPPING flag when checking line drawing function.
+ 46. Support WriteBitmap when only non-transparent color expansion is
+ supported.
+
+Version 0.3b (31 October 1996)
+ 45. Update vga256 patch (vga.c) to force GC validation after a VT-switch.
+ 44. Support ImageText when only transparent color expansion is supported.
+ 43. Add PolyText color expansion for TE fonts.
+ 42. Use devPrivate.val to signal status of GC ops, and use this to
+ modify them when required.
+ 41. Create new GC ops when GC ops are still pointing to a defaults
+ structure when modifying GC ops in ValidateGC.
+ 40. As a stop-gap measure, reset all GC ops and pretend everything in
+ the GC has changed when a switch-away is detected in ValidateGC.
+ 39. Update sampledrv.c.
+ 38. Disable the pixmap cache if the memory range is wrongly specified
+ (Alan).
+ 37. Fix typo in pixmap cache initialization in sampledrv.c.
+ 36. Make xf86PolyRectangle use new line drawing functions for vertical
+ lines.
+ 35. Add ErrorTermBits to the xf86AccelInfoRec for re-scaling Bresenham
+ error terms when software clipping is used.
+ 34. Add flags to indicate whether PolySegment is supported with CapNotLast
+ using TwoPointLine.
+ 33. Implement xf86PolyLine/Segment using BresenhamLine or TwoPointLine
+ (untested).
+ 32. Add BresenhamLine and TwoPointLine primitives.
+ 32. Fix initial coordinates for color-expanded text.
+ 31. Move function prototypes from xf86gc.h to xf86local.h.
+ 30. Take into account source offset into first byte of bitmap scanline.
+ 29. Bitmap with buffered screen-to-screen color expansion now works.
+ 28. Fix prototypes for intermediate-level text functions.
+ 27. Fix source overrun problems in xf86DrawBitmapScanline.
+ 26. Intialize FramebufferBase in ScreenInit.
+ 25. Implement untested/unused functions for filling 24bpp pixels using
+ 8bpp mode color expansion in two passes.
+ 24. Fix color expand flag testing in xf86bitmap.c.
+
+Version 0.3a (28 October 1996)
+ 23. If tiles are cached but not stipples (but stipples are accelerated),
+ be aware of this in xf86PolyFillRect.
+ 22. Disable updating of the PolyGlyphBlt GC op in ValidateGC because of an
+ unresolved problem showing up at > 8bpp.
+ 21. Implement a better understanding of how GC changes affect the selection
+ of cfb and accelerated functions in ValidateGC.
+ 20. Fix the way ValidateGC handles cfb operations initialized with
+ MatchCommon.
+ 19. Add xf86mapfuncs.h for local functions that are depth-mapped.
+ 18. Fix bugs accidently introduced into xf86initacl.c in version 0.3,
+ which effectively disabled pixmap caching.
+ 17. Add untested, unoptimized CopyPlane1to24 (GXcopy, no planemask),
+ for use with stipple caching. Doesn't work yet.
+
+Version 0.3 (27 October 1996)
+ 16. Use framebuffer function for some vertical lines in PolyRectangle.
+ 15. Fix SaveAreas and RestoreAreas for vga256.
+ 14. Add PolyLine and PolySegment hooks to the xf86GCInfoRec.
+ 13. Fix missing cfbPolyFillArc mappings in vga256map.h.
+ 12. Fix MatchCommon call in ValidateGC. This fixes vga256 operation.
+ 11. Fix updating of GC ops for text functions during ValidateGC.
+ 10. Optimize the CopyPlane1to16/32 functions.
+ 9. Update the docs, and include a sample driver template.
+
+Version 0.2 (26 October 1996)
+ 8. Re-enable CopyPlane hook.
+ 7. Fix typo that prevented CopyArea from being accelerated.
+ 6. Fix confusion over arguments of cfbBitBlt helper function.
+ 5. Call the correct depth-specific cfbBitBlt helper function.
+ 4. Fix the coordinates for the transparent stipple mi fall-back.
+ 3. Fix problem with zero-width spans in FillSpansAsRects.
+ 2. Disable CopyPlane hook because it doesn't work.
+
+Version 0.1 (25 October 1996)
+ 1. First logged version. Implements solid filled rectangles, arcs,
+ polygons, CopyArea, pixmap caching.
+ Untested are line-drawn rectangles, color expansion text, color
+ expansion stipple upload, bitmaps.
+
+
+Overview of XAA
+---------------
+
+1.1
+
+Some advantages of this new interface:
+
+- Easier implementation of accelerated functions.
+- More efficient use of accelerated functions.
+- Code size reduction.
+- Source code size reduction (less duplicated code).
+- Greater test base for higher level code.
+- Improvements can be beneficial for all drivers.
+
+Disadvantages:
+
+- More overhead in ValidateGC.
+- Arguably more complex set of acceleration primitives.
+
+
+1.2 Graphics Operation Flags
+
+GXCOPY_ONLY
+
+ Indicates that the graphics operation only allows a GXcopy
+ raster-op (copy source). If this flag is not defined, the graphics
+ operation is assumed to be supported with all 16 raster operations.
+
+NO_PLANEMASK
+
+ Indicates that the graphics operation does not allow a write
+ planemask. All bits in a pixel are written.
+
+ONE_RECT_CLIPPING
+
+ Indicates that an accelerated function (usually a high-level one that
+ handles clipping) only accepts one clipping rectangle. This may be
+ of use for line drawing. [It is only checked for line drawing]
+
+RGB_EQUAL
+
+ Indicates that the graphics operation requires that the red, green,
+ and blue bytes of the foreground color (and background color, if
+ applicable) are equal. This is useful for 24bpp when the graphics
+ coprocessor is used in 8bpp mode, which is the often the case since
+ most chips have no or only limited support for acceleration at
+ 24bpp. This way, many operations will be accelerated for the common
+ case of "grayscale" colors. It should only be defined for 24bpp.
+
+NO_TRANSPARENCY
+
+ Indicates that the graphics operation does not handle transparency.
+ This can be enabled for screen-to-screen copy.
+
+NO_CAP_NOT_LAST
+
+ Indicates that the graphics operation (PolyLine or PolySegment) does
+ not support not drawing of the last pixel.
+
+TRANSPARENCY_GXCOPY
+
+ Indicates that, unlike the case of no transparency, when
+ transparency is enabled only the GXcopy raster-op is allowed. This
+ is valid only for ScreenToScreenCopy.
+
+
+1.3 The AccelInfoRec
+
+Flags
+
+ This is a set of flags that controls some overall parameters for
+ the acceleration code.
+
+ BACKGROUND_OPERATIONS
+
+ If enabled, the "simple" acceleration functions are not assumed to
+ wait until the graphic coprocessor operation is finished. The
+ generic acceleration functions will call Sync() when all operations
+ have been done.
+
+ DELAYED_SYNC
+
+ If enabled, the acceleration functions will try to use as much
+ parallellism between the CPU and the accelerator as possible by
+ postponing calls to Sync() as much as possible. Without this flag, and
+ with BACKGROUND_OPERATIONS enabled, the acceleration functions will call
+ Sync() after each major set of acelerated operations. With DELAYED_SYNC
+ set, Sync() will only be called when absolutely necessary to maintain
+ framebuffer consistency. In practice, this means Sync() will only be
+ called just before writing to or reading from the framebuffer with the
+ CPU. This option increases performance, but is much more vulnerable to
+ display errors and synchronisation problems.
+
+ PIXMAP_CACHE
+
+ Use a pixmap cache for tiles and stipples, when the required
+ low-level functions (such as ScreenToScreenCopy) are available.
+
+ COP_FRAMEBUFFER_CONCURRENCY
+
+ CPU access to the framebuffer can continue while a screen-to-screen
+ coprocessor operation is being executed. This is taken advantage of
+ in some color expansion routines when CPU-to-screen color expansion
+ is not available, and potentially in some other places.
+
+ DO_NOT_CACHE_STIPPLES
+
+ Do not cache stipples, but instead use the CPU-to-screen color
+ expansion routines for stipples. These routines have not yet been
+ implemented.
+
+ HARDWARE_CLIP_LINE
+
+ When a general line has to be clipped, use hardware clipping
+ (SetClippingRectangle must be defined, and clipping must only
+ be active for the single following general line draw).
+
+ USE_TWO_POINT_LINE
+
+ Use two-point lines (TwoPointLine) instead of Bresenham lines for
+ general lines. This flag is automatically set if appropriate. It
+ must be set in a driver.
+
+ HORIZONTAL_TWOPOINTLINE
+
+ Use TwoPointLine for Horizontal Lines instead of the FillRectSolid
+ function.
+
+ TWO_POINT_LINE_NOT_LAST
+
+ Indicates that TwoPointLine supports the notlast flag that indicates
+ whether the last pixel should be drawn. If this is not supported,
+ PolyLine and PolySegment cannot support the CapNotLast CapStyle.
+
+ TWO_POINT_LINE_ERROR_TERM
+
+ Indicates that TwoPointLine supports the optional error term flag
+ and parameter that allows the initial error term to be provided
+ for software clipped lines.
+
+ ONLY_TWO_BITBLT_DIRECTIONS
+
+ Indicates that ScreenToScreenCopy is only allowed with xdir = ydir
+ (both -1 or both 1). BitBLTs are converted to smaller BitBLTs with
+ supported directions if necessary.
+
+ ONLY_LEFT_TO_RIGHT_BITBLT
+
+ Indicates that ScreenToScreenCopy is only allowed with xdir = 1.
+ BitBLTs are converted to smaller BitBLTs with supported directions
+ if necessary.
+
+ NO_SYNC_AFTER_CPU_COLOR_EXPAND
+
+ Indicates that a Sync() is not required after a CPU-to-screen color
+ expansion operation. Generally, this can be defined if host color
+ expansion data is processed by the graphics chip in the same way as
+ accelerated graphics commands (it uses the command FIFO).
+
+ NO_TEXT_COLOR_EXPANSION
+
+ Do not use color expansion to accelerate text. Define this if
+ color expansion is slower than plain framebuffer for text (which
+ might happen with scanline screen-to-screen color expansion,
+ when there is little video memory bandwidth but the CPU to
+ framebuffer bandwidth is decent).
+
+ LINE_PATTERN_POWER_OF_2_ONLY
+
+ Indicates that hardware dashed lines only support pattern lengths
+ that are a power of two.
+
+ LINE_PATTERN_ONLY_TRANSPARENCY
+
+ Indicates that the hardware dashed lines only support the foreground
+ colors.
+
+ LINE_PATTERN_MSBFIRST_INCREASING
+ LINE_PATTERN_MSBFIRST_DECREASING
+
+ Indicates that the dashed line pattern stored in the LinePatternBuffer
+ progresses from MSB to LSB within each DWORD. INCREASING patterns
+ are stored with the beginning of the pattern in the first DWORD of
+ the LinePatternBuffer, while DECREASING indicates that the end of the
+ pattern is in the first DWORD in the LinePatternBuffer. INCREASING or
+ DECREASING is only relevant if the pattern is longer than a DWORD.
+
+PatternFlags
+
+ This is a set of flags that controls some overall parameters for
+ the acceleration code related to the hardware pattern.
+
+ HARDWARE_PATTERN_SCREEN_ORIGIN
+
+ Indicates that the baseline origin for hardware 8x8 pattern fills
+ is the top left corner of the screen, as opposed to the top left
+ corner of the area to be filled. Note that an origin offset feature
+ might still be supported.
+
+ HARDWARE_PATTERN_TRANSPARENCY
+
+ Indicates that the hardware 8x8 pattern fill supports transparency
+ color compare (does not apply to mono pattern).
+
+ HARDWARE_PATTERN_ALIGN_64
+
+ Indicates that the 8x8 hardware pattern must be stored on a
+ 64-pixel boundary in video memory, and programmed pattern start
+ location must be the start of such a pattern. In the absence of a
+ programmable origin, this requires a lot more pre-rotated copies to
+ be made, although they should still fit within a 128x128 cache
+ area.
+
+ HARDWARE_PATTERN_MOD_64_OFFSET
+
+ Indicates that while the 8x8 hardware pattern must be stored
+ aligned on a 64-pixel boundary, the programmed pattern start
+ location can in fact include a multiple-of-8-pixels offset, which
+ indicates the vertical offset into the pattern. This flag is
+ mutually exclusive to HARDWARE_PATTERN_ALIGN_64. If you can also
+ specify the horizontal offset, do not use this flag, but instead
+ use HARDWARE_PATTERN_PROGRAMMED_ORIGIN.
+
+ HARDWARE_PATTERN_PROGRAMMED_BITS
+
+ Indicates that the monochrome (color expand) 8x8 pattern data must be
+ programmed into registers, rather than stored in video memory. This
+ is only supported in combination with the following flag.
+
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN
+
+ Indicates that the hardware pattern supports a programmable origin
+ (x and y offsets into the pattern). This is supported for all three
+ pattern storage types (programmed monochrome, monochrome in video
+ memory and regular (pixel depth) in video memory).
+
+ HARDWARE_PATTERN_BIT_ORDER_MSBFIRST
+
+ Indicates that the monochrome 8x8 pattern data is in MSB-first bit
+ order ("Windows-style").
+
+ HARDWARE_PATTERN_MONO_TRANSPARENCY
+
+ Indicates that the monochrome 8x8 pattern supports transparency
+ (signalled by a background color equal to -1).
+
+ HARDWARE_PATTERN_NOT_LINEAR
+
+ Indicates that the 8x8 pattern data should not be stored linearly
+ in video memory, but rather, as a tiled 8x8 pattern in the cache.
+
+ HARDWARE_PATTERN_NO_PLANEMASK
+
+ Indicates that the 8x8 pattern doesn't support a write planemask.
+ All bits in a pixel must be written.
+
+Sync()
+
+ This function should be defined if BACKGROUND_OPERATIONS is enabled
+ (and also if any kind of CPU-to-screen color expansion is used). It
+ should wait for all graphics coprocessor operations to finish. It
+ also provides an opportunity to clean up the coprocessor state
+ after a batch for commands.
+
+SetupForFillRectSolid(color, rop, planemask)
+
+ Sets up the color, raster-op and planemask for a solid rectangle
+ fill. It is called once before a batch of "Subsequent" fill
+ commands. Currently the restrictions for the operation are set up
+ with xf86GCInfoRec.PolyFillRectSolidFlags.
+
+ Another acceleration commmand might still be executing when a SetUp
+ function is called (assuming BACKGROUND_OPERATIONS). You may have
+ to do a Sync() here. In the current XAA code this doesn't happen,
+ but it might in the future.
+
+SubsequentFillRectSolid(x, y, w, h)
+
+ This actually fills a rectangle. When writing spans, h will
+ be 1. It is usually called many times in a row.
+
+ A key thing to notice here is that the function call overhead
+ is "eaten" when performing coprocessor operations "in the
+ background" (concurrently with CPU processing). If you need to
+ wait for the previous operation to finish before sending the
+ commands for the next one, you can do that in this function.
+ Generally, you want to avoid querying the chip as much as
+ possible since PCI read operations have a devastating effect
+ on performance.
+
+ This function is taken advantage of when filling solid rectangles,
+ spans, polygons and arcs, and in other places.
+
+SubsequentFillTrapezoidSolid(y, h, left, dxl, dyl, el, right, dxr, dyr, er)
+
+ Defining this will enable most solid polygons to be rendered as a
+ collection of trapezoids rather than horizontal spans. Y is the
+ top line of a trapezoid which has height h. Left and right are the
+ starting X positions of the left and right edges on the top line.
+ Dyl/dxl and dyr/dxr define the slopes of the left and right edges
+ and el and er are the initial error terms (always rendered from
+ top of the screen to the bottom).
+
+ Note that dyl, dxl, dyr and dxr are merely used to define the slope
+ of the line and are not necessarily the deltas between the top and
+ bottom points.
+
+SetupForScreenToScreenCopy(xdir, ydir, rop, planemask, transparency_color)
+
+ Set up for a screen-to-screen BitBLT. The transparency color is -1
+ when there is no transparency. Transparency is used when drawing
+ transparent stipples from the pixmap cache. There are general flags
+ (set in xf86AccelInfoRec.Flags) to indicate restrictions for the
+ direction of the BitBLT (xdir, ydir); if restrictions exist, the
+ generic code converts the blits to allowable blits. Currently the
+ other restrictions for the operation are set up with
+ xf86GCInfoRec.CopyAreaFlags.
+
+SubsequentScreenToScreenCopy(x1, y1, x2, y2, w, h)
+
+ Perform a screen-to-screen BitBLT. Again often there is
+ a batch of commands. Note that (x1, y1) is always the top-left
+ corner, regardless of the direction.
+
+ It is used for screen-to-screen area copies (such as scrolling),
+ and for the pixmap cache.
+
+SubsequentBresenhamLine(x1, y1, octant, err, e1, e2, length)
+
+ Draw a line using the Bresenham algorithm. This is the most common
+ general line drawing feature that chips support. The octant consists
+ of bitflags that are defined as follows (miline.h defines them):
+
+ XDECREASING 4 Draw from right to left (a.o.t. right to left).
+ YDECREASING 2 Draw from bottom to top (top to bottom).
+ YMAJOR 1 Y is the major axis (X is the major axis).
+
+ The error terms are usually no bigger than a screen coordinate, but
+ when software clipping is used, the error time might be too big; it
+ is then rescaled according to the number of bits specified in
+ ErrorTermBits. When HARDWARE_CLIP_LINE is defined,
+ SetClippingRectangle must be defined. It seems to me that hardware
+ clipping makes the implicit assumption that the chip can handle
+ coordinates in the range [-37268, 32767]. Or are coordinates
+ guaranteed to be on-screen? Anyway I think having the chip trace
+ lines way off the screen does not sound like a good idea.
+
+ There is no SetUp function. SetupForFillRectSolid is called before
+ a batch of lines (this linked to the fact that horizontal lines
+ are drawn with FillRectSolid; they should not be affected by
+ hardware clipping).
+
+SubsequentTwoPointLine(x1, y1, x2, y2, bias)
+
+ Draw a line between (x1, y1) and (x2, y2); the last point is drawn.
+ This is found in some newer chips. It is taken advantage of. The 8
+ lower bits of bias indicate whether 1 should be subtracted from the
+ error term for each of the octants (e.g. bit 0 matches octant 0),
+ it is not a requirement to support this parameter. If bit 8
+ (0x100) of bias is set, the last pixel should not be drawn (use
+ TWO_POINT_LINE_NOT_LAST to indicate whether this flag is
+ supported). This function requires hardware clipping.
+
+ Note that horizontal lines are always drawn with FillRectSolid.
+
+SetClippingRectangle(x1, y1, x2, y2)
+
+ Set the hardware clipping rectangle. (x2, y2) is the inclusive
+ right-bottom corner. Clipping should be active only for the first
+ following line draw (BresenhamLine or TwoPointLine). This function
+ is only used when HARDWARE_CLIP_LINE is enabled.
+
+SetupForDashedLine(fg, bg, rop, planemask, size)
+
+ Setup the hardware for accelerated dashed lines. Fg and bg are the
+ foreground and background colors respectively. If bg is -1, the
+ background is transparent. Size indicates the length of the color
+ expand pattern in bits (pixels) to be used by the subsequent dashed
+ line command. By the time this function is called, the bit pattern
+ will already reside in the LinePatternBuffer. The packing order in
+ the buffer is determined by one of the following flags:
+ LINE_PATTERN_MSBFIRST_MSBJUSTIFIED
+ LINE_PATTERN_MSBFIRST_LSBJUSTIFIED
+ One and only one of these flags must be set. A LinePatternBuffer must
+ be allocated and its length (in bits) recorded as LinePatternMaxLength
+ in order to use hardware dashed lines.
+
+SubsequentDashedBresenhamLine(x1, y1, octant, err, e1, e2, length, offset)
+SubsequentDashedTwoPointLine(x1, y1, x2, y2, bias, offset)
+
+ Draw a dashed line. The first arguments are identical to those of
+ SubsequentBresenhamLine and SubsequentTwoPointLine. The only
+ difference is the offset argument which specifies the offset into
+ the bit pattern the first pixel of this line must start on.
+
+LinePatternMaxLength
+LinePatternBuffer
+
+ LinePatternMaxLength is the maximum length pattern that the hardware
+ can accelerate. Additionally the LINE_PATTERN_POWER_OF_2_ONLY flag
+ can be set indicating that only patterns with lengths that are a
+ power of two can be accelerated. The LinePatternBuffer should be
+ allocated by the driver and should be long enough to hold
+ LinePatternMaxLength bits padded out to a DWORD.
+
+SetupForImageWrite(rop, planemask, transparency_color)
+
+ This sets up for multiple pixmap (image) transfers using the
+ transfer window defined by ImageWriteBase and ImageWriteRange.
+ Currently, DWORD padding is required. CPU_TRANSFER_BASE_FIXED
+ is supported but is often only faster than the non-accelerated
+ versions for rops other than GXcopy.
+
+ If the transparency_color is not -1, then it defines the
+ transparent "masking" color. If your hardware cannot do
+ transparent image transfers then you should set NO_TRANSPARENCY
+ in the ImageWriteFlags.
+
+SubsequentImageWrite(x, y, w, h, skipleft)
+
+ This sets up for an individual image transfer and is
+ analogous to the SubsequentCPUToScreenColorExpand function.
+ If the driver supports left edge clipping, then the skipleft
+ parameter specifies the number of pixels to be skipped on the
+ left edge (0 - 3). This is used in cases of unfavorable source
+ alignment.
+
+SubsequentScanlineScreenToScreenCopy(LineAddr, skipleft, x, y, w)
+
+ This sets up for a scanline by scanline image transfer. If the
+ driver supports left edge clipping, then the skipleft parameter
+ specifies the number of pixels to be skipped on the left edge
+ (0 - 3). This is used in cases of unfavourable source alignment.
+
+ImageWriteFlags
+
+ In addition to the regular planemask/rop restrictions, the
+ following flags are defined (with meaning similar to the color
+ expand flags).
+
+ LEFT_EDGE_CLIPPING
+ LEFT_EDGE_CLIPPING_NEGATIVE_X
+ NO_TRANSPARENCY
+ CPU_TRANSFER_BASE_FIXED
+
+ Additionally, a NO_GXCOPY flag can be set to indicate that
+ ImageWrites should only be used for the more complicated rops.
+ This is useful in the case where accelerator assisted image transfers
+ are not faster than the unaccelerated versions for simple copies.
+ Note: When using the Scanline version of ImageWrite the
+ CPU_TRANSFER_BASE_FIXED is currently unsupported.
+
+ImageWriteBase
+ImageWriteRange
+ImageWriteOffset
+
+ This is often, but not necessarily, the same window defined by the
+ CPUToScreenColorExpandBase and Range. ImageWrites may be
+ suboptimal if this range is not at least as large as the
+ framebuffer width. By default ImageWriteBase is set to
+ FramebufferBase if not defined.
+
+ When using the ScanlineScreenToScreenCopy, the ImageWriteRange must
+ be a large buffer in video memory, from testing about four scanlines
+ should be sufficient. (needs furthur testing).
+ ImageWriteOffset should be set as the (x * y) offset into the frame
+ buffer for the copy, similar to ImageWriteBase. ImageWriteBase is
+ not used in the Scanline version.
+
+SetupForFill8x8Pattern(patternx, patterny, rop, planemask, trans_col)
+
+ Set up for hardware 8x8 pattern fill (non-color expanded). If
+ neither the HARDWARE_PATTERN_SCREEN_ORIGIN flag or the HARDWARE_
+ PATTERN_PROGRAMMED_ORIGIN flag is set, patternx and patterny can be
+ ignored. Otherwise, patternx and patterny just indicate the video
+ memory address where the pattern is stored. The pattern is stored
+ linearly in video memory unless HARDWARE_PATTERN_NOT_LINEAR is
+ specified. When the transparency color is -1 there is no transparency.
+
+SubsequentFill8x8Pattern(patternx, patterny, x, y, w, h)
+
+ Perform a hardware 8x8 pattern fill. If the flag HARDWARE_PATTERN_
+ SCREEN_ORIGIN is set, patternx and patterny can be ignored;
+ otherwise, patternx and patterny indicate the video memory address
+ where the pattern is stored. However, if HARDWARE_PATTERN_
+ PROGRAMMED_ORIGIN is set patternx and patterny define the origin
+ offset into the pattern. Any rotation issues are handled by the
+ generic code by generating pre-rotated copies of the pattern. The
+ pattern address will always be at a multiple of 8 pixels offset
+ from the start of a scanline (x will be a multiple of 8), unless
+ the HARDWARE_PATTERN_ALIGN_64 is set. At the moment, setting
+ HARDWARE_PATTERN_ALIGN_64 in the absence of HARDWARE_PATTERN_
+ PROGRAMMED_ORIGIN will disable the use of this function, but this
+ will change in a future version.
+
+SetupFor8x8PatternColorExpand(patternx, patterny, bg, fg, rop, planemask)
+
+ Set up for hardware color-expanded 8x8 pattern fill. If the flag
+ HARDWARE_PATTERN_SCREEN_ORIGIN is set, or HARDWARE_PATTERN_
+ PROGRAMMED_ORIGIN is set in the absence of HARDWARE_PATTERN_
+ PROGRAMMED_BITS, patternx and patterny indicate the video memory
+ address where the pattern is stored, which will be on an 8 byte
+ boundary relative to the start of a scanline. Otherwise, patternx
+ and patterny can be ignored. The pattern x-coordinate will be in
+ units of "bits", that is, a byte offset of one relative to the
+ start of the scanline is represented by a patternx value of 8.
+
+ If HARDWARE_PATTERN_PROGRAMMED_BITS is set, patternx and patterny
+ are overloaded as follows: patternx holds the first 4 lines (32
+ pixels) of the pattern, with each byte (MSB-first bit order if the
+ HARDWARE_PATTERN_BIT_ORDER_MSBFIRST flag is set) corresponding to a
+ scanline of the pattern. patterny holds the second half of the
+ pattern. This is the so-called "Windows-format".
+
+ A background color of -1 indicates transparency (support of
+ transparency is indicated by HARDWARE_PATTERN_MONO_TRANSPARENCY).
+
+Subsequent8x8PatternColorExpand(patternx, patterny, x, y, w, h)
+
+ Perform a hardware color-expanded 8x8 pattern fill. If the flag
+ HARDWARE_PATTERN_SCREEN_ORIGIN is set, patternx and patterny
+ can be ignored; otherwise, patternx and patterny indicate the
+ video memory address where the pattern is stored. Any rotating
+ issues are handled by the generic code by generating pre-rotated
+ copies of the pattern. Again patternx is in "bit" or "stencil"
+ units.
+
+ If HARDWARE_PATTERN_PROGRAMMED_ORIGIN is set, patternx and
+ patterny hold the origin (x and y offsets into the pattern).
+ HARDWARE_PATTERN_SCREEN_ORIGIN may be defined additionally;
+ in that case, the following is true: patternx and patterny will
+ be the same for all "Subsequent" calls. You may only need to
+ program the origin in the first Subsequent call.
+
+ColorExpandFlags
+
+ This selects the restrictions for color expansion operations. The
+ flags are extended with a set of flags that is used to define
+ details about the hardware-specific implementation of color
+ expansion, as performed by the low-level color expansion functions.
+ The following extra flags are defined:
+
+ SCANLINE_NO_PAD
+ SCANLINE_PAD_BYTE
+ SCANLINE_PAD_DWORD
+
+ Defines the padding at the end of a scanline of monochrome
+ data, which indicates the number of bits that is ignored by the
+ graphics chip at the end of each scanline in multi-scanline
+ color-expansion operations from the CPU to the screen. DWORD
+ padding is preferred. These flags do not apply to screen-to-screen
+ color expansion. Currently, not defining SCANLINE_PAD_DWORD will
+ result in non-optimized and limited use of CPU-to-screen color
+ expansion.
+
+ CPU_TRANSFER_PAD_DWORD
+ CPU_TRANSFER_PAD_QWORD
+
+ Defines the total amount of data to be transferred in a
+ multi-scanline CPU-to-screen color-expansion operation. Most
+ chips pad to a DWORD boundary.
+
+ CPU_TRANSFER_BASE_FIXED
+
+ Indicates that the destination address for monochrome data for
+ CPU-to-screen color-expansion is a fixed address, rather than
+ a large range starting from the ColorExpandBase address.
+
+ ONLY_TRANSPARENCY_SUPPORTED
+
+ Indicates that the color expansion operations only work with
+ transparency (bit 0 pixels are not written).
+
+ TRIPLE_BITS_24BPP
+
+ When enabled (must be in 24bpp mode), color expansion functions
+ are expected to require three times the amount of bits to be
+ transferred so that 24bpp grayscale colors can used with color
+ expansion in 8bpp coprocessor mode. Each bit is expanded to 3
+ bits when writing the monochrome data. When definining this
+ flag, also define RGB_EQUAL.
+
+ VIDEO_SOURCE_GRANULARITY_PIXEL
+ VIDEO_SOURCE_GRANULARITY_BYTE
+ VIDEO_SOURCE_GRANULARITY_DWORD
+
+ This indicates the granularity of the horizontal source location
+ specification for screen-to-screen color expansion operations.
+ It is either one pixel, 8 pixels (a byte), or 32 pixels (a 32-bit
+ word). If there's some kind of clipping mechanism available, pixel
+ granularity is usually possible.
+
+ BIT_ORDER_IN_BYTE_LSBFIRST
+ BIT_ORDER_IN_BYTE_MSBFIRST
+
+ This defines the order of bits within a byte. As far as X is
+ concerned, it's best when the lowest-order bit corresponds to
+ the leftmost pixel on the screen (this is the technically
+ superior format), but many chips only support the "wrong" bit
+ order (MSBFIRST).
+
+ LEFT_EDGE_CLIPPING
+
+ This indicates that CPU-to-screen color expansion operations
+ support the left-edge clipping parameter, which indicates
+ the number of pixels to skip at the left edge.
+
+ LEFT_EDGE_CLIPPING_NEGATIVE_X
+
+ This indicates that when the left-edge clipping parameter is
+ specified, the x coordinate is allowed to be negative (while
+ being on-screen when the parameter is actually added to it).
+ At the moment, this flag is a requirement for CPU-to-screen
+ color expansion acceleration of (large) stipples.
+
+ Note that the regular graphics operations flags for raster-op,
+ planemask and color restrictions are also valid. NO_TRANSPARENCY
+ indicates that color expansion does not support transparency.
+
+SetupForCPUToScreenColorExpand(bg, fg, rop, planemask)
+
+ Set up for CPU-to-screen color expansion operations. This is used
+ for writing bitmaps and text, and (not yet) stipples. When bg is
+ equal to -1, the background (bits that are 0) is transparent.
+
+SubsequentCPUToScreenColorExpand(x, y, w, h, skipleft)
+
+ Perform a CPU-to-screen color expansion operation. The monochrome
+ data will be transferred after this function has been called.
+ Sync() is called when the data has been transferred. The optional
+ skipleft parameter defines a number of pixels (0 - 7) to be skipped
+ at the left edge (at the start of each scanline).
+
+SetupForScreenToScreenColorExpand(bg, fg, rop, planemask)
+
+ Set up for screen-to-screen color expansion operations. This will
+ only be used when the storing of monochrome data in the pixmap (or
+ font) cache is implemented.
+
+SubsequentScreenToScreenColorExpand(srcx, srcy, x, y, w, h)
+
+ Perform a screen-to-screen color expansion operation. scrx is in
+ pixel units (8 corresponds to one byte offset).
+
+SetupForScanlineCPUToScreenColorExpand(x, y, w, bg, fg, rop, planemask)
+
+ Set up for a scanline-by-scanline color expansion operation from
+ the CPU to the screen. This is not of much use (except when a chip
+ is not compatible with supported methods of color expanding a whole
+ bitmap). It's not used currently.
+
+SubsequentScanlineCPUToScreenColorExpand()
+
+ Color expand a scanline from the CPU to the screen. Many chips
+ automatically add the pitch of the dislay to the destination
+ address after a scanline has been written so that it doesn't need
+ to be updated. Otherwise you'll need to keep track of the address.
+
+SetupForScanlineScreenToScreenColorExpand(x, y, w, h, bg, fg, rop, planemask)
+
+ Set up for a scanline-by-scanline color expansion operation from
+ the screen to the screen (top-down). This is typically used for
+ chips that don't have usable CPU-to-screen color expansion. It is
+ taken advantage of for bitmaps, text, and (not yet) stipples.
+
+SubsequentScanlineScreenToScreenColorExpand(srcaddr)
+
+ This performs color expansion of a scanline from the screen
+ (typically a scratch buffer) to the screen. To take advantage of
+ this operation, ScratchBufferAddr and ScratchBufferSize must be
+ defined (> 0), and either linear addressing must be used or
+ ScratchBufferBase must be defined. Being able to support
+ COP_FRAMEBUFFER_CONCURRENCY is a win here. The srcaddr is the
+ linear framebuffer address in (non-expanded) pixel units. The real
+ address is (srcaddr / 8). When TRIPLE_BITS_24BPP is defined,
+ srcaddr is in non-expanded 8bpp pixel units.
+
+ In addition, PingPongBuffers defines the number of alternating
+ buffers used. The default is two. Depending on the implementation
+ and size of framebuffer and coprocessor write buffers on the chip,
+ you might need more than two.
+
+CPUToScreenColorExpandBase
+
+ This address defines the base address for writing monochrome bitmap
+ data to when performing CPU-to-screen color expansion operations.
+ When the CPU_TRANSFER_BASE_FIXED flag is not set and
+ CPUToScreenColorExpandRange is not defined, a large range is
+ assumed to be available (at least the number pixels in the virtual
+ screen / 8). For text operations this is probably never a problem.
+ At the moment hardware that has 64 bytes or so of transfer space is
+ unlucky. 32-bit access is always used.
+
+ If this is not defined, FramebufferBase will automatically be
+ used.
+
+CPUToScreenColorExpandRange
+
+ This defines the size of the "window" starting from the base
+ address for writing CPU-to-screen color-expand data. If this is
+ not defined or zero, the range is assumed to be large enough.
+ When it is greater than the width of the screen in pixels / 8,
+ the base address will be adjusted if necessary at the end of each
+ scanline. Currently, if it is smaller than that, the
+ CPU_TRANSFER_BASE_FIXED flag is set.
+
+ At the moment, the bottom line is that you need about 256 bytes
+ of transfer space to use CPU-to-screen color expansion (128 bytes
+ with a 1024 pixel screen width) with PCI-burst mode support.
+ However, "fixed-base" operation is supported.
+
+FramebufferBase
+
+ This is a pointer to the framebuffer. It is required by the
+ ScanlineScreenToScreenColorExpand, and is automatically
+ initialized. It should not be set up in a chip-specific driver.
+
+BitsPerPixel
+
+ This is the number of bits per pixel, stored here for convenience.
+ There's no need to initialize this from a driver.
+
+FramebufferWidth
+
+ The is the width of the framebuffer in pixels, stored here for
+ convenience. There's no need to initialize this from a driver.
+
+ScratchBufferAddr
+ScratchBufferSize
+
+ This specifies the linear address in bytes and size of the scratch
+ buffer used for ScanlineScreenToScreenColorExpand operations.
+
+ScratchBufferBase
+
+ This is a pointer to the mapped video memory of the scratch buffer.
+ When not defined, the scratch buffer is assumed to be at the
+ specified offset (ScratchBufferAddr) into a linear framebuffer.
+ This field should only be initialized when using
+ ScanlineScreenToScreenColorExpand with a non-linear framebuffer,
+ in which case it should be noted that it is totally independent
+ from ScratchBufferAddr.
+
+PingPongBuffers
+
+ This field defines the number of alternating buffers used in the
+ scratch buffer for ScanlineScreenToScreenColorExpand. The default
+ is two. Depending on the implementation and size of framebuffer and
+ coprocessor write buffers on the chip, you might need more than
+ two.
+
+ErrorTermBits
+
+ Indicates the number of bits of precision for the Bresenham line
+ error terms. The absolute values of the of the terms are guaranteed
+ to be in the range [0, 2 ^ ErrorTermBits - 1]. If your registers
+ have 14 significant bits, you would probably use 13 here because of
+ the sign bit.
+
+ServerInfoRec
+
+ This is a pointer to the XFree86 server InfoRec. It must be defined.
+ The InitPixmapCache function initializes it for compatibility with
+ earlier versions of XAA. The SVGA server initializes it
+ automatically.
+
+PixmapCacheMemoryStart
+PixmapCacheMemoryEnd
+
+ These values must be defined if the pixmap cache is enabled. The
+ InitPixmapCache function initializes them, for compatibility with
+ earlier versions of XAA.
+
+
+1.6 Commonly Used Parameters
+
+This section clarifies the format of some of the commonly used
+parameters in the low-level functions (as described above).
+
+Coordinates ("x", "y") are pixel coordinates unless otherwise noted.
+
+The width and height ("w", "h") define the size of the area involved in
+pixel units.
+
+Colors (named "color", "bg" or "fg") are simple pixel values. They are
+not "replicated" over the 32-bit integer argument. So for example in
+8bpp mode, bits 0-7 of the value represent the pixel value, and the
+rest of the bits is zero. If your chip requires a "replicated" 32-bit
+pixel value (4 duplicated pixels for 8bpp), you will have to do that in
+your low-level functions implementation.
+
+The planemask is a mask that defines what bits in the pixel value
+are to be modified on the screen. Again, this value cannot be assumed
+to be "replicated" to 32-bit in 8bpp and 16bpp modes.
+
+The raster-op ("rop") is one of the 16 raster-operations that X
+defines:
+
+ #define GXclear 0x0 /* 0 */
+ #define GXand 0x1 /* src AND dst */
+ #define GXandReverse 0x2 /* src AND NOT dst */
+ #define GXcopy 0x3 /* src */
+ #define GXandInverted 0x4 /* NOT src AND dst */
+ #define GXnoop 0x5 /* dst */
+ #define GXxor 0x6 /* src XOR dst */
+ #define GXor 0x7 /* src OR dst */
+ #define GXnor 0x8 /* NOT src AND NOT dst */
+ #define GXequiv 0x9 /* NOT src XOR dst */
+ #define GXinvert 0xa /* NOT dst */
+ #define GXorReverse 0xb /* src OR NOT dst */
+ #define GXcopyInverted 0xc /* NOT src */
+ #define GXorInverted 0xd /* NOT src OR dst */
+ #define GXnand 0xe /* NOT src OR NOT dst */
+ #define GXset 0xf /* 1 */
+
+For each graphics operation you can define that only GXcopy is supported
+by setting the GXCOPY_ONLY flag in the flags for that particular
+operation. Similarly, NO_PLANEMASK indicates that the plane mask is
+not supported.
+
+
+1.5 The best strategy
+
+Start with simple filled solid rectangles and screen-to-screen copies
+(BitBLT). Those two functions alone will accelerate the vast majority
+of graphic operations requested. The sample driver can be used as a
+starting point.
+
+Next you might want to look at color expansion (CPUToScreen, or if
+that can't be done, ScanlineScreenToScreen), BresenhamLine or
+TwoPointLine, and Fill8x8Pattern/ColorExpand8x8Pattern.
+
+The relative win of seperately implementing functions that are already
+accelerated with solid filled rectangles varies, but it can make a
+difference since just using rectangle fills has some overhead. You may
+be able to make better use of features of the graphics chip, and better
+exploit CPU/graphics concurrency, although this already done by the
+generic code for some operations (such as filled polygons and arcs).
+
+
+2 Acceleration hooks
+
+Many operations can be "hooked" at a higher level, instead of just
+defining the low-level functions. This can be useful for existing code
+or operations for which there are no adequate low-level functions. What
+follow is a description of most of the functions that can be hooked.
+
+[This isn't complete]
+
+2.1 Filled Rectangles
+
+Rectangles can be filled with a single source color, or with three
+different types of repeating pattern:
+
+ Stipple: a transparent bitmap pattern where 1's correspond to the
+ foreground color.
+
+ Opaque stipple: a bitmap pattern where 0's correspond to the
+ background color and 1's to the foreground color.
+
+ Tile: an image pattern that can have full pixel depth.
+
+2.1.1 Solid Filled Rectangles
+
+Solid filled rectangles are a very common operation. Apart from
+a regular solid fill, special raster ops are often used, for example
+for inverting the destination.
+
+To define a simple function for drawing one filled rectangle that will
+be used for many kinds of operation, use this:
+
+ xf86AccelInfoRec.SetupForFillRectSolid = MySetupForFillRectSolid;
+ xf86AccelInfoRec.SubsequentFillRectSolid = MySubsequentFillRectSolid;
+
+If you accelerate solid filled rectangles, and have a complete
+replacement for PolyFillRect that handles clipping, do this:
+
+ xf86GCInfoRec.PolyFillRectSolid = MyPolyFillRect;
+
+If you don't handle clipping, but do have a replacement for accelerated
+solid filled rectangles, do this:
+
+ xf86GCInfoRec.PolyFillRectSolid = xf86PolyFillRect;
+ xf86AccelInfoRec.FillRectSolid = MyFillRectSolid;
+
+In all cases, the following flags can be set in
+xfGCInfoRec.FillRectSolidFlags:
+
+ GXCOPY_ONLY Only the raster-op GXcopy is supported.
+ NO_PLANEMASK No special planemask is supported.
+ RGB_EQUAL Only a foreground color with same values
+ for red, green and blue is accepted.
+
+2.1.2 Tiled Filled Rectangles
+
+If you have the required low-level functions and enable PIXMAP_CACHE,
+the pixmap cache will be used to draw tiles. For tiles, you just need
+ScreenToScreenCopy.
+
+If you accelerate tiled filled rectangles, and have a complete
+replacement for PolyFillRect that handles clipping, do this:
+
+ xf86GCInfoRec.PolyFillRectTiled = MyPolyFillRect;
+
+If you don't handle clipping, but do have accelerated tiled filled
+rectangles, do this:
+
+ xf86GCInfoRec.PolyFillRectTiled = xf86PolyFillRect;
+ xf86AccelInfoRec.FillRectTiled = MyFillRectTiled;
+
+In both cases, the following flags can be set in
+xfGCInfoRec.FillRectTiledFlags:
+
+ GXCOPY_ONLY Only the raster-op GXcopy is supported.
+ NO_PLANEMASK No special planemask is supported.
+
+2.1.3 Stippled Filled Rectangles
+
+If you have the required low-level functions and enable PIXMAP_CACHE,
+the pixmap cache will be used to draw stipples. For stipples, you just need
+ScreenToScreenCopy with support for transparency.
+
+If you accelerate stippled filled rectangles, and have a complete
+replacement for PolyFillRect that handles clipping, do this:
+
+ xf86GCInfoRec.PolyFillRectStippled = MyPolyFillRect;
+
+If you don't handle clipping, but do have accelerated stippled filled
+rectangles, do this:
+
+ xf86GCInfoRec.PolyFillRectStippled = xf86PolyFillRect;
+ xf86AccelInfoRec.FillRectStippled = MyFillRectStippled;
+
+In both cases, the following flags can be set in
+xfGCInfoRec.FillRectStippledFlags:
+
+ GXCOPY_ONLY Only the raster-op GXcopy is supported.
+ NO_PLANEMASK No special planemask is supported.
+
+2.1.4 Opaque Stippled Filled Rectangles
+
+If you have the required low-level functions and enable PIXMAP_CACHE,
+the pixmap cache will be used to draw stipples. For stipples, you just need
+ScreenToScreenCopy.
+
+If you accelerate opaque filled rectangles, and have a complete
+replacement for PolyFillRect that handles clipping, do this:
+
+ xf86GCInfoRec.PolyFillRectOpaqueStippled = MyPolyFillRect;
+
+If you don't handle clipping, but do have accelerated opaque filled
+rectangles, do this:
+
+ xf86GCInfoRec.PolyFillRectOpaqueStippled = xf86PolyFillRect;
+ xf86AccelInfoRec.FillRectOpaqueStippled = MyFillRectOpaqueStippled;
+
+In both cases, the following flags can be set in
+xf86GCInfoRec.FillRectOpaqueStippledFlags:
+
+ GXCOPY_ONLY Only the raster-op GXcopy is supported.
+ NO_PLANEMASK No special planemask is supported.
+
+2.2 Filled Spans
+
+Filled spans can be used for many purposes, mostly filled areas
+of different shapes. The fill style can be solid (by far the most
+useful), tiled, stippled and opaque stippled.
+
+If you accelerate solid filled spans, and have a complete
+replacement for FillSpansSolid that handles clipping, do this:
+
+ xf86GCInfoRec.FillSpansSolid = MyFillSpanstSolid;
+
+And similarly for other fill styles:
+
+ xf86GCInfoRec.FillSpansTiled = MyFillSpanstTiled;
+ xf86GCInfoRec.FillSpansStippled = MyFillSpanstStippled;
+ xf86GCInfoRec.FillSpansOpaqueStippled = MyFillSpanstOpaqueStippled;
+
+If you don't handle clipping, but do have a function for drawing solid
+filled spans, do this:
+
+ xf86GCInfoRec.FillSpansSolid = xf86FillSpans;
+ xf86AccelInfoRec.FillSpansSolid = MyFillSpansSolid;
+
+In all cases, the following flags can be set in
+xfGCInfoRec.FillSpansSolidFlags (and similarly for for other fill styles):
+
+ GXCOPY_ONLY Only the raster-op GXcopy is supported.
+ NO_PLANEMASK No special planemask is supported.
+ RGB_EQUAL Only a foreground color with same values
+ for red, green and blue is accepted.
+
+2.3 Filled Arcs
+
+If you accelerate filled solid arcs, and have a complete replacement
+for PolyFillArc that handles clipping, do this:
+
+ xf86GCInfoRec.PolyFillArc = MyPolyFillArc;
+
+The following flags can be set in xf86GCInfoRec.PolyFillArcFlags:
+
+ GXCOPY_ONLY Only the raster-op GXcopy is supported.
+ NO_PLANEMASK No special planemask is supported.
+
+If you have a function for accelerated solid horizontal spans, it will
+automatically be taken advantage of for filled arcs.
+
+2.4 Text
+
+There are two kinds of text, transparent text (the background is not
+written), and image text (the background is filled with the background
+color).
+
+There are also two types of font. Terminal-emulator fonts, which have
+characters that are all the same size, and non-terminal emulator fonts,
+which have characters of varying size.
+
+In the case of image text with a non-terminal emulator font, the filled
+background corresponds to the bounding box of the text image.
+
+2.4.1 Transparent Text
+
+If you accelerate transparent text strings, and have a complete replacement
+for PolyGlyphBlt that handles clipping, do this if you accelerate
+terminal-emulator fonts:
+
+ xf86GCInfoRec.PolyGlyphBltTE = MyPolyGlyphBltTE;
+
+And if you also support non-terminal emulator fonts:
+
+ xf8GCInfoRec.PolyGlyphBltNonTE = MyPolyGlyphBltNonTE;
+
+And if you also support non-terminal emulator fonts:
+
+ xf8GCInfoRec.PolyGlyphBltNonTE = MyPolyGlyphBltNonTE;
+
+If you don't handle clipping, but do have accelerated transparent text:
+
+ xf86GCInfoRec.PolyGlyphBltTE = xf86PolyGlyphBltTE;
+ xf86AccelInfoRec.PolyTextTE = MyPolyTextTE;
+
+And similarly for non-terminal emulator fonts:
+
+ xf86GCInfoRec.PolyGlyphBltNonTE = xf86PolyGlyphBltNonTE;
+ xf86AccelInfoRec.PolyTextNonTE = MyPolyTextNonTE;
+
+2.4.2 Image text
+
+If you accelerate image text strings, and have a complete replacement
+for ImageGlyphBlt that handles clipping, do this if you accelerate
+terminal-emulator fonts:
+
+ xf86GCInfoRec.ImageGlyphBltTE = MyImageGlyphBltTE;
+
+And if you also support non-terminal emulator fonts:
+
+ xf8GCInfoRec.ImageGlyphBltNonTE = MyImageGlyphBltNonTE;
+
+If you don't handle clipping, but do have accelerated transparent text:
+
+ xf86GCInfoRec.ImageGlyphBltTE = xf86ImageGlyphBltTE;
+ xf86AccelInfoRec.ImageTextTE = MyImageTextTE;
+
+And similarly for non-terminal emulator fonts:
+
+ xf86GCInfoRec.ImageGlyphBltNonTE = xf86ImageGlyphBltNonTE;
+ xf86AccelInfoRec.ImageTextNonTE = MyImageTextNonTE;
+
+2.5 CopyArea
+
+Screen-to-screen area copies (BitBLTs) are extremely useful. It's vital
+for smooth scrolling and dragging of windows. Unaccelerated, this
+operation is often slow because of the slowness of read operations
+from the framebuffer. This function can also be used to great effect
+for caching mechanisms for patterns and fonts, when support for it
+is added.
+
+If you accelerate screen-to-screen area copies (BitBLTs), and have a
+complete replacement for CopyArea that handles clipping, do this:
+
+ xf8GCInfoRec.CopyArea = MyCopyArea;
+
+If you don't handle clipping, but do have an accelerated CopyArea:
+
+ xf86GCInfoRec.CopyArea = xf86CopyArea;
+ xf86AccelInfoRec.ScreenToScreenBitBlt = MyScreenToScreenBitBlt;
+
+In all cases, the following flags can be set in
+xfGCInfoRec.CopyAreaFlags:
+
+ GXCOPY_ONLY Only the raster-op GXcopy is supported.
+ NO_PLANEMASK No special planemask is supported.
+ NO_TRANSPARENCY Transparency color compare is not supported.
+
+
+3. Opportunities For Improvement
+
+- The graphics operation flags aren't consistent. There should be
+ seperate flags indicating the restrictions for the lower-level
+ functions.
+
+- VT-switching awareness has not been extensively tested, and the
+ current implement has a few rough edges.
+
+- Solid tile fill may be faster with cfb in some cases (if the chip
+ doesn't have much video memory bandwidth to play with and the PCI
+ bus bandwidth is decent).
+
+- Having a function for clipped filled spans that clips on the fly. This
+ doesn't exist yet anywhere in the source tree. This would be a minor
+ speed up for things like clipped filled polygons and arcs, and wide
+ lines.
+
+- Having the pixmap cache store stipples in monochrome format, and using
+ color expansion features of the graphics chip to replicate them. This
+ is more efficient since less video memory bandwidth is required for
+ the cached pattern source. Not all chips support this kind of operation
+ easily, especially w.r.t. clipping of the leftmost edge (the first pixel
+ to be drawn may start at some bit of the leftmost video memory byte), and
+ defining the location of the monochrome pattern in video memory can be
+ a little complex.
+
+- Taking more advantage of built-in (8x8) chip pattern registers. This
+ works OK now, but things not implemented include detection of
+ tiles that have only two colors so that they can be done with
+ color-expand 8x8 pattern fill, and interleaving schemes allowing 16
+ and 32 pixel high patterns to be done using the hardware pattern. Also
+ some chips support 16x8 and 32x8 pattern fill at 8bpp by using 16bpp
+ or 32bpp pattern fill. Currently, support for chips that require the
+ pattern to be aligned on a 64-pixel boundary is missing in most cases,
+ which in practice means the 8x8 pattern is not usable for many chips.
+
+- Font-caching (useful for configurations where it's not possible to use
+ color expansion for text, and for certain fonts). Non-"terminal emulator"
+ fonts is certainly a weak area of XAA.
+
+- Complete implementation of non-terminal emulator font text acceleration
+ using color expansion (the code is in place, but causes problems).
+
+- Generic hardware-cursor code (this sounds very useful to me), including
+ Harald Koenig's support for real-time software/hardware cursor switching.
+
+- More complete 24bpp-in-8bpp-mode support. Missing is full implementation
+ of color expansion schemes to allow 24bpp fills in 8bpp mode in two
+ passes.
+
+- The Pentium optimized text bitmap functions exist only for 6 and 8-pixel
+ wide fonts. BTW, on a Cyrix 6x86 the Pentium-optimized 6-wide function
+ seems to cause a 2% performance decrease.
+
+- Accelerated stipples using direct color expansion would definitely be
+ worthwhile. The lowest-level function is in place (but untested). It
+ would take care of cases where the font cache cannot be used (such as
+ 24bpp, lack of transparency color compare for transparent stipples,
+ lack of off-screen video memory), or when color expansion is faster
+ (generally on video memory bandwidth-starved configurations).
+
+3.1 More Concurrency?
+
+More concurrency between graphics and CPU processing sounds very
+attractive. This can be implemented by not "syncing" when leaving the
+graphic drawing code, but instead allowing graphics commands to
+continue while X is doing its request processing, or even during
+context switching or when the client is running. The ever larger PCI
+write buffers help to make this a very nice optimization. This requires
+awareness of coprocessor activity at several levels in the server code
+(for example, at any point where something is read or written to the
+video card).
+
+There are variations between chipsets that affect how easily they would
+support such a scheme. The best behaviour is what I would call "in
+order execution" of coprocessor commands and simple CPU writes to the
+framebuffer. That is, if you send some graphics coprocessor commands to
+the chip, and then write something to the framebuffer, it is guaranteed
+that the framebuffer writes will only happen when the graphics commands
+have been completed. This avoids, for example, having to check for
+coprocessor activity each time something is drawn with a "dumb"
+framebuffer function. I think that PCI write buffers on the motherboard
+generally follow this behaviour, but graphics chips generally do not.
+
+Of course, reading or querying anything from the graphics card is
+something you will want to avoid, since in most cases this will result
+in the CPU being stalled until all the PCI and on-chip write buffers
+are flushed and processed. Chips that require frequent querying or do
+not allow concurrent coprocessor execution and CPU framebuffer access
+will take much less benefit.
+
+A somewhat wild way to test this kind of scheme is to simply not define
+the BACKGROUND_OPERATIONS flag, but despite that not do any syncing
+in the graphics primitives. Without BACKGROUND_OPERATIONS set, the XAA
+code almost never calls Sync itself. Someone (inadvertently) tried
+this on an ET6000, and it seemed to measurably increase
+performance. This is of course hazardous and prone to lock-ups etc.
+
+
+4. Comparison Of Chip-specific Implementations
+
+
+4.1 Current Chip-specific Implementations
+
+ARK Logic
+
+ Uses BACKGROUND_OPERATIONS and COP_FRAMEBUFFER_CONCURRENCY. The
+ latter is vital for high-performance color expansion, since the
+ ARK chips don't appear to have CPU-to-screen color expansion.
+ There's no need to "sync" during a batch of accelerator commands;
+ the ARK chips seem to have "PCI-Retry" support.
+
+ Screen locations are programmed as pixel addresses. The ARK chip
+ also supports coordinates, but that restricts the possible
+ framebuffer widths and I don't think it would be faster.
+
+ FillRectSolid is provided. At 24bpp, it uses 8bpp coprocessor mode
+ which leads to RGB_EQUAL and NO_PLANEMASK restrictions.
+ ScreenToScreenCopy is supported, again restrictions at 24bpp:
+ NO_PLANEMASK and NO_TRANSPARENCY. BresenhamLine is very
+ straightforward.
+
+ Fill8x8Pattern is supported; the ARK chip requires the pattern to
+ be aligned on a 64-pixel boundary and the address modulo 64 seems
+ to indicate the vertical offset (y origin) (HARDWARE_PATTERN_MOD_
+ 64_OFFSET). The latter means the pattern can actually be used (when
+ the framebuffer width is a multiple of 64), despite the limited
+ support for 64-pixel pattern alignment in XAA. The ARK chips don't
+ seem to have support for a monochrome pattern.
+
+ Color expansion is implemented using ScanlineScreenToScreen-
+ ColorExpand (24bpp: RGB_EQUAL, NO_PLANEMASK), which is pretty fast
+ thanks to COP_FRAMEBUFFER_CONCURRENCY.
+ Color expansion flags are VIDEO_SOURCE_GRANULARITY_PIXEL and
+ BIT_ORDER_IN_BYTE_LSBFIRST. At 24bpp, TRIPLE_BITS_24BPP would be
+ useful but is not yet supported by XAA.
+
+ ScreenToScreenColorExpand is provided for future use by XAA. One
+ thing that ARK chips can accelerate but is not yet provided by XAA
+ is styled (patterned) line drawing.
+
+Cirrus Logic GD5426/28/29/30/34/40/46 and 7543/48
+
+ Uses BACKGROUND_OPERATIONS. The driver is shared by a very wide
+ range of largely compatible chips, from the first-generation
+ accelerator CL-GD5426 to the recent CL-GD5446, which is the only
+ one to support COP_FRAMEBUFFER_CONCURRENCY and also doesn't need
+ "sync"-ing between coprocessor operations. Screen locations are
+ programmed as byte addresses (which makes the driver larger than,
+ for example, ARK). The driver is compiled twice, with programmed I/O
+ (required for earlier chips) and with memory-mapped I/O.
+
+ FillSolidRect is provided (NO_PLANEMASK, since the chips don't
+ support a planemask), and at 24bpp on a non-5436/46 uses 8bpp mode
+ in which case RGB_EQUAL is set.
+
+ ScreenToScreenCopy is supported (NO_PLANEMASK). A few chips
+ (5429/30/34) don't support transparency color compare at all
+ (NO_TRANSPARENCY), and none of the chips support it at pixel depths
+ greater than 16bpp.
+
+ For CPU-to-screen color expansion, chips earlier than the CL-GD5436
+ don't support DWORD padding of scanlines, so the XAA code isn't
+ usable for them. Instead, these chips use byte-padding-aware text
+ acceleration code from the old accelerated driver, and the
+ ScanlineScreenToScreenColorExpand method (which isn't very fast
+ on these chips) is provided for other things. NO_PLANEMASK. The
+ 5436/46 support 24bpp color expansion, but only with transparency
+ (ONLY_TRANSPARENCY_SUPPORTED); the others would benefit from
+ TRIPLE_BITS_24BPP. The bit order is BIT_ORDER_IN_BYTE_MSBFIRST. The
+ LEFT_EDGE_CLIPPING parameter (a value from 0 to 7) is supported for
+ CPU-to-screen color expansion. Screen-to-screen color expansion is
+ provided for future use. It requires the source to be aligned on a
+ DWORD boundary (VIDEO_SOURCE_GRANULARITY_DWORD).
+
+Matrox Millennium
+
+ BACKGROUND_OPERATIONS
+ 24bpp: NO_PLANEMASK
+ FillRectSolid
+ ScreenToScreenCopy (NO_TRANSPARENCY)
+
+ Color expansion:
+ CPUToScreenColorExpand
+ SCANLINE_PAD_DWORD
+ CPU_TRANSFER_PAD_DWORD
+ BIT_ORDER_IN_BYTE_LSBFIRST
+ LEFT_EDGE_CLIPPING
+ ScreenToScreenColorExpand
+ VIDEO_SOURCE_GRANULARITY_PIXEL
+
+
+4.2 Chip-specific Performance
+
+This table is intended to help with determining what kinds of
+operations best suit a particular chip. It shows the results (in MB/s)
+for the low-level bandwidth benchmarks run at start-up. Because refresh
+is disabled at the time time benchmark is run, the result reflects the
+full DRAM bandwidth on DRAM-based cards (the dot clock doesn't really
+matter). For this reason, the comparison isn't really fair (biased against
+VRAM/WRAM and MDRAM). The virtual display width can have an influence.
+
+Chip ARK1000PV Trid9385 CLGD5434 TGUI9440 MGA-Mill ET6000
+Memory 1MB DRAM 2MB DRAM 2MB DRAM 1MB DRAM 2MB WRAM 2MB MDRAM
+CPU DX4/100 ? DX4/100 AMK5/100 AMK5/100 6x86P150+
+Bus PCI 33MHz PCI VLB 33MHz PCI 33MHz PCI 33MHz PCI 30MHz
+bpp, width 8bpp 1024 8bpp 8bpp 1024 8bpp 8bpp 8bpp
+-----------------------------------------------------------------------------
+framebuffer 43.95 15.89 32.76 44.23 44.48 61.40
+solid filled rect
+10x1 7.38 3.14 4.58 8.72 34.99 28.22
+40x40 85.82 89.93 120.34 62.60 369.84 143.84
+400x400 108.81 157.20 211.18 80.03 1618.11 264.35
+screen copy
+10x10 24.77 11.26 20.49 18.53 28.14 24.22
+40x40 38.81 43.90 41.68 32.11 89.27 70.57
+400x400 46.70 68.59 54.47 34.14 126.88 194.23
+400x400 scroll - - 55.63 40.22 - 189.34
+8x8 pattern fill
+400x400 105.16 116.08 - 80.02 - 264.34
+color expansion
+CPU to screen - - 116.25 - 261.03* -
+scanl. scr-to-scr 71.75 - 80.64 - - 187.25
+10x10 scr-to-scr 29.90 - 26.69 20.07 - -
+
+Chip MGA-Mill MGA-Mill MGA-Mill TGUI9680 ARK2000PV
+Memory 2MB WRAM 4MB WRAM 2MB WRAM 2MB DRAM 2MB EDO
+CPU DX4/133 P133 P133 DX4/100
+Bus PCI 33MHz PCI 33MHz PCI 33Mhz PCI PCI 33MHz
+bpp, width 8bpp 8bpp 1024 8bpp 1152 8bpp 2048 8bpp 1024
+-------------------------------------------------------------------
+framebuffer 26.48 83.70 83.13 10.09 64.44
+solid filled rect
+10x1 28.63 34.28 41.30 3.06 7.91
+40x40 385.13 316.47 453.02 55.97 155.76
+400x400 1656.93 1367.64 1942.59 145.16 244.35
+screen copy
+10x10 29.18 23.47 35.09 12.61 33.20
+40x40 81.52 74.55 99.92 35.38 78.80
+400x400 114.81 105.83 137.60 46.48 99.03
+400x400 scroll - - - 51.88 100.08
+8x8 pattern fill
+400x400 - - - 51.74 228.70
+color expansion
+CPU to screen 211.11* 419.09* 416.23* - -
+scanl. scr-to-scr - - - - 137.97
+10x10 scr-to-scr - - - 15.26 36.79
+
+Chip ARK2000PV ARK2000PV MGA-Mill CL-GD5426 CL-GD5446
+Memory 2MB EDO 2MB EDO 2MB WRAM 1MB DRAM 2MB DRAM
+CPU 6x86P150+ 6x86P166+ 6x86P166+ DX4/100 P133
+Bus PCI 30MHz PCI 33Mhz PCI 33MHz VLB 33MHz PCI 33Mhz
+bpp, width 8bpp 1024 8bpp 1024 8bpp 1024 8bpp 1024 8bpp 1280
+-------------------------------------------------------------------
+framebuffer 88.84 100.45 92.18 13.22 80.81
+solid filled rect
+10x1 20.99 22.82 41.30 1.16 25.49
+40x40 157.00 157.00 458.38 28.88 167.10
+400x400 244.34 244.34 1961.74 41.74 218.02
+screen copy
+10x10 33.22 33.23 35.09 5.35 34.39
+40x40 78.81 78.81 99.93 15.83 77.71
+400x400 99.13 99.02 137.87 20.98 97.03
+400x400 scroll 100.09 100.09 664.02 21.18 98.55
+8x8 pattern fill
+400x400 228.68 228.72 - 41.10 217.91
+color expansion
+CPU to screen - 730.52 - 221.10
+scanl. scr-to-scr 138.01 138.09 - 19.56 -
+10x10 scr-to-scr 36.87 36.86 39.19 6.16 66.46
+
+(*) After this benchmark was taken, the color expansion benchmark was
+ changed to write a pattern including both colors instead of just the
+ background one, which is likely to affect the score.
+
+The 10x1 filled rectangles score tells a lot about the command overhead
+for small fills, which is important for operations that fill span-by-span.
+The 10x10 and 40x40 screencopy give an impression of pixmap cache
+efficiency, while the 10x10 score also indicates how a simple font cache
+would perform (compare with color expansion). The 10x10 screen-to-screen
+color expand score reflects a smarter kind of font cache.
+
+If your implementation seems weak at a particular kind of operation, maybe
+you are not doing it optimally and can improve it (usually by reducing
+the command overhead, for example by minimizing the number of graphics
+chip queries).
+
+
+5. Development notes
+
+When adding a function to the GCInfoRec or AccelInfoRec, make sure to
+have a Makefile with dependencies (run make depend after doing make
+Makefile). If you don't, you're bound to get unexplainable core dumps.
+That also applies to SVGA drivers using the new interface; they should
+be recompiled after a new version of the generic acceleration code
+in installed.
+
+Header files:
+
+vgabpp.h Declares the new ScreenInit functions for each depth.
+
+xf86xaa.h General public definitions, including the GCInfoRec and
+ AccelInfoRec.
+
+xf86scrin.h XAA screen initialization functions.
+
+xf86local.h Declares functions local to the generic acceleration code.
+
+xf86gcmap.h Maps names of some local functions to depth-specific
+ versions.
+
+xf86maploc.h Declares local functions that are name-mapped depending on
+ the depth.
+
+vga256map.h Maps the name of some cfb functions to their vga256
+ equivalents. This is used for the vga256 version of the
+ GC validation code.
+
+xf86pcache.h Some declarations for the pixmap cache.
+
+xf86expblt.h Declares monochrome data color-expansion blit functions
+ defined in xf86expblt.c
+
+
+6. Acknowledgements
+
+The Mach64 server by Kevin Martin has been used a base for some parts
+(notably pixmap caching), and the set of functions accelerated in the
+Mach64 server provided a baseline for what to implement first.
+
+
+
+$XFree86: xc/programs/Xserver/hw/xfree86/xaa/NOTES,v 3.20 1998/07/26 00:40:48 dawes Exp $
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/XAA.HOWTO b/xc/programs/Xserver/hw/xfree86/xaa/XAA.HOWTO
new file mode 100644
index 000000000..e70bbf260
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/XAA.HOWTO
@@ -0,0 +1,1438 @@
+
+
+ XAA.HOWTO
+
+ This file describes how to add basic XAA support to a chipset driver.
+For a more in-depth discussion of XAA, one should read the XAA.DESIGN
+document as well.
+
+0) What is XAA
+1) XAA Initialization and Shutdown
+2) The Primitives
+ 2.0 Generic Flags
+ 2.1 Screen to Screen Copies
+ 2.2 Solid Fills
+ 2.3 Solid Lines
+ 2.4 Dashed Lines
+ 2.5 Color Expand Fills
+ 2.5.1 Screen to Screen Color Expansion
+ 2.5.2 CPU to Screen Color Expansion
+ 2.5.2.1 The Direct Method
+ 2.5.2.2 The Indirect Method
+ 2.6 8x8 Mono Pattern Fills
+ 2.7 8x8 Color Pattern Fills
+ 2.8 Image Writes
+ 2.8.1 The Direct Method
+ 2.8.2 The Indirect Method
+ 2.9 Image Reads
+ 2.10 Clipping
+3) The Pixmap Cache
+4) Offscreen Pixmaps
+
+/********************************************************************/
+
+0) WHAT IS XAA
+
+ XAA (the XFree86 Acceleration Architecture) is a device dependent
+layer that encapsulates the unaccelerated framebuffer rendering layer,
+intercepting rendering commands sent to it from higher levels of the
+server. For rendering tasks where hardware acceleration is not
+possible, XAA allows the requests to proceed to the software rendering
+code. Otherwise, XAA breaks the sometimes complicated X primitives
+into simpler primitives more suitable for hardware acceleration and
+will use accelerated functions exported by the chipset driver to
+render these.
+
+ XAA provides a simple, easy to use driver interface that allows
+the driver to communicate its acceleration capabilities and restrictions
+back to XAA. XAA will use the information provided by the driver
+to determine whether or not acceleration will be possible for a
+particular X primitive.
+
+
+
+1) XAA INITIALIZATION AND SHUTDOWN
+
+ All relevant prototypes and defines are in xaa.h.
+
+ To Initialize the XAA layer, the driver should allocate an XAAInfoRec
+via XAACreateInfoRec(), fill it out as described in this document
+and pass it to XAAInit(). XAAInit() must be called _after_ the
+framebuffer initialization (usually cfb?ScreenInit or similar) since
+it is "wrapping" that layer. XAAInit() should be called _before_ the
+cursor initialization (usually miDCInitialize) since the cursor
+layer needs to "wrap" all the rendering code including XAA.
+
+ When shutting down, the driver should free the XAAInfoRec
+structure in its CloseScreen function via XAADestroyInfoRec().
+The prototypes for the functions mentioned above are as follows:
+
+ XAAInfoRecPtr XAACreateInfoRec(void);
+ Bool XAAInit(ScreenPtr, XAAInfoRecPtr);
+ void XAADestroyInfoRec(XAAInfoRec);
+
+ The driver informs XAA of it's acceleration capablities by
+filling out an XAAInfoRec structure and passing it to XAAInit().
+The XAAInfoRec structure contains many fields, most of which are
+function pointers and flags. Each primitive will typically have
+two functions and a set of flags associated with it, but it may
+have more. These two functions are the "SetupFor" and "Subsequent"
+functions. The "SetupFor" function tells the driver that the
+hardware should be initialized for a particular type of graphics
+operation. After the "SetupFor" function, one or more calls to the
+"Subsequent" function will be made to indicate that an instance
+of the particular primitive should be rendered by the hardware.
+The details of each instance (width, height, etc...) are given
+with each "Subsequent" function. The set of flags associated
+with each primitive lets the driver tell XAA what its hardware
+limitations are (eg. It doesn't support a planemask, it can only
+do one of the raster-ops, etc...).
+
+ Of the XAAInfoRec fields, one is required. This is the
+Sync function. XAA initialization will fail if this function
+is not provided.
+
+void Sync(ScrnInfoPtr pScrn) /* Required */
+
+ Sync will be called when XAA needs to be certain that all
+ graphics coprocessor operations are finished, such as when
+ the framebuffer must be written to or read from directly
+ and it must be certain that the accelerator will not be
+ overwriting the area of interest.
+
+ One needs to make certain that the Sync function not only
+ waits for the accelerator fifo to empty, but that it waits for
+ the rendering of that last operation to complete.
+
+ It is guaranteed that no direct framebuffer access will
+ occur after a "SetupFor" or "Subsequent" function without
+ the Sync function being called first.
+
+
+
+2) THE PRIMITIVES
+
+2.0 Generic Flags
+
+ Each primitive type has a set of flags associated with it which
+allow the driver to tell XAA what the hardware limitations are.
+The common ones are as follows:
+
+/* Foreground, Background, rop and planemask restrictions */
+
+ GXCOPY_ONLY
+
+ This indicates that the accelerator only supports GXcopy
+ for the particular primitive.
+
+ ROP_NEEDS_SOURCE
+
+ This indicates that the accelerator doesn't supports a
+ particular primitive with rops that don't involve the source.
+ These rops are GXclear, GXnoop, GXinvert and GXset. If neither
+ this flag nor GXCOPY_ONLY is defined, it is assumed that the
+ accelerator supports all 16 raster operations (rops) for that
+ primitive.
+
+ NO_PLANEMASK
+
+ This indicates that the accelerator does not support a hardware
+ write planemask for the particular primitive.
+
+ RGB_EQUAL
+
+ This indicates that the particular primitive requires the red,
+ green and blue bytes of the foreground color (and background color,
+ if applicable) to be equal. This is useful for 24bpp when a graphics
+ coprocessor is used in 8bpp mode, which is not uncommon in older
+ hardware since some have no support for or only limited support for
+ acceleration at 24bpp. This way, many operations will be accelerated
+ for the common case of "grayscale" colors. This flag should only
+ be used in 24bpp.
+
+ In addition to the common ones listed above which are possible for
+nearly all primitives, each primitive may have its own flags specific
+to that primitive. If such flags exist they are documented in the
+descriptions of those primitives below.
+
+
+
+
+2.1 Screen to Screen Copies
+
+ The SetupFor and Subsequent ScreenToScreenCopy functions provide
+ an interface for copying rectangular areas from video memory to
+ video memory. To accelerate this primitive the driver should
+ provide both the SetupFor and Subsequent functions and indicate
+ the hardware restrictions via the ScreenToScreenCopyFlags. The
+ NO_PLANEMASK, GXCOPY_ONLY and ROP_NEEDS_SOURCE flags as described
+ in Section 2.0 are valid as well as the following:
+
+ NO_TRANSPARENCY
+
+ This indicates that the accelerator does not support skipping
+ of color keyed pixels when copying from the source to the destination.
+
+ TRANSPARENCY_GXCOPY_ONLY
+
+ This indicates that the accelerator supports skipping of color keyed
+ pixels only when the rop is GXcopy.
+
+ ONLY_LEFT_TO_RIGHT_BITBLT
+
+ This indicates that the hardware only accepts blitting when the
+ x direction is positive.
+
+ ONLY_TWO_BITBLT_DIRECTIONS
+
+ This indicates that the hardware can only cope with blitting when
+ the direction of x is the same as the direction in y.
+
+
+void SetupForScreenToScreenCopy( ScrnInfoPtr pScrn,
+ int xdir, int ydir,
+ int rop,
+ unsigned int planemask,
+ int trans_color )
+
+ When this is called, SubsequentScreenToScreenCopy will be called
+ one or more times directly after. If ydir is 1, then the accelerator
+ should copy starting from the top (minimum y) of the source and
+ proceed downward. If ydir is -1, then the accelerator should copy
+ starting from the bottom of the source (maximum y) and proceed
+ upward. If xdir is 1, then the accelerator should copy each
+ y scanline starting from the leftmost pixel of the source. If
+ xdir is -1, it should start from the rightmost pixel.
+ If trans_color is not -1 then trans_color indicates that the
+ accelerator should not copy pixels with the color trans_color
+ from the source to the destination, but should skip them.
+ Trans_color is always -1 if the NO_TRANSPARENCY flag is set.
+
+
+void SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1,
+ int x2, int y2,
+ int width, int height)
+
+ Copy a rectangle "width" x "height" from the source (x1,y1) to the
+ destination (x2,y2) using the parameters passed by the last
+ SetupForScreenToScreenCopy call. (x1,y1) and (x2,y2) always denote
+ the upper left hand corners of the source and destination regardless
+ of which xdir and ydir values are given by SetupForScreenToScreenCopy.
+
+
+
+2.2 Solid Fills
+
+ The SetupFor and Subsequent SolidFill(Rect/Trap) functions provide
+ an interface for filling rectangular areas of the screen with a
+ foreground color. To accelerate this primitive the driver should
+ provide both the SetupForSolidFill and SubsequentSolidFillRect
+ functions and indicate the hardware restrictions via the SolidFillFlags.
+ The driver may optionally provide a SubsequentSolidFillTrap if
+ it is capable of rendering the primitive correctly.
+ The GXCOPY_ONLY, ROP_NEEDS_SOURCE, NO_PLANEMASK and RGB_EQUAL flags
+ as described in Section 2.0 are valid.
+
+
+void SetupForSolidFill(ScrnInfoPtr pScrn,
+ int color, int rop, unsigned int planemask)
+
+ SetupForSolidFill indicates that any combination of the following
+ may follow it.
+
+ SubsequentSolidFillRect
+ SubsequentSolidFillTrap
+
+
+
+void SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+
+ Fill a rectangle of dimensions "w" by "h" with origin at (x,y)
+ using the color, rop and planemask given by the last
+ SetupForSolidFill call.
+
+void SubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR)
+
+ These parameters describe a trapezoid via a version of
+ Bresenham's parameters. "y" is the top line. "h" is the
+ number of spans to be filled in the positive Y direction.
+ "left" and "right" indicate the starting X values of the
+ left and right edges. dy/dx describes the edge slope.
+ These are not the deltas between the beginning and ending
+ points on an edge. They merely describe the slope. "e" is
+ the initial error term. It's the relationships between dx,
+ dy and e that define the edge.
+ If your engine does not do bresenham trapezoids or does
+ not allow the programmer to specify the error term then
+ you are not expected to be able to accelerate them.
+
+
+2.3 Solid Lines
+
+ XAA provides an interface for drawing thin lines. In order to
+ draw X lines correctly a high degree of accuracy is required.
+ This usually limits line acceleration to hardware which has a
+ Bresenham line engine, though depending on the algorithm used,
+ other line engines may come close if they accept 16 bit line
+ deltas. XAA has both a Bresenham line interface and a two-point
+ line interface for drawing lines of arbitrary orientation.
+ Additionally there is a SubsequentSolidHorVertLine which will
+ be used for all horizontal and vertical lines. Horizontal and
+ vertical lines are handled separately since hardware that doesn't
+ have a line engine (or has one that is unusable due to precision
+ problems) can usually draw these lines by some other method such
+ as drawing them as thin rectangles. Even for hardware that can
+ draw arbitrary lines via the Bresenham or two-point interfaces,
+ the SubsequentSolidHorVertLine is used for horizontal and vertical
+ lines since most hardware is able to render the horizontal lines
+ and sometimes the vertical lines faster by other methods (Hint:
+ try rendering horizontal lines as flattened rectangles). If you have
+ not provided a SubsequentSolidHorVertLine but you have provided
+ Bresenham or two-point lines, a SubsequentSolidHorVertLine function
+ will be supplied for you.
+
+ The flags field associated with Solid Lines is SolidLineFlags and
+ the GXCOPY_ONLY, ROP_NEEDS_SOURCE, NO_PLANEMASK and RGB_EQUAL flags as
+ described in Section 2.0 are valid restrictions.
+
+ Some line engines have line biases hardcoded to comply with
+ Microsoft line biasing rules. A tell-tale sign of this is the
+ hardware lines not matching the software lines in the zeroth and
+ fourth octants. The driver can set the flag:
+
+ MICROSOFT_ZERO_LINE_BIAS
+
+ in the AccelInfoRec.Flags field to adjust the software lines to
+ match the hardware lines. This is in the generic flags field
+ rather than the SolidLineFlags since this flag applies to all
+ software zero-width lines on the screen and not just the solid ones.
+
+
+void SetupForSolidLine(ScrnInfoPtr pScrn,
+ int color, int rop, unsigned int planemask)
+
+ SetupForSolidLine indicates that any combination of the following
+ may follow it.
+
+ SubsequentSolidBresenhamLine
+ SubsequentSolidTwoPointLine
+ SubsequentSolidHorVertLine
+
+
+void SubsequentSolidHorVertLine( ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir )
+
+ All vertical and horizontal solid thin lines are rendered with
+ this function. The line starts at coordinate (x,y) and extends
+ "len" pixels inclusive. In the direction indicated by "dir."
+ The direction is either DEGREES_O or DEGREES_270. That is, it
+ always extends to the right or down.
+
+
+
+void SubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags)
+
+ Draw a line from (x1,y1) to (x2,y2). If the flags field contains
+ the flag OMIT_LAST, the last pixel should not be drawn. Otherwise,
+ the pixel at (x2,y2) should be drawn.
+
+ If you use the TwoPoint line interface there is a good possibility
+ that your line engine has hard-coded line biases that do not match
+ the default X zero-width lines. If so, you may need to set the
+ MICROSOFT_ZERO_LINE_BIAS flag described above. Note that since
+ any vertex in the 16-bit signed coordinate system is valid, your
+ line engine is expected to handle 16-bit values if you have hardware
+ line clipping enabled. If your engine cannot handle 16-bit values,
+ you should not use hardware line clipping.
+
+
+void SubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
+ int x, int y, int major, int minor, int err, int len, int octant)
+
+ "X" and "y" are the starting point of the line. "Major" and "minor"
+ are the major and minor step constants. "Err" is the initial error
+ term. "Len" is the number of pixels to be drawn (inclusive). "Octant"
+ can be any combination of the following flags OR'd together:
+
+ Y_MAJOR Y is the major axis (X otherwise)
+ X_DECREASING The line is drawn from right to left
+ Y_DECREASING The line is drawn from bottom to top
+
+ The major, minor and err terms are the "raw" Bresenham parameters
+ consistent with a line engine that does:
+
+ e = err;
+ while(len--) {
+ DRAW_POINT(x,y);
+ e += minor;
+ if(e >= 0) {
+ e -= major;
+ TAKE_ONE_STEP_ALONG_MINOR_AXIS;
+ }
+ TAKE_ONE_STEP_ALONG_MAJOR_AXIS;
+ }
+
+ IBM 8514 style Bresenham line interfaces require their parameters
+ modified in the following way:
+
+ Axial = minor;
+ Diagonal = minor - major;
+ Error = minor + err;
+
+SolidBresenhamLineErrorTermBits
+
+ This field allows the driver to tell XAA how many bits large its
+ Bresenham parameter registers are. Many engines have registers that
+ only accept 12 or 13 bit Bresenham parameters, and the parameters
+ for clipped lines may overflow these if they are not scaled down.
+ If this field is not set, XAA will assume the engine can accomodate
+ 16 bit parameters, otherwise, it will scale the parameters to the
+ size specified.
+
+
+2.4 Dashed Lines
+
+ The same degree of accuracy required by the solid lines is required
+ for drawing dashed lines as well. The dash pattern itself is a
+ buffer of binary data where ones are expanded into the foreground
+ color and zeros either correspond to the background color or
+ indicate transparency depending on whether or not DoubleDash or
+ OnOffDashes are being drawn.
+
+ The flags field associated with dashed Lines is DashedLineFlags and
+ the GXCOPY_ONLY, ROP_NEEDS_SOURCE, NO_PLANEMASK and RGB_EQUAL flags as
+ described in Section 2.0 are valid restrictions. Additionally, the
+ following flags are valid:
+
+ NO_TRANSPARENCY
+
+ This indicates that the driver cannot support dashed lines
+ with transparent backgrounds (OnOffDashes).
+
+ TRANSPARENCY_ONLY
+
+ This indicates that the driver cannot support dashes with
+ both a foreground and background color (DoubleDashes).
+
+ LINE_PATTERN_POWER_OF_2_ONLY
+
+ This indicates that only patterns with a power of 2 length
+ can be accelerated.
+
+ LINE_PATTERN_LSBFIRST_MSBJUSTIFIED
+ LINE_PATTERN_LSBFIRST_LSBJUSTIFIED
+ LINE_PATTERN_MSBFIRST_MSBJUSTIFIED
+ LINE_PATTERN_MSBFIRST_LSBJUSTIFIED
+
+ These describe how the line pattern should be packed.
+ The pattern buffer is DWORD padded. LSBFIRST indicates
+ that the pattern runs from the LSB end to the MSB end.
+ MSBFIRST indicates that the pattern runs from the MSB end
+ to the LSB end. When the pattern does not completely fill
+ the DWORD padded buffer, the pattern will be justified
+ towards the MSB or LSB end based on the flags above.
+
+
+ The following field indicates the maximum length dash pattern that
+ should be accelerated.
+
+ int DashPatternMaxLength
+
+
+void SetupForDashedLine(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop, unsigned int planemask,
+ int length, unsigned char *pattern)
+
+
+ SetupForDashedLine indicates that any combination of the following
+ may follow it.
+
+ SubsequentDashedBresenhamLine
+ SubsequentDashedTwoPointLine
+
+ If "bg" is -1, then the background (pixels corresponding to clear
+ bits in the pattern) should remain unmodified. "Bg" indicates the
+ background color otherwise. "Length" indicates the length of
+ the pattern in bits and "pattern" points to the DWORD padded buffer
+ holding the pattern which has been packed according to the flags
+ set above.
+
+
+void SubsequentDashedTwoPointLine( ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags, int phase)
+
+void SubsequentDashedBresenhamLine(ScrnInfoPtr pScrn,
+ int x1, int y1, int major, int minor, int err, int len, int octant,
+ int phase)
+
+ These are the same as the SubsequentSolidTwoPointLine and
+ SubsequentBresenhamLine functions except for the addition
+ of the "phase" field which indicates the offset into the dash
+ pattern that the pixel at (x1,y1) corresponds to.
+
+ As with the SubsequentBresenhamLine, there is an
+
+ int DashedBresenhamLineErrorTermBits
+
+ field which indicates the size of the error term registers
+ used with dashed lines. This is usually the same value as
+ the field for the solid lines (because it's usually the same
+ register).
+
+
+
+2.5 Color Expansion Fills
+
+ When filling a color expansion rectangle, the accelerator
+ paints each pixel depending on whether or not a bit in a
+ corresponding bitmap is set or clear. Opaque expansions are
+ when a set bit corresponds to the foreground color and a clear
+ bit corresponds to the background color. A transparent expansion
+ is when a set bit corresponds to the foreground color and a
+ clear bit indicates that the pixel should remain unmodified.
+
+ The graphics accelerator usually has access to the source
+ bitmap in one of two ways: 1) the bitmap data is sent serially
+ to the accelerator by the CPU through some memory mapped aperture
+ or 2) the accelerator reads the source bitmap out of offscreen
+ video memory. Some types of primitives are better suited towards
+ one method or the other. Type 2 is useful for reusable patterns
+ such as stipples which can be cached in offscreen memory. The
+ aperature method can be used for stippling but the CPU must pass
+ the data across the bus each time a stippled fill is to be performed.
+ For expanding 1bpp client pixmaps or text strings to the screen,
+ the aperature method is usually superior because the intermediate
+ copy in offscreen memory needed by the second method would only be
+ used once. Unfortunately, many accelerators can only do one of these
+ methods and not both.
+
+ XAA provides both ScreenToScreen and CPUToScreen color expansion
+ interfaces for doing color expansion fills. The ScreenToScreen
+ functions can only be used with hardware that supports reading
+ of source bitmaps from offscreen video memory, and these are only
+ used for cacheable patterns such as stipples. There are two
+ variants of the CPUToScreen routines - a direct method intended
+ for hardware that has a transfer aperature, and an indirect method
+ intended for hardware without transfer aperatures or hardware
+ with unusual transfer requirements. Hardware that can only expand
+ bitmaps from video memory should supply ScreenToScreen routines
+ but also ScanlineCPUToScreen (indirect) routines to optimize transfers
+ of non-cacheable data. Hardware that can only accept source bitmaps
+ through an aperature should supply CPUToScreen (or ScanlineCPUToScreen)
+ routines. Hardware that can do both should provide both ScreenToScreen
+ and CPUToScreen routines.
+
+ For both ScreenToScreen and CPUToScreen interfaces, the GXCOPY_ONLY,
+ ROP_NEEDS_SOURCE, NO_PLANEMASK and RGB_EQUAL flags described in
+ Section 2.0 are valid as well as the following:
+
+ /* bit order requirements (one of these must be set) */
+
+ BIT_ORDER_IN_BYTE_LSBFIRST
+
+ This indicates that least significant bit in each byte of the source
+ data corresponds to the leftmost of that block of 8 pixels. This
+ is the prefered format.
+
+ BIT_ORDER_IN_BYTE_MSBFIRST
+
+ This indicates that most significant bit in each byte of the source
+ data corresponds to the leftmost of that block of 8 pixels.
+
+ /* transparency restrictions */
+
+ NO_TRANSPARENCY
+
+ This indicates that the accelerator cannot do a transparent expansion.
+
+ TRANSPARENCY_ONLY
+
+ This indicates that the accelerator cannot do an opaque expansion.
+ In cases where where the background needs to be filled, XAA will
+ render the primitive in two passes when using the CPUToScreen
+ interface, but will not do so with the ScreenToScreen interface
+ since that would require caching of two patterns. Some
+ ScreenToScreen hardware may be able to render two passes at the
+ driver level and remove the TRANSPARENCY_ONLY restriction if
+ it can render pixels corresponding to the zero bits.
+
+
+
+2.5.1 Screen To Screen Color Expansion
+
+ The ScreenToScreenColorExpandFill routines provide an interface
+ for doing expansion blits from source patterns stored in offscreen
+ video memory.
+
+ void SetupForScreenToScreenColorExpandFill (ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop, unsigned int planemask)
+
+
+ Ones in the source bitmap will correspond to the fg color.
+ Zeros in the source bitmap will correspond to the bg color
+ unless bg = -1. In that case the pixels corresponding to the
+ zeros in the bitmap shall be left unmodified by the accelerator.
+
+ For hardware that doesn't allow an easy implementation of skipleft, the
+ driver can replace CacheMonoStipple function with one that stores multiple
+ rotated copies of the stipple and select between them. In this case the
+ driver should set CacheColorExpandDensity to tell XAA how many copies of
+ the pattern are stored in the width of a cache slot. For instance if the
+ hardware can specify the starting address in bytes, then 8 rotated copies
+ of the stipple are needed and CacheColorExpandDensity should be set to 8.
+
+ void SubsequentScreenToScreenColorExpandFill( ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int offset )
+
+
+ Fill a rectangle "w" x "h" at location (x,y). The source pitch
+ between scanlines is the framebuffer pitch (pScrn->displayWidth
+ pixels) and srcx and srcy indicate the start of the source pattern
+ in units of framebuffer pixels. "Offset" indicates the bit offset
+ into the pattern that corresponds to the pixel being painted at
+ "x" on the screen. Some hardware accepts source coordinates in
+ units of bits which makes implementation of the offset trivial.
+ In that case, the bit address of the source bit corresponding to
+ the pixel painted at (x,y) would be:
+
+ (srcy * pScrn->displayWidth + srcx) * pScrn->bitsPerPixel + offset
+
+ It should be noted that the offset assumes LSBFIRST hardware.
+ For MSBFIRST hardware, the driver may need to implement the
+ offset by bliting only from byte boundaries and hardware clipping.
+
+
+
+2.5.2 CPU To Screen Color Expansion
+
+
+ The CPUToScreenColorExpandFill routines provide an interface for
+ doing expansion blits from source patterns stored in system memory.
+ There are two varieties of this primitive, a CPUToScreenColorExpandFill
+ and a ScanlineCPUToScreenColorExpandFill. With the
+ CPUToScreenColorExpandFill method, the source data is sent serially
+ through a memory mapped aperature. With the Scanline version, the
+ data is rendered scanline at a time into intermediate buffers with
+ a call to SubsequentColorExpandScanline following each scanline.
+
+ These two methods have separate flags fields, the
+ CPUToScreenColorExpandFillFlags and ScanlineCPUToScreenColorExpandFillFlags
+ respectively. Flags specific to one method or the other are described
+ in sections 2.5.2.1 and 2.5.2.2 but for both cases the bit order and
+ transparency restrictions listed at the beginning of section 2.5 are
+ valid as well as the following:
+
+ /* clipping (optional) */
+
+ LEFT_EDGE_CLIPPING
+
+ This indicates that the accelerator supports omission of up to
+ 31 pixels on the left edge of the rectangle to be filled. This
+ is beneficial since it allows transfer of the source bitmap to
+ always occur from DWORD boundaries.
+
+ LEFT_EDGE_CLIPPING_NEGATIVE_X
+
+ This flag indicates that the accelerator can render color expansion
+ rectangles even if the value of x origin is negative (off of
+ the screen on the left edge).
+
+ /* misc */
+
+ TRIPLE_BITS_24BPP
+
+ When enabled (must be in 24bpp mode), color expansion functions
+ are expected to require three times the amount of bits to be
+ transferred so that 24bpp grayscale colors can be used with color
+ expansion in 8bpp coprocessor mode. Each bit is expanded to 3
+ bits when writing the monochrome data. When definining this
+ flag, also define RGB_EQUAL.
+
+
+ 2.5.1 The Direct Method
+
+
+ Using the direct method of color expansion XAA will send all
+ bitmap data to the accelerator serially through an memory mapped
+ transfer window defined by the following two fields:
+
+ unsigned char *ColorExpandBase
+
+ This indicates the memory address of the beginning of the aperture.
+
+ int ColorExpandRange
+
+ This indicates the size in bytes of the aperture.
+
+ The driver should specify how the transfered data should be padded.
+ There are options for both the padding of each Y scanline and for the
+ total transfer to the aperature.
+ One of the following two flags must be set:
+
+ CPU_TRANSFER_PAD_DWORD
+
+ This indicates that the total transfer (sum of all scanlines) sent
+ to the aperature must be DWORD padded. This is the default behavior.
+
+ CPU_TRANSFER_PAD_QWORD
+
+ This indicates that the total transfer (sum of all scanlines) sent
+ to the aperature must be QWORD padded. With this set, XAA will send
+ an extra DWORD to the aperature when needed to ensure that only
+ an even number of DWORDs are sent.
+
+ And then there are the flags for padding of each scanline:
+
+ SCANLINE_PAD_DWORD
+
+ This indicates that each Y scanline should be DWORD padded.
+ This is the only option available and is the default.
+
+ Finally, there is the CPU_TRANSFER_BASE_FIXED flag which indicates
+ that the aperture is a single register rather than a range of
+ registers, and XAA should write all of the data to the first DWORD.
+ If the ColorExpandRange is not large enough to accomodate scanlines
+ the width of the screen, this option will be forced. That is, the
+ ColorExpandRange must be:
+
+ ((virtualX + 31)/32) * 4 bytes or more.
+
+ ((virtualX + 62)/32 * 4) if LEFT_EDGE_CLIPPING_NEGATIVE_X is set.
+
+ If the TRIPLE_BITS_24BPP flag is set, the required area should be
+ multiplied by three.
+
+
+void SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask)
+
+
+
+ Ones in the source bitmap will correspond to the fg color.
+ Zeros in the source bitmap will correspond to the bg color
+ unless bg = -1. In that case the pixels corresponding to the
+ zeros in the bitmap shall be left unmodified by the accelerator.
+
+
+void SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft )
+
+ When this function is called, the accelerator should be setup
+ to fill a rectangle of dimension "w" by "h" with origin at (x,y)
+ in the fill style prescribed by the last call to
+ SetupForCPUToScreenColorExpandFill. XAA will pass the data to
+ the aperture immediately after this function is called. If the
+ skipleft is non-zero (and LEFT_EDGE_CLIPPING has been enabled), then
+ the accelerator _should_not_ render skipleft pixels on the leftmost
+ edge of the rectangle. Some engines have an alignment feature
+ like this built in, some others can do this using a clipping
+ window.
+
+ It can be arranged for XAA to call Sync() after it is through
+ calling the Subsequent function by setting SYNC_AFTER_COLOR_EXPAND
+ in the CPUToScreenColorExpandFillFlags. This can provide the driver
+ with an oportunity to reset a clipping window if needed.
+
+
+2.5.2 The Indirect Method
+
+ Using the indirect method, XAA will render the bitmap data scanline
+ at a time to one or more buffers. These buffers may be memory
+ mapped apertures or just intermediate storage.
+
+ int NumScanlineColorExpandBuffers
+
+ This indicates the number of buffers available.
+
+ unsigned char **ScanlineColorExpandBuffers
+
+ This is an array of pointers to the memory locations of each buffer.
+ Each buffer is expected to be large enough to accommodate scanlines
+ the width of the screen. That is:
+
+ ((virtualX + 31)/32) * 4 bytes or more.
+
+ ((virtualX + 62)/32 * 4) if LEFT_EDGE_CLIPPING_NEGATIVE_X is set.
+
+ Scanlines are always DWORD padded.
+ If the TRIPLE_BITS_24BPP flag is set, the required area should be
+ multiplied by three.
+
+
+void SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask)
+
+ Ones in the source bitmap will correspond to the fg color.
+ Zeros in the source bitmap will correspond to the bg color
+ unless bg = -1. In that case the pixels corresponding to the
+ zeros in the bitmap shall be left unmodified by the accelerator.
+
+
+void SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft )
+
+void SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+
+
+ When SubsequentScanlineCPUToScreenColorExpandFill is called, XAA
+ will begin transfering the source data scanline at a time, calling
+ SubsequentColorExpandScanline after each scanline. If more than
+ one buffer is available, XAA will cycle through the buffers.
+ Subsequent scanlines will use the next buffer and go back to the
+ buffer 0 again when the last buffer is reached. The index into
+ the ScanlineColorExpandBuffers array is presented as "bufno"
+ with each SubsequentColorExpandScanline call.
+
+ The skipleft field is the same as for the direct method.
+
+ The indirect method can be use to send the source data directly
+ to a memory mapped aperture represented by a single color expand
+ buffer, scanline at a time, but more commonly it is used to place
+ the data into offscreen video memory so that the accelerator can
+ blit it to the visible screen from there. In the case where the
+ accelerator permits rendering into offscreen video memory while
+ the accelerator is active, several buffers can be used so that
+ XAA can be placing source data into the next buffer while the
+ accelerator is blitting the current buffer. For cases where
+ the accelerator requires some special manipulation of the source
+ data first, the buffers can be in system memory. The CPU can
+ manipulate these buffers and then send the data to the accelerator.
+
+
+
+2.6 8x8 Mono Pattern Fills
+
+ XAA provides support for two types of 8x8 hardware patterns -
+ "Mono" patterns and "Color" patterns. Mono pattern data is
+ 64 bits of color expansion data with ones indicating the
+ foreground color and zeros indicating the background color.
+ The source bitmaps for the 8x8 mono patterns can be presented
+ to the graphics accelerator in one of two ways. They can be
+ passed as two DWORDS to the 8x8 mono pattern functions or
+ they can be cached in offscreen memory and their locations
+ passed to the 8x8 mono pattern functions. In addition to the
+ GXCOPY_ONLY, ROP_NEEDS_SOURCE, NO_PLANEMASK and RGB_EQUAL flags
+ defined in Section 2.0, the following are defined for the
+ Mono8x8PatternFillFlags:
+
+ HARDWARE_PATTERN_PROGRAMMED_BITS
+
+ This indicates that the 8x8 patterns should be packed into two
+ DWORDS and passed to the 8x8 mono pattern functions. The default
+ behavior is to cache the patterns in offscreen video memory and
+ pass the locations of these patterns to the functions instead.
+ The pixmap cache must be enabled for the default behavior (8x8
+ pattern caching) to work. See Section 3 for how to enable the
+ pixmap cache. The pixmap cache is not necessary for
+ HARDWARE_PATTERN_PROGRAMMED_BITS.
+
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN
+
+ If the hardware supports programmable pattern offsets then
+ this option should be set. See the table below for further
+ infomation.
+
+ HARDWARE_PATTERN_SCREEN_ORIGIN
+
+ Some hardware wants the pattern offset specified with respect to the
+ upper left-hand corner of the primitive being drawn. Other hardware
+ needs the option HARDWARE_PATTERN_SCREEN_ORIGIN set to indicate that
+ all pattern offsets should be referenced to the upper left-hand
+ corner of the screen. HARDWARE_PATTERN_SCREEN_ORIGIN is preferable
+ since this is more natural for the X-Window system and offsets will
+ have to be recalculated for each Subsequent function otherwise.
+
+ BIT_ORDER_IN_BYTE_MSBFIRST
+ BIT_ORDER_IN_BYTE_LSBFIRST
+
+ As with other color expansion routines this indicates whether the
+ most or the least significant bit in each byte from the pattern is
+ the leftmost on the screen.
+
+ TRANSPARENCY_ONLY
+ NO_TRANSPARENCY
+
+ This means the same thing as for the color expansion rect routines
+ except that for TRANSPARENCY_ONLY XAA will not render the primitive
+ in two passes since this is more easily handled by the driver.
+ It is recommended that TRANSPARENCY_ONLY hardware handle rendering
+ of opaque patterns in two passes (the background can be filled as
+ a rectangle in GXcopy) in the Subsequent function so that the
+ TRANSPARENCY_ONLY restriction can be removed.
+
+
+
+ Additional information about cached patterns...
+ For the case where HARDWARE_PATTERN_PROGRAMMED_BITS is not set and
+ the pattern must be cached in offscreen memory, the first pattern
+ starts at the cache slot boundary which is set by the
+ CachePixelGranularity field used to configure the pixmap cache.
+ One should ensure that the CachePixelGranularity reflects any
+ alignment restrictions that the accelerator may put on 8x8 pattern
+ storage locations. When HARDWARE_PATTERN_PROGRAMMED_ORIGIN is set
+ there is only one pattern stored. When this flag is not set,
+ all 64 pre-rotated copies of the pattern are cached in offscreen memory.
+ The MonoPatternPitch field can be used to specify the X position pixel
+ granularity that each of these patterns must align on. If the
+ MonoPatternPitch is not supplied, the patterns will be densely packed
+ within the cache slot. The behavior of the default XAA 8x8 pattern
+ caching mechanism to store all 8x8 patterns linearly in video memory.
+ If the accelerator needs the patterns stored in a more unusual fashion,
+ the driver will need to provide its own 8x8 mono pattern caching
+ routines for XAA to use. How to do this will be described in the
+ XAA.DESIGN document.
+
+ The following table describes the meanings of the "patx" and "paty"
+ fields in both the SetupFor and Subsequent functions.
+
+ With HARDWARE_PATTERN_SCREEN_ORIGIN
+ -----------------------------------
+
+ HARDWARE_PATTERN_PROGRAMMED_BITS and HARDWARE_PATTERN_PROGRAMMED_ORIGIN
+
+ SetupFor: patx and paty are the first and second DWORDS of the
+ 8x8 mono pattern.
+
+ Subsequent: patx and paty are the x,y offset into that pattern.
+ All Subsequent calls will have the same offset in
+ the case of HARDWARE_PATTERN_SCREEN_ORIGIN so only
+ the offset specified by the first Subsequent call
+ after a SetupFor call will need to be observed.
+
+ HARDWARE_PATTERN_PROGRAMMED_BITS only
+
+ SetupFor: patx and paty hold the first and second DWORDS of
+ the 8x8 mono pattern pre-rotated to match the desired
+ offset.
+
+ Subsequent: These just hold the same patterns and can be ignored.
+
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN only
+
+ SetupFor: patx and paty hold the x,y coordinates of the offscreen
+ memory location where the 8x8 pattern is stored. The
+ bits are stored linearly in memory at that location.
+
+ Subsequent: patx and paty hold the offset into the pattern.
+ All Subsequent calls will have the same offset in
+ the case of HARDWARE_PATTERN_SCREEN_ORIGIN so only
+ the offset specified by the first Subsequent call
+ after a SetupFor call will need to be observed.
+
+ Neither programmed bits or origin
+
+ SetupFor: patx and paty hold the x,y coordinates of the offscreen
+ memory location where the pre-rotated 8x8 pattern is
+ stored.
+
+ Subsequent: patx and paty are the same as in the SetupFor function
+ and can be ignored.
+
+
+ Without HARDWARE_PATTERN_SCREEN_ORIGIN
+ --------------------------------------
+
+ HARDWARE_PATTERN_PROGRAMMED_BITS and HARDWARE_PATTERN_PROGRAMMED_ORIGIN
+
+ SetupFor: patx and paty are the first and second DWORDS of the
+ 8x8 mono pattern.
+
+ Subsequent: patx and paty are the x,y offset into that pattern.
+
+ HARDWARE_PATTERN_PROGRAMMED_BITS only
+
+ SetupFor: patx and paty holds the first and second DWORDS of
+ the unrotated 8x8 mono pattern. This can be ignored.
+
+ Subsequent: patx and paty hold the rotated 8x8 pattern to be
+ rendered.
+
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN only
+
+ SetupFor: patx and paty hold the x,y coordinates of the offscreen
+ memory location where the 8x8 pattern is stored. The
+ bits are stored linearly in memory at that location.
+
+ Subsequent: patx and paty hold the offset into the pattern.
+
+ Neither programmed bits or origin
+
+ SetupFor: patx and paty hold the x,y coordinates of the offscreen
+ memory location where the unrotated 8x8 pattern is
+ stored. This can be ignored.
+
+ Subsequent: patx and paty hold the x,y coordinates of the
+ rotated 8x8 pattern to be rendered.
+
+
+
+void SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
+ int fg, int bg, int rop, unsigned int planemask)
+
+ SetupForMono8x8PatternFill indicates that any combination of the
+ following may follow it.
+
+ SubsequentMono8x8PatternFillRect
+ SubsequentMono8x8PatternFillTrap
+
+ The fg, bg, rop and planemask fields have the same meaning as the
+ ones used for the other color expansion routines. Patx's and paty's
+ meaning can be determined from the table above.
+
+
+void SubsequentMono8x8PatternFillRect( ScrnInfoPtr pScrn,
+ int patx, int paty, int x, int y, int w, int h)
+
+ Fill a rectangle of dimensions "w" by "h" with origin at (x,y)
+ using the parameters give by the last SetupForMono8x8PatternFill
+ call. The meanings of patx and paty can be determined by the
+ table above.
+
+void SubsequentMono8x8PatternFillTrap( ScrnInfoPtr pScrn,
+ int patx, int paty, int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR )
+
+ The meanings of patx and paty can be determined by the table above.
+ The rest of the fields have the same meanings as those in the
+ SubsequentSolidFillTrap function.
+
+
+
+2.7 8x8 Color Pattern Fills
+
+ 8x8 color pattern data is 64 pixels of full color data that
+ is stored linearly in offscreen video memory. 8x8 color patterns
+ are useful as a substitute for 8x8 mono patterns when tiling,
+ doing opaque stipples, or in the case where transperency is
+ supported, regular stipples. 8x8 color pattern fills also have
+ the additional benefit of being able to tile full color 8x8
+ patterns instead of just 2 color ones like the mono patterns.
+ However, full color 8x8 patterns aren't used very often in the
+ X Window system so you might consider passing this primitive
+ by if you already can do mono patterns, especially if they
+ require alot of cache area. Color8x8PatternFillFlags is
+ the flags field for this primitive and the GXCOPY_ONLY,
+ ROP_NEEDS_SOURCE and NO_PLANEMASK flags as described in
+ Section 2.0 are valid as well as the following:
+
+
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN
+
+ If the hardware supports programmable pattern offsets then
+ this option should be set.
+
+ HARDWARE_PATTERN_SCREEN_ORIGIN
+
+ Some hardware wants the pattern offset specified with respect to the
+ upper left-hand corner of the primitive being drawn. Other hardware
+ needs the option HARDWARE_PATTERN_SCREEN_ORIGIN set to indicate that
+ all pattern offsets should be referenced to the upper left-hand
+ corner of the screen. HARDWARE_PATTERN_SCREEN_ORIGIN is preferable
+ since this is more natural for the X-Window system and offsets will
+ have to be recalculated for each Subsequent function otherwise.
+
+ NO_TRANSPARENCY
+ TRANSPARENCY_GXCOPY_ONLY
+
+ These mean the same as for the ScreenToScreenCopy functions.
+
+
+ The following table describes the meanings of patx and paty passed
+ to the SetupFor and Subsequent fields:
+
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN && HARDWARE_PATTERN_SCREEN_ORIGIN
+
+ SetupFor: patx and paty hold the x,y location of the unrotated
+ pattern.
+
+ Subsequent: patx and paty hold the pattern offset. For the case
+ of HARDWARE_PATTERN_SCREEN_ORIGIN all Subsequent calls
+ have the same offset so only the first call will need
+ to be observed.
+
+
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN only
+
+ SetupFor: patx and paty hold the x,y location of the unrotated
+ pattern.
+
+ Subsequent: patx and paty hold the pattern offset.
+
+ HARDWARE_PATTERN_SCREEN_ORIGIN
+
+ SetupFor: patx and paty hold the x,y location of the rotated pattern.
+
+ Subsequent: patx and paty hold the same location as the SetupFor
+ function so these can be ignored.
+
+ neither flag
+
+ SetupFor: patx and paty hold the x,y location of the unrotated
+ pattern. This can be ignored.
+
+ Subsequent: patx and paty hold the x,y location of the rotated
+ pattern.
+
+ Additional information about cached patterns...
+ All 8x8 color patterns are cached in offscreen video memory so
+ the pixmap cache must be enabled to use them. The first pattern
+ starts at the cache slot boundary which is set by the
+ CachePixelGranularity field used to configure the pixmap cache.
+ One should ensure that the CachePixelGranularity reflects any
+ alignment restrictions that the accelerator may put on 8x8 pattern
+ storage locations. When HARDWARE_PATTERN_PROGRAMMED_ORIGIN is set
+ there is only one pattern stored. When this flag is not set,
+ all 64 rotations off the pattern are accessible but it is assumed
+ that the accelerator is capable of accessing data stored on 8
+ pixel boundaries. If the accelerator has stricter alignment
+ requirements than this the dirver will need to provide its own
+ 8x8 color pattern caching routines. How to do this will be
+ described in the XAA.DESIGN document.
+
+
+void SetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
+ int rop, unsigned int planemask, int trans_color)
+
+ SetupForColor8x8PatternFill indicates that any combination of the
+ following may follow it.
+
+ SubsequentColor8x8PatternFillRect
+ SubsequentColor8x8PatternFillTrap (not implemented yet)
+
+ For the meanings of patx and paty, see the table above. Trans_color
+ means the same as for the ScreenToScreenCopy functions.
+
+
+
+void SubsequentColor8x8PatternFillRect( ScrnInfoPtr pScrn,
+ int patx, int paty, int x, int y, int w, int h)
+
+ Fill a rectangle of dimensions "w" by "h" with origin at (x,y)
+ using the parameters give by the last SetupForColor8x8PatternFill
+ call. The meanings of patx and paty can be determined by the
+ table above.
+
+void SubsequentColor8x8PatternFillTrap( ScrnInfoPtr pScrn,
+ int patx, int paty, int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR )
+
+ For the meanings of patx and paty, see the table above.
+ The rest of the fields have the same meanings as those in the
+ SubsequentSolidFillTrap function.
+
+
+
+2.8 Image Writes
+
+ XAA provides a mechanism for transfering full color pixel data from
+ system memory to video memory through the accelerator. This is
+ useful for dealing with alignment issues and performing raster ops
+ on the data when writing it to the framebuffer. As with color
+ expansion rectangles, there is a direct and indirect method. The
+ direct method sends all data through a memory mapped aperature.
+ The indirect method sends the data to an intermediated buffer scanline
+ at a time.
+
+ The direct and indirect methods have separate flags fields, the
+ ImageWriteFlags and ScanlineImageWriteFlags respectively.
+ Flags specific to one method or the other are described in sections
+ 2.8.1 and 2.8.2 but for both cases the GXCOPY_ONLY, ROP_NEEDS_SOURCE
+ and NO_PLANEMASK flags described in Section 2.0 are valid as well as
+ the following:
+
+ NO_GXCOPY
+
+ In order to have accelerated image transfers faster than the
+ software versions for GXcopy, the engine needs to support clipping,
+ be using the direct method and have a large enough image transfer
+ range so that CPU_TRANSFER_BASE_FIXED doesn't need to be set.
+ If these are not supported, then it is unlikely that transfering
+ the data through the accelerator will be of any advantage for the
+ simple case of GXcopy. In fact, it may be much slower. For such
+ cases it's probably best to set the NO_GXCOPY flag so that
+ Image writes will only be used for the more complicated rops.
+
+ /* transparency restrictions */
+
+ NO_TRANSPARENCY
+
+ This indicates that the accelerator does not support skipping
+ of color keyed pixels when copying from the source to the destination.
+
+ TRANSPARENCY_GXCOPY_ONLY
+
+ This indicates that the accelerator supports skipping of color keyed
+ pixels only when the rop is GXcopy.
+
+ /* clipping (optional) */
+
+ LEFT_EDGE_CLIPPING
+
+ This indicates that the accelerator supports omission of up to
+ 3 pixels on the left edge of the rectangle to be filled. This
+ is beneficial since it allows transfer from the source pixmap to
+ always occur from DWORD boundaries.
+
+ LEFT_EDGE_CLIPPING_NEGATIVE_X
+
+ This flag indicates that the accelerator can fill areas with
+ image write data even if the value of x origin is negative (off of
+ the screen on the left edge).
+
+
+2.8.1 The Direct Method
+
+ Using the direct method of ImageWrite XAA will send all
+ bitmap data to the accelerator serially through an memory mapped
+ transfer window defined by the following two fields:
+
+ unsigned char *ImageWriteBase
+
+ This indicates the memory address of the beginning of the aperture.
+
+ int ImageWriteRange
+
+ This indicates the size in bytes of the aperture.
+
+ The driver should specify how the transfered data should be padded.
+ There are options for both the padding of each Y scanline and for the
+ total transfer to the aperature.
+ One of the following two flags must be set:
+
+ CPU_TRANSFER_PAD_DWORD
+
+ This indicates that the total transfer (sum of all scanlines) sent
+ to the aperature must be DWORD padded. This is the default behavior.
+
+ CPU_TRANSFER_PAD_QWORD
+
+ This indicates that the total transfer (sum of all scanlines) sent
+ to the aperature must be QWORD padded. With this set, XAA will send
+ an extra DWORD to the aperature when needed to ensure that only
+ an even number of DWORDs are sent.
+
+ And then there are the flags for padding of each scanline:
+
+ SCANLINE_PAD_DWORD
+
+ This indicates that each Y scanline should be DWORD padded.
+ This is the only option available and is the default.
+
+ Finally, there is the CPU_TRANSFER_BASE_FIXED flag which indicates
+ that the aperture is a single register rather than a range of
+ registers, and XAA should write all of the data to the first DWORD.
+ XAA will automatically select CPU_TRANSFER_BASE_FIXED if the
+ ImageWriteRange is not large enough to accomodate an entire scanline.
+
+
+void SetupForImageWrite(ScrnInfoPtr pScrn, int rop, unsigned int planemask,
+ int trans_color, int bpp, int depth)
+
+ If trans_color is not -1 then trans_color indicates the transparency
+ color key and pixels with color trans_color passed through the
+ aperature should not be transfered to the screen but should be
+ skipped. Bpp and depth indicate the bits per pixel and depth of
+ the source pixmap. Trans_color is always -1 if the NO_TRANSPARENCY
+ flag is set.
+
+
+void SubsequentImageWriteRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft)
+
+
+ Data passed through the aperature should be copied to a rectangle
+ of width "w" and height "h" with origin (x,y). If LEFT_EDGE_CLIPPING
+ has been enabled, skipleft will correspond to the number of pixels
+ on the left edge that should not be drawn. Skipleft is zero
+ otherwise.
+
+ It can be arranged for XAA to call Sync() after it is through
+ calling the Subsequent functions by setting SYNC_AFTER_IMAGE_WRITE
+ in the ImageWriteFlags. This can provide the driver with an
+ oportunity to reset a clipping window if needed.
+
+2.8.2 The Indirect Method
+
+ Using the indirect method, XAA will render the pixel data scanline
+ at a time to one or more buffers. These buffers may be memory
+ mapped apertures or just intermediate storage.
+
+ int NumScanlineImageWriteBuffers
+
+ This indicates the number of buffers available.
+
+ unsigned char **ScanlineImageWriteBuffers
+
+ This is an array of pointers to the memory locations of each buffer.
+ Each buffer is expected to be large enough to accommodate scanlines
+ the width of the screen. That is:
+
+ pScrn->VirtualX * pScreen->bitsPerPixel/8 bytes or more.
+
+ If LEFT_EDGE_CLIPPING_NEGATIVE_X is set, add an additional 4
+ bytes to that requirement in 8 and 16bpp, 12 bytes in 24bpp.
+
+ Scanlines are always DWORD padded.
+
+void SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int trans_color,
+ int bpp, int depth)
+
+ If trans_color is not -1 then trans_color indicates the transparency
+ color key and pixels with color trans_color in the buffer should not
+ be transfered to the screen but should be skipped. Bpp and depth
+ indicate the bits per pixel and depth of the source bitmap.
+ Trans_color is always -1 if the NO_TRANSPARENCY flag is set.
+
+
+void SubsequentImageWriteRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft)
+
+
+void SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
+
+
+ When SubsequentImageWriteRect is called, XAA will begin
+ transfering the source data scanline at a time, calling
+ SubsequentImageWriteScanline after each scanline. If more than
+ one buffer is available, XAA will cycle through the buffers.
+ Subsequent scanlines will use the next buffer and go back to the
+ buffer 0 again when the last buffer is reached. The index into
+ the ScanlineImageWriteBuffers array is presented as "bufno"
+ with each SubsequentImageWriteScanline call.
+
+ The skipleft field is the same as for the direct method.
+
+ The indirect method can be use to send the source data directly
+ to a memory mapped aperture represented by a single image write
+ buffer, scanline at a time, but more commonly it is used to place
+ the data into offscreen video memory so that the accelerator can
+ blit it to the visible screen from there. In the case where the
+ accelerator permits rendering into offscreen video memory while
+ the accelerator is active, several buffers can be used so that
+ XAA can be placing source data into the next buffer while the
+ accelerator is blitting the current buffer. For cases where
+ the accelerator requires some special manipulation of the source
+ data first, the buffers can be in system memory. The CPU can
+ manipulate these buffers and then send the data to the accelerator.
+
+
+2.9 Image Reads
+
+ /* More to come */
+
+
+2.10 Clipping
+
+ XAA supports hardware clipping rectangles. To use clipping
+ in this way it is expected that the graphics accelerator can
+ clip primitives with verticies anywhere in the 16 bit signed
+ coordinate system.
+
+void SetClippingRectangle ( ScrnInfoPtr pScrn,
+ int left, int top, int right, int bottom)
+
+void DisableClipping (ScrnInfoPtr pScrn)
+
+ When SetClippingRectangle is called, all hardware rendering
+ following it should be clipped to the rectangle specified
+ until DisableClipping is called.
+
+ The ClippingFlags field indicates which operations this sort
+ of Set/Disable pairing can be used with. Any of the following
+ flags may be OR'd together.
+
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY
+ HARDWARE_CLIP_MONO_8x8_FILL
+ HARDWARE_CLIP_COLOR_8x8_FILL
+ HARDWARE_CLIP_SOLID_FILL
+ HARDWARE_CLIP_DASHED_LINE
+ HARDWARE_CLIP_SOLID_LINE
+
+
+
+3) XAA PIXMAP CACHE
+
+ /* NOTE: XAA has no knowledge of framebuffer particulars so until
+ the framebuffer is able to render into offscreen memory, usage
+ of the pixmap cache requires that the driver provide ImageWrite
+ routines or a WritePixmap or WritePixmapToCache replacement so
+ that patterns can even be placed in the cache.
+
+ ADDENDUM: XAA can now load the pixmap cache without requiring
+ that the driver supply an ImageWrite function, but this can
+ only be done on linear framebuffers. If you have a linear
+ framebuffer, set LINEAR_FRAMEBUFFER in the XAAInfoRec.Flags
+ field and XAA will then be able to upload pixmaps into the
+ cache without the driver providing functions to do so.
+ */
+
+
+ The XAA pixmap cache provides a mechanism for caching of patterns
+ in offscreen video memory so that tiled fills and in some cases
+ stippling can be done by blitting the source patterns from offscreen
+ video memory. The pixmap cache also provides the mechanism for caching
+ of 8x8 color and mono hardware patterns. Any unused offscreen video
+ memory gets used for the pixmap cache and that information is
+ provided by the XFree86 Offscreen Memory Manager. XAA registers a
+ callback with the manager so that it can be informed of any changes
+ in the offscreen memory configuration. The driver writer does not
+ need to deal with any of this since it is all automatic. The driver
+ merely needs to initialize the Offscreen Memory Manager as described
+ in the DESIGN document and set the PIXMAP_CACHE flag in the
+ XAAInfoRec.Flags field. The Offscreen Memory Manager initialization
+ must occur before XAA is initialized or else pixmap cache
+ initialization will fail.
+
+ PixmapCacheFlags is an XAAInfoRec field which allows the driver to
+ control pixmap cache behavior to some extent. Currently only one
+ flag is defined:
+
+ DO_NOT_BLIT_STIPPLES
+
+ This indicates that the stippling should not be done by blitting
+ from the pixmap cache. This does not apply to 8x8 pattern fills.
+
+
+ CachePixelGranularity is an optional field. If the hardware requires
+ that a 8x8 patterns have some particular pixel alignment it should
+ be reflected in this field. Ignoring this field or setting it to
+ zero or one means there are no alignment issues.
+
+
+4) OFFSCREEN PIXMAPS
+
+ XAA has the ability to store pixmap drawables in offscreen video
+ memory and render into them with full hardware acceleration. Placement
+ of pixmaps in the cache is done automatically on a first-come basis and
+ only if there is room. To enable this feature, set the OFFSCREEN_PIXMAPS
+ flag in the XAAInfoRec.Flags field. This is only available when a
+ ScreenToScreenCopy function is provided, when the Offscreen memory
+ manager has been initialized and when the LINEAR_FRAMEBUFFER flag is
+ also set.
+
+ int maxOffPixWidth
+ int maxOffPixHeight
+
+ These two fields allow the driver to limit the maximum dimensions
+ of an offscreen pixmap. If one of these is not set, it is assumed
+ that there is no limit on that dimension. Note that if an offscreen
+ pixmap with a particular dimension is allowed, then your driver will be
+ expected to render primitives as large as that pixmap.
+
+$XFree86: xc/programs/Xserver/hw/xfree86/xaa/XAA.HOWTO,v 1.10 1999/03/07 11:40:45 dawes Exp $
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/lsb_first/Imakefile b/xc/programs/Xserver/hw/xfree86/xaa/lsb_first/Imakefile
new file mode 100755
index 000000000..c65ad7505
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/lsb_first/Imakefile
@@ -0,0 +1,15 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/xaa/lsb_first/Imakefile,v 1.3 1999/01/31 12:22:14 dawes Exp $
+
+#define LinkDirectory ..
+#define EXPDEFINES -DLSBFIRST
+#define EXPOBJECTNAME lsb_first
+
+XCOMM
+XCOMM To enable the assembly code GlyphRenderers uncomment the lines below
+XCOMM
+XCOMM #if defined(i386Architecture) && !MakeDllModules
+XCOMM #define UseAssembler
+XCOMM #define EXPDEFINES -DLSBFIRST -DUSEASSEMBLER
+XCOMM #endif
+
+#include "../Imakefile.EXP"
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/lsb_fixed/Imakefile b/xc/programs/Xserver/hw/xfree86/xaa/lsb_fixed/Imakefile
new file mode 100644
index 000000000..542dc3c37
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/lsb_fixed/Imakefile
@@ -0,0 +1,7 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/xaa/lsb_fixed/Imakefile,v 1.2 1998/07/25 16:59:11 dawes Exp $
+
+#define LinkDirectory ..
+#define EXPDEFINES -DLSBFIRST -DFIXEDBASE
+#define EXPOBJECTNAME lsb_fixed
+
+#include "../Imakefile.EXP"
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/msb_first/Imakefile b/xc/programs/Xserver/hw/xfree86/xaa/msb_first/Imakefile
new file mode 100644
index 000000000..64a1bddf6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/msb_first/Imakefile
@@ -0,0 +1,15 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/xaa/msb_first/Imakefile,v 1.3 1999/01/31 12:22:14 dawes Exp $
+
+#define LinkDirectory ..
+#define EXPDEFINES -DMSBFIRST
+#define EXPOBJECTNAME msb_first
+
+XCOMM
+XCOMM To enable the assembly code GlyphRenderes uncomment the lines below
+XCOMM
+XCOMM #if defined(i386Architecture) && !MakeDllModules
+XCOMM #define UseAssembler
+XCOMM #define EXPDEFINES -DMSBFIRST -DUSEASSEMBLER
+XCOMM #endif
+
+#include "../Imakefile.EXP"
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/msb_fixed/Imakefile b/xc/programs/Xserver/hw/xfree86/xaa/msb_fixed/Imakefile
new file mode 100644
index 000000000..83af6088d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/msb_fixed/Imakefile
@@ -0,0 +1,7 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/xaa/msb_fixed/Imakefile,v 1.2 1998/07/25 16:59:12 dawes Exp $
+
+#define LinkDirectory ..
+#define EXPDEFINES -DMSBFIRST -DFIXEDBASE
+#define EXPOBJECTNAME msb_fixed
+
+#include "../Imakefile.EXP"
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaa.h b/xc/programs/Xserver/hw/xfree86/xaa/xaa.h
new file mode 100644
index 000000000..60ac1cdbe
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaa.h
@@ -0,0 +1,1248 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaa.h,v 1.27 1999/07/10 12:17:41 dawes Exp $ */
+
+#ifndef _XAA_H
+#define _XAA_H
+
+/*
+
+ ******** OPERATION SPECIFIC FLAGS *********
+
+ **** solid/dashed line flags ****
+
+--------- --------
+23 LINE_PATTERN_LSBFIRST_MSBJUSTIFIED
+22 LINE_PATTERN_LSBFIRST_LSBJUSTIFIED
+21 LINE_PATTERN_MSBFIRST_MSBJUSTIFIED
+20 LINE_PATTERN_MSBFIRST_LSBJUSTIFIED
+19 LINE_PATTERN_POWER_OF_2_ONLY
+18 .
+17 .
+16 .
+--------- -------
+
+ **** screen to screen copy flags ****
+
+--------- --------
+23 ONLY_LEFT_TO_RIGHT_BITBLT
+22 ONLY_TWO_BITBLT_DIRECTIONS
+21 .
+20 .
+19 .
+18 .
+17 .
+16 .
+--------- -------
+
+ **** clipping flags ****
+
+--------- --------
+23 .
+22 HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND
+21 HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY
+20 HARDWARE_CLIP_MONO_8x8_FILL
+19 HARDWARE_CLIP_COLOR_8x8_FILL
+18 HARDWARE_CLIP_SOLID_FILL
+17 HARDWARE_CLIP_DASHED_LINE
+16 HARDWARE_CLIP_SOLID_LINE
+--------- -------
+
+
+ **** hardware pattern flags ****
+
+--------- --------
+23 .
+22 .
+21 HARDWARE_PATTERN_SCREEN_ORIGIN
+20 .
+19 .
+18 .
+17 HARDWARE_PATTERN_PROGRAMMED_ORIGIN
+16 HARDWARE_PATTERN_PROGRAMMED_BITS
+--------- -------
+
+ **** write pixmap flags ****
+
+--------- --------
+23 .
+22 .
+21 .
+20 .
+19 .
+18 .
+17 .
+16 CONVERT_32BPP_TO_24BPP
+--------- -------
+
+
+ ******** GENERIC FLAGS *********
+
+--------- -------
+15 SYNC_AFTER_COLOR_EXPAND
+14 CPU_TRANSFER_PAD_QWORD
+13 .
+12 LEFT_EDGE_CLIPPING_NEGATIVE_X
+11 LEFT_EDGE_CLIPPING
+10 CPU_TRANSFER_BASE_FIXED
+ 9 BIT_ORDER_IN_BYTE_MSBFIRST
+ 8 TRANSPARENCY_GXCOPY_ONLY
+--------- -------
+ 7 NO_TRANSPARENCY
+ 6 TRANSPARENCY_ONLY
+ 5 ROP_NEEDS_SOURCE
+ 4 TRIPLE_BITS_24BPP
+ 3 RGB_EQUAL
+ 2 NO_PLANEMASK
+ 1 NO_GXCOPY
+ 0 GXCOPY_ONLY
+--------- -------
+
+
+*/
+
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "regionstr.h"
+#include "xf86fbman.h"
+
+/* Flags */
+#define PIXMAP_CACHE 0x00000001
+#define MICROSOFT_ZERO_LINE_BIAS 0x00000002
+#define OFFSCREEN_PIXMAPS 0x00000004
+#define LINEAR_FRAMEBUFFER 0x00000008
+
+
+/* GC fg, bg, and planemask restrictions */
+#define GXCOPY_ONLY 0x00000001
+#define NO_GXCOPY 0x00000002
+#define NO_PLANEMASK 0x00000004
+#define RGB_EQUAL 0x00000008
+#define TRIPLE_BITS_24BPP 0x00000010
+#define ROP_NEEDS_SOURCE 0x00000020
+
+/* transparency restrictions */
+#define TRANSPARENCY_ONLY 0x00000040
+#define NO_TRANSPARENCY 0x00000080
+#define TRANSPARENCY_GXCOPY_ONLY 0x00000100
+
+/* bit order restrictions */
+#define BIT_ORDER_IN_BYTE_MSBFIRST 0x00000200
+#define BIT_ORDER_IN_BYTE_LSBFIRST 0x00000000
+
+/* transfer base restriction */
+#define CPU_TRANSFER_BASE_FIXED 0x00000400
+
+/* skipleft restrictions */
+#define LEFT_EDGE_CLIPPING 0x00000800
+#define LEFT_EDGE_CLIPPING_NEGATIVE_X 0x00001000
+
+/* data padding */
+#define CPU_TRANSFER_PAD_DWORD 0x00000000
+#define CPU_TRANSFER_PAD_QWORD 0x00004000
+#define SCANLINE_PAD_DWORD 0x00000000
+
+#define SYNC_AFTER_COLOR_EXPAND 0x00008000
+#define SYNC_AFTER_IMAGE_WRITE SYNC_AFTER_COLOR_EXPAND
+
+/* hardware pattern */
+#define HARDWARE_PATTERN_PROGRAMMED_BITS 0x00010000
+#define HARDWARE_PATTERN_PROGRAMMED_ORIGIN 0x00020000
+#define HARDWARE_PATTERN_SCREEN_ORIGIN 0x00200000
+
+/* copyarea flags */
+#define ONLY_TWO_BITBLT_DIRECTIONS 0x00400000
+#define ONLY_LEFT_TO_RIGHT_BITBLT 0x00800000
+
+/* line flags */
+#define LINE_PATTERN_LSBFIRST_MSBJUSTIFIED 0x00800000
+#define LINE_PATTERN_LSBFIRST_LSBJUSTIFIED 0x00400000
+#define LINE_PATTERN_MSBFIRST_MSBJUSTIFIED 0x00200000
+#define LINE_PATTERN_MSBFIRST_LSBJUSTIFIED 0x00100000
+#define LINE_PATTERN_POWER_OF_2_ONLY 0x00080000
+
+/* clipping flags */
+#define HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND 0x00400000
+#define HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY 0x00200000
+#define HARDWARE_CLIP_MONO_8x8_FILL 0x00100000
+#define HARDWARE_CLIP_COLOR_8x8_FILL 0x00080000
+#define HARDWARE_CLIP_SOLID_FILL 0x00040000
+#define HARDWARE_CLIP_DASHED_LINE 0x00020000
+#define HARDWARE_CLIP_SOLID_LINE 0x00010000
+
+#define HARDWARE_CLIP_LINE 0x00000000
+
+
+/* image write flags */
+#define CONVERT_32BPP_TO_24BPP 0x00010000
+
+/* pixmap cache flags */
+#define CACHE_MONO_8x8 0x00000001
+#define CACHE_COLOR_8x8 0x00000002
+#define DO_NOT_BLIT_STIPPLES 0x00000004
+#define DO_NOT_TILE_MONO_DATA 0x00000008
+#define DO_NOT_TILE_COLOR_DATA 0x00000010
+
+
+#define DEGREES_0 0
+#define DEGREES_90 1
+#define DEGREES_180 2
+#define DEGREES_270 3
+
+#define OMIT_LAST 1
+
+
+typedef void (* ValidateGCProcPtr)(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+typedef struct {
+ unsigned char *bits;
+ int width;
+ int height;
+ int yoff;
+ int srcwidth;
+ int start;
+ int end;
+} NonTEGlyphInfo, *NonTEGlyphPtr;
+
+
+typedef struct {
+ int x;
+ int y;
+ int w;
+ int h;
+ int orig_w;
+ int orig_h;
+ unsigned long serialNumber;
+ int pat0;
+ int pat1;
+ int fg;
+ int bg;
+ int trans_color;
+ DDXPointPtr offsets;
+ DevUnion devPrivate;
+} XAACacheInfoRec, *XAACacheInfoPtr;
+
+
+typedef struct _PixmapLink {
+ PixmapPtr pPix;
+ struct _PixmapLink *next;
+ FBAreaPtr area;
+} PixmapLink, *PixmapLinkPtr;
+
+typedef struct _XAAInfoRec {
+ ScrnInfoPtr pScrn;
+ int Flags;
+
+ void (*Sync)(
+ ScrnInfoPtr pScrn
+ );
+
+ /***************** Low Level *****************/
+
+/* Blits */
+ void (*SetupForScreenToScreenCopy)(
+ ScrnInfoPtr pScrn,
+ int xdir, int ydir,
+ int rop,
+ unsigned int planemask,
+ int trans_color
+ );
+ int ScreenToScreenCopyFlags;
+
+ void (*SubsequentScreenToScreenCopy)(
+ ScrnInfoPtr pScrn,
+ int x1, int y1,
+ int x2, int y2,
+ int w, int h
+ );
+
+
+/* Solid fills */
+ void (*SetupForSolidFill)(
+ ScrnInfoPtr pScrn,
+ int color,
+ int rop,
+ unsigned int planemask
+ );
+ int SolidFillFlags;
+
+ void (*SubsequentSolidFillRect)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h
+ );
+
+ void (*SubsequentSolidFillTrap)(
+ ScrnInfoPtr pScrn,
+ int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR
+ );
+
+
+/* Solid lines */
+
+ void (*SetupForSolidLine)(
+ ScrnInfoPtr pScrn,
+ int color,
+ int rop,
+ unsigned int planemask
+ );
+ int SolidLineFlags;
+
+ void (*SubsequentSolidTwoPointLine)(
+ ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags
+ );
+
+ void (*SubsequentSolidBresenhamLine)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int absmaj, int absmin, int err, int len, int octant
+ );
+ int SolidBresenhamLineErrorTermBits;
+
+ void (*SubsequentSolidHorVertLine)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+ );
+
+/* Dashed lines */
+
+ void (*SetupForDashedLine)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask,
+ int length,
+ unsigned char *pattern
+ );
+ int DashedLineFlags;
+ int DashPatternMaxLength;
+
+ void (*SubsequentDashedTwoPointLine)(
+ ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags, int phase
+ );
+
+ void (*SubsequentDashedBresenhamLine)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int absmaj, int absmin, int err, int len, int flags,
+ int phase
+ );
+ int DashedBresenhamLineErrorTermBits;
+
+/* Clipper */
+
+ void (*SetClippingRectangle) (
+ ScrnInfoPtr pScrn,
+ int left, int top, int right, int bottom
+ );
+ int ClippingFlags;
+
+ void (*DisableClipping)(ScrnInfoPtr pScrn);
+
+/* 8x8 mono pattern fills */
+ void (*SetupForMono8x8PatternFill)(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+ );
+ int Mono8x8PatternFillFlags;
+
+ void (*SubsequentMono8x8PatternFillRect)(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h
+ );
+
+ void (*SubsequentMono8x8PatternFillTrap)(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR
+ );
+
+/* 8x8 color pattern fills */
+
+ void (*SetupForColor8x8PatternFill)(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int rop,
+ unsigned int planemask,
+ int transparency_color
+ );
+ int Color8x8PatternFillFlags;
+
+ void (*SubsequentColor8x8PatternFillRect)(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h
+ );
+
+ void (*SubsequentColor8x8PatternFillTrap)(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR
+ );
+
+
+/* Color expansion */
+
+ void (*SetupForCPUToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+ );
+ int CPUToScreenColorExpandFillFlags;
+
+ void (*SubsequentCPUToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+ );
+
+ unsigned char *ColorExpandBase;
+ int ColorExpandRange;
+
+
+/* Scanline color expansion */
+
+ void (*SetupForScanlineCPUToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+ );
+ int ScanlineCPUToScreenColorExpandFillFlags;
+
+ void (*SubsequentScanlineCPUToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+ );
+
+ void (*SubsequentColorExpandScanline)(
+ ScrnInfoPtr pScrn,
+ int bufno
+ );
+
+ int NumScanlineColorExpandBuffers;
+ unsigned char **ScanlineColorExpandBuffers;
+
+/* Screen to screen color expansion */
+
+ void (*SetupForScreenToScreenColorExpandFill) (
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+ );
+ int ScreenToScreenColorExpandFillFlags;
+
+ void (*SubsequentScreenToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int skipleft
+ );
+
+
+/* Image transfers */
+
+ void (*SetupForImageWrite)(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+ );
+ int ImageWriteFlags;
+
+ void (*SubsequentImageWriteRect)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+ );
+ unsigned char *ImageWriteBase;
+ int ImageWriteRange;
+
+/* Scanline Image transfers */
+
+ void (*SetupForScanlineImageWrite)(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+ );
+ int ScanlineImageWriteFlags;
+
+ void (*SubsequentScanlineImageWriteRect)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+ );
+
+ void (*SubsequentImageWriteScanline) (
+ ScrnInfoPtr pScrn,
+ int bufno
+ );
+
+ int NumScanlineImageWriteBuffers;
+ unsigned char **ScanlineImageWriteBuffers;
+
+ /* Image Reads */
+
+ void (*SetupForImageRead) (
+ ScrnInfoPtr pScrn,
+ int bpp, int depth
+ );
+ int ImageReadFlags;
+
+ unsigned char *ImageReadBase;
+ int ImageReadRange;
+
+ void (*SubsequentImageReadRect)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h
+ );
+
+
+ /***************** Mid Level *****************/
+ void (*ScreenToScreenBitBlt)(
+ ScrnInfoPtr pScrn,
+ int nbox,
+ DDXPointPtr pptSrc,
+ BoxPtr pbox,
+ int xdir, int ydir,
+ int alu,
+ unsigned int planmask
+ );
+ int ScreenToScreenBitBltFlags;
+
+ void (*WriteBitmap) (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+ );
+ int WriteBitmapFlags;
+
+ void (*FillSolidRects)(
+ ScrnInfoPtr pScrn,
+ int fg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox
+ );
+ int FillSolidRectsFlags;
+
+ void (*FillMono8x8PatternRects)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int pat0, int pat1,
+ int xorg, int yorg
+ );
+ int FillMono8x8PatternRectsFlags;
+
+ void (*FillColor8x8PatternRects)(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+ );
+ int FillColor8x8PatternRectsFlags;
+
+ void (*FillCacheBltRects)(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+ );
+ int FillCacheBltRectsFlags;
+
+ void (*FillColorExpandRects)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+ );
+ int FillColorExpandRectsFlags;
+
+ void (*FillCacheExpandRects)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+ );
+ int FillCacheExpandRectsFlags;
+
+ void (*FillImageWriteRects)(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+ );
+ int FillImageWriteRectsFlags;
+
+
+ void (*FillSolidSpans)(
+ ScrnInfoPtr pScrn,
+ int fg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr points,
+ int *widths,
+ int fSorted
+ );
+ int FillSolidSpansFlags;
+
+ void (*FillMono8x8PatternSpans)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr points,
+ int *widths,
+ int fSorted,
+ int pat0, int pat1,
+ int xorg, int yorg
+ );
+ int FillMono8x8PatternSpansFlags;
+
+ void (*FillColor8x8PatternSpans)(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr points,
+ int *widths,
+ int fSorted,
+ XAACacheInfoPtr pCache,
+ int xorg, int yorg
+ );
+ int FillColor8x8PatternSpansFlags;
+
+ void (*FillCacheBltSpans)(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr points,
+ int *widths,
+ int fSorted,
+ XAACacheInfoPtr pCache,
+ int xorg, int yorg
+ );
+ int FillCacheBltSpansFlags;
+
+ void (*FillColorExpandSpans)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr points,
+ int *widths,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+ );
+ int FillColorExpandSpansFlags;
+
+ void (*FillCacheExpandSpans)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+ );
+ int FillCacheExpandSpansFlags;
+
+ void (*TEGlyphRenderer)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+ );
+ int TEGlyphRendererFlags;
+
+ void (*NonTEGlyphRenderer)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int n,
+ NonTEGlyphPtr glyphs,
+ BoxPtr pbox,
+ int fg, int rop,
+ unsigned int planemask
+ );
+ int NonTEGlyphRendererFlags;
+
+ void (*WritePixmap) (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+ );
+ int WritePixmapFlags;
+
+ void (*ReadPixmap) (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *dst,
+ int dstwidth,
+ int bpp, int depth
+ );
+ int ReadPixmapFlags;
+
+ /***************** GC Level *****************/
+ RegionPtr (*CopyArea)(
+ DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+ );
+ int CopyAreaFlags;
+
+ RegionPtr (*CopyPlane)(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+ );
+ int CopyPlaneFlags;
+
+ void (*PushPixelsSolid) (
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDrawable,
+ int dx, int dy,
+ int xOrg, int yOrg
+ );
+ int PushPixelsFlags;
+
+ /** PolyFillRect **/
+
+ void (*PolyFillRectSolid)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+ );
+ int PolyFillRectSolidFlags;
+
+ void (*PolyFillRectStippled)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+ );
+ int PolyFillRectStippledFlags;
+
+ void (*PolyFillRectOpaqueStippled)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+ );
+ int PolyFillRectOpaqueStippledFlags;
+
+ void (*PolyFillRectTiled)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+ );
+ int PolyFillRectTiledFlags;
+
+ /** FillSpans **/
+
+ void (*FillSpansSolid)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+ );
+ int FillSpansSolidFlags;
+
+ void (*FillSpansStippled)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+ );
+ int FillSpansStippledFlags;
+
+ void (*FillSpansOpaqueStippled)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+ );
+ int FillSpansOpaqueStippledFlags;
+
+ void (*FillSpansTiled)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+ );
+ int FillSpansTiledFlags;
+
+ int (*PolyText8TE) (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+ );
+ int PolyText8TEFlags;
+
+ int (*PolyText16TE) (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+ );
+ int PolyText16TEFlags;
+
+ void (*ImageText8TE) (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+ );
+ int ImageText8TEFlags;
+
+ void (*ImageText16TE) (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+ );
+ int ImageText16TEFlags;
+
+ void (*ImageGlyphBltTE) (
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+ );
+ int ImageGlyphBltTEFlags;
+
+ void (*PolyGlyphBltTE) (
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+ );
+ int PolyGlyphBltTEFlags;
+
+ int (*PolyText8NonTE) (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+ );
+ int PolyText8NonTEFlags;
+
+ int (*PolyText16NonTE) (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+ );
+ int PolyText16NonTEFlags;
+
+ void (*ImageText8NonTE) (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+ );
+ int ImageText8NonTEFlags;
+
+ void (*ImageText16NonTE) (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+ );
+ int ImageText16NonTEFlags;
+
+ void (*ImageGlyphBltNonTE) (
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+ );
+ int ImageGlyphBltNonTEFlags;
+
+ void (*PolyGlyphBltNonTE) (
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+ );
+ int PolyGlyphBltNonTEFlags;
+
+ void (*PolyRectangleThinSolid)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+ );
+ int PolyRectangleThinSolidFlags;
+
+ void (*PolylinesWideSolid)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+ );
+ int PolylinesWideSolidFlags;
+
+ void (*PolylinesThinSolid)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+ );
+ int PolylinesThinSolidFlags;
+
+ void (*PolySegmentThinSolid)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+ );
+ int PolySegmentThinSolidFlags;
+
+ void (*PolylinesThinDashed)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+ );
+ int PolylinesThinDashedFlags;
+
+ void (*PolySegmentThinDashed)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+ );
+ int PolySegmentThinDashedFlags;
+
+ void (*FillPolygonSolid)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+ );
+ int FillPolygonSolidFlags;
+
+ void (*FillPolygonStippled)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+ );
+ int FillPolygonStippledFlags;
+
+ void (*FillPolygonOpaqueStippled)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+ );
+ int FillPolygonOpaqueStippledFlags;
+
+ void (*FillPolygonTiled)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+ );
+ int FillPolygonTiledFlags;
+
+ void (*PolyFillArcSolid)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+ );
+ int PolyFillArcSolidFlags;
+
+ void (*PutImage)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage
+ );
+ int PutImageFlags;
+
+ /* Validation masks */
+
+ unsigned long FillSpansMask;
+ ValidateGCProcPtr ValidateFillSpans;
+ unsigned long SetSpansMask;
+ ValidateGCProcPtr ValidateSetSpans;
+ unsigned long PutImageMask;
+ ValidateGCProcPtr ValidatePutImage;
+ unsigned long CopyAreaMask;
+ ValidateGCProcPtr ValidateCopyArea;
+ unsigned long CopyPlaneMask;
+ ValidateGCProcPtr ValidateCopyPlane;
+ unsigned long PolyPointMask;
+ ValidateGCProcPtr ValidatePolyPoint;
+ unsigned long PolylinesMask;
+ ValidateGCProcPtr ValidatePolylines;
+ unsigned long PolySegmentMask;
+ ValidateGCProcPtr ValidatePolySegment;
+ unsigned long PolyRectangleMask;
+ ValidateGCProcPtr ValidatePolyRectangle;
+ unsigned long PolyArcMask;
+ ValidateGCProcPtr ValidatePolyArc;
+ unsigned long FillPolygonMask;
+ ValidateGCProcPtr ValidateFillPolygon;
+ unsigned long PolyFillRectMask;
+ ValidateGCProcPtr ValidatePolyFillRect;
+ unsigned long PolyFillArcMask;
+ ValidateGCProcPtr ValidatePolyFillArc;
+ unsigned long PolyText8Mask;
+ ValidateGCProcPtr ValidatePolyText8;
+ unsigned long PolyText16Mask;
+ ValidateGCProcPtr ValidatePolyText16;
+ unsigned long ImageText8Mask;
+ ValidateGCProcPtr ValidateImageText8;
+ unsigned long ImageText16Mask;
+ ValidateGCProcPtr ValidateImageText16;
+ unsigned long PolyGlyphBltMask;
+ ValidateGCProcPtr ValidatePolyGlyphBlt;
+ unsigned long ImageGlyphBltMask;
+ ValidateGCProcPtr ValidateImageGlyphBlt;
+ unsigned long PushPixelsMask;
+ ValidateGCProcPtr ValidatePushPixels;
+
+ void (*ComputeDash)(GCPtr pGC);
+
+ /* Pixmap Cache */
+
+ int PixmapCacheFlags;
+ Bool UsingPixmapCache;
+ Bool CanDoMono8x8;
+ Bool CanDoColor8x8;
+
+ void (*InitPixmapCache)(
+ ScreenPtr pScreen,
+ RegionPtr areas,
+ pointer data
+ );
+ void (*ClosePixmapCache)(
+ ScreenPtr pScreen
+ );
+
+ int (*StippledFillChooser)(GCPtr pGC);
+ int (*OpaqueStippledFillChooser)(GCPtr pGC);
+ int (*TiledFillChooser)(GCPtr pGC);
+
+ int CachePixelGranularity;
+ int MaxCacheableTileWidth;
+ int MaxCacheableTileHeight;
+ int MaxCacheableStippleWidth;
+ int MaxCacheableStippleHeight;
+
+ XAACacheInfoPtr (*CacheTile)(
+ ScrnInfoPtr Scrn, PixmapPtr pPix
+ );
+ XAACacheInfoPtr (*CacheStipple)(
+ ScrnInfoPtr Scrn, PixmapPtr pPix,
+ int fg, int bg
+ );
+ XAACacheInfoPtr (*CacheMonoStipple)(
+ ScrnInfoPtr Scrn, PixmapPtr pPix
+ );
+ XAACacheInfoPtr (*CacheMono8x8Pattern)(
+ ScrnInfoPtr Scrn, int pat0, int pat1
+ );
+ XAACacheInfoPtr (*CacheColor8x8Pattern)(
+ ScrnInfoPtr Scrn, PixmapPtr pPix,
+ int fg, int bg
+ );
+
+
+ int MonoPatternPitch;
+ int CacheWidthMono8x8Pattern;
+ int CacheHeightMono8x8Pattern;
+
+ int ColorPatternPitch;
+ int CacheWidthColor8x8Pattern;
+ int CacheHeightColor8x8Pattern;
+
+ int CacheColorExpandDensity;
+
+ void (*WriteBitmapToCache) (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int fg, int bg
+ );
+ void (*WritePixmapToCache) (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int bpp, int depth
+ );
+ void (*WriteMono8x8PatternToCache)(
+ ScrnInfoPtr pScrn,
+ XAACacheInfoPtr pCache
+ );
+ void (*WriteColor8x8PatternToCache)(
+ ScrnInfoPtr pScrn,
+ PixmapPtr pPix,
+ XAACacheInfoPtr pCache
+ );
+
+ char* PixmapCachePrivate;
+
+ /* Miscellaneous */
+
+ GC ScratchGC;
+ int PreAllocSize;
+ unsigned char *PreAllocMem;
+
+ CharInfoPtr CharInfo[255];
+ NonTEGlyphInfo GlyphInfo[255];
+
+ unsigned int FullPlanemask;
+
+ PixmapLinkPtr OffscreenPixmaps;
+ int maxOffPixWidth;
+ int maxOffPixHeight;
+
+ XAACacheInfoRec ScratchCacheInfoRec;
+
+ BoxPtr ClipBox;
+
+ Bool NeedToSync;
+
+ char *dgaSaves;
+
+ /* These can be supplied to override the defaults */
+
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ CopyWindowProcPtr CopyWindow;
+ BackingStoreSaveAreasProcPtr SaveAreas;
+ BackingStoreRestoreAreasProcPtr RestoreAreas;
+
+} XAAInfoRec, *XAAInfoRecPtr;
+
+
+Bool
+XAAInit(
+ ScreenPtr pScreen,
+ XAAInfoRecPtr infoRec
+);
+
+XAAInfoRecPtr XAACreateInfoRec(void);
+
+void
+XAADestroyInfoRec(
+ XAAInfoRecPtr infoRec
+);
+
+typedef void (*DepthChangeFuncPtr) (ScrnInfoPtr pScrn, int depth);
+
+Bool
+XAAInitDualFramebufferOverlay(
+ ScreenPtr pScreen,
+ DepthChangeFuncPtr callback
+);
+
+#endif /* _XAA_H */
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaBitBlt.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaBitBlt.c
new file mode 100644
index 000000000..015b539e5
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaBitBlt.c
@@ -0,0 +1,219 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaBitBlt.c,v 1.3 1998/12/06 06:08:39 dawes Exp $ */
+
+/*
+ This is a lighter version of cfbBitBlt. We calculate the boxes
+ when accelerating pixmap->screen and screen->screen copies.
+ We also pass the GC to the doBitBlt function so that it has access
+ to the fg and bg so CopyPlane can use this.
+*/
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "mi.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "xaalocal.h"
+
+
+RegionPtr
+XAABitBlt(
+ DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ void (*doBitBlt)(DrawablePtr, DrawablePtr, GCPtr, RegionPtr, DDXPointPtr),
+ unsigned long bitPlane )
+{
+
+ RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */
+ RegionPtr prgnExposed;
+ Bool freeSrcClip = FALSE;
+ RegionRec rgnDst;
+ DDXPointPtr pptSrc, ppt;
+ DDXPointRec origDest;
+ BoxPtr pbox;
+ BoxRec fastBox;
+ int i, dx, dy, numRects;
+ xRectangle origSource;
+ int fastClip = 0; /* for fast clipping with pixmap source */
+ int fastExpose = 0; /* for fast exposures with pixmap source */
+
+ origSource.x = srcx;
+ origSource.y = srcy;
+ origSource.width = width;
+ origSource.height = height;
+ origDest.x = dstx;
+ origDest.y = dsty;
+
+ if((pSrcDrawable != pDstDrawable) &&
+ pSrcDrawable->pScreen->SourceValidate) {
+ (*pSrcDrawable->pScreen->SourceValidate) (
+ pSrcDrawable, srcx, srcy, width, height);
+ }
+
+ srcx += pSrcDrawable->x;
+ srcy += pSrcDrawable->y;
+
+ /* clip the source */
+ if (pSrcDrawable->type == DRAWABLE_PIXMAP) {
+ if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE))
+ prgnSrcClip = pGC->pCompositeClip;
+ else
+ fastClip = 1;
+ } else { /* Window */
+ if (pGC->subWindowMode == IncludeInferiors) {
+ if (!((WindowPtr) pSrcDrawable)->parent) {
+ /*
+ * special case bitblt from root window in
+ * IncludeInferiors mode; just like from a pixmap
+ */
+ fastClip = 1;
+ } else if ((pSrcDrawable == pDstDrawable) &&
+ (pGC->clientClipType == CT_NONE)) {
+ prgnSrcClip = pGC->pCompositeClip;
+ } else {
+ prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
+ freeSrcClip = TRUE;
+ }
+ } else {
+ prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
+ }
+ }
+
+ fastBox.x1 = srcx;
+ fastBox.y1 = srcy;
+ fastBox.x2 = srcx + width;
+ fastBox.y2 = srcy + height;
+
+ /* Don't create a source region if we are doing a fast clip */
+ if (fastClip) {
+ fastExpose = 1;
+ /*
+ * clip the source; if regions extend beyond the source size,
+ * make sure exposure events get sent
+ */
+ if (fastBox.x1 < pSrcDrawable->x) {
+ fastBox.x1 = pSrcDrawable->x;
+ fastExpose = 0;
+ }
+ if (fastBox.y1 < pSrcDrawable->y) {
+ fastBox.y1 = pSrcDrawable->y;
+ fastExpose = 0;
+ }
+ if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width) {
+ fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
+ fastExpose = 0;
+ }
+ if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height) {
+ fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
+ fastExpose = 0;
+ }
+ } else {
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+ REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
+ }
+
+ dstx += pDstDrawable->x;
+ dsty += pDstDrawable->y;
+
+ if (pDstDrawable->type == DRAWABLE_WINDOW) {
+ if (!((WindowPtr)pDstDrawable)->realized) {
+ if (!fastClip)
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return NULL;
+ }
+ }
+
+ dx = srcx - dstx;
+ dy = srcy - dsty;
+
+ /* Translate and clip the dst to the destination composite clip */
+ if (fastClip) {
+ RegionPtr cclip;
+
+ /* Translate the region directly */
+ fastBox.x1 -= dx;
+ fastBox.x2 -= dx;
+ fastBox.y1 -= dy;
+ fastBox.y2 -= dy;
+
+ /* If the destination composite clip is one rectangle we can
+ do the clip directly. Otherwise we have to create a full
+ blown region and call intersect */
+
+ cclip = pGC->pCompositeClip;
+ if (REGION_NUM_RECTS(cclip) == 1) {
+ BoxPtr pBox = REGION_RECTS(cclip);
+
+ if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
+ if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
+ if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
+ if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
+
+ /* Check to see if the region is empty */
+ if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2) {
+ REGION_INIT(pGC->pScreen, &rgnDst, NullBox, 0);
+ } else {
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+ }
+ } else {
+ /* We must turn off fastClip now, since we must create
+ a full blown region. It is intersected with the
+ composite clip below. */
+ fastClip = 0;
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox,1);
+ }
+ } else {
+ REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
+ }
+
+ if (!fastClip) {
+ REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst,
+ pGC->pCompositeClip);
+ }
+
+ /* Do bit blitting */
+ numRects = REGION_NUM_RECTS(&rgnDst);
+ if (numRects && width && height) {
+ if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects *
+ sizeof(DDXPointRec)))) {
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return NULL;
+ }
+ pbox = REGION_RECTS(&rgnDst);
+ ppt = pptSrc;
+ for (i = numRects; --i >= 0; pbox++, ppt++) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ (*doBitBlt) (pSrcDrawable, pDstDrawable, pGC, &rgnDst, pptSrc);
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+
+ prgnExposed = NULL;
+ if (pGC->fExpose) {
+ /* Pixmap sources generate a NoExposed (we return NULL to do this) */
+ if (!fastExpose)
+ prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
+ origSource.x, origSource.y,
+ (int)origSource.width,
+ (int)origSource.height,
+ origDest.x, origDest.y, bitPlane);
+ }
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return prgnExposed;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaBitOrder.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaBitOrder.c
new file mode 100644
index 000000000..2a42e3aec
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaBitOrder.c
@@ -0,0 +1,65 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaBitOrder.c,v 1.5 1998/09/05 06:37:03 dawes Exp $ */
+
+#include "xf86.h"
+#include "xf86_ansic.h"
+#ifndef RAMDAC_MODULE
+#include "xaa.h"
+#include "xaalocal.h"
+#else
+#include "xf86CursorPriv.h"
+#endif
+
+
+#if defined(__GNUC__) && defined(__i386__) && !defined(DLOPEN_HACK)
+CARD32
+XAAReverseBitOrder(CARD32 data)
+{
+#if defined(Lynx) || (defined(SYSV) || defined(SVR4)) && !defined(ACK_ASSEMBLER) || defined(__ELF__) || defined(__GNU__)
+ __asm__(
+ "movl $0,%%ecx\n"
+ "movb %%al,%%cl\n"
+ "movb byte_reversed(%%ecx),%%al\n"
+ "movb %%ah,%%cl\n"
+ "movb byte_reversed(%%ecx),%%ah\n"
+ "roll $16,%%eax\n"
+ "movb %%al,%%cl\n"
+ "movb byte_reversed(%%ecx),%%al\n"
+ "movb %%ah,%%cl\n"
+ "movb byte_reversed(%%ecx),%%ah\n"
+ "roll $16,%%eax\n"
+ : "=a" (data) : "0" (data)
+ : "cx"
+ );
+#else
+ __asm__(
+ "movl $0,%%ecx\n"
+ "movb %%al,%%cl\n"
+ "movb _byte_reversed(%%ecx),%%al\n"
+ "movb %%ah,%%cl\n"
+ "movb _byte_reversed(%%ecx),%%ah\n"
+ "roll $16,%%eax\n"
+ "movb %%al,%%cl\n"
+ "movb _byte_reversed(%%ecx),%%al\n"
+ "movb %%ah,%%cl\n"
+ "movb _byte_reversed(%%ecx),%%ah\n"
+ "roll $16,%%eax\n"
+ : "=a" (data) : "0" (data)
+ : "cx"
+ );
+#endif
+ return data;
+}
+#else
+CARD32
+XAAReverseBitOrder(CARD32 data)
+{
+ unsigned char* kludge = (unsigned char*)&data;
+
+ kludge[0] = byte_reversed[kludge[0]];
+ kludge[1] = byte_reversed[kludge[1]];
+ kludge[2] = byte_reversed[kludge[2]];
+ kludge[3] = byte_reversed[kludge[3]];
+
+ return data;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaBitmap.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaBitmap.c
new file mode 100644
index 000000000..3b1ed842f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaBitmap.c
@@ -0,0 +1,408 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaBitmap.c,v 1.5 1999/08/14 10:50:13 dawes Exp $ */
+
+
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaacexp.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+
+
+
+/********** byte swapping ***************/
+
+
+#ifdef FIXEDBASE
+# define DEST(i) *dest
+# define RETURN(i) return(dest)
+#else
+# define DEST(i) dest[i]
+# define RETURN(i) return(dest + i)
+#endif
+
+#ifdef MSBFIRST
+# define SOURCE(i) XAAReverseBitOrder(src[i])
+#else
+# define SOURCE(i) src[i]
+#endif
+
+
+typedef CARD32 *(* BitmapScanlineProcPtr)(CARD32 *, CARD32 *, int, int);
+
+#ifdef TRIPLE_BITS
+static CARD32*
+BitmapScanline(
+ CARD32 *src, CARD32 *base,
+ int count, int skipleft )
+{
+ while(count >= 3) {
+ WRITE_BITS3(*src);
+ src++;
+ count -= 3;
+ }
+ if (count == 2) {
+ WRITE_BITS2(*src);
+ } else if (count == 1) {
+ WRITE_BITS1(*src);
+ }
+
+ return base;
+}
+
+static CARD32*
+BitmapScanline_Inverted(
+ CARD32 *src, CARD32 *base,
+ int count, int skipleft )
+{
+ while(count >= 3) {
+ WRITE_BITS3(~(*src));
+ src++;
+ count -= 3;
+ }
+ if (count == 2) {
+ WRITE_BITS2(~(*src));
+ } else if (count == 1) {
+ WRITE_BITS1(~(*src));
+ }
+
+ return base;
+}
+
+
+static CARD32*
+BitmapScanline_Shifted(
+ CARD32 *bits, CARD32 *base,
+ int count, int skipleft )
+{
+ while(count >= 3) {
+ WRITE_BITS3((SHIFT_R(*bits,skipleft) |
+ SHIFT_L(*(bits + 1),(32 - skipleft))));
+ bits++;
+ count -= 3;
+ }
+ if (count == 2) {
+ WRITE_BITS2((SHIFT_R(*bits,skipleft) |
+ SHIFT_L(*(bits + 1),(32 - skipleft))));
+ } else if (count == 1) {
+ WRITE_BITS1((SHIFT_R(*bits,skipleft) |
+ SHIFT_L(*(bits + 1),(32 - skipleft))));
+ }
+
+ return base;
+}
+
+static CARD32*
+BitmapScanline_Shifted_Inverted(
+ CARD32 *bits, CARD32 *base,
+ int count, int skipleft )
+{
+ while(count >= 3) {
+ WRITE_BITS3(~(SHIFT_R(*bits,skipleft) |
+ SHIFT_L(*(bits + 1),(32 - skipleft))));
+ bits++;
+ count -= 3;
+ }
+ if (count == 2) {
+ WRITE_BITS2(~(SHIFT_R(*bits,skipleft) |
+ SHIFT_L(*(bits + 1),(32 - skipleft))));
+ } else if (count == 1) {
+ WRITE_BITS1(~(SHIFT_R(*bits,skipleft) |
+ SHIFT_L(*(bits + 1),(32 - skipleft))));
+ }
+
+ return base;
+}
+
+#else
+static CARD32*
+BitmapScanline(
+ CARD32 *src, CARD32 *dest,
+ int count, int skipleft )
+{
+ while(count >= 4) {
+ DEST(0) = SOURCE(0);
+ DEST(1) = SOURCE(1);
+ DEST(2) = SOURCE(2);
+ DEST(3) = SOURCE(3);
+ count -= 4;
+ src += 4;
+#ifndef FIXEDBASE
+ dest += 4;
+#endif
+ }
+
+ if(!count) return dest;
+ DEST(0) = SOURCE(0);
+ if(count == 1) RETURN(1);
+ DEST(1) = SOURCE(1);
+ if(count == 2) RETURN(2);
+ DEST(2) = SOURCE(2);
+ RETURN(3);
+}
+
+static CARD32*
+BitmapScanline_Inverted(
+ CARD32 *src, CARD32 *dest,
+ int count, int skipleft )
+{
+ while(count >= 4) {
+ DEST(0) = ~SOURCE(0);
+ DEST(1) = ~SOURCE(1);
+ DEST(2) = ~SOURCE(2);
+ DEST(3) = ~SOURCE(3);
+ count -= 4;
+ src += 4;
+#ifndef FIXEDBASE
+ dest += 4;
+#endif
+ }
+
+ if(!count) return dest;
+ DEST(0) = ~SOURCE(0);
+ if(count == 1) RETURN(1);
+ DEST(1) = ~SOURCE(1);
+ if(count == 2) RETURN(2);
+ DEST(2) = ~SOURCE(2);
+ RETURN(3);
+}
+
+
+static CARD32*
+BitmapScanline_Shifted(
+ CARD32 *bits, CARD32 *base,
+ int count, int skipleft )
+{
+ while(count--) {
+ WRITE_BITS(SHIFT_R(*bits,skipleft) |
+ SHIFT_L(*(bits + 1),(32 - skipleft)));
+ bits++;
+ }
+ return base;
+}
+
+static CARD32*
+BitmapScanline_Shifted_Inverted(
+ CARD32 *bits, CARD32 *base,
+ int count, int skipleft )
+{
+ while(count--) {
+ WRITE_BITS(~(SHIFT_R(*bits,skipleft) |
+ SHIFT_L(*(bits + 1),(32 - skipleft))));
+ bits++;
+ }
+ return base;
+}
+#endif
+
+/*
+ When the accelerator is TRANSPARENCY_ONLY, WriteBitmap can do
+ the fill in two passes, inverting the source on the second pass.
+ For GXcopy we can fill the backing rectangle as a solid rect and
+ avoid the invert.
+*/
+
+void
+#ifdef TRIPLE_BITS
+EXPNAME(XAAWriteBitmapColorExpand3)(
+#else
+EXPNAME(XAAWriteBitmapColorExpand)(
+#endif
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32* base;
+ unsigned char *srcp = src;
+ int SecondPassColor = -1;
+ int shift = 0, dwords;
+ BitmapScanlineProcPtr firstFunc;
+ BitmapScanlineProcPtr secondFunc;
+ int flag;
+
+#ifdef TRIPLE_BITS
+ if((bg != -1) &&
+ ((infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) ||
+ ((infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) &&
+ (!CHECK_RGB_EQUAL(bg))))) {
+#else
+ if((bg != -1) &&
+ (infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
+#endif
+ if(rop == GXcopy) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ } else SecondPassColor = bg;
+ bg = -1;
+ }
+
+#ifdef TRIPLE_BITS
+ if(skipleft) {
+#else
+ if(skipleft &&
+ (!(infoRec->CPUToScreenColorExpandFillFlags & LEFT_EDGE_CLIPPING) ||
+ (!(infoRec->CPUToScreenColorExpandFillFlags & LEFT_EDGE_CLIPPING_NEGATIVE_X) &&
+ (skipleft > x)))) {
+#endif
+ firstFunc = BitmapScanline_Shifted;
+ secondFunc = BitmapScanline_Shifted_Inverted;
+ shift = skipleft;
+ skipleft = 0;
+ } else {
+ firstFunc = BitmapScanline;
+ secondFunc = BitmapScanline_Inverted;
+ w += skipleft;
+ x -= skipleft;
+ }
+
+#ifdef TRIPLE_BITS
+ dwords = (3 * w + 31) >> 5;
+#else
+ dwords = (w + 31) >> 5;
+#endif
+
+SECOND_PASS:
+
+ flag = (infoRec->CPUToScreenColorExpandFillFlags
+ & CPU_TRANSFER_PAD_QWORD) && ((dwords * h) & 0x01);
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, x, y, w, h, skipleft);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+#ifndef FIXEDBASE
+ if((dwords * h) <= infoRec->ColorExpandRange)
+ while(h--) {
+ base = (*firstFunc)((CARD32*)srcp, base, dwords, shift);
+ srcp += srcwidth;
+ }
+ else
+#endif
+ while(h--) {
+ (*firstFunc)((CARD32*)srcp, base, dwords, shift);
+ srcp += srcwidth;
+ }
+
+ if(flag){
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+
+ if(SecondPassColor != -1) {
+ fg = SecondPassColor;
+ SecondPassColor = -1;
+ firstFunc = secondFunc;
+ srcp = src;
+ goto SECOND_PASS;
+ }
+
+ if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+#ifndef FIXEDBASE
+
+void
+#ifdef TRIPLE_BITS
+EXPNAME(XAAWriteBitmapScanlineColorExpand3)(
+#else
+EXPNAME(XAAWriteBitmapScanlineColorExpand)(
+#endif
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32* base;
+ unsigned char *srcp = src;
+ int SecondPassColor = -1;
+ int shift = 0, dwords, bufferNo;
+ BitmapScanlineProcPtr firstFunc;
+ BitmapScanlineProcPtr secondFunc;
+
+#ifdef TRIPLE_BITS
+ if((bg != -1) &&
+ ((infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)
+ || ((infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) &&
+ (!CHECK_RGB_EQUAL(bg))))) {
+#else
+ if((bg != -1) &&
+ (infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)){
+#endif
+ if(rop == GXcopy) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ } else SecondPassColor = bg;
+ bg = -1;
+ }
+
+#ifdef TRIPLE_BITS
+ if(skipleft) {
+#else
+ if(skipleft &&
+ (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ LEFT_EDGE_CLIPPING) ||
+ (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ LEFT_EDGE_CLIPPING_NEGATIVE_X) && (skipleft > x)))) {
+#endif
+ firstFunc = BitmapScanline_Shifted;
+ secondFunc = BitmapScanline_Shifted_Inverted;
+ shift = skipleft;
+ skipleft = 0;
+ } else {
+ firstFunc = BitmapScanline;
+ secondFunc = BitmapScanline_Inverted;
+ w += skipleft;
+ x -= skipleft;
+ }
+
+#ifdef TRIPLE_BITS
+ dwords = (3 * w + 31) >> 5;
+#else
+ dwords = (w + 31) >> 5;
+#endif
+
+SECOND_PASS:
+
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn, fg, bg, rop, planemask);
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, x, y, w, h, skipleft);
+
+ bufferNo = 0;
+
+ while(h--) {
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ (*firstFunc)((CARD32*)srcp, base, dwords, shift);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ srcp += srcwidth;
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ }
+
+ if(SecondPassColor != -1) {
+ fg = SecondPassColor;
+ SecondPassColor = -1;
+ firstFunc = secondFunc;
+ srcp = src;
+ goto SECOND_PASS;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaCpyArea.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaCpyArea.c
new file mode 100644
index 000000000..2ea9a148e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaCpyArea.c
@@ -0,0 +1,354 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaCpyArea.c,v 1.10 1999/04/04 08:46:24 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "migc.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+
+/*
+ Written mostly by Harm Hanemaayer (H.Hanemaayer@inter.nl.net).
+ */
+
+
+RegionPtr
+XAACopyArea(
+ DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(pDstDrawable->type == DRAWABLE_WINDOW) {
+ if((pSrcDrawable->type == DRAWABLE_WINDOW) ||
+ IS_OFFSCREEN_PIXMAP(pSrcDrawable)){
+ if(infoRec->ScreenToScreenBitBlt &&
+ CHECK_ROP(pGC,infoRec->ScreenToScreenBitBltFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->ScreenToScreenBitBltFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->ScreenToScreenBitBltFlags))
+ return (XAABitBlt( pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ XAADoBitBlt, 0L));
+ } else {
+ if(infoRec->WritePixmap &&
+ ((pDstDrawable->bitsPerPixel == pSrcDrawable->bitsPerPixel) ||
+ ((pDstDrawable->bitsPerPixel == 24) &&
+ (pSrcDrawable->bitsPerPixel == 32) &&
+ (infoRec->WritePixmapFlags & CONVERT_32BPP_TO_24BPP))) &&
+ CHECK_ROP(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_NO_GXCOPY(pGC,infoRec->WritePixmapFlags))
+ return (XAABitBlt( pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ XAADoImageWrite, 0L));
+ }
+ } else if(IS_OFFSCREEN_PIXMAP(pDstDrawable)){
+ if((pSrcDrawable->type == DRAWABLE_WINDOW) ||
+ IS_OFFSCREEN_PIXMAP(pSrcDrawable)){
+ if(infoRec->ScreenToScreenBitBlt &&
+ CHECK_ROP(pGC,infoRec->ScreenToScreenBitBltFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->ScreenToScreenBitBltFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->ScreenToScreenBitBltFlags))
+ return (XAABitBlt( pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ XAADoBitBlt, 0L));
+ }
+ }
+
+ return (XAAFallbackOps.CopyArea(pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty));
+}
+
+
+void
+XAADoBitBlt(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc )
+{
+ int nbox, careful;
+ BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
+ DDXPointPtr pptTmp, pptNew1, pptNew2;
+ int xdir, ydir;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ /* XXX we have to err on the side of safety when both are windows,
+ * because we don't know if IncludeInferiors is being used.
+ */
+ careful = ((pSrc == pDst) ||
+ ((pSrc->type == DRAWABLE_WINDOW) &&
+ (pDst->type == DRAWABLE_WINDOW)));
+
+ pbox = REGION_RECTS(prgnDst);
+ nbox = REGION_NUM_RECTS(prgnDst);
+
+ pboxNew1 = NULL;
+ pptNew1 = NULL;
+ pboxNew2 = NULL;
+ pptNew2 = NULL;
+ if (careful && (pptSrc->y < pbox->y1)) {
+ /* walk source botttom to top */
+ ydir = -1;
+
+ if (nbox > 1) {
+ /* keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ if(!pboxNew1)
+ return;
+ pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pptNew1) {
+ DEALLOCATE_LOCAL(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox) {
+ while ((pboxNext >= pbox) &&
+ (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp <= pboxBase) {
+ *pboxNew1++ = *pboxTmp++;
+ *pptNew1++ = *pptTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ pptNew1 -= nbox;
+ pptSrc = pptNew1;
+ }
+ } else {
+ /* walk source top to bottom */
+ ydir = 1;
+ }
+
+ if (careful && (pptSrc->x < pbox->x1)) {
+ /* walk source right to left */
+ xdir = -1;
+
+ if (nbox > 1) {
+ /* reverse order of rects in each band */
+ pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pboxNew2 || !pptNew2) {
+ if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
+ if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
+ if (pboxNew1) {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox) {
+ while ((pboxNext < pbox+nbox) &&
+ (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp != pboxBase) {
+ *pboxNew2++ = *--pboxTmp;
+ *pptNew2++ = *--pptTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ pptNew2 -= nbox;
+ pptSrc = pptNew2;
+ }
+ } else {
+ /* walk source left to right */
+ xdir = 1;
+ }
+
+ (*infoRec->ScreenToScreenBitBlt)(infoRec->pScrn, nbox, pptSrc, pbox,
+ xdir, ydir, pGC->alu, pGC->planemask);
+
+ if (pboxNew2) {
+ DEALLOCATE_LOCAL(pptNew2);
+ DEALLOCATE_LOCAL(pboxNew2);
+ }
+ if (pboxNew1) {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+
+}
+
+void
+XAADoImageWrite(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc )
+{
+ int srcwidth;
+ unsigned char* psrcBase; /* start of image */
+ unsigned char* srcPntr; /* index into the image */
+ BoxPtr pbox = REGION_RECTS(prgnDst);
+ int nbox = REGION_NUM_RECTS(prgnDst);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int Bpp = pSrc->bitsPerPixel >> 3;
+
+ psrcBase = (unsigned char *)((PixmapPtr)pSrc)->devPrivate.ptr;
+ srcwidth = (int)((PixmapPtr)pSrc)->devKind;
+
+ for(; nbox; pbox++, pptSrc++, nbox--) {
+ srcPntr = psrcBase + (pptSrc->y * srcwidth) + (pptSrc->x * Bpp);
+
+ (*infoRec->WritePixmap)(infoRec->pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, srcPntr, srcwidth,
+ pGC->alu, pGC->planemask, -1, pSrc->bitsPerPixel, pSrc->depth);
+ }
+}
+
+void
+XAAScreenToScreenBitBlt(
+ ScrnInfoPtr pScrn,
+ int nbox,
+ DDXPointPtr pptSrc,
+ BoxPtr pbox,
+ int xdir, int ydir,
+ int alu,
+ unsigned int planemask )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int dirsetup;
+
+ if ((!(infoRec->CopyAreaFlags & ONLY_TWO_BITBLT_DIRECTIONS)
+ || (xdir == ydir)) &&
+ (!(infoRec->CopyAreaFlags & ONLY_LEFT_TO_RIGHT_BITBLT)
+ || (xdir == 1))) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ xdir, ydir, alu, planemask, -1);
+ for (; nbox; pbox++, pptSrc++, nbox--)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
+ pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ SET_SYNC_FLAG(infoRec);
+ return;
+ }
+
+ if (infoRec->CopyAreaFlags & ONLY_LEFT_TO_RIGHT_BITBLT) {
+ /*
+ * This is the case of a chip that only supports xdir = 1,
+ * with ydir = 1 or ydir = -1, but we have xdir = -1.
+ */
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ 1, ydir, alu, planemask, -1);
+ for (; nbox; pbox++, pptSrc++, nbox--)
+ if (pptSrc->y != pbox->y1 || pptSrc->x >= pbox->x1)
+ /* No problem. Do a xdir = 1 blit instead. */
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x, pptSrc->y, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ else
+ {
+ /*
+ * This is the difficult case. Needs striping into
+ * non-overlapping horizontal chunks.
+ */
+ int stripeWidth, w, fullStripes, extra, i;
+ stripeWidth = 16;
+ w = pbox->x2 - pbox->x1;
+ if (pbox->x1 - pptSrc->x < stripeWidth)
+ stripeWidth = pbox->x1 - pptSrc->x;
+ fullStripes = w / stripeWidth;
+ extra = w % stripeWidth;
+
+ /* First, take care of the little bit on the far right */
+ if (extra)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x + fullStripes * stripeWidth, pptSrc->y,
+ pbox->x1 + fullStripes * stripeWidth, pbox->y1,
+ extra, pbox->y2 - pbox->y1);
+
+ /* Now, take care of the rest of the blit */
+ for (i = fullStripes - 1; i >= 0; i--)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x + i * stripeWidth, pptSrc->y,
+ pbox->x1 + i * stripeWidth, pbox->y1,
+ stripeWidth, pbox->y2 - pbox->y1);
+ }
+ SET_SYNC_FLAG(infoRec);
+ return;
+ }
+
+ /*
+ * Now the case of a chip that only supports xdir = ydir = 1 or
+ * xdir = ydir = -1, but we have xdir != ydir.
+ */
+ dirsetup = 0; /* No direction set up yet. */
+ for (; nbox; pbox++, pptSrc++, nbox--) {
+ if (xdir == 1 && pptSrc->y != pbox->y1) {
+ /* Do a xdir = ydir = -1 blit instead. */
+ if (dirsetup != -1) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ -1, -1, alu, planemask, -1);
+ dirsetup = -1;
+ }
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
+ pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ }
+ else if (xdir == -1 && pptSrc->y != pbox->y1) {
+ /* Do a xdir = ydir = 1 blit instead. */
+ if (dirsetup != 1) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ 1, 1, alu, planemask, -1);
+ dirsetup = 1;
+ }
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
+ pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ }
+ else
+ if (xdir == 1) {
+ /*
+ * xdir = 1, ydir = -1.
+ * Perform line-by-line xdir = ydir = 1 blits, going up.
+ */
+ int i;
+ if (dirsetup != 1) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ 1, 1, alu, planemask, -1);
+ dirsetup = 1;
+ }
+ for (i = pbox->y2 - pbox->y1 - 1; i >= 0; i--)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x, pptSrc->y + i, pbox->x1, pbox->y1 + i,
+ pbox->x2 - pbox->x1, 1);
+ }
+ else {
+ /*
+ * xdir = -1, ydir = 1.
+ * Perform line-by-line xdir = ydir = -1 blits, going down.
+ */
+ int i;
+ if (dirsetup != -1) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ -1, -1, alu, planemask, -1);
+ dirsetup = -1;
+ }
+ for (i = 0; i < pbox->y2 - pbox->y1; i++)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x, pptSrc->y + i, pbox->x1, pbox->y1 + i,
+ pbox->x2 - pbox->x1, 1);
+ }
+ } /* next box */
+ SET_SYNC_FLAG(infoRec);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaCpyPlane.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaCpyPlane.c
new file mode 100644
index 000000000..320fab72e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaCpyPlane.c
@@ -0,0 +1,205 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaCpyPlane.c,v 1.9 1999/08/14 10:50:13 dawes Exp $ */
+
+/*
+ A CopyPlane function that handles bitmap->screen copies and
+ sends anything else to the Fallback.
+
+ Also, a PushPixels for solid fill styles.
+
+ Written by Mark Vojkovich (markv@valinux.com)
+
+*/
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+#include "servermd.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "mi.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+
+static void XAACopyPlane1toNColorExpand(DrawablePtr pSrc, DrawablePtr pDst,
+ GCPtr pGC, RegionPtr rgnDst,
+ DDXPointPtr pptSrc);
+static void XAACopyPlaneNtoNColorExpand(DrawablePtr pSrc, DrawablePtr pDst,
+ GCPtr pGC, RegionPtr rgnDst,
+ DDXPointPtr pptSrc);
+
+
+static unsigned long TmpBitPlane;
+
+RegionPtr
+XAACopyPlaneColorExpansion(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+){
+ if(pSrc->type == DRAWABLE_PIXMAP) {
+ if(pSrc->bitsPerPixel == 1) {
+ return(XAABitBlt(pSrc, pDst, pGC, srcx, srcy,
+ width, height, dstx, dsty,
+ XAACopyPlane1toNColorExpand, bitPlane));
+ } else if(bitPlane < (1 << pDst->depth)){
+ TmpBitPlane = bitPlane;
+ return(XAABitBlt(pSrc, pDst, pGC, srcx, srcy,
+ width, height, dstx, dsty,
+ XAACopyPlaneNtoNColorExpand, bitPlane));
+ }
+ }
+
+ return (XAAFallbackOps.CopyPlane(pSrc, pDst, pGC, srcx, srcy,
+ width, height, dstx, dsty, bitPlane));
+}
+
+
+static void
+XAACopyPlane1toNColorExpand(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ RegionPtr rgnDst,
+ DDXPointPtr pptSrc )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ BoxPtr pbox = REGION_RECTS(rgnDst);
+ int numrects = REGION_NUM_RECTS(rgnDst);
+ unsigned char *src = ((PixmapPtr)pSrc)->devPrivate.ptr;
+ int srcwidth = ((PixmapPtr)pSrc)->devKind;
+
+ while(numrects--) {
+ (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ src + (srcwidth * pptSrc->y) + ((pptSrc->x >> 5) << 2),
+ srcwidth, pptSrc->x & 31,
+ pGC->fgPixel, pGC->bgPixel, pGC->alu, pGC->planemask);
+ pbox++; pptSrc++;
+ }
+}
+
+
+static void
+XAACopyPlaneNtoNColorExpand(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ RegionPtr rgnDst,
+ DDXPointPtr pptSrc
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ BoxPtr pbox = REGION_RECTS(rgnDst);
+ int numrects = REGION_NUM_RECTS(rgnDst);
+ unsigned char *src = ((PixmapPtr)pSrc)->devPrivate.ptr;
+ unsigned char *data, *srcPtr, *dataPtr;
+ int srcwidth = ((PixmapPtr)pSrc)->devKind;
+ int pitch, width, height, h, i, index, offset;
+ int Bpp = pSrc->bitsPerPixel >> 3;
+ unsigned long mask = TmpBitPlane;
+
+ if(TmpBitPlane < 8) {
+ offset = 0;
+ } else if(TmpBitPlane < 16) {
+ offset = 1;
+ mask >>= 8;
+ } else if(TmpBitPlane < 24) {
+ offset = 2;
+ mask >>= 16;
+ } else {
+ offset = 3;
+ mask >>= 24;
+ }
+
+ if(IS_OFFSCREEN_PIXMAP(pSrc))
+ SYNC_CHECK(pSrc);
+
+ while(numrects--) {
+ width = pbox->x2 - pbox->x1;
+ h = height = pbox->y2 - pbox->y1;
+ pitch = BitmapBytePad(width);
+
+ if(!(data = ALLOCATE_LOCAL(height * pitch)))
+ goto ALLOC_FAILED;
+
+ bzero(data, height * pitch);
+
+ dataPtr = data;
+ srcPtr = ((pbox->y1 + pSrc->y) * srcwidth) + src +
+ ((pbox->x1 + pSrc->x) * Bpp) + offset;
+ while(h--) {
+ for(i = index = 0; i < width; i++, index += Bpp) {
+ if(mask & srcPtr[index])
+ dataPtr[i >> 3] |= (1 << (i & 7));
+ }
+ dataPtr += pitch;
+ srcPtr += srcwidth;
+ }
+
+ (*infoRec->WriteBitmap)(infoRec->pScrn,
+ pbox->x1, pbox->y1, width, height, data, pitch, 0,
+ pGC->fgPixel, pGC->bgPixel, pGC->alu, pGC->planemask);
+
+ DEALLOCATE_LOCAL(data);
+
+ALLOC_FAILED:
+
+ pbox++; pptSrc++;
+ }
+}
+
+void
+XAAPushPixelsSolidColorExpansion(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy,
+ int xOrg, int yOrg )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int MaxBoxes = REGION_NUM_RECTS(pGC->pCompositeClip);
+ BoxPtr pbox, pClipBoxes;
+ int nboxes, srcx, srcy;
+ xRectangle TheRect;
+ unsigned char *src = pBitMap->devPrivate.ptr;
+ int srcwidth = pBitMap->devKind;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ TheRect.x = xOrg;
+ TheRect.y = yOrg;
+ TheRect.width = dx;
+ TheRect.height = dy;
+
+ if(MaxBoxes > (infoRec->PreAllocSize/sizeof(BoxRec))) {
+ pClipBoxes = xalloc(MaxBoxes * sizeof(BoxRec));
+ if(!pClipBoxes) return;
+ } else pClipBoxes = (BoxPtr)infoRec->PreAllocMem;
+
+ nboxes = XAAGetRectClipBoxes(pGC->pCompositeClip, pClipBoxes, 1, &TheRect);
+ pbox = pClipBoxes;
+
+ while(nboxes--) {
+ srcx = pbox->x1 - xOrg;
+ srcy = pbox->y1 - yOrg;
+ (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ src + (srcwidth * srcy) + ((srcx >> 5) << 2),
+ srcwidth, srcx & 31,
+ pGC->fgPixel, -1, pGC->alu, pGC->planemask);
+ pbox++;
+ }
+
+ if(pClipBoxes != (BoxPtr)infoRec->PreAllocMem)
+ xfree(pClipBoxes);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaCpyWin.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaCpyWin.c
new file mode 100644
index 000000000..3c087bee1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaCpyWin.c
@@ -0,0 +1,82 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaCpyWin.c,v 1.2 1998/07/25 16:58:43 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "xaawrap.h"
+
+/*
+ Written by Harm Hanemaayer (H.Hanemaayer@inter.nl.net).
+*/
+
+extern WindowPtr *WindowTable;
+
+void
+XAACopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc )
+{
+ DDXPointPtr pptSrc, ppt;
+ RegionRec rgnDst;
+ BoxPtr pbox;
+ int dx, dy, nbox;
+ WindowPtr pwinRoot;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAInfoRecPtr infoRec =
+ GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
+
+ if (!infoRec->pScrn->vtSema || !infoRec->ScreenToScreenBitBlt) {
+ XAA_SCREEN_PROLOGUE (pScreen, CopyWindow);
+ if(infoRec->pScrn->vtSema && infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
+ XAA_SCREEN_EPILOGUE (pScreen, CopyWindow, XAACopyWindow);
+ return;
+ }
+
+ pwinRoot = WindowTable[pScreen->myNum];
+
+ REGION_INIT(pScreen, &rgnDst, NullBox, 0);
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
+ REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
+
+ pbox = REGION_RECTS(&rgnDst);
+ nbox = REGION_NUM_RECTS(&rgnDst);
+ if(!nbox ||
+ !(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) {
+ REGION_UNINIT(pScreen, &rgnDst);
+ return;
+ }
+ ppt = pptSrc;
+
+ while(nbox--) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ ppt++; pbox++;
+ }
+
+ infoRec->ScratchGC.planemask = ~0L;
+ infoRec->ScratchGC.alu = GXcopy;
+
+ XAADoBitBlt((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
+ &(infoRec->ScratchGC), &rgnDst, pptSrc);
+
+ DEALLOCATE_LOCAL(pptSrc);
+ REGION_UNINIT(pScreen, &rgnDst);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaDashLine.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaDashLine.c
new file mode 100644
index 000000000..3a076796e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaDashLine.c
@@ -0,0 +1,275 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaDashLine.c,v 1.3 1999/05/30 03:03:30 dawes Exp $ */
+
+#include "X.h"
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "miline.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+
+void
+#ifdef POLYSEGMENT
+XAAPolySegmentDashed(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+#else
+XAAPolyLinesDashed(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode, /* Origin or Previous */
+ int npt, /* number of points */
+ DDXPointPtr pptInit
+#endif
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAAGCPtr pGCPriv = (XAAGCPtr) (pGC)->devPrivates[XAAGCIndex].ptr;
+ BoxPtr pboxInit = REGION_RECTS(pGC->pCompositeClip);
+ int nboxInit = REGION_NUM_RECTS(pGC->pCompositeClip);
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ int xorg = pDrawable->x;
+ int yorg = pDrawable->y;
+ int nbox;
+ BoxPtr pbox;
+#ifndef POLYSEGMENT
+ DDXPointPtr ppt;
+#endif
+ unsigned int oc1, oc2;
+ int dmin, dmaj, e, octant;
+ int x1, x2, y1, y2, tmp, len, offset;
+ int PatternLength, PatternOffset;
+
+ if(!nboxInit)
+ return;
+
+ PatternLength = pGCPriv->DashLength;
+ PatternOffset = pGC->dashOffset % PatternLength;
+
+ (*infoRec->SetupForDashedLine)(infoRec->pScrn, pGC->fgPixel,
+ (pGC->lineStyle == LineDoubleDash) ? pGC->bgPixel : -1,
+ pGC->alu, pGC->planemask, PatternLength, pGCPriv->DashPattern);
+
+
+#ifdef POLYSEGMENT
+ while (nseg--)
+#else
+ ppt = pptInit;
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+ while(--npt)
+#endif
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+
+#ifdef POLYSEGMENT
+ x1 = pSeg->x1 + xorg;
+ y1 = pSeg->y1 + yorg;
+ x2 = pSeg->x2 + xorg;
+ y2 = pSeg->y2 + yorg;
+ pSeg++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious) {
+ xorg = x1;
+ yorg = y1;
+ }
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+#endif
+
+
+ if (infoRec->SubsequentDashedBresenhamLine) {
+ if((dmaj = x2 - x1) < 0) {
+ dmaj = -dmaj;
+ octant = XDECREASING;
+ } else octant = 0;
+
+ if((dmin = y2 - y1) < 0) {
+ dmin = -dmin;
+ octant |= YDECREASING;
+ }
+
+ if(dmin >= dmaj){
+ tmp = dmin; dmin = dmaj; dmaj = tmp;
+ octant |= YMAJOR;
+ }
+
+ e = -dmaj - ((bias >> octant) & 1);
+ len = dmaj;
+ dmin <<= 1;
+ dmaj <<= 1;
+ }
+
+ while(nbox--) {
+ oc1 = oc2 = 0;
+ OUTCODES(oc1, x1, y1, pbox);
+ OUTCODES(oc2, x2, y2, pbox);
+ if (!(oc1 | oc2)) { /* uncliped */
+ if(infoRec->SubsequentDashedTwoPointLine) {
+ (*infoRec->SubsequentDashedTwoPointLine)(
+ infoRec->pScrn, x1, y1, x2, y2,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? 0 :
+#endif
+ OMIT_LAST, PatternOffset);
+ } else {
+ (*infoRec->SubsequentDashedBresenhamLine)(
+ infoRec->pScrn, x1, y1, dmaj, dmin, e,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? (len+1) :
+#endif
+ len, octant, PatternOffset);
+ }
+ break;
+ } else if (oc1 & oc2) { /* completely clipped */
+ pbox++;
+ } else if (infoRec->ClippingFlags & HARDWARE_CLIP_DASHED_LINE) {
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ pbox->x1, pbox->y1, pbox->x2 - 1, pbox->y2 - 1);
+
+ if(infoRec->SubsequentDashedBresenhamLine) {
+ (*infoRec->SubsequentDashedBresenhamLine)(
+ infoRec->pScrn, x1, y1, dmaj, dmin, e,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? (len+1) :
+#endif
+ len, octant, PatternOffset);
+ } else {
+ (*infoRec->SubsequentDashedTwoPointLine)(
+ infoRec->pScrn, x1, y1, x2, y2,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? 0 :
+#endif
+ OMIT_LAST, PatternOffset
+ );
+ }
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+ pbox++;
+ } else {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int err, adx, ady;
+
+ if(octant & YMAJOR) {
+ ady = dmaj >> 1;
+ adx = dmin >> 1;
+ } else {
+ ady = dmin >> 1;
+ adx = dmaj >> 1;
+ }
+
+ if (miZeroClipLine(pbox->x1, pbox->y1,
+ pbox->x2 - 1, pbox->y2 - 1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pbox++;
+ continue;
+ }
+
+ if (octant & YMAJOR)
+ len = abs(new_y2 - new_y1);
+ else
+ len = abs(new_x2 - new_x1);
+#ifdef POLYSEGMENT
+ if (clip2 != 0 || pGC->capStyle != CapNotLast)
+ len++;
+#else
+ len += (clip2 != 0);
+#endif
+ if (len) {
+ int abserr, clipdx, clipdy;
+ /* unwind bresenham error term to first point */
+ if (clip1) {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+
+ if (octant & YMAJOR)
+ err = e + clipdy*dmin - clipdx*dmaj;
+ else
+ err = e + clipdx*dmin - clipdy*dmaj;
+ } else
+ err = e;
+
+#define range infoRec->DashedBresenhamLineErrorTermBits
+ abserr = abs(err);
+ while((abserr & range) ||
+ (dmaj & range) ||
+ (dmin & range)) {
+ dmin >>= 1;
+ dmaj >>= 1;
+ abserr >>= 1;
+ err /= 2;
+ }
+
+ if(octant & YMAJOR)
+ offset = abs(new_y1 - y1);
+ else
+ offset = abs(new_x1 - x1);
+
+ offset += PatternOffset;
+ offset %= PatternLength;
+
+ (*infoRec->SubsequentDashedBresenhamLine)(
+ infoRec->pScrn, new_x1, new_y1,
+ dmaj, dmin, err, len, octant, offset);
+ }
+ pbox++;
+ }
+ } /* while (nbox--) */
+#ifndef POLYSEGMENT
+ len = abs(y2 - y1);
+ tmp = abs(x2 - x1);
+ PatternOffset += (len > tmp) ? len : tmp;
+ PatternOffset %= PatternLength;
+#endif
+ } /* while (nline--) */
+
+#ifndef POLYSEGMENT
+ /* paint the last point if the end style isn't CapNotLast.
+ (Assume that a projecting, butt, or round cap that is one
+ pixel wide is the same as the single pixel of the endpoint.)
+ */
+
+ if ((pGC->capStyle != CapNotLast) &&
+ ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
+ (ppt->y + yorg != pptInit->y + pDrawable->y) ||
+ (ppt == pptInit + 1)))
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+ while (nbox--) {
+ if ((x2 >= pbox->x1) && (y2 >= pbox->y1) &&
+ (x2 < pbox->x2) && (y2 < pbox->y2))
+ {
+ if(infoRec->SubsequentDashedTwoPointLine) {
+ (*infoRec->SubsequentDashedTwoPointLine)(
+ infoRec->pScrn, x2, y2, x2, y2, 0,
+ PatternOffset);
+ } else {
+ (*infoRec->SubsequentDashedBresenhamLine)(
+ infoRec->pScrn, x2, y2, 2, 0, -1,
+ 1, 0, PatternOffset);
+ }
+ break;
+ } else
+ pbox++;
+ }
+ }
+#endif
+
+ SET_SYNC_FLAG(infoRec);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaFallback.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaFallback.c
new file mode 100644
index 000000000..01b4bb408
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaFallback.c
@@ -0,0 +1,352 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaFallback.c,v 1.5 1999/05/30 03:03:31 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "xaawrap.h"
+
+
+
+static void
+XAAFillSpansFallback(
+ DrawablePtr pDraw,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAASetSpansFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ char *pcharsrc,
+ register DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPutImageFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static RegionPtr
+XAACopyAreaFallback(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty )
+{
+ RegionPtr ret;
+
+ XAA_GC_OP_PROLOGUE(pGC);
+ if((pSrc->type == DRAWABLE_WINDOW) || (pDst->type == DRAWABLE_WINDOW) ||
+ IS_OFFSCREEN_PIXMAP(pSrc) || IS_OFFSCREEN_PIXMAP(pDst)) {
+ SYNC_CHECK(pGC);
+ }
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ XAA_GC_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static RegionPtr
+XAACopyPlaneFallback(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane )
+{
+ RegionPtr ret;
+
+ XAA_GC_OP_PROLOGUE(pGC);
+ if((pSrc->type == DRAWABLE_WINDOW) || (pDst->type == DRAWABLE_WINDOW) ||
+ IS_OFFSCREEN_PIXMAP(pSrc) || IS_OFFSCREEN_PIXMAP(pDst)) {
+ SYNC_CHECK(pGC);
+ }
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+ XAA_GC_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static void
+XAAPolyPointFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAPolylinesFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolySegmentFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolyRectangleFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolyArcFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAFillPolygonFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAPolyFillRectFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAPolyFillArcFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static int
+XAAPolyText8Fallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars )
+{
+ int ret;
+
+ XAA_GC_OP_PROLOGUE(pGC);
+ SYNC_CHECK(pGC);
+ ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
+ XAA_GC_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static int
+XAAPolyText16Fallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars )
+{
+ int ret;
+
+ XAA_GC_OP_PROLOGUE(pGC);
+ SYNC_CHECK(pGC);
+ ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
+ XAA_GC_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static void
+XAAImageText8Fallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAImageText16Fallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAImageGlyphBltFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolyGlyphBltFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPushPixelsFallback(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy, int xOrg, int yOrg )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+GCOps XAAFallbackOps = {
+ XAAFillSpansFallback, XAASetSpansFallback,
+ XAAPutImageFallback, XAACopyAreaFallback,
+ XAACopyPlaneFallback, XAAPolyPointFallback,
+ XAAPolylinesFallback, XAAPolySegmentFallback,
+ XAAPolyRectangleFallback, XAAPolyArcFallback,
+ XAAFillPolygonFallback, XAAPolyFillRectFallback,
+ XAAPolyFillArcFallback, XAAPolyText8Fallback,
+ XAAPolyText16Fallback, XAAImageText8Fallback,
+ XAAImageText16Fallback, XAAImageGlyphBltFallback,
+ XAAPolyGlyphBltFallback, XAAPushPixelsFallback,
+#ifdef NEED_LINEHELPER
+ NULL,
+#endif
+ {NULL} /* devPrivate */
+};
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaFillArc.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaFillArc.c
new file mode 100644
index 000000000..352d8e084
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaFillArc.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright 1996 The XFree86 Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HARM HANEMAAYER 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.
+ *
+ * Written by Harm Hanemaayer (H.Hanemaayer@inter.nl.net).
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaFillArc.c,v 1.4 1999/05/30 03:03:31 dawes Exp $ */
+
+/*
+ * Filled solid arcs, based on cfbfillarc.c.
+ *
+ * Fill arc using calls to low-level span fill. Because the math for
+ * each span can be done concurrently with the drawing of the span
+ * with a graphics coprocessor operation, this is faster than just
+ * using miPolyFillArc, which first calculates all the spans and then
+ * calls FillSpans.
+ *
+ * Clipped arcs are dispatched to FillSpans.
+ */
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "mifillarc.h"
+#include "mi.h"
+
+/*
+ * This is based on the integer-math versions from mi. Perhaps on a
+ * Pentium, the floating-point (double)-math version is faster.
+ */
+
+static void
+XAAFillEllipseSolid(DrawablePtr pDraw, GCPtr pGC, xArc *arc)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ register int x, y, e;
+ int yk, xk, ym, xm, dx, dy, xorg, yorg;
+ int slw;
+ miFillArcRec info;
+
+ (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
+ pGC->planemask);
+
+ miFillArcSetup(arc, &info);
+ MIFILLARCSETUP();
+ if (pGC->miTranslate)
+ {
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ }
+ while (y > 0)
+ {
+ MIFILLARCSTEP(slw);
+ if (slw > 0) {
+ (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn, xorg - x,
+ yorg - y, slw, 1);
+ if (miFillArcLower(slw))
+ (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
+ xorg - x, yorg + y + dy, slw, 1);
+ }
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+#define ADDSPAN(l,r) \
+ if (r >= l) \
+ (*infoRec->SubsequentSolidFillRect)( \
+ infoRec->pScrn, l, ya, r - l + 1, 1);
+
+#define ADDSLICESPANS(flip) \
+ if (!flip) \
+ { \
+ ADDSPAN(xl, xr); \
+ } \
+ else \
+ { \
+ xc = xorg - x; \
+ ADDSPAN(xc, xr); \
+ xc += slw - 1; \
+ ADDSPAN(xl, xc); \
+ }
+
+static void
+XAAFillArcSliceSolid(DrawablePtr pDraw, GCPtr pGC, xArc *arc)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
+ register int x, y, e;
+ miFillArcRec info;
+ miArcSliceRec slice;
+ int ya, xl, xr, xc;
+
+ (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
+ pGC->planemask);
+
+ miFillArcSetup(arc, &info);
+ miFillArcSliceSetup(arc, &slice, pGC);
+ MIFILLARCSETUP();
+ slw = arc->height;
+ if (slice.flip_top || slice.flip_bot)
+ slw += (arc->height >> 1) + 1;
+ if (pGC->miTranslate)
+ {
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ slice.edge1.x += pDraw->x;
+ slice.edge2.x += pDraw->x;
+ }
+ while (y > 0)
+ {
+ MIFILLARCSTEP(slw);
+ MIARCSLICESTEP(slice.edge1);
+ MIARCSLICESTEP(slice.edge2);
+ if (miFillSliceUpper(slice))
+ {
+ ya = yorg - y;
+ MIARCSLICEUPPER(xl, xr, slice, slw);
+
+ ADDSLICESPANS(slice.flip_top);
+ }
+ if (miFillSliceLower(slice))
+ {
+ ya = yorg + y + dy;
+ MIARCSLICELOWER(xl, xr, slice, slw);
+ ADDSLICESPANS(slice.flip_bot);
+ }
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+void
+XAAPolyFillArcSolid(pDraw, pGC, narcs, parcs)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ register xArc *arc;
+ register int i;
+ int x2, y2;
+ BoxRec box;
+ RegionPtr cclip;
+
+ cclip = pGC->pCompositeClip;
+
+ if(!REGION_NUM_RECTS(cclip))
+ return;
+
+ for (arc = parcs, i = narcs; --i >= 0; arc++)
+ {
+ if (miFillArcEmpty(arc))
+ continue;
+ if (miCanFillArc(arc))
+ {
+ box.x1 = arc->x + pDraw->x;
+ box.y1 = arc->y + pDraw->y;
+ /*
+ * Because box.x2 and box.y2 get truncated to 16 bits, and the
+ * RECT_IN_REGION test treats the resulting number as a signed
+ * integer, the RECT_IN_REGION test alone can go the wrong way.
+ * This can result in a server crash because the rendering
+ * routines in this file deal directly with cpu addresses
+ * of pixels to be stored, and do not clip or otherwise check
+ * that all such addresses are within their respective pixmaps.
+ * So we only allow the RECT_IN_REGION test to be used for
+ * values that can be expressed correctly in a signed short.
+ */
+ x2 = box.x1 + (int)arc->width + 1;
+ box.x2 = x2;
+ y2 = box.y1 + (int)arc->height + 1;
+ box.y2 = y2;
+ if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) &&
+ (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
+ {
+ if ((arc->angle2 >= FULLCIRCLE) ||
+ (arc->angle2 <= -FULLCIRCLE))
+ XAAFillEllipseSolid(pDraw, pGC, arc);
+ else
+ XAAFillArcSliceSolid(pDraw, pGC, arc);
+ continue;
+ }
+ }
+ miPolyFillArc(pDraw, pGC, 1, arc);
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaFillPoly.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaFillPoly.c
new file mode 100644
index 000000000..d8add9ea0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaFillPoly.c
@@ -0,0 +1,954 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaFillPoly.c,v 1.11 1999/05/30 03:03:31 dawes Exp $ */
+
+/*
+ * Copyright 1996 The XFree86 Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HARM HANEMAAYER 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.
+ *
+ */
+
+/*
+ * Written by Mark Vojkovich. Loosly based on an original version
+ * written by Harm Hanemaayer (H.Hanemaayer@inter.nl.net) which
+ * only did solid rectangles and didn't have trapezoid support.
+ *
+ */
+
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "mi.h"
+#define PSZ 8 /* PSZ doesn't matter */
+#include "cfb.h"
+
+#include "xaa.h"
+#include "xaalocal.h"
+
+#define POLY_USE_MI 0
+#define POLY_FULLY_CLIPPED 1
+#define POLY_IS_EASY 2
+
+
+#define Setup(c,x,vertex,dx,dy,e,sign,step,DX) {\
+ x = intToX(vertex); \
+ if ((dy = intToY(c) - y)) { \
+ DX = dx = intToX(c) - x; \
+ step = 0; \
+ if (dx >= 0) \
+ { \
+ e = 0; \
+ sign = 1; \
+ if (dx >= dy) {\
+ step = dx / dy; \
+ dx %= dy; \
+ } \
+ } \
+ else \
+ { \
+ e = 1 - dy; \
+ sign = -1; \
+ dx = -dx; \
+ if (dx >= dy) { \
+ step = - (dx / dy); \
+ dx %= dy; \
+ } \
+ } \
+ } \
+ x += origin; \
+ vertex = c; \
+}
+
+#define Step(x,dx,dy,e,sign,step) {\
+ x += step; \
+ if ((e += dx) > 0) \
+ { \
+ x += sign; \
+ e -= dy; \
+ } \
+}
+
+#define FixError(x, dx, dy, e, sign, step, h) { \
+ e += (h) * dx; \
+ x += (h) * step; \
+ if(e > 0) { \
+ x += e * sign/dy; \
+ e %= dy; \
+ if(e) { \
+ x += sign; \
+ e -= dy; \
+ } \
+ } \
+}
+
+
+/*
+ XAAIsEasyPoly -
+
+ Checks CoordModeOrigin one rect polygons to see if we need
+ to use Mi.
+ Returns: POLY_USE_MI, POLY_FULLY_CLIPPED or POLY_IS_EASY
+ as well as the pointer to the "top" point and the y
+ extents.
+*/
+
+int
+XAAIsEasyPolygon(
+ DDXPointPtr ptsIn,
+ int count,
+ BoxPtr extents,
+ int origin,
+ DDXPointPtr *topPoint, /* return */
+ int *topY, int *bottomY, /* return */
+ int shape
+){
+ int c,vertex1, vertex2;
+
+ *topY = 32767;
+ *bottomY = 0;
+
+ origin -= (origin & 0x8000) << 1;
+ vertex1 = *((int *) &extents->x1) - origin;
+ vertex2 = *((int *) &extents->x2) - origin /* - 0x00010001 */;
+ /* I think this was an error in cfb ^ */
+
+ if (shape == Convex) {
+ while (count--) {
+ c = *((int*)ptsIn);
+ if (((c - vertex1) | (vertex2 - c)) & 0x80008000)
+ return POLY_USE_MI;
+
+ c = intToY(c);
+ if (c < *topY) {
+ *topY = c;
+ *topPoint = ptsIn;
+ }
+ ptsIn++;
+ if (c > *bottomY) *bottomY = c;
+ }
+ } else {
+ int yFlip = 0;
+ int dx2, dx1, x1, x2;
+
+ x2 = x1 = -1;
+ dx1 = 1;
+
+ while (count--) {
+ c = *((int*)ptsIn);
+ if (((c - vertex1) | (vertex2 - c)) & 0x80008000)
+ return POLY_USE_MI;
+ c = intToY(c);
+ if (c < *topY) {
+ *topY = c;
+ *topPoint = ptsIn;
+ }
+ ptsIn++;
+ if (c > *bottomY) *bottomY = c;
+ if (c == x1)
+ continue;
+ if (dx1 > 0) {
+ if (x2 < 0) x2 = c;
+ else dx2 = dx1 = (c - x1) >> 31;
+ } else if ((c - x1) >> 31 != dx1) {
+ dx1 = ~dx1;
+ yFlip++;
+ }
+ x1 = c;
+ }
+ x1 = (x2 - c) >> 31;
+ if (x1 != dx1) yFlip++;
+ if (x1 != dx2) yFlip++;
+ if (yFlip != 2) {
+ if(*topY == *bottomY)
+ return POLY_FULLY_CLIPPED;
+ else
+ return POLY_USE_MI;
+ }
+ }
+ if (*topY == *bottomY)
+ return POLY_FULLY_CLIPPED;
+
+ return POLY_IS_EASY;
+}
+
+void
+XAAFillPolygonSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int origin, vertex1, vertex2;
+ int *vertex1p, *vertex2p, *endp;
+ int x1, x2, dx1, dx2, dy1, dy2, DX1, DX2, e1, e2;
+ int step1, step2, sign1, sign2;
+ int c, y, maxy, h, yoffset;
+ DDXPointPtr topPoint;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ if (mode == CoordModePrevious) {
+ register DDXPointPtr ppt = ptsIn + 1;
+
+ for (origin = 1; origin < count; origin++, ppt++) {
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ }
+ mode = CoordModeOrigin;
+ }
+
+ if (REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
+ miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+
+ origin = coordToInt(pDraw->x, pDraw->y);
+
+ switch( XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents,
+ origin, &topPoint, &y, &maxy, shape) ) {
+ case POLY_USE_MI:
+ miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
+ case POLY_FULLY_CLIPPED:
+ return;
+ }
+
+ endp = (int*)ptsIn + count;
+ vertex2p = vertex1p = (int *)topPoint;
+ origin = pDraw->x;
+ yoffset = pDraw->y;
+ vertex2 = vertex1 = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+
+ (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
+ pGC->planemask);
+
+ while(1) {
+ if (y == intToY(vertex1)) {
+ do {
+ if (vertex1p == (int *) ptsIn)
+ vertex1p = endp;
+ c = *--vertex1p;
+ Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1,DX1)
+ } while (y >= intToY(vertex1));
+ h = dy1;
+ } else {
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ h = intToY(vertex1) - y;
+ }
+ if (y == intToY(vertex2)) {
+ do {
+ c = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+ Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2,DX2)
+ } while (y >= intToY(vertex2));
+ if (dy2 < h)
+ h = dy2;
+ } else {
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ if ((c = (intToY(vertex2) - y)) < h)
+ h = c;
+ }
+
+ /* fill spans for this segment */
+ if(DX1 | DX2) {
+ if(infoRec->SubsequentSolidFillTrap && (h > 6)) {
+ if(x1 == x2) {
+ while(x1 == x2) {
+ y++;
+ if (!--h) break;
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ }
+ if(y == maxy) break;
+ if(!h) continue;
+ }
+
+ if(x1 < x2)
+ (*infoRec->SubsequentSolidFillTrap)(infoRec->pScrn,
+ y + yoffset, h,
+ x1, DX1, dy1, e1,
+ x2 - 1, DX2, dy2, e2);
+ else
+ (*infoRec->SubsequentSolidFillTrap)(infoRec->pScrn,
+ y + yoffset, h,
+ x2, DX2, dy2, e2,
+ x1 - 1, DX1, dy1, e1);
+ y += h;
+ if(--h) {
+ FixError(x1,dx1,dy1,e1,sign1,step1,h);
+ FixError(x2,dx2,dy2,e2,sign2,step2,h);
+ h = 0;
+ }
+ } else {
+ while(1) {
+ if (x2 > x1)
+ (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
+ x1, y + yoffset, x2 - x1, 1);
+ else if (x1 > x2)
+ (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
+ x2, y + yoffset, x1 - x2, 1);
+ y++;
+ if (!--h) break;
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ }
+ }
+ } else {
+ if (x2 > x1)
+ (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
+ x1, y + yoffset, x2 - x1, h);
+ else if (x1 > x2)
+ (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
+ x2, y + yoffset, x1 - x2, h);
+
+ y += h;
+ h = 0;
+ }
+ if (y == maxy) break;
+ }
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+
+
+void
+XAAFillPolygonHelper(
+ ScrnInfoPtr pScrn,
+ DDXPointPtr ptsIn,
+ int count,
+ DDXPointPtr topPoint,
+ int y,
+ int maxy,
+ int origin,
+ RectFuncPtr RectFunc,
+ TrapFuncPtr TrapFunc,
+ int xorg,
+ int yorg,
+ XAACacheInfoPtr pCache
+){
+ int *vertex1p, *vertex2p, *endp;
+ int vertex1, vertex2;
+ int x1, x2, dx1, dx2, dy1, dy2, DX1, DX2, e1, e2;
+ int step1, step2, sign1, sign2;
+ int c, h, yoffset;
+
+
+ endp = (int*)ptsIn + count;
+ vertex2p = vertex1p = (int *)topPoint;
+ yoffset = intToY(origin);
+ origin = intToX(origin);
+ vertex2 = vertex1 = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *)ptsIn;
+
+ while(1) {
+ if (y == intToY(vertex1)) {
+ do {
+ if (vertex1p == (int *) ptsIn)
+ vertex1p = endp;
+ c = *--vertex1p;
+ Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1,DX1)
+ } while (y >= intToY(vertex1));
+ h = dy1;
+ } else {
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ h = intToY(vertex1) - y;
+ }
+ if (y == intToY(vertex2)) {
+ do {
+ c = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+ Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2,DX2)
+ } while (y >= intToY(vertex2));
+ if (dy2 < h)
+ h = dy2;
+ } else {
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ if ((c = (intToY(vertex2) - y)) < h)
+ h = c;
+ }
+
+ /* fill spans for this segment */
+ if(DX1 | DX2) {
+ if(TrapFunc && (h > 6)) {
+ if(x1 == x2) {
+ while(x1 == x2) {
+ y++;
+ if (!--h) break;
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ }
+ if(y == maxy) break;
+ if(!h) continue;
+ }
+
+ if(x1 < x2)
+ (*TrapFunc)(pScrn, y + yoffset, h,
+ x1, DX1, dy1, e1,
+ x2 - 1, DX2, dy2, e2, xorg, yorg, pCache);
+ else
+ (*TrapFunc)(pScrn, y + yoffset, h,
+ x2, DX2, dy2, e2,
+ x1 - 1, DX1, dy1, e1, xorg, yorg, pCache);
+ y += h;
+ if(--h) {
+ FixError(x1,dx1,dy1,e1,sign1,step1,h);
+ FixError(x2,dx2,dy2,e2,sign2,step2,h);
+ h = 0;
+ }
+ } else {
+ while(1) {
+ if (x2 > x1)
+ (*RectFunc)(pScrn,
+ x1, y + yoffset, x2 - x1, 1, xorg, yorg, pCache);
+ else if (x1 > x2)
+ (*RectFunc)(pScrn,
+ x2, y + yoffset, x1 - x2, 1, xorg, yorg, pCache);
+ y++;
+ if (!--h) break;
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ }
+ }
+ } else {
+ if (x2 > x1)
+ (*RectFunc)(pScrn,
+ x1, y + yoffset, x2 - x1, h, xorg, yorg, pCache);
+ else if (x1 > x2)
+ (*RectFunc)(pScrn,
+ x2, y + yoffset, x1 - x2, h, xorg, yorg, pCache);
+
+ y += h;
+ h = 0;
+ }
+ if (y == maxy) break;
+ }
+}
+
+ /*****************\
+ | Solid Helpers |
+ \*****************/
+
+static void
+SolidTrapHelper(
+ ScrnInfoPtr pScrn,
+ int y, int h,
+ int x1, int dx1, int dy1, int e1,
+ int x2, int dx2, int dy2, int e2,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->SubsequentSolidFillTrap) (pScrn,
+ y, h, x1, dx1, dy1, e1, x2, dx2, dy2, e2);
+}
+
+static void
+SolidRectHelper (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h);
+}
+
+
+ /*********************\
+ | Mono 8x8 Patterns |
+ \*********************/
+
+static void
+Mono8x8PatternTrapHelper_ScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int y, int h,
+ int x1, int dx1, int dy1, int e1,
+ int x2, int dx2, int dy2, int e2,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->SubsequentMono8x8PatternFillTrap) (pScrn, xorg, yorg,
+ y, h, x1, dx1, dy1, e1, x2, dx2, dy2, e2);
+}
+
+static void
+Mono8x8PatternRectHelper_ScreenOrigin (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->SubsequentMono8x8PatternFillRect) (pScrn, xorg, yorg,
+ x, y, w, h);
+}
+
+static void
+Mono8x8PatternRectHelper (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ xorg = (x - xorg) & 0x07;
+ yorg = (y - yorg) & 0x07;
+
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ int patx = pCache->pat0;
+ int paty = pCache->pat1;
+ XAARotateMonoPattern(&patx, &paty, xorg, yorg,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ xorg = patx; yorg = paty;
+ } else {
+ int slot = (yorg << 3) + xorg;
+ xorg = pCache->x + pCache->offsets[slot].x;
+ yorg = pCache->y + pCache->offsets[slot].y;
+ }
+ }
+
+
+ (*infoRec->SubsequentMono8x8PatternFillRect) (pScrn, xorg, yorg,
+ x, y, w, h);
+}
+
+
+
+ /****************\
+ | Cache Expand |
+ \****************/
+
+
+static void
+CacheExpandRectHelper (
+ ScrnInfoPtr pScrn,
+ int X, int Y, int Width, int Height,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, phaseY, phaseX, skipleft, w, blit_w, blit_h;
+ int cacheWidth;
+
+ cacheWidth = (pCache->w * pScrn->bitsPerPixel) /
+ infoRec->CacheColorExpandDensity;
+
+ phaseY = (Y - yorg) % pCache->orig_h;
+ if(phaseY < 0) phaseY += pCache->orig_h;
+ phaseX = (X - xorg) % pCache->orig_w;
+ if(phaseX < 0) phaseX += pCache->orig_w;
+
+ while(1) {
+ w = Width; skipleft = phaseX; x = X;
+ blit_h = pCache->h - phaseY;
+ if(blit_h > Height) blit_h = Height;
+
+ while(1) {
+ blit_w = cacheWidth - skipleft;
+ if(blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenColorExpandFill)(
+ pScrn, x, Y, blit_w, blit_h,
+ pCache->x, pCache->y + phaseY, skipleft);
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ skipleft = (skipleft + blit_w) % pCache->orig_w;
+ }
+ Height -= blit_h;
+ if(!Height) break;
+ Y += blit_h;
+ phaseY = (phaseY + blit_h) % pCache->orig_h;
+ }
+}
+
+
+
+ /**************\
+ | Cache Blit |
+ \**************/
+
+
+static void
+CacheBltRectHelper (
+ ScrnInfoPtr pScrn,
+ int X, int Y, int Width, int Height,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, phaseY, phaseX, skipleft, w, blit_w, blit_h;
+
+ phaseY = (Y - yorg) % pCache->orig_h;
+ if(phaseY < 0) phaseY += pCache->orig_h;
+ phaseX = (X - xorg) % pCache->orig_w;
+ if(phaseX < 0) phaseX += pCache->orig_w;
+
+ while(1) {
+ w = Width; skipleft = phaseX; x = X;
+ blit_h = pCache->h - phaseY;
+ if(blit_h > Height) blit_h = Height;
+
+ while(1) {
+ blit_w = pCache->w - skipleft;
+ if(blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pCache->x + skipleft, pCache->y + phaseY,
+ x, Y, blit_w, blit_h);
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ skipleft = (skipleft + blit_w) % pCache->orig_w;
+ }
+ Height -= blit_h;
+ if(!Height) break;
+ Y += blit_h;
+ phaseY = (phaseY + blit_h) % pCache->orig_h;
+ }
+}
+
+
+ /**********************\
+ | Stippled Polygons |
+ \**********************/
+
+
+void
+XAAFillPolygonStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+ int origin, type, patx, paty, fg, bg;
+ int y, maxy, xorg, yorg;
+ DDXPointPtr topPoint;
+ XAACacheInfoPtr pCache = NULL;
+ RectFuncPtr RectFunc = NULL;
+ TrapFuncPtr TrapFunc = NULL;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ if (mode == CoordModePrevious) {
+ register DDXPointPtr ppt = ptsIn + 1;
+
+ for (origin = 1; origin < count; origin++, ppt++) {
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ }
+ mode = CoordModeOrigin;
+ }
+
+ if (REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
+ miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+
+
+ if(pGC->fillStyle == FillStippled) {
+ type = (*infoRec->StippledFillChooser)(pGC);
+ fg = pGC->fgPixel; bg = -1;
+ } else {
+ type = (*infoRec->OpaqueStippledFillChooser)(pGC);
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ }
+
+
+ if(!type) {
+ (*XAAFallbackOps.FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+
+ if((type == DO_COLOR_EXPAND) || (type == DO_COLOR_8x8)) {
+ miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+
+ origin = *((int *)&pDraw->x);
+
+ switch( XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents,
+ origin, &topPoint, &y, &maxy, shape) ) {
+ case POLY_USE_MI:
+ miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
+ case POLY_FULLY_CLIPPED:
+ return;
+ }
+
+ xorg = (pDraw->x + pGC->patOrg.x);
+ yorg = (pDraw->y + pGC->patOrg.y);
+
+
+ if((fg == bg) && (bg != -1) &&
+ infoRec->SubsequentSolidFillRect && infoRec->SetupForSolidFill) {
+
+ (*infoRec->SetupForSolidFill)(infoRec->pScrn, fg,
+ pGC->alu, pGC->planemask);
+
+ RectFunc = SolidRectHelper;
+ TrapFunc = infoRec->SubsequentSolidFillTrap ? SolidTrapHelper : NULL;
+ } else
+ switch(type) {
+ case DO_MONO_8x8:
+ patx = pPriv->pattern0; paty = pPriv->pattern1;
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_SCREEN_ORIGIN) {
+ xorg = (-xorg) & 0x07; yorg = (-yorg) & 0x07;
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
+ XAARotateMonoPattern(&patx, &paty, xorg, yorg,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ xorg = patx; yorg = paty;
+ }
+ } else {
+ XAACacheInfoPtr pCache = (*infoRec->CacheMono8x8Pattern)(
+ infoRec->pScrn, patx, paty);
+ patx = pCache->x; paty = pCache->y;
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int slot = (yorg << 3) + xorg;
+ patx += pCache->offsets[slot].x;
+ paty += pCache->offsets[slot].y;
+ xorg = patx; yorg = paty;
+ }
+ }
+ RectFunc = Mono8x8PatternRectHelper_ScreenOrigin;
+ if(infoRec->SubsequentMono8x8PatternFillTrap)
+ TrapFunc = Mono8x8PatternTrapHelper_ScreenOrigin;
+ } else { /* !HARDWARE_PATTERN_SCREEN_ORIGIN */
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS)){
+ pCache = (*infoRec->CacheMono8x8Pattern)(
+ infoRec->pScrn, patx, paty);
+ patx = pCache->x; paty = pCache->y;
+ }
+ RectFunc = Mono8x8PatternRectHelper;
+ }
+
+ (*infoRec->SetupForMono8x8PatternFill)(infoRec->pScrn,
+ patx, paty, fg, bg, pGC->alu, pGC->planemask);
+ break;
+ case DO_CACHE_EXPAND:
+ pCache = (*infoRec->CacheMonoStipple)(infoRec->pScrn, pGC->stipple);
+
+ (*infoRec->SetupForScreenToScreenColorExpandFill)(
+ infoRec->pScrn, fg, bg, pGC->alu, pGC->planemask);
+
+ RectFunc = CacheExpandRectHelper;
+ break;
+ case DO_CACHE_BLT:
+ pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple,
+ fg, bg);
+ (*infoRec->SetupForScreenToScreenCopy)(infoRec->pScrn, 1, 1,
+ pGC->alu, pGC->planemask, pCache->trans_color);
+
+ RectFunc = CacheBltRectHelper;
+ break;
+ default:
+ return;
+ }
+
+
+ XAAFillPolygonHelper(infoRec->pScrn, ptsIn, count, topPoint,
+ y, maxy, origin, RectFunc, TrapFunc, xorg, yorg, pCache);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+
+
+ /*******************\
+ | Tiled Polygons |
+ \*******************/
+
+
+void
+XAAFillPolygonTiled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+ int origin, type, patx, paty;
+ int y, maxy, xorg, yorg;
+ DDXPointPtr topPoint;
+ XAACacheInfoPtr pCache = NULL;
+ RectFuncPtr RectFunc = NULL;
+ TrapFuncPtr TrapFunc = NULL;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ if (mode == CoordModePrevious) {
+ register DDXPointPtr ppt = ptsIn + 1;
+
+ for (origin = 1; origin < count; origin++, ppt++) {
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ }
+ mode = CoordModeOrigin;
+ }
+
+ if (REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
+ miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+
+
+ type = (*infoRec->TiledFillChooser)(pGC);
+
+ if(!type || (type == DO_IMAGE_WRITE)) {
+ (*XAAFallbackOps.FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+
+ if(type == DO_COLOR_8x8) {
+ miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+
+ origin = *((int *)&pDraw->x);
+
+ switch( XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents,
+ origin, &topPoint, &y, &maxy, shape) ) {
+ case POLY_USE_MI:
+ miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
+ case POLY_FULLY_CLIPPED:
+ return;
+ }
+
+ xorg = (pDraw->x + pGC->patOrg.x);
+ yorg = (pDraw->y + pGC->patOrg.y);
+
+ switch(type) {
+ case DO_MONO_8x8:
+ patx = pPriv->pattern0; paty = pPriv->pattern1;
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_SCREEN_ORIGIN) {
+ xorg = (-xorg) & 0x07; yorg = (-yorg) & 0x07;
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
+ XAARotateMonoPattern(&patx, &paty, xorg, yorg,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ xorg = patx; yorg = paty;
+ }
+ } else {
+ XAACacheInfoPtr pCache = (*infoRec->CacheMono8x8Pattern)(
+ infoRec->pScrn, patx, paty);
+ patx = pCache->x; paty = pCache->y;
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int slot = (yorg << 3) + xorg;
+ patx += pCache->offsets[slot].x;
+ paty += pCache->offsets[slot].y;
+ xorg = patx; yorg = paty;
+ }
+ }
+ RectFunc = Mono8x8PatternRectHelper_ScreenOrigin;
+ if(infoRec->SubsequentMono8x8PatternFillTrap)
+ TrapFunc = Mono8x8PatternTrapHelper_ScreenOrigin;
+ } else { /* !HARDWARE_PATTERN_SCREEN_ORIGIN */
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS)){
+ pCache = (*infoRec->CacheMono8x8Pattern)(
+ infoRec->pScrn, patx, paty);
+ patx = pCache->x; paty = pCache->y;
+ }
+ else {
+ pCache = &(infoRec->ScratchCacheInfoRec);
+ pCache->pat0 = patx;
+ pCache->pat1 = paty;
+ }
+ RectFunc = Mono8x8PatternRectHelper;
+ }
+
+ (*infoRec->SetupForMono8x8PatternFill)(infoRec->pScrn,
+ patx, paty, pPriv->fg, pPriv->bg, pGC->alu, pGC->planemask);
+ break;
+ case DO_CACHE_BLT:
+ pCache = (*infoRec->CacheTile)(infoRec->pScrn, pGC->tile.pixmap);
+ (*infoRec->SetupForScreenToScreenCopy)(infoRec->pScrn, 1, 1,
+ pGC->alu, pGC->planemask, pCache->trans_color);
+
+ RectFunc = CacheBltRectHelper;
+ break;
+ case DO_PIXMAP_COPY:
+ pCache = &(infoRec->ScratchCacheInfoRec);
+ pCache->x = pPriv->offscreenArea->box.x1;
+ pCache->y = pPriv->offscreenArea->box.y1;
+ pCache->w = pCache->orig_w =
+ pPriv->offscreenArea->box.x2 - pCache->x;
+ pCache->h = pCache->orig_h =
+ pPriv->offscreenArea->box.y2 - pCache->y;
+
+ (*infoRec->SetupForScreenToScreenCopy)(infoRec->pScrn, 1, 1,
+ pGC->alu, pGC->planemask, pCache->trans_color);
+
+ RectFunc = CacheBltRectHelper;
+ break;
+ default:
+ return;
+ }
+
+ XAAFillPolygonHelper(infoRec->pScrn, ptsIn, count, topPoint,
+ y, maxy, origin, RectFunc, TrapFunc, xorg, yorg, pCache);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaFillRect.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaFillRect.c
new file mode 100644
index 000000000..aaf273448
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaFillRect.c
@@ -0,0 +1,1076 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaFillRect.c,v 1.11 1999/05/30 03:03:31 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+
+static void XAARenderSolidRects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderColor8x8Rects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderMono8x8Rects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderColorExpandRects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderCacheExpandRects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderCacheBltRects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderImageWriteRects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderPixmapCopyRects(GCPtr, int, BoxPtr, int, int);
+
+void
+XAAPolyFillRect(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill, /* number of rectangles to fill */
+ xRectangle *prectInit /* Pointer to first rectangle to fill */
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int xorg = pDraw->x;
+ int yorg = pDraw->y;
+ int type = 0;
+ ClipAndRenderRectsFunc function;
+
+ if((nrectFill <= 0) || !pGC->planemask)
+ return;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ switch(pGC->fillStyle) {
+ case FillSolid:
+ type = DO_SOLID;
+ break;
+ case FillStippled:
+ type = (*infoRec->StippledFillChooser)(pGC);
+ break;
+ case FillOpaqueStippled:
+ if((pGC->fgPixel == pGC->bgPixel) && infoRec->FillSolidRects &&
+ CHECK_PLANEMASK(pGC,infoRec->FillSolidRectsFlags) &&
+ CHECK_ROP(pGC,infoRec->FillSolidRectsFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillSolidRectsFlags) &&
+ CHECK_FG(pGC,infoRec->FillSolidRectsFlags))
+ type = DO_SOLID;
+ else
+ type = (*infoRec->OpaqueStippledFillChooser)(pGC);
+ break;
+ case FillTiled:
+ type = (*infoRec->TiledFillChooser)(pGC);
+ break;
+ }
+
+ switch(type) {
+ case DO_SOLID:
+ function = XAARenderSolidRects;
+ break;
+ case DO_COLOR_8x8:
+ function = XAARenderColor8x8Rects;
+ break;
+ case DO_MONO_8x8:
+ function = XAARenderMono8x8Rects;
+ break;
+ case DO_CACHE_BLT:
+ function = XAARenderCacheBltRects;
+ break;
+ case DO_COLOR_EXPAND:
+ function = XAARenderColorExpandRects;
+ break;
+ case DO_CACHE_EXPAND:
+ function = XAARenderCacheExpandRects;
+ break;
+ case DO_IMAGE_WRITE:
+ function = XAARenderImageWriteRects;
+ break;
+ case DO_PIXMAP_COPY:
+ function = XAARenderPixmapCopyRects;
+ break;
+ default:
+ (*XAAFallbackOps.PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
+ return;
+ }
+
+ if(xorg | yorg) {
+ int n = nrectFill;
+ xRectangle *prect = prectInit;
+
+ while(n--) {
+ prect->x += xorg;
+ prect->y += yorg;
+ prect++;
+ }
+ }
+
+
+ XAAClipAndRenderRects(pGC, function, nrectFill, prectInit, xorg, yorg);
+}
+
+
+
+ /*********************\
+ | Solid Rects |
+ \*********************/
+
+static void
+XAARenderSolidRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ (*infoRec->FillSolidRects) (infoRec->pScrn,
+ pGC->fgPixel, pGC->alu, pGC->planemask, nboxes, pClipBoxes);
+}
+
+
+ /************************\
+ | Mono 8x8 Rects |
+ \************************/
+
+static void
+XAARenderMono8x8Rects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAAPixmapPtr pPriv;
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ case FillTiled:
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+ fg = pPriv->fg; bg = pPriv->bg;
+ break;
+ }
+
+ (*infoRec->FillMono8x8PatternRects) (infoRec->pScrn,
+ fg, bg, pGC->alu, pGC->planemask,
+ nboxes, pClipBoxes, pPriv->pattern0, pPriv->pattern1,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y));
+}
+
+ /*************************\
+ | Color 8x8 Rects |
+ \*************************/
+
+static void
+XAARenderColor8x8Rects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAACacheInfoPtr pCache;
+ XAAPixmapPtr pPriv;
+ PixmapPtr pPix;
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ pPix = pGC->stipple;
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ pPix = pGC->stipple;
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ case FillTiled:
+ pPix = pGC->tile.pixmap;
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ fg = -1; bg = -1;
+ break;
+ }
+
+ pCache = (*infoRec->CacheColor8x8Pattern)(infoRec->pScrn, pPix, fg, bg);
+ (*infoRec->FillColor8x8PatternRects) (infoRec->pScrn,
+ pGC->alu, pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y), pCache);
+}
+
+
+ /****************************\
+ | Color Expand Rects |
+ \****************************/
+
+static void
+XAARenderColorExpandRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ }
+
+ (*infoRec->FillColorExpandRects) (infoRec->pScrn, fg, bg,
+ pGC->alu, pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
+ pGC->stipple);
+}
+
+
+ /*************************\
+ | Cache Blt Rects |
+ \*************************/
+
+static void
+XAARenderCacheBltRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAACacheInfoPtr pCache;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple,
+ pGC->fgPixel, -1);
+ break;
+ case FillOpaqueStippled:
+ pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple,
+ pGC->fgPixel, pGC->bgPixel);
+ break;
+ case FillTiled:
+ pCache = (*infoRec->CacheTile)(infoRec->pScrn, pGC->tile.pixmap);
+ break;
+ }
+
+ (*infoRec->FillCacheBltRects) (infoRec->pScrn, pGC->alu,
+ pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y), pCache);
+}
+
+
+ /****************************\
+ | Cache Expand Rects |
+ \****************************/
+
+static void
+XAARenderCacheExpandRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ }
+
+ (*infoRec->FillCacheExpandRects) (infoRec->pScrn, fg, bg,
+ pGC->alu, pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
+ pGC->stipple);
+}
+
+
+
+ /***************************\
+ | Image Write Rects |
+ \***************************/
+
+static void
+XAARenderImageWriteRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ (*infoRec->FillImageWriteRects) (infoRec->pScrn, pGC->alu,
+ pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
+ pGC->tile.pixmap);
+}
+
+
+
+ /***************************\
+ | Pixmap Copy Rects |
+ \***************************/
+
+static void
+XAARenderPixmapCopyRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAACacheInfoPtr pCache = &(infoRec->ScratchCacheInfoRec);
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+
+ pCache->x = pPriv->offscreenArea->box.x1;
+ pCache->y = pPriv->offscreenArea->box.y1;
+ pCache->w = pCache->orig_w =
+ pPriv->offscreenArea->box.x2 - pCache->x;
+ pCache->h = pCache->orig_h =
+ pPriv->offscreenArea->box.y2 - pCache->y;
+
+ (*infoRec->FillCacheBltRects) (infoRec->pScrn, pGC->alu,
+ pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
+ pCache);
+}
+
+
+
+ /************\
+ | Solid |
+ \************/
+
+void
+XAAFillSolidRects(
+ ScrnInfoPtr pScrn,
+ int fg, int rop,
+ unsigned int planemask,
+ int nBox, /* number of rectangles to fill */
+ BoxPtr pBox /* Pointer to first rectangle to fill */
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask);
+ while(nBox--) {
+ (*infoRec->SubsequentSolidFillRect)(pScrn, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+ pBox++;
+ }
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+
+
+ /*********************\
+ | 8x8 Mono Patterns |
+ \*********************/
+
+
+void
+XAAFillMono8x8PatternRectsScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int pattern0, int pattern1,
+ int xorigin, int yorigin
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int patx = pattern0, paty = pattern1;
+ int xorg = (-xorigin) & 0x07;
+ int yorg = (-yorigin) & 0x07;
+
+
+ if(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ XAARotateMonoPattern(&patx, &paty, xorg, yorg,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ xorg = patx; yorg = paty;
+ }
+ } else {
+ XAACacheInfoPtr pCache =
+ (*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1);
+ patx = pCache->x; paty = pCache->y;
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int slot = (yorg << 3) + xorg;
+ patx += pCache->offsets[slot].x;
+ paty += pCache->offsets[slot].y;
+ xorg = patx; yorg = paty;
+ }
+ }
+
+ (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty,
+ fg, bg, rop, planemask);
+
+ while(nBox--) {
+ (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn,
+ xorg, yorg, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+ pBox++;
+ }
+ SET_SYNC_FLAG(infoRec);
+}
+
+void
+XAAFillMono8x8PatternRects(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int pattern0, int pattern1,
+ int xorigin, int yorigin
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int patx = pattern0, paty = pattern1;
+ int xorg, yorg;
+ XAACacheInfoPtr pCache = NULL;
+
+
+ if(!(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS)){
+ pCache = (*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1);
+ patx = pCache->x; paty = pCache->y;
+ }
+
+
+ (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty,
+ fg, bg, rop, planemask);
+
+
+ while(nBox--) {
+ xorg = (pBox->x1 - xorigin) & 0x07;
+ yorg = (pBox->y1 - yorigin) & 0x07;
+
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ patx = pattern0; paty = pattern1;
+ XAARotateMonoPattern(&patx, &paty, xorg, yorg,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ xorg = patx; yorg = paty;
+ } else {
+ int slot = (yorg << 3) + xorg;
+ xorg = patx + pCache->offsets[slot].x;
+ yorg = paty + pCache->offsets[slot].y;
+ }
+ }
+
+ (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn,
+ xorg, yorg, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+ pBox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+ /**********************\
+ | 8x8 Color Patterns |
+ \**********************/
+
+
+void
+XAAFillColor8x8PatternRectsScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorigin, int yorigin,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int patx = pCache->x, paty = pCache->y;
+ int xorg = (-xorigin) & 0x07;
+ int yorg = (-yorigin) & 0x07;
+
+ if(!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int slot = (yorg << 3) + xorg;
+ paty += pCache->offsets[slot].y;
+ patx += pCache->offsets[slot].x;
+ xorg = patx; yorg = paty;
+ }
+
+ (*infoRec->SetupForColor8x8PatternFill)(pScrn, patx, paty,
+ rop, planemask, pCache->trans_color);
+
+ while(nBox--) {
+ (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn,
+ xorg, yorg, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+ pBox++;
+ }
+ SET_SYNC_FLAG(infoRec);
+}
+
+void
+XAAFillColor8x8PatternRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorigin, int yorigin,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int xorg, yorg;
+
+ (*infoRec->SetupForColor8x8PatternFill)(pScrn, pCache->x, pCache->y,
+ rop, planemask, pCache->trans_color);
+
+ while(nBox--) {
+ xorg = (pBox->x1 - xorigin) & 0x07;
+ yorg = (pBox->y1 - yorigin) & 0x07;
+
+ if(!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int slot = (yorg << 3) + xorg;
+ yorg = pCache->y + pCache->offsets[slot].y;
+ xorg = pCache->x + pCache->offsets[slot].x;
+ }
+
+ (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn,
+ xorg, yorg, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+ pBox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+ /***************\
+ | Cache Blits |
+ \***************/
+
+void
+XAAFillCacheBltRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, y, phaseY, phaseX, skipleft, height, width, w, blit_w, blit_h;
+
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, rop, planemask,
+ pCache->trans_color);
+
+ while(nBox--) {
+ y = pBox->y1;
+ phaseY = (y - yorg) % pCache->orig_h;
+ if(phaseY < 0) phaseY += pCache->orig_h;
+ phaseX = (pBox->x1 - xorg) % pCache->orig_w;
+ if(phaseX < 0) phaseX += pCache->orig_w;
+ height = pBox->y2 - y;
+ width = pBox->x2 - pBox->x1;
+
+ if (rop == GXcopy) {
+ while(1) {
+ w = width; skipleft = phaseX; x = pBox->x1;
+ blit_h = pCache->h - phaseY;
+ if(blit_h > height) blit_h = height;
+
+ while(1) {
+ blit_w = pCache->w - skipleft;
+ if(blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pCache->x + skipleft, pCache->y + phaseY,
+ x, y, blit_w, blit_h);
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ skipleft = (skipleft + blit_w) % pCache->orig_w;
+ if(blit_w >= pCache->orig_w) break;
+ }
+
+ /* Expand horizontally */
+ if (w) {
+ skipleft -= phaseX;
+ if (skipleft < 0) skipleft += pCache->orig_w;
+ blit_w = x - pBox->x1 - skipleft;
+ while(w) {
+ if (blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pBox->x1 + skipleft, y, x, y, blit_w, blit_h);
+ w -= blit_w;
+ x += blit_w;
+ blit_w <<= 1;
+ }
+ }
+
+ height -= blit_h;
+ if(!height) break;
+ y += blit_h;
+ phaseY = (phaseY + blit_h) % pCache->orig_h;
+ if(blit_h >= pCache->orig_h) break;
+ }
+
+ /* Expand vertically */
+ if (height) {
+ blit_w = pBox->x2 - pBox->x1;
+ phaseY -= (pBox->y1 - yorg) % pCache->orig_h;
+ if (phaseY < 0) phaseY += pCache->orig_h;
+ blit_h = y - pBox->y1 - phaseY;
+ while(height) {
+ if (blit_h > height) blit_h = height;
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pBox->x1,
+ pBox->y1 + phaseY, pBox->x1, y, blit_w, blit_h);
+ height -= blit_h;
+ y += blit_h;
+ blit_h <<= 1;
+ }
+ }
+ } else {
+ while(1) {
+ w = width; skipleft = phaseX; x = pBox->x1;
+ blit_h = pCache->h - phaseY;
+ if(blit_h > height) blit_h = height;
+
+ while(1) {
+ blit_w = pCache->w - skipleft;
+ if(blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pCache->x + skipleft, pCache->y + phaseY,
+ x, y, blit_w, blit_h);
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ skipleft = (skipleft + blit_w) % pCache->orig_w;
+ }
+ height -= blit_h;
+ if(!height) break;
+ y += blit_h;
+ phaseY = (phaseY + blit_h) % pCache->orig_h;
+ }
+ }
+ pBox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+
+
+ /*******************\
+ | Cache Expansion |
+ \*******************/
+
+
+
+void
+XAAFillCacheExpandRects(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, y, phaseY, phaseX, skipleft, height, width, w, blit_w, blit_h;
+ int cacheWidth;
+ XAACacheInfoPtr pCache;
+
+ pCache = (*infoRec->CacheMonoStipple)(pScrn, pPix);
+
+ cacheWidth = (pCache->w * pScrn->bitsPerPixel) /
+ infoRec->CacheColorExpandDensity;
+
+ (*infoRec->SetupForScreenToScreenColorExpandFill)(pScrn, fg, bg, rop,
+ planemask);
+
+ while(nBox--) {
+ y = pBox->y1;
+ phaseY = (y - yorg) % pCache->orig_h;
+ if(phaseY < 0) phaseY += pCache->orig_h;
+ phaseX = (pBox->x1 - xorg) % pCache->orig_w;
+ if(phaseX < 0) phaseX += pCache->orig_w;
+ height = pBox->y2 - y;
+ width = pBox->x2 - pBox->x1;
+
+ while(1) {
+ w = width; skipleft = phaseX; x = pBox->x1;
+ blit_h = pCache->h - phaseY;
+ if(blit_h > height) blit_h = height;
+
+ while(1) {
+ blit_w = cacheWidth - skipleft;
+ if(blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenColorExpandFill)(
+ pScrn, x, y, blit_w, blit_h,
+ pCache->x, pCache->y + phaseY, skipleft);
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ skipleft = (skipleft + blit_w) % pCache->orig_w;
+ }
+ height -= blit_h;
+ if(!height) break;
+ y += blit_h;
+ phaseY = (phaseY + blit_h) % pCache->orig_h;
+ }
+ pBox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+ /******************\
+ | Image Writes |
+ \******************/
+
+
+
+/* This requires all LEFT_EDGE clipping. You get too many problems
+ with reading past the edge of the pattern otherwise */
+
+static void
+WriteColumn(
+ ScrnInfoPtr pScrn,
+ unsigned char *pSrc,
+ int x, int y, int w, int h,
+ int xoff, int yoff,
+ int pHeight,
+ int srcwidth,
+ int Bpp
+) {
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ unsigned char *src;
+ Bool PlusOne = FALSE;
+ int skipleft, dwords;
+
+ pSrc += (Bpp * xoff);
+
+ if((skipleft = (long)pSrc & 0x03L)) {
+ if(Bpp == 3)
+ skipleft = 4 - skipleft;
+ else
+ skipleft /= Bpp;
+
+ x -= skipleft;
+ w += skipleft;
+
+ if(Bpp == 3)
+ pSrc -= 3 * skipleft;
+ else /* is this Alpha friendly ? */
+ pSrc = (unsigned char*)((long)pSrc & ~0x03L);
+ }
+
+ src = pSrc + (yoff * srcwidth);
+
+ dwords = ((w * Bpp) + 3) >> 2;
+
+ if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
+ ((dwords * h) & 0x01)) {
+ PlusOne = TRUE;
+ }
+
+ (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, skipleft);
+
+ if(dwords > infoRec->ImageWriteRange) {
+ while(h--) {
+ XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src += srcwidth;
+ yoff++;
+ if(yoff >= pHeight) {
+ yoff = 0;
+ src = pSrc;
+ }
+ }
+ } else {
+ if(srcwidth == (dwords << 2)) {
+ int maxLines = infoRec->ImageWriteRange/dwords;
+ int step;
+
+ while(h) {
+ step = pHeight - yoff;
+ if(step > maxLines) step = maxLines;
+ if(step > h) step = h;
+
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords * step);
+
+ src += (srcwidth * step);
+ yoff += step;
+ if(yoff >= pHeight) {
+ yoff = 0;
+ src = pSrc;
+ }
+ h -= step;
+ }
+ } else {
+ while(h--) {
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src += srcwidth;
+ yoff++;
+ if(yoff >= pHeight) {
+ yoff = 0;
+ src = pSrc;
+ }
+ }
+ }
+ }
+
+ if(PlusOne) {
+ CARD32* base = (CARD32*)infoRec->ImageWriteBase;
+ *base = 0x00000000;
+ }
+}
+
+void
+XAAFillImageWriteRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, phaseY, phaseX, height, width, blit_w;
+ int pHeight = pPix->drawable.height;
+ int pWidth = pPix->drawable.width;
+ int Bpp = pPix->drawable.bitsPerPixel >> 3;
+ int srcwidth = pPix->devKind;
+
+ (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, -1,
+ pPix->drawable.bitsPerPixel, pPix->drawable.depth);
+
+ while(nBox--) {
+ x = pBox->x1;
+ phaseY = (pBox->y1 - yorg) % pHeight;
+ if(phaseY < 0) phaseY += pHeight;
+ phaseX = (x - xorg) % pWidth;
+ if(phaseX < 0) phaseX += pWidth;
+ height = pBox->y2 - pBox->y1;
+ width = pBox->x2 - x;
+
+ while(1) {
+ blit_w = pWidth - phaseX;
+ if(blit_w > width) blit_w = width;
+
+ WriteColumn(pScrn, pPix->devPrivate.ptr, x, pBox->y1,
+ blit_w, height, phaseX, phaseY, pHeight, srcwidth, Bpp);
+
+ width -= blit_w;
+ if(!width) break;
+ x += blit_w;
+ phaseX = (phaseX + blit_w) % pWidth;
+ }
+ pBox++;
+ }
+
+ if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+
+ /*************\
+ | Utilities |
+ \*************/
+
+
+void
+XAAClipAndRenderRects(
+ GCPtr pGC,
+ ClipAndRenderRectsFunc BoxFunc,
+ int nrectFill,
+ xRectangle *prect,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int Right, Bottom, MaxBoxes;
+ BoxPtr pextent, pboxClipped, pboxClippedBase;
+
+ MaxBoxes = infoRec->PreAllocSize/sizeof(BoxRec);
+ pboxClippedBase = (BoxPtr)infoRec->PreAllocMem;
+ pboxClipped = pboxClippedBase;
+
+ if (REGION_NUM_RECTS(pGC->pCompositeClip) == 1) {
+ pextent = REGION_RECTS(pGC->pCompositeClip);
+ while (nrectFill--) {
+ pboxClipped->x1 = max(pextent->x1, prect->x);
+ pboxClipped->y1 = max(pextent->y1, prect->y);
+
+ Right = (int)prect->x + (int)prect->width;
+ pboxClipped->x2 = min(pextent->x2, Right);
+
+ Bottom = (int)prect->y + (int)prect->height;
+ pboxClipped->y2 = min(pextent->y2, Bottom);
+
+ prect++;
+ if ((pboxClipped->x1 < pboxClipped->x2) &&
+ (pboxClipped->y1 < pboxClipped->y2)) {
+ pboxClipped++;
+ if(pboxClipped >= (pboxClippedBase + MaxBoxes)) {
+ (*BoxFunc)(pGC, MaxBoxes, pboxClippedBase, xorg, yorg);
+ pboxClipped = pboxClippedBase;
+ }
+ }
+ }
+ } else {
+ pextent = REGION_EXTENTS(pGC->pScreen, pGC->pCompositeClip);
+ while (nrectFill--) {
+ int n;
+ BoxRec box, *pbox;
+
+ box.x1 = max(pextent->x1, prect->x);
+ box.y1 = max(pextent->y1, prect->y);
+
+ Right = (int)prect->x + (int)prect->width;
+ box.x2 = min(pextent->x2, Right);
+
+ Bottom = (int)prect->y + (int)prect->height;
+ box.y2 = min(pextent->y2, Bottom);
+
+ prect++;
+
+ if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
+ continue;
+
+ n = REGION_NUM_RECTS (pGC->pCompositeClip);
+ pbox = REGION_RECTS(pGC->pCompositeClip);
+
+ /* clip the rectangle to each box in the clip region
+ this is logically equivalent to calling Intersect()
+ */
+ while(n--) {
+ pboxClipped->x1 = max(box.x1, pbox->x1);
+ pboxClipped->y1 = max(box.y1, pbox->y1);
+ pboxClipped->x2 = min(box.x2, pbox->x2);
+ pboxClipped->y2 = min(box.y2, pbox->y2);
+ pbox++;
+
+ /* see if clipping left anything */
+ if(pboxClipped->x1 < pboxClipped->x2 &&
+ pboxClipped->y1 < pboxClipped->y2) {
+ pboxClipped++;
+ if(pboxClipped >= (pboxClippedBase + MaxBoxes)) {
+ (*BoxFunc)(pGC, MaxBoxes, pboxClippedBase, xorg, yorg);
+ pboxClipped = pboxClippedBase;
+ }
+ }
+ }
+ }
+ }
+
+ if(pboxClipped != pboxClippedBase)
+ (*BoxFunc)(pGC, pboxClipped - pboxClippedBase, pboxClippedBase,
+ xorg, yorg);
+}
+
+
+int
+XAAGetRectClipBoxes(
+ RegionPtr prgnClip,
+ BoxPtr pboxClippedBase,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ int Right, Bottom;
+ BoxPtr pextent, pboxClipped = pboxClippedBase;
+ xRectangle *prect = prectInit;
+
+
+ if (REGION_NUM_RECTS(prgnClip) == 1) {
+ pextent = REGION_RECTS(prgnClip);
+ while (nrectFill--) {
+ pboxClipped->x1 = max(pextent->x1, prect->x);
+ pboxClipped->y1 = max(pextent->y1, prect->y);
+
+ Right = (int)prect->x + (int)prect->width;
+ pboxClipped->x2 = min(pextent->x2, Right);
+
+ Bottom = (int)prect->y + (int)prect->height;
+ pboxClipped->y2 = min(pextent->y2, Bottom);
+
+ prect++;
+ if ((pboxClipped->x1 < pboxClipped->x2) &&
+ (pboxClipped->y1 < pboxClipped->y2)) {
+ pboxClipped++;
+ }
+ }
+ } else {
+ pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
+ while (nrectFill--) {
+ int n;
+ BoxRec box, *pbox;
+
+ box.x1 = max(pextent->x1, prect->x);
+ box.y1 = max(pextent->y1, prect->y);
+
+ Right = (int)prect->x + (int)prect->width;
+ box.x2 = min(pextent->x2, Right);
+
+ Bottom = (int)prect->y + (int)prect->height;
+ box.y2 = min(pextent->y2, Bottom);
+
+ prect++;
+
+ if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
+ continue;
+
+ n = REGION_NUM_RECTS (prgnClip);
+ pbox = REGION_RECTS(prgnClip);
+
+ /* clip the rectangle to each box in the clip region
+ this is logically equivalent to calling Intersect()
+ */
+ while(n--) {
+ pboxClipped->x1 = max(box.x1, pbox->x1);
+ pboxClipped->y1 = max(box.y1, pbox->y1);
+ pboxClipped->x2 = min(box.x2, pbox->x2);
+ pboxClipped->y2 = min(box.y2, pbox->y2);
+ pbox++;
+
+ /* see if clipping left anything */
+ if(pboxClipped->x1 < pboxClipped->x2 &&
+ pboxClipped->y1 < pboxClipped->y2) {
+ pboxClipped++;
+ }
+ }
+ }
+ }
+
+ return(pboxClipped - pboxClippedBase);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaGC.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaGC.c
new file mode 100644
index 000000000..99e71c061
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaGC.c
@@ -0,0 +1,630 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaGC.c,v 1.15 1999/06/20 08:41:38 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "migc.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "xaawrap.h"
+
+static void XAAValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDraw);
+static void XAAChangeGC(GCPtr pGC, unsigned long mask);
+static void XAACopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
+static void XAADestroyGC(GCPtr pGC);
+static void XAAChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
+static void XAADestroyClip(GCPtr pGC);
+static void XAACopyClip(GCPtr pgcDst, GCPtr pgcSrc);
+
+GCFuncs XAAGCFuncs = {
+ XAAValidateGC, XAAChangeGC, XAACopyGC, XAADestroyGC,
+ XAAChangeClip, XAADestroyClip, XAACopyClip
+};
+
+extern GCOps XAAPixmapOps;
+
+Bool
+XAACreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ XAAGCPtr pGCPriv = (XAAGCPtr)(pGC->devPrivates[XAAGCIndex].ptr);
+ Bool ret;
+
+ XAA_SCREEN_PROLOGUE(pScreen,CreateGC);
+
+ if((ret = (*pScreen->CreateGC)(pGC))) {
+ pGCPriv->wrapOps = NULL;
+ pGCPriv->wrapFuncs = pGC->funcs;
+ pGCPriv->XAAOps = &XAAFallbackOps;
+ pGCPriv->flags = 0;
+ pGCPriv->DashLength = 0;
+ pGCPriv->DashPattern = NULL;
+ pGCPriv->changes = 0;
+ /* initialize any other private fields here */
+ pGC->funcs = &XAAGCFuncs;
+ }
+
+ XAA_SCREEN_EPILOGUE(pScreen,CreateGC,XAACreateGC);
+
+ return ret;
+}
+
+
+static void
+XAAValidateGC(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAA_GC_FUNC_PROLOGUE(pGC);
+
+ (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
+
+ if(pGC->bgPixel == -1) /* -1 is reserved for transparency */
+ pGC->bgPixel = 0x7fffffff;
+ if(pGC->fgPixel == -1) /* -1 is reserved for transparency */
+ pGC->fgPixel = 0x7fffffff;
+
+ if((pDraw->type == DRAWABLE_PIXMAP) && !IS_OFFSCREEN_PIXMAP(pDraw)){
+ pGCPriv->flags = OPS_ARE_PIXMAP;
+ pGCPriv->changes |= changes;
+
+ /* make sure we're not using videomemory pixmaps to render
+ onto system memory drawables */
+
+ if((pGC->fillStyle == FillTiled) &&
+ IS_OFFSCREEN_PIXMAP(pGC->tile.pixmap) &&
+ !OFFSCREEN_PIXMAP_LOCKED(pGC->tile.pixmap)) {
+
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+ FBAreaPtr area = pPriv->offscreenArea;
+
+ XAARemoveAreaCallback(area); /* clobbers pPriv->offscreenArea */
+ xf86FreeOffscreenArea(area);
+ }
+ }
+ else if(!infoRec->pScrn->vtSema && (pDraw->type == DRAWABLE_WINDOW)) {
+ pGCPriv->flags = 0;
+ pGCPriv->changes |= changes;
+ }
+ else {
+ if(!(pGCPriv->flags & OPS_ARE_ACCEL)) {
+ changes |= pGCPriv->changes;
+ pGCPriv->changes = 0;
+ }
+ pGCPriv->flags = OPS_ARE_ACCEL;
+
+#if 1
+ /* Ugh. If we can't use the blitter on offscreen pixmaps used
+ as tiles, then we need to move them out as cfb can't handle
+ tiles with non-zero origins */
+
+ if((pGC->fillStyle == FillTiled) &&
+ IS_OFFSCREEN_PIXMAP(pGC->tile.pixmap) &&
+ (DO_PIXMAP_COPY != (*infoRec->TiledFillChooser)(pGC))) {
+
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+ FBAreaPtr area = pPriv->offscreenArea;
+
+ XAARemoveAreaCallback(area); /* clobbers pPriv->offscreenArea */
+ xf86FreeOffscreenArea(area);
+ }
+#endif
+ }
+
+ XAA_GC_FUNC_EPILOGUE(pGC);
+
+ if(!(pGCPriv->flags & OPS_ARE_ACCEL)) return;
+
+ if((changes & GCTile) && !pGC->tileIsPixel && pGC->tile.pixmap){
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+
+ if(pixPriv->flags & DIRTY) {
+ pixPriv->flags &= ~(DIRTY | REDUCIBILITY_MASK);
+ pGC->tile.pixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ }
+ if((changes & GCStipple) && pGC->stipple){
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+
+ if(pixPriv->flags & DIRTY) {
+ pixPriv->flags &= ~(DIRTY | REDUCIBILITY_MASK);
+ pGC->stipple->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ }
+
+ /* If our Ops are still the default ones we need to allocate new ones */
+ if(pGC->ops == &XAAFallbackOps) {
+ if(!(pGCPriv->XAAOps = xalloc(sizeof(GCOps)))) {
+ pGCPriv->XAAOps = &XAAFallbackOps;
+ return;
+ }
+ /* make a modifiable copy of the default ops */
+ memcpy(pGCPriv->XAAOps, &XAAFallbackOps, sizeof(GCOps));
+ pGC->ops = pGCPriv->XAAOps;
+ changes = ~0;
+ }
+
+ if(!changes) return;
+
+ if((changes & GCDashList) && infoRec->ComputeDash)
+ infoRec->ComputeDash(pGC);
+
+ if(changes & infoRec->FillSpansMask)
+ (*infoRec->ValidateFillSpans)(pGC, changes, pDraw);
+
+ if(changes & infoRec->SetSpansMask)
+ (*infoRec->ValidateSetSpans)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PutImageMask)
+ (*infoRec->ValidatePutImage)(pGC, changes, pDraw);
+
+ if(changes & infoRec->CopyAreaMask)
+ (*infoRec->ValidateCopyArea)(pGC, changes, pDraw);
+
+ if(changes & infoRec->CopyPlaneMask)
+ (*infoRec->ValidateCopyPlane)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyPointMask)
+ (*infoRec->ValidatePolyPoint)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolylinesMask)
+ (*infoRec->ValidatePolylines)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolySegmentMask)
+ (*infoRec->ValidatePolySegment)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyRectangleMask)
+ (*infoRec->ValidatePolyRectangle)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyArcMask)
+ (*infoRec->ValidatePolyArc)(pGC, changes, pDraw);
+
+ if(changes & infoRec->FillPolygonMask)
+ (*infoRec->ValidateFillPolygon)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyFillRectMask)
+ (*infoRec->ValidatePolyFillRect)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyFillArcMask)
+ (*infoRec->ValidatePolyFillArc)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyGlyphBltMask)
+ (*infoRec->ValidatePolyGlyphBlt)(pGC, changes, pDraw);
+
+ if(changes & infoRec->ImageGlyphBltMask)
+ (*infoRec->ValidateImageGlyphBlt)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyText8Mask)
+ (*infoRec->ValidatePolyText8)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyText16Mask)
+ (*infoRec->ValidatePolyText16)(pGC, changes, pDraw);
+
+ if(changes & infoRec->ImageText8Mask)
+ (*infoRec->ValidateImageText8)(pGC, changes, pDraw);
+
+ if(changes & infoRec->ImageText16Mask)
+ (*infoRec->ValidateImageText16)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PushPixelsMask)
+ (*infoRec->ValidatePushPixels)(pGC, changes, pDraw);
+}
+
+
+static void
+XAADestroyGC(GCPtr pGC)
+{
+ XAA_GC_FUNC_PROLOGUE (pGC);
+
+ if(pGCPriv->XAAOps != &XAAFallbackOps)
+ xfree(pGCPriv->XAAOps);
+
+ if(pGCPriv->DashPattern)
+ xfree(pGCPriv->DashPattern);
+
+ (*pGC->funcs->DestroyGC)(pGC);
+ XAA_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+XAAChangeGC (
+ GCPtr pGC,
+ unsigned long mask
+)
+{
+ XAA_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ XAA_GC_FUNC_EPILOGUE (pGC);
+
+ /* we have to assume that shared memory pixmaps are dirty
+ because we can't wrap all operations on them */
+
+ if((mask & GCTile) && !pGC->tileIsPixel &&
+ PIXMAP_IS_SHARED(pGC->tile.pixmap))
+ {
+ XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+ pPixPriv->flags |= DIRTY;
+ }
+
+ if((mask & GCStipple) && PIXMAP_IS_SHARED(pGC->stipple)){
+ XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+ pPixPriv->flags |= DIRTY;
+ }
+}
+
+static void
+XAACopyGC (
+ GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst)
+{
+ XAA_GC_FUNC_PROLOGUE (pGCDst);
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ XAA_GC_FUNC_EPILOGUE (pGCDst);
+}
+static void
+XAAChangeClip (
+ GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects )
+{
+ XAA_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ XAA_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+XAACopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ XAA_GC_FUNC_PROLOGUE (pgcDst);
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ XAA_GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+XAADestroyClip(GCPtr pGC)
+{
+ XAA_GC_FUNC_PROLOGUE (pGC);
+ (* pGC->funcs->DestroyClip)(pGC);
+ XAA_GC_FUNC_EPILOGUE (pGC);
+}
+
+/**** Pixmap Wrappers ****/
+
+
+
+static void
+XAAFillSpansPixmap(
+ DrawablePtr pDraw,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAASetSpansPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ char *pcharsrc,
+ register DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPutImagePixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static RegionPtr
+XAACopyAreaPixmap(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ RegionPtr ret;
+
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDst);
+
+ if(infoRec->pScrn->vtSema &&
+ ((pSrc->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pSrc))){
+ if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ }
+
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static RegionPtr
+XAACopyPlanePixmap(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ RegionPtr ret;
+
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDst);
+
+ if(infoRec->pScrn->vtSema &&
+ ((pSrc->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pSrc))){
+ if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ }
+
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static void
+XAAPolyPointPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAPolylinesPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolySegmentPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolyRectanglePixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolyArcPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAFillPolygonPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAPolyFillRectPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAPolyFillArcPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static int
+XAAPolyText8Pixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ int ret;
+
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static int
+XAAPolyText16Pixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ int ret;
+
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static void
+XAAImageText8Pixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+static void
+XAAImageText16Pixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAImageGlyphBltPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph,
+ ppci, pglyphBase);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolyGlyphBltPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph,
+ ppci, pglyphBase);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPushPixelsPixmap(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy, int xOrg, int yOrg
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+GCOps XAAPixmapOps = {
+ XAAFillSpansPixmap, XAASetSpansPixmap,
+ XAAPutImagePixmap, XAACopyAreaPixmap,
+ XAACopyPlanePixmap, XAAPolyPointPixmap,
+ XAAPolylinesPixmap, XAAPolySegmentPixmap,
+ XAAPolyRectanglePixmap, XAAPolyArcPixmap,
+ XAAFillPolygonPixmap, XAAPolyFillRectPixmap,
+ XAAPolyFillArcPixmap, XAAPolyText8Pixmap,
+ XAAPolyText16Pixmap, XAAImageText8Pixmap,
+ XAAImageText16Pixmap, XAAImageGlyphBltPixmap,
+ XAAPolyGlyphBltPixmap, XAAPushPixelsPixmap,
+#ifdef NEED_LINEHELPER
+ NULL,
+#endif
+ {NULL} /* devPrivate */
+};
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaGCmisc.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaGCmisc.c
new file mode 100644
index 000000000..352abd553
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaGCmisc.c
@@ -0,0 +1,420 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaGCmisc.c,v 1.12 1998/12/06 06:08:41 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "migc.h"
+#include "mi.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+
+void
+XAAValidateCopyArea(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(infoRec->CopyArea &&
+ CHECK_PLANEMASK(pGC,infoRec->CopyAreaFlags) &&
+ CHECK_ROP(pGC,infoRec->CopyAreaFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->CopyAreaFlags)
+ )
+ pGC->ops->CopyArea = infoRec->CopyArea;
+ else
+ pGC->ops->CopyArea = XAAFallbackOps.CopyArea;
+}
+
+void
+XAAValidatePutImage(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(infoRec->PutImage &&
+ CHECK_PLANEMASK(pGC,infoRec->PutImageFlags) &&
+ CHECK_ROP(pGC,infoRec->PutImageFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PutImageFlags) &&
+ CHECK_COLORS(pGC,infoRec->PutImageFlags)
+ )
+ pGC->ops->PutImage = infoRec->PutImage;
+ else
+ pGC->ops->PutImage = XAAFallbackOps.PutImage;
+}
+
+void
+XAAValidateCopyPlane(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(infoRec->CopyPlane &&
+ CHECK_PLANEMASK(pGC,infoRec->CopyPlaneFlags) &&
+ CHECK_ROP(pGC,infoRec->CopyPlaneFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->CopyPlaneFlags) &&
+ CHECK_COLORS(pGC,infoRec->CopyPlaneFlags)
+ )
+ pGC->ops->CopyPlane = infoRec->CopyPlane;
+ else
+ pGC->ops->CopyPlane = XAAFallbackOps.CopyPlane;
+}
+
+void
+XAAValidatePushPixels(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(infoRec->PushPixelsSolid &&
+ (pGC->fillStyle == FillSolid) &&
+ CHECK_PLANEMASK(pGC,infoRec->PushPixelsFlags) &&
+ CHECK_ROP(pGC,infoRec->PushPixelsFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PushPixelsFlags) &&
+ CHECK_FG(pGC,infoRec->PushPixelsFlags) &&
+ (!(infoRec->PushPixelsFlags & TRANSPARENCY_GXCOPY_ONLY) ||
+ (pGC->alu == GXcopy))
+ )
+ pGC->ops->PushPixels = infoRec->PushPixelsSolid;
+ else
+ pGC->ops->PushPixels = XAAFallbackOps.PushPixels;
+
+}
+
+
+/* We make the assumption that the FillSpans, PolyFillRect, FillPolygon
+ and PolyFillArc functions are linked in a way that they all have
+ the same rop/color/planemask restrictions. If the driver provides
+ a GC level replacement for these, it will need to supply a new
+ Validate functions if it breaks this assumption */
+
+
+void
+XAAValidateFillSpans(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(pGC->fillStyle != FillTiled) changes &= ~GCTile;
+ if((pGC->fillStyle == FillTiled) || (pGC->fillStyle == FillSolid))
+ changes &= ~GCStipple;
+ if(!changes) return;
+
+
+ pGC->ops->FillSpans = XAAFallbackOps.FillSpans;
+ pGC->ops->PolyFillRect = XAAFallbackOps.PolyFillRect;
+ pGC->ops->FillPolygon = XAAFallbackOps.FillPolygon;
+ pGC->ops->PolyFillArc = XAAFallbackOps.PolyFillArc;
+
+ switch(pGC->fillStyle){
+ case FillSolid:
+ if(infoRec->FillSpansSolid &&
+ CHECK_PLANEMASK(pGC,infoRec->FillSpansSolidFlags) &&
+ CHECK_ROP(pGC,infoRec->FillSpansSolidFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillSpansSolidFlags) &&
+ CHECK_FG(pGC,infoRec->FillSpansSolidFlags)
+ ) {
+ pGC->ops->FillSpans = infoRec->FillSpansSolid;
+ pGC->ops->PolyFillRect = infoRec->PolyFillRectSolid;
+ pGC->ops->FillPolygon = infoRec->FillPolygonSolid;
+ pGC->ops->PolyFillArc = infoRec->PolyFillArcSolid;
+ }
+ break;
+ /* The [Stippled/OpaqueStippled/Tiled]FillChooser
+ functions do the validating */
+ case FillStippled:
+ if(infoRec->FillSpansStippled) {
+ pGC->ops->FillSpans = infoRec->FillSpansStippled;
+ pGC->ops->PolyFillRect = infoRec->PolyFillRectStippled;
+ pGC->ops->FillPolygon = infoRec->FillPolygonStippled;
+ pGC->ops->PolyFillArc = miPolyFillArc;
+ }
+ break;
+ case FillOpaqueStippled:
+ if(infoRec->FillSpansOpaqueStippled) {
+ pGC->ops->FillSpans = infoRec->FillSpansOpaqueStippled;
+ pGC->ops->PolyFillRect = infoRec->PolyFillRectOpaqueStippled;
+ pGC->ops->FillPolygon = infoRec->FillPolygonOpaqueStippled;
+ pGC->ops->PolyFillArc = miPolyFillArc;
+ }
+ break;
+ case FillTiled:
+ if(infoRec->FillSpansTiled) {
+ pGC->ops->FillSpans = infoRec->FillSpansTiled;
+ pGC->ops->PolyFillRect = infoRec->PolyFillRectTiled;
+ pGC->ops->FillPolygon = infoRec->FillPolygonTiled;
+ pGC->ops->PolyFillArc = miPolyFillArc;
+ }
+ break;
+ default: return;
+ }
+}
+
+
+/* We make the assumption that these Text8/16 and GlyphBlt functions
+ are linked in a way that they all have the same rop/color/planemask
+ restrictions. If the driver provides a GC level replacement for
+ these, it will need to supply a new Validate functions if it breaks
+ this assumption */
+
+void
+XAAValidatePolyGlyphBlt(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ Bool BigFont = FALSE;
+
+ pGC->ops->PolyText8 = XAAFallbackOps.PolyText8;
+ pGC->ops->PolyText16 = XAAFallbackOps.PolyText16;
+ pGC->ops->PolyGlyphBlt = XAAFallbackOps.PolyGlyphBlt;
+
+ if(!pGC->font) return;
+ if(pGC->fillStyle != FillSolid) return;
+
+ if((FONTMAXBOUNDS(pGC->font, rightSideBearing) -
+ FONTMINBOUNDS(pGC->font, leftSideBearing) > 32))
+ BigFont = TRUE;
+
+ /* no funny business */
+ if((FONTMINBOUNDS(pGC->font, characterWidth) <= 0) ||
+ ((FONTASCENT(pGC->font) + FONTDESCENT(pGC->font)) <= 0))
+ return;
+
+ /* Check for TE Fonts */
+ if(!TERMINALFONT(pGC->font) || BigFont) {
+ if(infoRec->PolyGlyphBltNonTE &&
+ CHECK_PLANEMASK(pGC,infoRec->PolyGlyphBltNonTEFlags) &&
+ CHECK_ROP(pGC,infoRec->PolyGlyphBltNonTEFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolyGlyphBltNonTEFlags) &&
+ CHECK_FG(pGC,infoRec->PolyGlyphBltNonTEFlags) &&
+ (!(infoRec->PolyGlyphBltNonTEFlags & TRANSPARENCY_GXCOPY_ONLY) ||
+ (pGC->alu == GXcopy))
+ ) {
+ pGC->ops->PolyText8 = infoRec->PolyText8NonTE;
+ pGC->ops->PolyText16 = infoRec->PolyText16NonTE;
+ pGC->ops->PolyGlyphBlt = infoRec->PolyGlyphBltNonTE;
+ }
+ } else {
+ if(infoRec->PolyGlyphBltTE &&
+ CHECK_PLANEMASK(pGC,infoRec->PolyGlyphBltTEFlags) &&
+ CHECK_ROP(pGC,infoRec->PolyGlyphBltTEFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolyGlyphBltNonTEFlags) &&
+ CHECK_FG(pGC,infoRec->PolyGlyphBltTEFlags) &&
+ (!(infoRec->PolyGlyphBltTEFlags & TRANSPARENCY_GXCOPY_ONLY) ||
+ (pGC->alu == GXcopy))
+ ) {
+ pGC->ops->PolyText8 = infoRec->PolyText8TE;
+ pGC->ops->PolyText16 = infoRec->PolyText16TE;
+ pGC->ops->PolyGlyphBlt = infoRec->PolyGlyphBltTE;
+ }
+ }
+}
+
+void
+XAAValidateImageGlyphBlt(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ Bool BigFont = FALSE;
+
+ pGC->ops->ImageText8 = XAAFallbackOps.ImageText8;
+ pGC->ops->ImageText16 = XAAFallbackOps.ImageText16;
+ pGC->ops->ImageGlyphBlt = XAAFallbackOps.ImageGlyphBlt;
+
+ if(!pGC->font) return;
+
+ if((FONTMAXBOUNDS(pGC->font, rightSideBearing) -
+ FONTMINBOUNDS(pGC->font, leftSideBearing) > 32))
+ BigFont = TRUE;
+
+ /* no funny business */
+ if((FONTMINBOUNDS(pGC->font, characterWidth) <= 0) ||
+ ((FONTASCENT(pGC->font) + FONTDESCENT(pGC->font)) <= 0))
+ return;
+
+
+ /* Check for TE Fonts */
+ if(!TERMINALFONT(pGC->font) || BigFont) {
+ if(infoRec->ImageGlyphBltNonTE &&
+ CHECK_PLANEMASK(pGC,infoRec->ImageGlyphBltNonTEFlags) &&
+ CHECK_FG(pGC,infoRec->ImageGlyphBltNonTEFlags) &&
+ infoRec->SetupForSolidFill && infoRec->SubsequentSolidFillRect &&
+ CHECK_PLANEMASK(pGC,infoRec->SolidFillFlags) &&
+ CHECK_BG(pGC,infoRec->SolidFillFlags))
+ {
+ pGC->ops->ImageText8 = infoRec->ImageText8NonTE;
+ pGC->ops->ImageText16 = infoRec->ImageText16NonTE;
+ pGC->ops->ImageGlyphBlt = infoRec->ImageGlyphBltNonTE;
+ }
+ } else if(infoRec->ImageGlyphBltTE &&
+ CHECK_PLANEMASK(pGC,infoRec->ImageGlyphBltTEFlags)){
+ if(!(infoRec->ImageGlyphBltTEFlags & TRANSPARENCY_ONLY) &&
+ CHECK_COLORS(pGC,infoRec->ImageGlyphBltTEFlags))
+ {
+ pGC->ops->ImageText8 = infoRec->ImageText8TE;
+ pGC->ops->ImageText16 = infoRec->ImageText16TE;
+ pGC->ops->ImageGlyphBlt = infoRec->ImageGlyphBltTE;
+ } else {
+ if(CHECK_FG(pGC,infoRec->ImageGlyphBltTEFlags) &&
+ infoRec->SetupForSolidFill && infoRec->SubsequentSolidFillRect &&
+ CHECK_PLANEMASK(pGC,infoRec->SolidFillFlags) &&
+ CHECK_BG(pGC,infoRec->SolidFillFlags))
+ {
+ pGC->ops->ImageText8 = infoRec->ImageText8TE;
+ pGC->ops->ImageText16 = infoRec->ImageText16TE;
+ pGC->ops->ImageGlyphBlt = infoRec->ImageGlyphBltTE;
+ }
+ }
+ }
+}
+
+
+void
+XAAValidatePolylines(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAAGCPtr pGCPriv = (XAAGCPtr) (pGC)->devPrivates[XAAGCIndex].ptr;
+
+ if(pGC->lineStyle == LineSolid) changes &= ~GCDashList;
+ if(!changes) return;
+
+ pGC->ops->PolySegment = XAAFallbackOps.PolySegment;
+ pGC->ops->Polylines = XAAFallbackOps.Polylines;
+ pGC->ops->PolyRectangle = XAAFallbackOps.PolyRectangle;
+ pGC->ops->PolyArc = XAAFallbackOps.PolyArc;
+
+ if((pGC->ops->FillSpans != XAAFallbackOps.FillSpans) &&
+ (pGC->lineWidth > 0)){
+
+ pGC->ops->PolyArc = miPolyArc;
+ pGC->ops->PolySegment = miPolySegment;
+ pGC->ops->PolyRectangle = miPolyRectangle;
+ if(pGC->lineStyle == LineSolid)
+ pGC->ops->Polylines = miWideLine;
+ else
+ pGC->ops->Polylines = miWideDash;
+ }
+
+ if((pGC->lineWidth == 0) && (pGC->fillStyle == FillSolid)) {
+
+ if(pGC->lineStyle == LineSolid) {
+
+ if(infoRec->PolyRectangleThinSolid &&
+ CHECK_PLANEMASK(pGC,infoRec->PolyRectangleThinSolidFlags) &&
+ CHECK_ROP(pGC,infoRec->PolyRectangleThinSolidFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolyRectangleThinSolidFlags) &&
+ CHECK_FG(pGC,infoRec->PolyRectangleThinSolidFlags)) {
+
+ pGC->ops->PolyRectangle = infoRec->PolyRectangleThinSolid;
+ }
+
+ if(infoRec->PolySegmentThinSolid &&
+ CHECK_PLANEMASK(pGC,infoRec->PolySegmentThinSolidFlags) &&
+ CHECK_ROP(pGC,infoRec->PolySegmentThinSolidFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolySegmentThinSolidFlags) &&
+ CHECK_FG(pGC,infoRec->PolySegmentThinSolidFlags)) {
+
+ pGC->ops->PolySegment = infoRec->PolySegmentThinSolid;
+ }
+
+ if(infoRec->PolylinesThinSolid &&
+ CHECK_PLANEMASK(pGC,infoRec->PolylinesThinSolidFlags) &&
+ CHECK_ROP(pGC,infoRec->PolylinesThinSolidFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolylinesThinSolidFlags) &&
+ CHECK_FG(pGC,infoRec->PolylinesThinSolidFlags)) {
+
+ pGC->ops->Polylines = infoRec->PolylinesThinSolid;
+ }
+ } else if((pGC->lineStyle == LineOnOffDash) && pGCPriv->DashPattern){
+
+ if(infoRec->PolySegmentThinDashed &&
+ !(infoRec->PolySegmentThinDashedFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->PolySegmentThinDashedFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_PLANEMASK(pGC,infoRec->PolySegmentThinDashedFlags) &&
+ CHECK_ROP(pGC,infoRec->PolySegmentThinDashedFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolySegmentThinDashedFlags) &&
+ CHECK_FG(pGC,infoRec->PolySegmentThinDashedFlags)) {
+
+ pGC->ops->PolySegment = infoRec->PolySegmentThinDashed;
+ }
+
+ if(infoRec->PolylinesThinDashed &&
+ !(infoRec->PolylinesThinDashedFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->PolylinesThinDashedFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_PLANEMASK(pGC,infoRec->PolylinesThinDashedFlags) &&
+ CHECK_ROP(pGC,infoRec->PolylinesThinDashedFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolylinesThinDashedFlags) &&
+ CHECK_FG(pGC,infoRec->PolylinesThinDashedFlags)) {
+
+ pGC->ops->Polylines = infoRec->PolylinesThinDashed;
+ }
+
+ if(pGC->ops->Polylines != XAAFallbackOps.Polylines)
+ pGC->ops->PolyRectangle = miPolyRectangle;
+
+ } else if(pGCPriv->DashPattern) { /* LineDoubleDash */
+
+ if(infoRec->PolySegmentThinDashed &&
+ !(infoRec->PolySegmentThinDashedFlags & TRANSPARENCY_ONLY) &&
+ CHECK_PLANEMASK(pGC,infoRec->PolySegmentThinDashedFlags) &&
+ CHECK_ROP(pGC,infoRec->PolySegmentThinDashedFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolySegmentThinDashedFlags) &&
+ CHECK_COLORS(pGC,infoRec->PolySegmentThinDashedFlags)) {
+
+ pGC->ops->PolySegment = infoRec->PolySegmentThinDashed;
+ }
+
+ if(infoRec->PolylinesThinDashed &&
+ !(infoRec->PolylinesThinDashedFlags & TRANSPARENCY_ONLY) &&
+ CHECK_PLANEMASK(pGC,infoRec->PolylinesThinDashedFlags) &&
+ CHECK_ROP(pGC,infoRec->PolylinesThinDashedFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolylinesThinDashedFlags) &&
+ CHECK_COLORS(pGC,infoRec->PolylinesThinDashedFlags)) {
+
+ pGC->ops->Polylines = infoRec->PolylinesThinDashed;
+ }
+
+ if(pGC->ops->Polylines != XAAFallbackOps.Polylines)
+ pGC->ops->PolyRectangle = miPolyRectangle;
+
+ }
+ }
+
+ if(infoRec->PolylinesWideSolid &&
+ (pGC->lineWidth > 0) &&
+ (pGC->fillStyle == FillSolid) &&
+ (pGC->lineStyle == LineSolid) &&
+ CHECK_PLANEMASK(pGC,infoRec->PolylinesWideSolidFlags) &&
+ CHECK_ROP(pGC,infoRec->PolylinesWideSolidFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolylinesWideSolidFlags) &&
+ CHECK_FG(pGC,infoRec->PolylinesWideSolidFlags)) {
+
+ pGC->ops->Polylines = infoRec->PolylinesWideSolid;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaImage.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaImage.c
new file mode 100644
index 000000000..7a1c9be14
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaImage.c
@@ -0,0 +1,601 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaImage.c,v 1.16 1999/07/04 06:39:17 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+#include "servermd.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "mi.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+void XAAMoveDWORDS_FixedBase(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *dest = *(src + 1);
+ *dest = *(src + 2);
+ *dest = *(src + 3);
+ dwords -= 4;
+ src += 4;
+ }
+
+ if(!dwords) return;
+ *dest = *src;
+ if(dwords == 1) return;
+ *dest = *(src + 1);
+ if(dwords == 2) return;
+ *dest = *(src + 2);
+}
+
+void XAAMoveDWORDS(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ *(dest + 2) = *(src + 2);
+ *(dest + 3) = *(src + 3);
+ src += 4;
+ dest += 4;
+ dwords -= 4;
+ }
+ if(!dwords) return;
+ *dest = *src;
+ if(dwords == 1) return;
+ *(dest + 1) = *(src + 1);
+ if(dwords == 2) return;
+ *(dest + 2) = *(src + 2);
+}
+
+void XAAMoveDWORDS_FixedSrc(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *src;
+ *(dest + 2) = *src;
+ *(dest + 3) = *src;
+ dest += 4;
+ dwords -= 4;
+ }
+ if(!dwords) return;
+ *dest = *src;
+ if(dwords == 1) return;
+ *(dest + 1) = *src;
+ if(dwords == 2) return;
+ *(dest + 2) = *src;
+}
+
+static void
+XAAWritePixmap32To24(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *srcInit,
+ int srcwidth, /* bytes */
+ int rop,
+ unsigned int planemask,
+ int trans
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int count, dwords = ((w * 3) + 3) >> 2;
+ CARD32 *src, *dst;
+ Bool PlusOne = FALSE;
+
+ if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
+ ((dwords * h) & 0x01)) {
+ PlusOne = TRUE;
+ }
+
+ (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, 24, 24);
+ (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, 0);
+
+ if(dwords > infoRec->ImageWriteRange) {
+ dst = (CARD32*)infoRec->ImageWriteBase;
+ while(h--) {
+ src = (CARD32*)srcInit;
+ count = w;
+
+ while(count >= 4) {
+ *dst = (src[0] & 0x00ffffff) | (src[1] << 24);
+ *dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
+ *dst = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8);
+ src += 4;
+ count -= 4;
+ }
+ switch(count) {
+ case 0: break;
+ case 1: *dst = src[0];
+ break;
+ case 2: *dst = (src[0] & 0x00ffffff) | (src[1] << 24);
+ *dst = src[1] >> 8;
+ break;
+ default: *dst = (src[0] & 0x00ffffff) | (src[1] << 24);
+ *dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
+ *dst = src[2] >> 16;
+ break;
+ }
+ srcInit += srcwidth;
+ }
+ } else {
+ while(h--) {
+ dst = (CARD32*)infoRec->ImageWriteBase;
+ src = (CARD32*)srcInit;
+ count = w;
+
+ while(count >= 4) {
+ dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
+ dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
+ dst[2] = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8);
+ dst += 3;
+ src += 4;
+ count -= 4;
+ }
+ switch(count) {
+ case 0: break;
+ case 1: dst[0] = src[0];
+ break;
+ case 2: dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
+ dst[1] = src[1] >> 8;
+ break;
+ default: dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
+ dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
+ dst[2] = src[2] >> 16;
+ break;
+ }
+ srcInit += srcwidth;
+ }
+ }
+
+ if(PlusOne) {
+ CARD32* base = (CARD32*)infoRec->ImageWriteBase;
+ *base = 0x00000000;
+ }
+
+ if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+
+}
+
+void
+XAAWritePixmap (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth, /* bytes */
+ int rop,
+ unsigned int planemask,
+ int trans,
+ int bpp, int depth
+){
+ XAAInfoRecPtr infoRec;
+ int dwords, skipleft, Bpp;
+ Bool beCareful, PlusOne;
+
+ if((bpp == 32) && (pScrn->bitsPerPixel == 24)) {
+ XAAWritePixmap32To24(pScrn, x, y, w, h, src, srcwidth,
+ rop, planemask, trans);
+ return;
+ }
+
+ infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ beCareful = PlusOne = FALSE;
+ Bpp = bpp >> 3;
+
+ if((skipleft = (long)src & 0x03L)) {
+ if(!(infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING)) {
+ skipleft = 0;
+ beCareful = TRUE;
+ goto BAD_ALIGNMENT;
+ }
+
+ if(Bpp == 3)
+ skipleft = 4 - skipleft;
+ else
+ skipleft /= Bpp;
+
+ if((x < skipleft) && !(infoRec->ImageWriteFlags &
+ LEFT_EDGE_CLIPPING_NEGATIVE_X)) {
+ skipleft = 0;
+ beCareful = TRUE;
+ goto BAD_ALIGNMENT;
+ }
+
+ x -= skipleft;
+ w += skipleft;
+
+ if(Bpp == 3)
+ src -= 3 * skipleft;
+ else /* is this Alpha friendly ? */
+ src = (unsigned char*)((long)src & ~0x03L);
+ }
+
+BAD_ALIGNMENT:
+
+ dwords = ((w * Bpp) + 3) >> 2;
+
+ if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
+ ((dwords * h) & 0x01)) {
+ PlusOne = TRUE;
+ }
+
+
+ (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, bpp, depth);
+ (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, skipleft);
+
+ if(beCareful) {
+ /* in cases with bad alignment we have to be careful not
+ to read beyond the end of the source */
+ if(((x * Bpp) + (dwords << 2)) > srcwidth) h--;
+ else beCareful = FALSE;
+ }
+
+ if(dwords > infoRec->ImageWriteRange) {
+ while(h--) {
+ XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src += srcwidth;
+ }
+ if(beCareful) {
+ int shift = ((long)src & 0x03L) << 3;
+ if(--dwords)
+ XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
+ *((CARD32*)infoRec->ImageWriteBase) = *((CARD32*)src) >> shift;
+ }
+ } else {
+ if(srcwidth == (dwords << 2)) {
+ int decrement = infoRec->ImageWriteRange/dwords;
+
+ while(h > decrement) {
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords * decrement);
+ src += (srcwidth * decrement);
+ h -= decrement;
+ }
+ if(h) {
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords * h);
+ if(beCareful) src += (srcwidth * h);
+ }
+ } else {
+ while(h--) {
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src += srcwidth;
+ }
+ }
+
+ if(beCareful) {
+ int shift = ((long)src & 0x03L) << 3;
+ if(--dwords)
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
+
+ ((CARD32*)infoRec->ImageWriteBase)[dwords] =
+ *((CARD32*)src) >> shift;
+ }
+ }
+
+ if(PlusOne) {
+ CARD32* base = (CARD32*)infoRec->ImageWriteBase;
+ *base = 0x00000000;
+ }
+
+ if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+
+void
+XAAWritePixmapScanline (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth, /* bytes */
+ int rop,
+ unsigned int planemask,
+ int trans,
+ int bpp, int depth
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int dwords, skipleft, bufferNo = 0, Bpp = bpp >> 3;
+ Bool beCareful = FALSE;
+ CARD32* base = (CARD32*)infoRec->ScanlineImageWriteBuffers[0];
+
+ if((skipleft = (long)src & 0x03L)) {
+ if(!(infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING)) {
+ skipleft = 0;
+ beCareful = TRUE;
+ goto BAD_ALIGNMENT;
+ }
+
+ if(Bpp == 3)
+ skipleft = 4 - skipleft;
+ else
+ skipleft /= Bpp;
+
+ if((x < skipleft) && !(infoRec->ImageWriteFlags &
+ LEFT_EDGE_CLIPPING_NEGATIVE_X)) {
+ skipleft = 0;
+ beCareful = TRUE;
+ goto BAD_ALIGNMENT;
+ }
+
+ x -= skipleft;
+ w += skipleft;
+
+ if(Bpp == 3)
+ src -= 3 * skipleft;
+ else
+ src = (unsigned char*)((long)src & ~0x03L);
+ }
+
+BAD_ALIGNMENT:
+
+ dwords = ((w * Bpp) + 3) >> 2;
+
+ (*infoRec->SetupForScanlineImageWrite)(
+ pScrn, rop, planemask, trans, bpp, depth);
+ (*infoRec->SubsequentScanlineImageWriteRect)(pScrn, x, y, w, h, skipleft);
+
+ if(beCareful) {
+ /* in cases with bad alignment we have to be careful not
+ to read beyond the end of the source */
+ if(((x * Bpp) + (dwords << 2)) > srcwidth) h--;
+ else beCareful = FALSE;
+ }
+
+ while(h--) {
+ XAAMoveDWORDS(base, (CARD32*)src, dwords);
+ (*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo++);
+ src += srcwidth;
+ if(bufferNo >= infoRec->NumScanlineImageWriteBuffers)
+ bufferNo = 0;
+ base = (CARD32*)infoRec->ScanlineImageWriteBuffers[bufferNo];
+ }
+
+ if(beCareful) {
+ int shift = ((long)src & 0x03L) << 3;
+ if(--dwords)
+ XAAMoveDWORDS(base,(CARD32*)src, dwords);
+ src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
+
+ base[dwords] = *((CARD32*)src) >> shift;
+ (*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo);
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+void
+XAAPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int bpp = BitsPerPixel(depth);
+ if(!w || !h) return;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ if(((format == ZPixmap) && infoRec->WritePixmap &&
+ ((pDraw->bitsPerPixel == bpp) ||
+ ((pDraw->bitsPerPixel == 24) && (bpp == 32) &&
+ (infoRec->WritePixmapFlags & CONVERT_32BPP_TO_24BPP))) &&
+ CHECK_ROP(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_NO_GXCOPY(pGC,infoRec->WritePixmapFlags)) ||
+ ((format == XYBitmap) && infoRec->WriteBitmap &&
+ CHECK_ROP(pGC,infoRec->WriteBitmapFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->WriteBitmapFlags) &&
+ CHECK_COLORS(pGC,infoRec->WriteBitmapFlags) &&
+ !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY)) ||
+ ((format == XYPixmap) && infoRec->WriteBitmap &&
+ CHECK_ROP(pGC,infoRec->WriteBitmapFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) &&
+ !(infoRec->WriteBitmapFlags & NO_PLANEMASK) &&
+ !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY))){
+
+ int MaxBoxes = REGION_NUM_RECTS(pGC->pCompositeClip);
+ BoxPtr pbox, pClipBoxes;
+ int nboxes, srcx, srcy, srcwidth;
+ xRectangle TheRect;
+
+ TheRect.x = pDraw->x + x;
+ TheRect.y = pDraw->y + y;
+ TheRect.width = w;
+ TheRect.height = h;
+
+ if(MaxBoxes > (infoRec->PreAllocSize/sizeof(BoxRec))) {
+ pClipBoxes = xalloc(MaxBoxes * sizeof(BoxRec));
+ if(!pClipBoxes) return;
+ } else pClipBoxes = (BoxPtr)infoRec->PreAllocMem;
+
+ nboxes =
+ XAAGetRectClipBoxes(pGC->pCompositeClip, pClipBoxes, 1, &TheRect);
+ pbox = pClipBoxes;
+
+ if(format == XYBitmap) {
+ srcwidth = BitmapBytePad(leftPad + w);
+ while(nboxes--) {
+ srcx = pbox->x1 - TheRect.x + leftPad;
+ srcy = pbox->y1 - TheRect.y;
+ (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ (unsigned char*)pImage +
+ (srcwidth * srcy) + ((srcx >> 5) << 2),
+ srcwidth, srcx & 31, pGC->fgPixel, pGC->bgPixel,
+ pGC->alu, pGC->planemask);
+ pbox++;
+ }
+ } else if(format == ZPixmap) {
+ int Bpp = bpp >> 3;
+ srcwidth = PixmapBytePad(leftPad + w, depth);
+ while(nboxes--) {
+ srcx = pbox->x1 - TheRect.x + leftPad;
+ srcy = pbox->y1 - TheRect.y;
+ (*infoRec->WritePixmap)(infoRec->pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ (unsigned char*)pImage +
+ (srcwidth * srcy) + (srcx * Bpp),
+ srcwidth, pGC->alu, pGC->planemask, -1,
+ Bpp << 3, depth);
+ pbox++;
+ }
+ } else { /* XYPixmap */
+ int depth = pGC->depth;
+ int numBox, increment;
+ unsigned long i, mask;
+ BoxPtr pntBox;
+
+ srcwidth = BitmapBytePad(w + leftPad);
+ increment = h * srcwidth;
+ i = 1 << (depth - 1);
+ mask = ~0;
+
+ if((infoRec->pScrn->overlayFlags & OVERLAY_8_32_PLANAR) &&
+ (pGC->depth == 8)){
+ i = 0x80000000; mask = 0xff000000;
+ }
+
+ for(; i & mask; i >>= 1, pImage += increment) {
+ if(i & pGC->planemask) {
+ pntBox = pbox;
+ numBox = nboxes;
+ while(numBox--) {
+ srcx = pntBox->x1 - TheRect.x + leftPad;
+ srcy = pntBox->y1 - TheRect.y;
+ (*infoRec->WriteBitmap)(infoRec->pScrn,
+ pntBox->x1, pntBox->y1,
+ pntBox->x2 - pntBox->x1,
+ pntBox->y2 - pntBox->y1,
+ (unsigned char*)pImage +
+ (srcwidth * srcy) + ((srcx >> 5) << 2),
+ srcwidth, srcx & 31, ~0, 0, pGC->alu, i);
+ pntBox++;
+ }
+ }
+ }
+
+ }
+
+ if(pClipBoxes != (BoxPtr)infoRec->PreAllocMem)
+ xfree(pClipBoxes);
+ } else
+ XAAFallbackOps.PutImage(pDraw, pGC, depth, x, y, w, h, leftPad,
+ format, pImage);
+}
+
+
+void
+XAAReadPixmap (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *dst,
+ int dstwidth, /* bytes */
+ int bpp, int depth
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int ReadDwords, WriteBytes, Surplus, Bpp = bpp >> 3;
+ unsigned char *tmp;
+ Bool PlusOne = FALSE;
+ union {
+ CARD32 IntData;
+ unsigned char CharData[4];
+ } extra;
+
+ WriteBytes = w * Bpp;
+ ReadDwords = (WriteBytes + 3) >> 2;
+
+ if((infoRec->ImageReadFlags & CPU_TRANSFER_PAD_QWORD) &&
+ ((ReadDwords * h) & 0x01)) {
+ PlusOne = TRUE;
+ }
+
+
+ (*infoRec->SetupForImageRead)(pScrn, bpp, depth);
+ (*infoRec->SubsequentImageReadRect)(pScrn, x, y, w, h);
+
+ if(ReadDwords > infoRec->ImageWriteRange) {
+ if((Surplus = (ReadDwords << 2) - WriteBytes)) {
+ ReadDwords--;
+ while(h--) {
+ if(ReadDwords)
+ XAAMoveDWORDS_FixedSrc((CARD32*)dst,
+ (CARD32*)infoRec->ImageReadBase, ReadDwords);
+ extra.IntData = *((CARD32*)infoRec->ImageReadBase);
+ tmp = dst + (ReadDwords << 2);
+ switch(Surplus) {
+ case 3: tmp[2] = extra.CharData[2];
+ case 2: tmp[1] = extra.CharData[1];
+ case 1: tmp[0] = extra.CharData[0];
+ }
+ dst += dstwidth;
+ }
+ } else {
+ while(h--) {
+ XAAMoveDWORDS_FixedSrc((CARD32*)dst,
+ (CARD32*)infoRec->ImageReadBase, ReadDwords);
+ dst += dstwidth;
+ }
+ }
+ } else {
+ if((Surplus = (ReadDwords << 2) - WriteBytes)) {
+ ReadDwords--;
+ while(h--) {
+ if(ReadDwords)
+ XAAMoveDWORDS((CARD32*)dst,
+ (CARD32*)infoRec->ImageReadBase, ReadDwords);
+ extra.IntData =
+ *((CARD32*)(infoRec->ImageReadBase) + ReadDwords);
+ tmp = dst + (ReadDwords << 2);
+ switch(Surplus) {
+ case 3: tmp[2] = extra.CharData[2];
+ case 2: tmp[1] = extra.CharData[1];
+ case 1: tmp[0] = extra.CharData[0];
+ }
+ dst += dstwidth;
+ }
+ } else {
+ while(h--) {
+ XAAMoveDWORDS((CARD32*)dst,
+ (CARD32*)infoRec->ImageReadBase, ReadDwords);
+ dst += dstwidth;
+ }
+ }
+ }
+
+ if(PlusOne)
+ extra.IntData = *((CARD32*)infoRec->ImageReadBase);
+
+ SET_SYNC_FLAG(infoRec);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaInit.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaInit.c
new file mode 100644
index 000000000..86100a07a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaInit.c
@@ -0,0 +1,687 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaInit.c,v 1.21 1999/07/10 12:17:41 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "mi.h"
+#include "miline.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+#include "xf86fbman.h"
+#include "servermd.h"
+
+#define MAX_PREALLOC_MEM 65536 /* MUST be >= 1024 */
+
+#define MIN_OFFPIX_SIZE (320*200)
+
+static Bool XAACloseScreen(int i, ScreenPtr pScreen);
+static void XAAGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
+ unsigned int format, unsigned long planemask,
+ char *pdstLine);
+static void XAAGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
+ int *pwidth, int nspans, char *pdstStart);
+static PixmapPtr XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth);
+static Bool XAADestroyPixmap(PixmapPtr pPixmap);
+static void XAARestoreAreas (PixmapPtr pPixmap, RegionPtr prgnRestore,
+ int xorg, int yorg, WindowPtr pWin);
+static void XAASaveAreas (PixmapPtr pPixmap, RegionPtr prgnSave,
+ int xorg, int yorg, WindowPtr pWin);
+static Bool XAAEnterVT (int index, int flags);
+static void XAALeaveVT (int index, int flags);
+static int XAASetDGAMode(int index, int num, DGADevicePtr devRet);
+static Bool XAASaveRestoreImage (int index, SaveRestoreFlags what);
+static Bool XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask);
+
+int XAAScreenIndex = -1;
+int XAAGCIndex = -1;
+int XAAPixmapIndex = -1;
+static unsigned long XAAGeneration = 0;
+
+
+#ifdef XFree86LOADER
+
+static XF86ModuleVersionInfo xaaVersRec =
+{
+ "xaa",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_VIDEODRV, /* requires the video driver ABI */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0}
+};
+
+
+XF86ModuleData xaaModuleData = { &xaaVersRec, NULL, NULL };
+
+#endif
+
+
+XAAInfoRecPtr
+XAACreateInfoRec()
+{
+ XAAInfoRecPtr infoRec;
+
+ infoRec = xcalloc(1, sizeof(XAAInfoRec));
+ if(infoRec)
+ infoRec->CachePixelGranularity = -1;
+
+ return infoRec;
+}
+
+void
+XAADestroyInfoRec(XAAInfoRecPtr infoRec)
+{
+ if(!infoRec) return;
+
+ if(infoRec->ClosePixmapCache)
+ (*infoRec->ClosePixmapCache)(infoRec->pScrn->pScreen);
+
+ if(infoRec->PreAllocMem)
+ xfree(infoRec->PreAllocMem);
+
+ if(infoRec->PixmapCachePrivate)
+ xfree(infoRec->PixmapCachePrivate);
+
+ xfree(infoRec);
+}
+
+
+Bool
+XAAInit(ScreenPtr pScreen, XAAInfoRecPtr infoRec)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAScreenPtr pScreenPriv;
+
+ if (XAAGeneration != serverGeneration) {
+ if ( ((XAAScreenIndex = AllocateScreenPrivateIndex()) < 0) ||
+ ((XAAGCIndex = AllocateGCPrivateIndex()) < 0) ||
+ ((XAAPixmapIndex = AllocatePixmapPrivateIndex()) < 0))
+ return FALSE;
+
+ XAAGeneration = serverGeneration;
+ }
+
+ if (!AllocateGCPrivate(pScreen, XAAGCIndex, sizeof(XAAGCRec)))
+ return FALSE;
+
+ if (!AllocatePixmapPrivate(pScreen, XAAPixmapIndex, sizeof(XAAPixmapRec)))
+ return FALSE;
+
+ if (!(pScreenPriv = xalloc(sizeof(XAAScreenRec))))
+ return FALSE;
+
+ pScreen->devPrivates[XAAScreenIndex].ptr = (pointer)pScreenPriv;
+
+ if(!xf86FBManagerRunning(pScreen))
+ infoRec->Flags &= ~(PIXMAP_CACHE | OFFSCREEN_PIXMAPS);
+ if(!(infoRec->Flags & LINEAR_FRAMEBUFFER))
+ infoRec->Flags &= ~OFFSCREEN_PIXMAPS;
+#if 0
+ if(pScreen->backingStoreSupport || pScreen->saveUnderSupport)
+ infoRec->Flags &= ~OFFSCREEN_PIXMAPS;
+#endif
+
+ if(!XAAInitAccel(pScreen, infoRec)) return FALSE;
+ pScreenPriv->AccelInfoRec = infoRec;
+ infoRec->ScratchGC.pScreen = pScreen;
+
+
+ if(!infoRec->GetImage)
+ infoRec->GetImage = XAAGetImage;
+ if(!infoRec->GetSpans)
+ infoRec->GetSpans = XAAGetSpans;
+ if(!infoRec->PaintWindowBackground)
+ infoRec->PaintWindowBackground = XAAPaintWindow;
+ if(!infoRec->PaintWindowBorder)
+ infoRec->PaintWindowBorder = XAAPaintWindow;
+ if(!infoRec->CopyWindow)
+ infoRec->CopyWindow = XAACopyWindow;
+ if(!infoRec->SaveAreas)
+ infoRec->SaveAreas = XAASaveAreas;
+ if(!infoRec->RestoreAreas)
+ infoRec->RestoreAreas = XAARestoreAreas;
+
+ pScreenPriv->CreateGC = pScreen->CreateGC;
+ pScreen->CreateGC = XAACreateGC;
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = XAACloseScreen;
+ pScreenPriv->GetImage = pScreen->GetImage;
+ pScreen->GetImage = infoRec->GetImage;
+ pScreenPriv->GetSpans = pScreen->GetSpans;
+ pScreen->GetSpans = infoRec->GetSpans;
+ pScreenPriv->PaintWindowBackground = pScreen->PaintWindowBackground;
+ pScreen->PaintWindowBackground = infoRec->PaintWindowBackground;
+ pScreenPriv->PaintWindowBorder = pScreen->PaintWindowBorder;
+ pScreen->PaintWindowBorder = infoRec->PaintWindowBorder;
+ pScreenPriv->CopyWindow = pScreen->CopyWindow;
+ pScreen->CopyWindow = infoRec->CopyWindow;
+ pScreenPriv->CreatePixmap = pScreen->CreatePixmap;
+ pScreen->CreatePixmap = XAACreatePixmap;
+ pScreenPriv->DestroyPixmap = pScreen->DestroyPixmap;
+ pScreen->DestroyPixmap = XAADestroyPixmap;
+ pScreenPriv->BackingStoreFuncs.RestoreAreas =
+ pScreen->BackingStoreFuncs.RestoreAreas;
+ pScreen->BackingStoreFuncs.RestoreAreas = infoRec->RestoreAreas;
+ pScreenPriv->BackingStoreFuncs.SaveAreas =
+ pScreen->BackingStoreFuncs.SaveAreas;
+ pScreen->BackingStoreFuncs.SaveAreas = infoRec->SaveAreas;
+ pScreenPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
+ pScreen->ChangeWindowAttributes = XAAChangeWindowAttributes;
+
+ pScreenPriv->EnterVT = pScrn->EnterVT;
+ pScrn->EnterVT = XAAEnterVT;
+ pScreenPriv->LeaveVT = pScrn->LeaveVT;
+ pScrn->LeaveVT = XAALeaveVT;
+ pScreenPriv->SetDGAMode = pScrn->SetDGAMode;
+ pScrn->SetDGAMode = XAASetDGAMode;
+ pScreenPriv->SaveRestoreImage = pScrn->SaveRestoreImage;
+ pScrn->SaveRestoreImage = XAASaveRestoreImage;
+
+ pScreenPriv->WindowExposures = pScreen->WindowExposures;
+ if(pScrn->overlayFlags & OVERLAY_8_32_PLANAR) {
+ pScreen->PaintWindowBackground = XAAPaintWindow8_32;
+ pScreen->PaintWindowBorder = XAAPaintWindow8_32;
+ pScreen->CopyWindow = XAACopyWindow8_32;
+ pScreen->WindowExposures = XAAWindowExposures8_32;
+ infoRec->FullPlanemask = ~0;
+ }
+
+ infoRec->PreAllocMem = xalloc(MAX_PREALLOC_MEM);
+ if(infoRec->PreAllocMem)
+ infoRec->PreAllocSize = MAX_PREALLOC_MEM;
+
+ if(infoRec->Flags & PIXMAP_CACHE)
+ xf86RegisterFreeBoxCallback(pScreen, infoRec->InitPixmapCache,
+ (pointer)infoRec);
+
+ if(infoRec->Flags & MICROSOFT_ZERO_LINE_BIAS)
+ miSetZeroLineBias(pScreen, OCTANT1 | OCTANT2 | OCTANT3 | OCTANT4);
+
+ return TRUE;
+}
+
+
+
+static Bool
+XAACloseScreen (int i, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAScreenPtr pScreenPriv =
+ (XAAScreenPtr) pScreen->devPrivates[XAAScreenIndex].ptr;
+
+ pScrn->EnterVT = pScreenPriv->EnterVT;
+ pScrn->LeaveVT = pScreenPriv->LeaveVT;
+ pScrn->SaveRestoreImage = pScreenPriv->SaveRestoreImage;
+
+ pScreen->CreateGC = pScreenPriv->CreateGC;
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ pScreen->GetImage = pScreenPriv->GetImage;
+ pScreen->GetSpans = pScreenPriv->GetSpans;
+ pScreen->PaintWindowBackground = pScreenPriv->PaintWindowBackground;
+ pScreen->PaintWindowBorder = pScreenPriv->PaintWindowBorder;
+ pScreen->CopyWindow = pScreenPriv->CopyWindow;
+ pScreen->WindowExposures = pScreenPriv->WindowExposures;
+ pScreen->CreatePixmap = pScreenPriv->CreatePixmap;
+ pScreen->DestroyPixmap = pScreenPriv->DestroyPixmap;
+ pScreen->BackingStoreFuncs.RestoreAreas =
+ pScreenPriv->BackingStoreFuncs.RestoreAreas;
+ pScreen->BackingStoreFuncs.SaveAreas =
+ pScreenPriv->BackingStoreFuncs.SaveAreas;
+ pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes;
+
+ /* We leave it up to the client to free the XAAInfoRec */
+
+ xfree ((pointer) pScreenPriv);
+
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+static void
+XAAGetImage (
+ DrawablePtr pDraw,
+ int sx, int sy, int w, int h,
+ unsigned int format,
+ unsigned long planemask,
+ char *pdstLine
+)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ XAA_SCREEN_PROLOGUE (pScreen, GetImage);
+ if(xf86Screens[pScreen->myNum]->vtSema &&
+ ((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw))) {
+ SYNC_CHECK(pDraw);
+ }
+ (*pScreen->GetImage) (pDraw, sx, sy, w, h, format, planemask, pdstLine);
+ XAA_SCREEN_EPILOGUE (pScreen, GetImage, XAAGetImage);
+}
+
+static void
+XAAGetSpans (
+ DrawablePtr pDraw,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pdstStart
+)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ XAA_SCREEN_PROLOGUE (pScreen, GetSpans);
+ if(xf86Screens[pScreen->myNum]->vtSema &&
+ ((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw))) {
+ SYNC_CHECK(pDraw);
+ }
+ (*pScreen->GetSpans) (pDraw, wMax, ppt, pwidth, nspans, pdstStart);
+ XAA_SCREEN_EPILOGUE (pScreen, GetSpans, XAAGetSpans);
+}
+
+
+static void
+XAASaveAreas (
+ PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+){
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+
+ if(IS_OFFSCREEN_PIXMAP(pPixmap)) {
+ BoxPtr pbox = REGION_RECTS(prgnSave);
+ int nboxes = REGION_NUM_RECTS(prgnSave);
+
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, GXcopy, ~0, -1);
+ while(nboxes--) {
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pbox->x1 + xorg, pbox->y1 + yorg,
+ pPixmap->drawable.x + pbox->x1,
+ pPixmap->drawable.y + pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ pbox++;
+ }
+ SET_SYNC_FLAG(infoRec);
+ return;
+ }
+
+ if(xf86Screens[pScreen->myNum]->vtSema && infoRec->ReadPixmap &&
+ (pWin->drawable.bitsPerPixel == pPixmap->drawable.bitsPerPixel)) {
+ BoxPtr pbox = REGION_RECTS(prgnSave);
+ int nboxes = REGION_NUM_RECTS(prgnSave);
+ int Bpp = pPixmap->drawable.bitsPerPixel >> 3;
+ unsigned char *dstp = (unsigned char*)pPixmap->devPrivate.ptr;
+
+ while(nboxes--) {
+ (*infoRec->ReadPixmap)(infoRec->pScrn,
+ pbox->x1 + xorg, pbox->y1 + yorg,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ dstp + (pPixmap->devKind * pbox->y1) + (pbox->x1 * Bpp),
+ pPixmap->devKind,
+ pPixmap->drawable.bitsPerPixel, pPixmap->drawable.depth);
+ pbox++;
+ }
+ return;
+ }
+
+ XAA_SCREEN_PROLOGUE (pScreen, BackingStoreFuncs.SaveAreas);
+ if(pScrn->vtSema) {
+ SYNC_CHECK(&pWin->drawable);
+ }
+ (*pScreen->BackingStoreFuncs.SaveAreas) (
+ pPixmap, prgnSave, xorg, yorg, pWin);
+
+ XAA_SCREEN_EPILOGUE (pScreen, BackingStoreFuncs.SaveAreas,
+ XAASaveAreas);
+}
+
+static void
+XAARestoreAreas (
+ PixmapPtr pPixmap,
+ RegionPtr prgnRestore,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+){
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+
+ if(IS_OFFSCREEN_PIXMAP(pPixmap)) {
+ BoxPtr pbox = REGION_RECTS(prgnRestore);
+ int nboxes = REGION_NUM_RECTS(prgnRestore);
+ int pm = ~0;
+
+ if((pScrn->overlayFlags & OVERLAY_8_32_PLANAR) &&
+ (pWin->drawable.depth == 24))
+ pm = 0x00ffffff;
+
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, GXcopy, pm, -1);
+ while(nboxes--) {
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pPixmap->drawable.x + pbox->x1 - xorg,
+ pPixmap->drawable.y + pbox->y1 - yorg,
+ pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ pbox++;
+ }
+ SET_SYNC_FLAG(infoRec);
+ return;
+ }
+
+ if(pScrn->vtSema && infoRec->WritePixmap &&
+ !(infoRec->WritePixmapFlags & NO_GXCOPY) &&
+ ((pWin->drawable.bitsPerPixel == pPixmap->drawable.bitsPerPixel) ||
+ ((pWin->drawable.bitsPerPixel == 24) &&
+ (pPixmap->drawable.bitsPerPixel == 32) &&
+ (infoRec->WritePixmapFlags & CONVERT_32BPP_TO_24BPP)))) {
+ BoxPtr pbox = REGION_RECTS(prgnRestore);
+ int nboxes = REGION_NUM_RECTS(prgnRestore);
+ int Bpp = pPixmap->drawable.bitsPerPixel >> 3;
+ unsigned char *srcp = (unsigned char*)pPixmap->devPrivate.ptr;
+ int pm = ~0;
+
+ if((pScrn->overlayFlags & OVERLAY_8_32_PLANAR) &&
+ (pWin->drawable.depth == 24))
+ pm = 0x00ffffff;
+
+ while(nboxes--) {
+ (*infoRec->WritePixmap)(pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ srcp + (pPixmap->devKind * (pbox->y1 - yorg)) +
+ ((pbox->x1 - xorg) * Bpp),
+ pPixmap->devKind, GXcopy, pm, -1,
+ pPixmap->drawable.bitsPerPixel, pPixmap->drawable.depth);
+ pbox++;
+ }
+ return;
+ }
+
+ XAA_SCREEN_PROLOGUE (pScreen, BackingStoreFuncs.RestoreAreas);
+ if(pScrn->vtSema) {
+ SYNC_CHECK(&pWin->drawable);
+ }
+ (*pScreen->BackingStoreFuncs.RestoreAreas) (
+ pPixmap, prgnRestore, xorg, yorg, pWin);
+
+ XAA_SCREEN_EPILOGUE (pScreen, BackingStoreFuncs.RestoreAreas,
+ XAARestoreAreas);
+}
+
+
+static PixmapPtr
+XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAPixmapPtr pPriv;
+ PixmapPtr pPix = NULL;
+ int size = w * h;
+
+ if((infoRec->Flags & OFFSCREEN_PIXMAPS) && pScrn->vtSema && (depth != 1) &&
+ ((BitsPerPixel(depth) == pScrn->bitsPerPixel) ||
+ !(pScrn->overlayFlags & OVERLAY_8_32_PLANAR)) &&
+ (size >= MIN_OFFPIX_SIZE) &&
+ (!infoRec->maxOffPixWidth || (w <= infoRec->maxOffPixWidth)) &&
+ (!infoRec->maxOffPixHeight || (h <= infoRec->maxOffPixHeight)) )
+ {
+
+ PixmapPtr pScreenPix;
+
+ XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
+ pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth);
+ XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap);
+
+ if(pPix) {
+ FBAreaPtr area = NULL;
+ PixmapLinkPtr pLink = NULL;
+ int gran = 0;
+
+ pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
+
+ switch(pScrn->bitsPerPixel) {
+ case 24:
+ case 8: gran = 4; break;
+ case 16: gran = 2; break;
+ case 32: gran = 1; break;
+ default: break;
+ }
+
+ if(BITMAP_SCANLINE_PAD == 64)
+ gran *= 2;
+
+ pLink = xalloc(sizeof(PixmapLink));
+
+ if(pLink)
+ area = xf86AllocateOffscreenArea(pScreen, w, h, gran, 0,
+ XAARemoveAreaCallback, pPix);
+ if(area){
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ pPix->drawable.x = area->box.x1;
+ pPix->drawable.y = area->box.y1;
+ pPix->drawable.width = w;
+ pPix->drawable.height = h;
+ pPix->drawable.bitsPerPixel = pScrn->bitsPerPixel;
+ pPix->devKind = pScreenPix->devKind;
+ pPix->devPrivate.ptr = pScreenPix->devPrivate.ptr;
+
+ pPriv->flags = OFFSCREEN;
+ pPriv->offscreenArea = area;
+
+ pLink->next = infoRec->OffscreenPixmaps;
+ pLink->pPix = pPix;
+ infoRec->OffscreenPixmaps = pLink;
+ } else {
+ if(pLink) xfree(pLink);
+ (*pScreen->DestroyPixmap)(pPix);
+ pPix = NULL;
+ }
+ }
+ }
+
+ if(!pPix) {
+ XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
+ pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth);
+ XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap);
+
+ if(pPix) {
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ pPriv->flags = 0;
+ pPriv->offscreenArea = NULL;
+ if(!w || !h) /* either scratch or shared memory */
+ pPriv->flags |= SHARED_PIXMAP;
+ }
+ }
+
+ return pPix;
+}
+
+static Bool
+XAADestroyPixmap(PixmapPtr pPix)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ Bool ret;
+
+ if((pPix->refcnt == 1) && (pPriv->flags & OFFSCREEN)) {
+ if(pPriv->offscreenArea) {
+ if(pPriv->flags & DGA_PIXMAP)
+ xfree(pPriv->offscreenArea);
+ else
+ xf86FreeOffscreenArea(pPriv->offscreenArea);
+ } else
+ xfree(pPix->devPrivate.ptr);
+
+ DELIST_OFFSCREEN_PIXMAP(pPix);
+ }
+
+ XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap);
+ ret = (*pScreen->DestroyPixmap) (pPix);
+ XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, XAADestroyPixmap);
+
+ return ret;
+}
+
+static Bool
+XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ Bool ret;
+
+ XAA_SCREEN_PROLOGUE (pScreen, ChangeWindowAttributes);
+ ret = (*pScreen->ChangeWindowAttributes) (pWin, mask);
+ XAA_SCREEN_EPILOGUE (pScreen, ChangeWindowAttributes, XAAChangeWindowAttributes);
+
+ /* we have to assume that shared memory pixmaps are dirty
+ because we can't wrap operations on them */
+
+ if((mask & CWBackPixmap) && (pWin->backgroundState == BackgroundPixmap) &&
+ PIXMAP_IS_SHARED(pWin->background.pixmap))
+ {
+ XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->background.pixmap);
+ pPixPriv->flags |= DIRTY;
+ }
+ if((mask & CWBorderPixmap) && !(pWin->borderIsPixel) &&
+ PIXMAP_IS_SHARED(pWin->border.pixmap))
+ {
+ XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->border.pixmap);
+ pPixPriv->flags |= DIRTY;
+ }
+
+ return ret;
+}
+
+
+
+/* These two aren't really needed for anything */
+
+static Bool
+XAAEnterVT(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XAAScreenPtr pScreenPriv =
+ (XAAScreenPtr) pScreen->devPrivates[XAAScreenIndex].ptr;
+
+ return((*pScreenPriv->EnterVT)(index, flags));
+}
+
+static void
+XAALeaveVT(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XAAScreenPtr pScreenPriv =
+ (XAAScreenPtr) pScreen->devPrivates[XAAScreenIndex].ptr;
+ XAAInfoRecPtr infoRec = pScreenPriv->AccelInfoRec;
+
+ if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+
+ (*pScreenPriv->LeaveVT)(index, flags);
+}
+
+typedef struct {
+ Bool UsingPixmapCache;
+ Bool CanDoColor8x8;
+ Bool CanDoMono8x8;
+} SavedCacheState, *SavedCacheStatePtr;
+
+static int
+XAASetDGAMode(int index, int num, DGADevicePtr devRet)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAScreenPtr pScreenPriv =
+ (XAAScreenPtr) pScreen->devPrivates[XAAScreenIndex].ptr;
+ int ret;
+
+ if (!num && infoRec->dgaSaves) { /* restore old pixmap cache state */
+ SavedCacheStatePtr state = (SavedCacheStatePtr)infoRec->dgaSaves;
+
+ infoRec->UsingPixmapCache = state->UsingPixmapCache;
+ infoRec->CanDoColor8x8 = state->CanDoColor8x8;
+ infoRec->CanDoMono8x8 = state->CanDoMono8x8;
+ xfree(infoRec->dgaSaves);
+ infoRec->dgaSaves = NULL;
+ }
+
+ ret = (*pScreenPriv->SetDGAMode)(index, num, devRet);
+
+ if(num && devRet->pPix) { /* accelerate this pixmap */
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(devRet->pPix);
+ FBAreaPtr area;
+
+ if((area = xalloc(sizeof(FBArea)))) {
+ area->pScreen = pScreen;
+ area->box.x1 = 0;
+ area->box.x2 = 0;
+ area->box.y1 = devRet->mode->pixmapWidth;
+ area->box.y2 = devRet->mode->pixmapHeight;
+ area->granularity = 0;
+ area->MoveAreaCallback = 0;
+ area->RemoveAreaCallback = 0;
+ area->devPrivate.ptr = 0;
+
+ pixPriv->flags |= OFFSCREEN | DGA_PIXMAP;
+ pixPriv->offscreenArea = area;
+
+ if(!infoRec->dgaSaves) { /* save pixmap cache state */
+ SavedCacheStatePtr state = xalloc(sizeof(SavedCacheState));
+
+ state->UsingPixmapCache = infoRec->UsingPixmapCache;
+ state->CanDoColor8x8 = infoRec->CanDoColor8x8;
+ state->CanDoMono8x8 = infoRec->CanDoMono8x8;
+ infoRec->dgaSaves = (char*)state;
+
+ infoRec->UsingPixmapCache = FALSE;
+ if(infoRec->PixmapCacheFlags & CACHE_MONO_8x8)
+ infoRec->CanDoMono8x8 = FALSE;
+ if(infoRec->PixmapCacheFlags & CACHE_COLOR_8x8)
+ infoRec->CanDoColor8x8 = FALSE;
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+
+static Bool
+XAASaveRestoreImage (int index, SaveRestoreFlags what)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAScreenPtr pScreenPriv =
+ (XAAScreenPtr) pScreen->devPrivates[XAAScreenIndex].ptr;
+ Bool ret;
+
+ if(what == SaveImage) {
+ if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps))
+ XAAMoveOutOffscreenPixmaps(pScreen);
+ if(infoRec->Flags & PIXMAP_CACHE)
+ XAAInvalidatePixmapCache(pScreen);
+ }
+
+ ret = (*pScreenPriv->SaveRestoreImage)(index, what);
+
+ if(what == RestoreImage) {
+ if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps))
+ XAAMoveInOffscreenPixmaps(pScreen);
+ }
+
+ return ret;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaInitAccel.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaInitAccel.c
new file mode 100644
index 000000000..ecbc7106d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaInitAccel.c
@@ -0,0 +1,1356 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaInitAccel.c,v 1.19 1999/07/10 12:17:42 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xf86fbman.h"
+#include "servermd.h"
+
+/*
+ * XAA Config options
+ */
+
+typedef enum {
+ XAAOPT_SCREEN_TO_SCREEN_COPY,
+ XAAOPT_SOLID_FILL_RECT,
+ XAAOPT_SOLID_FILL_TRAP,
+ XAAOPT_SOLID_TWO_POINT_LINE,
+ XAAOPT_SOLID_BRESENHAM_LINE,
+ XAAOPT_SOLID_HORVERT_LINE,
+ XAAOPT_DASHED_TWO_POINT_LINE,
+ XAAOPT_DASHED_BRESENHAM_LINE,
+ XAAOPT_MONO_8x8_PATTERN_FILL_RECT,
+ XAAOPT_MONO_8x8_PATTERN_FILL_TRAP,
+ XAAOPT_COL_8x8_PATTERN_FILL_RECT,
+ XAAOPT_COL_8x8_PATTERN_FILL_TRAP,
+ XAAOPT_CPU_TO_SCREEN_COL_EXP_FILL,
+ XAAOPT_SCANLINE_CPU_TO_SCREEN_COL_EXP_FILL,
+ XAAOPT_SCREEN_TO_SCREEN_COL_EXP_FILL,
+ XAAOPT_IMAGE_WRITE_RECT,
+ XAAOPT_SCANLINE_IMAGE_WRITE_RECT,
+ XAAOPT_IMAGE_READ_RECT,
+ XAAOPT_PIXMAP_CACHE,
+ XAAOPT_OFFSCREEN_PIXMAPS
+} XAAOpts;
+
+static OptionInfoRec XAAOptions[] = {
+ {XAAOPT_SCREEN_TO_SCREEN_COPY, "XaaNoScreenToScreenCopy",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SOLID_FILL_RECT, "XaaNoSolidFillRect",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SOLID_FILL_TRAP, "XaaNoSolidFillTrap",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SOLID_TWO_POINT_LINE, "XaaNoSolidTwoPointLine",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SOLID_BRESENHAM_LINE, "XaaNoSolidBresenhamLine",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SOLID_HORVERT_LINE, "XaaNoSolidHorVertLine",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_DASHED_TWO_POINT_LINE, "XaaNoDashedTwoPointLine",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_DASHED_BRESENHAM_LINE, "XaaNoDashedBresenhamLine",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_MONO_8x8_PATTERN_FILL_RECT, "XaaNoMono8x8PatternFillRect",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_MONO_8x8_PATTERN_FILL_TRAP, "XaaNoMono8x8PatternFillTrap",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_COL_8x8_PATTERN_FILL_RECT, "XaaNoColor8x8PatternFillRect",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_COL_8x8_PATTERN_FILL_TRAP, "XaaNoColor8x8PatternFillTrap",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_CPU_TO_SCREEN_COL_EXP_FILL, "XaaNoCPUToScreenColorExpandFill",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SCANLINE_CPU_TO_SCREEN_COL_EXP_FILL,"XaaNoScanlineCPUToScreenColorExpandFill",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SCREEN_TO_SCREEN_COL_EXP_FILL, "XaaNoScreenToScreenColorExpandFill",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_IMAGE_WRITE_RECT, "XaaNoImageWriteRect",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SCANLINE_IMAGE_WRITE_RECT, "XaaNoScanlineImageWriteRect",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_IMAGE_READ_RECT, "XaaNoImageReadRect",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_PIXMAP_CACHE, "XaaNoPixmapCache",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_OFFSCREEN_PIXMAPS, "XaaNoOffscreenPixmaps",
+ OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL,
+ OPTV_NONE, {0}, FALSE }
+};
+
+Bool
+XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec)
+{
+ int index = pScreen->myNum;
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ Bool HaveScreenToScreenCopy = FALSE;
+ Bool HaveColorExpansion = FALSE;
+ Bool HaveScanlineColorExpansion = FALSE;
+ Bool HaveSolidFillRect = FALSE;
+ Bool HaveMono8x8PatternFillRect = FALSE;
+ Bool HaveColor8x8PatternFillRect = FALSE;
+ Bool HaveSolidFillTrap = FALSE;
+ Bool HaveMono8x8PatternFillTrap = FALSE;
+ Bool HaveColor8x8PatternFillTrap = FALSE;
+ Bool HaveSolidTwoPointLine = FALSE;
+ Bool HaveSolidBresenhamLine = FALSE;
+ Bool HaveSolidHorVertLine = FALSE;
+ Bool HaveDashedTwoPointLine = FALSE;
+ Bool HaveDashedBresenhamLine = FALSE;
+ Bool HaveImageWriteRect = FALSE;
+ Bool HaveScanlineImageWriteRect = FALSE;
+ Bool HaveScreenToScreenColorExpandFill = FALSE;
+ Bool HaveImageReadRect = FALSE;
+
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, XAAOptions);
+
+ infoRec->pScrn = pScrn;
+ infoRec->NeedToSync = FALSE;
+
+ /* must have a Sync function */
+ if(!infoRec->Sync) return FALSE;
+
+ if(!infoRec->FullPlanemask)
+ infoRec->FullPlanemask = (1 << pScrn->depth) - 1;
+
+ if (serverGeneration == 1)
+ xf86DrvMsg(index, X_INFO,
+ "Using XFree86 Acceleration Architecture (XAA)\n");
+
+
+ /************** Low Level *************/
+
+ if(!infoRec->SetClippingRectangle || !infoRec->DisableClipping)
+ infoRec->ClippingFlags = 0;
+
+ /**** CopyArea ****/
+
+ if(infoRec->SetupForScreenToScreenCopy &&
+ infoRec->SubsequentScreenToScreenCopy &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_SCREEN_TO_SCREEN_COPY))
+ HaveScreenToScreenCopy = TRUE;
+
+ /**** Solid Filled Rects ****/
+
+ if(infoRec->SetupForSolidFill && infoRec->SubsequentSolidFillRect &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_SOLID_FILL_RECT)) {
+ HaveSolidFillRect = TRUE;
+ if(infoRec->SubsequentSolidFillTrap &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_SOLID_FILL_TRAP))
+ HaveSolidFillTrap = TRUE;
+ }
+
+ /**** Solid lines ****/
+ if(infoRec->SetupForSolidLine) {
+ if(infoRec->SubsequentSolidTwoPointLine &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_SOLID_TWO_POINT_LINE))
+ HaveSolidTwoPointLine = TRUE;
+ if(infoRec->SubsequentSolidBresenhamLine &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_SOLID_BRESENHAM_LINE)) {
+ HaveSolidBresenhamLine = TRUE;
+
+ if(infoRec->SolidBresenhamLineErrorTermBits)
+ infoRec->SolidBresenhamLineErrorTermBits =
+ ~((1 << infoRec->SolidBresenhamLineErrorTermBits) - 1);
+ }
+
+ if(infoRec->SubsequentSolidHorVertLine &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_SOLID_HORVERT_LINE))
+ HaveSolidHorVertLine = TRUE;
+ else if(HaveSolidTwoPointLine) {
+ infoRec->SubsequentSolidHorVertLine =
+ XAASolidHorVertLineAsTwoPoint;
+ HaveSolidHorVertLine = TRUE;
+ } else if(HaveSolidBresenhamLine) {
+ infoRec->SubsequentSolidHorVertLine =
+ XAASolidHorVertLineAsBresenham;
+ HaveSolidHorVertLine = TRUE;
+ }
+ } else if(HaveSolidFillRect) {
+ infoRec->SetupForSolidLine = infoRec->SetupForSolidFill;
+ infoRec->SubsequentSolidHorVertLine = XAASolidHorVertLineAsRects;
+ infoRec->SolidLineFlags = infoRec->SolidFillFlags;
+ HaveSolidHorVertLine = TRUE;
+ }
+
+
+
+
+ /**** 8x8 Mono Pattern Filled Rects ****/
+
+ if(infoRec->SetupForMono8x8PatternFill &&
+ infoRec->SubsequentMono8x8PatternFillRect &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_MONO_8x8_PATTERN_FILL_RECT)) {
+ HaveMono8x8PatternFillRect = TRUE;
+ if(infoRec->SubsequentMono8x8PatternFillTrap &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_MONO_8x8_PATTERN_FILL_TRAP))
+ HaveMono8x8PatternFillTrap = TRUE;
+
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ infoRec->CanDoMono8x8 = TRUE;
+ } else { /* others require caching */
+ int min_pitch;
+ infoRec->PixmapCacheFlags |= CACHE_MONO_8x8;
+
+ switch(pScrn->bitsPerPixel) {
+ case 32: min_pitch = 2; break;
+ case 24: min_pitch = 3; break;
+ case 16: min_pitch = 4; break;
+ default: min_pitch = 8; break;
+ }
+
+ if(min_pitch > infoRec->MonoPatternPitch)
+ infoRec->MonoPatternPitch = min_pitch;
+
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
+ if(!infoRec->CacheWidthMono8x8Pattern ||
+ !infoRec->CacheHeightMono8x8Pattern) {
+ infoRec->CacheWidthMono8x8Pattern =
+ infoRec->MonoPatternPitch;
+ infoRec->CacheHeightMono8x8Pattern = 1;
+ }
+ } else {
+ int numPerLine = 128/infoRec->MonoPatternPitch;
+
+ if(!infoRec->CacheWidthMono8x8Pattern ||
+ !infoRec->CacheHeightMono8x8Pattern) {
+ infoRec->CacheWidthMono8x8Pattern =
+ numPerLine * infoRec->MonoPatternPitch;
+ infoRec->CacheHeightMono8x8Pattern =
+ (64 + numPerLine - 1)/numPerLine;
+ }
+ }
+ }
+ }
+
+
+ /**** Dashed lines ****/
+
+ if(infoRec->SetupForDashedLine && infoRec->DashPatternMaxLength) {
+ if(infoRec->SubsequentDashedTwoPointLine &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_DASHED_TWO_POINT_LINE))
+ HaveDashedTwoPointLine = TRUE;
+ if(infoRec->SubsequentDashedBresenhamLine &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_DASHED_BRESENHAM_LINE)) {
+ HaveDashedBresenhamLine = TRUE;
+
+ if(infoRec->DashedBresenhamLineErrorTermBits)
+ infoRec->DashedBresenhamLineErrorTermBits =
+ ~((1 << infoRec->DashedBresenhamLineErrorTermBits) - 1);
+ }
+ }
+
+ /**** 8x8 Color Pattern Filled Rects ****/
+
+ if(infoRec->SetupForColor8x8PatternFill &&
+ infoRec->SubsequentColor8x8PatternFillRect &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_COL_8x8_PATTERN_FILL_RECT)) {
+ HaveColor8x8PatternFillRect = TRUE;
+ if(infoRec->SubsequentColor8x8PatternFillTrap &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_COL_8x8_PATTERN_FILL_TRAP))
+ HaveColor8x8PatternFillTrap = TRUE;
+
+ infoRec->PixmapCacheFlags |= CACHE_COLOR_8x8;
+
+ if(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
+ if(!infoRec->CacheWidthColor8x8Pattern ||
+ !infoRec->CacheHeightColor8x8Pattern) {
+ infoRec->CacheWidthColor8x8Pattern = 64;
+ infoRec->CacheHeightColor8x8Pattern = 1;
+ }
+ } else {
+ if(!infoRec->CacheWidthColor8x8Pattern ||
+ !infoRec->CacheHeightColor8x8Pattern) {
+ infoRec->CacheWidthColor8x8Pattern = 128;
+ infoRec->CacheHeightColor8x8Pattern = 8;
+ }
+ }
+ }
+
+ /**** Color Expansion ****/
+
+
+ if(infoRec->SetupForCPUToScreenColorExpandFill &&
+ infoRec->ColorExpandBase &&
+ infoRec->SubsequentCPUToScreenColorExpandFill &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_CPU_TO_SCREEN_COL_EXP_FILL)) {
+ int dwordsNeeded = pScrn->virtualX;
+
+ infoRec->ColorExpandRange >>= 2; /* convert to DWORDS */
+ HaveColorExpansion = TRUE;
+
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ LEFT_EDGE_CLIPPING_NEGATIVE_X)
+ dwordsNeeded += 31;
+ dwordsNeeded = (dwordsNeeded + 31) >> 5;
+ if(dwordsNeeded > infoRec->ColorExpandRange)
+ infoRec->CPUToScreenColorExpandFillFlags |= CPU_TRANSFER_BASE_FIXED;
+ }
+
+ /**** Scanline Color Expansion ****/
+
+ if(infoRec->SetupForScanlineCPUToScreenColorExpandFill &&
+ infoRec->SubsequentScanlineCPUToScreenColorExpandFill &&
+ infoRec->SubsequentColorExpandScanline &&
+ infoRec->ScanlineColorExpandBuffers &&
+ (infoRec->NumScanlineColorExpandBuffers > 0) &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_SCANLINE_CPU_TO_SCREEN_COL_EXP_FILL))
+ HaveScanlineColorExpansion = TRUE;
+
+
+ /**** Screen to Screen Color Expansion ****/
+
+ if(infoRec->SetupForScreenToScreenColorExpandFill &&
+ infoRec->SubsequentScreenToScreenColorExpandFill &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_SCREEN_TO_SCREEN_COL_EXP_FILL)) {
+ HaveScreenToScreenColorExpandFill = TRUE;
+ if (!infoRec->CacheColorExpandDensity)
+ infoRec->CacheColorExpandDensity = 1;
+ }
+
+ /**** Image Writes ****/
+
+ if(infoRec->SetupForImageWrite && infoRec->ImageWriteBase &&
+ infoRec->SubsequentImageWriteRect &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_IMAGE_WRITE_RECT)) {
+
+ infoRec->ImageWriteRange >>= 2; /* convert to DWORDS */
+ if(infoRec->ImageWriteFlags & CPU_TRANSFER_BASE_FIXED)
+ infoRec->ImageWriteRange = 0;
+ HaveImageWriteRect = TRUE;
+ }
+
+ /**** Scanline Image Writes ****/
+
+ if(infoRec->SetupForScanlineImageWrite &&
+ infoRec->SubsequentScanlineImageWriteRect &&
+ infoRec->SubsequentImageWriteScanline &&
+ infoRec->ScanlineImageWriteBuffers &&
+ (infoRec->NumScanlineImageWriteBuffers > 0) &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_SCANLINE_IMAGE_WRITE_RECT))
+ HaveScanlineImageWriteRect = TRUE;
+
+ /**** Image Reads ****/
+
+ if(infoRec->SetupForImageRead && infoRec->ImageReadBase &&
+ infoRec->SubsequentImageReadRect &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_IMAGE_READ_RECT)) {
+
+ infoRec->ImageReadRange >>= 2; /* convert to DWORDS */
+ if(infoRec->ImageReadFlags & CPU_TRANSFER_BASE_FIXED)
+ infoRec->ImageReadRange = 0;
+ HaveImageReadRect = TRUE;
+ }
+
+ if (serverGeneration == 1) {
+ if(HaveScreenToScreenCopy)
+ xf86ErrorF("\tScreen to screen bit blits\n");
+ if(HaveSolidFillRect)
+ xf86ErrorF("\tSolid filled rectangles\n");
+ if(HaveSolidFillTrap)
+ xf86ErrorF("\tSolid filled trapezoids\n");
+ if(HaveMono8x8PatternFillRect)
+ xf86ErrorF("\t8x8 mono pattern filled rectangles\n");
+ if(HaveMono8x8PatternFillTrap)
+ xf86ErrorF("\t8x8 mono pattern filled trapezoids\n");
+ if(HaveColor8x8PatternFillRect)
+ xf86ErrorF("\t8x8 color pattern filled rectangles\n");
+ if(HaveColor8x8PatternFillTrap)
+ xf86ErrorF("\t8x8 color pattern filled trapezoids\n");
+
+ if(HaveColorExpansion)
+ xf86ErrorF("\tCPU to Screen color expansion\n");
+ else if(HaveScanlineColorExpansion)
+ xf86ErrorF("\tIndirect CPU to Screen color expansion\n");
+
+ if(HaveScreenToScreenColorExpandFill)
+ xf86ErrorF("\tScreen to Screen color expansion\n");
+
+ if(HaveSolidTwoPointLine || HaveSolidBresenhamLine)
+ xf86ErrorF("\tSolid Lines\n");
+ else if(HaveSolidHorVertLine)
+ xf86ErrorF("\tSolid Horizontal and Vertical Lines\n");
+
+ if(HaveDashedTwoPointLine || HaveDashedBresenhamLine)
+ xf86ErrorF("\tDashed Lines\n");
+
+ if(HaveImageWriteRect)
+ xf86ErrorF("\tImage Writes\n");
+ else if(HaveScanlineImageWriteRect)
+ xf86ErrorF("\tScanline Image Writes\n");
+
+ if(HaveImageReadRect)
+ xf86ErrorF("\tImage Reads\n");
+ }
+
+#define XAAMSG(s) do { if (serverGeneration == 1) xf86ErrorF(s); } while (0)
+
+ if((infoRec->Flags & OFFSCREEN_PIXMAPS) && HaveScreenToScreenCopy &&
+ !xf86IsOptionSet(XAAOptions, XAAOPT_OFFSCREEN_PIXMAPS)) {
+ XAAMSG("\tOffscreen Pixmaps\n");
+ } else {
+ infoRec->Flags &= ~OFFSCREEN_PIXMAPS;
+ }
+
+
+ /************** Mid Level *************/
+
+ /**** ScreenToScreenBitBlt ****/
+
+ if(infoRec->ScreenToScreenBitBlt) {
+ XAAMSG("\tDriver provided ScreenToScreenBitBlt replacement\n");
+ } else if(HaveScreenToScreenCopy) {
+ infoRec->ScreenToScreenBitBlt = XAAScreenToScreenBitBlt;
+ infoRec->ScreenToScreenBitBltFlags = infoRec->ScreenToScreenCopyFlags;
+ }
+
+ /**** FillSolidRects ****/
+
+ if(infoRec->FillSolidRects) {
+ XAAMSG("\tDriver provided FillSolidRects replacement\n");
+ } else if(HaveSolidFillRect) {
+ infoRec->FillSolidRects = XAAFillSolidRects;
+ infoRec->FillSolidRectsFlags = infoRec->SolidFillFlags;
+ }
+
+
+ /**** FillSolidSpans ****/
+
+ if(infoRec->FillSolidSpans) {
+ XAAMSG("\tDriver provided FillSolidSpans replacement\n");
+ } else if(HaveSolidFillRect) {
+ infoRec->FillSolidSpans = XAAFillSolidSpans;
+ infoRec->FillSolidSpansFlags = infoRec->SolidFillFlags;
+ }
+
+
+ /**** FillMono8x8PatternRects ****/
+
+ if(infoRec->FillMono8x8PatternRects) {
+ XAAMSG("\tDriver provided FillMono8x8PatternRects replacement\n");
+ } else if(HaveMono8x8PatternFillRect) {
+ infoRec->FillMono8x8PatternRects =
+ (infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_SCREEN_ORIGIN) ?
+ XAAFillMono8x8PatternRectsScreenOrigin :
+ XAAFillMono8x8PatternRects;
+
+ infoRec->FillMono8x8PatternRectsFlags =
+ infoRec->Mono8x8PatternFillFlags;
+ }
+
+ /**** FillMono8x8PatternSpans ****/
+
+ if(infoRec->FillMono8x8PatternSpans) {
+ XAAMSG("\tDriver provided FillMono8x8PatternSpans replacement\n");
+ } else if(HaveMono8x8PatternFillRect) {
+ infoRec->FillMono8x8PatternSpans =
+ (infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_SCREEN_ORIGIN) ?
+ XAAFillMono8x8PatternSpansScreenOrigin:
+ XAAFillMono8x8PatternSpans;
+
+ infoRec->FillMono8x8PatternSpansFlags =
+ infoRec->Mono8x8PatternFillFlags;
+ }
+
+ /**** FillColor8x8Rects ****/
+
+ if(infoRec->FillColor8x8PatternRects) {
+ XAAMSG("\tDriver provided FillColor8x8PatternRects replacement\n");
+ } else if(HaveColor8x8PatternFillRect) {
+ infoRec->FillColor8x8PatternRects =
+ (infoRec->Color8x8PatternFillFlags & HARDWARE_PATTERN_SCREEN_ORIGIN) ?
+ XAAFillColor8x8PatternRectsScreenOrigin :
+ XAAFillColor8x8PatternRects;
+
+ infoRec->FillColor8x8PatternRectsFlags =
+ infoRec->Color8x8PatternFillFlags;
+ }
+
+ /**** FillColor8x8Spans ****/
+
+ if(infoRec->FillColor8x8PatternSpans) {
+ XAAMSG("\tDriver provided FillColor8x8PatternSpans replacement\n");
+ } else if(HaveColor8x8PatternFillRect) {
+ infoRec->FillColor8x8PatternSpans =
+ (infoRec->Color8x8PatternFillFlags & HARDWARE_PATTERN_SCREEN_ORIGIN) ?
+ XAAFillColor8x8PatternSpansScreenOrigin:
+ XAAFillColor8x8PatternSpans;
+
+ infoRec->FillColor8x8PatternSpansFlags =
+ infoRec->Color8x8PatternFillFlags;
+ }
+
+
+ /**** FillCacheBltRects ****/
+
+ if(infoRec->FillCacheBltRects) {
+ XAAMSG("\tDriver provided FillCacheBltRects replacement\n");
+ } else if(HaveScreenToScreenCopy) {
+ infoRec->FillCacheBltRects = XAAFillCacheBltRects;
+ infoRec->FillCacheBltRectsFlags = infoRec->ScreenToScreenCopyFlags;
+ }
+
+ /**** FillCacheBltSpans ****/
+
+ if(infoRec->FillCacheBltSpans) {
+ XAAMSG("\tDriver provided FillCacheBltSpans replacement\n");
+ } else if(HaveScreenToScreenCopy) {
+ infoRec->FillCacheBltSpans = XAAFillCacheBltSpans;
+ infoRec->FillCacheBltSpansFlags = infoRec->ScreenToScreenCopyFlags;
+ }
+
+
+ /**** FillCacheExpandRects ****/
+
+ if(infoRec->FillCacheExpandRects) {
+ XAAMSG("\tDriver provided FillCacheExpandRects replacement\n");
+ } else if(HaveScreenToScreenColorExpandFill) {
+ infoRec->FillCacheExpandRects = XAAFillCacheExpandRects;
+ infoRec->FillCacheExpandRectsFlags =
+ infoRec->ScreenToScreenColorExpandFillFlags;
+ }
+
+ /**** FillCacheExpandSpans ****/
+
+ if(infoRec->FillCacheExpandSpans) {
+ XAAMSG("\tDriver provided FillCacheExpandSpans replacement\n");
+ } else if(HaveScreenToScreenColorExpandFill) {
+ infoRec->FillCacheExpandSpans = XAAFillCacheExpandSpans;
+ infoRec->FillCacheExpandSpansFlags =
+ infoRec->ScreenToScreenColorExpandFillFlags;
+ }
+
+
+ /**** FillColorExpandRects ****/
+
+ if(infoRec->FillColorExpandRects) {
+ XAAMSG("\tDriver provided FillColorExpandRects replacement\n");
+ } else if(HaveColorExpansion) {
+#if 0
+ if (infoRec->CPUToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRects3MSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRects3MSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRects3LSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRects3LSBFirst;
+ }
+ } else
+#endif
+ {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRectsMSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRectsMSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRectsLSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRectsLSBFirst;
+ }
+ }
+ infoRec->FillColorExpandRectsFlags =
+ infoRec->CPUToScreenColorExpandFillFlags & ~TRANSPARENCY_ONLY;
+ } else if(HaveScanlineColorExpansion) {
+#if 0
+ if (infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ TRIPLE_BITS_24BPP) {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRects3MSBFirst;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRects3LSBFirst;
+ } else
+#endif
+ {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->FillColorExpandRects =
+ XAAFillScanlineColorExpandRectsMSBFirst;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillScanlineColorExpandRectsLSBFirst;
+ }
+ infoRec->FillColorExpandRectsFlags = ~TRANSPARENCY_ONLY &
+ infoRec->ScanlineCPUToScreenColorExpandFillFlags;
+ }
+
+ /**** FillColorExpandSpans ****/
+
+ if(infoRec->FillColorExpandSpans) {
+ XAAMSG("\tDriver provided FillColorExpandSpans replacement\n");
+ } else if(HaveColorExpansion) {
+#if 0
+ if (infoRec->CPUToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpans3MSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpans3MSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpans3LSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpans3LSBFirst;
+ }
+ } else
+#endif
+ {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpansMSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpansMSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpansLSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpansLSBFirst;
+ }
+ }
+ infoRec->FillColorExpandSpansFlags =
+ infoRec->CPUToScreenColorExpandFillFlags & ~TRANSPARENCY_ONLY;
+ } else if(HaveScanlineColorExpansion) {
+#if 0
+ if (infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ TRIPLE_BITS_24BPP) {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpans3MSBFirst;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpans3LSBFirst;
+ } else
+#endif
+ {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->FillColorExpandSpans =
+ XAAFillScanlineColorExpandSpansMSBFirst;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillScanlineColorExpandSpansLSBFirst;
+ }
+ infoRec->FillColorExpandSpansFlags = ~TRANSPARENCY_ONLY &
+ infoRec->ScanlineCPUToScreenColorExpandFillFlags;
+ }
+
+
+ /**** FillImageWriteRects ****/
+
+ if(infoRec->FillImageWriteRects) {
+ XAAMSG("\tDriver provided FillImageWriteRects replacement\n");
+ } else if(HaveImageWriteRect &&
+ (infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING_NEGATIVE_X) &&
+ (infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING)) {
+ infoRec->FillImageWriteRects = XAAFillImageWriteRects;
+ infoRec->FillImageWriteRectsFlags = infoRec->ImageWriteFlags;
+ }
+
+ /**** WriteBitmap ****/
+
+ if(infoRec->WriteBitmap) {
+ XAAMSG("\tDriver provided WriteBitmap replacement\n");
+ } else if(HaveColorExpansion) {
+ if (infoRec->CPUToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapColorExpand3MSBFirstFixedBase;
+ else
+ infoRec->WriteBitmap = XAAWriteBitmapColorExpand3MSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapColorExpand3LSBFirstFixedBase;
+ else
+ infoRec->WriteBitmap = XAAWriteBitmapColorExpand3LSBFirst;
+ }
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapColorExpandMSBFirstFixedBase;
+ else
+ infoRec->WriteBitmap = XAAWriteBitmapColorExpandMSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapColorExpandLSBFirstFixedBase;
+ else
+ infoRec->WriteBitmap = XAAWriteBitmapColorExpandLSBFirst;
+ }
+ }
+ infoRec->WriteBitmapFlags =
+ infoRec->CPUToScreenColorExpandFillFlags & ~TRANSPARENCY_ONLY;
+ } else if(HaveScanlineColorExpansion) {
+ if (infoRec->CPUToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP) {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapScanlineColorExpand3MSBFirst;
+ else
+ infoRec->WriteBitmap =
+ XAAWriteBitmapScanlineColorExpand3LSBFirst;
+ } else {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapScanlineColorExpandMSBFirst;
+ else
+ infoRec->WriteBitmap =
+ XAAWriteBitmapScanlineColorExpandLSBFirst;
+ }
+ infoRec->WriteBitmapFlags = ~TRANSPARENCY_ONLY &
+ infoRec->ScanlineCPUToScreenColorExpandFillFlags;
+ }
+
+
+
+ /**** TE Glyphs ****/
+
+ if(infoRec->TEGlyphRenderer) {
+ XAAMSG("\tDriver provided TEGlyphRenderer replacement\n");
+ } else if(HaveColorExpansion) {
+ if (infoRec->CPUToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->TEGlyphRenderer =
+ XAATEGlyphRenderer3MSBFirstFixedBase;
+ else
+ infoRec->TEGlyphRenderer = XAATEGlyphRenderer3MSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->TEGlyphRenderer =
+ XAATEGlyphRenderer3LSBFirstFixedBase;
+ else
+ infoRec->TEGlyphRenderer = XAATEGlyphRenderer3LSBFirst;
+ }
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->TEGlyphRenderer =
+ XAATEGlyphRendererMSBFirstFixedBase;
+ else
+ infoRec->TEGlyphRenderer = XAATEGlyphRendererMSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->TEGlyphRenderer =
+ XAATEGlyphRendererLSBFirstFixedBase;
+ else
+ infoRec->TEGlyphRenderer = XAATEGlyphRendererLSBFirst;
+ }
+ }
+ infoRec->TEGlyphRendererFlags =
+ infoRec->CPUToScreenColorExpandFillFlags;
+
+ if(HaveSolidFillRect)
+ infoRec->TEGlyphRendererFlags &= ~TRANSPARENCY_ONLY;
+
+ } else if(HaveScanlineColorExpansion) {
+ if (infoRec->CPUToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP) {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->TEGlyphRenderer =
+ XAATEGlyphRendererScanline3MSBFirst;
+ else
+ infoRec->TEGlyphRenderer =
+ XAATEGlyphRendererScanline3LSBFirst;
+ } else {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->TEGlyphRenderer =
+ XAATEGlyphRendererScanlineMSBFirst;
+ else
+ infoRec->TEGlyphRenderer =
+ XAATEGlyphRendererScanlineLSBFirst;
+ }
+
+ infoRec->TEGlyphRendererFlags =
+ infoRec->ScanlineCPUToScreenColorExpandFillFlags;
+
+ if(HaveSolidFillRect)
+ infoRec->TEGlyphRendererFlags &= ~TRANSPARENCY_ONLY;
+ }
+
+
+ /**** NonTE Glyphs ****/
+
+ if(infoRec->NonTEGlyphRenderer) {
+ XAAMSG("\tDriver provided NonTEGlyphRenderer replacement\n");
+ } else if(infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY)) {
+ infoRec->NonTEGlyphRenderer = XAANonTEGlyphRenderer;
+ infoRec->NonTEGlyphRendererFlags = infoRec->WriteBitmapFlags;
+ }
+
+
+ /**** WritePixmap ****/
+
+ if(infoRec->WritePixmap) {
+ XAAMSG("\tDriver provided WritePixmap replacement\n");
+ } else if(HaveImageWriteRect) {
+ infoRec->WritePixmap = XAAWritePixmap;
+ infoRec->WritePixmapFlags =
+ infoRec->ImageWriteFlags | CONVERT_32BPP_TO_24BPP;
+ } else if(HaveScanlineImageWriteRect) {
+ infoRec->WritePixmap = XAAWritePixmapScanline;
+ infoRec->WritePixmapFlags = infoRec->ScanlineImageWriteFlags;
+ }
+
+
+ /**** ReadPixmap ****/
+
+ if(infoRec->ReadPixmap) {
+ XAAMSG("\tDriver provided ReadPixmap replacement\n");
+ } else if(HaveImageReadRect) {
+ infoRec->ReadPixmap = XAAReadPixmap;
+ infoRec->ReadPixmapFlags = infoRec->ImageReadFlags;
+ }
+
+ /************** GC Level *************/
+
+ /**** CopyArea ****/
+
+ if(infoRec->CopyArea) {
+ XAAMSG("\tDriver provided GC level CopyArea replacement\n");
+ } else if(infoRec->ScreenToScreenBitBlt) {
+ infoRec->CopyArea = XAACopyArea;
+ infoRec->CopyAreaFlags = infoRec->ScreenToScreenBitBltFlags;
+
+ /* most GC level primitives use one mid-level primitive so
+ the GC level primitive gets the mid-level primitive flag
+ and we use that at GC validation time. But CopyArea uses
+ more than one mid-level primitive so we have to essentially
+ do a GC validation every time that primitive is used.
+ The CopyAreaFlags would only be used for filtering out the
+ common denominators. Here we assume that if you don't do
+ ScreenToScreenBitBlt you aren't going to do the others.
+ We also assume that ScreenToScreenBitBlt has the least
+ restrictions. */
+ }
+
+ if(infoRec->CopyPlane) {
+ XAAMSG("\tDriver provided GC level CopyPlane replacement\n");
+ } else if(infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY)) {
+ infoRec->CopyPlane = XAACopyPlaneColorExpansion;
+ infoRec->CopyPlaneFlags = infoRec->WriteBitmapFlags;
+ }
+
+ if(infoRec->PushPixelsSolid) {
+ XAAMSG("\tDriver provided GC level PushPixelsSolid replacement\n");
+ } else if(infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY)) {
+ infoRec->PushPixelsSolid = XAAPushPixelsSolidColorExpansion;
+ infoRec->PushPixelsFlags = infoRec->WriteBitmapFlags;
+ }
+
+ if(infoRec->FillSolidRects) {
+ if(!infoRec->PolyFillRectSolid) {
+ infoRec->PolyFillRectSolid = XAAPolyFillRect;
+ infoRec->PolyFillRectSolidFlags = infoRec->FillSolidRectsFlags;
+ }
+ }
+ if(infoRec->FillSolidSpans) {
+ if(!infoRec->FillSpansSolid) {
+ infoRec->FillSpansSolid = XAAFillSpans;
+ infoRec->FillSpansSolidFlags = infoRec->FillSolidSpansFlags;
+ }
+ }
+
+
+ if(infoRec->FillMono8x8PatternRects || infoRec->FillColor8x8PatternRects ||
+ infoRec->FillCacheBltRects || infoRec->FillColorExpandRects ||
+ infoRec->FillCacheExpandRects) {
+ if(!infoRec->PolyFillRectStippled) {
+
+ infoRec->PolyFillRectStippled = XAAPolyFillRect;
+ infoRec->PolyFillRectStippledFlags = 0;
+ }
+ }
+ if(infoRec->FillMono8x8PatternSpans || infoRec->FillColor8x8PatternSpans ||
+ infoRec->FillCacheBltSpans || infoRec->FillColorExpandSpans ||
+ infoRec->FillCacheExpandSpans) {
+ if(!infoRec->FillSpansStippled) {
+
+ infoRec->FillSpansStippled = XAAFillSpans;
+ infoRec->FillSpansStippledFlags = 0;
+ }
+ }
+
+ if(infoRec->FillMono8x8PatternRects || infoRec->FillColor8x8PatternRects ||
+ infoRec->FillCacheBltRects || infoRec->FillColorExpandRects ||
+ infoRec->FillCacheExpandRects) {
+ if(!infoRec->PolyFillRectOpaqueStippled) {
+
+ infoRec->PolyFillRectOpaqueStippled = XAAPolyFillRect;
+ infoRec->PolyFillRectOpaqueStippledFlags = 0;
+ }
+ }
+ if(infoRec->FillMono8x8PatternSpans || infoRec->FillColor8x8PatternSpans ||
+ infoRec->FillCacheBltSpans || infoRec->FillColorExpandSpans ||
+ infoRec->FillCacheExpandSpans) {
+ if(!infoRec->FillSpansOpaqueStippled) {
+
+ infoRec->FillSpansOpaqueStippled = XAAFillSpans;
+ infoRec->FillSpansOpaqueStippledFlags = 0;
+ }
+ }
+
+
+ if(infoRec->FillMono8x8PatternRects || infoRec->FillColor8x8PatternRects ||
+ infoRec->FillCacheBltRects || infoRec->FillImageWriteRects) {
+ if(!infoRec->PolyFillRectTiled) {
+
+ infoRec->PolyFillRectTiled = XAAPolyFillRect;
+ infoRec->PolyFillRectTiledFlags = 0;
+ }
+ }
+ if(infoRec->FillMono8x8PatternSpans || infoRec->FillColor8x8PatternSpans ||
+ infoRec->FillCacheBltSpans) {
+ if(!infoRec->FillSpansTiled) {
+
+ infoRec->FillSpansTiled = XAAFillSpans;
+ infoRec->FillSpansTiledFlags = 0;
+ }
+ }
+
+
+ if(infoRec->TEGlyphRenderer &&
+ !(infoRec->TEGlyphRendererFlags & NO_TRANSPARENCY)) {
+
+ if(!infoRec->PolyText8TE) {
+ infoRec->PolyText8TE = XAAPolyText8TEColorExpansion;
+ infoRec->PolyText8TEFlags = infoRec->TEGlyphRendererFlags;
+ }
+
+ if(!infoRec->PolyText16TE) {
+ infoRec->PolyText16TE = XAAPolyText16TEColorExpansion;
+ infoRec->PolyText16TEFlags = infoRec->TEGlyphRendererFlags;
+ }
+
+ if(!infoRec->PolyGlyphBltTE) {
+ infoRec->PolyGlyphBltTE = XAAPolyGlyphBltTEColorExpansion;
+ infoRec->PolyGlyphBltTEFlags = infoRec->TEGlyphRendererFlags;
+ }
+ }
+
+ if(infoRec->TEGlyphRenderer &&
+ !(infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY)) {
+
+ if(!infoRec->ImageText8TE) {
+ infoRec->ImageText8TE = XAAImageText8TEColorExpansion;
+ infoRec->ImageText8TEFlags = infoRec->TEGlyphRendererFlags;
+ }
+
+ if(!infoRec->ImageText16TE) {
+ infoRec->ImageText16TE = XAAImageText16TEColorExpansion;
+ infoRec->ImageText16TEFlags = infoRec->TEGlyphRendererFlags;
+ }
+
+ if(!infoRec->ImageGlyphBltTE) {
+ infoRec->ImageGlyphBltTE = XAAImageGlyphBltTEColorExpansion;
+ infoRec->ImageGlyphBltTEFlags = infoRec->TEGlyphRendererFlags;
+ }
+ }
+
+ if(infoRec->NonTEGlyphRenderer) {
+ if(!infoRec->PolyText8NonTE) {
+ infoRec->PolyText8NonTE = XAAPolyText8NonTEColorExpansion;
+ infoRec->PolyText8NonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+
+ if(!infoRec->PolyText16NonTE) {
+ infoRec->PolyText16NonTE = XAAPolyText16NonTEColorExpansion;
+ infoRec->PolyText16NonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+ if(!infoRec->PolyGlyphBltNonTE) {
+ infoRec->PolyGlyphBltNonTE = XAAPolyGlyphBltNonTEColorExpansion;
+ infoRec->PolyGlyphBltNonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+ }
+
+
+ if(infoRec->NonTEGlyphRenderer && HaveSolidFillRect) {
+ if(!infoRec->ImageText8NonTE) {
+ infoRec->ImageText8NonTE = XAAImageText8NonTEColorExpansion;
+ infoRec->ImageText8NonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+
+ if(!infoRec->ImageText16NonTE) {
+ infoRec->ImageText16NonTE = XAAImageText16NonTEColorExpansion;
+ infoRec->ImageText16NonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+
+ if(!infoRec->ImageGlyphBltNonTE) {
+ infoRec->ImageGlyphBltNonTE = XAAImageGlyphBltNonTEColorExpansion;
+ infoRec->ImageGlyphBltNonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+ }
+
+ if(!infoRec->PolyRectangleThinSolid && HaveSolidHorVertLine) {
+ infoRec->PolyRectangleThinSolid = XAAPolyRectangleThinSolid;
+ infoRec->PolyRectangleThinSolidFlags = infoRec->SolidLineFlags;
+ }
+
+ if(!infoRec->FillPolygonSolid && HaveSolidFillRect) {
+ infoRec->FillPolygonSolid = XAAFillPolygonSolid;
+ infoRec->FillPolygonSolidFlags = infoRec->SolidFillFlags;
+ }
+
+ if(!infoRec->FillPolygonStippled && (HaveMono8x8PatternFillRect ||
+ HaveScreenToScreenColorExpandFill || HaveScreenToScreenCopy)) {
+ infoRec->FillPolygonStippled = XAAFillPolygonStippled;
+ infoRec->FillPolygonStippledFlags = infoRec->SolidFillFlags;
+ }
+
+ if(!infoRec->FillPolygonOpaqueStippled && (HaveMono8x8PatternFillRect ||
+ HaveScreenToScreenColorExpandFill || HaveScreenToScreenCopy)) {
+ infoRec->FillPolygonOpaqueStippled = XAAFillPolygonStippled;
+ infoRec->FillPolygonOpaqueStippledFlags = infoRec->SolidFillFlags;
+ }
+
+ if(!infoRec->FillPolygonTiled && (HaveMono8x8PatternFillRect ||
+ HaveScreenToScreenColorExpandFill || HaveScreenToScreenCopy)) {
+ infoRec->FillPolygonTiled = XAAFillPolygonTiled;
+ infoRec->FillPolygonTiledFlags = infoRec->SolidFillFlags;
+ }
+
+
+ if(!infoRec->PolyFillArcSolid && HaveSolidFillRect) {
+ infoRec->PolyFillArcSolid = XAAPolyFillArcSolid;
+ infoRec->PolyFillArcSolidFlags = infoRec->SolidFillFlags;
+ }
+
+ if(!infoRec->PolylinesWideSolid && HaveSolidFillRect) {
+ infoRec->PolylinesWideSolid = XAAPolylinesWideSolid;
+ infoRec->PolylinesWideSolidFlags =
+ infoRec->SolidFillFlags | GXCOPY_ONLY;
+ }
+
+ if(!infoRec->PutImage && (infoRec->WritePixmap ||
+ (infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY)))) {
+ infoRec->PutImage = XAAPutImage;
+
+ /* See comment for CopyArea above. But here we make fewer
+ assumptions. The driver can provide the PutImageFlags if
+ it wants too */
+ }
+
+ if(HaveSolidHorVertLine &&
+ (HaveSolidBresenhamLine || (HaveSolidTwoPointLine &&
+ (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_LINE)))){
+ if(!infoRec->PolylinesThinSolid) {
+ infoRec->PolylinesThinSolid = XAAPolyLines;
+ infoRec->PolylinesThinSolidFlags = infoRec->SolidLineFlags;
+ }
+ if(!infoRec->PolySegmentThinSolid) {
+ infoRec->PolySegmentThinSolid = XAAPolySegment;
+ infoRec->PolySegmentThinSolidFlags = infoRec->SolidLineFlags;
+ }
+ }
+
+ if(HaveDashedBresenhamLine || (HaveDashedTwoPointLine &&
+ (infoRec->ClippingFlags & HARDWARE_CLIP_DASHED_LINE))){
+ if(!infoRec->PolylinesThinDashed) {
+ infoRec->PolylinesThinDashed = XAAPolyLinesDashed;
+ infoRec->PolylinesThinDashedFlags = infoRec->DashedLineFlags;
+ }
+ if(!infoRec->PolySegmentThinDashed) {
+ infoRec->PolySegmentThinDashed = XAAPolySegmentDashed;
+ infoRec->PolySegmentThinDashedFlags = infoRec->DashedLineFlags;
+ }
+ }
+
+ if(infoRec->PolylinesThinDashed || infoRec->PolySegmentThinDashed) {
+ if(!infoRec->ComputeDash)
+ infoRec->ComputeDash = XAAComputeDash;
+ }
+
+ /************ Validation Functions **************/
+
+ if(!infoRec->ValidateCopyArea && infoRec->CopyArea) {
+ infoRec->CopyAreaMask = GCWhenForced;
+ if((infoRec->CopyAreaFlags & GXCOPY_ONLY) ||
+ (infoRec->CopyAreaFlags & ROP_NEEDS_SOURCE))
+ infoRec->CopyAreaMask |= GCFunction;
+ if(infoRec->CopyAreaFlags & NO_PLANEMASK)
+ infoRec->CopyAreaMask |= GCPlaneMask;
+ infoRec->ValidateCopyArea = XAAValidateCopyArea;
+ }
+
+ if(!infoRec->ValidateCopyPlane && infoRec->CopyPlane) {
+ infoRec->CopyPlaneMask = GCWhenForced;
+ if((infoRec->CopyPlaneFlags & GXCOPY_ONLY) ||
+ (infoRec->CopyPlaneFlags & ROP_NEEDS_SOURCE))
+ infoRec->CopyPlaneMask |= GCFunction;
+ if(infoRec->CopyPlaneFlags & NO_PLANEMASK)
+ infoRec->CopyPlaneMask |= GCPlaneMask;
+ if(infoRec->CopyPlaneFlags & RGB_EQUAL)
+ infoRec->CopyPlaneMask |= GCForeground | GCBackground;
+ infoRec->ValidateCopyPlane = XAAValidateCopyPlane;
+ }
+
+ if(!infoRec->ValidatePutImage && infoRec->PutImage) {
+ infoRec->PutImageMask = GCWhenForced;
+ if((infoRec->PutImageFlags & GXCOPY_ONLY) ||
+ (infoRec->PutImageFlags & ROP_NEEDS_SOURCE))
+ infoRec->PutImageMask |= GCFunction;
+ if(infoRec->PutImageFlags & NO_PLANEMASK)
+ infoRec->PutImageMask |= GCPlaneMask;
+ if(infoRec->PutImageFlags & RGB_EQUAL)
+ infoRec->PutImageMask |= GCForeground | GCBackground;
+ infoRec->ValidatePutImage = XAAValidatePutImage;
+ }
+
+
+ if(!infoRec->ValidatePushPixels && infoRec->PushPixelsSolid) {
+ infoRec->PushPixelsMask = GCFillStyle;
+ if((infoRec->PushPixelsFlags & GXCOPY_ONLY) ||
+ (infoRec->PushPixelsFlags & ROP_NEEDS_SOURCE) ||
+ (infoRec->PushPixelsFlags & TRANSPARENCY_GXCOPY_ONLY))
+ infoRec->PushPixelsMask |= GCFunction;
+ if(infoRec->PushPixelsFlags & NO_PLANEMASK)
+ infoRec->PushPixelsMask |= GCPlaneMask;
+ if(infoRec->PushPixelsFlags & RGB_EQUAL)
+ infoRec->PushPixelsMask |= GCForeground;
+ infoRec->ValidatePushPixels = XAAValidatePushPixels;
+ }
+
+ /* By default XAA assumes the FillSpans, PolyFillRects, FillPolygon
+ and PolyFillArcs have the same restrictions. If you supply GC
+ level replacements for any of these and alter this relationship
+ you may need to supply replacement validation routines */
+
+ if(!infoRec->ValidateFillSpans &&
+ (infoRec->FillSpansSolid || infoRec->FillSpansStippled ||
+ infoRec->FillSpansOpaqueStippled || infoRec->FillSpansTiled)) {
+
+ int compositeFlags = infoRec->FillSpansSolidFlags |
+ infoRec->FillSpansStippledFlags |
+ infoRec->FillSpansOpaqueStippledFlags |
+ infoRec->FillSpansTiledFlags;
+
+ infoRec->FillSpansMask = GCFillStyle | GCTile | GCStipple;
+
+ if((compositeFlags & GXCOPY_ONLY) ||
+ (compositeFlags & ROP_NEEDS_SOURCE))
+ infoRec->FillSpansMask |= GCFunction;
+ if(compositeFlags & NO_PLANEMASK)
+ infoRec->FillSpansMask |= GCPlaneMask;
+ if(compositeFlags & RGB_EQUAL)
+ infoRec->FillSpansMask |= GCForeground;
+ infoRec->ValidateFillSpans = XAAValidateFillSpans;
+ }
+
+ /* By default XAA only provides Validations for the GlyphBlt
+ functions and not the text higher up. This is because the
+ Text8/16 and GlyphBlt are linked. If you break this linkage,
+ you may need to have the driver supply its own Validation
+ routines */
+
+ if(!infoRec->ValidatePolyGlyphBlt &&
+ (infoRec->PolyGlyphBltTE || infoRec->PolyGlyphBltNonTE)) {
+ int compositeFlags = infoRec->PolyGlyphBltTEFlags |
+ infoRec->PolyGlyphBltNonTEFlags;
+
+ infoRec->PolyGlyphBltMask = GCFillStyle | GCFont;
+ if((compositeFlags & GXCOPY_ONLY) ||
+ (compositeFlags & ROP_NEEDS_SOURCE) ||
+ (infoRec->PolyGlyphBltNonTEFlags & TRANSPARENCY_GXCOPY_ONLY))
+ infoRec->PolyGlyphBltMask |= GCFunction;
+ if(compositeFlags & NO_PLANEMASK)
+ infoRec->PolyGlyphBltMask |= GCPlaneMask;
+ if(compositeFlags & RGB_EQUAL)
+ infoRec->PolyGlyphBltMask |= GCForeground;
+ infoRec->ValidatePolyGlyphBlt = XAAValidatePolyGlyphBlt;
+ }
+
+ if(!infoRec->ValidateImageGlyphBlt &&
+ (infoRec->ImageGlyphBltTE || infoRec->ImageGlyphBltNonTE)) {
+ int compositeFlags = infoRec->ImageGlyphBltTEFlags |
+ infoRec->ImageGlyphBltNonTEFlags;
+
+ if(infoRec->ImageGlyphBltNonTE)
+ compositeFlags |= infoRec->SolidFillFlags;
+
+ infoRec->ImageGlyphBltMask = GCFont;
+ if(compositeFlags & NO_PLANEMASK)
+ infoRec->ImageGlyphBltMask |= GCPlaneMask;
+ if(compositeFlags & RGB_EQUAL)
+ infoRec->ImageGlyphBltMask |= GCForeground | GCBackground;
+ infoRec->ValidateImageGlyphBlt = XAAValidateImageGlyphBlt;
+ }
+
+ /* By default XAA only provides a Validation function for the
+ Polylines and does segments and polylines at the same time */
+
+ if(!infoRec->ValidatePolylines && infoRec->ValidateFillSpans) {
+ int compositeFlags = infoRec->PolyRectangleThinSolidFlags |
+ infoRec->PolylinesWideSolidFlags |
+ infoRec->PolylinesThinSolidFlags |
+ infoRec->PolySegmentThinSolidFlags |
+ infoRec->PolySegmentThinDashedFlags |
+ infoRec->PolylinesThinDashedFlags;
+
+ infoRec->ValidatePolylines = XAAValidatePolylines;
+ infoRec->PolylinesMask =
+ infoRec->FillSpansMask | GCLineStyle | GCLineWidth;
+
+ if(infoRec->PolySegmentThinDashed || infoRec->PolylinesThinDashed)
+ infoRec->PolylinesMask |= GCDashList;
+
+ if(compositeFlags & NO_PLANEMASK)
+ infoRec->PolylinesMask |= GCPlaneMask;
+ if((compositeFlags & GXCOPY_ONLY) ||
+ (compositeFlags & ROP_NEEDS_SOURCE))
+ infoRec->PolylinesMask |= GCFunction;
+ if(compositeFlags & RGB_EQUAL)
+ infoRec->PolylinesMask |= GCForeground;
+ }
+
+
+
+
+ if(!infoRec->StippledFillChooser)
+ infoRec->StippledFillChooser = XAAStippledFillChooser;
+
+ if(!infoRec->OpaqueStippledFillChooser)
+ infoRec->OpaqueStippledFillChooser = XAAOpaqueStippledFillChooser;
+
+ if(!infoRec->TiledFillChooser)
+ infoRec->TiledFillChooser = XAATiledFillChooser;
+
+
+ /**** Setup the pixmap cache ****/
+
+
+ if(infoRec->WriteBitmapToCache) {}
+ else if(infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY))
+ infoRec->WriteBitmapToCache = XAAWriteBitmapToCache;
+ else if(infoRec->Flags & LINEAR_FRAMEBUFFER)
+ infoRec->WriteBitmapToCache = XAAWriteBitmapToCacheLinear;
+ else
+ infoRec->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES;
+
+
+ if(infoRec->WritePixmapToCache) {}
+ else if(infoRec->WritePixmap && !(infoRec->WritePixmapFlags & NO_GXCOPY))
+ infoRec->WritePixmapToCache = XAAWritePixmapToCache;
+ else if(infoRec->Flags & LINEAR_FRAMEBUFFER)
+ infoRec->WritePixmapToCache = XAAWritePixmapToCacheLinear;
+ else
+ infoRec->Flags &= ~PIXMAP_CACHE;
+
+ if (xf86IsOptionSet(XAAOptions, XAAOPT_PIXMAP_CACHE))
+ infoRec->Flags &= ~PIXMAP_CACHE;
+
+
+ if(infoRec->WriteMono8x8PatternToCache) {}
+ else if(infoRec->PixmapCacheFlags & CACHE_MONO_8x8) {
+ if(infoRec->WritePixmapToCache)
+ infoRec->WriteMono8x8PatternToCache = XAAWriteMono8x8PatternToCache;
+ else
+ infoRec->PixmapCacheFlags &= ~CACHE_MONO_8x8;
+ }
+
+ if(infoRec->WriteColor8x8PatternToCache) {}
+ else if(infoRec->PixmapCacheFlags & CACHE_COLOR_8x8) {
+ if(infoRec->WritePixmapToCache && infoRec->WriteBitmapToCache)
+ infoRec->WriteColor8x8PatternToCache = XAAWriteColor8x8PatternToCache;
+ else
+ infoRec->PixmapCacheFlags &= ~CACHE_COLOR_8x8;
+ }
+
+ if(infoRec->CachePixelGranularity < 0) {
+ switch(pScrn->bitsPerPixel) {
+ case 24:
+ case 8: infoRec->CachePixelGranularity = 4; break;
+ case 16: infoRec->CachePixelGranularity = 2; break;
+ case 32: infoRec->CachePixelGranularity = 1; break;
+ default: break;
+ }
+
+ if(BITMAP_SCANLINE_PAD == 64)
+ infoRec->CachePixelGranularity *= 2;
+ }
+
+ if(!infoRec->CacheTile && infoRec->WritePixmapToCache)
+ infoRec->CacheTile = XAACacheTile;
+ if(!infoRec->CacheMonoStipple && infoRec->WritePixmapToCache)
+ infoRec->CacheMonoStipple = XAACacheMonoStipple;
+ if(!infoRec->CacheStipple && infoRec->WriteBitmapToCache)
+ infoRec->CacheStipple = XAACacheStipple;
+ if(!infoRec->CacheMono8x8Pattern && infoRec->WriteMono8x8PatternToCache)
+ infoRec->CacheMono8x8Pattern = XAACacheMono8x8Pattern;
+ if(!infoRec->CacheColor8x8Pattern && infoRec->WriteColor8x8PatternToCache)
+ infoRec->CacheColor8x8Pattern = XAACacheColor8x8Pattern;
+
+ if((infoRec->Flags & PIXMAP_CACHE) && !infoRec->InitPixmapCache) {
+ infoRec->InitPixmapCache = XAAInitPixmapCache;
+ infoRec->ClosePixmapCache = XAAClosePixmapCache;
+ }
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaLine.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaLine.c
new file mode 100644
index 000000000..fb6de091d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaLine.c
@@ -0,0 +1,336 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaLine.c,v 1.4 1999/05/30 03:03:32 dawes Exp $ */
+
+#include "X.h"
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "miline.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+
+void
+#ifdef POLYSEGMENT
+XAAPolySegment(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+#else
+XAAPolyLines(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode, /* Origin or Previous */
+ int npt, /* number of points */
+ DDXPointPtr pptInit
+#endif
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ BoxPtr pboxInit = REGION_RECTS(pGC->pCompositeClip);
+ int nboxInit = REGION_NUM_RECTS(pGC->pCompositeClip);
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ int xorg = pDrawable->x;
+ int yorg = pDrawable->y;
+ int nbox;
+ BoxPtr pbox;
+#ifndef POLYSEGMENT
+ DDXPointPtr ppt;
+#endif
+ int x1, x2, y1, y2, tmp, len;
+
+ if(!nboxInit)
+ return;
+
+ (*infoRec->SetupForSolidLine)(infoRec->pScrn, pGC->fgPixel,
+ pGC->alu, pGC->planemask);
+
+#ifdef POLYSEGMENT
+ while (nseg--)
+#else
+ ppt = pptInit;
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+ while(--npt)
+#endif
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+
+#ifdef POLYSEGMENT
+ x1 = pSeg->x1 + xorg;
+ y1 = pSeg->y1 + yorg;
+ x2 = pSeg->x2 + xorg;
+ y2 = pSeg->y2 + yorg;
+ pSeg++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious) {
+ xorg = x1;
+ yorg = y1;
+ }
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+#endif
+
+ if (x1 == x2) { /* vertical line */
+ /* make the line go top to bottom of screen, keeping
+ endpoint semantics
+ */
+ if (y1 > y2) {
+ tmp = y2;
+ y2 = y1 + 1;
+ y1 = tmp + 1;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast) y1--;
+#endif
+ }
+#ifdef POLYSEGMENT
+ else if (pGC->capStyle != CapNotLast) y2++;
+#endif
+ /* get to first band that might contain part of line */
+ while(nbox && (pbox->y2 <= y1)) {
+ pbox++;
+ nbox--;
+ }
+
+ /* stop when lower edge of box is beyond end of line */
+ while(nbox && (y2 >= pbox->y1)) {
+ if ((x1 >= pbox->x1) && (x1 < pbox->x2)) {
+ tmp = max(y1, pbox->y1);
+ len = min(y2, pbox->y2) - tmp;
+ if (len) (*infoRec->SubsequentSolidHorVertLine)(
+ infoRec->pScrn, x1, tmp, len, DEGREES_270);
+ }
+ nbox--;
+ pbox++;
+ }
+#ifndef POLYSEGMENT
+ y2 = ppt->y + yorg;
+#endif
+ } else if (y1 == y2) { /* horizontal line */
+ /* force line from left to right, keeping endpoint semantics */
+ if (x1 > x2) {
+ tmp = x2;
+ x2 = x1 + 1;
+ x1 = tmp + 1;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast) x1--;
+#endif
+ }
+#ifdef POLYSEGMENT
+ else if (pGC->capStyle != CapNotLast) x2++;
+#endif
+
+ /* find the correct band */
+ while(nbox && (pbox->y2 <= y1)) {
+ pbox++;
+ nbox--;
+ }
+
+ /* try to draw the line, if we haven't gone beyond it */
+ if (nbox && (pbox->y1 <= y1)) {
+ int orig_y = pbox->y1;
+ /* when we leave this band, we're done */
+ while(nbox && (orig_y == pbox->y1)) {
+ if (pbox->x2 <= x1) {
+ /* skip boxes until one might contain start point */
+ nbox--;
+ pbox++;
+ continue;
+ }
+
+ /* stop if left of box is beyond right of line */
+ if (pbox->x1 >= x2) {
+ nbox = 0;
+ break;
+ }
+
+ tmp = max(x1, pbox->x1);
+ len = min(x2, pbox->x2) - tmp;
+ if (len) (*infoRec->SubsequentSolidHorVertLine)(
+ infoRec->pScrn, tmp, y1, len, DEGREES_0);
+ nbox--;
+ pbox++;
+ }
+ }
+#ifndef POLYSEGMENT
+ x2 = ppt->x + xorg;
+#endif
+ } else{ /* sloped line */
+ unsigned int oc1, oc2;
+ int dmin, dmaj, e, octant;
+
+ if (infoRec->SubsequentSolidBresenhamLine) {
+ if((dmaj = x2 - x1) < 0) {
+ dmaj = -dmaj;
+ octant = XDECREASING;
+ } else octant = 0;
+
+ if((dmin = y2 - y1) < 0) {
+ dmin = -dmin;
+ octant |= YDECREASING;
+ }
+
+ if(dmin >= dmaj){
+ tmp = dmin; dmin = dmaj; dmaj = tmp;
+ octant |= YMAJOR;
+ }
+
+ e = -dmaj - ((bias >> octant) & 1);
+ len = dmaj;
+ dmin <<= 1;
+ dmaj <<= 1;
+ }
+
+ while(nbox--) {
+ oc1 = oc2 = 0;
+ OUTCODES(oc1, x1, y1, pbox);
+ OUTCODES(oc2, x2, y2, pbox);
+ if (!(oc1 | oc2)) { /* uncliped */
+ if(infoRec->SubsequentSolidTwoPointLine) {
+ (*infoRec->SubsequentSolidTwoPointLine)(
+ infoRec->pScrn, x1, y1, x2, y2,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? 0 :
+#endif
+ OMIT_LAST
+ );
+ } else {
+ (*infoRec->SubsequentSolidBresenhamLine)(
+ infoRec->pScrn, x1, y1, dmaj, dmin, e,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? (len+1) :
+#endif
+ len, octant);
+ }
+ break;
+ } else if (oc1 & oc2) { /* completely clipped */
+ pbox++;
+ } else if (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_LINE) {
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ pbox->x1, pbox->y1, pbox->x2 - 1, pbox->y2 - 1);
+
+ if(infoRec->SubsequentSolidBresenhamLine) {
+ (*infoRec->SubsequentSolidBresenhamLine)(
+ infoRec->pScrn, x1, y1, dmaj, dmin, e,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? (len+1) :
+#endif
+ len, octant);
+ } else {
+ (*infoRec->SubsequentSolidTwoPointLine)(
+ infoRec->pScrn, x1, y1, x2, y2,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? 0 :
+#endif
+ OMIT_LAST
+ );
+ }
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+ pbox++;
+ } else {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int err, adx, ady;
+
+ if(octant & YMAJOR) {
+ ady = dmaj >> 1;
+ adx = dmin >> 1;
+ } else {
+ ady = dmin >> 1;
+ adx = dmaj >> 1;
+ }
+
+ if (miZeroClipLine(pbox->x1, pbox->y1,
+ pbox->x2 - 1, pbox->y2 - 1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pbox++;
+ continue;
+ }
+
+ if (octant & YMAJOR)
+ len = abs(new_y2 - new_y1);
+ else
+ len = abs(new_x2 - new_x1);
+#ifdef POLYSEGMENT
+ if (clip2 != 0 || pGC->capStyle != CapNotLast)
+ len++;
+#else
+ len += (clip2 != 0);
+#endif
+ if (len) {
+ int abserr, clipdx, clipdy;
+ /* unwind bresenham error term to first point */
+ if (clip1) {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+
+ if (octant & YMAJOR)
+ err = e + clipdy*dmin - clipdx*dmaj;
+ else
+ err = e + clipdx*dmin - clipdy*dmaj;
+ } else
+ err = e;
+
+#define range infoRec->SolidBresenhamLineErrorTermBits
+ abserr = abs(err);
+ while((abserr & range) ||
+ (dmaj & range) ||
+ (dmin & range)) {
+ dmin >>= 1;
+ dmaj >>= 1;
+ abserr >>= 1;
+ err /= 2;
+ }
+
+ (*infoRec->SubsequentSolidBresenhamLine)(
+ infoRec->pScrn, new_x1, new_y1,
+ dmaj, dmin, err, len, octant);
+ }
+ pbox++;
+ }
+ } /* while (nbox--) */
+ } /* sloped line */
+ } /* while (nline--) */
+
+#ifndef POLYSEGMENT
+ /* paint the last point if the end style isn't CapNotLast.
+ (Assume that a projecting, butt, or round cap that is one
+ pixel wide is the same as the single pixel of the endpoint.)
+ */
+
+ if ((pGC->capStyle != CapNotLast) &&
+ ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
+ (ppt->y + yorg != pptInit->y + pDrawable->y) ||
+ (ppt == pptInit + 1)))
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+ while (nbox--)
+ {
+ if ((x2 >= pbox->x1) && (y2 >= pbox->y1) &&
+ (x2 < pbox->x2) && (y2 < pbox->y2))
+ {
+ (*infoRec->SubsequentSolidHorVertLine)(
+ infoRec->pScrn, x2, y2, 1, DEGREES_0);
+ break;
+ }
+ else
+ pbox++;
+ }
+ }
+#endif
+
+ SET_SYNC_FLAG(infoRec);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaLineMisc.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaLineMisc.c
new file mode 100644
index 000000000..370921002
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaLineMisc.c
@@ -0,0 +1,148 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaLineMisc.c,v 1.5 1999/01/14 13:05:27 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "miline.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+
+void
+XAASolidHorVertLineAsRects(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ if(dir == DEGREES_0)
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, len, 1);
+ else
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, 1, len);
+}
+
+
+void
+XAASolidHorVertLineAsTwoPoint(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ len--;
+
+ if(dir == DEGREES_0)
+ (*infoRec->SubsequentSolidTwoPointLine)(pScrn, x, y, x + len, y, 0);
+ else
+ (*infoRec->SubsequentSolidTwoPointLine)(pScrn, x, y, x, y + len, 0);
+}
+
+void
+XAASolidHorVertLineAsBresenham(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ if(dir == DEGREES_0)
+ (*infoRec->SubsequentSolidBresenhamLine)(
+ pScrn, x, y, len << 1, 0, -len, len, 0);
+ else
+ (*infoRec->SubsequentSolidBresenhamLine)(
+ pScrn, x, y, len << 1, 0, -len, len, YMAJOR);
+}
+
+
+void
+XAAComputeDash(GCPtr pGC)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAAGCPtr pGCPriv = (XAAGCPtr) (pGC)->devPrivates[XAAGCIndex].ptr;
+ Bool EvenDash = (pGC->numInDashList & 0x01) ? FALSE : TRUE;
+ int PatternLength = 0;
+ unsigned char* DashPtr = (unsigned char*)pGC->dash;
+ CARD32 *ptr;
+ int count = pGC->numInDashList;
+ int shift, value, direction;
+ Bool set;
+
+ if(pGCPriv->DashPattern)
+ xfree(pGCPriv->DashPattern);
+
+ pGCPriv->DashPattern = NULL;
+ pGCPriv->DashLength = 0;
+
+ while(count--)
+ PatternLength += *(DashPtr++);
+
+ if(!EvenDash)
+ PatternLength <<= 1;
+
+ if(PatternLength > infoRec->DashPatternMaxLength)
+ return;
+
+ if((infoRec->DashedLineFlags & LINE_PATTERN_POWER_OF_2_ONLY) &&
+ (PatternLength & (PatternLength - 1)))
+ return;
+
+ pGCPriv->DashPattern = xcalloc((PatternLength + 31) >> 5, 4);
+ if(!pGCPriv->DashPattern) return;
+ pGCPriv->DashLength = PatternLength;
+
+ if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
+ LINE_PATTERN_LSBFIRST_LSBJUSTIFIED)) {
+ direction = 1;
+ set = TRUE;
+ DashPtr = (unsigned char*)pGC->dash;
+ } else {
+ direction = -1;
+ set = FALSE;
+ DashPtr = (unsigned char*)pGC->dash + pGC->numInDashList - 1;
+ }
+
+ if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
+ LINE_PATTERN_MSBFIRST_MSBJUSTIFIED))
+ shift = 32 - (PatternLength & 31);
+ else
+ shift = 0;
+
+ ptr = (CARD32*)(pGCPriv->DashPattern);
+
+CONCATENATE:
+
+ count = pGC->numInDashList;
+
+ while(count--) {
+ value = *DashPtr;
+ DashPtr += direction;
+ while(value) {
+ if(value < (32 - shift)) {
+ if(set) *ptr |= XAAShiftMasks[value] << shift;
+ shift += value;
+ break;
+ } else {
+ if(set) *ptr |= ~0L << shift;
+ value -= (32 - shift);
+ shift = 0;
+ ptr++;
+ }
+ }
+ if(set) set = FALSE;
+ else set = TRUE;
+ }
+
+ if(!EvenDash) {
+ EvenDash = TRUE;
+ if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
+ LINE_PATTERN_LSBFIRST_LSBJUSTIFIED))
+ DashPtr = (unsigned char*)pGC->dash;
+ else
+ DashPtr = (unsigned char*)pGC->dash + pGC->numInDashList;
+ goto CONCATENATE;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaNonTEGlyph.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaNonTEGlyph.c
new file mode 100644
index 000000000..1a8d11190
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaNonTEGlyph.c
@@ -0,0 +1,198 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaNonTEGlyph.c,v 1.5 1998/09/27 04:43:45 dawes Exp $ */
+
+
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaacexp.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+
+/* Not used anymore because the algorithm isn't correct. It doesn't
+ handle overlapping characters properly */
+
+#ifdef TRIPLE_BITS
+#define NonTEGlyphFunc EXPNAME(XAANonTEGlyphScanlineFunc3)
+#else
+#define NonTEGlyphFunc EXPNAME(XAANonTEGlyphScanlineFunc)
+#endif
+
+/********************************************************************
+
+ Here we have NonTEGlyphRenders for a bunch of different color
+ expansion types. The driver may provide its own renderer, but
+ this is the default one which renders using lower-level primitives
+ exported by the chipset driver.
+
+********************************************************************/
+
+/* Since the dimensions of the text string and the backing rectangle
+ do not always coincide, it is possible that wBack or wText
+ may be 0! The NonTEGlyphRender must always check for this. */
+
+/* This gets built for MSBFIRST or LSBFIRST with FIXEDBASE or not,
+ with TRIPLE_BITS or not. A total of 8 versions */
+
+/* if the backing rectangle and text are of the same dimensions
+ then we can draw in one pass */
+
+void
+#ifdef TRIPLE_BITS
+EXPNAME(XAANonTEGlyphRenderer3)(
+#else
+EXPNAME(XAANonTEGlyphRenderer)(
+#endif
+ ScrnInfoPtr pScrn,
+ int xText, int wText,
+ int y, int h, int skipleft, int startline,
+ NonTEGlyphInfo *glyphp,
+ int fg, int rop,
+ unsigned int planemask )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32* base = (CARD32*)infoRec->ColorExpandBase;
+#ifdef TRIPLE_BITS
+ int dwords = ((3 * wText + 31) >> 5) * h;
+#else
+ int dwords = ((wText + 31) >> 5) * h;
+#endif
+
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, -1, rop, planemask);
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, xText, y, wText, h, 0);
+
+#ifndef FIXEDBASE
+#ifdef TRIPLE_BITS
+ if((((3 * wText + 31) >> 5) * h) <= infoRec->ColorExpandRange)
+#else
+ if((((wText + 31) >> 5) * h) <= infoRec->ColorExpandRange)
+#endif
+ while(h--)
+ base = NonTEGlyphFunc(base, glyphp, startline++, wText, skipleft);
+ else
+#endif
+ while(h--)
+ NonTEGlyphFunc(base, glyphp, startline++, wText, skipleft);
+
+ if((infoRec->CPUToScreenColorExpandFillFlags & CPU_TRANSFER_PAD_QWORD) &&
+ (dwords & 1)) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+
+ if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+#ifndef FIXEDBASE
+/* Scanline version of above gets built for LSBFIRST and MSBFIRST */
+
+void
+#ifdef TRIPLE_BITS
+EXPNAME(XAANonTEGlyphRendererScanline3)(
+#else
+EXPNAME(XAANonTEGlyphRendererScanline)(
+#endif
+ ScrnInfoPtr pScrn,
+ int xText, int wText,
+ int y, int h, int skipleft, int startline,
+ NonTEGlyphInfo *glyphp,
+ int fg, int rop,
+ unsigned int planemask )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int bufferNo = 0;
+ CARD32* base = (CARD32*)infoRec->ScanlineColorExpandBuffers[0];
+
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
+ pScrn, fg, -1, rop, planemask);
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, xText, y, wText, h, 0);
+
+ while(h--) {
+ NonTEGlyphFunc(base, glyphp, startline++, wText, skipleft);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+#endif
+
+/********************************************************************
+
+ Generic NonTE scanline rendering code.
+
+********************************************************************/
+
+
+CARD32*
+NonTEGlyphFunc(
+ CARD32 *base,
+ NonTEGlyphInfo *glyphp,
+ int line, int TotalWidth, int skipleft )
+{
+ CARD32 bits = 0;
+ int shift = glyphp->width;
+
+ if(skipleft) {
+ if((line >= glyphp->firstline) && (line <= glyphp->lastline))
+ bits = SHIFT_R(glyphp->bitsp[line], skipleft);
+ shift -= skipleft;
+ } else if((line >= glyphp->firstline) && (line <= glyphp->lastline))
+ bits = glyphp->bitsp[line];
+
+
+ while(TotalWidth > 32) {
+ while(shift < 32) {
+ glyphp++;
+ if((line >= glyphp->firstline) && (line <= glyphp->lastline))
+ bits |= SHIFT_L(glyphp->bitsp[line],shift);
+ shift += glyphp->width;
+ }
+#ifdef TRIPLE_BITS
+ WRITE_BITS3(bits);
+#else
+ WRITE_BITS(bits);
+#endif
+ shift &= 31;
+ if(shift &&
+ (line >= glyphp->firstline) && (line <= glyphp->lastline))
+ bits = SHIFT_R(glyphp->bitsp[line], glyphp->width - shift);
+ else bits = 0;
+ TotalWidth -= 32;
+ }
+
+ if(TotalWidth) {
+ TotalWidth -= shift;
+ while(TotalWidth > 0) {
+ glyphp++;
+ if((line >= glyphp->firstline) && (line <= glyphp->lastline))
+ bits |= SHIFT_L(glyphp->bitsp[line], shift);
+ shift += glyphp->width;
+ TotalWidth -= glyphp->width;
+ }
+#ifdef TRIPLE_BITS
+ if (shift >= 22) {
+ WRITE_BITS3(bits);
+ } else if (shift >= 11) {
+ WRITE_BITS2(bits);
+ } else {
+ WRITE_BITS1(bits);
+ }
+#else
+ WRITE_BITS(bits);
+#endif
+ }
+
+
+ return base;
+}
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaNonTEText.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaNonTEText.c
new file mode 100644
index 000000000..62a393a91
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaNonTEText.c
@@ -0,0 +1,585 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaNonTEText.c,v 1.9 1999/07/11 08:49:30 dawes Exp $ */
+
+/********************************************************************
+
+ In this file we have GC level replacements for PolyText8/16,
+ ImageText8/16, ImageGlyphBlt and PolyGlyphBlt for NonTE (proportional)
+ fonts. The idea is that everything in this file is device independent.
+ The mentioned GCOps are merely wrappers for the
+ PolyGlyphBltNonTEColorExpansion and ImageGlyphBltNonTEColorExpansion
+ functions which calculate the boxes containing arbitrarily clipped
+ text and passes them to the NonTEGlyphRenderer which will usually
+ be a lower level XAA function which renders these clipped glyphs using
+ the basic color expansion functions exported by the chipset driver.
+ The NonTEGlyphRenderer itself may optionally be driver supplied to
+ facilitate work-arounds/optimizations at a higher level than usual.
+
+ Written by Mark Vojkovich (mvojkovi@ucsd.edu)
+
+********************************************************************/
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "font.h"
+#include "scrnintstr.h"
+#include "dixfontstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaacexp.h"
+#include "xaalocal.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+
+
+static void ImageGlyphBltNonTEColorExpansion(ScrnInfoPtr pScrn,
+ int xInit, int yInit, FontPtr font,
+ int fg, int bg, unsigned planemask,
+ RegionPtr cclip, int nglyph,
+ unsigned char* gBase, CharInfoPtr *ppci);
+static int PolyGlyphBltNonTEColorExpansion(ScrnInfoPtr pScrn,
+ int xInit, int yInit, FontPtr font,
+ int fg, int rop, unsigned planemask,
+ RegionPtr cclip, int nglyph,
+ unsigned char* gBase, CharInfoPtr *ppci);
+
+/********************************************************************
+
+ GC level replacements for PolyText8/16 and ImageText8/16
+ for NonTE fonts when using color expansion.
+
+********************************************************************/
+
+
+int
+XAAPolyText8NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+ int width = 0;
+
+ (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
+ (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
+
+ if(n) {
+ width = PolyGlyphBltNonTEColorExpansion( infoRec->pScrn,
+ x + pDraw->x, y + pDraw->y, pGC->font,
+ pGC->fgPixel, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font),
+ infoRec->CharInfo);
+ }
+
+ return (x + width);
+}
+
+
+int
+XAAPolyText16NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+ int width = 0;
+
+ (*pGC->font->get_glyphs)(
+ pGC->font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, infoRec->CharInfo);
+
+ if(n) {
+ width = PolyGlyphBltNonTEColorExpansion( infoRec->pScrn,
+ x + pDraw->x, y + pDraw->y, pGC->font,
+ pGC->fgPixel, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font),
+ infoRec->CharInfo);
+ }
+
+ return (x + width);
+}
+
+
+void
+XAAImageText8NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
+ (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
+
+ if(n) ImageGlyphBltNonTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+}
+
+
+void
+XAAImageText16NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ (*pGC->font->get_glyphs)(
+ pGC->font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, infoRec->CharInfo);
+
+ if(n) ImageGlyphBltNonTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+}
+
+
+
+/********************************************************************
+
+ GC level replacements for ImageGlyphBlt and PolyGlyphBlt for
+ NonTE fonts when using color expansion.
+
+********************************************************************/
+
+
+void
+XAAImageGlyphBltNonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci, /* array of character info */
+ pointer pglyphBase /* start of array of glyphs */
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ ImageGlyphBltNonTEColorExpansion(
+ infoRec->pScrn, xInit + pDraw->x, yInit + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask,
+ pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
+}
+
+void
+XAAPolyGlyphBltNonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci, /* array of character info */
+ pointer pglyphBase /* start of array of glyphs */
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ PolyGlyphBltNonTEColorExpansion(
+ infoRec->pScrn, xInit + pDraw->x, yInit + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
+}
+
+
+
+
+/********************************************************************
+
+ ImageGlyphBltNonTEColorExpansion -
+ PolyGlyphBltNonTEColorExpansion -
+
+ These guys compute the clipped pieces of text and send it to
+ the lower-level function which will handle acceleration of
+ arbitrarily clipped text.
+
+********************************************************************/
+
+
+
+static int
+CollectCharacterInfo(
+ NonTEGlyphPtr glyphs,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ FontPtr pfont
+){
+ int i, w = 0;
+
+ for(i = 0; i < nglyph; i++, ppci++, glyphs++) {
+ glyphs->bits = (unsigned char*)((*ppci)->bits);
+ glyphs->start = w + (*ppci)->metrics.leftSideBearing;
+ glyphs->end = w + (*ppci)->metrics.rightSideBearing;
+ glyphs->yoff = (*ppci)->metrics.ascent;
+ glyphs->height = glyphs->yoff + (*ppci)->metrics.descent;
+ glyphs->srcwidth = PADGLYPHWIDTHBYTES(glyphs->end - glyphs->start);
+ w += (*ppci)->metrics.characterWidth;
+ }
+ return w;
+}
+
+
+static void
+PolyGlyphBltAsSingleBitmap (
+ ScrnInfoPtr pScrn,
+ int nglyph,
+ FontPtr font,
+ int xInit,
+ int yInit,
+ int nbox,
+ BoxPtr pbox,
+ int fg,
+ int rop,
+ unsigned planemask
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *block, *pntr, *bits;
+ int pitch, topLine, botLine, top, bot;
+ int Left, Right, Top, Bottom;
+ int LeftEdge, RightEdge;
+ int bitPitch, shift, size, i, skippix;
+ NonTEGlyphPtr glyphs = infoRec->GlyphInfo;
+ Bool extra;
+
+ Left = xInit + infoRec->GlyphInfo[0].start;
+ Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
+ Top = yInit - FONTMAXBOUNDS(font,ascent);
+ Bottom = yInit + FONTMAXBOUNDS(font,descent);
+
+ /* get into the first band that may contain part of our string */
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ if(!nbox) return;
+
+ pitch = (Right - Left + 31) >> 5;
+ size = (pitch << 2) * (Bottom - Top);
+ block = (CARD32*)ALLOCATE_LOCAL(size);
+ bzero(block, size);
+
+ topLine = 10000; botLine = -10000;
+
+ while(nglyph--) {
+ top = -glyphs->yoff;
+ bot = top + glyphs->height;
+ if(top < topLine) topLine = top;
+ if(bot > botLine) botLine = bot;
+ skippix = glyphs->start - infoRec->GlyphInfo[0].start;
+ bits = (CARD32*)glyphs->bits;
+ bitPitch = glyphs->srcwidth >> 2;
+ pntr = block + ((FONTMAXBOUNDS(font,ascent) + top) * pitch) +
+ (skippix >> 5);
+ shift = skippix & 31;
+ extra = ((shift + glyphs->end - glyphs->start) > 32);
+
+ for(i = top; i < bot; i++) {
+ *pntr |= SHIFT_L(*bits, shift);
+ if(extra)
+ *(pntr + 1) |= SHIFT_R(*bits,32 - shift);
+ pntr += pitch;
+ bits += bitPitch;
+ }
+
+ glyphs++;
+ }
+
+ pntr = block + ((FONTMAXBOUNDS(font,ascent) + topLine) * pitch);
+
+ Top = yInit + topLine;
+ Bottom = yInit + botLine;
+
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ while(nbox && (Bottom >= pbox->y1)) {
+ LeftEdge = max(Left, pbox->x1);
+ RightEdge = min(Right, pbox->x2);
+
+ if(RightEdge > LeftEdge) {
+ skippix = LeftEdge - Left;
+ topLine = max(Top, pbox->y1);
+ botLine = min(Bottom, pbox->y2);
+
+ (*infoRec->WriteBitmap)(pScrn, LeftEdge, topLine,
+ RightEdge - LeftEdge, botLine - topLine,
+ (unsigned char*)(pntr + ((topLine - Top) * pitch) +
+ (skippix >> 5)),
+ pitch << 2, skippix & 31, fg, -1, rop, planemask);
+ }
+
+ nbox--; pbox++;
+ }
+
+ DEALLOCATE_LOCAL(block);
+}
+
+static void
+ImageGlyphBltNonTEColorExpansion(
+ ScrnInfoPtr pScrn,
+ int xInit, int yInit,
+ FontPtr font,
+ int fg, int bg,
+ unsigned planemask,
+ RegionPtr cclip,
+ int nglyph,
+ unsigned char* gBase,
+ CharInfoPtr *ppci
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int skippix, skipglyph, width, n, i;
+ int Left, Right, Top, Bottom;
+ int LeftEdge, RightEdge, ytop, ybot;
+ int nbox = REGION_NUM_RECTS(cclip);
+ BoxPtr pbox = REGION_RECTS(cclip);
+ Bool AlreadySetup = FALSE;
+
+ width = CollectCharacterInfo(infoRec->GlyphInfo, nglyph, ppci, font);
+
+ /* find our backing rectangle dimensions */
+ Left = xInit;
+ Right = Left + width;
+ Top = yInit - FONTASCENT(font);
+ Bottom = yInit + FONTDESCENT(font);
+
+ /* get into the first band that may contain part of our box */
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ while(nbox && (Bottom >= pbox->y1)) {
+ /* handle backing rect first */
+ LeftEdge = max(Left, pbox->x1);
+ RightEdge = min(Right, pbox->x2);
+ if(RightEdge > LeftEdge) {
+ ytop = max(Top, pbox->y1);
+ ybot = min(Bottom, pbox->y2);
+
+ if(ybot > ytop) {
+ if(!AlreadySetup) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, GXcopy, planemask);
+ AlreadySetup = TRUE;
+ }
+ (*infoRec->SubsequentSolidFillRect)(pScrn,
+ LeftEdge, ytop, RightEdge - LeftEdge, ybot - ytop);
+ }
+ }
+ nbox--; pbox++;
+ }
+
+ nbox = REGION_NUM_RECTS(cclip);
+ pbox = REGION_RECTS(cclip);
+
+ if((nglyph > 1) && ((FONTMAXBOUNDS(font, rightSideBearing) -
+ FONTMINBOUNDS(font, leftSideBearing)) <= 32)) {
+
+ PolyGlyphBltAsSingleBitmap(pScrn, nglyph, font,
+ xInit, yInit, nbox, pbox,
+ fg, GXcopy, planemask);
+
+ return;
+ }
+
+ /* compute an approximate but covering bounding box */
+ Left = xInit + infoRec->GlyphInfo[0].start;
+ Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
+ Top = yInit - FONTMAXBOUNDS(font,ascent);
+ Bottom = yInit + FONTMAXBOUNDS(font,descent);
+
+ /* get into the first band that may contain part of our box */
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ /* stop when the lower edge of the box is beyond our string */
+ while(nbox && (Bottom >= pbox->y1)) {
+ LeftEdge = max(Left, pbox->x1);
+ RightEdge = min(Right, pbox->x2);
+
+ if(RightEdge > LeftEdge) { /* we're possibly drawing something */
+ ytop = max(Top, pbox->y1);
+ ybot = min(Bottom, pbox->y2);
+ if(ybot > ytop) {
+ skippix = LeftEdge - xInit;
+ skipglyph = 0;
+ while(skippix >= infoRec->GlyphInfo[skipglyph].end)
+ skipglyph++;
+
+ skippix = RightEdge - xInit;
+ n = 0; i = skipglyph;
+ while((i < nglyph) && (skippix > infoRec->GlyphInfo[i].start)) {
+ i++; n++;
+ }
+
+ if(n) (*infoRec->NonTEGlyphRenderer)(pScrn,
+ xInit, yInit, n, infoRec->GlyphInfo + skipglyph,
+ pbox, fg, GXcopy, planemask);
+ }
+ }
+
+ nbox--; pbox++;
+ }
+}
+
+
+static int
+PolyGlyphBltNonTEColorExpansion(
+ ScrnInfoPtr pScrn,
+ int xInit, int yInit,
+ FontPtr font,
+ int fg, int rop,
+ unsigned planemask,
+ RegionPtr cclip,
+ int nglyph,
+ unsigned char* gBase,
+ CharInfoPtr *ppci
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int skippix, skipglyph, width, n, i;
+ int Left, Right, Top, Bottom;
+ int LeftEdge, RightEdge;
+ int nbox = REGION_NUM_RECTS(cclip);
+ BoxPtr pbox = REGION_RECTS(cclip);
+
+ width = CollectCharacterInfo(infoRec->GlyphInfo, nglyph, ppci, font);
+
+ if(!nbox)
+ return width;
+
+ if((rop == GXcopy) && (nglyph > 1) &&
+ ((FONTMAXBOUNDS(font, rightSideBearing) -
+ FONTMINBOUNDS(font, leftSideBearing)) <= 32)) {
+
+ PolyGlyphBltAsSingleBitmap(pScrn, nglyph, font,
+ xInit, yInit, nbox, pbox,
+ fg, rop, planemask);
+
+ return width;
+ }
+
+ /* compute an approximate but covering bounding box */
+ Left = xInit + infoRec->GlyphInfo[0].start;
+ Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
+ Top = yInit - FONTMAXBOUNDS(font,ascent);
+ Bottom = yInit + FONTMAXBOUNDS(font,descent);
+
+ /* get into the first band that may contain part of our string */
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ /* stop when the lower edge of the box is beyond our string */
+ while(nbox && (Bottom >= pbox->y1)) {
+ LeftEdge = max(Left, pbox->x1);
+ RightEdge = min(Right, pbox->x2);
+
+ if(RightEdge > LeftEdge) { /* we're possibly drawing something */
+
+ skippix = LeftEdge - xInit;
+ skipglyph = 0;
+ while(skippix >= infoRec->GlyphInfo[skipglyph].end)
+ skipglyph++;
+
+ skippix = RightEdge - xInit;
+ n = 0; i = skipglyph;
+ while((i < nglyph) && (skippix > infoRec->GlyphInfo[i].start)) {
+ i++; n++;
+ }
+
+ if(n) (*infoRec->NonTEGlyphRenderer)(pScrn,
+ xInit, yInit, n, infoRec->GlyphInfo + skipglyph,
+ pbox, fg, rop, planemask);
+ }
+
+ nbox--; pbox++;
+ }
+ return width;
+}
+
+
+/* It is possible that the none of the glyphs passed to the
+ NonTEGlyphRenderer will be drawn. This function being called
+ indicates that part of the text string's bounding box is visible
+ but not necessarily that any of the characters are visible */
+
+void XAANonTEGlyphRenderer(
+ ScrnInfoPtr pScrn,
+ int x, int y, int n,
+ NonTEGlyphPtr glyphs,
+ BoxPtr pbox,
+ int fg, int rop,
+ unsigned int planemask
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x1, x2, y1, y2, i, w, h, skipleft, skiptop;
+ unsigned char *src;
+
+ for(i = 0; i < n; i++, glyphs++) {
+ x1 = x + glyphs->start;
+ x2 = x + glyphs->end;
+ y1 = y - glyphs->yoff;
+ y2 = y1 + glyphs->height;
+
+ if(y1 < pbox->y1) {
+ skiptop = pbox->y1 - y1;
+ y1 = pbox->y1;
+ } else skiptop = 0;
+ if(y2 > pbox->y2) y2 = pbox->y2;
+ h = y2 - y1;
+ if(h <= 0) continue;
+
+ if(x1 < pbox->x1) {
+ skipleft = pbox->x1 - x1;
+ x1 = pbox->x1;
+ } else skipleft = 0;
+ if(x2 > pbox->x2) x2 = pbox->x2;
+
+ w = x2 - x1;
+
+ if(w > 0) {
+ src = glyphs->bits + (skiptop * glyphs->srcwidth);
+
+ if(skipleft) {
+ src += (skipleft >> 5) << 2;
+ skipleft &= 31;
+ }
+
+ (*infoRec->WriteBitmap)(pScrn, x1, y1, w, h, src,
+ glyphs->srcwidth, skipleft, fg, -1, rop, planemask);
+ }
+ }
+
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaOffscreen.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaOffscreen.c
new file mode 100644
index 000000000..18fd82954
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaOffscreen.c
@@ -0,0 +1,158 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaOffscreen.c,v 1.5 1999/07/04 06:39:17 dawes Exp $ */
+
+/*
+ Copyright (c) 1999 - The XFree86 Project Inc.
+
+ Written by Mark Vojkovich
+
+*/
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "mi.h"
+#include "miline.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+#include "xf86fbman.h"
+#include "servermd.h"
+
+void
+XAAMoveOutOffscreenPixmaps(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ PixmapLinkPtr pLink = infoRec->OffscreenPixmaps;
+ XAAPixmapPtr pPriv;
+
+ while(pLink) {
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pLink->pPix);
+ pLink->area = pPriv->offscreenArea;
+ XAAMoveOutOffscreenPixmap(pLink->pPix);
+ pLink = pLink->next;
+ }
+}
+
+
+
+void
+XAAMoveInOffscreenPixmaps(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ PixmapLinkPtr pLink = infoRec->OffscreenPixmaps;
+ PixmapPtr pPix, pScreenPix, tmpPix;
+ pointer data;
+ XAAPixmapPtr pPriv;
+ GCPtr pGC;
+ FBAreaPtr area;
+
+ pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
+
+ while(pLink) {
+ pPix = pLink->pPix;
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ area = pLink->area;
+
+ data = pPix->devPrivate.ptr;
+ tmpPix = GetScratchPixmapHeader(pScreen,
+ pPix->drawable.width, pPix->drawable.height,
+ pPix->drawable.depth, pPix->drawable.bitsPerPixel,
+ pPix->devKind, data);
+
+
+ pPix->drawable.x = area->box.x1;
+ pPix->drawable.y = area->box.y1;
+ pPix->devKind = pScreenPix->devKind;
+ pPix->devPrivate.ptr = pScreenPix->devPrivate.ptr;
+ pPix->drawable.bitsPerPixel = infoRec->pScrn->bitsPerPixel;
+ pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ if(!tmpPix) {
+ pPriv->offscreenArea = area;
+ xfree(data);
+ pLink = pLink->next;
+ continue;
+ }
+
+ pGC = GetScratchGC(pPix->drawable.depth, pScreen);
+ ValidateGC((DrawablePtr)pPix, pGC);
+
+ (*pGC->ops->CopyArea)((DrawablePtr)tmpPix, (DrawablePtr)pPix, pGC,
+ 0, 0, pPix->drawable.width, pPix->drawable.height, 0, 0);
+
+ xfree(data);
+ tmpPix->devPrivate.ptr = NULL;
+
+ FreeScratchGC(pGC);
+ FreeScratchPixmapHeader(tmpPix);
+
+ pPriv->offscreenArea = area;
+ pLink->area = NULL;
+ pLink = pLink->next;
+ }
+}
+
+
+void
+XAARemoveAreaCallback(FBAreaPtr area)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(area->pScreen);
+ PixmapPtr pPix = (PixmapPtr)area->devPrivate.ptr;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+
+ XAAMoveOutOffscreenPixmap(pPix);
+
+ pPriv->flags &= ~OFFSCREEN;
+
+ DELIST_OFFSCREEN_PIXMAP(pPix);
+}
+
+void
+XAAMoveOutOffscreenPixmap(PixmapPtr pPix)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ int width, height, devKind, bitsPerPixel;
+ PixmapPtr tmpPix;
+ unsigned char *data;
+ GCPtr pGC;
+
+ width = pPix->drawable.width;
+ height = pPix->drawable.height;
+ bitsPerPixel = pPix->drawable.bitsPerPixel;
+
+ devKind = BitmapBytePad(width * bitsPerPixel);
+ if(!(data = xalloc(devKind * height)))
+ FatalError("Out of memory\n");
+
+ tmpPix = GetScratchPixmapHeader(pScreen, width, height,
+ pPix->drawable.depth, bitsPerPixel, devKind, data);
+ if(!tmpPix) {
+ xfree(data);
+ FatalError("Out of memory\n");
+ }
+
+ pGC = GetScratchGC(pPix->drawable.depth, pScreen);
+ ValidateGC((DrawablePtr)tmpPix, pGC);
+
+ (*pGC->ops->CopyArea)((DrawablePtr)pPix, (DrawablePtr)tmpPix,
+ pGC, 0, 0, width, height, 0, 0);
+
+ FreeScratchGC(pGC);
+ FreeScratchPixmapHeader(tmpPix);
+
+ pPix->drawable.x = 0;
+ pPix->drawable.y = 0;
+ pPix->devKind = devKind;
+ pPix->devPrivate.ptr = data;
+ pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ pPriv->offscreenArea = NULL;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaOverlay.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaOverlay.c
new file mode 100644
index 000000000..7cdf5f969
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaOverlay.c
@@ -0,0 +1,324 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaOverlay.c,v 1.9 1999/05/16 10:13:03 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+extern WindowPtr *WindowTable;
+
+void
+XAACopyWindow8_32(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DDXPointPtr ppt, pptSrc;
+ RegionRec rgnDst8, rgnDst32;
+ BoxPtr pbox;
+ int i, nbox, dx, dy;
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+ unsigned long pm = (pWin->drawable.depth == 24) ? ~0 : 0xff000000;
+ XAAInfoRecPtr infoRec =
+ GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
+
+ if (!infoRec->pScrn->vtSema || !infoRec->ScreenToScreenBitBlt) {
+ XAA_SCREEN_PROLOGUE (pScreen, CopyWindow);
+ if(infoRec->pScrn->vtSema && infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
+ XAA_SCREEN_EPILOGUE (pScreen, CopyWindow, XAACopyWindow8_32);
+ return;
+ }
+
+ REGION_INIT(pScreen, &rgnDst8, NullBox, 0);
+ REGION_INIT(pScreen, &rgnDst32, NullBox, 0);
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
+ REGION_INTERSECT(pScreen, &rgnDst8, &pWin->borderClip, prgnSrc);
+
+ infoRec->ScratchGC.alu = GXcopy;
+
+ nbox = REGION_NUM_RECTS(&rgnDst8);
+ if(nbox &&
+ (pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) {
+
+ pbox = REGION_RECTS(&rgnDst8);
+ for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ infoRec->ScratchGC.planemask = pm;
+ XAADoBitBlt((DrawablePtr)pRoot, (DrawablePtr)pRoot,
+ &(infoRec->ScratchGC), &rgnDst8, pptSrc);
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+
+ if(pm != ~0) {
+ miSegregateChildren(pWin, &rgnDst32, 24);
+ if(REGION_NOTEMPTY(pScreen, &rgnDst32)) {
+ REGION_INTERSECT(pScreen, &rgnDst32, &rgnDst32, prgnSrc);
+ nbox = REGION_NUM_RECTS(&rgnDst32);
+ if(nbox &&
+ (pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))){
+
+ pbox = REGION_RECTS(&rgnDst32);
+ for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ infoRec->ScratchGC.planemask = 0x00ffffff;
+ XAADoBitBlt((DrawablePtr)pRoot, (DrawablePtr)pRoot,
+ &(infoRec->ScratchGC), &rgnDst32, pptSrc);
+
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+ }
+ }
+
+ REGION_UNINIT(pScreen, &rgnDst8);
+ REGION_UNINIT(pScreen, &rgnDst32);
+}
+
+
+
+
+void
+XAAPaintWindow8_32(
+ WindowPtr pWin,
+ RegionPtr prgn,
+ int what
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
+ int nBox = REGION_NUM_RECTS(prgn);
+ BoxPtr pBox = REGION_RECTS(prgn);
+ int depth = pWin->drawable.depth;
+ int fg, key;
+ PixmapPtr pPix = NULL;
+
+ if(!infoRec->pScrn->vtSema) goto BAILOUT;
+
+ switch (what) {
+ case PW_BACKGROUND:
+ switch(pWin->backgroundState) {
+ case None: return;
+ case ParentRelative:
+ do { pWin = pWin->parent; }
+ while(pWin->backgroundState == ParentRelative);
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, what);
+ return;
+ case BackgroundPixel:
+ fg = pWin->background.pixel;
+ break;
+ case BackgroundPixmap:
+ pPix = pWin->background.pixmap;
+ break;
+ }
+ break;
+ case PW_BORDER:
+ if(depth == 24)
+ key = infoRec->pScrn->colorKey << 24;
+ if (pWin->borderIsPixel)
+ fg = pWin->border.pixel;
+ else /* pixmap */
+ pPix = pWin->border.pixmap;
+ break;
+ default: return;
+ }
+
+
+ if(!pPix) {
+ if(infoRec->FillSolidRects &&
+ (!(infoRec->FillSolidRectsFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(fg))) ) {
+ if(depth == 8)
+ (*infoRec->FillSolidRects)(infoRec->pScrn, fg << 24, GXcopy,
+ 0xff000000, nBox, pBox);
+ else if(what == PW_BORDER)
+ (*infoRec->FillSolidRects)(infoRec->pScrn,
+ (fg & 0x00ffffff) | key,
+ GXcopy, ~0, nBox, pBox);
+ else
+ (*infoRec->FillSolidRects)(infoRec->pScrn, fg, GXcopy,
+ 0x00ffffff, nBox, pBox);
+ return;
+ }
+ } else { /* pixmap */
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ WindowPtr pBgWin = pWin;
+ unsigned int pm = (depth == 8) ? 0xff000000 : 0x00ffffff;
+ Bool DoExpose = FALSE;
+ int xorg, yorg;
+
+
+ if (what == PW_BORDER) {
+ for (pBgWin = pWin;
+ pBgWin->backgroundState == ParentRelative;
+ pBgWin = pBgWin->parent);
+ if(depth == 24)
+ DoExpose = TRUE;
+ }
+
+ xorg = pBgWin->drawable.x;
+ yorg = pBgWin->drawable.y;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ int index = pScreen->myNum;
+ if(WindowTable[index] == pBgWin) {
+ xorg -= panoramiXdataPtr[index].x;
+ yorg -= panoramiXdataPtr[index].y;
+ }
+ }
+#endif
+
+ if(IS_OFFSCREEN_PIXMAP(pPix) && infoRec->FillCacheBltRects) {
+ XAACacheInfoPtr pCache = &(infoRec->ScratchCacheInfoRec);
+
+ pCache->x = pPriv->offscreenArea->box.x1;
+ pCache->y = pPriv->offscreenArea->box.y1;
+ pCache->w = pCache->orig_w =
+ pPriv->offscreenArea->box.x2 - pCache->x;
+ pCache->h = pCache->orig_h =
+ pPriv->offscreenArea->box.y2 - pCache->y;
+
+ (*infoRec->FillCacheBltRects)(infoRec->pScrn, GXcopy, pm,
+ nBox, pBox, xorg, yorg, pCache);
+
+ if(DoExpose)
+ (*infoRec->FillSolidRects)(infoRec->pScrn, key, GXcopy,
+ 0xff000000, nBox, pBox);
+ return;
+ }
+
+ if(pPriv->flags & DIRTY) {
+ pPriv->flags &= ~(DIRTY | REDUCIBILITY_MASK);
+ pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+
+ if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
+ (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
+ XAACheckTileReducibility(pPix, infoRec->CanDoMono8x8);
+ }
+
+ if(pPriv->flags & REDUCIBLE_TO_8x8) {
+ if((pPriv->flags & REDUCIBLE_TO_2_COLOR) &&
+ infoRec->CanDoMono8x8 && infoRec->FillMono8x8PatternRects &&
+ !(infoRec->FillMono8x8PatternRectsFlags & TRANSPARENCY_ONLY) &&
+ (!(infoRec->FillMono8x8PatternRectsFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(pPriv->fg) && CHECK_RGB_EQUAL(pPriv->bg)))) {
+
+ (*infoRec->FillMono8x8PatternRects)(infoRec->pScrn,
+ pPriv->fg, pPriv->bg, GXcopy, pm, nBox, pBox,
+ pPriv->pattern0, pPriv->pattern1, xorg, yorg);
+ if(DoExpose)
+ (*infoRec->FillSolidRects)(infoRec->pScrn, key, GXcopy,
+ 0xff000000, nBox, pBox);
+ return;
+ }
+ if(infoRec->CanDoColor8x8 && infoRec->FillColor8x8PatternRects) {
+ XAACacheInfoPtr pCache = (*infoRec->CacheColor8x8Pattern)(
+ infoRec->pScrn, pPix, -1, -1);
+
+ (*infoRec->FillColor8x8PatternRects) (infoRec->pScrn,
+ GXcopy, pm, nBox, pBox, xorg, yorg, pCache);
+ if(DoExpose)
+ (*infoRec->FillSolidRects)(infoRec->pScrn, key, GXcopy,
+ 0xff000000, nBox, pBox);
+ return;
+ }
+ }
+
+ if(infoRec->UsingPixmapCache && infoRec->FillCacheBltRects &&
+ (pPix->drawable.height <= infoRec->MaxCacheableTileHeight) &&
+ (pPix->drawable.width <= infoRec->MaxCacheableTileWidth)) {
+
+ XAACacheInfoPtr pCache =
+ (*infoRec->CacheTile)(infoRec->pScrn, pPix);
+ (*infoRec->FillCacheBltRects)(infoRec->pScrn, GXcopy, pm,
+ nBox, pBox, xorg, yorg, pCache);
+ if(DoExpose)
+ (*infoRec->FillSolidRects)(infoRec->pScrn, key, GXcopy,
+ 0xff000000, nBox, pBox);
+ return;
+ }
+
+ if(infoRec->FillImageWriteRects &&
+ !(infoRec->FillImageWriteRectsFlags & NO_GXCOPY)) {
+ (*infoRec->FillImageWriteRects) (infoRec->pScrn, GXcopy,
+ pm, nBox, pBox, xorg, yorg, pPix);
+ if(DoExpose)
+ (*infoRec->FillSolidRects)(infoRec->pScrn, key, GXcopy,
+ 0xff000000, nBox, pBox);
+ return;
+ }
+ }
+
+ if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+
+BAILOUT:
+
+ if(what == PW_BACKGROUND) {
+ XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBackground);
+ (*pScreen->PaintWindowBackground) (pWin, prgn, what);
+ XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBackground, XAAPaintWindow8_32);
+ } else {
+ XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBorder);
+ (*pScreen->PaintWindowBorder) (pWin, prgn, what);
+ XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBorder, XAAPaintWindow8_32);
+ }
+}
+
+
+void
+XAAWindowExposures8_32(
+ WindowPtr pWin,
+ RegionPtr pReg,
+ RegionPtr pOtherReg
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+
+ if((pWin->drawable.depth == 24) && infoRec->pScrn->vtSema) {
+ if(REGION_NUM_RECTS(pReg) && infoRec->FillSolidRects) {
+ (*infoRec->FillSolidRects)(infoRec->pScrn,
+ (infoRec->pScrn->colorKey << 24), GXcopy, 0xff000000,
+ REGION_NUM_RECTS(pReg), REGION_RECTS(pReg));
+ miWindowExposures(pWin, pReg, pOtherReg);
+ return;
+ } else if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ }
+
+ XAA_SCREEN_PROLOGUE (pScreen, WindowExposures);
+ (*pScreen->WindowExposures) (pWin, pReg, pOtherReg);
+ XAA_SCREEN_EPILOGUE(pScreen, WindowExposures, XAAWindowExposures8_32);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaOverlayDF.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaOverlayDF.c
new file mode 100644
index 000000000..82a2011a4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaOverlayDF.c
@@ -0,0 +1,1154 @@
+/*
+ Copyright (c) 1999 - The XFree86 Project Inc.
+
+ Written by Mark Vojkovich
+*/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaOverlayDF.c,v 1.1 1999/03/28 15:33:03 dawes Exp $ */
+
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "mi.h"
+#include "miline.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+#include "servermd.h"
+
+/* Screen funcs */
+
+static void XAAOverCopyWindow(WindowPtr, DDXPointRec, RegionPtr);
+static void XAAOverPaintWindow(WindowPtr, RegionPtr, int);
+static void XAAOverWindowExposures(WindowPtr, RegionPtr, RegionPtr);
+static void XAAOverSaveAreas(PixmapPtr, RegionPtr, int, int, WindowPtr);
+static void XAAOverRestoreAreas(PixmapPtr, RegionPtr, int, int, WindowPtr);
+
+
+static int XAAOverStippledFillChooser(GCPtr);
+static int XAAOverOpaqueStippledFillChooser(GCPtr);
+static int XAAOverTiledFillChooser(GCPtr);
+
+/* GC funcs */
+
+static RegionPtr XAAOverCopyArea(DrawablePtr, DrawablePtr, GC *,
+ int, int, int, int, int, int);
+static RegionPtr XAAOverCopyPlane(DrawablePtr, DrawablePtr, GCPtr,
+ int, int, int, int, int, int, unsigned long);
+static void XAAOverPushPixelsSolid(GCPtr, PixmapPtr, DrawablePtr, int,
+ int, int, int);
+static void XAAOverPolyFillRectSolid(DrawablePtr, GCPtr, int, xRectangle*);
+static void XAAOverPolyFillRectStippled(DrawablePtr, GCPtr, int, xRectangle*);
+static void XAAOverPolyFillRectOpaqueStippled(DrawablePtr, GCPtr,
+ int, xRectangle*);
+static void XAAOverPolyFillRectTiled(DrawablePtr, GCPtr, int, xRectangle*);
+static void XAAOverFillSpansSolid(DrawablePtr, GCPtr, int, DDXPointPtr,
+ int*, int);
+static void XAAOverFillSpansStippled(DrawablePtr, GCPtr, int, DDXPointPtr,
+ int*, int);
+static void XAAOverFillSpansOpaqueStippled(DrawablePtr, GCPtr, int,
+ DDXPointPtr, int*, int);
+static void XAAOverFillSpansTiled(DrawablePtr, GCPtr, int, DDXPointPtr,
+ int*, int);
+static int XAAOverPolyText8TE(DrawablePtr, GCPtr, int, int, int, char *);
+static int XAAOverPolyText16TE(DrawablePtr, GCPtr, int, int, int,
+ unsigned short*);
+static void XAAOverImageText8TE(DrawablePtr, GCPtr, int, int, int, char*);
+static void XAAOverImageText16TE(DrawablePtr, GCPtr, int, int, int,
+ unsigned short*);
+static void XAAOverImageGlyphBltTE(DrawablePtr, GCPtr, int, int,
+ unsigned int, CharInfoPtr*, pointer);
+static void XAAOverPolyGlyphBltTE(DrawablePtr, GCPtr, int, int,
+ unsigned int, CharInfoPtr*, pointer);
+static int XAAOverPolyText8NonTE(DrawablePtr, GCPtr, int, int, int, char*);
+static int XAAOverPolyText16NonTE(DrawablePtr, GCPtr, int, int, int,
+ unsigned short*);
+static void XAAOverImageText8NonTE(DrawablePtr, GCPtr, int, int, int, char*);
+static void XAAOverImageText16NonTE(DrawablePtr, GCPtr, int, int, int,
+ unsigned short*);
+static void XAAOverImageGlyphBltNonTE(DrawablePtr, GCPtr, int, int,
+ unsigned int, CharInfoPtr *, pointer);
+static void XAAOverPolyGlyphBltNonTE(DrawablePtr, GCPtr, int, int,
+ unsigned int, CharInfoPtr *, pointer);
+static void XAAOverPolyRectangleThinSolid(DrawablePtr, GCPtr, int, xRectangle*);
+static void XAAOverPolylinesWideSolid(DrawablePtr, GCPtr, int, int,
+ DDXPointPtr);
+static void XAAOverPolylinesThinSolid(DrawablePtr, GCPtr, int, int,
+ DDXPointPtr);
+static void XAAOverPolySegmentThinSolid(DrawablePtr, GCPtr, int, xSegment*);
+static void XAAOverPolylinesThinDashed(DrawablePtr, GCPtr, int, int,
+ DDXPointPtr);
+static void XAAOverPolySegmentThinDashed(DrawablePtr, GCPtr, int, xSegment*);
+static void XAAOverFillPolygonSolid(DrawablePtr, GCPtr, int, int, int,
+ DDXPointPtr);
+static void XAAOverFillPolygonStippled(DrawablePtr, GCPtr, int, int, int,
+ DDXPointPtr);
+static void XAAOverFillPolygonOpaqueStippled(DrawablePtr, GCPtr, int, int, int,
+ DDXPointPtr);
+static void XAAOverFillPolygonTiled(DrawablePtr, GCPtr, int, int, int,
+ DDXPointPtr);
+static void XAAOverPolyFillArcSolid(DrawablePtr, GCPtr, int, xArc*);
+static void XAAOverPutImage(DrawablePtr, GCPtr, int, int, int, int, int,
+ int, int, char*);
+
+
+typedef struct {
+ ScrnInfoPtr pScrn;
+ DepthChangeFuncPtr callback;
+ int currentDepth;
+/* GC funcs */
+ RegionPtr (*CopyArea)(DrawablePtr, DrawablePtr, GC *,
+ int, int, int, int, int, int);
+ RegionPtr (*CopyPlane)(DrawablePtr, DrawablePtr, GCPtr,
+ int, int, int, int, int, int, unsigned long);
+ void (*PushPixelsSolid)(GCPtr, PixmapPtr, DrawablePtr, int, int, int, int);
+ void (*PolyFillRectSolid)(DrawablePtr, GCPtr, int, xRectangle*);
+ void (*PolyFillRectStippled)(DrawablePtr, GCPtr, int, xRectangle*);
+ void (*PolyFillRectOpaqueStippled)(DrawablePtr, GCPtr, int, xRectangle*);
+ void (*PolyFillRectTiled)(DrawablePtr, GCPtr, int, xRectangle*);
+ void (*FillSpansSolid)(DrawablePtr, GCPtr, int, DDXPointPtr, int*, int);
+ void (*FillSpansStippled)(DrawablePtr, GCPtr, int, DDXPointPtr, int*, int);
+ void (*FillSpansOpaqueStippled)(DrawablePtr,GCPtr,int,DDXPointPtr,int*,int);
+ void (*FillSpansTiled)(DrawablePtr, GCPtr, int, DDXPointPtr, int*, int);
+ int (*PolyText8TE)(DrawablePtr, GCPtr, int, int, int, char *);
+ int (*PolyText16TE)(DrawablePtr, GCPtr, int, int, int, unsigned short*);
+ void (*ImageText8TE)(DrawablePtr, GCPtr, int, int, int, char*);
+ void (*ImageText16TE)(DrawablePtr, GCPtr, int, int, int, unsigned short*);
+ void (*ImageGlyphBltTE)(DrawablePtr, GCPtr, int, int, unsigned int,
+ CharInfoPtr*, pointer);
+ void (*PolyGlyphBltTE)(DrawablePtr, GCPtr, int, int, unsigned int,
+ CharInfoPtr*, pointer);
+ int (*PolyText8NonTE)(DrawablePtr, GCPtr, int, int, int, char*);
+ int (*PolyText16NonTE)(DrawablePtr, GCPtr, int, int, int, unsigned short*);
+ void (*ImageText8NonTE)(DrawablePtr, GCPtr, int, int, int, char*);
+ void (*ImageText16NonTE)(DrawablePtr, GCPtr, int, int, int, unsigned short*);
+ void (*ImageGlyphBltNonTE)(DrawablePtr, GCPtr, int, int, unsigned int,
+ CharInfoPtr *, pointer);
+ void (*PolyGlyphBltNonTE)(DrawablePtr, GCPtr, int, int, unsigned int,
+ CharInfoPtr *, pointer);
+ void (*PolyRectangleThinSolid)(DrawablePtr, GCPtr, int, xRectangle*);
+ void (*PolylinesWideSolid)(DrawablePtr, GCPtr, int, int, DDXPointPtr);
+
+ void (*PolylinesThinSolid)(DrawablePtr, GCPtr, int, int, DDXPointPtr);
+ void (*PolySegmentThinSolid)(DrawablePtr, GCPtr, int, xSegment*);
+ void (*PolylinesThinDashed)(DrawablePtr, GCPtr, int, int, DDXPointPtr);
+ void (*PolySegmentThinDashed)(DrawablePtr, GCPtr, int, xSegment*);
+ void (*FillPolygonSolid)(DrawablePtr, GCPtr, int, int, int, DDXPointPtr);
+ void (*FillPolygonStippled)(DrawablePtr, GCPtr, int, int, int, DDXPointPtr);
+ void (*FillPolygonOpaqueStippled)(DrawablePtr, GCPtr, int, int, int,
+ DDXPointPtr);
+ void (*FillPolygonTiled)(DrawablePtr, GCPtr, int, int, int, DDXPointPtr);
+ void (*PolyFillArcSolid)(DrawablePtr, GCPtr, int, xArc*);
+ void (*PutImage)(DrawablePtr, GCPtr, int, int, int, int, int, int,
+ int, char*);
+ int (*StippledFillChooser)(GCPtr);
+ int (*OpaqueStippledFillChooser)(GCPtr);
+ int (*TiledFillChooser)(GCPtr);
+} XAAOverlayRec, *XAAOverlayPtr;
+
+static int XAAOverlayIndex = -1;
+static unsigned long XAAOverlayGeneration = 0;
+
+#define GET_OVERLAY_PRIV(pScreen) \
+ ((XAAOverlayPtr)((pScreen)->devPrivates[XAAOverlayIndex].ptr))
+
+#define SWITCH_DEPTH(d) \
+ if(pOverPriv->currentDepth != d) { \
+ (*pOverPriv->callback)(pOverPriv->pScrn, d); \
+ pOverPriv->currentDepth = d; \
+ }
+
+
+Bool
+XAAInitDualFramebufferOverlay(
+ ScreenPtr pScreen,
+ DepthChangeFuncPtr callback
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAOverlayPtr pOverPriv;
+
+ if (XAAOverlayGeneration != serverGeneration) {
+ if((XAAOverlayIndex = AllocateScreenPrivateIndex()) < 0)
+ return FALSE;
+
+ XAAOverlayGeneration = serverGeneration;
+ }
+
+
+ if(!(pOverPriv = xalloc(sizeof(XAAOverlayRec))))
+ return FALSE;
+
+ pScreen->devPrivates[XAAOverlayIndex].ptr = (pointer)pOverPriv;
+
+ pOverPriv->pScrn = pScrn;
+ pOverPriv->callback = callback;
+ pOverPriv->currentDepth = -1;
+
+ /* Overwrite key screen functions. The XAA core will clean up */
+
+ pScreen->CopyWindow = XAAOverCopyWindow;
+ pScreen->PaintWindowBackground = XAAOverPaintWindow;
+ pScreen->PaintWindowBorder = XAAOverPaintWindow;
+ pScreen->WindowExposures = XAAOverWindowExposures;
+ pScreen->BackingStoreFuncs.SaveAreas = XAAOverSaveAreas;
+ pScreen->BackingStoreFuncs.RestoreAreas = XAAOverRestoreAreas;
+
+ pOverPriv->StippledFillChooser = infoRec->StippledFillChooser;
+ pOverPriv->OpaqueStippledFillChooser = infoRec->OpaqueStippledFillChooser;
+ pOverPriv->TiledFillChooser = infoRec->TiledFillChooser;
+
+ infoRec->StippledFillChooser = XAAOverStippledFillChooser;
+ infoRec->OpaqueStippledFillChooser = XAAOverOpaqueStippledFillChooser;
+ infoRec->TiledFillChooser = XAAOverTiledFillChooser;
+
+ /* wrap all XAA GC rendering */
+
+ pOverPriv->CopyArea = infoRec->CopyArea;
+ pOverPriv->CopyPlane = infoRec->CopyPlane;
+ pOverPriv->PushPixelsSolid = infoRec->PushPixelsSolid;
+ pOverPriv->PolyFillRectSolid = infoRec->PolyFillRectSolid;
+ pOverPriv->PolyFillRectStippled = infoRec->PolyFillRectStippled;
+ pOverPriv->PolyFillRectOpaqueStippled = infoRec->PolyFillRectOpaqueStippled;
+ pOverPriv->PolyFillRectTiled = infoRec->PolyFillRectTiled;
+ pOverPriv->FillSpansSolid = infoRec->FillSpansSolid;
+ pOverPriv->FillSpansStippled = infoRec->FillSpansStippled;
+ pOverPriv->FillSpansOpaqueStippled = infoRec->FillSpansOpaqueStippled;
+ pOverPriv->FillSpansTiled = infoRec->FillSpansTiled;
+ pOverPriv->PolyText8TE = infoRec->PolyText8TE;
+ pOverPriv->PolyText16TE = infoRec->PolyText16TE;
+ pOverPriv->ImageText8TE = infoRec->ImageText8TE;
+ pOverPriv->ImageText16TE = infoRec->ImageText16TE;
+ pOverPriv->ImageGlyphBltTE = infoRec->ImageGlyphBltTE;
+ pOverPriv->PolyGlyphBltTE = infoRec->PolyGlyphBltTE;
+ pOverPriv->PolyText8NonTE = infoRec->PolyText8NonTE;
+ pOverPriv->PolyText16NonTE = infoRec->PolyText16NonTE;
+ pOverPriv->ImageText8NonTE = infoRec->ImageText8NonTE;
+ pOverPriv->ImageText16NonTE = infoRec->ImageText16NonTE;
+ pOverPriv->ImageGlyphBltNonTE = infoRec->ImageGlyphBltNonTE;
+ pOverPriv->PolyGlyphBltNonTE = infoRec->PolyGlyphBltNonTE;
+ pOverPriv->PolyRectangleThinSolid = infoRec->PolyRectangleThinSolid;
+ pOverPriv->PolylinesWideSolid = infoRec->PolylinesWideSolid;
+ pOverPriv->PolylinesThinSolid = infoRec->PolylinesThinSolid;
+ pOverPriv->PolySegmentThinSolid = infoRec->PolySegmentThinSolid;
+ pOverPriv->PolylinesThinDashed = infoRec->PolylinesThinDashed;
+ pOverPriv->PolySegmentThinDashed = infoRec->PolySegmentThinDashed;
+ pOverPriv->FillPolygonSolid = infoRec->FillPolygonSolid;
+ pOverPriv->FillPolygonStippled = infoRec->FillPolygonStippled;
+ pOverPriv->FillPolygonOpaqueStippled = infoRec->FillPolygonOpaqueStippled;
+ pOverPriv->FillPolygonTiled = infoRec->FillPolygonTiled;
+ pOverPriv->PolyFillArcSolid = infoRec->PolyFillArcSolid;
+ pOverPriv->PutImage = infoRec->PutImage;
+
+
+ if(infoRec->CopyArea)
+ infoRec->CopyArea = XAAOverCopyArea;
+ if(infoRec->CopyPlane)
+ infoRec->CopyPlane = XAAOverCopyPlane;
+ if(infoRec->PushPixelsSolid)
+ infoRec->PushPixelsSolid = XAAOverPushPixelsSolid;
+ if(infoRec->PolyFillRectSolid)
+ infoRec->PolyFillRectSolid = XAAOverPolyFillRectSolid;
+ if(infoRec->PolyFillRectStippled)
+ infoRec->PolyFillRectStippled = XAAOverPolyFillRectStippled;
+ if(infoRec->PolyFillRectOpaqueStippled)
+ infoRec->PolyFillRectOpaqueStippled = XAAOverPolyFillRectOpaqueStippled;
+ if(infoRec->PolyFillRectTiled)
+ infoRec->PolyFillRectTiled = XAAOverPolyFillRectTiled;
+ if(infoRec->FillSpansSolid)
+ infoRec->FillSpansSolid = XAAOverFillSpansSolid;
+ if(infoRec->FillSpansStippled)
+ infoRec->FillSpansStippled = XAAOverFillSpansStippled;
+ if(infoRec->FillSpansOpaqueStippled)
+ infoRec->FillSpansOpaqueStippled = XAAOverFillSpansOpaqueStippled;
+ if(infoRec->FillSpansTiled)
+ infoRec->FillSpansTiled = XAAOverFillSpansTiled;
+ if(infoRec->PolyText8TE)
+ infoRec->PolyText8TE = XAAOverPolyText8TE;
+ if(infoRec->PolyText16TE)
+ infoRec->PolyText16TE = XAAOverPolyText16TE;
+ if(infoRec->ImageText8TE)
+ infoRec->ImageText8TE = XAAOverImageText8TE;
+ if(infoRec->ImageText16TE)
+ infoRec->ImageText16TE = XAAOverImageText16TE;
+ if(infoRec->ImageGlyphBltTE)
+ infoRec->ImageGlyphBltTE = XAAOverImageGlyphBltTE;
+ if(infoRec->PolyGlyphBltTE)
+ infoRec->PolyGlyphBltTE = XAAOverPolyGlyphBltTE;
+ if(infoRec->PolyText8NonTE)
+ infoRec->PolyText8NonTE = XAAOverPolyText8NonTE;
+ if(infoRec->PolyText16NonTE)
+ infoRec->PolyText16NonTE = XAAOverPolyText16NonTE;
+ if(infoRec->ImageText8NonTE)
+ infoRec->ImageText8NonTE = XAAOverImageText8NonTE;
+ if(infoRec->ImageText16NonTE)
+ infoRec->ImageText16NonTE = XAAOverImageText16NonTE;
+ if(infoRec->ImageGlyphBltNonTE)
+ infoRec->ImageGlyphBltNonTE = XAAOverImageGlyphBltNonTE;
+ if(infoRec->PolyGlyphBltNonTE)
+ infoRec->PolyGlyphBltNonTE = XAAOverPolyGlyphBltNonTE;
+ if(infoRec->PolyRectangleThinSolid)
+ infoRec->PolyRectangleThinSolid = XAAOverPolyRectangleThinSolid;
+ if(infoRec->PolylinesWideSolid)
+ infoRec->PolylinesWideSolid = XAAOverPolylinesWideSolid;
+ if(infoRec->PolylinesThinSolid)
+ infoRec->PolylinesThinSolid = XAAOverPolylinesThinSolid;
+ if(infoRec->PolySegmentThinSolid)
+ infoRec->PolySegmentThinSolid = XAAOverPolySegmentThinSolid;
+ if(infoRec->PolylinesThinDashed)
+ infoRec->PolylinesThinDashed = XAAOverPolylinesThinDashed;
+ if(infoRec->PolySegmentThinDashed)
+ infoRec->PolySegmentThinDashed = XAAOverPolySegmentThinDashed;
+ if(infoRec->FillPolygonSolid)
+ infoRec->FillPolygonSolid = XAAOverFillPolygonSolid;
+ if(infoRec->FillPolygonStippled)
+ infoRec->FillPolygonStippled = XAAOverFillPolygonStippled;
+ if(infoRec->FillPolygonOpaqueStippled)
+ infoRec->FillPolygonOpaqueStippled = XAAOverFillPolygonOpaqueStippled;
+ if(infoRec->FillPolygonTiled)
+ infoRec->FillPolygonTiled = XAAOverFillPolygonTiled;
+ if(infoRec->PolyFillArcSolid)
+ infoRec->PolyFillArcSolid = XAAOverPolyFillArcSolid;
+ if(infoRec->PutImage)
+ infoRec->PutImage = XAAOverPutImage;
+
+ return TRUE;
+}
+
+/*********************** Screen functions ************************/
+
+void
+XAAOverCopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pScreen);
+ ScrnInfoPtr pScrn = infoRec->pScrn;
+ DDXPointPtr ppt, pptSrc;
+ RegionRec rgnDst;
+ BoxPtr pbox;
+ int i, nbox, dx, dy;
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+
+
+ if (!pScrn->vtSema || !infoRec->ScreenToScreenBitBlt) {
+ XAA_SCREEN_PROLOGUE (pScreen, CopyWindow);
+ if(pScrn->vtSema && infoRec->NeedToSync) {
+ (*infoRec->Sync)(pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
+ XAA_SCREEN_EPILOGUE (pScreen, CopyWindow, XAAOverCopyWindow);
+ return;
+ }
+
+ infoRec->ScratchGC.alu = GXcopy;
+ infoRec->ScratchGC.planemask = ~0;
+
+ REGION_INIT(pScreen, &rgnDst, NullBox, 0);
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
+ REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
+
+ nbox = REGION_NUM_RECTS(&rgnDst);
+ if(nbox &&
+ (pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) {
+
+ pbox = REGION_RECTS(&rgnDst);
+ for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ SWITCH_DEPTH(8);
+ XAADoBitBlt((DrawablePtr)pRoot, (DrawablePtr)pRoot,
+ &(infoRec->ScratchGC), &rgnDst, pptSrc);
+
+ if(pWin->drawable.bitsPerPixel != 8) {
+ SWITCH_DEPTH(pScrn->depth);
+ XAADoBitBlt((DrawablePtr)pRoot, (DrawablePtr)pRoot,
+ &(infoRec->ScratchGC), &rgnDst, pptSrc);
+ }
+
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+
+ REGION_UNINIT(pScreen, &rgnDst);
+
+ if(pWin->drawable.depth == 8) {
+ REGION_INIT(pScreen, &rgnDst, NullBox, 0);
+ miSegregateChildren(pWin, &rgnDst, pScrn->depth);
+ if(REGION_NOTEMPTY(pScreen, &rgnDst)) {
+ REGION_INTERSECT(pScreen, &rgnDst, &rgnDst, prgnSrc);
+ nbox = REGION_NUM_RECTS(&rgnDst);
+ if(nbox &&
+ (pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))){
+
+ pbox = REGION_RECTS(&rgnDst);
+ for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ SWITCH_DEPTH(pScrn->depth);
+ XAADoBitBlt((DrawablePtr)pRoot, (DrawablePtr)pRoot,
+ &(infoRec->ScratchGC), &rgnDst, pptSrc);
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+ }
+ REGION_UNINIT(pScreen, &rgnDst);
+ }
+}
+
+
+static void
+XAAOverPaintWindow(
+ WindowPtr pWin,
+ RegionPtr pRegion,
+ int what
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pScreen);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ ScrnInfoPtr pScrn = infoRec->pScrn;
+
+ if(pScrn->vtSema) {
+ if(what == PW_BACKGROUND) {
+ SWITCH_DEPTH(pWin->drawable.depth);
+ (*infoRec->PaintWindowBackground)(pWin, pRegion, what);
+ return;
+ } else {
+ if(pWin->drawable.bitsPerPixel == 8) {
+ SWITCH_DEPTH(8);
+ (*infoRec->PaintWindowBorder)(pWin, pRegion, what);
+ return;
+ } else if (infoRec->FillSolidRects) {
+ SWITCH_DEPTH(8);
+ (*infoRec->FillSolidRects)(pScrn, pScrn->colorKey, GXcopy,
+ ~0, REGION_NUM_RECTS(pRegion), REGION_RECTS(pRegion));
+
+ SWITCH_DEPTH(pWin->drawable.depth);
+ (*infoRec->PaintWindowBorder)(pWin, pRegion, what);
+ return;
+ }
+ }
+
+ if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ }
+
+ if(what == PW_BACKGROUND) {
+ XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBackground);
+ (*pScreen->PaintWindowBackground) (pWin, pRegion, what);
+ XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBackground, XAAOverPaintWindow);
+ } else {
+ XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBorder);
+ (*pScreen->PaintWindowBorder) (pWin, pRegion, what);
+ XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBorder, XAAOverPaintWindow);
+ }
+}
+
+
+void
+XAAOverWindowExposures(
+ WindowPtr pWin,
+ RegionPtr pReg,
+ RegionPtr pOtherReg
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+
+ if((pWin->drawable.bitsPerPixel != 8) && infoRec->pScrn->vtSema) {
+ if(REGION_NUM_RECTS(pReg) && infoRec->FillSolidRects) {
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pScreen);
+
+ SWITCH_DEPTH(8);
+ (*infoRec->FillSolidRects)(infoRec->pScrn,
+ infoRec->pScrn->colorKey, GXcopy, ~0,
+ REGION_NUM_RECTS(pReg), REGION_RECTS(pReg));
+ miWindowExposures(pWin, pReg, pOtherReg);
+ return;
+ } else if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ }
+
+ XAA_SCREEN_PROLOGUE (pScreen, WindowExposures);
+ (*pScreen->WindowExposures) (pWin, pReg, pOtherReg);
+ XAA_SCREEN_EPILOGUE(pScreen, WindowExposures, XAAOverWindowExposures);
+}
+
+
+static void
+XAAOverSaveAreas (
+ PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pWin->drawable.pScreen);
+ XAAInfoRecPtr infoRec =
+ GET_XAAINFORECPTR_FROM_DRAWABLE((DrawablePtr)pWin);
+
+ if(pOverPriv->pScrn->vtSema) {
+ SWITCH_DEPTH(pWin->drawable.depth);
+ }
+
+ (*infoRec->SaveAreas)(pPixmap, prgnSave, xorg, yorg, pWin);
+}
+
+
+static void
+XAAOverRestoreAreas (
+ PixmapPtr pPixmap,
+ RegionPtr prgnRestore,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pWin->drawable.pScreen);
+ XAAInfoRecPtr infoRec =
+ GET_XAAINFORECPTR_FROM_DRAWABLE((DrawablePtr)pWin);
+
+ if(pOverPriv->pScrn->vtSema) {
+ SWITCH_DEPTH(pWin->drawable.depth);
+ }
+
+ (*infoRec->RestoreAreas)(pPixmap, prgnRestore, xorg, yorg, pWin);
+}
+
+/********************* Choosers *************************/
+
+static int
+XAAOverStippledFillChooser(GCPtr pGC)
+{
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+ int ret;
+
+ ret = (*pOverPriv->StippledFillChooser)(pGC);
+
+ if((pGC->depth == 8) &&
+ ((ret == DO_COLOR_8x8) || (ret == DO_CACHE_BLT))) {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int
+XAAOverOpaqueStippledFillChooser(GCPtr pGC)
+{
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+ int ret;
+
+ ret = (*pOverPriv->OpaqueStippledFillChooser)(pGC);
+
+ if((pGC->depth == 8) &&
+ ((ret == DO_COLOR_8x8) || (ret == DO_CACHE_BLT))) {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int
+XAAOverTiledFillChooser(GCPtr pGC)
+{
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+ int ret;
+
+ ret = (*pOverPriv->TiledFillChooser)(pGC);
+
+ if((pGC->depth == 8) &&
+ ((ret == DO_COLOR_8x8) || (ret == DO_CACHE_BLT))) {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+
+/**************************** GC Functions **************************/
+
+static RegionPtr
+XAAOverCopyArea(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+}
+
+static RegionPtr
+XAAOverCopyPlane(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->CopyPlane)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+
+}
+
+static void
+XAAOverPushPixelsSolid(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy,
+ int xOrg, int yOrg
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PushPixelsSolid)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+}
+
+
+
+static void
+XAAOverPolyFillRectSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyFillRectSolid)(pDraw, pGC, nrectFill, prectInit);
+}
+
+static void
+XAAOverPolyFillRectStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyFillRectStippled)(pDraw, pGC, nrectFill, prectInit);
+}
+
+
+static void
+XAAOverPolyFillRectOpaqueStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyFillRectOpaqueStippled)(pDraw, pGC, nrectFill, prectInit);
+}
+
+static void
+XAAOverPolyFillRectTiled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyFillRectTiled)(pDraw, pGC, nrectFill, prectInit);
+}
+
+
+static void
+XAAOverFillSpansSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillSpansSolid)(
+ pDraw, pGC, nInit, ppt, pwidth, fSorted);
+}
+
+
+static void
+XAAOverFillSpansStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillSpansStippled)(pDraw, pGC, nInit, ppt, pwidth, fSorted);
+}
+
+static void
+XAAOverFillSpansOpaqueStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillSpansOpaqueStippled)(
+ pDraw, pGC, nInit, ppt, pwidth, fSorted);
+}
+
+
+static void
+XAAOverFillSpansTiled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillSpansTiled)(pDraw, pGC, nInit, ppt, pwidth, fSorted);
+}
+
+static int
+XAAOverPolyText8TE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->PolyText8TE)(pDraw, pGC, x, y, count, chars);
+}
+
+
+static int
+XAAOverPolyText16TE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->PolyText16TE)(pDraw, pGC, x, y, count, chars);
+}
+
+
+static void
+XAAOverImageText8TE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageText8TE)(pDraw, pGC, x, y, count, chars);
+}
+
+
+static void
+XAAOverImageText16TE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageText16TE)(pDraw, pGC, x, y, count, chars);
+}
+
+static void
+XAAOverImageGlyphBltTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageGlyphBltTE)(
+ pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
+}
+
+static void
+XAAOverPolyGlyphBltTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyGlyphBltTE)(
+ pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
+}
+
+static int
+XAAOverPolyText8NonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->PolyText8NonTE)(pDraw, pGC, x, y, count, chars);
+}
+
+
+static int
+XAAOverPolyText16NonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->PolyText16NonTE)(pDraw, pGC, x, y, count, chars);
+}
+
+static void
+XAAOverImageText8NonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageText8NonTE)(pDraw, pGC, x, y, count, chars);
+}
+
+static void
+XAAOverImageText16NonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageText16NonTE)(pDraw, pGC, x, y, count, chars);
+}
+
+
+static void
+XAAOverImageGlyphBltNonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageGlyphBltNonTE)(
+ pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
+}
+
+static void
+XAAOverPolyGlyphBltNonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyGlyphBltNonTE)(
+ pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
+}
+
+static void
+XAAOverPolyRectangleThinSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyRectangleThinSolid)(pDraw, pGC, nRectsInit, pRectsInit);
+}
+
+
+
+static void
+XAAOverPolylinesWideSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolylinesWideSolid)(pDraw, pGC, mode, npt, pPts);
+}
+
+
+static void
+XAAOverPolylinesThinSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolylinesThinSolid)(pDraw, pGC, mode, npt, pPts);
+}
+
+static void
+XAAOverPolySegmentThinSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolySegmentThinSolid)(pDraw, pGC, nseg, pSeg);
+}
+
+static void
+XAAOverPolylinesThinDashed(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolylinesThinDashed)(pDraw, pGC, mode, npt, pPts);
+}
+
+static void
+XAAOverPolySegmentThinDashed(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolySegmentThinDashed)(pDraw, pGC, nseg, pSeg);
+}
+
+
+static void
+XAAOverFillPolygonSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillPolygonSolid)(pDraw, pGC, shape, mode, count, ptsIn);
+}
+
+static void
+XAAOverFillPolygonStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillPolygonStippled)(pDraw, pGC, shape, mode, count, ptsIn);
+}
+
+
+static void
+XAAOverFillPolygonOpaqueStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillPolygonOpaqueStippled)(
+ pDraw, pGC, shape, mode, count, ptsIn);
+}
+
+static void
+XAAOverFillPolygonTiled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillPolygonTiled)(pDraw, pGC, shape, mode, count, ptsIn);
+}
+
+
+static void
+XAAOverPolyFillArcSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyFillArcSolid)(pDraw, pGC, narcs, parcs);
+}
+
+
+static void
+XAAOverPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PutImage)(pDraw, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaPCache.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaPCache.c
new file mode 100644
index 000000000..1b8382755
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaPCache.c
@@ -0,0 +1,2352 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaPCache.c,v 1.21 1999/08/22 05:57:39 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "gc.h"
+#include "mi.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "regionstr.h"
+#include "servermd.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+
+#define MAX_COLOR 32
+#define MAX_MONO 32
+#define MAX_8 32
+#define MAX_128 32
+#define MAX_256 32
+#define MAX_512 16
+
+static int CacheInitIndex = -1;
+#define CACHEINIT(p) ((p)->privates[CacheInitIndex].val)
+
+
+typedef struct _CacheLink {
+ int x;
+ int y;
+ int w;
+ int h;
+ struct _CacheLink *next;
+} CacheLink, *CacheLinkPtr;
+
+
+static void
+TransferList(CacheLinkPtr list, XAACacheInfoPtr array, int num)
+{
+ while(num--) {
+ array->x = list->x;
+ array->y = list->y;
+ array->w = list->w;
+ array->h = list->h;
+ array->serialNumber = 0;
+ array->fg = array->bg = -1;
+ list = list->next;
+ array++;
+ }
+}
+
+
+
+static CacheLinkPtr
+Enlist(CacheLinkPtr link, int x, int y, int w, int h)
+{
+ CacheLinkPtr newLink;
+
+ newLink = xalloc(sizeof(CacheLink));
+ newLink->next = link;
+ newLink->x = x; newLink->y = y;
+ newLink->w = w; newLink->h = h;
+ return newLink;
+}
+
+
+
+static CacheLinkPtr
+Delist(CacheLinkPtr link) {
+ CacheLinkPtr ret = NULL;
+
+ if(link) {
+ ret = link->next;
+ xfree(link);
+ }
+ return ret;
+}
+
+
+
+static void
+FreeList(CacheLinkPtr link) {
+ CacheLinkPtr tmp;
+
+ while(link) {
+ tmp = link;
+ link = link->next;
+ xfree(tmp);
+ }
+}
+
+
+
+static CacheLinkPtr
+QuadLinks(CacheLinkPtr big, CacheLinkPtr little)
+{
+ /* CAUTION: This doesn't free big */
+ int w1, w2, h1, h2;
+
+ while(big) {
+ w1 = big->w >> 1;
+ w2 = big->w - w1;
+ h1 = big->h >> 1;
+ h2 = big->h - h1;
+
+ little = Enlist(little, big->x, big->y, w1, h1);
+ little = Enlist(little, big->x + w1, big->y, w2, h1);
+ little = Enlist(little, big->x, big->y + h1, w1, h2);
+ little = Enlist(little, big->x + w1, big->y + h1, w2, h2);
+
+ big = big->next;
+ }
+ return little;
+}
+
+
+static void
+SubdivideList(CacheLinkPtr *large, CacheLinkPtr *small)
+{
+ CacheLinkPtr big = *large;
+ CacheLinkPtr little = *small;
+ int size = big->w >> 1;
+
+ little = Enlist(little, big->x, big->y, size, size);
+ little = Enlist(little, big->x + size, big->y, size, size);
+ little = Enlist(little, big->x, big->y + size, size, size);
+ little = Enlist(little, big->x + size, big->y + size, size, size);
+ *small = little;
+ big = Delist(big);
+ *large = big;
+}
+
+static void
+FreePixmapCachePrivate(XAAPixmapCachePrivatePtr pPriv)
+{
+ if(!pPriv) return;
+
+ if(pPriv->Info512)
+ xfree(pPriv->Info512);
+ if(pPriv->Info256)
+ xfree(pPriv->Info256);
+ if(pPriv->Info128)
+ xfree(pPriv->Info128);
+ if(pPriv->InfoColor)
+ xfree(pPriv->InfoColor);
+ if(pPriv->InfoMono)
+ xfree(pPriv->InfoMono);
+ if(pPriv->InfoPartial)
+ xfree(pPriv->InfoPartial);
+
+ xfree(pPriv);
+}
+
+void
+XAAClosePixmapCache(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+
+ if(infoRec->PixmapCachePrivate)
+ FreePixmapCachePrivate(
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate);
+
+ infoRec->PixmapCachePrivate = NULL;
+}
+
+
+
+static CacheLinkPtr
+ThinOutPartials(
+ CacheLinkPtr ListPartial,
+ int *num, int *maxw, int *maxh
+) {
+/* This guy's job is to get at least 4 big slots out of a list of fragments */
+
+ CacheLinkPtr List64, List32, List16, List8, pCur, next, ListKeepers;
+ int Num64, Num32, Num16, Num8, NumKeepers;
+ int w, h;
+
+ List64 = List32 = List16 = List8 = ListKeepers = NULL;
+ Num64 = Num32 = Num16 = Num8 = NumKeepers = 0;
+ w = h = 0;
+
+ /* We sort partials by how large a square tile they can cache.
+ If a partial can't store a 64x64, 32x32, 16x16 or 8x8 tile,
+ we free it. */
+
+ pCur = ListPartial;
+ while(pCur) {
+ next = pCur->next;
+ if((pCur->w >= 64) && (pCur->h >= 64)) {
+ pCur->next = List64; List64 = pCur;
+ Num64++;
+ } else
+ if((pCur->w >= 32) && (pCur->h >= 32)) {
+ pCur->next = List32; List32 = pCur;
+ Num32++;
+ } else
+ if((pCur->w >= 16) && (pCur->h >= 16)) {
+ pCur->next = List16; List16 = pCur;
+ Num16++;
+ } else
+ if((pCur->w >= 8) && (pCur->h >= 8)) {
+ pCur->next = List8; List8 = pCur;
+ Num8++;
+ } else {
+ xfree(pCur);
+ }
+
+ pCur = next;
+ }
+
+ /* We save all the tiles from the largest bin that we can get
+ at least 4 of. If there are too few of a bigger slot, we
+ cut it in fourths to make smaller slots. */
+
+ if(Num64 >= 4) {
+ ListKeepers = List64; List64 = NULL;
+ NumKeepers = Num64;
+ goto GOT_EM;
+ } else if(Num64) {
+ List32 = QuadLinks(List64, List32);
+ Num32 += Num64 * 4;
+ Num64 = 0;
+ }
+
+ if(Num32 >= 4) {
+ ListKeepers = List32; List32 = NULL;
+ NumKeepers = Num32;
+ goto GOT_EM;
+ } else if(Num32) {
+ List16 = QuadLinks(List32, List16);
+ Num16 += Num32 * 4;
+ Num32 = 0;
+ }
+
+ if(Num16 >= 4) {
+ ListKeepers = List16; List16 = NULL;
+ NumKeepers = Num16;
+ goto GOT_EM;
+ } else if(Num16) {
+ List8 = QuadLinks(List16, List8);
+ Num8 += Num16 * 4;
+ Num16 = 0;
+ }
+
+ if(Num8 >= 4) {
+ ListKeepers = List8; List8 = NULL;
+ NumKeepers = Num8;
+ goto GOT_EM;
+ }
+
+GOT_EM:
+
+ /* Free the ones we aren't using */
+
+ if(List64) FreeList(List64);
+ if(List32) FreeList(List32);
+ if(List16) FreeList(List16);
+ if(List8) FreeList(List8);
+
+
+ /* Enlarge the slots if we can */
+
+ if(ListKeepers) {
+ CacheLinkPtr pLink = ListKeepers;
+ w = h = 128;
+
+ while(pLink) {
+ if(pLink->w < w) w = pLink->w;
+ if(pLink->h < h) h = pLink->h;
+ pLink = pLink->next;
+ }
+ }
+
+ *maxw = w;
+ *maxh = h;
+ *num = NumKeepers;
+ return ListKeepers;
+}
+
+static void
+ConvertColorToMono(
+ CacheLinkPtr *ColorList,
+ int ColorW, int ColorH,
+ CacheLinkPtr *MonoList,
+ int MonoW, int MonoH
+){
+ int x, y, w;
+
+ x = (*ColorList)->x; y = (*ColorList)->y;
+ *ColorList = Delist(*ColorList);
+
+ while(ColorH) {
+ ColorH -= MonoH;
+ for(w = 0; w <= (ColorW - MonoW); w += MonoW)
+ *MonoList = Enlist(*MonoList, x + w, y + ColorH, MonoW, MonoH);
+ }
+}
+
+static void
+ConvertAllPartialsTo8x8(
+ int *NumMono, int *NumColor,
+ CacheLinkPtr ListPartial,
+ CacheLinkPtr *ListMono,
+ CacheLinkPtr *ListColor,
+ XAAInfoRecPtr infoRec
+){
+/* This guy extracts as many 8x8 slots as it can out of fragments */
+
+ int ColorH = infoRec->CacheHeightColor8x8Pattern;
+ int ColorW = infoRec->CacheWidthColor8x8Pattern;
+ int MonoH = infoRec->CacheHeightMono8x8Pattern;
+ int MonoW = infoRec->CacheWidthMono8x8Pattern;
+ int x, y, w, Height, Width;
+ Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
+ Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
+ CacheLinkPtr pLink = ListPartial;
+ CacheLinkPtr MonoList = *ListMono, ColorList = *ListColor;
+ int MonosPerColor = 1;
+
+ if(DoColor && DoMono) {
+ /* we assume color patterns take more space than color ones */
+ if(MonoH > ColorH) ColorH = MonoH;
+ if(MonoW > ColorW) ColorW = MonoW;
+ MonosPerColor = (ColorH/MonoH) * (ColorW/MonoW);
+ }
+
+ /* Break up the area into as many Color and Mono slots as we can */
+
+ while(pLink) {
+ Height = pLink->h;
+ Width = pLink->w;
+ x = pLink->x;
+ y = pLink->y;
+
+ if(DoColor) {
+ while(Height >= ColorH) {
+ Height -= ColorH;
+ for(w = 0; w <= (Width - ColorW); w += ColorW) {
+ ColorList = Enlist(
+ ColorList, x + w, y + Height, ColorW, ColorH);
+ (*NumColor)++;
+ }
+ }
+ }
+
+ if(DoMono && (Height >= MonoH)) {
+ while(Height >= MonoH) {
+ Height -= MonoH;
+ for(w = 0; w <= (Width - MonoW); w += MonoW) {
+ MonoList = Enlist(
+ MonoList, x + w, y + Height, MonoW, MonoH);
+ (*NumMono)++;
+ }
+ }
+ }
+
+ pLink = pLink->next;
+ }
+
+
+ *ListMono = MonoList;
+ *ListColor = ColorList;
+ FreeList(ListPartial);
+}
+
+
+static CacheLinkPtr
+ExtractOneThatFits(CacheLinkPtr *initList, int w, int h)
+{
+ CacheLinkPtr list = *initList;
+ CacheLinkPtr prev = NULL;
+
+ while(list) {
+ if((list->w >= w) && (list->h >= h))
+ break;
+ prev = list;
+ list = list->next;
+ }
+
+ if(list) {
+ if(prev)
+ prev->next = list->next;
+ else
+ *initList = list->next;
+
+ list->next = NULL;
+ }
+
+ return list;
+}
+
+
+static CacheLinkPtr
+ConvertSomePartialsTo8x8(
+ int *NumMono, int *NumColor, int *NumPartial,
+ CacheLinkPtr ListPartial,
+ CacheLinkPtr *ListMono,
+ CacheLinkPtr *ListColor,
+ int *maxw, int *maxh,
+ XAAInfoRecPtr infoRec
+){
+/* This guy tries to get 4 of each type of 8x8 slot requested out of
+ a list of fragments all while trying to retain some big fragments
+ for the cache blits */
+
+ int ColorH = infoRec->CacheHeightColor8x8Pattern;
+ int ColorW = infoRec->CacheWidthColor8x8Pattern;
+ int MonoH = infoRec->CacheHeightMono8x8Pattern;
+ int MonoW = infoRec->CacheWidthMono8x8Pattern;
+ Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
+ Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
+ CacheLinkPtr List64, List32, List16, List8, pCur, next, ListKeepers;
+ CacheLinkPtr MonoList = *ListMono, ColorList = *ListColor;
+ int Num64, Num32, Num16, Num8, NumKeepers;
+ int w, h, Width, Height;
+ int MonosPerColor = 1;
+
+ if(DoColor && DoMono) {
+ /* we assume color patterns take more space than color ones */
+ if(MonoH > ColorH) ColorH = MonoH;
+ if(MonoW > ColorW) ColorW = MonoW;
+ MonosPerColor = (ColorH/MonoH) * (ColorW/MonoW);
+ }
+
+ List64 = List32 = List16 = List8 = ListKeepers = MonoList = ColorList = NULL;
+ Num64 = Num32 = Num16 = Num8 = NumKeepers = 0;
+ Width = Height = 0;
+
+ /* We sort partials by how large a square tile they can cache.
+ We make 8x8 patterns from the leftovers if we can. */
+
+ pCur = ListPartial;
+ while(pCur) {
+ next = pCur->next;
+ if((pCur->w >= 64) && (pCur->h >= 64)) {
+ pCur->next = List64; List64 = pCur;
+ Num64++;
+ } else
+ if((pCur->w >= 32) && (pCur->h >= 32)) {
+ pCur->next = List32; List32 = pCur;
+ Num32++;
+ } else
+ if((pCur->w >= 16) && (pCur->h >= 16)) {
+ pCur->next = List16; List16 = pCur;
+ Num16++;
+ } else
+ if((pCur->w >= 8) && (pCur->h >= 8)) {
+ pCur->next = List8; List8 = pCur;
+ Num8++;
+ } else {
+ h = pCur->h;
+ if(DoColor && (pCur->w >= ColorW) && (h >= ColorH)) {
+ while(h >= ColorH) {
+ h -= ColorH;
+ for(w = 0; w <= (pCur->w - ColorW); w += ColorW) {
+ ColorList = Enlist( ColorList,
+ pCur->x + w, pCur->y + h, ColorW, ColorH);
+ (*NumColor)++;
+ }
+ }
+ }
+ if(DoMono && (pCur->w >= MonoW) && (h >= MonoH)) {
+ while(h >= MonoH) {
+ h -= MonoH;
+ for(w = 0; w <= (pCur->w - MonoW); w += MonoW) {
+ MonoList = Enlist( MonoList,
+ pCur->x + w, pCur->y + h, MonoW, MonoH);
+ (*NumMono)++;
+ }
+ }
+ }
+ xfree(pCur);
+ }
+
+ pCur = next;
+ }
+
+ /* Try to extract at least 4 of each type of 8x8 slot that we need */
+
+ if(DoColor) {
+ CacheLinkPtr theOne;
+ while(*NumColor < 4) {
+ theOne = NULL;
+ if(Num8) {
+ if((theOne = ExtractOneThatFits(&List8, ColorW, ColorH)))
+ Num8--;
+ }
+ if(Num16 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List16, ColorW, ColorH)))
+ Num16--;
+ }
+ if(Num32 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List32, ColorW, ColorH)))
+ Num32--;
+ }
+ if(Num64 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List64, ColorW, ColorH)))
+ Num64--;
+ }
+
+ if(!theOne) break;
+
+
+ ConvertAllPartialsTo8x8(NumMono, NumColor, theOne,
+ &MonoList, &ColorList, infoRec);
+
+ if(DoMono) {
+ while(*NumColor && (*NumMono < 4)) {
+ ConvertColorToMono(&ColorList, ColorW, ColorH,
+ &MonoList, MonoW, MonoH);
+ (*NumColor)--; *NumMono += MonosPerColor;
+ }
+ }
+ }
+ }
+
+ if(DoMono) {
+ CacheLinkPtr theOne;
+ while(*NumMono < 4) {
+ theOne = NULL;
+ if(Num8) {
+ if((theOne = ExtractOneThatFits(&List8, MonoW, MonoH)))
+ Num8--;
+ }
+ if(Num16 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List16, MonoW, MonoH)))
+ Num16--;
+ }
+ if(Num32 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List32, MonoW, MonoH)))
+ Num32--;
+ }
+ if(Num64 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List64, MonoW, MonoH)))
+ Num64--;
+ }
+
+ if(!theOne) break;
+
+ ConvertAllPartialsTo8x8(NumMono, NumColor, theOne,
+ &MonoList, &ColorList, infoRec);
+ }
+ }
+
+ /* We save all the tiles from the largest bin that we can get
+ at least 4 of. If there are too few of a bigger slot, we
+ cut it in fourths to make smaller slots. */
+
+ if(Num64 >= 4) {
+ ListKeepers = List64; List64 = NULL;
+ NumKeepers = Num64;
+ goto GOT_EM;
+ } else if(Num64) {
+ List32 = QuadLinks(List64, List32);
+ Num32 += Num64 * 4;
+ Num64 = 0;
+ }
+
+ if(Num32 >= 4) {
+ ListKeepers = List32; List32 = NULL;
+ NumKeepers = Num32;
+ goto GOT_EM;
+ } else if(Num32) {
+ List16 = QuadLinks(List32, List16);
+ Num16 += Num32 * 4;
+ Num32 = 0;
+ }
+
+ if(Num16 >= 4) {
+ ListKeepers = List16; List16 = NULL;
+ NumKeepers = Num16;
+ goto GOT_EM;
+ } else if(Num16) {
+ List8 = QuadLinks(List16, List8);
+ Num8 += Num16 * 4;
+ Num16 = 0;
+ }
+
+ if(Num8 >= 4) {
+ ListKeepers = List8; List8 = NULL;
+ NumKeepers = Num8;
+ goto GOT_EM;
+ }
+
+GOT_EM:
+
+ /* Free the ones we aren't using */
+
+ if(List64)
+ ConvertAllPartialsTo8x8(NumMono, NumColor, List64,
+ &MonoList, &ColorList, infoRec);
+ if(List32)
+ ConvertAllPartialsTo8x8(NumMono, NumColor, List32,
+ &MonoList, &ColorList, infoRec);
+ if(List16)
+ ConvertAllPartialsTo8x8(NumMono, NumColor, List16,
+ &MonoList, &ColorList, infoRec);
+ if(List8)
+ ConvertAllPartialsTo8x8(NumMono, NumColor, List8,
+ &MonoList, &ColorList, infoRec);
+
+
+ /* Enlarge the slots if we can */
+
+ if(ListKeepers) {
+ CacheLinkPtr pLink = ListKeepers;
+ Width = Height = 128;
+
+ while(pLink) {
+ if(pLink->w < Width) Width = pLink->w;
+ if(pLink->h < Height) Height = pLink->h;
+ pLink = pLink->next;
+ }
+ }
+
+ *ListMono = MonoList;
+ *ListColor = ColorList;
+ *maxw = Width;
+ *maxh = Height;
+ *NumPartial = NumKeepers;
+ return ListKeepers;
+}
+
+
+void
+XAAInitPixmapCache(
+ ScreenPtr pScreen,
+ RegionPtr areas,
+ pointer data
+) {
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAInfoRecPtr infoRec = (XAAInfoRecPtr)data;
+ XAAPixmapCachePrivatePtr pCachePriv;
+ BoxPtr pBox = REGION_RECTS(areas);
+ int nBox = REGION_NUM_RECTS(areas);
+ int Num512, Num256, Num128, NumPartial, NumColor, NumMono;
+ int Target512, Target256;
+ CacheLinkPtr List512, List256, List128, ListPartial, ListColor, ListMono;
+ int x, y, w, h, ntotal, granularity, width, height, i;
+ int MaxPartialWidth, MaxPartialHeight;
+
+ infoRec->MaxCacheableTileWidth = 0;
+ infoRec->MaxCacheableTileHeight = 0;
+ infoRec->MaxCacheableStippleHeight = 0;
+ infoRec->MaxCacheableStippleWidth = 0;
+ infoRec->UsingPixmapCache = FALSE;
+
+
+ if(!nBox || !pBox || !(infoRec->Flags & PIXMAP_CACHE))
+ return;
+
+ /* Allocate a persistent per-screen init flag to control messages */
+ if (CacheInitIndex < 0)
+ CacheInitIndex = xf86AllocateScrnInfoPrivateIndex();
+
+ /* free the old private data if it exists */
+ if(infoRec->PixmapCachePrivate) {
+ FreePixmapCachePrivate(
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate);
+ infoRec->PixmapCachePrivate = NULL;
+ }
+
+ Num512 = Num256 = Num128 = NumPartial = NumMono = NumColor = 0;
+ List512 = List256 = List128 = ListPartial = ListMono = ListColor = NULL;
+ granularity = infoRec->CachePixelGranularity;
+ if(granularity <= 1) granularity = 0;
+
+ /* go through the boxes and break it into as many pieces as we can fit */
+
+ while(nBox--) {
+ x = pBox->x1;
+ if(granularity) {
+ int tmp = x % granularity;
+ if(tmp) x += (granularity - tmp);
+ }
+ width = pBox->x2 - x;
+ if(width <= 0) {pBox++; continue;}
+
+ y = pBox->y1;
+ height = pBox->y2 - y;
+
+ for(h = 0; h <= (height - 512); h += 512) {
+ for(w = 0; w <= (width - 512); w += 512) {
+ List512 = Enlist(List512, x + w, y + h, 512, 512);
+ Num512++;
+ }
+ for(; w <= (width - 256); w += 256) {
+ List256 = Enlist(List256, x + w, y + h, 256, 256);
+ List256 = Enlist(List256, x + w, y + h + 256, 256, 256);
+ Num256 += 2;
+ }
+ for(; w <= (width - 128); w += 128) {
+ List128 = Enlist(List128, x + w, y + h, 128, 128);
+ List128 = Enlist(List128, x + w, y + h + 128, 128, 128);
+ List128 = Enlist(List128, x + w, y + h + 256, 128, 128);
+ List128 = Enlist(List128, x + w, y + h + 384, 128, 128);
+ Num128 += 4;
+ }
+ if(w < width) {
+ int d = width - w;
+ ListPartial = Enlist(ListPartial, x + w, y + h, d, 128);
+ ListPartial = Enlist(ListPartial, x + w, y + h + 128, d, 128);
+ ListPartial = Enlist(ListPartial, x + w, y + h + 256, d, 128);
+ ListPartial = Enlist(ListPartial, x + w, y + h + 384, d, 128);
+ NumPartial += 4;
+ }
+ }
+ for(; h <= (height - 256); h += 256) {
+ for(w = 0; w <= (width - 256); w += 256) {
+ List256 = Enlist(List256, x + w, y + h, 256, 256);
+ Num256++;
+ }
+ for(; w <= (width - 128); w += 128) {
+ List128 = Enlist(List128, x + w, y + h, 128, 128);
+ List128 = Enlist(List128, x + w, y + h + 128, 128, 128);
+ Num128 += 2;
+ }
+ if(w < width) {
+ int d = width - w;
+ ListPartial = Enlist(ListPartial, x + w, y + h, d, 128);
+ ListPartial = Enlist(ListPartial, x + w, y + h + 128, d, 128);
+ NumPartial += 2;
+ }
+ }
+ for(; h <= (height - 128); h += 128) {
+ for(w = 0; w <= (width - 128); w += 128) {
+ List128 = Enlist(List128, x + w, y + h, 128, 128);
+ Num128++;
+ }
+ if(w < width) {
+ ListPartial = Enlist(
+ ListPartial, x + w, y + h, width - w, 128);
+ NumPartial++;
+ }
+ }
+ if(h < height) {
+ int d = height - h;
+ for(w = 0; w <= (width - 128); w += 128) {
+ ListPartial = Enlist(ListPartial, x + w, y + h, 128, d);
+ NumPartial++;
+ }
+ if(w < width) {
+ ListPartial = Enlist(ListPartial, x + w, y + h, width - w, d);
+ NumPartial++;
+ }
+ }
+ pBox++;
+ }
+
+
+/*
+ by this point we've carved the space into as many 512x512, 256x256
+ and 128x128 blocks as we could fit. We will then break larger
+ blocks into smaller ones if we need to. The rules are as follows:
+
+ 512x512 -
+ 1) Don't take up more than half the memory.
+ 2) Don't bother if you can't get at least four.
+ 3) Don't make more than MAX_512.
+
+ 256x256 -
+ 1) Don't take up more than a quarter of the memory enless there
+ aren't any 512x512s. Then we can take up to half.
+ 2) Don't bother if you can't get at least four.
+ 3) Don't make more than MAX_256.
+
+ 128x128 -
+ 1) Don't make more than MAX_128.
+
+ We don't bother with the partial blocks unless we can use them
+ for 8x8 pattern fills or we are short on larger blocks.
+
+*/
+
+ ntotal = Num128 + (Num256<<2) + (Num512<<4);
+
+ Target512 = ntotal >> 5;
+ if(Target512 < 4) Target512 = 0;
+ if(!Target512) Target256 = ntotal >> 3;
+ else Target256 = ntotal >> 4;
+ if(Target256 < 4) Target256 = 0;
+
+
+ if(!Num512) { /* no room */
+ } else if((Num512 < 4) || (!Target512)) {
+ while(Num512) {
+ SubdivideList(&List512, &List256);
+ Num256 += 4; Num512--;
+ }
+ } else if(Num512 > MAX_512) {
+ while(Num512 > MAX_512) {
+ SubdivideList(&List512, &List256);
+ Num256 += 4; Num512--;
+ }
+ } else {
+ while(Num512 > Target512) {
+ if(Num256 < MAX_256) {
+ SubdivideList(&List512, &List256);
+ Num256 += 4; Num512--;
+ } else break;
+ }
+ }
+
+ if(!Num256) { /* no room */
+ } else if((Num256 < 4) || (!Target256)) {
+ while(Num256) {
+ SubdivideList(&List256, &List128);
+ Num128 += 4; Num256--;
+ }
+ } else if(Num256 > MAX_256) {
+ while(Num256 > MAX_256) {
+ SubdivideList(&List256, &List128);
+ Num128 += 4; Num256--;
+ }
+ } else {
+ while(Num256 > Target256) {
+ if(Num128 < MAX_128) {
+ SubdivideList(&List256, &List128);
+ Num128 += 4; Num256--;
+ } else break;
+ }
+ }
+
+ if(Num128 && ((Num128 < 4) || (Num128 > MAX_128))) {
+ CacheLinkPtr next;
+ int max = (Num128 > MAX_128) ? MAX_128 : 0;
+
+ while(Num128 > max) {
+ next = List128->next;
+ List128->next = ListPartial; ListPartial = List128;
+ List128 = next;
+ NumPartial++; Num128--;
+ }
+ }
+
+
+ MaxPartialHeight = MaxPartialWidth = 0;
+
+ /* at this point we have as many 512x512 and 256x256 slots as we
+ want but may have an excess of 128x128 slots. We still need
+ to find out if we need 8x8 slots. We take these from the
+ partials if we have them. Otherwise, we break some 128x128's */
+
+ if(!(infoRec->PixmapCacheFlags & (CACHE_MONO_8x8 | CACHE_COLOR_8x8))) {
+ if(NumPartial) {
+ if(Num128) { /* don't bother with partials */
+ FreeList(ListPartial);
+ NumPartial = 0; ListPartial = NULL;
+ } else {
+ /* We have no big slots. Weed out the unusable partials */
+ ListPartial = ThinOutPartials(ListPartial, &NumPartial,
+ &MaxPartialWidth, &MaxPartialHeight);
+ }
+ }
+ } else {
+ int MonosPerColor = 1;
+ int ColorH = infoRec->CacheHeightColor8x8Pattern;
+ int ColorW = infoRec->CacheWidthColor8x8Pattern;
+ int MonoH = infoRec->CacheHeightMono8x8Pattern;
+ int MonoW = infoRec->CacheWidthMono8x8Pattern;
+ Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
+ Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
+
+ if(DoColor) infoRec->CanDoColor8x8 = FALSE;
+ if(DoMono) infoRec->CanDoMono8x8 = FALSE;
+
+ if(DoColor && DoMono) {
+ /* we assume color patterns take more space than color ones */
+ if(MonoH > ColorH) ColorH = MonoH;
+ if(MonoW > ColorW) ColorW = MonoW;
+ MonosPerColor = (ColorH/MonoH) * (ColorW/MonoW);
+ }
+
+ if(Num128) {
+ if(NumPartial) { /* use all for 8x8 slots */
+ ConvertAllPartialsTo8x8(&NumMono, &NumColor,
+ ListPartial, &ListMono, &ListColor, infoRec);
+ NumPartial = 0; ListPartial = NULL;
+ }
+
+ /* Get some 8x8 slots from the 128 slots */
+ while((Num128 > 4) &&
+ ((NumMono < MAX_MONO) && (NumColor < MAX_COLOR))) {
+ CacheLinkPtr tmp = NULL;
+
+ tmp = Enlist(tmp, List128->x, List128->y,
+ List128->w, List128->h);
+ List128 = Delist(List128);
+ Num128--;
+
+ ConvertAllPartialsTo8x8(&NumMono, &NumColor,
+ tmp, &ListMono, &ListColor, infoRec);
+ }
+ } else if(NumPartial) {
+ /* We have share partials between 8x8 slots and tiles. */
+ ListPartial = ConvertSomePartialsTo8x8(&NumMono, &NumColor,
+ &NumPartial, ListPartial, &ListMono, &ListColor,
+ &MaxPartialWidth, &MaxPartialHeight, infoRec);
+ }
+
+
+ if(DoMono && DoColor) {
+ if(NumColor && ((NumColor > MAX_COLOR) || (NumColor < 4))) {
+ int max = (NumColor > MAX_COLOR) ? MAX_COLOR : 0;
+
+ while(NumColor > max) {
+ ConvertColorToMono(&ListColor, ColorW, ColorH,
+ &ListMono, MonoW, MonoH);
+ NumColor--; NumMono += MonosPerColor;
+ }
+ }
+
+ /* favor Mono slots over Color ones */
+ while((NumColor > 4) && (NumMono < MAX_MONO)) {
+ ConvertColorToMono(&ListColor, ColorW, ColorH,
+ &ListMono, MonoW, MonoH);
+ NumColor--; NumMono += MonosPerColor;
+ }
+ }
+
+ if(NumMono && ((NumMono > MAX_MONO) || (NumMono < 4))) {
+ int max = (NumMono > MAX_MONO) ? MAX_MONO : 0;
+
+ while(NumMono > max) {
+ ListMono = Delist(ListMono);
+ NumMono--;
+ }
+ }
+ if(NumColor && ((NumColor > MAX_COLOR) || (NumColor < 4))) {
+ int max = (NumColor > MAX_COLOR) ? MAX_COLOR : 0;
+
+ while(NumColor > max) {
+ ListColor = Delist(ListColor);
+ NumColor--;
+ }
+ }
+ }
+
+
+ pCachePriv = xcalloc(1,sizeof(XAAPixmapCachePrivate));
+ if(!pCachePriv) {
+ if(Num512) FreeList(List512);
+ if(Num256) FreeList(List256);
+ if(Num128) FreeList(List128);
+ if(NumPartial) FreeList(ListPartial);
+ if(NumColor) FreeList(ListColor);
+ if(NumMono) FreeList(ListMono);
+ return;
+ }
+
+ infoRec->PixmapCachePrivate = (char*)pCachePriv;
+
+ if(Num512) {
+ pCachePriv->Info512 = xcalloc(Num512,sizeof(XAACacheInfoRec));
+ if(!pCachePriv->Info512) Num512 = 0;
+ if(Num512) TransferList(List512, pCachePriv->Info512, Num512);
+ FreeList(List512);
+ pCachePriv->Num512x512 = Num512;
+ }
+ if(Num256) {
+ pCachePriv->Info256 = xcalloc(Num256, sizeof(XAACacheInfoRec));
+ if(!pCachePriv->Info256) Num256 = 0;
+ if(Num256) TransferList(List256, pCachePriv->Info256, Num256);
+ FreeList(List256);
+ pCachePriv->Num256x256 = Num256;
+ }
+ if(Num128) {
+ pCachePriv->Info128 = xcalloc(Num128, sizeof(XAACacheInfoRec));
+ if(!pCachePriv->Info128) Num128 = 0;
+ if(Num128) TransferList(List128, pCachePriv->Info128, Num128);
+ FreeList(List128);
+ pCachePriv->Num128x128 = Num128;
+ }
+
+ if(NumPartial) {
+ pCachePriv->InfoPartial = xcalloc(NumPartial, sizeof(XAACacheInfoRec));
+ if(!pCachePriv->InfoPartial) NumPartial = 0;
+ if(NumPartial)
+ TransferList(ListPartial, pCachePriv->InfoPartial, NumPartial);
+ FreeList(ListPartial);
+ pCachePriv->NumPartial = NumPartial;
+ }
+
+ if(NumColor) {
+ pCachePriv->InfoColor = xcalloc(NumColor, sizeof(XAACacheInfoRec));
+ if(!pCachePriv->InfoColor) NumColor = 0;
+ if(NumColor) TransferList(ListColor, pCachePriv->InfoColor, NumColor);
+ FreeList(ListColor);
+ pCachePriv->NumColor = NumColor;
+ }
+
+ if(NumMono) {
+ pCachePriv->InfoMono = xcalloc(NumMono, sizeof(XAACacheInfoRec));
+ if(!pCachePriv->InfoMono) NumMono = 0;
+ if(NumMono) TransferList(ListMono, pCachePriv->InfoMono, NumMono);
+ FreeList(ListMono);
+ pCachePriv->NumMono = NumMono;
+ }
+
+
+ if(NumPartial) {
+ infoRec->MaxCacheableTileWidth = MaxPartialWidth;
+ infoRec->MaxCacheableTileHeight = MaxPartialHeight;
+ }
+ if(Num128)
+ infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 128;
+ if(Num256)
+ infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 256;
+ if(Num512)
+ infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 512;
+
+
+ infoRec->MaxCacheableStippleHeight = infoRec->MaxCacheableTileHeight;
+ infoRec->MaxCacheableStippleWidth =
+ infoRec->MaxCacheableTileWidth * pScrn->bitsPerPixel;
+ if(infoRec->ScreenToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP)
+ infoRec->MaxCacheableStippleWidth /= 3;
+
+ if(NumMono) {
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ (HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS))) {
+ int numPerLine =
+ infoRec->CacheWidthMono8x8Pattern/infoRec->MonoPatternPitch;
+
+ for(i = 0; i < 64; i++) {
+ pCachePriv->MonoOffsets[i].y = i/numPerLine;
+ pCachePriv->MonoOffsets[i].x = (i % numPerLine) *
+ infoRec->MonoPatternPitch;
+ }
+ }
+ infoRec->CanDoMono8x8 = TRUE;
+ }
+ if(NumColor) {
+ if(!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
+
+ for(i = 0; i < 64; i++) {
+ pCachePriv->ColorOffsets[i].y = i & 0x07;
+ pCachePriv->ColorOffsets[i].x = i & ~0x07;
+ }
+ }
+ infoRec->CanDoColor8x8 = TRUE;
+ }
+
+ if(!CACHEINIT(pScrn)) {
+ xf86ErrorF("\tSetting up tile and stipple cache:\n");
+ if(NumPartial)
+ xf86ErrorF("\t\t%i %ix%i slots\n",
+ NumPartial, MaxPartialWidth, MaxPartialHeight);
+ if(Num128) xf86ErrorF("\t\t%i 128x128 slots\n", Num128);
+ if(Num256) xf86ErrorF("\t\t%i 256x256 slots\n", Num256);
+ if(Num512) xf86ErrorF("\t\t%i 512x512 slots\n", Num512);
+ if(NumColor) xf86ErrorF("\t\t%i 8x8 color pattern slots\n", NumColor);
+ if(NumMono) xf86ErrorF("\t\t%i 8x8 color expansion slots\n", NumMono);
+ }
+
+ if(!(NumPartial | Num128 | Num256 | Num512 | NumColor | NumMono)) {
+ if(!CACHEINIT(pScrn))
+ xf86ErrorF("\t\tNot enough video memory for pixmap cache\n");
+ } else infoRec->UsingPixmapCache = TRUE;
+
+ CACHEINIT(pScrn) = 1;
+}
+
+static CARD32 StippleMasks[4] = {
+ 0x01010101,
+ 0x03030303,
+ 0x00000000,
+ 0x0F0F0F0F
+};
+
+Bool
+XAACheckStippleReducibility(PixmapPtr pPixmap)
+{
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_DRAWABLE(&pPixmap->drawable);
+ CARD32 *IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
+ int w = pPixmap->drawable.width;
+ int h = pPixmap->drawable.height;
+ int i;
+ CARD32 bits[8];
+
+ pPriv->flags |= REDUCIBILITY_CHECKED | REDUCIBLE_TO_2_COLOR;
+ pPriv->flags &= ~REDUCIBLE_TO_8x8;
+
+ if((w > 32) || (h > 32) || (w & (w - 1)) || (h & (h - 1)))
+ return FALSE;
+
+ i = (h > 8) ? 8 : h;
+
+ switch(w) {
+ case 32:
+ while(i--) {
+ bits[i] = IntPtr[i] & 0x000000FF;
+ if( (bits[i] != ((IntPtr[i] & 0x0000FF00) >> 8)) ||
+ (bits[i] != ((IntPtr[i] & 0x00FF0000) >> 16)) ||
+ (bits[i] != ((IntPtr[i] & 0xFF000000) >> 24)))
+ return FALSE;
+ }
+ break;
+ case 16:
+ while(i--) {
+ bits[i] = IntPtr[i] & 0x000000FF;
+ if(bits[i] != ((IntPtr[i] & 0x0000FF00) >> 8))
+ return FALSE;
+ }
+ break;
+ default:
+ while(i--)
+ bits[i] = IntPtr[i] & 0x000000FF;
+ break;
+ }
+
+ switch(h) {
+ case 32:
+ if( (IntPtr[8] != IntPtr[16]) || (IntPtr[9] != IntPtr[17]) ||
+ (IntPtr[10] != IntPtr[18]) || (IntPtr[11] != IntPtr[19]) ||
+ (IntPtr[12] != IntPtr[20]) || (IntPtr[13] != IntPtr[21]) ||
+ (IntPtr[14] != IntPtr[22]) || (IntPtr[15] != IntPtr[23]) ||
+ (IntPtr[16] != IntPtr[24]) || (IntPtr[17] != IntPtr[25]) ||
+ (IntPtr[18] != IntPtr[26]) || (IntPtr[19] != IntPtr[27]) ||
+ (IntPtr[20] != IntPtr[28]) || (IntPtr[21] != IntPtr[29]) ||
+ (IntPtr[22] != IntPtr[30]) || (IntPtr[23] != IntPtr[31]))
+ return FALSE;
+ /* fall through */
+ case 16:
+ if( (IntPtr[0] != IntPtr[8]) || (IntPtr[1] != IntPtr[9]) ||
+ (IntPtr[2] != IntPtr[10]) || (IntPtr[3] != IntPtr[11]) ||
+ (IntPtr[4] != IntPtr[12]) || (IntPtr[5] != IntPtr[13]) ||
+ (IntPtr[6] != IntPtr[14]) || (IntPtr[7] != IntPtr[15]))
+ return FALSE;
+ case 8: break;
+ case 1: bits[1] = bits[0];
+ case 2: bits[2] = bits[0]; bits[3] = bits[1];
+ case 4: bits[4] = bits[0]; bits[5] = bits[1];
+ bits[6] = bits[2]; bits[7] = bits[3];
+ break;
+ }
+
+ pPriv->flags |= REDUCIBLE_TO_8x8;
+
+ pPriv->pattern0 = bits[0] | (bits[1]<<8) | (bits[2]<<16) | (bits[3]<<24);
+ pPriv->pattern1 = bits[4] | (bits[5]<<8) | (bits[6]<<16) | (bits[7]<<24);
+
+ if(w < 8) {
+ pPriv->pattern0 &= StippleMasks[w - 1];
+ pPriv->pattern1 &= StippleMasks[w - 1];
+
+ switch(w) {
+ case 1: pPriv->pattern0 |= (pPriv->pattern0 << 1);
+ pPriv->pattern1 |= (pPriv->pattern1 << 1);
+ case 2: pPriv->pattern0 |= (pPriv->pattern0 << 2);
+ pPriv->pattern1 |= (pPriv->pattern1 << 2);
+ case 4: pPriv->pattern0 |= (pPriv->pattern0 << 4);
+ pPriv->pattern1 |= (pPriv->pattern1 << 4);
+ }
+ }
+
+ if(infoRec->Mono8x8PatternFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
+ pPriv->pattern0 = XAAReverseBitOrder(pPriv->pattern0);
+ pPriv->pattern1 = XAAReverseBitOrder(pPriv->pattern1);
+ }
+
+
+ return TRUE;
+}
+
+
+Bool
+XAACheckTileReducibility(PixmapPtr pPixmap, Bool checkMono)
+{
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+ CARD32 *IntPtr;
+ int w = pPixmap->drawable.width;
+ int h = pPixmap->drawable.height;
+ int pitch = pPixmap->devKind >> 2;
+ int dwords, i, j;
+
+ pPriv->flags |= REDUCIBILITY_CHECKED;
+ pPriv->flags &= ~(REDUCIBILITY_CHECKED | REDUCIBLE_TO_2_COLOR);
+
+ if((w > 32) || (h > 32) || (w & (w - 1)) || (h & (h - 1)))
+ return FALSE;
+
+ dwords = ((w * pPixmap->drawable.bitsPerPixel) + 31) >> 5;
+ i = (h > 8) ? 8 : h;
+
+
+ if(w > 8) {
+ IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
+ switch(pPixmap->drawable.bitsPerPixel) {
+ case 8:
+ while(i--) {
+ for(j = 2; j < dwords; j++)
+ if(IntPtr[j] != IntPtr[j & 0x01])
+ return FALSE;
+ IntPtr += pitch;
+ }
+ break;
+ case 16:
+ while(i--) {
+ for(j = 4; j < dwords; j++)
+ if(IntPtr[j] != IntPtr[j & 0x03])
+ return FALSE;
+ IntPtr += pitch;
+ }
+ break;
+ case 24:
+ while(i--) {
+ for(j = 6; j < dwords; j++)
+ if(IntPtr[j] != IntPtr[j % 6])
+ return FALSE;
+ IntPtr += pitch;
+ }
+ break;
+ case 32:
+ while(i--) {
+ for(j = 8; j < dwords; j++)
+ if(IntPtr[j] != IntPtr[j & 0x07])
+ return FALSE;
+ IntPtr += pitch;
+ }
+ break;
+ default: return FALSE;
+ }
+
+ }
+
+
+ if(h == 32) {
+ CARD32 *IntPtr2, *IntPtr3, *IntPtr4;
+ i = 8;
+ IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
+ IntPtr2 = IntPtr + (pitch << 3);
+ IntPtr3 = IntPtr2 + (pitch << 3);
+ IntPtr4 = IntPtr3 + (pitch << 3);
+ while(i--) {
+ for(j = 0; j < dwords; j++)
+ if((IntPtr[j] != IntPtr2[j]) || (IntPtr[j] != IntPtr3[j]) ||
+ (IntPtr[j] != IntPtr4[j]))
+ return FALSE;
+ IntPtr += pitch;
+ IntPtr2 += pitch;
+ IntPtr3 += pitch;
+ IntPtr4 += pitch;
+ }
+ } else if (h == 16) {
+ CARD32 *IntPtr2;
+ i = 8;
+ IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
+ IntPtr2 = IntPtr + (pitch << 3);
+ while(i--) {
+ for(j = 0; j < dwords; j++)
+ if(IntPtr[j] != IntPtr2[j])
+ return FALSE;
+ IntPtr += pitch;
+ IntPtr2 += pitch;
+ }
+ }
+
+ pPriv->flags |= REDUCIBLE_TO_8x8;
+
+ if(checkMono) {
+ XAAInfoRecPtr infoRec =
+ GET_XAAINFORECPTR_FROM_DRAWABLE(&pPixmap->drawable);
+ unsigned char bits[8];
+ int fg, bg = -1, x, y;
+
+ i = (h > 8) ? 8 : h;
+ j = (w > 8) ? 8 : w;
+
+ if(pPixmap->drawable.bitsPerPixel == 8) {
+ unsigned char *srcp = pPixmap->devPrivate.ptr;
+ fg = srcp[0];
+ pitch = pPixmap->devKind;
+ for(y = 0; y < i; y++) {
+ bits[y] = 0;
+ for(x = 0; x < j; x++) {
+ if(srcp[x] != fg) {
+ if(bg == -1) bg = srcp[x];
+ else if(bg != srcp[x]) return TRUE;
+ } else bits[y] |= 1 << x;
+ }
+ srcp += pitch;
+ }
+ } else if(pPixmap->drawable.bitsPerPixel == 16) {
+ unsigned short *srcp = (unsigned short*)pPixmap->devPrivate.ptr;
+ fg = srcp[0];
+ pitch = pPixmap->devKind >> 1;
+ for(y = 0; y < i; y++) {
+ bits[y] = 0;
+ for(x = 0; x < j; x++) {
+ if(srcp[x] != fg) {
+ if(bg == -1) bg = srcp[x];
+ else if(bg != srcp[x]) return TRUE;
+ } else bits[y] |= 1 << x;
+ }
+ srcp += pitch;
+ }
+ } else if(pPixmap->drawable.bitsPerPixel == 24) {
+ CARD32 val;
+ unsigned char *srcp = pPixmap->devPrivate.ptr;
+ fg = *((CARD32*)srcp) & 0x00FFFFFF;
+ pitch = pPixmap->devKind;
+ j *= 3;
+ for(y = 0; y < i; y++) {
+ bits[y] = 0;
+ for(x = 0; x < j; x+=3) {
+ val = *((CARD32*)(srcp+x)) & 0x00FFFFFF;
+ if(val != fg) {
+ if(bg == -1) bg = val;
+ else if(bg != val)
+ return TRUE;
+ } else bits[y] |= 1 << (x/3);
+ }
+ srcp += pitch;
+ }
+ } else if(pPixmap->drawable.bitsPerPixel == 32) {
+ IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
+ fg = IntPtr[0];
+ for(y = 0; y < i; y++) {
+ bits[y] = 0;
+ for(x = 0; x < j; x++) {
+ if(IntPtr[x] != fg) {
+ if(bg == -1) bg = IntPtr[x];
+ else if(bg != IntPtr[x]) return TRUE;
+ } else bits[y] |= 1 << x;
+ }
+ IntPtr += pitch;
+ }
+ } else return TRUE;
+
+ pPriv->fg = fg;
+ if(bg == -1) pPriv->bg = fg;
+ else pPriv->bg = bg;
+
+ if(h < 8) {
+ switch(h) {
+ case 1: bits[1] = bits[0];
+ case 2: bits[2] = bits[0]; bits[3] = bits[1];
+ case 4: bits[4] = bits[0]; bits[5] = bits[1];
+ bits[6] = bits[2]; bits[7] = bits[3];
+ break;
+ }
+ }
+
+ pPriv->pattern0 =
+ bits[0] | (bits[1]<<8) | (bits[2]<<16) | (bits[3]<<24);
+ pPriv->pattern1 =
+ bits[4] | (bits[5]<<8) | (bits[6]<<16) | (bits[7]<<24);
+
+ if(w < 8) {
+ switch(w) {
+ case 1: pPriv->pattern0 |= (pPriv->pattern0 << 1);
+ pPriv->pattern1 |= (pPriv->pattern1 << 1);
+ case 2: pPriv->pattern0 |= (pPriv->pattern0 << 2);
+ pPriv->pattern1 |= (pPriv->pattern1 << 2);
+ case 4: pPriv->pattern0 |= (pPriv->pattern0 << 4);
+ pPriv->pattern1 |= (pPriv->pattern1 << 4);
+ }
+ }
+ pPriv->flags |= REDUCIBLE_TO_2_COLOR;
+
+ if(infoRec->Mono8x8PatternFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
+ pPriv->pattern0 = XAAReverseBitOrder(pPriv->pattern0);
+ pPriv->pattern1 = XAAReverseBitOrder(pPriv->pattern1);
+ }
+
+ }
+
+ return TRUE;
+}
+
+
+static void XAATileCache(
+ ScrnInfoPtr pScrn,
+ XAACacheInfoPtr pCache,
+ int w, int h
+) {
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, GXcopy, ~0, -1);
+
+ while((w << 1) <= pCache->w) {
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
+ pCache->x + w, pCache->y, w, h);
+ w <<= 1;
+ }
+ if(w != pCache->w) {
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
+ pCache->x + w, pCache->y, pCache->w - w, h);
+ w = pCache->w;
+ }
+
+ while((h << 1) <= pCache->h) {
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
+ pCache->x, pCache->y + h, w, h);
+ h <<= 1;
+ }
+ if(h != pCache->h) {
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
+ pCache->x, pCache->y + h, w, pCache->h - h);
+ }
+ SET_SYNC_FLAG(infoRec);
+}
+
+XAACacheInfoPtr
+XAACacheTile(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ int size = max(w, h);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ int i, max = 0;
+ int *current;
+
+ if(size <= 128) {
+ if(pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ } else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ } else if(size <= 256) {
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ } else if(size <= 512) {
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ } else { /* something's wrong */
+ ErrorF("Something's wrong in XAACacheTile()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+
+ /* lets look for it */
+ for(i = 0; i < max; i++, pCache++) {
+ if(pCache->serialNumber == pPix->drawable.serialNumber) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if(*current >= max) *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->bg = pCache->fg = -1;
+ pCache->orig_w = w; pCache->orig_h = h;
+ (*infoRec->WritePixmapToCache)(
+ pScrn, pCache->x, pCache->y, w, h, pPix->devPrivate.ptr,
+ pPix->devKind, pPix->drawable.bitsPerPixel, pPix->drawable.depth);
+ if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_COLOR_DATA) &&
+ ((w != pCache->w) || (h != pCache->h)))
+ XAATileCache(pScrn, pCache, w, h);
+
+ return pCache;
+}
+
+XAACacheInfoPtr
+XAACacheMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ int i, max = 0, funcNo, pad, dwords, bpp = pScrn->bitsPerPixel;
+ int *current;
+ StippleScanlineProcPtr StippleFunc;
+ unsigned char *data, *srcPtr, *dstPtr;
+
+ if((h <= 128) && (w <= 128 * bpp)) {
+ if(pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ } else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ } else if((h <= 256) && (w <= 256 * bpp)){
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ } else if((h <= 512) && (w <= 526 * bpp)){
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ } else { /* something's wrong */
+ ErrorF("Something's wrong in XAACacheMonoStipple()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+
+ /* lets look for it */
+ for(i = 0; i < max; i++, pCache++) {
+ if((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (pCache->fg == -1) && (pCache->bg == -1)) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if(*current >= max) *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->bg = pCache->fg = -1;
+ pCache->orig_w = w; pCache->orig_h = h;
+
+ if(w <= 32) {
+ if(w & (w - 1)) funcNo = 1;
+ else funcNo = 0;
+ } else funcNo = 2;
+
+ pad = BitmapBytePad(pCache->w * bpp);
+ dwords = pad >> 2;
+ dstPtr = data = (unsigned char*)ALLOCATE_LOCAL(pad * pCache->h);
+ srcPtr = (unsigned char*)pPix->devPrivate.ptr;
+
+ if(infoRec->ScreenToScreenColorExpandFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST)
+ StippleFunc = XAAStippleScanlineFuncMSBFirst[funcNo];
+ else
+ StippleFunc = XAAStippleScanlineFuncLSBFirst[funcNo];
+
+ /* don't bother generating more than we'll ever use */
+ max = ((pScrn->displayWidth + w - 1) + 31) >> 5;
+ if(dwords > max)
+ dwords = max;
+
+ for(i = 0; i < h; i++) {
+ (*StippleFunc)((CARD32*)dstPtr, (CARD32*)srcPtr, 0, w, dwords);
+ srcPtr += pPix->devKind;
+ dstPtr += pad;
+ }
+
+ while((h<<1) <= pCache->h) {
+ memcpy(data + (pad * h), data, pad * h);
+ h <<= 1;
+ }
+
+ if(h < pCache->h)
+ memcpy(data + (pad * h), data, pad * (pCache->h - h));
+
+ (*infoRec->WritePixmapToCache)(
+ pScrn, pCache->x, pCache->y, pCache->w, pCache->h, data,
+ pad, bpp, pScrn->depth);
+
+ DEALLOCATE_LOCAL(data);
+
+ return pCache;
+}
+
+XAACacheInfoPtr
+XAACachePlanarMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ int i, max = 0;
+ int *current;
+
+ if((h <= 128) && (w <= 128)) {
+ if(pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ } else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ } else if((h <= 256) && (w <= 256)){
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ } else if((h <= 512) && (w <= 526)){
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ } else { /* something's wrong */
+ ErrorF("Something's wrong in XAACachePlanarMonoStipple()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+
+ /* lets look for it */
+ for(i = 0; i < max; i++, pCache++) {
+ if((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (pCache->fg == -1) && (pCache->bg == -1)) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if(*current >= max) *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->bg = pCache->fg = -1;
+ pCache->orig_w = w; pCache->orig_h = h;
+
+ /* Plane 0 holds the stipple. Plane 1 holds the inverted stipple */
+ (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y,
+ pPix->drawable.width, pPix->drawable.height, pPix->devPrivate.ptr,
+ pPix->devKind, 1, 2);
+ if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_MONO_DATA) &&
+ ((w != pCache->w) || (h != pCache->h)))
+ XAATileCache(pScrn, pCache, w, h);
+
+ return pCache;
+}
+
+
+
+XAACacheInfoPtr
+XAACacheStipple(ScrnInfoPtr pScrn, PixmapPtr pPix, int fg, int bg)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ int size = max(w, h);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ int i, max = 0;
+ int *current;
+
+ if(size <= 128) {
+ if(pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ } else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ } else if(size <= 256) {
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ } else if(size <= 512) {
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ } else { /* something's wrong */
+ ErrorF("Something's wrong in XAACacheStipple()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+ /* lets look for it */
+ if(bg == -1)
+ for(i = 0; i < max; i++, pCache++) {
+ if((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (fg == pCache->fg) && (pCache->fg != pCache->bg)) {
+ pCache->trans_color = pCache->bg;
+ return pCache;
+ }
+ }
+ else
+ for(i = 0; i < max; i++, pCache++) {
+ if((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (fg == pCache->fg) && (bg == pCache->bg)) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if(*current >= max) *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->fg = fg;
+ if(bg == -1)
+ pCache->trans_color = bg = fg ^ 1;
+ else
+ pCache->trans_color = -1;
+ pCache->bg = bg;
+
+ pCache->orig_w = w; pCache->orig_h = h;
+ (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y,
+ pPix->drawable.width, pPix->drawable.height, pPix->devPrivate.ptr,
+ pPix->devKind, fg, bg);
+ if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_COLOR_DATA) &&
+ ((w != pCache->w) || (h != pCache->h)))
+ XAATileCache(pScrn, pCache, w, h);
+
+ return pCache;
+}
+
+
+
+XAACacheInfoPtr
+XAACacheMono8x8Pattern(ScrnInfoPtr pScrn, int pat0, int pat1)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache = pCachePriv->InfoMono;
+ int i;
+
+ for(i = 0; i < pCachePriv->NumMono; i++, pCache++) {
+ if(pCache->serialNumber &&
+ (pCache->pat0 == pat0) && (pCache->pat1 == pat1))
+ return pCache;
+ }
+
+ /* OK, let's cache it */
+ pCache = &pCachePriv->InfoMono[pCachePriv->CurrentMono++];
+ if(pCachePriv->CurrentMono >= pCachePriv->NumMono)
+ pCachePriv->CurrentMono = 0;
+
+ pCache->serialNumber = 1; /* we don't care since we do lookups by pattern */
+ pCache->pat0 = pat0;
+ pCache->pat1 = pat1;
+
+ (*infoRec->WriteMono8x8PatternToCache)(pScrn, pCache);
+
+ return pCache;
+}
+
+
+
+XAACacheInfoPtr
+XAACacheColor8x8Pattern(ScrnInfoPtr pScrn, PixmapPtr pPix, int fg, int bg)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache = pCachePriv->InfoColor;
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ int i;
+
+ if(!(pixPriv->flags & REDUCIBLE_TO_2_COLOR)) {
+ for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
+ if(pCache->serialNumber == pPix->drawable.serialNumber) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+ pCache = &pCachePriv->InfoColor[pCachePriv->CurrentColor++];
+ if(pCachePriv->CurrentColor >= pCachePriv->NumColor)
+ pCachePriv->CurrentColor = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->fg = pCache->bg = -1;
+ } else {
+ int pat0 = pixPriv->pattern0;
+ int pat1 = pixPriv->pattern1;
+
+ if(fg == -1) { /* it's a tile */
+ fg = pixPriv->fg; bg = pixPriv->bg;
+ }
+
+ if(bg == -1) { /* stipple */
+ for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
+ if(pCache->serialNumber &&
+ (pCache->pat0 == pat0) && (pCache->pat1 == pat1) &&
+ (pCache->fg == fg) && (pCache->bg != fg)) {
+ pCache->trans_color = pCache->bg;
+ return pCache;
+ }
+ }
+ } else { /* opaque stipple */
+ for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
+ if(pCache->serialNumber &&
+ (pCache->pat0 == pat0) && (pCache->pat1 == pat1) &&
+ (pCache->fg == fg) && (pCache->bg == bg)) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+ }
+ pCache = &pCachePriv->InfoColor[pCachePriv->CurrentColor++];
+ if(pCachePriv->CurrentColor >= pCachePriv->NumColor)
+ pCachePriv->CurrentColor = 0;
+
+ if(bg == -1)
+ pCache->trans_color = bg = fg ^ 1;
+ else
+ pCache->trans_color = -1;
+
+ pCache->pat0 = pat0; pCache->pat1 = pat1;
+ pCache->fg = fg; pCache->bg = bg;
+ pCache->serialNumber = 1;
+ }
+
+ (*infoRec->WriteColor8x8PatternToCache)(pScrn, pPix, pCache);
+
+ return pCache;
+}
+
+
+void
+XAAWriteBitmapToCache(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int fg, int bg
+) {
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->WriteBitmap)(pScrn, x, y, w, h, src, srcwidth,
+ 0, fg, bg, GXcopy, ~0);
+}
+
+void
+XAAWriteBitmapToCacheLinear(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int fg, int bg
+){
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr pScreenPix, pDstPix;
+ XID gcvals[2];
+ GCPtr pGC;
+
+ pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
+
+ pDstPix = GetScratchPixmapHeader(pScreen, pScreenPix->drawable.width,
+ y + h, pScreenPix->drawable.depth,
+ pScreenPix->drawable.bitsPerPixel,
+ pScreenPix->devKind,
+ pScreenPix->devPrivate.ptr);
+
+ pGC = GetScratchGC(pScreenPix->drawable.depth, pScreen);
+ gcvals[0] = fg;
+ gcvals[1] = bg;
+ DoChangeGC(pGC, GCForeground | GCBackground, gcvals, 0);
+ ValidateGC((DrawablePtr)pDstPix, pGC);
+
+ /* We've unwrapped already so these ops miss a sync */
+ SYNC_CHECK(pScrn);
+
+ (*pGC->ops->PutImage)((DrawablePtr)pDstPix, pGC, 1, x, y, w, h, 0,
+ XYBitmap, (pointer)src);
+
+ FreeScratchGC(pGC);
+ FreeScratchPixmapHeader(pDstPix);
+}
+
+
+void
+XAAWritePixmapToCache(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int bpp, int depth
+) {
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->WritePixmap)(pScrn, x, y, w, h, src, srcwidth,
+ GXcopy, ~0, -1, bpp, depth);
+}
+
+
+
+void
+XAAWritePixmapToCacheLinear(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int bpp, int depth
+){
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr pScreenPix, pDstPix;
+ GCPtr pGC;
+
+ pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
+
+ pDstPix = GetScratchPixmapHeader(pScreen, pScreenPix->drawable.width,
+ y + h, depth, bpp, pScreenPix->devKind,
+ pScreenPix->devPrivate.ptr);
+
+ pGC = GetScratchGC(depth, pScreen);
+ ValidateGC((DrawablePtr)pDstPix, pGC);
+
+ /* We've unwrapped already so these ops miss a sync */
+ SYNC_CHECK(pScrn);
+
+ if(bpp == BitsPerPixel(depth))
+ (*pGC->ops->PutImage)((DrawablePtr)pDstPix, pGC, depth, x, y, w,
+ h, 0, ZPixmap, (pointer)src);
+ else {
+ PixmapPtr pSrcPix;
+
+ pSrcPix = GetScratchPixmapHeader(pScreen, w, h, depth, bpp,
+ srcwidth, (pointer)src);
+
+ (*pGC->ops->CopyArea)((DrawablePtr)pSrcPix, (DrawablePtr)pDstPix,
+ pGC, 0, 0, w, h, x, y);
+
+ FreeScratchPixmapHeader(pSrcPix);
+ }
+
+ FreeScratchGC(pGC);
+ FreeScratchPixmapHeader(pDstPix);
+}
+
+
+void
+XAAWriteMono8x8PatternToCache(
+ ScrnInfoPtr pScrn,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ unsigned char *data;
+ int pad, Bpp = (pScrn->bitsPerPixel >> 3);
+
+ pCache->offsets = pCachePriv->MonoOffsets;
+
+ pad = BitmapBytePad(pCache->w * pScrn->bitsPerPixel);
+
+ data = (unsigned char*)ALLOCATE_LOCAL(pad * pCache->h);
+ if(!data) return;
+
+ if(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
+ CARD32* ptr = (CARD32*)data;
+ ptr[0] = pCache->pat0; ptr[1] = pCache->pat1;
+ } else {
+ CARD32 *ptr;
+ DDXPointPtr pPoint = pCache->offsets;
+ int patx, paty, i;
+
+ for(i = 0; i < 64; i++, pPoint++) {
+ patx = pCache->pat0; paty = pCache->pat1;
+ XAARotateMonoPattern(&patx, &paty, i & 0x07, i >> 3,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ ptr = (CARD32*)(data + (pad * pPoint->y) + (Bpp * pPoint->x));
+ ptr[0] = patx; ptr[1] = paty;
+ }
+ }
+
+ (*infoRec->WritePixmapToCache)(pScrn, pCache->x, pCache->y,
+ pCache->w, pCache->h, data, pad, pScrn->bitsPerPixel, pScrn->depth);
+
+ DEALLOCATE_LOCAL(data);
+}
+
+void
+XAAWriteColor8x8PatternToCache(
+ ScrnInfoPtr pScrn,
+ PixmapPtr pPix,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ int pad, i, w, h, nw, nh, Bpp;
+ unsigned char *data, *srcPtr, *dstPtr;
+
+ pCache->offsets = pCachePriv->ColorOffsets;
+
+ if(pixPriv->flags & REDUCIBLE_TO_2_COLOR) {
+ CARD32* ptr;
+ pad = BitmapBytePad(pCache->w);
+ data = (unsigned char*)ALLOCATE_LOCAL(pad * pCache->h);
+ if(!data) return;
+
+ if(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
+ ptr = (CARD32*)data;
+ ptr[0] = pCache->pat0; ptr[1] = pCache->pat1;
+ } else {
+ int patx, paty;
+
+ ptr = (CARD32*)data;
+ ptr[0] = ptr[2] = pCache->pat0; ptr[1] = ptr[3] = pCache->pat1;
+ for(i = 1; i < 8; i++) {
+ patx = pCache->pat0; paty = pCache->pat1;
+ XAARotateMonoPattern(&patx, &paty, i, 0,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ ptr = (CARD32*)(data + (pad * i));
+ ptr[0] = ptr[2] = patx; ptr[1] = ptr[3] = paty;
+ }
+ }
+
+ (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y,
+ pCache->w, pCache->h, data, pad, pCache->fg, pCache->bg);
+
+ DEALLOCATE_LOCAL(data);
+ return;
+ }
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ h = min(8,pPix->drawable.height);
+ w = min(8,pPix->drawable.width);
+ pad = BitmapBytePad(pCache->w * pScrn->bitsPerPixel);
+
+ data = (unsigned char*)ALLOCATE_LOCAL(pad * pCache->h);
+ if(!data) return;
+
+ /* Write and expand horizontally. */
+ for (i = h, dstPtr = data, srcPtr = pPix->devPrivate.ptr; i--;
+ srcPtr += pPix->devKind, dstPtr += pScrn->bitsPerPixel) {
+ nw = w;
+ memcpy(dstPtr, srcPtr, w * Bpp);
+ while (nw != 8) {
+ memcpy(dstPtr + (nw * Bpp), srcPtr, nw * Bpp);
+ nw <<= 1;
+ }
+ }
+ nh = h;
+ /* Expand vertically. */
+ while (nh != 8) {
+ memcpy(data + (nh*pScrn->bitsPerPixel), data, nh*pScrn->bitsPerPixel);
+ nh <<= 1;
+ }
+
+ if(!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int j;
+ unsigned char *ptr = data + (128 * Bpp);
+
+ memcpy(data + (64 * Bpp), data, 64 * Bpp);
+ for(i = 1; i < 8; i++, ptr += (128 * Bpp)) {
+ for(j = 0; j < 8; j++) {
+ memcpy(ptr + (j * 8) * Bpp, data + (j * 8 + i) * Bpp,
+ (8 - i) * Bpp);
+ memcpy(ptr + (j * 8 + 8 - i) * Bpp, data + j * 8 * Bpp, i*Bpp);
+ }
+ memcpy(ptr + (64 * Bpp), ptr, 64 * Bpp);
+ }
+ }
+
+ (*infoRec->WritePixmapToCache)(pScrn, pCache->x, pCache->y,
+ pCache->w, pCache->h, data, pad, pScrn->bitsPerPixel, pScrn->depth);
+
+ DEALLOCATE_LOCAL(data);
+}
+
+
+
+int
+XAAStippledFillChooser(GCPtr pGC)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ PixmapPtr pPixmap = pGC->stipple;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+
+ if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
+ (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
+ XAACheckStippleReducibility(pPixmap);
+ }
+
+
+ if(pPriv->flags & REDUCIBLE_TO_8x8) {
+ if(infoRec->CanDoMono8x8 &&
+ !(infoRec->FillMono8x8PatternSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillMono8x8PatternSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_FG(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
+
+ return DO_MONO_8x8;
+ }
+
+ if(infoRec->CanDoColor8x8 &&
+ !(infoRec->FillColor8x8PatternSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillColor8x8PatternSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
+
+ return DO_COLOR_8x8;
+ }
+ }
+
+ if(infoRec->UsingPixmapCache && infoRec->FillCacheExpandSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableStippleHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableStippleWidth /
+ infoRec->CacheColorExpandDensity) &&
+ !(infoRec->FillCacheExpandSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillCacheExpandSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_FG(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheExpandSpansFlags)) {
+
+ return DO_CACHE_EXPAND;
+ }
+
+
+ if(infoRec->UsingPixmapCache &&
+ !(infoRec->PixmapCacheFlags & DO_NOT_BLIT_STIPPLES) &&
+ infoRec->FillCacheBltSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
+ !(infoRec->FillCacheBltSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillCacheBltSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
+
+ return DO_CACHE_BLT;
+ }
+
+ if(infoRec->FillColorExpandSpans &&
+ !(infoRec->FillColorExpandSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillColorExpandSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_FG(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillColorExpandSpansFlags)) {
+
+ return DO_COLOR_EXPAND;
+ }
+
+ return 0;
+}
+
+
+int
+XAAOpaqueStippledFillChooser(GCPtr pGC)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ PixmapPtr pPixmap = pGC->stipple;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+
+
+ if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
+ (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
+ XAACheckStippleReducibility(pPixmap);
+ }
+
+
+ if(pPriv->flags & REDUCIBLE_TO_8x8) {
+ if(infoRec->CanDoMono8x8 &&
+ !(infoRec->FillMono8x8PatternSpansFlags & TRANSPARENCY_ONLY) &&
+ CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_COLORS(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
+
+ return DO_MONO_8x8;
+ }
+
+ if(infoRec->CanDoColor8x8 &&
+ CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
+
+ return DO_COLOR_8x8;
+ }
+ }
+
+ if(infoRec->UsingPixmapCache && infoRec->FillCacheExpandSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableStippleHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableStippleWidth /
+ infoRec->CacheColorExpandDensity) &&
+ !(infoRec->FillCacheExpandSpansFlags & TRANSPARENCY_ONLY) &&
+ CHECK_ROP(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_COLORS(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheExpandSpansFlags)) {
+
+ return DO_CACHE_EXPAND;
+ }
+
+ if(infoRec->UsingPixmapCache &&
+ !(infoRec->PixmapCacheFlags & DO_NOT_BLIT_STIPPLES) &&
+ infoRec->FillCacheBltSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
+ CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
+
+ return DO_CACHE_BLT;
+ }
+
+ if(infoRec->FillColorExpandSpans &&
+ !(infoRec->FillColorExpandSpansFlags & TRANSPARENCY_ONLY) &&
+ CHECK_ROP(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_COLORS(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillColorExpandSpansFlags)) {
+
+ return DO_COLOR_EXPAND;
+ }
+
+ return 0;
+}
+
+
+
+int
+XAATiledFillChooser(GCPtr pGC)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ PixmapPtr pPixmap = pGC->tile.pixmap;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+
+ if(IS_OFFSCREEN_PIXMAP(pPixmap) && infoRec->FillCacheBltSpans &&
+ CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
+
+ return DO_PIXMAP_COPY;
+ }
+
+ if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
+ (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
+ XAACheckTileReducibility(pPixmap,infoRec->CanDoMono8x8);
+ }
+
+ if(pPriv->flags & REDUCIBLE_TO_8x8) {
+ if((pPriv->flags & REDUCIBLE_TO_2_COLOR) && infoRec->CanDoMono8x8 &&
+ !(infoRec->FillMono8x8PatternSpansFlags & TRANSPARENCY_ONLY) &&
+ CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ (!(infoRec->FillMono8x8PatternSpansFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(pPriv->fg) && CHECK_RGB_EQUAL(pPriv->bg))) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
+
+ return DO_MONO_8x8;
+ }
+
+ if(infoRec->CanDoColor8x8 &&
+ CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
+
+ return DO_COLOR_8x8;
+ }
+ }
+
+ if(infoRec->UsingPixmapCache && infoRec->FillCacheBltSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
+ CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
+
+ return DO_CACHE_BLT;
+ }
+
+ if(infoRec->FillImageWriteRects &&
+ CHECK_NO_GXCOPY(pGC,infoRec->FillImageWriteRectsFlags) &&
+ CHECK_ROP(pGC,infoRec->FillImageWriteRectsFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillImageWriteRectsFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillImageWriteRectsFlags)) {
+
+ return DO_IMAGE_WRITE;
+ }
+
+ return 0;
+}
+
+
+static int RotateMasksX[8] = {
+ 0xFFFFFFFF, 0x7F7F7F7F, 0x3F3F3F3F, 0x1F1F1F1F,
+ 0x0F0F0F0F, 0x07070707, 0x03030303, 0x01010101
+};
+
+static int RotateMasksY[4] = {
+ 0xFFFFFFFF, 0x00FFFFFF, 0x0000FFFF, 0x000000FF
+};
+
+void
+XAARotateMonoPattern(
+ int *pat0, int *pat1,
+ int xorg, int yorg,
+ Bool msbfirst
+){
+ int tmp, mask;
+
+ if(xorg) {
+ if(msbfirst) xorg = 8 - xorg;
+ mask = RotateMasksX[xorg];
+ *pat0 = ((*pat0 >> xorg) & mask) | ((*pat0 << (8 - xorg)) & ~mask);
+ *pat1 = ((*pat1 >> xorg) & mask) | ((*pat1 << (8 - xorg)) & ~mask);
+ }
+ if(yorg >= 4) {
+ tmp = *pat0; *pat0 = *pat1; *pat1 = tmp;
+ yorg -= 4;
+ }
+ if(yorg) {
+ mask = RotateMasksY[yorg];
+ yorg <<= 3;
+ tmp = *pat0;
+ *pat0 = ((*pat0 >> yorg) & mask) | ((*pat1 << (32 - yorg)) & ~mask);
+ *pat1 = ((*pat1 >> yorg) & mask) | ((tmp << (32 - yorg)) & ~mask);
+ }
+}
+
+
+
+void
+XAAInvalidatePixmapCache(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ int i;
+
+ if(!pCachePriv) return;
+
+ for(i = 0; i < pCachePriv->Num512x512; i++)
+ (pCachePriv->Info512)[i].serialNumber = 0;
+ for(i = 0; i < pCachePriv->Num256x256; i++)
+ (pCachePriv->Info256)[i].serialNumber = 0;
+ for(i = 0; i < pCachePriv->Num128x128; i++)
+ (pCachePriv->Info128)[i].serialNumber = 0;
+ for(i = 0; i < pCachePriv->NumPartial; i++)
+ (pCachePriv->InfoPartial)[i].serialNumber = 0;
+ for(i = 0; i < pCachePriv->NumMono; i++)
+ (pCachePriv->InfoMono)[i].serialNumber = 0;
+ for(i = 0; i < pCachePriv->NumColor; i++)
+ (pCachePriv->InfoColor)[i].serialNumber = 0;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaPaintWin.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaPaintWin.c
new file mode 100644
index 000000000..20d2e9e99
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaPaintWin.c
@@ -0,0 +1,199 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaPaintWin.c,v 1.8 1999/08/28 09:01:18 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "xaawrap.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+extern WindowPtr *WindowTable;
+
+void
+XAAPaintWindow(
+ WindowPtr pWin,
+ RegionPtr prgn,
+ int what
+)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
+ int nBox = REGION_NUM_RECTS(prgn);
+ BoxPtr pBox = REGION_RECTS(prgn);
+ int fg;
+ PixmapPtr pPix = NULL;
+
+ if(!infoRec->pScrn->vtSema) goto BAILOUT;
+
+ switch (what) {
+ case PW_BACKGROUND:
+ switch(pWin->backgroundState) {
+ case None: return;
+ case ParentRelative:
+ do { pWin = pWin->parent; }
+ while(pWin->backgroundState == ParentRelative);
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, what);
+ return;
+ case BackgroundPixel:
+ fg = pWin->background.pixel;
+ break;
+ case BackgroundPixmap:
+ pPix = pWin->background.pixmap;
+ break;
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel)
+ fg = pWin->border.pixel;
+ else /* pixmap */
+ pPix = pWin->border.pixmap;
+ break;
+ default: return;
+ }
+
+
+ if(!pPix) {
+ if(infoRec->FillSolidRects &&
+ (!(infoRec->FillSolidRectsFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(fg))) ) {
+ (*infoRec->FillSolidRects)(infoRec->pScrn, fg, GXcopy, ~0,
+ nBox, pBox);
+ return;
+ }
+ } else { /* pixmap */
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ WindowPtr pBgWin = pWin;
+ Bool NoCache = FALSE;
+ int xorg, yorg;
+
+ /* Hack so we can use this with the dual framebuffer layers
+ which only support the pixmap cache in the primary bpp */
+ if(pPix->drawable.bitsPerPixel != infoRec->pScrn->bitsPerPixel)
+ NoCache = TRUE;
+
+ if (what == PW_BORDER) {
+ for (pBgWin = pWin;
+ pBgWin->backgroundState == ParentRelative;
+ pBgWin = pBgWin->parent);
+ }
+
+ xorg = pBgWin->drawable.x;
+ yorg = pBgWin->drawable.y;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ int index = pScreen->myNum;
+ if(WindowTable[index] == pBgWin) {
+ xorg -= panoramiXdataPtr[index].x;
+ yorg -= panoramiXdataPtr[index].y;
+ }
+ }
+#endif
+
+ if(IS_OFFSCREEN_PIXMAP(pPix) && infoRec->FillCacheBltRects) {
+ XAACacheInfoPtr pCache = &(infoRec->ScratchCacheInfoRec);
+
+ pCache->x = pPriv->offscreenArea->box.x1;
+ pCache->y = pPriv->offscreenArea->box.y1;
+ pCache->w = pCache->orig_w =
+ pPriv->offscreenArea->box.x2 - pCache->x;
+ pCache->h = pCache->orig_h =
+ pPriv->offscreenArea->box.y2 - pCache->y;
+
+ (*infoRec->FillCacheBltRects)(infoRec->pScrn, GXcopy, ~0,
+ nBox, pBox, xorg, yorg, pCache);
+ return;
+ }
+
+ if(pPriv->flags & DIRTY) {
+ pPriv->flags &= ~(DIRTY | REDUCIBILITY_MASK);
+ pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+
+ if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
+ (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
+ XAACheckTileReducibility(pPix, infoRec->CanDoMono8x8);
+ }
+
+ if(pPriv->flags & REDUCIBLE_TO_8x8) {
+ if((pPriv->flags & REDUCIBLE_TO_2_COLOR) &&
+ infoRec->CanDoMono8x8 && infoRec->FillMono8x8PatternRects &&
+ !(infoRec->FillMono8x8PatternRectsFlags & TRANSPARENCY_ONLY) &&
+ (!(infoRec->FillMono8x8PatternRectsFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(pPriv->fg) && CHECK_RGB_EQUAL(pPriv->bg)))) {
+
+ (*infoRec->FillMono8x8PatternRects)(infoRec->pScrn,
+ pPriv->fg, pPriv->bg, GXcopy, ~0, nBox, pBox,
+ pPriv->pattern0, pPriv->pattern1, xorg, yorg);
+ return;
+ }
+ if(infoRec->CanDoColor8x8 && !NoCache &&
+ infoRec->FillColor8x8PatternRects) {
+ XAACacheInfoPtr pCache = (*infoRec->CacheColor8x8Pattern)(
+ infoRec->pScrn, pPix, -1, -1);
+
+ (*infoRec->FillColor8x8PatternRects) ( infoRec->pScrn,
+ GXcopy, ~0, nBox, pBox, xorg, yorg, pCache);
+ return;
+ }
+ }
+
+ /* The window size check is to reduce pixmap cache thrashing
+ when there are lots of little windows with pixmap backgrounds
+ like are sometimes used for buttons, etc... */
+
+ if(infoRec->UsingPixmapCache &&
+ infoRec->FillCacheBltRects && !NoCache &&
+ ((what == PW_BORDER) ||
+ (pPix->drawable.height != pWin->drawable.height) ||
+ (pPix->drawable.width != pWin->drawable.width)) &&
+ (pPix->drawable.height <= infoRec->MaxCacheableTileHeight) &&
+ (pPix->drawable.width <= infoRec->MaxCacheableTileWidth)) {
+
+ XAACacheInfoPtr pCache =
+ (*infoRec->CacheTile)(infoRec->pScrn, pPix);
+ (*infoRec->FillCacheBltRects)(infoRec->pScrn, GXcopy, ~0,
+ nBox, pBox, xorg, yorg, pCache);
+ return;
+ }
+
+ if(infoRec->FillImageWriteRects &&
+ !(infoRec->FillImageWriteRectsFlags & NO_GXCOPY)) {
+ (*infoRec->FillImageWriteRects) (infoRec->pScrn, GXcopy,
+ ~0, nBox, pBox, xorg, yorg, pPix);
+ return;
+ }
+ }
+
+
+ if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+
+BAILOUT:
+
+ if(what == PW_BACKGROUND) {
+ XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBackground);
+ (*pScreen->PaintWindowBackground) (pWin, prgn, what);
+ XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBackground, XAAPaintWindow);
+ } else {
+ XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBorder);
+ (*pScreen->PaintWindowBorder) (pWin, prgn, what);
+ XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBorder, XAAPaintWindow);
+ }
+
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaROP.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaROP.c
new file mode 100644
index 000000000..6dc5e568e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaROP.c
@@ -0,0 +1,164 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaROP.c,v 1.1 1999/03/21 07:35:31 dawes Exp $ */
+
+#include "X.h"
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "scrnintstr.h"
+#include "xf86str.h"
+#include "xaarop.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+
+int XAACopyROP[16] =
+{
+ ROP_0, /* GXclear */
+ ROP_DSa, /* GXand */
+ ROP_SDna, /* GXandReverse */
+ ROP_S, /* GXcopy */
+ ROP_DSna, /* GXandInverted */
+ ROP_D, /* GXnoop */
+ ROP_DSx, /* GXxor */
+ ROP_DSo, /* GXor */
+ ROP_DSon, /* GXnor */
+ ROP_DSxn, /* GXequiv */
+ ROP_Dn, /* GXinvert*/
+ ROP_SDno, /* GXorReverse */
+ ROP_Sn, /* GXcopyInverted */
+ ROP_DSno, /* GXorInverted */
+ ROP_DSan, /* GXnand */
+ ROP_1 /* GXset */
+};
+
+int XAACopyROP_PM[16] =
+{
+ ROP_0, /* not used */
+ ROP_DSPnoa,
+ ROP_DPSnaon,
+ ROP_DPSDxax,
+ ROP_DPSana,
+ ROP_D, /* not used */
+ ROP_DPSax,
+ ROP_DPSao,
+ ROP_DPSaon,
+ ROP_DPSaxn,
+ ROP_Dn, /* not used */
+ ROP_DPSanan,
+ ROP_PSDPxox, /* is that correct ? */
+ ROP_DPSnao,
+ ROP_DSPnoan,
+ ROP_1 /* not used */
+};
+
+
+int XAAPatternROP[16]=
+{
+ ROP_0,
+ ROP_DPa,
+ ROP_PDna,
+ ROP_P,
+ ROP_DPna,
+ ROP_D,
+ ROP_DPx,
+ ROP_DPo,
+ ROP_DPon,
+ ROP_PDxn,
+ ROP_Dn,
+ ROP_PDno,
+ ROP_Pn,
+ ROP_DPno,
+ ROP_DPan,
+ ROP_1
+};
+
+int XAAPatternROP_PM[16] =
+{
+ ROP_DPna,
+ ROP_DPSnoa,
+ ROP_DSPnaon,
+ ROP_DSPDxax,
+ ROP_DPSana,
+ ROP_D,
+ ROP_DPSax,
+ ROP_DPSao,
+ ROP_DPSaon,
+ ROP_DPSaxn,
+ ROP_DPx,
+ ROP_DPSanan,
+ ROP_SPDSxox, /* is that correct ? */
+ ROP_DSPnao,
+ ROP_DPSnoan,
+ ROP_DPo
+};
+
+
+int
+XAAHelpPatternROP(ScrnInfoPtr pScrn, int *fg, int *bg, int pm, int *rop)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int ret = 0;
+
+ pm &= infoRec->FullPlanemask;
+
+ if(pm == infoRec->FullPlanemask) {
+ if(!NO_SRC_ROP(*rop))
+ ret |= ROP_PAT;
+ *rop = XAAPatternROP[*rop];
+ } else {
+ switch(*rop) {
+ case GXnoop:
+ break;
+ case GXset:
+ case GXclear:
+ case GXinvert:
+ ret |= ROP_PAT;
+ *fg = pm;
+ if(*bg != -1)
+ *bg = pm;
+ break;
+ default:
+ ret |= ROP_PAT | ROP_SRC;
+ break;
+ }
+ *rop = XAAPatternROP_PM[*rop];
+ }
+
+ return ret;
+}
+
+
+int
+XAAHelpSolidROP(ScrnInfoPtr pScrn, int *fg, int pm, int *rop)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int ret = 0;
+
+ pm &= infoRec->FullPlanemask;
+
+ if(pm == infoRec->FullPlanemask) {
+ if(!NO_SRC_ROP(*rop))
+ ret |= ROP_PAT;
+ *rop = XAAPatternROP[*rop];
+ } else {
+ switch(*rop) {
+ case GXnoop:
+ break;
+ case GXset:
+ case GXclear:
+ case GXinvert:
+ ret |= ROP_PAT;
+ *fg = pm;
+ break;
+ default:
+ ret |= ROP_PAT | ROP_SRC;
+ break;
+ }
+ *rop = XAAPatternROP_PM[*rop];
+ }
+
+ return ret;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaRect.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaRect.c
new file mode 100644
index 000000000..fe8d70de2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaRect.c
@@ -0,0 +1,134 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaRect.c,v 1.3 1999/05/30 03:03:33 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+/*
+ Much of this file based on code by
+ Harm Hanemaayer (H.Hanemaayer@inter.nl.net).
+*/
+
+
+void
+XAAPolyRectangleThinSolid(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int nClipRects; /* number of clip rectangles */
+ BoxPtr pClipRects; /* points to the list of clip rects */
+ int xOrigin; /* Drawables x origin */
+ int yOrigin; /* Drawables x origin */
+ xRectangle *pRect; /* list of rects */
+ int nRects; /* running count of number of rects */
+ int origX1, origY1; /* original rectangle's U/L corner */
+ int origX2, origY2; /* original rectangle's L/R corner */
+ int clippedX1; /* clipped rectangle's left x */
+ int clippedY1; /* clipped rectangle's top y */
+ int clippedX2; /* clipped rectangle's right x */
+ int clippedY2; /* clipped rectangle's bottom y */
+ int clipXMin; /* upper left corner of clip rect */
+ int clipYMin; /* upper left corner of clip rect */
+ int clipXMax; /* lower right corner of clip rect */
+ int clipYMax; /* lower right corner of clip rect */
+ int width, height; /* width and height of rect */
+
+ nClipRects = REGION_NUM_RECTS(pGC->pCompositeClip);
+ pClipRects = REGION_RECTS(pGC->pCompositeClip);
+
+ if(!nClipRects) return;
+
+ xOrigin = pDrawable->x;
+ yOrigin = pDrawable->y;
+
+
+ (*infoRec->SetupForSolidLine)(infoRec->pScrn,
+ pGC->fgPixel, pGC->alu, pGC->planemask);
+
+
+ for ( ; nClipRects > 0;
+ nClipRects--, pClipRects++ )
+ {
+ clipYMin = pClipRects->y1;
+ clipYMax = pClipRects->y2 - 1;
+ clipXMin = pClipRects->x1;
+ clipXMax = pClipRects->x2 - 1;
+
+ for (pRect = pRectsInit, nRects = nRectsInit;
+ nRects > 0;
+ nRects--, pRect++ )
+ {
+ /* translate rectangle data over to the drawable */
+ origX1 = pRect->x + xOrigin;
+ origY1 = pRect->y + yOrigin;
+ origX2 = origX1 + pRect->width;
+ origY2 = origY1 + pRect->height;
+
+ /* reject entire rectangle if completely outside clip rect */
+ if ((origX1 > clipXMax) || (origX2 < clipXMin) ||
+ (origY1 > clipYMax) || (origY2 < clipYMin))
+ continue;
+
+ /* clip the rectangle */
+ clippedX1 = max (origX1, clipXMin);
+ clippedX2 = min (origX2, clipXMax);
+ clippedY1 = max (origY1, clipYMin);
+ clippedY2 = min (origY2, clipYMax);
+
+ width = clippedX2 - clippedX1 + 1;
+
+ if (origY1 >= clipYMin) {
+ (*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
+ clippedX1, clippedY1, width, DEGREES_0);
+
+ /* don't overwrite corner */
+ clippedY1++;
+ }
+
+ if ((origY2 <= clipYMax) && (origY1 != origY2)) {
+ (*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
+ clippedX1, clippedY2, width, DEGREES_0);
+
+ /* don't overwrite corner */
+ clippedY2--;
+ }
+
+ if (clippedY2 < clippedY1) continue;
+
+ height = clippedY2 - clippedY1 + 1;
+
+ /* draw vertical edges using lines if not clipped out */
+ if (origX1 >= clipXMin)
+ (*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
+ clippedX1, clippedY1, height, DEGREES_270);
+
+ if ((origX2 <= clipXMax) && (origX2 != origX1))
+ (*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
+ clippedX2, clippedY1, height, DEGREES_270);
+ }
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaSpans.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaSpans.c
new file mode 100644
index 000000000..aecd21aa9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaSpans.c
@@ -0,0 +1,866 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaSpans.c,v 1.12 1999/05/30 03:03:33 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "mi.h"
+#include "mispans.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+
+static void XAARenderSolidSpans(
+ GCPtr, int, DDXPointPtr, int*, int, int, int);
+static void XAARenderColor8x8Spans(
+ GCPtr, int, DDXPointPtr, int*, int, int, int);
+static void XAARenderMono8x8Spans(
+ GCPtr, int, DDXPointPtr, int*, int, int, int);
+static void XAARenderCacheBltSpans(
+ GCPtr, int, DDXPointPtr, int*, int, int, int);
+static void XAARenderColorExpandSpans(
+ GCPtr, int, DDXPointPtr, int*, int, int, int);
+static void XAARenderCacheExpandSpans(
+ GCPtr, int, DDXPointPtr, int*, int, int, int);
+static void XAARenderPixmapCopySpans(
+ GCPtr, int, DDXPointPtr, int*, int, int, int);
+
+void
+XAAFillSpans(
+ DrawablePtr pDraw,
+ GC *pGC,
+ int nInit, /* number of spans to fill */
+ DDXPointPtr pptInit, /* pointer to list of start points */
+ int *pwidthInit, /* pointer to list of n widths */
+ int fSorted
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int type = 0;
+ ClipAndRenderSpansFunc function;
+ Bool fastClip = FALSE;
+
+ if((nInit <= 0) || !pGC->planemask)
+ return;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ switch(pGC->fillStyle) {
+ case FillSolid:
+ type = DO_SOLID;
+ break;
+ case FillStippled:
+ type = (*infoRec->StippledFillChooser)(pGC);
+ break;
+ case FillOpaqueStippled:
+ if((pGC->fgPixel == pGC->bgPixel) && infoRec->FillSpansSolid &&
+ CHECK_PLANEMASK(pGC,infoRec->FillSpansSolidFlags) &&
+ CHECK_ROP(pGC,infoRec->FillSpansSolidFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillSpansSolidFlags) &&
+ CHECK_FG(pGC,infoRec->FillSpansSolidFlags))
+ type = DO_SOLID;
+ else
+ type = (*infoRec->OpaqueStippledFillChooser)(pGC);
+ break;
+ case FillTiled:
+ type = (*infoRec->TiledFillChooser)(pGC);
+ break;
+ }
+
+ switch(type) {
+ case DO_SOLID:
+ function = XAARenderSolidSpans;
+ if(infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL)
+ fastClip = TRUE;
+ break;
+ case DO_COLOR_8x8:
+ function = XAARenderColor8x8Spans;
+ if(infoRec->ClippingFlags & HARDWARE_CLIP_COLOR_8x8_FILL)
+ fastClip = TRUE;
+ break;
+ case DO_MONO_8x8:
+ function = XAARenderMono8x8Spans;
+ if(infoRec->ClippingFlags & HARDWARE_CLIP_MONO_8x8_FILL)
+ fastClip = TRUE;
+ break;
+ case DO_CACHE_BLT:
+ function = XAARenderCacheBltSpans;
+ if(infoRec->ClippingFlags & HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY)
+ fastClip = TRUE;
+ break;
+ case DO_COLOR_EXPAND:
+ function = XAARenderColorExpandSpans;
+ break;
+ case DO_CACHE_EXPAND:
+ function = XAARenderCacheExpandSpans;
+ if(infoRec->ClippingFlags &
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND)
+ fastClip = TRUE;
+ break;
+ case DO_PIXMAP_COPY:
+ function = XAARenderPixmapCopySpans;
+ if(infoRec->ClippingFlags & HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY)
+ fastClip = TRUE;
+ break;
+ case DO_IMAGE_WRITE:
+ default:
+ (*XAAFallbackOps.FillSpans)(pDraw, pGC, nInit, pptInit,
+ pwidthInit, fSorted);
+ return;
+ }
+
+
+ if((nInit < 10) || (REGION_NUM_RECTS(pGC->pCompositeClip) != 1))
+ fastClip = FALSE;
+
+ if(fastClip) {
+ infoRec->ClipBox = &pGC->pCompositeClip->extents;
+ (*function)(pGC, nInit, pptInit, pwidthInit, fSorted,
+ pDraw->x, pDraw->y);
+ infoRec->ClipBox = NULL;
+ } else
+ XAAClipAndRenderSpans(pGC, pptInit, pwidthInit, nInit, fSorted,
+ function, pDraw->x, pDraw->y);
+}
+
+
+ /*********************\
+ | Solid Spans |
+ \*********************/
+
+
+static void
+XAARenderSolidSpans(
+ GCPtr pGC,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ (*infoRec->FillSolidSpans) (infoRec->pScrn, pGC->fgPixel,
+ pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted);
+}
+
+
+ /************************\
+ | Mono 8x8 Spans |
+ \************************/
+
+
+static void
+XAARenderMono8x8Spans(
+ GCPtr pGC,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAAPixmapPtr pPriv;
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ case FillTiled:
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+ fg = pPriv->fg; bg = pPriv->bg;
+ break;
+ }
+
+ (*infoRec->FillMono8x8PatternSpans) (infoRec->pScrn,
+ fg, bg, pGC->alu, pGC->planemask,
+ n, ppt, pwidth, fSorted, pPriv->pattern0, pPriv->pattern1,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y));
+}
+
+
+ /*************************\
+ | Color 8x8 Spans |
+ \*************************/
+
+
+static void
+XAARenderColor8x8Spans(
+ GCPtr pGC,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAACacheInfoPtr pCache;
+ XAAPixmapPtr pPriv;
+ PixmapPtr pPix;
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ pPix = pGC->stipple;
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ pPix = pGC->stipple;
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ case FillTiled:
+ pPix = pGC->tile.pixmap;
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ fg = -1; bg = -1;
+ break;
+ }
+
+ pCache = (*infoRec->CacheColor8x8Pattern)(infoRec->pScrn, pPix, fg, bg);
+
+ (*infoRec->FillColor8x8PatternSpans) (infoRec->pScrn,
+ pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted, pCache,
+ (yorg + pGC->patOrg.x), (xorg + pGC->patOrg.y));
+}
+
+
+ /****************************\
+ | Color Expand Spans |
+ \****************************/
+
+
+static void
+XAARenderColorExpandSpans(
+ GCPtr pGC,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ }
+
+ (*infoRec->FillColorExpandSpans) (infoRec->pScrn, fg, bg,
+ pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
+ pGC->stipple);
+
+}
+
+
+ /*************************\
+ | Cache Blt Spans |
+ \*************************/
+
+
+static void
+XAARenderCacheBltSpans(
+ GCPtr pGC,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAACacheInfoPtr pCache;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple,
+ pGC->fgPixel, -1);
+ break;
+ case FillOpaqueStippled:
+ pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple,
+ pGC->fgPixel, pGC->bgPixel);
+ break;
+ case FillTiled:
+ pCache = (*infoRec->CacheTile)(infoRec->pScrn, pGC->tile.pixmap);
+ break;
+ }
+
+ (*infoRec->FillCacheBltSpans) (infoRec->pScrn,
+ pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted, pCache,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y));
+
+}
+
+
+ /****************************\
+ | Cache Expand Spans |
+ \****************************/
+
+
+static void
+XAARenderCacheExpandSpans(
+ GCPtr pGC,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ }
+
+ (*infoRec->FillCacheExpandSpans) (infoRec->pScrn, fg, bg,
+ pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
+ pGC->stipple);
+}
+
+
+ /***************************\
+ | Pixmap Copy Spans |
+ \***************************/
+
+
+static void
+XAARenderPixmapCopySpans(
+ GCPtr pGC,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAACacheInfoPtr pCache = &(infoRec->ScratchCacheInfoRec);
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+
+ pCache->x = pPriv->offscreenArea->box.x1;
+ pCache->y = pPriv->offscreenArea->box.y1;
+ pCache->w = pCache->orig_w =
+ pPriv->offscreenArea->box.x2 - pCache->x;
+ pCache->h = pCache->orig_h =
+ pPriv->offscreenArea->box.y2 - pCache->y;
+
+ (*infoRec->FillCacheBltSpans) (infoRec->pScrn,
+ pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted, pCache,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y));
+}
+
+
+
+
+
+ /****************\
+ | Solid |
+ \****************/
+
+
+void
+XAAFillSolidSpans(
+ ScrnInfoPtr pScrn,
+ int fg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ if(infoRec->ClipBox)
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ infoRec->ClipBox->x1, infoRec->ClipBox->y1,
+ infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
+
+ (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask);
+ while(n--) {
+ if (*pwidth > 0)
+ (*infoRec->SubsequentSolidFillRect)(pScrn, ppt->x, ppt->y,
+ *pwidth, 1);
+ ppt++; pwidth++;
+ }
+
+ if(infoRec->ClipBox)
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+ /***************\
+ | Mono 8x8 |
+ \***************/
+
+
+void
+XAAFillMono8x8PatternSpansScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ int pattern0, int pattern1,
+ int xorigin, int yorigin
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int patx = pattern0, paty = pattern1;
+ int xorg = (-xorigin) & 0x07;
+ int yorg = (-yorigin) & 0x07;
+
+
+ if(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ XAARotateMonoPattern(&patx, &paty, xorg, yorg,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ xorg = patx; yorg = paty;
+ }
+ } else {
+ XAACacheInfoPtr pCache =
+ (*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1);
+ patx = pCache->x; paty = pCache->y;
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int slot = (yorg << 3) + xorg;
+ patx += pCache->offsets[slot].x;
+ paty += pCache->offsets[slot].y;
+ xorg = patx; yorg = paty;
+ }
+ }
+
+ if(infoRec->ClipBox)
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ infoRec->ClipBox->x1, infoRec->ClipBox->y1,
+ infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
+
+ (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty,
+ fg, bg, rop, planemask);
+
+ while(n--) {
+ (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn,
+ xorg, yorg, ppt->x, ppt->y, *pwidth, 1);
+ ppt++; pwidth++;
+ }
+
+ if(infoRec->ClipBox)
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+void
+XAAFillMono8x8PatternSpans(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ int pattern0, int pattern1,
+ int xorigin, int yorigin
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int patx = pattern0, paty = pattern1;
+ int xorg, yorg, slot;
+ XAACacheInfoPtr pCache;
+
+
+ if(!(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS)){
+ pCache = (*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1);
+ patx = pCache->x; paty = pCache->y;
+ }
+
+ if(infoRec->ClipBox)
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ infoRec->ClipBox->x1, infoRec->ClipBox->y1,
+ infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
+
+ (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty,
+ fg, bg, rop, planemask);
+
+ while(n--) {
+ xorg = (ppt->x - xorigin) & 0x07;
+ yorg = (ppt->y - yorigin) & 0x07;
+
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ patx = pattern0; paty = pattern1;
+ XAARotateMonoPattern(&patx, &paty, xorg, yorg,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ xorg = patx; yorg = paty;
+ } else {
+ slot = (yorg << 3) + xorg;
+ xorg = patx + pCache->offsets[slot].x;
+ yorg = paty + pCache->offsets[slot].y;
+ }
+ }
+
+ (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn,
+ xorg, yorg, ppt->x, ppt->y, *pwidth, 1);
+ ppt++; pwidth++;
+ }
+
+ if(infoRec->ClipBox)
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+
+ /****************\
+ | Color 8x8 |
+ \****************/
+
+
+void
+XAAFillColor8x8PatternSpansScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ XAACacheInfoPtr pCache,
+ int xorigin, int yorigin
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int patx = pCache->x, paty = pCache->y;
+ int xorg = (-xorigin) & 0x07;
+ int yorg = (-yorigin) & 0x07;
+
+
+ if(!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int slot = (yorg << 3) + xorg;
+ paty += pCache->offsets[slot].y;
+ patx += pCache->offsets[slot].x;
+ xorg = patx; yorg = paty;
+ }
+
+ if(infoRec->ClipBox)
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ infoRec->ClipBox->x1, infoRec->ClipBox->y1,
+ infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
+
+ (*infoRec->SetupForColor8x8PatternFill)(pScrn, patx, paty,
+ rop, planemask, pCache->trans_color);
+
+ while(n--) {
+ (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn,
+ xorg, yorg, ppt->x, ppt->y, *pwidth, 1);
+ ppt++; pwidth++;
+ }
+
+ if(infoRec->ClipBox)
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+void
+XAAFillColor8x8PatternSpans(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ XAACacheInfoPtr pCache,
+ int xorigin, int yorigin
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int xorg, yorg, slot;
+
+
+ if(infoRec->ClipBox)
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ infoRec->ClipBox->x1, infoRec->ClipBox->y1,
+ infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
+
+ (*infoRec->SetupForColor8x8PatternFill)(pScrn, pCache->x, pCache->y,
+ rop, planemask, pCache->trans_color);
+
+ while(n--) {
+ xorg = (ppt->x - xorigin) & 0x07;
+ yorg = (ppt->y - yorigin) & 0x07;
+
+ if(!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ slot = (yorg << 3) + xorg;
+ yorg = pCache->y + pCache->offsets[slot].y;
+ xorg = pCache->x + pCache->offsets[slot].x;
+ }
+
+ (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn,
+ xorg, yorg, ppt->x, ppt->y, *pwidth, 1);
+ ppt++; pwidth++;
+ }
+
+ if(infoRec->ClipBox)
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+ /*****************\
+ | Cache Blit |
+ \*****************/
+
+
+void
+XAAFillCacheBltSpans(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ XAACacheInfoPtr pCache,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, w, phaseX, phaseY, blit_w;
+
+ if(infoRec->ClipBox)
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ infoRec->ClipBox->x1, infoRec->ClipBox->y1,
+ infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
+
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, rop, planemask,
+ pCache->trans_color);
+
+ while(n--) {
+ x = ppt->x;
+ w = *pwidth;
+ phaseX = (x - xorg) % pCache->orig_w;
+ if(phaseX < 0) phaseX += pCache->orig_w;
+ phaseY = (ppt->y - yorg) % pCache->orig_h;
+ if(phaseY < 0) phaseY += pCache->orig_h;
+
+ while(1) {
+ blit_w = pCache->w - phaseX;
+ if(blit_w > w) blit_w = w;
+
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pCache->x + phaseX, pCache->y + phaseY,
+ x, ppt->y, blit_w, 1);
+
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ phaseX = (phaseX + blit_w) % pCache->orig_w;
+ }
+ ppt++; pwidth++;
+ }
+
+ if(infoRec->ClipBox)
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+ /****************\
+ | Cache Expand |
+ \****************/
+
+
+void
+XAAFillCacheExpandSpans(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, w, phaseX, phaseY, blit_w, cacheWidth;
+ XAACacheInfoPtr pCache;
+
+ pCache = (*infoRec->CacheMonoStipple)(pScrn, pPix);
+
+ cacheWidth = (pCache->w * pScrn->bitsPerPixel) /
+ infoRec->CacheColorExpandDensity;
+
+ if(infoRec->ClipBox)
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ infoRec->ClipBox->x1, infoRec->ClipBox->y1,
+ infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
+
+ (*infoRec->SetupForScreenToScreenColorExpandFill)(pScrn, fg, bg, rop,
+ planemask);
+
+ while(n--) {
+ x = ppt->x;
+ w = *pwidth;
+ phaseX = (x - xorg) % pCache->orig_w;
+ if(phaseX < 0) phaseX += pCache->orig_w;
+ phaseY = (ppt->y - yorg) % pCache->orig_h;
+ if(phaseY < 0) phaseY += pCache->orig_h;
+
+ while(1) {
+ blit_w = cacheWidth - phaseX;
+ if(blit_w > w) blit_w = w;
+
+ (*infoRec->SubsequentScreenToScreenColorExpandFill)(
+ pScrn, x, ppt->y, blit_w, 1,
+ pCache->x, pCache->y + phaseY, phaseX);
+
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ phaseX = (phaseX + blit_w) % pCache->orig_w;
+ }
+ ppt++; pwidth++;
+ }
+
+ if(infoRec->ClipBox)
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+
+void
+XAAClipAndRenderSpans(
+ GCPtr pGC,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted,
+ ClipAndRenderSpansFunc func,
+ int xorg,
+ int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ DDXPointPtr pptNew, pptBase;
+ int *pwidthBase, *pwidthNew;
+ int Right, numRects, MaxBoxes;
+
+ MaxBoxes = infoRec->PreAllocSize/(sizeof(DDXPointRec) + sizeof(int));
+ pptBase = (DDXPointRec*)infoRec->PreAllocMem;
+ pwidthBase = (int*)(&pptBase[MaxBoxes]);
+
+ pptNew = pptBase;
+ pwidthNew = pwidthBase;
+
+ numRects = REGION_NUM_RECTS(pGC->pCompositeClip);
+
+ if(numRects == 1) {
+ BoxPtr pextent = REGION_RECTS(pGC->pCompositeClip);
+
+ while(nspans--) {
+ if ((pextent->y1 <= ppt->y) && (ppt->y < pextent->y2)) {
+ pptNew->x = max(pextent->x1, ppt->x);
+ Right = ppt->x + *pwidth;
+ *pwidthNew = min(pextent->x2, Right) - pptNew->x;
+
+ if (*pwidthNew > 0) {
+ pptNew->y = ppt->y;
+ pptNew++;
+ pwidthNew++;
+
+ if(pptNew >= (pptBase + MaxBoxes)) {
+ (*func)(pGC, MaxBoxes, pptBase, pwidthBase, fSorted,
+ xorg, yorg);
+ pptNew = pptBase;
+ pwidthNew = pwidthBase;
+ }
+ }
+ }
+ ppt++;
+ pwidth++;
+ }
+ } else if (numRects) {
+ BoxPtr pbox;
+ int nbox;
+
+ while(nspans--) {
+ nbox = numRects;
+ pbox = REGION_RECTS(pGC->pCompositeClip);
+
+ /* find the first band */
+ while(nbox && (pbox->y2 <= ppt->y)) {
+ pbox++;
+ nbox--;
+ }
+
+ if(nbox && (pbox->y1 <= ppt->y)) {
+ int orig_y = pbox->y1;
+ Right = ppt->x + *pwidth;
+ while(nbox && (orig_y == pbox->y1)) {
+ if(pbox->x2 <= ppt->x) {
+ nbox--;
+ pbox++;
+ continue;
+ }
+
+ if(pbox->x1 >= Right) {
+ nbox = 0;
+ break;
+ }
+
+ pptNew->x = max(pbox->x1, ppt->x);
+ *pwidthNew = min(pbox->x2, Right) - pptNew->x;
+ if(*pwidthNew > 0) {
+ pptNew->y = ppt->y;
+ pptNew++;
+ pwidthNew++;
+
+ if(pptNew >= (pptBase + MaxBoxes)) {
+ (*func)(pGC, MaxBoxes, pptBase, pwidthBase,
+ fSorted, xorg, yorg);
+ pptNew = pptBase;
+ pwidthNew = pwidthBase;
+ }
+ }
+ pbox++;
+ nbox--;
+ }
+ }
+ ppt++;
+ pwidth++;
+ }
+ }
+
+ if(pptNew != pptBase)
+ (*func)(pGC, pptNew - pptBase, pptBase, pwidthBase, fSorted,
+ xorg, yorg);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaStipple.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaStipple.c
new file mode 100644
index 000000000..a3d3dd44f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaStipple.c
@@ -0,0 +1,642 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaStipple.c,v 1.5 1999/08/14 10:50:14 dawes Exp $ */
+
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaacexp.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+
+static CARD32* StipplePowerOfTwo(CARD32*, CARD32*, int, int, int);
+static CARD32* StipplePowerOfTwo_Inverted(CARD32*, CARD32*, int, int, int);
+static CARD32* StippleUpTo32(CARD32*, CARD32*, int, int, int);
+static CARD32* StippleUpTo32_Inverted(CARD32*, CARD32*, int, int, int);
+static CARD32* StippleOver32(CARD32*, CARD32*, int, int, int);
+static CARD32* StippleOver32_Inverted(CARD32*, CARD32*, int, int, int);
+
+#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc)
+
+StippleScanlineProcPtr stipple_scanline_func[6] = {
+ StipplePowerOfTwo,
+ StippleUpTo32,
+ StippleOver32,
+ StipplePowerOfTwo_Inverted,
+ StippleUpTo32_Inverted,
+ StippleOver32_Inverted
+};
+
+
+#ifdef FIXEDBASE
+# define DEST(i) *dest
+# define RETURN(i) return(dest)
+#else
+# define DEST(i) dest[i]
+# define RETURN(i) return(dest + i)
+#endif
+
+
+#if defined(FIXEDBASE) && defined(MSBFIRST)
+
+unsigned int XAAShiftMasks[32] = {
+ 0x00000000, 0x00000001, 0x00000003, 0x00000007,
+ 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F,
+ 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
+ 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF,
+ 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF,
+ 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
+ 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF,
+ 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF
+};
+
+#endif
+
+void
+EXPNAME(XAAFillColorExpandRects)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *base;
+ Bool TwoPass = FALSE, FirstPass = TRUE;
+ StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
+ int stipplewidth = pPix->drawable.width;
+ int stippleheight = pPix->drawable.height;
+ int srcwidth = pPix->devKind;
+ int dwords, srcy, srcx, funcNo = 2, h;
+ unsigned char *src = (unsigned char*)pPix->devPrivate.ptr;
+ unsigned char *srcp;
+ int flag;
+
+ if(stipplewidth <= 32) {
+ if(stipplewidth & (stipplewidth - 1))
+ funcNo = 1;
+ else
+ funcNo = 0;
+ }
+ StippleFunc = stipple_scanline_func[funcNo];
+
+ if((bg == -1) ||
+ !(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
+ /* one pass */
+ } else if((rop == GXcopy) && infoRec->FillSolidRects) {
+ /* one pass but we fill background rects first */
+ (*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox);
+ bg = -1;
+ } else {
+ /* gotta do two passes */
+ TwoPass = TRUE;
+ SecondFunc = stipple_scanline_func[funcNo];
+ FirstFunc = stipple_scanline_func[funcNo + 3];
+ }
+
+ if(!TwoPass)
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ while(nBox--) {
+ dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
+
+SECOND_PASS:
+ if(TwoPass) {
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn,
+ (FirstPass) ? bg : fg, -1, rop, planemask);
+ StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
+ }
+
+ h = pBox->y2 - pBox->y1;
+ flag = (infoRec->CPUToScreenColorExpandFillFlags
+ & CPU_TRANSFER_PAD_QWORD) && ((dwords * h) & 0x01);
+
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, h, 0);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+ srcy = (pBox->y1 - yorg) % stippleheight;
+ if(srcy < 0) srcy += stippleheight;
+ srcx = (pBox->x1 - xorg) % stipplewidth;
+ if(srcx < 0) srcx += stipplewidth;
+
+ srcp = (srcwidth * srcy) + src;
+
+#ifndef FIXEDBASE
+ if((dwords * h) <= infoRec->ColorExpandRange) {
+ while(h--) {
+ base = (*StippleFunc)(
+ base, (CARD32*)srcp, srcx, stipplewidth, dwords);
+ srcy++;
+ srcp += srcwidth;
+ if (srcy >= stippleheight) {
+ srcy = 0;
+ srcp = src;
+ }
+ }
+ } else
+#endif
+ while(h--) {
+ (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
+ srcy++;
+ srcp += srcwidth;
+ if (srcy >= stippleheight) {
+ srcy = 0;
+ srcp = src;
+ }
+ }
+
+ if (flag) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+
+ if(TwoPass) {
+ if(FirstPass) {
+ FirstPass = FALSE;
+ goto SECOND_PASS;
+ } else FirstPass = TRUE;
+ }
+
+ pBox++;
+ }
+
+ if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+
+
+void
+EXPNAME(XAAFillColorExpandSpans)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *base;
+ Bool TwoPass = FALSE, FirstPass = TRUE;
+ StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
+ int stipplewidth = pPix->drawable.width;
+ int stippleheight = pPix->drawable.height;
+ int dwords, srcy, srcx, funcNo = 2;
+ unsigned char *srcp;
+
+ if(stipplewidth <= 32) {
+ if(stipplewidth & (stipplewidth - 1))
+ funcNo = 1;
+ else
+ funcNo = 0;
+ }
+ StippleFunc = stipple_scanline_func[funcNo];
+
+ if((bg == -1) ||
+ !(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
+ /* one pass */
+ } else if((rop == GXcopy) && infoRec->FillSolidSpans) {
+ /* one pass but we fill background rects first */
+ (*infoRec->FillSolidSpans)(
+ pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted);
+ bg = -1;
+ } else {
+ /* gotta do two passes */
+ TwoPass = TRUE;
+ SecondFunc = stipple_scanline_func[funcNo];
+ FirstFunc = stipple_scanline_func[funcNo + 3];
+ }
+
+ if(!TwoPass)
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ while(n--) {
+ dwords = (*pwidth + 31) >> 5;
+
+ srcy = (ppt->y - yorg) % stippleheight;
+ if(srcy < 0) srcy += stippleheight;
+ srcx = (ppt->x - xorg) % stipplewidth;
+ if(srcx < 0) srcx += stipplewidth;
+
+ srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr;
+
+SECOND_PASS:
+ if(TwoPass) {
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn,
+ (FirstPass) ? bg : fg, -1, rop, planemask);
+ StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
+ }
+
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(pScrn, ppt->x, ppt->y,
+ *pwidth, 1, 0);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+ (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
+
+ if((infoRec->CPUToScreenColorExpandFillFlags & CPU_TRANSFER_PAD_QWORD)
+ && (dwords & 0x01)) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+
+ if(TwoPass) {
+ if(FirstPass) {
+ FirstPass = FALSE;
+ goto SECOND_PASS;
+ } else FirstPass = TRUE;
+ }
+
+ ppt++; pwidth++;
+ }
+
+ if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+
+#ifndef FIXEDBASE
+
+void
+EXPNAME(XAAFillScanlineColorExpandRects)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *base;
+ Bool TwoPass = FALSE, FirstPass = TRUE;
+ StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
+ int stipplewidth = pPix->drawable.width;
+ int stippleheight = pPix->drawable.height;
+ int srcwidth = pPix->devKind;
+ int dwords, srcy, srcx, funcNo = 2, bufferNo, h;
+ unsigned char *src = pPix->devPrivate.ptr;
+ unsigned char *srcp;
+
+ if(stipplewidth <= 32) {
+ if(stipplewidth & (stipplewidth - 1))
+ funcNo = 1;
+ else
+ funcNo = 0;
+ }
+ StippleFunc = stipple_scanline_func[funcNo];
+
+ if((bg == -1) ||
+ !(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
+ /* one pass */
+ } else if((rop == GXcopy) && infoRec->FillSolidRects) {
+ /* one pass but we fill background rects first */
+ (*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox);
+ bg = -1;
+ } else {
+ /* gotta do two passes */
+ TwoPass = TRUE;
+ SecondFunc = stipple_scanline_func[funcNo];
+ FirstFunc = stipple_scanline_func[funcNo + 3];
+ }
+
+ if(!TwoPass)
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ while(nBox--) {
+ dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
+SECOND_PASS:
+ if(TwoPass) {
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn,
+ (FirstPass) ? bg : fg, -1, rop, planemask);
+ StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
+ }
+
+ h = pBox->y2 - pBox->y1;
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, pBox->x1, pBox->y1, pBox->x2 - pBox->x1, h, 0);
+
+ bufferNo = 0;
+
+ srcy = (pBox->y1 - yorg) % stippleheight;
+ if(srcy < 0) srcy += stippleheight;
+ srcx = (pBox->x1 - xorg) % stipplewidth;
+ if(srcx < 0) srcx += stipplewidth;
+
+ srcp = (srcwidth * srcy) + src;
+
+ while(h--) {
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ srcy++;
+ srcp += srcwidth;
+ if (srcy >= stippleheight) {
+ srcy = 0;
+ srcp = src;
+ }
+ }
+
+ if(TwoPass) {
+ if(FirstPass) {
+ FirstPass = FALSE;
+ goto SECOND_PASS;
+ } else FirstPass = TRUE;
+ }
+
+ pBox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+void
+EXPNAME(XAAFillScanlineColorExpandSpans)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *base;
+ Bool TwoPass = FALSE, FirstPass = TRUE;
+ StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
+ int stipplewidth = pPix->drawable.width;
+ int stippleheight = pPix->drawable.height;
+ int dwords, srcy, srcx, funcNo = 2;
+ unsigned char *srcp;
+
+ if(stipplewidth <= 32) {
+ if(stipplewidth & (stipplewidth - 1))
+ funcNo = 1;
+ else
+ funcNo = 0;
+ }
+ StippleFunc = stipple_scanline_func[funcNo];
+
+ if((bg == -1) ||
+ !(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
+ /* one pass */
+ } else if((rop == GXcopy) && infoRec->FillSolidSpans) {
+ /* one pass but we fill background rects first */
+ (*infoRec->FillSolidSpans)(
+ pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted);
+ bg = -1;
+ } else {
+ /* gotta do two passes */
+ TwoPass = TRUE;
+ SecondFunc = stipple_scanline_func[funcNo];
+ FirstFunc = stipple_scanline_func[funcNo + 3];
+ }
+
+ if(!TwoPass)
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+
+ while(n--) {
+ dwords = (*pwidth + 31) >> 5;
+
+ srcy = (ppt->y - yorg) % stippleheight;
+ if(srcy < 0) srcy += stippleheight;
+ srcx = (ppt->x - xorg) % stipplewidth;
+ if(srcx < 0) srcx += stipplewidth;
+
+ srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr;
+
+SECOND_PASS:
+ if(TwoPass) {
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn,
+ (FirstPass) ? bg : fg, -1, rop, planemask);
+ StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
+ }
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, ppt->x, ppt->y, *pwidth, 1, 0);
+
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[0];
+
+ (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, 0);
+
+ if(TwoPass) {
+ if(FirstPass) {
+ FirstPass = FALSE;
+ goto SECOND_PASS;
+ } else FirstPass = TRUE;
+ }
+
+ ppt++; pwidth++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+#endif
+
+static CARD32 *
+StipplePowerOfTwo(
+ CARD32* dest, CARD32* src,
+ int shift, int width, int dwords
+){
+ CARD32 pat = *src;
+ if(width < 32) {
+ pat &= XAAShiftMasks[width];
+ while(width < 32) {
+ pat |= SHIFT_L(pat,width);
+ width <<= 1;
+ }
+ }
+
+ if(shift)
+ pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift);
+
+#ifdef MSBFIRST
+ pat = XAAReverseBitOrder(pat);
+#endif
+
+ while(dwords >= 4) {
+ DEST(0) = pat;
+ DEST(1) = pat;
+ DEST(2) = pat;
+ DEST(3) = pat;
+ dwords -= 4;
+#ifndef FIXEDBASE
+ dest += 4;
+#endif
+ }
+
+ if(!dwords) return dest;
+ DEST(0) = pat;
+ if(dwords == 1) RETURN(1);
+ DEST(1) = pat;
+ if(dwords == 2) RETURN(2);
+ DEST(2) = pat;
+ RETURN(3);
+}
+
+static CARD32 *
+StipplePowerOfTwo_Inverted(
+ CARD32* dest, CARD32* src,
+ int shift, int width, int dwords
+){
+ CARD32 pat = *src;
+ if(width < 32) {
+ pat &= XAAShiftMasks[width];
+ while(width < 32) {
+ pat |= SHIFT_L(pat,width);
+ width <<= 1;
+ }
+ }
+
+ if(shift)
+ pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift);
+
+#ifdef MSBFIRST
+ pat = XAAReverseBitOrder(pat);
+#endif
+
+ pat = ~pat;
+
+ while(dwords >= 4) {
+ DEST(0) = pat;
+ DEST(1) = pat;
+ DEST(2) = pat;
+ DEST(3) = pat;
+ dwords -= 4;
+#ifndef FIXEDBASE
+ dest += 4;
+#endif
+ }
+
+ if(!dwords) return dest;
+ DEST(0) = pat;
+ if(dwords == 1) RETURN(1);
+ DEST(1) = pat;
+ if(dwords == 2) RETURN(2);
+ DEST(2) = pat;
+ RETURN(3);
+}
+
+
+static CARD32 *
+StippleUpTo32(
+ CARD32* base, CARD32* src,
+ int shift, int width, int dwords
+){
+ int offset = shift;
+ CARD32 pat = *src & XAAShiftMasks[width];
+
+ while(width <= 15) {
+ pat |= SHIFT_L(pat,width);
+ width <<= 1;
+ }
+ pat |= SHIFT_L(pat,width);
+
+ while(dwords--) {
+ WRITE_BITS(SHIFT_R(pat,offset) | SHIFT_L(pat,width-offset));
+ offset += 32;
+ while(offset >= width) offset -= width;
+ }
+ return base;
+}
+
+
+static CARD32 *
+StippleUpTo32_Inverted(
+ CARD32* base, CARD32* src,
+ int shift, int width, int dwords
+){
+ CARD32 pat = *src & XAAShiftMasks[width];
+
+ while(width <= 15) {
+ pat |= SHIFT_L(pat,width);
+ width <<= 1;
+ }
+ pat |= SHIFT_L(pat,width);
+
+ while(dwords--) {
+ WRITE_BITS(~(SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift)));
+ shift += 32;
+ while(shift >= width) shift -= width;
+ }
+ return base;
+}
+
+
+static CARD32 *
+StippleOver32(
+ CARD32* base, CARD32* src,
+ int offset, int width, int dwords
+){
+ CARD32* srcp;
+ int bitsleft, shift;
+
+ while(dwords--) {
+ bitsleft = width - offset;
+ srcp = (CARD32*)(src + (offset >> 5));
+ shift = offset & 31;
+
+ if(bitsleft >= 32) {
+ if(shift)
+ WRITE_BITS(SHIFT_R(*srcp,shift) |
+ SHIFT_L(srcp[1],32-shift));
+ else
+ WRITE_BITS(*srcp);
+ } else {
+ WRITE_BITS(SHIFT_L(*src,bitsleft) |
+ (SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]));
+ }
+ offset += 32;
+ while(offset >= width) offset -= width;
+ }
+ return base;
+}
+
+
+static CARD32 *
+StippleOver32_Inverted(
+ CARD32* base, CARD32* src,
+ int offset, int width, int dwords
+){
+ CARD32* srcp;
+ int bitsleft, shift;
+
+ while(dwords--) {
+ bitsleft = width - offset;
+ srcp = (CARD32*)(src + (offset >> 5));
+ shift = offset & 31;
+
+ if(bitsleft >= 32) {
+ if(shift)
+ WRITE_BITS(~(SHIFT_R(*srcp,shift) |
+ SHIFT_L(srcp[1],32-shift)));
+ else
+ WRITE_BITS(~(*srcp));
+ } else {
+ WRITE_BITS(~(SHIFT_L(*src,bitsleft) |
+ (SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft])));
+ }
+ offset += 32;
+ while(offset >= width) offset -= width;
+ }
+ return base;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaTEGlyph.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaTEGlyph.c
new file mode 100644
index 000000000..06332cf9f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaTEGlyph.c
@@ -0,0 +1,1076 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaTEGlyph.c,v 1.6 1999/08/14 10:50:14 dawes Exp $ */
+
+
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaacexp.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+
+
+/* scanline function for TRIPLE_BITS_24BPP */
+static CARD32 *DrawTextScanline3(CARD32 *base, CARD32 *mem, int width);
+
+/* Loop unrolled functions for common font widths */
+static CARD32 *DrawTETextScanlineGeneric(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth7(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth10(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth12(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth14(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth16(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth18(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth24(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+
+
+#ifdef USEASSEMBLER
+# ifdef FIXEDBASE
+# ifdef MSBFIRST
+CARD32 *DrawTETextScanlineWidth6PMSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth8PMSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth9PMSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+# else
+CARD32 *DrawTETextScanlineWidth6PLSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth8PLSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth9PLSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+# endif
+# else
+# ifdef MSBFIRST
+CARD32 *DrawTETextScanlineWidth6PMSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth8PMSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth9PMSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+# else
+CARD32 *DrawTETextScanlineWidth6PLSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth8PLSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth9PLSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+# endif
+# endif
+#else
+static CARD32 *DrawTETextScanlineWidth6(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth8(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth9(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+#endif
+
+#define glyph_scanline_func EXPNAME(XAAGlyphScanlineFunc)
+
+
+
+GlyphScanlineFuncPtr glyph_scanline_func[32] = {
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric,
+#ifdef USEASSEMBLER
+# ifdef FIXEDBASE
+# ifdef MSBFIRST
+ DrawTETextScanlineWidth6PMSBFirstFixedBase,
+ DrawTETextScanlineWidth7,
+ DrawTETextScanlineWidth8PMSBFirstFixedBase,
+ DrawTETextScanlineWidth9PMSBFirstFixedBase,
+# else
+ DrawTETextScanlineWidth6PLSBFirstFixedBase,
+ DrawTETextScanlineWidth7,
+ DrawTETextScanlineWidth8PLSBFirstFixedBase,
+ DrawTETextScanlineWidth9PLSBFirstFixedBase,
+# endif
+# else
+# ifdef MSBFIRST
+ DrawTETextScanlineWidth6PMSBFirst,
+ DrawTETextScanlineWidth7,
+ DrawTETextScanlineWidth8PMSBFirst,
+ DrawTETextScanlineWidth9PMSBFirst,
+# else
+ DrawTETextScanlineWidth6PLSBFirst,
+ DrawTETextScanlineWidth7,
+ DrawTETextScanlineWidth8PLSBFirst,
+ DrawTETextScanlineWidth9PLSBFirst,
+# endif
+# endif
+#else
+ DrawTETextScanlineWidth6, DrawTETextScanlineWidth7,
+ DrawTETextScanlineWidth8, DrawTETextScanlineWidth9,
+#endif
+ DrawTETextScanlineWidth10,
+ DrawTETextScanlineGeneric, DrawTETextScanlineWidth12,
+ DrawTETextScanlineGeneric, DrawTETextScanlineWidth14,
+ DrawTETextScanlineGeneric, DrawTETextScanlineWidth16,
+ DrawTETextScanlineGeneric, DrawTETextScanlineWidth18,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineWidth24,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric
+};
+
+
+/********************************************************************
+
+ Here we have TEGlyphRenders for a bunch of different color
+ expansion types. The driver may provide its own renderer, but
+ this is the default one which renders using lower-level primitives
+ exported by the chipset driver.
+
+********************************************************************/
+
+/* This gets built for MSBFIRST or LSBFIRST with FIXEDBASE or not.
+ A total of 4 versions */
+
+void
+EXPNAME(XAATEGlyphRenderer)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32* base;
+ GlyphScanlineFuncPtr GlyphFunc = glyph_scanline_func[glyphWidth - 1];
+ int dwords = 0;
+
+ if((bg != -1) &&
+ (infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ bg = -1;
+ }
+
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ if(skipleft &&
+ (!(infoRec->CPUToScreenColorExpandFillFlags & LEFT_EDGE_CLIPPING) ||
+ (!(infoRec->CPUToScreenColorExpandFillFlags &
+ LEFT_EDGE_CLIPPING_NEGATIVE_X) &&
+ (skipleft > x)))) {
+ /* draw the first character only */
+
+ int count = h, line = startline;
+ int width = glyphWidth - skipleft;
+
+ if(width > w) width = w;
+
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, x, y, width, h, 0);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+ while(count--) {
+ WRITE_BITS(SHIFT_R(glyphs[0][line++],skipleft));
+ }
+
+ w -= width;
+ if((infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_PAD_QWORD) &&
+ ((((width + 31) >> 5) * h) & 1)) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+ if(!w) goto THE_END;
+ glyphs++;
+ x += width;
+ skipleft = 0; /* nicely aligned again */
+ }
+
+ w += skipleft;
+ x -= skipleft;
+ dwords = ((w + 31) >> 5) * h;
+
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, x, y, w, h, skipleft);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+#ifndef FIXEDBASE
+ if((((w + 31) >> 5) * h) <= infoRec->ColorExpandRange)
+ while(h--) {
+ base = (*GlyphFunc)(base, glyphs, startline++, w, glyphWidth);
+ }
+ else
+#endif
+ while(h--) {
+ (*GlyphFunc)(base, glyphs, startline++, w, glyphWidth);
+ }
+
+ if((infoRec->CPUToScreenColorExpandFillFlags & CPU_TRANSFER_PAD_QWORD) &&
+ (dwords & 1)) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+
+THE_END:
+
+ if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+/********************************************************************
+
+ This is the GlyphRenderer for TRIPLE_BITS_24BPP. It renders to a buffer
+ with the non FIXEDBASE LSB_FIRST code before tripling, and possibly
+ reversing the bits and sending them to the screen
+
+********************************************************************/
+
+void
+EXPNAME(XAATEGlyphRenderer3)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *base, *mem;
+ GlyphScanlineFuncPtr GlyphFunc = XAAGlyphScanlineFuncLSBFirst[glyphWidth - 1];
+ int dwords = 0;
+
+ if((bg != -1) &&
+ ((infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) ||
+ ((infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) &&
+ (!CHECK_RGB_EQUAL(bg))))) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ bg = -1;
+ }
+
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ if(skipleft) {
+ /* draw the first character only */
+
+ int count = h, line = startline;
+ int width = glyphWidth - skipleft;
+ CARD32 bits;
+
+ if(width > w) width = w;
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, x, y, width, h, 0);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+ while(count--) {
+ bits = SHIFT_R(glyphs[0][line++],skipleft);
+ if (width >= 22) {
+ WRITE_BITS3(bits);
+ } else if (width >= 11) {
+ WRITE_BITS2(bits);
+ } else {
+ WRITE_BITS1(bits);
+ }
+ }
+
+ w -= width;
+ if((infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_PAD_QWORD) &&
+ ((((3 * width + 31) >> 5) * h) & 1)) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+ if(!w) goto THE_END;
+ glyphs++;
+ x += width;
+ skipleft = 0; /* nicely aligned again */
+ }
+
+ dwords = ((3 * w + 31) >> 5) * h;
+ mem = (CARD32*)ALLOCATE_LOCAL(((w + 31) >> 3) * sizeof(char));
+ if (!mem) return;
+
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(pScrn, x, y, w, h, 0);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+# ifndef FIXEDBASE
+ if((((3 * w + 31) >> 5) * h) <= infoRec->ColorExpandRange)
+ while(h--) {
+ (*GlyphFunc)(mem, glyphs, startline++, w, glyphWidth);
+ base = DrawTextScanline3(base, mem, w);
+ }
+ else
+# endif
+ while(h--) {
+ (*GlyphFunc)(mem, glyphs, startline++, w, glyphWidth);
+ DrawTextScanline3(base, mem, w);
+ }
+
+ DEALLOCATE_LOCAL(mem);
+
+ if((infoRec->CPUToScreenColorExpandFillFlags & CPU_TRANSFER_PAD_QWORD) &&
+ (dwords & 1)) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+
+THE_END:
+
+ if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+
+#ifndef FIXEDBASE
+/* Scanline version of above gets built for LSBFIRST and MSBFIRST */
+
+void
+EXPNAME(XAATEGlyphRendererScanline)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int bufferNo;
+ CARD32* base = (CARD32*)infoRec->ScanlineColorExpandBuffers[0];
+ GlyphScanlineFuncPtr GlyphFunc = glyph_scanline_func[glyphWidth - 1];
+
+ if((bg != -1) &&
+ (infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ bg = -1;
+ }
+
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ if(skipleft &&
+ (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ LEFT_EDGE_CLIPPING) ||
+ (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ LEFT_EDGE_CLIPPING_NEGATIVE_X) && (skipleft > x)))) {
+ /* draw the first character only */
+
+ int count = h, line = startline;
+ int width = glyphWidth - skipleft;
+
+ if(width > w) width = w;
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, x, y, width, h, 0);
+
+ bufferNo = 0;
+
+ while(count--) {
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ WRITE_BITS(SHIFT_R(glyphs[0][line++],skipleft));
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ }
+
+ w -= width;
+ if(!w) goto THE_END;
+ glyphs++;
+ x += width;
+ skipleft = 0; /* nicely aligned again */
+ }
+
+ w += skipleft;
+ x -= skipleft;
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, x, y, w, h, skipleft);
+
+ bufferNo = 0;
+
+ while(h--) {
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ (*GlyphFunc)(base, glyphs, startline++, w, glyphWidth);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ }
+
+THE_END:
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+void
+EXPNAME(XAATEGlyphRendererScanline3)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int bufferNo;
+ CARD32 *base, *mem;
+ GlyphScanlineFuncPtr GlyphFunc = XAAGlyphScanlineFuncLSBFirst[glyphWidth - 1];
+
+ if((bg != -1) &&
+ ((infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) ||
+ ((infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) &&
+ (!CHECK_RGB_EQUAL(bg))))) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ bg = -1;
+ }
+
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ if(skipleft) {
+ /* draw the first character only */
+
+ int count = h, line = startline;
+ int width = glyphWidth - skipleft;
+ CARD32 bits;
+
+ if(width > w) width = w;
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, x, y, width, h, 0);
+
+ bufferNo = 0;
+
+ while(count--) {
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ bits = SHIFT_R(glyphs[0][line++],skipleft);
+ if (width >= 22) {
+ WRITE_BITS3(bits);
+ } else if (width >= 11) {
+ WRITE_BITS2(bits);
+ } else {
+ WRITE_BITS1(bits);
+ }
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ }
+
+ w -= width;
+ if(!w) goto THE_END;
+ glyphs++;
+ x += width;
+ skipleft = 0; /* nicely aligned again */
+ }
+
+ w += skipleft;
+ x -= skipleft;
+ mem = (CARD32*)ALLOCATE_LOCAL(((w + 31) >> 3) * sizeof(char));
+ if (!mem) return;
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, x, y, w, h, skipleft);
+
+ bufferNo = 0;
+
+ while(h--) {
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ (*GlyphFunc)(mem, glyphs, startline++, w, glyphWidth);
+ DrawTextScanline3(base, mem, w);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ }
+
+ DEALLOCATE_LOCAL(mem);
+
+THE_END:
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+#endif
+
+
+
+/********************************************************************
+
+ TRIPLE_BITS_24BPP scanline rendering code.
+
+********************************************************************/
+
+
+
+static CARD32*
+DrawTextScanline3(
+ CARD32 *base,
+ CARD32 *mem,
+ int width )
+{
+
+ while(width > 32) {
+ WRITE_BITS3(*mem);
+ mem++;
+ width -= 32;
+ }
+ if(width) {
+ if (width >= 22) {
+ WRITE_BITS3(*mem);
+ } else if (width >= 11) {
+ WRITE_BITS2(*mem);
+ } else {
+ WRITE_BITS1(*mem);
+ }
+ }
+
+ return base;
+}
+
+
+/********************************************************************
+
+ Generic TE scanline rendering code.
+
+********************************************************************/
+
+
+
+static CARD32*
+DrawTETextScanlineGeneric(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ CARD32 bits = (*glyphp)[line];
+ int shift = glyphwidth;
+
+ while(width > 32) {
+ while(shift < 32) {
+ glyphp++;
+ bits |= SHIFT_L((*glyphp)[line], shift);
+ shift += glyphwidth;
+ }
+ WRITE_BITS(bits);
+ shift &= 31;
+ if(shift)
+ bits = SHIFT_R((*glyphp)[line],(glyphwidth - shift));
+ else bits = 0;
+ width -= 32;
+ }
+
+ if(width) {
+ width -= shift;
+ while(width > 0) {
+ glyphp++;
+ bits |= SHIFT_L((*glyphp)[line],shift);
+ shift += glyphwidth;
+ width -= glyphwidth;
+ }
+ WRITE_BITS(bits);
+ }
+
+ return base;
+}
+
+
+/********************************************************************
+
+ Loop unrolled TE font scanline rendering code
+
+********************************************************************/
+
+
+#ifndef USEASSEMBLER
+static CARD32*
+DrawTETextScanlineWidth6(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],6);
+ bits |= SHIFT_L(glyphp[2][line],12);
+ bits |= SHIFT_L(glyphp[3][line],18);
+ bits |= SHIFT_L(glyphp[4][line],24);
+ bits |= SHIFT_L(glyphp[5][line],30);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[5][line],2);
+ bits |= SHIFT_L(glyphp[6][line],4);
+ bits |= SHIFT_L(glyphp[7][line],10);
+ bits |= SHIFT_L(glyphp[8][line],16);
+ bits |= SHIFT_L(glyphp[9][line],22);
+ bits |= SHIFT_L(glyphp[10][line],28);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[10][line],4);
+ bits |= SHIFT_L(glyphp[11][line],2);
+ bits |= SHIFT_L(glyphp[12][line],8);
+ bits |= SHIFT_L(glyphp[13][line],14);
+ bits |= SHIFT_L(glyphp[14][line],20);
+ bits |= SHIFT_L(glyphp[15][line],26);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+#ifndef FIXEDBASE
+ base += 3;
+#endif
+ width -= 96;
+ glyphp += 16;
+ }
+ return base;
+}
+#endif
+
+static CARD32*
+DrawTETextScanlineWidth7(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],7);
+ bits |= SHIFT_L(glyphp[2][line],14);
+ bits |= SHIFT_L(glyphp[3][line],21);
+ bits |= SHIFT_L(glyphp[4][line],28);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[4][line],4);
+ bits |= SHIFT_L(glyphp[5][line],3);
+ bits |= SHIFT_L(glyphp[6][line],10);
+ bits |= SHIFT_L(glyphp[7][line],17);
+ bits |= SHIFT_L(glyphp[8][line],24);
+ bits |= SHIFT_L(glyphp[9][line],31);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[9][line],1);
+ bits |= SHIFT_L(glyphp[10][line],6);
+ bits |= SHIFT_L(glyphp[11][line],13);
+ bits |= SHIFT_L(glyphp[12][line],20);
+ bits |= SHIFT_L(glyphp[13][line],27);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = SHIFT_R(glyphp[13][line],5);
+ bits |= SHIFT_L(glyphp[14][line],2);
+ bits |= SHIFT_L(glyphp[15][line],9);
+ bits |= SHIFT_L(glyphp[16][line],16);
+ bits |= SHIFT_L(glyphp[17][line],23);
+ bits |= SHIFT_L(glyphp[18][line],30);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+ bits = SHIFT_R(glyphp[18][line],2);
+ bits |= SHIFT_L(glyphp[19][line],5);
+ bits |= SHIFT_L(glyphp[20][line],12);
+ bits |= SHIFT_L(glyphp[21][line],19);
+ bits |= SHIFT_L(glyphp[22][line],26);
+ WRITE_IN_BITORDER(base, 4, bits);
+ CHECKRETURN(5);
+ bits = SHIFT_R(glyphp[22][line],6);
+ bits |= SHIFT_L(glyphp[23][line],1);
+ bits |= SHIFT_L(glyphp[24][line],8);
+ bits |= SHIFT_L(glyphp[25][line],15);
+ bits |= SHIFT_L(glyphp[26][line],22);
+ bits |= SHIFT_L(glyphp[27][line],29);
+ WRITE_IN_BITORDER(base, 5, bits);
+ CHECKRETURN(6);
+ bits = SHIFT_R(glyphp[27][line],3);
+ bits |= SHIFT_L(glyphp[28][line],4);
+ bits |= SHIFT_L(glyphp[29][line],11);
+ bits |= SHIFT_L(glyphp[30][line],18);
+ bits |= SHIFT_L(glyphp[31][line],25);
+ WRITE_IN_BITORDER(base, 6, bits);
+ CHECKRETURN(7);
+#ifndef FIXEDBASE
+ base += 7;
+#endif
+ width -= 224;
+ glyphp += 32;
+ }
+ return base;
+}
+
+
+#ifndef USEASSEMBLER
+static CARD32*
+DrawTETextScanlineWidth8(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],8);
+ bits |= SHIFT_L(glyphp[2][line],16);
+ bits |= SHIFT_L(glyphp[3][line],24);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = glyphp[4][line];
+ bits |= SHIFT_L(glyphp[5][line],8);
+ bits |= SHIFT_L(glyphp[6][line],16);
+ bits |= SHIFT_L(glyphp[7][line],24);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+#ifndef FIXEDBASE
+ base += 2;
+#endif
+ width -= 64;
+ glyphp += 8;
+ }
+ return base;
+}
+#endif
+
+#ifndef USEASSEMBLER
+static CARD32*
+DrawTETextScanlineWidth9(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],9);
+ bits |= SHIFT_L(glyphp[2][line],18);
+ bits |= SHIFT_L(glyphp[3][line],27);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[3][line],5);
+ bits |= SHIFT_L(glyphp[4][line],4);
+ bits |= SHIFT_L(glyphp[5][line],13);
+ bits |= SHIFT_L(glyphp[6][line],22);
+ bits |= SHIFT_L(glyphp[7][line],31);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[7][line],1);
+ bits |= SHIFT_L(glyphp[8][line],8);
+ bits |= SHIFT_L(glyphp[9][line],17);
+ bits |= SHIFT_L(glyphp[10][line],26);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = SHIFT_R(glyphp[10][line],6);
+ bits |= SHIFT_L(glyphp[11][line],3);
+ bits |= SHIFT_L(glyphp[12][line],12);
+ bits |= SHIFT_L(glyphp[13][line],21);
+ bits |= SHIFT_L(glyphp[14][line],30);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+ bits = SHIFT_R(glyphp[14][line],2);
+ bits |= SHIFT_L(glyphp[15][line],7);
+ bits |= SHIFT_L(glyphp[16][line],16);
+ bits |= SHIFT_L(glyphp[17][line],25);
+ WRITE_IN_BITORDER(base, 4, bits);
+ CHECKRETURN(5);
+ bits = SHIFT_R(glyphp[17][line],7);
+ bits |= SHIFT_L(glyphp[18][line],2);
+ bits |= SHIFT_L(glyphp[19][line],11);
+ bits |= SHIFT_L(glyphp[20][line],20);
+ bits |= SHIFT_L(glyphp[21][line],29);
+ WRITE_IN_BITORDER(base, 5, bits);
+ CHECKRETURN(6);
+ bits = SHIFT_R(glyphp[21][line],3);
+ bits |= SHIFT_L(glyphp[22][line],6);
+ bits |= SHIFT_L(glyphp[23][line],15);
+ bits |= SHIFT_L(glyphp[24][line],24);
+ WRITE_IN_BITORDER(base, 6, bits);
+ CHECKRETURN(7);
+ bits = SHIFT_R(glyphp[24][line],8);
+ bits |= SHIFT_L(glyphp[25][line],1);
+ bits |= SHIFT_L(glyphp[26][line],10);
+ bits |= SHIFT_L(glyphp[27][line],19);
+ bits |= SHIFT_L(glyphp[28][line],28);
+ WRITE_IN_BITORDER(base, 7, bits);
+ CHECKRETURN(8);
+ bits = SHIFT_R(glyphp[28][line],4);
+ bits |= SHIFT_L(glyphp[29][line],5);
+ bits |= SHIFT_L(glyphp[30][line],14);
+ bits |= SHIFT_L(glyphp[31][line],23);
+ WRITE_IN_BITORDER(base, 8, bits);
+ CHECKRETURN(9);
+#ifndef FIXEDBASE
+ base += 9;
+#endif
+ width -= 288;
+ glyphp += 32;
+ }
+ return base;
+}
+#endif
+
+static CARD32*
+DrawTETextScanlineWidth10(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],10);
+ bits |= SHIFT_L(glyphp[2][line],20);
+ bits |= SHIFT_L(glyphp[3][line],30);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[3][line],2);
+ bits |= SHIFT_L(glyphp[4][line],8);
+ bits |= SHIFT_L(glyphp[5][line],18);
+ bits |= SHIFT_L(glyphp[6][line],28);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[6][line],4);
+ bits |= SHIFT_L(glyphp[7][line],6);
+ bits |= SHIFT_L(glyphp[8][line],16);
+ bits |= SHIFT_L(glyphp[9][line],26);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = SHIFT_R(glyphp[9][line],6);
+ bits |= SHIFT_L(glyphp[10][line],4);
+ bits |= SHIFT_L(glyphp[11][line],14);
+ bits |= SHIFT_L(glyphp[12][line],24);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+ bits = SHIFT_R(glyphp[12][line],8);
+ bits |= SHIFT_L(glyphp[13][line],2);
+ bits |= SHIFT_L(glyphp[14][line],12);
+ bits |= SHIFT_L(glyphp[15][line],22);
+ WRITE_IN_BITORDER(base, 4, bits);
+ CHECKRETURN(5);
+#ifndef FIXEDBASE
+ base += 5;
+#endif
+ width -= 160;
+ glyphp += 16;
+ }
+ return base;
+}
+
+static CARD32*
+DrawTETextScanlineWidth12(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],12);
+ bits |= SHIFT_L(glyphp[2][line],24);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[2][line],8);
+ bits |= SHIFT_L(glyphp[3][line],4);
+ bits |= SHIFT_L(glyphp[4][line],16);
+ bits |= SHIFT_L(glyphp[5][line],28);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[5][line],4);
+ bits |= SHIFT_L(glyphp[6][line],8);
+ bits |= SHIFT_L(glyphp[7][line],20);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+#ifndef FIXEDBASE
+ base += 3;
+#endif
+ width -= 96;
+ glyphp += 8;
+ }
+ return base;
+}
+
+
+
+static CARD32*
+DrawTETextScanlineWidth14(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],14);
+ bits |= SHIFT_L(glyphp[2][line],28);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[2][line],4);
+ bits |= SHIFT_L(glyphp[3][line],10);
+ bits |= SHIFT_L(glyphp[4][line],24);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[4][line],8);
+ bits |= SHIFT_L(glyphp[5][line],6);
+ bits |= SHIFT_L(glyphp[6][line],20);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = SHIFT_R(glyphp[6][line],12);
+ bits |= SHIFT_L(glyphp[7][line],2);
+ bits |= SHIFT_L(glyphp[8][line],16);
+ bits |= SHIFT_L(glyphp[9][line],30);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+ bits = SHIFT_R(glyphp[9][line],2);
+ bits |= SHIFT_L(glyphp[10][line],12);
+ bits |= SHIFT_L(glyphp[11][line],26);
+ WRITE_IN_BITORDER(base, 4, bits);
+ CHECKRETURN(5);
+ bits = SHIFT_R(glyphp[11][line],6);
+ bits |= SHIFT_L(glyphp[12][line],8);
+ bits |= SHIFT_L(glyphp[13][line],22);
+ WRITE_IN_BITORDER(base, 5, bits);
+ CHECKRETURN(6);
+ bits = SHIFT_R(glyphp[13][line],10);
+ bits |= SHIFT_L(glyphp[14][line],4);
+ bits |= SHIFT_L(glyphp[15][line],18);
+ WRITE_IN_BITORDER(base, 6, bits);
+ CHECKRETURN(7);
+#ifndef FIXEDBASE
+ base += 7;
+#endif
+ width -= 224;
+ glyphp += 16;
+ }
+ return base;
+}
+
+
+static CARD32*
+DrawTETextScanlineWidth16(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],16);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = glyphp[2][line];
+ bits |= SHIFT_L(glyphp[3][line],16);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = glyphp[4][line];
+ bits |= SHIFT_L(glyphp[5][line],16);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = glyphp[6][line];
+ bits |= SHIFT_L(glyphp[7][line],16);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+#ifndef FIXEDBASE
+ base += 4;
+#endif
+ width -= 128;
+ glyphp += 8;
+ }
+ return base;
+}
+
+
+
+static CARD32*
+DrawTETextScanlineWidth18(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],18);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[1][line],14);
+ bits |= SHIFT_L(glyphp[2][line],4);
+ bits |= SHIFT_L(glyphp[3][line],22);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[3][line],10);
+ bits |= SHIFT_L(glyphp[4][line],8);
+ bits |= SHIFT_L(glyphp[5][line],26);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = SHIFT_R(glyphp[5][line],6);
+ bits |= SHIFT_L(glyphp[6][line],12);
+ bits |= SHIFT_L(glyphp[7][line],30);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+ bits = SHIFT_R(glyphp[7][line],2);
+ bits |= SHIFT_L(glyphp[8][line],16);
+ WRITE_IN_BITORDER(base, 4, bits);
+ CHECKRETURN(5);
+ bits = SHIFT_R(glyphp[8][line],16);
+ bits |= SHIFT_L(glyphp[9][line],2);
+ bits |= SHIFT_L(glyphp[10][line],20);
+ WRITE_IN_BITORDER(base, 5, bits);
+ CHECKRETURN(6);
+ bits = SHIFT_R(glyphp[10][line],12);
+ bits |= SHIFT_L(glyphp[11][line],6);
+ bits |= SHIFT_L(glyphp[12][line],24);
+ WRITE_IN_BITORDER(base, 6, bits);
+ CHECKRETURN(7);
+ bits = SHIFT_R(glyphp[12][line],8);
+ bits |= SHIFT_L(glyphp[13][line],10);
+ bits |= SHIFT_L(glyphp[14][line],28);
+ WRITE_IN_BITORDER(base, 7, bits);
+ CHECKRETURN(8);
+ bits = SHIFT_R(glyphp[14][line],4);
+ bits |= SHIFT_L(glyphp[15][line],14);
+ WRITE_IN_BITORDER(base, 8, bits);
+ CHECKRETURN(9);
+#ifndef FIXEDBASE
+ base += 9;
+#endif
+ width -= 288;
+ glyphp += 16;
+ }
+ return base;
+}
+
+
+static CARD32*
+DrawTETextScanlineWidth24(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],24);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[1][line],8);
+ bits |= SHIFT_L(glyphp[2][line],16);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[2][line],16);
+ bits |= SHIFT_L(glyphp[3][line],8);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+#ifndef FIXEDBASE
+ base += 3;
+#endif
+ width -= 96;
+ glyphp += 4;
+ }
+ return base;
+}
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaTEGlyphBlt.S b/xc/programs/Xserver/hw/xfree86/xaa/xaaTEGlyphBlt.S
new file mode 100644
index 000000000..c674d053b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaTEGlyphBlt.S
@@ -0,0 +1,960 @@
+/*
+ * Copyright 1996 The XFree86 Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HARM HANEMAAYER 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.
+ *
+ * Written by Harm Hanemaayer (H.Hanemaayer@inter.nl.net).
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaTEGlyphBlt.S,v 1.1 1999/07/10 07:24:54 dawes Exp $ */
+
+
+/*
+ * Intel Pentium-optimized versions of "terminal emulator font" text
+ * bitmap transfer routines.
+ *
+ * SCANLINE_PAD_DWORD.
+ *
+ * Only for glyphs with a fixed width of 6 pixels or 8 pixels.
+ */
+
+#include "assyntax.h"
+
+ FILE("xaaTEGlyphBlt.s")
+
+ AS_BEGIN
+
+/*
+ * Definition of stack frame function arguments.
+ * All functions have the same arguments (some don't have glyphwidth,
+ * but that's OK, since it comes last and doesn't affect the offset
+ * of the other arguments).
+ */
+
+#define base_arg REGOFF(20,ESP)
+#define glyphp_arg REGOFF(24,ESP)
+#define line_arg REGOFF(28,ESP)
+#define width_arg REGOFF(32,ESP)
+#define glyphwidth_arg REGOFF(36,ESP)
+
+#define BYTE_REVERSED GLNAME(byte_reversed)
+
+/* I assume %eax and %edx can be trashed. */
+
+ SEG_TEXT
+
+ ALIGNTEXT4
+
+#ifdef FIXEDBASE
+# ifdef MSBFIRST
+ GLOBL GLNAME(DrawTETextScanlineWidth6PMSBFirstFixedBase)
+GLNAME(DrawTETextScanlineWidth6PMSBFirstFixedBase):
+# else
+ GLOBL GLNAME(DrawTETextScanlineWidth6PLSBFirstFixedBase)
+GLNAME(DrawTETextScanlineWidth6PLSBFirstFixedBase):
+# endif
+#else
+# ifdef MSBFIRST
+ GLOBL GLNAME(DrawTETextScanlineWidth6PMSBFirst)
+GLNAME(DrawTETextScanlineWidth6PMSBFirst):
+# else
+ GLOBL GLNAME(DrawTETextScanlineWidth6PLSBFirst)
+GLNAME(DrawTETextScanlineWidth6PLSBFirst):
+# endif
+#endif
+
+/* Definition of stack frame function arguments. */
+
+#define base_arg REGOFF(20,ESP)
+#define glyphp_arg REGOFF(24,ESP)
+#define line_arg REGOFF(28,ESP)
+#define width_arg REGOFF(32,ESP)
+
+ SUB_L (CONST(16),ESP)
+ MOV_L (EBP,REGOFF(12,ESP)) /* PUSH EBP */
+ MOV_L (EBX,REGOFF(8,ESP)) /* PUSH EBX */
+ MOV_L (ESI,REGOFF(4,ESP)) /* PUSH ESI */
+ MOV_L (EDI,REGOFF(0,ESP)) /* PUSH EDI */
+
+ MOV_L (line_arg,EBP)
+ MOV_L (base_arg,EDI)
+ MOV_L (glyphp_arg,ESI)
+
+ ALIGNTEXT4
+
+.L6_1:
+ /* Pentium-optimized instruction pairing. */
+ /* EBX = bits = glyph[0][line] */
+ MOV_L (REGOFF(4,ESI),EDX) /* glyphp[1] */
+ MOV_L (REGIND(ESI),EBX) /* glyphp[0] */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[1][line] */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[0][line] */
+ SAL_L (CONST(6),EDX) /* glyphp[1][line] << 6 */
+ MOV_L (REGOFF(8,ESI),ECX) /* glyphp[2] */
+ MOV_L (REGOFF(12,ESI),EAX) /* glyphp[3] */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[2][line] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[3][line] */
+ SAL_L (CONST(12),ECX) /* glyphp[2][line] << 12 */
+ OR_L (EDX,EBX) /* bits |= ..[1].. << 6 */
+ SAL_L (CONST(18),EAX) /* glyphp[3][line] << 18 */
+ OR_L (ECX,EBX) /* bits |= ..[2].. << 12 */
+
+ MOV_L (REGOFF(16,ESI),EDX) /* glyphp[4] */
+ MOV_L (REGOFF(20,ESI),ECX) /* glyphp[5] */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[4][line] */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[5][line] */
+ SAL_L (CONST(24),EDX) /* glyphp[4][line] << 24 */
+ OR_L (EAX,EBX) /* bits |= ..[3].. << 18 */
+ SAL_L (CONST(30),ECX) /* glyphp[5][line] << 30 */
+ OR_L (EDX,EBX) /* bits |= ..[4].. << 24 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(20,ESI),EAX) /* glyphp[5] */
+ OR_L (ECX,EBX) /* bits |= ..[5].. << 30 */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[5][line] */
+ MOV_L (EBX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (CONST(0),EAX)
+ OR_L (ECX,EBX) /* bits |= ..[5].. << 30 */
+ MOV_L (CONST(0),EDX)
+ MOV_B (BL,AL)
+ MOV_B (BH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),BH)
+ ROL_L (CONST(16),EBX)
+ MOV_B (BL,AL)
+ MOV_B (BH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),BH)
+ ROL_L (CONST(16),EBX)
+ MOV_L (REGOFF(20,ESI),EAX) /* glyphp[5] */
+ MOV_L (EBX,REGIND(EDI))
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[5][line] */
+#endif
+
+ CMP_L (CONST(32),width_arg)
+ JG (.L6_2)
+#ifndef FIXEDBASE
+ ADD_L (CONST(4),EDI) /* base++ */
+#endif
+ JMP (.L6_4)
+.L6_2:
+ /* Note that glyphp[5][line] is already read again. */
+ /* EAX = bits = glyphp[5][line] >> 2 */
+ MOV_L (REGOFF(24,ESI),EDX) /* glyphp[6] */
+ MOV_L (REGOFF(28,ESI),EBX) /* glyphp[7] */
+ SHR_L (CONST(2),EAX) /* glyphp[5][line] >> 2 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[6][line] */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[7][line] */
+ MOV_L (REGOFF(32,ESI),ECX) /* glyphp[8] */
+ SAL_L (CONST(4),EDX) /* glyphp[6][line] << 4 */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[8][line] */
+ SAL_L (CONST(10),EBX) /* glyphp[7][line] << 10 */
+ OR_L (EDX,EAX) /* bits |= ..[6].. << 4 */
+ SAL_L (CONST(16),ECX) /* glyphp[8][line] << 16 */
+ MOV_L (REGOFF(36,ESI),EDX) /* glyphp[9] */
+ OR_L (EBX,EAX) /* bits |= ..[7].. << 10 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[9][line] */
+ OR_L (ECX,EAX) /* bits |= ..[8].. << 16 */
+ MOV_L (REGOFF(40,ESI),EBX) /* glyphp[10] */
+ SAL_L (CONST(22),EDX) /* glyphp[9][line] << 22 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[10][line] */
+ OR_L (EDX,EAX) /* bits |= ..[9].. << 22 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(40,ESI),ECX) /* glyphp[10] */
+ SAL_L (CONST(28),EBX) /* glyphp[10][line] << 28 */
+ MOV_L (REGOFF(44,ESI),EDX) /* glyphp[11] */
+ OR_L (EBX,EAX) /* bits |= ..[10].. << 28 */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[10][line] */
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(4,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[11][line] */
+#else
+ MOV_L (CONST(0),ECX)
+ SAL_L (CONST(28),EBX) /* glyphp[10][line] << 28 */
+ MOV_L (CONST(0),EDX)
+ OR_L (EBX,EAX) /* bits |= ..[10].. << 28 */
+ MOV_B (AL,CL)
+ MOV_B (AH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),AH)
+ ROL_L (CONST(16),EAX)
+ MOV_B (AL,CL)
+ MOV_B (AH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),AH)
+ MOV_L (REGOFF(40,ESI),ECX) /* glyphp[10] */
+ ROL_L (CONST(16),EAX)
+ MOV_L (REGOFF(44,ESI),EDX) /* glyphp[11] */
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(4,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[10][line] */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[11][line] */
+#endif
+
+ CMP_L (CONST(64),width_arg)
+ JG (.L6_3)
+#ifndef FIXEDBASE
+ ADD_L (CONST(8),EDI) /* base+=2 */
+#endif
+ JMP (.L6_4)
+.L6_3:
+ /* Note that glyphp[10][line] is read again. */
+ /* EAX = bits = glyphp[10][line] >> 4 */
+ SHR_L (CONST(4),ECX) /* glyphp[10][line] >> 4 */
+ MOV_L (REGOFF(48,ESI),EBX) /* glyphp[12] */
+ SAL_L (CONST(2),EDX) /* glyphp[11][line] << 2 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[12][line] */
+ OR_L (EDX,ECX) /* bits |= ..[11].. << 2 */
+ MOV_L (REGOFF(52,ESI),EAX) /* glyphp[13] */
+ SAL_L (CONST(8),EBX) /* glyphp[12][line] << 8 */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[13][line] */
+ OR_L (EBX,ECX) /* bits |= ..[12].. << 8 */
+ MOV_L (REGOFF(56,ESI),EDX) /* glyphp[14] */
+ SAL_L (CONST(14),EAX) /* glyphp[13][line] << 14 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[14][line] */
+ OR_L (EAX,ECX) /* bits |= ..[13].. << 14 */
+ MOV_L (REGOFF(60,ESI),EBX) /* glyphp[15] */
+ SAL_L (CONST(20),EDX) /* glyphp[14][line] << 20 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[15][line] */
+ OR_L (EDX,ECX) /* bits |= ..[14].. << 20 */
+
+#ifndef MSBFIRST
+ SAL_L (CONST(26),EBX) /* glyphp[15][line] << 26 */
+ OR_L (EBX,ECX) /* bits |= ..[15].. << 26 */
+#ifndef FIXEDBASE
+ MOV_L (ECX,REGOFF(8,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (ECX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),EAX)
+ SAL_L (CONST(26),EBX) /* glyphp[15][line] << 26 */
+ MOV_L (CONST(0),EDX)
+ OR_L (EBX,ECX) /* bits |= ..[15].. << 26 */
+ MOV_B (CL,AL)
+ MOV_B (CH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),CH)
+ ROL_L (CONST(16),ECX)
+ MOV_B (CL,AL)
+ MOV_B (CH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),CH)
+ ROL_L (CONST(16),ECX)
+#ifndef FIXEDBASE
+ MOV_L (ECX,REGOFF(8,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (ECX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#endif
+
+#ifndef FIXEDBASE
+ ADD_L (CONST(12),EDI) /* base += 3*/
+#endif
+ CMP_L (CONST(96),width_arg)
+ JLE (.L6_4)
+ ADD_L (CONST(64),ESI) /* glyphp += 16 */
+ SUB_L (CONST(96),width_arg)
+ JMP (.L6_1)
+
+.L6_4:
+
+#ifndef FIXEDBASE
+ MOV_L (EDI,EAX) /* return base */
+#else
+ MOV_L (base_arg,EAX) /* return base */
+#endif
+ MOV_L (REGOFF(0,ESP),EDI) /* POPL EDI */
+ MOV_L (REGOFF(4,ESP),ESI) /* POPL ESI */
+ MOV_L (REGOFF(8,ESP),EBX) /* POPL EBX */
+ MOV_L (REGOFF(12,ESP),EBP) /* POPL EBP */
+ ADD_L (CONST(16),ESP)
+ RET
+
+
+ ALIGNTEXT4
+
+#ifdef FIXEDBASE
+# ifdef MSBFIRST
+ GLOBL GLNAME(DrawTETextScanlineWidth8PMSBFirstFixedBase)
+GLNAME(DrawTETextScanlineWidth8PMSBFirstFixedBase):
+# else
+ GLOBL GLNAME(DrawTETextScanlineWidth8PLSBFirstFixedBase)
+GLNAME(DrawTETextScanlineWidth8PLSBFirstFixedBase):
+# endif
+#else
+# ifdef MSBFIRST
+ GLOBL GLNAME(DrawTETextScanlineWidth8PMSBFirst)
+GLNAME(DrawTETextScanlineWidth8PMSBFirst):
+# else
+ GLOBL GLNAME(DrawTETextScanlineWidth8PLSBFirst)
+GLNAME(DrawTETextScanlineWidth8PLSBFirst):
+# endif
+#endif
+
+ SUB_L (CONST(16),ESP)
+ MOV_L (EBP,REGOFF(12,ESP)) /* PUSH EBP */
+ MOV_L (EBX,REGOFF(8,ESP)) /* PUSH EBX */
+ MOV_L (ESI,REGOFF(4,ESP)) /* PUSH ESI */
+ MOV_L (EDI,REGOFF(0,ESP)) /* PUSH EDI */
+
+ MOV_L (line_arg,EBP)
+ MOV_L (base_arg,EDI)
+ MOV_L (glyphp_arg,ESI)
+
+ ALIGNTEXT4
+
+.L8_1:
+ /* Pentium-optimized instruction pairing. */
+ /* EBX = bits */
+ MOV_L (REGIND(ESI),EAX) /* glyphp[0] */
+ MOV_L (REGOFF(4,ESI),EDX) /* glyphp[1] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[0][line] */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[1][line] */
+#ifdef MSBFIRST
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),BH)
+#else
+ MOV_L (EAX,EBX) /* bits = glyph[0][line] */
+ MOV_B (DL,BH) /* bits |= ..[1].. << 8 */
+#endif
+
+ ROL_L (CONST(16),EBX)
+ MOV_L (REGOFF(8,ESI),EAX) /* glyphp[2] */
+ MOV_L (REGOFF(12,ESI),ECX) /* glyphp[3] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[2][line] */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[3][line] */
+#ifdef MSBFIRST
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),BL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),BH)
+#else
+ MOV_B (AL,BL) /* bits |= ..[2].. << 16 */
+ MOV_B (CL,BH) /* bits |= ..[3].. << 24 */
+#endif
+ ROL_L (CONST(16),EBX)
+ MOV_L (EBX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+ CMP_L (CONST(32),width_arg)
+#ifndef FIXEDBASE
+ JLE (.L8_2)
+#else
+ JLE (.L8_3)
+#endif
+
+ MOV_L (REGOFF(16,ESI),EAX) /* glyphp[4] */
+ MOV_L (REGOFF(20,ESI),EDX) /* glyphp[5] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[4][line] */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[5][line] */
+#ifdef MSBFIRST
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),BH)
+#else
+ MOV_L (EAX,EBX) /* bits = glyph[4][line] */
+ MOV_B (DL,BH) /* nits |= ..[5].. << 8 */
+#endif
+
+ ROL_L (CONST(16),EBX)
+ MOV_L (REGOFF(24,ESI),EAX) /* glyphp[6] */
+ MOV_L (REGOFF(28,ESI),ECX) /* glyphp[7] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[6][line] */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[7][line] */
+#ifdef MSBFIRST
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),BL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),BH)
+#else
+ MOV_B (AL,BL) /* bits |= ..[6].. << 16 */
+ MOV_B (CL,BH) /* bits |= ..[7].. << 24 */
+#endif
+ ROL_L (CONST(16),EBX)
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(4,EDI)) /* WRITE_IN_BIT_ORDER(base+1, bits) */
+ ADD_L (CONST(8),EDI) /* base += 2 */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+ CMP_L (CONST(64),width_arg)
+ JLE (.L8_3)
+ ADD_L (CONST(32),ESI) /* glyphp += 8 */
+ SUB_L (CONST(64),width_arg)
+ JMP (.L8_1)
+
+#ifndef FIXEDBASE
+.L8_2:
+ ADD_L (CONST(4),EDI) /* base++ */
+.L8_3:
+ MOV_L (EDI,EAX) /* return base */
+#else
+.L8_3:
+ MOV_L (base_arg,EAX) /* return base */
+#endif
+ MOV_L (REGOFF(0,ESP),EDI) /* POPL EDI */
+ MOV_L (REGOFF(4,ESP),ESI) /* POPL ESI */
+ MOV_L (REGOFF(8,ESP),EBX) /* POPL EBX */
+ MOV_L (REGOFF(12,ESP),EBP) /* POPL EBP */
+ ADD_L (CONST(16),ESP)
+ RET
+
+ ALIGNTEXT4
+
+#ifdef FIXEDBASE
+# ifdef MSBFIRST
+ GLOBL GLNAME(DrawTETextScanlineWidth9PMSBFirstFixedBase)
+GLNAME(DrawTETextScanlineWidth9PMSBFirstFixedBase):
+# else
+ GLOBL GLNAME(DrawTETextScanlineWidth9PLSBFirstFixedBase)
+GLNAME(DrawTETextScanlineWidth9PLSBFirstFixedBase):
+# endif
+#else
+# ifdef MSBFIRST
+ GLOBL GLNAME(DrawTETextScanlineWidth9PMSBFirst)
+GLNAME(DrawTETextScanlineWidth9PMSBFirst):
+# else
+ GLOBL GLNAME(DrawTETextScanlineWidth9PLSBFirst)
+GLNAME(DrawTETextScanlineWidth9PLSBFirst):
+# endif
+#endif
+
+ SUB_L (CONST(16),ESP)
+ MOV_L (EBP,REGOFF(12,ESP)) /* PUSH EBP */
+ MOV_L (EBX,REGOFF(8,ESP)) /* PUSH EBX */
+ MOV_L (ESI,REGOFF(4,ESP)) /* PUSH ESI */
+ MOV_L (EDI,REGOFF(0,ESP)) /* PUSH EDI */
+
+ MOV_L (line_arg,EBP)
+ MOV_L (base_arg,EDI)
+ MOV_L (glyphp_arg,ESI)
+
+ ALIGNTEXT4
+
+.L9_1:
+ /* Pentium-optimized instruction pairing. */
+ /* EAX = bits */
+ MOV_L (REGOFF(4,ESI),EBX) /* glyphp[1] */
+ MOV_L (REGIND(ESI),EAX) /* glyphp[0] */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[1][line] */
+ MOV_L (REGOFF(8,ESI),ECX) /* glyphp[2] */
+ SAL_L (CONST(9),EBX) /* glyphp[1][line] << 9 */
+ MOV_L (REGOFF(12,ESI),EDX) /* glyphp[3] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[0][line] */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[3][line] */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[2][line] */
+ OR_L (EBX,EAX) /* bits |= ..[1].. << 9 */
+ SAL_L (CONST(18),ECX) /* glyphp[2][line] << 18 */
+ OR_L (ECX,EAX) /* bits |= ..[2].. << 18 */
+ SAL_L (CONST(27),EDX) /* glyphp[3][line << 27 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(12,ESI),EBX) /* glyphp[3] */
+ OR_L (EDX,EAX) /* bits |= ..[3].. << 27 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[3][line] */
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (CONST(0),EBX)
+ OR_L (EDX,EAX) /* bits |= ..[3].. << 27 */
+ MOV_L (CONST(0),ECX)
+ MOV_B (AL,BL)
+ MOV_B (AH,CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),AH)
+ ROL_L (CONST(16),EAX)
+ MOV_B (AL,BL)
+ MOV_B (AH,CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),AH)
+ MOV_L (REGOFF(12,ESI),EBX) /* glyphp[3] */
+ ROL_L (CONST(16),EAX)
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[3][line] */
+ MOV_L (EAX,REGIND(EDI))
+#endif
+
+ CMP_L (CONST(32),width_arg)
+ JG (.L9_2)
+#ifndef FIXEDBASE
+ ADD_L (CONST(4),EDI) /* base++ */
+#endif
+ JMP (.L9_11)
+.L9_2:
+ /* Note that glyphp[3][line] is read again. */
+ /* EAX = bits, EBX = glyphp[3][line] >> 5 */
+ SHR_L (CONST(5),EBX) /* glyphp[3][line] >> 5 */
+ MOV_L (REGOFF(16,ESI),EAX) /* glyphp[4] */
+ MOV_L (REGOFF(20,ESI),ECX) /* glyphp[5] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[4][line] */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[5][line] */
+ MOV_L (REGOFF(24,ESI),EDX) /* glyphp[6] */
+ SAL_L (CONST(4),EAX) /* glyphp[4][line] << 4 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[6][line] */
+ SAL_L (CONST(13),ECX) /* glyphp[5][line] << 13 */
+ OR_L (EBX,EAX) /* bits |= ..[4].. << 4 */
+ SAL_L (CONST(22),EDX) /* glyphp[6][line] << 22 */
+ MOV_L (REGOFF(28,ESI),EBX) /* glyphp[7] */
+ OR_L (ECX,EAX) /* bits |= ..[5].. << 13 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[7][line] */
+ OR_L (EDX,EAX) /* bits |= ..[6].. << 22 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(28,ESI),ECX) /* glyphp[7] */
+ SAL_L (CONST(31),EBX) /* glyphp[7][line] << 31 */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[7][line] */
+ OR_L (EBX,EAX) /* bits |= ..[7].. << 31 */
+ MOV_L (REGOFF(32,ESI),EDX) /* glyphp[8] */
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(4,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),ECX)
+ SAL_L (CONST(31),EBX) /* glyphp[7][line] << 31 */
+ MOV_L (CONST(0),EDX)
+ OR_L (EBX,EAX) /* bits |= ..[7].. << 31 */
+ MOV_B (AL,CL)
+ MOV_B (AH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),AH)
+ ROL_L (CONST(16),EAX)
+ MOV_B (AL,CL)
+ MOV_B (AH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),AH)
+ MOV_L (REGOFF(28,ESI),ECX) /* glyphp[7] */
+ ROL_L (CONST(16),EAX)
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[7][line] */
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(4,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+ MOV_L (REGOFF(32,ESI),EDX) /* glyphp[8] */
+#endif
+
+ CMP_L (CONST(64),width_arg)
+ JG (.L9_3)
+#ifndef FIXEDBASE
+ ADD_L (CONST(8),EDI) /* base+=2 */
+#endif
+ JMP (.L9_11)
+.L9_3:
+
+ /* Note that glyphp[7][line] is read again. */
+ /* ECX = bits = glyphp[7][line] >> 1 */
+ SHR_L (CONST(1),ECX) /* glyphp[7][line] >> 1 */
+ MOV_L (REGOFF(36,ESI),EBX) /* glyphp[9] */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[8][line] */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[9][line] */
+ SAL_L (CONST(8),EDX) /* glyphp[8][line] << 8 */
+ MOV_L (REGOFF(40,ESI),EAX) /* glyphp[10] */
+ SAL_L (CONST(17),EBX) /* glyphp[9][line] << 17 */
+ OR_L (EDX,ECX) /* bits |= ..[8].. << 8 */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[10][line] */
+ OR_L (EBX,ECX) /* bits |= ..[9].. << 17 */
+ SAL_L (CONST(26),EAX) /* glyphp[10][line] << 26 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(40,ESI),EDX) /* glyphp[10] */
+ OR_L (EAX,ECX) /* bits |= ..[10].. << 26 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[10][line] */
+#ifndef FIXEDBASE
+ MOV_L (ECX,REGOFF(8,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (ECX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),EDX)
+ OR_L (EAX,ECX) /* bits |= ..[10].. << 26 */
+ MOV_L (CONST(0),EBX)
+ MOV_B (CL,DL)
+ MOV_B (CH,BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),CH)
+ ROL_L (CONST(16),ECX)
+ MOV_B (CL,DL)
+ MOV_B (CH,BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),CH)
+ MOV_L (REGOFF(40,ESI),EDX) /* glyphp[10] */
+ ROL_L (CONST(16),ECX)
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[10][line] */
+#ifndef FIXEDBASE
+ MOV_L (ECX,REGOFF(8,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (ECX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#endif
+
+ CMP_L (CONST(96),width_arg)
+ JG (.L9_4)
+#ifndef FIXEDBASE
+ ADD_L (CONST(12),EDI) /* base+=3 */
+#endif
+ JMP (.L9_11)
+.L9_4:
+ /* Note that glyphp[10][line] is read again. */
+ /* EDX = bits = glyphp[10][line] >> 6 */
+ SHR_L (CONST(6),EDX) /* glyphp[10][line] >> 6 */
+ MOV_L (REGOFF(44,ESI),EBX) /* glyphp[11] */
+ MOV_L (REGOFF(48,ESI),EAX) /* glyphp[12] */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[11][line] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[12][line] */
+ MOV_L (REGOFF(52,ESI),ECX) /* glyphp[13] */
+ SAL_L (CONST(3),EBX) /* glyphp[11][line] << 3 */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[13][line] */
+ SAL_L (CONST(12),EAX) /* glyphp[12][line] << 12 */
+ OR_L (EBX,EDX) /* bits |= ..[11].. << 3 */
+ SAL_L (CONST(21),ECX) /* glyphp[13][line] << 21 */
+ MOV_L (REGOFF(56,ESI),EBX) /* glyphp[14] */
+ OR_L (EAX,EDX) /* bits |= ..[12].. << 17 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[14][line] */
+ SAL_L (CONST(30),EBX) /* glyphp[14][line] << 30 */
+ OR_L (ECX,EDX) /* bits |= ..[13].. << 21 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(56,ESI),EAX) /* glyphp[14] */
+ OR_L (EBX,EDX) /* bits |= ..[14].. << 30 */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[14][line] */
+#ifndef FIXEDBASE
+ MOV_L (EDX,REGOFF(12,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EDX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),EAX)
+ OR_L (EBX,EDX) /* bits |= ..[14].. << 30 */
+ MOV_L (CONST(0),ECX)
+ MOV_B (DL,AL)
+ MOV_B (DH,CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),DL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),DH)
+ ROL_L (CONST(16),EDX)
+ MOV_B (DL,AL)
+ MOV_B (DH,CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),DL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),DH)
+ MOV_L (REGOFF(56,ESI),EAX) /* glyphp[14] */
+ ROL_L (CONST(16),EDX)
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[14][line] */
+#ifndef FIXEDBASE
+ MOV_L (EDX,REGOFF(12,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EDX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#endif
+
+ CMP_L (CONST(128),width_arg)
+ JG (.L9_5)
+#ifndef FIXEDBASE
+ ADD_L (CONST(16),EDI) /* base+=4 */
+#endif
+ JMP (.L9_11)
+.L9_5:
+ /* Note that glyphp[14][line] is read again. */
+ /* EAX = bits = glyphp[14][line] >> 2 */
+ SHR_L (CONST(2),EAX) /* glyphp[14][line] >> 2 */
+ MOV_L (REGOFF(60,ESI),ECX) /* glyphp[15] */
+ MOV_L (REGOFF(64,ESI),EBX) /* glyphp[16] */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[15][line] */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[16][line] */
+ MOV_L (REGOFF(68,ESI),EDX) /* glyphp[17] */
+ SAL_L (CONST(7),ECX) /* glyphp[15][line] << 7 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[17][line] */
+ SAL_L (CONST(16),EBX) /* glyphp[16][line] << 16 */
+ OR_L (ECX,EAX) /* bits |= ..[15].. << 7 */
+ SAL_L (CONST(25),EDX) /* glyphp[17][line] << 25 */
+ OR_L (EBX,EAX) /* bits |= ..[16].. << 16 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(68,ESI),ECX) /* glyphp[17] */
+ OR_L (EDX,EAX) /* bits |= ..[17].. << 25 */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[17][line] */
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(16,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),ECX)
+ OR_L (EDX,EAX) /* bits |= ..[17].. << 25 */
+ MOV_L (CONST(0),EBX)
+ MOV_B (AL,CL)
+ MOV_B (AH,BL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),AH)
+ ROL_L (CONST(16),EAX)
+ MOV_B (AL,CL)
+ MOV_B (AH,BL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),AH)
+ MOV_L (REGOFF(68,ESI),ECX) /* glyphp[17] */
+ ROL_L (CONST(16),EAX)
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[17][line] */
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(16,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#endif
+
+ CMP_L (CONST(160),width_arg)
+ JG (.L9_6)
+#ifndef FIXEDBASE
+ ADD_L (CONST(20),EDI) /* base+=5 */
+#endif
+ JMP (.L9_11)
+.L9_6:
+ /* Note that glyphp[17][line] is read again. */
+ /* ECX = bits = glyphp[17][line] >> 7 */
+ SHR_L (CONST(7),ECX) /* glyphp[17][line] >> 7 */
+ MOV_L (REGOFF(72,ESI),EBX) /* glyphp[18] */
+ MOV_L (REGOFF(76,ESI),EAX) /* glyphp[19] */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[18][line] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[19][line] */
+ MOV_L (REGOFF(80,ESI),EDX) /* glyphp[20] */
+ SAL_L (CONST(2),EBX) /* glyphp[18][line] << 2 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[20][line] */
+ SAL_L (CONST(11),EAX) /* glyphp[19][line] << 11 */
+ OR_L (EBX,ECX) /* bits |= ..[18].. << 2 */
+ SAL_L (CONST(20),EDX) /* glyphp[20][line] << 20 */
+ MOV_L (REGOFF(84,ESI),EBX) /* glyphp[21] */
+ OR_L (EAX,ECX) /* bits |= ..[19].. << 11 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[21][line] */
+ OR_L (EDX,ECX) /* bits |= ..[20].. << 20 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(84,ESI),EAX) /* glyphp[21] */
+ SAL_L (CONST(29),EBX) /* glyphp[21][line] << 29 */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[21][line] */
+ OR_L (EBX,ECX) /* bits |= ..[14].. << 30 */
+ MOV_L (REGOFF(88,ESI),EDX) /* glyphp[22] */
+#ifndef FIXEDBASE
+ MOV_L (ECX,REGOFF(20,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (ECX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),EAX)
+ SAL_L (CONST(29),EBX) /* glyphp[21][line] << 29 */
+ MOV_L (CONST(0),EDX)
+ OR_L (EBX,ECX) /* bits |= ..[14].. << 30 */
+ MOV_B (CL,AL)
+ MOV_B (CH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),CH)
+ ROL_L (CONST(16),ECX)
+ MOV_B (CL,AL)
+ MOV_B (CH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),CH)
+ MOV_L (REGOFF(84,ESI),EAX) /* glyphp[21] */
+ ROL_L (CONST(16),ECX)
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[21][line] */
+#ifndef FIXEDBASE
+ MOV_L (ECX,REGOFF(20,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (ECX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+ MOV_L (REGOFF(88,ESI),EDX) /* glyphp[22] */
+#endif
+
+ CMP_L (CONST(192),width_arg)
+ JG (.L9_7)
+#ifndef FIXEDBASE
+ ADD_L (CONST(24),EDI) /* base+=6 */
+#endif
+ JMP (.L9_11)
+.L9_7:
+ /* Note that glyphp[21][line] is read again. */
+ /* EAX = bits = glyphp[21][line] >> 3 */
+ SHR_L (CONST(3),EAX) /* glyphp[21][line] >> 3 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[22][line] */
+ MOV_L (REGOFF(92,ESI),EBX) /* glyphp[23] */
+ MOV_L (REGOFF(96,ESI),ECX) /* glyphp[24] */
+ SAL_L (CONST(6),EDX) /* glyphp[22][line] << 6 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[23][line] */
+ OR_L (EDX,EAX) /* bits |= ..[22].. << 6 */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[24][line] */
+ SAL_L (CONST(15),EBX) /* glyphp[23][line] << 15 */
+ OR_L (EBX,EAX) /* bits |= ..[23].. << 15 */
+ SAL_L (CONST(24),ECX) /* glyphp[24][line] << 24 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(96,ESI),EDX) /* glyphp[24] */
+ OR_L (ECX,EAX) /* bits |= ..[24].. << 24 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[24][line] */
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(24,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),EDX)
+ OR_L (ECX,EAX) /* bits |= ..[24].. << 24 */
+ MOV_L (CONST(0),EBX)
+ MOV_B (AL,DL)
+ MOV_B (AH,BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),AH)
+ ROL_L (CONST(16),EAX)
+ MOV_B (AL,DL)
+ MOV_B (AH,BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),AH)
+ MOV_L (REGOFF(96,ESI),EDX) /* glyphp[24] */
+ ROL_L (CONST(16),EAX)
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[24][line] */
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(24,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#endif
+
+ CMP_L (CONST(224),width_arg)
+ JG (.L9_8)
+#ifndef FIXEDBASE
+ ADD_L (CONST(28),EDI) /* base+=7 */
+#endif
+ JMP (.L9_11)
+.L9_8:
+ /* Note that glyphp[24][line] is read again. */
+ /* EDX = bits = glyphp[24][line] >> 8 */
+
+ SHR_L (CONST(8),EDX) /* glyphp[24][line] >> 8 */
+ MOV_L (REGOFF(100,ESI),EAX) /* glyphp[25] */
+ MOV_L (REGOFF(104,ESI),EBX) /* glyphp[26] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[25][line] */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[26][line] */
+ MOV_L (REGOFF(108,ESI),ECX) /* glyphp[27] */
+ SAL_L (CONST(1),EAX) /* glyphp[25][line] << 1 */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[27][line] */
+ SAL_L (CONST(10),EBX) /* glyphp[26][line] << 10 */
+ OR_L (EAX,EDX) /* bits |= ..[25].. << 1 */
+ SAL_L (CONST(19),ECX) /* glyphp[27][line] << 19 */
+ OR_L (EBX,EDX) /* bits |= ..[26].. << 10 */
+ MOV_L (REGOFF(112,ESI),EAX) /* glyphp[28] */
+ OR_L (ECX,EDX) /* bits |= ..[27].. << 19 */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[28][line] */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(112,ESI),EBX) /* glyphp[28] */
+ SAL_L (CONST(28),EAX) /* glyphp[28][line] << 28 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[28][line] */
+ OR_L (EAX,EDX) /* bits |= ..[28].. << 28 */
+ MOV_L (REGOFF(116,ESI),ECX) /* glyphp[29] */
+#ifndef FIXEDBASE
+ MOV_L (EDX,REGOFF(28,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EDX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),EBX)
+ SAL_L (CONST(28),EAX) /* glyphp[28][line] << 28 */
+ MOV_L (CONST(0),ECX)
+ OR_L (EAX,EDX) /* bits |= ..[28].. << 28 */
+ MOV_B (DL,BL)
+ MOV_B (DH,CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),DL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),DH)
+ ROL_L (CONST(16),EDX)
+ MOV_B (DL,BL)
+ MOV_B (DH,CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),DL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),DH)
+ MOV_L (REGOFF(112,ESI),EBX) /* glyphp[28] */
+ ROL_L (CONST(16),EDX)
+ MOV_L (REGOFF(116,ESI),ECX) /* glyphp[29] */
+#ifndef FIXEDBASE
+ MOV_L (EDX,REGOFF(28,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EDX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[28][line] */
+#endif
+
+ CMP_L (CONST(256),width_arg)
+ JG (.L9_9)
+#ifndef FIXEDBASE
+ ADD_L (CONST(32),EDI) /* base+=8 */
+#endif
+ JMP (.L9_11)
+.L9_9:
+ /* Note that glyphp[28][line] is read again. */
+ /* EBX = bits = glyphp[28][line] >> 4 */
+ SHR_L (CONST(4),EBX) /* glyphp[28][line] >> 4 */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[29][line] */
+ MOV_L (REGOFF(120,ESI),EAX) /* glyphp[30] */
+ MOV_L (REGOFF(124,ESI),EDX) /* glyphp[31] */
+ SAL_L (CONST(5),ECX) /* glyphp[29][line] << 5 */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[30][line] */
+ OR_L (ECX,EBX) /* bits |= ..[29].. << 5 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[31][line] */
+ SAL_L (CONST(14),EAX) /* glyphp[30][line] << 14 */
+ ADD_L (CONST(128),ESI) /* glyphp+=32 */
+ SAL_L (CONST(23),EDX) /* glyphp[31][line] << 23 */
+ OR_L (EAX,EBX) /* bits |= ..[30].. << 14 */
+ SUB_L (CONST(288),width_arg) /* width-=288 */
+ OR_L (EDX,EBX) /* bits |= ..[31].. << 23 */
+
+#ifndef MSBFIRST
+#ifndef FIXEDBASE
+ MOV_L (EBX,REGOFF(32,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EBX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),ECX)
+ MOV_L (CONST(0),EAX)
+ MOV_B (BL,CL)
+ MOV_B (BH,AL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),BH)
+ ROL_L (CONST(16),EBX)
+ MOV_B (BL,CL)
+ MOV_B (BH,AL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),BH)
+ ROL_L (CONST(16),EBX)
+#ifndef FIXEDBASE
+ MOV_L (EBX,REGOFF(32,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EBX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#endif
+
+ ADD_L (CONST(36),EDI) /* base+=9 */
+ CMP_L (CONST(0),width_arg)
+ JG (.L9_1)
+
+.L9_11:
+#ifndef FIXEDBASE
+ MOV_L (EDI,EAX) /* return base */
+#else
+ MOV_L (base_arg,EAX) /* return base */
+#endif
+ MOV_L (REGOFF(0,ESP),EDI) /* POPL EDI */
+ MOV_L (REGOFF(4,ESP),ESI) /* POPL ESI */
+ MOV_L (REGOFF(8,ESP),EBX) /* POPL EBX */
+ MOV_L (REGOFF(12,ESP),EBP) /* POPL EBP */
+ ADD_L (CONST(16),ESP)
+ RET
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaTEText.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaTEText.c
new file mode 100644
index 000000000..82fa28674
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaTEText.c
@@ -0,0 +1,293 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaTEText.c,v 1.7 1999/05/30 03:03:33 dawes Exp $ */
+
+/********************************************************************
+
+ In this file we have GC level replacements for PolyText8/16,
+ ImageText8/16, ImageGlyphBlt and PolyGlyphBlt for TE (fixed) fonts.
+ The idea is that everything in this file is device independent.
+ The mentioned GCOps are merely wrappers for XAAGlyphBltTEColorExpansion
+ which calculates the boxes containing arbitrarily clipped text
+ and passes them to the TEGlyphRenderer which will usually be a lower
+ level XAA function which renders these clipped glyphs using
+ the basic color expansion functions exported by the chipset driver.
+ The TEGlyphRenderer itself may optionally be driver supplied to
+ facilitate work-arounds/optimizations at a higher level than usual.
+
+ v1.0 - Mark Vojkovich (mvojkovi@ucsd.edu)
+
+
+********************************************************************/
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "font.h"
+#include "scrnintstr.h"
+#include "dixfontstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+
+
+static void XAAGlyphBltTEColorExpansion(ScrnInfoPtr pScrn, int xInit,
+ int yInit, FontPtr font, int fg, int bg, int rop,
+ unsigned int planemask, RegionPtr cclip, int nglyph,
+ unsigned char* gBase, CharInfoPtr *ppci);
+
+
+/********************************************************************
+
+ GC level replacements for PolyText8/16 and ImageText8/16
+ for TE fonts when using color expansion.
+
+********************************************************************/
+
+
+int
+XAAPolyText8TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
+ (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
+
+ /* we have divorced XAAGlyphBltTEColorExpansion from the drawable */
+ if(n) XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+
+ return (x + (n * FONTMAXBOUNDS(pGC->font, characterWidth)));
+}
+
+
+int
+XAAPolyText16TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ (*pGC->font->get_glyphs)(
+ pGC->font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, infoRec->CharInfo);
+
+ if(n) XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+
+ return (x + (n * FONTMAXBOUNDS(pGC->font, characterWidth)));
+}
+
+
+void
+XAAImageText8TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
+ (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
+
+ if(n) XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+}
+
+
+void
+XAAImageText16TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ (*pGC->font->get_glyphs)(
+ pGC->font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, infoRec->CharInfo);
+
+ if(n) XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+}
+
+
+
+/********************************************************************
+
+ GC level replacements for ImageGlyphBlt and PolyGlyphBlt for
+ TE fonts when using color expansion.
+
+********************************************************************/
+
+
+void
+XAAImageGlyphBltTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, xInit + pDrawable->x, yInit + pDrawable->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
+ pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
+}
+
+void
+XAAPolyGlyphBltTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, xInit + pDrawable->x, yInit + pDrawable->y,
+ pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
+}
+
+
+
+
+/********************************************************************
+
+ XAAGlyphBltTEColorExpansion -
+
+ This guy computes the clipped pieces of text and sends it to
+ the lower-level function which will handle acceleration of
+ arbitrarily clipped text.
+
+********************************************************************/
+
+
+static void
+XAAGlyphBltTEColorExpansion(
+ ScrnInfoPtr pScrn,
+ int xInit, int yInit,
+ FontPtr font,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask,
+ RegionPtr cclip,
+ int nglyph,
+ unsigned char* gBase,
+ CharInfoPtr *ppci )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int skippix, skipglyphs;
+ int Left, Right, Top, Bottom;
+ int LeftEdge, RightEdge, ytop, ybot;
+ int nbox = REGION_NUM_RECTS(cclip);
+ BoxPtr pbox = REGION_RECTS(cclip);
+ unsigned int **glyphs = NULL;
+ int glyphWidth = FONTMAXBOUNDS(font, characterWidth);
+
+ /* find the size of the box */
+ Left = xInit;
+ Right = Left + (glyphWidth * nglyph);
+ Top = yInit - FONTASCENT(font);
+ Bottom = yInit + FONTDESCENT(font);
+
+ /* get into the first band that may contain part of our string */
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ /* stop when the lower edge of the box is beyond our string */
+ while(nbox && (Bottom > pbox->y1)) {
+ LeftEdge = max(Left, pbox->x1);
+ RightEdge = min(Right, pbox->x2);
+
+ if(RightEdge > LeftEdge) { /* we have something to draw */
+ ytop = max(Top, pbox->y1);
+ ybot = min(Bottom, pbox->y2);
+
+ if((skippix = LeftEdge - Left)) {
+ skipglyphs = skippix/glyphWidth;
+ skippix %= glyphWidth;
+ } else skipglyphs = 0;
+
+ if(!glyphs) {
+ int count;
+ glyphs = (unsigned int**)(infoRec->PreAllocMem);
+
+ for(count = 0; count < nglyph; count++)
+ glyphs[count] = (unsigned int*)
+ FONTGLYPHBITS(gBase,*ppci++);
+
+ /* our new unrolled TE code only writes DWORDS at a time
+ so it can read up to 6 characters past the last one
+ we're displaying */
+ glyphs[count + 0] = glyphs[0];
+ glyphs[count + 1] = glyphs[0];
+ glyphs[count + 2] = glyphs[0];
+ glyphs[count + 3] = glyphs[0];
+ glyphs[count + 4] = glyphs[0];
+ glyphs[count + 5] = glyphs[0];
+ }
+
+ /* x, y, w, h, skipleft, skiptop, glyphp, glyphWidth, fg, bg, rop, pm */
+
+ (*infoRec->TEGlyphRenderer)( pScrn,
+ LeftEdge, ytop, RightEdge - LeftEdge, ybot - ytop,
+ skippix, ytop - Top, glyphs + skipglyphs, glyphWidth,
+ fg, bg, rop, planemask);
+ }
+
+ nbox--; pbox++;
+ }
+}
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaTables.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaTables.c
new file mode 100644
index 000000000..0d2ce760a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaTables.c
@@ -0,0 +1,88 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaTables.c,v 1.2 1998/07/25 16:58:53 dawes Exp $ */
+
+/*
+ * This is a table of 24-bit values, indexed with an 8-bit byte value, then
+ * expands each bit to three consecutive bits. This is required for color
+ * expansion in 24bpp mode with the coprocessor in 8bpp mode, with LSB-first
+ * bit order within a byte.
+ */
+
+unsigned int byte_expand3[256] =
+{
+ 0x000000, 0x000007, 0x000038, 0x00003F, 0x0001C0, 0x0001C7, 0x0001F8, 0x0001FF,
+ 0x000E00, 0x000E07, 0x000E38, 0x000E3F, 0x000FC0, 0x000FC7, 0x000FF8, 0x000FFF,
+ 0x007000, 0x007007, 0x007038, 0x00703F, 0x0071C0, 0x0071C7, 0x0071F8, 0x0071FF,
+ 0x007E00, 0x007E07, 0x007E38, 0x007E3F, 0x007FC0, 0x007FC7, 0x007FF8, 0x007FFF,
+ 0x038000, 0x038007, 0x038038, 0x03803F, 0x0381C0, 0x0381C7, 0x0381F8, 0x0381FF,
+ 0x038E00, 0x038E07, 0x038E38, 0x038E3F, 0x038FC0, 0x038FC7, 0x038FF8, 0x038FFF,
+ 0x03F000, 0x03F007, 0x03F038, 0x03F03F, 0x03F1C0, 0x03F1C7, 0x03F1F8, 0x03F1FF,
+ 0x03FE00, 0x03FE07, 0x03FE38, 0x03FE3F, 0x03FFC0, 0x03FFC7, 0x03FFF8, 0x03FFFF,
+ 0x1C0000, 0x1C0007, 0x1C0038, 0x1C003F, 0x1C01C0, 0x1C01C7, 0x1C01F8, 0x1C01FF,
+ 0x1C0E00, 0x1C0E07, 0x1C0E38, 0x1C0E3F, 0x1C0FC0, 0x1C0FC7, 0x1C0FF8, 0x1C0FFF,
+ 0x1C7000, 0x1C7007, 0x1C7038, 0x1C703F, 0x1C71C0, 0x1C71C7, 0x1C71F8, 0x1C71FF,
+ 0x1C7E00, 0x1C7E07, 0x1C7E38, 0x1C7E3F, 0x1C7FC0, 0x1C7FC7, 0x1C7FF8, 0x1C7FFF,
+ 0x1F8000, 0x1F8007, 0x1F8038, 0x1F803F, 0x1F81C0, 0x1F81C7, 0x1F81F8, 0x1F81FF,
+ 0x1F8E00, 0x1F8E07, 0x1F8E38, 0x1F8E3F, 0x1F8FC0, 0x1F8FC7, 0x1F8FF8, 0x1F8FFF,
+ 0x1FF000, 0x1FF007, 0x1FF038, 0x1FF03F, 0x1FF1C0, 0x1FF1C7, 0x1FF1F8, 0x1FF1FF,
+ 0x1FFE00, 0x1FFE07, 0x1FFE38, 0x1FFE3F, 0x1FFFC0, 0x1FFFC7, 0x1FFFF8, 0x1FFFFF,
+ 0xE00000, 0xE00007, 0xE00038, 0xE0003F, 0xE001C0, 0xE001C7, 0xE001F8, 0xE001FF,
+ 0xE00E00, 0xE00E07, 0xE00E38, 0xE00E3F, 0xE00FC0, 0xE00FC7, 0xE00FF8, 0xE00FFF,
+ 0xE07000, 0xE07007, 0xE07038, 0xE0703F, 0xE071C0, 0xE071C7, 0xE071F8, 0xE071FF,
+ 0xE07E00, 0xE07E07, 0xE07E38, 0xE07E3F, 0xE07FC0, 0xE07FC7, 0xE07FF8, 0xE07FFF,
+ 0xE38000, 0xE38007, 0xE38038, 0xE3803F, 0xE381C0, 0xE381C7, 0xE381F8, 0xE381FF,
+ 0xE38E00, 0xE38E07, 0xE38E38, 0xE38E3F, 0xE38FC0, 0xE38FC7, 0xE38FF8, 0xE38FFF,
+ 0xE3F000, 0xE3F007, 0xE3F038, 0xE3F03F, 0xE3F1C0, 0xE3F1C7, 0xE3F1F8, 0xE3F1FF,
+ 0xE3FE00, 0xE3FE07, 0xE3FE38, 0xE3FE3F, 0xE3FFC0, 0xE3FFC7, 0xE3FFF8, 0xE3FFFF,
+ 0xFC0000, 0xFC0007, 0xFC0038, 0xFC003F, 0xFC01C0, 0xFC01C7, 0xFC01F8, 0xFC01FF,
+ 0xFC0E00, 0xFC0E07, 0xFC0E38, 0xFC0E3F, 0xFC0FC0, 0xFC0FC7, 0xFC0FF8, 0xFC0FFF,
+ 0xFC7000, 0xFC7007, 0xFC7038, 0xFC703F, 0xFC71C0, 0xFC71C7, 0xFC71F8, 0xFC71FF,
+ 0xFC7E00, 0xFC7E07, 0xFC7E38, 0xFC7E3F, 0xFC7FC0, 0xFC7FC7, 0xFC7FF8, 0xFC7FFF,
+ 0xFF8000, 0xFF8007, 0xFF8038, 0xFF803F, 0xFF81C0, 0xFF81C7, 0xFF81F8, 0xFF81FF,
+ 0xFF8E00, 0xFF8E07, 0xFF8E38, 0xFF8E3F, 0xFF8FC0, 0xFF8FC7, 0xFF8FF8, 0xFF8FFF,
+ 0xFFF000, 0xFFF007, 0xFFF038, 0xFFF03F, 0xFFF1C0, 0xFFF1C7, 0xFFF1F8, 0xFFF1FF,
+ 0xFFFE00, 0xFFFE07, 0xFFFE38, 0xFFFE3F, 0xFFFFC0, 0xFFFFC7, 0xFFFFF8, 0xFFFFFF
+};
+
+/*
+ * This is a table of 24-bit values, indexed with an 8-bit byte value,
+ * that reverses the bit order of a byte and then expands each bit to three
+ * consecutive bits. This is required for color expansion in 24bpp mode
+ * with the coprocessor in 8bpp mode, with MSB-first bit order within a
+ * byte.
+ */
+
+unsigned int byte_reversed_expand3[256] =
+{
+ 0x000000, 0x0000E0, 0x00001C, 0x0000FC, 0x008003, 0x0080E3, 0x00801F, 0x0080FF,
+ 0x007000, 0x0070E0, 0x00701C, 0x0070FC, 0x00F003, 0x00F0E3, 0x00F01F, 0x00F0FF,
+ 0x000E00, 0x000EE0, 0x000E1C, 0x000EFC, 0x008E03, 0x008EE3, 0x008E1F, 0x008EFF,
+ 0x007E00, 0x007EE0, 0x007E1C, 0x007EFC, 0x00FE03, 0x00FEE3, 0x00FE1F, 0x00FEFF,
+ 0xC00100, 0xC001E0, 0xC0011C, 0xC001FC, 0xC08103, 0xC081E3, 0xC0811F, 0xC081FF,
+ 0xC07100, 0xC071E0, 0xC0711C, 0xC071FC, 0xC0F103, 0xC0F1E3, 0xC0F11F, 0xC0F1FF,
+ 0xC00F00, 0xC00FE0, 0xC00F1C, 0xC00FFC, 0xC08F03, 0xC08FE3, 0xC08F1F, 0xC08FFF,
+ 0xC07F00, 0xC07FE0, 0xC07F1C, 0xC07FFC, 0xC0FF03, 0xC0FFE3, 0xC0FF1F, 0xC0FFFF,
+ 0x380000, 0x3800E0, 0x38001C, 0x3800FC, 0x388003, 0x3880E3, 0x38801F, 0x3880FF,
+ 0x387000, 0x3870E0, 0x38701C, 0x3870FC, 0x38F003, 0x38F0E3, 0x38F01F, 0x38F0FF,
+ 0x380E00, 0x380EE0, 0x380E1C, 0x380EFC, 0x388E03, 0x388EE3, 0x388E1F, 0x388EFF,
+ 0x387E00, 0x387EE0, 0x387E1C, 0x387EFC, 0x38FE03, 0x38FEE3, 0x38FE1F, 0x38FEFF,
+ 0xF80100, 0xF801E0, 0xF8011C, 0xF801FC, 0xF88103, 0xF881E3, 0xF8811F, 0xF881FF,
+ 0xF87100, 0xF871E0, 0xF8711C, 0xF871FC, 0xF8F103, 0xF8F1E3, 0xF8F11F, 0xF8F1FF,
+ 0xF80F00, 0xF80FE0, 0xF80F1C, 0xF80FFC, 0xF88F03, 0xF88FE3, 0xF88F1F, 0xF88FFF,
+ 0xF87F00, 0xF87FE0, 0xF87F1C, 0xF87FFC, 0xF8FF03, 0xF8FFE3, 0xF8FF1F, 0xF8FFFF,
+ 0x070000, 0x0700E0, 0x07001C, 0x0700FC, 0x078003, 0x0780E3, 0x07801F, 0x0780FF,
+ 0x077000, 0x0770E0, 0x07701C, 0x0770FC, 0x07F003, 0x07F0E3, 0x07F01F, 0x07F0FF,
+ 0x070E00, 0x070EE0, 0x070E1C, 0x070EFC, 0x078E03, 0x078EE3, 0x078E1F, 0x078EFF,
+ 0x077E00, 0x077EE0, 0x077E1C, 0x077EFC, 0x07FE03, 0x07FEE3, 0x07FE1F, 0x07FEFF,
+ 0xC70100, 0xC701E0, 0xC7011C, 0xC701FC, 0xC78103, 0xC781E3, 0xC7811F, 0xC781FF,
+ 0xC77100, 0xC771E0, 0xC7711C, 0xC771FC, 0xC7F103, 0xC7F1E3, 0xC7F11F, 0xC7F1FF,
+ 0xC70F00, 0xC70FE0, 0xC70F1C, 0xC70FFC, 0xC78F03, 0xC78FE3, 0xC78F1F, 0xC78FFF,
+ 0xC77F00, 0xC77FE0, 0xC77F1C, 0xC77FFC, 0xC7FF03, 0xC7FFE3, 0xC7FF1F, 0xC7FFFF,
+ 0x3F0000, 0x3F00E0, 0x3F001C, 0x3F00FC, 0x3F8003, 0x3F80E3, 0x3F801F, 0x3F80FF,
+ 0x3F7000, 0x3F70E0, 0x3F701C, 0x3F70FC, 0x3FF003, 0x3FF0E3, 0x3FF01F, 0x3FF0FF,
+ 0x3F0E00, 0x3F0EE0, 0x3F0E1C, 0x3F0EFC, 0x3F8E03, 0x3F8EE3, 0x3F8E1F, 0x3F8EFF,
+ 0x3F7E00, 0x3F7EE0, 0x3F7E1C, 0x3F7EFC, 0x3FFE03, 0x3FFEE3, 0x3FFE1F, 0x3FFEFF,
+ 0xFF0100, 0xFF01E0, 0xFF011C, 0xFF01FC, 0xFF8103, 0xFF81E3, 0xFF811F, 0xFF81FF,
+ 0xFF7100, 0xFF71E0, 0xFF711C, 0xFF71FC, 0xFFF103, 0xFFF1E3, 0xFFF11F, 0xFFF1FF,
+ 0xFF0F00, 0xFF0FE0, 0xFF0F1C, 0xFF0FFC, 0xFF8F03, 0xFF8FE3, 0xFF8F1F, 0xFF8FFF,
+ 0xFF7F00, 0xFF7FE0, 0xFF7F1C, 0xFF7FFC, 0xFFFF03, 0xFFFFE3, 0xFFFF1F, 0xFFFFFF,
+};
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaaWideLine.c b/xc/programs/Xserver/hw/xfree86/xaa/xaaWideLine.c
new file mode 100644
index 000000000..118faaa21
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaaWideLine.c
@@ -0,0 +1,948 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaWideLine.c,v 1.6 1999/05/30 03:03:34 dawes Exp $ */
+
+/*
+
+XAAPolylinesWideSolid does not maintain a span list and subsequently does
+not follow the "touch-each-pixel-once" rules for wide lines and arcs.
+This means it can only be used in the case where we have
+miSpansEasyRop(pGC->alu). Since we clip spans on the fly, we
+limited usage of this function to one rect situations. This
+function is used only for solid lines.
+
+ Adapted from miWideLine by Mark Vojkovich (mvojkovi@ucsd.edu)
+Original mi code written by Keith Packard.
+
+*/
+
+#ifndef XFree86LOADER
+#ifdef _XOPEN_SOURCE
+#include <math.h>
+#else
+#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */
+#include <math.h>
+#undef _XOPEN_SOURCE
+#endif
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "windowstr.h"
+#include "gcstruct.h"
+#include "miscstruct.h"
+#include "miwideline.h"
+#include "mi.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+#ifdef ICEILTEMPDECL
+ICEILTEMPDECL
+#endif
+
+#define DRAW_POINT(pScrn, x, y) \
+ if(hardClip) (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, 1, 1); \
+ else XAAPointHelper(pScrn, x, y)
+
+#define FILL_RECT(pScrn, x, y, w, h) \
+ if(hardClip) (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); \
+ else XAAFillRectHelper(pScrn, x, y, w, h)
+
+#define FILL_SPAN(pScrn, x, y, w) \
+ if(hardClip) (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, 1); \
+ else XAASpanHelper(pScrn, x, y, w)
+
+
+#define CLIPSTEPEDGE(edgey,edge,edgeleft) \
+ if (ybase == edgey) { \
+ if (edgeleft) { \
+ if (edge->x > xcl) \
+ xcl = edge->x; \
+ } else { \
+ if (edge->x < xcr) \
+ xcr = edge->x; \
+ } \
+ edgey++; \
+ edge->x += edge->stepx; \
+ edge->e += edge->dx; \
+ if (edge->e > 0) { \
+ edge->x += edge->signdx; \
+ edge->e -= edge->dy; \
+ } \
+ }
+
+static void
+XAAPointHelper(ScrnInfoPtr pScrn, int x, int y)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ BoxPtr extents = infoRec->ClipBox;
+
+ if((x >= extents->x1) && (x < extents->x2) &&
+ (y >= extents->y1) && (y < extents->y2))
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, 1, 1);
+}
+
+static void
+XAAFillRectHelper(ScrnInfoPtr pScrn, int x1, int y1, int dx, int dy)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ BoxPtr extents = infoRec->ClipBox;
+ int x2 = x1 + dx;
+ int y2 = y1 + dy;
+
+ if(x1 < extents->x1) x1 = extents->x1;
+ if(x2 >= extents->x2) x2 = extents->x2;
+ if((dx = x2 - x1)<1) return;
+ if(y1 < extents->y1) y1 = extents->y1;
+ if(y2 >= extents->y2) y2 = extents->y2;
+ if((dy = y2 - y1)<1) return;
+
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x1, y1, dx, dy);
+}
+
+
+static void
+XAASpanHelper(ScrnInfoPtr pScrn, int x1, int y, int width)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ BoxPtr extents = infoRec->ClipBox;
+ int x2;
+
+ if((y < extents->y1) || (y >= extents->y2)) return;
+
+ x2 = x1 + width;
+ if(x1 < extents->x1) x1 = extents->x1;
+ if(x2 > extents->x2) x2 = extents->x2;
+ width = x2 - x1;
+
+ if(width > 0)
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x1, y, width, 1);
+
+}
+
+#define FixError(x, dx, dy, e, sign, step, h) { \
+ e += (h) * dx; \
+ x += (h) * step; \
+ if(e > 0) { \
+ x += e * sign/dy; \
+ e %= dy; \
+ if(e) { \
+ x += sign; \
+ e -= dy; \
+ } \
+ } \
+}
+
+
+static void
+XAAFillPolyHelper (
+ GCPtr pGC,
+ int y, /* start y coordinate */
+ int overall_height, /* height of entire segment */
+ PolyEdgePtr left, PolyEdgePtr right,
+ int left_count, int right_count )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ BoxPtr extents = infoRec->ClipBox;
+ int left_x, left_e, left_stepx, left_signdx, left_dy, left_dx;
+ int right_x, right_e, right_stepx, right_signdx, right_dy, right_dx;
+ int height;
+ int left_height = 0;
+ int right_height = 0;
+ int xorg = 0;
+ Bool hardClip;
+
+ if((y >= extents->y2) || ((y + overall_height) <= extents->y1))
+ return;
+
+ hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
+
+ while ((left_count || left_height) && (right_count || right_height)) {
+ if (!left_height && left_count) {
+ left_height = left->height;
+ left_x = left->x + xorg;
+ left_stepx = left->stepx;
+ left_signdx = left->signdx;
+ left_e = left->e;
+ left_dy = left->dy;
+ left_dx = left->dx;
+ left_count--;
+ left++;
+ }
+ if (!right_height && right_count) {
+ right_height = right->height;
+ right_x = right->x + xorg + 1;
+ right_stepx = right->stepx;
+ right_signdx = right->signdx;
+ right_e = right->e;
+ right_dy = right->dy;
+ right_dx = right->dx;
+ right_count--;
+ right++;
+ }
+
+ height = (left_height > right_height) ? right_height : left_height;
+
+ left_height -= height;
+ right_height -= height;
+
+ if(infoRec->SubsequentSolidFillTrap && (height > 6)) {
+ int right_DX, left_DX, left_box, right_box;
+
+ right_DX = (right_dx * right_signdx) + (right_stepx * right_dy);
+ left_DX = (left_dx * left_signdx) + (left_stepx * left_dy);
+ if(!hardClip) {
+ left_box = (left_DX < 0) ? (left_x + left_DX) : left_x;
+ right_box = (right_DX < 0) ? right_x : (right_x + right_DX);
+ }
+
+ if(hardClip || ((left_box >= extents->x1) &&
+ (right_box < extents->x2) &&
+ (y >= extents->y1) &&
+ ((y + height) < extents->y2))){
+
+ (*infoRec->SubsequentSolidFillTrap)(infoRec->pScrn, y, height,
+ left_x, left_DX, left_dy, left_e,
+ right_x - 1, right_DX, right_dy, right_e);
+
+ FixError(left_x, left_dx, left_dy, left_e, left_signdx,
+ left_stepx, height);
+ FixError(right_x, right_dx, right_dy, right_e, right_signdx,
+ right_stepx, height);
+ y += height;
+ continue;
+ }
+ }
+
+ while (height--) {
+ if(right_x > left_x) {
+ FILL_SPAN(infoRec->pScrn, left_x, y, right_x - left_x);
+ }
+ y++;
+
+ left_x += left_stepx;
+ left_e += left_dx;
+ if (left_e > 0) {
+ left_x += left_signdx;
+ left_e -= left_dy;
+ }
+ right_x += right_stepx;
+ right_e += right_dx;
+ if (right_e > 0) {
+ right_x += right_signdx;
+ right_e -= right_dy;
+ }
+
+ }
+ }
+}
+
+
+
+static void
+XAAWideSegment (
+ GCPtr pGC,
+ int x1, int y1, int x2, int y2,
+ Bool projectLeft, Bool projectRight,
+ LineFacePtr leftFace, LineFacePtr rightFace )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ double l, L, r;
+ double xa, ya;
+ double projectXoff, projectYoff;
+ double k;
+ double maxy;
+ int x, y;
+ int dx, dy;
+ int finaly;
+ PolyEdgePtr left, right;
+ PolyEdgePtr top, bottom;
+ int lefty, righty, topy, bottomy;
+ int signdx;
+ PolyEdgeRec lefts[2], rights[2];
+ LineFacePtr tface;
+ int lw = pGC->lineWidth;
+ Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
+
+ /* draw top-to-bottom always */
+ if (y2 < y1 || y2 == y1 && x2 < x1) {
+ x = x1;
+ x1 = x2;
+ x2 = x;
+
+ y = y1;
+ y1 = y2;
+ y2 = y;
+
+ x = projectLeft;
+ projectLeft = projectRight;
+ projectRight = x;
+
+ tface = leftFace;
+ leftFace = rightFace;
+ rightFace = tface;
+ }
+
+ dy = y2 - y1;
+ signdx = 1;
+ dx = x2 - x1;
+ if (dx < 0)
+ signdx = -1;
+
+ leftFace->x = x1;
+ leftFace->y = y1;
+ leftFace->dx = dx;
+ leftFace->dy = dy;
+
+ rightFace->x = x2;
+ rightFace->y = y2;
+ rightFace->dx = -dx;
+ rightFace->dy = -dy;
+
+
+ if (!dy) {
+ rightFace->xa = 0;
+ rightFace->ya = (double) lw / 2.0;
+ rightFace->k = -(double) (lw * dx) / 2.0;
+ leftFace->xa = 0;
+ leftFace->ya = -rightFace->ya;
+ leftFace->k = rightFace->k;
+ x = x1;
+ if (projectLeft)
+ x -= (lw >> 1);
+ y = y1 - (lw >> 1);
+ dx = x2 - x;
+ if (projectRight)
+ dx += ((lw + 1) >> 1);
+ dy = lw;
+ FILL_RECT(infoRec->pScrn, x, y, dx, dy);
+ } else if (!dx) {
+ leftFace->xa = (double) lw / 2.0;
+ leftFace->ya = 0;
+ leftFace->k = (double) (lw * dy) / 2.0;
+ rightFace->xa = -leftFace->xa;
+ rightFace->ya = 0;
+ rightFace->k = leftFace->k;
+ y = y1;
+ if (projectLeft)
+ y -= lw >> 1;
+ x = x1 - (lw >> 1);
+ dy = y2 - y;
+ if (projectRight)
+ dy += ((lw + 1) >> 1);
+ dx = lw;
+ FILL_RECT(infoRec->pScrn, x, y, dx, dy);
+ } else {
+ l = ((double) lw) / 2.0;
+ L = sqrt((double)(dx*dx + dy*dy));
+
+ if (dx < 0) {
+ right = &rights[1];
+ left = &lefts[0];
+ top = &rights[0];
+ bottom = &lefts[1];
+ } else {
+ right = &rights[0];
+ left = &lefts[1];
+ top = &lefts[0];
+ bottom = &rights[1];
+ }
+ r = l / L;
+
+ /* coord of upper bound at integral y */
+ ya = -r * dx;
+ xa = r * dy;
+
+ if (projectLeft | projectRight) {
+ projectXoff = -ya;
+ projectYoff = xa;
+ }
+
+ /* xa * dy - ya * dx */
+ k = l * L;
+
+ leftFace->xa = xa;
+ leftFace->ya = ya;
+ leftFace->k = k;
+ rightFace->xa = -xa;
+ rightFace->ya = -ya;
+ rightFace->k = k;
+
+ if (projectLeft)
+ righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
+ k, dx, dy, x1, y1, 0, right);
+ else
+ righty = miPolyBuildEdge (xa, ya,
+ k, dx, dy, x1, y1, 0, right);
+
+ /* coord of lower bound at integral y */
+ ya = -ya;
+ xa = -xa;
+
+ /* xa * dy - ya * dx */
+ k = - k;
+
+ if (projectLeft)
+ lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
+ k, dx, dy, x1, y1, 1, left);
+ else
+ lefty = miPolyBuildEdge (xa, ya,
+ k, dx, dy, x1, y1, 1, left);
+
+ /* coord of top face at integral y */
+
+ if (signdx > 0) {
+ ya = -ya;
+ xa = -xa;
+ }
+
+ if (projectLeft) {
+ double xap = xa - projectXoff;
+ double yap = ya - projectYoff;
+ topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
+ -dy, dx, x1, y1, dx > 0, top);
+ }
+ else
+ topy = miPolyBuildEdge(xa, ya, 0.0,
+ -dy, dx, x1, y1, dx > 0, top);
+
+ /* coord of bottom face at integral y */
+
+ if (projectRight) {
+ double xap = xa + projectXoff;
+ double yap = ya + projectYoff;
+ bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
+ -dy, dx, x2, y2, dx < 0, bottom);
+ maxy = -ya + projectYoff;
+ } else {
+ bottomy = miPolyBuildEdge (xa, ya, 0.0,
+ -dy, dx, x2, y2, dx < 0, bottom);
+ maxy = -ya;
+ }
+
+ finaly = ICEIL (maxy) + y2;
+
+ if (dx < 0) {
+ left->height = bottomy - lefty;
+ right->height = finaly - righty;
+ top->height = righty - topy;
+ } else {
+ right->height = bottomy - righty;
+ left->height = finaly - lefty;
+ top->height = lefty - topy;
+ }
+ bottom->height = finaly - bottomy;
+ XAAFillPolyHelper (pGC, topy,
+ bottom->height + bottomy - topy, lefts, rights, 2, 2);
+ }
+}
+
+
+static void
+XAALineArcI (GCPtr pGC, int xorg, int yorg)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int x, y, e, ex;
+ int slw = pGC->lineWidth;
+ Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
+
+ y = (slw >> 1) + 1;
+ if (slw & 1)
+ e = - ((y << 2) + 3);
+ else
+ e = - (y << 3);
+ ex = -4;
+ x = 0;
+ while (y) {
+ e += (y << 3) - 4;
+ while (e >= 0) {
+ x++;
+ e += (ex = -((x << 3) + 4));
+ }
+ y--;
+ slw = (x << 1) + 1;
+ if ((e == ex) && (slw > 1))
+ slw--;
+
+ FILL_SPAN(infoRec->pScrn, xorg - x, yorg - y, slw);
+
+ if ((y != 0) && ((slw > 1) || (e != ex))) {
+ FILL_SPAN(infoRec->pScrn, xorg - x, yorg + y, slw);
+ }
+ }
+}
+
+
+static void
+XAALineArcD (
+ GCPtr pGC,
+ double xorg,
+ double yorg,
+ PolyEdgePtr edge1,
+ int edgey1,
+ Bool edgeleft1,
+ PolyEdgePtr edge2,
+ int edgey2,
+ Bool edgeleft2 )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ double radius, x0, y0, el, er, yk, xlk, xrk, k;
+ int xbase, ybase, y, boty, xl, xr, xcl, xcr;
+ int ymin, ymax;
+ Bool edge1IsMin, edge2IsMin;
+ int ymin1, ymin2;
+ Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
+
+
+ xbase = floor(xorg);
+ x0 = xorg - xbase;
+ ybase = ICEIL (yorg);
+ y0 = yorg - ybase;
+
+ xlk = x0 + x0 + 1.0;
+ xrk = x0 + x0 - 1.0;
+ yk = y0 + y0 - 1.0;
+ radius = ((double)pGC->lineWidth) / 2.0;
+ y = floor(radius - y0 + 1.0);
+ ybase -= y;
+ ymin = ybase;
+ ymax = 65536;
+ edge1IsMin = FALSE;
+ ymin1 = edgey1;
+ if (edge1->dy >= 0) {
+ if (!edge1->dy) {
+ if (edgeleft1)
+ edge1IsMin = TRUE;
+ else
+ ymax = edgey1;
+ edgey1 = 65536;
+ } else if ((edge1->signdx < 0) == edgeleft1)
+ edge1IsMin = TRUE;
+ }
+ edge2IsMin = FALSE;
+ ymin2 = edgey2;
+ if (edge2->dy >= 0) {
+ if (!edge2->dy) {
+ if (edgeleft2)
+ edge2IsMin = TRUE;
+ else
+ ymax = edgey2;
+ edgey2 = 65536;
+ } else if ((edge2->signdx < 0) == edgeleft2)
+ edge2IsMin = TRUE;
+ }
+ if (edge1IsMin) {
+ ymin = ymin1;
+ if (edge2IsMin && (ymin1 > ymin2))
+ ymin = ymin2;
+ } else if (edge2IsMin)
+ ymin = ymin2;
+ el = radius * radius - ((y + y0) * (y + y0)) - (x0 * x0);
+ er = el + xrk;
+ xl = 1;
+ xr = 0;
+ if (x0 < 0.5) {
+ xl = 0;
+ el -= xlk;
+ }
+ boty = (y0 < -0.5) ? 1 : 0;
+ if (ybase + y - boty > ymax)
+ boty = ymax - ybase - y;
+ while (y > boty) {
+ k = (y << 1) + yk;
+ er += k;
+ while (er > 0.0) {
+ xr++;
+ er += xrk - (xr << 1);
+ }
+ el += k;
+ while (el >= 0.0) {
+ xl--;
+ el += (xl << 1) - xlk;
+ }
+ y--;
+ ybase++;
+ if (ybase < ymin)
+ continue;
+ xcl = xl + xbase;
+ xcr = xr + xbase;
+ CLIPSTEPEDGE(edgey1, edge1, edgeleft1);
+ CLIPSTEPEDGE(edgey2, edge2, edgeleft2);
+ if(xcr >= xcl) {
+ FILL_SPAN(infoRec->pScrn, xcl, ybase, xcr - xcl + 1);
+ }
+ }
+ er = xrk - (xr << 1) - er;
+ el = (xl << 1) - xlk - el;
+ boty = floor(-y0 - radius + 1.0);
+ if (ybase + y - boty > ymax)
+ boty = ymax - ybase - y;
+ while (y > boty) {
+ k = (y << 1) + yk;
+ er -= k;
+ while ((er >= 0.0) && (xr >= 0)) {
+ xr--;
+ er += xrk - (xr << 1);
+ }
+ el -= k;
+ while ((el > 0.0) && (xl <= 0)) {
+ xl++;
+ el += (xl << 1) - xlk;
+ }
+ y--;
+ ybase++;
+ if (ybase < ymin)
+ continue;
+ xcl = xl + xbase;
+ xcr = xr + xbase;
+ CLIPSTEPEDGE(edgey1, edge1, edgeleft1);
+ CLIPSTEPEDGE(edgey2, edge2, edgeleft2);
+ if(xcr >= xcl) {
+ FILL_SPAN(infoRec->pScrn, xcl, ybase, xcr - xcl + 1);
+ }
+ }
+}
+
+
+static void
+XAALineArc (
+ GCPtr pGC,
+ LineFacePtr leftFace,
+ LineFacePtr rightFace,
+ double xorg,
+ double yorg,
+ Bool isInt )
+{
+ int xorgi, yorgi;
+ PolyEdgeRec edge1, edge2;
+ int edgey1, edgey2;
+ Bool edgeleft1, edgeleft2;
+
+ if (isInt) {
+ xorgi = leftFace ? leftFace->x : rightFace->x;
+ yorgi = leftFace ? leftFace->y : rightFace->y;
+ }
+ edgey1 = 65536;
+ edgey2 = 65536;
+ edge1.x = 0; /* not used, keep memory checkers happy */
+ edge1.dy = -1;
+ edge2.x = 0; /* not used, keep memory checkers happy */
+ edge2.dy = -1;
+ edgeleft1 = FALSE;
+ edgeleft2 = FALSE;
+
+ if ((pGC->lineWidth > 2) &&
+ (pGC->capStyle == CapRound && pGC->joinStyle != JoinRound ||
+ pGC->joinStyle == JoinRound && pGC->capStyle == CapButt)) {
+ if (isInt) {
+ xorg = (double) xorgi;
+ yorg = (double) yorgi;
+ }
+
+ if (leftFace && rightFace)
+ miRoundJoinClip (leftFace, rightFace, &edge1, &edge2,
+ &edgey1, &edgey2, &edgeleft1, &edgeleft2);
+ else if (leftFace)
+ edgey1 = miRoundCapClip (leftFace, isInt, &edge1, &edgeleft1);
+ else if (rightFace)
+ edgey2 = miRoundCapClip (rightFace, isInt, &edge2, &edgeleft2);
+
+ isInt = FALSE;
+ }
+
+ if (isInt) {
+ if(pGC->lineWidth == 1) {
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
+ DRAW_POINT(infoRec->pScrn, xorgi, yorgi);
+ } else
+ XAALineArcI(pGC, xorgi, yorgi);
+ } else
+ XAALineArcD(pGC, xorg, yorg, &edge1, edgey1, edgeleft1,
+ &edge2, edgey2, edgeleft2);
+
+}
+
+
+static void
+XAALineJoin (
+ GCPtr pGC,
+ LineFacePtr pLeft,
+ LineFacePtr pRight )
+{
+ double mx, my;
+ double denom;
+ PolyVertexRec vertices[4];
+ PolySlopeRec slopes[4];
+ int edgecount;
+ PolyEdgeRec left[4], right[4];
+ int nleft, nright;
+ int y, height;
+ int swapslopes;
+ int joinStyle = pGC->joinStyle;
+ int lw = pGC->lineWidth;
+
+ if (lw == 1) {
+ /* Lines going in the same direction have no join */
+ if ((pLeft->dx >= 0) == (pRight->dx <= 0))
+ return;
+ if (joinStyle != JoinRound) {
+ denom = - pLeft->dx * (double)pRight->dy + pRight->dx *
+ (double)pLeft->dy;
+ if (denom == 0.0)
+ return; /* no join to draw */
+ }
+ if (joinStyle != JoinMiter) {
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
+ DRAW_POINT(infoRec->pScrn, pLeft->x, pLeft->y);
+ return;
+ }
+ } else {
+ if (joinStyle == JoinRound) {
+ XAALineArc(pGC, pLeft, pRight,(double)0.0, (double)0.0, TRUE);
+ return;
+ }
+ denom = - pLeft->dx * (double)pRight->dy + pRight->dx *
+ (double)pLeft->dy;
+ if (denom == 0.0)
+ return; /* no join to draw */
+ }
+
+ swapslopes = 0;
+ if (denom > 0) {
+ pLeft->xa = -pLeft->xa;
+ pLeft->ya = -pLeft->ya;
+ pLeft->dx = -pLeft->dx;
+ pLeft->dy = -pLeft->dy;
+ } else {
+ swapslopes = 1;
+ pRight->xa = -pRight->xa;
+ pRight->ya = -pRight->ya;
+ pRight->dx = -pRight->dx;
+ pRight->dy = -pRight->dy;
+ }
+
+ vertices[0].x = pRight->xa;
+ vertices[0].y = pRight->ya;
+ slopes[0].dx = -pRight->dy;
+ slopes[0].dy = pRight->dx;
+ slopes[0].k = 0;
+
+ vertices[1].x = 0;
+ vertices[1].y = 0;
+ slopes[1].dx = pLeft->dy;
+ slopes[1].dy = -pLeft->dx;
+ slopes[1].k = 0;
+
+ vertices[2].x = pLeft->xa;
+ vertices[2].y = pLeft->ya;
+
+ if (joinStyle == JoinMiter) {
+ my = (pLeft->dy * (pRight->xa * pRight->dy - pRight->ya * pRight->dx) -
+ pRight->dy * (pLeft->xa * pLeft->dy - pLeft->ya * pLeft->dx ))/
+ denom;
+ if (pLeft->dy != 0)
+ mx = pLeft->xa + (my - pLeft->ya) *
+ (double) pLeft->dx / (double) pLeft->dy;
+ else
+ mx = pRight->xa + (my - pRight->ya) *
+ (double) pRight->dx / (double) pRight->dy;
+
+ /* check miter limit */
+ if ((mx * mx + my * my) * 4 > SQSECANT * lw * lw)
+ joinStyle = JoinBevel;
+ }
+
+ if (joinStyle == JoinMiter) {
+ slopes[2].dx = pLeft->dx;
+ slopes[2].dy = pLeft->dy;
+ slopes[2].k = pLeft->k;
+ if (swapslopes) {
+ slopes[2].dx = -slopes[2].dx;
+ slopes[2].dy = -slopes[2].dy;
+ slopes[2].k = -slopes[2].k;
+ }
+ vertices[3].x = mx;
+ vertices[3].y = my;
+ slopes[3].dx = pRight->dx;
+ slopes[3].dy = pRight->dy;
+ slopes[3].k = pRight->k;
+ if (swapslopes) {
+ slopes[3].dx = -slopes[3].dx;
+ slopes[3].dy = -slopes[3].dy;
+ slopes[3].k = -slopes[3].k;
+ }
+ edgecount = 4;
+ } else {
+ double scale, dx, dy, adx, ady;
+
+ adx = dx = pRight->xa - pLeft->xa;
+ ady = dy = pRight->ya - pLeft->ya;
+ if (adx < 0)
+ adx = -adx;
+ if (ady < 0)
+ ady = -ady;
+ scale = ady;
+ if (adx > ady)
+ scale = adx;
+ slopes[2].dx = (dx * 65536) / scale;
+ slopes[2].dy = (dy * 65536) / scale;
+ slopes[2].k = ((pLeft->xa + pRight->xa) * slopes[2].dy -
+ (pLeft->ya + pRight->ya) * slopes[2].dx) / 2.0;
+ edgecount = 3;
+ }
+
+ y = miPolyBuildPoly (vertices, slopes, edgecount, pLeft->x, pLeft->y,
+ left, right, &nleft, &nright, &height);
+ XAAFillPolyHelper(pGC, y, height, left, right, nleft, nright);
+}
+
+
+void
+XAAPolylinesWideSolid (
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int x1, y1, x2, y2;
+ Bool projectLeft, projectRight;
+ LineFaceRec leftFace, rightFace, prevRightFace, firstFace;
+ int first = TRUE;
+ Bool somethingDrawn = FALSE;
+ Bool selfJoin = FALSE;
+ int xorg = pDrawable->x;
+ int yorg = pDrawable->y;
+ Bool hardClip = FALSE;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ if(REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
+ miWideLine(pDrawable, pGC, mode, npt, pPts);
+ return;
+ }
+
+ infoRec->ClipBox = &pGC->pCompositeClip->extents;
+
+ if(infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL) {
+ hardClip = TRUE;
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ infoRec->ClipBox->x1, infoRec->ClipBox->y1,
+ infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
+ }
+
+ if (mode == CoordModePrevious) {
+ pPts->x += xorg;
+ pPts->y += yorg;
+ } else if(xorg | yorg) {
+ register int n = npt;
+ register DDXPointPtr pts = pPts;
+
+ while(n--) {
+ pts->x += xorg;
+ pts->y += yorg;
+ pts++;
+ }
+ }
+
+ x2 = pPts->x;
+ y2 = pPts->y;
+ if (npt > 1) {
+ if (mode == CoordModePrevious) {
+ int nptTmp;
+ register DDXPointPtr pPtsTmp;
+
+ x1 = x2;
+ y1 = y2;
+ nptTmp = npt;
+ pPtsTmp = pPts + 1;
+ while (--nptTmp) {
+ x1 += pPtsTmp->x;
+ y1 += pPtsTmp->y;
+ ++pPtsTmp;
+ }
+ if ((x2 == x1) && (y2 == y1))
+ selfJoin = TRUE;
+ } else if ((x2 == pPts[npt-1].x) && (y2 == pPts[npt-1].y))
+ selfJoin = TRUE;
+ }
+
+ projectLeft = ((pGC->capStyle == CapProjecting) && !selfJoin);
+ projectRight = FALSE;
+
+ (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
+ pGC->planemask);
+
+
+ while (--npt) {
+ x1 = x2;
+ y1 = y2;
+ ++pPts;
+ x2 = pPts->x;
+ y2 = pPts->y;
+ if (mode == CoordModePrevious) {
+ x2 += x1;
+ y2 += y1;
+ }
+ if ((x1 != x2) || (y1 != y2)) {
+ somethingDrawn = TRUE;
+ if ((npt == 1) && (pGC->capStyle == CapProjecting) && !selfJoin)
+ projectRight = TRUE;
+ XAAWideSegment(pGC, x1, y1, x2, y2,
+ projectLeft, projectRight, &leftFace, &rightFace);
+ if (first) {
+ if (selfJoin)
+ firstFace = leftFace;
+ else if (pGC->capStyle == CapRound) {
+ if (pGC->lineWidth == 1) {
+ DRAW_POINT(infoRec->pScrn, x1, y1);
+ } else
+ XAALineArc(pGC,&leftFace, (LineFacePtr) NULL,
+ (double)0.0, (double)0.0,TRUE);
+ }
+ } else
+ XAALineJoin (pGC, &leftFace, &prevRightFace);
+
+ prevRightFace = rightFace;
+ first = FALSE;
+ projectLeft = FALSE;
+ }
+ if (npt == 1 && somethingDrawn) {
+ if (selfJoin)
+ XAALineJoin (pGC, &firstFace, &rightFace);
+ else if (pGC->capStyle == CapRound) {
+ if (pGC->lineWidth == 1) {
+ DRAW_POINT(infoRec->pScrn, x2, y2);
+ } else
+ XAALineArc (pGC, (LineFacePtr) NULL, &rightFace,
+ (double)0.0, (double)0.0,TRUE);
+ }
+ }
+ }
+ /* handle crock where all points are coincedent */
+ if (!somethingDrawn) {
+ projectLeft = (pGC->capStyle == CapProjecting);
+ XAAWideSegment (pGC, x2, y2, x2, y2, projectLeft, projectLeft,
+ &leftFace, &rightFace);
+ if (pGC->capStyle == CapRound) {
+ XAALineArc (pGC, &leftFace, (LineFacePtr) NULL,
+ (double)0.0, (double)0.0, TRUE);
+ rightFace.dx = -1; /* sleezy hack to make it work */
+ XAALineArc (pGC, (LineFacePtr) NULL, &rightFace,
+ (double)0.0, (double)0.0, TRUE);
+ }
+ }
+
+ infoRec->ClipBox = NULL;
+ if(hardClip)
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+
+ SET_SYNC_FLAG(infoRec);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaacexp.h b/xc/programs/Xserver/hw/xfree86/xaa/xaacexp.h
new file mode 100644
index 000000000..516fe842e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaacexp.h
@@ -0,0 +1,117 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaacexp.h,v 1.2 1998/07/25 16:58:54 dawes Exp $ */
+
+
+#ifndef FIXEDBASE
+#define CHECKRETURN(b) if(width <= ((b) * 32)) return(base + (b))
+#else
+#define CHECKRETURN(b) if(width <= ((b) * 32)) return(base)
+#endif
+
+#define SHIFT_L(value, shift) ((value) << (shift))
+#define SHIFT_R(value, shift) ((value) >> (shift))
+
+#ifndef MSBFIRST
+# ifdef FIXEDBASE
+# define WRITE_IN_BITORDER(dest, offset, data) *(dest) = data;
+# else
+# define WRITE_IN_BITORDER(dest, offset, data) *(dest + offset) = data;
+# endif
+#else
+# ifdef FIXEDBASE
+# define WRITE_IN_BITORDER(dest, offset, data) *(dest) = XAAReverseBitOrder(data);
+# else
+# define WRITE_IN_BITORDER(dest, offset, data) *(dest + offset) = XAAReverseBitOrder(data)
+# endif
+#endif
+
+#ifdef FIXEDBASE
+# ifdef MSBFIRST
+# define WRITE_BITS(b) *base = XAAReverseBitOrder(b)
+# define WRITE_BITS1(b) { \
+ *base = byte_reversed_expand3[(b) & 0xFF] | \
+ byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; }
+# define WRITE_BITS2(b) { \
+ *base = byte_reversed_expand3[(b) & 0xFF] | \
+ byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; \
+ *base = byte_reversed_expand3[((b) & 0xFF00) >> 8] >> 8 | \
+ byte_reversed_expand3[((b) & 0xFF0000) >> 16] << 16; }
+# define WRITE_BITS3(b) { \
+ *base = byte_reversed_expand3[(b) & 0xFF] | \
+ byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; \
+ *base = byte_reversed_expand3[((b) & 0xFF00) >> 8] >> 8 | \
+ byte_reversed_expand3[((b) & 0xFF0000) >> 16] << 16; \
+ *base = byte_reversed_expand3[((b) & 0xFF0000) >> 16] >> 16 | \
+ byte_reversed_expand3[((b) & 0xFF000000) >> 24] << 8; }
+# else
+# define WRITE_BITS(b) *base = (b)
+# define WRITE_BITS1(b) { \
+ *base = byte_expand3[(b) & 0xFF] | \
+ byte_expand3[((b) & 0xFF00) >> 8] << 24; }
+# define WRITE_BITS2(b) { \
+ *base = byte_expand3[(b) & 0xFF] | \
+ byte_expand3[((b) & 0xFF00) >> 8] << 24; \
+ *base = byte_expand3[((b) & 0xFF00) >> 8] >> 8 | \
+ byte_expand3[((b) & 0xFF0000) >> 16] << 16; }
+# define WRITE_BITS3(b) { \
+ *base = byte_expand3[(b) & 0xFF] | \
+ byte_expand3[((b) & 0xFF00) >> 8] << 24; \
+ *base = byte_expand3[((b) & 0xFF00) >> 8] >> 8 | \
+ byte_expand3[((b) & 0xFF0000) >> 16] << 16; \
+ *base = byte_expand3[((b) & 0xFF0000) >> 16] >> 16 | \
+ byte_expand3[((b) & 0xFF000000) >> 24] << 8; }
+# endif
+#else
+# ifdef MSBFIRST
+# define WRITE_BITS(b) *(base++) = XAAReverseBitOrder(b)
+# define WRITE_BITS1(b) { \
+ *(base++) = byte_reversed_expand3[(b) & 0xFF] | \
+ byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; }
+# define WRITE_BITS2(b) { \
+ *(base) = byte_reversed_expand3[(b) & 0xFF] | \
+ byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; \
+ *(base + 1) = byte_reversed_expand3[((b) & 0xFF00) >> 8] >> 8 | \
+ byte_reversed_expand3[((b) & 0xFF0000) >> 16] << 16; \
+ base += 2; }
+# define WRITE_BITS3(b) { \
+ *(base) = byte_reversed_expand3[(b) & 0xFF] | \
+ byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; \
+ *(base + 1) = byte_reversed_expand3[((b) & 0xFF00) >> 8] >> 8 | \
+ byte_reversed_expand3[((b) & 0xFF0000) >> 16] << 16; \
+ *(base + 2) = byte_reversed_expand3[((b) & 0xFF0000) >> 16] >> 16 | \
+ byte_reversed_expand3[((b) & 0xFF000000) >> 24] << 8; \
+ base += 3; }
+# else
+# define WRITE_BITS(b) *(base++) = (b)
+# define WRITE_BITS1(b) { \
+ *(base++) = byte_expand3[(b) & 0xFF] | \
+ byte_expand3[((b) & 0xFF00) >> 8] << 24; }
+# define WRITE_BITS2(b) { \
+ *(base) = byte_expand3[(b) & 0xFF] | \
+ byte_expand3[((b) & 0xFF00) >> 8] << 24; \
+ *(base + 1) = byte_expand3[((b) & 0xFF00) >> 8] >> 8 | \
+ byte_expand3[((b) & 0xFF0000) >> 16] << 16; \
+ base += 2; }
+# define WRITE_BITS3(b) { \
+ *(base) = byte_expand3[(b) & 0xFF] | \
+ byte_expand3[((b) & 0xFF00) >> 8] << 24; \
+ *(base + 1) = byte_expand3[((b) & 0xFF00) >> 8] >> 8 | \
+ byte_expand3[((b) & 0xFF0000) >> 16] << 16; \
+ *(base + 2) = byte_expand3[((b) & 0xFF0000) >> 16] >> 16 | \
+ byte_expand3[((b) & 0xFF000000) >> 24] << 8; \
+ base += 3; }
+# endif
+#endif
+
+#ifdef FIXEDBASE
+# ifdef MSBFIRST
+# define EXPNAME(x) x##MSBFirstFixedBase
+# else
+# define EXPNAME(x) x##LSBFirstFixedBase
+# endif
+#else
+# ifdef MSBFIRST
+# define EXPNAME(x) x##MSBFirst
+# else
+# define EXPNAME(x) x##LSBFirst
+# endif
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaalocal.h b/xc/programs/Xserver/hw/xfree86/xaa/xaalocal.h
new file mode 100644
index 000000000..b7dff7e50
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaalocal.h
@@ -0,0 +1,1524 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaalocal.h,v 1.19 1999/06/20 08:41:40 dawes Exp $ */
+
+#ifndef _XAALOCAL_H
+#define _XAALOCAL_H
+
+/* This file is very unorganized ! */
+
+
+#include "gcstruct.h"
+#include "regionstr.h"
+#include "xf86fbman.h"
+#include "xaa.h"
+#include "mi.h"
+
+#define GCWhenForced (GCArcMode << 1)
+
+#define DO_COLOR_8x8 0x00000001
+#define DO_MONO_8x8 0x00000002
+#define DO_CACHE_BLT 0x00000003
+#define DO_COLOR_EXPAND 0x00000004
+#define DO_CACHE_EXPAND 0x00000005
+#define DO_IMAGE_WRITE 0x00000006
+#define DO_PIXMAP_COPY 0x00000007
+#define DO_SOLID 0x00000008
+
+
+typedef CARD32 * (*GlyphScanlineFuncPtr)(
+ CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
+);
+
+typedef CARD32 *(*StippleScanlineProcPtr)(CARD32*, CARD32*, int, int, int);
+
+typedef void (*RectFuncPtr) (ScrnInfoPtr, int, int, int, int, int, int,
+ XAACacheInfoPtr);
+typedef void (*TrapFuncPtr) (ScrnInfoPtr, int, int, int, int, int, int,
+ int, int, int, int, int, int,
+ XAACacheInfoPtr);
+
+
+
+typedef struct _XAAScreen {
+ CreateGCProcPtr CreateGC;
+ CloseScreenProcPtr CloseScreen;
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ CopyWindowProcPtr CopyWindow;
+ WindowExposuresProcPtr WindowExposures;
+ BSFuncRec BackingStoreFuncs;
+ CreatePixmapProcPtr CreatePixmap;
+ DestroyPixmapProcPtr DestroyPixmap;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+ XAAInfoRecPtr AccelInfoRec;
+ Bool (*EnterVT)(int, int);
+ void (*LeaveVT)(int, int);
+ int (*SetDGAMode)(int, int, DGADevicePtr);
+ Bool (*SaveRestoreImage)(int, SaveRestoreFlags);
+} XAAScreenRec, *XAAScreenPtr;
+
+#define OPS_ARE_PIXMAP 0x00000001
+#define OPS_ARE_ACCEL 0x00000002
+
+typedef struct _XAAGC {
+ GCOps *wrapOps;
+ GCFuncs *wrapFuncs;
+ GCOps *XAAOps;
+ int DashLength;
+ unsigned char* DashPattern;
+ unsigned long changes;
+ unsigned long flags;
+} XAAGCRec, *XAAGCPtr;
+
+#define REDUCIBILITY_CHECKED 0x00000001
+#define REDUCIBLE_TO_8x8 0x00000002
+#define REDUCIBLE_TO_2_COLOR 0x00000004
+#define DIRTY 0x00010000
+#define OFFSCREEN 0x00020000
+#define DGA_PIXMAP 0x00040000
+#define SHARED_PIXMAP 0x00080000
+#define LOCKED_PIXMAP 0x00100000
+
+#define REDUCIBILITY_MASK \
+ (REDUCIBILITY_CHECKED | REDUCIBLE_TO_8x8 | REDUCIBLE_TO_2_COLOR)
+
+typedef struct _XAAPixmap {
+ unsigned long flags;
+ CARD32 pattern0;
+ CARD32 pattern1;
+ int fg;
+ int bg;
+ FBAreaPtr offscreenArea;
+} XAAPixmapRec, *XAAPixmapPtr;
+
+
+Bool
+XAACreateGC(
+ GCPtr pGC
+);
+
+Bool
+XAAInitAccel(
+ ScreenPtr pScreen,
+ XAAInfoRecPtr infoRec
+);
+
+RegionPtr
+XAABitBlt(
+ DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GC *pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty,
+ void (*doBitBlt)(DrawablePtr, DrawablePtr, GCPtr, RegionPtr, DDXPointPtr),
+ unsigned long bitPlane
+);
+
+void
+XAAScreenToScreenBitBlt(
+ ScrnInfoPtr pScrn,
+ int nbox,
+ DDXPointPtr pptSrc,
+ BoxPtr pbox,
+ int xdir,
+ int ydir,
+ int alu,
+ unsigned int planemask
+);
+
+void
+XAADoBitBlt(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc
+);
+
+void
+XAADoImageWrite(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc
+);
+
+void
+XAACopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc
+);
+
+
+RegionPtr
+XAACopyArea(
+ DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GC *pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty
+);
+
+void
+XAAValidateCopyArea(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+void
+XAAValidatePutImage(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+void
+XAAValidateCopyPlane(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+void
+XAAValidatePushPixels(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+void
+XAAValidateFillSpans(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+void
+XAAValidatePolyGlyphBlt(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+void
+XAAValidateImageGlyphBlt(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+void
+XAAValidatePolylines(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+
+RegionPtr
+XAACopyPlaneColorExpansion(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty,
+ unsigned long bitPlane
+);
+
+
+void
+XAAPushPixelsSolidColorExpansion(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDrawable,
+ int dx,
+ int dy,
+ int xOrg,
+ int yOrg
+);
+
+void
+XAAWriteBitmapColorExpandMSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapColorExpand3MSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapColorExpandMSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapColorExpand3MSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapColorExpandLSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapColorExpand3LSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapColorExpandLSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapColorExpand3LSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+
+void
+XAAWriteBitmapScanlineColorExpandMSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapScanlineColorExpand3MSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapScanlineColorExpandMSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapScanlineColorExpand3MSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapScanlineColorExpandLSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapScanlineColorExpand3LSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapScanlineColorExpandLSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapScanlineColorExpand3LSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWritePixmap (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+);
+
+void
+XAAWritePixmapScanline (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+);
+
+typedef void (*ClipAndRenderRectsFunc)(GCPtr, int, BoxPtr, int, int);
+
+
+void
+XAAClipAndRenderRects(
+ GCPtr pGC,
+ ClipAndRenderRectsFunc func,
+ int nrectFill,
+ xRectangle *prectInit,
+ int xorg, int yorg
+);
+
+
+typedef void (*ClipAndRenderSpansFunc)(GCPtr, int, DDXPointPtr, int*,
+ int, int, int);
+
+void
+XAAClipAndRenderSpans(
+ GCPtr pGC,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted,
+ ClipAndRenderSpansFunc func,
+ int xorg,
+ int yorg
+);
+
+
+void
+XAAFillSolidRects(
+ ScrnInfoPtr pScrn,
+ int fg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox
+);
+
+void
+XAAFillMono8x8PatternRects(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int pat0, int pat1,
+ int xorg, int yorg
+);
+
+void
+XAAFillMono8x8PatternRectsScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int pat0, int pat1,
+ int xorg, int yorg
+);
+
+
+void
+XAAFillColor8x8PatternRectsScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorigin, int yorigin,
+ XAACacheInfoPtr pCache
+);
+
+void
+XAAFillColor8x8PatternRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorigin, int yorigin,
+ XAACacheInfoPtr pCache
+);
+
+void
+XAAFillCacheBltRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+);
+
+void
+XAAFillCacheExpandRects(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillImageWriteRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAPolyFillRect(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+);
+
+
+void
+XAATEGlyphRendererMSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRenderer3MSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRendererMSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRenderer3MSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRendererLSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+
+void
+XAATEGlyphRenderer3LSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRendererLSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRenderer3LSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+
+void
+XAATEGlyphRendererScanlineMSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRendererScanline3MSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRendererScanlineLSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRendererScanline3LSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+
+extern CARD32 *(*XAAGlyphScanlineFuncMSBFirstFixedBase[32])(
+ CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
+);
+
+extern CARD32 *(*XAAGlyphScanlineFuncMSBFirst[32])(
+ CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
+);
+
+extern CARD32 *(*XAAGlyphScanlineFuncLSBFirstFixedBase[32])(
+ CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
+);
+
+extern CARD32 *(*XAAGlyphScanlineFuncLSBFirst[32])(
+ CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
+);
+
+void
+XAAFillColorExpandRectsLSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillColorExpandRectsLSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+
+void
+XAAFillColorExpandRectsMSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+
+void
+XAAFillColorExpandRectsMSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+
+
+void
+XAAFillScanlineColorExpandRectsLSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+
+void
+XAAFillScanlineColorExpandRectsMSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+
+void
+XAAFillColorExpandSpansLSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillColorExpandSpansLSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+
+void
+XAAFillColorExpandSpansMSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+
+void
+XAAFillColorExpandSpansMSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+
+void
+XAAFillScanlineColorExpandSpansLSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage
+);
+
+void
+XAAFillScanlineColorExpandSpansMSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+
+extern CARD32 *(*XAAStippleScanlineFuncMSBFirstFixedBase[6])(
+ CARD32* base, CARD32* src, int offset, int width, int dwords
+);
+
+extern CARD32 *(*XAAStippleScanlineFuncMSBFirst[6])(
+ CARD32* base, CARD32* src, int offset, int width, int dwords
+);
+
+extern CARD32 *(*XAAStippleScanlineFuncLSBFirstFixedBase[6])(
+ CARD32* base, CARD32* src, int offset, int width, int dwords
+);
+
+extern CARD32 *(*XAAStippleScanlineFuncLSBFirst[6])(
+ CARD32* base, CARD32* src, int offset, int width, int dwords
+);
+
+int
+XAAPolyText8TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+);
+
+int
+XAAPolyText16TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+);
+
+void
+XAAImageText8TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+);
+
+void
+XAAImageText16TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+);
+
+void
+XAAImageGlyphBltTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+);
+
+void
+XAAPolyGlyphBltTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+);
+
+
+int
+XAAPolyText8NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+);
+
+int
+XAAPolyText16NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+);
+
+void
+XAAImageText8NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+);
+
+void
+XAAImageText16NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+);
+
+void
+XAAImageGlyphBltNonTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+);
+
+void
+XAAPolyGlyphBltNonTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+);
+
+
+void XAANonTEGlyphRenderer(
+ ScrnInfoPtr pScrn,
+ int x, int y, int n,
+ NonTEGlyphPtr glyphs,
+ BoxPtr pbox,
+ int fg, int rop,
+ unsigned int planemask
+);
+
+void
+XAAFillSolidSpans(
+ ScrnInfoPtr pScrn,
+ int fg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted
+);
+
+void
+XAAFillMono8x8PatternSpans(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ int patx, int paty,
+ int xorg, int yorg
+);
+
+void
+XAAFillMono8x8PatternSpansScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ int patx, int paty,
+ int xorg, int yorg
+);
+
+void
+XAAFillColor8x8PatternSpansScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ XAACacheInfoPtr,
+ int xorigin, int yorigin
+);
+
+void
+XAAFillColor8x8PatternSpans(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ XAACacheInfoPtr,
+ int xorigin, int yorigin
+);
+
+void
+XAAFillCacheBltSpans(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr points,
+ int *widths,
+ int fSorted,
+ XAACacheInfoPtr pCache,
+ int xorg, int yorg
+);
+
+void
+XAAFillCacheExpandSpans(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillSpans(
+ DrawablePtr pDrawable,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidth,
+ int fSorted
+);
+
+
+void
+XAAInitPixmapCache(
+ ScreenPtr pScreen,
+ RegionPtr areas,
+ pointer data
+);
+
+void
+XAAWriteBitmapToCache(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int fg, int bg
+);
+
+void
+XAAWriteBitmapToCacheLinear(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int fg, int bg
+);
+
+void
+XAAWritePixmapToCache(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int bpp, int depth
+);
+
+void
+XAAWritePixmapToCacheLinear(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int bpp, int depth
+);
+
+
+void
+XAAPaintWindow(
+ WindowPtr pWin,
+ RegionPtr prgn,
+ int what
+);
+
+void
+XAASolidHorVertLineAsRects(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+);
+
+void
+XAASolidHorVertLineAsTwoPoint(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+);
+
+void
+XAASolidHorVertLineAsBresenham(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+);
+
+
+void
+XAAPolyRectangleThinSolid(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+);
+
+
+void
+XAAPolylinesWideSolid (
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+);
+
+void
+XAAFillPolygonSolid(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+);
+
+void
+XAAFillPolygonStippled(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+);
+
+
+void
+XAAFillPolygonTiled(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+);
+
+
+int
+XAAIsEasyPolygon(
+ DDXPointPtr ptsIn,
+ int count,
+ BoxPtr extents,
+ int origin,
+ DDXPointPtr *topPoint,
+ int *topY, int *bottomY,
+ int shape
+);
+
+void
+XAAFillPolygonHelper(
+ ScrnInfoPtr pScrn,
+ DDXPointPtr ptsIn,
+ int count,
+ DDXPointPtr topPoint,
+ int y,
+ int maxy,
+ int origin,
+ RectFuncPtr RectFunc,
+ TrapFuncPtr TrapFunc,
+ int xorg,
+ int yorg,
+ XAACacheInfoPtr pCache
+);
+
+void
+XAAReadPixmap (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *dst,
+ int dstwidth,
+ int bpp, int depth
+);
+
+void
+XAAPolySegment(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+);
+
+void
+XAAPolyLines(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit
+);
+
+void
+XAAPolySegmentDashed(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+);
+
+void
+XAAPolyLinesDashed(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit
+);
+
+
+void
+XAAWriteMono8x8PatternToCache(ScrnInfoPtr pScrn, XAACacheInfoPtr pCache);
+
+void
+XAAWriteColor8x8PatternToCache(
+ ScrnInfoPtr pScrn,
+ PixmapPtr pPix,
+ XAACacheInfoPtr pCache
+);
+
+void
+XAARotateMonoPattern(
+ int *pat0, int *pat1,
+ int xoffset, int yoffset,
+ Bool msbfirst
+);
+
+void XAAComputeDash(GCPtr pGC);
+
+void XAAMoveDWORDS_FixedBase(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords
+);
+
+void XAAMoveDWORDS(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords
+);
+
+int
+XAAGetRectClipBoxes(
+ RegionPtr prgnClip,
+ BoxPtr pboxClippedBase,
+ int nrectFill,
+ xRectangle *prectInit
+);
+
+void
+XAACopyWindow8_32(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc
+);
+
+void
+XAAPaintWindow8_32(
+ WindowPtr pWin,
+ RegionPtr prgn,
+ int what
+);
+
+void
+XAAWindowExposures8_32(
+ WindowPtr pWin,
+ RegionPtr pReg,
+ RegionPtr pOtherReg
+);
+
+void
+XAAPolyFillArcSolid(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs);
+
+XAACacheInfoPtr
+XAACacheTile(ScrnInfoPtr Scrn, PixmapPtr pPix);
+
+XAACacheInfoPtr
+XAACacheMonoStipple(ScrnInfoPtr Scrn, PixmapPtr pPix);
+
+XAACacheInfoPtr
+XAACachePlanarMonoStipple(ScrnInfoPtr Scrn, PixmapPtr pPix);
+
+XAACacheInfoPtr
+XAACacheStipple(ScrnInfoPtr Scrn, PixmapPtr pPix, int fg, int bg);
+
+XAACacheInfoPtr
+XAACacheMono8x8Pattern(ScrnInfoPtr Scrn, int pat0, int pat1);
+
+XAACacheInfoPtr
+XAACacheColor8x8Pattern(ScrnInfoPtr Scrn, PixmapPtr pPix, int fg, int bg);
+
+
+void XAAClosePixmapCache(ScreenPtr pScreen);
+void XAAInvalidatePixmapCache(ScreenPtr pScreen);
+
+Bool XAACheckStippleReducibility(PixmapPtr pPixmap);
+Bool XAACheckTileReducibility(PixmapPtr pPixmap, Bool checkMono);
+
+int XAAStippledFillChooser(GCPtr pGC);
+int XAAOpaqueStippledFillChooser(GCPtr pGC);
+int XAATiledFillChooser(GCPtr pGC);
+
+void XAAMoveInOffscreenPixmaps(ScreenPtr pScreen);
+void XAAMoveOutOffscreenPixmaps(ScreenPtr pScreen);
+void XAARemoveAreaCallback(FBAreaPtr area);
+void XAAMoveOutOffscreenPixmap(PixmapPtr pPix);
+
+extern GCOps XAAFallbackOps;
+extern GCFuncs XAAGCFuncs;
+extern int XAAScreenIndex;
+extern int XAAGCIndex;
+extern int XAAPixmapIndex;
+
+extern unsigned int XAAShiftMasks[32];
+
+extern unsigned int byte_expand3[256], byte_reversed_expand3[256];
+
+CARD32 XAAReverseBitOrder(CARD32 data);
+
+#define GET_XAASCREENPTR_FROM_SCREEN(pScreen)\
+ (pScreen)->devPrivates[XAAScreenIndex].ptr
+
+#define GET_XAASCREENPTR_FROM_GC(pGC)\
+ (pGC)->pScreen->devPrivates[XAAScreenIndex].ptr
+
+#define GET_XAASCREENPTR_FROM_DRAWABLE(pDraw)\
+ (pDraw)->pScreen->devPrivates[XAAScreenIndex].ptr
+
+#define GET_XAAINFORECPTR_FROM_SCREEN(pScreen)\
+ ((XAAScreenPtr)((pScreen)->devPrivates[XAAScreenIndex].ptr))->AccelInfoRec
+
+#define GET_XAAINFORECPTR_FROM_GC(pGC)\
+((XAAScreenPtr)((pGC)->pScreen->devPrivates[XAAScreenIndex].ptr))->AccelInfoRec
+
+#define GET_XAAINFORECPTR_FROM_DRAWABLE(pDraw)\
+((XAAScreenPtr)((pDraw)->pScreen->devPrivates[XAAScreenIndex].ptr))->AccelInfoRec
+
+#define GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn)\
+((XAAScreenPtr)((pScrn)->pScreen->devPrivates[XAAScreenIndex].ptr))->AccelInfoRec
+
+#define XAA_GET_PIXMAP_PRIVATE(pix)\
+ (XAAPixmapPtr)((pix)->devPrivates[XAAPixmapIndex].ptr)
+
+#define SET_SYNC_FLAG(infoRec) infoRec->NeedToSync = TRUE
+
+#define CHECK_RGB_EQUAL(c) (!((((c) >> 8) ^ (c)) & 0xffff))
+
+#define CHECK_FG(pGC, flags) \
+ (!(flags & RGB_EQUAL) || CHECK_RGB_EQUAL(pGC->fgPixel))
+
+#define CHECK_BG(pGC, flags) \
+ (!(flags & RGB_EQUAL) || CHECK_RGB_EQUAL(pGC->bgPixel))
+
+#define CHECK_ROP(pGC, flags) \
+ (!(flags & GXCOPY_ONLY) || (pGC->alu == GXcopy))
+
+#define CHECK_ROPSRC(pGC, flags) \
+ (!(flags & ROP_NEEDS_SOURCE) || ((pGC->alu != GXclear) && \
+ (pGC->alu != GXnoop) && (pGC->alu != GXinvert) && \
+ (pGC->alu != GXset)))
+
+#define CHECK_PLANEMASK(pGC, flags) \
+ (!(flags & NO_PLANEMASK) || \
+ ((pGC->planemask & infoRec->FullPlanemask) == infoRec->FullPlanemask))
+
+#define CHECK_COLORS(pGC, flags) \
+ (!(flags & RGB_EQUAL) || \
+ (CHECK_RGB_EQUAL(pGC->fgPixel) && CHECK_RGB_EQUAL(pGC->bgPixel)))
+
+#define CHECK_NO_GXCOPY(pGC, flags) \
+ ((pGC->alu != GXcopy) || !(flags & NO_GXCOPY) || \
+ ((pGC->planemask & infoRec->FullPlanemask) != infoRec->FullPlanemask))
+
+#define IS_OFFSCREEN_PIXMAP(pPix)\
+ ((XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pPix)))->offscreenArea)
+
+#define PIXMAP_IS_SHARED(pPix)\
+ ((XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pPix)))->flags & SHARED_PIXMAP)
+
+#define OFFSCREEN_PIXMAP_LOCKED(pPix)\
+ ((XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pPix)))->flags & LOCKED_PIXMAP)
+
+#define DELIST_OFFSCREEN_PIXMAP(pPix) { \
+ PixmapLinkPtr _pLink, _prev; \
+ _pLink = infoRec->OffscreenPixmaps; \
+ _prev = NULL; \
+ while(_pLink) { \
+ if(_pLink->pPix == pPix) { \
+ if(_prev) _prev->next = _pLink->next; \
+ else infoRec->OffscreenPixmaps = _pLink->next; \
+ xfree(_pLink); \
+ break; \
+ } \
+ _prev = _pLink; \
+ _pLink = _pLink->next; \
+ }}
+
+
+
+/*
+ * Moved XAAPixmapCachePrivate here from xaaPCache.c, since driver
+ * replacements for CacheMonoStipple need access to it
+ */
+
+typedef struct {
+ int Num512x512;
+ int Current512;
+ XAACacheInfoPtr Info512;
+ int Num256x256;
+ int Current256;
+ XAACacheInfoPtr Info256;
+ int Num128x128;
+ int Current128;
+ XAACacheInfoPtr Info128;
+ int NumMono;
+ int CurrentMono;
+ XAACacheInfoPtr InfoMono;
+ int NumColor;
+ int CurrentColor;
+ XAACacheInfoPtr InfoColor;
+ int NumPartial;
+ int CurrentPartial;
+ XAACacheInfoPtr InfoPartial;
+ DDXPointRec MonoOffsets[64];
+ DDXPointRec ColorOffsets[64];
+} XAAPixmapCachePrivate, *XAAPixmapCachePrivatePtr;
+
+
+#endif /* _XAALOCAL_H */
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaarop.h b/xc/programs/Xserver/hw/xfree86/xaa/xaarop.h
new file mode 100644
index 000000000..8fee07533
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaarop.h
@@ -0,0 +1,307 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaarop.h,v 1.1 1999/03/21 07:35:31 dawes Exp $ */
+
+/*
+
+ int XAAHelpSolidROP(ScrnInfoPtr pScrn, int *fg, int pm, int *rop)
+
+ For use with solid fills emulated by solid 8x8 patterns. You
+ give it the foreground, planemask and X rop and it will replace
+ the foreground with a new one and the rop with the appropriate
+ MS triadic raster op. The function will return which components
+ (S-P) need to be enabled.
+
+
+ int XAAHelpPatternROP(ScrnInfoPtr pScrn, int *fg, int *bg, int pm, int *rop)
+
+ For use with 8x8 opaque pattern fills. You give it the foreground,
+ and background, planemask and X rop and it will replace the
+ foreground and background with new ones and the rop with the
+ appropriate MS triadic raster op. The function will return which
+ components (S-P) need to be enabled.
+
+
+ ROP_PAT - Means to enable 8x8 mono patterns (all bits
+ set for solid patterns). Set the foreground and
+ background as returned by the function.
+
+ ROP_SRC - Means a source of color == planemask should be used.
+
+
+*/
+
+#ifndef _XAAROP_H
+#define _XAAROP_H
+
+#define ROP_DST 0x00000001
+#define ROP_SRC 0x00000002
+#define ROP_PAT 0x00000004
+
+#define ROP_0 0x00
+#define ROP_DPSoon 0x01
+#define ROP_DPSona 0x02
+#define ROP_PSon 0x03
+#define ROP_SDPona 0x04
+#define ROP_DPon 0x05
+#define ROP_PDSxnon 0x06
+#define ROP_PDSaon 0x07
+#define ROP_SDPnaa 0x08
+#define ROP_PDSxon 0x09
+#define ROP_DPna 0x0A
+#define ROP_PSDnaon 0x0B
+#define ROP_SPna 0x0C
+#define ROP_PDSnaon 0x0D
+#define ROP_PDSonon 0x0E
+#define ROP_Pn 0x0F
+#define ROP_PDSona 0x10
+#define ROP_DSon 0x11
+#define ROP_SDPxnon 0x12
+#define ROP_SDPaon 0x13
+#define ROP_DPSxnon 0x14
+#define ROP_DPSaon 0x15
+#define ROP_PSDPSanaxx 0x16
+#define ROP_SSPxDSxaxn 0x17
+#define ROP_SPxPDxa 0x18
+#define ROP_SDPSanaxn 0x19
+#define ROP_PDSPaox 0x1A
+#define ROP_SDPSxaxn 0x1B
+#define ROP_PSDPaox 0x1C
+#define ROP_DSPDxaxn 0x1D
+#define ROP_PDSox 0x1E
+#define ROP_PDSoan 0x1F
+#define ROP_DPSnaa 0x20
+#define ROP_SDPxon 0x21
+#define ROP_DSna 0x22
+#define ROP_SPDnaon 0x23
+#define ROP_SPxDSxa 0x24
+#define ROP_PDSPanaxn 0x25
+#define ROP_SDPSaox 0x26
+#define ROP_SDPSxnox 0x27
+#define ROP_DPSxa 0x28
+#define ROP_PSDPSaoxxn 0x29
+#define ROP_DPSana 0x2A
+#define ROP_SSPxPDxaxn 0x2B
+#define ROP_SPDSoax 0x2C
+#define ROP_PSDnox 0x2D
+#define ROP_PSDPxox 0x2E
+#define ROP_PSDnoan 0x2F
+#define ROP_PSna 0x30
+#define ROP_SDPnaon 0x31
+#define ROP_SDPSoox 0x32
+#define ROP_Sn 0x33
+#define ROP_SPDSaox 0x34
+#define ROP_SPDSxnox 0x35
+#define ROP_SDPox 0x36
+#define ROP_SDPoan 0x37
+#define ROP_PSDPoax 0x38
+#define ROP_SPDnox 0x39
+#define ROP_SPDSxox 0x3A
+#define ROP_SPDnoan 0x3B
+#define ROP_PSx 0x3C
+#define ROP_SPDSonox 0x3D
+#define ROP_SPDSnaox 0x3E
+#define ROP_PSan 0x3F
+#define ROP_PSDnaa 0x40
+#define ROP_DPSxon 0x41
+#define ROP_SDxPDxa 0x42
+#define ROP_SPDSanaxn 0x43
+#define ROP_SDna 0x44
+#define ROP_DPSnaon 0x45
+#define ROP_DSPDaox 0x46
+#define ROP_PSDPxaxn 0x47
+#define ROP_SDPxa 0x48
+#define ROP_PDSPDaoxxn 0x49
+#define ROP_DPSDoax 0x4A
+#define ROP_PDSnox 0x4B
+#define ROP_SDPana 0x4C
+#define ROP_SSPxDSxoxn 0x4D
+#define ROP_PDSPxox 0x4E
+#define ROP_PDSnoan 0x4F
+#define ROP_PDna 0x50
+#define ROP_DSPnaon 0x51
+#define ROP_DPSDaox 0x52
+#define ROP_SPDSxaxn 0x53
+#define ROP_DPSonon 0x54
+#define ROP_Dn 0x55
+#define ROP_DPSox 0x56
+#define ROP_DPSoan 0x57
+#define ROP_PDSPoax 0x58
+#define ROP_DPSnox 0x59
+#define ROP_DPx 0x5A
+#define ROP_DPSDonox 0x5B
+#define ROP_DPSDxox 0x5C
+#define ROP_DPSnoan 0x5D
+#define ROP_DPSDnaox 0x5E
+#define ROP_DPan 0x5F
+#define ROP_PDSxa 0x60
+#define ROP_DSPDSaoxxn 0x61
+#define ROP_DSPDoax 0x62
+#define ROP_SDPnox 0x63
+#define ROP_SDPSoax 0x64
+#define ROP_DSPnox 0x65
+#define ROP_DSx 0x66
+#define ROP_SDPSonox 0x67
+#define ROP_DSPDSonoxxn 0x68
+#define ROP_PDSxxn 0x69
+#define ROP_DPSax 0x6A
+#define ROP_PSDPSoaxxn 0x6B
+#define ROP_SDPax 0x6C
+#define ROP_PDSPDoaxxn 0x6D
+#define ROP_SDPSnoax 0x6E
+#define ROP_PDSxnan 0x6F
+#define ROP_PDSana 0x70
+#define ROP_SSDxPDxaxn 0x71
+#define ROP_SDPSxox 0x72
+#define ROP_SDPnoan 0x73
+#define ROP_DSPDxox 0x74
+#define ROP_DSPnoan 0x75
+#define ROP_SDPSnaox 0x76
+#define ROP_DSan 0x77
+#define ROP_PDSax 0x78
+#define ROP_DSPDSoaxxn 0x79
+#define ROP_DPSDnoax 0x7A
+#define ROP_SDPxnan 0x7B
+#define ROP_SPDSnoax 0x7C
+#define ROP_DPSxnan 0x7D
+#define ROP_SPxDSxo 0x7E
+#define ROP_DPSaan 0x7F
+#define ROP_DPSaa 0x80
+#define ROP_SPxDSxon 0x81
+#define ROP_DPSxna 0x82
+#define ROP_SPDSnoaxn 0x83
+#define ROP_SDPxna 0x84
+#define ROP_PDSPnoaxn 0x85
+#define ROP_DSPDSoaxx 0x86
+#define ROP_PDSaxn 0x87
+#define ROP_DSa 0x88
+#define ROP_SDPSnaoxn 0x89
+#define ROP_DSPnoa 0x8A
+#define ROP_DSPDxoxn 0x8B
+#define ROP_SDPnoa 0x8C
+#define ROP_SDPSxoxn 0x8D
+#define ROP_SSDxPDxax 0x8E
+#define ROP_PDSanan 0x8F
+#define ROP_PDSxna 0x90
+#define ROP_SDPSnoaxn 0x91
+#define ROP_DPSDPoaxx 0x92
+#define ROP_SPDaxn 0x93
+#define ROP_PSDPSoaxx 0x94
+#define ROP_DPSaxn 0x95
+#define ROP_DPSxx 0x96
+#define ROP_PSDPSonoxx 0x97
+#define ROP_SDPSonoxn 0x98
+#define ROP_DSxn 0x99
+#define ROP_DPSnax 0x9A
+#define ROP_SDPSoaxn 0x9B
+#define ROP_SPDnax 0x9C
+#define ROP_DSPDoaxn 0x9D
+#define ROP_DSPDSaoxx 0x9E
+#define ROP_PDSxan 0x9F
+#define ROP_DPa 0xA0
+#define ROP_PDSPnaoxn 0xA1
+#define ROP_DPSnoa 0xA2
+#define ROP_DPSDxoxn 0xA3
+#define ROP_PDSPonoxn 0xA4
+#define ROP_PDxn 0xA5
+#define ROP_DSPnax 0xA6
+#define ROP_PDSPoaxn 0xA7
+#define ROP_DPSoa 0xA8
+#define ROP_DPSoxn 0xA9
+#define ROP_D 0xAA
+#define ROP_DPSono 0xAB
+#define ROP_SPDSxax 0xAC
+#define ROP_DPSDaoxn 0xAD
+#define ROP_DSPnao 0xAE
+#define ROP_DPno 0xAF
+#define ROP_PDSnoa 0xB0
+#define ROP_PDSPxoxn 0xB1
+#define ROP_SSPxDSxox 0xB2
+#define ROP_SDPanan 0xB3
+#define ROP_PSDnax 0xB4
+#define ROP_DPSDoaxn 0xB5
+#define ROP_DPSDPaoxx 0xB6
+#define ROP_SDPxan 0xB7
+#define ROP_PSDPxax 0xB8
+#define ROP_DSPDaoxn 0xB9
+#define ROP_DPSnao 0xBA
+#define ROP_DSno 0xBB
+#define ROP_SPDSanax 0xBC
+#define ROP_SDxPDxan 0xBD
+#define ROP_DPSxo 0xBE
+#define ROP_DPSano 0xBF
+#define ROP_Psa 0xC0
+#define ROP_SPDSnaoxn 0xC1
+#define ROP_SPDSonoxn 0xC2
+#define ROP_PSxn 0xC3
+#define ROP_SPDnoa 0xC4
+#define ROP_SPDSxoxn 0xC5
+#define ROP_SDPnax 0xC6
+#define ROP_PSDPoaxn 0xC7
+#define ROP_SDPoa 0xC8
+#define ROP_SPDoxn 0xC9
+#define ROP_DPSDxax 0xCA
+#define ROP_SPDSaoxn 0xCB
+#define ROP_S 0xCC
+#define ROP_SDPono 0xCD
+#define ROP_SDPnao 0xCE
+#define ROP_SPno 0xCF
+#define ROP_PSDnoa 0xD0
+#define ROP_PSDPxoxn 0xD1
+#define ROP_PDSnax 0xD2
+#define ROP_SPDSoaxn 0xD3
+#define ROP_SSPxPDxax 0xD4
+#define ROP_DPSanan 0xD5
+#define ROP_PSDPSaoxx 0xD6
+#define ROP_DPSxan 0xD7
+#define ROP_PDSPxax 0xD8
+#define ROP_SDPSaoxn 0xD9
+#define ROP_DPSDanax 0xDA
+#define ROP_SPxDSxan 0xDB
+#define ROP_SPDnao 0xDC
+#define ROP_SDno 0xDD
+#define ROP_SDPxo 0xDE
+#define ROP_SDPano 0xDF
+#define ROP_PDSoa 0xE0
+#define ROP_PDSoxn 0xE1
+#define ROP_DSPDxax 0xE2
+#define ROP_PSDPaoxn 0xE3
+#define ROP_SDPSxax 0xE4
+#define ROP_PDSPaoxn 0xE5
+#define ROP_SDPSanax 0xE6
+#define ROP_SPxPDxan 0xE7
+#define ROP_SSPxDSxax 0xE8
+#define ROP_DSPDSanaxxn 0xE9
+#define ROP_DPSao 0xEA
+#define ROP_DPSxno 0xEB
+#define ROP_SDPao 0xEC
+#define ROP_SDPxno 0xED
+#define ROP_DSo 0xEE
+#define ROP_SDPnoo 0xEF
+#define ROP_P 0xF0
+#define ROP_PDSono 0xF1
+#define ROP_PDSnao 0xF2
+#define ROP_PSno 0xF3
+#define ROP_PSDnao 0xF4
+#define ROP_PDno 0xF5
+#define ROP_PDSxo 0xF6
+#define ROP_PDSano 0xF7
+#define ROP_PDSao 0xF8
+#define ROP_PDSxno 0xF9
+#define ROP_DPo 0xFA
+#define ROP_DPSnoo 0xFB
+#define ROP_PSo 0xFC
+#define ROP_PSDnoo 0xFD
+#define ROP_DPSoo 0xFE
+#define ROP_1 0xFF
+
+#define NO_SRC_ROP(rop) \
+ ((rop == GXnoop) || (rop == GXset) || (rop == GXclear) || (rop == GXinvert))
+
+int XAAHelpSolidROP(ScrnInfoPtr pScrn, int *fg, int pm, int *rop);
+int XAAHelpPatternROP(ScrnInfoPtr pScrn, int *fg, int *bg, int pm, int *rop);
+
+extern int XAACopyROP[16];
+extern int XAACopyROP_PM[16];
+extern int XAAPatternROP[16];
+extern int XAAPatternROP_PM[16];
+
+#endif /* _XAAROP_H */
diff --git a/xc/programs/Xserver/hw/xfree86/xaa/xaawrap.h b/xc/programs/Xserver/hw/xfree86/xaa/xaawrap.h
new file mode 100644
index 000000000..872b6560f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xaa/xaawrap.h
@@ -0,0 +1,71 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaawrap.h,v 1.4 1999/05/30 03:03:34 dawes Exp $ */
+
+#define XAA_SCREEN_PROLOGUE(pScreen, field)\
+ ((pScreen)->field = \
+ ((XAAScreenPtr) (pScreen)->devPrivates[XAAScreenIndex].ptr)->field)
+
+#define XAA_SCREEN_EPILOGUE(pScreen, field, wrapper)\
+ ((pScreen)->field = wrapper)
+
+
+#define XAA_GC_FUNC_PROLOGUE(pGC)\
+ XAAGCPtr pGCPriv = (XAAGCPtr) (pGC)->devPrivates[XAAGCIndex].ptr;\
+ (pGC)->funcs = pGCPriv->wrapFuncs;\
+ if(pGCPriv->flags)\
+ (pGC)->ops = pGCPriv->wrapOps
+
+#define XAA_GC_FUNC_EPILOGUE(pGC)\
+ pGCPriv->wrapFuncs = (pGC)->funcs;\
+ (pGC)->funcs = &XAAGCFuncs;\
+ if(pGCPriv->flags) {\
+ pGCPriv->wrapOps = (pGC)->ops;\
+ (pGC)->ops = (pGCPriv->flags & OPS_ARE_ACCEL) ? pGCPriv->XAAOps :\
+ &XAAPixmapOps;\
+ }
+
+
+#define XAA_GC_OP_PROLOGUE(pGC)\
+ XAAGCPtr pGCPriv = (XAAGCPtr)(pGC->devPrivates[XAAGCIndex].ptr);\
+ GCFuncs *oldFuncs = pGC->funcs;\
+ pGC->funcs = pGCPriv->wrapFuncs;\
+ pGC->ops = pGCPriv->wrapOps
+
+#define XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC)\
+ XAAGCPtr pGCPriv = (XAAGCPtr)(pGC->devPrivates[XAAGCIndex].ptr);\
+ GCFuncs *oldFuncs = pGC->funcs;\
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip)) return; \
+ pGC->funcs = pGCPriv->wrapFuncs;\
+ pGC->ops = pGCPriv->wrapOps
+
+
+#define XAA_GC_OP_EPILOGUE(pGC)\
+ pGCPriv->wrapOps = pGC->ops;\
+ pGC->funcs = oldFuncs;\
+ pGC->ops = pGCPriv->XAAOps
+
+
+#define XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw)\
+ XAAGCPtr pGCPriv = (XAAGCPtr)(pGC->devPrivates[XAAGCIndex].ptr);\
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDraw));\
+ GCFuncs *oldFuncs = pGC->funcs;\
+ pGC->funcs = pGCPriv->wrapFuncs;\
+ pGC->ops = pGCPriv->wrapOps
+
+
+#define XAA_PIXMAP_OP_EPILOGUE(pGC)\
+ pGCPriv->wrapOps = pGC->ops;\
+ pGC->funcs = oldFuncs;\
+ pGC->ops = &XAAPixmapOps;\
+ pixPriv->flags |= DIRTY
+
+
+
+/* This also works fine for drawables */
+
+#define SYNC_CHECK(pGC) {\
+ XAAInfoRecPtr infoRec =\
+((XAAScreenPtr)((pGC)->pScreen->devPrivates[XAAScreenIndex].ptr))->AccelInfoRec;\
+ if(infoRec->NeedToSync) {\
+ (*infoRec->Sync)(infoRec->pScrn);\
+ infoRec->NeedToSync = FALSE;\
+ }}
diff --git a/xc/programs/Xserver/hw/xfree86/xf1bpp/Imakefile b/xc/programs/Xserver/hw/xfree86/xf1bpp/Imakefile
new file mode 100644
index 000000000..e3e203259
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf1bpp/Imakefile
@@ -0,0 +1,120 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/xf1bpp/Imakefile,v 1.5 1999/08/14 10:50:15 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#if DoLoadableServer
+XF86INCL = -I$(XF86COMSRC) -I$(XF86SRC)
+XFMODSRC = mfbmodule.c
+XFMODOBJ = mfbmodule.o
+#endif
+
+SRCS1 = mfbgc.c mfbwindow.c mfbfont.c \
+ mfbfillrct.c mfbpntwin.c maskbits.c mfbpixmap.c \
+ mfbimage.c mfbline.c mfbbres.c mfbhrzvert.c mfbbresd.c \
+ mfbpushpxl.c mfbzerarc.c mfbfillarc.c \
+ mfbfillsp.c mfbsetsp.c mfbscrinit.c mfbscrclse.c mfbclip.c \
+ mfbbitblt.c mfbgetsp.c mfbpolypnt.c \
+ mfbbltC.c mfbbltX.c mfbbltCI.c mfbbltO.c mfbbltG.c \
+ mfbcmap.c mfbtileC.c mfbtileG.c mfbmisc.c mfbbstore.c $(XFMODSRC)
+
+SRCS = $(SRCS1) mfbseg.c mfbpgbwht.c mfbpgbblak.c mfbpgbinv.c mfbigbwht.c \
+ mfbigbblak.c mfbpawhite.c mfbpablack.c mfbpainv.c mfbtewhite.c \
+ mfbteblack.c mfbbltC.c mfbbltX.c mfbbltCI.c mfbbltO.c mfbbltG.c \
+ mfbtileC.c mfbtileG.c mfbplywhite.c mfbplyblack.c mfbplyinv.c
+
+OBJS = mfbgc.o mfbwindow.o mfbfont.o \
+ mfbfillrct.o mfbpntwin.o maskbits.o mfbpixmap.o \
+ mfbimage.o mfbline.o mfbbres.o mfbhrzvert.o mfbbresd.o mfbseg.o \
+ mfbpushpxl.o mfbzerarc.o mfbfillarc.o \
+ mfbfillsp.o mfbsetsp.o mfbscrinit.o mfbscrclse.o mfbclip.o \
+ mfbbitblt.o mfbgetsp.o mfbpolypnt.o \
+ mfbbltC.o mfbbltX.o mfbbltCI.o mfbbltO.o mfbbltG.o \
+ mfbpgbwht.o mfbpgbblak.o mfbpgbinv.o \
+ mfbigbwht.o mfbigbblak.o mfbcmap.o \
+ mfbpawhite.o mfbpablack.o mfbpainv.o mfbtileC.o mfbtileG.o \
+ mfbtewhite.o mfbteblack.o mfbmisc.o mfbbstore.o \
+ mfbplywhite.o mfbplyblack.o mfbplyinv.o $(XFMODOBJ)
+
+INCLUDES = -I. -I$(SERVERSRC)/mfb -I$(SERVERSRC)/mi -I$(SERVERSRC)/include \
+ -I$(XINCLUDESRC) -I$(FONTINCSRC) $(XF86INCL)
+LINTDEFS = -DMFBPOLYGLYPHBLT=mfbPolyGlyphBltWhite \
+ -DMFBIMAGEGLYPHBLT=mfbImageGlyphBltWhite \
+ -DEQWHOLEWORD=\=\~0 -DOPEQ=\|=
+LINTLIBS = $(SERVERSRC)/dix/llib-ldix.ln $(SERVERSRC)/os/llib-los.ln \
+ $(SERVERSRC)/mi/llib-lmi.ln
+
+DEFINES = -DXF86MONO
+
+ModuleObjectRule()
+LibraryModuleTarget(xf1bpp,$(OBJS))
+LintLibraryTarget(xf1bpp,$(SRCS1))
+NormalLintTarget($(LINTDEFS) $(SRCS1))
+
+ObjectMapIncludeFromSpecialSource(maskbits,$(SERVERSRC)/mfb/maskbits,/**/)
+ObjectMapIncludeFromSpecialSource(mfbbitblt,$(SERVERSRC)/mfb/mfbbitblt,/**/)
+ObjectMapIncludeFromSpecialSource(mfbblt,$(SERVERSRC)/mfb/mfbblt,/**/)
+ObjectMapIncludeFromSpecialSource(mfbbres,$(SERVERSRC)/mfb/mfbbres,/**/)
+ObjectMapIncludeFromSpecialSource(mfbbresd,$(SERVERSRC)/mfb/mfbbresd,/**/)
+ObjectMapIncludeFromSpecialSource(mfbbstore,$(SERVERSRC)/mfb/mfbbstore,/**/)
+ObjectMapIncludeFromSpecialSource(mfbclip,$(SERVERSRC)/mfb/mfbclip,/**/)
+ObjectMapIncludeFromSpecialSource(mfbcmap,$(SERVERSRC)/mfb/mfbcmap,/**/)
+ObjectMapIncludeFromSpecialSource(mfbfillarc,$(SERVERSRC)/mfb/mfbfillarc,/**/)
+ObjectMapIncludeFromSpecialSource(mfbfillrct,$(SERVERSRC)/mfb/mfbfillrct,/**/)
+ObjectMapIncludeFromSpecialSource(mfbfillsp,$(SERVERSRC)/mfb/mfbfillsp,/**/)
+ObjectMapIncludeFromSpecialSource(mfbfont,$(SERVERSRC)/mfb/mfbfont,/**/)
+ObjectMapIncludeFromSpecialSource(mfbgc,$(SERVERSRC)/mfb/mfbgc,/**/)
+ObjectMapIncludeFromSpecialSource(mfbgetsp,$(SERVERSRC)/mfb/mfbgetsp,/**/)
+ObjectMapIncludeFromSpecialSource(mfbhrzvert,$(SERVERSRC)/mfb/mfbhrzvert,/**/)
+ObjectMapIncludeFromSpecialSource(mfbimage,$(SERVERSRC)/mfb/mfbimage,/**/)
+ObjectMapIncludeFromSpecialSource(mfbimggblt,$(SERVERSRC)/mfb/mfbimggblt,/**/)
+ObjectMapIncludeFromSpecialSource(mfbline,$(SERVERSRC)/mfb/mfbline,/**/)
+ObjectMapIncludeFromSpecialSource(mfbmisc,$(SERVERSRC)/mfb/mfbmisc,/**/)
+ObjectMapIncludeFromSpecialSource(mfbpixmap,$(SERVERSRC)/mfb/mfbpixmap,/**/)
+ObjectMapIncludeFromSpecialSource(mfbply1rct,$(SERVERSRC)/mfb/mfbply1rct,/**/)
+ObjectMapIncludeFromSpecialSource(mfbplygblt,$(SERVERSRC)/mfb/mfbplygblt,/**/)
+ObjectMapIncludeFromSpecialSource(mfbpntarea,$(SERVERSRC)/mfb/mfbpntarea,/**/)
+ObjectMapIncludeFromSpecialSource(mfbpntwin,$(SERVERSRC)/mfb/mfbpntwin,/**/)
+ObjectMapIncludeFromSpecialSource(mfbpolypnt,$(SERVERSRC)/mfb/mfbpolypnt,/**/)
+ObjectMapIncludeFromSpecialSource(mfbpushpxl,$(SERVERSRC)/mfb/mfbpushpxl,/**/)
+ObjectMapIncludeFromSpecialSource(mfbscrclse,$(SERVERSRC)/mfb/mfbscrclse,/**/)
+ObjectMapIncludeFromSpecialSource(mfbscrinit,$(SERVERSRC)/mfb/mfbscrinit,/**/)
+ObjectMapIncludeFromSpecialSource(mfbsetsp,$(SERVERSRC)/mfb/mfbsetsp,/**/)
+ObjectMapIncludeFromSpecialSource(mfbtegblt,$(SERVERSRC)/mfb/mfbtegblt,/**/)
+ObjectMapIncludeFromSpecialSource(mfbtile,$(SERVERSRC)/mfb/mfbtile,/**/)
+ObjectMapIncludeFromSpecialSource(mfbwindow,$(SERVERSRC)/mfb/mfbwindow,/**/)
+ObjectMapIncludeFromSpecialSource(mfbzerarc,$(SERVERSRC)/mfb/mfbzerarc,/**/)
+
+ObjectFromSpecialSource(mfbseg,mfbline,-DPOLYSEGMENT)
+ObjectFromSpecialSource(mfbpgbwht,mfbplygblt,-DMFBPOLYGLYPHBLT=mfbPolyGlyphBltWhite -DOPEQ=\|=)
+ObjectFromSpecialSource(mfbpgbblak,mfbplygblt,-DMFBPOLYGLYPHBLT=mfbPolyGlyphBltBlack -DOPEQ=\&=\~)
+ObjectFromSpecialSource(mfbpgbinv,mfbplygblt,-DMFBPOLYGLYPHBLT=mfbPolyGlyphBltInvert -DOPEQ=\^=)
+ObjectFromSpecialSource(mfbigbwht,mfbimggblt,-DMFBIMAGEGLYPHBLT=mfbImageGlyphBltWhite -DOPEQ=\|=)
+ObjectFromSpecialSource(mfbigbblak,mfbimggblt,-DMFBIMAGEGLYPHBLT=mfbImageGlyphBltBlack -DOPEQ=\&=\~)
+ObjectFromSpecialSource(mfbpawhite,mfbpntarea,-DMFBSOLIDFILLAREA=mfbSolidWhiteArea -DMFBSTIPPLEFILLAREA=mfbStippleWhiteArea -DOPEQ=\|= -DEQWHOLEWORD=\=\~0)
+ObjectFromSpecialSource(mfbpablack,mfbpntarea,-DMFBSOLIDFILLAREA=mfbSolidBlackArea -DMFBSTIPPLEFILLAREA=mfbStippleBlackArea -DOPEQ=\&=\~ -DEQWHOLEWORD=\=0)
+ObjectFromSpecialSource(mfbpainv,mfbpntarea,-DMFBSOLIDFILLAREA=mfbSolidInvertArea -DMFBSTIPPLEFILLAREA=mfbStippleInvertArea -DOPEQ=\^= -DEQWHOLEWORD=\^=\~0)
+ObjectFromSpecialSource(mfbtewhite,mfbtegblt,-DMFBTEGLYPHBLT=mfbTEGlyphBltWhite -DOP= -DCLIPTETEXT=mfbImageGlyphBltWhite)
+ObjectFromSpecialSource(mfbteblack,mfbtegblt,-DMFBTEGLYPHBLT=mfbTEGlyphBltBlack -DOP=\~ -DCLIPTETEXT=mfbImageGlyphBltBlack)
+ObjectFromSpecialSource(mfbplywhite,mfbply1rct,-DMFBFILLPOLY1RECT=mfbFillPolyWhite -DOPEQ=\|= -DEQWHOLEWORD=\=\~0)
+ObjectFromSpecialSource(mfbplyblack,mfbply1rct,-DMFBFILLPOLY1RECT=mfbFillPolyBlack -DOPEQ=\&=\~ -DEQWHOLEWORD=\=0)
+ObjectFromSpecialSource(mfbplyinv,mfbply1rct,-DMFBFILLPOLY1RECT=mfbFillPolyInvert -DOPEQ=\^= -DEQWHOLEWORD=\^=\~0)
+ObjectFromSpecialSource(mfbbltC,mfbblt,-DMROP=Mcopy)
+ObjectFromSpecialSource(mfbbltX,mfbblt,-DMROP=Mxor)
+ObjectFromSpecialSource(mfbbltCI,mfbblt,-DMROP=McopyInverted)
+ObjectFromSpecialSource(mfbbltO,mfbblt,'-DMROP=Mor')
+ObjectFromSpecialSource(mfbbltG,mfbblt,-DMROP=0)
+ObjectFromSpecialSource(mfbtileC,mfbtile,-DMROP=Mcopy)
+ObjectFromSpecialSource(mfbtileG,mfbtile,-DMROP=0)
+
+InstallLibraryModule(xf1bpp,$(MODULEDIR),.)
+
+#ifndef OS2Architecture
+DependTarget()
+#endif
+
+InstallDriverSDKLibraryModule(xf1bpp,$(DRIVERSDKMODULEDIR),.)
+
+InstallDriverSDKNonExecFile(mfbmap.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(mfbunmap.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(xf1bpp.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/xc/programs/Xserver/hw/xfree86/xf1bpp/mfbmap.h b/xc/programs/Xserver/hw/xfree86/xf1bpp/mfbmap.h
new file mode 100644
index 000000000..e72fa4316
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf1bpp/mfbmap.h
@@ -0,0 +1,109 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf1bpp/mfbmap.h,v 1.2 1998/07/25 16:59:24 dawes Exp $ */
+
+#ifndef _MFBMAP_H
+#define _MFBMAP_H
+
+#define InverseAlu xf1bppInverseAlu
+#define endtab xf1bppendtab
+#define mask xf1bppmask
+#define mergeRopBits xf1bppmergeRopBits
+#define mfbAllocatePrivates xf1bppAllocatePrivates
+#define mfbBSFuncRec xf1bppBSFuncRec
+#define mfbBlackSolidFS xf1bppBlackSolidFS
+#define mfbBlackStippleFS xf1bppBlackStippleFS
+#define mfbBresD xf1bppBresD
+#define mfbBresS xf1bppBresS
+#define mfbChangeWindowAttributes xf1bppChangeWindowAttributes
+#define mfbCloseScreen xf1bppCloseScreen
+#define mfbCopyArea xf1bppCopyArea
+#define mfbCopyPixmap xf1bppCopyPixmap
+#define mfbCopyPlane xf1bppCopyPlane
+#define mfbCopyRotatePixmap xf1bppCopyRotatePixmap
+#define mfbCopyWindow xf1bppCopyWindow
+#define mfbCreateColormap xf1bppCreateColormap
+#define mfbCreateDefColormap xf1bppCreateDefColormap
+#define mfbCreateGC xf1bppCreateGC
+#define mfbCreatePixmap xf1bppCreatePixmap
+#define mfbCreateWindow xf1bppCreateWindow
+#define mfbDestroyColormap xf1bppDestroyColormap
+#define mfbDestroyPixmap xf1bppDestroyPixmap
+#define mfbDestroyWindow xf1bppDestroyWindow
+#define mfbDoBitblt xf1bppDoBitblt
+#define mfbDoBitbltCopy xf1bppDoBitbltCopy
+#define mfbDoBitbltCopyInverted xf1bppDoBitbltCopyInverted
+#define mfbDoBitbltGeneral xf1bppDoBitbltGeneral
+#define mfbDoBitbltOr xf1bppDoBitbltOr
+#define mfbDoBitbltXor xf1bppDoBitbltXor
+#define mfbFillPolyBlack xf1bppFillPolyBlack
+#define mfbFillPolyInvert xf1bppFillPolyInvert
+#define mfbFillPolyWhite xf1bppFillPolyWhite
+#define mfbGCPrivateIndex xf1bppGCPrivateIndex
+#define mfbGetImage xf1bppGetImage
+#define mfbGetSpans xf1bppGetSpans
+#define mfbGetWindowPixmap xf1bppGetWindowPixmap
+#define mfbHorzS xf1bppHorzS
+#define mfbImageGlyphBltBlack xf1bppImageGlyphBltBlack
+#define mfbImageGlyphBltWhite xf1bppImageGlyphBltWhite
+#define mfbInstallColormap xf1bppInstallColormap
+#define mfbInvertSolidFS xf1bppInvertSolidFS
+#define mfbInvertStippleFS xf1bppInvertStippleFS
+#define mfbLineSD xf1bppLineSD
+#define mfbLineSS xf1bppLineSS
+#define mfbListInstalledColormaps xf1bppListInstalledColormaps
+#define mfbMapWindow xf1bppMapWindow
+#define mfbPadPixmap xf1bppPadPixmap
+#define mfbPaintWindow xf1bppPaintWindow
+#define mfbPixmapToRegion xf1bppPixmapToRegion
+#define mfbPolyFillArcSolid xf1bppPolyFillArcSolid
+#define mfbPolyFillRect xf1bppPolyFillRect
+#define mfbPolyGlyphBltBlack xf1bppPolyGlyphBltBlack
+#define mfbPolyGlyphBltInvert xf1bppPolyGlyphBltInvert
+#define mfbPolyGlyphBltWhite xf1bppPolyGlyphBltWhite
+#define mfbPolyPoint xf1bppPolyPoint
+#define mfbPositionWindow xf1bppPositionWindow
+#define mfbPushPixels xf1bppPushPixels
+#define mfbPutImage xf1bppPutImage
+#define mfbQueryBestSize xf1bppQueryBestSize
+#define mfbRealizeFont xf1bppRealizeFont
+#define mfbReduceRop xf1bppReduceRop
+#define mfbRegisterCopyPlaneProc xf1bppRegisterCopyPlaneProc
+#define mfbResolveColor xf1bppResolveColor
+#define mfbRestoreAreas xf1bppRestoreAreas
+#define mfbSaveAreas xf1bppSaveAreas
+#define mfbScreenInit xf1bppScreenInit
+#define mfbSegmentSD xf1bppSegmentSD
+#define mfbSegmentSS xf1bppSegmentSS
+#define mfbSetScanline xf1bppSetScanline
+#define mfbSetSpans xf1bppSetSpans
+#define mfbSetWindowPixmap xf1bppSetWindowPixmap
+#define mfbSolidBlackArea xf1bppSolidBlackArea
+#define mfbSolidInvertArea xf1bppSolidInvertArea
+#define mfbSolidPP xf1bppSolidPP
+#define mfbSolidWhiteArea xf1bppSolidWhiteArea
+#define mfbStippleBlackArea xf1bppStippleBlackArea
+#define mfbStippleInvertArea xf1bppStippleInvertArea
+#define mfbStippleWhiteArea xf1bppStippleWhiteArea
+#define mfbTEGlyphBltBlack xf1bppTEGlyphBltBlack
+#define mfbTEGlyphBltWhite xf1bppTEGlyphBltWhite
+#define mfbTileAreaPPW xf1bppTileAreaPPW
+#define mfbTileAreaPPWCopy xf1bppTileAreaPPWCopy
+#define mfbTileAreaPPWGeneral xf1bppTileAreaPPWGeneral
+#define mfbTileFS xf1bppTileFS
+#define mfbUninstallColormap xf1bppUninstallColormap
+#define mfbUnmapWindow xf1bppUnmapWindow
+#define mfbUnnaturalStippleFS xf1bppUnnaturalStippleFS
+#define mfbUnnaturalTileFS xf1bppUnnaturalTileFS
+#define mfbUnrealizeFont xf1bppUnrealizeFont
+#define mfbValidateGC xf1bppValidateGC
+#define mfbVertS xf1bppVertS
+#define mfbWhiteSolidFS xf1bppWhiteSolidFS
+#define mfbWhiteStippleFS xf1bppWhiteStippleFS
+#define mfbWindowPrivateIndex xf1bppWindowPrivateIndex
+#define mfbXRotatePixmap xf1bppXRotatePixmap
+#define mfbYRotatePixmap xf1bppYRotatePixmap
+#define mfbZeroPolyArcSS xf1bppZeroPolyArcSS
+#define partmasks xf1bpppartmasks
+#define rmask xf1bpprmask
+#define starttab xf1bppstarttab
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/xf1bpp/mfbmap.sh b/xc/programs/Xserver/hw/xfree86/xf1bpp/mfbmap.sh
new file mode 100644
index 000000000..a8f43eceb
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf1bpp/mfbmap.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# $XFree86: xc/programs/Xserver/hw/xfree86/xf1bpp/mfbmap.sh,v 1.2 1998/07/25 16:59:24 dawes Exp $
+#
+# This script recreates the mapping list that maps the mfb external
+# symbols * to xf1bpp* (without "mfb")
+# This should only be rerun if there have been changes in the mfb code
+# that affect the external symbols.
+# It assumes that Xserver/mfb has been compiled.
+# The output goes to stdout.
+echo ""
+echo "#ifndef _MFBMAP_H"
+echo "#define _MFBMAP_H"
+echo ""
+
+nm ../../../mfb/*.o | \
+awk "{ if ((\$2 == \"D\") || (\$2 == \"T\") || (\$2 == \"C\")) print \$3 }" | \
+sed s/^_// | \
+grep -v "ModuleInit$" | \
+sort | \
+awk "{ print \"#define \" \$1 \" xf1bpp\"\$1 }" | \
+sed s/xf1bppmfb/xf1bpp/
+
+echo ""
+echo "#endif"
diff --git a/xc/programs/Xserver/hw/xfree86/xf1bpp/mfbmodule.c b/xc/programs/Xserver/hw/xfree86/xf1bpp/mfbmodule.c
new file mode 100644
index 000000000..4fb795152
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf1bpp/mfbmodule.c
@@ -0,0 +1,48 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf1bpp/mfbmodule.c,v 1.6 1999/01/26 05:54:19 dawes Exp $ */
+/*
+ * Copyright (C) 1997 The XFree86 Project, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * XFREE86 PROJECT 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 XFree86 Project 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
+ * XFree86 Project.
+ */
+
+#ifdef XFree86LOADER
+#include "xf86Module.h"
+
+
+static XF86ModuleVersionInfo VersRec =
+{
+ "xf1bpp",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_ANSIC, /* Only need ansic layer */
+ ABI_ANSIC_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0} /* signature, to be patched into the file by a tool */
+};
+
+XF86ModuleData xf1bppModuleData = { &VersRec, NULL, NULL };
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/xf1bpp/mfbunmap.h b/xc/programs/Xserver/hw/xfree86/xf1bpp/mfbunmap.h
new file mode 100644
index 000000000..94c029856
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf1bpp/mfbunmap.h
@@ -0,0 +1,109 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf1bpp/mfbunmap.h,v 1.2 1998/07/25 16:59:25 dawes Exp $ */
+
+#ifdef _MFBMAP_H
+#undef _MFBMAP_H
+
+#undef InverseAlu
+#undef endtab
+#undef mask
+#undef mergeRopBits
+#undef mfbAllocatePrivates
+#undef mfbBSFuncRec
+#undef mfbBlackSolidFS
+#undef mfbBlackStippleFS
+#undef mfbBresD
+#undef mfbBresS
+#undef mfbChangeWindowAttributes
+#undef mfbCloseScreen
+#undef mfbCopyArea
+#undef mfbCopyPixmap
+#undef mfbCopyPlane
+#undef mfbCopyRotatePixmap
+#undef mfbCopyWindow
+#undef mfbCreateColormap
+#undef mfbCreateDefColormap
+#undef mfbCreateGC
+#undef mfbCreatePixmap
+#undef mfbCreateWindow
+#undef mfbDestroyColormap
+#undef mfbDestroyPixmap
+#undef mfbDestroyWindow
+#undef mfbDoBitblt
+#undef mfbDoBitbltCopy
+#undef mfbDoBitbltCopyInverted
+#undef mfbDoBitbltGeneral
+#undef mfbDoBitbltOr
+#undef mfbDoBitbltXor
+#undef mfbFillPolyBlack
+#undef mfbFillPolyInvert
+#undef mfbFillPolyWhite
+#undef mfbGCPrivateIndex
+#undef mfbGetImage
+#undef mfbGetSpans
+#undef mfbGetWindowPixmap
+#undef mfbHorzS
+#undef mfbImageGlyphBltBlack
+#undef mfbImageGlyphBltWhite
+#undef mfbInstallColormap
+#undef mfbInvertSolidFS
+#undef mfbInvertStippleFS
+#undef mfbLineSD
+#undef mfbLineSS
+#undef mfbListInstalledColormaps
+#undef mfbMapWindow
+#undef mfbPadPixmap
+#undef mfbPaintWindow
+#undef mfbPixmapToRegion
+#undef mfbPolyFillArcSolid
+#undef mfbPolyFillRect
+#undef mfbPolyGlyphBltBlack
+#undef mfbPolyGlyphBltInvert
+#undef mfbPolyGlyphBltWhite
+#undef mfbPolyPoint
+#undef mfbPositionWindow
+#undef mfbPushPixels
+#undef mfbPutImage
+#undef mfbQueryBestSize
+#undef mfbRealizeFont
+#undef mfbReduceRop
+#undef mfbRegisterCopyPlaneProc
+#undef mfbResolveColor
+#undef mfbRestoreAreas
+#undef mfbSaveAreas
+#undef mfbScreenInit
+#undef mfbSegmentSD
+#undef mfbSegmentSS
+#undef mfbSetScanline
+#undef mfbSetSpans
+#undef mfbSetWindowPixmap
+#undef mfbSolidBlackArea
+#undef mfbSolidInvertArea
+#undef mfbSolidPP
+#undef mfbSolidWhiteArea
+#undef mfbStippleBlackArea
+#undef mfbStippleInvertArea
+#undef mfbStippleWhiteArea
+#undef mfbTEGlyphBltBlack
+#undef mfbTEGlyphBltWhite
+#undef mfbTileAreaPPW
+#undef mfbTileAreaPPWCopy
+#undef mfbTileAreaPPWGeneral
+#undef mfbTileFS
+#undef mfbUninstallColormap
+#undef mfbUnmapWindow
+#undef mfbUnnaturalStippleFS
+#undef mfbUnnaturalTileFS
+#undef mfbUnrealizeFont
+#undef mfbValidateGC
+#undef mfbVertS
+#undef mfbWhiteSolidFS
+#undef mfbWhiteStippleFS
+#undef mfbWindowPrivateIndex
+#undef mfbXRotatePixmap
+#undef mfbYRotatePixmap
+#undef mfbZeroPolyArcSS
+#undef partmasks
+#undef rmask
+#undef starttab
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/xf1bpp/mfbunmap.sh b/xc/programs/Xserver/hw/xfree86/xf1bpp/mfbunmap.sh
new file mode 100644
index 000000000..6b244e68e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf1bpp/mfbunmap.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# $XFree86: xc/programs/Xserver/hw/xfree86/xf1bpp/mfbunmap.sh,v 1.2 1998/07/25 16:59:25 dawes Exp $
+#
+# This script recreates a header that undoes the effect of mfbmap.h
+# This should only be rerun if there have been changes in the mfb code
+# that affect the external symbols.
+# It assumes that Xserver/mfb has been compiled.
+# The output goes to stdout.
+echo ""
+echo "#ifdef _MFBMAP_H"
+echo "#undef _MFBMAP_H"
+echo ""
+
+nm ../../../mfb/*.o | \
+awk "{ if ((\$2 == \"D\") || (\$2 == \"T\") || (\$2 == \"C\")) print \$3 }" | \
+sed s/^_// | \
+grep -v "ModuleInit$" | \
+sort | \
+awk "{ print \"#undef \" \$1 }"
+
+echo ""
+echo "#endif"
diff --git a/xc/programs/Xserver/hw/xfree86/xf1bpp/xf1bpp.h b/xc/programs/Xserver/hw/xfree86/xf1bpp/xf1bpp.h
new file mode 100644
index 000000000..18104a77e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf1bpp/xf1bpp.h
@@ -0,0 +1,37 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf1bpp/xf1bpp.h,v 1.2 1998/07/25 16:59:25 dawes Exp $ */
+/*
+ * Copyright (C) 1994-1998 The XFree86 Project, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * XFREE86 PROJECT 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 XFree86 Project 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
+ * XFree86 Project.
+ */
+
+#ifndef __XF1BPP_H__
+#define __XF1BPP_H__
+
+#define MFB_PROTOTYPES_ONLY
+#include "mfbmap.h"
+#include "mfb.h"
+#include "mfbunmap.h"
+#undef MFB_PROTOTYPES_ONLY
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/xf24_32bpp/Imakefile b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/Imakefile
new file mode 100644
index 000000000..ddb881f07
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/Imakefile
@@ -0,0 +1,41 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/xf24_32bpp/Imakefile,v 1.4 1999/08/14 10:50:15 dawes Exp $
+#define IHaveModules
+#include <Server.tmpl>
+
+
+#if DoLoadableServer
+XFMODSRC = cfb24_32module.c
+XFMODOBJ = cfb24_32module.o
+#endif
+
+SRCS = cfbcpyarea.c cfbgcmisc.c cfbpixmap.c \
+ cfbimage.c cfbscrinit.c cfbwindow.c \
+ $(XFMODSRC) cfbgc24.c cfbgc32.c
+
+
+OBJS = cfbcpyarea.o cfbgcmisc.o cfbpixmap.o \
+ cfbimage.o cfbscrinit.o cfbwindow.o \
+ $(XFMODOBJ) cfbgc24.o cfbgc32.o
+
+INCLUDES = -I. -I$(XF86SRC)/xf1bpp -I$(SERVERSRC)/mfb \
+ -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mi -I$(SERVERSRC)/include \
+ -I$(XF86OSSRC) -I$(XF86COMSRC) \
+ -I$(FONTINCSRC) -I$(XINCLUDESRC)
+
+
+ModuleObjectRule()
+LibraryModuleTarget(xf24_32bpp,$(OBJS))
+LintLibraryTarget(xf24_32bpp,$(SRCS))
+NormalLintTarget($(LINTDEFS) $(SRCS))
+
+ObjectFromSpecialSource(cfbgc24,cfbgc,-DPSZ=24)
+ObjectFromSpecialSource(cfbgc32,cfbgc,-DPSZ=32)
+
+
+InstallLibraryModule(xf24_32bpp,$(MODULEDIR),.)
+
+DependTarget()
+
+InstallDriverSDKLibraryModule(xf24_32bpp,$(DRIVERSDKMODULEDIR),.)
+
+InstallDriverSDKNonExecFile(cfb24_32.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfb24_32.h b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfb24_32.h
new file mode 100644
index 000000000..9f2458758
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfb24_32.h
@@ -0,0 +1,163 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfb24_32.h,v 1.3 1999/03/02 10:42:01 dawes Exp $ */
+
+#ifndef _CFB24_32_H
+#define _CFB24_32_H
+
+#include "gcstruct.h"
+
+typedef struct {
+ GCOps *Ops24bpp;
+ GCOps *Ops32bpp;
+ unsigned long changes;
+ Bool OpsAre24bpp;
+} cfb24_32GCRec, *cfb24_32GCPtr;
+
+
+extern int cfb24_32GCIndex;
+extern int cfb24_32PixmapIndex;
+
+typedef struct {
+ PixmapPtr pix;
+ Bool freePrivate;
+} cfb24_32PixmapRec, *cfb24_32PixmapPtr;
+
+RegionPtr
+cfb24_32CopyArea(
+ DrawablePtr pSrcDraw,
+ DrawablePtr pDstDraw,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+);
+
+void
+cfbDoBitblt24To32(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ int rop,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc,
+ unsigned long planemask,
+ unsigned long bitPlane
+);
+
+void
+cfbDoBitblt32To24(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ int rop,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc,
+ unsigned long planemask,
+ unsigned long bitPlane
+);
+
+void
+cfb24_32DoBitblt24To24GXcopy(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ int rop,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc,
+ unsigned long pm,
+ unsigned long bitPlane
+);
+
+void
+cfb24_32ValidateGC24(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDrawable
+);
+
+void
+cfb24_32ValidateGC32(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDrawable
+);
+
+Bool cfb24_32CreateGC(GCPtr pGC);
+
+void
+cfb24_32GetSpans(
+ DrawablePtr pDraw,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pchardstStart
+);
+
+void
+cfb24_32PutImage (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage
+);
+
+void
+cfb24_32GetImage (
+ DrawablePtr pDraw,
+ int sx, int sy, int w, int h,
+ unsigned int format,
+ unsigned long planeMask,
+ char *pdstLine
+);
+
+Bool
+cfb24_32ScreenInit (
+ ScreenPtr pScreen,
+ pointer pbits,
+ int xsize, int ysize,
+ int dpix, int dpiy,
+ int width
+);
+
+
+Bool cfb24_32CreateWindow(WindowPtr pWin);
+Bool cfb24_32DestroyWindow(WindowPtr pWin);
+
+Bool
+cfb24_32PositionWindow(
+ WindowPtr pWin,
+ int x, int y
+);
+
+void
+cfb24_32CopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc
+);
+
+Bool
+cfb24_32ChangeWindowAttributes(
+ WindowPtr pWin,
+ unsigned long mask
+);
+
+PixmapPtr
+cfb24_32CreatePixmap (
+ ScreenPtr pScreen,
+ int width,
+ int height,
+ int depth
+);
+
+Bool cfb24_32DestroyPixmap(PixmapPtr pPixmap);
+
+PixmapPtr cfb24_32RefreshPixmap(PixmapPtr pix);
+
+#define CFB24_32_GET_GC_PRIVATE(pGC)\
+ (cfb24_32GCPtr)((pGC)->devPrivates[cfb24_32GCIndex].ptr)
+
+#define CFB24_32_GET_PIXMAP_PRIVATE(pPix) \
+ (cfb24_32PixmapPtr)((pPix)->devPrivates[cfb24_32PixmapIndex].ptr)
+
+#endif /* _CFB24_32_H */
diff --git a/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfb24_32module.c b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfb24_32module.c
new file mode 100644
index 000000000..33fb74632
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfb24_32module.c
@@ -0,0 +1,37 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfb24_32module.c,v 1.3 1999/01/26 05:54:20 dawes Exp $ */
+
+#ifdef XFree86LOADER
+
+#include "xf86Module.h"
+
+static MODULESETUPPROTO(xf24_32bppSetup);
+
+static XF86ModuleVersionInfo VersRec =
+{
+ "xf24_32bpp",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_ANSIC, /* Only need the ansic layer */
+ ABI_ANSIC_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0} /* signature, to be patched into the file by a tool */
+};
+
+XF86ModuleData xf24_32bppModuleData = { &VersRec, xf24_32bppSetup, NULL };
+
+static pointer
+xf24_32bppSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ if (!LoadSubModule(module, "cfb24", NULL, NULL, NULL, NULL,
+ errmaj, errmin))
+ return NULL;
+ if (!LoadSubModule(module, "cfb32", NULL, NULL, NULL, NULL,
+ errmaj, errmin))
+ return NULL;
+ return (pointer)1; /* non-NULL required to indicate success */
+}
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbbstore.c b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbbstore.c
new file mode 100644
index 000000000..07808c321
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbbstore.c
@@ -0,0 +1,89 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbbstore.c,v 1.1 1999/01/23 09:56:13 dawes Exp $ */
+
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb24.h"
+#include "cfb32.h"
+#include "cfb24_32.h"
+#include "X.h"
+#include "mibstore.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+
+void
+cfb24_32SaveAreas(
+ PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+){
+ DDXPointPtr pPt;
+ DDXPointPtr pPtsInit;
+ BoxPtr pBox;
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ PixmapPtr pScrPix;
+ int i = REGION_NUM_RECTS(prgnSave);
+
+
+ pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(i * sizeof(DDXPointRec));
+ if (!pPtsInit)
+ return;
+
+ pBox = REGION_RECTS(prgnSave);
+ pPt = pPtsInit;
+ while (--i >= 0) {
+ pPt->x = pBox->x1 + xorg;
+ pPt->y = pBox->y1 + yorg;
+ pPt++;
+ pBox++;
+ }
+
+ pScrPix = (PixmapPtr) pScreen->devPrivate;
+
+ cfbDoBitblt24To32((DrawablePtr) pScrPix, (DrawablePtr)pPixmap,
+ GXcopy, prgnSave, pPtsInit, ~0L, 0);
+
+ DEALLOCATE_LOCAL (pPtsInit);
+}
+
+
+void
+cfb24_32RestoreAreas(
+ PixmapPtr pPixmap,
+ RegionPtr prgnRestore,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+){
+ DDXPointPtr pPt;
+ DDXPointPtr pPtsInit;
+ BoxPtr pBox;
+ int i;
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ PixmapPtr pScrPix;
+
+ i = REGION_NUM_RECTS(prgnRestore);
+ pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(i*sizeof(DDXPointRec));
+ if (!pPtsInit)
+ return;
+
+ pBox = REGION_RECTS(prgnRestore);
+ pPt = pPtsInit;
+ while (--i >= 0) {
+ pPt->x = pBox->x1 - xorg;
+ pPt->y = pBox->y1 - yorg;
+ pPt++;
+ pBox++;
+ }
+
+ pScrPix = (PixmapPtr) pScreen->devPrivate;
+
+ cfbDoBitblt32To24((DrawablePtr)pPixmap, (DrawablePtr) pScrPix,
+ GXcopy, prgnRestore, pPtsInit, ~0L, 0);
+
+ DEALLOCATE_LOCAL (pPtsInit);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbcpyarea.c b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbcpyarea.c
new file mode 100644
index 000000000..56c9a6908
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbcpyarea.c
@@ -0,0 +1,714 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbcpyarea.c,v 1.5 1999/05/16 10:13:05 dawes Exp $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "servermd.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "resource.h"
+#include "colormap.h"
+#include "colormapst.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb24.h"
+#include "cfb32.h"
+#include "cfb24_32.h"
+#include "mi.h"
+#include "mistruct.h"
+#include "dix.h"
+#include "mibstore.h"
+
+
+
+RegionPtr
+cfb24_32CopyArea(
+ DrawablePtr pSrcDraw,
+ DrawablePtr pDstDraw,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+){
+
+ if(pSrcDraw->bitsPerPixel == 32) {
+ if(pDstDraw->bitsPerPixel == 32) {
+ return(cfb32CopyArea(pSrcDraw, pDstDraw, pGC, srcx, srcy,
+ width, height, dstx, dsty));
+ } else {
+ /* have to translate 32 -> 24 copies */
+ return cfb32BitBlt (pSrcDraw, pDstDraw,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ cfbDoBitblt32To24, 0L);
+ }
+ } else {
+ if(pDstDraw->bitsPerPixel == 32) {
+ /* have to translate 24 -> 32 copies */
+ return cfb32BitBlt (pSrcDraw, pDstDraw,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ cfbDoBitblt24To32, 0L);
+ } else if((pDstDraw->type == DRAWABLE_WINDOW) &&
+ (pSrcDraw->type == DRAWABLE_WINDOW) && (pGC->alu == GXcopy) &&
+ ((pGC->planemask & 0x00ffffff) == 0x00ffffff)) {
+
+ return cfb24BitBlt (pSrcDraw, pDstDraw,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ cfb24_32DoBitblt24To24GXcopy, 0L);
+ } else {
+ return(cfb24CopyArea(pSrcDraw, pDstDraw, pGC, srcx, srcy,
+ width, height, dstx, dsty));
+ }
+ }
+}
+
+
+
+void
+cfbDoBitblt24To32(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ int rop,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc,
+ unsigned long planemask,
+ unsigned long bitPlane
+){
+ BoxPtr pbox = REGION_RECTS(prgnDst);
+ int nbox = REGION_NUM_RECTS(prgnDst);
+ unsigned char *data24, *data32;
+ unsigned char *ptr24, *ptr32;
+ int pitch24, pitch32;
+ int height, width, i, j;
+ unsigned char *pm;
+
+ cfbGetByteWidthAndPointer(pSrc, pitch24, ptr24);
+ cfbGetByteWidthAndPointer(pDst, pitch32, ptr32);
+
+ planemask &= 0x00ffffff;
+ pm = (unsigned char*)(&planemask);
+
+ if((planemask == 0x00ffffff) && (rop == GXcopy)) {
+ CARD32 *dst, *src;
+ CARD32 tmp, phase;
+
+ for(;nbox; pbox++, pptSrc++, nbox--) {
+ data24 = ptr24 + (pptSrc->y * pitch24) + (pptSrc->x * 3);
+ data32 = ptr32 + (pbox->y1 * pitch32) + (pbox->x1 << 2);
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ phase = (long)data24 & 3L;
+ data24 = (unsigned char*)((long)data24 & ~3L);
+
+ while(height--) {
+ src = (CARD32*)data24;
+ dst = (CARD32*)data32;
+ i = width;
+
+ switch(phase) {
+ case 0: break;
+ case 1:
+ dst[0] = src[0] >> 8;
+ dst++;
+ src++;
+ i--;
+ break;
+ case 2:
+ dst[0] = src[0] >> 16;
+ tmp = src[1];
+ dst[0] |= tmp << 16;
+ if(!(--i)) break;
+ dst[1] = tmp >> 8;
+ dst += 2;
+ src += 2;
+ i--;
+ break;
+ default:
+ dst[0] = src[0] >> 24;
+ tmp = src[1];
+ dst[0] |= tmp << 8;
+ if(!(--i)) break;
+ dst[1] = tmp >> 16;
+ tmp = src[2];
+ dst[1] |= tmp << 16;
+ if(!(--i)) break;
+ dst[2] = tmp >> 8;
+ dst += 3;
+ src += 3;
+ i--;
+ break;
+ }
+
+ while(i >= 4) {
+ dst[0] = src[0];
+ tmp = src[1];
+ dst[3] = src[2];
+ dst[1] = (dst[0] >> 24) | (tmp << 8);
+ dst[2] = (tmp >> 16) | (dst[3] << 16);
+ dst[3] >>= 8;
+
+ src += 3;
+ dst += 4;
+ i -= 4;
+ }
+
+ switch(i) {
+ case 0: break;
+ case 1:
+ dst[0] = src[0];
+ break;
+ case 2:
+ dst[0] = src[0];
+ dst[1] = (dst[0] >> 24) | (src[1] << 8);
+ break;
+ default:
+ dst[0] = src[0];
+ tmp = src[1];
+ dst[2] = src[2] << 16;
+ dst[1] = (dst[0] >> 24) | (tmp << 8);
+ dst[2] |= tmp >> 16;
+ break;
+ }
+
+ data24 += pitch24;
+ data32 += pitch32;
+ }
+ }
+ } else { /* it ain't pretty, but hey */
+ for(;nbox; pbox++, pptSrc++, nbox--) {
+ data24 = ptr24 + (pptSrc->y * pitch24) + (pptSrc->x * 3);
+ data32 = ptr32 + (pbox->y1 * pitch32) + (pbox->x1 << 2);
+ width = (pbox->x2 - pbox->x1) << 2;
+ height = pbox->y2 - pbox->y1;
+
+ while(height--) {
+ switch(rop) {
+ case GXcopy:
+ for(i = j = 0; i < width; i += 4, j += 3) {
+ data32[i] = (data24[j] & pm[0]) | (data32[i] & ~pm[0]);
+ data32[i+1] = (data24[j+1] & pm[1]) |
+ (data32[i+1] & ~pm[1]);
+ data32[i+2] = (data24[j+2] & pm[2]) |
+ (data32[i+2] & ~pm[2]);
+ }
+ break;
+ case GXor:
+ for(i = j = 0; i < width; i += 4, j += 3) {
+ data32[i] |= data24[j] & pm[0];
+ data32[i+1] |= data24[j+1] & pm[1];
+ data32[i+2] |= data24[j+2] & pm[2];
+ }
+ break;
+ case GXclear:
+ for(i = 0; i < width; i += 4) {
+ data32[i] &= ~pm[0];
+ data32[i+1] &= ~pm[1];
+ data32[i+2] &= ~pm[2];
+ }
+ break;
+ case GXand:
+ for(i = j = 0; i < width; i += 4, j += 3) {
+ data32[i] &= data24[j] | ~pm[0];
+ data32[i+1] &= data24[j+1] | ~pm[1];
+ data32[i+2] &= data24[j+2] | ~pm[2];
+ }
+ break;
+ case GXandReverse:
+ for(i = j = 0; i < width; i += 4, j += 3) {
+ data32[i] = ~data32[i] & (data24[j] | ~pm[0]);
+ data32[i+1] = ~data32[i+1] & (data24[j+1] | ~pm[1]);
+ data32[i+2] = ~data32[i+2] & (data24[j+2] | ~pm[2]);
+ }
+ break;
+ case GXandInverted:
+ for(i = j = 0; i < width; i += 4, j += 3) {
+ data32[i] &= ~(data24[j] & pm[0]);
+ data32[i+1] &= ~(data24[j+1] & pm[1]);
+ data32[i+2] &= ~(data24[j+2] & pm[2]);
+ }
+ break;
+ case GXnoop:
+ return;
+ case GXxor:
+ for(i = j = 0; i < width; i += 4, j += 3) {
+ data32[i] ^= data24[j] & pm[0];
+ data32[i+1] ^= data24[j+1] & pm[1];
+ data32[i+2] ^= data24[j+2] & pm[2];
+ }
+ break;
+ case GXnor:
+ for(i = j = 0; i < width; i += 4, j += 3) {
+ data32[i] = ~(data32[i] | (data24[j] & pm[0]));
+ data32[i+1] = ~(data32[i+1] | (data24[j+1] & pm[1]));
+ data32[i+2] = ~(data32[i+2] | (data24[j+2] & pm[2]));
+ }
+ break;
+ case GXequiv:
+ for(i = j = 0; i < width; i += 4, j += 3) {
+ data32[i] = ~(data32[i] ^ (data24[j] & pm[0]));
+ data32[i+1] = ~(data32[i+1] ^ (data24[j+1] & pm[1]));
+ data32[i+2] = ~(data32[i+2] ^ (data24[j+2] & pm[2]));
+ }
+ break;
+ case GXinvert:
+ for(i = 0; i < width; i += 4) {
+ data32[i] ^= pm[0];
+ data32[i+1] ^= pm[1];
+ data32[i+2] ^= pm[2];
+ }
+ break;
+ case GXorReverse:
+ for(i = j = 0; i < width; i += 4, j += 3) {
+ data32[i] = ~data32[i] | (data24[j] & pm[0]);
+ data32[i+1] = ~data32[i+1] | (data24[j+1] & pm[1]);
+ data32[i+2] = ~data32[i+2] | (data24[j+2] & pm[2]);
+ }
+ break;
+ case GXcopyInverted:
+ for(i = j = 0; i < width; i += 4, j += 3) {
+ data32[i] = (~data24[j] & pm[0]) | (data32[i] & ~pm[0]);
+ data32[i+1] = (~data24[j+1] & pm[1]) |
+ (data32[i+1] & ~pm[1]);
+ data32[i+2] = (~data24[j+2] & pm[2]) |
+ (data32[i+2] & ~pm[2]);
+ }
+ break;
+ case GXorInverted:
+ for(i = j = 0; i < width; i += 4, j += 3) {
+ data32[i] |= ~data24[j] & pm[0];
+ data32[i+1] |= ~data24[j+1] & pm[1];
+ data32[i+2] |= ~data24[j+2] & pm[2];
+ }
+ break;
+ case GXnand:
+ for(i = j = 0; i < width; i += 4, j += 3) {
+ data32[i] = ~(data32[i] & (data24[j] | ~pm[0]));
+ data32[i+1] = ~(data32[i+1] & (data24[j+1] | ~pm[1]));
+ data32[i+2] = ~(data32[i+2] & (data24[j+2] | ~pm[2]));
+ }
+ break;
+ case GXset:
+ for(i = 0; i < width; i+=4) {
+ data32[i] |= pm[0];
+ data32[i+1] |= pm[1];
+ data32[i+2] |= pm[2];
+ }
+ break;
+ }
+ data24 += pitch24;
+ data32 += pitch32;
+ }
+ }
+ }
+}
+
+
+void
+cfbDoBitblt32To24(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ int rop,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc,
+ unsigned long planemask,
+ unsigned long bitPlane
+){
+ BoxPtr pbox = REGION_RECTS(prgnDst);
+ int nbox = REGION_NUM_RECTS(prgnDst);
+ unsigned char *ptr24, *ptr32;
+ unsigned char *data24, *data32;
+ int pitch24, pitch32;
+ int height, width, i, j;
+ unsigned char *pm;
+
+ cfbGetByteWidthAndPointer(pDst, pitch24, ptr24);
+ cfbGetByteWidthAndPointer(pSrc, pitch32, ptr32);
+
+ planemask &= 0x00ffffff;
+ pm = (unsigned char*)(&planemask);
+
+ if((planemask == 0x00ffffff) && (rop == GXcopy)) {
+ CARD32 *src;
+ CARD8 *dst;
+ long phase;
+ for(;nbox; pbox++, pptSrc++, nbox--) {
+ data24 = ptr24 + (pbox->y1 * pitch24) + (pbox->x1 * 3);
+ data32 = ptr32 + (pptSrc->y * pitch32) + (pptSrc->x << 2);
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ phase = (long)data24 & 3L;
+
+ while(height--) {
+ src = (CARD32*)data32;
+ dst = data24;
+ j = width;
+
+ switch(phase) {
+ case 0: break;
+ case 1:
+ dst[0] = src[0];
+ *((CARD16*)(dst + 1)) = src[0] >> 8;
+ dst += 3;
+ src++;
+ j--;
+ break;
+ case 2:
+ if(j == 1) break;
+ *((CARD16*)dst) = src[0];
+ *((CARD32*)(dst + 2)) = ((src[0] >> 16) & 0x000000ff) |
+ (src[1] << 8);
+ dst += 6;
+ src += 2;
+ j -= 2;
+ break;
+ default:
+ if(j < 3) break;
+ dst[0] = src[0];
+ *((CARD32*)(dst + 1)) = ((src[0] >> 8) & 0x0000ffff) |
+ (src[1] << 16);
+ *((CARD32*)(dst + 5)) = ((src[1] >> 16) & 0x000000ff) |
+ (src[2] << 8);
+ dst += 9;
+ src += 3;
+ j -= 3;
+ }
+
+ while(j >= 4) {
+ *((CARD32*)dst) = (src[0] & 0x00ffffff) | (src[1] << 24);
+ *((CARD32*)(dst + 4)) = ((src[1] >> 8) & 0x0000ffff)|
+ (src[2] << 16);
+ *((CARD32*)(dst + 8)) = ((src[2] >> 16) & 0x000000ff) |
+ (src[3] << 8);
+ dst += 12;
+ src += 4;
+ j -= 4;
+ }
+ switch(j) {
+ case 0:
+ break;
+ case 1:
+ *((CARD16*)dst) = src[0];
+ dst[2] = src[0] >> 16;
+ break;
+ case 2:
+ *((CARD32*)dst) = (src[0] & 0x00ffffff) | (src[1] << 24);
+ *((CARD16*)(dst + 4)) = src[1] >> 8;
+ break;
+ default:
+ *((CARD32*)dst) = (src[0] & 0x00ffffff) | (src[1] << 24);
+ *((CARD32*)(dst + 4)) = ((src[1] >> 8) & 0x0000ffff) |
+ (src[2] << 16);
+ dst[8] = src[2] >> 16;
+ break;
+ }
+
+ data24 += pitch24;
+ data32 += pitch32;
+ }
+ }
+ } else {
+ for(;nbox; pbox++, pptSrc++, nbox--) {
+ data24 = ptr24 + (pbox->y1 * pitch24) + (pbox->x1 * 3);
+ data32 = ptr32 + (pptSrc->y * pitch32) + (pptSrc->x << 2);
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ while(height--) {
+ switch(rop) {
+ case GXcopy:
+ for(i = j = 0; j < width; i += 4, j += 3) {
+ data24[j] = (data32[i] & pm[0]) | (data24[j] & ~pm[0]);
+ data24[j+1] = (data32[i+1] & pm[1]) |
+ (data24[j+1] & ~pm[1]);
+ data24[j+2] = (data32[i+2] & pm[2]) |
+ (data24[j+2] & ~pm[2]);
+ }
+ break;
+ case GXor:
+ for(i = j = 0; j < width; i += 4, j += 3) {
+ data24[j] |= data32[i] & pm[0];
+ data24[j+1] |= data32[i+1] & pm[1];
+ data24[j+2] |= data32[i+2] & pm[2];
+ }
+ break;
+ case GXclear:
+ for(j = 0; j < width; j += 3) {
+ data24[j] &= ~pm[0];
+ data24[j+1] &= ~pm[1];
+ data24[j+2] &= ~pm[2];
+ }
+ break;
+ case GXand:
+ for(i = j = 0; j < width; i += 4, j += 3) {
+ data24[j] &= data32[i] | ~pm[0];
+ data24[j+1] &= data32[i+1] | ~pm[1];
+ data24[j+2] &= data32[i+2] | ~pm[2];
+ }
+ break;
+ case GXandReverse:
+ for(i = j = 0; j < width; i += 4, j += 3) {
+ data24[j] = ~data24[j] & (data32[i] | ~pm[0]);
+ data24[j+1] = ~data24[j+1] & (data32[i+1] | ~pm[1]);
+ data24[j+2] = ~data24[j+2] & (data32[i+2] | ~pm[2]);
+ }
+ break;
+ case GXandInverted:
+ for(i = j = 0; j < width; i += 4, j += 3) {
+ data24[j] &= ~(data32[i] & pm[0]);
+ data24[j+1] &= ~(data32[i+1] & pm[1]);
+ data24[j+2] &= ~(data32[i+2] & pm[2]);
+ }
+ break;
+ case GXnoop:
+ return;
+ case GXxor:
+ for(i = j = 0; j < width; i += 4, j += 3) {
+ data24[j] ^= data32[i] & pm[0];
+ data24[j+1] ^= data32[i+1] & pm[1];
+ data24[j+2] ^= data32[i+2] & pm[2];
+ }
+ break;
+ case GXnor:
+ for(i = j = 0; j < width; i += 4, j += 3) {
+ data24[j] = ~(data24[j] | (data32[i] & pm[0]));
+ data24[j+1] = ~(data24[j+1] | (data32[i+1] & pm[1]));
+ data24[j+2] = ~(data24[j+2] | (data32[i+2] & pm[2]));
+ }
+ break;
+ case GXequiv:
+ for(i = j = 0; j < width; i += 4, j += 3) {
+ data24[j] = ~(data24[j] ^ (data32[i] & pm[0]));
+ data24[j+1] = ~(data24[j+1] ^ (data32[i+1] & pm[1]));
+ data24[j+2] = ~(data24[j+2] ^ (data32[i+2] & pm[2]));
+ }
+ break;
+ case GXinvert:
+ for(j = 0; j < width; j+=3) {
+ data24[j] ^= pm[0];
+ data24[j+1] ^= pm[1];
+ data24[j+2] ^= pm[2];
+ }
+ break;
+ case GXorReverse:
+ for(i = j = 0; j < width; i += 4, j += 3) {
+ data24[j] = ~data24[j] | (data32[i] & pm[0]);
+ data24[j+1] = ~data24[j+1] | (data32[i+1] & pm[1]);
+ data24[j+2] = ~data24[j+2] | (data32[i+2] & pm[2]);
+ }
+ break;
+ case GXcopyInverted:
+ for(i = j = 0; j < width; i += 4, j += 3) {
+ data24[j] = (~data32[i] & pm[0]) | (data24[j] & ~pm[0]);
+ data24[j+1] = (~data32[i+1] & pm[1]) |
+ (data24[j+1] & ~pm[1]);
+ data24[j+2] = (~data32[i+2] & pm[2]) |
+ (data24[j+2] & ~pm[2]);
+ }
+ break;
+ case GXorInverted:
+ for(i = j = 0; j < width; i += 4, j += 3) {
+ data24[j] |= ~data32[i] & pm[0];
+ data24[j+1] |= ~data32[i+1] & pm[1];
+ data24[j+2] |= ~data32[i+2] & pm[2];
+ }
+ break;
+ case GXnand:
+ for(i = j = 0; j < width; i += 4, j += 3) {
+ data24[j] = ~(data24[j] & (data32[i] | ~pm[0]));
+ data24[j+1] = ~(data24[j+1] & (data32[i+1] | ~pm[1]));
+ data24[j+2] = ~(data24[j+2] & (data32[i+2] | ~pm[2]));
+ }
+ break;
+ case GXset:
+ for(j = 0; j < width; j+=3) {
+ data24[j] |= pm[0];
+ data24[j+1] |= pm[1];
+ data24[j+2] |= pm[2];
+ }
+ break;
+ }
+ data24 += pitch24;
+ data32 += pitch32;
+ }
+ }
+ }
+}
+
+
+
+
+static void
+Do24To24Blt(
+ unsigned char *ptr,
+ int pitch,
+ int nbox,
+ DDXPointPtr pptSrc,
+ BoxPtr pbox,
+ int xdir, int ydir
+){
+ int width, height, diff, phase;
+ CARD8 *swap, *lineAddr;
+
+ ydir *= pitch;
+
+ swap = (CARD8*)ALLOCATE_LOCAL((2048 * 3) + 3);
+
+ for(;nbox; pbox++, pptSrc++, nbox--) {
+ lineAddr = ptr + (pptSrc->y * pitch) + (pptSrc->x * 3);
+ diff = ((pbox->y1 - pptSrc->y) * pitch) + ((pbox->x1 - pptSrc->x) * 3);
+ width = (pbox->x2 - pbox->x1) * 3;
+ height = pbox->y2 - pbox->y1;
+
+ if(ydir < 0)
+ lineAddr += (height - 1) * pitch;
+
+ phase = (long)lineAddr & 3L;
+
+ while(height--) {
+ /* copy src onto the stack */
+ memcpy(swap, (CARD32*)((long)lineAddr & ~3L),
+ (width + phase + 3) & ~3L);
+
+ /* copy the stack to the dst */
+ memcpy(lineAddr + diff, swap + phase, width);
+ lineAddr += ydir;
+ }
+ }
+
+ DEALLOCATE_LOCAL(swap);
+}
+
+
+static void
+cfb24_32DoBitBlt(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc,
+ void (*DoBlt)()
+){
+ int nbox, careful, pitch;
+ BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
+ DDXPointPtr pptTmp, pptNew1, pptNew2;
+ int xdir, ydir;
+ unsigned char *ptr;
+
+ /* XXX we have to err on the side of safety when both are windows,
+ * because we don't know if IncludeInferiors is being used.
+ */
+ careful = ((pSrc == pDst) ||
+ ((pSrc->type == DRAWABLE_WINDOW) &&
+ (pDst->type == DRAWABLE_WINDOW)));
+
+ pbox = REGION_RECTS(prgnDst);
+ nbox = REGION_NUM_RECTS(prgnDst);
+
+ pboxNew1 = NULL;
+ pptNew1 = NULL;
+ pboxNew2 = NULL;
+ pptNew2 = NULL;
+ if (careful && (pptSrc->y < pbox->y1)) {
+ /* walk source botttom to top */
+ ydir = -1;
+
+ if (nbox > 1) {
+ /* keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ if(!pboxNew1)
+ return;
+ pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pptNew1) {
+ DEALLOCATE_LOCAL(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox) {
+ while ((pboxNext >= pbox) &&
+ (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp <= pboxBase) {
+ *pboxNew1++ = *pboxTmp++;
+ *pptNew1++ = *pptTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ pptNew1 -= nbox;
+ pptSrc = pptNew1;
+ }
+ } else {
+ /* walk source top to bottom */
+ ydir = 1;
+ }
+
+ if (careful && (pptSrc->x < pbox->x1)) {
+ /* walk source right to left */
+ xdir = -1;
+
+ if (nbox > 1) {
+ /* reverse order of rects in each band */
+ pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pboxNew2 || !pptNew2) {
+ if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
+ if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
+ if (pboxNew1) {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox) {
+ while ((pboxNext < pbox+nbox) &&
+ (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp != pboxBase) {
+ *pboxNew2++ = *--pboxTmp;
+ *pptNew2++ = *--pptTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ pptNew2 -= nbox;
+ pptSrc = pptNew2;
+ }
+ } else {
+ /* walk source left to right */
+ xdir = 1;
+ }
+
+ cfbGetByteWidthAndPointer(pDst, pitch, ptr);
+
+ (*DoBlt)(ptr, pitch, nbox, pptSrc, pbox, xdir, ydir);
+
+ if (pboxNew2) {
+ DEALLOCATE_LOCAL(pptNew2);
+ DEALLOCATE_LOCAL(pboxNew2);
+ }
+ if (pboxNew1) {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+
+}
+
+void
+cfb24_32DoBitblt24To24GXcopy(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ int rop,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc,
+ unsigned long pm,
+ unsigned long bitPlane
+){
+ cfb24_32DoBitBlt(pSrc, pDst, prgnDst, pptSrc, Do24To24Blt);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbgc.c b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbgc.c
new file mode 100644
index 000000000..348b3d785
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbgc.c
@@ -0,0 +1,667 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbgc.c,v 1.2 1999/08/21 13:48:43 dawes Exp $ */
+
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+
+/*
+
+PSZ 8 16 24 32
+PIXEL_ADDR True True True True
+NO_ONE_RECT False False False False
+WriteBitGroup True True True True
+FOUR_BIT_CODE True False False False
+LOWMEMFTPT False False False False
+
+*/
+
+
+/* This gets built twice. Once for 24bpp and another for 32bpp */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "cfb.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "region.h"
+
+#include "mistruct.h"
+#include "mibstore.h"
+#include "migc.h"
+
+#include "cfb24_32.h"
+#include "cfbmskbits.h"
+#include "cfb8bit.h"
+
+
+#if PSZ == 8
+# define useTEGlyphBlt cfbTEGlyphBlt8
+#else
+# ifdef WriteBitGroup
+# define useTEGlyphBlt cfbImageGlyphBlt8
+# else
+# define useTEGlyphBlt cfbTEGlyphBlt
+# endif
+#endif
+
+#ifdef WriteBitGroup
+# define useImageGlyphBlt cfbImageGlyphBlt8
+# define usePolyGlyphBlt cfbPolyGlyphBlt8
+#else
+# define useImageGlyphBlt miImageGlyphBlt
+# define usePolyGlyphBlt miPolyGlyphBlt
+#endif
+
+#ifdef FOUR_BIT_CODE
+# define usePushPixels cfbPushPixels8
+#else
+#ifndef LOWMEMFTPT
+# define usePushPixels mfbPushPixels
+#else
+# define usePushPixels miPushPixels
+#endif /* ifndef LOWMEMFTPT */
+#endif
+
+#ifdef PIXEL_ADDR
+# define ZeroPolyArc cfbZeroPolyArcSS8Copy
+#else
+# define ZeroPolyArc miZeroPolyArc
+#endif
+
+
+static GCOps cfb24_32TEOps1Rect = {
+ cfbSolidSpansCopy,
+ cfbSetSpans,
+ cfbPutImage,
+ cfb24_32CopyArea,
+ cfbCopyPlane,
+ cfbPolyPoint,
+#ifdef PIXEL_ADDR
+ cfb8LineSS1Rect,
+ cfb8SegmentSS1Rect,
+#else
+ cfbLineSS,
+ cfbSegmentSS,
+#endif
+ miPolyRectangle,
+ ZeroPolyArc,
+ cfbFillPoly1RectCopy,
+ cfbPolyFillRect,
+ cfbPolyFillArcSolidCopy,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ useTEGlyphBlt,
+ usePolyGlyphBlt,
+ usePushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps cfb24_32NonTEOps1Rect = {
+ cfbSolidSpansCopy,
+ cfbSetSpans,
+ cfbPutImage,
+ cfb24_32CopyArea,
+ cfbCopyPlane,
+ cfbPolyPoint,
+#ifdef PIXEL_ADDR
+ cfb8LineSS1Rect,
+ cfb8SegmentSS1Rect,
+#else
+ cfbLineSS,
+ cfbSegmentSS,
+#endif
+ miPolyRectangle,
+ ZeroPolyArc,
+ cfbFillPoly1RectCopy,
+ cfbPolyFillRect,
+ cfbPolyFillArcSolidCopy,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ useImageGlyphBlt,
+ usePolyGlyphBlt,
+ usePushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps cfb24_32TEOps = {
+ cfbSolidSpansCopy,
+ cfbSetSpans,
+ cfbPutImage,
+ cfb24_32CopyArea,
+ cfbCopyPlane,
+ cfbPolyPoint,
+ cfbLineSS,
+ cfbSegmentSS,
+ miPolyRectangle,
+ ZeroPolyArc,
+ miFillPolygon,
+ cfbPolyFillRect,
+ cfbPolyFillArcSolidCopy,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ useTEGlyphBlt,
+ usePolyGlyphBlt,
+ usePushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps cfb24_32NonTEOps = {
+ cfbSolidSpansCopy,
+ cfbSetSpans,
+ cfbPutImage,
+ cfb24_32CopyArea,
+ cfbCopyPlane,
+ cfbPolyPoint,
+ cfbLineSS,
+ cfbSegmentSS,
+ miPolyRectangle,
+#ifdef PIXEL_ADDR
+ cfbZeroPolyArcSS8Copy,
+#else
+ miZeroPolyArc,
+#endif
+ miFillPolygon,
+ cfbPolyFillRect,
+ cfbPolyFillArcSolidCopy,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ useImageGlyphBlt,
+ usePolyGlyphBlt,
+ usePushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps *
+cfb24_32MatchCommon (GCPtr pGC, cfbPrivGCPtr devPriv)
+{
+ if (pGC->lineWidth != 0)
+ return 0;
+ if (pGC->lineStyle != LineSolid)
+ return 0;
+ if (pGC->fillStyle != FillSolid)
+ return 0;
+ if (devPriv->rop != GXcopy)
+ return 0;
+ if (pGC->font &&
+ FONTMAXBOUNDS(pGC->font,rightSideBearing) -
+ FONTMINBOUNDS(pGC->font,leftSideBearing) <= 32 &&
+ FONTMINBOUNDS(pGC->font,characterWidth) >= 0)
+ {
+ if (TERMINALFONT(pGC->font)
+#ifdef FOUR_BIT_CODE
+ && FONTMAXBOUNDS(pGC->font,characterWidth) >= PGSZB
+#endif
+ )
+#ifdef NO_ONE_RECT
+ return &cfb24_32TEOps1Rect;
+#else
+ if (devPriv->oneRect)
+ return &cfb24_32TEOps1Rect;
+ else
+ return &cfb24_32TEOps;
+#endif
+ else
+#ifdef NO_ONE_RECT
+ return &cfb24_32NonTEOps1Rect;
+#else
+ if (devPriv->oneRect)
+ return &cfb24_32NonTEOps1Rect;
+ else
+ return &cfb24_32NonTEOps;
+#endif
+ }
+ return 0;
+}
+
+
+/* Clipping conventions
+ if the drawable is a window
+ CT_REGION ==> pCompositeClip really is the composite
+ CT_other ==> pCompositeClip is the window clip region
+ if the drawable is a pixmap
+ CT_REGION ==> pCompositeClip is the translated client region
+ clipped to the pixmap boundary
+ CT_other ==> pCompositeClip is the pixmap bounding box
+*/
+
+void
+#if PSZ == 24
+cfb24_32ValidateGC24(
+#else
+cfb24_32ValidateGC32(
+#endif
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDrawable
+){
+ int mask; /* stateChanges */
+ int index; /* used for stepping through bitfields */
+ int new_rrop;
+ int new_line, new_text, new_fillspans, new_fillarea;
+ /* flags for changing the proc vector */
+ cfbPrivGCPtr devPriv;
+ int oneRect;
+
+ pGC->lastWinOrg.x = pDrawable->x;
+ pGC->lastWinOrg.y = pDrawable->y;
+ devPriv = cfbGetGCPrivate(pGC);
+
+ new_rrop = FALSE;
+ new_line = FALSE;
+ new_text = FALSE;
+ new_fillspans = FALSE;
+ new_fillarea = FALSE;
+
+ /*
+ * if the client clip is different or moved OR the subwindowMode has
+ * changed OR the window's clip has changed since the last validation
+ * we need to recompute the composite clip
+ */
+
+ if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
+ (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS)))
+ {
+ miComputeCompositeClip (pGC, pDrawable);
+#ifdef NO_ONE_RECT
+ devPriv->oneRect = FALSE;
+#else
+ oneRect = REGION_NUM_RECTS(pGC->pCompositeClip) == 1;
+ if (oneRect != devPriv->oneRect)
+ new_line = TRUE;
+ devPriv->oneRect = oneRect;
+#endif
+ }
+
+ mask = changes;
+ while (mask) {
+ index = lowbit (mask);
+ mask &= ~index;
+
+ /*
+ * this switch acculmulates a list of which procedures might have
+ * to change due to changes in the GC. in some cases (e.g.
+ * changing one 16 bit tile for another) we might not really need
+ * a change, but the code is being paranoid. this sort of batching
+ * wins if, for example, the alu and the font have been changed,
+ * or any other pair of items that both change the same thing.
+ */
+ switch (index) {
+ case GCFunction:
+ case GCForeground:
+ new_rrop = TRUE;
+ break;
+ case GCPlaneMask:
+ new_rrop = TRUE;
+ new_text = TRUE;
+ break;
+ case GCBackground:
+ break;
+ case GCLineStyle:
+ case GCLineWidth:
+ new_line = TRUE;
+ break;
+ case GCJoinStyle:
+ case GCCapStyle:
+ break;
+ case GCFillStyle:
+ new_text = TRUE;
+ new_fillspans = TRUE;
+ new_line = TRUE;
+ new_fillarea = TRUE;
+ break;
+ case GCFillRule:
+ break;
+ case GCTile:
+ new_fillspans = TRUE;
+ new_fillarea = TRUE;
+ break;
+ case GCStipple:
+ new_fillspans = TRUE;
+ new_fillarea = TRUE;
+ break;
+ case GCTileStipXOrigin:
+ case GCTileStipYOrigin:
+ break;
+ case GCFont:
+ new_text = TRUE;
+ break;
+ case GCSubwindowMode:
+ case GCGraphicsExposures:
+ case GCClipXOrigin:
+ case GCClipYOrigin:
+ case GCClipMask:
+ case GCDashOffset:
+ case GCDashList:
+ case GCArcMode:
+ default:
+ break;
+ }
+ }
+
+ /*
+ * If the drawable has changed, ensure suitable
+ * entries are in the proc vector.
+ */
+ if (pDrawable->serialNumber != (pGC->serialNumber & (DRAWABLE_SERIAL_BITS)))
+ new_fillspans = TRUE; /* deal with FillSpans later */
+
+ if (new_rrop)
+ {
+ int old_rrop;
+
+ old_rrop = devPriv->rop;
+ devPriv->rop = cfbReduceRasterOp (pGC->alu, pGC->fgPixel,
+ pGC->planemask,
+ &devPriv->and, &devPriv->xor);
+ if (old_rrop == devPriv->rop)
+ new_rrop = FALSE;
+ else
+ {
+#ifdef PIXEL_ADDR
+ new_line = TRUE;
+#endif
+#ifdef WriteBitGroup
+ new_text = TRUE;
+#endif
+ new_fillspans = TRUE;
+ new_fillarea = TRUE;
+ }
+ }
+
+ if(!pGC->ops)
+ pGC->ops = & cfb24_32NonTEOps;
+
+ if (new_rrop || new_fillspans || new_text || new_fillarea || new_line)
+ {
+ GCOps *newops;
+
+ if ((newops = cfb24_32MatchCommon (pGC, devPriv)))
+ {
+ if (pGC->ops->devPrivate.val)
+ miDestroyGCOps (pGC->ops);
+ pGC->ops = newops;
+ new_rrop = new_line = new_fillspans = new_text = new_fillarea = 0;
+ }
+ else
+ {
+ if (!pGC->ops->devPrivate.val)
+ {
+ pGC->ops = miCreateGCOps (pGC->ops);
+ pGC->ops->devPrivate.val = 1;
+ }
+ }
+ }
+
+ /* deal with the changes we've collected */
+ if (new_line)
+ {
+ pGC->ops->FillPolygon = miFillPolygon;
+#ifdef NO_ONE_RECT
+ if (pGC->fillStyle == FillSolid)
+ {
+ switch (devPriv->rop) {
+ case GXcopy:
+ pGC->ops->FillPolygon = cfbFillPoly1RectCopy;
+ break;
+ default:
+ pGC->ops->FillPolygon = cfbFillPoly1RectGeneral;
+ break;
+ }
+ }
+#else
+ if (devPriv->oneRect && pGC->fillStyle == FillSolid)
+ {
+ switch (devPriv->rop) {
+ case GXcopy:
+ pGC->ops->FillPolygon = cfbFillPoly1RectCopy;
+ break;
+ default:
+ pGC->ops->FillPolygon = cfbFillPoly1RectGeneral;
+ break;
+ }
+ }
+#endif
+ if (pGC->lineWidth == 0)
+ {
+#ifdef PIXEL_ADDR
+ if ((pGC->lineStyle == LineSolid) && (pGC->fillStyle == FillSolid))
+ {
+ switch (devPriv->rop)
+ {
+ case GXxor:
+ pGC->ops->PolyArc = cfbZeroPolyArcSS8Xor;
+ break;
+ case GXcopy:
+ pGC->ops->PolyArc = cfbZeroPolyArcSS8Copy;
+ break;
+ default:
+ pGC->ops->PolyArc = cfbZeroPolyArcSS8General;
+ break;
+ }
+ }
+ else
+#endif
+ pGC->ops->PolyArc = miZeroPolyArc;
+ }
+ else
+ pGC->ops->PolyArc = miPolyArc;
+ pGC->ops->PolySegment = miPolySegment;
+ switch (pGC->lineStyle)
+ {
+ case LineSolid:
+ if(pGC->lineWidth == 0)
+ {
+ if (pGC->fillStyle == FillSolid)
+ {
+#if defined(PIXEL_ADDR) && !defined(NO_ONE_RECT)
+ if (devPriv->oneRect &&
+ ((pDrawable->x >= pGC->pScreen->width - 32768) &&
+ (pDrawable->y >= pGC->pScreen->height - 32768)))
+ {
+ pGC->ops->Polylines = cfb8LineSS1Rect;
+ pGC->ops->PolySegment = cfb8SegmentSS1Rect;
+ } else
+#endif
+#ifdef NO_ONE_RECT
+ {
+ pGC->ops->Polylines = cfb8LineSS1Rect;
+ pGC->ops->PolySegment = cfb8SegmentSS1Rect;
+ }
+#else
+ {
+ pGC->ops->Polylines = cfbLineSS;
+ pGC->ops->PolySegment = cfbSegmentSS;
+ }
+#endif
+ }
+ else
+ pGC->ops->Polylines = miZeroLine;
+ }
+ else
+ pGC->ops->Polylines = miWideLine;
+ break;
+ case LineOnOffDash:
+ case LineDoubleDash:
+ if (pGC->lineWidth == 0 && pGC->fillStyle == FillSolid)
+ {
+ pGC->ops->Polylines = cfbLineSD;
+ pGC->ops->PolySegment = cfbSegmentSD;
+ } else
+ pGC->ops->Polylines = miWideDash;
+ break;
+ }
+ }
+
+ if (new_text && (pGC->font))
+ {
+ if (FONTMAXBOUNDS(pGC->font,rightSideBearing) -
+ FONTMINBOUNDS(pGC->font,leftSideBearing) > 32 ||
+ FONTMINBOUNDS(pGC->font,characterWidth) < 0)
+ {
+ pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
+ pGC->ops->ImageGlyphBlt = miImageGlyphBlt;
+ }
+ else
+ {
+#ifdef WriteBitGroup
+ if (pGC->fillStyle == FillSolid)
+ {
+ if (devPriv->rop == GXcopy)
+ pGC->ops->PolyGlyphBlt = cfbPolyGlyphBlt8;
+ else
+#ifdef FOUR_BIT_CODE
+ pGC->ops->PolyGlyphBlt = cfbPolyGlyphRop8;
+#else
+ pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
+#endif
+ }
+ else
+#endif
+ pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
+ /* special case ImageGlyphBlt for terminal emulator fonts */
+#if !defined(WriteBitGroup) || PSZ == 8
+ if (TERMINALFONT(pGC->font) &&
+ (pGC->planemask & PMSK) == PMSK
+#ifdef FOUR_BIT_CODE
+ && FONTMAXBOUNDS(pGC->font,characterWidth) >= PGSZB
+#endif
+ )
+ {
+ pGC->ops->ImageGlyphBlt = useTEGlyphBlt;
+ }
+ else
+#endif
+ {
+#ifdef WriteBitGroup
+ if (devPriv->rop == GXcopy &&
+ pGC->fillStyle == FillSolid &&
+ (pGC->planemask & PMSK) == PMSK)
+ pGC->ops->ImageGlyphBlt = cfbImageGlyphBlt8;
+ else
+#endif
+ pGC->ops->ImageGlyphBlt = miImageGlyphBlt;
+ }
+ }
+ }
+
+
+ if (new_fillspans) {
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ switch (devPriv->rop) {
+ case GXcopy:
+ pGC->ops->FillSpans = cfbSolidSpansCopy;
+ break;
+ case GXxor:
+ pGC->ops->FillSpans = cfbSolidSpansXor;
+ break;
+ default:
+ pGC->ops->FillSpans = cfbSolidSpansGeneral;
+ break;
+ }
+ break;
+ case FillTiled:
+ pGC->ops->FillSpans = cfbUnnaturalTileFS;
+ break;
+ case FillStippled:
+ case FillOpaqueStippled:
+ pGC->ops->FillSpans = cfbUnnaturalStippleFS;
+ break;
+ default:
+ FatalError("cfbValidateGC: illegal fillStyle\n");
+ }
+ } /* end of new_fillspans */
+
+ if (new_fillarea) {
+#ifndef FOUR_BIT_CODE
+ pGC->ops->PolyFillRect = miPolyFillRect;
+ if (pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled)
+ {
+ pGC->ops->PolyFillRect = cfbPolyFillRect;
+ }
+#endif
+#ifdef FOUR_BIT_CODE
+#ifndef LOWMEMFTPT
+ pGC->ops->PushPixels = mfbPushPixels;
+#else
+ pGC->ops->PushPixels = miPushPixels;
+#endif /* ifndef LOWMEMFTPT */
+ if (pGC->fillStyle == FillSolid && devPriv->rop == GXcopy)
+ pGC->ops->PushPixels = cfbPushPixels8;
+#endif
+ pGC->ops->PolyFillArc = miPolyFillArc;
+ if (pGC->fillStyle == FillSolid)
+ {
+ switch (devPriv->rop)
+ {
+ case GXcopy:
+ pGC->ops->PolyFillArc = cfbPolyFillArcSolidCopy;
+ break;
+ default:
+ pGC->ops->PolyFillArc = cfbPolyFillArcSolidGeneral;
+ break;
+ }
+ }
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbgcmisc.c b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbgcmisc.c
new file mode 100644
index 000000000..8c4f98db2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbgcmisc.c
@@ -0,0 +1,170 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbgcmisc.c,v 1.1 1999/01/23 09:56:14 dawes Exp $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb24.h"
+#include "cfb32.h"
+#include "cfb24_32.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "region.h"
+
+#include "mistruct.h"
+#include "mibstore.h"
+#include "migc.h"
+
+
+static void cfb24_32ValidateGC(GCPtr, unsigned long, DrawablePtr);
+static void cfb24_32DestroyGC(GCPtr pGC);
+static void cfb24_32ChangeGC(GCPtr pGC, unsigned long mask);
+static void cfb24_32CopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst);
+
+static
+GCFuncs cfb24_32GCFuncs = {
+ cfb24_32ValidateGC,
+ cfb24_32ChangeGC,
+ cfb24_32CopyGC,
+ cfb24_32DestroyGC,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip,
+};
+
+static void
+cfb24_32DestroyGC(GCPtr pGC)
+{
+ cfb24_32GCPtr pGCPriv = CFB24_32_GET_GC_PRIVATE(pGC);
+
+ if (pGC->freeCompClip)
+ REGION_DESTROY(pGC->pScreen, pGC->pCompositeClip);
+ if(pGCPriv->Ops24bpp)
+ miDestroyGCOps(pGCPriv->Ops24bpp);
+ if(pGCPriv->Ops32bpp)
+ miDestroyGCOps(pGCPriv->Ops32bpp);
+}
+
+static void
+cfb24_32ChangeGC(
+ GCPtr pGC,
+ unsigned long mask
+){
+
+ if((mask & GCTile) && pGC->tile.pixmap && !pGC->tileIsPixel) {
+ PixmapPtr pPix = pGC->tile.pixmap;
+ cfb24_32PixmapPtr pixPriv = CFB24_32_GET_PIXMAP_PRIVATE(pPix);
+
+ if(pixPriv->pix && (pPix->refcnt != pixPriv->pix->refcnt))
+ pixPriv->pix->refcnt = pPix->refcnt;
+ }
+
+ return;
+}
+
+static void
+cfb24_32CopyGC(
+ GCPtr pGCSrc,
+ unsigned long changes,
+ GCPtr pGCDst
+){
+ if((changes & GCTile) && pGCDst->tile.pixmap && !pGCDst->tileIsPixel) {
+ PixmapPtr pPix = pGCDst->tile.pixmap;
+ cfb24_32PixmapPtr pixPriv = CFB24_32_GET_PIXMAP_PRIVATE(pPix);
+
+ if(pixPriv->pix && (pPix->refcnt != pixPriv->pix->refcnt))
+ pixPriv->pix->refcnt = pPix->refcnt;
+ }
+
+ return;
+}
+
+
+
+Bool
+cfb24_32CreateGC(GCPtr pGC)
+{
+ cfb24_32GCPtr pGCPriv;
+ cfbPrivGC *pPriv;
+
+ if (PixmapWidthPaddingInfo[pGC->depth].padPixelsLog2 == LOG2_BITMAP_PAD)
+ return (mfbCreateGC(pGC));
+
+ pGC->clientClip = NULL;
+ pGC->clientClipType = CT_NONE;
+ pGC->miTranslate = 1;
+ pGC->fExpose = TRUE;
+ pGC->freeCompClip = FALSE;
+ pGC->pRotatedPixmap = (PixmapPtr) NULL;
+
+ pPriv = cfbGetGCPrivate(pGC);
+ pPriv->rop = pGC->alu;
+ pPriv->oneRect = FALSE;
+
+ pGC->ops = NULL;
+ pGC->funcs = &cfb24_32GCFuncs;
+
+ pGCPriv = CFB24_32_GET_GC_PRIVATE(pGC);
+ pGCPriv->Ops24bpp = NULL;
+ pGCPriv->Ops32bpp = NULL;
+ pGCPriv->OpsAre24bpp = FALSE;
+ pGCPriv->changes = 0;
+
+ return TRUE;
+}
+
+
+static void
+cfb24_32ValidateGC(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+){
+ cfb24_32GCPtr pGCPriv = CFB24_32_GET_GC_PRIVATE(pGC);
+
+ if(pDraw->bitsPerPixel == 32) {
+ if(pGCPriv->OpsAre24bpp) {
+ int origChanges = changes;
+ pGC->ops = pGCPriv->Ops32bpp;
+ changes |= pGCPriv->changes;
+ pGCPriv->changes = origChanges;
+ pGCPriv->OpsAre24bpp = FALSE;
+ } else
+ pGCPriv->changes |= changes;
+
+ if((pGC->fillStyle == FillTiled) &&
+ (pGC->tile.pixmap->drawable.bitsPerPixel == 24)){
+ pGC->tile.pixmap = cfb24_32RefreshPixmap(pGC->tile.pixmap);
+ changes |= GCTile;
+ }
+
+ cfb24_32ValidateGC32(pGC, changes, pDraw);
+ pGCPriv->Ops32bpp = pGC->ops;
+ } else { /* bitsPerPixel == 24 */
+ if(!pGCPriv->OpsAre24bpp) {
+ int origChanges = changes;
+ pGC->ops = pGCPriv->Ops24bpp;
+ changes |= pGCPriv->changes;
+ pGCPriv->changes = origChanges;
+ pGCPriv->OpsAre24bpp = TRUE;
+ } else
+ pGCPriv->changes |= changes;
+
+ if((pGC->fillStyle == FillTiled) &&
+ (pGC->tile.pixmap->drawable.bitsPerPixel == 32)){
+ pGC->tile.pixmap = cfb24_32RefreshPixmap(pGC->tile.pixmap);
+ changes |= GCTile;
+ }
+
+ cfb24_32ValidateGC24(pGC, changes, pDraw);
+ pGCPriv->Ops24bpp = pGC->ops;
+ }
+
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbimage.c b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbimage.c
new file mode 100644
index 000000000..cae24ac80
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbimage.c
@@ -0,0 +1,95 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbimage.c,v 1.2 1999/08/29 12:21:05 dawes Exp $ */
+
+#include "X.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb24.h"
+#include "cfb32.h"
+#include "cfb24_32.h"
+#include "servermd.h"
+#include "mi.h"
+
+
+void
+cfb24_32GetImage (
+ DrawablePtr pDraw,
+ int sx, int sy, int w, int h,
+ unsigned int format,
+ unsigned long planemask,
+ char *pdstLine
+){
+ if(!w || !h) return;
+
+ if(pDraw->bitsPerPixel != 24) {
+ cfb32GetImage(pDraw, sx, sy, w, h, format, planemask, pdstLine);
+ return;
+ } else if (format == ZPixmap) {
+ BoxRec box;
+ DDXPointRec ptSrc;
+ RegionRec rgnDst;
+ ScreenPtr pScreen;
+ PixmapPtr pPixmap;
+
+ pScreen = pDraw->pScreen;
+ pPixmap = GetScratchPixmapHeader(pScreen, w, h, 24, 32,
+ PixmapBytePad(w,24), (pointer)pdstLine);
+ if (!pPixmap)
+ return;
+ if ((planemask & 0x00ffffff) != 0x00ffffff)
+ bzero((char *)pdstLine, pPixmap->devKind * h);
+ ptSrc.x = sx + pDraw->x;
+ ptSrc.y = sy + pDraw->y;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = w;
+ box.y2 = h;
+ REGION_INIT(pScreen, &rgnDst, &box, 1);
+ cfbDoBitblt24To32(pDraw, (DrawablePtr)pPixmap, GXcopy, &rgnDst,
+ &ptSrc, planemask, 0);
+ REGION_UNINIT(pScreen, &rgnDst);
+ FreeScratchPixmapHeader(pPixmap);
+ } else
+ miGetImage(pDraw, sx, sy, w, h, format, planemask, pdstLine);
+}
+
+
+void
+cfb24_32GetSpans(
+ DrawablePtr pDraw,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pDst
+){
+ int pitch, i;
+ CARD8 *ptr, *ptrBase;
+
+ if(pDraw->bitsPerPixel != 24){
+ cfb32GetSpans(pDraw, wMax, ppt, pwidth, nspans, pDst);
+ return;
+ }
+
+ /* gotta get spans from a 24 bpp window */
+ cfbGetByteWidthAndPointer(pDraw, pitch, ptrBase);
+
+ while(nspans--) {
+ ptr = ptrBase + (ppt->y * pitch) + (ppt->x * 3);
+
+ for(i = *pwidth; i--; ptr += 3, pDst += 4) {
+ /* this is used so infrequently that it's not worth optimizing */
+ pDst[0] = ptr[0];
+ pDst[1] = ptr[1];
+ pDst[2] = ptr[2];
+ }
+
+ ppt++; pwidth++;
+ }
+}
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbpixmap.c b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbpixmap.c
new file mode 100644
index 000000000..6e566c253
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbpixmap.c
@@ -0,0 +1,145 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbpixmap.c,v 1.2 1999/01/31 12:22:15 dawes Exp $ */
+
+#include "Xmd.h"
+#include "servermd.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "mi.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb24_32.h"
+
+
+PixmapPtr
+cfb24_32CreatePixmap (
+ ScreenPtr pScreen,
+ int width,
+ int height,
+ int depth
+){
+ cfb24_32PixmapPtr pPixPriv;
+ PixmapPtr pPix;
+ int size, bpp, pitch;
+
+ /* All depth 24 pixmaps are 24bpp unless the caller is allocating
+ its own data (width == 0) */
+
+ if(depth == 1) {
+ pitch = ((width + 31) >> 5) << 2;
+ bpp = 1;
+ } else { /* depth == 24 */
+ pitch = ((width * 3) + 3) & ~3L;
+ bpp = (width && height) ? 24 : 32;
+ }
+
+ size = height * pitch;
+ pPix = AllocatePixmap(pScreen, size);
+ if (!pPix)
+ return NullPixmap;
+ pPix->drawable.type = DRAWABLE_PIXMAP;
+ pPix->drawable.class = 0;
+ pPix->drawable.pScreen = pScreen;
+ pPix->drawable.depth = depth;
+ pPix->drawable.bitsPerPixel = bpp;
+ pPix->drawable.id = 0;
+ pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPix->drawable.x = 0;
+ pPix->drawable.y = 0;
+ pPix->drawable.width = width;
+ pPix->drawable.height = height;
+ pPix->devKind = pitch;
+ pPix->refcnt = 1;
+ pPix->devPrivate.ptr = size ?
+ (pointer)((char*)pPix + pScreen->totalPixmapSize) : NULL;
+
+ pPixPriv = CFB24_32_GET_PIXMAP_PRIVATE(pPix);
+ pPixPriv->pix = NULL; /* no clone yet */
+ pPixPriv->freePrivate = FALSE;
+
+ return pPix;
+}
+
+Bool
+cfb24_32DestroyPixmap(PixmapPtr pPix)
+{
+ cfb24_32PixmapPtr pPriv = CFB24_32_GET_PIXMAP_PRIVATE(pPix);
+ PixmapPtr pClone = pPriv->pix;
+
+ if(pClone) {
+ cfb24_32PixmapPtr cPriv = CFB24_32_GET_PIXMAP_PRIVATE(pClone);
+ int refcnt = pPix->refcnt;
+ cPriv->pix = NULL; /* avoid looping back */
+
+ if(refcnt != pClone->refcnt)
+ ErrorF("Pixmap refcnt mismatch in DestroyPixmap()\n");
+
+ (*pPix->drawable.pScreen->DestroyPixmap)(pClone);
+
+ if(refcnt > 1)
+ cPriv->pix = pPix;
+ }
+
+ if(--pPix->refcnt)
+ return TRUE;
+
+ if(pPriv->freePrivate)
+ xfree(pPix->devPrivate.ptr);
+ xfree(pPix);
+
+ return TRUE;
+}
+
+PixmapPtr
+cfb24_32RefreshPixmap(PixmapPtr pPix)
+{
+ cfb24_32PixmapPtr newPixPriv, pixPriv = CFB24_32_GET_PIXMAP_PRIVATE(pPix);
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ int width = pPix->drawable.width;
+ int height = pPix->drawable.height;
+ GCPtr pGC;
+
+ if(pPix->drawable.bitsPerPixel == 24) {
+ if(!pixPriv->pix) { /* need to make a 32bpp clone */
+ int pitch = width << 2;
+ unsigned char* data;
+ PixmapPtr newPix;
+
+ if(!(data = (unsigned char*)xalloc(pitch * height)))
+ FatalError("Out of memory\n");
+
+ /* cfb24_32CreatePixmap will make a 32bpp header for us */
+ newPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, 24);
+ newPix->devKind = pitch;
+ newPix->devPrivate.ptr = (pointer)data;
+ newPix->drawable.width = width;
+ newPix->drawable.height = height;
+ newPix->refcnt = pPix->refcnt;
+ pixPriv->pix = newPix;
+ newPixPriv = CFB24_32_GET_PIXMAP_PRIVATE(newPix);
+ newPixPriv->pix = pPix;
+ newPixPriv->freePrivate = TRUE;
+ }
+ } else { /* bitsPerPixel == 32 */
+ if(!pixPriv->pix) { /* need to make a 32bpp clone */
+
+ /* cfb24_32CreatePixmap will make a 24bpp pixmap for us */
+ pixPriv->pix = (*pScreen->CreatePixmap)(pScreen, width, height, 24);
+ pixPriv->pix->refcnt = pPix->refcnt;
+ newPixPriv = CFB24_32_GET_PIXMAP_PRIVATE(pixPriv->pix);
+ newPixPriv->pix = pPix;
+ }
+ }
+
+ if(pPix->refcnt != pixPriv->pix->refcnt)
+ ErrorF("Pixmap refcnt mismatch in RefreshPixmap()\n");
+
+ pGC = GetScratchGC(24, pScreen);
+ ValidateGC((DrawablePtr)pixPriv->pix, pGC);
+ (*pGC->ops->CopyArea)((DrawablePtr)pPix, (DrawablePtr)pixPriv->pix,
+ pGC, 0, 0, width, height, 0, 0);
+ FreeScratchGC(pGC);
+
+ return pixPriv->pix;
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbscrinit.c b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbscrinit.c
new file mode 100644
index 000000000..0940963a8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbscrinit.c
@@ -0,0 +1,192 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbscrinit.c,v 1.4 1999/08/14 10:50:16 dawes Exp $ */
+
+
+#include "X.h"
+#include "Xmd.h"
+#include "misc.h"
+#include "servermd.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "resource.h"
+#include "colormap.h"
+#include "colormapst.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb24.h"
+#include "cfb32.h"
+#include "cfb24_32.h"
+#include "mi.h"
+#include "micmap.h"
+#include "mistruct.h"
+#include "dix.h"
+#include "mibstore.h"
+
+/* CAUTION: We require that cfb24 and cfb32 were NOT
+ compiled with CFB_NEED_SCREEN_PRIVATE */
+
+static BSFuncRec cfb24_32BSFuncRec = {
+ cfb24SaveAreas,
+ cfb24RestoreAreas,
+ (BackingStoreSetClipmaskRgnProcPtr) 0,
+ (BackingStoreGetImagePixmapProcPtr) 0,
+ (BackingStoreGetSpansPixmapProcPtr) 0,
+};
+
+
+int cfb24_32GCIndex = 1;
+int cfb24_32PixmapIndex = 1;
+
+static unsigned long cfb24_32Generation = 0;
+extern WindowPtr *WindowTable;
+
+static Bool
+cfb24_32AllocatePrivates(ScreenPtr pScreen)
+{
+ if(cfb24_32Generation != serverGeneration) {
+ if( ((cfb24_32GCIndex = AllocateGCPrivateIndex()) < 0) |
+ ((cfb24_32PixmapIndex = AllocatePixmapPrivateIndex()) < 0))
+ return FALSE;
+ cfb24_32Generation = serverGeneration;
+ }
+
+
+ /* All cfb will have the same GC and Window private indicies */
+ if(!mfbAllocatePrivates(pScreen,&cfbWindowPrivateIndex, &cfbGCPrivateIndex))
+ return FALSE;
+
+ /* The cfb indicies are the mfb indicies. Reallocating them resizes them */
+ if(!AllocateWindowPrivate(pScreen,cfbWindowPrivateIndex,sizeof(cfbPrivWin)))
+ return FALSE;
+
+ if(!AllocateGCPrivate(pScreen, cfbGCPrivateIndex, sizeof(cfbPrivGC)))
+ return FALSE;
+
+ if(!AllocateGCPrivate(pScreen, cfb24_32GCIndex, sizeof(cfb24_32GCRec)))
+ return FALSE;
+
+ if(!AllocatePixmapPrivate(
+ pScreen, cfb24_32PixmapIndex, sizeof(cfb24_32PixmapRec)))
+ return FALSE;
+
+
+ return TRUE;
+}
+
+static Bool
+cfb24_32SetupScreen(
+ ScreenPtr pScreen,
+ pointer pbits, /* pointer to screen bitmap */
+ int xsize, int ysize, /* in pixels */
+ int dpix, int dpiy, /* dots per inch */
+ int width /* pixel width of frame buffer */
+){
+ if (!cfb24_32AllocatePrivates(pScreen))
+ return FALSE;
+ pScreen->defColormap = FakeClientID(0);
+ /* let CreateDefColormap do whatever it wants for pixels */
+ pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0;
+ pScreen->QueryBestSize = mfbQueryBestSize;
+ /* SaveScreen */
+ pScreen->GetImage = cfb24_32GetImage;
+ pScreen->GetSpans = cfb24_32GetSpans;
+ pScreen->CreateWindow = cfb24_32CreateWindow;
+ pScreen->DestroyWindow = cfb24_32DestroyWindow;
+ pScreen->PositionWindow = cfb24_32PositionWindow;
+ pScreen->ChangeWindowAttributes = cfb24_32ChangeWindowAttributes;
+ pScreen->RealizeWindow = cfb24MapWindow; /* OK */
+ pScreen->UnrealizeWindow = cfb24UnmapWindow; /* OK */
+ pScreen->PaintWindowBackground = cfb24PaintWindow; /* OK */
+ pScreen->PaintWindowBorder = cfb24PaintWindow; /* OK */
+ pScreen->CopyWindow = cfb24_32CopyWindow;
+ pScreen->CreatePixmap = cfb24_32CreatePixmap;
+ pScreen->DestroyPixmap = cfb24_32DestroyPixmap;
+ pScreen->RealizeFont = mfbRealizeFont;
+ pScreen->UnrealizeFont = mfbUnrealizeFont;
+ pScreen->CreateGC = cfb24_32CreateGC;
+ pScreen->CreateColormap = miInitializeColormap;
+ pScreen->DestroyColormap = (void (*)())NoopDDA;
+ pScreen->InstallColormap = miInstallColormap;
+ pScreen->UninstallColormap = miUninstallColormap;
+ pScreen->ListInstalledColormaps = miListInstalledColormaps;
+ pScreen->StoreColors = (void (*)())NoopDDA;
+ pScreen->ResolveColor = miResolveColor;
+ pScreen->BitmapToRegion = mfbPixmapToRegion;
+
+ mfbRegisterCopyPlaneProc (pScreen, miCopyPlane);
+ return TRUE;
+}
+
+typedef struct {
+ pointer pbits;
+ int width;
+} miScreenInitParmsRec, *miScreenInitParmsPtr;
+
+static Bool
+cfb24_32CreateScreenResources(ScreenPtr pScreen)
+{
+ miScreenInitParmsPtr pScrInitParms;
+ int pitch;
+ Bool retval;
+
+ /* get the pitch before mi destroys it */
+ pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate;
+ pitch = BitmapBytePad(pScrInitParms->width * 24);
+
+ if((retval = miCreateScreenResources(pScreen))) {
+ /* fix the screen pixmap */
+ PixmapPtr pPix = (PixmapPtr)pScreen->devPrivate;
+ pPix->drawable.bitsPerPixel = 24;
+ pPix->devKind = pitch;
+ }
+
+ return retval;
+}
+
+
+static Bool
+cfb24_32FinishScreenInit(
+ ScreenPtr pScreen,
+ pointer pbits, /* pointer to screen bitmap */
+ int xsize, int ysize, /* in pixels */
+ int dpix, int dpiy, /* dots per inch */
+ int width /* pixel width of frame buffer */
+){
+ VisualPtr visuals;
+ DepthPtr depths;
+ int nvisuals;
+ int ndepths;
+ int rootdepth;
+ VisualID defaultVisual;
+
+ rootdepth = 0;
+ if (!miInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
+ &defaultVisual,((unsigned long)1<<(24-1)), 8, -1))
+ return FALSE;
+ if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
+ rootdepth, ndepths, depths,
+ defaultVisual, nvisuals, visuals))
+ return FALSE;
+
+ pScreen->BackingStoreFuncs = cfb24_32BSFuncRec;
+ pScreen->CreateScreenResources = cfb24_32CreateScreenResources;
+ pScreen->CloseScreen = cfb32CloseScreen; /* OK */
+ pScreen->GetScreenPixmap = cfb32GetScreenPixmap; /* OK */
+ pScreen->SetScreenPixmap = cfb32SetScreenPixmap; /* OK */
+ return TRUE;
+}
+
+Bool
+cfb24_32ScreenInit(
+ ScreenPtr pScreen,
+ pointer pbits, /* pointer to screen bitmap */
+ int xsize, int ysize, /* in pixels */
+ int dpix, int dpiy, /* dots per inch */
+ int width /* pixel width of frame buffer */
+){
+ if (!cfb24_32SetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width))
+ return FALSE;
+ return cfb24_32FinishScreenInit(
+ pScreen, pbits, xsize, ysize, dpix, dpiy, width);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbwindow.c b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbwindow.c
new file mode 100644
index 000000000..ced584d09
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbwindow.c
@@ -0,0 +1,124 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf24_32bpp/cfbwindow.c,v 1.2 1999/02/28 11:19:50 dawes Exp $ */
+
+#include "X.h"
+#include "windowstr.h"
+#include "regionstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb24.h"
+#include "cfb32.h"
+#include "cfb24_32.h"
+#include "mi.h"
+
+
+Bool
+cfb24_32CreateWindow(WindowPtr pWin)
+{
+ cfbPrivWin *pPrivWin = cfbGetWindowPrivate(pWin);
+
+ pPrivWin->fastBackground = FALSE;
+ pPrivWin->fastBorder = FALSE;
+
+ pWin->drawable.bitsPerPixel = 24;
+ return TRUE;
+}
+
+
+Bool
+cfb24_32DestroyWindow(WindowPtr pWin)
+{
+ return TRUE;
+}
+
+Bool
+cfb24_32PositionWindow(
+ WindowPtr pWin,
+ int x, int y
+){
+ return TRUE;
+}
+
+
+Bool
+cfb24_32ChangeWindowAttributes(
+ WindowPtr pWin,
+ unsigned long mask
+){
+ cfb24_32PixmapPtr pixPriv;
+ PixmapPtr pPix;
+
+ /* The dix layer may have incremented a refcnt. We sync them here */
+
+ if((mask & CWBackPixmap) && (pWin->backgroundState == BackgroundPixmap)) {
+ pPix = pWin->background.pixmap;
+ pixPriv = CFB24_32_GET_PIXMAP_PRIVATE(pPix);
+
+ if(pixPriv->pix && (pPix->refcnt != pixPriv->pix->refcnt))
+ pixPriv->pix->refcnt = pPix->refcnt;
+
+ if(pPix->drawable.bitsPerPixel != 24)
+ pWin->background.pixmap = cfb24_32RefreshPixmap(pPix);
+ }
+
+ if((mask & CWBorderPixmap) && !pWin->borderIsPixel) {
+ pPix = pWin->border.pixmap;
+ pixPriv = CFB24_32_GET_PIXMAP_PRIVATE(pPix);
+
+ if(pixPriv->pix && (pPix->refcnt != pixPriv->pix->refcnt))
+ pixPriv->pix->refcnt = pPix->refcnt;
+
+ if(pPix->drawable.bitsPerPixel != 24)
+ pWin->border.pixmap = cfb24_32RefreshPixmap(pPix);
+ }
+
+ return TRUE;
+}
+
+extern WindowPtr *WindowTable;
+
+void
+cfb24_32CopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc
+){
+ DDXPointPtr pptSrc, ppt;
+ RegionRec rgnDst;
+ BoxPtr pbox;
+ int i, nbox, dx, dy;
+ WindowPtr pwinRoot;
+
+ pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];
+
+ REGION_INIT(pWin->drawable.pScreen, &rgnDst, NullBox, 0);
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
+ REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst,
+ &pWin->borderClip, prgnSrc);
+
+ pbox = REGION_RECTS(&rgnDst);
+ nbox = REGION_NUM_RECTS(&rgnDst);
+ if(!nbox ||
+ !(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec))))
+ {
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+ return;
+ }
+ ppt = pptSrc;
+
+ for (i = nbox; --i >= 0; ppt++, pbox++)
+ {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ cfb24_32DoBitblt24To24GXcopy((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
+ GXcopy, &rgnDst, pptSrc, ~0L, 0);
+ DEALLOCATE_LOCAL(pptSrc);
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/Imakefile b/xc/programs/Xserver/hw/xfree86/xf4bpp/Imakefile
new file mode 100644
index 000000000..65aaab080
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/Imakefile
@@ -0,0 +1,61 @@
+XCOMM $XConsortium: Imakefile /main/8 1996/09/28 17:25:44 rws $
+
+
+
+
+
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/Imakefile,v 1.5 1999/08/14 10:50:16 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#if DoLoadableServer
+XFMODSRC = vgamodule.c
+XFMODOBJ = vgamodule.o
+#endif
+
+SRCS = ppcArea.c ppcBStore.c ppcClip.c ppcCpArea.c ppcCReduce.c ppcDepth.c \
+ ppcFillRct.c ppcWinFS.c ppcPixFS.c ppcGC.c ppcGetSp.c ppcImg.c \
+ ppcPixmap.c ppcPntWin.c ppcPolyPnt.c ppcPolyRec.c ppcQuery.c \
+ ppcRslvC.c ppcSetSp.c ppcWindow.c ppcIO.c \
+ emulOpStip.c emulRepAre.c emulTile.c \
+ vgaGC.c vgaBitBlt.c vgaImages.c vgaStipple.c vgaSolid.c \
+ offscreen.c wm3.c \
+ mfbimggblt.c mfbline.c mfbseg.c mfbhrzvert.c mfbbres.c mfbbresd.c \
+ mfbfillarc.c mfbzerarc.c \
+ $(XFMODSRC)
+
+OBJS = ppcArea.o ppcBStore.o ppcClip.o ppcCpArea.o ppcCReduce.o ppcDepth.o \
+ ppcFillRct.o ppcWinFS.o ppcPixFS.o ppcGC.o ppcGetSp.o ppcImg.o \
+ ppcPixmap.o ppcPntWin.o ppcPolyPnt.o ppcPolyRec.o ppcQuery.o \
+ ppcRslvC.o ppcSetSp.o ppcWindow.o ppcIO.o \
+ emulOpStip.o emulRepAre.o emulTile.o \
+ vgaGC.o vgaBitBlt.o vgaImages.o vgaStipple.o vgaSolid.o \
+ offscreen.o wm3.o \
+ mfbimggblt.o mfbline.o mfbseg.o mfbhrzvert.o mfbbres.o mfbbresd.o \
+ mfbfillarc.o mfbzerarc.o \
+ $(XFMODOBJ)
+
+DEFINES = -DXF86VGA16
+
+INCLUDES = -I. -I$(XF86SRC)/xf1bpp -I$(SERVERSRC)/mfb \
+ -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mi -I$(SERVERSRC)/include \
+ -I$(XF86OSSRC) -I$(XF86COMSRC) \
+ -I$(FONTINCSRC) -I$(XINCLUDESRC)
+
+ModuleObjectRule()
+LibraryModuleTarget(xf4bpp,$(OBJS))
+LintLibraryTarget(xf4bpp,$(SRCS))
+NormalLintTarget($(LINTDEFS) $(SRCS))
+
+ObjectFromSpecialSource(mfbseg,mfbline,-DPOLYSEGMENT)
+
+InstallLibraryModule(xf4bpp,$(MODULEDIR),.)
+
+#ifndef OS2Architecture
+DependTarget()
+#endif
+
+InstallDriverSDKLibraryModule(xf4bpp,$(DRIVERSDKMODULEDIR),.)
+
+InstallDriverSDKNonExecFile(xf4bpp.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/NOTES b/xc/programs/Xserver/hw/xfree86/xf4bpp/NOTES
new file mode 100644
index 000000000..f9ccc95c1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/NOTES
@@ -0,0 +1,194 @@
+This code originally hails from IBM. It was ported to an early XFree86 by
+Gertjan Akkerman, whose BUGS file I append here.
+
+In turn, this is a port of Gertjan's work to the new server design. Among the
+changes are:
+
+- The removal of almost all unreferenced code.
+- The removal of this code's own copy of mfb (xf1bpp is used instead).
+- The removal of banking support (mibank is used instead).
+- External symbols were made static where this was sufficient.
+- The remaining external names were renamed to xf4bpp*.
+- Several minor cleanups too many to mention here.
+
+To understate the matter, this code is >UGLY<. This seems inherent in IBM's
+corporate culture. Be that as it may, it *does* survive X11R4's xtest
+(whatever that means these days...). For now, this is sufficient for 4bpp
+support in the new design, but at some point, I'll have to sit down and
+rewrite this from scratch. A more technical justification for a rewrite is
+that the pixmap format is 8bpp, instead of 4bpp, which is causing me to
+pepper the rest of the server with unclean accomodations.
+
+Marc.
+
+===============================================================================
+Section 1: From IBM's X11R4 contribution towards XFree86.
+
+This section describes what I did to obtain a 16 colour vga server.
+
+I started with the SYSV, ppc, vga and common directories from IBM's X11R4
+contribution. Those directories have the following function:
+1. SYSV implements the mouse and keyboard.
+2. ppc is a generic layer implementing ddx in terms of drawing operations
+ through rectangles. (With spans as a boundary case: height = 1.)
+3. vga implements a layer of operations drawing through rectangles.
+4. common implements ddx initialization and quitting, and screen saving.
+
+I eliminated SYSV and common since the functionality provided therein is
+already provided in XFree86. Since XFree86 is actively being ported to
+new operating systems, while X11R4 is out of date, I preferred the XFree86
+code here above the SYSV and common code.
+Whatever functionality was still needed from common (default colormap
+initialization -- not much code) was moved into ppc.
+
+Since XFree86 uses the mi-provided software cursor code, IBM's software
+cursor code was deleted from ppc and vga. This is a pity, since it is
+expected that it is more efficient than mi's code, but the XFree86 mouse and
+keyboard code directly call mi, and I do not want to maintain the XFree86
+mouse and keyboard code.
+
+Since we cannot support a monolithic multi-screen server using all of the
+x11r4 contributed code yet, all multi screen code was deleted. This includes
+one header file containing a nasty copyright statement.
+
+Since glyph handling has changed between X11R4 and X11R5, the code handling
+glyphs was replaced by appropriate calls to mi.
+I hope it can be modified and put back one day.
+
+Provisionally, some code was added (viz. file vga/offscreen.c) to intercept
+calls to the rectangle drawing code when we are switched out of the VT.
+I hope this can be replaced by some window tree invalidation and GC validation
+scheme.
+
+
+Section 2: BUGS
+
+This section describes fixed and still unfixed bugs in this code.
+All bugs not labeled otherwise also occur in IBM's X11R4 code, and may be of
+interest to anybody using that code.
+
+1. (Fixed.)
+I found (and provisionally fixed) a bug in the IBM bitblit code:
+In file ddx/ibm/vga/vgaImages.c a function vgaReadColorImage is defined.
+When this function is used to read less than 8 pixels starting on a byte
+boundary it will always read precisely 8 pixels.
+Thus, when space is allocated for 4 or less pixels, it will write beyond
+the allocated space.
+Since the code is rather convoluted, this may not be apparent at first sight,
+but going through the code with an example shows the error.
+
+2. (Fixed.)
+In ppcPixmapFS.c, function ppcStipplePixmapFS there was a bug
+regarding the stipple origin: The horizontal origin is added while
+the vertical one is subtracted. The horizontal origin should be subtracted
+instead of added here.
+This bug gets visible when backing-store is enabled and one uses twm:
+the submenu icons get truncated on their left hand side.
+(In case you wonder why this bug appears: under those circumstances
+twm prepares its menus by drawing into an unmapped window.
+The miCopyPlane function uses the ppcStipplePixmap (and many others)
+to get the plane copied.)
+I also fixed this bug in the other routines (ppcOpStipplePixmapFS,
+ppcTilePixmapFS) in this file, although I had no visible clues for this.
+I hope this is appropriate.
+
+3. (Fixed.)
+I find it suspect that ppcSetSpans gives different output when one
+claims that an actually sorted list of spans is unsorted.
+The unsorted code is wrong, and should be made to look more like the sorted
+code. I.e., use ( xStart - ppt->x ) instead of ( xStart - pbox->x1 )
+
+4. (Fixed.)
+There used to be another bug that became visible when using twm and backing
+store: popping up a submenu, and moving the cursor upwards til it leaves the
+submenu, the submenu would disappears, as it should.
+But the submenu icon would not get restored, while it should be.
+10b. By replacing the clip-computing code in ppcValidateGC by that in
+cfbValidateGC, I *finally* fixed the disappearing twm menu icon problem.
+
+5. Added mfbRegisterCopyplaneProc call. [Its omission was an error on my
+ part.]
+ Fixing a server core dump in XTest.
+
+6. Fixed not-very-high tile bug in function ppcTileRect, file emulTile.c
+ (I.e., if the tile was higher than the area to be tiled, far too much
+ was drawn, causing server core dumps in XTest.)
+ Actually, "savey" ought to be used to determine the height of the tiles in
+ the top line to be tiled, instead of "pTile->drawable.height".
+7. A use of height where width was intended was fixed in ppcTileRect:
+ "savehcount = w / pTile->drawable.height;" should use "... .width" and
+ "savehcount = ( x + w - htarget ) / pTile->drawable.height;" too.
+
+8. Deleted overly clever code in ppcCReduce.c
+ (All code that tried to pre-compute how alu's could be replaced by
+ other alu's with inverted colors, etc. was deleted. I think it is
+ at least wrong for FillSolid.)
+
+9. Looked at suspicious code in ppcSetSp.c
+ "tmpx = *pdst;" was never updated during the loop. We took it out of the
+ initialization position of the for and moved it into the loop.
+
+10. Add xSrc := GC->patOrg.x + pDrawable.x and ySrc := ... in ppcPixmapFS.c,
+ functions ppcStipplePixmapFS, ppcOpStipplePixmapFS, and ppcTilePixmapFS.
+ This because stipple and tile origins are taken relative to the drawable.
+ Also use a "modulo" function that gets the cases of a negative stipple
+ or tile offset right. (When the stipple origin is to the right of or
+ below the origin of the drawable.)
+
+11. File vgaSolid.c, function vgaFillSolid:
+ Inverting is XORing with all ones. Not with the color we want to AND/OR
+ later. So we'll have to set the color to VGA_ALLPLANES
+ whenever we want to invert existing data, and reset it before the
+ AND/OR is done.
+ Also we replaced an outb( 0x3CF, tmp2 ) by the SetVideoGraphicsData( tmp2 )
+ it is representing. (Just a cosmetic replacement.)
+
+12. File vgaImages, function vgaDrawColorImage.
+ Moved a line "invert_existing_data = TRUE;" two lines down, past a case
+ label. Now it is also part of the code executed for GXorReverse, as it
+ should be.
+
+13. The pixmap FillSpans routines (file ppcPixmapFS.c) got somewhat better
+ after importing some code from ddx/ibm/vga. (A getbits function that does
+ wrapping.)
+ They were wrong for the FillStippled and FillOpaqueStippled modes.
+ I don't understand the old code. How could it handle stipples of a size not
+ an exact multiple of 32? (or 8, for that matter.)
+
+14. In function vgaBitBlt file vgaBitBlt.c, in the shortcuts for
+ GXSet, GXClear and GXInvert, the source (x0,y0) is accidentally operated
+ upon by vgaFillSolid, instead of the destination (x1,y1).
+
+15. Notice that in DoMonoSingle and DoMonoMany in file vgaStipple.c, the left
+ edge of the square to be stippled is treated wrong.
+ Correct would be to get the bits with getbits using offset xshift, and
+ to shift them right (x & 07) places.
+ [One might wish to use the variable tmp1 at this place, since it had been
+ set to (x & 07) at this place; but that is already re-used at this point.]
+ Also note that NeedValX is set wrong: The implicit assumption was that
+ stipples are more than 8 wide.
+ This only fixes the problem when miPushPixel is used instead of ppcPushPixel.
+ I think I should look some more into this.
+
+16. I took out some code of the CopyArea function, in which a no-op function
+ was called while a real one was needed. My fix does not completely work,
+ although it improved the behaviour of GetImage somewhat.
+
+17. After finding three kinds of errors in this single function,
+ -- the new kinds being the right side not being always written due to
+ an incorrect if scope, and the lower end not always being written due
+ to variables being updated at the wrong place --
+ (requiring modifications to be made at at least 10 places,
+ I decided to REWRITE the body of the ppcTileRect function from scratch.
+ This version simply computes all relevant margins in advance, and does
+ not try to reuse temporary variables. I leave that to the compiler.
+ (This was a maintenance and robustness nightmare anyway.)
+
+MORE NOTES:
+ It is funny that there are two files in mi that require compilation
+ with the proper #defines ( -DXF86VGA16 in my case ):
+ Besides the obvious mibitblt.c, there is also mipushpxl.c.
+
+
+
+$XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/NOTES,v 1.2 1998/07/25 16:59:26 dawes Exp $
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/OScompiler.h b/xc/programs/Xserver/hw/xfree86/xf4bpp/OScompiler.h
new file mode 100644
index 000000000..63ad85a8b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/OScompiler.h
@@ -0,0 +1,59 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/OScompiler.h,v 1.3 1999/01/31 12:22:15 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+/* $XConsortium: OScompiler.h /main/4 1996/02/21 17:56:09 kaleb $ */
+
+#ifndef __COMPILER_DEPENDANCIES__
+#define __COMPILER_DEPENDANCIES__
+
+#define MOVE( src, dst, length ) memcpy( dst, src, length)
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#define ABS(x) (((x)>0)?(x):-(x))
+
+#include "misc.h"
+#ifdef XFree86LOADER
+#include "xf86_ansic.h"
+#endif
+#include "compiler.h"
+
+#ifdef lint
+/* So that lint doesn't complain about constructs it doesn't understand */
+#ifdef volatile
+#undef volatile
+#endif
+#define volatile
+#ifdef const
+#undef const
+#endif
+#define const
+#ifdef signed
+#undef signed
+#endif
+#define signed
+#ifdef _ANSI_DECLS_
+#undef _ANSI_DECLS_
+#endif
+#endif
+
+#endif /* !__COMPILER_DEPENDANCIES__ */
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/emulOpStip.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/emulOpStip.c
new file mode 100644
index 000000000..e9ac98dc9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/emulOpStip.c
@@ -0,0 +1,100 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/emulOpStip.c,v 1.3 1999/06/06 08:48:54 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+/* $XConsortium: emulOpStip.c /main/4 1996/02/21 17:56:12 kaleb $ */
+
+/* ppc OpaqueStipple
+ *
+ * Based on the private stipple; does a foreground, and then an inverted
+ * on the background
+ *
+ */
+
+#include "xf4bpp.h"
+#include "OScompiler.h"
+#include "mfbmap.h"
+#include "mfb.h"
+
+void
+xf4bppOpaqueStipple( pWin, pStipple, fg, bg, alu, planes, x, y, w, h, xSrc, ySrc )
+WindowPtr pWin; /* GJA */
+register PixmapPtr pStipple ;
+unsigned long int fg ;
+unsigned long int bg ;
+int alu ;
+unsigned long int planes ;
+register int x, y, w, h ;
+int xSrc, ySrc ;
+{
+ /* DO BACKGROUND */
+ switch ( alu ) {
+ /* Easy Cases -- i.e. Final Result Doesn't Depend On Initial Dest. */
+ case GXclear: /* 0x0 Zero 0 */
+ case GXset: /* 0xf 1 */
+ /* Foreground And Background Are Both The Same !! */
+ xf4bppFillSolid( pWin, bg, alu, planes, x, y, w, h ) ;
+ case GXnoop: /* 0x5 dst */
+ break ;
+ case GXcopy: /* 0x3 src */
+ case GXcopyInverted: /* 0xc NOT src */
+ { /* Special Case Code */
+ register int vtarget, htarget ;
+
+ /* We Can Draw Just One Copy Then Blit The Rest !! */
+ /* Draw The One Copy */
+ htarget = MIN( w, pStipple->drawable.width ) ;
+ vtarget = MIN( h, pStipple->drawable.height ) ;
+
+ /* First The Background */
+ xf4bppFillSolid( pWin, bg, alu, planes, x, y,
+ htarget, vtarget ) ;
+ /* Then The Foreground */
+ xf4bppFillStipple( pWin, pStipple, fg, alu, planes,
+ x, y, htarget, vtarget,
+ xSrc, ySrc ) ;
+
+ /* Here We Double The Size Of The BLIT Each Iteration */
+ xf4bppReplicateArea(pWin, x, y, planes, w, h, htarget, vtarget);
+ }
+ break ;
+ default:
+ /* Hard Cases -- i.e. Final Result DOES Depend On Initial Dest. */
+ { /* Do The Background */
+ register int i, j;
+ register PixmapPtr pInvPixmap = xf4bppCopyPixmap( pStipple ) ;
+ register unsigned char *data = pInvPixmap->devPrivate.ptr ;
+
+ /* INVERT PIXMAP OK, jeff, this is for you */
+ for ( i = pInvPixmap->drawable.height ; i-- ; )
+ for ( j = pInvPixmap->devKind ; j-- ; data++ )
+ *data = ~ ( *data ) ;
+
+ xf4bppFillStipple( pWin, pInvPixmap, bg, alu, planes, x, y, w, h, xSrc, ySrc );
+ mfbDestroyPixmap( pInvPixmap ) ;
+ /* DO FOREGROUND */
+ xf4bppFillStipple( pWin, pStipple, fg, alu, planes, x, y, w, h, xSrc, ySrc );
+ }
+ break ;
+ }
+ return;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/emulRepAre.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/emulRepAre.c
new file mode 100644
index 000000000..42f118aac
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/emulRepAre.c
@@ -0,0 +1,67 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/emulRepAre.c,v 1.3 1999/06/06 08:48:54 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+/* $XConsortium: emulRepAre.c /main/5 1996/02/21 17:56:16 kaleb $ */
+
+/* ppc Replicate Area -- A Divide & Conquer Algorithm
+ * a "ppc" Helper Function For Stipples And Tiling
+ * P. Shupak 1/88
+ */
+
+#include "xf4bpp.h"
+
+void xf4bppReplicateArea( pWin, x, y, planeMask, goalWidth, goalHeight,
+ currentHoriz, currentVert)
+WindowPtr pWin; /* GJA */
+register int x, y, planeMask ;
+int goalWidth, goalHeight ;
+int currentHoriz, currentVert ;
+{
+ for ( ;
+ currentHoriz <= ( goalWidth >> 1 ) ;
+ currentHoriz <<= 1 ) {
+ xf4bppBitBlt( pWin, GXcopy, planeMask,
+ x, y,
+ x + currentHoriz, y,
+ currentHoriz, currentVert ) ;
+ }
+ if ( goalWidth - currentHoriz )
+ xf4bppBitBlt( pWin, GXcopy, planeMask,
+ x, y,
+ x + currentHoriz, y,
+ goalWidth - currentHoriz, currentVert ) ;
+ for ( ;
+ currentVert <= ( goalHeight >> 1 ) ;
+ currentVert <<= 1 ) {
+ xf4bppBitBlt( pWin, GXcopy, planeMask,
+ x, y,
+ x, y + currentVert,
+ goalWidth, currentVert ) ;
+ }
+ if ( goalHeight - currentVert )
+ xf4bppBitBlt( pWin, GXcopy, planeMask,
+ x, y,
+ x, y + currentVert,
+ goalWidth, goalHeight - currentVert ) ;
+return ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/emulTile.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/emulTile.c
new file mode 100644
index 000000000..a2d24f4d9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/emulTile.c
@@ -0,0 +1,352 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/emulTile.c,v 1.3 1999/06/06 08:48:54 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+/* $XConsortium: emulTile.c /main/4 1996/02/21 17:56:23 kaleb $ */
+
+/* ppc Tile
+ * P. Shupak 11/87
+ * Modified From original ppc Tile
+ * T. Paquin 9/87
+ * Uses private imageFill a bunch of times
+ */
+
+#include "xf4bpp.h"
+#include "OScompiler.h"
+#include "ibmTrace.h"
+
+static void
+DrawFirstTile
+(
+ WindowPtr pWin, /* GJA */
+ register PixmapPtr pTile,
+ register int x,
+ register int y,
+ int w,
+ int h,
+ int alu,
+ unsigned long int planes,
+ int xOffset,
+ int yOffset
+)
+{
+register int htarget ;
+register int vtarget ;
+
+ if ( xOffset ) { /* Not X-Aligned */
+ if ( yOffset ) { /* Nor Y-Aligned */
+ htarget = MIN( pTile->drawable.width - xOffset, w ),
+ vtarget = MIN( pTile->drawable.height - yOffset, h ),
+ yOffset *= pTile->devKind ;
+ xf4bppDrawColorImage( pWin,x, y,
+ htarget,
+ vtarget,
+ (unsigned char *)pTile->devPrivate.ptr + yOffset + xOffset,
+ pTile->devKind,
+ alu, planes ) ;
+ if ( w > htarget ) {
+ w = MIN( w, pTile->drawable.width ) ;
+ if ( h > vtarget ) {
+ h = MIN( h, pTile->drawable.height ) ;
+ xf4bppDrawColorImage( pWin, x, y + vtarget,
+ htarget,
+ h - vtarget,
+ (unsigned char *)pTile->devPrivate.ptr + xOffset,
+ pTile->devKind,
+ alu, planes ) ;
+ xf4bppDrawColorImage( pWin, x + htarget, y,
+ w - htarget,
+ vtarget,
+ (unsigned char *)pTile->devPrivate.ptr + yOffset,
+ pTile->devKind,
+ alu, planes ) ;
+ xf4bppDrawColorImage( pWin, x + htarget,
+ y + vtarget,
+ w - htarget,
+ h - vtarget,
+ pTile->devPrivate.ptr,
+ pTile->devKind,
+ alu, planes ) ;
+ }
+ else { /* h <= vtarget */
+ xf4bppDrawColorImage( pWin, x + htarget, y,
+ w - htarget,
+ vtarget,
+ (unsigned char *)pTile->devPrivate.ptr + yOffset,
+ pTile->devKind,
+ alu, planes ) ;
+ }
+ }
+ else if ( h > vtarget ) {
+ xf4bppDrawColorImage( pWin, x, y + vtarget,
+ htarget,
+ MIN( h, pTile->drawable.height ) - vtarget,
+ (unsigned char *)pTile->devPrivate.ptr + xOffset,
+ pTile->devKind,
+ alu, planes ) ;
+ vtarget = pTile->drawable.height ;
+ }
+ }
+ else { /* No Y Offset */
+ xf4bppDrawColorImage( pWin, x, y,
+ htarget = MIN( pTile->drawable.width - xOffset, w ),
+ vtarget = MIN( pTile->drawable.height, h ),
+ (unsigned char *)pTile->devPrivate.ptr + xOffset,
+ pTile->devKind,
+ alu, planes ) ;
+ if ( w > htarget ) {
+ xf4bppDrawColorImage( pWin, x + htarget, y,
+ MIN( pTile->drawable.width, w ) - htarget,
+ vtarget,
+ pTile->devPrivate.ptr,
+ pTile->devKind,
+ alu, planes ) ;
+ }
+ }
+ }
+ else if ( yOffset ) {
+ xf4bppDrawColorImage( pWin, x, y,
+ htarget = MIN( pTile->drawable.width, w ),
+ vtarget = MIN( pTile->drawable.height - yOffset, h ),
+ (unsigned char *)pTile->devPrivate.ptr + ( yOffset * pTile->devKind ),
+ pTile->devKind,
+ alu, planes ) ;
+ if ( h > vtarget ) {
+ xf4bppDrawColorImage( pWin, x, y + vtarget,
+ htarget,
+ MIN( pTile->drawable.height, h ) - vtarget,
+ pTile->devPrivate.ptr,
+ pTile->devKind,
+ alu, planes ) ;
+ }
+ }
+ else { /* NO Offset */
+ xf4bppDrawColorImage( pWin, x, y,
+ htarget = MIN( pTile->drawable.width, w ),
+ vtarget = MIN( pTile->drawable.height, h ),
+ pTile->devPrivate.ptr,
+ pTile->devKind,
+ alu, planes ) ;
+ }
+
+ return ;
+}
+
+/* GJA --
+ * After finding three kinds of errors in this single function,
+ * (requiring modifications to be made at at least 10 places,
+ * I decided to REWRITE the body of the xf4bppTileRect function from scratch.
+ * This version simply computes all relevant margins in advance, and does
+ * not try to reuse temporary variables. I leave that to the compiler.
+ * (This was a maintenance and robustness nightmare anyway.)
+ * The code is pretty obvious: all margins, coordinates, and numbers of tiles
+ * are computed before drawing starts.
+ * Notice that the margins consist of incompletely drawn tiles. Therefore
+ * we need offsets in the data for the left and upper margins.
+ * The right and lower margins are also incomplete, but start at offset 0
+ * in the data. They just end at awkward offsets.
+ * The center block, by definition, consists of fully drawn tiles.
+ * Perhaps we could leave out some if's. But why bother? It would decrease
+ * robustness.
+ */
+void
+xf4bppTileRect( pWin, pTile, alu, planes, x0, y0, w, h, xSrc, ySrc )
+WindowPtr pWin; /* GJA */
+register PixmapPtr pTile ;
+const int alu ;
+const unsigned long int planes ;
+register int x0, y0, w, h ;
+int xSrc ;
+int ySrc ;
+{
+ScreenPtr pScreen ;
+int xOffset ;
+int yOffset ;
+int width, height;
+
+TRACE( ( "xf4bppTileRect(pTile=x%x,alu=x%x,planes=x%02x,x0=%d,y0=%d,w=%d,h=%d,xSrc=%d,ySrc=%d\n",
+ pTile, alu, planes, x0, y0, w, h, xSrc, ySrc ) ) ;
+
+ pScreen = pTile->drawable.pScreen ;
+ switch ( alu ) {
+ case GXclear: /* 0x0 Zero 0 */
+ case GXinvert: /* 0xa NOT dst */
+ case GXset: /* 0xf 1 */
+ xf4bppFillSolid
+ ( pWin, 0xFF, alu, planes, x0, y0, w, h ) ;
+ case GXnoop: /* 0x5 dst */
+ return ;
+ default:
+ break ;
+}
+
+ width = pTile->drawable.width;
+ if ( ( xOffset = ( x0 - xSrc ) ) > 0 )
+ xOffset %= width ;
+ else
+ xOffset = width - (( - xOffset ) % width ) ;
+ if ( xOffset == width ) xOffset = 0; /* For else case */
+
+ height = pTile->drawable.height;
+ if ( ( yOffset = ( y0 - ySrc ) ) > 0 )
+ yOffset %= height ;
+ else
+ yOffset = height - (( - yOffset ) % height ) ;
+ if ( yOffset == height ) yOffset = 0; /* For else case */
+
+ switch ( alu ) {
+ case GXcopyInverted: /* 0xc NOT src */
+ case GXcopy: /* 0x3 src */
+ /* Special Case Code */
+ DrawFirstTile( pWin, pTile, x0, y0, w, h,
+ alu, planes, xOffset, yOffset ) ;
+ /* Here We Double The Size Of The BLIT Each Iteration */
+ xf4bppReplicateArea( pWin, x0, y0, planes, w, h,
+ MIN( w, pTile->drawable.width ),
+ MIN( h, pTile->drawable.height ) ) ;
+ break ;
+ case GXnor: /* 0x8 NOT src AND NOT dst */
+ case GXandReverse: /* 0x2 src AND NOT dst */
+ case GXorReverse: /* 0xb src OR NOT dst */
+ case GXnand: /* 0xe NOT src OR NOT dst */
+ case GXandInverted: /* 0x4 NOT src AND dst */
+ case GXand: /* 0x1 src AND dst */
+ case GXequiv: /* 0x9 NOT src XOR dst */
+ case GXxor: /* 0x6 src XOR dst */
+ case GXorInverted: /* 0xd NOT src OR dst */
+ case GXor: /* 0x7 src OR dst */
+ default:
+ {
+ register unsigned char *data ;
+ register int hcount, vcount ; /* Number of tiles in center */
+ int xcount, ycount; /* Temporaries */
+ int x1, y1; /* Left upper corner of center */
+ int x2, y2; /* Left upper corner of lower right margin */
+ int leftmgn, rightmgn, topmgn, botmgn; /* Margins */
+
+ int htarget, vtarget ;
+
+ data = pTile->devPrivate.ptr;
+
+ /* Compute the various sizes and coordinates. */
+ leftmgn = MIN( w, width - xOffset ) ;
+ x1 = x0 + leftmgn;
+ topmgn = MIN( h, height - yOffset ) ;
+ y1 = y0 + topmgn;
+
+ rightmgn = (w - leftmgn) % width;
+ hcount = (w - leftmgn) / width;
+ x2 = x0 + w - rightmgn;
+ botmgn = (h - topmgn) % height;
+ vcount = (h - topmgn) / height;
+ y2 = y0 + h - botmgn;
+
+ /* We'll use yOffset as offset in data.
+ * This requires yOffset != height (ditto xOffset).
+ */
+ yOffset *= pTile->devKind;
+
+ /* Draw top margin, including corners */
+ if ( topmgn ) {
+ if ( leftmgn ) {
+ xf4bppDrawColorImage( pWin, x0, y0, leftmgn, topmgn,
+ data + yOffset + xOffset,
+ pTile->devKind, alu, planes ) ;
+ }
+ for ( xcount = hcount, htarget = x1;
+ xcount ;
+ xcount--, htarget += width )
+ {
+ xf4bppDrawColorImage( pWin, htarget, y0, width, topmgn,
+ data + yOffset,
+ pTile->devKind, alu, planes ) ;
+ }
+ if ( rightmgn ) {
+ xf4bppDrawColorImage( pWin, x2, y0, rightmgn, topmgn,
+ data + yOffset,
+ pTile->devKind, alu, planes ) ;
+ }
+ }
+
+ /* Draw bottom margin, including corners */
+ if ( botmgn ) {
+ if ( leftmgn ) {
+ xf4bppDrawColorImage( pWin, x0, y2, leftmgn, botmgn,
+ data + xOffset,
+ pTile->devKind, alu, planes ) ;
+ }
+ for ( xcount = hcount, htarget = x1;
+ xcount ;
+ xcount--, htarget += width )
+ {
+ xf4bppDrawColorImage( pWin, htarget, y2, width, botmgn,
+ data,
+ pTile->devKind, alu, planes ) ;
+ }
+ if ( rightmgn ) {
+ xf4bppDrawColorImage( pWin, x2, y2, rightmgn, botmgn,
+ data,
+ pTile->devKind, alu, planes ) ;
+ }
+ }
+
+ /* Draw left margin, excluding corners */
+ if ( leftmgn ) {
+ for ( ycount = vcount, vtarget = y1 ;
+ ycount ;
+ ycount--, vtarget += height )
+ {
+ xf4bppDrawColorImage( pWin, x0, vtarget, leftmgn, height,
+ data + xOffset,
+ pTile->devKind, alu, planes ) ;
+ }
+ }
+
+ /* Draw right margin, excluding corners */
+ if ( rightmgn ) {
+ for ( ycount = vcount, vtarget = y1 ;
+ ycount ;
+ ycount--, vtarget += height )
+ {
+ xf4bppDrawColorImage( pWin, x2, vtarget, rightmgn, height,
+ data,
+ pTile->devKind, alu, planes ) ;
+ }
+ }
+
+ /* Draw center consisting of full tiles */
+ for ( ycount = vcount, vtarget = y1 ;
+ ycount ;
+ ycount--, vtarget += height )
+ {
+ for ( xcount = hcount, htarget = x1 ;
+ xcount ;
+ xcount--, htarget += width )
+ {
+ xf4bppDrawColorImage( pWin, htarget, vtarget, width, height,
+ data,
+ pTile->devKind, alu, planes ) ;
+
+ }
+ }
+ } } /* Block + switch */
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ibmTrace.h b/xc/programs/Xserver/hw/xfree86/xf4bpp/ibmTrace.h
new file mode 100644
index 000000000..f99ce33e0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ibmTrace.h
@@ -0,0 +1,10 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ibmTrace.h,v 1.2 1998/07/25 16:59:28 dawes Exp $ */
+
+
+
+
+
+/* $XConsortium: ibmTrace.h /main/3 1996/02/21 17:56:27 kaleb $ */
+
+#define TRACE(x) /* empty */
+
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbbres.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbbres.c
new file mode 100644
index 000000000..300256021
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbbres.c
@@ -0,0 +1,162 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/mfbbres.c,v 1.3 1999/06/06 08:48:54 dawes Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* GJA -- modified this file for vga16 */
+/* $XConsortium: mfbbres.c /main/5 1996/02/21 17:56:30 kaleb $ */
+
+#include "xf4bpp.h"
+#include "OScompiler.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "maskbits.h"
+#include "miline.h"
+#include "wm3.h"
+
+/* Solid bresenham line */
+/* NOTES
+ e2 is used less often than e1, so it's not in a register
+*/
+
+void
+xf4bppBresS(addrlbase, nlwidth, signdx, signdy, axis, x1, y1, e, e1, e2, len)
+PixelType *addrlbase; /* pointer to base of bitmap */
+int nlwidth; /* width in longwords of bitmap */
+int signdx, signdy; /* signs of directions */
+int axis; /* major axis (Y_AXIS or X_AXIS) */
+int x1, y1; /* initial point */
+register int e; /* error accumulator */
+register int e1; /* bresenham increments */
+int e2;
+int len; /* length of line */
+{
+ register int yinc; /* increment to next scanline, in bytes */
+ register PixelType *addrl; /* bitmask long pointer
+ *dont* * cast to char pointer */
+ register PixelType bit; /* current bit being set/cleared/etc. */
+ PixelType leftbit = mask[0]; /* leftmost bit to process in new word */
+ PixelType rightbit = mask[PPW-1]; /* rightmost bit to process in new word */
+
+ register int e3 = e2-e1;
+
+ /* point to longword containing first point */
+ addrl = mfbScanline(addrlbase, x1, y1, nlwidth);
+ yinc = signdy * nlwidth;
+ e = e-e1; /* to make looping easier */
+ bit = mask[x1 & PIM];
+
+ if (!len)
+ return;
+
+ if (axis == X_AXIS)
+ {
+ if (signdx > 0)
+ {
+ while(len--)
+ {
+ UPDRW(addrl,bit);
+ e += e1;
+ if (e >= 0)
+ {
+ addrl += yinc;
+ e += e3;
+ }
+ bit = SCRRIGHT(bit,1);
+ if (!bit) { bit = leftbit; addrl++; }
+ }
+ }
+ else
+ {
+ while(len--)
+ {
+ UPDRW(addrl,bit);
+ e += e1;
+ if (e >= 0)
+ {
+ addrl += yinc;
+ e += e3;
+ }
+ bit = SCRLEFT(bit,1);
+ if (!bit) { bit = rightbit; addrl--; }
+ }
+ }
+ } /* if X_AXIS */
+ else
+ {
+ if (signdx > 0)
+ {
+ while(len--)
+ {
+ UPDRW(addrl,bit);
+ e += e1;
+ if (e >= 0)
+ {
+ bit = SCRRIGHT(bit,1);
+ if (!bit) { bit = leftbit; addrl++; }
+ e += e3;
+ }
+ addrl += yinc;
+ }
+ }
+ else
+ {
+ while(len--)
+ {
+ UPDRW(addrl,bit);
+ e += e1;
+ if (e >= 0)
+ {
+ bit = SCRLEFT(bit,1);
+ if (!bit) { bit = rightbit; addrl--; }
+ e += e3;
+ }
+ addrl += yinc;
+ }
+ }
+ } /* else Y_AXIS */
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbbresd.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbbresd.c
new file mode 100644
index 000000000..d43b3ba68
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbbresd.c
@@ -0,0 +1,199 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/mfbbresd.c,v 1.3 1999/06/06 08:48:55 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* GJA -- modified this file for vga16 */
+/* $XConsortium: mfbbresd.c /main/5 1996/02/21 17:56:34 kaleb $ */
+
+#include "xf4bpp.h"
+#include "OScompiler.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "maskbits.h"
+#include "miline.h"
+#include "wm3.h"
+
+/* Dashed bresenham line */
+
+#define NO_INK (-1) /* GJA -- means: dash is off */
+
+#define StepDash\
+ if (!--dashRemaining) { \
+ if (++ dashIndex == numInDashList) \
+ dashIndex = 0; \
+ dashRemaining = pDash[dashIndex]; \
+ ink = fgink; \
+ if (dashIndex & 1) \
+ ink = bgink; \
+ if (isDoubleDash) \
+ WM3_SET_INK(ink); \
+ }
+
+void
+xf4bppBresD(fgink, bgink,
+ pdashIndex, pDash, numInDashList, pdashOffset, isDoubleDash,
+ addrlbase, nlwidth,
+ signdx, signdy, axis, x1, y1, e, e1, e2, len)
+int fgink, bgink;
+int *pdashIndex; /* current dash */
+unsigned char *pDash; /* dash list */
+int numInDashList; /* total length of dash list */
+int *pdashOffset; /* offset into current dash */
+int isDoubleDash;
+PixelType *addrlbase; /* pointer to base of bitmap */
+int nlwidth; /* width in longwords of bitmap */
+int signdx, signdy; /* signs of directions */
+int axis; /* major axis (Y_AXIS or X_AXIS) */
+int x1, y1; /* initial point */
+register int e; /* error accumulator */
+register int e1; /* bresenham increments */
+int e2;
+int len; /* length of line */
+{
+ register int yinc; /* increment to next scanline, in bytes */
+ register PixelType *addrl;
+ register int e3 = e2-e1;
+ register unsigned long bit;
+ PixelType leftbit = mask[0]; /* leftmost bit to process in new word */
+ PixelType rightbit = mask[PPW-1]; /* rightmost bit to process in new word */
+ int dashIndex;
+ int dashOffset;
+ int dashRemaining;
+ int ink;
+
+ fgink &= 0x0F; bgink &= 0x0F; /* GJA -- so they're != NO_INK */
+
+ dashOffset = *pdashOffset;
+ dashIndex = *pdashIndex;
+ dashRemaining = pDash[dashIndex] - dashOffset;
+ ink = fgink;
+ if (!isDoubleDash)
+ bgink = NO_INK;
+ if (dashIndex & 1)
+ ink = bgink;
+ if ( ink != NO_INK ) WM3_SET_INK(ink);
+
+ /* point to longword containing first point */
+ addrl = mfbScanline(addrlbase, x1, y1, nlwidth);
+ yinc = signdy * nlwidth;
+ e = e-e1; /* to make looping easier */
+ bit = mask[x1 & PIM];
+ if (axis == X_AXIS)
+ {
+ if (signdx > 0)
+ {
+ while(len--)
+ {
+ if ( ink != NO_INK ) UPDRW(addrl,bit);
+ e += e1;
+ if (e >= 0)
+ {
+ addrl += yinc;
+ e += e3;
+ }
+ bit = SCRRIGHT(bit,1);
+ if (!bit) { bit = leftbit; addrl++; }
+ StepDash
+ }
+ }
+ else
+ {
+ while(len--)
+ {
+
+ if ( ink != NO_INK ) UPDRW(addrl,bit);
+ e += e1;
+ if (e >= 0)
+ {
+ addrl += yinc;
+ e += e3;
+ }
+ bit = SCRLEFT(bit,1);
+ if (!bit) { bit = rightbit; addrl--; }
+ StepDash
+ }
+ }
+ } /* if X_AXIS */
+ else
+ {
+ if (signdx > 0)
+ {
+ while(len--)
+ {
+ if ( ink != NO_INK ) UPDRW(addrl,bit);
+ e += e1;
+ if (e >= 0)
+ {
+ bit = SCRRIGHT(bit,1);
+ if (!bit) { bit = leftbit; addrl++; }
+ e += e3;
+ }
+ addrl += yinc;
+ StepDash
+ }
+ }
+ else
+ {
+ while(len--)
+ {
+
+ if ( ink != NO_INK ) UPDRW(addrl,bit);
+ e += e1;
+ if (e >= 0)
+ {
+ bit = SCRLEFT(bit,1);
+ if (!bit) { bit = rightbit; addrl--; }
+ e += e3;
+ }
+ addrl += yinc;
+ StepDash
+ }
+ }
+ } /* else Y_AXIS */
+ *pdashIndex = dashIndex;
+ *pdashOffset = pDash[dashIndex] - dashRemaining;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbfillarc.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbfillarc.c
new file mode 100644
index 000000000..c6803b982
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbfillarc.c
@@ -0,0 +1,299 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/mfbfillarc.c,v 1.3 1999/06/06 08:48:55 dawes Exp $ */
+/************************************************************
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+********************************************************/
+
+/* GJA -- Took mfb code and modified it. */
+
+/* $XConsortium: mfbfillarc.c /main/4 1996/02/21 17:56:37 kaleb $ */
+
+#include "xf4bpp.h"
+#include "OScompiler.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "maskbits.h"
+#include "mi.h"
+#include "mifillarc.h"
+#include "wm3.h"
+
+#include "xf86str.h" /* for pScrn->vtSema */
+extern ScrnInfoPtr *xf86Screens;
+
+static void
+v16FillEllipseSolid
+(
+ DrawablePtr pDraw,
+ xArc *arc
+)
+{
+ int x, y, e;
+ int yk, xk, ym, xm, dx, dy, xorg, yorg;
+ register int slw;
+ miFillArcRec info;
+ int *addrlt, *addrlb;
+ register int *addrl;
+ register int n;
+ int nlwidth;
+ register int xpos;
+ int startmask, endmask, nlmiddle;
+
+ if (pDraw->type == DRAWABLE_WINDOW)
+ {
+ addrlt = (int *)
+ (((PixmapPtr)(pDraw->pScreen->devPrivate))->devPrivate.ptr);
+ nlwidth = (int)
+ (((PixmapPtr)(pDraw->pScreen->devPrivate))->devKind) >> 2;
+ }
+ else
+ {
+ addrlt = (int *)(((PixmapPtr)pDraw)->devPrivate.ptr);
+ nlwidth = (int)(((PixmapPtr)pDraw)->devKind) >> 2;
+ }
+
+ miFillArcSetup(arc, &info);
+ MIFILLARCSETUP();
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ addrlb = addrlt;
+ addrlt += nlwidth * (yorg - y);
+ addrlb += nlwidth * (yorg + y + dy);
+ while (y)
+ {
+ addrlt += nlwidth;
+ addrlb -= nlwidth;
+ MIFILLARCSTEP(slw);
+ if (!slw)
+ continue;
+ xpos = xorg - x;
+ addrl = addrlt + (xpos >> 5);
+ if (((xpos & 0x1f) + slw) < 32)
+ {
+ maskpartialbits(xpos, slw, startmask);
+ UPDRW(addrl,startmask);
+ if (miFillArcLower(slw))
+ {
+ addrl = addrlb + (xpos >> 5);
+ UPDRW(addrl,startmask);
+ }
+ continue;
+ }
+ maskbits(xpos, slw, startmask, endmask, nlmiddle);
+ if (startmask)
+ {
+ UPDRW(addrl,startmask); addrl++;
+ }
+ n = nlmiddle;
+ while (n--) {
+ UPDRW(addrl,~0); addrl++;
+ }
+ if (endmask)
+ {
+ UPDRW(addrl,endmask);
+ }
+ if (!miFillArcLower(slw))
+ continue;
+ addrl = addrlb + (xpos >> 5);
+ if (startmask)
+ {
+ UPDRW(addrl,startmask); addrl++;
+ }
+ n = nlmiddle;
+ while (n--) {
+ UPDRW(addrl,~0); addrl++;
+ }
+ if (endmask)
+ {
+ UPDRW(addrl,endmask);
+ }
+ }
+}
+
+#define FILLSPAN(xl,xr,addr) \
+ if (xr >= xl) \
+ { \
+ width = xr - xl + 1; \
+ addrl = addr + (xl >> 5); \
+ if (((xl & 0x1f) + width) < 32) \
+ { \
+ maskpartialbits(xl, width, startmask); \
+ UPDRW(addrl,startmask); \
+ } \
+ else \
+ { \
+ maskbits(xl, width, startmask, endmask, nlmiddle); \
+ if (startmask) \
+ { \
+ UPDRW(addrl,startmask); addrl++; \
+ } \
+ n = nlmiddle; \
+ while (n--) { \
+ UPDRW(addrl,~0); addrl++; \
+ } \
+ if (endmask) \
+ { \
+ UPDRW(addrl,endmask); \
+ } \
+ } \
+ }
+
+#define FILLSLICESPANS(flip,addr) \
+ if (!flip) \
+ { \
+ FILLSPAN(xl, xr, addr); \
+ } \
+ else \
+ { \
+ xc = xorg - x; \
+ FILLSPAN(xc, xr, addr); \
+ xc += slw - 1; \
+ FILLSPAN(xl, xc, addr); \
+ }
+
+static void
+v16FillArcSliceSolidCopy
+(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ xArc *arc
+)
+{
+ register int *addrl;
+ register int n;
+ int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
+ register int x, y, e;
+ miFillArcRec info;
+ miArcSliceRec slice;
+ int xl, xr, xc;
+ int *addrlt, *addrlb;
+ int nlwidth;
+ int width;
+ int startmask, endmask, nlmiddle;
+
+ if (pDraw->type == DRAWABLE_WINDOW)
+ {
+ addrlt = (int *)
+ (((PixmapPtr)(pDraw->pScreen->devPrivate))->devPrivate.ptr);
+ nlwidth = (int)
+ (((PixmapPtr)(pDraw->pScreen->devPrivate))->devKind) >> 2;
+ }
+ else
+ {
+ addrlt = (int *)(((PixmapPtr)pDraw)->devPrivate.ptr);
+ nlwidth = (int)(((PixmapPtr)pDraw)->devKind) >> 2;
+ }
+
+ miFillArcSetup(arc, &info);
+ miFillArcSliceSetup(arc, &slice, pGC);
+ MIFILLARCSETUP();
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ addrlb = addrlt;
+ addrlt += nlwidth * (yorg - y);
+ addrlb += nlwidth * (yorg + y + dy);
+ slice.edge1.x += pDraw->x;
+ slice.edge2.x += pDraw->x;
+ while (y > 0)
+ {
+ addrlt += nlwidth;
+ addrlb -= nlwidth;
+ MIFILLARCSTEP(slw);
+ MIARCSLICESTEP(slice.edge1);
+ MIARCSLICESTEP(slice.edge2);
+ if (miFillSliceUpper(slice))
+ {
+ MIARCSLICEUPPER(xl, xr, slice, slw);
+ FILLSLICESPANS(slice.flip_top, addrlt);
+ }
+ if (miFillSliceLower(slice))
+ {
+ MIARCSLICELOWER(xl, xr, slice, slw);
+ FILLSLICESPANS(slice.flip_bot, addrlb);
+ }
+ }
+}
+
+static void
+xf4bppPolyFillArcSolid
+(
+ register DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+)
+{
+ mfbPrivGC *priv;
+ register xArc *arc;
+ register int i;
+ BoxRec box;
+ RegionPtr cclip;
+ int rop;
+
+ priv = (mfbPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr;
+ rop = priv->rop;
+#if 0
+ if ((rop == RROP_NOP) || !(pGC->planemask & 1))
+#else
+ if ( !(pGC->planemask & 0x0F))
+#endif
+ return;
+ cclip = pGC->pCompositeClip;
+ for (arc = parcs, i = narcs; --i >= 0; arc++)
+ {
+ if (miFillArcEmpty(arc))
+ continue;
+ if (miCanFillArc(arc))
+ {
+ box.x1 = arc->x + pDraw->x;
+ box.y1 = arc->y + pDraw->y;
+ box.x2 = box.x1 + (int)arc->width + 1;
+ box.y2 = box.y1 + (int)arc->height + 1;
+ if ((*pDraw->pScreen->RectIn)(cclip, &box) == rgnIN)
+ {
+ if ((arc->angle2 >= FULLCIRCLE) ||
+ (arc->angle2 <= -FULLCIRCLE))
+ DO_WM3(pGC,v16FillEllipseSolid(pDraw, arc))
+ else
+ DO_WM3(pGC,v16FillArcSliceSolidCopy(pDraw, pGC, arc))
+ continue;
+ }
+ }
+ miPolyFillArc(pDraw, pGC, 1, arc);
+ }
+}
+
+void
+xf4bppPolyFillArc(pDraw, pGC, narcs, parcs)
+ register DrawablePtr pDraw;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ if ( !xf86Screens[pDraw->pScreen->myNum]->vtSema || (pGC->fillStyle != FillSolid) ) {
+ miPolyFillArc(pDraw, pGC, narcs, parcs);
+ } else {
+ xf4bppPolyFillArcSolid(pDraw, pGC, narcs, parcs);
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbhrzvert.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbhrzvert.c
new file mode 100644
index 000000000..3d6c3df52
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbhrzvert.c
@@ -0,0 +1,133 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/mfbhrzvert.c,v 1.3 1999/06/06 08:48:55 dawes Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* GJA -- modified this file for vga16 */
+/* $XConsortium: mfbhrzvert.c /main/3 1996/02/21 17:56:41 kaleb $ */
+
+#include "xf4bpp.h"
+#include "OScompiler.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "maskbits.h"
+#include "wm3.h"
+
+/* horizontal solid line
+ abs(len) > 1
+*/
+
+void
+xf4bppHorzS(addrl, nlwidth, x1, y1, len)
+register PixelType *addrl; /* pointer to base of bitmap */
+register int nlwidth; /* width in longwords of bitmap */
+int x1; /* initial point */
+int y1;
+int len; /* length of line */
+{
+ register PixelType startmask;
+ register PixelType endmask;
+ register int nlmiddle;
+
+
+ /* force the line to go left to right
+ but don't draw the last point
+ */
+ if (len < 0)
+ {
+ x1 += len;
+ x1 += 1;
+ len = -len;
+ }
+
+ addrl = mfbScanline(addrl, x1, y1, nlwidth);
+
+ /* all bits inside same longword */
+ if ( ((x1 & PIM) + len) < PPW)
+ {
+ maskpartialbits(x1, len, startmask);
+ UPDRW(addrl,startmask);
+ }
+ else
+ {
+ maskbits(x1, len, startmask, endmask, nlmiddle);
+ if (startmask) {
+ UPDRW(addrl,startmask); addrl++;
+ }
+ Duff (nlmiddle, UPDRW(addrl,~0); addrl++);
+ if (endmask) {
+ UPDRW(addrl,endmask);
+ }
+ }
+}
+
+/* vertical solid line
+ this uses do loops because pcc (Ultrix 1.2, bsd 4.2) generates
+ better code. sigh. we know that len will never be 0 or 1, so
+ it's OK to use it.
+*/
+
+void
+xf4bppVertS(addrl, nlwidth, x1, y1, len)
+register PixelType *addrl; /* pointer to base of bitmap */
+register int nlwidth; /* width in longwords of bitmap */
+int x1, y1; /* initial point */
+register int len; /* length of line */
+{
+ register PixelType bitmask;
+
+ addrl = mfbScanline(addrl, x1, y1, nlwidth);
+
+ if (len < 0)
+ {
+ nlwidth = -nlwidth;
+ len = -len;
+ }
+
+ bitmask = mask[x1 & PIM];
+ Duff(len, UPDRW(addrl,bitmask); addrl += nlwidth);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbimggblt.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbimggblt.c
new file mode 100644
index 000000000..021bb5460
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbimggblt.c
@@ -0,0 +1,515 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/mfbimggblt.c,v 1.3 1999/06/06 08:48:56 dawes Exp $ */
+
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: mfbimggblt.c /main/5 1996/02/21 17:56:44 kaleb $ */
+
+#include "xf4bpp.h"
+#include "OScompiler.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "maskbits.h"
+#include "mi.h"
+#include "dixfontstr.h"
+#include "ppcGCstr.h"
+#include "wm3.h"
+
+#include "xf86str.h" /* for pScrn->vtSema */
+extern ScrnInfoPtr *xf86Screens;
+
+/*
+ we should eventually special-case fixed-width fonts for ImageText.
+
+ this works for fonts with glyphs <= 32 bits wide.
+
+ the clipping calculations are done for worst-case fonts.
+we make no assumptions about the heights, widths, or bearings
+of the glyphs. if we knew that the glyphs are all the same height,
+we could clip the tops and bottoms per clipping box, rather
+than per character per clipping box. if we knew that the glyphs'
+left and right bearings were wlle-behaved, we could clip a single
+character at the start, output until the last unclipped
+character, and then clip the last one. this is all straightforward
+to determine based on max-bounds and min-bounds from the font.
+ there is some inefficiency introduced in the per-character
+clipping to make what's going on clearer.
+
+ (it is possible, for example, for a font to be defined in which the
+next-to-last character in a font would be clipped out, but the last
+one wouldn't. the code below deals with this.)
+
+ Image text looks at the bits in the glyph and the fg and bg in the
+GC. it paints a rectangle, as defined in the protocol dcoument,
+and the paints the characters.
+
+ to avoid source proliferation, this file is compiled
+three times:
+ MFBIMAGEGLYPHBLT OPEQ
+ mfbImageGlyphBltWhite |=
+ mfbImageGlyphBltBlack &=~
+
+ the register allocations for startmask and endmask may not
+be the right thing. are there two other deserving candidates?
+xoff, pdst, pglyph, and tmpSrc seem like the right things, though.
+*/
+
+/* Forward declarations -- GJA */
+static void doImageGlyphBlt(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GC *,
+ int,
+ int,
+ unsigned int,
+ CharInfoPtr *,
+ unsigned char *,
+ ExtentInfoRec *
+#endif
+);
+
+void
+xf4bppImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ unsigned char *pglyphBase; /* start of array of glyphs */
+{
+ ExtentInfoRec info; /* used by QueryGlyphExtents() */
+ xRectangle backrect;/* backing rectangle to paint.
+ in the general case, NOT necessarily
+ the same as the string's bounding box
+ */
+
+ /* GJA -- I agree, this ALL should be moved to GC validation. */
+ if ( (pDrawable->type != DRAWABLE_WINDOW) || (pGC->alu != GXcopy) ||
+ !xf86Screens[pDrawable->pScreen->myNum]->vtSema ||
+ ((pGC->font) &&
+ (FONTMAXBOUNDS(pGC->font,rightSideBearing) -
+ FONTMINBOUNDS(pGC->font,leftSideBearing) > 32 ||
+ FONTMINBOUNDS(pGC->font,characterWidth) < 0)) ) {
+ miImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ } else {
+ void (* oldFillArea)();
+ int oldfillStyle, oldfg, oldalu;
+
+ if (!(pGC->planemask & 0x0F))
+ return;
+
+ QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info);
+
+ backrect.x = x;
+ backrect.y = y - FONTASCENT(pGC->font);
+ backrect.width = info.overallWidth;
+ backrect.height = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+
+
+ oldFillArea = ((ppcPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->
+ FillArea;
+ oldfillStyle = ((ppcPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->
+ colorRrop.fillStyle; /* GJA */
+ oldfg = ((ppcPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->
+ colorRrop.fgPixel; /* GJA */
+ oldalu = ((ppcPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->
+ colorRrop.alu; /* GJA */
+
+ ((ppcPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->
+ FillArea = xf4bppAreaFill;
+ ((ppcPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->
+ colorRrop.fillStyle = FillSolid; /* GJA */
+ ((ppcPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->
+ colorRrop.fgPixel = pGC->bgPixel; /* GJA */
+ pGC->fgPixel = pGC->bgPixel;
+ ((ppcPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->
+ colorRrop.alu = GXcopy; /* GJA */
+ pGC->alu = GXcopy;
+
+ /* Required fields:
+ * colorRrop.alu, colorRrop.planemask, colorRrop.fgPixel, FillArea
+ */
+ xf4bppPolyFillRect(pDrawable, pGC, 1, &backrect);
+
+ ((ppcPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->
+ FillArea = oldFillArea;
+ ((ppcPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->
+ colorRrop.fgPixel = oldfg; /* GJA */
+ pGC->fgPixel = oldfg;
+
+ /* the faint-hearted can open their eyes now */
+
+ DO_WM3(pGC,doImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci,
+ pglyphBase,&info))
+
+ ((ppcPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->
+ colorRrop.fillStyle = oldfillStyle; /* GJA */
+ ((ppcPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->
+ colorRrop.alu = oldalu; /* GJA */
+ pGC->alu = oldalu;
+ }
+}
+
+static void
+doImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase,infop)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ unsigned char *pglyphBase; /* start of array of glyphs */
+ ExtentInfoRec* infop; /* used by QueryGlyphExtents() */
+{
+ BoxRec bbox; /* string's bounding box */
+
+ CharInfoPtr pci;
+ int xorg, yorg; /* origin of drawable in bitmap */
+ int widthDst; /* width of dst in longwords */
+
+ /* these keep track of the character origin */
+ unsigned long *pdstBase;
+ /* points to longword with character origin */
+ int xchar; /* xorigin of char (mod 32) */
+
+ /* these are used for placing the glyph */
+ register int xoff; /* x offset of left edge of glyph (mod 32) */
+ register unsigned long *pdst;
+ /* pointer to current longword in dst */
+
+ int w; /* width of glyph in bits */
+ int h; /* height of glyph */
+ int widthGlyph; /* width of glyph, in bytes */
+ register unsigned char *pglyph;
+ /* pointer to current row of glyph */
+
+ /* used for putting down glyph */
+ register unsigned int tmpSrc;
+ /* for getting bits from glyph */
+ register int startmask;
+ register int endmask;
+
+ register int nFirst;/* bits of glyph in current longword */
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pdstBase = (unsigned long *)
+ (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate.ptr);
+ widthDst = (int)
+ (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
+ }
+ else
+ {
+ pdstBase = (unsigned long *)(((PixmapPtr)pDrawable)->devPrivate.ptr);
+ widthDst = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
+ }
+
+ x += xorg;
+ y += yorg;
+
+ bbox.x1 = x + infop->overallLeft;
+ bbox.x2 = x + infop->overallRight;
+ bbox.y1 = y - infop->overallAscent;
+ bbox.y2 = y + infop->overallDescent;
+
+ /* UNCLEAN CODE
+ we know the mfbPolyFillRect uses only three fields in
+ devPrivate[mfbGCPrivateIndex].ptr, two of which (the rotated
+ tile/stipple and the ropFillArea) are
+ irrelevant for solid filling, so we just poke the FillArea
+ field. the GC is now in an inconsistent state, but we'll fix
+ it as soon as PolyFillRect returns. fortunately, the server
+ is single threaded.
+
+ NOTE:
+ if you are not using the standard mfbFillRectangle code, you
+ need to poke any fields in the GC the rectangle stuff need
+ (probably alu, fgPixel, and fillStyle) and in devPrivate[mfbGCPrivateIndex].ptr
+ (probably rop or ropFillArea.) You could just call ValidateGC,
+ but that is usually not a cheap thing to do.
+ */
+
+ switch ((*pGC->pScreen->RectIn)(pGC->pCompositeClip, &bbox))
+ {
+ case rgnOUT:
+ break;
+ case rgnIN:
+ pdstBase = pdstBase + (widthDst * y) + (x >> 5);
+ xchar = x & 0x1f;
+
+ while(nglyph--)
+ {
+ pci = *ppci;
+ pglyph = FONTGLYPHBITS(pglyphBase, pci);
+ w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ h = pci->metrics.ascent + pci->metrics.descent;
+ widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
+
+ /* start at top scanline of glyph */
+ pdst = pdstBase - (pci->metrics.ascent * widthDst);
+
+ /* find correct word in scanline and x offset within it
+ for left edge of glyph
+ */
+ xoff = xchar + pci->metrics.leftSideBearing;
+ if (xoff > 31)
+ {
+ pdst++;
+ xoff &= 0x1f;
+ }
+ else if (xoff < 0)
+ {
+ xoff += 32;
+ pdst--;
+ }
+
+ if ((xoff + w) <= 32)
+ {
+ /* glyph all in one longword */
+ maskpartialbits(xoff, w, startmask);
+ while (h--)
+ {
+ getleftbits(pglyph, w, tmpSrc);
+ UPDRW(pdst,(SCRRIGHT(tmpSrc, xoff) & startmask));
+ pglyph += widthGlyph;
+ pdst += widthDst;
+ }
+ }
+ else
+ {
+ /* glyph crosses longword boundary */
+ maskPPWbits(xoff, w, startmask, endmask);
+ nFirst = 32 - xoff;
+ while (h--)
+ {
+ getleftbits(pglyph, w, tmpSrc);
+ UPDRW(pdst,(SCRRIGHT(tmpSrc, xoff) & startmask));
+ UPDRW(&(pdst[1]),(SCRLEFT(tmpSrc, nFirst) & endmask));
+ pglyph += widthGlyph;
+ pdst += widthDst;
+ }
+ } /* glyph crosses longwords boundary */
+
+ /* update character origin */
+ x += pci->metrics.characterWidth;
+ xchar += pci->metrics.characterWidth;
+ if (xchar > 31)
+ {
+ xchar -= 32;
+ pdstBase++;
+ }
+ else if (xchar < 0)
+ {
+ xchar += 32;
+ pdstBase--;
+ }
+ ppci++;
+ } /* while nglyph-- */
+ break;
+ case rgnPART:
+ {
+ TEXTPOS *ppos;
+ int nbox;
+ BoxPtr pbox;
+ RegionPtr cclip;
+ int xpos; /* x position of char origin */
+ unsigned int i;
+ BoxRec clip;
+ int leftEdge, rightEdge;
+ int topEdge, bottomEdge;
+ int glyphRow; /* first row of glyph not wholly
+ clipped out */
+ int glyphCol; /* leftmost visible column of glyph */
+ int getWidth; /* bits to get from glyph */
+
+ if(!(ppos = (TEXTPOS *)ALLOCATE_LOCAL(nglyph * sizeof(TEXTPOS))))
+ return;
+
+ pdstBase = pdstBase + (widthDst * y) + (x >> 5);
+ xpos = x;
+ xchar = xpos & 0x1f;
+
+ for (i=0; i<nglyph; i++)
+ {
+ pci = ppci[i];
+
+ ppos[i].xpos = xpos;
+ ppos[i].xchar = xchar;
+ ppos[i].leftEdge = xpos + pci->metrics.leftSideBearing;
+ ppos[i].rightEdge = xpos + pci->metrics.rightSideBearing;
+ ppos[i].topEdge = y - pci->metrics.ascent;
+ ppos[i].bottomEdge = y + pci->metrics.descent;
+ ppos[i].pdstBase = pdstBase;
+ ppos[i].widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
+
+ xpos += pci->metrics.characterWidth;
+ xchar += pci->metrics.characterWidth;
+ if (xchar > 31)
+ {
+ xchar &= 0x1f;
+ pdstBase++;
+ }
+ else if (xchar < 0)
+ {
+ xchar += 32;
+ pdstBase--;
+ }
+ }
+
+ cclip = pGC->pCompositeClip;
+ pbox = REGION_RECTS(cclip);
+ nbox = REGION_NUM_RECTS(cclip);
+
+ /* HACK ALERT
+ since we continue out of the loop below so often, it
+ is easier to increment pbox at the top than at the end.
+ don't try this at home.
+ */
+ pbox--;
+ while(nbox--)
+ {
+ pbox++;
+ clip.x1 = max(bbox.x1, pbox->x1);
+ clip.y1 = max(bbox.y1, pbox->y1);
+ clip.x2 = min(bbox.x2, pbox->x2);
+ clip.y2 = min(bbox.y2, pbox->y2);
+ if ((clip.x2<=clip.x1) || (clip.y2<=clip.y1))
+ continue;
+
+ for(i=0; i<nglyph; i++)
+ {
+ pci = ppci[i];
+ xchar = ppos[i].xchar;
+
+ /* clip the left and right edges */
+ if (ppos[i].leftEdge < clip.x1)
+ leftEdge = clip.x1;
+ else
+ leftEdge = ppos[i].leftEdge;
+
+ if (ppos[i].rightEdge > clip.x2)
+ rightEdge = clip.x2;
+ else
+ rightEdge = ppos[i].rightEdge;
+
+ w = rightEdge - leftEdge;
+ if (w <= 0)
+ continue;
+
+ /* clip the top and bottom edges */
+ if (ppos[i].topEdge < clip.y1)
+ topEdge = clip.y1;
+ else
+ topEdge = ppos[i].topEdge;
+
+ if (ppos[i].bottomEdge > clip.y2)
+ bottomEdge = clip.y2;
+ else
+ bottomEdge = ppos[i].bottomEdge;
+
+ h = bottomEdge - topEdge;
+ if (h <= 0)
+ continue;
+
+ glyphRow = (topEdge - y) + pci->metrics.ascent;
+ widthGlyph = ppos[i].widthGlyph;
+ pglyph = FONTGLYPHBITS(pglyphBase, pci);
+ pglyph += (glyphRow * widthGlyph);
+
+ pdst = ppos[i].pdstBase - ((y-topEdge) * widthDst);
+
+ glyphCol = (leftEdge - ppos[i].xpos) -
+ (pci->metrics.leftSideBearing);
+ getWidth = w + glyphCol;
+ xoff = xchar + (leftEdge - ppos[i].xpos);
+ if (xoff > 31)
+ {
+ xoff &= 0x1f;
+ pdst++;
+ }
+ else if (xoff < 0)
+ {
+ xoff += 32;
+ pdst--;
+ }
+
+ if ((xoff + w) <= 32)
+ {
+ maskpartialbits(xoff, w, startmask);
+ while (h--)
+ {
+ getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
+ UPDRW(pdst,(SCRRIGHT(tmpSrc, xoff) & startmask));
+ pglyph += widthGlyph;
+ pdst += widthDst;
+ }
+ }
+ else
+ {
+ maskPPWbits(xoff, w, startmask, endmask);
+ nFirst = 32 - xoff;
+ while (h--)
+ {
+ getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
+ UPDRW(pdst,(SCRRIGHT(tmpSrc, xoff) & startmask));
+ UPDRW(&(pdst[1]),(SCRLEFT(tmpSrc, nFirst) & endmask));
+ pglyph += widthGlyph;
+ pdst += widthDst;
+ }
+ }
+ } /* for each glyph */
+ } /* while nbox-- */
+ DEALLOCATE_LOCAL(ppos);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbline.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbline.c
new file mode 100644
index 000000000..b51e1541a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbline.c
@@ -0,0 +1,982 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/mfbline.c,v 1.3 1999/06/06 08:48:56 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* GJA -- modified this file for vga16 */
+/* $XConsortium: mfbline.c /main/4 1996/02/21 17:56:48 kaleb $ */
+
+#include "xf4bpp.h"
+#include "OScompiler.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "maskbits.h"
+#include "mi.h"
+#include "miline.h"
+#include "vgaVideo.h"
+#include "wm3.h"
+
+#include "xf86str.h" /* for pScrn->vtSema */
+extern ScrnInfoPtr *xf86Screens;
+
+/* single-pixel lines on a color frame buffer
+
+ NON-SLOPED LINES
+ horizontal lines are always drawn left to right; we have to
+move the endpoints right by one after they're swapped.
+ horizontal lines will be confined to a single band of a
+region. the code finds that band (giving up if the lower
+bound of the band is above the line we're drawing); then it
+finds the first box in that band that contains part of the
+line. we clip the line to subsequent boxes in that band.
+ vertical lines are always drawn top to bottom (y-increasing.)
+this requires adding one to the y-coordinate of each endpoint
+after swapping.
+
+ SLOPED LINES
+ when clipping a sloped line, we bring the second point inside
+the clipping box, rather than one beyond it, and then add 1 to
+the length of the line before drawing it. this lets us use
+the same box for finding the outcodes for both endpoints. since
+the equation for clipping the second endpoint to an edge gives us
+1 beyond the edge, we then have to move the point towards the
+first point by one step on the major axis.
+ eventually, there will be a diagram here to explain what's going
+on. the method uses Cohen-Sutherland outcodes to determine
+outsideness, and a method similar to Pike's layers for doing the
+actual clipping.
+
+*/
+#ifdef POLYSEGMENT
+static void DoV16SegmentSS(
+#if NeedFunctionPrototypes
+ DrawablePtr, GCPtr, int, xSegment*
+#endif
+);
+
+void
+xf4bppSegmentSS (pDrawable, pGC, nseg, pSeg)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nseg;
+ register xSegment *pSeg;
+{
+ if ( ! xf86Screens[pDrawable->pScreen->myNum]->vtSema ) {
+ miPolySegment(pDrawable, pGC, nseg, pSeg);
+ } else {
+ DO_WM3(pGC,DoV16SegmentSS (pDrawable, pGC, nseg, pSeg));
+ }
+}
+
+#else
+static void DoV16LineSS(
+#if NeedFunctionPrototypes
+ DrawablePtr, GCPtr, int, int, DDXPointPtr
+#endif
+);
+
+void
+xf4bppLineSS (pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt; /* number of points */
+ DDXPointPtr pptInit;
+{
+ if ( ! xf86Screens[pDrawable->pScreen->myNum]->vtSema ) {
+ miZeroLine(pDrawable, pGC, mode, npt, pptInit);
+ } else {
+ DO_WM3(pGC,DoV16LineSS (pDrawable, pGC, mode, npt, pptInit));
+ }
+}
+#endif
+
+static void
+#ifdef POLYSEGMENT
+DoV16SegmentSS (pDrawable, pGC, nseg, pSeg)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nseg;
+ register xSegment *pSeg;
+#else
+DoV16LineSS (pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt; /* number of points */
+ DDXPointPtr pptInit;
+#endif
+{
+ int nboxInit;
+ register int nbox;
+ BoxPtr pboxInit;
+ register BoxPtr pbox;
+#ifndef POLYSEGMENT
+ register DDXPointPtr ppt; /* pointer to list of translated points */
+#endif
+
+ unsigned int oc1; /* outcode of point 1 */
+ unsigned int oc2; /* outcode of point 2 */
+
+ PixelType *addrlBase; /* pointer to start of drawable */
+#ifndef POLYSEGMENT
+ PixelType *addrl; /* address of destination pixmap */
+#endif
+ int nlwidth; /* width in longwords of destination pixmap */
+ int xorg, yorg; /* origin of window */
+
+ int adx; /* abs values of dx and dy */
+ int ady;
+ int signdx; /* sign of dx and dy */
+ int signdy;
+ int e, e1, e2; /* bresenham error and increments */
+ int len; /* length of segment */
+ int axis; /* major axis */
+ int octant;
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+
+ /* a bunch of temporaries */
+ register int y1, y2;
+ register int x1, x2;
+ RegionPtr cclip;
+ int alu;
+
+ if (!(pGC->planemask & 0x0F))
+ return;
+
+ cclip = pGC->pCompositeClip;
+ alu = pGC->alu; /* GJA */
+ pboxInit = REGION_RECTS(cclip);
+ nboxInit = REGION_NUM_RECTS(cclip);
+
+ nlwidth = BYTES_PER_LINE(pDrawable) >> 2; /* GJA */
+ addrlBase = (PixelType *)VIDBASE(pDrawable); /* GJA */
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+#ifdef POLYSEGMENT
+ while (nseg--)
+#else
+ ppt = pptInit;
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+ while(--npt)
+#endif
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+
+#ifdef POLYSEGMENT
+ x1 = pSeg->x1 + xorg;
+ y1 = pSeg->y1 + yorg;
+ x2 = pSeg->x2 + xorg;
+ y2 = pSeg->y2 + yorg;
+ pSeg++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious)
+ {
+ xorg = x1;
+ yorg = y1;
+ }
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+#endif
+
+ if (x1 == x2) /* vertical line */
+ {
+ /* make the line go top to bottom of screen, keeping
+ endpoint semantics
+ */
+ if (y1 > y2)
+ {
+ register int tmp;
+
+ tmp = y2;
+ y2 = y1 + 1;
+ y1 = tmp + 1;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ y1--;
+#endif
+ }
+#ifdef POLYSEGMENT
+ else if (pGC->capStyle != CapNotLast)
+ y2++;
+#endif
+ /* get to first band that might contain part of line */
+ while ((nbox) && (pbox->y2 <= y1))
+ {
+ pbox++;
+ nbox--;
+ }
+
+ if (nbox)
+ {
+ /* stop when lower edge of box is beyond end of line */
+ while((nbox) && (y2 >= pbox->y1))
+ {
+ if ((x1 >= pbox->x1) && (x1 < pbox->x2))
+ {
+ int y1t, y2t;
+ /* this box has part of the line in it */
+ y1t = max(y1, pbox->y1);
+ y2t = min(y2, pbox->y2);
+ if (y1t != y2t)
+ {
+ xf4bppVertS (addrlBase, nlwidth,
+ x1, y1t, y2t-y1t);
+ }
+ }
+ nbox--;
+ pbox++;
+ }
+ }
+#ifndef POLYSEGMENT
+ y2 = ppt->y + yorg;
+#endif
+ }
+ else if (y1 == y2) /* horizontal line */
+ {
+ /* force line from left to right, keeping
+ endpoint semantics
+ */
+ if (x1 > x2)
+ {
+ register int tmp;
+
+ tmp = x2;
+ x2 = x1 + 1;
+ x1 = tmp + 1;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ x1--;
+#endif
+ }
+#ifdef POLYSEGMENT
+ else if (pGC->capStyle != CapNotLast)
+ x2++;
+#endif
+
+ /* find the correct band */
+ while( (nbox) && (pbox->y2 <= y1))
+ {
+ pbox++;
+ nbox--;
+ }
+
+ /* try to draw the line, if we haven't gone beyond it */
+ if ((nbox) && (pbox->y1 <= y1))
+ {
+ int tmp;
+
+ /* when we leave this band, we're done */
+ tmp = pbox->y1;
+ while((nbox) && (pbox->y1 == tmp))
+ {
+ int x1t, x2t;
+
+ if (pbox->x2 <= x1)
+ {
+ /* skip boxes until one might contain start point */
+ nbox--;
+ pbox++;
+ continue;
+ }
+
+ /* stop if left of box is beyond right of line */
+ if (pbox->x1 >= x2)
+ {
+ nbox = 0;
+ break;
+ }
+
+ x1t = max(x1, pbox->x1);
+ x2t = min(x2, pbox->x2);
+ if (x1t != x2t)
+ {
+ xf4bppHorzS (addrlBase, nlwidth,
+ x1t, y1, x2t-x1t);
+ }
+ nbox--;
+ pbox++;
+ }
+ }
+#ifndef POLYSEGMENT
+ x2 = ppt->x + xorg;
+#endif
+ }
+ else /* sloped line */
+ {
+ CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy,
+ 1, 1, octant);
+
+ if (adx > ady)
+ {
+ axis = X_AXIS;
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ }
+ else
+ {
+ axis = Y_AXIS;
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ SetYMajorOctant(octant);
+ }
+
+ FIXUP_ERROR(e, octant, bias);
+
+ /* we have bresenham parameters and two points.
+ all we have to do now is clip and draw.
+ */
+
+ while(nbox--)
+ {
+ oc1 = 0;
+ oc2 = 0;
+ OUTCODES(oc1, x1, y1, pbox);
+ OUTCODES(oc2, x2, y2, pbox);
+ if ((oc1 | oc2) == 0)
+ {
+ if (axis == X_AXIS)
+ len = adx;
+ else
+ len = ady;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ len++;
+#endif
+ xf4bppBresS (addrlBase, nlwidth,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e2, len);
+ break;
+ }
+ else if (oc1 & oc2)
+ {
+ pbox++;
+ }
+ else
+ {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int clipdx, clipdy;
+ int err;
+
+ if (miZeroClipLine(pbox->x1, pbox->y1, pbox->x2-1,
+ pbox->y2-1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pbox++;
+ continue;
+ }
+
+ if (axis == X_AXIS)
+ len = abs(new_x2 - new_x1);
+ else
+ len = abs(new_y2 - new_y1);
+#ifdef POLYSEGMENT
+ if (clip2 != 0 || pGC->capStyle != CapNotLast)
+ len++;
+#else
+ len += (clip2 != 0);
+#endif
+ if (len)
+ {
+ /* unwind bresenham error term to first point */
+ if (clip1)
+ {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ if (axis == X_AXIS)
+ err = e+((clipdy*e2) + ((clipdx-clipdy)*e1));
+ else
+ err = e+((clipdx*e2) + ((clipdy-clipdx)*e1));
+ }
+ else
+ err = e;
+ xf4bppBresS (addrlBase, nlwidth,
+ signdx, signdy, axis, new_x1, new_y1,
+ err, e1, e2, len);
+ }
+ pbox++;
+ }
+ } /* while (nbox--) */
+ } /* sloped line */
+ } /* while (nline--) */
+
+#ifndef POLYSEGMENT
+
+ /* paint the last point if the end style isn't CapNotLast.
+ (Assume that a projecting, butt, or round cap that is one
+ pixel wide is the same as the single pixel of the endpoint.)
+ */
+
+ if ((pGC->capStyle != CapNotLast) &&
+ ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
+ (ppt->y + yorg != pptInit->y + pDrawable->y) ||
+ (ppt == pptInit + 1)))
+ {
+ PixelType _mask;
+
+ if (alu == RROP_BLACK)
+ _mask = rmask[x2 & PIM];
+ else
+ _mask = mask[x2 & PIM];
+
+ nbox = nboxInit;
+ pbox = pboxInit;
+ while (nbox--)
+ {
+ if ((x2 >= pbox->x1) &&
+ (y2 >= pbox->y1) &&
+ (x2 < pbox->x2) &&
+ (y2 < pbox->y2))
+ {
+ addrl = mfbScanline(addrlBase, x2, y2, nlwidth);
+ UPDRW(addrl,_mask);
+ break;
+ }
+ else
+ pbox++;
+ }
+ }
+#endif
+}
+
+/*
+ * Draw dashed 1-pixel lines.
+ */
+
+#ifdef POLYSEGMENT
+static void DoV16SegmentSD(
+#if NeedFunctionPrototypes
+ DrawablePtr, GCPtr, int, xSegment*
+#endif
+);
+
+void
+xf4bppSegmentSD (pDrawable, pGC, nseg, pSeg)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nseg;
+ register xSegment *pSeg;
+{
+ if ( ! xf86Screens[pDrawable->pScreen->myNum]->vtSema ) {
+ miPolySegment(pDrawable, pGC, nseg, pSeg);
+ } else {
+ DO_WM3(pGC,DoV16SegmentSD (pDrawable, pGC, nseg, pSeg));
+ }
+}
+
+#else
+static void DoV16LineSD(
+#if NeedFunctionPrototypes
+ DrawablePtr, GCPtr, int, int, DDXPointPtr
+#endif
+);
+
+void
+xf4bppLineSD (pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt; /* number of points */
+ DDXPointPtr pptInit;
+{
+ if ( ! xf86Screens[pDrawable->pScreen->myNum]->vtSema ) {
+ miZeroDashLine(pDrawable, pGC, mode, npt, pptInit);
+ } else {
+ DO_WM3(pGC,DoV16LineSD (pDrawable, pGC, mode, npt, pptInit));
+ }
+}
+#endif
+
+static void
+#ifdef POLYSEGMENT
+DoV16SegmentSD (pDrawable, pGC, nseg, pSeg)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int nseg;
+ register xSegment *pSeg;
+#else
+DoV16LineSD( pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt; /* number of points */
+ DDXPointPtr pptInit;
+#endif
+{
+ int nboxInit;
+ register int nbox;
+ BoxPtr pboxInit;
+ register BoxPtr pbox;
+#ifndef POLYSEGMENT
+ register DDXPointPtr ppt; /* pointer to list of translated points */
+#endif
+
+ register unsigned int oc1; /* outcode of point 1 */
+ register unsigned int oc2; /* outcode of point 2 */
+
+ PixelType *addrl; /* address of destination pixmap */
+ int nlwidth; /* width in longwords of destination pixmap */
+ int xorg, yorg; /* origin of window */
+
+ int adx; /* abs values of dx and dy */
+ int ady;
+ int signdx; /* sign of dx and dy */
+ int signdy;
+ int e, e1, e2; /* bresenham error and increments */
+ int len; /* length of segment */
+ int axis; /* major axis */
+ int octant;
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ int x1, x2, y1, y2;
+ RegionPtr cclip;
+ int fgink, bgink; /* GJA */
+ unsigned char *pDash;
+ int dashOffset;
+ int numInDashList;
+ int dashIndex;
+ int isDoubleDash;
+ int dashIndexTmp, dashOffsetTmp;
+ int unclippedlen;
+
+ if (!(pGC->planemask & 0x0F))
+ return;
+
+ cclip = pGC->pCompositeClip;
+ fgink = bgink = pGC->fgPixel; /* GJA */
+ pboxInit = REGION_RECTS(cclip);
+ nboxInit = REGION_NUM_RECTS(cclip);
+
+ nlwidth = BYTES_PER_LINE(pDrawable) >> 2; /* GJA */
+ addrl = (PixelType *)VIDBASE(pDrawable); /* GJA */
+
+ /* compute initial dash values */
+
+ pDash = (unsigned char *) pGC->dash;
+ numInDashList = pGC->numInDashList;
+ isDoubleDash = (pGC->lineStyle == LineDoubleDash);
+ dashIndex = 0;
+ dashOffset = 0;
+ miStepDash ((int)pGC->dashOffset, &dashIndex, pDash,
+ numInDashList, &dashOffset);
+
+ if (isDoubleDash)
+ bgink = pGC->bgPixel; /* GJA */
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+#ifdef POLYSEGMENT
+ while (nseg--)
+#else
+ ppt = pptInit;
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+ while(--npt)
+#endif
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+
+#ifdef POLYSEGMENT
+ x1 = pSeg->x1 + xorg;
+ y1 = pSeg->y1 + yorg;
+ x2 = pSeg->x2 + xorg;
+ y2 = pSeg->y2 + yorg;
+ pSeg++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious)
+ {
+ xorg = x1;
+ yorg = y1;
+ }
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+#endif
+
+ CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);
+
+ if (adx > ady)
+ {
+ axis = X_AXIS;
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ unclippedlen = adx;
+ }
+ else
+ {
+ axis = Y_AXIS;
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ unclippedlen = ady;
+ SetYMajorOctant(octant);
+ }
+
+ FIXUP_ERROR(e, octant, bias);
+
+ /* we have bresenham parameters and two points.
+ all we have to do now is clip and draw.
+ */
+
+ while(nbox--)
+ {
+ oc1 = 0;
+ oc2 = 0;
+ OUTCODES(oc1, x1, y1, pbox);
+ OUTCODES(oc2, x2, y2, pbox);
+ if ((oc1 | oc2) == 0)
+ {
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ unclippedlen++;
+ dashIndexTmp = dashIndex;
+ dashOffsetTmp = dashOffset;
+ xf4bppBresD (fgink, bgink,
+ &dashIndexTmp, pDash, numInDashList,
+ &dashOffsetTmp, isDoubleDash,
+ addrl, nlwidth,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e2, unclippedlen);
+ break;
+#else
+ xf4bppBresD (fgink, bgink,
+ &dashIndex, pDash, numInDashList,
+ &dashOffset, isDoubleDash,
+ addrl, nlwidth,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e2, unclippedlen);
+ goto dontStep;
+#endif
+ }
+ else if (oc1 & oc2)
+ {
+ pbox++;
+ }
+ else /* have to clip */
+ {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int clipdx, clipdy;
+ int err;
+
+ if (miZeroClipLine(pbox->x1, pbox->y1, pbox->x2-1, pbox->y2-1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pbox++;
+ continue;
+ }
+ dashIndexTmp = dashIndex;
+ dashOffsetTmp = dashOffset;
+ if (clip1)
+ {
+ int dlen;
+
+ if (axis == X_AXIS)
+ dlen = abs(new_x1 - x1);
+ else
+ dlen = abs(new_y1 - y1);
+ miStepDash (dlen, &dashIndexTmp, pDash,
+ numInDashList, &dashOffsetTmp);
+ }
+ if (axis == X_AXIS)
+ len = abs(new_x2 - new_x1);
+ else
+ len = abs(new_y2 - new_y1);
+#ifdef POLYSEGMENT
+ if (clip2 != 0 || pGC->capStyle != CapNotLast)
+ len++;
+#else
+ len += (clip2 != 0);
+#endif
+ if (len)
+ {
+ /* unwind bresenham error term to first point */
+ if (clip1)
+ {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ if (axis == X_AXIS)
+ err = e+((clipdy*e2) + ((clipdx-clipdy)*e1));
+ else
+ err = e+((clipdx*e2) + ((clipdy-clipdx)*e1));
+ }
+ else
+ err = e;
+ xf4bppBresD (fgink, bgink,
+ &dashIndexTmp, pDash, numInDashList,
+ &dashOffsetTmp, isDoubleDash,
+ addrl, nlwidth,
+ signdx, signdy, axis, new_x1, new_y1,
+ err, e1, e2, len);
+ }
+ pbox++;
+ }
+ } /* while (nbox--) */
+#ifndef POLYSEGMENT
+ /*
+ * walk the dash list around to the next line
+ */
+ miStepDash (unclippedlen, &dashIndex, pDash,
+ numInDashList, &dashOffset);
+dontStep: ;
+#endif
+ } /* while (nline--) */
+
+#ifndef POLYSEGMENT
+ /* paint the last point if the end style isn't CapNotLast.
+ (Assume that a projecting, butt, or round cap that is one
+ pixel wide is the same as the single pixel of the endpoint.)
+ */
+
+ if ((pGC->capStyle != CapNotLast) &&
+ ((dashIndex & 1) == 0 || isDoubleDash) &&
+ ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
+ (ppt->y + yorg != pptInit->y + pDrawable->y) ||
+ (ppt == pptInit + 1)))
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+ while (nbox--)
+ {
+ if ((x2 >= pbox->x1) &&
+ (y2 >= pbox->y1) &&
+ (x2 < pbox->x2) &&
+ (y2 < pbox->y2))
+ {
+ unsigned long _mask;
+ int ink;
+
+ ink = fgink;
+ if (dashIndex & 1) ink = bgink;
+ _mask = mask[x2 & PIM];
+ addrl = mfbScanline(addrl, x2, y2, nlwidth);
+ UPDRW(addrl,_mask);
+ break;
+ }
+ else
+ pbox++;
+ }
+ }
+#endif
+}
+
+
+#if 0
+#ifndef POLYSEGMENT
+/*
+ the clipping code could be cleaned up some; most of its
+mess derives from originally being inline in the line code,
+then pulled out to make clipping dashes easier.
+*/
+
+int
+mfbClipLine(pbox, box,
+ ppt1Orig, ppt1, ppt2,
+ adx, ady, signdx, signdy, axis,
+ pclip1, pclip2)
+BoxPtr pbox; /* box to clip to */
+BoxRec box; /* box to do calculations with */
+DDXPointPtr ppt1Orig, ppt1, ppt2;
+int adx, ady;
+int signdx, signdy;
+register int axis;
+int *pclip1, *pclip2;
+{
+ DDXPointRec pt1Orig, pt1, pt2;
+ register int swapped = 0;
+ int clipDone = 0;
+ register unsigned int utmp;
+ register int oc1, oc2;
+ int clip1, clip2;
+
+ pt1Orig = *ppt1Orig;
+ pt1 = *ppt1;
+ pt2 = *ppt2;
+ clip1 = 0;
+ clip2 = 0;
+
+ do
+ {
+ oc1 = 0;
+ oc2 = 0;
+ OUTCODES(oc1, pt1.x, pt1.y, pbox);
+ OUTCODES(oc2, pt2.x, pt2.y, pbox);
+
+ if (oc1 & oc2)
+ clipDone = -1;
+ else if ((oc1 | oc2) == 0)
+ {
+ clipDone = 1;
+ if (swapped)
+ {
+ SWAPPT(pt1, pt2);
+ SWAPINT(oc1, oc2);
+ SWAPINT(clip1, clip2);
+ }
+ }
+ else /* have to clip */
+ {
+ /* only clip one point at a time */
+ if (!oc1)
+ {
+ SWAPPT(pt1, pt2);
+ SWAPINT(oc1, oc2);
+ SWAPINT(clip1, clip2);
+ swapped = !swapped;
+ }
+
+ clip1 |= oc1;
+ if (oc1 & OUT_LEFT)
+ {
+ pt1.x = box.x1;
+ utmp = abs(box.x1 - pt1Orig.x);
+ utmp *= ady;
+ if(axis==X_AXIS)
+ {
+ pt1.y = pt1Orig.y + SignTimes(signdy, round(utmp, adx));
+ }
+ else
+ {
+ utmp <<= 1;
+ if (swapped)
+ utmp += ady;
+ else
+ utmp -= ady;
+ pt1.y = pt1Orig.y + SignTimes(signdy, ceiling(utmp, 2*adx));
+ if (swapped)
+ pt1.y -= signdy;
+ }
+ }
+ else if (oc1 & OUT_ABOVE)
+ {
+ pt1.y = box.y1;
+ utmp = abs(box.y1 - pt1Orig.y);
+ utmp *= adx;
+ if (axis == Y_AXIS)
+ {
+ pt1.x = pt1Orig.x + SignTimes(signdx, round(utmp, ady));
+ }
+ else
+ {
+ utmp <<= 1;
+ if (swapped)
+ utmp += adx;
+ else
+ utmp -= adx;
+ pt1.x = pt1Orig.x + SignTimes(signdx, ceiling(utmp, 2*ady));
+ if (swapped)
+ pt1.x -= signdx;
+ }
+ }
+ else if (oc1 & OUT_RIGHT)
+ {
+ pt1.x = box.x2;
+ utmp = abs(pt1Orig.x - box.x2);
+ utmp *= ady;
+ if (axis == X_AXIS)
+ {
+ pt1.y = pt1Orig.y + SignTimes(signdy, round(utmp, adx));
+ }
+ else
+ {
+ utmp <<= 1;
+ if (swapped)
+ utmp += ady;
+ else
+ utmp -= ady;
+ pt1.y = pt1Orig.y + SignTimes(signdy, ceiling(utmp, 2*adx));
+ if (swapped)
+ pt1.y -= signdy;
+ }
+ }
+ else if (oc1 & OUT_BELOW)
+ {
+ pt1.y = box.y2;
+ utmp = abs(pt1Orig.y - box.y2);
+ utmp *= adx;
+ if (axis == Y_AXIS)
+ {
+ pt1.x = pt1Orig.x + SignTimes(signdx, round(utmp, ady));
+ }
+ else
+ {
+ utmp <<= 1;
+ if (swapped)
+ utmp += adx;
+ else
+ utmp -= adx;
+ pt1.x = pt1Orig.x + SignTimes(signdx, ceiling(utmp, 2*ady));
+ if (swapped)
+ pt1.x -= signdx;
+ }
+ }
+ } /* else have to clip */
+ } while(!clipDone);
+ *ppt1 = pt1;
+ *ppt2 = pt2;
+ *pclip1 = clip1;
+ *pclip2 = clip2;
+
+ return clipDone;
+}
+#endif
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbzerarc.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbzerarc.c
new file mode 100644
index 000000000..c8a8540f1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/mfbzerarc.c
@@ -0,0 +1,266 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/mfbzerarc.c,v 1.3 1999/06/06 08:48:56 dawes Exp $ */
+
+/************************************************************
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+********************************************************/
+/* GJA -- Took mfb code and modified it. */
+
+/* $XConsortium: mfbzerarc.c /main/4 1996/02/21 17:56:52 kaleb $ */
+
+/* Derived from:
+ * "Algorithm for drawing ellipses or hyperbolae with a digital plotter"
+ * by M. L. V. Pitteway
+ * The Computer Journal, November 1967, Volume 10, Number 3, pp. 282-289
+ */
+
+#include "xf4bpp.h"
+#include "OScompiler.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "maskbits.h"
+#include "mi.h"
+#include "mizerarc.h"
+#include "wm3.h"
+
+#include "xf86str.h" /* for pScrn->vtSema */
+extern ScrnInfoPtr *xf86Screens;
+
+/*
+ * Note, LEFTMOST must be the bit leftmost in the actual screen
+ * representation. This depends on both BITMAP_BIT_ORDER and
+ * IMAGE_BYTE_ORDER
+ * DHD 10/92
+ */
+
+#if (BITMAP_BIT_ORDER == MSBFirst)
+#if (IMAGE_BYTE_ORDER == MSBFirst)
+#define LEFTMOST ((unsigned int) 0x80000000)
+#else
+#define LEFTMOST ((unsigned int) 0x80)
+#endif
+#else
+#if (IMAGE_BYTE_ORDER == LSBFirst)
+#define LEFTMOST ((unsigned int) 1)
+#else
+#define LEFTMOST ((unsigned int) 0x1000000)
+#endif
+#endif
+
+#define PixelateWhite(addr,off) \
+{ \
+ register int *tmpaddr = &((addr)[(off)>>5]); \
+ UPDRW(tmpaddr,SCRRIGHT (LEFTMOST, ((off) & 0x1f))); \
+}
+#define PixelateBlack(addr,off) \
+{ \
+ register int *tmpaddr = &((addr)[(off)>>5]); \
+ UPDRW(tmpaddr,~(SCRRIGHT (LEFTMOST, ((off) & 0x1f)))); \
+}
+
+#define Pixelate(base,off) \
+{ \
+ paddr = base + ((off)>>5); \
+ pmask = SCRRIGHT(LEFTMOST, (off) & 0x1f); \
+ UPDRW(paddr,(pixel & pmask)); \
+}
+
+#define DoPix(bit,base,off) if (msk & bit) Pixelate(base,off);
+
+static void
+v16ZeroArcSS
+(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ xArc *arc
+)
+{
+ miZeroArcRec info;
+ Bool do360;
+ register int x, y, a, b, d, msk;
+ register int k1, k3, dx, dy;
+ int *addrl;
+ int *yorgl, *yorgol;
+ unsigned long pixel;
+ int nlwidth, yoffset, dyoffset;
+ int pmask;
+ register int *paddr;
+
+ if (((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->rop ==
+ RROP_BLACK)
+ pixel = 0;
+ else
+ pixel = ~0UL;
+
+ if (pDraw->type == DRAWABLE_WINDOW)
+ {
+ addrl = (int *)
+ (((PixmapPtr)(pDraw->pScreen->devPrivate))->devPrivate.ptr);
+ nlwidth = (int)
+ (((PixmapPtr)(pDraw->pScreen->devPrivate))->devKind) >> 2;
+ }
+ else
+ {
+ addrl = (int *)(((PixmapPtr)pDraw)->devPrivate.ptr);
+ nlwidth = (int)(((PixmapPtr)pDraw)->devKind) >> 2;
+ }
+
+ do360 = miZeroArcSetup(arc, &info, TRUE);
+ yorgl = addrl + ((info.yorg + pDraw->y) * nlwidth);
+ yorgol = addrl + ((info.yorgo + pDraw->y) * nlwidth);
+ info.xorg += pDraw->x;
+ info.xorgo += pDraw->x;
+ MIARCSETUP();
+ yoffset = y ? nlwidth : 0;
+ dyoffset = 0;
+ msk = info.initialMask;
+ if (!(arc->width & 1))
+ {
+ DoPix(2, yorgl, info.xorgo);
+ DoPix(8, yorgol, info.xorgo);
+ }
+ if (!info.end.x || !info.end.y)
+ {
+ msk = info.end.mask;
+ info.end = info.altend;
+ }
+ if (do360 && (arc->width == arc->height) && !(arc->width & 1))
+ {
+ int xoffset = nlwidth;
+ int *yorghl = yorgl + (info.h * nlwidth);
+ int xorghp = info.xorg + info.h;
+ int xorghn = info.xorg - info.h;
+
+ while (1)
+ {
+ PixelateWhite(yorgl + yoffset, info.xorg + x);
+ PixelateWhite(yorgl + yoffset, info.xorg - x);
+ PixelateWhite(yorgol- yoffset, info.xorg - x);
+ PixelateWhite(yorgol - yoffset, info.xorg + x);
+ if (a < 0)
+ break;
+ PixelateWhite(yorghl - xoffset, xorghp - y);
+ PixelateWhite(yorghl - xoffset, xorghn + y);
+ PixelateWhite(yorghl + xoffset, xorghn + y);
+ PixelateWhite(yorghl + xoffset, xorghp - y);
+ xoffset += nlwidth;
+ MIARCCIRCLESTEP(yoffset += nlwidth;);
+ }
+ x = info.w;
+ yoffset = info.h * nlwidth;
+ }
+ else if (do360)
+ {
+ while (y < info.h || x < info.w)
+ {
+ MIARCOCTANTSHIFT(dyoffset = nlwidth;);
+ Pixelate(yorgl + yoffset, info.xorg + x);
+ Pixelate(yorgl + yoffset, info.xorgo - x);
+ Pixelate(yorgol - yoffset, info.xorgo - x);
+ Pixelate(yorgol - yoffset, info.xorg + x);
+ MIARCSTEP(yoffset += dyoffset;, yoffset += nlwidth;);
+ }
+ }
+ else
+ {
+ while (y < info.h || x < info.w)
+ {
+ MIARCOCTANTSHIFT(dyoffset = nlwidth;);
+ if ((x == info.start.x) || (y == info.start.y))
+ {
+ msk = info.start.mask;
+ info.start = info.altstart;
+ }
+ DoPix(1, yorgl + yoffset, info.xorg + x);
+ DoPix(2, yorgl + yoffset, info.xorgo - x);
+ DoPix(4, yorgol - yoffset, info.xorgo - x);
+ DoPix(8, yorgol - yoffset, info.xorg + x);
+ if ((x == info.end.x) || (y == info.end.y))
+ {
+ msk = info.end.mask;
+ info.end = info.altend;
+ }
+ MIARCSTEP(yoffset += dyoffset;, yoffset += nlwidth;);
+ }
+ }
+ if ((x == info.start.x) || (y == info.start.y))
+ msk = info.start.mask;
+ DoPix(1, yorgl + yoffset, info.xorg + x);
+ DoPix(4, yorgol - yoffset, info.xorgo - x);
+ if (arc->height & 1)
+ {
+ DoPix(2, yorgl + yoffset, info.xorgo - x);
+ DoPix(8, yorgol - yoffset, info.xorg + x);
+ }
+}
+
+static void
+xf4bppZeroPolyArcSS
+(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+)
+{
+ register xArc *arc;
+ register int i;
+ BoxRec box;
+ RegionPtr cclip;
+
+ if (!pGC->planemask & 0x0F)
+ return;
+ cclip = pGC->pCompositeClip;
+ for (arc = parcs, i = narcs; --i >= 0; arc++)
+ {
+ if (miCanZeroArc(arc))
+ {
+ box.x1 = arc->x + pDraw->x;
+ box.y1 = arc->y + pDraw->y;
+ box.x2 = box.x1 + (int)arc->width + 1;
+ box.y2 = box.y1 + (int)arc->height + 1;
+ if ((*pDraw->pScreen->RectIn)(cclip, &box) == rgnIN)
+ v16ZeroArcSS(pDraw, pGC, arc);
+ else
+ miZeroPolyArc(pDraw, pGC, 1, arc);
+ }
+ else
+ miPolyArc(pDraw, pGC, 1, arc);
+ }
+}
+
+void
+xf4bppZeroPolyArc(pDraw, pGC, narcs, parcs)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ if ( !xf86Screens[pDraw->pScreen->myNum]->vtSema ) {
+ miZeroPolyArc(pDraw, pGC, narcs, parcs);
+ } else {
+ DO_WM3(pGC,xf4bppZeroPolyArcSS(pDraw, pGC, narcs, parcs));
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/offscreen.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/offscreen.c
new file mode 100644
index 000000000..629fb90cf
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/offscreen.c
@@ -0,0 +1,359 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/offscreen.c,v 1.3 1999/06/06 08:48:57 dawes Exp $ */
+/*
+ * Copyright 1993 Gerrit Jan Akkerman
+ *
+ * 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 Gerrit Jan Akkerman not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * GERRIT JAN AKKERMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL GERRIT JAN AKKERMAN BE LIABLE FOR ANY SPECIAL, INDIRECT
+ * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+*/
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+/* $XConsortium: offscreen.c /main/4 1996/02/21 17:56:55 kaleb $ */
+
+#include "xf4bpp.h"
+#include "vgaVideo.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+
+#define saved_screen(pWin) \
+ ((unsigned char *)(((PixmapPtr)((pWin)->drawable.pScreen->devPrivate))->devPrivate.ptr))
+
+#define SAVEDSCREEN(pWin, x, y) \
+ (*(saved_screen(pWin) + (y) * (BYTES_PER_LINE(pWin) << 3) + (x)))
+
+#define DO_ROP(src,dst,alu,planes) \
+ ((dst) = do_rop((src),(dst),(alu),(planes)))
+
+/* NOTE:
+ * The following to functions don't do anything. They're just there to
+ * provide a stable interface to the rest of the system.
+ */
+
+static int
+do_rop
+(
+ int src,
+ int dst,
+ int alu,
+ const unsigned long planes
+)
+{
+ int _dst; /* New dst */
+
+ switch ( alu ) {
+ case GXclear: /* 0x0 Zero 0 */
+ _dst = 0; break ;
+ case GXinvert: /* 0xa NOT dst */
+ _dst = ~dst; break ;
+ case GXset: /* 0xf 1 */
+ _dst = src; break ;
+ default:
+ case GXnoop: /* 0x5 dst */
+ return dst;
+ case GXnor: /* 0x8 NOT src AND NOT dst */
+ _dst = ~src & ~dst; break ;
+ case GXandInverted: /* 0x4 NOT src AND dst */
+ _dst = ~src & dst; break ;
+ case GXand: /* 0x1 src AND dst */
+ _dst = src & dst; break ;
+ case GXequiv: /* 0x9 NOT src XOR dst */
+ _dst = ~src ^ dst; break ;
+ case GXxor: /* 0x6 src XOR dst */
+ _dst = src ^ dst; break ;
+ case GXandReverse: /* 0x2 src AND NOT dst */
+ _dst = src & ~dst; break ;
+ case GXnand: /* 0xe NOT src OR NOT dst */
+ _dst = ~src | ~dst; break ;
+ case GXorReverse: /* 0xb src OR NOT dst */
+ _dst = src | ~dst; break ;
+ case GXorInverted: /* 0xd NOT src OR dst */
+ _dst = ~src | dst; break ;
+ case GXor: /* 0x7 src OR dst */
+ _dst = src | dst; break ;
+ case GXcopyInverted: /* 0xc NOT src */
+ _dst = ~src; break ;
+ case GXcopy: /* 0x3 src */
+ _dst = src; break ;
+ }
+ return (dst & ~planes) | (_dst & planes);
+}
+
+/* File vgaBitBlt.c */
+void
+xf4bppOffBitBlt( pWin, alu, writeplanes, x0, y0, x1, y1, w, h )
+WindowPtr pWin; /* GJA */
+const int alu, writeplanes ;
+register int x0 ;
+int y0 ;
+register int x1 ;
+int y1 ;
+register int w, h ;
+{
+ int x,y;
+
+ switch ( alu ) {
+ case GXclear: /* 0x0 Zero 0 */
+ case GXinvert: /* 0xa NOT dst */
+ case GXset: /* 0xf 1 */
+ xf4bppOffFillSolid( pWin, VGA_ALLPLANES, alu, writeplanes,
+ x0, y0, w, h ) ;
+ case GXnoop: /* 0x5 dst */
+ return ;
+ default:
+ break ;
+ }
+
+ if ( (w <= 0) || (h <= 0) ) return;
+
+ for ( y = 0 ; y < h ; y++ ) {
+ for ( x = 0 ; x < w ; x++ ) {
+ DO_ROP(SAVEDSCREEN(pWin,x0+x,y0+y),SAVEDSCREEN(pWin,x1+x,y1+y),
+ alu,writeplanes);
+ }
+ }
+}
+
+/* for file vgaImages.c */
+
+void
+xf4bppOffDrawColorImage( pWin, x, y, w, h, data, RowIncrement, alu, planes )
+WindowPtr pWin; /* GJA */
+int x, y ;
+register int w, h ;
+unsigned char *data ;
+register int RowIncrement ;
+const int alu ;
+const unsigned long int planes ;
+{
+ int dx,dy;
+
+ for ( dy = 0 ; dy < h ; dy++ ) {
+ for ( dx = 0 ; dx < w ; dx++ ) {
+ DO_ROP( data[dy * RowIncrement + dx],
+ SAVEDSCREEN(pWin,x+dx,y+dy), alu, planes);
+ }
+ }
+}
+
+void
+xf4bppOffReadColorImage( pWin, x, y, lx, ly, data, RowIncrement )
+WindowPtr pWin; /* GJA */
+int x, y ;
+int lx, ly ;
+unsigned char *data ;
+int RowIncrement ;
+{
+ int dx, dy;
+
+ if ( ( lx <= 0 ) || ( ly <= 0 ) )
+ return ;
+
+ for ( dy = 0 ; dy < ly ; dy++ ) {
+ for ( dx = 0 ; dx < lx ; dx++ ) {
+ data[dy*RowIncrement+dx] = SAVEDSCREEN(pWin,x+dx,y+dy);
+ }
+ }
+}
+
+/* For file vgaSolid.c */
+
+void xf4bppOffFillSolid( pWin, color, alu, planes, x0, y0, lx, ly )
+WindowPtr pWin; /* GJA */
+unsigned long int color ;
+const int alu ;
+unsigned long int planes ;
+register int x0 ;
+register const int y0 ;
+register int lx ;
+register const int ly ; /* MUST BE > 0 !! */
+{
+ int dx, dy;
+
+ if ( ( lx == 0 ) || ( ly == 0 ) )
+ return;
+
+ for ( dy = 0 ; dy < ly ; dy++ ) {
+ for ( dx = 0 ; dx < lx ; dx++ ) {
+ DO_ROP(color,SAVEDSCREEN(pWin, x0+dx,y0+dy),alu,planes);
+ }
+ }
+}
+
+/* For file vgaStipple.c */
+
+/* GJA -- modified this to take both Width and Height, and to
+ * reduce x and y to Width and Height by taking remainders.
+ */
+static unsigned char
+xygetbits
+(
+ register int x,
+ register int y,
+ register const unsigned int Width,
+ register const unsigned int paddedByteWidth,
+ register const unsigned int Height,
+ register const unsigned char * const data
+)
+{
+ register unsigned char bits ;
+ unsigned const char *lineptr, *cptr ;
+ register shift ;
+ register wrap ;
+
+ x = x % Width;
+ y = y % Height;
+
+ lineptr = data + (y * paddedByteWidth);
+ cptr = lineptr + (x >> 3) ;
+ bits = *cptr ;
+ if ((shift = x & 7))
+ bits = SCRLEFT8( bits, shift ) |
+ SCRRIGHT8( cptr[1], ( 8 - shift ) ) ;
+ if ( ( wrap = x + 8 - Width ) > 0 ) {
+ bits &= SCRLEFT8( 0xFF, wrap ) ;
+ bits |= SCRRIGHT8( *lineptr, ( 8 - wrap ) ) ;
+ }
+
+ return bits ;
+}
+
+static void
+DoMono
+(
+ WindowPtr pWin, /* GJA */
+ int w,
+ int x,
+ int y,
+ register const unsigned char *mastersrc,
+ int h,
+ unsigned int width,
+ register unsigned int paddedByteWidth,
+ unsigned int height,
+ int xshift,
+ int yshift,
+ int alu,
+ int planes,
+ int fg
+)
+{
+ int dy, dx, i;
+ int byte;
+
+ for ( dy = 0 ; dy < h ; dy++ ) {
+ for ( dx = 0; dx <= w - 8 ; dx += 8 ) {
+ /* get next byte */
+ byte = xygetbits(dx+xshift,dy+yshift,width,
+ paddedByteWidth, height, mastersrc);
+ for ( i = 0 ; i < 8 ; i++ ) {
+ if ( byte & (128 >> i) ) {
+ DO_ROP(fg,SAVEDSCREEN(pWin,x+dx+i,y+dy),
+ alu,planes);
+ }
+ }
+ }
+ /* get last bits */
+ byte = xygetbits(dx+xshift,dy+yshift,width,
+ paddedByteWidth, height, mastersrc);
+ for ( i = 0 ; i < (w - dx) ; i++ ) {
+ if ( byte & (128 >> i) ) {
+ DO_ROP(fg,SAVEDSCREEN(pWin,x+dx+i,y+dy),
+ alu,planes);
+ }
+ }
+ }
+}
+
+void
+xf4bppOffDrawMonoImage( pWin, data, x, y, w, h, fg, alu, planes )
+WindowPtr pWin; /* GJA */
+unsigned char *data;
+int x, y, w, h ;
+unsigned long int fg ;
+int alu ;
+unsigned long int planes;
+{
+
+ if ( ( alu == GXnoop ) || !( planes &= VGA_ALLPLANES ) )
+ return ;
+
+ DoMono( pWin, w, x, y, (const unsigned char *) data, h,
+ w, ( ( w + 31 ) & ~31 ) >> 3, h, 0, 0, alu,
+ (int)planes, (int)fg) ;
+
+}
+
+void
+xf4bppOffFillStipple( pWin, pStipple, fg, alu, planes, x, y, w, h, xSrc, ySrc )
+WindowPtr pWin; /* GJA */
+register PixmapPtr const pStipple ;
+unsigned long int fg ;
+const int alu ;
+unsigned long int planes ;
+int x, y, w, h ;
+const int xSrc, ySrc ;
+{
+ unsigned int width ;
+ unsigned int height ;
+ int xshift ;
+ int yshift ;
+
+ if ( ( alu == GXnoop ) || !( planes &= VGA_ALLPLANES ) )
+ return ;
+
+ /* Figure Bit Offsets & Source Address */
+ width = pStipple->drawable.width ;
+ if ( ( xshift = ( x - xSrc ) ) < 0 )
+ xshift = width - ( ( - xshift ) % width ) ;
+ else
+ xshift %= width ;
+
+ height = pStipple->drawable.height ;
+ if ( ( yshift = ( y - ySrc ) ) < 0 )
+ yshift = height - ( ( - yshift ) % height ) ;
+ else
+ yshift %= height ;
+
+ DoMono( pWin, w, x, y,
+ (const unsigned char *) pStipple->devPrivate.ptr,
+ h,
+ width,
+ ( ( width + 31 ) & (unsigned)(~31) ) >> 3,
+ height,
+ xshift, yshift,
+ alu, (int)planes, (int)fg ) ;
+ return ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcArea.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcArea.c
new file mode 100644
index 000000000..e9b7d0199
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcArea.c
@@ -0,0 +1,96 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcArea.c,v 1.3 1999/06/06 08:48:57 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+/* $XConsortium: ppcArea.c /main/4 1996/02/21 17:57:02 kaleb $ */
+
+/*
+ * ppc solid area fill
+ *
+ * Tom Paquin 8/87
+ */
+
+#include "xf4bpp.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "ppcGCstr.h"
+#include "ibmTrace.h"
+
+void
+xf4bppAreaFill( pWin, nboxes, pBox, pGC )
+ register WindowPtr pWin ;
+ register int nboxes ;
+ register BoxPtr pBox ;
+ GCPtr pGC ;
+{
+register int x, y, w, h ;
+int alu ;
+unsigned long int fg, bg, pm ;
+int xSrc, ySrc ;
+PixmapPtr pPixmap ;
+
+TRACE( ( "xf4bppAreaFill(0x%x,%d,0x%x,0x%x)\n", pWin, nboxes, pBox, pGC ) ) ;
+
+if ( ( alu = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.alu ) == GXnoop
+ || !nboxes )
+ return ;
+
+xSrc = pGC->patOrg.x + pWin->drawable.x ;
+ySrc = pGC->patOrg.y + pWin->drawable.y ;
+
+pm = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.planemask ;
+fg = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.fgPixel ;
+bg = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.bgPixel ;
+
+nboxes++ ;
+switch ( ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.fillStyle ) {
+ case FillTiled:
+ for ( pPixmap = pGC->tile.pixmap ; --nboxes ; pBox++ )
+ if ( ( w = pBox->x2 - ( x = pBox->x1 ) )
+ && ( h = pBox->y2 - ( y = pBox->y1 ) ) )
+ xf4bppTileRect( pWin, pPixmap, alu, pm,
+ x, y, w, h, xSrc, ySrc ) ;
+ break ;
+ case FillOpaqueStippled:
+ for ( pPixmap = pGC->stipple ; --nboxes ; pBox++ )
+ if ( ( w = pBox->x2 - ( x = pBox->x1 ) )
+ && ( h = pBox->y2 - ( y = pBox->y1 ) ) )
+ xf4bppOpaqueStipple( pWin, pPixmap, fg, bg, alu, pm,
+ x, y, w, h, xSrc, ySrc ) ;
+ break ;
+ case FillStippled:
+ for ( pPixmap = pGC->stipple ; --nboxes ; pBox++ )
+ if ( ( w = pBox->x2 - ( x = pBox->x1 ) )
+ && ( h = pBox->y2 - ( y = pBox->y1 ) ) )
+ xf4bppFillStipple( pWin, pPixmap, fg, alu, pm,
+ x, y, w, h, xSrc, ySrc ) ;
+ break ;
+ case FillSolid:
+ for ( ; --nboxes ; pBox++ )
+ if ( ( w = pBox->x2 - ( x = pBox->x1 ) )
+ && ( h = pBox->y2 - ( y = pBox->y1 ) ) )
+ xf4bppFillSolid( pWin, fg, alu, pm, x, y, w, h ) ;
+ break ;
+}
+
+return ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcBStore.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcBStore.c
new file mode 100644
index 000000000..a1f49a486
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcBStore.c
@@ -0,0 +1,153 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcBStore.c,v 1.3 1999/06/06 08:48:57 dawes Exp $ */
+/*
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+
+Copyright IBM Corporation 1987,1988,1989
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of IBM not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+
+Copyright 1987 by the Regents of the University of California
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+*/
+/* $XConsortium: ppcBStore.c /main/5 1996/02/21 17:57:06 kaleb $ */
+
+#include "xf4bpp.h"
+#include "vgaVideo.h"
+#include "ibmTrace.h"
+
+/*-----------------------------------------------------------------------
+ * xf4bppSaveAreas --
+ * Function called by miSaveAreas to actually fetch the areas to be
+ * saved into the backing pixmap.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Data are copied from the screen into the pixmap.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+xf4bppSaveAreas( pPixmap, prgnSave, xorg, yorg, pWin )
+ register PixmapPtr pPixmap ; /* Backing pixmap */
+ RegionPtr prgnSave ; /* Region to save (pixmap-relative) */
+ int xorg ; /* X origin of region */
+ int yorg ; /* Y origin of region */
+ WindowPtr pWin;
+{
+ register BoxPtr pBox ;
+ register int nBox ;
+
+ TRACE( ( "xf4bppSaveAreas(0x%x,0x%x,%d,%d)\n",
+ pPixmap, prgnSave, xorg, yorg ) ) ;
+/* WHOOP WHOOP WHOOP XXX -- depth 8 *only* */ /* GJA -- ? */
+
+ if ( !( nBox = REGION_NUM_RECTS(prgnSave) ) )
+ return ;
+
+ for ( pBox = REGION_RECTS(prgnSave) ; nBox-- ; pBox++ )
+ xf4bppReadColorImage( pWin, pBox->x1 + xorg,
+ pBox->y1 + yorg,
+ pBox->x2 - pBox->x1,
+ pBox->y2 - pBox->y1,
+ ( (unsigned char *) pPixmap->devPrivate.ptr )
+ + ( pBox->y1 * pPixmap->devKind ) + pBox->x1,
+ pPixmap->devKind ) ;
+
+ return ;
+}
+
+/*-----------------------------------------------------------------------
+ * xf4bppRestoreAreas --
+ * Function called by miRestoreAreas to actually fetch the areas to be
+ * restored from the backing pixmap.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Data are copied from the pixmap into the screen.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+xf4bppRestoreAreas( pPixmap, prgnRestore, xorg, yorg, pWin )
+ register PixmapPtr pPixmap ; /* Backing pixmap */
+ RegionPtr prgnRestore ; /* Region to restore (screen-relative)*/
+ int xorg ; /* X origin of window */
+ int yorg ; /* Y origin of window */
+ WindowPtr pWin;
+{
+ register BoxPtr pBox ;
+ register int nBox ;
+
+ TRACE( ( "xf4bppRestoreAreas(0x%x,0x%x,%d,%d)\n",
+ pPixmap, prgnRestore, xorg, yorg ) ) ;
+/* WHOOP WHOOP WHOOP XXX -- depth 8 *only* */
+
+ if ( !( nBox = REGION_NUM_RECTS(prgnRestore) ) )
+ return ;
+ for ( pBox = REGION_RECTS(prgnRestore) ; nBox-- ; pBox++ )
+ xf4bppDrawColorImage( pWin, pBox->x1,
+ pBox->y1,
+ pBox->x2 - pBox->x1,
+ pBox->y2 - pBox->y1,
+ ( (unsigned char *)pPixmap->devPrivate.ptr )
+ + ( ( pBox->y1 - yorg ) * pPixmap->devKind )
+ + ( pBox->x1 - xorg ),
+ pPixmap->devKind,
+ GXcopy, VGA_ALLPLANES ) ;
+ return ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcCReduce.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcCReduce.c
new file mode 100644
index 000000000..a68f5faff
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcCReduce.c
@@ -0,0 +1,236 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcCReduce.c,v 1.3 1999/06/06 08:48:58 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+
+/* $XConsortium: ppcCReduce.c /main/3 1996/02/21 17:57:17 kaleb $ */
+
+#include "xf4bpp.h"
+#include "ppcGCstr.h"
+
+/* xf4bppGetReducedColorRrop( pGC, drawableDepth, returnLoc )
+ * An attempt to do "strength reduction" on color raster-ops
+ * P. Shupak 1/88
+ */
+
+static void
+ppcReduceGeneral
+(
+ register int alu,
+ register unsigned long pm,
+ register unsigned long fg,
+ register unsigned long bg,
+ register int fillStyle,
+ int drawableDepth,
+ ppcReducedRrop *returnLoc
+)
+{
+
+if ( ( alu == GXnoop )
+ || !( pm &= ( ( 1 << drawableDepth ) - 1 ) ) ) {
+ returnLoc->alu = GXnoop ;
+ return ;
+}
+
+#ifdef DELETE_THIS
+switch ( fillStyle ) {
+ case FillTiled:
+ switch ( alu ) {
+ case GXclear: /* 0x0 Zero 0 */
+ case GXinvert: /* 0xa NOT dst */
+ case GXset: /* 0xf 1 */
+ fillStyle = FillSolid ;
+ default: /* We Can't Do Much Here */
+ break ;
+ }
+ break ;
+ case FillOpaqueStippled:
+ if ( ( fg & pm ) != ( bg & pm ) ) { /* else FillSolid */
+ switch ( alu ) {
+ case GXclear: /* 0x0 Zero 0 */
+ case GXset: /* 0xf 1 */
+ case GXinvert: /* 0xa NOT dst */
+ fillStyle = FillSolid ;
+ break ;
+ case GXnor: /* 0x8 NOT src AND NOT dst */
+ case GXnand: /* 0xe NOT src OR NOT dst */
+ case GXcopy: /* 0x3 src */
+ break ;
+ case GXandReverse: /* 0x2 src AND NOT dst */
+ fg = ~fg ;
+ bg = ~bg ;
+ alu = GXnor ;
+ break ;
+ case GXandInverted: /* 0x4 NOT src AND dst */
+ fg = ~fg ;
+ bg = ~bg ;
+ alu = GXand ; /* Fall Through */
+ case GXand: /* 0x1 src AND dst */
+ pm &= ~( fg & bg ) ;
+ if ( ( bg & pm ) == pm ) {
+ fillStyle = FillStippled ;
+ alu = GXclear ;
+ }
+ break ;
+ case GXequiv: /* 0x9 NOT src XOR dst */
+ fg = ~fg ;
+ bg = ~bg ;
+ alu = GXxor ; /* Fall Through */
+ case GXxor: /* 0x6 src XOR dst */
+ pm &= ( fg | bg ) ;
+ if ( !( bg & pm ) ) {
+ fillStyle = FillStippled ;
+ alu = GXinvert ;
+ }
+ break ;
+ case GXorReverse: /* 0xb src OR NOT dst */
+ fg = ~fg ;
+ bg = ~bg ;
+ alu = GXnand ;
+ break ;
+ case GXcopyInverted: /* 0xc NOT src */
+ fg = ~fg ;
+ bg = ~bg ;
+ alu = GXcopy ;
+ break ;
+ case GXorInverted: /* 0xd NOT src OR dst */
+ fg = ~fg ;
+ bg = ~bg ;
+ alu = GXor ; /* Fall Through */
+ case GXor: /* 0x7 src OR dst */
+ pm &= ( fg | bg ) ;
+ if ( !( bg & pm ) ) {
+ fillStyle = FillStippled ;
+ alu = GXset ;
+ }
+ break ;
+ default:
+ ErrorF(
+ "xf4bppGetReducedColorRrop: Unknown Alu Raster-Op" ) ;
+ break ;
+ }
+ break ; /* Don't Fall Through */
+ }
+ else
+ fillStyle = FillSolid ;
+ /* Fall Through */
+ case FillStippled:
+ case FillSolid:
+ switch ( alu ) {
+ case GXclear: /* 0x0 Zero 0 */
+ case GXset: /* 0xf 1 */
+ case GXinvert: /* 0xa NOT dst */
+ break ;
+ case GXand: /* 0x1 src AND dst */
+ pm &= ~fg ;
+ alu = GXclear ;
+ break ;
+ case GXandReverse: /* 0x2 src AND NOT dst */
+ fg = ~fg ;
+ alu = GXnor ; /* Fall Through */
+ case GXnor: /* 0x8 NOT src AND NOT dst */
+ if ( !( fg & pm ) )
+ alu = GXclear ;
+ else if ( ( fg & pm ) == pm )
+ alu = GXinvert ;
+ break ;
+ case GXandInverted: /* 0x4 NOT src AND dst */
+ pm &= fg ;
+ alu = GXclear ;
+ break ;
+ case GXxor: /* 0x6 src XOR dst */
+ pm &= fg ;
+ alu = GXinvert ;
+ break ;
+ case GXor: /* 0x7 src OR dst */
+ pm &= fg ;
+ alu = GXset ;
+ break ;
+ case GXequiv: /* 0x9 NOT src XOR dst */
+ pm &= ~fg ;
+ alu = GXinvert ;
+ break ;
+ case GXorReverse: /* 0xb src OR NOT dst */
+ fg = ~fg ;
+ alu = GXnand ; /* Fall Through */
+ case GXnand: /* 0xe NOT src OR NOT dst */
+ if ( !( fg & pm ) )
+ alu = GXset ;
+ else if ( ( fg & pm ) == pm )
+ alu = GXinvert ;
+ break ;
+ case GXcopyInverted: /* 0xc NOT src */
+ fg = ~fg ;
+ alu = GXcopy ; /* Fall Through */
+ case GXcopy: /* 0x3 src */
+ if ( !( fg & pm ) )
+ alu = GXclear ;
+ else if ( ( fg & pm ) == pm )
+ alu = GXset ;
+ break ;
+ case GXorInverted: /* 0xd NOT src OR dst */
+ pm &= ~fg ;
+ alu = GXset ;
+ break ;
+ default:
+ ErrorF(
+ "xf4bppGetReducedColorRrop: Unknown Alu Raster-Op" ) ;
+ break ;
+ }
+ break;
+ default:
+ ErrorF("xf4bppGetReducedColorRrop: Bad Fillstyle\n");
+ break;
+}
+#endif
+
+/* Final Test On Restricted Plane Mask */
+if ( !pm )
+ alu = GXnoop ;
+
+/* Set Actual Returned Values */
+returnLoc->planemask = pm ;
+returnLoc->fgPixel = fg ;
+returnLoc->bgPixel = bg ;
+returnLoc->alu = alu ;
+returnLoc->fillStyle = fillStyle ;
+
+return ;
+}
+
+void
+xf4bppGetReducedColorRrop( pGC, drawableDepth, returnLoc )
+GC *pGC ;
+int drawableDepth ;
+ppcReducedRrop *returnLoc ;
+{
+
+ppcReduceGeneral( pGC->alu,
+ pGC->planemask,
+ pGC->fgPixel,
+ pGC->bgPixel,
+ pGC->fillStyle,
+ drawableDepth,
+ returnLoc ) ;
+
+return ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcClip.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcClip.c
new file mode 100644
index 000000000..0ce331a59
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcClip.c
@@ -0,0 +1,154 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcClip.c,v 1.4 1999/06/06 08:48:58 dawes Exp $ */
+/*
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+
+Copyright IBM Corporation 1987,1988,1989
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of IBM not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XConsortium: ppcClip.c /main/4 1996/02/21 17:57:21 kaleb $ */
+
+#include "xf4bpp.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "scrnintstr.h"
+
+void
+xf4bppDestroyClip(pGC)
+ GCPtr pGC;
+{
+ if(pGC->clientClipType == CT_NONE)
+ return;
+ else if (pGC->clientClipType == CT_PIXMAP)
+ {
+ mfbDestroyPixmap((PixmapPtr)(pGC->clientClip));
+ }
+ else
+ {
+ /* we know we'll never have a list of rectangles, since
+ ChangeClip immediately turns them into a region
+ */
+ (*pGC->pScreen->RegionDestroy)(pGC->clientClip);
+ }
+ pGC->clientClip = NULL;
+ pGC->clientClipType = CT_NONE;
+}
+
+void
+xf4bppChangeClip(pGC, type, pvalue, nrects)
+ GCPtr pGC;
+ int type;
+ pointer pvalue;
+ int nrects;
+{
+ xf4bppDestroyClip(pGC);
+ if(type == CT_PIXMAP)
+ {
+ /* convert the pixmap to a region */
+ pGC->clientClip = (pointer) (*pGC->pScreen->BitmapToRegion)((PixmapPtr)pvalue);
+ /* you wouldn't do this if you were leaving the pixmap in
+ rather than converting it.
+ */
+ (*pGC->pScreen->DestroyPixmap)(pvalue);
+ }
+ else if (type == CT_REGION)
+ {
+ /* stuff the region in the GC */
+ pGC->clientClip = pvalue;
+ }
+ else if (type != CT_NONE)
+ {
+ pGC->clientClip = (pointer) (*pGC->pScreen->RectsToRegion)(nrects,
+ (xRectangle *)pvalue,
+ type);
+ xfree(pvalue);
+ }
+ pGC->clientClipType = (type != CT_NONE && pGC->clientClip) ? CT_REGION :
+ CT_NONE;
+ pGC->stateChanges |= GCClipMask;
+}
+
+void
+xf4bppCopyClip (pgcDst, pgcSrc)
+ GCPtr pgcDst, pgcSrc;
+{
+ RegionPtr prgnNew;
+
+ switch(pgcSrc->clientClipType)
+ {
+ case CT_PIXMAP:
+ ((PixmapPtr) pgcSrc->clientClip)->refcnt++;
+ /* Fall through !! */
+ case CT_NONE:
+ xf4bppChangeClip(pgcDst, pgcSrc->clientClipType, pgcSrc->clientClip, 0);
+ break;
+ case CT_REGION:
+ prgnNew = (*pgcSrc->pScreen->RegionCreate)(NULL, 1);
+ (*pgcSrc->pScreen->RegionCopy)(prgnNew,
+ (RegionPtr)(pgcSrc->clientClip));
+ xf4bppChangeClip(pgcDst, CT_REGION, (pointer)prgnNew, 0);
+ break;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcCpArea.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcCpArea.c
new file mode 100644
index 000000000..bcf094b7d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcCpArea.c
@@ -0,0 +1,490 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcCpArea.c,v 1.3 1999/06/06 08:48:58 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+
+/* $XConsortium: ppcCpArea.c /main/6 1996/02/21 17:57:24 kaleb $ */
+
+/***********************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#include "xf4bpp.h"
+#include "mfbmap.h"
+#define PSZ 8
+#include "cfb.h"
+#include "cfbmskbits.h"
+#include "mergerop.h"
+#include "mi.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+/*
+ * Graft in the DoBitblt from cfb. It does everything correctly.
+ */
+static void
+vga16DoBitblt
+(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ int alu,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc,
+ unsigned long planemask
+)
+{
+ unsigned long *psrcBase, *pdstBase;
+ /* start of src and dst bitmaps */
+ int widthSrc, widthDst; /* add to get to same position in next line */
+
+ BoxPtr pbox;
+ int nbox;
+
+ BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
+ /* temporaries for shuffling rectangles */
+ DDXPointPtr pptTmp, pptNew1, pptNew2;
+ /* shuffling boxes entails shuffling the
+ source points too */
+ int w, h;
+ int xdir; /* 1 = left right, -1 = right left/ */
+ int ydir; /* 1 = top down, -1 = bottom up */
+
+ MROP_DECLARE_REG()
+
+ int careful;
+
+ MROP_INITIALIZE(alu,planemask);
+
+ cfbGetLongWidthAndPointer (pSrc, widthSrc, psrcBase)
+
+ cfbGetLongWidthAndPointer (pDst, widthDst, pdstBase)
+
+ /* XXX we have to err on the side of safety when both are windows,
+ * because we don't know if IncludeInferiors is being used.
+ */
+ careful = ((pSrc == pDst) ||
+ ((pSrc->type == DRAWABLE_WINDOW) &&
+ (pDst->type == DRAWABLE_WINDOW)));
+
+ pbox = REGION_RECTS(prgnDst);
+ nbox = REGION_NUM_RECTS(prgnDst);
+
+ pboxNew1 = NULL;
+ pptNew1 = NULL;
+ pboxNew2 = NULL;
+ pptNew2 = NULL;
+ if (careful && (pptSrc->y < pbox->y1))
+ {
+ /* walk source botttom to top */
+ ydir = -1;
+ widthSrc = -widthSrc;
+ widthDst = -widthDst;
+
+ if (nbox > 1)
+ {
+ /* keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ if(!pboxNew1)
+ return;
+ pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pptNew1)
+ {
+ DEALLOCATE_LOCAL(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox)
+ {
+ while ((pboxNext >= pbox) &&
+ (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp <= pboxBase)
+ {
+ *pboxNew1++ = *pboxTmp++;
+ *pptNew1++ = *pptTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ pptNew1 -= nbox;
+ pptSrc = pptNew1;
+ }
+ }
+ else
+ {
+ /* walk source top to bottom */
+ ydir = 1;
+ }
+
+ if (careful && (pptSrc->x < pbox->x1))
+ {
+ /* walk source right to left */
+ xdir = -1;
+
+ if (nbox > 1)
+ {
+ /* reverse order of rects in each band */
+ pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pboxNew2 || !pptNew2)
+ {
+ if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
+ if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
+ if (pboxNew1)
+ {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox)
+ {
+ while ((pboxNext < pbox+nbox) &&
+ (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp != pboxBase)
+ {
+ *pboxNew2++ = *--pboxTmp;
+ *pptNew2++ = *--pptTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ pptNew2 -= nbox;
+ pptSrc = pptNew2;
+ }
+ }
+ else
+ {
+ /* walk source left to right */
+ xdir = 1;
+ }
+
+ while(nbox--)
+ {
+ w = pbox->x2 - pbox->x1;
+ h = pbox->y2 - pbox->y1;
+
+ if( pSrc->type == DRAWABLE_WINDOW )
+ xf4bppBitBlt( (WindowPtr)pDst, alu, planemask,
+ pptSrc->x, /* x0 */
+ pptSrc->y, /* y0 */
+ pbox->x1, /* x1 */
+ pbox->y1, /* y1 */
+ w, h ); /* w, h */
+ else /* DRAWABLE_PIXMAP */
+ xf4bppDrawColorImage( (WindowPtr)pDst,
+ pbox->x1, pbox->y1,
+ w,
+ h,
+ ((unsigned char *)((PixmapPtr)pSrc)->devPrivate.ptr
+ + pptSrc->x + (pptSrc->y*((PixmapPtr)pSrc)->devKind)),
+ ((PixmapPtr)pSrc)->devKind,
+ alu, planemask ) ;
+ pbox++;
+ pptSrc++;
+ }
+ if (pboxNew2)
+ {
+ DEALLOCATE_LOCAL(pptNew2);
+ DEALLOCATE_LOCAL(pboxNew2);
+ }
+ if (pboxNew1)
+ {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+}
+
+
+/*
+ * Graft in the CopyArea from mfb/cfb. It does everything correctly.
+ */
+
+RegionPtr
+xf4bppCopyArea(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty)
+register DrawablePtr pSrcDrawable;
+register DrawablePtr pDstDrawable;
+register GC *pGC;
+int srcx, srcy;
+int width, height;
+int dstx, dsty;
+{
+ RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */
+ Bool freeSrcClip = FALSE;
+
+ RegionPtr prgnExposed;
+ RegionRec rgnDst;
+ DDXPointPtr pptSrc;
+ register DDXPointPtr ppt;
+ register BoxPtr pbox;
+ int i;
+ register int dx;
+ register int dy;
+ xRectangle origSource;
+ DDXPointRec origDest;
+ int numRects;
+ BoxRec fastBox;
+ int fastClip = 0; /* for fast clipping with pixmap source */
+ int fastExpose = 0; /* for fast exposures with pixmap source */
+
+ if ( pDstDrawable->type != DRAWABLE_WINDOW )
+ return miCopyArea( pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty ) ;
+
+ /* Begin code from mfb/cfbCopyArea */
+
+ origSource.x = srcx;
+ origSource.y = srcy;
+ origSource.width = width;
+ origSource.height = height;
+ origDest.x = dstx;
+ origDest.y = dsty;
+
+ if ((pSrcDrawable != pDstDrawable) &&
+ pSrcDrawable->pScreen->SourceValidate)
+ {
+ (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, srcx, srcy, width, height);
+ }
+
+ srcx += pSrcDrawable->x;
+ srcy += pSrcDrawable->y;
+
+ /* clip the source */
+
+ if (pSrcDrawable->type == DRAWABLE_PIXMAP)
+ {
+ if ((pSrcDrawable == pDstDrawable) &&
+ (pGC->clientClipType == CT_NONE))
+ {
+ prgnSrcClip = pGC->pCompositeClip;
+ }
+ else
+ {
+ fastClip = 1;
+ }
+ }
+ else
+ {
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ if (!((WindowPtr) pSrcDrawable)->parent)
+ {
+ /*
+ * special case bitblt from root window in
+ * IncludeInferiors mode; just like from a pixmap
+ */
+ fastClip = 1;
+ }
+ else if ((pSrcDrawable == pDstDrawable) &&
+ (pGC->clientClipType == CT_NONE))
+ {
+ prgnSrcClip = pGC->pCompositeClip;
+ }
+ else
+ {
+ prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
+ freeSrcClip = TRUE;
+ }
+ }
+ else
+ {
+ prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
+ }
+ }
+
+ fastBox.x1 = srcx;
+ fastBox.y1 = srcy;
+ fastBox.x2 = srcx + width;
+ fastBox.y2 = srcy + height;
+
+ /* Don't create a source region if we are doing a fast clip */
+ if (fastClip)
+ {
+ fastExpose = 1;
+ /*
+ * clip the source; if regions extend beyond the source size,
+ * make sure exposure events get sent
+ */
+ if (fastBox.x1 < pSrcDrawable->x)
+ {
+ fastBox.x1 = pSrcDrawable->x;
+ fastExpose = 0;
+ }
+ if (fastBox.y1 < pSrcDrawable->y)
+ {
+ fastBox.y1 = pSrcDrawable->y;
+ fastExpose = 0;
+ }
+ if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
+ {
+ fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
+ fastExpose = 0;
+ }
+ if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
+ {
+ fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
+ fastExpose = 0;
+ }
+ }
+ else
+ {
+ (*pGC->pScreen->RegionInit)(&rgnDst, &fastBox, 1);
+ (*pGC->pScreen->Intersect)(&rgnDst, &rgnDst, prgnSrcClip);
+ }
+
+ dstx += pDstDrawable->x;
+ dsty += pDstDrawable->y;
+
+ if (pDstDrawable->type == DRAWABLE_WINDOW)
+ {
+ if (!((WindowPtr)pDstDrawable)->realized)
+ {
+ if (!fastClip)
+ (*pGC->pScreen->RegionUninit)(&rgnDst);
+ if (freeSrcClip)
+ (*pGC->pScreen->RegionDestroy)(prgnSrcClip);
+ return NULL;
+ }
+ }
+
+ dx = srcx - dstx;
+ dy = srcy - dsty;
+
+ /* Translate and clip the dst to the destination composite clip */
+ if (fastClip)
+ {
+ RegionPtr cclip;
+
+ /* Translate the region directly */
+ fastBox.x1 -= dx;
+ fastBox.x2 -= dx;
+ fastBox.y1 -= dy;
+ fastBox.y2 -= dy;
+
+ /* If the destination composite clip is one rectangle we can
+ do the clip directly. Otherwise we have to create a full
+ blown region and call intersect */
+ cclip = pGC->pCompositeClip;
+ if (REGION_NUM_RECTS(cclip) == 1)
+ {
+ BoxPtr pBox = REGION_RECTS(cclip);
+
+ if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
+ if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
+ if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
+ if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
+
+ /* Check to see if the region is empty */
+ if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2)
+ (*pGC->pScreen->RegionInit)(&rgnDst, NullBox, 0);
+ else
+ (*pGC->pScreen->RegionInit)(&rgnDst, &fastBox, 1);
+ }
+ else
+ {
+ /* We must turn off fastClip now, since we must create
+ a full blown region. It is intersected with the
+ composite clip below. */
+ fastClip = 0;
+ (*pGC->pScreen->RegionInit)(&rgnDst, &fastBox,1);
+ }
+ }
+ else
+ {
+ (*pGC->pScreen->TranslateRegion)(&rgnDst, -dx, -dy);
+ }
+
+ if (!fastClip)
+ {
+ (*pGC->pScreen->Intersect)(&rgnDst, &rgnDst, pGC->pCompositeClip);
+ }
+
+ /* Do bit blitting */
+ numRects = REGION_NUM_RECTS(&rgnDst);
+ if (numRects && width && height)
+ {
+ if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects *
+ sizeof(DDXPointRec))))
+ {
+ (*pGC->pScreen->RegionUninit)(&rgnDst);
+ if (freeSrcClip)
+ (*pGC->pScreen->RegionDestroy)(prgnSrcClip);
+ return NULL;
+ }
+ pbox = REGION_RECTS(&rgnDst);
+ ppt = pptSrc;
+ for (i = numRects; --i >= 0; pbox++, ppt++)
+ {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ vga16DoBitblt(pSrcDrawable, pDstDrawable, pGC->alu,
+ &rgnDst, pptSrc, pGC->planemask );
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+
+ prgnExposed = NULL;
+ if (pGC->fExpose)
+ {
+ /* Pixmap sources generate a NoExposed (we return NULL to do this) */
+ if (!fastExpose)
+ prgnExposed =
+ miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
+ origSource.x, origSource.y,
+ (int)origSource.width,
+ (int)origSource.height,
+ origDest.x, origDest.y, (unsigned long)0);
+ }
+ (*pGC->pScreen->RegionUninit)(&rgnDst);
+ if (freeSrcClip)
+ (*pGC->pScreen->RegionDestroy)(prgnSrcClip);
+ return prgnExposed;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcDepth.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcDepth.c
new file mode 100644
index 000000000..919fa0133
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcDepth.c
@@ -0,0 +1,52 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcDepth.c,v 1.3 1999/06/06 08:48:58 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+
+/* $XConsortium: ppcDepth.c /main/3 1996/02/21 17:57:31 kaleb $ */
+
+/* Check to see if the alleged depth is acceptable for the Screen
+ *
+ * T. Paquin 9/87
+ *
+ */
+
+#include "xf4bpp.h"
+#include "scrnintstr.h"
+
+Bool
+xf4bppDepthOK(pDraw,depth)
+register DrawablePtr pDraw;
+register int depth;
+{
+register ScreenPtr pScreen= pDraw->pScreen;
+register int i = pScreen->numDepths;
+
+ if ( ( pDraw->type == DRAWABLE_PIXMAP ) && ( depth == 1 ) )
+ return TRUE ;
+
+ while ( i-- )
+ if ( depth == pScreen->allowedDepths[i].depth )
+ return TRUE ;
+
+ return FALSE ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcFillRct.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcFillRct.c
new file mode 100644
index 000000000..b56b5eb31
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcFillRct.c
@@ -0,0 +1,220 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcFillRct.c,v 1.3 1999/06/06 08:48:59 dawes Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ppcFillRct.c /main/5 1996/02/21 17:57:35 kaleb $ */
+
+#include "xf4bpp.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "maskbits.h"
+#include "scrnintstr.h"
+
+#define MODEQ(a, b) ((a) %= (b))
+
+/*
+ filled rectangles.
+ translate the rectangles, clip them, and call the
+helper function in the GC.
+*/
+
+#define NUM_STACK_RECTS 1024
+
+void
+xf4bppPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nrectFill; /* number of rectangles to fill */
+ xRectangle *prectInit; /* Pointer to first rectangle to fill */
+{
+ xRectangle *prect;
+ RegionPtr prgnClip;
+ register BoxPtr pbox;
+ register BoxPtr pboxClipped;
+ BoxPtr pboxClippedBase;
+ BoxPtr pextent;
+ BoxRec stackRects[NUM_STACK_RECTS];
+ int numRects;
+ int n;
+ int xorg, yorg;
+ mfbPrivGC *priv;
+/* int alu; */
+ void (* pfn) ();
+/* PixmapPtr ppix; */
+
+ if (!(pGC->planemask & 0x0F)) /* GJA */
+ return;
+
+ priv = (mfbPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr;
+/* alu = priv->ropFillArea; */
+ pfn = priv->FillArea;
+/* ppix = pGC->pRotatedPixmap; */
+ prgnClip = pGC->pCompositeClip;
+
+ prect = prectInit;
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+ if (xorg || yorg)
+ {
+ prect = prectInit;
+ n = nrectFill;
+ Duff (n, prect->x += xorg; prect->y += yorg; prect++);
+ }
+
+
+ prect = prectInit;
+
+ numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
+ if (numRects > NUM_STACK_RECTS)
+ {
+ pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
+ if (!pboxClippedBase)
+ return;
+ }
+ else
+ pboxClippedBase = stackRects;
+
+ pboxClipped = pboxClippedBase;
+
+ if (REGION_NUM_RECTS(prgnClip) == 1)
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_RECTS(prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ if ((pboxClipped->x1 = prect->x) < x1)
+ pboxClipped->x1 = x1;
+
+ if ((pboxClipped->y1 = prect->y) < y1)
+ pboxClipped->y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ pboxClipped->x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ pboxClipped->y2 = by2;
+
+ prect++;
+ if ((pboxClipped->x1 < pboxClipped->x2) &&
+ (pboxClipped->y1 < pboxClipped->y2))
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ else
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = (*pGC->pScreen->RegionExtents)(prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ BoxRec box;
+
+ if ((box.x1 = prect->x) < x1)
+ box.x1 = x1;
+
+ if ((box.y1 = prect->y) < y1)
+ box.y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ box.x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ box.y2 = by2;
+
+ prect++;
+
+ if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
+ continue;
+
+ n = REGION_NUM_RECTS (prgnClip);
+ pbox = REGION_RECTS(prgnClip);
+
+ /* clip the rectangle to each box in the clip region
+ this is logically equivalent to calling Intersect()
+ */
+ while(n--)
+ {
+ pboxClipped->x1 = max(box.x1, pbox->x1);
+ pboxClipped->y1 = max(box.y1, pbox->y1);
+ pboxClipped->x2 = min(box.x2, pbox->x2);
+ pboxClipped->y2 = min(box.y2, pbox->y2);
+ pbox++;
+
+ /* see if clipping left anything */
+ if(pboxClipped->x1 < pboxClipped->x2 &&
+ pboxClipped->y1 < pboxClipped->y2)
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ }
+ if (pboxClipped != pboxClippedBase)
+ (*pfn) (pDrawable,pboxClipped-pboxClippedBase, pboxClippedBase, pGC);
+ if (pboxClippedBase != stackRects)
+ DEALLOCATE_LOCAL(pboxClippedBase);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcGC.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcGC.c
new file mode 100644
index 000000000..2958c4ad1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcGC.c
@@ -0,0 +1,459 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcGC.c,v 1.4 1999/06/06 08:48:59 dawes Exp $ */
+/*
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+
+Copyright IBM Corporation 1987,1988,1989
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of IBM not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+
+/* $XConsortium: ppcGC.c /main/6 1996/02/21 17:57:38 kaleb $ */
+
+#include "xf4bpp.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "mi.h"
+#include "scrnintstr.h"
+#include "ppcGCstr.h"
+#include "vgaVideo.h"
+#include "ibmTrace.h"
+
+#define ppcGCInterestValidateMask \
+( GCLineStyle | GCLineWidth | GCJoinStyle | GCBackground | GCForeground \
+| GCFunction | GCPlaneMask | GCFillStyle | GC_CALL_VALIDATE_BIT \
+| GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode )
+
+
+/* GJA -- we modified the following function to get rid of
+ * the records in file vgaData.c
+ */
+static GCFuncs vgaGCFuncs = {
+ xf4bppValidateGC,
+ (void (*)())NoopDDA,
+ (void (*)())NoopDDA,
+ xf4bppDestroyGC,
+ xf4bppChangeClip,
+ xf4bppDestroyClip,
+ xf4bppCopyClip
+};
+
+
+static ppcPrivGC vgaPrototypeGCPriv = {
+ GXcopy, /* unsigned char rop */
+ 0, /* unsigned char ropOpStip */
+ 0, /* unsigned char ropFillArea */
+ {0, }, /* unsigned char unused[sizeof(long) - 3] */
+ xf4bppAreaFill, /* void (* FillArea)() */
+ {
+ VGA_ALLPLANES, /* unsigned long planemask */
+ 1, /* unsigned long fgPixel */
+ 0, /* unsigned long bgPixel */
+ GXcopy, /* int alu */
+ FillSolid, /* int fillStyle */
+ }, /* ppcReducedRrop colorRrop */
+ -1, /* short lastDrawableType */
+ -1, /* short lastDrawableDepth */
+ 0 /* pointer devPriv */
+} ;
+
+static GCOps vgaGCOps = {
+ xf4bppSolidWindowFS, /* void (* FillSpans)() */
+ xf4bppSetSpans, /* void (* SetSpans)() */
+ miPutImage, /* void (* PutImage)() */
+ xf4bppCopyArea, /* RegionPtr (* CopyArea)() */
+ miCopyPlane, /* void (* CopyPlane)() */
+ xf4bppPolyPoint, /* void (* PolyPoint)() */
+ miZeroLine, /* void (* Polylines)() */
+ miPolySegment, /* void (* PolySegment)() */
+ miPolyRectangle, /* void (* PolyRectangle)() */
+ xf4bppZeroPolyArc, /* void (* PolyArc)() */
+ miFillPolygon, /* void (* FillPolygon)() */
+ miPolyFillRect, /* void (* PolyFillRect)() */
+ xf4bppPolyFillArc, /* void (* PolyFillArc)() */
+ miPolyText8, /* int (* PolyText8)() */
+ miPolyText16, /* int (* PolyText16)() */
+ miImageText8, /* void (* ImageText8)() */
+ miImageText16, /* void (* ImageText16)() */
+ (void (*)())xf4bppImageGlyphBlt, /* GJA -- void (* ImageGlyphBlt)() */
+ miPolyGlyphBlt, /* GJA -- void (* PolyGlyphBlt)() */
+ miPushPixels, /* void (* PushPixels)() */
+#ifdef NEED_LINEHELPER
+ miMiter, /* void (* LineHelper)() */
+#endif
+ NULL
+};
+
+Bool
+xf4bppCreateGC( pGC )
+register GCPtr pGC ;
+{
+ ppcPrivGC *pPriv ;
+ GCOps *pOps ;
+
+ if ( pGC->depth == 1 )
+ {
+ return (mfbCreateGC(pGC));
+ }
+
+ if ( !( pPriv = xalloc( sizeof( ppcPrivGC ) ) ) )
+ return FALSE ;
+
+ if ( !( pOps = xalloc( sizeof( GCOps ) ) ) ) {
+ xfree(pPriv);
+ return FALSE;
+ }
+
+ /* Now we initialize the GC fields */
+ pGC->miTranslate = 1;
+ pGC->unused = 0;
+ pGC->planemask = VGA_ALLPLANES;
+ pGC->fgPixel = VGA_BLACK_PIXEL;
+ pGC->bgPixel = VGA_WHITE_PIXEL;
+ pGC->funcs = &vgaGCFuncs;
+ /* ops, -- see below */
+
+ pGC->fExpose = TRUE;
+ pGC->freeCompClip = FALSE;
+ pGC->pRotatedPixmap = NullPixmap;
+
+ /* GJA: I don't like this code:
+ * they allocated a mfbPrivGC, ignore the allocated data and place
+ * a pointer to a ppcPrivGC in its slot.
+ */
+ *pPriv = vgaPrototypeGCPriv;
+ (pGC->devPrivates[mfbGCPrivateIndex].ptr) = (pointer) pPriv;
+
+ /* Set the vgaGCOps */
+ *pOps = vgaGCOps;
+ pOps->devPrivate.val = 1;
+ pGC->ops = pOps;
+
+ return TRUE ;
+}
+
+void
+xf4bppDestroyGC( pGC )
+ register GC *pGC ;
+
+{
+ TRACE( ( "xf4bppDestroyGC(pGC=0x%x)\n", pGC ) ) ;
+
+ /* (ef) 11/9/87 -- ppc doesn't use rotated tile or stipple, but */
+ /* *does* call mfbValidateGC under some conditions. */
+ /* mfbValidateGC *does* use rotated tile and stipple */
+ if ( pGC->pRotatedPixmap )
+ mfbDestroyPixmap( pGC->pRotatedPixmap ) ;
+
+ if ( pGC->freeCompClip && pGC->pCompositeClip )
+ (* pGC->pScreen->RegionDestroy)( pGC->pCompositeClip ) ;
+ if(pGC->ops->devPrivate.val) xfree( pGC->ops );
+ xfree( pGC->devPrivates[mfbGCPrivateIndex].ptr ) ;
+ return ;
+}
+
+static Mask
+ppcChangePixmapGC
+(
+ register GC *pGC,
+ register Mask changes
+)
+{
+register ppcPrivGCPtr devPriv = (ppcPrivGCPtr) (pGC->devPrivates[mfbGCPrivateIndex].ptr ) ;
+register unsigned long int idx ; /* used for stepping through bitfields */
+
+#define LOWBIT( x ) ( x & - x ) /* Two's complement */
+while ((idx = LOWBIT(changes))) {
+ switch ( idx ) {
+
+ case GCLineStyle:
+ case GCLineWidth:
+ pGC->ops->Polylines = ( ! pGC->lineWidth )
+ ? miZeroLine
+ : ( ( pGC->lineStyle == LineSolid )
+ ? miWideLine : miWideDash ) ;
+ changes &= ~( GCLineStyle | GCLineWidth ) ;
+ break ;
+
+ case GCJoinStyle:
+#ifdef NEED_LINEHELPER
+ pGC->ops->LineHelper = ( pGC->joinStyle == JoinMiter )
+ ? miMiter : miNotMiter ;
+#endif
+ changes &= ~ idx ; /* i.e. changes &= ~ GCJoinStyle */
+ break ;
+
+ case GCBackground:
+ if ( pGC->fillStyle != FillOpaqueStippled ) {
+ changes &= ~ idx ; /* i.e. changes &= ~GCBackground */
+ break ;
+ } /* else Fall Through */
+ case GCForeground:
+ if ( pGC->fillStyle == FillTiled ) {
+ changes &= ~ idx ; /* i.e. changes &= ~GCForeground */
+ break ;
+ } /* else Fall Through */
+ case GCFunction:
+ case GCPlaneMask:
+ case GCFillStyle:
+ { /* new_fill */
+ int fillStyle = devPriv->colorRrop.fillStyle ;
+ /* install a suitable fillspans */
+ if ( fillStyle == FillSolid )
+ pGC->ops->FillSpans = xf4bppSolidPixmapFS ;
+ else if ( fillStyle == FillStippled )
+ pGC->ops->FillSpans = xf4bppStipplePixmapFS ;
+ else if ( fillStyle == FillOpaqueStippled )
+ pGC->ops->FillSpans = xf4bppOpStipplePixmapFS ;
+ else /* fillStyle == FillTiled */
+ pGC->ops->FillSpans = xf4bppTilePixmapFS ;
+ changes &= ~( GCBackground | GCForeground
+ | GCFunction | GCPlaneMask | GCFillStyle ) ;
+ break ;
+ } /* end of new_fill */
+
+ default:
+ ErrorF( "ppcChangePixmapGC: Unexpected GC Change\n" ) ;
+ changes &= ~ idx ; /* Remove it anyway */
+ break ;
+ }
+}
+
+return 0 ;
+}
+
+/* Clipping conventions
+ if the drawable is a window
+ CT_REGION ==> pCompositeClip really is the composite
+ CT_other ==> pCompositeClip is the window clip region
+ if the drawable is a pixmap
+ CT_REGION ==> pCompositeClip is the translated client region
+ clipped to the pixmap boundary
+ CT_other ==> pCompositeClip is the pixmap bounding box
+*/
+
+void
+xf4bppValidateGC( pGC, changes, pDrawable )
+ register GCPtr pGC ;
+ register Mask changes ;
+ DrawablePtr pDrawable ;
+{
+ register ppcPrivGCPtr devPriv ;
+ WindowPtr pWin ;
+
+ devPriv = (ppcPrivGCPtr) (pGC->devPrivates[mfbGCPrivateIndex].ptr ) ;
+
+ if ( pDrawable->type != devPriv->lastDrawableType ) {
+ devPriv->lastDrawableType = pDrawable->type ;
+ xf4bppChangeGCtype( pGC, devPriv ) ;
+ changes = (unsigned)~0 ;
+ }
+
+ if ( pDrawable->depth == 1 ) {
+/* ibmAbort(); */
+ xf4bppNeverCalled();
+ }
+
+ if ( pDrawable->type == DRAWABLE_WINDOW ) {
+ pWin = (WindowPtr) pDrawable ;
+ pGC->lastWinOrg.x = pWin->drawable.x ;
+ pGC->lastWinOrg.y = pWin->drawable.y ;
+ }
+ else {
+ pWin = (WindowPtr) NULL ;
+ pGC->lastWinOrg.x = 0 ;
+ pGC->lastWinOrg.y = 0 ;
+ }
+
+ changes &= ppcGCInterestValidateMask ;
+ /* If Nothing REALLY Changed, Just Return */
+ if ( pDrawable->serialNumber == (pGC->serialNumber & DRAWABLE_SERIAL_BITS) )
+ if ( !( changes &= ~ GC_CALL_VALIDATE_BIT ) )
+ return ;
+
+ /* GJA -- start of cfb code */
+ /*
+ * if the client clip is different or moved OR the subwindowMode has
+ * changed OR the window's clip has changed since the last validation
+ * we need to recompute the composite clip
+ */
+
+ if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
+ (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
+ )
+ {
+ ScreenPtr pScreen = pGC->pScreen;
+
+ if (pWin) {
+ RegionPtr pregWin;
+ Bool freeTmpClip, freeCompClip;
+
+ if (pGC->subWindowMode == IncludeInferiors) {
+ pregWin = NotClippedByChildren(pWin);
+ freeTmpClip = TRUE;
+ }
+ else {
+ pregWin = &pWin->clipList;
+ freeTmpClip = FALSE;
+ }
+ freeCompClip = pGC->freeCompClip;
+
+ /*
+ * if there is no client clip, we can get by with just keeping
+ * the pointer we got, and remembering whether or not should
+ * destroy (or maybe re-use) it later. this way, we avoid
+ * unnecessary copying of regions. (this wins especially if
+ * many clients clip by children and have no client clip.)
+ */
+ if (pGC->clientClipType == CT_NONE) {
+ if (freeCompClip)
+ (*pScreen->RegionDestroy) (pGC->pCompositeClip);
+ pGC->pCompositeClip = pregWin;
+ pGC->freeCompClip = freeTmpClip;
+ }
+ else {
+ /*
+ * we need one 'real' region to put into the composite
+ * clip. if pregWin the current composite clip are real,
+ * we can get rid of one. if pregWin is real and the
+ * current composite clip isn't, use pregWin for the
+ * composite clip. if the current composite clip is real
+ * and pregWin isn't, use the current composite clip. if
+ * neither is real, create a new region.
+ */
+
+ (*pScreen->TranslateRegion)(pGC->clientClip,
+ pDrawable->x + pGC->clipOrg.x,
+ pDrawable->y + pGC->clipOrg.y);
+
+ if (freeCompClip)
+ {
+ (*pGC->pScreen->Intersect)(pGC->pCompositeClip,
+ pregWin, pGC->clientClip);
+ if (freeTmpClip)
+ (*pScreen->RegionDestroy)(pregWin);
+ }
+ else if (freeTmpClip)
+ {
+ (*pScreen->Intersect)(pregWin, pregWin, pGC->clientClip);
+ pGC->pCompositeClip = pregWin;
+ }
+ else
+ {
+ pGC->pCompositeClip = (*pScreen->RegionCreate)(NullBox, 0);
+ (*pScreen->Intersect)(pGC->pCompositeClip,
+ pregWin, pGC->clientClip);
+ }
+ pGC->freeCompClip = TRUE;
+ (*pScreen->TranslateRegion)(pGC->clientClip,
+ -(pDrawable->x + pGC->clipOrg.x),
+ -(pDrawable->y + pGC->clipOrg.y));
+
+ }
+ } /* end of composite clip for a window */
+ else {
+ BoxRec pixbounds;
+
+ /* XXX should we translate by drawable.x/y here ? */
+ pixbounds.x1 = 0;
+ pixbounds.y1 = 0;
+ pixbounds.x2 = pDrawable->width;
+ pixbounds.y2 = pDrawable->height;
+
+ if (pGC->freeCompClip)
+ (*pScreen->RegionReset)(pGC->pCompositeClip, &pixbounds);
+ else {
+ pGC->freeCompClip = TRUE;
+ pGC->pCompositeClip = (*pScreen->RegionCreate)(&pixbounds, 1);
+ }
+
+ if (pGC->clientClipType == CT_REGION)
+ {
+ (*pScreen->TranslateRegion)(pGC->pCompositeClip,
+ -pGC->clipOrg.x, -pGC->clipOrg.y);
+ (*pScreen->Intersect)(pGC->pCompositeClip,
+ pGC->pCompositeClip,
+ pGC->clientClip);
+ (*pScreen->TranslateRegion)(pGC->pCompositeClip,
+ pGC->clipOrg.x, pGC->clipOrg.y);
+ }
+ } /* end of composute clip for pixmap */
+ }
+ /* GJA -- End of cfb code */
+
+ changes &= ~ ( GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode
+ | GC_CALL_VALIDATE_BIT ) ;
+
+ /* If needed, Calculate the Color Reduced Raster-Op */
+ if ( changes & ( GCFillStyle | GCBackground | GCForeground
+ | GCPlaneMask | GCFunction ) )
+ xf4bppGetReducedColorRrop( pGC, pDrawable->depth,
+ &devPriv->colorRrop ) ;
+
+ (* ( ( pDrawable->type == DRAWABLE_WINDOW )
+ ? xf4bppChangeWindowGC
+ : ppcChangePixmapGC ) )( pGC, changes ) ;
+
+ return ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcGCstr.h b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcGCstr.h
new file mode 100644
index 000000000..7d5ce91d1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcGCstr.h
@@ -0,0 +1,94 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcGCstr.h,v 1.2 1998/07/25 16:59:34 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+*/
+/***********************************************************
+ Copyright IBM Corporation 1988
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of IBM not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+IBM 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.
+
+******************************************************************/
+/* $XConsortium: ppcGCstr.h /main/3 1996/02/21 17:57:42 kaleb $ */
+
+#include "gc.h"
+
+typedef struct {
+ unsigned long planemask ;
+ unsigned long fgPixel ;
+ unsigned long bgPixel ;
+ int alu ;
+ int fillStyle ;
+ } ppcReducedRrop ;
+
+/* ************************************************************************ */
+
+/* private field of GC */
+typedef struct {
+/* The next five (5) fields MUST CORRESPOND to
+ * the fields of a "mfbPrivGC" struct
+ * ----- BEGINNING OF "DO-NOT-CHANGE" REGION -----
+ */
+ unsigned char rop ; /* reduction of rasterop to 1 of 3 */
+ unsigned char ropOpStip ; /* rop for opaque stipple */
+ unsigned char ropFillArea ; /* == alu, rop, or ropOpStip */
+ unsigned char unused[sizeof(long) - 3];
+ void (* FillArea)() ; /* fills regions; look at the code */
+/* ----- END OF "DO-NOT-CHANGE" REGION ----- */
+ ppcReducedRrop colorRrop ;
+ short lastDrawableType ; /* was last drawable a window or a pixmap? */
+ short lastDrawableDepth ; /* was last drawable 1 or 8 planes? */
+ pointer devPriv ; /* Private area for device specific stuff */
+ } ppcPrivGC ;
+typedef ppcPrivGC *ppcPrivGCPtr ;
+
+/* ppcCReduce.c */
+void xf4bppGetReducedColorRrop(
+#if NeedFunctionPrototypes
+ GCPtr,
+ int,
+ ppcReducedRrop *
+#endif
+);
+
+/* vgaGC.c */
+void xf4bppChangeGCtype(
+#if NeedFunctionPrototypes
+ GCPtr,
+ ppcPrivGCPtr
+#endif
+);
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcGetSp.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcGetSp.c
new file mode 100644
index 000000000..b6c404e80
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcGetSp.c
@@ -0,0 +1,139 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcGetSp.c,v 1.3 1999/06/06 08:48:59 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+*/
+
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* $XConsortium: ppcGetSp.c /main/5 1996/02/21 17:57:45 kaleb $ */
+
+#include "xf4bpp.h"
+#include "OScompiler.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "servermd.h"
+#include "ibmTrace.h"
+
+/* GetSpans -- for each span, gets bits from drawable starting at ppt[i]
+ * and continuing for pwidth[i] bits
+ * Each scanline returned will be server scanline padded, i.e., it will come
+ * out to an integral number of words.
+ */
+void
+xf4bppGetSpans( pDrawable, wMax, ppt, pwidth, nspans, pdstStart )
+ DrawablePtr pDrawable ; /* drawable from which to get bits */
+ int wMax ; /* largest value of all *pwidths */
+ DDXPointPtr ppt ; /* points to start copying from */
+ int *pwidth ; /* list of number of bits to copy */
+ int nspans ; /* number of scanlines to copy */
+ char *pdstStart ;
+{
+ register int j ;
+ register unsigned char *pdst ; /* where to put the bits */
+ register unsigned char *psrc ; /* where to get the bits */
+ register int pixmapStride ;
+
+
+ TRACE( ( "xf4bppGetSpans(pDrawable=0x%x,wMax=%d,ppt=0x%x,pwidth=0x%x,nspans=%d)\n",
+ pDrawable, wMax, ppt, pwidth, nspans ) ) ;
+
+ if ( ( pDrawable->depth == 1 ) && ( pDrawable->type == DRAWABLE_PIXMAP ) )
+ {
+ mfbGetSpans( pDrawable, wMax, ppt, pwidth, nspans, pdstStart ) ;
+ return;
+ }
+
+ pixmapStride = PixmapBytePad( wMax, pDrawable->depth ) ;
+ pdst = (unsigned char *) /* GJA */ pdstStart ;
+
+ if ( pDrawable->type == DRAWABLE_WINDOW ) {
+ for ( ; nspans-- ; ppt++, pwidth++ ) {
+ xf4bppReadColorImage( (WindowPtr)pDrawable,
+ ppt->x, ppt->y, j = *pwidth, 1, pdst, pixmapStride ) ;
+ pdst += j ; /* width is in 32 bit words */
+ j = ( -j ) & 3 ;
+ while ( j-- ) /* Pad out to 32-bit boundary */
+ *pdst++ = 0 ;
+ }
+ }
+ else { /* OK, if we are here, we had better be a DRAWABLE PIXMAP */
+ register int widthSrc = /* width of pixmap in bytes */
+ (int) ( (PixmapPtr) pDrawable )->devKind ;
+
+ psrc = (unsigned char *) ( (PixmapPtr) pDrawable )->devPrivate.ptr ;
+ for ( ; nspans-- ; ppt++, pwidth++ ) {
+ MOVE( psrc + ( ppt->y * widthSrc ) + ppt->x,
+ pdst, j = *pwidth ) ;
+ pdst += j ;
+ j = ( -j ) & 3 ;
+ while ( j-- ) /* Pad out to 32-bit boundary */
+ *pdst++ = 0 ;
+ }
+ }
+ return ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcIO.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcIO.c
new file mode 100644
index 000000000..46cf5dfc6
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcIO.c
@@ -0,0 +1,253 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcIO.c,v 1.4 1999/06/06 08:48:59 dawes Exp $ */
+/*
+
+Copyright (c) 1990 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+
+Copyright IBM Corporation 1987,1988,1989
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of IBM not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+IBM 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.
+
+*/
+/* $XConsortium: ppcIO.c /main/8 1996/02/21 17:57:49 kaleb $ */
+
+#include "xf4bpp.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "mi.h"
+#include "micmap.h"
+#include "scrnintstr.h"
+#include "vgaVideo.h"
+
+#if 0
+/* XXX This remains to remind of the PC98 difference */
+static VisualRec vgaVisuals[] = {
+/* StaticColor needs to be first so is can be used as the default */
+/* vid class bpRGB cmpE nplan rMask gMask bMask oRed oGreen oBlue */
+#ifdef PC98
+{ 0, StaticColor, 4, 1 << VGA_MAXPLANES, VGA_MAXPLANES, 0, 0, 0, 0, 0, 0 },
+{ 0, StaticGray, 4, 1 << VGA_MAXPLANES, VGA_MAXPLANES, 0, 0, 0, 0, 0, 0 },
+{ 0, GrayScale, 4, 1 << VGA_MAXPLANES, VGA_MAXPLANES, 0, 0, 0, 0, 0, 0 },
+{ 0, PseudoColor, 4, 1 << VGA_MAXPLANES, VGA_MAXPLANES, 0, 0, 0, 0, 0, 0 },
+#else
+{ 0, StaticColor, 6, 1 << VGA_MAXPLANES, VGA_MAXPLANES, 0, 0, 0, 0, 0, 0 },
+{ 0, StaticGray, 6, 1 << VGA_MAXPLANES, VGA_MAXPLANES, 0, 0, 0, 0, 0, 0 },
+{ 0, GrayScale, 6, 1 << VGA_MAXPLANES, VGA_MAXPLANES, 0, 0, 0, 0, 0, 0 },
+{ 0, PseudoColor, 6, 1 << VGA_MAXPLANES, VGA_MAXPLANES, 0, 0, 0, 0, 0, 0 },
+#endif
+} ;
+#endif
+
+int
+xf4bppNeverCalled()
+{
+ ErrorF("xf4bppNeverCalled was nevertheless called\n");
+ abort();
+}
+
+static BSFuncRec ppcBSFuncRec = {
+ xf4bppSaveAreas,
+ xf4bppRestoreAreas,
+ (BackingStoreSetClipmaskRgnProcPtr) 0,
+ (BackingStoreGetImagePixmapProcPtr) 0,
+ (BackingStoreGetSpansPixmapProcPtr) 0,
+};
+
+/*ARGSUSED*/
+static Bool
+vgaScreenClose
+(
+ int idx,
+ ScreenPtr pScreen
+)
+{
+ pScreen->defColormap = 0 ;
+ return TRUE;
+}
+
+
+static GCPtr sampleGCperDepth[MAXFORMATS+1] = { 0 };
+static PixmapPtr samplePixmapPerDepth[1] = { 0 };
+
+/* GJA -- Took this from miscrinit.c.
+ * We want that devKind contains the distance in bytes between two scanlines.
+ * The computation that mi does is not appropriate for planar VGA.
+ * Therefore we provide here our own routine.
+ */
+
+/* GJA -- WARNING: this is an internal structure declaration, taken from
+ * miscrinit.c
+ */
+typedef struct
+{
+ pointer pbits; /* pointer to framebuffer */
+ int width; /* delta to add to a framebuffer addr to move one row down */
+} miScreenInitParmsRec, *miScreenInitParmsPtr;
+
+/* With the introduction of pixmap privates, the "screen pixmap" can no
+ * longer be created in miScreenInit, since all the modules that could
+ * possibly ask for pixmap private space have not been initialized at
+ * that time. pScreen->CreateScreenResources is called after all
+ * possible private-requesting modules have been inited; we create the
+ * screen pixmap here.
+ */
+static Bool
+v16CreateScreenResources
+(
+ ScreenPtr pScreen
+)
+{
+ miScreenInitParmsPtr pScrInitParms;
+ pointer value;
+
+ pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate;
+
+ /* if width is non-zero, pScreen->devPrivate will be a pixmap
+ * else it will just take the value pbits
+ */
+ if (pScrInitParms->width)
+ {
+ PixmapPtr pPixmap;
+
+ /* create a pixmap with no data, then redirect it to point to
+ * the screen
+ */
+ pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth);
+ if (!pPixmap)
+ return FALSE;
+
+ if (!(*pScreen->ModifyPixmapHeader)(pPixmap, pScreen->width,
+ pScreen->height, pScreen->rootDepth, 8 /* bits per pixel */,
+/* GJA: was PixmapBytePad(pScrInitParms->width, pScreen->rootDepth), */
+#define BITS_PER_BYTE_SHIFT 3
+ pScrInitParms->width >> BITS_PER_BYTE_SHIFT,
+ pScrInitParms->pbits))
+ return FALSE;
+ value = (pointer)pPixmap;
+ }
+ else
+ {
+ value = pScrInitParms->pbits;
+ }
+ xfree(pScreen->devPrivate); /* freeing miScreenInitParmsRec */
+ pScreen->devPrivate = value; /* pPixmap or pbits */
+ return TRUE;
+}
+
+
+Bool
+xf4bppScreenInit( pScreen, pbits, virtx, virty, dpix, dpiy, width )
+ ScreenPtr pScreen;
+ pointer pbits;
+ int virtx, virty;
+ int dpix, dpiy;
+ int width;
+{
+ Bool ret;
+ VisualPtr visuals;
+ DepthPtr depths;
+ int nvisuals;
+ int ndepths;
+ int rootdepth;
+ VisualID defaultVisual;
+
+ rootdepth = 0;
+ ret = miInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
+ &defaultVisual, (unsigned long)1 << 8, 6, -1);
+ if (!ret)
+ return FALSE;
+
+ pScreen-> id = 0;
+ pScreen->defColormap = FakeClientID(0);
+ pScreen-> whitePixel = VGA_WHITE_PIXEL;
+ pScreen-> blackPixel = VGA_BLACK_PIXEL;
+ pScreen-> rgf = 0;
+ *(pScreen-> GCperDepth) = *(sampleGCperDepth);
+ *(pScreen-> PixmapPerDepth) = *(samplePixmapPerDepth);
+ pScreen-> CloseScreen = vgaScreenClose;
+ pScreen-> QueryBestSize = xf4bppQueryBestSize;
+ pScreen-> GetImage = xf4bppGetImage;
+ pScreen-> GetSpans = xf4bppGetSpans;
+ pScreen-> CreateWindow = xf4bppCreateWindowForXYhardware;
+ pScreen-> DestroyWindow = xf4bppDestroyWindow;
+ pScreen-> PositionWindow = xf4bppPositionWindow;
+ pScreen-> ChangeWindowAttributes = mfbChangeWindowAttributes;
+ pScreen-> RealizeWindow = mfbMapWindow;
+ pScreen-> UnrealizeWindow = mfbUnmapWindow;
+ pScreen-> PaintWindowBackground = xf4bppPaintWindow;
+ pScreen-> PaintWindowBorder = xf4bppPaintWindow;
+ pScreen-> CopyWindow = xf4bppCopyWindow;
+ pScreen-> CreatePixmap = xf4bppCreatePixmap;
+ pScreen-> DestroyPixmap = mfbDestroyPixmap;
+ pScreen-> SaveDoomedAreas = (SaveDoomedAreasProcPtr)NoopDDA;
+ pScreen-> RestoreAreas = (RestoreAreasProcPtr)NoopDDA;
+ pScreen-> ExposeCopy = (ExposeCopyProcPtr)NoopDDA;
+ pScreen-> TranslateBackingStore = (TranslateBackingStoreProcPtr)NoopDDA;
+ pScreen-> ClearBackingStore = (ClearBackingStoreProcPtr)NoopDDA;
+ pScreen-> DrawGuarantee = (DrawGuaranteeProcPtr)NoopDDA;
+ pScreen-> RealizeFont = mfbRealizeFont;
+ pScreen-> UnrealizeFont = mfbUnrealizeFont;
+ pScreen-> CreateGC = xf4bppCreateGC;
+ pScreen-> CreateColormap = xf4bppInitializeColormap;
+ pScreen-> DestroyColormap = (DestroyColormapProcPtr)NoopDDA;
+ pScreen-> InstallColormap = miInstallColormap;
+ pScreen-> UninstallColormap = miUninstallColormap;
+ pScreen-> ListInstalledColormaps = miListInstalledColormaps;
+ pScreen-> StoreColors = (StoreColorsProcPtr)NoopDDA;
+ pScreen-> ResolveColor = xf4bppResolveColor;
+ pScreen-> BitmapToRegion = mfbPixmapToRegion;
+
+ if (!mfbAllocatePrivates(pScreen, (int*)NULL, (int*)NULL))
+ return FALSE;
+
+ if (!miScreenInit(pScreen, pbits, virtx, virty, dpix, dpiy, width,
+ rootdepth, ndepths, depths, defaultVisual /* See above */,
+ nvisuals, visuals))
+ return FALSE;
+ pScreen->BackingStoreFuncs = ppcBSFuncRec;
+
+ /* GJA -- Now we override the supplied default: */
+ pScreen -> CreateScreenResources = v16CreateScreenResources;
+
+ mfbRegisterCopyPlaneProc(pScreen,miCopyPlane); /* GJA -- R4->R5 */
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcImg.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcImg.c
new file mode 100644
index 000000000..b6be7683a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcImg.c
@@ -0,0 +1,140 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcImg.c,v 1.3 1999/06/06 08:49:00 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+
+/* $XConsortium: ppcImg.c /main/4 1996/02/21 17:57:53 kaleb $ */
+
+#include "xf4bpp.h"
+#include "OScompiler.h"
+#include "mi.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+
+/* GETBITSPERPIXEL -- Find out how many bits per pixel are supported at
+ * this depth -- another helper function
+ */
+static int
+GetBitsPerPixel
+(
+ int depth
+)
+{
+ register int i ;
+
+ for ( i = screenInfo.numPixmapFormats ; i-- ; )
+ if ( screenInfo.formats[i].depth == depth )
+ return screenInfo.formats[i].bitsPerPixel ;
+ return 1 ;
+}
+
+/* Was MIGETIMAGE -- public entry for the GetImage Request
+ * We're getting the image into a memory buffer. While we have to use GetSpans
+ * to read a line from the device ( since we don't know what that looks like ) ,
+ * we can just write into the destination buffer
+ *
+ * two different strategies are used, depending on whether we're getting the
+ * image in Z format or XY format
+ * Z format:
+ * Line at a time, GetSpans a line and bcopy it to the destination
+ * buffer, except that if the planemask is not all ones, we create a
+ * temporary pixmap and do a SetSpans into it ( to get bits turned off )
+ * and then another GetSpans to get stuff back ( because pixmaps are
+ * opaque, and we are passed in the memory to write into ) . This is
+ * completely ugly and slow but works, but the interfaces just aren't
+ * designed for this case. Life is hard.
+ * XY format:
+ * get the single plane specified in planemask
+ */
+void
+xf4bppGetImage( pDraw, sx, sy, w, h, format, planeMask, pdstLine )
+ DrawablePtr pDraw ;
+ int sx, sy, w, h ;
+ unsigned int format ;
+ unsigned long planeMask ;
+ char * pdstLine ;
+{
+ int depth, i, linelength, width ;
+ DDXPointRec pt ;
+ char *pbits ;
+ unsigned long int gcv[2] ;
+ PixmapPtr pPixmap = (PixmapPtr) NULL ;
+ GCPtr pGC ;
+ char *pDst = pdstLine ;
+
+#if 0
+ miGetImage( pDraw, sx, sy, w, h, format, planeMask, pdstLine ) ;
+ return;
+#endif
+
+ depth = pDraw->depth ;
+ if ( format == ZPixmap ) {
+ linelength = PixmapBytePad( w, depth ) ;
+/* if ( pDraw->type == DRAWABLE_WINDOW ) { */
+ sx += pDraw->x ;
+ sy += pDraw->y ;
+/* } */
+ if ( ( ( ( 1 << pDraw->depth ) - 1 ) & planeMask )
+ != (unsigned)( 1 << pDraw->depth ) - 1 ) {
+ pGC = GetScratchGC( depth, pDraw->pScreen ) ;
+ pPixmap = (PixmapPtr)
+ (* pDraw->pScreen->CreatePixmap)( pDraw->pScreen, w, h, depth ) ;
+ gcv[0] = GXcopy ;
+ gcv[1] = planeMask ;
+ DoChangeGC( pGC, GCPlaneMask | GCFunction, gcv, 0 ) ;
+ ValidateGC( (DrawablePtr)pPixmap, pGC ) ;
+
+ pbits = (char *)ALLOCATE_LOCAL(w);
+
+ for ( i = 0 ; i < h ; i++ ) {
+ pt.x = sx ;
+ pt.y = sy + i ;
+ width = w ;
+ (* pDraw->pScreen->GetSpans)( pDraw, w, &pt, &width, 1, pbits ) ;
+ pt.x = 0 ;
+ pt.y = i ;
+ width = w ;
+ if ( planeMask & ((1 << depth) - 1) ) /* GJA -- mfb bug */
+ (* pGC->ops->SetSpans)( (DrawablePtr)pPixmap, pGC, pbits, &pt, &width, 1, TRUE ) ;
+ (* pDraw->pScreen->GetSpans)( (DrawablePtr)pPixmap, w, &pt, &width, 1, pDst ) ;
+ pDst += linelength ;
+ }
+
+ DEALLOCATE_LOCAL(pbits) ;
+ (* pGC->pScreen->DestroyPixmap)( pPixmap ) ;
+ FreeScratchGC( pGC ) ;
+ return ;
+ }
+
+ for ( i = 0 ; i < h ; i++ ) {
+ pt.x = sx ;
+ pt.y = sy + i ;
+ width = w ;
+ (* pDraw->pScreen->GetSpans)( pDraw, w, &pt, &width, 1, pDst ) ;
+ pDst += linelength ;
+ }
+ }
+ else
+ miGetImage( pDraw, sx, sy, w, h, format, planeMask, pdstLine ) ;
+
+ return ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPixFS.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPixFS.c
new file mode 100644
index 000000000..c2009a69c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPixFS.c
@@ -0,0 +1,502 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPixFS.c,v 1.3 1999/06/06 08:49:00 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+*/
+
+/******************************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ppcPixFS.c /main/3 1996/02/21 17:57:57 kaleb $ */
+
+#include "xf4bpp.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "maskbits.h"
+#include "mi.h"
+#include "mispans.h"
+#include "ppcGCstr.h"
+#include "ppcSpMcro.h"
+#include "vgaVideo.h"
+#include "ibmTrace.h"
+
+#define LeftMostBitInScreenLongWord SCRLEFT( 0xFFFFFFFF, 31 )
+
+/* GJA -- copied this from VGA */
+#define SCRLEFT8(lw, n) ( (unsigned char) (((unsigned char) lw) << (n)) )
+#define SCRRIGHT8(lw, n) ( (unsigned char) (((unsigned char)lw) >> (n)) )
+/*
+********** ********** ********** ********** ********** ********** **********
+ these routines all clip. they assume that anything that has called
+them has already translated the points (i.e. pGC->miTranslate is
+non-zero, which is howit gets set in mfbCreateGC().)
+
+ the number of new scnalines created by clipping ==
+MaxRectsPerBand * nSpans.
+********** ********** ********** ********** ********** ********** **********
+*/
+/* A mod definition that goes smoothly into the negative.
+ */
+static int
+modulo
+(
+ int n1,
+ int n2
+)
+{
+ int tmp;
+ if ( n1 < 0 ) {
+ tmp = (-n1) % n2;
+ if ( tmp == 0 ) {
+ return 0;
+ } else {
+ return n2 - tmp;
+ }
+ } else {
+ return n1 % n2;
+ }
+}
+
+void
+xf4bppSolidPixmapFS( pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted )
+ DrawablePtr pDrawable ;
+ GCPtr pGC ;
+ int nInit ; /* number of spans to fill */
+ DDXPointPtr pptInit ; /* pointer to list of start points */
+ int *pwidthInit ; /* pointer to list of n widths */
+ int fSorted ;
+{
+ register unsigned long int pm, npm ;
+ register unsigned long int fg ;
+ register int alu ;
+ /* next three parameters are post-clip */
+ int n ; /* number of spans to fill */
+ register DDXPointPtr ppt ; /* pointer to list of start points */
+ register int *pwidth ; /* pointer to list of n widths */
+ register unsigned char *addrl ; /* pointer to current longword in bitmap */
+ int i ;
+ int *pwidthFree ; /* copies of the pointers to free */
+ DDXPointPtr pptFree ;
+
+ TRACE(("xf4bppSolidPixmapFS(pDrawable=0x%x, pGC=0x%x, nInit=%d, pptInit=0x%x, pwidthInit=0x%x, fSorted=%d)\n", pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)) ;
+
+ if ( pDrawable->type != DRAWABLE_PIXMAP ) {
+ ErrorF("xf4bppSolidPixmapFS: drawable is not a pixmap\n") ;
+ return ;
+ }
+
+ if ( ( alu = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.alu ) == GXnoop )
+ return ;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip) ;
+ if ( !( pwidth = (int *) ALLOCATE_LOCAL( n * sizeof( int ) ) ) )
+ return ;
+ pwidthFree = pwidth ;
+
+ if ( !( ppt = (DDXPointRec *)
+ ALLOCATE_LOCAL( n * sizeof( DDXPointRec ) ) ) ) {
+ DEALLOCATE_LOCAL( pwidth ) ;
+ return ;
+ }
+ pptFree = ppt ;
+
+ n = miClipSpans( pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted ) ;
+
+ pm = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.planemask ;
+ fg = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.fgPixel ;
+ npm = ( ~ pm ) & ( ( 1 << pDrawable->depth ) - 1 ) ;
+
+ for ( ; n-- ; ppt++, pwidth++ ) {
+ addrl = ( (unsigned char *) ( ( (PixmapPtr) pDrawable )->devPrivate.ptr ) )
+ + ( ppt->y * ( (int) ( ( (PixmapPtr) pDrawable )->devKind ) ) )
+ + ppt->x ;
+ for ( i = *pwidth ; i-- ; addrl++ )
+ {
+ unsigned _p;
+ DoRop( _p, alu, fg, *addrl );
+ *addrl = ( *addrl & npm ) | ( pm & _p ) ;
+ }
+#ifdef notdef /* PURDUE */
+ *addrl = ( *addrl & npm ) | ( pm & DoRop( alu, fg, *addrl ) ) ;
+#endif /* PURDUE */
+ }
+ DEALLOCATE_LOCAL( pptFree ) ;
+ DEALLOCATE_LOCAL( pwidthFree ) ;
+ return ;
+}
+
+/* GJA -- copied from vgaStipple.c */
+static unsigned char
+vgagetbits
+(
+ register const int x,
+ register const unsigned int patternWidth,
+ register const unsigned char * const lineptr
+)
+{
+register unsigned char bits ;
+register const unsigned char *cptr ;
+register shift ;
+register wrap ;
+
+cptr = lineptr + ( x >> 3 ) ;
+bits = *cptr ;
+if ((shift = x & 7))
+ bits = SCRLEFT8( bits, shift ) | SCRRIGHT8( cptr[1], ( 8 - shift ) ) ;
+if ( ( wrap = x + 8 - patternWidth ) > 0 ) {
+ bits &= SCRLEFT8( 0xFF, wrap ) ;
+ bits |= SCRRIGHT8( *lineptr, ( 8 - wrap ) ) ;
+}
+
+/* GJA -- Handle extraction of 8 bits from < 8 bits wide stipple.
+ * I duplicated case 4,5,6,7 to give the compiler a chance to optimize.
+ */
+switch (patternWidth) {
+case 1: /* Not really useful. */
+ bits &= ~SCRRIGHT8(0xFF,1);
+ bits |= SCRRIGHT8(bits,1);
+ bits |= SCRRIGHT8(bits,2);
+ bits |= SCRRIGHT8(bits,4);
+ break;
+case 2:
+ bits &= ~SCRRIGHT8(0xFF,2);
+ bits |= SCRRIGHT8(bits,2); bits |= SCRRIGHT8(bits,4); break;
+case 3:
+ bits &= ~SCRRIGHT8(0xFF,3);
+ bits |= (SCRRIGHT8(bits,3) | SCRRIGHT8(bits,6)); break;
+case 4:
+ bits = (bits & ~SCRRIGHT8(0xFF,4)) | SCRRIGHT8(bits,4); break;
+case 5:
+ bits = (bits & ~SCRRIGHT8(0xFF,5)) | SCRRIGHT8(bits,5); break;
+case 6:
+ bits = (bits & ~SCRRIGHT8(0xFF,6)) | SCRRIGHT8(bits,6); break;
+case 7:
+ bits = (bits & ~SCRRIGHT8(0xFF,7)) | SCRRIGHT8(bits,7); break;
+default:
+ ;
+ /* Do nothing, of course */
+}
+
+return bits ;
+}
+
+void
+xf4bppStipplePixmapFS( pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted )
+register DrawablePtr pDrawable ;
+GC *pGC ;
+int nInit ; /* number of spans to fill */
+DDXPointPtr pptInit ; /* pointer to list of start points */
+int *pwidthInit ; /* pointer to list of n widths */
+int fSorted ;
+{
+ register unsigned char *pdst ; /* pointer to current word in bitmap */
+ register int *psrc ; /* pointer to current word in tile */
+ register unsigned long int pm, npm ;
+ register unsigned long int fg ;
+ register int alu ;
+ /* next three parameters are post-clip */
+ int n ; /* number of spans to fill */
+ register DDXPointPtr ppt ; /* pointer to list of start points */
+ register int *pwidth ; /* pointer to list of n widths */
+ PixmapPtr pTile ; /* pointer to tile we want to fill with */
+ int width, x, xSrc, ySrc ;
+ int tlwidth, tileWidth ;
+ unsigned char *psrcT ;
+ int *pwidthFree ; /* copies of the pointers to free */
+ DDXPointPtr pptFree ;
+ int xoff, count, stip, i ;
+
+ TRACE(("xf4bppStipplePixmapFS(pDrawable=0x%x, pGC=0x%x, nInit=%d, pptInit=0x%x, pwidthInit=0x%x, fSorted=%d)\n",
+ pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)) ;
+
+ if ( pDrawable->type != DRAWABLE_PIXMAP ) {
+ ErrorF( "xf4bppStippleWindowFS: drawable is not a pixmap\n") ;
+ return ;
+ }
+ if ( pGC->stipple->drawable.depth != 1 ) {
+ ErrorF( "ppcStippleFS: bad depth\ntype = %d, depth = %d\n",
+ pDrawable->type, pGC->stipple->drawable.depth ) ;
+ return ;
+ }
+
+ if ( ( alu = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.alu ) == GXnoop )
+ return ;
+
+ SETSPANPTRS( nInit, n, pwidthInit, pwidth, pptInit,
+ ppt, pwidthFree, pptFree, fSorted ) ;
+
+ pm = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.planemask ;
+ fg = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.fgPixel ;
+
+ pTile = pGC->stipple ;
+ tlwidth = pTile->devKind ;
+
+ tileWidth = pTile->drawable.width ;
+
+ npm = ( ~ pm ) & ( ( 1 << pDrawable->depth ) - 1 ) ;
+
+ /* this replaces rotating the stipple. Instead, we just adjust the offset
+ * at which we start grabbing bits from the stipple */
+ xSrc = pGC->patOrg.x + pDrawable->x;
+ ySrc = pGC->patOrg.y + pDrawable->y;
+
+ while ( n-- ) {
+ pdst = ( (unsigned char *) ( (PixmapPtr) pDrawable )->devPrivate.ptr )
+ + ( ppt->y * ( (int) ( ( (PixmapPtr) pDrawable )->devKind ) ) )
+ + ppt->x ;
+ psrcT = (unsigned char *)pTile->devPrivate.ptr
+ + ( modulo( ppt->y - ySrc, pTile->drawable.height ) * tlwidth ) ;
+ x = ppt->x ;
+
+ xoff = modulo( x - xSrc, tileWidth) ;
+ for ( width = *pwidth ; width ; psrc++, width -= count, xoff+=count ) {
+
+ if ( xoff >= tileWidth ) xoff -= tileWidth;
+
+ if ( width < 8 )
+ count = width;
+ else
+ count = 8;
+
+ stip = vgagetbits( xoff, tileWidth, psrcT ) ;
+
+ for ( i = count ; i-- ; ) {
+ if ( stip & 128 )
+ {
+ unsigned _p;
+ DoRop( _p, alu, fg, *pdst ) ;
+ *pdst = ( *pdst & npm ) | ( pm & _p ) ;
+ }
+#ifdef notdef /* PURDUE */
+ *pdst = ( *pdst & npm ) | ( pm & DoRop( alu, fg, *pdst ) ) ;
+#endif /* PURDUE */
+ pdst++ ;
+ stip = SCRLEFT( stip, 1 ) ;
+ }
+ }
+ ppt++ ;
+ pwidth++ ;
+ }
+ DEALLOCATE_LOCAL( pptFree ) ;
+ DEALLOCATE_LOCAL( pwidthFree ) ;
+ return ;
+}
+
+void
+xf4bppOpStipplePixmapFS( pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted )
+DrawablePtr pDrawable ;
+GC *pGC ;
+int nInit ; /* number of spans to fill */
+DDXPointPtr pptInit ; /* pointer to list of start points */
+int *pwidthInit ; /* pointer to list of n widths */
+int fSorted ;
+{
+ register unsigned char *pdst ; /* pointer to current word in bitmap */
+ register unsigned long int pm, npm ;
+ register unsigned long int fg, bg ;
+ register int alu ;
+ /* next three parameters are post-clip */
+ int n ; /* number of spans to fill */
+ register DDXPointPtr ppt ; /* pointer to list of start points */
+ register int *pwidth ; /* pointer to list of n widths */
+ register int *psrc ; /* pointer to current word in tile */
+ PixmapPtr pTile ; /* pointer to tile we want to fill with */
+ int width ;
+ int xSrc, ySrc ;
+ int tlwidth, tileWidth ;
+ unsigned char *psrcT ;
+ int *pwidthFree ; /* copies of the pointers to free */
+ DDXPointPtr pptFree ;
+ int xoff, count, stip, i ;
+
+ TRACE( ( "xf4bppOpStipplePixmapFS(pDrawable=0x%x,pGC=0x%x,nInit=%d,pptInit=0x%x,pwidthInit=0x%x,fSorted=%d)\n",
+ pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted ) ) ;
+
+ if ( pGC->stipple->drawable.depth != 1 ) {
+ ErrorF( "xf4bppOpStipplePixmapFS: bad depth\ntype = %d, depth = %d\n",
+ pDrawable->type, pGC->stipple->drawable.depth ) ;
+ return ;
+ }
+
+ if ( ( alu = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.alu ) == GXnoop )
+ return ;
+
+ SETSPANPTRS( nInit, n, pwidthInit, pwidth, pptInit,
+ ppt, pwidthFree, pptFree, fSorted ) ;
+
+ fg = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.fgPixel ;
+ bg = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.bgPixel ;
+ pm = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.planemask ;
+ npm = ( ~ pm ) & ( ( 1 << pDrawable->depth ) - 1 ) ;
+
+ pTile = pGC->stipple ;
+ tlwidth = pTile->devKind ;
+ tileWidth = pTile->drawable.width ;
+
+ xSrc = pGC->patOrg.x + pDrawable->x;
+ ySrc = pGC->patOrg.y + pDrawable->y;
+
+ /* this replaces rotating the stipple. Instead, we just adjust the offset
+ * at which we start grabbing bits from the stipple */
+ for ( ; n-- ; ppt++, pwidth++ ) {
+ pdst = ( (unsigned char *) ( (PixmapPtr) pDrawable )->devPrivate.ptr )
+ + ( ppt->y * ( (int) ( (PixmapPtr) pDrawable )->devKind ) )
+ + ppt->x ;
+ psrcT = (unsigned char *)pTile->devPrivate.ptr
+ + ( modulo( ppt->y - ySrc, pTile->drawable.height ) * tlwidth ) ;
+
+ xoff = modulo( ppt->x - xSrc, tileWidth) ;
+
+ for ( width = *pwidth ; width ; psrc++, width -= count, xoff+=count ) {
+
+ if ( xoff >= tileWidth ) xoff -= tileWidth;
+
+ if ( width < 8 )
+ count = width;
+ else
+ count = 8;
+
+ stip = vgagetbits( xoff, tileWidth, psrcT ) ;
+ for ( i = count ; i-- ; pdst++, stip = SCRLEFT( stip, 1 ) )
+ if ( stip & 128 )
+ {
+ unsigned _p;
+ DoRop( _p, alu, fg, *pdst ) ;
+ *pdst = ( *pdst & npm ) | ( pm & _p ) ;
+ }
+#ifdef notdef /* PURDUE */
+ *pdst = ( *pdst & npm ) | ( pm & DoRop( alu, fg, *pdst ) ) ;
+#endif /* PURDUE */
+ else
+ {
+ unsigned _p;
+ DoRop( _p, alu, bg, *pdst ) ;
+ *pdst = ( *pdst & npm ) | ( pm & _p ) ;
+ }
+#ifdef notdef /* PURDUE */
+ *pdst = ( *pdst & npm ) | ( pm & DoRop( alu, bg, *pdst ) ) ;
+#endif /* PURDUE */
+ }
+ }
+ DEALLOCATE_LOCAL( pptFree ) ;
+ DEALLOCATE_LOCAL( pwidthFree ) ;
+ return ;
+}
+
+void
+xf4bppTilePixmapFS( pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted )
+register DrawablePtr pDrawable ;
+GC *pGC ;
+int nInit ; /* number of spans to fill */
+DDXPointPtr pptInit ; /* pointer to list of start points */
+int *pwidthInit ; /* pointer to list of n widths */
+int fSorted ;
+{
+ register DDXPointPtr ppt ; /* pointer to list of start points */
+ register int *pwidth ; /* pointer to list of n widths */
+ register unsigned char *pdst ; /* pointer to current word in bitmap */
+ register unsigned char *psrc ; /* pointer to current word in tile */
+ register PixmapPtr pTile ; /* pointer to tile we want to fill with */
+ int i ;
+ int alu ;
+ unsigned char pm, npm ;
+ /* next three parameters are post-clip */
+ int n ; /* number of spans to fill */
+ int tileWidth ;
+ int xSrc, ySrc;
+ unsigned char *psrcT ;
+ int *pwidthFree ; /* copies of the pointers to free */
+ DDXPointPtr pptFree ;
+
+ TRACE( ( "ppcTileFS(pDrawable=0x%x,pGC=0x%x,nInit=%d,pptInit=0x%x,pwidthInit=0x%x,fSorted=%d)\n",
+ pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted ) ) ;
+
+ if ( ( pDrawable->depth == 1 ) && ( pDrawable->type == DRAWABLE_PIXMAP ) ) {
+ mfbTileFS( pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted ) ;
+ return ;
+ }
+ if ( !xf4bppDepthOK( pDrawable, pGC->tile.pixmap->drawable.depth ) ) {
+ ErrorF( "ppcTileFS: bad depth\ntype = %d, depth = %d\n",
+ pDrawable->type, pDrawable->depth) ;
+ return ;
+ }
+
+ if ( ( alu = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.alu ) == GXnoop )
+ return ;
+
+ SETSPANPTRS( nInit, n, pwidthInit, pwidth, pptInit,
+ ppt, pwidthFree, pptFree, fSorted ) ;
+
+ /* the following code is for 8 bits per pixel addressable memory only */
+ pm = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.planemask ;
+ npm = ( ~ pm ) & ( ( 1 << pDrawable->depth ) - 1 ) ;
+ pTile = pGC->tile.pixmap ;
+ tileWidth = pTile->drawable.width ;
+
+ xSrc = pGC->patOrg.x + pDrawable->x;
+ ySrc = pGC->patOrg.y + pDrawable->y;
+ /* this replaces rotating the tile. Instead we just adjust the offset
+ * at which we start grabbing bits from the tile */
+ for ( ; n-- ; ppt++, pwidth++ ) {
+ pdst = ( (unsigned char *) ( (PixmapPtr) pDrawable )->devPrivate.ptr )
+ + ( ppt->y * ( (int) ( (PixmapPtr) pDrawable )->devKind ) )
+ + ppt->x ;
+ psrcT = (unsigned char *) pTile->devPrivate.ptr
+ + ( modulo( ppt->y - ySrc, pTile->drawable.height) * pTile->devKind ) ;
+
+ psrc = psrcT + modulo( ppt->x - xSrc, tileWidth ) ;
+ for ( i = *pwidth ; i-- ; pdst++, psrc++ ) {
+ if ( psrc >= ( psrcT + tileWidth ) )
+ psrc = psrcT ;
+ {
+ unsigned _p;
+ DoRop( _p, alu, *psrc, *pdst ) ;
+ *pdst = ( *pdst & npm ) | ( pm & _p ) ;
+ }
+#ifdef notdef /* PURDUE */
+ *pdst = ( *pdst & npm ) | ( pm & DoRop( alu, *psrc, *pdst ) ) ;
+#endif /* PURDUE */
+ }
+ }
+ DEALLOCATE_LOCAL( pptFree ) ;
+ DEALLOCATE_LOCAL( pwidthFree ) ;
+ return ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPixmap.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPixmap.c
new file mode 100644
index 000000000..da51784dd
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPixmap.c
@@ -0,0 +1,138 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPixmap.c,v 1.4 1999/06/06 08:49:00 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+*/
+
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ppcPixmap.c /main/5 1996/02/21 17:58:00 kaleb $ */
+
+#include "xf4bpp.h"
+#include "servermd.h"
+#include "OScompiler.h"
+#include "ibmTrace.h"
+
+PixmapPtr
+xf4bppCreatePixmap( pScreen, width, height, depth )
+ ScreenPtr pScreen ;
+ int width ;
+ int height ;
+ int depth ;
+{
+ register PixmapPtr pPixmap = (PixmapPtr)NULL;
+ int size ;
+
+ TRACE(("xf4bppCreatePixmap(pScreen=0x%x, width=%d, height=%d, depth=%d)\n", pScreen, width, height, depth)) ;
+
+ if ( depth > 8 )
+ return (PixmapPtr) NULL ;
+
+ size = PixmapBytePad(width, depth);
+ pPixmap = xalloc( sizeof (PixmapRec) + (height * size) ) ;
+ if ( !pPixmap )
+ return (PixmapPtr) NULL ;
+ pPixmap->drawable.type = DRAWABLE_PIXMAP ;
+ pPixmap->drawable.class = 0 ;
+ pPixmap->drawable.pScreen = pScreen ;
+ pPixmap->drawable.depth = depth ;
+ pPixmap->drawable.id = 0 ;
+ pPixmap->drawable.bitsPerPixel = ( depth == 1 ) ? 1 : 8 ;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER ;
+ pPixmap->drawable.x = 0 ;
+ pPixmap->drawable.y = 0 ;
+ pPixmap->drawable.width = width ;
+ pPixmap->drawable.height = height ;
+ pPixmap->devKind = size;
+ pPixmap->refcnt = 1 ;
+ size = height * pPixmap->devKind ;
+
+ pPixmap->devPrivate.ptr = (pointer) (pPixmap + 1);
+ bzero( (char *) pPixmap->devPrivate.ptr, size ) ;
+ return pPixmap ;
+}
+
+PixmapPtr
+xf4bppCopyPixmap(pSrc)
+ register PixmapPtr pSrc;
+{
+ register PixmapPtr pDst;
+ int size;
+
+ TRACE(("xf4bppCopyPixmap(pSrc=0x%x)\n", pSrc)) ;
+ size = pSrc->drawable.height * pSrc->devKind;
+ pDst = xalloc(sizeof(PixmapRec) + size);
+ if (!pDst)
+ return NullPixmap;
+ pDst->drawable = pSrc->drawable;
+ pDst->drawable.id = 0;
+ pDst->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pDst->devKind = pSrc->devKind;
+ pDst->refcnt = 1;
+ pDst->devPrivate.ptr = (pointer)(pDst + 1);
+ MOVE( (char *)pSrc->devPrivate.ptr, (char *)pDst->devPrivate.ptr, size ) ;
+ return pDst;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPntWin.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPntWin.c
new file mode 100644
index 000000000..e61fed342
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPntWin.c
@@ -0,0 +1,218 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPntWin.c,v 1.3 1999/06/06 08:49:01 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+*/
+
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ppcPntWin.c /main/5 1996/02/21 17:58:04 kaleb $ */
+
+#include "xf4bpp.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "mi.h"
+#include "scrnintstr.h"
+#include "ibmTrace.h"
+
+/* NOTE: These functions only work for visuals up to 31-bits deep */
+static void xf4bppPaintWindowSolid(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ RegionPtr,
+ int
+#endif
+);
+static void xf4bppPaintWindowTile(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ RegionPtr,
+ int
+#endif
+);
+
+void
+xf4bppPaintWindow(pWin, pRegion, what)
+ WindowPtr pWin;
+ RegionPtr pRegion;
+ int what;
+{
+
+ register mfbPrivWin *pPrivWin;
+ pPrivWin = (mfbPrivWin *)(pWin->devPrivates[mfbWindowPrivateIndex].ptr);
+
+ TRACE(("xf4bppPaintWindow( pWin= 0x%x, pRegion= 0x%x, what= %d )\n",
+ pWin,pRegion,what));
+
+ switch (what) {
+ case PW_BACKGROUND:
+ switch (pWin->backgroundState) {
+ case None:
+ return;
+ case ParentRelative:
+ do {
+ pWin = pWin->parent;
+ } while (pWin->backgroundState == ParentRelative);
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
+ what);
+ return;
+ case BackgroundPixmap:
+ if (pPrivWin->fastBackground)
+ {
+ xf4bppPaintWindowTile(pWin, pRegion, what);
+ return;
+ }
+ break;
+ case BackgroundPixel:
+ xf4bppPaintWindowSolid(pWin, pRegion, what);
+ return;
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel)
+ {
+ xf4bppPaintWindowSolid(pWin, pRegion, what);
+ return;
+ }
+ else if (pPrivWin->fastBorder)
+ {
+ xf4bppPaintWindowTile(pWin, pRegion, what);
+ return;
+ }
+ break;
+ }
+ miPaintWindow(pWin, pRegion, what);
+}
+
+static void
+xf4bppPaintWindowSolid(pWin, pRegion, what)
+ register WindowPtr pWin;
+ register RegionPtr pRegion;
+ int what;
+{
+ register int nbox;
+ register BoxPtr pbox;
+ register unsigned long int pixel;
+ register unsigned long int pm ;
+
+ TRACE(("xf4bppPaintWindowSolid(pWin= 0x%x, pRegion= 0x%x, what= %d)\n", pWin, pRegion, what));
+
+ if ( !( nbox = REGION_NUM_RECTS(pRegion)))
+ return ;
+ pbox = REGION_RECTS(pRegion);
+
+ if (what == PW_BACKGROUND)
+ pixel = pWin->background.pixel;
+ else
+ pixel = pWin->border.pixel;
+
+ pm = ( 1 << pWin->drawable.depth ) - 1 ;
+ for ( ; nbox-- ; pbox++ ) {
+ /*
+ * call fill routine, the parms are:
+ * fill(color, alu, planes, x, y, width, height);
+ */
+ xf4bppFillSolid( pWin, pixel, GXcopy, pm, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1 ) ;
+ }
+ return ;
+}
+
+static void
+xf4bppPaintWindowTile(pWin, pRegion, what)
+ register WindowPtr pWin;
+ register RegionPtr pRegion;
+ int what;
+{
+ register int nbox;
+ register BoxPtr pbox;
+ register PixmapPtr pTile;
+ register unsigned long int pm ;
+
+ TRACE(("xf4bppPaintWindowTile(pWin= 0x%x, pRegion= 0x%x, what= %d)\n", pWin, pRegion, what));
+
+ if ( !( nbox = REGION_NUM_RECTS(pRegion)))
+ return ;
+ pbox = REGION_RECTS(pRegion);
+
+ if (what == PW_BACKGROUND)
+ pTile = pWin->background.pixmap;
+ else
+ pTile = pWin->border.pixmap;
+
+ pm = ( 1 << pWin->drawable.depth ) - 1 ;
+ for ( ; nbox-- ; pbox++ ) {
+ /*
+ * call tile routine, the parms are:
+ * tile(tile, alu, planes, x, y, width, height,xSrc,ySrc);
+ */
+ xf4bppTileRect(pWin, pTile, GXcopy, pm,
+ pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ pWin->drawable.x, pWin->drawable.y );
+ }
+ return ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPolyPnt.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPolyPnt.c
new file mode 100644
index 000000000..e8d29a5e8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPolyPnt.c
@@ -0,0 +1,142 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPolyPnt.c,v 1.3 1999/06/06 08:49:01 dawes Exp $ */
+/*
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+
+Copyright IBM Corporation 1987,1988,1989
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of IBM not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XConsortium: ppcPolyPnt.c /main/5 1996/02/21 17:58:07 kaleb $ */
+
+#include "xf4bpp.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "mi.h"
+#include "scrnintstr.h"
+#include "ppcGCstr.h"
+#include "ibmTrace.h"
+
+void
+xf4bppPolyPoint( pDrawable, pGC, mode, npt, pptInit )
+DrawablePtr pDrawable ;
+GCPtr pGC ;
+int mode ; /* Origin or Previous */
+int npt ;
+xPoint *pptInit ;
+{
+register xPoint *ppt ;
+ppcPrivGC *devPriv ;
+int alu ;
+int nptTmp ;
+
+TRACE( ("xf4bppPolyPoint(0x%x,0x%x,%d,%d,0x%x)\n",
+ pDrawable, pGC, mode, npt, pptInit ) ) ;
+
+if ( pDrawable->type == DRAWABLE_PIXMAP ) {
+ if ( pGC->alu != GXnoop )
+ miPolyPoint( pDrawable, pGC, mode, npt, pptInit ) ;
+ return ;
+}
+
+devPriv = (ppcPrivGC *) ( pGC->devPrivates[mfbGCPrivateIndex].ptr ) ;
+if ( ( alu = devPriv->colorRrop.alu ) == GXnoop )
+ return ;
+
+/* make pointlist origin relative */
+if ( mode == CoordModePrevious )
+ for ( ppt = pptInit, nptTmp = npt ; --nptTmp ; ) {
+ ppt++ ;
+ ppt->x += (ppt-1)->x ;
+ ppt->y += (ppt-1)->y ;
+ }
+
+if ( pGC->miTranslate ) {
+ register int xorg = pDrawable->x ;
+ register int yorg = pDrawable->y ;
+ for ( ppt = pptInit, nptTmp = npt ; nptTmp-- ; ppt++ ) {
+ ppt->x += xorg ;
+ ppt->y += yorg ;
+ }
+}
+
+{
+ register PointInRegionProcPtr PointInRegion =
+ pDrawable->pScreen->PointInRegion ;
+ register RegionPtr pRegion = pGC->pCompositeClip ;
+ register unsigned long int fg = devPriv->colorRrop.fgPixel ;
+ register unsigned long int pm = devPriv->colorRrop.planemask ;
+ BoxRec box ; /* Scratch Space */
+
+ if ( ! REGION_NUM_RECTS(pRegion))
+ return ;
+
+ for ( ppt = pptInit ; npt-- ; ppt++ )
+ if ( (* PointInRegion)( pRegion, ppt->x, ppt->y, &box ) )
+ xf4bppFillSolid( (WindowPtr)pDrawable,
+ fg, alu, pm, ppt->x, ppt->y, 1, 1 ) ;
+}
+
+return ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPolyRec.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPolyRec.c
new file mode 100644
index 000000000..754eb3732
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPolyRec.c
@@ -0,0 +1,127 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcPolyRec.c,v 1.3 1999/06/06 08:49:01 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+*/
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ppcPolyRec.c /main/4 1996/02/21 17:58:11 kaleb $ */
+
+#include "xf4bpp.h"
+
+void
+xf4bppPolyRectangle(pDraw, pGC, nrects, pRects)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int nrects;
+ xRectangle *pRects;
+{
+ int i;
+ xRectangle *pR = pRects;
+ xRectangle *tmprects, *tmprectsinit;
+ int lw, fs, ss;
+
+ if ( ! ( tmprectsinit = tmprects = (xRectangle *)ALLOCATE_LOCAL( ( sizeof ( xRectangle ) * nrects ) << 2 ) ) )
+ return;
+
+ lw = pGC->lineWidth;
+ ss = lw >> 1; /* skinny side of line */
+ fs = ( lw + 1 ) >> 1; /* fat side of line */
+
+ for (i=0; i<nrects; i++)
+ {
+ tmprects->x = pR->x - ss;
+ tmprects->y = pR->y - ss;
+ tmprects->width = pR->width + lw;
+ tmprects->height = lw;
+ tmprects++;
+
+ tmprects->x = pR->x - ss;
+ tmprects->y = pR->y + fs;
+ tmprects->width = lw;
+ tmprects->height = pR->height - lw;
+ tmprects++;
+
+ tmprects->x = pR->x + pR->width - ss;
+ tmprects->y = pR->y + fs;
+ tmprects->width = lw;
+ tmprects->height = pR->height - lw;
+ tmprects++;
+
+ tmprects->x = pR->x - ss;
+ tmprects->y = pR->y + pR->height - ss;
+ tmprects->width = pR->width + lw;
+ tmprects->height = lw;
+ tmprects++;
+
+ pR++;
+ }
+
+ (* pGC->ops->PolyFillRect)( pDraw, pGC, nrects << 2, tmprectsinit );
+
+ DEALLOCATE_LOCAL( tmprectsinit );
+ return ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcQuery.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcQuery.c
new file mode 100644
index 000000000..57d5fcff8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcQuery.c
@@ -0,0 +1,44 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcQuery.c,v 1.3 1999/06/06 08:49:01 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+/* $XConsortium: ppcQuery.c /main/3 1996/02/21 17:58:18 kaleb $ */
+
+#include "xf4bpp.h"
+
+void
+xf4bppQueryBestSize
+(
+ register int class,
+ register unsigned short *pwidth,
+ register unsigned short *pheight,
+ ScreenPtr pScreen
+)
+{
+if ( class == CursorShape )
+ *pwidth = *pheight = 32 ; /* ppc's cursor max out at 32 by 32 */
+else /* either TileShape or StippleShape */
+ /* Round Up To Nearest Multiple Of 8 -- We don't care what height they use */
+ *pwidth = ( *pwidth + 0x7 ) & ~ 0x7 ;
+
+return ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcRslvC.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcRslvC.c
new file mode 100644
index 000000000..210a99934
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcRslvC.c
@@ -0,0 +1,176 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcRslvC.c,v 1.4 1999/06/06 08:49:01 dawes Exp $ */
+/************************************************************
+Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
+
+ 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 no-
+tice appear in all copies and that both that copyright no-
+tice and this permission notice appear in supporting docu-
+mentation, and that the names of Sun or X Consortium
+not be used in advertising or publicity pertaining to
+distribution of the software without specific prior
+written permission. Sun and X Consortium make no
+representations about the suitability of this software for
+any purpose. It is provided "as is" without any express or
+implied warranty.
+
+SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
+NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
+ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+
+/* $XConsortium: ppcRslvC.c /main/7 1996/02/21 17:58:25 kaleb $ */
+
+/* Generic Color Resolution Scheme
+ * P. Shupak 12/31/87
+ */
+
+#include "xf4bpp.h"
+#include "scrnintstr.h"
+
+/*
+ * New colormap routines that can support multiple Visual types.
+ */
+
+static unsigned short defstaticpalette[16][3] = {
+ /* R G B */
+ { 0x0000, 0x0000, 0x0000 }, /* black */
+ { 0xFFFF, 0xFFFF, 0xFFFF }, /* white */
+ { 0xAAAA, 0xAAAA, 0xAAAA }, /* grey */
+ { 0x0000, 0x0000, 0xAAAA }, /* dark blue */
+ { 0x0000, 0x0000, 0xFFFF }, /* medium blue */
+ { 0x0000, 0xAAAA, 0xFFFF }, /* light blue */
+ { 0x0000, 0xFFFF, 0xFFFF }, /* cyan */
+ { 0x0000, 0xAAAA, 0x0000 }, /* dark green */
+ { 0x0000, 0xFFFF, 0x0000 }, /* green */
+ { 0xAAAA, 0xFFFF, 0x5555 }, /* pale green */
+ { 0xAAAA, 0x5555, 0x0000 }, /* brown */
+ { 0xFFFF, 0xAAAA, 0x0000 }, /* light brown */
+ { 0xFFFF, 0xFFFF, 0x0000 }, /* yellow */
+ { 0xAAAA, 0x0000, 0xAAAA }, /* purple */
+ { 0xFFFF, 0x0000, 0xFFFF }, /* magenta */
+ { 0xFFFF, 0x0000, 0x0000 }, /* red */
+ };
+
+Bool
+xf4bppInitializeColormap(pmap)
+ register ColormapPtr pmap;
+{
+ register unsigned i;
+ register VisualPtr pVisual;
+ unsigned lim, maxent, shift;
+
+ pVisual = pmap->pVisual;
+ lim = (1 << pVisual->bitsPerRGBValue) - 1;
+ shift = 16 - pVisual->bitsPerRGBValue;
+ maxent = pVisual->ColormapEntries - 1;
+
+ switch( pVisual->class )
+ {
+ case StaticGray:
+ for ( i = 0 ; i < maxent ; i++ ) {
+ pmap->red[i].co.local.red =
+ pmap->red[i].co.local.green =
+ pmap->red[i].co.local.blue =
+ ((((i * 65535) / maxent) >> shift) * 65535) / lim;
+ }
+ break;
+ case StaticColor:
+ for ( i = 0 ; i < 16 ; i++ ) {
+ pmap->red[i].co.local.red = (defstaticpalette[i][0]);
+ pmap->red[i].co.local.green = (defstaticpalette[i][1]);
+ pmap->red[i].co.local.blue = (defstaticpalette[i][2]);
+ }
+ break;
+ case GrayScale:
+ case PseudoColor:
+ for(i=0;i<=maxent;i++) {
+ int a,b,c;
+ a = i << 10;
+ b = i << 12;
+ c = i << 14;
+ pmap->red[i].co.local.red = a;
+ pmap->red[i].co.local.green = b;
+ pmap->red[i].co.local.blue = c;
+ }
+ break;
+ case TrueColor:
+ case DirectColor:
+ default:
+ ErrorF( "Unsupported Visual class %d\b", pVisual->class );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void
+xf4bppResolveColor( pred, pgreen, pblue, pVisual )
+register unsigned short* const pred ;
+register unsigned short* const pgreen ;
+register unsigned short* const pblue ;
+register VisualPtr const pVisual ;
+{
+ unsigned lim, maxent, shift;
+
+ lim = (1 << pVisual->bitsPerRGBValue) - 1;
+ shift = 16 - pVisual->bitsPerRGBValue;
+ maxent = pVisual->ColormapEntries - 1;
+
+ switch( pVisual->class )
+ {
+ case StaticGray:
+ *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100;
+ *pred = (((*pred * (maxent + 1)) >> 16) * 65535) / maxent;
+ *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim;
+ break;
+ case StaticColor:
+ break;
+ case GrayScale:
+ *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100;
+ *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim;
+ break;
+ case PseudoColor:
+ /* rescale to rgb bits */
+ *pred = ((*pred >> shift) * 65535) / lim;
+ *pgreen = ((*pgreen >> shift) * 65535) / lim;
+ *pblue = ((*pblue >> shift) * 65535) / lim;
+ break;
+ case TrueColor:
+ case DirectColor:
+ default:
+ ErrorF( "Unsupported Visual class %d\b", pVisual->class );
+ }
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcSetSp.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcSetSp.c
new file mode 100644
index 000000000..81294b2cc
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcSetSp.c
@@ -0,0 +1,315 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcSetSp.c,v 1.3 1999/06/06 08:49:02 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+*/
+
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ppcSetSp.c /main/5 1996/02/21 17:58:32 kaleb $ */
+
+#include "xf4bpp.h"
+#include "OScompiler.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "servermd.h"
+
+/* SetScanline -- copies the bits from psrc to the drawable starting at
+ * (xStart, y) and continuing to (xEnd, y). xOrigin tells us where psrc
+ * starts on the scanline. (I.e., if this scanline passes through multiple
+ * boxes, we may not want to start grabbing bits at psrc but at some offset
+ * further on.)
+ */
+static void
+ppcSetScanline
+(
+ register int pixCount, /* width of scanline in bits */
+ register char *psrc,
+ register unsigned char *pdst, /* where to put the bits */
+ register int pm, /* plane mask */
+ const int alu /* raster op */
+)
+{
+register int npm = ~pm ; /* inverted plane mask */
+register char tmpx ;
+
+pm &= 0x0F; npm &= 0x0F; /* GJA */
+
+switch ( alu ) {
+ case GXclear: /* 0x0 Zero 0 */
+ while ( pixCount-- )
+ *pdst++ &= npm ;
+ break ;
+ case GXand: /* 0x1 src AND dst */
+ while ( pixCount-- )
+ *pdst++ &= *psrc++ | npm ;
+ break ;
+ case GXandReverse: /* 0x2 src AND NOT dst */
+ for ( ; pixCount-- ; pdst++, psrc++ ) {
+ tmpx = *pdst;
+ *pdst = ( tmpx & npm ) | ( pm & *psrc & ~tmpx ) ;
+ }
+ break ;
+ case GXcopy: /* 0x3 src */
+ for ( ; pixCount-- ; pdst++, psrc++ )
+ *pdst = ( *pdst & npm ) | ( pm & *psrc ) ;
+ break ;
+ case GXandInverted: /* 0x4 NOT src AND dst */
+ while ( pixCount-- )
+ *pdst++ &= npm | ~*psrc++ ;
+ break ;
+ case GXnoop: /* 0x5 dst */
+ break ;
+ case GXxor: /* 0x6 src XOR dst */
+ while ( pixCount-- )
+ *pdst++ ^= pm & *psrc++ ;
+ break ;
+ case GXor: /* 0x7 src OR dst */
+ while ( pixCount-- )
+ *pdst++ |= *psrc++ & pm ;
+ break ;
+ case GXnor: /* 0x8 NOT src AND NOT dst */
+ for ( ; pixCount-- ; pdst++, psrc++ ) {
+ tmpx = *pdst;
+ *pdst = ( tmpx & npm ) | ( pm & ~( tmpx | *psrc ) ) ;
+ }
+ break ;
+ case GXequiv: /* 0x9 NOT src XOR dst */
+ while ( pixCount-- )
+ *pdst++ ^= pm & ~ *psrc++ ;
+ break ;
+ case GXorReverse: /* 0xb src OR NOT dst */
+ for ( ; pixCount-- ; pdst++, psrc++ ) {
+ tmpx = *pdst;
+ *pdst = ( tmpx & npm ) | ( pm & ( *psrc | ~tmpx ) ) ;
+ }
+ break ;
+ case GXinvert: /* 0xa NOT dst */
+ while ( pixCount-- )
+ *pdst++ ^= pm ;
+ break ;
+ case GXcopyInverted: /* 0xc NOT src */
+ for ( ; pixCount-- ; pdst++, psrc++ )
+ *pdst = ( *pdst & npm ) | ( pm & ~ *psrc ) ;
+ break ;
+ case GXorInverted: /* 0xd NOT src OR dst */
+ while ( pixCount-- )
+ *pdst++ |= pm & ~ *psrc++ ;
+ break ;
+ case GXnand: /* 0xe NOT src OR NOT dst */
+ for ( ; pixCount-- ; pdst++, psrc++ ) {
+ tmpx = *pdst;
+ *pdst = ( tmpx & npm ) | ( pm & ~( tmpx & *psrc ) ) ;
+ }
+ break ;
+ case GXset: /* 0xf 1 */
+ while ( pixCount-- )
+ *pdst++ |= pm ;
+ break ;
+ default:
+ ErrorF( "ppcSetScanLine: bad alu value == 0x%02X\n", alu ) ;
+ break ;
+}
+
+return ;
+}
+
+/* SetSpans -- for each span copy pwidth[i] bits from psrc to pDrawable at
+ * ppt[i] using the raster op from the GC. If fSorted is TRUE, the scanlines
+ * are in increasing Y order.
+ * Source bit lines are server scanline padded so that they always begin
+ * on a word boundary.
+ */
+void
+xf4bppSetSpans( pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted )
+ register DrawablePtr pDrawable ;
+ GCPtr pGC ;
+ char *psrc ;
+ register DDXPointPtr ppt ;
+ int *pwidth ;
+ int nspans ;
+ int fSorted ;
+{
+ unsigned char *pdstBase = NULL; /* start of dst bitmap */
+ int widthDst = 0; /* width of bitmap in words */
+ register BoxPtr pbox, pboxLast, pboxTest ;
+ register DDXPointPtr pptLast ;
+ RegionPtr prgnDst ;
+ register int width ;
+ int xStart, xEnd ;
+ int yMax ;
+ int alu ;
+ int pm ;
+
+ /* allow for 1-deep windows on nfb machines (eg apa8, aed) */
+ if ( ( pDrawable->depth == 1 ) && ( pDrawable->type == DRAWABLE_PIXMAP ) ) {
+ mfbSetSpans( pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted ) ;
+ return ;
+ }
+
+ if ( !( pm = pGC->planemask & ~( (~0) << pDrawable->depth ) )
+ || ( ( alu = pGC->alu ) == GXnoop ) )
+ return ;
+
+ prgnDst = pGC->pCompositeClip ;
+
+ if ( ! REGION_NUM_RECTS(prgnDst))
+ return ;
+
+ pboxLast = ( pbox = REGION_RECTS(prgnDst) ) + REGION_NUM_RECTS(prgnDst);
+ pptLast = ppt + nspans ;
+
+ if ( pDrawable->type == DRAWABLE_WINDOW ) {
+ yMax = (int) pDrawable->height + pDrawable->y ;
+ }
+ else {
+ pdstBase = (unsigned char *) ( (PixmapPtr) pDrawable )->devPrivate.ptr ;
+ widthDst = (int) ( (PixmapPtr) pDrawable )->devKind ;
+ yMax = pDrawable->height ;
+ }
+
+ if ( fSorted ) {
+ /* scan lines sorted in ascending order. Because they are sorted, we
+ * don't have to check each scanline against each clip box. We can be
+ * sure that this scanline only has to be clipped to boxes at or after the
+ * beginning of this y-band
+ */
+ for ( pboxTest = pbox ;
+ ( ppt < pptLast ) && ( ppt->y < yMax ) ;
+ ppt++, pwidth++,
+ psrc += PixmapBytePad( width, pDrawable->depth ) ) {
+ width = *pwidth ;
+ for ( pbox = pboxTest ;
+ pbox < pboxLast ;
+ pbox++ ) {
+ if ( pbox->y2 <= ppt->y ) {
+ /* clip box is before scanline */
+ pboxTest = pbox + 1 ;
+ }
+ else if ( ( pbox->y1 > ppt->y )
+ || ( pbox->x1 > ppt->x + width ) )
+ break ; /* scanline before clip box or left of clip box */
+ else if ( pbox->x2 > ppt->x ) {
+ /* some of the scanline is in the current clip box */
+ xStart = MAX( pbox->x1, ppt->x ) ;
+ xEnd = MIN( ppt->x + width, pbox->x2 ) ;
+ if ( pDrawable->type == DRAWABLE_PIXMAP )
+ ppcSetScanline( xEnd - xStart,
+ psrc + ( xStart - ppt->x ),
+ pdstBase + xStart
+ + ( ppt->y * widthDst ),
+ pm, alu ) ;
+ else
+ xf4bppDrawColorImage( (WindowPtr)pDrawable,
+ xStart, ppt->y, xEnd - xStart, 1,
+ (unsigned char *)psrc + ( xStart - ppt->x ),
+ xEnd - xStart, alu, pm ) ;
+ if ( ppt->x + width <= pbox->x2 )
+ break ; /* End of the line, as it were */
+ }
+ }
+ /* We've tried this line against every box ; it must be outside them
+ * all. move on to the next point */
+ }
+ }
+ else {
+ /* scan lines not sorted. We must clip each line against all the boxes */
+ for ( ;
+ ppt < pptLast ;
+ ppt++, pwidth++,
+ psrc += PixmapBytePad( width, pDrawable->depth ) ) {
+ width = *pwidth ;
+ if ( ppt->y >= 0 && ppt->y < yMax ) {
+ for ( pbox = REGION_RECTS(prgnDst) ; pbox < pboxLast ; pbox++ ) {
+ if ( pbox->y1 > ppt->y )
+ break ; /* rest of clip region is above this scanline */
+ else if ( ( pbox->y2 > ppt->y )
+ && ( pbox->x1 <= ppt->x + width )
+ && ( pbox->x2 > ppt->x ) ) {
+ xStart = MAX( pbox->x1, ppt->x ) ;
+ xEnd = MIN( pbox->x2, ppt->x + width ) ;
+ if ( pDrawable->type == DRAWABLE_PIXMAP )
+ ppcSetScanline( xEnd - xStart,
+ psrc + ( xStart - ppt->x ),
+ /* ^ GJA */
+ ( ( pdstBase
+ + ( ppt->y * widthDst ) )
+ + xStart ),
+ pm, alu ) ;
+ else /* pDrawable->type == DRAWABLE_WINDOW */
+ xf4bppDrawColorImage( (WindowPtr)pDrawable,
+ xStart, ppt->y, xEnd - xStart, 1,
+ (unsigned char *)psrc + ( xStart - ppt->x ),
+ /* GJA ^ */
+ xEnd - xStart, alu, pm ) ;
+ }
+
+ }
+ }
+ }
+ }
+ return ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcSpMcro.h b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcSpMcro.h
new file mode 100644
index 000000000..7ea244f66
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcSpMcro.h
@@ -0,0 +1,45 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcSpMcro.h,v 1.2 1998/07/25 16:59:42 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+/* $XConsortium: ppcSpMcro.h /main/3 1996/02/21 17:58:36 kaleb $ */
+
+/* This screwy macro is used in all the spans routines and you find
+ it all over the place, so it is a macro just to tidy things up.
+*/
+
+#define SETSPANPTRS(IN,N,IPW,PW,IPPT,PPT,FPW,FPPT,FSORT) \
+ { \
+ N = IN * miFindMaxBand(pGC->pCompositeClip); \
+ if(!(PW = (int *)ALLOCATE_LOCAL(N * sizeof(int)))) \
+ return; \
+ if(!(PPT = (DDXPointRec *)ALLOCATE_LOCAL(N * sizeof(DDXPointRec)))) \
+ { \
+ DEALLOCATE_LOCAL(PW); \
+ return; \
+ } \
+ FPW = PW; \
+ FPPT = PPT; \
+ N = miClipSpans(pGC->pCompositeClip, IPPT, IPW, IN, \
+ PPT, PW, FSORT); \
+ }
+
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcWinFS.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcWinFS.c
new file mode 100644
index 000000000..29d466f00
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcWinFS.c
@@ -0,0 +1,278 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcWinFS.c,v 1.3 1999/06/06 08:49:02 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+*/
+
+/******************************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ppcWinFS.c /main/3 1996/02/21 17:58:39 kaleb $ */
+
+#include "xf4bpp.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "mi.h"
+#include "mispans.h"
+#include "ppcGCstr.h"
+#include "ppcSpMcro.h"
+#include "ibmTrace.h"
+
+#define LeftMostBitInScreenLongWord SCRLEFT( 0xFFFFFFFF, 31 )
+/*
+********** ********** ********** ********** ********** ********** **********
+ these routines all clip. they assume that anything that has called
+them has already translated the points (i.e. pGC->miTranslate is
+non-zero, which is howit gets set in mfbCreateGC().)
+
+ the number of new scanlines created by clipping ==
+MaxRectsPerBand * nSpans.
+********** ********** ********** ********** ********** ********** **********
+*/
+
+void
+xf4bppSolidWindowFS( pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted )
+ DrawablePtr pDrawable ;
+ GCPtr pGC ;
+ int nInit ; /* number of spans to fill */
+ DDXPointPtr pptInit ; /* pointer to list of start points */
+ int *pwidthInit ; /* pointer to list of n widths */
+ int fSorted ;
+{
+ register unsigned long int pm ;
+ register unsigned long int fg ;
+ register int alu ;
+ /* next three parameters are post-clip */
+ int n ; /* number of spans to fill */
+ register DDXPointPtr ppt ; /* pointer to list of start points */
+ register int *pwidth ; /* pointer to list of n widths */
+ int *pwidthFree ; /* copies of the pointers to free */
+ DDXPointPtr pptFree ;
+
+ TRACE( ( "xf4bppSolidWindowFS(pDrawable=0x%x,pGC=0x%x,nInit=%d,pptInit=0x%x,pwidthInit=0x%x,fSorted=%d)\n",
+ pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted ) ) ;
+
+ if ( pDrawable->type != DRAWABLE_WINDOW ) {
+ ErrorF( "xf4bppSolidWindowFS: drawable is not a window\n") ;
+ return ;
+ }
+
+ if ( ( alu = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.alu ) == GXnoop )
+ return ;
+
+ n = nInit * miFindMaxBand( pGC->pCompositeClip ) ;
+ if ( !( pwidth = (int *) ALLOCATE_LOCAL( n * sizeof( int ) ) ) )
+ return ;
+ pwidthFree = pwidth ;
+
+ if ( !( ppt = (DDXPointRec *)
+ ALLOCATE_LOCAL( n * sizeof( DDXPointRec ) ) ) ) {
+ DEALLOCATE_LOCAL( pwidth ) ;
+ return ;
+ }
+ pptFree = ppt ;
+
+ n = miClipSpans( pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted ) ;
+
+ pm = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.planemask ;
+ fg = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.fgPixel ;
+
+ for ( ; n-- ; ppt++, pwidth++ )
+ if ( *pwidth )
+ xf4bppFillSolid( (WindowPtr)pDrawable,
+ fg, alu, pm, ppt->x, ppt->y, *pwidth, 1 ) ;
+
+ DEALLOCATE_LOCAL( pptFree ) ;
+ DEALLOCATE_LOCAL( pwidthFree ) ;
+ return ;
+}
+
+void
+xf4bppStippleWindowFS( pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted )
+DrawablePtr pDrawable ;
+register GC *pGC ;
+int nInit ; /* number of spans to fill */
+DDXPointPtr pptInit ; /* pointer to list of start points */
+int *pwidthInit ; /* pointer to list of n widths */
+int fSorted ;
+{
+ register unsigned long int pm ;
+ register unsigned long int fg ;
+ register int alu ;
+ /* next three parameters are post-clip */
+ int n ; /* number of spans to fill */
+ register DDXPointPtr ppt ; /* pointer to list of start points */
+ register int *pwidth ; /* pointer to list of n widths */
+ PixmapPtr pTile ; /* pointer to tile we want to fill with */
+ int xSrc ;
+ int ySrc ;
+ int *pwidthFree ; /* copies of the pointers to free */
+ DDXPointPtr pptFree ;
+
+ TRACE( ( "xf4bppStippleWindowFS(pDrawable=0x%x,pGC=0x%x,nInit=%d,pptInit=0x%x,pwidthInit=0x%x,fSorted=%d)\n",
+ pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted ) ) ;
+
+ if ( pDrawable->type != DRAWABLE_WINDOW ) {
+ ErrorF( "xf4bppStippleWindowFS: drawable is not a window\n" ) ;
+ return ;
+ }
+
+ if ( pGC->stipple->drawable.depth != 1 ) {
+ ErrorF("ppcStippleFS: bad depth\ntype = %d, depth = %d\n",
+ pDrawable->type, pGC->stipple->drawable.depth ) ;
+ return ;
+ }
+
+ if ( ( alu = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.alu ) == GXnoop )
+ return ;
+
+ SETSPANPTRS( nInit, n, pwidthInit, pwidth, pptInit,
+ ppt, pwidthFree, pptFree, fSorted ) ;
+
+ pm = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.planemask ;
+ fg = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.fgPixel ;
+
+ xSrc = pGC->patOrg.x + pDrawable->x ;
+ ySrc = pGC->patOrg.y + pDrawable->y ;
+ pTile = pGC->stipple ;
+
+ for ( ; n-- ; ppt++, pwidth++ )
+ xf4bppFillStipple( (WindowPtr)pDrawable, pTile, fg, alu, pm,
+ ppt->x, ppt->y, *pwidth, 1, xSrc, ySrc ) ;
+
+ DEALLOCATE_LOCAL( pptFree ) ;
+ DEALLOCATE_LOCAL( pwidthFree ) ;
+
+ return ;
+}
+
+void
+xf4bppOpStippleWindowFS( pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted )
+DrawablePtr pDrawable ;
+register GC *pGC ;
+int nInit ; /* number of spans to fill */
+DDXPointPtr pptInit ; /* pointer to list of start points */
+int *pwidthInit ; /* pointer to list of n widths */
+int fSorted ;
+{
+ register DDXPointPtr ppt ; /* pointer to list of start points */
+ register int *pwidth ; /* pointer to list of n widths */
+ int n ; /* number of spans to fill */
+ int xSrc ;
+ int ySrc ;
+ unsigned long int pm ;
+ unsigned long int fg, bg ;
+ int alu ;
+ int *pwidthFree ; /* copies of the pointers to free */
+ DDXPointPtr pptFree ;
+
+ TRACE( ( "xf4bppOpStippleWindowFS(pDrawable=0x%x,pGC=0x%x,nInit=%d,pptInit=0x%x,pwidthInit=0x%x,fSorted=%d)\n",
+ pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted ) ) ;
+
+ if ( pGC->stipple->drawable.depth != 1 ) {
+ ErrorF( "xf4bppOpStippleWindowFS: bad depth\ntype = %d, depth = %d\n",
+ pDrawable->type, pGC->stipple->drawable.depth ) ;
+ return ;
+ }
+
+ if ( ( alu = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.alu ) == GXnoop )
+ return ;
+
+ SETSPANPTRS( nInit, n, pwidthInit, pwidth, pptInit,
+ ppt, pwidthFree, pptFree, fSorted ) ;
+
+ pm = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.planemask ;
+ fg = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.fgPixel ;
+ bg = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.bgPixel ;
+
+ xSrc = pGC->patOrg.x + pDrawable->x ;
+ ySrc = pGC->patOrg.y + pDrawable->y ;
+
+ for ( ; n-- ; ppt++, pwidth++ )
+ xf4bppOpaqueStipple( (WindowPtr)pDrawable, pGC->stipple, fg, bg, alu, pm,
+ ppt->x, ppt->y, *pwidth, 1, xSrc, ySrc ) ;
+
+ DEALLOCATE_LOCAL( pptFree ) ;
+ DEALLOCATE_LOCAL( pwidthFree ) ;
+ return ;
+}
+
+void
+xf4bppTileWindowFS( pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted )
+DrawablePtr pDrawable ;
+register GC *pGC ;
+int nInit ; /* number of spans to fill */
+DDXPointPtr pptInit ; /* pointer to list of start points */
+int *pwidthInit ; /* pointer to list of n widths */
+int fSorted ;
+{
+ /* next three parameters are post-clip */
+ register DDXPointPtr ppt ; /* pointer to list of start points */
+ register int *pwidth ; /* pointer to list of n widths */
+ int n ; /* number of spans to fill */
+ unsigned char pm ;
+ int alu ;
+ int xSrc ;
+ int ySrc ;
+ int *pwidthFree ; /* copies of the pointers to free */
+ DDXPointPtr pptFree ;
+
+ TRACE( ( "xf4bppTileWindowFS(pDrawable=0x%x,pGC=0x%x,nInit=%d,pptInit=0x%x,pwidthInit=0x%x,fSorted=%d)\n",
+ pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted ) ) ;
+
+ if ( ( alu = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.alu ) == GXnoop )
+ return ;
+
+ SETSPANPTRS( nInit, n, pwidthInit, pwidth, pptInit,
+ ppt, pwidthFree, pptFree, fSorted ) ;
+
+ xSrc = pGC->patOrg.x + pDrawable->x ;
+ ySrc = pGC->patOrg.y + pDrawable->y ;
+ pm = ( (ppcPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr )->colorRrop.planemask ;
+
+ for ( ; n-- ; ppt++, pwidth++ )
+ xf4bppTileRect( (WindowPtr)pDrawable, pGC->tile.pixmap, alu, pm,
+ ppt->x, ppt->y, *pwidth, 1, xSrc, ySrc ) ;
+
+ DEALLOCATE_LOCAL( pptFree ) ;
+ DEALLOCATE_LOCAL( pwidthFree ) ;
+ return ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcWindow.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcWindow.c
new file mode 100644
index 000000000..d5214de40
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/ppcWindow.c
@@ -0,0 +1,224 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/ppcWindow.c,v 1.3 1999/06/06 08:49:06 dawes Exp $ */
+/*
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+
+Copyright IBM Corporation 1987,1988,1989
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of IBM not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XConsortium: ppcWindow.c /main/5 1996/02/21 17:58:43 kaleb $ */
+
+#include "xf4bpp.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "scrnintstr.h"
+#include "ibmTrace.h"
+
+/*
+ xf4bppCopyWindow copies only the parts of the destination that are
+visible in the source.
+*/
+
+void
+xf4bppCopyWindow(pWin, ptOldOrg, prgnSrc)
+ register WindowPtr pWin ;
+ DDXPointRec ptOldOrg ;
+ RegionPtr prgnSrc ;
+{
+ RegionPtr prgnDst ;
+ register BoxPtr pbox ;
+ register int dx, dy ;
+ register int nbox ;
+ register int pm ;
+
+ BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew ;
+ /* temporaries for shuffling rectangles */
+
+ TRACE(("xf4bppCopyWindow(pWin= 0x%x, ptOldOrg= 0x%x, prgnSrc= 0x%x)\n", pWin, ptOldOrg, prgnSrc)) ;
+
+
+ dx = ptOldOrg.x - pWin->drawable.x ;
+ dy = ptOldOrg.y - pWin->drawable.y ;
+ (* pWin->drawable.pScreen->TranslateRegion)(prgnSrc, -dx, -dy) ;
+
+ prgnDst = (* pWin->drawable.pScreen->RegionCreate)(NULL, 1);
+ (* pWin->drawable.pScreen->Intersect)(prgnDst, &pWin->borderClip, prgnSrc) ;
+
+ if ( !( nbox = REGION_NUM_RECTS(prgnDst) ) )
+ return;
+
+ pbox = REGION_RECTS(prgnDst);
+
+ pboxNew = 0 ;
+ if ( nbox > 1 ) {
+ if ( dy < 0 ) {
+ if ( dx > 0 ) {
+ /* walk source bottom to top */
+ /* keep ordering in each band, reverse order of bands */
+ if ( !( pboxNew =
+ (BoxPtr) ALLOCATE_LOCAL( sizeof( BoxRec ) * nbox ) ) )
+ return ;
+ pboxBase = pboxNext = pbox+nbox - 1 ;
+ while ( pboxBase >= pbox ) {
+ while ( ( pboxNext >= pbox )
+ && ( pboxBase->y1 == pboxNext->y1 ) )
+ pboxNext-- ;
+ pboxTmp = pboxNext + 1 ;
+ while ( pboxTmp <= pboxBase )
+ *pboxNew++ = *pboxTmp++ ;
+ pboxBase = pboxNext ;
+ }
+ pboxNew -= nbox ;
+ pbox = pboxNew ;
+ }
+ else { /* dx <= 0 */
+ /* we can just reverse the entire list in place */
+ /* Do three-position swaps */
+ BoxRec tmpBox ;
+
+ pboxBase = pbox ;
+ pboxNext = pbox + nbox - 1 ;
+ while ( pboxBase < pboxNext ) {
+ /* ****** Warning Structure Assignment !! ****** */
+ tmpBox = *pboxBase ;
+ *pboxBase = *pboxNext ;
+ *pboxNext = tmpBox ;
+ pboxBase++ ;
+ pboxNext-- ;
+ }
+ }
+ }
+ else if ( dx < 0 ) {
+ /* walk source right to left */
+ /* reverse order of rects in each band */
+ if ( !( pboxNew = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox) ) )
+ return ;
+ pboxBase = pboxNext = pbox ;
+ while (pboxBase < pbox+nbox)
+ {
+ while ((pboxNext < pbox+nbox) &&
+ (pboxNext->y1 == pboxBase->y1))
+ pboxNext++ ;
+ pboxTmp = pboxNext ;
+ while (pboxTmp != pboxBase)
+ *pboxNew++ = *--pboxTmp ;
+ pboxBase = pboxNext ;
+ }
+ pboxNew -= nbox ;
+ pbox = pboxNew ;
+ }
+ } /* END if nbox > 1 */
+
+ /*
+ * call blit several times, the parms are:
+ * blit( alu,rplanes, wplanes, srcx, srcy, destx, desty, width, height ) ;
+ */
+
+ pm = ( 1 << pWin->drawable.depth ) - 1 ;
+ for ( ; nbox-- ; pbox++ )
+ xf4bppBitBlt( pWin, GXcopy, pm,
+ pbox->x1 + dx, pbox->y1 + dy,
+ pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1) ;
+
+ /* free up stuff */
+ if ( pboxNew )
+ DEALLOCATE_LOCAL( pboxNew ) ;
+
+ (* pWin->drawable.pScreen->RegionDestroy)(prgnDst) ;
+ return ;
+}
+
+Bool xf4bppPositionWindow(pWin, x, y)
+register WindowPtr pWin ;
+register int x, y ;
+{
+ return TRUE ;
+}
+
+Bool
+xf4bppDestroyWindow(pWin)
+register WindowPtr pWin ;
+{
+return pWin ? TRUE : FALSE ;
+}
+
+/* As The Name Says -- Used For ega, vga and apa8c */
+Bool
+xf4bppCreateWindowForXYhardware(pWin)
+register WindowPtr pWin ;
+{
+ register mfbPrivWin *pPrivWin;
+
+ TRACE(("xf4bppCreateWindowForXYhardware (pWin= 0x%x)\n", pWin));
+
+ pPrivWin = (mfbPrivWin *)(pWin->devPrivates[mfbWindowPrivateIndex].ptr);
+ pPrivWin->pRotatedBorder = NullPixmap;
+ pPrivWin->pRotatedBackground = NullPixmap;
+ pPrivWin->fastBackground = 0;
+ pPrivWin->fastBorder = 0;
+
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaBitBlt.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaBitBlt.c
new file mode 100644
index 000000000..1885a860f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaBitBlt.c
@@ -0,0 +1,757 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/vgaBitBlt.c,v 1.3 1999/06/06 08:49:06 dawes Exp $ */
+/* GJA -- span move routines */
+
+
+
+/* $XConsortium: vgaBitBlt.c /main/8 1996/10/27 11:06:39 kaleb $ */
+
+#include "xf4bpp.h"
+#include "OScompiler.h"
+#include "vgaReg.h"
+#include "vgaVideo.h"
+
+#include "xf86str.h" /* for pScrn->vtSema */
+extern ScrnInfoPtr *xf86Screens;
+
+#ifndef PC98_EGC /* not PC98_EGC */
+/* NOTE: It seems that there is no way to program the VGA to copy just
+ * a part of a byte in the smarter modes. Therefore we copy the boundaries
+ * plane by plane.
+ */
+#define WORDSZ 8
+ /* The fast blit code requires WORDSZ = 8 for its read-modify write cycle.
+ * Therefore, we do not fully implement the other options.
+ */
+#define HIGHPLANEMASK 0x08
+#define HIGHPLANEINDEX 3
+
+/* Of course, we want the following anyway:
+ * (Yes, they're identical now.)
+ */
+#define SMEM(x,y) ( VIDBASE(pWin) + (y) * BYTES_PER_LINE(pWin) + (x) )
+#define DMEM(x,y) ( VIDBASE(pWin) + (y) * BYTES_PER_LINE(pWin) + (x) )
+
+#define WORD8 unsigned char
+#define LW8 BYTES_PER_LINE(pWin) /* Line width */
+#define WSHIFT8 0x3
+#define WMASK8 0x07
+/* NOTE: lmask[8] matters. It must be different from lmask[0] */
+static unsigned char lmasktab[] = {
+ 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF
+} ;
+static unsigned char rmasktab[] = {
+ 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00
+} ;
+
+#define LMASK8(n) lmasktab[n]
+#define RMASK8(n) rmasktab[n]
+#define SWAPB8(x) (x)
+
+#if (WORDSZ == 8)
+
+#define WORD WORD8
+#define LW LW8
+#define WSHIFT WSHIFT8
+#define WMASK WMASK8
+
+#define LMASK(n) LMASK8(n)
+#define RMASK(n) RMASK8(n)
+#define SWAPB(x) SWAPB8(x)
+
+#endif /* WORDSZ == 8 */
+
+#define DO_ALU(dst,src,mask,alu) {\
+ int _ndst, _odst; _odst = dst; \
+ switch ( alu ) { \
+ case GXclear: \
+ _ndst = 0; break; \
+ case GXand: \
+ _ndst = src & _odst; break; \
+ case GXandReverse: \
+ _ndst = src & ~ _odst; break; \
+ case GXcopy: \
+ _ndst = src; break; \
+ case GXandInverted: \
+ _ndst = ~ src & _odst; break; \
+ default: \
+ case GXnoop: \
+ _ndst = _odst; break; \
+ case GXxor: \
+ _ndst = src ^ _odst; break; \
+ case GXor: \
+ _ndst = src | _odst; break; \
+ case GXnor: \
+ _ndst = ~ src & ~ _odst; break; \
+ case GXequiv: \
+ _ndst = ~ src ^ _odst; break; \
+ case GXinvert: \
+ _ndst = ~ _odst; break; \
+ case GXorReverse: \
+ _ndst = src | ~ _odst; break; \
+ case GXcopyInverted: \
+ _ndst = ~ src; break; \
+ case GXorInverted: \
+ _ndst = ~ src | _odst; break; \
+ case GXnand: \
+ _ndst = ~ src | ~ _odst; break; \
+ case GXset: \
+ _ndst = ~0; break; \
+ } \
+ dst = (_odst & ~(mask)) | (_ndst & (mask)); \
+ }
+
+static void aligned_blit(
+#if NeedFunctionPrototypes
+ WindowPtr, int, int, int, int, int, int, int, int
+#endif
+);
+
+static void aligned_blit_center(
+#if NeedFunctionPrototypes
+ WindowPtr, int, int, int, int, int, int
+#endif
+);
+
+static void shift(
+#if NeedFunctionPrototypes
+ WindowPtr, int, int, int, int, int, int, int
+#endif
+);
+
+static void shift_thin_rect(
+#if NeedFunctionPrototypes
+ WindowPtr, int, int, int, int, int, int, int
+#endif
+);
+
+static void shift_center(
+#if NeedFunctionPrototypes
+ WindowPtr, int, int, int, int, int, int, int
+#endif
+);
+
+void xf4bppBitBlt(pWin,alu,writeplanes,x0,y0,x1,y1,w,h)
+WindowPtr pWin; /* GJA */
+int alu;
+int writeplanes; /* planes */
+int x0, y0, x1, y1, w, h;
+{
+ int plane, bit;
+
+ if ( !w || !h ) return;
+
+ if ( ! xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) {
+ xf4bppOffBitBlt(pWin,alu,writeplanes,x0,y0,x1,y1,w,h);
+ return;
+ }
+
+ /* 0x7, not WMASK: it is hardware dependant */
+ if ( ((x0 - x1) & 0x7) || (alu != GXcopy) ) {
+ /* Use slow copy */
+ SetVideoGraphics(Enb_Set_ResetIndex, 0); /* All from CPU */
+ SetVideoGraphics(Bit_MaskIndex, 0xFF); /* All bits */
+ SetVideoGraphics(Graphics_ModeIndex, 0); /* Write mode 0 */
+ SetVideoGraphics(Data_RotateIndex, 0); /* Don't rotate, replace */
+
+ for ( plane = HIGHPLANEMASK, bit = HIGHPLANEINDEX ;
+ plane ; plane >>= 1, bit-- )
+ {
+
+ if ( writeplanes & plane) {
+ SetVideoGraphics(Read_Map_SelectIndex, bit);
+ SetVideoSequencer(Mask_MapIndex, plane);
+
+ shift(pWin,x0,x1,y0,y1,w,h,alu);
+ }
+ }
+ } else {
+ aligned_blit(pWin,x0,x1,y0,y1,w,h,alu,writeplanes);
+ }
+}
+
+/* Copy a span a number of places to the right.
+ */
+static void
+shift(pWin,x0,x1,y0,y1,w,h,alu)
+WindowPtr pWin; /* GJA */
+int x0; /* left edge of source */
+int x1; /* left edge of target */
+int y0;
+int y1;
+int w; /* length of source, and of target */
+int h;
+int alu;
+{
+ if ( ((x1 & WMASK) + w) <= WORDSZ ) {
+ shift_thin_rect(pWin,x0,x1,y0,y1,w,h,alu);
+ } else if ( x1 > x0 ) { /* Shift right: start right */
+ int l1 = x1 & WMASK, r1 = (x1 + w) & WMASK;
+
+ if ( r1 ) /* right edge */
+ shift_thin_rect(pWin,x0+w-r1,x1+w-r1,y0,y1,r1,h,alu);
+ shift_center(pWin,x0,x1,y0,y1,w,h,alu);
+ if ( l1 ) /* left edge */
+ shift_thin_rect(pWin,x0,x1,y0,y1,(WORDSZ-l1),h,alu);
+ } else {
+ int l1 = x1 & WMASK, r1 = (x1 + w) & WMASK;
+
+ if ( l1 ) /* left edge */
+ shift_thin_rect(pWin,x0,x1,y0,y1,(WORDSZ-l1),h,alu);
+ shift_center(pWin,x0,x1,y0,y1,w,h,alu);
+ if ( r1 ) /* right edge */
+ shift_thin_rect(pWin,x0+w-r1,x1+w-r1,y0,y1,r1,h,alu);
+ }
+}
+
+/* The whole rectangle is so thin that it fits in one byte written */
+static void
+shift_thin_rect(pWin,x0,x1,y0,y1,w,h,alu)
+WindowPtr pWin; /* GJA */
+int x0; /* left edge of source */
+int x1; /* left edge of target */
+int y0;
+int y1;
+int w; /* length of source, and of target */
+int h;
+int alu;
+{
+ int l0 = x0 & WMASK; /* Left edge of source, as bit */
+ int l1 = x1 & WMASK; /* Left edge of target, as bit */
+ int L0 = x0 >> WSHIFT; /* Left edge of source, as byte */
+ int L1 = x1 >> WSHIFT; /* Left edge of target, as byte */
+ int pad;
+ int htmp;
+ int mask;
+ int tmp;
+ int bs;
+
+ volatile unsigned char *sp, *dp;
+
+ mask = RMASK(l1) & LMASK(l1+w);
+ bs = (x1 - x0) & WMASK;
+
+ if ( y1 > y0 ) { /* Move down, start at the bottom */
+ pad = - BYTES_PER_LINE(pWin);
+ sp = SMEM(L0,y0+h-1);
+ dp = DMEM(L1,y1+h-1);
+ } else { /* Move up, start at the top */
+ pad = BYTES_PER_LINE(pWin);
+ sp = SMEM(L0,y0);
+ dp = DMEM(L1,y1);
+ }
+
+ if ( l0+w > WORDSZ ) {
+ /* Need two bytes */
+ for ( htmp = h ; htmp ; htmp-- ) {
+ tmp = (sp[0] << (WORDSZ - bs));
+ sp++;
+ tmp |= (sp[0] >> bs);
+ sp--;
+ DO_ALU(dp[0],tmp,mask,alu);
+ dp += pad;
+ sp += pad;
+ }
+ } else if ( l0 <= l1 ) {
+ /* Need one byte, shifted right */
+ for ( htmp = h ; htmp ; htmp-- ) {
+ tmp = (sp[0] >> bs);
+ DO_ALU(dp[0],tmp,mask,alu);
+ dp += pad;
+ sp += pad;
+ }
+ } else {
+ /* Need one byte, shifted left */
+ for ( htmp = h ; htmp ; htmp-- ) {
+ tmp = (sp[0] << (WORDSZ - bs));
+ DO_ALU(dp[0],tmp,mask,alu);
+ dp += pad;
+ sp += pad;
+ }
+ }
+}
+
+static void
+shift_center(pWin,x0,x1,y0,y1,w,h,alu)
+WindowPtr pWin; /* GJA */
+int x0; /* left edge of source */
+int x1; /* left edge of target */
+int y0;
+int y1;
+int w; /* length of source, and of target */
+int h;
+int alu;
+{
+ int l1 = x1 & WMASK; /* Left edge of target, as bit */
+ int r1 = (x1 + w) & WMASK; /* Right edge of target, as bit */
+ int pad;
+ int htmp, wtmp; /* Temporaries for indices over height and width */
+ volatile unsigned char tmp; /* Temporary result of the shifts */
+ int bs;
+ int rem; /* Remaining bits; temporary in loop */
+ int bytecnt;
+
+ volatile unsigned char *sp, *dp;
+
+ bs = (x1 - x0) & WMASK;
+
+ if ( l1 ) {
+ bytecnt = (w - (WORDSZ - l1) - r1) >> WSHIFT;
+ sp = SMEM( ((x0 + (WORDSZ - l1)) >> WSHIFT), y0);
+ dp = DMEM( ((x1 + (WORDSZ - l1)) >> WSHIFT), y1);
+ } else {
+ bytecnt = (w - r1) >> WSHIFT;
+ sp = SMEM( (x0 >> WSHIFT), y0);
+ dp = DMEM( (x1 >> WSHIFT), y1);
+ }
+
+ if ( y1 > y0 ) { /* Move down, start at the bottom */
+ if ( x1 > x0 ) { /* Move right, start right */
+ pad = - BYTES_PER_LINE(pWin) + bytecnt;
+ sp += BYTES_PER_LINE(pWin) * (h - 1) + bytecnt - 1;
+ dp += BYTES_PER_LINE(pWin) * (h - 1) + bytecnt - 1;
+ } else { /* Move left, start left */
+ pad = - BYTES_PER_LINE(pWin) - bytecnt;
+ sp += BYTES_PER_LINE(pWin) * (h - 1);
+ dp += BYTES_PER_LINE(pWin) * (h - 1);
+ }
+ } else { /* Move up, start at the top */
+ if ( x1 > x0 ) { /* Move right, start right */
+ pad = BYTES_PER_LINE(pWin) + bytecnt;
+ sp += bytecnt - 1;
+ dp += bytecnt - 1;
+ } else { /* Move left, start left */
+ pad = BYTES_PER_LINE(pWin) - bytecnt;
+ sp += 0;
+ dp += 0;
+ }
+ }
+
+ if ( x1 > x0 ) { /* Move right, start right */
+ if ( bs == 0 ) { /* No shift. Need one byte only */
+ for ( htmp = h ; htmp ; htmp-- ) {
+ for ( wtmp = bytecnt ; wtmp ; wtmp-- ) {
+ tmp = sp[0];
+ DO_ALU(dp[0],tmp,~0,alu);
+ dp--;
+ sp--;
+ }
+ dp += pad;
+ sp += pad;
+ }
+ } else {
+ for ( htmp = h ; htmp ; htmp-- ) {
+ if ( bytecnt ) {
+ sp++;
+ rem = sp[0];
+ sp--;
+ for ( wtmp = bytecnt ; wtmp ; wtmp-- ) {
+ tmp = (rem >> bs);
+ rem = sp[0];
+ tmp |= (rem << (WORDSZ - bs)) ;
+ DO_ALU(dp[0],tmp,~0,alu);
+ dp--;
+ sp--;
+ }
+ }
+ dp += pad;
+ sp += pad;
+ }
+ }
+ } else { /* x1 <= x0 */ /* Move left, start left */
+ if ( bs == 0 ) { /* No shift. Need one byte only */
+ for ( htmp = h ; htmp ; htmp-- ) {
+ for ( wtmp = bytecnt ; wtmp ; wtmp-- ) {
+ tmp = sp[0];
+ DO_ALU(dp[0],tmp,~0,alu);
+ dp++;
+ sp++;
+ }
+ dp += pad;
+ sp += pad;
+ }
+ } else {
+ for ( htmp = h ; htmp ; htmp-- ) {
+ if ( bytecnt ) {
+ rem = sp[0];
+ for ( wtmp = bytecnt ; wtmp ; wtmp-- ) {
+ tmp = (rem << (WORDSZ - bs));
+ sp++;
+ rem = sp[0];
+ sp--;
+ tmp |= (rem >> bs);
+ DO_ALU(dp[0],tmp,~0,alu);
+ dp++;
+ sp++;
+ }
+ }
+ dp += pad;
+ sp += pad;
+ }
+ }
+ }
+}
+
+/* Copy a rectangle.
+ */
+static void
+aligned_blit(pWin,x0,x1,y0,y1,w,h,alu,planes)
+WindowPtr pWin; /* GJA */
+int x0; /* left edge of source */
+int x1; /* left edge of target */
+int y0;
+int y1;
+int w; /* length of source, and of target */
+int h;
+int alu;
+int planes;
+{
+ int plane, bit;
+
+ if ( ((x1 & WMASK) + w) <= WORDSZ ) {
+ SetVideoGraphics(Enb_Set_ResetIndex, 0); /* All from CPU */
+ SetVideoGraphics(Bit_MaskIndex, 0xFF); /* All bits */
+ SetVideoGraphics(Graphics_ModeIndex, 0); /* Write mode 0 */
+ SetVideoGraphics(Data_RotateIndex, 0); /* Don't rotate, replace */
+
+ for ( plane = HIGHPLANEMASK, bit = HIGHPLANEINDEX;
+ plane ; plane >>= 1, bit-- )
+ {
+ if ( planes & plane) {
+ SetVideoGraphics(Read_Map_SelectIndex, bit);
+ SetVideoSequencer(Mask_MapIndex, plane);
+
+ shift_thin_rect(pWin,x0,x1,y0,y1,w,h,alu);
+ }
+ }
+ } else if ( x1 > x0 ) { /* Shift right: start right */
+ int l1 = x1 & WMASK, r1 = (x1 + w) & WMASK;
+
+ if ( r1 ) { /* right edge */
+ SetVideoGraphics(Enb_Set_ResetIndex, 0); /* All from CPU */
+ SetVideoGraphics(Bit_MaskIndex, 0xFF); /* All bits */
+ SetVideoGraphics(Graphics_ModeIndex, 0); /* Write mode 0 */
+ SetVideoGraphics(Data_RotateIndex, 0); /* Don't rotate, replace */
+
+ for ( plane = HIGHPLANEMASK, bit = HIGHPLANEINDEX;
+ plane ; plane >>= 1, bit-- )
+ {
+ if ( planes & plane) {
+ SetVideoGraphics(Read_Map_SelectIndex, bit);
+ SetVideoSequencer(Mask_MapIndex, plane);
+
+ shift_thin_rect(pWin,x0+w-r1,x1+w-r1,y0,y1,r1,h,alu);
+ }
+ }
+ }
+
+ /* Center */
+ SetVideoGraphics(Graphics_ModeIndex, 1); /* Write mode 1 */
+ SetVideoSequencer(Mask_MapIndex, planes);
+
+ aligned_blit_center(pWin,x0,x1,y0,y1,w,h);
+
+ if ( l1 ) { /* left edge */
+ SetVideoGraphics(Enb_Set_ResetIndex, 0); /* All from CPU */
+ SetVideoGraphics(Bit_MaskIndex, 0xFF); /* All bits */
+ SetVideoGraphics(Graphics_ModeIndex, 0); /* Write mode 0 */
+ SetVideoGraphics(Data_RotateIndex, 0); /* Don't rotate, replace */
+
+ for ( plane = HIGHPLANEMASK, bit = HIGHPLANEINDEX;
+ plane ; plane >>= 1, bit-- )
+ {
+ if ( planes & plane) {
+ SetVideoGraphics(Read_Map_SelectIndex, bit);
+ SetVideoSequencer(Mask_MapIndex, plane);
+
+ shift_thin_rect(pWin,x0,x1,y0,y1,(WORDSZ-l1),h,alu);
+ }
+ }
+ }
+ } else {
+ int l1 = x1 & WMASK, r1 = (x1 + w) & WMASK;
+
+ if ( l1 ) { /* left edge */
+ SetVideoGraphics(Enb_Set_ResetIndex, 0); /* All from CPU */
+ SetVideoGraphics(Bit_MaskIndex, 0xFF); /* All bits */
+ SetVideoGraphics(Graphics_ModeIndex, 0); /* Write mode 0 */
+ SetVideoGraphics(Data_RotateIndex, 0); /* Don't rotate, replace */
+
+ for ( plane = HIGHPLANEMASK, bit = HIGHPLANEINDEX;
+ plane ; plane >>= 1, bit-- )
+ {
+ if ( planes & plane) {
+ SetVideoGraphics(Read_Map_SelectIndex, bit);
+ SetVideoSequencer(Mask_MapIndex, plane);
+
+ shift_thin_rect(pWin,x0,x1,y0,y1,(WORDSZ-l1),h,alu);
+ }
+ }
+ }
+
+ /* Center */
+ SetVideoGraphics(Graphics_ModeIndex, 1); /* Write mode 1 */
+ SetVideoSequencer(Mask_MapIndex, planes);
+
+ aligned_blit_center(pWin,x0,x1,y0,y1,w,h);
+
+ if ( r1 ) { /* right edge */
+ SetVideoGraphics(Enb_Set_ResetIndex, 0); /* All from CPU */
+ SetVideoGraphics(Bit_MaskIndex, 0xFF); /* All bits */
+ SetVideoGraphics(Graphics_ModeIndex, 0); /* Write mode 0 */
+ SetVideoGraphics(Data_RotateIndex, 0); /* Don't rotate, replace */
+
+ for ( plane = HIGHPLANEMASK, bit = HIGHPLANEINDEX ;
+ plane ; plane >>= 1, bit-- )
+ {
+ if ( planes & plane) {
+ SetVideoGraphics(Read_Map_SelectIndex, bit);
+ SetVideoSequencer(Mask_MapIndex, plane);
+
+ shift_thin_rect(pWin,x0+w-r1,x1+w-r1,y0,y1,r1,h,alu);
+ }
+ }
+ }
+ }
+}
+
+static void
+aligned_blit_center(pWin,x0,x1,y0,y1,w,h)
+WindowPtr pWin; /* GJA */
+int x0; /* left edge of source */
+int x1; /* left edge of target */
+int y0;
+int y1;
+int w; /* length of source, and of target */
+int h;
+{
+ int l1 = x1 & WMASK; /* Left edge of target, as bit */
+ int r1 = (x1 + w) & WMASK; /* Right edge of target, as bit */
+ int pad;
+ int htmp, wtmp; /* Temporaries for indices over height and width */
+ volatile unsigned char tmp; /* Temporary result of the shifts */
+ int bs;
+ int bytecnt;
+
+ volatile unsigned char *sp, *dp;
+
+ bs = (x1 - x0) & WMASK;
+
+ if ( l1 ) {
+ bytecnt = (w - (WORDSZ - l1) - r1) >> WSHIFT;
+ sp = SMEM( ((x0 + (WORDSZ - l1)) >> WSHIFT), y0);
+ dp = DMEM( ((x1 + (WORDSZ - l1)) >> WSHIFT), y1);
+ } else {
+ bytecnt = (w - r1) >> WSHIFT;
+ sp = SMEM( (x0 >> WSHIFT), y0);
+ dp = DMEM( (x1 >> WSHIFT), y1);
+ }
+
+ if ( y1 > y0 ) { /* Move down, start at the bottom */
+ if ( x1 > x0 ) { /* Move right, start right */
+ pad = - BYTES_PER_LINE(pWin) + bytecnt;
+ sp += BYTES_PER_LINE(pWin) * (h - 1) + bytecnt - 1;
+ dp += BYTES_PER_LINE(pWin) * (h - 1) + bytecnt - 1;
+ } else { /* Move left, start left */
+ pad = - BYTES_PER_LINE(pWin) - bytecnt;
+ sp += BYTES_PER_LINE(pWin) * (h - 1);
+ dp += BYTES_PER_LINE(pWin) * (h - 1);
+ }
+ } else { /* Move up, start at the top */
+ if ( x1 > x0 ) { /* Move right, start right */
+ pad = BYTES_PER_LINE(pWin) + bytecnt;
+ sp += bytecnt - 1;
+ dp += bytecnt - 1;
+ } else { /* Move left, start left */
+ pad = BYTES_PER_LINE(pWin) - bytecnt;
+ sp += 0;
+ dp += 0;
+ }
+ }
+
+ if ( x1 > x0 ) { /* Move right, start right */
+ for ( htmp = h ; htmp ; htmp-- ) {
+ for ( wtmp = bytecnt ; wtmp ; wtmp-- ) {
+ tmp = sp[0];
+ dp[0] = tmp;
+ dp--;
+ sp--;
+ }
+ dp += pad;
+ sp += pad;
+ }
+ } else { /* x1 <= x0 */ /* Move left, start left */
+ for ( htmp = h ; htmp ; htmp-- ) {
+ for ( wtmp = bytecnt ; wtmp ; wtmp-- ) {
+ tmp = sp[0];
+ dp[0] = tmp;
+ dp++;
+ sp++;
+ }
+ dp += pad;
+ sp += pad;
+ }
+ }
+}
+#else /* PC98_EGC */
+
+static void
+egc_fast_blt (pWin, alu, writeplanes, x0, y0, x1, y1, w, h)
+WindowPtr pWin;
+const int alu, writeplanes ;
+register int x0, x1 ;
+int y0, y1 ;
+register int w, h ;
+{
+register volatile unsigned char *src ;
+register volatile unsigned char *dst ;
+unsigned short *src_x ;
+unsigned short *dst_x ;
+int x_direction, y_interval ;
+int src_off, dst_off ;
+register int k, i ;
+unsigned short ROP_value;
+
+src = (unsigned char *)SCREENADDRESS( pWin, 0, y0);
+dst = (unsigned char *)SCREENADDRESS( pWin, 0, y1);
+
+/* Set Map Mask */
+outw(EGC_PLANE, ~(writeplanes & VGA_ALLPLANES));
+switch(alu) {
+case GXnor: /* ~(S|D) */
+ ROP_value = 0x2903;
+ break;
+case GXandInverted: /* ~S&D */
+ ROP_value = 0x290c;
+ break;
+case GXand: /* S&D */
+ ROP_value = 0x29c0;
+ break;
+case GXequiv: /* ~S ^ D */
+ ROP_value = 0x29c3;
+ break;
+case GXxor: /* S^D */
+ ROP_value = 0x293c;
+ break;
+case GXandReverse: /* S&~D */
+ ROP_value = 0x2930;
+ break;
+case GXorReverse: /* S|~D */
+ ROP_value = 0x29f3;
+ break;
+case GXnand: /* ~(S&D) */
+ ROP_value = 0x293f;
+ break;
+case GXorInverted: /* ~S|D */
+ ROP_value = 0x29cf;
+ break;
+case GXor: /* S|D */
+ ROP_value = 0x29fa;
+ break;
+case GXcopyInverted: /* ~S */
+ ROP_value = 0x290f;
+ break;
+case GXcopy: /* S */
+default:
+ ROP_value = 0x29f0;
+}
+outw(EGC_MODE, ROP_value);
+if ( y1 > y0 ) {
+ y_interval = - BYTES_PER_LINE(pWin) * 8 ;
+ src += BYTES_PER_LINE(pWin) * ( h - 1 ) ;
+ dst += BYTES_PER_LINE(pWin) * ( h - 1 ) ;
+}
+else {
+ y_interval = BYTES_PER_LINE(pWin) * 8 ;
+}
+
+src = (unsigned char *)((int)src << 3) ;
+dst = (unsigned char *)((int)dst << 3) ;
+
+if ( y1 > y0) {
+ x_direction = 0x1000 ;
+ src += x0 + w - 1 ;
+ dst += x1 + w - 1 ;
+} else if ( y1 < y0 ) {
+ x_direction = 0 ;
+ src += x0 ;
+ dst += x1 ;
+} else {
+ if ( x1 < x0 ) {
+ x_direction = 0 ;
+ src += x0 ;
+ dst += x1 ;
+ } else {
+ x_direction = 0x1000 ;
+ src += x0 + w - 1 ;
+ dst += x1 + w - 1 ;
+ }
+}
+ outw ( EGC_LENGTH , w - 1 ) ;
+
+for ( ; h-- ; ) {
+ if ( x_direction ) {
+ src_off = 15 - (int)src & 0xf ;
+ dst_off = 15 - (int)dst & 0xf ;
+ } else {
+ src_off = (int)src & 0xf ;
+ dst_off = (int)dst & 0xf ;
+ }
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+ src_x = (unsigned short *)(((unsigned int)src >> 4 ) << 1) ;
+ dst_x = (unsigned short *)(((unsigned int)dst >> 4 ) << 1) ;
+#else
+ src_x = (unsigned short *)(((int)src >> 4 ) << 1) ;
+ dst_x = (unsigned short *)(((int)dst >> 4 ) << 1) ;
+#endif
+ k = ( src_off + w + 15 ) >> 4 ;
+ if ( src_off < dst_off ) {
+ if ( ((src_off + w - 1 ) >> 4) < ((dst_off + w - 1) >> 4)) k++ ;
+ }
+ if ( src_off > dst_off ) {
+ if ( ((src_off + w - 1) >> 4 ) == ((dst_off + w - 1) >> 4) ) k++ ;
+ if ( x_direction ) dst_x ++ ;
+ else dst_x -- ;
+ }
+ outw ( EGC_ADD , x_direction | src_off | dst_off << 4 );
+ if ( x_direction ) {
+ wcopyl ( src_x, dst_x, k, VIDBASE(pWin) ) ;
+ } else {
+ wcopyr ( src_x, dst_x, k, VIDBASE(pWin) ) ;
+ }
+src += y_interval ;
+dst += y_interval ;
+}
+outw ( EGC_ADD, 0 ) ;
+outw ( EGC_LENGTH , 0xf );
+return;
+}
+
+void
+xf4bppBitBlt( pWin,alu, writeplanes, x0, y0, x1, y1, w, h )
+WindowPtr pWin; /* GJA */
+int alu;
+int writeplanes; /* planes */
+int x0, y0, x1, y1, w, h;
+{
+ if ( ! xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) {
+ xf4bppOffBitBlt( pWin, alu, writeplanes,
+ x0, y0, x1, y1, w, h );
+ return;
+ }
+
+switch ( alu ) {
+ case GXclear: /* 0x0 Zero 0 */
+ case GXinvert: /* 0xa NOT dst */
+ case GXset: /* 0xf 1 */
+ xf4bppFillSolid( pWin, VGA_ALLPLANES, alu, writeplanes, x1, y1, w, h ) ;
+ /* x1, y1, GJA */
+ case GXnoop: /* 0x5 dst */
+ return ;
+ default:
+ break ;
+}
+
+egc_fast_blt ( pWin, alu, writeplanes, x0, y0, x1, y1, w, h);
+return;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaGC.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaGC.c
new file mode 100644
index 000000000..0c6f48544
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaGC.c
@@ -0,0 +1,218 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/vgaGC.c,v 1.3 1999/06/06 08:49:06 dawes Exp $ */
+/*
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+
+Copyright IBM Corporation 1987,1988,1989
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of IBM not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+
+/* $XConsortium: vgaGC.c /main/6 1996/02/21 17:58:54 kaleb $ */
+
+#include "xf4bpp.h"
+#include "mfbmap.h"
+#include "mfb.h"
+#include "mi.h"
+#include "ppcGCstr.h"
+
+void
+xf4bppChangeGCtype( pGC, devPriv )
+register GC *pGC ;
+register ppcPrivGCPtr devPriv ;
+{
+ if ( devPriv->lastDrawableType == DRAWABLE_PIXMAP ) {
+ devPriv->FillArea = mfbSolidInvertArea ;
+ pGC->ops->CopyArea = miCopyArea ;
+ pGC->ops->PolyFillRect = miPolyFillRect ;
+ pGC->ops->PushPixels = miPushPixels ;
+ pGC->ops->PolyArc = miPolyArc ;
+ pGC->ops->PolyFillArc = miPolyFillArc ;
+ pGC->ops->PolySegment = miPolySegment ;
+ }
+ else {
+ devPriv->FillArea = xf4bppAreaFill ;
+ pGC->ops->CopyArea = xf4bppCopyArea ;
+ pGC->ops->PolyFillRect = xf4bppPolyFillRect ;
+ pGC->ops->PushPixels = miPushPixels ; /* GJA */
+ pGC->ops->PolyArc = xf4bppZeroPolyArc ;
+ pGC->ops->PolyFillArc = xf4bppPolyFillArc ;
+ pGC->ops->PolySegment = xf4bppSegmentSS ;
+ }
+ return;
+}
+
+Mask
+xf4bppChangeWindowGC( pGC, changes )
+register GC *pGC ;
+register Mask changes ;
+{
+register ppcPrivGCPtr devPriv = (ppcPrivGCPtr) (pGC->devPrivates[mfbGCPrivateIndex].ptr) ;
+register unsigned long int idx ; /* used for stepping through bitfields */
+
+#define LOWBIT( x ) ( x & - x ) /* Two's complement */
+ while ((idx = LOWBIT(changes))) {
+ switch ( idx ) {
+
+ case GCLineStyle:
+ case GCLineWidth:
+ pGC->ops->PolyArc = ( ( pGC->lineStyle == LineSolid )
+ ? ( ( pGC->lineWidth == 0 ) ? xf4bppZeroPolyArc
+ : miPolyArc )
+ : miPolyArc ) ;
+ pGC->ops->PolySegment = ( ( pGC->lineStyle == LineSolid )
+ ? ( ( pGC->lineWidth == 0 )
+ ? ( ( pGC->fillStyle == FillSolid ) ?
+ xf4bppSegmentSS : miPolySegment )
+ : miPolySegment )
+ : ( ( pGC->lineWidth == 0 )
+ ? ( ( pGC->fillStyle == FillSolid ) ?
+ xf4bppSegmentSD : miPolySegment )
+ : miPolySegment ) ) ;
+ pGC->ops->Polylines = ( ( pGC->lineStyle == LineSolid )
+ ? ( ( pGC->lineWidth == 0 )
+ ? ( (pGC->fillStyle == FillSolid ) ?
+ xf4bppLineSS : miZeroLine )
+ : miWideLine )
+ : ( ( pGC->lineWidth == 0 )
+ ? ( (pGC->fillStyle == FillSolid ) ?
+ xf4bppLineSD : miWideDash )
+ : miWideDash ) ) ;
+ /*
+ * If these are just square boxes with no funny business
+ * going on we can call the fast routine that draws
+ * rectangles without floating point.
+ */
+/* too buggy */
+#if 0
+ if ( ( pGC->lineStyle == LineSolid )
+ && ( pGC->joinStyle == JoinMiter )
+ && ( pGC->lineWidth != 0 ) )
+ pGC->ops->PolyRectangle = xf4bppPolyRectangle;
+ else
+#endif
+ pGC->ops->PolyRectangle = miPolyRectangle;
+
+ changes &= ~( GCLineStyle | GCLineWidth ) ;
+ break ;
+ case GCJoinStyle:
+#ifdef NEED_LINEHELPER
+ pGC->ops->LineHelper =
+ ( pGC->joinStyle == JoinMiter ) ? miMiter : miNotMiter ;
+#endif
+ /*
+ * If these are just square boxes with no funny business
+ * going on we can call the fast routine that draws
+ * rectangles without floating point.
+ */
+/* too buggy */
+#if 0
+ if ( ( pGC->lineStyle == LineSolid )
+ && ( pGC->joinStyle == JoinMiter )
+ && ( pGC->lineWidth != 0 ) )
+ pGC->ops->PolyRectangle = xf4bppPolyRectangle;
+ else
+#endif
+ pGC->ops->PolyRectangle = miPolyRectangle;
+ changes &= ~ idx ; /* i.e. changes &= ~ GCJoinStyle */
+ break ;
+
+ case GCBackground:
+ if ( pGC->fillStyle != FillOpaqueStippled ) {
+ changes &= ~ idx ; /* i.e. changes &= ~GCBackground */
+ break ;
+ } /* else Fall Through */
+ case GCForeground:
+ if ( pGC->fillStyle == FillTiled ) {
+ changes &= ~ idx ; /* i.e. changes &= ~GCForeground */
+ break ;
+ } /* else Fall Through */
+ case GCFunction:
+ case GCPlaneMask:
+ case GCFillStyle:
+ { /* new_fill */
+ int fillStyle = devPriv->colorRrop.fillStyle ;
+ /* install a suitable fillspans */
+ if ( fillStyle == FillSolid )
+ pGC->ops->FillSpans = xf4bppSolidWindowFS ;
+ else if ( fillStyle == FillStippled )
+ pGC->ops->FillSpans = xf4bppStippleWindowFS ;
+ else if ( fillStyle == FillOpaqueStippled )
+ pGC->ops->FillSpans = xf4bppOpStippleWindowFS ;
+ else /* fillStyle == FillTiled */
+ pGC->ops->FillSpans = xf4bppTileWindowFS ;
+ } /* end of new_fill */
+ changes &= ~( GCBackground | GCForeground
+ | GCFunction
+ | GCPlaneMask | GCFillStyle ) ;
+ break ;
+
+ default:
+ ErrorF("xf4bppChangeWindowGC: Unexpected GC Change\n") ;
+ changes &= ~ idx ; /* Remove it anyway */
+ break ;
+ }
+ }
+ return changes;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaImages.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaImages.c
new file mode 100644
index 000000000..f8ba7884a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaImages.c
@@ -0,0 +1,448 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/vgaImages.c,v 1.3 1999/06/06 08:49:07 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+/* $XConsortium: vgaImages.c /main/5 1996/02/21 17:58:58 kaleb $ */
+
+#include "xf4bpp.h"
+#include "OScompiler.h"
+#include "vgaReg.h"
+#include "vgaVideo.h"
+
+#include "xf86str.h" /* for pScrn->vtSema */
+extern ScrnInfoPtr *xf86Screens;
+
+#undef TRUE
+#undef FALSE
+#define TRUE 1
+#define FALSE 0
+
+void
+xf4bppDrawColorImage( pWin, x, y, w, h, data, RowIncrement, alu, planes )
+WindowPtr pWin; /* GJA */
+int x, y ;
+register int w, h ;
+unsigned char *data ;
+register int RowIncrement ;
+const int alu ;
+const unsigned long int planes ;
+{
+register unsigned long int tmp ;
+register const unsigned char *src ;
+register volatile unsigned char *dst ;
+register int Pixel_Count ;
+register unsigned int currMask ;
+register unsigned int InitialMask ;
+register volatile unsigned char *StartByte ;
+unsigned int invert_source_data = FALSE ;
+#ifdef PC98_EGC /* new EGC test */
+register unsigned char tmp1;
+#endif
+
+{ /* Start GJA */
+ if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) {
+ xf4bppOffDrawColorImage( pWin, x, y, w, h, data, RowIncrement, alu, planes );
+ return;
+ }
+} /* End GJA */
+
+{
+ unsigned int invert_existing_data = FALSE ;
+ unsigned int data_rotate_value = VGA_COPY_MODE ;
+#ifdef PC98_EGC
+ unsigned short ROP_value;
+#endif
+
+ switch ( alu ) {
+ case GXclear: /* 0x0 Zero 0 */
+ case GXinvert: /* 0xa NOT dst */
+ case GXset: /* 0xf 1 */
+ xf4bppFillSolid( pWin, VGA_ALLPLANES, alu, planes, x, y, w, h ) ;
+ case GXnoop: /* 0x5 dst */
+ return ;
+ case GXnor: /* 0x8 NOT src AND NOT dst */
+ invert_existing_data = TRUE ;
+ case GXandInverted: /* 0x4 NOT src AND dst */
+ invert_source_data = TRUE ;
+ case GXand: /* 0x1 src AND dst */
+ data_rotate_value = VGA_AND_MODE ;
+ break ;
+ case GXequiv: /* 0x9 NOT src XOR dst */
+ invert_source_data = TRUE ;
+ case GXxor: /* 0x6 src XOR dst */
+ data_rotate_value = VGA_XOR_MODE ;
+ break ;
+ case GXandReverse: /* 0x2 src AND NOT dst */
+ invert_existing_data = TRUE ;
+ data_rotate_value = VGA_AND_MODE ;
+ break ;
+ case GXnand: /* 0xe NOT src OR NOT dst */
+ invert_source_data = TRUE ;
+ case GXorReverse: /* 0xb src OR NOT dst */
+ invert_existing_data = TRUE ;
+ /* GJA -- moved this here */
+ data_rotate_value = VGA_OR_MODE ;
+ break ;
+ case GXorInverted: /* 0xd NOT src OR dst */
+ invert_source_data = TRUE ;
+ case GXor: /* 0x7 src OR dst */
+ data_rotate_value = VGA_OR_MODE ;
+ break ;
+ case GXcopyInverted: /* 0xc NOT src */
+ invert_source_data = TRUE ;
+ case GXcopy: /* 0x3 src */
+ default:
+ break ;
+ }
+#ifndef PC98_EGC
+ if ( invert_existing_data )
+ xf4bppFillSolid( pWin, VGA_ALLPLANES, GXinvert, planes, x, y, w, h ) ;
+#endif
+#ifdef PC98_EGC
+ /* Setup EGC Registers */
+ switch(data_rotate_value) {
+/* EGC MODE.. Cmp Read: Flase, WriteSource=ROP, ReadSource=CPU */
+ case VGA_AND_MODE:
+ if (invert_existing_data)
+ ROP_value = EGC_AND_INV_MODE;
+ else
+ ROP_value = EGC_AND_MODE;
+ break;
+ case VGA_OR_MODE:
+ if (invert_existing_data)
+ ROP_value = EGC_OR_INV_MODE;
+ else
+ ROP_value = EGC_OR_MODE;
+ break;
+ case VGA_XOR_MODE:
+ if (invert_existing_data)
+ ROP_value = EGC_XOR_INV_MODE;
+ else
+ ROP_value = EGC_XOR_MODE;
+ break;
+ case VGA_COPY_MODE:
+ default:
+ ROP_value = EGC_COPY_MODE;
+ break;
+ }
+ outw(EGC_PLANE, ~(planes & VGA_ALLPLANES));
+ outw(EGC_MODE, ROP_value);
+ outw(EGC_FGC, 0x0000);
+ tmp1 = 0;
+#else
+ /* Setup VGA Registers */
+ SetVideoSequencer( Mask_MapIndex, planes & VGA_ALLPLANES ) ;
+ /* Set Raster Op */
+ SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ;
+ SetVideoGraphics( Graphics_ModeIndex, VGA_WRITE_MODE_2 ) ;
+#endif
+}
+
+StartByte = SCREENADDRESS(pWin, x, y);
+InitialMask = SCRRIGHT8( LeftmostBit, BIT_OFFSET( x ) ) ;
+if ( invert_source_data )
+#ifdef PC98_EGC
+#if 0 /* New EGC version */
+ egc_image_invert ( StartByte, data, InitialMask, w, h,
+ RowIncrement ) ;
+#else /* new EGC c version */
+ for ( ;
+ h-- ;
+ data += RowIncrement, StartByte += BYTES_PER_LINE(pWin) ) {
+ dst = StartByte;
+ for ( src = data,
+ Pixel_Count = w, currMask = InitialMask ;
+ Pixel_Count-- ;
+ src++ ) {
+ if (tmp1 != (~*src & VGA_ALLPLANES)) {
+ tmp1 = ~*src & VGA_ALLPLANES;
+ /* set FGC */
+ outw(EGC_FGC, ~*src & VGA_ALLPLANES);
+ }
+ *((VgaMemoryPtr) dst) = currMask;
+ if ( currMask & RightmostBit ) {
+ currMask = LeftmostBit ;
+ dst++;
+ }
+ else
+ currMask = SCRRIGHT8( currMask, 1 ) ;
+ }
+ }
+#endif /* new EGC */
+#else /* original */
+ for ( ;
+ h-- ;
+ data += RowIncrement, StartByte += BYTES_PER_LINE(pWin) ) {
+ dst = StartByte;
+ for ( src = data,
+ Pixel_Count = w, currMask = InitialMask ;
+ Pixel_Count-- ;
+ src++ ) {
+ /* Set The Bit Mask Reg */
+ SetVideoGraphics( Bit_MaskIndex, currMask ) ;
+ /* Read To Load vga Data Latches */
+ tmp = *( (VgaMemoryPtr) dst ) ;
+ *( (VgaMemoryPtr) dst ) = ~ *src ;
+ if ( currMask & RightmostBit ) {
+ currMask = LeftmostBit ;
+ dst++;
+ }
+ else
+ currMask = SCRRIGHT8( currMask, 1 ) ;
+ }
+ }
+#endif
+else /* invert_source_data == FALSE */
+#ifdef PC98_EGC
+#if 0 /* new EGC version */
+ egc_image ( StartByte, data, InitialMask, w, h,
+ RowIncrement );
+#else /* new EGC c version */
+ for ( ;
+ h-- ;
+ data += RowIncrement, StartByte += BYTES_PER_LINE(pWin) ) {
+ dst = StartByte;
+ for ( src = data,
+ Pixel_Count = w, currMask = InitialMask ;
+ Pixel_Count-- ;
+ src++ ) {
+ if (tmp1 != *src & VGA_ALLPLANES) {
+ tmp1 = *src & VGA_ALLPLANES;
+ outw(EGC_FGC, tmp1); /* set FGC */
+ }
+ *((VgaMemoryPtr) dst) = currMask; /* write with mask */
+ if ( currMask & RightmostBit ) {
+ currMask = LeftmostBit ;
+ dst++;
+ }
+ else
+ currMask = SCRRIGHT8( currMask, 1 ) ;
+ }
+ }
+#endif /* new EGC version */
+#else /* original */
+ for ( ;
+ h-- ;
+ data += RowIncrement, StartByte += BYTES_PER_LINE(pWin) ) {
+ dst = StartByte;
+ for ( src = data,
+ Pixel_Count = w, currMask = InitialMask ;
+ Pixel_Count-- ;
+ src++ ) {
+ /* Set The Bit Mask Reg */
+ SetVideoGraphics( Bit_MaskIndex, currMask ) ; /* GJA */
+ /* Read To Load vga Data Latches */
+ tmp = *( (VgaMemoryPtr) dst ) ;
+ *( (VgaMemoryPtr) dst ) = *src ;
+ if ( currMask & RightmostBit ) {
+ currMask = LeftmostBit ;
+ dst++;
+ }
+ else
+ currMask = SCRRIGHT8( currMask, 1 ) ;
+ }
+ }
+#endif /* original */
+
+return ;
+}
+
+#ifndef PC98_EGC
+static unsigned long int
+read8Z
+(
+ register volatile unsigned char *screen_ptr
+)
+{
+register unsigned long int i ;
+register unsigned long int j ;
+
+/* Read One Byte At A Time to get
+ * i == [ Plane 3 ] [ Plane 2 ] [ Plane 1 ] [ Plane 0 ]
+ * into a single register
+ */
+SetVideoGraphicsData( 3 ) ;
+i = *( (VgaMemoryPtr) screen_ptr ) << 8 ;
+SetVideoGraphicsData( 2 ) ;
+i |= *( (VgaMemoryPtr) screen_ptr ) ;
+i <<= 8 ;
+SetVideoGraphicsData( 1 ) ;
+i |= *( (VgaMemoryPtr) screen_ptr ) ;
+i <<= 8 ;
+SetVideoGraphicsData( 0 ) ;
+i |= *( (VgaMemoryPtr) screen_ptr ) ;
+
+/* Push Bits To Get
+ * j == [Pixel 7][Pixel 6][Pixel 5][Pixel 4][Pixel 3][Pixel 2][Pixel 1][Pixel 0]
+ * into one register
+ */
+
+j = ( i & 0x1 ) << 4 ;
+j |= ( i >>= 1 ) & 0x1 ;
+j <<= 4 ;
+j |= ( i >>= 1 ) & 0x1 ;
+j <<= 4 ;
+j |= ( i >>= 1 ) & 0x1 ;
+j <<= 4 ;
+j |= ( i >>= 1 ) & 0x1 ;
+j <<= 4 ;
+j |= ( i >>= 1 ) & 0x1 ;
+j <<= 4 ;
+j |= ( i >>= 1 ) & 0x1 ;
+j <<= 4 ;
+j |= ( i >>= 1 ) & 0x1 ;
+
+j |= ( i & 0x2 ) << 28 ;
+j |= ( ( i >>= 1 ) & 0x2 ) << 24 ;
+j |= ( ( i >>= 1 ) & 0x2 ) << 20 ;
+j |= ( ( i >>= 1 ) & 0x2 ) << 16 ;
+j |= ( ( i >>= 1 ) & 0x2 ) << 12 ;
+j |= ( ( i >>= 1 ) & 0x2 ) << 8 ;
+j |= ( ( i >>= 1 ) & 0x2 ) << 4 ;
+j |= ( i >>= 1 ) & 0x2 ;
+
+j |= ( i & 0x4 ) << 28 ;
+j |= ( ( i >>= 1 ) & 0x4 ) << 24 ;
+j |= ( ( i >>= 1 ) & 0x4 ) << 20 ;
+j |= ( ( i >>= 1 ) & 0x4 ) << 16 ;
+j |= ( ( i >>= 1 ) & 0x4 ) << 12 ;
+j |= ( ( i >>= 1 ) & 0x4 ) << 8 ;
+j |= ( ( i >>= 1 ) & 0x4 ) << 4 ;
+j |= ( i >>= 1 ) & 0x4 ;
+
+j |= ( i & 0x8 ) << 28 ;
+j |= ( ( i >>= 1 ) & 0x8 ) << 24 ;
+j |= ( ( i >>= 1 ) & 0x8 ) << 20 ;
+j |= ( ( i >>= 1 ) & 0x8 ) << 16 ;
+j |= ( ( i >>= 1 ) & 0x8 ) << 12 ;
+j |= ( ( i >>= 1 ) & 0x8 ) << 8 ;
+j |= ( ( i >>= 1 ) & 0x8 ) << 4 ;
+j |= ( i >>= 1 ) & 0x8 ;
+
+return j ;
+}
+#endif /* not PC98_EGC */
+
+void
+xf4bppReadColorImage( pWin, x, y, lx, ly, data, RowIncrement )
+WindowPtr pWin; /* GJA */
+int x, y ;
+int lx, ly ;
+register unsigned char *data ;
+int RowIncrement ;
+{
+register unsigned long int tmp ;
+register volatile unsigned char *src ;
+volatile unsigned char *masterSrc ;
+int savCenterWidth ;
+int dx ;
+int skip ;
+int center_width ;
+int ignore ;
+int pad ;
+unsigned char tmpc;
+
+{ /* Start GJA */
+ if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) {
+ xf4bppOffReadColorImage( pWin, x, y, lx, ly, data, RowIncrement );
+ return;
+ }
+} /* End GJA */
+
+if ( ( lx <= 0 ) || ( ly <= 0 ) )
+ return ;
+
+/* Setup VGA Registers */
+#ifndef PC98_EGC
+SetVideoGraphicsIndex( Graphics_ModeIndex ) ;
+tmpc = inb( 0x3CF );
+SetVideoGraphicsData( tmpc & ~0x8 ) ; /* Clear the bit */
+SetVideoGraphicsIndex( Read_Map_SelectIndex ) ;
+#else
+outw(EGC_MODE, 0x0800);
+#endif
+
+skip = BIT_OFFSET( x ) ;
+pad = RowIncrement - lx ;
+ignore = BIT_OFFSET( x + lx ) ;
+masterSrc = SCREENADDRESS( pWin, x, y ) ;
+center_width = ROW_OFFSET( x + lx ) - ROW_OFFSET( ( x + 0x7 ) & ~0x7 ) ;
+
+#define SINGLE_STEP *data++ = tmp & VGA_ALLPLANES ; tmp >>= 4
+
+
+if ( center_width < 0 ) {
+ src = masterSrc;
+ for ( ; ly-- ; ) {
+ tmp = read8Z( src ) >> ( skip << 2 ) ;
+ for ( dx = lx + 1 ; --dx ; ) {
+ SINGLE_STEP ;
+ }
+ data += pad ;
+ src += BYTES_PER_LINE(pWin);
+ }
+} else
+ for ( savCenterWidth = center_width ;
+ ly-- ;
+ center_width = savCenterWidth,
+ masterSrc += BYTES_PER_LINE(pWin) ) {
+ src = masterSrc ;
+ tmp = read8Z( src ) ; src++;
+ if ((dx = skip))
+ tmp >>= ( dx << 2 ) ;
+ else
+ if ( lx < 8 ) { /* kludge -- GJA */
+ --center_width ; /* kludge -- GJA */
+ dx = 8 - lx ; /* kludge -- GJA */
+ } else /* kludge -- GJA */
+ --center_width ;
+ BranchPoint:
+ switch ( dx ) {
+ LoopTop:
+ case 0x0: SINGLE_STEP ;
+ case 0x1: SINGLE_STEP ;
+ case 0x2: SINGLE_STEP ;
+ case 0x3: SINGLE_STEP ;
+ case 0x4: SINGLE_STEP ;
+ case 0x5: SINGLE_STEP ;
+ case 0x6: SINGLE_STEP ;
+ case 0x7: *data++ = tmp & VGA_ALLPLANES ;
+
+ /* Fall Through To End Of Inner Loop */
+ if ( center_width > 0 ) {
+ tmp = read8Z( src ) ; src++;
+ center_width-- ;
+ goto LoopTop ;
+ }
+ else if ( ( center_width == 0 )
+ && ( dx = ( - ignore ) & 07 ) ) {
+ tmp = read8Z( src ) ; src++;
+ center_width-- ;
+ goto BranchPoint ; /* Do Mod 8 edge */
+ }
+ else /* End of this line */
+ data += pad ;
+ }
+ }
+
+return ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaReg.h b/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaReg.h
new file mode 100644
index 000000000..4aae4c59e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaReg.h
@@ -0,0 +1,134 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/vgaReg.h,v 1.3 1999/06/06 08:49:07 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+
+/* $XConsortium: vgaReg.h /main/4 1996/02/21 17:59:02 kaleb $ */
+
+#define SET_BYTE_REGISTER( ioport, value ) outb( ioport, value )
+#define SET_INDEX_REGISTER( ioport, value ) SET_BYTE_REGISTER( ioport, value )
+#define SET_DATA_REGISTER( ioport, value ) SET_BYTE_REGISTER( ioport, value )
+/* GJA -- deleted RTIO and ATRIO case here, so that a PCIO #define became
+ * superfluous.
+ */
+#define SET_INDEXED_REGISTER(RegGroup, Index, Value) \
+ (SET_BYTE_REGISTER(RegGroup, Index), \
+ SET_BYTE_REGISTER((RegGroup) + 1, Value))
+
+/* There is a jumper on the ega to change this to 0x200 instead !! */
+#define REGBASE 0x300
+
+#define AttributeIndexRegister REGBASE + 0xC0
+#define AttributeDataWriteRegister REGBASE + 0xC0
+#define AttributeDataReadRegister REGBASE + 0xC1
+#define AttributeRegister AttributeIndexRegister
+#define AttributeModeIndex 0x30
+#define OverScanColorIndex 0x31
+#define ColorPlaneEnableIndex 0x32
+#define HorizPelPanIndex 0x33
+#define ColorSelectIndex 0x34
+#ifndef PC98_EGC
+#define SetVideoAttributeIndex( index ) \
+ SET_INDEX_REGISTER( AttributeIndexRegister, index )
+#define SetVideoAttribute( index, value ) \
+ SetVideoAttributeIndex( index ) ; \
+ SET_BYTE_REGISTER( AttributeDataWriteRegister, value )
+#endif
+
+ /* Graphics Registers 03CE & 03CF */
+#define GraphicsIndexRegister REGBASE + 0xCE
+#define GraphicsDataRegister REGBASE + 0xCF
+#define GraphicsRegister GraphicsIndexRegister
+#define Set_ResetIndex 0x00
+#define Enb_Set_ResetIndex 0x01
+#define Color_CompareIndex 0x02
+#define Data_RotateIndex 0x03
+#define Read_Map_SelectIndex 0x04
+#define Graphics_ModeIndex 0x05
+#define MiscellaneousIndex 0x06
+#define Color_Dont_CareIndex 0x07
+#define Bit_MaskIndex 0x08
+#ifndef PC98_EGC
+#define SetVideoGraphicsIndex( index ) \
+ SET_INDEX_REGISTER( GraphicsIndexRegister, index )
+#define SetVideoGraphicsData( value ) \
+ SET_INDEX_REGISTER( GraphicsDataRegister, value )
+#define SetVideoGraphics( index, value ) \
+ SET_INDEXED_REGISTER( GraphicsRegister, index, value )
+#endif
+
+/* Sequencer Registers 03C4 & 03C5 */
+#define SequencerIndexRegister REGBASE + 0xC4
+#define SequencerDataRegister REGBASE + 0xC5
+#define SequencerRegister SequencerIndexRegister
+#define Seq_ResetIndex 00
+#define Clock_ModeIndex 01
+#define Mask_MapIndex 02
+#define Char_Map_SelectIndex 03
+#define Memory_ModeIndex 04
+#ifndef PC98_EGC
+#define SetVideoSequencerIndex( index ) \
+ SET_INDEX_REGISTER( SequencerIndexRegister, index )
+#define SetVideoSequencer( index, value ) \
+ SET_INDEXED_REGISTER( SequencerRegister, index, value )
+#endif
+
+/* BIT CONSTANTS FOR THE VGA/EGA HARDWARE */
+/* for the Graphics' Data_Rotate Register */
+#define VGA_ROTATE_FUNC_SHIFT 3
+#define VGA_COPY_MODE ( 0 << VGA_ROTATE_FUNC_SHIFT ) /* 0x00 */
+#define VGA_AND_MODE ( 1 << VGA_ROTATE_FUNC_SHIFT ) /* 0x08 */
+#define VGA_OR_MODE ( 2 << VGA_ROTATE_FUNC_SHIFT ) /* 0x10 */
+#define VGA_XOR_MODE ( 3 << VGA_ROTATE_FUNC_SHIFT ) /* 0x18 */
+/* for the Graphics' Graphics_Mode Register */
+#define VGA_READ_MODE_SHIFT 3
+#define VGA_WRITE_MODE_0 0
+#define VGA_WRITE_MODE_1 1
+#define VGA_WRITE_MODE_2 2
+#define VGA_WRITE_MODE_3 3
+#define VGA_READ_MODE_0 ( 0 << VGA_READ_MODE_SHIFT )
+#define VGA_READ_MODE_1 ( 1 << VGA_READ_MODE_SHIFT )
+
+#ifdef PC98_EGC
+/* I/O port address define for extended EGC */
+#define EGC_PLANE 0x4a0 /* EGC active plane select */
+#define EGC_READ 0x4a2 /* EGC FGC,EGC,Read Plane */
+#define EGC_MODE 0x4a4 /* EGC Mode register & ROP */
+#define EGC_FGC 0x4a6 /* EGC Forground color */
+#define EGC_MASK 0x4a8 /* EGC Mask register */
+#define EGC_BGC 0x4aa /* EGC Background color */
+#define EGC_ADD 0x4ac /* EGC Dest/Source address */
+#define EGC_LENGTH 0x4ae /* EGC Bit length */
+
+#define PALETTE_ADD 0xa8 /* Palette address */
+#define PALETTE_GRE 0xaa /* Palette Green */
+#define PALETTE_RED 0xac /* Palette Red */
+#define PALETTE_BLU 0xae /* Palette Blue */
+
+#define EGC_AND_MODE 0x2c8c /* (S&P&D)|(~S&D) */
+#define EGC_AND_INV_MODE 0x2c2c /* (S&P&~D)|(~S&D) */
+#define EGC_OR_MODE 0x2cec /* S&(P|D)|(~S&D) */
+#define EGC_OR_INV_MODE 0x2cbc /* S&(P|~D)|(~S&D) */
+#define EGC_XOR_MODE 0x2c6c /* (S&(P&~D|~P&D))|(~S&D) */
+#define EGC_XOR_INV_MODE 0x2c9c /* (S&(P&D)|(~P&~D))|(~S&D) */
+#define EGC_COPY_MODE 0x2cac /* (S&P)|(~S&D) */
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaSolid.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaSolid.c
new file mode 100644
index 000000000..142e85dce
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaSolid.c
@@ -0,0 +1,565 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/vgaSolid.c,v 1.3 1999/06/06 08:49:07 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+
+/* $XConsortium: vgaSolid.c /main/5 1996/02/21 17:59:06 kaleb $ */
+
+#include "xf4bpp.h"
+#include "OScompiler.h"
+#include "vgaReg.h"
+#include "vgaVideo.h"
+
+#include "xf86str.h" /* for pScrn->vtSema */
+extern ScrnInfoPtr *xf86Screens;
+
+#undef TRUE
+#undef FALSE
+#define TRUE 1
+#define FALSE 0
+
+#ifndef PC98_EGC
+#ifdef USE_ASM
+extern void fastFill();
+extern void fastFillRMW();
+#else
+
+static void fastFill
+(
+ register volatile unsigned char *destination,
+ register const unsigned int bytes_per_line,
+ register const unsigned int bytewidth, /* MUST BE > 0 !! */
+ register unsigned int height /* MUST BE > 0 !! */
+)
+{
+int stop_count = bytewidth ;
+register int row_jump = bytes_per_line - bytewidth ;
+#if !defined(OLDHC) && defined(BSDrt) && !defined(i386)
+register const unsigned int notZero = ((unsigned char)(~0x0));
+#else
+#define notZero ((unsigned char)(~0))
+#endif
+
+#define SINGLE_STORE \
+ ( *( (VgaMemoryPtr) destination ) = notZero ); \
+ destination++; stop_count--;
+
+/* TOP OF FIRST LOOP */
+BranchPoint:
+
+switch ( bytewidth & 0xF ) { /* Jump into loop at mod 16 remainder */
+ LoopTop :
+ case 0x0 : SINGLE_STORE ;
+ case 0xF : SINGLE_STORE ;
+ case 0xE : SINGLE_STORE ;
+ case 0xD : SINGLE_STORE ;
+ case 0xC : SINGLE_STORE ;
+ case 0xB : SINGLE_STORE ;
+ case 0xA : SINGLE_STORE ;
+ case 0x9 : SINGLE_STORE ;
+ case 0x8 : SINGLE_STORE ;
+ case 0x7 : SINGLE_STORE ;
+ case 0x6 : SINGLE_STORE ;
+ case 0x5 : SINGLE_STORE ;
+ case 0x4 : SINGLE_STORE ;
+ case 0x3 : SINGLE_STORE ;
+ case 0x2 : SINGLE_STORE ;
+ case 0x1 : SINGLE_STORE ;
+/* FIRST LOOP */
+ if ( stop_count )
+ goto LoopTop ;
+/* SECOND LOOP */
+ if ( --height ) {
+ destination += row_jump ;
+ stop_count = bytewidth ;
+ goto BranchPoint ;
+ }
+ else
+ return ;
+#undef SINGLE_STORE
+}
+/*NOTREACHED*/
+}
+
+/* For Read-Modify-Write Case */
+static void fastFillRMW
+(
+ register volatile unsigned char *destination,
+ register const unsigned int bytes_per_line,
+ register const unsigned int bytewidth, /* MUST BE > 0 !! */
+ register unsigned int height /* MUST BE > 0 !! */
+)
+{
+int stop_count = bytewidth ;
+register int row_jump = bytes_per_line - bytewidth ;
+#if !defined(OLDHC) && defined(BSDrt) && !defined(i386)
+register const unsigned int notZero = ((unsigned char)(~0x0));
+#endif
+register int tmp ;
+
+#define SINGLE_STORE \
+ tmp = *( (VgaMemoryPtr) destination ) ; \
+ ( *( (VgaMemoryPtr) destination ) = notZero ) ; \
+ destination++; stop_count-- ;
+
+/* TOP OF FIRST LOOP */
+BranchPoint:
+
+switch ( bytewidth & 0xF ) { /* Jump into loop at mod 16 remainder */
+ LoopTop :
+ case 0x0 : SINGLE_STORE ;
+ case 0xF : SINGLE_STORE ;
+ case 0xE : SINGLE_STORE ;
+ case 0xD : SINGLE_STORE ;
+ case 0xC : SINGLE_STORE ;
+ case 0xB : SINGLE_STORE ;
+ case 0xA : SINGLE_STORE ;
+ case 0x9 : SINGLE_STORE ;
+ case 0x8 : SINGLE_STORE ;
+ case 0x7 : SINGLE_STORE ;
+ case 0x6 : SINGLE_STORE ;
+ case 0x5 : SINGLE_STORE ;
+ case 0x4 : SINGLE_STORE ;
+ case 0x3 : SINGLE_STORE ;
+ case 0x2 : SINGLE_STORE ;
+ case 0x1 : SINGLE_STORE ;
+/* FIRST LOOP */
+ if ( stop_count )
+ goto LoopTop ;
+/* SECOND LOOP */
+ if ( --height ) {
+ destination += row_jump ;
+ stop_count = bytewidth ;
+ goto BranchPoint ;
+ }
+ else
+ return ;
+}
+#undef SINGLE_STORE
+/*NOTREACHED*/
+}
+#endif
+
+
+void xf4bppFillSolid( pWin, color, alu, planes, x0, y0, lx, ly )
+WindowPtr pWin; /* GJA */
+unsigned long int color ;
+const int alu ;
+unsigned long int planes ;
+register int x0 ;
+register const int y0 ;
+register int lx ;
+register const int ly ; /* MUST BE > 0 !! */
+{
+register volatile unsigned char *dst ;
+register tmp ;
+register tmp2 ;
+register tmp3 ;
+unsigned int data_rotate_value = VGA_COPY_MODE ;
+unsigned int read_write_modify = FALSE ;
+unsigned int invert_existing_data = FALSE ;
+
+{ /* Start GJA */
+ if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) {
+ xf4bppOffFillSolid( pWin, color, alu, planes, x0, y0, lx, ly );
+ return;
+ }
+} /* End GJA */
+
+if ( ( lx == 0 ) || ( ly == 0 ) )
+ return;
+
+switch ( alu ) {
+ case GXclear: /* 0x0 Zero 0 */
+ color = 0 ;
+ break ;
+ case GXnor: /* 0x8 NOT src AND NOT dst */
+ invert_existing_data = TRUE ;
+ case GXandInverted: /* 0x4 NOT src AND dst */
+ color = ~color ;
+ case GXand: /* 0x1 src AND dst */
+ data_rotate_value = VGA_AND_MODE ;
+ read_write_modify = TRUE ;
+ case GXcopy: /* 0x3 src */
+ break ;
+ case GXnoop: /* 0x5 dst */
+ return ;
+ case GXequiv: /* 0x9 NOT src XOR dst */
+ color = ~color ;
+ case GXxor: /* 0x6 src XOR dst */
+ data_rotate_value = VGA_XOR_MODE ;
+ read_write_modify = TRUE ;
+ planes &= color ;
+ break ;
+ case GXandReverse: /* 0x2 src AND NOT dst */
+ invert_existing_data = TRUE ;
+ data_rotate_value = VGA_AND_MODE ;
+ read_write_modify = TRUE ;
+ break ;
+ case GXorReverse: /* 0xb src OR NOT dst */
+ invert_existing_data = TRUE ;
+ data_rotate_value = VGA_OR_MODE ;
+ read_write_modify = TRUE ;
+ break ;
+ case GXnand: /* 0xe NOT src OR NOT dst */
+ invert_existing_data = TRUE ;
+ case GXorInverted: /* 0xd NOT src OR dst */
+ color = ~color ;
+ case GXor: /* 0x7 src OR dst */
+ data_rotate_value = VGA_OR_MODE ;
+ read_write_modify = TRUE ;
+ break ;
+ case GXcopyInverted: /* 0xc NOT src */
+ color = ~color ;
+ break ;
+ case GXinvert: /* 0xa NOT dst */
+ data_rotate_value = VGA_XOR_MODE ;
+ read_write_modify = TRUE ;
+ case GXset: /* 0xf 1 */
+ color = VGA_ALLPLANES ;
+ default:
+ break ;
+}
+
+if ( !( planes &= VGA_ALLPLANES ) )
+ return ;
+
+/*
+ * Set The Plane-Enable
+ */
+SetVideoSequencer( Mask_MapIndex, planes ) ;
+SetVideoGraphics( Enb_Set_ResetIndex, planes ) ;
+/*
+ * Put Display Into SET/RESET Write Mode
+ */
+SetVideoGraphics( Graphics_ModeIndex, VGA_WRITE_MODE_3 ) ;
+/*
+ * Set The Color in The Set/Reset Register
+ */
+SetVideoGraphics( Set_ResetIndex, color & VGA_ALLPLANES ) ;
+/*
+ * Set The Function-Select In The Data Rotate Register
+ */
+SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ;
+
+/* Do Left Edge */
+if ((tmp = x0 & 07)) {
+ tmp2 = SCRRIGHT8( ( (unsigned) 0xFF ), tmp ) ;
+ /* Catch The Cases Where The Entire Region Is Within One Byte */
+ if ( ( lx -= 8 - tmp ) < 0 ) {
+ tmp2 &= SCRLEFT8( 0xFF, -lx ) ;
+ lx = 0 ;
+ }
+ /* Set The Bit Mask Reg */
+ SetVideoGraphics(Bit_MaskIndex, tmp2 ) ;
+ if ( invert_existing_data == TRUE ) {
+ SetVideoGraphics( Set_ResetIndex, VGA_ALLPLANES ) ;
+ SetVideoGraphics( Data_RotateIndex, VGA_XOR_MODE ) ;
+ dst = SCREENADDRESS( pWin, x0, y0 );
+ for ( tmp = ly;
+ tmp-- ; ) {
+ tmp3 = *( (VgaMemoryPtr) dst ) ;
+ *( (VgaMemoryPtr) dst ) = tmp2 ;
+ dst += BYTES_PER_LINE(pWin);
+ }
+ SetVideoGraphics( Set_ResetIndex, color & VGA_ALLPLANES ) ;
+ SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ;
+ /* Un-Set XOR */
+ }
+ dst = SCREENADDRESS( pWin, x0, y0 );
+ for ( tmp = ly;
+ tmp-- ; ) {
+ tmp3 = *( (VgaMemoryPtr) dst ) ;
+ *( (VgaMemoryPtr) dst ) = tmp2 ;
+ dst += BYTES_PER_LINE(pWin);
+ }
+ if ( !lx ) { /* All Handled In This Byte */
+ return ;
+ }
+ x0 = ( x0 + 8 ) & ~07 ;
+}
+
+/* Fill The Center Of The Box */
+if ( ROW_OFFSET( lx ) ) {
+ SetVideoGraphics(Bit_MaskIndex, 0xFF ) ;
+ if ( invert_existing_data == TRUE ) {
+ SetVideoGraphics( Set_ResetIndex, VGA_ALLPLANES ) ;
+ SetVideoGraphics( Data_RotateIndex, VGA_XOR_MODE ) ;
+ fastFillRMW( SCREENADDRESS( pWin, x0, y0 ),
+ BYTES_PER_LINE(pWin),
+ ROW_OFFSET( lx ), ly ) ;
+ SetVideoGraphics( Set_ResetIndex, color & VGA_ALLPLANES ) ;
+ SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ;
+ /* Un-Set XOR */
+ /* Point At The Bit Mask Reg */
+ }
+ (* ( ( read_write_modify == FALSE ) ? fastFill : fastFillRMW ) )
+ ( SCREENADDRESS( pWin, x0, y0 ), BYTES_PER_LINE(pWin),
+ ROW_OFFSET( lx ), ly ) ;
+}
+
+/* Do Right Edge */
+if ((tmp = BIT_OFFSET(lx))) { /* x0 Now Is Byte Aligned */
+ /* Set The Bit Mask */
+ SetVideoGraphics( Bit_MaskIndex,
+ (tmp2 = SCRLEFT8( 0xFF, ( 8 - tmp ) ) ) ) ;
+ if ( invert_existing_data == TRUE ) {
+ SetVideoGraphics( Set_ResetIndex, VGA_ALLPLANES ) ;
+ SetVideoGraphics( Data_RotateIndex, VGA_XOR_MODE ) ;
+ dst = SCREENADDRESS( pWin, ( x0 + lx ), y0 );
+ for ( tmp = ly;
+ tmp-- ; ) {
+ tmp3 = *( (VgaMemoryPtr) dst ) ;
+ *( (VgaMemoryPtr) dst ) = tmp2 ;
+ dst += BYTES_PER_LINE(pWin);
+ }
+ SetVideoGraphics( Set_ResetIndex, color & VGA_ALLPLANES ) ;
+ SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ;
+ /* Un-Set XOR */
+ }
+ dst = SCREENADDRESS( pWin, ( x0 + lx ), y0 );
+ for ( tmp = ly;
+ tmp-- ; ) {
+ tmp3 = *( (VgaMemoryPtr) dst ) ;
+ *( (VgaMemoryPtr) dst ) = tmp2 ;
+ dst += BYTES_PER_LINE(pWin) ;
+ }
+}
+/* Disable Set/Reset Register */
+SetVideoGraphics( Enb_Set_ResetIndex, 0 ) ;
+
+
+return ;
+}
+
+#else /* for PC98 EGC */
+static void WordfastFill( destination, bytes_per_line, wordwidth, height )
+register volatile unsigned char *destination ;
+register const unsigned int bytes_per_line ;
+register const unsigned int wordwidth ; /* MUST BE > 0 !! */
+register unsigned int height ; /* MUST BE > 0 !! */
+{
+int stop_count = wordwidth ;
+register int row_jump = bytes_per_line - wordwidth*2 ;
+#if !defined(OLDHC) && defined(BSDrt) && !defined(i386) && 0
+register const int notZero = ~0x0 ;
+#else
+#define notZero ( ~0 )
+#endif
+
+#define SINGLE_STORE \
+ ( *( (unsigned short *) destination++ ) = notZero ); \
+ destination++; stop_count--;
+
+/* TOP OF FIRST LOOP */
+BranchPoint:
+
+switch ( wordwidth & 0xF ) { /* Jump into loop at mod 16 remainder */
+ LoopTop :
+ case 0x0 : SINGLE_STORE ;
+ case 0xF : SINGLE_STORE ;
+ case 0xE : SINGLE_STORE ;
+ case 0xD : SINGLE_STORE ;
+ case 0xC : SINGLE_STORE ;
+ case 0xB : SINGLE_STORE ;
+ case 0xA : SINGLE_STORE ;
+ case 0x9 : SINGLE_STORE ;
+ case 0x8 : SINGLE_STORE ;
+ case 0x7 : SINGLE_STORE ;
+ case 0x6 : SINGLE_STORE ;
+ case 0x5 : SINGLE_STORE ;
+ case 0x4 : SINGLE_STORE ;
+ case 0x3 : SINGLE_STORE ;
+ case 0x2 : SINGLE_STORE ;
+ case 0x1 : SINGLE_STORE ;
+/* FIRST LOOP */
+ if ( stop_count )
+ goto LoopTop ;
+/* SECOND LOOP */
+ if ( --height ) {
+ destination += row_jump ;
+ stop_count = wordwidth ;
+ goto BranchPoint ;
+ }
+ else
+ return ;
+#undef SINGLE_STORE
+}
+/*NOTREACHED*/
+}
+
+void xf4bppFillSolid( pWin, color, alu, planes, x0, y0, lx, ly )
+WindowPtr pWin; /* GJA */
+unsigned long int color ;
+const int alu ;
+unsigned long int planes ;
+register int x0 ;
+register const int y0 ;
+register int lx ;
+register const int ly ; /* MUST BE > 0 !! */
+{
+register volatile unsigned char *dst ;
+register tmp ;
+register tmp2 ;
+register unsigned short tmp3 ;
+unsigned short ROP_value;
+unsigned int data_rotate_value = VGA_COPY_MODE ;
+unsigned int read_write_modify = FALSE ;
+unsigned int invert_existing_data = FALSE ;
+
+{ /* Start GJA */
+ if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) {
+ xf4bppOffFillSolid( pWin, color, alu, planes, x0, y0, lx, ly );
+ return;
+ }
+} /* End GJA */
+
+if ( ( lx == 0 ) || ( ly == 0 ) )
+ return;
+
+switch ( alu ) {
+ case GXclear: /* 0x0 Zero 0 */
+ color = 0 ;
+ break ;
+ case GXnor: /* 0x8 NOT src AND NOT dst */
+ invert_existing_data = TRUE ;
+ case GXandInverted: /* 0x4 NOT src AND dst */
+ color = ~color ;
+ case GXand: /* 0x1 src AND dst */
+ data_rotate_value = VGA_AND_MODE ;
+ read_write_modify = TRUE ;
+ case GXcopy: /* 0x3 src */
+ break ;
+ case GXnoop: /* 0x5 dst */
+ return ;
+ case GXequiv: /* 0x9 NOT src XOR dst */
+ color = ~color ;
+ case GXxor: /* 0x6 src XOR dst */
+ data_rotate_value = VGA_XOR_MODE ;
+ read_write_modify = TRUE ;
+ planes &= color ;
+ break ;
+ case GXandReverse: /* 0x2 src AND NOT dst */
+ invert_existing_data = TRUE ;
+ data_rotate_value = VGA_AND_MODE ;
+ read_write_modify = TRUE ;
+ break ;
+ case GXorReverse: /* 0xb src OR NOT dst */
+ invert_existing_data = TRUE ;
+ data_rotate_value = VGA_OR_MODE ;
+ read_write_modify = TRUE ;
+ break ;
+ case GXnand: /* 0xe NOT src OR NOT dst */
+ invert_existing_data = TRUE ;
+ case GXorInverted: /* 0xd NOT src OR dst */
+ color = ~color ;
+ case GXor: /* 0x7 src OR dst */
+ data_rotate_value = VGA_OR_MODE ;
+ read_write_modify = TRUE ;
+ break ;
+ case GXcopyInverted: /* 0xc NOT src */
+ color = ~color ;
+ break ;
+ case GXinvert: /* 0xa NOT dst */
+ data_rotate_value = VGA_XOR_MODE ;
+ read_write_modify = TRUE ;
+ case GXset: /* 0xf 1 */
+ color = VGA_ALLPLANES ;
+ default:
+ break ;
+}
+
+if ( !( planes &= VGA_ALLPLANES ) )
+ return ;
+
+/* Set Access Planes */
+outw(EGC_PLANE, ~planes);
+switch(data_rotate_value) {
+/* EGC MODE.. Cmp Read: Flase, WriteSource=ROP, ReadSource=CPU */
+ case VGA_AND_MODE:
+ if (invert_existing_data)
+ ROP_value = EGC_AND_INV_MODE;
+ else
+ ROP_value = EGC_AND_MODE;
+ break;
+ case VGA_OR_MODE:
+ if (invert_existing_data)
+ ROP_value = EGC_OR_INV_MODE;
+ else
+ ROP_value = EGC_OR_MODE;
+ break;
+ case VGA_XOR_MODE:
+ if (invert_existing_data)
+ ROP_value = EGC_XOR_INV_MODE;
+ else
+ ROP_value = EGC_XOR_MODE;
+ break;
+ case VGA_COPY_MODE:
+ default:
+ ROP_value = EGC_COPY_MODE;
+ break;
+}
+outw(EGC_MODE, ROP_value);
+outw(EGC_FGC, color & VGA_ALLPLANES);
+/* Do Left Edge */
+if ( tmp = x0 & 0x0f ) {
+ dst = (unsigned char *)((int)(SCREENADDRESS(pWin,x0,y0)) & ~0x01);
+ tmp3 = (unsigned)0xffff >>tmp;
+ /* Catch The Cases Where The Entire Region Is Within One Word */
+ if ( ( lx -= 16 - tmp ) < 0 ) {
+ tmp3 &= (unsigned)0xffff << -lx;
+ lx = 0 ;
+ }
+ tmp3 = (unsigned short)(tmp3 >> 8 | tmp3 << 8);
+ for ( tmp = ly;
+ tmp-- ; ) {
+ *((unsigned short *) dst ) = tmp3 ;
+ dst += BYTES_PER_LINE(pWin);
+ }
+ if ( !lx ) { /* All Handled In This Word */
+ return ;
+ }
+ x0 = ( x0 + 0x0f ) & ~0x0f ;
+}
+
+/* Fill The Center Of The Box */
+if (lx >> 4) {
+ WordfastFill( SCREENADDRESS( pWin, x0, y0 ), BYTES_PER_LINE(pWin),
+ (lx >> 4), ly ) ;
+}
+
+/* Do Right Edge */
+if ( tmp = lx & 0x0f ) { /* x0 Now Is Word Aligned */
+ /* Set The Bit Mask */
+ tmp3 = (unsigned)0xffff << ( 16 - tmp );
+ dst = (unsigned char*)((int)SCREENADDRESS(pWin,(x0+lx),y0) & ~0x01);
+ tmp3 = (unsigned short)(tmp3 >> 8 | tmp3 << 8);
+ for ( tmp = ly;
+ tmp-- ; ) {
+ *( (unsigned short *) dst ) = tmp3 ;
+ dst += BYTES_PER_LINE(pWin);
+ }
+}
+
+return ;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaStipple.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaStipple.c
new file mode 100644
index 000000000..5ddc52228
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaStipple.c
@@ -0,0 +1,708 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/vgaStipple.c,v 1.3 1999/06/06 08:49:07 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+/* $XConsortium: vgaStipple.c /main/5 1996/02/21 17:59:10 kaleb $ */
+
+#include "xf4bpp.h"
+#include "OScompiler.h"
+#include "vgaReg.h"
+#include "vgaVideo.h"
+
+#include "xf86str.h" /* for pScrn->vtSema */
+extern ScrnInfoPtr *xf86Screens;
+
+#ifndef PC98_EGC
+static unsigned char
+getbits
+(
+ register const int x,
+ register const unsigned int patternWidth,
+ register const unsigned char * const lineptr
+)
+{
+register unsigned char bits ;
+register const unsigned char *cptr ;
+register shift ;
+register wrap ;
+
+cptr = lineptr + ( x >> 3 ) ;
+bits = *cptr ;
+if ((shift = x & 7))
+ bits = SCRLEFT8( bits, shift ) | SCRRIGHT8( cptr[1], ( 8 - shift ) ) ;
+if ( ( wrap = x + 8 - patternWidth ) > 0 ) {
+ bits &= SCRLEFT8( 0xFF, wrap ) ;
+ bits |= SCRRIGHT8( *lineptr, ( 8 - wrap ) ) ;
+}
+
+/* GJA -- Handle extraction of 8 bits from < 8 bits wide stipple.
+ * I duplicated case 4,5,6,7 to give the compiler a chance to optimize.
+ */
+switch (patternWidth) {
+case 1: /* Not really useful. */
+ bits &= ~SCRRIGHT8(0xFF,1);
+ bits |= SCRRIGHT8(bits,1);
+ bits |= SCRRIGHT8(bits,2);
+ bits |= SCRRIGHT8(bits,4);
+ break;
+case 2:
+ bits &= ~SCRRIGHT8(0xFF,2);
+ bits |= SCRRIGHT8(bits,2); bits |= SCRRIGHT8(bits,4); break;
+case 3:
+ bits &= ~SCRRIGHT8(0xFF,3);
+ bits |= (SCRRIGHT8(bits,3) | SCRRIGHT8(bits,6)); break;
+case 4:
+ bits = (bits & ~SCRRIGHT8(0xFF,4)) | SCRRIGHT8(bits,4); break;
+case 5:
+ bits = (bits & ~SCRRIGHT8(0xFF,5)) | SCRRIGHT8(bits,5); break;
+case 6:
+ bits = (bits & ~SCRRIGHT8(0xFF,6)) | SCRRIGHT8(bits,6); break;
+case 7:
+ bits = (bits & ~SCRRIGHT8(0xFF,7)) | SCRRIGHT8(bits,7); break;
+default:
+ ;
+ /* Do nothing, of course */
+}
+return bits ;
+}
+#endif
+
+/* GJA --
+ * Basically, in the code below, we will draw a stipple in the usual
+ * three parts: left edge, center and right edge.
+ * For efficiency reasons, the center will be drawn byte aligned, so that
+ * we will have to shuffle the bits in the left and right edges.
+ * The hard cases will be stipples with width < 8: In order to get 8
+ * bits from those, we will need a loop. One single 'if' will never do.
+ * This is taken care of above.
+ */
+static void
+DoMonoSingle
+(
+ WindowPtr pWin, /* GJA */
+ int w,
+ int x,
+ int y,
+ register const unsigned char *mastersrc,
+ int h,
+ register unsigned int width,
+ register unsigned int paddedByteWidth,
+ unsigned int height,
+ int xshift,
+ int yshift
+)
+{
+register volatile unsigned char *xDst ;
+register VideoAdapterObject tmp2 ;
+register int NeedValX ;
+register int counter ;
+register int tmp1 ;
+unsigned int rowCounter ;
+int byte_cnt ;
+#ifdef PC98_EGC
+unsigned char bitmask;
+#endif
+
+/* Do Left Edge */
+if ((tmp1 = x & 07)) {
+ tmp2 = SCRRIGHT8( ( (unsigned) 0xFF ), tmp1 ) ;
+ /* Catch The Cases Where The Entire Region Is Within One Byte */
+ if ( ( w -= 8 - tmp1 ) < 0 ) {
+ tmp2 &= SCRLEFT8( (unsigned) 0xFF, -w ) ;
+ w = 0 ;
+ }
+#ifndef PC98_EGC
+ SetVideoGraphics( Bit_MaskIndex, tmp2 ) ; /* Set The Bit Mask */
+#else
+ bitmask = tmp2; /* Set The Bit Mask */
+#endif
+ /*
+ * For Each Line In The Source Pixmap
+ */
+ xDst = SCREENADDRESS( pWin, x, y );
+ for ( tmp1 = yshift, rowCounter = h;
+ rowCounter ;
+ rowCounter-- , tmp1++ ) {
+
+ if ( tmp1 >= (int)height )
+ tmp1 -= height ;
+#ifndef PC98_EGC
+ /* Read To Save */
+ tmp2 = *( (VgaMemoryPtr) xDst) ;
+#endif
+ /* Write Pattern */
+ *( (VgaMemoryPtr) xDst ) =
+#ifndef PC98_EGC
+ getbits( xshift /* GJA */, width,
+ mastersrc
+ + ( tmp1 * paddedByteWidth ) ) >> (x & 07) ;
+#else
+#if 0
+ (getbits( xshift /* GJA */, width,
+ mastersrc
+ + ( tmp1 * paddedByteWidth ) ) >> (x & 07)
+ & bitmask);
+#else
+ (getbits_x( xshift /* GJA */, width,
+ mastersrc
+ + ( tmp1 * paddedByteWidth ), (x & 07))
+ & bitmask);
+#endif
+#endif
+ xDst += BYTES_PER_LINE(pWin);
+ }
+ NeedValX = (xshift + 8 - (x & 07)) % width;
+ x = ( x + 7 ) & ~07 ;
+}
+else {
+ NeedValX = xshift ;
+}
+
+if ((byte_cnt = ROW_OFFSET(w))) { /* Fill The Center Of The Box */
+ int SavNeedX = NeedValX ;
+
+#ifndef PC98_EGC
+ SetVideoGraphics( Bit_MaskIndex, 0xFF ) ; /* Set The Bit Mask */
+#endif
+ /*
+ * For Each Line In The Source Pixmap
+ */
+ xDst = SCREENADDRESS( pWin, x, y );
+ for ( tmp1 = yshift, rowCounter = h;
+ rowCounter ;
+ rowCounter-- , tmp1++ ) {
+ register const unsigned char *l_ptr ;
+ if ( tmp1 >= (int)height )
+ tmp1 -= height ;
+ l_ptr = mastersrc + ( tmp1 * paddedByteWidth ) ;
+ /*
+ * For Each Byte Across The Pattern In X
+ */
+ for ( counter = byte_cnt, NeedValX = SavNeedX ;
+ counter-- ; ) {
+#ifndef PC98_EGC
+ /* Read To Save */
+ tmp2 = *( (VgaMemoryPtr) xDst) ;
+#endif
+ /* Write Pattern */
+ *( (VgaMemoryPtr) xDst ) =
+#ifndef PC98_EGC
+ getbits( NeedValX, width, l_ptr ) ;
+#else
+#if 0
+ getbits( NeedValX, width, l_ptr ) ;
+#else
+ getbits_x ( NeedValX, width, l_ptr, 0 ) ;
+#endif
+#endif
+ /* GJA -- The '%' is there since width could be < 8 */
+ NeedValX = (NeedValX + 8) % width;
+ xDst++;
+ }
+ xDst += BYTES_PER_LINE(pWin) - byte_cnt;
+ }
+}
+
+/* Do Right Edge */
+if ((tmp1 = BIT_OFFSET(w))) { /* x Now Is Byte Aligned */
+ /* Set The Bit Mask */
+#ifndef PC98_EGC
+ SetVideoGraphics( Bit_MaskIndex, SCRLEFT8( 0xFF, ( 8 - tmp1 ) ) ) ;
+#else
+ bitmask = SCRLEFT8( 0xFF, ( 8 - tmp1 ));
+#endif
+ /*
+ * For Each Line In The Source Pixmap
+ */
+ xDst = SCREENADDRESS( pWin, ( x + w ), y );
+ for ( tmp1 = yshift, rowCounter = h;
+ rowCounter ;
+ rowCounter-- , tmp1++ ) {
+ if ( tmp1 >= (int)height )
+ tmp1 -= height ;
+#ifndef PC98_EGC
+ /* Read To Save */
+ tmp2 = *( (VgaMemoryPtr) xDst) ;
+#endif
+ /* Write Pattern */
+ *( (VgaMemoryPtr) xDst ) =
+#ifndef PC98_EGC
+ getbits( NeedValX, width,
+ mastersrc
+ + ( tmp1 * paddedByteWidth ) ) ;
+#else
+#if 0
+ (getbits( NeedValX, width,
+ mastersrc
+ + ( tmp1 * paddedByteWidth ) ) & bitmask);
+#else
+ (getbits_x( NeedValX, width,
+ mastersrc
+ + ( tmp1 * paddedByteWidth ), 0 ) & bitmask);
+#endif
+#endif
+ xDst += BYTES_PER_LINE(pWin) ;
+ }
+}
+
+return ;
+}
+
+static void
+DoMonoMany
+(
+ WindowPtr pWin, /* GJA */
+ int w,
+ int x,
+ int y,
+ register const unsigned char *mastersrc,
+ int h,
+ register unsigned int width,
+ register unsigned int paddedByteWidth,
+ unsigned int height,
+ int xshift,
+ int yshift
+)
+{
+register volatile unsigned char *xDst ;
+register VideoAdapterObject tmp2 ;
+register int NeedValX ;
+register int byte_cnt ;
+register int tmp1 ;
+unsigned DestinationRow ;
+unsigned int SourceRow ;
+volatile unsigned char *dst ;
+int scr_incr = ( height * BYTES_PER_LINE(pWin) ) ;
+#ifdef PC98_EGC
+unsigned char bitmask;
+#endif
+
+/* Do Left Edge */
+if ((tmp1 = x & 07)) {
+ tmp2 = SCRRIGHT8( ( (unsigned) 0xFF ), tmp1 ) ;
+ /* Catch The Cases Where The Entire Region Is Within One Byte */
+ if ( ( w -= 8 - tmp1 ) < 0 ) {
+ tmp2 &= SCRLEFT8( (unsigned) 0xFF, -w ) ;
+ w = 0 ;
+ }
+#ifndef PC98_EGC
+ SetVideoGraphics( Bit_MaskIndex, tmp2 ) ; /* Set The Bit Mask */
+#else
+ bitmask = tmp2; /* Set The Bit Mask */
+#endif
+ /*
+ * For Each Line In The Source Pixmap
+ */
+ for ( tmp1 = yshift, SourceRow = 0, dst = SCREENADDRESS( pWin, x, y ) ;
+ SourceRow < height ;
+ tmp1++, SourceRow++, dst += BYTES_PER_LINE(pWin) ) {
+ register unsigned bitPattern ;
+
+ if ( tmp1 >= (int)height )
+ tmp1 -= height ;
+ /*
+ * For Each Time Pattern Repeats In The Y Dimension
+ */
+ xDst = dst;
+ for ( DestinationRow = SourceRow,
+#ifndef PC98_EGC
+ bitPattern = getbits( xshift, width,
+ mastersrc
+ + ( tmp1 * paddedByteWidth ) ) ;
+#else
+#if 0
+ bitPattern = getbits( xshift, width,
+ mastersrc
+ + ( tmp1 * paddedByteWidth ) ) ;
+#else
+ bitPattern = getbits_x( xshift, width,
+ mastersrc
+ + ( tmp1 * paddedByteWidth ), 0 ) ;
+#endif
+#endif
+ (int)DestinationRow < h ;
+ DestinationRow += height ) {
+#ifndef PC98_EGC
+ /* Read To Save */
+ tmp2 = *( (VgaMemoryPtr) xDst ) ;
+#endif
+ /* Write Pattern */
+#ifndef PC98_EGC
+ *( (VgaMemoryPtr) xDst ) = bitPattern >> (x & 07);
+#else
+ *( (VgaMemoryPtr) xDst ) = (bitPattern >> (x & 07)) & bitmask;
+#endif
+ xDst += scr_incr;
+ }
+ }
+ NeedValX = (xshift + 8 - (x & 07)) % width;
+ x = ( x + 7 ) & ~07 ;
+}
+else {
+ NeedValX = xshift ;
+}
+
+if ((byte_cnt = ROW_OFFSET(w))) { /* Fill The Center Of The Box */
+ int SavNeedX = NeedValX ;
+
+#ifndef PC98_EGC
+ SetVideoGraphics( Bit_MaskIndex, 0xFF ) ; /* Set The Bit Mask */
+#endif
+ /*
+ * For Each Line In The Source Pixmap
+ */
+ for ( tmp1 = yshift, SourceRow = 0, dst = SCREENADDRESS( pWin, x, y ) ;
+ SourceRow < height ;
+ tmp1++, SourceRow++, dst += BYTES_PER_LINE(pWin) - byte_cnt ) {
+ register const unsigned char *l_ptr ;
+ if ( tmp1 >= (int)height )
+ tmp1 -= height ;
+ l_ptr = mastersrc + ( tmp1 * paddedByteWidth ) ;
+ /*
+ * For Each Byte Across The Pattern In X
+ */
+ for ( tmp2 = byte_cnt, NeedValX = SavNeedX ;
+ tmp2-- ;
+ dst++ ) {
+ register unsigned bitPattern ;
+ register VideoAdapterObject tmp3 ;
+ /*
+ * For Each Time Pattern Repeats In Y
+ */
+ xDst = dst;
+ for ( DestinationRow = SourceRow,
+#ifndef PC98_EGC
+ bitPattern = getbits( NeedValX, width, l_ptr ) ;
+#else
+#if 0
+ bitPattern = getbits( NeedValX, width, l_ptr ) ;
+#else
+ bitPattern = getbits_x( NeedValX, width, l_ptr, 0 ) ;
+#endif
+#endif
+ (int)DestinationRow < h ;
+ DestinationRow += height ) {
+#ifndef PC98_EGC
+ /* Read To Save */
+ tmp3 = *( (VgaMemoryPtr) xDst) ;
+#endif
+ /* Write Pattern */
+ *( (VgaMemoryPtr) xDst ) = bitPattern ;
+ xDst += scr_incr;
+ }
+ NeedValX = (NeedValX + 8) % width;
+ }
+ }
+}
+
+/* Do Right Edge */
+if ((tmp1 = BIT_OFFSET(w))) { /* x Now Is Byte Aligned */
+ /* Set The Bit Mask */
+#ifndef PC98_EGC
+ SetVideoGraphics( Bit_MaskIndex, SCRLEFT8( 0xFF, ( 8 - tmp1 ) ) ) ;
+#else
+ bitmask = SCRLEFT8( 0xFF, ( 8 - tmp1 ) );
+#endif
+ /*
+ * For Each Line In The Source Pixmap
+ */
+ for ( tmp1 = yshift, SourceRow = 0,
+ dst = SCREENADDRESS( pWin, ( x + w ), y ) ;
+ SourceRow < height ;
+ tmp1++, SourceRow++, dst += BYTES_PER_LINE(pWin) ) {
+ register unsigned bitPattern ;
+ if ( tmp1 >= (int)height )
+ tmp1 -= height ;
+ /*
+ * For Each Time Pattern Repeats In The Y Dimension
+ */
+ xDst = dst;
+ for ( DestinationRow = SourceRow,
+#ifndef PC98_EGC
+ bitPattern = getbits( NeedValX, width,
+ mastersrc
+ + ( tmp1 * paddedByteWidth ) ) ;
+#else
+#if 0
+ bitPattern = getbits( NeedValX, width,
+ mastersrc
+ + ( tmp1 * paddedByteWidth ) ) ;
+#else
+ bitPattern = getbits_x( NeedValX, width,
+ mastersrc
+ + ( tmp1 * paddedByteWidth ), 0 ) ;
+#endif
+#endif
+ (int)DestinationRow < h ;
+ DestinationRow += height ) {
+#ifndef PC98_EGC
+ /* Read To Save */
+ tmp2 = *( (VgaMemoryPtr) xDst) ;
+#endif
+ /* Write Pattern */
+#ifndef PC98_EGC
+ *( (VgaMemoryPtr) xDst ) = bitPattern ;
+#else
+ *( (VgaMemoryPtr) xDst ) = bitPattern & bitmask;
+#endif
+ xDst += scr_incr;
+ }
+ }
+}
+
+return ;
+}
+
+#define DO_RECURSE 0x10000
+
+static void
+vgaSetMonoRegisters
+(
+ register unsigned long int plane_mask,
+ register unsigned long int desiredState
+)
+{
+#ifndef PC98_EGC
+/* Setup VGA Registers */
+/*
+ * Set The Plane-Enable
+ */
+SetVideoSequencer( Mask_MapIndex, plane_mask ) ;
+SetVideoGraphics( Enb_Set_ResetIndex, plane_mask ) ;
+/*
+ * Put Display Into SET-AND (i.e. Write Mode 3 )
+ */
+SetVideoGraphics( Graphics_ModeIndex, VGA_WRITE_MODE_3 ) ;
+/*
+ * Set The Color in The Set/Reset Register
+ */
+SetVideoGraphics( Set_ResetIndex, desiredState & VGA_ALLPLANES ) ;
+/*
+ * Set The Vga's Alu Function
+ */
+SetVideoGraphics( Data_RotateIndex, desiredState >> 8 ) ;
+#else /* PC98_EGC */
+unsigned short ROP_value;
+/* Setup VGA Registers */
+/*
+ * Set The Plane-Enable
+ */
+outw(EGC_PLANE, ~plane_mask);
+switch((desiredState >> 8)&0x18) {
+/* EGC MODE.. Cmp Read: Flase, WriteSource=ROP, ReadSource=CPU */
+ case VGA_AND_MODE:
+ if (desiredState & DO_RECURSE)
+ ROP_value = EGC_AND_INV_MODE;
+ else
+ ROP_value = EGC_AND_MODE;
+ break;
+ case VGA_OR_MODE:
+ if (desiredState & DO_RECURSE)
+ ROP_value = EGC_OR_INV_MODE;
+ else
+ ROP_value = EGC_OR_MODE;
+ break;
+ case VGA_XOR_MODE:
+ if (desiredState & DO_RECURSE)
+ ROP_value = EGC_XOR_INV_MODE;
+ else
+ ROP_value = EGC_XOR_MODE;
+ break;
+ case VGA_COPY_MODE:
+ default:
+ ROP_value = EGC_COPY_MODE;
+ break;
+}
+outw(EGC_MODE, ROP_value);
+outw(EGC_FGC, desiredState & VGA_ALLPLANES);
+#endif
+
+return ;
+}
+
+static unsigned long
+vgaCalcMonoMode
+(
+ int rasterOp,
+ register unsigned long int color
+)
+{
+register unsigned int data_rotate_value = VGA_COPY_MODE << 8 ;
+register unsigned int invert_existing_data = 0 ;
+
+/* Test The Raster-Op */
+switch ( rasterOp ) {
+ case GXclear: /* 0x0 Zero 0 */
+ color = 0 ;
+ break ;
+ case GXinvert: /* 0xa NOT dst */
+ data_rotate_value = VGA_XOR_MODE << 8 ;
+ case GXset: /* 0xf 1 */
+ color = VGA_ALLPLANES ;
+ break ;
+ case GXnor: /* 0x8 NOT src AND NOT dst */
+ invert_existing_data = DO_RECURSE ;
+ case GXandInverted: /* 0x4 NOT src AND dst */
+ color = ~color ;
+ case GXand: /* 0x1 src AND dst */
+ data_rotate_value = VGA_AND_MODE << 8 ;
+ case GXcopy: /* 0x3 src */
+ break ;
+ case GXequiv: /* 0x9 NOT src XOR dst */
+ color = ~color ;
+ case GXxor: /* 0x6 src XOR dst */
+ data_rotate_value = VGA_XOR_MODE << 8 ;
+ break ;
+ case GXandReverse: /* 0x2 src AND NOT dst */
+ invert_existing_data = DO_RECURSE ;
+ data_rotate_value = VGA_AND_MODE << 8 ;
+ break ;
+ case GXorReverse: /* 0xb src OR NOT dst */
+ invert_existing_data = DO_RECURSE ;
+ data_rotate_value = VGA_OR_MODE << 8 ;
+ break ;
+ case GXnand: /* 0xe NOT src OR NOT dst */
+ invert_existing_data = DO_RECURSE ;
+ case GXorInverted: /* 0xd NOT src OR dst */
+ color = ~color ;
+ case GXor: /* 0x7 src OR dst */
+ data_rotate_value = VGA_OR_MODE << 8 ;
+ break ;
+ case GXcopyInverted: /* 0xc NOT src */
+ color = ~color ;
+ break ;
+ case GXnoop: /* 0x5 dst */
+ ; /* Shouldn't Get Here !! */
+}
+
+return ( color & VGA_ALLPLANES ) | data_rotate_value | invert_existing_data ;
+}
+
+static void
+vgaDrawMonoImage
+(
+ WindowPtr pWin, /* GJA */
+ unsigned char *data,
+ int x,
+ int y,
+ int w,
+ int h,
+ unsigned long int fg,
+ int alu,
+ unsigned long int planes
+)
+{
+unsigned long regState ;
+
+if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) {
+ xf4bppOffDrawMonoImage( pWin, data, x, y, w, h, fg, alu, planes );
+ return;
+}
+
+if ( ( alu == GXnoop ) || !( planes &= VGA_ALLPLANES ) )
+ return ;
+
+#ifndef PC98_EGC
+if ( ( regState = vgaCalcMonoMode( alu, fg ) ) & DO_RECURSE ) {
+ vgaDrawMonoImage( pWin, data, x, y, w, h,
+ VGA_ALLPLANES, GXinvert, planes ) ;
+ regState &= ~DO_RECURSE ;
+}
+#else
+regState = vgaCalcMonoMode(alu, (char)fg);
+#endif
+
+
+vgaSetMonoRegisters( planes, regState ) ;
+
+DoMonoSingle( pWin, w, x, y, (const unsigned char *) data, h,
+ w, ( ( w + 31 ) & ~31 ) >> 3, h, 0, 0 ) ;
+
+
+return ;
+}
+
+void
+xf4bppFillStipple( pWin, pStipple, fg, alu, planes, x, y, w, h, xSrc, ySrc )
+WindowPtr pWin; /* GJA */
+register PixmapPtr const pStipple ;
+unsigned long int fg ;
+const int alu ;
+unsigned long int planes ;
+int x, y, w, h ;
+const int xSrc, ySrc ;
+{
+unsigned int width ;
+unsigned int height ;
+int xshift ;
+int yshift ;
+unsigned long regState ;
+
+if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) {
+ xf4bppOffFillStipple( pWin, pStipple, fg, alu, planes,
+ x, y, w, h, xSrc, ySrc );
+ return;
+}
+
+if ( ( alu == GXnoop ) || !( planes &= VGA_ALLPLANES ) )
+ return ;
+
+#if 1
+if ( ( regState = vgaCalcMonoMode( alu, fg ) ) & DO_RECURSE ) {
+ xf4bppFillStipple( pWin, pStipple, VGA_ALLPLANES, GXinvert, planes,
+ x, y, w, h, xSrc, ySrc ) ;
+ regState &= ~DO_RECURSE ;
+}
+#else
+regState = vgaCalcMonoMode(alu, (char)fg);
+#endif
+
+
+vgaSetMonoRegisters( planes, regState ) ;
+
+/* Figure Bit Offsets & Source Address */
+width = pStipple->drawable.width ;
+if ( ( xshift = ( x - xSrc ) ) < 0 )
+ xshift = width - ( ( - xshift ) % width ) ;
+else
+ xshift %= width ;
+if ( xshift == (int)width ) xshift = 0;
+
+height = pStipple->drawable.height ;
+if ( ( yshift = ( y - ySrc ) ) < 0 )
+ yshift = height - ( ( - yshift ) % height ) ;
+else
+ yshift %= height ;
+if ( yshift == (int)height ) yshift = 0;
+
+ (* ( (h > (int)height) ? DoMonoMany : DoMonoSingle ) ) (
+ pWin, w, x, y,
+ (const unsigned char *) pStipple->devPrivate.ptr,
+ h,
+ width,
+ ( ( width + 31 ) & ((unsigned)(~31)) ) >> 3,
+ height,
+ xshift, yshift
+ ) ;
+
+return ;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaVideo.h b/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaVideo.h
new file mode 100644
index 000000000..ecc2fa738
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/vgaVideo.h
@@ -0,0 +1,92 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/vgaVideo.h,v 1.2 1998/07/25 16:59:45 dawes Exp $ */
+/*
+ * Copyright IBM Corporation 1987,1988,1989
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of IBM not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * IBM 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.
+ *
+*/
+
+/* $XConsortium: vgaVideo.h /main/4 1996/02/21 17:59:14 kaleb $ */
+
+#include "misc.h" /* GJA -- for pointer data type */
+#ifdef lint
+#if defined(volatile)
+#undef volatile
+#endif
+#define volatile /**/
+#if defined(const)
+#undef const
+#endif
+#define const /**/
+#if defined(signed)
+#undef signed
+#endif
+#define signed /**/
+#endif
+
+/*
+ * References to all pc ( i.e. '286 ) memory in the
+ * regions used by the [ev]ga server ( the 128K windows )
+ * MUST be long-word ( i.e. 32-bit ) reads or writes.
+ * This definition will change for other memory architectures
+ * ( e.g. AIX-Rt )
+ */
+typedef unsigned char VideoAdapterObject ;
+typedef volatile VideoAdapterObject *VideoMemoryPtr ;
+typedef volatile VideoAdapterObject *VgaMemoryPtr ;
+#if !defined(BITMAP_BIT_ORDER)
+#define BITMAP_BIT_ORDER MSBFirst
+#endif
+
+#if !defined(IMAGE_BYTE_ORDER)
+#define IMAGE_BYTE_ORDER LSBFirst
+#endif
+
+/* Bit Ordering Macros */
+#if !defined(SCRLEFT8)
+#define SCRLEFT8(lw, n) ( (unsigned char) (((unsigned char) lw) << (n)) )
+#endif
+#if !defined(SCRRIGHT8)
+#define SCRRIGHT8(lw, n) ( (unsigned char) (((unsigned char)lw) >> (n)) )
+#endif
+/* These work ONLY on 8-bit wide Quantities !! */
+#define LeftmostBit ( SCRLEFT8( 0xFF, 7 ) & 0xFF )
+#define RightmostBit ( SCRRIGHT8( 0xFF, 7 ) & 0xFF )
+
+/*
+ * [ev]ga video screen defines & macros
+ */
+#define VGA_BLACK_PIXEL 0
+#define VGA_WHITE_PIXEL 1
+
+#define VGA_MAXPLANES 4
+#define VGA_ALLPLANES 0xFL
+
+#define VIDBASE(pDraw) ((volatile unsigned char *) \
+ (((PixmapPtr)(((DrawablePtr)(pDraw))->pScreen->devPrivate))-> \
+ devPrivate.ptr))
+#define BYTES_PER_LINE(pDraw) \
+ ((int)((PixmapPtr)(((DrawablePtr)(pDraw))->pScreen->devPrivate))->devKind)
+
+#define ROW_OFFSET( x ) ( ( x ) >> 3 )
+#define BIT_OFFSET( x ) ( ( x ) & 0x7 )
+#define SCREENADDRESS( pWin, x, y ) \
+ ( VIDBASE(pWin) + (y) * BYTES_PER_LINE(pWin) + ROW_OFFSET(x) )
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/vgamodule.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/vgamodule.c
new file mode 100644
index 000000000..c7cf1b7d3
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/vgamodule.c
@@ -0,0 +1,57 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/vgamodule.c,v 1.8 1999/01/26 05:54:20 dawes Exp $ */
+/*
+ * Copyright (C) 1998 The XFree86 Project, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * XFREE86 PROJECT 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 XFree86 Project 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
+ * XFree86 Project.
+ */
+
+#ifdef XFree86LOADER
+#include "xf86Module.h"
+
+static MODULESETUPPROTO(xf4bppSetup);
+
+static XF86ModuleVersionInfo VersRec =
+{
+ "xf4bpp",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_ANSIC, /* Only need ansic layer */
+ ABI_ANSIC_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0} /* signature, to be patched into the file by a tool */
+};
+
+XF86ModuleData xf4bppModuleData = { &VersRec, xf4bppSetup, NULL };
+
+static pointer
+xf4bppSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ /* This module requires xf1bpp for bitmap support */
+ return LoadSubModule(module, "xf1bpp", NULL, NULL, NULL, NULL,
+ errmaj, errmin);
+}
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/wm3.c b/xc/programs/Xserver/hw/xfree86/xf4bpp/wm3.c
new file mode 100644
index 000000000..f71301298
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/wm3.c
@@ -0,0 +1,205 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/wm3.c,v 1.3 1999/06/06 08:49:08 dawes Exp $ */
+
+
+
+
+
+/* $XConsortium: wm3.c /main/5 1996/02/21 17:59:21 kaleb $ */
+
+#include "xf4bpp.h"
+#include "OScompiler.h"
+#include "wm3.h"
+#include "vgaVideo.h"
+
+/* Ferraro is wrong. GJA */
+#define COPY (0 << 3)
+#define AND (1 << 3)
+#define OR (2 << 3)
+#define XOR (3 << 3)
+
+int
+wm3_set_regs(pGC)
+GC *pGC;
+{
+#ifndef PC98_EGC
+ int post_invert = 0;
+ int ALU;
+
+ switch(pGC->alu) {
+ case GXclear: /* rop0 = RROP_BLACK; rop1 = RROP_BLACK; */
+ pGC->fgPixel = 0;
+ pGC->bgPixel = 0;
+ ALU = COPY;
+ break;
+ case GXand: /* rop0 = RROP_BLACK; rop1 = RROP_NOP; */
+ ALU = AND;
+ break;
+ case GXandReverse: /* rop0 = RROP_BLACK; rop1 = RROP_INVERT; -- TRICKY */
+ pGC->fgPixel = ~pGC->fgPixel;
+ pGC->bgPixel = ~pGC->bgPixel;
+ ALU = OR;
+ post_invert = 1;
+ break;
+ case GXcopy: /* rop0 = RROP_BLACK; rop1 = RROP_WHITE; */
+ ALU = COPY;
+ break;
+ case GXandInverted: /* rop0 = RROP_NOP; rop1 = RROP_BLACK; */
+ pGC->fgPixel = ~pGC->fgPixel;
+ pGC->bgPixel = ~pGC->bgPixel;
+ ALU = AND;
+ break;
+ default:
+ case GXnoop: /* rop0 = RROP_NOP; rop1 = RROP_NOP; */
+ return 0;
+ case GXxor: /* rop0 = RROP_NOP; rop1 = RROP_INVERT; */
+ ALU = XOR;
+ break;
+ case GXor: /* rop0 = RROP_NOP; rop1 = RROP_WHITE; */
+ ALU = OR;
+ break;
+ case GXnor: /* rop0 = RROP_INVERT; rop1 = RROP_BLACK; -- TRICKY*/
+ ALU = OR;
+ post_invert = 1;
+ break;
+ case GXequiv: /* rop0 = RROP_INVERT; rop1 = RROP_NOP; */
+ pGC->fgPixel = ~pGC->fgPixel;
+ pGC->bgPixel = ~pGC->bgPixel;
+ ALU = XOR;
+ break;
+ case GXinvert: /* rop0 = RROP_INVERT; rop1 = RROP_INVERT; */
+ pGC->fgPixel = 0x0F;
+ pGC->bgPixel = 0x0F;
+ ALU = XOR;
+ break;
+ case GXorReverse: /* rop0 = RROP_INVERT; rop1 = RROP_WHITE; -- TRICKY */
+ pGC->fgPixel = ~pGC->fgPixel;
+ pGC->bgPixel = ~pGC->bgPixel;
+ ALU = AND;
+ post_invert = 1;
+ break;
+ case GXcopyInverted: /* rop0 = RROP_WHITE; rop1 = RROP_BLACK; */
+ pGC->fgPixel = ~pGC->fgPixel;
+ pGC->bgPixel = ~pGC->bgPixel;
+ ALU = COPY;
+ break;
+ case GXorInverted: /* rop0 = RROP_WHITE; rop1 = RROP_NOP; */
+ pGC->fgPixel = ~pGC->fgPixel;
+ pGC->bgPixel = ~pGC->bgPixel;
+ ALU = OR;
+ break;
+ case GXnand: /* rop0 = RROP_WHITE; rop1 = RROP_INVERT; -- TRICKY */
+ ALU = AND;
+ post_invert = 1;
+ break;
+ case GXset: /* rop0 = RROP_WHITE; rop1 = RROP_WHITE; */
+ pGC->fgPixel = 0x0F;
+ pGC->bgPixel = 0x0F;
+ ALU = COPY;
+ break;
+ }
+
+
+ SetVideoSequencer(Mask_MapIndex, (pGC->planemask & VGA_ALLPLANES));
+ SetVideoGraphics(Enb_Set_ResetIndex, VGA_ALLPLANES);
+ SetVideoGraphics(Set_ResetIndex, pGC->fgPixel);
+ SetVideoGraphics(Bit_MaskIndex, 0xFF);
+ SetVideoGraphics(Graphics_ModeIndex, 3); /* Write Mode 3 */
+ SetVideoGraphics(Data_RotateIndex, ALU);
+
+ return post_invert;
+#else
+ int ALU;
+
+ switch(pGC->alu) {
+ case GXclear: /* rop0 = RROP_BLACK; rop1 = RROP_BLACK; */
+ pGC->fgPixel = 0;
+ pGC->bgPixel = 0;
+ ALU = EGC_COPY_MODE;
+ break;
+ case GXand: /* rop0 = RROP_BLACK; rop1 = RROP_NOP; */
+ ALU = EGC_AND_MODE;
+ break;
+ case GXandReverse: /* rop0 = RROP_BLACK; rop1 = RROP_INVERT; -- TRICKY */
+ pGC->fgPixel = ~pGC->fgPixel;
+ pGC->bgPixel = ~pGC->bgPixel;
+ ALU = EGC_OR_INV_MODE;
+ break;
+ case GXcopy: /* rop0 = RROP_BLACK; rop1 = RROP_WHITE; */
+ ALU = EGC_COPY_MODE;
+ break;
+ case GXandInverted: /* rop0 = RROP_NOP; rop1 = RROP_BLACK; */
+ pGC->fgPixel = ~pGC->fgPixel;
+ pGC->bgPixel = ~pGC->bgPixel;
+ ALU = EGC_AND_MODE;
+ break;
+ case GXnoop: /* rop0 = RROP_NOP; rop1 = RROP_NOP; */
+ return 0;
+ case GXxor: /* rop0 = RROP_NOP; rop1 = RROP_INVERT; */
+ ALU = EGC_XOR_MODE;
+ break;
+ case GXor: /* rop0 = RROP_NOP; rop1 = RROP_WHITE; */
+ ALU = EGC_OR_MODE;
+ break;
+ case GXnor: /* rop0 = RROP_INVERT; rop1 = RROP_BLACK; -- TRICKY*/
+ ALU = EGC_OR_INV_MODE;
+ break;
+ case GXequiv: /* rop0 = RROP_INVERT; rop1 = RROP_NOP; */
+ pGC->fgPixel = ~pGC->fgPixel;
+ pGC->bgPixel = ~pGC->bgPixel;
+ ALU = EGC_XOR_MODE;
+ break;
+ case GXinvert: /* rop0 = RROP_INVERT; rop1 = RROP_INVERT; */
+ pGC->fgPixel = 0x0F;
+ pGC->bgPixel = 0x0F;
+ ALU = EGC_XOR_MODE;
+ break;
+ case GXorReverse: /* rop0 = RROP_INVERT; rop1 = RROP_WHITE; -- TRICKY */
+ pGC->fgPixel = ~pGC->fgPixel;
+ pGC->bgPixel = ~pGC->bgPixel;
+ ALU = EGC_AND_INV_MODE;
+ break;
+ case GXcopyInverted: /* rop0 = RROP_WHITE; rop1 = RROP_BLACK; */
+ pGC->fgPixel = ~pGC->fgPixel;
+ pGC->bgPixel = ~pGC->bgPixel;
+ ALU = EGC_COPY_MODE;
+ break;
+ case GXorInverted: /* rop0 = RROP_WHITE; rop1 = RROP_NOP; */
+ pGC->fgPixel = ~pGC->fgPixel;
+ pGC->bgPixel = ~pGC->bgPixel;
+ ALU = EGC_OR_MODE;
+ break;
+ case GXnand: /* rop0 = RROP_WHITE; rop1 = RROP_INVERT; -- TRICKY */
+ ALU = EGC_OR_INV_MODE;
+ break;
+ case GXset: /* rop0 = RROP_WHITE; rop1 = RROP_WHITE; */
+ pGC->fgPixel = 0x0F;
+ pGC->bgPixel = 0x0F;
+ ALU = EGC_COPY_MODE;
+ break;
+ }
+
+ outw(EGC_PLANE, ~(pGC->planemask & VGA_ALLPLANES));
+ outw(EGC_MODE, ALU);
+ outw(EGC_FGC, pGC->fgPixel & VGA_ALLPLANES); /* set FGC */
+
+ return 0;
+#endif
+}
+
+/*
+ Now we will have to set the alu.
+ Problematic is: How do we handle IsDoubleDash, which draws with both fg
+ and bg colour?
+ The answer is: We take care to store the ink colour in one register only.
+ Then we need set only this register to change the ink.
+ */
+
+/* -- MORE NOTES:
+ We might try to 'wrap' the mfb functions in a 16-colour wrapper that does
+ all operations once. However, this does not work:
+ Some operations (esp) CopyArea may for example cause expositions.
+ Such expositions will cause data to be copied in from backing store,
+ and this copying in may damage the contents of the VGA registers.
+ So we must take care to set the VGA registers at each place where they could
+ be modified.
+ */
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/wm3.h b/xc/programs/Xserver/hw/xfree86/xf4bpp/wm3.h
new file mode 100644
index 000000000..19c30b7de
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/wm3.h
@@ -0,0 +1,77 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/wm3.h,v 1.2 1998/07/25 16:59:46 dawes Exp $ */
+
+
+
+
+
+/* $XConsortium: wm3.h /main/4 1996/02/21 17:59:24 kaleb $ */
+
+#include "vgaReg.h"
+
+#ifdef PC98_EGC
+#define VGA_ALLPLANES 0xFL
+#endif
+
+/* Do call in Write Mode 3.
+ * We take care of the possibility that two passes are needed.
+ */
+#ifndef PC98_EGC
+#define DO_WM3(pgc,call) \
+ { int _tp, _fg, _bg, _alu; \
+ _fg = pgc->fgPixel; _bg = pgc->bgPixel; \
+ _tp = wm3_set_regs(pgc); \
+ (call); \
+ if ( _tp ) { \
+ _alu = pgc->alu; \
+ pgc->alu = GXinvert; \
+ _tp = wm3_set_regs(pgc); \
+ (call); \
+ pgc->alu = _alu; \
+ } \
+ pgc->fgPixel = _fg; pgc->bgPixel = _bg; \
+ }
+#else
+#define DO_WM3(pgc,call) \
+ { int _tp, _fg, _bg; \
+ _fg = pgc->fgPixel; _bg = pgc->bgPixel; \
+ _tp = wm3_set_regs(pgc); \
+ (call); \
+ pgc->fgPixel = _fg; pgc->bgPixel = _bg; \
+ }
+#endif
+
+#ifndef PC98_EGC
+#define WM3_SET_INK(ink) \
+ SetVideoGraphics(Set_ResetIndex, ink)
+#else
+#define WM3_SET_INK(ink) \
+ outw(EGC_FGC, ink)
+#endif
+
+/* GJA -- Move a long word to screen memory.
+ * The reads into 'dummy' are here to load the VGA latches.
+ * This is a RMW operation except for trivial cases.
+ * Notice that we ignore the operation.
+ */
+#ifdef PC98_EGC
+#define UPDRW(destp,src) \
+ { volatile unsigned short *_dtmp = \
+ (volatile unsigned short *)(destp); \
+ unsigned int _stmp = (src); \
+ *_dtmp = _stmp; _dtmp++; _stmp >>= 16; \
+ *_dtmp = _stmp; }
+#else
+#define UPDRW(destp,src) \
+ { volatile char *_dtmp = (volatile char *)(destp); \
+ int _stmp = (src); \
+ volatile int dummy; /* Bit bucket. */ \
+ _stmp = ldl_u(&_stmp); \
+ dummy = *_dtmp; *_dtmp = _stmp; _dtmp++; _stmp >>= 8; \
+ dummy = *_dtmp; *_dtmp = _stmp; _dtmp++; _stmp >>= 8; \
+ dummy = *_dtmp; *_dtmp = _stmp; _dtmp++; _stmp >>= 8; \
+ dummy = *_dtmp; *_dtmp = _stmp; }
+#endif
+
+#define UPDRWB(destp,src) \
+ { volatile int dummy; /* Bit bucket. */ \
+ dummy = *(destp); *(destp) = (src); }
diff --git a/xc/programs/Xserver/hw/xfree86/xf4bpp/xf4bpp.h b/xc/programs/Xserver/hw/xfree86/xf4bpp/xf4bpp.h
new file mode 100644
index 000000000..f9c8838b2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf4bpp/xf4bpp.h
@@ -0,0 +1,803 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/xf4bpp.h,v 1.4 1999/06/06 08:49:08 dawes Exp $ */
+
+
+#ifndef __XF4BPP_H__
+#define __XF4BPP_H__
+
+
+#include "windowstr.h"
+#include "gcstruct.h"
+#include "colormapst.h"
+#include "fontstruct.h"
+#ifndef PixelType
+#define PixelType unsigned long
+#endif
+
+/* ppcArea.c */
+void xf4bppAreaFill(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ int,
+ BoxPtr,
+ GCPtr
+#endif
+);
+
+/* ppcBStore.c */
+void xf4bppSaveAreas(
+#if NeedFunctionPrototypes
+ PixmapPtr,
+ RegionPtr,
+ int,
+ int,
+ WindowPtr
+#endif
+);
+void xf4bppRestoreAreas(
+#if NeedFunctionPrototypes
+ PixmapPtr,
+ RegionPtr,
+ int,
+ int,
+ WindowPtr
+#endif
+);
+
+/* ppcClip.c */
+void xf4bppDestroyClip(
+#if NeedFunctionPrototypes
+ GCPtr
+#endif
+);
+void xf4bppChangeClip(
+#if NeedFunctionPrototypes
+ GCPtr,
+ int,
+ pointer,
+ int
+#endif
+);
+void xf4bppCopyClip(
+#if NeedFunctionPrototypes
+ GCPtr,
+ GCPtr
+#endif
+);
+
+/* ppcCpArea.c */
+RegionPtr xf4bppCopyArea(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ DrawablePtr,
+ GCPtr,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int
+#endif
+);
+
+/* ppcDepth.c */
+Bool xf4bppDepthOK(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ int
+#endif
+);
+
+/* ppcFillRct.c */
+void xf4bppPolyFillRect(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ xRectangle *
+#endif
+);
+
+/* ppcWindowFS.c */
+void xf4bppSolidWindowFS(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ DDXPointPtr,
+ int *,
+ int
+#endif
+);
+void xf4bppStippleWindowFS(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ DDXPointPtr,
+ int *,
+ int
+#endif
+);
+void xf4bppOpStippleWindowFS(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ DDXPointPtr,
+ int *,
+ int
+#endif
+);
+void xf4bppTileWindowFS(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ DDXPointPtr,
+ int *,
+ int
+#endif
+);
+
+/* xf4bppPixmapFS.c */
+void xf4bppSolidPixmapFS(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ DDXPointPtr,
+ int *,
+ int
+#endif
+);
+void xf4bppStipplePixmapFS(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ DDXPointPtr,
+ int *,
+ int
+#endif
+);
+void xf4bppOpStipplePixmapFS(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ DDXPointPtr,
+ int *,
+ int
+#endif
+);
+void xf4bppTilePixmapFS(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ DDXPointPtr,
+ int *,
+ int
+#endif
+);
+
+/* ppcGC.c */
+Bool xf4bppCreateGC(
+#if NeedFunctionPrototypes
+ GCPtr
+#endif
+);
+void xf4bppDestroyGC(
+#if NeedFunctionPrototypes
+ GC *
+#endif
+);
+void xf4bppValidateGC(
+#if NeedFunctionPrototypes
+ GCPtr,
+ Mask,
+ DrawablePtr
+#endif
+);
+
+/* ppcGetSp.c */
+void xf4bppGetSpans(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ int,
+ DDXPointPtr,
+ int *,
+ int,
+ char *
+#endif
+);
+
+/* ppcImg.c */
+void xf4bppGetImage(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ int,
+ int,
+ int,
+ int,
+ unsigned int,
+ unsigned long,
+ char *
+#endif
+);
+
+/* ppcLine.c */
+void xf4bppScrnZeroLine(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ int,
+ DDXPointPtr
+#endif
+);
+void xf4bppScrnZeroDash(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ int,
+ DDXPointPtr
+#endif
+);
+void xf4bppScrnZeroSegs(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ xSegment *
+#endif
+);
+
+/* ppcPixmap.c */
+PixmapPtr xf4bppCreatePixmap(
+#if NeedFunctionPrototypes
+ ScreenPtr,
+ int,
+ int,
+ int
+#endif
+);
+PixmapPtr xf4bppCopyPixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr
+#endif
+);
+
+/* ppcPntWin.c */
+void xf4bppPaintWindow(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ RegionPtr,
+ int
+#endif
+);
+
+/* ppcPolyPnt.c */
+void xf4bppPolyPoint(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ int,
+ xPoint *
+#endif
+);
+
+/* ppcPolyRec.c */
+void xf4bppPolyRectangle(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ xRectangle *
+#endif
+);
+
+/* ppcQuery.c */
+void xf4bppQueryBestSize(
+#if NeedFunctionPrototypes
+ int,
+ unsigned short *,
+ unsigned short *,
+ ScreenPtr
+#endif
+);
+
+/* ppcRslvC.c */
+void xf4bppResolveColor(
+#if NeedFunctionPrototypes
+ unsigned short *,
+ unsigned short *,
+ unsigned short *,
+ VisualPtr
+#endif
+);
+Bool xf4bppInitializeColormap(
+#if NeedFunctionPrototypes
+ ColormapPtr
+#endif
+);
+
+/* ppcSetSp.c */
+void xf4bppSetSpans(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ char *,
+ DDXPointPtr,
+ int *,
+ int,
+ int
+#endif
+);
+
+/* ppcWindow.c */
+void xf4bppCopyWindow(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ DDXPointRec,
+ RegionPtr
+#endif
+);
+Bool xf4bppPositionWindow(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ int,
+ int
+#endif
+);
+Bool xf4bppUnrealizeWindow(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ int,
+ int
+#endif
+);
+Bool xf4bppDestroyWindow(
+#if NeedFunctionPrototypes
+ WindowPtr
+#endif
+);
+Bool xf4bppCreateWindowForXYhardware(
+#if NeedFunctionPrototypes
+ WindowPtr
+#endif
+);
+
+/* emulOpStip.c */
+void xf4bppOpaqueStipple(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ PixmapPtr,
+ unsigned long int,
+ unsigned long int,
+ int,
+ unsigned long int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int
+#endif
+);
+
+/* emulRepAre.c */
+void xf4bppReplicateArea(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int
+#endif
+);
+
+/* emulTile.c */
+void xf4bppTileRect(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ PixmapPtr,
+ const int,
+ const unsigned long int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int
+#endif
+);
+
+/* vgaGC.c */
+Mask xf4bppChangeWindowGC(
+#if NeedFunctionPrototypes
+ GCPtr,
+ Mask
+#endif
+);
+
+/* vgaBitBlt.c */
+void xf4bppBitBlt(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int
+#endif
+);
+
+/* vgaImages.c */
+void xf4bppDrawColorImage(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ int,
+ int,
+ int,
+ int,
+ unsigned char *,
+ int,
+ const int,
+ const unsigned long int
+#endif
+);
+void xf4bppReadColorImage(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ int,
+ int,
+ int,
+ int,
+ unsigned char *,
+ int
+#endif
+);
+
+/* vgaLine.c */
+void xf4bppHorzLine(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ unsigned long int,
+ int,
+ unsigned long int,
+ int,
+ int,
+ int
+#endif
+);
+void xf4bppVertLine(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ unsigned long int,
+ int,
+ unsigned long int,
+ int,
+ int,
+ int
+#endif
+);
+void xf4bppBresLine(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ unsigned long int,
+ int,
+ unsigned long int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ unsigned long int
+#endif
+);
+
+/* vgaStipple.c */
+void xf4bppFillStipple(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ const PixmapPtr,
+ unsigned long int,
+ const int,
+ unsigned long int,
+ int,
+ int,
+ int,
+ int,
+ const int,
+ const int
+#endif
+);
+
+/* vgaSolid.c */
+void xf4bppFillSolid(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ unsigned long int,
+ const int,
+ unsigned long int,
+ int,
+ const int,
+ int,
+ const int
+#endif
+);
+
+/* offscreen.c */
+void xf4bppOffBitBlt(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ const int,
+ const int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int
+#endif
+);
+void xf4bppOffDrawColorImage(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ int,
+ int,
+ int,
+ int,
+ unsigned char *,
+ int,
+ const int,
+ const unsigned long int
+#endif
+);
+void xf4bppOffReadColorImage(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ int,
+ int,
+ int,
+ int,
+ unsigned char *,
+ int
+#endif
+);
+void xf4bppOffFillSolid(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ unsigned long int,
+ const int,
+ unsigned long int,
+ int,
+ const int,
+ int,
+ const int
+#endif
+);
+void xf4bppOffDrawMonoImage(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ unsigned char *,
+ int,
+ int,
+ int,
+ int,
+ unsigned long int,
+ int,
+ unsigned long int
+#endif
+);
+void xf4bppOffFillStipple(
+#if NeedFunctionPrototypes
+ WindowPtr,
+ const PixmapPtr,
+ unsigned long int,
+ const int,
+ unsigned long int,
+ int,
+ int,
+ int,
+ int,
+ const int,
+ const int
+#endif
+);
+
+/* mfbimggblt.c */
+void xf4bppImageGlyphBlt(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ int,
+ unsigned int,
+ CharInfoPtr *,
+ unsigned char *
+#endif
+);
+
+/* wm3.c */
+int wm3_set_regs(
+#if NeedFunctionPrototypes
+ GC *
+#endif
+);
+
+/* ppcIO.c */
+int xf4bppNeverCalled(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+Bool xf4bppScreenInit(
+#if NeedFunctionPrototypes
+ ScreenPtr,
+ pointer,
+ int,
+ int,
+ int,
+ int,
+ int
+#endif
+);
+
+/* mfbfillarc.c */
+void xf4bppPolyFillArc(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ xArc *
+#endif
+);
+
+/* mfbzerarc.c */
+void xf4bppZeroPolyArc(
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ xArc *
+#endif
+);
+
+/* mfbline.c */
+void xf4bppSegmentSS (
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ xSegment *
+#endif
+);
+void xf4bppLineSS (
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ int,
+ DDXPointPtr
+#endif
+);
+void xf4bppSegmentSD (
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ xSegment *
+#endif
+);
+void xf4bppLineSD (
+#if NeedFunctionPrototypes
+ DrawablePtr,
+ GCPtr,
+ int,
+ int,
+ DDXPointPtr
+#endif
+);
+
+/* mfbbres.c */
+void xf4bppBresS(
+#if NeedFunctionPrototypes
+ PixelType *,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int,
+ int
+#endif
+);
+
+/* mfbbresd.c */
+void xf4bppBresD(
+#if NeedFunctionPrototypes
+ int, int,
+ int *,
+ unsigned char *,
+ int,
+ int *,
+ int,
+ PixelType *,
+ int, int, int, int, int, int,
+ int, int,
+ int, int
+#endif
+);
+
+/* mfbhrzvert.c */
+void xf4bppHorzS(
+#if NeedFunctionPrototypes
+ PixelType *,
+ int,
+ int,
+ int,
+ int
+#endif
+);
+void xf4bppVertS(
+#if NeedFunctionPrototypes
+ PixelType *,
+ int,
+ int,
+ int,
+ int
+#endif
+);
+
+#ifdef PC98_EGC
+
+/* egc_asm.s */
+unsigned char getbits_x(
+#if NeedFunctionPrototypes
+ int,
+ unsigned int,
+ pointer,
+ unsigned int
+#endif
+);
+void wcopyr(
+#if NeedFunctionPrototypes
+ pointer,
+ pointer,
+ int,
+ pointer
+#endif
+);
+void wcopyl(
+#if NeedFunctionPrototypes
+ pointer,
+ pointer,
+ int,
+ pointer
+#endif
+);
+unsigned long int read8Z(
+#if NeedFunctionPrototypes
+ pointer
+#endif
+);
+
+#endif /* PC98_EGC */
+
+#endif /* __XF4BPP_H__ */
diff --git a/xc/programs/Xserver/hw/xfree86/xf86config/Cards b/xc/programs/Xserver/hw/xfree86/xf86config/Cards
new file mode 100644
index 000000000..a5b693556
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf86config/Cards
@@ -0,0 +1,3059 @@
+# $XConsortium: Cards /main/27 1996/10/28 05:43:53 kaleb $
+# This is the database of card definitions used by xf86config.
+# Each definition should have a NAME entry, CHIPSET (descriptive) and
+# SERVER (one of Mono, VGA16, SVGA, S3, 8514, Mach8, Mach32, Mach64, AGX,
+# P9000, W32, I128).
+# A reference to another definition is made with SEE (already defined
+# entries are not overridden).
+# Optional entries are RAMDAC (identifier), CLOCKCHIP (identifier),
+# DACSPEED, NOCLOCKPROBE (advises never to probe clocks), UNSUPPORTED
+# (indicates card that is not yet properly supported by a dedicated
+# server). A LINE entry adds a line of text to be included in the
+# Device section (can include options or comments).
+# There's no CLOCKS option (although a Clocks line can be included
+# with LINE), as it is very undesirable to have a Clocks line that
+# is incorrect. The idea is that the Clocks are probed for to be
+# sure (a commented suggested Clocks line can be included).
+#
+# The majority of entries are just a binding of a model name to a
+# chipset/server and untested.
+#
+# $XFree86: xc/programs/Xserver/hw/xfree86/xf86config/Cards,v 3.66 1999/08/28 09:01:18 dawes Exp $
+
+# VGA
+
+NAME Generic VGA compatible
+CHIPSET Generic VGA
+SERVER VGA16
+DRIVER vga
+
+NAME Unsupported VGA compatible
+CHIPSET Generic VGA
+SERVER VGA16
+DRIVER vga
+UNSUPPORTED
+
+#Chips & Technologies
+
+#untested
+NAME Chips & Technologies CT65520
+CHIPSET ct65520
+SERVER SVGA
+DRIVER chips
+LINE # Device section for C&T cards.
+LINE # Option "suspend_hack"
+LINE # Option "STN"
+LINE # Option "no_stretch"
+LINE # Option "no_center"
+LINE # Option "use_modeline"
+LINE # Option "fix_panel_size"
+LINE # videoram 512
+
+NAME Chips & Technologies CT65525
+CHIPSET ct65525
+LINE # Option "nolinear"
+LINE # MemBase 0x03b00000
+SEE Chips & Technologies CT65520
+
+NAME Chips & Technologies CT65530
+CHIPSET ct65530
+SEE Chips & Technologies CT65525
+
+NAME Chips & Technologies CT65535
+CHIPSET ct65535
+NOCLOCKPROBE
+LINE # Option "hw_clocks"
+LINE # Textclockfreq 25.175
+SEE Chips & Technologies CT65530
+
+NAME Chips & Technologies CT65540
+CHIPSET ct65540
+NOCLOCKPROBE
+LINE # Option "use_18bit_bus"
+SEE Chips & Technologies CT65535
+
+NAME Chips & Technologies CT65545
+CHIPSET ct65545
+NOCLOCKPROBE
+LINE # Option "noaccel"
+LINE # Option "no_bitblt"
+LINE # Option "xaa_no_color_exp"
+LINE # Option "xaa_benchmark"
+LINE # Option "hw_cursor"
+LINE # Option "mmio"
+SEE Chips & Technologies CT65540
+
+NAME Chips & Technologies CT65546
+CHIPSET ct65546
+SEE Chips & Technologies CT65545
+
+NAME Chips & Technologies CT65548
+CHIPSET ct65548
+SEE Chips & Technologies CT65545
+
+NAME Chips & Technologies CT65550
+CHIPSET ct65550
+NOCLOCKPROBE
+LINE # Option "noaccel"
+LINE # Option "no_bitblt"
+LINE # Option "xaa_no_color_exp"
+LINE # Option "xaa_benchmark"
+LINE # Option "hw_cursor"
+LINE # Option "sync_on_green"
+LINE # Option "fast_dram"
+LINE # Option "use_vclk1"
+LINE # Textclockfreq 25.175
+SEE Chips & Technologies CT65530
+
+NAME Chips & Technologies CT65554
+CHIPSET ct65554
+SEE Chips & Technologies CT65550
+
+NAME Chips & Technologies CT65555
+CHIPSET ct65555
+SEE Chips & Technologies CT65550
+
+NAME Chips & Technologies CT68554
+CHIPSET ct68554
+SEE Chips & Technologies CT65550
+
+NAME Chips & Technologies CT69000
+CHIPSET ct69000
+SEE Chips & Technologies CT65550
+
+NAME Chips & Technologies CT69030
+CHIPSET ct69030
+SEE Chips & Technologies CT65550
+
+NAME Chips & Technologies CT64200
+CHIPSET ct64200
+SERVER SVGA
+DRIVER chips
+LINE # Device section for C&T cards.
+LINE # videoram 1024
+
+NAME Chips & Technologies CT64300
+CHIPSET ct64300
+SERVER SVGA
+DRIVER chips
+LINE # Option "noaccel"
+LINE # Option "no_bitblt"
+LINE # Option "xaa_no_color_exp"
+LINE # Option "xaa_benchmark"
+LINE # Option "hw_cursor"
+LINE # Option "nolinear"
+LINE # MemBase 0x03b00000
+LINE # Option "hw_clocks"
+LINE # Textclockfreq 25.175
+SEE Chips & Technologies CT64200
+
+# Cirrus Logic
+
+#tested
+NAME Cirrus Logic GD542x
+CHIPSET CL-GD5420/2/4/6/8/9
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+LINE # Device section for Cirrus Logic GD5420/2/4/6/8/9-based cards.
+LINE #MemBase 0x00e00000
+LINE #MemBase 0x04e00000
+LINE #Option "linear"
+
+#tested
+NAME Cirrus Logic GD543x
+CHIPSET CL-GD5430/5434/5436
+SERVER SVGA
+DRIVER cirrus
+NOCLOCKPROBE
+LINE # Device section for Cirrus Logic GD5430/34-based cards.
+LINE #MemBase 0x00e00000 # ISA card that maps to 14Mb
+LINE #MemBase 0x04000000 # VLB card that maps to 64Mb
+LINE #MemBase 0x80000000 # VLB card that maps to 2048Mb
+LINE #MemBase 0x02000000 # VLB card that maps to 32Mb
+LINE #Option "linear"
+
+NAME Cirrus Logic GD544x
+CHIPSET CL-GD544x
+SERVER SVGA
+DRIVER cirrus
+NOCLOCKPROBE
+
+NAME Creative Labs Graphics Blaster MA201
+SEE Cirrus Logic GD544x
+
+NAME Creative Labs Graphics Blaster MA202
+SEE Cirrus Logic GD544x
+
+#tested
+NAME Cirrus Logic GD5462
+CHIPSET CL-GD5462
+SERVER SVGA
+DRIVER cirrus
+NOCLOCKPROBE
+LINE #Option "fifo_conservative"
+
+#tested
+NAME Cirrus Logic GD5464
+CHIPSET CL-GD5464
+SERVER SVGA
+DRIVER cirrus
+NOCLOCKPROBE
+LINE #Option "fifo_conservative"
+
+#tested
+NAME Cirrus Logic GD5465
+CHIPSET CL-GD5465
+SERVER SVGA
+DRIVER cirrus
+NOCLOCKPROBE
+LINE #Option "fifo_conservative"
+
+NAME Creative Labs Graphics Blaster MA302
+CHIPSET CL-GD5462
+SEE Cirrus Logic GD5462
+
+NAME Creative Labs Graphics Blaster MA334
+CHIPSET CL-GD5464
+SEE Cirrus Logic GD5464
+
+NAME Creative Labs Graphics Blaster 3D
+CHIPSET CL-GD5464
+SEE Cirrus Logic GD5464
+
+#tested
+NAME Cirrus Logic GD5480
+CHIPSET CL-GD5480
+SERVER SVGA
+DRIVER cirrus
+NOCLOCKPROBE
+
+#tested
+NAME Diamond SpeedStar 64
+CHIPSET CL-GD5434
+SEE Cirrus Logic GD543x
+
+NAME Diamond SpeedStar64 Graphics 2000/2200
+CHIPSET CL-GD5434
+SEE Cirrus Logic GD543x
+
+NAME Diamond SpeedStar Pro SE (CL-GD5430/5434)
+SEE Cirrus Logic GD543x
+
+NAME Diamond SpeedStar Pro 1100
+SEE Cirrus Logic GD542x
+
+NAME Orchid Kelvin 64 VLB Rev A
+CHIPSET CL-GD5434
+SERVER SVGA
+DRIVER cirrus
+NOCLOCKPROBE
+LINE # Device section for Orchid Kelvin 64 VLB Rev A
+LINE # Linear framebuffer maps at 2048Mb. Some motherboards make linear addressing
+LINE # impossible. Some cards map at 32Mb.
+LINE #MemBase 0x02000000 # VLB card that maps to 32Mb
+LINE #MemBase 0x04000000 # VLB card that maps to 64Mb
+LINE MemBase 0x80000000 # VLB card that maps to 2048Mb
+LINE #Option "linear"
+
+NAME Orchid Kelvin 64 VLB Rev B
+CHIPSET CL-GD5434
+SERVER SVGA
+DRIVER cirrus
+NOCLOCKPROBE
+LINE # Device section for Orchid Kelvin 64 VLB Rev B
+LINE # Linear framebuffer maps at 32Mb. Some motherboards make linear addressing
+LINE # impossible. Some cards map at 2048Mb.
+LINE MemBase 0x02000000 # VLB card that maps to 32Mb
+LINE #MemBase 0x04000000 # VLB card that maps to 64Mb
+LINE #MemBase 0x80000000 # VLB card that maps to 2048Mb
+LINE #Option "linear"
+
+NAME Orchid Kelvin 64
+CHIPSET CL-GD5434
+SEE Cirrus Logic GD543x
+
+NAME Intel 5430
+CHIPSET CL-GD5430
+SEE Cirrus Logic GD543x
+
+NAME STB Nitro (64)
+CHIPSET CL-GD5434
+SEE Cirrus Logic GD543x
+
+NAME STB Nitro 64 Video
+CHIPSET CL-GD5446
+SEE Cirrus Logic GD544x
+
+NAME STB Horizon
+CHIPSET CL-GD5426/28
+SEE Cirrus Logic GD542x
+
+NAME STB Horizon Video
+CHIPSET CL-GD5440
+SEE Cirrus Logic GD544x
+
+NAME Genoa 8500VL(-28)
+CHIPSET CL-GD5426/28
+SEE Cirrus Logic GD542x
+
+NAME Diamond SpeedStar Pro (not SE)
+CHIPSET CL-GD5426/28
+SEE Cirrus Logic GD542x
+
+NAME ALG-5434(E)
+CHIPSET CL-GD5434
+SEE Cirrus Logic GD543x
+
+NAME Actix ProStar
+CHIPSET CL-GD5426/5428
+SEE Cirrus Logic GD542x
+
+NAME Actix ProStar 64
+CHIPSET CL-GD5434
+SEE Cirrus Logic GD543x
+
+#tested
+NAME Acumos AVGA3
+SEE Cirrus Logic GD542x
+
+NAME DFI-WG1000
+SEE Cirrus Logic GD542x
+
+NAME Spider VLB Plus
+CHIPSET CL-GD5428
+SEE Cirrus Logic GD542x
+
+NAME VI720
+CHIPSET CL-GD5434
+SEE Cirrus Logic GD543x
+
+NAME Cirrus Logic GD62xx (laptop)
+CHIPSET CL-GD6205/15/25/35
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+NAME Cirrus Logic GD64xx (laptop)
+CHIPSET CL-GD6420/6440
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME Cirrus Logic GD754x (laptop)
+CHIPSET CL-GD7541/42/43/48
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+NAME Techworks Ultimate 3D
+CHIPSET CL-GD5464
+SEE Cirrus Logic GD5464
+
+NAME VideoLogic GrafixStar 550
+CHIPSET CL-GD5464
+SEE Cirrus Logic GD5464
+
+NAME Jaton Video-70P
+CHIPSET CL-GD5464
+SEE Cirrus Logic GD5464
+
+NAME PixelView Combo TV Pro (Prolink)
+CHIPSET CL-GD5480, 4MB
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+COMMENT on card TV Tuner
+NOCLOCKPROBE
+
+NAME PixelView Combo TV 3D AGP (Prolink)
+CHIPSET CL-GD5465, 4MB
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+COMMENT on card TV+FM Tuner
+NOCLOCKPROBE
+
+NAME Creative Labs Graphics Blaster Eclipse (OEM Model CT6510)
+SEE Cirrus Logic GD5465
+
+NAME VideoLogic GrafixStar 560 (PCI/AGP)
+SEE Cirrus Logic GD5465
+
+NAME Cirrus Logic GD5446 (noname card)
+CHIPSET CL-GD5446, 1MB (upgradable to 2MB).
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+NAME Octek VL-VGA-26
+CHIPSET CL-GD5426
+SEE Cirrus Logic GD542x
+
+NAME Octek VL-VGA-28
+CHIPSET CL-GD5428
+SEE Cirrus Logic GD542x
+
+NAME Octek Combo-26
+CHIPSET CL-GD5426
+SEE Cirrus Logic GD542x
+
+NAME Octek Combo-28
+CHIPSET CL-GD5428
+SEE Cirrus Logic GD542x
+
+NAME Octek AVGA-20
+CHIPSET CL-GD5420
+SEE Cirrus Logic GD542x
+
+# S3 801/805
+
+NAME S3 801/805 (generic)
+CHIPSET S3 801/805
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+
+NAME S3 86C801 (generic)
+SEE S3 801/805 (generic)
+
+NAME S3 86C805 (generic)
+SEE S3 801/805 (generic)
+
+#tested
+NAME S3 801/805 with ATT20c490 RAMDAC
+CHIPSET S3 801/805
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC att20c490
+LINE #Option "dac_8_bit" # Not supported by some 20c490 clones
+
+NAME S3 801/805 with SC1148{2,3,4} RAMDAC
+CHIPSET S3 801/805
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC sc11482
+
+NAME S3 801/805 with SC1148{5,7,9} RAMDAC
+CHIPSET S3 801/805
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC sc11485
+
+NAME S3 801/805 with S3 GenDAC
+CHIPSET S3 801/805
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC s3gendac
+CLOCKCHIP s3gendac
+
+NAME S3 801/805 with ATT20c490 RAMDAC and ICD2061A
+CHIPSET S3 801/805
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC att20c490
+CLOCKCHIP icd2061a
+LINE #Option "dac_8_bit" # Not supported by some 20c490 clones
+
+NAME S3 801/805 with Chrontel 8391
+CHIPSET S3 801/805
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC att20c490
+CLOCKCHIP ch8391
+LINE Option "dac_8_bit"
+
+#tested
+NAME Actix GE32+ 2MB
+CHIPSET S3 801/805
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC att20c490
+LINE #Option "dac_8_bit"
+
+NAME Actix GE32i
+CHIPSET S3 805i
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+
+NAME Orchid Fahrenheit VA
+CHIPSET S3 801/805
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC att20c490
+
+NAME Orchid Fahrenheit 1280
+CHIPSET S3 801
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+LINE #Probable clocks:
+LINE #Clocks 25.20 28.32 32.50 0.00 40.00 44.90 50.40 65.00
+LINE #Clocks 78.00 56.70 63.10 75.10 80.00 89.90 100.90 31.50
+
+NAME Orchid Fahrenheit-1280+
+CHIPSET S3 801/805
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC att20C490
+LINE Dacspeed 110
+LINE Option "dac_8_bit"
+LINE #Option "nolinear" # VLB card may require this
+LINE #Probable clocks:
+LINE #Clocks 25.20 28.32 40.0 0.0 50.10 77.0 36.10 45.0
+LINE #Clocks 130.0 120.20 80.0 31.50 110.30 65.0 75.0 94.60
+
+NAME Diamond Stealth 24
+CHIPSET S3 801/805
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+CLOCKCHIP icd2061a
+LINE #Option "nolinear"
+LINE #Ramdac "att20c490" # The Diamond RAMDAC is reportedly compatible for 15bpp
+
+NAME Miro Crystal 8S
+SEE S3 801/805 (generic)
+
+NAME Miro Crystal 10SD with GenDAC
+SEE S3 801/805 with S3 GenDAC
+
+NAME Dell S3 805
+SEE S3 801/805 (generic)
+
+NAME STB Powergraph X-24
+SEE S3 801/805 with ATT20c490 RAMDAC and ICD2061A
+
+NAME JAX 8241
+SEE S3 801/805 with Chrontel 8391
+
+NAME VL-41
+SEE S3 801/805 with Chrontel 8391
+
+NAME SPEA Mirage
+SEE S3 801/805 with Chrontel 8391
+
+# S3 864/Trio64/Trio32/868
+
+NAME S3 864 (generic)
+CHIPSET S3 864
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+
+NAME S3 86C864 (generic)
+SEE S3 864 (generic)
+
+NAME S3 Vision864 (generic)
+SEE S3 864 (generic)
+
+NAME S3 864 with SDAC (86C716)
+CHIPSET S3 864
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC s3_sdac
+CLOCKCHIP s3_sdac
+NOCLOCKPROBE
+
+NAME S3 864 with ATT 20C498 or 21C498
+CHIPSET S3 864
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC att20c498
+
+NAME S3 864 with STG1703
+CHIPSET S3 864
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC stg1703
+NOCLOCKPROBE
+
+NAME S3 868 (generic)
+CHIPSET S3 868
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+
+NAME S3 86C868 (generic)
+SEE S3 868 (generic)
+
+NAME S3 Vision868 (generic)
+SEE S3 868 (generic)
+
+NAME S3 868 with SDAC (86C716)
+CHIPSET S3 868
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+NAME S3 868 with ATT 20C498 or 21C498
+CHIPSET S3 868
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC att20c498
+
+NAME S3 868 with ATT 20C409
+CHIPSET S3 868
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC att20c409
+NOCLOCKPROBE
+
+NAME Number Nine FX Motion 531
+CLOCKCHIP icd2061a
+SEE S3 868 with ATT 20C498 or 21C498
+
+NAME S3 Trio64 (generic)
+CHIPSET S3 Trio64
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+NAME S3 86C764 (generic)
+SEE S3 Trio64 (generic)
+
+NAME S3 Trio64V+ (generic)
+CHIPSET S3 Trio64V+
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+NAME S3 86C765 (generic)
+SEE S3 Trio64V+ (generic)
+
+NAME S3 Trio32 (generic)
+CHIPSET S3 Trio32
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+NAME Genoa Phantom 64i with S3 SDAC
+DACSPEED 135
+SEE S3 864 with SDAC (86C716)
+
+NAME Number Nine GXE64
+CHIPSET S3 864
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+CLOCKCHIP icd2061a
+LINE Option "number_nine"
+
+NAME Number Nine GXE64 with S3 Trio64
+SEE S3 Trio64 (generic)
+
+NAME Diamond Stealth 64 DRAM with S3 SDAC
+DACSPEED 135
+SEE S3 864 with SDAC (86C716)
+
+NAME Diamond Stealth64 Graphics 2xx0 series (864 + SDAC)
+DACSPEED 135
+SEE S3 864 with SDAC (86C716)
+
+NAME Diamond Stealth 64 DRAM with S3 Trio64
+SEE S3 Trio64 (generic)
+
+NAME Diamond Stealth64 Graphics 2xx0 series (Trio64)
+SEE S3 Trio64 (generic)
+
+NAME Diamond Stealth 64 DRAM SE
+SEE S3 Trio32 (generic)
+
+NAME Diamond Stealth64 Video 2001 series (2121/2201)
+SEE S3 Trio64V+ (generic)
+
+NAME Actix GE64
+CLOCKCHIP icd2061a
+SEE S3 864 (generic)
+
+NAME ELSA Winner 1000PRO with S3 SDAC
+SEE S3 864 with SDAC (86C716)
+
+NAME ELSA Winner 1000PRO with STG1700 or AT&T RAMDAC
+CHIPSET S3 864
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+CLOCKCHIP icd2061a
+
+NAME ELSA Winner 1000PRO/X
+SEE S3 868 with SDAC (86C716)
+
+NAME ELSA Winner 1000ISA
+CHIPSET S3 805i
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+CLOCKCHIP icd2061a
+LINE Option "dac_8_bit"
+LINE # the following settings should be detected and set automatically by XF86_S3
+LINE # if the serial number of the ELSA card is printed correctly:
+LINE #ClockChip "icd2061a"
+
+NAME Cardex Trio64
+SEE S3 Trio64 (generic)
+
+NAME Cardex Trio64Pro
+SEE S3 Trio64 (generic)
+
+NAME Miro Crystal 12SD
+SEE S3 Trio32 (generic)
+
+NAME Miro Crystal 22SD
+SEE S3 Trio64 (generic)
+
+NAME Miro Crystal 20SD with ICS2494 (BIOS 1.xx)
+SEE S3 864 with ATT 20C498 or 21C498
+
+NAME Miro Crystal 20SD with ICD2061A (BIOS 2.xx)
+CLOCKCHIP icd2061a
+SEE S3 864 with ATT 20C498 or 21C498
+
+NAME Miro Crystal 20SD VLB with S3 SDAC (BIOS 3.xx)
+SEE S3 864 with SDAC (86C716)
+
+NAME Miro Crystal 20SD PCI with S3 SDAC
+SEE S3 868 with SDAC (86C716)
+
+NAME ELSA Winner 1000AVI (SDAC version)
+SEE S3 868 with SDAC (86C716)
+
+NAME ELSA Winner 1000AVI (AT&T 20C409 version)
+SEE S3 868 with ATT 20C409
+
+NAME Diamond Stealth Video DRAM
+SEE S3 868 with SDAC (86C716)
+
+NAME Diamond Stealth64 Video 2120/2200
+SEE S3 868 with SDAC (86C716)
+
+NAME SPEA/V7 Mirage P64
+CLOCKCHIP ics2595
+SEE S3 864 (generic)
+
+NAME SPEA/V7 Mirage P64 with S3 Trio64
+SEE S3 Trio64 (generic)
+
+NAME Number Nine FX Vision 330
+SEE S3 Trio64 (generic)
+
+NAME Number Nine FX Motion 331
+SEE S3 Trio64V+ (generic)
+
+NAME ASUS Video Magic PCI V864
+SEE S3 864 (generic)
+
+NAME ASUS Video Magic PCI VT64
+SEE S3 Trio64 (generic)
+
+NAME VidTech FastMax P20
+SEE S3 864 (generic)
+
+NAME VideoLogic GrafixStar 500
+SEE S3 868 with SDAC (86C716)
+
+NAME VideoLogic GrafixStar 400
+SEE S3 Trio64V+ (generic)
+
+NAME VideoLogic GrafixStar 300
+SEE S3 Trio64 (generic)
+
+NAME 2 the Max MAXColor S3 Trio64V+
+SEE S3 Trio64V+ (generic)
+
+NAME DataExpert DSV3365
+SEE S3 Trio64V+ (generic)
+
+NAME ExpertColor DSV3365
+SEE S3 Trio64V+ (generic)
+
+NAME DSV3326
+SEE S3 Trio64V+ (generic)
+
+# S3 Trio64V2
+
+NAME S3 Trio64V2 (generic)
+CHIPSET S3 Trio64V2
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+NAME S3 Trio64V2/DX (generic)
+SEE S3 Trio64V2 (generic)
+
+NAME S3 Trio64V2/GX (generic)
+SEE S3 Trio64V2 (generic)
+
+NAME S3 86C775 (generic)
+SEE S3 Trio64V2/DX (generic)
+
+NAME S3 86C785 (generic)
+SEE S3 Trio64V2/GX (generic)
+
+NAME ELSA WINNER 1000/T2D
+SEE S3 Trio64V2/DX (generic)
+
+
+# S3 Aurora64V+
+
+NAME S3 Aurora64V+ (generic)
+CHIPSET S3 Aurora64V+
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+LINE # Option "lcd_center"
+LINE # Set_LCDClk <pixel_clock_for_LCD>
+
+NAME S3 86CM65
+SEE S3 Aurora64V+ (generic)
+
+NAME SHARP 9080
+SEE S3 Aurora64V+ (generic)
+
+NAME SHARP 9090
+SEE S3 Aurora64V+ (generic)
+
+NAME COMPAQ Armada 7730MT
+SEE S3 Aurora64V+ (generic)
+
+NAME COMPAQ Armada 7380DMT
+SEE S3 Aurora64V+ (generic)
+
+
+# S3 964/968
+
+NAME S3 964 (generic)
+CHIPSET S3 964
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+NAME S3 86C964 (generic)
+SEE S3 964 (generic)
+
+NAME S3 Vision964 (generic)
+SEE S3 964 (generic)
+
+NAME S3 968 (generic)
+CHIPSET S3 968
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+NAME S3 86C968 (generic)
+SEE S3 968 (generic)
+
+NAME S3 Vision968 (generic)
+SEE S3 968 (generic)
+
+NAME Number Nine GXE64 Pro
+CHIPSET S3 964
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC ti3025
+LINE Option "number_nine"
+
+NAME Diamond Stealth 64 VRAM
+CLOCKCHIP icd2061a
+LINE #Option "slow_vram"
+SEE S3 964 (generic)
+
+NAME Diamond Stealth64 Video 3200
+CHIPSET S3 968
+LINE #Option "slow_vram"
+SEE S3 968 (generic)
+
+NAME Diamond Stealth 64 Video VRAM (TI RAMDAC)
+CHIPSET S3 968
+LINE #Option "slow_vram"
+LINE #DacSpeed 220
+SEE S3 968 (generic)
+
+NAME Diamond Stealth64 Video 3240/3400 (TI RAMDAC)
+CHIPSET S3 968
+LINE #Option "slow_vram"
+LINE #DacSpeed 220
+SEE S3 968 (generic)
+
+NAME Diamond Stealth64 Video 3240/3400 (IBM RAMDAC)
+CHIPSET S3 968
+LINE #Option "slow_vram"
+RAMDAC ibm_rgb526
+LINE DacSpeed 220
+SEE S3 968 (generic)
+
+NAME Genoa VideoBlitz III AV
+CHIPSET S3 968
+LINE #s3RefClk 50
+LINE #DACspeed 170
+SEE S3 968 (generic)
+
+NAME STB Velocity 64 Video
+CHIPSET S3 968
+LINE #s3RefClk 24
+LINE #DACspeed 220
+SEE S3 968 (generic)
+
+NAME STB Powergraph 64 Video
+SEE S3 Trio64V+ (generic)
+
+NAME STB Powergraph 64
+SEE S3 Trio64 (generic)
+
+NAME ELSA Winner 1000TRIO
+SEE S3 Trio64 (generic)
+
+NAME ELSA Winner 1000TRIO/V
+SEE S3 Trio64V+ (generic)
+
+NAME Hercules Graphite Terminator 64
+LINE Option "slow_vram"
+LINE #s3RefClk 50
+LINE #DACspeed 170
+SEE S3 964 (generic)
+
+NAME Hercules Terminator 64/Video
+SEE S3 Trio64V+ (generic)
+
+NAME Hercules Graphite Terminator 64/DRAM
+SEE S3 Trio64 (generic)
+
+NAME Hercules Graphite Terminator Pro 64
+LINE #s3RefClk 16
+LINE #DACspeed 220
+SEE S3 968 (generic)
+
+NAME Number Nine FX Motion 771
+LINE #s3RefClk 16
+SEE S3 968 (generic)
+
+NAME Spider Tarantula 64
+SEE S3 964 (generic)
+
+NAME Miro Crystal 20SV
+CHIPSET S3 964
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+CLOCKCHIP icd2061a
+
+NAME Miro Crystal 40SV
+CHIPSET S3 964
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+CLOCKCHIP ti3025
+
+NAME Miro Crystal 80SV
+CHIPSET S3 968
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+NAME Miro Video 20SV
+CHIPSET S3 968
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC att20c505
+LINE #DacSpeed 150
+CLOCKCHIP ics9161a
+
+NAME SPEA Mercury 64
+CHIPSET S3 964
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+CLOCKCHIP ics9161a
+LINE #Option "spea_mercury"
+
+NAME ELSA Winner 2000PRO-2
+CHIPSET S3 964
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+LINE #Option "ELSA_w2000pro"
+NOCLOCKPROBE
+
+NAME ELSA Winner 2000PRO-4
+CHIPSET S3 964
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+LINE #Option "ELSA_w2000pro"
+NOCLOCKPROBE
+
+NAME ELSA Winner 2000PRO/X-2
+CHIPSET S3 968
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+LINE #Option "sync_on_green"
+NOCLOCKPROBE
+
+NAME ELSA Winner 2000PRO/X-4
+CHIPSET S3 968
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+LINE #Option "sync_on_green"
+NOCLOCKPROBE
+
+NAME ELSA Winner 2000PRO/X-8
+CHIPSET S3 968
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+LINE #Option "sync_on_green"
+NOCLOCKPROBE
+
+NAME ELSA Winner 2000AVI
+CHIPSET S3 968
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+LINE #Option "sync_on_green"
+NOCLOCKPROBE
+
+NAME ELSA Gloria-4
+CHIPSET S3 968
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+LINE #Option "sync_on_green"
+NOCLOCKPROBE
+
+NAME ELSA Gloria-8
+CHIPSET S3 968
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+LINE #Option "sync_on_green"
+NOCLOCKPROBE
+
+NAME VideoLogic GrafixStar 700
+CHIPSET S3 968
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+NAME LeadTek WinFast S430
+CHIPSET S3 968
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+NAME WinFast S430
+SEE LeadTek WinFast S430
+
+NAME LeadTek WinFast S510
+CHIPSET S3 968
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+NAME WinFast S510
+SEE LeadTek WinFast S510
+
+# S3 928
+
+NAME S3 928 (generic)
+CHIPSET S3 928
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+
+NAME S3 86C928 (generic)
+SEE S3 928 (generic)
+
+NAME Actix Ultra
+CHIPSET S3 928
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC att20c490
+LINE #Option "dac_8_bit"
+
+NAME Diamond Stealth Pro
+CHIPSET S3 928
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+CLOCKCHIP icd2061a
+LINE #Ramdac "att20c490" # The Diamond RAMDAC is reportedly compatible for 15bpp
+LINE #Option "no_linear" # Some VLB machines may require this
+
+NAME ELSA Winner 1000VL
+CHIPSET S3 928
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+LINE # the following settings should be detected and set automatically by XF86_S3
+LINE # if the serial number of the ELSA card is printed correctly:
+LINE #ClockChip "icd2061a"
+LINE #Membase 0xf8000000
+
+NAME ELSA Winner 1000TwinBus
+SEE ELSA Winner 1000VL
+
+NAME ELSA Winner 2000
+SEE S3 928 (generic)
+
+NAME Miro Crystal 16S
+SEE S3 928 (generic)
+
+NAME SPEA/V7 Mercury
+CHIPSET S3 928
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+CLOCKCHIP sc11412
+LINE Option "spea_mercury"
+
+NAME STB Pegasus
+CHIPSET S3 928
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+RAMDAC bt485
+CLOCKCHIP icd2061a
+LINE Option "stb_pegasus"
+LINE #Option "sync_on_green"
+
+NAME Number Nine GXE Level 14/16
+CHIPSET S3 928
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+DACSPEED 200
+CLOCKCHIP icd2061a
+LINE Option "number_nine"
+LINE #Option "nolinear"
+LINE #Option "nomemaccess"
+
+NAME Number Nine GXE Level 10/11/12
+CHIPSET S3 928
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+CLOCKCHIP icd2061a
+LINE Option "number_nine"
+
+NAME 928Movie
+CHIPSET S3 928
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+CLOCKCHIP icd2595
+RAMDAC bt485
+LINE # pixel multiplexing not supported
+
+# S3 911/924
+
+NAME S3 911/924 (generic)
+CHIPSET S3 911/924
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+
+NAME S3 86C911 (generic)
+SEE S3 911/924 (generic)
+
+NAME S3 86C924 (generic)
+SEE S3 911/924 (generic)
+
+NAME Diamond Stealth VRAM
+CHIPSET S3 911/924
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+CLOCKCHIP icd2061a
+
+#NAME Orchid Fahrenheit 1280
+#SEE S3 911/924 (generic)
+
+NAME S3 924 with SC1148 DAC
+CHIPSET S3 924
+SERVER S3
+DRIVER vga
+UNSUPPORTED
+LINE #Probable clocks:
+LINE #Clocks 25.2 28.3 39.7 1.7 49.9 76.7 35.7 44
+LINE #Clocks 130.2 119.5 79.4 31.2 110.0 65.2 74.9 71.3
+
+# S3 ViRGE,/DX,/GX and ViRGE/VX
+
+NAME S3 ViRGE (old S3V server)
+CHIPSET S3 ViRGE
+SERVER S3V
+DRIVER s3virge
+NOCLOCKPROBE
+
+NAME S3 ViRGE (generic)
+CHIPSET S3 ViRGE
+SERVER SVGA
+DRIVER s3virge
+NOCLOCKPROBE
+LINE #Option "xaa_benchmark"
+LINE #Option "fifo_moderate"
+LINE #Option "pci_burst_on"
+LINE #Option "pci_retry"
+
+NAME S3 ViRGE/DX (generic)
+CHIPSET S3 ViRGE/DX
+SERVER SVGA
+DRIVER s3virge
+NOCLOCKPROBE
+LINE #Option "xaa_benchmark"
+LINE #Option "fifo_moderate"
+LINE #Option "pci_burst_on"
+LINE #Option "pci_retry"
+
+NAME S3 ViRGE/GX (generic)
+CHIPSET S3 ViRGE/GX
+SERVER SVGA
+DRIVER s3virge
+NOCLOCKPROBE
+LINE #Option "xaa_benchmark"
+LINE #Option "fifo_moderate"
+LINE #Option "pci_burst_on"
+LINE #Option "pci_retry"
+
+
+NAME S3 ViRGE/GX2 (generic)
+CHIPSET S3 ViRGE/GX2
+SERVER SVGA
+DRIVER s3virge
+NOCLOCKPROBE
+LINE #Option "xaa_benchmark"
+LINE #Option "fifo_moderate"
+LINE #Option "pci_burst_on"
+LINE #Option "pci_retry"
+
+NAME S3 ViRGE/MX (generic)
+CHIPSET S3 ViRGE/MX
+SERVER SVGA
+DRIVER s3virge
+NOCLOCKPROBE
+LINE #Option "lcd_center"
+LINE #Set_LCDClk <pixel_clock_for_LCD>
+LINE #Option "xaa_benchmark"
+LINE #Option "fifo_moderate"
+LINE #Option "pci_burst_on"
+LINE #Option "pci_retry"
+
+NAME S3 ViRGE/MX+ (generic)
+SEE S3 ViRGE/MX (generic)
+
+
+
+
+NAME S3 86C325 (generic)
+SEE S3 ViRGE (generic)
+
+NAME S3 86C375 (generic)
+SEE S3 ViRGE/DX (generic)
+
+NAME S3 86C385 (generic)
+SEE S3 ViRGE/GX (generic)
+
+NAME S3 86C357 (generic)
+SEE S3 ViRGE/GX2 (generic)
+
+NAME S3 86C260 (generic)
+SEE S3 ViRGE/MX (generic)
+
+NAME S3 86C280 (generic)
+SEE S3 ViRGE/MX+ (generic)
+
+
+NAME ELSA Victory 3D
+SEE S3 ViRGE (generic)
+
+NAME ELSA Victory 3DX
+SEE S3 ViRGE/DX (generic)
+
+NAME ELSA Winner 3000-S
+SEE S3 ViRGE (generic)
+
+NAME Number Nine Visual 9FX Reality 332
+SEE S3 ViRGE (generic)
+
+NAME Number Nine FX Motion 332
+SEE S3 ViRGE (generic)
+
+NAME Diamond Stealth 3D 2000
+SEE S3 ViRGE (generic)
+
+NAME Diamond Stealth 3D 2000 PRO
+SEE S3 ViRGE/DX (generic)
+
+NAME Diamond Multimedia Stealth 3D 2000
+SEE S3 ViRGE (generic)
+
+NAME Diamond Multimedia Stealth 3D 2000 PRO
+SEE S3 ViRGE/DX (generic)
+
+NAME Canopus Co. Power Window 3DV
+SEE S3 ViRGE (generic)
+
+NAME DataExpert DSV3325
+SEE S3 ViRGE (generic)
+
+NAME ExpertColor DSV3325
+SEE S3 ViRGE (generic)
+
+NAME DSV3325
+SEE S3 ViRGE (generic)
+
+NAME Hercules Terminator 64/3D
+SEE S3 ViRGE (generic)
+
+NAME Hercules Terminator 3D/DX
+SEE S3 ViRGE/DX (generic)
+
+NAME LeadTek WinFast 3D S600
+SEE S3 ViRGE (generic)
+
+NAME WinFast 3D S600
+SEE LeadTek WinFast 3D S600
+
+NAME LeadTek WinFast 3D S680
+SEE S3 ViRGE/GX2 (generic)
+
+NAME Miro MiroMedia 3D
+SEE S3 ViRGE (generic)
+
+NAME Orchid Technology Fahrenheit Video 3D
+SEE S3 ViRGE (generic)
+
+NAME STB Systems Powergraph 3D
+SEE S3 ViRGE (generic)
+
+NAME STB Nitro 3D
+CHIPSET S3 ViRGE/GX
+SEE S3 ViRGE/GX (generic)
+
+NAME MELCO WGP-VG4S
+LINE #DACSpeed 191 162 111 83
+LINE #SetMClck 75
+SEE S3 ViRGE (generic)
+
+
+
+NAME S3 ViRGE/VX (generic)
+CHIPSET S3 ViRGE/VX
+SERVER SVGA
+DRIVER s3virge
+NOCLOCKPROBE
+LINE #Option "xaa_benchmark"
+LINE #Option "fifo_moderate"
+LINE #Option "pci_burst_on"
+LINE #Option "pci_retry"
+
+
+NAME S3 86C988 (generic)
+SEE S3 ViRGE/VX (generic)
+
+NAME ELSA Winner 3000
+SEE S3 ViRGE/VX (generic)
+
+NAME ELSA Winner 3000-M-22
+SEE S3 ViRGE/VX (generic)
+
+NAME ELSA Winner 3000-L-42
+SEE S3 ViRGE/VX (generic)
+
+NAME ELSA Winner 2000AVI/3D
+SEE S3 ViRGE/VX (generic)
+
+NAME Diamond Stealth 3D 3000
+SEE S3 ViRGE/VX (generic)
+
+NAME STB Systems Velocity 3D
+SEE S3 ViRGE/VX (generic)
+
+NAME MELCO WGP-VX8
+SEE S3 ViRGE/VX (generic)
+
+NAME Diamond Stealth 3D 4000
+SEE S3 ViRGE/GX2 (generic)
+
+NAME Toshiba Tecra 750CDT
+SEE S3 ViRGE/MX (generic)
+
+NAME Toshiba Tecra 750DVD
+SEE S3 ViRGE/MX (generic)
+
+NAME Toshiba Tecra 540CDT
+SEE S3 ViRGE/MX (generic)
+
+NAME Toshiba Tecra 550CDT
+SEE S3 ViRGE/MX (generic)
+
+# currently unsupported S3
+
+NAME S3 86C365 (Trio3D)
+SEE Unsupported VGA compatible
+
+NAME S3 86C391 (Savage3D)
+SEE Unsupported VGA compatible
+
+NAME S3 Trio3D
+SEE Unsupported VGA compatible
+
+NAME S3 Savage3D
+SEE Unsupported VGA compatible
+
+
+
+# ET4000/ET6000
+
+NAME ET3000 (generic)
+CHIPSET ET3000
+SERVER SVGA
+DRIVER tseng
+
+NAME Genoa 5400
+SEE ET3000 (generic)
+
+NAME ET4000 (generic)
+CHIPSET ET4000
+SERVER SVGA
+DRIVER tseng
+
+NAME ET4000/W32 (generic)
+CHIPSET ET4000/W32
+SERVER W32
+DRIVER tseng
+
+NAME ET4000 W32i, W32p (generic)
+CHIPSET ET4000/W32(i/p)
+SERVER SVGA
+DRIVER tsemg
+LINE #Option "linear" # for linear mode at 8bpp
+LINE #Option "noaccel" # when problems with accelerator
+LINE #Option "power_saver" # enable VESA DPMS
+LINE #Option "fast_dram"
+LINE #Option "pci_retry" # faster, but problematic for ISA DMA
+LINE #Option "hibit_high" # see README.tseng -- most cards need this
+LINE #Option "hibit_low" # see README.tseng -- mostly for older ET4000 cards
+LINE #MemBase 0x3C00000 # when automatic MemBase detection doesn't work
+LINE # -- see README.tseng for more (important) information on MemBase
+
+NAME ET6000 (generic)
+CHIPSET ET6000
+SERVER SVGA
+DRIVER tseng
+NOCLOCKPROBE
+LINE #videoram 2304 # 2.25 MB, when memory probe is incorrect
+LINE #Option "linear" # for linear mode at 8bpp
+LINE #Option "noaccel" # when problems with accelerator
+LINE #Option "power_saver" # enable VESA DPMS
+LINE #Option "pci_retry" # faster, but problematic for ISA DMA
+LINE #Option "hw_cursor" # Use hardware cursor (see docs for limitations)
+LINE #Option "xaa_no_color_exp" # When text (or bitmap) is not rendered correctly
+
+NAME ET6100 (generic)
+CHIPSET ET6100
+SEE ET6000 (generic)
+
+NAME Diamond Stealth 32
+CLOCKCHIP icd2061a
+NOCLOCKPROBE
+SEE ET4000 W32i, W32p (generic)
+
+NAME Cardex Cobra
+SEE ET4000 W32i, W32p (generic)
+
+NAME Cardex Challenger (Pro)
+SEE ET4000 W32i, W32p (generic)
+
+NAME Colorgraphic Dual Lightning
+SEE ET4000 W32i, W32p (generic)
+
+NAME Dell onboard ET4000
+SEE ET4000 (generic)
+
+NAME DFI-WG5000
+SEE ET4000 W32i, W32p (generic)
+
+NAME Diamond SpeedStar (Plus)
+SEE ET4000 (generic)
+
+NAME Diamond SpeedStar 24
+SEE ET4000 (generic)
+
+NAME Diamond SpeedStar HiColor
+SEE ET4000 (generic)
+
+NAME Genoa 8900 Phantom 32i
+SEE ET4000 W32i, W32p (generic)
+
+NAME Hercules Dynamite
+SEE ET4000/W32 (generic)
+
+NAME Hercules Dynamite Power
+SEE ET4000 W32i, W32p (generic)
+
+NAME Hercules Dynamite Pro
+SEE ET4000 W32i, W32p (generic)
+
+NAME Integral FlashPoint
+SEE ET4000 W32i, W32p (generic)
+
+NAME LeadTek WinFast S200
+SEE ET4000 W32i, W32p (generic)
+
+NAME Matrox Comet
+SEE ET4000 W32i, W32p (generic)
+
+NAME Matrox Marvel II
+SEE ET4000 W32i, W32p (generic)
+
+NAME Miro MiroVideo 20TD
+SEE ET4000 W32i, W32p (generic)
+
+NAME WinFast S200
+SEE LeadTek WinFast S200
+
+NAME Sigma Concorde
+SEE ET4000/W32 (generic)
+
+NAME Sigma Legend
+SEE ET4000 (generic)
+
+NAME SPEA/V7 ShowTime Plus
+SEE ET4000 W32i, W32p (generic)
+
+NAME STB LightSpeed
+SEE ET4000 W32i, W32p (generic)
+
+NAME STB MVP-2
+SEE ET4000 (generic)
+
+NAME STB MVP-2 PCI
+SEE ET4000 W32i, W32p (generic)
+
+NAME STB MVP-2X
+SEE ET4000 W32i, W32p (generic)
+
+NAME STB MVP-4 PCI
+SEE ET4000 W32i, W32p (generic)
+
+NAME STB MVP-4X
+SEE ET4000 W32i, W32p (generic)
+
+NAME TechWorks Thunderbolt
+SEE ET4000/W32 (generic)
+
+NAME ViewTop PCI
+SEE ET4000 W32i, W32p (generic)
+
+NAME SNI PC5H W32
+CLOCKCHIP stg1703
+NOCLOCKPROBE
+SEE ET4000 W32i, W32p (generic)
+
+NAME SNI Scenic W32
+CLOCKCHIP stg1703
+NOCLOCKPROBE
+SEE ET4000 W32i, W32p (generic)
+
+NAME Hercules Dynamite 128/Video
+SEE ET6000 (generic)
+
+NAME STB LightSpeed 128
+SEE ET6000 (generic)
+
+NAME VideoLogic GrafixStar 600
+SEE ET6000 (generic)
+
+NAME Jazz Multimedia G-Force 128
+SEE ET6000 (generic)
+
+NAME Mirage Z-128
+SEE ET6000 (generic)
+
+NAME California Graphics SunTracer 6000
+SEE ET6000 (generic)
+
+NAME Binar Graphics AnyView
+SEE ET6000 (generic)
+
+NAME MediaVision Proaxcel 128
+SEE ET6000 (generic)
+
+NAME ATrend ATC-2165A
+SEE ET6000 (generic)
+
+NAME Interay PMC Viper
+SEE ET6000 (generic)
+
+2-the-Max MAXColor 6000
+SEE ET6000 (generic)
+
+Gainward Challenger EV
+SEE ET6000 (generic)
+
+MachSpeed VGA ET6000
+SEE ET6000 (generic)
+
+KouTech KeyVision 128 EV
+SEE ET6000 (generic)
+
+NAME Jaton Video-58P
+SEE ET6000 (generic)
+
+# ATI
+
+NAME ATI 8514 Ultra (no VGA)
+CHIPSET ATI-Mach8
+SERVER Mach8
+DRIVER vga
+UNSUPPORTED
+
+NAME ATI Graphics Ultra
+CHIPSET ATI-Mach8
+SERVER Mach8
+DRIVER vga
+UNSUPPORTED
+LINE #Probable clocks:
+LINE #Clocks 43 49 80 36 50 56 0 45 30 32 110 79 40 45 75 65
+LINE #Clocks 22 25 46 18 25 28 0 22 15 16 55 40 20 22 38 32
+
+NAME ATI Graphics Ultra Pro
+CHIPSET ATI-Mach32
+SERVER Mach32
+DRIVER vga
+UNSUPPORTED
+LINE #Probable clocks:
+LINE #Clocks 100 126 92 36 51 57 0 44 135 32 110 80 39
+LINE #Clocks 45 75 65 50 63 46 18 25 28 0 22 67 16 55 40 19 23 37 33
+LINE #Option "dac_8_bit"
+
+NAME ATI Wonder SVGA
+CHIPSET ATI vgawonder
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+LINE #probable clocks:
+LINE #Clocks 30 32 11 80 42 48 92 36 40 45 75 65 50 56 0 0
+LINE #Clocks 15 16 55 0 21 24 46 18 20 22 37 32 25 28 0 0
+
+NAME ATI Ultra Plus
+CHIPSET ATI-Mach32
+SERVER Mach32
+DRIVER vga
+UNSUPPORTED
+
+NAME ATI Mach32
+CHIPSET ATI-Mach32
+SERVER Mach32
+DRIVER vga
+UNSUPPORTED
+
+NAME ATI Mach64
+CHIPSET ATI-Mach64
+SERVER Mach64
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+NAME ATI Mach64 with ATI68860 RAMDAC
+LINE #Ramdac "ati68860"
+SEE ATI Mach64
+
+NAME ATI Mach64 with ATI68860B RAMDAC
+LINE #Ramdac "ati68860b"
+SEE ATI Mach64
+
+NAME ATI Mach64 with ATI68860C RAMDAC
+LINE #Ramdac "ati68860c"
+SEE ATI Mach64
+
+NAME ATI Mach64 with ATI68875 RAMDAC
+LINE #Ramdac "ati68875"
+SEE ATI Mach64
+
+NAME ATI Mach64 with AT&T 20C408 RAMDAC
+LINE #Ramdac "att20c408"
+SEE ATI Mach64
+
+NAME ATI Mach64 with CH8398 RAMDAC
+LINE #Ramdac "ch8398"
+SEE ATI Mach64
+
+NAME ATI Mach64 with IBM RGB514 RAMDAC
+LINE #Ramdac "ibm_rgb514"
+SEE ATI Mach64
+
+NAME ATI Mach64 with STG1702 RAMDAC
+LINE #Ramdac "stg1702"
+SEE ATI Mach64
+
+NAME ATI Mach64 with STG1703 RAMDAC
+LINE #Ramdac "stg1703"
+SEE ATI Mach64
+
+NAME ATI Mach64 with TLC34075 RAMDAC
+LINE #Ramdac "tlc34075"
+SEE ATI Mach64
+
+NAME ATI Mach64 with Internal RAMDAC
+SEE ATI Mach64
+
+NAME ATI Mach64 CT (264CT)
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI Mach64 VT (264VT)
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI Mach64 GT (264GT), aka 3D RAGE
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI Mach64 3D RAGE II
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI Mach64 3D RAGE II+DVD
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI Mach64 3D Rage IIC
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI Mach64 3D Rage Pro
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI 3D Pro Turbo
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI 3D Pro Turbo PC2TV
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI 3D Xpression
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI 3D Xpression+
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI 3D Xpression+ PC2TV
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI All-in-Wonder
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI All-in-Wonder Pro
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI Graphics Pro Turbo
+SEE ATI Mach64
+
+NAME ATI Graphics Pro Turbo with ATI68860 RAMDAC
+SEE ATI Mach64 with ATI68860 RAMDAC
+
+NAME ATI Graphics Pro Turbo with ATI68860B RAMDAC
+SEE ATI Mach64 with ATI68860B RAMDAC
+
+NAME ATI Graphics Pro Turbo with ATI68860C RAMDAC
+SEE ATI Mach64 with ATI68860C RAMDAC
+
+NAME ATI Graphics Pro Turbo with ATI68875 RAMDAC
+SEE ATI Mach64 with ATI68875 RAMDAC
+
+NAME ATI Graphics Pro Turbo with AT&T 20C408 RAMDAC
+SEE ATI Mach64 with AT&T 20C408 RAMDAC
+
+NAME ATI Graphics Pro Turbo with CH8398 RAMDAC
+SEE ATI Mach64 with CH8398 RAMDAC
+
+NAME ATI Graphics Pro Turbo with STG1702 RAMDAC
+SEE ATI Mach64 with STG1702 RAMDAC
+
+NAME ATI Graphics Pro Turbo with STG1703 RAMDAC
+SEE ATI Mach64 with STG1703 RAMDAC
+
+NAME ATI Graphics Pro Turbo with TLC34075 RAMDAC
+SEE ATI Mach64 with TLC34075 RAMDAC
+
+NAME ATI Graphics Pro Turbo 1600
+SEE ATI Mach64 with IBM RGB514 RAMDAC
+
+NAME ATI Graphics Xpression
+SEE ATI Mach64
+
+NAME ATI Graphics Xpression with ATI68860 RAMDAC
+SEE ATI Mach64 with ATI68860 RAMDAC
+
+NAME ATI Graphics Xpression with ATI68860B RAMDAC
+SEE ATI Mach64 with ATI68860B RAMDAC
+
+NAME ATI Graphics Xpression with ATI68860C RAMDAC
+SEE ATI Mach64 with ATI68860C RAMDAC
+
+NAME ATI Graphics Xpression with ATI68875 RAMDAC
+SEE ATI Mach64 with ATI68875 RAMDAC
+
+NAME ATI Graphics Xpression with AT&T 20C408 RAMDAC
+SEE ATI Mach64 with AT&T 20C408 RAMDAC
+
+NAME ATI Graphics Xpression with CH8398 RAMDAC
+SEE ATI Mach64 with CH8398 RAMDAC
+
+NAME ATI Graphics Xpression with STG1702 RAMDAC
+SEE ATI Mach64 with STG1702 RAMDAC
+
+NAME ATI Graphics Xpression with STG1703 RAMDAC
+SEE ATI Mach64 with STG1703 RAMDAC
+
+NAME ATI Graphics Xpression with TLC34075 RAMDAC
+SEE ATI Mach64 with TLC34075 RAMDAC
+
+NAME ATI Graphics Xpression with Mach64 CT (264CT)
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI Video Boost
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI Video Charger
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI Video Xpression
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI Video Xpression+
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI WinBoost
+SEE ATI Mach64
+
+NAME ATI WinBoost with ATI68860 RAMDAC
+SEE ATI Mach64 with ATI68860 RAMDAC
+
+NAME ATI WinBoost with ATI68860B RAMDAC
+SEE ATI Mach64 with ATI68860B RAMDAC
+
+NAME ATI WinBoost with ATI68860C RAMDAC
+SEE ATI Mach64 with ATI68860C RAMDAC
+
+NAME ATI WinBoost with ATI68875 RAMDAC
+SEE ATI Mach64 with ATI68875 RAMDAC
+
+NAME ATI WinBoost with AT&T 20C408 RAMDAC
+SEE ATI Mach64 with AT&T 20C408 RAMDAC
+
+NAME ATI WinBoost with CH8398 RAMDAC
+SEE ATI Mach64 with CH8398 RAMDAC
+
+NAME ATI WinBoost with STG1702 RAMDAC
+SEE ATI Mach64 with STG1702 RAMDAC
+
+NAME ATI WinBoost with STG1703 RAMDAC
+SEE ATI Mach64 with STG1703 RAMDAC
+
+NAME ATI WinBoost with TLC34075 RAMDAC
+SEE ATI Mach64 with TLC34075 RAMDAC
+
+NAME ATI WinBoost with Mach64 CT (264CT)
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI WinCharger
+SEE ATI Mach64
+
+NAME ATI WinCharger with ATI68860 RAMDAC
+SEE ATI Mach64 with ATI68860 RAMDAC
+
+NAME ATI WinCharger with ATI68860B RAMDAC
+SEE ATI Mach64 with ATI68860B RAMDAC
+
+NAME ATI WinCharger with ATI68860C RAMDAC
+SEE ATI Mach64 with ATI68860C RAMDAC
+
+NAME ATI WinCharger with ATI68875 RAMDAC
+SEE ATI Mach64 with ATI68875 RAMDAC
+
+NAME ATI WinCharger with AT&T 20C408 RAMDAC
+SEE ATI Mach64 with AT&T 20C408 RAMDAC
+
+NAME ATI WinCharger with CH8398 RAMDAC
+SEE ATI Mach64 with CH8398 RAMDAC
+
+NAME ATI WinCharger with STG1702 RAMDAC
+SEE ATI Mach64 with STG1702 RAMDAC
+
+NAME ATI WinCharger with STG1703 RAMDAC
+SEE ATI Mach64 with STG1703 RAMDAC
+
+NAME ATI WinCharger with TLC34075 RAMDAC
+SEE ATI Mach64 with TLC34075 RAMDAC
+
+NAME ATI WinCharger with Mach64 CT (264CT)
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI WinTurbo
+SEE ATI Mach64
+
+NAME ATI WinTurbo with ATI68860 RAMDAC
+SEE ATI Mach64 with ATI68860 RAMDAC
+
+NAME ATI WinTurbo with ATI68860B RAMDAC
+SEE ATI Mach64 with ATI68860B RAMDAC
+
+NAME ATI WinTurbo with ATI68860C RAMDAC
+SEE ATI Mach64 with ATI68860C RAMDAC
+
+NAME ATI WinTurbo with ATI68875 RAMDAC
+SEE ATI Mach64 with ATI68875 RAMDAC
+
+NAME ATI WinTurbo with AT&T 20C408 RAMDAC
+SEE ATI Mach64 with AT&T 20C408 RAMDAC
+
+NAME ATI WinTurbo with CH8398 RAMDAC
+SEE ATI Mach64 with CH8398 RAMDAC
+
+NAME ATI WinTurbo with STG1702 RAMDAC
+SEE ATI Mach64 with STG1702 RAMDAC
+
+NAME ATI WinTurbo with STG1703 RAMDAC
+SEE ATI Mach64 with STG1703 RAMDAC
+
+NAME ATI WinTurbo with TLC34075 RAMDAC
+SEE ATI Mach64 with TLC34075 RAMDAC
+
+NAME ATI WinTurbo with Mach64 CT (264CT)
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI Xpert 98
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI Xpert XL
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI Xpert@Play
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI Xpert@Play 98
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI Xpert@Work
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ATI integrated on Intel Maui MU440EX motherboard
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ASUS PCI-V264CT
+SEE ATI Mach64 with Internal RAMDAC
+
+NAME ASUS PCI-AV264CT
+SEE ATI Mach64 with Internal RAMDAC
+
+# AGX
+
+NAME AGX (generic)
+CHIPSET AGX-014/15/16
+SERVER AGX
+DRIVER vga
+UNSUPPORTED
+
+NAME Boca Vortex (Sierra RAMDAC)
+CHIPSET AGX-015
+SERVER AGX
+DRIVER vga
+UNSUPPORTED
+RAMDAC sc15025
+LINE Option "dac_8_bit"
+LINE Option "no_wait_state"
+LINE #Option "fifo_moderate" # 2x bus bw - may result in random pixels
+
+NAME EIZO (VRAM)
+SEE AGX (generic)
+
+NAME Orchid Celsius (AT&T RAMDAC)
+CHIPSET AGX-015
+SERVER AGX
+DRIVER vga
+UNSUPPORTED
+RAMDAC att20c490
+LINE Option "dac_8_bit"
+LINE Option "no_wait_state"
+LINE #Option "fifo_moderate" # 2x bus bw - may result in random pixels
+
+NAME Orchid Celsius (Sierra RAMDAC)
+CHIPSET AGX-015
+SERVER AGX
+DRIVER vga
+UNSUPPORTED
+RAMDAC sc15025
+LINE Option "dac_8_bit"
+LINE Option "no_wait_state"
+LINE #Option "fifo_moderate" # 2x bus bw - may result in random pixels
+
+
+NAME Spider Black Widow
+CHIPSET AGX-015
+SERVER AGX
+DRIVER vga
+UNSUPPORTED
+RAMDAC sc15025
+LINE Option "dac_8_bit"
+LINE Option "no_wait_state"
+LINE #Option "fifo_moderate" # 2x bus bw - may result in random pixels
+
+
+NAME Spider Black Widow Plus
+CHIPSET AGX-016
+SERVER AGX
+DRIVER vga
+UNSUPPORTED
+RAMDAC sc15025
+LINE Option "dac_8_bit"
+LINE Option "no_wait_state"
+LINE #Option "fifo_moderate" # 2x bus bw - may result in random pixels
+LINE #Option "fifo_aggressive" # 3x bus bw - may result in random pixels
+LINE #Probable clocks:
+LINE #Clocks 25.2 28.3 39.9 72.2 50.0 76.9 36.1 44.8
+LINE #Clocks 89.0 119.8 79.9 31.5 110.0 64.9 74.9 94.9
+
+NAME Hercules Graphite HG210
+CHIPSET AGX-014
+SERVER AGX
+DRIVER vga
+UNSUPPORTED
+RAMDAC bt482
+DACSPEED 85
+LINE Chipset "AGX-014"
+LINE Option "dac_8_bit"
+LINE Option "no_wait_state"
+LINE #Probable clocks:
+LINE #Clocks 25.0 28.0 32.0 36.0 40.0 45.0 50.0 65.0
+LINE #Clocks 70.0 75.0 80.0 85.0 90.0 95.0 100.0 110.0
+
+NAME Hercules Graphite Pro
+CHIPSET AGX-015
+SERVER AGX
+DRIVER vga
+UNSUPPORTED
+# Card specific DAC, doesn't appear in ramdac menu
+LINE Ramdac "herc_dual_dac"
+LINE Chipset "AGX-015"
+LINE Option "dac_8_bit"
+LINE Option "no_wait_state"
+LINE #Option "fifo_moderate" # 2x bus bw - may result in random pixels
+LINE #Probable clocks:
+LINE #Clocks 25.0 28.0 32.0 36.0 40.0 45.0 50.0 65.0
+LINE #Clocks 70.0 75.0 80.0 85.0 90.0 95.0 100.0 110.0
+
+NAME Hercules Graphite Power
+CHIPSET AGX-016
+SERVER AGX
+DRIVER vga
+UNSUPPORTED
+# Card specific DAC, doesn't appear in ramdac menu
+# The glue logic state machine for RAMDAC switching doesn't work as
+# documented, for now we're stuck with the small RAMDAC
+LINE Ramdac "herc_small_dac"
+LINE Chipset "AGX-016"
+LINE Option "dac_8_bit"
+LINE Option "no_wait_state"
+LINE #Option "fifo_moderate" # 2x bus bw - may result in random pixels
+LINE #Option "fifo_aggressive" # 3x bus bw - may result in random pixels
+LINE #Probable clocks:
+LINE #Clocks 25.0 28.0 32.0 36.0 40.0 45.0 50.0 65.0
+LINE #Clocks 70.0 75.0 80.0 85.0 90.0 95.0 100.0 110.0
+
+NAME XGA-2 (ISA bus)
+CHIPSET XGA-2
+SERVER AGX
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+LINE #Instance 7 # XGA instance 0-7
+LINE #COPbase 0xC8F00 # XGA memory-mapped register address
+LINE #POSbase 0 # Disable probing if above are specified
+
+NAME XGA-1 (ISA bus)
+CHIPSET XGA-1
+SERVER AGX
+DRIVER vga
+UNSUPPORTED
+LINE #Instance 7 # XGA instance 0-7
+LINE #COPbase 0xC8F00 # XGA memory-mapped register address
+LINE #POSbase 0 # Disable probing if above are specified
+
+# WD
+
+NAME Paradise/WD 90CXX
+CHIPSET WD90CXX
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME DFI-WG6000
+CHIPSET WD90C33
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME Diamond SpeedStar 24X (not fully supported)
+CHIPSET WD90C31
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME WD 90C24 (laptop)
+CHIPSET WD90C24
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+LINE #Chipset "wd90c24"
+LINE #Option "noaccel" # Use this if acceleration is causing problems
+LINE #Clocks 25.175 28.322 65 36 # These are not programmable
+LINE #Clocks 29.979 77.408 62.195 59.957 # These are programmable
+LINE #Clocks 31.5 35.501 75.166 50.114 # These are not programmable
+LINE #Clocks 39.822 72.038 44.744 80.092 # These are programmable
+LINE #Clocks 44.297 # Must match Mclk
+
+
+NAME WD 90C24A or 90C24A2 (laptop)
+CHIPSET WD90C24A
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+LINE #Chipset "wd90c24"
+LINE #Clocks 25.175 28.322 65 36 # These are not programmable
+LINE #Clocks 29.979 77.408 62.195 59.957 # These are programmable
+LINE #Clocks 31.5 35.501 75.166 50.114 # These are not programmable
+LINE #Clocks 39.822 72.038 44.744 80.092 # These are programmable
+LINE #Clocks 44.297 # Must match Mclk
+
+# Avance Logic
+
+NAME Avance Logic 2101
+CHIPSET Avance Logic
+LINE #chipset "al2101"
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME Avance Logic 2228
+CHIPSET Avance Logic
+LINE #chipset "ali2228"
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME Avance Logic 2301
+CHIPSET Avance Logic
+LINE #chipset "ali2301"
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME Avance Logic 2302
+CHIPSET Avance Logic
+LINE #chipset "ali2302"
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME Avance Logic 2308
+CHIPSET Avance Logic
+LINE #chipset "ali2308"
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME Avance Logic 2401
+CHIPSET Avance Logic
+LINE #chipset "ali2401"
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME Hercules Stingray
+CHIPSET ALG-2228/2301/2302
+LINE #chipset "ali2228"
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME SPEA/V7 Mirage VEGA Plus
+CHIPSET ALG-2228
+LINE #chipset "ali2228"
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+# ARK Logic
+
+NAME Ark Logic ARK1000PV (generic)
+CHIPSET ARK1000PV
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+# For now, treat the VL as a PV. This may be changed later
+NAME Ark Logic ARK1000VL (generic)
+CHIPSET ARK1000VL
+LINE Chipset "ark1000pv"
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME Ark Logic ARK2000PV (generic)
+CHIPSET ARK1000PV
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME Ark Logic ARK2000MT (generic)
+CHIPSET ARK1000MT
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME Hercules Stingray Pro
+SEE Ark Logic ARK1000PV (generic)
+
+NAME Hercules Stingray Pro/V
+SEE Ark Logic ARK1000PV (generic)
+
+NAME Ocean (octek) VL-VGA-1000
+RAMDAC att20c490
+SEE Ark Logic ARK1000VL (generic)
+
+NAME Hercules Stingray 64/V with ZoomDAC
+SEE Ark Logic ARK2000PV (generic)
+
+NAME Hercules Stingray 64/V with ICS5342
+CHIPSET ARK2000MT
+RAMDAC ics5342
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME Diamond Stealth64 Graphics 2001 series
+CHIPSET ARK2000PV
+RAMDAC ics5342
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+# Oak
+
+NAME Oak ISA Card (generic)
+CHIPSET Oak OTI-067/77
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME Oak 87 VLB (generic)
+CHIPSET Oak OTI-087
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+LINE Option "fifo_aggressive" # Comment this if you experience streaks.
+LINE Option "no_wait" # Comment this if you find problems.
+LINE #Option "enable_bitblt" # You may enable this and see if it works (see README.Oak file)
+
+NAME Oak 87 ISA (generic)
+CHIPSET Oak OTI-087
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+LINE Option "noaccel" # ISA cards seem to have Color Expansion support broken
+LINE #Option "enable_bitblt" # This should work on ISA, but lets not make it default just in case.
+
+NAME Paradise Accelerator Value
+SEE Oak 87 ISA (generic)
+
+# P9000
+
+NAME Diamond Viper VLB 2Mb
+CHIPSET Weitek 9000
+SERVER P9000
+DRIVER vga
+UNSUPPORTED
+LINE #Clocks must match the mode clocks (XFree86 3.1 P9000 server)
+LINE #Versions later than 3.1 do not require a clocks line
+LINE Chipset "vipervlb" # Required for some cards which autodetect as PCI
+LINE Videoram 2048 # Required
+LINE Membase 0x80000000 # Optional (0x80000000 is default)
+NOCLOCKPROBE
+
+NAME Diamond Viper PCI 2Mb
+CHIPSET Weitek 9000
+SERVER P9000
+DRIVER vga
+UNSUPPORTED
+LINE #Clocks must match the mode clocks (XFree86 3.1 P9000 server)
+LINE #Versions later than 3.1 do not require a clocks line
+LINE Videoram 2048 # Required
+LINE #Membase 0x80000000 # Use scanpci to get the correct Membase
+NOCLOCKPROBE
+
+NAME Orchid P9000 VLB
+CHIPSET Weitek 9000
+SERVER P9000
+DRIVER vga
+UNSUPPORTED
+LINE Chipset "orchid_p9000"
+LINE Membase 0xE0000000
+NOCLOCKPROBE
+
+# P9100
+
+NAME Weitek P9100 (generic)
+CHIPSET Weitek P9100
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+NAME Diamond Viper Pro Video
+SEE Weitek P9100 (generic)
+
+# Trident
+
+NAME Trident 8900/9000 (generic)
+CHIPSET TVGA8900/9000
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME Trident 8900D (generic)
+CHIPSET TVGA8900D
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME Trident TVGA9200CXr (generic)
+CHIPSET TVGA9200CXr
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+NAME Trident TGUI9400CXi (generic)
+CHIPSET TGUI9400CXi
+SERVER SVGA
+DRIVER trident
+
+NAME Trident TGUI9420DGi (generic)
+CHIPSET TGUI9420DGi
+SERVER SVGA
+DRIVER trident
+
+NAME Trident TGUI9430DGi (generic)
+CHIPSET TGUI9430DGi
+SERVER SVGA
+DRIVER trident
+
+NAME Trident TGUI9420 (generic)
+CHIPSET TGUI9420
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident TGUI9440 (generic)
+CHIPSET TGUI9440
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident TGUI9660 (generic)
+CHIPSET TGUI9660
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident TGUI9680 (generic)
+CHIPSET TGUI9680
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident TGUI9682 (generic)
+CHIPSET TGUI9682
+SERVER SVGA
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident TGUI9685 (generic)
+CHIPSET TGUI9685
+SERVER SVGA
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident Cyber 9320 (generic)
+CHIPSET Cyber9320
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident Cyber 9382 (generic)
+CHIPSET Cyber9382
+SERVER SVGA
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident Cyber 9385 (generic)
+CHIPSET Cyber9385
+SERVER SVGA
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident Cyber 9388 (generic)
+CHIPSET Cyber9388
+SERVER SVGA
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident Cyber 939a (generic)
+CHIPSET Cyber939a
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident Cyber 9397 (generic)
+CHIPSET Cyber9397
+SERVER SVGA
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident Cyber 9520 (generic)
+CHIPSET Cyber9520
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident 3DImage975 (generic)
+CHIPSET 3dimage975
+SERVER SVGA
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident 3DImage975 AGP (generic)
+CHIPSET 3dimage975
+SERVER SVGA
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident 3DImage985 (generic)
+CHIPSET 3dimage985
+SERVER SVGA
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident Providia 9682 (generic)
+CHIPSET Providia9682
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident Providia 9685 (generic)
+CHIPSET Providia9685
+DRIVER trident
+NOCLOCKPROBE
+
+NAME Trident TVGA 8800BR
+SEE Generic VGA compatible
+
+NAME Trident TVGA 8800CS
+SEE Generic VGA compatible
+
+# SiS
+
+NAME SiS 530
+CHIPSET SIS520
+DRIVER sis
+
+NAME SiS 620
+CHIPSET SIS620
+DRIVER sis
+
+NAME SiS SG86C201
+CHIPSET SIS86C201
+SERVER SVGA
+DRIVER sis
+
+NAME SiS SG86C205
+CHIPSET SIS86C205
+SERVER SVGA
+DRIVER sis
+LINE # Option "no_accel" # Use this if acceleration is causing problems
+LINE # Option "fifo_moderate"
+LINE # Option "fifo_conserv"
+LINE # Option "fifo_aggresive"
+NOCLOCKPROBE
+
+NAME SiS SG86C215
+CHIPSET SIS86C215
+SERVER SVGA
+DRIVER sis
+LINE # This is a cheap version of 86c205. I am not sure if acceleration works
+LINE # Option "no_accel" # Use this if acceleration is causing problems
+LINE # Option "no_BitBlt" # Use this if acceleration is causing problems
+LINE # Option "fifo_moderate"
+LINE # Option "fifo_conserv"
+LINE # Option "fifo_aggresive"
+NOCLOCKPROBE
+
+NAME SiS SG86C225
+CHIPSET SIS86C225
+SERVER SVGA
+DRIVER sis
+LINE # Option "no_accel" # Use this if acceleration is causing problems
+LINE # Option "fifo_moderate"
+LINE # Option "fifo_conserv"
+LINE # Option "fifo_aggresive"
+NOCLOCKPROBE
+
+NAME SiS 5597
+CHIPSET SiS5597
+SERVER SVGA
+DRIVER sis
+LINE # Option "no_accel" # Use this if acceleration is causing problems
+LINE # Option "fifo_moderate"
+LINE # Option "fifo_conserv"
+LINE # Option "fifo_aggresive"
+LINE # Option "fast_vram"
+LINE # Option "pci_burst_on"
+LINE # Option "xaa_benchmark" # DON'T use with "ext_eng_queue" !!!
+LINE # Option "ext_eng_queue" # Turbo-queue. This can cause drawing
+LINE # errors, but gives some accel
+NOCLOCKPROBE
+
+NAME SiS 5598
+CHIPSET SIS5598
+SERVER SVGA
+DRIVER sis
+LINE # Option "no_accel" # Use this if acceleration is causing problems
+LINE # Option "fifo_moderate"
+LINE # Option "fifo_conserv"
+LINE # Option "fifo_aggresive"
+LINE # Option "fast_vram"
+LINE # Option "pci_burst_on"
+LINE # Option "xaa_benchmark" # DON'T use with "ext_eng_queue" !!!
+LINE # Option "ext_eng_queue" # Turbo-queue. This can cause drawing
+LINE # errors, but gives some accel
+NOCLOCKPROBE
+
+NAME SiS 6326
+CHIPSET SiS6326
+SERVER SVGA
+DRIVER sis
+LINE # Option "no_accel" # Use this if acceleration is causing problems
+LINE # Option "fifo_moderate"
+LINE # Option "fifo_conserv"
+LINE # Option "fifo_aggresive"
+LINE # Option "fast_vram"
+LINE # Option "pci_burst_on"
+LINE # Option "xaa_benchmark" # DON'T use with "ext_eng_queue" !!!
+LINE # Option "ext_eng_queue" # Turbo-queue. This can cause drawing
+LINE # errors, but gives some accel
+NOCLOCKPROBE
+
+NAME MSI MS-4417
+SEE SiS 6326
+
+NAME SiS 3D PRO AGP
+SEE SiS 6326
+
+NAME Miro Crystal DVD
+SEE SiS 6326
+
+NAME PC-Chips M567 Mainboard
+SEE SiS 5597
+
+NAME Diamond SpeedStar A50
+SEE SiS 6326
+
+# Cyrix
+
+NAME MediaGX
+CHIPSET mediagx
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+# Alliance ProMotion
+
+NAME Alliance ProMotion 6422
+CHIPSET AP6422
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+
+# Number 9 I128
+
+NAME Number Nine Imagine I-128 (2-8MB)
+CHIPSET I128
+SERVER I128
+DRIVER vga
+UNSUPPORTED
+
+NAME Number Nine Imagine I-128 Series 2 (2-4MB)
+CHIPSET I128
+SERVER I128
+DRIVER vga
+UNSUPPORTED
+
+NAME Revolution 3D (T2R)
+CHIPSET I128
+SERVER I128
+DRIVER vga
+UNSUPPORTED
+
+NAME Number Nine Revolution 3D AGP (4-8MB SGRAM)
+CHIPSET I128
+SERVER I128
+DRIVER vga
+UNSUPPORTED
+
+NAME Number Nine Imagine-128-T2R
+CHIPSET I128
+SERVER I128
+DRIVER vga
+UNSUPPORTED
+
+# Matrox
+
+NAME Matrox Millennium 2MB
+CHIPSET mga2064w
+SERVER SVGA
+DRIVER mga
+LINE VideoRam 2048
+NOCLOCKPROBE
+
+NAME Matrox Millennium 4MB
+CHIPSET mga2064w
+SERVER SVGA
+DRIVER mga
+LINE VideoRam 4096
+NOCLOCKPROBE
+
+NAME Matrox Millennium 8MB
+CHIPSET mga2064w
+SERVER SVGA
+DRIVER mga
+LINE VideoRam 8192
+NOCLOCKPROBE
+
+NAME Matrox Millennium II 4MB
+CHIPSET mga2164w
+SERVER SVGA
+DRIVER mga
+LINE VideoRam 4096
+NOCLOCKPROBE
+
+NAME Matrox Millennium II 8MB
+CHIPSET mga2164w
+SERVER SVGA
+DRIVER mga
+LINE VideoRam 8192
+NOCLOCKPROBE
+
+NAME Matrox Millennium II 16MB
+CHIPSET mga2164w
+SERVER SVGA
+DRIVER mga
+LINE VideoRam 16384
+NOCLOCKPROBE
+
+NAME Matrox Millennium G200 4MB
+CHIPSET mgag200
+SERVER SVGA
+DRIVER mga
+LINE VideoRam 4096
+NOCLOCKPROBE
+
+NAME Matrox Millennium G200 8MB
+CHIPSET mgag200
+SERVER SVGA
+DRIVER mga
+LINE VideoRam 8192
+NOCLOCKPROBE
+
+NAME Matrox Millennium G200 16MB
+CHIPSET mgag200
+SERVER SVGA
+DRIVER mga
+LINE VideoRam 16384
+NOCLOCKPROBE
+
+NAME Matrox Millennium G200 SD 4MB
+CHIPSET mgag200
+SERVER SVGA
+DRIVER mga
+LINE VideoRam 4096
+LINE # Option "mga_sdram"
+NOCLOCKPROBE
+
+NAME Matrox Millennium G200 SD 8MB
+CHIPSET mgag200
+SERVER SVGA
+DRIVER mga
+LINE VideoRam 8192
+LINE # Option "mga_sdram"
+NOCLOCKPROBE
+
+NAME Matrox Millennium G200 SD 16MB
+CHIPSET mgag200
+SERVER SVGA
+DRIVER mga
+LINE VideoRam 16384
+LINE # Option "mga_sdram"
+NOCLOCKPROBE
+
+NAME Matrox Mystique
+CHIPSET mga1064sg
+SERVER SVGA
+DRIVER mga
+NOCLOCKPROBE
+
+NAME Matrox Mystique G200 4MB
+CHIPSET mgag200
+SERVER SVGA
+DRIVER mga
+LINE VideoRam 4096
+NOCLOCKPROBE
+
+NAME Matrox Mystique G200 8MB
+CHIPSET mgag200
+SERVER SVGA
+DRIVER mga
+LINE VideoRam 8192
+NOCLOCKPROBE
+
+NAME Matrox Mystique G200 16MB
+CHIPSET mgag200
+SERVER SVGA
+DRIVER mga
+LINE VideoRam 16384
+NOCLOCKPROBE
+
+NAME Matrox Productiva G100 4MB
+CHIPSET mgag100
+SERVER SVGA
+DRIVER mga
+LINE VideoRam 4096
+NOCLOCKPROBE
+
+NAME Matrox Productiva G100 8MB
+CHIPSET mgag100
+SERVER SVGA
+DRIVER mga
+LINE VideoRam 8192
+NOCLOCKPROBE
+
+# NVIDIA
+
+NAME Diamond Edge 3D
+CHIPSET nv1
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+NOCLOCKPROBE
+
+NAME RIVA128
+CHIPSET RIVA128
+SERVER SVGA
+DRIVER nv
+NOCLOCKPROBE
+
+NAME RIVA TNT
+CHIPSET RIVATNT
+SERVER SVGA
+DRIVER nv
+NOCLOCKPROBE
+
+NAME RIVA TNT2
+CHIPSET RIVATNT2
+SERVER SVGA
+DRIVER nv
+NOCLOCKPROBE
+
+NAME ELSA VICTORY ERAZOR
+SEE RIVA128
+
+NAME ELSA Winner 1000 R3D
+SEE RIVA128
+
+NAME ELSA ERAZOR II
+SEE RIVA TNT
+
+NAME Diamond Viper 330
+SEE RIVA128
+
+NAME Diamond Viper 550
+SEE RIVA TNT
+
+NAME Diamond Viper 770
+SEE RIVA TNT2
+
+NAME STB Velocity 128
+SEE RIVA128
+
+NAME STB nvidia 128
+SEE RIVA128
+
+NAME STB Velocity 4400
+SEE RIVATNT
+
+NAME ASUS 3Dexplorer
+SEE RIVA128
+
+NAME Guillemot Maxi Gamer Xentor
+SEE RIVATNT2
+
+NAME Guillemot Maxi Gamer Xentor 32
+SEE RIVATNT2
+
+NAME Creative Graphics Blaster TNT
+SEE RIVATNT
+
+NAME Creative Graphics Blaster TNT2
+SEE RIVATNT2
+
+# 3DLabs
+
+NAME ELSA GLoria-L/MX
+CHIPSET GLINT MX
+SERVER 3DLabs
+DRIVER glint
+LINE #Option "no_accel"
+NOCLOCKPROBE
+
+NAME ELSA GLoria-L
+CHIPSET GLINT 500TX
+SERVER 3DLabs
+DRIVER glint
+NOCLOCKPROBE
+
+NAME ELSA GLoria-XL
+CHIPSET GLINT MX
+SERVER 3DLabs
+DRIVER glint
+NOCLOCKPROBE
+
+NAME Diamond Fire GL 3000
+CHIPSET GLINT 500TX
+SERVER 3DLabs
+DRIVER glint
+LINE Option "firegl_3000"
+NOCLOCKPROBE
+
+NAME ELSA GLoria-S
+CHIPSET PERMEDIA
+SERVER 3DLabs
+DRIVER glint
+LINE #Option "no_accel"
+LINE #VideoRam 8192
+NOCLOCKPROBE
+
+NAME Diamond Fire GL 1000
+CHIPSET PERMEDIA
+SERVER 3DLabs
+DRIVER glint
+LINE #Option "no_accel"
+LINE #VideoRam 8192
+NOCLOCKPROBE
+
+NAME ELSA GLoria Synergy
+CHIPSET PERMEDIA 2
+SERVER 3DLabs
+DRIVER glint
+LINE #Option "no_accel"
+NOCLOCKPROBE
+
+NAME ELSA Winner 2000/Office
+CHIPSET PERMEDIA 2
+SERVER 3DLabs
+DRIVER glint
+LINE #Option "no_accel"
+NOCLOCKPROBE
+
+NAME Diamond Fire GL 1000 PRO
+CHIPSET PERMEDIA 2
+SERVER 3DLabs
+DRIVER glint
+LINE #Option "no_accel"
+NOCLOCKPROBE
+
+NAME Creative Blaster Exxtreme
+CHIPSET PERMEDIA 2
+SERVER 3DLabs
+DRIVER glint
+LINE #Option "no_accel"
+NOCLOCKPROBE
+
+NAME AccelStar Permedia II AGP
+CHIPSET PERMEDIA 2
+SERVER 3DLabs
+DRIVER glint
+LINE #Option "no_accel"
+NOCLOCKPROBE
+
+NAME Leadtek WinFast 2300
+CHIPSET PERMEDIA 2
+SERVER 3DLabs
+DRIVER glint
+NOCLOCKPROBE
+
+NAME 3DLabs Oxygen GMX
+CHIPSET PERMEDIA 2
+SERVER 3DLabs
+DRIVER glint
+LINE #Option "no_accel"
+NOCLOCKPROBE
+
+# Alliance Semiconductor
+
+NAME Diamond Stealth Video 2500
+CHIPSET Alliance AT24
+SERVER SVGA
+DRIVER apm
+NOCLOCKPROBE
+
+NAME AT3D
+CHIPSET Alliance AT3D
+SERVER SVGA
+DRIVER apm
+NOCLOCKPROBE
+LINE #Option "no_accel"
+
+NAME AT25
+SEE AT3D
+
+NAME Hercules Stingray 128 3D
+SEE AT3D
+
+# NeoMagic
+
+NAME NeoMagic (laptop/notebook)
+CHIPSET MagicGraph 128 series
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+LINE # Chipset "NM2160"
+LINE # IOBase 0xfea00000
+LINE # MemBase 0xfd000000
+LINE # VideoRam 2048
+LINE # DacSpeed 90
+LINE # Option "linear"
+LINE # Option "nolinear"
+LINE # Option "sw_cursor"
+LINE # Option "hw_cursor"
+LINE # Option "no_accel"
+LINE # Option "intern_disp"
+LINE # Option "extern_disp"
+LINE # Option "mmio"
+LINE # Option "no_mmio"
+LINE # Option "lcd_center"
+LINE # Option "no_stretch"
+
+# Epson SPC8110
+
+NAME EPSON SPC8110 (CardPC)
+CHIPSET SPC8110
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+LINE # Chipset "spc8110"
+LINE # MemBase 0x03e00000
+LINE # VideoRam 1024
+LINE # Option "nolinear"
+LINE # Option "sw_cursor"
+LINE # Option "noaccel"
+LINE # Option "fifo_moderate"
+LINE # Option "fifo_conservative"
+
+# Rendition
+
+NAME Rendition Verite 1000
+CHIPSET Verite 1000
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+LINE # Option "sw_cursor"
+
+NAME Rendition Verite 2x00
+CHIPSET Verite 2x00
+SERVER SVGA
+DRIVER vga
+UNSUPPORTED
+LINE # Option "sw_cursor"
+
+NAME Creative Labs 3D Blaster PCI (Verite 1000)
+SEE Rendition Verite 1000
+
+NAME Canopus Total-3D
+SEE Rendition Verite 1000
+
+NAME Sierra Screaming 3D
+SEE Rendition Verite 1000
+
+NAME Miro CRYSTAL VRX
+SEE Rendition Verite 1000
+
+NAME Diamond Stealth II S220
+CHIPSET Verite 2100
+SEE Rendition Verite 2x00
+
+NAME Hercules Thriller3D
+CHIPSET Verite 2200
+SEE Rendition Verite 2x00
+
+# Digital
+
+NAME Digital 8-plane TGA (UDB/Multia)
+CHIPSET TGA
+SERVER TGA
+DRIVER tga
+RAMDAC Bt485
+
+NAME Digital 8-plane TGA (ZLXp-E1)
+CHIPSET TGA
+SERVER TGA
+DRIVER tga
+RAMDAC Bt485
+
+NAME Digital 24-plane TGA (ZLXp-E2)
+CHIPSET TGA
+SERVER TGA
+DRIVER tga
+RAMDAC Bt463
+
+NAME Digital 24-plane+3D TGA (ZLXp-E3)
+CHIPSET TGA
+SERVER TGA
+DRIVER tga
+RAMDAC Bt463
+
+# Misc
+
+END
diff --git a/xc/programs/Xserver/hw/xfree86/xf86config/Cards98 b/xc/programs/Xserver/hw/xfree86/xf86config/Cards98
new file mode 100644
index 000000000..cfd96dc16
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf86config/Cards98
@@ -0,0 +1,647 @@
+# $XFree86: xc/programs/Xserver/hw/xfree86/xf86config/Cards98,v 1.1 1999/07/11 10:50:41 dawes Exp $
+#
+#
+#
+# $XConsortium: Cards /main/27 1996/10/28 05:43:53 kaleb $
+# This is the database of card definitions used by xf86config.
+# Each definition should have a NAME entry, CHIPSET (descriptive) and
+# SERVER (one of EGC, GANBWAP, PEGC, NKVNEC, WABS, WABEP, WSNA, TGUI,
+# MGA, SVGA, NECS3, PWSKB, PWLB, GA968).
+# A reference to another definition is made with SEE (already defined
+# entries are not overridden).
+# Optional entries are RAMDAC (identifier), CLOCKCHIP (identifier),
+# DACSPEED, NOCLOCKPROBE (advises never to probe clocks), UNSUPPORTED
+# (indicates card that is not yet properly supported by a dedicated
+# server). A LINE entry adds a line of text to be included in the
+# Device section (can include options or comments).
+# There's no CLOCKS option (although a Clocks line can be included
+# with LINE), as it is very undesirable to have a Clocks line that
+# is incorrect. The idea is that the Clocks are probed for to be
+# sure (a commented suggested Clocks line can be included).
+#
+# The majority of entries are just a binding of a model name to a
+# chipset/server and untested.
+#
+
+# EGC
+
+NAME EGC16
+CHIPSET EGC
+SERVER EGC
+LINE Chipset "vga"
+
+# PEGC
+
+NAME PEGC
+CHIPSET PEGC
+SERVER PEGC
+LINE VideoRam 512
+LINE Clocks 31.5
+LINE # Virtual resolution for 640x400
+LINE # Clocks 28.322
+
+# GANBWAP
+
+NAME GA-98NBI
+CHIPSET CL-GD5434
+SERVER GANBWAP
+LINE ClockChip "cirrus"
+LINE Option "ga98nb1"
+LINE Option "no_mmio"
+LINE # Option "sw_cursor"
+
+NAME GA-98NBII
+CHIPSET CL-GD5434
+SERVER GANBWAP
+LINE ClockChip "cirrus"
+LINE Option "ga98nb2"
+LINE Option "no_mmio"
+LINE # Option "sw_cursor"
+
+NAME GA-98NBIV
+CHIPSET CL-GD5434
+SERVER GANBWAP
+LINE ClockChip "cirrus"
+LINE Option "ga98nb4"
+LINE Option "no_mmio"
+LINE # Option "sw_cursor"
+
+NAME WAP-2000/4000
+CHIPSET CL-GD5434
+SERVER GANBWAP
+LINE Option "wap"
+LINE Option "no_mmio"
+LINE # Option "epsonmemwin"
+
+# NKVNEC
+
+NAME PCNKV/PCNKV2/NEC_CIRRUS
+CHIPSET CL-GD5428/5429/5430
+SERVER NKVNEC
+LINE # Option "fast_dram"
+LINE VideoRam 1024
+
+NAME PC9821Bf/U8W
+LINE Option "nec_cirrus"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Bp/U8W/U7W
+LINE Option "nec_cirrus"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Bs/U7W
+LINE Option "nec_cirrus"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Be/U7W
+LINE Option "nec_cirrus"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821BA3/U2/W
+LINE Option "nec_cirrus"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821BX3/U2/W
+LINE Option "nec_cirrus"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821BX4/U2
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Cb
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Ce
+LINE Option "nec_cirrus"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Cf
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Ce2
+LINE Option "nec_cirrus"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Cs
+LINE Option "nec_cirrus"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Cs2
+LINE Option "nec_cirrus"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Cx
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Cx2
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Es
+LINE Option "nec_cirrus"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Nd
+LINE Option "nec_cirrus"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Ne2
+LINE Option "nec_cirrus"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Nf
+LINE Option "nec_cirrus"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Np
+LINE Option "nec_cirrus"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Ns
+LINE Option "nec_cirrus"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821V7/C
+LINE Chipset "clgd5430"
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821V10/C,S
+LINE Chipset "clgd5430"
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821V12/S
+LINE Chipset "clgd5430"
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821V13/S
+LINE Chipset "clgd5430"
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821V16/S
+LINE Chipset "clgd5430"
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821V16/S5V,P
+LINE Chipset "clgd5446"
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821V20/S7
+LINE Chipset "clgd5430"
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Xb10
+LINE Chipset "clgd5430"
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Xc13/S5
+LINE Chipset "clgd5446"
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Xc16/M,S
+LINE Chipset "clgd5446"
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Xc200/M,S
+LINE Chipset "clgd5446"
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Xa7e
+LINE Chipset "clgd5430"
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Xe
+LINE Chipset "clgd5430"
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC9821Xe10
+LINE Chipset "clgd5430"
+LINE Option "nec_cirrus"
+LINE Option "no_mmio"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC486MR
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC486MS
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC486MU
+LINE Chipset "clgd5429"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC486MV
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC586MV
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+NAME PC586RV
+LINE Chipset "clgd5429"
+SEE PCNKV/PCNKV2/NEC_CIRRUS
+
+# WABS
+
+NAME WAB-S
+CHIPSET CL-GD5426/5428
+SERVER WABS
+LINE VideoRam 1024
+LINE # VideoRam 2048
+
+NAME WAB-1000/2000
+CHIPSET CL-GD5428
+SERVER WABS
+LINE VideoRam 1024
+LINE # VideoRam 2048
+
+NAME WSR-E/G
+SEE WAB-1000/2000
+
+# WABEP
+
+NAME WAB-EP
+CHIPSET CL-GD5428
+SERVER WABEP
+LINE Option "med_dram"
+
+# WSNA
+
+NAME WSN-A2F
+CHIPSET CL-GD5434
+SERVER WSNA
+LINE Option "no_mmio"
+LINE Option "med_dram"
+
+# TGUI
+
+NAME NEC Trident
+CHIPSET TGUI9680/9682
+SERVER TGUI
+LINE Option "xaa_no_color_exp"
+LINE # Option "noaccel"
+LINE # Option "Linear"
+LINE # Option "med_dram"
+LINE # Option "hw_cursor"
+
+NAME PC9821Ra20/N
+SEE NEC Trident
+
+NAME PC9821RaII23/N,W
+SEE NEC Trident
+
+NAME PC9821Ra266/N,W
+SEE NEC Trident
+
+NAME PC9821Rs20/B20
+SEE NEC Trident
+
+NAME PC9821RsII26/B40
+SEE NEC Trident
+
+NAME PC9821V13/M7
+SEE NEC Trident
+
+NAME PC9821V16/M7
+SEE NEC Trident
+
+NAME PC9821V20/M7
+SEE NEC Trident
+
+NAME PC9821Xa7/C,K
+SEE NEC Trident
+
+NAME PC9821Xa9/C,K
+SEE NEC Trident
+
+NAME PC9821Xa10/C,K
+SEE NEC Trident
+
+NAME PC9821Xa12/C,K
+SEE NEC Trident
+
+NAME PC9821Xa13/C,K,W
+SEE NEC Trident
+
+NAME PC9821Xa16/R,W
+SEE NEC Trident
+
+NAME PC9821Xa20/W
+SEE NEC Trident
+
+NAME PC9821Xc13/M,S
+SEE NEC Trident
+
+NAME PC9821Xv13/R
+SEE NEC Trident
+
+NAME GA-DRV/98
+CHIPSET TGUI9680
+SERVER TGUI
+LINE Option "noaccel"
+LINE # Option "med_dram"
+LINE # Option "hw_cursor"
+
+# MGA
+
+NAME MGA Millennium
+CHIPSET MGA2064W
+SERVER MGA
+
+NAME PC9821Xt13
+SEE MGA Millennium
+
+NAME PC9821Xt16
+SEE MGA Millennium
+
+NAME PC9821Xv13/W
+SEE MGA Millennium
+
+NAME PC9821Xv20/W
+SEE MGA Millennium
+
+NAME PC9821St15
+SEE MGA Millennium
+
+NAME PC9821St20
+SEE MGA Millennium
+
+NAME PC9821RvII26/N20
+SEE MGA Millennium
+
+NAME NEC FC-WAB-X2
+SEE MGA Millennium
+
+NAME MGA Mystique
+CHIPSET MGA1064SG
+SERVER MGA
+
+NAME PC9821V166/S
+LINE VideoRam 2048
+SEE MGA Mystique
+
+NAME PC9821V200/S
+LINE VideoRam 2048
+SEE MGA Mystique
+
+NAME PC9821V200/M
+LINE VideoRam 4096
+SEE MGA Mystique
+
+NAME PC9821V233/M7
+LINE VideoRam 2048
+SEE MGA Mystique
+
+NAME PC9821V233/M7V
+LINE VideoRam 4096
+SEE MGA Mystique
+
+# SVGA
+
+NAME NEC Cirrus 755x
+CHIPSET CL-GD7555
+LINE Chipset "clgd7555"
+LINE # VideoRam 2048
+LINE # Option "no_bitblt"
+LINE # Option "fast_dram"
+LINE Option "linear"
+LINE Option "noaccel"
+SERVER SVGA
+
+NAME PC9821Nr12
+SEE NEC Cirrus 755x
+
+NAME PC9821Nr13
+SEE NEC Cirrus 755x
+
+NAME PC9821La13
+SEE NEC Cirrus 755x
+
+NAME PC9821Ls12
+SEE NEC Cirrus 755x
+
+NAME PC9821Ls13
+SEE NEC Cirrus 755x
+
+NAME PC9821Ls150
+SEE NEC Cirrus 755x
+
+# NECS3
+
+NAME NEC WAB-A/B
+CHIPSET S3 928
+SERVER NECS3
+LINE Chipset "s3_generic"
+LINE Dacspeed 110
+LINE Ramdac "sc15025"
+LINE Option "dac_8_bit"
+LINE # Option "necwab"
+LINE # Option "nomemaccess"
+LINE Clocks 25.0 28.0 40.0 0.0 50.0 77.0 36.0 45.0
+LINE Clocks 130.0 120.0 80.0 31.0 110.0 65.0 75.0 94.0
+
+NAME NEC FC-WAB-A/B
+CHIPSET S3 928
+SERVER NECS3
+LINE Chipset "s3_generic"
+LINE Dacspeed 110
+LINE Ramdac "bt485"
+LINE Option "necwab"
+LINE Option "nomemaccess"
+LINE Option "noinit"
+LINE Option "nolinear"
+LINE Clocks 25.0 28.0 40.0 0.0 50.0 77.0 36.0 45.0
+LINE Clocks 130.0 120.0 80.0 31.0 110.0 65.0 75.0 94.0
+
+NAME PC9821Af/U9W E09?
+SEE NEC WAB-A/B
+
+NAME PC9821An/U8W
+SEE NEC WAB-A/B
+
+NAME PC9821Ap2/U8W/C9W
+SEE NEC WAB-A/B
+
+NAME PC9821As2/U7W/U8W
+SEE NEC WAB-A/B
+
+NAME NEC 864
+CHIPSET S3 864
+SERVER NECS3
+LINE Chipset "s3_generic"
+LINE Option "necwab"
+LINE Ramdac "s3_sdac"
+LINE ClockChip "s3_sdac"
+
+NAME PC9821Ap3
+SEE NEC 864
+
+NAME PC9821As3
+SEE NEC 864
+
+NAME PC9821Xp
+SEE NEC 864
+
+NAME PC9821Xs
+SEE NEC 864
+
+# PWSKB
+
+NAME PowerWindow 928/801
+CHIPSET S3 928
+SERVER PWSKB
+LINE Chipset "s3_generic"
+LINE # Chipset "mmio_928"
+LINE Ramdac "sc15025"
+LINE Dacspeed 110
+LINE Option "dac_8_bit"
+LINE # Option "epsonmemwin"
+LINE # Option "nomemaccess"
+LINE ClockChip "icd2061a"
+
+NAME PowerWindow 928II
+CHIPSET S3 928
+SERVER PWSKB
+LINE Chipset "s3_generic"
+LINE # Chipset "mmio_928"
+LINE Ramdac "att20c505"
+LINE # Ramdac "bt485"
+LINE Dacspeed 110
+LINE Option "dac_8_bit"
+LINE # Option "pw_mux"
+LINE Option "bt485_curs"
+LINE # Option "epsonmemwin"
+LINE # Option "nomemaccess"
+LINE ClockChip "icd2061a"
+
+NAME PowerWindow 805i
+CHIPSET S3 805
+SERVER PWSKB
+LINE Chipset "s3_generic"
+LINE Ramdac "s3gendac"
+LINE Dacspeed 110
+LINE Option "dac_8_bit"
+LINE # Option "pw805i"
+LINE # Option "epsonmemwin"
+LINE # Option "nomemaccess"
+LINE ClockChip "s3_sdac"
+
+NAME PowerWindow 928G
+CHIPSET S3 928
+SERVER PWSKB
+LINE Chipset "s3_generic"
+LINE # Chipset "mmio_928"
+LINE Ramdac "sc15025"
+LINE Dacspeed 110
+LINE Option "dac_8_bit"
+LINE # Option "nomemaccess"
+LINE # Option "nolinear"
+LINE ClockChip "icd2061a"
+
+NAME PCSKB/PCSKB2
+CHIPSET S3 911/924
+SERVER PWSKB
+LINE Chipset "s3_generic"
+LINE Ramdac "sc15025"
+LINE Dacspeed 110
+LINE Option "dac_8_bit"
+LINE # Option "nomemaccess"
+LINE Option "pcskb"
+LINE Clocks 25.0 28.0 40.0 0.0 50.0 77.0 36.0 45.0
+LINE Clocks 130.0 120.0 80.0 31.0 110.0 65.0 75.0 94.0
+
+NAME PCSKB3/PCSKB4/PCPKB4
+CHIPSET S3 928
+SERVER PWSKB
+LINE Chipset "s3_generic"
+LINE Ramdac "sc15025"
+LINE # Ramdac "att20c498"
+LINE Dacspeed 110
+LINE Option "dac_8_bit"
+LINE Option "nomemaccess"
+LINE Option "pcskb4"
+LINE Clocks 25.0 28.0 40.0 0.0 50.0 77.0 36.0 45.0
+LINE Clocks 130.0 120.0 80.0 31.0 110.0 65.0 75.0 94.0
+
+# PWLB
+
+NAME PowerWindow 928GLB
+CHIPSET S3 928
+SERVER PWLB
+LINE Chipset "s3_generic"
+LINE # Chipset "mmio_928"
+LINE Ramdac "sc15025"
+LINE Dacspeed 110
+LINE Option "dac_8_bit"
+LINE # Option "pw_localbus"
+LINE # Option "nomemaccess"
+LINE # Option "nolinear"
+LINE ClockChip "icd2061a"
+
+NAME PowerWindow 928IILB
+CHIPSET S3 928
+SERVER PWLB
+LINE Chipset "s3_generic"
+LINE # Chipset "mmio_928"
+LINE Ramdac "att20c505"
+LINE # Ramdac "bt485"
+LINE Dacspeed 110
+LINE Option "dac_8_bit"
+LINE Option "bt485_curs"
+LINE Option "pw_localbus"
+LINE # Option "pw_mux"
+LINE # Option "nomemaccess"
+LINE # Option "nolinear"
+LINE ClockChip "icd2061a"
+
+NAME PowerWindow 964LB
+CHIPSET S3 964
+SERVER PWLB
+LINE Chipset "s3_generic"
+LINE Option "pw_localbus"
+LINE Option "number_nine"
+LINE Ramdac "ti3025"
+LINE ClockChip "ti3025"
+LINE VideoRam 4096
+
+# GA968
+
+NAME GA-968V4/PCI
+CHIPSET S3 968
+SERVER GA968
+LINE Chipset "s3_generic"
+LINE # Chipset "mmio_928"
+LINE VideoRam 4096
diff --git a/xc/programs/Xserver/hw/xfree86/xf86config/Imakefile b/xc/programs/Xserver/hw/xfree86/xf86config/Imakefile
new file mode 100644
index 000000000..c2d16b3ac
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf86config/Imakefile
@@ -0,0 +1,23 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/xf86config/Imakefile,v 3.6 1996/12/23 07:04:41 dawes Exp $
+
+
+
+
+
+XCOMM $XConsortium: Imakefile /main/5 1996/02/21 18:12:46 kaleb $
+
+ SRCS = xf86config.c cards.c
+ OBJS = xf86config.o cards.o
+ LOCAL_LIBRARIES =
+ DEPLIBS =
+ CARDDBFILE = $(LIBDIR)/Cards
+ DEFINES = -DCARD_DATABASE_FILE='"$(CARDDBFILE)"'
+
+AllTarget(ProgramTargetName(xf86config))
+
+NormalProgramTarget(xf86config,$(OBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),NullParameter)
+InstallProgram(xf86config,$(BINDIR))
+DependTarget()
+
+InstallNonExecFile(Cards,$(LIBDIR))
+InstallManPageLong(xf86conf,$(MANDIR),xf86config)
diff --git a/xc/programs/Xserver/hw/xfree86/xf86config/cards.c b/xc/programs/Xserver/hw/xfree86/xf86config/cards.c
new file mode 100644
index 000000000..8c8c7f1df
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf86config/cards.c
@@ -0,0 +1,292 @@
+/* $XConsortium: cards.c /main/9 1996/10/19 18:15:32 kaleb $ */
+
+
+
+
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf86config/cards.c,v 3.15 1999/07/05 12:12:05 dawes Exp $ */
+
+/*
+ * Functions to manipulate card database.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "cards.h"
+
+/*
+ * Database format:
+ *
+ * NAME <name of card>
+ * CHIPSET <chipset description>
+ * SERVER <server name>
+ * DRIVER <driver name>
+ *
+ * Optional keywords:
+ * RAMDAC <ramdac identifier>
+ * CLOCKCHIP <clockchip identifier>
+ * DACSPEED <dacspeed>
+ * NOCLOCKPROBE
+ * UNSUPPORTED
+ *
+ * SEE <name of card> refers to another card definition; parameters that
+ * are already defined are not overridden.
+ *
+ * <server name> is one of Mono, VGA16, SVGA, S3, Mach32, Mach8, 8514,
+ * P9000, AGX, W32.
+ *
+ * A useful additional keywords may be CLOCKS.
+ */
+
+
+
+/* Database vars. */
+
+int lastcard;
+
+Card card[MAX_CARDS];
+
+
+static int
+getnextline(FILE *f, char *l)
+{
+ if (fgets(l, 128, f) == NULL)
+ return -1;
+#ifdef __EMX__
+ {
+ char *p = strchr(l,'\r');
+ if (p) {
+ *p = '\n';
+ *(p+1) = '\0';
+ }
+ }
+#endif
+ return 0;
+}
+
+static void
+appendstring(char **destp, char *src)
+{
+ char *newstr;
+ newstr = malloc(strlen(*destp) + strlen(src) + 1);
+ strcpy(newstr, *destp);
+ strcat(newstr, src);
+ if (strlen(*destp) > 0)
+ free(*destp);
+ *destp = newstr;
+}
+
+int
+lookupcard(char *name) {
+ int i;
+ for (i = 0; i <= lastcard; i++)
+ if (strcmp(name, card[i].name) == 0)
+ return i;
+ return -1;
+}
+
+static char *s3_comment =
+"# Use Option \"nolinear\" if the server doesn't start up correctly\n"
+"# (this avoids the linear framebuffer probe). If that fails try\n"
+"# option \"nomemaccess\".\n"
+"#\n"
+"# Refer to /usr/X11R6/lib/doc/README.S3, and the XF86_S3 man page.\n";
+
+static char *cirrus_comment =
+"# Use Option \"no_bitblt\" if you have graphics problems. If that fails\n"
+"# try Option \"noaccel\".\n"
+"# Refer to /usr/X11R6/lib/doc/README.cirrus.\n"
+"# To allow linear addressing, uncomment the Option line and the\n"
+"# address that the card maps the framebuffer to.\n";
+
+int parse_database() {
+ FILE *f;
+ char buf[128];
+ int i, lineno;
+ char filename[128];
+
+#ifndef __EMX__
+ strcpy(filename, CARD_DATABASE_FILE);
+#else
+ strcpy(filename, (char*)__XOS2RedirRoot(CARD_DATABASE_FILE));
+#endif
+ f = fopen(filename, "r");
+ if (f == NULL)
+ return -1;
+
+ lastcard = -1;
+ lineno = 0;
+
+ for (;;) {
+ if (getnextline(f, buf))
+ break;
+ lineno++;
+ if (buf[0] == '#')
+ /* Comment. */
+ continue;
+ if (strncmp(buf, "END", 3) == 0)
+ /* End of database. */
+ break;
+ if (strncmp(buf, "LINE", 4) == 0 && lastcard>=0) {
+ /* Line of Device comment. */
+ /* Append to existing lines. */
+ appendstring(&card[lastcard].lines, buf + 5);
+ continue;
+ }
+ /*
+ * The following keywords require the trailing newline
+ * to be deleted.
+ */
+ i = strlen(buf);
+ buf[--i] = '\0';
+
+ /* remove trailing spaces or tabs */
+ for(--i; i>=0 && (buf[i] == ' ' || buf[i] == '\011'); i--) ;
+ if (i>=0)
+ buf[i+1] = '\0';
+ else
+ continue; /* skip empty lines */
+
+ if (strncmp(buf, "NAME", 4) == 0) {
+ /* New entry. */
+ lastcard++;
+ card[lastcard].name = malloc(strlen(buf + 5) + 1);
+ strcpy(card[lastcard].name, buf + 5);
+ card[lastcard].chipset = NULL;
+ card[lastcard].server = NULL;
+ card[lastcard].driver = NULL;
+ card[lastcard].ramdac = NULL;
+ card[lastcard].clockchip = NULL;
+ card[lastcard].dacspeed = NULL;
+ card[lastcard].flags = 0;
+ card[lastcard].lines = "";
+ continue;
+ }
+ if (lastcard < 0) /* no NAME line found yet */
+ continue;
+ if (strncmp(buf, "SEE", 3) == 0) {
+ /* Reference to another entry. */
+ int i;
+ i = lookupcard(buf + 4);
+ if (i == -1) {
+ printf("Error in database, invalid reference: %s.\n",
+ buf + 4);
+ free(card[lastcard].name);
+ lastcard--;
+ continue;
+ }
+ if (card[lastcard].chipset == NULL)
+ card[lastcard].chipset = card[i].chipset;
+ if (card[lastcard].server == NULL)
+ card[lastcard].server = card[i].server;
+ if (card[lastcard].driver == NULL)
+ card[lastcard].driver = card[i].driver;
+ if (card[lastcard].ramdac == NULL)
+ card[lastcard].ramdac = card[i].ramdac;
+ if (card[lastcard].clockchip == NULL)
+ card[lastcard].clockchip = card[i].clockchip;
+ if (card[lastcard].dacspeed == NULL)
+ card[lastcard].dacspeed = card[i].dacspeed;
+ card[lastcard].flags |= card[i].flags;
+ appendstring(&card[lastcard].lines, card[i].lines);
+ continue;
+ }
+ if (strncmp(buf, "CHIPSET", 7) == 0) {
+ /* Chipset description. */
+ card[lastcard].chipset = malloc(strlen(buf + 8) + 1);
+ strcpy(card[lastcard].chipset, buf + 8);
+ continue;
+ }
+ if (strncmp(buf, "SERVER", 6) == 0) {
+ /* Server identifier. */
+ card[lastcard].server = malloc(strlen(buf + 7) + 1);
+ strcpy(card[lastcard].server, buf + 7);
+ continue;
+ }
+ if (strncmp(buf, "DRIVER", 6) == 0) {
+ /* Driver identifier. */
+ card[lastcard].driver = malloc(strlen(buf + 7) + 1);
+ strcpy(card[lastcard].driver, buf + 7);
+ continue;
+ }
+ if (strncmp(buf, "RAMDAC", 6) == 0) {
+ /* Ramdac indentifier. */
+ card[lastcard].ramdac = malloc(strlen(buf + 7) + 1);
+ strcpy(card[lastcard].ramdac, buf + 7);
+ continue;
+ }
+ if (strncmp(buf, "CLOCKCHIP", 9) == 0) {
+ /* Clockchip indentifier. */
+ card[lastcard].clockchip = malloc(strlen(buf + 10) + 1);
+ strcpy(card[lastcard].clockchip, buf + 10);
+ card[lastcard].flags |= NOCLOCKPROBE;
+ continue;
+ }
+ if (strncmp(buf, "DACSPEED", 8) == 0) {
+ /* Clockchip indentifier. */
+ card[lastcard].dacspeed = malloc(strlen(buf + 9) + 1);
+ strcpy(card[lastcard].dacspeed, buf + 9);
+ continue;
+ }
+ if (strncmp(buf, "NOCLOCKPROBE", 12) == 0) {
+ card[lastcard].flags |= NOCLOCKPROBE;
+ continue;
+ }
+ if (strncmp(buf, "UNSUPPORTED", 12) == 0) {
+ card[lastcard].flags |= UNSUPPORTED;
+ continue;
+ }
+ /* test for missing required fields */
+ if (card[lastcard].driver == NULL) {
+ fprintf(stderr, "Warning DRIVER specification missing "
+ "in Card database entry %s (line %d).\n",
+ card[lastcard].name, lineno);
+ keypress();
+ card[lastcard].driver = "unknown";
+ }
+ if (card[lastcard].chipset == NULL) {
+ fprintf(stderr, "Warning CHIPSET specification missing "
+ "in Card database entry %s (line %d).\n",
+ card[lastcard].name, lineno);
+ keypress();
+ card[lastcard].chipset = "unknown";
+ }
+ }
+
+ fclose(f);
+
+ /*
+ * Add general comments.
+ */
+ for (i = 0; i <= lastcard; i++) {
+ if (card[i].server && strcmp(card[i].server, "S3") == 0)
+ appendstring(&card[i].lines, s3_comment);
+ if (card[i].chipset &&
+ strncmp(card[i].chipset, "CL-GD", 5) == 0)
+ appendstring(&card[i].lines, cirrus_comment);
+ }
+
+ sort_database();
+
+ return 0;
+}
+
+#ifdef __STDC__
+#define CONST const
+#else
+#define CONST
+#endif
+
+static int
+compare_card(CONST void *e1, CONST void *e2)
+{
+ return strcmp(((Card *)e1)->name, ((Card *)e2)->name);
+}
+
+void
+sort_database() {
+ /* Each element is a bunch of words, but nothing too bad. */
+ qsort(card, lastcard + 1, sizeof(Card), compare_card);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf86config/cards.h b/xc/programs/Xserver/hw/xfree86/xf86config/cards.h
new file mode 100644
index 000000000..c5299e899
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf86config/cards.h
@@ -0,0 +1,38 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf86config/cards.h,v 3.5 1999/07/05 12:12:06 dawes Exp $ */
+
+
+
+
+
+/* $XConsortium: cards.h /main/3 1996/02/21 18:12:53 kaleb $ */
+
+#ifndef CARD_DATABASE_FILE
+#define CARD_DATABASE_FILE "Cards"
+#endif
+
+#define MAX_CARDS 1000
+
+typedef struct {
+ char *name; /* Name of the card. */
+ char *chipset; /* Chipset (decriptive). */
+ char *server; /* Server identifier. */
+ char *driver; /* Driver identifier. */
+ char *ramdac; /* Ramdac identifier. */
+ char *clockchip; /* Clockchip identifier. */
+ char *dacspeed; /* DAC speed rating. */
+ int flags;
+ char *lines; /* Additional Device section lines. */
+} Card;
+
+/* Flags: */
+#define NOCLOCKPROBE 0x1 /* Never probe clocks of the card. */
+#define UNSUPPORTED 0x2 /* Card is not supported (only VGA). */
+
+extern int lastcard;
+
+extern Card card[MAX_CARDS];
+
+extern int lookupcard ( char *name );
+extern int parse_database ( void );
+extern void sort_database ( void );
+extern void keypress ( void );
diff --git a/xc/programs/Xserver/hw/xfree86/xf86config/xf86conf.man b/xc/programs/Xserver/hw/xfree86/xf86config/xf86conf.man
new file mode 100644
index 000000000..10c21e878
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf86config/xf86conf.man
@@ -0,0 +1,16 @@
+.\" $XFree86: xc/programs/Xserver/hw/xfree86/xf86config/xf86conf.man,v 3.7 1998/04/05 02:28:43 dawes Exp $
+.TH xf86config 1 "Version 3.2" "XFree86"
+.SH NAME
+xf86config \- generate an XF86Config file
+.SH SYNOPSIS
+.B xf86config
+.SH DESCRIPTION
+\fIxf86config\fP is an interactive program for generating an XF86Config file
+for use with XFree86 X servers.
+.SH FILES
+<xroot>/lib/X11/Cards Video cards database
+.SH "SEE ALSO"
+XFree86(1), XF86Config(4/5), reconfig(1)
+.SH AUTHOR
+Harm Hanemaayer.
+.\" $TOG: xf86conf.man /main/9 1997/07/19 10:53:08 kaleb $
diff --git a/xc/programs/Xserver/hw/xfree86/xf86config/xf86config.c b/xc/programs/Xserver/hw/xfree86/xf86config/xf86config.c
new file mode 100644
index 000000000..a43899a39
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf86config/xf86config.c
@@ -0,0 +1,2628 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf86config/xf86config.c,v 3.48 1999/07/10 12:17:43 dawes Exp $ */
+
+/*
+ * This is a configuration program that will create a base XF86Config
+ * file based on menu choices. Its main feature is that clueless users
+ * may be less inclined to select crazy sync rates way over monitor spec,
+ * by presenting a menu with standard monitor types. Also some people
+ * don't read docs unless an executable that they can run tells them to.
+ *
+ * It assumes a 24-line or bigger text console.
+ *
+ * Revision history:
+ * 25Sep94 Initial version.
+ * 27Sep94 Fix hsync range of monitor types to match with best possible mode.
+ * Remove 'const'.
+ * Tweak descriptions.
+ * 28Sep94 Fixes from J"org Wunsch:
+ * Don't use gets().
+ * Add mouse device prompt.
+ * Fix lines overrun for 24-line console.
+ * Increase buffer size for probeonly output.
+ * 29Sep94 Fix bad bug with old XF86Config preserving during probeonly run.
+ * Add note about vertical refresh in interlaced modes.
+ * Name gets() replacement getstring().
+ * Add warning about binary paths.
+ * Fixes from David Dawes:
+ * Don't use 'ln -sf'.
+ * Omit man path reference in comment.
+ * Generate only a generic 320x200 SVGA section for accel cards.
+ * Only allow writing to /usr/X11R6/lib/X11 if root, and use
+ * -xf86config for the -probeonly phase (root only).
+ * Fix bug that forces screen type to accel in some cases.
+ * 30Sep94 Continue after clocks probe fails.
+ * Note about programmable clocks.
+ * Rename to 'xf86config'. Not to be confused with XF86Config
+ * or the -xf86config option.
+ * 07Oct94 Correct hsync in standard mode timings comments, and include
+ * the proper +/-h/vsync flags.
+ * 11Oct94 Skip 'numclocks:' and 'pixel clocks:' lines when probing for
+ * clocks.
+ * 18Oct94 Add check for existence of /usr/X11R6.
+ * Add note about ctrl-alt-backspace.
+ * 06Nov94 Add comment above standard mode timings in XF86Config.
+ * 24Dec94 Add low-resolution modes using doublescan.
+ * 29Dec94 Add note in horizontal sync range selection.
+ * Ask about ClearDTR/RTS option for Mouse Systems mice.
+ * Ask about writing to /etc/XF86Config.
+ * Allow link to be set in /var/X11R6/bin.
+ * Note about X -probeonly crashing.
+ * Add keyboard Alt binding option for non-ASCII characters.
+ * Add card database selection.
+ * Write temporary XF86Config for clock probing in /tmp instead
+ * of /usr/X11R6/lib/X11.
+ * Add RAMDAC and Clockchip menu.
+ * 27Mar99 Modified for XFree86 4.0 config file format
+ *
+ * Possible enhancements:
+ * - Add more standard mode timings (also applies to README.Config). Missing
+ * are 1024x768 @ 72 Hz, 1152x900 modes, and 1280x1024 @ ~70 Hz.
+ * I suspect there is a VESA standard for 1024x768 @ 72 Hz with 77 MHz dot
+ * clock, and 1024x768 @ 75 Hz with 78.7 MHz dot clock. New types of
+ * monitors probably work better with VESA 75 Hz timings.
+ * - Add option for creation of clear, minimal XF86Config.
+ * - The card database doesn't include most of the entries in previous
+ * databases.
+ *
+ * Send comments to H.Hanemaayer@inter.nl.net.
+ *
+ * Things to keep up-to-date:
+ * - Accelerated server names.
+ * - Ramdac and Clockchip settings.
+ * - The card database.
+ *
+ */
+/* $XConsortium: xf86config.c /main/21 1996/10/28 05:43:57 kaleb $ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "cards.h"
+
+
+/*
+ * Define the following to 310 to remove references to XFree86 features that
+ * have been added since XFree86 3.1 (e.g. DoubleScan modes).
+ * or to 311 to remove certain new modelines
+ */
+#define XFREE86_VERSION 399
+
+/*
+ * This is the filename of the temporary XF86Config file that is written
+ * when the program is told to probe clocks (which can only happen for
+ * root).
+ */
+#ifndef __EMX__
+#define TEMPORARY_XF86CONFIG_DIR_PREFIX "/tmp/.xf86config"
+#define TEMPORARY_XF86CONFIG_FILENAME "XF86Config.tmp"
+#else
+/* put in root dir, would have to find TMP dir first else */
+#define TEMPORARY_XF86CONFIG_FILENAME "\\XConfig.tmp"
+#endif
+
+/*
+ * Define this to have /etc/XF86Config prompted for as the default
+ * location to write the XF86Config file to.
+ */
+#define PREFER_XF86CONFIG_IN_ETC
+
+/*
+ * Define this to force the user to go through XKB configuration section.
+ *
+ */
+#define FORCE_XKB_DIALOG
+
+/*
+ * Configuration variables.
+ */
+
+#define MAX_CLOCKS_LINES 16
+
+/* (hv) make a number of filenames defines, because I want OS/2 to need just
+ * 8.3 names here
+ */
+#ifdef __EMX__
+#define DUMBCONFIG2 "\\dconfig.2"
+#define DUMBCONFIG3 "\\dconfig.3"
+#else
+#define DUMBCONFIG2 "dumbconfig.2"
+#define DUMBCONFIG3 "dumbconfig.3"
+#endif
+
+/* some more vars to make path names in texts more flexible. OS/2 users
+ * may be more irritated than Unix users
+ */
+#ifndef __EMX__
+#define TREEROOT "/usr/X11R6"
+#define TREEROOTLX "/usr/X11R6/lib/X11"
+#define TREEROOTCFG "/usr/X11R6/etc/X11"
+#define MODULEPATH "/usr/X11R6/lib/modules"
+#else
+#define TREEROOT "/XFree86"
+#define TREEROOTLX "/XFree86/lib/X11"
+#define TREEROOTCFG "/XFree86/lib/X11"
+#define MODULEPATH "/XFree86/lib/modules"
+#endif
+#define CONFIGNAME "XF86Config"
+
+int config_mousetype; /* Mouse. */
+int config_emulate3buttons;
+int config_chordmiddle;
+int config_cleardtrrts;
+char *config_pointerdevice;
+int config_altmeta; /* Keyboard. */
+int config_monitortype; /* Monitor. */
+char *config_hsyncrange;
+char *config_vsyncrange;
+char *config_monitoridentifier;
+int config_videomemory; /* Video card. */
+int config_screentype; /* mono, vga16, svga, accel */
+char *config_deviceidentifier;
+int config_numberofclockslines;
+char *config_clocksline[MAX_CLOCKS_LINES];
+char *config_modesline8bpp;
+char *config_modesline16bpp;
+char *config_modesline24bpp;
+int config_virtual; /* 1 (yes) or 0 (no) */
+int config_virtualx8bpp, config_virtualy8bpp;
+int config_virtualx16bpp, config_virtualy16bpp;
+int config_virtualx24bpp, config_virtualy24bpp;
+char *config_ramdac;
+char *config_dacspeed;
+char *config_clockchip;
+int config_xkbdisable = 0;
+char *config_xkbrules;
+char *config_xkbmodel;
+char *config_xkblayout;
+char *config_depth;
+
+char *temp_dir = "";
+
+/*
+ * These are from the selected card definition. Parameters from the
+ * definition are offered during the questioning about the video card.
+ */
+
+int card_selected; /* Card selected from database. */
+
+
+static void write_XF86Config(char *filename);
+
+
+/*
+ * This is the initial intro text that appears when the program is started.
+ */
+
+static char *intro_text =
+"\n"
+"This program will create a basic " CONFIGNAME " file, based on menu selections you\n"
+"make.\n"
+"\n"
+"The " CONFIGNAME " file usually resides in " TREEROOTCFG " or /etc/X11. A sample\n"
+CONFIGNAME " file is supplied with XFree86; it is configured for a standard\n"
+"VGA card and monitor with 640x480 resolution. This program will ask for a\n"
+"pathname when it is ready to write the file.\n"
+"\n"
+"You can either take the sample " CONFIGNAME " as a base and edit it for your\n"
+"configuration, or let this program produce a base " CONFIGNAME " file for your\n"
+"configuration and fine-tune it.\n"
+#if 0
+" Refer to " TREEROOTLX "/doc/README.Config\n"
+"for a detailed overview of the configuration process.\n"
+"\n"
+"(what should we change this section to?)\n"
+"For accelerated servers (including accelerated drivers in the SVGA server),\n"
+"there are many chipset and card-specific options and settings. This program\n"
+"does not know about these. On some configurations some of these settings must\n"
+"be specified. Refer to the server man pages and chipset-specific READMEs.\n"
+#endif
+"\n"
+"Before continuing with this program, make sure you know what video card\n"
+"you have, and preferably also the chipset it uses and the amount of video\n"
+"memory on your video card. SuperProbe may be able to help with this.\n"
+"\n"
+;
+
+static char *finalcomment_text =
+"File has been written. Take a look at it before running 'startx'. Note that\n"
+"the " CONFIGNAME " file must be in one of the directories searched by the server\n"
+"(e.g. /etc/X11) in order to be used. Within the server press\n"
+"ctrl, alt and '+' simultaneously to cycle video resolutions. Pressing ctrl,\n"
+"alt and backspace simultaneously immediately exits the server (use if\n"
+"the monitor doesn't sync for a particular mode).\n"
+"\n"
+"For further configuration, refer to " TREEROOTLX "/doc/README.Config.\n"
+"\n";
+
+static void *
+Malloc(int i) {
+ void *p;
+
+ p = malloc(i);
+ if (p == NULL) {
+ printf("Fatal malloc error\n");
+ exit(-1);
+ }
+ return p;
+}
+
+static void
+createtmpdir(void) {
+#ifndef __EMX__
+ /* length of prefix + 20 (digits in 2**64) + 1 (slash) + 1 */
+ temp_dir = Malloc(strlen(TEMPORARY_XF86CONFIG_DIR_PREFIX) + 22);
+ sprintf(temp_dir, "%s%d", TEMPORARY_XF86CONFIG_DIR_PREFIX, getpid());
+ if (mkdir(temp_dir, 0700) != 0) {
+ printf("Cannot create directory %s\n", temp_dir);
+ exit(-1);
+ }
+ /* append a slash */
+ strcat(temp_dir, "/");
+#endif
+}
+
+
+void
+keypress(void) {
+ printf("Press enter to continue, or ctrl-c to abort.");
+ getchar();
+ printf("\n");
+}
+
+static void
+emptylines(void) {
+ int i;
+ for (i = 0; i < 50; i++)
+ printf("\n");
+}
+
+static int
+answerisyes(char *s)
+{
+ if (s[0] == '\'') /* For fools that type the ' literally. */
+ return tolower(s[1]) == 'y';
+ return tolower(s[0]) == 'y';
+}
+
+/*
+ * This is a replacement for gets(). Limit is 80 chars.
+ * The 386BSD descendants scream about using gets(), for good reason.
+ */
+
+static void
+getstring(char *s)
+{
+ char *cp;
+ fgets(s, 80, stdin);
+ cp = strchr(s, '\n');
+ if (cp)
+ *cp=0;
+}
+
+/*
+ * Mouse configuration.
+ *
+ * (hv) OS/2 (__EMX__) only has an OS supported mouse, so user has no options
+ * the server will enable a third button automatically if there is one
+ */
+
+static char *mousetype_identifier[] = {
+ "Microsoft",
+ "MouseSystems",
+ "Busmouse",
+ "PS/2",
+ "Logitech",
+ "MouseMan",
+ "MMSeries",
+ "MMHitTab",
+ "IntelliMouse",
+#ifdef __EMX__
+ "OSMOUSE"
+#endif
+};
+
+#ifndef __EMX__
+static char *mouseintro_text =
+"First specify a mouse protocol type. Choose one from the following list:\n"
+"\n";
+
+static char *mousetype_name[] = {
+ "Microsoft compatible (2-button protocol)",
+ "Mouse Systems (3-button protocol)",
+ "Bus Mouse",
+ "PS/2 Mouse",
+ "Logitech Mouse (serial, old type, Logitech protocol)",
+ "Logitech MouseMan (Microsoft compatible)",
+ "MM Series", /* XXXX These descriptions should be improved. */
+ "MM HitTablet",
+ "Microsoft IntelliMouse"
+};
+
+static char *mousedev_text =
+"Now give the full device name that the mouse is connected to, for example\n"
+"/dev/tty00. Just pressing enter will use the default, /dev/mouse.\n"
+"\n";
+
+static char *mousecomment_text =
+"If you have a two-button mouse, it is most likely of type 1, and if you have\n"
+"a three-button mouse, it can probably support both protocol 1 and 2. There are\n"
+"two main varieties of the latter type: mice with a switch to select the\n"
+"protocol, and mice that default to 1 and require a button to be held at\n"
+"boot-time to select protocol 2. Some mice can be convinced to do 2 by sending\n"
+"a special sequence to the serial port (see the ClearDTR/ClearRTS options).\n"
+"\n";
+
+static char *twobuttonmousecomment_text =
+"You have selected a two-button mouse protocol. It is recommended that you\n"
+"enable Emulate3Buttons.\n";
+
+static char *threebuttonmousecomment_text =
+"You have selected a three-button mouse protocol. It is recommended that you\n"
+"do not enable Emulate3Buttons, unless the third button doesn't work.\n";
+
+static char *unknownbuttonsmousecomment_text =
+"If your mouse has only two buttons, it is recommended that you enable\n"
+"Emulate3Buttons.\n";
+
+static char *microsoftmousecomment_text =
+"You have selected a Microsoft protocol mouse. If your mouse was made by\n"
+"Logitech, you might want to enable ChordMiddle which could cause the\n"
+"third button to work.\n";
+
+static char *mousesystemscomment_text =
+"You have selected a Mouse Systems protocol mouse. If your mouse is normally\n"
+"in Microsoft-compatible mode, enabling the ClearDTR and ClearRTS options\n"
+"may cause it to switch to Mouse Systems mode when the server starts.\n";
+
+static char *logitechmousecomment_text =
+"You have selected a Logitech protocol mouse. This is only valid for old\n"
+"Logitech mice.\n";
+
+static char *mousemancomment_text =
+"You have selected a Logitech MouseMan type mouse. You might want to enable\n"
+"ChordMiddle which could cause the third button to work.\n";
+
+#endif /* !__EMX__ */
+
+static void
+mouse_configuration(void) {
+
+#ifndef __EMX__
+ int i;
+ char s[80];
+ printf("%s", mouseintro_text);
+
+ for (i = 0; i < 9; i++)
+ printf("%2d. %s\n", i + 1, mousetype_name[i]);
+
+ printf("\n");
+
+ printf("%s", mousecomment_text);
+
+ printf("Enter a protocol number: ");
+ getstring(s);
+ config_mousetype = atoi(s) - 1;
+ if (config_mousetype < 0)
+ config_mousetype = 0;
+
+ printf("\n");
+
+ if (config_mousetype == 4) {
+ /* Logitech. */
+ printf("%s", logitechmousecomment_text);
+ printf("\n");
+ printf("Please answer the following question with either 'y' or 'n'.\n");
+ printf("Are you sure it's really not a Microsoft compatible one? ");
+ getstring(s);
+ if (!answerisyes(s))
+ config_mousetype = 0;
+ printf("\n");
+ }
+
+ config_chordmiddle = 0;
+ if (config_mousetype == 0 || config_mousetype == 5) {
+ /* Microsoft or MouseMan. */
+ if (config_mousetype == 0)
+ printf("%s", microsoftmousecomment_text);
+ else
+ printf("%s", mousemancomment_text);
+ printf("\n");
+ printf("Please answer the following question with either 'y' or 'n'.\n");
+ printf("Do you want to enable ChordMiddle? ");
+ getstring(s);
+ if (answerisyes(s))
+ config_chordmiddle = 1;
+ printf("\n");
+ }
+
+ config_cleardtrrts = 0;
+ if (config_mousetype == 1) {
+ /* Mouse Systems. */
+ printf("%s", mousesystemscomment_text);
+ printf("\n");
+ printf("Please answer the following question with either 'y' or 'n'.\n");
+ printf("Do you want to enable ClearDTR and ClearRTS? ");
+ getstring(s);
+ if (answerisyes(s))
+ config_cleardtrrts = 1;
+ printf("\n");
+ }
+
+ switch (config_mousetype) {
+ case 0 : /* Microsoft compatible */
+ if (config_chordmiddle)
+ printf("%s", threebuttonmousecomment_text);
+ else
+ printf("%s", twobuttonmousecomment_text);
+ break;
+ case 1 : /* Mouse Systems. */
+ case 8 : /* IntelliMouse */
+ printf("%s", threebuttonmousecomment_text);
+ break;
+ default :
+ printf("%s", unknownbuttonsmousecomment_text);
+ break;
+ }
+
+ printf("\n");
+
+ printf("Please answer the following question with either 'y' or 'n'.\n");
+ printf("Do you want to enable Emulate3Buttons? ");
+ getstring(s);
+ if (answerisyes(s))
+ config_emulate3buttons = 1;
+ else
+ config_emulate3buttons = 0;
+ printf("\n");
+
+ printf("%s", mousedev_text);
+ printf("Mouse device: ");
+ getstring(s);
+ if (strlen(s) == 0)
+ config_pointerdevice = "/dev/mouse";
+ else {
+ config_pointerdevice = Malloc(strlen(s) + 1);
+ strcpy(config_pointerdevice, s);
+ }
+ printf("\n");
+
+#else /* __EMX__ */
+ /* set some reasonable defaults for OS/2 */
+ config_mousetype = 9;
+ config_chordmiddle = 0;
+ config_cleardtrrts = 0;
+ config_emulate3buttons = 0;
+ config_pointerdevice = "OS2MOUSE";
+#endif /* __EMX__ */
+}
+
+
+/*
+ * Keyboard configuration.
+ */
+
+
+/*
+ * Configuration of XKB
+ */
+static char *xkbmodeltext =
+"Please select one of the following keyboard types that is the better\n"
+"description of your keyboard. If nothing really matches,\n"
+"choose 1 (Generic 101-key PC)\n\n";
+
+static struct xkb_model_str {
+ char *model;
+ char *desc;
+} xkb_model_list[] = {
+ { "pc101", "Generic 101-key PC" },
+ { "pc102", "Generic 102-key (Intl) PC" },
+ { "pc104", "Generic 104-key PC" },
+ { "pc105", "Generic 105-key (Intl) PC" },
+ { "dell101", "Dell 101-key PC" },
+ { "everex", "Everex STEPnote" },
+ { "flexpro", "Keytronic FlexPro" },
+ { "microsoft", "Microsoft Natural" },
+ { "omnikey101", "Northgate OmniKey 101" },
+ { "winbook", "Winbook Model XP5" },
+ { "jp106", "Japanese 106-key" },
+ { "pc98", "PC-98xx Series" },
+};
+static int nmodels = sizeof(xkb_model_list)/sizeof(struct xkb_model_str);
+
+static char *xkblayouttext =
+"Please select the layout corresponding to your keyboard\n";
+
+static struct xkb_layout_str {
+ char *layout;
+ char *desc;
+} xkb_layout_list[] = {
+ { "us", "U.S. English" },
+ { "en_US", "U.S. English w/ISO9995-3" },
+ { "be", "Belgian" },
+ { "bg", "Bulgarian" },
+ { "ca", "Canadian" },
+ { "cs", "Czechoslovakian" },
+ { "de", "German" },
+ { "de_CH", "Swiss German" },
+ { "dk", "Danish" },
+ { "es", "Spanish" },
+ { "fi", "Finnish" },
+ { "fr", "French" },
+ { "fr_CH", "Swiss French" },
+ { "gb", "United Kingdom" },
+ { "hu", "Hungarian" },
+ { "it", "Italian" },
+ { "jp", "Japanese" },
+ { "no", "Norwegian" },
+ { "pl", "Polish" },
+ { "pt", "Portugese" },
+ { "ru", "Russian" },
+ { "se", "Swedish" },
+ { "th", "Thai" },
+ { "nec/jp", "PC-98xx Series" },
+};
+static int nlayouts = sizeof(xkb_layout_list)/sizeof(struct xkb_layout_str);
+
+static void
+keyboard_configuration(void)
+{
+ int i;
+ char s[80];
+ int xkbmodel,xkblayout;
+
+ /* this is entered when the user did not find a preconfigured
+ * XkbKeymap
+ */
+ emptylines();
+ printf(xkbmodeltext);
+ for (i=0; i<nmodels; i++) {
+ printf("%3d %-50s\n",i+1,xkb_model_list[i].desc);
+ }
+
+ printf("\nEnter a number to choose the keyboard.\n\n");
+ getstring(s);
+ if (strlen(s) == 0)
+ xkbmodel = 0;
+ else {
+ i = atoi(s)-1;
+ xkbmodel = (i < 0 || i > nmodels) ? 0 : i;
+ }
+ emptylines();
+ printf(xkblayouttext);
+
+ xkblayout = -1;
+ for (i=0;;) {
+ int j;
+ emptylines();
+ for (j = i; j < i + 18 && j < nlayouts; j++)
+ printf("%3d %-50s\n", j+1,
+ xkb_layout_list[j].desc);
+ printf("\n");
+ printf("Enter a number to choose the country.\n");
+ if (nlayouts >= 18)
+ printf("Press enter for the next page\n");
+ printf("\n");
+ getstring(s);
+ if (strlen(s) == 0) {
+ i += 18;
+ if (i > nlayouts)
+ i = 0;
+ continue;
+ }
+ xkblayout = atoi(s) - 1;
+ if (xkblayout >= 0 && xkblayout < nlayouts)
+ break;
+ }
+
+
+ /* compose the lines */
+#ifdef XFREE98_XKB
+ config_xkbrules = "xfree98"; /* static */
+#else
+ config_xkbrules = "xfree86"; /* static */
+#endif
+
+ i = strlen(xkb_model_list[xkbmodel].model) + 1;
+ config_xkbmodel = Malloc(i);
+ sprintf(config_xkbmodel,"%s", xkb_model_list[xkbmodel].model);
+
+ config_xkblayout = Malloc(strlen(xkb_layout_list[xkblayout].layout)+1);
+ sprintf(config_xkblayout,"%s", xkb_layout_list[xkblayout].layout);
+
+ return;
+}
+
+
+
+/*
+ * Monitor configuration.
+ */
+
+static char *monitorintro_text =
+"Now we want to set the specifications of the monitor. The two critical\n"
+"parameters are the vertical refresh rate, which is the rate at which the\n"
+"the whole screen is refreshed, and most importantly the horizontal sync rate,\n"
+"which is the rate at which scanlines are displayed.\n"
+"\n"
+"The valid range for horizontal sync and vertical sync should be documented\n"
+"in the manual of your monitor. If in doubt, check the monitor database\n"
+TREEROOTLX "/doc/Monitors to see if your monitor is there.\n"
+"\n";
+
+static char *hsyncintro_text =
+"You must indicate the horizontal sync range of your monitor. You can either\n"
+"select one of the predefined ranges below that correspond to industry-\n"
+"standard monitor types, or give a specific range.\n"
+"\n"
+"It is VERY IMPORTANT that you do not specify a monitor type with a horizontal\n"
+"sync range that is beyond the capabilities of your monitor. If in doubt,\n"
+"choose a conservative setting.\n"
+"\n";
+
+static char *customhsync_text =
+"Please enter the horizontal sync range of your monitor, in the format used\n"
+"in the table of monitor types above. You can either specify one or more\n"
+"continuous ranges (e.g. 15-25, 30-50), or one or more fixed sync frequencies.\n"
+"\n";
+
+static char *vsyncintro_text =
+"You must indicate the vertical sync range of your monitor. You can either\n"
+"select one of the predefined ranges below that correspond to industry-\n"
+"standard monitor types, or give a specific range. For interlaced modes,\n"
+"the number that counts is the high one (e.g. 87 Hz rather than 43 Hz).\n"
+"\n"
+" 1 50-70\n"
+" 2 50-90\n"
+" 3 50-100\n"
+" 4 40-150\n"
+" 5 Enter your own vertical sync range\n";
+
+static char *monitordescintro_text =
+"You must now enter a few identification/description strings, namely an\n"
+"identifier, a vendor name, and a model name. Just pressing enter will fill\n"
+"in default names.\n"
+"\n";
+
+#define NU_MONITORTYPES 10
+
+static char *monitortype_range[NU_MONITORTYPES] = {
+ "31.5",
+ "31.5 - 35.1",
+ "31.5, 35.5",
+ "31.5, 35.15, 35.5",
+ "31.5 - 37.9",
+ "31.5 - 48.5",
+ "31.5 - 57.0",
+ "31.5 - 64.3",
+ "31.5 - 79.0",
+ "31.5 - 82.0"
+};
+
+static char *monitortype_name[NU_MONITORTYPES] = {
+ "Standard VGA, 640x480 @ 60 Hz",
+ "Super VGA, 800x600 @ 56 Hz",
+ "8514 Compatible, 1024x768 @ 87 Hz interlaced (no 800x600)",
+ "Super VGA, 1024x768 @ 87 Hz interlaced, 800x600 @ 56 Hz",
+ "Extended Super VGA, 800x600 @ 60 Hz, 640x480 @ 72 Hz",
+ "Non-Interlaced SVGA, 1024x768 @ 60 Hz, 800x600 @ 72 Hz",
+ "High Frequency SVGA, 1024x768 @ 70 Hz",
+ "Monitor that can do 1280x1024 @ 60 Hz",
+ "Monitor that can do 1280x1024 @ 74 Hz",
+ "Monitor that can do 1280x1024 @ 76 Hz"
+};
+
+static void
+monitor_configuration(void) {
+ int i;
+ char s[80];
+ printf("%s", monitorintro_text);
+
+ keypress();
+ emptylines();
+
+ printf("%s", hsyncintro_text);
+
+ printf(" hsync in kHz; monitor type with characteristic modes\n");
+ for (i = 0; i < NU_MONITORTYPES; i++)
+ printf("%2d %s; %s\n", i + 1, monitortype_range[i],
+ monitortype_name[i]);
+
+ printf("%2d Enter your own horizontal sync range\n",
+ NU_MONITORTYPES + 1);
+ printf("\n");
+
+ printf("Enter your choice (1-%d): ", NU_MONITORTYPES + 1);
+ getstring(s);
+ config_monitortype = atoi(s) - 1;
+ if (config_monitortype < 0)
+ config_monitortype = 0;
+
+ printf("\n");
+
+ if (config_monitortype < NU_MONITORTYPES)
+ config_hsyncrange = monitortype_range[config_monitortype];
+ else {
+ /* Custom hsync range option selected. */
+ printf("%s", customhsync_text);
+ printf("Horizontal sync range: ");
+ getstring(s);
+ config_hsyncrange = Malloc(strlen(s) + 1);
+ strcpy(config_hsyncrange, s);
+ printf("\n");
+ }
+
+ printf("%s", vsyncintro_text);
+ printf("\n");
+
+ printf("Enter your choice: ");
+ getstring(s);
+ printf("\n");
+ switch (atoi(s)) {
+ case 0 :
+ case 1 :
+ config_vsyncrange = "50-70";
+ break;
+ case 2 :
+ config_vsyncrange = "50-90";
+ break;
+ case 3 :
+ config_vsyncrange = "50-100";
+ break;
+ case 4 :
+ config_vsyncrange = "40-150";
+ break;
+ case 5 :
+ /* Custom vsync range option selected. */
+ printf("Vertical sync range: ");
+ getstring(s);
+ config_vsyncrange = Malloc(strlen(s) + 1);
+ strcpy(config_vsyncrange, s);
+ printf("\n");
+ break;
+ }
+ printf("%s", monitordescintro_text);
+ printf("The strings are free-form, spaces are allowed.\n");
+ printf("Enter an identifier for your monitor definition: ");
+ getstring(s);
+ if (strlen(s) == 0)
+ config_monitoridentifier = "My Monitor";
+ else {
+ config_monitoridentifier = Malloc(strlen(s) + 1);
+ strcpy(config_monitoridentifier, s);
+ }
+}
+
+
+/*
+ * Card database.
+ */
+
+static char *cardintro_text =
+"Now we must configure video card specific settings. At this point you can\n"
+"choose to make a selection out of a database of video card definitions.\n"
+"Because there can be variation in Ramdacs and clock generators even\n"
+"between cards of the same model, it is not sensible to blindly copy\n"
+"the settings (e.g. a Device section). For this reason, after you make a\n"
+"selection, you will still be asked about the components of the card, with\n"
+"the settings from the chosen database entry presented as a strong hint.\n"
+"\n"
+"The database entries include information about the chipset, what driver to\n"
+"run, the Ramdac and ClockChip, and comments that will be included in the\n"
+"Device section. However, a lot of definitions only hint about what driver\n"
+"to run (based on the chipset the card uses) and are untested.\n"
+"\n"
+"If you can't find your card in the database, there's nothing to worry about.\n"
+"You should only choose a database entry that is exactly the same model as\n"
+"your card; choosing one that looks similar is just a bad idea (e.g. a\n"
+"GemStone Snail 64 may be as different from a GemStone Snail 64+ in terms of\n"
+"hardware as can be).\n"
+"\n";
+
+static char *cardunsupported_text =
+"This card is basically UNSUPPORTED. It may only work as a generic\n"
+"VGA-compatible card. If you have an XFree86 version more recent than what\n"
+"this card definition was based on, there's a chance that it is now\n"
+"supported.\n";
+
+static void
+carddb_configuration(void) {
+ int i;
+ char s[80];
+ card_selected = -1;
+ printf("%s", cardintro_text);
+ printf("Do you want to look at the card database? ");
+ getstring(s);
+ printf("\n");
+ if (!answerisyes(s))
+ return;
+
+ /*
+ * Choose a database entry.
+ */
+ if (parse_database()) {
+ printf("Couldn't read card database file %s.\n",
+ CARD_DATABASE_FILE);
+ keypress();
+ return;
+ }
+
+ i = 0;
+ for (;;) {
+ int j;
+ emptylines();
+ for (j = i; j < i + 18 && j <= lastcard; j++)
+ printf("%3d %-50s%s\n", j,
+ card[j].name,
+ card[j].chipset);
+ printf("\n");
+ printf("Enter a number to choose the corresponding card definition.\n");
+ printf("Press enter for the next page, q to continue configuration.\n");
+ printf("\n");
+ getstring(s);
+ if (s[0] == 'q')
+ break;
+ if (strlen(s) == 0) {
+ i += 18;
+ if (i > lastcard)
+ i = 0;
+ continue;
+ }
+ card_selected = atoi(s);
+ if (card_selected >= 0 && card_selected <= lastcard)
+ break;
+ }
+
+ /*
+ * Look at the selected card.
+ */
+ if (card_selected != -1) {
+ printf("\nYour selected card definition:\n\n");
+ printf("Identifier: %s\n", card[card_selected].name);
+ printf("Chipset: %s\n", card[card_selected].chipset);
+ if (!card[card_selected].driver)
+ card[card_selected].driver = "unknown";
+ printf("Driver: %s\n", card[card_selected].driver);
+
+ if (card[card_selected].ramdac != NULL)
+ printf("Ramdac: %s\n", card[card_selected].ramdac);
+ if (card[card_selected].dacspeed != NULL)
+ printf("DacSpeed: %s\n", card[card_selected].dacspeed);
+ if (card[card_selected].clockchip != NULL)
+ printf("Clockchip: %s\n", card[card_selected].clockchip);
+ if (card[card_selected].flags & NOCLOCKPROBE)
+ printf("Do NOT probe clocks or use any Clocks line.\n");
+ if (card[card_selected].flags & UNSUPPORTED)
+ printf("%s", cardunsupported_text);
+#if 0 /* Might be confusing. */
+ if (strlen(card[card_selected].lines) > 0)
+ printf("Device section text:\n%s",
+ card[card_selected].lines);
+#endif
+ printf("\n");
+ keypress();
+ }
+}
+
+
+/*
+ * Screen/video card configuration.
+ */
+
+static char *deviceintro_text =
+"Now you must give information about your video card. This will be used for\n"
+"the \"Device\" section of your video card in " CONFIGNAME ".\n"
+"\n";
+
+static char *videomemoryintro_text =
+"You must indicate how much video memory you have. It is probably a good\n"
+"idea to use the same approximate amount as that detected by the server you\n"
+"intend to use. If you encounter problems that are due to the used server\n"
+"not supporting the amount memory you have (e.g. ATI Mach64 is limited to\n"
+"1024K with the SVGA server), specify the maximum amount supported by the\n"
+"server.\n"
+"\n"
+"How much video memory do you have on your video card:\n"
+"\n";
+
+static char *carddescintro_text =
+"You must now enter a few identification/description strings, namely an\n"
+"identifier, a vendor name, and a model name. Just pressing enter will fill\n"
+"in default names (possibly from a card definition).\n"
+"\n";
+
+#if 0
+static char *devicesettingscomment_text =
+"Especially for accelerated drivers, Ramdac, Dacspeed and ClockChip settings\n"
+"or special options may be required in the Device section.\n"
+"\n";
+
+static char *ramdaccomment_text =
+"The RAMDAC setting only applies to some drivers. Some RAMDAC's are\n"
+"auto-detected by the server. The detection of a RAMDAC is forced by using a\n"
+"Ramdac \"identifier\" line in the Device section. The identifiers are shown\n"
+"at the right of the following table of RAMDAC types:\n"
+"\n";
+
+#define NU_RAMDACS 24
+
+static char *ramdac_name[NU_RAMDACS] = {
+ "AT&T 20C490 (S3 and AGX servers, ARK driver)",
+ "AT&T 20C498/21C498/22C498 (S3, autodetected)",
+ "AT&T 20C409/20C499 (S3, autodetected)",
+ "AT&T 20C505 (S3)",
+ "BrookTree BT481 (AGX)",
+ "BrookTree BT482 (AGX)",
+ "BrookTree BT485/9485 (S3)",
+ "Sierra SC15025 (S3, AGX)",
+#if XFREE86_VERSION >= 311
+ "S3 GenDAC (86C708) (autodetected)",
+ "S3 SDAC (86C716) (autodetected)",
+#else
+ "S3 GenDAC (86C708)",
+ "S3 SDAC (86C716)",
+#endif
+ "STG-1700 (S3, autodetected)",
+ "STG-1703 (S3, autodetected)",
+ "TI 3020 (S3, autodetected)",
+ "TI 3025 (S3, autodetected)",
+ "TI 3026 (S3, autodetected)",
+ "IBM RGB 514 (S3, autodetected)",
+ "IBM RGB 524 (S3, autodetected)",
+ "IBM RGB 525 (S3, autodetected)",
+ "IBM RGB 526 (S3)",
+ "IBM RGB 528 (S3, autodetected)",
+ "ICS5342 (S3, ARK)",
+ "ICS5341 (W32)",
+ "IC Works w30C516 ZoomDac (ARK)",
+ "Normal DAC"
+};
+
+static char *ramdac_id[NU_RAMDACS] = {
+ "att20c490", "att20c498", "att20c409", "att20c505", "bt481", "bt482",
+ "bt485", "sc15025", "s3gendac", "s3_sdac", "stg1700","stg1703",
+ "ti3020", "ti3025", "ti3026", "ibm_rgb514", "ibm_rgb524",
+ "ibm_rgb525", "ibm_rgb526", "ibm_rgb528", "ics5342", "ics5341",
+ "zoomdac", "normal"
+};
+
+static char *clockchipcomment_text =
+"A Clockchip line in the Device section forces the detection of a\n"
+"programmable clock device. With a clockchip enabled, any required\n"
+"clock can be programmed without requiring probing of clocks or a\n"
+"Clocks line. Most cards don't have a programmable clock chip.\n"
+"Choose from the following list:\n"
+"\n";
+
+#define NU_CLOCKCHIPS 12
+
+static char *clockchip_name[] = {
+ "Chrontel 8391",
+ "ICD2061A and compatibles (ICS9161A, DCS2824)",
+ "ICS2595",
+ "ICS5342 (similar to SDAC, but not completely compatible)",
+ "ICS5341",
+ "S3 GenDAC (86C708) and ICS5300 (autodetected)",
+ "S3 SDAC (86C716)",
+ "STG 1703 (autodetected)",
+ "Sierra SC11412",
+ "TI 3025 (autodetected)",
+ "TI 3026 (autodetected)",
+ "IBM RGB 51x/52x (autodetected)",
+};
+
+static char *clockchip_id[] = {
+ "ch8391", "icd2061a", "ics2595", "ics5342", "ics5341",
+ "s3gendac", "s3_sdac",
+ "stg1703", "sc11412", "ti3025", "ti3026", "ibm_rgb5xx",
+};
+
+static char *deviceclockscomment_text =
+"For most modern configurations, a Clocks line is neither required or\n"
+"desirable. However for some older hardware it can be useful since it\n"
+"prevents the slow and nasty sounding clock probing at server start-up.\n"
+"Probed clocks are displayed at server startup, along with other server\n"
+"and hardware configuration info. You can save this information in a file\n"
+"by running 'X -probeonly 2>output_file'. Be warned that clock probing is\n"
+"inherently imprecise; some clocks may be slightly too high (varies per run).\n"
+"\n";
+
+static char *deviceclocksquestion_text =
+"At this point I can run X -probeonly, and try to extract the clock information\n"
+"from the output. It is recommended that you do this yourself and if a set of\n"
+"clocks is shown then you add a clocks line (note that the list of clocks may\n"
+"be split over multiple Clocks lines) to your Device section afterwards. Be\n"
+"aware that a clocks line is not appropriate for most modern hardware that\n"
+"has programmable clocks.\n"
+"\n"
+"You must be root to be able to run X -probeonly now.\n"
+"\n";
+
+static char *probeonlywarning_text =
+"It is possible that the hardware detection routines in the server will somehow\n"
+"cause the system to crash and the screen to remain blank. If this is the\n"
+"case, do not choose this option the next time. The server may need a\n"
+"Ramdac, ClockChip or special option (e.g. \"nolinear\" for S3) to probe\n"
+"and start-up correctly.\n"
+"\n";
+#endif
+
+static char *modesorderintro_text =
+"For each depth, a list of modes (resolutions) is defined. The default\n"
+"resolution that the server will start-up with will be the first listed\n"
+"mode that can be supported by the monitor and card.\n"
+"Currently it is set to:\n"
+"\n";
+
+static char *modesorder_text2 =
+"Modes that cannot be supported due to monitor or clock constraints will\n"
+"be automatically skipped by the server.\n"
+"\n"
+" 1 Change the modes for 8-bit (256 colors)\n"
+" 2 Change the modes for 16-bit (32K/64K colors)\n"
+" 3 Change the modes for 24-bit (24-bit color)\n"
+" 4 The modes are OK, continue.\n"
+"\n";
+
+static char *modeslist_text =
+"Please type the digits corresponding to the modes that you want to select.\n"
+"For example, 432 selects \"1024x768\" \"800x600\" \"640x480\", with a\n"
+"default mode of 1024x768.\n"
+"\n";
+
+static char *virtual_text =
+"You can have a virtual screen (desktop), which is screen area that is larger\n"
+"than the physical screen and which is panned by moving the mouse to the edge\n"
+"of the screen. If you don't want virtual desktop at a certain resolution,\n"
+"you cannot have modes listed that are larger. Each color depth can have a\n"
+"differently-sized virtual screen\n"
+"\n";
+
+static int videomemory[5] = {
+ 256, 512, 1024, 2048, 4096
+};
+
+#if XFREE86_VERSION >= 330
+#define NU_MODESTRINGS 12
+#else
+#if XFREE86_VERSION >= 311
+#define NU_MODESTRINGS 8
+#else
+#define NU_MODESTRINGS 5
+#endif
+#endif
+
+static char *modestring[NU_MODESTRINGS] = {
+ "\"640x400\"",
+ "\"640x480\"",
+ "\"800x600\"",
+ "\"1024x768\"",
+ "\"1280x1024\"",
+#if XFREE86_VERSION >= 311
+ "\"320x200\"",
+ "\"320x240\"",
+ "\"400x300\""
+#endif
+#if XFREE86_VERSION >= 330
+ ,"\"1152x864\"",
+ "\"1600x1200\"",
+ "\"1800x1400\"",
+ "\"512x384\""
+#endif
+};
+
+#ifdef __EMX__
+/* yet another instance of this code, sigh! */
+static char *
+__XOS2RedirRoot(char *path, char sep)
+{
+ static char pn[300];
+ char *root;
+ int i,l;
+ if ((isalpha(path[0]) && path[1]==':') || path[0] != '/')
+ return path;
+
+ root = getenv("X11ROOT");
+ if (!root) root = "";
+ sprintf(pn,"%s%s",root,path);
+ if (sep=='\\') {
+ l = strlen(pn);
+ for (i=0; i<l; i++)
+ if (pn[i]=='/') pn[i]='\\';
+ }
+ return pn;
+}
+#endif
+
+/* (hv) to avoid the UNIXISM to try to open a dir to check for existance */
+static int exists_dir(char *name) {
+ struct stat sbuf;
+
+#ifdef __EMX__
+ name = __XOS2RedirRoot(name,'/');
+#endif
+ /* is it there ? */
+ if (stat(name,&sbuf) == -1)
+ return 0;
+
+ /* is there, but is it a dir? */
+ return S_ISDIR(sbuf.st_mode) ? 1 : 0;
+}
+
+static void
+screen_configuration(void) {
+ int i, c/*, np*/;
+ char s[80];
+
+ /*
+ * Configure the "Device" section for the video card.
+ */
+
+ printf("%s", deviceintro_text);
+
+ printf("%s", videomemoryintro_text);
+
+ for (i = 0; i < 5; i++)
+ printf("%2d %dK\n", i + 1, videomemory[i]);
+ printf(" 6 Other\n\n");
+
+ printf("Enter your choice: ");
+ getstring(s);
+ printf("\n");
+
+ c = atoi(s) - 1;
+ if (c < 0)
+ c = 0;
+ if (c < 5)
+ config_videomemory = videomemory[c];
+ else {
+ printf("Amount of video memory in Kbytes: ");
+ getstring(s);
+ config_videomemory = atoi(s);
+ printf("\n");
+ }
+
+ printf("%s", carddescintro_text);
+ if (card_selected != -1)
+ printf("Your card definition is %s.\n\n",
+ card[card_selected].name);
+ printf("The strings are free-form, spaces are allowed.\n");
+ printf("Enter an identifier for your video card definition: ");
+ getstring(s);
+ if (strlen(s) == 0)
+ if (card_selected != -1)
+ config_deviceidentifier = card[card_selected].name;
+ else
+ config_deviceidentifier = "My Video Card";
+ else {
+ config_deviceidentifier = Malloc(strlen(s) + 1);
+ strcpy(config_deviceidentifier, s);
+ }
+ printf("\n");
+
+ emptylines();
+
+ /*
+ * Initialize screen mode variables for svga and accel
+ * to default values.
+ * XXXX Doesn't leave room for off-screen caching in 16/32bpp modes
+ * for the accelerated servers in some situations.
+ */
+ config_modesline8bpp =
+ config_modesline16bpp =
+ config_modesline24bpp = "\"640x480\"";
+ config_virtualx8bpp = config_virtualx16bpp = config_virtualx24bpp =
+ config_virtualy8bpp = config_virtualy16bpp = config_virtualy24bpp = 0;
+ if (config_videomemory >= 4096) {
+ config_virtualx8bpp = 1600;
+ config_virtualy8bpp = 1280;
+ if (card_selected != -1 && !(card[card_selected].flags & UNSUPPORTED)) {
+ /*
+ * Allow room for font/pixmap cache for accel
+ * servers.
+ */
+ config_virtualx16bpp = 1280;
+ config_virtualy16bpp = 1024;
+ }
+ else {
+ config_virtualx16bpp = 1600;
+ config_virtualy16bpp = 1280;
+ }
+ if (card_selected != -1 && !(card[card_selected].flags & UNSUPPORTED)) {
+ config_virtualx24bpp = 1152;
+ config_virtualy24bpp = 900;
+ }
+ else {
+ config_virtualx24bpp = 1280;
+ config_virtualy24bpp = 1024;
+ }
+ /* Add 1600x1280 */
+ config_modesline8bpp = "\"640x480\" \"800x600\" \"1024x768\" \"1280x1024\"";
+ config_modesline16bpp = "\"640x480\" \"800x600\" \"1024x768\" \"1280x1024\"";
+ config_modesline24bpp = "\"640x480\" \"800x600\" \"1024x768\" \"1280x1024\"";
+ }
+ else
+ if (config_videomemory >= 2048) {
+ if (card_selected != -1 && !(card[card_selected].flags & UNSUPPORTED)) {
+ /*
+ * Allow room for font/pixmap cache for accel
+ * servers.
+ * Also the mach32 is has a limited width.
+ */
+ config_virtualx8bpp = 1280;
+ config_virtualy8bpp = 1024;
+ }
+ else {
+ config_virtualx8bpp = 1600;
+ config_virtualy8bpp = 1200;
+ }
+ if (card_selected != -1 && !(card[card_selected].flags & UNSUPPORTED)) {
+ config_virtualx16bpp = 1024;
+ config_virtualy16bpp = 768;
+ }
+ else {
+ config_virtualx16bpp = 1152;
+ config_virtualy16bpp = 900;
+ }
+ config_virtualx24bpp = 800;
+ config_virtualy24bpp = 600;
+ if (config_videomemory >= 2048 + 256) {
+ config_virtualx24bpp = 1024;
+ config_virtualy24bpp = 768;
+ }
+ config_modesline8bpp = "\"640x480\" \"800x600\" \"1024x768\" \"1280x1024\"";
+ config_modesline16bpp = "\"640x480\" \"800x600\" \"1024x768\"";
+ if (config_videomemory >= 2048 + 256)
+ config_modesline24bpp = "\"640x480\" \"800x600\" \"1024x768\"";
+ else
+ config_modesline24bpp = "\"640x480\" \"800x600\"";
+ }
+ else
+ if (config_videomemory >= 1024) {
+ if (card_selected != -1 && !(card[card_selected].flags & UNSUPPORTED)) {
+ /*
+ * Allow room for font/pixmap cache for accel
+ * servers.
+ */
+ config_virtualx8bpp = 1024;
+ config_virtualy8bpp = 768;
+ }
+ else {
+ config_virtualx8bpp = 1152;
+ config_virtualy8bpp = 900;
+ }
+ config_virtualx16bpp = 800; /* Forget about cache space; */
+ config_virtualy16bpp = 600; /* it's small enough as it is. */
+ config_virtualx24bpp = 640;
+ config_virtualy24bpp = 480;
+ config_modesline8bpp = "\"640x480\" \"800x600\" \"1024x768\"";
+ config_modesline16bpp = "\"640x480\" \"800x600\"";
+ config_modesline24bpp = "\"640x480\"";
+ }
+ else
+ if (config_videomemory >= 512) {
+ config_virtualx8bpp = 800;
+ config_virtualy8bpp = 600;
+ config_modesline8bpp = "\"640x480\" \"800x600\"";
+ config_modesline16bpp = "\"640x400\"";
+ }
+ else
+ if (config_videomemory >= 256) {
+ config_modesline8bpp = "\"640x400\"";
+ config_virtualx8bpp = 640;
+ config_virtualy8bpp = 400;
+ }
+ else {
+ printf("Fatal error: Invalid amount of video memory.\n");
+ exit(-1);
+ }
+
+#if 0
+ /*
+ * Handle the Ramdac/Clockchip setting.
+ */
+
+ printf("%s", devicesettingscomment_text);
+
+ if (card_selected == -1 || (card[card_selected].flags & UNSUPPORTED))
+ goto skipramdacselection;
+
+ printf("%s", ramdaccomment_text);
+
+ /* meanwhile there are so many RAMDACs that they do no longer fit on
+ * on page
+ */
+ for (np=12, i=0 ;;) {
+ int j;
+ for (j = i; j < i + np && j < NU_RAMDACS; j++)
+ printf("%3d %-60s%s\n", j+1,
+ ramdac_name[j],
+ ramdac_id[j]);
+
+ printf("\n");
+ if (card_selected != -1)
+ if (card[card_selected].ramdac != NULL)
+ printf("The card definition has Ramdac \"%s\".\n\n",
+ card[card_selected].ramdac);
+ printf("\n");
+ printf("Enter a number to choose the corresponding RAMDAC.\n");
+ printf("Press enter for the next page, q to quit without selection of a RAMDAC.\n");
+ printf("\n");
+ getstring(s);
+
+ config_ramdac = NULL;
+ if (s[0] == 'q')
+ break;
+
+ if (strlen(s) > 0) {
+ c = atoi(s)-1;
+ if (c >= 0 && c < NU_RAMDACS) {
+ config_ramdac = ramdac_id[atoi(s)-1];
+ break;
+ }
+ }
+
+ i += np;
+ if (np==12) np = 18; /* account intro lines only displayed 1st time */
+ if (i >= NU_RAMDACS)
+ i = 0;
+ emptylines();
+ }
+
+skipramdacselection:
+ emptylines();
+ printf("%s", clockchipcomment_text);
+
+ for (i = 0; i < NU_CLOCKCHIPS; i++)
+ printf("%2d %-60s%s\n",
+ i + 1, clockchip_name[i], clockchip_id[i]);
+
+ printf("\n");
+
+ if (card_selected != -1)
+ if (card[card_selected].clockchip != NULL)
+ printf("The card definition has Clockchip \"%s\"\n\n",
+ card[card_selected].clockchip);
+
+ printf("Just press enter if you don't want a Clockchip setting.\n");
+ printf("What Clockchip setting do you want (1-%d)? ", NU_CLOCKCHIPS);
+
+ getstring(s);
+ config_clockchip = NULL;
+ if (strlen(s) > 0)
+ config_clockchip = clockchip_id[atoi(s) - 1];
+
+ emptylines();
+
+ /*
+ * Optionally run X -probeonly to figure out the clocks.
+ */
+
+ config_numberofclockslines = 0;
+
+ printf("%s", deviceclockscomment_text);
+
+ printf("%s", deviceclocksquestion_text);
+#endif
+
+#if 0
+ /*
+ * XXX Change this to check for a CLOCKPROBE flag rather than an
+ * NOCLOCKPROBE.
+ */
+ if (card_selected != -1)
+ if (card[card_selected].flags & NOCLOCKPROBE)
+ printf("The card definition says to NOT probe clocks.\n");
+
+ if (config_clockchip != NULL) {
+ printf("Because you have enabled a Clockchip line, there's no need for clock\n"
+ "probing.\n");
+ keypress();
+ goto skipclockprobing;
+ }
+
+ printf("Do you want me to run 'X -probeonly' now? ");
+ getstring(s);
+ printf("\n");
+ if (answerisyes(s)) {
+ /*
+ * Write temporary XF86Config and run X -probeonly.
+ * Only allow when root.
+ */
+ FILE *f;
+ char *buf;
+ char syscmdline[2*256+100]; /* enough */
+ char *fname = NULL;
+ char *d2name = NULL;
+ char *d3name = NULL;
+
+ if (getuid() != 0) {
+ printf("Sorry, you must be root to do this.\n\n");
+ goto endofprobeonly;
+ }
+ printf("%s", probeonlywarning_text);
+ keypress();
+ fname = Malloc(strlen(temp_dir) +
+ strlen(TEMPORARY_XF86CONFIG_FILENAME) + 1);
+ sprintf(fname, "%s%s", temp_dir,
+ TEMPORARY_XF86CONFIG_FILENAME);
+ d2name = Malloc(strlen(temp_dir) + strlen(DUMBCONFIG2) + 1);
+ sprintf(d2name, "%s%s", temp_dir, DUMBCONFIG2);
+ d3name = Malloc(strlen(temp_dir) + strlen(DUMBCONFIG3) + 1);
+ sprintf(d3name, "%s%s", temp_dir, DUMBCONFIG3);
+ printf("Running X -probeonly -pn -xf86config %s.\n", fname);
+ write_XF86Config(fname);
+#ifndef __EMX__
+ sync();
+#endif
+ /* compose a line with the real path */
+#ifndef __EMX__
+ sprintf(syscmdline, "X -probeonly -pn -xf86config %s 2> %s",
+ fname, d2name);
+#else
+ /* OS/2 does not have symlinks, so "X" does not exist,
+ * call the real X server
+ */
+ sprintf(syscmdline,"%s/XFree86 -probeonly -pn -xf86config "
+ TEMPORARY_XF86CONFIG_FILENAME " 2>" DUMBCONFIG2,
+ __XOS2RedirRoot("/XFree86/bin",'\\'),
+ card[card_selected].server);
+#endif
+
+ if (system(syscmdline)) {
+ printf("X -probeonly call failed.\n");
+ printf("No Clocks line inserted.\n");
+ goto clocksprobefailed;
+ }
+ /* Look for 'clocks:' (case sensitive). */
+ sprintf(syscmdline, "grep clocks\\: %s > %s", d2name, d3name);
+ if (system(syscmdline)) {
+ printf("grep failed.\n");
+ printf("Cannot find clocks in server output.\n");
+ goto clocksprobefailed;
+ }
+ f = fopen(d3name, "r");
+ buf = Malloc(8192);
+ /* Parse lines. */
+ while (fgets(buf, 8192, f) != NULL) {
+ char *clks;
+ clks = strstr(buf, "clocks: ") + 8;
+ if (clks >= buf + 3 && strcmp(clks - 11, "num") == 0)
+ /* Reject lines with 'numclocks:'. */
+ continue;
+ if (clks >= buf + 8 && strcpy(clks - 14, "pixel ") == 0)
+ /* Reject lines with 'pixel clocks:'. */
+ continue;
+ clks[strlen(clks) - 1] = '\0'; /* Remove '\n'. */
+ config_clocksline[config_numberofclockslines] =
+ Malloc(strlen(clks) + 1);
+ strcpy(config_clocksline[config_numberofclockslines],
+ clks);
+ printf("Clocks %s\n", clks);
+ config_numberofclockslines++;
+ }
+ fclose(f);
+clocksprobefailed:
+ unlink(d3name);
+ unlink(d2name);
+ unlink(fname);
+ printf("\n");
+
+endofprobeonly:
+ keypress();
+ }
+skipclockprobing:
+#endif
+
+ /*
+ * For vga driver, no further configuration is required.
+ */
+ if (card_selected == -1 || (card[card_selected].flags & UNSUPPORTED))
+ return;
+
+ /*
+ * Configure the modes order.
+ */
+ config_virtual = 0;
+ for (;;) {
+ char modes[128];
+
+ emptylines();
+
+ printf("%s", modesorderintro_text);
+ printf("%s for 8-bit\n", config_modesline8bpp);
+ printf("%s for 16-bit\n", config_modesline16bpp);
+ printf("%s for 24-bit\n", config_modesline24bpp);
+ printf("\n");
+ printf("%s", modesorder_text2);
+
+ printf("Enter your choice: ");
+ getstring(s);
+ printf("\n");
+
+ c = atoi(s) - 1;
+ if (c < 0 || c >= 3)
+ break;
+
+ printf("Select modes from the following list:\n\n");
+
+ for (i = 0; i < NU_MODESTRINGS; i++)
+ printf(" %c %s\n", i < 9 ? '1' + i :
+ 'a' + i - 9,
+ modestring[i]);
+ printf("\n");
+
+ printf("%s", modeslist_text);
+
+ printf("Which modes? ");
+ getstring(s);
+ printf("\n");
+
+ modes[0] = '\0';
+ for (i = 0; i < strlen(s); i++) {
+ if ( NU_MODESTRINGS > 9 ) {
+ if ((s[i] < '1' || s[i] > '9') &&
+ (s[i] < 'a' || s[i] > 'a' + NU_MODESTRINGS - 10)) {
+ printf("Invalid mode skipped.\n");
+ continue;
+ }
+ }
+ else {
+ if (s[i] < '1' || s[i] > '0' + NU_MODESTRINGS) {
+ printf("Invalid mode skipped.\n");
+ continue;
+ }
+ }
+ if (i > 0)
+ strcat(modes, " ");
+ strcat(modes, modestring[s[i] <= '9' ? s[i] - '1' :
+ s[i] - 'a' + 9]);
+ }
+ switch (c) {
+ case 0 :
+ config_modesline8bpp = Malloc(strlen(modes) + 1);
+ strcpy(config_modesline8bpp, modes);
+ break;
+ case 1 :
+ config_modesline16bpp = Malloc(strlen(modes) + 1);
+ strcpy(config_modesline16bpp, modes);
+ break;
+ case 2 :
+ config_modesline24bpp = Malloc(strlen(modes) + 1);
+ strcpy(config_modesline24bpp, modes);
+ break;
+ }
+
+ printf("%s", virtual_text);
+
+ printf("Please answer the following question with either 'y' or 'n'.\n");
+ printf("Do you want a virtual screen that is larger than the physical screen?");
+ getstring(s);
+ if (answerisyes(s))
+ config_virtual = 1;
+ }
+}
+
+static char *defaultdepthtext =
+"Please specify which color depth you want to use by default:\n"
+"\n";
+
+static struct depth_str {
+ char *name;
+ char *desc;
+} depth_list[] = {
+ { "1", "1 bit (monochrome)" },
+ { "4", "4 bits (16 colors)" },
+ { "8", "8 bits (256 colors)" },
+ { "16", "16 bits (65536 colors)" },
+ { "24", "24 bits (16 million colors)" }
+};
+
+static int ndepths = sizeof(depth_list)/sizeof(struct depth_str);
+
+static void
+depth_configuration(void)
+{
+ int i;
+ char s[80];
+ int depth;
+
+ printf(defaultdepthtext);
+ for (i=0; i<ndepths; i++) {
+ printf("%3d %-50s\n",i+1,depth_list[i].desc);
+ }
+
+ printf("\nEnter a number to choose the default depth.\n\n");
+ getstring(s);
+ if (strlen(s) == 0)
+ depth = 0;
+ else {
+ i = atoi(s)-1;
+ depth = (i < 0 || i > ndepths) ? 0 : i;
+ }
+ config_depth = depth_list[depth].name;
+}
+
+/*
+ * Create the XF86Config file.
+ */
+
+static char *XF86Config_firstchunk_text =
+"# File generated by xf86config.\n"
+"\n"
+"#\n"
+"# Copyright (c) 1999 by The XFree86 Project, Inc.\n"
+"#\n"
+"# Permission is hereby granted, free of charge, to any person obtaining a\n"
+"# copy of this software and associated documentation files (the \"Software\"),\n"
+"# to deal in the Software without restriction, including without limitation\n"
+"# the rights to use, copy, modify, merge, publish, distribute, sublicense,\n"
+"# and/or sell copies of the Software, and to permit persons to whom the\n"
+"# Software is furnished to do so, subject to the following conditions:\n"
+"# \n"
+"# The above copyright notice and this permission notice shall be included in\n"
+"# all copies or substantial portions of the Software.\n"
+"# \n"
+"# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n"
+"# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n"
+"# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n"
+"# THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n"
+"# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF\n"
+"# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n"
+"# SOFTWARE.\n"
+"# \n"
+"# Except as contained in this notice, the name of the XFree86 Project shall\n"
+"# not be used in advertising or otherwise to promote the sale, use or other\n"
+"# dealings in this Software without prior written authorization from the\n"
+"# XFree86 Project.\n"
+"#\n"
+"\n"
+"# **********************************************************************\n"
+"# Refer to the XF86Config(4/5) man page for details about the format of \n"
+"# this file.\n"
+"# **********************************************************************\n"
+"\n"
+"# **********************************************************************\n"
+"# Module section -- this section is used to specify\n"
+"# which dynamically loadable modules to load.\n"
+"# **********************************************************************\n"
+"#\n"
+"Section \"Module\"\n"
+"\n"
+"# This loads the DBE extension module.\n"
+"\n"
+" Load \"dbe\" # Double buffer extension\n"
+"\n"
+"# This loads the miscellaneous extensions module, and disables\n"
+"# initialisation of the XFree86-DGA extension within that module.\n"
+" SubSection \"extmod\"\n"
+" Option \"omit xfree86-dga\" # don't initialise the DGA extension\n"
+" EndSubSection\n"
+"\n"
+"# This loads the Type1 and FreeType font modules\n"
+" Load \"type1\"\n"
+" Load \"freetype\"\n"
+"\n"
+"# This loads the GLX module\n"
+"# Load \"glx\"\n"
+"\n"
+"EndSection\n"
+"\n"
+"# **********************************************************************\n"
+"# Files section. This allows default font and rgb paths to be set\n"
+"# **********************************************************************\n"
+"\n"
+"Section \"Files\"\n"
+"\n"
+"# The location of the RGB database. Note, this is the name of the\n"
+"# file minus the extension (like \".txt\" or \".db\"). There is normally\n"
+"# no need to change the default.\n"
+"\n"
+" RgbPath \"" TREEROOTLX "/rgb\"\n"
+"\n"
+"# Multiple FontPath entries are allowed (which are concatenated together),\n"
+"# as well as specifying multiple comma-separated entries in one FontPath\n"
+"# command (or a combination of both methods)\n"
+"# \n"
+"# If you don't have a floating point coprocessor and emacs, Mosaic or other\n"
+"# programs take long to start up, try moving the Type1 and Speedo directory\n"
+"# to the end of this list (or comment them out).\n"
+"# \n"
+"\n";
+
+static char *XF86Config_fontpaths[] =
+{
+/* " FontPath \"" TREEROOTLX "/fonts/75dpi/\"\n"*/
+ "/fonts/local/",
+ "/fonts/misc/",
+ "/fonts/75dpi/:unscaled",
+ "/fonts/100dpi/:unscaled",
+ "/fonts/Type1/",
+ "/fonts/Speedo/",
+ "/fonts/75dpi/",
+ "/fonts/100dpi/",
+ 0 /* end of fontpaths */
+};
+
+static char *XF86Config_fontpathchunk_text =
+
+"\n"
+"# The module search path. The default path is shown here.\n"
+"\n"
+"# ModulePath \"" MODULEPATH "\"\n"
+"\n"
+"EndSection\n"
+"\n"
+"# **********************************************************************\n"
+"# Server flags section.\n"
+"# **********************************************************************\n"
+"\n"
+"Section \"ServerFlags\"\n"
+"\n"
+"# Uncomment this to cause a core dump at the spot where a signal is \n"
+"# received. This may leave the console in an unusable state, but may\n"
+"# provide a better stack trace in the core dump to aid in debugging\n"
+"\n"
+"# Option \"NoTrapSignals\"\n"
+"\n"
+"# Uncomment this to disable the <Crtl><Alt><BS> server abort sequence\n"
+"# This allows clients to receive this key event.\n"
+"\n"
+"# Option \"DontZap\"\n"
+"\n"
+"# Uncomment this to disable the <Crtl><Alt><KP_+>/<KP_-> mode switching\n"
+"# sequences. This allows clients to receive these key events.\n"
+"\n"
+"# Option \"Dont Zoom\"\n"
+"\n"
+"# Uncomment this to disable tuning with the xvidtune client. With\n"
+"# it the client can still run and fetch card and monitor attributes,\n"
+"# but it will not be allowed to change them. If it tries it will\n"
+"# receive a protocol error.\n"
+"\n"
+"# Option \"DisableVidModeExtension\"\n"
+"\n"
+"# Uncomment this to enable the use of a non-local xvidtune client. \n"
+"\n"
+"# Option \"AllowNonLocalXvidtune\"\n"
+"\n"
+"# Uncomment this to disable dynamically modifying the input device\n"
+"# (mouse and keyboard) settings. \n"
+"\n"
+"# Option \"DisableModInDev\"\n"
+"\n"
+"# Uncomment this to enable the use of a non-local client to\n"
+"# change the keyboard or mouse settings (currently only xset).\n"
+"\n"
+"# Option \"AllowNonLocalModInDev\"\n"
+"\n"
+"EndSection\n"
+"\n"
+"# **********************************************************************\n"
+"# Input devices\n"
+"# **********************************************************************\n"
+"\n"
+"# **********************************************************************\n"
+"# Core keyboard's InputDevice section\n"
+"# **********************************************************************\n"
+"\n"
+"Section \"InputDevice\"\n"
+"\n"
+" Identifier \"Keyboard1\"\n"
+" Driver \"Keyboard\"\n"
+"# For most OSs the protocol can be omitted (it defaults to \"Standard\").\n"
+"# When using XQUEUE (only for SVR3 and SVR4, but not Solaris),\n"
+"# uncomment the following line.\n"
+"\n"
+"# Option \"Protocol\" \"Xqueue\"\n"
+"\n"
+" Option \"AutoRepeat\" \"500 5\"\n"
+"\n"
+"# Specify which keyboard LEDs can be user-controlled (eg, with xset(1))\n"
+"# Option \"Xleds\" \"1 2 3\"\n"
+"\n";
+
+static char *keyboardchunk2_text =
+"\n";
+
+static char *keyboardchunk3_text =
+"# To customise the XKB settings to suit your keyboard, modify the\n"
+"# lines below (which are the defaults). For example, for a non-U.S.\n"
+"# keyboard, you will probably want to use:\n"
+"# Option \"XkbModel\" \"pc102\"\n"
+"# If you have a US Microsoft Natural keyboard, you can use:\n"
+"# Option \"XkbModel\" \"microsoft\"\n"
+"#\n"
+"# Then to change the language, change the Layout setting.\n"
+"# For example, a german layout can be obtained with:\n"
+"# Option \"XkbLayout\" \"de\"\n"
+"# or:\n"
+"# Option \"XkbLayout\" \"de\"\n"
+"# Option \"XkbVariant\" \"nodeadkeys\"\n"
+"#\n"
+"# If you'd like to switch the positions of your capslock and\n"
+"# control keys, use:\n"
+"# Option \"XkbOptions\" \"ctrl:swapcaps\"\n"
+"\n"
+"# These are the default XKB settings for XFree86\n"
+"# Option \"XkbRules\" \"xfree86\"\n"
+"# Option \"XkbModel\" \"pc101\"\n"
+"# Option \"XkbLayout\" \"us\"\n"
+"# Option \"XkbVariant\" \"\"\n"
+"# Option \"XkbOptions\" \"\"\n"
+"\n";
+
+static char *keyboardlastchunk_text =
+"\n"
+"EndSection\n"
+"\n"
+"\n";
+
+static char *pointersection_text1 =
+"# **********************************************************************\n"
+"# Core Pointer's InputDevice section\n"
+"# **********************************************************************\n"
+"\n"
+"Section \"InputDevice\"\n"
+"\n"
+"# Identifier and driver\n"
+"\n"
+" Identifier \"Mouse1\"\n"
+" Driver \"mouse\"\n"
+;
+
+static char *pointersection_text2 =
+"\n"
+"# When using XQUEUE, comment out the above two lines, and uncomment\n"
+"# the following line.\n"
+"\n"
+"# Option \"Protocol\" \"Xqueue\"\n"
+"\n"
+"# Baudrate and SampleRate are only for some Logitech mice. In\n"
+"# almost every case these lines should be omitted.\n"
+"\n"
+"# Option \"BaudRate\" \"9600\"\n"
+"# Option \"SampleRate\" \"150\"\n"
+"\n"
+"# Emulate3Buttons is an option for 2-button Microsoft mice\n"
+"# Emulate3Timeout is the timeout in milliseconds (default is 50ms)\n"
+"\n";
+
+static char *xinputsection_text =
+"# **********************************************************************\n"
+"# Other input device sections \n"
+"# this is optional and is required only if you\n"
+"# are using extended input devices. This is for example only. Refer\n"
+"# to the XF86Config man page for a description of the options.\n"
+"# **********************************************************************\n"
+"#\n"
+"# Section \"InputDevice\" \n"
+"# Identifier \"Mouse2\"\n"
+"# Driver \"mouse\"\n"
+"# Option \"Protocol\" \"MouseMan\"\n"
+"# Option \"Device\" \"/dev/mouse2\"\n"
+"# EndSection\n"
+"#\n"
+"# Section \"InputDevice\"\n"
+"# Identifier \"spaceball\"\n"
+"# Driver \"magellan\"\n"
+"# Option \"Device\" \"/dev/cua0\"\n"
+"# EndSection\n"
+"#\n"
+"# Section \"InputDevice\"\n"
+"# Identifier \"spaceball2\"\n"
+"# Driver \"spaceorb\"\n"
+"# Option \"Device\" \"/dev/cua0\"\n"
+"# EndSection\n"
+"#\n"
+"# Section \"InputDevice\"\n"
+"# Identifier \"touchscreen0\"\n"
+"# Driver \"microtouch\"\n"
+"# Option \"Device\" \"/dev/ttyS0\"\n"
+"# Option \"MinX\" \"1412\"\n"
+"# Option \"MaxX\" \"15184\"\n"
+"# Option \"MinY\" \"15372\"\n"
+"# Option \"MaxY\" \"1230\"\n"
+"# Option \"ScreenNumber\" \"0\"\n"
+"# Option \"ReportingMode\" \"Scaled\"\n"
+"# Option \"ButtonNumber\" \"1\"\n"
+"# Option \"SendCoreEvents\"\n"
+"# EndSection\n"
+"#\n"
+"# Section \"InputDevice\"\n"
+"# Identifier \"touchscreen1\"\n"
+"# Driver \"elo2300\"\n"
+"# Option \"Device\" \"/dev/ttyS0\"\n"
+"# Option \"MinX\" \"231\"\n"
+"# Option \"MaxX\" \"3868\"\n"
+"# Option \"MinY\" \"3858\"\n"
+"# Option \"MaxY\" \"272\"\n"
+"# Option \"ScreenNumber\" \"0\"\n"
+"# Option \"ReportingMode\" \"Scaled\"\n"
+"# Option \"ButtonThreshold\" \"17\"\n"
+"# Option \"ButtonNumber\" \"1\"\n"
+"# Option \"SendCoreEvents\"\n"
+"# EndSection\n"
+"\n";
+
+static char *monitorsection_text1 =
+"# **********************************************************************\n"
+"# Monitor section\n"
+"# **********************************************************************\n"
+"\n"
+"# Any number of monitor sections may be present\n"
+"\n"
+"Section \"Monitor\"\n"
+"\n";
+
+static char *monitorsection_text2 =
+"# HorizSync is in kHz unless units are specified.\n"
+"# HorizSync may be a comma separated list of discrete values, or a\n"
+"# comma separated list of ranges of values.\n"
+"# NOTE: THE VALUES HERE ARE EXAMPLES ONLY. REFER TO YOUR MONITOR\'S\n"
+"# USER MANUAL FOR THE CORRECT NUMBERS.\n"
+"\n";
+
+static char *monitorsection_text3 =
+"# HorizSync 30-64 # multisync\n"
+"# HorizSync 31.5, 35.2 # multiple fixed sync frequencies\n"
+"# HorizSync 15-25, 30-50 # multiple ranges of sync frequencies\n"
+"\n"
+"# VertRefresh is in Hz unless units are specified.\n"
+"# VertRefresh may be a comma separated list of discrete values, or a\n"
+"# comma separated list of ranges of values.\n"
+"# NOTE: THE VALUES HERE ARE EXAMPLES ONLY. REFER TO YOUR MONITOR\'S\n"
+"# USER MANUAL FOR THE CORRECT NUMBERS.\n"
+"\n";
+
+#if 0
+static char *monitorsection_text4 =
+"# Modes can be specified in two formats. A compact one-line format, or\n"
+"# a multi-line format.\n"
+"\n"
+"# These two are equivalent\n"
+"\n"
+"# ModeLine \"1024x768i\" 45 1024 1048 1208 1264 768 776 784 817 Interlace\n"
+"\n"
+"# Mode \"1024x768i\"\n"
+"# DotClock 45\n"
+"# HTimings 1024 1048 1208 1264\n"
+"# VTimings 768 776 784 817\n"
+"# Flags \"Interlace\"\n"
+"# EndMode\n"
+"\n";
+
+static char *modelines_text =
+"# This is a set of standard mode timings. Modes that are out of monitor spec\n"
+"# are automatically deleted by the server (provided the HorizSync and\n"
+"# VertRefresh lines are correct), so there's no immediate need to\n"
+"# delete mode timings (unless particular mode timings don't work on your\n"
+"# monitor). With these modes, the best standard mode that your monitor\n"
+"# and video card can support for a given resolution is automatically\n"
+"# used.\n"
+"\n"
+"# 640x400 @ 70 Hz, 31.5 kHz hsync\n"
+"Modeline \"640x400\" 25.175 640 664 760 800 400 409 411 450\n"
+"# 640x480 @ 60 Hz, 31.5 kHz hsync\n"
+"Modeline \"640x480\" 25.175 640 664 760 800 480 491 493 525\n"
+"# 800x600 @ 56 Hz, 35.15 kHz hsync\n"
+"ModeLine \"800x600\" 36 800 824 896 1024 600 601 603 625\n"
+"# 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync\n"
+"Modeline \"1024x768\" 44.9 1024 1048 1208 1264 768 776 784 817 Interlace\n"
+"\n"
+"# 640x400 @ 85 Hz, 37.86 kHz hsync\n"
+"Modeline \"640x400\" 31.5 640 672 736 832 400 401 404 445 -HSync +VSync\n"
+"# 640x480 @ 72 Hz, 36.5 kHz hsync\n"
+"Modeline \"640x480\" 31.5 640 680 720 864 480 488 491 521\n"
+"# 640x480 @ 75 Hz, 37.50 kHz hsync\n"
+"ModeLine \"640x480\" 31.5 640 656 720 840 480 481 484 500 -HSync -VSync\n"
+"# 800x600 @ 60 Hz, 37.8 kHz hsync\n"
+"Modeline \"800x600\" 40 800 840 968 1056 600 601 605 628 +hsync +vsync\n"
+"\n"
+"# 640x480 @ 85 Hz, 43.27 kHz hsync\n"
+"Modeline \"640x480\" 36 640 696 752 832 480 481 484 509 -HSync -VSync\n"
+"# 1152x864 @ 89 Hz interlaced, 44 kHz hsync\n"
+"ModeLine \"1152x864\" 65 1152 1168 1384 1480 864 865 875 985 Interlace\n"
+"\n"
+"# 800x600 @ 72 Hz, 48.0 kHz hsync\n"
+"Modeline \"800x600\" 50 800 856 976 1040 600 637 643 666 +hsync +vsync\n"
+"# 1024x768 @ 60 Hz, 48.4 kHz hsync\n"
+"Modeline \"1024x768\" 65 1024 1032 1176 1344 768 771 777 806 -hsync -vsync\n"
+"\n"
+"# 640x480 @ 100 Hz, 53.01 kHz hsync\n"
+"Modeline \"640x480\" 45.8 640 672 768 864 480 488 494 530 -HSync -VSync\n"
+"# 1152x864 @ 60 Hz, 53.5 kHz hsync\n"
+"Modeline \"1152x864\" 89.9 1152 1216 1472 1680 864 868 876 892 -HSync -VSync\n"
+"# 800x600 @ 85 Hz, 55.84 kHz hsync\n"
+"Modeline \"800x600\" 60.75 800 864 928 1088 600 616 621 657 -HSync -VSync\n"
+"\n"
+"# 1024x768 @ 70 Hz, 56.5 kHz hsync\n"
+"Modeline \"1024x768\" 75 1024 1048 1184 1328 768 771 777 806 -hsync -vsync\n"
+"# 1280x1024 @ 87 Hz interlaced, 51 kHz hsync\n"
+"Modeline \"1280x1024\" 80 1280 1296 1512 1568 1024 1025 1037 1165 Interlace\n"
+"\n"
+"# 800x600 @ 100 Hz, 64.02 kHz hsync\n"
+"Modeline \"800x600\" 69.65 800 864 928 1088 600 604 610 640 -HSync -VSync\n"
+"# 1024x768 @ 76 Hz, 62.5 kHz hsync\n"
+"Modeline \"1024x768\" 85 1024 1032 1152 1360 768 784 787 823\n"
+"# 1152x864 @ 70 Hz, 62.4 kHz hsync\n"
+"Modeline \"1152x864\" 92 1152 1208 1368 1474 864 865 875 895\n"
+"# 1280x1024 @ 61 Hz, 64.2 kHz hsync\n"
+"Modeline \"1280x1024\" 110 1280 1328 1512 1712 1024 1025 1028 1054\n"
+"\n"
+"# 1024x768 @ 85 Hz, 70.24 kHz hsync\n"
+"Modeline \"1024x768\" 98.9 1024 1056 1216 1408 768 782 788 822 -HSync -VSync\n"
+"# 1152x864 @ 78 Hz, 70.8 kHz hsync\n"
+"Modeline \"1152x864\" 110 1152 1240 1324 1552 864 864 876 908\n"
+"\n"
+"# 1280x1024 @ 70 Hz, 74.59 kHz hsync\n"
+"Modeline \"1280x1024\" 126.5 1280 1312 1472 1696 1024 1032 1040 1068 -HSync -VSync\n"
+"# 1600x1200 @ 60Hz, 75.00 kHz hsync\n"
+"Modeline \"1600x1200\" 162 1600 1664 1856 2160 1200 1201 1204 1250 +HSync +VSync\n"
+"# 1152x864 @ 84 Hz, 76.0 kHz hsync\n"
+"Modeline \"1152x864\" 135 1152 1464 1592 1776 864 864 876 908\n"
+"\n"
+"# 1280x1024 @ 74 Hz, 78.85 kHz hsync\n"
+"Modeline \"1280x1024\" 135 1280 1312 1456 1712 1024 1027 1030 1064\n"
+"\n"
+"# 1024x768 @ 100Hz, 80.21 kHz hsync\n"
+"Modeline \"1024x768\" 115.5 1024 1056 1248 1440 768 771 781 802 -HSync -VSync\n"
+"# 1280x1024 @ 76 Hz, 81.13 kHz hsync\n"
+"Modeline \"1280x1024\" 135 1280 1312 1416 1664 1024 1027 1030 1064\n"
+"\n"
+"# 1600x1200 @ 70 Hz, 87.50 kHz hsync\n"
+"Modeline \"1600x1200\" 189 1600 1664 1856 2160 1200 1201 1204 1250 -HSync -VSync\n"
+"# 1152x864 @ 100 Hz, 89.62 kHz hsync\n"
+"Modeline \"1152x864\" 137.65 1152 1184 1312 1536 864 866 885 902 -HSync -VSync\n"
+"# 1280x1024 @ 85 Hz, 91.15 kHz hsync\n"
+"Modeline \"1280x1024\" 157.5 1280 1344 1504 1728 1024 1025 1028 1072 +HSync +VSync\n"
+"# 1600x1200 @ 75 Hz, 93.75 kHz hsync\n"
+"Modeline \"1600x1200\" 202.5 1600 1664 1856 2160 1200 1201 1204 1250 +HSync +VSync\n"
+"# 1600x1200 @ 85 Hz, 105.77 kHz hsync\n"
+"Modeline \"1600x1200\" 220 1600 1616 1808 2080 1200 1204 1207 1244 +HSync +VSync\n"
+"# 1280x1024 @ 100 Hz, 107.16 kHz hsync\n"
+"Modeline \"1280x1024\" 181.75 1280 1312 1440 1696 1024 1031 1046 1072 -HSync -VSync\n"
+"\n"
+"# 1800x1440 @ 64Hz, 96.15 kHz hsync \n"
+"ModeLine \"1800X1440\" 230 1800 1896 2088 2392 1440 1441 1444 1490 +HSync +VSync\n"
+"# 1800x1440 @ 70Hz, 104.52 kHz hsync \n"
+"ModeLine \"1800X1440\" 250 1800 1896 2088 2392 1440 1441 1444 1490 +HSync +VSync\n"
+"\n"
+"# 512x384 @ 78 Hz, 31.50 kHz hsync\n"
+"Modeline \"512x384\" 20.160 512 528 592 640 384 385 388 404 -HSync -VSync\n"
+"# 512x384 @ 85 Hz, 34.38 kHz hsync\n"
+"Modeline \"512x384\" 22 512 528 592 640 384 385 388 404 -HSync -VSync\n"
+"\n"
+#if XFREE86_VERSION >= 311
+"# Low-res Doublescan modes\n"
+"# If your chipset does not support doublescan, you get a 'squashed'\n"
+"# resolution like 320x400.\n"
+"\n"
+"# 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio\n"
+"Modeline \"320x200\" 12.588 320 336 384 400 200 204 205 225 Doublescan\n"
+"# 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio\n"
+"Modeline \"320x240\" 12.588 320 336 384 400 240 245 246 262 Doublescan\n"
+"# 320x240 @ 72 Hz, 36.5 kHz hsync\n"
+"Modeline \"320x240\" 15.750 320 336 384 400 240 244 246 262 Doublescan\n"
+"# 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio\n"
+"ModeLine \"400x300\" 18 400 416 448 512 300 301 302 312 Doublescan\n"
+"# 400x300 @ 60 Hz, 37.8 kHz hsync\n"
+"Modeline \"400x300\" 20 400 416 480 528 300 301 303 314 Doublescan\n"
+"# 400x300 @ 72 Hz, 48.0 kHz hsync\n"
+"Modeline \"400x300\" 25 400 424 488 520 300 319 322 333 Doublescan\n"
+"# 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio\n"
+"ModeLine \"480x300\" 21.656 480 496 536 616 300 301 302 312 Doublescan\n"
+"# 480x300 @ 60 Hz, 37.8 kHz hsync\n"
+"Modeline \"480x300\" 23.890 480 496 576 632 300 301 303 314 Doublescan\n"
+"# 480x300 @ 63 Hz, 39.6 kHz hsync\n"
+"Modeline \"480x300\" 25 480 496 576 632 300 301 303 314 Doublescan\n"
+"# 480x300 @ 72 Hz, 48.0 kHz hsync\n"
+"Modeline \"480x300\" 29.952 480 504 584 624 300 319 322 333 Doublescan\n"
+"\n"
+#endif
+;
+#endif
+
+static char *devicesection_text =
+"# **********************************************************************\n"
+"# Graphics device section\n"
+"# **********************************************************************\n"
+"\n"
+"# Any number of graphics device sections may be present\n"
+"\n"
+"# Standard VGA Device:\n"
+"\n"
+"Section \"Device\"\n"
+" Identifier \"Standard VGA\"\n"
+" VendorName \"Unknown\"\n"
+" BoardName \"Unknown\"\n"
+"\n"
+"# The chipset line is optional in most cases. It can be used to override\n"
+"# the driver's chipset detection, and should not normally be specified.\n"
+"\n"
+"# Chipset \"generic\"\n"
+"\n"
+"# The Driver line must be present. When using run-time loadable driver\n"
+"# modules, this line instructs the server to load the specified driver\n"
+"# module. Even when not using loadable driver modules, this line\n"
+"# indicates which driver should interpret the information in this section.\n"
+"\n"
+" Driver \"vga\"\n"
+"# The BusID line is used to specify which of possibly multiple devices\n"
+"# this section is intended for. When this line isn't present, a device\n"
+"# section can only match up with the primary video device. For PCI\n"
+"# devices a line like the following could be used. This line should not\n"
+"# normally be included unless there is more than one video device\n"
+"# intalled.\n"
+"\n"
+"# BusID \"PCI:0:10:0\"\n"
+"\n"
+"# VideoRam 256\n"
+"\n"
+"# Clocks 25.2 28.3\n"
+"\n"
+"EndSection\n"
+"\n"
+"# Device configured by xf86config:\n"
+"\n";
+
+static char *screensection_text1 =
+"# **********************************************************************\n"
+"# Screen sections\n"
+"# **********************************************************************\n"
+"\n"
+"# Any number of screen sections may be present. Each describes\n"
+"# the configuration of a single screen. A single specific screen section\n"
+"# may be specified from the X server command line with the \"-screen\"\n"
+"# option.\n";
+
+static char *serverlayout_section_text1 =
+"# **********************************************************************\n"
+"# ServerLayout sections.\n"
+"# **********************************************************************\n"
+"\n"
+"# Any number of ServerLayout sections may be present. Each describes\n"
+"# the way multiple screens are organised. A specific ServerLayout\n"
+"# section may be specified from the X server command line with the\n"
+"# \"-layout\" option. In the absence of this, the first section is used.\n"
+"# When now ServerLayout section is present, the first Screen section\n"
+"# is used alone.\n"
+"\n"
+"Section \"ServerLayout\"\n"
+"\n"
+"# The Identifier line must be present\n"
+" Identifier \"Simple Layout\"\n"
+"\n"
+"# Each Screen line specifies a Screen section name, and optionally\n"
+"# the relative position of other screens. The four names after\n"
+"# primary screen name are the screens to the top, bottom, left and right\n"
+"# of the primary screen. In this example, screen 2 is located to the\n"
+"# right of screen 1.\n"
+"\n";
+
+static char *serverlayout_section_text2 =
+"\n"
+"# Each InputDevice line specifies an InputDevice section name and\n"
+"# optionally some options to specify the way the device is to be\n"
+"# used. Those options include \"CorePointer\", \"CoreKeyboard\" and\n"
+"# \"SendCoreEvents\".\n"
+"\n"
+" InputDevice \"Mouse1\" \"CorePointer\"\n"
+" InputDevice \"Keyboard1\" \"CoreKeyboard\"\n"
+"\n"
+"EndSection\n"
+"\n";
+
+static void
+write_fontpath_section(FILE *f)
+{
+ /* this will create the Fontpath lines, but only after checking,
+ * that the corresponding dir exists (was THE absolute problem
+ * users had with XFree86/OS2 3.1.2D !)
+ */
+ int i;
+ char cur[256+20],*colon, *hash;
+
+ for (i=0; XF86Config_fontpaths[i]; i++) {
+ strcpy(cur,TREEROOTLX);
+ strcat(cur,XF86Config_fontpaths[i]);
+ /* remove a ':' */
+ colon = strchr(cur+2,':'); /* OS/2: C:/...:scaled */
+ if (colon) *colon = 0;
+ hash = exists_dir(cur) ? "" : "#";
+ fprintf(f,"%s FontPath \"%s%s\"\n",
+ hash,
+ TREEROOTLX,
+ XF86Config_fontpaths[i]);
+ }
+}
+
+static void
+write_XF86Config(char *filename)
+{
+ FILE *f;
+
+ /*
+ * Write the file.
+ */
+
+ f = fopen(filename, "w");
+ if (f == NULL) {
+ printf("Failed to open filename for writing.\n");
+#ifndef __EMX__
+ if (getuid() != 0)
+ printf("Maybe you need to be root to write to the specified directory?\n");
+#endif
+ exit(-1);
+ }
+
+ fprintf(f, "%s", XF86Config_firstchunk_text);
+ write_fontpath_section(f);
+ fprintf(f, "%s", XF86Config_fontpathchunk_text);
+
+ /*
+ * Write keyboard section.
+ */
+ if (config_altmeta) {
+ fprintf(f, " Option \"LeftAlt\" \"Meta\"\n");
+ fprintf(f, " Option \"RightAlt\" \"ModeShift\"\n");
+ }
+ else {
+ fprintf(f, "# Option \"LeftAlt\" \"Meta\"\n");
+ fprintf(f, "# Option \"RightAlt\" \"ModeShift\"\n");
+ }
+ fprintf(f, "%s", keyboardchunk2_text);
+
+ fprintf(f, "%s", keyboardchunk3_text);
+ if (config_xkbdisable) {
+ fprintf(f, " Option \"XkbDisable\"\n\n");
+ } else {
+ fprintf(f, "# Option \"XkbDisable\"\n\n");
+ }
+ fprintf(f, " Option \"XkbRules\" \"%s\"\n",
+ config_xkbrules);
+ fprintf(f, " Option \"XkbModel\" \"%s\"\n",
+ config_xkbmodel);
+ fprintf(f, " Option \"XkbLayout\" \"%s\"\n",
+ config_xkblayout);
+
+ fprintf(f, "%s",keyboardlastchunk_text);
+
+ /*
+ * Write pointer section.
+ */
+ fprintf(f, "%s", pointersection_text1);
+ fprintf(f, " Option \"Protocol\" \"%s\"\n",
+ mousetype_identifier[config_mousetype]);
+#ifndef __EMX__
+ fprintf(f, " Option \"Device\" \"%s\"\n", config_pointerdevice);
+#endif
+ fprintf(f, "%s", pointersection_text2);
+ if (!config_emulate3buttons)
+ fprintf(f, "#");
+ fprintf(f, " Option \"Emulate3Buttons\"\n");
+ if (!config_emulate3buttons)
+ fprintf(f, "#");
+ fprintf(f, " Option \"Emulate3Timeout\" 50\n\n");
+ fprintf(f, "# ChordMiddle is an option for some 3-button Logitech mice\n\n");
+ if (!config_chordmiddle)
+ fprintf(f, "#");
+ fprintf(f, " Option \"ChordMiddle\"\n\n");
+ if (config_cleardtrrts) {
+ fprintf(f, " Option \"ClearDTR\"\n");
+ fprintf(f, " Option \"ClearRTS\"\n\n");
+ }
+ fprintf(f, "EndSection\n\n\n");
+
+ /*
+ * Write XInput sample section
+ */
+ fprintf(f, "%s", xinputsection_text);
+
+ /*
+ * Write monitor section.
+ */
+ fprintf(f, "%s", monitorsection_text1);
+ fprintf(f, " Identifier \"%s\"\n", config_monitoridentifier);
+ fprintf(f, "\n");
+ fprintf(f, "%s", monitorsection_text2);
+ fprintf(f, " HorizSync %s\n", config_hsyncrange);
+ fprintf(f, "\n");
+ fprintf(f, "%s", monitorsection_text3);
+ fprintf(f, " VertRefresh %s\n", config_vsyncrange);
+ fprintf(f, "\n");
+#if 0
+ fprintf(f, "%s", monitorsection_text4);
+ fprintf(f, "%s", modelines_text);
+#endif
+ fprintf(f, "EndSection\n\n\n");
+
+ /*
+ * Write Device section.
+ */
+
+ fprintf(f, "%s", devicesection_text);
+ fprintf(f, "Section \"Device\"\n");
+ fprintf(f, " Identifier \"%s\"\n", config_deviceidentifier);
+ if (card_selected != -1) {
+ fprintf(f, " Driver \"%s\"\n", card[card_selected].driver);
+ if (card[card_selected].flags & UNSUPPORTED) {
+ fprintf(f, " # unsupported card\n");
+ }
+ } else {
+ fprintf(f, " Driver \"vga\"\n"
+ " # unsupported card\n");
+ }
+ /* Rely on server to detect video memory. */
+ fprintf(f, " #VideoRam %d\n", config_videomemory);
+ if (card_selected != -1)
+ /* Add comment lines from card definition. */
+ fprintf(f, card[card_selected].lines);
+ if (config_ramdac != NULL)
+ fprintf(f, " Ramdac \"%s\"\n", config_ramdac);
+ if (card_selected != -1)
+ if (card[card_selected].dacspeed != NULL)
+ fprintf(f, " Dacspeed %s\n",
+ card[card_selected].dacspeed);
+ if (config_clockchip != NULL)
+ fprintf(f, " Clockchip \"%s\"\n", config_clockchip);
+ else
+ if (config_numberofclockslines == 0)
+ fprintf(f, " # Insert Clocks lines here if appropriate\n");
+ else {
+ int i;
+ for (i = 0; i < config_numberofclockslines; i++)
+ fprintf(f, " Clocks %s\n", config_clocksline[i]);
+ }
+ fprintf(f, "EndSection\n\n\n");
+
+ /*
+ * Write Screen sections.
+ */
+
+ fprintf(f, "%s", screensection_text1);
+
+ fprintf(f,
+ "Section \"Screen\"\n"
+ " Identifier \"Screen 1\"\n"
+ " Device \"%s\"\n"
+ " Monitor \"%s\"\n"
+ " DefaultDepth %s\n"
+ "\n"
+ " Subsection \"Display\"\n"
+ " Depth 8\n"
+ " Modes %s\n"
+ " ViewPort 0 0\n",
+ config_deviceidentifier,
+ config_monitoridentifier,
+ config_depth,
+ config_modesline8bpp);
+ if (config_virtual)
+ fprintf(f, " Virtual %d %d\n",
+ config_virtualx8bpp, config_virtualy8bpp);
+ fprintf(f,
+ " EndSubsection\n"
+ " Subsection \"Display\"\n"
+ " Depth 16\n"
+ " Modes %s\n"
+ " ViewPort 0 0\n",
+ config_modesline16bpp);
+ if (config_virtual)
+ fprintf(f, " Virtual %d %d\n",
+ config_virtualx16bpp, config_virtualy16bpp);
+ fprintf(f,
+ " EndSubsection\n"
+ " Subsection \"Display\"\n"
+ " Depth 24\n"
+ " Modes %s\n"
+ " ViewPort 0 0\n",
+ config_modesline24bpp);
+ if (config_virtual)
+ fprintf(f, " Virtual %d %d\n",
+ config_virtualx24bpp, config_virtualy24bpp);
+ fprintf(f,
+ " EndSubsection\n"
+ "EndSection\n"
+ "\n");
+
+ /*
+ * ServerLayout section
+ */
+
+ fprintf(f, serverlayout_section_text1);
+ /* replace with screen config */
+ fprintf(f, " Screen \"Screen 1\"\n");
+
+ fprintf(f, serverlayout_section_text2);
+
+ fclose(f);
+}
+
+
+/*
+ * Ask where to write XF86Config to. Returns filename.
+ */
+
+static char *
+ask_XF86Config_location(void) {
+ char s[80];
+ char *filename;
+
+ printf(
+"I am going to write the XF86Config file now. Make sure you don't accidently\n"
+"overwrite a previously configured one.\n\n");
+
+#ifndef __EMX__
+ if (getuid() == 0) {
+#ifdef PREFER_XF86CONFIG_IN_ETC
+ printf("Shall I write it to /etc/X11/XF86Config? ");
+ getstring(s);
+ printf("\n");
+ if (answerisyes(s))
+ return "/etc/X11/XF86Config";
+#endif
+
+ printf("Please answer the following question with either 'y' or 'n'.\n");
+ printf("Shall I write it to the default location, /usr/X11R6/etc/X11/XF86Config? ");
+ getstring(s);
+ printf("\n");
+ if (answerisyes(s))
+ return "/usr/X11R6/etc/X11/XF86Config";
+
+#ifndef PREFER_XF86CONFIG_IN_ETC
+ printf("Shall I write it to /etc/X11/XF86Config? ");
+ getstring(s);
+ printf("\n");
+ if (answerisyes(s))
+ return "/etc/X11/XF86Config";
+#endif
+#else /* __EMX__ */
+ {
+ printf("Please answer the following question with either 'y' or 'n'.\n");
+ printf("Shall I write it to the default location, drive:/XFree86/lib/X11/XConfig? ");
+ getstring(s);
+ printf("\n");
+ if (answerisyes(s)) {
+ return __XOS2RedirRoot("/XFree86/lib/X11/XConfig",'/');
+ }
+#endif /* __EMX__ */
+ }
+
+ printf("Do you want it written to the current directory as 'XF86Config'? ");
+ getstring(s);
+ printf("\n");
+ if (answerisyes(s))
+#ifndef __EMX__
+ return "XF86Config";
+#else
+ return "XConfig";
+#endif
+
+ printf("Please give a filename to write to: ");
+ getstring(s);
+ printf("\n");
+ filename = Malloc(strlen(s) + 1);
+ strcpy(filename, s);
+ return filename;
+}
+
+
+/*
+ * Check if an earlier version of XFree86 is installed; warn about proper
+ * search path order in that case.
+ */
+
+static char *notinstalled_text =
+"The directory " TREEROOT " does not exist. This probably means that you have\n"
+"not yet installed an X11R6-based version of XFree86. Please install\n"
+"XFree86 3.1+ before running this program, following the instructions in\n"
+"the INSTALL or README that comes with the XFree86 distribution for your OS.\n"
+"For a minimal installation it is sufficient to only install base binaries,\n"
+"libraries, configuration files and a server that you want to use.\n"
+"\n";
+
+#ifndef __EMX__
+static char *oldxfree86_text =
+"The directory '/usr/X386/bin' exists. You probably have an old version of\n"
+"XFree86 installed (XFree86 3.1 installs in '" TREEROOT "' instead of\n"
+"'/usr/X386').\n"
+"\n"
+"It is important that the directory '" TREEROOT "' is present in your\n"
+"search path, *before* any occurrence of '/usr/X386/bin'. If you have installed\n"
+"X program binaries that are not in the base XFree86 distribution in\n"
+"'/usr/X386/bin', you can keep the directory in your path as long as it is\n"
+"after '" TREEROOT "'.\n"
+"\n";
+
+static char *pathnote_text =
+"Note that the X binary directory in your path may be a symbolic link.\n"
+"In that case you could modify the symbolic link to point to the new binaries.\n"
+"Example: 'rm -f /usr/bin/X11; ln -s /usr/X11R6/bin /usr/bin/X11', if the\n"
+"link is '/usr/bin/X11'.\n"
+"\n"
+"Make sure the path is OK before continuing.\n";
+#endif
+
+static void
+path_check(void) {
+ char s[80];
+ int ok;
+
+ ok = exists_dir(TREEROOT);
+ if (!ok) {
+ printf("%s", notinstalled_text);
+ printf("Do you want to continue? ");
+ getstring(s);
+ if (!answerisyes(s))
+ exit(-1);
+ printf("\n");
+ }
+
+#ifndef __EMX__
+ ok = exists_dir("/usr/X386/bin");
+ if (!ok)
+ return;
+
+ printf("%s", oldxfree86_text);
+ printf("Your PATH is currently set as follows:\n%s\n\n",
+ getenv("PATH"));
+ printf("%s", pathnote_text);
+ keypress();
+#endif
+}
+
+
+/*
+ * Program entry point.
+ */
+
+int
+main(int argc, char *argv[]) {
+
+ createtmpdir();
+
+ emptylines();
+
+ printf("%s", intro_text);
+
+ keypress();
+ emptylines();
+
+ path_check();
+
+ emptylines();
+
+ mouse_configuration();
+
+ emptylines();
+
+ keyboard_configuration();
+
+ emptylines();
+
+ monitor_configuration();
+
+ emptylines();
+
+ carddb_configuration();
+
+ emptylines();
+
+ screen_configuration();
+
+ emptylines();
+
+ depth_configuration();
+
+ emptylines();
+
+ write_XF86Config(ask_XF86Config_location());
+
+ printf("%s", finalcomment_text);
+
+ exit(0);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_16bpp/Imakefile b/xc/programs/Xserver/hw/xfree86/xf8_16bpp/Imakefile
new file mode 100644
index 000000000..b85f6f98f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_16bpp/Imakefile
@@ -0,0 +1,33 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/xf8_16bpp/Imakefile,v 1.3 1999/08/14 10:50:17 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+
+#if DoLoadableServer
+XFMODSRC = cfb8_16module.c
+XFMODOBJ = cfb8_16module.o
+#endif
+
+SRCS = cfbscrinit.c cfbwindow.c $(XFMODSRC)
+
+OBJS = cfbscrinit.o cfbwindow.o $(XFMODOBJ)
+
+INCLUDES = -I. -I$(XF86SRC)/xf1bpp -I$(SERVERSRC)/mfb \
+ -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mi -I$(SERVERSRC)/include \
+ -I$(XF86OSSRC) -I$(XF86COMSRC) \
+ -I$(FONTINCSRC) -I$(XINCLUDESRC)
+
+
+ModuleObjectRule()
+LibraryModuleTarget(xf8_16bpp,$(OBJS))
+LintLibraryTarget(xf8_16bpp,$(SRCS))
+NormalLintTarget($(LINTDEFS) $(SRCS))
+
+InstallLibraryModule(xf8_16bpp,$(MODULEDIR),.)
+
+DependTarget()
+
+InstallDriverSDKLibraryModule(xf8_16bpp,$(DRIVERSDKMODULEDIR),.)
+
+InstallDriverSDKNonExecFile(cfb8_16.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfb8_16.h b/xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfb8_16.h
new file mode 100644
index 000000000..b7fa9fd00
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfb8_16.h
@@ -0,0 +1,69 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfb8_16.h,v 1.2 1999/03/28 15:33:09 dawes Exp $ */
+
+#ifndef _CFB8_16_H
+#define _CFB8_16_H
+
+#include "regionstr.h"
+#include "windowstr.h"
+
+typedef struct {
+ pointer pix8;
+ int width8;
+ pointer pix16;
+ int width16;
+ unsigned char key;
+} cfb8_16ScreenRec, *cfb8_16ScreenPtr;
+
+extern int cfb8_16ScreenPrivateIndex;
+
+Bool
+cfb8_16ScreenInit (
+ ScreenPtr pScreen,
+ pointer pbits16,
+ pointer pbits8,
+ int xsize, int ysize,
+ int dpix, int dpiy,
+ int width16,
+ int width8
+);
+
+void
+cfb8_16PaintWindow (
+ WindowPtr pWin,
+ RegionPtr pRegion,
+ int what
+);
+
+Bool cfb8_16CreateWindow(WindowPtr pWin);
+Bool cfb8_16DestroyWindow(WindowPtr pWin);
+
+Bool
+cfb8_16PositionWindow(
+ WindowPtr pWin,
+ int x, int y
+);
+
+void
+cfb8_16CopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc
+);
+
+Bool
+cfb8_16ChangeWindowAttributes(
+ WindowPtr pWin,
+ unsigned long mask
+);
+
+void
+cfb8_16WindowExposures(
+ WindowPtr pWin,
+ RegionPtr pReg,
+ RegionPtr pOtherReg
+);
+
+#define CFB8_16_GET_SCREEN_PRIVATE(pScreen)\
+ (cfb8_16ScreenPtr)((pScreen)->devPrivates[cfb8_16ScreenPrivateIndex].ptr)
+
+#endif /* _CFB8_16_H */
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfb8_16module.c b/xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfb8_16module.c
new file mode 100644
index 000000000..d0d1974e7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfb8_16module.c
@@ -0,0 +1,37 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfb8_16module.c,v 1.1 1999/01/31 12:22:16 dawes Exp $ */
+
+#ifdef XFree86LOADER
+
+#include "xf86Module.h"
+
+static MODULESETUPPROTO(xf8_16bppSetup);
+
+static XF86ModuleVersionInfo VersRec =
+{
+ "xf8_16bpp",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_ANSIC, /* Only need the ansic layer */
+ ABI_ANSIC_VERSION,
+ NULL,
+ {0,0,0,0} /* signature, to be patched into the file by a tool */
+};
+
+XF86ModuleData xf8_16bppModuleData = { &VersRec, xf8_16bppSetup, NULL };
+
+static pointer
+xf8_16bppSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ if (!LoadSubModule(module, "cfb", NULL, NULL, NULL, NULL,
+ errmaj, errmin))
+ return NULL;
+ if (!LoadSubModule(module, "cfb16", NULL, NULL, NULL, NULL,
+ errmaj, errmin))
+ return NULL;
+ return (pointer)1; /* non-NULL required to indicate success */
+}
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfbscrinit.c b/xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfbscrinit.c
new file mode 100644
index 000000000..410c64297
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfbscrinit.c
@@ -0,0 +1,511 @@
+/*
+ Copyright (C) 1999. The XFree86 Project Inc.
+
+ Written by Mark Vojkovich (mvojkovi@ucsd.edu)
+*/
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfbscrinit.c,v 1.5 1999/04/04 08:46:24 dawes Exp $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "misc.h"
+#include "servermd.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "resource.h"
+#include "colormap.h"
+#include "colormapst.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb8_16.h"
+#include "mi.h"
+#include "micmap.h"
+#include "mistruct.h"
+#include "gcstruct.h"
+#include "dix.h"
+#include "mibstore.h"
+#include "xf86str.h"
+#include "xf86.h"
+
+/* CAUTION: We require that cfb8 and cfb16 were NOT
+ compiled with CFB_NEED_SCREEN_PRIVATE */
+
+int cfb8_16ScreenPrivateIndex;
+
+static unsigned long cfb8_16Generation = 0;
+extern WindowPtr *WindowTable;
+
+static PixmapPtr cfb8_16GetWindowPixmap(WindowPtr pWin);
+static void
+cfb8_16SaveAreas(
+ PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+);
+
+static void
+cfb8_16RestoreAreas(
+ PixmapPtr pPixmap,
+ RegionPtr prgnRestore,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+);
+
+static BSFuncRec cfb8_16BSFuncRec = {
+ cfb8_16SaveAreas,
+ cfb8_16RestoreAreas,
+ (BackingStoreSetClipmaskRgnProcPtr) 0,
+ (BackingStoreGetImagePixmapProcPtr) 0,
+ (BackingStoreGetSpansPixmapProcPtr) 0,
+};
+
+static void
+cfb8_16GetSpans(
+ DrawablePtr pDraw,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pchardstStart
+);
+
+static void
+cfb8_16GetImage (
+ DrawablePtr pDraw,
+ int sx, int sy, int w, int h,
+ unsigned int format,
+ unsigned long planeMask,
+ char *pdstLine
+);
+
+static Bool cfb8_16CreateGC(GCPtr pGC);
+static Bool cfb8_16SaveRestoreImage(int index, SaveRestoreFlags what);
+
+
+static Bool
+cfb8_16AllocatePrivates(ScreenPtr pScreen)
+{
+ cfb8_16ScreenPtr pScreenPriv;
+
+ if(cfb8_16Generation != serverGeneration) {
+ if((cfb8_16ScreenPrivateIndex = AllocateScreenPrivateIndex()) < 0)
+ return FALSE;
+ cfb8_16Generation = serverGeneration;
+ }
+
+ if (!(pScreenPriv = xalloc(sizeof(cfb8_16ScreenRec))))
+ return FALSE;
+
+ pScreen->devPrivates[cfb8_16ScreenPrivateIndex].ptr = (pointer)pScreenPriv;
+
+
+ /* All cfb will have the same GC and Window private indicies */
+ if(!mfbAllocatePrivates(pScreen,&cfbWindowPrivateIndex, &cfbGCPrivateIndex))
+ return FALSE;
+
+ /* The cfb indicies are the mfb indicies. Reallocating them resizes them */
+ if(!AllocateWindowPrivate(pScreen,cfbWindowPrivateIndex,sizeof(cfbPrivWin)))
+ return FALSE;
+
+ if(!AllocateGCPrivate(pScreen, cfbGCPrivateIndex, sizeof(cfbPrivGC)))
+ return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+cfb8_16SetupScreen(
+ ScreenPtr pScreen,
+ int xsize, int ysize, /* in pixels */
+ int dpix, int dpiy
+){
+ if (!cfb8_16AllocatePrivates(pScreen))
+ return FALSE;
+ pScreen->defColormap = FakeClientID(0);
+ /* let CreateDefColormap do whatever it wants for pixels */
+ pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0;
+ pScreen->QueryBestSize = mfbQueryBestSize;
+ /* SaveScreen */
+ pScreen->GetImage = cfb8_16GetImage;
+ pScreen->GetSpans = cfb8_16GetSpans;
+ pScreen->CreateWindow = cfb8_16CreateWindow;
+ pScreen->DestroyWindow = cfb8_16DestroyWindow;
+ pScreen->PositionWindow = cfb8_16PositionWindow;
+ pScreen->ChangeWindowAttributes = cfb8_16ChangeWindowAttributes;
+ pScreen->RealizeWindow = cfb16MapWindow; /* OK */
+ pScreen->UnrealizeWindow = cfb16UnmapWindow; /* OK */
+ pScreen->PaintWindowBackground = cfb8_16PaintWindow;
+ pScreen->PaintWindowBorder = cfb8_16PaintWindow;
+ pScreen->CopyWindow = cfb8_16CopyWindow;
+ pScreen->CreatePixmap = cfb16CreatePixmap; /* OK */
+ pScreen->DestroyPixmap = cfb16DestroyPixmap; /* OK */
+ pScreen->RealizeFont = mfbRealizeFont;
+ pScreen->UnrealizeFont = mfbUnrealizeFont;
+ pScreen->CreateGC = cfb8_16CreateGC;
+ pScreen->CreateColormap = miInitializeColormap;
+ pScreen->DestroyColormap = (void (*)())NoopDDA;
+ pScreen->InstallColormap = miInstallColormap;
+ pScreen->UninstallColormap = miUninstallColormap;
+ pScreen->ListInstalledColormaps = miListInstalledColormaps;
+ pScreen->StoreColors = (void (*)())NoopDDA;
+ pScreen->ResolveColor = miResolveColor;
+ pScreen->BitmapToRegion = mfbPixmapToRegion;
+
+ mfbRegisterCopyPlaneProc (pScreen, cfbCopyPlane);
+ return TRUE;
+}
+
+static Bool
+cfb8_16CreateScreenResources(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ cfb8_16ScreenPtr pScreenPriv = CFB8_16_GET_SCREEN_PRIVATE(pScreen);
+ PixmapPtr pix8, pix16;
+
+ xfree(pScreen->devPrivate); /* freeing miScreenInitParmsRec */
+
+ pix8 = (*pScreen->CreatePixmap)(pScreen, 0, 0, 8);
+ pix16 = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScrn->depth);
+ if(!pix16 || !pix8)
+ return FALSE;
+
+ pix8->drawable.width = pScreen->width;
+ pix8->drawable.height = pScreen->height;
+ pix8->devKind = pScreenPriv->width8;
+ pix8->devPrivate.ptr = pScreenPriv->pix8;
+
+ pix16->drawable.width = pScreen->width;
+ pix16->drawable.height = pScreen->height;
+ pix16->devKind = pScreenPriv->width16 * 2;
+ pix16->devPrivate.ptr = pScreenPriv->pix16;
+
+ pScreenPriv->pix8 = (pointer)pix8;
+ pScreenPriv->pix16 = (pointer)pix16;
+
+ pScreen->devPrivate = (pointer)pix16;
+
+ return TRUE;
+}
+
+
+static Bool
+cfb8_16CloseScreen (int i, ScreenPtr pScreen)
+{
+ cfb8_16ScreenPtr pScreenPriv = CFB8_16_GET_SCREEN_PRIVATE(pScreen);
+
+ xfree((pointer) pScreenPriv);
+
+ return(cfb16CloseScreen(i, pScreen));
+}
+
+static Bool
+cfb8_16FinishScreenInit(
+ ScreenPtr pScreen,
+ int xsize, int ysize, /* in pixels */
+ int dpix, int dpiy /* dots per inch */
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VisualPtr visuals;
+ DepthPtr depths;
+ int nvisuals;
+ int ndepths;
+ int rootdepth;
+ VisualID defaultVisual;
+
+ rootdepth = 0;
+ if (!miInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
+ &defaultVisual,((unsigned long)1<<(16-1)), 8, -1))
+ return FALSE;
+ if (! miScreenInit(pScreen, NULL, xsize, ysize, dpix, dpiy, 0,
+ rootdepth, ndepths, depths,
+ defaultVisual, nvisuals, visuals))
+ return FALSE;
+
+ pScreen->BackingStoreFuncs = cfb8_16BSFuncRec;
+ pScreen->CreateScreenResources = cfb8_16CreateScreenResources;
+ pScreen->CloseScreen = cfb8_16CloseScreen;
+ pScreen->GetWindowPixmap = cfb8_16GetWindowPixmap;
+ pScreen->WindowExposures = cfb8_16WindowExposures;
+
+ pScrn->SaveRestoreImage = cfb8_16SaveRestoreImage;
+
+ return TRUE;
+}
+
+Bool
+cfb8_16ScreenInit(
+ ScreenPtr pScreen,
+ pointer pbits16, /* pointer to screen bitmap */
+ pointer pbits8,
+ int xsize, int ysize, /* in pixels */
+ int dpix, int dpiy, /* dots per inch */
+ int width16, /* pixel width of frame buffer */
+ int width8
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ cfb8_16ScreenPtr pScreenPriv;
+
+ if (!cfb8_16SetupScreen(pScreen, xsize, ysize, dpix, dpiy))
+ return FALSE;
+
+ pScreenPriv = CFB8_16_GET_SCREEN_PRIVATE(pScreen);
+ pScreenPriv->pix8 = pbits8;
+ pScreenPriv->pix16 = pbits16;
+ pScreenPriv->width8 = width8;
+ pScreenPriv->width16 = width16;
+ pScreenPriv->key = pScrn->colorKey;
+
+ return cfb8_16FinishScreenInit(pScreen, xsize, ysize, dpix, dpiy);
+}
+
+
+static PixmapPtr
+cfb8_16GetWindowPixmap(WindowPtr pWin)
+{
+ cfb8_16ScreenPtr pScreenPriv =
+ CFB8_16_GET_SCREEN_PRIVATE(pWin->drawable.pScreen);
+
+ return((pWin->drawable.bitsPerPixel == 16) ?
+ (PixmapPtr)pScreenPriv->pix16 : (PixmapPtr)pScreenPriv->pix8);
+}
+
+static void
+cfb8_16GetImage (
+ DrawablePtr pDraw,
+ int sx, int sy, int w, int h,
+ unsigned int format,
+ unsigned long planemask,
+ char *pdstLine
+){
+ if(!w || !h) return;
+
+ if(pDraw->bitsPerPixel == 16)
+ cfb16GetImage(pDraw, sx, sy, w, h, format, planemask, pdstLine);
+ else
+ cfbGetImage(pDraw, sx, sy, w, h, format, planemask, pdstLine);
+}
+
+static void
+cfb8_16GetSpans(
+ DrawablePtr pDraw,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pDst
+){
+ if(pDraw->bitsPerPixel == 16)
+ cfb16GetSpans(pDraw, wMax, ppt, pwidth, nspans, pDst);
+ else
+ cfbGetSpans(pDraw, wMax, ppt, pwidth, nspans, pDst);
+}
+
+static void
+cfb8_16SaveAreas(
+ PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+){
+ if(pWin->drawable.bitsPerPixel == 16)
+ cfb16SaveAreas(pPixmap, prgnSave, xorg, yorg, pWin);
+ else
+ cfbSaveAreas(pPixmap, prgnSave, xorg, yorg, pWin);
+}
+
+static void
+cfb8_16RestoreAreas(
+ PixmapPtr pPixmap,
+ RegionPtr prgnRestore,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+){
+ if(pWin->drawable.bitsPerPixel == 16)
+ cfb16RestoreAreas(pPixmap, prgnRestore, xorg, yorg, pWin);
+ else
+ cfbRestoreAreas(pPixmap, prgnRestore, xorg, yorg, pWin);
+}
+
+
+static Bool
+cfb8_16CreateGC(GCPtr pGC)
+{
+ if(pGC->depth == 8)
+ return(cfbCreateGC(pGC));
+ else
+ return(cfb16CreateGC(pGC));
+}
+
+static Bool
+cfb8_16SaveRestoreImage(int index, SaveRestoreFlags what)
+{
+ ScreenPtr pScreen = xf86Screens[index]->pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ cfb8_16ScreenPtr pScreenPriv = CFB8_16_GET_SCREEN_PRIVATE(pScreen);
+ static unsigned char *devPrivates8[MAXSCREENS];
+ static unsigned char *devPrivates16[MAXSCREENS];
+ static int devKinds8[MAXSCREENS];
+ static int devKinds16[MAXSCREENS];
+ pointer devPrivate8, devPrivate16;
+ Bool ret = FALSE;
+ int devKind8, devKind16;
+ PixmapPtr pPixSrc, pPixDst;
+ BoxRec pixBox;
+ RegionRec pixReg;
+ DDXPointRec Pnt;
+
+ pixBox.x1 = pixBox.y1 = 0;
+ pixBox.x2 = pScreen->width;
+ pixBox.y2 = pScreen->height;
+ (*pScreen->RegionInit)(&pixReg, &pixBox, 1);
+
+ Pnt.x = 0;
+ Pnt.y = 0;
+
+ switch (what) {
+ case SaveImage:
+
+ /* save the old data */
+ devPrivates8[index] =
+ (unsigned char*)(((PixmapPtr)pScreenPriv->pix8)->devPrivate.ptr);
+ devKinds8[index] = ((PixmapPtr)pScreenPriv->pix8)->devKind;
+ devPrivates16[index] =
+ (unsigned char*)(((PixmapPtr)pScreenPriv->pix16)->devPrivate.ptr);
+ devKinds16[index] = ((PixmapPtr)pScreenPriv->pix16)->devKind;
+
+ /* allocate new data */
+ devKind8 = PixmapBytePad(pScreen->width, 8);
+ if(!(devPrivate8 = xalloc(devKind8 * pScreen->height)))
+ break;
+
+ devKind16 = PixmapBytePad(pScreen->width, pScrn->depth);
+ if(!(devPrivate16 = xalloc(devKind16 * pScreen->height))) {
+ xfree(devPrivate8);
+ break;
+ }
+
+ /* DEPTH 8 */
+
+ pPixDst = GetScratchPixmapHeader(pScreen, pScreen->width,
+ pScreen->height, 8, 8, devKind8, devPrivate8);
+
+ pPixSrc = GetScratchPixmapHeader(pScreen, pScreen->width,
+ pScreen->height, 8, 8, devKinds8[index],
+ devPrivates8[index]);
+
+ cfbDoBitbltCopy((DrawablePtr)pPixSrc, (DrawablePtr)pPixDst,
+ GXcopy, &pixReg, &Pnt, ~0L);
+
+ FreeScratchPixmapHeader(pPixSrc);
+ FreeScratchPixmapHeader(pPixDst);
+
+ ((PixmapPtr)pScreenPriv->pix8)->devPrivate.ptr = (pointer)devPrivate8;
+ ((PixmapPtr)pScreenPriv->pix8)->devKind = devKind8;
+
+
+ /* DEPTH 16 */
+
+ pPixDst = GetScratchPixmapHeader(pScreen, pScreen->width,
+ pScreen->height, pScrn->depth, 16, devKind16,
+ devPrivate16);
+
+ pPixSrc = GetScratchPixmapHeader(pScreen, pScreen->width,
+ pScreen->height, pScrn->depth, 16,
+ devKinds16[index], devPrivates16[index]);
+
+ cfb16DoBitbltCopy((DrawablePtr)pPixSrc, (DrawablePtr)pPixDst,
+ GXcopy, &pixReg, &Pnt, ~0L);
+
+ FreeScratchPixmapHeader(pPixSrc);
+ FreeScratchPixmapHeader(pPixDst);
+
+ ((PixmapPtr)pScreenPriv->pix16)->devPrivate.ptr = (pointer)devPrivate16;
+ ((PixmapPtr)pScreenPriv->pix16)->devKind = devKind16;
+ ((PixmapPtr)pScreen->devPrivate)->devKind = devKind16;
+ ((PixmapPtr)pScreen->devPrivate)->devPrivate.ptr =
+ (pointer)devPrivate16;
+
+ ret = TRUE;
+
+ WalkTree(xf86Screens[index]->pScreen,xf86NewSerialNumber,0);
+
+ break;
+ case RestoreImage:
+
+ if (!xf86ServerIsResetting()) {
+ devPrivate8 = ((PixmapPtr)pScreenPriv->pix8)->devPrivate.ptr;
+ devKind8 = ((PixmapPtr)pScreenPriv->pix8)->devKind;
+
+ devPrivate16 = ((PixmapPtr)pScreenPriv->pix16)->devPrivate.ptr;
+ devKind16 = ((PixmapPtr)pScreenPriv->pix16)->devKind;
+
+ /* DEPTH 8 */
+
+ pPixSrc = GetScratchPixmapHeader(pScreen, pScreen->width,
+ pScreen->height, 8, 8, devKind8, devPrivate8);
+
+
+ pPixDst = GetScratchPixmapHeader(pScreen, pScreen->width,
+ pScreen->height, 8, 8, devKinds8[index],
+ devPrivates8[index]);
+
+ cfbDoBitbltCopy((DrawablePtr)pPixSrc, (DrawablePtr)pPixDst,
+ GXcopy, &pixReg, &Pnt, ~0L);
+
+ xfree(devPrivate8);
+ FreeScratchPixmapHeader(pPixSrc);
+ FreeScratchPixmapHeader(pPixDst);
+
+ ((PixmapPtr)pScreenPriv->pix8)->devPrivate.ptr =
+ (pointer)devPrivates8[index];
+ ((PixmapPtr)pScreenPriv->pix8)->devKind = devKinds8[index];
+
+
+ /* DEPTH 16 */
+ pPixSrc = GetScratchPixmapHeader(pScreen, pScreen->width,
+ pScreen->height, 16, 16, devKind16, devPrivate16);
+
+
+ pPixDst = GetScratchPixmapHeader(pScreen, pScreen->width,
+ pScreen->height, 16, 16, devKinds16[index],
+ devPrivates16[index]);
+
+ cfbDoBitbltCopy((DrawablePtr)pPixSrc, (DrawablePtr)pPixDst,
+ GXcopy, &pixReg, &Pnt, ~0L);
+
+ xfree(devPrivate16);
+ FreeScratchPixmapHeader(pPixSrc);
+ FreeScratchPixmapHeader(pPixDst);
+
+ ((PixmapPtr)pScreenPriv->pix16)->devPrivate.ptr =
+ (pointer)devPrivates16[index];
+ ((PixmapPtr)pScreenPriv->pix16)->devKind = devKinds16[index];
+ ((PixmapPtr)pScreen->devPrivate)->devKind = devKinds16[index];
+ ((PixmapPtr)pScreen->devPrivate)->devPrivate.ptr =
+ (pointer)devPrivates16[index];
+
+ WalkTree(xf86Screens[index]->pScreen,xf86NewSerialNumber,0);
+ ret = TRUE;
+ break;
+ }
+ /* Fall through */
+ case FreeImage:
+ if (((PixmapPtr)pScreenPriv->pix16)->devPrivate.ptr)
+ xfree(((PixmapPtr)pScreenPriv->pix16)->devPrivate.ptr);
+ if (((PixmapPtr)pScreenPriv->pix8)->devPrivate.ptr)
+ xfree(((PixmapPtr)pScreenPriv->pix8)->devPrivate.ptr);
+ ret = TRUE;
+ break;
+ default:
+ ErrorF("cfb8_16SaveRestoreImage: Invalid flag (%d)\n", what);
+ }
+ (*pScreen->RegionUninit)(&pixReg);
+ return ret;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfbwindow.c b/xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfbwindow.c
new file mode 100644
index 000000000..81aee232f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfbwindow.c
@@ -0,0 +1,173 @@
+/*
+ Copyright (C) 1999. The XFree86 Project Inc.
+
+ Written by Mark Vojkovich (mvojkovi@ucsd.edu)
+*/
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_16bpp/cfbwindow.c,v 1.2 1999/03/21 07:35:34 dawes Exp $ */
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb16.h"
+#include "cfb8_16.h"
+#include "mistruct.h"
+#include "regionstr.h"
+#include "cfbmskbits.h"
+#include "xf86.h"
+
+/* We don't bother with cfb's fastBackground/Border so we don't
+ need to use the Window privates */
+
+extern WindowPtr *WindowTable;
+
+
+Bool
+cfb8_16CreateWindow(WindowPtr pWin)
+{
+ cfbPrivWin *pPrivWin = cfbGetWindowPrivate(pWin);
+
+ pPrivWin->fastBackground = FALSE;
+ pPrivWin->fastBorder = FALSE;
+
+ return TRUE;
+}
+
+
+Bool
+cfb8_16DestroyWindow(WindowPtr pWin)
+{
+ return TRUE;
+}
+
+Bool
+cfb8_16PositionWindow(
+ WindowPtr pWin,
+ int x, int y
+){
+ return TRUE;
+}
+
+
+void
+cfb8_16CopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ cfb8_16ScreenPtr pScreenPriv =
+ CFB8_16_GET_SCREEN_PRIVATE(pWin->drawable.pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ DDXPointPtr ppt, pptSrc;
+ RegionRec rgnDst;
+ BoxPtr pbox;
+ int i, nbox, dx, dy;
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+
+ REGION_INIT(pScreen, &rgnDst, NullBox, 0);
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
+ REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
+
+ nbox = REGION_NUM_RECTS(&rgnDst);
+ if(nbox &&
+ (pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) {
+
+ pbox = REGION_RECTS(&rgnDst);
+ for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+ cfbDoBitbltCopy((DrawablePtr)pRoot, (DrawablePtr)pRoot,
+ GXcopy, &rgnDst, pptSrc, ~0L);
+ if(pWin->drawable.bitsPerPixel == 16)
+ cfb16DoBitbltCopy((DrawablePtr)pScreenPriv->pix16,
+ (DrawablePtr)pScreenPriv->pix16,
+ GXcopy, &rgnDst, pptSrc, ~0L);
+
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+
+ REGION_UNINIT(pScreen, &rgnDst);
+
+ if(pWin->drawable.depth == 8) {
+ REGION_INIT(pScreen, &rgnDst, NullBox, 0);
+ miSegregateChildren(pWin, &rgnDst, pScrn->depth);
+ if(REGION_NOTEMPTY(pScreen, &rgnDst)) {
+ REGION_INTERSECT(pScreen, &rgnDst, &rgnDst, prgnSrc);
+ nbox = REGION_NUM_RECTS(&rgnDst);
+ if(nbox &&
+ (pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))){
+
+ pbox = REGION_RECTS(&rgnDst);
+ for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ cfb16DoBitbltCopy((DrawablePtr)pScreenPriv->pix16,
+ (DrawablePtr)pScreenPriv->pix16,
+ GXcopy, &rgnDst, pptSrc, ~0L);
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+ }
+ REGION_UNINIT(pScreen, &rgnDst);
+ }
+}
+
+Bool
+cfb8_16ChangeWindowAttributes(
+ WindowPtr pWin,
+ unsigned long mask
+){
+ return TRUE;
+}
+
+
+void
+cfb8_16WindowExposures(
+ WindowPtr pWin,
+ RegionPtr pReg,
+ RegionPtr pOtherReg
+){
+
+ if(REGION_NUM_RECTS(pReg) && (pWin->drawable.bitsPerPixel == 16)) {
+ cfb8_16ScreenPtr pScreenPriv =
+ CFB8_16_GET_SCREEN_PRIVATE(pWin->drawable.pScreen);
+
+ cfbFillBoxSolid((DrawablePtr)pScreenPriv->pix8,
+ REGION_NUM_RECTS(pReg), REGION_RECTS(pReg),
+ pScreenPriv->key);
+ }
+
+ miWindowExposures(pWin, pReg, pOtherReg);
+}
+
+
+void
+cfb8_16PaintWindow (
+ WindowPtr pWin,
+ RegionPtr pRegion,
+ int what
+){
+ if(pWin->drawable.bitsPerPixel == 16) {
+ cfb16PaintWindow(pWin, pRegion, what);
+ if(what == PW_BORDER) {
+ cfb8_16ScreenPtr pScreenPriv =
+ CFB8_16_GET_SCREEN_PRIVATE(pWin->drawable.pScreen);
+
+ cfbFillBoxSolid((DrawablePtr)pScreenPriv->pix8,
+ REGION_NUM_RECTS(pRegion), REGION_RECTS(pRegion),
+ pScreenPriv->key);
+ }
+ } else
+ cfbPaintWindow(pWin, pRegion, what);
+
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_32bpp/Imakefile b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/Imakefile
new file mode 100644
index 000000000..70b60b2f7
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/Imakefile
@@ -0,0 +1,42 @@
+XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/Imakefile,v 1.5 1999/08/14 10:50:17 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+
+#if DoLoadableServer
+XFMODSRC = cfb8_32module.c
+XFMODOBJ = cfb8_32module.o
+#endif
+
+SRCS = cfbbstore.c cfbcpyarea.c cfbcpyplane.c cfbgcmisc.c \
+ cfbimage.c cfbpntwin.c cfbscrinit.c cfbwindow.c xf86overlay.c \
+ $(XFMODSRC) cfbgc8.c cfbgc32.c
+
+
+OBJS = cfbbstore.o cfbcpyarea.o cfbcpyplane.o cfbgcmisc.o \
+ cfbimage.o cfbpntwin.o cfbscrinit.o cfbwindow.o xf86overlay.o \
+ $(XFMODOBJ) cfbgc8.o cfbgc32.o
+
+INCLUDES = -I. -I$(XF86SRC)/xf1bpp -I$(SERVERSRC)/mfb \
+ -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mi -I$(SERVERSRC)/include \
+ -I$(XF86OSSRC) -I$(XF86COMSRC) -I$(EXTINCSRC) \
+ -I$(FONTINCSRC) -I$(XINCLUDESRC)
+
+
+ModuleObjectRule()
+LibraryModuleTarget(xf8_32bpp,$(OBJS))
+LintLibraryTarget(xf8_32bpp,$(SRCS))
+NormalLintTarget($(LINTDEFS) $(SRCS))
+
+ObjectFromSpecialSource(cfbgc8,cfbgc,-DPSZ=8)
+ObjectFromSpecialSource(cfbgc32,cfbgc,-DPSZ=32)
+
+
+InstallLibraryModule(xf8_32bpp,$(MODULEDIR),.)
+
+DependTarget()
+
+InstallDriverSDKLibraryModule(xf8_32bpp,$(DRIVERSDKMODULEDIR),.)
+
+InstallDriverSDKNonExecFile(cfb8_32.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfb8_32.h b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfb8_32.h
new file mode 100644
index 000000000..58707b46a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfb8_32.h
@@ -0,0 +1,233 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfb8_32.h,v 1.2 1999/03/21 07:35:34 dawes Exp $ */
+
+#ifndef _CFB8_32_H
+#define _CFB8_32_H
+
+#include "gcstruct.h"
+
+typedef struct {
+ GCOps *Ops8bpp;
+ GCOps *Ops32bpp;
+ unsigned long changes;
+ Bool OpsAre8bpp;
+} cfb8_32GCRec, *cfb8_32GCPtr;
+
+typedef struct {
+ unsigned char key;
+} cfb8_32ScreenRec, *cfb8_32ScreenPtr;
+
+
+extern int cfb8_32GCPrivateIndex;
+extern int cfb8_32ScreenPrivateIndex;
+
+void
+cfb8_32SaveAreas(
+ PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+);
+
+void
+cfb8_32RestoreAreas(
+ PixmapPtr pPixmap,
+ RegionPtr prgnRestore,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+);
+
+RegionPtr
+cfb8_32CopyArea(
+ DrawablePtr pSrcDraw,
+ DrawablePtr pDstDraw,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+);
+
+void
+cfbDoBitblt8To32(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ int rop,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc,
+ unsigned long planemask,
+ unsigned long bitPlane
+);
+
+void
+cfbDoBitblt32To8(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ int rop,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc,
+ unsigned long planemask,
+ unsigned long bitPlane
+);
+
+
+void
+cfb8_32ValidateGC8(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDrawable
+);
+
+void
+cfb8_32ValidateGC32(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDrawable
+);
+
+Bool cfb8_32CreateGC(GCPtr pGC);
+
+void
+cfb8_32GetSpans(
+ DrawablePtr pDraw,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pchardstStart
+);
+
+void
+cfb8_32PutImage (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage
+);
+
+void
+cfb8_32GetImage (
+ DrawablePtr pDraw,
+ int sx, int sy, int w, int h,
+ unsigned int format,
+ unsigned long planeMask,
+ char *pdstLine
+);
+
+void
+cfb8_32PaintWindow (
+ WindowPtr pWin,
+ RegionPtr pRegion,
+ int what
+);
+
+Bool
+cfb8_32ScreenInit (
+ ScreenPtr pScreen,
+ pointer pbits,
+ int xsize, int ysize,
+ int dpix, int dpiy,
+ int width
+);
+
+void
+cfb8_32SegregateChildren (
+ WindowPtr pWin,
+ RegionPtr pReg32
+);
+
+
+void
+cfb8_32FillBoxSolid8 (
+ DrawablePtr pDraw,
+ int nbox,
+ BoxPtr pBox,
+ unsigned long color
+);
+
+
+void
+cfb8_32FillBoxSolid32 (
+ DrawablePtr pDraw,
+ int nbox,
+ BoxPtr pBox,
+ unsigned long color
+);
+
+RegionPtr
+cfb8_32CopyPlane(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+);
+
+void
+cfbDoBitblt8To8GXcopy(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ int rop,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc,
+ unsigned long pm,
+ unsigned long bitPlane
+);
+
+void
+cfbDoBitblt24To24GXcopy(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ int rop,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc,
+ unsigned long pm,
+ unsigned long bitPlane
+);
+
+Bool cfb8_32CreateWindow(WindowPtr pWin);
+Bool cfb8_32DestroyWindow(WindowPtr pWin);
+
+Bool
+cfb8_32PositionWindow(
+ WindowPtr pWin,
+ int x, int y
+);
+
+void
+cfb8_32CopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc
+);
+
+Bool
+cfb8_32ChangeWindowAttributes(
+ WindowPtr pWin,
+ unsigned long mask
+);
+
+void
+cfb8_32WindowExposures(
+ WindowPtr pWin,
+ RegionPtr pReg,
+ RegionPtr pOtherReg
+);
+
+#define CFB8_32_GET_GC_PRIVATE(pGC)\
+ (cfb8_32GCPtr)((pGC)->devPrivates[cfb8_32GCPrivateIndex].ptr)
+
+#define CFB8_32_GET_SCREEN_PRIVATE(pScreen)\
+ (cfb8_32ScreenPtr)((pScreen)->devPrivates[cfb8_32ScreenPrivateIndex].ptr)
+
+Bool xf86Overlay8Plus32Init (ScreenPtr pScreen);
+
+unsigned char
+cfb8_32GetKey(ScreenPtr pScreen);
+
+#endif /* _CFB8_32_H */
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfb8_32module.c b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfb8_32module.c
new file mode 100644
index 000000000..9ed6b2018
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfb8_32module.c
@@ -0,0 +1,38 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfb8_32module.c,v 1.6 1999/01/26 05:54:20 dawes Exp $ */
+
+
+#ifdef XFree86LOADER
+
+#include "xf86Module.h"
+
+static MODULESETUPPROTO(xf8_32bppSetup);
+
+static XF86ModuleVersionInfo VersRec =
+{
+ "xf8_32bpp",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_ANSIC, /* Only need the ansic layer */
+ ABI_ANSIC_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0} /* signature, to be patched into the file by a tool */
+};
+
+XF86ModuleData xf8_32bppModuleData = { &VersRec, xf8_32bppSetup, NULL };
+
+static pointer
+xf8_32bppSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ if (!LoadSubModule(module, "cfb", NULL, NULL, NULL, NULL,
+ errmaj, errmin))
+ return NULL;
+ if (!LoadSubModule(module, "cfb32", NULL, NULL, NULL, NULL,
+ errmaj, errmin))
+ return NULL;
+ return (pointer)1; /* non-NULL required to indicate success */
+}
+
+#endif
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbbstore.c b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbbstore.c
new file mode 100644
index 000000000..919fabf5f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbbstore.c
@@ -0,0 +1,102 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbbstore.c,v 1.2 1999/01/31 12:22:17 dawes Exp $ */
+
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb32.h"
+#include "cfb8_32.h"
+#include "X.h"
+#include "mibstore.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+
+void
+cfb8_32SaveAreas(
+ PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+){
+ DDXPointPtr pPt;
+ DDXPointPtr pPtsInit;
+ BoxPtr pBox;
+ int i;
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ PixmapPtr pScrPix;
+
+ if(pPixmap->drawable.bitsPerPixel == 32) {
+ cfb32SaveAreas(pPixmap, prgnSave, xorg, yorg, pWin);
+ return;
+ }
+
+ i = REGION_NUM_RECTS(prgnSave);
+ pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(i * sizeof(DDXPointRec));
+ if (!pPtsInit)
+ return;
+
+ pBox = REGION_RECTS(prgnSave);
+ pPt = pPtsInit;
+ while (--i >= 0) {
+ pPt->x = pBox->x1 + xorg;
+ pPt->y = pBox->y1 + yorg;
+ pPt++;
+ pBox++;
+ }
+
+ pScrPix = (PixmapPtr) pScreen->devPrivate;
+
+ cfbDoBitblt32To8((DrawablePtr) pScrPix, (DrawablePtr)pPixmap,
+ GXcopy, prgnSave, pPtsInit, ~0L, 0);
+
+ DEALLOCATE_LOCAL (pPtsInit);
+}
+
+
+void
+cfb8_32RestoreAreas(
+ PixmapPtr pPixmap,
+ RegionPtr prgnRestore,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+){
+ DDXPointPtr pPt;
+ DDXPointPtr pPtsInit;
+ BoxPtr pBox;
+ int i;
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ PixmapPtr pScrPix;
+
+ i = REGION_NUM_RECTS(prgnRestore);
+ pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(i*sizeof(DDXPointRec));
+ if (!pPtsInit)
+ return;
+
+ pBox = REGION_RECTS(prgnRestore);
+ pPt = pPtsInit;
+ while (--i >= 0) {
+ pPt->x = pBox->x1 - xorg;
+ pPt->y = pBox->y1 - yorg;
+ pPt++;
+ pBox++;
+ }
+
+ pScrPix = (PixmapPtr) pScreen->devPrivate;
+
+ if(pPixmap->drawable.bitsPerPixel == 32) {
+ if(pWin->drawable.depth == 24)
+ cfb32DoBitbltCopy((DrawablePtr)pPixmap, (DrawablePtr) pScrPix,
+ GXcopy, prgnRestore, pPtsInit, 0x00ffffff);
+ else
+ cfb32DoBitbltCopy((DrawablePtr)pPixmap, (DrawablePtr) pScrPix,
+ GXcopy, prgnRestore, pPtsInit, ~0);
+ } else {
+ cfbDoBitblt8To32((DrawablePtr)pPixmap, (DrawablePtr) pScrPix,
+ GXcopy, prgnRestore, pPtsInit, ~0L, 0);
+ }
+
+ DEALLOCATE_LOCAL (pPtsInit);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbcpyarea.c b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbcpyarea.c
new file mode 100644
index 000000000..5d6514137
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbcpyarea.c
@@ -0,0 +1,540 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbcpyarea.c,v 1.4 1999/05/23 06:33:51 dawes Exp $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "servermd.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "resource.h"
+#include "colormap.h"
+#include "colormapst.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb32.h"
+#include "cfb8_32.h"
+#include "mi.h"
+#include "mistruct.h"
+#include "dix.h"
+#include "mibstore.h"
+
+
+RegionPtr
+cfb8_32CopyArea(
+ DrawablePtr pSrcDraw,
+ DrawablePtr pDstDraw,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+){
+
+ if(pSrcDraw->bitsPerPixel == 32) {
+ if(pDstDraw->bitsPerPixel == 32) {
+ if((pGC->alu == GXcopy) && (pGC->planemask == 0xff000000)) {
+ return cfb32BitBlt (pSrcDraw, pDstDraw,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ cfbDoBitblt8To8GXcopy, 0L);
+ }
+ return(cfb32CopyArea(pSrcDraw, pDstDraw, pGC, srcx, srcy,
+ width, height, dstx, dsty));
+ } else {
+ /* have to translate 32 -> 8 copies */
+ return cfb32BitBlt (pSrcDraw, pDstDraw,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ cfbDoBitblt32To8, 0L);
+ }
+ } else {
+ if(pDstDraw->bitsPerPixel == 32) {
+ /* have to translate 8 -> 32 copies */
+ return cfb32BitBlt (pSrcDraw, pDstDraw,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ cfbDoBitblt8To32, 0L);
+ } else {
+ return(cfbCopyArea(pSrcDraw, pDstDraw, pGC, srcx, srcy,
+ width, height, dstx, dsty));
+ }
+ }
+}
+
+
+
+
+void
+cfbDoBitblt8To32(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ int rop,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc,
+ unsigned long pm,
+ unsigned long bitPlane
+){
+ BoxPtr pbox = REGION_RECTS(prgnDst);
+ int nbox = REGION_NUM_RECTS(prgnDst);
+ unsigned char *ptr8, *ptr32;
+ unsigned char *data8, *data32;
+ int pitch8, pitch32;
+ int height, width, i;
+
+ cfbGetByteWidthAndPointer(pSrc, pitch8, ptr8);
+ cfbGetByteWidthAndPointer(pDst, pitch32, ptr32);
+ ptr32 += 3; /* point to the top byte */
+
+ pm >>= 24;
+
+ if((pm == 0xff) && (rop == GXcopy)) {
+ for(;nbox; pbox++, pptSrc++, nbox--) {
+ data8 = ptr8 + (pptSrc->y * pitch8) + pptSrc->x;
+ data32 = ptr32 + (pbox->y1 * pitch32) + (pbox->x1 << 2);
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ while(height--) {
+ for(i = 0; i < width; i++)
+ data32[i << 2] = data8[i];
+ data8 += pitch8;
+ data32 += pitch32;
+ }
+ }
+ } else { /* it ain't pretty, but hey */
+ for(;nbox; pbox++, pptSrc++, nbox--) {
+ data8 = ptr8 + (pptSrc->y * pitch8) + pptSrc->x;
+ data32 = ptr32 + (pbox->y1 * pitch32) + (pbox->x1 << 2);
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ while(height--) {
+ switch(rop) {
+ case GXcopy:
+ for(i = 0; i < width; i++)
+ data32[i<<2] = (data8[i] & pm) | (data32[i<<2] & ~pm);
+ break;
+ case GXor:
+ for(i = 0; i < width; i++)
+ data32[i<<2] |= data8[i] & pm;
+ break;
+ case GXclear:
+ for(i = 0; i < width; i++)
+ data32[i<<2] &= ~pm;
+ break;
+ case GXand:
+ for(i = 0; i < width; i++)
+ data32[i<<2] &= data8[i] | ~pm;
+ break;
+ case GXandReverse:
+ for(i = 0; i < width; i++)
+ data32[i<<2] = ~data32[i<<2] & (data8[i] | ~pm);
+ break;
+ case GXandInverted:
+ for(i = 0; i < width; i++)
+ data32[i<<2] &= ~data8[i] | ~pm;
+ break;
+ case GXnoop:
+ return;
+ case GXxor:
+ for(i = 0; i < width; i++)
+ data32[i<<2] ^= data8[i] & pm;
+ break;
+ case GXnor:
+ for(i = 0; i < width; i++)
+ data32[i<<2] = ~(data32[i<<2] | (data8[i] & pm));
+ break;
+ case GXequiv:
+ for(i = 0; i < width; i++)
+ data32[i<<2] = ~(data32[i<<2] ^ (data8[i] & pm));
+ break;
+ case GXinvert:
+ for(i = 0; i < width; i++)
+ data32[i<<2] ^= pm;
+ break;
+ case GXorReverse:
+ for(i = 0; i < width; i++)
+ data32[i<<2] = ~data32[i<<2] | (data8[i] & pm);
+ break;
+ case GXcopyInverted:
+ for(i = 0; i < width; i++)
+ data32[i<<2] = (~data8[i] & pm) | (data32[i<<2] & ~pm);
+ break;
+ case GXorInverted:
+ for(i = 0; i < width; i++)
+ data32[i<<2] |= ~data8[i] & pm;
+ break;
+ case GXnand:
+ for(i = 0; i < width; i++)
+ data32[i<<2] = ~(data32[i<<2] & (data8[i] | ~pm));
+ break;
+ case GXset:
+ for(i = 0; i < width; i++)
+ data32[i<<2] |= pm;
+ break;
+ }
+ data8 += pitch8;
+ data32 += pitch32;
+ }
+ }
+ }
+}
+
+
+void
+cfbDoBitblt32To8(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ int rop,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc,
+ unsigned long pm,
+ unsigned long bitPlane
+){
+ BoxPtr pbox = REGION_RECTS(prgnDst);
+ int nbox = REGION_NUM_RECTS(prgnDst);
+ unsigned char *ptr8, *ptr32;
+ unsigned char *data8, *data32;
+ int pitch8, pitch32;
+ int height, width, i;
+
+ cfbGetByteWidthAndPointer(pDst, pitch8, ptr8);
+ cfbGetByteWidthAndPointer(pSrc, pitch32, ptr32);
+ ptr32 += 3; /* point to the top byte */
+
+ if(((pm & 0xff) == 0xff) && (rop == GXcopy)) {
+ for(;nbox; pbox++, pptSrc++, nbox--) {
+ data8 = ptr8 + (pbox->y1 * pitch8) + pbox->x1;
+ data32 = ptr32 + (pptSrc->y * pitch32) + (pptSrc->x << 2);
+
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ while(height--) {
+ for(i = 0; i < width; i++)
+ data8[i] = data32[i << 2];
+ data8 += pitch8;
+ data32 += pitch32;
+ }
+ }
+ } else {
+ for(;nbox; pbox++, pptSrc++, nbox--) {
+ data8 = ptr8 + (pbox->y1 * pitch8) + pbox->x1;
+ data32 = ptr32 + (pptSrc->y * pitch32) + (pptSrc->x << 2);
+
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ while(height--) {
+ switch(rop) {
+ case GXcopy:
+ for(i = 0; i < width; i++)
+ data8[i] = (data32[i<<2] & pm) | (data8[i] & ~pm);
+ break;
+ case GXor:
+ for(i = 0; i < width; i++)
+ data8[i] |= data32[i<<2] & pm;
+ break;
+ case GXclear:
+ for(i = 0; i < width; i++)
+ data8[i] &= ~pm;
+ break;
+ case GXand:
+ for(i = 0; i < width; i++)
+ data8[i] &= data32[i<<2] | ~pm;
+ break;
+ case GXandReverse:
+ for(i = 0; i < width; i++)
+ data8[i] = ~data8[i] & (data32[i<<2] | ~pm);
+ break;
+ case GXandInverted:
+ for(i = 0; i < width; i++)
+ data8[i] &= ~data32[i<<2] | ~pm;
+ break;
+ case GXnoop:
+ return;
+ case GXxor:
+ for(i = 0; i < width; i++)
+ data8[i] ^= data32[i<<2] & pm;
+ break;
+ case GXnor:
+ for(i = 0; i < width; i++)
+ data8[i] = ~(data8[i] | (data32[i<<2] & pm));
+ break;
+ case GXequiv:
+ for(i = 0; i < width; i++)
+ data8[i] = ~(data8[i] ^ (data32[i<<2] & pm));
+ break;
+ case GXinvert:
+ for(i = 0; i < width; i++)
+ data8[i] ^= pm;
+ break;
+ case GXorReverse:
+ for(i = 0; i < width; i++)
+ data8[i] = ~data8[i] | (data32[i<<2] & pm);
+ break;
+ case GXcopyInverted:
+ for(i = 0; i < width; i++)
+ data8[i] = (~data32[i<<2] & pm) | (data8[i] & ~pm);
+ break;
+ case GXorInverted:
+ for(i = 0; i < width; i++)
+ data8[i] |= ~data32[i<<2] & pm;
+ break;
+ case GXnand:
+ for(i = 0; i < width; i++)
+ data8[i] = ~(data8[i] & (data32[i<<2] | ~pm));
+ break;
+ case GXset:
+ for(i = 0; i < width; i++)
+ data8[i] |= pm;
+ break;
+ }
+ data8 += pitch8;
+ data32 += pitch32;
+ }
+ }
+ }
+}
+
+
+
+static void
+Do8To8Blt(
+ unsigned char *SrcPtr,
+ int SrcPitch,
+ unsigned char *DstPtr,
+ int DstPitch,
+ int nbox,
+ DDXPointPtr pptSrc,
+ BoxPtr pbox,
+ int xdir, int ydir
+){
+ int i, j, width, height, ydir2;
+ CARD8 *src, *dst;
+
+ SrcPtr += 3;
+ DstPtr += 3;
+ xdir *= 4;
+ ydir2 = ydir * DstPitch;
+ ydir *= SrcPitch;
+
+ for(;nbox; pbox++, pptSrc++, nbox--) {
+ src = SrcPtr + (pptSrc->y * SrcPitch) + (pptSrc->x << 2);
+ dst = DstPtr + (pbox->y1 * DstPitch) + (pbox->x1 << 2);
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ if(ydir < 0) {
+ src += (height - 1) * SrcPitch;
+ dst += (height - 1) * DstPitch;
+ }
+
+ if(xdir < 0) {
+ register tmp = (width - 1) << 2;
+ src += tmp;
+ dst += tmp;
+ }
+
+ while(height--) {
+ for(i = width, j = 0; i--; j+=xdir)
+ dst[j] = src[j];
+ src += ydir;
+ dst += ydir2;
+ }
+ }
+}
+
+static void
+Do24To24Blt(
+ unsigned char *SrcPtr,
+ int SrcPitch,
+ unsigned char *DstPtr,
+ int DstPitch,
+ int nbox,
+ DDXPointPtr pptSrc,
+ BoxPtr pbox,
+ int xdir, int ydir
+){
+ int i, j, width, height, ydir2;
+ CARD8 *src, *dst;
+
+ xdir *= 4;
+ ydir2 = ydir * DstPitch;
+ ydir *= SrcPitch;
+
+ for(;nbox; pbox++, pptSrc++, nbox--) {
+ src = SrcPtr + (pptSrc->y * SrcPitch) + (pptSrc->x << 2);
+ dst = DstPtr + (pbox->y1 * DstPitch) + (pbox->x1 << 2);
+ width = pbox->x2 - pbox->x1;
+ height = pbox->y2 - pbox->y1;
+
+ if(ydir < 0) {
+ src += (height - 1) * SrcPitch;
+ dst += (height - 1) * DstPitch;
+ }
+
+ if(xdir < 0) {
+ register tmp = (width - 1) << 2;
+ src += tmp;
+ dst += tmp;
+ }
+
+ while(height--) {
+ for(i = width, j = 0; i--; j+=xdir) {
+ *((CARD16*)(dst + j)) = *((CARD32*)(src + j));
+ dst[j + 2] = src[j + 2];
+ }
+ src += ydir;
+ dst += ydir2;
+ }
+ }
+}
+
+
+static void
+cfb8_32DoBitBlt(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc,
+ void (*DoBlt)()
+){
+ int nbox, careful, SrcPitch, DstPitch;
+ BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
+ DDXPointPtr pptTmp, pptNew1, pptNew2;
+ int xdir, ydir;
+ unsigned char *SrcPtr, *DstPtr;
+
+ /* XXX we have to err on the side of safety when both are windows,
+ * because we don't know if IncludeInferiors is being used.
+ */
+ careful = ((pSrc == pDst) ||
+ ((pSrc->type == DRAWABLE_WINDOW) &&
+ (pDst->type == DRAWABLE_WINDOW)));
+
+ pbox = REGION_RECTS(prgnDst);
+ nbox = REGION_NUM_RECTS(prgnDst);
+
+ pboxNew1 = NULL;
+ pptNew1 = NULL;
+ pboxNew2 = NULL;
+ pptNew2 = NULL;
+ if (careful && (pptSrc->y < pbox->y1)) {
+ /* walk source botttom to top */
+ ydir = -1;
+
+ if (nbox > 1) {
+ /* keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ if(!pboxNew1)
+ return;
+ pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pptNew1) {
+ DEALLOCATE_LOCAL(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox) {
+ while ((pboxNext >= pbox) &&
+ (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp <= pboxBase) {
+ *pboxNew1++ = *pboxTmp++;
+ *pptNew1++ = *pptTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ pptNew1 -= nbox;
+ pptSrc = pptNew1;
+ }
+ } else {
+ /* walk source top to bottom */
+ ydir = 1;
+ }
+
+ if (careful && (pptSrc->x < pbox->x1)) {
+ /* walk source right to left */
+ xdir = -1;
+
+ if (nbox > 1) {
+ /* reverse order of rects in each band */
+ pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pboxNew2 || !pptNew2) {
+ if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
+ if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
+ if (pboxNew1) {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox) {
+ while ((pboxNext < pbox+nbox) &&
+ (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp != pboxBase) {
+ *pboxNew2++ = *--pboxTmp;
+ *pptNew2++ = *--pptTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ pptNew2 -= nbox;
+ pptSrc = pptNew2;
+ }
+ } else {
+ /* walk source left to right */
+ xdir = 1;
+ }
+
+ cfbGetByteWidthAndPointer(pSrc, SrcPitch, SrcPtr);
+ cfbGetByteWidthAndPointer(pDst, DstPitch, DstPtr);
+
+ (*DoBlt)(SrcPtr,SrcPitch,DstPtr,DstPitch,nbox,pptSrc,pbox,xdir,ydir);
+
+ if (pboxNew2) {
+ DEALLOCATE_LOCAL(pptNew2);
+ DEALLOCATE_LOCAL(pboxNew2);
+ }
+ if (pboxNew1) {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+
+}
+
+
+/* A couple routines to speed up full planemask copies */
+
+void
+cfbDoBitblt8To8GXcopy(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ int rop,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc,
+ unsigned long pm,
+ unsigned long bitPlane
+){
+ cfb8_32DoBitBlt(pSrc, pDst, prgnDst, pptSrc, Do8To8Blt);
+}
+
+
+void
+cfbDoBitblt24To24GXcopy(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ int rop,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc,
+ unsigned long pm,
+ unsigned long bitPlane
+){
+ cfb8_32DoBitBlt(pSrc, pDst, prgnDst, pptSrc, Do24To24Blt);
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbcpyplane.c b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbcpyplane.c
new file mode 100644
index 000000000..248ca0869
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbcpyplane.c
@@ -0,0 +1,39 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbcpyplane.c,v 1.1 1999/01/03 03:58:55 dawes Exp $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb32.h"
+#include "cfb8_32.h"
+#include "mi.h"
+
+
+RegionPtr
+cfb8_32CopyPlane(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+){
+ /* There's actually much more to it than this */
+
+ if((pDst->bitsPerPixel == 8) && (pSrc->bitsPerPixel != 32)){
+ return(cfbCopyPlane(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane));
+ }
+
+
+ return(miCopyPlane (pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane));
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbgc.c b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbgc.c
new file mode 100644
index 000000000..a4da70e61
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbgc.c
@@ -0,0 +1,666 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbgc.c,v 1.2 1999/01/23 09:56:15 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+
+/*
+
+PSZ 8 16 24 32
+PIXEL_ADDR True True True True
+NO_ONE_RECT False False False False
+WriteBitGroup True True True True
+FOUR_BIT_CODE True False False False
+LOWMEMFTPT False False False False
+
+*/
+
+
+/* This gets built twice. Once for 8bpp and another for 32bpp */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "cfb.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "region.h"
+
+#include "mistruct.h"
+#include "mibstore.h"
+#include "migc.h"
+
+#include "cfb8_32.h"
+#include "cfbmskbits.h"
+#include "cfb8bit.h"
+
+
+#if PSZ == 8
+# define useTEGlyphBlt cfbTEGlyphBlt8
+#else
+# ifdef WriteBitGroup
+# define useTEGlyphBlt cfbImageGlyphBlt8
+# else
+# define useTEGlyphBlt cfbTEGlyphBlt
+# endif
+#endif
+
+#ifdef WriteBitGroup
+# define useImageGlyphBlt cfbImageGlyphBlt8
+# define usePolyGlyphBlt cfbPolyGlyphBlt8
+#else
+# define useImageGlyphBlt miImageGlyphBlt
+# define usePolyGlyphBlt miPolyGlyphBlt
+#endif
+
+#ifdef FOUR_BIT_CODE
+# define usePushPixels cfbPushPixels8
+#else
+#ifndef LOWMEMFTPT
+# define usePushPixels mfbPushPixels
+#else
+# define usePushPixels miPushPixels
+#endif /* ifndef LOWMEMFTPT */
+#endif
+
+#ifdef PIXEL_ADDR
+# define ZeroPolyArc cfbZeroPolyArcSS8Copy
+#else
+# define ZeroPolyArc miZeroPolyArc
+#endif
+
+
+static GCOps cfb8_32TEOps1Rect = {
+ cfbSolidSpansCopy,
+ cfbSetSpans,
+ cfb8_32PutImage,
+ cfb8_32CopyArea,
+ cfb8_32CopyPlane,
+ cfbPolyPoint,
+#ifdef PIXEL_ADDR
+ cfb8LineSS1Rect,
+ cfb8SegmentSS1Rect,
+#else
+ cfbLineSS,
+ cfbSegmentSS,
+#endif
+ miPolyRectangle,
+ ZeroPolyArc,
+ cfbFillPoly1RectCopy,
+ cfbPolyFillRect,
+ cfbPolyFillArcSolidCopy,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ useTEGlyphBlt,
+ usePolyGlyphBlt,
+ usePushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps cfb8_32NonTEOps1Rect = {
+ cfbSolidSpansCopy,
+ cfbSetSpans,
+ cfb8_32PutImage,
+ cfb8_32CopyArea,
+ cfb8_32CopyPlane,
+ cfbPolyPoint,
+#ifdef PIXEL_ADDR
+ cfb8LineSS1Rect,
+ cfb8SegmentSS1Rect,
+#else
+ cfbLineSS,
+ cfbSegmentSS,
+#endif
+ miPolyRectangle,
+ ZeroPolyArc,
+ cfbFillPoly1RectCopy,
+ cfbPolyFillRect,
+ cfbPolyFillArcSolidCopy,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ useImageGlyphBlt,
+ usePolyGlyphBlt,
+ usePushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps cfb8_32TEOps = {
+ cfbSolidSpansCopy,
+ cfbSetSpans,
+ cfb8_32PutImage,
+ cfb8_32CopyArea,
+ cfb8_32CopyPlane,
+ cfbPolyPoint,
+ cfbLineSS,
+ cfbSegmentSS,
+ miPolyRectangle,
+ ZeroPolyArc,
+ miFillPolygon,
+ cfbPolyFillRect,
+ cfbPolyFillArcSolidCopy,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ useTEGlyphBlt,
+ usePolyGlyphBlt,
+ usePushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps cfb8_32NonTEOps = {
+ cfbSolidSpansCopy,
+ cfbSetSpans,
+ cfb8_32PutImage,
+ cfb8_32CopyArea,
+ cfb8_32CopyPlane,
+ cfbPolyPoint,
+ cfbLineSS,
+ cfbSegmentSS,
+ miPolyRectangle,
+#ifdef PIXEL_ADDR
+ cfbZeroPolyArcSS8Copy,
+#else
+ miZeroPolyArc,
+#endif
+ miFillPolygon,
+ cfbPolyFillRect,
+ cfbPolyFillArcSolidCopy,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ useImageGlyphBlt,
+ usePolyGlyphBlt,
+ usePushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps *
+cfb8_32MatchCommon (GCPtr pGC, cfbPrivGCPtr devPriv)
+{
+ if (pGC->lineWidth != 0)
+ return 0;
+ if (pGC->lineStyle != LineSolid)
+ return 0;
+ if (pGC->fillStyle != FillSolid)
+ return 0;
+ if (devPriv->rop != GXcopy)
+ return 0;
+ if (pGC->font &&
+ FONTMAXBOUNDS(pGC->font,rightSideBearing) -
+ FONTMINBOUNDS(pGC->font,leftSideBearing) <= 32 &&
+ FONTMINBOUNDS(pGC->font,characterWidth) >= 0)
+ {
+ if (TERMINALFONT(pGC->font)
+#ifdef FOUR_BIT_CODE
+ && FONTMAXBOUNDS(pGC->font,characterWidth) >= PGSZB
+#endif
+ )
+#ifdef NO_ONE_RECT
+ return &cfb8_32TEOps1Rect;
+#else
+ if (devPriv->oneRect)
+ return &cfb8_32TEOps1Rect;
+ else
+ return &cfb8_32TEOps;
+#endif
+ else
+#ifdef NO_ONE_RECT
+ return &cfb8_32NonTEOps1Rect;
+#else
+ if (devPriv->oneRect)
+ return &cfb8_32NonTEOps1Rect;
+ else
+ return &cfb8_32NonTEOps;
+#endif
+ }
+ return 0;
+}
+
+
+/* Clipping conventions
+ if the drawable is a window
+ CT_REGION ==> pCompositeClip really is the composite
+ CT_other ==> pCompositeClip is the window clip region
+ if the drawable is a pixmap
+ CT_REGION ==> pCompositeClip is the translated client region
+ clipped to the pixmap boundary
+ CT_other ==> pCompositeClip is the pixmap bounding box
+*/
+
+void
+#if PSZ == 8
+cfb8_32ValidateGC8(
+#else
+cfb8_32ValidateGC32(
+#endif
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDrawable
+){
+ int mask; /* stateChanges */
+ int index; /* used for stepping through bitfields */
+ int new_rrop;
+ int new_line, new_text, new_fillspans, new_fillarea;
+ /* flags for changing the proc vector */
+ cfbPrivGCPtr devPriv;
+ int oneRect;
+
+ pGC->lastWinOrg.x = pDrawable->x;
+ pGC->lastWinOrg.y = pDrawable->y;
+ devPriv = cfbGetGCPrivate(pGC);
+
+ new_rrop = FALSE;
+ new_line = FALSE;
+ new_text = FALSE;
+ new_fillspans = FALSE;
+ new_fillarea = FALSE;
+
+ /*
+ * if the client clip is different or moved OR the subwindowMode has
+ * changed OR the window's clip has changed since the last validation
+ * we need to recompute the composite clip
+ */
+
+ if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
+ (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS)))
+ {
+ miComputeCompositeClip (pGC, pDrawable);
+#ifdef NO_ONE_RECT
+ devPriv->oneRect = FALSE;
+#else
+ oneRect = REGION_NUM_RECTS(pGC->pCompositeClip) == 1;
+ if (oneRect != devPriv->oneRect)
+ new_line = TRUE;
+ devPriv->oneRect = oneRect;
+#endif
+ }
+
+ mask = changes;
+ while (mask) {
+ index = lowbit (mask);
+ mask &= ~index;
+
+ /*
+ * this switch acculmulates a list of which procedures might have
+ * to change due to changes in the GC. in some cases (e.g.
+ * changing one 16 bit tile for another) we might not really need
+ * a change, but the code is being paranoid. this sort of batching
+ * wins if, for example, the alu and the font have been changed,
+ * or any other pair of items that both change the same thing.
+ */
+ switch (index) {
+ case GCFunction:
+ case GCForeground:
+ new_rrop = TRUE;
+ break;
+ case GCPlaneMask:
+ new_rrop = TRUE;
+ new_text = TRUE;
+ break;
+ case GCBackground:
+ break;
+ case GCLineStyle:
+ case GCLineWidth:
+ new_line = TRUE;
+ break;
+ case GCJoinStyle:
+ case GCCapStyle:
+ break;
+ case GCFillStyle:
+ new_text = TRUE;
+ new_fillspans = TRUE;
+ new_line = TRUE;
+ new_fillarea = TRUE;
+ break;
+ case GCFillRule:
+ break;
+ case GCTile:
+ new_fillspans = TRUE;
+ new_fillarea = TRUE;
+ break;
+ case GCStipple:
+ new_fillspans = TRUE;
+ new_fillarea = TRUE;
+ break;
+ case GCTileStipXOrigin:
+ case GCTileStipYOrigin:
+ break;
+ case GCFont:
+ new_text = TRUE;
+ break;
+ case GCSubwindowMode:
+ case GCGraphicsExposures:
+ case GCClipXOrigin:
+ case GCClipYOrigin:
+ case GCClipMask:
+ case GCDashOffset:
+ case GCDashList:
+ case GCArcMode:
+ default:
+ break;
+ }
+ }
+
+ /*
+ * If the drawable has changed, ensure suitable
+ * entries are in the proc vector.
+ */
+ if (pDrawable->serialNumber != (pGC->serialNumber & (DRAWABLE_SERIAL_BITS)))
+ new_fillspans = TRUE; /* deal with FillSpans later */
+
+ if (new_rrop)
+ {
+ int old_rrop;
+
+ old_rrop = devPriv->rop;
+ devPriv->rop = cfbReduceRasterOp (pGC->alu, pGC->fgPixel,
+ pGC->planemask,
+ &devPriv->and, &devPriv->xor);
+ if (old_rrop == devPriv->rop)
+ new_rrop = FALSE;
+ else
+ {
+#ifdef PIXEL_ADDR
+ new_line = TRUE;
+#endif
+#ifdef WriteBitGroup
+ new_text = TRUE;
+#endif
+ new_fillspans = TRUE;
+ new_fillarea = TRUE;
+ }
+ }
+
+ if(!pGC->ops)
+ pGC->ops = & cfb8_32NonTEOps;
+
+ if (new_rrop || new_fillspans || new_text || new_fillarea || new_line)
+ {
+ GCOps *newops;
+
+ if ((newops = cfb8_32MatchCommon (pGC, devPriv)))
+ {
+ if (pGC->ops->devPrivate.val)
+ miDestroyGCOps (pGC->ops);
+ pGC->ops = newops;
+ new_rrop = new_line = new_fillspans = new_text = new_fillarea = 0;
+ }
+ else
+ {
+ if (!pGC->ops->devPrivate.val)
+ {
+ pGC->ops = miCreateGCOps (pGC->ops);
+ pGC->ops->devPrivate.val = 1;
+ }
+ }
+ }
+
+ /* deal with the changes we've collected */
+ if (new_line)
+ {
+ pGC->ops->FillPolygon = miFillPolygon;
+#ifdef NO_ONE_RECT
+ if (pGC->fillStyle == FillSolid)
+ {
+ switch (devPriv->rop) {
+ case GXcopy:
+ pGC->ops->FillPolygon = cfbFillPoly1RectCopy;
+ break;
+ default:
+ pGC->ops->FillPolygon = cfbFillPoly1RectGeneral;
+ break;
+ }
+ }
+#else
+ if (devPriv->oneRect && pGC->fillStyle == FillSolid)
+ {
+ switch (devPriv->rop) {
+ case GXcopy:
+ pGC->ops->FillPolygon = cfbFillPoly1RectCopy;
+ break;
+ default:
+ pGC->ops->FillPolygon = cfbFillPoly1RectGeneral;
+ break;
+ }
+ }
+#endif
+ if (pGC->lineWidth == 0)
+ {
+#ifdef PIXEL_ADDR
+ if ((pGC->lineStyle == LineSolid) && (pGC->fillStyle == FillSolid))
+ {
+ switch (devPriv->rop)
+ {
+ case GXxor:
+ pGC->ops->PolyArc = cfbZeroPolyArcSS8Xor;
+ break;
+ case GXcopy:
+ pGC->ops->PolyArc = cfbZeroPolyArcSS8Copy;
+ break;
+ default:
+ pGC->ops->PolyArc = cfbZeroPolyArcSS8General;
+ break;
+ }
+ }
+ else
+#endif
+ pGC->ops->PolyArc = miZeroPolyArc;
+ }
+ else
+ pGC->ops->PolyArc = miPolyArc;
+ pGC->ops->PolySegment = miPolySegment;
+ switch (pGC->lineStyle)
+ {
+ case LineSolid:
+ if(pGC->lineWidth == 0)
+ {
+ if (pGC->fillStyle == FillSolid)
+ {
+#if defined(PIXEL_ADDR) && !defined(NO_ONE_RECT)
+ if (devPriv->oneRect &&
+ ((pDrawable->x >= pGC->pScreen->width - 32768) &&
+ (pDrawable->y >= pGC->pScreen->height - 32768)))
+ {
+ pGC->ops->Polylines = cfb8LineSS1Rect;
+ pGC->ops->PolySegment = cfb8SegmentSS1Rect;
+ } else
+#endif
+#ifdef NO_ONE_RECT
+ {
+ pGC->ops->Polylines = cfb8LineSS1Rect;
+ pGC->ops->PolySegment = cfb8SegmentSS1Rect;
+ }
+#else
+ {
+ pGC->ops->Polylines = cfbLineSS;
+ pGC->ops->PolySegment = cfbSegmentSS;
+ }
+#endif
+ }
+ else
+ pGC->ops->Polylines = miZeroLine;
+ }
+ else
+ pGC->ops->Polylines = miWideLine;
+ break;
+ case LineOnOffDash:
+ case LineDoubleDash:
+ if (pGC->lineWidth == 0 && pGC->fillStyle == FillSolid)
+ {
+ pGC->ops->Polylines = cfbLineSD;
+ pGC->ops->PolySegment = cfbSegmentSD;
+ } else
+ pGC->ops->Polylines = miWideDash;
+ break;
+ }
+ }
+
+ if (new_text && (pGC->font))
+ {
+ if (FONTMAXBOUNDS(pGC->font,rightSideBearing) -
+ FONTMINBOUNDS(pGC->font,leftSideBearing) > 32 ||
+ FONTMINBOUNDS(pGC->font,characterWidth) < 0)
+ {
+ pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
+ pGC->ops->ImageGlyphBlt = miImageGlyphBlt;
+ }
+ else
+ {
+#ifdef WriteBitGroup
+ if (pGC->fillStyle == FillSolid)
+ {
+ if (devPriv->rop == GXcopy)
+ pGC->ops->PolyGlyphBlt = cfbPolyGlyphBlt8;
+ else
+#ifdef FOUR_BIT_CODE
+ pGC->ops->PolyGlyphBlt = cfbPolyGlyphRop8;
+#else
+ pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
+#endif
+ }
+ else
+#endif
+ pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
+ /* special case ImageGlyphBlt for terminal emulator fonts */
+#if !defined(WriteBitGroup) || PSZ == 8
+ if (TERMINALFONT(pGC->font) &&
+ (pGC->planemask & PMSK) == PMSK
+#ifdef FOUR_BIT_CODE
+ && FONTMAXBOUNDS(pGC->font,characterWidth) >= PGSZB
+#endif
+ )
+ {
+ pGC->ops->ImageGlyphBlt = useTEGlyphBlt;
+ }
+ else
+#endif
+ {
+#ifdef WriteBitGroup
+ if (devPriv->rop == GXcopy &&
+ pGC->fillStyle == FillSolid &&
+ (pGC->planemask & PMSK) == PMSK)
+ pGC->ops->ImageGlyphBlt = cfbImageGlyphBlt8;
+ else
+#endif
+ pGC->ops->ImageGlyphBlt = miImageGlyphBlt;
+ }
+ }
+ }
+
+
+ if (new_fillspans) {
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ switch (devPriv->rop) {
+ case GXcopy:
+ pGC->ops->FillSpans = cfbSolidSpansCopy;
+ break;
+ case GXxor:
+ pGC->ops->FillSpans = cfbSolidSpansXor;
+ break;
+ default:
+ pGC->ops->FillSpans = cfbSolidSpansGeneral;
+ break;
+ }
+ break;
+ case FillTiled:
+ pGC->ops->FillSpans = cfbUnnaturalTileFS;
+ break;
+ case FillStippled:
+ case FillOpaqueStippled:
+ pGC->ops->FillSpans = cfbUnnaturalStippleFS;
+ break;
+ default:
+ FatalError("cfbValidateGC: illegal fillStyle\n");
+ }
+ } /* end of new_fillspans */
+
+ if (new_fillarea) {
+#ifndef FOUR_BIT_CODE
+ pGC->ops->PolyFillRect = miPolyFillRect;
+ if (pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled)
+ {
+ pGC->ops->PolyFillRect = cfbPolyFillRect;
+ }
+#endif
+#ifdef FOUR_BIT_CODE
+#ifndef LOWMEMFTPT
+ pGC->ops->PushPixels = mfbPushPixels;
+#else
+ pGC->ops->PushPixels = miPushPixels;
+#endif /* ifndef LOWMEMFTPT */
+ if (pGC->fillStyle == FillSolid && devPriv->rop == GXcopy)
+ pGC->ops->PushPixels = cfbPushPixels8;
+#endif
+ pGC->ops->PolyFillArc = miPolyFillArc;
+ if (pGC->fillStyle == FillSolid)
+ {
+ switch (devPriv->rop)
+ {
+ case GXcopy:
+ pGC->ops->PolyFillArc = cfbPolyFillArcSolidCopy;
+ break;
+ default:
+ pGC->ops->PolyFillArc = cfbPolyFillArcSolidGeneral;
+ break;
+ }
+ }
+ }
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbgcmisc.c b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbgcmisc.c
new file mode 100644
index 000000000..3e75c0116
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbgcmisc.c
@@ -0,0 +1,120 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbgcmisc.c,v 1.1 1999/01/03 03:58:56 dawes Exp $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb32.h"
+#include "cfb8_32.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "region.h"
+
+#include "mistruct.h"
+#include "mibstore.h"
+#include "migc.h"
+
+
+static void cfb8_32ValidateGC(GCPtr, unsigned long, DrawablePtr);
+static void cfb8_32DestroyGC(GCPtr pGC);
+
+static
+GCFuncs cfb8_32GCFuncs = {
+ cfb8_32ValidateGC,
+ miChangeGC,
+ miCopyGC,
+ cfb8_32DestroyGC,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip,
+};
+
+static void
+cfb8_32DestroyGC(GCPtr pGC)
+{
+ cfb8_32GCPtr pGCPriv = CFB8_32_GET_GC_PRIVATE(pGC);
+
+ if (pGC->freeCompClip)
+ REGION_DESTROY(pGC->pScreen, pGC->pCompositeClip);
+ if(pGCPriv->Ops8bpp)
+ miDestroyGCOps(pGCPriv->Ops8bpp);
+ if(pGCPriv->Ops32bpp)
+ miDestroyGCOps(pGCPriv->Ops32bpp);
+}
+
+Bool
+cfb8_32CreateGC(GCPtr pGC)
+{
+ cfb8_32GCPtr pGCPriv;
+ cfbPrivGC *pPriv;
+
+ if (PixmapWidthPaddingInfo[pGC->depth].padPixelsLog2 == LOG2_BITMAP_PAD)
+ return (mfbCreateGC(pGC));
+ if (pGC->depth == 24)
+ return (cfb32CreateGC(pGC));
+
+ pGC->clientClip = NULL;
+ pGC->clientClipType = CT_NONE;
+ pGC->miTranslate = 1;
+ pGC->fExpose = TRUE;
+ pGC->freeCompClip = FALSE;
+ pGC->pRotatedPixmap = (PixmapPtr) NULL;
+
+ pPriv = cfbGetGCPrivate(pGC);
+ pPriv->rop = pGC->alu;
+ pPriv->oneRect = FALSE;
+
+ pGC->ops = NULL;
+ pGC->funcs = &cfb8_32GCFuncs;
+
+ pGCPriv = CFB8_32_GET_GC_PRIVATE(pGC);
+ pGCPriv->Ops8bpp = NULL;
+ pGCPriv->Ops32bpp = NULL;
+ pGCPriv->OpsAre8bpp = FALSE;
+ pGCPriv->changes = 0;
+
+ return TRUE;
+}
+
+
+static void
+cfb8_32ValidateGC(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+){
+ cfb8_32GCPtr pGCPriv = CFB8_32_GET_GC_PRIVATE(pGC);
+
+ if(pDraw->bitsPerPixel == 32) {
+ if(pGCPriv->OpsAre8bpp) {
+ int origChanges = changes;
+ pGC->ops = pGCPriv->Ops32bpp;
+ changes |= pGCPriv->changes;
+ pGCPriv->changes = origChanges;
+ pGCPriv->OpsAre8bpp = FALSE;
+ } else
+ pGCPriv->changes |= changes;
+
+ cfb8_32ValidateGC32(pGC, changes, pDraw);
+ pGCPriv->Ops32bpp = pGC->ops;
+ } else { /* bitsPerPixel == 8 */
+ if(!pGCPriv->OpsAre8bpp) {
+ int origChanges = changes;
+ pGC->ops = pGCPriv->Ops8bpp;
+ changes |= pGCPriv->changes;
+ pGCPriv->changes = origChanges;
+ pGCPriv->OpsAre8bpp = TRUE;
+ } else
+ pGCPriv->changes |= changes;
+
+ cfb8_32ValidateGC8(pGC, changes, pDraw);
+ pGCPriv->Ops8bpp = pGC->ops;
+ }
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbimage.c b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbimage.c
new file mode 100644
index 000000000..d2c4424f2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbimage.c
@@ -0,0 +1,162 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbimage.c,v 1.1 1999/01/03 03:58:56 dawes Exp $ */
+
+#include "X.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb32.h"
+#include "cfb8_32.h"
+#include "servermd.h"
+#include "mi.h"
+
+
+void
+cfb8_32GetImage (
+ DrawablePtr pDraw,
+ int sx, int sy, int w, int h,
+ unsigned int format,
+ unsigned long planemask,
+ char *pdstLine
+){
+ if(!w || !h) return;
+
+ if(pDraw->depth == 24){
+ cfb32GetImage(pDraw, sx, sy, w, h, format, planemask, pdstLine);
+ return;
+ }
+
+ if((pDraw->bitsPerPixel == 8) || (pDraw->bitsPerPixel == 1)){
+ cfbGetImage(pDraw, sx, sy, w, h, format, planemask, pdstLine);
+ return;
+ }
+
+ /* source is depth 8, 32 bpp */
+ if(format != ZPixmap) {
+ miGetImage(pDraw, sx, sy, w, h, format, planemask, pdstLine);
+ return;
+ } else {
+ BoxRec box;
+ DDXPointRec ptSrc;
+ RegionRec rgnDst;
+ ScreenPtr pScreen;
+ PixmapPtr pPixmap;
+
+ pScreen = pDraw->pScreen;
+ pPixmap = GetScratchPixmapHeader(pScreen, w, h, 8, 8,
+ PixmapBytePad(w,8), (pointer)pdstLine);
+ if (!pPixmap)
+ return;
+ if ((planemask & 0xff) != 0xff)
+ bzero((char *)pdstLine, pPixmap->devKind * h);
+ ptSrc.x = sx + pDraw->x;
+ ptSrc.y = sy + pDraw->y;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = w;
+ box.y2 = h;
+ REGION_INIT(pScreen, &rgnDst, &box, 1);
+ cfbDoBitblt32To8(pDraw, (DrawablePtr)pPixmap, GXcopy, &rgnDst,
+ &ptSrc, planemask, 0);
+ REGION_UNINIT(pScreen, &rgnDst);
+ FreeScratchPixmapHeader(pPixmap);
+ }
+}
+
+void
+cfb8_32PutImage (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage
+){
+ if(!w || !h) return;
+
+ if((pDraw->bitsPerPixel == 8) || (format != XYPixmap)){
+ cfbPutImage(pDraw, pGC, depth, x, y, w, h, leftPad, format, pImage);
+ return;
+ } else { /* moving an 8bpp XYPixmap to a 32bpp screen */
+ unsigned long oldFg, oldBg;
+ XID gcv[3];
+ unsigned long oldPlanemask;
+ unsigned long i;
+ long bytesPer;
+
+ oldPlanemask = pGC->planemask;
+ oldFg = pGC->fgPixel;
+ oldBg = pGC->bgPixel;
+ gcv[0] = ~0L;
+ gcv[1] = 0;
+ DoChangeGC(pGC, GCForeground | GCBackground, gcv, 0);
+ bytesPer = (long)h * BitmapBytePad(w + leftPad);
+
+ for (i = 0x80000000; i & 0xff000000; i >>= 1, pImage += bytesPer)
+ {
+ if (i & oldPlanemask)
+ {
+ gcv[0] = i;
+ DoChangeGC(pGC, GCPlaneMask, gcv, 0);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->PutImage)(pDraw, pGC, 1, x, y, w, h, leftPad,
+ XYBitmap, pImage);
+ }
+ }
+ gcv[0] = oldPlanemask;
+ gcv[1] = oldFg;
+ gcv[2] = oldBg;
+ DoChangeGC(pGC, GCPlaneMask | GCForeground | GCBackground, gcv, 0);
+ ValidateGC(pDraw, pGC);
+ }
+}
+
+
+
+
+void
+cfb8_32GetSpans(
+ DrawablePtr pDraw,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pDst
+){
+ int pitch, i;
+ CARD8 *ptr, *ptrBase;
+
+ if(pDraw->bitsPerPixel == 1) {
+ mfbGetSpans(pDraw, wMax, ppt, pwidth, nspans, pDst);
+ return;
+ }
+
+ if(pDraw->depth == 24) {
+ cfb32GetSpans(pDraw, wMax, ppt, pwidth, nspans, pDst);
+ return;
+ } else if(pDraw->bitsPerPixel == 8) {
+ cfbGetSpans(pDraw, wMax, ppt, pwidth, nspans, pDst);
+ return;
+ }
+
+ /* gotta get spans from a depth 8 window */
+ cfbGetByteWidthAndPointer(pDraw, pitch, ptrBase);
+ ptrBase += 3; /* point to top byte */
+
+ while(nspans--) {
+ ptr = ptrBase + (ppt->y * pitch) + (ppt->x << 2);
+
+ for(i = *pwidth; i--; ptr += 4)
+ *(pDst++) = *ptr;
+
+ pDst = (char*)((long)(pDst + 3) & ~3L);
+
+ ppt++; pwidth++;
+ }
+}
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbpntwin.c b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbpntwin.c
new file mode 100644
index 000000000..431ff5d79
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbpntwin.c
@@ -0,0 +1,196 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbpntwin.c,v 1.2 1999/05/16 10:13:06 dawes Exp $ */
+
+#include "X.h"
+
+#include "windowstr.h"
+#include "regionstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb32.h"
+#include "cfb8_32.h"
+#include "mi.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+void
+cfb8_32PaintWindow(
+ WindowPtr pWin,
+ RegionPtr pRegion,
+ int what
+){
+ cfb8_32ScreenPtr pScreenPriv;
+ WindowPtr pBgWin;
+ int xorg, yorg;
+
+ switch (what) {
+ case PW_BACKGROUND:
+ switch (pWin->backgroundState) {
+ case None:
+ break;
+ case ParentRelative:
+ do {
+ pWin = pWin->parent;
+ } while (pWin->backgroundState == ParentRelative);
+ (*pWin->drawable.pScreen->PaintWindowBackground)(
+ pWin, pRegion, what);
+ break;
+ case BackgroundPixmap:
+ xorg = pWin->drawable.x;
+ yorg = pWin->drawable.y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ int index = pWin->drawable.pScreen->myNum;
+ if(WindowTable[index] == pWin) {
+ xorg -= panoramiXdataPtr[index].x;
+ yorg -= panoramiXdataPtr[index].y;
+ }
+ }
+#endif
+ cfb32FillBoxTileOddCopy ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion), REGION_RECTS(pRegion),
+ pWin->background.pixmap, xorg, yorg, GXcopy,
+ (pWin->drawable.depth == 24) ? 0x00ffffff : 0xff000000);
+ break;
+ case BackgroundPixel:
+ if(pWin->drawable.depth == 24)
+ cfb8_32FillBoxSolid32 ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->background.pixel);
+ else
+ cfb8_32FillBoxSolid8 ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->background.pixel);
+ break;
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel) {
+ if(pWin->drawable.depth == 24) {
+ pScreenPriv = CFB8_32_GET_SCREEN_PRIVATE(pWin->drawable.pScreen);
+ cfb32FillBoxSolid ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ (pScreenPriv->key << 24) |
+ (pWin->border.pixel & 0x00ffffff));
+ } else
+ cfb8_32FillBoxSolid8 ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->border.pixel);
+ } else {
+ for (pBgWin = pWin;
+ pBgWin->backgroundState == ParentRelative;
+ pBgWin = pBgWin->parent);
+
+ xorg = pBgWin->drawable.x;
+ yorg = pBgWin->drawable.y;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ int index = pWin->drawable.pScreen->myNum;
+ if(WindowTable[index] == pBgWin) {
+ xorg -= panoramiXdataPtr[index].x;
+ yorg -= panoramiXdataPtr[index].y;
+ }
+ }
+#endif
+ cfb32FillBoxTileOddCopy ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion), REGION_RECTS(pRegion),
+ pWin->border.pixmap, xorg, yorg, GXcopy,
+ (pWin->drawable.depth == 24) ? 0x00ffffff : 0xff000000);
+
+ if(pWin->drawable.depth == 24) {
+ pScreenPriv = CFB8_32_GET_SCREEN_PRIVATE(pWin->drawable.pScreen);
+ cfb8_32FillBoxSolid8 ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pScreenPriv->key);
+ }
+ }
+ break;
+ }
+
+}
+
+void
+cfb8_32FillBoxSolid8(
+ DrawablePtr pDraw,
+ int nbox,
+ BoxPtr pbox,
+ unsigned long color
+){
+ CARD8 *ptr, *data;
+ int pitch, height, width, i;
+ CARD8 c = (CARD8)color;
+
+ cfbGetByteWidthAndPointer(pDraw, pitch, ptr);
+ ptr += 3; /* point to the top byte */
+
+ while(nbox--) {
+ data = ptr + (pbox->y1 * pitch) + (pbox->x1 << 2);
+ width = (pbox->x2 - pbox->x1) << 2;
+ height = pbox->y2 - pbox->y1;
+
+ while(height--) {
+ for(i = 0; i < width; i+=4)
+ data[i] = c;
+ data += pitch;
+ }
+ pbox++;
+ }
+}
+
+
+void
+cfb8_32FillBoxSolid32(
+ DrawablePtr pDraw,
+ int nbox,
+ BoxPtr pbox,
+ unsigned long color
+){
+ CARD8 *ptr, *data;
+ CARD16 *ptr2, *data2;
+ int pitch, pitch2;
+ int height, width, i;
+ CARD8 c = (CARD8)(color >> 16);
+ CARD16 c2 = (CARD16)color;
+
+ cfbGetByteWidthAndPointer(pDraw, pitch, ptr);
+ cfbGetTypedWidthAndPointer(pDraw, pitch2, ptr2, CARD16, CARD16);
+ ptr += 2; /* point to the third byte */
+
+ while(nbox--) {
+ data = ptr + (pbox->y1 * pitch) + (pbox->x1 << 2);
+ data2 = ptr2 + (pbox->y1 * pitch2) + (pbox->x1 << 1);
+ width = (pbox->x2 - pbox->x1) << 1;
+ height = pbox->y2 - pbox->y1;
+
+ while(height--) {
+ for(i = 0; i < width; i+=2) {
+ data[i << 1] = c;
+ data2[i] = c2;
+ }
+ data += pitch;
+ data2 += pitch2;
+ }
+ pbox++;
+ }
+}
+
+
+unsigned char
+cfb8_32GetKey(ScreenPtr pScreen)
+{
+ cfb8_32ScreenPtr pScreenPriv = CFB8_32_GET_SCREEN_PRIVATE(pScreen);
+
+ return pScreenPriv->key;
+}
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbscrinit.c b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbscrinit.c
new file mode 100644
index 000000000..e4fb9f284
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbscrinit.c
@@ -0,0 +1,214 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbscrinit.c,v 1.3 1999/03/21 07:35:35 dawes Exp $ */
+
+
+#include "X.h"
+#include "Xmd.h"
+#include "misc.h"
+#include "servermd.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "resource.h"
+#include "colormap.h"
+#include "colormapst.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb32.h"
+#include "cfb8_32.h"
+#include "mi.h"
+#include "micmap.h"
+#include "mistruct.h"
+#include "dix.h"
+#include "mibstore.h"
+#include "xf86.h"
+#include "xf86str.h"
+
+/* CAUTION: We require that cfb8 and cfb32 were NOT
+ compiled with CFB_NEED_SCREEN_PRIVATE */
+
+static BSFuncRec cfb8_32BSFuncRec = {
+ cfb8_32SaveAreas,
+ cfb8_32RestoreAreas,
+ (BackingStoreSetClipmaskRgnProcPtr) 0,
+ (BackingStoreGetImagePixmapProcPtr) 0,
+ (BackingStoreGetSpansPixmapProcPtr) 0,
+};
+
+
+int cfb8_32GCPrivateIndex;
+int cfb8_32ScreenPrivateIndex;
+
+static unsigned long cfb8_32Generation = 0;
+extern WindowPtr *WindowTable;
+
+static Bool
+cfb8_32AllocatePrivates(ScreenPtr pScreen)
+{
+ cfb8_32ScreenPtr pScreenPriv;
+
+ if(cfb8_32Generation != serverGeneration) {
+ if(((cfb8_32GCPrivateIndex = AllocateGCPrivateIndex()) < 0) ||
+ ((cfb8_32ScreenPrivateIndex = AllocateScreenPrivateIndex()) < 0))
+ return FALSE;
+ cfb8_32Generation = serverGeneration;
+ }
+
+ if (!(pScreenPriv = xalloc(sizeof(cfb8_32ScreenRec))))
+ return FALSE;
+
+ pScreen->devPrivates[cfb8_32ScreenPrivateIndex].ptr = (pointer)pScreenPriv;
+
+
+ /* All cfb will have the same GC and Window private indicies */
+ if(!mfbAllocatePrivates(pScreen,&cfbWindowPrivateIndex, &cfbGCPrivateIndex))
+ return FALSE;
+
+ /* The cfb indicies are the mfb indicies. Reallocating them resizes them */
+ if(!AllocateWindowPrivate(pScreen,cfbWindowPrivateIndex,sizeof(cfbPrivWin)))
+ return FALSE;
+
+ if(!AllocateGCPrivate(pScreen, cfbGCPrivateIndex, sizeof(cfbPrivGC)))
+ return FALSE;
+
+ if(!AllocateGCPrivate(pScreen, cfb8_32GCPrivateIndex, sizeof(cfb8_32GCRec)))
+ return FALSE;
+
+ return TRUE;
+}
+
+static Bool
+cfb8_32SetupScreen(
+ ScreenPtr pScreen,
+ pointer pbits, /* pointer to screen bitmap */
+ int xsize, int ysize, /* in pixels */
+ int dpix, int dpiy, /* dots per inch */
+ int width /* pixel width of frame buffer */
+){
+ if (!cfb8_32AllocatePrivates(pScreen))
+ return FALSE;
+ pScreen->defColormap = FakeClientID(0);
+ /* let CreateDefColormap do whatever it wants for pixels */
+ pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0;
+ pScreen->QueryBestSize = mfbQueryBestSize;
+ /* SaveScreen */
+ pScreen->GetImage = cfb8_32GetImage;
+ pScreen->GetSpans = cfb8_32GetSpans;
+ pScreen->CreateWindow = cfb8_32CreateWindow;
+ pScreen->DestroyWindow = cfb8_32DestroyWindow;
+ pScreen->PositionWindow = cfb8_32PositionWindow;
+ pScreen->ChangeWindowAttributes = cfb8_32ChangeWindowAttributes;
+ pScreen->RealizeWindow = cfb32MapWindow; /* OK */
+ pScreen->UnrealizeWindow = cfb32UnmapWindow; /* OK */
+ pScreen->PaintWindowBackground = cfb8_32PaintWindow;
+ pScreen->PaintWindowBorder = cfb8_32PaintWindow;
+ pScreen->CopyWindow = cfb8_32CopyWindow;
+ pScreen->CreatePixmap = cfb32CreatePixmap; /* OK */
+ pScreen->DestroyPixmap = cfb32DestroyPixmap; /* OK */
+ pScreen->RealizeFont = mfbRealizeFont;
+ pScreen->UnrealizeFont = mfbUnrealizeFont;
+ pScreen->CreateGC = cfb8_32CreateGC;
+ pScreen->CreateColormap = miInitializeColormap;
+ pScreen->DestroyColormap = (void (*)())NoopDDA;
+ pScreen->InstallColormap = miInstallColormap;
+ pScreen->UninstallColormap = miUninstallColormap;
+ pScreen->ListInstalledColormaps = miListInstalledColormaps;
+ pScreen->StoreColors = (void (*)())NoopDDA;
+ pScreen->ResolveColor = miResolveColor;
+ pScreen->BitmapToRegion = mfbPixmapToRegion;
+
+ mfbRegisterCopyPlaneProc (pScreen, cfb8_32CopyPlane);
+ return TRUE;
+}
+
+typedef struct {
+ pointer pbits;
+ int width;
+} miScreenInitParmsRec, *miScreenInitParmsPtr;
+
+static Bool
+cfb8_32CreateScreenResources(ScreenPtr pScreen)
+{
+ miScreenInitParmsPtr pScrInitParms;
+ int pitch;
+ Bool retval;
+
+ /* get the pitch before mi destroys it */
+ pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate;
+ pitch = pScrInitParms->width << 2;
+
+ if((retval = miCreateScreenResources(pScreen))) {
+ /* fix the screen pixmap */
+ PixmapPtr pPix = (PixmapPtr)pScreen->devPrivate;
+ pPix->drawable.bitsPerPixel = 32;
+ pPix->drawable.depth = 8;
+ pPix->devKind = pitch;
+ }
+
+ return retval;
+}
+
+
+static Bool
+cfb8_32CloseScreen (int i, ScreenPtr pScreen)
+{
+ cfb8_32ScreenPtr pScreenPriv = CFB8_32_GET_SCREEN_PRIVATE(pScreen);
+
+ xfree((pointer) pScreenPriv);
+
+ return(cfb32CloseScreen(i, pScreen));
+}
+
+static Bool
+cfb8_32FinishScreenInit(
+ ScreenPtr pScreen,
+ pointer pbits, /* pointer to screen bitmap */
+ int xsize, int ysize, /* in pixels */
+ int dpix, int dpiy, /* dots per inch */
+ int width /* pixel width of frame buffer */
+){
+ VisualPtr visuals;
+ DepthPtr depths;
+ int nvisuals;
+ int ndepths;
+ int rootdepth;
+ VisualID defaultVisual;
+
+ rootdepth = 0;
+ if (!miInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
+ &defaultVisual,((unsigned long)1<<(32-1)), 8, -1))
+ return FALSE;
+ if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
+ rootdepth, ndepths, depths,
+ defaultVisual, nvisuals, visuals))
+ return FALSE;
+
+ pScreen->BackingStoreFuncs = cfb8_32BSFuncRec;
+ pScreen->CreateScreenResources = cfb8_32CreateScreenResources;
+ pScreen->CloseScreen = cfb8_32CloseScreen;
+ pScreen->GetScreenPixmap = cfb32GetScreenPixmap; /* OK */
+ pScreen->SetScreenPixmap = cfb32SetScreenPixmap; /* OK */
+ pScreen->WindowExposures = cfb8_32WindowExposures;
+ return TRUE;
+}
+
+Bool
+cfb8_32ScreenInit(
+ ScreenPtr pScreen,
+ pointer pbits, /* pointer to screen bitmap */
+ int xsize, int ysize, /* in pixels */
+ int dpix, int dpiy, /* dots per inch */
+ int width /* pixel width of frame buffer */
+){
+ cfb8_32ScreenPtr pScreenPriv;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if (!cfb8_32SetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width))
+ return FALSE;
+
+ pScreenPriv = CFB8_32_GET_SCREEN_PRIVATE(pScreen);
+ pScreenPriv->key = pScrn->colorKey;
+
+ return cfb8_32FinishScreenInit(
+ pScreen, pbits, xsize, ysize, dpix, dpiy, width);
+}
+
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbwindow.c b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbwindow.c
new file mode 100644
index 000000000..af19393cd
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbwindow.c
@@ -0,0 +1,146 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/cfbwindow.c,v 1.4 1999/01/23 09:56:16 dawes Exp $ */
+
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#define PSZ 8
+#include "cfb.h"
+#undef PSZ
+#include "cfb32.h"
+#include "cfb8_32.h"
+#include "mistruct.h"
+#include "regionstr.h"
+#include "cfbmskbits.h"
+
+
+/* We don't bother with cfb's fastBackground/Border so we don't
+ need to use the Window privates */
+
+extern WindowPtr *WindowTable;
+
+
+Bool
+cfb8_32CreateWindow(WindowPtr pWin)
+{
+ cfbPrivWin *pPrivWin = cfbGetWindowPrivate(pWin);
+
+ pPrivWin->fastBackground = FALSE;
+ pPrivWin->fastBorder = FALSE;
+
+ pWin->drawable.bitsPerPixel = 32;
+ return TRUE;
+}
+
+
+Bool
+cfb8_32DestroyWindow(WindowPtr pWin)
+{
+ return TRUE;
+}
+
+Bool
+cfb8_32PositionWindow(
+ WindowPtr pWin,
+ int x, int y
+){
+ return TRUE;
+}
+
+
+
+void
+cfb8_32CopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DDXPointPtr ppt, pptSrc;
+ RegionRec rgnDst8, rgnDst32;
+ BoxPtr pbox;
+ int i, nbox, dx, dy;
+ unsigned long pm = (pWin->drawable.depth == 24) ? ~0 : 0xff000000;
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+
+ REGION_INIT(pScreen, &rgnDst8, NullBox, 0);
+ REGION_INIT(pScreen, &rgnDst32, NullBox, 0);
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
+ REGION_INTERSECT(pScreen, &rgnDst8, &pWin->borderClip, prgnSrc);
+
+ nbox = REGION_NUM_RECTS(&rgnDst8);
+ if(nbox &&
+ (pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) {
+
+ pbox = REGION_RECTS(&rgnDst8);
+ for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+ if(pm == ~0)
+ cfb32DoBitbltCopy((DrawablePtr)pRoot, (DrawablePtr)pRoot,
+ GXcopy, &rgnDst8, pptSrc, ~0L);
+ else
+ cfbDoBitblt8To8GXcopy((DrawablePtr)pRoot, (DrawablePtr)pRoot,
+ GXcopy, &rgnDst8, pptSrc, ~0, 0);
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+
+ if(pm != ~0) {
+ miSegregateChildren(pWin, &rgnDst32, 24);
+ if(REGION_NOTEMPTY(pScreen, &rgnDst32)) {
+ REGION_INTERSECT(pScreen, &rgnDst32, &rgnDst32, prgnSrc);
+ nbox = REGION_NUM_RECTS(&rgnDst32);
+ if(nbox &&
+ (pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))){
+
+ pbox = REGION_RECTS(&rgnDst32);
+ for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ cfbDoBitblt24To24GXcopy((DrawablePtr)pRoot, (DrawablePtr)pRoot,
+ GXcopy, &rgnDst32, pptSrc, ~0, 0);
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+ }
+ }
+
+ REGION_UNINIT(pScreen, &rgnDst8);
+ REGION_UNINIT(pScreen, &rgnDst32);
+}
+
+Bool
+cfb8_32ChangeWindowAttributes(
+ WindowPtr pWin,
+ unsigned long mask
+){
+ return TRUE;
+}
+
+
+void
+cfb8_32WindowExposures(
+ WindowPtr pWin,
+ RegionPtr pReg,
+ RegionPtr pOtherReg
+){
+
+ if(REGION_NUM_RECTS(pReg) && (pWin->drawable.depth == 24)) {
+ cfb8_32ScreenPtr pScreenPriv =
+ CFB8_32_GET_SCREEN_PRIVATE(pWin->drawable.pScreen);
+
+ cfb8_32FillBoxSolid8((DrawablePtr)pWin, REGION_NUM_RECTS(pReg),
+ REGION_RECTS(pReg), pScreenPriv->key);
+ }
+
+ miWindowExposures(pWin, pReg, pOtherReg);
+}
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xfree86/xf8_32bpp/xf86overlay.c b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/xf86overlay.c
new file mode 100644
index 000000000..0db0465b4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xfree86/xf8_32bpp/xf86overlay.c
@@ -0,0 +1,1251 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xf8_32bpp/xf86overlay.c,v 1.5 1999/03/21 07:35:35 dawes Exp $ */
+
+/*
+ Copyright (C) 1998. The XFree86 Project Inc.
+
+ Written by Mark Vojkovich (mvojkovi@ucsd.edu)
+*/
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "migc.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "colormapst.h"
+#include "cfb8_32.h"
+
+/** Screen Functions **/
+
+static Bool OverlayCloseScreen (int, ScreenPtr);
+static Bool OverlayCreateGC(GCPtr pGC);
+static Bool OverlayDestroyPixmap(PixmapPtr);
+static PixmapPtr OverlayCreatePixmap(ScreenPtr, int, int, int);
+static Bool OverlayChangeWindowAttributes(WindowPtr, unsigned long);
+static void OverlayPaintWindow(WindowPtr, RegionPtr, int);
+
+/** Funcs **/
+static void OverlayValidateGC(GCPtr, unsigned long, DrawablePtr);
+static void OverlayChangeGC(GCPtr, unsigned long);
+static void OverlayCopyGC(GCPtr, unsigned long, GCPtr);
+static void OverlayDestroyGC(GCPtr);
+static void OverlayChangeClip(GCPtr, int, pointer, int);
+static void OverlayDestroyClip(GCPtr);
+static void OverlayCopyClip(GCPtr, GCPtr);
+
+
+static PixmapPtr OverlayRefreshPixmap(PixmapPtr);
+
+static GCFuncs OverlayGCFuncs = {
+ OverlayValidateGC, OverlayChangeGC,
+ OverlayCopyGC, OverlayDestroyGC,
+ OverlayChangeClip, OverlayDestroyClip,
+ OverlayCopyClip
+};
+
+
+/** Pixmap Ops */
+static void PixmapFillSpans(DrawablePtr, GCPtr, int, DDXPointPtr, int *,
+ int);
+static void PixmapSetSpans(DrawablePtr, GCPtr, char *, DDXPointPtr,
+ int *, int, int);
+static void PixmapPutImage(DrawablePtr, GCPtr, int, int, int, int, int,
+ int, int, char *);
+static void PixmapPushPixels(GCPtr, PixmapPtr, DrawablePtr, int, int,
+ int, int);
+static RegionPtr PixmapCopyArea(DrawablePtr, DrawablePtr, GCPtr, int, int,
+ int, int, int, int);
+static RegionPtr PixmapCopyPlane(DrawablePtr, DrawablePtr, GCPtr, int, int,
+ int, int, int, int, unsigned long);
+static void PixmapPolyPoint(DrawablePtr, GCPtr, int, int, xPoint *);
+static void PixmapPolylines(DrawablePtr, GCPtr, int, int, DDXPointPtr);
+static void PixmapPolySegment(DrawablePtr, GCPtr, int, xSegment *);
+static void PixmapPolyRectangle(DrawablePtr, GCPtr, int, xRectangle *);
+static void PixmapPolyArc(DrawablePtr, GCPtr, int, xArc *);
+static void PixmapFillPolygon(DrawablePtr, GCPtr, int, int, int,
+ DDXPointPtr);
+static void PixmapPolyFillRect(DrawablePtr, GCPtr, int, xRectangle *);
+static void PixmapPolyFillArc(DrawablePtr, GCPtr, int, xArc *);
+static int PixmapPolyText8(DrawablePtr, GCPtr, int, int, int, char *);
+static int PixmapPolyText16(DrawablePtr, GCPtr, int, int, int,
+ unsigned short *);
+static void PixmapImageText8(DrawablePtr, GCPtr, int, int, int, char *);
+static void PixmapImageText16(DrawablePtr, GCPtr, int, int, int,
+ unsigned short *);
+static void PixmapImageGlyphBlt(DrawablePtr, GCPtr, int, int,
+ unsigned int, CharInfoPtr *, pointer);
+static void PixmapPolyGlyphBlt(DrawablePtr, GCPtr, int, int,
+ unsigned int, CharInfoPtr *, pointer);
+
+static GCOps PixmapGCOps = {
+ PixmapFillSpans, PixmapSetSpans,
+ PixmapPutImage, PixmapCopyArea,
+ PixmapCopyPlane, PixmapPolyPoint,
+ PixmapPolylines, PixmapPolySegment,
+ PixmapPolyRectangle, PixmapPolyArc,
+ PixmapFillPolygon, PixmapPolyFillRect,
+ PixmapPolyFillArc, PixmapPolyText8,
+ PixmapPolyText16, PixmapImageText8,
+ PixmapImageText16, PixmapImageGlyphBlt,
+ PixmapPolyGlyphBlt, PixmapPushPixels,
+#ifdef NEED_LINEHELPER
+ NULL,
+#endif
+ {NULL} /* devPrivate */
+};
+
+
+/** Window Ops **/
+static void WindowFillSpans(DrawablePtr, GCPtr, int, DDXPointPtr, int *,
+ int);
+static void WindowSetSpans(DrawablePtr, GCPtr, char *, DDXPointPtr,
+ int *, int, int);
+static void WindowPutImage(DrawablePtr, GCPtr, int, int, int, int, int,
+ int, int, char *);
+static void WindowPushPixels(GCPtr, PixmapPtr, DrawablePtr, int, int,
+ int, int);
+static RegionPtr WindowCopyArea(DrawablePtr, DrawablePtr, GCPtr, int, int,
+ int, int, int, int);
+static RegionPtr WindowCopyPlane(DrawablePtr, DrawablePtr, GCPtr, int, int,
+ int, int, int, int, unsigned long);
+static void WindowPolyPoint(DrawablePtr, GCPtr, int, int, xPoint *);
+static void WindowPolylines(DrawablePtr, GCPtr, int, int, DDXPointPtr);
+static void WindowPolySegment(DrawablePtr, GCPtr, int, xSegment *);
+static void WindowPolyRectangle(DrawablePtr, GCPtr, int, xRectangle *);
+static void WindowPolyArc(DrawablePtr, GCPtr, int, xArc *);
+static void WindowFillPolygon(DrawablePtr, GCPtr, int, int, int,
+ DDXPointPtr);
+static void WindowPolyFillRect(DrawablePtr, GCPtr, int, xRectangle *);
+static void WindowPolyFillArc(DrawablePtr, GCPtr, int, xArc *);
+static int WindowPolyText8(DrawablePtr, GCPtr, int, int, int, char *);
+static int WindowPolyText16(DrawablePtr, GCPtr, int, int, int,
+ unsigned short *);
+static void WindowImageText8(DrawablePtr, GCPtr, int, int, int, char *);
+static void WindowImageText16(DrawablePtr, GCPtr, int, int, int,
+ unsigned short *);
+static void WindowImageGlyphBlt(DrawablePtr, GCPtr, int, int,
+ unsigned int, CharInfoPtr *, pointer);
+static void WindowPolyGlyphBlt(DrawablePtr, GCPtr, int, int,
+ unsigned int, CharInfoPtr *, pointer);
+
+static GCOps WindowGCOps = {
+ WindowFillSpans, WindowSetSpans,
+ WindowPutImage, WindowCopyArea,
+ WindowCopyPlane, WindowPolyPoint,
+ WindowPolylines, WindowPolySegment,
+ WindowPolyRectangle, WindowPolyArc,
+ WindowFillPolygon, WindowPolyFillRect,
+ WindowPolyFillArc, WindowPolyText8,
+ WindowPolyText16, WindowImageText8,
+ WindowImageText16, WindowImageGlyphBlt,
+ WindowPolyGlyphBlt, WindowPushPixels,
+#ifdef NEED_LINEHELPER
+ NULL,
+#endif
+ {NULL} /* devPrivate */
+};
+
+/** privates **/
+
+typedef struct {
+ CloseScreenProcPtr CloseScreen;
+ CreateGCProcPtr CreateGC;
+ CreatePixmapProcPtr CreatePixmap;
+ DestroyPixmapProcPtr DestroyPixmap;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ int LockPrivate;
+} OverlayScreenRec, *OverlayScreenPtr;
+
+typedef struct {
+ GCFuncs *wrapFuncs;
+ GCOps *wrapOps;
+ GCOps *overlayOps;
+ unsigned long fg;
+ unsigned long bg;
+ unsigned long pm;
+ PixmapPtr tile;
+} OverlayGCRec, *OverlayGCPtr;
+
+typedef struct {
+ PixmapPtr pix32;
+ Bool dirty;
+} OverlayPixmapRec, *OverlayPixmapPtr;
+
+
+static int OverlayScreenIndex = -1;
+static int OverlayGCIndex = -1;
+static int OverlayPixmapIndex = -1;
+static unsigned long OverlayGeneration = 0;
+
+/** Macros **/
+
+#define TILE_EXISTS(pGC) (!(pGC)->tileIsPixel && (pGC)->tile.pixmap)
+
+#define OVERLAY_GET_PIXMAP_PRIVATE(pPix) \
+ (OverlayPixmapPtr)((pPix)->devPrivates[OverlayPixmapIndex].ptr)
+
+#define OVERLAY_GET_SCREEN_PRIVATE(pScreen) \
+ (OverlayScreenPtr)((pScreen)->devPrivates[OverlayScreenIndex].ptr)
+
+#define OVERLAY_GET_GC_PRIVATE(pGC) \
+ (OverlayGCPtr)((pGC)->devPrivates[OverlayGCIndex].ptr)
+
+#define OVERLAY_GC_FUNC_PROLOGUE(pGC)\
+ OverlayGCPtr pGCPriv = OVERLAY_GET_GC_PRIVATE(pGC);\
+ (pGC)->funcs = pGCPriv->wrapFuncs;\
+ if(pGCPriv->overlayOps) \
+ (pGC)->ops = pGCPriv->wrapOps
+
+#define OVERLAY_GC_FUNC_EPILOGUE(pGC)\
+ pGCPriv->wrapFuncs = (pGC)->funcs;\
+ (pGC)->funcs = &OverlayGCFuncs;\
+ if(pGCPriv->overlayOps) { \
+ pGCPriv->wrapOps = (pGC)->ops;\
+ (pGC)->ops = pGCPriv->overlayOps;\
+ }
+
+#define WINDOW_GC_OP_PROLOGUE(pGC)\
+ OverlayScreenPtr pScreenPriv = OVERLAY_GET_SCREEN_PRIVATE((pGC)->pScreen);\
+ OverlayGCPtr pGCPriv = OVERLAY_GET_GC_PRIVATE(pGC);\
+ unsigned long oldfg = (pGC)->fgPixel;\
+ unsigned long oldbg = (pGC)->bgPixel;\
+ unsigned long oldpm = (pGC)->planemask;\
+ PixmapPtr oldtile = (pGC)->tile.pixmap;\
+ (pGC)->fgPixel = pGCPriv->fg;\
+ (pGC)->bgPixel = pGCPriv->bg;\
+ (pGC)->planemask = pGCPriv->pm;\
+ if(pGCPriv->tile) (pGC)->tile.pixmap = pGCPriv->tile;\
+ (pGC)->funcs = pGCPriv->wrapFuncs;\
+ (pGC)->ops = pGCPriv->wrapOps;\
+ pScreenPriv->LockPrivate++
+
+
+#define WINDOW_GC_OP_EPILOGUE(pGC)\
+ pGCPriv->wrapOps = (pGC)->ops;\
+ pGCPriv->wrapFuncs = (pGC)->funcs;\
+ (pGC)->fgPixel = oldfg;\
+ (pGC)->bgPixel = oldbg;\
+ (pGC)->planemask = oldpm;\
+ (pGC)->tile.pixmap = oldtile;\
+ (pGC)->funcs = &OverlayGCFuncs;\
+ (pGC)->ops = &WindowGCOps;\
+ pScreenPriv->LockPrivate--
+
+
+#define PIXMAP_GC_OP_PROLOGUE(pGC)\
+ OverlayGCPtr pGCPriv = OVERLAY_GET_GC_PRIVATE(pGC);\
+ OverlayPixmapPtr pPixPriv = OVERLAY_GET_PIXMAP_PRIVATE((PixmapPtr)pDraw);\
+ pGC->funcs = pGCPriv->wrapFuncs;\
+ pGC->ops = pGCPriv->wrapOps
+
+#define PIXMAP_GC_OP_EPILOGUE(pGC)\
+ pGCPriv->wrapOps = pGC->ops;\
+ pGC->funcs = &OverlayGCFuncs;\
+ pGC->ops = &PixmapGCOps;\
+ pPixPriv->dirty = TRUE
+
+
+Bool
+xf86Overlay8Plus32Init (ScreenPtr pScreen)
+{
+ OverlayScreenPtr pScreenPriv;
+
+ if(OverlayGeneration != serverGeneration) {
+ if(((OverlayScreenIndex = AllocateScreenPrivateIndex()) < 0) ||
+ ((OverlayGCIndex = AllocateGCPrivateIndex()) < 0) ||
+ ((OverlayPixmapIndex = AllocatePixmapPrivateIndex()) < 0))
+ return FALSE;
+
+ OverlayGeneration = serverGeneration;
+ }
+
+ if (!AllocateGCPrivate(pScreen, OverlayGCIndex, sizeof(OverlayGCRec)))
+ return FALSE;
+
+ if (!AllocatePixmapPrivate(pScreen, OverlayPixmapIndex,
+ sizeof(OverlayPixmapRec)))
+ return FALSE;
+
+ if (!(pScreenPriv = xalloc(sizeof(OverlayScreenRec))))
+ return FALSE;
+
+ pScreen->devPrivates[OverlayScreenIndex].ptr = (pointer)pScreenPriv;
+
+ pScreenPriv->CreateGC = pScreen->CreateGC;
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreenPriv->CreatePixmap = pScreen->CreatePixmap;
+ pScreenPriv->DestroyPixmap = pScreen->DestroyPixmap;
+ pScreenPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
+ pScreenPriv->PaintWindowBackground = pScreen->PaintWindowBackground;
+ pScreenPriv->PaintWindowBorder = pScreen->PaintWindowBorder;
+
+ pScreen->CreateGC = OverlayCreateGC;
+ pScreen->CloseScreen = OverlayCloseScreen;
+ pScreen->CreatePixmap = OverlayCreatePixmap;
+ pScreen->DestroyPixmap = OverlayDestroyPixmap;
+ pScreen->ChangeWindowAttributes = OverlayChangeWindowAttributes;
+ pScreen->PaintWindowBackground = OverlayPaintWindow;
+ pScreen->PaintWindowBorder = OverlayPaintWindow;
+
+ pScreenPriv->LockPrivate = 0;
+
+ /* allocate the key in the default map */
+ if(pScreen->defColormap) {
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ unsigned short red = 0;
+ unsigned short green = ~0;
+ unsigned short blue = 0;
+ Pixel pixel = pScrn->colorKey;
+ ColormapPtr pmap;
+ xColorItem color;
+
+ color.red = color.blue = color.green = 0;
+ color.pixel = pScrn->colorKey;
+ color.flags = DoRed | DoGreen | DoBlue;
+
+ pmap = (ColormapPtr)LookupIDByType(pScreen->defColormap, RT_COLORMAP);
+
+ /* allocate a color not already in the map (like green) */
+ AllocColor(pmap, &red, &green, &blue, &pixel, 0);
+
+ /* set it to something already in the map (like black) */
+ StoreColors(pmap, 1, &color);
+ }
+
+ return TRUE;
+}
+
+
+/*********************** Screen Funcs ***********************/
+
+Bool
+OverlayCreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ OverlayGCPtr pGCPriv = OVERLAY_GET_GC_PRIVATE(pGC);
+ OverlayScreenPtr pScreenPriv = OVERLAY_GET_SCREEN_PRIVATE(pScreen);
+ Bool ret;
+
+ pScreen->CreateGC = pScreenPriv->CreateGC;
+
+ if((ret = (*pScreen->CreateGC)(pGC)) && (pGC->depth != 1)) {
+ pGCPriv->wrapFuncs = pGC->funcs;
+ pGC->funcs = &OverlayGCFuncs;
+ pGCPriv->wrapOps = NULL;
+ pGCPriv->overlayOps = NULL;
+ pGCPriv->tile = NULL;
+ }
+
+ pScreen->CreateGC = OverlayCreateGC;
+
+ return ret;
+}
+
+static PixmapPtr
+OverlayCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
+{
+ OverlayScreenPtr pScreenPriv = OVERLAY_GET_SCREEN_PRIVATE(pScreen);
+ PixmapPtr pPix;
+
+ pScreen->CreatePixmap = pScreenPriv->CreatePixmap;
+ pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth);
+ pScreen->CreatePixmap = OverlayCreatePixmap;
+
+ /* We initialize all the privates */
+ if(pPix) {
+ OverlayPixmapPtr pPriv = OVERLAY_GET_PIXMAP_PRIVATE(pPix);
+ pPriv->pix32 = NULL;
+ pPriv->dirty = TRUE;
+ }
+
+ return pPix;
+}
+
+static Bool
+OverlayDestroyPixmap(PixmapPtr pPix)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ OverlayScreenPtr pScreenPriv = OVERLAY_GET_SCREEN_PRIVATE(pScreen);
+ Bool result;
+
+ pScreen->DestroyPixmap = pScreenPriv->DestroyPixmap;
+
+ if((pPix->refcnt == 1) && (pPix->drawable.bitsPerPixel == 8)) {
+ OverlayPixmapPtr pPriv = OVERLAY_GET_PIXMAP_PRIVATE(pPix);
+ if(pPriv->pix32) {
+ if(pPriv->pix32->refcnt != 1)
+ ErrorF("Warning! private pix refcnt = %i\n", pPriv->pix32->refcnt);
+ (*pScreen->DestroyPixmap)(pPriv->pix32);
+ }
+ pPriv->pix32 = NULL;
+ }
+
+ result = (*pScreen->DestroyPixmap) (pPix);
+ pScreen->DestroyPixmap = OverlayDestroyPixmap;
+
+ return result;
+}
+
+static Bool
+OverlayCloseScreen (int i, ScreenPtr pScreen)
+{
+ OverlayScreenPtr pScreenPriv = OVERLAY_GET_SCREEN_PRIVATE(pScreen);
+
+ pScreen->CreateGC = pScreenPriv->CreateGC;
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ pScreen->CreatePixmap = pScreenPriv->CreatePixmap;
+ pScreen->DestroyPixmap = pScreenPriv->DestroyPixmap;
+ pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes;
+ pScreen->PaintWindowBackground = pScreenPriv->PaintWindowBackground;
+ pScreen->PaintWindowBorder = pScreenPriv->PaintWindowBorder;
+
+ xfree ((pointer) pScreenPriv);
+
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+
+
+static Bool
+OverlayChangeWindowAttributes (WindowPtr pWin, unsigned long mask)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ OverlayScreenPtr pScreenPriv = OVERLAY_GET_SCREEN_PRIVATE(pScreen);
+ Bool result;
+
+ if(pWin->drawable.depth == 8) {
+ if((mask & CWBackPixmap) &&
+ (pWin->backgroundState == BackgroundPixmap))
+ OverlayRefreshPixmap(pWin->background.pixmap);
+
+ if((mask & CWBorderPixmap) && !pWin->borderIsPixel)
+ OverlayRefreshPixmap(pWin->border.pixmap);
+ }
+
+ pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes;
+ result = (*pScreen->ChangeWindowAttributes) (pWin, mask);
+ pScreen->ChangeWindowAttributes = OverlayChangeWindowAttributes;
+
+ return result;
+}
+
+static void
+OverlayPaintWindow(
+ WindowPtr pWin,
+ RegionPtr pReg,
+ int what
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ OverlayScreenPtr pScreenPriv = OVERLAY_GET_SCREEN_PRIVATE(pScreen);
+ OverlayPixmapPtr pixPriv;
+ PixmapPtr oldPix = NULL;
+
+ if(what == PW_BACKGROUND) {
+ if(pWin->drawable.depth == 8) {
+ if(pWin->backgroundState == ParentRelative) {
+ do {
+ pWin = pWin->parent;
+ } while (pWin->backgroundState == ParentRelative);
+ }
+
+ if(pWin->backgroundState == BackgroundPixmap) {
+ oldPix = pWin->background.pixmap;
+ pixPriv = OVERLAY_GET_PIXMAP_PRIVATE(oldPix);
+ pWin->background.pixmap = pixPriv->pix32;
+ }
+ }
+
+ pScreen->PaintWindowBackground = pScreenPriv->PaintWindowBackground;
+ (*pScreen->PaintWindowBackground) (pWin, pReg, what);
+ pScreen->PaintWindowBackground = OverlayPaintWindow;
+
+ if(oldPix)
+ pWin->background.pixmap = oldPix;
+ } else {
+ if((pWin->drawable.depth == 8) && !pWin->borderIsPixel) {
+ oldPix = pWin->border.pixmap;
+ pixPriv = OVERLAY_GET_PIXMAP_PRIVATE(oldPix);
+ pWin->border.pixmap = pixPriv->pix32;
+ }
+
+ pScreen->PaintWindowBorder = pScreenPriv->PaintWindowBorder;
+ (*pScreen->PaintWindowBorder) (pWin, pReg, what);
+ pScreen->PaintWindowBorder = OverlayPaintWindow;
+
+ if(oldPix)
+ pWin->border.pixmap = oldPix;
+ }
+}
+
+
+/*********************** GC Funcs *****************************/
+
+
+static PixmapPtr
+OverlayRefreshPixmap(PixmapPtr pix8)
+{
+ OverlayPixmapPtr pixPriv = OVERLAY_GET_PIXMAP_PRIVATE(pix8);
+ ScreenPtr pScreen = pix8->drawable.pScreen;
+
+ if(!pixPriv->pix32) {
+ PixmapPtr newPix;
+
+ newPix = (*pScreen->CreatePixmap)(pScreen, pix8->drawable.width,
+ pix8->drawable.height, 24);
+ newPix->drawable.depth = 8; /* Bad Mark! Bad Mark! */
+ pixPriv->pix32 = newPix;
+ pixPriv->dirty = TRUE;
+ }
+
+ if(pixPriv->dirty) {
+ OverlayScreenPtr pScreenPriv = OVERLAY_GET_SCREEN_PRIVATE(pScreen);
+ GCPtr pGC;
+
+ pGC = GetScratchGC(8, pScreen);
+
+ pScreenPriv->LockPrivate++; /* don't modify this one */
+ ValidateGC((DrawablePtr)pixPriv->pix32, pGC);
+
+ (*pGC->ops->CopyArea)((DrawablePtr)pix8, (DrawablePtr)pixPriv->pix32,
+ pGC, 0, 0, pix8->drawable.width, pix8->drawable.height, 0, 0);
+ pScreenPriv->LockPrivate--;
+ FreeScratchGC(pGC);
+
+ pixPriv->dirty = FALSE;
+ pixPriv->pix32->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+
+ return pixPriv->pix32;
+}
+
+
+static void
+OverlayValidateGC(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+){
+ OverlayScreenPtr pScreenPriv = OVERLAY_GET_SCREEN_PRIVATE(pGC->pScreen);
+ OVERLAY_GC_FUNC_PROLOGUE (pGC);
+
+ if(pScreenPriv->LockPrivate < 0) {
+ ErrorF("Something is wrong in OverlayValidateGC!\n");
+ pScreenPriv->LockPrivate = 0;
+ }
+
+ if(pGC->depth == 24) {
+ unsigned long oldpm = pGC->planemask;
+ pGCPriv->overlayOps = NULL;
+
+ if(pDraw->type == DRAWABLE_WINDOW)
+ pGC->planemask &= 0x00ffffff;
+ else
+ pGC->planemask |= 0xff000000;
+
+ if(oldpm != pGC->planemask) changes |= GCPlaneMask;
+
+ (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
+
+ } else { /* depth == 8 */
+ unsigned long newChanges = 0;
+
+ if(pDraw->bitsPerPixel == 32) {
+
+ if(pGC->fillStyle == FillTiled)
+ pGCPriv->tile = OverlayRefreshPixmap(pGC->tile.pixmap);
+ else pGCPriv->tile = NULL;
+
+ if(pGCPriv->overlayOps != &WindowGCOps) {
+ newChanges = GCForeground | GCBackground | GCPlaneMask;
+ if(pGCPriv->tile)
+ newChanges |= GCTile;
+ }
+ pGCPriv->overlayOps = &WindowGCOps;
+
+ if(!pScreenPriv->LockPrivate) {
+ unsigned long oldfg = pGC->fgPixel;
+ unsigned long oldbg = pGC->bgPixel;
+ unsigned long oldpm = pGC->planemask;
+ PixmapPtr oldtile = pGC->tile.pixmap;
+
+ pGC->fgPixel = pGCPriv->fg = oldfg << 24;
+ pGC->bgPixel = pGCPriv->bg = oldbg << 24;
+ pGC->planemask = pGCPriv->pm = oldpm << 24;
+ if(pGCPriv->tile)
+ pGC->tile.pixmap = pGCPriv->tile;
+
+ (*pGC->funcs->ValidateGC)(pGC, changes | newChanges, pDraw);
+
+ pGC->fgPixel = oldfg;
+ pGC->bgPixel = oldbg;
+ pGC->planemask = oldpm;
+ pGC->tile.pixmap = oldtile;
+ } else {
+ pGCPriv->fg = pGC->fgPixel;
+ pGCPriv->bg = pGC->bgPixel;
+ pGCPriv->pm = pGC->planemask;
+
+ (*pGC->funcs->ValidateGC)(pGC, changes | newChanges, pDraw);
+ }
+
+ } else { /* bitsPerPixel == 8 */
+ if(pGCPriv->overlayOps == &WindowGCOps) {
+ newChanges = GCForeground | GCBackground | GCPlaneMask;
+ if(pGCPriv->tile)
+ newChanges |= GCTile;
+ }
+ pGCPriv->overlayOps = &PixmapGCOps;
+
+ (*pGC->funcs->ValidateGC)(pGC, changes | newChanges, pDraw);
+ }
+ }
+
+ OVERLAY_GC_FUNC_EPILOGUE (pGC);
+}
+
+
+static void
+OverlayDestroyGC(GCPtr pGC)
+{
+ OVERLAY_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->DestroyGC)(pGC);
+ OVERLAY_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+OverlayChangeGC (
+ GCPtr pGC,
+ unsigned long mask
+){
+ OVERLAY_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ OVERLAY_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+OverlayCopyGC (
+ GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst
+){
+ OVERLAY_GC_FUNC_PROLOGUE (pGCDst);
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ OVERLAY_GC_FUNC_EPILOGUE (pGCDst);
+}
+static void
+OverlayChangeClip (
+ GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects
+){
+ OVERLAY_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ OVERLAY_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+OverlayCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ OVERLAY_GC_FUNC_PROLOGUE (pgcDst);
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ OVERLAY_GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+OverlayDestroyClip(GCPtr pGC)
+{
+ OVERLAY_GC_FUNC_PROLOGUE (pGC);
+ (* pGC->funcs->DestroyClip)(pGC);
+ OVERLAY_GC_FUNC_EPILOGUE (pGC);
+}
+
+
+
+/******************* Window GC ops ***********************/
+
+static void
+WindowFillSpans(
+ DrawablePtr pDraw,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted
+){
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+WindowSetSpans(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ char *pcharsrc,
+ register DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted
+){
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+WindowPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage
+){
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+}
+
+static RegionPtr
+WindowCopyArea(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+){
+ RegionPtr ret;
+
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static RegionPtr
+WindowCopyPlane(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+){
+ RegionPtr ret;
+
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static void
+WindowPolyPoint(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit
+){
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+WindowPolylines(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit
+){
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+WindowPolySegment(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+WindowPolyRectangle(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+){
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+WindowPolyArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+WindowFillPolygon(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+WindowPolyFillRect(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+WindowPolyFillArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+}
+
+static int
+WindowPolyText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ int ret;
+
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static int
+WindowPolyText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ int ret;
+
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static void
+WindowImageText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+WindowImageText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+WindowImageGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph,
+ ppci, pglyphBase);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+WindowPolyGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph,
+ ppci, pglyphBase);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+WindowPushPixels(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy, int xOrg, int yOrg
+){
+ WINDOW_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+ WINDOW_GC_OP_EPILOGUE(pGC);
+}
+
+
+/******************* Pixmap GC ops ***********************/
+
+static void
+PixmapFillSpans(
+ DrawablePtr pDraw,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted
+){
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+PixmapSetSpans(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ char *pcharsrc,
+ register DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted
+){
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+PixmapPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage
+){
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+}
+
+static RegionPtr
+PixmapCopyArea(
+ DrawablePtr pSrc,
+ DrawablePtr pDraw,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+){
+ RegionPtr ret;
+
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ ret = (*pGC->ops->CopyArea)(pSrc, pDraw,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static RegionPtr
+PixmapCopyPlane(
+ DrawablePtr pSrc,
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+){
+ RegionPtr ret;
+
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDraw,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static void
+PixmapPolyPoint(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit
+){
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+PixmapPolylines(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit
+){
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+PixmapPolySegment(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+PixmapPolyRectangle(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+){
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+PixmapPolyArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+PixmapFillPolygon(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+PixmapPolyFillRect(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+PixmapPolyFillArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+}
+
+static int
+PixmapPolyText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ int ret;
+
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static int
+PixmapPolyText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ int ret;
+
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static void
+PixmapImageText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+PixmapImageText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+PixmapImageGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph,
+ ppci, pglyphBase);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+PixmapPolyGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph,
+ ppci, pglyphBase);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+PixmapPushPixels(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy, int xOrg, int yOrg
+){
+ PIXMAP_GC_OP_PROLOGUE(pGC);
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+ PIXMAP_GC_OP_EPILOGUE(pGC);
+}
+
+
diff --git a/xc/programs/Xserver/hw/xnest/Args.c b/xc/programs/Xserver/hw/xnest/Args.c
new file mode 100644
index 000000000..77ba9ac5b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Args.c
@@ -0,0 +1,188 @@
+/* $XConsortium: Args.c /main/3 1996/08/20 11:31:52 kaleb $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+#include "X.h"
+#include "Xproto.h"
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Args.h"
+
+char *xnestDisplayName = NULL;
+Bool xnestSynchronize = False;
+Bool xnestFullGeneration = False;
+int xnestDefaultClass;
+Bool xnestUserDefaultClass = False;
+int xnestDefaultDepth;
+Bool xnestUserDefaultDepth = False;
+Bool xnestSoftwareScreenSaver = False;
+int xnestX;
+int xnestY;
+unsigned int xnestWidth;
+unsigned int xnestHeight;
+int xnestUserGeometry = 0;
+int xnestBorderWidth;
+Bool xnestUserBorderWidth = False;
+char *xnestWindowName = NULL;
+int xnestNumScreens = 0;
+Bool xnestDoDirectColormaps = False;
+Window xnestParentWindow = 0;
+
+int ddxProcessArgument (argc, argv, i)
+ int argc;
+ char *argv[] ;
+ int i;
+{
+ if (!strcmp(argv[i], "-display")) {
+ if (++i < argc) {
+ xnestDisplayName = argv[i];
+ return 2;
+ }
+ return 0;
+ }
+ if (!strcmp(argv[i], "-sync")) {
+ xnestSynchronize = True;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-full")) {
+ xnestFullGeneration = True;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-class")) {
+ if (++i < argc) {
+ if (!strcmp(argv[i], "StaticGray")) {
+ xnestDefaultClass = StaticGray;
+ xnestUserDefaultClass = True;
+ return 2;
+ }
+ else if (!strcmp(argv[i], "GrayScale")) {
+ xnestDefaultClass = GrayScale;
+ xnestUserDefaultClass = True;
+ return 2;
+ }
+ else if (!strcmp(argv[i], "StaticColor")) {
+ xnestDefaultClass = StaticColor;
+ xnestUserDefaultClass = True;
+ return 2;
+ }
+ else if (!strcmp(argv[i], "PseudoColor")) {
+ xnestDefaultClass = PseudoColor;
+ xnestUserDefaultClass = True;
+ return 2;
+ }
+ else if (!strcmp(argv[i], "TrueColor")) {
+ xnestDefaultClass = TrueColor;
+ xnestUserDefaultClass = True;
+ return 2;
+ }
+ else if (!strcmp(argv[i], "DirectColor")) {
+ xnestDefaultClass = DirectColor;
+ xnestUserDefaultClass = True;
+ return 2;
+ }
+ }
+ return 0;
+ }
+ if (!strcmp(argv[i], "-cc")) {
+ if (++i < argc && sscanf(argv[i], "%i", &xnestDefaultClass) == 1) {
+ if (xnestDefaultClass >= 0 && xnestDefaultClass <= 5) {
+ xnestUserDefaultClass = True;
+ /* lex the OS layer process it as well, so return 0 */
+ }
+ }
+ return 0;
+ }
+ if (!strcmp(argv[i], "-depth")) {
+ if (++i < argc && sscanf(argv[i], "%i", &xnestDefaultDepth) == 1) {
+ if (xnestDefaultDepth > 0) {
+ xnestUserDefaultDepth = True;
+ return 2;
+ }
+ }
+ return 0;
+ }
+ if (!strcmp(argv[i], "-sss")) {
+ xnestSoftwareScreenSaver = True;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-geometry")) {
+ if (++i < argc) {
+ xnestUserGeometry = XParseGeometry(argv[i],
+ &xnestX, &xnestY,
+ &xnestWidth, &xnestHeight);
+ if (xnestUserGeometry) return 2;
+ }
+ return 0;
+ }
+ if (!strcmp(argv[i], "-bw")) {
+ if (++i < argc && sscanf(argv[i], "%i", &xnestBorderWidth) == 1) {
+ if (xnestBorderWidth >= 0) {
+ xnestUserBorderWidth = True;
+ return 2;
+ }
+ }
+ return 0;
+ }
+ if (!strcmp(argv[i], "-name")) {
+ if (++i < argc) {
+ xnestWindowName = argv[i];
+ return 2;
+ }
+ return 0;
+ }
+ if (!strcmp(argv[i], "-scrns")) {
+ if (++i < argc && sscanf(argv[i], "%i", &xnestNumScreens) == 1) {
+ if (xnestNumScreens > 0) {
+ if (xnestNumScreens > MAXSCREENS) {
+ ErrorF("Maximum number of screens is %d.\n", MAXSCREENS);
+ xnestNumScreens = MAXSCREENS;
+ }
+ return 2;
+ }
+ }
+ return 0;
+ }
+ if (!strcmp(argv[i], "-install")) {
+ xnestDoDirectColormaps = True;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-parent")) {
+ if (++i < argc) {
+ xnestParentWindow = (XID) strtol (argv[i], (char**)NULL, 0);
+ return 2;
+ }
+ }
+ return 0;
+}
+
+void ddxUseMsg()
+{
+ ErrorF("-display string display name of the real server\n");
+ ErrorF("-sync sinchronize with the real server\n");
+ ErrorF("-full utilize full regeneration\n");
+ ErrorF("-class string default visual class\n");
+ ErrorF("-depth int default depth\n");
+ ErrorF("-sss use software screen saver\n");
+ ErrorF("-geometry WxH+X+Y window size and position\n");
+ ErrorF("-bw int window border width\n");
+ ErrorF("-name string window name\n");
+ ErrorF("-scrns int number of screens to generate\n");
+ ErrorF("-install instal colormaps directly\n");
+}
diff --git a/xc/programs/Xserver/hw/xnest/Args.h b/xc/programs/Xserver/hw/xnest/Args.h
new file mode 100644
index 000000000..3841bf182
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Args.h
@@ -0,0 +1,38 @@
+/* $XConsortium: Args.h,v 1.1 93/07/12 15:27:56 rws Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef XNESTARGC_H
+#define XNESTARGS_H
+
+extern char *xnestDisplayName;
+extern Bool xnestSynchronize;
+extern Bool xnestFullGeneration;
+extern int xnestDefaultClass;
+extern Bool xnestUserDefaultClass;
+extern int xnestDefaultDepth;
+extern Bool xnestUserDefaultDepth;
+extern Bool xnestSoftwareScreenSaver;
+extern int xnestX;
+extern int xnestY;
+extern unsigned int xnestWidth;
+extern unsigned int xnestHeight;
+extern int xnestUserGeometry;
+extern int xnestBorderWidth;
+extern Bool xnestUserBorderWidth;
+extern char *xnestWindowName;
+extern int xnestNumScreens;
+extern Bool xnestDoDirectColormaps;
+
+#endif /* XNESTARGS_H */
diff --git a/xc/programs/Xserver/hw/xnest/Color.c b/xc/programs/Xserver/hw/xnest/Color.c
new file mode 100644
index 000000000..f5ad6d47e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Color.c
@@ -0,0 +1,499 @@
+/* $XConsortium: Color.c /main/8 1996/12/02 10:20:51 lehors $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+#include "X.h"
+#include "Xproto.h"
+#include "scrnintstr.h"
+#include "window.h"
+#include "windowstr.h"
+#include "colormapst.h"
+#include "resource.h"
+
+#include "Xnest.h"
+
+
+#include "Display.h"
+#include "Screen.h"
+#include "Color.h"
+#include "Visual.h"
+#include "XNWindow.h"
+#include "Args.h"
+
+static ColormapPtr InstalledMaps[MAXSCREENS];
+
+Bool xnestCreateColormap(pCmap)
+ ColormapPtr pCmap;
+{
+ VisualPtr pVisual;
+ XColor *colors;
+ int i, ncolors;
+ Pixel red, green, blue;
+ Pixel redInc, greenInc, blueInc;
+
+ pVisual = pCmap->pVisual;
+ ncolors = pVisual->ColormapEntries;
+
+ pCmap->devPriv = (pointer)xalloc(sizeof(xnestPrivColormap));
+
+ xnestColormapPriv(pCmap)->colormap =
+ XCreateColormap(xnestDisplay,
+ xnestDefaultWindows[pCmap->pScreen->myNum],
+ xnestVisual(pVisual),
+ (pVisual->class & DynamicClass) ?
+ AllocAll : AllocNone);
+
+
+ switch (pVisual->class) {
+ case StaticGray: /* read only */
+ colors = (XColor *)xalloc(ncolors * sizeof(XColor));
+ for (i = 0; i < ncolors; i++)
+ colors[i].pixel = i;
+ XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
+ for (i = 0; i < ncolors; i++) {
+ pCmap->red[i].co.local.red = colors[i].red;
+ pCmap->red[i].co.local.green = colors[i].red;
+ pCmap->red[i].co.local.blue = colors[i].red;
+ }
+ xfree(colors);
+ break;
+
+ case StaticColor: /* read only */
+ colors = (XColor *)xalloc(ncolors * sizeof(XColor));
+ for (i = 0; i < ncolors; i++)
+ colors[i].pixel = i;
+ XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
+ for (i = 0; i < ncolors; i++) {
+ pCmap->red[i].co.local.red = colors[i].red;
+ pCmap->red[i].co.local.green = colors[i].green;
+ pCmap->red[i].co.local.blue = colors[i].blue;
+ }
+ xfree(colors);
+ break;
+
+ case TrueColor: /* read only */
+ colors = (XColor *)xalloc(ncolors * sizeof(XColor));
+ red = green = blue = 0L;
+ redInc = lowbit(pVisual->redMask);
+ greenInc = lowbit(pVisual->greenMask);
+ blueInc = lowbit(pVisual->blueMask);
+ for (i = 0; i < ncolors; i++) {
+ colors[i].pixel = red | green | blue;
+ red += redInc;
+ if (red > pVisual->redMask) red = 0L;
+ green += greenInc;
+ if (green > pVisual->greenMask) green = 0L;
+ blue += blueInc;
+ if (blue > pVisual->blueMask) blue = 0L;
+ }
+ XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
+ for (i = 0; i < ncolors; i++) {
+ pCmap->red[i].co.local.red = colors[i].red;
+ pCmap->green[i].co.local.green = colors[i].green;
+ pCmap->blue[i].co.local.blue = colors[i].blue;
+ }
+ xfree(colors);
+ break;
+
+ case GrayScale: /* read and write */
+ break;
+
+ case PseudoColor: /* read and write */
+ break;
+
+ case DirectColor: /* read and write */
+ break;
+ }
+
+ return True;
+}
+
+void xnestDestroyColormap (pCmap)
+ ColormapPtr pCmap;
+{
+ XFreeColormap(xnestDisplay, xnestColormap(pCmap));
+ xfree(pCmap->devPriv);
+}
+
+#define SEARCH_PREDICATE \
+ (xnestWindow(pWin) != None && wColormap(pWin) == icws->cmapIDs[i])
+
+static int xnestCountInstalledColormapWindows(pWin, ptr)
+ WindowPtr pWin;
+ pointer ptr;
+{
+ xnestInstalledColormapWindows *icws = (xnestInstalledColormapWindows *)ptr;
+ int i;
+
+ for (i = 0; i < icws->numCmapIDs; i++)
+ if (SEARCH_PREDICATE) {
+ icws->numWindows++;
+ return WT_DONTWALKCHILDREN;
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+static int xnestGetInstalledColormapWindows(pWin, ptr)
+ WindowPtr pWin;
+ pointer ptr;
+{
+ xnestInstalledColormapWindows *icws = (xnestInstalledColormapWindows *)ptr;
+ int i;
+
+ for (i = 0; i < icws->numCmapIDs; i++)
+ if (SEARCH_PREDICATE) {
+ icws->windows[icws->index++] = xnestWindow(pWin);
+ return WT_DONTWALKCHILDREN;
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+static Window *xnestOldInstalledColormapWindows = NULL;
+static int xnestNumOldInstalledColormapWindows = 0;
+
+static Bool xnestSameInstalledColormapWindows(windows, numWindows)
+ Window *windows;
+ int numWindows;
+{
+ if (xnestNumOldInstalledColormapWindows != numWindows)
+ return False;
+
+ if (xnestOldInstalledColormapWindows == windows)
+ return True;
+
+ if (xnestOldInstalledColormapWindows == NULL || windows == NULL)
+ return False;
+
+ if (memcmp(xnestOldInstalledColormapWindows, windows,
+ numWindows * sizeof(Window)))
+ return False;
+
+ return True;
+}
+
+void xnestSetInstalledColormapWindows(pScreen)
+ ScreenPtr pScreen;
+{
+ xnestInstalledColormapWindows icws;
+ int numWindows;
+
+ icws.cmapIDs = (Colormap *)xalloc(pScreen->maxInstalledCmaps *
+ sizeof(Colormap));
+ icws.numCmapIDs = xnestListInstalledColormaps(pScreen, icws.cmapIDs);
+ icws.numWindows = 0;
+ WalkTree(pScreen, xnestCountInstalledColormapWindows, (pointer)&icws);
+ if (icws.numWindows) {
+ icws.windows = (Window *)xalloc((icws.numWindows + 1) * sizeof(Window));
+ icws.index = 0;
+ WalkTree(pScreen, xnestGetInstalledColormapWindows, (pointer)&icws);
+ icws.windows[icws.numWindows] = xnestDefaultWindows[pScreen->myNum];
+ numWindows = icws.numWindows + 1;
+ }
+ else {
+ icws.windows = NULL;
+ numWindows = 0;
+ }
+
+ xfree(icws.cmapIDs);
+
+ if (!xnestSameInstalledColormapWindows(icws.windows, icws.numWindows)) {
+ if (xnestOldInstalledColormapWindows)
+ xfree(xnestOldInstalledColormapWindows);
+
+#ifdef _XSERVER64
+ {
+ int i;
+ Window64 *windows = (Window64 *)xalloc(numWindows * sizeof(Window64));
+
+ for(i = 0; i < numWindows; ++i)
+ windows[i] = icws.windows[i];
+ XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
+ windows, numWindows);
+ xfree(windows);
+ }
+#else
+ XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
+ icws.windows, numWindows);
+#endif
+
+ xnestOldInstalledColormapWindows = icws.windows;
+ xnestNumOldInstalledColormapWindows = icws.numWindows;
+
+#ifdef DUMB_WINDOW_MANAGERS
+ /*
+ This code is for dumb window managers.
+ This will only work with default local visual colormaps.
+ */
+ if (icws.numWindows)
+ {
+ WindowPtr pWin;
+ Visual *visual;
+ ColormapPtr pCmap;
+
+ pWin = xnestWindowPtr(icws.windows[0]);
+ visual = xnestVisualFromID(pScreen, wVisual(pWin));
+
+ if (visual == xnestDefaultVisual(pScreen))
+ pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin),
+ RT_COLORMAP);
+ else
+ pCmap = (ColormapPtr)LookupIDByType(pScreen->defColormap,
+ RT_COLORMAP);
+
+ XSetWindowColormap(xnestDisplay,
+ xnestDefaultWindows[pScreen->myNum],
+ xnestColormap(pCmap));
+ }
+#endif /* DUMB_WINDOW_MANAGERS */
+ }
+ else
+ if (icws.windows) xfree(icws.windows);
+}
+
+void xnestSetScreenSaverColormapWindow(pScreen)
+ ScreenPtr pScreen;
+{
+ if (xnestOldInstalledColormapWindows)
+ xfree(xnestOldInstalledColormapWindows);
+
+#ifdef _XSERVER64
+ {
+ Window64 window;
+
+ window = xnestScreenSaverWindows[pScreen->myNum];
+ XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
+ &window, 1);
+ xnestScreenSaverWindows[pScreen->myNum] = window;
+ }
+#else
+ XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
+ &xnestScreenSaverWindows[pScreen->myNum], 1);
+#endif /* _XSERVER64 */
+
+ xnestOldInstalledColormapWindows = NULL;
+ xnestNumOldInstalledColormapWindows = 0;
+
+ xnestDirectUninstallColormaps(pScreen);
+}
+
+void xnestDirectInstallColormaps(pScreen)
+ ScreenPtr pScreen;
+{
+ int i, n;
+ Colormap pCmapIDs[MAXCMAPS];
+
+ if (!xnestDoDirectColormaps) return;
+
+ n = (*pScreen->ListInstalledColormaps)(pScreen, pCmapIDs);
+
+ for (i = 0; i < n; i++) {
+ ColormapPtr pCmap;
+
+ pCmap = (ColormapPtr)LookupIDByType(pCmapIDs[i], RT_COLORMAP);
+ if (pCmap)
+ XInstallColormap(xnestDisplay, xnestColormap(pCmap));
+ }
+}
+
+void xnestDirectUninstallColormaps(pScreen)
+ ScreenPtr pScreen;
+{
+ int i, n;
+ Colormap pCmapIDs[MAXCMAPS];
+
+ if (!xnestDoDirectColormaps) return;
+
+ n = (*pScreen->ListInstalledColormaps)(pScreen, pCmapIDs);
+
+ for (i = 0; i < n; i++) {
+ ColormapPtr pCmap;
+
+ pCmap = (ColormapPtr)LookupIDByType(pCmapIDs[i], RT_COLORMAP);
+ if (pCmap)
+ XUninstallColormap(xnestDisplay, xnestColormap(pCmap));
+ }
+}
+
+void xnestInstallColormap(pCmap)
+ ColormapPtr pCmap;
+{
+ int index;
+ ColormapPtr pOldCmap;
+
+ index = pCmap->pScreen->myNum;
+ pOldCmap = InstalledMaps[index];
+
+ if(pCmap != pOldCmap)
+ {
+ xnestDirectUninstallColormaps(pCmap->pScreen);
+
+ /* Uninstall pInstalledMap. Notify all interested parties. */
+ if(pOldCmap != (ColormapPtr)None)
+ WalkTree(pCmap->pScreen, TellLostMap, (pointer)&pOldCmap->mid);
+
+ InstalledMaps[index] = pCmap;
+ WalkTree(pCmap->pScreen, TellGainedMap, (pointer)&pCmap->mid);
+
+ xnestSetInstalledColormapWindows(pCmap->pScreen);
+ xnestDirectInstallColormaps(pCmap->pScreen);
+ }
+}
+
+void xnestUninstallColormap(pCmap)
+ ColormapPtr pCmap;
+{
+ int index;
+ ColormapPtr pCurCmap;
+
+ index = pCmap->pScreen->myNum;
+ pCurCmap = InstalledMaps[index];
+
+ if(pCmap == pCurCmap)
+ {
+ if (pCmap->mid != pCmap->pScreen->defColormap)
+ {
+ pCurCmap = (ColormapPtr)LookupIDByType(pCmap->pScreen->defColormap,
+ RT_COLORMAP);
+ (*pCmap->pScreen->InstallColormap)(pCurCmap);
+ }
+ }
+}
+
+static Bool xnestInstalledDefaultColormap = False;
+
+int xnestListInstalledColormaps(pScreen, pCmapIDs)
+ ScreenPtr pScreen;
+ Colormap *pCmapIDs;
+{
+ if (xnestInstalledDefaultColormap) {
+ *pCmapIDs = InstalledMaps[pScreen->myNum]->mid;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+void xnestStoreColors(pCmap, nColors, pColors)
+ ColormapPtr pCmap;
+ int nColors;
+ xColorItem *pColors;
+{
+ if (pCmap->pVisual->class & DynamicClass)
+#ifdef _XSERVER64
+ {
+ int i;
+ XColor *pColors64 = (XColor *)xalloc(nColors * sizeof(XColor) );
+
+ for(i = 0; i < nColors; ++i)
+ {
+ pColors64[i].pixel = pColors[i].pixel;
+ pColors64[i].red = pColors[i].red;
+ pColors64[i].green = pColors[i].green;
+ pColors64[i].blue = pColors[i].blue;
+ pColors64[i].flags = pColors[i].flags;
+ }
+ XStoreColors(xnestDisplay, xnestColormap(pCmap), pColors64, nColors);
+ xfree(pColors64);
+ }
+#else
+ XStoreColors(xnestDisplay, xnestColormap(pCmap),
+ (XColor *)pColors, nColors);
+#endif
+}
+
+void xnestResolveColor(pRed, pGreen, pBlue, pVisual)
+ unsigned short *pRed;
+ unsigned short *pGreen;
+ unsigned short *pBlue;
+ VisualPtr pVisual;
+{
+ int shift;
+ unsigned int lim;
+
+ shift = 16 - pVisual->bitsPerRGBValue;
+ lim = (1 << pVisual->bitsPerRGBValue) - 1;
+
+ if ((pVisual->class == PseudoColor) || (pVisual->class == DirectColor))
+ {
+ /* rescale to rgb bits */
+ *pRed = ((*pRed >> shift) * 65535) / lim;
+ *pGreen = ((*pGreen >> shift) * 65535) / lim;
+ *pBlue = ((*pBlue >> shift) * 65535) / lim;
+ }
+ else if (pVisual->class == GrayScale)
+ {
+ /* rescale to gray then rgb bits */
+ *pRed = (30L * *pRed + 59L * *pGreen + 11L * *pBlue) / 100;
+ *pBlue = *pGreen = *pRed = ((*pRed >> shift) * 65535) / lim;
+ }
+ else if (pVisual->class == StaticGray)
+ {
+ unsigned int limg;
+
+ limg = pVisual->ColormapEntries - 1;
+ /* rescale to gray then [0..limg] then [0..65535] then rgb bits */
+ *pRed = (30L * *pRed + 59L * *pGreen + 11L * *pBlue) / 100;
+ *pRed = ((((*pRed * (limg + 1))) >> 16) * 65535) / limg;
+ *pBlue = *pGreen = *pRed = ((*pRed >> shift) * 65535) / lim;
+ }
+ else
+ {
+ unsigned limr, limg, limb;
+
+ limr = pVisual->redMask >> pVisual->offsetRed;
+ limg = pVisual->greenMask >> pVisual->offsetGreen;
+ limb = pVisual->blueMask >> pVisual->offsetBlue;
+ /* rescale to [0..limN] then [0..65535] then rgb bits */
+ *pRed = ((((((*pRed * (limr + 1)) >> 16) *
+ 65535) / limr) >> shift) * 65535) / lim;
+ *pGreen = ((((((*pGreen * (limg + 1)) >> 16) *
+ 65535) / limg) >> shift) * 65535) / lim;
+ *pBlue = ((((((*pBlue * (limb + 1)) >> 16) *
+ 65535) / limb) >> shift) * 65535) / lim;
+ }
+}
+
+Bool xnestCreateDefaultColormap(pScreen)
+ ScreenPtr pScreen;
+{
+ VisualPtr pVisual;
+ ColormapPtr pCmap;
+ unsigned short zero = 0, ones = 0xFFFF;
+ Pixel wp, bp;
+
+ for (pVisual = pScreen->visuals;
+ pVisual->vid != pScreen->rootVisual;
+ pVisual++);
+
+ if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &pCmap,
+ (pVisual->class & DynamicClass) ? AllocNone : AllocAll, 0)
+ != Success)
+ return False;
+
+ wp = pScreen->whitePixel;
+ bp = pScreen->blackPixel;
+ if ((AllocColor(pCmap, &ones, &ones, &ones, &wp, 0) !=
+ Success) ||
+ (AllocColor(pCmap, &zero, &zero, &zero, &bp, 0) !=
+ Success))
+ return FALSE;
+ pScreen->whitePixel = wp;
+ pScreen->blackPixel = bp;
+ (*pScreen->InstallColormap)(pCmap);
+
+ xnestInstalledDefaultColormap = True;
+
+ return True;
+}
diff --git a/xc/programs/Xserver/hw/xnest/Color.h b/xc/programs/Xserver/hw/xnest/Color.h
new file mode 100644
index 000000000..1d0d7172f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Color.h
@@ -0,0 +1,56 @@
+/* $XConsortium: Color.h,v 1.1 93/07/12 15:28:00 rws Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef XNESTCOLOR_H
+#define XNESTCOLOR_H
+
+#define DUMB_WINDOW_MANAGERS
+
+#define MAXCMAPS 1
+#define MINCMAPS 1
+
+typedef struct {
+ Colormap colormap;
+} xnestPrivColormap;
+
+typedef struct {
+ int numCmapIDs;
+ Colormap *cmapIDs;
+ int numWindows;
+ Window *windows;
+ int index;
+} xnestInstalledColormapWindows;
+
+#define xnestColormapPriv(pCmap) \
+ ((xnestPrivColormap *)((pCmap)->devPriv))
+
+#define xnestColormap(pCmap) (xnestColormapPriv(pCmap)->colormap)
+
+#define xnestPixel(pixel) (pixel)
+
+Bool xnestCreateColormap();
+void xnestDestroyColormap ();
+void xnestSetInstalledColormapWindows();
+void xnestSetScreenSaverColormapWindow();
+void xnestDirectInstallColormaps();
+void xnestDirectUninstallColormaps();
+void xnestInstallColormap();
+void xnestUninstallColormap();
+int xnestListInstalledColormaps();
+void xnestStoreColors();
+void xnestResolveColor();
+Bool xnestCreateDefaultColormap();
+
+#endif /* XNESTCOLOR_H */
diff --git a/xc/programs/Xserver/hw/xnest/Cursor.c b/xc/programs/Xserver/hw/xnest/Cursor.c
new file mode 100644
index 000000000..dd231df2f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Cursor.c
@@ -0,0 +1,214 @@
+/* $XConsortium: Cursor.c /main/5 1996/09/28 17:13:30 rws $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+#include "X.h"
+#include "Xproto.h"
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "cursor.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Screen.h"
+#include "Cursor.h"
+#include "Visual.h"
+#include "Keyboard.h"
+#include "Args.h"
+
+void xnestConstrainCursor(pScreen, pBox)
+ ScreenPtr pScreen;
+ BoxPtr pBox;
+{
+#ifdef _XSERVER64
+ Window64 wroot;
+#else
+ Window wroot;
+#endif
+
+ int wx, wy;
+ unsigned int wwidth, wheight;
+ unsigned int wborderwidth;
+ unsigned int wdepth;
+
+ XGetGeometry(xnestDisplay, xnestDefaultWindows[pScreen->myNum], &wroot,
+ &wx, &wy, &wwidth, &wheight, &wborderwidth, &wdepth);
+
+ if (pBox->x1 <= 0 && pBox->y1 <= 0 &&
+ pBox->x2 >= wwidth && pBox->y2 >= wheight)
+ XUngrabPointer(xnestDisplay, CurrentTime);
+ else {
+ XReparentWindow(xnestDisplay, xnestConfineWindow,
+ xnestDefaultWindows[pScreen->myNum],
+ pBox->x1, pBox->y1);
+ XResizeWindow(xnestDisplay, xnestConfineWindow,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+
+ XGrabPointer(xnestDisplay,
+ xnestDefaultWindows[pScreen->myNum],
+ True,
+ xnestEventMask & (~XNEST_KEYBOARD_EVENT_MASK|KeymapStateMask),
+ GrabModeAsync, GrabModeAsync,
+ xnestConfineWindow,
+ None, CurrentTime);
+ }
+}
+
+void xnestCursorLimits(pScreen, pCursor, pHotBox, pTopLeftBox)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+ BoxPtr pHotBox;
+ BoxPtr pTopLeftBox;
+{
+ *pTopLeftBox = *pHotBox;
+}
+
+Bool xnestDisplayCursor(pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ XDefineCursor(xnestDisplay,
+ xnestDefaultWindows[pScreen->myNum],
+ xnestCursor(pCursor, pScreen));
+ return True;
+}
+
+Bool xnestRealizeCursor(pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ XImage *ximage;
+ Pixmap source, mask;
+ XColor fg_color, bg_color;
+ unsigned long valuemask;
+ XGCValues values;
+
+ valuemask = GCFunction |
+ GCPlaneMask |
+ GCForeground |
+ GCBackground |
+ GCClipMask;
+
+ values.function = GXcopy;
+ values.plane_mask = AllPlanes;
+ values.foreground = 1L;
+ values.background = 0L;
+ values.clip_mask = None;
+
+ XChangeGC(xnestDisplay, xnestBitmapGC, valuemask, &values);
+
+ source = XCreatePixmap(xnestDisplay,
+ xnestDefaultWindows[pScreen->myNum],
+ pCursor->bits->width,
+ pCursor->bits->height,
+ 1);
+
+ mask = XCreatePixmap(xnestDisplay,
+ xnestDefaultWindows[pScreen->myNum],
+ pCursor->bits->width,
+ pCursor->bits->height,
+ 1);
+
+ ximage = XCreateImage(xnestDisplay,
+ xnestDefaultVisual(pScreen),
+ 1, XYBitmap, 0,
+ (char *)pCursor->bits->source,
+ pCursor->bits->width,
+ pCursor->bits->height,
+ BitmapPad(xnestDisplay), 0);
+
+ XPutImage(xnestDisplay, source, xnestBitmapGC, ximage,
+ 0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
+
+ XFree(ximage);
+
+ ximage = XCreateImage(xnestDisplay,
+ xnestDefaultVisual(pScreen),
+ 1, XYBitmap, 0,
+ (char *)pCursor->bits->mask,
+ pCursor->bits->width,
+ pCursor->bits->height,
+ BitmapPad(xnestDisplay), 0);
+
+ XPutImage(xnestDisplay, mask, xnestBitmapGC, ximage,
+ 0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
+
+ XFree(ximage);
+
+ fg_color.red = pCursor->foreRed;
+ fg_color.green = pCursor->foreGreen;
+ fg_color.blue = pCursor->foreBlue;
+
+ bg_color.red = pCursor->backRed;
+ bg_color.green = pCursor->backGreen;
+ bg_color.blue = pCursor->backBlue;
+
+ pCursor->devPriv[pScreen->myNum] = (pointer)xalloc(sizeof(xnestPrivCursor));
+ xnestCursorPriv(pCursor, pScreen)->cursor =
+ XCreatePixmapCursor(xnestDisplay, source, mask, &fg_color, &bg_color,
+ pCursor->bits->xhot, pCursor->bits->yhot);
+
+ XFreePixmap(xnestDisplay, source);
+ XFreePixmap(xnestDisplay, mask);
+
+ return True;
+}
+
+Bool xnestUnrealizeCursor(pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ XFreeCursor(xnestDisplay, xnestCursor(pCursor, pScreen));
+ xfree(xnestCursorPriv(pCursor, pScreen));
+ return True;
+}
+
+void xnestRecolorCursor(pScreen, pCursor, displayed)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+ Bool displayed;
+{
+ XColor fg_color, bg_color;
+
+ fg_color.red = pCursor->foreRed;
+ fg_color.green = pCursor->foreGreen;
+ fg_color.blue = pCursor->foreBlue;
+
+ bg_color.red = pCursor->backRed;
+ bg_color.green = pCursor->backGreen;
+ bg_color.blue = pCursor->backBlue;
+
+ XRecolorCursor(xnestDisplay,
+ xnestCursor(pCursor, pScreen),
+ &fg_color, &bg_color);
+}
+
+Bool xnestSetCursorPosition(pScreen, x, y, generateEvent)
+ ScreenPtr pScreen;
+ int x, y;
+ Bool generateEvent;
+{
+ int i;
+
+ for (i = 0; i < xnestNumScreens; i++)
+ XWarpPointer(xnestDisplay, xnestDefaultWindows[i],
+ xnestDefaultWindows[pScreen->myNum],
+ 0, 0, 0, 0, x, y);
+
+ return True;
+}
diff --git a/xc/programs/Xserver/hw/xnest/Cursor.h b/xc/programs/Xserver/hw/xnest/Cursor.h
new file mode 100644
index 000000000..975200e04
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Cursor.h
@@ -0,0 +1,37 @@
+/* $XConsortium: Cursor.h,v 1.1 93/07/12 15:28:04 rws Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef XNESTCURSOR_H
+#define XNESTCURSOR_H
+
+typedef struct {
+ Cursor cursor;
+} xnestPrivCursor;
+
+#define xnestCursorPriv(pCursor, pScreen) \
+ ((xnestPrivCursor *)((pCursor)->devPriv[pScreen->myNum]))
+
+#define xnestCursor(pCursor, pScreen) \
+ (xnestCursorPriv(pCursor, pScreen)->cursor)
+
+void xnestConstrainCursor();
+void xnestCursorLimits();
+Bool xnestDisplayCursor();
+Bool xnestRealizeCursor();
+Bool xnestUnrealizeCursor();
+void xnestRecolorCursor();
+Bool xnestSetCursorPosition();
+
+#endif /* XNESTCURSOR_H */
diff --git a/xc/programs/Xserver/hw/xnest/Display.c b/xc/programs/Xserver/hw/xnest/Display.c
new file mode 100644
index 000000000..d0a2180b4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Display.c
@@ -0,0 +1,202 @@
+/* $XConsortium: Display.c /main/4 1996/08/20 11:31:58 kaleb $ */
+/* $XFree86: xc/programs/Xserver/hw/xnest/Display.c,v 3.1 1996/12/23 07:09:11 dawes Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+
+#include "X.h"
+#include "Xproto.h"
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Init.h"
+#include "Args.h"
+
+#include "icon"
+#include "screensaver"
+
+Display *xnestDisplay = NULL;
+XVisualInfo *xnestVisuals;
+int xnestNumVisuals;
+int xnestDefaultVisualIndex;
+Colormap *xnestDefaultColormaps;
+int xnestNumDefaultColormaps;
+int *xnestDepths;
+int xnestNumDepths;
+XPixmapFormatValues *xnestPixmapFormats;
+int xnestNumPixmapFormats;
+Pixel xnestBlackPixel;
+Pixel xnestWhitePixel;
+Drawable xnestDefaultDrawables[MAXDEPTH + 1];
+Pixmap xnestIconBitmap;
+Pixmap xnestScreenSaverPixmap;
+XlibGC xnestBitmapGC;
+Window xnestConfineWindow;
+unsigned long xnestEventMask;
+
+void xnestOpenDisplay(argc, argv)
+ int argc;
+ char *argv[];
+{
+ XVisualInfo vi;
+ long mask;
+ int i, j;
+ extern Window xnestParentWindow;
+
+ if (!xnestDoFullGeneration) return;
+
+ xnestCloseDisplay();
+
+ xnestDisplay = XOpenDisplay(xnestDisplayName);
+ if (xnestDisplay == NULL)
+ FatalError("Unable to open display \"%s\".\n",
+ XDisplayName(xnestDisplayName));
+
+ if (xnestSynchronize)
+ XSynchronize(xnestDisplay, True);
+
+ mask = VisualScreenMask;
+ vi.screen = DefaultScreen(xnestDisplay);
+ xnestVisuals = XGetVisualInfo(xnestDisplay, mask, &vi, &xnestNumVisuals);
+ if (xnestNumVisuals == 0 || xnestVisuals == NULL)
+ FatalError("Unable to find any visuals.\n");
+
+ if (xnestUserDefaultClass || xnestUserDefaultDepth) {
+ xnestDefaultVisualIndex = UNDEFINED;
+ for (i = 0; i < xnestNumVisuals; i++)
+ if ((!xnestUserDefaultClass ||
+ xnestVisuals[i].class == xnestDefaultClass)
+ &&
+ (!xnestUserDefaultDepth ||
+ xnestVisuals[i].depth == xnestDefaultDepth)) {
+ xnestDefaultVisualIndex = i;
+ break;
+ }
+ if (xnestDefaultVisualIndex == UNDEFINED)
+ FatalError("Unable to find desired default visual.\n");
+ }
+ else {
+ vi.visualid = XVisualIDFromVisual(DefaultVisual(xnestDisplay,
+ DefaultScreen(xnestDisplay)));
+ xnestDefaultVisualIndex = 0;
+ for (i = 0; i < xnestNumVisuals; i++)
+ if (vi.visualid == xnestVisuals[i].visualid)
+ xnestDefaultVisualIndex = i;
+ }
+
+ xnestNumDefaultColormaps = xnestNumVisuals;
+ xnestDefaultColormaps = (Colormap *)xalloc(xnestNumDefaultColormaps *
+ sizeof(Colormap));
+ for (i = 0; i < xnestNumDefaultColormaps; i++)
+ xnestDefaultColormaps[i] = XCreateColormap(xnestDisplay,
+ DefaultRootWindow(xnestDisplay),
+ xnestVisuals[i].visual,
+ AllocNone);
+
+ xnestDepths = XListDepths(xnestDisplay, DefaultScreen(xnestDisplay),
+ &xnestNumDepths);
+
+ xnestPixmapFormats = XListPixmapFormats(xnestDisplay,
+ &xnestNumPixmapFormats);
+
+ xnestBlackPixel = BlackPixel(xnestDisplay, DefaultScreen(xnestDisplay));
+ xnestWhitePixel = WhitePixel(xnestDisplay, DefaultScreen(xnestDisplay));
+
+ if (xnestParentWindow != (Window) 0)
+ xnestEventMask = StructureNotifyMask;
+ else
+ xnestEventMask = 0L;
+
+ for (i = 0; i <= MAXDEPTH; i++)
+ xnestDefaultDrawables[i] = None;
+
+ for (i = 0; i < xnestNumPixmapFormats; i++)
+ for (j = 0; j < xnestNumDepths; j++)
+ if (xnestPixmapFormats[i].depth == 1 ||
+ xnestPixmapFormats[i].depth == xnestDepths[j]) {
+ xnestDefaultDrawables[xnestPixmapFormats[i].depth] =
+ XCreatePixmap(xnestDisplay, DefaultRootWindow(xnestDisplay),
+ 1, 1, xnestPixmapFormats[i].depth);
+ }
+
+ xnestBitmapGC = XCreateGC(xnestDisplay, xnestDefaultDrawables[1], 0L, NULL);
+
+ xnestConfineWindow = XCreateWindow(xnestDisplay,
+ DefaultRootWindow(xnestDisplay),
+ 0, 0, 1, 1, 0, 0,
+ InputOnly,
+ CopyFromParent,
+ 0L, NULL);
+
+ if (!(xnestUserGeometry & XValue))
+ xnestX = 0;
+
+ if (!(xnestUserGeometry & YValue))
+ xnestY = 0;
+
+ if (xnestParentWindow == 0) {
+ if (!(xnestUserGeometry & WidthValue))
+ xnestWidth = 3 * DisplayWidth(xnestDisplay,
+ DefaultScreen(xnestDisplay)) / 4;
+
+ if (!(xnestUserGeometry & HeightValue))
+ xnestHeight = 3 * DisplayHeight(xnestDisplay,
+ DefaultScreen(xnestDisplay)) / 4;
+ }
+
+ if (!xnestUserBorderWidth)
+ xnestBorderWidth = 1;
+
+ xnestIconBitmap =
+ XCreateBitmapFromData(xnestDisplay,
+ DefaultRootWindow(xnestDisplay),
+ (char *)icon_bits,
+ icon_width,
+ icon_height);
+
+ xnestScreenSaverPixmap =
+ XCreatePixmapFromBitmapData(xnestDisplay,
+ DefaultRootWindow(xnestDisplay),
+ (char *)screensaver_bits,
+ screensaver_width,
+ screensaver_height,
+ xnestWhitePixel,
+ xnestBlackPixel,
+ DefaultDepth(xnestDisplay,
+ DefaultScreen(xnestDisplay)));
+}
+
+void xnestCloseDisplay()
+{
+ int i;
+
+ if (!xnestDoFullGeneration || !xnestDisplay) return;
+
+ /*
+ If xnestDoFullGeneration all x resources will be destroyed upon closing
+ the display connection. There is no need to generate extra protocol.
+ */
+
+ xfree(xnestDefaultColormaps);
+ XFree(xnestVisuals);
+ XFree(xnestDepths);
+ XFree(xnestPixmapFormats);
+ XCloseDisplay(xnestDisplay);
+}
diff --git a/xc/programs/Xserver/hw/xnest/Display.h b/xc/programs/Xserver/hw/xnest/Display.h
new file mode 100644
index 000000000..c0d554fe4
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Display.h
@@ -0,0 +1,47 @@
+/* $XConsortium: Display.h,v 1.2 94/02/06 17:51:43 rws Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+/* $XFree86: xc/programs/Xserver/hw/xnest/Display.h,v 1.3 1998/12/20 22:18:57 dawes Exp $ */
+
+#ifndef XNESTCOMMON_H
+#define XNESTCOMMON_H
+
+#define UNDEFINED -1
+
+#define MAXDEPTH 32
+#define MAXVISUALSPERDEPTH 32
+
+extern Display *xnestDisplay;
+extern XVisualInfo *xnestVisuals;
+extern int xnestNumVisuals;
+extern int xnestDefaultVisualIndex;
+extern Colormap *xnestDefaultColormaps;
+extern int xnestNumDefaultClormaps;
+extern int *xnestDepths;
+extern int xnestNumDepths;
+extern XPixmapFormatValues *xnestPixmapFormats;
+extern int xnestNumPixmapFormats;
+extern Pixel xnestBlackPixel;
+extern Pixel xnestWhitePixel;
+extern Drawable xnestDefaultDrawables[MAXDEPTH + 1];
+extern Pixmap xnestIconBitmap;
+extern Pixmap xnestScreenSaverPixmap;
+extern XlibGC xnestBitmapGC;
+extern Window xnestConfineWindow;
+extern unsigned long xnestEventMask;
+
+void xnestOpenDisplay();
+void xnestCloseDisplay();
+
+#endif /* XNESTCOMMON_H */
diff --git a/xc/programs/Xserver/hw/xnest/Drawable.h b/xc/programs/Xserver/hw/xnest/Drawable.h
new file mode 100644
index 000000000..a990b0ae0
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Drawable.h
@@ -0,0 +1,27 @@
+/* $XConsortium: Drawable.h /main/2 1996/12/02 10:20:59 lehors $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef XNESTDRAWABLE_H
+#define XNESTDRAWABLE_H
+
+#include "XNWindow.h"
+#include "Pixmap.h"
+
+#define xnestDrawable(pDrawable) \
+ ((pDrawable)->type == DRAWABLE_WINDOW ? \
+ xnestWindow((WindowPtr)pDrawable) : \
+ xnestPixmap((PixmapPtr)pDrawable))
+
+#endif /* XNESTDRAWABLE_H */
diff --git a/xc/programs/Xserver/hw/xnest/Events.c b/xc/programs/Xserver/hw/xnest/Events.c
new file mode 100644
index 000000000..c94d61794
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Events.c
@@ -0,0 +1,189 @@
+/* $XConsortium: Events.c /main/6 1996/12/02 10:21:07 lehors $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+#include "X.h"
+#define NEED_EVENTS
+#include "Xproto.h"
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Screen.h"
+#include "XNWindow.h"
+#include "Events.h"
+
+CARD32 lastEventTime = 0;
+
+void ProcessInputEvents()
+{
+ mieqProcessInputEvents();
+}
+
+int TimeSinceLastInputEvent()
+{
+ if (lastEventTime == 0)
+ lastEventTime = GetTimeInMillis();
+ return GetTimeInMillis() - lastEventTime;
+}
+
+void SetTimeSinceLastInputEvent()
+{
+ lastEventTime = GetTimeInMillis();
+}
+
+static Bool xnestExposurePredicate(display, event, args)
+ Display *display;
+ XEvent *event;
+ char *args;
+{
+ return (event->type == Expose || event->type == ProcessedExpose);
+}
+
+static Bool xnestNotExposurePredicate(display, event, args)
+ Display *display;
+ XEvent *event;
+ char *args;
+{
+ return !xnestExposurePredicate(display, event, args);
+}
+
+void xnestCollectExposures()
+{
+ XEvent X;
+ WindowPtr pWin;
+ RegionRec Rgn;
+ BoxRec Box;
+
+ while (XCheckIfEvent(xnestDisplay, &X, xnestExposurePredicate, NULL)) {
+ pWin = xnestWindowPtr(X.xexpose.window);
+
+ if (pWin) {
+ Box.x1 = pWin->drawable.x + wBorderWidth(pWin) + X.xexpose.x;
+ Box.y1 = pWin->drawable.y + wBorderWidth(pWin) + X.xexpose.y;
+ Box.x2 = Box.x1 + X.xexpose.width;
+ Box.y2 = Box.y1 + X.xexpose.height;
+
+ REGION_INIT(pWin->drawable.pScreen, &Rgn, &Box, 1);
+
+ miWindowExposures(pWin, &Rgn, NullRegion);
+ }
+ }
+}
+
+void xnestCollectEvents()
+{
+ XEvent X;
+ xEvent x;
+ ScreenPtr pScreen;
+ extern Window xnestParentWindow;
+
+ while (XCheckIfEvent(xnestDisplay, &X, xnestNotExposurePredicate, NULL)) {
+ switch (X.type) {
+ case KeyPress:
+ x.u.u.type = KeyPress;
+ x.u.u.detail = X.xkey.keycode;
+ x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis();
+ mieqEnqueue(&x);
+ break;
+
+ case KeyRelease:
+ x.u.u.type = KeyRelease;
+ x.u.u.detail = X.xkey.keycode;
+ x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis();
+ mieqEnqueue(&x);
+ break;
+
+ case ButtonPress:
+ x.u.u.type = ButtonPress;
+ x.u.u.detail = X.xbutton.button;
+ x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis();
+ mieqEnqueue(&x);
+ break;
+
+ case ButtonRelease:
+ x.u.u.type = ButtonRelease;
+ x.u.u.detail = X.xbutton.button;
+ x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis();
+ mieqEnqueue(&x);
+ break;
+
+ case MotionNotify:
+ x.u.u.type = MotionNotify;
+ x.u.keyButtonPointer.rootX = X.xmotion.x;
+ x.u.keyButtonPointer.rootY = X.xmotion.y;
+ x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis();
+ mieqEnqueue(&x);
+ break;
+
+ case FocusIn:
+ if (X.xfocus.detail != NotifyInferior) {
+ pScreen = xnestScreen(X.xfocus.window);
+ if (pScreen)
+ xnestDirectInstallColormaps(pScreen);
+ }
+ break;
+
+ case FocusOut:
+ if (X.xfocus.detail != NotifyInferior) {
+ pScreen = xnestScreen(X.xfocus.window);
+ if (pScreen)
+ xnestDirectUninstallColormaps(pScreen);
+ }
+ break;
+
+ case KeymapNotify:
+ break;
+
+ case EnterNotify:
+ if (X.xcrossing.detail != NotifyInferior) {
+ pScreen = xnestScreen(X.xcrossing.window);
+ if (pScreen) {
+ NewCurrentScreen(pScreen, X.xcrossing.x, X.xcrossing.y);
+ x.u.u.type = MotionNotify;
+ x.u.keyButtonPointer.rootX = X.xcrossing.x;
+ x.u.keyButtonPointer.rootY = X.xcrossing.y;
+ x.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis();
+ mieqEnqueue(&x);
+ xnestDirectInstallColormaps(pScreen);
+ }
+ }
+ break;
+
+ case LeaveNotify:
+ if (X.xcrossing.detail != NotifyInferior) {
+ pScreen = xnestScreen(X.xcrossing.window);
+ if (pScreen) {
+ xnestDirectUninstallColormaps(pScreen);
+ }
+ }
+ break;
+
+ case DestroyNotify:
+ if (xnestParentWindow != (Window) 0 &&
+ X.xdestroywindow.window == xnestParentWindow)
+ exit (0);
+ break;
+
+ default:
+ ErrorF("xnest warning: unhandled event\n");
+ break;
+ }
+ }
+}
diff --git a/xc/programs/Xserver/hw/xnest/Events.h b/xc/programs/Xserver/hw/xnest/Events.h
new file mode 100644
index 000000000..c5848f61d
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Events.h
@@ -0,0 +1,28 @@
+/* $XConsortium: Events.h,v 1.2 93/09/23 18:57:02 rws Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef XNESTEVENTS_H
+#define XNESTEVENTS_H
+
+#include <X11/Xmd.h>
+
+#define ProcessedExpose (LASTEvent + 1)
+
+extern CARD32 lastEventTime;
+
+void xnestCollectExposures();
+void xnestCollectEvents();
+
+#endif /* XNESTEVENTS_H */
diff --git a/xc/programs/Xserver/hw/xnest/Font.c b/xc/programs/Xserver/hw/xnest/Font.c
new file mode 100644
index 000000000..47030ee46
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Font.c
@@ -0,0 +1,88 @@
+/* $XConsortium: Font.c /main/4 1996/12/02 10:21:13 lehors $ */
+/* $XFree86: xc/programs/Xserver/hw/xnest/Font.c,v 3.4 1996/12/27 07:07:48 dawes Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+#include "X.h"
+#include "Xatom.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "miscstruct.h"
+#include "font.h"
+#include "fontstruct.h"
+#include "scrnintstr.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "XNFont.h"
+
+int xnestFontPrivateIndex;
+
+Bool xnestRealizeFont(pScreen, pFont)
+ ScreenPtr pScreen;
+ FontPtr pFont;
+{
+ pointer priv;
+ Atom name_atom, value_atom;
+ int nprops;
+ FontPropPtr props;
+ int i;
+ char *name;
+
+ FontSetPrivate(pFont, xnestFontPrivateIndex, NULL);
+
+ if (requestingClient && XpClientIsPrintClient(requestingClient, NULL))
+ return True;
+
+ name_atom = MakeAtom("FONT", 4, True);
+ value_atom = 0L;
+
+ nprops = pFont->info.nprops;
+ props = pFont->info.props;
+
+ for (i = 0; i < nprops; i++)
+ if (props[i].name == name_atom) {
+ value_atom = props[i].value;
+ break;
+ }
+
+ if (!value_atom) return False;
+
+ name = (char *)NameForAtom(value_atom);
+
+ if (!name) return False;
+
+ priv = (pointer)xalloc(sizeof(xnestPrivFont));
+ FontSetPrivate(pFont, xnestFontPrivateIndex, priv);
+
+ xnestFontPriv(pFont)->font_struct = XLoadQueryFont(xnestDisplay, name);
+
+ if (!xnestFontStruct(pFont)) return False;
+
+ return True;
+}
+
+
+Bool xnestUnrealizeFont(pScreen, pFont)
+ ScreenPtr pScreen;
+ FontPtr pFont;
+{
+ if (xnestFontPriv(pFont)) {
+ if (xnestFontStruct(pFont))
+ XFreeFont(xnestDisplay, xnestFontStruct(pFont));
+ xfree(xnestFontPriv(pFont));
+ FontSetPrivate(pFont, xnestFontPrivateIndex, NULL);
+ }
+ return True;
+}
diff --git a/xc/programs/Xserver/hw/xnest/GC.c b/xc/programs/Xserver/hw/xnest/GC.c
new file mode 100644
index 000000000..4916bce9c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/GC.c
@@ -0,0 +1,346 @@
+/* $XConsortium: GC.c /main/8 1996/12/02 10:21:19 lehors $ */
+/* $XFree86: xc/programs/Xserver/hw/xnest/GC.c,v 3.3 1996/12/23 07:09:13 dawes Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+#include "X.h"
+#include "Xproto.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "fontstruct.h"
+#include "mistruct.h"
+#include "region.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "XNGC.h"
+#include "GCOps.h"
+#include "Drawable.h"
+#include "XNFont.h"
+#include "Color.h"
+
+int xnestGCPrivateIndex;
+
+static GCFuncs xnestFuncs = {
+ xnestValidateGC,
+ xnestChangeGC,
+ xnestCopyGC,
+ xnestDestroyGC,
+ xnestChangeClip,
+ xnestDestroyClip,
+ xnestCopyClip,
+};
+
+static GCOps xnestOps = {
+ xnestFillSpans,
+ xnestSetSpans,
+ xnestPutImage,
+ xnestCopyArea,
+ xnestCopyPlane,
+ xnestPolyPoint,
+ xnestPolylines,
+ xnestPolySegment,
+ xnestPolyRectangle,
+ xnestPolyArc,
+ xnestFillPolygon,
+ xnestPolyFillRect,
+ xnestPolyFillArc,
+ xnestPolyText8,
+ xnestPolyText16,
+ xnestImageText8,
+ xnestImageText16,
+ xnestImageGlyphBlt,
+ xnestPolyGlyphBlt,
+ xnestPushPixels
+};
+
+Bool xnestCreateGC(pGC)
+ GCPtr pGC;
+{
+ pGC->clientClipType = CT_NONE;
+ pGC->clientClip = NULL;
+
+ pGC->funcs = &xnestFuncs;
+ pGC->ops = &xnestOps;
+
+ pGC->miTranslate = 1;
+
+ xnestGCPriv(pGC)->gc = XCreateGC(xnestDisplay,
+ xnestDefaultDrawables[pGC->depth],
+ 0L, NULL);
+ xnestGCPriv(pGC)->nClipRects = 0;
+
+ return True;
+}
+
+void xnestValidateGC(pGC, changes, pDrawable)
+ GCPtr pGC;
+ unsigned long changes;
+ DrawablePtr pDrawable;
+{
+ pGC->lastWinOrg.x = pDrawable->x;
+ pGC->lastWinOrg.y = pDrawable->y;
+}
+
+void xnestChangeGC(pGC, mask)
+ GC *pGC;
+ unsigned long mask;
+{
+ XGCValues values;
+
+ if (mask & GCFunction)
+ values.function = pGC->alu;
+
+ if (mask & GCPlaneMask)
+ values.plane_mask = pGC->planemask;
+
+ if (mask & GCForeground)
+ values.foreground = xnestPixel(pGC->fgPixel);
+
+ if (mask & GCBackground)
+ values.background = xnestPixel(pGC->bgPixel);
+
+ if (mask & GCLineWidth)
+ values.line_width = pGC->lineWidth;
+
+ if (mask & GCLineStyle)
+ values.line_style = pGC->lineStyle;
+
+ if (mask & GCCapStyle)
+ values.cap_style = pGC->capStyle;
+
+ if (mask & GCJoinStyle)
+ values.join_style = pGC->joinStyle;
+
+ if (mask & GCFillStyle)
+ values.fill_style = pGC->fillStyle;
+
+ if (mask & GCFillRule)
+ values.fill_rule = pGC->fillRule;
+
+ if (mask & GCTile)
+ if (pGC->tileIsPixel)
+ mask &= ~GCTile;
+ else
+ values.tile = xnestPixmap(pGC->tile.pixmap);
+
+ if (mask & GCStipple)
+ values.stipple = xnestPixmap(pGC->stipple);
+
+ if (mask & GCTileStipXOrigin)
+ values.ts_x_origin = pGC->patOrg.x;
+
+ if (mask & GCTileStipYOrigin)
+ values.ts_y_origin = pGC->patOrg.y;
+
+ if (mask & GCFont)
+ values.font = xnestFont(pGC->font);
+
+ if (mask & GCSubwindowMode)
+ values.subwindow_mode = pGC->subWindowMode;
+
+ if (mask & GCGraphicsExposures)
+ values.graphics_exposures = pGC->graphicsExposures;
+
+ if (mask & GCClipXOrigin)
+ values.clip_x_origin = pGC->clipOrg.x;
+
+ if (mask & GCClipYOrigin)
+ values.clip_y_origin = pGC->clipOrg.y;
+
+ if (mask & GCClipMask) /* this is handled in change clip */
+ mask &= ~GCClipMask;
+
+ if (mask & GCDashOffset)
+ values.dash_offset = pGC->dashOffset;
+
+ if (mask & GCDashList) {
+ mask &= ~GCDashList;
+ XSetDashes(xnestDisplay, xnestGC(pGC),
+ pGC->dashOffset, (char *)pGC->dash, pGC->numInDashList);
+ }
+
+ if (mask & GCArcMode)
+ values.arc_mode = pGC->arcMode;
+
+ if (mask)
+ XChangeGC(xnestDisplay, xnestGC(pGC), mask, &values);
+}
+
+void xnestCopyGC(pGCSrc, mask, pGCDst)
+ GCPtr pGCSrc;
+ unsigned long mask;
+ GCPtr pGCDst;
+{
+ XCopyGC(xnestDisplay, xnestGC(pGCSrc), mask, xnestGC(pGCDst));
+}
+
+void xnestDestroyGC(pGC)
+ GC *pGC;
+{
+ XFreeGC(xnestDisplay, xnestGC(pGC));
+}
+
+void xnestChangeClip(pGC, type, pValue, nRects)
+ GCPtr pGC;
+ int type;
+ pointer pValue;
+ int nRects;
+{
+ int i, size;
+ BoxPtr pBox;
+ XRectangle *pRects;
+
+ xnestDestroyClipHelper(pGC);
+
+ switch(type)
+ {
+ case CT_NONE:
+ XSetClipMask(xnestDisplay, xnestGC(pGC), None);
+ break;
+
+ case CT_REGION:
+ nRects = REGION_NUM_RECTS((RegionPtr)pValue);
+ size = nRects * sizeof(*pRects);
+ pRects = (XRectangle *) xalloc(size);
+ pBox = REGION_RECTS((RegionPtr)pValue);
+ for (i = nRects; i-- > 0; ) {
+ pRects[i].x = pBox[i].x1;
+ pRects[i].y = pBox[i].y1;
+ pRects[i].width = pBox[i].x2 - pBox[i].x1;
+ pRects[i].height = pBox[i].y2 - pBox[i].y1;
+ }
+ XSetClipRectangles(xnestDisplay, xnestGC(pGC), 0, 0,
+ pRects, nRects, Unsorted);
+ xfree((char *) pRects);
+ break;
+
+ case CT_PIXMAP:
+ XSetClipMask(xnestDisplay, xnestGC(pGC),
+ xnestPixmap((PixmapPtr)pValue));
+ /*
+ * Need to change into region, so subsequent uses are with
+ * current pixmap contents.
+ */
+ pGC->clientClip = (pointer) (*pGC->pScreen->BitmapToRegion)((PixmapPtr)pValue);
+ (*pGC->pScreen->DestroyPixmap)((PixmapPtr)pValue);
+ pValue = pGC->clientClip;
+ type = CT_REGION;
+ break;
+
+ case CT_UNSORTED:
+ XSetClipRectangles(xnestDisplay, xnestGC(pGC),
+ pGC->clipOrg.x, pGC->clipOrg.y,
+ (XRectangle *)pValue, nRects, Unsorted);
+ break;
+
+ case CT_YSORTED:
+ XSetClipRectangles(xnestDisplay, xnestGC(pGC),
+ pGC->clipOrg.x, pGC->clipOrg.y,
+ (XRectangle *)pValue, nRects, YSorted);
+ break;
+
+ case CT_YXSORTED:
+ XSetClipRectangles(xnestDisplay, xnestGC(pGC),
+ pGC->clipOrg.x, pGC->clipOrg.y,
+ (XRectangle *)pValue, nRects, YXSorted);
+ break;
+
+ case CT_YXBANDED:
+ XSetClipRectangles(xnestDisplay, xnestGC(pGC),
+ pGC->clipOrg.x, pGC->clipOrg.y,
+ (XRectangle *)pValue, nRects, YXBanded);
+ break;
+ }
+
+ switch(type)
+ {
+ default:
+ break;
+
+ case CT_UNSORTED:
+ case CT_YSORTED:
+ case CT_YXSORTED:
+ case CT_YXBANDED:
+
+ /*
+ * other parts of server can only deal with CT_NONE,
+ * CT_PIXMAP and CT_REGION client clips.
+ */
+ pGC->clientClip = (pointer) (*pGC->pScreen->RectsToRegion)(nRects,
+ (xRectangle *)pValue,
+ type);
+ xfree(pValue);
+ pValue = pGC->clientClip;
+ type = CT_REGION;
+
+ break;
+ }
+
+ pGC->clientClipType = type;
+ pGC->clientClip = pValue;
+ xnestGCPriv(pGC)->nClipRects = nRects;
+}
+
+void xnestDestroyClip(pGC)
+ GCPtr pGC;
+{
+ xnestDestroyClipHelper(pGC);
+
+ XSetClipMask(xnestDisplay, xnestGC(pGC), None);
+
+ pGC->clientClipType = CT_NONE;
+ pGC->clientClip = NULL;
+ xnestGCPriv(pGC)->nClipRects = 0;
+}
+
+void xnestDestroyClipHelper(pGC)
+ GCPtr pGC;
+{
+ switch (pGC->clientClipType)
+ {
+ default:
+ case CT_NONE:
+ break;
+
+ case CT_REGION:
+ REGION_DESTROY(pGC->pScreen, pGC->clientClip);
+ break;
+ }
+}
+
+void xnestCopyClip(pGCDst, pGCSrc)
+ GCPtr pGCSrc;
+ GCPtr pGCDst;
+{
+ RegionPtr pRgn;
+ int nRects, size;
+ xRectangle *pRects;
+
+ switch (pGCSrc->clientClipType)
+ {
+ default:
+ case CT_NONE:
+ xnestDestroyClip(pGCDst);
+ break;
+
+ case CT_REGION:
+ pRgn = REGION_CREATE(pGCDst->pScreen, NULL, 1);
+ REGION_COPY(pGCDst->pScreen, pRgn, pGCSrc->clientClip);
+ xnestChangeClip(pGCDst, CT_REGION, pRgn, 0);
+ break;
+ }
+}
diff --git a/xc/programs/Xserver/hw/xnest/GCOps.c b/xc/programs/Xserver/hw/xnest/GCOps.c
new file mode 100644
index 000000000..977329608
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/GCOps.c
@@ -0,0 +1,388 @@
+/* $XConsortium: GCOps.c /main/10 1996/12/02 10:21:24 lehors $ */
+/* $XFree86: xc/programs/Xserver/hw/xnest/GCOps.c,v 3.3 1996/12/23 07:09:14 dawes Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+#include "X.h"
+#include "Xproto.h"
+#include "miscstruct.h"
+#include "fontstruct.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "region.h"
+#include "servermd.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Screen.h"
+#include "XNGC.h"
+#include "XNFont.h"
+#include "GCOps.h"
+#include "Drawable.h"
+#include "Visual.h"
+
+void xnestFillSpans(pDrawable, pGC, nSpans, pPoints, pWidths, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nSpans;
+ xPoint *pPoints;
+ int *pWidths;
+ int fSorted;
+{
+ ErrorF("xnest warning: function xnestFillSpans not implemented\n");
+}
+
+void xnestSetSpans(pDrawable, pGC, pSrc, pPoints, pWidths, nSpans, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ unsigned char * pSrc;
+ xPoint *pPoints;
+ int *pWidths;
+ int nSpans;
+ int fSorted;
+{
+ ErrorF("xnest warning: function xnestSetSpans not implemented\n");
+}
+
+void xnestGetSpans(pDrawable, maxWidth, pPoints, pWidths, nSpans, pBuffer)
+ DrawablePtr pDrawable;
+ int maxWidth;
+ xPoint *pPoints;
+ int *pWidths;
+ int nSpans;
+ int *pBuffer;
+{
+ ErrorF("xnest warning: function xnestGetSpans not implemented\n");
+}
+
+void xnestQueryBestSize(class, pWidth, pHeight, pScreen)
+ int class;
+ short *pWidth;
+ short *pHeight;
+ ScreenPtr pScreen;
+{
+ unsigned int width, height;
+
+ width = *pWidth;
+ height = *pHeight;
+
+ XQueryBestSize(xnestDisplay, class,
+ xnestDefaultWindows[pScreen->myNum],
+ width, height, &width, &height);
+
+ *pWidth = width;
+ *pHeight = height;
+}
+
+void xnestPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, pImage)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int depth, x, y, w, h;
+ int leftPad;
+ unsigned int format;
+ unsigned char *pImage;
+{
+ XImage *ximage;
+
+ ximage = XCreateImage(xnestDisplay, xnestDefaultVisual(pDrawable->pScreen),
+ depth, format, leftPad, (char *)pImage,
+ w, h, BitmapPad(xnestDisplay),
+ (format == ZPixmap) ?
+ PixmapBytePad(w, depth) : BitmapBytePad(w+leftPad));
+
+ if (ximage) {
+ XPutImage(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
+ ximage, 0, 0, x, y, w, h);
+ XFree(ximage);
+ }
+}
+
+void xnestGetImage(pDrawable, x, y, w, h, format, planeMask, pImage)
+ DrawablePtr pDrawable;
+ int x, y, w, h;
+ unsigned int format;
+ unsigned long planeMask;
+ unsigned char *pImage;
+{
+ XImage *ximage;
+ int length;
+
+ ximage = XGetImage(xnestDisplay, xnestDrawable(pDrawable),
+ x, y, w, h, planeMask, format);
+
+ if (ximage) {
+ length = ximage->bytes_per_line * ximage->height;
+
+ memmove(pImage, ximage->data, length);
+
+ XDestroyImage(ximage);
+ }
+}
+
+static Bool xnestBitBlitPredicate(display, event, args)
+ Display *display;
+ XEvent *event;
+ char *args;
+{
+ return (event->type == GraphicsExpose || event->type == NoExpose);
+}
+
+RegionPtr xnestBitBlitHelper(pGC)
+ GC *pGC;
+{
+ if (!pGC->graphicsExposures)
+ return NullRegion;
+ else {
+ XEvent event;
+ RegionPtr pReg, pTmpReg;
+ BoxRec Box;
+ Bool pending, overlap;
+
+ pReg = REGION_CREATE(pGC->pScreen, NULL, 1);
+ pTmpReg = REGION_CREATE(pGC->pScreen, NULL, 1);
+ if(!pReg || !pTmpReg) return NullRegion;
+
+ pending = True;
+ while (pending) {
+ XIfEvent(xnestDisplay, &event, xnestBitBlitPredicate, NULL);
+
+ switch (event.type) {
+ case NoExpose:
+ pending = False;
+ break;
+
+ case GraphicsExpose:
+ Box.x1 = event.xgraphicsexpose.x;
+ Box.y1 = event.xgraphicsexpose.y;
+ Box.x2 = event.xgraphicsexpose.x + event.xgraphicsexpose.width;
+ Box.y2 = event.xgraphicsexpose.y + event.xgraphicsexpose.height;
+ REGION_RESET(pGC->pScreen, pTmpReg, &Box);
+ REGION_APPEND(pGC->pScreen, pReg, pTmpReg);
+ pending = event.xgraphicsexpose.count;
+ break;
+ }
+ }
+
+ REGION_DESTROY(pGC->pScreen, pTmpReg);
+ REGION_VALIDATE(pGC->pScreen, pReg, &overlap);
+ return(pReg);
+ }
+}
+
+RegionPtr xnestCopyArea(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty)
+ DrawablePtr pSrcDrawable;
+ DrawablePtr pDstDrawable;
+ GC *pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+{
+ XCopyArea(xnestDisplay,
+ xnestDrawable(pSrcDrawable), xnestDrawable(pDstDrawable),
+ xnestGC(pGC), srcx, srcy, width, height, dstx, dsty);
+
+ return xnestBitBlitHelper(pGC);
+}
+
+RegionPtr xnestCopyPlane(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, plane)
+ DrawablePtr pSrcDrawable;
+ DrawablePtr pDstDrawable;
+ GC *pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+ unsigned long plane;
+{
+ XCopyPlane(xnestDisplay,
+ xnestDrawable(pSrcDrawable), xnestDrawable(pDstDrawable),
+ xnestGC(pGC), srcx, srcy, width, height, dstx, dsty, plane);
+
+ return xnestBitBlitHelper(pGC);
+}
+
+void xnestPolyPoint(pDrawable, pGC, mode, nPoints, pPoints)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode;
+ int nPoints;
+ XPoint *pPoints;
+{
+ XDrawPoints(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
+ pPoints, nPoints, mode);
+}
+
+void xnestPolylines(pDrawable, pGC, mode, nPoints, pPoints)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode;
+ int nPoints;
+ XPoint *pPoints;
+{
+ XDrawLines(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
+ pPoints, nPoints, mode);
+}
+
+void xnestPolySegment(pDrawable, pGC, nSegments, pSegments)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nSegments;
+ XSegment *pSegments;
+{
+ XDrawSegments(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
+ pSegments, nSegments);
+}
+
+void xnestPolyRectangle(pDrawable, pGC, nRectangles, pRectangles)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nRectangles;
+ XRectangle *pRectangles;
+{
+ XDrawRectangles(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
+ pRectangles, nRectangles);
+}
+
+void xnestPolyArc(pDrawable, pGC, nArcs, pArcs)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nArcs;
+ XArc *pArcs;
+{
+ XDrawArcs(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
+ pArcs, nArcs);
+}
+
+void xnestFillPolygon(pDrawable, pGC, shape, mode, nPoints, pPoints)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int shape;
+ int mode;
+ int nPoints;
+ XPoint *pPoints;
+{
+ XFillPolygon(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
+ pPoints, nPoints, shape, mode);
+}
+
+void xnestPolyFillRect(pDrawable, pGC, nRectangles, pRectangles)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nRectangles;
+ XRectangle *pRectangles;
+{
+ XFillRectangles(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
+ pRectangles, nRectangles);
+}
+
+void xnestPolyFillArc(pDrawable, pGC, nArcs, pArcs)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nArcs;
+ XArc *pArcs;
+{
+ XFillArcs(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
+ pArcs, nArcs);
+}
+
+int xnestPolyText8(pDrawable, pGC, x, y, count, string)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *string;
+{
+ int width;
+
+ XDrawString(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
+ x, y, string, count);
+
+ width = XTextWidth(xnestFontStruct(pGC->font), string, count);
+
+ return width + x;
+}
+
+int xnestPolyText16(pDrawable, pGC, x, y, count, string)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ XChar2b *string;
+{
+ int width;
+
+ XDrawString16(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
+ x, y, string, count);
+
+ width = XTextWidth16(xnestFontStruct(pGC->font), string, count);
+
+ return width + x;
+}
+
+void xnestImageText8(pDrawable, pGC, x, y, count, string)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *string;
+{
+ XDrawImageString(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
+ x, y, string, count);
+}
+
+void xnestImageText16(pDrawable, pGC, x, y, count, string)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ XChar2b *string;
+{
+ XDrawImageString16(xnestDisplay, xnestDrawable(pDrawable), xnestGC(pGC),
+ x, y, string, count);
+}
+
+void xnestImageGlyphBlt(pDrawable, pGC, x, y, nGlyphs, pCharInfo, pGlyphBase)
+ DrawablePtr pDrawable;
+ GC pGC;
+ int x, y;
+ int nGlyphs;
+ CharInfoPtr pCharInfo;
+ char pGlyphBase;
+{
+ ErrorF("xnest warning: function xnestImageGlyphBlt not implemented\n");
+}
+
+void xnestPolyGlyphBlt(pDrawable, pGC, x, y, nGlyphs, pCharInfo, pGlyphBase)
+ DrawablePtr pDrawable;
+ GC pGC;
+ int x, y;
+ int nGlyphs;
+ CharInfoPtr pCharInfo;
+ char pGlyphBase;
+{
+ ErrorF("xnest warning: function xnestPolyGlyphBlt not implemented\n");
+}
+
+void xnestPushPixels(pDrawable, pGC, pBitmap, width, height, x, y)
+ DrawablePtr pDrawable;
+ GC pGC;
+ PixmapPtr pBitmap;
+ int width, height;
+ int x, y;
+{
+ ErrorF("xnest warning: function xnestPushPixels not implemented\n");
+}
diff --git a/xc/programs/Xserver/hw/xnest/GCOps.h b/xc/programs/Xserver/hw/xnest/GCOps.h
new file mode 100644
index 000000000..98c31205b
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/GCOps.h
@@ -0,0 +1,43 @@
+/* $XConsortium: GCOps.h,v 1.2 93/09/20 20:18:48 dpw Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef XNESTGCOPS_H
+#define XNESTGCOPS_H
+
+void xnestFillSpans();
+void xnestSetSpans();
+void xnestGetSpans();
+void xnestPutImage();
+void xnestGetImage();
+RegionPtr xnestCopyArea();
+RegionPtr xnestCopyPlane();
+void xnestQueryBestSize();
+void xnestPolyPoint();
+void xnestPolylines();
+void xnestPolySegment();
+void xnestPolyRectangle();
+void xnestPolyArc();
+void xnestFillPolygon();
+void xnestPolyFillRect();
+void xnestPolyFillArc();
+int xnestPolyText8();
+int xnestPolyText16();
+void xnestImageText8();
+void xnestImageText16();
+void xnestImageGlyphBlt();
+void xnestPolyGlyphBlt();
+void xnestPushPixels();
+
+#endif /* XNESTGCOPS_H */
diff --git a/xc/programs/Xserver/hw/xnest/GetTime.c b/xc/programs/Xserver/hw/xnest/GetTime.c
new file mode 100644
index 000000000..bd4df1777
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/GetTime.c
@@ -0,0 +1,43 @@
+/* $XConsortium: GetTime.c,v 1.5 94/04/17 20:30:01 dpw Exp $ */
+/*
+
+Copyright (c) 1993 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+*/
+
+
+#include "Xos.h"
+#include <time.h>
+
+long
+GetTimeInMillis()
+{
+ struct timeval tp;
+
+ X_GETTIMEOFDAY(&tp);
+ return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
+}
diff --git a/xc/programs/Xserver/hw/xnest/Handlers.c b/xc/programs/Xserver/hw/xnest/Handlers.c
new file mode 100644
index 000000000..ecfd95ea8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Handlers.c
@@ -0,0 +1,43 @@
+/* $XConsortium: Handlers.c,v 1.2 95/07/10 17:42:22 ray Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+#include "X.h"
+#include "Xproto.h"
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Handlers.h"
+
+void xnestBlockHandler(blockData, pTimeout, pReadMask)
+ pointer blockData;
+ pointer pTimeout;
+ pointer pReadMask;
+{
+ xnestCollectExposures();
+ XFlush(xnestDisplay);
+}
+
+void xnestWakeupHandler(result, pReadMask)
+ int result;
+ pointer pReadMask;
+{
+ xnestCollectEvents();
+}
diff --git a/xc/programs/Xserver/hw/xnest/Handlers.h b/xc/programs/Xserver/hw/xnest/Handlers.h
new file mode 100644
index 000000000..ef4380118
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Handlers.h
@@ -0,0 +1,22 @@
+/* $XConsortium: Handlers.h,v 1.1 93/07/12 15:28:31 rws Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef XNESTHANDLERS_H
+#define XNESTHANDLERS_H
+
+void xnestBlockHandler();
+void xnestWakeupHandler();
+
+#endif /* XNESTHANDLERS_H */
diff --git a/xc/programs/Xserver/hw/xnest/Imakefile b/xc/programs/Xserver/hw/xnest/Imakefile
new file mode 100644
index 000000000..6820123af
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Imakefile
@@ -0,0 +1,75 @@
+XCOMM $TOG: Imakefile /main/12 1997/11/03 14:13:20 kaleb $
+XCOMM $XFree86: xc/programs/Xserver/hw/xnest/Imakefile,v 3.13 1999/06/14 07:32:10 dawes Exp $
+#include <Server.tmpl>
+
+#ifdef OS2Architecture
+SRCS1 = os2Stub.c
+OBJS1 = os2Stub.o
+#endif
+
+SRCS = Args.c \
+ Color.c \
+ Cursor.c \
+ Display.c \
+ Events.c \
+ Font.c \
+ GC.c \
+ GCOps.c \
+ GetTime.c \
+ Handlers.c \
+ Init.c \
+ Keyboard.c \
+ Pixmap.c \
+ Pointer.c \
+ Screen.c \
+ TestExt.c \
+ Visual.c \
+ Window.c \
+ stubs.c \
+ miinitext.c $(SRCS1)
+
+OBJS = Args.o \
+ Color.o \
+ Cursor.o \
+ Display.o \
+ Events.o \
+ Font.o \
+ GC.o \
+ GCOps.o \
+ GetTime.o \
+ Handlers.o \
+ Init.o \
+ Keyboard.o \
+ Pixmap.o \
+ Pointer.o \
+ Screen.o \
+ TestExt.o \
+ Visual.o \
+ Window.o \
+ stubs.o \
+ miinitext.o $(OBJS1)
+
+
+INCLUDES = -I$(BUILDINCDIR) -I$(FONTINCSRC) \
+ -I../../mi -I../../include -I../../os \
+ -I$(EXTINCSRC) -I$(INCLUDESRC) -I.
+
+all:: $(OBJS)
+
+INCLUDES = -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
+ -I../../mi -I../../include -I../../os \
+ -I$(EXTINCSRC) -I$(XINCLUDESRC)
+
+LinkSourceFile(stubs.c,$(SERVERSRC)/Xi)
+SpecialCObjectRule(Init,$(ICONFIGFILES),$(EXT_DEFINES))
+LinkSourceFile(miinitext.c,$(SERVERSRC)/mi)
+SpecialCObjectRule(miinitext,$(ICONFIGFILES),$(OS_DEFINES) -UXINPUT \
+ -UXF86VIDMODE -UXFreeXDGA -UXF86MISC -UMITSHM -UDPMSExtension \
+ -UXF86DRI)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(xnest,$(OBJS))
+
+InstallManPage(Xnest,$(MANDIR))
+
+DependTarget()
diff --git a/xc/programs/Xserver/hw/xnest/Init.c b/xc/programs/Xserver/hw/xnest/Init.c
new file mode 100644
index 000000000..b0ee70b96
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Init.c
@@ -0,0 +1,164 @@
+/* $TOG: Init.c /main/8 1997/11/12 14:38:50 kaleb $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+/* $XFree86: xc/programs/Xserver/hw/xnest/Init.c,v 3.18 1999/05/14 14:11:22 dawes Exp $ */
+
+#include "X.h"
+#include "Xproto.h"
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Screen.h"
+#include "Pointer.h"
+#include "Keyboard.h"
+#include "Handlers.h"
+#include "Init.h"
+#include "Args.h"
+#include "Drawable.h"
+#include "XNGC.h"
+#include "XNFont.h"
+
+#ifdef XFree86Server
+/*
+ * when building the loader, we add some code that tries to
+ * switch bit ordering based on xf86bpp; since Xnest doesn't
+ * use that, we have to add this dummy here
+ */
+int xf86bpp = 8;
+#endif
+
+Bool xnestDoFullGeneration = True;
+
+void InitOutput(screenInfo, argc, argv)
+ ScreenInfo *screenInfo;
+ int argc;
+ char *argv[];
+{
+ int i, j;
+
+ xnestOpenDisplay(argc, argv);
+
+ screenInfo->imageByteOrder = ImageByteOrder(xnestDisplay);
+ screenInfo->bitmapScanlineUnit = BitmapUnit(xnestDisplay);
+ screenInfo->bitmapScanlinePad = BitmapPad(xnestDisplay);
+ screenInfo->bitmapBitOrder = BitmapBitOrder(xnestDisplay);
+
+ screenInfo->numPixmapFormats = 0;
+ for (i = 0; i < xnestNumPixmapFormats; i++)
+ for (j = 0; j < xnestNumDepths; j++)
+ if ((xnestPixmapFormats[i].depth == 1) ||
+ (xnestPixmapFormats[i].depth == xnestDepths[j])) {
+ screenInfo->formats[screenInfo->numPixmapFormats].depth =
+ xnestPixmapFormats[i].depth;
+ screenInfo->formats[screenInfo->numPixmapFormats].bitsPerPixel =
+ xnestPixmapFormats[i].bits_per_pixel;
+ screenInfo->formats[screenInfo->numPixmapFormats].scanlinePad =
+ xnestPixmapFormats[i].scanline_pad;
+ screenInfo->numPixmapFormats++;
+ }
+
+ xnestWindowPrivateIndex = AllocateWindowPrivateIndex();
+ xnestGCPrivateIndex = AllocateGCPrivateIndex();
+ xnestFontPrivateIndex = AllocateFontPrivateIndex();
+
+ if (!xnestNumScreens) xnestNumScreens = 1;
+
+ for (i = 0; i < xnestNumScreens; i++)
+ AddScreen(xnestOpenScreen, argc, argv);
+
+ xnestNumScreens = screenInfo->numScreens;
+
+ xnestDoFullGeneration = xnestFullGeneration;
+}
+
+void InitInput(argc, argv)
+ int argc;
+ char *argv[];
+{
+ DeviceIntPtr ptr, kbd;
+
+ ptr = AddInputDevice(xnestPointerProc, TRUE);
+ kbd = AddInputDevice(xnestKeyboardProc, TRUE);
+
+ RegisterPointerDevice(ptr);
+ RegisterKeyboardDevice(kbd);
+
+ mieqInit(kbd, ptr);
+
+ AddEnabledDevice(XConnectionNumber(xnestDisplay));
+
+ RegisterBlockAndWakeupHandlers(xnestBlockHandler, xnestWakeupHandler, NULL);
+}
+
+/*
+ * DDX - specific abort routine. Called by AbortServer().
+ */
+void AbortDDX()
+{
+ xnestDoFullGeneration = True;
+ xnestCloseDisplay();
+}
+
+/* Called by GiveUp(). */
+void ddxGiveUp()
+{
+ AbortDDX();
+}
+
+void OsVendorInit()
+{
+ return;
+}
+
+void OsVendorFatalError()
+{
+ return;
+}
+
+/* this is just to get the server to link on AIX */
+#ifdef AIXV3
+int SelectWaitTime = 10000; /* usec */
+#endif
+
+#ifdef DPMSExtension
+/**************************************************************
+ * DPMSSet(), DPMSGet(), DPMSSupported()
+ *
+ * stubs
+ *
+ ***************************************************************/
+
+void DPMSSet (level)
+ int level;
+{
+}
+
+int DPMSGet (level)
+ int* level;
+{
+ return -1;
+}
+
+Bool DPMSSupported ()
+{
+ return FALSE;
+}
+#endif
diff --git a/xc/programs/Xserver/hw/xnest/Init.h b/xc/programs/Xserver/hw/xnest/Init.h
new file mode 100644
index 000000000..84a81bfd1
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Init.h
@@ -0,0 +1,21 @@
+/* $XConsortium: Init.h,v 1.1 93/07/12 15:28:35 rws Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef XNESTINIT_H
+#define XNESTINIT_H
+
+extern Bool xnestDoFullGeneration;
+
+#endif /* XNESTINIT_H */
diff --git a/xc/programs/Xserver/hw/xnest/Keyboard.c b/xc/programs/Xserver/hw/xnest/Keyboard.c
new file mode 100644
index 000000000..89c44a005
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Keyboard.c
@@ -0,0 +1,165 @@
+/* $TOG: Keyboard.c /main/5 1998/04/21 09:19:15 msr $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "keysym.h"
+#include "screenint.h"
+#include "inputstr.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Screen.h"
+#include "Keyboard.h"
+#include "Args.h"
+
+void xnestBell(volume, pDev, ctrl, cls)
+ int volume;
+ DeviceIntPtr pDev;
+ pointer ctrl;
+ int cls;
+{
+ XBell(xnestDisplay, volume);
+}
+
+void xnestChangeKeyboardControl(pDev, ctrl)
+ DeviceIntPtr pDev;
+ KeybdCtrl *ctrl;
+{
+ unsigned long value_mask;
+ XKeyboardControl values;
+ int i;
+
+ value_mask = KBKeyClickPercent |
+ KBBellPercent |
+ KBBellPitch |
+ KBBellDuration |
+ KBAutoRepeatMode;
+
+ values.key_click_percent = ctrl->click;
+ values.bell_percent = ctrl->bell;
+ values.bell_pitch = ctrl->bell_pitch;
+ values.bell_duration = ctrl->bell_duration;
+ values.auto_repeat_mode = ctrl->autoRepeat ?
+ AutoRepeatModeOn : AutoRepeatModeOff;
+
+ XChangeKeyboardControl(xnestDisplay, value_mask, &values);
+
+ /*
+ value_mask = KBKey | KBAutoRepeatMode;
+ At this point, we need to walk through the vector and compare it
+ to the current server vector. If there are differences, report them.
+ */
+
+ value_mask = KBLed | KBLedMode;
+ for (i = 1; i <= 32; i++) {
+ values.led = i;
+ values.led_mode = (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff;
+ XChangeKeyboardControl(xnestDisplay, value_mask, &values);
+ }
+}
+
+int xnestKeyboardProc(pDev, onoff, argc, argv)
+ DevicePtr pDev;
+ int onoff, argc;
+ char *argv[];
+{
+ XModifierKeymap *modifier_keymap;
+ KeySym *keymap;
+ int mapWidth;
+ int min_keycode, max_keycode;
+ KeySymsRec keySyms;
+ CARD8 modmap[256];
+ int i, j;
+ XKeyboardState values;
+
+ switch (onoff)
+ {
+ case DEVICE_INIT:
+ modifier_keymap = XGetModifierMapping(xnestDisplay);
+ XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
+#ifdef _XSERVER64
+ {
+ KeySym64 *keymap64;
+ int i, len;
+ keymap64 = XGetKeyboardMapping(xnestDisplay,
+ min_keycode,
+ max_keycode - min_keycode + 1,
+ &mapWidth);
+ len = (max_keycode - min_keycode + 1) * mapWidth;
+ keymap = (KeySym *)xalloc(len * sizeof(KeySym));
+ for(i = 0; i < len; ++i)
+ keymap[i] = keymap64[i];
+ XFree(keymap64);
+ }
+#else
+ keymap = XGetKeyboardMapping(xnestDisplay,
+ min_keycode,
+ max_keycode - min_keycode + 1,
+ &mapWidth);
+#endif
+
+ for (i = 0; i < 256; i++)
+ modmap[i] = 0;
+ for (j = 0; j < 8; j++)
+ for(i = 0; i < modifier_keymap->max_keypermod; i++) {
+ CARD8 keycode;
+ if (keycode =
+ modifier_keymap->
+ modifiermap[j * modifier_keymap->max_keypermod + i])
+ modmap[keycode] |= 1<<j;
+ }
+ XFreeModifiermap(modifier_keymap);
+
+ keySyms.minKeyCode = min_keycode;
+ keySyms.maxKeyCode = max_keycode;
+ keySyms.mapWidth = mapWidth;
+ keySyms.map = keymap;
+
+ XGetKeyboardControl(xnestDisplay, &values);
+
+ memmove((char *) defaultKeyboardControl.autoRepeats,
+ (char *) values.auto_repeats, sizeof(values.auto_repeats));
+
+ InitKeyboardDeviceStruct(pDev, &keySyms, modmap,
+ xnestBell, xnestChangeKeyboardControl);
+ XFree(keymap);
+ break;
+ case DEVICE_ON:
+ xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
+ for (i = 0; i < xnestNumScreens; i++)
+ XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
+ break;
+ case DEVICE_OFF:
+ xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
+ for (i = 0; i < xnestNumScreens; i++)
+ XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
+ break;
+ case DEVICE_CLOSE:
+ break;
+ }
+ return Success;
+}
+
+Bool LegalModifier(key, pDev)
+ unsigned int key;
+ DevicePtr pDev;
+{
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/hw/xnest/Keyboard.h b/xc/programs/Xserver/hw/xnest/Keyboard.h
new file mode 100644
index 000000000..99eeacb10
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Keyboard.h
@@ -0,0 +1,26 @@
+/* $XConsortium: Keyboard.h,v 1.1 93/07/12 15:28:38 rws Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef XNESTKEYBOARD_H
+#define XNESTKEYBOARD_H
+
+#define XNEST_KEYBOARD_EVENT_MASK \
+ (KeyPressMask | KeyReleaseMask | FocusChangeMask | KeymapStateMask)
+
+void xnestBell();
+void xnestChangeKeyboardControl();
+int xnestKeyboardProc();
+
+#endif /* XNESTKEYBOARD_H */
diff --git a/xc/programs/Xserver/hw/xnest/Pixmap.c b/xc/programs/Xserver/hw/xnest/Pixmap.c
new file mode 100644
index 000000000..98f1e3389
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Pixmap.c
@@ -0,0 +1,130 @@
+/* $XConsortium: Pixmap.c,v 1.3 95/07/10 17:42:22 ray Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+#include "X.h"
+#include "Xproto.h"
+#include "miscstruct.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "gc.h"
+#include "servermd.h"
+#include "mi.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Screen.h"
+#include "Pixmap.h"
+
+PixmapPtr xnestCreatePixmap(pScreen, width, height, depth)
+ ScreenPtr pScreen;
+ int width;
+ int height;
+ int depth;
+{
+ PixmapPtr pPixmap;
+
+ pPixmap = (PixmapPtr)xalloc(sizeof(PixmapRec) + sizeof(xnestPrivPixmap));
+ if (!pPixmap)
+ return NullPixmap;
+ pPixmap->drawable.type = DRAWABLE_PIXMAP;
+ pPixmap->drawable.class = 0;
+ pPixmap->drawable.depth = depth;
+ pPixmap->drawable.bitsPerPixel = depth;
+ pPixmap->drawable.id = 0;
+ pPixmap->drawable.x = 0;
+ pPixmap->drawable.y = 0;
+ pPixmap->drawable.width = width;
+ pPixmap->drawable.height = height;
+ pPixmap->drawable.pScreen = pScreen;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap->refcnt = 1;
+ pPixmap->devKind = PixmapBytePad(width, depth);
+ pPixmap->devPrivate.ptr = (pointer)(pPixmap + 1);
+ if (width && height)
+ xnestPixmapPriv(pPixmap)->pixmap =
+ XCreatePixmap(xnestDisplay,
+ xnestDefaultWindows[pScreen->myNum],
+ width, height, depth);
+ else
+ xnestPixmapPriv(pPixmap)->pixmap = 0;
+
+ return pPixmap;
+}
+
+Bool xnestDestroyPixmap(pPixmap)
+ PixmapPtr pPixmap;
+{
+ if(--pPixmap->refcnt)
+ return TRUE;
+ XFreePixmap(xnestDisplay, xnestPixmap(pPixmap));
+ xfree(pPixmap);
+ return TRUE;
+}
+
+RegionPtr xnestPixmapToRegion(pPixmap)
+ PixmapPtr pPixmap;
+{
+ XImage *ximage;
+ register RegionPtr pReg, pTmpReg;
+ register int x, y;
+ unsigned long previousPixel, currentPixel;
+ BoxRec Box;
+ int nWidth;
+ Bool overlap;
+
+ ximage = XGetImage(xnestDisplay, xnestPixmap(pPixmap), 0, 0,
+ pPixmap->drawable.width, pPixmap->drawable.height,
+ 1, XYPixmap);
+
+ pReg = REGION_CREATE(pPixmap->drawable.pScreen, NULL, 1);
+ pTmpReg = REGION_CREATE(pPixmap->drawable.pScreen, NULL, 1);
+ if(!pReg || !pTmpReg) return NullRegion;
+
+ for (y = 0; y < pPixmap->drawable.height; y++) {
+ Box.y1 = y;
+ Box.y2 = y + 1;
+ previousPixel = 0L;
+ for (x = 0; x < pPixmap->drawable.width; x++) {
+ currentPixel = XGetPixel(ximage, x, y);
+ if (previousPixel != currentPixel) {
+ if (previousPixel == 0L) {
+ /* left edge */
+ Box.x1 = x;
+ }
+ else if (currentPixel == 0L) {
+ /* right edge */
+ Box.x2 = x;
+ REGION_RESET(pPixmap->drawable.pScreen, pTmpReg, &Box);
+ REGION_APPEND(pPixmap->drawable.pScreen, pReg, pTmpReg);
+ }
+ previousPixel = currentPixel;
+ }
+ }
+ if (previousPixel != 0L) {
+ /* right edge because of the end of pixmap */
+ Box.x2 = pPixmap->drawable.width;
+ REGION_RESET(pPixmap->drawable.pScreen, pTmpReg, &Box);
+ REGION_APPEND(pPixmap->drawable.pScreen, pReg, pTmpReg);
+ }
+ }
+
+ REGION_DESTROY(pPixmap->drawable.pScreen, pTmpReg);
+ XDestroyImage(ximage);
+
+ REGION_VALIDATE(pPixmap->drawable.pScreen, pReg, &overlap);
+
+ return(pReg);
+}
diff --git a/xc/programs/Xserver/hw/xnest/Pixmap.h b/xc/programs/Xserver/hw/xnest/Pixmap.h
new file mode 100644
index 000000000..3331bb306
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Pixmap.h
@@ -0,0 +1,34 @@
+/* $XConsortium: Pixmap.h,v 1.1 93/07/12 15:28:41 rws Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef XNESTPIXMAP_H
+#define XNESTPIXMAP_H
+
+typedef struct {
+ Pixmap pixmap;
+} xnestPrivPixmap;
+
+#define xnestPixmapPriv(pPixmap) \
+ ((xnestPrivPixmap *)((pPixmap)->devPrivate.ptr))
+
+#define xnestPixmap(pPixmap) (xnestPixmapPriv(pPixmap)->pixmap)
+
+#define xnestSharePixmap(pPixmap) ((pPixmap)->refcnt++)
+
+PixmapPtr xnestCreatePixmap();
+Bool xnestDestroyPixmap();
+RegionPtr xnestPixmapToRegion();
+
+#endif /* XNESTPIXMAP_H */
diff --git a/xc/programs/Xserver/hw/xnest/Pointer.c b/xc/programs/Xserver/hw/xnest/Pointer.c
new file mode 100644
index 000000000..8b82c1ed8
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Pointer.c
@@ -0,0 +1,73 @@
+/* $XConsortium: Pointer.c /main/3 1996/09/28 17:13:56 rws $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+#include "X.h"
+#include "Xproto.h"
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#include "mipointer.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Screen.h"
+#include "Pointer.h"
+#include "Args.h"
+
+void xnestChangePointerControl(pDev, ctrl)
+ DeviceIntPtr pDev;
+ PtrCtrl *ctrl;
+{
+ XChangePointerControl(xnestDisplay, True, True,
+ ctrl->num, ctrl->den, ctrl->threshold);
+}
+
+int xnestPointerProc(pDev, onoff, argc, argv)
+ DevicePtr pDev;
+ int onoff, argc;
+ char *argv[];
+{
+ CARD8 map[MAXBUTTONS];
+ int nmap;
+ int i;
+
+ switch (onoff)
+ {
+ case DEVICE_INIT:
+ nmap = XGetPointerMapping(xnestDisplay, map, MAXBUTTONS);
+ for (i = 0; i <= nmap; i++)
+ map[i] = i; /* buttons are already mapped */
+ InitPointerDeviceStruct(pDev, map, nmap,
+ miPointerGetMotionEvents,
+ xnestChangePointerControl,
+ miPointerGetMotionBufferSize());
+ break;
+ case DEVICE_ON:
+ xnestEventMask |= XNEST_POINTER_EVENT_MASK;
+ for (i = 0; i < xnestNumScreens; i++)
+ XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
+ break;
+ case DEVICE_OFF:
+ xnestEventMask &= ~XNEST_POINTER_EVENT_MASK;
+ for (i = 0; i < xnestNumScreens; i++)
+ XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
+ break;
+ case DEVICE_CLOSE:
+ break;
+ }
+ return Success;
+}
diff --git a/xc/programs/Xserver/hw/xnest/Pointer.h b/xc/programs/Xserver/hw/xnest/Pointer.h
new file mode 100644
index 000000000..784c1fe21
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Pointer.h
@@ -0,0 +1,28 @@
+/* $XConsortium: Pointer.h,v 1.1 93/07/12 15:28:44 rws Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef XNESTPOINTER_H
+#define XNESTPOINTER_H
+
+#define MAXBUTTONS 256
+
+#define XNEST_POINTER_EVENT_MASK \
+ (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | \
+ EnterWindowMask | LeaveWindowMask)
+
+void xnestChangePointerControl();
+int xnestPointerProc();
+
+#endif /* XNESTPOINTER_H */
diff --git a/xc/programs/Xserver/hw/xnest/Screen.c b/xc/programs/Xserver/hw/xnest/Screen.c
new file mode 100644
index 000000000..7e4b6b119
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Screen.c
@@ -0,0 +1,378 @@
+/* $XConsortium: Screen.c /main/8 1996/12/02 10:21:46 lehors $ */
+/* $XFree86: xc/programs/Xserver/hw/xnest/Screen.c,v 3.7 1998/12/20 11:57:54 dawes Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+#include "X.h"
+#include "Xproto.h"
+#include "scrnintstr.h"
+#include "dix.h"
+#include "mi.h"
+#include "mibstore.h"
+#include "colormapst.h"
+#include "resource.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Screen.h"
+#include "Args.h"
+#include "XNGC.h"
+#include "GCOps.h"
+#include "Drawable.h"
+#include "XNFont.h"
+#include "Color.h"
+#include "Cursor.h"
+#include "Visual.h"
+#include "Events.h"
+#include "Init.h"
+#include "Args.h"
+
+extern Window xnestParentWindow;
+
+Window xnestDefaultWindows[MAXSCREENS];
+Window xnestScreenSaverWindows[MAXSCREENS];
+
+ScreenPtr xnestScreen(window)
+ Window window;
+{
+ int i;
+
+ for (i = 0; i < xnestNumScreens; i++)
+ if (xnestDefaultWindows[i] == window)
+ return screenInfo.screens[i];
+
+ return NULL;
+}
+
+static int offset(mask)
+ unsigned long mask;
+{
+ int count;
+
+ for (count = 0; !(mask & 1) && count < 32; count++)
+ mask >>= 1;
+
+ return count;
+}
+
+static Bool xnestSaveScreen(pScreen, what)
+ ScreenPtr pScreen;
+ int what;
+{
+ if (xnestSoftwareScreenSaver)
+ return False;
+ else {
+ switch (what) {
+ case SCREEN_SAVER_ON:
+ XMapRaised(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
+ xnestSetScreenSaverColormapWindow(pScreen);
+ break;
+
+ case SCREEN_SAVER_OFF:
+ XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
+ xnestSetInstalledColormapWindows(pScreen);
+ break;
+
+ case SCREEN_SAVER_FORCER:
+ lastEventTime = GetTimeInMillis();
+ XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
+ xnestSetInstalledColormapWindows(pScreen);
+ break;
+
+ case SCREEN_SAVER_CYCLE:
+ XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
+ xnestSetInstalledColormapWindows(pScreen);
+ break;
+ }
+ return True;
+ }
+}
+
+Bool xnestOpenScreen(index, pScreen, argc, argv)
+ int index;
+ register ScreenPtr pScreen;
+ int argc;
+ char *argv[];
+{
+ VisualPtr visuals;
+ DepthPtr depths;
+ int numVisuals, numDepths;
+ int i, j, depthIndex;
+ unsigned long valuemask;
+ XSetWindowAttributes attributes;
+ XWindowAttributes gattributes;
+ XSizeHints sizeHints;
+
+ if (!(AllocateWindowPrivate(pScreen, xnestWindowPrivateIndex,
+ sizeof(xnestPrivWin)) &&
+ AllocateGCPrivate(pScreen, xnestGCPrivateIndex,
+ sizeof(xnestPrivGC))))
+ return False;
+
+ visuals = (VisualPtr)xalloc(xnestNumVisuals * sizeof(VisualRec));
+ numVisuals = 0;
+
+ depths = (DepthPtr)xalloc(MAXDEPTH * sizeof(DepthRec));
+ depths[0].depth = 1;
+ depths[0].numVids = 0;
+ depths[0].vids = (VisualID *)xalloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
+ numDepths = 1;
+
+ for (i = 0; i < xnestNumVisuals; i++) {
+ visuals[numVisuals].vid = FakeClientID(0);
+ visuals[numVisuals].class = xnestVisuals[i].class;
+ visuals[numVisuals].bitsPerRGBValue = xnestVisuals[i].bits_per_rgb;
+ visuals[numVisuals].ColormapEntries = xnestVisuals[i].colormap_size;
+ visuals[numVisuals].nplanes = xnestVisuals[i].depth;
+ visuals[numVisuals].redMask = xnestVisuals[i].red_mask;
+ visuals[numVisuals].greenMask = xnestVisuals[i].green_mask;
+ visuals[numVisuals].blueMask = xnestVisuals[i].blue_mask;
+ visuals[numVisuals].offsetRed = offset(xnestVisuals[i].red_mask);
+ visuals[numVisuals].offsetGreen = offset(xnestVisuals[i].green_mask);
+ visuals[numVisuals].offsetBlue = offset(xnestVisuals[i].blue_mask);
+
+ depthIndex = UNDEFINED;
+ for (j = 0; j < numDepths; j++)
+ if (depths[j].depth == xnestVisuals[i].depth) {
+ depthIndex = j;
+ break;
+ }
+
+ if (depthIndex == UNDEFINED) {
+ depthIndex = numDepths;
+ depths[depthIndex].depth = xnestVisuals[i].depth;
+ depths[depthIndex].numVids = 0;
+ depths[depthIndex].vids =
+ (VisualID *)xalloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
+ numDepths++;
+ }
+ if (depths[depthIndex].numVids >= MAXVISUALSPERDEPTH) {
+ FatalError("Visual table overflow");
+ }
+ depths[depthIndex].vids[depths[depthIndex].numVids] =
+ visuals[numVisuals].vid;
+ depths[depthIndex].numVids++;
+
+ numVisuals++;
+ }
+
+ if (xnestParentWindow != 0) {
+ XGetWindowAttributes(xnestDisplay, xnestParentWindow, &gattributes);
+ xnestWidth = gattributes.width;
+ xnestHeight = gattributes.height;
+ }
+
+ /* myNum */
+ /* id */
+ miScreenInit(pScreen, NULL, xnestWidth, xnestHeight, 1, 1, xnestWidth,
+ visuals[xnestDefaultVisualIndex].nplanes, /* rootDepth */
+ numDepths, depths,
+ visuals[xnestDefaultVisualIndex].vid, /* root visual */
+ numVisuals, visuals);
+
+ miInitializeBackingStore(pScreen);
+
+ pScreen->mmWidth = xnestWidth * DisplayWidthMM(xnestDisplay,
+ DefaultScreen(xnestDisplay)) /
+ DisplayWidth(xnestDisplay,
+ DefaultScreen(xnestDisplay));
+ pScreen->mmHeight = xnestHeight * DisplayHeightMM(xnestDisplay,
+ DefaultScreen(xnestDisplay)) /
+ DisplayHeight(xnestDisplay,
+ DefaultScreen(xnestDisplay));
+
+ pScreen->defColormap = (Colormap) FakeClientID(0);
+ pScreen->minInstalledCmaps = MINCMAPS;
+ pScreen->maxInstalledCmaps = MAXCMAPS;
+ pScreen->backingStoreSupport = NotUseful;
+ pScreen->saveUnderSupport = NotUseful;
+ pScreen->whitePixel = xnestWhitePixel;
+ pScreen->blackPixel = xnestBlackPixel;
+ /* rgf */
+ /* GCperDepth */
+ /* PixmapPerDepth */
+ pScreen->devPrivate = NULL;
+ /* WindowPrivateLen */
+ /* WindowPrivateSizes */
+ /* totalWindowSize */
+ /* GCPrivateLen */
+ /* GCPrivateSizes */
+ /* totalGCSize */
+
+ /* Random screen procedures */
+
+ pScreen->CloseScreen = xnestCloseScreen;
+ pScreen->QueryBestSize = xnestQueryBestSize;
+ pScreen->SaveScreen = xnestSaveScreen;
+ pScreen->GetImage = xnestGetImage;
+ pScreen->GetSpans = xnestGetSpans;
+ pScreen->PointerNonInterestBox = (void (*)()) 0;
+ pScreen->SourceValidate = (void (*)()) 0;
+
+ /* Window Procedures */
+
+ pScreen->CreateWindow = xnestCreateWindow;
+ pScreen->DestroyWindow = xnestDestroyWindow;
+ pScreen->PositionWindow = xnestPositionWindow;
+ pScreen->ChangeWindowAttributes = xnestChangeWindowAttributes;
+ pScreen->RealizeWindow = xnestRealizeWindow;
+ pScreen->UnrealizeWindow = xnestUnrealizeWindow;
+ pScreen->PostValidateTree = (void (*)()) 0;
+ pScreen->WindowExposures = xnestWindowExposures;
+ pScreen->PaintWindowBackground = xnestPaintWindowBackground;
+ pScreen->PaintWindowBorder = xnestPaintWindowBorder;
+ pScreen->CopyWindow = xnestCopyWindow;
+ pScreen->ClipNotify = xnestClipNotify;
+
+ /* Pixmap procedures */
+
+ pScreen->CreatePixmap = xnestCreatePixmap;
+ pScreen->DestroyPixmap = xnestDestroyPixmap;
+
+ /* Backing store procedures */
+
+ pScreen->SaveDoomedAreas = (void (*)()) 0;
+ pScreen->RestoreAreas = (RegionPtr (*)()) 0;
+ pScreen->ExposeCopy = (void (*)()) 0;
+ pScreen->TranslateBackingStore = (RegionPtr (*)()) 0;
+ pScreen->ClearBackingStore = (RegionPtr (*)()) 0;
+ pScreen->DrawGuarantee = (void (*)()) 0;
+
+ /* Font procedures */
+
+ pScreen->RealizeFont = xnestRealizeFont;
+ pScreen->UnrealizeFont = xnestUnrealizeFont;
+
+ /* Cursor Procedures */
+
+ pScreen->ConstrainCursor = xnestConstrainCursor;
+ pScreen->CursorLimits = xnestCursorLimits;
+ pScreen->DisplayCursor = xnestDisplayCursor;
+ pScreen->RealizeCursor = xnestRealizeCursor;
+ pScreen->UnrealizeCursor = xnestUnrealizeCursor;
+ pScreen->RecolorCursor = xnestRecolorCursor;
+ pScreen->SetCursorPosition = xnestSetCursorPosition;
+
+ /* GC procedures */
+
+ pScreen->CreateGC = xnestCreateGC;
+
+ /* Colormap procedures */
+
+ pScreen->CreateColormap = xnestCreateColormap;
+ pScreen->DestroyColormap = xnestDestroyColormap;
+ pScreen->InstallColormap = xnestInstallColormap;
+ pScreen->UninstallColormap = xnestUninstallColormap;
+ pScreen->ListInstalledColormaps = xnestListInstalledColormaps;
+ pScreen->StoreColors = xnestStoreColors;
+ pScreen->ResolveColor = xnestResolveColor;
+
+ pScreen->BitmapToRegion = xnestPixmapToRegion;
+
+ /* OS layer procedures */
+
+ pScreen->BlockHandler = (void (*)())NoopDDA;
+ pScreen->WakeupHandler = (void (*)())NoopDDA;
+ pScreen->blockData = (pointer)0;
+ pScreen->wakeupData = (pointer)0;
+ if (!miScreenDevPrivateInit(pScreen, xnestWidth, NULL))
+ return FALSE;
+
+ /* devPrivates */
+
+#define POSITION_OFFSET (pScreen->myNum * (xnestWidth + xnestHeight) / 32)
+
+ if (xnestDoFullGeneration) {
+
+ valuemask = CWBackPixel | CWEventMask | CWColormap;
+ attributes.background_pixel = xnestWhitePixel;
+ attributes.event_mask = xnestEventMask;
+ attributes.colormap = xnestDefaultVisualColormap(xnestDefaultVisual(pScreen));
+
+ if (xnestParentWindow != 0) {
+ xnestDefaultWindows[pScreen->myNum] = xnestParentWindow;
+ XSelectInput (xnestDisplay, xnestDefaultWindows[pScreen->myNum],
+ xnestEventMask);
+ } else
+ xnestDefaultWindows[pScreen->myNum] =
+ XCreateWindow(xnestDisplay,
+ DefaultRootWindow(xnestDisplay),
+ xnestX + POSITION_OFFSET,
+ xnestY + POSITION_OFFSET,
+ xnestWidth, xnestHeight,
+ xnestBorderWidth,
+ pScreen->rootDepth,
+ InputOutput,
+ xnestDefaultVisual(pScreen),
+ valuemask, &attributes);
+
+ if (!xnestWindowName)
+ xnestWindowName = argv[0];
+
+ sizeHints.flags = PPosition | PSize | PMaxSize;
+ sizeHints.x = xnestX + POSITION_OFFSET;
+ sizeHints.y = xnestY + POSITION_OFFSET;
+ sizeHints.width = sizeHints.max_width = xnestWidth;
+ sizeHints.height = sizeHints.max_height = xnestHeight;
+ if (xnestUserGeometry & XValue || xnestUserGeometry & YValue)
+ sizeHints.flags |= USPosition;
+ if (xnestUserGeometry & WidthValue || xnestUserGeometry & HeightValue)
+ sizeHints.flags |= USSize;
+ XSetStandardProperties(xnestDisplay,
+ xnestDefaultWindows[pScreen->myNum],
+ xnestWindowName,
+ xnestWindowName,
+ xnestIconBitmap,
+ argv, argc, &sizeHints);
+
+ XMapWindow(xnestDisplay, xnestDefaultWindows[pScreen->myNum]);
+
+ valuemask = CWBackPixmap | CWColormap;
+ attributes.background_pixmap = xnestScreenSaverPixmap;
+ attributes.colormap =
+ DefaultColormap(xnestDisplay, DefaultScreen(xnestDisplay));
+ xnestScreenSaverWindows[pScreen->myNum] =
+ XCreateWindow(xnestDisplay,
+ xnestDefaultWindows[pScreen->myNum],
+ 0, 0, xnestWidth, xnestHeight, 0,
+ DefaultDepth(xnestDisplay, DefaultScreen(xnestDisplay)),
+ InputOutput,
+ DefaultVisual(xnestDisplay, DefaultScreen(xnestDisplay)),
+ valuemask, &attributes);
+ }
+
+ if (!xnestCreateDefaultColormap(pScreen)) return False;
+
+ return True;
+}
+
+Bool xnestCloseScreen(index, pScreen)
+ int index;
+ ScreenPtr pScreen;
+{
+ int i;
+
+ for (i = 0; i < pScreen->numDepths; i++)
+ xfree(pScreen->allowedDepths[i].vids);
+ xfree(pScreen->allowedDepths);
+ xfree(pScreen->visuals);
+ xfree(pScreen->devPrivate);
+
+ /*
+ If xnestDoFullGeneration all x resources will be destroyed upon closing
+ the display connection. There is no need to generate extra protocol.
+ */
+
+ return True;
+}
diff --git a/xc/programs/Xserver/hw/xnest/Screen.h b/xc/programs/Xserver/hw/xnest/Screen.h
new file mode 100644
index 000000000..63b8d7085
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Screen.h
@@ -0,0 +1,26 @@
+/* $XConsortium: Screen.h,v 1.1 93/07/12 15:28:49 rws Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef XNESTSCREEN_H
+#define XNESTSCREEN_H
+
+extern Window xnestDefaultWindows[MAXSCREENS];
+extern Window xnestScreenSaverWindows[MAXSCREENS];
+
+ScreenPtr xnestScreen();
+Bool xnestOpenScreen();
+Bool xnestCloseScreen();
+
+#endif /* XNESTSCREEN_H */
diff --git a/xc/programs/Xserver/hw/xnest/TestExt.c b/xc/programs/Xserver/hw/xnest/TestExt.c
new file mode 100644
index 000000000..c1ff6618c
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/TestExt.c
@@ -0,0 +1,68 @@
+/* $XConsortium: TestExt.c,v 1.3 94/10/28 20:47:10 dpw Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xnest/TestExt.c,v 3.2 1996/01/07 10:46:49 dawes Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+#include "X.h"
+#include "Xproto.h"
+#include "Xlib.h"
+#undef Bool
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#define XTestSERVER_SIDE
+#include "xtestext1.h"
+
+extern CARD32 lastEventTime;
+
+void XTestGetPointerPos(fmousex, fmousey)
+ short *fmousex;
+ short *fmousey;
+{
+ int x,y;
+
+ miPointerPosition(&x, &y);
+ *fmousex = x;
+ *fmousey = y;
+}
+
+void XTestJumpPointer(jx, jy, dev_type)
+ int jx;
+ int jy;
+ int dev_type;
+{
+ miPointerAbsoluteCursor(jx, jy, GetTimeInMillis());
+}
+
+void XTestGenerateEvent(dev_type, keycode, keystate, mousex, mousey)
+ int dev_type;
+ int keycode;
+ int keystate;
+ int mousex;
+ int mousey;
+{
+/*
+ xEvent tevent;
+
+ tevent.u.u.type = (dev_type == XE_POINTER) ?
+ (keystate == XTestKEY_UP) ? ButtonRelease : ButtonPress :
+ (keystate == XTestKEY_UP) ? KeyRelease : KeyPress;
+ tevent.u.u.detail = keycode;
+ tevent.u.keyButtonPointer.rootX = mousex;
+ tevent.u.keyButtonPointer.rootY = mousey;
+ tevent.u.keyButtonPointer.time = lastEventTime = GetTimeInMillis();
+ mieqEnqueue(&tevent);
+*/
+}
diff --git a/xc/programs/Xserver/hw/xnest/Visual.c b/xc/programs/Xserver/hw/xnest/Visual.c
new file mode 100644
index 000000000..33e261502
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Visual.c
@@ -0,0 +1,67 @@
+/* $XConsortium: Visual.c,v 1.2 95/07/10 17:42:22 ray Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+#include "X.h"
+#include "Xproto.h"
+#include "scrnintstr.h"
+#include "dix.h"
+#include "mi.h"
+#include "mibstore.h"
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Visual.h"
+
+Visual *xnestVisual(pVisual)
+ VisualPtr pVisual;
+{
+ int i;
+
+ for (i = 0; i < xnestNumVisuals; i++)
+ if (pVisual->class == xnestVisuals[i].class &&
+ pVisual->bitsPerRGBValue == xnestVisuals[i].bits_per_rgb &&
+ pVisual->ColormapEntries == xnestVisuals[i].colormap_size &&
+ pVisual->nplanes == xnestVisuals[i].depth &&
+ pVisual->redMask == xnestVisuals[i].red_mask &&
+ pVisual->greenMask == xnestVisuals[i].green_mask &&
+ pVisual->blueMask == xnestVisuals[i].blue_mask)
+ return xnestVisuals[i].visual;
+
+ return NULL;
+}
+
+Visual *xnestVisualFromID(pScreen, visual)
+ ScreenPtr pScreen;
+ VisualID visual;
+{
+ int i;
+
+ for (i = 0; i < pScreen->numVisuals; i++)
+ if (pScreen->visuals[i].vid == visual)
+ return xnestVisual(&pScreen->visuals[i]);
+
+ return NULL;
+}
+
+Colormap xnestDefaultVisualColormap(visual)
+ Visual *visual;
+{
+ int i;
+
+ for (i = 0; i < xnestNumVisuals; i++)
+ if (xnestVisuals[i].visual == visual)
+ return xnestDefaultColormaps[i];
+
+ return None;
+}
diff --git a/xc/programs/Xserver/hw/xnest/Visual.h b/xc/programs/Xserver/hw/xnest/Visual.h
new file mode 100644
index 000000000..44c87c88a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Visual.h
@@ -0,0 +1,26 @@
+/* $XConsortium: Visual.h,v 1.1 93/07/12 15:28:54 rws Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef XNESTVISUAL_H
+#define XNESTVISUAL_H
+
+Visual *xnestVisual();
+Visual *xnestVisualFromID();
+Colormap xnestDefaultVisualColormap();
+
+#define xnestDefaultVisual(pScreen) \
+ xnestVisualFromID((pScreen), (pScreen)->rootVisual)
+
+#endif /* XNESTVISUAL_H */
diff --git a/xc/programs/Xserver/hw/xnest/Window.c b/xc/programs/Xserver/hw/xnest/Window.c
new file mode 100644
index 000000000..6573f1a8e
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Window.c
@@ -0,0 +1,556 @@
+/* $XConsortium: Window.c /main/8 1996/12/02 10:21:53 lehors $ */
+/* $XFree86: xc/programs/Xserver/hw/xnest/Window.c,v 3.4 1996/12/27 07:07:53 dawes Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+#include "X.h"
+#include "Xproto.h"
+#include "gcstruct.h"
+#include "window.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "colormapst.h"
+#include "scrnintstr.h"
+#include "region.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Screen.h"
+#include "XNGC.h"
+#include "Drawable.h"
+#include "Color.h"
+#include "Visual.h"
+#include "Events.h"
+#include "Args.h"
+
+int xnestWindowPrivateIndex;
+
+static int xnestFindWindowMatch(pWin, ptr)
+ WindowPtr pWin;
+ pointer ptr;
+{
+ xnestWindowMatch *wm = (xnestWindowMatch *)ptr;
+ if (wm->window == xnestWindow(pWin)) {
+ wm->pWin = pWin;
+ return WT_STOPWALKING;
+ }
+ else
+ return WT_WALKCHILDREN;
+}
+
+WindowPtr xnestWindowPtr(window)
+ Window window;
+{
+ xnestWindowMatch wm;
+ int i;
+
+ wm.pWin = NullWindow;
+ wm.window = window;
+
+ for (i = 0; i < xnestNumScreens; i++) {
+ WalkTree(screenInfo.screens[i], xnestFindWindowMatch, (pointer) &wm);
+ if (wm.pWin) break;
+ }
+
+ return wm.pWin;
+}
+
+Bool xnestCreateWindow(pWin)
+ WindowPtr pWin;
+{
+ unsigned long mask;
+ XSetWindowAttributes attributes;
+ Visual *visual;
+ ColormapPtr pCmap;
+
+ if (pWin->drawable.class == InputOnly) {
+ mask = 0L;
+ visual = CopyFromParent;
+ }
+ else {
+ mask = CWEventMask | CWBackingStore;
+ attributes.event_mask = ExposureMask;
+ attributes.backing_store = NotUseful;
+
+ if (pWin->parent) {
+ if (pWin->optional && pWin->optional->visual != wVisual(pWin->parent)) {
+ visual = xnestVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
+ mask |= CWColormap;
+ if (pWin->optional->colormap) {
+ pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin), RT_COLORMAP);
+ attributes.colormap = xnestColormap(pCmap);
+ }
+ else
+ attributes.colormap = xnestDefaultVisualColormap(visual);
+ }
+ else
+ visual = CopyFromParent;
+ }
+ else { /* root windows have their own colormaps at creation time */
+ visual = xnestVisualFromID(pWin->drawable.pScreen, wVisual(pWin));
+ pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin), RT_COLORMAP);
+ mask |= CWColormap;
+ attributes.colormap = xnestColormap(pCmap);
+ }
+ }
+
+ xnestWindowPriv(pWin)->window = XCreateWindow(xnestDisplay,
+ xnestWindowParent(pWin),
+ pWin->origin.x -
+ wBorderWidth(pWin),
+ pWin->origin.y -
+ wBorderWidth(pWin),
+ pWin->drawable.width,
+ pWin->drawable.height,
+ pWin->borderWidth,
+ pWin->drawable.depth,
+ pWin->drawable.class,
+ visual,
+ mask, &attributes);
+ xnestWindowPriv(pWin)->parent = xnestWindowParent(pWin);
+ xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
+ xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
+ xnestWindowPriv(pWin)->width = pWin->drawable.width;
+ xnestWindowPriv(pWin)->height = pWin->drawable.height;
+ xnestWindowPriv(pWin)->border_width = pWin->borderWidth;
+ xnestWindowPriv(pWin)->sibling_above = None;
+ if (pWin->nextSib)
+ xnestWindowPriv(pWin->nextSib)->sibling_above = xnestWindow(pWin);
+#ifdef SHAPE
+ xnestWindowPriv(pWin)->bounding_shape =
+ REGION_CREATE(pWin->drawable.pScreen, NULL, 1);
+ xnestWindowPriv(pWin)->clip_shape =
+ REGION_CREATE(pWin->drawable.pScreen, NULL, 1);
+#endif /* SHAPE */
+
+ if (!pWin->parent) /* only the root window will have the right colormap */
+ xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
+
+ return True;
+}
+
+Bool xnestDestroyWindow(pWin)
+ WindowPtr pWin;
+{
+ if (pWin->nextSib)
+ xnestWindowPriv(pWin->nextSib)->sibling_above =
+ xnestWindowPriv(pWin)->sibling_above;
+#ifdef SHAPE
+ REGION_DESTROY(pWin->drawable.pScreen,
+ xnestWindowPriv(pWin)->bounding_shape);
+ REGION_DESTROY(pWin->drawable.pScreen,
+ xnestWindowPriv(pWin)->clip_shape);
+#endif
+ XDestroyWindow(xnestDisplay, xnestWindow(pWin));
+ xnestWindowPriv(pWin)->window = None;
+
+ if (pWin->optional && pWin->optional->colormap && pWin->parent)
+ xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
+
+ return True;
+}
+
+Bool xnestPositionWindow(pWin, x, y)
+ WindowPtr pWin;
+ int x, y;
+{
+ xnestConfigureWindow(pWin,
+ CWParent |
+ CWX | CWY |
+ CWWidth | CWHeight |
+ CWBorderWidth);
+
+ return True;
+}
+
+void xnestConfigureWindow(pWin, mask)
+ WindowPtr pWin;
+ unsigned int mask;
+{
+ unsigned int valuemask;
+ XWindowChanges values;
+
+ if (mask & CWParent &&
+ xnestWindowPriv(pWin)->parent != xnestWindowParent(pWin)) {
+ XReparentWindow(xnestDisplay, xnestWindow(pWin),
+ xnestWindowParent(pWin),
+ pWin->origin.x - wBorderWidth(pWin),
+ pWin->origin.y - wBorderWidth(pWin));
+ xnestWindowPriv(pWin)->parent = xnestWindowParent(pWin);
+ xnestWindowPriv(pWin)->x = pWin->origin.x - wBorderWidth(pWin);
+ xnestWindowPriv(pWin)->y = pWin->origin.y - wBorderWidth(pWin);
+ xnestWindowPriv(pWin)->sibling_above = None;
+ if (pWin->nextSib)
+ xnestWindowPriv(pWin->nextSib)->sibling_above = xnestWindow(pWin);
+ }
+
+ valuemask = 0;
+
+ if (mask & CWX &&
+ xnestWindowPriv(pWin)->x != pWin->origin.x - wBorderWidth(pWin)) {
+ valuemask |= CWX;
+ values.x =
+ xnestWindowPriv(pWin)->x =
+ pWin->origin.x - wBorderWidth(pWin);
+ }
+
+ if (mask & CWY &&
+ xnestWindowPriv(pWin)->y != pWin->origin.y - wBorderWidth(pWin)) {
+ valuemask |= CWY;
+ values.y =
+ xnestWindowPriv(pWin)->y =
+ pWin->origin.y - wBorderWidth(pWin);
+ }
+
+ if (mask & CWWidth &&
+ xnestWindowPriv(pWin)->width != pWin->drawable.width) {
+ valuemask |= CWWidth;
+ values.width =
+ xnestWindowPriv(pWin)->width =
+ pWin->drawable.width;
+ }
+
+ if (mask & CWHeight &&
+ xnestWindowPriv(pWin)->height != pWin->drawable.height) {
+ valuemask |= CWHeight;
+ values.height =
+ xnestWindowPriv(pWin)->height =
+ pWin->drawable.height;
+ }
+
+ if (mask & CWBorderWidth &&
+ xnestWindowPriv(pWin)->border_width != pWin->borderWidth) {
+ valuemask |= CWBorderWidth;
+ values.border_width =
+ xnestWindowPriv(pWin)->border_width =
+ pWin->borderWidth;
+ }
+
+ if (valuemask)
+ XConfigureWindow(xnestDisplay, xnestWindow(pWin), valuemask, &values);
+
+ if (mask & CWStackingOrder &&
+ xnestWindowPriv(pWin)->sibling_above != xnestWindowSiblingAbove(pWin)) {
+ WindowPtr pSib;
+
+ /* find the top sibling */
+ for (pSib = pWin; pSib->prevSib != NullWindow; pSib = pSib->prevSib);
+
+ /* the top sibling */
+ valuemask = CWStackMode;
+ values.stack_mode = Above;
+ XConfigureWindow(xnestDisplay, xnestWindow(pSib), valuemask, &values);
+ xnestWindowPriv(pSib)->sibling_above = None;
+
+ /* the rest of siblings */
+ for (pSib = pSib->nextSib; pSib != NullWindow; pSib = pSib->nextSib) {
+ valuemask = CWSibling | CWStackMode;
+ values.sibling = xnestWindowSiblingAbove(pSib);
+ values.stack_mode = Below;
+ XConfigureWindow(xnestDisplay, xnestWindow(pSib), valuemask, &values);
+ xnestWindowPriv(pSib)->sibling_above = xnestWindowSiblingAbove(pSib);
+ }
+ }
+}
+
+Bool xnestChangeWindowAttributes(pWin, mask)
+ WindowPtr pWin;
+ unsigned long mask;
+{
+ XSetWindowAttributes attributes;
+
+ if (mask & CWBackPixmap)
+ switch (pWin->backgroundState) {
+ case None:
+ attributes.background_pixmap = None;
+ break;
+
+ case ParentRelative:
+ attributes.background_pixmap = ParentRelative;
+ break;
+
+ case BackgroundPixmap:
+ attributes.background_pixmap = xnestPixmap(pWin->background.pixmap);
+ break;
+
+ case BackgroundPixel:
+ mask &= ~CWBackPixmap;
+ break;
+ }
+
+ if (mask & CWBackPixel)
+ if (pWin->backgroundState == BackgroundPixel)
+ attributes.background_pixel = xnestPixel(pWin->background.pixel);
+ else
+ mask &= ~CWBackPixel;
+
+ if (mask & CWBorderPixmap)
+ if (pWin->borderIsPixel)
+ mask &= ~CWBorderPixmap;
+ else
+ attributes.border_pixmap = xnestPixmap(pWin->border.pixmap);
+
+ if (mask & CWBorderPixel)
+ if (pWin->borderIsPixel)
+ attributes.border_pixel = xnestPixel(pWin->border.pixel);
+ else
+ mask &= ~CWBorderPixel;
+
+ if (mask & CWBitGravity)
+ attributes.bit_gravity = pWin->bitGravity;
+
+ if (mask & CWWinGravity) /* dix does this for us */
+ mask &= ~CWWinGravity;
+
+ if (mask & CWBackingStore) /* this is really not useful */
+ mask &= ~CWBackingStore;
+
+ if (mask & CWBackingPlanes) /* this is really not useful */
+ mask &= ~CWBackingPlanes;
+
+ if (mask & CWBackingPixel) /* this is really not useful */
+ mask &= ~CWBackingPixel;
+
+ if (mask & CWOverrideRedirect)
+ attributes.override_redirect = pWin->overrideRedirect;
+
+ if (mask & CWSaveUnder) /* this is really not useful */
+ mask &= ~CWSaveUnder;
+
+ if (mask & CWEventMask) /* events are handled elsewhere */
+ mask &= ~CWEventMask;
+
+ if (mask & CWDontPropagate) /* events are handled elsewhere */
+ mask &= ~CWDontPropagate;
+
+ if (mask & CWColormap) {
+ ColormapPtr pCmap;
+
+ pCmap = (ColormapPtr)LookupIDByType(wColormap(pWin), RT_COLORMAP);
+
+ attributes.colormap = xnestColormap(pCmap);
+
+ xnestSetInstalledColormapWindows(pWin->drawable.pScreen);
+ }
+
+ if (mask & CWCursor) /* this is handeled in cursor code */
+ mask &= ~CWCursor;
+
+ if (mask)
+ XChangeWindowAttributes(xnestDisplay, xnestWindow(pWin),
+ mask, &attributes);
+
+ return True;
+}
+
+Bool xnestRealizeWindow(pWin)
+ WindowPtr pWin;
+{
+ xnestConfigureWindow(pWin, CWStackingOrder);
+#ifdef SHAPE
+ xnestShapeWindow(pWin);
+#endif /* SHAPE */
+ XMapWindow(xnestDisplay, xnestWindow(pWin));
+
+ return True;
+}
+
+Bool xnestUnrealizeWindow(pWin)
+ WindowPtr pWin;
+{
+ XUnmapWindow(xnestDisplay, xnestWindow(pWin));
+
+ return True;
+}
+
+void xnestPaintWindowBackground(pWin, pRegion, what)
+ WindowPtr pWin;
+ RegionPtr pRegion;
+ int what;
+{
+ int i;
+ BoxPtr pBox;
+
+ xnestConfigureWindow(pWin, CWWidth | CWHeight);
+
+ pBox = REGION_RECTS(pRegion);
+ for (i = 0; i < REGION_NUM_RECTS(pRegion); i++)
+ XClearArea(xnestDisplay, xnestWindow(pWin),
+ pBox[i].x1 - pWin->drawable.x,
+ pBox[i].y1 - pWin->drawable.y,
+ pBox[i].x2 - pBox[i].x1,
+ pBox[i].y2 - pBox[i].y1,
+ False);
+}
+
+void xnestPaintWindowBorder(pWin, pRegion, what)
+ WindowPtr pWin;
+ RegionPtr pRegion;
+ int what;
+{
+ xnestConfigureWindow(pWin, CWBorderWidth);
+}
+
+void xnestCopyWindow(pWin, oldOrigin, oldRegion)
+ WindowPtr pWin;
+ xPoint oldOrigin;
+ RegionPtr oldRegion;
+{
+}
+
+void xnestClipNotify(pWin, dx, dy)
+ WindowPtr pWin;
+ int dx, dy;
+{
+ xnestConfigureWindow(pWin, CWStackingOrder);
+#ifdef SHAPE
+ xnestShapeWindow(pWin);
+#endif /* SHAPE */
+}
+
+static Bool xnestWindowExposurePredicate(display, event, ptr)
+ Display *display;
+ XEvent *event;
+ XPointer ptr;
+{
+ return (event->type == Expose && event->xexpose.window == *(Window *)ptr);
+}
+
+void xnestWindowExposures(pWin, pRgn, other_exposed)
+ WindowPtr pWin;
+ RegionPtr pRgn, other_exposed;
+{
+ XEvent event;
+ Window window;
+ BoxRec Box;
+
+ XSync(xnestDisplay, False);
+
+ window = xnestWindow(pWin);
+
+ while (XCheckIfEvent(xnestDisplay, &event,
+ xnestWindowExposurePredicate, (char *)&window)) {
+
+ Box.x1 = pWin->drawable.x + wBorderWidth(pWin) + event.xexpose.x;
+ Box.y1 = pWin->drawable.y + wBorderWidth(pWin) + event.xexpose.y;
+ Box.x2 = Box.x1 + event.xexpose.width;
+ Box.y2 = Box.y1 + event.xexpose.height;
+
+ event.xexpose.type = ProcessedExpose;
+
+ if (RECT_IN_REGION(pWin->drawable.pScreen, pRgn, &Box) != rgnIN)
+ XPutBackEvent(xnestDisplay, &event);
+ }
+
+ miWindowExposures(pWin, pRgn, other_exposed);
+}
+
+#ifdef SHAPE
+static Bool xnestRegionEqual(pReg1, pReg2)
+ RegionPtr pReg1, pReg2;
+{
+ BoxPtr pBox1, pBox2;
+ unsigned int n1, n2;
+
+ if (pReg1 == pReg2) return True;
+
+ if (pReg1 == NullRegion || pReg2 == NullRegion) return False;
+
+ pBox1 = REGION_RECTS(pReg1);
+ n1 = REGION_NUM_RECTS(pReg1);
+
+ pBox2 = REGION_RECTS(pReg2);
+ n2 = REGION_NUM_RECTS(pReg2);
+
+ if (n1 != n2) return False;
+
+ if (pBox1 == pBox2) return True;
+
+ if (memcmp(pBox1, pBox2, n1 * sizeof(BoxRec))) return False;
+
+ return True;
+}
+
+void xnestShapeWindow(pWin)
+ WindowPtr pWin;
+{
+ Region reg;
+ BoxPtr pBox;
+ XRectangle rect;
+ int i;
+ Bool overlap;
+
+ if (!xnestRegionEqual(xnestWindowPriv(pWin)->bounding_shape,
+ wBoundingShape(pWin))) {
+
+ if (wBoundingShape(pWin)) {
+ REGION_COPY(pWin->drawable.pScreen,
+ xnestWindowPriv(pWin)->bounding_shape, wBoundingShape(pWin));
+
+ reg = XCreateRegion();
+ pBox = REGION_RECTS(xnestWindowPriv(pWin)->bounding_shape);
+ for (i = 0;
+ i < REGION_NUM_RECTS(xnestWindowPriv(pWin)->bounding_shape);
+ i++) {
+ rect.x = pBox[i].x1;
+ rect.y = pBox[i].y1;
+ rect.width = pBox[i].x2 - pBox[i].x1;
+ rect.height = pBox[i].y2 - pBox[i].y1;
+ XUnionRectWithRegion(&rect, reg, reg);
+ }
+ XShapeCombineRegion(xnestDisplay, xnestWindow(pWin),
+ ShapeBounding, 0, 0, reg, ShapeSet);
+ XDestroyRegion(reg);
+ }
+ else {
+ REGION_EMPTY(pWin->drawable.pScreen,
+ xnestWindowPriv(pWin)->bounding_shape);
+
+ XShapeCombineMask(xnestDisplay, xnestWindow(pWin),
+ ShapeBounding, 0, 0, None, ShapeSet);
+ }
+ }
+
+ if (!xnestRegionEqual(xnestWindowPriv(pWin)->clip_shape,
+ wClipShape(pWin))) {
+
+ if (wClipShape(pWin)) {
+ REGION_COPY(pWin->drawable.pScreen,
+ xnestWindowPriv(pWin)->clip_shape, wClipShape(pWin));
+
+ reg = XCreateRegion();
+ pBox = REGION_RECTS(xnestWindowPriv(pWin)->clip_shape);
+ for (i = 0;
+ i < REGION_NUM_RECTS(xnestWindowPriv(pWin)->clip_shape);
+ i++) {
+ rect.x = pBox[i].x1;
+ rect.y = pBox[i].y1;
+ rect.width = pBox[i].x2 - pBox[i].x1;
+ rect.height = pBox[i].y2 - pBox[i].y1;
+ XUnionRectWithRegion(&rect, reg, reg);
+ }
+ XShapeCombineRegion(xnestDisplay, xnestWindow(pWin),
+ ShapeClip, 0, 0, reg, ShapeSet);
+ XDestroyRegion(reg);
+ }
+ else {
+ REGION_EMPTY(pWin->drawable.pScreen,
+ xnestWindowPriv(pWin)->clip_shape);
+
+ XShapeCombineMask(xnestDisplay, xnestWindow(pWin),
+ ShapeClip, 0, 0, None, ShapeSet);
+ }
+ }
+}
+#endif /* SHAPE */
diff --git a/xc/programs/Xserver/hw/xnest/XNFont.h b/xc/programs/Xserver/hw/xnest/XNFont.h
new file mode 100644
index 000000000..87cbebf05
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/XNFont.h
@@ -0,0 +1,36 @@
+/* $XConsortium: Font.h,v 1.1 93/07/12 15:28:20 rws Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+
+#ifndef XNESTFONT_H
+#define XNESTFONT_H
+
+typedef struct {
+ XFontStruct *font_struct;
+} xnestPrivFont;
+
+extern int xnestFontPrivateIndex;
+
+#define xnestFontPriv(pFont) \
+ ((xnestPrivFont *)FontGetPrivate(pFont, xnestFontPrivateIndex))
+
+#define xnestFontStruct(pFont) (xnestFontPriv(pFont)->font_struct)
+
+#define xnestFont(pFont) (xnestFontStruct(pFont)->fid)
+
+Bool xnestRealizeFont();
+Bool xnestUnrealizeFont();
+
+#endif /* XNESTFONT_H */
diff --git a/xc/programs/Xserver/hw/xnest/XNGC.h b/xc/programs/Xserver/hw/xnest/XNGC.h
new file mode 100644
index 000000000..51adb69d2
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/XNGC.h
@@ -0,0 +1,43 @@
+/* $XConsortium: GC.h,v 1.1 93/07/12 15:28:24 rws Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef XNESTGC_H
+#define XNESTGC_H
+
+/* This file uses the GC definition form Xlib.h as XlibGC. */
+
+typedef struct {
+ XlibGC gc;
+ int nClipRects;
+} xnestPrivGC;
+
+extern int xnestGCPrivateIndex;
+
+#define xnestGCPriv(pGC) \
+ ((xnestPrivGC *)((pGC)->devPrivates[xnestGCPrivateIndex].ptr))
+
+#define xnestGC(pGC) (xnestGCPriv(pGC)->gc)
+
+Bool xnestCreateGC();
+void xnestValidateGC();
+void xnestChangeGC();
+void xnestCopyGC();
+void xnestDestroyGC();
+void xnestChangeClip();
+void xnestDestroyClip();
+void xnestDestroyClipHelper();
+void xnestCopyClip();
+
+#endif /* XNESTGC_H */
diff --git a/xc/programs/Xserver/hw/xnest/XNWindow.h b/xc/programs/Xserver/hw/xnest/XNWindow.h
new file mode 100644
index 000000000..9b96804a9
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/XNWindow.h
@@ -0,0 +1,79 @@
+/* $XConsortium: Window.h,v 1.1 93/07/12 15:28:58 rws Exp $ */
+/*
+
+Copyright 1993 by Davor Matic
+
+Permission to use, copy, modify, distribute, and sell this software
+and its documentation for any purpose is hereby granted without fee,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifndef XNESTWINDOW_H
+#define XNESTWINDOW_H
+
+typedef struct {
+ Window window;
+ Window parent;
+ int x;
+ int y;
+ unsigned int width;
+ unsigned int height;
+ unsigned int border_width;
+ Window sibling_above;
+#ifdef SHAPE
+ RegionPtr bounding_shape;
+ RegionPtr clip_shape;
+#endif /* SHAPE */
+} xnestPrivWin;
+
+typedef struct {
+ WindowPtr pWin;
+ Window window;
+} xnestWindowMatch;
+
+extern int xnestWindowPrivateIndex;
+
+#define xnestWindowPriv(pWin) \
+ ((xnestPrivWin *)((pWin)->devPrivates[xnestWindowPrivateIndex].ptr))
+
+#define xnestWindow(pWin) (xnestWindowPriv(pWin)->window)
+
+#define xnestWindowParent(pWin) \
+ ((pWin)->parent ? \
+ xnestWindow((pWin)->parent) : \
+ xnestDefaultWindows[pWin->drawable.pScreen->myNum])
+
+#define xnestWindowSiblingAbove(pWin) \
+ ((pWin)->prevSib ? xnestWindow((pWin)->prevSib) : None)
+
+#define xnestWindowSiblingBelow(pWin) \
+ ((pWin)->nextSib ? xnestWindow((pWin)->nextSib) : None)
+
+#define CWParent CWSibling
+#define CWStackingOrder CWStackMode
+
+extern WindowPtr *WindowTable;
+
+WindowPtr xnestWindowPtr();
+Bool xnestCreateWindow();
+Bool xnestDestroyWindow();
+Bool xnestPositionWindow();
+void xnestConfigureWindow();
+Bool xnestChangeWindowAttributes();
+Bool xnestRealizeWindow();
+Bool xnestUnrealizeWindow();
+void xnestPaintWindowBackground();
+void xnestPaintWindowBorder();
+void xnestCopyWindow();
+void xnestClipNotify();
+void xnestWindowExposures();
+#ifdef SHAPE
+void xnestShapeWindow();
+#endif /* SHAPE */
+
+#endif /* XNESTWINDOW_H */
diff --git a/xc/programs/Xserver/hw/xnest/Xnest.h b/xc/programs/Xserver/hw/xnest/Xnest.h
new file mode 100644
index 000000000..c61a1154f
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Xnest.h
@@ -0,0 +1,95 @@
+/* $XConsortium: Xnest.h,v 1.1 95/07/10 17:43:42 ray Exp $ */
+/*
+
+Copyright (c) 1995 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+*/
+
+/*
+** Machines with a 64 bit library interface and a 32 bit server require
+** name changes to protect the guilty.
+*/
+#ifdef _XSERVER64
+#define _XSERVER64_tmp
+#undef _XSERVER64
+typedef unsigned long XID64;
+typedef unsigned long Mask64;
+typedef unsigned long Atom64;
+typedef unsigned long VisualID64;
+typedef unsigned long Time64;
+#define XID XID64
+#define Mask Mask64
+#define Atom Atom64
+#define VisualID VisualID64
+#define Time Time64
+typedef XID Window64;
+typedef XID Drawable64;
+typedef XID Font64;
+typedef XID Pixmap64;
+typedef XID Cursor64;
+typedef XID Colormap64;
+typedef XID GContext64;
+typedef XID KeySym64;
+#define Window Window64
+#define Drawable Drawable64
+#define Font Font64
+#define Pixmap Pixmap64
+#define Cursor Cursor64
+#define Colormap Colormap64
+#define GContext GContext64
+#define KeySym KeySym64
+#endif /*_XSERVER64*/
+
+#define GC XlibGC
+#include "Xlib.h"
+#include "Xutil.h"
+#include <X11/extensions/shape.h>
+#undef GC
+
+#ifdef _XSERVER64_tmp
+#define _XSERVER64
+#undef _XSERVER64_tmp
+#undef XID
+#undef Mask
+#undef Atom
+#undef VisualID
+#undef Time
+#undef Window
+#undef Drawable
+#undef Font
+#undef Pixmap
+#undef Cursor
+#undef Colormap
+#undef GContext
+#undef KeySym
+#endif /*_XSERVER64_tmp*/
+
+
+
+
+
+
diff --git a/xc/programs/Xserver/hw/xnest/Xnest.man b/xc/programs/Xserver/hw/xnest/Xnest.man
new file mode 100644
index 000000000..e4009b662
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/Xnest.man
@@ -0,0 +1,261 @@
+.\" $TOG: Xnest.man /main/7 1997/11/04 21:21:03 kaleb $
+.\" Copyright (c) 1993, 1994 X Consortium
+.\"
+.\" Permission is hereby granted, free of charge, to any person obtaining
+.\" a copy of this software and associated documentation files (the
+.\" "Software"), to deal in the Software without restriction, including
+.\" without limitation the rights to use, copy, modify, merge, publish,
+.\" distribute, sublicense, and/or sell copies of the Software, and to
+.\" permit persons to whom the Software is furnished to do so, subject to
+.\" the following conditions:
+.\"
+.\" The above copyright notice and this permission notice shall be included
+.\" in all copies or substantial portions of the Software.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+.\" IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+.\" OTHER DEALINGS IN THE SOFTWARE.
+.\"
+.\" Except as contained in this notice, the name of the X Consortium shall
+.\" not be used in advertising or otherwise to promote the sale, use or
+.\" other dealings in this Software without prior written authorization
+.\" from the X Consortium.
+.TH XNEST 1 "Release 6.4" "X Version 11"
+.SH NAME
+Xnest \- a nested X server
+.SH SYNOPSIS
+.B Xnest
+[-options]
+.SH DESCRIPTION
+\fIXnest\fP is a client and a server. \fIXnest\fP is a client of the
+real server which manages windows and graphics requests on its behalf.
+\fIXnest\fP is a server to its own clients. \fIXnest\fP manages
+windows and graphics requests on their behalf. To these clients
+\fIXnest\fP appears to be a conventional server.
+.SH OPTIONS
+\fIXnest\fP supports all standard options of the sample server
+implementation. For more details, please see the manual page on your
+system for \fIXserver\fP. The following additional arguments are
+supported as well.
+.TP 4
+.B \-display \fIstring\fP
+This option specifies the display name of the real server that
+\fIXnest\fP should try to connect with. If it is not provided on the
+command line \fIXnest\fP will read the \fIDISPLAY\fP environment
+variable in order to find out the same information.
+.TP 4
+.B \-sync
+This option tells \fIXnest\fP to synchronize its window and graphics
+operations with the real server. This is a useful option for
+debugging, but it will slow down the performance considerably. It
+should not be used unless absolutely necessary.
+.TP 4
+.B \-full
+This option tells \fIXnest\fP to utilize full regeneration of real
+server objects and reopen a new connection to the real server each
+time the nested server regenerates. The sample server implementation
+regenerates all objects in the server when the last client of this
+server terminates. When this happens, \fIXnest\fP by default
+maintains the same top level window and the same real server
+connection in each new generation. If the user selects full
+regeneration, even the top level window and the connection to the real
+server will be regenerated for each server generation.
+.TP 4
+.B \-class \fIstring\fP
+This option specifies the default visual class of the nested server.
+It is similar to the \fI-cc\fP option from the set of standard options
+except that it will accept a string rather than a number for the
+visual class specification. The string must be one of the following
+six values: \fIStaticGray\fP, \fIGrayScale\fP, \fIStaticColor\fP,
+\fIPseudoColor\fP, \fITrueColor\fP, or \fIDirectColor\fP. If both,
+\fI-class\fP and \fI-cc\fP options are specified, the last instance of
+either option assumes precedence. The class of the default visual of
+the nested server need not be the same as the class of the default
+visual of the real server; although, it has to be supported by the
+real server. See \fIxdpyinfo\fP for a list of supported visual
+classes on the real server before starting \fIXnest\fP. If the user
+chooses a static class, all the colors in the default colormap will be
+preallocated. If the user chooses a dynamic class, colors in the
+default colormap will be available to individual clients for
+allocation.
+.TP 4
+.B \-depth \fIint\fP
+This option specifies the default visual depth of the nested server.
+The depth of the default visual of the nested server need not be the
+same as the depth of the default visual of the real server; although,
+it has to be supported by the real server. See \fIxdpyinfo\fP for a
+list of supported visual depths on the real server before starting
+\fIXnest\fP.
+.TP 4
+.B \-sss
+This option tells \fIXnest\fP to use the software screen saver. By
+default \fIXnest\fP will use the screen saver that corresponds to the
+hardware screen saver in the real server. Of course, even this screen
+saver is software generated since \fIXnest\fP does not control any
+actual hardware. However, it is treated as a hardware screen saver
+within the sample server code.
+.TP 4
+.B \-geometry \fIW+H+X+Y\fP
+This option specifies geometry parameters for the top level
+\fIXnest\fP windows. These windows corresponds to the root windows of
+the nested server. The width and height specified with this option
+will be the maximum width and height of each top level \fIXnest\fP
+window. \fIXnest\fP will allow the user to make any top level window
+smaller, but it will not actually change the size of the nested server
+root window. As of yet, there is no mechanism within the sample
+server implementation to change the size of the root window after
+screen initialization. In order to do so, one would probably need to
+extend the X protocol. Therefore, it is not likely that this will be
+available any time soon. If this option is not specified \fIXnest\fP
+will choose width and height to be 3/4 of the dimensions of the root
+window of the real server.
+.TP 4
+.B \-bw \fIint\fP
+This option specifies the border width of the top level \fIXnest\fP
+window. The integer parameter must be a positive number. The default
+border width is 1.
+.TP 4
+.B \-name \fIstring\fP
+This option specifies the name of the top level \fIXnest\fP window.
+The default value is the program name.
+.TP 4
+.B \-scrns \fIint\fP
+This option specifies the number of screens to create in the nested
+server. For each screen, \fIXnest\fP will create a separate top level
+window. Each screen is referenced by the number after the dot in the
+client display name specification. For example, \fIxterm -display
+:1.1\fP will open an \fIxterm\fP client in the nested server with the
+display number \fI:1\fP on the second screen. The number of screens
+is limited by the hard coded constant in the server sample code which
+is usually 3.
+.TP 4
+.B \-install
+This option tells \fIXnest\fP to do its own colormap installation by
+bypassing the real window manager. For it to work properly the user
+will probably have to temporarily quit the real window manager. By
+default \fIXnest\fP will keep the nested client window whose colormap
+should be installed in the real server in the
+\fIWM\_COLORMAP\_WINDOWS\fP property of the top level \fIXnest\fP
+window. If this colormap is of the same visual type as the root
+window of the nested server, \fIXnest\fP will associate this colormap
+with the top level \fIXnest\fP window as well. Since this does not
+have to be the case, window managers should look primarily at the
+\fIWM\_COLORMAP\_WINDOWS\fP property rather than the colormap
+associated with the top level \fIXnest\fP window. Unfortunately,
+window managers are not very good at doing that yet so this option
+might come in handy.
+.TP 4
+.B \-parent \fIwindow_id\fP
+This option tells \fIXnest\fP to use the \fIwindow_id\fP as the
+root window instead of creating a window. This option is used
+by the xrx xnestplugin.
+.SH USAGE
+Starting up \fIXnest\fP is as simple as starting up \fIxclock\fP from
+a terminal emulator. If a user wishes to run \fIXnest\fP on the same
+workstation as the real server, it is important that the nested server
+is given its own listening socket address. Therefore, if there is a
+server already running on the user's workstation, \fIXnest\fP will
+have to be started up with a new display number. Since there is
+usually no more than one server running on a workstation, specifying
+\fIXnest :1\fP on the command line will be sufficient for most users.
+For each server running on the workstation the display number needs to
+be incremented by one. Thus, if you wish to start another
+\fIXnest\fP, you will need to type \fIXnest :2\fP on the command line.
+.PP
+To run clients in the nested server each client needs to be given the
+same display number as the nested server. For example, \fIxterm
+-display :1\fP will start up an \fIxterm\fP in the first nested server
+and \fIxterm -display :2\fP will start an \fIxterm\fP in the second
+nested server from the example above. Additional clients can be
+started from these \fIxterm\fPs in each nested server.
+.SH XNEST AS A CLIENT
+\fIXnest\fP behaves and looks to the real server and other real
+clients as another real client. It is a rather demanding client,
+however, since almost any window or graphics request from a nested
+client will result in a window or graphics request from \fIXnest\fP to
+the real server. Therefore, it is desirable that \fIXnest\fP and the
+real server are on a local network, or even better, on the same
+machine. As of now, \fIXnest\fP assumes that the real server supports
+the shape extension. There is no way to turn off this assumption
+dynamically. \fIXnest\fP can be compiled without the shape extension
+built in, and in that case the real server need not support it. The
+dynamic shape extension selection support should be considered in
+further development of \fIXnest\fP.
+.PP
+Since \fIXnest\fP need not use the same default visual as the the real
+server, the top level window of the \fIXnest\fP client always has its
+own colormap. This implies that other windows' colors will not be
+displayed properly while the keyboard or pointer focus is in the
+\fIXnest\fP window, unless the real server has support for more than
+one installed colormap at any time. The colormap associated with the
+top window of the \fIXnest\fP client need not be the appropriate
+colormap that the nested server wants installed in the real server.
+In the case that a nested client attempts to install a colormap of a
+different visual from the default visual of the nested server,
+\fIXnest\fP will put the top window of this nested client and all
+other top windows of the nested clients that use the same colormap
+into the \fIWM\_COLORMAP\_WINDOWS\fP property of the top level
+\fIXnest\fP window on the real server. Thus, it is important that the
+real window manager that manages the \fIXnest\fP top level window
+looks at the \fIWM\_COLORMAP\_WINDOWS\fP property rather than the
+colormap associated with the top level \fIXnest\fP window. Since most
+window managers appear to not implement this convention properly as of
+yet, \fIXnest\fP can optionally do direct installation of colormaps
+into the real server bypassing the real window manager. If the user
+chooses this option, it is usually necessary to temporarily disable
+the real window manager since it will interfere with the \fIXnest\fP
+scheme of colormap installation.
+.PP
+Keyboard and pointer control procedures of the nested server change
+the keyboard and pointer control parameters of the real server.
+Therefore, after \fIXnest\fP is started up, it will change the
+keyboard and pointer controls of the real server to its own internal
+defaults. Perhaps there should be a command line option to tell
+\fIXnest\fP to inherit the keyboard and pointer control parameters
+from the real server rather than imposing its own. This is a future
+consideration.
+.SH XNEST AS A SERVER
+\fIXnest\fP as a server looks exactly like a real server to its own
+clients. For the clients there is no way of telling if they are
+running on a real or a nested server.
+.PP
+As already mentioned, \fIXnest\fP is a very user friendly server when
+it comes to customization. \fIXnest\fP will pick up a number of
+command line arguments that can configure its default visual class and
+depth, number of screens, etc. In the future, \fIXnest\fP should read
+a customization input file to provide even greater freedom and
+simplicity in selecting the desired layout. Unfortunately, there is
+no support for backing store and save under as of yet, but this should
+also be considered in the future development of \fIXnest\fP.
+.PP
+The only apparent intricacy from the users' perspective about using
+\fIXnest\fP as a server is the selection of fonts. \fIXnest\fP
+manages fonts by loading them locally and then passing the font name
+to the real server and asking it to load that font remotely. This
+approach avoids the overload of sending the glyph bits across the
+network for every text operation, although it is really a bug. The
+proper implementation of fonts should be moved into the \fIos\fP
+layer. The consequence of this approach is that the user will have to
+worry about two different font paths - a local one for the nested
+server and a remote one for the real server - since \fIXnest\fP does
+not propagate its font path to the real server. The reason for this
+is because real and nested servers need not run on the same file
+system which makes the two font paths mutually incompatible. Thus, if
+there is a font in the local font path of the nested server, there is
+no guarantee that this font exists in the remote font path of the real
+server. \fIXlsfonts\fP client, if run on the nested server will list
+fonts in the local font path and if run on the real server will list
+fonts in the remote font path. Before a font can be successfully
+opened by the nested server it has to exist in local and remote font
+paths. It is the users' responsibility to make sure that this is the
+case.
+.SH BUGS
+Won't run well on servers supporting different visual depths.
+Still crashes randomly. Probably has some memory leaks.
+.SH AUTHOR
+Davor Matic, MIT X Consortium
+
diff --git a/xc/programs/Xserver/hw/xnest/icon b/xc/programs/Xserver/hw/xnest/icon
new file mode 100644
index 000000000..725f1131a
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/icon
@@ -0,0 +1,14 @@
+#define icon_width 32
+#define icon_height 32
+static unsigned char icon_bits[] = {
+ 0xff, 0x00, 0x00, 0xc0, 0xfe, 0x01, 0x00, 0xc0, 0xfc, 0x03, 0x00, 0x60,
+ 0xf8, 0x07, 0x00, 0x30, 0xf8, 0x07, 0x00, 0x18, 0xf0, 0x0f, 0x00, 0x0c,
+ 0xe0, 0x1f, 0x00, 0x06, 0xc0, 0x3f, 0x00, 0x06, 0xc0, 0x3f, 0x00, 0x03,
+ 0x80, 0x7f, 0x80, 0x01, 0x00, 0xff, 0xc0, 0x00, 0x00, 0xfe, 0x61, 0x00,
+ 0x00, 0xfe, 0x31, 0x00, 0x00, 0xfc, 0x33, 0x00, 0x00, 0xf8, 0x1b, 0x00,
+ 0x00, 0xf0, 0x0d, 0x00, 0x00, 0xf0, 0x0e, 0x00, 0x00, 0x60, 0x1f, 0x00,
+ 0x00, 0xb0, 0x3f, 0x00, 0x00, 0x98, 0x7f, 0x00, 0x00, 0x98, 0x7f, 0x00,
+ 0x00, 0x0c, 0xff, 0x00, 0x00, 0x06, 0xfe, 0x01, 0x00, 0x03, 0xfc, 0x03,
+ 0x80, 0x01, 0xfc, 0x03, 0xc0, 0x00, 0xf8, 0x07, 0xc0, 0x00, 0xf0, 0x0f,
+ 0x60, 0x00, 0xe0, 0x1f, 0x30, 0x00, 0xe0, 0x1f, 0x18, 0x00, 0xc0, 0x3f,
+ 0x0c, 0x00, 0x80, 0x7f, 0x06, 0x00, 0x00, 0xff};
diff --git a/xc/programs/Xserver/hw/xnest/os2Stub.c b/xc/programs/Xserver/hw/xnest/os2Stub.c
new file mode 100644
index 000000000..a31172436
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/os2Stub.c
@@ -0,0 +1,386 @@
+/*
+ * (c) Copyright 1996 by Sebastien Marineau
+ * <marineau@genie.uottawa.ca>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HOLGER VEIT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Sebastien Marineau shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Sebastien Marineau.
+ *
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xnest/os2Stub.c,v 3.0 1996/05/13 06:44:20 dawes Exp $ */
+
+/* This below implements select() for calls in xnest. It has been */
+/* somewhat optimized for improved performance, but assumes a few */
+/* things so it cannot be used as a general select. */
+
+#include <stdio.h>
+#include <sys/select.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#define INCL_DOSSEMAPHORES
+#define INCL_DOSNPIPES
+#define INCL_DOSMISC
+#define INCL_DOSMODULEMGR
+#undef BOOL
+#undef BYTE
+#include <os2.h>
+#include "Xpoll.h"
+
+HEV hPipeSem;
+HMODULE hmod_so32dll;
+static int (*os2_tcp_select)(int*,int,int,int,long);
+ULONG os2_get_sys_millis();
+extern int _files[];
+
+#define MAX_TCP 256
+/* These lifted from sys/emx.h. Change if that changes there! */
+#define F_SOCKET 0x10000000
+#define F_PIPE 0x20000000
+
+struct select_data
+{
+ fd_set read_copy;
+ fd_set write_copy;
+ BOOL have_read;
+ BOOL have_write;
+ int tcp_select_mask[MAX_TCP];
+ int tcp_emx_handles[MAX_TCP];
+ int tcp_select_copy[MAX_TCP];
+ int socket_nread;
+ int socket_nwrite;
+ int socket_ntotal;
+ int pipe_ntotal;
+ int pipe_have_write;
+ int max_fds;
+};
+
+int os2PseudoSelect(int nfds, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds, struct timeval *timeout)
+{
+static BOOL FirstTime=TRUE;
+static haveTCPIP=TRUE;
+ULONG timeout_ms;
+ULONG postCount, start_millis,now_millis;
+char faildata[16];
+struct select_data sd;
+BOOL any_ready;
+int np,ns, i,ready_handles,n;
+APIRET rc;
+
+sd.have_read=FALSE; sd.have_write=FALSE;
+sd.socket_nread=0; sd.socket_nwrite=0; sd.socket_ntotal=0;
+sd.max_fds=31; ready_handles=0; any_ready=FALSE;
+sd.pipe_ntotal=0; sd.pipe_have_write=FALSE;
+
+if(FirstTime){
+ /* First load the so32dll.dll module and get a pointer to the SELECT function */
+
+ if((rc=DosLoadModule(faildata,sizeof(faildata),"SO32DLL",&hmod_so32dll))!=0){
+ fprintf(stderr, "Could not load module so32dll.dll, rc = %d. Error note %s\n",rc,faildata);
+ haveTCPIP=FALSE;
+ }
+ if((rc = DosQueryProcAddr(hmod_so32dll, 0, "SELECT", (PPFN)&os2_tcp_select))!=0){
+ fprintf(stderr, "Could not query address of SELECT, rc = %d.\n",rc);
+ haveTCPIP=FALSE;
+ }
+ /* Call these a first time to set the semaphore */
+ /* rc = DosCreateEventSem(NULL, &hPipeSem, DC_SEM_SHARED, FALSE);
+ if(rc) {
+ fprintf(stderr, "Could not create event semaphore, rc=%d\n",rc);
+ return(-1);
+ }
+ rc = DosResetEventSem(hPipeSem, &postCount); */ /* Done in xtrans code for servers*/
+
+fprintf(stderr, "Client select() done first-time stuff, sem handle %d.\n",hPipeSem);
+
+ FirstTime = FALSE;
+}
+
+/* Set up the time delay structs */
+
+ if(timeout!=NULL) {
+ timeout_ms=timeout->tv_sec*1000+timeout->tv_usec/1000;
+ }
+ else { timeout_ms=1000000; } /* This should be large enough... */
+ if(timeout_ms>0) start_millis=os2_get_sys_millis();
+
+/* Copy the masks */
+ {FD_ZERO(&sd.read_copy);}
+ {FD_ZERO(&sd.write_copy);}
+ if(readfds!=NULL){ XFD_COPYSET(readfds,&sd.read_copy); sd.have_read=TRUE;}
+ if(writefds!=NULL) {XFD_COPYSET(writefds,&sd.write_copy);sd.have_write=TRUE;}
+
+/* And zero the original masks */
+ if(sd.have_read){ FD_ZERO(readfds);}
+ if(sd.have_write) {FD_ZERO(writefds);}
+ if(exceptfds != NULL) {FD_ZERO(exceptfds);}
+
+/* Now we parse the fd_sets passed to select and separate pipe/sockets */
+ n = os2_parse_select(&sd,nfds);
+ if(n == -1) {
+ errno = EBADF;
+ return (-1);
+ }
+
+/* Now we have three cases: either we have sockets, pipes, or both */
+/* We handle all three cases differently to optimize things */
+
+/* Case 1: only pipes! */
+ if((sd.pipe_ntotal >0) && (!sd.socket_ntotal)){
+ np = os2_check_pipes(&sd,readfds,writefds);
+ if(np > 0){
+ return (np);
+ }
+ else if (np == -1) { return(-1); }
+ while(!any_ready){
+ rc = DosWaitEventSem(hPipeSem, timeout_ms);
+ /* if(rc) fprintf(stderr,"Sem-wait timeout, rc = %d\n",rc); */
+ if(rc == 640) {
+ return(0);
+ }
+ if((rc != 0) && (rc != 95)) {errno= EBADF; return(-1);}
+ np = os2_check_pipes(&sd,readfds,writefds);
+ if (np > 0){
+ return(np);
+ }
+ else if (np < 0){ return(-1); }
+ }
+ }
+
+/* Case 2: only sockets. Just let the os/2 tcp select do the work */
+ if((sd.socket_ntotal > 0) && (!sd.pipe_ntotal)){
+ ns = os2_check_sockets(&sd, readfds, writefds, timeout_ms);
+ return (ns);
+ }
+
+/* Case 3: combination of both */
+ if((sd.socket_ntotal > 0) && (sd.pipe_ntotal)){
+ np = os2_check_pipes(&sd,readfds,writefds);
+ if(np > 0){
+ any_ready=TRUE;
+ ready_handles += np;
+ }
+ else if (np == -1) { return(-1); }
+
+ ns = os2_check_sockets(&sd,readfds,writefds, 0);
+ if(ns>0){
+ ready_handles+=ns;
+ any_ready = TRUE;
+ }
+ else if (ns == -1) {return(-1);}
+
+ while (!any_ready && timeout_ms){
+
+ rc = DosWaitEventSem(hPipeSem, 10L);
+ if(rc == 0){
+ np = os2_check_pipes(&sd,readfds,writefds);
+ if(np > 0){
+ ready_handles+=np;
+ any_ready = TRUE;
+ }
+ else if (np == -1) {
+ return(-1); }
+ }
+
+ ns = os2_check_sockets(&sd,readfds,writefds,exceptfds, 0);
+ if(ns>0){
+ ready_handles+=ns;
+ any_ready = TRUE;
+ }
+ else if (ns == -1) {return(-1);}
+
+ if (i%8 == 0) {
+ now_millis = os2_get_sys_millis();
+ if((now_millis-start_millis) > timeout_ms) timeout_ms = 0;
+ }
+ i++;
+ }
+ }
+
+return(ready_handles);
+}
+
+
+ULONG os2_get_sys_millis()
+{
+ APIRET rc;
+ ULONG milli;
+
+ rc = DosQuerySysInfo(14, 14, &milli, sizeof(milli));
+ if(rc) {
+ fprintf(stderr,"Bad return code querying the millisecond counter! rc=%d\n",rc);
+ return(0);
+ }
+ return(milli);
+}
+
+int os2_parse_select(sd,nfds)
+struct select_data *sd;
+int nfds;
+{
+ int i;
+ APIRET rc;
+/* First we determine up to which descriptor we need to check. */
+/* No need to check up to 256 if we don't have to (and usually we dont...)*/
+/* Note: stuff here is hardcoded for fd_sets which are int[8] as in EMX! */
+
+ if(nfds > sd->max_fds){
+ for(i=0;i<((FD_SETSIZE+31)/32);i++){
+ if(sd->read_copy.fds_bits[i] ||
+ sd->write_copy.fds_bits[i])
+ sd->max_fds=(i*32) +32;
+ }
+ }
+ else { sd->max_fds = nfds; }
+/* Check if result is greater than specified in select() call */
+ if(sd->max_fds > nfds) sd->max_fds = nfds;
+
+ if (sd->have_read)
+ {
+ for (i = 0; i < sd->max_fds; ++i) {
+ if (FD_ISSET (i, &sd->read_copy)){
+ if(_files[i] & F_SOCKET)
+ {
+ sd->tcp_select_mask[sd->socket_ntotal]=_getsockhandle(i);
+ sd->tcp_emx_handles[sd->socket_ntotal]=i;
+ sd->socket_ntotal++; sd->socket_nread++;
+ }
+ else if (_files[i] & F_PIPE)
+ {
+ sd -> pipe_ntotal++;
+ /* rc = DosSetNPipeSem((HPIPE)i, (HSEM) hPipeSem, i);
+ if(rc) { fprintf(stderr,"Error SETNPIPE rc = %d\n",rc); return -1;} */
+ }
+ }
+ }
+ }
+
+ if (sd->have_write)
+ {
+ for (i = 0; i < sd->max_fds; ++i) {
+ if (FD_ISSET (i, &sd->write_copy)){
+ if(_files[i] & F_SOCKET)
+ {
+ sd->tcp_select_mask[sd->socket_ntotal]=_getsockhandle(i);
+ sd->tcp_emx_handles[sd->socket_ntotal]=i;
+ sd->socket_ntotal++; sd->socket_nwrite++;
+ }
+ else if (_files[i] & F_PIPE)
+ {
+ sd -> pipe_ntotal++;
+ /* rc = DosSetNPipeSem((HPIPE)i, (HSEM) hPipeSem, i);
+ if(rc) { fprintf(stderr,"Error SETNPIPE rc = %d\n",rc); return -1;} */
+ sd -> pipe_have_write=TRUE;
+ }
+ }
+ }
+ }
+
+
+return(sd->socket_ntotal);
+}
+
+
+int os2_check_sockets(sd,readfds,writefds)
+struct select_data *sd;
+fd_set *readfds,*writefds;
+{
+ int e,i;
+ int j,n;
+ memcpy(sd->tcp_select_copy,sd->tcp_select_mask,
+ sd->socket_ntotal*sizeof(int));
+
+ e = os2_tcp_select(sd->tcp_select_copy,sd->socket_nread,
+ sd->socket_nwrite, 0, 0);
+
+ if(e == 0) return(e);
+/* We have something ready? */
+ if(e>0){
+ j = 0; n = 0;
+ for (i = 0; i < sd->socket_nread; ++i, ++j)
+ if (sd->tcp_select_copy[j] != -1)
+ {
+ FD_SET (sd->tcp_emx_handles[j], readfds);
+ n ++;
+ }
+ for (i = 0; i < sd->socket_nwrite; ++i, ++j)
+ if (sd->tcp_select_copy[j] != -1)
+ {
+ FD_SET (sd->tcp_emx_handles[j], writefds);
+ n ++;
+ }
+ errno = 0;
+
+ return n;
+ }
+ if(e<0){
+ /*Error -- TODO. EBADF is a good choice for now. */
+ fprintf(stderr,"Error in server select! e=%d\n",e);
+ errno = EBADF;
+ return (-1);
+ }
+ }
+
+/* Check to see if anything is ready on pipes */
+
+int os2_check_pipes(sd,readfds,writefds)
+struct select_data *sd;
+fd_set *readfds,*writefds;
+{
+int i,e;
+ULONG ulPostCount;
+PIPESEMSTATE pipeSemState[128];
+APIRET rc;
+ e = 0;
+ rc = DosResetEventSem(hPipeSem,&ulPostCount);
+ rc = DosQueryNPipeSemState((HSEM) hPipeSem, (PPIPESEMSTATE)&pipeSemState,
+ sizeof(pipeSemState));
+ if(rc) fprintf(stderr,"SELECT: rc from QueryNPipeSem: %d\n",rc);
+ i=0;
+ while (pipeSemState[i].fStatus != 0) {
+ /*fprintf(stderr,"SELECT: sem entry, stat=%d, flag=%d, key=%d,avail=%d\n",
+ pipeSemState[i].fStatus,pipeSemState[i].fFlag,pipeSemState[i].usKey,
+ pipeSemState[i].usAvail); */
+ if((pipeSemState[i].fStatus == 1) &&
+ (FD_ISSET(pipeSemState[i].usKey,&sd->read_copy))){
+ FD_SET(pipeSemState[i].usKey,readfds);
+ e++;
+ }
+ else if((pipeSemState[i].fStatus == 2) &&
+ (FD_ISSET(pipeSemState[i].usKey,&sd->write_copy))){
+ FD_SET(pipeSemState[i].usKey,writefds);
+ e++;
+ }
+ else if( (pipeSemState[i].fStatus == 3) &&
+ ( (FD_ISSET(pipeSemState[i].usKey,&sd->read_copy)) ||
+ (FD_ISSET(pipeSemState[i].usKey,&sd->write_copy)) )){
+ errno = EBADF;
+ /* fprintf(stderr,"Pipe has closed down, fd=%d\n",pipeSemState[i].usKey); */
+ return (-1);
+ }
+ i++;
+ } /* endwhile */
+ /*fprintf(stderr,"Done listing pipe sem entries, total %d entries, total ready entries %d\n",i,e);*/
+errno = 0;
+return(e);
+}
+
diff --git a/xc/programs/Xserver/hw/xnest/screensaver b/xc/programs/Xserver/hw/xnest/screensaver
new file mode 100644
index 000000000..4940f2650
--- /dev/null
+++ b/xc/programs/Xserver/hw/xnest/screensaver
@@ -0,0 +1,686 @@
+#define screensaver_width 256
+#define screensaver_height 256
+static unsigned char screensaver_bits[] = {
+ 0xa8, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0x00, 0x80, 0x0a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x40, 0x55,
+ 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x55, 0x05, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x80, 0xaa, 0x2a, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0x00, 0xa0,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x15, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x55, 0x05, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0xaa,
+ 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0xaa, 0x0a, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x15, 0x00, 0x50,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xaa, 0x2a, 0x80, 0x02, 0x80, 0xaa, 0xaa, 0x82, 0x0a, 0xa8, 0x28, 0x80,
+ 0x8a, 0x80, 0x2a, 0x80, 0x80, 0x8a, 0xa2, 0x82, 0x0a, 0xaa, 0x0a, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2a, 0x02, 0x80, 0x82, 0x41, 0x40, 0x00, 0x50,
+ 0x55, 0x41, 0x00, 0x00, 0x04, 0x00, 0x54, 0x40, 0x10, 0x00, 0x40, 0x00,
+ 0x51, 0x55, 0x00, 0x15, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x41, 0x00, 0x10, 0x14, 0x00, 0x00, 0x00, 0xa8, 0x8a, 0x02, 0x00, 0x02,
+ 0x00, 0x20, 0xa2, 0x00, 0x80, 0x00, 0x08, 0x00, 0xaa, 0x2a, 0x00, 0x2a,
+ 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80,
+ 0x01, 0x00, 0x01, 0x50, 0x45, 0x05, 0x00, 0x01, 0x10, 0x10, 0x40, 0x11,
+ 0x40, 0x00, 0x44, 0x00, 0x50, 0x15, 0x01, 0x15, 0x04, 0x00, 0x40, 0x00,
+ 0x05, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, 0x50, 0x20, 0x00, 0x00, 0xa2,
+ 0xaa, 0x2a, 0x00, 0x00, 0x02, 0x00, 0xa0, 0x08, 0x00, 0x00, 0x00, 0x00,
+ 0xa2, 0xaa, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x20,
+ 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x01, 0x40, 0x44, 0x15, 0x10, 0x01,
+ 0x10, 0x10, 0x40, 0x01, 0x40, 0x00, 0x00, 0x00, 0x54, 0x55, 0x41, 0x45,
+ 0x04, 0x00, 0x40, 0x00, 0x14, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x54,
+ 0x20, 0x80, 0x00, 0x82, 0xaa, 0x0a, 0x00, 0x00, 0x22, 0x00, 0x80, 0x0a,
+ 0x00, 0x00, 0x82, 0x00, 0xa0, 0x8a, 0x22, 0x02, 0x00, 0x08, 0x20, 0x00,
+ 0xa8, 0x00, 0x00, 0x20, 0x00, 0x80, 0x00, 0x2a, 0x10, 0x40, 0x00, 0x01,
+ 0x54, 0x45, 0x10, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x00,
+ 0x50, 0x45, 0x05, 0x41, 0x00, 0x04, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x15, 0x00, 0x28, 0x00, 0xaa, 0xaa, 0x0a, 0x0a, 0x00,
+ 0x20, 0x08, 0x00, 0x20, 0x00, 0x00, 0x80, 0x00, 0xa8, 0xa2, 0x22, 0x2a,
+ 0x00, 0x00, 0x0a, 0x00, 0xa8, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x0a,
+ 0x50, 0x05, 0x00, 0x01, 0x55, 0x45, 0x00, 0x00, 0x01, 0x00, 0x00, 0x40,
+ 0x01, 0x00, 0x00, 0x00, 0x40, 0x55, 0x11, 0x00, 0x00, 0x54, 0x01, 0x00,
+ 0x44, 0x01, 0x00, 0x00, 0x05, 0x40, 0x00, 0x05, 0x00, 0x08, 0x00, 0x80,
+ 0xaa, 0xaa, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x0a, 0x00, 0x80, 0x00,
+ 0x80, 0xaa, 0x28, 0x20, 0x00, 0x00, 0x02, 0x00, 0x80, 0x02, 0x00, 0x00,
+ 0x28, 0x00, 0x80, 0x02, 0x10, 0x10, 0x00, 0x01, 0x54, 0x45, 0x01, 0x00,
+ 0x41, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x10, 0x55, 0x14, 0x00,
+ 0x00, 0x04, 0x04, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x40, 0x40, 0x01,
+ 0x08, 0x00, 0x80, 0x00, 0xa8, 0xa2, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0xa0, 0xaa, 0x00, 0x80, 0x28, 0x0a, 0x00, 0x00, 0x02, 0x00, 0x00,
+ 0x80, 0x02, 0x00, 0x00, 0x80, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x14, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x00, 0x40, 0x00, 0x00, 0x08, 0x20, 0x80, 0x00, 0x08, 0x08, 0x80, 0x80,
+ 0x80, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x8a, 0x00,
+ 0x02, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01,
+ 0x10, 0x10, 0x00, 0x01, 0x10, 0x45, 0x55, 0x01, 0x00, 0x00, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00,
+ 0x20, 0xa2, 0xaa, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x80, 0x00, 0x02, 0x04, 0x00, 0x40, 0x00, 0x04, 0x04, 0x40, 0x40,
+ 0x00, 0x01, 0x00, 0x04, 0x04, 0x00, 0x00, 0x01, 0x00, 0x51, 0x45, 0x05,
+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x45, 0x01,
+ 0x2a, 0x80, 0xaa, 0xaa, 0x82, 0xaa, 0x2a, 0xa0, 0x02, 0x02, 0x80, 0xa8,
+ 0x00, 0x2a, 0xa0, 0x02, 0x80, 0xa2, 0x00, 0xa0, 0xa0, 0x0a, 0xa0, 0x00,
+ 0x00, 0x00, 0x80, 0x88, 0x02, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x50, 0x41, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xa0, 0xaa, 0x0a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x20, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x40, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x2a, 0x80, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x55, 0x55,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x05, 0x00, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa0, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x54, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x15, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0xa8, 0xaa,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x50, 0x55, 0x05, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x15, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x00, 0x00, 0xa8, 0xaa, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x2a, 0x20, 0x00, 0x00, 0x41, 0x05, 0x55, 0x54, 0x11, 0x04, 0x00, 0x14,
+ 0x40, 0x10, 0x44, 0x15, 0x15, 0x00, 0x00, 0x50, 0x01, 0x00, 0x50, 0x55,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x10, 0x50, 0x40,
+ 0x82, 0x08, 0x02, 0x08, 0x20, 0x08, 0x00, 0x22, 0xa0, 0x20, 0x88, 0x00,
+ 0x22, 0x00, 0x00, 0xa8, 0x2a, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x80, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0xaa, 0x08, 0x88, 0x20, 0x44, 0x10, 0x01, 0x04,
+ 0x50, 0x04, 0x00, 0x41, 0x10, 0x11, 0x44, 0x00, 0x41, 0x00, 0x00, 0x54,
+ 0x41, 0x00, 0x40, 0x55, 0x15, 0x00, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x54, 0x11, 0x04, 0x11, 0x80, 0x20, 0x02, 0x08, 0xa0, 0x08, 0x00, 0x02,
+ 0x88, 0x20, 0x88, 0x00, 0x82, 0x00, 0x00, 0x2a, 0x22, 0x00, 0x80, 0xaa,
+ 0x2a, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x08, 0x20,
+ 0x40, 0x10, 0x01, 0x04, 0x50, 0x04, 0x00, 0x01, 0x04, 0x41, 0x44, 0x00,
+ 0x41, 0x00, 0x00, 0x15, 0x05, 0x14, 0x15, 0x50, 0x10, 0x05, 0x40, 0x41,
+ 0x41, 0x10, 0x45, 0x05, 0x50, 0x04, 0x04, 0x10, 0x80, 0x20, 0x02, 0x08,
+ 0xa0, 0x08, 0x00, 0x02, 0x08, 0x22, 0x82, 0x00, 0x82, 0x00, 0x00, 0x0a,
+ 0x2a, 0x22, 0x8a, 0x22, 0x22, 0x08, 0x80, 0x22, 0x22, 0x88, 0x88, 0x02,
+ 0x28, 0x02, 0x08, 0x20, 0x40, 0x10, 0x15, 0x54, 0x10, 0x05, 0x00, 0x14,
+ 0x04, 0x41, 0x44, 0x05, 0x41, 0x00, 0x00, 0x05, 0x50, 0x01, 0x41, 0x04,
+ 0x05, 0x11, 0x00, 0x05, 0x44, 0x44, 0x50, 0x00, 0x10, 0x05, 0x50, 0x10,
+ 0x80, 0x0a, 0x02, 0x08, 0x20, 0x0a, 0x00, 0x20, 0xa8, 0x82, 0x82, 0x00,
+ 0x2a, 0x00, 0x80, 0x02, 0x22, 0x02, 0x82, 0x20, 0x20, 0x08, 0x20, 0x88,
+ 0x82, 0x88, 0x8a, 0x00, 0x88, 0x0a, 0x80, 0x20, 0x40, 0x04, 0x01, 0x04,
+ 0x10, 0x05, 0x00, 0x40, 0x04, 0x41, 0x41, 0x00, 0x11, 0x00, 0x40, 0x01,
+ 0x41, 0x41, 0x41, 0x14, 0x15, 0x11, 0x40, 0x44, 0x04, 0x44, 0x40, 0x00,
+ 0x44, 0x15, 0x00, 0x11, 0x80, 0x08, 0x02, 0x08, 0x20, 0x0a, 0x00, 0x80,
+ 0x08, 0x82, 0x82, 0x00, 0x22, 0x00, 0xa0, 0x00, 0x22, 0x22, 0x82, 0x20,
+ 0x22, 0x0a, 0x20, 0x28, 0x82, 0x82, 0x88, 0x00, 0x88, 0x2a, 0x00, 0x22,
+ 0x44, 0x10, 0x01, 0x04, 0x10, 0x04, 0x00, 0x41, 0x04, 0x01, 0x41, 0x00,
+ 0x41, 0x00, 0x50, 0x01, 0x14, 0x14, 0x01, 0x55, 0x10, 0x15, 0x40, 0x45,
+ 0x05, 0x01, 0x45, 0x00, 0x04, 0x55, 0x04, 0x11, 0x82, 0x20, 0x02, 0x08,
+ 0x20, 0x08, 0x00, 0x22, 0x08, 0x82, 0x80, 0x00, 0x82, 0x00, 0xa8, 0x00,
+ 0x00, 0x00, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0xaa, 0x88, 0x20, 0x41, 0x10, 0x55, 0x54, 0x11, 0x04, 0x00, 0x14,
+ 0x04, 0x01, 0x41, 0x15, 0x41, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x55, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x54, 0x51, 0x40,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0x2a, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x54, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x15, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x54, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xa8, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00,
+ 0x50, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x15,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x15, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00,
+ 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x14, 0x40, 0x01, 0x41, 0x40, 0x01, 0x14, 0x10, 0x01, 0x00, 0x40,
+ 0x01, 0x04, 0x14, 0x14, 0x14, 0x10, 0x04, 0x00, 0xa0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0a, 0xaa, 0x00, 0x00, 0x00, 0x80, 0x82, 0xa0, 0x20, 0x82,
+ 0xa2, 0x20, 0x02, 0x22, 0x28, 0x02, 0x00, 0x08, 0x8a, 0x22, 0x08, 0x08,
+ 0x22, 0x28, 0x0a, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x54,
+ 0x01, 0x00, 0x00, 0x40, 0x41, 0x40, 0x10, 0x04, 0x11, 0x11, 0x04, 0x41,
+ 0x10, 0x04, 0x00, 0x04, 0x04, 0x40, 0x10, 0x00, 0x41, 0x10, 0x11, 0x00,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xaa, 0x02, 0x00, 0x00, 0xa0,
+ 0x82, 0x80, 0x08, 0x08, 0x02, 0x08, 0x88, 0x80, 0x08, 0x08, 0x00, 0x08,
+ 0x08, 0x20, 0x20, 0x80, 0x80, 0x20, 0x00, 0x00, 0x10, 0x50, 0x14, 0x14,
+ 0x45, 0x05, 0x40, 0x05, 0x41, 0x14, 0x15, 0x50, 0x41, 0x01, 0x04, 0x00,
+ 0x01, 0x04, 0x50, 0x00, 0x11, 0x04, 0x00, 0x14, 0x00, 0x40, 0x10, 0x44,
+ 0x00, 0x11, 0x00, 0x00, 0xa0, 0x88, 0x22, 0xa2, 0x88, 0x08, 0x00, 0x2a,
+ 0x82, 0x22, 0x22, 0xa8, 0x80, 0x0a, 0x08, 0x00, 0x02, 0xa8, 0x8a, 0xaa,
+ 0x08, 0x08, 0x00, 0xa8, 0x00, 0x2a, 0x20, 0x80, 0xaa, 0x20, 0x00, 0x00,
+ 0x00, 0x05, 0x04, 0x15, 0x55, 0x04, 0x40, 0x04, 0x50, 0x54, 0x01, 0x54,
+ 0x00, 0x54, 0x04, 0x00, 0x01, 0x04, 0x40, 0x00, 0x10, 0x04, 0x00, 0x40,
+ 0x05, 0x41, 0x40, 0x40, 0x00, 0x10, 0x00, 0x00, 0x80, 0x08, 0x02, 0x82,
+ 0x80, 0x08, 0x80, 0x20, 0x02, 0x02, 0x02, 0x2a, 0x00, 0xa0, 0x08, 0x00,
+ 0x02, 0x08, 0x80, 0x00, 0x08, 0x08, 0x00, 0x00, 0x8a, 0x20, 0x20, 0x82,
+ 0x00, 0x20, 0x00, 0x00, 0x10, 0x45, 0x04, 0x11, 0x51, 0x04, 0x50, 0x44,
+ 0x44, 0x44, 0x01, 0x15, 0x00, 0x40, 0x05, 0x00, 0x01, 0x04, 0x40, 0x00,
+ 0x10, 0x04, 0x00, 0x00, 0x54, 0x40, 0x40, 0x41, 0x00, 0x10, 0x00, 0x00,
+ 0xa0, 0x28, 0x02, 0x0a, 0x8a, 0x08, 0x20, 0x0a, 0x0a, 0x28, 0x02, 0x0a,
+ 0x00, 0x80, 0x08, 0x00, 0x02, 0x08, 0x80, 0x00, 0x08, 0x08, 0x00, 0x00,
+ 0x88, 0x20, 0x80, 0x80, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x05, 0x40, 0x00, 0x11, 0x00,
+ 0x01, 0x10, 0x10, 0x01, 0x11, 0x04, 0x00, 0x04, 0x50, 0x40, 0x41, 0x01,
+ 0x01, 0x11, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa,
+ 0xaa, 0x00, 0x80, 0x02, 0x80, 0x80, 0x20, 0x02, 0x02, 0x20, 0x08, 0x82,
+ 0x08, 0x08, 0x00, 0x08, 0x88, 0x20, 0x80, 0x00, 0x82, 0x20, 0x00, 0x00,
+ 0x00, 0x40, 0x01, 0x10, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x40, 0x01,
+ 0x40, 0x14, 0x40, 0x41, 0x05, 0x40, 0x01, 0x14, 0x14, 0x14, 0x00, 0x44,
+ 0x01, 0x45, 0x00, 0x00, 0x14, 0x54, 0x00, 0x00, 0x00, 0x80, 0x02, 0x08,
+ 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x04, 0x00, 0x00, 0x00, 0x50,
+ 0x55, 0x05, 0x50, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0a, 0x02, 0x00, 0x00, 0x00, 0xa0, 0xaa, 0x0a, 0xa8, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x01,
+ 0x00, 0x00, 0x00, 0x50, 0x55, 0x05, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0xaa, 0x0a, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x15, 0x15, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0xaa, 0x2a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x55, 0x15, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x8a, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x45, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0xa8, 0xa2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x05, 0x50, 0x00, 0x50, 0x40, 0x45, 0x11, 0x00, 0x50,
+ 0x40, 0x41, 0x01, 0x00, 0x14, 0x00, 0x51, 0x40, 0x40, 0x00, 0x05, 0x14,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x0a,
+ 0x88, 0x02, 0xaa, 0xa8, 0x80, 0x00, 0x00, 0xaa, 0xa8, 0xa2, 0x02, 0x00,
+ 0xa2, 0xa0, 0x22, 0xa8, 0xa0, 0xa0, 0x8a, 0x2a, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x14, 0x04, 0x01, 0x45, 0x51,
+ 0x04, 0x40, 0x00, 0x45, 0x41, 0x51, 0x01, 0x00, 0x41, 0x50, 0x54, 0x50,
+ 0x50, 0x50, 0x14, 0x14, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0x82, 0xa2, 0xa0, 0x02, 0xa0, 0x88, 0x82,
+ 0xa0, 0x88, 0x02, 0x80, 0x82, 0x28, 0x28, 0xa0, 0x20, 0x28, 0x08, 0x8a,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x45, 0x54, 0x00,
+ 0x14, 0x40, 0x41, 0x50, 0x05, 0x51, 0x10, 0x41, 0x41, 0x41, 0x01, 0x00,
+ 0x05, 0x14, 0x10, 0x50, 0x40, 0x10, 0x14, 0x54, 0x04, 0x00, 0x41, 0x55,
+ 0x04, 0x45, 0x01, 0x04, 0x20, 0x02, 0x08, 0x00, 0x2a, 0xa0, 0x00, 0xa0,
+ 0x8a, 0x20, 0xa8, 0xa2, 0xa0, 0xa0, 0x00, 0x80, 0x0a, 0x28, 0x28, 0xa0,
+ 0x20, 0x28, 0x0a, 0x2a, 0x00, 0x00, 0x22, 0x0a, 0x80, 0x88, 0x02, 0x88,
+ 0x04, 0x50, 0x01, 0x00, 0x54, 0x40, 0x01, 0x50, 0x15, 0x10, 0x14, 0x51,
+ 0x40, 0x41, 0x01, 0x00, 0x15, 0x14, 0x14, 0x40, 0x11, 0x14, 0x05, 0x14,
+ 0x00, 0x40, 0x10, 0x00, 0x15, 0x45, 0x04, 0x01, 0x00, 0x00, 0x08, 0x00,
+ 0xa8, 0xa0, 0x00, 0x28, 0x8a, 0x08, 0x0a, 0x28, 0xa0, 0xa0, 0x00, 0x00,
+ 0x2a, 0x0a, 0x28, 0xa0, 0x08, 0x8a, 0x02, 0x0a, 0x00, 0x80, 0x00, 0x08,
+ 0x80, 0x00, 0x00, 0x82, 0x44, 0x11, 0x00, 0x00, 0x50, 0x50, 0x00, 0x10,
+ 0x05, 0x40, 0x15, 0x05, 0x50, 0x50, 0x00, 0x00, 0x14, 0x14, 0x14, 0x40,
+ 0x11, 0x54, 0x00, 0x05, 0x00, 0x00, 0x11, 0x00, 0x01, 0x40, 0x04, 0x44,
+ 0x80, 0x20, 0x0a, 0x00, 0xa0, 0xa0, 0x00, 0x88, 0x82, 0xa8, 0x0a, 0x00,
+ 0xa0, 0xa0, 0x00, 0x00, 0x28, 0x0a, 0x0a, 0xa0, 0x08, 0x0a, 0x00, 0x0a,
+ 0x00, 0x00, 0x22, 0x0a, 0xa2, 0x00, 0x00, 0x88, 0x01, 0x40, 0x15, 0x00,
+ 0x50, 0x51, 0x40, 0x00, 0x01, 0x51, 0x15, 0x00, 0x50, 0x50, 0x00, 0x00,
+ 0x54, 0x14, 0x54, 0x40, 0x05, 0x14, 0x00, 0x05, 0x00, 0x40, 0x41, 0x15,
+ 0x14, 0x45, 0x04, 0x05, 0x00, 0x00, 0x00, 0x80, 0xa0, 0xa0, 0x20, 0x88,
+ 0x80, 0xaa, 0x08, 0x82, 0x28, 0x28, 0x02, 0x20, 0x28, 0x0a, 0x2a, 0xa0,
+ 0x02, 0x0a, 0x88, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x41, 0x40, 0x11, 0x44, 0x00, 0x55, 0x14, 0x44,
+ 0x50, 0x50, 0x01, 0x40, 0x10, 0x54, 0x15, 0x40, 0x01, 0x14, 0x04, 0x45,
+ 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x22, 0xa0, 0x0a, 0x00, 0x00, 0x0a, 0x2a, 0x20, 0x28, 0xa8, 0x00, 0xa0,
+ 0x08, 0xa8, 0x08, 0xa0, 0x00, 0xa8, 0x82, 0x82, 0x02, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x05, 0x00,
+ 0x00, 0x54, 0x55, 0x10, 0x50, 0x50, 0x00, 0x00, 0x05, 0x50, 0x04, 0x40,
+ 0x00, 0x50, 0x40, 0x05, 0x05, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x80, 0xaa, 0x2a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x00, 0x40, 0x55, 0x15, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0a,
+ 0x00, 0x80, 0xaa, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x00, 0x00, 0x55, 0x55,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01,
+ 0x00, 0x00, 0x54, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0xa8, 0xaa,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x50, 0x55, 0x05, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00,
+ 0x00, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x82, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x50, 0x55,
+ 0x05, 0x00, 0x00, 0x14, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x28,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x0a, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00,
+ 0x00, 0x00, 0x40, 0x55, 0x15, 0x00, 0x00, 0x50, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x80, 0xaa,
+ 0x2a, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55, 0x50, 0x15,
+ 0x55, 0x11, 0x55, 0x00, 0x15, 0x00, 0x54, 0x01, 0x00, 0x54, 0x01, 0x40,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x50, 0x00, 0x20, 0x82, 0x20, 0x08, 0x82, 0x00, 0x22, 0x80,
+ 0x08, 0x08, 0x28, 0xa2, 0x28, 0x20, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa2,
+ 0x00, 0x04, 0x41, 0x10, 0x04, 0x11, 0x00, 0x40, 0x10, 0x14, 0x10, 0x54,
+ 0x54, 0x11, 0x10, 0x00, 0x01, 0x00, 0x50, 0x14, 0x15, 0x05, 0x45, 0x01,
+ 0x50, 0x50, 0x44, 0x14, 0x05, 0x00, 0x04, 0x40, 0x20, 0x02, 0x22, 0x02,
+ 0x22, 0x08, 0x20, 0x20, 0x00, 0x08, 0x20, 0xa8, 0x28, 0x22, 0x08, 0x80,
+ 0x02, 0x00, 0x88, 0x22, 0xa2, 0x88, 0x28, 0x02, 0x88, 0x80, 0x22, 0xa2,
+ 0x08, 0x00, 0x08, 0x22, 0x00, 0x04, 0x41, 0x00, 0x04, 0x00, 0x01, 0x40,
+ 0x00, 0x10, 0x40, 0x04, 0x11, 0x10, 0x04, 0x10, 0x05, 0x00, 0x10, 0x04,
+ 0x01, 0x55, 0x45, 0x04, 0x10, 0x50, 0x44, 0x15, 0x01, 0x00, 0x14, 0x10,
+ 0x00, 0x2a, 0xa0, 0x02, 0x2a, 0x20, 0x22, 0x80, 0x02, 0x22, 0x20, 0x02,
+ 0x0a, 0xa0, 0x02, 0x08, 0x0a, 0x00, 0x20, 0x02, 0x82, 0x80, 0x20, 0x02,
+ 0x80, 0x88, 0x28, 0x82, 0x00, 0x00, 0xa8, 0x20, 0x00, 0x44, 0x40, 0x01,
+ 0x14, 0x00, 0x04, 0x00, 0x05, 0x10, 0x40, 0x00, 0x11, 0x10, 0x05, 0x04,
+ 0x14, 0x00, 0x44, 0x44, 0x01, 0x51, 0x44, 0x04, 0x10, 0x45, 0x14, 0x11,
+ 0x01, 0x00, 0x50, 0x11, 0x00, 0x82, 0x20, 0x02, 0x22, 0x20, 0x28, 0x20,
+ 0x08, 0x2a, 0x80, 0x02, 0x02, 0x20, 0x08, 0x00, 0x00, 0x00, 0x28, 0x28,
+ 0x02, 0x8a, 0x22, 0x02, 0xa0, 0xa8, 0x08, 0x8a, 0x00, 0x00, 0x80, 0x22,
+ 0x00, 0x04, 0x41, 0x10, 0x04, 0x01, 0x10, 0x00, 0x10, 0x41, 0x40, 0x01,
+ 0x11, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x51, 0x20, 0x82, 0x20, 0x00,
+ 0x02, 0x20, 0x28, 0x20, 0x88, 0x20, 0x80, 0x00, 0x82, 0x20, 0x28, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x22, 0x10, 0x04, 0x45, 0x10, 0x04, 0x01, 0x10, 0x40,
+ 0x04, 0x40, 0x00, 0x00, 0x41, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x41,
+ 0x8a, 0x0a, 0xaa, 0x8a, 0xaa, 0xa8, 0x20, 0xa0, 0x82, 0xa2, 0x80, 0x80,
+ 0xaa, 0xa8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x15, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0xaa, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa8, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54,
+ 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa0, 0xa2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x10, 0x50,
+ 0x41, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x15, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0xa0, 0x80, 0x02, 0xa8, 0x28,
+ 0x0a, 0xa0, 0x02, 0xa8, 0x00, 0x8a, 0x02, 0x28, 0x00, 0x00, 0x00, 0x0a,
+ 0x28, 0x80, 0x2a, 0x80, 0x22, 0x80, 0x0a, 0x00, 0xa8, 0x00, 0x28, 0x2a,
+ 0x00, 0x05, 0x00, 0x50, 0x00, 0x00, 0x55, 0x51, 0x14, 0x14, 0x54, 0x54,
+ 0x01, 0x54, 0x01, 0x50, 0x50, 0x05, 0x00, 0x05, 0x00, 0x50, 0x55, 0x40,
+ 0x51, 0x50, 0x15, 0x00, 0x54, 0x05, 0x14, 0x55, 0x00, 0x0a, 0x00, 0xa0,
+ 0x00, 0x80, 0xaa, 0x2a, 0x2a, 0x08, 0x2a, 0xa8, 0x02, 0xaa, 0x02, 0xa0,
+ 0xa0, 0x02, 0x00, 0x0a, 0x00, 0xa8, 0xaa, 0x80, 0x2a, 0xa8, 0x2a, 0x80,
+ 0xaa, 0x0a, 0xa8, 0xaa, 0x01, 0x05, 0x00, 0x50, 0x05, 0x40, 0x55, 0x55,
+ 0x14, 0x00, 0x14, 0x50, 0x05, 0x54, 0x01, 0x40, 0x51, 0x01, 0x00, 0x55,
+ 0x00, 0x54, 0x55, 0x41, 0x15, 0x54, 0x55, 0x40, 0x55, 0x15, 0x54, 0x55,
+ 0x02, 0x0a, 0x00, 0xa0, 0x0a, 0xa0, 0x02, 0x2a, 0x2a, 0x00, 0x0a, 0x88,
+ 0x0a, 0x2a, 0x00, 0x80, 0xaa, 0x00, 0x00, 0xaa, 0x00, 0xaa, 0xa0, 0xa2,
+ 0x0a, 0x2a, 0xa8, 0xa0, 0x0a, 0x0a, 0xaa, 0xa0, 0x01, 0x14, 0x01, 0x40,
+ 0x55, 0x50, 0x01, 0x14, 0x14, 0x00, 0x05, 0x04, 0x15, 0x15, 0x00, 0x00,
+ 0x51, 0x00, 0x00, 0x54, 0x05, 0x14, 0x40, 0x45, 0x05, 0x15, 0x50, 0x41,
+ 0x01, 0x14, 0x54, 0x40, 0x02, 0xa8, 0x00, 0x80, 0xaa, 0xa8, 0x00, 0x2a,
+ 0x28, 0x88, 0x02, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x0a, 0x0a, 0xa0, 0xa2, 0x82, 0x0a, 0xa0, 0xa0, 0x00, 0x28, 0x2a, 0xa0,
+ 0x01, 0x50, 0x00, 0x00, 0x55, 0x50, 0x00, 0x14, 0x54, 0x54, 0x05, 0x15,
+ 0x14, 0x15, 0x00, 0x00, 0x11, 0x00, 0x00, 0x50, 0x05, 0x15, 0x00, 0x40,
+ 0x01, 0x05, 0x40, 0x51, 0x00, 0x14, 0x14, 0x40, 0x00, 0xa8, 0x00, 0x00,
+ 0xa8, 0x28, 0x00, 0x28, 0x28, 0xa8, 0x02, 0x80, 0x0a, 0x0a, 0x00, 0x80,
+ 0x08, 0x00, 0x00, 0x80, 0x8a, 0x0a, 0x00, 0xa0, 0x80, 0xaa, 0xaa, 0xa8,
+ 0xaa, 0x2a, 0x0a, 0xa0, 0x01, 0x44, 0x01, 0x00, 0x50, 0x55, 0x00, 0x14,
+ 0x50, 0x14, 0x01, 0x00, 0x15, 0x05, 0x00, 0x40, 0x15, 0x00, 0x00, 0x00,
+ 0x15, 0x05, 0x00, 0x50, 0x41, 0x55, 0x55, 0x51, 0x55, 0x15, 0x15, 0x40,
+ 0x00, 0x80, 0x02, 0x00, 0xa0, 0x28, 0x00, 0x0a, 0x28, 0x0a, 0x02, 0x00,
+ 0x8a, 0x0a, 0x00, 0xa0, 0x2a, 0x00, 0x00, 0x00, 0x8a, 0x0a, 0x00, 0xa0,
+ 0x80, 0xaa, 0xaa, 0xa8, 0xaa, 0x2a, 0x0a, 0xa0, 0x01, 0x40, 0x01, 0x00,
+ 0x50, 0x55, 0x00, 0x14, 0x50, 0x05, 0x00, 0x00, 0x14, 0x05, 0x00, 0x50,
+ 0x50, 0x00, 0x00, 0x00, 0x15, 0x05, 0x00, 0x50, 0x40, 0x55, 0x55, 0x51,
+ 0x55, 0x15, 0x05, 0x50, 0x00, 0x80, 0x02, 0x2a, 0xa8, 0x28, 0x00, 0x0a,
+ 0xa8, 0x0a, 0x80, 0xaa, 0x82, 0x02, 0x00, 0x20, 0xa0, 0x00, 0xa0, 0x82,
+ 0x8a, 0x0a, 0x00, 0xa0, 0x80, 0x02, 0x00, 0x28, 0x00, 0x00, 0x0a, 0xa0,
+ 0x00, 0x00, 0x05, 0x14, 0x50, 0x54, 0x00, 0x15, 0x50, 0x05, 0x40, 0x55,
+ 0x01, 0x05, 0x00, 0x10, 0x40, 0x01, 0x40, 0x01, 0x05, 0x15, 0x50, 0x51,
+ 0x40, 0x01, 0x00, 0x50, 0x00, 0x00, 0x05, 0x50, 0x00, 0x00, 0x0a, 0x2a,
+ 0xa8, 0xa8, 0x80, 0x0a, 0xa0, 0x02, 0x80, 0x0a, 0x80, 0x02, 0x00, 0x08,
+ 0x80, 0x02, 0xa0, 0x82, 0x0a, 0x2a, 0xa8, 0xa0, 0x80, 0x02, 0x2a, 0xa8,
+ 0x80, 0x8a, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x54, 0x55, 0x50, 0x55, 0x05,
+ 0x50, 0x01, 0x00, 0x00, 0x44, 0x05, 0x00, 0x04, 0x00, 0x05, 0x40, 0x55,
+ 0x05, 0x54, 0x55, 0x50, 0x00, 0x55, 0x15, 0x50, 0x55, 0x05, 0x05, 0x50,
+ 0x00, 0x00, 0x00, 0xa8, 0x2a, 0xa0, 0xaa, 0x0a, 0xa0, 0x00, 0x08, 0x00,
+ 0x8a, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x80, 0xaa, 0x02, 0xaa, 0x2a, 0x28,
+ 0x80, 0xaa, 0x0a, 0xa0, 0xaa, 0x82, 0x02, 0x28, 0x00, 0x00, 0x00, 0x50,
+ 0x15, 0x40, 0x55, 0x05, 0x40, 0x01, 0x10, 0x00, 0x55, 0x01, 0x00, 0x05,
+ 0x00, 0x00, 0x00, 0x55, 0x01, 0x54, 0x15, 0x50, 0x00, 0x55, 0x05, 0x40,
+ 0x55, 0x01, 0x05, 0x50, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x80, 0x0a, 0x0a,
+ 0xa0, 0x00, 0x00, 0xa0, 0xaa, 0x02, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x2a,
+ 0x00, 0xa0, 0x0a, 0x28, 0x00, 0xa8, 0x00, 0x80, 0x2a, 0x80, 0x02, 0x28,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x55, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0xa0, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x50, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa,
+ 0xaa, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x50, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x55, 0x05, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xaa, 0x0a, 0x0a, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x55, 0x15, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0xaa, 0x8a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x45, 0x05, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x22, 0xa0, 0x22, 0xa8, 0x0a, 0xa8, 0x00,
+ 0xa8, 0xa0, 0x28, 0x80, 0xaa, 0x22, 0x28, 0xa0, 0x02, 0x2a, 0x2a, 0xa0,
+ 0x02, 0x8a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x40, 0x15, 0x50, 0x15, 0x54, 0x15, 0x54, 0x01, 0x55, 0x41, 0x55, 0x00,
+ 0x55, 0x11, 0x54, 0x50, 0x05, 0x54, 0x54, 0x54, 0x05, 0x54, 0x05, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x08, 0x08,
+ 0x20, 0x08, 0x02, 0x82, 0x82, 0x82, 0x82, 0x00, 0xaa, 0x08, 0x20, 0x20,
+ 0x08, 0x08, 0x08, 0x0a, 0x0a, 0x28, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x50, 0x10, 0x04, 0x10, 0x10, 0x00, 0x01, 0x04,
+ 0x01, 0x01, 0x01, 0x01, 0x54, 0x14, 0x11, 0x00, 0x10, 0x10, 0x04, 0x04,
+ 0x04, 0x10, 0x00, 0x14, 0x51, 0x10, 0x44, 0x01, 0x50, 0x44, 0x44, 0x14,
+ 0xa0, 0x00, 0x02, 0x08, 0x08, 0x80, 0x00, 0x82, 0x00, 0x82, 0x80, 0x00,
+ 0xa8, 0x28, 0x00, 0xa0, 0x0a, 0x20, 0x08, 0x02, 0x08, 0x08, 0x00, 0x00,
+ 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x05, 0x04, 0x00,
+ 0x10, 0x00, 0x55, 0x45, 0x55, 0x41, 0x40, 0x00, 0x54, 0x54, 0x00, 0x50,
+ 0x05, 0x10, 0x04, 0x55, 0x05, 0x04, 0x00, 0x44, 0x10, 0x14, 0x45, 0x04,
+ 0x10, 0x54, 0x54, 0x04, 0x00, 0x0a, 0x02, 0x00, 0x08, 0x80, 0xaa, 0x82,
+ 0xaa, 0x82, 0x80, 0x00, 0x2a, 0xaa, 0x00, 0x08, 0x08, 0x20, 0x02, 0xaa,
+ 0x0a, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00,
+ 0x10, 0x14, 0x04, 0x00, 0x04, 0x00, 0x01, 0x40, 0x00, 0x40, 0x40, 0x00,
+ 0x15, 0x45, 0x15, 0x04, 0x04, 0x10, 0x01, 0x01, 0x00, 0x04, 0x00, 0x05,
+ 0x15, 0x10, 0x44, 0x04, 0x14, 0x14, 0x41, 0x04, 0x08, 0x08, 0x0a, 0x08,
+ 0x08, 0x80, 0x02, 0x82, 0x80, 0x20, 0x20, 0x80, 0x8a, 0x8a, 0x22, 0x02,
+ 0x02, 0xa0, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x05, 0x54, 0x15, 0x55, 0x01, 0x55, 0x01,
+ 0x55, 0x51, 0x51, 0x01, 0x45, 0x05, 0x00, 0x54, 0x15, 0x40, 0x00, 0x54,
+ 0x45, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xa8, 0x02, 0xa8, 0x82, 0xaa, 0x00, 0xaa, 0x00, 0x2a, 0xa8, 0xa8, 0x80,
+ 0x82, 0x22, 0x20, 0xa8, 0x0a, 0x20, 0x00, 0xa8, 0x80, 0xaa, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x55, 0x55, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa0, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x00, 0x54, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x15, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0xa8, 0xaa, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x2a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0x00, 0x54, 0x55, 0x01, 0x00, 0x40, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,
+ 0x00, 0xa8, 0xaa, 0x02, 0x00, 0x80, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x50, 0x55, 0x05,
+ 0x00, 0x00, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x54, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x0a, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x0a, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x20, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05,
+ 0x00, 0x40, 0x55, 0x15, 0x00, 0x00, 0x14, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x80, 0xaa, 0x2a,
+ 0x00, 0x00, 0x28, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xa8, 0x02, 0x08, 0x00, 0x10, 0x50, 0x50, 0x50, 0x40, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x50, 0x00,
+ 0x50, 0x00, 0x05, 0x04, 0x01, 0x05, 0x50, 0x40, 0x54, 0x05, 0x04, 0x05,
+ 0x8a, 0x20, 0x20, 0x88, 0xa0, 0x28, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00,
+ 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x20, 0x00, 0x82, 0x82, 0x08, 0x8a,
+ 0x82, 0x08, 0x88, 0xa0, 0xa8, 0x0a, 0x22, 0x28, 0x00, 0x41, 0x00, 0x04,
+ 0x41, 0x44, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x55, 0x55,
+ 0x00, 0x00, 0x10, 0x00, 0x01, 0x41, 0x10, 0x44, 0x44, 0x10, 0x04, 0x41,
+ 0x50, 0x15, 0x11, 0x10, 0x80, 0x80, 0x00, 0x02, 0x82, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x80, 0x00,
+ 0x02, 0x22, 0x20, 0x08, 0x20, 0x20, 0x02, 0x22, 0xa0, 0x2a, 0x22, 0x20,
+ 0x00, 0x41, 0x10, 0x01, 0x44, 0x00, 0x00, 0x40, 0x41, 0x51, 0x04, 0x14,
+ 0x15, 0x00, 0x11, 0x44, 0x50, 0x54, 0x40, 0x01, 0x05, 0x10, 0x00, 0x04,
+ 0x10, 0x40, 0x01, 0x44, 0x10, 0x15, 0x51, 0x00, 0xa8, 0x80, 0x00, 0xaa,
+ 0x82, 0x00, 0x00, 0x20, 0x22, 0x8a, 0xa2, 0x22, 0x22, 0x80, 0xa0, 0x88,
+ 0x88, 0x88, 0x88, 0x02, 0x2a, 0x20, 0x00, 0x08, 0xa0, 0x2a, 0xaa, 0x22,
+ 0x20, 0x8a, 0xa0, 0x02, 0x04, 0x01, 0x01, 0x01, 0x40, 0x00, 0x00, 0x40,
+ 0x10, 0x10, 0x41, 0x54, 0x11, 0x00, 0x11, 0x40, 0x54, 0x05, 0x04, 0x05,
+ 0x50, 0x11, 0x00, 0x04, 0x10, 0x00, 0x01, 0x40, 0x10, 0x45, 0x00, 0x15,
+ 0x82, 0x80, 0x08, 0x02, 0x80, 0x00, 0x00, 0x00, 0x22, 0x88, 0x02, 0x02,
+ 0x22, 0x00, 0x82, 0x08, 0x02, 0x08, 0x02, 0x0a, 0x80, 0x22, 0x00, 0x08,
+ 0x20, 0x00, 0x02, 0x20, 0x20, 0xa2, 0x00, 0x28, 0x01, 0x01, 0x05, 0x01,
+ 0x40, 0x00, 0x00, 0x40, 0x14, 0x51, 0x41, 0x44, 0x11, 0x40, 0x04, 0x11,
+ 0x04, 0x05, 0x01, 0x14, 0x00, 0x15, 0x00, 0x04, 0x10, 0x00, 0x01, 0x40,
+ 0x10, 0x51, 0x01, 0x50, 0x82, 0x00, 0x02, 0x02, 0x80, 0x00, 0x00, 0x80,
+ 0xa2, 0x88, 0x2a, 0x28, 0x22, 0x80, 0x02, 0x28, 0x8a, 0x88, 0x00, 0x28,
+ 0x00, 0x22, 0x00, 0x08, 0x20, 0x00, 0x02, 0x20, 0xa0, 0xa8, 0x02, 0x20,
+ 0x01, 0x05, 0x05, 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00,
+ 0x00, 0x00, 0x40, 0x55, 0x15, 0x00, 0x00, 0x00, 0x01, 0x44, 0x00, 0x04,
+ 0x40, 0x40, 0x04, 0x44, 0x10, 0x51, 0x15, 0x40, 0x82, 0x00, 0x02, 0x08,
+ 0x82, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa,
+ 0x2a, 0x00, 0x00, 0x00, 0x02, 0x82, 0x08, 0x08, 0x80, 0x20, 0x08, 0x22,
+ 0xa0, 0xa0, 0x2a, 0x20, 0x14, 0x01, 0x00, 0x50, 0x50, 0x01, 0x00, 0x00,
+ 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00,
+ 0x51, 0x00, 0x05, 0x15, 0x00, 0x05, 0x50, 0x50, 0x50, 0x40, 0x15, 0x05,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x80, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x28, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x2a, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x54, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x00, 0x00, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa0, 0x0a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x50, 0x55, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00,
+ 0x00, 0xa0, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xaa,
+ 0x15, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x2a, 0x00, 0x00, 0x00,
+ 0x00, 0xa0, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0xaa, 0x15, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00,
+ 0x00, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55,
+ 0xa2, 0x00, 0x80, 0x02, 0x0a, 0xa2, 0x82, 0x02, 0x0a, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0a, 0xa8, 0xa0, 0x80, 0x82, 0xa0, 0x11, 0x01, 0x00, 0x04,
+ 0x11, 0x50, 0x41, 0x04, 0x11, 0x10, 0x00, 0x14, 0x44, 0x40, 0x00, 0x41,
+ 0x11, 0x00, 0x14, 0x00, 0x44, 0x05, 0x05, 0x04, 0x45, 0x00, 0x10, 0x44,
+ 0x11, 0x11, 0x04, 0x44, 0xa2, 0x02, 0x20, 0x80, 0x20, 0x28, 0x20, 0x08,
+ 0x02, 0x20, 0x80, 0x22, 0xa8, 0xa8, 0xa0, 0x82, 0x28, 0x00, 0x28, 0x80,
+ 0x22, 0x08, 0x82, 0x0a, 0x22, 0x80, 0x00, 0x82, 0x20, 0x00, 0x88, 0x8a,
+ 0x51, 0x05, 0x50, 0x00, 0x10, 0x11, 0x11, 0x10, 0x01, 0x50, 0x40, 0x10,
+ 0x54, 0x04, 0x11, 0x04, 0x41, 0x00, 0x50, 0x40, 0x10, 0x04, 0x44, 0x10,
+ 0x44, 0x40, 0x01, 0x01, 0x10, 0x10, 0x44, 0x14, 0xa2, 0x00, 0xa0, 0x00,
+ 0xa8, 0x02, 0xa0, 0x0a, 0x02, 0xa0, 0xa0, 0x00, 0x0a, 0x82, 0x08, 0x82,
+ 0x20, 0x00, 0xa0, 0x20, 0x20, 0x08, 0x22, 0x08, 0x02, 0x80, 0x02, 0x02,
+ 0x20, 0xa8, 0x8a, 0x82, 0x51, 0x01, 0x40, 0x01, 0x55, 0x01, 0x10, 0x00,
+ 0x01, 0x40, 0x41, 0x00, 0x04, 0x54, 0x50, 0x41, 0x40, 0x00, 0x40, 0x10,
+ 0x10, 0x04, 0x41, 0x05, 0x01, 0x00, 0x05, 0x01, 0x10, 0x10, 0x40, 0x50,
+ 0xa2, 0x08, 0x80, 0x82, 0xa0, 0x8a, 0x20, 0x00, 0x02, 0x80, 0x22, 0x00,
+ 0x02, 0x0a, 0x28, 0x80, 0x20, 0x00, 0x80, 0x20, 0x08, 0x88, 0xa0, 0x00,
+ 0x02, 0x00, 0x0a, 0x02, 0x20, 0x08, 0x80, 0xa0, 0x51, 0x01, 0x00, 0x44,
+ 0x50, 0x11, 0x10, 0x00, 0x01, 0x00, 0x11, 0x00, 0x01, 0x01, 0x04, 0x40,
+ 0x10, 0x00, 0x40, 0x11, 0x10, 0x10, 0x11, 0x00, 0x01, 0x00, 0x10, 0x01,
+ 0x10, 0x10, 0x40, 0x50, 0xa2, 0x08, 0x00, 0x88, 0x80, 0x08, 0x20, 0x00,
+ 0x02, 0x02, 0x22, 0x00, 0x02, 0x02, 0x08, 0x20, 0x20, 0x00, 0x80, 0x08,
+ 0x08, 0x88, 0x20, 0x80, 0x00, 0x00, 0x20, 0x02, 0x20, 0x28, 0x80, 0xa0,
+ 0x51, 0x11, 0x10, 0x44, 0x40, 0x50, 0x40, 0x10, 0x01, 0x00, 0x11, 0x00,
+ 0x01, 0x01, 0x04, 0x40, 0x10, 0x00, 0x01, 0x11, 0x04, 0x50, 0x10, 0x00,
+ 0x01, 0x40, 0x10, 0x04, 0x11, 0x50, 0x00, 0x01, 0xa2, 0x28, 0x20, 0x82,
+ 0x0a, 0x20, 0xa0, 0x0a, 0x02, 0x02, 0x22, 0x88, 0x00, 0x82, 0x08, 0x22,
+ 0x08, 0x80, 0x80, 0x28, 0x08, 0x28, 0x20, 0x88, 0x00, 0x80, 0x08, 0xaa,
+ 0x20, 0xa0, 0x82, 0xaa, 0x41, 0x50, 0x50, 0x01, 0x55, 0x00, 0x00, 0x05,
+ 0x05, 0x05, 0x51, 0x04, 0x01, 0x45, 0x14, 0x11, 0x50, 0x00, 0x41, 0x50,
+ 0x04, 0x10, 0x50, 0x44, 0x00, 0x40, 0x05, 0x50, 0x50, 0x40, 0x01, 0x14,
+ 0xaa, 0xaa, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xa0, 0x82,
+ 0x00, 0x2a, 0xa8, 0x20, 0x28, 0x80, 0x2a, 0x20, 0x08, 0x08, 0xa0, 0x82,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00,
+ 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0x80, 0x0a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x54, 0x55, 0x01, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xaa, 0x02, 0xa0,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x50, 0x55, 0x05, 0x40, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xa0, 0xaa, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x15, 0x50,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0x2a, 0x28, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x55, 0x55, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x40, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x2a, 0x2a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x15, 0x15, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xaa, 0x8a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x45, 0x45,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x88, 0xa2, 0x22, 0x08, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x88, 0x00, 0x00, 0x80, 0xaa, 0x2a, 0x0a, 0x00, 0x0a, 0x08,
+ 0x02, 0x22, 0xa0, 0x80, 0x08, 0x00, 0xa0, 0x00, 0x20, 0xa0, 0xa0, 0xa0,
+ 0x41, 0x01, 0x51, 0x45, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01,
+ 0x00, 0x00, 0x55, 0x55, 0x14, 0x00, 0x11, 0x14, 0x05, 0x45, 0x10, 0x41,
+ 0x11, 0x00, 0x40, 0x01, 0x14, 0x41, 0x40, 0x10, 0x82, 0x28, 0xa2, 0xaa,
+ 0x80, 0xa2, 0xa2, 0xa0, 0xa8, 0x00, 0x28, 0x28, 0x08, 0xa2, 0x02, 0xaa,
+ 0xa8, 0x80, 0x20, 0x88, 0x88, 0x0a, 0x08, 0x82, 0x20, 0x00, 0x80, 0x0a,
+ 0x00, 0x82, 0x00, 0x08, 0x04, 0x51, 0x51, 0x55, 0x45, 0x44, 0x11, 0x11,
+ 0x11, 0x01, 0x50, 0x44, 0x04, 0x11, 0x05, 0x55, 0x41, 0x41, 0x40, 0x10,
+ 0x40, 0x55, 0x04, 0x44, 0x40, 0x00, 0x00, 0x14, 0x00, 0x01, 0x01, 0x04,
+ 0x88, 0xa8, 0xa8, 0x2a, 0x2a, 0x20, 0x08, 0x0a, 0x0a, 0x02, 0xa0, 0x80,
+ 0x88, 0x08, 0xa2, 0xaa, 0x02, 0x22, 0x00, 0x08, 0xa0, 0x8a, 0x02, 0x88,
+ 0x20, 0x00, 0x00, 0x20, 0x00, 0x82, 0x20, 0x02, 0x05, 0x55, 0x54, 0x55,
+ 0x44, 0x40, 0x50, 0x51, 0x11, 0x01, 0x04, 0x51, 0x10, 0x51, 0x41, 0x55,
+ 0x05, 0x44, 0x00, 0x10, 0x00, 0x50, 0x54, 0x45, 0x40, 0x00, 0x00, 0x40,
+ 0x50, 0x01, 0x01, 0x54, 0x80, 0x2a, 0xaa, 0x0a, 0x28, 0x28, 0x08, 0x08,
+ 0x08, 0x02, 0x88, 0x88, 0x80, 0x08, 0xa8, 0xaa, 0x0a, 0x28, 0x00, 0x08,
+ 0xa0, 0x02, 0x02, 0x80, 0x20, 0x00, 0x00, 0x80, 0x08, 0x02, 0x02, 0x02,
+ 0x00, 0x15, 0x55, 0x15, 0x44, 0x44, 0x10, 0x11, 0x11, 0x01, 0x04, 0x45,
+ 0x50, 0x10, 0x51, 0x55, 0x15, 0x44, 0x00, 0x10, 0x00, 0x01, 0x04, 0x40,
+ 0x40, 0x00, 0x00, 0x40, 0x04, 0x01, 0x11, 0x04, 0x80, 0x0a, 0xaa, 0x2a,
+ 0x82, 0x22, 0xa0, 0xa0, 0x08, 0x02, 0xa8, 0xa8, 0x20, 0xa0, 0xa8, 0xaa,
+ 0x0a, 0x28, 0x00, 0x08, 0x80, 0x00, 0x02, 0x80, 0x20, 0x00, 0x00, 0x80,
+ 0x02, 0x02, 0x0a, 0x02, 0x00, 0x04, 0x54, 0x55, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x55, 0x15, 0x44, 0x00, 0x10,
+ 0x10, 0x00, 0x04, 0x40, 0x40, 0x00, 0x00, 0x40, 0x04, 0x01, 0x04, 0x04,
+ 0x08, 0x02, 0xa8, 0xaa, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0xaa, 0x28, 0x82, 0x00, 0x08, 0xa8, 0x80, 0x08, 0x88,
+ 0x20, 0x00, 0x20, 0x20, 0x02, 0x0a, 0x0a, 0x08, 0x44, 0x00, 0x50, 0x55,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x51, 0x01, 0x11, 0x10, 0x54, 0x41, 0x10, 0x44, 0x40, 0x00, 0x40, 0x10,
+ 0x04, 0x01, 0x04, 0x10, 0x00, 0x00, 0xa0, 0xaa, 0x0a, 0x00, 0x00, 0x00,
+ 0x00, 0xa0, 0x00, 0x08, 0x00, 0x00, 0x00, 0xaa, 0x08, 0x00, 0x0a, 0x2a,
+ 0x2a, 0x0a, 0xa0, 0xa0, 0xa0, 0x00, 0x20, 0x0a, 0x28, 0x02, 0x00, 0xa0,
+ 0x50, 0x01, 0x50, 0x55, 0x05, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/xc/programs/Xserver/ilbm/Imakefile b/xc/programs/Xserver/ilbm/Imakefile
new file mode 100644
index 000000000..69766108a
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/Imakefile
@@ -0,0 +1,63 @@
+XCOMM $XFree86: xc/programs/Xserver/ilbm/Imakefile,v 3.5 1999/08/14 10:50:17 dawes Exp $
+XCOMM $XConsortium: Imakefile,v 1.38 94/03/11 18:47:47 dpw Exp $
+#define IHaveModules
+#include <Server.tmpl>
+
+SRCS1 = ilbmgc.c ilbmwindow.c ilbmfont.c ilbmfillrct.c ilbmpntwin.c \
+ ilbmpixmap.c ilbmimage.c ilbmline.c ilbmbres.c ilbmhrzvert.c \
+ ilbmbresd.c ilbmpushpxl.c ilbmzerarc.c ilbmfillarc.c ilbmfillsp.c \
+ ilbmsetsp.c ilbmscrinit.c ilbmclip.c ilbmbitblt.c ilbmgetsp.c \
+ ilbmpolypnt.c ilbmbltC.c ilbmbltX.c ilbmbltCI.c ilbmbltO.c \
+ ilbmbltG.c ilbmcmap.c ilbmtileC.c ilbmtileG.c ilbmmisc.c ilbmbstore.c
+
+SRCS = $(SRCS1) ilbmseg.c ilbmbltC.c ilbmbltX.c ilbmbltCI.c ilbmbltO.c \
+ ilbmbltG.c ilbmtileC.c ilbmtileG.c
+
+OBJS = ilbmgc.o ilbmwindow.o ilbmfont.o ilbmpixmap.o ilbmfillsp.o \
+ ilbmsetsp.o ilbmscrinit.o ilbmclip.o ilbmbitblt.o ilbmgetsp.o \
+ ilbmbltC.o ilbmbltX.o ilbmbltCI.o ilbmbltO.o ilbmbltG.o ilbmcmap.o \
+ ilbmimage.o ilbmzerarc.o ilbmfillarc.o ilbmply1rct.o ilbmtileC.o \
+ ilbmtileG.o ilbmfillrct.o ilbmpolypnt.o ilbmmisc.o ilbmbstore.o \
+ ilbmbresd.o ilbmimggblt.o ilbmpushpxl.o ilbmplygblt.o ilbmtegblt.o \
+ ilbmpntwin.o ilbmpntarea.o ilbmbres.o ilbmhrzvert.o ilbmline.o \
+ ilbmseg.o
+
+INCLUDES = -I. -I../cfb -I../mfb -I../mi -I../include -I$(XINCLUDESRC) \
+ -I$(FONTINCSRC) $(EXTRAINCLUDES)
+LINTDEFS = -DMFBPOLYGLYPHBLT=ilbmPolyGlyphBltWhite \
+ -DMFBIMAGEGLYPHBLT=ilbmImageGlyphBltWhite \
+ -DEQWHOLEWORD=MFB_EQWHOLEWORD_WHITE -DOPEQ=MFB_OPEQ_WHITE
+
+LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln \
+ ../mfb/llib-lmfb.ln ../mi/llib-lmi.ln
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(ilbm,$(OBJS))
+LintLibraryTarget(ilbm,$(SRCS1))
+NormalLintTarget($(LINTDEFS) $(SRCS1))
+
+ObjectFromSpecialSource(ilbmseg,ilbmline,-DPOLYSEGMENT)
+
+ObjectFromSpecialSource(ilbmbltC,ilbmblt,-DMROP=Mcopy)
+
+ObjectFromSpecialSource(ilbmbltX,ilbmblt,-DMROP=Mxor)
+
+ObjectFromSpecialSource(ilbmbltCI,ilbmblt,-DMROP=McopyInverted)
+
+ObjectFromSpecialSource(ilbmbltO,ilbmblt,-DMROP=Mor)
+
+ObjectFromSpecialSource(ilbmbltG,ilbmblt,-DMROP=0)
+
+ObjectFromSpecialSource(ilbmtileC,ilbmtile,-DMROP=Mcopy)
+
+ObjectFromSpecialSource(ilbmtileG,ilbmtile,-DMROP=0)
+
+#if DoLoadableServer
+InstallDynamicModule(LibraryTargetName(ilbm),$(MODULEDIR))
+#endif
+
+#ifndef OS2Architecture
+DependTarget()
+#endif
+
+InstallDriverSDKDynamicModule(LibraryTargetName(ilbm),$(DRIVERSDKMODULEDIR))
diff --git a/xc/programs/Xserver/ilbm/README b/xc/programs/Xserver/ilbm/README
new file mode 100644
index 000000000..650d6b803
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/README
@@ -0,0 +1,17 @@
+
+ ilbm -- Interleaved bitplanes for Amiga
+ © Copyright 1995 by Geert Uytterhoeven and Others (read the sources)
+
+All stuff in this directory is based on Xdaniver, which is based on mfb (read
+../afb/Xdaniver.doc).
+
+I made changes to support the interleaved mode of the Linux/68k Amiga Color
+Frame Buffer Device, which uses interleaved bitplanes instead of normal
+bitplanes.
+
+Note: there are still some annoying bugs left in ilbmimage.
+
+--
+Geert Uytterhoeven Geert.Uytterhoeven@cs.kuleuven.ac.be
+Wavelets, Linux/m68k on Amiga http://www.cs.kuleuven.ac.be/~geert/
+Department of Computer Science -- Katholieke Universiteit Leuven -- Belgium
diff --git a/xc/programs/Xserver/ilbm/ilbm.h b/xc/programs/Xserver/ilbm/ilbm.h
new file mode 100644
index 000000000..1df8eff68
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbm.h
@@ -0,0 +1,1217 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbm.h,v 3.2 1998/04/05 16:42:23 robin Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbm.h,v 5.31 94/04/17 20:28:15 dpw Exp $ */
+/* Monochrome Frame Buffer definitions
+ written by drewry, september 1986
+*/
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "pixmap.h"
+#include "region.h"
+#include "gc.h"
+#include "colormap.h"
+#include "miscstruct.h"
+#include "mibstore.h"
+
+extern int ilbmInverseAlu[];
+extern int ilbmScreenPrivateIndex;
+/* warning: PixelType definition duplicated in maskbits.h */
+#ifndef PixelType
+#define PixelType unsigned long
+#endif /* PixelType */
+
+#define AFB_MAX_DEPTH 8
+
+/* ilbmbitblt.c */
+
+extern void ilbmDoBitblt(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/,
+ unsigned long /*planemask*/
+#endif
+);
+
+extern RegionPtr ilbmBitBlt(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ GCPtr /*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*width*/,
+ int /*height*/,
+ int /*dstx*/,
+ int /*dsty*/,
+ void (*doBitBlt)(),
+ unsigned long /*planemask*/
+#endif
+);
+
+extern RegionPtr ilbmCopyArea(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ GCPtr/*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*width*/,
+ int /*height*/,
+ int /*dstx*/,
+ int /*dsty*/
+#endif
+);
+
+extern RegionPtr ilbmCopyPlane(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ GCPtr/*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*width*/,
+ int /*height*/,
+ int /*dstx*/,
+ int /*dsty*/,
+ unsigned long /*plane*/
+#endif
+);
+
+extern void ilbmCopy1ToN(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/,
+ unsigned long /*planemask*/
+#endif
+);
+/* ilbmbltC.c */
+
+extern void ilbmDoBitbltCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/,
+ unsigned long /*planemask*/
+#endif
+);
+/* ilbmbltCI.c */
+
+extern void ilbmDoBitbltCopyInverted(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/,
+ unsigned long /*planemask*/
+#endif
+);
+/* ilbmbltG.c */
+
+extern void ilbmDoBitbltGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/,
+ unsigned long /*planemask*/
+#endif
+);
+/* ilbmbltO.c */
+
+extern void ilbmDoBitbltOr(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/,
+ unsigned long /*planemask*/
+#endif
+);
+/* ilbmbltX.c */
+
+extern void ilbmDoBitbltXor(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/,
+ unsigned long /*planemask*/
+#endif
+);
+/* ilbmbres.c */
+
+extern void ilbmBresS(
+#if NeedFunctionPrototypes
+ PixelType * /*addrl*/,
+ int /*nlwidth*/,
+ int /*sizeDst*/,
+ int /*depthDst*/,
+ int /*signdx*/,
+ int /*signdy*/,
+ int /*axis*/,
+ int /*x1*/,
+ int /*y1*/,
+ int /*e*/,
+ int /*e1*/,
+ int /*e2*/,
+ int /*len*/,
+ unsigned char * /*rrops*/
+#endif
+);
+/* ilbmbresd.c */
+
+extern void ilbmBresD(
+#if NeedFunctionPrototypes
+ int * /*pdashIndex*/,
+ unsigned char * /*pDash*/,
+ int /*numInDashList*/,
+ int * /*pdashOffset*/,
+ int /*isDoubleDash*/,
+ PixelType * /*addrl*/,
+ int /*nlwidth*/,
+ int /*sizeDst*/,
+ int /*depthDst*/,
+ int /*signdx*/,
+ int /*signdy*/,
+ int /*axis*/,
+ int /*x1*/,
+ int /*y1*/,
+ int /*e*/,
+ int /*e1*/,
+ int /*e2*/,
+ int /*len*/,
+ unsigned char * /*rrops*/,
+ unsigned char * /*bgrrops*/
+#endif
+);
+/* ilbmbstore.c */
+
+extern void ilbmSaveAreas(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPixmap*/,
+ RegionPtr /*prgnSave*/,
+ int /*xorg*/,
+ int /*yorg*/,
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern void ilbmRestoreAreas(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPixmap*/,
+ RegionPtr /*prgnRestore*/,
+ int /*xorg*/,
+ int /*yorg*/,
+ WindowPtr /*pWin*/
+#endif
+);
+/* ilbmclip.c */
+
+extern RegionPtr ilbmPixmapToRegion(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPix*/
+#endif
+);
+
+/* ilbmcmap.c */
+
+extern Bool ilbmInitializeColormap(
+#if NeedFunctionPrototypes
+ ColormapPtr /*pmap*/
+#endif
+);
+
+extern void ilbmResolveColor(
+#if NeedFunctionPrototypes
+ unsigned short * /*pred*/,
+ unsigned short * /*pgreen*/,
+ unsigned short * /*pblue*/,
+ VisualPtr /*pVisual*/
+#endif
+);
+
+extern Bool ilbmSetVisualTypes(
+#if NeedFunctionPrototypes
+ int /*depth*/,
+ int /*visuals*/,
+ int /*bitsPerRGB*/
+#endif
+);
+
+/* ilbmfillarc.c */
+
+extern void ilbmPolyFillArcSolid(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+/* ilbmfillrct.c */
+
+extern void ilbmPolyFillRect(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nrectFill*/,
+ xRectangle * /*prectInit*/
+#endif
+);
+
+/* ilbmply1rct.c */
+extern void ilbmFillPolygonSolid(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*shape*/,
+ int /*count*/,
+ DDXPointPtr /*ptsIn*/
+#endif
+);
+
+/* ilbmfillsp.c */
+
+extern void ilbmSolidFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+extern void ilbmStippleFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+extern void ilbmTileFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+extern void ilbmUnnaturalTileFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+extern void ilbmUnnaturalStippleFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+extern void ilbmOpaqueStippleFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+extern void ilbmUnnaturalOpaqueStippleFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+/* ilbmfont.c */
+
+extern Bool ilbmRealizeFont(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pscr*/,
+ FontPtr /*pFont*/
+#endif
+);
+
+extern Bool ilbmUnrealizeFont(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pscr*/,
+ FontPtr /*pFont*/
+#endif
+);
+/* ilbmgc.c */
+
+extern Bool ilbmCreateGC(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/
+#endif
+);
+
+extern void ilbmValidateGC(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/,
+ unsigned long /*changes*/,
+ DrawablePtr /*pDrawable*/
+#endif
+);
+
+extern void ilbmDestroyGC(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/
+#endif
+);
+
+extern void ilbmReduceRop(
+#if NeedFunctionPrototypes
+ int /*alu*/,
+ Pixel /*src*/,
+ unsigned long /*planemask*/,
+ int /*depth*/,
+ unsigned char * /*rrops*/
+#endif
+);
+
+extern void ilbmReduceOpaqueStipple (
+#if NeedFunctionPrototypes
+ Pixel /*fg*/,
+ Pixel /*bg*/,
+ unsigned long /*planemask*/,
+ int /*depth*/,
+ unsigned char * /*rrops*/
+#endif
+);
+
+extern void ilbmComputeCompositeClip(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/,
+ DrawablePtr /*pDrawable*/
+#endif
+);
+
+/* ilbmgetsp.c */
+
+extern void ilbmGetSpans(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*wMax*/,
+ DDXPointPtr /*ppt*/,
+ int * /*pwidth*/,
+ int /*nspans*/,
+ char * /*pdstStart*/
+#endif
+);
+/* ilbmhrzvert.c */
+
+extern int ilbmHorzS(
+#if NeedFunctionPrototypes
+ PixelType * /*addrl*/,
+ int /*nlwidth*/,
+ int /*sizeDst*/,
+ int /*depthDst*/,
+ int /*x1*/,
+ int /*y1*/,
+ int /*len*/,
+ unsigned char * /*rrops*/
+#endif
+);
+
+extern int ilbmVertS(
+#if NeedFunctionPrototypes
+ PixelType * /*addrl*/,
+ int /*nlwidth*/,
+ int /*sizeDst*/,
+ int /*depthDst*/,
+ int /*x1*/,
+ int /*y1*/,
+ int /*len*/,
+ unsigned char * /*rrops*/
+#endif
+);
+/* ilbmigbblak.c */
+
+extern void ilbmImageGlyphBlt (
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+/* ilbmigbwht.c */
+
+/* ilbmimage.c */
+
+extern void ilbmPutImage(
+#if NeedFunctionPrototypes
+ DrawablePtr /*dst*/,
+ GCPtr /*pGC*/,
+ int /*depth*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ int /*leftPad*/,
+ int /*format*/,
+ char * /*pImage*/
+#endif
+);
+
+extern void ilbmGetImage(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*sx*/,
+ int /*sy*/,
+ int /*w*/,
+ int /*h*/,
+ unsigned int /*format*/,
+ unsigned long /*planeMask*/,
+ char * /*pdstLine*/
+#endif
+);
+/* ilbmline.c */
+
+extern void ilbmLineSS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/
+#endif
+);
+
+extern void ilbmLineSD(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/
+#endif
+);
+
+/* ilbmmisc.c */
+
+extern void ilbmQueryBestSize(
+#if NeedFunctionPrototypes
+ int /*class*/,
+ unsigned short * /*pwidth*/,
+ unsigned short * /*pheight*/,
+ ScreenPtr /*pScreen*/
+#endif
+);
+/* ilbmpntarea.c */
+
+extern void ilbmSolidFillArea(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ unsigned char * /*rrops*/
+#endif
+);
+
+extern void ilbmStippleAreaPPW(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ PixmapPtr /*pstipple*/,
+ unsigned char * /*rrops*/
+#endif
+);
+extern void ilbmStippleArea(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ PixmapPtr /*pstipple*/,
+ int /*xOff*/,
+ int /*yOff*/,
+ unsigned char * /*rrops*/
+#endif
+);
+/* ilbmplygblt.c */
+
+extern void ilbmPolyGlyphBlt(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+
+/* ilbmpixmap.c */
+
+extern PixmapPtr ilbmCreatePixmap(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ int /*width*/,
+ int /*height*/,
+ int /*depth*/
+#endif
+);
+
+extern Bool ilbmDestroyPixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPixmap*/
+#endif
+);
+
+extern PixmapPtr ilbmCopyPixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pSrc*/
+#endif
+);
+
+extern void ilbmPadPixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPixmap*/
+#endif
+);
+
+extern void ilbmXRotatePixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPix*/,
+ int /*rw*/
+#endif
+);
+
+extern void ilbmYRotatePixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPix*/,
+ int /*rh*/
+#endif
+);
+
+extern void ilbmCopyRotatePixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*psrcPix*/,
+ PixmapPtr * /*ppdstPix*/,
+ int /*xrot*/,
+ int /*yrot*/
+#endif
+);
+extern void ilbmPaintWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ RegionPtr /*pRegion*/,
+ int /*what*/
+#endif
+);
+/* ilbmpolypnt.c */
+
+extern void ilbmPolyPoint(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ xPoint * /*pptInit*/
+#endif
+);
+/* ilbmpushpxl.c */
+
+extern void ilbmPushPixels(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/,
+ PixmapPtr /*pBitMap*/,
+ DrawablePtr /*pDrawable*/,
+ int /*dx*/,
+ int /*dy*/,
+ int /*xOrg*/,
+ int /*yOrg*/
+#endif
+);
+/* ilbmscrclse.c */
+
+extern Bool ilbmCloseScreen(
+#if NeedFunctionPrototypes
+ int /*index*/,
+ ScreenPtr /*pScreen*/
+#endif
+);
+/* ilbmscrinit.c */
+
+extern Bool ilbmAllocatePrivates(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ int * /*pWinIndex*/,
+ int * /*pGCIndex*/
+#endif
+);
+
+extern Bool ilbmScreenInit(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ pointer /*pbits*/,
+ int /*xsize*/,
+ int /*ysize*/,
+ int /*dpix*/,
+ int /*dpiy*/,
+ int /*width*/
+#endif
+);
+
+extern PixmapPtr ilbmGetWindowPixmap(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern void ilbmSetWindowPixmap(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ PixmapPtr /*pPix*/
+#endif
+);
+
+/* ilbmseg.c */
+
+extern void ilbmSegmentSS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nseg*/,
+ xSegment * /*pSeg*/
+#endif
+);
+
+extern void ilbmSegmentSD(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nseg*/,
+ xSegment * /*pSeg*/
+#endif
+);
+/* ilbmsetsp.c */
+
+extern int ilbmSetScanline(
+#if NeedFunctionPrototypes
+ int /*y*/,
+ int /*xOrigin*/,
+ int /*xStart*/,
+ int /*xEnd*/,
+ PixelType * /*psrc*/,
+ int /*alu*/,
+ PixelType * /*pdstBase*/,
+ int /*widthDst*/,
+ int /*sizeDst*/,
+ int /*depthDst*/,
+ int /*sizeSrc*/
+#endif
+);
+
+extern void ilbmSetSpans(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ char * /*psrc*/,
+ DDXPointPtr /*ppt*/,
+ int * /*pwidth*/,
+ int /*nspans*/,
+ int /*fSorted*/
+#endif
+);
+/* ilbmtegblt.c */
+
+extern void ilbmTEGlyphBlt(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+/* ilbmtileC.c */
+
+extern void ilbmTileAreaPPWCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*ptile*/,
+ unsigned long /*planemask*/
+#endif
+);
+/* ilbmtileG.c */
+
+extern void ilbmTileAreaPPWGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*ptile*/,
+ unsigned long /*planemask*/
+#endif
+);
+
+extern void ilbmTileAreaCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*ptile*/,
+ int /*xOff*/,
+ int /*yOff*/,
+ unsigned long /*planemask*/
+#endif
+);
+/* ilbmtileG.c */
+
+extern void ilbmTileAreaGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*ptile*/,
+ int /*xOff*/,
+ int /*yOff*/,
+ unsigned long /*planemask*/
+#endif
+);
+
+extern void ilbmOpaqueStippleAreaPPWCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*ptile*/,
+ unsigned char */*rropsOS*/,
+ unsigned long /*planemask*/
+#endif
+);
+/* ilbmtileG.c */
+
+extern void ilbmOpaqueStippleAreaPPWGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*ptile*/,
+ unsigned char */*rropsOS*/,
+ unsigned long /*planemask*/
+#endif
+);
+
+extern void ilbmOpaqueStippleAreaCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*ptile*/,
+ int /*xOff*/,
+ int /*yOff*/,
+ unsigned char */*rropsOS*/,
+ unsigned long /*planemask*/
+#endif
+);
+/* ilbmtileG.c */
+
+extern void ilbmOpaqueStippleAreaGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*ptile*/,
+ int /*xOff*/,
+ int /*yOff*/,
+ unsigned char */*rropsOS*/,
+ unsigned long /*planemask*/
+#endif
+);
+
+/* ilbmwindow.c */
+
+extern Bool ilbmCreateWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern Bool ilbmDestroyWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern Bool ilbmMapWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWindow*/
+#endif
+);
+
+extern Bool ilbmPositionWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ int /*x*/,
+ int /*y*/
+#endif
+);
+
+extern Bool ilbmUnmapWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWindow*/
+#endif
+);
+
+extern void ilbmCopyWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ DDXPointRec /*ptOldOrg*/,
+ RegionPtr /*prgnSrc*/
+#endif
+);
+
+extern Bool ilbmChangeWindowAttributes(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ unsigned long /*mask*/
+#endif
+);
+/* ilbmzerarc.c */
+
+extern void ilbmZeroPolyArcSS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+
+/*
+ private field of pixmap
+ pixmap.devPrivate = (PixelType *)pointer_to_bits
+ pixmap.devKind = width_of_pixmap_in_bytes
+
+ private field of screen
+ a pixmap, for which we allocate storage. devPrivate is a pointer to
+the bits in the hardware framebuffer. note that devKind can be poked to
+make the code work for framebuffers that are wider than their
+displayable screen (e.g. the early vsII, which displayed 960 pixels
+across, but was 1024 in the hardware.)
+
+ private field of GC
+*/
+
+typedef struct {
+ unsigned char rrops[AFB_MAX_DEPTH]; /* reduction of rasterop to 1 of 3 */
+ unsigned char rropOS[AFB_MAX_DEPTH]; /* rop for opaque stipple */
+} ilbmPrivGC;
+typedef ilbmPrivGC *ilbmPrivGCPtr;
+
+extern int ilbmGCPrivateIndex; /* index into GC private array */
+extern int ilbmWindowPrivateIndex; /* index into Window private array */
+#ifdef PIXMAP_PER_WINDOW
+extern int frameWindowPrivateIndex; /* index into Window private array */
+#endif
+
+#define ilbmGetGCPrivate(pGC) \
+ ((ilbmPrivGC *)((pGC)->devPrivates[ilbmGCPrivateIndex].ptr))
+
+/* private field of window */
+typedef struct {
+ unsigned char fastBorder; /* non-zero if border tile is 32 bits wide */
+ unsigned char fastBackground;
+ unsigned short unused; /* pad for alignment with Sun compiler */
+ DDXPointRec oldRotate;
+ PixmapPtr pRotatedBackground;
+ PixmapPtr pRotatedBorder;
+} ilbmPrivWin;
+
+/* Common macros for extracting drawing information */
+
+#define ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, width, aux, dep, pointer) {\
+ PixmapPtr _pPix; \
+ if ((pDrawable)->type == DRAWABLE_WINDOW) \
+ _pPix = (PixmapPtr)(pDrawable)->pScreen->devPrivates[ilbmScreenPrivateIndex].ptr; \
+ else \
+ _pPix = (PixmapPtr)(pDrawable); \
+ (pointer) = (PixelType *)_pPix->devPrivate.ptr; \
+ (width) = ((int)_pPix->devKind)/sizeof(PixelType); \
+ (dep) = _pPix->drawable.depth; \
+ (aux) = (width)*(dep); \
+}
+
+/* ilbm uses the following macros to calculate addresses in drawables.
+ * To support banked framebuffers, the macros come in four flavors.
+ * All four collapse into the same definition on unbanked devices.
+ *
+ * ilbmScanlineFoo - calculate address and do bank switching
+ * ilbmScanlineFooNoBankSwitch - calculate address, don't bank switch
+ * ilbmScanlineFooSrc - calculate address, switch source bank
+ * ilbmScanlineFooDst - calculate address, switch destination bank
+ */
+
+/* The NoBankSwitch versions are the same for banked and unbanked cases */
+
+#define ilbmScanlineIncNoBankSwitch(_ptr, _off) _ptr += (_off)
+#define ilbmScanlineOffsetNoBankSwitch(_ptr, _off) ((_ptr)+(_off))
+#define ilbmScanlineDeltaNoBankSwitch(_ptr, _y, _w) \
+ ilbmScanlineOffsetNoBankSwitch(_ptr, (_y)*(_w))
+#define ilbmScanlineNoBankSwitch(_ptr, _x, _y, _w) \
+ ilbmScanlineOffsetNoBankSwitch(_ptr, (_y)*(_w)+((_x)>>MFB_PWSH))
+
+#ifdef MFB_LINE_BANK
+
+#include "ilbmlinebank.h" /* get macro definitions from this file */
+
+#else /* !MFB_LINE_BANK - unbanked case */
+
+#define ilbmScanlineInc(_ptr, _off) ilbmScanlineIncNoBankSwitch(_ptr, _off)
+#define ilbmScanlineIncSrc(_ptr, _off) ilbmScanlineInc(_ptr, _off)
+#define ilbmScanlineIncDst(_ptr, _off) ilbmScanlineInc(_ptr, _off)
+
+#define ilbmScanlineOffset(_ptr, _off) ilbmScanlineOffsetNoBankSwitch(_ptr, _off)
+#define ilbmScanlineOffsetSrc(_ptr, _off) ilbmScanlineOffset(_ptr, _off)
+#define ilbmScanlineOffsetDst(_ptr, _off) ilbmScanlineOffset(_ptr, _off)
+
+#define ilbmScanlineSrc(_ptr, _x, _y, _w) ilbmScanline(_ptr, _x, _y, _w)
+#define ilbmScanlineDst(_ptr, _x, _y, _w) ilbmScanline(_ptr, _x, _y, _w)
+
+#define ilbmScanlineDeltaSrc(_ptr, _y, _w) ilbmScanlineDelta(_ptr, _y, _w)
+#define ilbmScanlineDeltaDst(_ptr, _y, _w) ilbmScanlineDelta(_ptr, _y, _w)
+
+#endif /* MFB_LINE_BANK */
+
+#define ilbmScanlineDelta(_ptr, _y, _w) \
+ ilbmScanlineOffset(_ptr, (_y)*(_w))
+
+#define ilbmScanline(_ptr, _x, _y, _w) \
+ ilbmScanlineOffset(_ptr, (_y)*(_w)+((_x)>>MFB_PWSH))
+
+/* precomputed information about each glyph for GlyphBlt code.
+ this saves recalculating the per glyph information for each box.
+*/
+
+typedef struct _ilbmpos{
+ int xpos; /* xposition of glyph's origin */
+ int xchar; /* x position mod 32 */
+ int leftEdge;
+ int rightEdge;
+ int topEdge;
+ int bottomEdge;
+ PixelType *pdstBase; /* longword with character origin */
+ int widthGlyph; /* width in bytes of this glyph */
+} ilbmTEXTPOS;
+
+/* reduced raster ops for ilbm */
+#define RROP_BLACK GXclear
+#define RROP_WHITE GXset
+#define RROP_NOP GXnoop
+#define RROP_INVERT GXinvert
+#define RROP_COPY GXcopy
+
+/* macros for ilbmbitblt.c, ilbmfillsp.c
+ these let the code do one switch on the rop per call, rather
+ than a switch on the rop per item (span or rectangle.)
+*/
+
+#define fnCLEAR(src, dst) (0)
+#define fnAND(src, dst) (src & dst)
+#define fnANDREVERSE(src, dst) (src & ~dst)
+#define fnCOPY(src, dst) (src)
+#define fnANDINVERTED(src, dst) (~src & dst)
+#define fnNOOP(src, dst) (dst)
+#define fnXOR(src, dst) (src ^ dst)
+#define fnOR(src, dst) (src | dst)
+#define fnNOR(src, dst) (~(src | dst))
+#define fnEQUIV(src, dst) (~src ^ dst)
+#define fnINVERT(src, dst) (~dst)
+#define fnORREVERSE(src, dst) (src | ~dst)
+#define fnCOPYINVERTED(src, dst) (~src)
+#define fnORINVERTED(src, dst) (~src | dst)
+#define fnNAND(src, dst) (~(src & dst))
+#define fnSET(src, dst) (~0)
+
+/* Using a "switch" statement is much faster in most cases
+ * since the compiler can do a look-up table or multi-way branch
+ * instruction, depending on the architecture. The result on
+ * A Sun 3/50 is at least 2.5 times faster, assuming a uniform
+ * distribution of RasterOp operation types.
+ *
+ * However, doing some profiling on a running system reveals
+ * GXcopy is the operation over 99.5% of the time and
+ * GXxor is the next most frequent (about .4%), so we make special
+ * checks for those first.
+ *
+ * Note that this requires a change to the "calling sequence"
+ * since we can't engineer a "switch" statement to have an lvalue.
+ */
+#define DoRop(result, alu, src, dst) \
+{ \
+ if (alu == GXcopy) \
+ result = fnCOPY (src, dst); \
+ else if (alu == GXxor) \
+ result = fnXOR (src, dst); \
+ else \
+ switch (alu) { \
+ case GXclear: \
+ result = fnCLEAR (src, dst); \
+ break; \
+ case GXand: \
+ result = fnAND (src, dst); \
+ break; \
+ case GXandReverse: \
+ result = fnANDREVERSE (src, dst); \
+ break; \
+ case GXandInverted: \
+ result = fnANDINVERTED (src, dst); \
+ break; \
+ case GXnoop: \
+ result = fnNOOP (src, dst); \
+ break; \
+ case GXor: \
+ result = fnOR (src, dst); \
+ break; \
+ case GXnor: \
+ result = fnNOR (src, dst); \
+ break; \
+ case GXequiv: \
+ result = fnEQUIV (src, dst); \
+ break; \
+ case GXinvert: \
+ result = fnINVERT (src, dst); \
+ break; \
+ case GXorReverse: \
+ result = fnORREVERSE (src, dst); \
+ break; \
+ case GXcopyInverted: \
+ result = fnCOPYINVERTED (src, dst); \
+ break; \
+ case GXorInverted: \
+ result = fnORINVERTED (src, dst); \
+ break; \
+ case GXnand: \
+ result = fnNAND (src, dst); \
+ break; \
+ case GXset: \
+ result = fnSET (src, dst); \
+ break; \
+ } \
+}
+
+
+/* C expression fragments for various operations. These get passed in
+ * as -D's on the compile command line. See ilbm/Imakefile. This
+ * fixes XBUG 6319.
+ *
+ * This seems like a good place to point out that ilbm's use of the
+ * words black and white is an unfortunate misnomer. In ilbm code, black
+ * means zero, and white means one.
+ */
+#define MFB_OPEQ_WHITE |=
+#define MFB_OPEQ_BLACK &=~
+#define MFB_OPEQ_INVERT ^=
+#define MFB_EQWHOLEWORD_WHITE =~0
+#define MFB_EQWHOLEWORD_BLACK =0
+#define MFB_EQWHOLEWORD_INVERT ^=~0
+#define MFB_OP_WHITE /* nothing */
+#define MFB_OP_BLACK ~
diff --git a/xc/programs/Xserver/ilbm/ilbmbitblt.c b/xc/programs/Xserver/ilbm/ilbmbitblt.c
new file mode 100644
index 000000000..6af3108b5
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmbitblt.c
@@ -0,0 +1,479 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmbitblt.c,v 3.2 1998/03/20 21:08:00 hohndel Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmbitblt.c,v 5.25 94/04/17 20:28:16 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "Xprotostr.h"
+
+#include "miscstruct.h"
+#include "regionstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+#include "mi.h"
+
+#include "ilbm.h"
+#include "maskbits.h"
+
+
+static unsigned char ilbmRropsOS[AFB_MAX_DEPTH];
+
+/* CopyArea and CopyPlane for a monchrome frame buffer
+
+
+ clip the source rectangle to the source's available bits. (this
+avoids copying unnecessary pieces that will just get exposed anyway.)
+this becomes the new shape of the destination.
+ clip the destination region to the composite clip in the
+GC. this requires translating the destination region to (dstx, dsty).
+ build a list of source points, one for each rectangle in the
+destination. this is a simple translation.
+ go do the multiple rectangle copies
+ do graphics exposures
+*/
+/** Optimized for drawing pixmaps into windows, especially when drawing into
+ ** unobscured windows. Calls to the general-purpose region code were
+ ** replaced with rectangle-to-rectangle clipping comparisions. This is
+ ** possible, since the pixmap is a single rectangle. In an unobscured
+ ** window, the destination clip is also a single rectangle, and region
+ ** code can be avoided entirely. This is a big savings, since the region
+ ** code uses XAlloc() and makes many function calls.
+ **
+ ** In addition, if source is a pixmap, there is no need to call the
+ ** expensive miHandleExposures() routine. Instead, we simply return NULL.
+ **
+ ** Previously, drawing a pixmap into an unobscured window executed at least
+ ** 8 XAlloc()'s, 30 function calls, and hundreds of lines of code.
+ **
+ ** Now, the same operation requires no XAlloc()'s, no region function calls,
+ ** and much less overhead. Nice for drawing lots of small pixmaps.
+ */
+
+void
+ilbmDoBitblt(pSrc, pDst, alu, prgnDst, pptSrc, planemask)
+ DrawablePtr pSrc, pDst;
+ int alu;
+ RegionPtr prgnDst;
+ DDXPointPtr pptSrc;
+ unsigned long planemask;
+{
+ switch (alu) {
+ case GXcopy:
+ ilbmDoBitbltCopy(pSrc, pDst, alu, prgnDst, pptSrc, planemask);
+ break;
+ case GXxor:
+ ilbmDoBitbltXor(pSrc, pDst, alu, prgnDst, pptSrc, planemask);
+ break;
+ case GXcopyInverted:
+ ilbmDoBitbltCopyInverted(pSrc, pDst, alu, prgnDst, pptSrc, planemask);
+ break;
+ case GXor:
+ ilbmDoBitbltOr(pSrc, pDst, alu, prgnDst, pptSrc, planemask);
+ break;
+ default:
+ ilbmDoBitbltGeneral(pSrc, pDst, alu, prgnDst, pptSrc, planemask);
+ break;
+ }
+}
+
+RegionPtr
+ilbmCopyArea(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height,
+ dstx, dsty)
+ DrawablePtr pSrcDrawable;
+ DrawablePtr pDstDrawable;
+ GC *pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+{
+ void (*doBitBlt)();
+
+ switch (pGC->alu) {
+ case GXcopy:
+ doBitBlt = ilbmDoBitbltCopy;
+ break;
+ case GXxor:
+ doBitBlt = ilbmDoBitbltXor;
+ break;
+ case GXcopyInverted:
+ doBitBlt = ilbmDoBitbltCopyInverted;
+ break;
+ case GXor:
+ doBitBlt = ilbmDoBitbltOr;
+ break;
+ default:
+ doBitBlt = ilbmDoBitbltGeneral;
+ break;
+ }
+
+ return(ilbmBitBlt(pSrcDrawable, pDstDrawable, pGC, srcx, srcy,
+ width, height, dstx, dsty, doBitBlt, pGC->planemask));
+}
+
+RegionPtr
+ilbmBitBlt(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height,
+ dstx, dsty, doBitBlt, planemask)
+ register DrawablePtr pSrcDrawable;
+ register DrawablePtr pDstDrawable;
+ register GC *pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+ void (*doBitBlt)();
+ unsigned long planemask;
+{
+ RegionPtr prgnSrcClip; /* may be a new region, or just a copy */
+ Bool freeSrcClip = FALSE;
+
+ RegionPtr prgnExposed;
+ RegionRec rgnDst;
+ DDXPointPtr pptSrc;
+ register DDXPointPtr ppt;
+ register BoxPtr pbox;
+ int i;
+ register int dx;
+ register int dy;
+ xRectangle origSource;
+ DDXPointRec origDest;
+ int numRects;
+ BoxRec fastBox;
+ int fastClip = 0; /* for fast clipping with pixmap source */
+ int fastExpose = 0; /* for fast exposures with pixmap source */
+ void (*localDoBitBlt)();
+
+ origSource.x = srcx;
+ origSource.y = srcy;
+ origSource.width = width;
+ origSource.height = height;
+ origDest.x = dstx;
+ origDest.y = dsty;
+
+ if ((pSrcDrawable != pDstDrawable) && pSrcDrawable->pScreen->SourceValidate)
+ (*pSrcDrawable->pScreen->SourceValidate)(pSrcDrawable, srcx, srcy, width,
+ height);
+
+ srcx += pSrcDrawable->x;
+ srcy += pSrcDrawable->y;
+
+ /* clip the source */
+
+ if (pSrcDrawable->type == DRAWABLE_PIXMAP)
+ if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE))
+ prgnSrcClip = pGC->pCompositeClip;
+ else
+ fastClip = 1;
+ else if (pGC->subWindowMode == IncludeInferiors)
+ if (!((WindowPtr)pSrcDrawable)->parent)
+ /*
+ * special case bitblt from root window in
+ * IncludeInferiors mode; just like from a pixmap
+ */
+ fastClip = 1;
+ else if ((pSrcDrawable == pDstDrawable) &&
+ (pGC->clientClipType == CT_NONE))
+ prgnSrcClip = pGC->pCompositeClip;
+ else {
+ prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
+ freeSrcClip = TRUE;
+ }
+ else
+ prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
+
+ fastBox.x1 = srcx;
+ fastBox.y1 = srcy;
+ fastBox.x2 = srcx + width;
+ fastBox.y2 = srcy + height;
+
+ /* Don't create a source region if we are doing a fast clip */
+ if (fastClip) {
+ fastExpose = 1;
+ /*
+ * clip the source; if regions extend beyond the source size,
+ * make sure exposure events get sent
+ */
+ if (fastBox.x1 < pSrcDrawable->x) {
+ fastBox.x1 = pSrcDrawable->x;
+ fastExpose = 0;
+ }
+ if (fastBox.y1 < pSrcDrawable->y) {
+ fastBox.y1 = pSrcDrawable->y;
+ fastExpose = 0;
+ }
+ if (fastBox.x2 > pSrcDrawable->x + (int)pSrcDrawable->width) {
+ fastBox.x2 = pSrcDrawable->x + (int)pSrcDrawable->width;
+ fastExpose = 0;
+ }
+ if (fastBox.y2 > pSrcDrawable->y + (int)pSrcDrawable->height) {
+ fastBox.y2 = pSrcDrawable->y + (int)pSrcDrawable->height;
+ fastExpose = 0;
+ }
+ } else {
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+ REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
+ }
+
+ dstx += pDstDrawable->x;
+ dsty += pDstDrawable->y;
+
+ if (pDstDrawable->type == DRAWABLE_WINDOW)
+ if (!((WindowPtr)pDstDrawable)->realized) {
+ if (!fastClip)
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return NULL;
+ }
+
+ dx = srcx - dstx;
+ dy = srcy - dsty;
+
+ /* Translate and clip the dst to the destination composite clip */
+ if (fastClip) {
+ RegionPtr cclip;
+
+ /* Translate the region directly */
+ fastBox.x1 -= dx;
+ fastBox.x2 -= dx;
+ fastBox.y1 -= dy;
+ fastBox.y2 -= dy;
+
+ /* If the destination composite clip is one rectangle we can
+ do the clip directly. Otherwise we have to create a full
+ blown region and call intersect */
+ cclip = pGC->pCompositeClip;
+ if (REGION_NUM_RECTS(cclip) == 1) {
+ BoxPtr pBox = REGION_RECTS(cclip);
+
+ if (fastBox.x1 < pBox->x1)
+ fastBox.x1 = pBox->x1;
+ if (fastBox.x2 > pBox->x2)
+ fastBox.x2 = pBox->x2;
+ if (fastBox.y1 < pBox->y1)
+ fastBox.y1 = pBox->y1;
+ if (fastBox.y2 > pBox->y2)
+ fastBox.y2 = pBox->y2;
+
+ /* Check to see if the region is empty */
+ if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2) {
+ REGION_INIT(pGC->pScreen, &rgnDst, NullBox, 0);
+ } else {
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+ }
+ } else {
+ /* We must turn off fastClip now, since we must create
+ a full blown region. It is intersected with the
+ composite clip below. */
+ fastClip = 0;
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox,1);
+ }
+ } else
+ REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
+
+ if (!fastClip) {
+ REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, pGC->pCompositeClip);
+ }
+
+ /* Do bit blitting */
+ numRects = REGION_NUM_RECTS(&rgnDst);
+ if (numRects && width && height) {
+ if (!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects *
+ sizeof(DDXPointRec)))) {
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return NULL;
+ }
+ pbox = REGION_RECTS(&rgnDst);
+ ppt = pptSrc;
+ for (i = numRects; --i >= 0; pbox++, ppt++) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ (*doBitBlt)(pSrcDrawable, pDstDrawable, pGC->alu, &rgnDst, pptSrc,
+ planemask);
+
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+
+ prgnExposed = NULL;
+ if (pGC->fExpose) {
+ /* Pixmap sources generate a NoExposed (we return NULL to do this) */
+ if (!fastExpose)
+ prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
+ origSource.x, origSource.y,
+ (int)origSource.width,
+ (int)origSource.height, origDest.x,
+ origDest.y, (unsigned long)0);
+ }
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return prgnExposed;
+}
+
+RegionPtr
+ilbmCopyPlane(pSrcDrawable, pDstDrawable, pGC, srcx, srcy, width, height,
+ dstx, dsty, plane)
+DrawablePtr pSrcDrawable, pDstDrawable;
+register GC *pGC;
+int srcx, srcy;
+int width, height;
+int dstx, dsty;
+unsigned long plane;
+{
+ int alu;
+ RegionPtr prgnExposed = NULL;
+ unsigned long old_planemask;
+ PixmapPtr pPixmap = NULL;
+
+ if (pDstDrawable->depth == 1) {
+ old_planemask = pGC->planemask;
+ pGC->planemask = plane;
+ if ((pGC->fgPixel & 1) == 1 && (pGC->bgPixel & 1) == 0) {
+ prgnExposed = (*pGC->ops->CopyArea)(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ } else if ((pGC->fgPixel & 1) == (pGC->bgPixel & 1)) {
+ unsigned char rop;
+
+ ilbmReduceRop(pGC->alu, pGC->fgPixel, 1, 1, &rop);
+ alu = pGC->alu;
+ pGC->alu = rop;
+ prgnExposed = (*pGC->ops->CopyArea)(pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx,
+ dsty);
+ pGC->alu = alu;
+ } else { /* need to invert the src */
+ alu = pGC->alu;
+ pGC->alu = ilbmInverseAlu[alu];
+ prgnExposed = (*pGC->ops->CopyArea)(pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx,
+ dsty);
+ pGC->alu = alu;
+ }
+ pGC->planemask = old_planemask;
+ } else {
+ int free_pixmap = FALSE;
+ PixmapPtr pBitmap = (PixmapPtr)pSrcDrawable;
+ ScreenPtr pScreen = pSrcDrawable->pScreen;
+ GCPtr pGC1;
+
+ if (pSrcDrawable == pDstDrawable ||
+ pSrcDrawable->type == DRAWABLE_WINDOW || pSrcDrawable->depth != 1) {
+ /* Copy a plane from source drawable to a tmp 1-bit deep pixmap */
+ /* XXX: Range check width and height */
+ pBitmap = (*pScreen->CreatePixmap)(pScreen, width, height, 1);
+
+ if (!pBitmap)
+ return(NULL);
+ pGC1 = GetScratchGC(1, pScreen);
+ if (!pGC1) {
+ (*pScreen->DestroyPixmap)(pBitmap);
+ return(NULL);
+ }
+ ValidateGC((DrawablePtr)pBitmap, pGC1);
+ (void)ilbmBitBlt(pSrcDrawable, (DrawablePtr)pBitmap, pGC1, srcx, srcy,
+ width, height, 0, 0, ilbmDoBitbltCopy, plane);
+ free_pixmap = TRUE;
+ }
+#if 0
+ else {
+ /* XXX: could cope with N-deep pixmap source case without using tmp
+ * src bitmap by setting up a scratch pixmap header and fiddle
+ * around with the pbits pointer.
+ */
+ }
+#endif
+ ilbmReduceOpaqueStipple(pGC->fgPixel, pGC->bgPixel, pGC->planemask,
+ pGC->depth, ilbmRropsOS);
+ (void)ilbmBitBlt((DrawablePtr)pBitmap, pDstDrawable, pGC, 0, 0, width,
+ height, dstx, dsty, ilbmCopy1ToN, pGC->planemask);
+ if (free_pixmap) {
+ (*pScreen->DestroyPixmap)(pBitmap);
+ FreeScratchGC(pGC1);
+ }
+
+ if (pGC->fExpose)
+ prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, srcx,
+ srcy, width, height, dstx, dsty,
+ plane);
+ }
+ return prgnExposed;
+}
+
+void
+ilbmCopy1ToN(pSrc, pDst, alu, prgnDst, pptSrc, planemask)
+ DrawablePtr pSrc, pDst;
+ int alu;
+ RegionPtr prgnDst;
+ DDXPointPtr pptSrc;
+ unsigned long planemask;
+{
+ int numRects = REGION_NUM_RECTS(prgnDst);
+ BoxPtr pbox = REGION_RECTS(prgnDst);
+ int r;
+
+ for (r = 0; r < numRects; r++, pbox++, pptSrc++) {
+ int dx = pptSrc->x;
+ int dy = pptSrc->y;
+
+ if (alu == GXcopy)
+ ilbmOpaqueStippleAreaCopy(pDst, 1, pbox, alu, (PixmapPtr)pSrc, dx, dy,
+ ilbmRropsOS, planemask);
+ else
+ ilbmOpaqueStippleAreaGeneral(pDst, 1, pbox, alu, (PixmapPtr)pSrc, dx,
+ dy, ilbmRropsOS, planemask);
+ }
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmblt.c b/xc/programs/Xserver/ilbm/ilbmblt.c
new file mode 100644
index 000000000..455c07cb5
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmblt.c
@@ -0,0 +1,569 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmblt.c,v 3.0 1996/08/18 01:53:39 dawes Exp $ */
+/*
+ * ilbm copy area
+ */
+
+/*
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+Author: Keith Packard
+
+*/
+/* $XConsortium: ilbmblt.c,v 1.11 94/04/17 20:28:16 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "ilbm.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "maskbits.h"
+#include "fastblt.h"
+#include "mergerop.h"
+
+void
+MROP_NAME(ilbmDoBitblt)(pSrc, pDst, alu, prgnDst, pptSrc, planemask)
+ DrawablePtr pSrc, pDst;
+ int alu;
+ RegionPtr prgnDst;
+ DDXPointPtr pptSrc;
+ unsigned long planemask;
+{
+ PixelType *psrcBase, *pdstBase; /* start of src and dst bitmaps */
+ int widthSrc, widthDst; /* add to get to same position in next line */
+ int heightSrc, heightDst;
+ int auxSrc, auxDst;
+
+ BoxPtr pbox;
+ int nbox;
+
+ BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
+ /* temporaries for shuffling rectangles */
+ DDXPointPtr pptTmp, pptNew1, pptNew2;
+ /* shuffling boxes entails shuffling the
+ source points too */
+ int w, h;
+ int xdir; /* 1 = left right, -1 = right left/ */
+ int ydir; /* 1 = top down, -1 = bottom up */
+
+ PixelType *psrcLine, *pdstLine;
+ /* pointers to line with current src and dst */
+ register PixelType *psrc; /* pointer to current src longword */
+ register PixelType *pdst; /* pointer to current dst longword */
+
+ MROP_DECLARE_REG()
+
+ /* following used for looping through a line */
+ PixelType startmask, endmask; /* masks for writing ends of dst */
+ int nlMiddle; /* whole longwords in dst */
+ int xoffSrc, xoffDst;
+ register int leftShift, rightShift;
+ register PixelType bits;
+ register PixelType bits1;
+ register int nl; /* temp copy of nlMiddle */
+
+ /* place to store full source word */
+ int nstart; /* number of ragged bits at start of dst */
+ int nend; /* number of ragged bits at end of dst */
+ int srcStartOver; /* pulling nstart bits from src
+ overflows into the next word? */
+ int careful;
+ int tmpSrc;
+ int depthSrc;
+ int depthDst;
+
+ MROP_INITIALIZE(alu,0);
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pSrc, widthSrc, auxSrc, depthSrc,
+ psrcBase);
+ ilbmGetPixelWidthAuxDepthAndPointer(pDst, widthDst, auxDst, depthDst,
+ pdstBase);
+
+ /* Special case where depth of dest pixmap is 1 but source pixmap isn't
+ * Used for GetImage to copy a plane from a source pixmap to a particular
+ * dest pixmap plane.
+ * Note: planemask should have only one bit set or several planes from
+ * the source will be copied to the same dest plane.
+ */
+ if (depthDst == 1 && depthDst != depthSrc)
+ widthDst = 0;
+
+ /* XXX we have to err on the side of safety when both are windows,
+ * because we don't know if IncludeInferiors is being used.
+ */
+ careful = ((pSrc == pDst) ||
+ ((pSrc->type == DRAWABLE_WINDOW) &&
+ (pDst->type == DRAWABLE_WINDOW)));
+
+ pbox = REGION_RECTS(prgnDst);
+ nbox = REGION_NUM_RECTS(prgnDst);
+
+ pboxNew1 = NULL;
+ pptNew1 = NULL;
+ pboxNew2 = NULL;
+ pptNew2 = NULL;
+ if (careful && (pptSrc->y < pbox->y1)) {
+ /* walk source botttom to top */
+ ydir = -1;
+ auxSrc = -auxSrc;
+ auxDst = -auxDst;
+
+ if (nbox > 1) {
+ /* keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox);
+ if (!pboxNew1)
+ return;
+ pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox);
+ if (!pptNew1) {
+ DEALLOCATE_LOCAL(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox) {
+ while ((pboxNext >= pbox) &&
+ (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp <= pboxBase) {
+ *pboxNew1++ = *pboxTmp++;
+ *pptNew1++ = *pptTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ pptNew1 -= nbox;
+ pptSrc = pptNew1;
+ }
+ } else {
+ /* walk source top to bottom */
+ ydir = 1;
+ }
+
+ if (careful && (pptSrc->x < pbox->x1)) {
+ /* walk source right to left */
+ xdir = -1;
+
+ if (nbox > 1) {
+ /* reverse order of rects in each band */
+ pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if (!pboxNew2 || !pptNew2) {
+ if (pptNew2)
+ DEALLOCATE_LOCAL(pptNew2);
+ if (pboxNew2)
+ DEALLOCATE_LOCAL(pboxNew2);
+ if (pboxNew1) {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox) {
+ while ((pboxNext < pbox+nbox) && (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp != pboxBase) {
+ *pboxNew2++ = *--pboxTmp;
+ *pptNew2++ = *--pptTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ pptNew2 -= nbox;
+ pptSrc = pptNew2;
+ }
+ } else {
+ /* walk source left to right */
+ xdir = 1;
+ }
+
+ while (nbox--) {
+ int d;
+ for (d = 0; d < depthSrc; d++) {
+ PixelType *psrcB;
+ PixelType *pdstB;
+
+ if (!(planemask & (1 << d)))
+ continue;
+
+ psrcB = psrcBase + widthSrc * d; /* @@@ NEXT PLANE @@@ */
+ pdstB = pdstBase + widthDst * d; /* @@@ NEXT PLANE @@@ */
+
+ w = pbox->x2 - pbox->x1;
+ h = pbox->y2 - pbox->y1;
+
+ if (ydir == -1) { /* start at last scanline of rectangle */
+ psrcLine = ilbmScanlineDeltaSrc(psrcB, -(pptSrc->y+h-1), auxSrc);
+ pdstLine = ilbmScanlineDeltaDst(pdstB, -(pbox->y2-1), auxDst);
+ } else { /* start at first scanline */
+ psrcLine = ilbmScanlineDeltaSrc(psrcB, pptSrc->y, auxSrc);
+ pdstLine = ilbmScanlineDeltaDst(pdstB, pbox->y1, auxDst);
+ }
+ if ((pbox->x1 & PIM) + w <= PPW) {
+ maskpartialbits (pbox->x1, w, startmask);
+ endmask = 0;
+ nlMiddle = 0;
+ } else {
+ maskbits(pbox->x1, w, startmask, endmask, nlMiddle);
+ }
+ if (xdir == 1) {
+ xoffSrc = pptSrc->x & PIM;
+ xoffDst = pbox->x1 & PIM;
+ pdstLine += (pbox->x1 >> PWSH);
+ psrcLine += (pptSrc->x >> PWSH);
+#ifdef DO_UNALIGNED_BITBLT
+ nl = xoffSrc - xoffDst;
+ psrcLine = (PixelType *)(((unsigned char *) psrcLine) + nl);
+#else
+ if (xoffSrc == xoffDst)
+#endif
+ {
+ while (h--) {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ if (startmask) {
+ *pdst = MROP_MASK(*psrc, *pdst, startmask);
+ psrc++;
+ pdst++;
+ }
+ nl = nlMiddle;
+
+#ifdef LARGE_INSTRUCTION_CACHE
+#ifdef FAST_CONSTANT_OFFSET_MODE
+
+ psrc += nl & (UNROLL-1);
+ pdst += nl & (UNROLL-1);
+
+#define BodyOdd(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]);
+#define BodyEven(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]);
+
+#define LoopReset \
+pdst += UNROLL; \
+psrc += UNROLL;
+
+#else
+
+#define BodyOdd(n) *pdst = MROP_SOLID (*psrc, *pdst); pdst++; psrc++;
+#define BodyEven(n) BodyOdd(n)
+
+#define LoopReset ;
+
+#endif
+ PackedLoop
+
+#undef BodyOdd
+#undef BodyEven
+#undef LoopReset
+
+#else
+#ifdef NOTDEF
+ /* you'd think this would be faster --
+ * a single instruction instead of 6
+ * but measurements show it to be ~15% slower
+ */
+ while ((nl -= 6) >= 0) {
+ asm ("moveml %1+,#0x0c0f;moveml#0x0c0f,%0"
+ : "=m" (*(char *)pdst)
+ : "m" (*(char *)psrc)
+ : "d0", "d1", "d2", "d3",
+ "a2", "a3");
+ pdst += 6;
+ }
+ nl += 6;
+ while (nl--)
+ *pdst++ = *psrc++;
+#endif
+ DuffL(nl, label1,
+ *pdst = MROP_SOLID (*psrc, *pdst);
+ pdst++; psrc++;)
+#endif
+
+ if (endmask)
+ *pdst = MROP_MASK(*psrc, *pdst, endmask);
+ ilbmScanlineIncDst(pdstLine, auxDst);
+ ilbmScanlineIncSrc(psrcLine, auxSrc);
+ }
+ }
+#ifndef DO_UNALIGNED_BITBLT
+ else {
+ if (xoffSrc > xoffDst) {
+ leftShift = (xoffSrc - xoffDst);
+ rightShift = PPW - leftShift;
+ } else {
+ rightShift = (xoffDst - xoffSrc);
+ leftShift = PPW - rightShift;
+ }
+ while (h--) {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ bits = 0;
+ if (xoffSrc > xoffDst)
+ bits = *psrc++;
+ if (startmask) {
+ bits1 = BitLeft(bits,leftShift);
+ bits = *psrc++;
+ bits1 |= BitRight(bits,rightShift);
+ *pdst = MROP_MASK(bits1, *pdst, startmask);
+ pdst++;
+ }
+ nl = nlMiddle;
+
+#ifdef LARGE_INSTRUCTION_CACHE
+ bits1 = bits;
+
+#ifdef FAST_CONSTANT_OFFSET_MODE
+
+ psrc += nl & (UNROLL-1);
+ pdst += nl & (UNROLL-1);
+
+#define BodyOdd(n) \
+bits = psrc[-n]; \
+pdst[-n] = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), pdst[-n]);
+
+#define BodyEven(n) \
+bits1 = psrc[-n]; \
+pdst[-n] = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), pdst[-n]);
+
+#define LoopReset \
+pdst += UNROLL; \
+psrc += UNROLL;
+
+#else
+
+#define BodyOdd(n) \
+bits = *psrc++; \
+*pdst = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), *pdst); \
+pdst++;
+
+#define BodyEven(n) \
+bits1 = *psrc++; \
+*pdst = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), *pdst); \
+pdst++;
+
+#define LoopReset ;
+
+#endif /* !FAST_CONSTANT_OFFSET_MODE */
+
+ PackedLoop
+
+#undef BodyOdd
+#undef BodyEven
+#undef LoopReset
+
+#else
+ DuffL(nl,label2,
+ bits1 = BitLeft(bits, leftShift);
+ bits = *psrc++;
+ *pdst = MROP_SOLID (bits1 | BitRight(bits, rightShift), *pdst);
+ pdst++;
+ )
+#endif
+
+ if (endmask) {
+ bits1 = BitLeft(bits, leftShift);
+ if (BitLeft(endmask, rightShift)) {
+ bits = *psrc;
+ bits1 |= BitRight(bits, rightShift);
+ }
+ *pdst = MROP_MASK (bits1, *pdst, endmask);
+ }
+ ilbmScanlineIncDst(pdstLine, auxDst);
+ ilbmScanlineIncSrc(psrcLine, auxSrc);
+ }
+ }
+#endif /* DO_UNALIGNED_BITBLT */
+ } else { /* xdir == -1 */
+ xoffSrc = (pptSrc->x + w - 1) & PIM;
+ xoffDst = (pbox->x2 - 1) & PIM;
+ pdstLine += ((pbox->x2-1) >> PWSH) + 1;
+ psrcLine += ((pptSrc->x+w - 1) >> PWSH) + 1;
+#ifdef DO_UNALIGNED_BITBLT
+ nl = xoffSrc - xoffDst;
+ psrcLine = (PixelType *)
+ (((unsigned char *) psrcLine) + nl);
+#else
+ if (xoffSrc == xoffDst)
+#endif
+ {
+ while (h--) {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ if (endmask) {
+ pdst--;
+ psrc--;
+ *pdst = MROP_MASK (*psrc, *pdst, endmask);
+ }
+ nl = nlMiddle;
+
+#ifdef LARGE_INSTRUCTION_CACHE
+#ifdef FAST_CONSTANT_OFFSET_MODE
+ psrc -= nl & (UNROLL - 1);
+ pdst -= nl & (UNROLL - 1);
+
+#define BodyOdd(n) pdst[n-1] = MROP_SOLID (psrc[n-1], pdst[n-1]);
+
+#define BodyEven(n) BodyOdd(n)
+
+#define LoopReset \
+pdst -= UNROLL;\
+psrc -= UNROLL;
+
+#else
+
+#define BodyOdd(n) --pdst; --psrc; *pdst = MROP_SOLID(*psrc, *pdst);
+#define BodyEven(n) BodyOdd(n)
+#define LoopReset ;
+
+#endif
+ PackedLoop
+
+#undef BodyOdd
+#undef BodyEven
+#undef LoopReset
+
+#else
+ DuffL(nl,label3,
+ --pdst; --psrc; *pdst = MROP_SOLID (*psrc, *pdst);)
+#endif
+
+ if (startmask) {
+ --pdst;
+ --psrc;
+ *pdst = MROP_MASK(*psrc, *pdst, startmask);
+ }
+ ilbmScanlineIncDst(pdstLine, auxDst);
+ ilbmScanlineIncSrc(psrcLine, auxSrc);
+ }
+ }
+#ifndef DO_UNALIGNED_BITBLT
+ else {
+ if (xoffDst > xoffSrc) {
+ rightShift = (xoffDst - xoffSrc);
+ leftShift = PPW - rightShift;
+ } else {
+ leftShift = (xoffSrc - xoffDst);
+ rightShift = PPW - leftShift;
+ }
+ while (h--) {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ bits = 0;
+ if (xoffDst > xoffSrc)
+ bits = *--psrc;
+ if (endmask) {
+ bits1 = BitRight(bits, rightShift);
+ bits = *--psrc;
+ bits1 |= BitLeft(bits, leftShift);
+ pdst--;
+ *pdst = MROP_MASK(bits1, *pdst, endmask);
+ }
+ nl = nlMiddle;
+
+#ifdef LARGE_INSTRUCTION_CACHE
+ bits1 = bits;
+#ifdef FAST_CONSTANT_OFFSET_MODE
+ psrc -= nl & (UNROLL - 1);
+ pdst -= nl & (UNROLL - 1);
+
+#define BodyOdd(n) \
+bits = psrc[n-1]; \
+pdst[n-1] = MROP_SOLID(BitRight(bits1, rightShift) | BitLeft(bits, leftShift),pdst[n-1]);
+
+#define BodyEven(n) \
+bits1 = psrc[n-1]; \
+pdst[n-1] = MROP_SOLID(BitRight(bits, rightShift) | BitLeft(bits1, leftShift),pdst[n-1]);
+
+#define LoopReset \
+pdst -= UNROLL; \
+psrc -= UNROLL;
+
+#else
+
+#define BodyOdd(n) \
+bits = *--psrc; --pdst; \
+*pdst = MROP_SOLID(BitRight(bits1, rightShift) | BitLeft(bits, leftShift),*pdst);
+
+#define BodyEven(n) \
+bits1 = *--psrc; --pdst; \
+*pdst = MROP_SOLID(BitRight(bits, rightShift) | BitLeft(bits1, leftShift),*pdst);
+
+#define LoopReset ;
+
+#endif
+
+ PackedLoop
+
+#undef BodyOdd
+#undef BodyEven
+#undef LoopReset
+
+#else
+ DuffL(nl, label4,
+ bits1 = BitRight(bits, rightShift);
+ bits = *--psrc;
+ --pdst;
+ *pdst = MROP_SOLID(bits1 | BitLeft(bits, leftShift),*pdst);
+ )
+#endif
+
+ if (startmask) {
+ bits1 = BitRight(bits, rightShift);
+ if (BitRight (startmask, leftShift)) {
+ bits = *--psrc;
+ bits1 |= BitLeft(bits, leftShift);
+ }
+ --pdst;
+ *pdst = MROP_MASK(bits1, *pdst, startmask);
+ }
+ ilbmScanlineIncDst(pdstLine, auxDst);
+ ilbmScanlineIncSrc(psrcLine, auxSrc);
+ }
+ }
+#endif
+ }
+ }
+ pbox++;
+ pptSrc++;
+ }
+ if (pboxNew2) {
+ DEALLOCATE_LOCAL(pptNew2);
+ DEALLOCATE_LOCAL(pboxNew2);
+ }
+ if (pboxNew1) {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmbres.c b/xc/programs/Xserver/ilbm/ilbmbres.c
new file mode 100644
index 000000000..4204c61b5
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmbres.c
@@ -0,0 +1,324 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmbres.c,v 3.0 1996/08/18 01:53:40 dawes Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmbres.c,v 1.22 94/04/17 20:28:17 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "misc.h"
+#include "ilbm.h"
+#include "maskbits.h"
+#include "miline.h"
+
+/* Solid bresenham line */
+/* NOTES
+ e2 is used less often than e1, so it's not in a register
+*/
+
+void
+ilbmBresS(addrlbase, nlwidth, auxDst, depthDst, signdx, signdy, axis, x1, y1,
+ e, e1, e2, len, rrops)
+PixelType *addrlbase; /* pointer to base of bitmap */
+int nlwidth; /* width in longwords of bitmap */
+int auxDst;
+int depthDst;
+int signdx, signdy; /* signs of directions */
+int axis; /* major axis (Y_AXIS or X_AXIS) */
+int x1, y1; /* initial point */
+register int e; /* error accumulator */
+register int e1; /* bresenham increments */
+int e2;
+int len; /* length of line */
+unsigned char *rrops;
+{
+ register int yinc; /* increment to next scanline, in bytes */
+ register PixelType *addrl; /* bitmask long pointer */
+ register PixelType bit; /* current bit being set/cleared/etc. */
+ PixelType leftbit = mask[0]; /* leftmost bit to process in new word */
+ PixelType rightbit = mask[PPW-1]; /* rightmost bit to process in new word */
+
+ register int e3 = e2-e1;
+ PixelType tmp;
+ int saveE;
+ int saveLen;
+ int d;
+
+ /* point to longword containing first point */
+ yinc = signdy * auxDst;
+ e = e-e1; /* to make looping easier */
+
+ if (!len)
+ return;
+
+ saveLen = len;
+ saveE = e;
+
+ for (d = 0; d < depthDst; d++) {
+ addrl = ilbmScanline(addrlbase, x1, y1, auxDst);
+ addrlbase += nlwidth; /* @@@ NEXT PLANE @@@ */
+ len = saveLen;
+ e = saveE;
+ bit = mask[x1 & PIM];
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ if (axis == X_AXIS) {
+ if (signdx > 0) {
+ tmp = *addrl;
+ for (;;) {
+ tmp &= ~bit;
+ if (!--len)
+ break;
+ bit = SCRRIGHT(bit,1);
+ e += e1;
+ if (e >= 0) {
+ *addrl = tmp;
+ ilbmScanlineInc(addrl, yinc);
+ e += e3;
+ if (!bit) {
+ bit = leftbit;
+ addrl ++;
+ }
+ tmp = *addrl;
+ } else if (!bit) {
+ *addrl = tmp;
+ bit = leftbit;
+ addrl ++;
+ tmp = *addrl;
+ }
+ }
+ *addrl = tmp;
+ } else {
+ tmp = *addrl;
+ for (;;) {
+ tmp &= ~bit;
+ if (!--len)
+ break;
+ e += e1;
+ bit = SCRLEFT(bit,1);
+ if (e >= 0) {
+ *addrl = tmp;
+ ilbmScanlineInc(addrl, yinc);
+ e += e3;
+ if (!bit) {
+ bit = rightbit;
+ addrl --;
+ }
+ tmp = *addrl;
+ } else if (!bit) {
+ *addrl = tmp;
+ bit = rightbit;
+ addrl --;
+ tmp = *addrl;
+ }
+ }
+ *addrl = tmp;
+ }
+ } /* if X_AXIS */ else {
+ if (signdx > 0) {
+ while (len--) {
+ *addrl &= ~bit;
+ e += e1;
+ if (e >= 0) {
+ bit = SCRRIGHT(bit,1);
+ if (!bit) { bit = leftbit;addrl ++; }
+ e += e3;
+ }
+ ilbmScanlineInc(addrl, yinc);
+ }
+ } else {
+ while (len--) {
+ *addrl &= ~bit;
+ e += e1;
+ if (e >= 0) {
+ bit = SCRLEFT(bit,1);
+ if (!bit) { bit = rightbit;addrl --; }
+ e += e3;
+ }
+ ilbmScanlineInc(addrl, yinc);
+ }
+ }
+ } /* else Y_AXIS */
+ break;
+
+ case RROP_WHITE:
+ if (axis == X_AXIS) {
+ if (signdx > 0) {
+ tmp = *addrl;
+ for (;;) {
+ tmp |= bit;
+ if (!--len)
+ break;
+ e += e1;
+ bit = SCRRIGHT(bit,1);
+ if (e >= 0) {
+ *addrl = tmp;
+ ilbmScanlineInc(addrl, yinc);
+ e += e3;
+ if (!bit) {
+ bit = leftbit;
+ addrl ++;
+ }
+ tmp = *addrl;
+ } else if (!bit) {
+ *addrl = tmp;
+ bit = leftbit;
+ addrl ++;
+ tmp = *addrl;
+ }
+ }
+ *addrl = tmp;
+ } else {
+ tmp = *addrl;
+ for (;;) {
+ tmp |= bit;
+ if (!--len)
+ break;
+ e += e1;
+ bit = SCRLEFT(bit,1);
+ if (e >= 0) {
+ *addrl = tmp;
+ ilbmScanlineInc(addrl, yinc);
+ e += e3;
+ if (!bit) {
+ bit = rightbit;
+ addrl --;
+ }
+ tmp = *addrl;
+ } else if (!bit) {
+ *addrl = tmp;
+ bit = rightbit;
+ addrl --;
+ tmp = *addrl;
+ }
+ }
+ *addrl = tmp;
+ }
+ } /* if X_AXIS */ else {
+ if (signdx > 0) {
+ while (len--) {
+ *addrl |= bit;
+ e += e1;
+ if (e >= 0) {
+ bit = SCRRIGHT(bit,1);
+ if (!bit) { bit = leftbit;addrl ++; }
+ e += e3;
+ }
+ ilbmScanlineInc(addrl, yinc);
+ }
+ } else {
+ while (len--) {
+ *addrl |= bit;
+ e += e1;
+ if (e >= 0) {
+ bit = SCRLEFT(bit,1);
+ if (!bit) { bit = rightbit;addrl --; }
+ e += e3;
+ }
+ ilbmScanlineInc(addrl, yinc);
+ }
+ }
+ } /* else Y_AXIS */
+ break;
+
+ case RROP_INVERT:
+ if (axis == X_AXIS) {
+ if (signdx > 0) {
+ while (len--) {
+ *addrl ^= bit;
+ e += e1;
+ if (e >= 0) {
+ ilbmScanlineInc(addrl, yinc);
+ e += e3;
+ }
+ bit = SCRRIGHT(bit,1);
+ if (!bit) { bit = leftbit;addrl ++; }
+ }
+ } else {
+ while (len--) {
+ *addrl ^= bit;
+ e += e1;
+ if (e >= 0) {
+ ilbmScanlineInc(addrl, yinc);
+ e += e3;
+ }
+ bit = SCRLEFT(bit,1);
+ if (!bit) { bit = rightbit;addrl --; }
+ }
+ }
+ } /* if X_AXIS */ else {
+ if (signdx > 0) {
+ while (len--) {
+ *addrl ^= bit;
+ e += e1;
+ if (e >= 0) {
+ bit = SCRRIGHT(bit,1);
+ if (!bit) { bit = leftbit;addrl ++; }
+ e += e3;
+ }
+ ilbmScanlineInc(addrl, yinc);
+ }
+ } else {
+ while (len--) {
+ *addrl ^= bit;
+ e += e1;
+ if (e >= 0) {
+ bit = SCRLEFT(bit,1);
+ if (!bit) { bit = rightbit; addrl --; }
+ e += e3;
+ }
+ ilbmScanlineInc(addrl, yinc);
+ }
+ }
+ } /* else Y_AXIS */
+ } /* switch */
+ } /* for (d = ... ) */
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmbresd.c b/xc/programs/Xserver/ilbm/ilbmbresd.c
new file mode 100644
index 000000000..75391e96b
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmbresd.c
@@ -0,0 +1,215 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmbresd.c,v 3.0 1996/08/18 01:53:41 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmbresd.c,v 1.10 94/04/17 20:28:18 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "misc.h"
+#include "ilbm.h"
+#include "maskbits.h"
+#include "miline.h"
+
+/* Dashed bresenham line */
+
+#define StepDash\
+ if (!--dashRemaining) { \
+ if (++ dashIndex == numInDashList) \
+ dashIndex = 0; \
+ dashRemaining = pDash[dashIndex]; \
+ rop = fgrop; \
+ if (dashIndex & 1) \
+ rop = bgrop; \
+ }
+
+void
+ilbmBresD(pdashIndex, pDash, numInDashList, pdashOffset, isDoubleDash,
+ addrlbase, nlwidth, auxDst, depthDst,
+ signdx, signdy, axis, x1, y1, e, e1, e2, len, rrops, bgrrops)
+int *pdashIndex; /* current dash */
+unsigned char *pDash; /* dash list */
+int numInDashList; /* total length of dash list */
+int *pdashOffset; /* offset into current dash */
+int isDoubleDash;
+PixelType *addrlbase; /* pointer to base of bitmap */
+int nlwidth; /* width in longwords of bitmap */
+int auxDst;
+int depthDst;
+int signdx, signdy; /* signs of directions */
+int axis; /* major axis (Y_AXIS or X_AXIS) */
+int x1, y1; /* initial point */
+register int e; /* error accumulator */
+register int e1; /* bresenham increments */
+int e2;
+int len; /* length of line */
+unsigned char *rrops;
+unsigned char *bgrrops;
+{
+ register int yinc; /* increment to next scanline, in bytes */
+ register PixelType *addrl;
+ register int e3 = e2-e1;
+ register unsigned long bit;
+ PixelType leftbit = mask[0]; /* leftmost bit to process in new word */
+ PixelType rightbit = mask[PPW-1]; /* rightmost bit to process in new word */
+ int dashIndex;
+ int dashOffset;
+ int dashRemaining;
+ int rop;
+ int fgrop;
+ int bgrop;
+ int saveE;
+ int saveLen;
+ int d;
+
+ dashOffset = *pdashOffset;
+ dashIndex = *pdashIndex;
+ dashRemaining = pDash[dashIndex] - dashOffset;
+ /* point to longword containing first point */
+
+ yinc = signdy * auxDst;
+ e = e-e1; /* to make looping easier */
+
+ saveE = e;
+ saveLen = len;
+
+ for (d = 0; d < depthDst; d++) {
+ addrl = ilbmScanline(addrlbase, x1, y1, auxDst);
+ addrlbase += nlwidth; /* @@@ NEXT PLANE @@@ */
+
+ fgrop = rrops[d];
+ bgrop = bgrrops[d];
+
+ e = saveE;
+ len = saveLen;
+ bit = mask[x1 & PIM];
+
+ rop = fgrop;
+ if (!isDoubleDash)
+ bgrop = -1;
+ if (dashIndex & 1)
+ rop = bgrop;
+
+ if (axis == X_AXIS) {
+ if (signdx > 0) {
+ while (len--) {
+ if (rop == RROP_BLACK)
+ *addrl &= ~bit;
+ else if (rop == RROP_WHITE)
+ *addrl |= bit;
+ else if (rop == RROP_INVERT)
+ *addrl ^= bit;
+ e += e1;
+ if (e >= 0) {
+ ilbmScanlineInc(addrl, yinc);
+ e += e3;
+ }
+ bit = SCRRIGHT(bit,1);
+ if (!bit) { bit = leftbit;addrl ++; }
+ StepDash
+ }
+ } else {
+ while (len--) {
+ if (rop == RROP_BLACK)
+ *addrl &= ~bit;
+ else if (rop == RROP_WHITE)
+ *addrl |= bit;
+ else if (rop == RROP_INVERT)
+ *addrl ^= bit;
+ e += e1;
+ if (e >= 0) {
+ ilbmScanlineInc(addrl, yinc);
+ e += e3;
+ }
+ bit = SCRLEFT(bit,1);
+ if (!bit) { bit = rightbit;addrl --; }
+ StepDash
+ }
+ }
+ } /* if X_AXIS */ else {
+ if (signdx > 0) {
+ while (len--) {
+ if (rop == RROP_BLACK)
+ *addrl &= ~bit;
+ else if (rop == RROP_WHITE)
+ *addrl |= bit;
+ else if (rop == RROP_INVERT)
+ *addrl ^= bit;
+ e += e1;
+ if (e >= 0) {
+ bit = SCRRIGHT(bit,1);
+ if (!bit) { bit = leftbit;addrl ++; }
+ e += e3;
+ }
+ ilbmScanlineInc(addrl, yinc);
+ StepDash
+ }
+ } else {
+ while (len--) {
+ if (rop == RROP_BLACK)
+ *addrl &= ~bit;
+ else if (rop == RROP_WHITE)
+ *addrl |= bit;
+ else if (rop == RROP_INVERT)
+ *addrl ^= bit;
+ e += e1;
+ if (e >= 0) {
+ bit = SCRLEFT(bit,1);
+ if (!bit) { bit = rightbit;addrl --; }
+ e += e3;
+ }
+ ilbmScanlineInc(addrl, yinc);
+ StepDash
+ }
+ }
+ } /* else Y_AXIS */
+ } /* for (d = ...) */
+ *pdashIndex = dashIndex;
+ *pdashOffset = pDash[dashIndex] - dashRemaining;
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmbstore.c b/xc/programs/Xserver/ilbm/ilbmbstore.c
new file mode 100644
index 000000000..8309e2600
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmbstore.c
@@ -0,0 +1,155 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmbstore.c,v 3.0 1996/08/18 01:53:43 dawes Exp $ */
+/* $XConsortium: ilbmbstore.c,v 5.7 94/04/17 20:28:18 dpw Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/*
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+*/
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "ilbm.h"
+#include "X.h"
+#include "mibstore.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * ilbmSaveAreas --
+ * Function called by miSaveAreas to actually fetch the areas to be
+ * saved into the backing pixmap. This is very simple to do, since
+ * ilbmDoBitblt is designed for this very thing. The region to save is
+ * already destination-relative and we're given the offset to the
+ * window origin, so we have only to create an array of points of the
+ * u.l. corners of the boxes in the region translated to the screen
+ * coordinate system and fetch the screen pixmap out of its devPrivate
+ * field....
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Data are copied from the screen into the pixmap.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+ilbmSaveAreas(pPixmap, prgnSave, xorg, yorg, pWin)
+ PixmapPtr pPixmap; /* Backing pixmap */
+ RegionPtr prgnSave; /* Region to save (pixmap-relative) */
+ int xorg; /* X origin of region */
+ int yorg; /* Y origin of region */
+ WindowPtr pWin;
+{
+ register DDXPointPtr pPt;
+ DDXPointPtr pPtsInit;
+ register BoxPtr pBox;
+ register int numRects;
+
+ numRects = REGION_NUM_RECTS(prgnSave);
+ pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(numRects * sizeof(DDXPointRec));
+ if (!pPtsInit)
+ return;
+
+ pBox = REGION_RECTS(prgnSave);
+ pPt = pPtsInit;
+ while (numRects--) {
+ pPt->x = pBox->x1 + xorg;
+ pPt->y = pBox->y1 + yorg;
+ pPt++;
+ pBox++;
+ }
+
+ ilbmDoBitblt((DrawablePtr)pPixmap->drawable.pScreen->devPrivates[ilbmScreenPrivateIndex].ptr,
+ (DrawablePtr)pPixmap,
+ GXcopy,
+ prgnSave,
+ pPtsInit, wBackingBitPlanes (pWin));
+
+ DEALLOCATE_LOCAL(pPtsInit);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * ilbmRestoreAreas --
+ * Function called by miRestoreAreas to actually fetch the areas to be
+ * restored from the backing pixmap. This is very simple to do, since
+ * ilbmDoBitblt is designed for this very thing. The region to restore is
+ * already destination-relative and we're given the offset to the
+ * window origin, so we have only to create an array of points of the
+ * u.l. corners of the boxes in the region translated to the pixmap
+ * coordinate system and fetch the screen pixmap out of its devPrivate
+ * field....
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Data are copied from the pixmap into the screen.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+ilbmRestoreAreas(pPixmap, prgnRestore, xorg, yorg, pWin)
+ PixmapPtr pPixmap; /* Backing pixmap */
+ RegionPtr prgnRestore; /* Region to restore (screen-relative)*/
+ int xorg; /* X origin of window */
+ int yorg; /* Y origin of window */
+ WindowPtr pWin;
+{
+ register DDXPointPtr pPt;
+ DDXPointPtr pPtsInit;
+ register BoxPtr pBox;
+ register int numRects;
+
+ numRects = REGION_NUM_RECTS(prgnRestore);
+ pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(numRects*sizeof(DDXPointRec));
+ if (!pPtsInit)
+ return;
+
+ pBox = REGION_RECTS(prgnRestore);
+ pPt = pPtsInit;
+ while (numRects--) {
+ pPt->x = pBox->x1 - xorg;
+ pPt->y = pBox->y1 - yorg;
+ pPt++;
+ pBox++;
+ }
+
+ ilbmDoBitblt((DrawablePtr)pPixmap,
+ (DrawablePtr)pPixmap->drawable.pScreen->devPrivates[ilbmScreenPrivateIndex].ptr,
+ GXcopy,
+ prgnRestore,
+ pPtsInit, wBackingBitPlanes (pWin));
+
+ DEALLOCATE_LOCAL(pPtsInit);
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmclip.c b/xc/programs/Xserver/ilbm/ilbmclip.c
new file mode 100644
index 000000000..4628e61d0
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmclip.c
@@ -0,0 +1,242 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmclip.c,v 3.0 1996/08/18 01:53:44 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmclip.c,v 5.6 94/04/17 20:28:19 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "miscstruct.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "gc.h"
+#include "maskbits.h"
+#include "mi.h"
+
+#define ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2) \
+if (((rx1) < (rx2)) && ((ry1) < (ry2)) && \
+ (!((reg)->data->numRects && \
+ ((r-1)->y1 == (ry1)) && \
+ ((r-1)->y2 == (ry2)) && \
+ ((r-1)->x1 <= (rx1)) && \
+ ((r-1)->x2 >= (rx2))))) { \
+ if ((reg)->data->numRects == (reg)->data->size) { \
+ miRectAlloc(reg, 1); \
+ fr = REGION_BOXPTR(reg); \
+ r = fr + (reg)->data->numRects; \
+ } \
+ r->x1 = (rx1); \
+ r->y1 = (ry1); \
+ r->x2 = (rx2); \
+ r->y2 = (ry2); \
+ (reg)->data->numRects++; \
+ if (r->x1 < (reg)->extents.x1) \
+ (reg)->extents.x1 = r->x1; \
+ if (r->x2 > (reg)->extents.x2) \
+ (reg)->extents.x2 = r->x2; \
+ r++; \
+}
+
+/* Convert bitmap clip mask into clipping region.
+ * First, goes through each line and makes boxes by noting the transitions
+ * from 0 to 1 and 1 to 0.
+ * Then it coalesces the current line with the previous if they have boxes
+ * at the same X coordinates.
+ */
+RegionPtr
+ilbmPixmapToRegion(pPix)
+ PixmapPtr pPix;
+{
+ register RegionPtr pReg;
+ register PixelType *pw, w;
+ register int ib;
+ int width, h, base, rx1, crects;
+ PixelType *pwLineEnd;
+ int irectPrevStart, irectLineStart;
+ register BoxPtr prectO, prectN;
+ BoxPtr FirstRect, rects, prectLineStart;
+ Bool fInBox, fSame;
+ register PixelType mask0 = mask[0];
+ PixelType *pwLine;
+ int nWidth;
+
+ pReg = REGION_CREATE(pPix->drawable.pScreen, NULL, 1);
+ if (!pReg)
+ return(NullRegion);
+ FirstRect = REGION_BOXPTR(pReg);
+ rects = FirstRect;
+
+ pwLine = (PixelType *)pPix->devPrivate.ptr;
+ nWidth = pPix->devKind/PGSZB;
+
+ width = pPix->drawable.width;
+ pReg->extents.x1 = width - 1;
+ pReg->extents.x2 = 0;
+ irectPrevStart = -1;
+ for (h = 0; h < pPix->drawable.height; h++) {
+ pw = pwLine;
+ pwLine += nWidth;
+ irectLineStart = rects - FirstRect;
+ /* If the Screen left most bit of the word is set, we're starting in
+ * a box */
+ if (*pw & mask0) {
+ fInBox = TRUE;
+ rx1 = 0;
+ } else
+ fInBox = FALSE;
+ /* Process all words which are fully in the pixmap */
+ pwLineEnd = pw + (width >> PWSH);
+ for (base = 0; pw < pwLineEnd; base += PPW) {
+ w = *pw++;
+ if (fInBox) {
+ if (!~w)
+ continue;
+ } else {
+ if (!w)
+ continue;
+ }
+ for (ib = 0; ib < PPW; ib++) {
+ /* If the Screen left most bit of the word is set, we're
+ * starting a box */
+ if (w & mask0) {
+ if (!fInBox) {
+ rx1 = base + ib;
+ /* start new box */
+ fInBox = TRUE;
+ }
+ } else {
+ if (fInBox) {
+ /* end box */
+ ADDRECT(pReg, rects, FirstRect, rx1, h, base + ib, h + 1);
+ fInBox = FALSE;
+ }
+ }
+ /* Shift the word VISUALLY left one. */
+ w = SCRLEFT(w, 1);
+ }
+ }
+ if (width & PIM) {
+ /* Process final partial word on line */
+ w = *pw++;
+ for (ib = 0; ib < (width & PIM); ib++) {
+ /* If the Screen left most bit of the word is set, we're
+ * starting a box */
+ if (w & mask0) {
+ if (!fInBox) {
+ rx1 = base + ib;
+ /* start new box */
+ fInBox = TRUE;
+ }
+ } else {
+ if (fInBox) {
+ /* end box */
+ ADDRECT(pReg, rects, FirstRect,
+ rx1, h, base + ib, h + 1);
+ fInBox = FALSE;
+ }
+ }
+ /* Shift the word VISUALLY left one. */
+ w = SCRLEFT(w, 1);
+ }
+ }
+ /* If scanline ended with last bit set, end the box */
+ if (fInBox) {
+ ADDRECT(pReg, rects, FirstRect,
+ rx1, h, base + (width & PIM), h + 1);
+ }
+ /* if all rectangles on this line have the same x-coords as
+ * those on the previous line, then add 1 to all the previous y2s and
+ * throw away all the rectangles from this line
+ */
+ fSame = FALSE;
+ if (irectPrevStart != -1) {
+ crects = irectLineStart - irectPrevStart;
+ if (crects == ((rects - FirstRect) - irectLineStart)) {
+ prectO = FirstRect + irectPrevStart;
+ prectN = prectLineStart = FirstRect + irectLineStart;
+ fSame = TRUE;
+ while (prectO < prectLineStart) {
+ if ((prectO->x1 != prectN->x1) || (prectO->x2 != prectN->x2)) {
+ fSame = FALSE;
+ break;
+ }
+ prectO++;
+ prectN++;
+ }
+ if (fSame) {
+ prectO = FirstRect + irectPrevStart;
+ while (prectO < prectLineStart) {
+ prectO->y2 += 1;
+ prectO++;
+ }
+ rects -= crects;
+ pReg->data->numRects -= crects;
+ }
+ }
+ }
+ if (!fSame)
+ irectPrevStart = irectLineStart;
+ }
+ if (!pReg->data->numRects)
+ pReg->extents.x1 = pReg->extents.x2 = 0;
+ else {
+ pReg->extents.y1 = REGION_BOXPTR(pReg)->y1;
+ pReg->extents.y2 = REGION_END(pReg)->y2;
+ if (pReg->data->numRects == 1) {
+ xfree(pReg->data);
+ pReg->data = (RegDataPtr)NULL;
+ }
+ }
+#ifdef DEBUG
+ if (!miValidRegion(pReg))
+ FatalError("Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__);
+#endif
+ return(pReg);
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmcmap.c b/xc/programs/Xserver/ilbm/ilbmcmap.c
new file mode 100644
index 000000000..10dadd968
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmcmap.c
@@ -0,0 +1,124 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmcmap.c,v 3.1 1998/11/22 10:37:40 dawes Exp $ */
+/* $XConsortium: ilbmcmap.c,v 4.19 94/04/17 20:28:46 dpw Exp $ */
+/************************************************************
+Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
+
+ 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 no-
+tice appear in all copies and that both that copyright no-
+tice and this permission notice appear in supporting docu-
+mentation, and that the names of Sun or X Consortium
+not be used in advertising or publicity pertaining to
+distribution of the software without specific prior
+written permission. Sun and X Consortium make no
+representations about the suitability of this software for
+any purpose. It is provided "as is" without any express or
+implied warranty.
+
+SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
+NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
+ABLE 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.
+
+********************************************************/
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "Xproto.h"
+#include "scrnintstr.h"
+#include "colormapst.h"
+#include "resource.h"
+#include "micmap.h"
+
+int
+ilbmListInstalledColormaps(pScreen, pmaps)
+ ScreenPtr pScreen;
+ Colormap *pmaps;
+{
+ return miListInstalledColormaps(pScreen, pmaps);
+}
+
+
+void
+ilbmInstallColormap(pmap)
+ ColormapPtr pmap;
+{
+ miInstallColormap(pmap);
+}
+
+void
+ilbmUninstallColormap(pmap)
+ ColormapPtr pmap;
+{
+ miUninstallColormap(pmap);
+}
+
+void
+ilbmResolveColor(pred, pgreen, pblue, pVisual)
+ unsigned short *pred, *pgreen, *pblue;
+ register VisualPtr pVisual;
+{
+ miResolveColor(pred, pgreen, pblue, pVisual);
+}
+
+Bool
+ilbmInitializeColormap(pmap)
+ register ColormapPtr pmap;
+{
+ return miInitializeColormap(pmap);
+}
+
+int
+ilbmExpandDirectColors(pmap, ndef, indefs, outdefs)
+ ColormapPtr pmap;
+ int ndef;
+ xColorItem *indefs, *outdefs;
+{
+ return miExpandDirectColors(pmap, ndef, indefs, outdefs);
+}
+
+Bool
+ilbmCreateDefColormap(pScreen)
+ ScreenPtr pScreen;
+{
+ return miCreateDefColormap(pScreen);
+}
+
+Bool
+ilbmSetVisualTypes(depth, visuals, bitsPerRGB)
+ int depth;
+ int visuals;
+ int bitsPerRGB;
+{
+ return miSetVisualTypes(depth, visuals, bitsPerRGB, -1);
+}
+
+/*
+ * Given a list of formats for a screen, create a list
+ * of visuals and depths for the screen which correspond to
+ * the set which can be used with this version of ilbm.
+ */
+
+Bool
+ilbmInitVisuals(visualp, depthp, nvisualp, ndepthp, rootDepthp, defaultVisp,
+ sizes, bitsPerRGB)
+ VisualPtr *visualp;
+ DepthPtr *depthp;
+ int *nvisualp, *ndepthp;
+ int *rootDepthp;
+ VisualID *defaultVisp;
+ unsigned long sizes;
+ int bitsPerRGB;
+{
+ return miInitVisuals(visualp, depthp, nvisualp, ndepthp, rootDepthp,
+ defaultVisp, sizes, bitsPerRGB, -1);
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmfillarc.c b/xc/programs/Xserver/ilbm/ilbmfillarc.c
new file mode 100644
index 000000000..f107e4692
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmfillarc.c
@@ -0,0 +1,373 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmfillarc.c,v 3.1 1998/03/20 21:08:01 hohndel Exp $ */
+/************************************************************
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+********************************************************/
+
+/* $XConsortium: ilbmfillarc.c,v 5.14 94/04/17 20:28:20 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "Xprotostr.h"
+#include "miscstruct.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "ilbm.h"
+#include "maskbits.h"
+#include "mifillarc.h"
+#include "mi.h"
+
+static void
+ilbmFillEllipseSolid(pDraw, arc, rrops)
+ DrawablePtr pDraw;
+ xArc *arc;
+ register unsigned char *rrops;
+{
+ int x, y, e;
+ int yk, xk, ym, xm, dx, dy, xorg, yorg;
+ register int slw;
+ miFillArcRec info;
+ PixelType *addrlt, *addrlb;
+ register PixelType *pdst;
+ PixelType *addrl;
+ register int n;
+ register int d;
+ int nlwidth;
+ register int xpos;
+ PixelType startmask, endmask;
+ int nlmiddle;
+ int depthDst;
+ int auxDst;
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDraw, nlwidth, auxDst, depthDst,
+ addrlt);
+ miFillArcSetup(arc, &info);
+ MIFILLARCSETUP();
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ addrlb = addrlt;
+ addrlt += auxDst * (yorg - y);
+ addrlb += auxDst * (yorg + y + dy);
+ while (y) {
+ addrlt += auxDst;
+ addrlb -= auxDst;
+ MIFILLARCSTEP(slw);
+ if (!slw)
+ continue;
+ xpos = xorg - x;
+ pdst = addrl = ilbmScanlineOffset(addrlt, (xpos >> PWSH));
+ if (((xpos & PIM) + slw) < PPW) {
+ maskpartialbits(xpos, slw, startmask);
+ for (d = 0; d < depthDst; d++, pdst += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ *pdst &= ~startmask;
+ break;
+ case RROP_WHITE:
+ *pdst |= startmask;
+ break;
+ case RROP_INVERT:
+ *pdst ^= startmask;
+ break;
+ case RROP_NOP:
+ break;
+ }
+ }
+ if (miFillArcLower(slw)) {
+ pdst = ilbmScanlineOffset(addrlb, (xpos >> PWSH));
+
+ for (d = 0; d < depthDst; d++, pdst += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ *pdst &= ~startmask;
+ break;
+ case RROP_WHITE:
+ *pdst |= startmask;
+ break;
+ case RROP_INVERT:
+ *pdst ^= startmask;
+ break;
+ case RROP_NOP:
+ break;
+ }
+ }
+ }
+ continue;
+ }
+ maskbits(xpos, slw, startmask, endmask, nlmiddle);
+ for (d = 0; d < depthDst; d++, addrl += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ n = nlmiddle;
+ pdst = addrl;
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ if (startmask)
+ *pdst++ &= ~startmask;
+ while (n--)
+ *pdst++ = 0;
+ if (endmask)
+ *pdst &= ~endmask;
+ break;
+
+ case RROP_WHITE:
+ if (startmask)
+ *pdst++ |= startmask;
+ while (n--)
+ *pdst++ = ~0;
+ if (endmask)
+ *pdst |= endmask;
+ break;
+
+ case RROP_INVERT:
+ if (startmask)
+ *pdst++ ^= startmask;
+ while (n--)
+ *pdst++ ^= ~0;
+ if (endmask)
+ *pdst ^= endmask;
+ break;
+
+ case RROP_NOP:
+ break;
+ }
+ }
+ if (!miFillArcLower(slw))
+ continue;
+ addrl = ilbmScanlineOffset(addrlb, (xpos >> PWSH));
+ for (d = 0; d < depthDst; d++, addrl += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ n = nlmiddle;
+ pdst = addrl;
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ if (startmask)
+ *pdst++ &= ~startmask;
+ while (n--)
+ *pdst++ = 0;
+ if (endmask)
+ *pdst &= ~endmask;
+ break;
+
+ case RROP_WHITE:
+ if (startmask)
+ *pdst++ |= startmask;
+ while (n--)
+ *pdst++ = ~0;
+ if (endmask)
+ *pdst |= endmask;
+ break;
+
+ case RROP_INVERT:
+ if (startmask)
+ *pdst++ ^= startmask;
+ while (n--)
+ *pdst++ ^= ~0;
+ if (endmask)
+ *pdst ^= endmask;
+ break;
+
+ case RROP_NOP:
+ break;
+ }
+ }
+ }
+}
+
+#define FILLSPAN(xl,xr,addr) \
+ if (xr >= xl) { \
+ width = xr - xl + 1; \
+ addrl = ilbmScanlineOffset(addr, (xl >> PWSH)); \
+ if (((xl & PIM) + width) < PPW) { \
+ maskpartialbits(xl, width, startmask); \
+ for (pdst = addrl, d = 0; d < depthDst; d++, pdst += nlwidth) { /* @@@ NEXT PLANE @@@ */ \
+ switch (rrops[d]) { \
+ case RROP_BLACK: \
+ *pdst &= ~startmask; \
+ break; \
+ case RROP_WHITE: \
+ *pdst |= startmask; \
+ break; \
+ case RROP_INVERT: \
+ *pdst ^= startmask; \
+ break; \
+ case RROP_NOP: \
+ break; \
+ } \
+ } \
+ } else { \
+ maskbits(xl, width, startmask, endmask, nlmiddle); \
+ for (d = 0; d < depthDst; d++, addrl += nlwidth) { /* @@@ NEXT PLANE @@@ */ \
+ n = nlmiddle; \
+ pdst = addrl; \
+ switch (rrops[d]) { \
+ case RROP_BLACK: \
+ if (startmask) \
+ *pdst++ &= ~startmask; \
+ while (n--) \
+ *pdst++ = 0; \
+ if (endmask) \
+ *pdst &= ~endmask; \
+ break; \
+ case RROP_WHITE: \
+ if (startmask) \
+ *pdst++ |= startmask; \
+ while (n--) \
+ *pdst++ = ~0; \
+ if (endmask) \
+ *pdst |= endmask; \
+ break; \
+ case RROP_INVERT: \
+ if (startmask) \
+ *pdst++ ^= startmask; \
+ while (n--) \
+ *pdst++ ^= ~0; \
+ if (endmask) \
+ *pdst ^= endmask; \
+ break; \
+ case RROP_NOP: \
+ break; \
+ } \
+ } \
+ } \
+ }
+
+#define FILLSLICESPANS(flip,addr) \
+ if (!flip) { \
+ FILLSPAN(xl, xr, addr); \
+ } else { \
+ xc = xorg - x; \
+ FILLSPAN(xc, xr, addr); \
+ xc += slw - 1; \
+ FILLSPAN(xl, xc, addr); \
+ }
+
+static void
+ilbmFillArcSliceSolidCopy(pDraw, pGC, arc, rrops)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ xArc *arc;
+ register unsigned char *rrops;
+{
+ PixelType *addrl;
+ register PixelType *pdst;
+ register int n;
+ register int d;
+ int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
+ register int x, y, e;
+ miFillArcRec info;
+ miArcSliceRec slice;
+ int xl, xr, xc;
+ PixelType *addrlt, *addrlb;
+ int nlwidth;
+ int width;
+ PixelType startmask, endmask;
+ int nlmiddle;
+ int auxDst;
+ int depthDst;
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDraw, nlwidth, auxDst, depthDst,
+ addrlt);
+ miFillArcSetup(arc, &info);
+ miFillArcSliceSetup(arc, &slice, pGC);
+ MIFILLARCSETUP();
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ addrlb = addrlt;
+ addrlt = ilbmScanlineDeltaNoBankSwitch(addrlt, yorg - y, auxDst);
+ addrlb = ilbmScanlineDeltaNoBankSwitch(addrlb, yorg + y + dy, auxDst);
+ slice.edge1.x += pDraw->x;
+ slice.edge2.x += pDraw->x;
+ while (y > 0) {
+ ilbmScanlineIncNoBankSwitch(addrlt, auxDst);
+ ilbmScanlineIncNoBankSwitch(addrlb, -auxDst);
+ MIFILLARCSTEP(slw);
+ MIARCSLICESTEP(slice.edge1);
+ MIARCSLICESTEP(slice.edge2);
+ if (miFillSliceUpper(slice)) {
+ MIARCSLICEUPPER(xl, xr, slice, slw);
+ FILLSLICESPANS(slice.flip_top, addrlt);
+ }
+ if (miFillSliceLower(slice)) {
+ MIARCSLICELOWER(xl, xr, slice, slw);
+ FILLSLICESPANS(slice.flip_bot, addrlb);
+ }
+ }
+}
+
+void
+ilbmPolyFillArcSolid(pDraw, pGC, narcs, parcs)
+ register DrawablePtr pDraw;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ ilbmPrivGC *priv;
+ register xArc *arc;
+ register int i;
+ int x2, y2;
+ BoxRec box;
+ RegionPtr cclip;
+ unsigned char *rrops;
+
+ priv = (ilbmPrivGC *) pGC->devPrivates[ilbmGCPrivateIndex].ptr;
+ rrops = priv->rrops;
+ cclip = pGC->pCompositeClip;
+ for (arc = parcs, i = narcs; --i >= 0; arc++) {
+ if (miFillArcEmpty(arc))
+ continue;
+ if (miCanFillArc(arc)) {
+ box.x1 = arc->x + pDraw->x;
+ box.y1 = arc->y + pDraw->y;
+ /*
+ * Because box.x2 and box.y2 get truncated to 16 bits, and the
+ * RECT_IN_REGION test treats the resulting number as a signed
+ * integer, the RECT_IN_REGION test alone can go the wrong way.
+ * This can result in a server crash because the rendering
+ * routines in this file deal directly with cpu addresses
+ * of pixels to be stored, and do not clip or otherwise check
+ * that all such addresses are within their respective pixmaps.
+ * So we only allow the RECT_IN_REGION test to be used for
+ * values that can be expressed correctly in a signed short.
+ */
+ x2 = box.x1 + (int)arc->width + 1;
+ box.x2 = x2;
+ y2 = box.y1 + (int)arc->height + 1;
+ box.y2 = y2;
+ if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) &&
+ (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) ) {
+ if ((arc->angle2 >= FULLCIRCLE) ||
+ (arc->angle2 <= -FULLCIRCLE))
+ ilbmFillEllipseSolid(pDraw, arc, rrops);
+ else
+ ilbmFillArcSliceSolidCopy(pDraw, pGC, arc, rrops);
+ continue;
+ }
+ }
+ miPolyFillArc(pDraw, pGC, 1, arc);
+ }
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmfillrct.c b/xc/programs/Xserver/ilbm/ilbmfillrct.c
new file mode 100644
index 000000000..642a95f40
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmfillrct.c
@@ -0,0 +1,295 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmfillrct.c,v 3.1 1998/03/20 21:08:01 hohndel Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmfillrct.c,v 5.10 94/04/17 20:28:21 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "Xprotostr.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "miscstruct.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+
+#include "ilbm.h"
+#include "maskbits.h"
+
+#define MODEQ(a, b) ((a) %= (b))
+void ilbmPaintOddSize();
+
+/*
+ filled rectangles.
+ translate the rectangles, clip them, and call the
+helper function in the GC.
+*/
+
+#define NUM_STACK_RECTS 1024
+
+void
+ilbmPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nrectFill; /* number of rectangles to fill */
+ xRectangle *prectInit; /* Pointer to first rectangle to fill */
+{
+ xRectangle *prect;
+ RegionPtr prgnClip;
+ register BoxPtr pbox;
+ register BoxPtr pboxClipped;
+ BoxPtr pboxClippedBase;
+ BoxPtr pextent;
+ BoxRec stackRects[NUM_STACK_RECTS];
+ int numRects;
+ int n;
+ int xorg, yorg;
+ ilbmPrivGC *priv;
+ PixmapPtr ppix;
+ unsigned char *rrops;
+ unsigned char *rropsOS;
+
+ priv = (ilbmPrivGC *)pGC->devPrivates[ilbmGCPrivateIndex].ptr;
+ ppix = pGC->pRotatedPixmap;
+ prgnClip = pGC->pCompositeClip;
+ rrops = priv->rrops;
+ rropsOS = priv->rropOS;
+
+ prect = prectInit;
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+ if (xorg || yorg) {
+ prect = prectInit;
+ n = nrectFill;
+ Duff(n, prect->x += xorg; prect->y += yorg; prect++);
+ }
+
+ prect = prectInit;
+
+ numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
+ if (numRects > NUM_STACK_RECTS) {
+ pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
+ if (!pboxClippedBase)
+ return;
+ }
+ else
+ pboxClippedBase = stackRects;
+
+ pboxClipped = pboxClippedBase;
+
+ if (REGION_NUM_RECTS(prgnClip) == 1) {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_RECTS(prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--) {
+ if ((pboxClipped->x1 = prect->x) < x1)
+ pboxClipped->x1 = x1;
+
+ if ((pboxClipped->y1 = prect->y) < y1)
+ pboxClipped->y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ pboxClipped->x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ pboxClipped->y2 = by2;
+
+ prect++;
+ if ((pboxClipped->x1 < pboxClipped->x2) &&
+ (pboxClipped->y1 < pboxClipped->y2)) {
+ pboxClipped++;
+ }
+ }
+ } else {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--) {
+ BoxRec box;
+
+ if ((box.x1 = prect->x) < x1)
+ box.x1 = x1;
+
+ if ((box.y1 = prect->y) < y1)
+ box.y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ box.x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ box.y2 = by2;
+
+ prect++;
+
+ if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
+ continue;
+
+ n = REGION_NUM_RECTS (prgnClip);
+ pbox = REGION_RECTS(prgnClip);
+
+ /* clip the rectangle to each box in the clip region
+ this is logically equivalent to calling Intersect()
+ */
+ while (n--) {
+ pboxClipped->x1 = max(box.x1, pbox->x1);
+ pboxClipped->y1 = max(box.y1, pbox->y1);
+ pboxClipped->x2 = min(box.x2, pbox->x2);
+ pboxClipped->y2 = min(box.y2, pbox->y2);
+ pbox++;
+
+ /* see if clipping left anything */
+ if (pboxClipped->x1 < pboxClipped->x2 &&
+ pboxClipped->y1 < pboxClipped->y2)
+ pboxClipped++;
+ }
+ }
+ }
+ if (pboxClipped != pboxClippedBase) {
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ ilbmSolidFillArea(pDrawable, pboxClipped-pboxClippedBase,
+ pboxClippedBase, rrops);
+ break;
+ case FillTiled:
+ switch (pGC->alu) {
+ case GXcopy:
+ if (pGC->pRotatedPixmap)
+ ilbmTileAreaPPWCopy(pDrawable, pboxClipped-pboxClippedBase,
+ pboxClippedBase, GXcopy,
+ pGC->pRotatedPixmap, pGC->planemask);
+ else
+ ilbmTileAreaCopy(pDrawable, pboxClipped-pboxClippedBase,
+ pboxClippedBase, GXcopy, pGC->tile.pixmap,
+ pGC->patOrg.x, pGC->patOrg.y,
+ pGC->planemask);
+ break;
+
+ default:
+ if (pGC->pRotatedPixmap)
+ ilbmTileAreaPPWGeneral(pDrawable, pboxClipped-pboxClippedBase,
+ pboxClippedBase, pGC->alu,
+ pGC->pRotatedPixmap,
+ pGC->planemask);
+ else
+ ilbmTileAreaGeneral(pDrawable, pboxClipped-pboxClippedBase,
+ pboxClippedBase, pGC->alu,
+ pGC->tile.pixmap, pGC->patOrg.x,
+ pGC->patOrg.y, pGC->planemask);
+ break;
+ } /* switch (alu) */
+ break;
+
+ case FillStippled:
+ if (pGC->pRotatedPixmap)
+ ilbmStippleAreaPPW(pDrawable, pboxClipped-pboxClippedBase,
+ pboxClippedBase, pGC->pRotatedPixmap, rrops);
+ else
+ ilbmStippleArea(pDrawable, pboxClipped-pboxClippedBase,
+ pboxClippedBase, pGC->stipple, pGC->patOrg.x,
+ pGC->patOrg.y, rrops);
+ break;
+
+ case FillOpaqueStippled:
+ switch (pGC->alu) {
+ case GXcopy:
+ if (pGC->pRotatedPixmap)
+ ilbmOpaqueStippleAreaPPWCopy(pDrawable,
+ pboxClipped-pboxClippedBase,
+ pboxClippedBase, GXcopy,
+ pGC->pRotatedPixmap, rropsOS,
+ pGC->planemask);
+ else
+ ilbmOpaqueStippleAreaCopy(pDrawable,
+ pboxClipped-pboxClippedBase,
+ pboxClippedBase, GXcopy,
+ pGC->stipple, pGC->patOrg.x,
+ pGC->patOrg.y, rropsOS,
+ pGC->planemask);
+ break;
+
+ default:
+ if (pGC->pRotatedPixmap)
+ ilbmOpaqueStippleAreaPPWGeneral(pDrawable,
+ pboxClipped-pboxClippedBase,
+ pboxClippedBase, pGC->alu,
+ pGC->pRotatedPixmap,
+ rropsOS, pGC->planemask);
+ else
+ ilbmOpaqueStippleAreaGeneral(pDrawable,
+ pboxClipped-pboxClippedBase,
+ pboxClippedBase, pGC->alu,
+ pGC->stipple, pGC->patOrg.x,
+ pGC->patOrg.y, rropsOS,
+ pGC->planemask);
+ break;
+ } /* switch (alu) */
+ break;
+ }
+ }
+ if (pboxClippedBase != stackRects)
+ DEALLOCATE_LOCAL(pboxClippedBase);
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmfillsp.c b/xc/programs/Xserver/ilbm/ilbmfillsp.c
new file mode 100644
index 000000000..5564e5142
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmfillsp.c
@@ -0,0 +1,1145 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmfillsp.c,v 3.1 1998/03/20 21:08:01 hohndel Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmfillsp.c,v 5.13 94/04/17 20:28:21 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "gcstruct.h"
+#include "window.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "ilbm.h"
+#include "maskbits.h"
+
+#include "mergerop.h"
+
+#include "servermd.h"
+#include "mi.h"
+#include "mispans.h"
+
+/* scanline filling for monochrome frame buffer
+ written by drewry, oct 1986
+
+ these routines all clip. they assume that anything that has called
+them has already translated the points (i.e. pGC->miTranslate is
+non-zero, which is howit gets set in ilbmCreateGC().)
+
+ the number of new scnalines created by clipping ==
+MaxRectsPerBand * nSpans.
+
+*/
+
+
+void
+ilbmSolidFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ PixelType *pBase;
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *addrl;/* pointer to current longword in bitmap */
+ register int nlmiddle;
+ register PixelType startmask;
+ register PixelType endmask;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ int depthDst;
+ int auxDst;
+ int d;
+ unsigned char *rrops;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if (!pptFree || !pwidthFree) {
+ if (pptFree)
+ DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree)
+ DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
+ pBase);
+ rrops = ((ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr))->rrops;
+ while (n--) {
+ addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
+
+ for (d = 0; d < depthDst; d++, addrlBase += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ if (*pwidth) {
+ addrl = addrlBase;
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ /* all bits inside same longword */
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl &= ~startmask;
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ &= ~startmask;
+ Duff (nlmiddle, *addrl++ = 0x0);
+ if (endmask)
+ *addrl &= ~endmask;
+ }
+ break;
+
+ case RROP_WHITE:
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ /* all bits inside same longword */
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl |= startmask;
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ |= startmask;
+ Duff (nlmiddle, *addrl++ = ~0);
+ if (endmask)
+ *addrl |= endmask;
+ }
+ break;
+ case RROP_INVERT:
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ /* all bits inside same longword */
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl ^= startmask;
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ ^= startmask;
+ Duff (nlmiddle, *addrl++ ^= ~0);
+ if (endmask)
+ *addrl ^= endmask;
+ }
+ break;
+ case RROP_NOP:
+ break;
+ }
+ }
+ }
+ pwidth++;
+ ppt++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+void
+ilbmStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ PixelType *pBase;
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *addrl;/* pointer to current longword in bitmap */
+ register PixelType src;
+ register int nlmiddle;
+ register PixelType startmask;
+ register PixelType endmask;
+ PixmapPtr pStipple;
+ PixelType *psrc;
+ int tileHeight;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ int d;
+ int depthDst;
+ int auxDst;
+ unsigned char *rrops;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if (!pptFree || !pwidthFree) {
+ if (pptFree)
+ DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree)
+ DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
+ pBase);
+
+ pStipple = pGC->pRotatedPixmap;
+ tileHeight = pStipple->drawable.height;
+ psrc = (PixelType *)(pStipple->devPrivate.ptr);
+
+ rrops = ((ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr))->rrops;
+
+ while (n--) {
+ src = psrc[ppt->y % tileHeight];
+ addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
+ for (d = 0; d < depthDst; d++, addrlBase += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ addrl = addrlBase;
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ /* all bits inside same longword */
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl &= ~(src & startmask);
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ &= ~(src & startmask);
+ Duff (nlmiddle, *addrl++ &= ~src);
+ if (endmask)
+ *addrl &= ~(src & endmask);
+ }
+ break;
+ case RROP_WHITE:
+ /* all bits inside same longword */
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl |= (src & startmask);
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ |= (src & startmask);
+ Duff (nlmiddle, *addrl++ |= src);
+ if (endmask)
+ *addrl |= (src & endmask);
+ }
+ break;
+ case RROP_INVERT:
+ /* all bits inside same longword */
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl ^= (src & startmask);
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ ^= (src & startmask);
+ Duff (nlmiddle, *addrl++ ^= src);
+ if (endmask)
+ *addrl ^= (src & endmask);
+ }
+ break;
+
+ case RROP_NOP:
+ break;
+ }
+ }
+ pwidth++;
+ ppt++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+void
+ilbmTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ PixelType *pBase;
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *addrl; /* pointer to current longword in bitmap */
+ register PixelType src;
+ register int nlmiddle;
+ register PixelType startmask;
+ register PixelType endmask;
+ PixmapPtr pTile;
+ PixelType *psrc;
+ int tileHeight;
+ int rop;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ int auxDst;
+ int depthDst;
+ int d;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if (!pptFree || !pwidthFree) {
+ if (pptFree)
+ DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree)
+ DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
+ pBase);
+
+ pTile = pGC->pRotatedPixmap;
+ tileHeight = pTile->drawable.height;
+ psrc = (PixelType *)(pTile->devPrivate.ptr);
+ rop = pGC->alu;
+
+ switch (rop) {
+ case GXcopy:
+#define DoMaskCopyRop(src,dst,mask) ((dst) & ~(mask) | (src) & (mask))
+ while (n--) {
+ if (*pwidth) {
+ addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
+
+ for (d = 0; d < depthDst; d++, addrlBase += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ if (!(pGC->planemask & (1 << d)))
+ continue;
+
+ addrl = addrlBase;
+ src = psrc[ppt->y % tileHeight + tileHeight * d];
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl = DoMaskCopyRop (src, *addrl, startmask);
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask) {
+ *addrl = DoMaskCopyRop (src, *addrl, startmask);
+ addrl++;
+ }
+ while (nlmiddle--) {
+ *addrl = src;
+ addrl++;
+ }
+ if (endmask)
+ *addrl = DoMaskCopyRop (src, *addrl, endmask);
+ }
+ }
+ }
+ pwidth++;
+ ppt++;
+ }
+ break;
+
+ default:
+ {
+ register DeclareMergeRop ();
+
+ InitializeMergeRop(rop,~0);
+ while (n--) {
+ if (*pwidth) {
+ addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
+ for (d = 0; d < depthDst; d++, addrlBase += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ if (!(pGC->planemask & (1 << d)))
+ continue;
+
+ addrl = addrlBase;
+
+ src = psrc[ppt->y % tileHeight + tileHeight * d];
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl = DoMaskMergeRop (src, *addrl, startmask);
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask) {
+ *addrl = DoMaskMergeRop (src, *addrl, startmask);
+ addrl++;
+ }
+ while (nlmiddle--) {
+ *addrl = DoMergeRop (src, *addrl);
+ addrl++;
+ }
+ if (endmask)
+ *addrl = DoMaskMergeRop (src, *addrl, endmask);
+ }
+ }
+ }
+ pwidth++;
+ ppt++;
+ }
+ break;
+ }
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+void
+ilbmOpaqueStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ PixelType *pBase;
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *addrl; /* pointer to current longword in bitmap */
+ register PixelType src;
+ register int nlmiddle;
+ register PixelType startmask;
+ register PixelType endmask;
+ PixmapPtr pTile;
+ PixelType *psrc;
+ int tileHeight;
+ int rop;
+ unsigned char *rropsOS;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ int auxDst;
+ int depthDst;
+ int d;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if (!pptFree || !pwidthFree) {
+ if (pptFree)
+ DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree)
+ DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
+ pBase);
+
+ pTile = pGC->pRotatedPixmap;
+ tileHeight = pTile->drawable.height;
+ psrc = (PixelType *)(pTile->devPrivate.ptr);
+ rop = pGC->alu;
+ rropsOS = ((ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr))->rropOS;
+
+ switch (rop) {
+ case GXcopy:
+#define DoMaskCopyRop(src,dst,mask) ((dst) & ~(mask) | (src) & (mask))
+ while (n--) {
+ addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
+ if (*pwidth) {
+ for (d = 0; d < depthDst; d++, addrlBase += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ src = 0;
+ break;
+ case RROP_WHITE:
+ src = ~0;
+ break;
+ case RROP_INVERT:
+ src = ~psrc[ppt->y % tileHeight];
+ break;
+ case RROP_COPY:
+ src = psrc[ppt->y % tileHeight];
+ break;
+ case RROP_NOP:
+ continue;
+ }
+
+ addrl = addrlBase;
+
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl = DoMaskCopyRop (src, *addrl, startmask);
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask) {
+ *addrl = DoMaskCopyRop (src, *addrl, startmask);
+ addrl++;
+ }
+ while (nlmiddle--) {
+ *addrl = src;
+ addrl++;
+ }
+ if (endmask)
+ *addrl = DoMaskCopyRop (src, *addrl, endmask);
+ }
+ } /* for (d = ...) */
+ }
+
+ pwidth++;
+ ppt++;
+ }
+ break;
+
+ default:
+ {
+ register DeclareMergeRop ();
+
+ InitializeMergeRop(rop,~0);
+ while (n--) {
+ addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
+ if (*pwidth) {
+ for (d = 0; d < depthDst; d++, addrlBase += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ src = 0;
+ break;
+ case RROP_WHITE:
+ src = ~0;
+ break;
+ case RROP_INVERT:
+ src = ~psrc[ppt->y % tileHeight];
+ break;
+ case RROP_COPY:
+ src = psrc[ppt->y % tileHeight];
+ break;
+ case RROP_NOP:
+ continue;
+ }
+
+ addrl = addrlBase;
+
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl = DoMaskMergeRop (src, *addrl, startmask);
+ } else {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask) {
+ *addrl = DoMaskMergeRop (src, *addrl, startmask);
+ addrl++;
+ }
+ while (nlmiddle--) {
+ *addrl = DoMergeRop (src, *addrl);
+ addrl++;
+ }
+ if (endmask)
+ *addrl = DoMaskMergeRop (src, *addrl, endmask);
+ }
+ } /* for (d = ...) */
+ }
+ pwidth++;
+ ppt++;
+ } /* while (n) */
+ break;
+ }
+ } /* switch (rop) */
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+/* Fill spans with tiles that aren't PPW bits wide */
+void
+ilbmUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ int iline; /* first line of tile to use */
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ PixelType *pBase;
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *pdst;/* pointer to current word in bitmap */
+ register PixelType *psrc;/* pointer to current word in tile */
+ register int nlMiddle;
+ register int rop, nstart;
+ PixelType startmask;
+ PixmapPtr pTile; /* pointer to tile we want to fill with */
+ int w, width, x, xSrc, ySrc, srcStartOver, nend;
+ int tlwidth, rem, tileWidth, tileHeight, endinc;
+ PixelType endmask, *psrcT;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ int auxDst;
+ int sizeTile;
+ int depthDst;
+ register int d;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if (!pptFree || !pwidthFree) {
+ if (pptFree)
+ DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree)
+ DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ pTile = pGC->tile.pixmap;
+ tlwidth = pTile->devKind/PGSZB;
+ rop = pGC->alu;
+
+ xSrc = pDrawable->x;
+ ySrc = pDrawable->y;
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
+ pBase);
+
+ tileWidth = pTile->drawable.width;
+ tileHeight = pTile->drawable.height;
+ sizeTile = tlwidth * tileHeight;
+
+ /* this replaces rotating the tile. Instead we just adjust the offset
+ * at which we start grabbing bits from the tile.
+ * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
+ * so that iline and rem always stay within the tile bounds.
+ */
+ xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
+ ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
+
+ while (n--) {
+ iline = (ppt->y - ySrc) % tileHeight;
+ psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
+ addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
+
+ for (d = 0; d < depthDst; d++, psrcT += sizeTile, addrlBase += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ if (!(pGC->planemask & (1 << d)))
+ continue;
+
+ if (*pwidth) {
+ x = ppt->x;
+ pdst = addrlBase;
+ width = *pwidth;
+ while (width > 0) {
+ psrc = psrcT;
+ w = min(tileWidth, width);
+ if ((rem = (x - xSrc) % tileWidth) != 0) {
+ /* if we're in the middle of the tile, get
+ as many bits as will finish the span, or
+ as many as will get to the left edge of the tile,
+ or a longword worth, starting at the appropriate
+ offset in the tile.
+ */
+ w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
+ endinc = rem / BITMAP_SCANLINE_PAD;
+ getandputrop((psrc+endinc), (rem&PIM), (x & PIM), w, pdst, rop);
+ if ((x & PIM) + w >= PPW)
+ pdst++;
+ } else if (((x & PIM) + w) < PPW) {
+ /* doing < PPW bits is easy, and worth special-casing */
+ putbitsrop(*psrc, x & PIM, w, pdst, rop);
+ } else {
+ /* start at the left edge of the tile,
+ and put down as much as we can
+ */
+ maskbits(x, w, startmask, endmask, nlMiddle);
+
+ if (startmask)
+ nstart = PPW - (x & PIM);
+ else
+ nstart = 0;
+ if (endmask)
+ nend = (x + w) & PIM;
+ else
+ nend = 0;
+
+ srcStartOver = nstart > PLST;
+
+ if (startmask) {
+ putbitsrop(*psrc, (x & PIM), nstart, pdst, rop);
+ pdst++;
+ if (srcStartOver)
+ psrc++;
+ }
+
+ while (nlMiddle--) {
+ getandputrop0(psrc, nstart, PPW, pdst, rop);
+ pdst++;
+ psrc++;
+ }
+ if (endmask) {
+ getandputrop0(psrc, nstart, nend, pdst, rop);
+ }
+ }
+ x += w;
+ width -= w;
+ }
+ }
+ }
+ ppt++;
+ pwidth++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+/* Fill spans with stipples that aren't PPW bits wide */
+void
+ilbmUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ int iline; /* first line of tile to use */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ PixelType *pBase;
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *pdst; /* pointer to current word in bitmap */
+ register PixelType *psrc; /* pointer to current word in tile */
+ register int nlMiddle;
+ register int rop, nstart;
+ PixelType startmask;
+ PixmapPtr pTile; /* pointer to tile we want to fill with */
+ int w, width, x, xSrc, ySrc, srcStartOver, nend;
+ PixelType endmask, *psrcT;
+ int tlwidth, rem, tileWidth, endinc;
+ int tileHeight;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ unsigned char *rrops;
+ register int d;
+ int auxDst;
+ int depthDst;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if (!pptFree || !pwidthFree) {
+ if (pptFree)
+ DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree)
+ DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ pTile = pGC->stipple;
+ tlwidth = pTile->devKind/PGSZB;
+ xSrc = pDrawable->x;
+ ySrc = pDrawable->y;
+ ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
+ pBase);
+
+ tileWidth = pTile->drawable.width;
+ tileHeight = pTile->drawable.height;
+ rrops = ((ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr))->rrops;
+
+ /* this replaces rotating the stipple. Instead, we just adjust the offset
+ * at which we start grabbing bits from the stipple.
+ * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
+ * so that iline and rem always stay within the tile bounds.
+ */
+ xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
+ ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
+ while (n--) {
+ iline = (ppt->y - ySrc) % tileHeight;
+ psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
+ addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
+
+ for (d = 0; d < depthDst; d++, addrlBase += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ rop = rrops[d];
+ if (rop == RROP_NOP)
+ continue;
+
+ pdst = addrlBase;
+ x = ppt->x;
+
+ if (*pwidth) {
+ width = *pwidth;
+ while (width > 0) {
+ psrc = psrcT;
+ w = min(tileWidth, width);
+ if ((rem = (x - xSrc) % tileWidth) != 0) {
+ /* if we're in the middle of the tile, get
+ as many bits as will finish the span, or
+ as many as will get to the left edge of the tile,
+ or a longword worth, starting at the appropriate
+ offset in the tile.
+ */
+ w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
+ endinc = rem / BITMAP_SCANLINE_PAD;
+ getandputrrop((psrc + endinc), (rem & PIM), (x & PIM),
+ w, pdst, rop)
+ if ((x & PIM) + w >= PPW)
+ pdst++;
+ } else if (((x & PIM) + w) < PPW) {
+ /* doing < PPW bits is easy, and worth special-casing */
+ putbitsrrop(*psrc, x & PIM, w, pdst, rop);
+ } else {
+ /* start at the left edge of the tile,
+ and put down as much as we can
+ */
+ maskbits(x, w, startmask, endmask, nlMiddle);
+
+ if (startmask)
+ nstart = PPW - (x & PIM);
+ else
+ nstart = 0;
+ if (endmask)
+ nend = (x + w) & PIM;
+ else
+ nend = 0;
+
+ srcStartOver = nstart > PLST;
+
+ if (startmask) {
+ putbitsrrop(*psrc, (x & PIM), nstart, pdst, rop);
+ pdst++;
+ if (srcStartOver)
+ psrc++;
+ }
+
+ while (nlMiddle--) {
+ getandputrrop0(psrc, nstart, PPW, pdst, rop);
+ pdst++;
+ psrc++;
+ }
+ if (endmask) {
+ getandputrrop0(psrc, nstart, nend, pdst, rop);
+ }
+ }
+ x += w;
+ width -= w;
+ }
+ }
+ }
+ ppt++;
+ pwidth++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+/* Fill spans with OpaqueStipples that aren't PPW bits wide */
+void
+ilbmUnnaturalOpaqueStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ int iline; /* first line of tile to use */
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ PixelType *pBase;
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *pdst;/* pointer to current word in bitmap */
+ register PixelType *psrc;/* pointer to current word in tile */
+ register int nlMiddle;
+ register int d;
+ register PixelType tmpsrc;
+ register PixelType tmpdst;
+ register int alu, nstart;
+ register unsigned char *rropsOS;
+ PixelType startmask;
+ PixmapPtr pTile; /* pointer to tile we want to fill with */
+ int w, width, x, xSrc, ySrc, srcStartOver, nend;
+ int tlwidth, rem, tileWidth, tileHeight, endinc;
+ PixelType endmask, *psrcT;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ int auxDst;
+ int sizeTile;
+ int depthDst;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if (!pptFree || !pwidthFree) {
+ if (pptFree)
+ DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree)
+ DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ pTile = pGC->stipple;
+ tlwidth = pTile->devKind/PGSZB;
+ alu = pGC->alu;
+
+ xSrc = pDrawable->x;
+ ySrc = pDrawable->y;
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
+ pBase);
+
+ tileWidth = pTile->drawable.width;
+ tileHeight = pTile->drawable.height;
+ rropsOS = ilbmGetGCPrivate(pGC)->rropOS;
+
+ /* this replaces rotating the tile. Instead we just adjust the offset
+ * at which we start grabbing bits from the tile.
+ * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
+ * so that iline and rem always stay within the tile bounds.
+ */
+ xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
+ ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
+
+ while (n--) {
+ iline = (ppt->y - ySrc) % tileHeight;
+ psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
+ addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
+
+ for (d = 0; d < depthDst; d++, addrlBase += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ if (!(pGC->planemask & (1 << d)))
+ continue;
+
+ if (*pwidth) {
+ x = ppt->x;
+ pdst = addrlBase;
+ width = *pwidth;
+ while (width > 0) {
+ psrc = psrcT;
+ w = min(tileWidth, width);
+ if ((rem = (x - xSrc) % tileWidth) != 0) {
+ /* if we're in the middle of the tile, get
+ as many bits as will finish the span, or
+ as many as will get to the left edge of the tile,
+ or a longword worth, starting at the appropriate
+ offset in the tile.
+ */
+ w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
+ endinc = rem / BITMAP_SCANLINE_PAD;
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ tmpsrc = 0;
+ break;
+ case RROP_WHITE:
+ tmpsrc = ~0;
+ break;
+
+ case RROP_COPY:
+ getbits ((psrc+endinc), (rem&PIM), w, tmpsrc);
+ break;
+
+ case RROP_INVERT:
+ getbits ((psrc+endinc), (rem&PIM), w, tmpsrc);
+ tmpsrc = ~tmpsrc;
+ break;
+ }
+
+ if (alu != GXcopy) {
+ getbits (pdst, (x & PIM), w, tmpdst);
+ DoRop (tmpsrc, alu, tmpsrc, tmpdst);
+ }
+
+ putbits (tmpsrc, (x & PIM), w, pdst);
+ if ((x & PIM) + w >= PPW)
+ pdst++;
+ } else if (((x & PIM) + w) < PPW) {
+ /* doing < PPW bits is easy, and worth special-casing */
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ tmpsrc = 0;
+ break;
+ case RROP_WHITE:
+ tmpsrc = ~0;
+ break;
+ case RROP_COPY:
+ tmpsrc = *psrc;
+ break;
+ case RROP_INVERT:
+ tmpsrc = ~*psrc;
+ break;
+ }
+ if (alu != GXcopy) {
+ getbits (pdst, (x & PIM), w, tmpdst);
+ DoRop (tmpsrc, alu, tmpsrc, tmpdst);
+ }
+ putbits (tmpsrc, (x & PIM), w, pdst);
+ } else {
+ /* start at the left edge of the tile,
+ and put down as much as we can
+ */
+ maskbits(x, w, startmask, endmask, nlMiddle);
+
+ if (startmask)
+ nstart = PPW - (x & PIM);
+ else
+ nstart = 0;
+ if (endmask)
+ nend = (x + w) & PIM;
+ else
+ nend = 0;
+
+ srcStartOver = nstart > PLST;
+
+ if (startmask) {
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ tmpsrc = 0;
+ break;
+ case RROP_WHITE:
+ tmpsrc = ~0;
+ break;
+ case RROP_COPY:
+ tmpsrc = *psrc;
+ break;
+ case RROP_INVERT:
+ tmpsrc = ~*psrc;
+ break;
+ }
+ if (alu != GXcopy) {
+ getbits (pdst, (x & PIM), nstart, tmpdst);
+ DoRop (tmpsrc, alu, tmpsrc, tmpdst);
+ }
+ putbits (tmpsrc, (x & PIM), nstart, pdst);
+ pdst++;
+ if (srcStartOver)
+ psrc++;
+ }
+
+ while (nlMiddle--) {
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ tmpsrc = 0;
+ break;
+ case RROP_WHITE:
+ tmpsrc = ~0;
+ break;
+ case RROP_COPY:
+ getbits (psrc, nstart, PPW, tmpsrc);
+ break;
+ case RROP_INVERT:
+ getbits (psrc, nstart, PPW, tmpsrc);
+ tmpsrc = ~tmpsrc;
+ break;
+ }
+ if (alu != GXcopy) {
+ tmpdst = *pdst;
+ DoRop (tmpsrc, alu, tmpsrc, tmpdst);
+ }
+ *pdst++ = tmpsrc;
+ /*putbits (tmpsrc, 0, PPW, pdst);
+ pdst++;*/
+ psrc++;
+ }
+ if (endmask) {
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ tmpsrc = 0;
+ break;
+ case RROP_WHITE:
+ tmpsrc = ~0;
+ break;
+
+ case RROP_COPY:
+ getbits (psrc, nstart, nend, tmpsrc);
+ break;
+
+ case RROP_INVERT:
+ getbits (psrc, nstart, nend, tmpsrc);
+ tmpsrc = ~tmpsrc;
+ break;
+ }
+ if (alu != GXcopy) {
+ tmpdst = *pdst;
+ DoRop (tmpsrc, alu, tmpsrc, tmpdst);
+ }
+ putbits (tmpsrc, 0, nend, pdst);
+ }
+ }
+ x += w;
+ width -= w;
+ }
+ }
+ }
+ ppt++;
+ pwidth++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmfont.c b/xc/programs/Xserver/ilbm/ilbmfont.c
new file mode 100644
index 000000000..50cf56773
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmfont.c
@@ -0,0 +1,78 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmfont.c,v 3.0 1996/08/18 01:53:51 dawes Exp $ */
+/*
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XConsortium: ilbmfont.c,v 1.18 94/04/17 20:28:22 keith Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "ilbm.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+
+/*ARGSUSED*/
+Bool
+ilbmRealizeFont( pscr, pFont)
+ ScreenPtr pscr;
+ FontPtr pFont;
+{
+ return (TRUE);
+}
+
+/*ARGSUSED*/
+Bool
+ilbmUnrealizeFont( pscr, pFont)
+ ScreenPtr pscr;
+ FontPtr pFont;
+{
+ return (TRUE);
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmgc.c b/xc/programs/Xserver/ilbm/ilbmgc.c
new file mode 100644
index 000000000..8253d9cd4
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmgc.c
@@ -0,0 +1,711 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmgc.c,v 3.1 1998/03/20 21:08:02 hohndel Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmgc.c,v 5.35 94/04/17 20:28:23 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "ilbm.h"
+#include "dixfontstr.h"
+#include "fontstruct.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "region.h"
+
+#include "mistruct.h"
+#include "migc.h"
+
+#include "maskbits.h"
+
+static GCFuncs ilbmFuncs = {
+ ilbmValidateGC,
+ miChangeGC,
+ miCopyGC,
+ ilbmDestroyGC,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip
+};
+
+static GCOps ilbmGCOps = {
+ ilbmSolidFS,
+ ilbmSetSpans,
+ ilbmPutImage,
+ ilbmCopyArea,
+ miCopyPlane,
+ ilbmPolyPoint,
+ ilbmLineSS,
+ ilbmSegmentSS,
+ miPolyRectangle,
+ ilbmZeroPolyArcSS,
+ ilbmFillPolygonSolid,
+ ilbmPolyFillRect,
+ ilbmPolyFillArcSolid,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ ilbmTEGlyphBlt,
+ ilbmPolyGlyphBlt,
+ ilbmPushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+
+Bool
+ilbmCreateGC(pGC)
+ register GCPtr pGC;
+{
+ ilbmPrivGC *pPriv;
+
+ pGC->clientClip = NULL;
+ pGC->clientClipType = CT_NONE;
+
+ /* some of the output primitives aren't really necessary, since
+ they will be filled in ValidateGC because of dix/CreateGC()
+ setting all the change bits. Others are necessary because although
+ they depend on being a monochrome frame buffer, they don't change
+ */
+
+ pGC->ops = &ilbmGCOps;
+ pGC->funcs = &ilbmFuncs;
+
+ /* ilbm wants to translate before scan convesion */
+ pGC->miTranslate = 1;
+
+ pPriv = (ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr);
+ ilbmReduceRop(pGC->alu, pGC->fgPixel, pGC->planemask, pGC->depth,
+ pPriv->rrops);
+ ilbmReduceOpaqueStipple(pGC->fgPixel, pGC->bgPixel, pGC->planemask,
+ pGC->depth, pPriv->rropOS);
+
+ pGC->fExpose = TRUE;
+ pGC->pRotatedPixmap = NullPixmap;
+ pGC->freeCompClip = FALSE;
+ return TRUE;
+}
+
+/* Clipping conventions
+ if the drawable is a window
+ CT_REGION ==> pCompositeClip really is the composite
+ CT_other ==> pCompositeClip is the window clip region
+ if the drawable is a pixmap
+ CT_REGION ==> pCompositeClip is the translated client region
+ clipped to the pixmap boundary
+ CT_other ==> pCompositeClip is the pixmap bounding box
+*/
+
+/*ARGSUSED*/
+void
+ilbmValidateGC(pGC, changes, pDrawable)
+ register GCPtr pGC;
+ unsigned long changes;
+ DrawablePtr pDrawable;
+{
+ register ilbmPrivGCPtr devPriv;
+ int mask; /* stateChanges */
+ int index; /* used for stepping through bitfields */
+ int xrot, yrot; /* rotations for tile and stipple pattern */
+ int rrop; /* reduced rasterop */
+ /* flags for changing the proc vector
+ and updating things in devPriv
+ */
+ int new_rotate, new_rrop, new_line, new_text, new_fill;
+ DDXPointRec oldOrg; /* origin of thing GC was last used with */
+
+ oldOrg = pGC->lastWinOrg;
+
+ pGC->lastWinOrg.x = pDrawable->x;
+ pGC->lastWinOrg.y = pDrawable->y;
+
+ /* we need to re-rotate the tile if the previous window/pixmap
+ origin (oldOrg) differs from the new window/pixmap origin
+ (pGC->lastWinOrg)
+ */
+ new_rotate = (oldOrg.x != pGC->lastWinOrg.x) ||
+ (oldOrg.y != pGC->lastWinOrg.y);
+
+
+ devPriv = ((ilbmPrivGCPtr)(pGC->devPrivates[ilbmGCPrivateIndex].ptr));
+
+
+ /*
+ if the client clip is different or moved OR
+ the subwindowMode has changed OR
+ the window's clip has changed since the last validation
+ we need to recompute the composite clip
+ */
+ if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
+ (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS)))
+ ilbmComputeCompositeClip(pGC, pDrawable);
+
+ new_rrop = FALSE;
+ new_line = FALSE;
+ new_text = FALSE;
+ new_fill = FALSE;
+
+ mask = changes;
+ while (mask) {
+ index = lowbit(mask);
+ mask &= ~index;
+
+ /* this switch acculmulates a list of which procedures
+ might have to change due to changes in the GC. in
+ some cases (e.g. changing one 16 bit tile for another)
+ we might not really need a change, but the code is
+ being paranoid.
+ this sort of batching wins if, for example, the alu
+ and the font have been changed, or any other pair
+ of items that both change the same thing.
+ */
+ switch (index) {
+ case GCPlaneMask:
+ case GCFunction:
+ case GCForeground:
+ new_rrop = TRUE;
+ break;
+ case GCBackground:
+ new_rrop = TRUE; /* for opaque stipples */
+ break;
+ case GCLineStyle:
+ case GCLineWidth:
+ case GCJoinStyle:
+ new_line = TRUE;
+ break;
+ case GCCapStyle:
+ break;
+ case GCFillStyle:
+ new_fill = TRUE;
+ break;
+ case GCFillRule:
+ break;
+ case GCTile:
+ if (pGC->tileIsPixel)
+ break;
+ new_rotate = TRUE;
+ new_fill = TRUE;
+ break;
+
+ case GCStipple:
+ if (pGC->stipple == (PixmapPtr)NULL)
+ break;
+ new_rotate = TRUE;
+ new_fill = TRUE;
+ break;
+
+ case GCTileStipXOrigin:
+ new_rotate = TRUE;
+ break;
+
+ case GCTileStipYOrigin:
+ new_rotate = TRUE;
+ break;
+
+ case GCFont:
+ new_text = TRUE;
+ break;
+ case GCSubwindowMode:
+ break;
+ case GCGraphicsExposures:
+ break;
+ case GCClipXOrigin:
+ break;
+ case GCClipYOrigin:
+ break;
+ case GCClipMask:
+ break;
+ case GCDashOffset:
+ break;
+ case GCDashList:
+ break;
+ case GCArcMode:
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* deal with the changes we've collected .
+ new_rrop must be done first because subsequent things
+ depend on it.
+ */
+
+ if (new_rotate || new_fill) {
+ Bool new_pix = FALSE;
+
+ /* figure out how much to rotate */
+ xrot = pGC->patOrg.x;
+ yrot = pGC->patOrg.y;
+ xrot += pDrawable->x;
+ yrot += pDrawable->y;
+
+ switch (pGC->fillStyle) {
+ case FillTiled:
+ /* copy current tile and stipple */
+ if (!pGC->tileIsPixel &&
+ (pGC->tile.pixmap->drawable.width <= PPW) &&
+ !(pGC->tile.pixmap->drawable.width &
+ (pGC->tile.pixmap->drawable.width - 1))) {
+ ilbmCopyRotatePixmap(pGC->tile.pixmap, &pGC->pRotatedPixmap,
+ xrot, yrot);
+ new_pix = TRUE;
+ }
+ break;
+ case FillStippled:
+ case FillOpaqueStippled:
+ if (pGC->stipple && (pGC->stipple->drawable.width <= PPW) &&
+ !(pGC->stipple->drawable.width &
+ (pGC->stipple->drawable.width - 1))) {
+ ilbmCopyRotatePixmap(pGC->stipple, &pGC->pRotatedPixmap,
+ xrot, yrot);
+ new_pix = TRUE;
+ }
+ }
+ /* destroy any previously rotated tile or stipple */
+ if (!new_pix && pGC->pRotatedPixmap) {
+ (*pDrawable->pScreen->DestroyPixmap)(pGC->pRotatedPixmap);
+ pGC->pRotatedPixmap = (PixmapPtr)NULL;
+ }
+ }
+
+ /*
+ * duck out here when the GC is unchanged
+ */
+
+ if (!changes)
+ return;
+
+ if (new_rrop || new_fill) {
+ ilbmReduceRop(pGC->alu, pGC->fgPixel, pGC->planemask, pDrawable->depth,
+ devPriv->rrops);
+ ilbmReduceOpaqueStipple(pGC->fgPixel, pGC->bgPixel, pGC->planemask,
+ pGC->depth, devPriv->rropOS);
+ new_fill = TRUE;
+ }
+
+ if (new_line || new_fill || new_text) {
+ if (!pGC->ops->devPrivate.val) {
+ pGC->ops = miCreateGCOps(pGC->ops);
+ pGC->ops->devPrivate.val = 1;
+ }
+ }
+
+ if (new_line || new_fill) {
+ if (pGC->lineWidth == 0) {
+ if (pGC->lineStyle == LineSolid && pGC->fillStyle == FillSolid)
+ pGC->ops->PolyArc = ilbmZeroPolyArcSS;
+ else
+ pGC->ops->PolyArc = miZeroPolyArc;
+ } else
+ pGC->ops->PolyArc = miPolyArc;
+ if (pGC->lineStyle == LineSolid) {
+ if (pGC->lineWidth == 0) {
+ if (pGC->fillStyle == FillSolid) {
+ pGC->ops->PolySegment = ilbmSegmentSS;
+ pGC->ops->Polylines = ilbmLineSS;
+ } else {
+ pGC->ops->PolySegment = miPolySegment;
+ pGC->ops->Polylines = miZeroLine;
+ }
+ } else {
+ pGC->ops->PolySegment = miPolySegment;
+ pGC->ops->Polylines = miWideLine;
+ }
+ } else {
+ if (pGC->lineWidth == 0 && pGC->fillStyle == FillSolid) {
+ pGC->ops->PolySegment = ilbmSegmentSD;
+ pGC->ops->Polylines = ilbmLineSD;
+ } else {
+ pGC->ops->PolySegment = miPolySegment;
+ pGC->ops->Polylines = miWideDash;
+ }
+ }
+ }
+
+ if (new_text || new_fill) {
+ if ((pGC->font) &&
+ (FONTMAXBOUNDS(pGC->font,rightSideBearing) -
+ FONTMINBOUNDS(pGC->font,leftSideBearing) > 32 ||
+ FONTMINBOUNDS(pGC->font,characterWidth) < 0)) {
+ pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
+ pGC->ops->ImageGlyphBlt = miImageGlyphBlt;
+ } else {
+ /* special case ImageGlyphBlt for terminal emulator fonts */
+ if ((pGC->font) &&
+ TERMINALFONT(pGC->font)) {
+ pGC->ops->ImageGlyphBlt = ilbmTEGlyphBlt;
+ } else {
+ pGC->ops->ImageGlyphBlt = ilbmImageGlyphBlt;
+ }
+
+ /* now do PolyGlyphBlt */
+ if (pGC->fillStyle == FillSolid) {
+ pGC->ops->PolyGlyphBlt = ilbmPolyGlyphBlt;
+ } else {
+ pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
+ }
+ }
+ }
+
+ if (new_fill) {
+ /* install a suitable fillspans and pushpixels */
+ pGC->ops->PushPixels = ilbmPushPixels;
+ pGC->ops->FillPolygon = miFillPolygon;
+ pGC->ops->PolyFillArc = miPolyFillArc;
+
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ pGC->ops->FillSpans = ilbmSolidFS;
+ pGC->ops->FillPolygon = ilbmFillPolygonSolid;
+ pGC->ops->PolyFillArc = ilbmPolyFillArcSolid;
+ break;
+ case FillTiled:
+ if (pGC->pRotatedPixmap)
+ pGC->ops->FillSpans = ilbmTileFS;
+ else
+ pGC->ops->FillSpans = ilbmUnnaturalTileFS;
+ break;
+ case FillOpaqueStippled:
+ if (pGC->pRotatedPixmap)
+ pGC->ops->FillSpans = ilbmOpaqueStippleFS;
+ else
+ pGC->ops->FillSpans = ilbmUnnaturalOpaqueStippleFS;
+ break;
+
+ case FillStippled:
+ if (pGC->pRotatedPixmap)
+ pGC->ops->FillSpans = ilbmStippleFS;
+ else
+ pGC->ops->FillSpans = ilbmUnnaturalStippleFS;
+ break;
+ }
+ } /* end of new_fill */
+}
+
+void
+ilbmDestroyGC(pGC)
+ GCPtr pGC;
+{
+ if (pGC->pRotatedPixmap)
+ (*pGC->pScreen->DestroyPixmap)(pGC->pRotatedPixmap);
+ if (pGC->freeCompClip)
+ REGION_DESTROY(pGC->pScreen, pGC->pCompositeClip);
+ miDestroyGCOps(pGC->ops);
+}
+
+/* table to map alu(src, dst) to alu(~src, dst) */
+int ilbmInverseAlu[16] = {
+ GXclear,
+ GXandInverted,
+ GXnor,
+ GXcopyInverted,
+ GXand,
+ GXnoop,
+ GXequiv,
+ GXorInverted,
+ GXandReverse,
+ GXxor,
+ GXinvert,
+ GXnand,
+ GXcopy,
+ GXor,
+ GXorReverse,
+ GXset
+};
+
+void
+ilbmReduceOpaqueStipple(fg, bg, planemask, depth, rop)
+register PixelType fg;
+register PixelType bg;
+register unsigned long planemask;
+int depth;
+register unsigned char *rop;
+{
+ register int d;
+ register Pixel mask = 1;
+
+ bg ^= fg;
+
+ for (d = 0; d < depth; d++, mask <<= 1) {
+ if (!(planemask & mask))
+ rop[d] = RROP_NOP;
+ else if (!(bg & mask)) {
+ /* Both fg and bg have a 0 or 1 in this plane */
+ if (fg & mask)
+ rop[d] = RROP_WHITE;
+ else
+ rop[d] = RROP_BLACK;
+ } else {
+ /* Both fg and bg have different bits on this plane */
+ if (fg & mask)
+ rop[d] = RROP_COPY;
+ else
+ rop[d] = RROP_INVERT;
+ }
+ }
+}
+
+void
+ilbmReduceRop(alu, src, planemask, depth, rop)
+ register int alu;
+ register Pixel src;
+ register unsigned long planemask;
+ int depth;
+ register unsigned char *rop;
+{
+ register int d;
+ register Pixel mask = 1;
+
+ for (d = 0; d < depth; d++, mask <<= 1) {
+ if (!(planemask & mask))
+ rop[d] = RROP_NOP;
+ else if ((src & mask) == 0) /* src is black */
+ switch (alu) {
+ case GXclear:
+ rop[d] = RROP_BLACK;
+ break;
+ case GXand:
+ rop[d] = RROP_BLACK;
+ break;
+ case GXandReverse:
+ rop[d] = RROP_BLACK;
+ break;
+ case GXcopy:
+ rop[d] = RROP_BLACK;
+ break;
+ case GXandInverted:
+ rop[d] = RROP_NOP;
+ break;
+ case GXnoop:
+ rop[d] = RROP_NOP;
+ break;
+ case GXxor:
+ rop[d] = RROP_NOP;
+ break;
+ case GXor:
+ rop[d] = RROP_NOP;
+ break;
+ case GXnor:
+ rop[d] = RROP_INVERT;
+ break;
+ case GXequiv:
+ rop[d] = RROP_INVERT;
+ break;
+ case GXinvert:
+ rop[d] = RROP_INVERT;
+ break;
+ case GXorReverse:
+ rop[d] = RROP_INVERT;
+ break;
+ case GXcopyInverted:
+ rop[d] = RROP_WHITE;
+ break;
+ case GXorInverted:
+ rop[d] = RROP_WHITE;
+ break;
+ case GXnand:
+ rop[d] = RROP_WHITE;
+ break;
+ case GXset:
+ rop[d] = RROP_WHITE;
+ break;
+ }
+ else /* src is white */
+ switch (alu) {
+ case GXclear:
+ rop[d] = RROP_BLACK;
+ break;
+ case GXand:
+ rop[d] = RROP_NOP;
+ break;
+ case GXandReverse:
+ rop[d] = RROP_INVERT;
+ break;
+ case GXcopy:
+ rop[d] = RROP_WHITE;
+ break;
+ case GXandInverted:
+ rop[d] = RROP_BLACK;
+ break;
+ case GXnoop:
+ rop[d] = RROP_NOP;
+ break;
+ case GXxor:
+ rop[d] = RROP_INVERT;
+ break;
+ case GXor:
+ rop[d] = RROP_WHITE;
+ break;
+ case GXnor:
+ rop[d] = RROP_BLACK;
+ break;
+ case GXequiv:
+ rop[d] = RROP_NOP;
+ break;
+ case GXinvert:
+ rop[d] = RROP_INVERT;
+ break;
+ case GXorReverse:
+ rop[d] = RROP_WHITE;
+ break;
+ case GXcopyInverted:
+ rop[d] = RROP_BLACK;
+ break;
+ case GXorInverted:
+ rop[d] = RROP_NOP;
+ break;
+ case GXnand:
+ rop[d] = RROP_INVERT;
+ break;
+ case GXset:
+ rop[d] = RROP_WHITE;
+ break;
+ }
+ }
+}
+
+void
+ilbmComputeCompositeClip(pGC, pDrawable)
+ GCPtr pGC;
+ DrawablePtr pDrawable;
+{
+ ScreenPtr pScreen = pGC->pScreen;
+
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ WindowPtr pWin = (WindowPtr) pDrawable;
+ RegionPtr pregWin;
+ Bool freeTmpClip, freeCompClip;
+
+ if (pGC->subWindowMode == IncludeInferiors) {
+ pregWin = NotClippedByChildren(pWin);
+ freeTmpClip = TRUE;
+ } else {
+ pregWin = &pWin->clipList;
+ freeTmpClip = FALSE;
+ }
+ freeCompClip = pGC->freeCompClip;
+
+ /*
+ * if there is no client clip, we can get by with just keeping the
+ * pointer we got, and remembering whether or not should destroy (or
+ * maybe re-use) it later. this way, we avoid unnecessary copying of
+ * regions. (this wins especially if many clients clip by children
+ * and have no client clip.)
+ */
+ if (pGC->clientClipType == CT_NONE) {
+ if (freeCompClip)
+ REGION_DESTROY(pScreen, pGC->pCompositeClip);
+ pGC->pCompositeClip = pregWin;
+ pGC->freeCompClip = freeTmpClip;
+ } else {
+ /*
+ * we need one 'real' region to put into the composite clip. if
+ * pregWin the current composite clip are real, we can get rid of
+ * one. if pregWin is real and the current composite clip isn't,
+ * use pregWin for the composite clip. if the current composite
+ * clip is real and pregWin isn't, use the current composite
+ * clip. if neither is real, create a new region.
+ */
+
+ REGION_TRANSLATE(pScreen, pGC->clientClip,
+ pDrawable->x + pGC->clipOrg.x,
+ pDrawable->y + pGC->clipOrg.y);
+
+ if (freeCompClip) {
+ REGION_INTERSECT(pGC->pScreen, pGC->pCompositeClip, pregWin,
+ pGC->clientClip);
+ if (freeTmpClip)
+ REGION_DESTROY(pScreen, pregWin);
+ } else if (freeTmpClip) {
+ REGION_INTERSECT(pScreen, pregWin, pregWin, pGC->clientClip);
+ pGC->pCompositeClip = pregWin;
+ } else {
+ pGC->pCompositeClip = REGION_CREATE(pScreen, NullBox, 0);
+ REGION_INTERSECT(pScreen, pGC->pCompositeClip,
+ pregWin, pGC->clientClip);
+ }
+ pGC->freeCompClip = TRUE;
+ REGION_TRANSLATE(pScreen, pGC->clientClip,
+ -(pDrawable->x + pGC->clipOrg.x),
+ -(pDrawable->y + pGC->clipOrg.y));
+ }
+ } /* end of composite clip for a window */
+ else {
+ BoxRec pixbounds;
+
+ /* XXX should we translate by drawable.x/y here ? */
+ pixbounds.x1 = 0;
+ pixbounds.y1 = 0;
+ pixbounds.x2 = pDrawable->width;
+ pixbounds.y2 = pDrawable->height;
+
+ if (pGC->freeCompClip) {
+ REGION_RESET(pScreen, pGC->pCompositeClip, &pixbounds);
+ } else {
+ pGC->freeCompClip = TRUE;
+ pGC->pCompositeClip = REGION_CREATE(pScreen, &pixbounds, 1);
+ }
+
+ if (pGC->clientClipType == CT_REGION) {
+ REGION_TRANSLATE(pScreen, pGC->pCompositeClip, -pGC->clipOrg.x,
+ -pGC->clipOrg.y);
+ REGION_INTERSECT(pScreen, pGC->pCompositeClip,
+ pGC->pCompositeClip, pGC->clientClip);
+ REGION_TRANSLATE(pScreen, pGC->pCompositeClip, pGC->clipOrg.x,
+ pGC->clipOrg.y);
+ }
+ } /* end of composite clip for pixmap */
+} /* end ilbmComputeCompositeClip */
diff --git a/xc/programs/Xserver/ilbm/ilbmgetsp.c b/xc/programs/Xserver/ilbm/ilbmgetsp.c
new file mode 100644
index 000000000..727bafd39
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmgetsp.c
@@ -0,0 +1,166 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmgetsp.c,v 3.0 1996/08/18 01:53:54 dawes Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmgetsp.c,v 5.10 94/04/17 20:28:24 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "Xmd.h"
+
+#include "misc.h"
+#include "region.h"
+#include "gc.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+#include "ilbm.h"
+#include "maskbits.h"
+
+#include "servermd.h"
+
+/* GetSpans -- for each span, gets bits from drawable starting at ppt[i]
+ * and continuing for pwidth[i] bits
+ * Each scanline returned will be server scanline padded, i.e., it will come
+ * out to an integral number of words.
+ */
+/*ARGSUSED*/
+void
+ilbmGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pchardstStart)
+ DrawablePtr pDrawable; /* drawable from which to get bits */
+ int wMax; /* largest value of all *pwidths */
+ register DDXPointPtr ppt; /* points to start copying from */
+ int *pwidth; /* list of number of bits to copy */
+ int nspans; /* number of scanlines to copy */
+ char *pchardstStart; /* where to put the bits */
+{
+ PixelType *pdstStart = (PixelType *)pchardstStart;
+ register PixelType *pdst; /* where to put the bits */
+ register PixelType *psrc; /* where to get the bits */
+ register PixelType tmpSrc; /* scratch buffer for bits */
+ PixelType *psrcBase; /* start of src bitmap */
+ int widthSrc; /* width of pixmap in bytes */
+ int auxSrc;
+ int depthSrc;
+ register DDXPointPtr pptLast; /* one past last point to get */
+ int xEnd; /* last pixel to copy from */
+ register int nstart;
+ register int d;
+ int nend;
+ int srcStartOver;
+ PixelType startmask, endmask;
+ unsigned int srcBit;
+ int nlMiddle, nl;
+ int w;
+
+ pptLast = ppt + nspans;
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, widthSrc, auxSrc, depthSrc,
+ psrcBase);
+ pdst = pdstStart;
+
+ while (ppt < pptLast) {
+ /* XXX should this really be << PWSH, or * 8, or * PGSZB? */
+ xEnd = min(ppt->x + *pwidth, widthSrc << PWSH);
+ pwidth++;
+ for (d = 0; d < depthSrc; d++) {
+ psrc = ilbmScanline(psrcBase, ppt->x, ppt->y, auxSrc);
+ psrcBase += widthSrc; /* @@@ NEXT PLANE @@@ */
+ w = xEnd - ppt->x;
+ srcBit = ppt->x & PIM;
+
+ if (srcBit + w <= PPW)
+ {
+ getandputbits0(psrc, srcBit, w, pdst);
+ pdst++;
+ }
+ else
+ {
+
+ maskbits(ppt->x, w, startmask, endmask, nlMiddle);
+ if (startmask)
+ nstart = PPW - srcBit;
+ else
+ nstart = 0;
+ if (endmask)
+ nend = xEnd & PIM;
+ srcStartOver = srcBit + nstart > PLST;
+ if (startmask)
+ {
+ getandputbits0(psrc, srcBit, nstart, pdst);
+ if (srcStartOver)
+ psrc++;
+ }
+ nl = nlMiddle;
+#ifdef FASTPUTBITS
+ Duff(nl, putbits(*psrc, nstart, PPW, pdst); psrc++; pdst++;);
+#else
+ while (nl--)
+ {
+ tmpSrc = *psrc;
+ putbits(tmpSrc, nstart, PPW, pdst);
+ psrc++;
+ pdst++;
+ }
+#endif
+ if (endmask)
+ {
+ putbits(*psrc, nstart, nend, pdst);
+ if (nstart + nend > PPW)
+ pdst++;
+ }
+ if (startmask || endmask)
+ pdst++;
+ }
+ }
+ ppt++;
+ }
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmhrzvert.c b/xc/programs/Xserver/ilbm/ilbmhrzvert.c
new file mode 100644
index 000000000..fe2638167
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmhrzvert.c
@@ -0,0 +1,209 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmhrzvert.c,v 3.0 1996/08/18 01:53:55 dawes Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmhrzvert.c,v 1.15 94/04/17 20:28:24 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+
+#include "gc.h"
+#include "window.h"
+#include "pixmap.h"
+#include "region.h"
+
+#include "ilbm.h"
+#include "maskbits.h"
+
+/* horizontal solid line
+ abs(len) > 1
+*/
+ilbmHorzS(pbase, nlwidth, auxDst, depthDst, x1, y1, len, rrops)
+PixelType *pbase; /* pointer to base of bitmap */
+register int nlwidth; /* width in longwords of bitmap */
+int auxDst;
+int depthDst;
+int x1; /* initial point */
+int y1;
+int len; /* length of line */
+register unsigned char *rrops;
+{
+ register PixelType *addrl;
+ register PixelType startmask;
+ register PixelType endmask;
+ register int nlmiddle;
+ register int d;
+ int saveNLmiddle;
+
+ /* force the line to go left to right
+ but don't draw the last point
+ */
+ if (len < 0) {
+ x1 += len;
+ x1 += 1;
+ len = -len;
+ }
+
+ /* all bits inside same longword */
+ if ( ((x1 & PIM) + len) < PPW) {
+ maskpartialbits(x1, len, startmask);
+
+ for (d = 0; d < depthDst; d++) {
+ addrl = ilbmScanline(pbase, x1, y1, auxDst);
+ pbase += nlwidth; /* @@@ NEXT PLANE @@@ */
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ *addrl &= ~startmask;
+ break;
+ case RROP_WHITE:
+ *addrl |= startmask;
+ break;
+ case RROP_INVERT:
+ *addrl ^= startmask;
+ break;
+ case RROP_NOP:
+ break;
+ } /* switch */
+ } /* for (d = ...) */
+ } else {
+ maskbits(x1, len, startmask, endmask, nlmiddle);
+ saveNLmiddle = nlmiddle;
+
+ for (d = 0; d < depthDst; d++) {
+ addrl = ilbmScanline(pbase, x1, y1, auxDst);
+ pbase += nlwidth; /* @@@ NEXT PLANE @@@ */
+ nlmiddle = saveNLmiddle;
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ if (startmask)
+ *addrl++ &= ~startmask;
+ Duff (nlmiddle, *addrl++ = 0x0);
+ if (endmask)
+ *addrl &= ~endmask;
+ break;
+
+ case RROP_WHITE:
+ if (startmask)
+ *addrl++ |= startmask;
+ Duff (nlmiddle, *addrl++ = ~0);
+ if (endmask)
+ *addrl |= endmask;
+ break;
+
+ case RROP_INVERT:
+ if (startmask)
+ *addrl++ ^= startmask;
+ Duff (nlmiddle, *addrl++ ^= ~0);
+ if (endmask)
+ *addrl ^= endmask;
+ break;
+
+ case RROP_NOP:
+ break;
+ } /* switch */
+ } /* for (d = ... ) */
+ }
+}
+
+/* vertical solid line
+ this uses do loops because pcc (Ultrix 1.2, bsd 4.2) generates
+ better code. sigh. we know that len will never be 0 or 1, so
+ it's OK to use it.
+*/
+
+ilbmVertS(pbase, nlwidth, auxDst, depthDst, x1, y1, len, rrops)
+PixelType *pbase; /* pointer to base of bitmap */
+register int nlwidth; /* width in longwords of bitmap */
+int auxDst;
+int depthDst;
+int x1, y1; /* initial point */
+register int len; /* length of line */
+unsigned char *rrops;
+{
+ register PixelType *addrl;
+ register PixelType bitmask;
+ int saveLen;
+ int d;
+
+ if (len < 0) {
+ auxDst = -auxDst;
+ len = -len;
+ }
+
+ saveLen = len;
+
+ for (d = 0; d < depthDst; d++) {
+ addrl = ilbmScanline(pbase, x1, y1, auxDst);
+ pbase += nlwidth; /* @@@ NEXT PLANE @@@ */
+ len = saveLen;
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ bitmask = rmask[x1 & PIM];
+ Duff(len, *addrl &= bitmask; ilbmScanlineInc(addrl, auxDst) );
+ break;
+
+ case RROP_WHITE:
+ bitmask = mask[x1 & PIM];
+ Duff(len, *addrl |= bitmask; ilbmScanlineInc(addrl, auxDst) );
+ break;
+
+ case RROP_INVERT:
+ bitmask = mask[x1 & PIM];
+ Duff(len, *addrl ^= bitmask; ilbmScanlineInc(addrl, auxDst) );
+ break;
+
+ case RROP_NOP:
+ break;
+ } /* switch */
+ } /* for (d = ...) */
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmimage.c b/xc/programs/Xserver/ilbm/ilbmimage.c
new file mode 100644
index 000000000..d2f7a4df9
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmimage.c
@@ -0,0 +1,437 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmimage.c,v 3.1 1998/03/20 21:08:02 hohndel Exp $ */
+#include <stdio.h>
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "ilbm.h"
+#include "maskbits.h"
+#include "servermd.h"
+
+void
+ilbmPutImage(pDraw, pGC, depth, x, y, width, height, leftPad, format, pImage)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int depth, x, y, width, height;
+ int leftPad;
+ int format;
+ char *pImage;
+{
+ PixmapPtr pPixmap;
+
+#if 1
+ fprintf(stderr, "ilbmPutImage()\n");
+ fprintf(stderr, "\tdepth = %d, x = %d, y = %d, width = %d, height = %d, "
+ "leftPad = %d\n", depth, x, y, width, height, leftPad);
+ switch (format) {
+ case XYBitmap:
+ fprintf(stderr, "\tformat = XYBitmap\n");
+ break;
+ case XYPixmap:
+ fprintf(stderr, "\tformat = XYPixmap\n");
+ break;
+ case ZPixmap:
+ fprintf(stderr, "\tformat = ZPixmap\n");
+ break;
+ default:
+ fprintf(stderr, "\tformat = %d\n");
+ break;
+ }
+#endif
+
+ if ((width == 0) || (height == 0))
+ return;
+
+ if (format != ZPixmap || depth == 1 || pDraw->depth == 1) {
+ if (format == XYBitmap) {
+ char *ptmp;
+ int realwidth;
+ int size;
+ int aux;
+ int d, yy, xx;
+ char *ss, *dd;
+
+ realwidth = BitmapBytePad(width+leftPad);
+ aux = depth*realwidth;
+ size = height*aux;
+
+#if 1
+ fprintf(stderr, "\trealwidth = %d, aux = %d, size = %d\n", realwidth,
+ aux, size);
+#endif
+
+ if (!(ptmp = (char *)ALLOCATE_LOCAL(size)))
+ return;
+
+ /*
+ * Convert from bitplanes to interleaved bitplanes
+ */
+
+ ss = (char *)pImage;
+ for (d = 0; d < depth; d++) {
+ dd = ptmp+d*realwidth;
+ for (yy = 0; yy < height; yy++) {
+ for (xx = 0; xx < realwidth; xx++)
+#if 1
+ {
+ fprintf(stderr, "*(%d) = *(%d)\n", (&dd[xx])-ptmp,
+ ss-(char *)pImage);
+#endif
+ dd[xx] = *(ss++);
+#if 1
+ }
+#endif
+ dd += aux;
+ }
+ }
+
+ pPixmap = GetScratchPixmapHeader(pDraw->pScreen, width+leftPad, height,
+ depth, depth,
+ BitmapBytePad(width+leftPad),
+ (pointer)ptmp);
+ if (!pPixmap) {
+ DEALLOCATE_LOCAL(ptmp);
+ return;
+ }
+ pGC->fExpose = FALSE;
+ (void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, pDraw, pGC, leftPad,
+ 0, width, height, x, y, 1);
+ DEALLOCATE_LOCAL(ptmp);
+ } else {
+#if 0
+ /* XXX: bit plane order wronge ! */
+ pPixmap->drawable.depth = 1;
+ pPixmap->drawable.bitsPerPixel = 1;
+
+ switch (pGC->alu) {
+ case GXcopy:
+ doBitBlt = ilbmDoBitbltCopy;
+ break;
+ case GXxor:
+ doBitBlt = ilbmDoBitbltXor;
+ break;
+ case GXcopyInverted:
+ doBitBlt = ilbmDoBitbltCopyInverted;
+ break;
+ case GXor:
+ doBitBlt = ilbmDoBitbltOr;
+ break;
+ default:
+ doBitBlt = ilbmDoBitbltGeneral;
+ break;
+ }
+
+ for (plane = (1L << (pPixmap->drawable.depth - 1)); plane;
+ plane >>= 1) {
+ (void)ilbmBitBlt((DrawablePtr)pPixmap, pDraw, pGC, leftPad, 0,
+ width, height, x, y, doBitBlt, plane);
+ /* pDraw->devKind += sizeDst; */
+ }
+#else
+ char *ptmp;
+ int realwidth;
+ int size;
+ int aux;
+ int d, yy, xx;
+ char *ss, *dd;
+
+ realwidth = BitmapBytePad(width+leftPad);
+ aux = depth*realwidth;
+ size = height*aux;
+
+#if 1
+ fprintf(stderr, "\trealwidth = %d, aux = %d, size = %d\n", realwidth,
+ aux, size);
+#endif
+
+ if (!(ptmp = (char *)ALLOCATE_LOCAL(size)))
+ return;
+
+ /*
+ * Convert from bitplanes to interleaved bitplanes
+ */
+
+ ss = (char *)pImage;
+ for (d = 0; d < depth; d++) {
+ dd = ptmp+d*realwidth;
+ for (yy = 0; yy < height; yy++) {
+ for (xx = 0; xx < realwidth; xx++)
+#if 1
+ {
+ fprintf(stderr, "*(%d) = *(%d)\n", (&dd[xx])-ptmp,
+ ss-(char *)pImage);
+#endif
+ dd[xx] = *(ss++);
+#if 1
+ }
+#endif
+ dd += aux;
+ }
+ }
+
+ pPixmap = GetScratchPixmapHeader(pDraw->pScreen, width+leftPad, height,
+ depth, depth,
+ BitmapBytePad(width+leftPad),
+ (pointer)ptmp);
+ if (!pPixmap) {
+ DEALLOCATE_LOCAL(ptmp);
+ return;
+ }
+
+ pGC->fExpose = FALSE;
+ (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, pDraw, pGC, leftPad,
+ 0, width, height, x, y);
+ DEALLOCATE_LOCAL(ptmp);
+#endif
+ }
+
+ pGC->fExpose = TRUE;
+ FreeScratchPixmapHeader(pPixmap);
+ } else {
+ /* Chunky to planar conversion required */
+
+ PixmapPtr pPixmap;
+ ScreenPtr pScreen = pDraw->pScreen;
+ int widthSrc;
+ int start_srcshift;
+ register int b;
+ register int dstshift;
+ register int shift_step;
+ register PixelType dst;
+ register PixelType srcbits;
+ register PixelType *pdst;
+ register PixelType *psrc;
+ int start_bit;
+ register int nl;
+ register int h;
+ register int d;
+ int auxDst;
+ PixelType *pdstBase;
+ int widthDst;
+ int depthDst;
+
+ /* Create a tmp pixmap */
+ pPixmap = (pScreen->CreatePixmap)(pScreen, width, height, depth);
+ if (!pPixmap)
+ return;
+
+ ilbmGetPixelWidthAuxDepthAndPointer((DrawablePtr)pPixmap, widthDst,
+ auxDst, depthDst, pdstBase);
+
+ widthSrc = PixmapWidthInPadUnits(width, depth);
+ /* XXX: if depth == 8, use fast chunky to planar assembly function.*/
+ if (depth > 4) {
+ start_srcshift = 24;
+ shift_step = 8;
+ } else {
+ start_srcshift = 28;
+ shift_step = 4;
+ }
+
+ for (d = 0; d < depth; d++, pdstBase += widthDst) { /* @@@ NEXT PLANE @@@ */
+ register PixelType *pdstLine = pdstBase;
+ start_bit = start_srcshift + d;
+ psrc = (PixelType *)pImage;
+ h = height;
+
+ while (h--) {
+ pdst = pdstLine;
+ pdstLine += auxDst;
+ dstshift = PPW - 1;
+ dst = 0;
+ nl = widthSrc;
+ while (nl--) {
+ srcbits = *psrc++;
+ for (b = start_bit; b >= 0; b -= shift_step) {
+ dst |= ((srcbits >> b) & 1) << dstshift;
+ if (--dstshift < 0) {
+ dstshift = PPW - 1;
+ *pdst++ = dst;
+ dst = 0;
+ }
+ }
+ }
+ if (dstshift != PPW - 1)
+ *pdst++ = dst;
+ }
+ } /* for (d = ...) */
+
+ pGC->fExpose = FALSE;
+ (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, pDraw, pGC, leftPad, 0,
+ width, height, x, y);
+ pGC->fExpose = TRUE;
+ (*pScreen->DestroyPixmap)(pPixmap);
+ }
+}
+
+void
+ilbmGetImage(pDrawable, sx, sy, width, height, format, planemask, pdstLine)
+ DrawablePtr pDrawable;
+ int sx, sy, width, height;
+ unsigned int format;
+ unsigned long planemask;
+ char *pdstLine;
+{
+ BoxRec box;
+ DDXPointRec ptSrc;
+ RegionRec rgnDst;
+ ScreenPtr pScreen;
+ PixmapPtr pPixmap;
+
+#if 1
+ fprintf(stderr, "ilbmGetImage()\n");
+ fprintf(stderr, "\tsx = %d, sy = %d, width = %d, height = %d, "
+ "planemask = 0x%08x\n", sx, sy, width, height, planemask);
+ switch (format) {
+ case XYBitmap:
+ fprintf(stderr, "\tformat = XYBitmap\n");
+ break;
+ case XYPixmap:
+ fprintf(stderr, "\tformat = XYPixmap\n");
+ break;
+ case ZPixmap:
+ fprintf(stderr, "\tformat = ZPixmap\n");
+ break;
+ default:
+ fprintf(stderr, "\tformat = %d\n");
+ break;
+ }
+#endif
+
+ if ((width == 0) || (height == 0))
+ return;
+
+ pScreen = pDrawable->pScreen;
+ sx += pDrawable->x;
+ sy += pDrawable->y;
+
+ if (format == XYPixmap || pDrawable->depth == 1) {
+ pPixmap = GetScratchPixmapHeader(pScreen, width, height, 1, 1,
+ BitmapBytePad(width), (pointer)pdstLine);
+ if (!pPixmap)
+ return;
+
+ ptSrc.x = sx;
+ ptSrc.y = sy;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = width;
+ box.y2 = height;
+ REGION_INIT(pScreen, &rgnDst, &box, 1);
+
+ pPixmap->drawable.depth = 1;
+ pPixmap->drawable.bitsPerPixel = 1;
+ /* dix layer only ever calls GetImage with 1 bit set in planemask
+ * when format is XYPixmap.
+ */
+ ilbmDoBitblt(pDrawable, (DrawablePtr)pPixmap, GXcopy, &rgnDst, &ptSrc,
+ planemask);
+
+ FreeScratchPixmapHeader(pPixmap);
+ REGION_UNINIT(pScreen, &rgnDst);
+ } else {
+ /* Planar to chunky conversion required */
+
+ PixelType *psrcBits;
+ PixelType *psrcLine;
+ PixelType startmask, endmask;
+ int depthSrc;
+ int widthSrc;
+ int auxSrc;
+ int sizeDst;
+ int widthDst;
+ register PixelType *psrc;
+ register PixelType *pdst;
+ register PixelType dst;
+ register PixelType srcbits;
+ register int d;
+ register int b;
+ register int dstshift;
+ register int shift_step;
+ register int start_endbit;
+ int start_startbit;
+ register int end_endbit;
+ register int start_dstshift;
+ register int nl;
+ register int h;
+ int nlmiddle;
+
+ widthDst = PixmapWidthInPadUnits(width, pDrawable->depth);
+ sizeDst = widthDst * height;
+
+ /* Clear the dest image */
+ bzero(pdstLine, sizeDst << 2);
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, widthSrc, auxSrc,
+ depthSrc, psrcBits);
+
+ psrcBits = ilbmScanline(psrcBits, sx, sy, auxSrc);
+
+ start_startbit = PPW - 1 - (sx & PIM);
+ if ((sx & PIM) + width < PPW) {
+ maskpartialbits(sx, width, startmask);
+ nlmiddle = 0;
+ endmask = 0;
+ start_endbit = PPW - ((sx + width) & PIM);
+ } else {
+ maskbits(sx, width, startmask, endmask, nlmiddle);
+ start_endbit = 0;
+ end_endbit = PPW - ((sx + width) & PIM);
+ }
+ /* ZPixmap images have either 4 or 8 bits per pixel dependent on
+ * depth.
+ */
+ if (depthSrc > 4) {
+ start_dstshift = 24;
+ shift_step = 8;
+ } else {
+ start_dstshift = 28;
+ shift_step = 4;
+ }
+#define SHIFT_BITS(start_bit,end_bit) \
+for (b = (start_bit); b >= (end_bit); b--) { \
+ dst |= ((srcbits >> b) & 1) << dstshift; \
+ if ((dstshift -= shift_step) < 0) { \
+ dstshift = start_dstshift + d; \
+ *pdst++ = dst; \
+ dst = *pdst; \
+ } \
+} \
+
+ for (d = 0; d < depthSrc; d++, psrcBits += widthSrc) { /* @@@ NEXT PLANE @@@ */
+ psrcLine = psrcBits;
+ pdst = (PixelType *)pdstLine;
+ h = height;
+
+ while (h--) {
+ psrc = psrcLine;
+ psrcLine += auxSrc;
+ dst = *pdst;
+ dstshift = start_dstshift + d;
+
+ if (startmask) {
+ srcbits = *psrc++ & startmask;
+ SHIFT_BITS(start_startbit, start_endbit);
+ }
+
+ nl = nlmiddle;
+ while (nl--) {
+ srcbits = *psrc++;
+ SHIFT_BITS(PPW - 1, 0);
+ }
+ if (endmask) {
+ srcbits = *psrc & endmask;
+ SHIFT_BITS(PPW - 1, end_endbit);
+ }
+
+ if (dstshift != start_dstshift + d)
+ *pdst++ = dst;
+ } /* while (h--) */
+ } /* for (d = ...) */
+ }
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmimggblt.c b/xc/programs/Xserver/ilbm/ilbmimggblt.c
new file mode 100644
index 000000000..1bd6f02f9
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmimggblt.c
@@ -0,0 +1,470 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmimggblt.c,v 3.1 1998/03/20 21:08:02 hohndel Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmimggblt.c,v 5.17 94/04/17 20:28:25 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "ilbm.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "maskbits.h"
+
+/*
+ we should eventually special-case fixed-width fonts for ImageText.
+
+ this works for fonts with glyphs <= 32 bits wide.
+
+ the clipping calculations are done for worst-case fonts.
+we make no assumptions about the heights, widths, or bearings
+of the glyphs. if we knew that the glyphs are all the same height,
+we could clip the tops and bottoms per clipping box, rather
+than per character per clipping box. if we knew that the glyphs'
+left and right bearings were wlle-behaved, we could clip a single
+character at the start, output until the last unclipped
+character, and then clip the last one. this is all straightforward
+to determine based on max-bounds and min-bounds from the font.
+ there is some inefficiency introduced in the per-character
+clipping to make what's going on clearer.
+
+ (it is possible, for example, for a font to be defined in which the
+next-to-last character in a font would be clipped out, but the last
+one wouldn't. the code below deals with this.)
+
+ Image text looks at the bits in the glyph and the fg and bg in the
+GC. it paints a rectangle, as defined in the protocol dcoument,
+and the paints the characters.
+
+ the register allocations for startmask and endmask may not
+be the right thing. are there two other deserving candidates?
+xoff, pdst, pglyph, and tmpSrc seem like the right things, though.
+*/
+
+void
+ilbmImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ pointer pglyphBase; /* start of array of glyphs */
+{
+ ExtentInfoRec info; /* used by QueryGlyphExtents() */
+ BoxRec bbox; /* string's bounding box */
+ xRectangle backrect;/* backing rectangle to paint.
+ in the general case, NOT necessarily
+ the same as the string's bounding box
+ */
+
+ CharInfoPtr pci;
+ int xorg, yorg; /* origin of drawable in bitmap */
+ int widthDst; /* width of dst in longwords */
+
+ /* these keep track of the character origin */
+ PixelType *pdstBase;
+ /* points to longword with character origin */
+ int xchar; /* xorigin of char (mod 32) */
+
+ /* these are used for placing the glyph */
+ register int xoff; /* x offset of left edge of glyph (mod 32) */
+ register PixelType *pdst;
+ /* pointer to current longword in dst */
+
+ register int d;
+ int depthDst;
+ int auxDst;
+ int hSave;
+ int w; /* width of glyph in bits */
+ int h; /* height of glyph */
+ int widthGlyph; /* width of glyph, in bytes */
+ unsigned char rrops[AFB_MAX_DEPTH];
+ register unsigned char *pglyph;
+ /* pointer to current row of glyph */
+ unsigned char *pglyphSave;
+
+ /* used for putting down glyph */
+ register PixelType tmpSrc;
+ /* for getting bits from glyph */
+ register PixelType startmask;
+ register PixelType endmask;
+
+ register int nFirst;/* bits of glyph in current longword */
+ PixelType *pdstSave;
+ int oldFill;
+ ilbmPrivGC *pPriv = (ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr);
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+ ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, widthDst, auxDst, depthDst,
+ pdstBase);
+
+ QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info);
+
+ backrect.x = x;
+ backrect.y = y - FONTASCENT(pGC->font);
+ backrect.width = info.overallWidth;
+ backrect.height = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+
+ x += xorg;
+ y += yorg;
+
+ bbox.x1 = x + info.overallLeft;
+ bbox.x2 = x + info.overallRight;
+ bbox.y1 = y - info.overallAscent;
+ bbox.y2 = y + info.overallDescent;
+
+ oldFill = pGC->fillStyle;
+ pGC->fillStyle = FillSolid;
+ ilbmReduceRop (pGC->alu, pGC->bgPixel, pGC->planemask, pGC->depth,
+ pPriv->rrops);
+ ilbmPolyFillRect(pDrawable, pGC, 1, &backrect);
+ pGC->fillStyle = oldFill;
+ ilbmReduceRop (pGC->alu, pGC->fgPixel, pGC->planemask, pGC->depth,
+ pPriv->rrops);
+ ilbmReduceRop (GXcopy, pGC->fgPixel, pGC->planemask, pGC->depth, rrops);
+
+ /* the faint-hearted can open their eyes now */
+
+ switch (RECT_IN_REGION(pGC->pScreen, pGC->pCompositeClip, &bbox)) {
+ case rgnOUT:
+ break;
+ case rgnIN:
+ pdstBase = ilbmScanlineNoBankSwitch(pdstBase, x, y, auxDst);
+ xchar = x & PIM;
+
+ while (nglyph--) {
+ pci = *ppci;
+ pglyphSave = FONTGLYPHBITS(pglyphBase, pci);
+ w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ hSave = pci->metrics.ascent + pci->metrics.descent;
+ widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
+ /* start at top scanline of glyph */
+ pdstSave = ilbmScanlineDelta(pdstBase, -pci->metrics.ascent,
+ auxDst);
+
+ /* find correct word in scanline and x offset within it
+ for left edge of glyph
+ */
+ xoff = xchar + pci->metrics.leftSideBearing;
+ if (xoff > PLST) {
+ pdstSave++;
+ xoff &= PIM;
+ } else if (xoff < 0) {
+ xoff += PPW;
+ pdstSave--;
+ }
+
+ for (d = 0; d < depthDst; d++) {
+ h = hSave;
+ pdst = pdstSave;
+ pdstSave += widthDst; /* @@@ NEXT PLANE @@@ */
+ pglyph = pglyphSave;
+
+ if ((xoff + w) <= PPW) {
+ /* glyph all in one longword */
+ maskpartialbits(xoff, w, startmask);
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ while (h--) {
+ getleftbits(pglyph, w, tmpSrc);
+ *pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask);
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ case RROP_WHITE:
+ while (h--) {
+ getleftbits(pglyph, w, tmpSrc);
+ *pdst |= SCRRIGHT(tmpSrc, xoff) & startmask;
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ case RROP_NOP:
+ break;
+ }
+ } else {
+ /* glyph crosses longword boundary */
+ maskPPWbits(xoff, w, startmask, endmask);
+ nFirst = PPW - xoff;
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ while (h--) {
+ getleftbits(pglyph, w, tmpSrc);
+ *pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask);
+ *(pdst+1) &= ~(SCRLEFT(tmpSrc, nFirst) & endmask);
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ case RROP_WHITE:
+ while (h--) {
+ getleftbits(pglyph, w, tmpSrc);
+ *pdst |= SCRRIGHT(tmpSrc, xoff) & startmask;
+ *(pdst+1) |= SCRLEFT(tmpSrc, nFirst) & endmask;
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ case RROP_NOP:
+ break;
+ }
+ } /* glyph crosses longwords boundary */
+ } /* depth loop */
+ /* update character origin */
+ x += pci->metrics.characterWidth;
+ xchar += pci->metrics.characterWidth;
+ if (xchar > PLST) {
+ xchar -= PPW;
+ pdstBase++;
+ } else if (xchar < 0) {
+ xchar += PPW;
+ pdstBase--;
+ }
+ ppci++;
+ } /* while nglyph-- */
+ break;
+ case rgnPART:
+ {
+ ilbmTEXTPOS *ppos;
+ int nbox;
+ BoxPtr pbox;
+ RegionPtr cclip;
+ int xpos; /* x position of char origin */
+ int i;
+ BoxRec clip;
+ int leftEdge, rightEdge;
+ int topEdge, bottomEdge;
+ int glyphRow; /* first row of glyph not wholly
+ clipped out */
+ int glyphCol; /* leftmost visible column of glyph */
+ int getWidth; /* bits to get from glyph */
+
+ if (!(ppos = (ilbmTEXTPOS *)ALLOCATE_LOCAL(nglyph *
+ sizeof(ilbmTEXTPOS))))
+ return;
+
+ pdstBase = ilbmScanlineNoBankSwitch(pdstBase, x, y, auxDst);
+ xpos = x;
+ xchar = xpos & PIM;
+
+ for (i = 0; i < nglyph; i++) {
+ pci = ppci[i];
+
+ ppos[i].xpos = xpos;
+ ppos[i].xchar = xchar;
+ ppos[i].leftEdge = xpos + pci->metrics.leftSideBearing;
+ ppos[i].rightEdge = xpos + pci->metrics.rightSideBearing;
+ ppos[i].topEdge = y - pci->metrics.ascent;
+ ppos[i].bottomEdge = y + pci->metrics.descent;
+ ppos[i].pdstBase = pdstBase;
+ ppos[i].widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
+
+ xpos += pci->metrics.characterWidth;
+ xchar += pci->metrics.characterWidth;
+ if (xchar > PLST) {
+ xchar &= PIM;
+ pdstBase++;
+ } else if (xchar < 0) {
+ xchar += PPW;
+ pdstBase--;
+ }
+ }
+
+ cclip = pGC->pCompositeClip;
+ pbox = REGION_RECTS(cclip);
+ nbox = REGION_NUM_RECTS(cclip);
+
+ /* HACK ALERT
+ since we continue out of the loop below so often, it
+ is easier to increment pbox at the top than at the end.
+ don't try this at home.
+ */
+ pbox--;
+ while (nbox--) {
+ pbox++;
+ clip.x1 = max(bbox.x1, pbox->x1);
+ clip.y1 = max(bbox.y1, pbox->y1);
+ clip.x2 = min(bbox.x2, pbox->x2);
+ clip.y2 = min(bbox.y2, pbox->y2);
+ if ((clip.x2<=clip.x1) || (clip.y2<=clip.y1))
+ continue;
+
+ for (i = 0; i < nglyph; i++) {
+ pci = ppci[i];
+ xchar = ppos[i].xchar;
+
+ /* clip the left and right edges */
+ if (ppos[i].leftEdge < clip.x1)
+ leftEdge = clip.x1;
+ else
+ leftEdge = ppos[i].leftEdge;
+
+ if (ppos[i].rightEdge > clip.x2)
+ rightEdge = clip.x2;
+ else
+ rightEdge = ppos[i].rightEdge;
+
+ w = rightEdge - leftEdge;
+ if (w <= 0)
+ continue;
+
+ /* clip the top and bottom edges */
+ if (ppos[i].topEdge < clip.y1)
+ topEdge = clip.y1;
+ else
+ topEdge = ppos[i].topEdge;
+
+ if (ppos[i].bottomEdge > clip.y2)
+ bottomEdge = clip.y2;
+ else
+ bottomEdge = ppos[i].bottomEdge;
+
+ hSave = bottomEdge - topEdge;
+ if (hSave <= 0)
+ continue;
+
+ glyphRow = (topEdge - y) + pci->metrics.ascent;
+ widthGlyph = ppos[i].widthGlyph;
+ pglyphSave = FONTGLYPHBITS(pglyphBase, pci);
+ pglyphSave += (glyphRow * widthGlyph);
+
+ glyphCol = (leftEdge - ppos[i].xpos) -
+ (pci->metrics.leftSideBearing);
+ getWidth = w + glyphCol;
+
+ pdstSave = ilbmScanlineDelta(ppos[i].pdstBase, -(y-topEdge),
+ auxDst);
+ xoff = xchar + (leftEdge - ppos[i].xpos);
+ if (xoff > PLST) {
+ xoff &= PIM;
+ pdstSave++;
+ } else if (xoff < 0) {
+ xoff += PPW;
+ pdstSave--;
+ }
+
+ for (d = 0; d < depthDst; d++) {
+ h = hSave;
+ pdst = pdstSave;
+ pdstSave += widthDst; /* @@@ NEXT PLANE @@@ */
+ pglyph = pglyphSave;
+
+ if ((xoff + w) <= PPW) {
+ maskpartialbits(xoff, w, startmask);
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ while (h--) {
+ getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
+ *pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask);
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ case RROP_WHITE:
+ while (h--) {
+ getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
+ *pdst |= SCRRIGHT(tmpSrc, xoff) & startmask;
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ case RROP_NOP:
+ break;
+ }
+ } else {
+ maskPPWbits(xoff, w, startmask, endmask);
+ nFirst = PPW - xoff;
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ while (h--) {
+ getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
+ *pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask);
+ *(pdst+1) &= ~(SCRLEFT(tmpSrc, nFirst) & endmask);
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ case RROP_WHITE:
+ while (h--) {
+ getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
+ *pdst |= SCRRIGHT(tmpSrc, xoff) & startmask;
+ *(pdst+1) |= SCRLEFT(tmpSrc, nFirst) & endmask;
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ case RROP_NOP:
+ break;
+ }
+ }
+ } /* depth */
+ } /* for each glyph */
+ } /* while nbox-- */
+ DEALLOCATE_LOCAL(ppos);
+ break;
+ }
+
+ default:
+ break;
+ }
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmline.c b/xc/programs/Xserver/ilbm/ilbmline.c
new file mode 100644
index 000000000..d831489c5
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmline.c
@@ -0,0 +1,701 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmline.c,v 3.1 1998/03/20 21:08:02 hohndel Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmline.c,v 5.18 94/04/17 20:28:26 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "mistruct.h"
+
+#include "ilbm.h"
+#include "maskbits.h"
+#include "miline.h"
+
+/* single-pixel lines on a color frame buffer
+
+ NON-SLOPED LINES
+ horizontal lines are always drawn left to right; we have to
+move the endpoints right by one after they're swapped.
+ horizontal lines will be confined to a single band of a
+region. the code finds that band (giving up if the lower
+bound of the band is above the line we're drawing); then it
+finds the first box in that band that contains part of the
+line. we clip the line to subsequent boxes in that band.
+ vertical lines are always drawn top to bottom (y-increasing.)
+this requires adding one to the y-coordinate of each endpoint
+after swapping.
+
+ SLOPED LINES
+ when clipping a sloped line, we bring the second point inside
+the clipping box, rather than one beyond it, and then add 1 to
+the length of the line before drawing it. this lets us use
+the same box for finding the outcodes for both endpoints. since
+the equation for clipping the second endpoint to an edge gives us
+1 beyond the edge, we then have to move the point towards the
+first point by one step on the major axis.
+ eventually, there will be a diagram here to explain what's going
+on. the method uses Cohen-Sutherland outcodes to determine
+outsideness, and a method similar to Pike's layers for doing the
+actual clipping.
+
+*/
+
+void
+#ifdef POLYSEGMENT
+ilbmSegmentSS(pDrawable, pGC, nseg, pSeg)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nseg;
+ register xSegment *pSeg;
+#else
+ilbmLineSS(pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt; /* number of points */
+ DDXPointPtr pptInit;
+#endif
+{
+ int nboxInit;
+ register int nbox;
+ BoxPtr pboxInit;
+ register BoxPtr pbox;
+#ifndef POLYSEGMENT
+ register DDXPointPtr ppt; /* pointer to list of translated points */
+#endif
+
+ unsigned int oc1; /* outcode of point 1 */
+ unsigned int oc2; /* outcode of point 2 */
+
+ PixelType *addrlBase; /* pointer to start of drawable */
+ PixelType *addrl; /* address of destination pixmap */
+ int nlwidth; /* width in longwords of destination pixmap */
+ int xorg, yorg; /* origin of window */
+
+ int adx; /* abs values of dx and dy */
+ int ady;
+ int signdx; /* sign of dx and dy */
+ int signdy;
+ int e, e1, e2; /* bresenham error and increments */
+ int len; /* length of segment */
+ int axis; /* major axis */
+ int octant;
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ int depthDst;
+ int d;
+ int auxDst;
+ unsigned char *rrops;
+
+ /* a bunch of temporaries */
+ register int y1, y2;
+ register int x1, x2;
+ RegionPtr cclip;
+
+ cclip = pGC->pCompositeClip;
+ rrops = ((ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr))->rrops;
+ pboxInit = REGION_RECTS(cclip);
+ nboxInit = REGION_NUM_RECTS(cclip);
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
+ addrlBase);
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+#ifdef POLYSEGMENT
+ while (nseg--)
+#else
+ ppt = pptInit;
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+ while (--npt)
+#endif
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+
+#ifdef POLYSEGMENT
+ x1 = pSeg->x1 + xorg;
+ y1 = pSeg->y1 + yorg;
+ x2 = pSeg->x2 + xorg;
+ y2 = pSeg->y2 + yorg;
+ pSeg++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious) {
+ xorg = x1;
+ yorg = y1;
+ }
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+#endif
+
+ if (x1 == x2) /* vertical line */
+ {
+ /* make the line go top to bottom of screen, keeping
+ endpoint semantics
+ */
+ if (y1 > y2) {
+ register int tmp;
+
+ tmp = y2;
+ y2 = y1 + 1;
+ y1 = tmp + 1;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ y1--;
+#endif
+ }
+#ifdef POLYSEGMENT
+ else if (pGC->capStyle != CapNotLast)
+ y2++;
+#endif
+ /* get to first band that might contain part of line */
+ while ((nbox) && (pbox->y2 <= y1)) {
+ pbox++;
+ nbox--;
+ }
+
+ if (nbox) {
+ /* stop when lower edge of box is beyond end of line */
+ while ((nbox) && (y2 >= pbox->y1)) {
+ if ((x1 >= pbox->x1) && (x1 < pbox->x2)) {
+ int y1t, y2t;
+ /* this box has part of the line in it */
+ y1t = max(y1, pbox->y1);
+ y2t = min(y2, pbox->y2);
+ if (y1t != y2t)
+ ilbmVertS(addrlBase, nlwidth, auxDst, depthDst, x1, y1t,
+ y2t-y1t, rrops); /* @@@ NEXT PLANE PASSED @@@ */
+ }
+ nbox--;
+ pbox++;
+ }
+ }
+#ifndef POLYSEGMENT
+ y2 = ppt->y + yorg;
+#endif
+ } else if (y1 == y2) /* horizontal line */ {
+ /* force line from left to right, keeping
+ endpoint semantics
+ */
+ if (x1 > x2) {
+ register int tmp;
+
+ tmp = x2;
+ x2 = x1 + 1;
+ x1 = tmp + 1;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ x1--;
+#endif
+ }
+#ifdef POLYSEGMENT
+ else if (pGC->capStyle != CapNotLast)
+ x2++;
+#endif
+
+ /* find the correct band */
+ while ((nbox) && (pbox->y2 <= y1)) {
+ pbox++;
+ nbox--;
+ }
+
+ /* try to draw the line, if we haven't gone beyond it */
+ if ((nbox) && (pbox->y1 <= y1)) {
+ int tmp;
+
+ /* when we leave this band, we're done */
+ tmp = pbox->y1;
+ while ((nbox) && (pbox->y1 == tmp)) {
+ int x1t, x2t;
+
+ if (pbox->x2 <= x1) {
+ /* skip boxes until one might contain start point */
+ nbox--;
+ pbox++;
+ continue;
+ }
+
+ /* stop if left of box is beyond right of line */
+ if (pbox->x1 >= x2) {
+ nbox = 0;
+ break;
+ }
+
+ x1t = max(x1, pbox->x1);
+ x2t = min(x2, pbox->x2);
+ if (x1t != x2t)
+ ilbmHorzS(addrlBase, nlwidth, auxDst, depthDst, x1t, y1,
+ x2t-x1t, rrops); /* @@@ NEXT PLANE PASSED @@@ */
+ nbox--;
+ pbox++;
+ }
+ }
+#ifndef POLYSEGMENT
+ x2 = ppt->x + xorg;
+#endif
+ }
+ else /* sloped line */
+ {
+ CalcLineDeltas(x1, y1, x2, y2, adx, ady,
+ signdx, signdy, 1, 1, octant);
+
+ if (adx > ady) {
+ axis = X_AXIS;
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ } else {
+ axis = Y_AXIS;
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ SetYMajorOctant(octant);
+ }
+
+ FIXUP_ERROR(e, octant, bias);
+
+ /* we have bresenham parameters and two points.
+ all we have to do now is clip and draw.
+ */
+
+ while (nbox--) {
+ oc1 = 0;
+ oc2 = 0;
+ OUTCODES(oc1, x1, y1, pbox);
+ OUTCODES(oc2, x2, y2, pbox);
+ if ((oc1 | oc2) == 0) {
+ if (axis == X_AXIS)
+ len = adx;
+ else
+ len = ady;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ len++;
+#endif
+ ilbmBresS(addrlBase, nlwidth, auxDst, depthDst, signdx, signdy,
+ axis, x1, y1, e, e1, e2, len, rrops); /* @@@ NEXT PLANE PASSED @@@ */
+ break;
+ } else if (oc1 & oc2) {
+ pbox++;
+ } else {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int clipdx, clipdy;
+ int err;
+
+ if (miZeroClipLine(pbox->x1, pbox->y1, pbox->x2-1,
+ pbox->y2-1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1) {
+ pbox++;
+ continue;
+ }
+
+ if (axis == X_AXIS)
+ len = abs(new_x2 - new_x1);
+ else
+ len = abs(new_y2 - new_y1);
+#ifdef POLYSEGMENT
+ if (clip2 != 0 || pGC->capStyle != CapNotLast)
+ len++;
+#else
+ len += (clip2 != 0);
+#endif
+ if (len) {
+ /* unwind bresenham error term to first point */
+ if (clip1) {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ if (axis == X_AXIS)
+ err = e+((clipdy*e2) + ((clipdx-clipdy)*e1));
+ else
+ err = e+((clipdx*e2) + ((clipdy-clipdx)*e1));
+ }
+ else
+ err = e;
+ ilbmBresS(addrlBase, nlwidth, auxDst, depthDst, signdx,
+ signdy, axis, new_x1, new_y1, err, e1, e2, len,
+ rrops); /* @@@ NEXT PLANE PASSED @@@ */
+ }
+ pbox++;
+ }
+ } /* while (nbox--) */
+ } /* sloped line */
+ } /* while (nline--) */
+
+#ifndef POLYSEGMENT
+
+ /* paint the last point if the end style isn't CapNotLast.
+ (Assume that a projecting, butt, or round cap that is one
+ pixel wide is the same as the single pixel of the endpoint.)
+ */
+
+ if ((pGC->capStyle != CapNotLast) &&
+ ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
+ (ppt->y + yorg != pptInit->y + pDrawable->y) ||
+ (ppt == pptInit + 1))) {
+ nbox = nboxInit;
+ pbox = pboxInit;
+ while (nbox--) {
+ if ((x2 >= pbox->x1) && (y2 >= pbox->y1) && (x2 < pbox->x2) &&
+ (y2 < pbox->y2)) {
+ for (d = 0; d < depthDst; d++) {
+ addrl = ilbmScanline(addrlBase, x2, y2, auxDst);
+ addrlBase += nlwidth; /* @@@ NEXT PLANE @@@ */
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ *addrl &= rmask[x2 & PIM];
+ break;
+ case RROP_WHITE:
+ *addrl |= mask[x2 & PIM];
+ break;
+ case RROP_INVERT:
+ *addrl ^= mask[x2 & PIM];
+ break;
+ case RROP_NOP:
+ break;
+ } /* switch */
+ } /* for (d = ...) */
+ break;
+ } else
+ pbox++;
+ }
+ }
+#endif
+}
+
+/*
+ * Draw dashed 1-pixel lines.
+ */
+
+void
+#ifdef POLYSEGMENT
+ilbmSegmentSD(pDrawable, pGC, nseg, pSeg)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int nseg;
+ register xSegment *pSeg;
+#else
+ilbmLineSD(pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt; /* number of points */
+ DDXPointPtr pptInit;
+#endif
+{
+ int nboxInit;
+ register int nbox;
+ BoxPtr pboxInit;
+ register BoxPtr pbox;
+#ifndef POLYSEGMENT
+ register DDXPointPtr ppt; /* pointer to list of translated points */
+#endif
+
+ register unsigned int oc1; /* outcode of point 1 */
+ register unsigned int oc2; /* outcode of point 2 */
+
+ PixelType *addrlBase; /* address of destination pixmap */
+ PixelType *addrl;
+ int nlwidth; /* width in longwords of destination pixmap */
+ int auxDst;
+ int depthDst;
+ int xorg, yorg; /* origin of window */
+
+ int adx; /* abs values of dx and dy */
+ int ady;
+ int signdx; /* sign of dx and dy */
+ int signdy;
+ int e, e1, e2; /* bresenham error and increments */
+ int len; /* length of segment */
+ int axis; /* major axis */
+ int octant;
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ int x1, x2, y1, y2;
+ RegionPtr cclip;
+ unsigned char *rrops;
+ unsigned char bgrrops[AFB_MAX_DEPTH];
+ unsigned char *pDash;
+ int dashOffset;
+ int numInDashList;
+ int dashIndex;
+ int isDoubleDash;
+ int dashIndexTmp, dashOffsetTmp;
+ int unclippedlen;
+ int d;
+
+ cclip = pGC->pCompositeClip;
+ rrops = ((ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr))->rrops;
+ pboxInit = REGION_RECTS(cclip);
+ nboxInit = REGION_NUM_RECTS(cclip);
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
+ addrlBase);
+
+ /* compute initial dash values */
+
+ pDash = (unsigned char *) pGC->dash;
+ numInDashList = pGC->numInDashList;
+ isDoubleDash = (pGC->lineStyle == LineDoubleDash);
+ dashIndex = 0;
+ dashOffset = 0;
+ miStepDash ((int)pGC->dashOffset, &dashIndex, pDash,
+ numInDashList, &dashOffset);
+
+ if (isDoubleDash)
+ ilbmReduceRop (pGC->alu, pGC->bgPixel, pGC->planemask, pGC->depth,
+ bgrrops);
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+#ifdef POLYSEGMENT
+ while (nseg--)
+#else
+ ppt = pptInit;
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+ while (--npt)
+#endif
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+
+#ifdef POLYSEGMENT
+ x1 = pSeg->x1 + xorg;
+ y1 = pSeg->y1 + yorg;
+ x2 = pSeg->x2 + xorg;
+ y2 = pSeg->y2 + yorg;
+ pSeg++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious) {
+ xorg = x1;
+ yorg = y1;
+ }
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+#endif
+
+ CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy,
+ 1, 1, octant);
+
+ if (adx > ady) {
+ axis = X_AXIS;
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ unclippedlen = adx;
+ } else {
+ axis = Y_AXIS;
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ unclippedlen = ady;
+ SetYMajorOctant(octant);
+ }
+
+ FIXUP_ERROR(e, octant, bias);
+
+ /* we have bresenham parameters and two points.
+ all we have to do now is clip and draw.
+ */
+
+ while (nbox--) {
+ oc1 = 0;
+ oc2 = 0;
+ OUTCODES(oc1, x1, y1, pbox);
+ OUTCODES(oc2, x2, y2, pbox);
+ if ((oc1 | oc2) == 0) {
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ unclippedlen++;
+ dashIndexTmp = dashIndex;
+ dashOffsetTmp = dashOffset;
+ ilbmBresD(&dashIndexTmp, pDash, numInDashList, &dashOffsetTmp,
+ isDoubleDash, addrlBase, nlwidth, auxDst, depthDst,
+ signdx, signdy, axis, x1, y1, e, e1, e2, unclippedlen,
+ rrops, bgrrops); /* @@@ NEXT PLANE PASSED @@@ */
+ break;
+#else
+ ilbmBresD(&dashIndex, pDash, numInDashList, &dashOffset,
+ isDoubleDash, addrlBase, nlwidth, auxDst, depthDst,
+ signdx, signdy, axis, x1, y1, e, e1, e2, unclippedlen,
+ rrops, bgrrops); /* @@@ NEXT PLANE PASSED @@@ */
+ goto dontStep;
+#endif
+ } else if (oc1 & oc2) {
+ pbox++;
+ } else /* have to clip */ {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int clipdx, clipdy;
+ int err;
+
+ if (miZeroClipLine(pbox->x1, pbox->y1, pbox->x2-1, pbox->y2-1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1) {
+ pbox++;
+ continue;
+ }
+ dashIndexTmp = dashIndex;
+ dashOffsetTmp = dashOffset;
+ if (clip1) {
+ int dlen;
+
+ if (axis == X_AXIS)
+ dlen = abs(new_x1 - x1);
+ else
+ dlen = abs(new_y1 - y1);
+ miStepDash (dlen, &dashIndexTmp, pDash,
+ numInDashList, &dashOffsetTmp);
+ }
+ if (axis == X_AXIS)
+ len = abs(new_x2 - new_x1);
+ else
+ len = abs(new_y2 - new_y1);
+#ifdef POLYSEGMENT
+ if (clip2 != 0 || pGC->capStyle != CapNotLast)
+ len++;
+#else
+ len += (clip2 != 0);
+#endif
+ if (len) {
+ /* unwind bresenham error term to first point */
+ if (clip1) {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ if (axis == X_AXIS)
+ err = e+((clipdy*e2) + ((clipdx-clipdy)*e1));
+ else
+ err = e+((clipdx*e2) + ((clipdy-clipdx)*e1));
+ }
+ else
+ err = e;
+ ilbmBresD(&dashIndexTmp, pDash, numInDashList, &dashOffsetTmp,
+ isDoubleDash, addrlBase, nlwidth, auxDst, depthDst,
+ signdx, signdy, axis, new_x1, new_y1, err, e1, e2,
+ len, rrops, bgrrops); /* @@@ NEXT PLANE PASSED @@@ */
+ }
+ pbox++;
+ }
+ } /* while (nbox--) */
+#ifndef POLYSEGMENT
+ /*
+ * walk the dash list around to the next line
+ */
+ miStepDash (unclippedlen, &dashIndex, pDash,
+ numInDashList, &dashOffset);
+dontStep: ;
+#endif
+ } /* while (nline--) */
+
+#ifndef POLYSEGMENT
+ /* paint the last point if the end style isn't CapNotLast.
+ (Assume that a projecting, butt, or round cap that is one
+ pixel wide is the same as the single pixel of the endpoint.)
+ */
+
+ if ((pGC->capStyle != CapNotLast) &&
+ ((dashIndex & 1) == 0 || isDoubleDash) &&
+ ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
+ (ppt->y + yorg != pptInit->y + pDrawable->y) ||
+ (ppt == pptInit + 1))) {
+ nbox = nboxInit;
+ pbox = pboxInit;
+ while (nbox--) {
+ if ((x2 >= pbox->x1) && (y2 >= pbox->y1) && (x2 < pbox->x2) &&
+ (y2 < pbox->y2)) {
+ int rop;
+
+ for (d = 0; d < depthDst; d++) {
+ addrl = ilbmScanline(addrlBase, x2, y2, auxDst);
+ addrlBase += nlwidth; /* @@@ NEXT PLANE @@@ */
+
+ rop = rrops[d];
+ if (dashIndex & 1)
+ rop = bgrrops[d];
+
+ switch (rop) {
+ case RROP_BLACK:
+ *addrl &= rmask[x2 & PIM];
+ break;
+ case RROP_WHITE:
+ *addrl |= mask[x2 & PIM];
+ break;
+
+ case RROP_INVERT:
+ *addrl ^= mask[x2 & PIM];
+ break;
+
+ case RROP_NOP:
+ break;
+ }
+ } /* for (d = ...) */
+ break;
+ } else
+ pbox++;
+ }
+ }
+#endif
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmmisc.c b/xc/programs/Xserver/ilbm/ilbmmisc.c
new file mode 100644
index 000000000..d85346aca
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmmisc.c
@@ -0,0 +1,95 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmmisc.c,v 3.0 1996/08/18 01:53:59 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmmisc.c,v 5.4 94/04/17 20:28:27 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "misc.h"
+#include "cursor.h"
+#include "scrnintstr.h"
+
+#include "ilbm.h"
+
+/*ARGSUSED*/
+void
+ilbmQueryBestSize(class, pwidth, pheight, pScreen)
+int class;
+unsigned short *pwidth;
+unsigned short *pheight;
+ScreenPtr pScreen;
+{
+ unsigned width, test;
+
+ switch (class) {
+ case CursorShape:
+ if (*pwidth > pScreen->width)
+ *pwidth = pScreen->width;
+ if (*pheight > pScreen->height)
+ *pheight = pScreen->height;
+ break;
+ case TileShape:
+ case StippleShape:
+ width = *pwidth;
+ if (!width) break;
+ /* Return the closes power of two not less than what they gave me */
+ test = 0x80000000;
+ /* Find the highest 1 bit in the width given */
+ while (!(test & width))
+ test >>= 1;
+ /* If their number is greater than that, bump up to the next
+ * power of two */
+ if ((test - 1) & width)
+ test <<= 1;
+ *pwidth = test;
+ /* We don't care what height they use */
+ break;
+ }
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmpixmap.c b/xc/programs/Xserver/ilbm/ilbmpixmap.c
new file mode 100644
index 000000000..ab5a33f2a
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmpixmap.c
@@ -0,0 +1,289 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmpixmap.c,v 3.0 1996/08/18 01:54:01 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmpixmap.c,v 5.13 94/04/17 20:28:28 dpw Exp $ */
+
+/* pixmap management
+ written by drewry, september 1986
+
+ on a monchrome device, a pixmap is a bitmap.
+*/
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "Xmd.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "maskbits.h"
+
+#include "ilbm.h"
+#include "mi.h"
+
+#include "servermd.h"
+
+PixmapPtr
+ilbmCreatePixmap(pScreen, width, height, depth)
+ ScreenPtr pScreen;
+ int width;
+ int height;
+ int depth;
+{
+ PixmapPtr pPixmap;
+ int datasize;
+ int paddedWidth;
+
+ paddedWidth = BitmapBytePad(width);
+ datasize = height * paddedWidth * depth;
+ pPixmap = AllocatePixmap(pScreen, datasize);
+ if (!pPixmap)
+ return(NullPixmap);
+ pPixmap->drawable.type = DRAWABLE_PIXMAP;
+ pPixmap->drawable.class = 0;
+ pPixmap->drawable.pScreen = pScreen;
+ pPixmap->drawable.depth = depth;
+ pPixmap->drawable.bitsPerPixel = depth;
+ pPixmap->drawable.id = 0;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap->drawable.x = 0;
+ pPixmap->drawable.y = 0;
+ pPixmap->drawable.width = width;
+ pPixmap->drawable.height = height;
+ pPixmap->devKind = paddedWidth;
+ pPixmap->refcnt = 1;
+#ifdef PIXPRIV
+ pPixmap->devPrivate.ptr = datasize ?
+ (pointer)((char *)pPixmap + pScreen->totalPixmapSize) : NULL;
+#else
+ pPixmap->devPrivate.ptr = (pointer)(pPixmap + 1);
+#endif
+ return(pPixmap);
+}
+
+Bool
+ilbmDestroyPixmap(pPixmap)
+ PixmapPtr pPixmap;
+{
+ if (--pPixmap->refcnt)
+ return(TRUE);
+ xfree(pPixmap);
+ return(TRUE);
+}
+
+
+PixmapPtr
+ilbmCopyPixmap(pSrc)
+ register PixmapPtr pSrc;
+{
+ register PixmapPtr pDst;
+ int size;
+ ScreenPtr pScreen;
+
+ size = pSrc->drawable.height * pSrc->devKind * pSrc->drawable.depth;
+ pScreen = pSrc->drawable.pScreen;
+ pDst = (*pScreen->CreatePixmap)(pScreen, pSrc->drawable.width,
+ pSrc->drawable.height, pSrc->drawable.depth);
+ if (!pDst)
+ return(NullPixmap);
+ memmove((char *)pDst->devPrivate.ptr, (char *)pSrc->devPrivate.ptr, size);
+ return(pDst);
+}
+
+
+/* replicates a pattern to be a full 32 bits wide.
+ relies on the fact that each scnaline is longword padded.
+ doesn't do anything if pixmap is not a factor of 32 wide.
+ changes width field of pixmap if successful, so that the fast
+ XRotatePixmap code gets used if we rotate the pixmap later.
+
+ calculate number of times to repeat
+ for each scanline of pattern
+ zero out area to be filled with replicate
+ left shift and or in original as many times as needed
+*/
+void
+ilbmPadPixmap(pPixmap)
+ PixmapPtr pPixmap;
+{
+ register int width = pPixmap->drawable.width;
+ register int h;
+ register PixelType mask;
+ register PixelType *p;
+ register PixelType bits; /* real pattern bits */
+ register int i;
+ int d;
+ int rep; /* repeat count for pattern */
+
+ if (width >= PPW)
+ return;
+
+ rep = PPW/width;
+ if (rep*width != PPW)
+ return;
+
+ mask = endtab[width];
+
+ p = (PixelType *)(pPixmap->devPrivate.ptr);
+
+ for (d = 0; d < pPixmap->drawable.depth; d++) {
+ for (h = 0; h < pPixmap->drawable.height; h++) {
+ *p &= mask;
+ bits = *p;
+ for (i = 1; i < rep; i++) {
+ bits = SCRRIGHT(bits, width);
+ *p |= bits;
+ }
+ p++;
+ }
+ }
+ pPixmap->drawable.width = PPW;
+}
+
+/* Rotates pixmap pPix by w pixels to the right on the screen. Assumes that
+ * words are PPW bits wide, and that the least significant bit appears on the
+ * left.
+ */
+void
+ilbmXRotatePixmap(pPix, rw)
+ PixmapPtr pPix;
+ register int rw;
+{
+ register PixelType *pw, *pwFinal;
+ register PixelType t;
+
+ if (pPix == NullPixmap)
+ return;
+
+ pw = (PixelType *)pPix->devPrivate.ptr;
+ rw %= (int)pPix->drawable.width;
+ if (rw < 0)
+ rw += (int)pPix->drawable.width;
+ if (pPix->drawable.width == PPW) {
+ pwFinal = pw + pPix->drawable.height * pPix->drawable.depth;
+ while (pw < pwFinal) {
+ t = *pw;
+ *pw++ = SCRRIGHT(t, rw) | (SCRLEFT(t, (PPW-rw)) & endtab[rw]);
+ }
+ } else {
+ /* We no longer do this. Validate doesn't try to rotate odd-size
+ * tiles or stipples. ilbmUnnatural<tile/stipple>FS works directly off
+ * the unrotate tile/stipple in the GC
+ */
+ ErrorF("X internal error: trying to rotate odd-sized pixmap.\n");
+ }
+
+}
+
+/* Rotates pixmap pPix by h lines. Assumes that h is always less than
+ pPix->height
+ works on any width.
+ */
+void
+ilbmYRotatePixmap(pPix, rh)
+ register PixmapPtr pPix;
+ int rh;
+{
+ int nbyDown; /* bytes to move down to row 0; also offset of
+ row rh */
+ int nbyUp; /* bytes to move up to line rh; also
+ offset of first line moved down to 0 */
+ char *pbase;
+ char *ptmp;
+ int height;
+ int aux;
+
+ if (pPix == NullPixmap)
+ return;
+ height = (int) pPix->drawable.height;
+ rh %= height;
+ if (rh < 0)
+ rh += height;
+
+ aux = pPix->devKind*pPix->drawable.depth;
+ nbyDown = rh*aux;
+ nbyUp = height*aux-nbyDown;
+
+ if (!(ptmp = (char *)ALLOCATE_LOCAL(nbyUp)))
+ return;
+
+ pbase = (char *)pPix->devPrivate.ptr;
+ memmove(ptmp, pbase, nbyUp); /* save the low rows */
+ memmove(pbase, pbase+nbyUp, nbyDown); /* slide the top rows down */
+ memmove(pbase+nbyDown, ptmp, nbyUp); /* move lower rows up to row rh */
+ DEALLOCATE_LOCAL(ptmp);
+}
+
+void
+ilbmCopyRotatePixmap(psrcPix, ppdstPix, xrot, yrot)
+ register PixmapPtr psrcPix, *ppdstPix;
+ int xrot, yrot;
+{
+ register PixmapPtr pdstPix;
+
+ if ((pdstPix = *ppdstPix) && (pdstPix->devKind == psrcPix->devKind) &&
+ (pdstPix->drawable.height == psrcPix->drawable.height) &&
+ (pdstPix->drawable.depth == psrcPix->drawable.depth)) {
+ memmove((char *)pdstPix->devPrivate.ptr, (char *)psrcPix->devPrivate.ptr,
+ psrcPix->drawable.height * psrcPix->devKind *
+ psrcPix->drawable.depth);
+ pdstPix->drawable.width = psrcPix->drawable.width;
+ pdstPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ } else {
+ if (pdstPix)
+ /* FIX XBUG 6168 */
+ (*pdstPix->drawable.pScreen->DestroyPixmap)(pdstPix);
+ *ppdstPix = pdstPix = ilbmCopyPixmap(psrcPix);
+ if (!pdstPix)
+ return;
+ }
+ ilbmPadPixmap(pdstPix);
+ if (xrot)
+ ilbmXRotatePixmap(pdstPix, xrot);
+ if (yrot)
+ ilbmYRotatePixmap(pdstPix, yrot);
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmply1rct.c b/xc/programs/Xserver/ilbm/ilbmply1rct.c
new file mode 100644
index 000000000..b76a29892
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmply1rct.c
@@ -0,0 +1,299 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmply1rct.c,v 3.1 1998/03/20 21:08:03 hohndel Exp $ */
+/*
+ * $XConsortium: ilbmply1rct.c,v 1.9 94/04/17 20:28:28 dpw Exp $
+ *
+Copyright (c) 1990 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "mistruct.h"
+
+#include "ilbm.h"
+#include "maskbits.h"
+
+#if defined(mips) || defined(sparc)
+#define GetHighWord(x) (((int)(x)) >> 16)
+#else
+#define GetHighWord(x) (((int)(x)) / 65536)
+#endif
+
+#if IMAGE_BYTE_ORDER == MSBFirst
+#define intToCoord(i,x,y) (((x) = GetHighWord(i)), ((y) = (int)((short) (i))))
+#define coordToInt(x,y) (((x) << 16) | (y))
+#define intToX(i) (GetHighWord(i))
+#define intToY(i) ((int)((short) i))
+#else
+#define intToCoord(i,x,y) (((x) = (int)((short) (i))), ((y) = GetHighWord(i)))
+#define coordToInt(x,y) (((y) << 16) | (x))
+#define intToX(i) ((int)((short) (i)))
+#define intToY(i) (GetHighWord(i))
+#endif
+
+void
+ilbmFillPolygonSolid (pDrawable, pGC, shape, mode, count, ptsIn)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int shape;
+ int mode;
+ int count;
+ DDXPointPtr ptsIn;
+{
+ ilbmPrivGCPtr devPriv;
+ int nlwidth;
+ PixelType *addrl, *addr;
+ int maxy;
+ int origin;
+ register int vertex1, vertex2;
+ int c;
+ BoxPtr extents;
+ int clip;
+ int y;
+ int *vertex1p, *vertex2p;
+ int *endp;
+ int x1, x2;
+ int dx1, dx2;
+ int dy1, dy2;
+ int e1, e2;
+ int step1, step2;
+ int sign1, sign2;
+ int h;
+ int l, r;
+ PixelType mask, bits = ~((PixelType)0);
+ int nmiddle;
+ register unsigned char *rrops;
+ register int n;
+ register int d;
+ int auxDst;
+ int depthDst;
+ register PixelType *pdst;
+
+ devPriv = (ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr);
+
+ if (mode == CoordModePrevious || shape != Convex ||
+ REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
+ miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+ origin = *((int *) &pDrawable->x);
+ origin -= (origin & 0x8000) << 1;
+ extents = &pGC->pCompositeClip->extents;
+ vertex1 = *((int *) &extents->x1) - origin;
+ vertex2 = *((int *) &extents->x2) - origin - 0x00010001;
+ clip = 0;
+ y = 32767;
+ maxy = 0;
+ vertex2p = (int *) ptsIn;
+ endp = vertex2p + count;
+ while (count--) {
+ c = *vertex2p;
+ clip |= (c - vertex1) | (vertex2 - c);
+ c = intToY(c);
+ if (c < y) {
+ y = c;
+ vertex1p = vertex2p;
+ }
+ vertex2p++;
+ if (c > maxy)
+ maxy = c;
+ }
+ if (y == maxy)
+ return;
+
+ if (clip & 0x80008000) {
+ miFillPolygon (pDrawable, pGC, shape, mode, vertex2p - (int *) ptsIn, ptsIn);
+ return;
+ }
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
+ addrl);
+ rrops = devPriv->rrops;
+ addrl = ilbmScanlineDelta(addrl, y + pDrawable->y, auxDst);
+ origin = intToX(origin);
+ vertex2p = vertex1p;
+ vertex2 = vertex1 = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+#define Setup(c,x,vertex,dx,dy,e,sign,step) {\
+ x = intToX(vertex); \
+ if (dy = intToY(c) - y) { \
+ dx = intToX(c) - x; \
+ step = 0; \
+ if (dx >= 0) { \
+ e = 0; \
+ sign = 1; \
+ if (dx >= dy) {\
+ step = dx / dy; \
+ dx = dx % dy; \
+ } \
+ } else { \
+ e = 1 - dy; \
+ sign = -1; \
+ dx = -dx; \
+ if (dx >= dy) { \
+ step = - (dx / dy); \
+ dx = dx % dy; \
+ } \
+ } \
+ } \
+ x += origin; \
+ vertex = c; \
+}
+
+#define Step(x,dx,dy,e,sign,step) {\
+ x += step; \
+ if ((e += dx) > 0) { \
+ x += sign; \
+ e -= dy; \
+ } \
+}
+ for (;;) {
+ if (y == intToY(vertex1)) {
+ do {
+ if (vertex1p == (int *) ptsIn)
+ vertex1p = endp;
+ c = *--vertex1p;
+ Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1)
+ } while (y >= intToY(vertex1));
+ h = dy1;
+ } else {
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ h = intToY(vertex1) - y;
+ }
+ if (y == intToY(vertex2)) {
+ do {
+ c = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+ Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2)
+ } while (y >= intToY(vertex2));
+ if (dy2 < h)
+ h = dy2;
+ } else {
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ if ((c = (intToY(vertex2) - y)) < h)
+ h = c;
+ }
+ /* fill spans for this segment */
+ y += h;
+ for (;;) {
+ l = x1;
+ r = x2;
+ nmiddle = x2 - x1;
+ if (nmiddle < 0) {
+ nmiddle = -nmiddle;
+ l = x2;
+ r = x1;
+ }
+ c = l & PIM;
+ l -= c;
+ l = l >> PWSH;
+ addr = addrl + l;
+ if (c + nmiddle < PPW) {
+ mask = SCRRIGHT (bits,c) ^ SCRRIGHT (bits,c+nmiddle);
+ for (pdst = addr, d = 0; d < depthDst; d++, pdst += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ *pdst &= ~mask;
+ break;
+ case RROP_WHITE:
+ *pdst |= mask;
+ break;
+ case RROP_INVERT:
+ *pdst ^= mask;
+ break;
+ case RROP_NOP:
+ break;
+ }
+ }
+ } else {
+ if (c) {
+ mask = SCRRIGHT(bits, c);
+ for (pdst = addr, d = 0; d < depthDst; d++, pdst += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ *pdst &= ~mask;
+ break;
+ case RROP_WHITE:
+ *pdst |= mask;
+ break;
+ case RROP_INVERT:
+ *pdst ^= mask;
+ break;
+ case RROP_NOP:
+ break;
+ }
+ }
+ nmiddle += c - PPW;
+ addr++;
+ }
+ nmiddle >>= PWSH;
+ mask = ~SCRRIGHT(bits, r & PIM);
+
+ for (d = 0; d < depthDst; d++, addr += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ n = nmiddle;
+ pdst = addr;
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ Duff (n, *pdst++ = 0;)
+ if (mask)
+ *pdst &= ~mask;
+ break;
+ case RROP_WHITE:
+ Duff (n, *pdst++ = ~0;);
+ if (mask)
+ *pdst |= mask;
+ break;
+ case RROP_INVERT:
+ Duff (n, *pdst++ ^= ~0;);
+ if (mask)
+ *pdst ^= mask;
+ break;
+ case RROP_NOP:
+ break;
+ }
+ }
+ }
+ if (!--h)
+ break;
+ ilbmScanlineInc(addrl, auxDst);
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ }
+ if (y == maxy)
+ break;
+ ilbmScanlineInc(addrl, auxDst);
+ }
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmplygblt.c b/xc/programs/Xserver/ilbm/ilbmplygblt.c
new file mode 100644
index 000000000..a7dca5756
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmplygblt.c
@@ -0,0 +1,465 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmplygblt.c,v 3.1 1998/03/20 21:08:03 hohndel Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmimggblt.c,v 5.17 94/04/17 20:28:25 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "ilbm.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "maskbits.h"
+
+/*
+ this works for fonts with glyphs <= 32 bits wide.
+
+ the clipping calculations are done for worst-case fonts.
+we make no assumptions about the heights, widths, or bearings
+of the glyphs. if we knew that the glyphs are all the same height,
+we could clip the tops and bottoms per clipping box, rather
+than per character per clipping box. if we knew that the glyphs'
+left and right bearings were wlle-behaved, we could clip a single
+character at the start, output until the last unclipped
+character, and then clip the last one. this is all straightforward
+to determine based on max-bounds and min-bounds from the font.
+ there is some inefficiency introduced in the per-character
+clipping to make what's going on clearer.
+
+ (it is possible, for example, for a font to be defined in which the
+next-to-last character in a font would be clipped out, but the last
+one wouldn't. the code below deals with this.)
+
+*/
+
+void
+ilbmPolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ pointer pglyphBase; /* start of array of glyphs */
+{
+ ExtentInfoRec info; /* used by QueryGlyphExtents() */
+ BoxRec bbox; /* string's bounding box */
+ xRectangle backrect; /* backing rectangle to paint.
+ in the general case, NOT necessarily
+ the same as the string's bounding box
+ */
+
+ CharInfoPtr pci;
+ int xorg, yorg; /* origin of drawable in bitmap */
+ int widthDst; /* width of dst in longwords */
+
+ /* these keep track of the character origin */
+ PixelType *pdstBase;
+ /* points to longword with character origin */
+ int xchar; /* xorigin of char (mod 32) */
+
+ /* these are used for placing the glyph */
+ register int xoff; /* x offset of left edge of glyph (mod 32) */
+ register PixelType *pdst; /* pointer to current longword in dst */
+
+ register int d;
+ int depthDst;
+ int auxDst;
+ int hSave;
+ int w; /* width of glyph in bits */
+ int h; /* height of glyph */
+ int widthGlyph; /* width of glyph, in bytes */
+ unsigned char *rrops;
+ register unsigned char *pglyph;
+ /* pointer to current row of glyph */
+ unsigned char *pglyphSave;
+
+ /* used for putting down glyph */
+ register PixelType tmpSrc;
+ /* for getting bits from glyph */
+ register PixelType startmask;
+ register PixelType endmask;
+
+ register int nFirst; /* bits of glyph in current longword */
+ PixelType *pdstSave;
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+ ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, widthDst, auxDst, depthDst,
+ pdstBase);
+
+ QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info);
+
+ x += xorg;
+ y += yorg;
+
+ bbox.x1 = x + info.overallLeft;
+ bbox.x2 = x + info.overallRight;
+ bbox.y1 = y - info.overallAscent;
+ bbox.y2 = y + info.overallDescent;
+
+ rrops = ((ilbmPrivGCPtr) pGC->devPrivates[ilbmGCPrivateIndex].ptr)->rrops;
+
+ switch (RECT_IN_REGION(pGC->pScreen, pGC->pCompositeClip, &bbox)) {
+ case rgnOUT:
+ break;
+ case rgnIN:
+ pdstBase = ilbmScanlineNoBankSwitch(pdstBase, x, y, auxDst);
+ xchar = x & PIM;
+
+ while (nglyph--) {
+ pci = *ppci;
+ pglyphSave = FONTGLYPHBITS(pglyphBase, pci);
+ w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ hSave = pci->metrics.ascent + pci->metrics.descent;
+ widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
+ /* start at top scanline of glyph */
+ pdstSave = ilbmScanlineDelta(pdstBase, -pci->metrics.ascent,
+ auxDst);
+
+ /* find correct word in scanline and x offset within it
+ for left edge of glyph
+ */
+ xoff = xchar + pci->metrics.leftSideBearing;
+ if (xoff > PLST) {
+ pdstSave++;
+ xoff &= PIM;
+ } else if (xoff < 0) {
+ xoff += PPW;
+ pdstSave--;
+ }
+
+ for (d = 0; d < depthDst; d++) {
+ h = hSave;
+ pdst = pdstSave;
+ pdstSave += widthDst; /* @@@ NEXT PLANE @@@ */
+ pglyph = pglyphSave;
+
+ if ((xoff + w) <= PPW) {
+ /* glyph all in one longword */
+ maskpartialbits(xoff, w, startmask);
+ switch (rrops[d]) {
+ case RROP_WHITE:
+ while (h--) {
+ getleftbits(pglyph, w, tmpSrc);
+ *pdst |= (SCRRIGHT(tmpSrc, xoff) & startmask);
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ case RROP_BLACK:
+ while (h--) {
+ getleftbits(pglyph, w, tmpSrc);
+ *pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask);
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ case RROP_INVERT:
+ while (h--) {
+ getleftbits(pglyph, w, tmpSrc);
+ *pdst ^= (SCRRIGHT(tmpSrc, xoff) & startmask);
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ }
+ } else {
+ /* glyph crosses longword boundary */
+ maskPPWbits(xoff, w, startmask, endmask);
+ nFirst = PPW - xoff;
+ switch (rrops[d]) {
+ case RROP_WHITE:
+ while (h--) {
+ getleftbits(pglyph, w, tmpSrc);
+ *pdst |= (SCRRIGHT(tmpSrc, xoff) & startmask);
+ *(pdst+1) |= (SCRLEFT(tmpSrc, nFirst) & endmask);
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ case RROP_BLACK:
+ while (h--) {
+ getleftbits(pglyph, w, tmpSrc);
+ *pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask);
+ *(pdst+1) &= ~(SCRLEFT(tmpSrc, nFirst) & endmask);
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ case RROP_INVERT:
+ while (h--) {
+ getleftbits(pglyph, w, tmpSrc);
+ *pdst ^= (SCRRIGHT(tmpSrc, xoff) & startmask);
+ *(pdst+1) ^= (SCRLEFT(tmpSrc, nFirst) & endmask);
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ }
+ } /* glyph crosses longwords boundary */
+ } /* depth loop */
+ /* update character origin */
+ x += pci->metrics.characterWidth;
+ xchar += pci->metrics.characterWidth;
+ if (xchar > PLST) {
+ xchar -= PPW;
+ pdstBase++;
+ } else if (xchar < 0) {
+ xchar += PPW;
+ pdstBase--;
+ }
+ ppci++;
+ } /* while nglyph-- */
+ break;
+ case rgnPART:
+ {
+ ilbmTEXTPOS *ppos;
+ int nbox;
+ BoxPtr pbox;
+ RegionPtr cclip;
+ int xpos; /* x position of char origin */
+ int i;
+ BoxRec clip;
+ int leftEdge, rightEdge;
+ int topEdge, bottomEdge;
+ int glyphRow; /* first row of glyph not wholly
+ clipped out */
+ int glyphCol; /* leftmost visible column of glyph */
+ int getWidth; /* bits to get from glyph */
+
+ if (!(ppos = (ilbmTEXTPOS *)ALLOCATE_LOCAL(nglyph *
+ sizeof(ilbmTEXTPOS))))
+ return;
+
+ pdstBase = ilbmScanlineNoBankSwitch(pdstBase, x, y, auxDst);
+ xpos = x;
+ xchar = xpos & PIM;
+
+ for (i = 0; i < nglyph; i++) {
+ pci = ppci[i];
+
+ ppos[i].xpos = xpos;
+ ppos[i].xchar = xchar;
+ ppos[i].leftEdge = xpos + pci->metrics.leftSideBearing;
+ ppos[i].rightEdge = xpos + pci->metrics.rightSideBearing;
+ ppos[i].topEdge = y - pci->metrics.ascent;
+ ppos[i].bottomEdge = y + pci->metrics.descent;
+ ppos[i].pdstBase = pdstBase;
+ ppos[i].widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
+
+ xpos += pci->metrics.characterWidth;
+ xchar += pci->metrics.characterWidth;
+ if (xchar > PLST) {
+ xchar &= PIM;
+ pdstBase++;
+ } else if (xchar < 0) {
+ xchar += PPW;
+ pdstBase--;
+ }
+ }
+
+ cclip = pGC->pCompositeClip;
+ pbox = REGION_RECTS(cclip);
+ nbox = REGION_NUM_RECTS(cclip);
+
+ /* HACK ALERT
+ since we continue out of the loop below so often, it
+ is easier to increment pbox at the top than at the end.
+ don't try this at home.
+ */
+ pbox--;
+ while (nbox--) {
+ pbox++;
+ clip.x1 = max(bbox.x1, pbox->x1);
+ clip.y1 = max(bbox.y1, pbox->y1);
+ clip.x2 = min(bbox.x2, pbox->x2);
+ clip.y2 = min(bbox.y2, pbox->y2);
+ if ((clip.x2<=clip.x1) || (clip.y2<=clip.y1))
+ continue;
+
+ for (i = 0; i<nglyph; i++) {
+ pci = ppci[i];
+ xchar = ppos[i].xchar;
+
+ /* clip the left and right edges */
+ if (ppos[i].leftEdge < clip.x1)
+ leftEdge = clip.x1;
+ else
+ leftEdge = ppos[i].leftEdge;
+
+ if (ppos[i].rightEdge > clip.x2)
+ rightEdge = clip.x2;
+ else
+ rightEdge = ppos[i].rightEdge;
+
+ w = rightEdge - leftEdge;
+ if (w <= 0)
+ continue;
+
+ /* clip the top and bottom edges */
+ if (ppos[i].topEdge < clip.y1)
+ topEdge = clip.y1;
+ else
+ topEdge = ppos[i].topEdge;
+
+ if (ppos[i].bottomEdge > clip.y2)
+ bottomEdge = clip.y2;
+ else
+ bottomEdge = ppos[i].bottomEdge;
+
+ hSave = bottomEdge - topEdge;
+ if (hSave <= 0)
+ continue;
+
+ glyphRow = (topEdge - y) + pci->metrics.ascent;
+ widthGlyph = ppos[i].widthGlyph;
+ pglyphSave = FONTGLYPHBITS(pglyphBase, pci);
+ pglyphSave += (glyphRow * widthGlyph);
+
+ glyphCol = (leftEdge - ppos[i].xpos) -
+ (pci->metrics.leftSideBearing);
+ getWidth = w + glyphCol;
+
+ pdstSave = ilbmScanlineDelta(ppos[i].pdstBase, -(y-topEdge),
+ auxDst);
+ xoff = xchar + (leftEdge - ppos[i].xpos);
+ if (xoff > PLST) {
+ xoff &= PIM;
+ pdstSave++;
+ } else if (xoff < 0) {
+ xoff += PPW;
+ pdstSave--;
+ }
+
+ for (d = 0; d < depthDst; d++) {
+ h = hSave;
+ pdst = pdstSave;
+ pdstSave += widthDst; /* @@@ NEXT PLANE @@@ */
+ pglyph = pglyphSave;
+
+ if ((xoff + w) <= PPW) {
+ maskpartialbits(xoff, w, startmask);
+ switch (rrops[d]) {
+ case RROP_WHITE:
+ while (h--) {
+ getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
+ *pdst |= (SCRRIGHT(tmpSrc, xoff) & startmask);
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ case RROP_BLACK:
+ while (h--) {
+ getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
+ *pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask);
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ case RROP_INVERT:
+ while (h--) {
+ getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
+ *pdst ^= (SCRRIGHT(tmpSrc, xoff) & startmask);
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ }
+ } else {
+ maskPPWbits(xoff, w, startmask, endmask);
+ nFirst = PPW - xoff;
+ switch (rrops[d]) {
+ case RROP_WHITE:
+ while (h--) {
+ getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
+ *pdst |= (SCRRIGHT(tmpSrc, xoff) & startmask);
+ *(pdst+1) |= (SCRLEFT(tmpSrc, nFirst) & endmask);
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ case RROP_BLACK:
+ while (h--) {
+ getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
+ *pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask);
+ *(pdst+1) &= ~(SCRLEFT(tmpSrc, nFirst) & endmask);
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ case RROP_INVERT:
+ while (h--) {
+ getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
+ *pdst ^= (SCRRIGHT(tmpSrc, xoff) & startmask);
+ *(pdst+1) ^= (SCRLEFT(tmpSrc, nFirst) & endmask);
+ pglyph += widthGlyph;
+ ilbmScanlineInc(pdst, auxDst);
+ }
+ break;
+ }
+ }
+ } /* depth */
+ } /* for each glyph */
+ } /* while nbox-- */
+ DEALLOCATE_LOCAL(ppos);
+ break;
+ }
+
+ default:
+ break;
+ }
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmpntarea.c b/xc/programs/Xserver/ilbm/ilbmpntarea.c
new file mode 100644
index 000000000..0199b0bc6
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmpntarea.c
@@ -0,0 +1,652 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmpntarea.c,v 3.0 1996/08/18 01:54:04 dawes Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmpntarea.c,v 5.7 94/04/17 20:28:29 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+
+#include "windowstr.h"
+#include "regionstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+#include "ilbm.h"
+#include "maskbits.h"
+
+/*
+ the solid fillers are called for rectangles and window backgrounds.
+ the boxes are already translated.
+ maybe this should always take a pixmap instead of a drawable?
+
+ NOTE:
+ iy = ++iy < tileHeight ? iy : 0
+is equivalent to iy%= tileheight, and saves a division.
+*/
+
+/*ARGSUSED*/
+void
+ilbmSolidFillArea(pDraw, nbox, pbox, rrops)
+ DrawablePtr pDraw;
+ int nbox;
+ BoxPtr pbox;
+ register unsigned char *rrops;
+{
+ int nlwidth; /* width in longwords of the drawable */
+ int w; /* width of current box */
+ register int h; /* height of current box */
+ register PixelType *p; /* pointer to bits we're writing */
+ register int nlw; /* loop version of nlwMiddle */
+ register PixelType startmask;
+ register PixelType endmask;
+ /* masks for reggedy bits at either end of line */
+ register int nlwExtra; /* to get from right of box to left of next span */
+ int nlwMiddle; /* number of longwords between sides of boxes */
+ PixelType *pbits; /* pointer to start of drawable */
+ PixelType *saveP;
+ int saveH;
+ int depthDst;
+ int auxDst;
+ register int d;
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDraw, nlwidth, auxDst, depthDst, pbits);
+
+ while (nbox--) {
+ w = pbox->x2 - pbox->x1;
+ saveH = pbox->y2 - pbox->y1;
+
+ saveP = ilbmScanline(pbits, pbox->x1, pbox->y1, auxDst);
+
+ if ( ((pbox->x1 & PIM) + w) < PPW) {
+ for (d = 0; d < depthDst; d++) {
+ h = saveH;
+ p = saveP;
+ saveP += nlwidth; /* @@@ NEXT PLANE @@@ */
+ maskpartialbits(pbox->x1, w, startmask);
+ nlwExtra = auxDst;
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ Duff(h, *p &= ~startmask; ilbmScanlineInc(p, nlwExtra));
+ break;
+ case RROP_WHITE:
+ Duff(h, *p |= startmask; ilbmScanlineInc(p, nlwExtra));
+ break;
+ case RROP_INVERT:
+ Duff(h, *p ^= startmask; ilbmScanlineInc(p, nlwExtra));
+ break;
+ case RROP_NOP:
+ break;
+ } /* switch */
+ } /* for (d = ..) */
+ } else {
+ maskbits(pbox->x1, w, startmask, endmask, nlwMiddle);
+
+ for (d = 0; d < depthDst; d++) {
+ h = saveH;
+ p = saveP;
+ saveP += nlwidth; /* @@@ NEXT PLANE @@@ */
+ nlwExtra = auxDst - nlwMiddle;
+
+ if (startmask && endmask) {
+ nlwExtra -= 1;
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ while (h--) {
+ nlw = nlwMiddle;
+ *p &= ~startmask;
+ p++;
+ Duff(nlw, *p++ = 0);
+ *p &= ~endmask;
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_WHITE:
+ while (h--) {
+ nlw = nlwMiddle;
+ *p |= startmask;
+ p++;
+ Duff(nlw, *p++ = ~0);
+ *p |= endmask;
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_INVERT:
+ while (h--) {
+ nlw = nlwMiddle;
+ *p ^= startmask;
+ p++;
+ Duff(nlw, *p++ ^= ~0);
+ *p ^= endmask;
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_NOP:
+ break;
+ }
+ } else if (startmask && !endmask) {
+ nlwExtra -= 1;
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ while (h--) {
+ nlw = nlwMiddle;
+ *p &= ~startmask;
+ p++;
+ Duff(nlw, *p++ = 0);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_WHITE:
+ while (h--) {
+ nlw = nlwMiddle;
+ *p |= startmask;
+ p++;
+ Duff(nlw, *p++ = ~0);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_INVERT:
+ while (h--) {
+ nlw = nlwMiddle;
+ *p ^= startmask;
+ p++;
+ Duff(nlw, *p++ ^= ~0);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_NOP:
+ break;
+ }
+ } else if (!startmask && endmask) {
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ while (h--) {
+ nlw = nlwMiddle;
+ Duff(nlw, *p++ = 0);
+ *p &= ~endmask;
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_WHITE:
+ while (h--) {
+ nlw = nlwMiddle;
+ Duff(nlw, *p++ = ~0);
+ *p |= endmask;
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_INVERT:
+ while (h--) {
+ nlw = nlwMiddle;
+ Duff(nlw, *p++ ^= ~0);
+ *p ^= endmask;
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ case RROP_NOP:
+ break;
+ }
+ } else { /* no ragged bits at either end */
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ while (h--) {
+ nlw = nlwMiddle;
+ Duff(nlw, *p++ = 0);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_WHITE:
+ while (h--) {
+ nlw = nlwMiddle;
+ Duff(nlw, *p++ = ~0);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_INVERT:
+ while (h--) {
+ nlw = nlwMiddle;
+ Duff(nlw, *p++ ^= ~0);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_NOP:
+ break;
+ } /* switch */
+ }
+ } /* for (d = 0 ... ) */
+ }
+ pbox++;
+ }
+}
+
+/* stipple a list of boxes -
+
+you can use the reduced rasterop for stipples. if rrop is
+black, AND the destination with (not stipple pattern). if rrop is
+white OR the destination with the stipple pattern. if rrop is invert,
+XOR the destination with the stipple pattern.
+*/
+
+/*ARGSUSED*/
+void
+ilbmStippleAreaPPW(pDraw, nbox, pbox, pstipple, rrops)
+ DrawablePtr pDraw;
+ int nbox;
+ BoxPtr pbox;
+ PixmapPtr pstipple;
+ unsigned char *rrops;
+{
+ register PixelType *psrc; /* pointer to bits in tile, if needed */
+ int tileHeight; /* height of the tile */
+ register PixelType srcpix;
+
+ int nlwidth; /* width in longwords of the drawable */
+ int w; /* width of current box */
+ register int nlw; /* loop version of nlwMiddle */
+ register PixelType *p; /* pointer to bits we're writing */
+ register int h; /* height of current box */
+ PixelType startmask;
+ PixelType endmask; /* masks for reggedy bits at either end of line */
+ int nlwMiddle; /* number of longwords between sides of boxes */
+ int nlwExtra; /* to get from right of box to left of next span */
+ int auxDst;
+ int depthDst;
+ int d;
+ int saveIy;
+ register int iy; /* index of current scanline in tile */
+ PixelType *pbits; /* pointer to start of drawable */
+ PixelType *pBase;
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDraw, nlwidth, auxDst, depthDst, pBase);
+
+ tileHeight = pstipple->drawable.height;
+ psrc = (PixelType *)(pstipple->devPrivate.ptr);
+
+ while (nbox--) {
+ w = pbox->x2 - pbox->x1;
+ saveIy = pbox->y1 % tileHeight;
+ pbits = pBase;
+
+ if ( ((pbox->x1 & PIM) + w) < PPW) {
+ maskpartialbits(pbox->x1, w, startmask);
+ nlwExtra = auxDst;
+ for (d = 0; d < depthDst; d++) {
+ p = ilbmScanline(pbits, pbox->x1, pbox->y1, auxDst);
+ pbits += nlwidth; /* @@@ NEXT PLANE @@@ */
+ iy = saveIy;
+ h = pbox->y2 - pbox->y1;
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ while (h--) {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ *p &= ~(srcpix & startmask);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_WHITE:
+ while (h--) {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ *p |= (srcpix & startmask);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_INVERT:
+ while (h--) {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ *p ^= (srcpix & startmask);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_NOP:
+ break;
+ } /* switch */
+ } /* for (d = ...) */
+
+ } else {
+ maskbits(pbox->x1, w, startmask, endmask, nlwMiddle);
+
+ for (d = 0; d < depthDst; d++) {
+ nlwExtra = auxDst - nlwMiddle;
+ p = ilbmScanline(pbits, pbox->x1, pbox->y1, auxDst);
+ pbits += nlwidth; /* @@@ NEXT PLANE @@@ */
+ iy = saveIy;
+ h = pbox->y2 - pbox->y1;
+
+ if (startmask && endmask) {
+ nlwExtra -= 1;
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ while (h--) {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ nlw = nlwMiddle;
+ *p &= ~(srcpix & startmask);
+ p++;
+ Duff (nlw, *p++ &= ~srcpix);
+ *p &= ~(srcpix & endmask);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_WHITE:
+ while (h--) {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ nlw = nlwMiddle;
+ *p |= (srcpix & startmask);
+ p++;
+ Duff (nlw, *p++ |= srcpix);
+ *p |= (srcpix & endmask);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_INVERT:
+ while (h--) {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ nlw = nlwMiddle;
+ *p ^= (srcpix & startmask);
+ p++;
+ Duff (nlw, *p++ ^= srcpix);
+ *p ^= (srcpix & endmask);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_NOP:
+ break;
+ } /* switch */
+ } else if (startmask && !endmask) {
+ nlwExtra -= 1;
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ while (h--) {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ nlw = nlwMiddle;
+ *p &= ~(srcpix & startmask);
+ p++;
+ Duff(nlw, *p++ &= ~srcpix);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_WHITE:
+ while (h--) {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ nlw = nlwMiddle;
+ *p |= (srcpix & startmask);
+ p++;
+ Duff(nlw, *p++ |= srcpix);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_INVERT:
+ while (h--) {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ nlw = nlwMiddle;
+ *p ^= (srcpix & startmask);
+ p++;
+ Duff(nlw, *p++ ^= srcpix);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_NOP:
+ break;
+ } /* switch */
+ } else if (!startmask && endmask) {
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ while (h--) {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ nlw = nlwMiddle;
+ Duff(nlw, *p++ &= ~srcpix);
+ *p &= ~(srcpix & endmask);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_WHITE:
+ while (h--) {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ nlw = nlwMiddle;
+ Duff(nlw, *p++ |= srcpix);
+ *p |= (srcpix & endmask);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_INVERT:
+ while (h--) {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ nlw = nlwMiddle;
+ Duff(nlw, *p++ ^= srcpix);
+ *p ^= (srcpix & endmask);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_NOP:
+ break;
+ } /* switch */
+ } else { /* no ragged bits at either end */
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ while (h--) {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ nlw = nlwMiddle;
+ Duff(nlw, *p++ &= ~srcpix);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_WHITE:
+ while (h--) {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ nlw = nlwMiddle;
+ Duff(nlw, *p++ |= srcpix);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ case RROP_INVERT:
+ while (h--) {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ nlw = nlwMiddle;
+ Duff(nlw, *p++ ^= srcpix);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ break;
+ } /* switch */
+ }
+ } /* for (d = ...) */
+ }
+ pbox++;
+ }
+}
+
+void
+ilbmStippleArea(pDraw, nbox, pbox, pTile, xOff, yOff, rrops)
+ DrawablePtr pDraw;
+ int nbox;
+ BoxPtr pbox;
+ PixmapPtr pTile;
+ int xOff;
+ int yOff;
+ unsigned char *rrops;
+{
+ register PixelType *psrc; /* pointer to bits in tile, if needed */
+ int nlwidth; /* width in longwords of the drawable */
+ register int h; /* height of current box */
+ register PixelType *pdst; /* pointer to bits we're writing */
+ int auxDst;
+ int depthDst;
+ int sizeTile;
+ int tileLine;
+ int iline;
+ int w, width, x, xSrc, ySrc, srcStartOver, nend;
+ int tlwidth, rem, tileWidth, tileHeight, endinc;
+ int saveW;
+ register int rop;
+ PixelType *psrcT;
+ int d;
+ int nstart;
+ PixelType startmask;
+ PixelType endmask; /* masks for reggedy bits at either end of line */
+ int nlMiddle; /* number of longwords between sides of boxes */
+ int iy;
+ PixelType *pBase; /* pointer to start of drawable */
+ PixelType *saveP;
+ PixelType *pStartDst;
+ PixelType *pStartTile;
+ int saveH;
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDraw, nlwidth, auxDst, depthDst, pBase);
+
+ tileHeight = pTile->drawable.height;
+ tileWidth = pTile->drawable.width;
+ tlwidth = pTile->devKind/sizeof(PixelType);
+
+ xSrc = pDraw->x + ((xOff % tileWidth) - tileWidth);
+ ySrc = pDraw->y + ((yOff % tileHeight) - tileHeight);
+
+ while (nbox--) {
+ saveW = pbox->x2 - pbox->x1;
+ iline = (pbox->y1 - ySrc) % tileHeight;
+ psrcT = (PixelType *)pTile->devPrivate.ptr;
+ tileLine = iline * tlwidth;
+ saveH = pbox->y2 - pbox->y1;
+ saveP = ilbmScanline(pBase, pbox->x1, pbox->y1, auxDst);
+
+ for (d = 0; d < depthDst; d++, saveP += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ h = saveH;
+ pStartDst = saveP;
+ pStartTile = psrcT + tileLine;
+ iy = iline;
+
+ while (h--) {
+ x = pbox->x1;
+ width = saveW;
+ pdst = pStartDst;
+ rop = rrops[d];
+
+ while (width > 0) {
+ psrc = pStartTile;
+ w = min(tileWidth, width);
+ if ((rem = (x - xSrc) % tileWidth) != 0) {
+ /* if we're in the middle of the tile, get
+ as many bits as will finish the span, or
+ as many as will get to the left edge of the tile,
+ or a longword worth, starting at the appropriate
+ offset in the tile.
+ */
+ w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
+ endinc = rem / BITMAP_SCANLINE_PAD;
+ getandputrrop((psrc + endinc), (rem & PIM), (x & PIM), w,
+ pdst, rop)
+ if ((x & PIM) + w >= PPW)
+ pdst++;
+ } else if (((x & PIM) + w) < PPW) {
+ /* doing < PPW bits is easy, and worth special-casing */
+ putbitsrrop(*psrc, x & PIM, w, pdst, rop);
+ } else {
+ /* start at the left edge of the tile,
+ and put down as much as we can
+ */
+ maskbits(x, w, startmask, endmask, nlMiddle);
+
+ if (startmask)
+ nstart = PPW - (x & PIM);
+ else
+ nstart = 0;
+ if (endmask)
+ nend = (x + w) & PIM;
+ else
+ nend = 0;
+
+ srcStartOver = nstart > PLST;
+
+ if (startmask) {
+ putbitsrrop(*psrc, (x & PIM), nstart, pdst, rop);
+ pdst++;
+ if (srcStartOver)
+ psrc++;
+ }
+
+ while (nlMiddle--) {
+ getandputrrop0(psrc, nstart, PPW, pdst, rop);
+ pdst++;
+ psrc++;
+ }
+
+ if (endmask) {
+ getandputrrop0(psrc, nstart, nend, pdst, rop);
+ }
+ }
+ x += w;
+ width -= w;
+ } /* while (width > 0) */
+
+ pStartDst += auxDst;
+ if (++iy >= tileHeight) {
+ iy = 0;
+ pStartTile = psrcT;
+ } else
+ pStartTile += tlwidth;
+
+ } /* while (h) */
+ } /* for (d = ... ) */
+ pbox++;
+ } /* for each box */
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmpntwin.c b/xc/programs/Xserver/ilbm/ilbmpntwin.c
new file mode 100644
index 000000000..5cc29e331
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmpntwin.c
@@ -0,0 +1,127 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmpntwin.c,v 3.0 1996/08/18 01:54:05 dawes Exp $ */
+/* $XConsortium: ilbmpntwin.c,v 5.12 94/04/17 20:28:30 dpw Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+
+#include "windowstr.h"
+#include "regionstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+#include "ilbm.h"
+#include "maskbits.h"
+#include "mi.h"
+
+void
+ilbmPaintWindow(pWin, pRegion, what)
+ WindowPtr pWin;
+ RegionPtr pRegion;
+ int what;
+{
+ register ilbmPrivWin *pPrivWin;
+ unsigned char rrops[AFB_MAX_DEPTH];
+
+ pPrivWin = (ilbmPrivWin *)(pWin->devPrivates[ilbmWindowPrivateIndex].ptr);
+
+ switch (what) {
+ case PW_BACKGROUND:
+ switch (pWin->backgroundState) {
+ case None:
+ return;
+ case ParentRelative:
+ do {
+ pWin = pWin->parent;
+ } while (pWin->backgroundState == ParentRelative);
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
+ what);
+ return;
+ case BackgroundPixmap:
+ if (pPrivWin->fastBackground) {
+ ilbmTileAreaPPWCopy((DrawablePtr)pWin,
+ REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion), GXcopy,
+ pPrivWin->pRotatedBackground, ~0);
+ return;
+ } else {
+ ilbmTileAreaCopy((DrawablePtr)pWin, REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion), GXcopy,
+ pWin->background.pixmap, 0, 0, ~0);
+ return;
+ }
+ break;
+ case BackgroundPixel:
+ ilbmReduceRop(GXcopy, pWin->background.pixel, ~0,
+ pWin->drawable.depth, rrops);
+ ilbmSolidFillArea((DrawablePtr)pWin, REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion), rrops);
+ return;
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel) {
+ ilbmReduceRop(GXcopy, pWin->border.pixel, ~0, pWin->drawable.depth,
+ rrops);
+ ilbmSolidFillArea((DrawablePtr)pWin, REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion), rrops);
+ return;
+ } else if (pPrivWin->fastBorder) {
+ ilbmTileAreaPPWCopy((DrawablePtr)pWin, REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion), GXcopy,
+ pPrivWin->pRotatedBorder, ~0);
+ return;
+ }
+ break;
+ }
+ miPaintWindow(pWin, pRegion, what);
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmpolypnt.c b/xc/programs/Xserver/ilbm/ilbmpolypnt.c
new file mode 100644
index 000000000..f313dc8d1
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmpolypnt.c
@@ -0,0 +1,148 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmpolypnt.c,v 3.1 1998/03/20 21:08:03 hohndel Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmpolypnt.c,v 5.6 94/04/17 20:28:30 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "Xprotostr.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "miscstruct.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+
+#include "ilbm.h"
+#include "maskbits.h"
+
+void
+ilbmPolyPoint(pDrawable, pGC, mode, npt, pptInit)
+ register DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt;
+ xPoint *pptInit;
+{
+
+ register BoxPtr pbox;
+ register int nbox;
+ register int d;
+
+ register PixelType *addrl;
+ PixelType *pBase;
+ PixelType *pBaseSave;
+ int nlwidth;
+ int auxDst;
+ int depthDst;
+
+ int nptTmp;
+ register xPoint *ppt;
+
+ register int x;
+ register int y;
+ register unsigned char *rrops;
+ ilbmPrivGC *pGCPriv;
+
+ pGCPriv = (ilbmPrivGC *) pGC->devPrivates[ilbmGCPrivateIndex].ptr;
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
+ pBaseSave);
+
+ rrops = pGCPriv->rrops;
+ if ((mode == CoordModePrevious) && (npt > 1))
+ for (ppt = pptInit + 1, nptTmp = npt - 1; --nptTmp >= 0; ppt++) {
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ }
+
+ nbox = REGION_NUM_RECTS(pGC->pCompositeClip);
+ pbox = REGION_RECTS(pGC->pCompositeClip);
+ for (; --nbox >= 0; pbox++)
+ for (d = 0, pBase = pBaseSave; d < depthDst; d++, pBase += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ addrl = pBase;
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ for (ppt = pptInit, nptTmp = npt; --nptTmp >= 0; ppt++) {
+ x = ppt->x + pDrawable->x;
+ y = ppt->y + pDrawable->y;
+ if ((x >= pbox->x1) && (x < pbox->x2) &&
+ (y >= pbox->y1) && (y < pbox->y2))
+ *ilbmScanline(addrl, x, y, auxDst) &= rmask[x & PIM];
+ }
+ break;
+
+ case RROP_WHITE:
+ for (ppt = pptInit, nptTmp = npt; --nptTmp >= 0; ppt++) {
+ x = ppt->x + pDrawable->x;
+ y = ppt->y + pDrawable->y;
+ if ((x >= pbox->x1) && (x < pbox->x2) &&
+ (y >= pbox->y1) && (y < pbox->y2))
+ *ilbmScanline(addrl, x, y, auxDst) |= mask[x & PIM];
+ }
+ break;
+
+ case RROP_INVERT:
+ for (ppt = pptInit, nptTmp = npt; --nptTmp >= 0; ppt++) {
+ x = ppt->x + pDrawable->x;
+ y = ppt->y + pDrawable->y;
+ if ((x >= pbox->x1) && (x < pbox->x2) &&
+ (y >= pbox->y1) && (y < pbox->y2))
+ *ilbmScanline(addrl, x, y, auxDst) ^= mask[x & PIM];
+ }
+ break;
+
+ case RROP_NOP:
+ break;
+ } /* switch */
+ } /* for (d = ...) */
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmpushpxl.c b/xc/programs/Xserver/ilbm/ilbmpushpxl.c
new file mode 100644
index 000000000..6a045d242
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmpushpxl.c
@@ -0,0 +1,259 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmpushpxl.c,v 3.1 1998/03/20 21:08:03 hohndel Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmpushpxl.c,v 5.6 94/04/17 20:28:31 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "miscstruct.h"
+#include "maskbits.h"
+#include "regionstr.h"
+#include "ilbm.h"
+
+/* ilbmSolidPP is courtesy of xhacks@csri.toronto.edu
+
+ For fillStyle==FillSolid, a monochrome PushPixels can be reduced to
+ a ROP in the following way: (Note that the ROP is the same as the
+ result of ROP(src=0x3,dst=0x5))
+
+ src=0011 0000 0011
+ dst=0101 0101 0101
+ rop fg=0 fg=1
+ GXclear 0x0 0000 0100 0100 0
+ GXand 0x1 0001 0100 0101 s&d
+ GXandReverse 0x2 0010 0100 0110 s&~d
+ GXcopy 0x3 0011 0100 0111 s
+ GXandInverted 0x4 0100 0101 0100 ~s&d
+ GXnoop 0x5 0101 0101 0101 d
+ GXxor 0x6 0110 0101 0110 s^d
+ GXor 0x7 0111 0101 0111 s|d
+ GXnor 0x8 1000 0110 0100 ~s&~d
+ GXequiv 0x9 1001 0110 0101 ~s^d
+ GXinvert 0xa 1010 0110 0110 ~d
+ GXorReverse 0xb 1011 0110 0111 s|~d
+ GXcopyInverted 0xc 1100 0111 0100 ~s
+ GXorInverted 0xd 1101 0111 0101 ~s|d
+ GXnand 0xe 1110 0111 0110 ~s|~d
+ GXset 0xf 1111 0111 0111 1
+
+For src=0: newRop = 0x4|(rop>>2)
+For src=1: newRop = 0x4|(rop&3)
+*/
+
+/* ilbmSolidPP -- squeegees the forground color of pGC through pBitMap
+ * into pDrawable. pBitMap is a stencil (dx by dy of it is used, it may
+ * be bigger) which is placed on the drawable at xOrg, yOrg. Where a 1 bit
+ * is set in the bitmap, the fill style is put onto the drawable using
+ * the GC's logical function. The drawable is not changed where the bitmap
+ * has a zero bit or outside the area covered by the stencil.
+ */
+void
+ilbmSolidPP(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg)
+ GCPtr pGC;
+ PixmapPtr pBitMap;
+ DrawablePtr pDrawable;
+ int dx, dy, xOrg, yOrg;
+{
+ unsigned char alu;
+ RegionRec rgnDst;
+ DDXPointPtr pptSrc;
+ BoxRec srcBox;
+ register DDXPointPtr ppt;
+ register BoxPtr pbox;
+ int i;
+
+ if (!pGC->planemask & 1) return;
+
+ /* compute the reduced rop function */
+ alu = pGC->alu;
+ if (!(pGC->fgPixel&1)) alu >>= 2;
+ alu = (alu & 0x3) | 0x4;
+ if (alu == GXnoop) return;
+
+ srcBox.x1 = xOrg;
+ srcBox.y1 = yOrg;
+ srcBox.x2 = xOrg + dx;
+ srcBox.y2 = yOrg + dy;
+ REGION_INIT(pGC->pScreen, &rgnDst, &srcBox, 1);
+
+ /* clip the shape of the dst to the destination composite clip */
+ REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, pGC->pCompositeClip);
+
+ if (!REGION_NIL(&rgnDst)) {
+ i = REGION_NUM_RECTS(&rgnDst);
+ pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(i * sizeof(DDXPointRec));
+ if (pptSrc) {
+ for (pbox = REGION_RECTS(&rgnDst), ppt = pptSrc; --i >= 0;
+ pbox++, ppt++) {
+ ppt->x = pbox->x1 - xOrg;
+ ppt->y = pbox->y1 - yOrg;
+ }
+ ilbmDoBitblt((DrawablePtr)pBitMap, pDrawable, alu, &rgnDst, pptSrc,
+ pGC->planemask);
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+ }
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+}
+
+#define NPT 128
+
+/* ilbmPushPixels -- squeegees the forground color of pGC through pBitMap
+ * into pDrawable. pBitMap is a stencil (dx by dy of it is used, it may
+ * be bigger) which is placed on the drawable at xOrg, yOrg. Where a 1 bit
+ * is set in the bitmap, the fill style is put onto the drawable using
+ * the GC's logical function. The drawable is not changed where the bitmap
+ * has a zero bit or outside the area covered by the stencil.
+ */
+void
+ilbmPushPixels(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg)
+ GCPtr pGC;
+ PixmapPtr pBitMap;
+ DrawablePtr pDrawable;
+ int dx, dy, xOrg, yOrg;
+{
+ int h, dxDivPPW, ibEnd;
+ PixelType *pwLineStart;
+ register PixelType *pw, *pwEnd;
+ register PixelType mask;
+ register int ib;
+ register PixelType w;
+ register int ipt; /* index into above arrays */
+ Bool fInBox;
+ DDXPointRec pt[NPT];
+ int width[NPT];
+
+ /* Now scan convert the pixmap and use the result to call fillspans in
+ * in the drawable with the original GC */
+ ipt = 0;
+ dxDivPPW = dx/PPW;
+ for (h = 0; h < dy; h++) {
+
+ pw = (PixelType *)
+ (((char *)(pBitMap->devPrivate.ptr))+(h * pBitMap->devKind));
+ pwLineStart = pw;
+ /* Process all words which are fully in the pixmap */
+
+ fInBox = FALSE;
+ pwEnd = pwLineStart + dxDivPPW;
+ while (pw < pwEnd) {
+ w = *pw;
+ mask = endtab[1];
+ for (ib = 0; ib < PPW; ib++) {
+ if (w & mask) {
+ if (!fInBox) {
+ pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
+ pt[ipt].y = h + yOrg;
+ /* start new box */
+ fInBox = TRUE;
+ }
+ } else {
+ if (fInBox) {
+ width[ipt] = ((pw - pwLineStart) << PWSH) +
+ ib + xOrg - pt[ipt].x;
+ if (++ipt >= NPT) {
+ (*pGC->ops->FillSpans)(pDrawable, pGC, NPT, pt,
+ width, TRUE);
+ ipt = 0;
+ }
+ /* end box */
+ fInBox = FALSE;
+ }
+ }
+ mask = SCRRIGHT(mask, 1);
+ }
+ pw++;
+ }
+ ibEnd = dx & PIM;
+ if (ibEnd) {
+ /* Process final partial word on line */
+ w = *pw;
+ mask = endtab[1];
+ for (ib = 0; ib < ibEnd; ib++) {
+ if (w & mask) {
+ if (!fInBox) {
+ /* start new box */
+ pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
+ pt[ipt].y = h + yOrg;
+ fInBox = TRUE;
+ }
+ } else {
+ if (fInBox) {
+ /* end box */
+ width[ipt] = ((pw - pwLineStart) << PWSH) +
+ ib + xOrg - pt[ipt].x;
+ if (++ipt >= NPT) {
+ (*pGC->ops->FillSpans)(pDrawable, pGC, NPT, pt,
+ width, TRUE);
+ ipt = 0;
+ }
+ fInBox = FALSE;
+ }
+ }
+ mask = SCRRIGHT(mask, 1);
+ }
+ }
+ /* If scanline ended with last bit set, end the box */
+ if (fInBox) {
+ width[ipt] = dx + xOrg - pt[ipt].x;
+ if (++ipt >= NPT) {
+ (*pGC->ops->FillSpans)(pDrawable, pGC, NPT, pt, width, TRUE);
+ ipt = 0;
+ }
+ }
+ }
+ /* Flush any remaining spans */
+ if (ipt) {
+ (*pGC->ops->FillSpans)(pDrawable, pGC, ipt, pt, width, TRUE);
+ }
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmscrinit.c b/xc/programs/Xserver/ilbm/ilbmscrinit.c
new file mode 100644
index 000000000..5a6fa71a0
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmscrinit.c
@@ -0,0 +1,247 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmscrinit.c,v 3.5 1998/11/22 10:37:40 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmscrinit.c,v 5.17 94/04/17 20:28:34 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "Xproto.h" /* for xColorItem */
+#include "Xmd.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "resource.h"
+#include "colormap.h"
+#include "ilbm.h"
+#include "mistruct.h"
+#include "dix.h"
+#include "mi.h"
+#include "mibstore.h"
+#include "migc.h"
+#include "servermd.h"
+
+#ifdef PIXMAP_PER_WINDOW
+int frameWindowPrivateIndex;
+#endif
+int ilbmWindowPrivateIndex;
+int ilbmGCPrivateIndex;
+int ilbmScreenPrivateIndex;
+
+static unsigned long ilbmGeneration = 0;
+
+BSFuncRec ilbmBSFuncRec = {
+ ilbmSaveAreas,
+ ilbmRestoreAreas,
+ (BackingStoreSetClipmaskRgnProcPtr) 0,
+ (BackingStoreGetImagePixmapProcPtr) 0,
+ (BackingStoreGetSpansPixmapProcPtr) 0,
+};
+
+Bool
+ilbmCloseScreen(index, pScreen)
+ int index;
+ ScreenPtr pScreen;
+{
+ int d;
+ DepthPtr depths = pScreen->allowedDepths;
+
+ for (d = 0; d < pScreen->numDepths; d++)
+ xfree(depths[d].vids);
+ xfree(depths);
+ xfree(pScreen->visuals);
+ xfree(pScreen->devPrivates[ilbmScreenPrivateIndex].ptr);
+ return(TRUE);
+}
+
+Bool
+ilbmCreateScreenResources(pScreen)
+ ScreenPtr pScreen;
+{
+ Bool retval;
+
+ pointer oldDevPrivate = pScreen->devPrivate;
+
+ pScreen->devPrivate = pScreen->devPrivates[ilbmScreenPrivateIndex].ptr;
+ retval = miCreateScreenResources(pScreen);
+
+ /* Modify screen's pixmap devKind value stored off devPrivate to
+ * be the width of a single plane in longs rather than the width
+ * of a chunky screen in longs as incorrectly setup by the mi routine.
+ */
+ ((PixmapPtr)pScreen->devPrivate)->devKind = BitmapBytePad(pScreen->width);
+ pScreen->devPrivates[ilbmScreenPrivateIndex].ptr = pScreen->devPrivate;
+ pScreen->devPrivate = oldDevPrivate;
+ return(retval);
+}
+
+Bool
+ilbmAllocatePrivates(pScreen, pWinIndex, pGCIndex)
+ ScreenPtr pScreen;
+ int *pWinIndex, *pGCIndex;
+{
+ if (ilbmGeneration != serverGeneration) {
+#ifdef PIXMAP_PER_WINDOW
+ frameWindowPrivateIndex = AllocateWindowPrivateIndex();
+#endif
+ ilbmWindowPrivateIndex = AllocateWindowPrivateIndex();
+ ilbmGCPrivateIndex = AllocateGCPrivateIndex();
+ ilbmGeneration = serverGeneration;
+ }
+ if (pWinIndex)
+ *pWinIndex = ilbmWindowPrivateIndex;
+ if (pGCIndex)
+ *pGCIndex = ilbmGCPrivateIndex;
+
+ ilbmScreenPrivateIndex = AllocateScreenPrivateIndex();
+ pScreen->GetWindowPixmap = ilbmGetWindowPixmap;
+ pScreen->SetWindowPixmap = ilbmSetWindowPixmap;
+ return(AllocateWindowPrivate(pScreen, ilbmWindowPrivateIndex, sizeof(ilbmPrivWin)) &&
+ AllocateGCPrivate(pScreen, ilbmGCPrivateIndex, sizeof(ilbmPrivGC)));
+}
+
+/* dts * (inch/dot) * (25.4 mm / inch) = mm */
+Bool
+ilbmScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width)
+ register ScreenPtr pScreen;
+ pointer pbits; /* pointer to screen bitmap */
+ int xsize, ysize; /* in pixels */
+ int dpix, dpiy; /* dots per inch */
+ int width; /* pixel width of frame buffer */
+{
+ VisualPtr visuals;
+ DepthPtr depths;
+ int nvisuals;
+ int ndepths;
+ int rootdepth;
+ VisualID defaultVisual;
+ pointer oldDevPrivate;
+
+ rootdepth = 0;
+ if (!ilbmInitVisuals(&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
+ &defaultVisual, 256, 8)) {
+ ErrorF("ilbmInitVisuals: FALSE\n");
+ return FALSE;
+ }
+ if (!ilbmAllocatePrivates(pScreen,(int *)NULL, (int *)NULL)) {
+ ErrorF("ilbmAllocatePrivates: FALSE\n");
+ return FALSE;
+ }
+
+ pScreen->defColormap = (Colormap)FakeClientID(0);
+ /* whitePixel, blackPixel */
+ pScreen->blackPixel = 0;
+ pScreen->whitePixel = 0;
+ pScreen->QueryBestSize = ilbmQueryBestSize;
+ /* SaveScreen */
+ pScreen->GetImage = ilbmGetImage;
+ pScreen->GetSpans = ilbmGetSpans;
+ pScreen->CreateWindow = ilbmCreateWindow;
+ pScreen->DestroyWindow = ilbmDestroyWindow;
+ pScreen->PositionWindow = ilbmPositionWindow;
+ pScreen->ChangeWindowAttributes = ilbmChangeWindowAttributes;
+ pScreen->RealizeWindow = ilbmMapWindow;
+ pScreen->UnrealizeWindow = ilbmUnmapWindow;
+ pScreen->PaintWindowBackground = ilbmPaintWindow;
+ pScreen->PaintWindowBorder = ilbmPaintWindow;
+ pScreen->CopyWindow = ilbmCopyWindow;
+ pScreen->CreatePixmap = ilbmCreatePixmap;
+ pScreen->DestroyPixmap = ilbmDestroyPixmap;
+ pScreen->RealizeFont = ilbmRealizeFont;
+ pScreen->UnrealizeFont = ilbmUnrealizeFont;
+ pScreen->CreateGC = ilbmCreateGC;
+ pScreen->CreateColormap = ilbmInitializeColormap;
+ pScreen->DestroyColormap = (void (*)())NoopDDA;
+ pScreen->InstallColormap = ilbmInstallColormap;
+ pScreen->UninstallColormap = ilbmUninstallColormap;
+ pScreen->ListInstalledColormaps = ilbmListInstalledColormaps;
+ pScreen->StoreColors = (void (*)())NoopDDA;
+ pScreen->ResolveColor = ilbmResolveColor;
+ pScreen->BitmapToRegion = ilbmPixmapToRegion;
+ oldDevPrivate = pScreen->devPrivate;
+ if (!miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width, rootdepth,
+ ndepths, depths, defaultVisual, nvisuals, visuals)) {
+ ErrorF("miScreenInit: FALSE\n");
+ return FALSE;
+ }
+
+ pScreen->CloseScreen = ilbmCloseScreen;
+ pScreen->CreateScreenResources = ilbmCreateScreenResources;
+ pScreen->BackingStoreFuncs = ilbmBSFuncRec;
+
+ pScreen->devPrivates[ilbmScreenPrivateIndex].ptr = pScreen->devPrivate;
+ pScreen->devPrivate = oldDevPrivate;
+
+ return TRUE;
+}
+
+PixmapPtr
+ilbmGetWindowPixmap(pWin)
+ WindowPtr pWin;
+{
+#ifdef PIXMAP_PER_WINDOW
+ return (PixmapPtr)(pWin->devPrivates[frameWindowPrivateIndex].ptr);
+#else
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ return (* pScreen->GetScreenPixmap)(pScreen);
+#endif
+}
+
+void
+ilbmSetWindowPixmap(pWin, pPix)
+ WindowPtr pWin;
+ PixmapPtr pPix;
+{
+#ifdef PIXMAP_PER_WINDOW
+ pWin->devPrivates[frameWindowPrivateIndex].ptr = (pointer)pPix;
+#else
+ (* pWin->drawable.pScreen->SetScreenPixmap)(pPix);
+#endif
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmsetsp.c b/xc/programs/Xserver/ilbm/ilbmsetsp.c
new file mode 100644
index 000000000..a18cf53f8
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmsetsp.c
@@ -0,0 +1,265 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmsetsp.c,v 3.1 1998/03/20 21:08:04 hohndel Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmsetsp.c,v 5.8 94/04/17 20:28:34 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "Xmd.h"
+
+#include "misc.h"
+#include "regionstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+#include "ilbm.h"
+#include "maskbits.h"
+
+#include "servermd.h"
+
+
+/* ilbmSetScanline -- copies the bits from psrc to the drawable starting at
+ * (xStart, y) and continuing to (xEnd, y). xOrigin tells us where psrc
+ * starts on the scanline. (I.e., if this scanline passes through multiple
+ * boxes, we may not want to start grabbing bits at psrc but at some offset
+ * further on.)
+ */
+ilbmSetScanline(y, xOrigin, xStart, xEnd, psrc, alu, pdstBase, widthDst, auxDst,
+ depthDst, widthSrc)
+ int y;
+ int xOrigin; /* where this scanline starts */
+ int xStart; /* first bit to use from scanline */
+ int xEnd; /* last bit to use from scanline + 1 */
+ register PixelType *psrc;
+ register int alu; /* raster op */
+ PixelType *pdstBase; /* start of the drawable */
+ int widthDst; /* width of drawable in words */
+ int auxDst;
+ int depthDst;
+ int widthSrc; /* width of drawable in words */
+{
+ int w; /* width of scanline in bits */
+ register PixelType *pdst; /* where to put the bits */
+ register PixelType tmpSrc; /* scratch buffer to collect bits in */
+ int dstBit; /* offset in bits from beginning of
+ * word */
+ register int nstart; /* number of bits from first partial */
+ register int nend; /* " " last partial word */
+ int offSrc;
+ PixelType startmask, endmask;
+ PixelType *savePsrc = psrc + ((xStart - xOrigin) >> PWSH);
+ int nlMiddle, nl;
+ int d;
+
+ for (d = 0; d < depthDst; d++) {
+ pdst = ilbmScanline(pdstBase, xStart, y, auxDst) + widthDst * d; /* @@@ NEXT PLANE @@@ */
+ psrc = savePsrc + widthSrc * d; /* @@@ NEXT PLANE @@@ */
+ offSrc = (xStart - xOrigin) & PIM;
+ w = xEnd - xStart;
+ dstBit = xStart & PIM;
+
+ if (dstBit + w <= PPW) {
+ getandputrop(psrc, offSrc, dstBit, w, pdst, alu)
+ } else {
+ maskbits(xStart, w, startmask, endmask, nlMiddle);
+ if (startmask)
+ nstart = PPW - dstBit;
+ else
+ nstart = 0;
+ if (endmask)
+ nend = xEnd & PIM;
+ else
+ nend = 0;
+ if (startmask) {
+ getandputrop(psrc, offSrc, dstBit, nstart, pdst, alu)
+ pdst++;
+ offSrc += nstart;
+ if (offSrc > PLST) {
+ psrc++;
+ offSrc -= PPW;
+ }
+ }
+ nl = nlMiddle;
+ while (nl--) {
+ getbits(psrc, offSrc, PPW, tmpSrc);
+ DoRop(*pdst, alu, tmpSrc, *pdst);
+ pdst++;
+ psrc++;
+ }
+ if (endmask) {
+ getandputrop0(psrc, offSrc, nend, pdst, alu);
+ }
+ }
+ }
+}
+
+/* SetSpans -- for each span copy pwidth[i] bits from psrc to pDrawable at
+ * ppt[i] using the raster op from the GC. If fSorted is TRUE, the scanlines
+ * are in increasing Y order.
+ * Source bit lines are server scanline padded so that they always begin
+ * on a word boundary.
+ */
+void
+ilbmSetSpans(pDrawable, pGC, pcharsrc, ppt, pwidth, nspans, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ char *pcharsrc;
+ register DDXPointPtr ppt;
+ int *pwidth;
+ int nspans;
+ int fSorted;
+{
+ PixelType *psrc = (PixelType *)pcharsrc;
+ PixelType *pdstBase; /* start of dst bitmap */
+ int widthDst; /* width of bitmap in words */
+ int auxDst;
+ int depthDst;
+ int widthSrc;
+ register BoxPtr pbox, pboxLast, pboxTest;
+ register DDXPointPtr pptLast;
+ int alu;
+ RegionPtr prgnDst;
+ int xStart, xEnd;
+ int yMax;
+
+ alu = pGC->alu;
+ prgnDst = pGC->pCompositeClip;
+
+ pptLast = ppt + nspans;
+
+ yMax = pDrawable->y + (int) pDrawable->height;
+ ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, widthDst, auxDst, depthDst,
+ pdstBase);
+
+ pbox = REGION_RECTS(prgnDst);
+ pboxLast = pbox + REGION_NUM_RECTS(prgnDst);
+
+ if (fSorted) {
+ /* scan lines sorted in ascending order. Because they are sorted, we
+ * don't have to check each scanline against each clip box. We can be
+ * sure that this scanline only has to be clipped to boxes at or after the
+ * beginning of this y-band
+ */
+ pboxTest = pbox;
+ while (ppt < pptLast) {
+ pbox = pboxTest;
+ if (ppt->y >= yMax)
+ break;
+ while (pbox < pboxLast) {
+ if (pbox->y1 > ppt->y) {
+ /* scanline is before clip box */
+ break;
+ } else if (pbox->y2 <= ppt->y) {
+ /* clip box is before scanline */
+ pboxTest = ++pbox;
+ continue;
+ } else if (pbox->x1 > ppt->x + *pwidth) {
+ /* clip box is to right of scanline */
+ break;
+ } else if (pbox->x2 <= ppt->x) {
+ /* scanline is to right of clip box */
+ pbox++;
+ continue;
+ }
+
+ /* at least some of the scanline is in the current clip box */
+ xStart = max(pbox->x1, ppt->x);
+ xEnd = min(ppt->x + *pwidth, pbox->x2);
+ widthSrc = PixmapWidthInPadUnits(*pwidth, 1);
+ ilbmSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu, pdstBase,
+ widthDst, auxDst, depthDst, widthSrc);
+ if (ppt->x + *pwidth <= pbox->x2) {
+ /* End of the line, as it were */
+ break;
+ } else
+ pbox++;
+ }
+ /* We've tried this line against every box; it must be outside them
+ * all. move on to the next point */
+ ppt++;
+ psrc += widthSrc * depthDst;
+ pwidth++;
+ }
+ } else {
+ /* scan lines not sorted. We must clip each line against all the boxes */
+ while (ppt < pptLast) {
+ if (ppt->y >= 0 && ppt->y < yMax) {
+ for (pbox = REGION_RECTS(prgnDst); pbox< pboxLast; pbox++) {
+ if (pbox->y1 > ppt->y) {
+ /* rest of clip region is above this scanline,
+ * skip it */
+ break;
+ }
+ if (pbox->y2 <= ppt->y) {
+ /* clip box is below scanline */
+ pbox++;
+ break;
+ }
+ if (pbox->x1 <= ppt->x + *pwidth &&
+ pbox->x2 > ppt->x) {
+ xStart = max(pbox->x1, ppt->x);
+ xEnd = min(pbox->x2, ppt->x + *pwidth);
+ widthSrc = PixmapWidthInPadUnits(*pwidth, 1);
+ ilbmSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu,
+ pdstBase, widthDst, auxDst, depthDst,
+ widthSrc);
+ }
+
+ }
+ }
+ psrc += widthSrc * depthDst;
+ ppt++;
+ pwidth++;
+ }
+ }
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmtegblt.c b/xc/programs/Xserver/ilbm/ilbmtegblt.c
new file mode 100644
index 000000000..dc42baee9
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmtegblt.c
@@ -0,0 +1,595 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmtegblt.c,v 3.1 1998/03/20 21:08:04 hohndel Exp $ */
+/* $XConsortium: ilbmtegblt.c,v 5.14 94/04/17 20:28:35 dpw Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "ilbm.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "maskbits.h"
+
+/*
+ this works for fonts with glyphs <= PPW bits wide.
+
+ This should be called only with a terminal-emulator font;
+this means that the FIXED_METRICS flag is set, and that
+glyphbounds == charbounds.
+
+ in theory, this goes faster; even if it doesn't, it reduces the
+flicker caused by writing a string over itself with image text (since
+the background gets repainted per character instead of per string.)
+this seems to be important for some converted X10 applications.
+
+ Image text looks at the bits in the glyph and the fg and bg in the
+GC. it paints a rectangle, as defined in the protocol dcoument,
+and the paints the characters.
+
+*/
+
+#if defined(NO_3_60_CG4) && defined(FASTPUTBITS) && defined(FASTGETBITS)
+#define FASTCHARS
+#endif
+
+/*
+ * this macro "knows" that only characters <= 8 bits wide will
+ * fit this case (which is why it is independent of GLYPHPADBYTES)
+ */
+
+#if (BITMAP_BIT_ORDER == MSBFirst) && (GLYPHPADBYTES != 4)
+#if GLYPHPADBYTES == 1
+#define ShiftAmnt 24
+#else
+#define ShiftAmnt 16
+#endif
+
+/*
+ * Note: for BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER, SCRRIGHT() evaluates its
+ * first argument more than once. Thus the imbedded char++ have to be moved.
+ * (DHD)
+ */
+#if BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER
+#if PPW == 32
+#define GetBits4 c = (*char1++ << ShiftAmnt) | \
+ SCRRIGHT (*char2++ << ShiftAmnt, xoff2) | \
+ SCRRIGHT (*char3++ << ShiftAmnt, xoff3) | \
+ SCRRIGHT (*char4++ << ShiftAmnt, xoff4);
+#else /* PPW */
+#define GetBits4 c = ((unsigned long)(*char1++ << ShiftAmnt) << 32 ) | \
+ (SCRRIGHT (*char2++ << ShiftAmnt, xoff2) << 32 ) | \
+ (SCRRIGHT (*char3++ << ShiftAmnt, xoff3) << 32 ) | \
+ (SCRRIGHT (*char4++ << ShiftAmnt, xoff4) << 32 ) | \
+ (*char5++ << ShiftAmnt) | \
+ SCRRIGHT (*char6++ << ShiftAmnt, xoff6) | \
+ SCRRIGHT (*char7++ << ShiftAmnt, xoff7) | \
+ SCRRIGHT (*char8++ << ShiftAmnt, xoff8);
+#endif /* PPW */
+#else /* BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER */
+#if PPW == 32
+#define GetBits4 c = (*char1++ << ShiftAmnt) | \
+ SCRRIGHT (*char2 << ShiftAmnt, xoff2) | \
+ SCRRIGHT (*char3 << ShiftAmnt, xoff3) | \
+ SCRRIGHT (*char4 << ShiftAmnt, xoff4); \
+ char2++; char3++; char4++;
+#else /* PPW == 64 */
+#define GetBits4 c = ((unsigned long)(*char1++ << ShiftAmnt) << 32 ) | \
+ (SCRRIGHT (*char2 << ShiftAmnt, xoff2) << 32 ) | \
+ (SCRRIGHT (*char3 << ShiftAmnt, xoff3) << 32 ) | \
+ (SCRRIGHT (*char4 << ShiftAmnt, xoff4) << 32 ) | \
+ (*char5++ << ShiftAmnt) | \
+ SCRRIGHT (*char6 << ShiftAmnt, xoff6) | \
+ SCRRIGHT (*char7 << ShiftAmnt, xoff7) | \
+ SCRRIGHT (*char8 << ShiftAmnt, xoff8); \
+ char2++; char3++; char4++; char6++; char7++; char8++;
+#endif /* PPW */
+#endif /* BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER */
+
+#else /* (BITMAP_BIT_ORDER != MSBFirst) || (GLYPHPADBYTES == 4) */
+
+#if BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER
+#if PPW == 32
+#define GetBits4 c = *char1++ | \
+ SCRRIGHT (*char2++, xoff2) | \
+ SCRRIGHT (*char3++, xoff3) | \
+ SCRRIGHT (*char4++, xoff4);
+#else /* PPW == 64 */
+#define GetBits4 c = (unsigned long)(((*char1++) << 64 ) | \
+ (SCRRIGHT (*char2++, xoff2) << 64 ) | \
+ (SCRRIGHT (*char3++, xoff3) << 64 ) | \
+ (SCRRIGHT (*char4++, xoff4) << 64 ) | \
+ SCRRIGHT (*char5++, xoff5) | \
+ SCRRIGHT (*char6++, xoff6) | \
+ SCRRIGHT (*char7++, xoff7) | \
+ SCRRIGHT (*char8++, xoff8));
+#endif /* PPW */
+#else /* BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER */
+#if PPW == 32
+#define GetBits4 c = *char1++ | \
+ SCRRIGHT (*char2, xoff2) | \
+ SCRRIGHT (*char3, xoff3) | \
+ SCRRIGHT (*char4, xoff4); \
+ char2++; char3++; char4++;
+#else /* PPW == 64 */
+#define GetBits4 c = (unsigned long)(((*char1++) << 64 ) | \
+ (SCRRIGHT (*char2, xoff2) << 64 ) | \
+ (SCRRIGHT (*char3, xoff3) << 64 ) | \
+ (SCRRIGHT (*char4, xoff4) << 64 ) | \
+ SCRRIGHT (*char5, xoff5) | \
+ SCRRIGHT (*char6, xoff6) | \
+ SCRRIGHT (*char7, xoff7) | \
+ SCRRIGHT (*char8, xoff8)); \
+ char2++; char3++; char4++; \
+ char5++; char6++; char7++; char8++;
+#endif /* PPW */
+#endif /* BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER */
+
+#endif /* BITMAP_BIT_ORDER && GLYPHPADBYTES */
+
+
+#if GLYPHPADBYTES == 1
+typedef unsigned char *glyphPointer;
+#define USE_LEFTBITS
+#endif
+
+#if GLYPHPADBYTES == 2
+typedef unsigned short *glyphPointer;
+#define USE_LEFTBITS
+#endif
+
+#if GLYPHPADBYTES == 4
+typedef unsigned int *glyphPointer;
+#endif
+
+#ifdef USE_LEFTBITS
+#define GetBits1 getleftbits (char1, widthGlyph, c); \
+ c &= glyphMask; \
+ char1 = (glyphPointer) (((char *) char1) + glyphBytes);
+#else
+#define GetBits1 c = *char1++;
+#endif
+
+void
+ilbmTEGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ pointer pglyphBase; /* start of array of glyphs */
+{
+ FontPtr pfont = pGC->font;
+ int widthDst;
+ PixelType *pdstBase; /* pointer to longword with top row
+ of current glyph */
+
+ int h; /* height of glyph and char */
+ register int xpos; /* current x */
+ int ypos; /* current y */
+ int widthGlyph;
+
+ int hTmp; /* counter for height */
+ register PixelType startmask, endmask;
+ int nfirst; /* used if glyphs spans a longword boundary */
+ BoxRec bbox; /* for clipping */
+ int widthGlyphs;
+ int auxDst;
+ int depthDst;
+ PixelType *saveDst;
+ register PixelType *dst;
+ register PixelType c;
+ register int d;
+ register int xoff1, xoff2, xoff3, xoff4;
+ register glyphPointer char1, char2, char3, char4;
+ glyphPointer schar1, schar2, schar3, schar4;
+#if PPW == 64
+ register int xoff5, xoff6, xoff7, xoff8;
+ register glyphPointer char5, char6, char7, char8;
+ glyphPointer schar5, schar6, schar7, schar8;
+#endif /* PPW */
+
+ unsigned char *rrops;
+#ifdef USE_LEFTBITS
+ register PixelType glyphMask;
+ register PixelType tmpSrc;
+ register int glyphBytes;
+#endif
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, widthDst, auxDst, depthDst,
+ pdstBase);
+
+ xpos = x + pDrawable->x;
+ ypos = y + pDrawable->y;
+
+ widthGlyph = FONTMAXBOUNDS(pfont,characterWidth);
+ h = FONTASCENT(pfont) + FONTDESCENT(pfont);
+
+ xpos += FONTMAXBOUNDS(pfont,leftSideBearing);
+ ypos -= FONTASCENT(pfont);
+
+ rrops = ((ilbmPrivGCPtr) pGC->devPrivates[ilbmGCPrivateIndex].ptr)->rropOS;
+
+ bbox.x1 = xpos;
+ bbox.x2 = xpos + (widthGlyph * nglyph);
+ bbox.y1 = ypos;
+ bbox.y2 = ypos + h;
+
+ switch (RECT_IN_REGION(pGC->pScreen, pGC->pCompositeClip, &bbox)) {
+ case rgnPART:
+ /* this is the WRONG thing to do, but it works.
+ calling the non-terminal text is easy, but slow, given
+ what we know about the font.
+
+ the right thing to do is something like:
+ for each clip rectangle
+ compute at which row the glyph starts to be in it,
+ and at which row the glyph ceases to be in it
+ compute which is the first glyph inside the left
+ edge, and the last one inside the right edge
+ draw a fractional first glyph, using only
+ the rows we know are in
+ draw all the whole glyphs, using the appropriate rows
+ draw any pieces of the last glyph, using the right rows
+
+ this way, the code would take advantage of knowing that
+ all glyphs are the same height and don't overlap.
+
+ one day...
+ */
+ ilbmImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ case rgnOUT:
+ return;
+ }
+ pdstBase = ilbmScanlineDeltaNoBankSwitch(pdstBase, ypos, auxDst);
+ widthGlyphs = widthGlyph * PGSZB;
+
+#ifdef USE_LEFTBITS
+ glyphMask = endtab[widthGlyph];
+ glyphBytes = GLYPHWIDTHBYTESPADDED(*ppci);
+#endif
+
+ if (nglyph >= PGSZB && widthGlyphs <= PPW) {
+ while (nglyph >= PGSZB) {
+ nglyph -= PGSZB;
+ xoff1 = xpos & PIM;
+ xoff2 = widthGlyph;
+ xoff3 = xoff2 + widthGlyph;
+ xoff4 = xoff3 + widthGlyph;
+#if PPW == 64
+ xoff5 = xoff4 + widthGlyph;
+ xoff6 = xoff5 + widthGlyph;
+ xoff7 = xoff6 + widthGlyph;
+ xoff8 = xoff7 + widthGlyph;
+#endif /* PPW */
+ schar1 = (glyphPointer)FONTGLYPHBITS(pglyphBase,(*ppci++));
+ schar2 = (glyphPointer)FONTGLYPHBITS(pglyphBase,(*ppci++));
+ schar3 = (glyphPointer)FONTGLYPHBITS(pglyphBase,(*ppci++));
+ schar4 = (glyphPointer)FONTGLYPHBITS(pglyphBase,(*ppci++));
+#if PPW == 64
+ schar5 = (glyphPointer)FONTGLYPHBITS(pglyphBase,(*ppci++));
+ schar6 = (glyphPointer)FONTGLYPHBITS(pglyphBase,(*ppci++));
+ schar7 = (glyphPointer)FONTGLYPHBITS(pglyphBase,(*ppci++));
+ schar8 = (glyphPointer)FONTGLYPHBITS(pglyphBase,(*ppci++));
+#endif /* PPW */
+
+ hTmp = h;
+ saveDst = ilbmScanlineOffset(pdstBase, (xpos >> PWSH)); /* switch now */
+
+#ifndef FASTCHARS
+ if (xoff1 + widthGlyphs <= PPW) {
+ maskpartialbits (xoff1, widthGlyphs, startmask);
+#endif
+ for (d = 0; d < depthDst; d++) {
+ hTmp = h;
+ dst = saveDst;
+ saveDst += widthDst; /* @@@ NEXT PLANE @@@ */
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ while (hTmp--) {
+#ifdef FASTCHARS
+ FASTPUTBITS(0, xoff1, widthGlyphs, dst);
+#else
+ *(dst) &= ~startmask;
+#endif
+ ilbmScanlineInc(dst, auxDst);
+ }
+ break;
+ case RROP_WHITE:
+ while (hTmp--) {
+#ifdef FASTCHARS
+ FASTPUTBITS(~0, xoff1, widthGlyphs, dst);
+#else
+ *(dst) |= startmask;
+#endif
+ ilbmScanlineInc(dst, auxDst);
+ }
+ break;
+ case RROP_INVERT:
+ char1 = schar1;
+ char2 = schar2;
+ char3 = schar3;
+ char4 = schar4;
+ /* XXX */
+ while (hTmp--) {
+ GetBits4
+#ifdef FASTCHARS
+# if BITMAP_BIT_ORDER == MSBFirst
+ c >>= PPW - widthGlyphs;
+# endif
+ FASTPUTBITS(~c, xoff1, widthGlyphs, dst);
+#else
+ *(dst) = (*dst) & ~startmask | ~SCRRIGHT(c, xoff1) & startmask;
+#endif
+ ilbmScanlineInc(dst, auxDst);
+ }
+ break;
+ case RROP_COPY:
+ char1 = schar1;
+ char2 = schar2;
+ char3 = schar3;
+ char4 = schar4;
+
+ while (hTmp--) {
+ GetBits4
+#ifdef FASTCHARS
+# if BITMAP_BIT_ORDER == MSBFirst
+ c >>= PPW - widthGlyphs;
+#endif
+ FASTPUTBITS(c, xoff1, widthGlyphs, dst);
+#else
+ *(dst) = (*dst) & ~startmask | SCRRIGHT(c, xoff1) & startmask;
+#endif
+ ilbmScanlineInc(dst, auxDst);
+ }
+ break;
+ case RROP_NOP:
+ break;
+ } /* switch (rrops[d]) */
+ } /* for (d = ... ) */
+#ifndef FASTCHARS
+ } else {
+ maskPPWbits (xoff1, widthGlyphs, startmask, endmask);
+ nfirst = PPW - xoff1;
+ for (d = 0; d < depthDst; d++) {
+ hTmp = h;
+ dst = saveDst;
+ saveDst += widthDst; /* @@@ NEXT PLANE @@@ */
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ while (hTmp--) {
+ dst[0] &= ~startmask;
+ dst[1] &= ~endmask;
+ ilbmScanlineInc(dst, auxDst);
+ }
+ break;
+ case RROP_WHITE:
+ while (hTmp--) {
+ dst[0] |= startmask;
+ dst[1] |= endmask;
+ ilbmScanlineInc(dst, auxDst);
+ }
+ break;
+ case RROP_INVERT:
+ char1 = schar1;
+ char2 = schar2;
+ char3 = schar3;
+ char4 = schar4;
+
+ while (hTmp--) {
+ GetBits4
+ dst[0] = dst[0] & ~startmask |
+ ~SCRRIGHT(c,xoff1) & startmask;
+ dst[1] = dst[1] & ~endmask |
+ ~SCRLEFT(c,nfirst) & endmask;
+ ilbmScanlineInc(dst, auxDst);
+ }
+ break;
+ case RROP_COPY:
+ char1 = schar1;
+ char2 = schar2;
+ char3 = schar3;
+ char4 = schar4;
+
+ while (hTmp--) {
+ GetBits4
+ dst[0] = dst[0] & ~startmask |
+ SCRRIGHT(c,xoff1) & startmask;
+ dst[1] = dst[1] & ~endmask |
+ SCRLEFT(c,nfirst) & endmask;
+ ilbmScanlineInc(dst, auxDst);
+ }
+ break;
+
+ case RROP_NOP:
+ break;
+ } /* switch */
+ } /* for (d = ... ) */
+ }
+#endif
+ xpos += widthGlyphs;
+ }
+ }
+
+ while (nglyph--) {
+ xoff1 = xpos & PIM;
+ schar1 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
+ hTmp = h;
+ saveDst = ilbmScanlineOffset(pdstBase, (xpos >> PWSH));
+
+ if (xoff1 + widthGlyph <= PPW) {
+ maskpartialbits (xoff1, widthGlyph, startmask);
+
+ for (d = 0; d < depthDst; d++) {
+ hTmp = h;
+ dst = saveDst;
+ saveDst += widthDst; /* @@@ NEXT PLANE @@@ */
+ char1 = schar1;
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ while (hTmp--) {
+ (*dst) &= ~startmask;
+ ilbmScanlineInc(dst, auxDst);
+ }
+ break;
+ case RROP_WHITE:
+ while (hTmp--) {
+ (*dst) |= startmask;
+ ilbmScanlineInc(dst, auxDst);
+ }
+ break;
+ case RROP_INVERT:
+ while (hTmp--) {
+#ifdef FASTCHARS
+#ifdef USE_LEFTBITS
+ FASTGETBITS (char1,0,widthGlyph,c);
+ char1 = (glyphPointer) (((char *) char1) + glyphBytes);
+#else
+ c = *char1++;
+#if BITMAP_BIT_ORDER == MSBFirst
+ c >>= PPW - widthGlyph;
+#endif
+#endif
+ FASTPUTBITS (~c,xoff1,widthGlyph,dst);
+#else
+ GetBits1
+ (*dst) = (*dst) & ~startmask | ~SCRRIGHT(c, xoff1) & startmask;
+#endif
+ ilbmScanlineInc(dst, auxDst);
+ }
+ break;
+ case RROP_COPY:
+ while (hTmp--) {
+#ifdef FASTCHARS
+#ifdef USE_LEFTBITS
+ FASTGETBITS (char1,0,widthGlyph,c);
+ char1 = (glyphPointer) (((char *) char1) + glyphBytes);
+#else
+ c = *char1++;
+#if BITMAP_BIT_ORDER == MSBFirst
+ c >>= PPW - widthGlyph;
+#endif
+#endif
+ FASTPUTBITS (c,xoff1,widthGlyph,dst);
+#else
+ GetBits1
+ (*dst) = (*dst) & ~startmask | SCRRIGHT(c, xoff1) & startmask;
+#endif
+ ilbmScanlineInc(dst, auxDst);
+ }
+ break;
+ case RROP_NOP:
+ break;
+ } /* switch */
+ } /* for (d = ...) */
+ } else {
+ maskPPWbits (xoff1, widthGlyph, startmask, endmask);
+ nfirst = PPW - xoff1;
+
+ for (d = 0; d < depthDst; d++) {
+ hTmp = h;
+ dst = saveDst;
+ saveDst += widthDst; /* @@@ NEXT PLANE @@@ */
+ char1 = schar1;
+
+ switch (rrops[d]) {
+ case RROP_BLACK:
+ while (hTmp--) {
+ dst[0] &= ~startmask;
+ dst[1] &= ~endmask;
+ ilbmScanlineInc(dst, auxDst);
+ }
+ break;
+ case RROP_WHITE:
+ while (hTmp--) {
+ dst[0] |= startmask;
+ dst[1] |= endmask;
+ ilbmScanlineInc(dst, auxDst);
+ }
+ break;
+ case RROP_INVERT:
+ while (hTmp--) {
+ GetBits1
+ dst[0] = dst[0] & ~startmask |
+ ~SCRRIGHT(c,xoff1) & startmask;
+ dst[1] = dst[1] & ~endmask |
+ ~SCRLEFT(c,nfirst) & endmask;
+ ilbmScanlineInc(dst, auxDst);
+ }
+ break;
+ case RROP_COPY:
+ while (hTmp--) {
+ GetBits1
+ dst[0] = dst[0] & ~startmask |
+ SCRRIGHT(c,xoff1) & startmask;
+ dst[1] = dst[1] & ~endmask |
+ SCRLEFT(c,nfirst) & endmask;
+ ilbmScanlineInc(dst, auxDst);
+ }
+ break;
+ case RROP_NOP:
+ break;
+ } /* switch */
+ } /* for (d = ...) */
+ }
+
+ xpos += widthGlyph;
+ }
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmtile.c b/xc/programs/Xserver/ilbm/ilbmtile.c
new file mode 100644
index 000000000..e289144ef
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmtile.c
@@ -0,0 +1,853 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmtile.c,v 3.0 1996/08/18 01:54:12 dawes Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: ilbmtile.c,v 5.8 94/04/17 20:28:36 dpw Exp $ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+
+#include "windowstr.h"
+#include "regionstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+#include "ilbm.h"
+#include "maskbits.h"
+
+#include "mergerop.h"
+/*
+
+ the boxes are already translated.
+
+ NOTE:
+ iy = ++iy < tileHeight ? iy : 0
+is equivalent to iy%= tileheight, and saves a division.
+*/
+
+/*
+ tile area with a PPW bit wide pixmap
+*/
+void
+MROP_NAME(ilbmTileAreaPPW)(pDraw, nbox, pbox, alu, ptile, planemask)
+ DrawablePtr pDraw;
+ int nbox;
+ BoxPtr pbox;
+ int alu;
+ PixmapPtr ptile;
+ unsigned long planemask;
+{
+ register PixelType *psrc;
+ /* pointer to bits in tile, if needed */
+ int tileHeight; /* height of the tile */
+ register PixelType srcpix;
+ int nlwidth; /* width in longwords of the drawable */
+ int w; /* width of current box */
+ MROP_DECLARE_REG ()
+ register int h; /* height of current box */
+ register int nlw; /* loop version of nlwMiddle */
+ register PixelType *p; /* pointer to bits we're writing */
+ int auxDst;
+ int depthDst;
+ int tlwidth;
+ register int d;
+ PixelType startmask;
+ PixelType endmask; /* masks for reggedy bits at either end of line */
+ int nlwMiddle; /* number of longwords between sides of boxes */
+ int nlwExtra; /* to get from right of box to left of next span */
+ register int iy; /* index of current scanline in tile */
+ PixelType *pbits; /* pointer to start of drawable */
+ PixelType *saveP;
+ PixelType *pSaveSrc;
+ int saveH;
+ int saveIY;
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDraw, nlwidth, auxDst, depthDst,
+ pbits);
+
+ MROP_INITIALIZE(alu,~0)
+
+ tileHeight = ptile->drawable.height;
+ tlwidth = ptile->devKind/sizeof(PixelType);
+ pSaveSrc = (PixelType *)(ptile->devPrivate.ptr);
+
+ while (nbox--) {
+ w = pbox->x2 - pbox->x1;
+ saveH = pbox->y2 - pbox->y1;
+ saveIY = pbox->y1 % tileHeight;
+ saveP = ilbmScanline(pbits, pbox->x1, pbox->y1, auxDst);
+ psrc = pSaveSrc;
+
+ if (((pbox->x1 & PIM) + w) < PPW) {
+ maskpartialbits(pbox->x1, w, startmask);
+ nlwExtra = auxDst;
+ for (d = 0; d < depthDst; d++, saveP += nlwidth, psrc += tileHeight) { /* @@@ NEXT PLANE @@@ */
+ if (!(planemask & (1 << d)))
+ continue;
+
+ p = saveP;
+ h = saveH;
+ iy = saveIY;
+
+ while (h--) {
+ srcpix = psrc[iy];
+ iy++;
+ if (iy == tileHeight)
+ iy = 0;
+ *p = MROP_MASK(srcpix,*p,startmask);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ }
+ } else {
+ maskbits(pbox->x1, w, startmask, endmask, nlwMiddle);
+
+ for (d = 0; d < depthDst; d++, saveP += nlwidth, psrc += tileHeight) { /* @@@ NEXT PLANE @@@ */
+ if (!(planemask & (1 << d)))
+ continue;
+
+ p = saveP;
+ h = saveH;
+ iy = saveIY;
+ nlwExtra = auxDst - nlwMiddle;
+
+ if (startmask && endmask) {
+ nlwExtra -= 1;
+ while (h--) {
+ srcpix = psrc[iy];
+ iy++;
+ if (iy == tileHeight)
+ iy = 0;
+ nlw = nlwMiddle;
+ *p = MROP_MASK (srcpix,*p,startmask);
+ p++;
+ while (nlw--) {
+ *p = MROP_SOLID(srcpix,*p);
+ p++;
+ }
+
+ *p = MROP_MASK(srcpix,*p,endmask);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ } else if (startmask && !endmask) {
+ nlwExtra -= 1;
+ while (h--) {
+ srcpix = psrc[iy];
+ iy++;
+ if (iy == tileHeight)
+ iy = 0;
+ nlw = nlwMiddle;
+ *p = MROP_MASK(srcpix,*p,startmask);
+ p++;
+ while (nlw--) {
+ *p = MROP_SOLID(srcpix,*p);
+ p++;
+ }
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ } else if (!startmask && endmask) {
+ while (h--) {
+ srcpix = psrc[iy];
+ iy++;
+ if (iy == tileHeight)
+ iy = 0;
+ nlw = nlwMiddle;
+ while (nlw--) {
+ *p = MROP_SOLID(srcpix,*p);
+ p++;
+ }
+
+ *p = MROP_MASK(srcpix,*p,endmask);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ } else { /* no ragged bits at either end */
+ while (h--) {
+ srcpix = psrc[iy];
+ iy++;
+ if (iy == tileHeight)
+ iy = 0;
+ nlw = nlwMiddle;
+ while (nlw--) {
+ *p = MROP_SOLID (srcpix,*p);
+ p++;
+ }
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ }
+ } /* for (d = ...) */
+ }
+ pbox++;
+ }
+}
+
+void
+MROP_NAME(ilbmTileArea)(pDraw, nbox, pbox, alu, pTile, xOff, yOff, planemask)
+ DrawablePtr pDraw;
+ int nbox;
+ BoxPtr pbox;
+ int alu;
+ PixmapPtr pTile;
+ int xOff;
+ int yOff;
+ unsigned long planemask;
+{
+ register PixelType *psrc;
+ /* pointer to bits in tile, if needed */
+ int nlwidth; /* width in longwords of the drawable */
+ MROP_DECLARE_REG ()
+ register int h; /* height of current box */
+ register PixelType *pdst; /* pointer to bits we're writing */
+ register PixelType tmpsrc, tmpdst;
+ int auxDst;
+ int depthDst;
+ int sizeTile;
+ int tileLine;
+ int iline;
+ int w, width, x, xSrc, ySrc, srcStartOver, nend;
+ int tlwidth, rem, tileWidth, tileHeight, endinc;
+ int saveW;
+ PixelType *psrcT;
+ int d;
+ int nstart;
+ PixelType startmask;
+ PixelType endmask; /* masks for reggedy bits at either end of line */
+ int nlMiddle; /* number of longwords between sides of boxes */
+ int iy;
+ PixelType *pBase; /* pointer to start of drawable */
+ PixelType *saveP;
+ PixelType *pStartDst;
+ PixelType *pStartTile;
+ int saveH;
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDraw, nlwidth, auxDst, depthDst,
+ pBase);
+
+ MROP_INITIALIZE(alu,~0)
+
+ tileHeight = pTile->drawable.height;
+ tileWidth = pTile->drawable.width;
+ tlwidth = pTile->devKind/sizeof(PixelType);
+ sizeTile = tlwidth * tileHeight;
+
+ xSrc = pDraw->x + ((xOff % tileWidth) - tileWidth);
+ ySrc = pDraw->y + ((yOff % tileHeight) - tileHeight);
+
+ while (nbox--) {
+ saveW = pbox->x2 - pbox->x1;
+ iline = (pbox->y1 - ySrc) % tileHeight;
+ psrcT = (PixelType *) pTile->devPrivate.ptr;
+ tileLine = iline * tlwidth;
+ saveH = pbox->y2 - pbox->y1;
+ saveP = ilbmScanline(pBase, pbox->x1, pbox->y1, auxDst);
+
+ for (d = 0; d < depthDst; d++, psrcT += sizeTile, saveP += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ if (!(planemask & (1 << d)))
+ continue;
+
+ h = saveH;
+ pStartDst = saveP;
+ pStartTile = psrcT + tileLine;
+ iy = iline;
+
+ while (h--) {
+ x = pbox->x1;
+ width = saveW;
+ pdst = pStartDst;
+ while (width > 0) {
+ psrc = pStartTile;
+ w = min(tileWidth, width);
+ if ((rem = (x - xSrc) % tileWidth) != 0) {
+ /* if we're in the middle of the tile, get
+ as many bits as will finish the span, or
+ as many as will get to the left edge of the tile,
+ or a longword worth, starting at the appropriate
+ offset in the tile.
+ */
+ w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
+ endinc = rem / BITMAP_SCANLINE_PAD;
+
+ getbits ((psrc+endinc), (rem&PIM), w, tmpsrc);
+#if (MROP) != Mcopy
+ getbits (pdst, (x & PIM), w, tmpdst);
+ tmpsrc = DoMergeRop (tmpsrc, tmpdst);
+#endif
+ putbits (tmpsrc, (x & PIM), w, pdst);
+
+ if ((x & PIM) + w >= PPW)
+ pdst++;
+ } else if (((x & PIM) + w) < PPW) {
+ /* doing < PPW bits is easy, and worth special-casing */
+ tmpsrc = *psrc;
+#if (MROP) != Mcopy
+ getbits (pdst, (x & PIM), w, tmpdst);
+ tmpsrc = DoMergeRop (tmpsrc, tmpdst);
+#endif
+ putbits (tmpsrc, (x & PIM), w, pdst);
+ } else {
+ /* start at the left edge of the tile,
+ and put down as much as we can
+ */
+ maskbits(x, w, startmask, endmask, nlMiddle);
+
+ if (startmask)
+ nstart = PPW - (x & PIM);
+ else
+ nstart = 0;
+ if (endmask)
+ nend = (x + w) & PIM;
+ else
+ nend = 0;
+
+ srcStartOver = nstart > PLST;
+
+ if (startmask) {
+ tmpsrc = *psrc;
+#if (MROP) != Mcopy
+ getbits (pdst, (x & PIM), nstart, tmpdst);
+ tmpsrc = DoMergeRop (tmpsrc, tmpdst);
+#endif
+ putbits (tmpsrc, (x & PIM), nstart, pdst);
+ pdst++;
+ if (srcStartOver)
+ psrc++;
+ }
+
+ while (nlMiddle--) {
+ getbits (psrc, nstart, PPW, tmpsrc);
+#if (MROP) != Mcopy
+ tmpdst = *pdst;
+ tmpsrc = DoMergeRop (tmpsrc, tmpdst);
+#endif
+ *pdst++ = tmpsrc;
+ /*putbits (tmpsrc, 0, PPW, pdst);
+ pdst++;*/
+ psrc++;
+ }
+
+ if (endmask) {
+ getbits (psrc, nstart, nend, tmpsrc);
+#if (MROP) != Mcopy
+ tmpdst = *pdst;
+ tmpsrc = DoMergeRop (tmpsrc, tmpdst);
+#endif
+ putbits (tmpsrc, 0, nend, pdst);
+ }
+ }
+ x += w;
+ width -= w;
+ } /* while (width > 0) */
+
+ pStartDst += auxDst;
+ if (++iy >= tileHeight) {
+ iy = 0;
+ pStartTile = psrcT;
+ } else
+ pStartTile += tlwidth;
+
+ } /* while (h) */
+ } /* for (d = ... ) */
+ pbox++;
+ } /* for each box */
+}
+
+void
+MROP_NAME(ilbmOpaqueStippleAreaPPW)(pDraw, nbox, pbox, alu, ptile,
+ rropsOS, planemask)
+ DrawablePtr pDraw;
+ int nbox;
+ BoxPtr pbox;
+ int alu;
+ PixmapPtr ptile;
+ register unsigned char *rropsOS;
+ unsigned long planemask;
+{
+ register PixelType *psrc;
+ /* pointer to bits in tile, if needed */
+ int tileHeight; /* height of the tile */
+ register PixelType srcpix;
+ int nlwidth; /* width in longwords of the drawable */
+ int w; /* width of current box */
+ MROP_DECLARE_REG ()
+ register int h; /* height of current box */
+ register int nlw; /* loop version of nlwMiddle */
+ register PixelType *p; /* pointer to bits we're writing */
+ int auxDst;
+ int depthDst;
+ register int d;
+ PixelType startmask;
+ PixelType endmask; /* masks for reggedy bits at either end of line */
+ int nlwMiddle; /* number of longwords between sides of boxes */
+ int nlwExtra; /* to get from right of box to left of next span */
+ register int iy; /* index of current scanline in tile */
+ PixelType *pbits; /* pointer to start of drawable */
+ PixelType *saveP;
+ int saveH;
+ int saveIY;
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDraw, nlwidth, auxDst, depthDst,
+ pbits);
+
+ MROP_INITIALIZE(alu,~0)
+
+ tileHeight = ptile->drawable.height;
+ psrc = (PixelType *)(ptile->devPrivate.ptr);
+
+ while (nbox--) {
+ w = pbox->x2 - pbox->x1;
+ saveH = pbox->y2 - pbox->y1;
+ saveIY = pbox->y1 % tileHeight;
+ saveP = ilbmScanline(pbits, pbox->x1, pbox->y1, auxDst);
+
+ if ( ((pbox->x1 & PIM) + w) < PPW) {
+ maskpartialbits(pbox->x1, w, startmask);
+ nlwExtra = auxDst;
+ for (d = 0; d < depthDst; d++, saveP += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ if (!(planemask & (1 << d)))
+ continue;
+
+ p = saveP;
+ h = saveH;
+ iy = saveIY;
+
+ while (h--) {
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ srcpix = 0;
+ break;
+ case RROP_WHITE:
+ srcpix = ~0;
+ break;
+ case RROP_COPY:
+ srcpix = psrc[iy];
+ break;
+ case RROP_INVERT:
+ srcpix = ~psrc[iy];
+ break;
+ }
+ iy++;
+ if (iy == tileHeight)
+ iy = 0;
+ *p = MROP_MASK(srcpix,*p,startmask);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ }
+ } else {
+ maskbits(pbox->x1, w, startmask, endmask, nlwMiddle);
+
+ for (d = 0; d < depthDst; d++, saveP += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ if (!(planemask & (1 << d)))
+ continue;
+
+ p = saveP;
+ h = saveH;
+ iy = saveIY;
+ nlwExtra = auxDst - nlwMiddle;
+
+ if (startmask && endmask) {
+ nlwExtra -= 1;
+ while (h--) {
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ srcpix = 0;
+ break;
+ case RROP_WHITE:
+ srcpix = ~0;
+ break;
+ case RROP_COPY:
+ srcpix = psrc[iy];
+ break;
+ case RROP_INVERT:
+ srcpix = ~psrc[iy];
+ break;
+ }
+ iy++;
+ if (iy == tileHeight)
+ iy = 0;
+ nlw = nlwMiddle;
+ *p = MROP_MASK (srcpix,*p,startmask);
+ p++;
+ while (nlw--) {
+ *p = MROP_SOLID(srcpix,*p);
+ p++;
+ }
+
+ *p = MROP_MASK(srcpix,*p,endmask);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ } else if (startmask && !endmask) {
+ nlwExtra -= 1;
+ while (h--) {
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ srcpix = 0;
+ break;
+ case RROP_WHITE:
+ srcpix = ~0;
+ break;
+ case RROP_COPY:
+ srcpix = psrc[iy];
+ break;
+ case RROP_INVERT:
+ srcpix = ~psrc[iy];
+ break;
+ }
+ iy++;
+ if (iy == tileHeight)
+ iy = 0;
+ nlw = nlwMiddle;
+ *p = MROP_MASK(srcpix,*p,startmask);
+ p++;
+ while (nlw--) {
+ *p = MROP_SOLID(srcpix,*p);
+ p++;
+ }
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ } else if (!startmask && endmask) {
+ while (h--) {
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ srcpix = 0;
+ break;
+ case RROP_WHITE:
+ srcpix = ~0;
+ break;
+ case RROP_COPY:
+ srcpix = psrc[iy];
+ break;
+ case RROP_INVERT:
+ srcpix = ~psrc[iy];
+ break;
+ }
+ iy++;
+ if (iy == tileHeight)
+ iy = 0;
+ nlw = nlwMiddle;
+ while (nlw--) {
+ *p = MROP_SOLID(srcpix,*p);
+ p++;
+ }
+
+ *p = MROP_MASK(srcpix,*p,endmask);
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ } else { /* no ragged bits at either end */
+ while (h--) {
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ srcpix = 0;
+ break;
+ case RROP_WHITE:
+ srcpix = ~0;
+ break;
+ case RROP_COPY:
+ srcpix = psrc[iy];
+ break;
+ case RROP_INVERT:
+ srcpix = ~psrc[iy];
+ break;
+ }
+ iy++;
+ if (iy == tileHeight)
+ iy = 0;
+ nlw = nlwMiddle;
+ while (nlw--) {
+ *p = MROP_SOLID (srcpix,*p);
+ p++;
+ }
+ ilbmScanlineInc(p, nlwExtra);
+ }
+ }
+ } /* for (d = ...) */
+ }
+ pbox++;
+ }
+}
+
+void
+MROP_NAME(ilbmOpaqueStippleArea)(pDraw, nbox, pbox, alu, pTile, xOff, yOff,
+ rropsOS, planemask)
+ DrawablePtr pDraw;
+ int nbox;
+ BoxPtr pbox;
+ int alu;
+ PixmapPtr pTile;
+ int xOff;
+ int yOff;
+ register unsigned char *rropsOS;
+ unsigned long planemask;
+{
+ register PixelType *psrc;
+ /* pointer to bits in tile, if needed */
+ int nlwidth; /* width in longwords of the drawable */
+ MROP_DECLARE_REG ()
+ register int h; /* height of current box */
+ register PixelType *pdst; /* pointer to bits we're writing */
+ register PixelType tmpsrc, tmpdst;
+ int auxDst;
+ int depthDst;
+ int tileLine;
+ int iline;
+ int w, width, x, xSrc, ySrc, srcStartOver, nend;
+ int tlwidth, rem, tileWidth, tileHeight, endinc;
+ int saveW;
+ PixelType *psrcT;
+ int d;
+ int nstart;
+ PixelType startmask;
+ PixelType endmask; /* masks for reggedy bits at either end of line */
+ int nlMiddle; /* number of longwords between sides of boxes */
+ int iy;
+ PixelType *pBase; /* pointer to start of drawable */
+ PixelType *saveP;
+ PixelType *pStartDst;
+ PixelType *pStartTile;
+ int saveH;
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDraw, nlwidth, auxDst, depthDst,
+ pBase);
+
+ MROP_INITIALIZE(alu,~0)
+
+ tileHeight = pTile->drawable.height;
+ tileWidth = pTile->drawable.width;
+ tlwidth = pTile->devKind/sizeof(PixelType);
+
+ xSrc = pDraw->x + ((xOff % tileWidth) - tileWidth);
+ ySrc = pDraw->y + ((yOff % tileHeight) - tileHeight);
+
+ while (nbox--) {
+ saveW = pbox->x2 - pbox->x1;
+ iline = (pbox->y1 - ySrc) % tileHeight;
+ psrcT = (PixelType *) pTile->devPrivate.ptr;
+ tileLine = iline * tlwidth;
+ saveH = pbox->y2 - pbox->y1;
+ saveP = ilbmScanline(pBase, pbox->x1, pbox->y1, auxDst);
+
+ for (d = 0; d < depthDst; d++, saveP += nlwidth) { /* @@@ NEXT PLANE @@@ */
+ if (!(planemask & (1 << d)))
+ continue;
+
+ h = saveH;
+ pStartDst = saveP;
+ pStartTile = psrcT + tileLine;
+ iy = iline;
+
+ while (h--) {
+ x = pbox->x1;
+ width = saveW;
+ pdst = pStartDst;
+ while (width > 0) {
+ psrc = pStartTile;
+ w = min(tileWidth, width);
+ if ((rem = (x - xSrc) % tileWidth) != 0) {
+ /* if we're in the middle of the tile, get
+ as many bits as will finish the span, or
+ as many as will get to the left edge of the tile,
+ or a longword worth, starting at the appropriate
+ offset in the tile.
+ */
+ w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
+ endinc = rem / BITMAP_SCANLINE_PAD;
+
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ tmpsrc = 0;
+ break;
+ case RROP_WHITE:
+ tmpsrc = ~0;
+ break;
+
+ case RROP_COPY:
+ getbits ((psrc+endinc), (rem&PIM), w, tmpsrc);
+ break;
+
+ case RROP_INVERT:
+ getbits ((psrc+endinc), (rem&PIM), w, tmpsrc);
+ tmpsrc = ~tmpsrc;
+ break;
+ }
+#if (MROP) != Mcopy
+ getbits (pdst, (x & PIM), w, tmpdst);
+ tmpsrc = DoMergeRop (tmpsrc, tmpdst);
+#endif
+ putbits (tmpsrc, (x & PIM), w, pdst);
+
+ if ((x & PIM) + w >= PPW)
+ pdst++;
+ } else if (((x & PIM) + w) < PPW) {
+ /* doing < PPW bits is easy, and worth special-casing */
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ tmpsrc = 0;
+ break;
+ case RROP_WHITE:
+ tmpsrc = ~0;
+ break;
+ case RROP_COPY:
+ tmpsrc = *psrc;
+ break;
+ case RROP_INVERT:
+ tmpsrc = ~*psrc;
+ break;
+ }
+#if (MROP) != Mcopy
+ getbits (pdst, (x & PIM), w, tmpdst);
+ tmpsrc = DoMergeRop (tmpsrc, tmpdst);
+#endif
+ putbits (tmpsrc, (x & PIM), w, pdst);
+ } else {
+ /* start at the left edge of the tile,
+ and put down as much as we can
+ */
+ maskbits(x, w, startmask, endmask, nlMiddle);
+
+ if (startmask)
+ nstart = PPW - (x & PIM);
+ else
+ nstart = 0;
+ if (endmask)
+ nend = (x + w) & PIM;
+ else
+ nend = 0;
+
+ srcStartOver = nstart > PLST;
+
+ if (startmask) {
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ tmpsrc = 0;
+ break;
+ case RROP_WHITE:
+ tmpsrc = ~0;
+ break;
+ case RROP_COPY:
+ tmpsrc = *psrc;
+ break;
+ case RROP_INVERT:
+ tmpsrc = ~*psrc;
+ break;
+ }
+#if (MROP) != Mcopy
+ getbits (pdst, (x & PIM), nstart, tmpdst);
+ tmpsrc = DoMergeRop (tmpsrc, tmpdst);
+#endif
+ putbits (tmpsrc, (x & PIM), nstart, pdst);
+ pdst++;
+ if (srcStartOver)
+ psrc++;
+ }
+
+ while (nlMiddle--) {
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ tmpsrc = 0;
+ break;
+ case RROP_WHITE:
+ tmpsrc = ~0;
+ break;
+ case RROP_COPY:
+ getbits (psrc, nstart, PPW, tmpsrc);
+ break;
+ case RROP_INVERT:
+ getbits (psrc, nstart, PPW, tmpsrc);
+ tmpsrc = ~tmpsrc;
+ break;
+ }
+#if (MROP) != Mcopy
+ tmpdst = *pdst;
+ tmpsrc = DoMergeRop (tmpsrc, tmpdst);
+#endif
+ *pdst++ = tmpsrc;
+ /*putbits (tmpsrc, 0, PPW, pdst);
+ pdst++; */
+ psrc++;
+ }
+
+ if (endmask) {
+ switch (rropsOS[d]) {
+ case RROP_BLACK:
+ tmpsrc = 0;
+ break;
+ case RROP_WHITE:
+ tmpsrc = ~0;
+ break;
+
+ case RROP_COPY:
+ getbits (psrc, nstart, nend, tmpsrc);
+ break;
+
+ case RROP_INVERT:
+ getbits (psrc, nstart, nend, tmpsrc);
+ tmpsrc = ~tmpsrc;
+ break;
+ }
+#if (MROP) != Mcopy
+ tmpdst = *pdst;
+ tmpsrc = DoMergeRop (tmpsrc, tmpdst);
+#endif
+ putbits (tmpsrc, 0, nend, pdst);
+ }
+ }
+ x += w;
+ width -= w;
+ } /* while (width > 0) */
+
+ pStartDst += auxDst;
+ if (++iy >= tileHeight) {
+ iy = 0;
+ pStartTile = psrcT;
+ } else
+ pStartTile += tlwidth;
+
+ } /* while (h) */
+ } /* for (d = ... ) */
+ pbox++;
+ } /* for each box */
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmwindow.c b/xc/programs/Xserver/ilbm/ilbmwindow.c
new file mode 100644
index 000000000..524972944
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmwindow.c
@@ -0,0 +1,319 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmwindow.c,v 3.0 1996/08/18 01:54:14 dawes Exp $ */
+/* $XConsortium: ilbmwindow.c,v 5.14 94/04/17 20:28:36 dpw Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "ilbm.h"
+#include "mistruct.h"
+#include "regionstr.h"
+#include "maskbits.h"
+
+extern WindowPtr *WindowTable;
+
+Bool
+ilbmCreateWindow(pWin)
+ register WindowPtr pWin;
+{
+ register ilbmPrivWin *pPrivWin;
+
+ pPrivWin = (ilbmPrivWin *)(pWin->devPrivates[ilbmWindowPrivateIndex].ptr);
+ pPrivWin->pRotatedBorder = NullPixmap;
+ pPrivWin->pRotatedBackground = NullPixmap;
+ pPrivWin->fastBackground = FALSE;
+ pPrivWin->fastBorder = FALSE;
+#ifdef PIXMAP_PER_WINDOW
+ pWin->devPrivates[frameWindowPrivateIndex].ptr =
+ pWin->pDrawable.pScreen->devPrivates[ilbmScreenPrivateIndex].ptr;
+#endif
+
+ return (TRUE);
+}
+
+/* This always returns true, because Xfree can't fail. It might be possible
+ * on some devices for Destroy to fail */
+Bool
+ilbmDestroyWindow(pWin)
+ WindowPtr pWin;
+{
+ register ilbmPrivWin *pPrivWin;
+
+ pPrivWin = (ilbmPrivWin *)(pWin->devPrivates[ilbmWindowPrivateIndex].ptr);
+
+ if (pPrivWin->pRotatedBorder)
+ (*pWin->drawable.pScreen->DestroyPixmap)(pPrivWin->pRotatedBorder);
+ if (pPrivWin->pRotatedBackground)
+ (*pWin->drawable.pScreen->DestroyPixmap)(pPrivWin->pRotatedBackground);
+
+ return (TRUE);
+}
+
+/*ARGSUSED*/
+Bool
+ilbmMapWindow(pWindow)
+ WindowPtr pWindow;
+{
+ return (TRUE);
+}
+
+/* (x, y) is the upper left corner of the window on the screen
+ do we really need to pass this? (is it a;ready in pWin->absCorner?)
+ we only do the rotation for pixmaps that are 32 bits wide (padded
+or otherwise.)
+ ilbmChangeWindowAttributes() has already put a copy of the pixmap
+in pPrivWin->pRotated*
+*/
+
+/*ARGSUSED*/
+Bool
+ilbmPositionWindow(pWin, x, y)
+ WindowPtr pWin;
+ int x, y;
+{
+ register ilbmPrivWin *pPrivWin;
+ int reset = 0;
+
+ pPrivWin = (ilbmPrivWin *)(pWin->devPrivates[ilbmWindowPrivateIndex].ptr);
+ if (pWin->backgroundState == BackgroundPixmap && pPrivWin->fastBackground) {
+ ilbmXRotatePixmap(pPrivWin->pRotatedBackground,
+ pWin->drawable.x - pPrivWin->oldRotate.x);
+ ilbmYRotatePixmap(pPrivWin->pRotatedBackground,
+ pWin->drawable.y - pPrivWin->oldRotate.y);
+ reset = 1;
+ }
+
+ if (!pWin->borderIsPixel && pPrivWin->fastBorder) {
+ while (pWin->backgroundState == ParentRelative)
+ pWin = pWin->parent;
+ ilbmXRotatePixmap(pPrivWin->pRotatedBorder,
+ pWin->drawable.x - pPrivWin->oldRotate.x);
+ ilbmYRotatePixmap(pPrivWin->pRotatedBorder,
+ pWin->drawable.y - pPrivWin->oldRotate.y);
+ reset = 1;
+ }
+ if (reset) {
+ pPrivWin->oldRotate.x = pWin->drawable.x;
+ pPrivWin->oldRotate.y = pWin->drawable.y;
+ }
+
+ /* This is the "wrong" fix to the right problem, but it doesn't really
+ * cost very much. When the window is moved, we need to invalidate any
+ * RotatedPixmap that exists in any GC currently validated against this
+ * window.
+ */
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ /* Again, we have no failure modes indicated by any of the routines
+ * we've called, so we have to assume it worked */
+ return (TRUE);
+}
+
+/*ARGSUSED*/
+Bool
+ilbmUnmapWindow(pWindow)
+ WindowPtr pWindow;
+{
+ return (TRUE);
+}
+
+/* UNCLEAN!
+ this code calls the bitblt helper code directly.
+
+ ilbmCopyWindow copies only the parts of the destination that are
+visible in the source.
+*/
+
+
+void
+ilbmCopyWindow(pWin, ptOldOrg, prgnSrc)
+ WindowPtr pWin;
+ DDXPointRec ptOldOrg;
+ RegionPtr prgnSrc;
+{
+ DDXPointPtr pptSrc;
+ register DDXPointPtr ppt;
+ RegionPtr prgnDst;
+ register BoxPtr pbox;
+ register int dx, dy;
+ register int i, nbox;
+ WindowPtr pwinRoot;
+
+ pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];
+
+ prgnDst = REGION_CREATE(pWin->drawable.pScreen, NULL, 1);
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
+ REGION_INTERSECT(pWin->drawable.pScreen, prgnDst, &pWin->borderClip,
+ prgnSrc);
+
+ pbox = REGION_RECTS(prgnDst);
+ nbox = REGION_NUM_RECTS(prgnDst);
+ if (!(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec))))
+ return;
+ ppt = pptSrc;
+
+ for (i=nbox; --i >= 0; ppt++, pbox++) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ ilbmDoBitblt((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot, GXcopy, prgnDst,
+ pptSrc, ~0);
+ DEALLOCATE_LOCAL(pptSrc);
+ REGION_DESTROY(pWin->drawable.pScreen, prgnDst);
+}
+
+
+
+/* swap in correct PaintWindow* routine. If we can use a fast output
+routine (i.e. the pixmap is paddable to 32 bits), also pre-rotate a copy
+of it in devPrivate.
+*/
+Bool
+ilbmChangeWindowAttributes(pWin, mask)
+ register WindowPtr pWin;
+ register unsigned long mask;
+{
+ register unsigned long index;
+ register ilbmPrivWin *pPrivWin;
+ WindowPtr pBgWin;
+
+ pPrivWin = (ilbmPrivWin *)(pWin->devPrivates[ilbmWindowPrivateIndex].ptr);
+ /*
+ * When background state changes from ParentRelative and
+ * we had previously rotated the fast border pixmap to match
+ * the parent relative origin, rerotate to match window
+ */
+ if (mask & (CWBackPixmap | CWBackPixel) &&
+ pWin->backgroundState != ParentRelative && pPrivWin->fastBorder &&
+ (pPrivWin->oldRotate.x != pWin->drawable.x ||
+ pPrivWin->oldRotate.y != pWin->drawable.y)) {
+ ilbmXRotatePixmap(pPrivWin->pRotatedBorder,
+ pWin->drawable.x - pPrivWin->oldRotate.x);
+ ilbmYRotatePixmap(pPrivWin->pRotatedBorder,
+ pWin->drawable.y - pPrivWin->oldRotate.y);
+ pPrivWin->oldRotate.x = pWin->drawable.x;
+ pPrivWin->oldRotate.y = pWin->drawable.y;
+ }
+ while (mask) {
+ index = lowbit (mask);
+ mask &= ~index;
+ switch (index) {
+ case CWBackPixmap:
+ if (pWin->backgroundState == None)
+ pPrivWin->fastBackground = FALSE;
+ else if (pWin->backgroundState == ParentRelative) {
+ pPrivWin->fastBackground = FALSE;
+ /* Rotate border to match parent origin */
+ if (pPrivWin->pRotatedBorder) {
+ for (pBgWin = pWin->parent;
+ pBgWin->backgroundState == ParentRelative;
+ pBgWin = pBgWin->parent);
+ ilbmXRotatePixmap(pPrivWin->pRotatedBorder,
+ pBgWin->drawable.x - pPrivWin->oldRotate.x);
+ ilbmYRotatePixmap(pPrivWin->pRotatedBorder,
+ pBgWin->drawable.y - pPrivWin->oldRotate.y);
+ pPrivWin->oldRotate.x = pBgWin->drawable.x;
+ pPrivWin->oldRotate.y = pBgWin->drawable.y;
+ }
+ } else if ((pWin->background.pixmap->drawable.width <= PPW) &&
+ !(pWin->background.pixmap->drawable.width &
+ (pWin->background.pixmap->drawable.width - 1))) {
+ ilbmCopyRotatePixmap(pWin->background.pixmap,
+ &pPrivWin->pRotatedBackground,
+ pWin->drawable.x, pWin->drawable.y);
+ if (pPrivWin->pRotatedBackground) {
+ pPrivWin->fastBackground = TRUE;
+ pPrivWin->oldRotate.x = pWin->drawable.x;
+ pPrivWin->oldRotate.y = pWin->drawable.y;
+ } else
+ pPrivWin->fastBackground = FALSE;
+ } else
+ pPrivWin->fastBackground = FALSE;
+ break;
+
+ case CWBackPixel:
+ pPrivWin->fastBackground = FALSE;
+ break;
+
+ case CWBorderPixmap:
+ if ((pWin->border.pixmap->drawable.width <= PPW) &&
+ !(pWin->border.pixmap->drawable.width &
+ (pWin->border.pixmap->drawable.width - 1))) {
+ for (pBgWin = pWin;
+ pBgWin->backgroundState == ParentRelative;
+ pBgWin = pBgWin->parent);
+ ilbmCopyRotatePixmap(pWin->border.pixmap,
+ &pPrivWin->pRotatedBorder,
+ pBgWin->drawable.x, pBgWin->drawable.y);
+ if (pPrivWin->pRotatedBorder) {
+ pPrivWin->fastBorder = TRUE;
+ pPrivWin->oldRotate.x = pBgWin->drawable.x;
+ pPrivWin->oldRotate.y = pBgWin->drawable.y;
+ } else
+ pPrivWin->fastBorder = FALSE;
+ } else
+ pPrivWin->fastBorder = FALSE;
+ break;
+ case CWBorderPixel:
+ pPrivWin->fastBorder = FALSE;
+ break;
+ }
+ }
+ /* Again, we have no failure modes indicated by any of the routines
+ * we've called, so we have to assume it worked */
+ return (TRUE);
+}
diff --git a/xc/programs/Xserver/ilbm/ilbmzerarc.c b/xc/programs/Xserver/ilbm/ilbmzerarc.c
new file mode 100644
index 000000000..9bdf22155
--- /dev/null
+++ b/xc/programs/Xserver/ilbm/ilbmzerarc.c
@@ -0,0 +1,210 @@
+/* $XFree86: xc/programs/Xserver/ilbm/ilbmzerarc.c,v 3.1 1998/03/20 21:08:04 hohndel Exp $ */
+/************************************************************
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+********************************************************/
+
+/* $XConsortium: ilbmzerarc.c,v 5.19 94/04/17 20:28:37 dpw Exp $ */
+
+/* Derived from:
+ * "Algorithm for drawing ellipses or hyperbolae with a digital plotter"
+ * by M. L. V. Pitteway
+ * The Computer Journal, November 1967, Volume 10, Number 3, pp. 282-289
+ */
+
+/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ to use interleaved bitplanes instead of normal bitplanes */
+
+#include "X.h"
+#include "Xprotostr.h"
+#include "miscstruct.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "ilbm.h"
+#include "maskbits.h"
+#include "mizerarc.h"
+#include "mi.h"
+
+/*
+ * Note: LEFTMOST must be the bit leftmost in the actual screen
+ * representation. This depends also on the IMAGE_BYTE_ORDER.
+ * LONG2CHARS() takes care of the re-ordering as required. (DHD)
+ */
+#if (BITMAP_BIT_ORDER == MSBFirst)
+#define LEFTMOST ((PixelType) LONG2CHARS((1 << PLST)))
+#else
+#define LEFTMOST ((PixelType) LONG2CHARS(1))
+#endif
+
+#define Pixelate(base,yoff,xoff) \
+{ \
+ paddr = ilbmScanlineOffset(base, (yoff) + ((xoff)>>PWSH)); \
+ pmask = SCRRIGHT(LEFTMOST, (xoff) & PIM); \
+ for (de = 0; de < depthDst; de++, paddr += nlwidth) /* @@@ NEXT PLANE @@@ */ \
+ switch (rrops[de]) { \
+ case RROP_BLACK: \
+ *paddr &= ~pmask; \
+ break; \
+ case RROP_WHITE: \
+ *paddr |= pmask; \
+ break; \
+ case RROP_INVERT: \
+ *paddr ^= pmask; \
+ break; \
+ case RROP_NOP: \
+ break; \
+ } \
+}
+
+#define DoPix(bit,base,yoff,xoff) if (mask & bit) Pixelate(base,yoff,xoff);
+
+static void
+ilbmZeroArcSS(pDraw, pGC, arc)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ xArc *arc;
+{
+ miZeroArcRec info;
+ Bool do360;
+ register int de;
+ register int x, y, a, b, d, mask;
+ register int k1, k3, dx, dy;
+ PixelType *addrl;
+ PixelType *yorgl, *yorgol;
+ PixelType pixel;
+ int nlwidth, yoffset, dyoffset;
+ int auxDst, depthDst;
+ PixelType pmask;
+ register PixelType *paddr;
+ register unsigned char *rrops;
+
+ rrops = ((ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr))->rrops;
+
+ ilbmGetPixelWidthAuxDepthAndPointer(pDraw, nlwidth, auxDst, depthDst,
+ addrl);
+ do360 = miZeroArcSetup(arc, &info, TRUE);
+ yorgl = addrl + ((info.yorg + pDraw->y) * auxDst);
+ yorgol = addrl + ((info.yorgo + pDraw->y) * auxDst);
+ info.xorg += pDraw->x;
+ info.xorgo += pDraw->x;
+ MIARCSETUP();
+ yoffset = y ? auxDst : 0;
+ dyoffset = 0;
+ mask = info.initialMask;
+ if (!(arc->width & 1)) {
+ DoPix(2, yorgl, 0, info.xorgo);
+ DoPix(8, yorgol, 0, info.xorgo);
+ }
+ if (!info.end.x || !info.end.y) {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ if (do360 && (arc->width == arc->height) && !(arc->width & 1)) {
+ int xoffset = auxDst;
+ PixelType *yorghl = ilbmScanlineDeltaNoBankSwitch(yorgl, info.h, auxDst);
+ int xorghp = info.xorg + info.h;
+ int xorghn = info.xorg - info.h;
+
+ while (1) {
+ Pixelate(yorgl, yoffset, info.xorg + x);
+ Pixelate(yorgl, yoffset, info.xorg - x);
+ Pixelate(yorgol, -yoffset, info.xorg - x);
+ Pixelate(yorgol, -yoffset, info.xorg + x);
+ if (a < 0)
+ break;
+ Pixelate(yorghl, -xoffset, xorghp - y);
+ Pixelate(yorghl, -xoffset, xorghn + y);
+ Pixelate(yorghl, xoffset, xorghn + y);
+ Pixelate(yorghl, xoffset, xorghp - y);
+ xoffset += auxDst;
+ MIARCCIRCLESTEP(yoffset += auxDst;);
+ }
+ x = info.w;
+ yoffset = info.h * auxDst;
+ } else if (do360) {
+ while (y < info.h || x < info.w) {
+ MIARCOCTANTSHIFT(dyoffset = auxDst;);
+ Pixelate(yorgl, yoffset, info.xorg + x);
+ Pixelate(yorgl, yoffset, info.xorgo - x);
+ Pixelate(yorgol, -yoffset, info.xorgo - x);
+ Pixelate(yorgol, -yoffset, info.xorg + x);
+ MIARCSTEP(yoffset += dyoffset;, yoffset += auxDst;);
+ }
+ } else {
+ while (y < info.h || x < info.w) {
+ MIARCOCTANTSHIFT(dyoffset = auxDst;);
+ if ((x == info.start.x) || (y == info.start.y)) {
+ mask = info.start.mask;
+ info.start = info.altstart;
+ }
+ DoPix(1, yorgl, yoffset, info.xorg + x);
+ DoPix(2, yorgl, yoffset, info.xorgo - x);
+ DoPix(4, yorgol, -yoffset, info.xorgo - x);
+ DoPix(8, yorgol, -yoffset, info.xorg + x);
+ if ((x == info.end.x) || (y == info.end.y)) {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ MIARCSTEP(yoffset += dyoffset;, yoffset += auxDst;);
+ }
+ }
+ if ((x == info.start.x) || (y == info.start.y))
+ mask = info.start.mask;
+ DoPix(1, yorgl, yoffset, info.xorg + x);
+ DoPix(4, yorgol, -yoffset, info.xorgo - x);
+ if (arc->height & 1) {
+ DoPix(2, yorgl, yoffset, info.xorgo - x);
+ DoPix(8, yorgol, -yoffset, info.xorg + x);
+ }
+}
+
+void
+ilbmZeroPolyArcSS(pDraw, pGC, narcs, parcs)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ register xArc *arc;
+ register int i;
+ BoxRec box;
+ RegionPtr cclip;
+
+ cclip = pGC->pCompositeClip;
+ for (arc = parcs, i = narcs; --i >= 0; arc++) {
+ if (miCanZeroArc(arc)) {
+ box.x1 = arc->x + pDraw->x;
+ box.y1 = arc->y + pDraw->y;
+ box.x2 = box.x1 + (int)arc->width + 1;
+ box.y2 = box.y1 + (int)arc->height + 1;
+ if (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN)
+ ilbmZeroArcSS(pDraw, pGC, arc);
+ else
+ miZeroPolyArc(pDraw, pGC, 1, arc);
+ } else
+ miPolyArc(pDraw, pGC, 1, arc);
+ }
+}
diff --git a/xc/programs/Xserver/include/Imakefile b/xc/programs/Xserver/include/Imakefile
new file mode 100644
index 000000000..b25614ec0
--- /dev/null
+++ b/xc/programs/Xserver/include/Imakefile
@@ -0,0 +1,51 @@
+XCOMM $XConsortium: Imakefile,v 1.2 95/01/13 20:28:14 kaleb Exp $
+XCOMM $XFree86: xc/programs/Xserver/include/Imakefile,v 3.14 1999/08/14 10:50:18 dawes Exp $
+
+#ifdef XFree86Version
+#if DoLoadableServer
+LinkSourceFile(xf86_libc.h,$(XF86OSSRC))
+LinkSourceFile(xf86_ansic.h,$(XF86OSSRC))
+LinkSourceFile(xf86Module.h,$(XF86COMSRC))
+LinkSourceFile(xf86Version.h,$(XF86SRC))
+LinkSourceFile(xf86Opt.h,$(XF86COMSRC))
+#endif
+LinkSourceFile(compiler.h,$(XF86COMSRC))
+#endif
+
+LinkSourceFile(osdep.h,../os)
+
+all::
+
+depend::
+
+
+InstallDriverSDKNonExecFile(XIstubs.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(bstore.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(bstorestr.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(colormap.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(colormapst.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(cursor.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(cursorstr.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(dix.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(dixstruct.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(gc.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(gcstruct.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(globals.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(input.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(inputstr.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(misc.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(miscstruct.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(opaque.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(os.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(pixmap.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(pixmapstr.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(property.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(region.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(regionstr.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(resource.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(screenint.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(scrnintstr.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(servermd.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(validate.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(window.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(windowstr.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/xc/programs/Xserver/include/XIstubs.h b/xc/programs/Xserver/include/XIstubs.h
new file mode 100644
index 000000000..156c4e34e
--- /dev/null
+++ b/xc/programs/Xserver/include/XIstubs.h
@@ -0,0 +1,101 @@
+/* $XFree86: xc/programs/Xserver/include/XIstubs.h,v 3.1 1996/04/15 11:34:22 dawes Exp $ */
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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 XI_STUBS_H
+#define XI_STUBS_H 1
+
+int
+ChangeKeyboardDevice (
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* old_dev */,
+ DeviceIntPtr /* new_dev */
+#endif
+ );
+
+int
+ChangePointerDevice (
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* old_dev */,
+ DeviceIntPtr /* new_dev */,
+ unsigned char /* x */,
+ unsigned char /* y */
+#endif
+ );
+
+void
+CloseInputDevice (
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* d */,
+ ClientPtr /* client */
+#endif
+ );
+
+void
+AddOtherInputDevices (
+#if NeedFunctionPrototypes
+ void
+#endif
+ );
+
+void
+OpenInputDevice (
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* dev */,
+ ClientPtr /* client */,
+ int * /* status */
+#endif
+ );
+
+int
+SetDeviceMode (
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ int /* mode */
+#endif
+ );
+
+int
+SetDeviceValuators (
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ int * /* valuators */,
+ int /* first_valuator */,
+ int /* num_valuators */
+#endif
+ );
+
+int
+ChangeDeviceControl (
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ xDeviceCtl * /* control */
+#endif
+ );
+
+#endif /* XI_STUBS_H */
diff --git a/xc/programs/Xserver/include/bstore.h b/xc/programs/Xserver/include/bstore.h
new file mode 100644
index 000000000..7d6926a31
--- /dev/null
+++ b/xc/programs/Xserver/include/bstore.h
@@ -0,0 +1,23 @@
+/* $XFree86: xc/programs/Xserver/include/bstore.h,v 1.1 1998/04/05 16:44:25 robin Exp $*/
+/*
+ * Copyright (c) 1987 by the Regents of the University of California
+ *
+ * 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. The University of
+ * California makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ */
+
+/*
+ * Moved here from mi to allow wrapping of lower level backing store functions.
+ * -- 1997.10.27 Marc Aurele La France (tsi@ualberta.ca)
+ */
+
+#ifndef _BSTORE_H_
+#define _BSTORE_H_
+
+#include "bstorestr.h"
+
+#endif /* _BSTORE_H_ */
diff --git a/xc/programs/Xserver/include/bstorestr.h b/xc/programs/Xserver/include/bstorestr.h
new file mode 100644
index 000000000..74f625bb9
--- /dev/null
+++ b/xc/programs/Xserver/include/bstorestr.h
@@ -0,0 +1,75 @@
+/* $XFree86: xc/programs/Xserver/include/bstorestr.h,v 1.1 1998/04/05 16:44:25 robin Exp $*/
+/*
+ * Copyright (c) 1987 by the Regents of the University of California
+ *
+ * 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. The University of
+ * California makes no representations about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied
+ * warranty.
+ */
+
+/*
+ * Moved here from mi to allow wrapping of lower level backing store functions.
+ * -- 1997.10.27 Marc Aurele La France (tsi@ualberta.ca)
+ */
+
+#ifndef _BSTORESTR_H_
+#define _BSTORESTR_H_
+
+#include "gc.h"
+#include "pixmap.h"
+#include "region.h"
+#include "window.h"
+
+typedef void (* BackingStoreSaveAreasProcPtr)(
+#if NeedNestedPrototypes
+ PixmapPtr /*pBackingPixmap*/,
+ RegionPtr /*pObscured*/,
+ int /*x*/,
+ int /*y*/,
+ WindowPtr /*pWin*/
+#endif
+);
+
+typedef void (* BackingStoreRestoreAreasProcPtr)(
+#if NeedNestedPrototypes
+ PixmapPtr /*pBackingPixmap*/,
+ RegionPtr /*pExposed*/,
+ int /*x*/,
+ int /*y*/,
+ WindowPtr /*pWin*/
+#endif
+);
+
+typedef void (* BackingStoreSetClipmaskRgnProcPtr)(
+#if NeedNestedPrototypes
+ GCPtr /*pBackingGC*/,
+ RegionPtr /*pbackingCompositeClip*/
+#endif
+);
+
+typedef PixmapPtr (* BackingStoreGetImagePixmapProcPtr)( /* unused */
+#if NeedNestedPrototypes
+ void
+#endif
+);
+
+typedef PixmapPtr (* BackingStoreGetSpansPixmapProcPtr)( /* unused */
+#if NeedNestedPrototypes
+ void
+#endif
+);
+
+typedef struct _BSFuncs {
+
+ BackingStoreSaveAreasProcPtr SaveAreas;
+ BackingStoreRestoreAreasProcPtr RestoreAreas;
+ BackingStoreSetClipmaskRgnProcPtr SetClipmaskRgn;
+ BackingStoreGetImagePixmapProcPtr GetImagePixmap;
+ BackingStoreGetSpansPixmapProcPtr GetSpansPixmap;
+
+} BSFuncRec, *BSFuncPtr;
+
+#endif /* _BSTORESTR_H_ */
diff --git a/xc/programs/Xserver/include/closestr.h b/xc/programs/Xserver/include/closestr.h
new file mode 100644
index 000000000..857a13f29
--- /dev/null
+++ b/xc/programs/Xserver/include/closestr.h
@@ -0,0 +1,159 @@
+/* $TOG: closestr.h /main/12 1998/03/26 17:26:54 kaleb $ */
+/*
+
+Copyright 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+/* $XFree86: xc/programs/Xserver/include/closestr.h,v 3.2 1998/10/04 09:38:54 dawes Exp $ */
+
+
+#ifndef CLOSESTR_H
+#define CLOSESTR_H
+
+#define NEED_REPLIES
+#include "Xproto.h"
+#include "closure.h"
+#include "dix.h"
+#include "misc.h"
+#include "gcstruct.h"
+
+/* closure structures */
+
+/* OpenFont */
+
+typedef struct _OFclosure {
+ ClientPtr client;
+ short current_fpe;
+ short num_fpes;
+ FontPathElementPtr *fpe_list;
+ Mask flags;
+ Bool slept;
+
+/* XXX -- get these from request buffer instead? */
+ char *origFontName;
+ int origFontNameLen;
+ XID fontid;
+ char *fontname;
+ int fnamelen;
+ FontPtr non_cachable_font;
+} OFclosureRec;
+
+/* ListFontsWithInfo */
+
+#define XLFDMAXFONTNAMELEN 256
+typedef struct _LFWIstate {
+ char pattern[XLFDMAXFONTNAMELEN];
+ int patlen;
+ int current_fpe;
+ int max_names;
+ Bool list_started;
+ pointer private;
+} LFWIstateRec, *LFWIstatePtr;
+
+typedef struct _LFWIclosure {
+ ClientPtr client;
+ int num_fpes;
+ FontPathElementPtr *fpe_list;
+ xListFontsWithInfoReply *reply;
+ int length;
+ LFWIstateRec current;
+ LFWIstateRec saved;
+ int savedNumFonts;
+ Bool haveSaved;
+ Bool slept;
+ char *savedName;
+} LFWIclosureRec;
+
+/* ListFonts */
+
+typedef struct _LFclosure {
+ ClientPtr client;
+ int num_fpes;
+ FontPathElementPtr *fpe_list;
+ FontNamesPtr names;
+ LFWIstateRec current;
+ LFWIstateRec saved;
+ Bool haveSaved;
+ Bool slept;
+ char *savedName;
+ int savedNameLen;
+} LFclosureRec;
+
+/* PolyText */
+
+typedef
+ int (* PolyTextPtr)(
+#if NeedNestedPrototypes
+ DrawablePtr /* pDraw */,
+ GCPtr /* pGC */,
+ int /* x */,
+ int /* y */,
+ int /* count */,
+ void * /* chars or shorts */
+#endif
+ );
+
+typedef struct _PTclosure {
+ ClientPtr client;
+ DrawablePtr pDraw;
+ GC *pGC;
+ unsigned char *pElt;
+ unsigned char *endReq;
+ unsigned char *data;
+ int xorg;
+ int yorg;
+ CARD8 reqType;
+ PolyTextPtr polyText;
+ int itemSize;
+ XID did;
+ int err;
+ Bool slept;
+} PTclosureRec;
+
+/* ImageText */
+
+typedef
+ void (* ImageTextPtr)(
+#if NeedNestedPrototypes
+ DrawablePtr /* pDraw */,
+ GCPtr /* pGC */,
+ int /* x */,
+ int /* y */,
+ int /* count */,
+ void * /* chars or shorts */
+#endif
+ );
+
+typedef struct _ITclosure {
+ ClientPtr client;
+ DrawablePtr pDraw;
+ GC *pGC;
+ BYTE nChars;
+ unsigned char *data;
+ int xorg;
+ int yorg;
+ CARD8 reqType;
+ ImageTextPtr imageText;
+ int itemSize;
+ XID did;
+ Bool slept;
+} ITclosureRec;
+#endif /* CLOSESTR_H */
diff --git a/xc/programs/Xserver/include/closure.h b/xc/programs/Xserver/include/closure.h
new file mode 100644
index 000000000..67843f5e4
--- /dev/null
+++ b/xc/programs/Xserver/include/closure.h
@@ -0,0 +1,53 @@
+/* $TOG: closure.h /main/4 1998/02/09 14:27:54 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+#ifndef CLOSURE_H
+#define CLOSURE_H 1
+
+typedef struct _LFclosure *LFclosurePtr;
+typedef struct _LFWIclosure *LFWIclosurePtr;
+typedef struct _OFclosure *OFclosurePtr;
+typedef struct _PTclosure *PTclosurePtr;
+typedef struct _ITclosure *ITclosurePtr;
+
+#endif /* CLOSURE_H */
diff --git a/xc/programs/Xserver/include/colormap.h b/xc/programs/Xserver/include/colormap.h
new file mode 100644
index 000000000..f326cc62d
--- /dev/null
+++ b/xc/programs/Xserver/include/colormap.h
@@ -0,0 +1,230 @@
+/* $TOG: colormap.h /main/15 1998/02/09 14:28:04 kaleb $ */
+/*
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/include/colormap.h,v 1.3 1998/10/04 09:38:55 dawes Exp $ */
+#ifndef CMAP_H
+#define CMAP_H 1
+
+#include "X11/Xproto.h"
+#include "screenint.h"
+#include "window.h"
+
+/* these follow X.h's AllocNone and AllocAll */
+#define CM_PSCREEN 2
+#define CM_PWIN 3
+/* Passed internally in colormap.c */
+#define REDMAP 0
+#define GREENMAP 1
+#define BLUEMAP 2
+#define PSEUDOMAP 3
+#define AllocPrivate (-1)
+#define AllocTemporary (-2)
+#define DynamicClass 1
+
+/* Values for the flags field of a colormap. These should have 1 bit set
+ * and not overlap */
+#define IsDefault 1
+#define AllAllocated 2
+#define BeingCreated 4
+
+
+typedef CARD32 Pixel;
+typedef struct _CMEntry *EntryPtr;
+/* moved to screenint.h: typedef struct _ColormapRec *ColormapPtr */
+typedef struct _colorResource *colorResourcePtr;
+
+extern int CreateColormap(
+#if NeedFunctionPrototypes
+ Colormap /*mid*/,
+ ScreenPtr /*pScreen*/,
+ VisualPtr /*pVisual*/,
+ ColormapPtr* /*ppcmap*/,
+ int /*alloc*/,
+ int /*client*/
+#endif
+);
+
+extern int FreeColormap(
+#if NeedFunctionPrototypes
+ pointer /*pmap*/,
+ XID /*mid*/
+#endif
+);
+
+extern int TellLostMap(
+#if NeedFunctionPrototypes
+ WindowPtr /*pwin*/,
+ pointer /* Colormap *pmid */
+#endif
+);
+
+extern int TellGainedMap(
+#if NeedFunctionPrototypes
+ WindowPtr /*pwin*/,
+ pointer /* Colormap *pmid */
+#endif
+);
+
+extern int CopyColormapAndFree(
+#if NeedFunctionPrototypes
+ Colormap /*mid*/,
+ ColormapPtr /*pSrc*/,
+ int /*client*/
+#endif
+);
+
+extern int AllocColor(
+#if NeedFunctionPrototypes
+ ColormapPtr /*pmap*/,
+ unsigned short* /*pred*/,
+ unsigned short* /*pgreen*/,
+ unsigned short* /*pblue*/,
+ Pixel* /*pPix*/,
+ int /*client*/
+#endif
+);
+
+extern void FakeAllocColor(
+#if NeedFunctionPrototypes
+ ColormapPtr /*pmap*/,
+ xColorItem * /*item*/
+#endif
+);
+
+extern void FakeFreeColor(
+#if NeedFunctionPrototypes
+ ColormapPtr /*pmap*/,
+ Pixel /*pixel*/
+#endif
+);
+
+typedef int (*ColorCompareProcPtr)(
+#if NeedNestedPrototypes
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/
+#endif
+);
+
+extern int FindColor(
+#if NeedFunctionPrototypes
+ ColormapPtr /*pmap*/,
+ EntryPtr /*pentFirst*/,
+ int /*size*/,
+ xrgb* /*prgb*/,
+ Pixel* /*pPixel*/,
+ int /*channel*/,
+ int /*client*/,
+ ColorCompareProcPtr /*comp*/
+#endif
+);
+
+extern int QueryColors(
+#if NeedFunctionPrototypes
+ ColormapPtr /*pmap*/,
+ int /*count*/,
+ Pixel* /*ppixIn*/,
+ xrgb* /*prgbList*/
+#endif
+);
+
+extern int FreeClientPixels(
+#if NeedFunctionPrototypes
+ pointer /*pcr*/,
+ XID /*fakeid*/
+#endif
+);
+
+extern int AllocColorCells(
+#if NeedFunctionPrototypes
+ int /*client*/,
+ ColormapPtr /*pmap*/,
+ int /*colors*/,
+ int /*planes*/,
+ Bool /*contig*/,
+ Pixel* /*ppix*/,
+ Pixel* /*masks*/
+#endif
+);
+
+extern int AllocColorPlanes(
+#if NeedFunctionPrototypes
+ int /*client*/,
+ ColormapPtr /*pmap*/,
+ int /*colors*/,
+ int /*r*/,
+ int /*g*/,
+ int /*b*/,
+ Bool /*contig*/,
+ Pixel* /*pixels*/,
+ Pixel* /*prmask*/,
+ Pixel* /*pgmask*/,
+ Pixel* /*pbmask*/
+#endif
+);
+
+extern int FreeColors(
+#if NeedFunctionPrototypes
+ ColormapPtr /*pmap*/,
+ int /*client*/,
+ int /*count*/,
+ Pixel* /*pixels*/,
+ Pixel /*mask*/
+#endif
+);
+
+extern int StoreColors(
+#if NeedFunctionPrototypes
+ ColormapPtr /*pmap*/,
+ int /*count*/,
+ xColorItem* /*defs*/
+#endif
+);
+
+extern int IsMapInstalled(
+#if NeedFunctionPrototypes
+ Colormap /*map*/,
+ WindowPtr /*pWin*/
+#endif
+);
+
+#endif /* CMAP_H */
diff --git a/xc/programs/Xserver/include/colormapst.h b/xc/programs/Xserver/include/colormapst.h
new file mode 100644
index 000000000..d094ecd66
--- /dev/null
+++ b/xc/programs/Xserver/include/colormapst.h
@@ -0,0 +1,116 @@
+/*
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $TOG: colormapst.h /main/5 1998/02/09 14:27:59 kaleb $ */
+#ifndef CMAPSTRUCT_H
+#define CMAPSTRUCT_H 1
+
+#include "colormap.h"
+#include "screenint.h"
+
+/* Shared color -- the color is used by AllocColorPlanes */
+typedef struct
+{
+ unsigned short color;
+ short refcnt;
+} SHAREDCOLOR;
+
+/* LOCO -- a local color for a PseudoColor cell. DirectColor maps always
+ * use the first value (called red) in the structure. What channel they
+ * are really talking about depends on which map they are in. */
+typedef struct
+{
+ unsigned short red, green, blue;
+} LOCO;
+
+/* SHCO -- a shared color for a PseudoColor cell. Used with AllocColorPlanes.
+ * DirectColor maps always use the first value (called red) in the structure.
+ * What channel they are really talking about depends on which map they
+ * are in. */
+typedef struct
+{
+ SHAREDCOLOR *red, *green, *blue;
+} SHCO;
+
+
+/* color map entry */
+typedef struct _CMEntry
+{
+ union
+ {
+ LOCO local;
+ SHCO shco;
+ } co;
+ short refcnt;
+ Bool fShared;
+} Entry;
+
+/* COLORMAPs can be used for either Direct or Pseudo color. PseudoColor
+ * only needs one cell table, we arbitrarily pick red. We keep track
+ * of that table with freeRed, numPixelsRed, and clientPixelsRed */
+
+typedef struct _ColormapRec
+{
+ VisualPtr pVisual;
+ short class; /* PseudoColor or DirectColor */
+ long mid; /* client's name for colormap */
+ ScreenPtr pScreen; /* screen map is associated with */
+ short flags; /* 1 = IsDefault
+ * 2 = AllAllocated */
+ int freeRed;
+ int freeGreen;
+ int freeBlue;
+ int *numPixelsRed;
+ int *numPixelsGreen;
+ int *numPixelsBlue;
+ Pixel **clientPixelsRed;
+ Pixel **clientPixelsGreen;
+ Pixel **clientPixelsBlue;
+ Entry *red;
+ Entry *green;
+ Entry *blue;
+ pointer devPriv;
+ DevUnion *devPrivates; /* dynamic devPrivates added after devPriv
+ already existed - must keep devPriv */
+} ColormapRec;
+
+#endif /* COLORMAP_H */
diff --git a/xc/programs/Xserver/include/cursor.h b/xc/programs/Xserver/include/cursor.h
new file mode 100644
index 000000000..36f3c9d17
--- /dev/null
+++ b/xc/programs/Xserver/include/cursor.h
@@ -0,0 +1,147 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: cursor.h /main/8 1998/02/09 14:28:12 kaleb $ */
+#ifndef CURSOR_H
+#define CURSOR_H
+
+#include "misc.h"
+#include "screenint.h"
+#include "window.h"
+
+#define NullCursor ((CursorPtr)NULL)
+
+typedef struct _Cursor *CursorPtr;
+typedef struct _CursorMetric *CursorMetricPtr;
+
+extern CursorPtr rootCursor;
+
+extern int FreeCursor(
+#if NeedFunctionPrototypes
+ pointer /*pCurs*/,
+ XID /*cid*/
+#endif
+);
+
+extern CursorPtr AllocCursor(
+#if NeedFunctionPrototypes
+ unsigned char* /*psrcbits*/,
+ unsigned char* /*pmaskbits*/,
+ CursorMetricPtr /*cm*/,
+ unsigned /*foreRed*/,
+ unsigned /*foreGreen*/,
+ unsigned /*foreBlue*/,
+ unsigned /*backRed*/,
+ unsigned /*backGreen*/,
+ unsigned /*backBlue*/
+#endif
+);
+
+extern int AllocGlyphCursor(
+#if NeedFunctionPrototypes
+ Font /*source*/,
+ unsigned int /*sourceChar*/,
+ Font /*mask*/,
+ unsigned int /*maskChar*/,
+ unsigned /*foreRed*/,
+ unsigned /*foreGreen*/,
+ unsigned /*foreBlue*/,
+ unsigned /*backRed*/,
+ unsigned /*backGreen*/,
+ unsigned /*backBlue*/,
+ CursorPtr* /*ppCurs*/,
+ ClientPtr /*client*/
+#endif
+);
+
+extern CursorPtr CreateRootCursor(
+#if NeedFunctionPrototypes
+ char* /*pfilename*/,
+ unsigned int /*glyph*/
+#endif
+);
+
+extern int ServerBitsFromGlyph(
+#if NeedFunctionPrototypes
+ FontPtr /*pfont*/,
+ unsigned int /*ch*/,
+ register CursorMetricPtr /*cm*/,
+ unsigned char ** /*ppbits*/
+#endif
+);
+
+extern Bool CursorMetricsFromGlyph(
+#if NeedFunctionPrototypes
+ FontPtr /*pfont*/,
+ unsigned /*ch*/,
+ CursorMetricPtr /*cm*/
+#endif
+);
+
+extern void CheckCursorConfinement(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern void NewCurrentScreen(
+#if NeedFunctionPrototypes
+ ScreenPtr /*newScreen*/,
+ int /*x*/,
+ int /*y*/
+#endif
+);
+
+extern Bool PointerConfinedToScreen(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void GetSpritePosition(
+#if NeedFunctionPrototypes
+ int * /*px*/,
+ int * /*py*/
+#endif
+);
+
+#endif /* CURSOR_H */
diff --git a/xc/programs/Xserver/include/cursorstr.h b/xc/programs/Xserver/include/cursorstr.h
new file mode 100644
index 000000000..402e012df
--- /dev/null
+++ b/xc/programs/Xserver/include/cursorstr.h
@@ -0,0 +1,79 @@
+/* $TOG: cursorstr.h /main/9 1998/02/09 14:28:08 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/include/cursorstr.h,v 1.4 1998/10/04 09:38:55 dawes Exp $ */
+
+#ifndef CURSORSTRUCT_H
+#define CURSORSTRUCT_H
+
+#include "cursor.h"
+/*
+ * device-independent cursor storage
+ */
+
+/*
+ * source and mask point directly to the bits, which are in the server-defined
+ * bitmap format.
+ */
+typedef struct _CursorBits {
+ unsigned char *source; /* points to bits */
+ unsigned char *mask; /* points to bits */
+ Bool emptyMask; /* all zeros mask */
+ unsigned short width, height, xhot, yhot; /* metrics */
+ int refcnt; /* can be shared */
+ pointer devPriv[MAXSCREENS]; /* set by pScr->RealizeCursor*/
+} CursorBits, *CursorBitsPtr;
+
+typedef struct _Cursor {
+ CursorBitsPtr bits;
+ unsigned short foreRed, foreGreen, foreBlue; /* device-independent color */
+ unsigned short backRed, backGreen, backBlue; /* device-independent color */
+ int refcnt;
+ pointer devPriv[MAXSCREENS]; /* set by pScr->RealizeCursor*/
+} CursorRec;
+
+typedef struct _CursorMetric {
+ unsigned short width, height, xhot, yhot;
+} CursorMetricRec;
+
+#endif /* CURSORSTRUCT_H */
diff --git a/xc/programs/Xserver/include/dix.h b/xc/programs/Xserver/include/dix.h
new file mode 100644
index 000000000..bd60b6c51
--- /dev/null
+++ b/xc/programs/Xserver/include/dix.h
@@ -0,0 +1,1094 @@
+/* $XFree86: xc/programs/Xserver/include/dix.h,v 3.10 1999/08/21 13:48:43 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: dix.h /main/45 1998/02/09 14:28:31 kaleb $ */
+
+#ifndef DIX_H
+#define DIX_H
+
+#include "gc.h"
+#include "window.h"
+#include "input.h"
+
+#define EARLIER -1
+#define SAMETIME 0
+#define LATER 1
+
+#define NullClient ((ClientPtr) 0)
+#define REQUEST(type) \
+ register type *stuff = (type *)client->requestBuffer
+
+
+#define REQUEST_SIZE_MATCH(req)\
+ if ((sizeof(req) >> 2) != client->req_len)\
+ return(BadLength)
+
+#define REQUEST_AT_LEAST_SIZE(req) \
+ if ((sizeof(req) >> 2) > client->req_len )\
+ return(BadLength)
+
+#define REQUEST_FIXED_SIZE(req, n)\
+ if (((sizeof(req) >> 2) > client->req_len) || \
+ (((sizeof(req) + (n) + 3) >> 2) != client->req_len)) \
+ return(BadLength)
+
+#define LEGAL_NEW_RESOURCE(id,client)\
+ if (!LegalNewID(id,client)) \
+ {\
+ client->errorValue = id;\
+ return(BadIDChoice);\
+ }
+
+/* XXX if you are using this macro, you are probably not generating Match
+ * errors where appropriate */
+#define LOOKUP_DRAWABLE(did, client)\
+ ((client->lastDrawableID == did) ? \
+ client->lastDrawable : (DrawablePtr)LookupDrawable(did, client))
+
+#ifdef XCSECURITY
+
+#define SECURITY_VERIFY_DRAWABLE(pDraw, did, client, mode)\
+ if (client->lastDrawableID == did && !client->trustLevel)\
+ pDraw = client->lastDrawable;\
+ else \
+ {\
+ pDraw = (DrawablePtr) SecurityLookupIDByClass(client, did, \
+ RC_DRAWABLE, mode);\
+ if (!pDraw) \
+ {\
+ client->errorValue = did; \
+ return BadDrawable;\
+ }\
+ if (pDraw->type == UNDRAWABLE_WINDOW)\
+ return BadMatch;\
+ }
+
+#define SECURITY_VERIFY_GEOMETRABLE(pDraw, did, client, mode)\
+ if (client->lastDrawableID == did && !client->trustLevel)\
+ pDraw = client->lastDrawable;\
+ else \
+ {\
+ pDraw = (DrawablePtr) SecurityLookupIDByClass(client, did, \
+ RC_DRAWABLE, mode);\
+ if (!pDraw) \
+ {\
+ client->errorValue = did; \
+ return BadDrawable;\
+ }\
+ }
+
+#define SECURITY_VERIFY_GC(pGC, rid, client, mode)\
+ if (client->lastGCID == rid && !client->trustLevel)\
+ pGC = client->lastGC;\
+ else\
+ pGC = (GC *) SecurityLookupIDByType(client, rid, RT_GC, mode);\
+ if (!pGC)\
+ {\
+ client->errorValue = rid;\
+ return (BadGC);\
+ }
+
+#define VERIFY_DRAWABLE(pDraw, did, client)\
+ SECURITY_VERIFY_DRAWABLE(pDraw, did, client, SecurityUnknownAccess)
+
+#define VERIFY_GEOMETRABLE(pDraw, did, client)\
+ SECURITY_VERIFY_GEOMETRABLE(pDraw, did, client, SecurityUnknownAccess)
+
+#define VERIFY_GC(pGC, rid, client)\
+ SECURITY_VERIFY_GC(pGC, rid, client, SecurityUnknownAccess)
+
+#else /* not XCSECURITY */
+
+#define VERIFY_DRAWABLE(pDraw, did, client)\
+ if (client->lastDrawableID == did)\
+ pDraw = client->lastDrawable;\
+ else \
+ {\
+ pDraw = (DrawablePtr) LookupIDByClass(did, RC_DRAWABLE);\
+ if (!pDraw) \
+ {\
+ client->errorValue = did; \
+ return BadDrawable;\
+ }\
+ if (pDraw->type == UNDRAWABLE_WINDOW)\
+ return BadMatch;\
+ }
+
+#define VERIFY_GEOMETRABLE(pDraw, did, client)\
+ if (client->lastDrawableID == did)\
+ pDraw = client->lastDrawable;\
+ else \
+ {\
+ pDraw = (DrawablePtr) LookupIDByClass(did, RC_DRAWABLE);\
+ if (!pDraw) \
+ {\
+ client->errorValue = did; \
+ return BadDrawable;\
+ }\
+ }
+
+#define VERIFY_GC(pGC, rid, client)\
+ if (client->lastGCID == rid)\
+ pGC = client->lastGC;\
+ else\
+ pGC = (GC *)LookupIDByType(rid, RT_GC);\
+ if (!pGC)\
+ {\
+ client->errorValue = rid;\
+ return (BadGC);\
+ }
+
+#define SECURITY_VERIFY_DRAWABLE(pDraw, did, client, mode)\
+ VERIFY_DRAWABLE(pDraw, did, client)
+
+#define SECURITY_VERIFY_GEOMETRABLE(pDraw, did, client, mode)\
+ VERIFY_GEOMETRABLE(pDraw, did, client)
+
+#define SECURITY_VERIFY_GC(pGC, rid, client, mode)\
+ VERIFY_GC(pGC, rid, client)
+
+#endif /* XCSECURITY */
+
+/*
+ * We think that most hardware implementations of DBE will want
+ * LookupID*(dbe_back_buffer_id) to return the window structure that the
+ * id is a back buffer for. Since both front and back buffers will
+ * return the same structure, you need to be able to distinguish
+ * somewhere what kind of buffer (front/back) was being asked for, so
+ * that ddx can render to the right place. That's the problem that the
+ * following code solves. Note: we couldn't embed this in the LookupID*
+ * functions because the VALIDATE_DRAWABLE_AND_GC macro often circumvents
+ * those functions by checking a one-element cache. That's why we're
+ * mucking with VALIDATE_DRAWABLE_AND_GC.
+ *
+ * If you put -DNEED_DBE_BUF_BITS into PervasiveDBEDefines, the window
+ * structure will have two additional bits defined, srcBuffer and
+ * dstBuffer, and their values will be maintained via the macros
+ * SET_DBE_DSTBUF and SET_DBE_SRCBUF (below). If you also
+ * put -DNEED_DBE_BUF_VALIDATE into PervasiveDBEDefines, the function
+ * DbeValidateBuffer will be called any time the bits change to give you
+ * a chance to do some setup. See the DBE code for more details on this
+ * function. We put in these levels of conditionality so that you can do
+ * just what you need to do, and no more. If neither of these defines
+ * are used, the bits won't be there, and VALIDATE_DRAWABLE_AND_GC will
+ * be unchanged. dpw
+ */
+
+#if defined(NEED_DBE_BUF_BITS)
+#define SET_DBE_DSTBUF(_pDraw, _drawID) \
+ SET_DBE_BUF(_pDraw, _drawID, dstBuffer, TRUE)
+#define SET_DBE_SRCBUF(_pDraw, _drawID) \
+ SET_DBE_BUF(_pDraw, _drawID, srcBuffer, FALSE)
+#if defined (NEED_DBE_BUF_VALIDATE)
+#define SET_DBE_BUF(_pDraw, _drawID, _whichBuffer, _dstbuf) \
+ if (_pDraw->type == DRAWABLE_WINDOW)\
+ {\
+ int thisbuf = (_pDraw->id == _drawID);\
+ if (thisbuf != ((WindowPtr)_pDraw)->_whichBuffer)\
+ {\
+ ((WindowPtr)_pDraw)->_whichBuffer = thisbuf;\
+ DbeValidateBuffer((WindowPtr)_pDraw, _drawID, _dstbuf);\
+ }\
+ }
+#else /* want buffer bits, but don't need to call DbeValidateBuffer */
+#define SET_DBE_BUF(_pDraw, _drawID, _whichBuffer, _dstbuf) \
+ if (_pDraw->type == DRAWABLE_WINDOW)\
+ {\
+ ((WindowPtr)_pDraw)->_whichBuffer = (_pDraw->id == _drawID);\
+ }
+#endif /* NEED_DBE_BUF_VALIDATE */
+#else /* don't want buffer bits in window */
+#define SET_DBE_DSTBUF(_pDraw, _drawID) /**/
+#define SET_DBE_SRCBUF(_pDraw, _drawID) /**/
+#endif /* NEED_DBE_BUF_BITS */
+
+#define VALIDATE_DRAWABLE_AND_GC(drawID, pDraw, pGC, client)\
+ if ((stuff->gc == INVALID) || (client->lastGCID != stuff->gc) ||\
+ (client->lastDrawableID != drawID))\
+ {\
+ SECURITY_VERIFY_GEOMETRABLE(pDraw, drawID, client, SecurityWriteAccess);\
+ SECURITY_VERIFY_GC(pGC, stuff->gc, client, SecurityReadAccess);\
+ if ((pGC->depth != pDraw->depth) ||\
+ (pGC->pScreen != pDraw->pScreen))\
+ return (BadMatch);\
+ client->lastDrawable = pDraw;\
+ client->lastDrawableID = drawID;\
+ client->lastGC = pGC;\
+ client->lastGCID = stuff->gc;\
+ }\
+ else\
+ {\
+ pGC = client->lastGC;\
+ pDraw = client->lastDrawable;\
+ }\
+ SET_DBE_DSTBUF(pDraw, drawID);\
+ if (pGC->serialNumber != pDraw->serialNumber)\
+ ValidateGC(pDraw, pGC);
+
+
+#define WriteReplyToClient(pClient, size, pReply) \
+ if ((pClient)->swapped) \
+ (*ReplySwapVector[((xReq *)(pClient)->requestBuffer)->reqType]) \
+ (pClient, (int)(size), pReply); \
+ else (void) WriteToClient(pClient, (int)(size), (char *)(pReply));
+
+#define WriteSwappedDataToClient(pClient, size, pbuf) \
+ if ((pClient)->swapped) \
+ (*(pClient)->pSwapReplyFunc)(pClient, (int)(size), pbuf); \
+ else (void) WriteToClient (pClient, (int)(size), (char *)(pbuf));
+
+typedef struct _TimeStamp *TimeStampPtr;
+
+#ifndef _XTYPEDEF_CLIENTPTR
+typedef struct _Client *ClientPtr; /* also in misc.h */
+#define _XTYPEDEF_CLIENTPTR
+#endif
+
+typedef struct _WorkQueue *WorkQueuePtr;
+
+extern ClientPtr requestingClient;
+extern ClientPtr *clients;
+extern ClientPtr serverClient;
+extern int currentMaxClients;
+
+#if !(defined(__alpha) || defined(__alpha__))
+typedef long HWEventQueueType;
+#else
+typedef int HWEventQueueType;
+#endif
+typedef HWEventQueueType* HWEventQueuePtr;
+
+extern HWEventQueuePtr checkForInput[2];
+
+typedef struct _TimeStamp {
+ CARD32 months; /* really ~49.7 days */
+ CARD32 milliseconds;
+} TimeStamp;
+
+/* dispatch.c */
+
+extern void SetInputCheck(
+#if NeedFunctionPrototypes
+ HWEventQueuePtr /*c0*/,
+ HWEventQueuePtr /*c1*/
+#endif
+);
+
+extern void CloseDownClient(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern void UpdateCurrentTime(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void UpdateCurrentTimeIf(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void InitSelections(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void FlushClientCaches(
+#if NeedFunctionPrototypes
+ XID /*id*/
+#endif
+);
+
+extern int dixDestroyPixmap(
+#if NeedFunctionPrototypes
+ pointer /*value*/,
+ XID /*pid*/
+#endif
+);
+
+extern void CloseDownRetainedResources(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void InitClient(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ int /*i*/,
+ pointer /*ospriv*/
+#endif
+);
+
+extern ClientPtr NextAvailableClient(
+#if NeedFunctionPrototypes
+ pointer /*ospriv*/
+#endif
+);
+
+extern void SendErrorToClient(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ unsigned int /*majorCode*/,
+ unsigned int /*minorCode*/,
+ XID /*resId*/,
+ int /*errorCode*/
+#endif
+);
+
+extern void DeleteWindowFromAnySelections(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern void MarkClientException(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern int GetGeometry(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ xGetGeometryReply* /* wa */
+#endif
+);
+
+/* dixutils.c */
+
+extern void CopyISOLatin1Lowered(
+#if NeedFunctionPrototypes
+ unsigned char * /*dest*/,
+ unsigned char * /*source*/,
+ int /*length*/
+#endif
+);
+
+#ifdef XCSECURITY
+
+extern WindowPtr SecurityLookupWindow(
+#if NeedFunctionPrototypes
+ XID /*rid*/,
+ ClientPtr /*client*/,
+ Mask /*access_mode*/
+#endif
+);
+
+extern pointer SecurityLookupDrawable(
+#if NeedFunctionPrototypes
+ XID /*rid*/,
+ ClientPtr /*client*/,
+ Mask /*access_mode*/
+#endif
+);
+
+extern WindowPtr LookupWindow(
+#if NeedFunctionPrototypes
+ XID /*rid*/,
+ ClientPtr /*client*/
+#endif
+);
+
+extern pointer LookupDrawable(
+#if NeedFunctionPrototypes
+ XID /*rid*/,
+ ClientPtr /*client*/
+#endif
+);
+
+#else
+
+extern WindowPtr LookupWindow(
+#if NeedFunctionPrototypes
+ XID /*rid*/,
+ ClientPtr /*client*/
+#endif
+);
+
+extern pointer LookupDrawable(
+#if NeedFunctionPrototypes
+ XID /*rid*/,
+ ClientPtr /*client*/
+#endif
+);
+
+#define SecurityLookupWindow(rid, client, access_mode) \
+ LookupWindow(rid, client)
+
+#define SecurityLookupDrawable(rid, client, access_mode) \
+ LookupDrawable(rid, client)
+
+#endif /* XCSECURITY */
+
+extern ClientPtr LookupClient(
+#if NeedFunctionPrototypes
+ XID /*rid*/,
+ ClientPtr /*client*/
+#endif
+);
+
+extern void NoopDDA(
+#if NeedVarargsPrototypes
+ void *,
+ ...
+#endif
+);
+
+extern int AlterSaveSetForClient(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ WindowPtr /*pWin*/,
+ unsigned /*mode*/
+#endif
+);
+
+extern void DeleteWindowFromAnySaveSet(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern void BlockHandler(
+#if NeedFunctionPrototypes
+ pointer /*pTimeout*/,
+ pointer /*pReadmask*/
+#endif
+);
+
+extern void WakeupHandler(
+#if NeedFunctionPrototypes
+ int /*result*/,
+ pointer /*pReadmask*/
+#endif
+);
+
+typedef void (* WakeupHandlerProcPtr)(
+#if NeedNestedPrototypes
+ pointer /* blockData */,
+ int /* result */,
+ pointer /* pReadmask */
+#endif
+);
+
+extern Bool RegisterBlockAndWakeupHandlers(
+#if NeedFunctionPrototypes
+ BlockHandlerProcPtr /*blockHandler*/,
+ WakeupHandlerProcPtr /*wakeupHandler*/,
+ pointer /*blockData*/
+#endif
+);
+
+extern void RemoveBlockAndWakeupHandlers(
+#if NeedFunctionPrototypes
+ BlockHandlerProcPtr /*blockHandler*/,
+ WakeupHandlerProcPtr /*wakeupHandler*/,
+ pointer /*blockData*/
+#endif
+);
+
+extern void InitBlockAndWakeupHandlers(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void ProcessWorkQueue(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern Bool QueueWorkProc(
+#if NeedFunctionPrototypes
+ Bool (* /*function*/)(
+#if NeedNestedPrototypes
+ ClientPtr /*clientUnused*/,
+ pointer /*closure*/
+#endif
+ ),
+ ClientPtr /*client*/,
+ pointer /*closure*/
+#endif
+);
+
+typedef Bool (* ClientSleepProcPtr)(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ pointer /*closure*/
+#endif
+);
+
+extern Bool ClientSleep(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ ClientSleepProcPtr /* function */,
+ pointer /*closure*/
+#endif
+);
+
+extern Bool ClientSignal(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern void ClientWakeup(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern Bool ClientIsAsleep(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+/* atom.c */
+
+extern Atom MakeAtom(
+#if NeedFunctionPrototypes
+ char * /*string*/,
+ unsigned /*len*/,
+ Bool /*makeit*/
+#endif
+);
+
+extern Bool ValidAtom(
+#if NeedFunctionPrototypes
+ Atom /*atom*/
+#endif
+);
+
+extern char *NameForAtom(
+#if NeedFunctionPrototypes
+ Atom /*atom*/
+#endif
+);
+
+extern void AtomError(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void FreeAllAtoms(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void InitAtoms(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+/* events.c */
+
+extern void SetMaskForEvent(
+#if NeedFunctionPrototypes
+ Mask /* mask */,
+ int /* event */
+#endif
+);
+
+#if 0
+extern Bool PointerConfinedToScreen(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+#endif
+
+extern Bool IsParent(
+#if NeedFunctionPrototypes
+ WindowPtr /* maybeparent */,
+ WindowPtr /* child */
+#endif
+);
+
+extern WindowPtr GetCurrentRootWindow(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern WindowPtr GetSpriteWindow(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+#if 0
+extern void GetSpritePosition(
+#if NeedFunctionPrototypes
+ int * /* px */,
+ int * /* py */
+#endif
+);
+#endif
+
+extern void NoticeEventTime(
+#if NeedFunctionPrototypes
+ xEventPtr /* xE */
+#endif
+);
+
+extern void EnqueueEvent(
+#if NeedFunctionPrototypes
+ xEventPtr /* xE */,
+ DeviceIntPtr /* device */,
+ int /* count */
+#endif
+);
+
+extern void ComputeFreezes(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void CheckGrabForSyncs(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* dev */,
+ Bool /* thisMode */,
+ Bool /* otherMode */
+#endif
+);
+
+extern void ActivatePointerGrab(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* mouse */,
+ GrabPtr /* grab */,
+ TimeStamp /* time */,
+ Bool /* autoGrab */
+#endif
+);
+
+extern void DeactivatePointerGrab(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* mouse */
+#endif
+);
+
+extern void ActivateKeyboardGrab(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* keybd */,
+ GrabPtr /* grab */,
+ TimeStamp /* time */,
+ Bool /* passive */
+#endif
+);
+
+extern void DeactivateKeyboardGrab(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* keybd */
+#endif
+);
+
+extern void AllowSome(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ TimeStamp /* time */,
+ DeviceIntPtr /* thisDev */,
+ int /* newState */
+#endif
+);
+
+extern void ReleaseActiveGrabs(
+#if NeedFunctionPrototypes
+ClientPtr client
+#endif
+);
+
+extern int DeliverEventsToWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */,
+ xEventPtr /* pEvents */,
+ int /* count */,
+ Mask /* filter */,
+ GrabPtr /* grab */,
+ int /* mskidx */
+#endif
+);
+
+extern int DeliverDeviceEvents(
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */,
+ xEventPtr /* xE */,
+ GrabPtr /* grab */,
+ WindowPtr /* stopAt */,
+ DeviceIntPtr /* dev */,
+ int /* count */
+#endif
+);
+
+extern void DefineInitialRootWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /* win */
+#endif
+);
+
+extern void WindowHasNewCursor(
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */
+#endif
+);
+
+extern Bool CheckDeviceGrabs(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* device */,
+ xEventPtr /* xE */,
+ int /* checkFirst */,
+ int /* count */
+#endif
+);
+
+extern void DeliverFocusedEvent(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* keybd */,
+ xEventPtr /* xE */,
+ WindowPtr /* window */,
+ int /* count */
+#endif
+);
+
+extern void DeliverGrabbedEvent(
+#if NeedFunctionPrototypes
+ xEventPtr /* xE */,
+ DeviceIntPtr /* thisDev */,
+ Bool /* deactivateGrab */,
+ int /* count */
+#endif
+);
+
+extern void RecalculateDeliverableEvents(
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */
+#endif
+);
+
+extern int OtherClientGone(
+#if NeedFunctionPrototypes
+ pointer /* value */,
+ XID /* id */
+#endif
+);
+
+extern void DoFocusEvents(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* dev */,
+ WindowPtr /* fromWin */,
+ WindowPtr /* toWin */,
+ int /* mode */
+#endif
+);
+
+extern int SetInputFocus(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ Window /* focusID */,
+ CARD8 /* revertTo */,
+ Time /* ctime */,
+ Bool /* followOK */
+#endif
+);
+
+extern int GrabDevice(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ unsigned /* this_mode */,
+ unsigned /* other_mode */,
+ Window /* grabWindow */,
+ unsigned /* ownerEvents */,
+ Time /* ctime */,
+ Mask /* mask */,
+ CARD8 * /* status */
+#endif
+);
+
+extern void InitEvents(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void DeleteWindowFromAnyEvents(
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */,
+ Bool /* freeResources */
+#endif
+);
+
+#if 0
+extern void CheckCursorConfinement(
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */
+#endif
+);
+#endif
+
+extern Mask EventMaskForClient(
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */,
+ ClientPtr /* client */
+#endif
+);
+
+
+
+extern int DeliverEvents(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ xEventPtr /*xE*/,
+ int /*count*/,
+ WindowPtr /*otherParent*/
+#endif
+);
+
+extern void WriteEventsToClient(
+#if NeedFunctionPrototypes
+ ClientPtr /*pClient*/,
+ int /*count*/,
+ xEventPtr /*events*/
+#endif
+);
+
+extern int TryClientEvents(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ xEventPtr /*pEvents*/,
+ int /*count*/,
+ Mask /*mask*/,
+ Mask /*filter*/,
+ GrabPtr /*grab*/
+#endif
+);
+
+extern int EventSelectForWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ ClientPtr /*client*/,
+ Mask /*mask*/
+#endif
+);
+
+extern int EventSuppressForWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ ClientPtr /*client*/,
+ Mask /*mask*/,
+ Bool * /*checkOptional*/
+#endif
+);
+
+extern int MaybeDeliverEventsToClient(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ xEventPtr /*pEvents*/,
+ int /*count*/,
+ Mask /*filter*/,
+ ClientPtr /*dontClient*/
+#endif
+);
+
+extern void WindowsRestructured(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void ResetClientPrivates(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern int AllocateClientPrivateIndex(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern Bool AllocateClientPrivate(
+#if NeedFunctionPrototypes
+ int /*index*/,
+ unsigned /*amount*/
+#endif
+);
+
+/*
+ * callback manager stuff
+ */
+
+#ifndef _XTYPEDEF_CALLBACKLISTPTR
+typedef struct _CallbackList *CallbackListPtr; /* also in misc.h */
+#define _XTYPEDEF_CALLBACKLISTPTR
+#endif
+
+typedef void (*CallbackProcPtr) (
+#if NeedNestedPrototypes
+ CallbackListPtr *, pointer, pointer
+#endif
+);
+
+typedef Bool (*AddCallbackProcPtr) (
+#if NeedNestedPrototypes
+ CallbackListPtr *, CallbackProcPtr, pointer
+#endif
+);
+
+typedef Bool (*DeleteCallbackProcPtr) (
+#if NeedNestedPrototypes
+ CallbackListPtr *, CallbackProcPtr, pointer
+#endif
+);
+
+typedef void (*CallCallbacksProcPtr) (
+#if NeedNestedPrototypes
+ CallbackListPtr *, pointer
+#endif
+);
+
+typedef void (*DeleteCallbackListProcPtr) (
+#if NeedNestedPrototypes
+ CallbackListPtr *
+#endif
+);
+
+typedef struct _CallbackProcs {
+ AddCallbackProcPtr AddCallback;
+ DeleteCallbackProcPtr DeleteCallback;
+ CallCallbacksProcPtr CallCallbacks;
+ DeleteCallbackListProcPtr DeleteCallbackList;
+} CallbackFuncsRec, *CallbackFuncsPtr;
+
+extern Bool CreateCallbackList(
+#if NeedFunctionPrototypes
+ CallbackListPtr * /*pcbl*/,
+ CallbackFuncsPtr /*cbfuncs*/
+#endif
+);
+
+extern Bool AddCallback(
+#if NeedFunctionPrototypes
+ CallbackListPtr * /*pcbl*/,
+ CallbackProcPtr /*callback*/,
+ pointer /*data*/
+#endif
+);
+
+extern Bool DeleteCallback(
+#if NeedFunctionPrototypes
+ CallbackListPtr * /*pcbl*/,
+ CallbackProcPtr /*callback*/,
+ pointer /*data*/
+#endif
+);
+
+extern void CallCallbacks(
+#if NeedFunctionPrototypes
+ CallbackListPtr * /*pcbl*/,
+ pointer /*call_data*/
+#endif
+);
+
+extern void DeleteCallbackList(
+#if NeedFunctionPrototypes
+ CallbackListPtr * /*pcbl*/
+#endif
+);
+
+extern void InitCallbackManager(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+/*
+ * ServerGrabCallback stuff
+ */
+
+extern CallbackListPtr ServerGrabCallback;
+
+typedef enum {SERVER_GRABBED, SERVER_UNGRABBED,
+ CLIENT_PERVIOUS, CLIENT_IMPERVIOUS } ServerGrabState;
+
+typedef struct {
+ ClientPtr client;
+ ServerGrabState grabstate;
+} ServerGrabInfoRec;
+
+/*
+ * EventCallback stuff
+ */
+
+extern CallbackListPtr EventCallback;
+
+typedef struct {
+ ClientPtr client;
+ xEventPtr events;
+ int count;
+} EventInfoRec;
+
+/*
+ * DeviceEventCallback stuff
+ */
+
+extern CallbackListPtr DeviceEventCallback;
+
+typedef struct {
+ xEventPtr events;
+ int count;
+} DeviceEventInfoRec;
+
+#endif /* DIX_H */
diff --git a/xc/programs/Xserver/include/dixevents.h b/xc/programs/Xserver/include/dixevents.h
new file mode 100644
index 000000000..957091bad
--- /dev/null
+++ b/xc/programs/Xserver/include/dixevents.h
@@ -0,0 +1,256 @@
+/* $XFree86: xc/programs/Xserver/include/dixevents.h,v 3.2 1996/12/24 02:27:27 dawes Exp $ */
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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 DIXEVENTS_H
+#define DIXEVENTS_H
+
+extern Mask
+GetNextEventMask(
+#if NeedFunctionPrototypes
+ void
+#endif
+ );
+
+extern void
+SetCriticalEvent(
+#if NeedFunctionPrototypes
+ int /* event */
+#endif
+ );
+
+extern void
+ConfineCursorToWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */,
+ Bool /* generateEvents */,
+ Bool /* confineToScreen */
+#endif
+ );
+
+extern CursorPtr
+GetSpriteCursor(
+#if NeedFunctionPrototypes
+ void
+#endif
+ );
+
+extern int
+ProcAllowEvents(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+extern int
+TryClientEvents (
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ xEvent * /* pEvents */,
+ int /* count */,
+ Mask /* mask */,
+ Mask /* filter */,
+ GrabPtr /* grab */
+#endif
+ );
+
+extern int
+MaybeDeliverEventsToClient(
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */,
+ xEvent * /* pEvents */,
+ int /* count */,
+ Mask /* filter */,
+ ClientPtr /* dontClient */
+#endif
+ );
+
+extern void
+WindowsRestructured(
+#if NeedFunctionPrototypes
+ void
+#endif
+ );
+
+extern void
+NewCurrentScreen(
+#if NeedFunctionPrototypes
+ ScreenPtr /* newScreen */,
+ int /* x */,
+ int /* y */
+#endif
+ );
+
+extern int
+ProcWarpPointer(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+extern void
+#ifdef XKB
+CoreProcessKeyboardEvent (
+#else
+ProcessKeyboardEvent (
+#endif
+#if NeedFunctionPrototypes
+ xEvent * /* xE */,
+ DeviceIntPtr /* keybd */,
+ int /* count */
+#endif
+ );
+
+extern void
+#ifdef XKB
+CoreProcessPointerEvent (
+#else
+ProcessPointerEvent (
+#endif
+#if NeedFunctionPrototypes
+ xEvent * /* xE */,
+ DeviceIntPtr /* mouse */,
+ int /* count */
+#endif
+ );
+
+extern int
+EventSelectForWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */,
+ ClientPtr /* client */,
+ Mask /* mask */
+#endif
+ );
+
+extern int
+EventSuppressForWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */,
+ ClientPtr /* client */,
+ Mask /* mask */,
+ Bool * /* checkOptional */
+#endif
+ );
+
+extern int
+ProcSetInputFocus(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+extern int
+ProcGetInputFocus(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+extern int
+ProcGrabPointer(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+extern int
+ProcChangeActivePointerGrab(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+extern int
+ProcUngrabPointer(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+extern int
+ProcGrabKeyboard(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+extern int
+ProcUngrabKeyboard(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+extern int
+ProcQueryPointer(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+extern int
+ProcSendEvent(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+extern int
+ProcUngrabKey(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+extern int
+ProcGrabKey(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+extern int
+ProcGrabButton(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+extern int
+ProcUngrabButton(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+extern int
+ProcRecolorCursor(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+#endif /* DIXEVENTS_H */
diff --git a/xc/programs/Xserver/include/dixfont.h b/xc/programs/Xserver/include/dixfont.h
new file mode 100644
index 000000000..89202698f
--- /dev/null
+++ b/xc/programs/Xserver/include/dixfont.h
@@ -0,0 +1,163 @@
+/* $XConsortium: dixfont.h /main/21 1996/09/28 17:14:16 rws $ */
+/***********************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/include/dixfont.h,v 3.5 1999/08/21 13:48:44 dawes Exp $ */
+
+#ifndef DIXFONT_H
+#define DIXFONT_H 1
+
+#include "dix.h"
+#include "font.h"
+#include "closure.h"
+#include "fontstruct.h"
+
+#define NullDIXFontProp ((DIXFontPropPtr)0)
+
+typedef struct _DIXFontProp *DIXFontPropPtr;
+
+extern FPEFunctions *fpe_functions;
+
+extern int FontToXError(int /*err*/);
+
+extern Bool SetDefaultFont(char * /*defaultfontname*/);
+
+extern void QueueFontWakeup(FontPathElementPtr /*fpe*/);
+
+extern void RemoveFontWakeup(FontPathElementPtr /*fpe*/);
+
+extern void FontWakeup(pointer /*data*/,
+ int /*count*/,
+ pointer /*LastSelectMask*/);
+
+extern int OpenFont(ClientPtr /*client*/,
+ XID /*fid*/,
+ Mask /*flags*/,
+ unsigned /*lenfname*/,
+ char * /*pfontname*/);
+
+extern int CloseFont(pointer /*pfont*/,
+ XID /*fid*/);
+
+typedef struct _xQueryFontReply *xQueryFontReplyPtr;
+
+extern void QueryFont(FontPtr /*pFont*/,
+ xQueryFontReplyPtr /*pReply*/,
+ int /*nProtoCCIStructs*/);
+
+extern int ListFonts(ClientPtr /*client*/,
+ unsigned char * /*pattern*/,
+ unsigned int /*length*/,
+ unsigned int /*max_names*/);
+
+int
+doListFontsWithInfo(ClientPtr /*client*/,
+ LFWIclosurePtr /*c*/);
+
+extern int doPolyText(ClientPtr /*client*/,
+ PTclosurePtr /*c*/
+);
+
+extern int PolyText(ClientPtr /*client*/,
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ unsigned char * /*pElt*/,
+ unsigned char * /*endReq*/,
+ int /*xorg*/,
+ int /*yorg*/,
+ int /*reqType*/,
+ XID /*did*/);
+
+extern int doImageText(ClientPtr /*client*/,
+ ITclosurePtr /*c*/);
+
+extern int ImageText(ClientPtr /*client*/,
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*nChars*/,
+ unsigned char * /*data*/,
+ int /*xorg*/,
+ int /*yorg*/,
+ int /*reqType*/,
+ XID /*did*/);
+
+extern int SetFontPath(ClientPtr /*client*/,
+ int /*npaths*/,
+ unsigned char * /*paths*/,
+ int * /*error*/);
+
+extern int SetDefaultFontPath(char * /*path*/);
+
+extern unsigned char *GetFontPath(int * /*count*/,
+ int * /*length*/);
+
+extern int LoadGlyphs(ClientPtr /*client*/,
+ FontPtr /*pfont*/,
+ unsigned /*nchars*/,
+ int /*item_size*/,
+ unsigned char * /*data*/);
+
+extern void DeleteClientFontStuff(ClientPtr /*client*/);
+
+extern void InitFonts(void);
+
+extern int GetDefaultPointSize(void);
+
+extern void FreeFonts(void);
+
+extern FontPtr find_old_font(XID /*id*/);
+
+extern Font GetNewFontClientID(void);
+
+extern int StoreFontClientFont(FontPtr /*pfont*/,
+ Font /*id*/);
+
+extern void DeleteFontClientID(Font /*id*/);
+
+
+extern void GetGlyphs(FontPtr /*font*/,
+ unsigned long /*count*/,
+ unsigned char * /*chars*/,
+ FontEncoding /*fontEncoding*/,
+ unsigned long * /*glyphcount*/,
+ CharInfoPtr * /*glyphs*/);
+
+extern void QueryGlyphExtents(FontPtr /*pFont*/,
+ CharInfoPtr * /*charinfo*/,
+ unsigned long /*count*/,
+ ExtentInfoPtr /*info*/);
+
+extern Bool QueryTextExtents(FontPtr /*pFont*/,
+ unsigned long /*count*/,
+ unsigned char * /*chars*/,
+ ExtentInfoPtr /*info*/);
+
+extern Bool ParseGlyphCachingMode(char * /*str*/);
+
+extern void InitGlyphCaching(void);
+
+extern void SetGlyphCachingMode(int /*newmode*/);
+
+extern void
+ResetFontPrivateIndex(void);
+
+#endif /* DIXFONT_H */
diff --git a/xc/programs/Xserver/include/dixfontstr.h b/xc/programs/Xserver/include/dixfontstr.h
new file mode 100644
index 000000000..280020410
--- /dev/null
+++ b/xc/programs/Xserver/include/dixfontstr.h
@@ -0,0 +1,95 @@
+/* $XConsortium: dixfontstr.h,v 1.15 94/04/17 20:25:39 dpw Exp $ */
+/***********************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#ifndef DIXFONTSTRUCT_H
+#define DIXFONTSTRUCT_H
+
+#include "servermd.h"
+#include "dixfont.h"
+#include "fontstruct.h"
+#include "closure.h"
+#define NEED_REPLIES
+#include "X11/Xproto.h" /* for xQueryFontReply */
+
+#define FONTCHARSET(font) (font)
+#define FONTMAXBOUNDS(font,field) (font)->info.maxbounds.field
+#define FONTMINBOUNDS(font,field) (font)->info.minbounds.field
+#define TERMINALFONT(font) (font)->info.terminalFont
+#define FONTASCENT(font) (font)->info.fontAscent
+#define FONTDESCENT(font) (font)->info.fontDescent
+#define FONTGLYPHS(font) 0
+#define FONTCONSTMETRICS(font) (font)->info.constantMetrics
+#define FONTCONSTWIDTH(font) (font)->info.constantWidth
+#define FONTALLEXIST(font) (font)->info.allExist
+#define FONTFIRSTCOL(font) (font)->info.firstCol
+#define FONTLASTCOL(font) (font)->info.lastCol
+#define FONTFIRSTROW(font) (font)->info.firstRow
+#define FONTLASTROW(font) (font)->info.lastRow
+#define FONTDEFAULTCH(font) (font)->info.defaultCh
+#define FONTINKMIN(font) (&((font)->info.ink_minbounds))
+#define FONTINKMAX(font) (&((font)->info.ink_maxbounds))
+#define FONTPROPS(font) (font)->info.props
+#define FONTGLYPHBITS(base,pci) ((unsigned char *) (pci)->bits)
+#define FONTINFONPROPS(font) (font)->info.nprops
+
+/* some things haven't changed names, but we'll be careful anyway */
+
+#define FONTREFCNT(font) (font)->refcnt
+
+/*
+ * for linear char sets
+ */
+#define N1dChars(pfont) (FONTLASTCOL(pfont) - FONTFIRSTCOL(pfont) + 1)
+
+/*
+ * for 2D char sets
+ */
+#define N2dChars(pfont) (N1dChars(pfont) * \
+ (FONTLASTROW(pfont) - FONTFIRSTROW(pfont) + 1))
+
+#ifndef GLYPHPADBYTES
+#define GLYPHPADBYTES -1
+#endif
+
+#if GLYPHPADBYTES == 0 || GLYPHPADBYTES == 1
+#define GLYPHWIDTHBYTESPADDED(pci) (GLYPHWIDTHBYTES(pci))
+#define PADGLYPHWIDTHBYTES(w) (((w)+7)>>3)
+#endif
+
+#if GLYPHPADBYTES == 2
+#define GLYPHWIDTHBYTESPADDED(pci) ((GLYPHWIDTHBYTES(pci)+1) & ~0x1)
+#define PADGLYPHWIDTHBYTES(w) (((((w)+7)>>3)+1) & ~0x1)
+#endif
+
+#if GLYPHPADBYTES == 4
+#define GLYPHWIDTHBYTESPADDED(pci) ((GLYPHWIDTHBYTES(pci)+3) & ~0x3)
+#define PADGLYPHWIDTHBYTES(w) (((((w)+7)>>3)+3) & ~0x3)
+#endif
+
+#if GLYPHPADBYTES == 8 /* for a cray? */
+#define GLYPHWIDTHBYTESPADDED(pci) ((GLYPHWIDTHBYTES(pci)+7) & ~0x7)
+#define PADGLYPHWIDTHBYTES(w) (((((w)+7)>>3)+7) & ~0x7)
+#endif
+
+#endif /* DIXFONTSTRUCT_H */
diff --git a/xc/programs/Xserver/include/dixgrabs.h b/xc/programs/Xserver/include/dixgrabs.h
new file mode 100644
index 000000000..5c3fc7fa0
--- /dev/null
+++ b/xc/programs/Xserver/include/dixgrabs.h
@@ -0,0 +1,79 @@
+/* $XFree86: xc/programs/Xserver/include/dixgrabs.h,v 3.0 1996/04/15 11:34:27 dawes Exp $ */
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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 DIXGRABS_H
+#define DIXGRABS_H 1
+
+GrabPtr
+CreateGrab(
+#if NeedFunctionPrototypes
+ int /* client */,
+ DeviceIntPtr /* device */,
+ WindowPtr /* window */,
+ Mask /* eventMask */,
+ Bool /* ownerEvents */,
+ Bool /* keyboardMode */,
+ Bool /* pointerMode */,
+ DeviceIntPtr /* modDevice */,
+ unsigned short /* modifiers */,
+ int /* type */,
+ KeyCode /* keybut */,
+ WindowPtr /* confineTo */,
+ CursorPtr /* cursor */
+#endif
+ );
+
+int
+DeletePassiveGrab(
+#if NeedFunctionPrototypes
+ pointer /* value */,
+ XID /* id */
+#endif
+ );
+
+Bool
+GrabMatchesSecond(
+#if NeedFunctionPrototypes
+ GrabPtr /* pFirstGrab */,
+ GrabPtr /* pSecondGrab */
+#endif
+ );
+
+int
+AddPassiveGrabToList(
+#if NeedFunctionPrototypes
+ GrabPtr /* pGrab */
+#endif
+ );
+
+Bool
+DeletePassiveGrabFromList(
+#if NeedFunctionPrototypes
+ GrabPtr /* pMinuendGrab */
+#endif
+ );
+
+#endif /* DIXGRABS_H */
diff --git a/xc/programs/Xserver/include/dixstruct.h b/xc/programs/Xserver/include/dixstruct.h
new file mode 100644
index 000000000..fc1dd3638
--- /dev/null
+++ b/xc/programs/Xserver/include/dixstruct.h
@@ -0,0 +1,237 @@
+/***********************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: dixstruct.h /main/43 1996/12/15 21:25:06 rws $ */
+/* $XFree86: xc/programs/Xserver/include/dixstruct.h,v 3.9 1998/07/26 02:33:02 dawes Exp $ */
+
+#ifndef DIXSTRUCT_H
+#define DIXSTRUCT_H
+
+#include "dix.h"
+#include "resource.h"
+#include "cursor.h"
+#include "gc.h"
+#include "pixmap.h"
+#include <X11/Xmd.h>
+
+/*
+ * direct-mapped hash table, used by resource manager to store
+ * translation from client ids to server addresses.
+ */
+
+#ifdef DEBUG
+#define MAX_REQUEST_LOG 100
+#endif
+
+extern CallbackListPtr ClientStateCallback;
+
+typedef struct {
+ ClientPtr client;
+ xConnSetupPrefix *prefix;
+ xConnSetup *setup;
+} NewClientInfoRec;
+
+typedef void (*ReplySwapPtr) (
+#if NeedNestedPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ void * /* pbuf */
+#endif
+);
+
+extern void ReplyNotSwappd (
+#if NeedNestedPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ void * /* pbuf */
+#endif
+);
+
+typedef enum {ClientStateInitial,
+ ClientStateAuthenticating,
+ ClientStateRunning,
+ ClientStateRetained,
+ ClientStateGone,
+ ClientStateCheckingSecurity,
+ ClientStateCheckedSecurity} ClientState;
+
+typedef struct _Client {
+ int index;
+ Mask clientAsMask;
+ pointer requestBuffer;
+ pointer osPrivate; /* for OS layer, including scheduler */
+ Bool swapped;
+ ReplySwapPtr pSwapReplyFunc;
+ XID errorValue;
+ int sequence;
+ int closeDownMode;
+ int clientGone;
+ int noClientException; /* this client died or needs to be
+ * killed */
+ DrawablePtr lastDrawable;
+ Drawable lastDrawableID;
+ GCPtr lastGC;
+ GContext lastGCID;
+ pointer *saveSet;
+ int numSaved;
+ pointer screenPrivate[MAXSCREENS];
+ int (**requestVector) (
+#if NeedNestedPrototypes
+ ClientPtr /* pClient */
+#endif
+);
+ CARD32 req_len; /* length of current request */
+ Bool big_requests; /* supports large requests */
+ int priority;
+ ClientState clientState;
+ DevUnion *devPrivates;
+#ifdef XKB
+ unsigned short xkbClientFlags;
+ unsigned short mapNotifyMask;
+ unsigned short newKeyboardNotifyMask;
+ unsigned short vMajor,vMinor;
+ KeyCode minKC,maxKC;
+#endif
+
+#ifdef DEBUG
+ unsigned char requestLog[MAX_REQUEST_LOG];
+ int requestLogIndex;
+#endif
+#ifdef LBX
+ int (*readRequest)(
+#if NeedNestedPrototypes
+ ClientPtr /*client*/
+#endif
+);
+#endif
+ unsigned long replyBytesRemaining;
+#ifdef XCSECURITY
+ XID authId;
+ unsigned int trustLevel;
+ pointer (* CheckAccess)(
+#if NeedNestedPrototypes
+ ClientPtr /*pClient*/,
+ XID /*id*/,
+ RESTYPE /*classes*/,
+ Mask /*access_mode*/,
+ pointer /*resourceval*/
+#endif
+);
+#endif
+#ifdef XAPPGROUP
+ struct _AppGroupRec* appgroup;
+#endif
+ struct _FontResolution * (*fontResFunc) ( /* no need for font.h */
+#if NeedNestedPrototypes
+ ClientPtr /* pClient */,
+ int * /* num */
+#endif
+);
+} ClientRec;
+
+/* This prototype is used pervasively in Xext, dix */
+#if NeedFunctionPrototypes
+#define DISPATCH_PROC(func) int func(ClientPtr /* client */)
+#else
+#define DISPATCH_PROC(func) int func(/* ClientPtr client */)
+#endif
+
+typedef struct _WorkQueue {
+ struct _WorkQueue *next;
+ Bool (*function) (
+#if NeedNestedPrototypes
+ ClientPtr /* pClient */,
+ pointer /* closure */
+#endif
+);
+ ClientPtr client;
+ pointer closure;
+} WorkQueueRec;
+
+extern TimeStamp currentTime;
+extern TimeStamp lastDeviceEventTime;
+
+extern int CompareTimeStamps(
+#if NeedFunctionPrototypes
+ TimeStamp /*a*/,
+ TimeStamp /*b*/
+#endif
+);
+
+extern TimeStamp ClientTimeToServerTime(
+#if NeedFunctionPrototypes
+ CARD32 /*c*/
+#endif
+);
+
+typedef struct _CallbackRec {
+ CallbackProcPtr proc;
+ pointer data;
+ Bool deleted;
+ struct _CallbackRec *next;
+} CallbackRec, *CallbackPtr;
+
+typedef struct _CallbackList {
+ CallbackFuncsRec funcs;
+ int inCallback;
+ Bool deleted;
+ int numDeleted;
+ CallbackPtr list;
+} CallbackListRec;
+
+/* proc vectors */
+
+extern int (* InitialVector[3]) (
+#if NeedNestedPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern int (* ProcVector[256]) (
+#if NeedNestedPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern int (* SwappedProcVector[256]) (
+#if NeedNestedPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+#ifdef K5AUTH
+extern int (*k5_Vector[256])() =
+#if NeedNestedPrototypes
+ ClientPtr /*client*/
+#endif
+);
+#endif
+
+extern ReplySwapPtr ReplySwapVector[256];
+
+extern int ProcBadRequest(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+#endif /* DIXSTRUCT_H */
diff --git a/xc/programs/Xserver/include/exevents.h b/xc/programs/Xserver/include/exevents.h
new file mode 100644
index 000000000..2ad79aa10
--- /dev/null
+++ b/xc/programs/Xserver/include/exevents.h
@@ -0,0 +1,275 @@
+/* $XFree86: xc/programs/Xserver/include/exevents.h,v 3.1 1996/04/15 11:34:29 dawes Exp $ */
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+/********************************************************************
+ * Interface of 'exevents.c'
+ */
+
+#ifndef EXEVENTS_H
+#define EXEVENTS_H
+
+void
+RegisterOtherDevice (
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* device */
+#endif
+ );
+
+void
+ProcessOtherEvent (
+#if NeedFunctionPrototypes
+ xEventPtr /* FIXME deviceKeyButtonPointer * xE */,
+ DeviceIntPtr /* other */,
+ int /* count */
+#endif
+ );
+
+int
+InitProximityClassDeviceStruct(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* dev */
+#endif
+ );
+
+void
+InitValuatorAxisStruct(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* dev */,
+ int /* axnum */,
+ int /* minval */,
+ int /* maxval */,
+ int /* resolution */,
+ int /* min_res */,
+ int /* max_res */
+#endif
+ );
+
+void
+DeviceFocusEvent(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* dev */,
+ int /* type */,
+ int /* mode */,
+ int /* detail */,
+ WindowPtr /* pWin */
+#endif
+ );
+
+int
+GrabButton(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ BYTE /* this_device_mode */,
+ BYTE /* other_devices_mode */,
+ CARD16 /* modifiers */,
+ DeviceIntPtr /* modifier_device */,
+ CARD8 /* button */,
+ Window /* grabWindow */,
+ BOOL /* ownerEvents */,
+ Cursor /* rcursor */,
+ Window /* rconfineTo */,
+ Mask /* eventMask */
+#endif
+ );
+
+int
+GrabKey(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ BYTE /* this_device_mode */,
+ BYTE /* other_devices_mode */,
+ CARD16 /* modifiers */,
+ DeviceIntPtr /* modifier_device */,
+ CARD8 /* key */,
+ Window /* grabWindow */,
+ BOOL /* ownerEvents */,
+ Mask /* mask */
+#endif
+ );
+
+int
+SelectForWindow(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* dev */,
+ WindowPtr /* pWin */,
+ ClientPtr /* client */,
+ Mask /* mask */,
+ Mask /* exclusivemasks */,
+ Mask /* validmasks */
+#endif
+ );
+
+int
+AddExtensionClient (
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */,
+ ClientPtr /* client */,
+ Mask /* mask */,
+ int /* mskidx */
+#endif
+ );
+
+void
+RecalculateDeviceDeliverableEvents(
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */
+#endif
+ );
+
+int
+InputClientGone(
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */,
+ XID /* id */
+#endif
+ );
+
+int
+SendEvent (
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ DeviceIntPtr /* d */,
+ Window /* dest */,
+ Bool /* propagate */,
+ xEvent * /* ev */,
+ Mask /* mask */,
+ int /* count */
+#endif
+ );
+
+int
+SetButtonMapping (
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ int /* nElts */,
+ BYTE * /* map */
+#endif
+ );
+
+int
+SetModifierMapping(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ int /* len */,
+ int /* rlen */,
+ int /* numKeyPerModifier */,
+ KeyCode * /* inputMap */,
+ KeyClassPtr * /* k */
+#endif
+ );
+
+void
+SendDeviceMappingNotify(
+#if NeedFunctionPrototypes
+ CARD8 /* request, */,
+ KeyCode /* firstKeyCode */,
+ CARD8 /* count */,
+ DeviceIntPtr /* dev */
+#endif
+);
+
+int
+ChangeKeyMapping(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ DeviceIntPtr /* dev */,
+ unsigned /* len */,
+ int /* type */,
+ KeyCode /* firstKeyCode */,
+ CARD8 /* keyCodes */,
+ CARD8 /* keySymsPerKeyCode */,
+ KeySym * /* map */
+#endif
+ );
+
+void
+DeleteWindowFromAnyExtEvents(
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */,
+ Bool /* freeResources */
+#endif
+);
+
+void
+DeleteDeviceFromAnyExtEvents(
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */,
+ DeviceIntPtr /* dev */
+#endif
+ );
+
+int
+MaybeSendDeviceMotionNotifyHint (
+#if NeedFunctionPrototypes
+ deviceKeyButtonPointer * /* pEvents */,
+ Mask /* mask */
+#endif
+);
+
+void
+CheckDeviceGrabAndHintWindow (
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */,
+ int /* type */,
+ deviceKeyButtonPointer * /* xE */,
+ GrabPtr /* grab */,
+ ClientPtr /* client */,
+ Mask /* deliveryMask */
+#endif
+ );
+
+Mask
+DeviceEventMaskForClient(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* dev */,
+ WindowPtr /* pWin */,
+ ClientPtr /* client */
+#endif
+);
+
+void
+MaybeStopDeviceHint(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* dev */,
+ ClientPtr /* client */
+#endif
+ );
+
+int
+DeviceEventSuppressForWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /* pWin */,
+ ClientPtr /* client */,
+ Mask /* mask */,
+ int /* maskndx */
+#endif
+ );
+
+#endif /* EXEVENTS_H */
diff --git a/xc/programs/Xserver/include/extension.h b/xc/programs/Xserver/include/extension.h
new file mode 100644
index 000000000..99f07f021
--- /dev/null
+++ b/xc/programs/Xserver/include/extension.h
@@ -0,0 +1,80 @@
+/* $TOG: extension.h /main/10 1998/02/09 14:28:37 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/include/extension.h,v 1.3 1999/04/11 15:28:09 dawes Exp $ */
+
+#ifndef EXTENSION_H
+#define EXTENSION_H
+
+_XFUNCPROTOBEGIN
+
+extern unsigned short StandardMinorOpcode(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern unsigned short MinorOpcodeOfRequest(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern void InitExtensions(
+#if NeedFunctionPrototypes
+ int argc,
+ char **argv
+#endif
+);
+
+extern void InitVisualWrap(void);
+
+extern void CloseDownExtensions(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+_XFUNCPROTOEND
+
+#endif /* EXTENSION_H */
diff --git a/xc/programs/Xserver/include/extinit.h b/xc/programs/Xserver/include/extinit.h
new file mode 100644
index 000000000..6364f1826
--- /dev/null
+++ b/xc/programs/Xserver/include/extinit.h
@@ -0,0 +1,210 @@
+/* $XFree86: xc/programs/Xserver/include/extinit.h,v 3.1 1996/04/15 11:34:30 dawes Exp $ */
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+
+********************************************************/
+
+/********************************************************************
+ * Interface of extinit.c
+ */
+
+#ifndef EXTINIT_H
+#define EXTINIT_H
+
+void
+XInputExtensionInit(
+#if NeedFunctionPrototypes
+ void
+#endif
+ );
+
+
+int
+ProcIDispatch (
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+int
+SProcIDispatch(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+ );
+
+void
+SReplyIDispatch (
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ int /* len */,
+ xGrabDeviceReply * /* rep */
+#endif
+ );
+
+void
+SEventIDispatch (
+#if NeedFunctionPrototypes
+ xEvent * /* from */,
+ xEvent * /* to */
+#endif
+ );
+
+void
+SEventDeviceValuator (
+#if NeedFunctionPrototypes
+ deviceValuator * /* from */,
+ deviceValuator * /* to */
+#endif
+ );
+
+void
+SEventFocus (
+#if NeedFunctionPrototypes
+ deviceFocus * /* from */,
+ deviceFocus * /* to */
+#endif
+ );
+
+void
+SDeviceStateNotifyEvent (
+#if NeedFunctionPrototypes
+ deviceStateNotify * /* from */,
+ deviceStateNotify * /* to */
+#endif
+ );
+
+void
+SDeviceKeyStateNotifyEvent (
+#if NeedFunctionPrototypes
+ deviceKeyStateNotify * /* from */,
+ deviceKeyStateNotify * /* to */
+#endif
+ );
+
+void
+SDeviceButtonStateNotifyEvent (
+#if NeedFunctionPrototypes
+ deviceButtonStateNotify * /* from */,
+ deviceButtonStateNotify * /* to */
+#endif
+ );
+
+void
+SChangeDeviceNotifyEvent (
+#if NeedFunctionPrototypes
+ changeDeviceNotify * /* from */,
+ changeDeviceNotify * /* to */
+#endif
+ );
+
+void
+SDeviceMappingNotifyEvent (
+#if NeedFunctionPrototypes
+ deviceMappingNotify * /* from */,
+ deviceMappingNotify * /* to */
+#endif
+ );
+
+void
+FixExtensionEvents (
+#if NeedFunctionPrototypes
+ ExtensionEntry * /* extEntry */
+#endif
+ );
+
+void
+RestoreExtensionEvents (
+#if NeedFunctionPrototypes
+ void
+#endif
+ );
+
+void
+IResetProc(
+#if NeedFunctionPrototypes
+ ExtensionEntry * /* unused */
+#endif
+ );
+
+void
+AssignTypeAndName (
+#if NeedFunctionPrototypes
+ DeviceIntPtr /* dev */,
+ Atom /* type */,
+ char * /* name */
+#endif
+ );
+
+void
+MakeDeviceTypeAtoms (
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+DeviceIntPtr
+LookupDeviceIntRec (
+#if NeedFunctionPrototypes
+ CARD8 /* id */
+#endif
+ );
+
+void
+SetExclusiveAccess (
+#if NeedFunctionPrototypes
+ Mask /* mask */
+#endif
+ );
+
+void
+AllowPropagateSuppress (
+#if NeedFunctionPrototypes
+ Mask /* mask */
+#endif
+ );
+
+Mask
+GetNextExtEventMask (
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+void
+SetMaskForExtEvent(
+#if NeedFunctionPrototypes
+ Mask /* mask */,
+ int /* event */
+#endif
+ );
+
+void
+SetEventInfo(
+#if NeedFunctionPrototypes
+ Mask /* mask */,
+ int /* constant */
+#endif
+ );
+
+#endif /* EXTINIT_H */
diff --git a/xc/programs/Xserver/include/extnsionst.h b/xc/programs/Xserver/include/extnsionst.h
new file mode 100644
index 000000000..a04056ed4
--- /dev/null
+++ b/xc/programs/Xserver/include/extnsionst.h
@@ -0,0 +1,190 @@
+/* $TOG: extnsionst.h /main/16 1998/02/09 14:28:41 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/include/extnsionst.h,v 3.3 1998/10/04 09:38:56 dawes Exp $ */
+
+#ifndef EXTENSIONSTRUCT_H
+#define EXTENSIONSTRUCT_H
+
+#include "misc.h"
+#include "screenint.h"
+#include "extension.h"
+#include "gc.h"
+
+typedef struct _ExtensionEntry {
+ int index;
+ void (* CloseDown)( /* called at server shutdown */
+#if NeedNestedPrototypes
+ struct _ExtensionEntry * /* extension */
+#endif
+);
+ char *name; /* extension name */
+ int base; /* base request number */
+ int eventBase;
+ int eventLast;
+ int errorBase;
+ int errorLast;
+ int num_aliases;
+ char **aliases;
+ pointer extPrivate;
+ unsigned short (* MinorOpcode)( /* called for errors */
+#if NeedNestedPrototypes
+ ClientPtr /* client */
+#endif
+);
+#ifdef XCSECURITY
+ Bool secure; /* extension visible to untrusted clients? */
+#endif
+} ExtensionEntry;
+
+/* any attempt to declare the types of the parameters to the functions
+ * in EventSwapVector fails. The functions take pointers to two events,
+ * but the exact event types that are declared vary from one function
+ * to another. You can't even put void *, void * (the ibm compiler
+ * complains, anyway).
+ */
+typedef void (*EventSwapPtr) (
+#if NeedFunctionPrototypes && defined(EVENT_SWAP_PTR)
+ xEvent *,
+ xEvent *
+#endif
+);
+
+extern EventSwapPtr EventSwapVector[128];
+
+extern void NotImplemented ( /* FIXME: this may move to another file... */
+#if NeedFunctionPrototypes && defined(EVENT_SWAP_PTR)
+ xEvent *,
+ xEvent *
+#endif
+);
+
+typedef void (* ExtensionLookupProc)( /*args indeterminate*/
+#ifdef EXTENSION_PROC_ARGS
+ EXTENSION_PROC_ARGS
+#endif
+);
+
+typedef struct _ProcEntry {
+ char *name;
+ ExtensionLookupProc proc;
+} ProcEntryRec, *ProcEntryPtr;
+
+typedef struct _ScreenProcEntry {
+ int num;
+ ProcEntryPtr procList;
+} ScreenProcEntry;
+
+#define SetGCVector(pGC, VectorElement, NewRoutineAddress, Atom) \
+ pGC->VectorElement = NewRoutineAddress;
+
+#define GetGCValue(pGC, GCElement) (pGC->GCElement)
+
+
+extern ExtensionEntry *AddExtension(
+#if NeedFunctionPrototypes
+ char* /*name*/,
+ int /*NumEvents*/,
+ int /*NumErrors*/,
+ int (* /*MainProc*/)(
+#if NeedNestedPrototypes
+ ClientPtr /*client*/
+#endif
+),
+ int (* /*SwappedMainProc*/)(
+#if NeedNestedPrototypes
+ ClientPtr /*client*/
+#endif
+),
+ void (* /*CloseDownProc*/)(
+#if NeedNestedPrototypes
+ ExtensionEntry * /*extension*/
+#endif
+),
+ unsigned short (* /*MinorOpcodeProc*/)(
+#if NeedNestedPrototypes
+ ClientPtr /*client*/
+#endif
+ )
+#endif /* NeedFunctionPrototypes */
+);
+
+extern Bool AddExtensionAlias(
+#if NeedFunctionPrototypes
+ char* /*alias*/,
+ ExtensionEntry * /*extension*/
+#endif
+);
+
+extern ExtensionLookupProc LookupProc(
+#if NeedFunctionPrototypes
+ char* /*name*/,
+ GCPtr /*pGC*/
+#endif
+);
+
+extern Bool RegisterProc(
+#if NeedFunctionPrototypes
+ char* /*name*/,
+ GCPtr /*pGC*/,
+ ExtensionLookupProc /*proc*/
+#endif
+);
+
+extern Bool RegisterScreenProc(
+#if NeedFunctionPrototypes
+ char* /*name*/,
+ ScreenPtr /*pScreen*/,
+ ExtensionLookupProc /*proc*/
+#endif
+);
+
+extern void DeclareExtensionSecurity(
+#if NeedFunctionPrototypes
+ char * /*extname*/,
+ Bool /*secure*/
+#endif
+);
+
+#endif /* EXTENSIONSTRUCT_H */
+
diff --git a/xc/programs/Xserver/include/gc.h b/xc/programs/Xserver/include/gc.h
new file mode 100644
index 000000000..94d551a00
--- /dev/null
+++ b/xc/programs/Xserver/include/gc.h
@@ -0,0 +1,228 @@
+/* $XFree86: xc/programs/Xserver/include/gc.h,v 1.3 1999/08/22 08:59:01 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: gc.h /main/17 1998/02/09 14:28:50 kaleb $ */
+
+#ifndef GC_H
+#define GC_H
+
+#include "X11/X.h" /* for GContext, Mask */
+#include "Xdefs.h" /* for Bool */
+#include "X11/Xproto.h"
+#include "screenint.h" /* for ScreenPtr */
+#include "pixmap.h" /* for DrawablePtr */
+
+/* clientClipType field in GC */
+#define CT_NONE 0
+#define CT_PIXMAP 1
+#define CT_REGION 2
+#define CT_UNSORTED 6
+#define CT_YSORTED 10
+#define CT_YXSORTED 14
+#define CT_YXBANDED 18
+
+#define GCQREASON_VALIDATE 1
+#define GCQREASON_CHANGE 2
+#define GCQREASON_COPY_SRC 3
+#define GCQREASON_COPY_DST 4
+#define GCQREASON_DESTROY 5
+
+#define GC_CHANGE_SERIAL_BIT (((unsigned long)1)<<31)
+#define GC_CALL_VALIDATE_BIT (1L<<30)
+#define GCExtensionInterest (1L<<29)
+
+#define DRAWABLE_SERIAL_BITS (~(GC_CHANGE_SERIAL_BIT))
+
+#define MAX_SERIAL_NUM (1L<<28)
+
+#define NEXT_SERIAL_NUMBER ((++globalSerialNumber) > MAX_SERIAL_NUM ? \
+ (globalSerialNumber = 1): globalSerialNumber)
+
+typedef struct _GCInterest *GCInterestPtr;
+typedef struct _GC *GCPtr;
+typedef struct _GCOps *GCOpsPtr;
+
+extern void ValidateGC(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/
+#endif
+);
+
+extern int ChangeGC(
+#if NeedFunctionPrototypes
+ GCPtr/*pGC*/,
+ BITS32 /*mask*/,
+ XID* /*pval*/
+#endif
+);
+
+extern int DoChangeGC(
+#if NeedFunctionPrototypes
+ GCPtr/*pGC*/,
+ BITS32 /*mask*/,
+ XID* /*pval*/,
+ int /*fPointer*/
+#endif
+);
+
+typedef union {
+ CARD32 val;
+ pointer ptr;
+} ChangeGCVal, *ChangeGCValPtr;
+
+extern int dixChangeGC(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ GCPtr /*pGC*/,
+ BITS32 /*mask*/,
+ CARD32 * /*pval*/,
+ ChangeGCValPtr /*pCGCV*/
+#endif
+);
+
+extern GCPtr CreateGC(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ BITS32 /*mask*/,
+ XID* /*pval*/,
+ int* /*pStatus*/
+#endif
+);
+
+extern int CopyGC(
+#if NeedFunctionPrototypes
+ GCPtr/*pgcSrc*/,
+ GCPtr/*pgcDst*/,
+ BITS32 /*mask*/
+#endif
+);
+
+extern int FreeGC(
+#if NeedFunctionPrototypes
+ pointer /*pGC*/,
+ XID /*gid*/
+#endif
+);
+
+extern void SetGCMask(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/,
+ Mask /*selectMask*/,
+ Mask /*newDataMask*/
+#endif
+);
+
+extern GCPtr CreateScratchGC(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ unsigned /*depth*/
+#endif
+);
+
+extern void FreeGCperDepth(
+#if NeedFunctionPrototypes
+ int /*screenNum*/
+#endif
+);
+
+extern Bool CreateGCperDepth(
+#if NeedFunctionPrototypes
+ int /*screenNum*/
+#endif
+);
+
+extern Bool CreateDefaultStipple(
+#if NeedFunctionPrototypes
+ int /*screenNum*/
+#endif
+);
+
+extern void FreeDefaultStipple(
+#if NeedFunctionPrototypes
+ int /*screenNum*/
+#endif
+);
+
+extern int SetDashes(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/,
+ unsigned /*offset*/,
+ unsigned /*ndash*/,
+ unsigned char* /*pdash*/
+#endif
+);
+
+extern int VerifyRectOrder(
+#if NeedFunctionPrototypes
+ int /*nrects*/,
+ xRectangle* /*prects*/,
+ int /*ordering*/
+#endif
+);
+
+extern int SetClipRects(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/,
+ int /*xOrigin*/,
+ int /*yOrigin*/,
+ int /*nrects*/,
+ xRectangle* /*prects*/,
+ int /*ordering*/
+#endif
+);
+
+extern GCPtr GetScratchGC(
+#if NeedFunctionPrototypes
+ unsigned /*depth*/,
+ ScreenPtr /*pScreen*/
+#endif
+);
+
+extern void FreeScratchGC(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/
+#endif
+);
+
+#endif /* GC_H */
diff --git a/xc/programs/Xserver/include/gcstruct.h b/xc/programs/Xserver/include/gcstruct.h
new file mode 100644
index 000000000..d87945031
--- /dev/null
+++ b/xc/programs/Xserver/include/gcstruct.h
@@ -0,0 +1,405 @@
+/* $TOG: gcstruct.h /main/19 1998/02/09 14:28:45 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+
+/* $XFree86: xc/programs/Xserver/include/gcstruct.h,v 1.3 1998/10/04 09:38:57 dawes Exp $ */
+
+#ifndef GCSTRUCT_H
+#define GCSTRUCT_H
+
+#include "gc.h"
+
+#include "miscstruct.h"
+#include "region.h"
+#include "pixmap.h"
+#include "screenint.h"
+#include "Xprotostr.h"
+
+/*
+ * functions which modify the state of the GC
+ */
+
+typedef struct _GCFuncs {
+ void (* ValidateGC)(
+#if NeedNestedPrototypes
+ GCPtr /*pGC*/,
+ unsigned long /*stateChanges*/,
+ DrawablePtr /*pDrawable*/
+#endif
+);
+
+ void (* ChangeGC)(
+#if NeedNestedPrototypes
+ GCPtr /*pGC*/,
+ unsigned long /*mask*/
+#endif
+);
+
+ void (* CopyGC)(
+#if NeedNestedPrototypes
+ GCPtr /*pGCSrc*/,
+ unsigned long /*mask*/,
+ GCPtr /*pGCDst*/
+#endif
+);
+
+ void (* DestroyGC)(
+#if NeedNestedPrototypes
+ GCPtr /*pGC*/
+#endif
+);
+
+ void (* ChangeClip)(
+#if NeedNestedPrototypes
+ GCPtr /*pGC*/,
+ int /*type*/,
+ pointer /*pvalue*/,
+ int /*nrects*/
+#endif
+);
+
+ void (* DestroyClip)(
+#if NeedNestedPrototypes
+ GCPtr /*pGC*/
+#endif
+);
+
+ void (* CopyClip)(
+#if NeedNestedPrototypes
+ GCPtr /*pgcDst*/,
+ GCPtr /*pgcSrc*/
+#endif
+);
+ DevUnion devPrivate;
+} GCFuncs;
+
+/*
+ * graphics operations invoked through a GC
+ */
+
+typedef struct _GCOps {
+ void (* FillSpans)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+ void (* SetSpans)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ char * /*psrc*/,
+ DDXPointPtr /*ppt*/,
+ int * /*pwidth*/,
+ int /*nspans*/,
+ int /*fSorted*/
+#endif
+);
+
+ void (* PutImage)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*depth*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ int /*leftPad*/,
+ int /*format*/,
+ char * /*pBits*/
+#endif
+);
+
+ RegionPtr (* CopyArea)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ GCPtr /*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*w*/,
+ int /*h*/,
+ int /*dstx*/,
+ int /*dsty*/
+#endif
+);
+
+ RegionPtr (* CopyPlane)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ GCPtr /*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*width*/,
+ int /*height*/,
+ int /*dstx*/,
+ int /*dsty*/,
+ unsigned long /*bitPlane*/
+#endif
+);
+ void (* PolyPoint)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/
+#endif
+);
+
+ void (* Polylines)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/
+#endif
+);
+
+ void (* PolySegment)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nseg*/,
+ xSegment * /*pSegs*/
+#endif
+);
+
+ void (* PolyRectangle)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nrects*/,
+ xRectangle * /*pRects*/
+#endif
+);
+
+ void (* PolyArc)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+
+ void (* FillPolygon)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*shape*/,
+ int /*mode*/,
+ int /*count*/,
+ DDXPointPtr /*pPts*/
+#endif
+);
+
+ void (* PolyFillRect)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nrectFill*/,
+ xRectangle * /*prectInit*/
+#endif
+);
+
+ void (* PolyFillArc)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+
+ int (* PolyText8)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/
+#endif
+);
+
+ int (* PolyText16)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ unsigned short * /*chars*/
+#endif
+);
+
+ void (* ImageText8)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/
+#endif
+);
+
+ void (* ImageText16)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ unsigned short * /*chars*/
+#endif
+);
+
+ void (* ImageGlyphBlt)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+
+ void (* PolyGlyphBlt)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+
+ void (* PushPixels)(
+#if NeedNestedPrototypes
+ GCPtr /*pGC*/,
+ PixmapPtr /*pBitMap*/,
+ DrawablePtr /*pDst*/,
+ int /*w*/,
+ int /*h*/,
+ int /*x*/,
+ int /*y*/
+#endif
+);
+
+#ifdef NEED_LINEHELPER
+ void (* LineHelper)();
+#endif
+
+ DevUnion devPrivate;
+} GCOps;
+
+/* there is padding in the bit fields because the Sun compiler doesn't
+ * force alignment to 32-bit boundaries. losers.
+ */
+typedef struct _GC {
+ ScreenPtr pScreen;
+ unsigned char depth;
+ unsigned char alu;
+ unsigned short lineWidth;
+ unsigned short dashOffset;
+ unsigned short numInDashList;
+ unsigned char *dash;
+ unsigned int lineStyle : 2;
+ unsigned int capStyle : 2;
+ unsigned int joinStyle : 2;
+ unsigned int fillStyle : 2;
+ unsigned int fillRule : 1;
+ unsigned int arcMode : 1;
+ unsigned int subWindowMode : 1;
+ unsigned int graphicsExposures : 1;
+ unsigned int clientClipType : 2; /* CT_<kind> */
+ unsigned int miTranslate:1; /* should mi things translate? */
+ unsigned int tileIsPixel:1; /* tile is solid pixel */
+ unsigned int fExpose:1; /* Call exposure handling */
+ unsigned int freeCompClip:1; /* Free composite clip */
+ unsigned int unused:14; /* see comment above */
+ unsigned long planemask;
+ unsigned long fgPixel;
+ unsigned long bgPixel;
+ /*
+ * alas -- both tile and stipple must be here as they
+ * are independently specifiable
+ */
+ PixUnion tile;
+ PixmapPtr stipple;
+ DDXPointRec patOrg; /* origin for (tile, stipple) */
+ struct _Font *font;
+ DDXPointRec clipOrg;
+ DDXPointRec lastWinOrg; /* position of window last validated */
+ pointer clientClip;
+ unsigned long stateChanges; /* masked with GC_<kind> */
+ unsigned long serialNumber;
+ GCFuncs *funcs;
+ GCOps *ops;
+ DevUnion *devPrivates;
+ /*
+ * The following were moved here from private storage to allow device-
+ * independent access to them from screen wrappers.
+ * --- 1997.11.03 Marc Aurele La France (tsi@ualberta.ca)
+ */
+ PixmapPtr pRotatedPixmap; /* tile/stipple rotated for alignment */
+ RegionPtr pCompositeClip;
+ /* fExpose & freeCompClip defined above */
+} GC;
+
+#endif /* GCSTRUCT_H */
diff --git a/xc/programs/Xserver/include/globals.h b/xc/programs/Xserver/include/globals.h
new file mode 100644
index 000000000..9ab1f6135
--- /dev/null
+++ b/xc/programs/Xserver/include/globals.h
@@ -0,0 +1,50 @@
+/* $XFree86: xc/programs/Xserver/include/globals.h,v 1.2 1999/03/14 11:18:11 dawes Exp $ */
+
+#ifndef _XSERV_GLOBAL_H_
+#define _XSERV_GLOBAL_H_
+
+#include "window.h" /* for WindowPtr */
+
+/* Global X server variables that are visible to mi, dix, os, and ddx */
+
+extern CARD32 defaultScreenSaverTime;
+extern CARD32 defaultScreenSaverInterval;
+extern CARD32 ScreenSaverTime;
+extern CARD32 ScreenSaverInterval;
+
+extern char *defaultFontPath;
+extern char *rgbPath;
+extern int monitorResolution;
+extern Bool loadableFonts;
+extern int defaultColorVisualClass;
+
+extern Bool Must_have_memory;
+extern WindowPtr *WindowTable;
+extern int GrabInProgress;
+extern Bool noTestExtensions;
+
+#if DPMSExtension
+extern CARD32 defaultDPMSStandbyTime;
+extern CARD32 defaultDPMSSuspendTime;
+extern CARD32 defaultDPMSOffTime;
+extern CARD32 DPMSStandbyTime;
+extern CARD32 DPMSSuspendTime;
+extern CARD32 DPMSOffTime;
+extern CARD16 DPMSPowerLevel;
+extern Bool defaultDPMSEnabled;
+extern Bool DPMSEnabled;
+extern Bool DPMSEnabledSwitch;
+extern Bool DPMSDisabledSwitch;
+extern Bool DPMSCapableFlag;
+#endif
+
+#ifdef PANORAMIX
+extern Bool noPanoramiXExtension;
+extern Bool PanoramiXMapped;
+extern Bool PanoramiXVisibilityNotifySent;
+extern Bool PanoramiXWindowExposureSent;
+extern Bool PanoramiXOneExposeRequest;
+#endif
+
+
+#endif /* _XSERV_GLOBAL_H_ */
diff --git a/xc/programs/Xserver/include/input.h b/xc/programs/Xserver/include/input.h
new file mode 100644
index 000000000..4d2fcaf0e
--- /dev/null
+++ b/xc/programs/Xserver/include/input.h
@@ -0,0 +1,531 @@
+/* $TOG: input.h /main/23 1998/02/09 14:28:58 kaleb $ */
+/************************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+********************************************************/
+/* $XFree86: xc/programs/Xserver/include/input.h,v 3.5 1998/10/04 09:38:57 dawes Exp $ */
+
+#ifndef INPUT_H
+#define INPUT_H
+
+#include "misc.h"
+#include "screenint.h"
+#include "X11/Xmd.h"
+#include "X11/Xproto.h"
+#include "window.h" /* for WindowPtr */
+
+#define DEVICE_INIT 0
+#define DEVICE_ON 1
+#define DEVICE_OFF 2
+#define DEVICE_CLOSE 3
+
+#define MAP_LENGTH 256
+#define DOWN_LENGTH 32 /* 256/8 => number of bytes to hold 256 bits */
+#define NullGrab ((GrabPtr)NULL)
+#define PointerRootWin ((WindowPtr)PointerRoot)
+#define NoneWin ((WindowPtr)None)
+#define NullDevice ((DevicePtr)NULL)
+
+#ifndef FollowKeyboard
+#define FollowKeyboard 3
+#endif
+#ifndef FollowKeyboardWin
+#define FollowKeyboardWin ((WindowPtr) FollowKeyboard)
+#endif
+#ifndef RevertToFollowKeyboard
+#define RevertToFollowKeyboard 3
+#endif
+
+typedef unsigned long Leds;
+typedef struct _OtherClients *OtherClientsPtr;
+typedef struct _InputClients *InputClientsPtr;
+typedef struct _DeviceIntRec *DeviceIntPtr;
+
+typedef int (*DeviceProc)(
+#if NeedNestedPrototypes
+ DeviceIntPtr /*device*/,
+ int /*what*/
+#endif
+);
+
+typedef void (*ProcessInputProc)(
+#if NeedNestedPrototypes
+ xEventPtr /*events*/,
+ DeviceIntPtr /*device*/,
+ int /*count*/
+#endif
+);
+
+typedef struct _DeviceRec {
+ pointer devicePrivate;
+ ProcessInputProc processInputProc; /* current */
+ ProcessInputProc realInputProc; /* deliver */
+ ProcessInputProc enqueueInputProc; /* enqueue */
+ Bool on; /* used by DDX to keep state */
+} DeviceRec, *DevicePtr;
+
+typedef struct {
+ int click, bell, bell_pitch, bell_duration;
+ Bool autoRepeat;
+ unsigned char autoRepeats[32];
+ Leds leds;
+ unsigned char id;
+} KeybdCtrl;
+
+typedef struct {
+ KeySym *map;
+ KeyCode minKeyCode,
+ maxKeyCode;
+ int mapWidth;
+} KeySymsRec, *KeySymsPtr;
+
+typedef struct {
+ int num, den, threshold;
+ unsigned char id;
+} PtrCtrl;
+
+typedef struct {
+ int resolution, min_value, max_value;
+ int integer_displayed;
+ unsigned char id;
+} IntegerCtrl;
+
+typedef struct {
+ int max_symbols, num_symbols_supported;
+ int num_symbols_displayed;
+ KeySym *symbols_supported;
+ KeySym *symbols_displayed;
+ unsigned char id;
+} StringCtrl;
+
+typedef struct {
+ int percent, pitch, duration;
+ unsigned char id;
+} BellCtrl;
+
+typedef struct {
+ Leds led_values;
+ Mask led_mask;
+ unsigned char id;
+} LedCtrl;
+
+extern KeybdCtrl defaultKeyboardControl;
+extern PtrCtrl defaultPointerControl;
+
+#undef AddInputDevice
+extern DevicePtr AddInputDevice(
+#if NeedFunctionPrototypes
+ DeviceProc /*deviceProc*/,
+ Bool /*autoStart*/
+#endif
+);
+
+#define AddInputDevice(deviceProc, autoStart) \
+ _AddInputDevice(deviceProc, autoStart)
+
+extern DeviceIntPtr _AddInputDevice(
+#if NeedFunctionPrototypes
+ DeviceProc /*deviceProc*/,
+ Bool /*autoStart*/
+#endif
+);
+
+extern Bool EnableDevice(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*device*/
+#endif
+);
+
+extern Bool DisableDevice(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*device*/
+#endif
+);
+
+extern int InitAndStartDevices(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void CloseDownDevices(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void RemoveDevice(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*dev*/
+#endif
+);
+
+extern int NumMotionEvents(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+#undef RegisterPointerDevice
+extern void RegisterPointerDevice(
+#if NeedFunctionPrototypes
+ DevicePtr /*device*/
+#endif
+);
+
+#define RegisterPointerDevice(device) \
+ _RegisterPointerDevice(device)
+
+extern void _RegisterPointerDevice(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*device*/
+#endif
+);
+
+#undef RegisterKeyboardDevice
+extern void RegisterKeyboardDevice(
+#if NeedFunctionPrototypes
+ DevicePtr /*device*/
+#endif
+);
+
+#define RegisterKeyboardDevice(device) \
+ _RegisterKeyboardDevice(device)
+
+extern void _RegisterKeyboardDevice(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*device*/
+#endif
+);
+
+extern DevicePtr LookupKeyboardDevice(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern DevicePtr LookupPointerDevice(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern DevicePtr LookupDevice(
+#if NeedFunctionPrototypes
+ int /* id */
+#endif
+);
+
+extern void QueryMinMaxKeyCodes(
+#if NeedFunctionPrototypes
+ KeyCode* /*minCode*/,
+ KeyCode* /*maxCode*/
+#endif
+);
+
+extern Bool SetKeySymsMap(
+#if NeedFunctionPrototypes
+ KeySymsPtr /*dst*/,
+ KeySymsPtr /*src*/
+#endif
+);
+
+extern Bool InitKeyClassDeviceStruct(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*device*/,
+ KeySymsPtr /*pKeySyms*/,
+ CARD8 /*pModifiers*/[]
+#endif
+);
+
+extern Bool InitButtonClassDeviceStruct(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*device*/,
+ int /*numButtons*/,
+ CARD8* /*map*/
+#endif
+);
+
+typedef int (*ValuatorMotionProcPtr)(
+#if NeedNestedPrototypes
+ DeviceIntPtr /*pdevice*/,
+ xTimecoord * /*coords*/,
+ unsigned long /*start*/,
+ unsigned long /*stop*/,
+ ScreenPtr /*pScreen*/
+#endif
+);
+
+extern Bool InitValuatorClassDeviceStruct(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*device*/,
+ int /*numAxes*/,
+ ValuatorMotionProcPtr /* motionProc */,
+ int /*numMotionEvents*/,
+ int /*mode*/
+#endif
+);
+
+extern Bool InitFocusClassDeviceStruct(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*device*/
+#endif
+);
+
+typedef void (*BellProcPtr)(
+#if NeedNestedPrototypes
+ int /*percent*/,
+ DeviceIntPtr /*device*/,
+ pointer /*ctrl*/,
+ int
+#endif
+);
+
+typedef void (*KbdCtrlProcPtr)(
+#if NeedNestedPrototypes
+ DeviceIntPtr /*device*/,
+ KeybdCtrl * /*ctrl*/
+#endif
+);
+
+extern Bool InitKbdFeedbackClassDeviceStruct(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*device*/,
+ BellProcPtr /*bellProc*/,
+ KbdCtrlProcPtr /*controlProc*/
+#endif
+);
+
+typedef void (*PtrCtrlProcPtr)(
+#if NeedNestedPrototypes
+ DeviceIntPtr /*device*/,
+ PtrCtrl * /*ctrl*/
+#endif
+);
+
+extern Bool InitPtrFeedbackClassDeviceStruct(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*device*/,
+ PtrCtrlProcPtr /*controlProc*/
+#endif
+);
+
+typedef void (*StringCtrlProcPtr)(
+#if NeedNestedPrototypes
+ DeviceIntPtr /*device*/,
+ StringCtrl * /*ctrl*/
+#endif
+);
+
+extern Bool InitStringFeedbackClassDeviceStruct(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*device*/,
+ StringCtrlProcPtr /*controlProc*/,
+ int /*max_symbols*/,
+ int /*num_symbols_supported*/,
+ KeySym* /*symbols*/
+#endif
+);
+
+typedef void (*BellCtrlProcPtr)(
+#if NeedNestedPrototypes
+ DeviceIntPtr /*device*/,
+ BellCtrl * /*ctrl*/
+#endif
+);
+
+extern Bool InitBellFeedbackClassDeviceStruct(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*device*/,
+ BellProcPtr /*bellProc*/,
+ BellCtrlProcPtr /*controlProc*/
+#endif
+);
+
+typedef void (*LedCtrlProcPtr)(
+#if NeedNestedPrototypes
+ DeviceIntPtr /*device*/,
+ LedCtrl * /*ctrl*/
+#endif
+);
+
+extern Bool InitLedFeedbackClassDeviceStruct(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*device*/,
+ LedCtrlProcPtr /*controlProc*/
+#endif
+);
+
+typedef void (*IntegerCtrlProcPtr)(
+#if NeedNestedPrototypes
+ DeviceIntPtr /*device*/,
+ IntegerCtrl * /*ctrl*/
+#endif
+);
+
+
+extern Bool InitIntegerFeedbackClassDeviceStruct(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*device*/,
+ IntegerCtrlProcPtr /*controlProc*/
+#endif
+);
+
+extern Bool InitPointerDeviceStruct(
+#if NeedFunctionPrototypes
+ DevicePtr /*device*/,
+ CARD8* /*map*/,
+ int /*numButtons*/,
+ ValuatorMotionProcPtr /*motionProc*/,
+ PtrCtrlProcPtr /*controlProc*/,
+ int /*numMotionEvents*/
+#endif
+);
+
+extern Bool InitKeyboardDeviceStruct(
+#if NeedFunctionPrototypes
+ DevicePtr /*device*/,
+ KeySymsPtr /*pKeySyms*/,
+ CARD8 /*pModifiers*/[],
+ BellProcPtr /*bellProc*/,
+ KbdCtrlProcPtr /*controlProc*/
+#endif
+);
+
+extern void SendMappingNotify(
+#if NeedFunctionPrototypes
+ unsigned int /*request*/,
+ unsigned int /*firstKeyCode*/,
+ unsigned int /*count*/,
+ ClientPtr /* client */
+#endif
+);
+
+extern Bool BadDeviceMap(
+#if NeedFunctionPrototypes
+ BYTE* /*buff*/,
+ int /*length*/,
+ unsigned /*low*/,
+ unsigned /*high*/,
+ XID* /*errval*/
+#endif
+);
+
+extern Bool AllModifierKeysAreUp(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*device*/,
+ CARD8* /*map1*/,
+ int /*per1*/,
+ CARD8* /*map2*/,
+ int /*per2*/
+#endif
+);
+
+extern void NoteLedState(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*keybd*/,
+ int /*led*/,
+ Bool /*on*/
+#endif
+);
+
+extern void MaybeStopHint(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*device*/,
+ ClientPtr /*client*/
+#endif
+);
+
+extern void ProcessPointerEvent(
+#if NeedFunctionPrototypes
+ xEventPtr /*xE*/,
+ DeviceIntPtr /*mouse*/,
+ int /*count*/
+#endif
+);
+
+extern void ProcessKeyboardEvent(
+#if NeedFunctionPrototypes
+ xEventPtr /*xE*/,
+ DeviceIntPtr /*keybd*/,
+ int /*count*/
+#endif
+);
+
+#ifdef XKB
+extern void CoreProcessPointerEvent(
+#if NeedFunctionPrototypes
+ xEventPtr /*xE*/,
+ DeviceIntPtr /*mouse*/,
+ int /*count*/
+#endif
+);
+
+extern void CoreProcessKeyboardEvent(
+#if NeedFunctionPrototypes
+ xEventPtr /*xE*/,
+ DeviceIntPtr /*keybd*/,
+ int /*count*/
+#endif
+);
+#endif
+
+extern Bool LegalModifier(
+#if NeedFunctionPrototypes
+ unsigned int /*key*/,
+ DevicePtr /*pDev*/
+#endif
+);
+
+extern void ProcessInputEvents(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void InitInput(
+#if NeedFunctionPrototypes
+ int /*argc*/,
+ char ** /*argv*/
+#endif
+);
+
+#endif /* INPUT_H */
diff --git a/xc/programs/Xserver/include/inputstr.h b/xc/programs/Xserver/include/inputstr.h
new file mode 100644
index 000000000..ccbf3f720
--- /dev/null
+++ b/xc/programs/Xserver/include/inputstr.h
@@ -0,0 +1,313 @@
+/* $XFree86: xc/programs/Xserver/include/inputstr.h,v 1.3 1998/12/20 22:18:58 dawes Exp $ */
+/************************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+********************************************************/
+
+/* $TOG: inputstr.h /main/29 1998/02/09 14:28:54 kaleb $ */
+
+#ifndef INPUTSTRUCT_H
+#define INPUTSTRUCT_H
+
+#include "input.h"
+#include "window.h"
+#include "dixstruct.h"
+
+#define BitIsOn(ptr, bit) (((BYTE *) (ptr))[(bit)>>3] & (1 << ((bit) & 7)))
+
+#define SameClient(obj,client) \
+ (CLIENT_BITS((obj)->resource) == (client)->clientAsMask)
+
+#define MAX_DEVICES 20
+
+#define EMASKSIZE MAX_DEVICES
+
+/* Kludge: OtherClients and InputClients must be compatible, see code */
+
+typedef struct _OtherClients {
+ OtherClientsPtr next;
+ XID resource; /* id for putting into resource manager */
+ Mask mask;
+} OtherClients;
+
+typedef struct _InputClients {
+ InputClientsPtr next;
+ XID resource; /* id for putting into resource manager */
+ Mask mask[EMASKSIZE];
+} InputClients;
+
+typedef struct _OtherInputMasks {
+ Mask deliverableEvents[EMASKSIZE];
+ Mask inputEvents[EMASKSIZE];
+ Mask dontPropagateMask[EMASKSIZE];
+ InputClientsPtr inputClients;
+} OtherInputMasks;
+
+/*
+ * The following structure gets used for both active and passive grabs. For
+ * active grabs some of the fields (e.g. modifiers) are not used. However,
+ * that is not much waste since there aren't many active grabs (one per
+ * keyboard/pointer device) going at once in the server.
+ */
+
+#define MasksPerDetailMask 8 /* 256 keycodes and 256 possible
+ modifier combinations, but only
+ 3 buttons. */
+
+ typedef struct _DetailRec { /* Grab details may be bit masks */
+ unsigned short exact;
+ Mask *pMask;
+ } DetailRec;
+
+ typedef struct _GrabRec {
+ GrabPtr next; /* for chain of passive grabs */
+ XID resource;
+ DeviceIntPtr device;
+ WindowPtr window;
+ unsigned ownerEvents:1;
+ unsigned keyboardMode:1;
+ unsigned pointerMode:1;
+ unsigned coreGrab:1; /* grab is on core device */
+ unsigned coreMods:1; /* modifiers are on core keyboard */
+ CARD8 type; /* event type */
+ DetailRec modifiersDetail;
+ DeviceIntPtr modifierDevice;
+ DetailRec detail; /* key or button */
+ WindowPtr confineTo; /* always NULL for keyboards */
+ CursorPtr cursor; /* always NULL for keyboards */
+ Mask eventMask;
+} GrabRec;
+
+typedef struct _KeyClassRec {
+ CARD8 down[DOWN_LENGTH];
+ KeyCode *modifierKeyMap;
+ KeySymsRec curKeySyms;
+ int modifierKeyCount[8];
+ CARD8 modifierMap[MAP_LENGTH];
+ CARD8 maxKeysPerModifier;
+ unsigned short state;
+ unsigned short prev_state;
+#ifdef XKB
+ struct _XkbSrvInfo *xkbInfo;
+#endif
+} KeyClassRec, *KeyClassPtr;
+
+typedef struct _AxisInfo {
+ int resolution;
+ int min_resolution;
+ int max_resolution;
+ int min_value;
+ int max_value;
+} AxisInfo, *AxisInfoPtr;
+
+typedef struct _ValuatorClassRec {
+ ValuatorMotionProcPtr GetMotionProc;
+ int numMotionEvents;
+ WindowPtr motionHintWindow;
+ AxisInfoPtr axes;
+ unsigned short numAxes;
+ int *axisVal;
+ CARD8 mode;
+} ValuatorClassRec, *ValuatorClassPtr;
+
+typedef struct _ButtonClassRec {
+ CARD8 numButtons;
+ CARD8 buttonsDown; /* number of buttons currently down */
+ unsigned short state;
+ Mask motionMask;
+ CARD8 down[DOWN_LENGTH];
+ CARD8 map[MAP_LENGTH];
+#ifdef XKB
+ union _XkbAction * xkb_acts;
+#endif
+} ButtonClassRec, *ButtonClassPtr;
+
+typedef struct _FocusClassRec {
+ WindowPtr win;
+ int revert;
+ TimeStamp time;
+ WindowPtr *trace;
+ int traceSize;
+ int traceGood;
+} FocusClassRec, *FocusClassPtr;
+
+typedef struct _ProximityClassRec {
+ char pad;
+} ProximityClassRec, *ProximityClassPtr;
+
+typedef struct _KbdFeedbackClassRec *KbdFeedbackPtr;
+typedef struct _PtrFeedbackClassRec *PtrFeedbackPtr;
+typedef struct _IntegerFeedbackClassRec *IntegerFeedbackPtr;
+typedef struct _StringFeedbackClassRec *StringFeedbackPtr;
+typedef struct _BellFeedbackClassRec *BellFeedbackPtr;
+typedef struct _LedFeedbackClassRec *LedFeedbackPtr;
+
+typedef struct _KbdFeedbackClassRec {
+ BellProcPtr BellProc;
+ KbdCtrlProcPtr CtrlProc;
+ KeybdCtrl ctrl;
+ KbdFeedbackPtr next;
+#ifdef XKB
+ struct _XkbSrvLedInfo *xkb_sli;
+#endif
+} KbdFeedbackClassRec;
+
+typedef struct _PtrFeedbackClassRec {
+ PtrCtrlProcPtr CtrlProc;
+ PtrCtrl ctrl;
+ PtrFeedbackPtr next;
+} PtrFeedbackClassRec;
+
+typedef struct _IntegerFeedbackClassRec {
+ IntegerCtrlProcPtr CtrlProc;
+ IntegerCtrl ctrl;
+ IntegerFeedbackPtr next;
+} IntegerFeedbackClassRec;
+
+typedef struct _StringFeedbackClassRec {
+ StringCtrlProcPtr CtrlProc;
+ StringCtrl ctrl;
+ StringFeedbackPtr next;
+} StringFeedbackClassRec;
+
+typedef struct _BellFeedbackClassRec {
+ BellProcPtr BellProc;
+ BellCtrlProcPtr CtrlProc;
+ BellCtrl ctrl;
+ BellFeedbackPtr next;
+} BellFeedbackClassRec;
+
+typedef struct _LedFeedbackClassRec {
+ LedCtrlProcPtr CtrlProc;
+ LedCtrl ctrl;
+ LedFeedbackPtr next;
+#ifdef XKB
+ struct _XkbSrvLedInfo *xkb_sli;
+#endif
+} LedFeedbackClassRec;
+
+/* states for devices */
+
+#define NOT_GRABBED 0
+#define THAWED 1
+#define THAWED_BOTH 2 /* not a real state */
+#define FREEZE_NEXT_EVENT 3
+#define FREEZE_BOTH_NEXT_EVENT 4
+#define FROZEN 5 /* any state >= has device frozen */
+#define FROZEN_NO_EVENT 5
+#define FROZEN_WITH_EVENT 6
+#define THAW_OTHERS 7
+
+typedef struct _DeviceIntRec {
+ DeviceRec public;
+ DeviceIntPtr next;
+ TimeStamp grabTime;
+ Bool startup; /* true if needs to be turned on at
+ server intialization time */
+ DeviceProc deviceProc; /* proc(DevicePtr, DEVICE_xx). It is
+ used to initialize, turn on, or
+ turn off the device */
+ Bool inited; /* TRUE if INIT returns Success */
+ GrabPtr grab; /* the grabber - used by DIX */
+ struct {
+ Bool frozen;
+ int state;
+ GrabPtr other; /* if other grab has this frozen */
+ xEvent *event; /* saved to be replayed */
+ int evcount;
+ } sync;
+ Atom type;
+ char *name;
+ CARD8 id;
+ CARD8 activatingKey;
+ Bool fromPassiveGrab;
+ GrabRec activeGrab;
+ void (*ActivateGrab) (
+#if NeedNestedPrototypes
+ DeviceIntPtr /*device*/,
+ GrabPtr /*grab*/,
+ TimeStamp /*time*/,
+ Bool /*autoGrab*/
+#endif
+);
+ void (*DeactivateGrab)(
+#if NeedNestedPrototypes
+ DeviceIntPtr /*device*/
+#endif
+);
+ KeyClassPtr key;
+ ValuatorClassPtr valuator;
+ ButtonClassPtr button;
+ FocusClassPtr focus;
+ ProximityClassPtr proximity;
+ KbdFeedbackPtr kbdfeed;
+ PtrFeedbackPtr ptrfeed;
+ IntegerFeedbackPtr intfeed;
+ StringFeedbackPtr stringfeed;
+ BellFeedbackPtr bell;
+ LedFeedbackPtr leds;
+#ifdef XKB
+ struct _XkbInterest * xkb_interest;
+#endif
+} DeviceIntRec;
+
+typedef struct {
+ int numDevices; /* total number of devices */
+ DeviceIntPtr devices; /* all devices turned on */
+ DeviceIntPtr off_devices; /* all devices turned off */
+ DeviceIntPtr keyboard; /* the main one for the server */
+ DeviceIntPtr pointer;
+} InputInfo;
+
+extern InputInfo inputInfo;
+
+/* for keeping the events for devices grabbed synchronously */
+typedef struct _QdEvent *QdEventPtr;
+typedef struct _QdEvent {
+ QdEventPtr next;
+ DeviceIntPtr device;
+ ScreenPtr pScreen; /* what screen the pointer was on */
+ unsigned long months; /* milliseconds is in the event */
+ xEvent *event;
+ int evcount;
+} QdEventRec;
+
+#endif /* INPUTSTRUCT_H */
diff --git a/xc/programs/Xserver/include/misc.h b/xc/programs/Xserver/include/misc.h
new file mode 100644
index 000000000..5bfb2bd09
--- /dev/null
+++ b/xc/programs/Xserver/include/misc.h
@@ -0,0 +1,284 @@
+/* $XFree86: xc/programs/Xserver/include/misc.h,v 3.22 1999/08/21 13:48:44 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+Copyright 1992, 1993 Data General Corporation;
+Copyright 1992, 1993 OMRON Corporation
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that the
+above copyright notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting documentation, and that
+neither the name OMRON or DATA GENERAL be used in advertising or publicity
+pertaining to distribution of the software without specific, written prior
+permission of the party whose name is to be used. Neither OMRON or
+DATA GENERAL make any representation about the suitability of this software
+for any purpose. It is provided "as is" without express or implied warranty.
+
+OMRON AND DATA GENERAL EACH DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL OMRON OR DATA GENERAL 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.
+
+******************************************************************/
+/* $TOG: misc.h /main/29 1998/02/09 14:29:08 kaleb $ */
+#ifndef MISC_H
+#define MISC_H 1
+/*
+ * X internal definitions
+ *
+ */
+
+extern unsigned long globalSerialNumber;
+extern unsigned long serverGeneration;
+
+#include <X11/Xosdefs.h>
+#include <X11/Xfuncproto.h>
+#include <X11/Xmd.h>
+#include <X11/X.h>
+#include <X11/Xdefs.h>
+
+#ifndef IN_MODULE
+#ifndef NULL
+#ifndef X_NOT_STDC_ENV
+#include <stddef.h>
+#else
+#define NULL 0
+#endif
+#endif
+#endif
+
+#ifndef MAXSCREENS
+#define MAXSCREENS 16
+#endif
+#define MAXCLIENTS 256
+#define MAXDITS 1
+#define MAXEXTENSIONS 128
+#define MAXFORMATS 8
+#define MAXVISUALS_PER_SCREEN 50
+
+typedef unsigned long PIXEL;
+typedef unsigned long ATOM;
+
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+#ifndef _XTYPEDEF_CALLBACKLISTPTR
+typedef struct _CallbackList *CallbackListPtr; /* also in dix.h */
+#define _XTYPEDEF_CALLBACKLISTPTR
+#endif
+
+typedef struct _xReq *xReqPtr;
+
+#include "os.h" /* for ALLOCATE_LOCAL and DEALLOCATE_LOCAL */
+#ifndef IN_MODULE
+#include <X11/Xfuncs.h> /* for bcopy, bzero, and bcmp */
+#endif
+
+#define NullBox ((BoxPtr)0)
+#define MILLI_PER_MIN (1000 * 60)
+#define MILLI_PER_SECOND (1000)
+
+ /* this next is used with None and ParentRelative to tell
+ PaintWin() what to use to paint the background. Also used
+ in the macro IS_VALID_PIXMAP */
+
+#define USE_BACKGROUND_PIXEL 3
+#define USE_BORDER_PIXEL 3
+
+
+/* byte swap a 32-bit literal */
+#define lswapl(x) ((((x) & 0xff) << 24) |\
+ (((x) & 0xff00) << 8) |\
+ (((x) & 0xff0000) >> 8) |\
+ (((x) >> 24) & 0xff))
+
+/* byte swap a short literal */
+#define lswaps(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))
+
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+#ifndef IN_MODULE
+#ifdef X_NOT_STDC_ENV
+#ifndef abs
+#define abs(a) ((a) > 0 ? (a) : -(a))
+#endif
+#else
+/* abs() is a function, not a macro; include the file declaring
+ * it in case we haven't done that yet.
+ */
+#include <stdlib.h>
+#endif /* X_NOT_STDC_ENV */
+#endif /* IN_MODULE */
+#ifndef Fabs
+#define Fabs(a) ((a) > 0.0 ? (a) : -(a)) /* floating absolute value */
+#endif
+#define sign(x) ((x) < 0 ? -1 : ((x) > 0 ? 1 : 0))
+/* this assumes b > 0 */
+#define modulus(a, b, d) if (((d) = (a) % (b)) < 0) (d) += (b)
+/*
+ * return the least significant bit in x which is set
+ *
+ * This works on 1's complement and 2's complement machines.
+ * If you care about the extra instruction on 2's complement
+ * machines, change to ((x) & (-(x)))
+ */
+#define lowbit(x) ((x) & (~(x) + 1))
+
+#ifndef IN_MODULE
+/* XXX Not for modules */
+#include <limits.h>
+#if !defined(MAXSHORT) || !defined(MINSHORT) || \
+ !defined(MAXINT) || !defined(MININT)
+/*
+ * Some implementations #define these through <math.h>, so preclude
+ * #include'ing it later.
+ */
+#include <math.h>
+#endif
+#undef MAXSHORT
+#define MAXSHORT SHRT_MAX
+#undef MINSHORT
+#define MINSHORT SHRT_MIN
+#undef MAXINT
+#define MAXINT INT_MAX
+#undef MININT
+#define MININT INT_MIN
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h> /* for fopen, etc... */
+
+#endif
+
+/* some macros to help swap requests, replies, and events */
+
+#define LengthRestB(stuff) \
+ ((client->req_len << 2) - sizeof(*stuff))
+
+#define LengthRestS(stuff) \
+ ((client->req_len << 1) - (sizeof(*stuff) >> 1))
+
+#define LengthRestL(stuff) \
+ (client->req_len - (sizeof(*stuff) >> 2))
+
+#define SwapRestS(stuff) \
+ SwapShorts((short *)(stuff + 1), LengthRestS(stuff))
+
+#define SwapRestL(stuff) \
+ SwapLongs((CARD32 *)(stuff + 1), LengthRestL(stuff))
+
+/* byte swap a 32-bit value */
+#define swapl(x, n) { \
+ n = ((char *) (x))[0];\
+ ((char *) (x))[0] = ((char *) (x))[3];\
+ ((char *) (x))[3] = n;\
+ n = ((char *) (x))[1];\
+ ((char *) (x))[1] = ((char *) (x))[2];\
+ ((char *) (x))[2] = n; }
+
+/* byte swap a short */
+#define swaps(x, n) { \
+ n = ((char *) (x))[0];\
+ ((char *) (x))[0] = ((char *) (x))[1];\
+ ((char *) (x))[1] = n; }
+
+/* copy 32-bit value from src to dst byteswapping on the way */
+#define cpswapl(src, dst) { \
+ ((char *)&(dst))[0] = ((char *) &(src))[3];\
+ ((char *)&(dst))[1] = ((char *) &(src))[2];\
+ ((char *)&(dst))[2] = ((char *) &(src))[1];\
+ ((char *)&(dst))[3] = ((char *) &(src))[0]; }
+
+/* copy short from src to dst byteswapping on the way */
+#define cpswaps(src, dst) { \
+ ((char *) &(dst))[0] = ((char *) &(src))[1];\
+ ((char *) &(dst))[1] = ((char *) &(src))[0]; }
+
+extern void SwapLongs(
+#if NeedFunctionPrototypes
+ CARD32 *list,
+ unsigned long count
+#endif
+);
+
+extern void SwapShorts(
+#if NeedFunctionPrototypes
+ short *list,
+ unsigned long count
+#endif
+);
+
+extern void MakePredeclaredAtoms(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern int Ones(
+#if NeedFunctionPrototypes
+ unsigned long /*mask*/
+#endif
+);
+
+typedef struct _xPoint *DDXPointPtr;
+typedef struct _Box *BoxPtr;
+typedef struct _xEvent *xEventPtr;
+typedef struct _xRectangle *xRectanglePtr;
+typedef struct _GrabRec *GrabPtr;
+
+/* typedefs from other places - duplicated here to minimize the amount
+ * of unnecessary junk that one would normally have to include to get
+ * these symbols defined
+ */
+
+#ifndef _XTYPEDEF_CHARINFOPTR
+typedef struct _CharInfo *CharInfoPtr; /* also in fonts/include/font.h */
+#define _XTYPEDEF_CHARINFOPTR
+#endif
+
+#endif /* MISC_H */
diff --git a/xc/programs/Xserver/include/miscstruct.h b/xc/programs/Xserver/include/miscstruct.h
new file mode 100644
index 000000000..946514449
--- /dev/null
+++ b/xc/programs/Xserver/include/miscstruct.h
@@ -0,0 +1,69 @@
+/* $TOG: miscstruct.h /main/11 1998/02/09 14:29:04 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/include/miscstruct.h,v 3.1 1998/10/04 09:38:58 dawes Exp $ */
+
+#ifndef MISCSTRUCT_H
+#define MISCSTRUCT_H 1
+
+#include "misc.h"
+#include "X11/Xprotostr.h"
+
+typedef xPoint DDXPointRec;
+
+typedef struct _Box {
+ short x1, y1, x2, y2;
+} BoxRec;
+
+typedef union _DevUnion {
+ pointer ptr;
+ long val;
+ unsigned long uval;
+ pointer (*fptr)(
+#if NeedFunctionPrototypes
+ void
+#endif
+ );
+} DevUnion;
+
+#endif /* MISCSTRUCT_H */
diff --git a/xc/programs/Xserver/include/opaque.h b/xc/programs/Xserver/include/opaque.h
new file mode 100644
index 000000000..0743f6975
--- /dev/null
+++ b/xc/programs/Xserver/include/opaque.h
@@ -0,0 +1,80 @@
+/* $TOG: opaque.h /main/20 1998/02/09 14:29:12 kaleb $ */
+/*
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+/* $XFree86: xc/programs/Xserver/include/opaque.h,v 1.7 1999/03/20 08:59:33 dawes Exp $ */
+
+#ifndef OPAQUE_H
+#define OPAQUE_H
+
+#include <X11/Xmd.h>
+
+#include "globals.h"
+
+extern char *defaultTextFont;
+extern char *defaultCursorFont;
+extern int MaxClients;
+extern char isItTimeToYield;
+extern char dispatchException;
+
+/* bit values for dispatchException */
+#define DE_RESET 1
+#define DE_TERMINATE 2
+#define DE_PRIORITYCHANGE 4 /* set when a client's priority changes */
+
+extern CARD32 TimeOutValue;
+extern int ScreenSaverBlanking;
+extern int ScreenSaverAllowExposures;
+extern int defaultScreenSaverBlanking;
+extern int defaultScreenSaverAllowExposures;
+extern int argcGlobal;
+extern char **argvGlobal;
+extern char *display;
+
+extern int defaultBackingStore;
+extern Bool disableBackingStore;
+extern Bool enableBackingStore;
+extern Bool disableSaveUnders;
+extern Bool PartialNetwork;
+#ifndef NOLOGOHACK
+extern int logoScreenSaver;
+#endif
+#ifdef RLIMIT_DATA
+extern int limitDataSpace;
+#endif
+#ifdef RLIMIT_STACK
+extern int limitStackSpace;
+#endif
+#ifdef RLIMIT_NOFILE
+extern int limitNoFile;
+#endif
+extern Bool permitOldBugs;
+extern Bool defeatAccessControl;
+#ifdef SERVER_LOCK
+static Bool nolock = FALSE;
+#endif
+extern char* protNoListen;
+
+
+
+#endif /* OPAQUE_H */
diff --git a/xc/programs/Xserver/include/os.h b/xc/programs/Xserver/include/os.h
new file mode 100644
index 000000000..9196ad86b
--- /dev/null
+++ b/xc/programs/Xserver/include/os.h
@@ -0,0 +1,805 @@
+/* $XFree86: xc/programs/Xserver/include/os.h,v 3.29 1999/05/15 12:10:34 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* $TOG: os.h /main/62 1998/02/09 14:29:17 kaleb $ */
+
+#ifndef OS_H
+#define OS_H
+#include "misc.h"
+#define ALLOCATE_LOCAL_FALLBACK(_size) Xalloc((unsigned long)(_size))
+#define DEALLOCATE_LOCAL_FALLBACK(_ptr) Xfree((pointer)(_ptr))
+#include "Xalloca.h"
+#if NeedVarargsPrototypes
+#include <stdarg.h>
+#endif
+
+#define NullFID ((FID) 0)
+
+#define SCREEN_SAVER_ON 0
+#define SCREEN_SAVER_OFF 1
+#define SCREEN_SAVER_FORCER 2
+#define SCREEN_SAVER_CYCLE 3
+
+#ifndef MAX_REQUEST_SIZE
+#define MAX_REQUEST_SIZE 65535
+#endif
+#ifndef MAX_BIG_REQUEST_SIZE
+#define MAX_BIG_REQUEST_SIZE 1048575
+#endif
+
+typedef pointer FID;
+typedef struct _FontPathRec *FontPathPtr;
+typedef struct _NewClientRec *NewClientPtr;
+
+#ifndef xalloc
+#define xnfalloc(size) XNFalloc((unsigned long)(size))
+#define xnfcalloc(_num, _size) XNFcalloc((unsigned long)(_num)*(unsigned long)(_size))
+#define xnfrealloc(ptr, size) XNFrealloc((pointer)(ptr), (unsigned long)(size))
+
+#define xalloc(size) Xalloc((unsigned long)(size))
+#define xcalloc(_num, _size) Xcalloc((unsigned long)(_num)*(unsigned long)(_size))
+#define xrealloc(ptr, size) Xrealloc((pointer)(ptr), (unsigned long)(size))
+#define xfree(ptr) Xfree((pointer)(ptr))
+#define xstrdup(s) Xstrdup(s)
+#define xnfstrdup(s) XNFstrdup(s)
+#endif
+
+#ifndef IN_MODULE
+#ifdef SCO
+#include <stdio.h>
+#endif
+#ifndef X_NOT_STDC_ENV
+#include <string.h>
+#else
+#ifdef SYSV
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#endif
+#endif
+
+/* have to put $(SIGNAL_DEFINES) in DEFINES in Imakefile to get this right */
+#ifdef SIGNALRETURNSINT
+#define SIGVAL int
+#else
+#define SIGVAL void
+#endif
+
+extern Bool OsDelayInitColors;
+extern void (*OsVendorVErrorFProc)(const char *, va_list args);
+
+extern int WaitForSomething(
+#if NeedFunctionPrototypes
+ int* /*pClientsReady*/
+#endif
+);
+
+#ifdef LBX
+#define ReadRequestFromClient(client) ((client)->readRequest(client))
+extern int StandardReadRequestFromClient(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+#else
+extern int ReadRequestFromClient(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+#endif /* LBX */
+
+extern Bool InsertFakeRequest(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ char* /*data*/,
+ int /*count*/
+#endif
+);
+
+extern int ResetCurrentRequest(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern void FlushAllOutput(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void FlushIfCriticalOutputPending(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void SetCriticalOutputPending(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern int WriteToClient(
+#if NeedFunctionPrototypes
+ ClientPtr /*who*/,
+ int /*count*/,
+ char* /*buf*/
+#endif
+);
+
+extern void ResetOsBuffers(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void CreateWellKnownSockets(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void ResetWellKnownSockets(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern XID
+AuthorizationIDOfClient(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern char *ClientAuthorized(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ unsigned int /*proto_n*/,
+ char* /*auth_proto*/,
+ unsigned int /*string_n*/,
+ char* /*auth_string*/
+#endif
+);
+
+extern Bool EstablishNewConnections(
+#if NeedFunctionPrototypes
+ ClientPtr /*clientUnused*/,
+ pointer /*closure*/
+#endif
+);
+
+extern void CheckConnections(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void CloseDownConnection(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern int AddEnabledDevice(
+#if NeedFunctionPrototypes
+ int /*fd*/
+#endif
+);
+
+extern int RemoveEnabledDevice(
+#if NeedFunctionPrototypes
+ int /*fd*/
+#endif
+);
+
+extern int OnlyListenToOneClient(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern int ListenToAllClients(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern int IgnoreClient(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern int AttendClient(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern int MakeClientGrabImpervious(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern int MakeClientGrabPervious(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern void Error(
+#if NeedFunctionPrototypes
+ char* /*str*/
+#endif
+);
+
+extern CARD32 GetTimeInMillis(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void AdjustWaitForDelay(
+#if NeedFunctionPrototypes
+ pointer /*waitTime*/,
+ unsigned long /*newdelay*/
+#endif
+);
+
+typedef struct _OsTimerRec *OsTimerPtr;
+
+typedef CARD32 (*OsTimerCallback)(
+#if NeedFunctionPrototypes
+ OsTimerPtr /* timer */,
+ CARD32 /* time */,
+ pointer /* arg */
+#endif
+);
+
+extern void TimerInit(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern Bool TimerForce(
+#if NeedFunctionPrototypes
+ OsTimerPtr /* timer */
+#endif
+);
+
+#define TimerAbsolute (1<<0)
+#define TimerForceOld (1<<1)
+
+extern OsTimerPtr TimerSet(
+#if NeedFunctionPrototypes
+ OsTimerPtr /* timer */,
+ int /* flags */,
+ CARD32 /* millis */,
+ OsTimerCallback /* func */,
+ pointer /* arg */
+#endif
+);
+
+extern void TimerCheck(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void TimerCancel(
+#if NeedFunctionPrototypes
+ OsTimerPtr /* pTimer */
+#endif
+);
+
+extern void TimerFree(
+#if NeedFunctionPrototypes
+ OsTimerPtr /* pTimer */
+#endif
+);
+
+extern SIGVAL AutoResetServer(
+#if NeedFunctionPrototypes
+ int /*sig*/
+#endif
+);
+
+extern SIGVAL GiveUp(
+#if NeedFunctionPrototypes
+ int /*sig*/
+#endif
+);
+
+extern void UseMsg(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void ProcessCommandLine(
+#if NeedFunctionPrototypes
+ int /*argc*/,
+ char* /*argv*/[]
+#endif
+);
+
+extern pointer Xalloc(
+#if NeedFunctionPrototypes
+ unsigned long /*amount*/
+#endif
+);
+
+extern pointer XNFalloc(
+#if NeedFunctionPrototypes
+ unsigned long /*amount*/
+#endif
+);
+
+extern pointer Xcalloc(
+#if NeedFunctionPrototypes
+ unsigned long /*amount*/
+#endif
+);
+
+extern pointer XNFcalloc(
+#if NeedFunctionPrototypes
+ unsigned long /*amount*/
+#endif
+);
+
+extern pointer Xrealloc(
+#if NeedFunctionPrototypes
+ pointer /*ptr*/,
+ unsigned long /*amount*/
+#endif
+);
+
+extern pointer XNFrealloc(
+#if NeedFunctionPrototypes
+ pointer /*ptr*/,
+ unsigned long /*amount*/
+#endif
+);
+
+extern void Xfree(
+#if NeedFunctionPrototypes
+ pointer /*ptr*/
+#endif
+);
+
+extern void OsInitAllocator(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern char *Xstrdup(const char *s);
+extern char *XNFstrdup(const char *s);
+
+typedef SIGVAL (*OsSigHandlerPtr)(
+#if NeedFunctionPrototypes
+ int /* sig */
+#endif
+);
+
+extern OsSigHandlerPtr OsSignal(
+#if NeedFunctionPrototypes
+ int /* sig */,
+ OsSigHandlerPtr /* handler */
+#endif
+);
+
+extern int auditTrailLevel;
+
+extern void AuditF(
+#if NeedVarargsPrototypes
+ const char* /*f*/,
+ ...
+#endif
+);
+
+extern void FatalError(
+#if NeedVarargsPrototypes
+ const char* /*f*/,
+ ...
+#endif
+)
+#if __GNUC__ == 2 && __GNUC_MINOR__ > 4
+__attribute((noreturn))
+#endif
+;
+
+extern void ErrorF(
+#if NeedVarargsPrototypes
+ const char* /*f*/,
+ ...
+#endif
+);
+
+#if NeedVarargsPrototypes
+extern void VErrorF(const char *f, va_list args);
+#endif
+
+#ifdef SERVER_LOCK
+extern void LockServer(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void UnlockServer(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+#endif
+
+extern int OsLookupColor(
+#if NeedFunctionPrototypes
+ int /*screen*/,
+ char * /*name*/,
+ unsigned /*len*/,
+ unsigned short * /*pred*/,
+ unsigned short * /*pgreen*/,
+ unsigned short * /*pblue*/
+#endif
+);
+
+extern void OsInit(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void OsCleanup(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void OsVendorFatalError(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void OsVendorInit(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern int OsInitColors(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+#if !defined(WIN32) && !defined(__EMX__)
+extern int System(char *);
+extern pointer Popen(char *, char *);
+extern int Pclose(pointer);
+#else
+#define System(a) system(a)
+#define Popen(a,b) popen(a,b)
+#define Pclose(a) pclose(a)
+#endif
+
+extern int AddHost(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ int /*family*/,
+ unsigned /*length*/,
+ pointer /*pAddr*/
+#endif
+);
+
+extern Bool ForEachHostInFamily (
+#if NeedFunctionPrototypes
+ int /*family*/,
+ Bool (* /*func*/ )(
+#if NeedNestedPrototypes
+ unsigned char * /* addr */,
+ short /* len */,
+ pointer /* closure */
+#endif
+ ),
+ pointer /*closure*/
+#endif
+);
+
+extern int RemoveHost(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ int /*family*/,
+ unsigned /*length*/,
+ pointer /*pAddr*/
+#endif
+);
+
+extern int GetHosts(
+#if NeedFunctionPrototypes
+ pointer * /*data*/,
+ int * /*pnHosts*/,
+ int * /*pLen*/,
+ BOOL * /*pEnabled*/
+#endif
+);
+
+typedef struct sockaddr * sockaddrPtr;
+
+extern int InvalidHost(
+#if NeedFunctionPrototypes
+ sockaddrPtr /*saddr*/,
+ int /*len*/
+#endif
+);
+
+extern int LocalClient(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */
+#endif
+);
+
+extern int ChangeAccessControl(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ int /*fEnabled*/
+#endif
+);
+
+extern int GetAccessControl(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+
+extern void AddLocalHosts(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void ResetHosts(
+#if NeedFunctionPrototypes
+ char *display
+#endif
+);
+
+extern void EnableLocalHost(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void DisableLocalHost(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void AccessUsingXdmcp(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void DefineSelf(
+#if NeedFunctionPrototypes
+ int /*fd*/
+#endif
+);
+
+extern void AugmentSelf(
+#if NeedFunctionPrototypes
+ pointer /*from*/,
+ int /*len*/
+#endif
+);
+
+extern void InitAuthorization(
+#if NeedFunctionPrototypes
+ char * /*filename*/
+#endif
+);
+
+extern int LoadAuthorization(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void RegisterAuthorizations(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern XID AuthorizationToID (
+ unsigned short name_length,
+ char *name,
+ unsigned short data_length,
+ char *data);
+
+extern int AuthorizationFromID (
+ XID id,
+ unsigned short *name_lenp,
+ char **namep,
+ unsigned short *data_lenp,
+ char **datap);
+
+extern XID CheckAuthorization(
+#if NeedFunctionPrototypes
+ unsigned int /*namelength*/,
+ char * /*name*/,
+ unsigned int /*datalength*/,
+ char * /*data*/,
+ ClientPtr /*client*/,
+ char ** /*reason*/
+#endif
+);
+
+extern void ResetAuthorization(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern int RemoveAuthorization (
+ unsigned short name_length,
+ char *name,
+ unsigned short data_length,
+ char *data);
+
+extern int AddAuthorization(
+#if NeedFunctionPrototypes
+ unsigned int /*name_length*/,
+ char * /*name*/,
+ unsigned int /*data_length*/,
+ char * /*data*/
+#endif
+);
+
+extern XID GenerateAuthorization(
+#if NeedFunctionPrototypes
+ unsigned int /* name_length */,
+ char * /* name */,
+ unsigned int /* data_length */,
+ char * /* data */,
+ unsigned int * /* data_length_return */,
+ char ** /* data_return */
+#endif
+);
+
+#ifdef COMMANDLINE_CHALLENGED_OPERATING_SYSTEMS
+extern void ExpandCommandLine(
+#if NeedFunctionPrototypes
+ int * /*pargc*/,
+ char *** /*pargv*/
+#endif
+);
+#endif
+
+extern int ddxProcessArgument(
+#if NeedFunctionPrototypes
+ int /*argc*/,
+ char * /*argv*/ [],
+ int /*i*/
+#endif
+);
+
+extern void ddxUseMsg(void);
+
+/*
+ * idiom processing stuff
+ */
+
+xReqPtr PeekNextRequest(
+#if NeedFunctionPrototypes
+ xReqPtr req, ClientPtr client, Bool readmore
+#endif
+);
+
+void SkipRequests(
+#if NeedFunctionPrototypes
+ xReqPtr req, ClientPtr client, int numskipped
+#endif
+);
+
+/* int ReqLen(xReq *req, ClientPtr client)
+ * Given a pointer to a *complete* request, return its length in bytes.
+ * Note that if the request is a big request (as defined in the Big
+ * Requests extension), the macro lies by returning 4 less than the
+ * length that it actually occupies in the request buffer. This is so you
+ * can blindly compare the length with the various sz_<request> constants
+ * in Xproto.h without having to know/care about big requests.
+ */
+#define ReqLen(_pxReq, _client) \
+ ((_pxReq->length ? \
+ (_client->swapped ? lswaps(_pxReq->length) : _pxReq->length) \
+ : ((_client->swapped ? \
+ lswapl(((CARD32*)_pxReq)[1]) : ((CARD32*)_pxReq)[1])-1) \
+ ) << 2)
+
+/* otherReqTypePtr CastxReq(xReq *req, otherReqTypePtr)
+ * Cast the given request to one of type otherReqTypePtr to access
+ * fields beyond the length field.
+ */
+#define CastxReq(_pxReq, otherReqTypePtr) \
+ (_pxReq->length ? (otherReqTypePtr)_pxReq \
+ : (otherReqTypePtr)(((CARD32*)_pxReq)+1))
+
+/* stuff for SkippedRequestsCallback */
+extern CallbackListPtr SkippedRequestsCallback;
+typedef struct {
+ xReqPtr req;
+ ClientPtr client;
+ int numskipped;
+} SkippedRequestInfoRec;
+
+/* stuff for ReplyCallback */
+extern CallbackListPtr ReplyCallback;
+typedef struct {
+ ClientPtr client;
+ pointer replyData;
+ unsigned long dataLenBytes;
+ unsigned long bytesRemaining;
+ Bool startOfReply;
+} ReplyInfoRec;
+
+/* stuff for FlushCallback */
+extern CallbackListPtr FlushCallback;
+
+extern void AbortDDX(void);
+extern void ddxGiveUp(void);
+extern int TimeSinceLastInputEvent(void);
+
+#endif /* OS_H */
diff --git a/xc/programs/Xserver/include/pixmap.h b/xc/programs/Xserver/include/pixmap.h
new file mode 100644
index 000000000..fb0d5143f
--- /dev/null
+++ b/xc/programs/Xserver/include/pixmap.h
@@ -0,0 +1,119 @@
+/* $TOG: pixmap.h /main/12 1998/02/09 14:29:25 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+#ifndef PIXMAP_H
+#define PIXMAP_H
+
+#include "misc.h"
+#include "screenint.h"
+
+/* types for Drawable */
+#define DRAWABLE_WINDOW 0
+#define DRAWABLE_PIXMAP 1
+#define UNDRAWABLE_WINDOW 2
+#define DRAWABLE_BUFFER 3
+
+/* flags to PaintWindow() */
+#define PW_BACKGROUND 0
+#define PW_BORDER 1
+
+#define NullPixmap ((PixmapPtr)0)
+
+typedef struct _Drawable *DrawablePtr;
+typedef struct _Pixmap *PixmapPtr;
+
+typedef union _PixUnion {
+ PixmapPtr pixmap;
+ unsigned long pixel;
+} PixUnion;
+
+#define SamePixUnion(a,b,isPixel)\
+ ((isPixel) ? (a).pixel == (b).pixel : (a).pixmap == (b).pixmap)
+
+#define EqualPixUnion(as, a, bs, b) \
+ ((as) == (bs) && (SamePixUnion (a, b, as)))
+
+#define OnScreenDrawable(type) \
+ ((type == DRAWABLE_WINDOW) || (type == DRAWABLE_BUFFER))
+
+#define WindowDrawable(type) \
+ ((type == DRAWABLE_WINDOW) || (type == UNDRAWABLE_WINDOW))
+
+extern PixmapPtr GetScratchPixmapHeader(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ int /*width*/,
+ int /*height*/,
+ int /*depth*/,
+ int /*bitsPerPixel*/,
+ int /*devKind*/,
+ pointer /*pPixData*/
+#endif
+);
+
+extern void FreeScratchPixmapHeader(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPixmap*/
+#endif
+);
+
+extern Bool CreateScratchPixmapsForScreen(
+#if NeedFunctionPrototypes
+ int /*scrnum*/
+#endif
+);
+
+extern void FreeScratchPixmapsForScreen(
+#if NeedFunctionPrototypes
+ int /*scrnum*/
+#endif
+);
+
+extern PixmapPtr AllocatePixmap(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ int /*pixDataSize*/
+#endif
+);
+
+#endif /* PIXMAP_H */
diff --git a/xc/programs/Xserver/include/pixmapstr.h b/xc/programs/Xserver/include/pixmapstr.h
new file mode 100644
index 000000000..215772e45
--- /dev/null
+++ b/xc/programs/Xserver/include/pixmapstr.h
@@ -0,0 +1,79 @@
+/* $TOG: pixmapstr.h /main/11 1998/02/09 14:29:22 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#ifndef PIXMAPSTRUCT_H
+#define PIXMAPSTRUCT_H
+#include "pixmap.h"
+#include "screenint.h"
+#include "miscstruct.h"
+
+typedef struct _Drawable {
+ unsigned char type; /* DRAWABLE_<type> */
+ unsigned char class; /* specific to type */
+ unsigned char depth;
+ unsigned char bitsPerPixel;
+ unsigned long id; /* resource id */
+ short x; /* window: screen absolute, pixmap: 0 */
+ short y; /* window: screen absolute, pixmap: 0 */
+ unsigned short width;
+ unsigned short height;
+ ScreenPtr pScreen;
+ unsigned long serialNumber;
+} DrawableRec;
+
+/*
+ * PIXMAP -- device dependent
+ */
+
+typedef struct _Pixmap {
+ DrawableRec drawable;
+ int refcnt;
+ int devKind;
+ DevUnion devPrivate;
+#ifdef PIXPRIV
+ DevUnion *devPrivates; /* real devPrivates like gcs & windows */
+#endif
+} PixmapRec;
+
+#endif /* PIXMAPSTRUCT_H */
diff --git a/xc/programs/Xserver/include/property.h b/xc/programs/Xserver/include/property.h
new file mode 100644
index 000000000..c77a7b87a
--- /dev/null
+++ b/xc/programs/Xserver/include/property.h
@@ -0,0 +1,74 @@
+/* $TOG: property.h /main/6 1998/02/09 14:29:34 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+#ifndef PROPERTY_H
+#define PROPERTY_H
+typedef struct _Property *PropertyPtr;
+
+extern int ChangeWindowProperty(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ Atom /*property*/,
+ Atom /*type*/,
+ int /*format*/,
+ int /*mode*/,
+ unsigned long /*len*/,
+ pointer /*value*/,
+ Bool /*sendevent*/
+#endif
+);
+
+extern int DeleteProperty(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ Atom /*propName*/
+#endif
+);
+
+extern void DeleteAllWindowProperties(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+#endif /* PROPERTY_H */
diff --git a/xc/programs/Xserver/include/propertyst.h b/xc/programs/Xserver/include/propertyst.h
new file mode 100644
index 000000000..9cad26888
--- /dev/null
+++ b/xc/programs/Xserver/include/propertyst.h
@@ -0,0 +1,72 @@
+/* $TOG: propertyst.h /main/6 1998/02/09 14:29:30 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/include/propertyst.h,v 3.1 1998/10/04 09:39:00 dawes Exp $ */
+
+#ifndef PROPERTYSTRUCT_H
+#define PROPERTYSTRUCT_H
+#include "misc.h"
+#include "property.h"
+/*
+ * PROPERTY -- property element
+ */
+
+typedef struct _Property {
+ struct _Property *next;
+ ATOM propertyName;
+ ATOM type; /* ignored by server */
+ short format; /* format of data for swapping - 8,16,32 */
+ long size; /* size of data in (format/8) bytes */
+ pointer data; /* private to client */
+#if defined(LBX) || defined(LBX_COMPAT)
+ /* If space is at a premium and binary compatibility is not
+ * an issue, you may want to put the owner_pid next to format
+ * so that the two shorts pack together without padding.
+ */
+ short owner_pid; /* proxy that has the data */
+ XID tag_id;
+#endif
+} PropertyRec;
+
+#endif /* PROPERTYSTRUCT_H */
+
diff --git a/xc/programs/Xserver/include/region.h b/xc/programs/Xserver/include/region.h
new file mode 100644
index 000000000..863d95dad
--- /dev/null
+++ b/xc/programs/Xserver/include/region.h
@@ -0,0 +1,49 @@
+/* $TOG: region.h /main/6 1998/02/09 14:29:42 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+#ifndef REGION_H
+#define REGION_H
+
+#include "regionstr.h"
+
+#endif /* REGION_H */
diff --git a/xc/programs/Xserver/include/regionstr.h b/xc/programs/Xserver/include/regionstr.h
new file mode 100644
index 000000000..84ffe5438
--- /dev/null
+++ b/xc/programs/Xserver/include/regionstr.h
@@ -0,0 +1,404 @@
+/* $TOG: regionstr.h /main/9 1998/02/09 14:29:38 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+#ifndef REGIONSTRUCT_H
+#define REGIONSTRUCT_H
+
+#include "miscstruct.h"
+
+/* Return values from RectIn() */
+
+#define rgnOUT 0
+#define rgnIN 1
+#define rgnPART 2
+
+#define NullRegion ((RegionPtr)0)
+
+/*
+ * clip region
+ */
+
+typedef struct _RegData {
+ long size;
+ long numRects;
+/* BoxRec rects[size]; in memory but not explicitly declared */
+} RegDataRec, *RegDataPtr;
+
+typedef struct _Region {
+ BoxRec extents;
+ RegDataPtr data;
+} RegionRec, *RegionPtr;
+
+extern BoxRec miEmptyBox;
+extern RegDataRec miEmptyData;
+
+#define REGION_NIL(reg) ((reg)->data && !(reg)->data->numRects)
+#define REGION_NUM_RECTS(reg) ((reg)->data ? (reg)->data->numRects : 1)
+#define REGION_SIZE(reg) ((reg)->data ? (reg)->data->size : 0)
+#define REGION_RECTS(reg) ((reg)->data ? (BoxPtr)((reg)->data + 1) \
+ : &(reg)->extents)
+#define REGION_BOXPTR(reg) ((BoxPtr)((reg)->data + 1))
+#define REGION_BOX(reg,i) (&REGION_BOXPTR(reg)[i])
+#define REGION_TOP(reg) REGION_BOX(reg, (reg)->data->numRects)
+#define REGION_END(reg) REGION_BOX(reg, (reg)->data->numRects - 1)
+#define REGION_SZOF(n) (sizeof(RegDataRec) + ((n) * sizeof(BoxRec)))
+
+#ifdef NEED_SCREEN_REGIONS
+
+#define REGION_CREATE(_pScreen, _rect, _size) \
+ (*(_pScreen)->RegionCreate)(_rect, _size)
+
+#define REGION_INIT(_pScreen, _pReg, _rect, _size) \
+ (*(_pScreen)->RegionInit)(_pReg, _rect, _size)
+
+#define REGION_COPY(_pScreen, dst, src) \
+ (*(_pScreen)->RegionCopy)(dst, src)
+
+#define REGION_DESTROY(_pScreen, _pReg) \
+ (*(_pScreen)->RegionDestroy)(_pReg)
+
+#define REGION_UNINIT(_pScreen, _pReg) \
+ (*(_pScreen)->RegionUninit)(_pReg)
+
+#define REGION_INTERSECT(_pScreen, newReg, reg1, reg2) \
+ (*(_pScreen)->Intersect)(newReg, reg1, reg2)
+
+#define REGION_UNION(_pScreen, newReg, reg1, reg2) \
+ (*(_pScreen)->Union)(newReg, reg1, reg2)
+
+#define REGION_SUBTRACT(_pScreen, newReg, reg1, reg2) \
+ (*(_pScreen)->Subtract)(newReg, reg1, reg2)
+
+#define REGION_INVERSE(_pScreen, newReg, reg1, invRect) \
+ (*(_pScreen)->Inverse)(newReg, reg1, invRect)
+
+#define REGION_RESET(_pScreen, _pReg, _pBox) \
+ (*(_pScreen)->RegionReset)(_pReg, _pBox)
+
+#define REGION_TRANSLATE(_pScreen, _pReg, _x, _y) \
+ (*(_pScreen)->TranslateRegion)(_pReg, _x, _y)
+
+#define RECT_IN_REGION(_pScreen, _pReg, prect) \
+ (*(_pScreen)->RectIn)(_pReg, prect)
+
+#define POINT_IN_REGION(_pScreen, _pReg, _x, _y, prect) \
+ (*(_pScreen)->PointInRegion)(_pReg, _x, _y, prect)
+
+#define REGION_NOTEMPTY(_pScreen, _pReg) \
+ (*(_pScreen)->RegionNotEmpty)(_pReg)
+
+#define REGION_EMPTY(_pScreen, _pReg) \
+ (*(_pScreen)->RegionEmpty)(_pReg)
+
+#define REGION_EXTENTS(_pScreen, _pReg) \
+ (*(_pScreen)->RegionExtents)(_pReg)
+
+#define REGION_APPEND(_pScreen, dstrgn, rgn) \
+ (*(_pScreen)->RegionAppend)(dstrgn, rgn)
+
+#define REGION_VALIDATE(_pScreen, badreg, pOverlap) \
+ (*(_pScreen)->RegionValidate)(badreg, pOverlap)
+
+#define BITMAP_TO_REGION(_pScreen, pPix) \
+ (*(_pScreen)->BitmapToRegion)(pPix)
+
+#define RECTS_TO_REGION(_pScreen, nrects, prect, ctype) \
+ (*(_pScreen)->RectsToRegion)(nrects, prect, ctype)
+
+#else /* !NEED_SCREEN_REGIONS */
+
+#define REGION_CREATE(_pScreen, _rect, _size) \
+ miRegionCreate(_rect, _size)
+
+#define REGION_COPY(_pScreen, dst, src) \
+ miRegionCopy(dst, src)
+
+#define REGION_DESTROY(_pScreen, _pReg) \
+ miRegionDestroy(_pReg)
+
+#define REGION_INTERSECT(_pScreen, newReg, reg1, reg2) \
+ miIntersect(newReg, reg1, reg2)
+
+#define REGION_UNION(_pScreen, newReg, reg1, reg2) \
+ miUnion(newReg, reg1, reg2)
+
+#define REGION_SUBTRACT(_pScreen, newReg, reg1, reg2) \
+ miSubtract(newReg, reg1, reg2)
+
+#define REGION_INVERSE(_pScreen, newReg, reg1, invRect) \
+ miInverse(newReg, reg1, invRect)
+
+#define REGION_TRANSLATE(_pScreen, _pReg, _x, _y) \
+ miTranslateRegion(_pReg, _x, _y)
+
+#define RECT_IN_REGION(_pScreen, _pReg, prect) \
+ miRectIn(_pReg, prect)
+
+#define POINT_IN_REGION(_pScreen, _pReg, _x, _y, prect) \
+ miPointInRegion(_pReg, _x, _y, prect)
+
+#define REGION_APPEND(_pScreen, dstrgn, rgn) \
+ miRegionAppend(dstrgn, rgn)
+
+#define REGION_VALIDATE(_pScreen, badreg, pOverlap) \
+ miRegionValidate(badreg, pOverlap)
+
+#define BITMAP_TO_REGION(_pScreen, pPix) \
+ (*(_pScreen)->BitmapToRegion)(pPix) /* no mi version?! */
+
+#define RECTS_TO_REGION(_pScreen, nrects, prect, ctype) \
+ miRectsToRegion(nrects, prect, ctype)
+
+#ifdef DONT_INLINE_REGION_OPS
+
+#define REGION_INIT(_pScreen, _pReg, _rect, _size) \
+ miRegionInit(_pReg, _rect, _size)
+
+#define REGION_UNINIT(_pScreen, _pReg) \
+ miRegionUninit(_pReg)
+
+#define REGION_RESET(_pScreen, _pReg, _pBox) \
+ miRegionReset(_pReg, _pBox)
+
+#define REGION_NOTEMPTY(_pScreen, _pReg) \
+ miRegionNotEmpty(_pReg)
+
+#define REGION_EMPTY(_pScreen, _pReg) \
+ miRegionEmpty(_pReg)
+
+#define REGION_EXTENTS(_pScreen, _pReg) \
+ miRegionExtents(_pReg)
+
+#else /* inline certain simple region ops for performance */
+
+#define REGION_INIT(_pScreen, _pReg, _rect, _size) \
+{ \
+ if (_rect) \
+ { \
+ (_pReg)->extents = *(_rect); \
+ (_pReg)->data = (RegDataPtr)NULL; \
+ } \
+ else \
+ { \
+ (_pReg)->extents = miEmptyBox; \
+ if (((_size) > 1) && ((_pReg)->data = \
+ (RegDataPtr)xalloc(REGION_SZOF(_size)))) \
+ { \
+ (_pReg)->data->size = (_size); \
+ (_pReg)->data->numRects = 0; \
+ } \
+ else \
+ (_pReg)->data = &miEmptyData; \
+ } \
+}
+
+#define REGION_UNINIT(_pScreen, _pReg) \
+{ \
+ if ((_pReg)->data && (_pReg)->data->size) xfree((_pReg)->data); \
+}
+
+#define REGION_RESET(_pScreen, _pReg, _pBox) \
+{ \
+ (_pReg)->extents = *(_pBox); \
+ REGION_UNINIT(_pScreen, _pReg); \
+ (_pReg)->data = (RegDataPtr)NULL; \
+}
+
+#define REGION_NOTEMPTY(_pScreen, _pReg) \
+ !REGION_NIL(_pReg)
+
+#define REGION_EMPTY(_pScreen, _pReg) \
+{ \
+ REGION_UNINIT(_pScreen, _pReg); \
+ (_pReg)->extents.x2 = (_pReg)->extents.x1; \
+ (_pReg)->extents.y2 = (_pReg)->extents.y1; \
+ (_pReg)->data = &miEmptyData; \
+}
+
+#define REGION_EXTENTS(_pScreen, _pReg) \
+ &(_pReg)->extents
+
+#endif /* DONT_INLINE_REGION_OPS */
+
+#endif /* NEED_SCREEN_REGIONS */
+
+/* moved from mi.h */
+
+extern RegionPtr miRegionCreate(
+#if NeedFunctionPrototypes
+ BoxPtr /*rect*/,
+ int /*size*/
+#endif
+);
+
+extern void miRegionInit(
+#if NeedFunctionPrototypes
+ RegionPtr /*pReg*/,
+ BoxPtr /*rect*/,
+ int /*size*/
+#endif
+);
+
+extern void miRegionDestroy(
+#if NeedFunctionPrototypes
+ RegionPtr /*pReg*/
+#endif
+);
+
+extern void miRegionUninit(
+#if NeedFunctionPrototypes
+ RegionPtr /*pReg*/
+#endif
+);
+
+extern Bool miRegionCopy(
+#if NeedFunctionPrototypes
+ RegionPtr /*dst*/,
+ RegionPtr /*src*/
+#endif
+);
+
+extern Bool miIntersect(
+#if NeedFunctionPrototypes
+ RegionPtr /*newReg*/,
+ RegionPtr /*reg1*/,
+ RegionPtr /*reg2*/
+#endif
+);
+
+extern Bool miUnion(
+#if NeedFunctionPrototypes
+ RegionPtr /*newReg*/,
+ RegionPtr /*reg1*/,
+ RegionPtr /*reg2*/
+#endif
+);
+
+extern Bool miRegionAppend(
+#if NeedFunctionPrototypes
+ RegionPtr /*dstrgn*/,
+ RegionPtr /*rgn*/
+#endif
+);
+
+extern Bool miRegionValidate(
+#if NeedFunctionPrototypes
+ RegionPtr /*badreg*/,
+ Bool * /*pOverlap*/
+#endif
+);
+
+extern RegionPtr miRectsToRegion(
+#if NeedFunctionPrototypes
+ int /*nrects*/,
+ xRectanglePtr /*prect*/,
+ int /*ctype*/
+#endif
+);
+
+extern Bool miSubtract(
+#if NeedFunctionPrototypes
+ RegionPtr /*regD*/,
+ RegionPtr /*regM*/,
+ RegionPtr /*regS*/
+#endif
+);
+
+extern Bool miInverse(
+#if NeedFunctionPrototypes
+ RegionPtr /*newReg*/,
+ RegionPtr /*reg1*/,
+ BoxPtr /*invRect*/
+#endif
+);
+
+extern int miRectIn(
+#if NeedFunctionPrototypes
+ RegionPtr /*region*/,
+ BoxPtr /*prect*/
+#endif
+);
+
+extern void miTranslateRegion(
+#if NeedFunctionPrototypes
+ RegionPtr /*pReg*/,
+ int /*x*/,
+ int /*y*/
+#endif
+);
+
+extern void miRegionReset(
+#if NeedFunctionPrototypes
+ RegionPtr /*pReg*/,
+ BoxPtr /*pBox*/
+#endif
+);
+
+extern Bool miPointInRegion(
+#if NeedFunctionPrototypes
+ RegionPtr /*pReg*/,
+ int /*x*/,
+ int /*y*/,
+ BoxPtr /*box*/
+#endif
+);
+
+extern Bool miRegionNotEmpty(
+#if NeedFunctionPrototypes
+ RegionPtr /*pReg*/
+#endif
+);
+
+extern void miRegionEmpty(
+#if NeedFunctionPrototypes
+ RegionPtr /*pReg*/
+#endif
+);
+
+extern BoxPtr miRegionExtents(
+#if NeedFunctionPrototypes
+ RegionPtr /*pReg*/
+#endif
+);
+
+#endif /* REGIONSTRUCT_H */
diff --git a/xc/programs/Xserver/include/resource.h b/xc/programs/Xserver/include/resource.h
new file mode 100644
index 000000000..0b0f714a6
--- /dev/null
+++ b/xc/programs/Xserver/include/resource.h
@@ -0,0 +1,277 @@
+/* $TOG: resource.h /main/24 1998/02/09 14:29:47 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+#ifndef RESOURCE_H
+#define RESOURCE_H 1
+#include "misc.h"
+
+/*****************************************************************
+ * STUFF FOR RESOURCES
+ *****************************************************************/
+
+/* classes for Resource routines */
+
+typedef unsigned long RESTYPE;
+
+#define RC_VANILLA ((RESTYPE)0)
+#define RC_CACHED ((RESTYPE)1<<31)
+#define RC_DRAWABLE ((RESTYPE)1<<30)
+/* Use class RC_NEVERRETAIN for resources that should not be retained
+ * regardless of the close down mode when the client dies. (A client's
+ * event selections on objects that it doesn't own are good candidates.)
+ * Extensions can use this too!
+ */
+#define RC_NEVERRETAIN ((RESTYPE)1<<29)
+#define RC_LASTPREDEF RC_NEVERRETAIN
+#define RC_ANY (~(RESTYPE)0)
+
+/* types for Resource routines */
+
+#define RT_WINDOW ((RESTYPE)1|RC_CACHED|RC_DRAWABLE)
+#define RT_PIXMAP ((RESTYPE)2|RC_CACHED|RC_DRAWABLE)
+#define RT_GC ((RESTYPE)3|RC_CACHED)
+#define RT_FONT ((RESTYPE)4)
+#define RT_CURSOR ((RESTYPE)5)
+#define RT_COLORMAP ((RESTYPE)6)
+#define RT_CMAPENTRY ((RESTYPE)7)
+#define RT_OTHERCLIENT ((RESTYPE)8|RC_NEVERRETAIN)
+#define RT_PASSIVEGRAB ((RESTYPE)9|RC_NEVERRETAIN)
+#define RT_LASTPREDEF ((RESTYPE)9)
+#define RT_NONE ((RESTYPE)0)
+
+/* bits and fields within a resource id */
+#define CLIENTOFFSET 22 /* client field */
+#define RESOURCE_ID_MASK 0x3FFFFF /* low 22 bits */
+#define CLIENT_BITS(id) ((id) & 0x1fc00000) /* hi 7 bits */
+#define CLIENT_ID(id) ((int)(CLIENT_BITS(id) >> CLIENTOFFSET))
+#define SERVER_BIT 0x20000000 /* use illegal bit */
+
+#ifdef INVALID
+#undef INVALID /* needed on HP/UX */
+#endif
+
+/* Invalid resource id */
+#define INVALID (0)
+
+#define BAD_RESOURCE 0xe0000000
+
+typedef int (*DeleteType)(
+#if NeedNestedPrototypes
+ pointer /*value*/,
+ XID /*id*/
+#endif
+);
+
+typedef void (*FindResType)(
+#if NeedNestedPrototypes
+ pointer /*value*/,
+ XID /*id*/,
+ pointer /*cdata*/
+#endif
+);
+
+extern RESTYPE CreateNewResourceType(
+#if NeedFunctionPrototypes
+ DeleteType /*deleteFunc*/
+#endif
+);
+
+extern RESTYPE CreateNewResourceClass(
+#if NeedFunctionPrototypes
+void
+#endif
+);
+
+extern Bool InitClientResources(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern XID FakeClientID(
+#if NeedFunctionPrototypes
+ int /*client*/
+#endif
+);
+
+extern Bool AddResource(
+#if NeedFunctionPrototypes
+ XID /*id*/,
+ RESTYPE /*type*/,
+ pointer /*value*/
+#endif
+);
+
+extern void FreeResource(
+#if NeedFunctionPrototypes
+ XID /*id*/,
+ RESTYPE /*skipDeleteFuncType*/
+#endif
+);
+
+extern void FreeResourceByType(
+#if NeedFunctionPrototypes
+ XID /*id*/,
+ RESTYPE /*type*/,
+ Bool /*skipFree*/
+#endif
+);
+
+extern Bool ChangeResourceValue(
+#if NeedFunctionPrototypes
+ XID /*id*/,
+ RESTYPE /*rtype*/,
+ pointer /*value*/
+#endif
+);
+
+extern void FindClientResourcesByType(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ RESTYPE /*type*/,
+ FindResType /*func*/,
+ pointer /*cdata*/
+#endif
+);
+
+extern void FreeClientNeverRetainResources(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern void FreeClientResources(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern void FreeAllResources(
+#if NeedFunctionPrototypes
+void
+#endif
+);
+
+extern Bool LegalNewID(
+#if NeedFunctionPrototypes
+ XID /*id*/,
+ ClientPtr /*client*/
+#endif
+);
+
+extern pointer LookupIDByType(
+#if NeedFunctionPrototypes
+ XID /*id*/,
+ RESTYPE /*rtype*/
+#endif
+);
+
+extern pointer LookupIDByClass(
+#if NeedFunctionPrototypes
+ XID /*id*/,
+ RESTYPE /*classes*/
+#endif
+);
+
+/* These are the access modes that can be passed in the last parameter
+ * to SecurityLookupIDByType/Class. The Security extension doesn't
+ * currently make much use of these; they're mainly provided as an
+ * example of what you might need for discretionary access control.
+ * You can or these values together to indicate multiple modes
+ * simultaneously.
+ */
+
+#define SecurityUnknownAccess 0 /* don't know intentions */
+#define SecurityReadAccess (1<<0) /* inspecting the object */
+#define SecurityWriteAccess (1<<1) /* changing the object */
+#define SecurityDestroyAccess (1<<2) /* destroying the object */
+
+#ifdef XCSECURITY
+
+extern pointer SecurityLookupIDByType(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ XID /*id*/,
+ RESTYPE /*rtype*/,
+ Mask /*access_mode*/
+#endif
+);
+
+extern pointer SecurityLookupIDByClass(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ XID /*id*/,
+ RESTYPE /*classes*/,
+ Mask /*access_mode*/
+#endif
+);
+
+#else /* not XCSECURITY */
+
+#define SecurityLookupIDByType(client, id, rtype, access_mode) \
+ LookupIDByType(id, rtype)
+
+#define SecurityLookupIDByClass(client, id, classes, access_mode) \
+ LookupIDByClass(id, classes)
+
+#endif /* XCSECURITY */
+
+extern void GetXIDRange(
+#if NeedFunctionPrototypes
+ int /*client*/,
+ Bool /*server*/,
+ XID * /*minp*/,
+ XID * /*maxp*/
+#endif
+);
+
+extern unsigned int GetXIDList(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ unsigned int /*count*/,
+ XID * /*pids*/
+#endif
+);
+
+#endif /* RESOURCE_H */
+
diff --git a/xc/programs/Xserver/include/rgb.h b/xc/programs/Xserver/include/rgb.h
new file mode 100644
index 000000000..10b98dd20
--- /dev/null
+++ b/xc/programs/Xserver/include/rgb.h
@@ -0,0 +1,50 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: rgb.h /main/5 1998/02/09 14:29:51 kaleb $ */
+
+#ifndef RGB_H
+#define RGB_H
+typedef struct _RGB {
+ unsigned short red, green, blue;
+ } RGB;
+#endif /* RGB_H */
diff --git a/xc/programs/Xserver/include/screenint.h b/xc/programs/Xserver/include/screenint.h
new file mode 100644
index 000000000..b49d4d033
--- /dev/null
+++ b/xc/programs/Xserver/include/screenint.h
@@ -0,0 +1,166 @@
+/* $TOG: screenint.h /main/7 1998/02/09 14:29:55 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/include/screenint.h,v 1.3 1998/10/04 09:39:00 dawes Exp $ */
+#ifndef SCREENINT_H
+#define SCREENINT_H
+
+#include "misc.h"
+
+typedef struct _PixmapFormat *PixmapFormatPtr;
+typedef struct _Visual *VisualPtr;
+typedef struct _Depth *DepthPtr;
+typedef struct _Screen *ScreenPtr;
+
+extern void ResetScreenPrivates(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern int AllocateScreenPrivateIndex(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void ResetWindowPrivates(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern int AllocateWindowPrivateIndex(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern Bool AllocateWindowPrivate(
+#if NeedFunctionPrototypes
+ ScreenPtr /* pScreen */,
+ int /* index */,
+ unsigned /* amount */
+#endif
+);
+
+extern void ResetGCPrivates(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern int AllocateGCPrivateIndex(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern Bool AllocateGCPrivate(
+#if NeedFunctionPrototypes
+ ScreenPtr /* pScreen */,
+ int /* index */,
+ unsigned /* amount */
+#endif
+);
+
+extern int AddScreen(
+#if NeedFunctionPrototypes
+ Bool (* /*pfnInit*/)(
+#if NeedNestedPrototypes
+ int /*index*/,
+ ScreenPtr /*pScreen*/,
+ int /*argc*/,
+ char ** /*argv*/
+#endif
+ ),
+ int /*argc*/,
+ char** /*argv*/
+#endif
+);
+
+#ifdef PIXPRIV
+
+extern void ResetPixmapPrivates(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern int AllocatePixmapPrivateIndex(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern Bool AllocatePixmapPrivate(
+#if NeedFunctionPrototypes
+ ScreenPtr /* pScreen */,
+ int /* index */,
+ unsigned /* amount */
+#endif
+);
+
+#endif /* PIXPRIV */
+
+extern void ResetColormapPrivates(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+
+typedef struct _ColormapRec *ColormapPtr;
+typedef int (*InitCmapPrivFunc)(
+#if NeedNestedPrototypes
+ ColormapPtr
+#endif
+);
+
+extern int AllocateColormapPrivateIndex(
+#if NeedFunctionPrototypes
+ InitCmapPrivFunc /* initPrivFunc */
+#endif
+);
+
+#endif /* SCREENINT_H */
diff --git a/xc/programs/Xserver/include/scrnintstr.h b/xc/programs/Xserver/include/scrnintstr.h
new file mode 100644
index 000000000..e496e8ebe
--- /dev/null
+++ b/xc/programs/Xserver/include/scrnintstr.h
@@ -0,0 +1,958 @@
+/* $TOG: scrnintstr.h /main/33 1998/02/09 14:29:59 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/include/scrnintstr.h,v 1.4 1999/08/21 13:48:45 dawes Exp $ */
+
+#ifndef SCREENINTSTRUCT_H
+#define SCREENINTSTRUCT_H
+
+#include "screenint.h"
+#include "miscstruct.h"
+#include "bstore.h"
+#include "colormap.h"
+#include "cursor.h"
+#include "validate.h"
+#include "X11/Xproto.h"
+#include "dix.h"
+
+typedef struct _PixmapFormat {
+ unsigned char depth;
+ unsigned char bitsPerPixel;
+ unsigned char scanlinePad;
+ } PixmapFormatRec;
+
+typedef struct _Visual {
+ VisualID vid;
+ short class;
+ short bitsPerRGBValue;
+ short ColormapEntries;
+ short nplanes;/* = log2 (ColormapEntries). This does not
+ * imply that the screen has this many planes.
+ * it may have more or fewer */
+ unsigned long redMask, greenMask, blueMask;
+ int offsetRed, offsetGreen, offsetBlue;
+ } VisualRec;
+
+typedef struct _Depth {
+ unsigned char depth;
+ short numVids;
+ VisualID *vids; /* block of visual ids for this depth */
+ } DepthRec;
+
+
+/*
+ * There is a typedef for each screen function pointer so that code that
+ * needs to declare a screen function pointer (e.g. in a screen private
+ * or as a local variable) can easily do so and retain full type checking.
+ */
+
+typedef Bool (* CloseScreenProcPtr)(
+#if NeedNestedPrototypes
+ int /*index*/,
+ ScreenPtr /*pScreen*/
+#endif
+);
+
+typedef void (* QueryBestSizeProcPtr)(
+#if NeedNestedPrototypes
+ int /*class*/,
+ unsigned short * /*pwidth*/,
+ unsigned short * /*pheight*/,
+ ScreenPtr /*pScreen*/
+#endif
+);
+
+typedef Bool (* SaveScreenProcPtr)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ int /*on*/
+#endif
+);
+
+typedef void (* GetImageProcPtr)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*sx*/,
+ int /*sy*/,
+ int /*w*/,
+ int /*h*/,
+ unsigned int /*format*/,
+ unsigned long /*planeMask*/,
+ char * /*pdstLine*/
+#endif
+);
+
+typedef void (* GetSpansProcPtr)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*wMax*/,
+ DDXPointPtr /*ppt*/,
+ int* /*pwidth*/,
+ int /*nspans*/,
+ char * /*pdstStart*/
+#endif
+);
+
+typedef void (* PointerNonInterestBoxProcPtr)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ BoxPtr /*pBox*/
+#endif
+);
+
+typedef void (* SourceValidateProcPtr)(
+#if NeedNestedPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*x*/,
+ int /*y*/,
+ int /*width*/,
+ int /*height*/
+#endif
+);
+
+typedef Bool (* CreateWindowProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWindow*/
+#endif
+);
+
+typedef Bool (* DestroyWindowProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWindow*/
+#endif
+);
+
+typedef Bool (* PositionWindowProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWindow*/,
+ int /*x*/,
+ int /*y*/
+#endif
+);
+
+typedef Bool (* ChangeWindowAttributesProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWindow*/,
+ unsigned long /*mask*/
+#endif
+);
+
+typedef Bool (* RealizeWindowProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWindow*/
+#endif
+);
+
+typedef Bool (* UnrealizeWindowProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWindow*/
+#endif
+);
+
+typedef int (* ValidateTreeProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pParent*/,
+ WindowPtr /*pChild*/,
+ VTKind /*kind*/
+#endif
+);
+
+typedef void (* PostValidateTreeProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pParent*/,
+ WindowPtr /*pChild*/,
+ VTKind /*kind*/
+#endif
+);
+
+typedef void (* WindowExposuresProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWindow*/,
+ RegionPtr /*prgn*/,
+ RegionPtr /*other_exposed*/
+#endif
+);
+
+typedef void (* PaintWindowProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWindow*/,
+ RegionPtr /*pRegion*/,
+ int /*what*/
+#endif
+);
+
+typedef PaintWindowProcPtr PaintWindowBackgroundProcPtr;
+typedef PaintWindowProcPtr PaintWindowBorderProcPtr;
+
+typedef void (* CopyWindowProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWindow*/,
+ DDXPointRec /*ptOldOrg*/,
+ RegionPtr /*prgnSrc*/
+#endif
+);
+
+typedef void (* ClearToBackgroundProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWindow*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ Bool /*generateExposures*/
+#endif
+);
+
+typedef void (* ClipNotifyProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWindow*/,
+ int /*dx*/,
+ int /*dy*/
+#endif
+);
+
+typedef PixmapPtr (* CreatePixmapProcPtr)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ int /*width*/,
+ int /*height*/,
+ int /*depth*/
+#endif
+);
+
+typedef Bool (* DestroyPixmapProcPtr)(
+#if NeedNestedPrototypes
+ PixmapPtr /*pPixmap*/
+#endif
+);
+
+typedef void (* SaveDoomedAreasProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWindow*/,
+ RegionPtr /*prgnSave*/,
+ int /*xorg*/,
+ int /*yorg*/
+#endif
+);
+
+typedef RegionPtr (* RestoreAreasProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWindow*/,
+ RegionPtr /*prgnRestore*/
+#endif
+);
+
+typedef void (* ExposeCopyProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ GCPtr /*pGC*/,
+ RegionPtr /*prgnExposed*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*dstx*/,
+ int /*dsty*/,
+ unsigned long /*plane*/
+#endif
+);
+
+typedef RegionPtr (* TranslateBackingStoreProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWindow*/,
+ int /*windx*/,
+ int /*windy*/,
+ RegionPtr /*oldClip*/,
+ int /*oldx*/,
+ int /*oldy*/
+#endif
+);
+
+typedef RegionPtr (* ClearBackingStoreProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWindow*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ Bool /*generateExposures*/
+#endif
+);
+
+typedef void (* DrawGuaranteeProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWindow*/,
+ GCPtr /*pGC*/,
+ int /*guarantee*/
+#endif
+);
+
+typedef Bool (* RealizeFontProcPtr)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ FontPtr /*pFont*/
+#endif
+);
+
+typedef Bool (* UnrealizeFontProcPtr)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ FontPtr /*pFont*/
+#endif
+);
+
+typedef void (* ConstrainCursorProcPtr)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ BoxPtr /*pBox*/
+#endif
+);
+
+typedef void (* CursorLimitsProcPtr)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/,
+ BoxPtr /*pHotBox*/,
+ BoxPtr /*pTopLeftBox*/
+#endif
+);
+
+typedef Bool (* DisplayCursorProcPtr)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/
+#endif
+);
+
+typedef Bool (* RealizeCursorProcPtr)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/
+#endif
+);
+
+typedef Bool (* UnrealizeCursorProcPtr)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/
+#endif
+);
+
+typedef void (* RecolorCursorProcPtr)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/,
+ Bool /*displayed*/
+#endif
+);
+
+typedef Bool (* SetCursorPositionProcPtr)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ int /*x*/,
+ int /*y*/,
+ Bool /*generateEvent*/
+#endif
+);
+
+typedef Bool (* CreateGCProcPtr)(
+#if NeedNestedPrototypes
+ GCPtr /*pGC*/
+#endif
+);
+
+typedef Bool (* CreateColormapProcPtr)(
+#if NeedNestedPrototypes
+ ColormapPtr /*pColormap*/
+#endif
+);
+
+typedef void (* DestroyColormapProcPtr)(
+#if NeedNestedPrototypes
+ ColormapPtr /*pColormap*/
+#endif
+);
+
+typedef void (* InstallColormapProcPtr)(
+#if NeedNestedPrototypes
+ ColormapPtr /*pColormap*/
+#endif
+);
+
+typedef void (* UninstallColormapProcPtr)(
+#if NeedNestedPrototypes
+ ColormapPtr /*pColormap*/
+#endif
+);
+
+typedef int (* ListInstalledColormapsProcPtr) (
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ XID* /*pmaps */
+#endif
+);
+
+typedef void (* StoreColorsProcPtr)(
+#if NeedNestedPrototypes
+ ColormapPtr /*pColormap*/,
+ int /*ndef*/,
+ xColorItem * /*pdef*/
+#endif
+);
+
+typedef void (* ResolveColorProcPtr)(
+#if NeedNestedPrototypes
+ unsigned short* /*pred*/,
+ unsigned short* /*pgreen*/,
+ unsigned short* /*pblue*/,
+ VisualPtr /*pVisual*/
+#endif
+);
+
+typedef RegionPtr (* RegionCreateProcPtr)(
+#if NeedNestedPrototypes
+ BoxPtr /*rect*/,
+ int /*size*/
+#endif
+);
+
+typedef void (* RegionInitProcPtr)(
+#if NeedNestedPrototypes
+ RegionPtr /*pReg*/,
+ BoxPtr /*rect*/,
+ int /*size*/
+#endif
+);
+
+typedef Bool (* RegionCopyProcPtr)(
+#if NeedNestedPrototypes
+ RegionPtr /*dst*/,
+ RegionPtr /*src*/
+#endif
+);
+
+typedef void (* RegionDestroyProcPtr)(
+#if NeedNestedPrototypes
+ RegionPtr /*pReg*/
+#endif
+);
+
+typedef void (* RegionUninitProcPtr)(
+#if NeedNestedPrototypes
+ RegionPtr /*pReg*/
+#endif
+);
+
+typedef Bool (* IntersectProcPtr)(
+#if NeedNestedPrototypes
+ RegionPtr /*newReg*/,
+ RegionPtr /*reg1*/,
+ RegionPtr /*reg2*/
+#endif
+);
+
+typedef Bool (* UnionProcPtr)(
+#if NeedNestedPrototypes
+ RegionPtr /*newReg*/,
+ RegionPtr /*reg1*/,
+ RegionPtr /*reg2*/
+#endif
+);
+
+typedef Bool (* SubtractProcPtr)(
+#if NeedNestedPrototypes
+ RegionPtr /*regD*/,
+ RegionPtr /*regM*/,
+ RegionPtr /*regS*/
+#endif
+);
+
+typedef Bool (* InverseProcPtr)(
+#if NeedNestedPrototypes
+ RegionPtr /*newReg*/,
+ RegionPtr /*reg1*/,
+ BoxPtr /*invRect*/
+#endif
+);
+
+typedef void (* RegionResetProcPtr)(
+#if NeedNestedPrototypes
+ RegionPtr /*pReg*/,
+ BoxPtr /*pBox*/
+#endif
+);
+
+typedef void (* TranslateRegionProcPtr)(
+#if NeedNestedPrototypes
+ RegionPtr /*pReg*/,
+ int /*x*/,
+ int /*y*/
+#endif
+);
+
+typedef int (* RectInProcPtr)(
+#if NeedNestedPrototypes
+ RegionPtr /*region*/,
+ BoxPtr /*prect*/
+#endif
+);
+
+typedef Bool (* PointInRegionProcPtr)(
+#if NeedNestedPrototypes
+ RegionPtr /*pReg*/,
+ int /*x*/,
+ int /*y*/,
+ BoxPtr /*box*/
+#endif
+);
+
+typedef Bool (* RegionNotEmptyProcPtr)(
+#if NeedNestedPrototypes
+ RegionPtr /*pReg*/
+#endif
+);
+
+typedef void (* RegionEmptyProcPtr)(
+#if NeedNestedPrototypes
+ RegionPtr /*pReg*/
+#endif
+);
+
+typedef BoxPtr (* RegionExtentsProcPtr)(
+#if NeedNestedPrototypes
+ RegionPtr /*pReg*/
+#endif
+);
+
+typedef Bool (* RegionAppendProcPtr)(
+#if NeedNestedPrototypes
+ RegionPtr /*dstrgn*/,
+ RegionPtr /*rgn*/
+#endif
+);
+
+typedef Bool (* RegionValidateProcPtr)(
+#if NeedNestedPrototypes
+ RegionPtr /*badreg*/,
+ Bool* /*pOverlap*/
+#endif
+);
+
+typedef RegionPtr (* BitmapToRegionProcPtr)(
+#if NeedNestedPrototypes
+ PixmapPtr /*pPix*/
+#endif
+);
+
+typedef RegionPtr (* RectsToRegionProcPtr)(
+#if NeedNestedPrototypes
+ int /*nrects*/,
+ xRectangle* /*prect*/,
+ int /*ctype*/
+#endif
+);
+
+typedef void (* SendGraphicsExposeProcPtr)(
+#if NeedNestedPrototypes
+ ClientPtr /*client*/,
+ RegionPtr /*pRgn*/,
+ XID /*drawable*/,
+ int /*major*/,
+ int /*minor*/
+#endif
+);
+
+typedef void (* ScreenBlockHandlerProcPtr)(
+#if NeedNestedPrototypes
+ int /*screenNum*/,
+ pointer /*blockData*/,
+ pointer /*pTimeout*/,
+ pointer /*pReadmask*/
+#endif
+);
+
+typedef void (* ScreenWakeupHandlerProcPtr)(
+#if NeedNestedPrototypes
+ int /*screenNum*/,
+ pointer /*wakeupData*/,
+ unsigned long /*result*/,
+ pointer /*pReadMask*/
+#endif
+);
+
+typedef Bool (* CreateScreenResourcesProcPtr)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/
+#endif
+);
+
+typedef Bool (* ModifyPixmapHeaderProcPtr)(
+#if NeedNestedPrototypes
+ PixmapPtr /*pPixmap*/,
+ int /*width*/,
+ int /*height*/,
+ int /*depth*/,
+ int /*bitsPerPixel*/,
+ int /*devKind*/,
+ pointer /*pPixData*/
+#endif
+);
+
+typedef PixmapPtr (* GetWindowPixmapProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+typedef void (* SetWindowPixmapProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWin*/,
+ PixmapPtr /*pPix*/
+#endif
+);
+
+typedef PixmapPtr (* GetScreenPixmapProcPtr)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/
+#endif
+);
+
+typedef void (* SetScreenPixmapProcPtr)(
+#if NeedNestedPrototypes
+ PixmapPtr /*pPix*/
+#endif
+);
+
+typedef void (* MarkWindowProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+typedef Bool (* MarkOverlappedWindowsProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*parent*/,
+ WindowPtr /*firstChild*/,
+ WindowPtr * /*pLayerWin*/
+#endif
+);
+
+typedef Bool (* ChangeSaveUnderProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pLayerWin*/,
+ WindowPtr /*firstChild*/
+#endif
+);
+
+typedef void (* PostChangeSaveUnderProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pLayerWin*/,
+ WindowPtr /*firstChild*/
+#endif
+);
+
+typedef void (* MoveWindowProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWin*/,
+ int /*x*/,
+ int /*y*/,
+ WindowPtr /*pSib*/,
+ VTKind /*kind*/
+#endif
+);
+
+typedef void (* ResizeWindowProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWin*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*w*/,
+ unsigned int /*h*/,
+ WindowPtr /*pSib*/
+#endif
+);
+
+typedef WindowPtr (* GetLayerWindowProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+typedef void (* HandleExposuresProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+typedef void (* ReparentWindowProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWin*/,
+ WindowPtr /*pPriorParent*/
+#endif
+);
+
+#ifdef SHAPE
+typedef void (* SetShapeProcPtr)(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+#endif /* SHAPE */
+
+typedef void (* ChangeBorderWidthProcPtr)(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ unsigned int /*width*/
+#endif
+);
+
+typedef void (* MarkUnrealizedWindowProcPtr)(
+#if NeedFunctionPrototypes
+ WindowPtr /*pChild*/,
+ WindowPtr /*pWin*/,
+ Bool /*fromConfigure*/
+#endif
+);
+
+typedef struct _Screen {
+ int myNum; /* index of this instance in Screens[] */
+ ATOM id;
+ short width, height;
+ short mmWidth, mmHeight;
+ short numDepths;
+ unsigned char rootDepth;
+ DepthPtr allowedDepths;
+ unsigned long rootVisual;
+ unsigned long defColormap;
+ short minInstalledCmaps, maxInstalledCmaps;
+ char backingStoreSupport, saveUnderSupport;
+ unsigned long whitePixel, blackPixel;
+ unsigned long rgf; /* array of flags; she's -- HUNGARIAN */
+ GCPtr GCperDepth[MAXFORMATS+1];
+ /* next field is a stipple to use as default in
+ a GC. we don't build default tiles of all depths
+ because they are likely to be of a color
+ different from the default fg pixel, so
+ we don't win anything by building
+ a standard one.
+ */
+ PixmapPtr PixmapPerDepth[1];
+ pointer devPrivate;
+ short numVisuals;
+ VisualPtr visuals;
+ int WindowPrivateLen;
+ unsigned *WindowPrivateSizes;
+ unsigned totalWindowSize;
+ int GCPrivateLen;
+ unsigned *GCPrivateSizes;
+ unsigned totalGCSize;
+
+ /* Random screen procedures */
+
+ CloseScreenProcPtr CloseScreen;
+ QueryBestSizeProcPtr QueryBestSize;
+ SaveScreenProcPtr SaveScreen;
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ PointerNonInterestBoxProcPtr PointerNonInterestBox;
+ SourceValidateProcPtr SourceValidate;
+
+ /* Window Procedures */
+
+ CreateWindowProcPtr CreateWindow;
+ DestroyWindowProcPtr DestroyWindow;
+ PositionWindowProcPtr PositionWindow;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+ RealizeWindowProcPtr RealizeWindow;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ ValidateTreeProcPtr ValidateTree;
+ PostValidateTreeProcPtr PostValidateTree;
+ WindowExposuresProcPtr WindowExposures;
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ CopyWindowProcPtr CopyWindow;
+ ClearToBackgroundProcPtr ClearToBackground;
+ ClipNotifyProcPtr ClipNotify;
+
+ /* Pixmap procedures */
+
+ CreatePixmapProcPtr CreatePixmap;
+ DestroyPixmapProcPtr DestroyPixmap;
+
+ /* Backing store procedures */
+
+ SaveDoomedAreasProcPtr SaveDoomedAreas;
+ RestoreAreasProcPtr RestoreAreas;
+ ExposeCopyProcPtr ExposeCopy;
+ TranslateBackingStoreProcPtr TranslateBackingStore;
+ ClearBackingStoreProcPtr ClearBackingStore;
+ DrawGuaranteeProcPtr DrawGuarantee;
+ /*
+ * A read/write copy of the lower level backing store vector is needed now
+ * that the functions can be wrapped.
+ */
+ BSFuncRec BackingStoreFuncs;
+
+ /* Font procedures */
+
+ RealizeFontProcPtr RealizeFont;
+ UnrealizeFontProcPtr UnrealizeFont;
+
+ /* Cursor Procedures */
+
+ ConstrainCursorProcPtr ConstrainCursor;
+ CursorLimitsProcPtr CursorLimits;
+ DisplayCursorProcPtr DisplayCursor;
+ RealizeCursorProcPtr RealizeCursor;
+ UnrealizeCursorProcPtr UnrealizeCursor;
+ RecolorCursorProcPtr RecolorCursor;
+ SetCursorPositionProcPtr SetCursorPosition;
+
+ /* GC procedures */
+
+ CreateGCProcPtr CreateGC;
+
+ /* Colormap procedures */
+
+ CreateColormapProcPtr CreateColormap;
+ DestroyColormapProcPtr DestroyColormap;
+ InstallColormapProcPtr InstallColormap;
+ UninstallColormapProcPtr UninstallColormap;
+ ListInstalledColormapsProcPtr ListInstalledColormaps;
+ StoreColorsProcPtr StoreColors;
+ ResolveColorProcPtr ResolveColor;
+
+ /* Region procedures */
+
+ RegionCreateProcPtr RegionCreate;
+ RegionInitProcPtr RegionInit;
+ RegionCopyProcPtr RegionCopy;
+ RegionDestroyProcPtr RegionDestroy;
+ RegionUninitProcPtr RegionUninit;
+ IntersectProcPtr Intersect;
+ UnionProcPtr Union;
+ SubtractProcPtr Subtract;
+ InverseProcPtr Inverse;
+ RegionResetProcPtr RegionReset;
+ TranslateRegionProcPtr TranslateRegion;
+ RectInProcPtr RectIn;
+ PointInRegionProcPtr PointInRegion;
+ RegionNotEmptyProcPtr RegionNotEmpty;
+ RegionEmptyProcPtr RegionEmpty;
+ RegionExtentsProcPtr RegionExtents;
+ RegionAppendProcPtr RegionAppend;
+ RegionValidateProcPtr RegionValidate;
+ BitmapToRegionProcPtr BitmapToRegion;
+ RectsToRegionProcPtr RectsToRegion;
+ SendGraphicsExposeProcPtr SendGraphicsExpose;
+
+ /* os layer procedures */
+
+ ScreenBlockHandlerProcPtr BlockHandler;
+ ScreenWakeupHandlerProcPtr WakeupHandler;
+
+ pointer blockData;
+ pointer wakeupData;
+
+ /* anybody can get a piece of this array */
+ DevUnion *devPrivates;
+
+ CreateScreenResourcesProcPtr CreateScreenResources;
+ ModifyPixmapHeaderProcPtr ModifyPixmapHeader;
+
+ GetWindowPixmapProcPtr GetWindowPixmap;
+ SetWindowPixmapProcPtr SetWindowPixmap;
+ GetScreenPixmapProcPtr GetScreenPixmap;
+ SetScreenPixmapProcPtr SetScreenPixmap;
+
+ PixmapPtr pScratchPixmap; /* scratch pixmap "pool" */
+
+#ifdef PIXPRIV
+ int PixmapPrivateLen;
+ unsigned *PixmapPrivateSizes;
+ unsigned totalPixmapSize;
+#endif
+
+ MarkWindowProcPtr MarkWindow;
+ MarkOverlappedWindowsProcPtr MarkOverlappedWindows;
+ ChangeSaveUnderProcPtr ChangeSaveUnder;
+ PostChangeSaveUnderProcPtr PostChangeSaveUnder;
+ MoveWindowProcPtr MoveWindow;
+ ResizeWindowProcPtr ResizeWindow;
+ GetLayerWindowProcPtr GetLayerWindow;
+ HandleExposuresProcPtr HandleExposures;
+ ReparentWindowProcPtr ReparentWindow;
+
+#ifdef SHAPE
+ SetShapeProcPtr SetShape;
+#endif /* SHAPE */
+
+ ChangeBorderWidthProcPtr ChangeBorderWidth;
+ MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
+
+} ScreenRec;
+
+typedef struct _ScreenInfo {
+ int imageByteOrder;
+ int bitmapScanlineUnit;
+ int bitmapScanlinePad;
+ int bitmapBitOrder;
+ int numPixmapFormats;
+ PixmapFormatRec
+ formats[MAXFORMATS];
+ int arraySize;
+ int numScreens;
+ ScreenPtr screens[MAXSCREENS];
+ int numVideoScreens;
+} ScreenInfo;
+
+extern ScreenInfo screenInfo;
+
+extern void InitOutput(
+#if NeedFunctionPrototypes
+ ScreenInfo * /*pScreenInfo*/,
+ int /*argc*/,
+ char ** /*argv*/
+#endif
+);
+
+#endif /* SCREENINTSTRUCT_H */
diff --git a/xc/programs/Xserver/include/selection.h b/xc/programs/Xserver/include/selection.h
new file mode 100644
index 000000000..0a2ae14a8
--- /dev/null
+++ b/xc/programs/Xserver/include/selection.h
@@ -0,0 +1,64 @@
+/* $TOG: selection.h /main/4 1998/02/09 14:30:04 kaleb $ */
+#ifndef SELECTION_H
+#define SELECTION_H 1
+
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#include "dixstruct.h"
+/*
+ *
+ * Selection data structures
+ */
+
+typedef struct _Selection {
+ Atom selection;
+ TimeStamp lastTimeChanged;
+ Window window;
+ WindowPtr pWin;
+ ClientPtr client;
+} Selection;
+
+#endif /* SELECTION_H */
+
+
diff --git a/xc/programs/Xserver/include/servermd.h b/xc/programs/Xserver/include/servermd.h
new file mode 100644
index 000000000..1580b9d83
--- /dev/null
+++ b/xc/programs/Xserver/include/servermd.h
@@ -0,0 +1,559 @@
+/* $XFree86: xc/programs/Xserver/include/servermd.h,v 3.33 1999/03/28 15:33:10 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+#ifndef SERVERMD_H
+#define SERVERMD_H 1
+
+/* $TOG: servermd.h /main/60 1998/02/09 14:30:08 kaleb $ */
+
+/*
+ * Machine dependent values:
+ * GLYPHPADBYTES should be chosen with consideration for the space-time
+ * trade-off. Padding to 0 bytes means that there is no wasted space
+ * in the font bitmaps (both on disk and in memory), but that access of
+ * the bitmaps will cause odd-address memory references. Padding to
+ * 2 bytes would ensure even address memory references and would
+ * be suitable for a 68010-class machine, but at the expense of wasted
+ * space in the font bitmaps. Padding to 4 bytes would be good
+ * for real 32 bit machines, etc. Be sure that you tell the font
+ * compiler what kind of padding you want because its defines are
+ * kept separate from this. See server/include/font.h for how
+ * GLYPHPADBYTES is used.
+ *
+ * Along with this, you should choose an appropriate value for
+ * GETLEFTBITS_ALIGNMENT, which is used in ddx/mfb/maskbits.h. This
+ * constant choses what kind of memory references are guarenteed during
+ * font access; either 1, 2 or 4, for byte, word or longword access,
+ * respectively. For instance, if you have decided to to have
+ * GLYPHPADBYTES == 4, then it is pointless for you to have a
+ * GETLEFTBITS_ALIGNMENT > 1, because the padding of the fonts has already
+ * guarenteed you that your fonts are longword aligned. On the other
+ * hand, even if you have chosen GLYPHPADBYTES == 1 to save space, you may
+ * also decide that the computing involved in aligning the pointer is more
+ * costly than an odd-address access; you choose GETLEFTBITS_ALIGNMENT == 1.
+ *
+ * Next, choose the tuning parameters which are appropriate for your
+ * hardware; these modify the behaviour of the raw frame buffer code
+ * in ddx/mfb and ddx/cfb. Defining these incorrectly will not cause
+ * the server to run incorrectly, but defining these correctly will
+ * cause some noticeable speed improvements:
+ *
+ * AVOID_MEMORY_READ - (8-bit cfb only)
+ * When stippling pixels on the screen (polytext and pushpixels),
+ * don't read long words from the display and mask in the
+ * appropriate values. Rather, perform multiple byte/short/long
+ * writes as appropriate. This option uses many more instructions
+ * but runs much faster when the destination is much slower than
+ * the CPU and at least 1 level of write buffer is availible (2
+ * is much better). Defined currently for SPARC and MIPS.
+ *
+ * FAST_CONSTANT_OFFSET_MODE - (cfb and mfb)
+ * This define is used on machines which have no auto-increment
+ * addressing mode, but do have an effectively free constant-offset
+ * addressing mode. Currently defined for MIPS and SPARC, even though
+ * I remember the cg6 as performing better without it (cg3 definitely
+ * performs better with it).
+ *
+ * LARGE_INSTRUCTION_CACHE -
+ * This define increases the number of times some loops are
+ * unrolled. On 68020 machines (with 256 bytes of i-cache),
+ * this define will slow execution down as instructions miss
+ * the cache frequently. On machines with real i-caches, this
+ * reduces loop overhead, causing a slight performance improvement.
+ * Currently defined for MIPS and SPARC
+ *
+ * FAST_UNALIGNED_READS -
+ * For machines with more memory bandwidth than CPU, this
+ * define uses unaligned reads for 8-bit BitBLT instead of doing
+ * aligned reads and combining the results with shifts and
+ * logical-ors. Currently defined for 68020 and vax.
+ * PLENTIFUL_REGISTERS -
+ * For machines with > 20 registers. Currently used for
+ * unrolling the text painting code a bit more. Currently
+ * defined for MIPS.
+ * SHARED_IDCACHE -
+ * For non-Harvard RISC machines, those which share the same
+ * CPU memory bus for instructions and data. This unrolls some
+ * solid fill loops which are otherwise best left rolled up.
+ * Currently defined for SPARC.
+ */
+
+#ifdef vax
+
+#define IMAGE_BYTE_ORDER LSBFirst /* Values for the VAX only */
+#define BITMAP_BIT_ORDER LSBFirst
+#define GLYPHPADBYTES 1
+#define GETLEFTBITS_ALIGNMENT 4
+#define FAST_UNALIGNED_READS
+
+#endif /* vax */
+
+#ifdef __arm32__
+
+#define IMAGE_BYTE_ORDER LSBFirst
+
+# if defined(XF86MONOVGA) || defined(XF86VGA16) || defined(XF86MONO)
+# define BITMAP_BIT_ORDER MSBFirst
+# else
+# define BITMAP_BIT_ORDER LSBFirst
+# endif
+
+# if defined(XF86MONOVGA) || defined(XF86VGA16)
+# define BITMAP_SCANLINE_UNIT 8
+# endif
+
+#define GLYPHPADBYTES 4
+#define GETLEFTBITS_ALIGNMENT 1
+#define LARGE_INSTRUCTION_CACHE
+#define AVOID_MEMORY_READ
+
+#endif /* __arm32__ */
+
+#if (defined(Lynx) && defined(__powerpc__))
+
+/* For now this is for Xvfb only */
+#define IMAGE_BYTE_ORDER MSBFirst
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 4
+#define GETLEFTBITS_ALIGNMENT 1
+#define BITMAP_SCANLINE_UNIT 8
+
+#define LARGE_INSTRUCTION_CACHE
+#define FAST_CONSTANT_OFFSET_MODE
+#define PLENTIFUL_REGISTERS
+#define AVOID_MEMORY_READ
+
+#define FAST_MEMCPY
+
+#endif /* LynxOS PowerPC */
+
+#if (defined(sun) && !(defined(i386) && defined(SVR4))) || \
+ (defined(AMOEBA) && (defined(sparc) || defined(mc68000))) || \
+ (defined(__uxp__) && (defined(sparc) || defined(mc68000))) || \
+ (defined(Lynx) && defined(__sparc__)) || \
+ (defined(linux) && defined(__sparc__)) || \
+ ((defined(__NetBSD__) || defined(__OpenBSD__)) && \
+ (defined(__sparc__) || defined(__mc68000__)))
+
+#if defined(sun386) || defined(sun5)
+# define IMAGE_BYTE_ORDER LSBFirst /* Values for the SUN only */
+# define BITMAP_BIT_ORDER LSBFirst
+#else
+# define IMAGE_BYTE_ORDER MSBFirst /* Values for the SUN only */
+# define BITMAP_BIT_ORDER MSBFirst
+#endif
+
+#ifdef sparc
+# define AVOID_MEMORY_READ
+# define LARGE_INSTRUCTION_CACHE
+# define FAST_CONSTANT_OFFSET_MODE
+# define SHARED_IDCACHE
+#endif
+
+#ifdef mc68020
+#define FAST_UNALIGNED_READS
+#endif
+
+#define GLYPHPADBYTES 4
+#define GETLEFTBITS_ALIGNMENT 1
+
+#endif /* sun && !(i386 && SVR4) */
+
+
+#if defined(AIXV3)
+
+#define IMAGE_BYTE_ORDER MSBFirst /* Values for the RISC/6000 */
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 4
+#define GETLEFTBITS_ALIGNMENT 1
+
+#define LARGE_INSTRUCTION_CACHE
+#define FAST_CONSTANT_OFFSET_MODE
+#define PLENTIFUL_REGISTERS
+#define AVOID_MEMORY_READ
+
+#define FAST_MEMCPY
+#endif /* AIXV3 */
+
+#if defined(ibm032) || defined (ibm)
+
+#ifdef i386
+# define IMAGE_BYTE_ORDER LSBFirst /* Value for PS/2 only */
+#else
+# define IMAGE_BYTE_ORDER MSBFirst /* Values for the RT only*/
+#endif
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 1
+#define GETLEFTBITS_ALIGNMENT 4
+/* ibm pcc doesn't understand pragmas. */
+
+#ifdef i386
+#define BITMAP_SCANLINE_UNIT 8
+#endif
+
+#endif /* ibm */
+
+#ifdef hpux
+
+#define IMAGE_BYTE_ORDER MSBFirst /* Values for the HP only */
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 2 /* to match product server */
+#define GETLEFTBITS_ALIGNMENT 4 /* PA forces longs to 4 */
+ /* byte boundries */
+#define AVOID_MEMORY_READ
+#define FAST_CONSTANT_OFFSET_MODE
+#define LARGE_INSTRUCTION_CACHE
+#define PLENTIFUL_REGISTERS
+
+#endif /* hpux */
+
+#if defined (M4310) || defined(M4315) || defined(M4317) || defined(M4319) || defined(M4330)
+
+#define IMAGE_BYTE_ORDER MSBFirst /* Values for Pegasus only */
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 4
+#define GETLEFTBITS_ALIGNMENT 1
+
+#define FAST_UNALIGNED_READS
+
+#endif /* tektronix */
+
+#ifdef macII
+
+#define IMAGE_BYTE_ORDER MSBFirst /* Values for the MacII only */
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 4
+#define GETLEFTBITS_ALIGNMENT 1
+
+/* might want FAST_UNALIGNED_READS for frame buffers with < 1us latency */
+
+#endif /* macII */
+
+#if (defined(mips) || defined(__mips)) && !defined(sgi)
+
+#if defined(MIPSEL) || defined(__MIPSEL__)
+# define IMAGE_BYTE_ORDER LSBFirst /* Values for the PMAX only */
+# define BITMAP_BIT_ORDER LSBFirst
+# define GLYPHPADBYTES 4
+# define GETLEFTBITS_ALIGNMENT 1
+#else
+# define IMAGE_BYTE_ORDER MSBFirst /* Values for the MIPS only */
+# define BITMAP_BIT_ORDER MSBFirst
+# define GLYPHPADBYTES 4
+# define GETLEFTBITS_ALIGNMENT 1
+#endif
+
+#define AVOID_MEMORY_READ
+#define FAST_CONSTANT_OFFSET_MODE
+#define LARGE_INSTRUCTION_CACHE
+#define PLENTIFUL_REGISTERS
+
+#endif /* mips */
+
+#if defined(__alpha) || defined(__alpha__) || defined(__alphaCross)
+# define IMAGE_BYTE_ORDER LSBFirst /* Values for the Alpha only */
+
+# if defined(XF86MONOVGA) || defined(XF86VGA16) || defined(XF86MONO)
+# define BITMAP_BIT_ORDER MSBFirst
+# else
+# define BITMAP_BIT_ORDER LSBFirst
+# endif
+
+# if defined(XF86MONOVGA) || defined(XF86VGA16)
+# define BITMAP_SCANLINE_UNIT 8
+# else
+ /* pad scanline to a longword */
+# define BITMAP_SCANLINE_UNIT 64
+# endif
+
+# define BITMAP_SCANLINE_PAD 64
+# define LOG2_BITMAP_PAD 6
+# define LOG2_BYTES_PER_SCANLINE_PAD 3
+# define GLYPHPADBYTES 4
+# define GETLEFTBITS_ALIGNMENT 1
+# define FAST_CONSTANT_OFFSET_MODE
+# define LARGE_INSTRUCTION_CACHE
+# define PLENTIFUL_REGISTERS
+
+/* Add for handling protocol XPutImage and XGetImage; see comment below */
+#define INTERNAL_VS_EXTERNAL_PADDING
+#define BITMAP_SCANLINE_UNIT_PROTO 32
+
+#define BITMAP_SCANLINE_PAD_PROTO 32
+#define LOG2_BITMAP_PAD_PROTO 5
+#define LOG2_BYTES_PER_SCANLINE_PAD_PROTO 2
+
+#endif /* alpha */
+
+#ifdef stellar
+
+#define IMAGE_BYTE_ORDER MSBFirst /* Values for the stellar only*/
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 4
+#define GETLEFTBITS_ALIGNMENT 4
+#define IMAGE_BUFSIZE (64*1024)
+/*
+ * Use SysV random number generator.
+ */
+#define random rand
+
+#endif /* stellar */
+
+#ifdef luna
+
+#define IMAGE_BYTE_ORDER MSBFirst /* Values for the OMRON only*/
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 4
+#define GETLEFTBITS_ALIGNMENT 1
+
+#ifndef mc68000
+#define FAST_CONSTANT_OFFSET_MODE
+#define AVOID_MEMORY_READ
+#define LARGE_INSTRUCTION_CACHE
+#define PLENTIFUL_REGISTERS
+#endif
+
+#endif /* luna */
+
+#if (defined(i386) && (defined(SVR4) || defined(SYSV) || (defined(sun) && defined(SVR4))) || defined(__bsdi__) || (defined(__NetBSD__) && defined(__i386__)) || (defined(__OpenBSD__) && defined(__i386__)) || defined(__FreeBSD__) || defined(MACH386) || (defined(linux) && (defined(__i386__) || defined(__alpha__))) || (defined(AMOEBA) && defined(i80386)) || defined(MINIX) || defined(__EMX__) || (defined(Lynx) && defined(__i386__))) || defined(__OS2ELF__) || (defined(__GNU__) && defined(__i386__))
+
+#ifndef IMAGE_BYTE_ORDER
+#define IMAGE_BYTE_ORDER LSBFirst
+#endif
+
+#ifndef BITMAP_BIT_ORDER
+# if defined(XF86MONOVGA) || defined(XF86VGA16) || defined(XF86MONO)
+# define BITMAP_BIT_ORDER MSBFirst
+# else
+# define BITMAP_BIT_ORDER LSBFirst
+# endif
+#endif
+
+#ifndef BITMAP_SCANLINE_UNIT
+# if defined(XF86MONOVGA) || defined(XF86VGA16)
+# define BITMAP_SCANLINE_UNIT 8
+# endif
+#endif
+
+#ifndef GLYPHPADBYTES
+#define GLYPHPADBYTES 4
+#endif
+
+#define GETLEFTBITS_ALIGNMENT 1
+#define AVOID_MEMORY_READ
+#ifdef XSVGA
+#define AVOID_GLYPHBLT
+#define FAST_CONSTANT_OFFSET_MODE
+#define FAST_MEMCPY
+#define NO_ONE_RECT
+#endif
+
+#endif /* SVR4 / BSD / i386 */
+
+#if defined (linux) && defined (__mc68000__)
+
+#define IMAGE_BYTE_ORDER MSBFirst
+#define BITMAP_BIT_ORDER MSBFirst
+#define FAST_UNALIGNED_READS
+#define GLYPHPADBYTES 4
+#define GETLEFTBITS_ALIGNMENT 1
+
+#endif /* linux/m68k */
+
+#if defined (linux) && defined(__powerpc__)
+
+#define IMAGE_BYTE_ORDER MSBFirst
+#define BITMAP_BIT_ORDER MSBFirst
+#define GLYPHPADBYTES 4
+#define GETLEFTBITS_ALIGNMENT 1
+
+#define LARGE_INSTRUCTION_CACHE
+#define FAST_CONSTANT_OFFSET_MODE
+#define PLENTIFUL_REGISTERS
+#define AVOID_MEMORY_READ
+
+#define FAST_MEMCPY
+
+#endif /* Linux/PPC */
+
+#ifdef sgi
+
+#define IMAGE_BYTE_ORDER MSBFirst
+#define BITMAP_BIT_ORDER MSBFirst
+
+#if (_MIPS_SZLONG == 64)
+
+# define GLYPHPADBYTES 4
+# define GETLEFTBITS_ALIGNMENT 1
+
+/* pad scanline to a longword */
+#define BITMAP_SCANLINE_UNIT 64
+
+#define BITMAP_SCANLINE_PAD 64
+#define LOG2_BITMAP_PAD 6
+#define LOG2_BYTES_PER_SCANLINE_PAD 3
+
+/* Add for handling protocol XPutImage and XGetImage; see comment below */
+#define INTERNAL_VS_EXTERNAL_PADDING
+#define BITMAP_SCANLINE_UNIT_PROTO 32
+
+#define BITMAP_SCANLINE_PAD_PROTO 32
+#define LOG2_BITMAP_PAD_PROTO 5
+#define LOG2_BYTES_PER_SCANLINE_PAD_PROTO 2
+
+#else
+
+#define GLYPHPADBYTES 2
+#define GETLEFTBITS_ALIGNMENT 4
+
+#endif
+
+#define AVOID_MEMORY_READ
+#define FAST_CONSTANT_OFFSET_MODE
+#define LARGE_INSTRUCTION_CACHE
+#define PLENTIFUL_REGISTERS
+
+#endif
+
+/* size of buffer to use with GetImage, measured in bytes. There's obviously
+ * a trade-off between the amount of stack (or whatever ALLOCATE_LOCAL gives
+ * you) used and the number of times the ddx routine has to be called.
+ *
+ * for a 1024 x 864 bit monochrome screen with a 32 bit word we get
+ * 8192/4 words per buffer
+ * (1024/32) = 32 words per scanline
+ * 2048 words per buffer / 32 words per scanline = 64 scanlines per buffer
+ * 864 scanlines / 64 scanlines = 14 buffers to draw a full screen
+ */
+#ifndef IMAGE_BUFSIZE
+#define IMAGE_BUFSIZE 8192
+#endif
+
+/* pad scanline to a longword */
+#ifndef BITMAP_SCANLINE_UNIT
+#define BITMAP_SCANLINE_UNIT 32
+#endif
+
+#ifndef BITMAP_SCANLINE_PAD
+#define BITMAP_SCANLINE_PAD 32
+#define LOG2_BITMAP_PAD 5
+#define LOG2_BYTES_PER_SCANLINE_PAD 2
+#endif
+
+/*
+ * This returns the number of padding units, for depth d and width w.
+ * For bitmaps this can be calculated with the macros above.
+ * Other depths require either grovelling over the formats field of the
+ * screenInfo or hardwired constants.
+ */
+
+typedef struct _PaddingInfo {
+ int padRoundUp; /* pixels per pad unit - 1 */
+ int padPixelsLog2; /* log 2 (pixels per pad unit) */
+ int padBytesLog2; /* log 2 (bytes per pad unit) */
+ int notPower2; /* bitsPerPixel not a power of 2 */
+ int bytesPerPixel; /* only set when notPower2 is TRUE */
+ int bitsPerPixel; /* bits per pixel */
+} PaddingInfo;
+extern PaddingInfo PixmapWidthPaddingInfo[];
+
+/* The only portable way to get the bpp from the depth is to look it up */
+#define BitsPerPixel(d) (PixmapWidthPaddingInfo[d].bitsPerPixel)
+
+#define PixmapWidthInPadUnits(w, d) \
+ (PixmapWidthPaddingInfo[d].notPower2 ? \
+ (((int)(w) * PixmapWidthPaddingInfo[d].bytesPerPixel + \
+ PixmapWidthPaddingInfo[d].bytesPerPixel) >> \
+ PixmapWidthPaddingInfo[d].padBytesLog2) : \
+ ((int)((w) + PixmapWidthPaddingInfo[d].padRoundUp) >> \
+ PixmapWidthPaddingInfo[d].padPixelsLog2))
+
+/*
+ * Return the number of bytes to which a scanline of the given
+ * depth and width will be padded.
+ */
+#define PixmapBytePad(w, d) \
+ (PixmapWidthInPadUnits(w, d) << PixmapWidthPaddingInfo[d].padBytesLog2)
+
+#define BitmapBytePad(w) \
+ (((int)((w) + BITMAP_SCANLINE_PAD - 1) >> LOG2_BITMAP_PAD) << LOG2_BYTES_PER_SCANLINE_PAD)
+
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+
+/* This is defined if the server's internal padding is different from the padding
+ * advertised in the protocol. The protocol does not allow for padding to
+ * 64 bits, for example, so if the server wants to use 64 bit padding internally,
+ * it has to advertise 32 bit padding and do padding fixups whenever images
+ * cross the wire. (See ProcGetImage and ProcPutImage.)
+ *
+ * The macros and constants that end in Proto or PROTO refer to the advertised
+ * padding, and the ones without Proto are for internal padding.
+ */
+
+extern PaddingInfo PixmapWidthPaddingInfoProto[];
+
+#define PixmapWidthInPadUnitsProto(w, d) \
+ (PixmapWidthPaddingInfoProto[d].notPower2 ? \
+ (((int)(w) * PixmapWidthPaddingInfoProto[d].bytesPerPixel + \
+ PixmapWidthPaddingInfoProto[d].bytesPerPixel) >> \
+ PixmapWidthPaddingInfoProto[d].padBytesLog2) : \
+ ((int)((w) + PixmapWidthPaddingInfoProto[d].padRoundUp) >> \
+ PixmapWidthPaddingInfoProto[d].padPixelsLog2))
+
+#define PixmapBytePadProto(w, d) \
+ (PixmapWidthInPadUnitsProto(w, d) << \
+ PixmapWidthPaddingInfoProto[d].padBytesLog2)
+
+#define BitmapBytePadProto(w) \
+ ((((w) + BITMAP_SCANLINE_PAD_PROTO - 1) >> LOG2_BITMAP_PAD_PROTO) \
+ << LOG2_BYTES_PER_SCANLINE_PAD_PROTO)
+
+#else /* protocol and internal padding is the same */
+
+#define PixmapWidthInPadUnitsProto(w, d) PixmapWidthInPadUnits(w, d)
+#define PixmapBytePadProto(w, d) PixmapBytePad(w, d)
+#define BitmapBytePadProto(w) BitmapBytePad(w)
+
+#endif /* protocol vs. internal padding */
+
+#endif /* SERVERMD_H */
diff --git a/xc/programs/Xserver/include/site.h b/xc/programs/Xserver/include/site.h
new file mode 100644
index 000000000..d6d9cfd71
--- /dev/null
+++ b/xc/programs/Xserver/include/site.h
@@ -0,0 +1,133 @@
+/* $TOG: site.h /main/29 1998/02/09 14:30:13 kaleb $ */
+/************************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+********************************************************/
+
+#ifndef SITE_H
+#define SITE_H
+/*
+ * The vendor string identifies the vendor responsible for the
+ * server executable.
+ */
+#ifndef VENDOR_STRING
+#define VENDOR_STRING "The Open Group"
+#endif
+
+/*
+ * The vendor release number identifies, for the purpose of submitting
+ * traceable bug reports, the release number of software produced
+ * by the vendor.
+ */
+#ifndef VENDOR_RELEASE
+#define VENDOR_RELEASE 6400
+#endif
+
+/*
+ * The following constants are provided solely as a last line of defense. The
+ * normal build ALWAYS overrides them using a special rule given in
+ * server/dix/Imakefile. If you want to change either of these constants,
+ * you should set the DefaultFontPath or DefaultRGBDatabase configuration
+ * parameters.
+ * DO NOT CHANGE THESE VALUES OR THE DIX IMAKEFILE!
+ */
+#ifndef COMPILEDDEFAULTFONTPATH
+#define COMPILEDDEFAULTFONTPATH "/usr/lib/X11/fonts/misc/"
+#endif
+#ifndef RGB_DB
+#define RGB_DB "/usr/lib/X11/rgb"
+#endif
+
+/*
+ * The following constants contain default values for all of the variables
+ * that can be initialized on the server command line or in the environment.
+ */
+#define COMPILEDDEFAULTFONT "fixed"
+#define COMPILEDCURSORFONT "cursor"
+#ifndef COMPILEDDISPLAYCLASS
+#define COMPILEDDISPLAYCLASS "MIT-unspecified"
+#endif
+#define DEFAULT_TIMEOUT 60 /* seconds */
+#define DEFAULT_KEYBOARD_CLICK 0
+#define DEFAULT_BELL 50
+#define DEFAULT_BELL_PITCH 400
+#define DEFAULT_BELL_DURATION 100
+#ifdef XKB
+#define DEFAULT_AUTOREPEAT TRUE
+#else
+#define DEFAULT_AUTOREPEAT FALSE
+#endif
+#ifdef hpux
+#define DEFAULT_AUTOREPEATS {\
+ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+#else
+#define DEFAULT_AUTOREPEATS {\
+ 0, 0, 0, 0, 0, 0, 0, 0,\
+ 0, 0, 0, 0, 0, 0, 0, 0,\
+ 0, 0, 0, 0, 0, 0, 0, 0,\
+ 0, 0, 0, 0, 0, 0, 0, 0 }
+#endif
+#define DEFAULT_LEDS 0x0 /* all off */
+#define DEFAULT_LEDS_MASK 0xffffffff /* 32 */
+#define DEFAULT_INT_RESOLUTION 1000
+#define DEFAULT_INT_MIN_VALUE 0
+#define DEFAULT_INT_MAX_VALUE 100
+#define DEFAULT_INT_DISPLAYED 0
+
+#define DEFAULT_PTR_NUMERATOR 2
+#define DEFAULT_PTR_DENOMINATOR 1
+#define DEFAULT_PTR_THRESHOLD 4
+
+#define DEFAULT_SCREEN_SAVER_TIME (10 * (60 * 1000))
+#define DEFAULT_SCREEN_SAVER_INTERVAL (10 * (60 * 1000))
+#define DEFAULT_SCREEN_SAVER_BLANKING PreferBlanking
+#define DEFAULT_SCREEN_SAVER_EXPOSURES AllowExposures
+#ifndef NOLOGOHACK
+#define DEFAULT_LOGO_SCREEN_SAVER 1
+#endif
+#ifndef DEFAULT_ACCESS_CONTROL
+#define DEFAULT_ACCESS_CONTROL TRUE
+#endif
+
+#endif /* SITE_H */
diff --git a/xc/programs/Xserver/include/swaprep.h b/xc/programs/Xserver/include/swaprep.h
new file mode 100644
index 000000000..a8453db60
--- /dev/null
+++ b/xc/programs/Xserver/include/swaprep.h
@@ -0,0 +1,542 @@
+/* $XFree86: xc/programs/Xserver/include/swaprep.h,v 3.0 1996/04/15 11:34:34 dawes Exp $ */
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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 SWAPREP_H
+#define SWAPREP_H 1
+
+void
+Swap32Write(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ CARD32 * /* pbuf */
+#endif
+);
+
+void
+CopySwap32Write(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ CARD32 * /* pbuf */
+#endif
+);
+
+void
+CopySwap16Write(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ short * /* pbuf */
+#endif
+);
+
+void
+SGenericReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGenericReply * /* pRep */
+#endif
+);
+
+void
+SGetWindowAttributesReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetWindowAttributesReply * /* pRep */
+#endif
+);
+
+void
+SGetGeometryReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetGeometryReply * /* pRep */
+#endif
+);
+
+void
+SQueryTreeReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xQueryTreeReply * /* pRep */
+#endif
+);
+
+void
+SInternAtomReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xInternAtomReply * /* pRep */
+#endif
+);
+
+void
+SGetAtomNameReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetAtomNameReply * /* pRep */
+#endif
+);
+
+void
+SGetPropertyReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetPropertyReply * /* pRep */
+#endif
+);
+
+void
+SListPropertiesReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xListPropertiesReply * /* pRep */
+#endif
+);
+
+void
+SGetSelectionOwnerReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetSelectionOwnerReply * /* pRep */
+#endif
+);
+
+void
+SQueryPointerReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xQueryPointerReply * /* pRep */
+#endif
+);
+
+void
+SwapTimecoord(
+#if NeedFunctionPrototypes
+ xTimecoord * /* pCoord */
+#endif
+);
+
+void
+SwapTimeCoordWrite(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xTimecoord * /* pRep */
+#endif
+);
+
+void
+SGetMotionEventsReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetMotionEventsReply * /* pRep */
+#endif
+);
+
+void
+STranslateCoordsReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xTranslateCoordsReply * /* pRep */
+#endif
+);
+
+void
+SGetInputFocusReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetInputFocusReply * /* pRep */
+#endif
+);
+
+void
+SQueryKeymapReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xQueryKeymapReply * /* pRep */
+#endif
+);
+
+#ifdef LBX
+void
+SwapCharInfo(
+#if NeedFunctionPrototypes
+ xCharInfo * /* pInfo */
+#endif
+);
+#endif
+
+#ifdef LBX
+void
+SwapFont(
+#if NeedFunctionPrototypes
+ xQueryFontReply * /* pr */,
+ Bool /* hasGlyphs */
+#endif
+);
+#endif
+
+void
+SQueryFontReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xQueryFontReply * /* pRep */
+#endif
+);
+
+void
+SQueryTextExtentsReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xQueryTextExtentsReply * /* pRep */
+#endif
+);
+
+void
+SListFontsReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xListFontsReply * /* pRep */
+#endif
+);
+
+void
+SListFontsWithInfoReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xListFontsWithInfoReply * /* pRep */
+#endif
+);
+
+void
+SGetFontPathReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetFontPathReply * /* pRep */
+#endif
+);
+
+void
+SGetImageReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetImageReply * /* pRep */
+#endif
+);
+
+void
+SListInstalledColormapsReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xListInstalledColormapsReply * /* pRep */
+#endif
+);
+
+void
+SAllocColorReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xAllocColorReply * /* pRep */
+#endif
+);
+
+void
+SAllocNamedColorReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xAllocNamedColorReply * /* pRep */
+#endif
+);
+
+void
+SAllocColorCellsReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xAllocColorCellsReply * /* pRep */
+#endif
+);
+
+void
+SAllocColorPlanesReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xAllocColorPlanesReply * /* pRep */
+#endif
+);
+
+void
+SwapRGB(
+#if NeedFunctionPrototypes
+ xrgb * /* prgb */
+#endif
+);
+
+void
+SQColorsExtend(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xrgb * /* prgb */
+#endif
+);
+
+void
+SQueryColorsReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xQueryColorsReply * /* pRep */
+#endif
+);
+
+void
+SLookupColorReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xLookupColorReply * /* pRep */
+#endif
+);
+
+void
+SQueryBestSizeReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xQueryBestSizeReply * /* pRep */
+#endif
+);
+
+void
+SListExtensionsReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xListExtensionsReply * /* pRep */
+#endif
+);
+
+void
+SGetKeyboardMappingReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetKeyboardMappingReply * /* pRep */
+#endif
+);
+
+void
+SGetPointerMappingReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetPointerMappingReply * /* pRep */
+#endif
+);
+
+void
+SGetModifierMappingReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetModifierMappingReply * /* pRep */
+#endif
+);
+
+void
+SGetKeyboardControlReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetKeyboardControlReply * /* pRep */
+#endif
+);
+
+void
+SGetPointerControlReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetPointerControlReply * /* pRep */
+#endif
+);
+
+void
+SGetScreenSaverReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xGetScreenSaverReply * /* pRep */
+#endif
+);
+
+void
+SLHostsExtend(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ char * /* buf */
+#endif
+);
+
+void
+SListHostsReply(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ int /* size */,
+ xListHostsReply * /* pRep */
+#endif
+);
+
+void
+SErrorEvent(
+#if NeedFunctionPrototypes
+ xError * /* from */,
+ xError * /* to */
+#endif
+);
+
+void
+SwapConnSetupInfo(
+#if NeedFunctionPrototypes
+ char * /* pInfo */,
+ char * /* pInfoTBase */
+#endif
+);
+
+void
+WriteSConnectionInfo(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ unsigned long /* size */,
+ char * /* pInfo */
+#endif
+);
+
+void
+SwapConnSetup(
+#if NeedFunctionPrototypes
+ xConnSetup * /* pConnSetup */,
+ xConnSetup * /* pConnSetupT */
+#endif
+);
+
+void
+SwapWinRoot(
+#if NeedFunctionPrototypes
+ xWindowRoot * /* pRoot */,
+ xWindowRoot * /* pRootT */
+#endif
+);
+
+void
+SwapVisual(
+#if NeedFunctionPrototypes
+ xVisualType * /* pVis */,
+ xVisualType * /* pVisT */
+#endif
+);
+
+void
+SwapConnSetupPrefix(
+#if NeedFunctionPrototypes
+ xConnSetupPrefix * /* pcspFrom */,
+ xConnSetupPrefix * /* pcspTo */
+#endif
+);
+
+void
+WriteSConnSetupPrefix(
+#if NeedFunctionPrototypes
+ ClientPtr /* pClient */,
+ xConnSetupPrefix * /* pcsp */
+#endif
+);
+
+#undef SWAPREP_PROC
+#if NeedFunctionPrototypes
+#define SWAPREP_PROC(func) void func(xEvent * /* from */, xEvent * /* to */)
+#else
+#define SWAPREP_PROC(func) void func(/* xEvent * from, xEvent * to */)
+#endif
+
+SWAPREP_PROC(SCirculateEvent);
+SWAPREP_PROC(SClientMessageEvent);
+SWAPREP_PROC(SColormapEvent);
+SWAPREP_PROC(SConfigureNotifyEvent);
+SWAPREP_PROC(SConfigureRequestEvent);
+SWAPREP_PROC(SCreateNotifyEvent);
+SWAPREP_PROC(SDestroyNotifyEvent);
+SWAPREP_PROC(SEnterLeaveEvent);
+SWAPREP_PROC(SExposeEvent);
+SWAPREP_PROC(SFocusEvent);
+SWAPREP_PROC(SGraphicsExposureEvent);
+SWAPREP_PROC(SGravityEvent);
+SWAPREP_PROC(SKeyButtonPtrEvent);
+SWAPREP_PROC(SKeymapNotifyEvent);
+SWAPREP_PROC(SMapNotifyEvent);
+SWAPREP_PROC(SMapRequestEvent);
+SWAPREP_PROC(SMappingEvent);
+SWAPREP_PROC(SNoExposureEvent);
+SWAPREP_PROC(SPropertyEvent);
+SWAPREP_PROC(SReparentEvent);
+SWAPREP_PROC(SResizeRequestEvent);
+SWAPREP_PROC(SSelectionClearEvent);
+SWAPREP_PROC(SSelectionNotifyEvent);
+SWAPREP_PROC(SSelectionRequestEvent);
+SWAPREP_PROC(SUnmapNotifyEvent);
+SWAPREP_PROC(SVisibilityEvent);
+
+#undef SWAPREP_PROC
+
+#endif /* SWAPREP_H */
diff --git a/xc/programs/Xserver/include/swapreq.h b/xc/programs/Xserver/include/swapreq.h
new file mode 100644
index 000000000..805788848
--- /dev/null
+++ b/xc/programs/Xserver/include/swapreq.h
@@ -0,0 +1,137 @@
+/* $XFree86: xc/programs/Xserver/include/swapreq.h,v 1.1 1998/10/06 06:59:38 dawes Exp $ */
+/************************************************************
+
+Copyright 1996 by Thomas E. Dickey <dickey@clark.net>
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of the above listed
+copyright holder(s) not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.
+
+THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD
+TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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 SWAPREQ_H
+#define SWAPREQ_H 1
+
+void
+SwapLongs (
+#if NeedFunctionPrototypes
+ CARD32 * /* list */,
+ unsigned long /* count */
+#endif
+);
+
+void
+SwapShorts (
+#if NeedFunctionPrototypes
+ short * /* list */,
+ unsigned long /* count */
+#endif
+);
+
+void
+SwapColorItem(
+#if NeedFunctionPrototypes
+ xColorItem * /* pItem */
+#endif
+);
+
+void
+SwapConnClientPrefix(
+#if NeedFunctionPrototypes
+ xConnClientPrefix * /* pCCP */
+#endif
+);
+
+#undef SWAPREQ_PROC
+
+#if NeedFunctionPrototypes
+#define SWAPREQ_PROC(func) int func(ClientPtr /* client */)
+#else
+#define SWAPREQ_PROC(func) int func(/* ClientPtr client */)
+#endif
+
+SWAPREQ_PROC(SProcAllocColor);
+SWAPREQ_PROC(SProcAllocColorCells);
+SWAPREQ_PROC(SProcAllocColorPlanes);
+SWAPREQ_PROC(SProcAllocNamedColor);
+SWAPREQ_PROC(SProcChangeActivePointerGrab);
+SWAPREQ_PROC(SProcChangeGC);
+SWAPREQ_PROC(SProcChangeHosts);
+SWAPREQ_PROC(SProcChangeKeyboardControl);
+SWAPREQ_PROC(SProcChangeKeyboardMapping);
+SWAPREQ_PROC(SProcChangePointerControl);
+SWAPREQ_PROC(SProcChangeProperty);
+SWAPREQ_PROC(SProcChangeWindowAttributes);
+SWAPREQ_PROC(SProcClearToBackground);
+SWAPREQ_PROC(SProcConfigureWindow);
+SWAPREQ_PROC(SProcConvertSelection);
+SWAPREQ_PROC(SProcCopyArea);
+SWAPREQ_PROC(SProcCopyColormapAndFree);
+SWAPREQ_PROC(SProcCopyGC);
+SWAPREQ_PROC(SProcCopyPlane);
+SWAPREQ_PROC(SProcCreateColormap);
+SWAPREQ_PROC(SProcCreateCursor);
+SWAPREQ_PROC(SProcCreateGC);
+SWAPREQ_PROC(SProcCreateGlyphCursor);
+SWAPREQ_PROC(SProcCreatePixmap);
+SWAPREQ_PROC(SProcCreateWindow);
+SWAPREQ_PROC(SProcDeleteProperty);
+SWAPREQ_PROC(SProcFillPoly);
+SWAPREQ_PROC(SProcFreeColors);
+SWAPREQ_PROC(SProcGetImage);
+SWAPREQ_PROC(SProcGetMotionEvents);
+SWAPREQ_PROC(SProcGetProperty);
+SWAPREQ_PROC(SProcGrabButton);
+SWAPREQ_PROC(SProcGrabKey);
+SWAPREQ_PROC(SProcGrabKeyboard);
+SWAPREQ_PROC(SProcGrabPointer);
+SWAPREQ_PROC(SProcImageText);
+SWAPREQ_PROC(SProcInternAtom);
+SWAPREQ_PROC(SProcListFonts);
+SWAPREQ_PROC(SProcListFontsWithInfo);
+SWAPREQ_PROC(SProcLookupColor);
+SWAPREQ_PROC(SProcNoOperation);
+SWAPREQ_PROC(SProcOpenFont);
+SWAPREQ_PROC(SProcPoly);
+SWAPREQ_PROC(SProcPolyText);
+SWAPREQ_PROC(SProcPutImage);
+SWAPREQ_PROC(SProcQueryBestSize);
+SWAPREQ_PROC(SProcQueryColors);
+SWAPREQ_PROC(SProcQueryExtension);
+SWAPREQ_PROC(SProcRecolorCursor);
+SWAPREQ_PROC(SProcReparentWindow);
+SWAPREQ_PROC(SProcResourceReq);
+SWAPREQ_PROC(SProcRotateProperties);
+SWAPREQ_PROC(SProcSendEvent);
+SWAPREQ_PROC(SProcSetClipRectangles);
+SWAPREQ_PROC(SProcSetDashes);
+SWAPREQ_PROC(SProcSetFontPath);
+SWAPREQ_PROC(SProcSetInputFocus);
+SWAPREQ_PROC(SProcSetScreenSaver);
+SWAPREQ_PROC(SProcSetSelectionOwner);
+SWAPREQ_PROC(SProcSimpleReq);
+SWAPREQ_PROC(SProcStoreColors);
+SWAPREQ_PROC(SProcStoreNamedColor);
+SWAPREQ_PROC(SProcTranslateCoords);
+SWAPREQ_PROC(SProcUngrabButton);
+SWAPREQ_PROC(SProcUngrabKey);
+SWAPREQ_PROC(SProcWarpPointer);
+
+#undef SWAPREQ_PROC
+
+#endif /* SWAPREQ_H */
diff --git a/xc/programs/Xserver/include/validate.h b/xc/programs/Xserver/include/validate.h
new file mode 100644
index 000000000..4cc699ed2
--- /dev/null
+++ b/xc/programs/Xserver/include/validate.h
@@ -0,0 +1,37 @@
+/* $TOG: validate.h /main/6 1998/02/09 14:30:17 kaleb $ */
+
+/*
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+*/
+
+#ifndef VALIDATE_H
+#define VALIDATE_H
+
+#include "miscstruct.h"
+#include "regionstr.h"
+
+typedef enum { VTOther, VTStack, VTMove, VTUnmap, VTMap } VTKind;
+
+/* union _Validate is now device dependent; see mivalidate.h for an example */
+typedef union _Validate *ValidatePtr;
+
+#define UnmapValData ((ValidatePtr)1)
+
+#endif /* VALIDATE_H */
diff --git a/xc/programs/Xserver/include/window.h b/xc/programs/Xserver/include/window.h
new file mode 100644
index 000000000..f08b085ba
--- /dev/null
+++ b/xc/programs/Xserver/include/window.h
@@ -0,0 +1,346 @@
+/* $TOG: window.h /main/9 1998/02/09 14:30:26 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#ifndef WINDOW_H
+#define WINDOW_H
+
+#include "misc.h"
+#include "region.h"
+#include "screenint.h"
+#include "X11/Xproto.h"
+
+#define TOTALLY_OBSCURED 0
+#define UNOBSCURED 1
+#define OBSCURED 2
+
+#define VisibilityNotViewable 3
+
+/* return values for tree-walking callback procedures */
+#define WT_STOPWALKING 0
+#define WT_WALKCHILDREN 1
+#define WT_DONTWALKCHILDREN 2
+#define WT_NOMATCH 3
+#define NullWindow ((WindowPtr) 0)
+
+typedef struct _BackingStore *BackingStorePtr;
+typedef struct _Window *WindowPtr;
+
+typedef int (*VisitWindowProcPtr)(
+#if NeedNestedPrototypes
+ WindowPtr /*pWin*/,
+ pointer /*data*/
+#endif
+);
+
+extern int TraverseTree(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ VisitWindowProcPtr /*func*/,
+ pointer /*data*/
+#endif
+);
+
+extern int WalkTree(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ VisitWindowProcPtr /*func*/,
+ pointer /*data*/
+#endif
+);
+
+extern WindowPtr AllocateWindow(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/
+#endif
+);
+
+extern Bool CreateRootWindow(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/
+#endif
+);
+
+extern void InitRootWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern void ClippedRegionFromBox(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ RegionPtr /*Rgn*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/
+#endif
+);
+
+extern WindowPtr RealChildHead(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern WindowPtr CreateWindow(
+#if NeedFunctionPrototypes
+ Window /*wid*/,
+ WindowPtr /*pParent*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*w*/,
+ unsigned int /*h*/,
+ unsigned int /*bw*/,
+ unsigned int /*class*/,
+ Mask /*vmask*/,
+ XID* /*vlist*/,
+ int /*depth*/,
+ ClientPtr /*client*/,
+ VisualID /*visual*/,
+ int* /*error*/
+#endif
+);
+
+extern int DeleteWindow(
+#if NeedFunctionPrototypes
+ pointer /*pWin*/,
+ XID /*wid*/
+#endif
+);
+
+extern void DestroySubwindows(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ ClientPtr /*client*/
+#endif
+);
+
+extern int ChangeWindowAttributes(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ Mask /*vmask*/,
+ XID* /*vlist*/,
+ ClientPtr /*client*/
+#endif
+);
+
+extern void GetWindowAttributes(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ ClientPtr /*client*/,
+ xGetWindowAttributesReply* /* wa */
+#endif
+);
+
+extern RegionPtr CreateUnclippedWinSize(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern void GravityTranslate(
+#if NeedFunctionPrototypes
+ int /*x*/,
+ int /*y*/,
+ int /*oldx*/,
+ int /*oldy*/,
+ int /*dw*/,
+ int /*dh*/,
+ unsigned /*gravity*/,
+ int* /*destx*/,
+ int* /*desty*/
+#endif
+);
+
+extern int ConfigureWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ Mask /*mask*/,
+ XID* /*vlist*/,
+ ClientPtr /*client*/
+#endif
+);
+
+extern int CirculateWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pParent*/,
+ int /*direction*/,
+ ClientPtr /*client*/
+#endif
+);
+
+extern int ReparentWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ WindowPtr /*pParent*/,
+ int /*x*/,
+ int /*y*/,
+ ClientPtr /*client*/
+#endif
+);
+
+extern int MapWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ ClientPtr /*client*/
+#endif
+);
+
+extern void MapSubwindows(
+#if NeedFunctionPrototypes
+ WindowPtr /*pParent*/,
+ ClientPtr /*client*/
+#endif
+);
+
+extern int UnmapWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ Bool /*fromConfigure*/
+#endif
+);
+
+extern void UnmapSubwindows(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern void HandleSaveSet(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern Bool VisibleBoundingBoxFromPoint(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ int /*x*/,
+ int /*y*/,
+ BoxPtr /*box*/
+#endif
+);
+
+extern Bool PointInWindowIsVisible(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ int /*x*/,
+ int /*y*/
+#endif
+);
+
+extern RegionPtr NotClippedByChildren(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern void SendVisibilityNotify(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern void SaveScreens(
+#if NeedFunctionPrototypes
+ int /*on*/,
+ int /*mode*/
+#endif
+);
+
+extern WindowPtr FindWindowWithOptional(
+#if NeedFunctionPrototypes
+ WindowPtr /*w*/
+#endif
+);
+
+extern void CheckWindowOptionalNeed(
+#if NeedFunctionPrototypes
+ WindowPtr /*w*/
+#endif
+);
+
+extern Bool MakeWindowOptional(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern void DisposeWindowOptional(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern WindowPtr MoveWindowInStack(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ WindowPtr /*pNextSib*/
+#endif
+);
+
+void SetWinSize(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+void SetBorderSize(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+void ResizeChildrenWinSize(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ int /*dx*/,
+ int /*dy*/,
+ int /*dw*/,
+ int /*dh*/
+#endif
+);
+
+#endif /* WINDOW_H */
diff --git a/xc/programs/Xserver/include/windowstr.h b/xc/programs/Xserver/include/windowstr.h
new file mode 100644
index 000000000..02350d260
--- /dev/null
+++ b/xc/programs/Xserver/include/windowstr.h
@@ -0,0 +1,223 @@
+/* $TOG: windowstr.h /main/37 1998/02/09 14:30:21 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#ifndef WINDOWSTRUCT_H
+#define WINDOWSTRUCT_H
+
+#include "window.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "cursor.h"
+#include "property.h"
+#include "resource.h" /* for ROOT_WINDOW_ID_BASE */
+#include "dix.h"
+#include "miscstruct.h"
+#include "X11/Xprotostr.h"
+#include "opaque.h"
+
+#define GuaranteeNothing 0
+#define GuaranteeVisBack 1
+
+#define SameBackground(as, a, bs, b) \
+ ((as) == (bs) && ((as) == None || \
+ (as) == ParentRelative || \
+ SamePixUnion(a,b,as == BackgroundPixel)))
+
+#define SameBorder(as, a, bs, b) \
+ EqualPixUnion(as, a, bs, b)
+
+typedef struct _WindowOpt {
+ VisualID visual; /* default: same as parent */
+ CursorPtr cursor; /* default: window.cursorNone */
+ Colormap colormap; /* default: same as parent */
+ Mask dontPropagateMask; /* default: window.dontPropagate */
+ Mask otherEventMasks; /* default: 0 */
+ struct _OtherClients *otherClients; /* default: NULL */
+ struct _GrabRec *passiveGrabs; /* default: NULL */
+ PropertyPtr userProps; /* default: NULL */
+ unsigned long backingBitPlanes; /* default: ~0L */
+ unsigned long backingPixel; /* default: 0 */
+#ifdef SHAPE
+ RegionPtr boundingShape; /* default: NULL */
+ RegionPtr clipShape; /* default: NULL */
+#endif
+#ifdef XINPUT
+ struct _OtherInputMasks *inputMasks; /* default: NULL */
+#endif
+} WindowOptRec, *WindowOptPtr;
+
+#define BackgroundPixel 2L
+#define BackgroundPixmap 3L
+
+typedef struct _Window {
+ DrawableRec drawable;
+ WindowPtr parent; /* ancestor chain */
+ WindowPtr nextSib; /* next lower sibling */
+ WindowPtr prevSib; /* next higher sibling */
+ WindowPtr firstChild; /* top-most child */
+ WindowPtr lastChild; /* bottom-most child */
+ RegionRec clipList; /* clipping rectangle for output */
+ RegionRec borderClip; /* NotClippedByChildren + border */
+ union _Validate *valdata;
+ RegionRec winSize;
+ RegionRec borderSize;
+ DDXPointRec origin; /* position relative to parent */
+ unsigned short borderWidth;
+ unsigned short deliverableEvents;
+ Mask eventMask;
+ PixUnion background;
+ PixUnion border;
+ pointer backStorage; /* null when BS disabled */
+ WindowOptPtr optional;
+ unsigned backgroundState:2; /* None, Relative, Pixel, Pixmap */
+ unsigned borderIsPixel:1;
+ unsigned cursorIsNone:1; /* else real cursor (might inherit) */
+ unsigned backingStore:2;
+ unsigned saveUnder:1;
+ unsigned DIXsaveUnder:1;
+ unsigned bitGravity:4;
+ unsigned winGravity:4;
+ unsigned overrideRedirect:1;
+ unsigned visibility:2;
+ unsigned mapped:1;
+ unsigned realized:1; /* ancestors are all mapped */
+ unsigned viewable:1; /* realized && InputOutput */
+ unsigned dontPropagate:3;/* index into DontPropagateMasks */
+ unsigned forcedBS:1; /* system-supplied backingStore */
+#ifdef NEED_DBE_BUF_BITS
+#define DBE_FRONT_BUFFER 1
+#define DBE_BACK_BUFFER 0
+ unsigned dstBuffer:1; /* destination buffer for rendering */
+ unsigned srcBuffer:1; /* source buffer for rendering */
+#endif
+ DevUnion *devPrivates;
+} WindowRec;
+
+/*
+ * Ok, a bunch of macros for accessing the optional record
+ * fields (or filling the appropriate default value)
+ */
+
+extern Mask DontPropagateMasks[];
+
+#define wTrackParent(w,field) ((w)->optional ? \
+ (w)->optional->field \
+ : FindWindowWithOptional(w)->optional->field)
+#define wUseDefault(w,field,def) ((w)->optional ? \
+ (w)->optional->field \
+ : def)
+
+#define wVisual(w) wTrackParent(w, visual)
+#define wCursor(w) ((w)->cursorIsNone ? None : wTrackParent(w, cursor))
+#define wColormap(w) ((w)->drawable.class == InputOnly ? None : wTrackParent(w, colormap))
+#define wDontPropagateMask(w) wUseDefault(w, dontPropagateMask, DontPropagateMasks[(w)->dontPropagate])
+#define wOtherEventMasks(w) wUseDefault(w, otherEventMasks, 0)
+#define wOtherClients(w) wUseDefault(w, otherClients, NULL)
+#ifdef XINPUT
+#define wOtherInputMasks(w) wUseDefault(w, inputMasks, NULL)
+#else
+#define wOtherInputMasks(w) NULL
+#endif
+#define wPassiveGrabs(w) wUseDefault(w, passiveGrabs, NULL)
+#define wUserProps(w) wUseDefault(w, userProps, NULL)
+#define wBackingBitPlanes(w) wUseDefault(w, backingBitPlanes, ~0L)
+#define wBackingPixel(w) wUseDefault(w, backingPixel, 0)
+#ifdef SHAPE
+#define wBoundingShape(w) wUseDefault(w, boundingShape, NULL)
+#define wClipShape(w) wUseDefault(w, clipShape, NULL)
+#endif
+#define wClient(w) (clients[CLIENT_ID((w)->drawable.id)])
+#define wBorderWidth(w) ((int) (w)->borderWidth)
+
+/* true when w needs a border drawn. */
+
+#ifdef SHAPE
+#define HasBorder(w) ((w)->borderWidth || wClipShape(w))
+#else
+#define HasBorder(w) ((w)->borderWidth)
+#endif
+
+typedef struct _ScreenSaverStuff {
+ WindowPtr pWindow;
+ XID wid;
+ char blanked;
+ Bool (*ExternalScreenSaver)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ int /*xstate*/,
+ Bool /*force*/
+#endif
+ );
+} ScreenSaverStuffRec, *ScreenSaverStuffPtr;
+
+#define SCREEN_IS_BLANKED 0
+#define SCREEN_ISNT_SAVED 1
+#define SCREEN_IS_TILED 2
+#define SCREEN_IS_BLACK 3
+
+#define HasSaverWindow(i) (savedScreenInfo[i].pWindow != NullWindow)
+
+extern int screenIsSaved;
+extern ScreenSaverStuffRec savedScreenInfo[MAXSCREENS];
+
+/*
+ * this is the configuration parameter "NO_BACK_SAVE"
+ * it means that any existant backing store should not
+ * be used to implement save unders.
+ */
+
+#ifndef NO_BACK_SAVE
+#define DO_SAVE_UNDERS(pWin) ((pWin)->drawable.pScreen->saveUnderSupport ==\
+ USE_DIX_SAVE_UNDERS)
+/*
+ * saveUnderSupport is set to this magic value when using DIXsaveUnders
+ */
+
+#define USE_DIX_SAVE_UNDERS 0x40
+#endif
+
+extern int numSaveUndersViewable;
+extern int deltaSaveUndersViewable;
+
+#endif /* WINDOWSTRUCT_H */
diff --git a/xc/programs/Xserver/iplan2p2/Imakefile b/xc/programs/Xserver/iplan2p2/Imakefile
new file mode 100644
index 000000000..d0858f1d3
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p2/Imakefile
@@ -0,0 +1,6 @@
+XCOMM $XFree86: xc/programs/Xserver/iplan2p2/Imakefile,v 3.0 1996/08/18 01:54:28 dawes Exp $
+XCOMM $XConsortium: Imakefile,v 1.1 91/12/28 13:32:27 rws Exp $
+#define IPlanes 2
+#define LinkDirectory ../iplan2p4
+
+#include "../iplan2p4/Imakefile"
diff --git a/xc/programs/Xserver/iplan2p4/Imakefile b/xc/programs/Xserver/iplan2p4/Imakefile
new file mode 100644
index 000000000..bafa629a5
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/Imakefile
@@ -0,0 +1,121 @@
+XCOMM $XFree86: xc/programs/Xserver/iplan2p4/Imakefile,v 3.4 1999/04/17 09:08:48 dawes Exp $
+XCOMM $XConsortium: Imakefile,v 5.41 93/09/06 18:37:23 rws Exp $
+#include <Server.tmpl>
+
+#ifndef IPlanes
+#define IPlanes 4
+#endif
+
+SRCS = iplgc.c iplrrop.c iplwindow.c \
+ iplpntwin.c iplmskbits.c iplpixmap.c iplbitblt.c \
+ iplfillsp.c iplsetsp.c iplscrinit.c iplallpriv.c \
+ iplgetsp.c iplfillrct.c \
+ iplsolidC.c iplsolidX.c iplsolidG.c \
+ ipltileoddC.c ipltileoddG.c ipltile32C.c ipltile32G.c \
+ iplcmap.c \
+ iplfillarcC.c iplfillarcG.c \
+ ipltegblt.c iplbstore.c \
+ iplpolypnt.c \
+ iplbres.c iplline.c iplhrzvert.c iplbresd.c iplimage.c iplseg.c \
+ iplbitblt.c iplbltC.c iplbltX.c iplbltO.c iplbltG.c \
+ iplply1rctC.c iplply1rctG.c iplpack.c
+
+OBJS = iplgc.o iplrrop.o iplwindow.o \
+ iplgetsp.o iplfillrct.o \
+ iplsolidC.o iplsolidX.o iplsolidG.o \
+ ipltileoddC.o ipltileoddG.o ipltile32C.o ipltile32G.o \
+ iplfillsp.o iplsetsp.o iplscrinit.o iplallpriv.o \
+ iplpntwin.o iplmskbits.o iplpixmap.o \
+ iplcmap.o \
+ iplfillarcC.o iplfillarcG.o \
+ ipltegblt.o iplbstore.o \
+ iplpolypnt.o \
+ iplbres.o iplline.o iplhrzvert.o iplbresd.o iplimage.o iplseg.o \
+ iplbitblt.o iplbltC.o iplbltX.o iplbltO.o iplbltG.o \
+ iplply1rctC.o iplply1rctG.o iplpack.o
+
+ INCLUDES = -I. -I../cfb -I../mfb -I../mi -I../include -I$(XINCLUDESRC) \
+ -I$(FONTINCSRC) $(EXTRAINCLUDES)
+ LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln \
+ ../mfb/llib-lmfb.ln ../mi/llib-lmi.ln
+ DEFINES = -DINTER_PLANES=IPlanes
+
+NormalLibraryObjectRule()
+#if IPlanes == 2
+NormalLibraryTarget(ipl2p2,$(OBJS))
+LintLibraryTarget(ipl2p2,$(SRCS))
+#elif IPlanes == 4
+NormalLibraryTarget(ipl2p4,$(OBJS))
+LintLibraryTarget(ipl2p4,$(SRCS))
+#elif IPlanes == 8
+NormalLibraryTarget(ipl2p8,$(OBJS))
+LintLibraryTarget(ipl2p8,$(SRCS))
+#endif
+
+NormalLintTarget($(SRCS))
+
+#ifdef LinkDirectory
+
+LinkSourceFile(ipl.h,LinkDirectory)
+LinkSourceFile(iplallpriv.c,LinkDirectory)
+LinkSourceFile(iplbitblt.c,LinkDirectory)
+LinkSourceFile(iplblt.c,LinkDirectory)
+LinkSourceFile(iplbres.c,LinkDirectory)
+LinkSourceFile(iplbresd.c,LinkDirectory)
+LinkSourceFile(iplbstore.c,LinkDirectory)
+LinkSourceFile(iplcmap.c,LinkDirectory)
+LinkSourceFile(iplfillarc.c,LinkDirectory)
+LinkSourceFile(iplfillrct.c,LinkDirectory)
+LinkSourceFile(iplfillsp.c,LinkDirectory)
+LinkSourceFile(iplgc.c,LinkDirectory)
+LinkSourceFile(iplgetsp.c,LinkDirectory)
+LinkSourceFile(iplhrzvert.c,LinkDirectory)
+LinkSourceFile(iplimage.c,LinkDirectory)
+LinkSourceFile(iplline.c,LinkDirectory)
+LinkSourceFile(iplmap.h,LinkDirectory)
+LinkSourceFile(iplmergerop.h,LinkDirectory)
+LinkSourceFile(iplmskbits.c,LinkDirectory)
+LinkSourceFile(iplmskbits.h,LinkDirectory)
+LinkSourceFile(iplpack.c,LinkDirectory)
+LinkSourceFile(iplpack.h,LinkDirectory)
+LinkSourceFile(iplpixmap.c,LinkDirectory)
+LinkSourceFile(iplply1rct.c,LinkDirectory)
+LinkSourceFile(iplpntwin.c,LinkDirectory)
+LinkSourceFile(iplpolypnt.c,LinkDirectory)
+LinkSourceFile(iplrrop.c,LinkDirectory)
+LinkSourceFile(iplrrop.h,LinkDirectory)
+LinkSourceFile(iplscrinit.c,LinkDirectory)
+LinkSourceFile(iplsetsp.c,LinkDirectory)
+LinkSourceFile(iplsolid.c,LinkDirectory)
+LinkSourceFile(ipltegblt.c,LinkDirectory)
+LinkSourceFile(ipltile32.c,LinkDirectory)
+LinkSourceFile(ipltileodd.c,LinkDirectory)
+LinkSourceFile(iplwindow.c,LinkDirectory)
+#endif
+
+ObjectFromSpecialSource(iplseg,iplline,-DPOLYSEGMENT)
+
+ObjectFromSpecialSource(iplfillarcC,iplfillarc,-DRROP=GXcopy)
+ObjectFromSpecialSource(iplfillarcG,iplfillarc,-DRROP=GXset)
+
+ObjectFromSpecialSource(iplbltC,iplblt,-DMROP=Mcopy)
+ObjectFromSpecialSource(iplbltX,iplblt,-DMROP=Mxor)
+ObjectFromSpecialSource(iplbltO,iplblt,-DMROP=Mor)
+ObjectFromSpecialSource(iplbltG,iplblt,-DMROP=0)
+
+ObjectFromSpecialSource(iplsolidC,iplsolid,-DRROP=GXcopy)
+ObjectFromSpecialSource(iplsolidX,iplsolid,-DRROP=GXxor)
+ObjectFromSpecialSource(iplsolidG,iplsolid,-DRROP=GXset)
+
+ObjectFromSpecialSource(ipltileoddC,ipltileodd,-DMROP=Mcopy)
+ObjectFromSpecialSource(ipltileoddG,ipltileodd,-DMROP=0)
+
+ObjectFromSpecialSource(ipltile32C,ipltile32,-DMROP=Mcopy)
+ObjectFromSpecialSource(ipltile32G,ipltile32,-DMROP=0)
+
+ObjectFromSpecialSource(iplply1rctC,iplply1rct,-DRROP=GXcopy)
+ObjectFromSpecialSource(iplply1rctG,iplply1rct,-DRROP=GXset)
+
+#ifndef OS2Architecture
+DependTarget()
+#endif
diff --git a/xc/programs/Xserver/iplan2p4/ipl.h b/xc/programs/Xserver/iplan2p4/ipl.h
new file mode 100644
index 000000000..cf741eeeb
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/ipl.h
@@ -0,0 +1,1493 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/ipl.h,v 3.4 1999/01/31 12:22:18 dawes Exp $ */
+/* $XConsortium: ipl.h,v 5.37 94/04/17 20:28:38 dpw Exp $ */
+/************************************************************
+Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
+
+ 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 no-
+tice appear in all copies and that both that copyright no-
+tice and this permission notice appear in supporting docu-
+mentation, and that the names of Sun or X Consortium
+not be used in advertising or publicity pertaining to
+distribution of the software without specific prior
+written permission. Sun and X Consortium make no
+representations about the suitability of this software for
+any purpose. It is provided "as is" without any express or
+implied warranty.
+
+SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
+NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
+ABLE 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.
+
+********************************************************/
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "pixmap.h"
+#include "region.h"
+#include "gc.h"
+#include "colormap.h"
+#include "miscstruct.h"
+#include "servermd.h"
+#include "windowstr.h"
+#include "mfb.h"
+#undef PixelType
+
+#include "iplmap.h"
+
+/*
+ private filed of pixmap
+ pixmap.devPrivate = (unsigned int *)pointer_to_bits
+ pixmap.devKind = width_of_pixmap_in_bytes
+*/
+
+extern int iplGCPrivateIndex;
+extern int iplWindowPrivateIndex;
+
+/* private field of GC */
+typedef struct {
+ unsigned char rop; /* special case rop values */
+ /* next two values unused in ipl, included for compatibility with mfb */
+ unsigned char ropOpStip; /* rop for opaque stipple */
+ /* this value is ropFillArea in mfb, usurped for ipl */
+ unsigned char oneRect; /* drawable has one clip rect */
+ unsigned long xor, and; /* reduced rop values */
+ unsigned short xorg[INTER_PLANES],andg[INTER_PLANES];
+ } iplPrivGC;
+
+typedef iplPrivGC *iplPrivGCPtr;
+
+#define iplGetGCPrivate(pGC) ((iplPrivGCPtr)\
+ (pGC)->devPrivates[iplGCPrivateIndex].ptr)
+
+#define iplGetCompositeClip(pGC) ((pGC)->pCompositeClip)
+
+/* way to carry RROP info around */
+typedef struct {
+ unsigned char rop;
+ unsigned long xor, and;
+ unsigned short xorg[INTER_PLANES],andg[INTER_PLANES];
+} iplRRopRec, *iplRRopPtr;
+
+/* private field of window */
+typedef struct {
+ unsigned char fastBorder; /* non-zero if border is 32 bits wide */
+ unsigned char fastBackground;
+ unsigned short unused; /* pad for alignment with Sun compiler */
+ DDXPointRec oldRotate;
+ PixmapPtr pRotatedBackground;
+ PixmapPtr pRotatedBorder;
+ } iplPrivWin;
+
+#define iplGetWindowPrivate(_pWin) ((iplPrivWin *)\
+ (_pWin)->devPrivates[iplWindowPrivateIndex].ptr)
+
+
+/* ipl8bit.c */
+
+extern int iplSetStipple(
+#if NeedFunctionPrototypes
+ int /*alu*/,
+ unsigned long /*fg*/,
+ unsigned long /*planemask*/
+#endif
+);
+
+extern int iplSetOpaqueStipple(
+#if NeedFunctionPrototypes
+ int /*alu*/,
+ unsigned long /*fg*/,
+ unsigned long /*bg*/,
+ unsigned long /*planemask*/
+#endif
+);
+
+extern int iplComputeClipMasks32(
+#if NeedFunctionPrototypes
+ BoxPtr /*pBox*/,
+ int /*numRects*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ CARD32 * /*clips*/
+#endif
+);
+/* ipl8cppl.c */
+
+extern void iplCopyImagePlane(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ int /*rop*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/,
+ unsigned long /*planemask*/
+#endif
+);
+
+extern void iplCopyPlane8to1(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ int /*rop*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/,
+ unsigned long /*planemask*/,
+ unsigned long /*bitPlane*/
+#endif
+);
+/* ipl8lineCO.c */
+
+extern int ipl8LineSS1RectCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/,
+ DDXPointPtr /*pptInitOrig*/,
+ int * /*x1p*/,
+ int * /*y1p*/,
+ int * /*x2p*/,
+ int * /*y2p*/
+#endif
+);
+
+extern void ipl8LineSS1Rect(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/
+#endif
+);
+
+extern void ipl8ClippedLineCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x1*/,
+ int /*y1*/,
+ int /*x2*/,
+ int /*y2*/,
+ BoxPtr /*boxp*/,
+ Bool /*shorten*/
+#endif
+);
+/* ipl8lineCP.c */
+
+extern int ipl8LineSS1RectPreviousCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/,
+ DDXPointPtr /*pptInitOrig*/,
+ int * /*x1p*/,
+ int * /*y1p*/,
+ int * /*x2p*/,
+ int * /*y2p*/
+
+#endif
+);
+/* ipl8lineG.c */
+
+extern int ipl8LineSS1RectGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/,
+ DDXPointPtr /*pptInitOrig*/,
+ int * /*x1p*/,
+ int * /*y1p*/,
+ int * /*x2p*/,
+ int * /*y2p*/
+#endif
+);
+
+extern void ipl8ClippedLineGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x1*/,
+ int /*y1*/,
+ int /*x2*/,
+ int /*y2*/,
+ BoxPtr /*boxp*/,
+ Bool /*shorten*/
+#endif
+);
+/* ipl8lineX.c */
+
+extern int ipl8LineSS1RectXor(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/,
+ DDXPointPtr /*pptInitOrig*/,
+ int * /*x1p*/,
+ int * /*y1p*/,
+ int * /*x2p*/,
+ int * /*y2p*/
+#endif
+);
+
+extern void ipl8ClippedLineXor(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x1*/,
+ int /*y1*/,
+ int /*x2*/,
+ int /*y2*/,
+ BoxPtr /*boxp*/,
+ Bool /*shorten*/
+#endif
+);
+/* ipl8segC.c */
+
+extern int ipl8SegmentSS1RectCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nseg*/,
+ xSegment * /*pSegInit*/
+#endif
+);
+/* ipl8segCS.c */
+
+extern int ipl8SegmentSS1RectShiftCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nseg*/,
+ xSegment * /*pSegInit*/
+#endif
+);
+
+extern void ipl8SegmentSS1Rect(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nseg*/,
+ xSegment * /*pSegInit*/
+#endif
+);
+/* ipl8segG.c */
+
+extern int ipl8SegmentSS1RectGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nseg*/,
+ xSegment * /*pSegInit*/
+#endif
+);
+/* iplsegX.c */
+
+extern int ipl8SegmentSS1RectXor(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nseg*/,
+ xSegment * /*pSegInit*/
+#endif
+);
+/* iplallpriv.c */
+
+extern Bool iplAllocatePrivates(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ int * /*window_index*/,
+ int * /*gc_index*/
+#endif
+);
+/* iplbitblt.c */
+
+extern RegionPtr iplBitBlt(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ GCPtr/*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*width*/,
+ int /*height*/,
+ int /*dstx*/,
+ int /*dsty*/,
+ void (* /*doBitBlt*/)(),
+ unsigned long /*bitPlane*/
+#endif
+);
+
+extern void iplDoBitblt(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/,
+ unsigned long /*planemask*/
+#endif
+);
+
+extern RegionPtr iplCopyArea(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ GCPtr/*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*width*/,
+ int /*height*/,
+ int /*dstx*/,
+ int /*dsty*/
+#endif
+);
+
+extern void iplCopyPlane1to8(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ int /*rop*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/,
+ unsigned long /*planemask*/,
+ unsigned long /*bitPlane*/
+#endif
+);
+
+extern RegionPtr iplCopyPlane(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ GCPtr /*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*width*/,
+ int /*height*/,
+ int /*dstx*/,
+ int /*dsty*/,
+ unsigned long /*bitPlane*/
+#endif
+);
+/* iplbltC.c */
+
+extern void iplDoBitbltCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/,
+ unsigned long /*planemask*/
+#endif
+);
+/* iplbltG.c */
+
+extern void iplDoBitbltGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/,
+ unsigned long /*planemask*/
+#endif
+);
+/* iplbltO.c */
+
+extern void iplDoBitbltOr(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/,
+ unsigned long /*planemask*/
+#endif
+);
+/* iplbltX.c */
+
+extern void iplDoBitbltXor(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/,
+ unsigned long /*planemask*/
+#endif
+);
+/* iplbres.c */
+
+extern void iplBresS(
+#if NeedFunctionPrototypes
+ int /*rop*/,
+ unsigned short * /*and*/,
+ unsigned short * /*xor*/,
+ unsigned short * /*addrl*/,
+ int /*nlwidth*/,
+ int /*signdx*/,
+ int /*signdy*/,
+ int /*axis*/,
+ int /*x1*/,
+ int /*y1*/,
+ int /*e*/,
+ int /*e1*/,
+ int /*e2*/,
+ int /*len*/
+#endif
+);
+/* iplbresd.c */
+
+extern void iplBresD(
+#if NeedFunctionPrototypes
+ iplRRopPtr /*rrops*/,
+ int * /*pdashIndex*/,
+ unsigned char * /*pDash*/,
+ int /*numInDashList*/,
+ int * /*pdashOffset*/,
+ int /*isDoubleDash*/,
+ unsigned short * /*addrl*/,
+ int /*nlwidth*/,
+ int /*signdx*/,
+ int /*signdy*/,
+ int /*axis*/,
+ int /*x1*/,
+ int /*y1*/,
+ int /*e*/,
+ int /*e1*/,
+ int /*e2*/,
+ int /*len*/
+#endif
+);
+/* iplbstore.c */
+
+extern void iplSaveAreas(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPixmap*/,
+ RegionPtr /*prgnSave*/,
+ int /*xorg*/,
+ int /*yorg*/,
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern void iplRestoreAreas(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPixmap*/,
+ RegionPtr /*prgnRestore*/,
+ int /*xorg*/,
+ int /*yorg*/,
+ WindowPtr /*pWin*/
+#endif
+);
+/* iplcmap.c */
+
+extern int iplListInstalledColormaps(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ Colormap * /*pmaps*/
+#endif
+);
+
+extern void iplInstallColormap(
+#if NeedFunctionPrototypes
+ ColormapPtr /*pmap*/
+#endif
+);
+
+extern void iplUninstallColormap(
+#if NeedFunctionPrototypes
+ ColormapPtr /*pmap*/
+#endif
+);
+
+extern void iplResolveColor(
+#if NeedFunctionPrototypes
+ unsigned short * /*pred*/,
+ unsigned short * /*pgreen*/,
+ unsigned short * /*pblue*/,
+ VisualPtr /*pVisual*/
+#endif
+);
+
+extern Bool iplInitializeColormap(
+#if NeedFunctionPrototypes
+ ColormapPtr /*pmap*/
+#endif
+);
+
+extern int iplExpandDirectColors(
+#if NeedFunctionPrototypes
+ ColormapPtr /*pmap*/,
+ int /*ndef*/,
+ xColorItem * /*indefs*/,
+ xColorItem * /*outdefs*/
+#endif
+);
+
+extern Bool iplCreateDefColormap(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/
+#endif
+);
+
+extern Bool iplSetVisualTypes(
+#if NeedFunctionPrototypes
+ int /*depth*/,
+ int /*visuals*/,
+ int /*bitsPerRGB*/
+#endif
+);
+
+extern Bool iplInitVisuals(
+#if NeedFunctionPrototypes
+ VisualPtr * /*visualp*/,
+ DepthPtr * /*depthp*/,
+ int * /*nvisualp*/,
+ int * /*ndepthp*/,
+ int * /*rootDepthp*/,
+ VisualID * /*defaultVisp*/,
+ unsigned long /*sizes*/,
+ int /*bitsPerRGB*/
+#endif
+);
+/* iplfillarcC.c */
+
+extern void iplPolyFillArcSolidCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+/* iplfillarcG.c */
+
+extern void iplPolyFillArcSolidGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+/* iplfillrct.c */
+
+extern void iplFillBoxTileOdd(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*n*/,
+ BoxPtr /*rects*/,
+ PixmapPtr /*tile*/,
+ int /*xrot*/,
+ int /*yrot*/
+#endif
+);
+
+extern void iplFillRectTileOdd(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nBox*/,
+ BoxPtr /*pBox*/
+#endif
+);
+
+extern void iplPolyFillRect(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nrectFill*/,
+ xRectangle * /*prectInit*/
+#endif
+);
+/* iplfillsp.c */
+
+extern void iplUnnaturalTileFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+extern void iplUnnaturalStippleFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+extern void ipl8Stipple32FS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+extern void ipl8OpaqueStipple32FS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+/* iplgc.c */
+
+extern GCOpsPtr iplMatchCommon(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/,
+ iplPrivGCPtr /*devPriv*/
+#endif
+);
+
+extern Bool iplCreateGC(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/
+#endif
+);
+
+extern void iplValidateGC(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/,
+ unsigned long /*changes*/,
+ DrawablePtr /*pDrawable*/
+#endif
+);
+
+/* iplgetsp.c */
+
+extern void iplGetSpans(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*wMax*/,
+ DDXPointPtr /*ppt*/,
+ int * /*pwidth*/,
+ int /*nspans*/,
+ char * /*pdstStart*/
+#endif
+);
+/* iplglblt8.c */
+
+extern void iplPolyGlyphBlt8(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+/* iplglrop8.c */
+
+extern void iplPolyGlyphRop8(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+/* iplhrzvert.c */
+
+extern int iplHorzS(
+#if NeedFunctionPrototypes
+ int /*rop*/,
+ unsigned short * /*and*/,
+ unsigned short * /*xor*/,
+ unsigned short * /*addrg*/,
+ int /*nlwidth*/,
+ int /*x1*/,
+ int /*y1*/,
+ int /*len*/
+#endif
+);
+
+extern int iplVertS(
+#if NeedFunctionPrototypes
+ int /*rop*/,
+ unsigned short * /*and*/,
+ unsigned short * /*xor*/,
+ unsigned short * /*addrg*/,
+ int /*nlwidth*/,
+ int /*x1*/,
+ int /*y1*/,
+ int /*len*/
+#endif
+);
+/* ipligblt8.c */
+
+extern void iplImageGlyphBlt8(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+/* iplimage.c */
+
+extern void iplPutImage(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*depth*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ int /*leftPad*/,
+ int /*format*/,
+ char * /*pImage*/
+#endif
+);
+
+extern void iplGetImage(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*sx*/,
+ int /*sy*/,
+ int /*w*/,
+ int /*h*/,
+ unsigned int /*format*/,
+ unsigned long /*planeMask*/,
+ char * /*pdstLine*/
+#endif
+);
+/* iplline.c */
+
+extern void iplLineSS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/
+#endif
+);
+
+extern void iplLineSD(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/
+#endif
+);
+/* iplmskbits.c */
+/* iplpixmap.c */
+
+extern PixmapPtr iplCreatePixmap(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ int /*width*/,
+ int /*height*/,
+ int /*depth*/
+#endif
+);
+
+extern Bool iplDestroyPixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPixmap*/
+#endif
+);
+
+extern PixmapPtr iplCopyPixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pSrc*/
+#endif
+);
+
+extern void iplPadPixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPixmap*/
+#endif
+);
+
+extern void iplXRotatePixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPix*/,
+ int /*rw*/
+#endif
+);
+
+extern void iplYRotatePixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPix*/,
+ int /*rh*/
+#endif
+);
+
+extern void iplCopyRotatePixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*psrcPix*/,
+ PixmapPtr * /*ppdstPix*/,
+ int /*xrot*/,
+ int /*yrot*/
+#endif
+);
+/* iplply1rctC.c */
+
+extern void iplFillPoly1RectCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*shape*/,
+ int /*mode*/,
+ int /*count*/,
+ DDXPointPtr /*ptsIn*/
+#endif
+);
+/* iplply1rctG.c */
+
+extern void iplFillPoly1RectGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*shape*/,
+ int /*mode*/,
+ int /*count*/,
+ DDXPointPtr /*ptsIn*/
+#endif
+);
+/* iplpntwin.c */
+
+extern void iplPaintWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ RegionPtr /*pRegion*/,
+ int /*what*/
+#endif
+);
+
+extern void iplFillBoxSolid(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*nBox*/,
+ BoxPtr /*pBox*/,
+ unsigned long /*pixel*/
+#endif
+);
+
+extern void iplFillBoxTile32(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*nBox*/,
+ BoxPtr /*pBox*/,
+ PixmapPtr /*tile*/
+#endif
+);
+/* iplpolypnt.c */
+
+extern void iplPolyPoint(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ xPoint * /*pptInit*/
+#endif
+);
+/* iplpush8.c */
+
+extern void iplPushPixels8(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/,
+ PixmapPtr /*pBitmap*/,
+ DrawablePtr /*pDrawable*/,
+ int /*dx*/,
+ int /*dy*/,
+ int /*xOrg*/,
+ int /*yOrg*/
+#endif
+);
+/* iplrctstp8.c */
+
+extern void ipl8FillRectOpaqueStippled32(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nBox*/,
+ BoxPtr /*pBox*/
+#endif
+);
+
+extern void ipl8FillRectTransparentStippled32(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nBox*/,
+ BoxPtr /*pBox*/
+#endif
+);
+
+extern void ipl8FillRectStippledUnnatural(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nBox*/,
+ BoxPtr /*pBox*/
+#endif
+);
+/* iplrrop.c */
+
+extern int iplReduceRasterOp(
+#if NeedFunctionPrototypes
+ int /*rop*/,
+ unsigned long /*fg*/,
+ unsigned long /*pm*/,
+ unsigned short * /*andp*/,
+ unsigned short * /*xorp*/
+#endif
+);
+/* iplscrinit.c */
+
+extern Bool iplCloseScreen(
+#if NeedFunctionPrototypes
+ int /*index*/,
+ ScreenPtr /*pScreen*/
+#endif
+);
+
+extern Bool iplSetupScreen(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ pointer /*pbits*/,
+ int /*xsize*/,
+ int /*ysize*/,
+ int /*dpix*/,
+ int /*dpiy*/,
+ int /*width*/
+#endif
+);
+
+extern int iplFinishScreenInit(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ pointer /*pbits*/,
+ int /*xsize*/,
+ int /*ysize*/,
+ int /*dpix*/,
+ int /*dpiy*/,
+ int /*width*/
+#endif
+);
+
+extern Bool iplScreenInit(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ pointer /*pbits*/,
+ int /*xsize*/,
+ int /*ysize*/,
+ int /*dpix*/,
+ int /*dpiy*/,
+ int /*width*/
+#endif
+);
+
+extern PixmapPtr iplGetScreenPixmap(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/
+#endif
+);
+
+extern void iplSetScreenPixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPix*/
+#endif
+);
+
+/* iplseg.c */
+
+extern void iplSegmentSS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nseg*/,
+ xSegment * /*pSeg*/
+#endif
+);
+
+extern void iplSegmentSD(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nseg*/,
+ xSegment * /*pSeg*/
+#endif
+);
+/* iplsetsp.c */
+
+extern int iplSetScanline(
+#if NeedFunctionPrototypes
+ int /*y*/,
+ int /*xOrigin*/,
+ int /*xStart*/,
+ int /*xEnd*/,
+ unsigned int * /*psrc*/,
+ int /*alu*/,
+ unsigned short * /*pdstBase*/,
+ int /*widthDst*/,
+ unsigned long /*planemask*/
+#endif
+);
+
+extern void iplSetSpans(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ char * /*psrc*/,
+ DDXPointPtr /*ppt*/,
+ int * /*pwidth*/,
+ int /*nspans*/,
+ int /*fSorted*/
+#endif
+);
+/* iplsolidC.c */
+
+extern void iplFillRectSolidCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nBox*/,
+ BoxPtr /*pBox*/
+#endif
+);
+
+extern void iplSolidSpansCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+/* iplsolidG.c */
+
+extern void iplFillRectSolidGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nBox*/,
+ BoxPtr /*pBox*/
+#endif
+);
+
+extern void iplSolidSpansGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+/* iplsolidX.c */
+
+extern void iplFillRectSolidXor(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nBox*/,
+ BoxPtr /*pBox*/
+#endif
+);
+
+extern void iplSolidSpansXor(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+/* iplteblt8.c */
+
+extern void iplTEGlyphBlt8(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*xInit*/,
+ int /*yInit*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+/* ipltegblt.c */
+
+extern void iplTEGlyphBlt(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+/* ipltile32C.c */
+
+extern void iplFillRectTile32Copy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nBox*/,
+ BoxPtr /*pBox*/
+#endif
+);
+
+extern void iplTile32FSCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+/* ipltile32G.c */
+
+extern void iplFillRectTile32General(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nBox*/,
+ BoxPtr /*pBox*/
+#endif
+);
+
+extern void iplTile32FSGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+/* ipltileoddC.c */
+
+extern void iplFillBoxTileOddCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*nBox*/,
+ BoxPtr /*pBox*/,
+ PixmapPtr /*tile*/,
+ int /*xrot*/,
+ int /*yrot*/,
+ int /*alu*/,
+ unsigned long /*planemask*/
+#endif
+);
+
+extern void iplFillSpanTileOddCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*n*/,
+ DDXPointPtr /*ppt*/,
+ int * /*pwidth*/,
+ PixmapPtr /*tile*/,
+ int /*xrot*/,
+ int /*yrot*/,
+ int /*alu*/,
+ unsigned long /*planemask*/
+#endif
+);
+
+extern void iplFillBoxTile32sCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*nBox*/,
+ BoxPtr /*pBox*/,
+ PixmapPtr /*tile*/,
+ int /*xrot*/,
+ int /*yrot*/,
+ int /*alu*/,
+ unsigned long /*planemask*/
+#endif
+);
+
+extern void iplFillSpanTile32sCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*n*/,
+ DDXPointPtr /*ppt*/,
+ int * /*pwidth*/,
+ PixmapPtr /*tile*/,
+ int /*xrot*/,
+ int /*yrot*/,
+ int /*alu*/,
+ unsigned long /*planemask*/
+#endif
+);
+/* ipltileoddG.c */
+
+extern void iplFillBoxTileOddGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*nBox*/,
+ BoxPtr /*pBox*/,
+ PixmapPtr /*tile*/,
+ int /*xrot*/,
+ int /*yrot*/,
+ int /*alu*/,
+ unsigned long /*planemask*/
+#endif
+);
+
+extern void iplFillSpanTileOddGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*n*/,
+ DDXPointPtr /*ppt*/,
+ int * /*pwidth*/,
+ PixmapPtr /*tile*/,
+ int /*xrot*/,
+ int /*yrot*/,
+ int /*alu*/,
+ unsigned long /*planemask*/
+#endif
+);
+
+extern void iplFillBoxTile32sGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*nBox*/,
+ BoxPtr /*pBox*/,
+ PixmapPtr /*tile*/,
+ int /*xrot*/,
+ int /*yrot*/,
+ int /*alu*/,
+ unsigned long /*planemask*/
+#endif
+);
+
+extern void iplFillSpanTile32sGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*n*/,
+ DDXPointPtr /*ppt*/,
+ int * /*pwidth*/,
+ PixmapPtr /*tile*/,
+ int /*xrot*/,
+ int /*yrot*/,
+ int /*alu*/,
+ unsigned long /*planemask*/
+#endif
+);
+/* iplwindow.c */
+
+extern Bool iplCreateWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern Bool iplDestroyWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern Bool iplMapWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWindow*/
+#endif
+);
+
+extern Bool iplPositionWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ int /*x*/,
+ int /*y*/
+#endif
+);
+
+extern Bool iplUnmapWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWindow*/
+#endif
+);
+
+extern void iplCopyWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ DDXPointRec /*ptOldOrg*/,
+ RegionPtr /*prgnSrc*/
+#endif
+);
+
+extern Bool iplChangeWindowAttributes(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ unsigned long /*mask*/
+#endif
+);
+/* iplzerarcC.c */
+
+extern void iplZeroPolyArcSS8Copy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+/* iplzerarcG.c */
+
+extern void iplZeroPolyArcSS8General(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+/* iplzerarcX.c */
+
+extern void iplZeroPolyArcSS8Xor(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+
+/* Common macros for extracting drawing information */
+
+#if !defined(SINGLEDEPTH) && PSZ != 8 || defined(FORCE_SEPARATE_PRIVATE)
+
+#define CFB_NEED_SCREEN_PRIVATE
+
+extern int iplScreenPrivateIndex;
+#endif
+
+#define iplGetWindowPixmap(d) \
+ ((* ((DrawablePtr)(d))->pScreen->GetWindowPixmap)((WindowPtr)(d)))
+
+#define iplGetTypedWidth(pDrawable,wtype) (\
+ (((pDrawable)->type != DRAWABLE_PIXMAP) ? \
+ (int) (iplGetWindowPixmap(pDrawable)->devKind) : \
+ (int)(((PixmapPtr)pDrawable)->devKind)) / sizeof (wtype))
+
+#define iplGetByteWidth(pDrawable) iplGetTypedWidth(pDrawable, unsigned char)
+
+#define iplGetPixelWidth(pDrawable) iplGetTypedWidth(pDrawable, PixelType)
+
+#define iplGetLongWidth(pDrawable) iplGetTypedWidth(pDrawable, unsigned long)
+
+#define iplGetTypedWidthAndPointer(pDrawable, width, pointer, wtype, ptype) {\
+ PixmapPtr _pPix; \
+ if ((pDrawable)->type != DRAWABLE_PIXMAP) \
+ _pPix = iplGetWindowPixmap(pDrawable); \
+ else \
+ _pPix = (PixmapPtr) (pDrawable); \
+ (pointer) = (ptype *) _pPix->devPrivate.ptr; \
+ (width) = ((int) _pPix->devKind) / sizeof (wtype); \
+}
+
+#define iplGetByteWidthAndPointer(pDrawable, width, pointer) \
+ iplGetTypedWidthAndPointer(pDrawable, width, pointer, unsigned char, unsigned char)
+
+#define iplGetLongWidthAndPointer(pDrawable, width, pointer) \
+ iplGetTypedWidthAndPointer(pDrawable, width, pointer, unsigned long, unsigned long)
+
+#define iplGetPixelWidthAndPointer(pDrawable, width, pointer) \
+ iplGetTypedWidthAndPointer(pDrawable, width, pointer, PixelType, PixelType)
+
+#define iplGetWindowTypedWidthAndPointer(pWin, width, pointer, wtype, ptype) {\
+ PixmapPtr _pPix = iplGetWindowPixmap((DrawablePtr) (pWin)); \
+ (pointer) = (ptype *) _pPix->devPrivate.ptr; \
+ (width) = ((int) _pPix->devKind) / sizeof (wtype); \
+}
+
+#define iplGetWindowLongWidthAndPointer(pWin, width, pointer) \
+ iplGetWindowTypedWidthAndPointer(pWin, width, pointer, unsigned long, unsigned long)
+
+#define iplGetWindowByteWidthAndPointer(pWin, width, pointer) \
+ iplGetWindowTypedWidthAndPointer(pWin, width, pointer, unsigned char, unsigned char)
+
+#define iplGetWindowPixelWidthAndPointer(pDrawable, width, pointer) \
+ iplGetWindowTypedWidthAndPointer(pDrawable, width, pointer, PixelType, PixelType)
+
+/* Macros which handle a coordinate in a single register */
+
+/* Most compilers will convert divide by 65536 into a shift, if signed
+ * shifts exist. If your machine does arithmetic shifts and your compiler
+ * can't get it right, add to this line.
+ */
+
+/* mips compiler - what a joke - it CSEs the 65536 constant into a reg
+ * forcing as to use div instead of shift. Let's be explicit.
+ */
+
+#if defined(mips) || defined(sparc) || defined(__alpha) || defined(__alpha__)
+#define GetHighWord(x) (((int) (x)) >> 16)
+#else
+#define GetHighWord(x) (((int) (x)) / 65536)
+#endif
+
+#if IMAGE_BYTE_ORDER == MSBFirst
+#define intToCoord(i,x,y) (((x) = GetHighWord(i)), ((y) = (int) ((short) (i))))
+#define coordToInt(x,y) (((x) << 16) | (y))
+#define intToX(i) (GetHighWord(i))
+#define intToY(i) ((int) ((short) i))
+#else
+#define intToCoord(i,x,y) (((x) = (int) ((short) (i))), ((y) = GetHighWord(i)))
+#define coordToInt(x,y) (((y) << 16) | (x))
+#define intToX(i) ((int) ((short) (i)))
+#define intToY(i) (GetHighWord(i))
+#endif
diff --git a/xc/programs/Xserver/iplan2p4/iplallpriv.c b/xc/programs/Xserver/iplan2p4/iplallpriv.c
new file mode 100644
index 000000000..57b8fce57
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplallpriv.c
@@ -0,0 +1,89 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplallpriv.c,v 3.0 1996/08/18 01:54:33 dawes Exp $ */
+/*
+ * $XConsortium: iplallpriv.c,v 1.5 94/04/17 20:28:42 dpw Exp $
+ *
+Copyright (c) 1991 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "servermd.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "resource.h"
+#include "colormap.h"
+#include "colormapst.h"
+#include "ipl.h"
+#include "mi.h"
+#include "mistruct.h"
+#include "dix.h"
+#include "mibstore.h"
+
+int iplWindowPrivateIndex;
+int iplGCPrivateIndex;
+#ifdef CFB_NEED_SCREEN_PRIVATE
+int iplScreenPrivateIndex;
+#endif
+
+extern RegionPtr (*iplPuntCopyPlane)();
+
+Bool
+iplAllocatePrivates(pScreen, window_index, gc_index)
+ ScreenPtr pScreen;
+ int *window_index, *gc_index;
+{
+ if (!window_index || !gc_index ||
+ *window_index == -1 && *gc_index == -1)
+ {
+ if (!mfbAllocatePrivates(pScreen,
+ &iplWindowPrivateIndex, &iplGCPrivateIndex))
+ return FALSE;
+ if (window_index)
+ *window_index = iplWindowPrivateIndex;
+ if (gc_index)
+ *gc_index = iplGCPrivateIndex;
+ }
+ else
+ {
+ iplWindowPrivateIndex = *window_index;
+ iplGCPrivateIndex = *gc_index;
+ }
+ if (!AllocateWindowPrivate(pScreen, iplWindowPrivateIndex,
+ sizeof(iplPrivWin)) ||
+ !AllocateGCPrivate(pScreen, iplGCPrivateIndex, sizeof(iplPrivGC)))
+ return FALSE;
+
+ iplPuntCopyPlane = miCopyPlane;
+#ifdef CFB_NEED_SCREEN_PRIVATE
+ iplScreenPrivateIndex = AllocateScreenPrivateIndex ();
+ if (iplScreenPrivateIndex == -1)
+ return FALSE;
+#endif
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplbitblt.c b/xc/programs/Xserver/iplan2p4/iplbitblt.c
new file mode 100644
index 000000000..50927e14f
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplbitblt.c
@@ -0,0 +1,384 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplbitblt.c,v 3.1 1998/03/20 21:08:08 hohndel Exp $ */
+/*
+ * ipl copy area
+ */
+
+/*
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+Author: Keith Packard
+
+*/
+/* $XConsortium: iplbitblt.c,v 5.51 94/05/27 11:00:56 dpw Exp $ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "ipl.h"
+#include "fastblt.h"
+#define MFB_CONSTS_ONLY
+#include "maskbits.h"
+
+#include "iplmskbits.h"
+
+RegionPtr
+iplBitBlt (pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, doBitBlt, bitPlane)
+ register DrawablePtr pSrcDrawable;
+ register DrawablePtr pDstDrawable;
+ GC *pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+ void (*doBitBlt)();
+ unsigned long bitPlane;
+{
+ RegionPtr prgnSrcClip; /* may be a new region, or just a copy */
+ Bool freeSrcClip = FALSE;
+
+ RegionPtr prgnExposed;
+ RegionRec rgnDst;
+ DDXPointPtr pptSrc;
+ register DDXPointPtr ppt;
+ register BoxPtr pbox;
+ int i;
+ register int dx;
+ register int dy;
+ xRectangle origSource;
+ DDXPointRec origDest;
+ int numRects;
+ BoxRec fastBox;
+ int fastClip = 0; /* for fast clipping with pixmap source */
+ int fastExpose = 0; /* for fast exposures with pixmap source */
+
+ origSource.x = srcx;
+ origSource.y = srcy;
+ origSource.width = width;
+ origSource.height = height;
+ origDest.x = dstx;
+ origDest.y = dsty;
+
+ if ((pSrcDrawable != pDstDrawable) &&
+ pSrcDrawable->pScreen->SourceValidate)
+ {
+ (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, srcx, srcy, width, height);
+ }
+
+ srcx += pSrcDrawable->x;
+ srcy += pSrcDrawable->y;
+
+ /* clip the source */
+
+ if (pSrcDrawable->type == DRAWABLE_PIXMAP)
+ {
+ if ((pSrcDrawable == pDstDrawable) &&
+ (pGC->clientClipType == CT_NONE))
+ {
+ prgnSrcClip = iplGetCompositeClip(pGC);
+ }
+ else
+ {
+ fastClip = 1;
+ }
+ }
+ else
+ {
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ if (!((WindowPtr) pSrcDrawable)->parent)
+ {
+ /*
+ * special case bitblt from root window in
+ * IncludeInferiors mode; just like from a pixmap
+ */
+ fastClip = 1;
+ }
+ else if ((pSrcDrawable == pDstDrawable) &&
+ (pGC->clientClipType == CT_NONE))
+ {
+ prgnSrcClip = iplGetCompositeClip(pGC);
+ }
+ else
+ {
+ prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
+ freeSrcClip = TRUE;
+ }
+ }
+ else
+ {
+ prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
+ }
+ }
+
+ fastBox.x1 = srcx;
+ fastBox.y1 = srcy;
+ fastBox.x2 = srcx + width;
+ fastBox.y2 = srcy + height;
+
+ /* Don't create a source region if we are doing a fast clip */
+ if (fastClip)
+ {
+ fastExpose = 1;
+ /*
+ * clip the source; if regions extend beyond the source size,
+ * make sure exposure events get sent
+ */
+ if (fastBox.x1 < pSrcDrawable->x)
+ {
+ fastBox.x1 = pSrcDrawable->x;
+ fastExpose = 0;
+ }
+ if (fastBox.y1 < pSrcDrawable->y)
+ {
+ fastBox.y1 = pSrcDrawable->y;
+ fastExpose = 0;
+ }
+ if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
+ {
+ fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
+ fastExpose = 0;
+ }
+ if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
+ {
+ fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
+ fastExpose = 0;
+ }
+ }
+ else
+ {
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+ REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
+ }
+
+ dstx += pDstDrawable->x;
+ dsty += pDstDrawable->y;
+
+ if (pDstDrawable->type == DRAWABLE_WINDOW)
+ {
+ if (!((WindowPtr)pDstDrawable)->realized)
+ {
+ if (!fastClip)
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return NULL;
+ }
+ }
+
+ dx = srcx - dstx;
+ dy = srcy - dsty;
+
+ /* Translate and clip the dst to the destination composite clip */
+ if (fastClip)
+ {
+ RegionPtr cclip;
+
+ /* Translate the region directly */
+ fastBox.x1 -= dx;
+ fastBox.x2 -= dx;
+ fastBox.y1 -= dy;
+ fastBox.y2 -= dy;
+
+ /* If the destination composite clip is one rectangle we can
+ do the clip directly. Otherwise we have to create a full
+ blown region and call intersect */
+
+ /* XXX because CopyPlane uses this routine for 8-to-1 bit
+ * copies, this next line *must* also correctly fetch the
+ * composite clip from an mfb gc
+ */
+
+ cclip = iplGetCompositeClip(pGC);
+ if (REGION_NUM_RECTS(cclip) == 1)
+ {
+ BoxPtr pBox = REGION_RECTS(cclip);
+
+ if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
+ if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
+ if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
+ if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
+
+ /* Check to see if the region is empty */
+ if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2)
+ {
+ REGION_INIT(pGC->pScreen, &rgnDst, NullBox, 0);
+ }
+ else
+ {
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+ }
+ }
+ else
+ {
+ /* We must turn off fastClip now, since we must create
+ a full blown region. It is intersected with the
+ composite clip below. */
+ fastClip = 0;
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox,1);
+ }
+ }
+ else
+ {
+ REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
+ }
+
+ if (!fastClip)
+ {
+ REGION_INTERSECT(pGC->pScreen, &rgnDst,
+ &rgnDst,
+ iplGetCompositeClip(pGC));
+ }
+
+ /* Do bit blitting */
+ numRects = REGION_NUM_RECTS(&rgnDst);
+ if (numRects && width && height)
+ {
+ if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects *
+ sizeof(DDXPointRec))))
+ {
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return NULL;
+ }
+ pbox = REGION_RECTS(&rgnDst);
+ ppt = pptSrc;
+ for (i = numRects; --i >= 0; pbox++, ppt++)
+ {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ (*doBitBlt) (pSrcDrawable, pDstDrawable, pGC->alu, &rgnDst, pptSrc, pGC->planemask, bitPlane);
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+
+ prgnExposed = NULL;
+ if (pGC->fExpose)
+ {
+ extern RegionPtr miHandleExposures();
+
+ /* Pixmap sources generate a NoExposed (we return NULL to do this) */
+ if (!fastExpose)
+ prgnExposed =
+ miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
+ origSource.x, origSource.y,
+ (int)origSource.width,
+ (int)origSource.height,
+ origDest.x, origDest.y, bitPlane);
+ }
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return prgnExposed;
+}
+
+
+void
+iplDoBitblt (pSrc, pDst, alu, prgnDst, pptSrc, planemask)
+ DrawablePtr pSrc, pDst;
+ int alu;
+ RegionPtr prgnDst;
+ DDXPointPtr pptSrc;
+ unsigned long planemask;
+{
+ void (*blt)() = iplDoBitbltGeneral;
+ if ((planemask & INTER_PMSK) == INTER_PMSK) {
+ switch (alu) {
+ case GXcopy:
+ blt = iplDoBitbltCopy;
+ break;
+ case GXxor:
+ blt = iplDoBitbltXor;
+ break;
+ case GXor:
+ blt = iplDoBitbltOr;
+ break;
+ }
+ }
+ (*blt) (pSrc, pDst, alu, prgnDst, pptSrc, planemask);
+}
+
+RegionPtr
+iplCopyArea(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty)
+ register DrawablePtr pSrcDrawable;
+ register DrawablePtr pDstDrawable;
+ GC *pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+{
+ void (*doBitBlt) ();
+
+ doBitBlt = iplDoBitbltCopy;
+ if (pGC->alu != GXcopy || (pGC->planemask & INTER_PMSK) != INTER_PMSK)
+ {
+ doBitBlt = iplDoBitbltGeneral;
+ if ((pGC->planemask & INTER_PMSK) == INTER_PMSK)
+ {
+ switch (pGC->alu) {
+ case GXxor:
+ doBitBlt = iplDoBitbltXor;
+ break;
+ case GXor:
+ doBitBlt = iplDoBitbltOr;
+ break;
+ }
+ }
+ }
+ return iplBitBlt (pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, doBitBlt, 0L);
+}
+
+/* shared among all different ipl depths through linker magic */
+RegionPtr (*iplPuntCopyPlane)();
+
+RegionPtr iplCopyPlane(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane)
+ DrawablePtr pSrcDrawable;
+ DrawablePtr pDstDrawable;
+ GCPtr pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+ unsigned long bitPlane;
+{
+ RegionPtr ret;
+ extern RegionPtr miHandleExposures();
+ void (*doBitBlt)();
+
+ ret = (*iplPuntCopyPlane) (pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+ return ret;
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplblt.c b/xc/programs/Xserver/iplan2p4/iplblt.c
new file mode 100644
index 000000000..8a48bd9da
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplblt.c
@@ -0,0 +1,427 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplblt.c,v 3.0 1996/08/18 01:54:35 dawes Exp $ */
+/*
+ * ipl copy area
+ */
+
+/*
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+Author: Keith Packard
+
+*/
+/* $XConsortium: iplblt.c,v 1.13 94/04/17 20:28:44 dpw Exp $ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "ipl.h"
+#include "fastblt.h"
+#include "iplmergerop.h"
+#include "iplmskbits.h"
+
+void
+INTER_MROP_NAME(iplDoBitblt)(pSrc, pDst, alu, prgnDst, pptSrc, planemask)
+ DrawablePtr pSrc, pDst;
+ int alu;
+ RegionPtr prgnDst;
+ DDXPointPtr pptSrc;
+ unsigned long planemask;
+{
+ INTER_DECLAREG(*psrcBase);
+ INTER_DECLAREG(*pdstBase); /* start of src and dst bitmaps */
+ int widthSrc, widthDst; /* add to get to same position in next line */
+
+ BoxPtr pbox;
+ int nbox;
+
+ BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
+ /* temporaries for shuffling rectangles */
+ DDXPointPtr pptTmp, pptNew1, pptNew2;
+ /* shuffling boxes entails shuffling the
+ source points too */
+ int w, h;
+ int xdir; /* 1 = left right, -1 = right left/ */
+ int ydir; /* 1 = top down, -1 = bottom up */
+
+ INTER_DECLAREG(*psrcLine);
+ INTER_DECLAREG(*pdstLine); /* pointers to line with current src and dst */
+ INTER_DECLAREG(*psrc); /* pointer to current src group */
+ INTER_DECLAREG(*pdst); /* pointer to current dst group */
+
+ INTER_MROP_DECLARE_REG()
+
+ /* following used for looping through a line */
+ INTER_DECLAREG(startmask);
+ INTER_DECLAREG(endmask); /* masks for writing ends of dst */
+ int ngMiddle; /* whole groups in dst */
+ int xoffSrc, xoffDst;
+ register int leftShift, rightShift;
+ INTER_DECLAREGP(bits);
+ INTER_DECLAREGP(bits1);
+ INTER_DECLAREGP(bits2);
+ register int ng; /* temp copy of ngMiddle */
+
+ /* place to store full source word */
+ int nstart; /* number of ragged bits at start of dst */
+ int nend; /* number of ragged bits at end of dst */
+ int srcStartOver; /* pulling nstart bits from src
+ overflows into the next word? */
+ int careful;
+ int tmpSrc;
+
+ INTER_MROP_INITIALIZE(alu,planemask);
+
+ iplGetGroupWidthAndPointer (pSrc, widthSrc, psrcBase)
+
+ iplGetGroupWidthAndPointer (pDst, widthDst, pdstBase)
+
+ /* XXX we have to err on the side of safety when both are windows,
+ * because we don't know if IncludeInferiors is being used.
+ */
+ careful = ((pSrc == pDst) ||
+ ((pSrc->type == DRAWABLE_WINDOW) &&
+ (pDst->type == DRAWABLE_WINDOW)));
+
+ pbox = REGION_RECTS(prgnDst);
+ nbox = REGION_NUM_RECTS(prgnDst);
+
+ pboxNew1 = NULL;
+ pptNew1 = NULL;
+ pboxNew2 = NULL;
+ pptNew2 = NULL;
+ if (careful && (pptSrc->y < pbox->y1))
+ {
+ /* walk source botttom to top */
+ ydir = -1;
+ widthSrc = -widthSrc;
+ widthDst = -widthDst;
+
+ if (nbox > 1)
+ {
+ /* keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ if(!pboxNew1)
+ return;
+ pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pptNew1)
+ {
+ DEALLOCATE_LOCAL(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox)
+ {
+ while ((pboxNext >= pbox) &&
+ (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp <= pboxBase)
+ {
+ *pboxNew1++ = *pboxTmp++;
+ *pptNew1++ = *pptTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ pptNew1 -= nbox;
+ pptSrc = pptNew1;
+ }
+ }
+ else
+ {
+ /* walk source top to bottom */
+ ydir = 1;
+ }
+
+ if (careful && (pptSrc->x < pbox->x1))
+ {
+ /* walk source right to left */
+ xdir = -1;
+
+ if (nbox > 1)
+ {
+ /* reverse order of rects in each band */
+ pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pboxNew2 || !pptNew2)
+ {
+ if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
+ if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
+ if (pboxNew1)
+ {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox)
+ {
+ while ((pboxNext < pbox+nbox) &&
+ (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp != pboxBase)
+ {
+ *pboxNew2++ = *--pboxTmp;
+ *pptNew2++ = *--pptTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ pptNew2 -= nbox;
+ pptSrc = pptNew2;
+ }
+ }
+ else
+ {
+ /* walk source left to right */
+ xdir = 1;
+ }
+
+ while(nbox--)
+ {
+ w = pbox->x2 - pbox->x1;
+ h = pbox->y2 - pbox->y1;
+
+ if (ydir == -1) /* start at last scanline of rectangle */
+ {
+ psrcLine = psrcBase + ((pptSrc->y+h-1) * -widthSrc);
+ pdstLine = pdstBase + ((pbox->y2-1) * -widthDst);
+ }
+ else /* start at first scanline */
+ {
+ psrcLine = psrcBase + (pptSrc->y * widthSrc);
+ pdstLine = pdstBase + (pbox->y1 * widthDst);
+ }
+ if ((pbox->x1 & INTER_PIM) + w <= INTER_PPG)
+ {
+ INTER_maskpartialbits (pbox->x1, w, endmask);
+ startmask = 0;
+ ngMiddle = 0;
+ }
+ else
+ {
+ INTER_maskbits(pbox->x1, w, startmask, endmask, ngMiddle);
+ }
+
+ if (xdir == 1)
+ {
+ xoffSrc = pptSrc->x & INTER_PIM;
+ xoffDst = pbox->x1 & INTER_PIM;
+ pdstLine += (pbox->x1 >> INTER_PGSH) * INTER_PLANES;
+ psrcLine += (pptSrc->x >> INTER_PGSH) * INTER_PLANES;
+ ng = xoffSrc - xoffDst;
+ if (xoffSrc == xoffDst)
+ {
+ while (h--)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ pdstLine += widthDst;
+ psrcLine += widthSrc;
+ if (startmask)
+ {
+ INTER_MROP_MASK(psrc, pdst, startmask, pdst);
+ INTER_NEXT_GROUP(psrc);
+ INTER_NEXT_GROUP(pdst);
+ }
+ ng = ngMiddle;
+
+ DuffL(ng, label1,
+ INTER_MROP_SOLID(psrc, pdst, pdst);
+ INTER_NEXT_GROUP(psrc);
+ INTER_NEXT_GROUP(pdst);
+ )
+ if (endmask)
+ INTER_MROP_MASK(psrc, pdst, endmask, pdst);
+ }
+ }
+ else
+ {
+ if (xoffSrc > xoffDst)
+ {
+ leftShift = xoffSrc - xoffDst;
+ rightShift = (INTER_PIM+1) - leftShift;
+ }
+ else
+ {
+ rightShift = xoffDst - xoffSrc;
+ leftShift = (INTER_PIM+1) - rightShift;
+ }
+ while (h--)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ pdstLine += widthDst;
+ psrcLine += widthSrc;
+ INTER_CLR(bits);
+ if (xoffSrc > xoffDst) {
+ INTER_COPY(psrc, bits);
+ INTER_NEXT_GROUP(psrc);
+ }
+ if (startmask)
+ {
+ INTER_GETLRC(leftShift, rightShift, psrc, bits, bits1);
+ INTER_MROP_MASK(bits1, pdst, startmask, pdst);
+ INTER_NEXT_GROUP(psrc);
+ INTER_NEXT_GROUP(pdst);
+ }
+ ng = ngMiddle;
+ DuffL (ng,label2,
+ INTER_GETLRC(leftShift, rightShift, psrc, bits, bits1);
+ INTER_MROP_SOLID(bits1, pdst, pdst);
+ INTER_NEXT_GROUP(psrc);
+ INTER_NEXT_GROUP(pdst);
+ )
+ if (endmask)
+ {
+ if ((endmask << rightShift) & 0xffff) {
+ INTER_GETLRC(leftShift, rightShift, psrc, bits,
+ bits1);
+ }
+ else {
+ INTER_SCRLEFT(leftShift, bits, bits1);
+ }
+ INTER_MROP_MASK(bits1, pdst, endmask, pdst);
+ }
+ }
+ }
+ }
+ else /* xdir == -1 */
+ {
+ xoffSrc = (pptSrc->x + w - 1) & INTER_PIM;
+ xoffDst = (pbox->x2 - 1) & INTER_PIM;
+ pdstLine += (((pbox->x2-1) >> INTER_PGSH) + 1) * INTER_PLANES;
+ psrcLine += (((pptSrc->x+w - 1) >> INTER_PGSH) + 1) * INTER_PLANES;
+ if (xoffSrc == xoffDst)
+ {
+ while (h--)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ pdstLine += widthDst;
+ psrcLine += widthSrc;
+ if (endmask)
+ {
+ INTER_PREV_GROUP(psrc);
+ INTER_PREV_GROUP(pdst);
+ INTER_MROP_MASK(psrc, pdst, endmask, pdst);
+ }
+ ng = ngMiddle;
+
+ DuffL(ng,label3,
+ INTER_PREV_GROUP(psrc);
+ INTER_PREV_GROUP(pdst);
+ INTER_MROP_SOLID(psrc, pdst, pdst);
+ )
+
+ if (startmask)
+ {
+ INTER_PREV_GROUP(psrc);
+ INTER_PREV_GROUP(pdst);
+ INTER_MROP_MASK(psrc, pdst, startmask, pdst);
+ }
+ }
+ }
+ else
+ {
+ if (xoffDst > xoffSrc)
+ {
+ rightShift = xoffDst - xoffSrc;
+ leftShift = (INTER_PIM + 1) - rightShift;
+ }
+ else
+ {
+ leftShift = xoffSrc - xoffDst;
+ rightShift = (INTER_PIM + 1) - leftShift;
+ }
+ while (h--)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ pdstLine += widthDst;
+ psrcLine += widthSrc;
+ INTER_CLR(bits);
+ if (xoffDst > xoffSrc) {
+ INTER_PREV_GROUP(psrc);
+ INTER_COPY(psrc, bits);
+ }
+ if (endmask)
+ {
+ INTER_PREV_GROUP(psrc);
+ INTER_PREV_GROUP(pdst);
+ INTER_GETRLC(rightShift, leftShift, psrc, bits, bits1);
+ INTER_MROP_MASK(bits1, pdst, endmask, pdst);
+ }
+ ng = ngMiddle;
+ DuffL (ng, label4,
+ INTER_PREV_GROUP(psrc);
+ INTER_PREV_GROUP(pdst);
+ INTER_GETRLC(rightShift, leftShift, psrc, bits, bits1);
+ INTER_MROP_SOLID(bits1, pdst, pdst);
+ )
+ if (startmask)
+ {
+ INTER_PREV_GROUP(psrc);
+ INTER_PREV_GROUP(pdst);
+ if ((startmask >> leftShift) & 0xffff) {
+ INTER_GETRLC(rightShift, leftShift, psrc, bits,
+ bits1);
+ }
+ else {
+ INTER_SCRRIGHT(rightShift, bits, bits1);
+ }
+ INTER_MROP_MASK(bits1, pdst, startmask, pdst);
+ }
+ }
+ }
+ }
+ pbox++;
+ pptSrc++;
+ }
+ if (pboxNew2)
+ {
+ DEALLOCATE_LOCAL(pptNew2);
+ DEALLOCATE_LOCAL(pboxNew2);
+ }
+ if (pboxNew1)
+ {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplbres.c b/xc/programs/Xserver/iplan2p4/iplbres.c
new file mode 100644
index 000000000..9d2b571db
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplbres.c
@@ -0,0 +1,182 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplbres.c,v 3.0 1996/08/18 01:54:36 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: iplbres.c,v 1.15 94/04/17 20:28:45 dpw Exp $ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "misc.h"
+#include "ipl.h"
+#include "servermd.h"
+#include "miline.h"
+
+#include "iplmskbits.h"
+
+/* Solid bresenham line */
+/* NOTES
+ e2 is used less often than e1, so it's not in a register
+*/
+
+void
+iplBresS(rop, andp, xorp, addrg, ngwidth, signdx, signdy, axis, x1, y1, e, e1,
+ e2, len)
+ int rop;
+ INTER_DECLARERRAX(andp);
+ INTER_DECLARERRAX(xorp);
+ INTER_DECLAREG(*addrg); /* pointer to base of bitmap */
+ int ngwidth; /* width in longwords of bitmap */
+ register int signdx;
+ int signdy; /* signs of directions */
+ int axis; /* major axis (Y_AXIS or X_AXIS) */
+ int x1, y1; /* initial point */
+ register int e; /* error accumulator */
+ register int e1; /* bresenham increments */
+ int e2;
+ int len; /* length of line */
+{
+ register int e3 = e2-e1;
+ INTER_DECLAREG(bit);
+ INTER_DECLAREG(leftbit);
+ INTER_DECLAREG(rightbit);
+
+ /* point to longword containing first point */
+ addrg = addrg + y1 * ngwidth + (x1 >> INTER_PGSH) * INTER_PLANES;
+
+ if (signdy < 0)
+ ngwidth = -ngwidth;
+ e = e-e1; /* to make looping easier */
+
+ leftbit = iplmask[0];
+ rightbit = iplmask[INTER_PPG-1];
+ bit = iplmask[x1 & INTER_PIM];
+
+ if (axis == X_AXIS)
+ {
+ if (signdx > 0)
+ {
+ while (len--)
+ {
+ INTER_DoMaskRRop(addrg, andp, xorp, bit, addrg);
+ bit = bit >> 1;
+ e += e1;
+ if (e >= 0)
+ {
+ addrg += ngwidth;
+ e += e3;
+ }
+ if (!bit)
+ {
+ bit = leftbit;
+ addrg += INTER_PLANES;
+ }
+ }
+ }
+ else
+ {
+ while (len--)
+ {
+ INTER_DoMaskRRop(addrg, andp, xorp, bit, addrg);
+ e += e1;
+ bit = bit << 1;
+ if (e >= 0)
+ {
+ addrg += ngwidth;
+ e += e3;
+ }
+ if (!bit)
+ {
+ bit = rightbit;
+ addrg -= INTER_PLANES;
+ }
+ }
+ }
+ } /* if X_AXIS */
+ else
+ {
+ if (signdx > 0)
+ {
+ while(len--)
+ {
+ INTER_DoMaskRRop(addrg, andp, xorp, bit, addrg);
+ e += e1;
+ if (e >= 0)
+ {
+ bit = bit >> 1;
+ if (!bit)
+ {
+ bit = leftbit;
+ addrg += INTER_PLANES;
+ }
+ e += e3;
+ }
+ addrg += ngwidth;
+ }
+ }
+ else
+ {
+ while(len--)
+ {
+ INTER_DoMaskRRop(addrg, andp, xorp, bit, addrg);
+ e += e1;
+ if (e >= 0)
+ {
+ bit = bit << 1;
+ if (!bit)
+ {
+ bit = rightbit;
+ addrg -= INTER_PLANES;
+ }
+ e += e3;
+ }
+ addrg += ngwidth;
+ }
+ }
+ } /* else Y_AXIS */
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplbresd.c b/xc/programs/Xserver/iplan2p4/iplbresd.c
new file mode 100644
index 000000000..7cc93e90c
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplbresd.c
@@ -0,0 +1,208 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplbresd.c,v 3.0 1996/08/18 01:54:38 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: iplbresd.c,v 1.16 94/04/17 20:28:45 dpw Exp $ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "misc.h"
+#include "ipl.h"
+#include "miline.h"
+#include "iplmskbits.h"
+
+/* Dashed bresenham line */
+
+void
+iplBresD(rrops,
+ pdashIndex, pDash, numInDashList, pdashOffset, isDoubleDash,
+ addrg, ngwidth,
+ signdx, signdy, axis, x1, y1, e, e1, e2, len)
+ iplRRopPtr rrops;
+ int *pdashIndex; /* current dash */
+ unsigned char *pDash; /* dash list */
+ int numInDashList; /* total length of dash list */
+ int *pdashOffset; /* offset into current dash */
+ int isDoubleDash;
+ INTER_DECLAREG(*addrg); /* pointer to base of bitmap */
+ int ngwidth; /* width in groups of bitmap */
+ int signdx, signdy; /* signs of directions */
+ int axis; /* major axis (Y_AXIS or X_AXIS) */
+ int x1, y1; /* initial point */
+ register int e; /* error accumulator */
+ register int e1; /* bresenham increments */
+ int e2;
+ int len; /* length of line */
+{
+ register int e3 = e2-e1;
+ int dashIndex;
+ int dashOffset;
+ int dashRemaining;
+ INTER_DECLARERRAX(xorFg);
+ INTER_DECLARERRAX(andFg);
+ INTER_DECLARERRAX(xorBg);
+ INTER_DECLARERRAX(andBg);
+ int thisDash;
+
+ dashOffset = *pdashOffset;
+ dashIndex = *pdashIndex;
+ xorFg = rrops[0].xorg;
+ andFg = rrops[0].andg;
+ xorBg = rrops[1].xorg;
+ andBg = rrops[1].andg;
+ dashRemaining = pDash[dashIndex] - dashOffset;
+ if ((thisDash = dashRemaining) >= len)
+ {
+ thisDash = len;
+ dashRemaining -= len;
+ }
+ e = e-e1; /* to make looping easier */
+
+#define BresStep(minor,major) {if ((e += e1) >= 0) { e += e3; minor; } major;}
+
+#define NextDash {\
+ dashIndex++; \
+ if (dashIndex == numInDashList) \
+ dashIndex = 0; \
+ dashRemaining = pDash[dashIndex]; \
+ if ((thisDash = dashRemaining) >= len) \
+ { \
+ dashRemaining -= len; \
+ thisDash = len; \
+ } \
+}
+
+ {
+ INTER_DECLAREG(startbit);
+ INTER_DECLAREG(bit);
+
+ /* point to longword containing first point */
+ addrg = addrg + (y1 * ngwidth) + (x1 >> INTER_PGSH) * INTER_PLANES;
+ signdy = signdy * ngwidth;
+ signdx = signdx * INTER_PLANES;
+
+ if (signdx > 0)
+ startbit = iplmask[0];
+ else
+ startbit = iplmask[INTER_PPG-1];
+ bit = iplmask[x1 & INTER_PIM];
+
+#define X_Loop(store) while(thisDash--) {\
+ store; \
+ BresStep(addrg += signdy, \
+ if (signdx > 0) \
+ bit >>= 1; \
+ else \
+ bit <<= 1; \
+ if (!bit) \
+ { \
+ bit = startbit; \
+ addrg += signdx; \
+ }) \
+ }
+#define Y_Loop(store) while(thisDash--) {\
+ store; \
+ BresStep(if (signdx > 0) \
+ bit >>= 1; \
+ else \
+ bit <<= 1; \
+ if (!bit) \
+ { \
+ bit = startbit; \
+ addrg += signdx; \
+ }, \
+ addrg += signdy) \
+ }
+
+ if (axis == X_AXIS)
+ {
+ for (;;)
+ {
+ len -= thisDash;
+ if (dashIndex & 1) {
+ if (isDoubleDash) {
+ X_Loop(
+ INTER_DoMaskRRop(addrg, andBg, xorBg, bit, addrg);
+ )
+ } else {
+ X_Loop(;)
+ }
+ } else {
+ X_Loop(INTER_DoMaskRRop(addrg, andFg, xorFg, bit, addrg));
+ }
+ if (!len)
+ break;
+ NextDash
+ }
+ } /* if X_AXIS */
+ else
+ {
+ for (;;)
+ {
+ len -= thisDash;
+ if (dashIndex & 1) {
+ if (isDoubleDash) {
+ Y_Loop(
+ INTER_DoMaskRRop(addrg, andBg, xorBg, bit, addrg);
+ )
+ } else {
+ Y_Loop(;)
+ }
+ } else {
+ Y_Loop(INTER_DoMaskRRop(addrg, andFg, xorFg, bit, addrg));
+ }
+ if (!len)
+ break;
+ NextDash
+ }
+ } /* else Y_AXIS */
+ }
+ *pdashIndex = dashIndex;
+ *pdashOffset = pDash[dashIndex] - dashRemaining;
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplbstore.c b/xc/programs/Xserver/iplan2p4/iplbstore.c
new file mode 100644
index 000000000..5719ca308
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplbstore.c
@@ -0,0 +1,155 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplbstore.c,v 3.0 1996/08/18 01:54:39 dawes Exp $ */
+
+/*-
+ * iplbstore.c --
+ * Functions required by the backing-store implementation in MI.
+ *
+ * Copyright (c) 1987 by the Regents of the University of California
+ *
+ * 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. The University of California
+ * makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ *
+ *
+ */
+#ifndef lint
+static char rcsid[] =
+"$XConsortium: iplbstore.c,v 5.8 93/12/13 17:21:51 dpw Exp $ SPRITE (Berkeley)";
+#endif
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "ipl.h"
+#include "X.h"
+#include "mibstore.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * iplSaveAreas --
+ * Function called by miSaveAreas to actually fetch the areas to be
+ * saved into the backing pixmap. This is very simple to do, since
+ * iplDoBitblt is designed for this very thing. The region to save is
+ * already destination-relative and we're given the offset to the
+ * window origin, so we have only to create an array of points of the
+ * u.l. corners of the boxes in the region translated to the screen
+ * coordinate system and fetch the screen pixmap out of its devPrivate
+ * field....
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Data are copied from the screen into the pixmap.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+iplSaveAreas(pPixmap, prgnSave, xorg, yorg, pWin)
+ PixmapPtr pPixmap; /* Backing pixmap */
+ RegionPtr prgnSave; /* Region to save (pixmap-relative) */
+ int xorg; /* X origin of region */
+ int yorg; /* Y origin of region */
+ WindowPtr pWin;
+{
+ register DDXPointPtr pPt;
+ DDXPointPtr pPtsInit;
+ register BoxPtr pBox;
+ register int i;
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ PixmapPtr pScrPix;
+
+ i = REGION_NUM_RECTS(prgnSave);
+ pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(i * sizeof(DDXPointRec));
+ if (!pPtsInit)
+ return;
+
+ pBox = REGION_RECTS(prgnSave);
+ pPt = pPtsInit;
+ while (--i >= 0) {
+ pPt->x = pBox->x1 + xorg;
+ pPt->y = pBox->y1 + yorg;
+ pPt++;
+ pBox++;
+ }
+
+#ifdef CFB_NEED_SCREEN_PRIVATE
+ pScrPix = (PixmapPtr) pScreen->devPrivates[iplScreenPrivateIndex].ptr;
+#else
+ pScrPix = (PixmapPtr) pScreen->devPrivate;
+#endif
+
+ iplDoBitbltCopy((DrawablePtr) pScrPix, (DrawablePtr)pPixmap,
+ GXcopy, prgnSave, pPtsInit, ~0L);
+
+ DEALLOCATE_LOCAL (pPtsInit);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * iplRestoreAreas --
+ * Function called by miRestoreAreas to actually fetch the areas to be
+ * restored from the backing pixmap. This is very simple to do, since
+ * iplDoBitblt is designed for this very thing. The region to restore is
+ * already destination-relative and we're given the offset to the
+ * window origin, so we have only to create an array of points of the
+ * u.l. corners of the boxes in the region translated to the pixmap
+ * coordinate system and fetch the screen pixmap out of its devPrivate
+ * field....
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Data are copied from the pixmap into the screen.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+iplRestoreAreas(pPixmap, prgnRestore, xorg, yorg, pWin)
+ PixmapPtr pPixmap; /* Backing pixmap */
+ RegionPtr prgnRestore; /* Region to restore (screen-relative)*/
+ int xorg; /* X origin of window */
+ int yorg; /* Y origin of window */
+ WindowPtr pWin;
+{
+ register DDXPointPtr pPt;
+ DDXPointPtr pPtsInit;
+ register BoxPtr pBox;
+ register int i;
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ PixmapPtr pScrPix;
+
+ i = REGION_NUM_RECTS(prgnRestore);
+ pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(i*sizeof(DDXPointRec));
+ if (!pPtsInit)
+ return;
+
+ pBox = REGION_RECTS(prgnRestore);
+ pPt = pPtsInit;
+ while (--i >= 0) {
+ pPt->x = pBox->x1 - xorg;
+ pPt->y = pBox->y1 - yorg;
+ pPt++;
+ pBox++;
+ }
+
+#ifdef CFB_NEED_SCREEN_PRIVATE
+ pScrPix = (PixmapPtr) pScreen->devPrivates[iplScreenPrivateIndex].ptr;
+#else
+ pScrPix = (PixmapPtr) pScreen->devPrivate;
+#endif
+
+ iplDoBitbltCopy((DrawablePtr)pPixmap, (DrawablePtr) pScrPix,
+ GXcopy, prgnRestore, pPtsInit, ~0L);
+
+ DEALLOCATE_LOCAL (pPtsInit);
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplcmap.c b/xc/programs/Xserver/iplan2p4/iplcmap.c
new file mode 100644
index 000000000..21abfdbb3
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplcmap.c
@@ -0,0 +1,122 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplcmap.c,v 3.1 1998/11/22 10:37:41 dawes Exp $ */
+/* $XConsortium: iplcmap.c,v 4.19 94/04/17 20:28:46 dpw Exp $ */
+/************************************************************
+Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
+
+ 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 no-
+tice appear in all copies and that both that copyright no-
+tice and this permission notice appear in supporting docu-
+mentation, and that the names of Sun or X Consortium
+not be used in advertising or publicity pertaining to
+distribution of the software without specific prior
+written permission. Sun and X Consortium make no
+representations about the suitability of this software for
+any purpose. It is provided "as is" without any express or
+implied warranty.
+
+SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
+NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
+ABLE 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.
+
+********************************************************/
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "Xproto.h"
+#include "scrnintstr.h"
+#include "colormapst.h"
+#include "resource.h"
+#include "micmap.h"
+
+int
+iplListInstalledColormaps(pScreen, pmaps)
+ ScreenPtr pScreen;
+ Colormap *pmaps;
+{
+ return miListInstalledColormaps(pScreen, pmaps);
+}
+
+
+void
+iplInstallColormap(pmap)
+ ColormapPtr pmap;
+{
+ miInstallColormap(pmap);
+}
+
+void
+iplUninstallColormap(pmap)
+ ColormapPtr pmap;
+{
+ miUninstallColormap(pmap);
+}
+
+void
+iplResolveColor(pred, pgreen, pblue, pVisual)
+ unsigned short *pred, *pgreen, *pblue;
+ register VisualPtr pVisual;
+{
+ miResolveColor(pred, pgreen, pblue, pVisual);
+}
+
+Bool
+iplInitializeColormap(pmap)
+ register ColormapPtr pmap;
+{
+ return miInitializeColormap(pmap);
+}
+
+int
+iplExpandDirectColors (pmap, ndef, indefs, outdefs)
+ ColormapPtr pmap;
+ int ndef;
+ xColorItem *indefs, *outdefs;
+{
+ return miExpandDirectColors(pmap, ndef, indefs, outdefs);
+}
+
+Bool
+iplCreateDefColormap(pScreen)
+ ScreenPtr pScreen;
+{
+ return miCreateDefColormap(pScreen);
+}
+
+Bool
+iplSetVisualTypes (depth, visuals, bitsPerRGB)
+ int depth;
+ int visuals;
+{
+ return miSetVisualTypes(depth, visuals, bitsPerRGB, -1);
+}
+
+/*
+ * Given a list of formats for a screen, create a list
+ * of visuals and depths for the screen which coorespond to
+ * the set which can be used with this version of ipl.
+ */
+
+Bool
+iplInitVisuals (visualp, depthp, nvisualp, ndepthp, rootDepthp, defaultVisp, sizes, bitsPerRGB)
+ VisualPtr *visualp;
+ DepthPtr *depthp;
+ int *nvisualp, *ndepthp;
+ int *rootDepthp;
+ VisualID *defaultVisp;
+ unsigned long sizes;
+ int bitsPerRGB;
+{
+ return miInitVisuals(visualp, depthp, nvisualp, ndepthp, rootDepthp,
+ defaultVisp, sizes, bitsPerRGB, -1);
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplfillarc.c b/xc/programs/Xserver/iplan2p4/iplfillarc.c
new file mode 100644
index 000000000..c77db6b63
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplfillarc.c
@@ -0,0 +1,267 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplfillarc.c,v 3.0 1996/08/18 01:54:41 dawes Exp $ */
+/************************************************************
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+********************************************************/
+
+/* $XConsortium: iplfillarc.c,v 5.15 94/04/17 20:28:47 dpw Exp $ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "Xprotostr.h"
+#include "miscstruct.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "ipl.h"
+#include "mifillarc.h"
+#include "iplrrop.h"
+#include "mi.h"
+#include "iplmskbits.h"
+
+static void
+INTER_RROP_NAME(iplFillEllipseSolid) (pDraw, pGC, arc)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ xArc *arc;
+{
+ int x, y, e;
+ int yk, xk, ym, xm, dx, dy, xorg, yorg;
+ miFillArcRec info;
+ INTER_DECLAREG(*addrgt);
+ INTER_DECLAREG(*addrgb);
+ INTER_DECLAREG(*addrg);
+ register int n;
+ int ngwidth;
+ INTER_RROP_DECLARE
+ register int xpos;
+ register int slw;
+ INTER_DECLAREG(startmask);
+ INTER_DECLAREG(endmask);
+ int nlmiddle;
+
+ iplGetGroupWidthAndPointer (pDraw, ngwidth, addrgt);
+
+ INTER_RROP_FETCH_GC(pGC);
+ miFillArcSetup(arc, &info);
+ MIFILLARCSETUP();
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ addrgb = addrgt;
+ addrgt += ngwidth * (yorg - y);
+ addrgb += ngwidth * (yorg + y + dy);
+ while (y)
+ {
+ addrgt += ngwidth;
+ addrgb -= ngwidth;
+ MIFILLARCSTEP(slw);
+ if (!slw)
+ continue;
+ xpos = xorg - x;
+ addrg = addrgt + (xpos >> INTER_PGSH) * INTER_PLANES;
+ if (((xpos & INTER_PIM) + slw) <= INTER_PPG)
+ {
+ INTER_maskpartialbits(xpos, slw, startmask);
+ INTER_RROP_SOLID_MASK(addrg,startmask);
+ if (miFillArcLower(slw))
+ {
+ addrg = addrgb + (xpos >> INTER_PGSH) * INTER_PLANES;
+ INTER_RROP_SOLID_MASK(addrg, startmask);
+ }
+ continue;
+ }
+ INTER_maskbits(xpos, slw, startmask, endmask, nlmiddle);
+ if (startmask)
+ {
+ INTER_RROP_SOLID_MASK(addrg, startmask);
+ INTER_NEXT_GROUP(addrg);
+ }
+ n = nlmiddle;
+ INTER_RROP_SPAN(addrg,n)
+
+ if (endmask)
+ INTER_RROP_SOLID_MASK(addrg, endmask);
+ if (!miFillArcLower(slw))
+ continue;
+ addrg = addrgb + (xpos >> INTER_PGSH) * INTER_PLANES;
+ if (startmask)
+ {
+ INTER_RROP_SOLID_MASK(addrg, startmask);
+ INTER_NEXT_GROUP(addrg);
+ }
+ n = nlmiddle;
+ INTER_RROP_SPAN(addrg, n);
+ if (endmask)
+ INTER_RROP_SOLID_MASK(addrg, endmask);
+ }
+}
+
+#define FILLSPAN(xl,xr,addr) \
+ if (xr >= xl) \
+ { \
+ n = xr - xl + 1; \
+ addrg = addr + (xl >> INTER_PGSH) * INTER_PLANES; \
+ if (((xl & INTER_PIM) + n) <= INTER_PPG) \
+ { \
+ INTER_maskpartialbits(xl, n, startmask); \
+ INTER_RROP_SOLID_MASK(addrg, startmask); \
+ } \
+ else \
+ { \
+ INTER_maskbits(xl, n, startmask, endmask, n); \
+ if (startmask) \
+ { \
+ INTER_RROP_SOLID_MASK(addrg, startmask); \
+ INTER_NEXT_GROUP(addrg); \
+ } \
+ while (n--) \
+ { \
+ INTER_RROP_SOLID(addrg); \
+ INTER_NEXT_GROUP(addrg); \
+ } \
+ if (endmask) \
+ INTER_RROP_SOLID_MASK(addrg, endmask); \
+ } \
+ }
+
+#define FILLSLICESPANS(flip,addr) \
+ if (!flip) \
+ { \
+ FILLSPAN(xl, xr, addr); \
+ } \
+ else \
+ { \
+ xc = xorg - x; \
+ FILLSPAN(xc, xr, addr); \
+ xc += slw - 1; \
+ FILLSPAN(xl, xc, addr); \
+ }
+
+static void
+INTER_RROP_NAME(iplFillArcSliceSolid)(pDraw, pGC, arc)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ xArc *arc;
+{
+ int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
+ register int x, y, e;
+ miFillArcRec info;
+ miArcSliceRec slice;
+ int xl, xr, xc;
+ INTER_DECLAREG(*addrgt);
+ INTER_DECLAREG(*addrgb);
+ INTER_DECLAREG(*addrg);
+ register int n;
+ int ngwidth;
+ INTER_RROP_DECLARE
+ INTER_DECLAREG(startmask);
+ INTER_DECLAREG(endmask);
+
+ iplGetGroupWidthAndPointer (pDraw, ngwidth, addrgt);
+
+ INTER_RROP_FETCH_GC(pGC);
+ miFillArcSetup(arc, &info);
+ miFillArcSliceSetup(arc, &slice, pGC);
+ MIFILLARCSETUP();
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ addrgb = addrgt;
+ addrgt += ngwidth * (yorg - y);
+ addrgb += ngwidth * (yorg + y + dy);
+ slice.edge1.x += pDraw->x;
+ slice.edge2.x += pDraw->x;
+ while (y > 0)
+ {
+ addrgt += ngwidth;
+ addrgb -= ngwidth;
+ MIFILLARCSTEP(slw);
+ MIARCSLICESTEP(slice.edge1);
+ MIARCSLICESTEP(slice.edge2);
+ if (miFillSliceUpper(slice))
+ {
+ MIARCSLICEUPPER(xl, xr, slice, slw);
+ FILLSLICESPANS(slice.flip_top, addrgt);
+ }
+ if (miFillSliceLower(slice))
+ {
+ MIARCSLICELOWER(xl, xr, slice, slw);
+ FILLSLICESPANS(slice.flip_bot, addrgb);
+ }
+ }
+}
+
+void
+INTER_RROP_NAME(iplPolyFillArcSolid) (pDraw, pGC, narcs, parcs)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ register xArc *arc;
+ register int i;
+ int x2, y2;
+ BoxRec box;
+ RegionPtr cclip;
+
+ cclip = iplGetCompositeClip(pGC);
+ for (arc = parcs, i = narcs; --i >= 0; arc++)
+ {
+ if (miFillArcEmpty(arc))
+ continue;
+ if (miCanFillArc(arc))
+ {
+ box.x1 = arc->x + pDraw->x;
+ box.y1 = arc->y + pDraw->y;
+ /*
+ * Because box.x2 and box.y2 get truncated to 16 bits, and the
+ * RECT_IN_REGION test treats the resulting number as a signed
+ * integer, the RECT_IN_REGION test alone can go the wrong way.
+ * This can result in a server crash because the rendering
+ * routines in this file deal directly with cpu addresses
+ * of pixels to be stored, and do not clip or otherwise check
+ * that all such addresses are within their respective pixmaps.
+ * So we only allow the RECT_IN_REGION test to be used for
+ * values that can be expressed correctly in a signed short.
+ */
+ x2 = box.x1 + (int)arc->width + 1;
+ box.x2 = x2;
+ y2 = box.y1 + (int)arc->height + 1;
+ box.y2 = y2;
+ if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) &&
+ (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
+ {
+ if ((arc->angle2 >= FULLCIRCLE) ||
+ (arc->angle2 <= -FULLCIRCLE))
+ INTER_RROP_NAME(iplFillEllipseSolid)(pDraw, pGC, arc);
+ else
+ INTER_RROP_NAME(iplFillArcSliceSolid)(pDraw, pGC, arc);
+ continue;
+ }
+ }
+ miPolyFillArc(pDraw, pGC, 1, arc);
+ }
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplfillrct.c b/xc/programs/Xserver/iplan2p4/iplfillrct.c
new file mode 100644
index 000000000..512c48048
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplfillrct.c
@@ -0,0 +1,277 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplfillrct.c,v 3.1 1998/03/20 21:08:08 hohndel Exp $ */
+/*
+ * Fill rectangles.
+ */
+
+/*
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+*/
+
+/* $XConsortium: iplfillrct.c,v 5.18 94/04/17 20:28:47 dpw Exp $ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "servermd.h"
+#include "gcstruct.h"
+#include "window.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+
+#include "ipl.h"
+#include "iplmskbits.h"
+#include "mergerop.h"
+
+
+void
+iplFillBoxTileOdd (pDrawable, n, rects, tile, xrot, yrot)
+ DrawablePtr pDrawable;
+ int n;
+ BoxPtr rects;
+ PixmapPtr tile;
+ int xrot, yrot;
+{
+ if (tile->drawable.width & INTER_PIM)
+ iplFillBoxTileOddCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L);
+ else
+ iplFillBoxTile32sCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0L);
+}
+
+void
+iplFillRectTileOdd (pDrawable, pGC, nBox, pBox)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nBox;
+ BoxPtr pBox;
+{
+ int xrot, yrot;
+ void (*fill)();
+
+ xrot = pDrawable->x + pGC->patOrg.x;
+ yrot = pDrawable->y + pGC->patOrg.y;
+ if (pGC->tile.pixmap->drawable.width & INTER_PIM)
+ {
+ fill = iplFillBoxTileOddGeneral;
+ if ((pGC->planemask & INTER_PMSK) == INTER_PMSK)
+ {
+ if (pGC->alu == GXcopy)
+ fill = iplFillBoxTileOddCopy;
+ }
+ }
+ else
+ {
+ fill = iplFillBoxTile32sGeneral;
+ if ((pGC->planemask & INTER_PMSK) == INTER_PMSK)
+ {
+ if (pGC->alu == GXcopy)
+ fill = iplFillBoxTile32sCopy;
+ }
+ }
+ (*fill) (pDrawable, nBox, pBox, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask);
+}
+
+#define NUM_STACK_RECTS 1024
+
+void
+iplPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int nrectFill; /* number of rectangles to fill */
+ xRectangle *prectInit; /* Pointer to first rectangle to fill */
+{
+ xRectangle *prect;
+ RegionPtr prgnClip;
+ register BoxPtr pbox;
+ register BoxPtr pboxClipped;
+ BoxPtr pboxClippedBase;
+ BoxPtr pextent;
+ BoxRec stackRects[NUM_STACK_RECTS];
+ iplPrivGC *priv;
+ int numRects;
+ void (*BoxFill)();
+ int n;
+ int xorg, yorg;
+
+ priv = iplGetGCPrivate(pGC);
+ prgnClip = pGC->pCompositeClip;
+
+ BoxFill = 0;
+ switch (pGC->fillStyle)
+ {
+ case FillSolid:
+ switch (priv->rop) {
+ case GXcopy:
+ BoxFill = iplFillRectSolidCopy;
+ break;
+ case GXxor:
+ BoxFill = iplFillRectSolidXor;
+ break;
+ default:
+ BoxFill = iplFillRectSolidGeneral;
+ break;
+ }
+ break;
+ case FillTiled:
+ if (!pGC->pRotatedPixmap)
+ BoxFill = iplFillRectTileOdd;
+ else
+ {
+ if (pGC->alu == GXcopy && (pGC->planemask & INTER_PMSK) == INTER_PMSK)
+ BoxFill = iplFillRectTile32Copy;
+ else
+ BoxFill = iplFillRectTile32General;
+ }
+ break;
+ }
+ prect = prectInit;
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+ if (xorg || yorg)
+ {
+ prect = prectInit;
+ n = nrectFill;
+ while(n--)
+ {
+ prect->x += xorg;
+ prect->y += yorg;
+ prect++;
+ }
+ }
+
+ prect = prectInit;
+
+ numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
+ if (numRects > NUM_STACK_RECTS)
+ {
+ pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
+ if (!pboxClippedBase)
+ return;
+ }
+ else
+ pboxClippedBase = stackRects;
+
+ pboxClipped = pboxClippedBase;
+
+ if (REGION_NUM_RECTS(prgnClip) == 1)
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_RECTS(prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ if ((pboxClipped->x1 = prect->x) < x1)
+ pboxClipped->x1 = x1;
+
+ if ((pboxClipped->y1 = prect->y) < y1)
+ pboxClipped->y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ pboxClipped->x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ pboxClipped->y2 = by2;
+
+ prect++;
+ if ((pboxClipped->x1 < pboxClipped->x2) &&
+ (pboxClipped->y1 < pboxClipped->y2))
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ else
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ BoxRec box;
+
+ if ((box.x1 = prect->x) < x1)
+ box.x1 = x1;
+
+ if ((box.y1 = prect->y) < y1)
+ box.y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ box.x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ box.y2 = by2;
+
+ prect++;
+
+ if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
+ continue;
+
+ n = REGION_NUM_RECTS (prgnClip);
+ pbox = REGION_RECTS(prgnClip);
+
+ /* clip the rectangle to each box in the clip region
+ this is logically equivalent to calling Intersect()
+ */
+ while(n--)
+ {
+ pboxClipped->x1 = max(box.x1, pbox->x1);
+ pboxClipped->y1 = max(box.y1, pbox->y1);
+ pboxClipped->x2 = min(box.x2, pbox->x2);
+ pboxClipped->y2 = min(box.y2, pbox->y2);
+ pbox++;
+
+ /* see if clipping left anything */
+ if(pboxClipped->x1 < pboxClipped->x2 &&
+ pboxClipped->y1 < pboxClipped->y2)
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ }
+ if (pboxClipped != pboxClippedBase)
+ (*BoxFill) (pDrawable, pGC,
+ pboxClipped-pboxClippedBase, pboxClippedBase);
+ if (pboxClippedBase != stackRects)
+ DEALLOCATE_LOCAL(pboxClippedBase);
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplfillsp.c b/xc/programs/Xserver/iplan2p4/iplfillsp.c
new file mode 100644
index 000000000..010f911f6
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplfillsp.c
@@ -0,0 +1,380 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplfillsp.c,v 3.0 1996/08/18 01:54:43 dawes Exp $ */
+/************************************************************
+Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
+
+ 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 no-
+tice appear in all copies and that both that copyright no-
+tice and this permission notice appear in supporting docu-
+mentation, and that the names of Sun or X Consortium
+not be used in advertising or publicity pertaining to
+distribution of the software without specific prior
+written permission. Sun and X Consortium make no
+representations about the suitability of this software for
+any purpose. It is provided "as is" without any express or
+implied warranty.
+
+SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
+NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
+ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* $XConsortium: iplfillsp.c,v 5.24 94/04/17 20:28:48 dpw Exp $ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "servermd.h"
+#include "gcstruct.h"
+#include "window.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+
+#include "ipl.h"
+
+#include "mergerop.h"
+
+#define MFB_CONSTS_ONLY
+#include "maskbits.h"
+
+#include "mi.h"
+#include "mispans.h"
+
+#include "iplmskbits.h"
+
+/* scanline filling for color frame buffer
+ written by drewry, oct 1986 modified by smarks
+ changes for compatibility with Little-endian systems Jul 1987; MIT:yba.
+
+ these routines all clip. they assume that anything that has called
+them has already translated the points (i.e. pGC->miTranslate is
+non-zero, which is howit gets set in iplCreateGC().)
+
+ the number of new scnalines created by clipping ==
+MaxRectsPerBand * nSpans.
+
+ FillSolid is overloaded to be used for OpaqueStipple as well,
+if fgPixel == bgPixel.
+Note that for solids, PrivGC.rop == PrivGC.ropOpStip
+
+
+ FillTiled is overloaded to be used for OpaqueStipple, if
+fgPixel != bgPixel. based on the fill style, it uses
+{RotatedTile, gc.alu} or {RotatedStipple, PrivGC.ropOpStip}
+*/
+
+#ifdef notdef
+#include <stdio.h>
+static
+dumpspans(n, ppt, pwidth)
+ int n;
+ DDXPointPtr ppt;
+ int *pwidth;
+{
+ fprintf(stderr,"%d spans\n", n);
+ while (n--) {
+ fprintf(stderr, "[%d,%d] %d\n", ppt->x, ppt->y, *pwidth);
+ ppt++;
+ pwidth++;
+ }
+ fprintf(stderr, "\n");
+}
+#endif
+
+/* Fill spans with tiles that aren't 32 bits wide */
+void
+iplUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+DrawablePtr pDrawable;
+GC *pGC;
+int nInit; /* number of spans to fill */
+DDXPointPtr pptInit; /* pointer to list of start points */
+int *pwidthInit; /* pointer to list of n widths */
+int fSorted;
+{
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ void (*fill)();
+ int xrot, yrot;
+
+ if (!(pGC->planemask))
+ return;
+
+ if (pGC->tile.pixmap->drawable.width & INTER_PIM)
+ {
+ fill = iplFillSpanTileOddGeneral;
+ if ((pGC->planemask & INTER_PMSK) == INTER_PMSK)
+ {
+ if (pGC->alu == GXcopy)
+ fill = iplFillSpanTileOddCopy;
+ }
+ }
+ else
+ {
+ fill = iplFillSpanTile32sGeneral;
+ if ((pGC->planemask & INTER_PMSK) == INTER_PMSK)
+ {
+ if (pGC->alu == GXcopy)
+ fill = iplFillSpanTile32sCopy;
+ }
+ }
+ n = nInit * miFindMaxBand( iplGetCompositeClip(pGC) );
+ if ( n == 0 )
+ return;
+ pwidth = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ ppt = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!ppt || !pwidth)
+ {
+ if (ppt) DEALLOCATE_LOCAL(ppt);
+ if (pwidth) DEALLOCATE_LOCAL(pwidth);
+ return;
+ }
+ n = miClipSpans( iplGetCompositeClip(pGC),
+ pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ xrot = pDrawable->x + pGC->patOrg.x;
+ yrot = pDrawable->y + pGC->patOrg.y;
+
+ (*fill) (pDrawable, n, ppt, pwidth, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask);
+
+ DEALLOCATE_LOCAL(ppt);
+ DEALLOCATE_LOCAL(pwidth);
+}
+
+/* Fill spans with stipples that aren't 32 bits wide */
+void
+iplUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+DrawablePtr pDrawable;
+GC *pGC;
+int nInit; /* number of spans to fill */
+DDXPointPtr pptInit; /* pointer to list of start points */
+int *pwidthInit; /* pointer to list of n widths */
+int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ int iline; /* first line of tile to use */
+ INTER_DECLAREG(*addrgBase); /* pointer to start of bitmap */
+ int ngwidth; /* width in groups of bitmap */
+ INTER_DECLAREG(*pdst); /* pointer to current group in bitmap */
+ PixmapPtr pStipple; /* pointer to stipple we want to fill with */
+ register int w;
+ int width, x, xrem, xSrc, ySrc;
+ INTER_DECLAREGP(tmpSrc);
+ INTER_DECLAREGP(tmpDst1);
+ INTER_DECLAREGP(tmpDst2);
+ int stwidth, stippleWidth;
+ unsigned long *psrcS;
+ int rop, stiprop;
+ int stippleHeight;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ INTER_DECLARERRAXP(bgfill);
+ INTER_DECLARERRAXP(fgfill);
+
+ if (!(pGC->planemask))
+ return;
+
+ n = nInit * miFindMaxBand( iplGetCompositeClip(pGC) );
+ if ( n == 0 )
+ return;
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans( iplGetCompositeClip(pGC),
+ pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+ rop = pGC->alu;
+ if (pGC->fillStyle == FillStippled) {
+ switch (rop) {
+ case GXand:
+ case GXcopy:
+ case GXnoop:
+ case GXor:
+ stiprop = rop;
+ break;
+ default:
+ stiprop = rop;
+ rop = GXcopy;
+ }
+ }
+ INTER_PFILL(pGC->fgPixel, fgfill);
+ INTER_PFILL(pGC->bgPixel, bgfill);
+
+ /*
+ * OK, so what's going on here? We have two Drawables:
+ *
+ * The Stipple:
+ * Depth = 1
+ * Width = stippleWidth
+ * Words per scanline = stwidth
+ * Pointer to pixels = pStipple->devPrivate.ptr
+ */
+ pStipple = pGC->stipple;
+
+ stwidth = pStipple->devKind / MFB_PGSZB;
+ stippleWidth = pStipple->drawable.width;
+ stippleHeight = pStipple->drawable.height;
+
+ /*
+ * The Target:
+ * Depth = INTER_PLANES
+ * Width = determined from *pwidth
+ * Groups per scanline = ngwidth
+ * Pointer to pixels = addrgBase
+ */
+
+ iplGetGroupWidthAndPointer (pDrawable, ngwidth, addrgBase)
+
+ /* this replaces rotating the stipple. Instead we just adjust the offset
+ * at which we start grabbing bits from the stipple.
+ * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
+ * so that iline and xrem always stay within the stipple bounds.
+ */
+ modulus (pGC->patOrg.x, stippleWidth, xSrc);
+ xSrc += pDrawable->x - stippleWidth;
+ modulus (pGC->patOrg.y, stippleHeight, ySrc);
+ ySrc += pDrawable->y - stippleHeight;
+
+ while (n--)
+ {
+ iline = (ppt->y - ySrc) % stippleHeight;
+ x = ppt->x;
+ pdst = addrgBase + (ppt->y * ngwidth);
+ psrcS = (unsigned long *) pStipple->devPrivate.ptr + (iline * stwidth);
+
+ if (*pwidth)
+ {
+ width = *pwidth;
+ while(width > 0)
+ {
+ int xtemp, tmpx;
+ register unsigned long *ptemp;
+ INTER_DECLAREG(*pdsttmp);
+ /*
+ * Do a stripe through the stipple & destination w pixels
+ * wide. w is not more than:
+ * - the width of the destination
+ * - the width of the stipple
+ * - the distance between x and the next word
+ * boundary in the destination
+ * - the distance between x and the next word
+ * boundary in the stipple
+ */
+
+ /* width of dest/stipple */
+ xrem = (x - xSrc) % stippleWidth;
+ w = min((stippleWidth - xrem), width);
+ /* dist to word bound in dest */
+ w = min(w, INTER_PPG - (x & INTER_PIM));
+ /* dist to word bound in stip */
+ w = min(w, MFB_PPW - (x & MFB_PIM));
+
+ xtemp = (xrem & MFB_PIM);
+ ptemp = (unsigned long *)(psrcS + (xrem >> MFB_PWSH));
+ tmpx = x & INTER_PIM;
+ pdsttmp = pdst + (x >> INTER_PGSH) * INTER_PLANES;
+ switch ( pGC->fillStyle ) {
+ case FillOpaqueStippled:
+ INTER_getstipplepixelsb(ptemp,xtemp,w,bgfill,fgfill,
+ tmpDst1);
+ INTER_putbitsrop(tmpDst1, tmpx, w, pdsttmp,
+ pGC->planemask, rop);
+ break;
+ case FillStippled:
+ /* Fill tmpSrc with the source pixels */
+ INTER_getbits(pdsttmp, tmpx, w, tmpSrc);
+ INTER_getstipplepixels(ptemp, xtemp, w, 0, tmpSrc,
+ tmpDst1);
+ if (rop != stiprop) {
+ INTER_putbitsrop(fgfill, 0, w, tmpSrc, pGC->planemask, stiprop);
+ } else {
+ INTER_COPY(fgfill, tmpSrc);
+ }
+ INTER_getstipplepixels(ptemp, xtemp, w, 1, tmpSrc, tmpDst2);
+ INTER_OR(tmpDst1,tmpDst2,tmpDst2);
+ INTER_putbitsrop(tmpDst2, tmpx, w, pdsttmp,
+ pGC->planemask, rop);
+ }
+ x += w;
+ width -= w;
+ }
+ }
+ ppt++;
+ pwidth++;
+ }
+
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
diff --git a/xc/programs/Xserver/iplan2p4/iplgc.c b/xc/programs/Xserver/iplan2p4/iplgc.c
new file mode 100644
index 000000000..794a62609
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplgc.c
@@ -0,0 +1,782 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplgc.c,v 3.1 1998/03/20 21:08:08 hohndel Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* $XConsortium: iplgc.c,v 5.62 94/04/17 20:28:49 dpw Exp $ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "ipl.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "region.h"
+
+#include "mistruct.h"
+#include "mibstore.h"
+#include "migc.h"
+
+#include "iplmskbits.h"
+
+# ifdef WriteBitGroup
+# define useTEGlyphBlt iplImageGlyphBlt8
+# else
+# define useTEGlyphBlt iplTEGlyphBlt
+# endif
+
+#ifdef WriteBitGroup
+# define useImageGlyphBlt iplImageGlyphBlt8
+# define usePolyGlyphBlt iplPolyGlyphBlt8
+#else
+# define useImageGlyphBlt miImageGlyphBlt
+# define usePolyGlyphBlt miPolyGlyphBlt
+#endif
+
+#ifdef FOUR_BIT_CODE
+# define usePushPixels iplPushPixels8
+#else
+# define usePushPixels mfbPushPixels
+#endif
+
+#ifdef PIXEL_ADDR
+# define ZeroPolyArc iplZeroPolyArcSS8Copy
+#else
+# define ZeroPolyArc miZeroPolyArc
+#endif
+
+GCFuncs iplGCFuncs = {
+ iplValidateGC,
+ miChangeGC,
+ miCopyGC,
+ miDestroyGC,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip,
+};
+
+GCOps iplTEOps1Rect = {
+ iplSolidSpansCopy,
+ iplSetSpans,
+ iplPutImage,
+ iplCopyArea,
+ iplCopyPlane,
+ iplPolyPoint,
+#ifdef PIXEL_ADDR
+ ipl8LineSS1Rect,
+ ipl8SegmentSS1Rect,
+#else
+ iplLineSS,
+ iplSegmentSS,
+#endif
+ miPolyRectangle,
+ ZeroPolyArc,
+ iplFillPoly1RectCopy,
+ iplPolyFillRect,
+ iplPolyFillArcSolidCopy,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ useTEGlyphBlt,
+ usePolyGlyphBlt,
+ usePushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+GCOps iplNonTEOps1Rect = {
+ iplSolidSpansCopy,
+ iplSetSpans,
+ iplPutImage,
+ iplCopyArea,
+ iplCopyPlane,
+ iplPolyPoint,
+#ifdef PIXEL_ADDR
+ ipl8LineSS1Rect,
+ ipl8SegmentSS1Rect,
+#else
+ iplLineSS,
+ iplSegmentSS,
+#endif
+ miPolyRectangle,
+ ZeroPolyArc,
+ iplFillPoly1RectCopy,
+ iplPolyFillRect,
+ iplPolyFillArcSolidCopy,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ useImageGlyphBlt,
+ usePolyGlyphBlt,
+ usePushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+GCOps iplTEOps = {
+ iplSolidSpansCopy,
+ iplSetSpans,
+ iplPutImage,
+ iplCopyArea,
+ iplCopyPlane,
+ iplPolyPoint,
+ iplLineSS,
+ iplSegmentSS,
+ miPolyRectangle,
+ ZeroPolyArc,
+ miFillPolygon,
+ iplPolyFillRect,
+ iplPolyFillArcSolidCopy,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ useTEGlyphBlt,
+ usePolyGlyphBlt,
+ usePushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+GCOps iplNonTEOps = {
+ iplSolidSpansCopy,
+ iplSetSpans,
+ iplPutImage,
+ iplCopyArea,
+ iplCopyPlane,
+ iplPolyPoint,
+ iplLineSS,
+ iplSegmentSS,
+ miPolyRectangle,
+#ifdef PIXEL_ADDR
+ iplZeroPolyArcSS8Copy,
+#else
+ miZeroPolyArc,
+#endif
+ miFillPolygon,
+ iplPolyFillRect,
+ iplPolyFillArcSolidCopy,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ useImageGlyphBlt,
+ usePolyGlyphBlt,
+ usePushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+GCOps *
+iplMatchCommon (pGC, devPriv)
+ GCPtr pGC;
+ iplPrivGCPtr devPriv;
+{
+ if (pGC->lineWidth != 0)
+ return 0;
+ if (pGC->lineStyle != LineSolid)
+ return 0;
+ if (pGC->fillStyle != FillSolid)
+ return 0;
+ if (devPriv->rop != GXcopy)
+ return 0;
+ if (pGC->font &&
+ FONTMAXBOUNDS(pGC->font,rightSideBearing) -
+ FONTMINBOUNDS(pGC->font,leftSideBearing) <= 32 &&
+ FONTMINBOUNDS(pGC->font,characterWidth) >= 0)
+ {
+ if (TERMINALFONT(pGC->font)
+#ifdef FOUR_BIT_CODE
+ && FONTMAXBOUNDS(pGC->font,characterWidth) >= PGSZB
+#endif
+ )
+#ifdef NO_ONE_RECT
+ return &iplTEOps1Rect;
+#else
+ if (devPriv->oneRect)
+ return &iplTEOps1Rect;
+ else
+ return &iplTEOps;
+#endif
+ else
+#ifdef NO_ONE_RECT
+ return &iplNonTEOps1Rect;
+#else
+ if (devPriv->oneRect)
+ return &iplNonTEOps1Rect;
+ else
+ return &iplNonTEOps;
+#endif
+ }
+ return 0;
+}
+
+Bool
+iplCreateGC(pGC)
+ register GCPtr pGC;
+{
+ iplPrivGC *pPriv;
+
+ if (PixmapWidthPaddingInfo[pGC->depth].padPixelsLog2 == LOG2_BITMAP_PAD)
+ return (mfbCreateGC(pGC));
+ pGC->clientClip = NULL;
+ pGC->clientClipType = CT_NONE;
+
+ /*
+ * some of the output primitives aren't really necessary, since they
+ * will be filled in ValidateGC because of dix/CreateGC() setting all
+ * the change bits. Others are necessary because although they depend
+ * on being a color frame buffer, they don't change
+ */
+
+ pGC->ops = &iplNonTEOps;
+ pGC->funcs = &iplGCFuncs;
+
+ /* ipl wants to translate before scan conversion */
+ pGC->miTranslate = 1;
+
+ pPriv = iplGetGCPrivate(pGC);
+ pPriv->rop = pGC->alu;
+ pPriv->oneRect = FALSE;
+ pGC->fExpose = TRUE;
+ pGC->freeCompClip = FALSE;
+ pGC->pRotatedPixmap = (PixmapPtr) NULL;
+ return TRUE;
+}
+
+/* Clipping conventions
+ if the drawable is a window
+ CT_REGION ==> pCompositeClip really is the composite
+ CT_other ==> pCompositeClip is the window clip region
+ if the drawable is a pixmap
+ CT_REGION ==> pCompositeClip is the translated client region
+ clipped to the pixmap boundary
+ CT_other ==> pCompositeClip is the pixmap bounding box
+*/
+
+void
+iplValidateGC(pGC, changes, pDrawable)
+ register GCPtr pGC;
+ unsigned long changes;
+ DrawablePtr pDrawable;
+{
+ int mask; /* stateChanges */
+ int index; /* used for stepping through bitfields */
+ int new_rrop;
+ int new_line, new_text, new_fillspans, new_fillarea;
+ int new_rotate;
+ int xrot, yrot;
+ /* flags for changing the proc vector */
+ iplPrivGCPtr devPriv;
+ int oneRect;
+
+ new_rotate = pGC->lastWinOrg.x != pDrawable->x ||
+ pGC->lastWinOrg.y != pDrawable->y;
+
+ pGC->lastWinOrg.x = pDrawable->x;
+ pGC->lastWinOrg.y = pDrawable->y;
+ devPriv = iplGetGCPrivate(pGC);
+
+ new_rrop = FALSE;
+ new_line = FALSE;
+ new_text = FALSE;
+ new_fillspans = FALSE;
+ new_fillarea = FALSE;
+
+ /*
+ * if the client clip is different or moved OR the subwindowMode has
+ * changed OR the window's clip has changed since the last validation
+ * we need to recompute the composite clip
+ */
+
+ if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
+ (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
+ )
+ {
+ miComputeCompositeClip (pGC, pDrawable);
+#ifdef NO_ONE_RECT
+ devPriv->oneRect = FALSE;
+#else
+ oneRect = REGION_NUM_RECTS(pGC->pCompositeClip) == 1;
+ if (oneRect != devPriv->oneRect)
+ new_line = TRUE;
+ devPriv->oneRect = oneRect;
+#endif
+ }
+
+ mask = changes;
+ while (mask) {
+ index = lowbit (mask);
+ mask &= ~index;
+
+ /*
+ * this switch acculmulates a list of which procedures might have
+ * to change due to changes in the GC. in some cases (e.g.
+ * changing one 16 bit tile for another) we might not really need
+ * a change, but the code is being paranoid. this sort of batching
+ * wins if, for example, the alu and the font have been changed,
+ * or any other pair of items that both change the same thing.
+ */
+ switch (index) {
+ case GCFunction:
+ case GCForeground:
+ new_rrop = TRUE;
+ break;
+ case GCPlaneMask:
+ new_rrop = TRUE;
+ new_text = TRUE;
+ break;
+ case GCBackground:
+ break;
+ case GCLineStyle:
+ case GCLineWidth:
+ new_line = TRUE;
+ break;
+ case GCJoinStyle:
+ case GCCapStyle:
+ break;
+ case GCFillStyle:
+ new_text = TRUE;
+ new_fillspans = TRUE;
+ new_line = TRUE;
+ new_fillarea = TRUE;
+ break;
+ case GCFillRule:
+ break;
+ case GCTile:
+ new_fillspans = TRUE;
+ new_fillarea = TRUE;
+ break;
+
+ case GCStipple:
+ if (pGC->stipple)
+ {
+ int width = pGC->stipple->drawable.width;
+ PixmapPtr nstipple;
+
+ if ((width <= INTER_PGSZ) && !(width & (width - 1)) &&
+ (nstipple = iplCopyPixmap(pGC->stipple)))
+ {
+ iplPadPixmap(nstipple);
+ (*pGC->pScreen->DestroyPixmap)(pGC->stipple);
+ pGC->stipple = nstipple;
+ }
+ }
+ new_fillspans = TRUE;
+ new_fillarea = TRUE;
+ break;
+
+ case GCTileStipXOrigin:
+ new_rotate = TRUE;
+ break;
+
+ case GCTileStipYOrigin:
+ new_rotate = TRUE;
+ break;
+
+ case GCFont:
+ new_text = TRUE;
+ break;
+ case GCSubwindowMode:
+ break;
+ case GCGraphicsExposures:
+ break;
+ case GCClipXOrigin:
+ break;
+ case GCClipYOrigin:
+ break;
+ case GCClipMask:
+ break;
+ case GCDashOffset:
+ break;
+ case GCDashList:
+ break;
+ case GCArcMode:
+ break;
+ default:
+ break;
+ }
+ }
+
+ /*
+ * If the drawable has changed, ensure suitable
+ * entries are in the proc vector.
+ */
+ if (pDrawable->serialNumber != (pGC->serialNumber & (DRAWABLE_SERIAL_BITS))) {
+ new_fillspans = TRUE; /* deal with FillSpans later */
+ }
+
+ if (new_rotate || new_fillspans)
+ {
+ Bool new_pix = FALSE;
+
+ xrot = pGC->patOrg.x + pDrawable->x;
+ yrot = pGC->patOrg.y + pDrawable->y;
+
+ switch (pGC->fillStyle)
+ {
+ case FillTiled:
+ if (!pGC->tileIsPixel)
+ {
+ int width = pGC->tile.pixmap->drawable.width;
+
+ if ((width <= INTER_PGSZ) && !(width & (width - 1)))
+ {
+ iplCopyRotatePixmap(pGC->tile.pixmap,
+ &pGC->pRotatedPixmap,
+ xrot, yrot);
+ new_pix = TRUE;
+ }
+ }
+ break;
+#ifdef FOUR_BIT_CODE
+ case FillStippled:
+ case FillOpaqueStippled:
+ {
+ int width = pGC->stipple->drawable.width;
+
+ if ((width <= INTER_PGSZ) && !(width & (width - 1)))
+ {
+ mfbCopyRotatePixmap(pGC->stipple,
+ &pGC->pRotatedPixmap, xrot, yrot);
+ new_pix = TRUE;
+ }
+ }
+ break;
+#endif
+ }
+ if (!new_pix && pGC->pRotatedPixmap)
+ {
+ (*pGC->pScreen->DestroyPixmap)(pGC->pRotatedPixmap);
+ pGC->pRotatedPixmap = (PixmapPtr) NULL;
+ }
+ }
+
+ if (new_rrop)
+ {
+ int old_rrop;
+
+ old_rrop = devPriv->rop;
+ devPriv->rop = iplReduceRasterOp(pGC->alu, pGC->fgPixel,
+ pGC->planemask, devPriv->andg, devPriv->xorg);
+ if (old_rrop == devPriv->rop)
+ new_rrop = FALSE;
+ else
+ {
+#ifdef PIXEL_ADDR
+ new_line = TRUE;
+#endif
+#ifdef WriteBitGroup
+ new_text = TRUE;
+#endif
+ new_fillspans = TRUE;
+ new_fillarea = TRUE;
+ }
+ }
+
+ if (new_rrop || new_fillspans || new_text || new_fillarea || new_line)
+ {
+ GCOps *newops;
+
+ if (newops = iplMatchCommon (pGC, devPriv))
+ {
+ if (pGC->ops->devPrivate.val)
+ miDestroyGCOps (pGC->ops);
+ pGC->ops = newops;
+ new_rrop = new_line = new_fillspans = new_text = new_fillarea = 0;
+ }
+ else
+ {
+ if (!pGC->ops->devPrivate.val)
+ {
+ pGC->ops = miCreateGCOps (pGC->ops);
+ pGC->ops->devPrivate.val = 1;
+ }
+ }
+ }
+
+ /* deal with the changes we've collected */
+ if (new_line)
+ {
+ pGC->ops->FillPolygon = miFillPolygon;
+#ifdef NO_ONE_RECT
+ if (pGC->fillStyle == FillSolid)
+ {
+ switch (devPriv->rop) {
+ case GXcopy:
+ pGC->ops->FillPolygon = iplFillPoly1RectCopy;
+ break;
+ default:
+ pGC->ops->FillPolygon = iplFillPoly1RectGeneral;
+ break;
+ }
+ }
+#else
+ if (devPriv->oneRect && pGC->fillStyle == FillSolid)
+ {
+ switch (devPriv->rop) {
+ case GXcopy:
+ pGC->ops->FillPolygon = iplFillPoly1RectCopy;
+ break;
+ default:
+ pGC->ops->FillPolygon = iplFillPoly1RectGeneral;
+ break;
+ }
+ }
+#endif
+ if (pGC->lineWidth == 0)
+ {
+#ifdef PIXEL_ADDR
+ if ((pGC->lineStyle == LineSolid) && (pGC->fillStyle == FillSolid))
+ {
+ switch (devPriv->rop)
+ {
+ case GXxor:
+ pGC->ops->PolyArc = iplZeroPolyArcSS8Xor;
+ break;
+ case GXcopy:
+ pGC->ops->PolyArc = iplZeroPolyArcSS8Copy;
+ break;
+ default:
+ pGC->ops->PolyArc = iplZeroPolyArcSS8General;
+ break;
+ }
+ }
+ else
+#endif
+ pGC->ops->PolyArc = miZeroPolyArc;
+ }
+ else
+ pGC->ops->PolyArc = miPolyArc;
+ pGC->ops->PolySegment = miPolySegment;
+ switch (pGC->lineStyle)
+ {
+ case LineSolid:
+ if(pGC->lineWidth == 0)
+ {
+ if (pGC->fillStyle == FillSolid)
+ {
+#if defined(PIXEL_ADDR) && !defined(NO_ONE_RECT)
+ if (devPriv->oneRect &&
+ ((pDrawable->x >= pGC->pScreen->width - 32768) &&
+ (pDrawable->y >= pGC->pScreen->height - 32768)))
+ {
+ pGC->ops->Polylines = ipl8LineSS1Rect;
+ pGC->ops->PolySegment = ipl8SegmentSS1Rect;
+ } else
+#endif
+#ifdef NO_ONE_RECT
+ {
+ pGC->ops->Polylines = ipl8LineSS1Rect;
+ pGC->ops->PolySegment = ipl8SegmentSS1Rect;
+ }
+#else
+ {
+ pGC->ops->Polylines = iplLineSS;
+ pGC->ops->PolySegment = iplSegmentSS;
+ }
+#endif
+ }
+ else
+ pGC->ops->Polylines = miZeroLine;
+ }
+ else
+ pGC->ops->Polylines = miWideLine;
+ break;
+ case LineOnOffDash:
+ case LineDoubleDash:
+ if (pGC->lineWidth == 0 && pGC->fillStyle == FillSolid)
+ {
+ pGC->ops->Polylines = iplLineSD;
+ pGC->ops->PolySegment = iplSegmentSD;
+ } else
+ pGC->ops->Polylines = miWideDash;
+ break;
+ }
+ }
+
+ if (new_text && (pGC->font))
+ {
+ if (FONTMAXBOUNDS(pGC->font,rightSideBearing) -
+ FONTMINBOUNDS(pGC->font,leftSideBearing) > 32 ||
+ FONTMINBOUNDS(pGC->font,characterWidth) < 0)
+ {
+ pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
+ pGC->ops->ImageGlyphBlt = miImageGlyphBlt;
+ }
+ else
+ {
+#ifdef WriteBitGroup
+ if (pGC->fillStyle == FillSolid)
+ {
+ if (devPriv->rop == GXcopy)
+ pGC->ops->PolyGlyphBlt = iplPolyGlyphBlt8;
+ else
+#ifdef FOUR_BIT_CODE
+ pGC->ops->PolyGlyphBlt = iplPolyGlyphRop8;
+#else
+ pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
+#endif
+ }
+ else
+#endif
+ pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
+ /* special case ImageGlyphBlt for terminal emulator fonts */
+#if !defined(WriteBitGroup)
+ if (TERMINALFONT(pGC->font) &&
+ (pGC->planemask & INTER_PMSK) == INTER_PMSK
+#ifdef FOUR_BIT_CODE
+ && FONTMAXBOUNDS(pGC->font,characterWidth) >= PGSZB
+#endif
+ )
+ {
+ pGC->ops->ImageGlyphBlt = useTEGlyphBlt;
+ }
+ else
+#endif
+ {
+#ifdef WriteBitGroup
+ if (devPriv->rop == GXcopy &&
+ pGC->fillStyle == FillSolid &&
+ (pGC->planemask & INTER_PMSK) == INTER_PMSK)
+ pGC->ops->ImageGlyphBlt = iplImageGlyphBlt8;
+ else
+#endif
+ pGC->ops->ImageGlyphBlt = miImageGlyphBlt;
+ }
+ }
+ }
+
+
+ if (new_fillspans) {
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ switch (devPriv->rop) {
+ case GXcopy:
+ pGC->ops->FillSpans = iplSolidSpansCopy;
+ break;
+ case GXxor:
+ pGC->ops->FillSpans = iplSolidSpansXor;
+ break;
+ default:
+ pGC->ops->FillSpans = iplSolidSpansGeneral;
+ break;
+ }
+ break;
+ case FillTiled:
+ if (pGC->pRotatedPixmap)
+ {
+ if (pGC->alu == GXcopy && (pGC->planemask & INTER_PMSK) == INTER_PMSK)
+ pGC->ops->FillSpans = iplTile32FSCopy;
+ else
+ pGC->ops->FillSpans = iplTile32FSGeneral;
+ }
+ else
+ pGC->ops->FillSpans = iplUnnaturalTileFS;
+ break;
+ case FillStippled:
+#ifdef FOUR_BIT_CODE
+ if (pGC->pRotatedPixmap)
+ pGC->ops->FillSpans = ipl8Stipple32FS;
+ else
+#endif
+ pGC->ops->FillSpans = iplUnnaturalStippleFS;
+ break;
+ case FillOpaqueStippled:
+#ifdef FOUR_BIT_CODE
+ if (pGC->pRotatedPixmap)
+ pGC->ops->FillSpans = ipl8OpaqueStipple32FS;
+ else
+#endif
+ pGC->ops->FillSpans = iplUnnaturalStippleFS;
+ break;
+ default:
+ FatalError("iplValidateGC: illegal fillStyle\n");
+ }
+ } /* end of new_fillspans */
+
+ if (new_fillarea) {
+#ifndef FOUR_BIT_CODE
+ pGC->ops->PolyFillRect = miPolyFillRect;
+ if (pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled)
+ {
+ pGC->ops->PolyFillRect = iplPolyFillRect;
+ }
+#endif
+#ifdef FOUR_BIT_CODE
+ pGC->ops->PushPixels = mfbPushPixels;
+ if (pGC->fillStyle == FillSolid && devPriv->rop == GXcopy)
+ pGC->ops->PushPixels = iplPushPixels8;
+#endif
+ pGC->ops->PolyFillArc = miPolyFillArc;
+ if (pGC->fillStyle == FillSolid)
+ {
+ switch (devPriv->rop)
+ {
+ case GXcopy:
+ pGC->ops->PolyFillArc = iplPolyFillArcSolidCopy;
+ break;
+ default:
+ pGC->ops->PolyFillArc = iplPolyFillArcSolidGeneral;
+ break;
+ }
+ }
+ }
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplgetsp.c b/xc/programs/Xserver/iplan2p4/iplgetsp.c
new file mode 100644
index 000000000..271656bda
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplgetsp.c
@@ -0,0 +1,162 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplgetsp.c,v 3.0 1996/08/18 01:54:47 dawes Exp $ */
+/* $XConsortium: iplgetsp.c,v 5.14 94/04/17 20:28:50 dpw Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "servermd.h"
+
+#include "misc.h"
+#include "region.h"
+#include "gc.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+#include "ipl.h"
+#include "iplmskbits.h"
+#include "iplpack.h"
+
+/* GetSpans -- for each span, gets bits from drawable starting at ppt[i]
+ * and continuing for pwidth[i] bits
+ * Each scanline returned will be server scanline padded, i.e., it will come
+ * out to an integral number of words.
+ */
+void
+iplGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pchardstStart)
+ DrawablePtr pDrawable; /* drawable from which to get bits */
+ int wMax; /* largest value of all *pwidths */
+ register DDXPointPtr ppt; /* points to start copying from */
+ int *pwidth; /* list of number of bits to copy */
+ int nspans; /* number of scanlines to copy */
+ char *pchardstStart; /* where to put the bits */
+{
+ unsigned long *pdst = (unsigned long *)pchardstStart;
+ INTER_DECLAREG(*psrc); /* where to get the bits */
+ INTER_DECLAREGP(tmpSrc); /* scratch buffer for bits */
+ INTER_DECLAREG(*psrcBase); /* start of src bitmap */
+ int widthSrc; /* width of pixmap in bytes */
+ register DDXPointPtr pptLast; /* one past last point to get */
+ int xEnd; /* last pixel to copy from */
+ register int nstart;
+ int nend;
+ INTER_DECLAREG(startmask);
+ INTER_DECLAREG(endmask);
+ int nlMiddle, nl, srcBit;
+ int w,longs;
+ INTER_DECLAREG(*tmppdst);
+ INTER_DECLAREG(*ipdst);
+
+ switch (pDrawable->bitsPerPixel) {
+ case 1:
+ mfbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pchardstStart);
+ return;
+ case INTER_PLANES:
+ break;
+ default:
+ FatalError("iplGetSpans: invalid depth\n");
+ }
+
+ longs = NUM_LONGS(INTER_PLANES, 0, wMax);
+ tmppdst = (unsigned short *)
+ ALLOCATE_LOCAL(NUM_TEMP_BYTES(INTER_PLANES, longs));
+ iplGetGroupWidthAndPointer (pDrawable, widthSrc, psrcBase)
+
+ pptLast = ppt + nspans;
+ while(ppt < pptLast)
+ {
+ xEnd = min(ppt->x + *pwidth, (widthSrc / INTER_PLANES) << INTER_PGSH);
+ psrc = psrcBase + ppt->y * widthSrc +
+ (ppt->x >> INTER_PGSH) * INTER_PLANES;
+ w = xEnd - ppt->x;
+ srcBit = ppt->x & INTER_PIM;
+ ipdst = tmppdst;
+
+ if (srcBit + w <= INTER_PPG)
+ {
+ INTER_getbits(psrc, srcBit, w, tmpSrc);
+ INTER_putbits(tmpSrc, 0, w, ipdst, ~((unsigned long)0));
+ }
+ else
+ {
+ INTER_maskbits(ppt->x, w, startmask, endmask, nlMiddle);
+ nstart = 0;
+ if (startmask)
+ {
+ nstart = INTER_PPG - srcBit;
+ INTER_getbits(psrc, srcBit, nstart, tmpSrc);
+ INTER_putbits(tmpSrc, 0, nstart, ipdst, ~((unsigned long)0));
+ if(srcBit + nstart >= INTER_PPG)
+ INTER_NEXT_GROUP(psrc);
+ }
+ nl = nlMiddle;
+ while (nl--)
+ {
+ INTER_putbits(psrc, nstart, INTER_PPG, ipdst, ~((unsigned long)0));
+ INTER_NEXT_GROUP(psrc);
+ INTER_NEXT_GROUP(ipdst);
+ }
+ if (endmask)
+ {
+ nend = xEnd & INTER_PIM;
+ INTER_getbits(psrc, 0, nend, tmpSrc);
+ INTER_putbits(tmpSrc, nstart, nend, ipdst, ~((unsigned long)0));
+ }
+ }
+ longs=(w * INTER_PLANES + 31)/32;
+ iplPackLine(INTER_PLANES, longs, tmppdst, pdst);
+ pdst+=longs;
+ ppt++;
+ pwidth++;
+ }
+ DEALLOCATE_LOCAL(tmppdst);
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplhrzvert.c b/xc/programs/Xserver/iplan2p4/iplhrzvert.c
new file mode 100644
index 000000000..6374e4d19
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplhrzvert.c
@@ -0,0 +1,124 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplhrzvert.c,v 3.0 1996/08/18 01:54:48 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: iplhrzvert.c,v 1.8 94/04/17 20:28:51 dpw Exp $ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+
+#include "gc.h"
+#include "window.h"
+#include "pixmap.h"
+#include "region.h"
+
+#include "ipl.h"
+
+#include "iplmskbits.h"
+
+/* horizontal solid line
+ abs(len) > 1
+*/
+iplHorzS(rop, andp, xorp, addrg, ngwidth, x1, y1, len)
+register int rop;
+INTER_DECLARERRAX(andp);
+INTER_DECLARERRAX(xorp);
+INTER_DECLAREG(*addrg); /* pointer to base of bitmap */
+int ngwidth; /* width in groups of bitmap */
+int x1; /* initial point */
+int y1;
+int len; /* length of line */
+{
+ register int ngmiddle;
+ INTER_DECLAREG(startmask);
+ INTER_DECLAREG(endmask);
+
+ addrg = addrg + y1 * ngwidth + (x1 >> INTER_PGSH) * INTER_PLANES;
+ /* all bits inside same group */
+ if ( ((x1 & INTER_PIM) + len) < INTER_PPG)
+ {
+ INTER_maskpartialbits(x1, len, startmask);
+ INTER_DoMaskRRop(addrg, andp, xorp, startmask, addrg);
+ }
+ else
+ {
+ INTER_maskbits(x1, len, startmask, endmask, ngmiddle);
+ if (startmask)
+ {
+ INTER_DoMaskRRop(addrg, andp, xorp, startmask, addrg);
+ addrg += INTER_PLANES;
+ }
+ while (ngmiddle--)
+ {
+ INTER_DoRRop(addrg, andp, xorp, addrg);
+ addrg += INTER_PLANES;
+ }
+ if (endmask)
+ INTER_DoMaskRRop(addrg, andp, xorp, endmask, addrg);
+ }
+}
+
+/* vertical solid line */
+
+iplVertS(rop, andp, xorp, addrg, ngwidth, x1, y1, len)
+int rop;
+INTER_DECLARERRAX(andp);
+INTER_DECLARERRAX(xorp);
+INTER_DECLAREG(*addrg); /* pointer to base of bitmap */
+register int ngwidth; /* width in groups of bitmap */
+int x1, y1; /* initial point */
+register int len; /* length of line */
+{
+ addrg = addrg + (y1 * ngwidth) + (x1 >> INTER_PGSH) * INTER_PLANES;
+ while (len--)
+ {
+ INTER_DoMaskRRop(addrg, andp, xorp, iplmask[x1 & INTER_PIM], addrg);
+ addrg += ngwidth;
+ }
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplimage.c b/xc/programs/Xserver/iplan2p4/iplimage.c
new file mode 100644
index 000000000..0522309b4
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplimage.c
@@ -0,0 +1,83 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplimage.c,v 3.0 1996/08/18 01:54:49 dawes Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: iplimage.c,v 1.18 94/04/17 20:28:52 dpw Exp $ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "ipl.h"
+#include "servermd.h"
+
+void
+iplPutImage(pDraw, pGC, depth, x, y, w, h, leftPad, format, pImage)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int depth, x, y, w, h;
+ int leftPad;
+ int format;
+ char *pImage;
+{
+ miPutImage(pDraw, pGC, depth, x, y, w, h, leftPad, format, pImage);
+}
+
+void
+iplGetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine)
+ DrawablePtr pDrawable;
+ int sx, sy, w, h;
+ unsigned int format;
+ unsigned long planeMask;
+ char *pdstLine;
+{
+ miGetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplline.c b/xc/programs/Xserver/iplan2p4/iplline.c
new file mode 100644
index 000000000..479bfb00a
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplline.c
@@ -0,0 +1,754 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplline.c,v 3.1 1998/03/20 21:08:08 hohndel Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: iplline.c,v 1.23 94/04/17 20:28:53 dpw Exp $ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "mistruct.h"
+
+#include "ipl.h"
+#include "miline.h"
+
+#include "iplmskbits.h"
+
+/* single-pixel lines on a color frame buffer
+
+ NON-SLOPED LINES
+ horizontal lines are always drawn left to right; we have to
+move the endpoints right by one after they're swapped.
+ horizontal lines will be confined to a single band of a
+region. the code finds that band (giving up if the lower
+bound of the band is above the line we're drawing); then it
+finds the first box in that band that contains part of the
+line. we clip the line to subsequent boxes in that band.
+ vertical lines are always drawn top to bottom (y-increasing.)
+this requires adding one to the y-coordinate of each endpoint
+after swapping.
+
+ SLOPED LINES
+ when clipping a sloped line, we bring the second point inside
+the clipping box, rather than one beyond it, and then add 1 to
+the length of the line before drawing it. this lets us use
+the same box for finding the outcodes for both endpoints. since
+the equation for clipping the second endpoint to an edge gives us
+1 beyond the edge, we then have to move the point towards the
+first point by one step on the major axis.
+ eventually, there will be a diagram here to explain what's going
+on. the method uses Cohen-Sutherland outcodes to determine
+outsideness, and a method similar to Pike's layers for doing the
+actual clipping.
+
+*/
+
+void
+#ifdef POLYSEGMENT
+iplSegmentSS (pDrawable, pGC, nseg, pSeg)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nseg;
+ register xSegment *pSeg;
+#else
+iplLineSS (pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt; /* number of points */
+ DDXPointPtr pptInit;
+#endif
+{
+ int nboxInit;
+ register int nbox;
+ BoxPtr pboxInit;
+ register BoxPtr pbox;
+#ifndef POLYSEGMENT
+ register DDXPointPtr ppt; /* pointer to list of translated points */
+#endif
+
+ unsigned int oc1; /* outcode of point 1 */
+ unsigned int oc2; /* outcode of point 2 */
+
+ INTER_DECLAREG(*addrg); /* address of destination pixmap */
+ int ngwidth; /* width in groups of destination pixmap */
+ int xorg, yorg; /* origin of window */
+
+ int adx; /* abs values of dx and dy */
+ int ady;
+ int signdx; /* sign of dx and dy */
+ int signdy;
+ int e, e1, e2; /* bresenham error and increments */
+ int len; /* length of segment */
+ int axis; /* major axis */
+ int octant;
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+
+ /* a bunch of temporaries */
+ int tmp;
+ register int y1, y2;
+ register int x1, x2;
+ RegionPtr cclip;
+ iplPrivGCPtr devPriv;
+ INTER_DECLARERRAX(xor);
+ INTER_DECLARERRAX(and);
+ int alu;
+
+ devPriv = iplGetGCPrivate(pGC);
+ cclip = pGC->pCompositeClip;
+ pboxInit = REGION_RECTS(cclip);
+ nboxInit = REGION_NUM_RECTS(cclip);
+
+ iplGetGroupWidthAndPointer (pDrawable, ngwidth, addrg)
+
+ alu = devPriv->rop;
+ xor = devPriv->xorg;
+ and = devPriv->andg;
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+#ifdef POLYSEGMENT
+ while (nseg--)
+#else
+ ppt = pptInit;
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+ while(--npt)
+#endif
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+
+#ifdef POLYSEGMENT
+ x1 = pSeg->x1 + xorg;
+ y1 = pSeg->y1 + yorg;
+ x2 = pSeg->x2 + xorg;
+ y2 = pSeg->y2 + yorg;
+ pSeg++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious)
+ {
+ xorg = x1;
+ yorg = y1;
+ }
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+#endif
+
+ if (x1 == x2) /* vertical line */
+ {
+ /* make the line go top to bottom of screen, keeping
+ endpoint semantics
+ */
+ if (y1 > y2)
+ {
+ register int tmp;
+
+ tmp = y2;
+ y2 = y1 + 1;
+ y1 = tmp + 1;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ y1--;
+#endif
+ }
+#ifdef POLYSEGMENT
+ else if (pGC->capStyle != CapNotLast)
+ y2++;
+#endif
+ /* get to first band that might contain part of line */
+ while ((nbox) && (pbox->y2 <= y1))
+ {
+ pbox++;
+ nbox--;
+ }
+
+ if (nbox)
+ {
+ /* stop when lower edge of box is beyond end of line */
+ while((nbox) && (y2 >= pbox->y1))
+ {
+ if ((x1 >= pbox->x1) && (x1 < pbox->x2))
+ {
+ int y1t, y2t;
+ /* this box has part of the line in it */
+ y1t = max(y1, pbox->y1);
+ y2t = min(y2, pbox->y2);
+ if (y1t != y2t)
+ {
+ iplVertS (alu, and, xor,
+ addrg, ngwidth,
+ x1, y1t, y2t-y1t);
+ }
+ }
+ nbox--;
+ pbox++;
+ }
+ }
+#ifndef POLYSEGMENT
+ y2 = ppt->y + yorg;
+#endif
+ }
+ else if (y1 == y2) /* horizontal line */
+ {
+ /* force line from left to right, keeping
+ endpoint semantics
+ */
+ if (x1 > x2)
+ {
+ register int tmp;
+
+ tmp = x2;
+ x2 = x1 + 1;
+ x1 = tmp + 1;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ x1--;
+#endif
+ }
+#ifdef POLYSEGMENT
+ else if (pGC->capStyle != CapNotLast)
+ x2++;
+#endif
+
+ /* find the correct band */
+ while( (nbox) && (pbox->y2 <= y1))
+ {
+ pbox++;
+ nbox--;
+ }
+
+ /* try to draw the line, if we haven't gone beyond it */
+ if ((nbox) && (pbox->y1 <= y1))
+ {
+ /* when we leave this band, we're done */
+ tmp = pbox->y1;
+ while((nbox) && (pbox->y1 == tmp))
+ {
+ int x1t, x2t;
+
+ if (pbox->x2 <= x1)
+ {
+ /* skip boxes until one might contain start point */
+ nbox--;
+ pbox++;
+ continue;
+ }
+
+ /* stop if left of box is beyond right of line */
+ if (pbox->x1 >= x2)
+ {
+ nbox = 0;
+ break;
+ }
+
+ x1t = max(x1, pbox->x1);
+ x2t = min(x2, pbox->x2);
+ if (x1t != x2t)
+ {
+ iplHorzS (alu, and, xor,
+ addrg, ngwidth,
+ x1t, y1, x2t-x1t);
+ }
+ nbox--;
+ pbox++;
+ }
+ }
+#ifndef POLYSEGMENT
+ x2 = ppt->x + xorg;
+#endif
+ }
+ else /* sloped line */
+ {
+ CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy,
+ 1, 1, octant);
+
+ if (adx > ady)
+ {
+ axis = X_AXIS;
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ }
+ else
+ {
+ axis = Y_AXIS;
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ SetYMajorOctant(octant);
+ }
+
+ FIXUP_ERROR(e, octant, bias);
+
+ /* we have bresenham parameters and two points.
+ all we have to do now is clip and draw.
+ */
+
+ while(nbox--)
+ {
+ oc1 = 0;
+ oc2 = 0;
+ OUTCODES(oc1, x1, y1, pbox);
+ OUTCODES(oc2, x2, y2, pbox);
+ if ((oc1 | oc2) == 0)
+ {
+ if (axis == X_AXIS)
+ len = adx;
+ else
+ len = ady;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ len++;
+#endif
+ iplBresS (alu, and, xor,
+ addrg, ngwidth,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e2, len);
+ break;
+ }
+ else if (oc1 & oc2)
+ {
+ pbox++;
+ }
+ else
+ {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int clipdx, clipdy;
+ int err;
+
+ if (miZeroClipLine(pbox->x1, pbox->y1, pbox->x2-1,
+ pbox->y2-1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pbox++;
+ continue;
+ }
+
+ if (axis == X_AXIS)
+ len = abs(new_x2 - new_x1);
+ else
+ len = abs(new_y2 - new_y1);
+#ifdef POLYSEGMENT
+ if (clip2 != 0 || pGC->capStyle != CapNotLast)
+ len++;
+#else
+ len += (clip2 != 0);
+#endif
+ if (len)
+ {
+ /* unwind bresenham error term to first point */
+ if (clip1)
+ {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ if (axis == X_AXIS)
+ err = e+((clipdy*e2) + ((clipdx-clipdy)*e1));
+ else
+ err = e+((clipdx*e2) + ((clipdy-clipdx)*e1));
+ }
+ else
+ err = e;
+ iplBresS(alu, and, xor,
+ addrg, ngwidth,
+ signdx, signdy, axis, new_x1, new_y1,
+ err, e1, e2, len);
+ }
+ pbox++;
+ }
+ } /* while (nbox--) */
+ } /* sloped line */
+ } /* while (nline--) */
+
+#ifndef POLYSEGMENT
+ /* paint the last point if the end style isn't CapNotLast.
+ (Assume that a projecting, butt, or round cap that is one
+ pixel wide is the same as the single pixel of the endpoint.)
+ */
+
+ if ((pGC->capStyle != CapNotLast) &&
+ ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
+ (ppt->y + yorg != pptInit->y + pDrawable->y) ||
+ (ppt == pptInit + 1)))
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+ while (nbox--)
+ {
+ if ((x2 >= pbox->x1) &&
+ (y2 >= pbox->y1) &&
+ (x2 < pbox->x2) &&
+ (y2 < pbox->y2))
+ {
+ INTER_DECLAREG(mask);
+ INTER_DECLAREGP(temp);
+
+ mask = iplmask[x2 & INTER_PIM];
+ addrg += (y2 * ngwidth) + (x2 >> INTER_PGSH) * INTER_PLANES;
+
+ INTER_DoRRop(addrg, and, xor, temp);
+ INTER_COPYM(temp, addrg, mask, addrg);
+ break;
+ }
+ else
+ pbox++;
+ }
+ }
+#endif
+}
+
+/*
+ * Draw dashed 1-pixel lines.
+ */
+
+void
+#ifdef POLYSEGMENT
+iplSegmentSD (pDrawable, pGC, nseg, pSeg)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int nseg;
+ register xSegment *pSeg;
+#else
+iplLineSD( pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt; /* number of points */
+ DDXPointPtr pptInit;
+#endif
+{
+ int nboxInit;
+ register int nbox;
+ BoxPtr pboxInit;
+ register BoxPtr pbox;
+#ifndef POLYSEGMENT
+ register DDXPointPtr ppt; /* pointer to list of translated points */
+#endif
+
+ register unsigned int oc1; /* outcode of point 1 */
+ register unsigned int oc2; /* outcode of point 2 */
+
+ INTER_DECLAREG(*addrg); /* address of destination pixmap */
+ int ngwidth; /* width in groups of destination pixmap */
+ int xorg, yorg; /* origin of window */
+
+ int adx; /* abs values of dx and dy */
+ int ady;
+ int signdx; /* sign of dx and dy */
+ int signdy;
+ int e, e1, e2; /* bresenham error and increments */
+ int len; /* length of segment */
+ int axis; /* major axis */
+ int octant;
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ int x1, x2, y1, y2;
+ RegionPtr cclip;
+ iplRRopRec rrops[2];
+ unsigned char *pDash;
+ int dashOffset;
+ int numInDashList;
+ int dashIndex;
+ int isDoubleDash;
+ int dashIndexTmp, dashOffsetTmp;
+ int unclippedlen;
+ iplPrivGCPtr devPriv;
+
+ devPriv = iplGetGCPrivate(pGC);
+ cclip = pGC->pCompositeClip;
+ rrops[0].rop = devPriv->rop;
+ INTER_COPY(devPriv->andg, rrops[0].andg)
+ INTER_COPY(devPriv->xorg, rrops[0].xorg)
+#if 0
+ if (pGC->alu == GXcopy)
+ {
+ rrops[1].rop = GXcopy;
+ rrops[1].and = 0;
+ rrops[1].xor = PFILL (pGC->bgPixel);
+ }
+ else
+#endif
+ {
+ rrops[1].rop = iplReduceRasterOp (pGC->alu,
+ pGC->bgPixel, pGC->planemask,
+ rrops[1].andg, rrops[1].xorg);
+ }
+ pboxInit = REGION_RECTS(cclip);
+ nboxInit = REGION_NUM_RECTS(cclip);
+
+ iplGetGroupWidthAndPointer (pDrawable, ngwidth, addrg)
+
+ /* compute initial dash values */
+
+ pDash = (unsigned char *) pGC->dash;
+ numInDashList = pGC->numInDashList;
+ isDoubleDash = (pGC->lineStyle == LineDoubleDash);
+ dashIndex = 0;
+ dashOffset = 0;
+ miStepDash ((int)pGC->dashOffset, &dashIndex, pDash,
+ numInDashList, &dashOffset);
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+#ifdef POLYSEGMENT
+ while (nseg--)
+#else
+ ppt = pptInit;
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+ while(--npt)
+#endif
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+
+#ifdef POLYSEGMENT
+ x1 = pSeg->x1 + xorg;
+ y1 = pSeg->y1 + yorg;
+ x2 = pSeg->x2 + xorg;
+ y2 = pSeg->y2 + yorg;
+ pSeg++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious)
+ {
+ xorg = x1;
+ yorg = y1;
+ }
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+#endif
+
+ CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);
+
+ if (adx > ady)
+ {
+ axis = X_AXIS;
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ unclippedlen = adx;
+ }
+ else
+ {
+ axis = Y_AXIS;
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ unclippedlen = ady;
+ SetYMajorOctant(octant);
+ }
+
+ FIXUP_ERROR(e, octant, bias);
+
+ /* we have bresenham parameters and two points.
+ all we have to do now is clip and draw.
+ */
+
+ while(nbox--)
+ {
+ oc1 = 0;
+ oc2 = 0;
+ OUTCODES(oc1, x1, y1, pbox);
+ OUTCODES(oc2, x2, y2, pbox);
+ if ((oc1 | oc2) == 0)
+ {
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ unclippedlen++;
+ dashIndexTmp = dashIndex;
+ dashOffsetTmp = dashOffset;
+ iplBresD (rrops,
+ &dashIndexTmp, pDash, numInDashList,
+ &dashOffsetTmp, isDoubleDash,
+ addrg, ngwidth,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e2, unclippedlen);
+ break;
+#else
+ iplBresD (rrops,
+ &dashIndex, pDash, numInDashList,
+ &dashOffset, isDoubleDash,
+ addrg, ngwidth,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e2, unclippedlen);
+ goto dontStep;
+#endif
+ }
+ else if (oc1 & oc2)
+ {
+ pbox++;
+ }
+ else /* have to clip */
+ {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int clipdx, clipdy;
+ int err;
+ int dashIndexTmp, dashOffsetTmp;
+
+ if (miZeroClipLine(pbox->x1, pbox->y1, pbox->x2-1,
+ pbox->y2-1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pbox++;
+ continue;
+ }
+
+ dashIndexTmp = dashIndex;
+ dashOffsetTmp = dashOffset;
+
+ if (clip1)
+ {
+ int dlen;
+
+ if (axis == X_AXIS)
+ dlen = abs(new_x1 - x1);
+ else
+ dlen = abs(new_y1 - y1);
+ miStepDash (dlen, &dashIndexTmp, pDash,
+ numInDashList, &dashOffsetTmp);
+ }
+
+ if (axis == X_AXIS)
+ len = abs(new_x2 - new_x1);
+ else
+ len = abs(new_y2 - new_y1);
+#ifdef POLYSEGMENT
+ if (clip2 != 0 || pGC->capStyle != CapNotLast)
+ len++;
+#else
+ len += (clip2 != 0);
+#endif
+ if (len)
+ {
+ /* unwind bresenham error term to first point */
+ if (clip1)
+ {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ if (axis == X_AXIS)
+ err = e+((clipdy*e2) + ((clipdx-clipdy)*e1));
+ else
+ err = e+((clipdx*e2) + ((clipdy-clipdx)*e1));
+ }
+ else
+ err = e;
+ iplBresD (rrops,
+ &dashIndexTmp, pDash, numInDashList,
+ &dashOffsetTmp, isDoubleDash,
+ addrg, ngwidth,
+ signdx, signdy, axis, new_x1, new_y1,
+ err, e1, e2, len);
+ }
+ pbox++;
+ }
+ } /* while (nbox--) */
+#ifndef POLYSEGMENT
+ /*
+ * walk the dash list around to the next line
+ */
+ miStepDash (unclippedlen, &dashIndex, pDash,
+ numInDashList, &dashOffset);
+dontStep: ;
+#endif
+ } /* while (nline--) */
+
+#ifndef POLYSEGMENT
+ /* paint the last point if the end style isn't CapNotLast.
+ (Assume that a projecting, butt, or round cap that is one
+ pixel wide is the same as the single pixel of the endpoint.)
+ */
+
+ if ((pGC->capStyle != CapNotLast) &&
+ ((dashIndex & 1) == 0 || isDoubleDash) &&
+ ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
+ (ppt->y + yorg != pptInit->y + pDrawable->y) ||
+ (ppt == pptInit + 1)))
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+ while (nbox--)
+ {
+ if ((x2 >= pbox->x1) &&
+ (y2 >= pbox->y1) &&
+ (x2 < pbox->x2) &&
+ (y2 < pbox->y2))
+ {
+ INTER_DECLAREG(mask);
+ int pix;
+
+ pix = 0;
+ if (dashIndex & 1)
+ pix = 1;
+ mask = iplmask[x2 & INTER_PIM];
+ addrg += (y2 * ngwidth) + (x2 >> INTER_PGSH) * INTER_PLANES;
+ INTER_DoMaskRRop(addrg, rrops[pix].andg, rrops[pix].xorg,
+ mask, addrg);
+ break;
+ }
+ else
+ pbox++;
+ }
+ }
+#endif
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplmap.h b/xc/programs/Xserver/iplan2p4/iplmap.h
new file mode 100644
index 000000000..0750db728
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplmap.h
@@ -0,0 +1,172 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplmap.h,v 3.1 1998/04/05 16:42:26 robin Exp $ */
+/*
+ * $XConsortium: iplmap.h,v 1.9 94/04/17 20:28:54 dpw Exp $
+ *
+Copyright (c) 1991 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+/*
+ * Map names around so that multiple depths can be supported simultaneously
+ */
+
+/* a losing vendor cpp dumps core if we define NAME in terms of CATNAME */
+
+#if INTER_PLANES == 2
+#define NAME(subname) ipl2p2##subname
+#elif INTER_PLANES == 4
+#define NAME(subname) ipl2p4##subname
+#elif INTER_PLANES == 8
+#define NAME(subname) ipl2p8##subname
+#endif
+
+
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define CATNAME(prefix,subname) prefix##subname
+#else
+#define CATNAME(prefix,subname) prefix/**/subname
+#endif
+
+#define iplScreenPrivateIndex NAME(ScreenPrivateIndex)
+#define QuartetBitsTable NAME(QuartetBitsTable)
+#define QuartetPixelMaskTable NAME(QuartetPixelMaskTable)
+#define iplAllocatePrivates NAME(AllocatePrivates)
+#define iplBSFuncRec NAME(BSFuncRec)
+#define iplBitBlt NAME(BitBlt)
+#define iplBresD NAME(BresD)
+#define iplBresS NAME(BresS)
+#define iplChangeWindowAttributes NAME(ChangeWindowAttributes)
+#define iplCloseScreen NAME(CloseScreen)
+#define iplCopyArea NAME(CopyArea)
+#define iplCopyImagePlane NAME(CopyImagePlane)
+#define iplCopyPixmap NAME(CopyPixmap)
+#define iplCopyPlane NAME(CopyPlane)
+#define iplCopyRotatePixmap NAME(CopyRotatePixmap)
+#define iplCopyWindow NAME(CopyWindow)
+#define iplCreateGC NAME(CreateGC)
+#define iplCreatePixmap NAME(CreatePixmap)
+#define iplCreateWindow NAME(CreateWindow)
+#define iplCreateScreenResources NAME(CreateScreenResoures)
+#define iplDestroyPixmap NAME(DestroyPixmap)
+#define iplDestroyWindow NAME(DestroyWindow)
+#define iplDoBitblt NAME(DoBitblt)
+#define iplDoBitbltCopy NAME(DoBitbltCopy)
+#define iplDoBitbltGeneral NAME(DoBitbltGeneral)
+#define iplDoBitbltOr NAME(DoBitbltOr)
+#define iplDoBitbltXor NAME(DoBitbltXor)
+#define iplFillBoxSolid NAME(FillBoxSolid)
+#define iplFillBoxTile32 NAME(FillBoxTile32)
+#define iplFillBoxTile32sCopy NAME(FillBoxTile32sCopy)
+#define iplFillBoxTile32sGeneral NAME(FillBoxTile32sGeneral)
+#define iplFillBoxTileOdd NAME(FillBoxTileOdd)
+#define iplFillBoxTileOddCopy NAME(FillBoxTileOddCopy)
+#define iplFillBoxTileOddGeneral NAME(FillBoxTileOddGeneral)
+#define iplFillPoly1RectCopy NAME(FillPoly1RectCopy)
+#define iplFillPoly1RectGeneral NAME(FillPoly1RectGeneral)
+#define iplFillRectSolidCopy NAME(FillRectSolidCopy)
+#define iplFillRectSolidGeneral NAME(FillRectSolidGeneral)
+#define iplFillRectSolidXor NAME(FillRectSolidXor)
+#define iplFillRectTile32Copy NAME(FillRectTile32Copy)
+#define iplFillRectTile32General NAME(FillRectTile32General)
+#define iplFillRectTileOdd NAME(FillRectTileOdd)
+#define iplFillSpanTile32sCopy NAME(FillSpanTile32sCopy)
+#define iplFillSpanTile32sGeneral NAME(FillSpanTile32sGeneral)
+#define iplFillSpanTileOddCopy NAME(FillSpanTileOddCopy)
+#define iplFillSpanTileOddGeneral NAME(FillSpanTileOddGeneral)
+#define iplFinishScreenInit NAME(FinishScreenInit)
+#define iplGCFuncs NAME(GCFuncs)
+#define iplGetImage NAME(GetImage)
+#define iplGetScreenPixmap NAME(GetScreenPixmap)
+#define iplGetSpans NAME(GetSpans)
+#define iplHorzS NAME(HorzS)
+#define iplImageGlyphBlt8 NAME(ImageGlyphBlt8)
+#define iplLineSD NAME(LineSD)
+#define iplLineSS NAME(LineSS)
+#define iplMapWindow NAME(MapWindow)
+#define iplMatchCommon NAME(MatchCommon)
+#define iplNonTEOps NAME(NonTEOps)
+#define iplNonTEOps1Rect NAME(NonTEOps1Rect)
+#define iplPadPixmap NAME(PadPixmap)
+#define iplPaintWindow NAME(PaintWindow)
+#define iplPolyGlyphBlt8 NAME(PolyGlyphBlt8)
+#define iplPolyGlyphRop8 NAME(PolyGlyphRop8)
+#define iplPolyFillArcSolidCopy NAME(PolyFillArcSolidCopy)
+#define iplPolyFillArcSolidGeneral NAME(PolyFillArcSolidGeneral)
+#define iplPolyFillRect NAME(PolyFillRect)
+#define iplPolyPoint NAME(PolyPoint)
+#define iplPositionWindow NAME(PositionWindow)
+#define iplPutImage NAME(PutImage)
+#define iplReduceRasterOp NAME(ReduceRasterOp)
+#define iplRestoreAreas NAME(RestoreAreas)
+#define iplSaveAreas NAME(SaveAreas)
+#define iplScreenInit NAME(ScreenInit)
+#define iplSegmentSD NAME(SegmentSD)
+#define iplSegmentSS NAME(SegmentSS)
+#define iplSetScanline NAME(SetScanline)
+#define iplSetScreenPixmap NAME(SetScreenPixmap)
+#define iplSetSpans NAME(SetSpans)
+#define iplSetupScreen NAME(SetupScreen)
+#define iplSolidSpansCopy NAME(SolidSpansCopy)
+#define iplSolidSpansGeneral NAME(SolidSpansGeneral)
+#define iplSolidSpansXor NAME(SolidSpansXor)
+#define iplStippleStack NAME(StippleStack)
+#define iplStippleStackTE NAME(StippleStackTE)
+#define iplTEGlyphBlt NAME(TEGlyphBlt)
+#define iplTEOps NAME(TEOps)
+#define iplTEOps1Rect NAME(TEOps1Rect)
+#define iplTile32FSCopy NAME(Tile32FSCopy)
+#define iplTile32FSGeneral NAME(Tile32FSGeneral)
+#define iplUnmapWindow NAME(UnmapWindow)
+#define iplUnnaturalStippleFS NAME(UnnaturalStippleFS)
+#define iplUnnaturalTileFS NAME(UnnaturalTileFS)
+#define iplValidateGC NAME(ValidateGC)
+#define iplVertS NAME(VertS)
+#define iplXRotatePixmap NAME(XRotatePixmap)
+#define iplYRotatePixmap NAME(YRotatePixmap)
+#define iplendpartial NAME(endpartial)
+#define iplendtab NAME(endtab)
+#define iplmask NAME(mask)
+#define iplrmask NAME(rmask)
+#define iplstartpartial NAME(startpartial)
+#define iplstarttab NAME(starttab)
+#define ipl8LineSS1Rect NAME(LineSS1Rect)
+#define ipl8SegmentSS1Rect NAME(SegmentSS1Rect)
+#define ipl8ClippedLineCopy NAME(ClippedLineCopy)
+#define ipl8ClippedLineXor NAME(ClippedLineXor)
+#define ipl8ClippedLineGeneral NAME(ClippedLineGeneral )
+#define ipl8SegmentSS1RectCopy NAME(SegmentSS1RectCopy)
+#define ipl8SegmentSS1RectXor NAME(SegmentSS1RectXor)
+#define ipl8SegmentSS1RectGeneral NAME(SegmentSS1RectGeneral )
+#define ipl8SegmentSS1RectShiftCopy NAME(SegmentSS1RectShiftCopy)
+#define ipl8LineSS1RectCopy NAME(LineSS1RectCopy)
+#define ipl8LineSS1RectXor NAME(LineSS1RectXor)
+#define ipl8LineSS1RectGeneral NAME(LineSS1RectGeneral )
+#define ipl8LineSS1RectPreviousCopy NAME(LineSS1RectPreviousCopy)
+#define iplZeroPolyArcSS8Copy NAME(ZeroPolyArcSSCopy)
+#define iplZeroPolyArcSS8Xor NAME(ZeroPolyArcSSXor)
+#define iplZeroPolyArcSS8General NAME(ZeroPolyArcSSGeneral)
diff --git a/xc/programs/Xserver/iplan2p4/iplmergerop.h b/xc/programs/Xserver/iplan2p4/iplmergerop.h
new file mode 100644
index 000000000..387f168bc
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplmergerop.h
@@ -0,0 +1,142 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplmergerop.h,v 3.0 1996/08/18 01:54:53 dawes Exp $ */
+#ifndef _IPLANMERGEROP_H_
+#define _IPLANMERGEROP_H_
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+/* defines:
+ INTER_MROP_NAME
+ INTER_MROP_DECLARE_REG()
+ INTER_MROP_INITIALIZE(alu, pm)
+ INTER_MROP_SOLID(src1, src2, dst)
+ INTER_MROP_MASK(src1, src2, mask, dst)
+ INTER_MROP_PREBUILD(src)
+ INTER_MROP_PREBUILT_DECLARE()
+ INTER_MROP_PREBUILT_SOLID(src,dst)
+ INTER_MROP_PREBUILT_MASK(src,dst,mask)
+*/
+
+#ifndef GXcopy
+#include "X.h"
+#endif
+
+typedef struct _mergeRopBits {
+ unsigned long ca1, cx1, ca2, cx2;
+} mergeRopRec, *mergeRopPtr;
+
+extern mergeRopRec mergeRopBits[16];
+
+#define INTER_DeclareMergeRop() \
+ INTER_DECLAREGP(_ca1); \
+ INTER_DECLAREGP(_cx1); \
+ INTER_DECLAREGP(_ca2); \
+ INTER_DECLAREGP(_cx2);
+
+#define INTER_DeclarePrebuiltMergeRop() \
+ INTER_DECLAREGP(_cca); \
+ INTER_DECLAREGP(_ccx);
+
+#define INTER_InitializeMergeRop(alu,pm) { \
+ INTER_DECLAREGP(_pm); \
+ mergeRopPtr _bits; \
+ INTER_PFILL(pm, _pm); \
+ _bits = &mergeRopBits[alu]; \
+ INTER_ANDMSK(_pm, _bits->ca1, _ca1); \
+ INTER_ANDMSK(_pm, _bits->ca2, _ca2); \
+ INTER_ANDMSK(_pm, _bits->cx2, _cx2); \
+ INTER_NOT(_pm, _pm); \
+ INTER_ORMSK(_pm, _bits->cx1, _cx1); \
+}
+
+#define INTER_DoMergeRop(src1, src2, dst) \
+ INTER_CPLX(src1, src2, _ca1, _cx1, _ca2, _cx2, dst)
+
+#define INTER_DoMaskMergeRop(src1, src2, mask, dst) \
+ INTER_CPLXM(src1, src2, _ca1, _cx1, _ca2, _cx2, mask, dst)
+
+#define INTER_DoPrebuiltMergeRop(src, dst) \
+ INTER_DoRRop(src, _cca, _ccx, dst)
+
+#define INTER_DoMaskPrebuiltMergeRop(src, mask, dst) \
+ INTER_DoMaskRRop(src, _cca, _ccx, mask, dst)
+
+#define INTER_PrebuildMergeRop(src) \
+ INTER_DoRRop(src, _ca1, _cx1, _cca); \
+ INTER_DoRRop(src, _ca2, _cx2, _ccx);
+
+#ifndef MROP
+#define MROP 0
+#endif
+
+#define Mclear (1<<GXclear)
+#define Mand (1<<GXand)
+#define MandReverse (1<<GXandReverse)
+#define Mcopy (1<<GXcopy)
+#define MandInverted (1<<GXandInverted)
+#define Mnoop (1<<GXnoop)
+#define Mxor (1<<GXxor)
+#define Mor (1<<GXor)
+#define Mnor (1<<GXnor)
+#define Mequiv (1<<GXequiv)
+#define Minvert (1<<GXinvert)
+#define MorReverse (1<<GXorReverse)
+#define McopyInverted (1<<GXcopyInverted)
+#define MorInverted (1<<GXorInverted)
+#define Mnand (1<<GXnand)
+#define Mset (1<<GXset)
+
+#if (MROP) == Mcopy
+#define INTER_MROP_NAME(prefix) INTER_MROP_NAME_CAT(prefix,Copy)
+#define INTER_MROP_DECLARE_REG()
+#define INTER_MROP_INITIALIZE(alu,pm)
+#define INTER_MROP_SOLID(src,dst,dst2) INTER_COPY(src, dst2)
+#define INTER_MROP_MASK(src,dst,mask, dst2) INTER_COPYM(src,dst,mask,dst2)
+#endif
+
+#if (MROP) == Mxor
+#define INTER_MROP_NAME(prefix) INTER_MROP_NAME_CAT(prefix,Xor)
+#define INTER_MROP_DECLARE_REG()
+#define INTER_MROP_INITIALIZE(alu,pm)
+#define INTER_MROP_SOLID(src,dst,dst2) INTER_XOR(src,dst,dst2)
+#define INTER_MROP_MASK(src,dst,mask,dst2) INTER_XORM(src,dst,mask,dst2)
+#endif
+
+#if (MROP) == Mor
+#define INTER_MROP_NAME(prefix) INTER_MROP_NAME_CAT(prefix,Or)
+#define INTER_MROP_DECLARE_REG()
+#define INTER_MROP_INITIALIZE(alu,pm)
+#define INTER_MROP_SOLID(src,dst,dst2) INTER_OR(src,dst,dst2)
+#define INTER_MROP_MASK(src,dst,mask,dst2) INTER_ORM(src,dst,mask,dst2)
+#endif
+
+#if (MROP) == 0
+#define INTER_MROP_NAME(prefix) INTER_MROP_NAME_CAT(prefix,General)
+#define INTER_MROP_DECLARE_REG() INTER_DeclareMergeRop()
+#define INTER_MROP_INITIALIZE(alu,pm) INTER_InitializeMergeRop(alu,pm)
+#define INTER_MROP_SOLID(src,dst,dst2) INTER_DoMergeRop(src, dst, dst2)
+#define INTER_MROP_MASK(src,dst,mask,dst2) \
+ INTER_DoMaskMergeRop(src, dst, mask, dst2)
+#define INTER_MROP_PREBUILD(src) INTER_PrebuildMergeRop(src)
+#define INTER_MROP_PREBUILT_DECLARE() INTER_DeclarePrebuiltMergeRop()
+#define INTER_MROP_PREBUILT_SOLID(src,dst, dst2) \
+ INTER_DoPrebuiltMergeRop(dst,dst2)
+#define INTER_MROP_PREBUILT_MASK(src,dst,mask,dst2) \
+ INTER_DoMaskPrebuiltMergeRop(dst,mask, dst2)
+#endif
+
+#ifndef INTER_MROP_PREBUILD
+#define INTER_MROP_PREBUILD(src)
+#define INTER_MROP_PREBUILT_DECLARE()
+#define INTER_MROP_PREBUILT_SOLID(src,dst,dst2) INTER_MROP_SOLID(src,dst,dst2)
+#define INTER_MROP_PREBUILT_MASK(src,dst,mask,dst2) \
+ INTER_MROP_MASK(src,dst,mask,dst2)
+#endif
+
+#if (__STDC__ && !defined(UNIXCPP)) || defined(ANSICPP)
+#define INTER_MROP_NAME_CAT(prefix,suffix) prefix##suffix
+#else
+#define INTER_MROP_NAME_CAT(prefix,suffix) prefix/**/suffix
+#endif
+
+#endif /* _IPLANMERGEROP_H_ */
diff --git a/xc/programs/Xserver/iplan2p4/iplmskbits.c b/xc/programs/Xserver/iplan2p4/iplmskbits.c
new file mode 100644
index 000000000..9f1d37dfb
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplmskbits.c
@@ -0,0 +1,104 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplmskbits.c,v 3.0 1996/08/18 01:54:54 dawes Exp $ */
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+#include "iplmap.h"
+
+unsigned short iplmask[] =
+ { 0x8000,
+ 0x4000,
+ 0x2000,
+ 0x1000,
+ 0x0800,
+ 0x0400,
+ 0x0200,
+ 0x0100,
+ 0x0080,
+ 0x0040,
+ 0x0020,
+ 0x0010,
+ 0x0008,
+ 0x0004,
+ 0x0002,
+ 0x0001
+ };
+
+unsigned short iplstarttab[] =
+ {
+ 0x0000,
+ 0x7fff,
+ 0x3fff,
+ 0x1fff,
+ 0x0fff,
+ 0x07ff,
+ 0x03ff,
+ 0x01ff,
+ 0x00ff,
+ 0x007f,
+ 0x003f,
+ 0x001f,
+ 0x000f,
+ 0x0007,
+ 0x0003,
+ 0x0001
+ };
+
+unsigned short iplendtab[] =
+ {
+ 0x0000,
+ 0x8000,
+ 0xc000,
+ 0xe000,
+ 0xf000,
+ 0xf800,
+ 0xfc00,
+ 0xfe00,
+ 0xff00,
+ 0xff80,
+ 0xffc0,
+ 0xffe0,
+ 0xfff0,
+ 0xfff8,
+ 0xfffc,
+ 0xfffe
+ };
+
+unsigned short iplstartpartial[] =
+ {
+ 0xffff,
+ 0x7fff,
+ 0x3fff,
+ 0x1fff,
+ 0x0fff,
+ 0x07ff,
+ 0x03ff,
+ 0x01ff,
+ 0x00ff,
+ 0x007f,
+ 0x003f,
+ 0x001f,
+ 0x000f,
+ 0x0007,
+ 0x0003,
+ 0x0001
+ };
+
+unsigned short iplendpartial[] =
+ {
+ 0xffff,
+ 0x8000,
+ 0xc000,
+ 0xe000,
+ 0xf000,
+ 0xf800,
+ 0xfc00,
+ 0xfe00,
+ 0xff00,
+ 0xff80,
+ 0xffc0,
+ 0xffe0,
+ 0xfff0,
+ 0xfff8,
+ 0xfffc,
+ 0xfffe
+ };
+
diff --git a/xc/programs/Xserver/iplan2p4/iplmskbits.h b/xc/programs/Xserver/iplan2p4/iplmskbits.h
new file mode 100644
index 000000000..4fb3fe066
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplmskbits.h
@@ -0,0 +1,496 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplmskbits.h,v 3.0 1996/08/18 01:54:55 dawes Exp $ */
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#define INTER_PIXGRP unsigned short
+
+#define INTER_PGSZ 16
+#define INTER_PGSZB 2
+#define INTER_PPG 16
+#define INTER_PPGMSK 0xffff
+#define INTER_PLST 15
+#define INTER_PIM 15
+#define INTER_PGSH 4
+#define INTER_PMSK ((1 << (INTER_PLANES)) - 1)
+
+extern INTER_PIXGRP iplmask[];
+extern INTER_PIXGRP iplstarttab[];
+extern INTER_PIXGRP iplendtab[];
+extern INTER_PIXGRP iplstartpartial[];
+extern INTER_PIXGRP iplendpartial[];
+
+#define MFB_PSZ 1
+
+#define INTER_NEXT(x) ((x) + INTER_PLANES)
+#define INTER_NEXT_GROUP(x) (x) += INTER_PLANES
+#define INTER_PREV_GROUP(x) (x) -= INTER_PLANES
+
+#define _I(x) (((unsigned long *) (x))[_INDEX])
+#define _IG(x) ((x)[_INDEX])
+
+#define INTER_DECLAREG(x) INTER_PIXGRP x
+#define INTER_DECLAREGP(x) INTER_PIXGRP x[INTER_PLANES]
+
+#define INTER_DECLARERRAX(x) INTER_PIXGRP *(x)
+#define INTER_DECLARERRAXP(x) INTER_PIXGRP x[INTER_PLANES]
+
+/* and |= PLANE_FILL(~fg), or &= PLANE_FILL(fg) */
+#define INTER_ANDXOR_PM(pm, and, xor) \
+ PLANE_TIMESG( \
+ if (!(pm & INTER_PLANE(_INDEX))) { \
+ _IG(and) = INTER_PPGMSK; \
+ _IG(xor) = 0; \
+ })
+
+#if INTER_PLANES == 2
+
+#define PLANE_TIMESCONDG(x) \
+ ({ int _INDEX; \
+ int _ret; \
+ _ret=(_INDEX=0, (x)) && \
+ (_INDEX=1, (x)) && \
+ _ret; \
+ })
+
+#define PLANE_TIMESCOND(x) \
+ ({ int _INDEX; \
+ (_INDEX=0, x) \
+ })
+
+#define PLANE_TIMESG(x) \
+ { int _INDEX; \
+ _INDEX=0; x; \
+ _INDEX=1; x; \
+ }
+
+#define PLANE_TIMES(x) \
+ { int _INDEX; \
+ _INDEX=0; x; \
+ }
+
+#elif INTER_PLANES == 4
+
+#define PLANE_TIMESCONDG(x) \
+ ({ int _INDEX; \
+ int _ret; \
+ _ret=(_INDEX=0, (x)) && \
+ (_INDEX=1, (x)) && \
+ (_INDEX=2, (x)) && \
+ (_INDEX=3, (x)); \
+ _ret; \
+ })
+
+#define PLANE_TIMESCOND(x) \
+ ({ int _INDEX; \
+ ((_INDEX=0, x) && \
+ (_INDEX=1, x)) \
+ })
+
+#define PLANE_TIMESG(x) \
+ { int _INDEX; \
+ _INDEX=0; x; \
+ _INDEX=1; x; \
+ _INDEX=2; x; \
+ _INDEX=3; x; \
+ }
+
+#define PLANE_TIMES(x) \
+ { int _INDEX; \
+ _INDEX=0; x; \
+ _INDEX=1; x; \
+ }
+
+#elif INTER_PLANES == 8
+
+#define PLANE_TIMESCONDG(x) \
+ ({ int _INDEX; \
+ int _ret; \
+ _ret=((_INDEX=0, (x)) && \
+ (_INDEX=1, (x)) && \
+ (_INDEX=2, (x)) && \
+ (_INDEX=3, (x)) && \
+ (_INDEX=4, (x)) && \
+ (_INDEX=5, (x)) && \
+ (_INDEX=6, (x)) && \
+ (_INDEX=7, (x))); \
+ _ret; \
+ })
+
+#define PLANE_TIMESCOND(x) \
+ ({ int _INDEX; \
+ ((_INDEX=0, x) && \
+ (_INDEX=1, x) && \
+ (_INDEX=2, x) && \
+ (_INDEX=3, x)) \
+ })
+
+#define PLANE_TIMESG(x) \
+ { int _INDEX; \
+ _INDEX=0; x; \
+ _INDEX=1; x; \
+ _INDEX=2; x; \
+ _INDEX=3; x; \
+ _INDEX=4; x; \
+ _INDEX=5; x; \
+ _INDEX=6; x; \
+ _INDEX=7; x; \
+ }
+
+#define PLANE_TIMES(x) \
+ { int _INDEX; \
+ _INDEX=0; x; \
+ _INDEX=1; x; \
+ _INDEX=2; x; \
+ _INDEX=3; x; \
+ }
+
+#endif
+
+/* src = 0 */
+#define INTER_IS_CLR(src) \
+ PLANE_TIMESCONDG(_IG(src) == 0)
+
+/* src = PPGMSK ? */
+#define INTER_IS_SET(src) \
+ PLANE_TIMESCONDG(_IG(src) == INTER_PPGMSK)
+
+/* (src1 ^ scr2) = PPGMSK ? */
+#define INTER_IS_XOR_SET(src1, src2) \
+ PLANE_TIMESCONDG((_IG(src1) ^ _IG(src2)) == INTER_PPGMSK)
+
+/* dst = ~src */
+#define INTER_NOT(src, dst) \
+ PLANE_TIMES(_I(dst) = ~_I(src))
+
+/* dst = 0 */
+#define INTER_CLR(dst) \
+ PLANE_TIMES(_I(dst) = 0)
+
+/* dst = PPGMSK */
+#define INTER_SET(dst) \
+ PLANE_TIMESG(_IG(dst) = INTER_PPGMSK)
+
+/* dst = src */
+#define INTER_COPY(src,dst) \
+ PLANE_TIMES(_I(dst) = _I(src))
+
+/* dst2 = (dst & ~mask) | (src & mask) */
+#define INTER_COPYM(src,dst,mask,dst2) \
+ PLANE_TIMESG( \
+ _IG(dst2) = (_IG(dst) & ~mask) | (_IG(src) & mask) \
+ )
+
+/* dst2 = dst ^ src */
+#define INTER_XOR(src,dst,dst2) \
+ PLANE_TIMES(_I(dst2) = _I(dst) ^ _I(src))
+
+/* dst2 = dst ^ (src & mask) */
+#define INTER_XORM(src,dst,mask,dst2) \
+ PLANE_TIMESG(_IG(dst2) = _IG(dst) ^ (_IG(src) & (mask)))
+
+/* dst2 = dst & src */
+#define INTER_AND(src,dst,dst2) \
+ PLANE_TIMES(_I(dst2) = _I(dst) & _I(src))
+
+/* dst2 = dst & (src | ~mask) */
+#define INTER_ANDM(mask,src,dst,dst2) \
+ PLANE_TIMESG(_IG(dst2) = _IG(dst) & (_IG(src) | ~(mask)))
+
+/* dst2 = dst | src */
+#define INTER_OR(src,dst,dst2) \
+ PLANE_TIMES(_I(dst2) = _I(dst) | _I(src))
+
+/* dst2 = dst | (src & mask) */
+#define INTER_ORM(src,dst,mask,dst2) \
+ PLANE_TIMESG(_IG(dst2) = _IG(dst) | (_IG(src) & (mask)))
+
+/* dst = src | msk */
+#define INTER_ORMSK(src,msk,dst) \
+ PLANE_TIMESG(_IG(dst) = _IG(src) | (msk))
+
+/* dst = src & msk */
+#define INTER_ANDMSK(src,msk,dst) \
+ PLANE_TIMESG(_IG(dst) = _IG(src) & (msk))
+
+/* dst = (src1 & msk1) | (src2 & msk2) */
+#define INTER_ANDMSK2(src1,msk1,src2,msk2,dst) \
+ PLANE_TIMESG(_IG(dst) = (_IG(src1) & (msk1)) | (_IG(src2) & (msk2)))
+
+#define INTER_PLANE(x) (1<<(x))
+
+#define INTER_PFILL(col, fill) \
+ PLANE_TIMESG(_IG(fill) = \
+ ((col) & INTER_PLANE(_INDEX)) ? INTER_PPGMSK : 0)
+
+/* dst = src >> cnt */
+#define INTER_SCRRIGHT(cnt, src, dst) \
+ PLANE_TIMESG(_IG(dst) = _IG(src) >> (cnt))
+
+/* dst = src << cnt */
+#define INTER_SCRLEFT(cnt, src, dst) \
+ PLANE_TIMESG(_IG(dst) = _IG(src) << (cnt))
+
+/* bits1=(bits >> right) | (bits=psrc) << left) */
+#define INTER_GETRLC(right, left, psrc, bits, bits1) \
+ PLANE_TIMESG( _IG(bits1)=(_IG(bits) >> (right)) | \
+ ((_IG(bits) = _IG(psrc)) << (left)))
+
+/* bits1=(bits << left) | (bits=psrc) >> right) */
+#define INTER_GETLRC(left, right, psrc, bits, bits1) \
+ PLANE_TIMESG( _IG(bits1)=(_IG(bits) << (left)) | \
+ ((_IG(bits) = _IG(psrc)) >> (right)))
+
+/* dst=src2 & (src1 & a1 ^ x1) ^ (src1 & a2 ^ x2) */
+#define INTER_CPLX(src1, src2, a1, x1, a2, x2, dst) \
+ PLANE_TIMES( _I(dst) = (_I(src2) \
+ & (_I(src1) & _I(a1) ^ _I(x1)) \
+ ^ (_I(src1) & _I(a2) ^ _I(x2)))) \
+
+/* dst=src2 & ((src1 & a1 ^ x1) | ~mask) ^ ((src1 & a2 ^ x2) & mask) */
+#define INTER_CPLXM(src1, src2, a1, x1, a2, x2, mask, dst) \
+ PLANE_TIMESG( _IG(dst) = (_IG(src2) \
+ & ((_IG(src1) & _IG(a1) ^ _IG(x1)) | ~mask) \
+ ^ ((_IG(src1) & _IG(a2) ^ _IG(x2)) & mask)))
+
+/* dst = (src & ~(bitmask | planemask)) | (insert | (bitmask | planemask)) */
+#define INTER_PMSKINS(bitmask, planemask, insert, src, dst) \
+ PLANE_TIMESG( \
+ if (planemask & INTER_PLANE(_INDEX)) \
+ _IG(dst) = (_IG(src) & ~bitmask) | (_IG(insert) & bitmask) \
+ )
+
+/* dst = (src & ~bitmask) | ((insert >> shift) & bitmask) */
+#define INTER_SCRRMSKINS(bitmask, planemask, insert, shift, src, dst) \
+ PLANE_TIMESG( \
+ if (planemask & INTER_PLANE(_INDEX)) \
+ _IG(dst) = (_IG(src) & ~(bitmask)) | \
+ ((_IG(insert) >> shift) & (bitmask)) \
+ )
+
+/* dst = (src & ~bitmask) | ((insert << shift) & bitmask) */
+#define INTER_SCRLMSKINS(bitmask, planemask, insert, shift, src, dst) \
+ PLANE_TIMESG( \
+ if (planemask & INTER_PLANE(_INDEX)) \
+ _IG(dst) = (_IG(src) & ~bitmask) | \
+ ((_IG(insert) << shift) & bitmask) \
+ )
+
+/* dst = ((src1 << sl1) & bitmask1) | ((src2 >> sr2) & bitmask2) */
+#define INTER_MSKINSM(bitmask1, sl1, src1, bitmask2, sr2, src2, dst) \
+ PLANE_TIMESG( \
+ _IG(dst) = ((_IG(src1) << sl1) & (bitmask1)) | \
+ ((_IG(src2) >> sr2) & (bitmask2)) \
+ )
+
+/* dst = src & and ^ xor */
+#define INTER_DoRRop(src, and, xor, dst) \
+ PLANE_TIMES(_I(dst) = (_I(src) & _I(and) ^ _I(xor))) \
+
+#define INTER_DoMaskRRop(src, and, xor, mask, dst) \
+ PLANE_TIMESG( \
+ _IG(dst) = (_IG(src) & ((_IG(and) | ~(mask))) \
+ ^ (_IG(xor) & mask)))
+
+#define INTER_DoRop(result, alu, src, dst) \
+{ \
+ if (alu == GXcopy) { \
+ PLANE_TIMES( \
+ _I(result) = fnCOPY (_I(src), _I(dst))); \
+ } else if (alu == GXxor) { \
+ PLANE_TIMES( \
+ _I(result) = fnXOR (_I(src), _I(dst))); \
+ } \
+ else { \
+ switch (alu) \
+ { \
+ case GXclear: \
+ PLANE_TIMES( \
+ _I(result) = fnCLEAR (_I(src), _I(dst))); \
+ break; \
+ case GXand: \
+ PLANE_TIMES( \
+ _I(result) = fnAND (_I(src), _I(dst))); \
+ break; \
+ case GXandReverse: \
+ PLANE_TIMES( \
+ _I(result) = fnANDREVERSE (_I(src), _I(dst))); \
+ break; \
+ case GXandInverted: \
+ PLANE_TIMES( \
+ _I(result) = fnANDINVERTED (_I(src), _I(dst))); \
+ break; \
+ case GXnoop: \
+ PLANE_TIMES( \
+ _I(result) = fnNOOP (_I(src), _I(dst))); \
+ break; \
+ case GXor: \
+ PLANE_TIMES( \
+ _I(result) = fnOR (_I(src), _I(dst))); \
+ break; \
+ case GXnor: \
+ PLANE_TIMES( \
+ _I(result) = fnNOR (_I(src), _I(dst))); \
+ break; \
+ case GXequiv: \
+ PLANE_TIMES( \
+ _I(result) = fnEQUIV (_I(src), _I(dst))); \
+ break; \
+ case GXinvert: \
+ PLANE_TIMES( \
+ _I(result) = fnINVERT (_I(src), _I(dst))); \
+ break; \
+ case GXorReverse: \
+ PLANE_TIMES( \
+ _I(result) = fnORREVERSE (_I(src), _I(dst))); \
+ break; \
+ case GXcopyInverted: \
+ PLANE_TIMES( \
+ _I(result) = fnCOPYINVERTED (_I(src), _I(dst))); \
+ break; \
+ case GXorInverted: \
+ PLANE_TIMES( \
+ _I(result) = fnORINVERTED (_I(src), _I(dst))); \
+ break; \
+ case GXnand: \
+ PLANE_TIMES( \
+ _I(result) = fnNAND (_I(src), _I(dst))); \
+ break; \
+ case GXset: \
+ PLANE_TIMES( \
+ _I(result) = fnSET (_I(src), _I(dst))); \
+ break; \
+ } \
+ } \
+}
+
+#define iplGetGroupWidthAndPointer(pDrawable, width, pointer) \
+ iplGetTypedWidthAndPointer(pDrawable, width, pointer, INTER_PIXGRP, INTER_PIXGRP)
+
+#define INTER_getstipplepixels(psrcstip, x, w, ones, psrcpix, pdstpix) \
+{ \
+ unsigned long q; \
+ int m; \
+ if (ones) { \
+ if ((m = ((x) - ((MFB_PPW*MFB_PSZ)-MFB_PPW))) > 0) { \
+ q = (*(psrcstip)) << m; \
+ if ( (x)+(w) > (MFB_PPW*MFB_PSZ) ) \
+ q |= *((psrcstip)+1) >> ((MFB_PPW*MFB_PSZ)-m); \
+ } \
+ else \
+ q = (*(psrcstip)) >> -m; \
+ } \
+ else { \
+ if ((m = ((x) - ((MFB_PPW*MFB_PSZ)-MFB_PPW))) > 0) { \
+ q = (~ *(psrcstip)) << m; \
+ if ( (x)+(w) > (MFB_PPW*MFB_PSZ) ) \
+ q |= (~*((psrcstip)+1)) >> ((MFB_PPW*MFB_PSZ)-m); \
+ } \
+ else \
+ q = (~ *(psrcstip)) >> -m; \
+ } \
+ q >>=16; \
+ INTER_ANDMSK(psrcpix,q,pdstpix); \
+}
+
+#define INTER_getstipplepixelsb(psrcstip, x, w, psrcpix0, psrcpix1, pdstpix) \
+{ \
+ unsigned long q,qn; \
+ int m; \
+ if ((m = ((x) - ((MFB_PPW*MFB_PSZ)-MFB_PPW))) > 0) { \
+ q = (*(psrcstip)) << m; \
+ qn = (~ *(psrcstip)) << m; \
+ if ( (x)+(w) > (MFB_PPW*MFB_PSZ) ) { \
+ q |= *((psrcstip)+1) >> ((MFB_PPW*MFB_PSZ)-m); \
+ qn |= (~ *((psrcstip)+1)) >> ((MFB_PPW*MFB_PSZ)-m); \
+ } \
+ } \
+ else { \
+ q = (*(psrcstip)) >> -m; \
+ qn = (~ *(psrcstip)) >> -m; \
+ } \
+ q >>=16; \
+ qn >>=16; \
+ INTER_ANDMSK2(psrcpix0,qn,psrcpix1,q,pdstpix); \
+}
+
+#define INTER_maskbits(x, w, startmask, endmask, nlg) \
+ startmask = iplstarttab[(x) & INTER_PIM]; \
+ endmask = iplendtab[((x)+(w)) & INTER_PIM]; \
+ if (startmask) \
+ nlg = (((w) - (INTER_PPG - ((x) & INTER_PIM))) >> INTER_PGSH); \
+ else \
+ nlg = (w) >> INTER_PGSH;
+
+#define INTER_maskpartialbits(x, w, mask) \
+ mask = iplstartpartial[(x) & INTER_PIM] & \
+ iplendpartial[((x) + (w)) & INTER_PIM];
+
+#define INTER_mask32bits(x, w, startmask, endmask, nlw) \
+ startmask = iplstarttab[(x) & INTER_PIM]; \
+ endmask = iplendtab[((x)+(w)) & INTER_PIM];
+
+#define INTER_getbits(psrc, x, w, pdst) \
+ if ( ((x) + (w)) <= INTER_PPG) \
+ { \
+ INTER_SCRLEFT((x), psrc, pdst); \
+ } \
+ else \
+ { \
+ int m; \
+ m = INTER_PPG-(x); \
+ INTER_MSKINSM(iplendtab[m], x, psrc, \
+ iplstarttab[m], m, INTER_NEXT(psrc), pdst); \
+ }
+
+#define INTER_putbits(psrc, x, w, pdst, planemask) \
+ if ( ((x)+(w)) <= INTER_PPG) \
+ { \
+ INTER_DECLAREG(tmpmask); \
+ INTER_maskpartialbits((x), (w), tmpmask); \
+ INTER_SCRRMSKINS(tmpmask, planemask, psrc, x, pdst, pdst); \
+ } \
+ else \
+ { \
+ unsigned long m; \
+ unsigned long n; \
+ m = INTER_PPG-(x); \
+ n = (w) - m; \
+ INTER_SCRRMSKINS(iplstarttab[x], planemask, psrc, x, \
+ pdst, pdst); \
+ INTER_SCRLMSKINS(iplendtab[n], planemask, psrc, m, \
+ INTER_NEXT(pdst), INTER_NEXT(pdst)); \
+ }
+
+#define INTER_putbitsrop(psrc, x, w, pdst, planemask, rop) \
+if ( ((x)+(w)) <= INTER_PPG) \
+{ \
+ INTER_DECLAREG(tmpmask); \
+ INTER_DECLAREGP(t1); INTER_DECLAREGP(t2); \
+ INTER_maskpartialbits((x), (w), tmpmask); \
+ INTER_SCRRIGHT((x), (psrc), (t1)); \
+ INTER_DoRop(t2, rop, t1, pdst); \
+ INTER_PMSKINS(tmpmask, planemask, t2, pdst, pdst); \
+} \
+else \
+{ \
+ unsigned long m; \
+ unsigned long n; \
+ INTER_DECLAREGP(t1); INTER_DECLAREGP(t2); \
+ m = INTER_PPG-(x); \
+ n = (w) - m; \
+ INTER_SCRRIGHT((x), (psrc), (t1)); \
+ INTER_DoRop(t2, rop, t1, pdst); \
+ INTER_PMSKINS(iplstarttab[x], planemask, t2, pdst, pdst); \
+ INTER_SCRLEFT(m, (psrc), (t1)); \
+ INTER_DoRop(t2, rop, t1, pdst+1); \
+ INTER_PMSKINS(iplendtab[n], planemask, t2, pdst, pdst); \
+}
+
+#define INTER_putbitsmropshort(src, x, w, pdst) { \
+ INTER_DECLAREG(_tmpmask); \
+ INTER_DECLAREGP(_t1); \
+ INTER_maskpartialbits((x), (w), _tmpmask); \
+ INTER_SCRRIGHT((x), (src), _t1); \
+ INTER_DoMaskMergeRop(_t1, pdst, _tmpmask, pdst); \
+}
+
diff --git a/xc/programs/Xserver/iplan2p4/iplpack.c b/xc/programs/Xserver/iplan2p4/iplpack.c
new file mode 100644
index 000000000..96072895c
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplpack.c
@@ -0,0 +1,316 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplpack.c,v 3.0 1996/08/18 01:54:56 dawes Exp $ */
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+/* abcd abcd abcd abcd abcd abcd abcd abcd */
+/* aaaa aaaa bbbb bbbb cccc cccc dddd dddd */
+
+unsigned long tabi[256] = {
+ 0x00000000,0x00001000,0x10000000,0x10001000,
+ 0x00002000,0x00003000,0x10002000,0x10003000,
+ 0x20000000,0x20001000,0x30000000,0x30001000,
+ 0x20002000,0x20003000,0x30002000,0x30003000,
+ 0x00004000,0x00005000,0x10004000,0x10005000,
+ 0x00006000,0x00007000,0x10006000,0x10007000,
+ 0x20004000,0x20005000,0x30004000,0x30005000,
+ 0x20006000,0x20007000,0x30006000,0x30007000,
+ 0x40000000,0x40001000,0x50000000,0x50001000,
+ 0x40002000,0x40003000,0x50002000,0x50003000,
+ 0x60000000,0x60001000,0x70000000,0x70001000,
+ 0x60002000,0x60003000,0x70002000,0x70003000,
+ 0x40004000,0x40005000,0x50004000,0x50005000,
+ 0x40006000,0x40007000,0x50006000,0x50007000,
+ 0x60004000,0x60005000,0x70004000,0x70005000,
+ 0x60006000,0x60007000,0x70006000,0x70007000,
+ 0x00008000,0x00009000,0x10008000,0x10009000,
+ 0x0000a000,0x0000b000,0x1000a000,0x1000b000,
+ 0x20008000,0x20009000,0x30008000,0x30009000,
+ 0x2000a000,0x2000b000,0x3000a000,0x3000b000,
+ 0x0000c000,0x0000d000,0x1000c000,0x1000d000,
+ 0x0000e000,0x0000f000,0x1000e000,0x1000f000,
+ 0x2000c000,0x2000d000,0x3000c000,0x3000d000,
+ 0x2000e000,0x2000f000,0x3000e000,0x3000f000,
+ 0x40008000,0x40009000,0x50008000,0x50009000,
+ 0x4000a000,0x4000b000,0x5000a000,0x5000b000,
+ 0x60008000,0x60009000,0x70008000,0x70009000,
+ 0x6000a000,0x6000b000,0x7000a000,0x7000b000,
+ 0x4000c000,0x4000d000,0x5000c000,0x5000d000,
+ 0x4000e000,0x4000f000,0x5000e000,0x5000f000,
+ 0x6000c000,0x6000d000,0x7000c000,0x7000d000,
+ 0x6000e000,0x6000f000,0x7000e000,0x7000f000,
+ 0x80000000,0x80001000,0x90000000,0x90001000,
+ 0x80002000,0x80003000,0x90002000,0x90003000,
+ 0xa0000000,0xa0001000,0xb0000000,0xb0001000,
+ 0xa0002000,0xa0003000,0xb0002000,0xb0003000,
+ 0x80004000,0x80005000,0x90004000,0x90005000,
+ 0x80006000,0x80007000,0x90006000,0x90007000,
+ 0xa0004000,0xa0005000,0xb0004000,0xb0005000,
+ 0xa0006000,0xa0007000,0xb0006000,0xb0007000,
+ 0xc0000000,0xc0001000,0xd0000000,0xd0001000,
+ 0xc0002000,0xc0003000,0xd0002000,0xd0003000,
+ 0xe0000000,0xe0001000,0xf0000000,0xf0001000,
+ 0xe0002000,0xe0003000,0xf0002000,0xf0003000,
+ 0xc0004000,0xc0005000,0xd0004000,0xd0005000,
+ 0xc0006000,0xc0007000,0xd0006000,0xd0007000,
+ 0xe0004000,0xe0005000,0xf0004000,0xf0005000,
+ 0xe0006000,0xe0007000,0xf0006000,0xf0007000,
+ 0x80008000,0x80009000,0x90008000,0x90009000,
+ 0x8000a000,0x8000b000,0x9000a000,0x9000b000,
+ 0xa0008000,0xa0009000,0xb0008000,0xb0009000,
+ 0xa000a000,0xa000b000,0xb000a000,0xb000b000,
+ 0x8000c000,0x8000d000,0x9000c000,0x9000d000,
+ 0x8000e000,0x8000f000,0x9000e000,0x9000f000,
+ 0xa000c000,0xa000d000,0xb000c000,0xb000d000,
+ 0xa000e000,0xa000f000,0xb000e000,0xb000f000,
+ 0xc0008000,0xc0009000,0xd0008000,0xd0009000,
+ 0xc000a000,0xc000b000,0xd000a000,0xd000b000,
+ 0xe0008000,0xe0009000,0xf0008000,0xf0009000,
+ 0xe000a000,0xe000b000,0xf000a000,0xf000b000,
+ 0xc000c000,0xc000d000,0xd000c000,0xd000d000,
+ 0xc000e000,0xc000f000,0xd000e000,0xd000f000,
+ 0xe000c000,0xe000d000,0xf000c000,0xf000d000,
+ 0xe000e000,0xe000f000,0xf000e000,0xf000f000,
+ };
+static unsigned long tabp[256] = {
+ 0x00000000,0x00020000,0x00080000,0x000a0000,
+ 0x00200000,0x00220000,0x00280000,0x002a0000,
+ 0x00800000,0x00820000,0x00880000,0x008a0000,
+ 0x00a00000,0x00a20000,0x00a80000,0x00aa0000,
+ 0x02000000,0x02020000,0x02080000,0x020a0000,
+ 0x02200000,0x02220000,0x02280000,0x022a0000,
+ 0x02800000,0x02820000,0x02880000,0x028a0000,
+ 0x02a00000,0x02a20000,0x02a80000,0x02aa0000,
+ 0x08000000,0x08020000,0x08080000,0x080a0000,
+ 0x08200000,0x08220000,0x08280000,0x082a0000,
+ 0x08800000,0x08820000,0x08880000,0x088a0000,
+ 0x08a00000,0x08a20000,0x08a80000,0x08aa0000,
+ 0x0a000000,0x0a020000,0x0a080000,0x0a0a0000,
+ 0x0a200000,0x0a220000,0x0a280000,0x0a2a0000,
+ 0x0a800000,0x0a820000,0x0a880000,0x0a8a0000,
+ 0x0aa00000,0x0aa20000,0x0aa80000,0x0aaa0000,
+ 0x20000000,0x20020000,0x20080000,0x200a0000,
+ 0x20200000,0x20220000,0x20280000,0x202a0000,
+ 0x20800000,0x20820000,0x20880000,0x208a0000,
+ 0x20a00000,0x20a20000,0x20a80000,0x20aa0000,
+ 0x22000000,0x22020000,0x22080000,0x220a0000,
+ 0x22200000,0x22220000,0x22280000,0x222a0000,
+ 0x22800000,0x22820000,0x22880000,0x228a0000,
+ 0x22a00000,0x22a20000,0x22a80000,0x22aa0000,
+ 0x28000000,0x28020000,0x28080000,0x280a0000,
+ 0x28200000,0x28220000,0x28280000,0x282a0000,
+ 0x28800000,0x28820000,0x28880000,0x288a0000,
+ 0x28a00000,0x28a20000,0x28a80000,0x28aa0000,
+ 0x2a000000,0x2a020000,0x2a080000,0x2a0a0000,
+ 0x2a200000,0x2a220000,0x2a280000,0x2a2a0000,
+ 0x2a800000,0x2a820000,0x2a880000,0x2a8a0000,
+ 0x2aa00000,0x2aa20000,0x2aa80000,0x2aaa0000,
+ 0x80000000,0x80020000,0x80080000,0x800a0000,
+ 0x80200000,0x80220000,0x80280000,0x802a0000,
+ 0x80800000,0x80820000,0x80880000,0x808a0000,
+ 0x80a00000,0x80a20000,0x80a80000,0x80aa0000,
+ 0x82000000,0x82020000,0x82080000,0x820a0000,
+ 0x82200000,0x82220000,0x82280000,0x822a0000,
+ 0x82800000,0x82820000,0x82880000,0x828a0000,
+ 0x82a00000,0x82a20000,0x82a80000,0x82aa0000,
+ 0x88000000,0x88020000,0x88080000,0x880a0000,
+ 0x88200000,0x88220000,0x88280000,0x882a0000,
+ 0x88800000,0x88820000,0x88880000,0x888a0000,
+ 0x88a00000,0x88a20000,0x88a80000,0x88aa0000,
+ 0x8a000000,0x8a020000,0x8a080000,0x8a0a0000,
+ 0x8a200000,0x8a220000,0x8a280000,0x8a2a0000,
+ 0x8a800000,0x8a820000,0x8a880000,0x8a8a0000,
+ 0x8aa00000,0x8aa20000,0x8aa80000,0x8aaa0000,
+ 0xa0000000,0xa0020000,0xa0080000,0xa00a0000,
+ 0xa0200000,0xa0220000,0xa0280000,0xa02a0000,
+ 0xa0800000,0xa0820000,0xa0880000,0xa08a0000,
+ 0xa0a00000,0xa0a20000,0xa0a80000,0xa0aa0000,
+ 0xa2000000,0xa2020000,0xa2080000,0xa20a0000,
+ 0xa2200000,0xa2220000,0xa2280000,0xa22a0000,
+ 0xa2800000,0xa2820000,0xa2880000,0xa28a0000,
+ 0xa2a00000,0xa2a20000,0xa2a80000,0xa2aa0000,
+ 0xa8000000,0xa8020000,0xa8080000,0xa80a0000,
+ 0xa8200000,0xa8220000,0xa8280000,0xa82a0000,
+ 0xa8800000,0xa8820000,0xa8880000,0xa88a0000,
+ 0xa8a00000,0xa8a20000,0xa8a80000,0xa8aa0000,
+ 0xaa000000,0xaa020000,0xaa080000,0xaa0a0000,
+ 0xaa200000,0xaa220000,0xaa280000,0xaa2a0000,
+ 0xaa800000,0xaa820000,0xaa880000,0xaa8a0000,
+ 0xaaa00000,0xaaa20000,0xaaa80000,0xaaaa0000,
+ };
+
+void
+iplUnpackLine(int planes, int longs, unsigned int *psrc, unsigned short *ipsrc)
+{
+ unsigned long temp,m;
+ unsigned char *t=(unsigned char *) &temp;
+ unsigned char *i=(unsigned char *) ipsrc;
+ unsigned char *s=(unsigned char *) psrc;
+ int j,off;
+ switch (planes) {
+ case 2:
+ for (j = 0 ; j < longs ; j++)
+ {
+ *((long *) ipsrc)++=(tabi[s[0]] >> 0) |
+ (tabi[s[1]] >> 4) |
+ (tabi[s[2]] >> 8) |
+ (tabi[s[3]] >> 12);
+ s+=4;
+ }
+ break;
+ case 4:
+ for (j = 0 ; j < longs ; j++)
+ {
+ temp= (tabi[s[0]] >> 0) |
+ (tabi[s[1]] >> 4) |
+ (tabi[s[2]] >> 8) |
+ (tabi[s[3]] >> 12);
+ temp= (tabi[t[0]] >> 0) |
+ (tabi[t[1]] >> 4) |
+ (tabi[t[2]] >> 8) |
+ (tabi[t[3]] >> 12);
+ s+=4;
+ if (j & 1) {
+ i[7]=t[0];
+ i[5]=t[1];
+ i[3]=t[2];
+ i[1]=t[3];
+ i += 8;
+ }
+ else {
+ i[6]=t[0];
+ i[4]=t[1];
+ i[2]=t[2];
+ i[0]=t[3];
+ }
+ }
+ break;
+ case 8:
+ for (j = 0 ; j < longs ; j++)
+ {
+ temp= (tabi[s[0]] >> 0) |
+ (tabi[s[1]] >> 4) |
+ (tabi[s[2]] >> 8) |
+ (tabi[s[3]] >> 12);
+
+ temp= (tabi[t[0]] >> 0) |
+ (tabi[t[1]] >> 4) |
+ (tabi[t[2]] >> 8) |
+ (tabi[t[3]] >> 12);
+
+ temp= (tabi[t[0]] >> 0) |
+ (tabi[t[1]] >> 4) |
+ (tabi[t[2]] >> 8) |
+ (tabi[t[3]] >> 12);
+
+ off=12-(j & 3)*4;
+ m=0xf << off;
+ ipsrc[7]=(ipsrc[7] & ~m) | (((temp >> 28) << off) & m);
+ ipsrc[6]=(ipsrc[6] & ~m) | (((temp >> 24) << off) & m);
+ ipsrc[5]=(ipsrc[5] & ~m) | (((temp >> 20) << off) & m);
+ ipsrc[4]=(ipsrc[4] & ~m) | (((temp >> 16) << off) & m);
+ ipsrc[3]=(ipsrc[3] & ~m) | (((temp >> 12) << off) & m);
+ ipsrc[2]=(ipsrc[2] & ~m) | (((temp >> 8) << off) & m);
+ ipsrc[1]=(ipsrc[1] & ~m) | (((temp >> 4) << off) & m);
+ ipsrc[0]=(ipsrc[0] & ~m) | (((temp >> 0) << off) & m);
+ if (! off)
+ ipsrc +=8;
+ s+=4;
+ }
+ }
+}
+
+void
+iplPackLine(int planes, int longs, unsigned short *ipdst, unsigned int *pdst)
+{
+ unsigned long temp,m;
+ unsigned char *t=(unsigned char *) &temp;
+ unsigned char *i=(unsigned char *) ipdst;
+ int j,off;
+ switch (planes) {
+ case 2:
+ for (j = 0 ; j < longs ; j++)
+ {
+ *pdst++=(tabp[i[2]] >> 0) |
+ (tabp[i[0]] >> 1) |
+ (tabp[i[3]] >> 16) |
+ (tabp[i[1]] >> 17);
+ i+=4;
+ }
+ break;
+ case 4:
+ for (j = 0 ; j < longs ; j++)
+ {
+ if (j & 1) {
+ temp= (tabp[i[7]] >> 0) |
+ (tabp[i[3]] >> 1) |
+ (tabp[i[5]] >> 16) |
+ (tabp[i[1]] >> 17);
+ i += 8;
+ }
+ else {
+ temp= (tabp[i[6]] >> 0) |
+ (tabp[i[2]] >> 1) |
+ (tabp[i[4]] >> 16) |
+ (tabp[i[0]] >> 17);
+ }
+ *pdst++=(tabp[t[0]] >> 0) |
+ (tabp[t[2]] >> 1) |
+ (tabp[t[1]] >> 16) |
+ (tabp[t[3]] >> 17);
+ }
+ break;
+ case 8:
+ for (j = 0 ; j < longs ; j++)
+ {
+ off=12-(j & 3)*4;
+ m=0xf;
+ temp=(((ipdst[7] >> off) & m) << 28) |
+ (((ipdst[6] >> off) & m) << 24) |
+ (((ipdst[5] >> off) & m) << 20) |
+ (((ipdst[4] >> off) & m) << 16) |
+ (((ipdst[3] >> off) & m) << 12) |
+ (((ipdst[2] >> off) & m) << 8) |
+ (((ipdst[1] >> off) & m) << 4) |
+ (((ipdst[0] >> off) & m) << 0);
+
+ if (! off)
+ ipdst +=8;
+
+ temp= (tabp[t[0]] >> 0) |
+ (tabp[t[2]] >> 1) |
+ (tabp[t[1]] >> 16) |
+ (tabp[t[3]] >> 17);
+
+ temp= (tabp[t[0]] >> 0) |
+ (tabp[t[2]] >> 1) |
+ (tabp[t[1]] >> 16) |
+ (tabp[t[3]] >> 17);
+
+ *pdst++=(tabp[t[0]] >> 0) |
+ (tabp[t[2]] >> 1) |
+ (tabp[t[1]] >> 16) |
+ (tabp[t[3]] >> 17);
+ }
+ }
+}
+
+unsigned long
+iplpack(unsigned long ipl)
+{
+ unsigned char *ic=(unsigned char *) &ipl;
+ return (tabp[ic[0]]) | /* a0a0a0a0a0a0a0a00000000000000000 */
+ (tabp[ic[2]] >> 1) | /* abababababababab0000000000000000 */
+ (tabp[ic[1]] >> 16) | /* ababababababababa0a0a0a0a0a0a0a0 */
+ (tabp[ic[3]] >> 17); /* abababababababababababababababab */
+}
+
+unsigned long
+iplunpack(unsigned long pack)
+{
+ unsigned char *ip=(unsigned char *) &pack;
+ return (tabi[ip[0]]) | /* aaaa000000000000bbbb000000000000 */
+ (tabi[ip[1]] >> 4) | /* aaaaaaaa00000000bbbbbbbb00000000 */
+ (tabi[ip[2]] >> 8) | /* aaaaaaaaaaaa0000bbbbbbbbbbbb0000 */
+ (tabi[ip[3]] >> 12); /* aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb */
+}
+
diff --git a/xc/programs/Xserver/iplan2p4/iplpack.h b/xc/programs/Xserver/iplan2p4/iplpack.h
new file mode 100644
index 000000000..9545c75ec
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplpack.h
@@ -0,0 +1,10 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplpack.h,v 3.0 1996/08/18 01:54:57 dawes Exp $ */
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#define NUM_LONGS(planes, xs, xe) \
+ (((((xe) * (planes) + 31) & ~31) - \
+ (((xs) * (planes)) & ~31))/32)
+
+#define NUM_TEMP_BYTES(planes, longs) \
+ (((2 * (longs) + (planes) - 1) / planes + 1) * planes * 2)
diff --git a/xc/programs/Xserver/iplan2p4/iplpixmap.c b/xc/programs/Xserver/iplan2p4/iplpixmap.c
new file mode 100644
index 000000000..1be01ffba
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplpixmap.c
@@ -0,0 +1,380 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplpixmap.c,v 3.0 1996/08/18 01:54:59 dawes Exp $ */
+/* $XConsortium: iplpixmap.c,v 5.14 94/04/17 20:28:56 dpw Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* pixmap management
+ written by drewry, september 1986
+
+ on a monchrome device, a pixmap is a bitmap.
+*/
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "Xmd.h"
+#include "servermd.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "mi.h"
+#include "ipl.h"
+#include "iplmskbits.h"
+
+extern unsigned long endtab[];
+
+PixmapPtr
+iplCreatePixmap (pScreen, width, height, depth)
+ ScreenPtr pScreen;
+ int width;
+ int height;
+ int depth;
+{
+ PixmapPtr pPixmap;
+ int datasize;
+ int paddedWidth;
+ int ipad=INTER_PLANES*2 - 1;
+
+ paddedWidth = PixmapBytePad(width, depth);
+ paddedWidth = (paddedWidth + ipad) & ~ipad;
+ datasize = height * paddedWidth;
+ pPixmap = AllocatePixmap(pScreen, datasize);
+ if (!pPixmap)
+ return NullPixmap;
+ pPixmap->drawable.type = DRAWABLE_PIXMAP;
+ pPixmap->drawable.class = 0;
+ pPixmap->drawable.pScreen = pScreen;
+ pPixmap->drawable.depth = depth;
+ pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth);
+ pPixmap->drawable.id = 0;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap->drawable.x = 0;
+ pPixmap->drawable.y = 0;
+ pPixmap->drawable.width = width;
+ pPixmap->drawable.height = height;
+ pPixmap->devKind = paddedWidth;
+ pPixmap->refcnt = 1;
+#ifdef PIXPRIV
+ pPixmap->devPrivate.ptr = datasize ?
+ (pointer)((char *)pPixmap + pScreen->totalPixmapSize) : NULL;
+#else
+ pPixmap->devPrivate.ptr = (pointer)((long)(pPixmap + 1));
+#endif
+ return pPixmap;
+}
+
+Bool
+iplDestroyPixmap(pPixmap)
+ PixmapPtr pPixmap;
+{
+ if(--pPixmap->refcnt)
+ return TRUE;
+ xfree(pPixmap);
+ return TRUE;
+}
+
+PixmapPtr
+iplCopyPixmap(pSrc)
+ register PixmapPtr pSrc;
+{
+ register PixmapPtr pDst;
+ int size;
+ ScreenPtr pScreen;
+
+ size = pSrc->drawable.height * pSrc->devKind;
+ pScreen = pSrc->drawable.pScreen;
+ pDst = (*pScreen->CreatePixmap) (pScreen, pSrc->drawable.width,
+ pSrc->drawable.height, pSrc->drawable.depth);
+ if (!pDst)
+ return NullPixmap;
+ memmove((char *)pDst->devPrivate.ptr, (char *)pSrc->devPrivate.ptr, size);
+ return pDst;
+}
+
+
+/* replicates a pattern to be a full 32 bits wide.
+ relies on the fact that each scnaline is longword padded.
+ doesn't do anything if pixmap is not a factor osf 32 wide.
+ changes width field of pixmap if successful, so that the fast
+ iplXRotatePixmap code gets used if we rotate the pixmap later.
+ iplYRotatePixmap code gets used if we rotate the pixmap later.
+
+ calculate number of times to repeat
+ for each scanline of pattern
+ zero out area to be filled with replicate
+ left shift and or in original as many times as needed
+*/
+
+void
+iplPadPixmap(pPixmap)
+ PixmapPtr pPixmap;
+{
+ register int width = pPixmap->drawable.width;
+ register int h;
+ register unsigned short mask;
+ register unsigned short *p;
+ register unsigned short bits; /* real pattern bits */
+ register int i;
+ int rep; /* repeat count for pattern */
+
+ if (width >= INTER_PGSZ)
+ return;
+
+ rep = INTER_PGSZ/width;
+/* if (rep*width != INTER_PGSZ)
+ return; */
+
+ mask = iplendtab[width];
+
+ p = (unsigned short *)(pPixmap->devPrivate.ptr);
+ for (h=0; h < pPixmap->drawable.height * INTER_PLANES; h++)
+ {
+ *p &= mask;
+ bits = *p ;
+ for(i=1; i<rep; i++)
+ {
+#if (BITMAP_BIT_ORDER == MSBFirst)
+ bits >>= width;
+#else
+ bits <<= width;
+#endif
+ *p |= bits;
+ }
+ p++;
+ }
+ pPixmap->drawable.width = rep*width; /* PGSZ/(pPixmap->drawable.bitsPerPixel); */
+}
+
+
+#ifdef notdef
+/*
+ * ipl debugging routine -- assumes pixmap is 1 byte deep
+ */
+static ipldumppixmap(pPix)
+ PixmapPtr pPix;
+{
+ unsigned int *pw;
+ char *psrc, *pdst;
+ int i, j;
+ char line[66];
+
+ ErrorF( "pPixmap: 0x%x\n", pPix);
+ ErrorF( "%d wide %d high\n", pPix->drawable.width, pPix->drawable.height);
+ if (pPix->drawable.width > 64)
+ {
+ ErrorF( "too wide to see\n");
+ return;
+ }
+
+ pw = (unsigned int *) pPix->devPrivate.ptr;
+ psrc = (char *) pw;
+
+/*
+ for ( i=0; i<pPix->drawable.height; ++i )
+ ErrorF( "0x%x\n", pw[i] );
+*/
+
+ for ( i = 0; i < pPix->drawable.height; ++i ) {
+ pdst = line;
+ for(j = 0; j < pPix->drawable.width; j++) {
+ *pdst++ = *psrc++ ? 'X' : ' ' ;
+ }
+ *pdst++ = '\n';
+ *pdst++ = '\0';
+ ErrorF( "%s", line);
+ }
+}
+#endif /* notdef */
+
+/* Rotates pixmap pPix by w pixels to the right on the screen. Assumes that
+ * words are PGSZ bits wide, and that the least significant bit appears on the
+ * left.
+ */
+void
+iplXRotatePixmap(pPix, rw)
+ PixmapPtr pPix;
+ register int rw;
+{
+ INTER_DECLAREG(*pw);
+ INTER_DECLAREG(*pwFinal);
+ INTER_DECLAREGP(t);
+ int rot;
+
+ if (pPix == NullPixmap)
+ return;
+
+ switch (((DrawablePtr) pPix)->bitsPerPixel) {
+ case INTER_PLANES:
+ break;
+ case 1:
+ mfbXRotatePixmap(pPix, rw);
+ return;
+ default:
+ ErrorF("iplXRotatePixmap: unsupported bitsPerPixel %d\n", ((DrawablePtr) pPix)->bitsPerPixel);
+ return;
+ }
+ pw = (unsigned short *)pPix->devPrivate.ptr;
+ modulus (rw, (int) pPix->drawable.width, rot);
+ if(pPix->drawable.width == 16)
+ {
+ pwFinal = pw + pPix->drawable.height * INTER_PLANES;
+ while(pw < pwFinal)
+ {
+ INTER_COPY(pw, t);
+ INTER_MSKINSM(iplendtab[rot], INTER_PPG-rot, t,
+ ~0, rot, t, pw)
+ INTER_NEXT_GROUP(pw);
+ }
+ }
+ else
+ {
+ ErrorF("ipl internal error: trying to rotate odd-sized pixmap.\n");
+#ifdef notdef
+ register unsigned long *pwTmp;
+ int size, tsize;
+
+ tsize = PixmapBytePad(pPix->drawable.width - rot, pPix->drawable.depth);
+ pwTmp = (unsigned long *) ALLOCATE_LOCAL(pPix->drawable.height * tsize);
+ if (!pwTmp)
+ return;
+ /* divide pw (the pixmap) in two vertically at (w - rot) and swap */
+ tsize >>= 2;
+ size = pPix->devKind >> SIZE0F(PixelGroup);
+ iplQuickBlt((long *)pw, (long *)pwTmp,
+ 0, 0, 0, 0,
+ (int)pPix->drawable.width - rot, (int)pPix->drawable.height,
+ size, tsize);
+ iplQuickBlt((long *)pw, (long *)pw,
+ (int)pPix->drawable.width - rot, 0, 0, 0,
+ rot, (int)pPix->drawable.height,
+ size, size);
+ iplQuickBlt((long *)pwTmp, (long *)pw,
+ 0, 0, rot, 0,
+ (int)pPix->drawable.width - rot, (int)pPix->drawable.height,
+ tsize, size);
+ DEALLOCATE_LOCAL(pwTmp);
+#endif
+ }
+}
+
+/* Rotates pixmap pPix by h lines. Assumes that h is always less than
+ pPix->drawable.height
+ works on any width.
+ */
+void
+iplYRotatePixmap(pPix, rh)
+ register PixmapPtr pPix;
+ int rh;
+{
+ int nbyDown; /* bytes to move down to row 0; also offset of
+ row rh */
+ int nbyUp; /* bytes to move up to line rh; also
+ offset of first line moved down to 0 */
+ char *pbase;
+ char *ptmp;
+ int rot;
+
+ if (pPix == NullPixmap)
+ return;
+ switch (((DrawablePtr) pPix)->bitsPerPixel) {
+ case INTER_PLANES:
+ break;
+ case 1:
+ mfbYRotatePixmap(pPix, rh);
+ return;
+ default:
+ ErrorF("iplYRotatePixmap: unsupported bitsPerPixel %d\n", ((DrawablePtr) pPix)->bitsPerPixel);
+ return;
+ }
+
+ modulus (rh, (int) pPix->drawable.height, rot);
+ pbase = (char *)pPix->devPrivate.ptr;
+
+ nbyDown = rot * pPix->devKind;
+ nbyUp = (pPix->devKind * pPix->drawable.height) - nbyDown;
+ if(!(ptmp = (char *)ALLOCATE_LOCAL(nbyUp)))
+ return;
+
+ memmove(ptmp, pbase, nbyUp); /* save the low rows */
+ memmove(pbase, pbase+nbyUp, nbyDown); /* slide the top rows down */
+ memmove(pbase+nbyDown, ptmp, nbyUp); /* move lower rows up to row rot */
+ DEALLOCATE_LOCAL(ptmp);
+}
+
+void
+iplCopyRotatePixmap(psrcPix, ppdstPix, xrot, yrot)
+ register PixmapPtr psrcPix, *ppdstPix;
+ int xrot, yrot;
+{
+ register PixmapPtr pdstPix;
+
+ if ((pdstPix = *ppdstPix) &&
+ (pdstPix->devKind == psrcPix->devKind) &&
+ (pdstPix->drawable.height == psrcPix->drawable.height))
+ {
+ memmove((char *)pdstPix->devPrivate.ptr,
+ (char *)psrcPix->devPrivate.ptr,
+ psrcPix->drawable.height * psrcPix->devKind);
+ pdstPix->drawable.width = psrcPix->drawable.width;
+ pdstPix->drawable.depth = psrcPix->drawable.depth;
+ pdstPix->drawable.bitsPerPixel = psrcPix->drawable.bitsPerPixel;
+ pdstPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ else
+ {
+ if (pdstPix)
+ /* FIX XBUG 6168 */
+ (*pdstPix->drawable.pScreen->DestroyPixmap)(pdstPix);
+ *ppdstPix = pdstPix = iplCopyPixmap(psrcPix);
+ if (!pdstPix)
+ return;
+ }
+ iplPadPixmap(pdstPix);
+ if (xrot)
+ iplXRotatePixmap(pdstPix, xrot);
+ if (yrot)
+ iplYRotatePixmap(pdstPix, yrot);
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplply1rct.c b/xc/programs/Xserver/iplan2p4/iplply1rct.c
new file mode 100644
index 000000000..f73bc8864
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplply1rct.c
@@ -0,0 +1,306 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplply1rct.c,v 3.1 1998/03/20 21:08:09 hohndel Exp $ */
+/*
+ * $XConsortium: iplply1rct.c,v 1.14 94/04/17 20:28:56 dpw Exp $
+ *
+Copyright (c) 1990 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "mistruct.h"
+
+#include "ipl.h"
+#include "iplrrop.h"
+
+#include "iplmskbits.h"
+
+void
+INTER_RROP_NAME(iplFillPoly1Rect) (pDrawable, pGC, shape, mode, count, ptsIn)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int count;
+ DDXPointPtr ptsIn;
+{
+ iplPrivGCPtr devPriv;
+ int ngwidth;
+ unsigned short *addrl, *addr;
+ int maxy;
+ int origin;
+ register int vertex1, vertex2;
+ int c;
+ BoxPtr extents;
+ int clip;
+ int y;
+ int *vertex1p, *vertex2p;
+ int *endp;
+ int x1, x2;
+ int dx1, dx2;
+ int dy1, dy2;
+ int e1, e2;
+ int step1, step2;
+ int sign1, sign2;
+ int h;
+ int l, r;
+ INTER_DECLAREG(mask);
+ INTER_DECLAREG(bits);
+ int nmiddle;
+ INTER_RROP_DECLARE
+ bits=~0;
+
+ if (mode == CoordModePrevious)
+ {
+ miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+
+ devPriv = iplGetGCPrivate(pGC);
+#ifdef NO_ONE_RECT
+ if (REGION_NUM_RECTS(pGC->pCompositeClip) != 1)
+ {
+ miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+#endif
+ origin = *((int *) &pDrawable->x);
+ origin -= (origin & 0x8000) << 1;
+ extents = &pGC->pCompositeClip->extents;
+ INTER_RROP_FETCH_GCPRIV(devPriv);
+ vertex1 = *((int *) &extents->x1) - origin;
+ vertex2 = *((int *) &extents->x2) - origin - 0x00010001;
+ clip = 0;
+ y = 32767;
+ maxy = 0;
+ vertex2p = (int *) ptsIn;
+ endp = vertex2p + count;
+ if (shape == Convex)
+ {
+ while (count--)
+ {
+ c = *vertex2p;
+ clip |= (c - vertex1) | (vertex2 - c);
+ c = intToY(c);
+ if (c < y)
+ {
+ y = c;
+ vertex1p = vertex2p;
+ }
+ vertex2p++;
+ if (c > maxy)
+ maxy = c;
+ }
+ }
+ else
+ {
+ int yFlip = 0;
+ dx1 = 1;
+ x2 = -1;
+ x1 = -1;
+ while (count--)
+ {
+ c = *vertex2p;
+ clip |= (c - vertex1) | (vertex2 - c);
+ c = intToY(c);
+ if (c < y)
+ {
+ y = c;
+ vertex1p = vertex2p;
+ }
+ vertex2p++;
+ if (c > maxy)
+ maxy = c;
+ if (c == x1)
+ continue;
+ if (dx1 > 0)
+ {
+ if (x2 < 0)
+ x2 = c;
+ else
+ dx2 = dx1 = (c - x1) >> 31;
+ }
+ else
+ if ((c - x1) >> 31 != dx1)
+ {
+ dx1 = ~dx1;
+ yFlip++;
+ }
+ x1 = c;
+ }
+ x1 = (x2 - c) >> 31;
+ if (x1 != dx1)
+ yFlip++;
+ if (x1 != dx2)
+ yFlip++;
+ if (yFlip != 2)
+ clip = 0x8000;
+ }
+ if (y == maxy)
+ return;
+
+ if (clip & 0x80008000)
+ {
+ miFillPolygon (pDrawable, pGC, shape, mode, vertex2p - (int *) ptsIn, ptsIn);
+ return;
+ }
+
+#define AddrYPlus(a,y) ((a) + (y) * ngwidth)
+
+ iplGetGroupWidthAndPointer(pDrawable, ngwidth, addrl);
+ addrl = AddrYPlus(addrl,y + pDrawable->y);
+ origin = intToX(origin);
+ vertex2p = vertex1p;
+ vertex2 = vertex1 = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+#define Setup(c,x,vertex,dx,dy,e,sign,step) {\
+ x = intToX(vertex); \
+ if (dy = intToY(c) - y) { \
+ dx = intToX(c) - x; \
+ step = 0; \
+ if (dx >= 0) \
+ { \
+ e = 0; \
+ sign = 1; \
+ if (dx >= dy) {\
+ step = dx / dy; \
+ dx = dx % dy; \
+ } \
+ } \
+ else \
+ { \
+ e = 1 - dy; \
+ sign = -1; \
+ dx = -dx; \
+ if (dx >= dy) { \
+ step = - (dx / dy); \
+ dx = dx % dy; \
+ } \
+ } \
+ } \
+ x += origin; \
+ vertex = c; \
+}
+
+#define Step(x,dx,dy,e,sign,step) {\
+ x += step; \
+ if ((e += dx) > 0) \
+ { \
+ x += sign; \
+ e -= dy; \
+ } \
+}
+ for (;;)
+ {
+ if (y == intToY(vertex1))
+ {
+ do
+ {
+ if (vertex1p == (int *) ptsIn)
+ vertex1p = endp;
+ c = *--vertex1p;
+ Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1)
+ } while (y >= intToY(vertex1));
+ h = dy1;
+ }
+ else
+ {
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ h = intToY(vertex1) - y;
+ }
+ if (y == intToY(vertex2))
+ {
+ do
+ {
+ c = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+ Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2)
+ } while (y >= intToY(vertex2));
+ if (dy2 < h)
+ h = dy2;
+ }
+ else
+ {
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ if ((c = (intToY(vertex2) - y)) < h)
+ h = c;
+ }
+ /* fill spans for this segment */
+ y += h;
+ for (;;)
+ {
+ l = x1;
+ r = x2;
+ nmiddle = x2 - x1;
+ if (nmiddle < 0)
+ {
+ nmiddle = -nmiddle;
+ l = x2;
+ r = x1;
+ }
+ c = l & INTER_PIM;
+ l -= c;
+
+ addr = addrl + (l >> INTER_PGSH) * INTER_PLANES;
+ if (c + nmiddle < INTER_PPG)
+ {
+ mask = (bits >> c) ^ (bits >> (c+nmiddle));
+ INTER_RROP_SOLID_MASK(addr,mask);
+ }
+ else
+ {
+ if (c)
+ {
+ mask = bits >> c;
+ INTER_RROP_SOLID_MASK(addr,mask);
+ nmiddle += c - INTER_PPG;
+ INTER_NEXT_GROUP(addr);
+ }
+ nmiddle >>= INTER_PGSH;
+ while (--nmiddle >= 0) {
+ INTER_RROP_SOLID(addr); INTER_NEXT_GROUP(addr);
+ }
+ if (mask = ~(bits >> (r & INTER_PIM)))
+ INTER_RROP_SOLID_MASK(addr,mask);
+ }
+ if (!--h)
+ break;
+ addrl = AddrYPlus (addrl, 1);
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ }
+ if (y == maxy)
+ break;
+ addrl = AddrYPlus (addrl, 1);
+ }
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplpntwin.c b/xc/programs/Xserver/iplan2p4/iplpntwin.c
new file mode 100644
index 000000000..a5a61194a
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplpntwin.c
@@ -0,0 +1,337 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplpntwin.c,v 3.0 1996/08/18 01:55:01 dawes Exp $ */
+/* $XConsortium: iplpntwin.c,v 5.18 94/04/17 20:28:57 dpw Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+
+#include "windowstr.h"
+#include "regionstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+#include "ipl.h"
+#include "mi.h"
+
+void
+iplPaintWindow(pWin, pRegion, what)
+ WindowPtr pWin;
+ RegionPtr pRegion;
+ int what;
+{
+ register iplPrivWin *pPrivWin;
+ WindowPtr pBgWin;
+
+ pPrivWin = iplGetWindowPrivate(pWin);
+
+ switch (what) {
+ case PW_BACKGROUND:
+ switch (pWin->backgroundState) {
+ case None:
+ break;
+ case ParentRelative:
+ do {
+ pWin = pWin->parent;
+ } while (pWin->backgroundState == ParentRelative);
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
+ what);
+ break;
+ case BackgroundPixmap:
+ if (pPrivWin->fastBackground)
+ {
+ iplFillBoxTile32 ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pPrivWin->pRotatedBackground);
+ }
+ else
+ {
+ iplFillBoxTileOdd ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->background.pixmap,
+ (int) pWin->drawable.x, (int) pWin->drawable.y);
+ }
+ break;
+ case BackgroundPixel:
+ iplFillBoxSolid ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->background.pixel);
+ break;
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel)
+ {
+ iplFillBoxSolid ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->border.pixel);
+ }
+ else if (pPrivWin->fastBorder)
+ {
+ iplFillBoxTile32 ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pPrivWin->pRotatedBorder);
+ }
+ else
+ {
+ for (pBgWin = pWin;
+ pBgWin->backgroundState == ParentRelative;
+ pBgWin = pBgWin->parent);
+
+ iplFillBoxTileOdd ((DrawablePtr)pWin,
+ (int)REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion),
+ pWin->border.pixmap,
+ (int) pBgWin->drawable.x,
+ (int) pBgWin->drawable.y);
+ }
+ break;
+ }
+}
+
+/*
+ * Use the RROP macros in copy mode
+ */
+
+#define RROP GXcopy
+#include "iplrrop.h"
+#include "iplmskbits.h"
+
+
+# define Expand(left, right, leftAdjust) { \
+ int widthStep; \
+ widthStep = widthDst - (nmiddle + leftAdjust) * INTER_PLANES; \
+ while (h--) { \
+ left \
+ m = nmiddle; \
+ INTER_RROP_SPAN(pdst, m); \
+ right \
+ pdst += widthStep; \
+ } \
+}
+
+void
+iplFillBoxSolid (pDrawable, nBox, pBox, pixel)
+ DrawablePtr pDrawable;
+ int nBox;
+ BoxPtr pBox;
+ unsigned long pixel;
+{
+ INTER_DECLAREG(*pdstBase);
+ int widthDst;
+ register int h;
+ INTER_DECLAREGP(rrop_xor);
+ INTER_DECLAREG(*pdst);
+ INTER_DECLAREG(leftMask);
+ INTER_DECLAREG(rightMask);
+ int nmiddle;
+ register int m;
+ int w;
+
+ iplGetGroupWidthAndPointer(pDrawable, widthDst, pdstBase);
+
+ INTER_PFILL(pixel, rrop_xor);
+ for (; nBox; nBox--, pBox++)
+ {
+ pdst = pdstBase + pBox->y1 * widthDst;
+ h = pBox->y2 - pBox->y1;
+ w = pBox->x2 - pBox->x1;
+ pdst += (pBox->x1 >> INTER_PGSH) * INTER_PLANES;
+ if ((pBox->x1 & INTER_PIM) + w <= INTER_PPG)
+ {
+ INTER_maskpartialbits(pBox->x1, w, leftMask);
+ while (h--) {
+ INTER_COPYM(rrop_xor, pdst, leftMask, pdst);
+ pdst += widthDst;
+ }
+ }
+ else
+ {
+ INTER_maskbits (pBox->x1, w, leftMask, rightMask, nmiddle);
+ if (leftMask)
+ {
+ if (rightMask)
+ {
+ Expand (INTER_RROP_SOLID_MASK (pdst, leftMask);
+ INTER_NEXT_GROUP(pdst);,
+ INTER_RROP_SOLID_MASK (pdst, rightMask); ,
+ 1)
+ }
+ else
+ {
+ Expand (INTER_RROP_SOLID_MASK (pdst, leftMask);
+ INTER_NEXT_GROUP(pdst);,
+ ;,
+ 1)
+ }
+ }
+ else
+ {
+ if (rightMask)
+ {
+ Expand (;,
+ INTER_RROP_SOLID_MASK (pdst, rightMask);,
+ 0)
+ }
+ else
+ {
+ Expand (;,
+ ;,
+ 0)
+ }
+ }
+ }
+ }
+}
+
+void
+iplFillBoxTile32 (pDrawable, nBox, pBox, tile)
+ DrawablePtr pDrawable;
+ int nBox; /* number of boxes to fill */
+ BoxPtr pBox; /* pointer to list of boxes to fill */
+ PixmapPtr tile; /* rotated, expanded tile */
+{
+ INTER_DECLAREGP(rrop_xor);
+ INTER_DECLAREG(*pdst);
+ register int m;
+ INTER_DECLAREG(*psrc);
+ int tileHeight;
+
+ int widthDst;
+ int w;
+ int h;
+ INTER_DECLAREG(leftMask);
+ INTER_DECLAREG(rightMask);
+ int nmiddle;
+ int y;
+ int srcy;
+
+ INTER_DECLAREG(*pdstBase);
+
+ tileHeight = tile->drawable.height;
+ psrc = (unsigned short *)tile->devPrivate.ptr;
+
+
+ iplGetGroupWidthAndPointer (pDrawable, widthDst, pdstBase);
+
+ while (nBox--)
+ {
+ w = pBox->x2 - pBox->x1;
+ h = pBox->y2 - pBox->y1;
+ y = pBox->y1;
+ pdst = pdstBase + (pBox->y1 * widthDst) +
+ (pBox->x1 >> INTER_PGSH) * INTER_PLANES;
+ srcy = y % tileHeight;
+
+#define StepTile INTER_COPY(psrc + srcy * INTER_PLANES, rrop_xor); \
+ ++srcy; \
+ if (srcy == tileHeight) \
+ srcy = 0;
+
+ if ( ((pBox->x1 & INTER_PIM) + w) < INTER_PPG)
+ {
+ INTER_maskpartialbits(pBox->x1, w, leftMask);
+ rightMask = ~leftMask;
+ while (h--)
+ {
+ StepTile
+ INTER_MSKINSM(rightMask, 0, pdst, leftMask, 0, rrop_xor, pdst);
+ pdst += widthDst;
+ }
+ }
+ else
+ {
+ INTER_maskbits(pBox->x1, w, leftMask, rightMask, nmiddle);
+
+ if (leftMask)
+ {
+ if (rightMask)
+ {
+ Expand (StepTile
+ INTER_RROP_SOLID_MASK(pdst, leftMask);
+ INTER_NEXT_GROUP(pdst);,
+ INTER_RROP_SOLID_MASK(pdst, rightMask);,
+ 1)
+ }
+ else
+ {
+ Expand (StepTile
+ INTER_RROP_SOLID_MASK(pdst, leftMask);
+ INTER_NEXT_GROUP(pdst);,
+ ;,
+ 1)
+ }
+ }
+ else
+ {
+ if (rightMask)
+ {
+ Expand (StepTile
+ ,
+ INTER_RROP_SOLID_MASK(pdst, rightMask);,
+ 0)
+ }
+ else
+ {
+ Expand (StepTile
+ ,
+ ;,
+ 0)
+ }
+ }
+ }
+ pBox++;
+ }
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplpolypnt.c b/xc/programs/Xserver/iplan2p4/iplpolypnt.c
new file mode 100644
index 000000000..3d90edea4
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplpolypnt.c
@@ -0,0 +1,119 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplpolypnt.c,v 3.1 1998/03/20 21:08:09 hohndel Exp $ */
+/************************************************************
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+********************************************************/
+
+/* $XConsortium: iplpolypnt.c,v 5.17 94/04/17 20:28:57 dpw Exp $ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "ipl.h"
+#include "iplmskbits.h"
+
+#define isClipped(c,ul,lr) ((((c) - (ul)) | ((lr) - (c))) & ClipMask)
+
+/* WARNING: pbox contains two shorts. This code assumes they are packed
+ * and can be referenced together as an INT32.
+ */
+
+#define PointLoop(fill) { \
+ for (nbox = REGION_NUM_RECTS(cclip), pbox = REGION_RECTS(cclip); \
+ --nbox >= 0; \
+ pbox++) \
+ { \
+ c1 = *((INT32 *) &pbox->x1) - off; \
+ c2 = *((INT32 *) &pbox->x2) - off - 0x00010001; \
+ for (ppt = (INT32 *) pptInit, i = npt; --i >= 0;) \
+ { \
+ pt = *ppt++; \
+ if (!isClipped(pt,c1,c2)) { \
+ fill \
+ } \
+ } \
+ } \
+}
+
+void
+iplPolyPoint(pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode;
+ int npt;
+ xPoint *pptInit;
+{
+ register INT32 pt;
+ register INT32 c1, c2;
+ register unsigned long ClipMask = 0x80008000;
+ INTER_DECLAREG(*addrg);
+ register int ngwidth;
+ register int xoffset;
+ INTER_DECLAREG(*addrgt);
+ register INT32 *ppt;
+ RegionPtr cclip;
+ int nbox;
+ register int i;
+ register BoxPtr pbox;
+ INTER_DECLARERRAX(and);
+ INTER_DECLARERRAX(xor);
+ int rop = pGC->alu;
+ int off;
+ iplPrivGCPtr devPriv;
+ xPoint *pptPrev;
+
+ devPriv =iplGetGCPrivate(pGC);
+ rop = devPriv->rop;
+ if (rop == GXnoop)
+ return;
+ cclip = pGC->pCompositeClip;
+ xor = devPriv->xorg;
+ and = devPriv->andg;
+ if ((mode == CoordModePrevious) && (npt > 1))
+ {
+ for (pptPrev = pptInit + 1, i = npt - 1; --i >= 0; pptPrev++)
+ {
+ pptPrev->x += (pptPrev-1)->x;
+ pptPrev->y += (pptPrev-1)->y;
+ }
+ }
+ off = *((int *) &pDrawable->x);
+ off -= (off & 0x8000) << 1;
+ iplGetGroupWidthAndPointer(pDrawable, ngwidth, addrg);
+ addrg = addrg + pDrawable->y * ngwidth +
+ (pDrawable->x >> INTER_PGSH) * INTER_PLANES;
+ xoffset = pDrawable->x & INTER_PIM;
+ PointLoop( addrgt = addrg + intToY(pt) * ngwidth
+ + ((intToX(pt) + xoffset) >> INTER_PGSH) * INTER_PLANES;
+ INTER_DoMaskRRop(addrgt, and, xor,
+ iplmask[(intToX(pt) + xoffset) & INTER_PIM], addrgt);
+ )
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplrrop.c b/xc/programs/Xserver/iplan2p4/iplrrop.c
new file mode 100644
index 000000000..cfc43c130
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplrrop.c
@@ -0,0 +1,215 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplrrop.c,v 3.0 1996/08/18 01:55:03 dawes Exp $ */
+/*
+ * $XConsortium: iplrrop.c,v 1.8 94/04/17 20:28:59 dpw Exp $
+ *
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+/* ipl reduced rasterop computations */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "ipl.h"
+
+#include "iplmskbits.h"
+
+/* A description:
+ *
+ * There are four possible operations on each bit in the destination word,
+ *
+ * 1 2 3 4
+ *
+ * 0 0 0 1 1
+ * 1 0 1 0 1
+ *
+ * On examination of the reduced rop equation (dst = (dst & and) ^ xor),
+ * these four fall to reduced rops as follows:
+ *
+ * and 0 1 1 0
+ * xor 0 0 1 1
+ *
+ * or, (if 'and' is expensive) (dst = (dst | or) ^ xor)
+ *
+ * or 1 0 0 1
+ * xor 1 0 1 0
+ *
+ * The trouble with using this later equation is that trivial
+ * rasterop reduction is more difficult; some common rasterops
+ * use complicated expressions of xor/and instead of the simple
+ * ones while other common rasterops are not made any simpler:
+ *
+ * GXcopy: *dst = ~xor instead of *dst = xor
+ * GXand: *dst = *dst & ~or instead of *dst = *dst & and
+ * GXor: *dst = *dst | or instead of *dst = *dst | xor
+ * GXxor: *dst = *dst ^ xor instead of *dst = *dst ^ xor
+ *
+ * If you're really set on using this second mechanism, the changes
+ * are pretty simple.
+ *
+ * All that remains is to provide a mechanism for computing and/xor values
+ * based on the raster op and foreground value.
+ *
+ * The 16 rops fall as follows, with the associated reduced
+ * rop and/xor and or/xor values. The values in parenthesis following the
+ * reduced values gives an equation using the source value for
+ * the reduced value, and is one of {0, src, ~src, 1} as appropriate.
+ *
+ * clear and andReverse copy
+ * src 0 1 0 1 0 1 0 1
+ * dst 0 0 0 0 0 0 0 0 1 0 0 1
+ * 1 0 0 1 0 1 1 0 0 1 0 1
+ *
+ * and 0 0 (0) 0 1 (src) 0 1 (src) 0 0 (0)
+ * xor 0 0 (0) 0 0 (0) 0 1 (src) 0 1 (src)
+ *
+ * or 1 1 (1) 1 0 (~src) 1 0 (~src) 1 1 (1)
+ * xor 1 1 (1) 1 0 (~src) 1 1 (1) 1 0 (~src)
+ *
+ * andInverted noop xor or
+ * src 0 1 0 1 0 1 0 1
+ * dst 0 0 0 0 0 0 0 0 1 0 0 1
+ * 1 1 0 1 1 1 1 1 0 1 1 1
+ *
+ * and 1 0 (~src) 1 1 (1) 1 1 (1) 1 0 (~src)
+ * xor 0 0 (0) 0 0 (0) 0 1 (src) 0 1 (src)
+ *
+ * or 0 1 (src) 0 0 (0) 0 0 (0) 0 1 (src)
+ * xor 0 1 (src) 0 0 (0) 0 1 (src) 0 0 (0)
+ *
+ * nor equiv invert orReverse
+ * src 0 1 0 1 0 1 0 1
+ * dst 0 1 0 0 1 0 0 1 1 0 1 1
+ * 1 0 0 1 0 1 1 0 0 1 0 1
+ *
+ * and 1 0 (~src) 1 1 (1) 1 1 (1) 1 0 (~src)
+ * xor 1 0 (~src) 1 0 (~src) 1 1 (1) 1 1 (1)
+ *
+ * or 0 1 (src) 0 0 (0) 0 0 (0) 0 1 (src)
+ * xor 1 1 (1) 1 0 (~src) 1 1 (1) 1 0 (~src)
+ *
+ * copyInverted orInverted nand set
+ * src 0 1 0 1 0 1 0 1
+ * dst 0 1 0 0 1 0 0 1 1 0 1 1
+ * 1 1 0 1 1 1 1 1 0 1 1 1
+ *
+ * and 0 0 (0) 0 1 (src) 0 1 (src) 0 0 (0)
+ * xor 1 0 (~src) 1 0 (~src) 1 1 (1) 1 1 (1)
+ *
+ * or 1 1 (1) 1 0 (~src) 1 0 (~src) 1 1 (1)
+ * xor 0 1 (src) 0 0 (0) 0 1 (src) 0 0 (0)
+ */
+
+iplReduceRasterOp (rop, fg, pm, and, xor)
+ int rop;
+ unsigned long fg, pm;
+ unsigned short *and;
+ unsigned short *xor;
+{
+ int rrop;
+ switch (rop)
+ {
+ case GXclear:
+ INTER_CLR(and);
+ INTER_CLR(xor);
+ break;
+ case GXand:
+ INTER_PFILL(fg, and);
+ INTER_CLR(xor);
+ break;
+ case GXandReverse:
+ INTER_PFILL(fg, and);
+ INTER_PFILL(fg, xor);
+ break;
+ case GXcopy:
+ INTER_CLR(and);
+ INTER_PFILL(fg, xor);
+ break;
+ case GXandInverted:
+ INTER_PFILL(~fg, xor);
+ INTER_CLR(xor);
+ break;
+ case GXnoop:
+ INTER_SET(and);
+ INTER_CLR(xor);
+ break;
+ case GXxor:
+ INTER_SET(and);
+ INTER_PFILL(fg, xor);
+ break;
+ case GXor:
+ INTER_PFILL(~fg, and);
+ INTER_PFILL(fg, xor);
+ break;
+ case GXnor:
+ INTER_PFILL(~fg, and);
+ INTER_PFILL(~fg, xor);
+ break;
+ case GXequiv:
+ INTER_SET(and);
+ INTER_PFILL(~fg, xor);
+ case GXinvert:
+ INTER_SET(and);
+ INTER_SET(xor);
+ break;
+ case GXorReverse:
+ INTER_PFILL(~fg, and);
+ INTER_SET(xor);
+ break;
+ case GXcopyInverted:
+ INTER_CLR(and);
+ INTER_PFILL(~fg, xor);
+ break;
+ case GXorInverted:
+ INTER_PFILL(fg, and);
+ INTER_PFILL(~fg, xor);
+ break;
+ case GXnand:
+ INTER_PFILL(fg, and);
+ INTER_SET(xor);
+ break;
+ case GXset:
+ INTER_CLR(and);
+ INTER_SET(xor);
+ break;
+ }
+ INTER_ANDXOR_PM(pm, and, xor);
+ if (INTER_IS_CLR(and))
+ rrop = GXcopy;
+ else if (INTER_IS_SET(and))
+ rrop = GXxor;
+ else if (INTER_IS_CLR(xor))
+ rrop = GXand;
+ else if (INTER_IS_XOR_SET(and, xor))
+ rrop = GXor;
+ else
+ rrop = GXset;
+ return rrop;
+}
+
diff --git a/xc/programs/Xserver/iplan2p4/iplrrop.h b/xc/programs/Xserver/iplan2p4/iplrrop.h
new file mode 100644
index 000000000..3d40927e9
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplrrop.h
@@ -0,0 +1,76 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplrrop.h,v 3.0 1996/08/18 01:55:04 dawes Exp $ */
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+/* reduced raster ops */
+/* INTER_RROP_DECLARE INTER_RROP_FETCH_GC,
+ INTER_RROP_SOLID_MASK, INTER_RROP_SPAN INTER_RROP_NAME */
+
+#define INTER_RROP_FETCH_GC(gc) \
+INTER_RROP_FETCH_GCPRIV(((iplPrivGCPtr)(gc)->devPrivates[iplGCPrivateIndex].ptr))
+
+#if RROP == GXcopy
+#define INTER_RROP_DECLARE register unsigned short *rrop_xor;
+#define INTER_RROP_FETCH_GCPRIV(devPriv) rrop_xor = (devPriv)->xorg;
+#define INTER_RROP_SOLID(dst) INTER_COPY(rrop_xor, dst)
+#define INTER_RROP_SOLID_MASK(dst,mask) INTER_COPYM(rrop_xor, dst, mask, dst)
+#define INTER_RROP_NAME(prefix) INTER_RROP_NAME_CAT(prefix,Copy)
+#endif /* GXcopy */
+
+#if RROP == GXxor
+#define INTER_RROP_DECLARE register unsigned short *rrop_xor;
+#define INTER_RROP_FETCH_GCPRIV(devPriv) rrop_xor = (devPriv)->xorg;
+#define INTER_RROP_SOLID(dst) INTER_XOR(rrop_xor, dst, dst)
+#define INTER_RROP_SOLID_MASK(dst,mask) INTER_XORM(rrop_xor, dst, mask, dst)
+#define INTER_RROP_NAME(prefix) INTER_RROP_NAME_CAT(prefix,Xor)
+#endif /* GXxor */
+
+#if RROP == GXand
+#define INTER_RROP_DECLARE register unsigned short *rrop_and;
+#define INTER_RROP_FETCH_GCPRIV(devPriv) rrop_and = (devPriv)->andg;
+#define INTER_RROP_SOLID(dst) INTER_AND(rrop_and, dst, dst)
+#define INTER_RROP_SOLID_MASK(dst,mask) INTER_ANDM(rrop_and, dst, mask, dst)
+#define INTER_RROP_NAME(prefix) INTER_RROP_NAME_CAT(prefix,And)
+#endif /* GXand */
+
+#if RROP == GXor
+#define INTER_RROP_DECLARE register unsigned short *rrop_or;
+#define INTER_RROP_FETCH_GCPRIV(devPriv) rrop_or = (devPriv)->xorg;
+#define INTER_RROP_SOLID(dst) INTER_OR(rrop_or, dst, dst)
+#define INTER_RROP_SOLID_MASK(dst,mask) INTER_ORM(mask, rrop_or, dst, dst)
+#define INTER_RROP_NAME(prefix) INTER_RROP_NAME_CAT(prefix,Or)
+#endif /* GXor */
+
+#if RROP == GXnoop
+#define INTER_RROP_DECLARE
+#define INTER_RROP_FETCH_GCPRIV(devPriv)
+#define INTER_RROP_SOLID(dst)
+#define INTER_RROP_SOLID_MASK(dst,mask)
+#define INTER_RROP_NAME(prefix) INTER_RROP_NAME_CAT(prefix,Noop)
+#endif /* GXnoop */
+
+#if RROP == GXset
+#define INTER_RROP_DECLARE register unsigned short *rrop_and, *rrop_xor;
+#define INTER_RROP_FETCH_GCPRIV(devPriv) rrop_and = (devPriv)->andg; \
+ rrop_xor = (devPriv)->xorg;
+#define INTER_RROP_SOLID(dst) INTER_DoRRop(dst, rrop_and, rrop_xor, dst)
+#define INTER_RROP_SOLID_MASK(dst,mask) \
+ INTER_DoMaskRRop(dst, rrop_and, rrop_xor, mask, dst)
+#define INTER_RROP_NAME(prefix) INTER_RROP_NAME_CAT(prefix,General)
+#endif /* GXset */
+
+#ifndef INTER_RROP_SPAN
+#define INTER_RROP_SPAN(pdst,nmiddle) \
+ while (--(nmiddle) >= 0) { \
+ INTER_RROP_SOLID(pdst); \
+ (pdst) = INTER_NEXT(pdst); \
+ }
+
+#endif
+
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define INTER_RROP_NAME_CAT(prefix,suffix) prefix##suffix
+#else
+#define INTER_RROP_NAME_CAT(prefix,suffix) prefix/**/suffix
+#endif
+
diff --git a/xc/programs/Xserver/iplan2p4/iplscrinit.c b/xc/programs/Xserver/iplan2p4/iplscrinit.c
new file mode 100644
index 000000000..1d7915776
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplscrinit.c
@@ -0,0 +1,229 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplscrinit.c,v 3.3 1998/11/22 10:37:41 dawes Exp $ */
+/************************************************************
+Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
+
+ 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 no-
+tice appear in all copies and that both that copyright no-
+tice and this permission notice appear in supporting docu-
+mentation, and that the names of Sun or X Consortium
+not be used in advertising or publicity pertaining to
+distribution of the software without specific prior
+written permission. Sun and X Consortium make no
+representations about the suitability of this software for
+any purpose. It is provided "as is" without any express or
+implied warranty.
+
+SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
+NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
+ABLE 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.
+
+********************************************************/
+/* $XConsortium: iplscrinit.c,v 5.32 94/04/17 20:29:00 dpw Exp $ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "servermd.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "resource.h"
+#include "colormap.h"
+#include "colormapst.h"
+#include "ipl.h"
+#include "mi.h"
+#include "mistruct.h"
+#include "dix.h"
+#include "mibstore.h"
+
+
+BSFuncRec iplBSFuncRec = {
+ iplSaveAreas,
+ iplRestoreAreas,
+ (BackingStoreSetClipmaskRgnProcPtr) 0,
+ (BackingStoreGetImagePixmapProcPtr) 0,
+ (BackingStoreGetSpansPixmapProcPtr) 0,
+};
+
+Bool
+iplCloseScreen (index, pScreen)
+ int index;
+ ScreenPtr pScreen;
+{
+ int d;
+ DepthPtr depths = pScreen->allowedDepths;
+
+ for (d = 0; d < pScreen->numDepths; d++)
+ xfree (depths[d].vids);
+ xfree (depths);
+ xfree (pScreen->visuals);
+#ifdef CFB_NEED_SCREEN_PRIVATE
+ xfree (pScreen->devPrivates[iplScreenPrivateIndex].ptr);
+#else
+ xfree (pScreen->devPrivate);
+#endif
+ return TRUE;
+}
+
+Bool
+iplSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width)
+ register ScreenPtr pScreen;
+ pointer pbits; /* pointer to screen bitmap */
+ int xsize, ysize; /* in pixels */
+ int dpix, dpiy; /* dots per inch */
+ int width; /* pixel width of frame buffer */
+{
+ int i;
+ extern RegionPtr (*iplPuntCopyPlane)();
+
+ if (!iplAllocatePrivates(pScreen, (int *) 0, (int *) 0))
+ return FALSE;
+ pScreen->defColormap = FakeClientID(0);
+ /* let CreateDefColormap do whatever it wants for pixels */
+ pScreen->blackPixel = pScreen->whitePixel = (Pixel) 0;
+ pScreen->QueryBestSize = mfbQueryBestSize;
+ /* SaveScreen */
+ pScreen->GetImage = iplGetImage;
+ pScreen->GetSpans = iplGetSpans;
+ pScreen->CreateWindow = iplCreateWindow;
+ pScreen->DestroyWindow = iplDestroyWindow;
+ pScreen->PositionWindow = iplPositionWindow;
+ pScreen->ChangeWindowAttributes = iplChangeWindowAttributes;
+ pScreen->RealizeWindow = iplMapWindow;
+ pScreen->UnrealizeWindow = iplUnmapWindow;
+ pScreen->PaintWindowBackground = iplPaintWindow;
+ pScreen->PaintWindowBorder = iplPaintWindow;
+ pScreen->CopyWindow = iplCopyWindow;
+ pScreen->CreatePixmap = iplCreatePixmap;
+ pScreen->DestroyPixmap = iplDestroyPixmap;
+ pScreen->RealizeFont = mfbRealizeFont;
+ pScreen->UnrealizeFont = mfbUnrealizeFont;
+ pScreen->CreateGC = iplCreateGC;
+ pScreen->CreateColormap = iplInitializeColormap;
+ pScreen->DestroyColormap = (void (*)())NoopDDA;
+ pScreen->InstallColormap = iplInstallColormap;
+ pScreen->UninstallColormap = iplUninstallColormap;
+ pScreen->ListInstalledColormaps = iplListInstalledColormaps;
+ pScreen->StoreColors = (void (*)())NoopDDA;
+ pScreen->ResolveColor = iplResolveColor;
+ pScreen->BitmapToRegion = mfbPixmapToRegion;
+
+ mfbRegisterCopyPlaneProc (pScreen, iplCopyPlane);
+ return TRUE;
+}
+
+#ifdef CFB_NEED_SCREEN_PRIVATE
+Bool
+iplCreateScreenResources(pScreen)
+ ScreenPtr pScreen;
+{
+ Bool retval;
+
+ pointer oldDevPrivate = pScreen->devPrivate;
+ pScreen->devPrivate = pScreen->devPrivates[iplScreenPrivateIndex].ptr;
+ retval = miCreateScreenResources(pScreen);
+ pScreen->devPrivates[iplScreenPrivateIndex].ptr = pScreen->devPrivate;
+ pScreen->devPrivate = oldDevPrivate;
+ return retval;
+}
+#endif
+
+Bool
+iplFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width)
+ register ScreenPtr pScreen;
+ pointer pbits; /* pointer to screen bitmap */
+ int xsize, ysize; /* in pixels */
+ int dpix, dpiy; /* dots per inch */
+ int width; /* pixel width of frame buffer */
+{
+ int i, j;
+#ifdef CFB_NEED_SCREEN_PRIVATE
+ pointer oldDevPrivate;
+#endif
+ VisualPtr visuals;
+ DepthPtr depths;
+ int nvisuals;
+ int ndepths;
+ int rootdepth;
+ VisualID defaultVisual;
+
+ rootdepth = 0;
+ if (!iplInitVisuals (&visuals, &depths, &nvisuals, &ndepths, &rootdepth,
+ &defaultVisual,((unsigned long)1<<(INTER_PLANES-1)), 8))
+ return FALSE;
+#ifdef CFB_NEED_SCREEN_PRIVATE
+ oldDevPrivate = pScreen->devPrivate;
+#endif
+ if (! miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
+ rootdepth, ndepths, depths,
+ defaultVisual, nvisuals, visuals))
+ return FALSE;
+ /* overwrite miCloseScreen with our own */
+ pScreen->CloseScreen = iplCloseScreen;
+#ifdef CFB_NEED_SCREEN_PRIVATE
+ pScreen->CreateScreenResources = iplCreateScreenResources;
+ pScreen->devPrivates[iplScreenPrivateIndex].ptr = pScreen->devPrivate;
+ pScreen->devPrivate = oldDevPrivate;
+#endif
+ pScreen->BackingStoreFuncs = iplBSFuncRec;
+ pScreen->GetScreenPixmap = iplGetScreenPixmap;
+ pScreen->SetScreenPixmap = iplSetScreenPixmap;
+ return TRUE;
+}
+
+/* dts * (inch/dot) * (25.4 mm / inch) = mm */
+Bool
+iplScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width)
+ register ScreenPtr pScreen;
+ pointer pbits; /* pointer to screen bitmap */
+ int xsize, ysize; /* in pixels */
+ int dpix, dpiy; /* dots per inch */
+ int width; /* pixel width of frame buffer */
+{
+ if (!iplSetupScreen(pScreen, pbits, xsize, ysize, dpix, dpiy, width))
+ return FALSE;
+ if (!iplFinishScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width))
+ return FALSE;
+#if INTER_PLANES == 2
+/* This shouldn't be necessary */
+ PixmapWidthPaddingInfo[2].padPixelsLog2 = 4;
+ PixmapWidthPaddingInfo[2].padRoundUp = 15;
+ PixmapWidthPaddingInfo[2].padBytesLog2 = 2;
+#endif
+ return TRUE;
+}
+
+PixmapPtr
+iplGetScreenPixmap(pScreen)
+ ScreenPtr pScreen;
+{
+#ifdef CFB_NEED_SCREEN_PRIVATE
+ return (PixmapPtr)(pScreen->devPrivates[iplScreenPrivateIndex].ptr);
+#else
+ return (PixmapPtr)(pScreen->devPrivate.ptr);
+#endif
+}
+
+void
+iplSetScreenPixmap(pPix)
+ PixmapPtr pPix;
+{
+#ifdef CFB_NEED_SCREEN_PRIVATE
+ if (pPix)
+ pPix->drawable.pScreen->devPrivates[iplScreenPrivateIndex].ptr =
+ (pointer)pPix;
+#else
+ if (pPix)
+ pPix->drawable.pScreen->devPrivate.ptr = (pointer)pPix;
+#endif
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplsetsp.c b/xc/programs/Xserver/iplan2p4/iplsetsp.c
new file mode 100644
index 000000000..0533eed71
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplsetsp.c
@@ -0,0 +1,300 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplsetsp.c,v 3.0 1996/08/18 01:55:07 dawes Exp $ */
+/* $XConsortium: iplsetsp.c,v 5.10 94/04/17 20:29:01 dpw Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "servermd.h"
+
+#include "misc.h"
+#include "regionstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+#include "ipl.h"
+
+#include "iplmskbits.h"
+#include "iplmergerop.h"
+#include "iplpack.h"
+
+/* iplSetScanline -- copies the bits from psrc to the drawable starting at
+ * (xStart, y) and continuing to (xEnd, y). xOrigin tells us where psrc
+ * starts on the scanline. (I.e., if this scanline passes through multiple
+ * boxes, we may not want to start grabbing bits at psrc but at some offset
+ * further on.)
+ */
+iplSetScanline(y, xOrigin, xStart, xEnd, psrc, alu, pdstBase, widthDst, planemask)
+ int y;
+ int xOrigin; /* where this scanline starts */
+ int xStart; /* first bit to use from scanline */
+ int xEnd; /* last bit to use from scanline + 1 */
+ register unsigned int *psrc;
+ register int alu; /* raster op */
+ INTER_DECLAREG(*pdstBase); /* start of the drawable */
+ int widthDst; /* width of drawable in groups */
+ unsigned long planemask;
+{
+ int w; /* width of scanline in bits */
+ INTER_DECLAREG(*pdst); /* where to put the bits */
+ INTER_DECLAREGP(tmpSrc); /* scratch buffer to collect bits in */
+ int dstBit; /* offset in bits from beginning of
+ * word */
+ register int nstart; /* number of bits from first partial */
+ register int nend; /* " " last partial word */
+ int offSrc;
+ INTER_DECLAREG(startmask);
+ INTER_DECLAREG(endmask);
+ int nlMiddle, nl, longs;
+ INTER_DECLAREG(*ipsrc);
+ INTER_DECLAREG(*tmppsrc);
+ INTER_DeclareMergeRop()
+
+ INTER_InitializeMergeRop(alu,planemask);
+
+ longs=NUM_LONGS(INTER_PLANES, xOrigin, xEnd);
+
+ tmppsrc = ipsrc = (unsigned short *)
+ ALLOCATE_LOCAL(NUM_TEMP_BYTES(INTER_PLANES,longs));
+
+ iplUnpackLine(INTER_PLANES, longs, psrc, ipsrc);
+
+ pdst = pdstBase + (y * widthDst) + (xStart >> INTER_PGSH) * INTER_PLANES;
+ offSrc = (xStart - xOrigin) & INTER_PIM;
+ w = xEnd - xStart;
+ dstBit = xStart & INTER_PIM;
+
+ ipsrc += ((xStart - xOrigin) >> INTER_PGSH) * INTER_PLANES;
+ if (dstBit + w <= INTER_PPG)
+ {
+ INTER_maskpartialbits(dstBit, w, startmask);
+ endmask = 0;
+ nlMiddle = 0;
+ }
+ else
+ {
+ INTER_maskbits(xStart, w, startmask, endmask, nlMiddle);
+ }
+ if (startmask)
+ nstart = INTER_PPG - dstBit;
+ else
+ nstart = 0;
+ if (endmask)
+ nend = xEnd & INTER_PIM;
+ else
+ nend = 0;
+ if (startmask)
+ {
+ INTER_getbits(ipsrc, offSrc, nstart, tmpSrc);
+ INTER_putbitsmropshort(tmpSrc, dstBit, nstart, pdst);
+ INTER_NEXT_GROUP(pdst);
+ offSrc += nstart;
+ if (offSrc > INTER_PLST)
+ {
+ INTER_NEXT_GROUP(ipsrc);
+ offSrc -= INTER_PPG;
+ }
+ }
+ nl = nlMiddle;
+ while (nl--)
+ {
+ INTER_getbits(ipsrc, offSrc, INTER_PPG, tmpSrc);
+ INTER_DoMergeRop(tmpSrc, pdst, pdst);
+ INTER_NEXT_GROUP(pdst);
+ INTER_NEXT_GROUP(ipsrc);
+ }
+ if (endmask)
+ {
+ INTER_getbits(ipsrc, offSrc, nend, tmpSrc);
+ INTER_putbitsmropshort(tmpSrc, 0, nend, pdst);
+ }
+ DEALLOCATE_LOCAL(tmppsrc);
+}
+
+
+
+/* SetSpans -- for each span copy pwidth[i] bits from psrc to pDrawable at
+ * ppt[i] using the raster op from the GC. If fSorted is TRUE, the scanlines
+ * are in increasing Y order.
+ * Source bit lines are server scanline padded so that they always begin
+ * on a word boundary.
+ */
+void
+iplSetSpans(pDrawable, pGC, pcharsrc, ppt, pwidth, nspans, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ char *pcharsrc;
+ register DDXPointPtr ppt;
+ int *pwidth;
+ int nspans;
+ int fSorted;
+{
+ unsigned int *psrc = (unsigned int *)pcharsrc;
+ INTER_DECLAREG(*pdstBase); /* start of dst bitmap */
+ int widthDst; /* width of bitmap in words */
+ register BoxPtr pbox, pboxLast, pboxTest;
+ register DDXPointPtr pptLast;
+ int alu;
+ RegionPtr prgnDst;
+ int xStart, xEnd;
+ int yMax;
+
+ alu = pGC->alu;
+ prgnDst = iplGetCompositeClip(pGC);
+ pptLast = ppt + nspans;
+
+ iplGetGroupWidthAndPointer (pDrawable, widthDst, pdstBase)
+
+ yMax = (int) pDrawable->y + (int) pDrawable->height;
+
+ pbox = REGION_RECTS(prgnDst);
+ pboxLast = pbox + REGION_NUM_RECTS(prgnDst);
+
+ if(fSorted)
+ {
+ /* scan lines sorted in ascending order. Because they are sorted, we
+ * don't have to check each scanline against each clip box. We can be
+ * sure that this scanline only has to be clipped to boxes at or after the
+ * beginning of this y-band
+ */
+ pboxTest = pbox;
+ while(ppt < pptLast)
+ {
+ pbox = pboxTest;
+ if(ppt->y >= yMax)
+ break;
+ while(pbox < pboxLast)
+ {
+ if(pbox->y1 > ppt->y)
+ {
+ /* scanline is before clip box */
+ break;
+ }
+ else if(pbox->y2 <= ppt->y)
+ {
+ /* clip box is before scanline */
+ pboxTest = ++pbox;
+ continue;
+ }
+ else if(pbox->x1 > ppt->x + *pwidth)
+ {
+ /* clip box is to right of scanline */
+ break;
+ }
+ else if(pbox->x2 <= ppt->x)
+ {
+ /* scanline is to right of clip box */
+ pbox++;
+ continue;
+ }
+
+ /* at least some of the scanline is in the current clip box */
+ xStart = max(pbox->x1, ppt->x);
+ xEnd = min(ppt->x + *pwidth, pbox->x2);
+ iplSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu,
+ pdstBase, widthDst, pGC->planemask);
+ if(ppt->x + *pwidth <= pbox->x2)
+ {
+ /* End of the line, as it were */
+ break;
+ }
+ else
+ pbox++;
+ }
+ /* We've tried this line against every box; it must be outside them
+ * all. move on to the next point */
+ ppt++;
+ psrc += PixmapWidthInPadUnits(*pwidth, pDrawable->depth);
+ pwidth++;
+ }
+ }
+ else
+ {
+ /* scan lines not sorted. We must clip each line against all the boxes */
+ while(ppt < pptLast)
+ {
+ if(ppt->y >= 0 && ppt->y < yMax)
+ {
+
+ for(pbox = REGION_RECTS(prgnDst); pbox< pboxLast; pbox++)
+ {
+ if(pbox->y1 > ppt->y)
+ {
+ /* rest of clip region is above this scanline,
+ * skip it */
+ break;
+ }
+ if(pbox->y2 <= ppt->y)
+ {
+ /* clip box is below scanline */
+ pbox++;
+ break;
+ }
+ if(pbox->x1 <= ppt->x + *pwidth &&
+ pbox->x2 > ppt->x)
+ {
+ xStart = max(pbox->x1, ppt->x);
+ xEnd = min(pbox->x2, ppt->x + *pwidth);
+ iplSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu,
+ pdstBase, widthDst, pGC->planemask);
+ }
+
+ }
+ }
+ psrc += PixmapWidthInPadUnits(*pwidth, pDrawable->depth);
+ ppt++;
+ pwidth++;
+ }
+ }
+}
+
diff --git a/xc/programs/Xserver/iplan2p4/iplsolid.c b/xc/programs/Xserver/iplan2p4/iplsolid.c
new file mode 100644
index 000000000..2f741ed7f
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplsolid.c
@@ -0,0 +1,217 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplsolid.c,v 3.1 1998/03/20 21:08:09 hohndel Exp $ */
+/*
+ * $XConsortium: iplsolid.c,v 1.9 94/04/17 20:29:02 dpw Exp $
+ *
+Copyright (c) 1990 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "servermd.h"
+#include "gcstruct.h"
+#include "window.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+
+#include "ipl.h"
+#include "iplrrop.h"
+
+#include "mi.h"
+#include "mispans.h"
+
+#include "iplmskbits.h"
+
+# define Expand(left, right, leftAdjust) { \
+ while (h--) { \
+ pdst = pdstRect; \
+ left \
+ m = nmiddle; \
+ INTER_RROP_SPAN(pdst, m); \
+ right \
+ pdstRect += widthDst; \
+ } \
+}
+
+
+void
+INTER_RROP_NAME(iplFillRectSolid) (pDrawable, pGC, nBox, pBox)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nBox;
+ BoxPtr pBox;
+{
+ register int m;
+ INTER_DECLAREG(*pdst);
+ INTER_RROP_DECLARE
+ INTER_DECLAREG(leftMask);
+ INTER_DECLAREG(rightMask);
+ INTER_DECLAREG(*pdstBase);
+ INTER_DECLAREG(*pdstRect);
+ int nmiddle;
+ int h;
+ int w;
+ int widthDst;
+
+ iplGetGroupWidthAndPointer (pDrawable, widthDst, pdstBase)
+
+ INTER_RROP_FETCH_GC(pGC)
+
+ for (; nBox; nBox--, pBox++)
+ {
+ pdstRect = pdstBase + pBox->y1 * widthDst;
+ h = pBox->y2 - pBox->y1;
+ w = pBox->x2 - pBox->x1;
+ pdstRect += (pBox->x1 >> INTER_PGSH) * INTER_PLANES;
+ if ((pBox->x1 & INTER_PIM) + w <= INTER_PPG)
+ {
+ INTER_maskpartialbits(pBox->x1, w, leftMask);
+ pdst = pdstRect;
+ while (h--) {
+ INTER_RROP_SOLID_MASK (pdst, leftMask);
+ pdst += widthDst;
+ }
+ }
+ else
+ {
+ INTER_maskbits (pBox->x1, w, leftMask, rightMask, nmiddle);
+ if (leftMask)
+ {
+ if (rightMask) /* left mask and right mask */
+ {
+ Expand(INTER_RROP_SOLID_MASK (pdst, leftMask);
+ INTER_NEXT_GROUP(pdst);,
+ INTER_RROP_SOLID_MASK (pdst, rightMask);, 1)
+ }
+ else /* left mask and no right mask */
+ {
+ Expand(INTER_RROP_SOLID_MASK (pdst, leftMask);
+ INTER_NEXT_GROUP(pdst);,
+ ;, 1)
+ }
+ }
+ else
+ {
+ if (rightMask) /* no left mask and right mask */
+ {
+ Expand(;,
+ INTER_RROP_SOLID_MASK (pdst, rightMask);, 0)
+ }
+ else /* no left mask and no right mask */
+ {
+ Expand(;,
+ ;, 0)
+ }
+ }
+ }
+ }
+}
+
+void
+INTER_RROP_NAME(iplSolidSpans) (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ INTER_DECLAREG(*pdstBase);
+ int widthDst;
+
+ INTER_RROP_DECLARE
+
+ INTER_DECLAREG(*pdst);
+ register int ngmiddle;
+ INTER_DECLAREG(startmask);
+ INTER_DECLAREG(endmask);
+ register int w;
+ int x;
+
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ DDXPointPtr ppt; /* pointer to list of start points */
+ int *pwidthFree;/* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ int *pwidth;
+ iplPrivGCPtr devPriv;
+
+ devPriv = iplGetGCPrivate(pGC);
+ INTER_RROP_FETCH_GCPRIV(devPriv)
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ iplGetGroupWidthAndPointer (pDrawable, widthDst, pdstBase)
+
+ while (n--)
+ {
+ x = ppt->x;
+ pdst = pdstBase + (ppt->y * widthDst);
+ ++ppt;
+ w = *pwidth++;
+ if (!w)
+ continue;
+ if ((x & INTER_PIM) + w <= INTER_PPG)
+ {
+ pdst += (x >> INTER_PGSH) * INTER_PLANES;
+ INTER_maskpartialbits (x, w, startmask);
+ INTER_RROP_SOLID_MASK (pdst, startmask);
+ }
+ else
+ {
+ pdst += (x >> INTER_PGSH) * INTER_PLANES;
+ INTER_maskbits (x, w, startmask, endmask, ngmiddle);
+ if (startmask)
+ {
+ INTER_RROP_SOLID_MASK (pdst, startmask);
+ INTER_NEXT_GROUP(pdst);
+ }
+
+ INTER_RROP_SPAN(pdst,ngmiddle);
+
+ if (endmask)
+ {
+ INTER_RROP_SOLID_MASK (pdst, endmask);
+ }
+ }
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
diff --git a/xc/programs/Xserver/iplan2p4/ipltegblt.c b/xc/programs/Xserver/iplan2p4/ipltegblt.c
new file mode 100644
index 000000000..4d82a655a
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/ipltegblt.c
@@ -0,0 +1,217 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/ipltegblt.c,v 3.0 1996/08/18 01:55:09 dawes Exp $ */
+/* $XConsortium: ipltegblt.c,v 5.9 94/04/17 20:29:03 dpw Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "ipl.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "mi.h"
+#define MFB_CONSTS_ONLY
+#include "maskbits.h"
+
+#include "iplmskbits.h"
+
+/*
+ this works for fonts with glyphs <= 32 bits wide, on an
+ arbitrarily deep display. Use iplTEGlyphBlt8 for 8 bit displays.
+
+ This should be called only with a terminal-emulator font;
+this means that the FIXED_METRICS flag is set, and that
+glyphbounds == charbounds.
+
+ in theory, this goes faster; even if it doesn't, it reduces the
+flicker caused by writing a string over itself with image text (since
+the background gets repainted per character instead of per string.)
+this seems to be important for some converted X10 applications.
+
+ Image text looks at the bits in the glyph and the fg and bg in the
+GC. it paints a rectangle, as defined in the protocol dcoument,
+and the paints the characters.
+
+*/
+
+void
+iplTEGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ pointer pglyphBase; /* start of array of glyphs */
+{
+ FontPtr pfont = pGC->font;
+ int widthDst;
+ INTER_DECLAREG(*pdstBase); /* pointer to group with top row
+ of current glyph */
+
+ int w; /* width of glyph and char */
+ int h; /* height of glyph and char */
+ register int xpos=x; /* current x%32 */
+ int ypos=y; /* current y%32 */
+ register unsigned char *pglyph;
+ int widthGlyph;
+
+ INTER_DECLAREG(*pdst); /* pointer to current group in dst */
+ int hTmp; /* counter for height */
+ BoxRec bbox; /* for clipping */
+
+ register int wtmp,xtemp,width;
+ INTER_DECLAREGP(bgfill);
+ INTER_DECLAREGP(fgfill);
+ unsigned long *ptemp;
+ INTER_DECLAREGP(tmpDst1);
+ INTER_DECLAREGP(tmpDst2);
+ INTER_DECLAREG(*pdtmp);
+ int tmpx;
+
+ xpos += pDrawable->x;
+ ypos += pDrawable->y;
+
+ iplGetGroupWidthAndPointer (pDrawable, widthDst, pdstBase)
+
+ wtmp = FONTMAXBOUNDS(pfont,characterWidth);
+ h = FONTASCENT(pfont) + FONTDESCENT(pfont);
+ widthGlyph = GLYPHWIDTHBYTESPADDED(*ppci);
+
+ xpos += FONTMAXBOUNDS(pfont,leftSideBearing);
+ ypos -= FONTASCENT(pfont);
+
+ bbox.x1 = xpos;
+ bbox.x2 = xpos + (wtmp * nglyph);
+ bbox.y1 = ypos;
+ bbox.y2 = ypos + h;
+
+ INTER_PFILL(pGC->fgPixel, fgfill);
+ INTER_PFILL(pGC->bgPixel, bgfill);
+
+ switch (RECT_IN_REGION(pGC->pScreen, iplGetCompositeClip(pGC), &bbox))
+ {
+ case rgnOUT:
+ break;
+ case rgnPART:
+ /* this is the WRONG thing to do, but it works.
+ calling the non-terminal text is easy, but slow, given
+ what we know about the font.
+
+ the right thing to do is something like:
+ for each clip rectangle
+ compute at which row the glyph starts to be in it,
+ and at which row the glyph ceases to be in it
+ compute which is the first glyph inside the left
+ edge, and the last one inside the right edge
+ draw a fractional first glyph, using only
+ the rows we know are in
+ draw all the whole glyphs, using the appropriate rows
+ draw any pieces of the last glyph, using the right rows
+
+ this way, the code would take advantage of knowing that
+ all glyphs are the same height and don't overlap.
+
+ one day...
+ */
+#if 1
+ miImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+#endif
+ break;
+ case rgnIN:
+
+ pdtmp = pdstBase + (widthDst * ypos);
+ while(nglyph--)
+ {
+
+ pglyph = FONTGLYPHBITS(pglyphBase, *ppci++);
+ pdst = pdtmp;
+ hTmp = h;
+
+ while (hTmp--)
+ {
+ x = xpos;
+ width = wtmp;
+ xtemp = 0;
+
+ while (width > 0)
+ {
+ tmpx = x & INTER_PIM;
+ w = min(width, INTER_PPG - tmpx);
+ /* w = min(w, (PGSZ - xtemp)); */
+
+ ptemp = (unsigned long *)(pglyph + (xtemp >> MFB_PWSH));
+#if 1
+ INTER_getstipplepixelsb(ptemp,xtemp,w,bgfill,fgfill,tmpDst1);
+#endif
+ {
+ INTER_DECLAREG(*pdsttmp) =
+ pdst + (x >> INTER_PGSH) * INTER_PLANES;
+#if 1
+ INTER_putbits(tmpDst1,tmpx,w,pdsttmp,pGC->planemask);
+#endif
+ }
+ x += w;
+ xtemp += w;
+ width -= w;
+ }
+ pglyph += widthGlyph;
+ pdst += widthDst;
+ }
+ xpos += wtmp;
+ }
+ break;
+ }
+}
diff --git a/xc/programs/Xserver/iplan2p4/ipltile32.c b/xc/programs/Xserver/iplan2p4/ipltile32.c
new file mode 100644
index 000000000..ea608effb
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/ipltile32.c
@@ -0,0 +1,268 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/ipltile32.c,v 3.1 1998/03/20 21:08:09 hohndel Exp $ */
+/*
+ * Fill 32 bit tiled rectangles. Used by both PolyFillRect and PaintWindow.
+ * no depth dependencies.
+ */
+
+/*
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+*/
+
+/* $XConsortium: ipltile32.c,v 1.8 94/04/17 20:29:05 dpw Exp $ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "servermd.h"
+#include "gcstruct.h"
+#include "window.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+
+#include "ipl.h"
+
+#include "mi.h"
+#include "mispans.h"
+
+#include "iplmskbits.h"
+#include "iplmergerop.h"
+
+#define STORE(p) INTER_MROP_PREBUILT_SOLID(srcpix, p, p)
+
+#define Expand(left,right) {\
+ while (h--) { \
+ INTER_COPY(psrc+srcy*INTER_PLANES, srcpix); \
+ INTER_MROP_PREBUILD(srcpix); \
+ ++srcy; \
+ if (srcy == tileHeight) \
+ srcy = 0; \
+ left \
+ ngw = ngwMiddle; \
+ while (ngw--) \
+ { \
+ STORE(p); \
+ INTER_NEXT_GROUP(p); \
+ } \
+ right \
+ p += ngwExtra; \
+ } \
+}
+
+void
+INTER_MROP_NAME(iplFillRectTile32) (pDrawable, pGC, nBox, pBox)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nBox; /* number of boxes to fill */
+ BoxPtr pBox; /* pointer to list of boxes to fill */
+{
+ INTER_DECLAREGP(srcpix);
+ INTER_DECLAREG(*psrc); /* pointer to bits in tile, if needed */
+ int tileHeight; /* height of the tile */
+
+ int ngwDst; /* width in longwords of the dest pixmap */
+ int w; /* width of current box */
+ register int h; /* height of current box */
+ INTER_DECLAREG(startmask);
+ INTER_DECLAREG(endmask); /* masks for reggedy bits at either end of line */
+ int ngwMiddle; /* number of longwords between sides of boxes */
+ int ngwExtra; /* to get from right of box to left of next span */
+ register int ngw; /* loop version of ngwMiddle */
+ INTER_DECLAREG(*p); /* pointer to bits we're writing */
+ int y; /* current scan line */
+ int srcy; /* current tile position */
+
+ INTER_DECLAREG(*pbits); /* pointer to start of pixmap */
+ PixmapPtr tile; /* rotated, expanded tile */
+ INTER_MROP_DECLARE_REG()
+ INTER_MROP_PREBUILT_DECLARE()
+
+ tile = pGC->pRotatedPixmap;
+ tileHeight = tile->drawable.height;
+ psrc = (unsigned short *)tile->devPrivate.ptr;
+
+ INTER_MROP_INITIALIZE(pGC->alu, pGC->planemask);
+
+ iplGetGroupWidthAndPointer (pDrawable, ngwDst, pbits)
+
+ while (nBox--)
+ {
+ w = pBox->x2 - pBox->x1;
+ h = pBox->y2 - pBox->y1;
+ y = pBox->y1;
+ p = pbits + (y * ngwDst) + (pBox->x1 >> INTER_PGSH) * INTER_PLANES;
+ srcy = y % tileHeight;
+
+ if ( ((pBox->x1 & INTER_PIM) + w) <= INTER_PPG)
+ {
+ INTER_maskpartialbits(pBox->x1, w, startmask);
+ ngwExtra = ngwDst;
+ while (h--)
+ {
+ INTER_COPY(psrc+srcy*INTER_PLANES, srcpix);
+ INTER_MROP_PREBUILD(srcpix);
+ ++srcy;
+ if (srcy == tileHeight)
+ srcy = 0;
+ INTER_MROP_PREBUILT_MASK(srcpix, p, startmask, p);
+ p += ngwExtra;
+ }
+ }
+ else
+ {
+ INTER_maskbits(pBox->x1, w, startmask, endmask, ngwMiddle);
+ ngwExtra = ngwDst - ngwMiddle * INTER_PLANES;
+
+ if (startmask)
+ {
+ ngwExtra -= INTER_PLANES;
+ if (endmask)
+ {
+ Expand(
+ INTER_MROP_PREBUILT_MASK(srcpix, p, startmask, p);
+ INTER_NEXT_GROUP(p);,
+ INTER_MROP_PREBUILT_MASK(srcpix, p, endmask, p));
+ }
+ else
+ {
+ Expand(
+ INTER_MROP_PREBUILT_MASK(srcpix, p, startmask, p);
+ INTER_NEXT_GROUP(p);,
+ ;)
+ }
+ }
+ else
+ {
+ if (endmask)
+ {
+ Expand(;,
+ INTER_MROP_PREBUILT_MASK(srcpix, p, endmask, p));
+ }
+ else
+ {
+ Expand(;,
+ ;)
+ }
+ }
+ }
+ pBox++;
+ }
+}
+
+void
+INTER_MROP_NAME(iplTile32FS)(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ DDXPointPtr ppt; /* pointer to list of start points */
+ int *pwidth;/* pointer to list of n widths */
+ INTER_DECLAREG(*pbits); /* pointer to start of bitmap */
+ int ngwDst; /* width in longwords of bitmap */
+ INTER_DECLAREG(*p); /* pointer to current longword in bitmap */
+ register int w; /* current span width */
+ register int ngw;
+ register int x;
+ INTER_DECLAREG(startmask);
+ INTER_DECLAREG(endmask);
+ INTER_DECLAREGP(srcpix);
+ int y;
+ int *pwidthFree;/* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ PixmapPtr tile;
+ INTER_DECLAREG(*psrc); /* pointer to bits in tile */
+ int tileHeight;/* height of the tile */
+ INTER_MROP_DECLARE_REG ()
+ INTER_MROP_PREBUILT_DECLARE()
+
+ n = nInit * miFindMaxBand( iplGetCompositeClip(pGC) );
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans( iplGetCompositeClip(pGC),
+ pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ tile = pGC->pRotatedPixmap;
+ tileHeight = tile->drawable.height;
+ psrc = (unsigned short *)tile->devPrivate.ptr;
+
+ INTER_MROP_INITIALIZE(pGC->alu, pGC->planemask);
+
+ iplGetGroupWidthAndPointer (pDrawable, ngwDst, pbits)
+
+ {
+ while (n--)
+ {
+ x = ppt->x;
+ y = ppt->y;
+ ++ppt;
+ w = *pwidth++;
+ p = pbits + (y * ngwDst) + (x >> INTER_PGSH) * INTER_PLANES;
+ INTER_COPY(psrc +(y % tileHeight)*INTER_PLANES,srcpix);
+ INTER_MROP_PREBUILD(srcpix);
+
+ if ((x & INTER_PIM) + w < INTER_PPG)
+ {
+ INTER_maskpartialbits(x, w, startmask);
+ INTER_MROP_PREBUILT_MASK(srcpix, p, startmask, p);
+ }
+ else
+ {
+ INTER_maskbits(x, w, startmask, endmask, ngw);
+ if (startmask)
+ {
+ INTER_MROP_PREBUILT_MASK(srcpix, p, startmask, p);
+ INTER_NEXT_GROUP(p);
+ }
+ while (ngw--)
+ {
+ STORE(p);
+ INTER_NEXT_GROUP(p);
+ }
+ if (endmask)
+ {
+ INTER_MROP_PREBUILT_MASK(srcpix, p, endmask, p);
+ }
+ }
+ }
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
diff --git a/xc/programs/Xserver/iplan2p4/ipltileodd.c b/xc/programs/Xserver/iplan2p4/ipltileodd.c
new file mode 100644
index 000000000..a63ce5da6
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/ipltileodd.c
@@ -0,0 +1,865 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/ipltileodd.c,v 3.0 1996/08/18 01:55:11 dawes Exp $ */
+/*
+ * Fill odd tiled rectangles and spans.
+ * no depth dependencies.
+ */
+
+/*
+
+Copyright (c) 1989 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+*/
+
+/* $XConsortium: ipltileodd.c,v 1.16 94/04/17 20:29:06 dpw Exp $ */
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "Xmd.h"
+#include "servermd.h"
+#include "gcstruct.h"
+#include "window.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+
+#include "ipl.h"
+
+#include "iplmskbits.h"
+#include "iplmergerop.h"
+
+#define LEFTSHIFT_AMT 0
+
+#define LastTileBits {\
+ INTER_COPY(bits, tmp); \
+ if (tileEndPart) \
+ INTER_MSKINSM(tileEndMask, 0, pSrc, \
+ ~0, tileEndLeftShift, pSrcLine, bits) \
+ else \
+ INTER_COPY(pSrc, bits); \
+}
+
+#define ResetTileBits {\
+ pSrc = pSrcLine; \
+ nlwSrc = widthSrc;\
+ if (tileEndPart) { \
+ if (INTER_PPG - xoff + tileEndPart <= INTER_PPG) {\
+ INTER_COPY(pSrc, bits); INTER_NEXT_GROUP(pSrc); \
+ nlwSrc--; \
+ } else \
+ INTER_MSKINSM(~0, tileEndLeftShift, tmp, \
+ ~0, tileEndRightShift, bits, bits); \
+ xoff = (xoff + xoffStep) & INTER_PIM; \
+ leftShift = xoff << LEFTSHIFT_AMT; \
+ rightShift = INTER_PGSZ - leftShift; \
+ }\
+}
+
+#define NextTileBits {\
+ if (nlwSrc == 1) {\
+ LastTileBits\
+ } else { \
+ if (nlwSrc == 0) {\
+ ResetTileBits\
+ } \
+ if (nlwSrc == 1) {\
+ LastTileBits\
+ } else {\
+ INTER_COPY(bits, tmp); \
+ INTER_COPY(pSrc, bits); INTER_NEXT_GROUP(pSrc); \
+ }\
+ }\
+ nlwSrc--; \
+}
+
+void
+INTER_MROP_NAME(iplFillBoxTileOdd) (pDrawable, nBox, pBox, tile, xrot, yrot, alu, planemask)
+ DrawablePtr pDrawable;
+ int nBox; /* number of boxes to fill */
+ register BoxPtr pBox; /* pointer to list of boxes to fill */
+ PixmapPtr tile; /* tile */
+ int xrot, yrot;
+ int alu;
+ unsigned long planemask;
+{
+ int tileWidth; /* width of tile in pixels */
+ int tileHeight; /* height of the tile */
+ int widthSrc;
+
+ int widthDst; /* width in longwords of the dest pixmap */
+ int w; /* width of current box */
+ int h; /* height of current box */
+ INTER_DECLAREG(startmask);
+ INTER_DECLAREG(endmask);/* masks for reggedy bits at either end of line */
+ int nlwMiddle; /* number of longwords between sides of boxes */
+ int nlwSrc; /* number of whole longwords in source */
+
+ register int nlw; /* loop version of nlwMiddle */
+ int srcy; /* current tile y position */
+ int srcx; /* current tile x position */
+ int xoffDst, xoffSrc;
+ int leftShift, rightShift;
+
+ INTER_MROP_DECLARE_REG()
+
+ INTER_DECLAREG(*pDstBase); /* pointer to start of dest */
+ INTER_DECLAREG(*pDstLine); /* poitner to start of dest box */
+ INTER_DECLAREG(*pSrcBase); /* pointer to start of source */
+ INTER_DECLAREG(*pSrcLine); /* pointer to start of source line */
+ INTER_DECLAREG(*pDst);
+ INTER_DECLAREG(*pSrc);
+ INTER_DECLAREGP(bits);
+ INTER_DECLAREGP(tmp);
+ INTER_DECLAREGP(tmp1);
+ register int nlwPart;
+ int xoffStart, xoff;
+ int leftShiftStart, rightShiftStart, nlwSrcStart;
+ INTER_DECLAREG(tileEndMask);
+ int tileEndLeftShift, tileEndRightShift;
+ int xoffStep;
+ int tileEndPart;
+ int needFirst;
+ unsigned short narrow[2 * INTER_PLANES];
+ INTER_DECLAREG(narrowMask);
+ int narrowShift;
+ Bool narrowTile;
+ int narrowRep;
+
+ INTER_MROP_INITIALIZE (alu, planemask)
+
+ tileHeight = tile->drawable.height;
+ tileWidth = tile->drawable.width;
+ widthSrc = tile->devKind / (INTER_PGSZB * INTER_PLANES);
+ narrowTile = FALSE;
+
+ if (widthSrc == 1)
+ {
+ narrowRep = INTER_PPG / tileWidth;
+ narrowMask = iplendpartial [tileWidth];
+ tileWidth *= narrowRep;
+ narrowShift = tileWidth;
+ tileWidth *= 2;
+ widthSrc = 2;
+ narrowTile = TRUE;
+ }
+ pSrcBase = (unsigned short *)tile->devPrivate.ptr;
+
+ iplGetGroupWidthAndPointer (pDrawable, widthDst, pDstBase)
+
+ tileEndPart = tileWidth & INTER_PIM;
+ tileEndMask = iplendpartial[tileEndPart];
+ tileEndLeftShift = (tileEndPart) << LEFTSHIFT_AMT;
+ tileEndRightShift = INTER_PGSZ - tileEndLeftShift;
+ xoffStep = INTER_PPG - tileEndPart;
+ /*
+ * current assumptions: tile > 32 bits wide.
+ */
+ while (nBox--)
+ {
+ w = pBox->x2 - pBox->x1;
+ h = pBox->y2 - pBox->y1;
+ modulus (pBox->x1 - xrot, tileWidth, srcx);
+ modulus (pBox->y1 - yrot, tileHeight, srcy);
+ xoffDst = pBox->x1 & INTER_PIM;
+ if (xoffDst + w < INTER_PPG)
+ {
+ INTER_maskpartialbits(pBox->x1, w, startmask);
+ endmask = 0;
+ nlwMiddle = 0;
+ }
+ else
+ {
+ INTER_maskbits (pBox->x1, w, startmask, endmask, nlwMiddle)
+ }
+ pDstLine = pDstBase + (pBox->y1 * widthDst) +
+ (pBox->x1 >> INTER_PGSH) * INTER_PLANES;
+ pSrcLine = pSrcBase + (srcy * widthSrc) * INTER_PLANES;
+ xoffSrc = srcx & INTER_PIM;
+ if (xoffSrc >= xoffDst)
+ {
+ xoffStart = xoffSrc - xoffDst;
+ needFirst = 1;
+ }
+ else
+ {
+ xoffStart = INTER_PPG - (xoffDst - xoffSrc);
+ needFirst = 0;
+ }
+ leftShiftStart = (xoffStart) << LEFTSHIFT_AMT;
+ rightShiftStart = INTER_PGSZ - leftShiftStart;
+ nlwSrcStart = (widthSrc - (srcx >> INTER_PGSH));
+ while (h--)
+ {
+ /* XXX only works when narrowShift >= INTER_PPG/2 */
+ if (narrowTile)
+ {
+ int tmpnarrowRep;
+ int shift=narrowShift/narrowRep;
+ INTER_ANDMSK(pSrcBase + srcy * INTER_PLANES, narrowMask, tmp);
+ tmpnarrowRep=narrowRep;
+ /* copy tile until its nearly a whole group wide */
+ while (--tmpnarrowRep)
+ INTER_MSKINSM(~0,0,tmp,~0,shift,tmp,tmp);
+ INTER_MSKINSM(~0, 0, tmp, ~0, narrowShift, tmp, narrow);
+ INTER_MSKINSM(~0, INTER_PPG - narrowShift, tmp,
+ ~0, 2 * narrowShift - INTER_PPG, tmp,
+ narrow + INTER_PLANES);
+ pSrcLine = narrow;
+ }
+ xoff = xoffStart;
+ leftShift = leftShiftStart;
+ rightShift = rightShiftStart;
+ nlwSrc = nlwSrcStart;
+ pSrc = pSrcLine + (srcx >> INTER_PGSH) * INTER_PLANES;
+ pDst = pDstLine;
+ INTER_CLR(bits);
+ if (needFirst)
+ {
+ NextTileBits
+ }
+ if (startmask)
+ {
+ NextTileBits
+ INTER_SCRLEFT(leftShift, tmp, tmp);
+ if (rightShift != INTER_PGSZ)
+ INTER_MSKINSM(~0, 0, tmp, ~0, rightShift, bits, tmp)
+ INTER_MROP_MASK (tmp, pDst, startmask, pDst);
+ INTER_NEXT_GROUP(pDst);
+ }
+ nlw = nlwMiddle;
+ while (nlw)
+ {
+ {
+ NextTileBits
+ if (rightShift != INTER_PGSZ)
+ {
+ INTER_MSKINSM(~0, leftShift, tmp, ~0, rightShift, bits,
+ tmp1);
+ INTER_MROP_SOLID(tmp1, pDst, pDst);
+ }
+ else
+ {
+ INTER_MROP_SOLID (tmp, pDst, pDst);
+ }
+ INTER_NEXT_GROUP(pDst);
+ nlw--;
+ }
+ }
+ if (endmask)
+ {
+ NextTileBits
+ if (rightShift == INTER_PGSZ)
+ INTER_CLR(bits);
+ INTER_MSKINSM(~0, leftShift, tmp, ~0, rightShift, bits, tmp1);
+ INTER_MROP_MASK(tmp1, pDst, endmask, pDst);
+ }
+ pDstLine += widthDst;
+ pSrcLine += widthSrc * INTER_PLANES;
+ if (++srcy == tileHeight)
+ {
+ srcy = 0;
+ pSrcLine = pSrcBase;
+ }
+ }
+ pBox++;
+ }
+}
+
+void
+INTER_MROP_NAME(iplFillSpanTileOdd) (pDrawable, n, ppt, pwidth, tile, xrot, yrot, alu, planemask)
+ DrawablePtr pDrawable;
+ int n;
+ DDXPointPtr ppt;
+ int *pwidth;
+ PixmapPtr tile;
+ int xrot, yrot;
+ int alu;
+ unsigned long planemask;
+{
+ int tileWidth; /* width of tile in pixels */
+ int tileHeight; /* height of the tile */
+ int widthSrc;
+
+ int widthDst; /* width in longwords of the dest pixmap */
+ int w; /* width of current span */
+ INTER_DECLAREG(startmask);
+ INTER_DECLAREG (endmask); /* masks for reggedy bits at either end of line */
+ int nlwSrc; /* number of whole longwords in source */
+
+ register int nlw; /* loop version of nlwMiddle */
+ int srcy; /* current tile y position */
+ int srcx; /* current tile x position */
+ int xoffDst, xoffSrc;
+ int leftShift, rightShift;
+
+ INTER_MROP_DECLARE_REG()
+
+ INTER_DECLAREG(*pDstBase); /* pointer to start of dest */
+ INTER_DECLAREG(*pDstLine); /* poitner to start of dest box */
+ INTER_DECLAREG(*pSrcBase); /* pointer to start of source */
+ INTER_DECLAREG(*pSrcLine); /* pointer to start of source line */
+ INTER_DECLAREG(*pDst);
+ INTER_DECLAREG(*pSrc);
+ INTER_DECLAREGP(bits);
+ INTER_DECLAREGP(tmp);
+ INTER_DECLAREGP(tmp1);
+ register int nlwPart;
+ int xoffStart, xoff;
+ int leftShiftStart, rightShiftStart, nlwSrcStart;
+ INTER_DECLAREG(tileEndMask);
+ int tileEndLeftShift, tileEndRightShift;
+ int xoffStep;
+ int tileEndPart;
+ int needFirst;
+ unsigned short narrow[2 * INTER_PLANES];
+ INTER_DECLAREG(narrowMask);
+ int narrowShift;
+ Bool narrowTile;
+ int narrowRep;
+
+ INTER_MROP_INITIALIZE (alu, planemask)
+
+ tileHeight = tile->drawable.height;
+ tileWidth = tile->drawable.width;
+ widthSrc = tile->devKind / (INTER_PGSZB * INTER_PLANES);
+ narrowTile = FALSE;
+ if (widthSrc == 1)
+ {
+ narrowRep = INTER_PPG / tileWidth;
+ narrowMask = iplendpartial [tileWidth];
+ tileWidth *= narrowRep;
+ narrowShift = tileWidth;
+ tileWidth *= 2;
+ widthSrc = 2;
+ narrowTile = TRUE;
+ }
+ pSrcBase = (unsigned short *)tile->devPrivate.ptr;
+
+ iplGetGroupWidthAndPointer (pDrawable, widthDst, pDstBase)
+
+ tileEndPart = tileWidth & INTER_PIM;
+ tileEndMask = iplendpartial[tileEndPart];
+ tileEndLeftShift = (tileEndPart) << LEFTSHIFT_AMT;
+ tileEndRightShift = INTER_PGSZ - tileEndLeftShift;
+ xoffStep = INTER_PPG - tileEndPart;
+ while (n--)
+ {
+ w = *pwidth++;
+ modulus (ppt->x - xrot, tileWidth, srcx);
+ modulus (ppt->y - yrot, tileHeight, srcy);
+ xoffDst = ppt->x & INTER_PIM;
+ if (xoffDst + w < INTER_PPG)
+ {
+ INTER_maskpartialbits(ppt->x, w, startmask);
+ endmask = 0;
+ nlw = 0;
+ }
+ else
+ {
+ INTER_maskbits (ppt->x, w, startmask, endmask, nlw)
+ }
+ pDstLine = pDstBase + (ppt->y * widthDst) +
+ (ppt->x >> INTER_PGSH) * INTER_PLANES;
+ pSrcLine = pSrcBase + (srcy * widthSrc) * INTER_PLANES;
+ xoffSrc = srcx & INTER_PIM;
+ if (xoffSrc >= xoffDst)
+ {
+ xoffStart = xoffSrc - xoffDst;
+ needFirst = 1;
+ }
+ else
+ {
+ xoffStart = INTER_PPG - (xoffDst - xoffSrc);
+ needFirst = 0;
+ }
+ leftShiftStart = (xoffStart) << LEFTSHIFT_AMT;
+ rightShiftStart = INTER_PGSZ - leftShiftStart;
+ nlwSrcStart = widthSrc - (srcx >> INTER_PGSH);
+ /* XXX only works when narrowShift >= INTER_PPG/2 */
+ if (narrowTile)
+ {
+ int tmpnarrowRep;
+ int shift=narrowShift/narrowRep;
+ INTER_ANDMSK(pSrcBase + srcy * INTER_PLANES, narrowMask, tmp);
+ tmpnarrowRep=narrowRep;
+ /* copy tile until its nearly a whole group wide */
+ while (--tmpnarrowRep)
+ INTER_MSKINSM(~0,0,tmp,~0,shift,tmp,tmp);
+ INTER_MSKINSM(~0, 0, tmp, ~0, narrowShift, tmp, narrow);
+ INTER_MSKINSM(~0, INTER_PPG - narrowShift, tmp,
+ ~0, 2 * narrowShift - INTER_PPG, tmp,
+ narrow + INTER_PLANES);
+ pSrcLine = narrow;
+ }
+ xoff = xoffStart;
+ leftShift = leftShiftStart;
+ rightShift = rightShiftStart;
+ nlwSrc = nlwSrcStart;
+ pSrc = pSrcLine + (srcx >> INTER_PGSH) * INTER_PLANES;
+ pDst = pDstLine;
+ INTER_CLR(bits);
+ if (needFirst)
+ {
+ NextTileBits
+ }
+ if (startmask)
+ {
+ NextTileBits
+ INTER_SCRLEFT(leftShift, tmp, tmp);
+ if (rightShift != INTER_PGSZ)
+ INTER_MSKINSM(~0, 0, tmp, ~0, rightShift, bits, tmp);
+ INTER_MROP_MASK (tmp, pDst, startmask, pDst);
+ INTER_NEXT_GROUP(pDst);
+ }
+ while (nlw)
+ {
+ {
+ NextTileBits
+ if (rightShift != INTER_PGSZ)
+ {
+ INTER_MSKINSM(~0, leftShift, tmp, ~0, rightShift, bits,
+ tmp1);
+ INTER_MROP_SOLID(tmp1, pDst, pDst);
+ INTER_NEXT_GROUP(pDst);
+ }
+ else
+ {
+ INTER_MROP_SOLID (tmp, pDst, pDst);
+ INTER_NEXT_GROUP(pDst);
+ }
+ nlw--;
+ }
+ }
+ if (endmask)
+ {
+ NextTileBits
+ if (rightShift == INTER_PGSZ)
+ INTER_CLR(bits);
+
+ INTER_MSKINSM(~0, leftShift, tmp, ~0, rightShift, bits, tmp1);
+ INTER_MROP_MASK(tmp1, pDst, endmask, pDst);
+ }
+ ppt++;
+ }
+}
+
+# include "fastblt.h"
+
+#define IncSrcPtr INTER_NEXT_GROUP(psrc); if (!--srcRemaining) { srcRemaining = widthSrc; psrc = psrcStart; }
+
+void
+INTER_MROP_NAME(iplFillBoxTile32s) (pDrawable, nBox, pBox, tile, xrot, yrot, alu, planemask)
+ DrawablePtr pDrawable;
+ int nBox; /* number of boxes to fill */
+ register BoxPtr pBox; /* pointer to list of boxes to fill */
+ PixmapPtr tile; /* tile */
+ int xrot, yrot;
+ int alu;
+ unsigned long planemask;
+{
+ int tileWidth; /* width of tile */
+ int tileHeight; /* height of the tile */
+ int widthSrc; /* width in longwords of the source tile */
+
+ int widthDst; /* width in longwords of the dest pixmap */
+ int w; /* width of current box */
+ int h; /* height of current box */
+ INTER_DECLAREG(startmask);
+ INTER_DECLAREG(endmask); /* masks for reggedy bits at either end of line */
+ int nlMiddle; /* number of longwords between sides of boxes */
+
+ register int nl; /* loop version of nlMiddle */
+ int srcy; /* current tile y position */
+ int srcx; /* current tile x position */
+ int srcRemaining; /* number of longwords remaining in source */
+ int xoffDst, xoffSrc;
+ int srcStart; /* number of longwords source offset at left of box */
+ int leftShift, rightShift;
+
+ INTER_MROP_DECLARE_REG()
+
+ INTER_DECLAREG(*pdstBase); /* pointer to start of dest */
+ INTER_DECLAREG(*pdstLine); /* poitner to start of dest box */
+ INTER_DECLAREG(*psrcBase); /* pointer to start of source */
+ INTER_DECLAREG(*psrcLine); /* pointer to fetch point of source */
+ INTER_DECLAREG(*psrcStart); /* pointer to start of source line */
+ INTER_DECLAREG(*pdst);
+ INTER_DECLAREG(*psrc);
+ INTER_DECLAREGP(bits);
+ INTER_DECLAREGP(bits1);
+ register int nlTemp;
+
+ INTER_MROP_INITIALIZE (alu, planemask)
+
+ psrcBase = (unsigned short *)tile->devPrivate.ptr;
+ tileHeight = tile->drawable.height;
+ tileWidth = tile->drawable.width;
+ widthSrc = tile->devKind / (INTER_PGSZB * INTER_PLANES);
+
+ iplGetGroupWidthAndPointer (pDrawable, widthDst, pdstBase)
+
+ while (nBox--)
+ {
+ w = pBox->x2 - pBox->x1;
+ h = pBox->y2 - pBox->y1;
+
+ /* set up source */
+ modulus (pBox->x1 - xrot, tileWidth, srcx);
+ modulus (pBox->y1 - yrot, tileHeight, srcy);
+ xoffSrc = srcx & INTER_PIM;
+ srcStart = srcx >> INTER_PGSH;
+ psrcStart = psrcBase + (srcy * widthSrc) * INTER_PLANES;
+ psrcLine = psrcStart + srcStart * INTER_PLANES;
+
+ /* set up dest */
+ xoffDst = pBox->x1 & INTER_PIM;
+ pdstLine = pdstBase + (pBox->y1 * widthDst) +
+ (pBox->x1 >> INTER_PGSH) * INTER_PLANES;
+ /* set up masks */
+ if (xoffDst + w < INTER_PPG)
+ {
+ INTER_maskpartialbits(pBox->x1, w, startmask);
+ endmask = 0;
+ nlMiddle = 0;
+ }
+ else
+ {
+ INTER_maskbits (pBox->x1, w, startmask, endmask, nlMiddle)
+ }
+ if (xoffSrc == xoffDst)
+ {
+ while (h--)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ srcRemaining = widthSrc - srcStart;
+ if (startmask)
+ {
+ INTER_MROP_MASK (psrc, pdst, startmask, pdst);
+ INTER_NEXT_GROUP(pdst);
+ IncSrcPtr
+ }
+ nlTemp = nlMiddle;
+ while (nlTemp)
+ {
+ nl = nlTemp;
+ if (nl > srcRemaining)
+ nl = srcRemaining;
+
+ nlTemp -= nl;
+ srcRemaining -= nl;
+
+ while (nl--) {
+ INTER_MROP_SOLID (psrc, pdst, pdst);
+ INTER_NEXT_GROUP(pdst); INTER_NEXT_GROUP(psrc);
+ }
+
+ if (!srcRemaining)
+ {
+ srcRemaining = widthSrc;
+ psrc = psrcStart;
+ }
+ }
+ if (endmask)
+ {
+ INTER_MROP_MASK (psrc, pdst, endmask, pdst);
+ }
+ pdstLine += widthDst;
+ psrcLine += widthSrc * INTER_PLANES;
+ psrcStart += widthSrc * INTER_PLANES;
+ if (++srcy == tileHeight)
+ {
+ psrcStart = psrcBase;
+ psrcLine = psrcStart + srcStart * INTER_PLANES;
+ srcy = 0;
+ }
+ }
+ }
+ else
+ {
+ if (xoffSrc > xoffDst)
+ {
+ leftShift = (xoffSrc - xoffDst) << LEFTSHIFT_AMT;
+ rightShift = INTER_PGSZ - leftShift;
+ }
+ else
+ {
+ rightShift = (xoffDst - xoffSrc) << LEFTSHIFT_AMT;
+ leftShift = INTER_PGSZ - rightShift;
+ }
+ while (h--)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ INTER_CLR(bits);
+ srcRemaining = widthSrc - srcStart;
+ if (xoffSrc > xoffDst)
+ {
+ INTER_COPY(psrc, bits);
+ IncSrcPtr
+ }
+ if (startmask)
+ {
+ INTER_SCRLEFT(leftShift, bits, bits1);
+ INTER_COPY(psrc, bits);
+ IncSrcPtr
+ INTER_MSKINSM(~0, 0, bits1, ~0, rightShift, bits, bits1);
+ INTER_MROP_MASK(bits1, pdst, startmask, pdst);
+ INTER_NEXT_GROUP(pdst);
+ }
+ nlTemp = nlMiddle;
+ while (nlTemp)
+ {
+ nl = nlTemp;
+ if (nl > srcRemaining)
+ nl = srcRemaining;
+
+ nlTemp -= nl;
+ srcRemaining -= nl;
+
+ while (nl--) {
+ INTER_SCRLEFT(leftShift, bits, bits1);
+ INTER_COPY(psrc, bits); INTER_NEXT_GROUP(psrc);
+ INTER_MSKINSM(~0, 0, bits1, ~0, rightShift, bits, bits1);
+ INTER_MROP_SOLID (bits1, pdst, pdst);
+ INTER_NEXT_GROUP(pdst);
+ }
+
+ if (!srcRemaining)
+ {
+ srcRemaining = widthSrc;
+ psrc = psrcStart;
+ }
+ }
+
+ if (endmask)
+ {
+ INTER_SCRLEFT(leftShift, bits, bits1);
+ if (endmask << rightShift)
+ {
+ INTER_COPY(psrc, bits);
+ INTER_MSKINSM(~0, 0, bits1, ~0, rightShift, bits, bits1);
+ }
+ INTER_MROP_MASK (bits1, pdst, endmask, pdst);
+ }
+ pdstLine += widthDst;
+ psrcLine += widthSrc * INTER_PLANES;
+ psrcStart += widthSrc * INTER_PLANES;
+ if (++srcy == tileHeight)
+ {
+ psrcStart = psrcBase;
+ psrcLine = psrcStart + srcStart * INTER_PLANES;
+ srcy = 0;
+ }
+ }
+ }
+ pBox++;
+ }
+}
+
+void
+INTER_MROP_NAME(iplFillSpanTile32s) (pDrawable, n, ppt, pwidth, tile, xrot, yrot, alu, planemask)
+ DrawablePtr pDrawable;
+ int n;
+ DDXPointPtr ppt;
+ int *pwidth;
+ PixmapPtr tile;
+ int xrot, yrot;
+ int alu;
+ unsigned long planemask;
+{
+ int tileWidth; /* width of tile */
+ int tileHeight; /* height of the tile */
+ int widthSrc; /* width in longwords of the source tile */
+
+ int widthDst; /* width in longwords of the dest pixmap */
+ int w; /* width of current box */
+ INTER_DECLAREG(startmask);
+ INTER_DECLAREG(endmask);/* masks for reggedy bits at either end of line */
+ int nlMiddle; /* number of longwords between sides of boxes */
+
+ register int nl; /* loop version of nlMiddle */
+ int srcy; /* current tile y position */
+ int srcx; /* current tile x position */
+ int srcRemaining; /* number of longwords remaining in source */
+ int xoffDst, xoffSrc;
+ int srcStart; /* number of longwords source offset at left of box */
+ int leftShift, rightShift;
+
+ INTER_MROP_DECLARE_REG()
+
+ INTER_DECLAREG(*pdstBase); /* pointer to start of dest */
+ INTER_DECLAREG(*pdstLine); /* poitner to start of dest box */
+ INTER_DECLAREG(*psrcBase); /* pointer to start of source */
+ INTER_DECLAREG(*psrcLine); /* pointer to fetch point of source */
+ INTER_DECLAREG(*psrcStart); /* pointer to start of source line */
+ INTER_DECLAREG(*pdst);
+ INTER_DECLAREG(*psrc);
+ INTER_DECLAREGP(bits);
+ INTER_DECLAREGP(bits1);
+ register int nlTemp;
+
+ INTER_MROP_INITIALIZE (alu, planemask)
+
+ psrcBase = (unsigned short *)tile->devPrivate.ptr;
+ tileHeight = tile->drawable.height;
+ tileWidth = tile->drawable.width;
+ widthSrc = tile->devKind / (INTER_PGSZB * INTER_PLANES);
+
+ iplGetGroupWidthAndPointer (pDrawable, widthDst, pdstBase)
+
+ while (n--)
+ {
+ w = *pwidth++;
+
+ /* set up source */
+ modulus (ppt->x - xrot, tileWidth, srcx);
+ modulus (ppt->y - yrot, tileHeight, srcy);
+ xoffSrc = srcx & INTER_PIM;
+ srcStart = srcx >> INTER_PGSH;
+ psrcStart = psrcBase + (srcy * widthSrc) * INTER_PLANES;
+ psrcLine = psrcStart + srcStart * INTER_PLANES;
+
+ /* set up dest */
+ xoffDst = ppt->x & INTER_PIM;
+ pdstLine = pdstBase + (ppt->y * widthDst) +
+ (ppt->x >> INTER_PGSH) * INTER_PLANES;
+ /* set up masks */
+ if (xoffDst + w < INTER_PPG)
+ {
+ INTER_maskpartialbits(ppt->x, w, startmask);
+ endmask = 0;
+ nlMiddle = 0;
+ }
+ else
+ {
+ INTER_maskbits (ppt->x, w, startmask, endmask, nlMiddle)
+ }
+
+ if (xoffSrc == xoffDst)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ srcRemaining = widthSrc - srcStart;
+ if (startmask)
+ {
+ INTER_MROP_MASK (psrc, pdst, startmask, pdst);
+ INTER_NEXT_GROUP(pdst);
+ IncSrcPtr
+ }
+ nlTemp = nlMiddle;
+ while (nlTemp)
+ {
+ nl = nlTemp;
+ if (nl > srcRemaining)
+ nl = srcRemaining;
+
+ nlTemp -= nl;
+ srcRemaining -= nl;
+
+ while (nl--) {
+ INTER_MROP_SOLID (psrc, pdst, pdst);
+ INTER_NEXT_GROUP(pdst); INTER_NEXT_GROUP(psrc);
+ }
+
+ if (!srcRemaining)
+ {
+ srcRemaining = widthSrc;
+ psrc = psrcStart;
+ }
+ }
+ if (endmask)
+ {
+ INTER_MROP_MASK (psrc, pdst, endmask, pdst);
+ }
+ }
+ else
+ {
+ if (xoffSrc > xoffDst)
+ {
+ leftShift = (xoffSrc - xoffDst) << LEFTSHIFT_AMT;
+ rightShift = INTER_PGSZ - leftShift;
+ }
+ else
+ {
+ rightShift = (xoffDst - xoffSrc) << LEFTSHIFT_AMT;
+ leftShift = INTER_PGSZ - rightShift;
+ }
+ psrc = psrcLine;
+ pdst = pdstLine;
+ INTER_CLR(bits);
+ srcRemaining = widthSrc - srcStart;
+ if (xoffSrc > xoffDst)
+ {
+ INTER_COPY(psrc, bits);
+ IncSrcPtr
+ }
+ if (startmask)
+ {
+ INTER_SCRLEFT(leftShift, bits, bits1);
+ INTER_COPY(psrc, bits);
+ IncSrcPtr
+ INTER_MSKINSM(~0, 0, bits1, ~0, rightShift, bits, bits1);
+ INTER_MROP_MASK(bits1, pdst, startmask, pdst);
+ INTER_NEXT_GROUP(pdst);
+ }
+ nlTemp = nlMiddle;
+ while (nlTemp)
+ {
+ nl = nlTemp;
+ if (nl > srcRemaining)
+ nl = srcRemaining;
+
+ nlTemp -= nl;
+ srcRemaining -= nl;
+
+ while (nl--) {
+ INTER_SCRLEFT(leftShift, bits, bits1);
+ INTER_COPY(psrc, bits); INTER_NEXT_GROUP(psrc);
+ INTER_MSKINSM(~0, 0, bits1, ~0, rightShift, bits, bits1);
+ INTER_MROP_SOLID(bits1, pdst, pdst);
+ INTER_NEXT_GROUP(pdst);
+ }
+
+ if (!srcRemaining)
+ {
+ srcRemaining = widthSrc;
+ psrc = psrcStart;
+ }
+ }
+
+ if (endmask)
+ {
+ INTER_SCRLEFT(leftShift, bits, bits1);
+ if (endmask << rightShift)
+ {
+ INTER_COPY(psrc, bits);
+ INTER_MSKINSM(~0, 0, bits1, ~0, rightShift, bits, bits1);
+ }
+ INTER_MROP_MASK (bits1, pdst, endmask, pdst);
+ }
+ }
+ ppt++;
+ }
+}
diff --git a/xc/programs/Xserver/iplan2p4/iplwindow.c b/xc/programs/Xserver/iplan2p4/iplwindow.c
new file mode 100644
index 000000000..3446b1904
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p4/iplwindow.c
@@ -0,0 +1,339 @@
+/* $XFree86: xc/programs/Xserver/iplan2p4/iplwindow.c,v 3.0 1996/08/18 01:55:13 dawes Exp $ */
+/* $XConsortium: iplwindow.c,v 5.22 94/04/17 20:29:07 dpw Exp $ */
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* Modified nov 94 by Martin Schaller (Martin_Schaller@maus.r.de) for use with
+interleaved planes */
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "ipl.h"
+#include "mistruct.h"
+#include "regionstr.h"
+#include "iplmskbits.h"
+
+extern WindowPtr *WindowTable;
+
+Bool
+iplCreateWindow(pWin)
+ WindowPtr pWin;
+{
+ iplPrivWin *pPrivWin;
+
+ pPrivWin = iplGetWindowPrivate(pWin);
+ pPrivWin->pRotatedBorder = NullPixmap;
+ pPrivWin->pRotatedBackground = NullPixmap;
+ pPrivWin->fastBackground = FALSE;
+ pPrivWin->fastBorder = FALSE;
+ pPrivWin->oldRotate.x = 0;
+ pPrivWin->oldRotate.y = 0;
+
+#ifdef PIXMAP_PER_WINDOW
+ /* Setup pointer to Screen pixmap */
+ pWin->devPrivates[frameWindowPrivateIndex].ptr =
+ (pointer) iplGetScreenPixmap(pWin->drawable.pScreen);
+#endif
+
+ return TRUE;
+}
+
+Bool
+iplDestroyWindow(pWin)
+ WindowPtr pWin;
+{
+ iplPrivWin *pPrivWin;
+
+ pPrivWin = iplGetWindowPrivate(pWin);
+
+ if (pPrivWin->pRotatedBorder)
+ (*pWin->drawable.pScreen->DestroyPixmap)(pPrivWin->pRotatedBorder);
+ if (pPrivWin->pRotatedBackground)
+ (*pWin->drawable.pScreen->DestroyPixmap)(pPrivWin->pRotatedBackground);
+ return(TRUE);
+}
+
+/*ARGSUSED*/
+Bool
+iplMapWindow(pWindow)
+ WindowPtr pWindow;
+{
+ return(TRUE);
+}
+
+/* (x, y) is the upper left corner of the window on the screen
+ do we really need to pass this? (is it a;ready in pWin->absCorner?)
+ we only do the rotation for pixmaps that are 32 bits wide (padded
+or otherwise.)
+ iplChangeWindowAttributes() has already put a copy of the pixmap
+in pPrivWin->pRotated*
+*/
+/*ARGSUSED*/
+Bool
+iplPositionWindow(pWin, x, y)
+ WindowPtr pWin;
+ int x, y;
+{
+ iplPrivWin *pPrivWin;
+ int setxy = 0;
+
+ pPrivWin = iplGetWindowPrivate(pWin);
+ if (pWin->backgroundState == BackgroundPixmap && pPrivWin->fastBackground)
+ {
+ iplXRotatePixmap(pPrivWin->pRotatedBackground,
+ pWin->drawable.x - pPrivWin->oldRotate.x);
+ iplYRotatePixmap(pPrivWin->pRotatedBackground,
+ pWin->drawable.y - pPrivWin->oldRotate.y);
+ setxy = 1;
+ }
+
+ if (!pWin->borderIsPixel && pPrivWin->fastBorder)
+ {
+ while (pWin->backgroundState == ParentRelative)
+ pWin = pWin->parent;
+ iplXRotatePixmap(pPrivWin->pRotatedBorder,
+ pWin->drawable.x - pPrivWin->oldRotate.x);
+ iplYRotatePixmap(pPrivWin->pRotatedBorder,
+ pWin->drawable.y - pPrivWin->oldRotate.y);
+ setxy = 1;
+ }
+ if (setxy)
+ {
+ pPrivWin->oldRotate.x = pWin->drawable.x;
+ pPrivWin->oldRotate.y = pWin->drawable.y;
+ }
+ return (TRUE);
+}
+
+/*ARGSUSED*/
+Bool
+iplUnmapWindow(pWindow)
+ WindowPtr pWindow;
+{
+ return (TRUE);
+}
+
+/* UNCLEAN!
+ this code calls the bitblt helper code directly.
+
+ iplCopyWindow copies only the parts of the destination that are
+visible in the source.
+*/
+
+
+void
+iplCopyWindow(pWin, ptOldOrg, prgnSrc)
+ WindowPtr pWin;
+ DDXPointRec ptOldOrg;
+ RegionPtr prgnSrc;
+{
+ DDXPointPtr pptSrc;
+ register DDXPointPtr ppt;
+ RegionRec rgnDst;
+ register BoxPtr pbox;
+ register int dx, dy;
+ register int i, nbox;
+ WindowPtr pwinRoot;
+
+ pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];
+
+ REGION_INIT(pWin->drawable.pScreen, &rgnDst, NullBox, 0);
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
+ REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
+
+ pbox = REGION_RECTS(&rgnDst);
+ nbox = REGION_NUM_RECTS(&rgnDst);
+ if(!nbox || !(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec))))
+ {
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+ return;
+ }
+ ppt = pptSrc;
+
+ for (i = nbox; --i >= 0; ppt++, pbox++)
+ {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ iplDoBitbltCopy((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
+ GXcopy, &rgnDst, pptSrc, ~0L);
+ DEALLOCATE_LOCAL(pptSrc);
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+}
+
+
+
+/* swap in correct PaintWindow* routine. If we can use a fast output
+routine (i.e. the pixmap is paddable to 32 bits), also pre-rotate a copy
+of it in devPrivates[iplWindowPrivateIndex].ptr.
+*/
+Bool
+iplChangeWindowAttributes(pWin, mask)
+ WindowPtr pWin;
+ unsigned long mask;
+{
+ register unsigned long index;
+ register iplPrivWin *pPrivWin;
+ int width;
+ WindowPtr pBgWin;
+
+ pPrivWin = iplGetWindowPrivate(pWin);
+
+ /*
+ * When background state changes from ParentRelative and
+ * we had previously rotated the fast border pixmap to match
+ * the parent relative origin, rerotate to match window
+ */
+ if (mask & (CWBackPixmap | CWBackPixel) &&
+ pWin->backgroundState != ParentRelative &&
+ pPrivWin->fastBorder &&
+ (pPrivWin->oldRotate.x != pWin->drawable.x ||
+ pPrivWin->oldRotate.y != pWin->drawable.y))
+ {
+ iplXRotatePixmap(pPrivWin->pRotatedBorder,
+ pWin->drawable.x - pPrivWin->oldRotate.x);
+ iplYRotatePixmap(pPrivWin->pRotatedBorder,
+ pWin->drawable.y - pPrivWin->oldRotate.y);
+ pPrivWin->oldRotate.x = pWin->drawable.x;
+ pPrivWin->oldRotate.y = pWin->drawable.y;
+ }
+ while(mask)
+ {
+ index = lowbit (mask);
+ mask &= ~index;
+ switch(index)
+ {
+ case CWBackPixmap:
+ if (pWin->backgroundState == None)
+ {
+ pPrivWin->fastBackground = FALSE;
+ }
+ else if (pWin->backgroundState == ParentRelative)
+ {
+ pPrivWin->fastBackground = FALSE;
+ /* Rotate border to match parent origin */
+ if (pPrivWin->pRotatedBorder) {
+ for (pBgWin = pWin->parent;
+ pBgWin->backgroundState == ParentRelative;
+ pBgWin = pBgWin->parent);
+ iplXRotatePixmap(pPrivWin->pRotatedBorder,
+ pBgWin->drawable.x - pPrivWin->oldRotate.x);
+ iplYRotatePixmap(pPrivWin->pRotatedBorder,
+ pBgWin->drawable.y - pPrivWin->oldRotate.y);
+ pPrivWin->oldRotate.x = pBgWin->drawable.x;
+ pPrivWin->oldRotate.y = pBgWin->drawable.y;
+ }
+ }
+ else if (((width = (pWin->background.pixmap->drawable.width))
+ <= INTER_PGSZ) && !(width & (width - 1)))
+ {
+ iplCopyRotatePixmap(pWin->background.pixmap,
+ &pPrivWin->pRotatedBackground,
+ pWin->drawable.x,
+ pWin->drawable.y);
+ if (pPrivWin->pRotatedBackground)
+ {
+ pPrivWin->fastBackground = TRUE;
+ pPrivWin->oldRotate.x = pWin->drawable.x;
+ pPrivWin->oldRotate.y = pWin->drawable.y;
+ }
+ else
+ {
+ pPrivWin->fastBackground = FALSE;
+ }
+ }
+ else
+ {
+ pPrivWin->fastBackground = FALSE;
+ }
+ break;
+
+ case CWBackPixel:
+ pPrivWin->fastBackground = FALSE;
+ break;
+
+ case CWBorderPixmap:
+ if (((width = (pWin->border.pixmap->drawable.width)) <= INTER_PGSZ) &&
+ !(width & (width - 1)))
+ {
+ for (pBgWin = pWin;
+ pBgWin->backgroundState == ParentRelative;
+ pBgWin = pBgWin->parent);
+ iplCopyRotatePixmap(pWin->border.pixmap,
+ &pPrivWin->pRotatedBorder,
+ pBgWin->drawable.x,
+ pBgWin->drawable.y);
+ if (pPrivWin->pRotatedBorder)
+ {
+ pPrivWin->fastBorder = TRUE;
+ pPrivWin->oldRotate.x = pBgWin->drawable.x;
+ pPrivWin->oldRotate.y = pBgWin->drawable.y;
+ }
+ else
+ {
+ pPrivWin->fastBorder = FALSE;
+ }
+ }
+ else
+ {
+ pPrivWin->fastBorder = FALSE;
+ }
+ break;
+ case CWBorderPixel:
+ pPrivWin->fastBorder = FALSE;
+ break;
+ }
+ }
+ return (TRUE);
+}
+
diff --git a/xc/programs/Xserver/iplan2p8/Imakefile b/xc/programs/Xserver/iplan2p8/Imakefile
new file mode 100644
index 000000000..df6a6bbf4
--- /dev/null
+++ b/xc/programs/Xserver/iplan2p8/Imakefile
@@ -0,0 +1,6 @@
+XCOMM $XFree86: xc/programs/Xserver/iplan2p8/Imakefile,v 3.0 1996/08/18 01:55:18 dawes Exp $
+XCOMM $XConsortium: Imakefile,v 1.1 91/12/28 13:32:27 rws Exp $
+#define IPlanes 8
+#define LinkDirectory ../iplan2p4
+
+#include "../iplan2p4/Imakefile"
diff --git a/xc/programs/Xserver/lbx/Imakefile b/xc/programs/Xserver/lbx/Imakefile
new file mode 100644
index 000000000..920b729b6
--- /dev/null
+++ b/xc/programs/Xserver/lbx/Imakefile
@@ -0,0 +1,56 @@
+/* $XConsortium: Imakefile /main/11 1996/09/28 17:14:46 rws $ */
+/*
+ * $NCDId: @(#)Imakefile,v 1.16 1994/11/18 20:32:34 lemke Exp $
+ *
+ * Copyright 1992 Network Computing Devices
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of NCD. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. NCD. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NCD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NCD.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Keith Packard, Network Computing Devices
+ */
+/* $XFree86: xc/programs/Xserver/lbx/Imakefile,v 1.3 1999/04/17 09:08:48 dawes Exp $ */
+
+#include <Server.tmpl>
+
+#ifdef NCD
+INCLUDES = \
+ -I$(EXTENSIONSRC)/include/lbx \
+ -I$(EXTENSIONSRC)/include \
+ -I$(EXTENSIONSRC)/lbxcommon/delta \
+ -I$(XINCLUDESRC) \
+ -I$(FONTSRC)/include \
+ -I$(SERVERSRC)/include
+#else
+INCLUDES = -I$(TOP)/include -I$(TOP)/include/fonts -I$(SERVERSRC)/include -I$(EXTINCSRC) -I../../../include/extensions
+#endif
+
+SRCS = \
+ lbxmain.c lbxdix.c lbxtags.c lbxprop.c lbxgfx.c lbxtables.c \
+ lbxswap.c lbxsquish.c lbxexts.c lbxopts.c lbxzerorep.c lbxcmap.c
+
+
+OBJS = \
+ lbxmain.o lbxdix.o lbxtags.o lbxprop.o lbxgfx.o lbxtables.o \
+ lbxswap.o lbxsquish.o lbxexts.o lbxopts.o lbxzerorep.o lbxcmap.o
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(lbx,$(OBJS))
+LintLibraryTarget(lbx,$(SRCS))
+NormalLintTarget($(SRCS))
+
+DependTarget()
diff --git a/xc/programs/Xserver/lbx/lbxcmap.c b/xc/programs/Xserver/lbx/lbxcmap.c
new file mode 100644
index 000000000..e70890263
--- /dev/null
+++ b/xc/programs/Xserver/lbx/lbxcmap.c
@@ -0,0 +1,1156 @@
+/* $TOG: lbxcmap.c /main/13 1998/03/11 16:28:54 barstow $ */
+
+/*
+Copyright 1996, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+*/
+/* $XFree86: xc/programs/Xserver/lbx/lbxcmap.c,v 1.5 1998/11/15 11:11:18 dawes Exp $ */
+
+#include <sys/types.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "Xos.h"
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "scrnintstr.h"
+#include "colormapst.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "lbxserve.h"
+#include "Xfuncproto.h"
+#include <stdio.h>
+
+static int lbxScreenPrivIndex; /* lbx screen private index */
+static int lbxColormapPrivIndex; /* lbx colormap private index */
+
+typedef struct { /* lbx screen private */
+ CreateColormapProcPtr CreateColormap;
+ DestroyColormapProcPtr DestroyColormap;
+} LbxScreenPriv;
+
+typedef struct _LbxStalled {
+ XID id;
+ struct _LbxStalled *next;
+} LbxStalled;
+
+typedef struct _LbxColormapPriv { /* lbx colormap private */
+ char grab_status;
+ char smart_grab;
+ LbxProxyPtr grabber;
+ int last_grabber; /* uid, not pid */
+ LbxStalled *stalled_clients;
+ ColormapPtr next; /* proxy chain */
+} LbxColormapPriv;
+
+#define CMAP_NOT_GRABBED 0
+#define CMAP_GRABBED 1
+#define CMAP_WAITING_FOR_UNGRAB 2
+
+static int LbxUnstallClient();
+void LbxReleaseCmap();
+
+static RESTYPE StalledResType;
+
+/*
+ * Initialize the fields in the colormap private allocated for LBX.
+ */
+
+static LbxColormapPriv *
+LbxColormapPrivInit (pmap)
+ ColormapPtr pmap;
+{
+ LbxColormapPriv *cmapPriv;
+
+ cmapPriv = (LbxColormapPriv *) xalloc (sizeof (LbxColormapPriv));
+ if (!cmapPriv)
+ return cmapPriv;
+
+ pmap->devPrivates[lbxColormapPrivIndex].ptr = (pointer) cmapPriv;
+
+ cmapPriv->grab_status = CMAP_NOT_GRABBED;
+ cmapPriv->grabber = NULL;
+ cmapPriv->last_grabber = 0;
+ cmapPriv->smart_grab = FALSE;
+ cmapPriv->stalled_clients = NULL;
+ cmapPriv->next = NULL;
+
+ return cmapPriv;
+}
+
+
+static int
+LbxDefCmapPrivInit (pmap)
+ ColormapPtr pmap;
+{
+#if 0
+ /* BUG: You can't do that. lbxColormapPrivIndex hasn't
+ been initialized yet. */
+ pmap->devPrivates[lbxColormapPrivIndex].ptr = NULL;
+#endif
+ return 1;
+}
+
+static Bool
+LbxCreateColormap (pmap)
+ ColormapPtr pmap;
+{
+ ScreenPtr pScreen = pmap->pScreen;
+ Bool ret;
+
+ pScreen->CreateColormap = ((LbxScreenPriv *) (pScreen->devPrivates[
+ lbxScreenPrivIndex].ptr))->CreateColormap;
+
+ pmap->devPrivates[lbxColormapPrivIndex].ptr = NULL;
+ ret = (*pScreen->CreateColormap) (pmap);
+
+ pScreen->CreateColormap = LbxCreateColormap;
+
+ return ret;
+}
+
+static void
+LbxDestroyColormap (pmap)
+ ColormapPtr pmap;
+{
+ ScreenPtr pScreen = pmap->pScreen;
+
+ LbxReleaseCmap(pmap, FALSE);
+ pScreen->DestroyColormap = ((LbxScreenPriv *) (pScreen->devPrivates[
+ lbxScreenPrivIndex].ptr))->DestroyColormap;
+ (*pScreen->DestroyColormap) (pmap);
+ if (pmap->devPrivates && pmap->devPrivates[lbxColormapPrivIndex].ptr)
+ xfree(pmap->devPrivates[lbxColormapPrivIndex].ptr);
+ pScreen->DestroyColormap = LbxDestroyColormap;
+}
+
+/*
+ * Initialize LBX colormap private.
+ */
+
+int
+LbxCmapInit ()
+
+{
+ LbxScreenPriv *pScreenPriv;
+ ColormapPtr defMap;
+ ScreenPtr pScreen;
+ int i;
+
+ StalledResType = CreateNewResourceType(LbxUnstallClient);
+
+ lbxScreenPrivIndex = AllocateScreenPrivateIndex ();
+ if (lbxScreenPrivIndex < 0)
+ return 0;
+
+ lbxColormapPrivIndex = AllocateColormapPrivateIndex (LbxDefCmapPrivInit);
+ if (lbxColormapPrivIndex < 0)
+ return 0;
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ pScreen = screenInfo.screens[i];
+
+ defMap = (ColormapPtr) LookupIDByType(
+ pScreen->defColormap, RT_COLORMAP);
+
+ /* now lbxColormapPrivIndex exists */
+ defMap->devPrivates[lbxColormapPrivIndex].ptr = NULL;
+
+ pScreenPriv = (LbxScreenPriv *) xalloc (sizeof (LbxScreenPriv));
+ if (!pScreenPriv)
+ return 0;
+
+ pScreenPriv->CreateColormap = pScreen->CreateColormap;
+ pScreen->CreateColormap = LbxCreateColormap;
+ pScreenPriv->DestroyColormap = pScreen->DestroyColormap;
+ pScreen->DestroyColormap = LbxDestroyColormap;
+ pScreen->devPrivates[lbxScreenPrivIndex].ptr = (pointer) pScreenPriv;
+ }
+
+ return 1;
+}
+
+
+/*
+ * Return the number of allocated cells in the PSEUDO colormap.
+ */
+
+static int
+NumAllocatedCells (pent, size)
+ EntryPtr pent;
+ int size;
+{
+ Pixel pixel;
+ int count = 0;
+
+ for (pixel = 0; pixel < size; pixel++)
+ {
+ if (pent[pixel].refcnt != 0 && pent[pixel].refcnt != AllocTemporary)
+ count++;
+ }
+
+ return count;
+}
+
+#define NUMRED(vis) ((vis->redMask >> vis->offsetRed) + 1)
+#define NUMGREEN(vis) ((vis->greenMask >> vis->offsetGreen) + 1)
+#define NUMBLUE(vis) ((vis->blueMask >> vis->offsetBlue) + 1)
+
+#define PIX_OUT(ptr,is2,val) \
+ if (is2) *ptr++ = (val) >> 8; \
+ *ptr++ = (val)
+#define RGB_OUT(ptr,is2,shift,val) \
+ *ptr++ = (val) >> shift; \
+ if (is2) *ptr++ = (val)
+
+/*
+ * Return the list of allocated cells in the channel in
+ * the format required by LbxGrabCmapReply.
+ */
+
+static CARD8 *
+OutputChannel(pmap, chan, size, ptr, flags, channels)
+ ColormapPtr pmap;
+ EntryPtr chan;
+ int size;
+ CARD8 *ptr;
+ CARD8 flags;
+ CARD8 channels;
+{
+ Bool px2;
+ Bool rgb2;
+ int shift;
+ int rgb_sz;
+ Pixel pixel;
+ EntryPtr pent;
+ CARD8 *pixel_private_range_ptr = NULL;
+ CARD8 *pixel_shared_range_ptr = NULL;
+ int allocpriv;
+
+ px2 = (flags & LBX_2BYTE_PIXELS) != 0;
+ rgb2 = (flags & LBX_RGB_BITS_MASK) > 7;
+ if (rgb2)
+ shift = 8;
+ else
+ shift = 15 - (flags & LBX_RGB_BITS_MASK);
+ rgb_sz = rgb2 + 1;
+ if (channels == DoRed|DoGreen|DoBlue)
+ rgb_sz *= 3;
+ /* kinda gross, but ddxen use AllocAll on static maps */
+ allocpriv = (pmap->pVisual->class & DynamicClass) ? AllocPrivate : 0;
+ for (pixel = 0; pixel < size; pixel++)
+ {
+ pent = (EntryPtr) &chan[pixel];
+
+ if (pent->refcnt == 0 || pent->refcnt == AllocTemporary)
+ {
+ /*
+ * A free pixel. This disrupts all ranges.
+ */
+
+ pixel_private_range_ptr = pixel_shared_range_ptr = NULL;
+
+ continue;
+ }
+ else if (pent->refcnt == allocpriv)
+ {
+ /*
+ * A private pixel. This disrupts any PIXEL_SHARED_RANGE.
+ */
+
+ pixel_shared_range_ptr = NULL;
+
+ if (!pixel_private_range_ptr)
+ {
+ pixel_private_range_ptr = ptr;
+
+ *ptr++ = LBX_PIXEL_PRIVATE;
+ PIX_OUT(ptr, px2, pixel);
+ }
+ else
+ {
+ CARD8 *pos = pixel_private_range_ptr + 2 + px2;
+ if (*pixel_private_range_ptr == LBX_PIXEL_PRIVATE) {
+ *pixel_private_range_ptr = LBX_PIXEL_RANGE_PRIVATE;
+ ptr += 1 + px2;
+ }
+ PIX_OUT(pos, px2, pixel);
+ }
+ }
+ else
+ {
+ /*
+ * A shared pixel. This disrupts any PIXEL_PRIVATE_RANGE.
+ */
+
+ pixel_private_range_ptr = NULL;
+
+ if (!pixel_shared_range_ptr)
+ {
+ pixel_shared_range_ptr = ptr;
+
+ *ptr++ = LBX_PIXEL_SHARED;
+ PIX_OUT(ptr, px2, pixel);
+ }
+ else
+ {
+ CARD8 *pos = pixel_shared_range_ptr + 2 + px2;
+ if (*pixel_shared_range_ptr == LBX_PIXEL_SHARED)
+ {
+ *pixel_shared_range_ptr = LBX_PIXEL_RANGE_SHARED;
+ memmove (pos + 1 + px2, pos, rgb_sz);
+ ptr += 1 + px2;
+ }
+ PIX_OUT(pos, px2, pixel);
+ }
+
+ if (channels & DoRed) {
+ RGB_OUT(ptr, rgb2, shift, pent->co.local.red);
+ }
+ if (channels & DoGreen) {
+ RGB_OUT(ptr, rgb2, shift, pent->co.local.green);
+ }
+ if (channels & DoBlue) {
+ RGB_OUT(ptr, rgb2, shift, pent->co.local.blue);
+ }
+ }
+ }
+ return ptr;
+}
+
+static void
+GetAllocatedCells (pmap, flags, buf, bytes)
+ ColormapPtr pmap;
+ CARD8 *flags;
+ CARD8 *buf;
+ int *bytes;
+{
+ CARD8 *ptr;
+
+ *flags = pmap->pVisual->bitsPerRGBValue - 1;
+ if (pmap->pVisual->ColormapEntries > 256)
+ *flags |= LBX_2BYTE_PIXELS;
+ if (!(pmap->pVisual->class & DynamicClass))
+ *flags |= LBX_AUTO_RELEASE;
+ if ((pmap->pVisual->class | DynamicClass) == DirectColor) {
+ *flags |= LBX_3CHANNELS;
+ ptr = OutputChannel(pmap, pmap->red, NUMRED(pmap->pVisual),
+ buf, *flags, DoRed);
+ *ptr++ = LBX_NEXT_CHANNEL;
+ ptr = OutputChannel(pmap, pmap->green, NUMGREEN(pmap->pVisual),
+ ptr, *flags, DoGreen);
+ *ptr++ = LBX_NEXT_CHANNEL;
+ ptr = OutputChannel(pmap, pmap->blue, NUMBLUE(pmap->pVisual),
+ ptr, *flags, DoBlue);
+ } else
+ ptr = OutputChannel(pmap, pmap->red, pmap->pVisual->ColormapEntries,
+ buf, *flags, DoRed|DoGreen|DoBlue);
+ *ptr++ = LBX_LIST_END;
+ *bytes = ptr - buf;
+}
+
+
+/*
+ * Send an LbxReleaseCmapEvent to a proxy.
+ */
+
+static void
+SendReleaseCmapEvent (proxy, cmap)
+ LbxProxyPtr proxy;
+ Colormap cmap;
+{
+ xLbxReleaseCmapEvent ev;
+ ClientPtr client;
+ LbxClientPtr lbxcp;
+ int n;
+
+ lbxcp = proxy->lbxClients[0];
+
+ if (lbxcp && (client = lbxcp->client))
+ {
+ ev.type = LbxEventCode;
+ ev.lbxType = LbxReleaseCmapEvent;
+ ev.sequenceNumber = client->sequence;
+ ev.colormap = cmap;
+ ev.pad1 = ev.pad2 = ev.pad3 = ev.pad4 = ev.pad5 = ev.pad6 = 0;
+
+ if (client->swapped)
+ {
+ swaps(&ev.sequenceNumber, n);
+ swapl(&ev.colormap, n);
+ }
+
+ WriteToClient(client, sz_xLbxReleaseCmapEvent, (char *) &ev);
+ LbxForceOutput(proxy);
+
+#ifdef COLOR_DEBUG
+ fprintf (stderr,
+ "Sent LbxReleaseCmapEvent to proxy %d, seq = 0x%x, cmap = 0x%x\n",
+ proxy->pid, client->sequence, cmap);
+#endif
+ }
+}
+
+
+/*
+ * WaitForServerCmapControl checks if the colormap is grabbed by a proxy,
+ * and if so, sends an LbxReleaseCmapEvent to the proxy. It then suspends
+ * the current request until the server gets the ReleaseCmap message from
+ * the proxy.
+ */
+
+static Bool
+WaitForServerCmapControl (client, pmap)
+ register ClientPtr client;
+ register ColormapPtr pmap;
+{
+ LbxColormapPriv *cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+ LbxStalled *stalled;
+
+ if (cmapPriv->grab_status == CMAP_GRABBED)
+ {
+ /*
+ * Send an LbxReleaseCmapEvent to the proxy that has the grab.
+ */
+
+ SendReleaseCmapEvent (cmapPriv->grabber, pmap->mid);
+ cmapPriv->grab_status = CMAP_WAITING_FOR_UNGRAB;
+ }
+
+ stalled = (LbxStalled *)xalloc(sizeof(LbxStalled));
+ if (!stalled)
+ return FALSE;
+ stalled->id = FakeClientID(client->index);
+ stalled->next = cmapPriv->stalled_clients;
+ cmapPriv->stalled_clients = stalled;
+ return AddResource(stalled->id, StalledResType, (pointer)cmapPriv);
+}
+
+
+/*
+ * When the X server gets any of the requests that allocate color cells,
+ * it calls LbxCheckColorRequest on the request. This function will check
+ * if the colormap is grabbed by a proxy, and if so, will suspend the
+ * current request and wait for the proxy to release the colormap.
+ */
+
+Bool
+LbxCheckColorRequest (client, pmap, req)
+ ClientPtr client;
+ ColormapPtr pmap;
+ xReq *req;
+{
+ LbxColormapPriv *cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+
+ if (!cmapPriv)
+ return FALSE;
+
+ if (cmapPriv->grab_status != CMAP_NOT_GRABBED)
+ {
+ /*
+ * The colormap is grabbed by a proxy. Reset this request, and
+ * process it after the server gets back control of the colormap.
+ * Before we reset the request, we must put it back in the
+ * client's byte order.
+ */
+
+ if (!WaitForServerCmapControl (client, pmap))
+ return FALSE;
+
+ if (client->swapped)
+ {
+ register int n;
+
+ switch (req->reqType)
+ {
+ case X_AllocColor:
+ {
+ xAllocColorReq *stuff = (xAllocColorReq *) req;
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+ swaps(&stuff->red, n);
+ swaps(&stuff->green, n);
+ swaps(&stuff->blue, n);
+ break;
+ }
+ case X_AllocNamedColor:
+ {
+ xAllocNamedColorReq *stuff = (xAllocNamedColorReq *) req;
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+ swaps(&stuff->nbytes, n);
+ break;
+ }
+ case X_AllocColorCells:
+ {
+ xAllocColorCellsReq *stuff = (xAllocColorCellsReq *) req;
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+ swaps(&stuff->colors, n);
+ swaps(&stuff->planes, n);
+ break;
+ }
+ case X_AllocColorPlanes:
+ {
+ xAllocColorPlanesReq *stuff = (xAllocColorPlanesReq *) req;
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+ swaps(&stuff->colors, n);
+ swaps(&stuff->red, n);
+ swaps(&stuff->green, n);
+ swaps(&stuff->blue, n);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ ResetCurrentRequest(client);
+ client->sequence--;
+ IgnoreClient(client);
+
+ return TRUE;
+ }
+
+ if (!LbxClient(client) ||
+ LbxProxy(client)->uid != cmapPriv->last_grabber)
+ {
+ /*
+ * Next time the proxy for this client does a colormap grab, it
+ * will have to get the colormap state (a non-smart grab).
+ */
+
+ cmapPriv->smart_grab = FALSE;
+ }
+
+ return FALSE;
+}
+
+static Bool
+LbxGrabbedByClient (client, pmap)
+ ClientPtr client;
+ ColormapPtr pmap;
+{
+ LbxColormapPriv *cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+ return (cmapPriv &&
+ (cmapPriv->grab_status != CMAP_NOT_GRABBED) &&
+ (cmapPriv->grabber == LbxProxy(client)));
+}
+
+/*
+ * Check if a colormap is grabbed by a proxy.
+ */
+
+int
+LbxCheckCmapGrabbed (pmap)
+ ColormapPtr pmap;
+{
+ LbxColormapPriv *cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+
+ return (cmapPriv && (cmapPriv->grab_status == CMAP_GRABBED));
+}
+
+
+/*
+ * Disable a smart grab on the specified colormap.
+ */
+
+void
+LbxDisableSmartGrab (pmap)
+ ColormapPtr pmap;
+{
+ LbxColormapPriv *cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+
+ if (cmapPriv)
+ cmapPriv->smart_grab = FALSE;
+}
+
+
+/*
+ * Send an LbxFreeCellsEvent to the specified proxy.
+ */
+
+static void
+SendFreeCellsEvent (proxy, cmap, pixel_start, pixel_end)
+ LbxProxyPtr proxy;
+ Colormap cmap;
+ Pixel pixel_start;
+ Pixel pixel_end;
+{
+ xLbxFreeCellsEvent ev;
+ ClientPtr client;
+ LbxClientPtr lbxcp;
+ int n;
+
+ lbxcp = proxy->lbxClients[0];
+
+ if (lbxcp && (client = lbxcp->client))
+ {
+ ev.type = LbxEventCode;
+ ev.lbxType = LbxFreeCellsEvent;
+ ev.sequenceNumber = client->sequence;
+ ev.colormap = cmap;
+ ev.pixelStart = pixel_start;
+ ev.pixelEnd = pixel_end;
+ ev.pad1 = ev.pad2 = ev.pad3 = ev.pad4 = 0;
+
+ if (client->swapped)
+ {
+ swaps(&ev.sequenceNumber, n);
+ swapl(&ev.colormap, n);
+ swapl(&ev.pixelStart, n);
+ swapl(&ev.pixelEnd, n);
+ }
+
+ WriteToClient(client, sz_xLbxFreeCellsEvent, (char *) &ev);
+ LbxForceOutput(proxy);
+#ifdef COLOR_DEBUG
+ fprintf (stderr, "Sent LbxFreeCellsEvent to proxy %d, seq = 0x%x\n",
+ proxy->pid, client->sequence);
+ fprintf (stderr, " cmap = 0x%x, pixelStart = %d, pixelEnd = %d\n",
+ cmap, pixel_start, pixel_end);
+#endif
+ }
+}
+
+/* XXX use of globals like this is gross */
+static long pixel_start;
+static long pixel_end;
+
+
+/*
+ * LbxFreeCellsEvent generation functions.
+ */
+
+/*ARGSUSED*/
+void
+LbxBeginFreeCellsEvent (pmap)
+ ColormapPtr pmap;
+{
+ pixel_start = -1;
+ pixel_end = -1;
+}
+
+
+void
+LbxAddFreeCellToEvent (pmap, pixel)
+ ColormapPtr pmap;
+ Pixel pixel;
+{
+ /*
+ * We must notify the proxy that has this colormap
+ * grabbed which cells are being freed (their refcount
+ * has reached zero).
+ */
+
+ if (pixel_start == -1)
+ pixel_start = pixel;
+ else
+ {
+ if (pixel_end == -1)
+ pixel_end = pixel;
+ else
+ {
+ if (pixel_end + 1 == pixel)
+ pixel_end = pixel;
+ else if (pixel > pixel_end + 1)
+ {
+ LbxColormapPriv *cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+
+ SendFreeCellsEvent (cmapPriv->grabber,
+ pmap->mid, pixel_start, pixel_end);
+
+ pixel_start = pixel;
+ pixel_end = -1;
+ }
+ }
+ }
+}
+
+void
+LbxEndFreeCellsEvent (pmap)
+ ColormapPtr pmap;
+{
+ /*
+ * Check if there is an LbxFreeCellEvent we need to write.
+ */
+
+ if (pixel_start != -1)
+ {
+ LbxColormapPriv *cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+
+ SendFreeCellsEvent (cmapPriv->grabber,
+ pmap->mid, pixel_start,
+ pixel_end == -1 ? pixel_start : pixel_end);
+ }
+}
+
+
+/*
+ * Sort the specified pixel list. This optimizes generation
+ * of LbxFreeCellsEvent.
+ */
+
+void
+LbxSortPixelList (pixels, count)
+ Pixel *pixels;
+ int count;
+{
+ int i, j;
+
+ for (i = 0; i <= count - 2; i++)
+ for (j = count - 1; j > i; j--)
+ if (pixels[j - 1] > pixels[j])
+ {
+ Pixel temp = pixels[j - 1];
+ pixels[j - 1] = pixels[j];
+ pixels[j] = temp;
+ }
+}
+
+
+/*
+ * Handle a colormap grab request from a proxy.
+ */
+
+int
+ProcLbxGrabCmap(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxGrabCmapReq);
+ xLbxGrabCmapReply *reply;
+ Bool smartGrab;
+ LbxColormapPriv *cmapPriv;
+ ColormapPtr pmap;
+ int bytes, n;
+ LbxProxyPtr proxy = LbxProxy(client);
+
+ client->sequence--; /* not a counted request */
+
+ pmap = (ColormapPtr) SecurityLookupIDByType (client, stuff->cmap,
+ RT_COLORMAP,
+ SecurityWriteAccess);
+
+ if (!pmap)
+ {
+ client->errorValue = stuff->cmap;
+ return BadColor;
+ }
+
+ cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+ if (!cmapPriv)
+ {
+ cmapPriv = LbxColormapPrivInit (pmap);
+ if (!cmapPriv)
+ return BadAlloc;
+ }
+
+
+ /*
+ * We have a SMART GRAB if since this proxy last ungrabbed the
+ * colormap, no color cell was alloc'd by an entity other than
+ * this proxy (this includes other proxies as well as clients
+ * directly connected to the X server without a proxy).
+ *
+ * We want to optimize this special case because a proxy may give
+ * up a grab because it got a request that it could not handle
+ * (e.g. AllocNamedColor or LookupColor). When it asks back for
+ * the grab, there is no need for the server to send the colormap
+ * state, because the proxy is already up to date on the state of
+ * the colormap.
+ *
+ * In order for this to work, the following assumptions are made
+ * about the proxy:
+ *
+ * - the proxy is kept up to date on all cell allocations made on its
+ * behalf resulting from the following requests: AllocNamedColor,
+ * AllocColorCells, AllocColorPlanes
+ * - the proxy is kept up to date on all cells freed by any client
+ * via the LbxFreeCell event.
+ */
+
+ /* if proxy is this confused, give it full info */
+ if (cmapPriv->grab_status == CMAP_GRABBED && cmapPriv->grabber == proxy)
+ LbxReleaseCmap(pmap, FALSE);
+
+ if (proxy->uid != cmapPriv->last_grabber)
+ cmapPriv->smart_grab = FALSE;
+ smartGrab = cmapPriv->smart_grab;
+
+#ifdef COLOR_DEBUG
+ fprintf (stderr, "\nGot colormap grab request, ");
+ fprintf (stderr, "seq = 0x%x, proxy = %d, client = %d, cmap = 0x%x\n",
+ client->sequence, proxy->pid, client->index, stuff->cmap);
+
+ if (cmapPriv->grab_status == CMAP_NOT_GRABBED)
+ {
+ fprintf (stderr, "cmap 0x%x is not grabbed by any proxy\n",
+ stuff->cmap);
+ if (smartGrab)
+ fprintf (stderr, "This is a smart grab\n");
+ }
+ else if (cmapPriv->grab_status == CMAP_GRABBED)
+ {
+ if (cmapPriv->grabber == proxy)
+ {
+ fprintf (stderr, "cmap 0x%x is already grabbed by proxy %d\n",
+ stuff->cmap, proxy->pid);
+ }
+ else
+ {
+ fprintf (stderr, "cmap 0x%x is currently grabbed by proxy %d\n",
+ stuff->cmap, cmapPriv->grabber->pid);
+ }
+ }
+ else if (cmapPriv->grab_status == CMAP_WAITING_FOR_UNGRAB)
+ {
+ fprintf (stderr,
+ "Already waiting for cmap 0x%x to be ungrabbed by proxy %d\n",
+ stuff->cmap, cmapPriv->grabber->pid);
+ }
+#endif
+
+ if (cmapPriv->grab_status != CMAP_NOT_GRABBED &&
+ cmapPriv->grabber != proxy)
+ {
+ /*
+ * The colormap is grabbed by a proxy other than the one that
+ * is requesting this grab. Reset this grab request, and process
+ * it after the server gets back control of the colormap. Before
+ * we reset the request, we must put it back in the client's byte
+ * order.
+ */
+
+ if (!WaitForServerCmapControl (client, pmap))
+ return BadAlloc;
+
+ if (client->swapped)
+ {
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+ }
+
+ ResetCurrentRequest(client);
+ IgnoreClient(client);
+
+ return Success;
+ }
+
+ if (pmap->pVisual->class & DynamicClass) {
+ cmapPriv->grabber = proxy;
+ cmapPriv->grab_status = CMAP_GRABBED;
+ cmapPriv->next = proxy->grabbedCmaps;
+ proxy->grabbedCmaps = pmap;
+ } else
+ smartGrab = FALSE;
+
+ /*
+ * For an smart grab (see comments above), there is no information
+ * sent about the colormap cells because the proxy is all up to date.
+ * Otherwise, the server sends the proxy the state of all allocated
+ * cells in the colormap. All cells not specified are assumed free.
+ */
+
+ bytes = 0;
+ if (!smartGrab) {
+ if ((pmap->pVisual->class | DynamicClass) == DirectColor) {
+ bytes = NumAllocatedCells(pmap->red,
+ NUMRED(pmap->pVisual)) * 9;
+ bytes += NumAllocatedCells(pmap->green,
+ NUMGREEN(pmap->pVisual)) * 9;
+ bytes += NumAllocatedCells(pmap->blue,
+ NUMBLUE(pmap->pVisual)) * 9;
+ bytes += 2;
+ } else
+ bytes = NumAllocatedCells(pmap->red,
+ pmap->pVisual->ColormapEntries) * 9;
+ }
+ bytes += sz_xLbxGrabCmapReply + 1;
+ reply = (xLbxGrabCmapReply *) xalloc (bytes);
+ bzero (reply, sz_xLbxGrabCmapReply);
+
+ if (smartGrab)
+ {
+ reply->flags = LBX_SMART_GRAB;
+ reply->length = 0;
+ }
+ else
+ {
+ GetAllocatedCells (pmap, &reply->flags,
+ (CARD8 *) reply + sz_xLbxGrabCmapReplyHdr, &bytes);
+ if (bytes <= (sz_xLbxGrabCmapReply - sz_xLbxGrabCmapReplyHdr))
+ reply->length = 0;
+ else
+ reply->length = (sz_xLbxGrabCmapReplyHdr +
+ bytes - sz_xLbxGrabCmapReply + 3) >> 2;
+ }
+
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+
+ bytes = sz_xLbxGrabCmapReply + (reply->length << 2);
+
+ if (client->swapped)
+ {
+ register char n;
+
+ swaps (&reply->sequenceNumber, n);
+ swapl (&reply->length, n);
+ }
+
+ WriteToClient (client, bytes, (char *)reply);
+
+ xfree (reply);
+
+ return (client->noClientException);
+}
+
+static int
+LbxUnstallClient(data, id)
+ pointer data;
+ XID id;
+{
+ LbxColormapPriv *cmapPriv = (LbxColormapPriv *)data;
+ LbxStalled **prev;
+ ClientPtr client;
+
+ for (prev = &cmapPriv->stalled_clients; *prev && (*prev)->id != id; )
+ prev = &(*prev)->next;
+ *prev = (*prev)->next;
+ client = clients[CLIENT_ID(id)];
+ if (!client->clientGone)
+ AttendClient(client);
+ return 0;
+}
+
+void
+LbxReleaseCmap(pmap, smart)
+ ColormapPtr pmap;
+ Bool smart;
+{
+ LbxColormapPriv *cmapPriv;
+ ColormapPtr *prev;
+
+ if (!pmap->devPrivates)
+ return;
+ cmapPriv = (LbxColormapPriv *)
+ (pmap->devPrivates[lbxColormapPrivIndex].ptr);
+ if (!cmapPriv || (cmapPriv->grab_status == CMAP_NOT_GRABBED))
+ return;
+
+ for (prev = &cmapPriv->grabber->grabbedCmaps; *prev && *prev != pmap; )
+ prev = &((LbxColormapPriv *)
+ (*prev)->devPrivates[lbxColormapPrivIndex].ptr)->next;
+ if (*prev == pmap)
+ *prev = cmapPriv->next;
+
+ while (cmapPriv->stalled_clients)
+ FreeResource(cmapPriv->stalled_clients->id, 0);
+
+ cmapPriv->grab_status = CMAP_NOT_GRABBED;
+ cmapPriv->last_grabber = smart ? cmapPriv->grabber->uid : 0;
+ cmapPriv->grabber = NULL;
+ cmapPriv->smart_grab = smart;
+}
+
+/*
+ * Handle a colormap release request from a proxy.
+ */
+
+int
+ProcLbxReleaseCmap(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxReleaseCmapReq);
+ ColormapPtr pmap;
+
+#ifdef COLOR_DEBUG
+ fprintf (stderr, "Got colormap release request, ");
+ fprintf (stderr, "seq = 0x%x, proxy = %d, client = %d, cmap = 0x%x\n",
+ client->sequence, LbxProxyID(client), client->index, stuff->cmap);
+#endif
+
+ pmap = (ColormapPtr) SecurityLookupIDByType (client, stuff->cmap,
+ RT_COLORMAP,
+ SecurityWriteAccess);
+
+ if (!pmap)
+ {
+ client->errorValue = stuff->cmap;
+ return BadColor;
+ }
+
+ if (LbxGrabbedByClient(client, pmap))
+ LbxReleaseCmap(pmap, TRUE);
+ return Success;
+}
+
+
+/*
+ * Handle an LbxAllocColor request. The proxy did the alloc and
+ * is telling the server what rgb and pixel value to use.
+ */
+
+int
+ProcLbxAllocColor(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxAllocColorReq);
+ ColormapPtr pmap;
+ CARD32 pixel = stuff->pixel;
+
+ REQUEST_SIZE_MATCH (xLbxAllocColorReq);
+ pmap = (ColormapPtr) SecurityLookupIDByType (client, stuff->cmap,
+ RT_COLORMAP,
+ SecurityWriteAccess);
+
+#ifdef COLOR_DEBUG
+ fprintf (stderr,
+ "Got LBX alloc color: seq = 0x%x, proxy = %d, client = %d\n",
+ client->sequence, LbxProxyID(client), client->index);
+ fprintf (stderr, " cmap = 0x%x, pixel = %d, rgb = (%d,%d,%d)\n",
+ stuff->cmap, stuff->pixel, stuff->red, stuff->green, stuff->blue);
+#endif
+
+ if (pmap)
+ {
+ int status;
+ if (!LbxGrabbedByClient(client, pmap))
+ return BadAccess;
+
+ status = AllocColor (pmap,
+ &stuff->red, &stuff->green, &stuff->blue,
+ &pixel, client->index);
+
+ if (status == Success && pixel != stuff->pixel)
+ {
+ /*
+ * Internal error - Proxy allocated different pixel from server
+ */
+#ifdef COLOR_DEBUG
+ fprintf(stderr, "got pixel %d (%d, %d, %d), expected %d\n",
+ pixel, stuff->red, stuff->green, stuff->blue, stuff->pixel);
+#endif
+ FreeColors (pmap, client->index, 1, &pixel, 0L);
+ return BadAlloc;
+ }
+
+ return status;
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (BadColor);
+ }
+}
+
+
+/*
+ * The proxy sends an LbxIncrementPixel request when it short circuits
+ * an AllocColor. The server must bump up the reference count the
+ * specified amount.
+ */
+
+int
+ProcLbxIncrementPixel(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxIncrementPixelReq);
+ ColormapPtr pmap;
+ EntryPtr pent;
+ Pixel pixel;
+ unsigned short red, green, blue;
+ VisualPtr pVisual;
+ int status;
+
+#ifdef COLOR_DEBUG
+ fprintf (stderr,
+ "Got LBX increment pixel: seq = 0x%x, proxy = %d, client = %d\n",
+ client->sequence, LbxProxyID(client), client->index);
+ fprintf (stderr, " cmap = 0x%x, pixel = %d\n",
+ stuff->cmap, stuff->pixel);
+#endif
+
+ /*
+ * Looks up the color associated with the pixel, and then call
+ * AllocColor() - a bit round-about, but it should work.
+ */
+
+ pmap = (ColormapPtr) SecurityLookupIDByType(client, stuff->cmap,
+ RT_COLORMAP,
+ SecurityWriteAccess);
+ if (!pmap) {
+ client->errorValue = stuff->cmap;
+ return BadColor;
+ }
+
+ pixel = stuff->pixel;
+
+ switch (pmap->class) {
+ case StaticColor:
+ case StaticGray:
+ red = pmap->red[pixel].co.local.red;
+ green = pmap->red[pixel].co.local.green;
+ blue = pmap->red[pixel].co.local.blue;
+ break;
+ case GrayScale:
+ case PseudoColor:
+ pent = pmap->red + pixel;
+ red = pent->co.local.red;
+ green = pent->co.local.green;
+ blue = pent->co.local.blue;
+ break;
+ default:
+ pVisual = pmap->pVisual;
+ red = pmap->red[(pixel & pVisual->redMask) >> pVisual->offsetRed].co.local.red;
+ green = pmap->green[(pixel & pVisual->greenMask) >> pVisual->offsetGreen].co.local.green;
+ blue = pmap->blue[(pixel & pVisual->blueMask) >> pVisual->offsetBlue].co.local.blue;
+ break;
+ }
+
+ status = AllocColor(pmap, &red, &green, &blue, &pixel, client->index);
+
+ if (status == Success && pixel != stuff->pixel)
+ {
+ /*
+ * Internal error - Proxy allocated different pixel from server
+ */
+#ifdef COLOR_DEBUG
+ fprintf(stderr, "got pixel %d, expected %d\n", pixel, stuff->pixel);
+#endif
+ FreeColors (pmap, client->index, 1, &pixel, 0L);
+ return BadAlloc;
+ }
+
+ return status;
+}
diff --git a/xc/programs/Xserver/lbx/lbxdata.h b/xc/programs/Xserver/lbx/lbxdata.h
new file mode 100644
index 000000000..fa9893460
--- /dev/null
+++ b/xc/programs/Xserver/lbx/lbxdata.h
@@ -0,0 +1,44 @@
+/* $XConsortium: lbxdata.h /main/6 1996/11/15 21:15:42 rws $ */
+/*
+ * Copyright 1994 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef _LBXDATA_H_
+#define _LBXDATA_H_
+#define NEED_REPLIES
+#include "X.h"
+#include "Xproto.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "dixfontstr.h"
+
+extern int lbx_font_private;
+
+typedef struct _fonttaginfo {
+ XID tid;
+ FontPtr pfont;
+ unsigned long size;
+ int compression;
+ xLbxFontInfo *fontinfo;
+} FontTagInfoRec, *FontTagInfoPtr;
+
+#endif /* _LBXDATA_H_ */
diff --git a/xc/programs/Xserver/lbx/lbxdix.c b/xc/programs/Xserver/lbx/lbxdix.c
new file mode 100644
index 000000000..4fde16b19
--- /dev/null
+++ b/xc/programs/Xserver/lbx/lbxdix.c
@@ -0,0 +1,884 @@
+/* $TOG: lbxdix.c /main/30 1998/05/15 10:29:37 msr $ */
+/*
+
+Copyright 1998 The Open Group
+
+All Rights Reserved.
+
+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 1993 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/lbx/lbxdix.c,v 1.3 1999/06/13 16:18:16 dawes Exp $ */
+
+/* various bits of DIX-level mangling */
+
+#include <sys/types.h>
+#include <stdio.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 "inputstr.h"
+#include "servermd.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "propertyst.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "lbxserve.h"
+#include "lbxtags.h"
+#include "lbxdata.h"
+#include "Xfuncproto.h"
+
+extern void CopySwap32Write();
+extern int (*ProcVector[256]) ();
+extern int (*SwappedProcVector[256]) ();
+extern void (*ReplySwapVector[256]) ();
+
+extern void LbxWriteSConnSetupPrefix();
+
+int lbx_font_private = -1;
+
+void
+LbxDixInit()
+{
+ TagInit();
+ lbx_font_private = AllocateFontPrivateIndex();
+}
+
+/* ARGSUSED */
+void
+LbxAllowMotion(client, num)
+ ClientPtr client;
+ int num;
+{
+ LbxProxyPtr proxy = LbxProxy(client);
+ proxy->motion_allowed_events += num;
+}
+
+extern WindowPtr *WindowTable;
+extern xConnSetupPrefix connSetupPrefix;
+extern char *ConnectionInfo;
+extern int connBlockScreenStart;
+
+int
+LbxSendConnSetup(client, reason)
+ ClientPtr client;
+ char *reason;
+{
+ int dlength;
+ int i, ndex, lim, wndex;
+ CARD32 dataBuf[16];
+ xLbxConnSetupPrefix csp;
+ NewClientInfoRec nci;
+ LbxProxyPtr proxy = LbxProxy(client);
+
+ if (reason) {
+ SendConnSetup(client, reason);
+ LbxForceOutput(proxy); /* expedient to avoid another state variable */
+ return (client->noClientException);
+ }
+
+ IncrementClientCount();
+
+ client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
+ client->sequence = 0;
+ dataBuf[0] = client->clientAsMask;
+
+ csp.success = TRUE;
+ csp.majorVersion = connSetupPrefix.majorVersion;
+ csp.minorVersion = connSetupPrefix.minorVersion;
+ csp.tag = 0;
+#ifdef XAPPGROUP
+ if (!client->appgroup) {
+#endif
+ csp.changeType = 1; /* LbxNormalDeltas */
+ csp.length = 2 + /* tag + resource-id-base */
+ screenInfo.numScreens; /* input-mask per screen */
+ wndex = 0; ndex = 1; lim = screenInfo.numScreens;
+#ifdef XAPPGROUP
+ } else {
+ csp.changeType = 2; /* LbxAppGroupDeltas */
+ csp.length = 7 + /* tag, res-id-base, root, visual, colormap, b&w-pix */
+ 1 + screenInfo.numScreens - screenInfo.numVideoScreens;
+ XagGetDeltaInfo (client, &dataBuf[1]);
+ for (i = 0; i < MAXSCREENS; i++) {
+ if ((CARD32) WindowTable[i]->drawable.id == dataBuf[1]) {
+ dataBuf[6] = WindowTable[i]->eventMask | wOtherEventMasks(WindowTable[i]);
+ break;
+ }
+ }
+ wndex = screenInfo.numVideoScreens;
+ ndex = 7;
+ lim = screenInfo.numScreens - screenInfo.numVideoScreens;
+ }
+#endif
+ for (i = 0; i < lim; i++, ndex++, wndex++) {
+ dataBuf[ndex] =
+ WindowTable[wndex]->eventMask | wOtherEventMasks(WindowTable[wndex]);
+ }
+ dlength = (csp.length - 1) << 2;
+
+ if (LbxProxyClient(proxy)->swapped) {
+ swaps(&csp.length, i);
+ }
+
+ if (client->swapped) {
+ LbxWriteSConnSetupPrefix(client, &csp);
+ SwapLongs(dataBuf, (1 + screenInfo.numScreens));
+ WriteToClient(client, dlength, (pointer) dataBuf);
+ } else {
+ WriteToClient(client, sizeof(xLbxConnSetupPrefix), (char *) &csp);
+ WriteToClient(client, dlength, (pointer) dataBuf);
+ }
+
+ LbxForceOutput(proxy); /* expedient to avoid another state variable */
+ client->clientState = ClientStateRunning;
+ if (ClientStateCallback) {
+ if (LbxProxyClient(proxy)->swapped != client->swapped) {
+ swaps(&csp.length, i);
+ }
+ nci.client = client;
+ nci.prefix = (xConnSetupPrefix*) &csp;
+ nci.setup = (xConnSetup *) ConnectionInfo;
+ CallCallbacks(&ClientStateCallback, (pointer) &nci);
+ }
+
+ return client->noClientException;
+}
+
+extern InputInfo inputInfo;
+
+static XID modifier_map_tag;
+
+int
+LbxGetModifierMapping(client)
+ ClientPtr client;
+{
+ TagData td;
+ pointer tagdata;
+ xLbxGetModifierMappingReply rep;
+ register KeyClassPtr keyc = inputInfo.keyboard->key;
+ int dlength = keyc->maxKeysPerModifier << 3;
+ Bool tag_known = FALSE,
+ send_data;
+ int n;
+
+ if (!modifier_map_tag) {
+ tagdata = (pointer) keyc->modifierKeyMap;
+ TagSaveTag(LbxTagTypeModmap, dlength, tagdata, &modifier_map_tag);
+ } else {
+ td = TagGetTag(modifier_map_tag);
+ tagdata = td->tdata;
+ tag_known = TagProxyMarked(modifier_map_tag, LbxProxyID(client));
+ }
+ if (modifier_map_tag)
+ TagMarkProxy(modifier_map_tag, LbxProxyID(client));
+
+ send_data = (!modifier_map_tag || !tag_known);
+
+ rep.type = X_Reply;
+ rep.keyspermod = keyc->maxKeysPerModifier;
+ rep.sequenceNumber = client->sequence;
+ rep.tag = modifier_map_tag;
+ rep.pad0 = rep.pad1 = rep.pad2 = rep.pad3 = rep.pad4 = 0;
+
+ if (send_data)
+ rep.length = dlength >> 2;
+ else
+ rep.length = 0;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.tag, n);
+ }
+ WriteToClient(client, sizeof(xLbxGetModifierMappingReply), (char *)&rep);
+
+ if (send_data)
+ WriteToClient(client, dlength, (char *) tagdata);
+
+ return client->noClientException;
+}
+
+void
+LbxFlushModifierMapTag()
+{
+
+ if (modifier_map_tag)
+ TagDeleteTag(modifier_map_tag);
+}
+
+static XID keyboard_map_tag;
+
+int
+LbxGetKeyboardMapping(client)
+ ClientPtr client;
+{
+ TagData td;
+ pointer tagdata;
+ xLbxGetKeyboardMappingReply rep;
+
+ REQUEST(xLbxGetKeyboardMappingReq);
+ KeySymsPtr curKeySyms = &inputInfo.keyboard->key->curKeySyms;
+ int dlength;
+ Bool tag_known = FALSE,
+ send_data;
+ int n;
+
+ REQUEST_SIZE_MATCH(xLbxGetKeyboardMappingReq);
+
+ if ((stuff->firstKeyCode < curKeySyms->minKeyCode) ||
+ (stuff->firstKeyCode > curKeySyms->maxKeyCode)) {
+ client->errorValue = stuff->firstKeyCode;
+ return BadValue;
+ }
+ if (stuff->firstKeyCode + stuff->count > curKeySyms->maxKeyCode + 1) {
+ client->errorValue = stuff->count;
+ return BadValue;
+ }
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.keysperkeycode = curKeySyms->mapWidth;
+ /* length is a count of 4 byte quantities and KeySyms are 4 bytes */
+
+ if (!keyboard_map_tag) {
+ tagdata = (pointer) &curKeySyms->map[(stuff->firstKeyCode -
+ curKeySyms->minKeyCode) * curKeySyms->mapWidth];
+ dlength = (curKeySyms->mapWidth * stuff->count);
+ TagSaveTag(LbxTagTypeKeymap, dlength, tagdata, &keyboard_map_tag);
+ } else {
+ td = TagGetTag(keyboard_map_tag);
+ tagdata = td->tdata;
+ tag_known = TagProxyMarked(keyboard_map_tag, LbxProxyID(client));
+ }
+ if (keyboard_map_tag)
+ TagMarkProxy(keyboard_map_tag, LbxProxyID(client));
+
+ send_data = (!keyboard_map_tag || !tag_known);
+ rep.type = X_Reply;
+ rep.keysperkeycode = curKeySyms->mapWidth;
+ rep.sequenceNumber = client->sequence;
+ rep.tag = keyboard_map_tag;
+ rep.pad0 = rep.pad1 = rep.pad2 = rep.pad3 = rep.pad4 = 0;
+
+ if (send_data)
+ rep.length = (curKeySyms->mapWidth * stuff->count);
+ else
+ rep.length = 0;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.tag, n);
+ }
+ WriteToClient(client, sizeof(xLbxGetKeyboardMappingReply), (char *)&rep);
+
+ if (send_data) {
+ client->pSwapReplyFunc = CopySwap32Write;
+ WriteSwappedDataToClient(client,
+ curKeySyms->mapWidth * stuff->count * sizeof(KeySym),
+ &curKeySyms->map[(stuff->firstKeyCode - curKeySyms->minKeyCode) *
+ curKeySyms->mapWidth]);
+ }
+ return client->noClientException;
+}
+
+void
+LbxFlushKeyboardMapTag()
+{
+ if (keyboard_map_tag)
+ TagDeleteTag(keyboard_map_tag);
+}
+
+/* counts number of bits needed to hold value */
+static int
+_bitsize(val)
+ int val;
+{
+ int bits = 1; /* always need one for sign bit */
+
+ if (val == 0)
+ return (bits);
+
+ if (val < 0) {
+ val = -val;
+ }
+ while (val) {
+ bits++;
+ val >>= 1;
+ }
+
+ return bits;
+
+}
+
+/*
+ * squashes the font (if possible), returning the new length and
+ * a pointer to the new data (which has been allocated). if it can't
+ * squish, it just returns a 0 and the data is sent in raw form.
+ */
+int _lbx_fi_junklen = sizeof(BYTE) * 2 + sizeof(CARD16) + sizeof(CARD32);
+
+static int
+squish_font_info(qfr, rlen, sqrep)
+ xQueryFontReply *qfr;
+ int rlen;
+ xLbxFontInfo **sqrep;
+{
+ int len,
+ hlen;
+ xLbxFontInfo *new;
+ xCharInfo *minb,
+ *maxb,
+ *ci,
+ bbox;
+ int i;
+ char *t;
+ xLbxCharInfo *chars;
+ int num_chars;
+
+ num_chars = qfr->nCharInfos;
+
+ if (num_chars == 0)
+ return 0;
+
+ minb = &qfr->minBounds;
+ maxb = &qfr->maxBounds;
+ /*
+ * first do the quick check -- if the attribute fields aren't all the
+ * same, punt
+ */
+
+ if (minb->attributes != maxb->attributes)
+ return 0;
+
+#define compute(field) \
+ bbox.field = max(_bitsize(minb->field), _bitsize(maxb->field))
+
+ compute(characterWidth);
+ compute(leftSideBearing);
+ compute(rightSideBearing);
+ compute(ascent);
+ compute(descent);
+
+#undef compute
+
+ /* make sure it fits */
+ if (!((bbox.characterWidth <= LBX_WIDTH_BITS) &&
+ (bbox.leftSideBearing <= LBX_LEFT_BITS) &&
+ (bbox.rightSideBearing <= LBX_RIGHT_BITS) &&
+ (bbox.ascent <= LBX_ASCENT_BITS) &&
+ (bbox.descent <= LBX_DESCENT_BITS))) {
+ return 0;
+ }
+
+ hlen = sizeof(xLbxFontInfo) + qfr->nFontProps * sizeof(xFontProp);
+
+ len = hlen + (num_chars * sizeof(xLbxCharInfo));
+
+ new = (xLbxFontInfo *) xalloc(len);
+ if (!new)
+ return 0;
+
+ /* gross hack to avoid copying all the fields */
+ t = (char *) qfr;
+ t += _lbx_fi_junklen;
+
+ /* copy all but the char infos */
+ memcpy((char *) new, (char *) t, hlen);
+
+ t = (char *) new;
+ t += hlen;
+ chars = (xLbxCharInfo *) t;
+
+ t = (char *) qfr;
+ t += sizeof(xQueryFontReply) + qfr->nFontProps * sizeof(xFontProp);
+ ci = (xCharInfo *) t;
+
+ /* now copy & pack the charinfos */
+ for (i = 0; i < num_chars; i++, chars++, ci++) {
+ chars->metrics = 0;
+ chars->metrics |= (LBX_MASK_BITS(ci->characterWidth, LBX_WIDTH_BITS)
+ << LBX_WIDTH_SHIFT);
+ chars->metrics |= (LBX_MASK_BITS(ci->leftSideBearing, LBX_LEFT_BITS)
+ << LBX_LEFT_SHIFT);
+ chars->metrics |= (LBX_MASK_BITS(ci->rightSideBearing, LBX_RIGHT_BITS)
+ << LBX_RIGHT_SHIFT);
+ chars->metrics |= (LBX_MASK_BITS(ci->ascent, LBX_ASCENT_BITS)
+ << LBX_ASCENT_SHIFT);
+ chars->metrics |= (LBX_MASK_BITS(ci->descent, LBX_DESCENT_BITS)
+ << LBX_DESCENT_SHIFT);
+ }
+
+ *sqrep = new;
+ return len;
+}
+
+int
+LbxQueryFont(client)
+ ClientPtr client;
+{
+ xQueryFontReply *reply;
+ xLbxQueryFontReply lbxrep;
+ FontPtr pFont;
+ register GC *pGC;
+ Bool send_data = FALSE;
+ Bool free_data = FALSE;
+ int rlength = 0;
+ FontTagInfoPtr ftip;
+ int sqlen = 0;
+ xLbxFontInfo *sqrep,
+ *sreply = NULL;
+
+ REQUEST(xLbxQueryFontReq);
+
+ REQUEST_SIZE_MATCH(xLbxQueryFontReq);
+
+ client->errorValue = stuff->fid; /* EITHER font or gc */
+ pFont = (FontPtr) SecurityLookupIDByType(client, stuff->fid, RT_FONT,
+ SecurityReadAccess);
+ if (!pFont) {
+ /* can't use VERIFY_GC because it might return BadGC */
+ pGC = (GC *) SecurityLookupIDByType(client, stuff->fid, RT_GC,
+ SecurityReadAccess);
+ if (!pGC || !pGC->font) { /* catch a non-existent builtin font */
+ client->errorValue = stuff->fid;
+ return (BadFont); /* procotol spec says only error is BadFont */
+ }
+ pFont = pGC->font;
+ }
+
+ /* get tag (if any) */
+ ftip = (FontTagInfoPtr) FontGetPrivate(pFont, lbx_font_private);
+
+ if (!ftip) {
+ xCharInfo *pmax = FONTINKMAX(pFont);
+ xCharInfo *pmin = FONTINKMIN(pFont);
+ int nprotoxcistructs;
+
+ nprotoxcistructs = (
+ pmax->rightSideBearing == pmin->rightSideBearing &&
+ pmax->leftSideBearing == pmin->leftSideBearing &&
+ pmax->descent == pmin->descent &&
+ pmax->ascent == pmin->ascent &&
+ pmax->characterWidth == pmin->characterWidth) ?
+ 0 : N2dChars(pFont);
+
+ rlength = sizeof(xQueryFontReply) +
+ FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) +
+ nprotoxcistructs * sizeof(xCharInfo);
+ reply = (xQueryFontReply *) xalloc(rlength);
+ if (!reply) {
+ return (BadAlloc);
+ }
+ free_data = TRUE;
+ send_data = TRUE;
+ QueryFont(pFont, reply, nprotoxcistructs);
+
+ sqlen = squish_font_info(reply, rlength, &sqrep);
+ if (!sqlen) { /* if it failed to squish, send it raw */
+ char *t;
+
+ lbxrep.compression = 0;
+
+ sqlen = rlength - _lbx_fi_junklen;
+ t = (char *) reply;
+ sqrep = (xLbxFontInfo *) (t + _lbx_fi_junklen);
+ } else {
+ lbxrep.compression = 1;
+ xfree(reply); /* no longer needed */
+ }
+ } else { /* just get data from tag */
+ sqrep = ftip->fontinfo;
+ sqlen = ftip->size;
+ lbxrep.compression = ftip->compression;
+ }
+
+ if (!ftip) {
+ /* data allocation is done when font is first queried */
+ ftip = (FontTagInfoPtr) xalloc(sizeof(FontTagInfoRec));
+ if (ftip &&
+ TagSaveTag(LbxTagTypeFont, sqlen, (pointer) ftip, &ftip->tid)) {
+ FontSetPrivate(pFont, lbx_font_private, (pointer) ftip);
+ ftip->pfont = pFont;
+ ftip->size = sqlen;
+ ftip->fontinfo = sqrep;
+ ftip->compression = lbxrep.compression;
+ free_data = FALSE;
+ } else {
+ xfree(ftip);
+ }
+ }
+ if (ftip) {
+ if (!TagProxyMarked(ftip->tid, LbxProxyID(client)))
+ send_data = TRUE;
+ TagMarkProxy(ftip->tid, LbxProxyID(client));
+ lbxrep.tag = ftip->tid;
+ } else {
+ lbxrep.tag = 0;
+ send_data = TRUE;
+ }
+
+ lbxrep.type = X_Reply;
+ lbxrep.sequenceNumber = client->sequence;
+ lbxrep.pad0 = lbxrep.pad1 = lbxrep.pad2 = lbxrep.pad3 = lbxrep.pad4 = 0;
+
+ if (send_data)
+ lbxrep.length = sqlen >> 2;
+ else
+ lbxrep.length = 0;
+
+ if (client->swapped) {
+ int n;
+
+ swaps(&lbxrep.sequenceNumber, n);
+ swapl(&lbxrep.length, n);
+ swapl(&lbxrep.tag, n);
+ sreply = (xLbxFontInfo *) ALLOCATE_LOCAL(sqlen);
+ if (!sreply)
+ return BadAlloc;
+ memcpy((char *) sreply, (char *) sqrep, sqlen);
+ LbxSwapFontInfo(sreply, lbxrep.compression);
+ sqrep = sreply;
+ }
+ WriteToClient(client, sizeof(xLbxQueryFontReply), (char *) &lbxrep);
+ if (send_data)
+ WriteToClient(client, sqlen, (char *)sqrep);
+ if (free_data)
+ xfree(sqrep);
+ if (sreply)
+ DEALLOCATE_LOCAL(sreply);
+ return (client->noClientException);
+}
+
+void
+LbxFreeFontTag(pfont)
+ FontPtr pfont;
+{
+ FontTagInfoPtr ftip;
+
+ ftip = (FontTagInfoPtr) FontGetPrivate(pfont, lbx_font_private);
+ if (ftip)
+ TagDeleteTag(ftip->tid);
+}
+
+LbxInvalidateTag(client, tag)
+ ClientPtr client;
+ XID tag;
+{
+ TagClearProxy(tag, LbxProxyID(client));
+ return client->noClientException;
+}
+
+void
+LbxSendInvalidateTag(client, tag, tagtype)
+ ClientPtr client;
+ XID tag;
+ int tagtype;
+{
+ xLbxInvalidateTagEvent ev;
+ int n;
+
+ ev.type = LbxEventCode;
+ ev.lbxType = LbxInvalidateTagEvent;
+ ev.sequenceNumber = client->sequence;
+ ev.tag = tag;
+ ev.tagType = tagtype;
+ ev.pad1 = ev.pad2 = ev.pad3 = ev.pad4 = ev.pad5 = 0;
+
+ if (client->swapped) {
+ swaps(&ev.sequenceNumber, n);
+ swapl(&ev.tag, n);
+ swapl(&ev.tagType, n);
+ }
+ DBG(DBG_CLIENT, (stderr, "Invalidating tag %d\n", tag));
+ WriteToClient(client, sizeof(xLbxInvalidateTagEvent), (char *) &ev);
+ LbxForceOutput(LbxProxy(client));
+}
+
+static void
+LbxSendSendTagData(pid, tag, tagtype)
+ int pid;
+ XID tag;
+ int tagtype;
+{
+ xLbxSendTagDataEvent ev;
+ int n;
+ LbxProxyPtr proxy;
+ ClientPtr client;
+ LbxClientPtr lbxcp;
+
+ proxy = LbxPidToProxy(pid);
+ lbxcp = (proxy != NULL) ? proxy->lbxClients[0] : NULL;
+ if (lbxcp && (client = lbxcp->client)) {
+ ev.type = LbxEventCode;
+ ev.lbxType = LbxSendTagDataEvent;
+ ev.sequenceNumber = client->sequence;
+ ev.tag = tag;
+ ev.tagType = tagtype;
+ ev.pad1 = ev.pad2 = ev.pad3 = ev.pad4 = ev.pad5 = 0;
+
+ if (client->swapped) {
+ swaps(&ev.sequenceNumber, n);
+ swapl(&ev.tag, n);
+ swapl(&ev.tagType, n);
+ }
+ DBG(DBG_CLIENT, (stderr, "Requesting tag %d\n", tag));
+ WriteToClient(client, sizeof(xLbxSendTagDataEvent), (char *) &ev);
+ LbxForceOutput(proxy);
+ }
+}
+
+/*
+ * keep track of clients stalled waiting for tags to come back from
+ * a proxy. since multiple clinets can be waiting for the same tag,
+ * we have to keep a list of all of them.
+ */
+
+typedef struct _sendtagq {
+ XID tag;
+ int num_stalled;
+ ClientPtr *stalled_clients;
+ struct _sendtagq *next;
+} SendTagQRec, *SendTagQPtr;
+
+static SendTagQPtr queried_tags = NULL;
+
+#define LbxSendTagFailed -1
+#define LbxSendTagSendIt 0
+#define LbxSendTagAlreadySent 1
+
+static Bool
+LbxQueueSendTag(client, tag)
+ ClientPtr client;
+ XID tag;
+{
+ SendTagQPtr stqp, *prev, new;
+ ClientPtr *newlist;
+
+
+ /* see if we're asking for one already in the pipeline */
+ for (prev = &queried_tags; stqp = *prev; prev = &stqp->next) {
+ if (stqp->tag == tag) {
+ /* add new client to list */
+ newlist = (ClientPtr *) xrealloc(stqp->stalled_clients,
+ (sizeof(ClientPtr) * (stqp->num_stalled + 1)));
+ if (!newlist)
+ return LbxSendTagFailed;
+ newlist[stqp->num_stalled++] = client;
+ stqp->stalled_clients = newlist;
+ DBG(DBG_CLIENT, (stderr, "Additional client requesting tag %d\n", tag));
+ return LbxSendTagAlreadySent;
+ }
+ }
+
+ /* make new one */
+ new = (SendTagQPtr) xalloc(sizeof(SendTagQRec));
+ newlist = (ClientPtr *) xalloc(sizeof(ClientPtr));
+ if (!new || !newlist) {
+ xfree(new);
+ xfree(newlist);
+ return LbxSendTagFailed;
+ }
+ *newlist = client;
+ new->stalled_clients = newlist;
+ new->num_stalled = 1;
+ new->tag = tag;
+ new->next = NULL;
+
+ /* stick on end of list */
+ *prev = new;
+ return LbxSendTagSendIt;
+}
+
+SendTagQPtr
+LbxFindQTag(tag)
+ XID tag;
+{
+ SendTagQPtr stqp;
+
+ for (stqp = queried_tags; stqp; stqp = stqp->next) {
+ if (stqp->tag == tag)
+ return stqp;
+ }
+ return NULL;
+}
+
+static void
+LbxFreeQTag(stqp)
+ SendTagQPtr stqp;
+{
+ xfree(stqp->stalled_clients);
+ xfree(stqp);
+}
+
+static void
+LbxRemoveQTag(tag)
+ XID tag;
+{
+ SendTagQPtr stqp, *prev;
+
+ for (prev = &queried_tags; stqp = *prev; prev = &stqp->next) {
+ if (stqp->tag == tag) {
+ *prev = stqp->next;
+ LbxFreeQTag(stqp);
+ return;
+ }
+ }
+}
+
+Bool
+LbxFlushQTag(tag)
+ XID tag;
+{
+ SendTagQPtr stqp;
+ ClientPtr *cp;
+
+ stqp = LbxFindQTag(tag);
+ if (!stqp)
+ return FALSE;
+ for (cp = stqp->stalled_clients; --stqp->num_stalled >= 0; cp++)
+ AttendClient(*cp);
+ LbxRemoveQTag(tag);
+ return TRUE;
+}
+
+void
+ProcessQTagZombies()
+{
+ SendTagQPtr stqp;
+ ClientPtr *out, *in;
+ int i;
+
+ for (stqp = queried_tags; stqp; stqp = stqp->next) {
+ out = stqp->stalled_clients;
+ for (in = out, i = stqp->num_stalled; --i >= 0; in++) {
+ if ((*in)->clientGone)
+ --stqp->num_stalled;
+ else
+ *out++ = *in;
+ }
+ }
+}
+
+/*
+ * server sends this
+ */
+
+void
+LbxQueryTagData(client, owner_pid, tag, tagtype)
+ ClientPtr client;
+ int owner_pid;
+ XID tag;
+ int tagtype;
+{
+ /* save the info and the client being stalled */
+ if (LbxQueueSendTag(client, tag) == LbxSendTagSendIt)
+ LbxSendSendTagData(owner_pid, tag, tagtype);
+}
+
+/*
+ * server recieves this
+ */
+int
+LbxTagData(client, tag, len, data)
+ ClientPtr client;
+ XID tag;
+ unsigned long len;
+ pointer data;
+{
+ TagData td;
+ PropertyPtr pProp;
+
+ td = TagGetTag(tag);
+ if (!td || td->data_type != LbxTagTypeProperty)
+ return Success;
+ if (!td->global) {
+ /* somebody changed contents while we were querying */
+ TagDeleteTag(tag);
+ return Success;
+ }
+ LbxFlushQTag(tag);
+ pProp = (PropertyPtr) td->tdata;
+ if (pProp->tag_id != tag || pProp->owner_pid != LbxProxyID(client))
+ return Success;
+ pProp->owner_pid = 0;
+ if (len != td->size)
+ pProp->size = len / (pProp->format >> 3);
+ pProp->data = xrealloc(pProp->data, len);
+ if (!pProp->data) {
+ pProp->size = 0;
+ return Success;
+ }
+ if (client->swapped) {
+ switch (pProp->format) {
+ case 32:
+ SwapLongs((CARD32 *) data, len >> 2);
+ break;
+ case 16:
+ SwapShorts((short *) data, len >> 1);
+ break;
+ default:
+ break;
+ }
+ }
+ memmove((char *) pProp->data, (char *) data, len);
+ return Success;
+}
+
+/* when server resets, need to reset global tags */
+void
+LbxResetTags()
+{
+ SendTagQPtr stqp;
+
+ modifier_map_tag = 0;
+ keyboard_map_tag = 0;
+
+ /* clean out any pending tag requests */
+ while (stqp = queried_tags) {
+ queried_tags = stqp->next;
+ LbxFreeQTag(stqp);
+ }
+}
diff --git a/xc/programs/Xserver/lbx/lbxexts.c b/xc/programs/Xserver/lbx/lbxexts.c
new file mode 100644
index 000000000..a1333b57f
--- /dev/null
+++ b/xc/programs/Xserver/lbx/lbxexts.c
@@ -0,0 +1,270 @@
+/* $XConsortium: lbxexts.c /main/9 1996/12/15 21:25:42 rws $ */
+/*
+ * Copyright 1994 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "dixstruct.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "extensions/security.h"
+#endif
+
+typedef struct _lbxext {
+ char *name;
+ char **aliases;
+ int num_aliases;
+ int idx;
+ int opcode;
+ int ev_base;
+ int err_base;
+ int num_reqs;
+ CARD8 *rep_mask;
+ CARD8 *ev_mask;
+#ifdef XCSECURITY
+ Bool secure;
+#endif
+} LbxExtensionEntry;
+
+static LbxExtensionEntry **lbx_extensions = NULL;
+static int num_exts = 0;
+
+
+Bool
+LbxAddExtension(name, opcode, ev_base, err_base)
+ char *name;
+ int opcode;
+ int ev_base,
+ err_base;
+{
+ int i;
+ register LbxExtensionEntry *ext,
+ **newexts;
+
+ ext = (LbxExtensionEntry *) xalloc(sizeof(LbxExtensionEntry));
+ if (!ext)
+ return FALSE;
+ ext->name = (char *) xalloc(strlen(name) + 1);
+ ext->num_aliases = 0;
+ ext->aliases = (char **) NULL;
+ if (!ext->name) {
+ xfree(ext);
+ return FALSE;
+ }
+ strcpy(ext->name, name);
+ i = num_exts;
+ newexts = (LbxExtensionEntry **) xrealloc(lbx_extensions,
+ (i + 1) * sizeof(LbxExtensionEntry *));
+ if (!newexts) {
+ xfree(ext->name);
+ xfree(ext);
+ return FALSE;
+ }
+ num_exts++;
+ lbx_extensions = newexts;
+ lbx_extensions[i] = ext;
+ ext->idx = i;
+
+ ext->opcode = opcode;;
+ ext->ev_base = ev_base;;
+ ext->err_base = err_base;
+ ext->ev_mask = NULL;
+ ext->rep_mask = NULL;
+ ext->num_reqs = 0;
+#ifdef XCSECURITY
+ ext->secure = FALSE;
+#endif
+
+ return TRUE;
+}
+
+Bool
+LbxAddExtensionAlias(idx, alias)
+ int idx;
+ char *alias;
+{
+ char *name;
+ char **aliases;
+ LbxExtensionEntry *ext = lbx_extensions[idx];
+
+ aliases = (char **) xrealloc(ext->aliases,
+ (ext->num_aliases + 1) * sizeof(char *));
+ if (!aliases)
+ return FALSE;
+ ext->aliases = aliases;
+ name = (char *) xalloc(strlen(alias) + 1);
+ if (!name)
+ return FALSE;
+ strcpy(name, alias);
+ ext->aliases[ext->num_aliases] = name;
+ ext->num_aliases++;
+ return TRUE;
+}
+
+static int
+LbxFindExtension(extname, len)
+ char *extname;
+ int len;
+{
+ int i, j;
+
+ for (i = 0; i < num_exts; i++) {
+ if ((strlen(lbx_extensions[i]->name) == len) &&
+ (strncmp(lbx_extensions[i]->name, extname, len) == 0))
+ return i;
+ for (j = lbx_extensions[i]->num_aliases; --j >= 0;) {
+ if ((strlen(lbx_extensions[i]->aliases[j]) == len) &&
+ (strncmp(lbx_extensions[i]->aliases[j], extname, len) == 0))
+ return i;
+ }
+ }
+ return -1;
+}
+
+void
+LbxDeclareExtensionSecurity(extname, secure)
+ char *extname;
+ Bool secure;
+{
+#ifdef XCSECURITY
+ int i = LbxFindExtension(extname, strlen(extname));
+ if (i >= 0)
+ lbx_extensions[i]->secure = secure;
+#endif
+}
+
+Bool
+LbxRegisterExtensionGenerationMasks(idx, num_reqs, rep_mask, ev_mask)
+ int idx;
+ int num_reqs;
+ char *rep_mask,
+ *ev_mask;
+{
+ LbxExtensionEntry *ext = lbx_extensions[idx];
+ CARD8 *nrm,
+ *nem;
+ int mlen = mlen = num_reqs / (8 * sizeof(CARD8)) + 1;
+
+ nrm = (CARD8 *) xalloc(sizeof(CARD8) * mlen);
+ nem = (CARD8 *) xalloc(sizeof(CARD8) * mlen);
+
+ if (!nrm || !nem) {
+ xfree(nrm);
+ xfree(nem);
+ return FALSE;
+ }
+ memcpy((char *) nrm, (char *) rep_mask, mlen);
+ memcpy((char *) nem, (char *) ev_mask, mlen);
+ ext->rep_mask = nrm;
+ ext->ev_mask = nem;
+ ext->num_reqs = num_reqs;
+
+ return TRUE;
+}
+
+int
+LbxQueryExtension(client, ename, nlen)
+ ClientPtr client;
+ char *ename;
+ int nlen;
+{
+ xLbxQueryExtensionReply rep;
+ int i;
+ int mlen = 0;
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.major_opcode = 0;
+ rep.present = FALSE;
+ rep.length = 0;
+ rep.pad0 = rep.pad1 = rep.pad2 = rep.pad3 = rep.pad4 = 0;
+
+ i = LbxFindExtension(ename, nlen);
+
+ if (i < 0
+#ifdef XCSECURITY
+ /* don't show insecure extensions to untrusted clients */
+ || (client->trustLevel == XSecurityClientUntrusted &&
+ !lbx_extensions[i]->secure)
+#endif
+ )
+ rep.present = FALSE;
+ else {
+ rep.present = TRUE;
+ rep.major_opcode = lbx_extensions[i]->opcode;
+ rep.first_event = lbx_extensions[i]->ev_base;
+ rep.first_error = lbx_extensions[i]->err_base;
+ rep.numReqs = lbx_extensions[i]->num_reqs;
+ if (lbx_extensions[i]->rep_mask) {
+ mlen = (lbx_extensions[i]->num_reqs + 7) >> 3;
+ rep.length = ((mlen + 3) >> 2) * 2;
+ }
+ }
+ if (client->swapped) {
+ char n;
+
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+ WriteToClient(client, sizeof(xLbxQueryExtensionReply), (char *)&rep);
+ if (mlen) {
+ WriteToClient(client, mlen, (char *)lbx_extensions[i]->rep_mask);
+ WriteToClient(client, mlen, (char *)lbx_extensions[i]->ev_mask);
+ }
+ return Success;
+}
+
+LbxCloseDownExtensions()
+{
+ int i;
+
+ for (i = 0; i < num_exts; i++) {
+ xfree(lbx_extensions[i]->name);
+ xfree(lbx_extensions[i]->aliases);
+ xfree(lbx_extensions[i]->rep_mask);
+ xfree(lbx_extensions[i]->ev_mask);
+ xfree(lbx_extensions[i]);
+ }
+ xfree(lbx_extensions);
+ lbx_extensions = NULL;
+ num_exts = 0;
+}
+
+void
+LbxSetReqMask(mask, req, on)
+ CARD8 *mask;
+ int req;
+ Bool on;
+{
+ int mword = req / (8 * sizeof(CARD8));
+
+ req = req % (8 * sizeof(CARD8));
+ if (on) {
+ mask[mword] |= (1 << req);
+ } else {
+ mask[mword] &= ~(1 << req);
+ }
+}
diff --git a/xc/programs/Xserver/lbx/lbxgfx.c b/xc/programs/Xserver/lbx/lbxgfx.c
new file mode 100644
index 000000000..0dc72ad51
--- /dev/null
+++ b/xc/programs/Xserver/lbx/lbxgfx.c
@@ -0,0 +1,867 @@
+/* $XConsortium: lbxgfx.c /main/27 1996/12/15 21:25:50 rws $ */
+/*
+ * Copyright 1993 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* various bits of DIX-level mangling */
+
+#include <sys/types.h>
+#include <stdio.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 "servermd.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "lbxserve.h"
+#include "lbxtags.h"
+#include "Xfuncproto.h"
+#include "lbximage.h"
+#include "lbxsrvopts.h"
+
+#define DrawableCache(client) (LbxClient(client)->drawableCache)
+#define GContextCache(client) (LbxClient(client)->gcontextCache)
+
+extern int (*ProcVector[256])();
+
+static void
+push (cache, xid)
+ XID cache[GFX_CACHE_SIZE];
+ XID xid;
+{
+ memmove (cache+1, cache, (GFX_CACHE_SIZE - 1) * sizeof (cache[0]));
+ cache[0] = xid;
+}
+
+static XID
+use (cache, i)
+ XID cache[GFX_CACHE_SIZE];
+ int i;
+{
+ XID tmp;
+
+ tmp = cache[i];
+ if (i != 0)
+ {
+ memmove (cache + 1, cache, i * sizeof (cache[0]));
+ cache[0] = tmp;
+ }
+ return tmp;
+}
+
+extern char *ConnectionInfo;
+
+int
+LbxDecodeGFXCache(client, cacheEnts, after, drawp, gcp)
+ ClientPtr client;
+ CARD8 cacheEnts;
+ char *after;
+ Drawable *drawp;
+ GContext *gcp;
+{
+ int skip;
+ int dcache, gcache;
+
+ dcache = GFXdCacheEnt (cacheEnts);
+ gcache = GFXgCacheEnt (cacheEnts);
+ skip = 0;
+ if (dcache == GFXCacheNone)
+ {
+ memcpy (drawp, after, sizeof (Drawable));
+ push (DrawableCache(client), *drawp);
+ after += sizeof (Drawable);
+ skip += sizeof (Drawable);
+ }
+ else
+ *drawp = use (DrawableCache(client), dcache);
+ if (gcache == GFXCacheNone)
+ {
+ memcpy (gcp, after, sizeof (GContext));
+ push (GContextCache(client), *gcp);
+ skip += sizeof (GContext);
+ }
+ else
+ *gcp = use (GContextCache(client), gcache);
+ return skip;
+}
+
+int
+LbxDecodeDrawableCache(client, cacheEnts, after, drawp)
+ ClientPtr client;
+ CARD8 cacheEnts;
+ char *after;
+ Drawable *drawp;
+{
+ int skip;
+ int dcache;
+
+ dcache = GFXdCacheEnt (cacheEnts);
+ skip = 0;
+ if (dcache == GFXCacheNone)
+ {
+ memcpy (drawp, after, sizeof (Drawable));
+ push (DrawableCache(client), *drawp);
+ after += sizeof (Drawable);
+ skip += sizeof (Drawable);
+ }
+ else
+ *drawp = use (DrawableCache(client), dcache);
+ return skip;
+}
+
+int
+LbxDecodeGCCache(client, cacheEnts, after, gcp)
+ ClientPtr client;
+ CARD8 cacheEnts;
+ char *after;
+ GContext *gcp;
+{
+ int skip;
+ int gcache;
+
+ gcache = GFXgCacheEnt (cacheEnts);
+ skip = 0;
+ if (gcache == GFXCacheNone)
+ {
+ memcpy (gcp, after, sizeof (GContext));
+ push (GContextCache(client), *gcp);
+ after += sizeof (GContext);
+ skip += sizeof (GContext);
+ }
+ else
+ *gcp = use (GContextCache(client), gcache);
+ return skip;
+}
+
+#define GFX_GET_DRAWABLE_AND_GC(type,in,len) {\
+ int skip; \
+ len = (client->req_len << 2) - SIZEOF(type); \
+ in = ((char *) stuff) + SIZEOF(type);\
+ skip = LbxDecodeGFXCache(client, stuff->cacheEnts, in, \
+ &drawable, &gc); \
+ in += skip; \
+ len -= skip; \
+}
+
+#define GFX_GET_DST_DRAWABLE_AND_GC(type,in,len) {\
+ int skip; \
+ len = (client->req_len << 2) - SIZEOF(type); \
+ in = ((char *) stuff) + SIZEOF(type);\
+ skip = LbxDecodeGFXCache(client, stuff->cacheEnts, in, \
+ &dstDrawable, &gc); \
+ in += skip; \
+ len -= skip; \
+}
+
+#define GFX_GET_SRC_DST_DRAWABLE_AND_GC(type, in, len) { \
+ int skip; \
+ len = (client->req_len << 2) - SIZEOF(type); \
+ in = ((char *) stuff) + SIZEOF(type); \
+ skip = LbxDecodeDrawableCache(client, stuff->srcCache, in, \
+ &srcDrawable); \
+ in += skip; \
+ len -= skip; \
+ skip = LbxDecodeGFXCache(client, stuff->cacheEnts, in, \
+ &dstDrawable, &gc); \
+ in += skip; \
+ len -= skip; \
+}
+
+#define GFX_GET_GC(type, in, len) { \
+ int skip; \
+ len = (client->req_len << 2) - SIZEOF(type); \
+ in = ((char *) stuff) + SIZEOF(type); \
+ skip = LbxDecodeGCCache(client, stuff->gcCache, in, &gc); \
+ in += skip; \
+ len -= skip; \
+}
+
+int
+LbxDecodePoly(client, xreqtype, decode_rtn)
+ register ClientPtr client;
+ CARD8 xreqtype;
+ int (*decode_rtn)();
+{
+ REQUEST(xLbxPolyPointReq);
+ char *in;
+ xPolyPointReq *xreq;
+ int len;
+ int retval;
+ Drawable drawable;
+ GContext gc;
+
+ GFX_GET_DRAWABLE_AND_GC(xLbxPolyPointReq, in, len);
+ if ((xreq = (xPolyPointReq *)
+ xalloc(sizeof(xPolyPointReq) + (len << 1))) == NULL)
+ return BadAlloc;
+ len = (*decode_rtn)(in, in + len - stuff->padBytes, &xreq[1]);
+ xreq->reqType = xreqtype;
+ xreq->coordMode = 1;
+ xreq->drawable = drawable;
+ xreq->gc = gc;
+ xreq->length = client->req_len = (sizeof(xPolyPointReq) + len) >> 2;
+ client->requestBuffer = (pointer)xreq;
+
+ retval = (*ProcVector[xreqtype])(client);
+ xfree(xreq);
+ return retval;
+}
+
+int
+LbxDecodeFillPoly(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxFillPolyReq);
+ char *in;
+ xFillPolyReq *xreq;
+ int len;
+ int retval;
+ Drawable drawable;
+ GContext gc;
+
+ GFX_GET_DRAWABLE_AND_GC(xLbxFillPolyReq, in, len);
+ if ((xreq = (xFillPolyReq *)
+ xalloc(sizeof(xFillPolyReq) + (len << 1))) == NULL)
+ return BadAlloc;
+ len = LbxDecodePoints(in, in + len - stuff->padBytes, (short *) &xreq[1]);
+ xreq->reqType = X_FillPoly;
+ xreq->drawable = drawable;
+ xreq->gc = gc;
+ xreq->shape = stuff->shape;
+ xreq->coordMode = 1;
+ xreq->length = client->req_len = (sizeof(xFillPolyReq) + len) >> 2;
+ client->requestBuffer = (pointer)xreq;
+
+ retval = (*ProcVector[X_FillPoly])(client);
+ xfree(xreq);
+ return retval;
+}
+
+/*
+ * Routines for decoding line drawing requests
+ */
+
+#define DECODE_PSHORT(in, val) \
+ if ((*(in) & 0xf0) != 0xf0) \
+ (val) = *(CARD8 *)(in)++; \
+ else { \
+ (val) = ((*(CARD8 *)(in) & 0x0f) << 8) | *(CARD8 *)((in) + 1); \
+ if ((val) >= 0xe00) \
+ (val) -= 0x1000; \
+ else \
+ (val) += 0xf0; \
+ (in) += 2; \
+ }
+
+#define DECODE_SHORT(in, val) \
+ if ((*(in) & 0xf0) != 0x80) \
+ (val) = *(INT8 *)(in)++; \
+ else { \
+ (val) = ((*(CARD8 *)(in) & 0x0f) << 8) | *(CARD8 *)((in) + 1); \
+ if ((val) & 0x0800) \
+ (val) = ((val) | 0xf000) - 0x70; \
+ else \
+ (val) += 0x80; \
+ (in) += 2; \
+ }
+
+#define DECODE_USHORT(in, val) \
+ if ((*(in) & 0xf0) != 0xf0) \
+ (val) = *(CARD8 *)(in)++; \
+ else { \
+ (val) = (((*(CARD8 *)(in) & 0x0f) << 8) | *(CARD8 *)((in) + 1)) + 0xf0; \
+ (in) += 2; \
+ }
+
+#define DECODE_ANGLE(in, val) \
+ if (*(INT8 *)(in) >= 0x6e) \
+ (val) = (*(INT8 *)(in)++ - 0x67) * (15 << 6); \
+ else if (*(INT8 *)(in) >= 0x5a) \
+ (val) = (*(INT8 *)(in)++ - 0x5a) * (5 << 6); \
+ else if (*(INT8 *)(in) <= (INT8)0x91) \
+ (val) = (*(INT8 *)(in)++ - (INT8)0x98) * (15 << 6); \
+ else if (*(INT8 *)(in) <= (INT8)0xa5) \
+ (val) = (*(INT8 *)(in)++ - (INT8)0xa6) * (5 << 6); \
+ else { \
+ (val) = (*(CARD8 *)(in) << 8) | *(CARD8 *)((in) + 1); \
+ (in) += 2; \
+ }
+
+int
+LbxDecodePoints(in, inend, out)
+ register char *in;
+ char *inend;
+ register short *out;
+{
+ char *start_out = (char *)out;
+
+ while (in < inend) {
+ DECODE_SHORT(in, *out);
+ out++;
+ DECODE_SHORT(in, *out);
+ out++;
+ }
+ return ((char *)out - start_out);
+}
+
+int
+LbxDecodeSegment(in, inend, out)
+ register char *in;
+ char *inend;
+ register short *out;
+{
+ register short diff;
+ short last_x = 0;
+ short last_y = 0;
+ char *start_out = (char *)out;
+
+ while (in < inend) {
+ DECODE_SHORT(in, diff);
+ *out = last_x + diff;
+ last_x += diff;
+ out++;
+ DECODE_SHORT(in, diff);
+ *out = last_y + diff;
+ last_y += diff;
+ out++;
+
+ DECODE_SHORT(in, diff);
+ *out = last_x + diff;
+ out++;
+ DECODE_SHORT(in, diff);
+ *out = last_y + diff;
+ out++;
+ }
+ return ((char *)out - start_out);
+}
+
+int
+LbxDecodeRectangle(in, inend, out)
+ register char *in;
+ char *inend;
+ register short *out;
+{
+ register short diff;
+ short last_x = 0;
+ short last_y = 0;
+ char *start_out = (char *)out;
+
+ while (in < inend) {
+ DECODE_SHORT(in, diff);
+ *out = last_x + diff;
+ last_x += diff;
+ out++;
+ DECODE_SHORT(in, diff);
+ *out = last_y + diff;
+ last_y += diff;
+ out++;
+
+ DECODE_USHORT(in, *(unsigned short *)out);
+ out++;
+ DECODE_USHORT(in, *(unsigned short *)out);
+ out++;
+ }
+ return ((char *)out - start_out);
+}
+
+int
+LbxDecodeArc(in, inend, out)
+ register char *in;
+ char *inend;
+ register short *out;
+{
+ register short diff;
+ short last_x = 0;
+ short last_y = 0;
+ char *start_out = (char *)out;
+
+ while (in < inend) {
+ DECODE_SHORT(in, diff);
+ *out = last_x + diff;
+ last_x += diff;
+ out++;
+ DECODE_SHORT(in, diff);
+ *out = last_y + diff;
+ last_y += diff;
+ out++;
+
+ DECODE_USHORT(in, *(unsigned short *)out);
+ out++;
+ DECODE_USHORT(in, *(unsigned short *)out);
+ out++;
+
+ DECODE_ANGLE(in, *out);
+ out++;
+ DECODE_ANGLE(in, *out);
+ out++;
+ }
+ return ((char *)out - start_out);
+}
+
+int
+LbxDecodeCopyArea (client)
+ ClientPtr client;
+{
+ REQUEST(xLbxCopyAreaReq);
+ char *in;
+ xCopyAreaReq req;
+ int len;
+ Drawable srcDrawable, dstDrawable;
+ GContext gc;
+
+ GFX_GET_SRC_DST_DRAWABLE_AND_GC(xLbxCopyAreaReq, in, len);
+ req.reqType = X_CopyArea;
+ req.length = client->req_len = SIZEOF(xCopyAreaReq) >> 2;
+ req.srcDrawable = srcDrawable;
+ req.dstDrawable = dstDrawable;
+ req.gc = gc;
+ DECODE_PSHORT (in, req.srcX);
+ DECODE_PSHORT (in, req.srcY);
+ DECODE_PSHORT (in, req.dstX);
+ DECODE_PSHORT (in, req.dstY);
+ DECODE_USHORT (in, req.width);
+ DECODE_USHORT (in, req.height);
+ client->requestBuffer = (pointer) &req;
+ return (*ProcVector[X_CopyArea])(client);
+}
+
+int
+LbxDecodeCopyPlane (client)
+ ClientPtr client;
+{
+ REQUEST(xLbxCopyPlaneReq);
+ char *in;
+ xCopyPlaneReq req;
+ int len;
+ Drawable srcDrawable, dstDrawable;
+ GContext gc;
+
+ GFX_GET_SRC_DST_DRAWABLE_AND_GC(xLbxCopyPlaneReq, in, len);
+ req.reqType = X_CopyPlane;
+ req.length = client->req_len = SIZEOF(xCopyPlaneReq) >> 2;
+ req.srcDrawable = srcDrawable;
+ req.dstDrawable = dstDrawable;
+ req.gc = gc;
+ DECODE_PSHORT (in, req.srcX);
+ DECODE_PSHORT (in, req.srcY);
+ DECODE_PSHORT (in, req.dstX);
+ DECODE_PSHORT (in, req.dstY);
+ DECODE_USHORT (in, req.width);
+ DECODE_USHORT (in, req.height);
+ req.bitPlane = stuff->bitPlane;
+ client->requestBuffer = (pointer) &req;
+ return (*ProcVector[X_CopyPlane])(client);
+}
+
+static pointer
+get_gfx_buffer(client, len)
+ ClientPtr client;
+ int len;
+{
+ LbxClientPtr lbxClient = LbxClient(client);
+ pointer tmp;
+
+ /* XXX should probably shrink this sucker too */
+ if (len > lbxClient->gb_size) {
+ tmp = (pointer) xrealloc(lbxClient->gfx_buffer, len);
+ if (!tmp)
+ return (pointer) NULL;
+ lbxClient->gfx_buffer = tmp;
+ lbxClient->gb_size = len;
+ }
+ return lbxClient->gfx_buffer;
+}
+
+int
+LbxDecodePolyText (client)
+ ClientPtr client;
+{
+ REQUEST(xLbxPolyTextReq);
+ char *in, *pos;
+ xPolyTextReq *xreq;
+ int len;
+ Drawable drawable;
+ GContext gc;
+
+ GFX_GET_DRAWABLE_AND_GC(xLbxPolyTextReq, in, len);
+ xreq = (xPolyTextReq *) get_gfx_buffer(client, sizeof (xPolyTextReq) + len);
+ if (!xreq)
+ return BadAlloc;
+ xreq->reqType = stuff->lbxReqType == X_LbxPolyText8? X_PolyText8 : X_PolyText16;
+ xreq->drawable = drawable;
+ xreq->gc = gc;
+ pos = in;
+ DECODE_PSHORT(in, xreq->x);
+ DECODE_PSHORT(in, xreq->y);
+ len -= (in - pos);
+ memmove ((char *) (xreq + 1), in, len);
+ xreq->length = client->req_len = (sizeof (xPolyTextReq) + len) >> 2;
+ client->requestBuffer = (pointer) xreq;
+ return (*ProcVector[xreq->reqType])(client);
+}
+
+int
+LbxDecodeImageText (client)
+ ClientPtr client;
+{
+ REQUEST(xLbxImageTextReq);
+ char *in, *pos;
+ xImageTextReq *xreq;
+ int len;
+ Drawable drawable;
+ GContext gc;
+
+ GFX_GET_DRAWABLE_AND_GC(xLbxImageTextReq, in, len);
+ xreq = (xImageTextReq *) get_gfx_buffer(client, sizeof (xImageTextReq) + len);
+ if (!xreq)
+ return BadAlloc;
+ xreq->reqType = stuff->lbxReqType == X_LbxImageText8? X_ImageText8 : X_ImageText16;
+ xreq->drawable = drawable;
+ xreq->gc = gc;
+ xreq->nChars = stuff->nChars;
+ pos = in;
+ DECODE_PSHORT(in, xreq->x);
+ DECODE_PSHORT(in, xreq->y);
+ len -= (in - pos);
+ memmove ((char *) (xreq + 1), in, len);
+ xreq->length = client->req_len = (sizeof (xImageTextReq) + len) >> 2;
+ client->requestBuffer = (pointer) xreq;
+ return (*ProcVector[xreq->reqType])(client);
+}
+
+int
+LbxDecodePutImage (client)
+ register ClientPtr client;
+{
+ REQUEST (xLbxPutImageReq);
+ char *in, *data;
+ xPutImageReq xreq;
+ int ppl, bpl, nbytes;
+ int retval;
+ int n;
+
+ xreq.reqType = X_PutImage;
+
+ in = (char *) stuff + sz_xLbxPutImageReq;
+
+ if (stuff->bitPacked & 0x80) {
+ xreq.format = (stuff->bitPacked >> 5) & 0x3;
+ xreq.depth = ((stuff->bitPacked >> 2) & 0x7) + 1;
+ xreq.leftPad = 0;
+ } else {
+ xreq.depth = (stuff->bitPacked >> 2) + 1;
+ xreq.format = (*in >> 5) & 0x3;
+ xreq.leftPad = *in++ & 0x1f;
+ }
+ DECODE_USHORT(in, xreq.width);
+ DECODE_USHORT(in, xreq.height);
+ DECODE_PSHORT(in, xreq.dstX);
+ DECODE_PSHORT(in, xreq.dstY);
+ if (client->swapped) {
+ if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone ||
+ GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ {
+ swapl (in, n);
+ if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone &&
+ GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ swapl (in + 4, n);
+ }
+ }
+ in += LbxDecodeGFXCache(client, stuff->cacheEnts, in,
+ &xreq.drawable, &xreq.gc);
+
+ ppl = xreq.width + xreq.leftPad;
+ if (xreq.format != ZPixmap ||
+ (xreq.depth == 1 && screenInfo.formats->bitsPerPixel == 1)) {
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ bpl = BitmapBytePadProto(ppl);
+#else
+ bpl = BitmapBytePad(ppl);
+#endif
+ nbytes = bpl;
+ if (xreq.format == XYPixmap)
+ nbytes *= xreq.depth;
+ } else {
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ bpl = PixmapBytePadProto(ppl, xreq.depth);
+#else
+ bpl = PixmapBytePad(ppl, xreq.depth);
+#endif
+ nbytes = bpl;
+ }
+ nbytes *= xreq.height;
+ xreq.length = ((nbytes + 3) >> 2) + (sz_xPutImageReq >> 2);
+ /* +1 is because fillspan in DecodeFaxG42D seems to go 1 byte too far,
+ * and I don't want to mess with that code */
+ if ((data = (char *) xalloc ((xreq.length << 2) + 1)) == NULL)
+ return BadAlloc;
+
+ *((xPutImageReq *)data) = xreq;
+
+ if (!stuff->compressionMethod)
+ {
+ memcpy(data + sz_xPutImageReq, in, nbytes);
+ }
+ else if (xreq.format != ZPixmap ||
+ (xreq.depth == 1 && screenInfo.formats->bitsPerPixel == 1))
+ {
+ LbxBitmapCompMethod *compMethod;
+
+ compMethod = LbxSrvrLookupBitmapCompMethod (LbxProxy(client),
+ stuff->compressionMethod);
+
+ if (!compMethod)
+ {
+ xfree (data);
+ return (BadValue);
+ }
+ else
+ {
+ if (!compMethod->inited)
+ {
+ if (compMethod->compInit)
+ (*compMethod->compInit)();
+ compMethod->inited = 1;
+ }
+
+ (*compMethod->decompFunc) (
+ (unsigned char *) in, (unsigned char *) data + sz_xPutImageReq,
+ nbytes,
+#if BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER
+ (ppl + BITMAP_SCANLINE_UNIT - 1) & ~BITMAP_SCANLINE_UNIT,
+#else
+ ppl,
+#endif
+ bpl,
+ ((xConnSetup *) ConnectionInfo)->bitmapBitOrder == LSBFirst);
+ }
+ }
+ else
+ {
+ LbxPixmapCompMethod *compMethod;
+
+ compMethod = LbxSrvrLookupPixmapCompMethod (LbxProxy(client),
+ stuff->compressionMethod);
+
+ if (!compMethod)
+ {
+ xfree (data);
+ return (BadValue);
+ }
+ else
+ {
+ if (!compMethod->inited)
+ {
+ if (compMethod->compInit)
+ (*compMethod->compInit)();
+ compMethod->inited = 1;
+ }
+
+ (*compMethod->decompFunc) (
+ in, (char *) data + sz_xPutImageReq,
+ (int) xreq.height, bpl);
+ }
+ }
+
+ client->req_len = xreq.length;
+ client->requestBuffer = (pointer) data;
+
+ retval = (*ProcVector[X_PutImage])(client);
+ xfree(data);
+ return retval;
+}
+
+int
+LbxDecodeGetImage (client)
+ register ClientPtr client;
+{
+ REQUEST (xLbxGetImageReq);
+ xLbxGetImageReply *reply = NULL;
+ int lbxLen, xLen, n;
+ int method, bytes, status;
+ xGetImageReply *theImage;
+
+ REQUEST_SIZE_MATCH(xLbxGetImageReq);
+
+ status = DoGetImage(client, stuff->format, stuff->drawable,
+ stuff->x, stuff->y,
+ (int)stuff->width, (int)stuff->height,
+ stuff->planeMask, &theImage);
+
+ if (status != Success)
+ return (status);
+
+ if ((reply = (xLbxGetImageReply *) xalloc (
+ sz_xLbxGetImageReply + theImage->length)) == NULL)
+ {
+ xfree(theImage);
+ return (BadAlloc);
+ }
+
+ if (stuff->format != ZPixmap ||
+ (theImage->depth == 1 && screenInfo.formats->bitsPerPixel == 1))
+ {
+ LbxBitmapCompMethod *compMethod;
+
+ compMethod = LbxSrvrFindPreferredBitmapCompMethod (LbxProxy(client));
+
+ if (!compMethod)
+ status = LBX_IMAGE_COMPRESS_NO_SUPPORT;
+ else
+ {
+ if (!compMethod->inited)
+ {
+ if (compMethod->compInit)
+ (*compMethod->compInit)();
+ compMethod->inited = 1;
+ }
+
+ status = (*compMethod->compFunc) (
+ (unsigned char *) &theImage[1],
+ (unsigned char *) &reply[1],
+ theImage->length,
+ theImage->length,
+#if BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER
+ (int) (stuff->width + BITMAP_SCANLINE_UNIT - 1) &
+ ~BITMAP_SCANLINE_UNIT,
+#else
+ (int) stuff->width,
+#endif
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ BitmapBytePadProto(stuff->width),
+#else
+ BitmapBytePad(stuff->width),
+#endif
+ ((xConnSetup *) ConnectionInfo)->bitmapBitOrder == LSBFirst,
+ &bytes);
+
+ method = compMethod->methodOpCode;
+ }
+ }
+ else
+ {
+ LbxPixmapCompMethod *compMethod;
+
+ compMethod = LbxSrvrFindPreferredPixmapCompMethod (
+ LbxProxy(client), (int) stuff->format, theImage->depth);
+
+ if (!compMethod)
+ status = LBX_IMAGE_COMPRESS_NO_SUPPORT;
+ else
+ {
+ if (!compMethod->inited)
+ {
+ if (compMethod->compInit)
+ (*compMethod->compInit)();
+ compMethod->inited = 1;
+ }
+
+ status = (*compMethod->compFunc) (
+ (char *) &theImage[1],
+ (char *) &reply[1],
+ theImage->length,
+ (int) stuff->format,
+ theImage->depth,
+ (int) stuff->height,
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ PixmapBytePadProto(stuff->width, theImage->depth),
+#else
+ PixmapBytePad(stuff->width, theImage->depth),
+#endif
+ &bytes);
+
+ method = compMethod->methodOpCode;
+ }
+ }
+
+ reply->type = X_Reply;
+ reply->depth = theImage->depth;
+ reply->sequenceNumber = client->sequence;
+ reply->visual = theImage->visual;
+ reply->pad1 = reply->pad2 = reply->pad3 = reply->pad4 = reply->pad5 = 0;
+
+ if (status != LBX_IMAGE_COMPRESS_SUCCESS)
+ {
+ reply->compressionMethod = LbxImageCompressNone;
+ reply->lbxLength = reply->xLength = (theImage->length + 3) >> 2;
+ }
+ else
+ {
+ reply->compressionMethod = method;
+ reply->lbxLength = (bytes + 3) >> 2;
+ reply->xLength = (theImage->length + 3) >> 2;
+ }
+
+ lbxLen = reply->lbxLength;
+ xLen = reply->xLength;
+
+ if (client->swapped)
+ {
+ swaps (&reply->sequenceNumber, n);
+ swapl (&reply->lbxLength, n);
+ swapl (&reply->xLength, n);
+ swapl (&reply->visual, n);
+ }
+
+ if (reply->compressionMethod != LbxImageCompressNone)
+ {
+ /*
+ * If the compressed image is greater that 25% of the original
+ * image, run the GetImage reply through the regular stream
+ * compressor. Otherwise, just write the compressed image.
+ */
+
+ if (lbxLen > (xLen / 4))
+ {
+ WriteToClient (client,
+ sz_xLbxGetImageReply + (lbxLen << 2), (char *)reply);
+ }
+ else
+ {
+ UncompressedWriteToClient (client,
+ sz_xLbxGetImageReply + (lbxLen << 2), (char *)reply);
+ }
+ }
+ else
+ {
+ /*
+ * Write back the original uncompressed image.
+ */
+
+ WriteToClient (client, sz_xLbxGetImageReply, (char *)reply);
+ WriteToClient (client, lbxLen << 2, (char *)&theImage[1]);
+ }
+
+ xfree (theImage);
+
+ if (reply)
+ xfree ((char *) reply);
+
+ return (Success);
+}
diff --git a/xc/programs/Xserver/lbx/lbxmain.c b/xc/programs/Xserver/lbx/lbxmain.c
new file mode 100644
index 000000000..e0ac1fee7
--- /dev/null
+++ b/xc/programs/Xserver/lbx/lbxmain.c
@@ -0,0 +1,1820 @@
+/* $TOG: lbxmain.c /main/74 1998/02/09 14:32:18 kaleb $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+All Rights Reserved.
+
+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 1992 Network Computing Devices
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of NCD. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. NCD. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NCD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NCD.
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/lbx/lbxmain.c,v 1.6 1998/10/04 09:39:05 dawes Exp $ */
+
+#include <sys/types.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "Xos.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"
+#include "lbxdeltastr.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "lbxserve.h"
+#include "lbximage.h"
+#include "lbxsrvopts.h"
+#include "Xfuncproto.h"
+#include <errno.h>
+#ifdef X_NOT_STDC_ENV
+extern int errno;
+#endif
+#ifndef Lynx
+#include <sys/uio.h>
+#else
+#include <uio.h>
+#endif
+#include <stdio.h>
+
+#ifndef X_NOT_POSIX
+#include <unistd.h>
+#endif
+
+#define CloseLbxClient 0xff
+
+#define MAXBYTESDIFF 8
+
+extern void LbxAllowMotion();
+extern int LbxDecodePoints();
+extern int LbxDecodeSegment();
+extern int LbxDecodeRectangle();
+extern int LbxDecodeArc();
+
+extern int GrabInProgress;
+
+int LbxWhoAmI = 1; /*
+ * for lbx zlib library to know who we are
+ * server = 1
+ * proxy = 0
+ */
+
+int ProcLbxDispatch();
+extern int SProcLbxDispatch();
+static void LbxResetProc();
+static int DecodeLbxDelta();
+static void LbxFreeClient ();
+static void LbxShutdownProxy ();
+
+static LbxProxyPtr proxyList;
+unsigned char LbxReqCode;
+int LbxEventCode;
+static int BadLbxClientCode;
+static int uid_seed;
+
+static int lbxCompressWorkProcCount;
+
+LbxClientPtr lbxClients[MAXCLIENTS];
+
+extern xConnSetupPrefix connSetupPrefix;
+extern char *ConnectionInfo;
+extern int (*LbxInitialVector[3])();
+
+#ifdef DEBUG
+int lbxDebug = 0;
+#endif
+
+
+void
+LbxExtensionInit()
+{
+ ExtensionEntry *extEntry;
+
+ lbxCompressWorkProcCount = 0;
+ proxyList = NULL;
+ uid_seed = 0;
+ if ((extEntry = AddExtension(LBXNAME, LbxNumberEvents, LbxNumberErrors,
+ ProcLbxDispatch, SProcLbxDispatch,
+ LbxResetProc, StandardMinorOpcode)))
+ {
+ LbxReqCode = (unsigned char)extEntry->base;
+ LbxEventCode = extEntry->eventBase;
+ BadLbxClientCode = extEntry->errorBase + BadLbxClient;
+ LbxDixInit();
+
+ LbxCmapInit ();
+ DeclareExtensionSecurity(LBXNAME, TRUE);
+ }
+}
+
+/*ARGSUSED*/
+static void
+LbxResetProc (extEntry)
+ExtensionEntry *extEntry;
+{
+ LbxResetTags();
+ uid_seed = 0;
+}
+
+void
+LbxCloseClient (client)
+ ClientPtr client;
+{
+ xLbxCloseEvent closeEvent;
+ ClientPtr master;
+ LbxProxyPtr proxy;
+ LbxClientPtr lbxClient = LbxClient(client);
+ CARD32 id;
+
+ if (!lbxClient)
+ return;
+ id = lbxClient->id;
+ proxy = lbxClient->proxy;
+
+ DBG (DBG_CLIENT, (stderr, "Close client %d\n", client->index));
+ LbxFreeClient (client);
+ if (!id)
+ {
+ isItTimeToYield = TRUE;
+ CloseDownFileDescriptor (client);
+ LbxShutdownProxy (proxy);
+ }
+ else
+ {
+ master = NULL;
+ if (proxy->lbxClients[0])
+ master = LbxProxyClient(proxy);
+ if (master && !master->clientGone)
+ {
+ closeEvent.type = LbxEventCode;
+ closeEvent.lbxType = LbxCloseEvent;
+ closeEvent.client = id;
+ closeEvent.sequenceNumber = master->sequence;
+ closeEvent.pad1 = closeEvent.pad2 = closeEvent.pad3 =
+ closeEvent.pad4 = closeEvent.pad5 = closeEvent.pad6 = 0;
+ if (master->swapped) {
+ int n;
+
+ swaps(&closeEvent.sequenceNumber, n);
+ swapl(&closeEvent.client, n);
+ }
+ WriteToClient(master, sizeof (closeEvent), (char *)&closeEvent);
+ LbxForceOutput(proxy);
+ }
+ }
+}
+
+static int
+LbxReencodeEvent(client, proxy, buf)
+ ClientPtr client;
+ LbxProxyPtr proxy;
+ char *buf;
+{
+ xEvent *ev = (xEvent *)buf;
+ int n;
+ lbxMotionCache *motionCache = &proxy->motionCache;
+ int motionDelta = 0;
+ Bool swapCache;
+ xEvent tev, *sev;
+
+ if (ev->u.u.type != MotionNotify) {
+ if (proxy->dosquishing)
+ return LbxSquishEvent(buf);
+ return 0;
+ }
+
+ /*
+ * Check if we can generate a motion delta event.
+ *
+ * The motion cache contains the last motion event the server sent.
+ *
+ * The following are always stored in the cache in the server's
+ * byte order:
+ * sequenceNumber, time, rootX, rootY, eventX, eventY
+ * This is because when determining if we can do a delta, all
+ * arithmetic must be done using the server's byte order.
+ *
+ * The following are stored in the byte order of the latest client
+ * receiving a motion event (indicated by motionCache->swapped):
+ * root, event, child, state
+ * These fields do not need to be stored in the server's byte order
+ * because we only use the '==' operator on them.
+ */
+
+ if (!proxy->motion_allowed_events) {
+ DBG(DBG_CLIENT, (stderr, "throttling motion event for client %d\n", client->index));
+ return sz_xEvent;
+ }
+ proxy->motion_allowed_events--;
+
+ motionCache = &proxy->motionCache;
+
+ if (!client->swapped)
+ {
+ swapCache = motionCache->swapped;
+ sev = ev;
+ }
+ else
+ {
+ swapCache = !motionCache->swapped;
+ sev = &tev;
+ cpswaps (ev->u.keyButtonPointer.rootX,
+ sev->u.keyButtonPointer.rootX);
+ cpswaps (ev->u.keyButtonPointer.rootY,
+ sev->u.keyButtonPointer.rootY);
+ cpswaps (ev->u.keyButtonPointer.eventX,
+ sev->u.keyButtonPointer.eventX);
+ cpswaps (ev->u.keyButtonPointer.eventY,
+ sev->u.keyButtonPointer.eventY);
+ cpswaps (ev->u.u.sequenceNumber,
+ sev->u.u.sequenceNumber);
+ cpswapl (ev->u.keyButtonPointer.time,
+ sev->u.keyButtonPointer.time);
+ }
+
+ if (swapCache)
+ {
+ swapl (&motionCache->root, n);
+ swapl (&motionCache->event, n);
+ swapl (&motionCache->child, n);
+ swaps (&motionCache->state, n);
+
+ motionCache->swapped = !motionCache->swapped;
+ }
+
+ motionDelta = 0;
+
+ if (ev->u.u.detail == motionCache->detail &&
+ ev->u.keyButtonPointer.root == motionCache->root &&
+ ev->u.keyButtonPointer.event == motionCache->event &&
+ ev->u.keyButtonPointer.child == motionCache->child &&
+ ev->u.keyButtonPointer.state == motionCache->state &&
+ ev->u.keyButtonPointer.sameScreen == motionCache->sameScreen) {
+
+ int root_delta_x =
+ sev->u.keyButtonPointer.rootX - motionCache->rootX;
+ int root_delta_y =
+ sev->u.keyButtonPointer.rootY - motionCache->rootY;
+ int event_delta_x =
+ sev->u.keyButtonPointer.eventX - motionCache->eventX;
+ int event_delta_y =
+ sev->u.keyButtonPointer.eventY - motionCache->eventY;
+ unsigned long sequence_delta =
+ sev->u.u.sequenceNumber - motionCache->sequenceNumber;
+ unsigned long time_delta =
+ sev->u.keyButtonPointer.time - motionCache->time;
+
+ if (root_delta_x == event_delta_x &&
+ event_delta_x >= -128 && event_delta_x < 128 &&
+ root_delta_y == event_delta_y &&
+ event_delta_y >= -128 && event_delta_y < 128) {
+
+ if (sequence_delta == 0 && time_delta < 256) {
+
+ lbxQuickMotionDeltaEvent *mev =
+ (lbxQuickMotionDeltaEvent *)(buf + sz_xEvent -
+ sz_lbxQuickMotionDeltaEvent);
+
+ mev->type = LbxEventCode + LbxQuickMotionDeltaEvent;
+ mev->deltaTime = time_delta;
+ mev->deltaX = event_delta_x;
+ mev->deltaY = event_delta_y;
+
+ motionDelta = sz_xEvent - sz_lbxQuickMotionDeltaEvent;
+
+ } else if (sequence_delta < 65536 && time_delta < 65536) {
+
+ lbxMotionDeltaEvent *mev =
+ (lbxMotionDeltaEvent *)(buf + sz_xEvent -
+ sz_lbxMotionDeltaEvent);
+
+ mev->type = LbxEventCode;
+ mev->lbxType = LbxMotionDeltaEvent;
+ mev->deltaTime = time_delta;
+ mev->deltaSequence = sequence_delta;
+ mev->deltaX = event_delta_x;
+ mev->deltaY = event_delta_y;
+
+ if (LbxProxyClient(proxy)->swapped)
+ {
+ swaps (&mev->deltaTime, n);
+ swaps (&mev->deltaSequence, n);
+ }
+
+ motionDelta = sz_xEvent - sz_lbxMotionDeltaEvent;
+ }
+ }
+ }
+
+ motionCache->sequenceNumber = sev->u.u.sequenceNumber;
+ motionCache->time = sev->u.keyButtonPointer.time;
+ motionCache->rootX = sev->u.keyButtonPointer.rootX;
+ motionCache->rootY = sev->u.keyButtonPointer.rootY;
+ motionCache->eventX = sev->u.keyButtonPointer.eventX;
+ motionCache->eventY = sev->u.keyButtonPointer.eventY;
+
+ if (motionDelta)
+ return motionDelta;
+
+ ev->u.keyButtonPointer.pad1 = 0;
+ motionCache->detail = ev->u.u.detail;
+ motionCache->root = ev->u.keyButtonPointer.root;
+ motionCache->event = ev->u.keyButtonPointer.event;
+ motionCache->child = ev->u.keyButtonPointer.child;
+ motionCache->state = ev->u.keyButtonPointer.state;
+ motionCache->sameScreen = ev->u.keyButtonPointer.sameScreen;
+ return 0;
+}
+
+static int
+LbxComposeDelta(proxy, reply, len, buf)
+ LbxProxyPtr proxy;
+ char *reply;
+ int len;
+ char *buf;
+{
+ int diffs;
+ int cindex;
+ int n;
+ xLbxDeltaReq *p = (xLbxDeltaReq *)buf;
+
+ diffs = LBXDeltaMinDiffs(&proxy->outdeltas, reply, len,
+ min(MAXBYTESDIFF, (len - sz_xLbxDeltaReq) >> 1),
+ &cindex);
+ if (diffs < 0) {
+ LBXAddDeltaOut(&proxy->outdeltas, reply, len);
+ return 0;
+ }
+ LBXEncodeDelta(&proxy->outdeltas, reply, diffs, cindex,
+ &buf[sz_xLbxDeltaReq]);
+ LBXAddDeltaOut(&proxy->outdeltas, reply, len);
+ p->reqType = LbxEventCode;
+ p->lbxReqType = LbxDeltaEvent;
+ p->diffs = diffs;
+ p->cindex = cindex;
+ len = (sz_xLbxDeltaReq + sz_xLbxDiffItem * diffs + 3) & ~3;
+ p->length = len >> 2;
+ if (LbxProxyClient(proxy)->swapped) {
+ swaps(&p->length, n);
+ }
+ return len;
+}
+
+void
+LbxReencodeOutput(client, pbuf, pcount, cbuf, ccount)
+ ClientPtr client;
+ char *pbuf;
+ int *pcount;
+ char *cbuf;
+ int *ccount;
+{
+ LbxClientPtr lbxClient = LbxClient(client);
+ LbxProxyPtr proxy = lbxClient->proxy;
+ CARD32 len;
+ int n;
+ int count = *ccount;
+ char *obuf = cbuf;
+
+ if (client->clientState != ClientStateRunning) {
+ if (DELTA_CACHEABLE(&proxy->outdeltas, count) &&
+ (n = LbxComposeDelta(proxy, cbuf, count, proxy->oDeltaBuf))) {
+ memcpy(obuf, proxy->oDeltaBuf, n);
+ *ccount -= (count - n);
+ }
+ return;
+ }
+ if (lbxClient->bytes_remaining) {
+ if (count < lbxClient->bytes_remaining) {
+ lbxClient->bytes_remaining -= count;
+ return;
+ }
+ if (DELTA_CACHEABLE(&proxy->outdeltas, lbxClient->bytes_in_reply)) {
+ len = lbxClient->bytes_in_reply - lbxClient->bytes_remaining;
+ pbuf += (*pcount - len);
+ memcpy(proxy->replyBuf, pbuf, len);
+ memcpy(proxy->replyBuf + len, cbuf, lbxClient->bytes_remaining);
+ n = LbxComposeDelta(proxy, proxy->replyBuf,
+ lbxClient->bytes_in_reply, proxy->oDeltaBuf);
+ if (!n)
+ obuf += lbxClient->bytes_remaining;
+ else if (n <= len) {
+ memcpy(pbuf, proxy->oDeltaBuf, n);
+ *pcount -= (len - n);
+ *ccount -= lbxClient->bytes_remaining;
+ } else {
+ memcpy(pbuf, proxy->oDeltaBuf, len);
+ memcpy(obuf, proxy->oDeltaBuf + len, n - len);
+ *ccount -= lbxClient->bytes_remaining - (n - len);
+ obuf += n - len;
+ }
+ } else
+ obuf += lbxClient->bytes_remaining;
+ cbuf += lbxClient->bytes_remaining;
+ count -= lbxClient->bytes_remaining;
+ lbxClient->bytes_remaining = 0;
+ }
+ while (count) {
+ lbxClient->bytes_in_reply = sz_xEvent;
+ if (((xGenericReply *)cbuf)->type == X_Reply) {
+ len = ((xGenericReply *)cbuf)->length;
+ if (client->swapped) {
+ swapl(&len, n);
+ }
+ lbxClient->bytes_in_reply += (len << 2);
+ if (LbxProxyClient(proxy)->swapped != client->swapped) {
+ swapl(&((xGenericReply *)cbuf)->length, n);
+ }
+ if (count < lbxClient->bytes_in_reply) {
+ lbxClient->bytes_remaining = lbxClient->bytes_in_reply - count;
+ if (obuf != cbuf)
+ memmove(obuf, cbuf, count);
+ return;
+ }
+ } else if (((xGenericReply *)cbuf)->type > X_Reply &&
+ ((xGenericReply *)cbuf)->type < LASTEvent &&
+ (n = LbxReencodeEvent(client, proxy, cbuf))) {
+ cbuf += n;
+ *ccount -= n;
+ count -= n;
+ if (n == sz_xEvent)
+ continue;
+ lbxClient->bytes_in_reply -= n;
+ }
+ if (DELTA_CACHEABLE(&proxy->outdeltas, lbxClient->bytes_in_reply) &&
+ (n = LbxComposeDelta(proxy, cbuf, lbxClient->bytes_in_reply,
+ proxy->oDeltaBuf))) {
+ memcpy(obuf, proxy->oDeltaBuf, n);
+ obuf += n;
+ *ccount -= (lbxClient->bytes_in_reply - n);
+ } else {
+ if (obuf != cbuf)
+ memmove(obuf, cbuf, lbxClient->bytes_in_reply);
+ obuf += lbxClient->bytes_in_reply;
+ }
+ cbuf += lbxClient->bytes_in_reply;
+ count -= lbxClient->bytes_in_reply;
+ }
+}
+
+/*ARGSUSED*/
+static void
+LbxReplyCallback(pcbl, nulldata, calldata)
+ CallbackListPtr *pcbl;
+ pointer nulldata;
+ pointer calldata;
+{
+ ReplyInfoRec *pri = (ReplyInfoRec *)calldata;
+ ClientPtr client = pri->client;
+ LbxClientPtr lbxClient;
+ REQUEST(xReq);
+
+ if (!pri->startOfReply || stuff->reqType > 127)
+ return;
+ lbxClient = LbxClient(client);
+ if (lbxClient)
+ ZeroReplyPadBytes(pri->replyData, stuff->reqType);
+}
+
+/*
+ * XXX If you think this is moronic, you're in good company,
+ * but things definitely hang if we don't have this.
+ */
+/* ARGSUSED */
+static Bool
+LbxCheckCompressInput (dummy1, dummy2)
+ ClientPtr dummy1;
+ pointer dummy2;
+{
+ LbxProxyPtr proxy;
+
+ if (!lbxCompressWorkProcCount)
+ return TRUE;
+
+ for (proxy = proxyList; proxy; proxy = proxy->next) {
+ if (proxy->compHandle &&
+ proxy->streamOpts.streamCompInputAvail(proxy->fd))
+ AvailableClientInput (LbxProxyClient(proxy));
+ }
+ return FALSE;
+}
+
+static Bool
+LbxIsClientBlocked (lbxClient)
+ LbxClientPtr lbxClient;
+{
+ LbxProxyPtr proxy = lbxClient->proxy;
+
+ return (lbxClient->ignored ||
+ (GrabInProgress && lbxClient->client->index != GrabInProgress &&
+ lbxClient != proxy->lbxClients[0]));
+}
+
+static void
+LbxSwitchRecv (proxy, lbxClient)
+ LbxProxyPtr proxy;
+ LbxClientPtr lbxClient;
+{
+ ClientPtr client;
+
+ proxy->curRecv = lbxClient;
+ if (!lbxClient || lbxClient->client->clientGone)
+ {
+ DBG(DBG_CLIENT, (stderr, "switching to dispose input\n"));
+ lbxClient = proxy->lbxClients[0];
+ if (!lbxClient)
+ return;
+ }
+ client = lbxClient->client;
+ DBG (DBG_SWITCH, (stderr, "switching input to client %d\n", client->index));
+
+ SwitchClientInput (client, FALSE);
+ proxy->curDix = lbxClient;
+}
+
+/* ARGSUSED */
+static Bool
+LbxWaitForUnblocked (client, closure)
+ ClientPtr client;
+ pointer closure;
+{
+ LbxClientPtr lbxClient;
+ LbxProxyPtr proxy;
+
+ if (client->clientGone)
+ return TRUE;
+ lbxClient = LbxClient(client);
+ if (!lbxClient)
+ return TRUE;
+ proxy = lbxClient->proxy;
+ if (LbxIsClientBlocked (lbxClient) ||
+ ((lbxClient != proxy->curDix) && proxy->curDix->reqs_pending &&
+ !LbxIsClientBlocked(proxy->curDix)))
+ return FALSE;
+ lbxClient->input_blocked = FALSE;
+ DBG (DBG_BLOCK, (stderr, "client %d no longer blocked, switching\n",
+ client->index));
+ SwitchClientInput (client, TRUE);
+ proxy->curDix = lbxClient;
+ return TRUE;
+}
+
+void
+LbxSetForBlock(lbxClient)
+ LbxClientPtr lbxClient;
+{
+ lbxClient->reqs_pending++;
+ if (!lbxClient->input_blocked)
+ {
+ lbxClient->input_blocked = TRUE;
+ QueueWorkProc(LbxWaitForUnblocked, lbxClient->client, NULL);
+ }
+}
+
+/* ARGSUSED */
+static int
+LbxWaitForUngrab (client, closure)
+ ClientPtr client;
+ pointer closure;
+{
+ LbxClientPtr lbxClient = LbxClient(client);
+ LbxProxyPtr proxy;
+ xLbxListenToAllEvent ungrabEvent;
+
+ if (client->clientGone || !lbxClient)
+ return TRUE;
+ if (GrabInProgress)
+ return FALSE;
+ proxy = lbxClient->proxy;
+ proxy->grabClient = 0;
+ ungrabEvent.type = LbxEventCode;
+ ungrabEvent.lbxType = LbxListenToAll;
+ ungrabEvent.pad1 = ungrabEvent.pad2 = ungrabEvent.pad3 =
+ ungrabEvent.pad4 = ungrabEvent.pad5 = ungrabEvent.pad6 =
+ ungrabEvent.pad7 = 0;
+ WriteToClient (client,
+ sizeof(xLbxListenToAllEvent), (char *)&ungrabEvent);
+ LbxForceOutput(proxy);
+ return TRUE;
+}
+
+static void
+LbxServerGrab(proxy)
+ LbxProxyPtr proxy;
+{
+ LbxClientPtr grabbingLbxClient;
+ xLbxListenToOneEvent grabEvent;
+
+ /*
+ * If the current grabbing client has changed, then we need
+ * to send a message to update the proxy.
+ */
+
+ grabEvent.type = LbxEventCode;
+ grabEvent.lbxType = LbxListenToOne;
+ if (!(grabbingLbxClient = lbxClients[GrabInProgress]) ||
+ grabbingLbxClient->proxy != proxy)
+ grabEvent.client = 0xffffffff; /* client other than a proxy client */
+ else
+ grabEvent.client = grabbingLbxClient->id;
+ grabEvent.pad1 = grabEvent.pad2 = grabEvent.pad3 =
+ grabEvent.pad4 = grabEvent.pad5 = grabEvent.pad6 = 0;
+ if (LbxProxyClient(proxy)->swapped) {
+ int n;
+ swapl(&grabEvent.client, n);
+ }
+ WriteToClient(LbxProxyClient(proxy),
+ sizeof(xLbxListenToOneEvent), (char *)&grabEvent);
+ LbxForceOutput(proxy);
+ if (!proxy->grabClient)
+ QueueWorkProc(LbxWaitForUngrab, LbxProxyClient(proxy), NULL);
+ proxy->grabClient = GrabInProgress;
+}
+
+#define MAJOROP(client) ((xReq *)client->requestBuffer)->reqType
+#define MINOROP(client) ((xReq *)client->requestBuffer)->data
+
+static Bool lbxCacheable[] = {
+ FALSE, /* LbxQueryVersion 0 */
+ FALSE, /* LbxStartProxy 1 */
+ TRUE, /* LbxStopProxy 2 */
+ FALSE, /* LbxSwitch 3 */
+ FALSE, /* LbxNewClient 4 */
+ TRUE, /* LbxCloseClient 5 */
+ TRUE, /* LbxModifySequence 6 */
+ FALSE, /* LbxAllowMotion 7 */
+ TRUE, /* LbxIncrementPixel 8 */
+ FALSE, /* LbxDelta 9 */
+ TRUE, /* LbxGetModifierMapping 10 */
+ FALSE, /* nothing 11 */
+ TRUE, /* LbxInvalidateTag 12 */
+ TRUE, /* LbxPolyPoint 13 */
+ TRUE, /* LbxPolyLine 14 */
+ TRUE, /* LbxPolySegment 15 */
+ TRUE, /* LbxPolyRectangle 16 */
+ TRUE, /* LbxPolyArc 17 */
+ TRUE, /* LbxFillPoly 18 */
+ TRUE, /* LbxPolyFillRectangle 19 */
+ TRUE, /* LbxPolyFillArc 20 */
+ TRUE, /* LbxGetKeyboardMapping 21 */
+ TRUE, /* LbxQueryFont 22 */
+ TRUE, /* LbxChangeProperty 23 */
+ TRUE, /* LbxGetProperty 24 */
+ TRUE, /* LbxTagData 25 */
+ TRUE, /* LbxCopyArea 26 */
+ TRUE, /* LbxCopyPlane 27 */
+ TRUE, /* LbxPolyText8 28 */
+ TRUE, /* LbxPolyText16 29 */
+ TRUE, /* LbxImageText8 30 */
+ TRUE, /* LbxImageText16 31 */
+ FALSE, /* LbxQueryExtension 32 */
+ TRUE, /* LbxPutImage 33 */
+ TRUE, /* LbxGetImage 34 */
+ FALSE, /* LbxBeginLargeRequest 35 */
+ FALSE, /* LbxLargeRequestData 36 */
+ FALSE, /* LbxEndLargeRequest 37 */
+ FALSE, /* LbxInternAtoms 38 */
+ TRUE, /* LbxGetWinAttrAndGeom 39 */
+ TRUE, /* LbxGrabCmap 40 */
+ TRUE, /* LbxReleaseCmap 41 */
+ TRUE, /* LbxAllocColor 42 */
+ TRUE, /* LbxSync 43 */
+};
+
+#define NUM(a) (sizeof (a) / sizeof (a[0]))
+
+static int
+LbxReadRequestFromClient (client)
+ ClientPtr client;
+{
+ int ret;
+ LbxClientPtr lbxClient = LbxClient(client);
+ LbxProxyPtr proxy = lbxClient->proxy;
+ ClientPtr masterClient = LbxProxyClient(proxy);
+ Bool isblocked;
+ Bool cacheable;
+
+ DBG (DBG_READ_REQ, (stderr, "Reading request from client %d\n", client->index));
+
+ if (GrabInProgress && (proxy->grabClient != GrabInProgress))
+ LbxServerGrab(proxy);
+ isblocked = LbxIsClientBlocked(lbxClient);
+
+ if (lbxClient->reqs_pending && !isblocked) {
+ ret = StandardReadRequestFromClient(client);
+ if (ret > 0 && (MAJOROP(client) == LbxReqCode) &&
+ (MINOROP(client) == X_LbxEndLargeRequest))
+ ret = PrepareLargeReqBuffer(client);
+ if (!--lbxClient->reqs_pending && (lbxClient != proxy->curRecv))
+ LbxSwitchRecv (proxy, proxy->curRecv);
+ return ret;
+ }
+ while (1) {
+ ret = StandardReadRequestFromClient(masterClient);
+ if (ret <= 0)
+ return ret;
+ client->requestBuffer = masterClient->requestBuffer;
+ client->req_len = masterClient->req_len;
+ cacheable = client->clientState == ClientStateRunning;
+ if (cacheable && (MAJOROP(client) == LbxReqCode)) {
+ /* Check to see if this request is delta cached */
+ if (MINOROP(client) < NUM(lbxCacheable))
+ cacheable = lbxCacheable[MINOROP(client)];
+ switch (MINOROP(client)) {
+ case X_LbxSwitch:
+ /* Switch is sent by proxy */
+ if (masterClient->swapped)
+ SProcLbxSwitch (client);
+ else
+ ProcLbxSwitch (client);
+ return 0;
+ case X_LbxDelta:
+ ret = DecodeLbxDelta (client);
+ DBG(DBG_DELTA,
+ (stderr,"delta decompressed msg %d, len = %d\n",
+ (unsigned)((unsigned char *)client->requestBuffer)[0],
+ ret));
+ break;
+ case X_LbxEndLargeRequest:
+ if (!isblocked)
+ ret = PrepareLargeReqBuffer(client);
+ break;
+ }
+ }
+ if (cacheable && DELTA_CACHEABLE(&proxy->indeltas, ret)) {
+ DBG(DBG_DELTA,
+ (stderr, "caching msg %d, len = %d, index = %d\n",
+ (unsigned)((unsigned char *)client->requestBuffer)[0],
+ ret, proxy->indeltas.nextDelta));
+ LBXAddDeltaIn(&proxy->indeltas, client->requestBuffer, ret);
+ }
+ if (client->swapped != masterClient->swapped) {
+ char n;
+ /* put length in client order */
+ swaps(&((xReq *)client->requestBuffer)->length, n);
+ }
+ if (!isblocked)
+ return ret;
+ DBG (DBG_BLOCK, (stderr, "Stashing %d bytes for %d\n",
+ ret, client->index));
+ AppendFakeRequest (client, client->requestBuffer, ret);
+ LbxSetForBlock(lbxClient);
+ }
+}
+
+static LbxClientPtr
+LbxInitClient (proxy, client, id)
+ LbxProxyPtr proxy;
+ ClientPtr client;
+ CARD32 id;
+{
+ LbxClientPtr lbxClient;
+ int i;
+
+ lbxClient = (LbxClientPtr) xalloc (sizeof (LbxClientRec));
+ if (!lbxClient)
+ return NULL;
+ lbxClient->id = id;
+ lbxClient->client = client;
+ lbxClient->proxy = proxy;
+ lbxClient->ignored = FALSE;
+ lbxClient->input_blocked = FALSE;
+ lbxClient->reqs_pending = 0;
+ lbxClient->bytes_in_reply = 0;
+ lbxClient->bytes_remaining = 0;
+ client->readRequest = LbxReadRequestFromClient;
+ bzero (lbxClient->drawableCache, sizeof (lbxClient->drawableCache));
+ bzero (lbxClient->gcontextCache, sizeof (lbxClient->gcontextCache));
+ lbxClients[client->index] = lbxClient;
+ for (i = 0; proxy->lbxClients[i]; i++)
+ ;
+ if (i > proxy->maxIndex)
+ proxy->maxIndex = i;
+ proxy->lbxClients[i] = lbxClient;
+ proxy->numClients++;
+ lbxClient->gfx_buffer = (pointer) NULL;
+ lbxClient->gb_size = 0;
+ return lbxClient;
+}
+
+static void
+LbxFreeClient (client)
+ ClientPtr client;
+{
+ LbxClientPtr lbxClient = LbxClient(client);
+ LbxProxyPtr proxy = lbxClient->proxy;
+ int i;
+
+ if (lbxClient != proxy->lbxClients[0]) {
+ if (lbxClient == proxy->curRecv)
+ LbxSwitchRecv(proxy, NULL);
+ else if (lbxClient == proxy->curDix)
+ LbxSwitchRecv(proxy, proxy->curRecv);
+ }
+
+ --proxy->numClients;
+ lbxClients[client->index] = NULL;
+ for (i = 0; i <= proxy->maxIndex; i++) {
+ if (proxy->lbxClients[i] == lbxClient) {
+ proxy->lbxClients[i] = NULL;
+ break;
+ }
+ }
+ while (proxy->maxIndex >= 0 && !proxy->lbxClients[proxy->maxIndex])
+ --proxy->maxIndex;
+ xfree(lbxClient->gfx_buffer);
+ client->readRequest = StandardReadRequestFromClient;
+ xfree (lbxClient);
+}
+
+static void
+LbxFreeProxy (proxy)
+ LbxProxyPtr proxy;
+{
+ LbxProxyPtr *p;
+
+ LBXFreeDeltaCache(&proxy->indeltas);
+ LBXFreeDeltaCache(&proxy->outdeltas);
+ LbxFreeOsBuffers(proxy);
+ if (proxy->iDeltaBuf)
+ xfree(proxy->iDeltaBuf);
+ if (proxy->replyBuf)
+ xfree(proxy->replyBuf);
+ if (proxy->oDeltaBuf)
+ xfree(proxy->oDeltaBuf);
+ if (proxy->compHandle)
+ proxy->streamOpts.streamCompFreeHandle(proxy->compHandle);
+ if (proxy->bitmapCompMethods)
+ xfree (proxy->bitmapCompMethods);
+ if (proxy->pixmapCompMethods)
+ xfree (proxy->pixmapCompMethods);
+ if (proxy->pixmapCompDepths)
+ {
+ int i;
+ for (i = 0; i < proxy->numPixmapCompMethods; i++)
+ xfree (proxy->pixmapCompDepths[i]);
+ xfree (proxy->pixmapCompDepths);
+ }
+
+ for (p = &proxyList; *p; p = &(*p)->next) {
+ if (*p == proxy) {
+ *p = proxy->next;
+ break;
+ }
+ }
+ if (!proxyList)
+ DeleteCallback(&ReplyCallback, LbxReplyCallback, NULL);
+
+ xfree (proxy);
+}
+
+LbxProxyPtr
+LbxPidToProxy(pid)
+ int pid;
+{
+ LbxProxyPtr proxy;
+
+ for (proxy = proxyList; proxy; proxy = proxy->next) {
+ if (proxy->pid == pid)
+ return proxy;
+ }
+ return NULL;
+}
+
+static void
+LbxShutdownProxy (proxy)
+ LbxProxyPtr proxy;
+{
+ int i;
+ ClientPtr client;
+
+ if (proxy->compHandle)
+ --lbxCompressWorkProcCount;
+ while (proxy->grabbedCmaps)
+ LbxReleaseCmap(proxy->grabbedCmaps, FALSE);
+ for (i = 0; i <= proxy->maxIndex; i++)
+ {
+ if (proxy->lbxClients[i])
+ {
+ client = proxy->lbxClients[i]->client;
+ if (!client->clientGone)
+ CloseDownClient (client);
+ }
+ }
+ LbxFlushTags(proxy);
+ LbxFreeProxy(proxy);
+}
+
+
+int
+ProcLbxQueryVersion(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxQueryVersionReq);
+ xLbxQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xLbxQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = LBX_MAJOR_VERSION;
+ rep.minorVersion = LBX_MINOR_VERSION;
+ rep.pad0 = rep.pad1 = rep.pad2 = rep.pad3 = rep.pad4 = 0;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xLbxQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+static int
+NextProxyID()
+{
+ LbxProxyPtr proxy;
+ int id;
+
+ for (id = 1; id < MAX_NUM_PROXIES; id++) {
+ for (proxy = proxyList; proxy && proxy->pid != id; proxy = proxy->next)
+ ;
+ if (!proxy)
+ return id;
+ }
+ return -1;
+}
+
+int
+ProcLbxStartProxy(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxStartProxyReq);
+ LbxProxyPtr proxy;
+ LbxClientPtr lbxClient;
+ int reqlen;
+ int replylen;
+ xLbxStartReply *replybuf;
+ LbxNegOptsRec negopt;
+ register int n;
+ pointer compHandle = NULL;
+
+ REQUEST_AT_LEAST_SIZE(xLbxStartProxyReq);
+ if (lbxClients[client->index])
+ return BadLbxClientCode;
+ proxy = (LbxProxyPtr) xalloc (sizeof (LbxProxyRec));
+ if (!proxy)
+ return BadAlloc;
+ bzero(proxy, sizeof (LbxProxyRec));
+ proxy->pid = NextProxyID();
+ if (proxy->pid < 0) { /* too many proxies */
+ xfree(proxy);
+ return BadAlloc;
+ }
+ proxy->uid = ++uid_seed;
+ if (!proxyList)
+ AddCallback(&ReplyCallback, LbxReplyCallback, NULL);
+
+ if(!proxyList)
+ proxyList = proxy;
+ else{
+ proxy->next = proxyList;
+ proxyList = proxy;
+ }
+
+ /*
+ * Don't know exactly how big the reply will be, but it won't be
+ * bigger than the request
+ */
+ reqlen = client->req_len << 2;
+ replybuf = (xLbxStartReply *) xalloc(max(reqlen, sz_xLbxStartReply));
+ if (!replybuf) {
+ LbxFreeProxy(proxy);
+ return BadAlloc;
+ }
+
+ LbxOptionInit(&negopt);
+
+ replylen = LbxOptionParse(&negopt,
+ &stuff[1],
+ reqlen - sz_xLbxStartProxyReq,
+ &replybuf->optDataStart);
+ if (replylen < 0) {
+ /*
+ * Didn't understand option format, so we'll just end up
+ * using the defaults. Set nopts so that the proxy will
+ * be informed that we rejected the options because of
+ * decoding problems.
+ */
+ LbxOptionInit(&negopt);
+ negopt.nopts = 0xff;
+ replylen = 0;
+ }
+
+ if (LBXInitDeltaCache(&proxy->indeltas, negopt.proxyDeltaN,
+ negopt.proxyDeltaMaxLen) < 0
+ ||
+ LBXInitDeltaCache(&proxy->outdeltas, negopt.serverDeltaN,
+ negopt.serverDeltaMaxLen) < 0) {
+ LbxFreeProxy(proxy);
+ xfree(replybuf);
+ return BadAlloc;
+ }
+
+ n = 0;
+ if (negopt.proxyDeltaN)
+ n = negopt.proxyDeltaMaxLen;
+ if (negopt.serverDeltaN && negopt.serverDeltaMaxLen > n)
+ n = negopt.serverDeltaMaxLen;
+ if (n &&
+ (!(proxy->iDeltaBuf = (char *)xalloc (n)) ||
+ !(proxy->replyBuf = (char *)xalloc (n)) ||
+ !(proxy->oDeltaBuf = (char *)xalloc (n)))) {
+ LbxFreeProxy(proxy);
+ xfree(replybuf);
+ return BadAlloc;
+ }
+
+ MakeClientGrabImpervious(client); /* proxy needs to be grab-proof */
+ proxy->fd = ClientConnectionNumber(client);
+ if (negopt.streamOpts.streamCompInit) {
+ compHandle =
+ (*negopt.streamOpts.streamCompInit)(proxy->fd, negopt.streamOpts.streamCompArg);
+ if (!compHandle) {
+ LbxFreeProxy(proxy);
+ xfree(replybuf);
+ return BadAlloc;
+ }
+ }
+ proxy->ofirst = NULL;
+ proxy->olast = NULL;
+ if (!LbxInitClient (proxy, client, 0))
+ {
+ LbxFreeProxy(proxy);
+ xfree(replybuf);
+ return BadAlloc;
+ }
+ proxy->dosquishing = negopt.squish;
+ proxy->numBitmapCompMethods = negopt.numBitmapCompMethods;
+ proxy->bitmapCompMethods = negopt.bitmapCompMethods;
+ proxy->numPixmapCompMethods = negopt.numPixmapCompMethods;
+ proxy->pixmapCompMethods = negopt.pixmapCompMethods;
+ proxy->pixmapCompDepths = negopt.pixmapCompDepths;
+
+ proxy->streamOpts = negopt.streamOpts;
+ proxy->useTags = negopt.useTags;
+
+ proxy->grabbedCmaps = NULL;
+
+ /* send reply */
+ replybuf->type = X_Reply;
+ replybuf->nOpts = negopt.nopts;
+ replybuf->sequenceNumber = client->sequence;
+
+ replylen += sz_xLbxStartReplyHdr;
+ if (replylen < sz_xLbxStartReply)
+ replylen = sz_xLbxStartReply;
+ replybuf->length = (replylen - sz_xLbxStartReply + 3) >> 2;
+ if (client->swapped) {
+ swaps(&replybuf->sequenceNumber, n);
+ swapl(&replybuf->length, n);
+ }
+ lbxClient = LbxClient(client);
+ WriteToClient(client, replylen, (char *)replybuf);
+
+ LbxProxyConnection(client, proxy);
+ lbxClient = proxy->lbxClients[0];
+ proxy->curDix = lbxClient;
+ proxy->curRecv = lbxClient;
+ proxy->compHandle = compHandle;
+
+ if (proxy->compHandle && !lbxCompressWorkProcCount++)
+ QueueWorkProc(LbxCheckCompressInput, NULL, NULL);
+
+ xfree(replybuf);
+ return Success;
+}
+
+int
+ProcLbxStopProxy(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxStopProxyReq);
+ LbxProxyPtr proxy;
+ LbxClientPtr lbxClient = LbxClient(client);
+
+ REQUEST_SIZE_MATCH(xLbxStopProxyReq);
+
+ if (!lbxClient)
+ return BadLbxClientCode;
+ if (lbxClient->id)
+ return BadLbxClientCode;
+
+ proxy = lbxClient->proxy;
+ LbxFreeClient (client);
+ LbxShutdownProxy (proxy);
+ return Success;
+}
+
+int
+ProcLbxSwitch(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxSwitchReq);
+ LbxProxyPtr proxy = LbxMaybeProxy(client);
+ LbxClientPtr lbxClient;
+ int i;
+
+ REQUEST_SIZE_MATCH(xLbxSwitchReq);
+ if (!proxy)
+ return BadLbxClientCode;
+ for (i = 0; i <= proxy->maxIndex; i++) {
+ lbxClient = proxy->lbxClients[i];
+ if (lbxClient && lbxClient->id == stuff->client) {
+ LbxSwitchRecv (proxy, lbxClient);
+ return Success;
+ }
+ }
+ LbxSwitchRecv (proxy, NULL);
+ return BadLbxClientCode;
+}
+
+int
+ProcLbxBeginLargeRequest(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxBeginLargeRequestReq);
+
+ client->sequence--;
+ REQUEST_SIZE_MATCH(xLbxBeginLargeRequestReq);
+ if (!AllocateLargeReqBuffer(client, stuff->largeReqLength << 2))
+ return BadAlloc;
+ return Success;
+}
+
+
+int
+ProcLbxLargeRequestData(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxLargeRequestDataReq);
+
+ client->sequence--;
+ REQUEST_AT_LEAST_SIZE(xLbxLargeRequestDataReq);
+ if (!AddToLargeReqBuffer(client, (char *) (stuff + 1),
+ (client->req_len - 1) << 2))
+ return BadAlloc;
+ return Success;
+}
+
+
+int
+ProcLbxEndLargeRequest(client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+
+ client->sequence--;
+ REQUEST_SIZE_MATCH(xReq);
+ return BadAlloc;
+}
+
+
+int
+ProcLbxInternAtoms(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxInternAtomsReq);
+ LbxClientPtr lbxClient = LbxClient(client);
+ xLbxInternAtomsReply *replyRet;
+ char *ptr = (char *) stuff + sz_xLbxInternAtomsReq;
+ Atom *atomsRet;
+ int replyLen, i;
+ char lenbuf[2];
+ CARD16 len;
+ char n;
+
+ REQUEST_AT_LEAST_SIZE(xLbxInternAtomsReq);
+
+ if (!lbxClient)
+ return BadLbxClientCode;
+ if (lbxClient->id)
+ return BadLbxClientCode;
+
+ replyLen = sz_xLbxInternAtomsReplyHdr + stuff->num * sizeof (Atom);
+ if (replyLen < sz_xLbxInternAtomsReply)
+ replyLen = sz_xLbxInternAtomsReply;
+
+ if (!(replyRet = (xLbxInternAtomsReply *) xalloc (replyLen)))
+ return BadAlloc;
+
+ atomsRet = (Atom *) ((char *) replyRet + sz_xLbxInternAtomsReplyHdr);
+
+ for (i = 0; i < stuff->num; i++)
+ {
+ lenbuf[0] = ptr[0];
+ lenbuf[1] = ptr[1];
+ len = *((CARD16 *) lenbuf);
+ ptr += 2;
+
+ if ((atomsRet[i] = MakeAtom (ptr, len, TRUE)) == BAD_RESOURCE)
+ {
+ xfree (replyRet);
+ return BadAlloc;
+ }
+
+ ptr += len;
+ }
+
+ if (client->swapped)
+ for (i = 0; i < stuff->num; i++)
+ swapl (&atomsRet[i], n);
+
+ replyRet->type = X_Reply;
+ replyRet->sequenceNumber = client->sequence;
+ replyRet->length = (replyLen - sz_xLbxInternAtomsReply + 3) >> 2;
+
+ if (client->swapped) {
+ swaps(&replyRet->sequenceNumber, n);
+ swapl(&replyRet->length, n);
+ }
+
+ WriteToClient (client, replyLen, (char *) replyRet);
+
+ xfree (replyRet);
+
+ return Success;
+}
+
+
+int
+ProcLbxGetWinAttrAndGeom(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxGetWinAttrAndGeomReq);
+ xGetWindowAttributesReply wa;
+ xGetGeometryReply wg;
+ xLbxGetWinAttrAndGeomReply reply;
+ WindowPtr pWin;
+ int status;
+
+ REQUEST_SIZE_MATCH(xLbxGetWinAttrAndGeomReq);
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return(BadWindow);
+ GetWindowAttributes(pWin, client, &wa);
+
+ if ((status = GetGeometry(client, &wg)) != Success)
+ return status;
+
+ reply.type = X_Reply;
+ reply.length = (sz_xLbxGetWinAttrAndGeomReply - 32) >> 2;
+ reply.sequenceNumber = client->sequence;
+
+ reply.backingStore = wa.backingStore;
+ reply.visualID = wa.visualID;
+#if defined(__cplusplus) || defined(c_plusplus)
+ reply.c_class = wa.c_class;
+#else
+ reply.class = wa.class;
+#endif
+ reply.bitGravity = wa.bitGravity;
+ reply.winGravity = wa.winGravity;
+ reply.backingBitPlanes = wa.backingBitPlanes;
+ reply.backingPixel = wa.backingPixel;
+ reply.saveUnder = wa.saveUnder;
+ reply.mapInstalled = wa.mapInstalled;
+ reply.mapState = wa.mapState;
+ reply.override = wa.override;
+ reply.colormap = wa.colormap;
+ reply.allEventMasks = wa.allEventMasks;
+ reply.yourEventMask = wa.yourEventMask;
+ reply.doNotPropagateMask = wa.doNotPropagateMask;
+ reply.pad1 = 0;
+ reply.root = wg.root;
+ reply.x = wg.x;
+ reply.y = wg.y;
+ reply.width = wg.width;
+ reply.height = wg.height;
+ reply.borderWidth = wg.borderWidth;
+ reply.depth = wg.depth;
+ reply.pad2 = 0;
+
+ if (client->swapped)
+ {
+ register char n;
+
+ swaps(&reply.sequenceNumber, n);
+ swapl(&reply.length, n);
+ swapl(&reply.visualID, n);
+ swaps(&reply.class, n);
+ swapl(&reply.backingBitPlanes, n);
+ swapl(&reply.backingPixel, n);
+ swapl(&reply.colormap, n);
+ swapl(&reply.allEventMasks, n);
+ swapl(&reply.yourEventMask, n);
+ swaps(&reply.doNotPropagateMask, n);
+ swapl(&reply.root, n);
+ swaps(&reply.x, n);
+ swaps(&reply.y, n);
+ swaps(&reply.width, n);
+ swaps(&reply.height, n);
+ swaps(&reply.borderWidth, n);
+ }
+
+ WriteToClient(client, sizeof(xLbxGetWinAttrAndGeomReply), (char *)&reply);
+ return(client->noClientException);
+}
+
+int
+ProcLbxNewClient(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxNewClientReq);
+ ClientPtr newClient;
+ LbxProxyPtr proxy = LbxMaybeProxy(client);
+ CARD32 id;
+ int len, i;
+ char *setupbuf;
+ LbxClientPtr lbxClient;
+
+ REQUEST_AT_LEAST_SIZE(xLbxNewClientReq);
+
+ /* save info before our request disappears */
+ id = stuff->client;
+ if (!proxy || !id)
+ return BadLbxClientCode;
+ if (proxy->numClients == MAX_LBX_CLIENTS)
+ return BadAlloc;
+ for (i = 1; i <= proxy->maxIndex; i++) {
+ if (proxy->lbxClients[i] && proxy->lbxClients[i]->id == id)
+ return BadLbxClientCode;
+ }
+ len = (client->req_len << 2) - sizeof(xLbxNewClientReq);
+ setupbuf = (char *)xalloc (len);
+ if (!setupbuf)
+ return BadAlloc;
+ memcpy (setupbuf, (char *)&stuff[1], len);
+
+ newClient = AllocLbxClientConnection (client, proxy);
+ if (!newClient)
+ return BadAlloc;
+ newClient->requestVector = LbxInitialVector;
+ lbxClient = LbxInitClient (proxy, newClient, id);
+ if (!lbxClient)
+ {
+ CloseDownClient (newClient);
+ return BadAlloc;
+ }
+
+ AppendFakeRequest (newClient, setupbuf, len);
+ xfree (setupbuf);
+ LbxSetForBlock(lbxClient);
+
+ DBG (DBG_CLIENT, (stderr, "lbxNewClient X %d\n", newClient->index));
+ return Success;
+}
+
+int
+ProcLbxEstablishConnection(client)
+ register ClientPtr client;
+{
+ char *reason = NULL;
+ char *auth_proto, *auth_string;
+ register xConnClientPrefix *prefix;
+ REQUEST(xReq);
+
+ prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+ auth_proto = (char *)prefix + sz_xConnClientPrefix;
+ auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
+ if ((prefix->majorVersion != X_PROTOCOL) ||
+ (prefix->minorVersion != X_PROTOCOL_REVISION))
+ reason = "Protocol version mismatch";
+ else
+ reason = ClientAuthorized(client,
+ prefix->nbytesAuthProto,
+ auth_proto,
+ prefix->nbytesAuthString,
+ auth_string);
+
+ if (client->clientState == ClientStateCheckingSecurity ||
+ client->clientState == ClientStateAuthenticating)
+ return (client->noClientException = -1); /* XXX some day */
+ return(LbxSendConnSetup(client, reason));
+}
+
+int
+ProcLbxCloseClient (client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxCloseClientReq);
+ LbxClientPtr lbxClient = LbxClient(client);
+
+ REQUEST_SIZE_MATCH(xLbxCloseClientReq);
+ if (!lbxClient || lbxClient->id != stuff->client)
+ return BadLbxClientCode;
+
+ /* this will cause the client to be closed down back in Dispatch() */
+ return(client->noClientException = CloseLbxClient);
+}
+
+int
+ProcLbxModifySequence (client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxModifySequenceReq);
+
+ REQUEST_SIZE_MATCH(xLbxModifySequenceReq);
+ client->sequence += (stuff->adjust - 1); /* Dispatch() adds 1 */
+ return Success;
+}
+
+int
+ProcLbxAllowMotion (client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxAllowMotionReq);
+
+ client->sequence--;
+ REQUEST_SIZE_MATCH(xLbxAllowMotionReq);
+ LbxAllowMotion(client, stuff->num);
+ return Success;
+}
+
+
+static int
+DecodeLbxDelta(client)
+ register ClientPtr client;
+{
+ REQUEST(xLbxDeltaReq);
+ LbxClientPtr lbxClient = LbxClient(client);
+ LbxProxyPtr proxy = lbxClient->proxy;
+ int len;
+ char *buf;
+
+ /* Note that LBXDecodeDelta decodes and adds current msg to the cache */
+ len = LBXDecodeDelta(&proxy->indeltas, ((char *)stuff) + sz_xLbxDeltaReq,
+ stuff->diffs, stuff->cindex, &buf);
+ /*
+ * Some requests, such as FillPoly, result in the protocol input
+ * buffer being modified. So we need to copy the request
+ * into a temporary buffer where a write would be harmless.
+ * Maybe some day do this copying on a case by case basis,
+ * since not all requests are guilty of this.
+ */
+ memcpy(proxy->iDeltaBuf, buf, len);
+
+ client->requestBuffer = proxy->iDeltaBuf;
+ client->req_len = len >> 2;
+ return len;
+}
+
+int
+ProcLbxGetModifierMapping(client)
+ ClientPtr client;
+{
+ REQUEST(xLbxGetModifierMappingReq);
+
+ REQUEST_SIZE_MATCH(xLbxGetModifierMappingReq);
+ return LbxGetModifierMapping(client);
+}
+
+int
+ProcLbxGetKeyboardMapping(client)
+ ClientPtr client;
+{
+ REQUEST(xLbxGetKeyboardMappingReq);
+
+ REQUEST_SIZE_MATCH(xLbxGetKeyboardMappingReq);
+ return LbxGetKeyboardMapping(client);
+}
+
+int
+ProcLbxQueryFont(client)
+ ClientPtr client;
+{
+ REQUEST(xLbxQueryFontReq);
+
+ REQUEST_SIZE_MATCH(xLbxQueryFontReq);
+ return LbxQueryFont(client);
+}
+
+int
+ProcLbxChangeProperty(client)
+ ClientPtr client;
+{
+ REQUEST(xLbxChangePropertyReq);
+
+ REQUEST_SIZE_MATCH(xLbxChangePropertyReq);
+ return LbxChangeProperty(client);
+}
+
+int
+ProcLbxGetProperty(client)
+ ClientPtr client;
+{
+ REQUEST(xLbxGetPropertyReq);
+
+ REQUEST_SIZE_MATCH(xLbxGetPropertyReq);
+ return LbxGetProperty(client);
+}
+
+int
+ProcLbxTagData(client)
+ ClientPtr client;
+{
+ REQUEST(xLbxTagDataReq);
+
+ client->sequence--; /* not a counted request */
+ REQUEST_AT_LEAST_SIZE(xLbxTagDataReq);
+
+ return LbxTagData(client, stuff->tag, stuff->real_length,
+ (pointer)&stuff[1]); /* better not give any errors */
+}
+
+int
+ProcLbxInvalidateTag(client)
+ ClientPtr client;
+{
+ REQUEST(xLbxInvalidateTagReq);
+
+ client->sequence--;
+ REQUEST_SIZE_MATCH(xLbxInvalidateTagReq);
+ return LbxInvalidateTag(client, stuff->tag);
+}
+
+int
+ProcLbxPolyPoint(client)
+ register ClientPtr client;
+{
+ return LbxDecodePoly(client, X_PolyPoint, LbxDecodePoints);
+}
+
+int
+ProcLbxPolyLine(client)
+ register ClientPtr client;
+{
+ return LbxDecodePoly(client, X_PolyLine, LbxDecodePoints);
+}
+
+int
+ProcLbxPolySegment(client)
+ register ClientPtr client;
+{
+ return LbxDecodePoly(client, X_PolySegment, LbxDecodeSegment);
+}
+
+int
+ProcLbxPolyRectangle(client)
+ register ClientPtr client;
+{
+ return LbxDecodePoly(client, X_PolyRectangle, LbxDecodeRectangle);
+}
+
+int
+ProcLbxPolyArc(client)
+ register ClientPtr client;
+{
+ return LbxDecodePoly(client, X_PolyArc, LbxDecodeArc);
+}
+
+int
+ProcLbxFillPoly(client)
+ register ClientPtr client;
+{
+ return LbxDecodeFillPoly(client);
+}
+
+int
+ProcLbxPolyFillRectangle(client)
+ register ClientPtr client;
+{
+ return LbxDecodePoly(client, X_PolyFillRectangle, LbxDecodeRectangle);
+}
+
+int
+ProcLbxPolyFillArc(client)
+ register ClientPtr client;
+{
+ return LbxDecodePoly(client, X_PolyFillArc, LbxDecodeArc);
+}
+
+int
+ProcLbxCopyArea (client)
+ register ClientPtr client;
+{
+ return LbxDecodeCopyArea(client);
+}
+
+int
+ProcLbxCopyPlane (client)
+ register ClientPtr client;
+{
+ return LbxDecodeCopyPlane(client);
+}
+
+
+int
+ProcLbxPolyText (client)
+ register ClientPtr client;
+{
+ return LbxDecodePolyText(client);
+}
+
+int
+ProcLbxImageText (client)
+ register ClientPtr client;
+{
+ return LbxDecodeImageText(client);
+}
+
+int
+ProcLbxQueryExtension(client)
+ ClientPtr client;
+{
+ REQUEST(xLbxQueryExtensionReq);
+ char *ename;
+
+ REQUEST_AT_LEAST_SIZE(xLbxQueryExtensionReq);
+ ename = (char *) &stuff[1];
+ return LbxQueryExtension(client, ename, stuff->nbytes);
+}
+
+int
+ProcLbxPutImage(client)
+ register ClientPtr client;
+{
+ return LbxDecodePutImage(client);
+}
+
+int
+ProcLbxGetImage(client)
+ register ClientPtr client;
+{
+ return LbxDecodeGetImage(client);
+}
+
+
+int
+ProcLbxSync(client)
+ register ClientPtr client;
+{
+ xLbxSyncReply reply;
+
+ client->sequence--; /* not a counted request */
+
+#ifdef COLOR_DEBUG
+ fprintf (stderr, "Got LBX sync, seq = 0x%x\n", client->sequence);
+#endif
+
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.pad0 = reply.pad1 = reply.pad2 = reply.pad3 = reply.pad4 =
+ reply.pad5 = reply.pad6 = 0;
+
+ if (client->swapped)
+ {
+ register char n;
+ swaps (&reply.sequenceNumber, n);
+ }
+
+ WriteToClient (client, sz_xLbxSyncReply, (char *)&reply);
+
+ return (client->noClientException);
+}
+
+
+int
+ProcLbxDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_LbxQueryVersion:
+ return ProcLbxQueryVersion(client);
+ case X_LbxStartProxy:
+ return ProcLbxStartProxy(client);
+ case X_LbxStopProxy:
+ return ProcLbxStopProxy(client);
+ case X_LbxNewClient:
+ return ProcLbxNewClient(client);
+ case X_LbxCloseClient:
+ return ProcLbxCloseClient(client);
+ case X_LbxModifySequence:
+ return ProcLbxModifySequence(client);
+ case X_LbxAllowMotion:
+ return ProcLbxAllowMotion(client);
+ case X_LbxIncrementPixel:
+ return ProcLbxIncrementPixel(client);
+ case X_LbxGrabCmap:
+ return ProcLbxGrabCmap(client);
+ case X_LbxReleaseCmap:
+ return ProcLbxReleaseCmap(client);
+ case X_LbxAllocColor:
+ return ProcLbxAllocColor(client);
+ case X_LbxGetModifierMapping:
+ return ProcLbxGetModifierMapping(client);
+ case X_LbxGetKeyboardMapping:
+ return ProcLbxGetKeyboardMapping(client);
+ case X_LbxInvalidateTag:
+ return ProcLbxInvalidateTag(client);
+ case X_LbxPolyPoint:
+ return ProcLbxPolyPoint (client);
+ case X_LbxPolyLine:
+ return ProcLbxPolyLine (client);
+ case X_LbxPolySegment:
+ return ProcLbxPolySegment (client);
+ case X_LbxPolyRectangle:
+ return ProcLbxPolyRectangle (client);
+ case X_LbxPolyArc:
+ return ProcLbxPolyArc (client);
+ case X_LbxFillPoly:
+ return ProcLbxFillPoly (client);
+ case X_LbxPolyFillRectangle:
+ return ProcLbxPolyFillRectangle (client);
+ case X_LbxPolyFillArc:
+ return ProcLbxPolyFillArc (client);
+ case X_LbxQueryFont:
+ return ProcLbxQueryFont (client);
+ case X_LbxChangeProperty:
+ return ProcLbxChangeProperty (client);
+ case X_LbxGetProperty:
+ return ProcLbxGetProperty (client);
+ case X_LbxTagData:
+ return ProcLbxTagData (client);
+ case X_LbxCopyArea:
+ return ProcLbxCopyArea (client);
+ case X_LbxCopyPlane:
+ return ProcLbxCopyPlane (client);
+ case X_LbxPolyText8:
+ case X_LbxPolyText16:
+ return ProcLbxPolyText (client);
+ case X_LbxImageText8:
+ case X_LbxImageText16:
+ return ProcLbxImageText (client);
+ case X_LbxQueryExtension:
+ return ProcLbxQueryExtension (client);
+ case X_LbxPutImage:
+ return ProcLbxPutImage (client);
+ case X_LbxGetImage:
+ return ProcLbxGetImage (client);
+ case X_LbxInternAtoms:
+ return ProcLbxInternAtoms(client);
+ case X_LbxGetWinAttrAndGeom:
+ return ProcLbxGetWinAttrAndGeom(client);
+ case X_LbxSync:
+ return ProcLbxSync(client);
+ case X_LbxBeginLargeRequest:
+ return ProcLbxBeginLargeRequest(client);
+ case X_LbxLargeRequestData:
+ return ProcLbxLargeRequestData(client);
+ case X_LbxEndLargeRequest:
+ return ProcLbxLargeRequestData(client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/xc/programs/Xserver/lbx/lbxopts.c b/xc/programs/Xserver/lbx/lbxopts.c
new file mode 100644
index 000000000..a03c78847
--- /dev/null
+++ b/xc/programs/Xserver/lbx/lbxopts.c
@@ -0,0 +1,818 @@
+/* $XConsortium: lbxopts.c /main/8 1996/11/15 21:14:56 rws $ */
+/*
+ * Copyright 1994 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/* $XFree86: xc/programs/Xserver/lbx/lbxopts.c,v 1.2 1998/12/20 11:57:56 dawes Exp $ */
+
+#ifdef OPTDEBUG
+#include <stdio.h>
+#endif
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "lbxserve.h"
+#include "lbxstr.h"
+#include "lbximage.h"
+#include "lbxopts.h"
+#include "lbxsrvopts.h"
+#ifndef NO_ZLIB
+#include "lbxzlib.h"
+#endif /* NO_ZLIB */
+
+static int LbxDeltaOpt();
+static int LbxProxyDeltaOpt();
+static int LbxServerDeltaOpt();
+static int LbxStreamCompOpt();
+static int LbxBitmapCompOpt();
+static int LbxPixmapCompOpt();
+static int LbxMessageCompOpt();
+static int LbxUseTagsOpt();
+static int LbxCmapAllOpt();
+
+/*
+ * List of LBX options we recognize and are willing to negotiate
+ */
+static struct _LbxOptionParser {
+ CARD8 optcode;
+ int (*parser)();
+} LbxOptions[] = {
+ { LBX_OPT_DELTA_PROXY, LbxProxyDeltaOpt },
+ { LBX_OPT_DELTA_SERVER, LbxServerDeltaOpt },
+ { LBX_OPT_STREAM_COMP, LbxStreamCompOpt },
+ { LBX_OPT_BITMAP_COMP, LbxBitmapCompOpt },
+ { LBX_OPT_PIXMAP_COMP, LbxPixmapCompOpt },
+ { LBX_OPT_MSG_COMP, LbxMessageCompOpt },
+ { LBX_OPT_USE_TAGS, LbxUseTagsOpt },
+ { LBX_OPT_CMAP_ALL, LbxCmapAllOpt }
+};
+
+#define LBX_N_OPTS (sizeof(LbxOptions) / sizeof(struct _LbxOptionParser))
+
+/*
+ * Set option defaults
+ */
+LbxOptionInit(pno)
+ LbxNegOptsPtr pno;
+{
+ bzero(pno, sizeof(LbxNegOptsRec));
+ pno->proxyDeltaN = pno->serverDeltaN = LBX_OPT_DELTA_NCACHE_DFLT;
+ pno->proxyDeltaMaxLen = pno->serverDeltaMaxLen = LBX_OPT_DELTA_MSGLEN_DFLT;
+ pno->squish = TRUE;
+ pno->numBitmapCompMethods = 0;
+ pno->bitmapCompMethods = NULL;
+ pno->numPixmapCompMethods = 0;
+ pno->pixmapCompMethods = NULL;
+ pno->pixmapCompDepths = NULL;
+ pno->useTags = TRUE;
+}
+
+int
+LbxOptionParse(pno, popt, optlen, preply)
+ LbxNegOptsPtr pno;
+ unsigned char *popt;
+ int optlen;
+ unsigned char *preply;
+{
+ int i;
+ int nopts = *popt++;
+ unsigned char *pout = preply;
+
+ for (i = 0; i < nopts; i++) {
+ int j;
+ int len;
+ int hdrlen;
+ int replylen;
+
+ LBX_OPT_DECODE_LEN(popt + 1, len, hdrlen);
+ if (len < ++hdrlen || len > optlen) {
+#ifdef OPTDEBUG
+ fprintf(stderr, "bad option length, len = %d, hdrlen = %d, optlen = %d\n", len, hdrlen, optlen);
+#endif
+ return -1;
+ }
+
+ for (j = 0; j < LBX_N_OPTS; j++) {
+ if (popt[0] == LbxOptions[j].optcode) {
+ replylen = (*LbxOptions[j].parser)(pno,
+ popt + hdrlen,
+ len - hdrlen,
+ pout + LBX_OPT_SMALLHDR_LEN);
+ if (replylen < 0)
+ return -1;
+ else if (replylen > 0) {
+ /*
+ * None of the current options require big headers,
+ * so this works for now.
+ */
+ *pout++ = i;
+ *pout++ = LBX_OPT_SMALLHDR_LEN + replylen;
+ pout += replylen;
+ pno->nopts++;
+ }
+ break;
+ }
+ }
+
+ optlen -= len;
+ popt += len;
+ }
+
+ return (pout - preply);
+}
+
+static int
+LbxProxyDeltaOpt(pno, popt, optlen, preply)
+ LbxNegOptsPtr pno;
+ unsigned char *popt;
+ int optlen;
+ unsigned char *preply;
+{
+ return LbxDeltaOpt(popt, optlen, preply,
+ &pno->proxyDeltaN, &pno->proxyDeltaMaxLen);
+}
+
+static int
+LbxServerDeltaOpt(pno, popt, optlen, preply)
+ LbxNegOptsPtr pno;
+ unsigned char *popt;
+ int optlen;
+ unsigned char *preply;
+{
+ return LbxDeltaOpt(popt, optlen, preply,
+ &pno->serverDeltaN, &pno->serverDeltaMaxLen);
+}
+
+static int
+LbxDeltaOpt(popt, optlen, preply, pn, pmaxlen)
+ unsigned char *popt;
+ int optlen;
+ unsigned char *preply;
+ short *pn;
+ short *pmaxlen;
+{
+ short n;
+ short maxlen;
+
+ /*
+ * If there's more data than we expect, we just ignore it.
+ */
+ if (optlen < LBX_OPT_DELTA_REQLEN) {
+#ifdef OPTDEBUG
+ fprintf(stderr, "bad delta option length = %d\n", optlen);
+#endif
+ return -1;
+ }
+
+ /*
+ * Accept whatever value the proxy prefers, so skip the
+ * min/max offerings. Note that the max message len value is
+ * encoded as the number of 4-byte values.
+ */
+ popt += 2;
+ n = *popt++;
+ popt += 2;
+ maxlen = *popt++;
+ if ((maxlen <<= 2) == 0)
+ n = 0;
+ else if (maxlen < 32) {
+#ifdef OPTDEBUG
+ fprintf(stderr, "bad delta max msg length %d\n", maxlen);
+#endif
+ return -1;
+ }
+
+ /*
+ * Put the response in the reply buffer
+ */
+ *preply++ = n;
+ *preply++ = maxlen >> 2;
+
+ *pn = n;
+ *pmaxlen = maxlen;
+
+ return LBX_OPT_DELTA_REPLYLEN;
+}
+
+static int ZlibParse();
+
+static struct _LbxStreamCompParser {
+ int typelen;
+ char *type;
+ int (*parser)();
+} LbxStreamComp[] = {
+#ifndef NO_ZLIB
+ { ZLIB_STRCOMP_OPT_LEN, ZLIB_STRCOMP_OPT, ZlibParse },
+#endif /* NO_ZLIB */
+};
+
+#define LBX_N_STRCOMP \
+ (sizeof(LbxStreamComp) / sizeof(struct _LbxStreamCompParser))
+
+static int
+LbxStreamCompOpt(pno, popt, optlen, preply)
+ LbxNegOptsPtr pno;
+ unsigned char *popt;
+ int optlen;
+ unsigned char *preply;
+{
+ int i;
+ int typelen;
+ int nopts = *popt++;
+
+ for (i = 0; i < nopts; i++) {
+ int j;
+ int len;
+ int lensize;
+ int replylen;
+
+ typelen = popt[0];
+ for (j = 0; j < LBX_N_STRCOMP; j++) {
+ if (typelen == LbxStreamComp[j].typelen &&
+ !strncmp((char *) popt + 1, LbxStreamComp[j].type, typelen))
+ break;
+ }
+
+ popt += 1 + typelen;
+ optlen -= 1 + typelen;
+ LBX_OPT_DECODE_LEN(popt, len, lensize);
+
+ if (j < LBX_N_STRCOMP) {
+ if (len > optlen)
+ return -1;
+ replylen = (*LbxStreamComp[j].parser)(pno,
+ popt + lensize,
+ len - lensize,
+ preply + 1);
+ if (replylen == -1)
+ return -1;
+ else if (replylen >= 0) {
+ *preply = i;
+ return replylen + 1;
+ }
+ }
+
+ optlen -= len;
+ popt += len;
+ }
+
+ return 0;
+}
+
+
+extern LbxStreamCompHandle ZlibInit();
+extern int ZlibStuffInput(), ZlibInputAvail(), ZlibFlush(),
+ ZlibRead(), ZlibWriteV();
+extern void ZlibCompressOn(), ZlibCompressOff(), ZlibFree();
+
+
+static int
+ZlibParse(pno, popt, optlen, preply)
+ LbxNegOptsPtr pno;
+ unsigned char *popt;
+ int optlen;
+ unsigned char *preply;
+{
+ int level; /* compression level */
+
+ if (*popt++ != 1) /* length should be 1 */
+ return (-1);
+
+ level = *popt;
+ if (level < 1 || level > 9)
+ return (-1);
+
+ pno->streamOpts.streamCompInit = ZlibInit;
+ pno->streamOpts.streamCompArg = (pointer)(long)level;
+ pno->streamOpts.streamCompStuffInput = ZlibStuffInput;
+ pno->streamOpts.streamCompInputAvail = ZlibInputAvail;
+ pno->streamOpts.streamCompFlush = ZlibFlush;
+ pno->streamOpts.streamCompRead = ZlibRead;
+ pno->streamOpts.streamCompWriteV = ZlibWriteV;
+ pno->streamOpts.streamCompOn = ZlibCompressOn;
+ pno->streamOpts.streamCompOff = ZlibCompressOff;
+ pno->streamOpts.streamCompFreeHandle = ZlibFree;
+
+ return (0);
+}
+
+static int
+LbxMessageCompOpt(pno, popt, optlen, preply)
+ LbxNegOptsPtr pno;
+ unsigned char *popt;
+ int optlen;
+ unsigned char *preply;
+{
+
+ if (optlen == 0) {
+#ifdef OPTDEBUG
+ fprintf(stderr, "bad message-comp option length specified %d\n", optlen);
+#endif
+ return -1;
+ }
+
+ pno->squish = *preply = *popt;
+ return 1;
+}
+
+
+static int
+LbxUseTagsOpt(pno, popt, optlen, preply)
+ LbxNegOptsPtr pno;
+ unsigned char *popt;
+ int optlen;
+ unsigned char *preply;
+{
+
+ if (optlen == 0) {
+#ifdef OPTDEBUG
+ fprintf(stderr, "bad use-tags option length specified %d\n", optlen);
+#endif
+ return -1;
+ }
+
+ pno->useTags = *preply = *popt;
+ return 1;
+}
+
+
+/*
+ * Option negotiation for image compression
+ */
+
+LbxBitmapCompMethod
+LbxBitmapCompMethods [] = {
+ {
+ "XC-FaxG42D", /* compression method name */
+ 0, /* inited */
+ 2, /* method opcode */
+ NULL, /* init function */
+ LbxImageEncodeFaxG42D, /* encode function */
+ LbxImageDecodeFaxG42D /* decode function */
+ }
+};
+
+#define NUM_BITMAP_METHODS \
+ (sizeof (LbxBitmapCompMethods) / sizeof (LbxBitmapCompMethod))
+
+
+#if 1
+/*
+ * Currently, we don't support any pixmap compression algorithms
+ * because regular stream compression does much better than PackBits.
+ * If we want to plug in a better pixmap image compression algorithm,
+ * it would go here.
+ */
+
+#define NUM_PIXMAP_METHODS 0
+LbxPixmapCompMethod LbxPixmapCompMethods [1]; /* dummy */
+
+#else
+
+LbxPixmapCompMethod
+LbxPixmapCompMethods [] = {
+ {
+ "XC-PackBits", /* compression method name */
+ 1 << ZPixmap, /* formats supported */
+ 1, {8}, /* depths supported */
+ 0, /* inited */
+ 1, /* method opcode */
+ NULL, /* init function */
+ LbxImageEncodePackBits, /* encode function */
+ LbxImageDecodePackBits /* decode function */
+ }
+};
+
+#define NUM_PIXMAP_METHODS \
+ (sizeof (LbxPixmapCompMethods) / sizeof (LbxPixmapCompMethod))
+#endif
+
+static int MergeDepths ();
+
+
+static int
+LbxImageCompOpt (pixmap, pno, popt, optlen, preply)
+
+Bool pixmap;
+LbxNegOptsPtr pno;
+unsigned char *popt;
+int optlen;
+unsigned char *preply;
+
+{
+ unsigned char *preplyStart = preply;
+ int numMethods = *popt++;
+ char *myIndices, *hisIndices;
+ unsigned *retFormats;
+ int **retDepths;
+ int replyCount = 0;
+ int status, i, j;
+
+ if (numMethods == 0)
+ {
+ if (pixmap)
+ pno->numPixmapCompMethods = 0;
+ else
+ pno->numBitmapCompMethods = 0;
+
+ *preply++ = 0;
+ return (1);
+ }
+
+ myIndices = (char *) xalloc (numMethods);
+ hisIndices = (char *) xalloc (numMethods);
+
+ if (!myIndices || !hisIndices)
+ {
+ if (myIndices)
+ xfree (myIndices);
+ if (hisIndices)
+ xfree (hisIndices);
+ return -1;
+ }
+
+ if (pixmap)
+ {
+ retFormats = (unsigned *) xalloc (numMethods);
+ retDepths = (int **) xalloc (numMethods * sizeof (int *));
+
+ if (!retFormats || !retDepths)
+ {
+ if (retFormats)
+ xfree (retFormats);
+ if (retDepths)
+ xfree (retDepths);
+ xfree (myIndices);
+ xfree (hisIndices);
+ return -1;
+ }
+ }
+
+ /*
+ * For each method in the list sent by the proxy, see if the server
+ * supports this method. If YES, update the following lists:
+ *
+ * myIndices[] is a list of indices into the server's
+ * LbxBit[Pix]mapCompMethods table.
+ *
+ * hisIndices[] is a list of indices into the list of
+ * method names sent by the proxy.
+ *
+ * retFormats[] indicates for each pixmap compression method,
+ * the pixmap formats supported.
+ *
+ * retDepths[] indicates for each pixmap compression method,
+ * the pixmap depths supported.
+ */
+
+ for (i = 0; i < numMethods; i++)
+ {
+ unsigned formatMask, newFormatMask;
+ int depthCount, *depths, len;
+ int freeDepths;
+ char *methodName;
+
+ freeDepths = 0;
+ len = *popt++;
+ methodName = (char *) popt;
+ popt += len;
+
+ if (pixmap)
+ {
+ formatMask = *popt++;
+ depthCount = *popt++;
+ depths = (int *) xalloc ((depthCount + 1) * sizeof (int));
+ freeDepths = 1;
+ depths[0] = depthCount;
+ for (j = 1; j <= depthCount; j++)
+ depths[j] = *popt++;
+ }
+
+ for (j = 0;
+ j < (pixmap ? NUM_PIXMAP_METHODS : NUM_BITMAP_METHODS); j++)
+ {
+
+ status = strncmp (methodName,
+ (pixmap ? LbxPixmapCompMethods[j].methodName :
+ LbxBitmapCompMethods[j].methodName),
+ len);
+
+ if (status == 0 && pixmap)
+ {
+ newFormatMask =
+ formatMask & LbxPixmapCompMethods[j].formatMask;
+
+ depthCount = MergeDepths (depths, &LbxPixmapCompMethods[j]);
+
+ if (newFormatMask == 0 || depthCount == 0)
+ status = 1;
+ }
+
+ if (status == 0)
+ {
+ myIndices[replyCount] = j;
+ hisIndices[replyCount] = i;
+
+ if (pixmap)
+ {
+ retFormats[replyCount] = newFormatMask;
+ retDepths[replyCount] = depths;
+ freeDepths = 0;
+ }
+
+ replyCount++;
+ break;
+ }
+ }
+
+ if (freeDepths)
+ xfree (depths);
+ }
+
+ *preply++ = replyCount;
+
+ /*
+ * Sort the lists by LBX server preference (increasing myIndices[] vals)
+ */
+
+ for (i = 0; i <= replyCount - 2; i++)
+ for (j = replyCount - 1; j >= i; j--)
+ if (myIndices[j - 1] > myIndices[j])
+ {
+ char temp1 = myIndices[j - 1];
+ char temp2 = hisIndices[j - 1];
+
+ myIndices[j - 1] = myIndices[j];
+ myIndices[j] = temp1;
+
+ hisIndices[j - 1] = hisIndices[j];
+ hisIndices[j] = temp2;
+
+ if (pixmap)
+ {
+ unsigned temp3 = retFormats[j - 1];
+ int *temp4 = retDepths[j - 1];
+
+ retFormats[j - 1] = retFormats[j];
+ retFormats[j] = temp3;
+
+ retDepths[j - 1] = retDepths[j];
+ retDepths[j] = temp4;
+ }
+ }
+
+ /*
+ * For each method supported, return to the proxy an index into
+ * the list sent by the proxy, the opcode to be used for the method,
+ * the pixmap formats supported, and the list of depths supported.
+ */
+
+ for (i = 0; i < replyCount; i++)
+ {
+ *preply++ = hisIndices[i];
+
+ if (pixmap)
+ {
+ int left;
+ *preply++ = LbxPixmapCompMethods[myIndices[i]].methodOpCode;
+ *preply++ = retFormats[i];
+ *preply++ = left = retDepths[i][0];
+ j = 1;
+ while (left > 0)
+ {
+ *preply++ = retDepths[i][j];
+ left--;
+ }
+ }
+ else
+ {
+ *preply++ = LbxBitmapCompMethods[myIndices[i]].methodOpCode;
+ }
+ }
+
+ if (pixmap)
+ {
+ pno->numPixmapCompMethods = replyCount;
+ pno->pixmapCompMethods = myIndices;
+ pno->pixmapCompDepths = retDepths;
+ }
+ else
+ {
+ pno->numBitmapCompMethods = replyCount;
+ pno->bitmapCompMethods = myIndices;
+ }
+
+ if (hisIndices)
+ xfree (hisIndices);
+
+ if (pixmap)
+ {
+ if (retFormats)
+ xfree (retFormats);
+ }
+
+ return (preply - preplyStart);
+}
+
+
+
+static int
+LbxBitmapCompOpt (pno, popt, optlen, preply)
+
+LbxNegOptsPtr pno;
+unsigned char *popt;
+int optlen;
+unsigned char *preply;
+
+{
+ return (LbxImageCompOpt (0 /* bitmap */, pno, popt, optlen, preply));
+}
+
+
+static int
+LbxPixmapCompOpt (pno, popt, optlen, preply)
+
+LbxNegOptsPtr pno;
+unsigned char *popt;
+int optlen;
+unsigned char *preply;
+
+{
+ return (LbxImageCompOpt (1 /* Pixmap */, pno, popt, optlen, preply));
+}
+
+
+LbxBitmapCompMethod *
+LbxSrvrLookupBitmapCompMethod (proxy, methodOpCode)
+
+LbxProxyPtr proxy;
+int methodOpCode;
+
+{
+ int i;
+
+ for (i = 0; i < proxy->numBitmapCompMethods; i++)
+ {
+ LbxBitmapCompMethod *method;
+
+ method = &LbxBitmapCompMethods[proxy->bitmapCompMethods[i]];
+
+ if (method->methodOpCode == methodOpCode)
+ return (method);
+ }
+
+ return (NULL);
+}
+
+
+LbxPixmapCompMethod *
+LbxSrvrLookupPixmapCompMethod (proxy, methodOpCode)
+
+LbxProxyPtr proxy;
+int methodOpCode;
+
+{
+ int i;
+
+ for (i = 0; i < proxy->numPixmapCompMethods; i++)
+ {
+ LbxPixmapCompMethod *method;
+
+ method = &LbxPixmapCompMethods[proxy->pixmapCompMethods[i]];
+
+ if (method->methodOpCode == methodOpCode)
+ return (method);
+ }
+
+ return (NULL);
+}
+
+
+LbxBitmapCompMethod *
+LbxSrvrFindPreferredBitmapCompMethod (proxy)
+
+LbxProxyPtr proxy;
+
+{
+ if (proxy->numBitmapCompMethods == 0)
+ return NULL;
+ else
+ return (&LbxBitmapCompMethods[proxy->bitmapCompMethods[0]]);
+}
+
+
+
+LbxPixmapCompMethod *
+LbxSrvrFindPreferredPixmapCompMethod (proxy, format, depth)
+
+LbxProxyPtr proxy;
+int format;
+int depth;
+
+{
+ if (proxy->numPixmapCompMethods == 0)
+ return NULL;
+ else
+ {
+ LbxPixmapCompMethod *method;
+ int i, j;
+
+ for (i = 0; i < proxy->numPixmapCompMethods; i++)
+ {
+ method = &LbxPixmapCompMethods[proxy->pixmapCompMethods[i]];
+
+ if ((method->formatMask & (1 << format)))
+ {
+ int n = proxy->pixmapCompDepths[i][0];
+ j = 1;
+ while (n > 0)
+ {
+ if (depth == proxy->pixmapCompDepths[i][j])
+ return method;
+ else
+ n--;
+ }
+ }
+ }
+
+ return NULL;
+ }
+}
+
+
+static int MergeDepths (depths, method)
+
+int *depths;
+LbxPixmapCompMethod *method;
+
+{
+ int i, j, count;
+ int temp[LBX_MAX_DEPTHS + 1];
+
+ temp[0] = count = 0;
+
+ for (i = 1; i <= depths[0]; i++)
+ {
+ for (j = 0; j < method->depthCount; j++)
+ if (method->depths[j] == depths[i])
+ {
+ temp[0]++;
+ temp[++count] = depths[i];
+ break;
+ }
+ }
+
+ memcpy (depths, temp, (count + 1) * sizeof (int));
+
+ return (count);
+}
+
+
+#define LbxCmapAllMethod "XC-CMAP"
+
+static int
+LbxCmapAllOpt (pno, popt, optlen, preply)
+
+LbxNegOptsPtr pno;
+unsigned char *popt;
+int optlen;
+unsigned char *preply;
+
+{
+ int numMethods = *popt++;
+ int i;
+
+ for (i = 0; i < numMethods; i++)
+ {
+ int len;
+ char *methodName;
+
+ len = *popt++;
+ methodName = (char *) popt;
+ popt += len;
+ if (!strncmp(methodName, LbxCmapAllMethod, len))
+ break;
+ }
+ if (i >= numMethods)
+ i = 0; /* assume first one is proxy's favorite */
+ *preply = i;
+ return 1;
+}
diff --git a/xc/programs/Xserver/lbx/lbxprop.c b/xc/programs/Xserver/lbx/lbxprop.c
new file mode 100644
index 000000000..e79d18e5d
--- /dev/null
+++ b/xc/programs/Xserver/lbx/lbxprop.c
@@ -0,0 +1,548 @@
+/* $TOG: lbxprop.c /main/24 1998/02/09 14:32:29 kaleb $ */
+/*
+
+Copyright 1986, 1998 The Open Group
+
+All Rights Reserved.
+
+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 1993 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* various bits of DIX-level mangling */
+
+#include <sys/types.h>
+#include <stdio.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 "servermd.h"
+#include "propertyst.h"
+#include "windowstr.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "lbxserve.h"
+#include "lbxtags.h"
+#include "Xfuncproto.h"
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "extensions/security.h"
+#endif
+
+extern int (*ProcVector[256]) ();
+extern void (*ReplySwapVector[256]) ();
+extern void CopySwap16Write(), CopySwap32Write(), Swap32Write();
+
+void
+LbxStallPropRequest(client, pProp)
+ ClientPtr client;
+ PropertyPtr pProp;
+{
+ xReq *req = (xReq *) client->requestBuffer;
+ register char n;
+
+ LbxQueryTagData(client, pProp->owner_pid,
+ pProp->tag_id, LbxTagTypeProperty);
+
+ /*
+ * Before we reset the request, we must make sure
+ * it is in the client's byte order.
+ */
+
+ if (client->swapped) {
+ if (req->reqType == X_ChangeProperty) {
+ xChangePropertyReq *stuff = (xChangePropertyReq *) req;
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->nUnits, n);
+ switch ( stuff->format ) {
+ case 16:
+ SwapRestS(stuff);
+ break;
+ case 32:
+ SwapRestL(stuff);
+ break;
+ }
+ } else if (req->reqType == X_GetProperty) {
+ xGetPropertyReq *stuff = (xGetPropertyReq *) req;
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->longOffset, n);
+ swapl(&stuff->longLength, n);
+ } else if (req->data == X_LbxChangeProperty) {
+ xLbxChangePropertyReq *stuff = (xLbxChangePropertyReq *) req;
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->nUnits, n);
+ } else if (req->data == X_LbxGetProperty) {
+ xLbxGetPropertyReq *stuff = (xLbxGetPropertyReq *) req;
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->longOffset, n);
+ swapl(&stuff->longLength, n);
+ }
+ }
+ ResetCurrentRequest(client);
+ client->sequence--;
+ IgnoreClient(client);
+}
+
+int
+LbxChangeWindowProperty(client, pWin, property, type, format, mode, len,
+ have_data, value, sendevent, tag)
+ ClientPtr client;
+ WindowPtr pWin;
+ Atom property,
+ type;
+ int format,
+ mode;
+ unsigned long len;
+ Bool have_data;
+ pointer value;
+ Bool sendevent;
+ XID *tag;
+{
+ PropertyPtr pProp;
+ xEvent event;
+ int sizeInBytes;
+ int totalSize;
+ pointer data;
+
+ sizeInBytes = format >> 3;
+ totalSize = len * sizeInBytes;
+
+ /* first see if property already exists */
+
+ pProp = wUserProps(pWin);
+ while (pProp) {
+ if (pProp->propertyName == property)
+ break;
+ pProp = pProp->next;
+ }
+ if (!pProp) { /* just add to list */
+ if (!pWin->optional && !MakeWindowOptional(pWin))
+ return (BadAlloc);
+ pProp = (PropertyPtr) xalloc(sizeof(PropertyRec));
+ if (!pProp)
+ return (BadAlloc);
+ data = (pointer) xalloc(totalSize);
+ if (!data && len) {
+ xfree(pProp);
+ return (BadAlloc);
+ }
+ pProp->propertyName = property;
+ pProp->type = type;
+ pProp->format = format;
+ pProp->data = data;
+ if (have_data) {
+ if (len)
+ memmove((char *) data, (char *) value, totalSize);
+ pProp->tag_id = 0;
+ pProp->owner_pid = 0;
+ } else {
+ if (!TagSaveTag(LbxTagTypeProperty, totalSize,
+ (pointer)pProp, &pProp->tag_id)) {
+ xfree(pProp);
+ xfree(pProp->data);
+ return BadAlloc;
+ }
+ pProp->owner_pid = LbxProxyID(client);
+ TagMarkProxy(pProp->tag_id, pProp->owner_pid);
+ }
+ pProp->size = len;
+ pProp->next = pWin->optional->userProps;
+ pWin->optional->userProps = pProp;
+ } else {
+ /*
+ * To append or prepend to a property the request format and type must
+ * match those of the already defined property. The existing format
+ * and type are irrelevant when using the mode "PropModeReplace" since
+ * they will be written over.
+ */
+
+ if ((format != pProp->format) && (mode != PropModeReplace))
+ return (BadMatch);
+ if ((pProp->type != type) && (mode != PropModeReplace))
+ return (BadMatch);
+
+ /*
+ * if its a modify instead of replace, make sure we have the current
+ * value
+ */
+ if ((mode != PropModeReplace) && pProp->tag_id && pProp->owner_pid) {
+ LbxStallPropRequest(client, pProp);
+ return (client->noClientException);
+ }
+ /* make sure any old tag is flushed first */
+ if (pProp->tag_id)
+ TagDeleteTag(pProp->tag_id);
+ if (mode == PropModeReplace) {
+ if (totalSize != pProp->size * (pProp->format >> 3)) {
+ data = (pointer) xrealloc(pProp->data, totalSize);
+ if (!data && len)
+ return (BadAlloc);
+ pProp->data = data;
+ }
+ if (have_data) {
+ if (len)
+ memmove((char *) pProp->data, (char *) value, totalSize);
+ } else {
+ if (!TagSaveTag(LbxTagTypeProperty, totalSize,
+ (pointer)pProp, &pProp->tag_id)) {
+ xfree(pProp);
+ xfree(pProp->data);
+ return BadAlloc;
+ }
+ pProp->owner_pid = LbxProxyID(client);
+ TagMarkProxy(pProp->tag_id, pProp->owner_pid);
+ }
+ pProp->size = len;
+ pProp->type = type;
+ pProp->format = format;
+ } else if (len == 0) {
+ /* do nothing */
+ } else if (mode == PropModeAppend) {
+ data = (pointer) xrealloc(pProp->data,
+ sizeInBytes * (len + pProp->size));
+ if (!data)
+ return (BadAlloc);
+ pProp->data = data;
+ memmove(&((char *) data)[pProp->size * sizeInBytes],
+ (char *) value,
+ totalSize);
+ pProp->size += len;
+ } else if (mode == PropModePrepend) {
+ data = (pointer) xalloc(sizeInBytes * (len + pProp->size));
+ if (!data)
+ return (BadAlloc);
+ memmove(&((char *) data)[totalSize], (char *) pProp->data,
+ (int) (pProp->size * sizeInBytes));
+ memmove((char *) data, (char *) value, totalSize);
+ xfree(pProp->data);
+ pProp->data = data;
+ pProp->size += len;
+ }
+ }
+ if (sendevent) {
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyNewValue;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr) NULL);
+ }
+ if (pProp->tag_id)
+ *tag = pProp->tag_id;
+ return (Success);
+}
+
+int
+LbxChangeProperty(client)
+ ClientPtr client;
+{
+ WindowPtr pWin;
+ char format,
+ mode;
+ unsigned long len;
+ int err;
+ int n;
+ XID newtag;
+ xLbxChangePropertyReply rep;
+ REQUEST(xLbxChangePropertyReq);
+
+ REQUEST_SIZE_MATCH(xLbxChangePropertyReq);
+ UpdateCurrentTime();
+ format = stuff->format;
+ mode = stuff->mode;
+ if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
+ (mode != PropModePrepend)) {
+ client->errorValue = mode;
+ return BadValue;
+ }
+ if ((format != 8) && (format != 16) && (format != 32)) {
+ client->errorValue = format;
+ return BadValue;
+ }
+ len = stuff->nUnits;
+ if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2))
+ return BadLength;
+
+ pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
+ SecurityWriteAccess);
+ if (!pWin)
+ return (BadWindow);
+ if (!ValidAtom(stuff->property)) {
+ client->errorValue = stuff->property;
+ return (BadAtom);
+ }
+ if (!ValidAtom(stuff->type)) {
+ client->errorValue = stuff->type;
+ return (BadAtom);
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.pad = rep.pad0 = rep.pad1 = rep.pad2 = rep.pad3 = rep.pad4 = 0;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ }
+
+#ifdef XCSECURITY
+ switch (SecurityCheckPropertyAccess(client, pWin, stuff->property,
+ SecurityWriteAccess))
+ {
+ case SecurityErrorOperation:
+ client->errorValue = stuff->property;
+ return BadAtom;
+ case SecurityIgnoreOperation:
+ rep.tag = 0;
+ WriteToClient(client, sizeof(xLbxChangePropertyReply), (char *)&rep);
+ return client->noClientException;
+ }
+#endif
+
+ err = LbxChangeWindowProperty(client, pWin, stuff->property, stuff->type,
+ (int) format, (int) mode, len, FALSE, (pointer) &stuff[1],
+ TRUE, &newtag);
+ if (err)
+ return err;
+
+ rep.tag = newtag;
+
+ if (client->swapped) {
+ swapl(&rep.tag, n);
+ }
+ WriteToClient(client, sizeof(xLbxChangePropertyReply), (char *)&rep);
+
+ return client->noClientException;
+}
+
+static void
+LbxWriteGetpropReply(client, rep)
+ ClientPtr client;
+ xLbxGetPropertyReply *rep;
+{
+ int n;
+
+ if (client->swapped) {
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ swapl(&rep->propertyType, n);
+ swapl(&rep->bytesAfter, n);
+ swapl(&rep->nItems, n);
+ swapl(&rep->tag, n);
+ }
+ WriteToClient(client, sizeof(xLbxGetPropertyReply), (char *)rep);
+}
+
+int
+LbxGetProperty(client)
+ ClientPtr client;
+{
+ PropertyPtr pProp,
+ prevProp;
+ unsigned long n,
+ len,
+ ind;
+ WindowPtr pWin;
+ xLbxGetPropertyReply reply;
+ Bool send_data = FALSE;
+
+ REQUEST(xLbxGetPropertyReq);
+
+ REQUEST_SIZE_MATCH(xLbxGetPropertyReq);
+
+ reply.pad1 = 0;
+ reply.pad2 = 0;
+
+ if (stuff->delete)
+ UpdateCurrentTime();
+ pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if (!pWin)
+ return (BadWindow);
+
+ if (!ValidAtom(stuff->property)) {
+ client->errorValue = stuff->property;
+ return (BadAtom);
+ }
+ if ((stuff->delete != xTrue) && (stuff->delete != xFalse)) {
+ client->errorValue = stuff->delete;
+ return (BadValue);
+ }
+ if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type))
+ {
+ client->errorValue = stuff->type;
+ return(BadAtom);
+ }
+ pProp = wUserProps(pWin);
+ prevProp = (PropertyPtr) NULL;
+ while (pProp) {
+ if (pProp->propertyName == stuff->property)
+ break;
+ prevProp = pProp;
+ pProp = pProp->next;
+ }
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ if (!pProp) {
+ reply.nItems = 0;
+ reply.length = 0;
+ reply.bytesAfter = 0;
+ reply.propertyType = None;
+ reply.format = 0;
+ reply.tag = 0;
+ LbxWriteGetpropReply(client, &reply);
+ return client->noClientException;
+ }
+ /*
+ * If the request type and actual type don't match. Return the
+ * property information, but not the data.
+ */
+ if ((stuff->type != pProp->type) &&
+ (stuff->type != AnyPropertyType)) {
+ reply.bytesAfter = pProp->size;
+ reply.format = pProp->format;
+ reply.length = 0;
+ reply.nItems = 0;
+ reply.propertyType = pProp->type;
+ reply.tag = 0;
+ LbxWriteGetpropReply(client, &reply);
+ return client->noClientException;
+ }
+ /*
+ * Return type, format, value to client
+ */
+ n = (pProp->format >> 3) * pProp->size; /* size (bytes) of prop */
+ ind = stuff->longOffset << 2;
+
+ /*
+ * If longOffset is invalid such that it causes "len" to be
+ * negative, it's a value error.
+ */
+
+ if (n < ind) {
+ client->errorValue = stuff->longOffset;
+ return BadValue;
+ }
+
+ /* make sure we have the current value */
+ if (pProp->tag_id && pProp->owner_pid) {
+ LbxStallPropRequest(client, pProp);
+ return client->noClientException;
+ }
+
+ len = min(n - ind, stuff->longLength << 2);
+
+ reply.bytesAfter = n - (ind + len);
+ reply.format = pProp->format;
+ reply.propertyType = pProp->type;
+
+ if (!pProp->tag_id) {
+ if (n && (!stuff->delete || reply.bytesAfter)) {
+ TagSaveTag(LbxTagTypeProperty, n, (pointer)pProp, &pProp->tag_id);
+ pProp->owner_pid = 0;
+ }
+ send_data = TRUE;
+ } else
+ send_data = !TagProxyMarked(pProp->tag_id, LbxProxyID(client));
+ if (pProp->tag_id && send_data)
+ TagMarkProxy(pProp->tag_id, LbxProxyID(client));
+ reply.tag = pProp->tag_id;
+
+ if (!send_data)
+ len = 0;
+ else if (reply.tag) {
+ len = n;
+ ind = 0;
+ }
+ reply.nItems = len / (pProp->format >> 3);
+ reply.length = (len + 3) >> 2;
+
+ if (stuff->delete && (reply.bytesAfter == 0)) {
+ xEvent event;
+
+ event.u.u.type = PropertyNotify;
+ event.u.property.window = pWin->drawable.id;
+ event.u.property.state = PropertyDelete;
+ event.u.property.atom = pProp->propertyName;
+ event.u.property.time = currentTime.milliseconds;
+ DeliverEvents(pWin, &event, 1, (WindowPtr) NULL);
+ }
+ LbxWriteGetpropReply(client, &reply);
+ if (len) {
+ switch (reply.format) {
+ case 32:
+ client->pSwapReplyFunc = CopySwap32Write;
+ break;
+ case 16:
+ client->pSwapReplyFunc = CopySwap16Write;
+ break;
+ default:
+ client->pSwapReplyFunc = (void (*) ()) WriteToClient;
+ break;
+ }
+ WriteSwappedDataToClient(client, len,
+ (char *) pProp->data + ind);
+ }
+ if (stuff->delete && (reply.bytesAfter == 0)) {
+ if (pProp->tag_id)
+ TagDeleteTag(pProp->tag_id);
+ if (prevProp == (PropertyPtr) NULL) {
+ if (!(pWin->optional->userProps = pProp->next))
+ CheckWindowOptionalNeed(pWin);
+ } else
+ prevProp->next = pProp->next;
+ xfree(pProp->data);
+ xfree(pProp);
+ }
+ return client->noClientException;
+}
diff --git a/xc/programs/Xserver/lbx/lbxserve.h b/xc/programs/Xserver/lbx/lbxserve.h
new file mode 100644
index 000000000..c5b3049a1
--- /dev/null
+++ b/xc/programs/Xserver/lbx/lbxserve.h
@@ -0,0 +1,169 @@
+/* $TOG: lbxserve.h /main/15 1998/02/09 14:32:34 kaleb $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+All Rights Reserved.
+
+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 1992 Network Computing Devices
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of NCD. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. NCD. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NCD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NCD.
+ * 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 _LBXSERVE_H_
+#define _LBXSERVE_H_
+#include "lbxdeltastr.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "lbxopts.h"
+
+#define MAX_LBX_CLIENTS MAXCLIENTS
+#define MAX_NUM_PROXIES (MAXCLIENTS >> 1)
+
+typedef struct _LbxClient *LbxClientPtr;
+typedef struct _LbxProxy *LbxProxyPtr;
+
+typedef struct _LbxClient {
+ CARD32 id;
+ ClientPtr client;
+ LbxProxyPtr proxy;
+ Bool ignored;
+ Bool input_blocked;
+ int reqs_pending;
+ long bytes_in_reply;
+ long bytes_remaining;
+ Drawable drawableCache[GFX_CACHE_SIZE];
+ GContext gcontextCache[GFX_CACHE_SIZE];
+ pointer gfx_buffer; /* tmp buffer for unpacking gfx requests */
+ unsigned long gb_size;
+} LbxClientRec;
+
+typedef struct _connectionOutput *OSBufPtr;
+
+typedef struct _LbxProxy {
+ LbxProxyPtr next;
+ /* this array is indexed by lbx proxy index */
+ LbxClientPtr lbxClients[MAX_LBX_CLIENTS];
+ LbxClientPtr curRecv,
+ curDix;
+ int fd;
+ int pid; /* proxy ID */
+ int uid;
+ int numClients;
+ int maxIndex;
+ Bool aborted;
+ int grabClient;
+ pointer compHandle;
+ Bool dosquishing;
+ Bool useTags;
+ LBXDeltasRec indeltas;
+ LBXDeltasRec outdeltas;
+ char *iDeltaBuf;
+ char *replyBuf;
+ char *oDeltaBuf;
+ OSBufPtr ofirst;
+ OSBufPtr olast;
+ CARD32 cur_send_id;
+
+ LbxStreamOpts streamOpts;
+
+ int numBitmapCompMethods;
+ char *bitmapCompMethods; /* array of indices */
+ int numPixmapCompMethods;
+ char *pixmapCompMethods; /* array of indices */
+ int **pixmapCompDepths; /* depths supported from each method */
+
+ struct _ColormapRec *grabbedCmaps; /* chained via lbx private */
+ int motion_allowed_events;
+ lbxMotionCache motionCache;
+} LbxProxyRec;
+
+/* This array is indexed by server client index, not lbx proxy index */
+
+extern LbxClientPtr lbxClients[MAXCLIENTS];
+
+#define LbxClient(client) (lbxClients[(client)->index])
+#define LbxProxy(client) (LbxClient(client)->proxy)
+#define LbxMaybeProxy(client) (LbxClient(client) ? LbxProxy(client) : 0)
+#define LbxProxyID(client) (LbxProxy(client)->pid)
+#define LbxProxyClient(proxy) ((proxy)->lbxClients[0]->client)
+
+extern int LbxEventCode;
+
+extern void LbxDixInit(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern LbxProxyPtr LbxPidToProxy(
+#if NeedFunctionPrototypes
+ int /* pid */
+#endif
+);
+
+extern void LbxReencodeOutput(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ char* /*pbuf*/,
+ int* /*pcount*/,
+ char* /*cbuf*/,
+ int* /*ccount*/
+#endif
+);
+
+extern int UncompressedWriteToClient(
+#if NeedFunctionPrototypes
+ ClientPtr /*who*/,
+ int /*count*/,
+ char* /*buf*/
+#endif
+);
+
+extern ClientPtr AllocLbxClientConnection(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ LbxProxyPtr /* proxy */
+#endif
+);
+
+extern void LbxProxyConnection(
+#if NeedFunctionPrototypes
+ ClientPtr /* client */,
+ LbxProxyPtr /* proxy */
+#endif
+);
+
+#endif /* _LBXSERVE_H_ */
diff --git a/xc/programs/Xserver/lbx/lbxsquish.c b/xc/programs/Xserver/lbx/lbxsquish.c
new file mode 100644
index 000000000..c8018cee0
--- /dev/null
+++ b/xc/programs/Xserver/lbx/lbxsquish.c
@@ -0,0 +1,148 @@
+/* $TOG: lbxsquish.c /main/6 1998/02/09 14:32:39 kaleb $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+All Rights Reserved.
+
+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 1994 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "Xos.h"
+#include "misc.h"
+#include "lbxserve.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+
+/* handles server-side protocol squishing */
+
+static char lbxevdelta[] = {
+ 0,
+ 0,
+ sz_xEvent - lbxsz_KeyButtonEvent,
+ sz_xEvent - lbxsz_KeyButtonEvent,
+ sz_xEvent - lbxsz_KeyButtonEvent,
+ sz_xEvent - lbxsz_KeyButtonEvent,
+ sz_xEvent - lbxsz_KeyButtonEvent,
+ sz_xEvent - lbxsz_EnterLeaveEvent,
+ sz_xEvent - lbxsz_EnterLeaveEvent,
+ sz_xEvent - lbxsz_FocusEvent,
+ sz_xEvent - lbxsz_FocusEvent,
+ sz_xEvent - lbxsz_KeymapEvent,
+ sz_xEvent - lbxsz_ExposeEvent,
+ sz_xEvent - lbxsz_GfxExposeEvent,
+ sz_xEvent - lbxsz_NoExposeEvent,
+ sz_xEvent - lbxsz_VisibilityEvent,
+ sz_xEvent - lbxsz_CreateNotifyEvent,
+ sz_xEvent - lbxsz_DestroyNotifyEvent,
+ sz_xEvent - lbxsz_UnmapNotifyEvent,
+ sz_xEvent - lbxsz_MapNotifyEvent,
+ sz_xEvent - lbxsz_MapRequestEvent,
+ sz_xEvent - lbxsz_ReparentEvent,
+ sz_xEvent - lbxsz_ConfigureNotifyEvent,
+ sz_xEvent - lbxsz_ConfigureRequestEvent,
+ sz_xEvent - lbxsz_GravityEvent,
+ sz_xEvent - lbxsz_ResizeRequestEvent,
+ sz_xEvent - lbxsz_CirculateEvent,
+ sz_xEvent - lbxsz_CirculateEvent,
+ sz_xEvent - lbxsz_PropertyEvent,
+ sz_xEvent - lbxsz_SelectionClearEvent,
+ sz_xEvent - lbxsz_SelectionRequestEvent,
+ sz_xEvent - lbxsz_SelectionNotifyEvent,
+ sz_xEvent - lbxsz_ColormapEvent,
+ sz_xEvent - lbxsz_ClientMessageEvent,
+ sz_xEvent - lbxsz_MappingNotifyEvent
+};
+
+static char lbxevpad[] = {
+ 0,
+ 0,
+ lbxsz_KeyButtonEvent - lbxupsz_KeyButtonEvent,
+ lbxsz_KeyButtonEvent - lbxupsz_KeyButtonEvent,
+ lbxsz_KeyButtonEvent - lbxupsz_KeyButtonEvent,
+ lbxsz_KeyButtonEvent - lbxupsz_KeyButtonEvent,
+ lbxsz_KeyButtonEvent - lbxupsz_KeyButtonEvent,
+ lbxsz_EnterLeaveEvent - lbxupsz_EnterLeaveEvent,
+ lbxsz_EnterLeaveEvent - lbxupsz_EnterLeaveEvent,
+ lbxsz_FocusEvent - lbxupsz_FocusEvent,
+ lbxsz_FocusEvent - lbxupsz_FocusEvent,
+ lbxsz_KeymapEvent - lbxupsz_KeymapEvent,
+ lbxsz_ExposeEvent - lbxupsz_ExposeEvent,
+ lbxsz_GfxExposeEvent - lbxupsz_GfxExposeEvent,
+ lbxsz_NoExposeEvent - lbxupsz_NoExposeEvent,
+ lbxsz_VisibilityEvent - lbxupsz_VisibilityEvent,
+ lbxsz_CreateNotifyEvent - lbxupsz_CreateNotifyEvent,
+ lbxsz_DestroyNotifyEvent - lbxupsz_DestroyNotifyEvent,
+ lbxsz_UnmapNotifyEvent - lbxupsz_UnmapNotifyEvent,
+ lbxsz_MapNotifyEvent - lbxupsz_MapNotifyEvent,
+ lbxsz_MapRequestEvent - lbxupsz_MapRequestEvent,
+ lbxsz_ReparentEvent - lbxupsz_ReparentEvent,
+ lbxsz_ConfigureNotifyEvent - lbxupsz_ConfigureNotifyEvent,
+ lbxsz_ConfigureRequestEvent - lbxupsz_ConfigureRequestEvent,
+ lbxsz_GravityEvent - lbxupsz_GravityEvent,
+ lbxsz_ResizeRequestEvent - lbxupsz_ResizeRequestEvent,
+ lbxsz_CirculateEvent - lbxupsz_CirculateEvent,
+ lbxsz_CirculateEvent - lbxupsz_CirculateEvent,
+ lbxsz_PropertyEvent - lbxupsz_PropertyEvent,
+ lbxsz_SelectionClearEvent - lbxupsz_SelectionClearEvent,
+ lbxsz_SelectionRequestEvent - lbxupsz_SelectionRequestEvent,
+ lbxsz_SelectionNotifyEvent - lbxupsz_SelectionNotifyEvent,
+ lbxsz_ColormapEvent - lbxupsz_ColormapEvent,
+ lbxsz_ClientMessageEvent - lbxupsz_ClientMessageEvent,
+ lbxsz_MappingNotifyEvent - lbxupsz_MappingNotifyEvent
+};
+
+int
+LbxSquishEvent(buf)
+ char *buf;
+{
+ int delta = lbxevdelta[((xEvent *)buf)->u.u.type];
+ int pad = lbxevpad[((xEvent *)buf)->u.u.type];
+
+ if (delta)
+ memmove(buf + delta, buf, sz_xEvent - delta);
+ if (pad) {
+ buf += sz_xEvent;
+ while (--pad >= 0)
+ *--buf = 0;
+ }
+ return delta;
+}
diff --git a/xc/programs/Xserver/lbx/lbxsrvopts.h b/xc/programs/Xserver/lbx/lbxsrvopts.h
new file mode 100644
index 000000000..b41e3c764
--- /dev/null
+++ b/xc/programs/Xserver/lbx/lbxsrvopts.h
@@ -0,0 +1,78 @@
+/* $XConsortium: lbxsrvopts.h /main/6 1996/11/15 21:14:37 rws $ */
+/*
+ * Copyright 1994 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef _LBX_SRVOPTS_H_
+#define _LBX_SRVOPTS_H_
+
+#include "lbxopts.h"
+
+typedef struct _LbxNegOpts {
+ int nopts;
+ short proxyDeltaN;
+ short proxyDeltaMaxLen;
+ short serverDeltaN;
+ short serverDeltaMaxLen;
+ LbxStreamOpts streamOpts;
+ int numBitmapCompMethods;
+ char *bitmapCompMethods; /* array of indices */
+ int numPixmapCompMethods;
+ char *pixmapCompMethods; /* array of indices */
+ int **pixmapCompDepths; /* depths supported from each method */
+ Bool squish;
+ Bool useTags;
+} LbxNegOptsRec;
+
+typedef LbxNegOptsRec *LbxNegOptsPtr;
+
+
+extern LbxBitmapCompMethod *LbxSrvrLookupBitmapCompMethod (
+#if NeedFunctionPrototypes
+ LbxProxyPtr, /* proxy */
+ int /* methodOpCode */
+#endif
+);
+
+extern LbxPixmapCompMethod *LbxSrvrLookupPixmapCompMethod (
+#if NeedFunctionPrototypes
+ LbxProxyPtr, /* proxy */
+ int /* methodOpCode */
+#endif
+);
+
+extern LbxBitmapCompMethod *LbxSrvrFindPreferredBitmapCompMethod (
+#if NeedFunctionPrototypes
+ LbxProxyPtr /* proxy */
+#endif
+);
+
+extern LbxPixmapCompMethod *LbxSrvrFindPreferredPixmapCompMethod (
+#if NeedFunctionPrototypes
+ LbxProxyPtr, /* proxy */
+ int, /* format */
+ int /* depth */
+#endif
+);
+
+
+#endif /* _LBX_SRVOPTS_H_ */
diff --git a/xc/programs/Xserver/lbx/lbxswap.c b/xc/programs/Xserver/lbx/lbxswap.c
new file mode 100644
index 000000000..d8447f19c
--- /dev/null
+++ b/xc/programs/Xserver/lbx/lbxswap.c
@@ -0,0 +1,854 @@
+/* $TOG: lbxswap.c /main/17 1998/02/09 14:32:52 kaleb $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+All Rights Reserved.
+
+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 1992 Network Computing Devices
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of NCD. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. NCD. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NCD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NCD.
+ * 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 <sys/types.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "Xos.h"
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "lbxserve.h"
+#include "Xfuncproto.h"
+
+#include <stdio.h>
+
+static int
+SProcLbxQueryVersion(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxQueryVersionReq);
+
+ swaps(&stuff->length, n);
+ return ProcLbxQueryVersion(client);
+}
+
+static int
+SProcLbxStartProxy(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxStartProxyReq);
+
+ swaps(&stuff->length, n);
+ return ProcLbxStartProxy(client);
+}
+
+static int
+SProcLbxStopProxy(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxStopProxyReq);
+
+ swaps(&stuff->length, n);
+ return ProcLbxStopProxy(client);
+}
+
+int
+SProcLbxSwitch(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxSwitchReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->client, n);
+ return ProcLbxSwitch(client);
+}
+
+int
+SProcLbxBeginLargeRequest (client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxBeginLargeRequestReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->largeReqLength, n);
+ return ProcLbxBeginLargeRequest(client);
+}
+
+int
+SProcLbxLargeRequestData (client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxLargeRequestDataReq);
+
+ swaps(&stuff->length, n);
+ return ProcLbxLargeRequestData(client);
+}
+
+int
+SProcLbxEndLargeRequest (client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxEndLargeRequestReq);
+
+ swaps(&stuff->length, n);
+ return ProcLbxEndLargeRequest(client);
+}
+
+static int
+SProcLbxNewClient(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxNewClientReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->client, n);
+ return ProcLbxNewClient(client);
+}
+
+static int
+SProcLbxCloseClient(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxCloseClientReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->client, n);
+ return ProcLbxCloseClient(client);
+}
+
+static int
+SProcLbxModifySequence(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxModifySequenceReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->adjust, n);
+ return ProcLbxModifySequence(client);
+}
+
+static int
+SProcLbxAllowMotion(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxAllowMotionReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->num, n);
+ return ProcLbxAllowMotion(client);
+}
+
+static int
+SProcLbxIncrementPixel(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxIncrementPixelReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+ swapl(&stuff->pixel, n);
+ return ProcLbxIncrementPixel(client);
+}
+
+static int
+SProcLbxGrabCmap(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxGrabCmapReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+
+ return ProcLbxGrabCmap(client);
+}
+
+static int
+SProcLbxReleaseCmap(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxReleaseCmapReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+
+ return ProcLbxReleaseCmap(client);
+}
+
+static int
+SProcLbxAllocColor(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxAllocColorReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->cmap, n);
+ swapl(&stuff->pixel, n);
+ swaps(&stuff->red, n);
+ swaps(&stuff->green, n);
+ swaps(&stuff->blue, n);
+
+ return ProcLbxAllocColor(client);
+}
+
+static int
+SProcLbxGetModifierMapping(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxGetModifierMappingReq);
+
+ swaps(&stuff->length, n);
+ return ProcLbxGetModifierMapping(client);
+}
+
+static int
+SProcLbxGetKeyboardMapping(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxGetKeyboardMappingReq);
+
+ swaps(&stuff->length, n);
+ return ProcLbxGetKeyboardMapping(client);
+}
+
+static int
+SProcLbxQueryFont(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxQueryFontReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->fid, n);
+ return ProcLbxQueryFont(client);
+}
+
+static int
+SProcLbxChangeProperty(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxChangePropertyReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xLbxChangePropertyReq);
+ swapl(&stuff->window, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->nUnits, n);
+ switch (stuff->format) {
+ case 8:
+ break;
+ case 16:
+ SwapRestS(stuff);
+ break;
+ case 32:
+ SwapRestL(stuff);
+ break;
+ }
+ return ProcLbxChangeProperty(client);
+}
+
+static int
+SProcLbxGetProperty(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxGetPropertyReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->longOffset, n);
+ swapl(&stuff->longLength, n);
+ return ProcLbxGetProperty(client);
+}
+
+static int
+SProcLbxTagData(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxTagDataReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->tag, n);
+ swapl(&stuff->real_length, n);
+ return ProcLbxTagData(client);
+}
+
+static int
+SProcLbxInvalidateTag(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxInvalidateTagReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->tag, n);
+ return ProcLbxInvalidateTag(client);
+}
+
+static int
+SProcLbxPoly(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxPolyPointReq);
+ char *after;
+
+ swaps(&stuff->length, n);
+ after = ((char *) stuff) + SIZEOF(xLbxPolyPointReq);
+ if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ {
+ swapl (((Drawable *) after), n);
+ after += sizeof (Drawable);
+ }
+ if (GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ swapl (((GContext *) after), n);
+ return ProcLbxDispatch(client);
+}
+
+static int
+SProcLbxFillPoly(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxFillPolyReq);
+ char *after;
+
+ swaps(&stuff->length, n);
+ after = ((char *) stuff) + SIZEOF(xLbxFillPolyReq);
+ if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ {
+ swapl (((Drawable *) after), n);
+ after += sizeof (Drawable);
+ }
+ if (GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ swapl (((GContext *) after), n);
+ return ProcLbxFillPoly(client);
+}
+
+static int
+SProcLbxCopyArea (client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxCopyAreaReq);
+ char *after;
+
+ swaps(&stuff->length, n);
+ after = ((char *) stuff) + SIZEOF(xLbxCopyAreaReq);
+ if (GFXdCacheEnt (stuff->srcCache) == GFXCacheNone)
+ {
+ swapl (((Drawable *) after), n);
+ after += sizeof (Drawable);
+ }
+ if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ {
+ swapl (((Drawable *) after), n);
+ after += sizeof (Drawable);
+ }
+ if (GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ swapl (((GContext *) after), n);
+ return ProcLbxCopyArea(client);
+}
+
+static int
+SProcLbxCopyPlane (client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxCopyPlaneReq);
+ char *after;
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->bitPlane, n);
+ after = ((char *) stuff) + SIZEOF(xLbxCopyPlaneReq);
+ if (GFXdCacheEnt (stuff->srcCache) == GFXCacheNone)
+ {
+ swapl (((Drawable *) after), n);
+ after += sizeof (Drawable);
+ }
+ if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ {
+ swapl (((Drawable *) after), n);
+ after += sizeof (Drawable);
+ }
+ if (GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ swapl (((GContext *) after), n);
+ return ProcLbxCopyPlane(client);
+}
+
+static int
+SProcLbxPolyText(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxPolyTextReq);
+ char *after;
+
+ swaps(&stuff->length, n);
+ after = ((char *) stuff) + SIZEOF(xLbxPolyTextReq);
+ if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ {
+ swapl (((Drawable *) after), n);
+ after += sizeof (Drawable);
+ }
+ if (GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ swapl (((GContext *) after), n);
+ return ProcLbxDispatch(client);
+}
+
+static int
+SProcLbxImageText(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxImageTextReq);
+ char *after;
+
+ swaps(&stuff->length, n);
+ after = ((char *) stuff) + SIZEOF(xLbxImageTextReq);
+ if (GFXdCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ {
+ swapl (((Drawable *) after), n);
+ after += sizeof (Drawable);
+ }
+ if (GFXgCacheEnt (stuff->cacheEnts) == GFXCacheNone)
+ swapl (((GContext *) after), n);
+ return ProcLbxDispatch(client);
+}
+
+
+static int
+SProcLbxPutImage(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxPutImageReq);
+
+ swaps (&stuff->length, n);
+ return ProcLbxPutImage(client);
+}
+
+static int
+SProcLbxGetImage(client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xLbxGetImageReq);
+
+ swaps (&stuff->length, n);
+ swapl (&stuff->drawable, n);
+ swaps (&stuff->x, n);
+ swaps (&stuff->y, n);
+ swaps (&stuff->width, n);
+ swaps (&stuff->height, n);
+ swapl (&stuff->planeMask, n);
+ return ProcLbxGetImage(client);
+}
+
+static int
+SProcLbxInternAtoms(client)
+ register ClientPtr client;
+{
+ register int n;
+ char *ptr;
+ char lenbuf[2];
+ CARD16 len;
+ int i;
+
+ REQUEST(xLbxInternAtomsReq);
+
+ swaps (&stuff->length, n);
+ swaps (&stuff->num, n);
+
+ ptr = (char *) stuff + sz_xLbxInternAtomsReq;
+ for (i = 0; i < stuff->num; i++)
+ {
+ swaps (ptr, n);
+ lenbuf[0] = ptr[0];
+ lenbuf[1] = ptr[1];
+ len = *((CARD16 *) lenbuf);
+ ptr += (len + 2);
+ }
+
+ return ProcLbxInternAtoms(client);
+}
+
+
+static int
+SProcLbxGetWinAttrAndGeom(client)
+ ClientPtr client;
+{
+ int n;
+
+ REQUEST(xLbxGetWinAttrAndGeomReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->id, n);
+
+ return ProcLbxGetWinAttrAndGeom(client);
+}
+
+
+
+static int
+SProcLbxQueryExtension(client)
+ ClientPtr client;
+{
+ int n;
+
+ REQUEST(xLbxQueryExtensionReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->nbytes, n);
+ return ProcLbxQueryExtension(client);
+}
+
+int
+SProcLbxDispatch(client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_LbxQueryVersion:
+ return SProcLbxQueryVersion(client);
+ case X_LbxStartProxy:
+ return SProcLbxStartProxy(client);
+ case X_LbxStopProxy:
+ return SProcLbxStopProxy(client);
+ case X_LbxNewClient:
+ return SProcLbxNewClient(client);
+ case X_LbxCloseClient:
+ return SProcLbxCloseClient(client);
+ case X_LbxModifySequence:
+ return SProcLbxModifySequence(client);
+ case X_LbxAllowMotion:
+ return SProcLbxAllowMotion(client);
+ case X_LbxIncrementPixel:
+ return SProcLbxIncrementPixel(client);
+ case X_LbxGrabCmap:
+ return SProcLbxGrabCmap(client);
+ case X_LbxReleaseCmap:
+ return SProcLbxReleaseCmap(client);
+ case X_LbxAllocColor:
+ return SProcLbxAllocColor(client);
+ case X_LbxGetModifierMapping:
+ return SProcLbxGetModifierMapping(client);
+ case X_LbxGetKeyboardMapping:
+ return SProcLbxGetKeyboardMapping(client);
+ case X_LbxInvalidateTag:
+ return SProcLbxInvalidateTag(client);
+ case X_LbxPolyPoint:
+ case X_LbxPolyLine:
+ case X_LbxPolySegment:
+ case X_LbxPolyRectangle:
+ case X_LbxPolyArc:
+ case X_LbxPolyFillRectangle:
+ case X_LbxPolyFillArc:
+ return SProcLbxPoly(client);
+ case X_LbxFillPoly:
+ return SProcLbxFillPoly(client);
+ case X_LbxQueryFont:
+ return SProcLbxQueryFont(client);
+ case X_LbxChangeProperty:
+ return SProcLbxChangeProperty(client);
+ case X_LbxGetProperty:
+ return SProcLbxGetProperty(client);
+ case X_LbxTagData:
+ return SProcLbxTagData(client);
+ case X_LbxCopyArea:
+ return SProcLbxCopyArea(client);
+ case X_LbxCopyPlane:
+ return SProcLbxCopyPlane(client);
+ case X_LbxPolyText8:
+ case X_LbxPolyText16:
+ return SProcLbxPolyText(client);
+ case X_LbxImageText8:
+ case X_LbxImageText16:
+ return SProcLbxImageText (client);
+ case X_LbxQueryExtension:
+ return SProcLbxQueryExtension(client);
+ case X_LbxPutImage:
+ return SProcLbxPutImage(client);
+ case X_LbxGetImage:
+ return SProcLbxGetImage(client);
+ case X_LbxInternAtoms:
+ return SProcLbxInternAtoms(client);
+ case X_LbxGetWinAttrAndGeom:
+ return SProcLbxGetWinAttrAndGeom(client);
+ case X_LbxSync:
+ return ProcLbxSync(client); /* nothing to swap */
+ case X_LbxBeginLargeRequest:
+ return SProcLbxBeginLargeRequest(client);
+ case X_LbxLargeRequestData:
+ return SProcLbxLargeRequestData(client);
+ default:
+ return BadRequest;
+ }
+}
+
+#ifdef notyet
+void
+LbxWriteSConnectionInfo(pClient, size, pInfo)
+ ClientPtr pClient;
+ unsigned long size;
+ char *pInfo;
+{
+ int i, j, k;
+ ScreenPtr pScreen;
+ DepthPtr pDepth;
+ char *pInfoT, *pInfoTBase;
+ xConnSetup *pConnSetup = (xConnSetup *)pInfo;
+
+ pInfoT = pInfoTBase = (char *) ALLOCATE_LOCAL(size);
+ if (!pInfoTBase)
+ {
+ pClient->noClientException = -1;
+ return;
+ }
+ SwapConnSetup(pConnSetup, (xConnSetup *)pInfoT);
+ pInfo += sizeof(xConnSetup);
+ pInfoT += sizeof(xConnSetup);
+
+ /* Copy the vendor string */
+ i = (pConnSetup->nbytesVendor + 3) & ~3;
+ memmove(pInfoT, pInfo, i);
+ pInfo += i;
+ pInfoT += i;
+
+ /* The Pixmap formats don't need to be swapped, just copied. */
+ i = sizeof(xPixmapFormat) * screenInfo.numPixmapFormats;
+ memmove(pInfoT, pInfo, i);
+ pInfo += i;
+ pInfoT += i;
+
+ for(i = 0; i < screenInfo.numScreens; i++)
+ {
+ pScreen = screenInfo.screens[i];
+ SwapWinRoot((xWindowRoot *)pInfo, (xWindowRoot *)pInfoT);
+ pInfo += sizeof(xWindowRoot);
+ pInfoT += sizeof(xWindowRoot);
+ pDepth = pScreen->allowedDepths;
+ for(j = 0; j < pScreen->numDepths; j++, pDepth++)
+ {
+ ((xDepth *)pInfoT)->depth = ((xDepth *)pInfo)->depth;
+ cpswaps(((xDepth *)pInfo)->nVisuals, ((xDepth *)pInfoT)->nVisuals);
+ pInfo += sizeof(xDepth);
+ pInfoT += sizeof(xDepth);
+ for(k = 0; k < pDepth->numVids; k++)
+ {
+ SwapVisual((xVisualType *)pInfo, (xVisualType *)pInfoT);
+ pInfo += sizeof(xVisualType);
+ pInfoT += sizeof(xVisualType);
+ }
+ }
+ }
+ (void)WriteToClient(pClient, (int)size, (char *) pInfoTBase);
+ DEALLOCATE_LOCAL(pInfoTBase);
+}
+
+void
+SwapConnSetup(pConnSetup, pConnSetupT)
+ xConnSetup *pConnSetup, *pConnSetupT;
+{
+ cpswapl(pConnSetup->release, pConnSetupT->release);
+ cpswapl(pConnSetup->ridBase, pConnSetupT->ridBase);
+ cpswapl(pConnSetup->ridMask, pConnSetupT->ridMask);
+ cpswapl(pConnSetup->motionBufferSize, pConnSetupT->motionBufferSize);
+ cpswaps(pConnSetup->nbytesVendor, pConnSetupT->nbytesVendor);
+ cpswaps(pConnSetup->maxRequestSize, pConnSetupT->maxRequestSize);
+ pConnSetupT->minKeyCode = pConnSetup->minKeyCode;
+ pConnSetupT->maxKeyCode = pConnSetup->maxKeyCode;
+ pConnSetupT->numRoots = pConnSetup->numRoots;
+ pConnSetupT->numFormats = pConnSetup->numFormats;
+ pConnSetupT->imageByteOrder = pConnSetup->imageByteOrder;
+ pConnSetupT->bitmapBitOrder = pConnSetup->bitmapBitOrder;
+ pConnSetupT->bitmapScanlineUnit = pConnSetup->bitmapScanlineUnit;
+ pConnSetupT->bitmapScanlinePad = pConnSetup->bitmapScanlinePad;
+}
+
+void
+SwapWinRoot(pRoot, pRootT)
+ xWindowRoot *pRoot, *pRootT;
+{
+ cpswapl(pRoot->windowId, pRootT->windowId);
+ cpswapl(pRoot->defaultColormap, pRootT->defaultColormap);
+ cpswapl(pRoot->whitePixel, pRootT->whitePixel);
+ cpswapl(pRoot->blackPixel, pRootT->blackPixel);
+ cpswapl(pRoot->currentInputMask, pRootT->currentInputMask);
+ cpswaps(pRoot->pixWidth, pRootT->pixWidth);
+ cpswaps(pRoot->pixHeight, pRootT->pixHeight);
+ cpswaps(pRoot->mmWidth, pRootT->mmWidth);
+ cpswaps(pRoot->mmHeight, pRootT->mmHeight);
+ cpswaps(pRoot->minInstalledMaps, pRootT->minInstalledMaps);
+ cpswaps(pRoot->maxInstalledMaps, pRootT->maxInstalledMaps);
+ cpswapl(pRoot->rootVisualID, pRootT->rootVisualID);
+ pRootT->backingStore = pRoot->backingStore;
+ pRootT->saveUnders = pRoot->saveUnders;
+ pRootT->rootDepth = pRoot->rootDepth;
+ pRootT->nDepths = pRoot->nDepths;
+}
+
+void
+SwapVisual(pVis, pVisT)
+ xVisualType *pVis, *pVisT;
+{
+ cpswapl(pVis->visualID, pVisT->visualID);
+ pVisT->class = pVis->class;
+ pVisT->bitsPerRGB = pVis->bitsPerRGB;
+ cpswaps(pVis->colormapEntries, pVisT->colormapEntries);
+ cpswapl(pVis->redMask, pVisT->redMask);
+ cpswapl(pVis->greenMask, pVisT->greenMask);
+ cpswapl(pVis->blueMask, pVisT->blueMask);
+}
+#endif
+
+void
+LbxWriteSConnSetupPrefix(pClient, pcsp)
+ ClientPtr pClient;
+ xLbxConnSetupPrefix *pcsp;
+{
+ xLbxConnSetupPrefix cspT;
+
+ cspT.success = pcsp->success;
+ cspT.changeType = pcsp->changeType;
+ cspT.length = pcsp->length;
+ cpswaps(pcsp->majorVersion, cspT.majorVersion);
+ cpswaps(pcsp->minorVersion, cspT.minorVersion);
+ cpswapl(pcsp->tag, cspT.tag);
+
+ (void)WriteToClient(pClient, sizeof(cspT), (char *) &cspT);
+}
+
+void
+LbxSwapFontInfo(pr, compressed)
+ xLbxFontInfo *pr;
+ Bool compressed;
+{
+ unsigned i;
+ xCharInfo *pxci;
+ unsigned nchars,
+ nprops;
+ char *pby;
+ register char n;
+
+ nchars = pr->nCharInfos;
+ nprops = pr->nFontProps;
+ swaps(&pr->minCharOrByte2, n);
+ swaps(&pr->maxCharOrByte2, n);
+ swaps(&pr->defaultChar, n);
+ swaps(&pr->nFontProps, n);
+ swaps(&pr->fontAscent, n);
+ swaps(&pr->fontDescent, n);
+ SwapCharInfo(&pr->minBounds);
+ SwapCharInfo(&pr->maxBounds);
+ swapl(&pr->nCharInfos, n);
+
+ pby = (char *) &pr[1];
+ /*
+ * Font properties are an atom and either an int32 or a CARD32, so they
+ * are always 2 4 byte values
+ */
+ for (i = 0; i < nprops; i++) {
+ swapl(pby, n);
+ pby += 4;
+ swapl(pby, n);
+ pby += 4;
+ }
+ if (!compressed) {
+ pxci = (xCharInfo *) pby;
+ for (i = 0; i < nchars; i++, pxci++)
+ SwapCharInfo(pxci);
+ } else {
+ SwapLongs((CARD32 *) pby, nchars);
+ }
+}
diff --git a/xc/programs/Xserver/lbx/lbxtables.c b/xc/programs/Xserver/lbx/lbxtables.c
new file mode 100644
index 000000000..590857eca
--- /dev/null
+++ b/xc/programs/Xserver/lbx/lbxtables.c
@@ -0,0 +1,33 @@
+/* $XConsortium: lbxtables.c /main/4 1996/11/15 21:14:28 rws $ */
+/*
+ * Copyright 1993 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+extern int ProcInitialConnection();
+extern int ProcLbxEstablishConnection();
+
+int (* LbxInitialVector[3]) () =
+{
+ 0,
+ ProcInitialConnection,
+ ProcLbxEstablishConnection
+};
diff --git a/xc/programs/Xserver/lbx/lbxtags.c b/xc/programs/Xserver/lbx/lbxtags.c
new file mode 100644
index 000000000..dc7a890c8
--- /dev/null
+++ b/xc/programs/Xserver/lbx/lbxtags.c
@@ -0,0 +1,234 @@
+/* $TOG: lbxtags.c /main/13 1998/05/15 10:29:43 msr $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+All Rights Reserved.
+
+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 1993 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "X.h"
+#include "misc.h"
+#include "lbxdata.h"
+#include "resource.h"
+#include "lbxtags.h"
+#define _XLBX_SERVER_
+#include "lbxstr.h"
+#include "propertyst.h"
+
+static int tag_free();
+
+static RESTYPE TagResType;
+
+/* ARGSUSED */
+static int
+tag_free(data, id)
+ pointer data;
+ XID id;
+{
+ TagData td = (TagData) data;
+ FontTagInfoPtr ftip;
+ char *t;
+ extern int _lbx_fi_junklen;
+
+ if (td->global)
+ *(td->global) = 0;
+ /* some types need to be freed, others are shared */
+ if (td->data_type == LbxTagTypeFont) {
+ /* remove any back links */
+ ftip = (FontTagInfoPtr) td->tdata;
+ FontSetPrivate(ftip->pfont, lbx_font_private, NULL);
+ t = (char *) ftip->fontinfo;
+ if (!ftip->compression) /* points to xQueryFont, so back up to it */
+ t -= _lbx_fi_junklen;
+ xfree(t);
+ xfree(ftip);
+ }
+ xfree(data);
+ return 0;
+}
+
+TagInit()
+{
+ TagResType = CreateNewResourceType(tag_free);
+}
+
+XID
+TagNewTag()
+{
+ return FakeClientID(0);
+}
+
+void
+TagClearProxy(tid, pid)
+ XID tid;
+ int pid;
+{
+ TagData td;
+
+ td = (TagData) LookupIDByType(tid, TagResType);
+ if (td)
+ td->sent_to_proxy[pid >> 3] &= ~(1 << (pid & 7));
+}
+
+void
+TagMarkProxy(tid, pid)
+ XID tid;
+ int pid;
+{
+ TagData td;
+
+ td = (TagData) LookupIDByType(tid, TagResType);
+ td->sent_to_proxy[pid >> 3] |= 1 << (pid & 7);
+}
+
+Bool
+TagProxyMarked(tid, pid)
+ XID tid;
+ int pid;
+{
+ TagData td;
+
+ td = (TagData) LookupIDByType(tid, TagResType);
+ return (td->sent_to_proxy[pid >> 3] & (1 << (pid & 7))) != 0;
+}
+
+XID
+TagSaveTag(dtype, size, data, global)
+ int dtype;
+ int size;
+ pointer data;
+ XID *global;
+{
+ TagData td;
+
+ td = (TagData) xalloc(sizeof(TagDataRec));
+ if (!td) {
+ if (global)
+ *global = 0;
+ return 0;
+ }
+ bzero((char *) td->sent_to_proxy, (MAX_NUM_PROXIES + 7) / 8);
+ td->tid = TagNewTag();
+ td->data_type = dtype;
+ td->tdata = data;
+ td->size = size;
+ td->global = global;
+ if (!AddResource(td->tid, TagResType, (pointer) td))
+ return 0;
+ if (global)
+ *global = td->tid;
+ return td->tid;
+}
+
+void
+TagDeleteTag(tid)
+ XID tid;
+{
+ int pid;
+ TagData td;
+ LbxProxyPtr proxy;
+ ClientPtr client;
+ LbxClientPtr lbxcp;
+
+ td = (TagData) LookupIDByType(tid, TagResType);
+ if (!td) /* shouldn't happen, but play it safe */
+ return;
+ for (pid = 1; pid < MAX_NUM_PROXIES; pid++) {
+ if (td->sent_to_proxy[pid >> 3] & (1 << (pid & 7))) {
+ proxy = LbxPidToProxy(pid);
+ lbxcp = (proxy != NULL) ? proxy->lbxClients[0] : NULL;
+ if (lbxcp && (client = lbxcp->client))
+ LbxSendInvalidateTag(client, tid, td->data_type);
+ td->sent_to_proxy[pid >> 3] &= ~(1 << (pid & 7));
+ }
+ }
+ if (td->data_type != LbxTagTypeProperty || !LbxFlushQTag(tid))
+ FreeResource(tid, 0);
+ else if (td->global) {
+ *(td->global) = 0;
+ td->global = NULL;
+ }
+}
+
+TagData
+TagGetTag(tid)
+ XID tid;
+{
+ TagData td;
+
+ td = (TagData) LookupIDByType(tid, TagResType);
+ return td;
+}
+
+static void
+LbxFlushTag(value, tid, cdata)
+ pointer value;
+ XID tid;
+ pointer cdata;
+{
+ TagData td = (TagData)value;
+ LbxProxyPtr proxy = (LbxProxyPtr)cdata;
+ int i;
+
+ if ((td->data_type == LbxTagTypeProperty) && td->global) {
+ PropertyPtr pProp = (PropertyPtr)td->tdata;
+ if ((pProp->tag_id == tid) && (pProp->owner_pid == proxy->pid)) {
+ LbxFlushQTag(tid);
+ pProp->size = 0;
+ FreeResource(tid, 0);
+ return;
+ }
+ }
+ td->sent_to_proxy[proxy->pid >> 3] &= ~(1 << (proxy->pid & 7));
+ for (i = 0; i < (MAX_NUM_PROXIES + 7) / 8; i++) {
+ if (td->sent_to_proxy[i])
+ return;
+ }
+ FreeResource(tid, 0);
+}
+
+/*
+ * clear out markers for proxies
+ */
+LbxFlushTags(proxy)
+ LbxProxyPtr proxy;
+{
+ FindClientResourcesByType(NULL, TagResType, LbxFlushTag, (pointer)proxy);
+}
diff --git a/xc/programs/Xserver/lbx/lbxtags.h b/xc/programs/Xserver/lbx/lbxtags.h
new file mode 100644
index 000000000..b76e9a646
--- /dev/null
+++ b/xc/programs/Xserver/lbx/lbxtags.h
@@ -0,0 +1,115 @@
+/* $TOG: lbxtags.h /main/8 1998/02/09 14:33:05 kaleb $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+All Rights Reserved.
+
+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 1993 Network Computing Devices, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name Network Computing Devices, Inc. not be
+ * used in advertising or publicity pertaining to distribution of this
+ * software without specific, written prior permission.
+ *
+ * THIS SOFTWARE IS PROVIDED `AS-IS'. NETWORK COMPUTING DEVICES, INC.,
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT
+ * LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NONINFRINGEMENT. IN NO EVENT SHALL NETWORK
+ * COMPUTING DEVICES, INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING
+ * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA,
+ * OR PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS OF
+ * WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef _LBXTAGS_H_
+#define _LBXTAGS_H_
+#include "lbxserve.h"
+
+#include "os.h"
+#include "opaque.h"
+#include "resource.h"
+#include "X.h"
+#include "Xproto.h"
+
+typedef struct _tagdata {
+ XID tid;
+ short data_type;
+ unsigned char sent_to_proxy[(MAX_NUM_PROXIES + 7) / 8];
+ int size;
+ pointer tdata;
+ XID *global;
+} TagDataRec;
+
+typedef struct _tagdata *TagData;
+
+extern TagData TagGetTag(
+#if NeedFunctionPrototypes
+ XID /*tid*/
+#endif
+);
+
+extern XID TagNewTag(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void TagClearProxy(
+#if NeedFunctionPrototypes
+ XID /*tid*/,
+ int /*pid*/
+#endif
+);
+
+extern void TagMarkProxy(
+#if NeedFunctionPrototypes
+ XID /*tid*/,
+ int /*pid*/
+#endif
+);
+
+extern Bool TagProxyMarked(
+#if NeedFunctionPrototypes
+ XID /*tid*/,
+ int /*pid*/
+#endif
+);
+
+extern void TagDeleteTag(
+#if NeedFunctionPrototypes
+ XID /*tid*/
+#endif
+);
+
+extern XID TagSaveTag(
+#if NeedFunctionPrototypes
+ int /*dtype*/,
+ int /*size*/,
+ pointer /*data*/,
+ XID* /*global*/
+#endif
+);
+
+#endif /* _LBXTAGS_H_ */
diff --git a/xc/programs/Xserver/lbx/lbxzerorep.c b/xc/programs/Xserver/lbx/lbxzerorep.c
new file mode 100644
index 000000000..335d4e575
--- /dev/null
+++ b/xc/programs/Xserver/lbx/lbxzerorep.c
@@ -0,0 +1,412 @@
+/* $TOG: lbxzerorep.c /main/3 1998/02/09 14:33:09 kaleb $ */
+
+/*
+
+Copyright 1996, 1998 The Open Group
+
+All Rights Reserved.
+
+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 module handles zeroing out unused pad bytes in core X replies.
+ * This will hopefully improve both stream and delta compression,
+ * since we are removing the random values in pad bytes.
+ */
+
+#define NEED_REPLIES
+#include "X.h"
+#include <X11/Xproto.h>
+
+
+ZeroReplyPadBytes (buf, reqType)
+ char *buf;
+ int reqType;
+{
+ switch (reqType) {
+ case X_GetWindowAttributes:
+ {
+ xGetWindowAttributesReply *reply = (xGetWindowAttributesReply *) buf;
+ reply->pad = 0;
+ break;
+ }
+ case X_GetGeometry:
+ {
+ xGetGeometryReply *reply = (xGetGeometryReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ break;
+ }
+ case X_QueryTree:
+ {
+ xQueryTreeReply *reply = (xQueryTreeReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ break;
+ }
+ case X_InternAtom:
+ {
+ xInternAtomReply *reply = (xInternAtomReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ break;
+ }
+ case X_GetAtomName:
+ {
+ xGetAtomNameReply *reply = (xGetAtomNameReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_GetProperty:
+ {
+ xGetPropertyReply *reply = (xGetPropertyReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ break;
+ }
+ case X_ListProperties:
+ {
+ xListPropertiesReply *reply = (xListPropertiesReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_GetSelectionOwner:
+ {
+ xGetSelectionOwnerReply *reply = (xGetSelectionOwnerReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ break;
+ }
+ case X_GrabKeyboard:
+ case X_GrabPointer:
+ {
+ xGrabKeyboardReply *reply = (xGrabKeyboardReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ break;
+ }
+ case X_QueryPointer:
+ {
+ xQueryPointerReply *reply = (xQueryPointerReply *) buf;
+ reply->pad1 = 0;
+ reply->pad = 0;
+ break;
+ }
+ case X_GetMotionEvents:
+ {
+ xGetMotionEventsReply *reply = (xGetMotionEventsReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ break;
+ }
+ case X_TranslateCoords:
+ {
+ xTranslateCoordsReply *reply = (xTranslateCoordsReply *) buf;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ break;
+ }
+ case X_GetInputFocus:
+ {
+ xGetInputFocusReply *reply = (xGetInputFocusReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ break;
+ }
+ case X_QueryKeymap:
+ {
+ xQueryKeymapReply *reply = (xQueryKeymapReply *) buf;
+ reply->pad1 = 0;
+ break;
+ }
+ case X_QueryFont:
+ {
+ xQueryFontReply *reply = (xQueryFontReply *) buf;
+ reply->pad1 = 0;
+ break;
+ }
+ case X_QueryTextExtents:
+ {
+ xQueryTextExtentsReply *reply = (xQueryTextExtentsReply *) buf;
+ reply->pad = 0;
+ break;
+ }
+ case X_ListFonts:
+ {
+ xListFontsReply *reply = (xListFontsReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_GetFontPath:
+ {
+ xGetFontPathReply *reply = (xGetFontPathReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_GetImage:
+ {
+ xGetImageReply *reply = (xGetImageReply *) buf;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_ListInstalledColormaps:
+ {
+ xListInstalledColormapsReply *reply =
+ (xListInstalledColormapsReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_AllocColor:
+ {
+ xAllocColorReply *reply = (xAllocColorReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ break;
+ }
+ case X_AllocNamedColor:
+ {
+ xAllocNamedColorReply *reply = (xAllocNamedColorReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ break;
+ }
+ case X_AllocColorCells:
+ {
+ xAllocColorCellsReply *reply = (xAllocColorCellsReply *) buf;
+ reply->pad1 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_AllocColorPlanes:
+ {
+ xAllocColorPlanesReply *reply = (xAllocColorPlanesReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ break;
+ }
+ case X_QueryColors:
+ {
+ xQueryColorsReply *reply = (xQueryColorsReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_LookupColor:
+ {
+ xLookupColorReply *reply = (xLookupColorReply *) buf;
+ reply->pad1 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ break;
+ }
+ case X_QueryBestSize:
+ {
+ xQueryBestSizeReply *reply = (xQueryBestSizeReply *) buf;
+ reply->pad1 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_QueryExtension:
+ {
+ xQueryExtensionReply *reply = (xQueryExtensionReply *) buf;
+ reply->pad1 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_ListExtensions:
+ {
+ xListExtensionsReply *reply = (xListExtensionsReply *) buf;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_SetPointerMapping:
+ case X_SetModifierMapping:
+ {
+ xSetMappingReply *reply = (xSetMappingReply *) buf;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_GetPointerMapping:
+ {
+ xGetPointerMappingReply *reply = (xGetPointerMappingReply *) buf;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_GetKeyboardMapping:
+ {
+ xGetKeyboardMappingReply *reply = (xGetKeyboardMappingReply *) buf;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ case X_GetModifierMapping:
+ {
+ xGetModifierMappingReply *reply = (xGetModifierMappingReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ break;
+ }
+ case X_GetKeyboardControl:
+ {
+ xGetKeyboardControlReply *reply = (xGetKeyboardControlReply *) buf;
+ reply->pad = 0;
+ break;
+ }
+ case X_GetPointerControl:
+ {
+ xGetPointerControlReply *reply = (xGetPointerControlReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ break;
+ }
+ case X_GetScreenSaver:
+ {
+ xGetScreenSaverReply *reply = (xGetScreenSaverReply *) buf;
+ reply->pad1 = 0;
+ reply->pad2 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ break;
+ }
+ case X_ListHosts:
+ {
+ xListHostsReply *reply = (xListHostsReply *) buf;
+ reply->pad1 = 0;
+ reply->pad3 = 0;
+ reply->pad4 = 0;
+ reply->pad5 = 0;
+ reply->pad6 = 0;
+ reply->pad7 = 0;
+ break;
+ }
+ }
+}
diff --git a/xc/programs/Xserver/mfb/Imakefile b/xc/programs/Xserver/mfb/Imakefile
new file mode 100644
index 000000000..ff79fed67
--- /dev/null
+++ b/xc/programs/Xserver/mfb/Imakefile
@@ -0,0 +1,111 @@
+XCOMM $TOG: Imakefile /main/43 1997/11/15 12:10:58 msr $
+XCOMM $XFree86: xc/programs/Xserver/mfb/Imakefile,v 3.14 1999/08/14 10:50:19 dawes Exp $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#ifdef XFree86Version
+#if DoLoadableServer
+XF86INCL = -I$(XF86COMSRC) -I$(XF86SRC)
+XFMODSRC = mfbmodule.c
+XFMODOBJ = mfbmodule.o
+#endif
+#endif
+
+#if BuildLowMem
+DEFINES=-ULOWMEMFTPT
+#endif
+
+SRCS1 = mfbgc.c mfbwindow.c mfbfont.c \
+ mfbfillrct.c mfbpntwin.c maskbits.c mfbpixmap.c \
+ mfbimage.c mfbline.c mfbbres.c mfbhrzvert.c mfbbresd.c \
+ mfbpushpxl.c mfbzerarc.c mfbfillarc.c \
+ mfbfillsp.c mfbsetsp.c mfbscrinit.c mfbscrclse.c mfbclip.c \
+ mfbbitblt.c mfbgetsp.c mfbpolypnt.c \
+ mfbbltC.c mfbbltX.c mfbbltCI.c mfbbltO.c mfbbltG.c \
+ mfbcmap.c mfbtileC.c mfbtileG.c mfbmisc.c mfbbstore.c $(XFMODSRC)
+
+SRCS = $(SRCS1) mfbseg.c mfbpgbwht.c mfbpgbblak.c mfbpgbinv.c mfbigbwht.c \
+ mfbigbblak.c mfbpawhite.c mfbpablack.c mfbpainv.c mfbtewhite.c \
+ mfbteblack.c mfbbltC.c mfbbltX.c mfbbltCI.c mfbbltO.c mfbbltG.c \
+ mfbtileC.c mfbtileG.c mfbplywhite.c mfbplyblack.c mfbplyinv.c
+
+OBJS = mfbgc.o mfbwindow.o mfbfont.o \
+ mfbfillrct.o mfbpntwin.o maskbits.o mfbpixmap.o \
+ mfbimage.o mfbline.o mfbbres.o mfbhrzvert.o mfbbresd.o mfbseg.o \
+ mfbpushpxl.o mfbzerarc.o mfbfillarc.o \
+ mfbfillsp.o mfbsetsp.o mfbscrinit.o mfbscrclse.o mfbclip.o \
+ mfbbitblt.o mfbgetsp.o mfbpolypnt.o \
+ mfbbltC.o mfbbltX.o mfbbltCI.o mfbbltO.o mfbbltG.o \
+ mfbpgbwht.o mfbpgbblak.o mfbpgbinv.o \
+ mfbigbwht.o mfbigbblak.o mfbcmap.o \
+ mfbpawhite.o mfbpablack.o mfbpainv.o mfbtileC.o mfbtileG.o \
+ mfbtewhite.o mfbteblack.o mfbmisc.o mfbbstore.o \
+ mfbplywhite.o mfbplyblack.o mfbplyinv.o $(XFMODOBJ)
+
+INCLUDES = -I. -I../mi -I../include -I$(XINCLUDESRC) -I$(FONTINCSRC) $(XF86INCL)
+LINTDEFS = -DMFBPOLYGLYPHBLT=mfbPolyGlyphBltWhite \
+ -DMFBIMAGEGLYPHBLT=mfbImageGlyphBltWhite \
+ -DEQWHOLEWORD=MFB_EQWHOLEWORD_WHITE -DOPEQ=MFB_OPEQ_WHITE
+
+LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln ../mi/llib-lmi.ln
+
+ModuleObjectRule()
+LibraryModuleTarget(mfb,$(OBJS))
+
+LintLibraryTarget(mfb,$(SRCS1))
+NormalLintTarget($(LINTDEFS) $(SRCS1))
+
+ObjectFromSpecialSource(mfbseg,mfbline,-DPOLYSEGMENT)
+
+ObjectFromSpecialSource(mfbpgbwht,mfbplygblt,-DMFBPOLYGLYPHBLT=mfbPolyGlyphBltWhite -DOPEQ=MFB_OPEQ_WHITE)
+
+ObjectFromSpecialSource(mfbpgbblak,mfbplygblt,-DMFBPOLYGLYPHBLT=mfbPolyGlyphBltBlack -DOPEQ=MFB_OPEQ_BLACK)
+
+ObjectFromSpecialSource(mfbpgbinv,mfbplygblt,-DMFBPOLYGLYPHBLT=mfbPolyGlyphBltInvert -DOPEQ=MFB_OPEQ_INVERT)
+
+ObjectFromSpecialSource(mfbigbwht,mfbimggblt,-DMFBIMAGEGLYPHBLT=mfbImageGlyphBltWhite -DOPEQ=MFB_OPEQ_WHITE)
+
+ObjectFromSpecialSource(mfbigbblak,mfbimggblt,-DMFBIMAGEGLYPHBLT=mfbImageGlyphBltBlack -DOPEQ=MFB_OPEQ_BLACK)
+
+ObjectFromSpecialSource(mfbpawhite,mfbpntarea,-DMFBSOLIDFILLAREA=mfbSolidWhiteArea -DMFBSTIPPLEFILLAREA=mfbStippleWhiteArea -DOPEQ=MFB_OPEQ_WHITE -DEQWHOLEWORD=MFB_EQWHOLEWORD_WHITE)
+
+ObjectFromSpecialSource(mfbpablack,mfbpntarea,-DMFBSOLIDFILLAREA=mfbSolidBlackArea -DMFBSTIPPLEFILLAREA=mfbStippleBlackArea -DOPEQ=MFB_OPEQ_BLACK -DEQWHOLEWORD=MFB_EQWHOLEWORD_BLACK)
+
+ObjectFromSpecialSource(mfbpainv,mfbpntarea,-DMFBSOLIDFILLAREA=mfbSolidInvertArea -DMFBSTIPPLEFILLAREA=mfbStippleInvertArea -DOPEQ=MFB_OPEQ_INVERT -DEQWHOLEWORD=MFB_EQWHOLEWORD_INVERT)
+
+ObjectFromSpecialSource(mfbtewhite,mfbtegblt,-DMFBTEGLYPHBLT=mfbTEGlyphBltWhite -DOP=MFB_OP_WHITE -DCLIPTETEXT=mfbImageGlyphBltWhite)
+
+ObjectFromSpecialSource(mfbteblack,mfbtegblt,-DMFBTEGLYPHBLT=mfbTEGlyphBltBlack -DOP=MFB_OP_BLACK -DCLIPTETEXT=mfbImageGlyphBltBlack)
+
+ObjectFromSpecialSource(mfbplywhite,mfbply1rct,-DMFBFILLPOLY1RECT=mfbFillPolyWhite -DOPEQ=MFB_OPEQ_WHITE -DEQWHOLEWORD=MFB_EQWHOLEWORD_WHITE)
+
+ObjectFromSpecialSource(mfbplyblack,mfbply1rct,-DMFBFILLPOLY1RECT=mfbFillPolyBlack -DOPEQ=MFB_OPEQ_BLACK -DEQWHOLEWORD=MFB_EQWHOLEWORD_BLACK)
+
+ObjectFromSpecialSource(mfbplyinv,mfbply1rct,-DMFBFILLPOLY1RECT=mfbFillPolyInvert -DOPEQ=MFB_OPEQ_INVERT -DEQWHOLEWORD=MFB_EQWHOLEWORD_INVERT)
+
+ObjectFromSpecialSource(mfbbltC,mfbblt,-DMROP=Mcopy)
+
+ObjectFromSpecialSource(mfbbltX,mfbblt,-DMROP=Mxor)
+
+ObjectFromSpecialSource(mfbbltCI,mfbblt,-DMROP=McopyInverted)
+
+ObjectFromSpecialSource(mfbbltO,mfbblt,-DMROP=Mor)
+
+ObjectFromSpecialSource(mfbbltG,mfbblt,-DMROP=0)
+
+ObjectFromSpecialSource(mfbtileC,mfbtile,-DMROP=Mcopy)
+
+ObjectFromSpecialSource(mfbtileG,mfbtile,-DMROP=0)
+
+SpecialCObjectRule(mfbpixmap,$(ICONFIGFILES),$(_NOOP_))
+
+InstallLibraryModule(mfb,$(MODULEDIR),.)
+
+#ifndef OS2Architecture
+DependTarget()
+#endif
+
+InstallDriverSDKLibraryModule(mfb,$(DRIVERSDKMODULEDIR),.)
+
+InstallDriverSDKNonExecFile(mfb.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/xc/programs/Xserver/mfb/fastblt.h b/xc/programs/Xserver/mfb/fastblt.h
new file mode 100644
index 000000000..58f373ef5
--- /dev/null
+++ b/xc/programs/Xserver/mfb/fastblt.h
@@ -0,0 +1,114 @@
+/* $TOG: fastblt.h /main/8 1998/02/09 14:37:36 kaleb $ */
+/*
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+
+/*
+ * Fast bitblt macros for certain hardware. If your machine has an addressing
+ * mode of small constant + register, you'll probably want this magic specific
+ * code. It's 25% faster for the R2000. I haven't studied the Sparc
+ * instruction set, but I suspect it also has this addressing mode. Also,
+ * unrolling the loop by 32 is possibly excessive for mfb. The number of times
+ * the loop is actually looped through is pretty small.
+ */
+
+/*
+ * WARNING: These macros make *a lot* of assumptions about
+ * the environment they are invoked in. Plenty of implicit
+ * arguments, lots of side effects. Don't use them casually.
+ */
+
+#define SwitchOdd(n) case n: BodyOdd(n)
+#define SwitchEven(n) case n: BodyEven(n)
+
+/* to allow mfb and cfb to share code... */
+#ifndef BitRight
+#define BitRight(a,b) SCRRIGHT(a,b)
+#define BitLeft(a,b) SCRLEFT(a,b)
+#endif
+
+#ifdef LARGE_INSTRUCTION_CACHE
+#define UNROLL 8
+#define PackedLoop \
+ switch (nl & (UNROLL-1)) { \
+ SwitchOdd( 7) SwitchEven( 6) SwitchOdd( 5) SwitchEven( 4) \
+ SwitchOdd( 3) SwitchEven( 2) SwitchOdd( 1) \
+ } \
+ while ((nl -= UNROLL) >= 0) { \
+ LoopReset \
+ BodyEven( 8) \
+ BodyOdd( 7) BodyEven( 6) BodyOdd( 5) BodyEven( 4) \
+ BodyOdd( 3) BodyEven( 2) BodyOdd( 1) \
+ }
+#else
+#define UNROLL 4
+#define PackedLoop \
+ switch (nl & (UNROLL-1)) { \
+ SwitchOdd( 3) SwitchEven( 2) SwitchOdd( 1) \
+ } \
+ while ((nl -= UNROLL) >= 0) { \
+ LoopReset \
+ BodyEven( 4) \
+ BodyOdd( 3) BodyEven( 2) BodyOdd( 1) \
+ }
+#endif
+
+#if PPW == 32
+#define DuffL(counter,label,body) \
+ switch (counter & 3) { \
+ label: \
+ body \
+ case 3: \
+ body \
+ case 2: \
+ body \
+ case 1: \
+ body \
+ case 0: \
+ if ((counter -= 4) >= 0) \
+ goto label; \
+ }
+#else /* PPW == 64 */
+#define DuffL(counter,label,body) \
+ switch (counter & 7) { \
+ label: \
+ body \
+ case 7: \
+ body \
+ case 6: \
+ body \
+ case 5: \
+ body \
+ case 4: \
+ body \
+ case 3: \
+ body \
+ case 2: \
+ body \
+ case 1: \
+ body \
+ case 0: \
+ if ((counter -= 8) >= 0) \
+ goto label; \
+ }
+#endif /* PPW */
diff --git a/xc/programs/Xserver/mfb/maskbits.c b/xc/programs/Xserver/mfb/maskbits.c
new file mode 100644
index 000000000..f5c875285
--- /dev/null
+++ b/xc/programs/Xserver/mfb/maskbits.c
@@ -0,0 +1,9868 @@
+/* $TOG: maskbits.c /main/18 1998/02/09 14:37:41 kaleb $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/*
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/mfb/maskbits.c,v 1.3 1999/04/11 13:11:10 dawes Exp $ */
+
+#include "maskbits.h"
+#include "servermd.h"
+
+/*
+these tables are used by several macros in the mfb code.
+
+ the vax numbers everything left to right, so bit indices on the
+screen match bit indices in longwords. the pc-rt and Sun number
+bits on the screen the way they would be written on paper,
+(i.e. msb to the left), and so a bit index n on the screen is
+bit index PPW-n in a longword
+
+ see also maskbits.h
+*/
+
+#if (BITMAP_BIT_ORDER == MSBFirst)
+/* NOTE:
+the first element in starttab could be 0xffffffff. making it 0
+lets us deal with a full first word in the middle loop, rather
+than having to do the multiple reads and masks that we'd
+have to do if we thought it was partial.
+*/
+PixelType starttab[PPW+1] =
+ {
+ LONG2CHARS( 0x00000000 ),
+#if PPW == 64
+ LONG2CHARS( 0x7FFFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x07FFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x03FFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x01FFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x00FFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x007FFFFFFFFFFFFF ),
+ LONG2CHARS( 0x003FFFFFFFFFFFFF ),
+ LONG2CHARS( 0x001FFFFFFFFFFFFF ),
+ LONG2CHARS( 0x000FFFFFFFFFFFFF ),
+ LONG2CHARS( 0x0007FFFFFFFFFFFF ),
+ LONG2CHARS( 0x0003FFFFFFFFFFFF ),
+ LONG2CHARS( 0x0001FFFFFFFFFFFF ),
+ LONG2CHARS( 0x0000FFFFFFFFFFFF ),
+ LONG2CHARS( 0x00007FFFFFFFFFFF ),
+ LONG2CHARS( 0x00003FFFFFFFFFFF ),
+ LONG2CHARS( 0x00001FFFFFFFFFFF ),
+ LONG2CHARS( 0x00000FFFFFFFFFFF ),
+ LONG2CHARS( 0x000007FFFFFFFFFF ),
+ LONG2CHARS( 0x000003FFFFFFFFFF ),
+ LONG2CHARS( 0x000001FFFFFFFFFF ),
+ LONG2CHARS( 0x000000FFFFFFFFFF ),
+ LONG2CHARS( 0x0000007FFFFFFFFF ),
+ LONG2CHARS( 0x0000003FFFFFFFFF ),
+ LONG2CHARS( 0x0000001FFFFFFFFF ),
+ LONG2CHARS( 0x0000000FFFFFFFFF ),
+ LONG2CHARS( 0x00000007FFFFFFFF ),
+ LONG2CHARS( 0x00000003FFFFFFFF ),
+ LONG2CHARS( 0x00000001FFFFFFFF ),
+ LONG2CHARS( 0x00000000FFFFFFFF ),
+#endif /* PPW == 64 */
+ LONG2CHARS( 0x7FFFFFFF ),
+ LONG2CHARS( 0x3FFFFFFF ),
+ LONG2CHARS( 0x1FFFFFFF ),
+ LONG2CHARS( 0x0FFFFFFF ),
+ LONG2CHARS( 0x07FFFFFF ),
+ LONG2CHARS( 0x03FFFFFF ),
+ LONG2CHARS( 0x01FFFFFF ),
+ LONG2CHARS( 0x00FFFFFF ),
+ LONG2CHARS( 0x007FFFFF ),
+ LONG2CHARS( 0x003FFFFF ),
+ LONG2CHARS( 0x001FFFFF ),
+ LONG2CHARS( 0x000FFFFF ),
+ LONG2CHARS( 0x0007FFFF ),
+ LONG2CHARS( 0x0003FFFF ),
+ LONG2CHARS( 0x0001FFFF ),
+ LONG2CHARS( 0x0000FFFF ),
+ LONG2CHARS( 0x00007FFF ),
+ LONG2CHARS( 0x00003FFF ),
+ LONG2CHARS( 0x00001FFF ),
+ LONG2CHARS( 0x00000FFF ),
+ LONG2CHARS( 0x000007FF ),
+ LONG2CHARS( 0x000003FF ),
+ LONG2CHARS( 0x000001FF ),
+ LONG2CHARS( 0x000000FF ),
+ LONG2CHARS( 0x0000007F ),
+ LONG2CHARS( 0x0000003F ),
+ LONG2CHARS( 0x0000001F ),
+ LONG2CHARS( 0x0000000F ),
+ LONG2CHARS( 0x00000007 ),
+ LONG2CHARS( 0x00000003 ),
+ LONG2CHARS( 0x00000001 ),
+ LONG2CHARS( 0x00000000 )
+ };
+
+PixelType endtab[PPW+1] =
+ {
+#if PPW == 32
+ LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x80000000 ),
+ LONG2CHARS( 0xC0000000 ),
+ LONG2CHARS( 0xE0000000 ),
+ LONG2CHARS( 0xF0000000 ),
+ LONG2CHARS( 0xF8000000 ),
+ LONG2CHARS( 0xFC000000 ),
+ LONG2CHARS( 0xFE000000 ),
+ LONG2CHARS( 0xFF000000 ),
+ LONG2CHARS( 0xFF800000 ),
+ LONG2CHARS( 0xFFC00000 ),
+ LONG2CHARS( 0xFFE00000 ),
+ LONG2CHARS( 0xFFF00000 ),
+ LONG2CHARS( 0xFFF80000 ),
+ LONG2CHARS( 0xFFFC0000 ),
+ LONG2CHARS( 0xFFFE0000 ),
+ LONG2CHARS( 0xFFFF0000 ),
+ LONG2CHARS( 0xFFFF8000 ),
+ LONG2CHARS( 0xFFFFC000 ),
+ LONG2CHARS( 0xFFFFE000 ),
+ LONG2CHARS( 0xFFFFF000 ),
+ LONG2CHARS( 0xFFFFF800 ),
+ LONG2CHARS( 0xFFFFFC00 ),
+ LONG2CHARS( 0xFFFFFE00 ),
+ LONG2CHARS( 0xFFFFFF00 ),
+ LONG2CHARS( 0xFFFFFF80 ),
+ LONG2CHARS( 0xFFFFFFC0 ),
+ LONG2CHARS( 0xFFFFFFE0 ),
+ LONG2CHARS( 0xFFFFFFF0 ),
+ LONG2CHARS( 0xFFFFFFF8 ),
+ LONG2CHARS( 0xFFFFFFFC ),
+ LONG2CHARS( 0xFFFFFFFE ),
+ LONG2CHARS( 0xFFFFFFFF )
+#else /* PPW */
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x8000000000000000 ),
+ LONG2CHARS( 0xC000000000000000 ),
+ LONG2CHARS( 0xE000000000000000 ),
+ LONG2CHARS( 0xF000000000000000 ),
+ LONG2CHARS( 0xF800000000000000 ),
+ LONG2CHARS( 0xFC00000000000000 ),
+ LONG2CHARS( 0xFE00000000000000 ),
+ LONG2CHARS( 0xFF00000000000000 ),
+ LONG2CHARS( 0xFF80000000000000 ),
+ LONG2CHARS( 0xFFC0000000000000 ),
+ LONG2CHARS( 0xFFE0000000000000 ),
+ LONG2CHARS( 0xFFF0000000000000 ),
+ LONG2CHARS( 0xFFF8000000000000 ),
+ LONG2CHARS( 0xFFFC000000000000 ),
+ LONG2CHARS( 0xFFFE000000000000 ),
+ LONG2CHARS( 0xFFFF000000000000 ),
+ LONG2CHARS( 0xFFFF800000000000 ),
+ LONG2CHARS( 0xFFFFC00000000000 ),
+ LONG2CHARS( 0xFFFFE00000000000 ),
+ LONG2CHARS( 0xFFFFF00000000000 ),
+ LONG2CHARS( 0xFFFFF80000000000 ),
+ LONG2CHARS( 0xFFFFFC0000000000 ),
+ LONG2CHARS( 0xFFFFFE0000000000 ),
+ LONG2CHARS( 0xFFFFFF0000000000 ),
+ LONG2CHARS( 0xFFFFFF8000000000 ),
+ LONG2CHARS( 0xFFFFFFC000000000 ),
+ LONG2CHARS( 0xFFFFFFE000000000 ),
+ LONG2CHARS( 0xFFFFFFF000000000 ),
+ LONG2CHARS( 0xFFFFFFF800000000 ),
+ LONG2CHARS( 0xFFFFFFFC00000000 ),
+ LONG2CHARS( 0xFFFFFFFE00000000 ),
+ LONG2CHARS( 0xFFFFFFFF00000000 ),
+ LONG2CHARS( 0xFFFFFFFF80000000 ),
+ LONG2CHARS( 0xFFFFFFFFC0000000 ),
+ LONG2CHARS( 0xFFFFFFFFE0000000 ),
+ LONG2CHARS( 0xFFFFFFFFF0000000 ),
+ LONG2CHARS( 0xFFFFFFFFF8000000 ),
+ LONG2CHARS( 0xFFFFFFFFFC000000 ),
+ LONG2CHARS( 0xFFFFFFFFFE000000 ),
+ LONG2CHARS( 0xFFFFFFFFFF000000 ),
+ LONG2CHARS( 0xFFFFFFFFFF800000 ),
+ LONG2CHARS( 0xFFFFFFFFFFC00000 ),
+ LONG2CHARS( 0xFFFFFFFFFFE00000 ),
+ LONG2CHARS( 0xFFFFFFFFFFF00000 ),
+ LONG2CHARS( 0xFFFFFFFFFFF80000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFC0000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFE0000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFF0000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFF8000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFC000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFE000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFF000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFF800 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFC00 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFE00 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFF00 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFF80 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFFC ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFFE ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFFF )
+#endif /* PPW */
+ };
+
+#ifndef LOWMEMFTPT
+
+#ifdef NEED_OLD_MFB_MASKS
+/* a hack, for now, since the entries for 0 need to be all
+ 1 bits, not all zeros.
+ this means the code DOES NOT WORK for segments of length
+ 0 (which is only a problem in the horizontal line code.)
+*/
+PixelType startpartial[33] =
+ {
+ LONG2CHARS( 0xFFFFFFFF ),
+ LONG2CHARS( 0x7FFFFFFF ),
+ LONG2CHARS( 0x3FFFFFFF ),
+ LONG2CHARS( 0x1FFFFFFF ),
+ LONG2CHARS( 0x0FFFFFFF ),
+ LONG2CHARS( 0x07FFFFFF ),
+ LONG2CHARS( 0x03FFFFFF ),
+ LONG2CHARS( 0x01FFFFFF ),
+ LONG2CHARS( 0x00FFFFFF ),
+ LONG2CHARS( 0x007FFFFF ),
+ LONG2CHARS( 0x003FFFFF ),
+ LONG2CHARS( 0x001FFFFF ),
+ LONG2CHARS( 0x000FFFFF ),
+ LONG2CHARS( 0x0007FFFF ),
+ LONG2CHARS( 0x0003FFFF ),
+ LONG2CHARS( 0x0001FFFF ),
+ LONG2CHARS( 0x0000FFFF ),
+ LONG2CHARS( 0x00007FFF ),
+ LONG2CHARS( 0x00003FFF ),
+ LONG2CHARS( 0x00001FFF ),
+ LONG2CHARS( 0x00000FFF ),
+ LONG2CHARS( 0x000007FF ),
+ LONG2CHARS( 0x000003FF ),
+ LONG2CHARS( 0x000001FF ),
+ LONG2CHARS( 0x000000FF ),
+ LONG2CHARS( 0x0000007F ),
+ LONG2CHARS( 0x0000003F ),
+ LONG2CHARS( 0x0000001F ),
+ LONG2CHARS( 0x0000000F ),
+ LONG2CHARS( 0x00000007 ),
+ LONG2CHARS( 0x00000003 ),
+ LONG2CHARS( 0x00000001 ),
+ LONG2CHARS( 0x00000000 )
+ };
+
+PixelType endpartial[33] =
+ {
+ LONG2CHARS( 0xFFFFFFFF ),
+ LONG2CHARS( 0x80000000 ),
+ LONG2CHARS( 0xC0000000 ),
+ LONG2CHARS( 0xE0000000 ),
+ LONG2CHARS( 0xF0000000 ),
+ LONG2CHARS( 0xF8000000 ),
+ LONG2CHARS( 0xFC000000 ),
+ LONG2CHARS( 0xFE000000 ),
+ LONG2CHARS( 0xFF000000 ),
+ LONG2CHARS( 0xFF800000 ),
+ LONG2CHARS( 0xFFC00000 ),
+ LONG2CHARS( 0xFFE00000 ),
+ LONG2CHARS( 0xFFF00000 ),
+ LONG2CHARS( 0xFFF80000 ),
+ LONG2CHARS( 0xFFFC0000 ),
+ LONG2CHARS( 0xFFFE0000 ),
+ LONG2CHARS( 0xFFFF0000 ),
+ LONG2CHARS( 0xFFFF8000 ),
+ LONG2CHARS( 0xFFFFC000 ),
+ LONG2CHARS( 0xFFFFE000 ),
+ LONG2CHARS( 0xFFFFF000 ),
+ LONG2CHARS( 0xFFFFF800 ),
+ LONG2CHARS( 0xFFFFFC00 ),
+ LONG2CHARS( 0xFFFFFE00 ),
+ LONG2CHARS( 0xFFFFFF00 ),
+ LONG2CHARS( 0xFFFFFF80 ),
+ LONG2CHARS( 0xFFFFFFC0 ),
+ LONG2CHARS( 0xFFFFFFE0 ),
+ LONG2CHARS( 0xFFFFFFF0 ),
+ LONG2CHARS( 0xFFFFFFF8 ),
+ LONG2CHARS( 0xFFFFFFFC ),
+ LONG2CHARS( 0xFFFFFFFE ),
+ LONG2CHARS( 0xFFFFFFFF )
+ };
+#endif /* NEED_OLD_MFB_MASKS */
+
+#endif /* ifndef LOWMEMFTPT */
+
+#if PPW == 32
+PixelType partmasks[PPW][PPW] = {
+ {LONG2CHARS( 0xFFFFFFFF ), LONG2CHARS( 0x80000000 ), LONG2CHARS( 0xC0000000 ), LONG2CHARS( 0xE0000000 ),
+ LONG2CHARS( 0xF0000000 ), LONG2CHARS( 0xF8000000 ), LONG2CHARS( 0xFC000000 ), LONG2CHARS( 0xFE000000 ),
+ LONG2CHARS( 0xFF000000 ), LONG2CHARS( 0xFF800000 ), LONG2CHARS( 0xFFC00000 ), LONG2CHARS( 0xFFE00000 ),
+ LONG2CHARS( 0xFFF00000 ), LONG2CHARS( 0xFFF80000 ), LONG2CHARS( 0xFFFC0000 ), LONG2CHARS( 0xFFFE0000 ),
+ LONG2CHARS( 0xFFFF0000 ), LONG2CHARS( 0xFFFF8000 ), LONG2CHARS( 0xFFFFC000 ), LONG2CHARS( 0xFFFFE000 ),
+ LONG2CHARS( 0xFFFFF000 ), LONG2CHARS( 0xFFFFF800 ), LONG2CHARS( 0xFFFFFC00 ), LONG2CHARS( 0xFFFFFE00 ),
+ LONG2CHARS( 0xFFFFFF00 ), LONG2CHARS( 0xFFFFFF80 ), LONG2CHARS( 0xFFFFFFC0 ), LONG2CHARS( 0xFFFFFFE0 ),
+ LONG2CHARS( 0xFFFFFFF0 ), LONG2CHARS( 0xFFFFFFF8 ), LONG2CHARS( 0xFFFFFFFC ), LONG2CHARS( 0xFFFFFFFE )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x40000000 ), LONG2CHARS( 0x60000000 ), LONG2CHARS( 0x70000000 ),
+ LONG2CHARS( 0x78000000 ), LONG2CHARS( 0x7C000000 ), LONG2CHARS( 0x7E000000 ), LONG2CHARS( 0x7F000000 ),
+ LONG2CHARS( 0x7F800000 ), LONG2CHARS( 0x7FC00000 ), LONG2CHARS( 0x7FE00000 ), LONG2CHARS( 0x7FF00000 ),
+ LONG2CHARS( 0x7FF80000 ), LONG2CHARS( 0x7FFC0000 ), LONG2CHARS( 0x7FFE0000 ), LONG2CHARS( 0x7FFF0000 ),
+ LONG2CHARS( 0x7FFF8000 ), LONG2CHARS( 0x7FFFC000 ), LONG2CHARS( 0x7FFFE000 ), LONG2CHARS( 0x7FFFF000 ),
+ LONG2CHARS( 0x7FFFF800 ), LONG2CHARS( 0x7FFFFC00 ), LONG2CHARS( 0x7FFFFE00 ), LONG2CHARS( 0x7FFFFF00 ),
+ LONG2CHARS( 0x7FFFFF80 ), LONG2CHARS( 0x7FFFFFC0 ), LONG2CHARS( 0x7FFFFFE0 ), LONG2CHARS( 0x7FFFFFF0 ),
+ LONG2CHARS( 0x7FFFFFF8 ), LONG2CHARS( 0x7FFFFFFC ), LONG2CHARS( 0x7FFFFFFE ), LONG2CHARS( 0x7FFFFFFF )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x20000000 ), LONG2CHARS( 0x30000000 ), LONG2CHARS( 0x38000000 ),
+ LONG2CHARS( 0x3C000000 ), LONG2CHARS( 0x3E000000 ), LONG2CHARS( 0x3F000000 ), LONG2CHARS( 0x3F800000 ),
+ LONG2CHARS( 0x3FC00000 ), LONG2CHARS( 0x3FE00000 ), LONG2CHARS( 0x3FF00000 ), LONG2CHARS( 0x3FF80000 ),
+ LONG2CHARS( 0x3FFC0000 ), LONG2CHARS( 0x3FFE0000 ), LONG2CHARS( 0x3FFF0000 ), LONG2CHARS( 0x3FFF8000 ),
+ LONG2CHARS( 0x3FFFC000 ), LONG2CHARS( 0x3FFFE000 ), LONG2CHARS( 0x3FFFF000 ), LONG2CHARS( 0x3FFFF800 ),
+ LONG2CHARS( 0x3FFFFC00 ), LONG2CHARS( 0x3FFFFE00 ), LONG2CHARS( 0x3FFFFF00 ), LONG2CHARS( 0x3FFFFF80 ),
+ LONG2CHARS( 0x3FFFFFC0 ), LONG2CHARS( 0x3FFFFFE0 ), LONG2CHARS( 0x3FFFFFF0 ), LONG2CHARS( 0x3FFFFFF8 ),
+ LONG2CHARS( 0x3FFFFFFC ), LONG2CHARS( 0x3FFFFFFE ), LONG2CHARS( 0x3FFFFFFF ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x10000000 ), LONG2CHARS( 0x18000000 ), LONG2CHARS( 0x1C000000 ),
+ LONG2CHARS( 0x1E000000 ), LONG2CHARS( 0x1F000000 ), LONG2CHARS( 0x1F800000 ), LONG2CHARS( 0x1FC00000 ),
+ LONG2CHARS( 0x1FE00000 ), LONG2CHARS( 0x1FF00000 ), LONG2CHARS( 0x1FF80000 ), LONG2CHARS( 0x1FFC0000 ),
+ LONG2CHARS( 0x1FFE0000 ), LONG2CHARS( 0x1FFF0000 ), LONG2CHARS( 0x1FFF8000 ), LONG2CHARS( 0x1FFFC000 ),
+ LONG2CHARS( 0x1FFFE000 ), LONG2CHARS( 0x1FFFF000 ), LONG2CHARS( 0x1FFFF800 ), LONG2CHARS( 0x1FFFFC00 ),
+ LONG2CHARS( 0x1FFFFE00 ), LONG2CHARS( 0x1FFFFF00 ), LONG2CHARS( 0x1FFFFF80 ), LONG2CHARS( 0x1FFFFFC0 ),
+ LONG2CHARS( 0x1FFFFFE0 ), LONG2CHARS( 0x1FFFFFF0 ), LONG2CHARS( 0x1FFFFFF8 ), LONG2CHARS( 0x1FFFFFFC ),
+ LONG2CHARS( 0x1FFFFFFE ), LONG2CHARS( 0x1FFFFFFF ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x08000000 ), LONG2CHARS( 0x0C000000 ), LONG2CHARS( 0x0E000000 ),
+ LONG2CHARS( 0x0F000000 ), LONG2CHARS( 0x0F800000 ), LONG2CHARS( 0x0FC00000 ), LONG2CHARS( 0x0FE00000 ),
+ LONG2CHARS( 0x0FF00000 ), LONG2CHARS( 0x0FF80000 ), LONG2CHARS( 0x0FFC0000 ), LONG2CHARS( 0x0FFE0000 ),
+ LONG2CHARS( 0x0FFF0000 ), LONG2CHARS( 0x0FFF8000 ), LONG2CHARS( 0x0FFFC000 ), LONG2CHARS( 0x0FFFE000 ),
+ LONG2CHARS( 0x0FFFF000 ), LONG2CHARS( 0x0FFFF800 ), LONG2CHARS( 0x0FFFFC00 ), LONG2CHARS( 0x0FFFFE00 ),
+ LONG2CHARS( 0x0FFFFF00 ), LONG2CHARS( 0x0FFFFF80 ), LONG2CHARS( 0x0FFFFFC0 ), LONG2CHARS( 0x0FFFFFE0 ),
+ LONG2CHARS( 0x0FFFFFF0 ), LONG2CHARS( 0x0FFFFFF8 ), LONG2CHARS( 0x0FFFFFFC ), LONG2CHARS( 0x0FFFFFFE ),
+ LONG2CHARS( 0x0FFFFFFF ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x04000000 ), LONG2CHARS( 0x06000000 ), LONG2CHARS( 0x07000000 ),
+ LONG2CHARS( 0x07800000 ), LONG2CHARS( 0x07C00000 ), LONG2CHARS( 0x07E00000 ), LONG2CHARS( 0x07F00000 ),
+ LONG2CHARS( 0x07F80000 ), LONG2CHARS( 0x07FC0000 ), LONG2CHARS( 0x07FE0000 ), LONG2CHARS( 0x07FF0000 ),
+ LONG2CHARS( 0x07FF8000 ), LONG2CHARS( 0x07FFC000 ), LONG2CHARS( 0x07FFE000 ), LONG2CHARS( 0x07FFF000 ),
+ LONG2CHARS( 0x07FFF800 ), LONG2CHARS( 0x07FFFC00 ), LONG2CHARS( 0x07FFFE00 ), LONG2CHARS( 0x07FFFF00 ),
+ LONG2CHARS( 0x07FFFF80 ), LONG2CHARS( 0x07FFFFC0 ), LONG2CHARS( 0x07FFFFE0 ), LONG2CHARS( 0x07FFFFF0 ),
+ LONG2CHARS( 0x07FFFFF8 ), LONG2CHARS( 0x07FFFFFC ), LONG2CHARS( 0x07FFFFFE ), LONG2CHARS( 0x07FFFFFF ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x02000000 ), LONG2CHARS( 0x03000000 ), LONG2CHARS( 0x03800000 ),
+ LONG2CHARS( 0x03C00000 ), LONG2CHARS( 0x03E00000 ), LONG2CHARS( 0x03F00000 ), LONG2CHARS( 0x03F80000 ),
+ LONG2CHARS( 0x03FC0000 ), LONG2CHARS( 0x03FE0000 ), LONG2CHARS( 0x03FF0000 ), LONG2CHARS( 0x03FF8000 ),
+ LONG2CHARS( 0x03FFC000 ), LONG2CHARS( 0x03FFE000 ), LONG2CHARS( 0x03FFF000 ), LONG2CHARS( 0x03FFF800 ),
+ LONG2CHARS( 0x03FFFC00 ), LONG2CHARS( 0x03FFFE00 ), LONG2CHARS( 0x03FFFF00 ), LONG2CHARS( 0x03FFFF80 ),
+ LONG2CHARS( 0x03FFFFC0 ), LONG2CHARS( 0x03FFFFE0 ), LONG2CHARS( 0x03FFFFF0 ), LONG2CHARS( 0x03FFFFF8 ),
+ LONG2CHARS( 0x03FFFFFC ), LONG2CHARS( 0x03FFFFFE ), LONG2CHARS( 0x03FFFFFF ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x01000000 ), LONG2CHARS( 0x01800000 ), LONG2CHARS( 0x01C00000 ),
+ LONG2CHARS( 0x01E00000 ), LONG2CHARS( 0x01F00000 ), LONG2CHARS( 0x01F80000 ), LONG2CHARS( 0x01FC0000 ),
+ LONG2CHARS( 0x01FE0000 ), LONG2CHARS( 0x01FF0000 ), LONG2CHARS( 0x01FF8000 ), LONG2CHARS( 0x01FFC000 ),
+ LONG2CHARS( 0x01FFE000 ), LONG2CHARS( 0x01FFF000 ), LONG2CHARS( 0x01FFF800 ), LONG2CHARS( 0x01FFFC00 ),
+ LONG2CHARS( 0x01FFFE00 ), LONG2CHARS( 0x01FFFF00 ), LONG2CHARS( 0x01FFFF80 ), LONG2CHARS( 0x01FFFFC0 ),
+ LONG2CHARS( 0x01FFFFE0 ), LONG2CHARS( 0x01FFFFF0 ), LONG2CHARS( 0x01FFFFF8 ), LONG2CHARS( 0x01FFFFFC ),
+ LONG2CHARS( 0x01FFFFFE ), LONG2CHARS( 0x01FFFFFF ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00800000 ), LONG2CHARS( 0x00C00000 ), LONG2CHARS( 0x00E00000 ),
+ LONG2CHARS( 0x00F00000 ), LONG2CHARS( 0x00F80000 ), LONG2CHARS( 0x00FC0000 ), LONG2CHARS( 0x00FE0000 ),
+ LONG2CHARS( 0x00FF0000 ), LONG2CHARS( 0x00FF8000 ), LONG2CHARS( 0x00FFC000 ), LONG2CHARS( 0x00FFE000 ),
+ LONG2CHARS( 0x00FFF000 ), LONG2CHARS( 0x00FFF800 ), LONG2CHARS( 0x00FFFC00 ), LONG2CHARS( 0x00FFFE00 ),
+ LONG2CHARS( 0x00FFFF00 ), LONG2CHARS( 0x00FFFF80 ), LONG2CHARS( 0x00FFFFC0 ), LONG2CHARS( 0x00FFFFE0 ),
+ LONG2CHARS( 0x00FFFFF0 ), LONG2CHARS( 0x00FFFFF8 ), LONG2CHARS( 0x00FFFFFC ), LONG2CHARS( 0x00FFFFFE ),
+ LONG2CHARS( 0x00FFFFFF ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00400000 ), LONG2CHARS( 0x00600000 ), LONG2CHARS( 0x00700000 ),
+ LONG2CHARS( 0x00780000 ), LONG2CHARS( 0x007C0000 ), LONG2CHARS( 0x007E0000 ), LONG2CHARS( 0x007F0000 ),
+ LONG2CHARS( 0x007F8000 ), LONG2CHARS( 0x007FC000 ), LONG2CHARS( 0x007FE000 ), LONG2CHARS( 0x007FF000 ),
+ LONG2CHARS( 0x007FF800 ), LONG2CHARS( 0x007FFC00 ), LONG2CHARS( 0x007FFE00 ), LONG2CHARS( 0x007FFF00 ),
+ LONG2CHARS( 0x007FFF80 ), LONG2CHARS( 0x007FFFC0 ), LONG2CHARS( 0x007FFFE0 ), LONG2CHARS( 0x007FFFF0 ),
+ LONG2CHARS( 0x007FFFF8 ), LONG2CHARS( 0x007FFFFC ), LONG2CHARS( 0x007FFFFE ), LONG2CHARS( 0x007FFFFF ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00200000 ), LONG2CHARS( 0x00300000 ), LONG2CHARS( 0x00380000 ),
+ LONG2CHARS( 0x003C0000 ), LONG2CHARS( 0x003E0000 ), LONG2CHARS( 0x003F0000 ), LONG2CHARS( 0x003F8000 ),
+ LONG2CHARS( 0x003FC000 ), LONG2CHARS( 0x003FE000 ), LONG2CHARS( 0x003FF000 ), LONG2CHARS( 0x003FF800 ),
+ LONG2CHARS( 0x003FFC00 ), LONG2CHARS( 0x003FFE00 ), LONG2CHARS( 0x003FFF00 ), LONG2CHARS( 0x003FFF80 ),
+ LONG2CHARS( 0x003FFFC0 ), LONG2CHARS( 0x003FFFE0 ), LONG2CHARS( 0x003FFFF0 ), LONG2CHARS( 0x003FFFF8 ),
+ LONG2CHARS( 0x003FFFFC ), LONG2CHARS( 0x003FFFFE ), LONG2CHARS( 0x003FFFFF ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00100000 ), LONG2CHARS( 0x00180000 ), LONG2CHARS( 0x001C0000 ),
+ LONG2CHARS( 0x001E0000 ), LONG2CHARS( 0x001F0000 ), LONG2CHARS( 0x001F8000 ), LONG2CHARS( 0x001FC000 ),
+ LONG2CHARS( 0x001FE000 ), LONG2CHARS( 0x001FF000 ), LONG2CHARS( 0x001FF800 ), LONG2CHARS( 0x001FFC00 ),
+ LONG2CHARS( 0x001FFE00 ), LONG2CHARS( 0x001FFF00 ), LONG2CHARS( 0x001FFF80 ), LONG2CHARS( 0x001FFFC0 ),
+ LONG2CHARS( 0x001FFFE0 ), LONG2CHARS( 0x001FFFF0 ), LONG2CHARS( 0x001FFFF8 ), LONG2CHARS( 0x001FFFFC ),
+ LONG2CHARS( 0x001FFFFE ), LONG2CHARS( 0x001FFFFF ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00080000 ), LONG2CHARS( 0x000C0000 ), LONG2CHARS( 0x000E0000 ),
+ LONG2CHARS( 0x000F0000 ), LONG2CHARS( 0x000F8000 ), LONG2CHARS( 0x000FC000 ), LONG2CHARS( 0x000FE000 ),
+ LONG2CHARS( 0x000FF000 ), LONG2CHARS( 0x000FF800 ), LONG2CHARS( 0x000FFC00 ), LONG2CHARS( 0x000FFE00 ),
+ LONG2CHARS( 0x000FFF00 ), LONG2CHARS( 0x000FFF80 ), LONG2CHARS( 0x000FFFC0 ), LONG2CHARS( 0x000FFFE0 ),
+ LONG2CHARS( 0x000FFFF0 ), LONG2CHARS( 0x000FFFF8 ), LONG2CHARS( 0x000FFFFC ), LONG2CHARS( 0x000FFFFE ),
+ LONG2CHARS( 0x000FFFFF ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00040000 ), LONG2CHARS( 0x00060000 ), LONG2CHARS( 0x00070000 ),
+ LONG2CHARS( 0x00078000 ), LONG2CHARS( 0x0007C000 ), LONG2CHARS( 0x0007E000 ), LONG2CHARS( 0x0007F000 ),
+ LONG2CHARS( 0x0007F800 ), LONG2CHARS( 0x0007FC00 ), LONG2CHARS( 0x0007FE00 ), LONG2CHARS( 0x0007FF00 ),
+ LONG2CHARS( 0x0007FF80 ), LONG2CHARS( 0x0007FFC0 ), LONG2CHARS( 0x0007FFE0 ), LONG2CHARS( 0x0007FFF0 ),
+ LONG2CHARS( 0x0007FFF8 ), LONG2CHARS( 0x0007FFFC ), LONG2CHARS( 0x0007FFFE ), LONG2CHARS( 0x0007FFFF ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00020000 ), LONG2CHARS( 0x00030000 ), LONG2CHARS( 0x00038000 ),
+ LONG2CHARS( 0x0003C000 ), LONG2CHARS( 0x0003E000 ), LONG2CHARS( 0x0003F000 ), LONG2CHARS( 0x0003F800 ),
+ LONG2CHARS( 0x0003FC00 ), LONG2CHARS( 0x0003FE00 ), LONG2CHARS( 0x0003FF00 ), LONG2CHARS( 0x0003FF80 ),
+ LONG2CHARS( 0x0003FFC0 ), LONG2CHARS( 0x0003FFE0 ), LONG2CHARS( 0x0003FFF0 ), LONG2CHARS( 0x0003FFF8 ),
+ LONG2CHARS( 0x0003FFFC ), LONG2CHARS( 0x0003FFFE ), LONG2CHARS( 0x0003FFFF ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00010000 ), LONG2CHARS( 0x00018000 ), LONG2CHARS( 0x0001C000 ),
+ LONG2CHARS( 0x0001E000 ), LONG2CHARS( 0x0001F000 ), LONG2CHARS( 0x0001F800 ), LONG2CHARS( 0x0001FC00 ),
+ LONG2CHARS( 0x0001FE00 ), LONG2CHARS( 0x0001FF00 ), LONG2CHARS( 0x0001FF80 ), LONG2CHARS( 0x0001FFC0 ),
+ LONG2CHARS( 0x0001FFE0 ), LONG2CHARS( 0x0001FFF0 ), LONG2CHARS( 0x0001FFF8 ), LONG2CHARS( 0x0001FFFC ),
+ LONG2CHARS( 0x0001FFFE ), LONG2CHARS( 0x0001FFFF ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00008000 ), LONG2CHARS( 0x0000C000 ), LONG2CHARS( 0x0000E000 ),
+ LONG2CHARS( 0x0000F000 ), LONG2CHARS( 0x0000F800 ), LONG2CHARS( 0x0000FC00 ), LONG2CHARS( 0x0000FE00 ),
+ LONG2CHARS( 0x0000FF00 ), LONG2CHARS( 0x0000FF80 ), LONG2CHARS( 0x0000FFC0 ), LONG2CHARS( 0x0000FFE0 ),
+ LONG2CHARS( 0x0000FFF0 ), LONG2CHARS( 0x0000FFF8 ), LONG2CHARS( 0x0000FFFC ), LONG2CHARS( 0x0000FFFE ),
+ LONG2CHARS( 0x0000FFFF ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00004000 ), LONG2CHARS( 0x00006000 ), LONG2CHARS( 0x00007000 ),
+ LONG2CHARS( 0x00007800 ), LONG2CHARS( 0x00007C00 ), LONG2CHARS( 0x00007E00 ), LONG2CHARS( 0x00007F00 ),
+ LONG2CHARS( 0x00007F80 ), LONG2CHARS( 0x00007FC0 ), LONG2CHARS( 0x00007FE0 ), LONG2CHARS( 0x00007FF0 ),
+ LONG2CHARS( 0x00007FF8 ), LONG2CHARS( 0x00007FFC ), LONG2CHARS( 0x00007FFE ), LONG2CHARS( 0x00007FFF ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00002000 ), LONG2CHARS( 0x00003000 ), LONG2CHARS( 0x00003800 ),
+ LONG2CHARS( 0x00003C00 ), LONG2CHARS( 0x00003E00 ), LONG2CHARS( 0x00003F00 ), LONG2CHARS( 0x00003F80 ),
+ LONG2CHARS( 0x00003FC0 ), LONG2CHARS( 0x00003FE0 ), LONG2CHARS( 0x00003FF0 ), LONG2CHARS( 0x00003FF8 ),
+ LONG2CHARS( 0x00003FFC ), LONG2CHARS( 0x00003FFE ), LONG2CHARS( 0x00003FFF ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00001000 ), LONG2CHARS( 0x00001800 ), LONG2CHARS( 0x00001C00 ),
+ LONG2CHARS( 0x00001E00 ), LONG2CHARS( 0x00001F00 ), LONG2CHARS( 0x00001F80 ), LONG2CHARS( 0x00001FC0 ),
+ LONG2CHARS( 0x00001FE0 ), LONG2CHARS( 0x00001FF0 ), LONG2CHARS( 0x00001FF8 ), LONG2CHARS( 0x00001FFC ),
+ LONG2CHARS( 0x00001FFE ), LONG2CHARS( 0x00001FFF ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000800 ), LONG2CHARS( 0x00000C00 ), LONG2CHARS( 0x00000E00 ),
+ LONG2CHARS( 0x00000F00 ), LONG2CHARS( 0x00000F80 ), LONG2CHARS( 0x00000FC0 ), LONG2CHARS( 0x00000FE0 ),
+ LONG2CHARS( 0x00000FF0 ), LONG2CHARS( 0x00000FF8 ), LONG2CHARS( 0x00000FFC ), LONG2CHARS( 0x00000FFE ),
+ LONG2CHARS( 0x00000FFF ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000400 ), LONG2CHARS( 0x00000600 ), LONG2CHARS( 0x00000700 ),
+ LONG2CHARS( 0x00000780 ), LONG2CHARS( 0x000007C0 ), LONG2CHARS( 0x000007E0 ), LONG2CHARS( 0x000007F0 ),
+ LONG2CHARS( 0x000007F8 ), LONG2CHARS( 0x000007FC ), LONG2CHARS( 0x000007FE ), LONG2CHARS( 0x000007FF ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000200 ), LONG2CHARS( 0x00000300 ), LONG2CHARS( 0x00000380 ),
+ LONG2CHARS( 0x000003C0 ), LONG2CHARS( 0x000003E0 ), LONG2CHARS( 0x000003F0 ), LONG2CHARS( 0x000003F8 ),
+ LONG2CHARS( 0x000003FC ), LONG2CHARS( 0x000003FE ), LONG2CHARS( 0x000003FF ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000100 ), LONG2CHARS( 0x00000180 ), LONG2CHARS( 0x000001C0 ),
+ LONG2CHARS( 0x000001E0 ), LONG2CHARS( 0x000001F0 ), LONG2CHARS( 0x000001F8 ), LONG2CHARS( 0x000001FC ),
+ LONG2CHARS( 0x000001FE ), LONG2CHARS( 0x000001FF ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000080 ), LONG2CHARS( 0x000000C0 ), LONG2CHARS( 0x000000E0 ),
+ LONG2CHARS( 0x000000F0 ), LONG2CHARS( 0x000000F8 ), LONG2CHARS( 0x000000FC ), LONG2CHARS( 0x000000FE ),
+ LONG2CHARS( 0x000000FF ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000040 ), LONG2CHARS( 0x00000060 ), LONG2CHARS( 0x00000070 ),
+ LONG2CHARS( 0x00000078 ), LONG2CHARS( 0x0000007C ), LONG2CHARS( 0x0000007E ), LONG2CHARS( 0x0000007F ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000020 ), LONG2CHARS( 0x00000030 ), LONG2CHARS( 0x00000038 ),
+ LONG2CHARS( 0x0000003C ), LONG2CHARS( 0x0000003E ), LONG2CHARS( 0x0000003F ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000010 ), LONG2CHARS( 0x00000018 ), LONG2CHARS( 0x0000001C ),
+ LONG2CHARS( 0x0000001E ), LONG2CHARS( 0x0000001F ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000008 ), LONG2CHARS( 0x0000000C ), LONG2CHARS( 0x0000000E ),
+ LONG2CHARS( 0x0000000F ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000004 ), LONG2CHARS( 0x00000006 ), LONG2CHARS( 0x00000007 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000002 ), LONG2CHARS( 0x00000003 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000001 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+};
+#else /* PPW == 64 */
+unsigned long partmasks[PPW][PPW] = {
+ {
+ LONG2CHARS( 0xFFFFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x8000000000000000 ),
+ LONG2CHARS( 0xC000000000000000 ),
+ LONG2CHARS( 0xE000000000000000 ),
+ LONG2CHARS( 0xF000000000000000 ),
+ LONG2CHARS( 0xF800000000000000 ),
+ LONG2CHARS( 0xFC00000000000000 ),
+ LONG2CHARS( 0xFE00000000000000 ),
+ LONG2CHARS( 0xFF00000000000000 ),
+ LONG2CHARS( 0xFF80000000000000 ),
+ LONG2CHARS( 0xFFC0000000000000 ),
+ LONG2CHARS( 0xFFE0000000000000 ),
+ LONG2CHARS( 0xFFF0000000000000 ),
+ LONG2CHARS( 0xFFF8000000000000 ),
+ LONG2CHARS( 0xFFFC000000000000 ),
+ LONG2CHARS( 0xFFFE000000000000 ),
+ LONG2CHARS( 0xFFFF000000000000 ),
+ LONG2CHARS( 0xFFFF800000000000 ),
+ LONG2CHARS( 0xFFFFC00000000000 ),
+ LONG2CHARS( 0xFFFFE00000000000 ),
+ LONG2CHARS( 0xFFFFF00000000000 ),
+ LONG2CHARS( 0xFFFFF80000000000 ),
+ LONG2CHARS( 0xFFFFFC0000000000 ),
+ LONG2CHARS( 0xFFFFFE0000000000 ),
+ LONG2CHARS( 0xFFFFFF0000000000 ),
+ LONG2CHARS( 0xFFFFFF8000000000 ),
+ LONG2CHARS( 0xFFFFFFC000000000 ),
+ LONG2CHARS( 0xFFFFFFE000000000 ),
+ LONG2CHARS( 0xFFFFFFF000000000 ),
+ LONG2CHARS( 0xFFFFFFF800000000 ),
+ LONG2CHARS( 0xFFFFFFFC00000000 ),
+ LONG2CHARS( 0xFFFFFFFE00000000 ),
+ LONG2CHARS( 0xFFFFFFFF00000000 ),
+ LONG2CHARS( 0xFFFFFFFF80000000 ),
+ LONG2CHARS( 0xFFFFFFFFC0000000 ),
+ LONG2CHARS( 0xFFFFFFFFE0000000 ),
+ LONG2CHARS( 0xFFFFFFFFF0000000 ),
+ LONG2CHARS( 0xFFFFFFFFF8000000 ),
+ LONG2CHARS( 0xFFFFFFFFFC000000 ),
+ LONG2CHARS( 0xFFFFFFFFFE000000 ),
+ LONG2CHARS( 0xFFFFFFFFFF000000 ),
+ LONG2CHARS( 0xFFFFFFFFFF800000 ),
+ LONG2CHARS( 0xFFFFFFFFFFC00000 ),
+ LONG2CHARS( 0xFFFFFFFFFFE00000 ),
+ LONG2CHARS( 0xFFFFFFFFFFF00000 ),
+ LONG2CHARS( 0xFFFFFFFFFFF80000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFC0000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFE0000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFF0000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFF8000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFC000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFE000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFF000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFF800 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFC00 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFE00 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFF00 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFF80 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFFC ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFFE ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x4000000000000000 ),
+ LONG2CHARS( 0x6000000000000000 ),
+ LONG2CHARS( 0x7000000000000000 ),
+ LONG2CHARS( 0x7800000000000000 ),
+ LONG2CHARS( 0x7C00000000000000 ),
+ LONG2CHARS( 0x7E00000000000000 ),
+ LONG2CHARS( 0x7F00000000000000 ),
+ LONG2CHARS( 0x7F80000000000000 ),
+ LONG2CHARS( 0x7FC0000000000000 ),
+ LONG2CHARS( 0x7FE0000000000000 ),
+ LONG2CHARS( 0x7FF0000000000000 ),
+ LONG2CHARS( 0x7FF8000000000000 ),
+ LONG2CHARS( 0x7FFC000000000000 ),
+ LONG2CHARS( 0x7FFE000000000000 ),
+ LONG2CHARS( 0x7FFF000000000000 ),
+ LONG2CHARS( 0x7FFF800000000000 ),
+ LONG2CHARS( 0x7FFFC00000000000 ),
+ LONG2CHARS( 0x7FFFE00000000000 ),
+ LONG2CHARS( 0x7FFFF00000000000 ),
+ LONG2CHARS( 0x7FFFF80000000000 ),
+ LONG2CHARS( 0x7FFFFC0000000000 ),
+ LONG2CHARS( 0x7FFFFE0000000000 ),
+ LONG2CHARS( 0x7FFFFF0000000000 ),
+ LONG2CHARS( 0x7FFFFF8000000000 ),
+ LONG2CHARS( 0x7FFFFFC000000000 ),
+ LONG2CHARS( 0x7FFFFFE000000000 ),
+ LONG2CHARS( 0x7FFFFFF000000000 ),
+ LONG2CHARS( 0x7FFFFFF800000000 ),
+ LONG2CHARS( 0x7FFFFFFC00000000 ),
+ LONG2CHARS( 0x7FFFFFFE00000000 ),
+ LONG2CHARS( 0x7FFFFFFF00000000 ),
+ LONG2CHARS( 0x7FFFFFFF80000000 ),
+ LONG2CHARS( 0x7FFFFFFFC0000000 ),
+ LONG2CHARS( 0x7FFFFFFFE0000000 ),
+ LONG2CHARS( 0x7FFFFFFFF0000000 ),
+ LONG2CHARS( 0x7FFFFFFFF8000000 ),
+ LONG2CHARS( 0x7FFFFFFFFC000000 ),
+ LONG2CHARS( 0x7FFFFFFFFE000000 ),
+ LONG2CHARS( 0x7FFFFFFFFF000000 ),
+ LONG2CHARS( 0x7FFFFFFFFF800000 ),
+ LONG2CHARS( 0x7FFFFFFFFFC00000 ),
+ LONG2CHARS( 0x7FFFFFFFFFE00000 ),
+ LONG2CHARS( 0x7FFFFFFFFFF00000 ),
+ LONG2CHARS( 0x7FFFFFFFFFF80000 ),
+ LONG2CHARS( 0x7FFFFFFFFFFC0000 ),
+ LONG2CHARS( 0x7FFFFFFFFFFE0000 ),
+ LONG2CHARS( 0x7FFFFFFFFFFF0000 ),
+ LONG2CHARS( 0x7FFFFFFFFFFF8000 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFC000 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFE000 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFF000 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFF800 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFC00 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFE00 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFF00 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFF80 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFFFC ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFFFE ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFFFF ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x2000000000000000 ),
+ LONG2CHARS( 0x3000000000000000 ),
+ LONG2CHARS( 0x3800000000000000 ),
+ LONG2CHARS( 0x3C00000000000000 ),
+ LONG2CHARS( 0x3E00000000000000 ),
+ LONG2CHARS( 0x3F00000000000000 ),
+ LONG2CHARS( 0x3F80000000000000 ),
+ LONG2CHARS( 0x3FC0000000000000 ),
+ LONG2CHARS( 0x3FE0000000000000 ),
+ LONG2CHARS( 0x3FF0000000000000 ),
+ LONG2CHARS( 0x3FF8000000000000 ),
+ LONG2CHARS( 0x3FFC000000000000 ),
+ LONG2CHARS( 0x3FFE000000000000 ),
+ LONG2CHARS( 0x3FFF000000000000 ),
+ LONG2CHARS( 0x3FFF800000000000 ),
+ LONG2CHARS( 0x3FFFC00000000000 ),
+ LONG2CHARS( 0x3FFFE00000000000 ),
+ LONG2CHARS( 0x3FFFF00000000000 ),
+ LONG2CHARS( 0x3FFFF80000000000 ),
+ LONG2CHARS( 0x3FFFFC0000000000 ),
+ LONG2CHARS( 0x3FFFFE0000000000 ),
+ LONG2CHARS( 0x3FFFFF0000000000 ),
+ LONG2CHARS( 0x3FFFFF8000000000 ),
+ LONG2CHARS( 0x3FFFFFC000000000 ),
+ LONG2CHARS( 0x3FFFFFE000000000 ),
+ LONG2CHARS( 0x3FFFFFF000000000 ),
+ LONG2CHARS( 0x3FFFFFF800000000 ),
+ LONG2CHARS( 0x3FFFFFFC00000000 ),
+ LONG2CHARS( 0x3FFFFFFE00000000 ),
+ LONG2CHARS( 0x3FFFFFFF00000000 ),
+ LONG2CHARS( 0x3FFFFFFF80000000 ),
+ LONG2CHARS( 0x3FFFFFFFC0000000 ),
+ LONG2CHARS( 0x3FFFFFFFE0000000 ),
+ LONG2CHARS( 0x3FFFFFFFF0000000 ),
+ LONG2CHARS( 0x3FFFFFFFF8000000 ),
+ LONG2CHARS( 0x3FFFFFFFFC000000 ),
+ LONG2CHARS( 0x3FFFFFFFFE000000 ),
+ LONG2CHARS( 0x3FFFFFFFFF000000 ),
+ LONG2CHARS( 0x3FFFFFFFFF800000 ),
+ LONG2CHARS( 0x3FFFFFFFFFC00000 ),
+ LONG2CHARS( 0x3FFFFFFFFFE00000 ),
+ LONG2CHARS( 0x3FFFFFFFFFF00000 ),
+ LONG2CHARS( 0x3FFFFFFFFFF80000 ),
+ LONG2CHARS( 0x3FFFFFFFFFFC0000 ),
+ LONG2CHARS( 0x3FFFFFFFFFFE0000 ),
+ LONG2CHARS( 0x3FFFFFFFFFFF0000 ),
+ LONG2CHARS( 0x3FFFFFFFFFFF8000 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFC000 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFE000 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFF000 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFF800 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFC00 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFE00 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFF00 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFF80 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFFFC ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFFFE ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x1000000000000000 ),
+ LONG2CHARS( 0x1800000000000000 ),
+ LONG2CHARS( 0x1C00000000000000 ),
+ LONG2CHARS( 0x1E00000000000000 ),
+ LONG2CHARS( 0x1F00000000000000 ),
+ LONG2CHARS( 0x1F80000000000000 ),
+ LONG2CHARS( 0x1FC0000000000000 ),
+ LONG2CHARS( 0x1FE0000000000000 ),
+ LONG2CHARS( 0x1FF0000000000000 ),
+ LONG2CHARS( 0x1FF8000000000000 ),
+ LONG2CHARS( 0x1FFC000000000000 ),
+ LONG2CHARS( 0x1FFE000000000000 ),
+ LONG2CHARS( 0x1FFF000000000000 ),
+ LONG2CHARS( 0x1FFF800000000000 ),
+ LONG2CHARS( 0x1FFFC00000000000 ),
+ LONG2CHARS( 0x1FFFE00000000000 ),
+ LONG2CHARS( 0x1FFFF00000000000 ),
+ LONG2CHARS( 0x1FFFF80000000000 ),
+ LONG2CHARS( 0x1FFFFC0000000000 ),
+ LONG2CHARS( 0x1FFFFE0000000000 ),
+ LONG2CHARS( 0x1FFFFF0000000000 ),
+ LONG2CHARS( 0x1FFFFF8000000000 ),
+ LONG2CHARS( 0x1FFFFFC000000000 ),
+ LONG2CHARS( 0x1FFFFFE000000000 ),
+ LONG2CHARS( 0x1FFFFFF000000000 ),
+ LONG2CHARS( 0x1FFFFFF800000000 ),
+ LONG2CHARS( 0x1FFFFFFC00000000 ),
+ LONG2CHARS( 0x1FFFFFFE00000000 ),
+ LONG2CHARS( 0x1FFFFFFF00000000 ),
+ LONG2CHARS( 0x1FFFFFFF80000000 ),
+ LONG2CHARS( 0x1FFFFFFFC0000000 ),
+ LONG2CHARS( 0x1FFFFFFFE0000000 ),
+ LONG2CHARS( 0x1FFFFFFFF0000000 ),
+ LONG2CHARS( 0x1FFFFFFFF8000000 ),
+ LONG2CHARS( 0x1FFFFFFFFC000000 ),
+ LONG2CHARS( 0x1FFFFFFFFE000000 ),
+ LONG2CHARS( 0x1FFFFFFFFF000000 ),
+ LONG2CHARS( 0x1FFFFFFFFF800000 ),
+ LONG2CHARS( 0x1FFFFFFFFFC00000 ),
+ LONG2CHARS( 0x1FFFFFFFFFE00000 ),
+ LONG2CHARS( 0x1FFFFFFFFFF00000 ),
+ LONG2CHARS( 0x1FFFFFFFFFF80000 ),
+ LONG2CHARS( 0x1FFFFFFFFFFC0000 ),
+ LONG2CHARS( 0x1FFFFFFFFFFE0000 ),
+ LONG2CHARS( 0x1FFFFFFFFFFF0000 ),
+ LONG2CHARS( 0x1FFFFFFFFFFF8000 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFC000 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFE000 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFF000 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFF800 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFC00 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFE00 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFF00 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFF80 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFFFC ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFFFE ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0800000000000000 ),
+ LONG2CHARS( 0x0C00000000000000 ),
+ LONG2CHARS( 0x0E00000000000000 ),
+ LONG2CHARS( 0x0F00000000000000 ),
+ LONG2CHARS( 0x0F80000000000000 ),
+ LONG2CHARS( 0x0FC0000000000000 ),
+ LONG2CHARS( 0x0FE0000000000000 ),
+ LONG2CHARS( 0x0FF0000000000000 ),
+ LONG2CHARS( 0x0FF8000000000000 ),
+ LONG2CHARS( 0x0FFC000000000000 ),
+ LONG2CHARS( 0x0FFE000000000000 ),
+ LONG2CHARS( 0x0FFF000000000000 ),
+ LONG2CHARS( 0x0FFF800000000000 ),
+ LONG2CHARS( 0x0FFFC00000000000 ),
+ LONG2CHARS( 0x0FFFE00000000000 ),
+ LONG2CHARS( 0x0FFFF00000000000 ),
+ LONG2CHARS( 0x0FFFF80000000000 ),
+ LONG2CHARS( 0x0FFFFC0000000000 ),
+ LONG2CHARS( 0x0FFFFE0000000000 ),
+ LONG2CHARS( 0x0FFFFF0000000000 ),
+ LONG2CHARS( 0x0FFFFF8000000000 ),
+ LONG2CHARS( 0x0FFFFFC000000000 ),
+ LONG2CHARS( 0x0FFFFFE000000000 ),
+ LONG2CHARS( 0x0FFFFFF000000000 ),
+ LONG2CHARS( 0x0FFFFFF800000000 ),
+ LONG2CHARS( 0x0FFFFFFC00000000 ),
+ LONG2CHARS( 0x0FFFFFFE00000000 ),
+ LONG2CHARS( 0x0FFFFFFF00000000 ),
+ LONG2CHARS( 0x0FFFFFFF80000000 ),
+ LONG2CHARS( 0x0FFFFFFFC0000000 ),
+ LONG2CHARS( 0x0FFFFFFFE0000000 ),
+ LONG2CHARS( 0x0FFFFFFFF0000000 ),
+ LONG2CHARS( 0x0FFFFFFFF8000000 ),
+ LONG2CHARS( 0x0FFFFFFFFC000000 ),
+ LONG2CHARS( 0x0FFFFFFFFE000000 ),
+ LONG2CHARS( 0x0FFFFFFFFF000000 ),
+ LONG2CHARS( 0x0FFFFFFFFF800000 ),
+ LONG2CHARS( 0x0FFFFFFFFFC00000 ),
+ LONG2CHARS( 0x0FFFFFFFFFE00000 ),
+ LONG2CHARS( 0x0FFFFFFFFFF00000 ),
+ LONG2CHARS( 0x0FFFFFFFFFF80000 ),
+ LONG2CHARS( 0x0FFFFFFFFFFC0000 ),
+ LONG2CHARS( 0x0FFFFFFFFFFE0000 ),
+ LONG2CHARS( 0x0FFFFFFFFFFF0000 ),
+ LONG2CHARS( 0x0FFFFFFFFFFF8000 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFC000 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFE000 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFF000 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFF800 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFC00 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFE00 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFF00 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFF80 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFFFC ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFFFE ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0400000000000000 ),
+ LONG2CHARS( 0x0600000000000000 ),
+ LONG2CHARS( 0x0700000000000000 ),
+ LONG2CHARS( 0x0780000000000000 ),
+ LONG2CHARS( 0x07C0000000000000 ),
+ LONG2CHARS( 0x07E0000000000000 ),
+ LONG2CHARS( 0x07F0000000000000 ),
+ LONG2CHARS( 0x07F8000000000000 ),
+ LONG2CHARS( 0x07FC000000000000 ),
+ LONG2CHARS( 0x07FE000000000000 ),
+ LONG2CHARS( 0x07FF000000000000 ),
+ LONG2CHARS( 0x07FF800000000000 ),
+ LONG2CHARS( 0x07FFC00000000000 ),
+ LONG2CHARS( 0x07FFE00000000000 ),
+ LONG2CHARS( 0x07FFF00000000000 ),
+ LONG2CHARS( 0x07FFF80000000000 ),
+ LONG2CHARS( 0x07FFFC0000000000 ),
+ LONG2CHARS( 0x07FFFE0000000000 ),
+ LONG2CHARS( 0x07FFFF0000000000 ),
+ LONG2CHARS( 0x07FFFF8000000000 ),
+ LONG2CHARS( 0x07FFFFC000000000 ),
+ LONG2CHARS( 0x07FFFFE000000000 ),
+ LONG2CHARS( 0x07FFFFF000000000 ),
+ LONG2CHARS( 0x07FFFFF800000000 ),
+ LONG2CHARS( 0x07FFFFFC00000000 ),
+ LONG2CHARS( 0x07FFFFFE00000000 ),
+ LONG2CHARS( 0x07FFFFFF00000000 ),
+ LONG2CHARS( 0x07FFFFFF80000000 ),
+ LONG2CHARS( 0x07FFFFFFC0000000 ),
+ LONG2CHARS( 0x07FFFFFFE0000000 ),
+ LONG2CHARS( 0x07FFFFFFF0000000 ),
+ LONG2CHARS( 0x07FFFFFFF8000000 ),
+ LONG2CHARS( 0x07FFFFFFFC000000 ),
+ LONG2CHARS( 0x07FFFFFFFE000000 ),
+ LONG2CHARS( 0x07FFFFFFFF000000 ),
+ LONG2CHARS( 0x07FFFFFFFF800000 ),
+ LONG2CHARS( 0x07FFFFFFFFC00000 ),
+ LONG2CHARS( 0x07FFFFFFFFE00000 ),
+ LONG2CHARS( 0x07FFFFFFFFF00000 ),
+ LONG2CHARS( 0x07FFFFFFFFF80000 ),
+ LONG2CHARS( 0x07FFFFFFFFFC0000 ),
+ LONG2CHARS( 0x07FFFFFFFFFE0000 ),
+ LONG2CHARS( 0x07FFFFFFFFFF0000 ),
+ LONG2CHARS( 0x07FFFFFFFFFF8000 ),
+ LONG2CHARS( 0x07FFFFFFFFFFC000 ),
+ LONG2CHARS( 0x07FFFFFFFFFFE000 ),
+ LONG2CHARS( 0x07FFFFFFFFFFF000 ),
+ LONG2CHARS( 0x07FFFFFFFFFFF800 ),
+ LONG2CHARS( 0x07FFFFFFFFFFFC00 ),
+ LONG2CHARS( 0x07FFFFFFFFFFFE00 ),
+ LONG2CHARS( 0x07FFFFFFFFFFFF00 ),
+ LONG2CHARS( 0x07FFFFFFFFFFFF80 ),
+ LONG2CHARS( 0x07FFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x07FFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x07FFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x07FFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x07FFFFFFFFFFFFFC ),
+ LONG2CHARS( 0x07FFFFFFFFFFFFFE ),
+ LONG2CHARS( 0x07FFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0200000000000000 ),
+ LONG2CHARS( 0x0300000000000000 ),
+ LONG2CHARS( 0x0380000000000000 ),
+ LONG2CHARS( 0x03C0000000000000 ),
+ LONG2CHARS( 0x03E0000000000000 ),
+ LONG2CHARS( 0x03F0000000000000 ),
+ LONG2CHARS( 0x03F8000000000000 ),
+ LONG2CHARS( 0x03FC000000000000 ),
+ LONG2CHARS( 0x03FE000000000000 ),
+ LONG2CHARS( 0x03FF000000000000 ),
+ LONG2CHARS( 0x03FF800000000000 ),
+ LONG2CHARS( 0x03FFC00000000000 ),
+ LONG2CHARS( 0x03FFE00000000000 ),
+ LONG2CHARS( 0x03FFF00000000000 ),
+ LONG2CHARS( 0x03FFF80000000000 ),
+ LONG2CHARS( 0x03FFFC0000000000 ),
+ LONG2CHARS( 0x03FFFE0000000000 ),
+ LONG2CHARS( 0x03FFFF0000000000 ),
+ LONG2CHARS( 0x03FFFF8000000000 ),
+ LONG2CHARS( 0x03FFFFC000000000 ),
+ LONG2CHARS( 0x03FFFFE000000000 ),
+ LONG2CHARS( 0x03FFFFF000000000 ),
+ LONG2CHARS( 0x03FFFFF800000000 ),
+ LONG2CHARS( 0x03FFFFFC00000000 ),
+ LONG2CHARS( 0x03FFFFFE00000000 ),
+ LONG2CHARS( 0x03FFFFFF00000000 ),
+ LONG2CHARS( 0x03FFFFFF80000000 ),
+ LONG2CHARS( 0x03FFFFFFC0000000 ),
+ LONG2CHARS( 0x03FFFFFFE0000000 ),
+ LONG2CHARS( 0x03FFFFFFF0000000 ),
+ LONG2CHARS( 0x03FFFFFFF8000000 ),
+ LONG2CHARS( 0x03FFFFFFFC000000 ),
+ LONG2CHARS( 0x03FFFFFFFE000000 ),
+ LONG2CHARS( 0x03FFFFFFFF000000 ),
+ LONG2CHARS( 0x03FFFFFFFF800000 ),
+ LONG2CHARS( 0x03FFFFFFFFC00000 ),
+ LONG2CHARS( 0x03FFFFFFFFE00000 ),
+ LONG2CHARS( 0x03FFFFFFFFF00000 ),
+ LONG2CHARS( 0x03FFFFFFFFF80000 ),
+ LONG2CHARS( 0x03FFFFFFFFFC0000 ),
+ LONG2CHARS( 0x03FFFFFFFFFE0000 ),
+ LONG2CHARS( 0x03FFFFFFFFFF0000 ),
+ LONG2CHARS( 0x03FFFFFFFFFF8000 ),
+ LONG2CHARS( 0x03FFFFFFFFFFC000 ),
+ LONG2CHARS( 0x03FFFFFFFFFFE000 ),
+ LONG2CHARS( 0x03FFFFFFFFFFF000 ),
+ LONG2CHARS( 0x03FFFFFFFFFFF800 ),
+ LONG2CHARS( 0x03FFFFFFFFFFFC00 ),
+ LONG2CHARS( 0x03FFFFFFFFFFFE00 ),
+ LONG2CHARS( 0x03FFFFFFFFFFFF00 ),
+ LONG2CHARS( 0x03FFFFFFFFFFFF80 ),
+ LONG2CHARS( 0x03FFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x03FFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x03FFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x03FFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x03FFFFFFFFFFFFFC ),
+ LONG2CHARS( 0x03FFFFFFFFFFFFFE ),
+ LONG2CHARS( 0x03FFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0100000000000000 ),
+ LONG2CHARS( 0x0180000000000000 ),
+ LONG2CHARS( 0x01C0000000000000 ),
+ LONG2CHARS( 0x01E0000000000000 ),
+ LONG2CHARS( 0x01F0000000000000 ),
+ LONG2CHARS( 0x01F8000000000000 ),
+ LONG2CHARS( 0x01FC000000000000 ),
+ LONG2CHARS( 0x01FE000000000000 ),
+ LONG2CHARS( 0x01FF000000000000 ),
+ LONG2CHARS( 0x01FF800000000000 ),
+ LONG2CHARS( 0x01FFC00000000000 ),
+ LONG2CHARS( 0x01FFE00000000000 ),
+ LONG2CHARS( 0x01FFF00000000000 ),
+ LONG2CHARS( 0x01FFF80000000000 ),
+ LONG2CHARS( 0x01FFFC0000000000 ),
+ LONG2CHARS( 0x01FFFE0000000000 ),
+ LONG2CHARS( 0x01FFFF0000000000 ),
+ LONG2CHARS( 0x01FFFF8000000000 ),
+ LONG2CHARS( 0x01FFFFC000000000 ),
+ LONG2CHARS( 0x01FFFFE000000000 ),
+ LONG2CHARS( 0x01FFFFF000000000 ),
+ LONG2CHARS( 0x01FFFFF800000000 ),
+ LONG2CHARS( 0x01FFFFFC00000000 ),
+ LONG2CHARS( 0x01FFFFFE00000000 ),
+ LONG2CHARS( 0x01FFFFFF00000000 ),
+ LONG2CHARS( 0x01FFFFFF80000000 ),
+ LONG2CHARS( 0x01FFFFFFC0000000 ),
+ LONG2CHARS( 0x01FFFFFFE0000000 ),
+ LONG2CHARS( 0x01FFFFFFF0000000 ),
+ LONG2CHARS( 0x01FFFFFFF8000000 ),
+ LONG2CHARS( 0x01FFFFFFFC000000 ),
+ LONG2CHARS( 0x01FFFFFFFE000000 ),
+ LONG2CHARS( 0x01FFFFFFFF000000 ),
+ LONG2CHARS( 0x01FFFFFFFF800000 ),
+ LONG2CHARS( 0x01FFFFFFFFC00000 ),
+ LONG2CHARS( 0x01FFFFFFFFE00000 ),
+ LONG2CHARS( 0x01FFFFFFFFF00000 ),
+ LONG2CHARS( 0x01FFFFFFFFF80000 ),
+ LONG2CHARS( 0x01FFFFFFFFFC0000 ),
+ LONG2CHARS( 0x01FFFFFFFFFE0000 ),
+ LONG2CHARS( 0x01FFFFFFFFFF0000 ),
+ LONG2CHARS( 0x01FFFFFFFFFF8000 ),
+ LONG2CHARS( 0x01FFFFFFFFFFC000 ),
+ LONG2CHARS( 0x01FFFFFFFFFFE000 ),
+ LONG2CHARS( 0x01FFFFFFFFFFF000 ),
+ LONG2CHARS( 0x01FFFFFFFFFFF800 ),
+ LONG2CHARS( 0x01FFFFFFFFFFFC00 ),
+ LONG2CHARS( 0x01FFFFFFFFFFFE00 ),
+ LONG2CHARS( 0x01FFFFFFFFFFFF00 ),
+ LONG2CHARS( 0x01FFFFFFFFFFFF80 ),
+ LONG2CHARS( 0x01FFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x01FFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x01FFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x01FFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x01FFFFFFFFFFFFFC ),
+ LONG2CHARS( 0x01FFFFFFFFFFFFFE ),
+ LONG2CHARS( 0x01FFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0080000000000000 ),
+ LONG2CHARS( 0x00C0000000000000 ),
+ LONG2CHARS( 0x00E0000000000000 ),
+ LONG2CHARS( 0x00F0000000000000 ),
+ LONG2CHARS( 0x00F8000000000000 ),
+ LONG2CHARS( 0x00FC000000000000 ),
+ LONG2CHARS( 0x00FE000000000000 ),
+ LONG2CHARS( 0x00FF000000000000 ),
+ LONG2CHARS( 0x00FF800000000000 ),
+ LONG2CHARS( 0x00FFC00000000000 ),
+ LONG2CHARS( 0x00FFE00000000000 ),
+ LONG2CHARS( 0x00FFF00000000000 ),
+ LONG2CHARS( 0x00FFF80000000000 ),
+ LONG2CHARS( 0x00FFFC0000000000 ),
+ LONG2CHARS( 0x00FFFE0000000000 ),
+ LONG2CHARS( 0x00FFFF0000000000 ),
+ LONG2CHARS( 0x00FFFF8000000000 ),
+ LONG2CHARS( 0x00FFFFC000000000 ),
+ LONG2CHARS( 0x00FFFFE000000000 ),
+ LONG2CHARS( 0x00FFFFF000000000 ),
+ LONG2CHARS( 0x00FFFFF800000000 ),
+ LONG2CHARS( 0x00FFFFFC00000000 ),
+ LONG2CHARS( 0x00FFFFFE00000000 ),
+ LONG2CHARS( 0x00FFFFFF00000000 ),
+ LONG2CHARS( 0x00FFFFFF80000000 ),
+ LONG2CHARS( 0x00FFFFFFC0000000 ),
+ LONG2CHARS( 0x00FFFFFFE0000000 ),
+ LONG2CHARS( 0x00FFFFFFF0000000 ),
+ LONG2CHARS( 0x00FFFFFFF8000000 ),
+ LONG2CHARS( 0x00FFFFFFFC000000 ),
+ LONG2CHARS( 0x00FFFFFFFE000000 ),
+ LONG2CHARS( 0x00FFFFFFFF000000 ),
+ LONG2CHARS( 0x00FFFFFFFF800000 ),
+ LONG2CHARS( 0x00FFFFFFFFC00000 ),
+ LONG2CHARS( 0x00FFFFFFFFE00000 ),
+ LONG2CHARS( 0x00FFFFFFFFF00000 ),
+ LONG2CHARS( 0x00FFFFFFFFF80000 ),
+ LONG2CHARS( 0x00FFFFFFFFFC0000 ),
+ LONG2CHARS( 0x00FFFFFFFFFE0000 ),
+ LONG2CHARS( 0x00FFFFFFFFFF0000 ),
+ LONG2CHARS( 0x00FFFFFFFFFF8000 ),
+ LONG2CHARS( 0x00FFFFFFFFFFC000 ),
+ LONG2CHARS( 0x00FFFFFFFFFFE000 ),
+ LONG2CHARS( 0x00FFFFFFFFFFF000 ),
+ LONG2CHARS( 0x00FFFFFFFFFFF800 ),
+ LONG2CHARS( 0x00FFFFFFFFFFFC00 ),
+ LONG2CHARS( 0x00FFFFFFFFFFFE00 ),
+ LONG2CHARS( 0x00FFFFFFFFFFFF00 ),
+ LONG2CHARS( 0x00FFFFFFFFFFFF80 ),
+ LONG2CHARS( 0x00FFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x00FFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x00FFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x00FFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x00FFFFFFFFFFFFFC ),
+ LONG2CHARS( 0x00FFFFFFFFFFFFFE ),
+ LONG2CHARS( 0x00FFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0040000000000000 ),
+ LONG2CHARS( 0x0060000000000000 ),
+ LONG2CHARS( 0x0070000000000000 ),
+ LONG2CHARS( 0x0078000000000000 ),
+ LONG2CHARS( 0x007C000000000000 ),
+ LONG2CHARS( 0x007E000000000000 ),
+ LONG2CHARS( 0x007F000000000000 ),
+ LONG2CHARS( 0x007F800000000000 ),
+ LONG2CHARS( 0x007FC00000000000 ),
+ LONG2CHARS( 0x007FE00000000000 ),
+ LONG2CHARS( 0x007FF00000000000 ),
+ LONG2CHARS( 0x007FF80000000000 ),
+ LONG2CHARS( 0x007FFC0000000000 ),
+ LONG2CHARS( 0x007FFE0000000000 ),
+ LONG2CHARS( 0x007FFF0000000000 ),
+ LONG2CHARS( 0x007FFF8000000000 ),
+ LONG2CHARS( 0x007FFFC000000000 ),
+ LONG2CHARS( 0x007FFFE000000000 ),
+ LONG2CHARS( 0x007FFFF000000000 ),
+ LONG2CHARS( 0x007FFFF800000000 ),
+ LONG2CHARS( 0x007FFFFC00000000 ),
+ LONG2CHARS( 0x007FFFFE00000000 ),
+ LONG2CHARS( 0x007FFFFF00000000 ),
+ LONG2CHARS( 0x007FFFFF80000000 ),
+ LONG2CHARS( 0x007FFFFFC0000000 ),
+ LONG2CHARS( 0x007FFFFFE0000000 ),
+ LONG2CHARS( 0x007FFFFFF0000000 ),
+ LONG2CHARS( 0x007FFFFFF8000000 ),
+ LONG2CHARS( 0x007FFFFFFC000000 ),
+ LONG2CHARS( 0x007FFFFFFE000000 ),
+ LONG2CHARS( 0x007FFFFFFF000000 ),
+ LONG2CHARS( 0x007FFFFFFF800000 ),
+ LONG2CHARS( 0x007FFFFFFFC00000 ),
+ LONG2CHARS( 0x007FFFFFFFE00000 ),
+ LONG2CHARS( 0x007FFFFFFFF00000 ),
+ LONG2CHARS( 0x007FFFFFFFF80000 ),
+ LONG2CHARS( 0x007FFFFFFFFC0000 ),
+ LONG2CHARS( 0x007FFFFFFFFE0000 ),
+ LONG2CHARS( 0x007FFFFFFFFF0000 ),
+ LONG2CHARS( 0x007FFFFFFFFF8000 ),
+ LONG2CHARS( 0x007FFFFFFFFFC000 ),
+ LONG2CHARS( 0x007FFFFFFFFFE000 ),
+ LONG2CHARS( 0x007FFFFFFFFFF000 ),
+ LONG2CHARS( 0x007FFFFFFFFFF800 ),
+ LONG2CHARS( 0x007FFFFFFFFFFC00 ),
+ LONG2CHARS( 0x007FFFFFFFFFFE00 ),
+ LONG2CHARS( 0x007FFFFFFFFFFF00 ),
+ LONG2CHARS( 0x007FFFFFFFFFFF80 ),
+ LONG2CHARS( 0x007FFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x007FFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x007FFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x007FFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x007FFFFFFFFFFFFC ),
+ LONG2CHARS( 0x007FFFFFFFFFFFFE ),
+ LONG2CHARS( 0x007FFFFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0020000000000000 ),
+ LONG2CHARS( 0x0030000000000000 ),
+ LONG2CHARS( 0x0038000000000000 ),
+ LONG2CHARS( 0x003C000000000000 ),
+ LONG2CHARS( 0x003E000000000000 ),
+ LONG2CHARS( 0x003F000000000000 ),
+ LONG2CHARS( 0x003F800000000000 ),
+ LONG2CHARS( 0x003FC00000000000 ),
+ LONG2CHARS( 0x003FE00000000000 ),
+ LONG2CHARS( 0x003FF00000000000 ),
+ LONG2CHARS( 0x003FF80000000000 ),
+ LONG2CHARS( 0x003FFC0000000000 ),
+ LONG2CHARS( 0x003FFE0000000000 ),
+ LONG2CHARS( 0x003FFF0000000000 ),
+ LONG2CHARS( 0x003FFF8000000000 ),
+ LONG2CHARS( 0x003FFFC000000000 ),
+ LONG2CHARS( 0x003FFFE000000000 ),
+ LONG2CHARS( 0x003FFFF000000000 ),
+ LONG2CHARS( 0x003FFFF800000000 ),
+ LONG2CHARS( 0x003FFFFC00000000 ),
+ LONG2CHARS( 0x003FFFFE00000000 ),
+ LONG2CHARS( 0x003FFFFF00000000 ),
+ LONG2CHARS( 0x003FFFFF80000000 ),
+ LONG2CHARS( 0x003FFFFFC0000000 ),
+ LONG2CHARS( 0x003FFFFFE0000000 ),
+ LONG2CHARS( 0x003FFFFFF0000000 ),
+ LONG2CHARS( 0x003FFFFFF8000000 ),
+ LONG2CHARS( 0x003FFFFFFC000000 ),
+ LONG2CHARS( 0x003FFFFFFE000000 ),
+ LONG2CHARS( 0x003FFFFFFF000000 ),
+ LONG2CHARS( 0x003FFFFFFF800000 ),
+ LONG2CHARS( 0x003FFFFFFFC00000 ),
+ LONG2CHARS( 0x003FFFFFFFE00000 ),
+ LONG2CHARS( 0x003FFFFFFFF00000 ),
+ LONG2CHARS( 0x003FFFFFFFF80000 ),
+ LONG2CHARS( 0x003FFFFFFFFC0000 ),
+ LONG2CHARS( 0x003FFFFFFFFE0000 ),
+ LONG2CHARS( 0x003FFFFFFFFF0000 ),
+ LONG2CHARS( 0x003FFFFFFFFF8000 ),
+ LONG2CHARS( 0x003FFFFFFFFFC000 ),
+ LONG2CHARS( 0x003FFFFFFFFFE000 ),
+ LONG2CHARS( 0x003FFFFFFFFFF000 ),
+ LONG2CHARS( 0x003FFFFFFFFFF800 ),
+ LONG2CHARS( 0x003FFFFFFFFFFC00 ),
+ LONG2CHARS( 0x003FFFFFFFFFFE00 ),
+ LONG2CHARS( 0x003FFFFFFFFFFF00 ),
+ LONG2CHARS( 0x003FFFFFFFFFFF80 ),
+ LONG2CHARS( 0x003FFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x003FFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x003FFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x003FFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x003FFFFFFFFFFFFC ),
+ LONG2CHARS( 0x003FFFFFFFFFFFFE ),
+ LONG2CHARS( 0x003FFFFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0010000000000000 ),
+ LONG2CHARS( 0x0018000000000000 ),
+ LONG2CHARS( 0x001C000000000000 ),
+ LONG2CHARS( 0x001E000000000000 ),
+ LONG2CHARS( 0x001F000000000000 ),
+ LONG2CHARS( 0x001F800000000000 ),
+ LONG2CHARS( 0x001FC00000000000 ),
+ LONG2CHARS( 0x001FE00000000000 ),
+ LONG2CHARS( 0x001FF00000000000 ),
+ LONG2CHARS( 0x001FF80000000000 ),
+ LONG2CHARS( 0x001FFC0000000000 ),
+ LONG2CHARS( 0x001FFE0000000000 ),
+ LONG2CHARS( 0x001FFF0000000000 ),
+ LONG2CHARS( 0x001FFF8000000000 ),
+ LONG2CHARS( 0x001FFFC000000000 ),
+ LONG2CHARS( 0x001FFFE000000000 ),
+ LONG2CHARS( 0x001FFFF000000000 ),
+ LONG2CHARS( 0x001FFFF800000000 ),
+ LONG2CHARS( 0x001FFFFC00000000 ),
+ LONG2CHARS( 0x001FFFFE00000000 ),
+ LONG2CHARS( 0x001FFFFF00000000 ),
+ LONG2CHARS( 0x001FFFFF80000000 ),
+ LONG2CHARS( 0x001FFFFFC0000000 ),
+ LONG2CHARS( 0x001FFFFFE0000000 ),
+ LONG2CHARS( 0x001FFFFFF0000000 ),
+ LONG2CHARS( 0x001FFFFFF8000000 ),
+ LONG2CHARS( 0x001FFFFFFC000000 ),
+ LONG2CHARS( 0x001FFFFFFE000000 ),
+ LONG2CHARS( 0x001FFFFFFF000000 ),
+ LONG2CHARS( 0x001FFFFFFF800000 ),
+ LONG2CHARS( 0x001FFFFFFFC00000 ),
+ LONG2CHARS( 0x001FFFFFFFE00000 ),
+ LONG2CHARS( 0x001FFFFFFFF00000 ),
+ LONG2CHARS( 0x001FFFFFFFF80000 ),
+ LONG2CHARS( 0x001FFFFFFFFC0000 ),
+ LONG2CHARS( 0x001FFFFFFFFE0000 ),
+ LONG2CHARS( 0x001FFFFFFFFF0000 ),
+ LONG2CHARS( 0x001FFFFFFFFF8000 ),
+ LONG2CHARS( 0x001FFFFFFFFFC000 ),
+ LONG2CHARS( 0x001FFFFFFFFFE000 ),
+ LONG2CHARS( 0x001FFFFFFFFFF000 ),
+ LONG2CHARS( 0x001FFFFFFFFFF800 ),
+ LONG2CHARS( 0x001FFFFFFFFFFC00 ),
+ LONG2CHARS( 0x001FFFFFFFFFFE00 ),
+ LONG2CHARS( 0x001FFFFFFFFFFF00 ),
+ LONG2CHARS( 0x001FFFFFFFFFFF80 ),
+ LONG2CHARS( 0x001FFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x001FFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x001FFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x001FFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x001FFFFFFFFFFFFC ),
+ LONG2CHARS( 0x001FFFFFFFFFFFFE ),
+ LONG2CHARS( 0x001FFFFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0008000000000000 ),
+ LONG2CHARS( 0x000C000000000000 ),
+ LONG2CHARS( 0x000E000000000000 ),
+ LONG2CHARS( 0x000F000000000000 ),
+ LONG2CHARS( 0x000F800000000000 ),
+ LONG2CHARS( 0x000FC00000000000 ),
+ LONG2CHARS( 0x000FE00000000000 ),
+ LONG2CHARS( 0x000FF00000000000 ),
+ LONG2CHARS( 0x000FF80000000000 ),
+ LONG2CHARS( 0x000FFC0000000000 ),
+ LONG2CHARS( 0x000FFE0000000000 ),
+ LONG2CHARS( 0x000FFF0000000000 ),
+ LONG2CHARS( 0x000FFF8000000000 ),
+ LONG2CHARS( 0x000FFFC000000000 ),
+ LONG2CHARS( 0x000FFFE000000000 ),
+ LONG2CHARS( 0x000FFFF000000000 ),
+ LONG2CHARS( 0x000FFFF800000000 ),
+ LONG2CHARS( 0x000FFFFC00000000 ),
+ LONG2CHARS( 0x000FFFFE00000000 ),
+ LONG2CHARS( 0x000FFFFF00000000 ),
+ LONG2CHARS( 0x000FFFFF80000000 ),
+ LONG2CHARS( 0x000FFFFFC0000000 ),
+ LONG2CHARS( 0x000FFFFFE0000000 ),
+ LONG2CHARS( 0x000FFFFFF0000000 ),
+ LONG2CHARS( 0x000FFFFFF8000000 ),
+ LONG2CHARS( 0x000FFFFFFC000000 ),
+ LONG2CHARS( 0x000FFFFFFE000000 ),
+ LONG2CHARS( 0x000FFFFFFF000000 ),
+ LONG2CHARS( 0x000FFFFFFF800000 ),
+ LONG2CHARS( 0x000FFFFFFFC00000 ),
+ LONG2CHARS( 0x000FFFFFFFE00000 ),
+ LONG2CHARS( 0x000FFFFFFFF00000 ),
+ LONG2CHARS( 0x000FFFFFFFF80000 ),
+ LONG2CHARS( 0x000FFFFFFFFC0000 ),
+ LONG2CHARS( 0x000FFFFFFFFE0000 ),
+ LONG2CHARS( 0x000FFFFFFFFF0000 ),
+ LONG2CHARS( 0x000FFFFFFFFF8000 ),
+ LONG2CHARS( 0x000FFFFFFFFFC000 ),
+ LONG2CHARS( 0x000FFFFFFFFFE000 ),
+ LONG2CHARS( 0x000FFFFFFFFFF000 ),
+ LONG2CHARS( 0x000FFFFFFFFFF800 ),
+ LONG2CHARS( 0x000FFFFFFFFFFC00 ),
+ LONG2CHARS( 0x000FFFFFFFFFFE00 ),
+ LONG2CHARS( 0x000FFFFFFFFFFF00 ),
+ LONG2CHARS( 0x000FFFFFFFFFFF80 ),
+ LONG2CHARS( 0x000FFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x000FFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x000FFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x000FFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x000FFFFFFFFFFFFC ),
+ LONG2CHARS( 0x000FFFFFFFFFFFFE ),
+ LONG2CHARS( 0x000FFFFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0004000000000000 ),
+ LONG2CHARS( 0x0006000000000000 ),
+ LONG2CHARS( 0x0007000000000000 ),
+ LONG2CHARS( 0x0007800000000000 ),
+ LONG2CHARS( 0x0007C00000000000 ),
+ LONG2CHARS( 0x0007E00000000000 ),
+ LONG2CHARS( 0x0007F00000000000 ),
+ LONG2CHARS( 0x0007F80000000000 ),
+ LONG2CHARS( 0x0007FC0000000000 ),
+ LONG2CHARS( 0x0007FE0000000000 ),
+ LONG2CHARS( 0x0007FF0000000000 ),
+ LONG2CHARS( 0x0007FF8000000000 ),
+ LONG2CHARS( 0x0007FFC000000000 ),
+ LONG2CHARS( 0x0007FFE000000000 ),
+ LONG2CHARS( 0x0007FFF000000000 ),
+ LONG2CHARS( 0x0007FFF800000000 ),
+ LONG2CHARS( 0x0007FFFC00000000 ),
+ LONG2CHARS( 0x0007FFFE00000000 ),
+ LONG2CHARS( 0x0007FFFF00000000 ),
+ LONG2CHARS( 0x0007FFFF80000000 ),
+ LONG2CHARS( 0x0007FFFFC0000000 ),
+ LONG2CHARS( 0x0007FFFFE0000000 ),
+ LONG2CHARS( 0x0007FFFFF0000000 ),
+ LONG2CHARS( 0x0007FFFFF8000000 ),
+ LONG2CHARS( 0x0007FFFFFC000000 ),
+ LONG2CHARS( 0x0007FFFFFE000000 ),
+ LONG2CHARS( 0x0007FFFFFF000000 ),
+ LONG2CHARS( 0x0007FFFFFF800000 ),
+ LONG2CHARS( 0x0007FFFFFFC00000 ),
+ LONG2CHARS( 0x0007FFFFFFE00000 ),
+ LONG2CHARS( 0x0007FFFFFFF00000 ),
+ LONG2CHARS( 0x0007FFFFFFF80000 ),
+ LONG2CHARS( 0x0007FFFFFFFC0000 ),
+ LONG2CHARS( 0x0007FFFFFFFE0000 ),
+ LONG2CHARS( 0x0007FFFFFFFF0000 ),
+ LONG2CHARS( 0x0007FFFFFFFF8000 ),
+ LONG2CHARS( 0x0007FFFFFFFFC000 ),
+ LONG2CHARS( 0x0007FFFFFFFFE000 ),
+ LONG2CHARS( 0x0007FFFFFFFFF000 ),
+ LONG2CHARS( 0x0007FFFFFFFFF800 ),
+ LONG2CHARS( 0x0007FFFFFFFFFC00 ),
+ LONG2CHARS( 0x0007FFFFFFFFFE00 ),
+ LONG2CHARS( 0x0007FFFFFFFFFF00 ),
+ LONG2CHARS( 0x0007FFFFFFFFFF80 ),
+ LONG2CHARS( 0x0007FFFFFFFFFFC0 ),
+ LONG2CHARS( 0x0007FFFFFFFFFFE0 ),
+ LONG2CHARS( 0x0007FFFFFFFFFFF0 ),
+ LONG2CHARS( 0x0007FFFFFFFFFFF8 ),
+ LONG2CHARS( 0x0007FFFFFFFFFFFC ),
+ LONG2CHARS( 0x0007FFFFFFFFFFFE ),
+ LONG2CHARS( 0x0007FFFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0002000000000000 ),
+ LONG2CHARS( 0x0003000000000000 ),
+ LONG2CHARS( 0x0003800000000000 ),
+ LONG2CHARS( 0x0003C00000000000 ),
+ LONG2CHARS( 0x0003E00000000000 ),
+ LONG2CHARS( 0x0003F00000000000 ),
+ LONG2CHARS( 0x0003F80000000000 ),
+ LONG2CHARS( 0x0003FC0000000000 ),
+ LONG2CHARS( 0x0003FE0000000000 ),
+ LONG2CHARS( 0x0003FF0000000000 ),
+ LONG2CHARS( 0x0003FF8000000000 ),
+ LONG2CHARS( 0x0003FFC000000000 ),
+ LONG2CHARS( 0x0003FFE000000000 ),
+ LONG2CHARS( 0x0003FFF000000000 ),
+ LONG2CHARS( 0x0003FFF800000000 ),
+ LONG2CHARS( 0x0003FFFC00000000 ),
+ LONG2CHARS( 0x0003FFFE00000000 ),
+ LONG2CHARS( 0x0003FFFF00000000 ),
+ LONG2CHARS( 0x0003FFFF80000000 ),
+ LONG2CHARS( 0x0003FFFFC0000000 ),
+ LONG2CHARS( 0x0003FFFFE0000000 ),
+ LONG2CHARS( 0x0003FFFFF0000000 ),
+ LONG2CHARS( 0x0003FFFFF8000000 ),
+ LONG2CHARS( 0x0003FFFFFC000000 ),
+ LONG2CHARS( 0x0003FFFFFE000000 ),
+ LONG2CHARS( 0x0003FFFFFF000000 ),
+ LONG2CHARS( 0x0003FFFFFF800000 ),
+ LONG2CHARS( 0x0003FFFFFFC00000 ),
+ LONG2CHARS( 0x0003FFFFFFE00000 ),
+ LONG2CHARS( 0x0003FFFFFFF00000 ),
+ LONG2CHARS( 0x0003FFFFFFF80000 ),
+ LONG2CHARS( 0x0003FFFFFFFC0000 ),
+ LONG2CHARS( 0x0003FFFFFFFE0000 ),
+ LONG2CHARS( 0x0003FFFFFFFF0000 ),
+ LONG2CHARS( 0x0003FFFFFFFF8000 ),
+ LONG2CHARS( 0x0003FFFFFFFFC000 ),
+ LONG2CHARS( 0x0003FFFFFFFFE000 ),
+ LONG2CHARS( 0x0003FFFFFFFFF000 ),
+ LONG2CHARS( 0x0003FFFFFFFFF800 ),
+ LONG2CHARS( 0x0003FFFFFFFFFC00 ),
+ LONG2CHARS( 0x0003FFFFFFFFFE00 ),
+ LONG2CHARS( 0x0003FFFFFFFFFF00 ),
+ LONG2CHARS( 0x0003FFFFFFFFFF80 ),
+ LONG2CHARS( 0x0003FFFFFFFFFFC0 ),
+ LONG2CHARS( 0x0003FFFFFFFFFFE0 ),
+ LONG2CHARS( 0x0003FFFFFFFFFFF0 ),
+ LONG2CHARS( 0x0003FFFFFFFFFFF8 ),
+ LONG2CHARS( 0x0003FFFFFFFFFFFC ),
+ LONG2CHARS( 0x0003FFFFFFFFFFFE ),
+ LONG2CHARS( 0x0003FFFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0001000000000000 ),
+ LONG2CHARS( 0x0001800000000000 ),
+ LONG2CHARS( 0x0001C00000000000 ),
+ LONG2CHARS( 0x0001E00000000000 ),
+ LONG2CHARS( 0x0001F00000000000 ),
+ LONG2CHARS( 0x0001F80000000000 ),
+ LONG2CHARS( 0x0001FC0000000000 ),
+ LONG2CHARS( 0x0001FE0000000000 ),
+ LONG2CHARS( 0x0001FF0000000000 ),
+ LONG2CHARS( 0x0001FF8000000000 ),
+ LONG2CHARS( 0x0001FFC000000000 ),
+ LONG2CHARS( 0x0001FFE000000000 ),
+ LONG2CHARS( 0x0001FFF000000000 ),
+ LONG2CHARS( 0x0001FFF800000000 ),
+ LONG2CHARS( 0x0001FFFC00000000 ),
+ LONG2CHARS( 0x0001FFFE00000000 ),
+ LONG2CHARS( 0x0001FFFF00000000 ),
+ LONG2CHARS( 0x0001FFFF80000000 ),
+ LONG2CHARS( 0x0001FFFFC0000000 ),
+ LONG2CHARS( 0x0001FFFFE0000000 ),
+ LONG2CHARS( 0x0001FFFFF0000000 ),
+ LONG2CHARS( 0x0001FFFFF8000000 ),
+ LONG2CHARS( 0x0001FFFFFC000000 ),
+ LONG2CHARS( 0x0001FFFFFE000000 ),
+ LONG2CHARS( 0x0001FFFFFF000000 ),
+ LONG2CHARS( 0x0001FFFFFF800000 ),
+ LONG2CHARS( 0x0001FFFFFFC00000 ),
+ LONG2CHARS( 0x0001FFFFFFE00000 ),
+ LONG2CHARS( 0x0001FFFFFFF00000 ),
+ LONG2CHARS( 0x0001FFFFFFF80000 ),
+ LONG2CHARS( 0x0001FFFFFFFC0000 ),
+ LONG2CHARS( 0x0001FFFFFFFE0000 ),
+ LONG2CHARS( 0x0001FFFFFFFF0000 ),
+ LONG2CHARS( 0x0001FFFFFFFF8000 ),
+ LONG2CHARS( 0x0001FFFFFFFFC000 ),
+ LONG2CHARS( 0x0001FFFFFFFFE000 ),
+ LONG2CHARS( 0x0001FFFFFFFFF000 ),
+ LONG2CHARS( 0x0001FFFFFFFFF800 ),
+ LONG2CHARS( 0x0001FFFFFFFFFC00 ),
+ LONG2CHARS( 0x0001FFFFFFFFFE00 ),
+ LONG2CHARS( 0x0001FFFFFFFFFF00 ),
+ LONG2CHARS( 0x0001FFFFFFFFFF80 ),
+ LONG2CHARS( 0x0001FFFFFFFFFFC0 ),
+ LONG2CHARS( 0x0001FFFFFFFFFFE0 ),
+ LONG2CHARS( 0x0001FFFFFFFFFFF0 ),
+ LONG2CHARS( 0x0001FFFFFFFFFFF8 ),
+ LONG2CHARS( 0x0001FFFFFFFFFFFC ),
+ LONG2CHARS( 0x0001FFFFFFFFFFFE ),
+ LONG2CHARS( 0x0001FFFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000800000000000 ),
+ LONG2CHARS( 0x0000C00000000000 ),
+ LONG2CHARS( 0x0000E00000000000 ),
+ LONG2CHARS( 0x0000F00000000000 ),
+ LONG2CHARS( 0x0000F80000000000 ),
+ LONG2CHARS( 0x0000FC0000000000 ),
+ LONG2CHARS( 0x0000FE0000000000 ),
+ LONG2CHARS( 0x0000FF0000000000 ),
+ LONG2CHARS( 0x0000FF8000000000 ),
+ LONG2CHARS( 0x0000FFC000000000 ),
+ LONG2CHARS( 0x0000FFE000000000 ),
+ LONG2CHARS( 0x0000FFF000000000 ),
+ LONG2CHARS( 0x0000FFF800000000 ),
+ LONG2CHARS( 0x0000FFFC00000000 ),
+ LONG2CHARS( 0x0000FFFE00000000 ),
+ LONG2CHARS( 0x0000FFFF00000000 ),
+ LONG2CHARS( 0x0000FFFF80000000 ),
+ LONG2CHARS( 0x0000FFFFC0000000 ),
+ LONG2CHARS( 0x0000FFFFE0000000 ),
+ LONG2CHARS( 0x0000FFFFF0000000 ),
+ LONG2CHARS( 0x0000FFFFF8000000 ),
+ LONG2CHARS( 0x0000FFFFFC000000 ),
+ LONG2CHARS( 0x0000FFFFFE000000 ),
+ LONG2CHARS( 0x0000FFFFFF000000 ),
+ LONG2CHARS( 0x0000FFFFFF800000 ),
+ LONG2CHARS( 0x0000FFFFFFC00000 ),
+ LONG2CHARS( 0x0000FFFFFFE00000 ),
+ LONG2CHARS( 0x0000FFFFFFF00000 ),
+ LONG2CHARS( 0x0000FFFFFFF80000 ),
+ LONG2CHARS( 0x0000FFFFFFFC0000 ),
+ LONG2CHARS( 0x0000FFFFFFFE0000 ),
+ LONG2CHARS( 0x0000FFFFFFFF0000 ),
+ LONG2CHARS( 0x0000FFFFFFFF8000 ),
+ LONG2CHARS( 0x0000FFFFFFFFC000 ),
+ LONG2CHARS( 0x0000FFFFFFFFE000 ),
+ LONG2CHARS( 0x0000FFFFFFFFF000 ),
+ LONG2CHARS( 0x0000FFFFFFFFF800 ),
+ LONG2CHARS( 0x0000FFFFFFFFFC00 ),
+ LONG2CHARS( 0x0000FFFFFFFFFE00 ),
+ LONG2CHARS( 0x0000FFFFFFFFFF00 ),
+ LONG2CHARS( 0x0000FFFFFFFFFF80 ),
+ LONG2CHARS( 0x0000FFFFFFFFFFC0 ),
+ LONG2CHARS( 0x0000FFFFFFFFFFE0 ),
+ LONG2CHARS( 0x0000FFFFFFFFFFF0 ),
+ LONG2CHARS( 0x0000FFFFFFFFFFF8 ),
+ LONG2CHARS( 0x0000FFFFFFFFFFFC ),
+ LONG2CHARS( 0x0000FFFFFFFFFFFE ),
+ LONG2CHARS( 0x0000FFFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000400000000000 ),
+ LONG2CHARS( 0x0000600000000000 ),
+ LONG2CHARS( 0x0000700000000000 ),
+ LONG2CHARS( 0x0000780000000000 ),
+ LONG2CHARS( 0x00007C0000000000 ),
+ LONG2CHARS( 0x00007E0000000000 ),
+ LONG2CHARS( 0x00007F0000000000 ),
+ LONG2CHARS( 0x00007F8000000000 ),
+ LONG2CHARS( 0x00007FC000000000 ),
+ LONG2CHARS( 0x00007FE000000000 ),
+ LONG2CHARS( 0x00007FF000000000 ),
+ LONG2CHARS( 0x00007FF800000000 ),
+ LONG2CHARS( 0x00007FFC00000000 ),
+ LONG2CHARS( 0x00007FFE00000000 ),
+ LONG2CHARS( 0x00007FFF00000000 ),
+ LONG2CHARS( 0x00007FFF80000000 ),
+ LONG2CHARS( 0x00007FFFC0000000 ),
+ LONG2CHARS( 0x00007FFFE0000000 ),
+ LONG2CHARS( 0x00007FFFF0000000 ),
+ LONG2CHARS( 0x00007FFFF8000000 ),
+ LONG2CHARS( 0x00007FFFFC000000 ),
+ LONG2CHARS( 0x00007FFFFE000000 ),
+ LONG2CHARS( 0x00007FFFFF000000 ),
+ LONG2CHARS( 0x00007FFFFF800000 ),
+ LONG2CHARS( 0x00007FFFFFC00000 ),
+ LONG2CHARS( 0x00007FFFFFE00000 ),
+ LONG2CHARS( 0x00007FFFFFF00000 ),
+ LONG2CHARS( 0x00007FFFFFF80000 ),
+ LONG2CHARS( 0x00007FFFFFFC0000 ),
+ LONG2CHARS( 0x00007FFFFFFE0000 ),
+ LONG2CHARS( 0x00007FFFFFFF0000 ),
+ LONG2CHARS( 0x00007FFFFFFF8000 ),
+ LONG2CHARS( 0x00007FFFFFFFC000 ),
+ LONG2CHARS( 0x00007FFFFFFFE000 ),
+ LONG2CHARS( 0x00007FFFFFFFF000 ),
+ LONG2CHARS( 0x00007FFFFFFFF800 ),
+ LONG2CHARS( 0x00007FFFFFFFFC00 ),
+ LONG2CHARS( 0x00007FFFFFFFFE00 ),
+ LONG2CHARS( 0x00007FFFFFFFFF00 ),
+ LONG2CHARS( 0x00007FFFFFFFFF80 ),
+ LONG2CHARS( 0x00007FFFFFFFFFC0 ),
+ LONG2CHARS( 0x00007FFFFFFFFFE0 ),
+ LONG2CHARS( 0x00007FFFFFFFFFF0 ),
+ LONG2CHARS( 0x00007FFFFFFFFFF8 ),
+ LONG2CHARS( 0x00007FFFFFFFFFFC ),
+ LONG2CHARS( 0x00007FFFFFFFFFFE ),
+ LONG2CHARS( 0x00007FFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000200000000000 ),
+ LONG2CHARS( 0x0000300000000000 ),
+ LONG2CHARS( 0x0000380000000000 ),
+ LONG2CHARS( 0x00003C0000000000 ),
+ LONG2CHARS( 0x00003E0000000000 ),
+ LONG2CHARS( 0x00003F0000000000 ),
+ LONG2CHARS( 0x00003F8000000000 ),
+ LONG2CHARS( 0x00003FC000000000 ),
+ LONG2CHARS( 0x00003FE000000000 ),
+ LONG2CHARS( 0x00003FF000000000 ),
+ LONG2CHARS( 0x00003FF800000000 ),
+ LONG2CHARS( 0x00003FFC00000000 ),
+ LONG2CHARS( 0x00003FFE00000000 ),
+ LONG2CHARS( 0x00003FFF00000000 ),
+ LONG2CHARS( 0x00003FFF80000000 ),
+ LONG2CHARS( 0x00003FFFC0000000 ),
+ LONG2CHARS( 0x00003FFFE0000000 ),
+ LONG2CHARS( 0x00003FFFF0000000 ),
+ LONG2CHARS( 0x00003FFFF8000000 ),
+ LONG2CHARS( 0x00003FFFFC000000 ),
+ LONG2CHARS( 0x00003FFFFE000000 ),
+ LONG2CHARS( 0x00003FFFFF000000 ),
+ LONG2CHARS( 0x00003FFFFF800000 ),
+ LONG2CHARS( 0x00003FFFFFC00000 ),
+ LONG2CHARS( 0x00003FFFFFE00000 ),
+ LONG2CHARS( 0x00003FFFFFF00000 ),
+ LONG2CHARS( 0x00003FFFFFF80000 ),
+ LONG2CHARS( 0x00003FFFFFFC0000 ),
+ LONG2CHARS( 0x00003FFFFFFE0000 ),
+ LONG2CHARS( 0x00003FFFFFFF0000 ),
+ LONG2CHARS( 0x00003FFFFFFF8000 ),
+ LONG2CHARS( 0x00003FFFFFFFC000 ),
+ LONG2CHARS( 0x00003FFFFFFFE000 ),
+ LONG2CHARS( 0x00003FFFFFFFF000 ),
+ LONG2CHARS( 0x00003FFFFFFFF800 ),
+ LONG2CHARS( 0x00003FFFFFFFFC00 ),
+ LONG2CHARS( 0x00003FFFFFFFFE00 ),
+ LONG2CHARS( 0x00003FFFFFFFFF00 ),
+ LONG2CHARS( 0x00003FFFFFFFFF80 ),
+ LONG2CHARS( 0x00003FFFFFFFFFC0 ),
+ LONG2CHARS( 0x00003FFFFFFFFFE0 ),
+ LONG2CHARS( 0x00003FFFFFFFFFF0 ),
+ LONG2CHARS( 0x00003FFFFFFFFFF8 ),
+ LONG2CHARS( 0x00003FFFFFFFFFFC ),
+ LONG2CHARS( 0x00003FFFFFFFFFFE ),
+ LONG2CHARS( 0x00003FFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000100000000000 ),
+ LONG2CHARS( 0x0000180000000000 ),
+ LONG2CHARS( 0x00001C0000000000 ),
+ LONG2CHARS( 0x00001E0000000000 ),
+ LONG2CHARS( 0x00001F0000000000 ),
+ LONG2CHARS( 0x00001F8000000000 ),
+ LONG2CHARS( 0x00001FC000000000 ),
+ LONG2CHARS( 0x00001FE000000000 ),
+ LONG2CHARS( 0x00001FF000000000 ),
+ LONG2CHARS( 0x00001FF800000000 ),
+ LONG2CHARS( 0x00001FFC00000000 ),
+ LONG2CHARS( 0x00001FFE00000000 ),
+ LONG2CHARS( 0x00001FFF00000000 ),
+ LONG2CHARS( 0x00001FFF80000000 ),
+ LONG2CHARS( 0x00001FFFC0000000 ),
+ LONG2CHARS( 0x00001FFFE0000000 ),
+ LONG2CHARS( 0x00001FFFF0000000 ),
+ LONG2CHARS( 0x00001FFFF8000000 ),
+ LONG2CHARS( 0x00001FFFFC000000 ),
+ LONG2CHARS( 0x00001FFFFE000000 ),
+ LONG2CHARS( 0x00001FFFFF000000 ),
+ LONG2CHARS( 0x00001FFFFF800000 ),
+ LONG2CHARS( 0x00001FFFFFC00000 ),
+ LONG2CHARS( 0x00001FFFFFE00000 ),
+ LONG2CHARS( 0x00001FFFFFF00000 ),
+ LONG2CHARS( 0x00001FFFFFF80000 ),
+ LONG2CHARS( 0x00001FFFFFFC0000 ),
+ LONG2CHARS( 0x00001FFFFFFE0000 ),
+ LONG2CHARS( 0x00001FFFFFFF0000 ),
+ LONG2CHARS( 0x00001FFFFFFF8000 ),
+ LONG2CHARS( 0x00001FFFFFFFC000 ),
+ LONG2CHARS( 0x00001FFFFFFFE000 ),
+ LONG2CHARS( 0x00001FFFFFFFF000 ),
+ LONG2CHARS( 0x00001FFFFFFFF800 ),
+ LONG2CHARS( 0x00001FFFFFFFFC00 ),
+ LONG2CHARS( 0x00001FFFFFFFFE00 ),
+ LONG2CHARS( 0x00001FFFFFFFFF00 ),
+ LONG2CHARS( 0x00001FFFFFFFFF80 ),
+ LONG2CHARS( 0x00001FFFFFFFFFC0 ),
+ LONG2CHARS( 0x00001FFFFFFFFFE0 ),
+ LONG2CHARS( 0x00001FFFFFFFFFF0 ),
+ LONG2CHARS( 0x00001FFFFFFFFFF8 ),
+ LONG2CHARS( 0x00001FFFFFFFFFFC ),
+ LONG2CHARS( 0x00001FFFFFFFFFFE ),
+ LONG2CHARS( 0x00001FFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000080000000000 ),
+ LONG2CHARS( 0x00000C0000000000 ),
+ LONG2CHARS( 0x00000E0000000000 ),
+ LONG2CHARS( 0x00000F0000000000 ),
+ LONG2CHARS( 0x00000F8000000000 ),
+ LONG2CHARS( 0x00000FC000000000 ),
+ LONG2CHARS( 0x00000FE000000000 ),
+ LONG2CHARS( 0x00000FF000000000 ),
+ LONG2CHARS( 0x00000FF800000000 ),
+ LONG2CHARS( 0x00000FFC00000000 ),
+ LONG2CHARS( 0x00000FFE00000000 ),
+ LONG2CHARS( 0x00000FFF00000000 ),
+ LONG2CHARS( 0x00000FFF80000000 ),
+ LONG2CHARS( 0x00000FFFC0000000 ),
+ LONG2CHARS( 0x00000FFFE0000000 ),
+ LONG2CHARS( 0x00000FFFF0000000 ),
+ LONG2CHARS( 0x00000FFFF8000000 ),
+ LONG2CHARS( 0x00000FFFFC000000 ),
+ LONG2CHARS( 0x00000FFFFE000000 ),
+ LONG2CHARS( 0x00000FFFFF000000 ),
+ LONG2CHARS( 0x00000FFFFF800000 ),
+ LONG2CHARS( 0x00000FFFFFC00000 ),
+ LONG2CHARS( 0x00000FFFFFE00000 ),
+ LONG2CHARS( 0x00000FFFFFF00000 ),
+ LONG2CHARS( 0x00000FFFFFF80000 ),
+ LONG2CHARS( 0x00000FFFFFFC0000 ),
+ LONG2CHARS( 0x00000FFFFFFE0000 ),
+ LONG2CHARS( 0x00000FFFFFFF0000 ),
+ LONG2CHARS( 0x00000FFFFFFF8000 ),
+ LONG2CHARS( 0x00000FFFFFFFC000 ),
+ LONG2CHARS( 0x00000FFFFFFFE000 ),
+ LONG2CHARS( 0x00000FFFFFFFF000 ),
+ LONG2CHARS( 0x00000FFFFFFFF800 ),
+ LONG2CHARS( 0x00000FFFFFFFFC00 ),
+ LONG2CHARS( 0x00000FFFFFFFFE00 ),
+ LONG2CHARS( 0x00000FFFFFFFFF00 ),
+ LONG2CHARS( 0x00000FFFFFFFFF80 ),
+ LONG2CHARS( 0x00000FFFFFFFFFC0 ),
+ LONG2CHARS( 0x00000FFFFFFFFFE0 ),
+ LONG2CHARS( 0x00000FFFFFFFFFF0 ),
+ LONG2CHARS( 0x00000FFFFFFFFFF8 ),
+ LONG2CHARS( 0x00000FFFFFFFFFFC ),
+ LONG2CHARS( 0x00000FFFFFFFFFFE ),
+ LONG2CHARS( 0x00000FFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000040000000000 ),
+ LONG2CHARS( 0x0000060000000000 ),
+ LONG2CHARS( 0x0000070000000000 ),
+ LONG2CHARS( 0x0000078000000000 ),
+ LONG2CHARS( 0x000007C000000000 ),
+ LONG2CHARS( 0x000007E000000000 ),
+ LONG2CHARS( 0x000007F000000000 ),
+ LONG2CHARS( 0x000007F800000000 ),
+ LONG2CHARS( 0x000007FC00000000 ),
+ LONG2CHARS( 0x000007FE00000000 ),
+ LONG2CHARS( 0x000007FF00000000 ),
+ LONG2CHARS( 0x000007FF80000000 ),
+ LONG2CHARS( 0x000007FFC0000000 ),
+ LONG2CHARS( 0x000007FFE0000000 ),
+ LONG2CHARS( 0x000007FFF0000000 ),
+ LONG2CHARS( 0x000007FFF8000000 ),
+ LONG2CHARS( 0x000007FFFC000000 ),
+ LONG2CHARS( 0x000007FFFE000000 ),
+ LONG2CHARS( 0x000007FFFF000000 ),
+ LONG2CHARS( 0x000007FFFF800000 ),
+ LONG2CHARS( 0x000007FFFFC00000 ),
+ LONG2CHARS( 0x000007FFFFE00000 ),
+ LONG2CHARS( 0x000007FFFFF00000 ),
+ LONG2CHARS( 0x000007FFFFF80000 ),
+ LONG2CHARS( 0x000007FFFFFC0000 ),
+ LONG2CHARS( 0x000007FFFFFE0000 ),
+ LONG2CHARS( 0x000007FFFFFF0000 ),
+ LONG2CHARS( 0x000007FFFFFF8000 ),
+ LONG2CHARS( 0x000007FFFFFFC000 ),
+ LONG2CHARS( 0x000007FFFFFFE000 ),
+ LONG2CHARS( 0x000007FFFFFFF000 ),
+ LONG2CHARS( 0x000007FFFFFFF800 ),
+ LONG2CHARS( 0x000007FFFFFFFC00 ),
+ LONG2CHARS( 0x000007FFFFFFFE00 ),
+ LONG2CHARS( 0x000007FFFFFFFF00 ),
+ LONG2CHARS( 0x000007FFFFFFFF80 ),
+ LONG2CHARS( 0x000007FFFFFFFFC0 ),
+ LONG2CHARS( 0x000007FFFFFFFFE0 ),
+ LONG2CHARS( 0x000007FFFFFFFFF0 ),
+ LONG2CHARS( 0x000007FFFFFFFFF8 ),
+ LONG2CHARS( 0x000007FFFFFFFFFC ),
+ LONG2CHARS( 0x000007FFFFFFFFFE ),
+ LONG2CHARS( 0x000007FFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000020000000000 ),
+ LONG2CHARS( 0x0000030000000000 ),
+ LONG2CHARS( 0x0000038000000000 ),
+ LONG2CHARS( 0x000003C000000000 ),
+ LONG2CHARS( 0x000003E000000000 ),
+ LONG2CHARS( 0x000003F000000000 ),
+ LONG2CHARS( 0x000003F800000000 ),
+ LONG2CHARS( 0x000003FC00000000 ),
+ LONG2CHARS( 0x000003FE00000000 ),
+ LONG2CHARS( 0x000003FF00000000 ),
+ LONG2CHARS( 0x000003FF80000000 ),
+ LONG2CHARS( 0x000003FFC0000000 ),
+ LONG2CHARS( 0x000003FFE0000000 ),
+ LONG2CHARS( 0x000003FFF0000000 ),
+ LONG2CHARS( 0x000003FFF8000000 ),
+ LONG2CHARS( 0x000003FFFC000000 ),
+ LONG2CHARS( 0x000003FFFE000000 ),
+ LONG2CHARS( 0x000003FFFF000000 ),
+ LONG2CHARS( 0x000003FFFF800000 ),
+ LONG2CHARS( 0x000003FFFFC00000 ),
+ LONG2CHARS( 0x000003FFFFE00000 ),
+ LONG2CHARS( 0x000003FFFFF00000 ),
+ LONG2CHARS( 0x000003FFFFF80000 ),
+ LONG2CHARS( 0x000003FFFFFC0000 ),
+ LONG2CHARS( 0x000003FFFFFE0000 ),
+ LONG2CHARS( 0x000003FFFFFF0000 ),
+ LONG2CHARS( 0x000003FFFFFF8000 ),
+ LONG2CHARS( 0x000003FFFFFFC000 ),
+ LONG2CHARS( 0x000003FFFFFFE000 ),
+ LONG2CHARS( 0x000003FFFFFFF000 ),
+ LONG2CHARS( 0x000003FFFFFFF800 ),
+ LONG2CHARS( 0x000003FFFFFFFC00 ),
+ LONG2CHARS( 0x000003FFFFFFFE00 ),
+ LONG2CHARS( 0x000003FFFFFFFF00 ),
+ LONG2CHARS( 0x000003FFFFFFFF80 ),
+ LONG2CHARS( 0x000003FFFFFFFFC0 ),
+ LONG2CHARS( 0x000003FFFFFFFFE0 ),
+ LONG2CHARS( 0x000003FFFFFFFFF0 ),
+ LONG2CHARS( 0x000003FFFFFFFFF8 ),
+ LONG2CHARS( 0x000003FFFFFFFFFC ),
+ LONG2CHARS( 0x000003FFFFFFFFFE ),
+ LONG2CHARS( 0x000003FFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000010000000000 ),
+ LONG2CHARS( 0x0000018000000000 ),
+ LONG2CHARS( 0x000001C000000000 ),
+ LONG2CHARS( 0x000001E000000000 ),
+ LONG2CHARS( 0x000001F000000000 ),
+ LONG2CHARS( 0x000001F800000000 ),
+ LONG2CHARS( 0x000001FC00000000 ),
+ LONG2CHARS( 0x000001FE00000000 ),
+ LONG2CHARS( 0x000001FF00000000 ),
+ LONG2CHARS( 0x000001FF80000000 ),
+ LONG2CHARS( 0x000001FFC0000000 ),
+ LONG2CHARS( 0x000001FFE0000000 ),
+ LONG2CHARS( 0x000001FFF0000000 ),
+ LONG2CHARS( 0x000001FFF8000000 ),
+ LONG2CHARS( 0x000001FFFC000000 ),
+ LONG2CHARS( 0x000001FFFE000000 ),
+ LONG2CHARS( 0x000001FFFF000000 ),
+ LONG2CHARS( 0x000001FFFF800000 ),
+ LONG2CHARS( 0x000001FFFFC00000 ),
+ LONG2CHARS( 0x000001FFFFE00000 ),
+ LONG2CHARS( 0x000001FFFFF00000 ),
+ LONG2CHARS( 0x000001FFFFF80000 ),
+ LONG2CHARS( 0x000001FFFFFC0000 ),
+ LONG2CHARS( 0x000001FFFFFE0000 ),
+ LONG2CHARS( 0x000001FFFFFF0000 ),
+ LONG2CHARS( 0x000001FFFFFF8000 ),
+ LONG2CHARS( 0x000001FFFFFFC000 ),
+ LONG2CHARS( 0x000001FFFFFFE000 ),
+ LONG2CHARS( 0x000001FFFFFFF000 ),
+ LONG2CHARS( 0x000001FFFFFFF800 ),
+ LONG2CHARS( 0x000001FFFFFFFC00 ),
+ LONG2CHARS( 0x000001FFFFFFFE00 ),
+ LONG2CHARS( 0x000001FFFFFFFF00 ),
+ LONG2CHARS( 0x000001FFFFFFFF80 ),
+ LONG2CHARS( 0x000001FFFFFFFFC0 ),
+ LONG2CHARS( 0x000001FFFFFFFFE0 ),
+ LONG2CHARS( 0x000001FFFFFFFFF0 ),
+ LONG2CHARS( 0x000001FFFFFFFFF8 ),
+ LONG2CHARS( 0x000001FFFFFFFFFC ),
+ LONG2CHARS( 0x000001FFFFFFFFFE ),
+ LONG2CHARS( 0x000001FFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000008000000000 ),
+ LONG2CHARS( 0x000000C000000000 ),
+ LONG2CHARS( 0x000000E000000000 ),
+ LONG2CHARS( 0x000000F000000000 ),
+ LONG2CHARS( 0x000000F800000000 ),
+ LONG2CHARS( 0x000000FC00000000 ),
+ LONG2CHARS( 0x000000FE00000000 ),
+ LONG2CHARS( 0x000000FF00000000 ),
+ LONG2CHARS( 0x000000FF80000000 ),
+ LONG2CHARS( 0x000000FFC0000000 ),
+ LONG2CHARS( 0x000000FFE0000000 ),
+ LONG2CHARS( 0x000000FFF0000000 ),
+ LONG2CHARS( 0x000000FFF8000000 ),
+ LONG2CHARS( 0x000000FFFC000000 ),
+ LONG2CHARS( 0x000000FFFE000000 ),
+ LONG2CHARS( 0x000000FFFF000000 ),
+ LONG2CHARS( 0x000000FFFF800000 ),
+ LONG2CHARS( 0x000000FFFFC00000 ),
+ LONG2CHARS( 0x000000FFFFE00000 ),
+ LONG2CHARS( 0x000000FFFFF00000 ),
+ LONG2CHARS( 0x000000FFFFF80000 ),
+ LONG2CHARS( 0x000000FFFFFC0000 ),
+ LONG2CHARS( 0x000000FFFFFE0000 ),
+ LONG2CHARS( 0x000000FFFFFF0000 ),
+ LONG2CHARS( 0x000000FFFFFF8000 ),
+ LONG2CHARS( 0x000000FFFFFFC000 ),
+ LONG2CHARS( 0x000000FFFFFFE000 ),
+ LONG2CHARS( 0x000000FFFFFFF000 ),
+ LONG2CHARS( 0x000000FFFFFFF800 ),
+ LONG2CHARS( 0x000000FFFFFFFC00 ),
+ LONG2CHARS( 0x000000FFFFFFFE00 ),
+ LONG2CHARS( 0x000000FFFFFFFF00 ),
+ LONG2CHARS( 0x000000FFFFFFFF80 ),
+ LONG2CHARS( 0x000000FFFFFFFFC0 ),
+ LONG2CHARS( 0x000000FFFFFFFFE0 ),
+ LONG2CHARS( 0x000000FFFFFFFFF0 ),
+ LONG2CHARS( 0x000000FFFFFFFFF8 ),
+ LONG2CHARS( 0x000000FFFFFFFFFC ),
+ LONG2CHARS( 0x000000FFFFFFFFFE ),
+ LONG2CHARS( 0x000000FFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000004000000000 ),
+ LONG2CHARS( 0x0000006000000000 ),
+ LONG2CHARS( 0x0000007000000000 ),
+ LONG2CHARS( 0x0000007800000000 ),
+ LONG2CHARS( 0x0000007C00000000 ),
+ LONG2CHARS( 0x0000007E00000000 ),
+ LONG2CHARS( 0x0000007F00000000 ),
+ LONG2CHARS( 0x0000007F80000000 ),
+ LONG2CHARS( 0x0000007FC0000000 ),
+ LONG2CHARS( 0x0000007FE0000000 ),
+ LONG2CHARS( 0x0000007FF0000000 ),
+ LONG2CHARS( 0x0000007FF8000000 ),
+ LONG2CHARS( 0x0000007FFC000000 ),
+ LONG2CHARS( 0x0000007FFE000000 ),
+ LONG2CHARS( 0x0000007FFF000000 ),
+ LONG2CHARS( 0x0000007FFF800000 ),
+ LONG2CHARS( 0x0000007FFFC00000 ),
+ LONG2CHARS( 0x0000007FFFE00000 ),
+ LONG2CHARS( 0x0000007FFFF00000 ),
+ LONG2CHARS( 0x0000007FFFF80000 ),
+ LONG2CHARS( 0x0000007FFFFC0000 ),
+ LONG2CHARS( 0x0000007FFFFE0000 ),
+ LONG2CHARS( 0x0000007FFFFF0000 ),
+ LONG2CHARS( 0x0000007FFFFF8000 ),
+ LONG2CHARS( 0x0000007FFFFFC000 ),
+ LONG2CHARS( 0x0000007FFFFFE000 ),
+ LONG2CHARS( 0x0000007FFFFFF000 ),
+ LONG2CHARS( 0x0000007FFFFFF800 ),
+ LONG2CHARS( 0x0000007FFFFFFC00 ),
+ LONG2CHARS( 0x0000007FFFFFFE00 ),
+ LONG2CHARS( 0x0000007FFFFFFF00 ),
+ LONG2CHARS( 0x0000007FFFFFFF80 ),
+ LONG2CHARS( 0x0000007FFFFFFFC0 ),
+ LONG2CHARS( 0x0000007FFFFFFFE0 ),
+ LONG2CHARS( 0x0000007FFFFFFFF0 ),
+ LONG2CHARS( 0x0000007FFFFFFFF8 ),
+ LONG2CHARS( 0x0000007FFFFFFFFC ),
+ LONG2CHARS( 0x0000007FFFFFFFFE ),
+ LONG2CHARS( 0x0000007FFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000002000000000 ),
+ LONG2CHARS( 0x0000003000000000 ),
+ LONG2CHARS( 0x0000003800000000 ),
+ LONG2CHARS( 0x0000003C00000000 ),
+ LONG2CHARS( 0x0000003E00000000 ),
+ LONG2CHARS( 0x0000003F00000000 ),
+ LONG2CHARS( 0x0000003F80000000 ),
+ LONG2CHARS( 0x0000003FC0000000 ),
+ LONG2CHARS( 0x0000003FE0000000 ),
+ LONG2CHARS( 0x0000003FF0000000 ),
+ LONG2CHARS( 0x0000003FF8000000 ),
+ LONG2CHARS( 0x0000003FFC000000 ),
+ LONG2CHARS( 0x0000003FFE000000 ),
+ LONG2CHARS( 0x0000003FFF000000 ),
+ LONG2CHARS( 0x0000003FFF800000 ),
+ LONG2CHARS( 0x0000003FFFC00000 ),
+ LONG2CHARS( 0x0000003FFFE00000 ),
+ LONG2CHARS( 0x0000003FFFF00000 ),
+ LONG2CHARS( 0x0000003FFFF80000 ),
+ LONG2CHARS( 0x0000003FFFFC0000 ),
+ LONG2CHARS( 0x0000003FFFFE0000 ),
+ LONG2CHARS( 0x0000003FFFFF0000 ),
+ LONG2CHARS( 0x0000003FFFFF8000 ),
+ LONG2CHARS( 0x0000003FFFFFC000 ),
+ LONG2CHARS( 0x0000003FFFFFE000 ),
+ LONG2CHARS( 0x0000003FFFFFF000 ),
+ LONG2CHARS( 0x0000003FFFFFF800 ),
+ LONG2CHARS( 0x0000003FFFFFFC00 ),
+ LONG2CHARS( 0x0000003FFFFFFE00 ),
+ LONG2CHARS( 0x0000003FFFFFFF00 ),
+ LONG2CHARS( 0x0000003FFFFFFF80 ),
+ LONG2CHARS( 0x0000003FFFFFFFC0 ),
+ LONG2CHARS( 0x0000003FFFFFFFE0 ),
+ LONG2CHARS( 0x0000003FFFFFFFF0 ),
+ LONG2CHARS( 0x0000003FFFFFFFF8 ),
+ LONG2CHARS( 0x0000003FFFFFFFFC ),
+ LONG2CHARS( 0x0000003FFFFFFFFE ),
+ LONG2CHARS( 0x0000003FFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000001000000000 ),
+ LONG2CHARS( 0x0000001800000000 ),
+ LONG2CHARS( 0x0000001C00000000 ),
+ LONG2CHARS( 0x0000001E00000000 ),
+ LONG2CHARS( 0x0000001F00000000 ),
+ LONG2CHARS( 0x0000001F80000000 ),
+ LONG2CHARS( 0x0000001FC0000000 ),
+ LONG2CHARS( 0x0000001FE0000000 ),
+ LONG2CHARS( 0x0000001FF0000000 ),
+ LONG2CHARS( 0x0000001FF8000000 ),
+ LONG2CHARS( 0x0000001FFC000000 ),
+ LONG2CHARS( 0x0000001FFE000000 ),
+ LONG2CHARS( 0x0000001FFF000000 ),
+ LONG2CHARS( 0x0000001FFF800000 ),
+ LONG2CHARS( 0x0000001FFFC00000 ),
+ LONG2CHARS( 0x0000001FFFE00000 ),
+ LONG2CHARS( 0x0000001FFFF00000 ),
+ LONG2CHARS( 0x0000001FFFF80000 ),
+ LONG2CHARS( 0x0000001FFFFC0000 ),
+ LONG2CHARS( 0x0000001FFFFE0000 ),
+ LONG2CHARS( 0x0000001FFFFF0000 ),
+ LONG2CHARS( 0x0000001FFFFF8000 ),
+ LONG2CHARS( 0x0000001FFFFFC000 ),
+ LONG2CHARS( 0x0000001FFFFFE000 ),
+ LONG2CHARS( 0x0000001FFFFFF000 ),
+ LONG2CHARS( 0x0000001FFFFFF800 ),
+ LONG2CHARS( 0x0000001FFFFFFC00 ),
+ LONG2CHARS( 0x0000001FFFFFFE00 ),
+ LONG2CHARS( 0x0000001FFFFFFF00 ),
+ LONG2CHARS( 0x0000001FFFFFFF80 ),
+ LONG2CHARS( 0x0000001FFFFFFFC0 ),
+ LONG2CHARS( 0x0000001FFFFFFFE0 ),
+ LONG2CHARS( 0x0000001FFFFFFFF0 ),
+ LONG2CHARS( 0x0000001FFFFFFFF8 ),
+ LONG2CHARS( 0x0000001FFFFFFFFC ),
+ LONG2CHARS( 0x0000001FFFFFFFFE ),
+ LONG2CHARS( 0x0000001FFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000800000000 ),
+ LONG2CHARS( 0x0000000C00000000 ),
+ LONG2CHARS( 0x0000000E00000000 ),
+ LONG2CHARS( 0x0000000F00000000 ),
+ LONG2CHARS( 0x0000000F80000000 ),
+ LONG2CHARS( 0x0000000FC0000000 ),
+ LONG2CHARS( 0x0000000FE0000000 ),
+ LONG2CHARS( 0x0000000FF0000000 ),
+ LONG2CHARS( 0x0000000FF8000000 ),
+ LONG2CHARS( 0x0000000FFC000000 ),
+ LONG2CHARS( 0x0000000FFE000000 ),
+ LONG2CHARS( 0x0000000FFF000000 ),
+ LONG2CHARS( 0x0000000FFF800000 ),
+ LONG2CHARS( 0x0000000FFFC00000 ),
+ LONG2CHARS( 0x0000000FFFE00000 ),
+ LONG2CHARS( 0x0000000FFFF00000 ),
+ LONG2CHARS( 0x0000000FFFF80000 ),
+ LONG2CHARS( 0x0000000FFFFC0000 ),
+ LONG2CHARS( 0x0000000FFFFE0000 ),
+ LONG2CHARS( 0x0000000FFFFF0000 ),
+ LONG2CHARS( 0x0000000FFFFF8000 ),
+ LONG2CHARS( 0x0000000FFFFFC000 ),
+ LONG2CHARS( 0x0000000FFFFFE000 ),
+ LONG2CHARS( 0x0000000FFFFFF000 ),
+ LONG2CHARS( 0x0000000FFFFFF800 ),
+ LONG2CHARS( 0x0000000FFFFFFC00 ),
+ LONG2CHARS( 0x0000000FFFFFFE00 ),
+ LONG2CHARS( 0x0000000FFFFFFF00 ),
+ LONG2CHARS( 0x0000000FFFFFFF80 ),
+ LONG2CHARS( 0x0000000FFFFFFFC0 ),
+ LONG2CHARS( 0x0000000FFFFFFFE0 ),
+ LONG2CHARS( 0x0000000FFFFFFFF0 ),
+ LONG2CHARS( 0x0000000FFFFFFFF8 ),
+ LONG2CHARS( 0x0000000FFFFFFFFC ),
+ LONG2CHARS( 0x0000000FFFFFFFFE ),
+ LONG2CHARS( 0x0000000FFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000400000000 ),
+ LONG2CHARS( 0x0000000600000000 ),
+ LONG2CHARS( 0x0000000700000000 ),
+ LONG2CHARS( 0x0000000780000000 ),
+ LONG2CHARS( 0x00000007C0000000 ),
+ LONG2CHARS( 0x00000007E0000000 ),
+ LONG2CHARS( 0x00000007F0000000 ),
+ LONG2CHARS( 0x00000007F8000000 ),
+ LONG2CHARS( 0x00000007FC000000 ),
+ LONG2CHARS( 0x00000007FE000000 ),
+ LONG2CHARS( 0x00000007FF000000 ),
+ LONG2CHARS( 0x00000007FF800000 ),
+ LONG2CHARS( 0x00000007FFC00000 ),
+ LONG2CHARS( 0x00000007FFE00000 ),
+ LONG2CHARS( 0x00000007FFF00000 ),
+ LONG2CHARS( 0x00000007FFF80000 ),
+ LONG2CHARS( 0x00000007FFFC0000 ),
+ LONG2CHARS( 0x00000007FFFE0000 ),
+ LONG2CHARS( 0x00000007FFFF0000 ),
+ LONG2CHARS( 0x00000007FFFF8000 ),
+ LONG2CHARS( 0x00000007FFFFC000 ),
+ LONG2CHARS( 0x00000007FFFFE000 ),
+ LONG2CHARS( 0x00000007FFFFF000 ),
+ LONG2CHARS( 0x00000007FFFFF800 ),
+ LONG2CHARS( 0x00000007FFFFFC00 ),
+ LONG2CHARS( 0x00000007FFFFFE00 ),
+ LONG2CHARS( 0x00000007FFFFFF00 ),
+ LONG2CHARS( 0x00000007FFFFFF80 ),
+ LONG2CHARS( 0x00000007FFFFFFC0 ),
+ LONG2CHARS( 0x00000007FFFFFFE0 ),
+ LONG2CHARS( 0x00000007FFFFFFF0 ),
+ LONG2CHARS( 0x00000007FFFFFFF8 ),
+ LONG2CHARS( 0x00000007FFFFFFFC ),
+ LONG2CHARS( 0x00000007FFFFFFFE ),
+ LONG2CHARS( 0x00000007FFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000200000000 ),
+ LONG2CHARS( 0x0000000300000000 ),
+ LONG2CHARS( 0x0000000380000000 ),
+ LONG2CHARS( 0x00000003C0000000 ),
+ LONG2CHARS( 0x00000003E0000000 ),
+ LONG2CHARS( 0x00000003F0000000 ),
+ LONG2CHARS( 0x00000003F8000000 ),
+ LONG2CHARS( 0x00000003FC000000 ),
+ LONG2CHARS( 0x00000003FE000000 ),
+ LONG2CHARS( 0x00000003FF000000 ),
+ LONG2CHARS( 0x00000003FF800000 ),
+ LONG2CHARS( 0x00000003FFC00000 ),
+ LONG2CHARS( 0x00000003FFE00000 ),
+ LONG2CHARS( 0x00000003FFF00000 ),
+ LONG2CHARS( 0x00000003FFF80000 ),
+ LONG2CHARS( 0x00000003FFFC0000 ),
+ LONG2CHARS( 0x00000003FFFE0000 ),
+ LONG2CHARS( 0x00000003FFFF0000 ),
+ LONG2CHARS( 0x00000003FFFF8000 ),
+ LONG2CHARS( 0x00000003FFFFC000 ),
+ LONG2CHARS( 0x00000003FFFFE000 ),
+ LONG2CHARS( 0x00000003FFFFF000 ),
+ LONG2CHARS( 0x00000003FFFFF800 ),
+ LONG2CHARS( 0x00000003FFFFFC00 ),
+ LONG2CHARS( 0x00000003FFFFFE00 ),
+ LONG2CHARS( 0x00000003FFFFFF00 ),
+ LONG2CHARS( 0x00000003FFFFFF80 ),
+ LONG2CHARS( 0x00000003FFFFFFC0 ),
+ LONG2CHARS( 0x00000003FFFFFFE0 ),
+ LONG2CHARS( 0x00000003FFFFFFF0 ),
+ LONG2CHARS( 0x00000003FFFFFFF8 ),
+ LONG2CHARS( 0x00000003FFFFFFFC ),
+ LONG2CHARS( 0x00000003FFFFFFFE ),
+ LONG2CHARS( 0x00000003FFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000100000000 ),
+ LONG2CHARS( 0x0000000180000000 ),
+ LONG2CHARS( 0x00000001C0000000 ),
+ LONG2CHARS( 0x00000001E0000000 ),
+ LONG2CHARS( 0x00000001F0000000 ),
+ LONG2CHARS( 0x00000001F8000000 ),
+ LONG2CHARS( 0x00000001FC000000 ),
+ LONG2CHARS( 0x00000001FE000000 ),
+ LONG2CHARS( 0x00000001FF000000 ),
+ LONG2CHARS( 0x00000001FF800000 ),
+ LONG2CHARS( 0x00000001FFC00000 ),
+ LONG2CHARS( 0x00000001FFE00000 ),
+ LONG2CHARS( 0x00000001FFF00000 ),
+ LONG2CHARS( 0x00000001FFF80000 ),
+ LONG2CHARS( 0x00000001FFFC0000 ),
+ LONG2CHARS( 0x00000001FFFE0000 ),
+ LONG2CHARS( 0x00000001FFFF0000 ),
+ LONG2CHARS( 0x00000001FFFF8000 ),
+ LONG2CHARS( 0x00000001FFFFC000 ),
+ LONG2CHARS( 0x00000001FFFFE000 ),
+ LONG2CHARS( 0x00000001FFFFF000 ),
+ LONG2CHARS( 0x00000001FFFFF800 ),
+ LONG2CHARS( 0x00000001FFFFFC00 ),
+ LONG2CHARS( 0x00000001FFFFFE00 ),
+ LONG2CHARS( 0x00000001FFFFFF00 ),
+ LONG2CHARS( 0x00000001FFFFFF80 ),
+ LONG2CHARS( 0x00000001FFFFFFC0 ),
+ LONG2CHARS( 0x00000001FFFFFFE0 ),
+ LONG2CHARS( 0x00000001FFFFFFF0 ),
+ LONG2CHARS( 0x00000001FFFFFFF8 ),
+ LONG2CHARS( 0x00000001FFFFFFFC ),
+ LONG2CHARS( 0x00000001FFFFFFFE ),
+ LONG2CHARS( 0x00000001FFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000080000000 ),
+ LONG2CHARS( 0x00000000C0000000 ),
+ LONG2CHARS( 0x00000000E0000000 ),
+ LONG2CHARS( 0x00000000F0000000 ),
+ LONG2CHARS( 0x00000000F8000000 ),
+ LONG2CHARS( 0x00000000FC000000 ),
+ LONG2CHARS( 0x00000000FE000000 ),
+ LONG2CHARS( 0x00000000FF000000 ),
+ LONG2CHARS( 0x00000000FF800000 ),
+ LONG2CHARS( 0x00000000FFC00000 ),
+ LONG2CHARS( 0x00000000FFE00000 ),
+ LONG2CHARS( 0x00000000FFF00000 ),
+ LONG2CHARS( 0x00000000FFF80000 ),
+ LONG2CHARS( 0x00000000FFFC0000 ),
+ LONG2CHARS( 0x00000000FFFE0000 ),
+ LONG2CHARS( 0x00000000FFFF0000 ),
+ LONG2CHARS( 0x00000000FFFF8000 ),
+ LONG2CHARS( 0x00000000FFFFC000 ),
+ LONG2CHARS( 0x00000000FFFFE000 ),
+ LONG2CHARS( 0x00000000FFFFF000 ),
+ LONG2CHARS( 0x00000000FFFFF800 ),
+ LONG2CHARS( 0x00000000FFFFFC00 ),
+ LONG2CHARS( 0x00000000FFFFFE00 ),
+ LONG2CHARS( 0x00000000FFFFFF00 ),
+ LONG2CHARS( 0x00000000FFFFFF80 ),
+ LONG2CHARS( 0x00000000FFFFFFC0 ),
+ LONG2CHARS( 0x00000000FFFFFFE0 ),
+ LONG2CHARS( 0x00000000FFFFFFF0 ),
+ LONG2CHARS( 0x00000000FFFFFFF8 ),
+ LONG2CHARS( 0x00000000FFFFFFFC ),
+ LONG2CHARS( 0x00000000FFFFFFFE ),
+ LONG2CHARS( 0x00000000FFFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000040000000 ),
+ LONG2CHARS( 0x0000000060000000 ),
+ LONG2CHARS( 0x0000000070000000 ),
+ LONG2CHARS( 0x0000000078000000 ),
+ LONG2CHARS( 0x000000007C000000 ),
+ LONG2CHARS( 0x000000007E000000 ),
+ LONG2CHARS( 0x000000007F000000 ),
+ LONG2CHARS( 0x000000007F800000 ),
+ LONG2CHARS( 0x000000007FC00000 ),
+ LONG2CHARS( 0x000000007FE00000 ),
+ LONG2CHARS( 0x000000007FF00000 ),
+ LONG2CHARS( 0x000000007FF80000 ),
+ LONG2CHARS( 0x000000007FFC0000 ),
+ LONG2CHARS( 0x000000007FFE0000 ),
+ LONG2CHARS( 0x000000007FFF0000 ),
+ LONG2CHARS( 0x000000007FFF8000 ),
+ LONG2CHARS( 0x000000007FFFC000 ),
+ LONG2CHARS( 0x000000007FFFE000 ),
+ LONG2CHARS( 0x000000007FFFF000 ),
+ LONG2CHARS( 0x000000007FFFF800 ),
+ LONG2CHARS( 0x000000007FFFFC00 ),
+ LONG2CHARS( 0x000000007FFFFE00 ),
+ LONG2CHARS( 0x000000007FFFFF00 ),
+ LONG2CHARS( 0x000000007FFFFF80 ),
+ LONG2CHARS( 0x000000007FFFFFC0 ),
+ LONG2CHARS( 0x000000007FFFFFE0 ),
+ LONG2CHARS( 0x000000007FFFFFF0 ),
+ LONG2CHARS( 0x000000007FFFFFF8 ),
+ LONG2CHARS( 0x000000007FFFFFFC ),
+ LONG2CHARS( 0x000000007FFFFFFE ),
+ LONG2CHARS( 0x000000007FFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000020000000 ),
+ LONG2CHARS( 0x0000000030000000 ),
+ LONG2CHARS( 0x0000000038000000 ),
+ LONG2CHARS( 0x000000003C000000 ),
+ LONG2CHARS( 0x000000003E000000 ),
+ LONG2CHARS( 0x000000003F000000 ),
+ LONG2CHARS( 0x000000003F800000 ),
+ LONG2CHARS( 0x000000003FC00000 ),
+ LONG2CHARS( 0x000000003FE00000 ),
+ LONG2CHARS( 0x000000003FF00000 ),
+ LONG2CHARS( 0x000000003FF80000 ),
+ LONG2CHARS( 0x000000003FFC0000 ),
+ LONG2CHARS( 0x000000003FFE0000 ),
+ LONG2CHARS( 0x000000003FFF0000 ),
+ LONG2CHARS( 0x000000003FFF8000 ),
+ LONG2CHARS( 0x000000003FFFC000 ),
+ LONG2CHARS( 0x000000003FFFE000 ),
+ LONG2CHARS( 0x000000003FFFF000 ),
+ LONG2CHARS( 0x000000003FFFF800 ),
+ LONG2CHARS( 0x000000003FFFFC00 ),
+ LONG2CHARS( 0x000000003FFFFE00 ),
+ LONG2CHARS( 0x000000003FFFFF00 ),
+ LONG2CHARS( 0x000000003FFFFF80 ),
+ LONG2CHARS( 0x000000003FFFFFC0 ),
+ LONG2CHARS( 0x000000003FFFFFE0 ),
+ LONG2CHARS( 0x000000003FFFFFF0 ),
+ LONG2CHARS( 0x000000003FFFFFF8 ),
+ LONG2CHARS( 0x000000003FFFFFFC ),
+ LONG2CHARS( 0x000000003FFFFFFE ),
+ LONG2CHARS( 0x000000003FFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000010000000 ),
+ LONG2CHARS( 0x0000000018000000 ),
+ LONG2CHARS( 0x000000001C000000 ),
+ LONG2CHARS( 0x000000001E000000 ),
+ LONG2CHARS( 0x000000001F000000 ),
+ LONG2CHARS( 0x000000001F800000 ),
+ LONG2CHARS( 0x000000001FC00000 ),
+ LONG2CHARS( 0x000000001FE00000 ),
+ LONG2CHARS( 0x000000001FF00000 ),
+ LONG2CHARS( 0x000000001FF80000 ),
+ LONG2CHARS( 0x000000001FFC0000 ),
+ LONG2CHARS( 0x000000001FFE0000 ),
+ LONG2CHARS( 0x000000001FFF0000 ),
+ LONG2CHARS( 0x000000001FFF8000 ),
+ LONG2CHARS( 0x000000001FFFC000 ),
+ LONG2CHARS( 0x000000001FFFE000 ),
+ LONG2CHARS( 0x000000001FFFF000 ),
+ LONG2CHARS( 0x000000001FFFF800 ),
+ LONG2CHARS( 0x000000001FFFFC00 ),
+ LONG2CHARS( 0x000000001FFFFE00 ),
+ LONG2CHARS( 0x000000001FFFFF00 ),
+ LONG2CHARS( 0x000000001FFFFF80 ),
+ LONG2CHARS( 0x000000001FFFFFC0 ),
+ LONG2CHARS( 0x000000001FFFFFE0 ),
+ LONG2CHARS( 0x000000001FFFFFF0 ),
+ LONG2CHARS( 0x000000001FFFFFF8 ),
+ LONG2CHARS( 0x000000001FFFFFFC ),
+ LONG2CHARS( 0x000000001FFFFFFE ),
+ LONG2CHARS( 0x000000001FFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000008000000 ),
+ LONG2CHARS( 0x000000000C000000 ),
+ LONG2CHARS( 0x000000000E000000 ),
+ LONG2CHARS( 0x000000000F000000 ),
+ LONG2CHARS( 0x000000000F800000 ),
+ LONG2CHARS( 0x000000000FC00000 ),
+ LONG2CHARS( 0x000000000FE00000 ),
+ LONG2CHARS( 0x000000000FF00000 ),
+ LONG2CHARS( 0x000000000FF80000 ),
+ LONG2CHARS( 0x000000000FFC0000 ),
+ LONG2CHARS( 0x000000000FFE0000 ),
+ LONG2CHARS( 0x000000000FFF0000 ),
+ LONG2CHARS( 0x000000000FFF8000 ),
+ LONG2CHARS( 0x000000000FFFC000 ),
+ LONG2CHARS( 0x000000000FFFE000 ),
+ LONG2CHARS( 0x000000000FFFF000 ),
+ LONG2CHARS( 0x000000000FFFF800 ),
+ LONG2CHARS( 0x000000000FFFFC00 ),
+ LONG2CHARS( 0x000000000FFFFE00 ),
+ LONG2CHARS( 0x000000000FFFFF00 ),
+ LONG2CHARS( 0x000000000FFFFF80 ),
+ LONG2CHARS( 0x000000000FFFFFC0 ),
+ LONG2CHARS( 0x000000000FFFFFE0 ),
+ LONG2CHARS( 0x000000000FFFFFF0 ),
+ LONG2CHARS( 0x000000000FFFFFF8 ),
+ LONG2CHARS( 0x000000000FFFFFFC ),
+ LONG2CHARS( 0x000000000FFFFFFE ),
+ LONG2CHARS( 0x000000000FFFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000004000000 ),
+ LONG2CHARS( 0x0000000006000000 ),
+ LONG2CHARS( 0x0000000007000000 ),
+ LONG2CHARS( 0x0000000007800000 ),
+ LONG2CHARS( 0x0000000007C00000 ),
+ LONG2CHARS( 0x0000000007E00000 ),
+ LONG2CHARS( 0x0000000007F00000 ),
+ LONG2CHARS( 0x0000000007F80000 ),
+ LONG2CHARS( 0x0000000007FC0000 ),
+ LONG2CHARS( 0x0000000007FE0000 ),
+ LONG2CHARS( 0x0000000007FF0000 ),
+ LONG2CHARS( 0x0000000007FF8000 ),
+ LONG2CHARS( 0x0000000007FFC000 ),
+ LONG2CHARS( 0x0000000007FFE000 ),
+ LONG2CHARS( 0x0000000007FFF000 ),
+ LONG2CHARS( 0x0000000007FFF800 ),
+ LONG2CHARS( 0x0000000007FFFC00 ),
+ LONG2CHARS( 0x0000000007FFFE00 ),
+ LONG2CHARS( 0x0000000007FFFF00 ),
+ LONG2CHARS( 0x0000000007FFFF80 ),
+ LONG2CHARS( 0x0000000007FFFFC0 ),
+ LONG2CHARS( 0x0000000007FFFFE0 ),
+ LONG2CHARS( 0x0000000007FFFFF0 ),
+ LONG2CHARS( 0x0000000007FFFFF8 ),
+ LONG2CHARS( 0x0000000007FFFFFC ),
+ LONG2CHARS( 0x0000000007FFFFFE ),
+ LONG2CHARS( 0x0000000007FFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000002000000 ),
+ LONG2CHARS( 0x0000000003000000 ),
+ LONG2CHARS( 0x0000000003800000 ),
+ LONG2CHARS( 0x0000000003C00000 ),
+ LONG2CHARS( 0x0000000003E00000 ),
+ LONG2CHARS( 0x0000000003F00000 ),
+ LONG2CHARS( 0x0000000003F80000 ),
+ LONG2CHARS( 0x0000000003FC0000 ),
+ LONG2CHARS( 0x0000000003FE0000 ),
+ LONG2CHARS( 0x0000000003FF0000 ),
+ LONG2CHARS( 0x0000000003FF8000 ),
+ LONG2CHARS( 0x0000000003FFC000 ),
+ LONG2CHARS( 0x0000000003FFE000 ),
+ LONG2CHARS( 0x0000000003FFF000 ),
+ LONG2CHARS( 0x0000000003FFF800 ),
+ LONG2CHARS( 0x0000000003FFFC00 ),
+ LONG2CHARS( 0x0000000003FFFE00 ),
+ LONG2CHARS( 0x0000000003FFFF00 ),
+ LONG2CHARS( 0x0000000003FFFF80 ),
+ LONG2CHARS( 0x0000000003FFFFC0 ),
+ LONG2CHARS( 0x0000000003FFFFE0 ),
+ LONG2CHARS( 0x0000000003FFFFF0 ),
+ LONG2CHARS( 0x0000000003FFFFF8 ),
+ LONG2CHARS( 0x0000000003FFFFFC ),
+ LONG2CHARS( 0x0000000003FFFFFE ),
+ LONG2CHARS( 0x0000000003FFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000001000000 ),
+ LONG2CHARS( 0x0000000001800000 ),
+ LONG2CHARS( 0x0000000001C00000 ),
+ LONG2CHARS( 0x0000000001E00000 ),
+ LONG2CHARS( 0x0000000001F00000 ),
+ LONG2CHARS( 0x0000000001F80000 ),
+ LONG2CHARS( 0x0000000001FC0000 ),
+ LONG2CHARS( 0x0000000001FE0000 ),
+ LONG2CHARS( 0x0000000001FF0000 ),
+ LONG2CHARS( 0x0000000001FF8000 ),
+ LONG2CHARS( 0x0000000001FFC000 ),
+ LONG2CHARS( 0x0000000001FFE000 ),
+ LONG2CHARS( 0x0000000001FFF000 ),
+ LONG2CHARS( 0x0000000001FFF800 ),
+ LONG2CHARS( 0x0000000001FFFC00 ),
+ LONG2CHARS( 0x0000000001FFFE00 ),
+ LONG2CHARS( 0x0000000001FFFF00 ),
+ LONG2CHARS( 0x0000000001FFFF80 ),
+ LONG2CHARS( 0x0000000001FFFFC0 ),
+ LONG2CHARS( 0x0000000001FFFFE0 ),
+ LONG2CHARS( 0x0000000001FFFFF0 ),
+ LONG2CHARS( 0x0000000001FFFFF8 ),
+ LONG2CHARS( 0x0000000001FFFFFC ),
+ LONG2CHARS( 0x0000000001FFFFFE ),
+ LONG2CHARS( 0x0000000001FFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000800000 ),
+ LONG2CHARS( 0x0000000000C00000 ),
+ LONG2CHARS( 0x0000000000E00000 ),
+ LONG2CHARS( 0x0000000000F00000 ),
+ LONG2CHARS( 0x0000000000F80000 ),
+ LONG2CHARS( 0x0000000000FC0000 ),
+ LONG2CHARS( 0x0000000000FE0000 ),
+ LONG2CHARS( 0x0000000000FF0000 ),
+ LONG2CHARS( 0x0000000000FF8000 ),
+ LONG2CHARS( 0x0000000000FFC000 ),
+ LONG2CHARS( 0x0000000000FFE000 ),
+ LONG2CHARS( 0x0000000000FFF000 ),
+ LONG2CHARS( 0x0000000000FFF800 ),
+ LONG2CHARS( 0x0000000000FFFC00 ),
+ LONG2CHARS( 0x0000000000FFFE00 ),
+ LONG2CHARS( 0x0000000000FFFF00 ),
+ LONG2CHARS( 0x0000000000FFFF80 ),
+ LONG2CHARS( 0x0000000000FFFFC0 ),
+ LONG2CHARS( 0x0000000000FFFFE0 ),
+ LONG2CHARS( 0x0000000000FFFFF0 ),
+ LONG2CHARS( 0x0000000000FFFFF8 ),
+ LONG2CHARS( 0x0000000000FFFFFC ),
+ LONG2CHARS( 0x0000000000FFFFFE ),
+ LONG2CHARS( 0x0000000000FFFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000400000 ),
+ LONG2CHARS( 0x0000000000600000 ),
+ LONG2CHARS( 0x0000000000700000 ),
+ LONG2CHARS( 0x0000000000780000 ),
+ LONG2CHARS( 0x00000000007C0000 ),
+ LONG2CHARS( 0x00000000007E0000 ),
+ LONG2CHARS( 0x00000000007F0000 ),
+ LONG2CHARS( 0x00000000007F8000 ),
+ LONG2CHARS( 0x00000000007FC000 ),
+ LONG2CHARS( 0x00000000007FE000 ),
+ LONG2CHARS( 0x00000000007FF000 ),
+ LONG2CHARS( 0x00000000007FF800 ),
+ LONG2CHARS( 0x00000000007FFC00 ),
+ LONG2CHARS( 0x00000000007FFE00 ),
+ LONG2CHARS( 0x00000000007FFF00 ),
+ LONG2CHARS( 0x00000000007FFF80 ),
+ LONG2CHARS( 0x00000000007FFFC0 ),
+ LONG2CHARS( 0x00000000007FFFE0 ),
+ LONG2CHARS( 0x00000000007FFFF0 ),
+ LONG2CHARS( 0x00000000007FFFF8 ),
+ LONG2CHARS( 0x00000000007FFFFC ),
+ LONG2CHARS( 0x00000000007FFFFE ),
+ LONG2CHARS( 0x00000000007FFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000200000 ),
+ LONG2CHARS( 0x0000000000300000 ),
+ LONG2CHARS( 0x0000000000380000 ),
+ LONG2CHARS( 0x00000000003C0000 ),
+ LONG2CHARS( 0x00000000003E0000 ),
+ LONG2CHARS( 0x00000000003F0000 ),
+ LONG2CHARS( 0x00000000003F8000 ),
+ LONG2CHARS( 0x00000000003FC000 ),
+ LONG2CHARS( 0x00000000003FE000 ),
+ LONG2CHARS( 0x00000000003FF000 ),
+ LONG2CHARS( 0x00000000003FF800 ),
+ LONG2CHARS( 0x00000000003FFC00 ),
+ LONG2CHARS( 0x00000000003FFE00 ),
+ LONG2CHARS( 0x00000000003FFF00 ),
+ LONG2CHARS( 0x00000000003FFF80 ),
+ LONG2CHARS( 0x00000000003FFFC0 ),
+ LONG2CHARS( 0x00000000003FFFE0 ),
+ LONG2CHARS( 0x00000000003FFFF0 ),
+ LONG2CHARS( 0x00000000003FFFF8 ),
+ LONG2CHARS( 0x00000000003FFFFC ),
+ LONG2CHARS( 0x00000000003FFFFE ),
+ LONG2CHARS( 0x00000000003FFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000100000 ),
+ LONG2CHARS( 0x0000000000180000 ),
+ LONG2CHARS( 0x00000000001C0000 ),
+ LONG2CHARS( 0x00000000001E0000 ),
+ LONG2CHARS( 0x00000000001F0000 ),
+ LONG2CHARS( 0x00000000001F8000 ),
+ LONG2CHARS( 0x00000000001FC000 ),
+ LONG2CHARS( 0x00000000001FE000 ),
+ LONG2CHARS( 0x00000000001FF000 ),
+ LONG2CHARS( 0x00000000001FF800 ),
+ LONG2CHARS( 0x00000000001FFC00 ),
+ LONG2CHARS( 0x00000000001FFE00 ),
+ LONG2CHARS( 0x00000000001FFF00 ),
+ LONG2CHARS( 0x00000000001FFF80 ),
+ LONG2CHARS( 0x00000000001FFFC0 ),
+ LONG2CHARS( 0x00000000001FFFE0 ),
+ LONG2CHARS( 0x00000000001FFFF0 ),
+ LONG2CHARS( 0x00000000001FFFF8 ),
+ LONG2CHARS( 0x00000000001FFFFC ),
+ LONG2CHARS( 0x00000000001FFFFE ),
+ LONG2CHARS( 0x00000000001FFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000080000 ),
+ LONG2CHARS( 0x00000000000C0000 ),
+ LONG2CHARS( 0x00000000000E0000 ),
+ LONG2CHARS( 0x00000000000F0000 ),
+ LONG2CHARS( 0x00000000000F8000 ),
+ LONG2CHARS( 0x00000000000FC000 ),
+ LONG2CHARS( 0x00000000000FE000 ),
+ LONG2CHARS( 0x00000000000FF000 ),
+ LONG2CHARS( 0x00000000000FF800 ),
+ LONG2CHARS( 0x00000000000FFC00 ),
+ LONG2CHARS( 0x00000000000FFE00 ),
+ LONG2CHARS( 0x00000000000FFF00 ),
+ LONG2CHARS( 0x00000000000FFF80 ),
+ LONG2CHARS( 0x00000000000FFFC0 ),
+ LONG2CHARS( 0x00000000000FFFE0 ),
+ LONG2CHARS( 0x00000000000FFFF0 ),
+ LONG2CHARS( 0x00000000000FFFF8 ),
+ LONG2CHARS( 0x00000000000FFFFC ),
+ LONG2CHARS( 0x00000000000FFFFE ),
+ LONG2CHARS( 0x00000000000FFFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000040000 ),
+ LONG2CHARS( 0x0000000000060000 ),
+ LONG2CHARS( 0x0000000000070000 ),
+ LONG2CHARS( 0x0000000000078000 ),
+ LONG2CHARS( 0x000000000007C000 ),
+ LONG2CHARS( 0x000000000007E000 ),
+ LONG2CHARS( 0x000000000007F000 ),
+ LONG2CHARS( 0x000000000007F800 ),
+ LONG2CHARS( 0x000000000007FC00 ),
+ LONG2CHARS( 0x000000000007FE00 ),
+ LONG2CHARS( 0x000000000007FF00 ),
+ LONG2CHARS( 0x000000000007FF80 ),
+ LONG2CHARS( 0x000000000007FFC0 ),
+ LONG2CHARS( 0x000000000007FFE0 ),
+ LONG2CHARS( 0x000000000007FFF0 ),
+ LONG2CHARS( 0x000000000007FFF8 ),
+ LONG2CHARS( 0x000000000007FFFC ),
+ LONG2CHARS( 0x000000000007FFFE ),
+ LONG2CHARS( 0x000000000007FFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000020000 ),
+ LONG2CHARS( 0x0000000000030000 ),
+ LONG2CHARS( 0x0000000000038000 ),
+ LONG2CHARS( 0x000000000003C000 ),
+ LONG2CHARS( 0x000000000003E000 ),
+ LONG2CHARS( 0x000000000003F000 ),
+ LONG2CHARS( 0x000000000003F800 ),
+ LONG2CHARS( 0x000000000003FC00 ),
+ LONG2CHARS( 0x000000000003FE00 ),
+ LONG2CHARS( 0x000000000003FF00 ),
+ LONG2CHARS( 0x000000000003FF80 ),
+ LONG2CHARS( 0x000000000003FFC0 ),
+ LONG2CHARS( 0x000000000003FFE0 ),
+ LONG2CHARS( 0x000000000003FFF0 ),
+ LONG2CHARS( 0x000000000003FFF8 ),
+ LONG2CHARS( 0x000000000003FFFC ),
+ LONG2CHARS( 0x000000000003FFFE ),
+ LONG2CHARS( 0x000000000003FFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000010000 ),
+ LONG2CHARS( 0x0000000000018000 ),
+ LONG2CHARS( 0x000000000001C000 ),
+ LONG2CHARS( 0x000000000001E000 ),
+ LONG2CHARS( 0x000000000001F000 ),
+ LONG2CHARS( 0x000000000001F800 ),
+ LONG2CHARS( 0x000000000001FC00 ),
+ LONG2CHARS( 0x000000000001FE00 ),
+ LONG2CHARS( 0x000000000001FF00 ),
+ LONG2CHARS( 0x000000000001FF80 ),
+ LONG2CHARS( 0x000000000001FFC0 ),
+ LONG2CHARS( 0x000000000001FFE0 ),
+ LONG2CHARS( 0x000000000001FFF0 ),
+ LONG2CHARS( 0x000000000001FFF8 ),
+ LONG2CHARS( 0x000000000001FFFC ),
+ LONG2CHARS( 0x000000000001FFFE ),
+ LONG2CHARS( 0x000000000001FFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000008000 ),
+ LONG2CHARS( 0x000000000000C000 ),
+ LONG2CHARS( 0x000000000000E000 ),
+ LONG2CHARS( 0x000000000000F000 ),
+ LONG2CHARS( 0x000000000000F800 ),
+ LONG2CHARS( 0x000000000000FC00 ),
+ LONG2CHARS( 0x000000000000FE00 ),
+ LONG2CHARS( 0x000000000000FF00 ),
+ LONG2CHARS( 0x000000000000FF80 ),
+ LONG2CHARS( 0x000000000000FFC0 ),
+ LONG2CHARS( 0x000000000000FFE0 ),
+ LONG2CHARS( 0x000000000000FFF0 ),
+ LONG2CHARS( 0x000000000000FFF8 ),
+ LONG2CHARS( 0x000000000000FFFC ),
+ LONG2CHARS( 0x000000000000FFFE ),
+ LONG2CHARS( 0x000000000000FFFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000004000 ),
+ LONG2CHARS( 0x0000000000006000 ),
+ LONG2CHARS( 0x0000000000007000 ),
+ LONG2CHARS( 0x0000000000007800 ),
+ LONG2CHARS( 0x0000000000007C00 ),
+ LONG2CHARS( 0x0000000000007E00 ),
+ LONG2CHARS( 0x0000000000007F00 ),
+ LONG2CHARS( 0x0000000000007F80 ),
+ LONG2CHARS( 0x0000000000007FC0 ),
+ LONG2CHARS( 0x0000000000007FE0 ),
+ LONG2CHARS( 0x0000000000007FF0 ),
+ LONG2CHARS( 0x0000000000007FF8 ),
+ LONG2CHARS( 0x0000000000007FFC ),
+ LONG2CHARS( 0x0000000000007FFE ),
+ LONG2CHARS( 0x0000000000007FFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000002000 ),
+ LONG2CHARS( 0x0000000000003000 ),
+ LONG2CHARS( 0x0000000000003800 ),
+ LONG2CHARS( 0x0000000000003C00 ),
+ LONG2CHARS( 0x0000000000003E00 ),
+ LONG2CHARS( 0x0000000000003F00 ),
+ LONG2CHARS( 0x0000000000003F80 ),
+ LONG2CHARS( 0x0000000000003FC0 ),
+ LONG2CHARS( 0x0000000000003FE0 ),
+ LONG2CHARS( 0x0000000000003FF0 ),
+ LONG2CHARS( 0x0000000000003FF8 ),
+ LONG2CHARS( 0x0000000000003FFC ),
+ LONG2CHARS( 0x0000000000003FFE ),
+ LONG2CHARS( 0x0000000000003FFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000001000 ),
+ LONG2CHARS( 0x0000000000001800 ),
+ LONG2CHARS( 0x0000000000001C00 ),
+ LONG2CHARS( 0x0000000000001E00 ),
+ LONG2CHARS( 0x0000000000001F00 ),
+ LONG2CHARS( 0x0000000000001F80 ),
+ LONG2CHARS( 0x0000000000001FC0 ),
+ LONG2CHARS( 0x0000000000001FE0 ),
+ LONG2CHARS( 0x0000000000001FF0 ),
+ LONG2CHARS( 0x0000000000001FF8 ),
+ LONG2CHARS( 0x0000000000001FFC ),
+ LONG2CHARS( 0x0000000000001FFE ),
+ LONG2CHARS( 0x0000000000001FFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000800 ),
+ LONG2CHARS( 0x0000000000000C00 ),
+ LONG2CHARS( 0x0000000000000E00 ),
+ LONG2CHARS( 0x0000000000000F00 ),
+ LONG2CHARS( 0x0000000000000F80 ),
+ LONG2CHARS( 0x0000000000000FC0 ),
+ LONG2CHARS( 0x0000000000000FE0 ),
+ LONG2CHARS( 0x0000000000000FF0 ),
+ LONG2CHARS( 0x0000000000000FF8 ),
+ LONG2CHARS( 0x0000000000000FFC ),
+ LONG2CHARS( 0x0000000000000FFE ),
+ LONG2CHARS( 0x0000000000000FFF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000400 ),
+ LONG2CHARS( 0x0000000000000600 ),
+ LONG2CHARS( 0x0000000000000700 ),
+ LONG2CHARS( 0x0000000000000780 ),
+ LONG2CHARS( 0x00000000000007C0 ),
+ LONG2CHARS( 0x00000000000007E0 ),
+ LONG2CHARS( 0x00000000000007F0 ),
+ LONG2CHARS( 0x00000000000007F8 ),
+ LONG2CHARS( 0x00000000000007FC ),
+ LONG2CHARS( 0x00000000000007FE ),
+ LONG2CHARS( 0x00000000000007FF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000200 ),
+ LONG2CHARS( 0x0000000000000300 ),
+ LONG2CHARS( 0x0000000000000380 ),
+ LONG2CHARS( 0x00000000000003C0 ),
+ LONG2CHARS( 0x00000000000003E0 ),
+ LONG2CHARS( 0x00000000000003F0 ),
+ LONG2CHARS( 0x00000000000003F8 ),
+ LONG2CHARS( 0x00000000000003FC ),
+ LONG2CHARS( 0x00000000000003FE ),
+ LONG2CHARS( 0x00000000000003FF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000100 ),
+ LONG2CHARS( 0x0000000000000180 ),
+ LONG2CHARS( 0x00000000000001C0 ),
+ LONG2CHARS( 0x00000000000001E0 ),
+ LONG2CHARS( 0x00000000000001F0 ),
+ LONG2CHARS( 0x00000000000001F8 ),
+ LONG2CHARS( 0x00000000000001FC ),
+ LONG2CHARS( 0x00000000000001FE ),
+ LONG2CHARS( 0x00000000000001FF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000080 ),
+ LONG2CHARS( 0x00000000000000C0 ),
+ LONG2CHARS( 0x00000000000000E0 ),
+ LONG2CHARS( 0x00000000000000F0 ),
+ LONG2CHARS( 0x00000000000000F8 ),
+ LONG2CHARS( 0x00000000000000FC ),
+ LONG2CHARS( 0x00000000000000FE ),
+ LONG2CHARS( 0x00000000000000FF ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000040 ),
+ LONG2CHARS( 0x0000000000000060 ),
+ LONG2CHARS( 0x0000000000000070 ),
+ LONG2CHARS( 0x0000000000000078 ),
+ LONG2CHARS( 0x000000000000007C ),
+ LONG2CHARS( 0x000000000000007E ),
+ LONG2CHARS( 0x000000000000007F ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000020 ),
+ LONG2CHARS( 0x0000000000000030 ),
+ LONG2CHARS( 0x0000000000000038 ),
+ LONG2CHARS( 0x000000000000003C ),
+ LONG2CHARS( 0x000000000000003E ),
+ LONG2CHARS( 0x000000000000003F ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000010 ),
+ LONG2CHARS( 0x0000000000000018 ),
+ LONG2CHARS( 0x000000000000001C ),
+ LONG2CHARS( 0x000000000000001E ),
+ LONG2CHARS( 0x000000000000001F ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000008 ),
+ LONG2CHARS( 0x000000000000000C ),
+ LONG2CHARS( 0x000000000000000E ),
+ LONG2CHARS( 0x000000000000000F ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000004 ),
+ LONG2CHARS( 0x0000000000000006 ),
+ LONG2CHARS( 0x0000000000000007 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000002 ),
+ LONG2CHARS( 0x0000000000000003 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000001 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+};
+#endif /* PPW */
+
+#else /* LSBFirst */
+/* NOTE:
+the first element in starttab could be LONG2CHARS( 0xffffffff. making it 0
+lets us deal with a full first word in the middle loop ), rather
+than having to do the multiple reads and masks that we'd
+have to do if we thought it was partial.
+*/
+PixelType starttab[PPW+1] =
+ {
+#if PPW == 32
+ LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0xFFFFFFFE ),
+ LONG2CHARS( 0xFFFFFFFC ),
+ LONG2CHARS( 0xFFFFFFF8 ),
+ LONG2CHARS( 0xFFFFFFF0 ),
+ LONG2CHARS( 0xFFFFFFE0 ),
+ LONG2CHARS( 0xFFFFFFC0 ),
+ LONG2CHARS( 0xFFFFFF80 ),
+ LONG2CHARS( 0xFFFFFF00 ),
+ LONG2CHARS( 0xFFFFFE00 ),
+ LONG2CHARS( 0xFFFFFC00 ),
+ LONG2CHARS( 0xFFFFF800 ),
+ LONG2CHARS( 0xFFFFF000 ),
+ LONG2CHARS( 0xFFFFE000 ),
+ LONG2CHARS( 0xFFFFC000 ),
+ LONG2CHARS( 0xFFFF8000 ),
+ LONG2CHARS( 0xFFFF0000 ),
+ LONG2CHARS( 0xFFFE0000 ),
+ LONG2CHARS( 0xFFFC0000 ),
+ LONG2CHARS( 0xFFF80000 ),
+ LONG2CHARS( 0xFFF00000 ),
+ LONG2CHARS( 0xFFE00000 ),
+ LONG2CHARS( 0xFFC00000 ),
+ LONG2CHARS( 0xFF800000 ),
+ LONG2CHARS( 0xFF000000 ),
+ LONG2CHARS( 0xFE000000 ),
+ LONG2CHARS( 0xFC000000 ),
+ LONG2CHARS( 0xF8000000 ),
+ LONG2CHARS( 0xF0000000 ),
+ LONG2CHARS( 0xE0000000 ),
+ LONG2CHARS( 0xC0000000 ),
+ LONG2CHARS( 0x80000000 ),
+ LONG2CHARS( 0x00000000 )
+#else /* PPW == 64 */
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFFE ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFFC ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFF80 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFF00 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFE00 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFC00 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFF800 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFF000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFE000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFC000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFF8000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFF0000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFE0000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFC0000 ),
+ LONG2CHARS( 0xFFFFFFFFFFF80000 ),
+ LONG2CHARS( 0xFFFFFFFFFFF00000 ),
+ LONG2CHARS( 0xFFFFFFFFFFE00000 ),
+ LONG2CHARS( 0xFFFFFFFFFFC00000 ),
+ LONG2CHARS( 0xFFFFFFFFFF800000 ),
+ LONG2CHARS( 0xFFFFFFFFFF000000 ),
+ LONG2CHARS( 0xFFFFFFFFFE000000 ),
+ LONG2CHARS( 0xFFFFFFFFFC000000 ),
+ LONG2CHARS( 0xFFFFFFFFF8000000 ),
+ LONG2CHARS( 0xFFFFFFFFF0000000 ),
+ LONG2CHARS( 0xFFFFFFFFE0000000 ),
+ LONG2CHARS( 0xFFFFFFFFC0000000 ),
+ LONG2CHARS( 0xFFFFFFFF80000000 ),
+ LONG2CHARS( 0xFFFFFFFF00000000 ),
+ LONG2CHARS( 0xFFFFFFFE00000000 ),
+ LONG2CHARS( 0xFFFFFFFC00000000 ),
+ LONG2CHARS( 0xFFFFFFF800000000 ),
+ LONG2CHARS( 0xFFFFFFF000000000 ),
+ LONG2CHARS( 0xFFFFFFE000000000 ),
+ LONG2CHARS( 0xFFFFFFC000000000 ),
+ LONG2CHARS( 0xFFFFFF8000000000 ),
+ LONG2CHARS( 0xFFFFFF0000000000 ),
+ LONG2CHARS( 0xFFFFFE0000000000 ),
+ LONG2CHARS( 0xFFFFFC0000000000 ),
+ LONG2CHARS( 0xFFFFF80000000000 ),
+ LONG2CHARS( 0xFFFFF00000000000 ),
+ LONG2CHARS( 0xFFFFE00000000000 ),
+ LONG2CHARS( 0xFFFFC00000000000 ),
+ LONG2CHARS( 0xFFFF800000000000 ),
+ LONG2CHARS( 0xFFFF000000000000 ),
+ LONG2CHARS( 0xFFFE000000000000 ),
+ LONG2CHARS( 0xFFFC000000000000 ),
+ LONG2CHARS( 0xFFF8000000000000 ),
+ LONG2CHARS( 0xFFF0000000000000 ),
+ LONG2CHARS( 0xFFE0000000000000 ),
+ LONG2CHARS( 0xFFC0000000000000 ),
+ LONG2CHARS( 0xFF80000000000000 ),
+ LONG2CHARS( 0xFF00000000000000 ),
+ LONG2CHARS( 0xFE00000000000000 ),
+ LONG2CHARS( 0xFC00000000000000 ),
+ LONG2CHARS( 0xF800000000000000 ),
+ LONG2CHARS( 0xF000000000000000 ),
+ LONG2CHARS( 0xE000000000000000 ),
+ LONG2CHARS( 0xC000000000000000 ),
+ LONG2CHARS( 0x8000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 )
+#endif /* PPW */
+ };
+
+PixelType endtab[PPW+1] =
+ {
+ LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0x00000001 ),
+ LONG2CHARS( 0x00000003 ),
+ LONG2CHARS( 0x00000007 ),
+ LONG2CHARS( 0x0000000F ),
+ LONG2CHARS( 0x0000001F ),
+ LONG2CHARS( 0x0000003F ),
+ LONG2CHARS( 0x0000007F ),
+ LONG2CHARS( 0x000000FF ),
+ LONG2CHARS( 0x000001FF ),
+ LONG2CHARS( 0x000003FF ),
+ LONG2CHARS( 0x000007FF ),
+ LONG2CHARS( 0x00000FFF ),
+ LONG2CHARS( 0x00001FFF ),
+ LONG2CHARS( 0x00003FFF ),
+ LONG2CHARS( 0x00007FFF ),
+ LONG2CHARS( 0x0000FFFF ),
+ LONG2CHARS( 0x0001FFFF ),
+ LONG2CHARS( 0x0003FFFF ),
+ LONG2CHARS( 0x0007FFFF ),
+ LONG2CHARS( 0x000FFFFF ),
+ LONG2CHARS( 0x001FFFFF ),
+ LONG2CHARS( 0x003FFFFF ),
+ LONG2CHARS( 0x007FFFFF ),
+ LONG2CHARS( 0x00FFFFFF ),
+ LONG2CHARS( 0x01FFFFFF ),
+ LONG2CHARS( 0x03FFFFFF ),
+ LONG2CHARS( 0x07FFFFFF ),
+ LONG2CHARS( 0x0FFFFFFF ),
+ LONG2CHARS( 0x1FFFFFFF ),
+ LONG2CHARS( 0x3FFFFFFF ),
+ LONG2CHARS( 0x7FFFFFFF ),
+ LONG2CHARS( 0xFFFFFFFF )
+#if PPW == 64
+ ,
+ LONG2CHARS( 0x00000001FFFFFFFF ),
+ LONG2CHARS( 0x00000003FFFFFFFF ),
+ LONG2CHARS( 0x00000007FFFFFFFF ),
+ LONG2CHARS( 0x0000000FFFFFFFFF ),
+ LONG2CHARS( 0x0000001FFFFFFFFF ),
+ LONG2CHARS( 0x0000003FFFFFFFFF ),
+ LONG2CHARS( 0x0000007FFFFFFFFF ),
+ LONG2CHARS( 0x000000FFFFFFFFFF ),
+ LONG2CHARS( 0x000001FFFFFFFFFF ),
+ LONG2CHARS( 0x000003FFFFFFFFFF ),
+ LONG2CHARS( 0x000007FFFFFFFFFF ),
+ LONG2CHARS( 0x00000FFFFFFFFFFF ),
+ LONG2CHARS( 0x00001FFFFFFFFFFF ),
+ LONG2CHARS( 0x00003FFFFFFFFFFF ),
+ LONG2CHARS( 0x00007FFFFFFFFFFF ),
+ LONG2CHARS( 0x0000FFFFFFFFFFFF ),
+ LONG2CHARS( 0x0001FFFFFFFFFFFF ),
+ LONG2CHARS( 0x0003FFFFFFFFFFFF ),
+ LONG2CHARS( 0x0007FFFFFFFFFFFF ),
+ LONG2CHARS( 0x000FFFFFFFFFFFFF ),
+ LONG2CHARS( 0x001FFFFFFFFFFFFF ),
+ LONG2CHARS( 0x003FFFFFFFFFFFFF ),
+ LONG2CHARS( 0x007FFFFFFFFFFFFF ),
+ LONG2CHARS( 0x00FFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x01FFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x03FFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x07FFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFFFF ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFFF )
+#endif /* PPW */
+ };
+
+#ifndef LOWMEMFTPT
+
+#ifdef NEED_OLD_MFB_MASKS
+/* a hack ), for now, since the entries for 0 need to be all
+ 1 bits ), not all zeros.
+ this means the code DOES NOT WORK for segments of length
+ 0 (which is only a problem in the horizontal line code.)
+*/
+PixelType startpartial[33] =
+ {
+ LONG2CHARS( 0xFFFFFFFF ),
+ LONG2CHARS( 0xFFFFFFFE ),
+ LONG2CHARS( 0xFFFFFFFC ),
+ LONG2CHARS( 0xFFFFFFF8 ),
+ LONG2CHARS( 0xFFFFFFF0 ),
+ LONG2CHARS( 0xFFFFFFE0 ),
+ LONG2CHARS( 0xFFFFFFC0 ),
+ LONG2CHARS( 0xFFFFFF80 ),
+ LONG2CHARS( 0xFFFFFF00 ),
+ LONG2CHARS( 0xFFFFFE00 ),
+ LONG2CHARS( 0xFFFFFC00 ),
+ LONG2CHARS( 0xFFFFF800 ),
+ LONG2CHARS( 0xFFFFF000 ),
+ LONG2CHARS( 0xFFFFE000 ),
+ LONG2CHARS( 0xFFFFC000 ),
+ LONG2CHARS( 0xFFFF8000 ),
+ LONG2CHARS( 0xFFFF0000 ),
+ LONG2CHARS( 0xFFFE0000 ),
+ LONG2CHARS( 0xFFFC0000 ),
+ LONG2CHARS( 0xFFF80000 ),
+ LONG2CHARS( 0xFFF00000 ),
+ LONG2CHARS( 0xFFE00000 ),
+ LONG2CHARS( 0xFFC00000 ),
+ LONG2CHARS( 0xFF800000 ),
+ LONG2CHARS( 0xFF000000 ),
+ LONG2CHARS( 0xFE000000 ),
+ LONG2CHARS( 0xFC000000 ),
+ LONG2CHARS( 0xF8000000 ),
+ LONG2CHARS( 0xF0000000 ),
+ LONG2CHARS( 0xE0000000 ),
+ LONG2CHARS( 0xC0000000 ),
+ LONG2CHARS( 0x80000000 ),
+ LONG2CHARS( 0x00000000 )
+ };
+
+PixelType endpartial[33] =
+ {
+ LONG2CHARS( 0xFFFFFFFF ),
+ LONG2CHARS( 0x00000001 ),
+ LONG2CHARS( 0x00000003 ),
+ LONG2CHARS( 0x00000007 ),
+ LONG2CHARS( 0x0000000F ),
+ LONG2CHARS( 0x0000001F ),
+ LONG2CHARS( 0x0000003F ),
+ LONG2CHARS( 0x0000007F ),
+ LONG2CHARS( 0x000000FF ),
+ LONG2CHARS( 0x000001FF ),
+ LONG2CHARS( 0x000003FF ),
+ LONG2CHARS( 0x000007FF ),
+ LONG2CHARS( 0x00000FFF ),
+ LONG2CHARS( 0x00001FFF ),
+ LONG2CHARS( 0x00003FFF ),
+ LONG2CHARS( 0x00007FFF ),
+ LONG2CHARS( 0x0000FFFF ),
+ LONG2CHARS( 0x0001FFFF ),
+ LONG2CHARS( 0x0003FFFF ),
+ LONG2CHARS( 0x0007FFFF ),
+ LONG2CHARS( 0x000FFFFF ),
+ LONG2CHARS( 0x001FFFFF ),
+ LONG2CHARS( 0x003FFFFF ),
+ LONG2CHARS( 0x007FFFFF ),
+ LONG2CHARS( 0x00FFFFFF ),
+ LONG2CHARS( 0x01FFFFFF ),
+ LONG2CHARS( 0x03FFFFFF ),
+ LONG2CHARS( 0x07FFFFFF ),
+ LONG2CHARS( 0x0FFFFFFF ),
+ LONG2CHARS( 0x1FFFFFFF ),
+ LONG2CHARS( 0x3FFFFFFF ),
+ LONG2CHARS( 0x7FFFFFFF ),
+ LONG2CHARS( 0xFFFFFFFF )
+ };
+#endif
+
+#endif /* ifndef LOWMEMFTPT */
+
+#if PPW == 32
+PixelType partmasks[PPW][PPW] = {
+ {LONG2CHARS( 0xFFFFFFFF ), LONG2CHARS( 0x00000001 ), LONG2CHARS( 0x00000003 ), LONG2CHARS( 0x00000007 ),
+ LONG2CHARS( 0x0000000F ), LONG2CHARS( 0x0000001F ), LONG2CHARS( 0x0000003F ), LONG2CHARS( 0x0000007F ),
+ LONG2CHARS( 0x000000FF ), LONG2CHARS( 0x000001FF ), LONG2CHARS( 0x000003FF ), LONG2CHARS( 0x000007FF ),
+ LONG2CHARS( 0x00000FFF ), LONG2CHARS( 0x00001FFF ), LONG2CHARS( 0x00003FFF ), LONG2CHARS( 0x00007FFF ),
+ LONG2CHARS( 0x0000FFFF ), LONG2CHARS( 0x0001FFFF ), LONG2CHARS( 0x0003FFFF ), LONG2CHARS( 0x0007FFFF ),
+ LONG2CHARS( 0x000FFFFF ), LONG2CHARS( 0x001FFFFF ), LONG2CHARS( 0x003FFFFF ), LONG2CHARS( 0x007FFFFF ),
+ LONG2CHARS( 0x00FFFFFF ), LONG2CHARS( 0x01FFFFFF ), LONG2CHARS( 0x03FFFFFF ), LONG2CHARS( 0x07FFFFFF ),
+ LONG2CHARS( 0x0FFFFFFF ), LONG2CHARS( 0x1FFFFFFF ), LONG2CHARS( 0x3FFFFFFF ), LONG2CHARS( 0x7FFFFFFF )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000002 ), LONG2CHARS( 0x00000006 ), LONG2CHARS( 0x0000000E ),
+ LONG2CHARS( 0x0000001E ), LONG2CHARS( 0x0000003E ), LONG2CHARS( 0x0000007E ), LONG2CHARS( 0x000000FE ),
+ LONG2CHARS( 0x000001FE ), LONG2CHARS( 0x000003FE ), LONG2CHARS( 0x000007FE ), LONG2CHARS( 0x00000FFE ),
+ LONG2CHARS( 0x00001FFE ), LONG2CHARS( 0x00003FFE ), LONG2CHARS( 0x00007FFE ), LONG2CHARS( 0x0000FFFE ),
+ LONG2CHARS( 0x0001FFFE ), LONG2CHARS( 0x0003FFFE ), LONG2CHARS( 0x0007FFFE ), LONG2CHARS( 0x000FFFFE ),
+ LONG2CHARS( 0x001FFFFE ), LONG2CHARS( 0x003FFFFE ), LONG2CHARS( 0x007FFFFE ), LONG2CHARS( 0x00FFFFFE ),
+ LONG2CHARS( 0x01FFFFFE ), LONG2CHARS( 0x03FFFFFE ), LONG2CHARS( 0x07FFFFFE ), LONG2CHARS( 0x0FFFFFFE ),
+ LONG2CHARS( 0x1FFFFFFE ), LONG2CHARS( 0x3FFFFFFE ), LONG2CHARS( 0x7FFFFFFE ), LONG2CHARS( 0xFFFFFFFE )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000004 ), LONG2CHARS( 0x0000000C ), LONG2CHARS( 0x0000001C ),
+ LONG2CHARS( 0x0000003C ), LONG2CHARS( 0x0000007C ), LONG2CHARS( 0x000000FC ), LONG2CHARS( 0x000001FC ),
+ LONG2CHARS( 0x000003FC ), LONG2CHARS( 0x000007FC ), LONG2CHARS( 0x00000FFC ), LONG2CHARS( 0x00001FFC ),
+ LONG2CHARS( 0x00003FFC ), LONG2CHARS( 0x00007FFC ), LONG2CHARS( 0x0000FFFC ), LONG2CHARS( 0x0001FFFC ),
+ LONG2CHARS( 0x0003FFFC ), LONG2CHARS( 0x0007FFFC ), LONG2CHARS( 0x000FFFFC ), LONG2CHARS( 0x001FFFFC ),
+ LONG2CHARS( 0x003FFFFC ), LONG2CHARS( 0x007FFFFC ), LONG2CHARS( 0x00FFFFFC ), LONG2CHARS( 0x01FFFFFC ),
+ LONG2CHARS( 0x03FFFFFC ), LONG2CHARS( 0x07FFFFFC ), LONG2CHARS( 0x0FFFFFFC ), LONG2CHARS( 0x1FFFFFFC ),
+ LONG2CHARS( 0x3FFFFFFC ), LONG2CHARS( 0x7FFFFFFC ), LONG2CHARS( 0xFFFFFFFC ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000008 ), LONG2CHARS( 0x00000018 ), LONG2CHARS( 0x00000038 ),
+ LONG2CHARS( 0x00000078 ), LONG2CHARS( 0x000000F8 ), LONG2CHARS( 0x000001F8 ), LONG2CHARS( 0x000003F8 ),
+ LONG2CHARS( 0x000007F8 ), LONG2CHARS( 0x00000FF8 ), LONG2CHARS( 0x00001FF8 ), LONG2CHARS( 0x00003FF8 ),
+ LONG2CHARS( 0X00007FF8 ), LONG2CHARS( 0x0000FFF8 ), LONG2CHARS( 0x0001FFF8 ), LONG2CHARS( 0x0003FFF8 ),
+ LONG2CHARS( 0X0007FFF8 ), LONG2CHARS( 0x000FFFF8 ), LONG2CHARS( 0x001FFFF8 ), LONG2CHARS( 0x003FFFF8 ),
+ LONG2CHARS( 0X007FFFF8 ), LONG2CHARS( 0x00FFFFF8 ), LONG2CHARS( 0x01FFFFF8 ), LONG2CHARS( 0x03FFFFF8 ),
+ LONG2CHARS( 0X07FFFFF8 ), LONG2CHARS( 0x0FFFFFF8 ), LONG2CHARS( 0x1FFFFFF8 ), LONG2CHARS( 0x3FFFFFF8 ),
+ LONG2CHARS( 0X7FFFFFF8 ), LONG2CHARS( 0xFFFFFFF8 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000010 ), LONG2CHARS( 0x00000030 ), LONG2CHARS( 0x00000070 ),
+ LONG2CHARS( 0X000000F0 ), LONG2CHARS( 0x000001F0 ), LONG2CHARS( 0x000003F0 ), LONG2CHARS( 0x000007F0 ),
+ LONG2CHARS( 0X00000FF0 ), LONG2CHARS( 0x00001FF0 ), LONG2CHARS( 0x00003FF0 ), LONG2CHARS( 0x00007FF0 ),
+ LONG2CHARS( 0X0000FFF0 ), LONG2CHARS( 0x0001FFF0 ), LONG2CHARS( 0x0003FFF0 ), LONG2CHARS( 0x0007FFF0 ),
+ LONG2CHARS( 0X000FFFF0 ), LONG2CHARS( 0x001FFFF0 ), LONG2CHARS( 0x003FFFF0 ), LONG2CHARS( 0x007FFFF0 ),
+ LONG2CHARS( 0X00FFFFF0 ), LONG2CHARS( 0x01FFFFF0 ), LONG2CHARS( 0x03FFFFF0 ), LONG2CHARS( 0x07FFFFF0 ),
+ LONG2CHARS( 0X0FFFFFF0 ), LONG2CHARS( 0x1FFFFFF0 ), LONG2CHARS( 0x3FFFFFF0 ), LONG2CHARS( 0x7FFFFFF0 ),
+ LONG2CHARS( 0XFFFFFFF0 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000020 ), LONG2CHARS( 0x00000060 ), LONG2CHARS( 0x000000E0 ),
+ LONG2CHARS( 0X000001E0 ), LONG2CHARS( 0x000003E0 ), LONG2CHARS( 0x000007E0 ), LONG2CHARS( 0x00000FE0 ),
+ LONG2CHARS( 0X00001FE0 ), LONG2CHARS( 0x00003FE0 ), LONG2CHARS( 0x00007FE0 ), LONG2CHARS( 0x0000FFE0 ),
+ LONG2CHARS( 0X0001FFE0 ), LONG2CHARS( 0x0003FFE0 ), LONG2CHARS( 0x0007FFE0 ), LONG2CHARS( 0x000FFFE0 ),
+ LONG2CHARS( 0X001FFFE0 ), LONG2CHARS( 0x003FFFE0 ), LONG2CHARS( 0x007FFFE0 ), LONG2CHARS( 0x00FFFFE0 ),
+ LONG2CHARS( 0X01FFFFE0 ), LONG2CHARS( 0x03FFFFE0 ), LONG2CHARS( 0x07FFFFE0 ), LONG2CHARS( 0x0FFFFFE0 ),
+ LONG2CHARS( 0X1FFFFFE0 ), LONG2CHARS( 0x3FFFFFE0 ), LONG2CHARS( 0x7FFFFFE0 ), LONG2CHARS( 0xFFFFFFE0 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000040 ), LONG2CHARS( 0x000000C0 ), LONG2CHARS( 0x000001C0 ),
+ LONG2CHARS( 0X000003C0 ), LONG2CHARS( 0x000007C0 ), LONG2CHARS( 0x00000FC0 ), LONG2CHARS( 0x00001FC0 ),
+ LONG2CHARS( 0X00003FC0 ), LONG2CHARS( 0x00007FC0 ), LONG2CHARS( 0x0000FFC0 ), LONG2CHARS( 0x0001FFC0 ),
+ LONG2CHARS( 0X0003FFC0 ), LONG2CHARS( 0x0007FFC0 ), LONG2CHARS( 0x000FFFC0 ), LONG2CHARS( 0x001FFFC0 ),
+ LONG2CHARS( 0X003FFFC0 ), LONG2CHARS( 0x007FFFC0 ), LONG2CHARS( 0x00FFFFC0 ), LONG2CHARS( 0x01FFFFC0 ),
+ LONG2CHARS( 0X03FFFFC0 ), LONG2CHARS( 0x07FFFFC0 ), LONG2CHARS( 0x0FFFFFC0 ), LONG2CHARS( 0x1FFFFFC0 ),
+ LONG2CHARS( 0X3FFFFFC0 ), LONG2CHARS( 0x7FFFFFC0 ), LONG2CHARS( 0xFFFFFFC0 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000080 ), LONG2CHARS( 0x00000180 ), LONG2CHARS( 0x00000380 ),
+ LONG2CHARS( 0X00000780 ), LONG2CHARS( 0x00000F80 ), LONG2CHARS( 0x00001F80 ), LONG2CHARS( 0x00003F80 ),
+ LONG2CHARS( 0X00007F80 ), LONG2CHARS( 0x0000FF80 ), LONG2CHARS( 0x0001FF80 ), LONG2CHARS( 0x0003FF80 ),
+ LONG2CHARS( 0X0007FF80 ), LONG2CHARS( 0x000FFF80 ), LONG2CHARS( 0x001FFF80 ), LONG2CHARS( 0x003FFF80 ),
+ LONG2CHARS( 0X007FFF80 ), LONG2CHARS( 0x00FFFF80 ), LONG2CHARS( 0x01FFFF80 ), LONG2CHARS( 0x03FFFF80 ),
+ LONG2CHARS( 0X07FFFF80 ), LONG2CHARS( 0x0FFFFF80 ), LONG2CHARS( 0x1FFFFF80 ), LONG2CHARS( 0x3FFFFF80 ),
+ LONG2CHARS( 0X7FFFFF80 ), LONG2CHARS( 0xFFFFFF80 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000100 ), LONG2CHARS( 0x00000300 ), LONG2CHARS( 0x00000700 ),
+ LONG2CHARS( 0X00000F00 ), LONG2CHARS( 0x00001F00 ), LONG2CHARS( 0x00003F00 ), LONG2CHARS( 0x00007F00 ),
+ LONG2CHARS( 0X0000FF00 ), LONG2CHARS( 0x0001FF00 ), LONG2CHARS( 0x0003FF00 ), LONG2CHARS( 0x0007FF00 ),
+ LONG2CHARS( 0X000FFF00 ), LONG2CHARS( 0x001FFF00 ), LONG2CHARS( 0x003FFF00 ), LONG2CHARS( 0x007FFF00 ),
+ LONG2CHARS( 0X00FFFF00 ), LONG2CHARS( 0x01FFFF00 ), LONG2CHARS( 0x03FFFF00 ), LONG2CHARS( 0x07FFFF00 ),
+ LONG2CHARS( 0X0FFFFF00 ), LONG2CHARS( 0x1FFFFF00 ), LONG2CHARS( 0x3FFFFF00 ), LONG2CHARS( 0x7FFFFF00 ),
+ LONG2CHARS( 0XFFFFFF00 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000200 ), LONG2CHARS( 0x00000600 ), LONG2CHARS( 0x00000E00 ),
+ LONG2CHARS( 0X00001E00 ), LONG2CHARS( 0x00003E00 ), LONG2CHARS( 0x00007E00 ), LONG2CHARS( 0x0000FE00 ),
+ LONG2CHARS( 0X0001FE00 ), LONG2CHARS( 0x0003FE00 ), LONG2CHARS( 0x0007FE00 ), LONG2CHARS( 0x000FFE00 ),
+ LONG2CHARS( 0X001FFE00 ), LONG2CHARS( 0x003FFE00 ), LONG2CHARS( 0x007FFE00 ), LONG2CHARS( 0x00FFFE00 ),
+ LONG2CHARS( 0X01FFFE00 ), LONG2CHARS( 0x03FFFE00 ), LONG2CHARS( 0x07FFFE00 ), LONG2CHARS( 0x0FFFFE00 ),
+ LONG2CHARS( 0X1FFFFE00 ), LONG2CHARS( 0x3FFFFE00 ), LONG2CHARS( 0x7FFFFE00 ), LONG2CHARS( 0xFFFFFE00 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000400 ), LONG2CHARS( 0x00000C00 ), LONG2CHARS( 0x00001C00 ),
+ LONG2CHARS( 0X00003C00 ), LONG2CHARS( 0x00007C00 ), LONG2CHARS( 0x0000FC00 ), LONG2CHARS( 0x0001FC00 ),
+ LONG2CHARS( 0X0003FC00 ), LONG2CHARS( 0x0007FC00 ), LONG2CHARS( 0x000FFC00 ), LONG2CHARS( 0x001FFC00 ),
+ LONG2CHARS( 0X003FFC00 ), LONG2CHARS( 0x007FFC00 ), LONG2CHARS( 0x00FFFC00 ), LONG2CHARS( 0x01FFFC00 ),
+ LONG2CHARS( 0X03FFFC00 ), LONG2CHARS( 0x07FFFC00 ), LONG2CHARS( 0x0FFFFC00 ), LONG2CHARS( 0x1FFFFC00 ),
+ LONG2CHARS( 0X3FFFFC00 ), LONG2CHARS( 0x7FFFFC00 ), LONG2CHARS( 0xFFFFFC00 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000800 ), LONG2CHARS( 0x00001800 ), LONG2CHARS( 0x00003800 ),
+ LONG2CHARS( 0X00007800 ), LONG2CHARS( 0x0000F800 ), LONG2CHARS( 0x0001F800 ), LONG2CHARS( 0x0003F800 ),
+ LONG2CHARS( 0X0007F800 ), LONG2CHARS( 0x000FF800 ), LONG2CHARS( 0x001FF800 ), LONG2CHARS( 0x003FF800 ),
+ LONG2CHARS( 0X007FF800 ), LONG2CHARS( 0x00FFF800 ), LONG2CHARS( 0x01FFF800 ), LONG2CHARS( 0x03FFF800 ),
+ LONG2CHARS( 0X07FFF800 ), LONG2CHARS( 0x0FFFF800 ), LONG2CHARS( 0x1FFFF800 ), LONG2CHARS( 0x3FFFF800 ),
+ LONG2CHARS( 0X7FFFF800 ), LONG2CHARS( 0xFFFFF800 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00001000 ), LONG2CHARS( 0x00003000 ), LONG2CHARS( 0x00007000 ),
+ LONG2CHARS( 0X0000F000 ), LONG2CHARS( 0x0001F000 ), LONG2CHARS( 0x0003F000 ), LONG2CHARS( 0x0007F000 ),
+ LONG2CHARS( 0X000FF000 ), LONG2CHARS( 0x001FF000 ), LONG2CHARS( 0x003FF000 ), LONG2CHARS( 0x007FF000 ),
+ LONG2CHARS( 0X00FFF000 ), LONG2CHARS( 0x01FFF000 ), LONG2CHARS( 0x03FFF000 ), LONG2CHARS( 0x07FFF000 ),
+ LONG2CHARS( 0X0FFFF000 ), LONG2CHARS( 0x1FFFF000 ), LONG2CHARS( 0x3FFFF000 ), LONG2CHARS( 0x7FFFF000 ),
+ LONG2CHARS( 0XFFFFF000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00002000 ), LONG2CHARS( 0x00006000 ), LONG2CHARS( 0x0000E000 ),
+ LONG2CHARS( 0X0001E000 ), LONG2CHARS( 0x0003E000 ), LONG2CHARS( 0x0007E000 ), LONG2CHARS( 0x000FE000 ),
+ LONG2CHARS( 0X001FE000 ), LONG2CHARS( 0x003FE000 ), LONG2CHARS( 0x007FE000 ), LONG2CHARS( 0x00FFE000 ),
+ LONG2CHARS( 0X01FFE000 ), LONG2CHARS( 0x03FFE000 ), LONG2CHARS( 0x07FFE000 ), LONG2CHARS( 0x0FFFE000 ),
+ LONG2CHARS( 0X1FFFE000 ), LONG2CHARS( 0x3FFFE000 ), LONG2CHARS( 0x7FFFE000 ), LONG2CHARS( 0xFFFFE000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00004000 ), LONG2CHARS( 0x0000C000 ), LONG2CHARS( 0x0001C000 ),
+ LONG2CHARS( 0X0003C000 ), LONG2CHARS( 0x0007C000 ), LONG2CHARS( 0x000FC000 ), LONG2CHARS( 0x001FC000 ),
+ LONG2CHARS( 0X003FC000 ), LONG2CHARS( 0x007FC000 ), LONG2CHARS( 0x00FFC000 ), LONG2CHARS( 0x01FFC000 ),
+ LONG2CHARS( 0X03FFC000 ), LONG2CHARS( 0x07FFC000 ), LONG2CHARS( 0x0FFFC000 ), LONG2CHARS( 0x1FFFC000 ),
+ LONG2CHARS( 0X3FFFC000 ), LONG2CHARS( 0x7FFFC000 ), LONG2CHARS( 0xFFFFC000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00008000 ), LONG2CHARS( 0x00018000 ), LONG2CHARS( 0x00038000 ),
+ LONG2CHARS( 0X00078000 ), LONG2CHARS( 0x000F8000 ), LONG2CHARS( 0x001F8000 ), LONG2CHARS( 0x003F8000 ),
+ LONG2CHARS( 0X007F8000 ), LONG2CHARS( 0x00FF8000 ), LONG2CHARS( 0x01FF8000 ), LONG2CHARS( 0x03FF8000 ),
+ LONG2CHARS( 0X07FF8000 ), LONG2CHARS( 0x0FFF8000 ), LONG2CHARS( 0x1FFF8000 ), LONG2CHARS( 0x3FFF8000 ),
+ LONG2CHARS( 0X7FFF8000 ), LONG2CHARS( 0xFFFF8000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00010000 ), LONG2CHARS( 0x00030000 ), LONG2CHARS( 0x00070000 ),
+ LONG2CHARS( 0X000F0000 ), LONG2CHARS( 0x001F0000 ), LONG2CHARS( 0x003F0000 ), LONG2CHARS( 0x007F0000 ),
+ LONG2CHARS( 0X00FF0000 ), LONG2CHARS( 0x01FF0000 ), LONG2CHARS( 0x03FF0000 ), LONG2CHARS( 0x07FF0000 ),
+ LONG2CHARS( 0X0FFF0000 ), LONG2CHARS( 0x1FFF0000 ), LONG2CHARS( 0x3FFF0000 ), LONG2CHARS( 0x7FFF0000 ),
+ LONG2CHARS( 0XFFFF0000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00020000 ), LONG2CHARS( 0x00060000 ), LONG2CHARS( 0x000E0000 ),
+ LONG2CHARS( 0X001E0000 ), LONG2CHARS( 0x003E0000 ), LONG2CHARS( 0x007E0000 ), LONG2CHARS( 0x00FE0000 ),
+ LONG2CHARS( 0X01FE0000 ), LONG2CHARS( 0x03FE0000 ), LONG2CHARS( 0x07FE0000 ), LONG2CHARS( 0x0FFE0000 ),
+ LONG2CHARS( 0X1FFE0000 ), LONG2CHARS( 0x3FFE0000 ), LONG2CHARS( 0x7FFE0000 ), LONG2CHARS( 0xFFFE0000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00040000 ), LONG2CHARS( 0x000C0000 ), LONG2CHARS( 0x001C0000 ),
+ LONG2CHARS( 0X003C0000 ), LONG2CHARS( 0x007C0000 ), LONG2CHARS( 0x00FC0000 ), LONG2CHARS( 0x01FC0000 ),
+ LONG2CHARS( 0X03FC0000 ), LONG2CHARS( 0x07FC0000 ), LONG2CHARS( 0x0FFC0000 ), LONG2CHARS( 0x1FFC0000 ),
+ LONG2CHARS( 0X3FFC0000 ), LONG2CHARS( 0x7FFC0000 ), LONG2CHARS( 0xFFFC0000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00080000 ), LONG2CHARS( 0x00180000 ), LONG2CHARS( 0x00380000 ),
+ LONG2CHARS( 0X00780000 ), LONG2CHARS( 0x00F80000 ), LONG2CHARS( 0x01F80000 ), LONG2CHARS( 0x03F80000 ),
+ LONG2CHARS( 0X07F80000 ), LONG2CHARS( 0x0FF80000 ), LONG2CHARS( 0x1FF80000 ), LONG2CHARS( 0x3FF80000 ),
+ LONG2CHARS( 0X7FF80000 ), LONG2CHARS( 0xFFF80000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00100000 ), LONG2CHARS( 0x00300000 ), LONG2CHARS( 0x00700000 ),
+ LONG2CHARS( 0X00F00000 ), LONG2CHARS( 0x01F00000 ), LONG2CHARS( 0x03F00000 ), LONG2CHARS( 0x07F00000 ),
+ LONG2CHARS( 0X0FF00000 ), LONG2CHARS( 0x1FF00000 ), LONG2CHARS( 0x3FF00000 ), LONG2CHARS( 0x7FF00000 ),
+ LONG2CHARS( 0XFFF00000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00200000 ), LONG2CHARS( 0x00600000 ), LONG2CHARS( 0x00E00000 ),
+ LONG2CHARS( 0X01E00000 ), LONG2CHARS( 0x03E00000 ), LONG2CHARS( 0x07E00000 ), LONG2CHARS( 0x0FE00000 ),
+ LONG2CHARS( 0X1FE00000 ), LONG2CHARS( 0x3FE00000 ), LONG2CHARS( 0x7FE00000 ), LONG2CHARS( 0xFFE00000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00400000 ), LONG2CHARS( 0x00C00000 ), LONG2CHARS( 0x01C00000 ),
+ LONG2CHARS( 0X03C00000 ), LONG2CHARS( 0x07C00000 ), LONG2CHARS( 0x0FC00000 ), LONG2CHARS( 0x1FC00000 ),
+ LONG2CHARS( 0X3FC00000 ), LONG2CHARS( 0x7FC00000 ), LONG2CHARS( 0xFFC00000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00800000 ), LONG2CHARS( 0x01800000 ), LONG2CHARS( 0x03800000 ),
+ LONG2CHARS( 0X07800000 ), LONG2CHARS( 0x0F800000 ), LONG2CHARS( 0x1F800000 ), LONG2CHARS( 0x3F800000 ),
+ LONG2CHARS( 0X7F800000 ), LONG2CHARS( 0xFF800000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x01000000 ), LONG2CHARS( 0x03000000 ), LONG2CHARS( 0x07000000 ),
+ LONG2CHARS( 0X0F000000 ), LONG2CHARS( 0x1F000000 ), LONG2CHARS( 0x3F000000 ), LONG2CHARS( 0x7F000000 ),
+ LONG2CHARS( 0XFF000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x02000000 ), LONG2CHARS( 0x06000000 ), LONG2CHARS( 0x0E000000 ),
+ LONG2CHARS( 0X1E000000 ), LONG2CHARS( 0x3E000000 ), LONG2CHARS( 0x7E000000 ), LONG2CHARS( 0xFE000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x04000000 ), LONG2CHARS( 0x0C000000 ), LONG2CHARS( 0x1C000000 ),
+ LONG2CHARS( 0X3C000000 ), LONG2CHARS( 0x7C000000 ), LONG2CHARS( 0xFC000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x08000000 ), LONG2CHARS( 0x18000000 ), LONG2CHARS( 0x38000000 ),
+ LONG2CHARS( 0X78000000 ), LONG2CHARS( 0xF8000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x10000000 ), LONG2CHARS( 0x30000000 ), LONG2CHARS( 0x70000000 ),
+ LONG2CHARS( 0XF0000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x20000000 ), LONG2CHARS( 0x60000000 ), LONG2CHARS( 0xE0000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x40000000 ), LONG2CHARS( 0xC0000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+ {LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x80000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ),
+ LONG2CHARS( 0X00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 ), LONG2CHARS( 0x00000000 )},
+};
+#else /* PPW == 64 */
+unsigned long partmasks[PPW][PPW] = {
+ {
+ LONG2CHARS( 0xFFFFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x0000000000000001 ),
+ LONG2CHARS( 0x0000000000000003 ),
+ LONG2CHARS( 0x0000000000000007 ),
+ LONG2CHARS( 0x000000000000000F ),
+ LONG2CHARS( 0x000000000000001F ),
+ LONG2CHARS( 0x000000000000003F ),
+ LONG2CHARS( 0x000000000000007F ),
+ LONG2CHARS( 0x00000000000000FF ),
+ LONG2CHARS( 0x00000000000001FF ),
+ LONG2CHARS( 0x00000000000003FF ),
+ LONG2CHARS( 0x00000000000007FF ),
+ LONG2CHARS( 0x0000000000000FFF ),
+ LONG2CHARS( 0x0000000000001FFF ),
+ LONG2CHARS( 0x0000000000003FFF ),
+ LONG2CHARS( 0x0000000000007FFF ),
+ LONG2CHARS( 0x000000000000FFFF ),
+ LONG2CHARS( 0x000000000001FFFF ),
+ LONG2CHARS( 0x000000000003FFFF ),
+ LONG2CHARS( 0x000000000007FFFF ),
+ LONG2CHARS( 0x00000000000FFFFF ),
+ LONG2CHARS( 0x00000000001FFFFF ),
+ LONG2CHARS( 0x00000000003FFFFF ),
+ LONG2CHARS( 0x00000000007FFFFF ),
+ LONG2CHARS( 0x0000000000FFFFFF ),
+ LONG2CHARS( 0x0000000001FFFFFF ),
+ LONG2CHARS( 0x0000000003FFFFFF ),
+ LONG2CHARS( 0x0000000007FFFFFF ),
+ LONG2CHARS( 0x000000000FFFFFFF ),
+ LONG2CHARS( 0x000000001FFFFFFF ),
+ LONG2CHARS( 0x000000003FFFFFFF ),
+ LONG2CHARS( 0x000000007FFFFFFF ),
+ LONG2CHARS( 0x00000000FFFFFFFF ),
+ LONG2CHARS( 0x00000001FFFFFFFF ),
+ LONG2CHARS( 0x00000003FFFFFFFF ),
+ LONG2CHARS( 0x00000007FFFFFFFF ),
+ LONG2CHARS( 0x0000000FFFFFFFFF ),
+ LONG2CHARS( 0x0000001FFFFFFFFF ),
+ LONG2CHARS( 0x0000003FFFFFFFFF ),
+ LONG2CHARS( 0x0000007FFFFFFFFF ),
+ LONG2CHARS( 0x000000FFFFFFFFFF ),
+ LONG2CHARS( 0x000001FFFFFFFFFF ),
+ LONG2CHARS( 0x000003FFFFFFFFFF ),
+ LONG2CHARS( 0x000007FFFFFFFFFF ),
+ LONG2CHARS( 0x00000FFFFFFFFFFF ),
+ LONG2CHARS( 0x00001FFFFFFFFFFF ),
+ LONG2CHARS( 0x00003FFFFFFFFFFF ),
+ LONG2CHARS( 0x00007FFFFFFFFFFF ),
+ LONG2CHARS( 0x0000FFFFFFFFFFFF ),
+ LONG2CHARS( 0x0001FFFFFFFFFFFF ),
+ LONG2CHARS( 0x0003FFFFFFFFFFFF ),
+ LONG2CHARS( 0x0007FFFFFFFFFFFF ),
+ LONG2CHARS( 0x000FFFFFFFFFFFFF ),
+ LONG2CHARS( 0x001FFFFFFFFFFFFF ),
+ LONG2CHARS( 0x003FFFFFFFFFFFFF ),
+ LONG2CHARS( 0x007FFFFFFFFFFFFF ),
+ LONG2CHARS( 0x00FFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x01FFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x03FFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x07FFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFFFF ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFFFF ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000002 ),
+ LONG2CHARS( 0x0000000000000006 ),
+ LONG2CHARS( 0x000000000000000E ),
+ LONG2CHARS( 0x000000000000001E ),
+ LONG2CHARS( 0x000000000000003E ),
+ LONG2CHARS( 0x000000000000007E ),
+ LONG2CHARS( 0x00000000000000FE ),
+ LONG2CHARS( 0x00000000000001FE ),
+ LONG2CHARS( 0x00000000000003FE ),
+ LONG2CHARS( 0x00000000000007FE ),
+ LONG2CHARS( 0x0000000000000FFE ),
+ LONG2CHARS( 0x0000000000001FFE ),
+ LONG2CHARS( 0x0000000000003FFE ),
+ LONG2CHARS( 0x0000000000007FFE ),
+ LONG2CHARS( 0x000000000000FFFE ),
+ LONG2CHARS( 0x000000000001FFFE ),
+ LONG2CHARS( 0x000000000003FFFE ),
+ LONG2CHARS( 0x000000000007FFFE ),
+ LONG2CHARS( 0x00000000000FFFFE ),
+ LONG2CHARS( 0x00000000001FFFFE ),
+ LONG2CHARS( 0x00000000003FFFFE ),
+ LONG2CHARS( 0x00000000007FFFFE ),
+ LONG2CHARS( 0x0000000000FFFFFE ),
+ LONG2CHARS( 0x0000000001FFFFFE ),
+ LONG2CHARS( 0x0000000003FFFFFE ),
+ LONG2CHARS( 0x0000000007FFFFFE ),
+ LONG2CHARS( 0x000000000FFFFFFE ),
+ LONG2CHARS( 0x000000001FFFFFFE ),
+ LONG2CHARS( 0x000000003FFFFFFE ),
+ LONG2CHARS( 0x000000007FFFFFFE ),
+ LONG2CHARS( 0x00000000FFFFFFFE ),
+ LONG2CHARS( 0x00000001FFFFFFFE ),
+ LONG2CHARS( 0x00000003FFFFFFFE ),
+ LONG2CHARS( 0x00000007FFFFFFFE ),
+ LONG2CHARS( 0x0000000FFFFFFFFE ),
+ LONG2CHARS( 0x0000001FFFFFFFFE ),
+ LONG2CHARS( 0x0000003FFFFFFFFE ),
+ LONG2CHARS( 0x0000007FFFFFFFFE ),
+ LONG2CHARS( 0x000000FFFFFFFFFE ),
+ LONG2CHARS( 0x000001FFFFFFFFFE ),
+ LONG2CHARS( 0x000003FFFFFFFFFE ),
+ LONG2CHARS( 0x000007FFFFFFFFFE ),
+ LONG2CHARS( 0x00000FFFFFFFFFFE ),
+ LONG2CHARS( 0x00001FFFFFFFFFFE ),
+ LONG2CHARS( 0x00003FFFFFFFFFFE ),
+ LONG2CHARS( 0x00007FFFFFFFFFFE ),
+ LONG2CHARS( 0x0000FFFFFFFFFFFE ),
+ LONG2CHARS( 0x0001FFFFFFFFFFFE ),
+ LONG2CHARS( 0x0003FFFFFFFFFFFE ),
+ LONG2CHARS( 0x0007FFFFFFFFFFFE ),
+ LONG2CHARS( 0x000FFFFFFFFFFFFE ),
+ LONG2CHARS( 0x001FFFFFFFFFFFFE ),
+ LONG2CHARS( 0x003FFFFFFFFFFFFE ),
+ LONG2CHARS( 0x007FFFFFFFFFFFFE ),
+ LONG2CHARS( 0x00FFFFFFFFFFFFFE ),
+ LONG2CHARS( 0x01FFFFFFFFFFFFFE ),
+ LONG2CHARS( 0x03FFFFFFFFFFFFFE ),
+ LONG2CHARS( 0x07FFFFFFFFFFFFFE ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFFFE ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFFFE ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFFFE ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFFFE ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFFE ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000004 ),
+ LONG2CHARS( 0x000000000000000C ),
+ LONG2CHARS( 0x000000000000001C ),
+ LONG2CHARS( 0x000000000000003C ),
+ LONG2CHARS( 0x000000000000007C ),
+ LONG2CHARS( 0x00000000000000FC ),
+ LONG2CHARS( 0x00000000000001FC ),
+ LONG2CHARS( 0x00000000000003FC ),
+ LONG2CHARS( 0x00000000000007FC ),
+ LONG2CHARS( 0x0000000000000FFC ),
+ LONG2CHARS( 0x0000000000001FFC ),
+ LONG2CHARS( 0x0000000000003FFC ),
+ LONG2CHARS( 0x0000000000007FFC ),
+ LONG2CHARS( 0x000000000000FFFC ),
+ LONG2CHARS( 0x000000000001FFFC ),
+ LONG2CHARS( 0x000000000003FFFC ),
+ LONG2CHARS( 0x000000000007FFFC ),
+ LONG2CHARS( 0x00000000000FFFFC ),
+ LONG2CHARS( 0x00000000001FFFFC ),
+ LONG2CHARS( 0x00000000003FFFFC ),
+ LONG2CHARS( 0x00000000007FFFFC ),
+ LONG2CHARS( 0x0000000000FFFFFC ),
+ LONG2CHARS( 0x0000000001FFFFFC ),
+ LONG2CHARS( 0x0000000003FFFFFC ),
+ LONG2CHARS( 0x0000000007FFFFFC ),
+ LONG2CHARS( 0x000000000FFFFFFC ),
+ LONG2CHARS( 0x000000001FFFFFFC ),
+ LONG2CHARS( 0x000000003FFFFFFC ),
+ LONG2CHARS( 0x000000007FFFFFFC ),
+ LONG2CHARS( 0x00000000FFFFFFFC ),
+ LONG2CHARS( 0x00000001FFFFFFFC ),
+ LONG2CHARS( 0x00000003FFFFFFFC ),
+ LONG2CHARS( 0x00000007FFFFFFFC ),
+ LONG2CHARS( 0x0000000FFFFFFFFC ),
+ LONG2CHARS( 0x0000001FFFFFFFFC ),
+ LONG2CHARS( 0x0000003FFFFFFFFC ),
+ LONG2CHARS( 0x0000007FFFFFFFFC ),
+ LONG2CHARS( 0x000000FFFFFFFFFC ),
+ LONG2CHARS( 0x000001FFFFFFFFFC ),
+ LONG2CHARS( 0x000003FFFFFFFFFC ),
+ LONG2CHARS( 0x000007FFFFFFFFFC ),
+ LONG2CHARS( 0x00000FFFFFFFFFFC ),
+ LONG2CHARS( 0x00001FFFFFFFFFFC ),
+ LONG2CHARS( 0x00003FFFFFFFFFFC ),
+ LONG2CHARS( 0x00007FFFFFFFFFFC ),
+ LONG2CHARS( 0x0000FFFFFFFFFFFC ),
+ LONG2CHARS( 0x0001FFFFFFFFFFFC ),
+ LONG2CHARS( 0x0003FFFFFFFFFFFC ),
+ LONG2CHARS( 0x0007FFFFFFFFFFFC ),
+ LONG2CHARS( 0x000FFFFFFFFFFFFC ),
+ LONG2CHARS( 0x001FFFFFFFFFFFFC ),
+ LONG2CHARS( 0x003FFFFFFFFFFFFC ),
+ LONG2CHARS( 0x007FFFFFFFFFFFFC ),
+ LONG2CHARS( 0x00FFFFFFFFFFFFFC ),
+ LONG2CHARS( 0x01FFFFFFFFFFFFFC ),
+ LONG2CHARS( 0x03FFFFFFFFFFFFFC ),
+ LONG2CHARS( 0x07FFFFFFFFFFFFFC ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFFFC ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFFFC ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFFFC ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFFFC ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFFC ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000008 ),
+ LONG2CHARS( 0x0000000000000018 ),
+ LONG2CHARS( 0x0000000000000038 ),
+ LONG2CHARS( 0x0000000000000078 ),
+ LONG2CHARS( 0x00000000000000F8 ),
+ LONG2CHARS( 0x00000000000001F8 ),
+ LONG2CHARS( 0x00000000000003F8 ),
+ LONG2CHARS( 0x00000000000007F8 ),
+ LONG2CHARS( 0x0000000000000FF8 ),
+ LONG2CHARS( 0x0000000000001FF8 ),
+ LONG2CHARS( 0x0000000000003FF8 ),
+ LONG2CHARS( 0x0000000000007FF8 ),
+ LONG2CHARS( 0x000000000000FFF8 ),
+ LONG2CHARS( 0x000000000001FFF8 ),
+ LONG2CHARS( 0x000000000003FFF8 ),
+ LONG2CHARS( 0x000000000007FFF8 ),
+ LONG2CHARS( 0x00000000000FFFF8 ),
+ LONG2CHARS( 0x00000000001FFFF8 ),
+ LONG2CHARS( 0x00000000003FFFF8 ),
+ LONG2CHARS( 0x00000000007FFFF8 ),
+ LONG2CHARS( 0x0000000000FFFFF8 ),
+ LONG2CHARS( 0x0000000001FFFFF8 ),
+ LONG2CHARS( 0x0000000003FFFFF8 ),
+ LONG2CHARS( 0x0000000007FFFFF8 ),
+ LONG2CHARS( 0x000000000FFFFFF8 ),
+ LONG2CHARS( 0x000000001FFFFFF8 ),
+ LONG2CHARS( 0x000000003FFFFFF8 ),
+ LONG2CHARS( 0x000000007FFFFFF8 ),
+ LONG2CHARS( 0x00000000FFFFFFF8 ),
+ LONG2CHARS( 0x00000001FFFFFFF8 ),
+ LONG2CHARS( 0x00000003FFFFFFF8 ),
+ LONG2CHARS( 0x00000007FFFFFFF8 ),
+ LONG2CHARS( 0x0000000FFFFFFFF8 ),
+ LONG2CHARS( 0x0000001FFFFFFFF8 ),
+ LONG2CHARS( 0x0000003FFFFFFFF8 ),
+ LONG2CHARS( 0x0000007FFFFFFFF8 ),
+ LONG2CHARS( 0x000000FFFFFFFFF8 ),
+ LONG2CHARS( 0x000001FFFFFFFFF8 ),
+ LONG2CHARS( 0x000003FFFFFFFFF8 ),
+ LONG2CHARS( 0x000007FFFFFFFFF8 ),
+ LONG2CHARS( 0x00000FFFFFFFFFF8 ),
+ LONG2CHARS( 0x00001FFFFFFFFFF8 ),
+ LONG2CHARS( 0x00003FFFFFFFFFF8 ),
+ LONG2CHARS( 0x00007FFFFFFFFFF8 ),
+ LONG2CHARS( 0x0000FFFFFFFFFFF8 ),
+ LONG2CHARS( 0x0001FFFFFFFFFFF8 ),
+ LONG2CHARS( 0x0003FFFFFFFFFFF8 ),
+ LONG2CHARS( 0x0007FFFFFFFFFFF8 ),
+ LONG2CHARS( 0x000FFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x001FFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x003FFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x007FFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x00FFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x01FFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x03FFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x07FFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFF8 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000010 ),
+ LONG2CHARS( 0x0000000000000030 ),
+ LONG2CHARS( 0x0000000000000070 ),
+ LONG2CHARS( 0x00000000000000F0 ),
+ LONG2CHARS( 0x00000000000001F0 ),
+ LONG2CHARS( 0x00000000000003F0 ),
+ LONG2CHARS( 0x00000000000007F0 ),
+ LONG2CHARS( 0x0000000000000FF0 ),
+ LONG2CHARS( 0x0000000000001FF0 ),
+ LONG2CHARS( 0x0000000000003FF0 ),
+ LONG2CHARS( 0x0000000000007FF0 ),
+ LONG2CHARS( 0x000000000000FFF0 ),
+ LONG2CHARS( 0x000000000001FFF0 ),
+ LONG2CHARS( 0x000000000003FFF0 ),
+ LONG2CHARS( 0x000000000007FFF0 ),
+ LONG2CHARS( 0x00000000000FFFF0 ),
+ LONG2CHARS( 0x00000000001FFFF0 ),
+ LONG2CHARS( 0x00000000003FFFF0 ),
+ LONG2CHARS( 0x00000000007FFFF0 ),
+ LONG2CHARS( 0x0000000000FFFFF0 ),
+ LONG2CHARS( 0x0000000001FFFFF0 ),
+ LONG2CHARS( 0x0000000003FFFFF0 ),
+ LONG2CHARS( 0x0000000007FFFFF0 ),
+ LONG2CHARS( 0x000000000FFFFFF0 ),
+ LONG2CHARS( 0x000000001FFFFFF0 ),
+ LONG2CHARS( 0x000000003FFFFFF0 ),
+ LONG2CHARS( 0x000000007FFFFFF0 ),
+ LONG2CHARS( 0x00000000FFFFFFF0 ),
+ LONG2CHARS( 0x00000001FFFFFFF0 ),
+ LONG2CHARS( 0x00000003FFFFFFF0 ),
+ LONG2CHARS( 0x00000007FFFFFFF0 ),
+ LONG2CHARS( 0x0000000FFFFFFFF0 ),
+ LONG2CHARS( 0x0000001FFFFFFFF0 ),
+ LONG2CHARS( 0x0000003FFFFFFFF0 ),
+ LONG2CHARS( 0x0000007FFFFFFFF0 ),
+ LONG2CHARS( 0x000000FFFFFFFFF0 ),
+ LONG2CHARS( 0x000001FFFFFFFFF0 ),
+ LONG2CHARS( 0x000003FFFFFFFFF0 ),
+ LONG2CHARS( 0x000007FFFFFFFFF0 ),
+ LONG2CHARS( 0x00000FFFFFFFFFF0 ),
+ LONG2CHARS( 0x00001FFFFFFFFFF0 ),
+ LONG2CHARS( 0x00003FFFFFFFFFF0 ),
+ LONG2CHARS( 0x00007FFFFFFFFFF0 ),
+ LONG2CHARS( 0x0000FFFFFFFFFFF0 ),
+ LONG2CHARS( 0x0001FFFFFFFFFFF0 ),
+ LONG2CHARS( 0x0003FFFFFFFFFFF0 ),
+ LONG2CHARS( 0x0007FFFFFFFFFFF0 ),
+ LONG2CHARS( 0x000FFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x001FFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x003FFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x007FFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x00FFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x01FFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x03FFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x07FFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFF0 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000020 ),
+ LONG2CHARS( 0x0000000000000060 ),
+ LONG2CHARS( 0x00000000000000E0 ),
+ LONG2CHARS( 0x00000000000001E0 ),
+ LONG2CHARS( 0x00000000000003E0 ),
+ LONG2CHARS( 0x00000000000007E0 ),
+ LONG2CHARS( 0x0000000000000FE0 ),
+ LONG2CHARS( 0x0000000000001FE0 ),
+ LONG2CHARS( 0x0000000000003FE0 ),
+ LONG2CHARS( 0x0000000000007FE0 ),
+ LONG2CHARS( 0x000000000000FFE0 ),
+ LONG2CHARS( 0x000000000001FFE0 ),
+ LONG2CHARS( 0x000000000003FFE0 ),
+ LONG2CHARS( 0x000000000007FFE0 ),
+ LONG2CHARS( 0x00000000000FFFE0 ),
+ LONG2CHARS( 0x00000000001FFFE0 ),
+ LONG2CHARS( 0x00000000003FFFE0 ),
+ LONG2CHARS( 0x00000000007FFFE0 ),
+ LONG2CHARS( 0x0000000000FFFFE0 ),
+ LONG2CHARS( 0x0000000001FFFFE0 ),
+ LONG2CHARS( 0x0000000003FFFFE0 ),
+ LONG2CHARS( 0x0000000007FFFFE0 ),
+ LONG2CHARS( 0x000000000FFFFFE0 ),
+ LONG2CHARS( 0x000000001FFFFFE0 ),
+ LONG2CHARS( 0x000000003FFFFFE0 ),
+ LONG2CHARS( 0x000000007FFFFFE0 ),
+ LONG2CHARS( 0x00000000FFFFFFE0 ),
+ LONG2CHARS( 0x00000001FFFFFFE0 ),
+ LONG2CHARS( 0x00000003FFFFFFE0 ),
+ LONG2CHARS( 0x00000007FFFFFFE0 ),
+ LONG2CHARS( 0x0000000FFFFFFFE0 ),
+ LONG2CHARS( 0x0000001FFFFFFFE0 ),
+ LONG2CHARS( 0x0000003FFFFFFFE0 ),
+ LONG2CHARS( 0x0000007FFFFFFFE0 ),
+ LONG2CHARS( 0x000000FFFFFFFFE0 ),
+ LONG2CHARS( 0x000001FFFFFFFFE0 ),
+ LONG2CHARS( 0x000003FFFFFFFFE0 ),
+ LONG2CHARS( 0x000007FFFFFFFFE0 ),
+ LONG2CHARS( 0x00000FFFFFFFFFE0 ),
+ LONG2CHARS( 0x00001FFFFFFFFFE0 ),
+ LONG2CHARS( 0x00003FFFFFFFFFE0 ),
+ LONG2CHARS( 0x00007FFFFFFFFFE0 ),
+ LONG2CHARS( 0x0000FFFFFFFFFFE0 ),
+ LONG2CHARS( 0x0001FFFFFFFFFFE0 ),
+ LONG2CHARS( 0x0003FFFFFFFFFFE0 ),
+ LONG2CHARS( 0x0007FFFFFFFFFFE0 ),
+ LONG2CHARS( 0x000FFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x001FFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x003FFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x007FFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x00FFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x01FFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x03FFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x07FFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFE0 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000040 ),
+ LONG2CHARS( 0x00000000000000C0 ),
+ LONG2CHARS( 0x00000000000001C0 ),
+ LONG2CHARS( 0x00000000000003C0 ),
+ LONG2CHARS( 0x00000000000007C0 ),
+ LONG2CHARS( 0x0000000000000FC0 ),
+ LONG2CHARS( 0x0000000000001FC0 ),
+ LONG2CHARS( 0x0000000000003FC0 ),
+ LONG2CHARS( 0x0000000000007FC0 ),
+ LONG2CHARS( 0x000000000000FFC0 ),
+ LONG2CHARS( 0x000000000001FFC0 ),
+ LONG2CHARS( 0x000000000003FFC0 ),
+ LONG2CHARS( 0x000000000007FFC0 ),
+ LONG2CHARS( 0x00000000000FFFC0 ),
+ LONG2CHARS( 0x00000000001FFFC0 ),
+ LONG2CHARS( 0x00000000003FFFC0 ),
+ LONG2CHARS( 0x00000000007FFFC0 ),
+ LONG2CHARS( 0x0000000000FFFFC0 ),
+ LONG2CHARS( 0x0000000001FFFFC0 ),
+ LONG2CHARS( 0x0000000003FFFFC0 ),
+ LONG2CHARS( 0x0000000007FFFFC0 ),
+ LONG2CHARS( 0x000000000FFFFFC0 ),
+ LONG2CHARS( 0x000000001FFFFFC0 ),
+ LONG2CHARS( 0x000000003FFFFFC0 ),
+ LONG2CHARS( 0x000000007FFFFFC0 ),
+ LONG2CHARS( 0x00000000FFFFFFC0 ),
+ LONG2CHARS( 0x00000001FFFFFFC0 ),
+ LONG2CHARS( 0x00000003FFFFFFC0 ),
+ LONG2CHARS( 0x00000007FFFFFFC0 ),
+ LONG2CHARS( 0x0000000FFFFFFFC0 ),
+ LONG2CHARS( 0x0000001FFFFFFFC0 ),
+ LONG2CHARS( 0x0000003FFFFFFFC0 ),
+ LONG2CHARS( 0x0000007FFFFFFFC0 ),
+ LONG2CHARS( 0x000000FFFFFFFFC0 ),
+ LONG2CHARS( 0x000001FFFFFFFFC0 ),
+ LONG2CHARS( 0x000003FFFFFFFFC0 ),
+ LONG2CHARS( 0x000007FFFFFFFFC0 ),
+ LONG2CHARS( 0x00000FFFFFFFFFC0 ),
+ LONG2CHARS( 0x00001FFFFFFFFFC0 ),
+ LONG2CHARS( 0x00003FFFFFFFFFC0 ),
+ LONG2CHARS( 0x00007FFFFFFFFFC0 ),
+ LONG2CHARS( 0x0000FFFFFFFFFFC0 ),
+ LONG2CHARS( 0x0001FFFFFFFFFFC0 ),
+ LONG2CHARS( 0x0003FFFFFFFFFFC0 ),
+ LONG2CHARS( 0x0007FFFFFFFFFFC0 ),
+ LONG2CHARS( 0x000FFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x001FFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x003FFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x007FFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x00FFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x01FFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x03FFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x07FFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFFC0 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000080 ),
+ LONG2CHARS( 0x0000000000000180 ),
+ LONG2CHARS( 0x0000000000000380 ),
+ LONG2CHARS( 0x0000000000000780 ),
+ LONG2CHARS( 0x0000000000000F80 ),
+ LONG2CHARS( 0x0000000000001F80 ),
+ LONG2CHARS( 0x0000000000003F80 ),
+ LONG2CHARS( 0x0000000000007F80 ),
+ LONG2CHARS( 0x000000000000FF80 ),
+ LONG2CHARS( 0x000000000001FF80 ),
+ LONG2CHARS( 0x000000000003FF80 ),
+ LONG2CHARS( 0x000000000007FF80 ),
+ LONG2CHARS( 0x00000000000FFF80 ),
+ LONG2CHARS( 0x00000000001FFF80 ),
+ LONG2CHARS( 0x00000000003FFF80 ),
+ LONG2CHARS( 0x00000000007FFF80 ),
+ LONG2CHARS( 0x0000000000FFFF80 ),
+ LONG2CHARS( 0x0000000001FFFF80 ),
+ LONG2CHARS( 0x0000000003FFFF80 ),
+ LONG2CHARS( 0x0000000007FFFF80 ),
+ LONG2CHARS( 0x000000000FFFFF80 ),
+ LONG2CHARS( 0x000000001FFFFF80 ),
+ LONG2CHARS( 0x000000003FFFFF80 ),
+ LONG2CHARS( 0x000000007FFFFF80 ),
+ LONG2CHARS( 0x00000000FFFFFF80 ),
+ LONG2CHARS( 0x00000001FFFFFF80 ),
+ LONG2CHARS( 0x00000003FFFFFF80 ),
+ LONG2CHARS( 0x00000007FFFFFF80 ),
+ LONG2CHARS( 0x0000000FFFFFFF80 ),
+ LONG2CHARS( 0x0000001FFFFFFF80 ),
+ LONG2CHARS( 0x0000003FFFFFFF80 ),
+ LONG2CHARS( 0x0000007FFFFFFF80 ),
+ LONG2CHARS( 0x000000FFFFFFFF80 ),
+ LONG2CHARS( 0x000001FFFFFFFF80 ),
+ LONG2CHARS( 0x000003FFFFFFFF80 ),
+ LONG2CHARS( 0x000007FFFFFFFF80 ),
+ LONG2CHARS( 0x00000FFFFFFFFF80 ),
+ LONG2CHARS( 0x00001FFFFFFFFF80 ),
+ LONG2CHARS( 0x00003FFFFFFFFF80 ),
+ LONG2CHARS( 0x00007FFFFFFFFF80 ),
+ LONG2CHARS( 0x0000FFFFFFFFFF80 ),
+ LONG2CHARS( 0x0001FFFFFFFFFF80 ),
+ LONG2CHARS( 0x0003FFFFFFFFFF80 ),
+ LONG2CHARS( 0x0007FFFFFFFFFF80 ),
+ LONG2CHARS( 0x000FFFFFFFFFFF80 ),
+ LONG2CHARS( 0x001FFFFFFFFFFF80 ),
+ LONG2CHARS( 0x003FFFFFFFFFFF80 ),
+ LONG2CHARS( 0x007FFFFFFFFFFF80 ),
+ LONG2CHARS( 0x00FFFFFFFFFFFF80 ),
+ LONG2CHARS( 0x01FFFFFFFFFFFF80 ),
+ LONG2CHARS( 0x03FFFFFFFFFFFF80 ),
+ LONG2CHARS( 0x07FFFFFFFFFFFF80 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFF80 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFF80 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFF80 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFF80 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFF80 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000100 ),
+ LONG2CHARS( 0x0000000000000300 ),
+ LONG2CHARS( 0x0000000000000700 ),
+ LONG2CHARS( 0x0000000000000F00 ),
+ LONG2CHARS( 0x0000000000001F00 ),
+ LONG2CHARS( 0x0000000000003F00 ),
+ LONG2CHARS( 0x0000000000007F00 ),
+ LONG2CHARS( 0x000000000000FF00 ),
+ LONG2CHARS( 0x000000000001FF00 ),
+ LONG2CHARS( 0x000000000003FF00 ),
+ LONG2CHARS( 0x000000000007FF00 ),
+ LONG2CHARS( 0x00000000000FFF00 ),
+ LONG2CHARS( 0x00000000001FFF00 ),
+ LONG2CHARS( 0x00000000003FFF00 ),
+ LONG2CHARS( 0x00000000007FFF00 ),
+ LONG2CHARS( 0x0000000000FFFF00 ),
+ LONG2CHARS( 0x0000000001FFFF00 ),
+ LONG2CHARS( 0x0000000003FFFF00 ),
+ LONG2CHARS( 0x0000000007FFFF00 ),
+ LONG2CHARS( 0x000000000FFFFF00 ),
+ LONG2CHARS( 0x000000001FFFFF00 ),
+ LONG2CHARS( 0x000000003FFFFF00 ),
+ LONG2CHARS( 0x000000007FFFFF00 ),
+ LONG2CHARS( 0x00000000FFFFFF00 ),
+ LONG2CHARS( 0x00000001FFFFFF00 ),
+ LONG2CHARS( 0x00000003FFFFFF00 ),
+ LONG2CHARS( 0x00000007FFFFFF00 ),
+ LONG2CHARS( 0x0000000FFFFFFF00 ),
+ LONG2CHARS( 0x0000001FFFFFFF00 ),
+ LONG2CHARS( 0x0000003FFFFFFF00 ),
+ LONG2CHARS( 0x0000007FFFFFFF00 ),
+ LONG2CHARS( 0x000000FFFFFFFF00 ),
+ LONG2CHARS( 0x000001FFFFFFFF00 ),
+ LONG2CHARS( 0x000003FFFFFFFF00 ),
+ LONG2CHARS( 0x000007FFFFFFFF00 ),
+ LONG2CHARS( 0x00000FFFFFFFFF00 ),
+ LONG2CHARS( 0x00001FFFFFFFFF00 ),
+ LONG2CHARS( 0x00003FFFFFFFFF00 ),
+ LONG2CHARS( 0x00007FFFFFFFFF00 ),
+ LONG2CHARS( 0x0000FFFFFFFFFF00 ),
+ LONG2CHARS( 0x0001FFFFFFFFFF00 ),
+ LONG2CHARS( 0x0003FFFFFFFFFF00 ),
+ LONG2CHARS( 0x0007FFFFFFFFFF00 ),
+ LONG2CHARS( 0x000FFFFFFFFFFF00 ),
+ LONG2CHARS( 0x001FFFFFFFFFFF00 ),
+ LONG2CHARS( 0x003FFFFFFFFFFF00 ),
+ LONG2CHARS( 0x007FFFFFFFFFFF00 ),
+ LONG2CHARS( 0x00FFFFFFFFFFFF00 ),
+ LONG2CHARS( 0x01FFFFFFFFFFFF00 ),
+ LONG2CHARS( 0x03FFFFFFFFFFFF00 ),
+ LONG2CHARS( 0x07FFFFFFFFFFFF00 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFF00 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFF00 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFF00 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFF00 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFF00 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000200 ),
+ LONG2CHARS( 0x0000000000000600 ),
+ LONG2CHARS( 0x0000000000000E00 ),
+ LONG2CHARS( 0x0000000000001E00 ),
+ LONG2CHARS( 0x0000000000003E00 ),
+ LONG2CHARS( 0x0000000000007E00 ),
+ LONG2CHARS( 0x000000000000FE00 ),
+ LONG2CHARS( 0x000000000001FE00 ),
+ LONG2CHARS( 0x000000000003FE00 ),
+ LONG2CHARS( 0x000000000007FE00 ),
+ LONG2CHARS( 0x00000000000FFE00 ),
+ LONG2CHARS( 0x00000000001FFE00 ),
+ LONG2CHARS( 0x00000000003FFE00 ),
+ LONG2CHARS( 0x00000000007FFE00 ),
+ LONG2CHARS( 0x0000000000FFFE00 ),
+ LONG2CHARS( 0x0000000001FFFE00 ),
+ LONG2CHARS( 0x0000000003FFFE00 ),
+ LONG2CHARS( 0x0000000007FFFE00 ),
+ LONG2CHARS( 0x000000000FFFFE00 ),
+ LONG2CHARS( 0x000000001FFFFE00 ),
+ LONG2CHARS( 0x000000003FFFFE00 ),
+ LONG2CHARS( 0x000000007FFFFE00 ),
+ LONG2CHARS( 0x00000000FFFFFE00 ),
+ LONG2CHARS( 0x00000001FFFFFE00 ),
+ LONG2CHARS( 0x00000003FFFFFE00 ),
+ LONG2CHARS( 0x00000007FFFFFE00 ),
+ LONG2CHARS( 0x0000000FFFFFFE00 ),
+ LONG2CHARS( 0x0000001FFFFFFE00 ),
+ LONG2CHARS( 0x0000003FFFFFFE00 ),
+ LONG2CHARS( 0x0000007FFFFFFE00 ),
+ LONG2CHARS( 0x000000FFFFFFFE00 ),
+ LONG2CHARS( 0x000001FFFFFFFE00 ),
+ LONG2CHARS( 0x000003FFFFFFFE00 ),
+ LONG2CHARS( 0x000007FFFFFFFE00 ),
+ LONG2CHARS( 0x00000FFFFFFFFE00 ),
+ LONG2CHARS( 0x00001FFFFFFFFE00 ),
+ LONG2CHARS( 0x00003FFFFFFFFE00 ),
+ LONG2CHARS( 0x00007FFFFFFFFE00 ),
+ LONG2CHARS( 0x0000FFFFFFFFFE00 ),
+ LONG2CHARS( 0x0001FFFFFFFFFE00 ),
+ LONG2CHARS( 0x0003FFFFFFFFFE00 ),
+ LONG2CHARS( 0x0007FFFFFFFFFE00 ),
+ LONG2CHARS( 0x000FFFFFFFFFFE00 ),
+ LONG2CHARS( 0x001FFFFFFFFFFE00 ),
+ LONG2CHARS( 0x003FFFFFFFFFFE00 ),
+ LONG2CHARS( 0x007FFFFFFFFFFE00 ),
+ LONG2CHARS( 0x00FFFFFFFFFFFE00 ),
+ LONG2CHARS( 0x01FFFFFFFFFFFE00 ),
+ LONG2CHARS( 0x03FFFFFFFFFFFE00 ),
+ LONG2CHARS( 0x07FFFFFFFFFFFE00 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFE00 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFE00 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFE00 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFE00 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFE00 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000400 ),
+ LONG2CHARS( 0x0000000000000C00 ),
+ LONG2CHARS( 0x0000000000001C00 ),
+ LONG2CHARS( 0x0000000000003C00 ),
+ LONG2CHARS( 0x0000000000007C00 ),
+ LONG2CHARS( 0x000000000000FC00 ),
+ LONG2CHARS( 0x000000000001FC00 ),
+ LONG2CHARS( 0x000000000003FC00 ),
+ LONG2CHARS( 0x000000000007FC00 ),
+ LONG2CHARS( 0x00000000000FFC00 ),
+ LONG2CHARS( 0x00000000001FFC00 ),
+ LONG2CHARS( 0x00000000003FFC00 ),
+ LONG2CHARS( 0x00000000007FFC00 ),
+ LONG2CHARS( 0x0000000000FFFC00 ),
+ LONG2CHARS( 0x0000000001FFFC00 ),
+ LONG2CHARS( 0x0000000003FFFC00 ),
+ LONG2CHARS( 0x0000000007FFFC00 ),
+ LONG2CHARS( 0x000000000FFFFC00 ),
+ LONG2CHARS( 0x000000001FFFFC00 ),
+ LONG2CHARS( 0x000000003FFFFC00 ),
+ LONG2CHARS( 0x000000007FFFFC00 ),
+ LONG2CHARS( 0x00000000FFFFFC00 ),
+ LONG2CHARS( 0x00000001FFFFFC00 ),
+ LONG2CHARS( 0x00000003FFFFFC00 ),
+ LONG2CHARS( 0x00000007FFFFFC00 ),
+ LONG2CHARS( 0x0000000FFFFFFC00 ),
+ LONG2CHARS( 0x0000001FFFFFFC00 ),
+ LONG2CHARS( 0x0000003FFFFFFC00 ),
+ LONG2CHARS( 0x0000007FFFFFFC00 ),
+ LONG2CHARS( 0x000000FFFFFFFC00 ),
+ LONG2CHARS( 0x000001FFFFFFFC00 ),
+ LONG2CHARS( 0x000003FFFFFFFC00 ),
+ LONG2CHARS( 0x000007FFFFFFFC00 ),
+ LONG2CHARS( 0x00000FFFFFFFFC00 ),
+ LONG2CHARS( 0x00001FFFFFFFFC00 ),
+ LONG2CHARS( 0x00003FFFFFFFFC00 ),
+ LONG2CHARS( 0x00007FFFFFFFFC00 ),
+ LONG2CHARS( 0x0000FFFFFFFFFC00 ),
+ LONG2CHARS( 0x0001FFFFFFFFFC00 ),
+ LONG2CHARS( 0x0003FFFFFFFFFC00 ),
+ LONG2CHARS( 0x0007FFFFFFFFFC00 ),
+ LONG2CHARS( 0x000FFFFFFFFFFC00 ),
+ LONG2CHARS( 0x001FFFFFFFFFFC00 ),
+ LONG2CHARS( 0x003FFFFFFFFFFC00 ),
+ LONG2CHARS( 0x007FFFFFFFFFFC00 ),
+ LONG2CHARS( 0x00FFFFFFFFFFFC00 ),
+ LONG2CHARS( 0x01FFFFFFFFFFFC00 ),
+ LONG2CHARS( 0x03FFFFFFFFFFFC00 ),
+ LONG2CHARS( 0x07FFFFFFFFFFFC00 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFFC00 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFFC00 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFFC00 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFFC00 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFFC00 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000800 ),
+ LONG2CHARS( 0x0000000000001800 ),
+ LONG2CHARS( 0x0000000000003800 ),
+ LONG2CHARS( 0x0000000000007800 ),
+ LONG2CHARS( 0x000000000000F800 ),
+ LONG2CHARS( 0x000000000001F800 ),
+ LONG2CHARS( 0x000000000003F800 ),
+ LONG2CHARS( 0x000000000007F800 ),
+ LONG2CHARS( 0x00000000000FF800 ),
+ LONG2CHARS( 0x00000000001FF800 ),
+ LONG2CHARS( 0x00000000003FF800 ),
+ LONG2CHARS( 0x00000000007FF800 ),
+ LONG2CHARS( 0x0000000000FFF800 ),
+ LONG2CHARS( 0x0000000001FFF800 ),
+ LONG2CHARS( 0x0000000003FFF800 ),
+ LONG2CHARS( 0x0000000007FFF800 ),
+ LONG2CHARS( 0x000000000FFFF800 ),
+ LONG2CHARS( 0x000000001FFFF800 ),
+ LONG2CHARS( 0x000000003FFFF800 ),
+ LONG2CHARS( 0x000000007FFFF800 ),
+ LONG2CHARS( 0x00000000FFFFF800 ),
+ LONG2CHARS( 0x00000001FFFFF800 ),
+ LONG2CHARS( 0x00000003FFFFF800 ),
+ LONG2CHARS( 0x00000007FFFFF800 ),
+ LONG2CHARS( 0x0000000FFFFFF800 ),
+ LONG2CHARS( 0x0000001FFFFFF800 ),
+ LONG2CHARS( 0x0000003FFFFFF800 ),
+ LONG2CHARS( 0x0000007FFFFFF800 ),
+ LONG2CHARS( 0x000000FFFFFFF800 ),
+ LONG2CHARS( 0x000001FFFFFFF800 ),
+ LONG2CHARS( 0x000003FFFFFFF800 ),
+ LONG2CHARS( 0x000007FFFFFFF800 ),
+ LONG2CHARS( 0x00000FFFFFFFF800 ),
+ LONG2CHARS( 0x00001FFFFFFFF800 ),
+ LONG2CHARS( 0x00003FFFFFFFF800 ),
+ LONG2CHARS( 0x00007FFFFFFFF800 ),
+ LONG2CHARS( 0x0000FFFFFFFFF800 ),
+ LONG2CHARS( 0x0001FFFFFFFFF800 ),
+ LONG2CHARS( 0x0003FFFFFFFFF800 ),
+ LONG2CHARS( 0x0007FFFFFFFFF800 ),
+ LONG2CHARS( 0x000FFFFFFFFFF800 ),
+ LONG2CHARS( 0x001FFFFFFFFFF800 ),
+ LONG2CHARS( 0x003FFFFFFFFFF800 ),
+ LONG2CHARS( 0x007FFFFFFFFFF800 ),
+ LONG2CHARS( 0x00FFFFFFFFFFF800 ),
+ LONG2CHARS( 0x01FFFFFFFFFFF800 ),
+ LONG2CHARS( 0x03FFFFFFFFFFF800 ),
+ LONG2CHARS( 0x07FFFFFFFFFFF800 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFF800 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFF800 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFF800 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFF800 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFF800 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000001000 ),
+ LONG2CHARS( 0x0000000000003000 ),
+ LONG2CHARS( 0x0000000000007000 ),
+ LONG2CHARS( 0x000000000000F000 ),
+ LONG2CHARS( 0x000000000001F000 ),
+ LONG2CHARS( 0x000000000003F000 ),
+ LONG2CHARS( 0x000000000007F000 ),
+ LONG2CHARS( 0x00000000000FF000 ),
+ LONG2CHARS( 0x00000000001FF000 ),
+ LONG2CHARS( 0x00000000003FF000 ),
+ LONG2CHARS( 0x00000000007FF000 ),
+ LONG2CHARS( 0x0000000000FFF000 ),
+ LONG2CHARS( 0x0000000001FFF000 ),
+ LONG2CHARS( 0x0000000003FFF000 ),
+ LONG2CHARS( 0x0000000007FFF000 ),
+ LONG2CHARS( 0x000000000FFFF000 ),
+ LONG2CHARS( 0x000000001FFFF000 ),
+ LONG2CHARS( 0x000000003FFFF000 ),
+ LONG2CHARS( 0x000000007FFFF000 ),
+ LONG2CHARS( 0x00000000FFFFF000 ),
+ LONG2CHARS( 0x00000001FFFFF000 ),
+ LONG2CHARS( 0x00000003FFFFF000 ),
+ LONG2CHARS( 0x00000007FFFFF000 ),
+ LONG2CHARS( 0x0000000FFFFFF000 ),
+ LONG2CHARS( 0x0000001FFFFFF000 ),
+ LONG2CHARS( 0x0000003FFFFFF000 ),
+ LONG2CHARS( 0x0000007FFFFFF000 ),
+ LONG2CHARS( 0x000000FFFFFFF000 ),
+ LONG2CHARS( 0x000001FFFFFFF000 ),
+ LONG2CHARS( 0x000003FFFFFFF000 ),
+ LONG2CHARS( 0x000007FFFFFFF000 ),
+ LONG2CHARS( 0x00000FFFFFFFF000 ),
+ LONG2CHARS( 0x00001FFFFFFFF000 ),
+ LONG2CHARS( 0x00003FFFFFFFF000 ),
+ LONG2CHARS( 0x00007FFFFFFFF000 ),
+ LONG2CHARS( 0x0000FFFFFFFFF000 ),
+ LONG2CHARS( 0x0001FFFFFFFFF000 ),
+ LONG2CHARS( 0x0003FFFFFFFFF000 ),
+ LONG2CHARS( 0x0007FFFFFFFFF000 ),
+ LONG2CHARS( 0x000FFFFFFFFFF000 ),
+ LONG2CHARS( 0x001FFFFFFFFFF000 ),
+ LONG2CHARS( 0x003FFFFFFFFFF000 ),
+ LONG2CHARS( 0x007FFFFFFFFFF000 ),
+ LONG2CHARS( 0x00FFFFFFFFFFF000 ),
+ LONG2CHARS( 0x01FFFFFFFFFFF000 ),
+ LONG2CHARS( 0x03FFFFFFFFFFF000 ),
+ LONG2CHARS( 0x07FFFFFFFFFFF000 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFF000 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFF000 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFF000 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFF000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFF000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000002000 ),
+ LONG2CHARS( 0x0000000000006000 ),
+ LONG2CHARS( 0x000000000000E000 ),
+ LONG2CHARS( 0x000000000001E000 ),
+ LONG2CHARS( 0x000000000003E000 ),
+ LONG2CHARS( 0x000000000007E000 ),
+ LONG2CHARS( 0x00000000000FE000 ),
+ LONG2CHARS( 0x00000000001FE000 ),
+ LONG2CHARS( 0x00000000003FE000 ),
+ LONG2CHARS( 0x00000000007FE000 ),
+ LONG2CHARS( 0x0000000000FFE000 ),
+ LONG2CHARS( 0x0000000001FFE000 ),
+ LONG2CHARS( 0x0000000003FFE000 ),
+ LONG2CHARS( 0x0000000007FFE000 ),
+ LONG2CHARS( 0x000000000FFFE000 ),
+ LONG2CHARS( 0x000000001FFFE000 ),
+ LONG2CHARS( 0x000000003FFFE000 ),
+ LONG2CHARS( 0x000000007FFFE000 ),
+ LONG2CHARS( 0x00000000FFFFE000 ),
+ LONG2CHARS( 0x00000001FFFFE000 ),
+ LONG2CHARS( 0x00000003FFFFE000 ),
+ LONG2CHARS( 0x00000007FFFFE000 ),
+ LONG2CHARS( 0x0000000FFFFFE000 ),
+ LONG2CHARS( 0x0000001FFFFFE000 ),
+ LONG2CHARS( 0x0000003FFFFFE000 ),
+ LONG2CHARS( 0x0000007FFFFFE000 ),
+ LONG2CHARS( 0x000000FFFFFFE000 ),
+ LONG2CHARS( 0x000001FFFFFFE000 ),
+ LONG2CHARS( 0x000003FFFFFFE000 ),
+ LONG2CHARS( 0x000007FFFFFFE000 ),
+ LONG2CHARS( 0x00000FFFFFFFE000 ),
+ LONG2CHARS( 0x00001FFFFFFFE000 ),
+ LONG2CHARS( 0x00003FFFFFFFE000 ),
+ LONG2CHARS( 0x00007FFFFFFFE000 ),
+ LONG2CHARS( 0x0000FFFFFFFFE000 ),
+ LONG2CHARS( 0x0001FFFFFFFFE000 ),
+ LONG2CHARS( 0x0003FFFFFFFFE000 ),
+ LONG2CHARS( 0x0007FFFFFFFFE000 ),
+ LONG2CHARS( 0x000FFFFFFFFFE000 ),
+ LONG2CHARS( 0x001FFFFFFFFFE000 ),
+ LONG2CHARS( 0x003FFFFFFFFFE000 ),
+ LONG2CHARS( 0x007FFFFFFFFFE000 ),
+ LONG2CHARS( 0x00FFFFFFFFFFE000 ),
+ LONG2CHARS( 0x01FFFFFFFFFFE000 ),
+ LONG2CHARS( 0x03FFFFFFFFFFE000 ),
+ LONG2CHARS( 0x07FFFFFFFFFFE000 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFE000 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFE000 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFE000 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFE000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFE000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000004000 ),
+ LONG2CHARS( 0x000000000000C000 ),
+ LONG2CHARS( 0x000000000001C000 ),
+ LONG2CHARS( 0x000000000003C000 ),
+ LONG2CHARS( 0x000000000007C000 ),
+ LONG2CHARS( 0x00000000000FC000 ),
+ LONG2CHARS( 0x00000000001FC000 ),
+ LONG2CHARS( 0x00000000003FC000 ),
+ LONG2CHARS( 0x00000000007FC000 ),
+ LONG2CHARS( 0x0000000000FFC000 ),
+ LONG2CHARS( 0x0000000001FFC000 ),
+ LONG2CHARS( 0x0000000003FFC000 ),
+ LONG2CHARS( 0x0000000007FFC000 ),
+ LONG2CHARS( 0x000000000FFFC000 ),
+ LONG2CHARS( 0x000000001FFFC000 ),
+ LONG2CHARS( 0x000000003FFFC000 ),
+ LONG2CHARS( 0x000000007FFFC000 ),
+ LONG2CHARS( 0x00000000FFFFC000 ),
+ LONG2CHARS( 0x00000001FFFFC000 ),
+ LONG2CHARS( 0x00000003FFFFC000 ),
+ LONG2CHARS( 0x00000007FFFFC000 ),
+ LONG2CHARS( 0x0000000FFFFFC000 ),
+ LONG2CHARS( 0x0000001FFFFFC000 ),
+ LONG2CHARS( 0x0000003FFFFFC000 ),
+ LONG2CHARS( 0x0000007FFFFFC000 ),
+ LONG2CHARS( 0x000000FFFFFFC000 ),
+ LONG2CHARS( 0x000001FFFFFFC000 ),
+ LONG2CHARS( 0x000003FFFFFFC000 ),
+ LONG2CHARS( 0x000007FFFFFFC000 ),
+ LONG2CHARS( 0x00000FFFFFFFC000 ),
+ LONG2CHARS( 0x00001FFFFFFFC000 ),
+ LONG2CHARS( 0x00003FFFFFFFC000 ),
+ LONG2CHARS( 0x00007FFFFFFFC000 ),
+ LONG2CHARS( 0x0000FFFFFFFFC000 ),
+ LONG2CHARS( 0x0001FFFFFFFFC000 ),
+ LONG2CHARS( 0x0003FFFFFFFFC000 ),
+ LONG2CHARS( 0x0007FFFFFFFFC000 ),
+ LONG2CHARS( 0x000FFFFFFFFFC000 ),
+ LONG2CHARS( 0x001FFFFFFFFFC000 ),
+ LONG2CHARS( 0x003FFFFFFFFFC000 ),
+ LONG2CHARS( 0x007FFFFFFFFFC000 ),
+ LONG2CHARS( 0x00FFFFFFFFFFC000 ),
+ LONG2CHARS( 0x01FFFFFFFFFFC000 ),
+ LONG2CHARS( 0x03FFFFFFFFFFC000 ),
+ LONG2CHARS( 0x07FFFFFFFFFFC000 ),
+ LONG2CHARS( 0x0FFFFFFFFFFFC000 ),
+ LONG2CHARS( 0x1FFFFFFFFFFFC000 ),
+ LONG2CHARS( 0x3FFFFFFFFFFFC000 ),
+ LONG2CHARS( 0x7FFFFFFFFFFFC000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFFC000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000008000 ),
+ LONG2CHARS( 0x0000000000018000 ),
+ LONG2CHARS( 0x0000000000038000 ),
+ LONG2CHARS( 0x0000000000078000 ),
+ LONG2CHARS( 0x00000000000F8000 ),
+ LONG2CHARS( 0x00000000001F8000 ),
+ LONG2CHARS( 0x00000000003F8000 ),
+ LONG2CHARS( 0x00000000007F8000 ),
+ LONG2CHARS( 0x0000000000FF8000 ),
+ LONG2CHARS( 0x0000000001FF8000 ),
+ LONG2CHARS( 0x0000000003FF8000 ),
+ LONG2CHARS( 0x0000000007FF8000 ),
+ LONG2CHARS( 0x000000000FFF8000 ),
+ LONG2CHARS( 0x000000001FFF8000 ),
+ LONG2CHARS( 0x000000003FFF8000 ),
+ LONG2CHARS( 0x000000007FFF8000 ),
+ LONG2CHARS( 0x00000000FFFF8000 ),
+ LONG2CHARS( 0x00000001FFFF8000 ),
+ LONG2CHARS( 0x00000003FFFF8000 ),
+ LONG2CHARS( 0x00000007FFFF8000 ),
+ LONG2CHARS( 0x0000000FFFFF8000 ),
+ LONG2CHARS( 0x0000001FFFFF8000 ),
+ LONG2CHARS( 0x0000003FFFFF8000 ),
+ LONG2CHARS( 0x0000007FFFFF8000 ),
+ LONG2CHARS( 0x000000FFFFFF8000 ),
+ LONG2CHARS( 0x000001FFFFFF8000 ),
+ LONG2CHARS( 0x000003FFFFFF8000 ),
+ LONG2CHARS( 0x000007FFFFFF8000 ),
+ LONG2CHARS( 0x00000FFFFFFF8000 ),
+ LONG2CHARS( 0x00001FFFFFFF8000 ),
+ LONG2CHARS( 0x00003FFFFFFF8000 ),
+ LONG2CHARS( 0x00007FFFFFFF8000 ),
+ LONG2CHARS( 0x0000FFFFFFFF8000 ),
+ LONG2CHARS( 0x0001FFFFFFFF8000 ),
+ LONG2CHARS( 0x0003FFFFFFFF8000 ),
+ LONG2CHARS( 0x0007FFFFFFFF8000 ),
+ LONG2CHARS( 0x000FFFFFFFFF8000 ),
+ LONG2CHARS( 0x001FFFFFFFFF8000 ),
+ LONG2CHARS( 0x003FFFFFFFFF8000 ),
+ LONG2CHARS( 0x007FFFFFFFFF8000 ),
+ LONG2CHARS( 0x00FFFFFFFFFF8000 ),
+ LONG2CHARS( 0x01FFFFFFFFFF8000 ),
+ LONG2CHARS( 0x03FFFFFFFFFF8000 ),
+ LONG2CHARS( 0x07FFFFFFFFFF8000 ),
+ LONG2CHARS( 0x0FFFFFFFFFFF8000 ),
+ LONG2CHARS( 0x1FFFFFFFFFFF8000 ),
+ LONG2CHARS( 0x3FFFFFFFFFFF8000 ),
+ LONG2CHARS( 0x7FFFFFFFFFFF8000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFF8000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000010000 ),
+ LONG2CHARS( 0x0000000000030000 ),
+ LONG2CHARS( 0x0000000000070000 ),
+ LONG2CHARS( 0x00000000000F0000 ),
+ LONG2CHARS( 0x00000000001F0000 ),
+ LONG2CHARS( 0x00000000003F0000 ),
+ LONG2CHARS( 0x00000000007F0000 ),
+ LONG2CHARS( 0x0000000000FF0000 ),
+ LONG2CHARS( 0x0000000001FF0000 ),
+ LONG2CHARS( 0x0000000003FF0000 ),
+ LONG2CHARS( 0x0000000007FF0000 ),
+ LONG2CHARS( 0x000000000FFF0000 ),
+ LONG2CHARS( 0x000000001FFF0000 ),
+ LONG2CHARS( 0x000000003FFF0000 ),
+ LONG2CHARS( 0x000000007FFF0000 ),
+ LONG2CHARS( 0x00000000FFFF0000 ),
+ LONG2CHARS( 0x00000001FFFF0000 ),
+ LONG2CHARS( 0x00000003FFFF0000 ),
+ LONG2CHARS( 0x00000007FFFF0000 ),
+ LONG2CHARS( 0x0000000FFFFF0000 ),
+ LONG2CHARS( 0x0000001FFFFF0000 ),
+ LONG2CHARS( 0x0000003FFFFF0000 ),
+ LONG2CHARS( 0x0000007FFFFF0000 ),
+ LONG2CHARS( 0x000000FFFFFF0000 ),
+ LONG2CHARS( 0x000001FFFFFF0000 ),
+ LONG2CHARS( 0x000003FFFFFF0000 ),
+ LONG2CHARS( 0x000007FFFFFF0000 ),
+ LONG2CHARS( 0x00000FFFFFFF0000 ),
+ LONG2CHARS( 0x00001FFFFFFF0000 ),
+ LONG2CHARS( 0x00003FFFFFFF0000 ),
+ LONG2CHARS( 0x00007FFFFFFF0000 ),
+ LONG2CHARS( 0x0000FFFFFFFF0000 ),
+ LONG2CHARS( 0x0001FFFFFFFF0000 ),
+ LONG2CHARS( 0x0003FFFFFFFF0000 ),
+ LONG2CHARS( 0x0007FFFFFFFF0000 ),
+ LONG2CHARS( 0x000FFFFFFFFF0000 ),
+ LONG2CHARS( 0x001FFFFFFFFF0000 ),
+ LONG2CHARS( 0x003FFFFFFFFF0000 ),
+ LONG2CHARS( 0x007FFFFFFFFF0000 ),
+ LONG2CHARS( 0x00FFFFFFFFFF0000 ),
+ LONG2CHARS( 0x01FFFFFFFFFF0000 ),
+ LONG2CHARS( 0x03FFFFFFFFFF0000 ),
+ LONG2CHARS( 0x07FFFFFFFFFF0000 ),
+ LONG2CHARS( 0x0FFFFFFFFFFF0000 ),
+ LONG2CHARS( 0x1FFFFFFFFFFF0000 ),
+ LONG2CHARS( 0x3FFFFFFFFFFF0000 ),
+ LONG2CHARS( 0x7FFFFFFFFFFF0000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFF0000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000020000 ),
+ LONG2CHARS( 0x0000000000060000 ),
+ LONG2CHARS( 0x00000000000E0000 ),
+ LONG2CHARS( 0x00000000001E0000 ),
+ LONG2CHARS( 0x00000000003E0000 ),
+ LONG2CHARS( 0x00000000007E0000 ),
+ LONG2CHARS( 0x0000000000FE0000 ),
+ LONG2CHARS( 0x0000000001FE0000 ),
+ LONG2CHARS( 0x0000000003FE0000 ),
+ LONG2CHARS( 0x0000000007FE0000 ),
+ LONG2CHARS( 0x000000000FFE0000 ),
+ LONG2CHARS( 0x000000001FFE0000 ),
+ LONG2CHARS( 0x000000003FFE0000 ),
+ LONG2CHARS( 0x000000007FFE0000 ),
+ LONG2CHARS( 0x00000000FFFE0000 ),
+ LONG2CHARS( 0x00000001FFFE0000 ),
+ LONG2CHARS( 0x00000003FFFE0000 ),
+ LONG2CHARS( 0x00000007FFFE0000 ),
+ LONG2CHARS( 0x0000000FFFFE0000 ),
+ LONG2CHARS( 0x0000001FFFFE0000 ),
+ LONG2CHARS( 0x0000003FFFFE0000 ),
+ LONG2CHARS( 0x0000007FFFFE0000 ),
+ LONG2CHARS( 0x000000FFFFFE0000 ),
+ LONG2CHARS( 0x000001FFFFFE0000 ),
+ LONG2CHARS( 0x000003FFFFFE0000 ),
+ LONG2CHARS( 0x000007FFFFFE0000 ),
+ LONG2CHARS( 0x00000FFFFFFE0000 ),
+ LONG2CHARS( 0x00001FFFFFFE0000 ),
+ LONG2CHARS( 0x00003FFFFFFE0000 ),
+ LONG2CHARS( 0x00007FFFFFFE0000 ),
+ LONG2CHARS( 0x0000FFFFFFFE0000 ),
+ LONG2CHARS( 0x0001FFFFFFFE0000 ),
+ LONG2CHARS( 0x0003FFFFFFFE0000 ),
+ LONG2CHARS( 0x0007FFFFFFFE0000 ),
+ LONG2CHARS( 0x000FFFFFFFFE0000 ),
+ LONG2CHARS( 0x001FFFFFFFFE0000 ),
+ LONG2CHARS( 0x003FFFFFFFFE0000 ),
+ LONG2CHARS( 0x007FFFFFFFFE0000 ),
+ LONG2CHARS( 0x00FFFFFFFFFE0000 ),
+ LONG2CHARS( 0x01FFFFFFFFFE0000 ),
+ LONG2CHARS( 0x03FFFFFFFFFE0000 ),
+ LONG2CHARS( 0x07FFFFFFFFFE0000 ),
+ LONG2CHARS( 0x0FFFFFFFFFFE0000 ),
+ LONG2CHARS( 0x1FFFFFFFFFFE0000 ),
+ LONG2CHARS( 0x3FFFFFFFFFFE0000 ),
+ LONG2CHARS( 0x7FFFFFFFFFFE0000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFE0000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000040000 ),
+ LONG2CHARS( 0x00000000000C0000 ),
+ LONG2CHARS( 0x00000000001C0000 ),
+ LONG2CHARS( 0x00000000003C0000 ),
+ LONG2CHARS( 0x00000000007C0000 ),
+ LONG2CHARS( 0x0000000000FC0000 ),
+ LONG2CHARS( 0x0000000001FC0000 ),
+ LONG2CHARS( 0x0000000003FC0000 ),
+ LONG2CHARS( 0x0000000007FC0000 ),
+ LONG2CHARS( 0x000000000FFC0000 ),
+ LONG2CHARS( 0x000000001FFC0000 ),
+ LONG2CHARS( 0x000000003FFC0000 ),
+ LONG2CHARS( 0x000000007FFC0000 ),
+ LONG2CHARS( 0x00000000FFFC0000 ),
+ LONG2CHARS( 0x00000001FFFC0000 ),
+ LONG2CHARS( 0x00000003FFFC0000 ),
+ LONG2CHARS( 0x00000007FFFC0000 ),
+ LONG2CHARS( 0x0000000FFFFC0000 ),
+ LONG2CHARS( 0x0000001FFFFC0000 ),
+ LONG2CHARS( 0x0000003FFFFC0000 ),
+ LONG2CHARS( 0x0000007FFFFC0000 ),
+ LONG2CHARS( 0x000000FFFFFC0000 ),
+ LONG2CHARS( 0x000001FFFFFC0000 ),
+ LONG2CHARS( 0x000003FFFFFC0000 ),
+ LONG2CHARS( 0x000007FFFFFC0000 ),
+ LONG2CHARS( 0x00000FFFFFFC0000 ),
+ LONG2CHARS( 0x00001FFFFFFC0000 ),
+ LONG2CHARS( 0x00003FFFFFFC0000 ),
+ LONG2CHARS( 0x00007FFFFFFC0000 ),
+ LONG2CHARS( 0x0000FFFFFFFC0000 ),
+ LONG2CHARS( 0x0001FFFFFFFC0000 ),
+ LONG2CHARS( 0x0003FFFFFFFC0000 ),
+ LONG2CHARS( 0x0007FFFFFFFC0000 ),
+ LONG2CHARS( 0x000FFFFFFFFC0000 ),
+ LONG2CHARS( 0x001FFFFFFFFC0000 ),
+ LONG2CHARS( 0x003FFFFFFFFC0000 ),
+ LONG2CHARS( 0x007FFFFFFFFC0000 ),
+ LONG2CHARS( 0x00FFFFFFFFFC0000 ),
+ LONG2CHARS( 0x01FFFFFFFFFC0000 ),
+ LONG2CHARS( 0x03FFFFFFFFFC0000 ),
+ LONG2CHARS( 0x07FFFFFFFFFC0000 ),
+ LONG2CHARS( 0x0FFFFFFFFFFC0000 ),
+ LONG2CHARS( 0x1FFFFFFFFFFC0000 ),
+ LONG2CHARS( 0x3FFFFFFFFFFC0000 ),
+ LONG2CHARS( 0x7FFFFFFFFFFC0000 ),
+ LONG2CHARS( 0xFFFFFFFFFFFC0000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000080000 ),
+ LONG2CHARS( 0x0000000000180000 ),
+ LONG2CHARS( 0x0000000000380000 ),
+ LONG2CHARS( 0x0000000000780000 ),
+ LONG2CHARS( 0x0000000000F80000 ),
+ LONG2CHARS( 0x0000000001F80000 ),
+ LONG2CHARS( 0x0000000003F80000 ),
+ LONG2CHARS( 0x0000000007F80000 ),
+ LONG2CHARS( 0x000000000FF80000 ),
+ LONG2CHARS( 0x000000001FF80000 ),
+ LONG2CHARS( 0x000000003FF80000 ),
+ LONG2CHARS( 0x000000007FF80000 ),
+ LONG2CHARS( 0x00000000FFF80000 ),
+ LONG2CHARS( 0x00000001FFF80000 ),
+ LONG2CHARS( 0x00000003FFF80000 ),
+ LONG2CHARS( 0x00000007FFF80000 ),
+ LONG2CHARS( 0x0000000FFFF80000 ),
+ LONG2CHARS( 0x0000001FFFF80000 ),
+ LONG2CHARS( 0x0000003FFFF80000 ),
+ LONG2CHARS( 0x0000007FFFF80000 ),
+ LONG2CHARS( 0x000000FFFFF80000 ),
+ LONG2CHARS( 0x000001FFFFF80000 ),
+ LONG2CHARS( 0x000003FFFFF80000 ),
+ LONG2CHARS( 0x000007FFFFF80000 ),
+ LONG2CHARS( 0x00000FFFFFF80000 ),
+ LONG2CHARS( 0x00001FFFFFF80000 ),
+ LONG2CHARS( 0x00003FFFFFF80000 ),
+ LONG2CHARS( 0x00007FFFFFF80000 ),
+ LONG2CHARS( 0x0000FFFFFFF80000 ),
+ LONG2CHARS( 0x0001FFFFFFF80000 ),
+ LONG2CHARS( 0x0003FFFFFFF80000 ),
+ LONG2CHARS( 0x0007FFFFFFF80000 ),
+ LONG2CHARS( 0x000FFFFFFFF80000 ),
+ LONG2CHARS( 0x001FFFFFFFF80000 ),
+ LONG2CHARS( 0x003FFFFFFFF80000 ),
+ LONG2CHARS( 0x007FFFFFFFF80000 ),
+ LONG2CHARS( 0x00FFFFFFFFF80000 ),
+ LONG2CHARS( 0x01FFFFFFFFF80000 ),
+ LONG2CHARS( 0x03FFFFFFFFF80000 ),
+ LONG2CHARS( 0x07FFFFFFFFF80000 ),
+ LONG2CHARS( 0x0FFFFFFFFFF80000 ),
+ LONG2CHARS( 0x1FFFFFFFFFF80000 ),
+ LONG2CHARS( 0x3FFFFFFFFFF80000 ),
+ LONG2CHARS( 0x7FFFFFFFFFF80000 ),
+ LONG2CHARS( 0xFFFFFFFFFFF80000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000100000 ),
+ LONG2CHARS( 0x0000000000300000 ),
+ LONG2CHARS( 0x0000000000700000 ),
+ LONG2CHARS( 0x0000000000F00000 ),
+ LONG2CHARS( 0x0000000001F00000 ),
+ LONG2CHARS( 0x0000000003F00000 ),
+ LONG2CHARS( 0x0000000007F00000 ),
+ LONG2CHARS( 0x000000000FF00000 ),
+ LONG2CHARS( 0x000000001FF00000 ),
+ LONG2CHARS( 0x000000003FF00000 ),
+ LONG2CHARS( 0x000000007FF00000 ),
+ LONG2CHARS( 0x00000000FFF00000 ),
+ LONG2CHARS( 0x00000001FFF00000 ),
+ LONG2CHARS( 0x00000003FFF00000 ),
+ LONG2CHARS( 0x00000007FFF00000 ),
+ LONG2CHARS( 0x0000000FFFF00000 ),
+ LONG2CHARS( 0x0000001FFFF00000 ),
+ LONG2CHARS( 0x0000003FFFF00000 ),
+ LONG2CHARS( 0x0000007FFFF00000 ),
+ LONG2CHARS( 0x000000FFFFF00000 ),
+ LONG2CHARS( 0x000001FFFFF00000 ),
+ LONG2CHARS( 0x000003FFFFF00000 ),
+ LONG2CHARS( 0x000007FFFFF00000 ),
+ LONG2CHARS( 0x00000FFFFFF00000 ),
+ LONG2CHARS( 0x00001FFFFFF00000 ),
+ LONG2CHARS( 0x00003FFFFFF00000 ),
+ LONG2CHARS( 0x00007FFFFFF00000 ),
+ LONG2CHARS( 0x0000FFFFFFF00000 ),
+ LONG2CHARS( 0x0001FFFFFFF00000 ),
+ LONG2CHARS( 0x0003FFFFFFF00000 ),
+ LONG2CHARS( 0x0007FFFFFFF00000 ),
+ LONG2CHARS( 0x000FFFFFFFF00000 ),
+ LONG2CHARS( 0x001FFFFFFFF00000 ),
+ LONG2CHARS( 0x003FFFFFFFF00000 ),
+ LONG2CHARS( 0x007FFFFFFFF00000 ),
+ LONG2CHARS( 0x00FFFFFFFFF00000 ),
+ LONG2CHARS( 0x01FFFFFFFFF00000 ),
+ LONG2CHARS( 0x03FFFFFFFFF00000 ),
+ LONG2CHARS( 0x07FFFFFFFFF00000 ),
+ LONG2CHARS( 0x0FFFFFFFFFF00000 ),
+ LONG2CHARS( 0x1FFFFFFFFFF00000 ),
+ LONG2CHARS( 0x3FFFFFFFFFF00000 ),
+ LONG2CHARS( 0x7FFFFFFFFFF00000 ),
+ LONG2CHARS( 0xFFFFFFFFFFF00000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000200000 ),
+ LONG2CHARS( 0x0000000000600000 ),
+ LONG2CHARS( 0x0000000000E00000 ),
+ LONG2CHARS( 0x0000000001E00000 ),
+ LONG2CHARS( 0x0000000003E00000 ),
+ LONG2CHARS( 0x0000000007E00000 ),
+ LONG2CHARS( 0x000000000FE00000 ),
+ LONG2CHARS( 0x000000001FE00000 ),
+ LONG2CHARS( 0x000000003FE00000 ),
+ LONG2CHARS( 0x000000007FE00000 ),
+ LONG2CHARS( 0x00000000FFE00000 ),
+ LONG2CHARS( 0x00000001FFE00000 ),
+ LONG2CHARS( 0x00000003FFE00000 ),
+ LONG2CHARS( 0x00000007FFE00000 ),
+ LONG2CHARS( 0x0000000FFFE00000 ),
+ LONG2CHARS( 0x0000001FFFE00000 ),
+ LONG2CHARS( 0x0000003FFFE00000 ),
+ LONG2CHARS( 0x0000007FFFE00000 ),
+ LONG2CHARS( 0x000000FFFFE00000 ),
+ LONG2CHARS( 0x000001FFFFE00000 ),
+ LONG2CHARS( 0x000003FFFFE00000 ),
+ LONG2CHARS( 0x000007FFFFE00000 ),
+ LONG2CHARS( 0x00000FFFFFE00000 ),
+ LONG2CHARS( 0x00001FFFFFE00000 ),
+ LONG2CHARS( 0x00003FFFFFE00000 ),
+ LONG2CHARS( 0x00007FFFFFE00000 ),
+ LONG2CHARS( 0x0000FFFFFFE00000 ),
+ LONG2CHARS( 0x0001FFFFFFE00000 ),
+ LONG2CHARS( 0x0003FFFFFFE00000 ),
+ LONG2CHARS( 0x0007FFFFFFE00000 ),
+ LONG2CHARS( 0x000FFFFFFFE00000 ),
+ LONG2CHARS( 0x001FFFFFFFE00000 ),
+ LONG2CHARS( 0x003FFFFFFFE00000 ),
+ LONG2CHARS( 0x007FFFFFFFE00000 ),
+ LONG2CHARS( 0x00FFFFFFFFE00000 ),
+ LONG2CHARS( 0x01FFFFFFFFE00000 ),
+ LONG2CHARS( 0x03FFFFFFFFE00000 ),
+ LONG2CHARS( 0x07FFFFFFFFE00000 ),
+ LONG2CHARS( 0x0FFFFFFFFFE00000 ),
+ LONG2CHARS( 0x1FFFFFFFFFE00000 ),
+ LONG2CHARS( 0x3FFFFFFFFFE00000 ),
+ LONG2CHARS( 0x7FFFFFFFFFE00000 ),
+ LONG2CHARS( 0xFFFFFFFFFFE00000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000400000 ),
+ LONG2CHARS( 0x0000000000C00000 ),
+ LONG2CHARS( 0x0000000001C00000 ),
+ LONG2CHARS( 0x0000000003C00000 ),
+ LONG2CHARS( 0x0000000007C00000 ),
+ LONG2CHARS( 0x000000000FC00000 ),
+ LONG2CHARS( 0x000000001FC00000 ),
+ LONG2CHARS( 0x000000003FC00000 ),
+ LONG2CHARS( 0x000000007FC00000 ),
+ LONG2CHARS( 0x00000000FFC00000 ),
+ LONG2CHARS( 0x00000001FFC00000 ),
+ LONG2CHARS( 0x00000003FFC00000 ),
+ LONG2CHARS( 0x00000007FFC00000 ),
+ LONG2CHARS( 0x0000000FFFC00000 ),
+ LONG2CHARS( 0x0000001FFFC00000 ),
+ LONG2CHARS( 0x0000003FFFC00000 ),
+ LONG2CHARS( 0x0000007FFFC00000 ),
+ LONG2CHARS( 0x000000FFFFC00000 ),
+ LONG2CHARS( 0x000001FFFFC00000 ),
+ LONG2CHARS( 0x000003FFFFC00000 ),
+ LONG2CHARS( 0x000007FFFFC00000 ),
+ LONG2CHARS( 0x00000FFFFFC00000 ),
+ LONG2CHARS( 0x00001FFFFFC00000 ),
+ LONG2CHARS( 0x00003FFFFFC00000 ),
+ LONG2CHARS( 0x00007FFFFFC00000 ),
+ LONG2CHARS( 0x0000FFFFFFC00000 ),
+ LONG2CHARS( 0x0001FFFFFFC00000 ),
+ LONG2CHARS( 0x0003FFFFFFC00000 ),
+ LONG2CHARS( 0x0007FFFFFFC00000 ),
+ LONG2CHARS( 0x000FFFFFFFC00000 ),
+ LONG2CHARS( 0x001FFFFFFFC00000 ),
+ LONG2CHARS( 0x003FFFFFFFC00000 ),
+ LONG2CHARS( 0x007FFFFFFFC00000 ),
+ LONG2CHARS( 0x00FFFFFFFFC00000 ),
+ LONG2CHARS( 0x01FFFFFFFFC00000 ),
+ LONG2CHARS( 0x03FFFFFFFFC00000 ),
+ LONG2CHARS( 0x07FFFFFFFFC00000 ),
+ LONG2CHARS( 0x0FFFFFFFFFC00000 ),
+ LONG2CHARS( 0x1FFFFFFFFFC00000 ),
+ LONG2CHARS( 0x3FFFFFFFFFC00000 ),
+ LONG2CHARS( 0x7FFFFFFFFFC00000 ),
+ LONG2CHARS( 0xFFFFFFFFFFC00000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000800000 ),
+ LONG2CHARS( 0x0000000001800000 ),
+ LONG2CHARS( 0x0000000003800000 ),
+ LONG2CHARS( 0x0000000007800000 ),
+ LONG2CHARS( 0x000000000F800000 ),
+ LONG2CHARS( 0x000000001F800000 ),
+ LONG2CHARS( 0x000000003F800000 ),
+ LONG2CHARS( 0x000000007F800000 ),
+ LONG2CHARS( 0x00000000FF800000 ),
+ LONG2CHARS( 0x00000001FF800000 ),
+ LONG2CHARS( 0x00000003FF800000 ),
+ LONG2CHARS( 0x00000007FF800000 ),
+ LONG2CHARS( 0x0000000FFF800000 ),
+ LONG2CHARS( 0x0000001FFF800000 ),
+ LONG2CHARS( 0x0000003FFF800000 ),
+ LONG2CHARS( 0x0000007FFF800000 ),
+ LONG2CHARS( 0x000000FFFF800000 ),
+ LONG2CHARS( 0x000001FFFF800000 ),
+ LONG2CHARS( 0x000003FFFF800000 ),
+ LONG2CHARS( 0x000007FFFF800000 ),
+ LONG2CHARS( 0x00000FFFFF800000 ),
+ LONG2CHARS( 0x00001FFFFF800000 ),
+ LONG2CHARS( 0x00003FFFFF800000 ),
+ LONG2CHARS( 0x00007FFFFF800000 ),
+ LONG2CHARS( 0x0000FFFFFF800000 ),
+ LONG2CHARS( 0x0001FFFFFF800000 ),
+ LONG2CHARS( 0x0003FFFFFF800000 ),
+ LONG2CHARS( 0x0007FFFFFF800000 ),
+ LONG2CHARS( 0x000FFFFFFF800000 ),
+ LONG2CHARS( 0x001FFFFFFF800000 ),
+ LONG2CHARS( 0x003FFFFFFF800000 ),
+ LONG2CHARS( 0x007FFFFFFF800000 ),
+ LONG2CHARS( 0x00FFFFFFFF800000 ),
+ LONG2CHARS( 0x01FFFFFFFF800000 ),
+ LONG2CHARS( 0x03FFFFFFFF800000 ),
+ LONG2CHARS( 0x07FFFFFFFF800000 ),
+ LONG2CHARS( 0x0FFFFFFFFF800000 ),
+ LONG2CHARS( 0x1FFFFFFFFF800000 ),
+ LONG2CHARS( 0x3FFFFFFFFF800000 ),
+ LONG2CHARS( 0x7FFFFFFFFF800000 ),
+ LONG2CHARS( 0xFFFFFFFFFF800000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000001000000 ),
+ LONG2CHARS( 0x0000000003000000 ),
+ LONG2CHARS( 0x0000000007000000 ),
+ LONG2CHARS( 0x000000000F000000 ),
+ LONG2CHARS( 0x000000001F000000 ),
+ LONG2CHARS( 0x000000003F000000 ),
+ LONG2CHARS( 0x000000007F000000 ),
+ LONG2CHARS( 0x00000000FF000000 ),
+ LONG2CHARS( 0x00000001FF000000 ),
+ LONG2CHARS( 0x00000003FF000000 ),
+ LONG2CHARS( 0x00000007FF000000 ),
+ LONG2CHARS( 0x0000000FFF000000 ),
+ LONG2CHARS( 0x0000001FFF000000 ),
+ LONG2CHARS( 0x0000003FFF000000 ),
+ LONG2CHARS( 0x0000007FFF000000 ),
+ LONG2CHARS( 0x000000FFFF000000 ),
+ LONG2CHARS( 0x000001FFFF000000 ),
+ LONG2CHARS( 0x000003FFFF000000 ),
+ LONG2CHARS( 0x000007FFFF000000 ),
+ LONG2CHARS( 0x00000FFFFF000000 ),
+ LONG2CHARS( 0x00001FFFFF000000 ),
+ LONG2CHARS( 0x00003FFFFF000000 ),
+ LONG2CHARS( 0x00007FFFFF000000 ),
+ LONG2CHARS( 0x0000FFFFFF000000 ),
+ LONG2CHARS( 0x0001FFFFFF000000 ),
+ LONG2CHARS( 0x0003FFFFFF000000 ),
+ LONG2CHARS( 0x0007FFFFFF000000 ),
+ LONG2CHARS( 0x000FFFFFFF000000 ),
+ LONG2CHARS( 0x001FFFFFFF000000 ),
+ LONG2CHARS( 0x003FFFFFFF000000 ),
+ LONG2CHARS( 0x007FFFFFFF000000 ),
+ LONG2CHARS( 0x00FFFFFFFF000000 ),
+ LONG2CHARS( 0x01FFFFFFFF000000 ),
+ LONG2CHARS( 0x03FFFFFFFF000000 ),
+ LONG2CHARS( 0x07FFFFFFFF000000 ),
+ LONG2CHARS( 0x0FFFFFFFFF000000 ),
+ LONG2CHARS( 0x1FFFFFFFFF000000 ),
+ LONG2CHARS( 0x3FFFFFFFFF000000 ),
+ LONG2CHARS( 0x7FFFFFFFFF000000 ),
+ LONG2CHARS( 0xFFFFFFFFFF000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000002000000 ),
+ LONG2CHARS( 0x0000000006000000 ),
+ LONG2CHARS( 0x000000000E000000 ),
+ LONG2CHARS( 0x000000001E000000 ),
+ LONG2CHARS( 0x000000003E000000 ),
+ LONG2CHARS( 0x000000007E000000 ),
+ LONG2CHARS( 0x00000000FE000000 ),
+ LONG2CHARS( 0x00000001FE000000 ),
+ LONG2CHARS( 0x00000003FE000000 ),
+ LONG2CHARS( 0x00000007FE000000 ),
+ LONG2CHARS( 0x0000000FFE000000 ),
+ LONG2CHARS( 0x0000001FFE000000 ),
+ LONG2CHARS( 0x0000003FFE000000 ),
+ LONG2CHARS( 0x0000007FFE000000 ),
+ LONG2CHARS( 0x000000FFFE000000 ),
+ LONG2CHARS( 0x000001FFFE000000 ),
+ LONG2CHARS( 0x000003FFFE000000 ),
+ LONG2CHARS( 0x000007FFFE000000 ),
+ LONG2CHARS( 0x00000FFFFE000000 ),
+ LONG2CHARS( 0x00001FFFFE000000 ),
+ LONG2CHARS( 0x00003FFFFE000000 ),
+ LONG2CHARS( 0x00007FFFFE000000 ),
+ LONG2CHARS( 0x0000FFFFFE000000 ),
+ LONG2CHARS( 0x0001FFFFFE000000 ),
+ LONG2CHARS( 0x0003FFFFFE000000 ),
+ LONG2CHARS( 0x0007FFFFFE000000 ),
+ LONG2CHARS( 0x000FFFFFFE000000 ),
+ LONG2CHARS( 0x001FFFFFFE000000 ),
+ LONG2CHARS( 0x003FFFFFFE000000 ),
+ LONG2CHARS( 0x007FFFFFFE000000 ),
+ LONG2CHARS( 0x00FFFFFFFE000000 ),
+ LONG2CHARS( 0x01FFFFFFFE000000 ),
+ LONG2CHARS( 0x03FFFFFFFE000000 ),
+ LONG2CHARS( 0x07FFFFFFFE000000 ),
+ LONG2CHARS( 0x0FFFFFFFFE000000 ),
+ LONG2CHARS( 0x1FFFFFFFFE000000 ),
+ LONG2CHARS( 0x3FFFFFFFFE000000 ),
+ LONG2CHARS( 0x7FFFFFFFFE000000 ),
+ LONG2CHARS( 0xFFFFFFFFFE000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000004000000 ),
+ LONG2CHARS( 0x000000000C000000 ),
+ LONG2CHARS( 0x000000001C000000 ),
+ LONG2CHARS( 0x000000003C000000 ),
+ LONG2CHARS( 0x000000007C000000 ),
+ LONG2CHARS( 0x00000000FC000000 ),
+ LONG2CHARS( 0x00000001FC000000 ),
+ LONG2CHARS( 0x00000003FC000000 ),
+ LONG2CHARS( 0x00000007FC000000 ),
+ LONG2CHARS( 0x0000000FFC000000 ),
+ LONG2CHARS( 0x0000001FFC000000 ),
+ LONG2CHARS( 0x0000003FFC000000 ),
+ LONG2CHARS( 0x0000007FFC000000 ),
+ LONG2CHARS( 0x000000FFFC000000 ),
+ LONG2CHARS( 0x000001FFFC000000 ),
+ LONG2CHARS( 0x000003FFFC000000 ),
+ LONG2CHARS( 0x000007FFFC000000 ),
+ LONG2CHARS( 0x00000FFFFC000000 ),
+ LONG2CHARS( 0x00001FFFFC000000 ),
+ LONG2CHARS( 0x00003FFFFC000000 ),
+ LONG2CHARS( 0x00007FFFFC000000 ),
+ LONG2CHARS( 0x0000FFFFFC000000 ),
+ LONG2CHARS( 0x0001FFFFFC000000 ),
+ LONG2CHARS( 0x0003FFFFFC000000 ),
+ LONG2CHARS( 0x0007FFFFFC000000 ),
+ LONG2CHARS( 0x000FFFFFFC000000 ),
+ LONG2CHARS( 0x001FFFFFFC000000 ),
+ LONG2CHARS( 0x003FFFFFFC000000 ),
+ LONG2CHARS( 0x007FFFFFFC000000 ),
+ LONG2CHARS( 0x00FFFFFFFC000000 ),
+ LONG2CHARS( 0x01FFFFFFFC000000 ),
+ LONG2CHARS( 0x03FFFFFFFC000000 ),
+ LONG2CHARS( 0x07FFFFFFFC000000 ),
+ LONG2CHARS( 0x0FFFFFFFFC000000 ),
+ LONG2CHARS( 0x1FFFFFFFFC000000 ),
+ LONG2CHARS( 0x3FFFFFFFFC000000 ),
+ LONG2CHARS( 0x7FFFFFFFFC000000 ),
+ LONG2CHARS( 0xFFFFFFFFFC000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000008000000 ),
+ LONG2CHARS( 0x0000000018000000 ),
+ LONG2CHARS( 0x0000000038000000 ),
+ LONG2CHARS( 0x0000000078000000 ),
+ LONG2CHARS( 0x00000000F8000000 ),
+ LONG2CHARS( 0x00000001F8000000 ),
+ LONG2CHARS( 0x00000003F8000000 ),
+ LONG2CHARS( 0x00000007F8000000 ),
+ LONG2CHARS( 0x0000000FF8000000 ),
+ LONG2CHARS( 0x0000001FF8000000 ),
+ LONG2CHARS( 0x0000003FF8000000 ),
+ LONG2CHARS( 0x0000007FF8000000 ),
+ LONG2CHARS( 0x000000FFF8000000 ),
+ LONG2CHARS( 0x000001FFF8000000 ),
+ LONG2CHARS( 0x000003FFF8000000 ),
+ LONG2CHARS( 0x000007FFF8000000 ),
+ LONG2CHARS( 0x00000FFFF8000000 ),
+ LONG2CHARS( 0x00001FFFF8000000 ),
+ LONG2CHARS( 0x00003FFFF8000000 ),
+ LONG2CHARS( 0x00007FFFF8000000 ),
+ LONG2CHARS( 0x0000FFFFF8000000 ),
+ LONG2CHARS( 0x0001FFFFF8000000 ),
+ LONG2CHARS( 0x0003FFFFF8000000 ),
+ LONG2CHARS( 0x0007FFFFF8000000 ),
+ LONG2CHARS( 0x000FFFFFF8000000 ),
+ LONG2CHARS( 0x001FFFFFF8000000 ),
+ LONG2CHARS( 0x003FFFFFF8000000 ),
+ LONG2CHARS( 0x007FFFFFF8000000 ),
+ LONG2CHARS( 0x00FFFFFFF8000000 ),
+ LONG2CHARS( 0x01FFFFFFF8000000 ),
+ LONG2CHARS( 0x03FFFFFFF8000000 ),
+ LONG2CHARS( 0x07FFFFFFF8000000 ),
+ LONG2CHARS( 0x0FFFFFFFF8000000 ),
+ LONG2CHARS( 0x1FFFFFFFF8000000 ),
+ LONG2CHARS( 0x3FFFFFFFF8000000 ),
+ LONG2CHARS( 0x7FFFFFFFF8000000 ),
+ LONG2CHARS( 0xFFFFFFFFF8000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000010000000 ),
+ LONG2CHARS( 0x0000000030000000 ),
+ LONG2CHARS( 0x0000000070000000 ),
+ LONG2CHARS( 0x00000000F0000000 ),
+ LONG2CHARS( 0x00000001F0000000 ),
+ LONG2CHARS( 0x00000003F0000000 ),
+ LONG2CHARS( 0x00000007F0000000 ),
+ LONG2CHARS( 0x0000000FF0000000 ),
+ LONG2CHARS( 0x0000001FF0000000 ),
+ LONG2CHARS( 0x0000003FF0000000 ),
+ LONG2CHARS( 0x0000007FF0000000 ),
+ LONG2CHARS( 0x000000FFF0000000 ),
+ LONG2CHARS( 0x000001FFF0000000 ),
+ LONG2CHARS( 0x000003FFF0000000 ),
+ LONG2CHARS( 0x000007FFF0000000 ),
+ LONG2CHARS( 0x00000FFFF0000000 ),
+ LONG2CHARS( 0x00001FFFF0000000 ),
+ LONG2CHARS( 0x00003FFFF0000000 ),
+ LONG2CHARS( 0x00007FFFF0000000 ),
+ LONG2CHARS( 0x0000FFFFF0000000 ),
+ LONG2CHARS( 0x0001FFFFF0000000 ),
+ LONG2CHARS( 0x0003FFFFF0000000 ),
+ LONG2CHARS( 0x0007FFFFF0000000 ),
+ LONG2CHARS( 0x000FFFFFF0000000 ),
+ LONG2CHARS( 0x001FFFFFF0000000 ),
+ LONG2CHARS( 0x003FFFFFF0000000 ),
+ LONG2CHARS( 0x007FFFFFF0000000 ),
+ LONG2CHARS( 0x00FFFFFFF0000000 ),
+ LONG2CHARS( 0x01FFFFFFF0000000 ),
+ LONG2CHARS( 0x03FFFFFFF0000000 ),
+ LONG2CHARS( 0x07FFFFFFF0000000 ),
+ LONG2CHARS( 0x0FFFFFFFF0000000 ),
+ LONG2CHARS( 0x1FFFFFFFF0000000 ),
+ LONG2CHARS( 0x3FFFFFFFF0000000 ),
+ LONG2CHARS( 0x7FFFFFFFF0000000 ),
+ LONG2CHARS( 0xFFFFFFFFF0000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000020000000 ),
+ LONG2CHARS( 0x0000000060000000 ),
+ LONG2CHARS( 0x00000000E0000000 ),
+ LONG2CHARS( 0x00000001E0000000 ),
+ LONG2CHARS( 0x00000003E0000000 ),
+ LONG2CHARS( 0x00000007E0000000 ),
+ LONG2CHARS( 0x0000000FE0000000 ),
+ LONG2CHARS( 0x0000001FE0000000 ),
+ LONG2CHARS( 0x0000003FE0000000 ),
+ LONG2CHARS( 0x0000007FE0000000 ),
+ LONG2CHARS( 0x000000FFE0000000 ),
+ LONG2CHARS( 0x000001FFE0000000 ),
+ LONG2CHARS( 0x000003FFE0000000 ),
+ LONG2CHARS( 0x000007FFE0000000 ),
+ LONG2CHARS( 0x00000FFFE0000000 ),
+ LONG2CHARS( 0x00001FFFE0000000 ),
+ LONG2CHARS( 0x00003FFFE0000000 ),
+ LONG2CHARS( 0x00007FFFE0000000 ),
+ LONG2CHARS( 0x0000FFFFE0000000 ),
+ LONG2CHARS( 0x0001FFFFE0000000 ),
+ LONG2CHARS( 0x0003FFFFE0000000 ),
+ LONG2CHARS( 0x0007FFFFE0000000 ),
+ LONG2CHARS( 0x000FFFFFE0000000 ),
+ LONG2CHARS( 0x001FFFFFE0000000 ),
+ LONG2CHARS( 0x003FFFFFE0000000 ),
+ LONG2CHARS( 0x007FFFFFE0000000 ),
+ LONG2CHARS( 0x00FFFFFFE0000000 ),
+ LONG2CHARS( 0x01FFFFFFE0000000 ),
+ LONG2CHARS( 0x03FFFFFFE0000000 ),
+ LONG2CHARS( 0x07FFFFFFE0000000 ),
+ LONG2CHARS( 0x0FFFFFFFE0000000 ),
+ LONG2CHARS( 0x1FFFFFFFE0000000 ),
+ LONG2CHARS( 0x3FFFFFFFE0000000 ),
+ LONG2CHARS( 0x7FFFFFFFE0000000 ),
+ LONG2CHARS( 0xFFFFFFFFE0000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000040000000 ),
+ LONG2CHARS( 0x00000000C0000000 ),
+ LONG2CHARS( 0x00000001C0000000 ),
+ LONG2CHARS( 0x00000003C0000000 ),
+ LONG2CHARS( 0x00000007C0000000 ),
+ LONG2CHARS( 0x0000000FC0000000 ),
+ LONG2CHARS( 0x0000001FC0000000 ),
+ LONG2CHARS( 0x0000003FC0000000 ),
+ LONG2CHARS( 0x0000007FC0000000 ),
+ LONG2CHARS( 0x000000FFC0000000 ),
+ LONG2CHARS( 0x000001FFC0000000 ),
+ LONG2CHARS( 0x000003FFC0000000 ),
+ LONG2CHARS( 0x000007FFC0000000 ),
+ LONG2CHARS( 0x00000FFFC0000000 ),
+ LONG2CHARS( 0x00001FFFC0000000 ),
+ LONG2CHARS( 0x00003FFFC0000000 ),
+ LONG2CHARS( 0x00007FFFC0000000 ),
+ LONG2CHARS( 0x0000FFFFC0000000 ),
+ LONG2CHARS( 0x0001FFFFC0000000 ),
+ LONG2CHARS( 0x0003FFFFC0000000 ),
+ LONG2CHARS( 0x0007FFFFC0000000 ),
+ LONG2CHARS( 0x000FFFFFC0000000 ),
+ LONG2CHARS( 0x001FFFFFC0000000 ),
+ LONG2CHARS( 0x003FFFFFC0000000 ),
+ LONG2CHARS( 0x007FFFFFC0000000 ),
+ LONG2CHARS( 0x00FFFFFFC0000000 ),
+ LONG2CHARS( 0x01FFFFFFC0000000 ),
+ LONG2CHARS( 0x03FFFFFFC0000000 ),
+ LONG2CHARS( 0x07FFFFFFC0000000 ),
+ LONG2CHARS( 0x0FFFFFFFC0000000 ),
+ LONG2CHARS( 0x1FFFFFFFC0000000 ),
+ LONG2CHARS( 0x3FFFFFFFC0000000 ),
+ LONG2CHARS( 0x7FFFFFFFC0000000 ),
+ LONG2CHARS( 0xFFFFFFFFC0000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000080000000 ),
+ LONG2CHARS( 0x0000000180000000 ),
+ LONG2CHARS( 0x0000000380000000 ),
+ LONG2CHARS( 0x0000000780000000 ),
+ LONG2CHARS( 0x0000000F80000000 ),
+ LONG2CHARS( 0x0000001F80000000 ),
+ LONG2CHARS( 0x0000003F80000000 ),
+ LONG2CHARS( 0x0000007F80000000 ),
+ LONG2CHARS( 0x000000FF80000000 ),
+ LONG2CHARS( 0x000001FF80000000 ),
+ LONG2CHARS( 0x000003FF80000000 ),
+ LONG2CHARS( 0x000007FF80000000 ),
+ LONG2CHARS( 0x00000FFF80000000 ),
+ LONG2CHARS( 0x00001FFF80000000 ),
+ LONG2CHARS( 0x00003FFF80000000 ),
+ LONG2CHARS( 0x00007FFF80000000 ),
+ LONG2CHARS( 0x0000FFFF80000000 ),
+ LONG2CHARS( 0x0001FFFF80000000 ),
+ LONG2CHARS( 0x0003FFFF80000000 ),
+ LONG2CHARS( 0x0007FFFF80000000 ),
+ LONG2CHARS( 0x000FFFFF80000000 ),
+ LONG2CHARS( 0x001FFFFF80000000 ),
+ LONG2CHARS( 0x003FFFFF80000000 ),
+ LONG2CHARS( 0x007FFFFF80000000 ),
+ LONG2CHARS( 0x00FFFFFF80000000 ),
+ LONG2CHARS( 0x01FFFFFF80000000 ),
+ LONG2CHARS( 0x03FFFFFF80000000 ),
+ LONG2CHARS( 0x07FFFFFF80000000 ),
+ LONG2CHARS( 0x0FFFFFFF80000000 ),
+ LONG2CHARS( 0x1FFFFFFF80000000 ),
+ LONG2CHARS( 0x3FFFFFFF80000000 ),
+ LONG2CHARS( 0x7FFFFFFF80000000 ),
+ LONG2CHARS( 0xFFFFFFFF80000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000100000000 ),
+ LONG2CHARS( 0x0000000300000000 ),
+ LONG2CHARS( 0x0000000700000000 ),
+ LONG2CHARS( 0x0000000F00000000 ),
+ LONG2CHARS( 0x0000001F00000000 ),
+ LONG2CHARS( 0x0000003F00000000 ),
+ LONG2CHARS( 0x0000007F00000000 ),
+ LONG2CHARS( 0x000000FF00000000 ),
+ LONG2CHARS( 0x000001FF00000000 ),
+ LONG2CHARS( 0x000003FF00000000 ),
+ LONG2CHARS( 0x000007FF00000000 ),
+ LONG2CHARS( 0x00000FFF00000000 ),
+ LONG2CHARS( 0x00001FFF00000000 ),
+ LONG2CHARS( 0x00003FFF00000000 ),
+ LONG2CHARS( 0x00007FFF00000000 ),
+ LONG2CHARS( 0x0000FFFF00000000 ),
+ LONG2CHARS( 0x0001FFFF00000000 ),
+ LONG2CHARS( 0x0003FFFF00000000 ),
+ LONG2CHARS( 0x0007FFFF00000000 ),
+ LONG2CHARS( 0x000FFFFF00000000 ),
+ LONG2CHARS( 0x001FFFFF00000000 ),
+ LONG2CHARS( 0x003FFFFF00000000 ),
+ LONG2CHARS( 0x007FFFFF00000000 ),
+ LONG2CHARS( 0x00FFFFFF00000000 ),
+ LONG2CHARS( 0x01FFFFFF00000000 ),
+ LONG2CHARS( 0x03FFFFFF00000000 ),
+ LONG2CHARS( 0x07FFFFFF00000000 ),
+ LONG2CHARS( 0x0FFFFFFF00000000 ),
+ LONG2CHARS( 0x1FFFFFFF00000000 ),
+ LONG2CHARS( 0x3FFFFFFF00000000 ),
+ LONG2CHARS( 0x7FFFFFFF00000000 ),
+ LONG2CHARS( 0xFFFFFFFF00000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000200000000 ),
+ LONG2CHARS( 0x0000000600000000 ),
+ LONG2CHARS( 0x0000000E00000000 ),
+ LONG2CHARS( 0x0000001E00000000 ),
+ LONG2CHARS( 0x0000003E00000000 ),
+ LONG2CHARS( 0x0000007E00000000 ),
+ LONG2CHARS( 0x000000FE00000000 ),
+ LONG2CHARS( 0x000001FE00000000 ),
+ LONG2CHARS( 0x000003FE00000000 ),
+ LONG2CHARS( 0x000007FE00000000 ),
+ LONG2CHARS( 0x00000FFE00000000 ),
+ LONG2CHARS( 0x00001FFE00000000 ),
+ LONG2CHARS( 0x00003FFE00000000 ),
+ LONG2CHARS( 0x00007FFE00000000 ),
+ LONG2CHARS( 0x0000FFFE00000000 ),
+ LONG2CHARS( 0x0001FFFE00000000 ),
+ LONG2CHARS( 0x0003FFFE00000000 ),
+ LONG2CHARS( 0x0007FFFE00000000 ),
+ LONG2CHARS( 0x000FFFFE00000000 ),
+ LONG2CHARS( 0x001FFFFE00000000 ),
+ LONG2CHARS( 0x003FFFFE00000000 ),
+ LONG2CHARS( 0x007FFFFE00000000 ),
+ LONG2CHARS( 0x00FFFFFE00000000 ),
+ LONG2CHARS( 0x01FFFFFE00000000 ),
+ LONG2CHARS( 0x03FFFFFE00000000 ),
+ LONG2CHARS( 0x07FFFFFE00000000 ),
+ LONG2CHARS( 0x0FFFFFFE00000000 ),
+ LONG2CHARS( 0x1FFFFFFE00000000 ),
+ LONG2CHARS( 0x3FFFFFFE00000000 ),
+ LONG2CHARS( 0x7FFFFFFE00000000 ),
+ LONG2CHARS( 0xFFFFFFFE00000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000400000000 ),
+ LONG2CHARS( 0x0000000C00000000 ),
+ LONG2CHARS( 0x0000001C00000000 ),
+ LONG2CHARS( 0x0000003C00000000 ),
+ LONG2CHARS( 0x0000007C00000000 ),
+ LONG2CHARS( 0x000000FC00000000 ),
+ LONG2CHARS( 0x000001FC00000000 ),
+ LONG2CHARS( 0x000003FC00000000 ),
+ LONG2CHARS( 0x000007FC00000000 ),
+ LONG2CHARS( 0x00000FFC00000000 ),
+ LONG2CHARS( 0x00001FFC00000000 ),
+ LONG2CHARS( 0x00003FFC00000000 ),
+ LONG2CHARS( 0x00007FFC00000000 ),
+ LONG2CHARS( 0x0000FFFC00000000 ),
+ LONG2CHARS( 0x0001FFFC00000000 ),
+ LONG2CHARS( 0x0003FFFC00000000 ),
+ LONG2CHARS( 0x0007FFFC00000000 ),
+ LONG2CHARS( 0x000FFFFC00000000 ),
+ LONG2CHARS( 0x001FFFFC00000000 ),
+ LONG2CHARS( 0x003FFFFC00000000 ),
+ LONG2CHARS( 0x007FFFFC00000000 ),
+ LONG2CHARS( 0x00FFFFFC00000000 ),
+ LONG2CHARS( 0x01FFFFFC00000000 ),
+ LONG2CHARS( 0x03FFFFFC00000000 ),
+ LONG2CHARS( 0x07FFFFFC00000000 ),
+ LONG2CHARS( 0x0FFFFFFC00000000 ),
+ LONG2CHARS( 0x1FFFFFFC00000000 ),
+ LONG2CHARS( 0x3FFFFFFC00000000 ),
+ LONG2CHARS( 0x7FFFFFFC00000000 ),
+ LONG2CHARS( 0xFFFFFFFC00000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000800000000 ),
+ LONG2CHARS( 0x0000001800000000 ),
+ LONG2CHARS( 0x0000003800000000 ),
+ LONG2CHARS( 0x0000007800000000 ),
+ LONG2CHARS( 0x000000F800000000 ),
+ LONG2CHARS( 0x000001F800000000 ),
+ LONG2CHARS( 0x000003F800000000 ),
+ LONG2CHARS( 0x000007F800000000 ),
+ LONG2CHARS( 0x00000FF800000000 ),
+ LONG2CHARS( 0x00001FF800000000 ),
+ LONG2CHARS( 0x00003FF800000000 ),
+ LONG2CHARS( 0x00007FF800000000 ),
+ LONG2CHARS( 0x0000FFF800000000 ),
+ LONG2CHARS( 0x0001FFF800000000 ),
+ LONG2CHARS( 0x0003FFF800000000 ),
+ LONG2CHARS( 0x0007FFF800000000 ),
+ LONG2CHARS( 0x000FFFF800000000 ),
+ LONG2CHARS( 0x001FFFF800000000 ),
+ LONG2CHARS( 0x003FFFF800000000 ),
+ LONG2CHARS( 0x007FFFF800000000 ),
+ LONG2CHARS( 0x00FFFFF800000000 ),
+ LONG2CHARS( 0x01FFFFF800000000 ),
+ LONG2CHARS( 0x03FFFFF800000000 ),
+ LONG2CHARS( 0x07FFFFF800000000 ),
+ LONG2CHARS( 0x0FFFFFF800000000 ),
+ LONG2CHARS( 0x1FFFFFF800000000 ),
+ LONG2CHARS( 0x3FFFFFF800000000 ),
+ LONG2CHARS( 0x7FFFFFF800000000 ),
+ LONG2CHARS( 0xFFFFFFF800000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000001000000000 ),
+ LONG2CHARS( 0x0000003000000000 ),
+ LONG2CHARS( 0x0000007000000000 ),
+ LONG2CHARS( 0x000000F000000000 ),
+ LONG2CHARS( 0x000001F000000000 ),
+ LONG2CHARS( 0x000003F000000000 ),
+ LONG2CHARS( 0x000007F000000000 ),
+ LONG2CHARS( 0x00000FF000000000 ),
+ LONG2CHARS( 0x00001FF000000000 ),
+ LONG2CHARS( 0x00003FF000000000 ),
+ LONG2CHARS( 0x00007FF000000000 ),
+ LONG2CHARS( 0x0000FFF000000000 ),
+ LONG2CHARS( 0x0001FFF000000000 ),
+ LONG2CHARS( 0x0003FFF000000000 ),
+ LONG2CHARS( 0x0007FFF000000000 ),
+ LONG2CHARS( 0x000FFFF000000000 ),
+ LONG2CHARS( 0x001FFFF000000000 ),
+ LONG2CHARS( 0x003FFFF000000000 ),
+ LONG2CHARS( 0x007FFFF000000000 ),
+ LONG2CHARS( 0x00FFFFF000000000 ),
+ LONG2CHARS( 0x01FFFFF000000000 ),
+ LONG2CHARS( 0x03FFFFF000000000 ),
+ LONG2CHARS( 0x07FFFFF000000000 ),
+ LONG2CHARS( 0x0FFFFFF000000000 ),
+ LONG2CHARS( 0x1FFFFFF000000000 ),
+ LONG2CHARS( 0x3FFFFFF000000000 ),
+ LONG2CHARS( 0x7FFFFFF000000000 ),
+ LONG2CHARS( 0xFFFFFFF000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000002000000000 ),
+ LONG2CHARS( 0x0000006000000000 ),
+ LONG2CHARS( 0x000000E000000000 ),
+ LONG2CHARS( 0x000001E000000000 ),
+ LONG2CHARS( 0x000003E000000000 ),
+ LONG2CHARS( 0x000007E000000000 ),
+ LONG2CHARS( 0x00000FE000000000 ),
+ LONG2CHARS( 0x00001FE000000000 ),
+ LONG2CHARS( 0x00003FE000000000 ),
+ LONG2CHARS( 0x00007FE000000000 ),
+ LONG2CHARS( 0x0000FFE000000000 ),
+ LONG2CHARS( 0x0001FFE000000000 ),
+ LONG2CHARS( 0x0003FFE000000000 ),
+ LONG2CHARS( 0x0007FFE000000000 ),
+ LONG2CHARS( 0x000FFFE000000000 ),
+ LONG2CHARS( 0x001FFFE000000000 ),
+ LONG2CHARS( 0x003FFFE000000000 ),
+ LONG2CHARS( 0x007FFFE000000000 ),
+ LONG2CHARS( 0x00FFFFE000000000 ),
+ LONG2CHARS( 0x01FFFFE000000000 ),
+ LONG2CHARS( 0x03FFFFE000000000 ),
+ LONG2CHARS( 0x07FFFFE000000000 ),
+ LONG2CHARS( 0x0FFFFFE000000000 ),
+ LONG2CHARS( 0x1FFFFFE000000000 ),
+ LONG2CHARS( 0x3FFFFFE000000000 ),
+ LONG2CHARS( 0x7FFFFFE000000000 ),
+ LONG2CHARS( 0xFFFFFFE000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000004000000000 ),
+ LONG2CHARS( 0x000000C000000000 ),
+ LONG2CHARS( 0x000001C000000000 ),
+ LONG2CHARS( 0x000003C000000000 ),
+ LONG2CHARS( 0x000007C000000000 ),
+ LONG2CHARS( 0x00000FC000000000 ),
+ LONG2CHARS( 0x00001FC000000000 ),
+ LONG2CHARS( 0x00003FC000000000 ),
+ LONG2CHARS( 0x00007FC000000000 ),
+ LONG2CHARS( 0x0000FFC000000000 ),
+ LONG2CHARS( 0x0001FFC000000000 ),
+ LONG2CHARS( 0x0003FFC000000000 ),
+ LONG2CHARS( 0x0007FFC000000000 ),
+ LONG2CHARS( 0x000FFFC000000000 ),
+ LONG2CHARS( 0x001FFFC000000000 ),
+ LONG2CHARS( 0x003FFFC000000000 ),
+ LONG2CHARS( 0x007FFFC000000000 ),
+ LONG2CHARS( 0x00FFFFC000000000 ),
+ LONG2CHARS( 0x01FFFFC000000000 ),
+ LONG2CHARS( 0x03FFFFC000000000 ),
+ LONG2CHARS( 0x07FFFFC000000000 ),
+ LONG2CHARS( 0x0FFFFFC000000000 ),
+ LONG2CHARS( 0x1FFFFFC000000000 ),
+ LONG2CHARS( 0x3FFFFFC000000000 ),
+ LONG2CHARS( 0x7FFFFFC000000000 ),
+ LONG2CHARS( 0xFFFFFFC000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000008000000000 ),
+ LONG2CHARS( 0x0000018000000000 ),
+ LONG2CHARS( 0x0000038000000000 ),
+ LONG2CHARS( 0x0000078000000000 ),
+ LONG2CHARS( 0x00000F8000000000 ),
+ LONG2CHARS( 0x00001F8000000000 ),
+ LONG2CHARS( 0x00003F8000000000 ),
+ LONG2CHARS( 0x00007F8000000000 ),
+ LONG2CHARS( 0x0000FF8000000000 ),
+ LONG2CHARS( 0x0001FF8000000000 ),
+ LONG2CHARS( 0x0003FF8000000000 ),
+ LONG2CHARS( 0x0007FF8000000000 ),
+ LONG2CHARS( 0x000FFF8000000000 ),
+ LONG2CHARS( 0x001FFF8000000000 ),
+ LONG2CHARS( 0x003FFF8000000000 ),
+ LONG2CHARS( 0x007FFF8000000000 ),
+ LONG2CHARS( 0x00FFFF8000000000 ),
+ LONG2CHARS( 0x01FFFF8000000000 ),
+ LONG2CHARS( 0x03FFFF8000000000 ),
+ LONG2CHARS( 0x07FFFF8000000000 ),
+ LONG2CHARS( 0x0FFFFF8000000000 ),
+ LONG2CHARS( 0x1FFFFF8000000000 ),
+ LONG2CHARS( 0x3FFFFF8000000000 ),
+ LONG2CHARS( 0x7FFFFF8000000000 ),
+ LONG2CHARS( 0xFFFFFF8000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000010000000000 ),
+ LONG2CHARS( 0x0000030000000000 ),
+ LONG2CHARS( 0x0000070000000000 ),
+ LONG2CHARS( 0x00000F0000000000 ),
+ LONG2CHARS( 0x00001F0000000000 ),
+ LONG2CHARS( 0x00003F0000000000 ),
+ LONG2CHARS( 0x00007F0000000000 ),
+ LONG2CHARS( 0x0000FF0000000000 ),
+ LONG2CHARS( 0x0001FF0000000000 ),
+ LONG2CHARS( 0x0003FF0000000000 ),
+ LONG2CHARS( 0x0007FF0000000000 ),
+ LONG2CHARS( 0x000FFF0000000000 ),
+ LONG2CHARS( 0x001FFF0000000000 ),
+ LONG2CHARS( 0x003FFF0000000000 ),
+ LONG2CHARS( 0x007FFF0000000000 ),
+ LONG2CHARS( 0x00FFFF0000000000 ),
+ LONG2CHARS( 0x01FFFF0000000000 ),
+ LONG2CHARS( 0x03FFFF0000000000 ),
+ LONG2CHARS( 0x07FFFF0000000000 ),
+ LONG2CHARS( 0x0FFFFF0000000000 ),
+ LONG2CHARS( 0x1FFFFF0000000000 ),
+ LONG2CHARS( 0x3FFFFF0000000000 ),
+ LONG2CHARS( 0x7FFFFF0000000000 ),
+ LONG2CHARS( 0xFFFFFF0000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000020000000000 ),
+ LONG2CHARS( 0x0000060000000000 ),
+ LONG2CHARS( 0x00000E0000000000 ),
+ LONG2CHARS( 0x00001E0000000000 ),
+ LONG2CHARS( 0x00003E0000000000 ),
+ LONG2CHARS( 0x00007E0000000000 ),
+ LONG2CHARS( 0x0000FE0000000000 ),
+ LONG2CHARS( 0x0001FE0000000000 ),
+ LONG2CHARS( 0x0003FE0000000000 ),
+ LONG2CHARS( 0x0007FE0000000000 ),
+ LONG2CHARS( 0x000FFE0000000000 ),
+ LONG2CHARS( 0x001FFE0000000000 ),
+ LONG2CHARS( 0x003FFE0000000000 ),
+ LONG2CHARS( 0x007FFE0000000000 ),
+ LONG2CHARS( 0x00FFFE0000000000 ),
+ LONG2CHARS( 0x01FFFE0000000000 ),
+ LONG2CHARS( 0x03FFFE0000000000 ),
+ LONG2CHARS( 0x07FFFE0000000000 ),
+ LONG2CHARS( 0x0FFFFE0000000000 ),
+ LONG2CHARS( 0x1FFFFE0000000000 ),
+ LONG2CHARS( 0x3FFFFE0000000000 ),
+ LONG2CHARS( 0x7FFFFE0000000000 ),
+ LONG2CHARS( 0xFFFFFE0000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000040000000000 ),
+ LONG2CHARS( 0x00000C0000000000 ),
+ LONG2CHARS( 0x00001C0000000000 ),
+ LONG2CHARS( 0x00003C0000000000 ),
+ LONG2CHARS( 0x00007C0000000000 ),
+ LONG2CHARS( 0x0000FC0000000000 ),
+ LONG2CHARS( 0x0001FC0000000000 ),
+ LONG2CHARS( 0x0003FC0000000000 ),
+ LONG2CHARS( 0x0007FC0000000000 ),
+ LONG2CHARS( 0x000FFC0000000000 ),
+ LONG2CHARS( 0x001FFC0000000000 ),
+ LONG2CHARS( 0x003FFC0000000000 ),
+ LONG2CHARS( 0x007FFC0000000000 ),
+ LONG2CHARS( 0x00FFFC0000000000 ),
+ LONG2CHARS( 0x01FFFC0000000000 ),
+ LONG2CHARS( 0x03FFFC0000000000 ),
+ LONG2CHARS( 0x07FFFC0000000000 ),
+ LONG2CHARS( 0x0FFFFC0000000000 ),
+ LONG2CHARS( 0x1FFFFC0000000000 ),
+ LONG2CHARS( 0x3FFFFC0000000000 ),
+ LONG2CHARS( 0x7FFFFC0000000000 ),
+ LONG2CHARS( 0xFFFFFC0000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000080000000000 ),
+ LONG2CHARS( 0x0000180000000000 ),
+ LONG2CHARS( 0x0000380000000000 ),
+ LONG2CHARS( 0x0000780000000000 ),
+ LONG2CHARS( 0x0000F80000000000 ),
+ LONG2CHARS( 0x0001F80000000000 ),
+ LONG2CHARS( 0x0003F80000000000 ),
+ LONG2CHARS( 0x0007F80000000000 ),
+ LONG2CHARS( 0x000FF80000000000 ),
+ LONG2CHARS( 0x001FF80000000000 ),
+ LONG2CHARS( 0x003FF80000000000 ),
+ LONG2CHARS( 0x007FF80000000000 ),
+ LONG2CHARS( 0x00FFF80000000000 ),
+ LONG2CHARS( 0x01FFF80000000000 ),
+ LONG2CHARS( 0x03FFF80000000000 ),
+ LONG2CHARS( 0x07FFF80000000000 ),
+ LONG2CHARS( 0x0FFFF80000000000 ),
+ LONG2CHARS( 0x1FFFF80000000000 ),
+ LONG2CHARS( 0x3FFFF80000000000 ),
+ LONG2CHARS( 0x7FFFF80000000000 ),
+ LONG2CHARS( 0xFFFFF80000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000100000000000 ),
+ LONG2CHARS( 0x0000300000000000 ),
+ LONG2CHARS( 0x0000700000000000 ),
+ LONG2CHARS( 0x0000F00000000000 ),
+ LONG2CHARS( 0x0001F00000000000 ),
+ LONG2CHARS( 0x0003F00000000000 ),
+ LONG2CHARS( 0x0007F00000000000 ),
+ LONG2CHARS( 0x000FF00000000000 ),
+ LONG2CHARS( 0x001FF00000000000 ),
+ LONG2CHARS( 0x003FF00000000000 ),
+ LONG2CHARS( 0x007FF00000000000 ),
+ LONG2CHARS( 0x00FFF00000000000 ),
+ LONG2CHARS( 0x01FFF00000000000 ),
+ LONG2CHARS( 0x03FFF00000000000 ),
+ LONG2CHARS( 0x07FFF00000000000 ),
+ LONG2CHARS( 0x0FFFF00000000000 ),
+ LONG2CHARS( 0x1FFFF00000000000 ),
+ LONG2CHARS( 0x3FFFF00000000000 ),
+ LONG2CHARS( 0x7FFFF00000000000 ),
+ LONG2CHARS( 0xFFFFF00000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000200000000000 ),
+ LONG2CHARS( 0x0000600000000000 ),
+ LONG2CHARS( 0x0000E00000000000 ),
+ LONG2CHARS( 0x0001E00000000000 ),
+ LONG2CHARS( 0x0003E00000000000 ),
+ LONG2CHARS( 0x0007E00000000000 ),
+ LONG2CHARS( 0x000FE00000000000 ),
+ LONG2CHARS( 0x001FE00000000000 ),
+ LONG2CHARS( 0x003FE00000000000 ),
+ LONG2CHARS( 0x007FE00000000000 ),
+ LONG2CHARS( 0x00FFE00000000000 ),
+ LONG2CHARS( 0x01FFE00000000000 ),
+ LONG2CHARS( 0x03FFE00000000000 ),
+ LONG2CHARS( 0x07FFE00000000000 ),
+ LONG2CHARS( 0x0FFFE00000000000 ),
+ LONG2CHARS( 0x1FFFE00000000000 ),
+ LONG2CHARS( 0x3FFFE00000000000 ),
+ LONG2CHARS( 0x7FFFE00000000000 ),
+ LONG2CHARS( 0xFFFFE00000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000400000000000 ),
+ LONG2CHARS( 0x0000C00000000000 ),
+ LONG2CHARS( 0x0001C00000000000 ),
+ LONG2CHARS( 0x0003C00000000000 ),
+ LONG2CHARS( 0x0007C00000000000 ),
+ LONG2CHARS( 0x000FC00000000000 ),
+ LONG2CHARS( 0x001FC00000000000 ),
+ LONG2CHARS( 0x003FC00000000000 ),
+ LONG2CHARS( 0x007FC00000000000 ),
+ LONG2CHARS( 0x00FFC00000000000 ),
+ LONG2CHARS( 0x01FFC00000000000 ),
+ LONG2CHARS( 0x03FFC00000000000 ),
+ LONG2CHARS( 0x07FFC00000000000 ),
+ LONG2CHARS( 0x0FFFC00000000000 ),
+ LONG2CHARS( 0x1FFFC00000000000 ),
+ LONG2CHARS( 0x3FFFC00000000000 ),
+ LONG2CHARS( 0x7FFFC00000000000 ),
+ LONG2CHARS( 0xFFFFC00000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000800000000000 ),
+ LONG2CHARS( 0x0001800000000000 ),
+ LONG2CHARS( 0x0003800000000000 ),
+ LONG2CHARS( 0x0007800000000000 ),
+ LONG2CHARS( 0x000F800000000000 ),
+ LONG2CHARS( 0x001F800000000000 ),
+ LONG2CHARS( 0x003F800000000000 ),
+ LONG2CHARS( 0x007F800000000000 ),
+ LONG2CHARS( 0x00FF800000000000 ),
+ LONG2CHARS( 0x01FF800000000000 ),
+ LONG2CHARS( 0x03FF800000000000 ),
+ LONG2CHARS( 0x07FF800000000000 ),
+ LONG2CHARS( 0x0FFF800000000000 ),
+ LONG2CHARS( 0x1FFF800000000000 ),
+ LONG2CHARS( 0x3FFF800000000000 ),
+ LONG2CHARS( 0x7FFF800000000000 ),
+ LONG2CHARS( 0xFFFF800000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0001000000000000 ),
+ LONG2CHARS( 0x0003000000000000 ),
+ LONG2CHARS( 0x0007000000000000 ),
+ LONG2CHARS( 0x000F000000000000 ),
+ LONG2CHARS( 0x001F000000000000 ),
+ LONG2CHARS( 0x003F000000000000 ),
+ LONG2CHARS( 0x007F000000000000 ),
+ LONG2CHARS( 0x00FF000000000000 ),
+ LONG2CHARS( 0x01FF000000000000 ),
+ LONG2CHARS( 0x03FF000000000000 ),
+ LONG2CHARS( 0x07FF000000000000 ),
+ LONG2CHARS( 0x0FFF000000000000 ),
+ LONG2CHARS( 0x1FFF000000000000 ),
+ LONG2CHARS( 0x3FFF000000000000 ),
+ LONG2CHARS( 0x7FFF000000000000 ),
+ LONG2CHARS( 0xFFFF000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0002000000000000 ),
+ LONG2CHARS( 0x0006000000000000 ),
+ LONG2CHARS( 0x000E000000000000 ),
+ LONG2CHARS( 0x001E000000000000 ),
+ LONG2CHARS( 0x003E000000000000 ),
+ LONG2CHARS( 0x007E000000000000 ),
+ LONG2CHARS( 0x00FE000000000000 ),
+ LONG2CHARS( 0x01FE000000000000 ),
+ LONG2CHARS( 0x03FE000000000000 ),
+ LONG2CHARS( 0x07FE000000000000 ),
+ LONG2CHARS( 0x0FFE000000000000 ),
+ LONG2CHARS( 0x1FFE000000000000 ),
+ LONG2CHARS( 0x3FFE000000000000 ),
+ LONG2CHARS( 0x7FFE000000000000 ),
+ LONG2CHARS( 0xFFFE000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0004000000000000 ),
+ LONG2CHARS( 0x000C000000000000 ),
+ LONG2CHARS( 0x001C000000000000 ),
+ LONG2CHARS( 0x003C000000000000 ),
+ LONG2CHARS( 0x007C000000000000 ),
+ LONG2CHARS( 0x00FC000000000000 ),
+ LONG2CHARS( 0x01FC000000000000 ),
+ LONG2CHARS( 0x03FC000000000000 ),
+ LONG2CHARS( 0x07FC000000000000 ),
+ LONG2CHARS( 0x0FFC000000000000 ),
+ LONG2CHARS( 0x1FFC000000000000 ),
+ LONG2CHARS( 0x3FFC000000000000 ),
+ LONG2CHARS( 0x7FFC000000000000 ),
+ LONG2CHARS( 0xFFFC000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0008000000000000 ),
+ LONG2CHARS( 0x0018000000000000 ),
+ LONG2CHARS( 0x0038000000000000 ),
+ LONG2CHARS( 0x0078000000000000 ),
+ LONG2CHARS( 0x00F8000000000000 ),
+ LONG2CHARS( 0x01F8000000000000 ),
+ LONG2CHARS( 0x03F8000000000000 ),
+ LONG2CHARS( 0x07F8000000000000 ),
+ LONG2CHARS( 0x0FF8000000000000 ),
+ LONG2CHARS( 0x1FF8000000000000 ),
+ LONG2CHARS( 0x3FF8000000000000 ),
+ LONG2CHARS( 0x7FF8000000000000 ),
+ LONG2CHARS( 0xFFF8000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0010000000000000 ),
+ LONG2CHARS( 0x0030000000000000 ),
+ LONG2CHARS( 0x0070000000000000 ),
+ LONG2CHARS( 0x00F0000000000000 ),
+ LONG2CHARS( 0x01F0000000000000 ),
+ LONG2CHARS( 0x03F0000000000000 ),
+ LONG2CHARS( 0x07F0000000000000 ),
+ LONG2CHARS( 0x0FF0000000000000 ),
+ LONG2CHARS( 0x1FF0000000000000 ),
+ LONG2CHARS( 0x3FF0000000000000 ),
+ LONG2CHARS( 0x7FF0000000000000 ),
+ LONG2CHARS( 0xFFF0000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0020000000000000 ),
+ LONG2CHARS( 0x0060000000000000 ),
+ LONG2CHARS( 0x00E0000000000000 ),
+ LONG2CHARS( 0x01E0000000000000 ),
+ LONG2CHARS( 0x03E0000000000000 ),
+ LONG2CHARS( 0x07E0000000000000 ),
+ LONG2CHARS( 0x0FE0000000000000 ),
+ LONG2CHARS( 0x1FE0000000000000 ),
+ LONG2CHARS( 0x3FE0000000000000 ),
+ LONG2CHARS( 0x7FE0000000000000 ),
+ LONG2CHARS( 0xFFE0000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0040000000000000 ),
+ LONG2CHARS( 0x00C0000000000000 ),
+ LONG2CHARS( 0x01C0000000000000 ),
+ LONG2CHARS( 0x03C0000000000000 ),
+ LONG2CHARS( 0x07C0000000000000 ),
+ LONG2CHARS( 0x0FC0000000000000 ),
+ LONG2CHARS( 0x1FC0000000000000 ),
+ LONG2CHARS( 0x3FC0000000000000 ),
+ LONG2CHARS( 0x7FC0000000000000 ),
+ LONG2CHARS( 0xFFC0000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0080000000000000 ),
+ LONG2CHARS( 0x0180000000000000 ),
+ LONG2CHARS( 0x0380000000000000 ),
+ LONG2CHARS( 0x0780000000000000 ),
+ LONG2CHARS( 0x0F80000000000000 ),
+ LONG2CHARS( 0x1F80000000000000 ),
+ LONG2CHARS( 0x3F80000000000000 ),
+ LONG2CHARS( 0x7F80000000000000 ),
+ LONG2CHARS( 0xFF80000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0100000000000000 ),
+ LONG2CHARS( 0x0300000000000000 ),
+ LONG2CHARS( 0x0700000000000000 ),
+ LONG2CHARS( 0x0F00000000000000 ),
+ LONG2CHARS( 0x1F00000000000000 ),
+ LONG2CHARS( 0x3F00000000000000 ),
+ LONG2CHARS( 0x7F00000000000000 ),
+ LONG2CHARS( 0xFF00000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0200000000000000 ),
+ LONG2CHARS( 0x0600000000000000 ),
+ LONG2CHARS( 0x0E00000000000000 ),
+ LONG2CHARS( 0x1E00000000000000 ),
+ LONG2CHARS( 0x3E00000000000000 ),
+ LONG2CHARS( 0x7E00000000000000 ),
+ LONG2CHARS( 0xFE00000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0400000000000000 ),
+ LONG2CHARS( 0x0C00000000000000 ),
+ LONG2CHARS( 0x1C00000000000000 ),
+ LONG2CHARS( 0x3C00000000000000 ),
+ LONG2CHARS( 0x7C00000000000000 ),
+ LONG2CHARS( 0xFC00000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0800000000000000 ),
+ LONG2CHARS( 0x1800000000000000 ),
+ LONG2CHARS( 0x3800000000000000 ),
+ LONG2CHARS( 0x7800000000000000 ),
+ LONG2CHARS( 0xF800000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x1000000000000000 ),
+ LONG2CHARS( 0x3000000000000000 ),
+ LONG2CHARS( 0x7000000000000000 ),
+ LONG2CHARS( 0xF000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x2000000000000000 ),
+ LONG2CHARS( 0x6000000000000000 ),
+ LONG2CHARS( 0xE000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x4000000000000000 ),
+ LONG2CHARS( 0xC000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+ {
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x8000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ LONG2CHARS( 0x0000000000000000 ),
+ },
+};
+#endif /* PPW */
+#endif
+
+
+/* used for masking bits in bresenham lines
+ mask[n] is used to mask out all but bit n in a longword (n is a
+screen position).
+ rmask[n] is used to mask out the single bit at position n (n
+is a screen posiotion.)
+*/
+
+#define _1_ ((PixelType)1)
+
+#if (BITMAP_BIT_ORDER == MSBFirst)
+PixelType mask[PPW] =
+ {
+#if PPW == 64
+ LONG2CHARS( _1_<<63 ), LONG2CHARS( 1L<<62 ), LONG2CHARS( 1L<<61 ),
+ LONG2CHARS( 1L<<60 ), LONG2CHARS( 1L<<59 ),
+ LONG2CHARS( 1L<<58 ), LONG2CHARS( 1L<<57 ), LONG2CHARS( 1L<<56 ),
+ LONG2CHARS( 1L<<55 ), LONG2CHARS( 1L<<54 ), LONG2CHARS( 1L<<53 ),
+ LONG2CHARS( 1L<<52 ), LONG2CHARS( 1L<<51 ), LONG2CHARS( 1L<<50 ),
+ LONG2CHARS( 1L<<49 ), LONG2CHARS( 1L<<48 ), LONG2CHARS( 1L<<47 ),
+ LONG2CHARS( 1L<<46 ), LONG2CHARS( 1L<<45 ), LONG2CHARS( 1L<<44 ),
+ LONG2CHARS( 1L<<43 ), LONG2CHARS( 1L<<42 ), LONG2CHARS( 1L<<41 ),
+ LONG2CHARS( 1L<<40 ), LONG2CHARS( 1L<<39 ), LONG2CHARS( 1L<<38 ),
+ LONG2CHARS( 1L<<37 ), LONG2CHARS( 1L<<36 ), LONG2CHARS( 1L<<35 ),
+ LONG2CHARS( 1L<<34 ), LONG2CHARS( 1L<<33 ), LONG2CHARS( 1L<<32 ),
+#endif /* PPW */
+ LONG2CHARS( _1_<<31 ), LONG2CHARS( 1<<30 ), LONG2CHARS( 1<<29 ),
+ LONG2CHARS( 1<<28 ), LONG2CHARS( 1<<27 ), LONG2CHARS( 1<<26 ),
+ LONG2CHARS( 1<<25 ), LONG2CHARS( 1<<24 ), LONG2CHARS( 1<<23 ),
+ LONG2CHARS( 1<<22 ), LONG2CHARS( 1<<21 ), LONG2CHARS( 1<<20 ),
+ LONG2CHARS( 1<<19 ), LONG2CHARS( 1<<18 ), LONG2CHARS( 1<<17 ),
+ LONG2CHARS( 1<<16 ), LONG2CHARS( 1<<15 ), LONG2CHARS( 1<<14 ),
+ LONG2CHARS( 1<<13 ), LONG2CHARS( 1<<12 ), LONG2CHARS( 1<<11 ),
+ LONG2CHARS( 1<<10 ), LONG2CHARS( 1<<9 ), LONG2CHARS( 1<<8 ),
+ LONG2CHARS( 1<<7 ), LONG2CHARS( 1<<6 ), LONG2CHARS( 1<<5 ),
+ LONG2CHARS( 1<<4 ), LONG2CHARS( 1<<3 ), LONG2CHARS( 1<<2 ),
+ LONG2CHARS( 1<<1 ), LONG2CHARS( 1<<0 )
+ };
+
+PixelType rmask[] =
+ {
+#if PPW == 64
+ 0xffffffffffffffff ^ LONG2CHARS( _1_<<63 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<62 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<61 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<60 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<59 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<58 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<57 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<56 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<55 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<54 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<53 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<52 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<51 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<50 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<49 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<48 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<47 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<46 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<45 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<44 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<43 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<42 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<41 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<40 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<39 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<38 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<37 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<36 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<35 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<34 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<33 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<32 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<31 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<30 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<29 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<28 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<27 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<26 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<25 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<24 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<23 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<22 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<21 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<20 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<19 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<18 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<17 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<16 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<15 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<14 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<13 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<12 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<11 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<10 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<9 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<8 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<7 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<6 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<5 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<4 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<3 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<2 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<1 ),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<0 )
+#else /* PPW */
+ 0xffffffff ^ LONG2CHARS( _1_<<31 ), 0xffffffff ^ LONG2CHARS( 1<<30 ),
+ 0xffffffff ^ LONG2CHARS( 1<<29 ), 0xffffffff ^ LONG2CHARS( 1<<28),
+ 0xffffffff ^ LONG2CHARS( 1<<27 ), 0xffffffff ^ LONG2CHARS( 1<<26),
+ 0xffffffff ^ LONG2CHARS( 1<<25 ), 0xffffffff ^ LONG2CHARS( 1<<24 ),
+ 0xffffffff ^ LONG2CHARS( 1<<23 ), 0xffffffff ^ LONG2CHARS( 1<<22),
+ 0xffffffff ^ LONG2CHARS( 1<<21 ), 0xffffffff ^ LONG2CHARS( 1<<20),
+ 0xffffffff ^ LONG2CHARS( 1<<19 ), 0xffffffff ^ LONG2CHARS( 1<<18 ),
+ 0xffffffff ^ LONG2CHARS( 1<<17 ), 0xffffffff ^ LONG2CHARS( 1<<16),
+ 0xffffffff ^ LONG2CHARS( 1<<15 ), 0xffffffff ^ LONG2CHARS( 1<<14),
+ 0xffffffff ^ LONG2CHARS( 1<<13 ), 0xffffffff ^ LONG2CHARS( 1<<12 ),
+ 0xffffffff ^ LONG2CHARS( 1<<11 ), 0xffffffff ^ LONG2CHARS( 1<<10),
+ 0xffffffff ^ LONG2CHARS( 1<<9 ), 0xffffffff ^ LONG2CHARS( 1<<8),
+ 0xffffffff ^ LONG2CHARS( 1<<7 ), 0xffffffff ^ LONG2CHARS( 1<<6),
+ 0xffffffff ^ LONG2CHARS( 1<<5 ), 0xffffffff ^ LONG2CHARS( 1<<4),
+ 0xffffffff ^ LONG2CHARS( 1<<3 ), 0xffffffff ^ LONG2CHARS( 1<<2),
+ 0xffffffff ^ LONG2CHARS( 1<<1 ), 0xffffffff ^ LONG2CHARS( 1<<0)
+#endif /* PPW */
+ };
+#else /* LSBFirst */
+PixelType mask[] =
+ {
+ LONG2CHARS( 1<<0 ), LONG2CHARS( 1<<1 ), LONG2CHARS( 1<<2),
+ LONG2CHARS( 1<<3 ), LONG2CHARS( 1<<4 ), LONG2CHARS( 1<<5),
+ LONG2CHARS( 1<<6 ), LONG2CHARS( 1<<7 ), LONG2CHARS( 1<<8),
+ LONG2CHARS( 1<<9 ), LONG2CHARS( 1<<10 ), LONG2CHARS( 1<<11),
+ LONG2CHARS( 1<<12 ), LONG2CHARS( 1<<13 ), LONG2CHARS( 1<<14),
+ LONG2CHARS( 1<<15 ), LONG2CHARS( 1<<16 ), LONG2CHARS( 1<<17),
+ LONG2CHARS( 1<<18 ), LONG2CHARS( 1<<19 ), LONG2CHARS( 1<<20),
+ LONG2CHARS( 1<<21 ), LONG2CHARS( 1<<22 ), LONG2CHARS( 1<<23),
+ LONG2CHARS( 1<<24 ), LONG2CHARS( 1<<25 ), LONG2CHARS( 1<<26),
+ LONG2CHARS( 1<<27 ), LONG2CHARS( 1<<28 ), LONG2CHARS( 1<<29),
+ LONG2CHARS( 1<<30 ), LONG2CHARS( _1_<<31 )
+#if PPW == 64
+ ,
+ LONG2CHARS( 1L<<32),
+ LONG2CHARS( 1L<<33 ), LONG2CHARS( 1L<<34 ), LONG2CHARS( 1L<<35),
+ LONG2CHARS( 1L<<36 ), LONG2CHARS( 1L<<37 ), LONG2CHARS( 1L<<38),
+ LONG2CHARS( 1L<<39 ), LONG2CHARS( 1L<<40 ), LONG2CHARS( 1L<<41),
+ LONG2CHARS( 1L<<42 ), LONG2CHARS( 1L<<43 ), LONG2CHARS( 1L<<44),
+ LONG2CHARS( 1L<<45 ), LONG2CHARS( 1L<<46 ), LONG2CHARS( 1L<<47),
+ LONG2CHARS( 1L<<48 ), LONG2CHARS( 1L<<49 ), LONG2CHARS( 1L<<50),
+ LONG2CHARS( 1L<<51 ), LONG2CHARS( 1L<<52 ), LONG2CHARS( 1L<<53),
+ LONG2CHARS( 1L<<54 ), LONG2CHARS( 1L<<55 ), LONG2CHARS( 1L<<56),
+ LONG2CHARS( 1L<<57 ), LONG2CHARS( 1L<<58 ), LONG2CHARS( 1L<<59),
+ LONG2CHARS( 1L<<60 ), LONG2CHARS( 1L<<61 ),
+ LONG2CHARS( 1L<<62 ), LONG2CHARS( _1_<<63 ),
+#endif /* PPW */
+ };
+PixelType rmask[] =
+ {
+#if PPW == 32
+ 0xffffffff ^ LONG2CHARS( 1<<0), 0xffffffff ^ LONG2CHARS( 1<<1),
+ 0xffffffff ^ LONG2CHARS( 1<<2), 0xffffffff ^ LONG2CHARS( 1<<3),
+ 0xffffffff ^ LONG2CHARS( 1<<4), 0xffffffff ^ LONG2CHARS( 1<<5),
+ 0xffffffff ^ LONG2CHARS( 1<<6), 0xffffffff ^ LONG2CHARS( 1<<7),
+ 0xffffffff ^ LONG2CHARS( 1<<8), 0xffffffff ^ LONG2CHARS( 1<<9),
+ 0xffffffff ^ LONG2CHARS( 1<<10), 0xffffffff ^ LONG2CHARS( 1<<11),
+ 0xffffffff ^ LONG2CHARS( 1<<12), 0xffffffff ^ LONG2CHARS( 1<<13),
+ 0xffffffff ^ LONG2CHARS( 1<<14), 0xffffffff ^ LONG2CHARS( 1<<15),
+ 0xffffffff ^ LONG2CHARS( 1<<16), 0xffffffff ^ LONG2CHARS( 1<<17),
+ 0xffffffff ^ LONG2CHARS( 1<<18), 0xffffffff ^ LONG2CHARS( 1<<19),
+ 0xffffffff ^ LONG2CHARS( 1<<20), 0xffffffff ^ LONG2CHARS( 1<<21),
+ 0xffffffff ^ LONG2CHARS( 1<<22), 0xffffffff ^ LONG2CHARS( 1<<23),
+ 0xffffffff ^ LONG2CHARS( 1<<24), 0xffffffff ^ LONG2CHARS( 1<<25),
+ 0xffffffff ^ LONG2CHARS( 1<<26), 0xffffffff ^ LONG2CHARS( 1<<27),
+ 0xffffffff ^ LONG2CHARS( 1<<28), 0xffffffff ^ LONG2CHARS( 1<<29),
+ 0xffffffff ^ LONG2CHARS( 1<<30), 0xffffffff ^ LONG2CHARS( _1_<<31)
+#else /* PPW */
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<0),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<1),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<2),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<3),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<4),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<5),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<6),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<7),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<8),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<9),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<10),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<11),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<12),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<13),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<14),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<15),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<16),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<17),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<18),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<19),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<20),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<21),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<22),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<23),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<24),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<25),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<26),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<27),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<28),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<29),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<30),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<31),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<32),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<33),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<34),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<35),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<36),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<37),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<38),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<39),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<40),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<41),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<42),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<43),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<44),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<45),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<46),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<47),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<48),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<49),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<50),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<51),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<52),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<53),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<54),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<55),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<56),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<57),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<58),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<59),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<60),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<61),
+ 0xffffffffffffffff ^ LONG2CHARS( 1L<<62),
+ 0xffffffffffffffff ^ LONG2CHARS( _1_<<63),
+#endif /* PPW */
+ };
+#endif /* BITMAP_BIT_ORDER */
+
+#undef _1_
+
+/*
+ * Merge raster ops for full src + dest + plane mask
+ *
+ * More clever usage of boolean arithmetic to reduce the
+ * cost of complex raster ops. This is for bitblt and
+ * reduces all 16 raster ops + planemask to a single
+ * expression:
+ *
+ * dst = dst & (src & ca1 ^ cx1) ^ (src & ca2 ^ cx2)
+ *
+ * The array below contains the values for c?? for each
+ * raster op. Those values are further modified by
+ * planemasks on multi-plane displays as follows:
+ *
+ * ca1 &= pm;
+ * cx1 |= ~pm;
+ * ca2 &= pm;
+ * cx2 &= pm;
+ */
+
+#include "mergerop.h"
+
+#define O 0
+#define I ~((unsigned long)0)
+
+mergeRopRec mergeRopBits[16] = {
+{ O,O,O,O, }, /* clear 0x0 0 */
+{ I,O,O,O, }, /* and 0x1 src AND dst */
+{ I,O,I,O, }, /* andReverse 0x2 src AND NOT dst */
+{ O,O,I,O, }, /* copy 0x3 src */
+{ I,I,O,O, }, /* andInverted 0x4 NOT src AND dst */
+{ O,I,O,O, }, /* noop 0x5 dst */
+{ O,I,I,O, }, /* xor 0x6 src XOR dst */
+{ I,I,I,O, }, /* or 0x7 src OR dst */
+{ I,I,I,I, }, /* nor 0x8 NOT src AND NOT dst */
+{ O,I,I,I, }, /* equiv 0x9 NOT src XOR dst */
+{ O,I,O,I, }, /* invert 0xa NOT dst */
+{ I,I,O,I, }, /* orReverse 0xb src OR NOT dst */
+{ O,O,I,I, }, /* copyInverted 0xc NOT src */
+{ I,O,I,I, }, /* orInverted 0xd NOT src OR dst */
+{ I,O,O,I, }, /* nand 0xe NOT src OR NOT dst */
+{ O,O,O,I, }, /* set 0xf 1 */
+};
+
+#undef O
+#undef I
diff --git a/xc/programs/Xserver/mfb/maskbits.h b/xc/programs/Xserver/mfb/maskbits.h
new file mode 100644
index 000000000..2e0800d53
--- /dev/null
+++ b/xc/programs/Xserver/mfb/maskbits.h
@@ -0,0 +1,745 @@
+/* Combined Purdue/PurduePlus patches, level 2.1, 1/24/89 */
+/***********************************************************
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XConsortium: maskbits.h,v 1.33 94/04/17 20:28:13 dpw Exp $ */
+/* $XFree86: xc/programs/Xserver/mfb/maskbits.h,v 3.5 1997/03/18 10:06:22 hohndel Exp $ */
+#include "X.h"
+#include "Xmd.h"
+#include "servermd.h"
+
+
+/* the following notes use the following conventions:
+SCREEN LEFT SCREEN RIGHT
+in this file and maskbits.c, left and right refer to screen coordinates,
+NOT bit numbering in registers.
+
+starttab[n]
+ bits[0,n-1] = 0 bits[n,PLST] = 1
+endtab[n] =
+ bits[0,n-1] = 1 bits[n,PLST] = 0
+
+startpartial[], endpartial[]
+ these are used as accelerators for doing putbits and masking out
+bits that are all contained between longword boudaries. the extra
+256 bytes of data seems a small price to pay -- code is smaller,
+and narrow things (e.g. window borders) go faster.
+
+the names may seem misleading; they are derived not from which end
+of the word the bits are turned on, but at which end of a scanline
+the table tends to be used.
+
+look at the tables and macros to understand boundary conditions.
+(careful readers will note that starttab[n] = ~endtab[n] for n != 0)
+
+-----------------------------------------------------------------------
+these two macros depend on the screen's bit ordering.
+in both of them x is a screen position. they are used to
+combine bits collected from multiple longwords into a
+single destination longword, and to unpack a single
+source longword into multiple destinations.
+
+SCRLEFT(dst, x)
+ takes dst[x, PPW] and moves them to dst[0, PPW-x]
+ the contents of the rest of dst are 0.
+ this is a right shift on LSBFirst (forward-thinking)
+ machines like the VAX, and left shift on MSBFirst
+ (backwards) machines like the 680x0 and pc/rt.
+
+SCRRIGHT(dst, x)
+ takes dst[0,x] and moves them to dst[PPW-x, PPW]
+ the contents of the rest of dst are 0.
+ this is a left shift on LSBFirst, right shift
+ on MSBFirst.
+
+
+the remaining macros are cpu-independent; all bit order dependencies
+are built into the tables and the two macros above.
+
+maskbits(x, w, startmask, endmask, nlw)
+ for a span of width w starting at position x, returns
+a mask for ragged bits at start, mask for ragged bits at end,
+and the number of whole longwords between the ends.
+
+maskpartialbits(x, w, mask)
+ works like maskbits(), except all the bits are in the
+ same longword (i.e. (x&PIM + w) <= PPW)
+
+maskPPWbits(x, w, startmask, endmask, nlw)
+ as maskbits, but does not calculate nlw. it is used by
+ mfbGlyphBlt to put down glyphs <= PPW bits wide.
+
+-------------------------------------------------------------------
+
+NOTE
+ any pointers passed to the following 4 macros are
+ guranteed to be PPW-bit aligned.
+ The only non-PPW-bit-aligned references ever made are
+ to font glyphs, and those are made with getleftbits()
+ and getshiftedleftbits (qq.v.)
+
+ For 64-bit server, it is assumed that we will never have font padding
+ of more than 4 bytes. The code uses int's to access the fonts
+ intead of longs.
+
+getbits(psrc, x, w, dst)
+ starting at position x in psrc (x < PPW), collect w
+ bits and put them in the screen left portion of dst.
+ psrc is a longword pointer. this may span longword boundaries.
+ it special-cases fetching all w bits from one longword.
+
+ +--------+--------+ +--------+
+ | | m |n| | ==> | m |n| |
+ +--------+--------+ +--------+
+ x x+w 0 w
+ psrc psrc+1 dst
+ m = PPW - x
+ n = w - m
+
+ implementation:
+ get m bits, move to screen-left of dst, zeroing rest of dst;
+ get n bits from next word, move screen-right by m, zeroing
+ lower m bits of word.
+ OR the two things together.
+
+putbits(src, x, w, pdst)
+ starting at position x in pdst, put down the screen-leftmost
+ w bits of src. pdst is a longword pointer. this may
+ span longword boundaries.
+ it special-cases putting all w bits into the same longword.
+
+ +--------+ +--------+--------+
+ | m |n| | ==> | | m |n| |
+ +--------+ +--------+--------+
+ 0 w x x+w
+ dst pdst pdst+1
+ m = PPW - x
+ n = w - m
+
+ implementation:
+ get m bits, shift screen-right by x, zero screen-leftmost x
+ bits; zero rightmost m bits of *pdst and OR in stuff
+ from before the semicolon.
+ shift src screen-left by m, zero bits n-PPW;
+ zero leftmost n bits of *(pdst+1) and OR in the
+ stuff from before the semicolon.
+
+putbitsrop(src, x, w, pdst, ROP)
+ like putbits but calls DoRop with the rasterop ROP (see mfb.h for
+ DoRop)
+
+putbitsrrop(src, x, w, pdst, ROP)
+ like putbits but calls DoRRop with the reduced rasterop ROP
+ (see mfb.h for DoRRop)
+
+-----------------------------------------------------------------------
+ The two macros below are used only for getting bits from glyphs
+in fonts, and glyphs in fonts are gotten only with the following two
+mcros.
+ You should tune these macros toyour font format and cpu
+byte ordering.
+
+NOTE
+getleftbits(psrc, w, dst)
+ get the leftmost w (w<=32) bits from *psrc and put them
+ in dst. this is used by the mfbGlyphBlt code for glyphs
+ <=PPW bits wide.
+ psrc is declared (unsigned char *)
+
+ psrc is NOT guaranteed to be PPW-bit aligned. on many
+ machines this will cause problems, so there are several
+ versions of this macro.
+
+ this macro is called ONLY for getting bits from font glyphs,
+ and depends on the server-natural font padding.
+
+ for blazing text performance, you want this macro
+ to touch memory as infrequently as possible (e.g.
+ fetch longwords) and as efficiently as possible
+ (e.g. don't fetch misaligned longwords)
+
+getshiftedleftbits(psrc, offset, w, dst)
+ used by the font code; like getleftbits, but shifts the
+ bits SCRLEFT by offset.
+ this is implemented portably, calling getleftbits()
+ and SCRLEFT().
+ psrc is declared (unsigned char *).
+*/
+
+/* to match CFB and allow algorithm sharing ...
+ * name mfb32 mfb64 explanation
+ * ---- ------ ----- -----------
+ * PGSZ 32 64 pixel group size (in bits; same as PPW for mfb)
+ * PGSZB 4 8 pixel group size (in bytes)
+ * PPW 32 64 pixels per word (pixels per pixel group)
+ * PLST 31 63 index of last pixel in a word (should be PPW-1)
+ * PIM 0x1f 0x3f pixel index mask (index within a pixel group)
+ * PWSH 5 6 pixel-to-word shift (should be log2(PPW))
+ *
+ * The MFB_ versions are here so that cfb can include maskbits.h to get
+ * the bitmap constants without conflicting with its own P* constants.
+ */
+
+/* warning: PixelType definition duplicated in mfb.h */
+#ifndef PixelType
+#define PixelType unsigned long
+#endif /* PixelType */
+
+#ifdef LONG64
+#define MFB_PGSZB 8
+#else
+#define MFB_PGSZB 4
+#endif /* LONG64 */
+#define MFB_PPW (MFB_PGSZB<<3) /* assuming 8 bits per byte */
+#define MFB_PGSZ MFB_PPW
+#define MFB_PLST (MFB_PPW-1)
+#define MFB_PIM MFB_PLST
+
+/* set PWSH = log2(PPW) using brute force */
+
+#if MFB_PPW == 32
+#define MFB_PWSH 5
+#else
+#if MFB_PPW == 64
+#define MFB_PWSH 6
+#endif /* MFB_PPW == 64 */
+#endif /* MFB_PPW == 32 */
+
+extern PixelType starttab[];
+extern PixelType endtab[];
+extern PixelType partmasks[MFB_PPW][MFB_PPW];
+extern PixelType rmask[];
+extern PixelType mask[];
+
+#ifndef MFB_CONSTS_ONLY
+
+#define PGSZB MFB_PGSZB
+#define PPW MFB_PPW
+#define PGSZ MFB_PGSZ
+#define PLST MFB_PLST
+#define PIM MFB_PIM
+#define PWSH MFB_PWSH
+
+#define BitLeft(b,s) SCRLEFT(b,s)
+#define BitRight(b,s) SCRRIGHT(b,s)
+
+#ifdef XFree86Server
+#define LONG2CHARSSAMEORDER(x) ((unsigned long)(x))
+#if PPW == 32
+#define LONG2CHARSDIFFORDER( x ) ( ( ( ( x ) & (unsigned long)0x000000FF ) << 0x18 ) \
+ | ( ( ( x ) & (unsigned long)0x0000FF00 ) << 0x08 ) \
+ | ( ( ( x ) & (unsigned long)0x00FF0000 ) >> 0x08 ) \
+ | ( ( ( x ) & (unsigned long)0xFF000000 ) >> 0x18 ) )
+#else /* PPW == 64 */
+#if defined( __alpha__)
+#define LONG2CHARSDIFFORDER( x ) \
+ ( ( ( ( x ) & 0x000000FFUL) << 0x38 ) \
+ | ( ( ( x ) & 0x0000FF00UL) << 0x28 ) \
+ | ( ( ( x ) & 0x00FF0000UL) << 0x18 ) \
+ | ( ( ( x ) & 0xFF000000UL) << 0x08 ) \
+ | ( ( ( x ) & 0x000000FF00000000UL) >> 0x08 ) \
+ | ( ( ( x ) & 0x0000FF0000000000UL) >> 0x18 ) \
+ | ( ( ( x ) & 0x00FF000000000000UL) >> 0x28 ) \
+ | ( ( ( x ) & 0xFF00000000000000UL) >> 0x38 ) )
+#else /* __alpha__ */
+#define LONG2CHARSDIFFORDER( x ) ( ( ( ( x ) & 0x000000FF000000FFUL) << 0x18 ) \
+ | ( ( ( x ) & 0x0000FF000000FF00UL) << 0x08 ) \
+ | ( ( ( x ) & 0x00FF000000FF0000UL) >> 0x08 ) \
+ | ( ( ( x ) & 0xFF000000FF000000UL) >> 0x18 ) )
+#endif /* __alpha__ */
+#endif /* PPW */
+#endif /* XFree86Server */
+#if (BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER)
+#define LONG2CHARS(x) ((unsigned long)(x))
+#else
+/*
+ * the unsigned case below is for compilers like
+ * the Danbury C and i386cc
+ */
+#if PPW == 32
+#define LONG2CHARS( x ) ( ( ( ( x ) & (unsigned long)0x000000FF ) << 0x18 ) \
+ | ( ( ( x ) & (unsigned long)0x0000FF00 ) << 0x08 ) \
+ | ( ( ( x ) & (unsigned long)0x00FF0000 ) >> 0x08 ) \
+ | ( ( ( x ) & (unsigned long)0xFF000000 ) >> 0x18 ) )
+#else /* PPW == 64 */
+#if defined( __alpha__)
+#define LONG2CHARS( x ) \
+ ( ( ( ( x ) & 0x000000FFUL) << 0x38 ) \
+ | ( ( ( x ) & 0x0000FF00UL) << 0x28 ) \
+ | ( ( ( x ) & 0x00FF0000UL) << 0x18 ) \
+ | ( ( ( x ) & 0xFF000000UL) << 0x08 ) \
+ | ( ( ( x ) & 0x000000FF00000000UL) >> 0x08 ) \
+ | ( ( ( x ) & 0x0000FF0000000000UL) >> 0x18 ) \
+ | ( ( ( x ) & 0x00FF000000000000UL) >> 0x28 ) \
+ | ( ( ( x ) & 0xFF00000000000000UL) >> 0x38 ) )
+#else /* __alpha__ */
+#define LONG2CHARS( x ) ( ( ( ( x ) & 0x000000FF000000FFUL) << 0x18 ) \
+ | ( ( ( x ) & 0x0000FF000000FF00UL) << 0x08 ) \
+ | ( ( ( x ) & 0x00FF000000FF0000UL) >> 0x08 ) \
+ | ( ( ( x ) & 0xFF000000FF000000UL) >> 0x18 ) )
+#endif /* __alpha__ */
+#endif /* PPW */
+#endif /* BITMAP_BIT_ORDER */
+
+#ifdef STRICT_ANSI_SHIFT
+#define SHL(x,y) ((y) >= PPW ? 0 : LONG2CHARS(LONG2CHARS(x) << (y)))
+#define SHR(x,y) ((y) >= PPW ? 0 : LONG2CHARS(LONG2CHARS(x) >> (y)))
+#else
+#define SHL(x,y) LONG2CHARS(LONG2CHARS(x) << (y))
+#define SHR(x,y) LONG2CHARS(LONG2CHARS(x) >> (y))
+#endif
+
+#if (BITMAP_BIT_ORDER == MSBFirst) /* pc/rt, 680x0 */
+#define SCRLEFT(lw, n) SHL((PixelType)(lw),(n))
+#define SCRRIGHT(lw, n) SHR((PixelType)(lw),(n))
+#else /* vax, intel */
+#define SCRLEFT(lw, n) SHR((PixelType)(lw),(n))
+#define SCRRIGHT(lw, n) SHL((PixelType)(lw),(n))
+#endif
+
+#define DoRRop(alu, src, dst) \
+(((alu) == RROP_BLACK) ? ((dst) & ~(src)) : \
+ ((alu) == RROP_WHITE) ? ((dst) | (src)) : \
+ ((alu) == RROP_INVERT) ? ((dst) ^ (src)) : \
+ (dst))
+
+#if PPW == 32
+/* A generalized form of a x4 Duff's Device */
+#define Duff(counter, block) { \
+ while (counter >= 4) {\
+ { block; } \
+ { block; } \
+ { block; } \
+ { block; } \
+ counter -= 4; \
+ } \
+ switch (counter & 3) { \
+ case 3: { block; } \
+ case 2: { block; } \
+ case 1: { block; } \
+ case 0: \
+ counter = 0; \
+ } \
+}
+#else /* PPW == 64 */
+/* A generalized form of a x8 Duff's Device */
+#define Duff(counter, block) { \
+ while (counter >= 8) {\
+ { block; } \
+ { block; } \
+ { block; } \
+ { block; } \
+ { block; } \
+ { block; } \
+ { block; } \
+ { block; } \
+ counter -= 8; \
+ } \
+ switch (counter & 7) { \
+ case 7: { block; } \
+ case 6: { block; } \
+ case 5: { block; } \
+ case 4: { block; } \
+ case 3: { block; } \
+ case 2: { block; } \
+ case 1: { block; } \
+ case 0: \
+ counter = 0; \
+ } \
+}
+#endif /* PPW */
+
+
+#define maskbits(x, w, startmask, endmask, nlw) \
+ startmask = starttab[(x) & PIM]; \
+ endmask = endtab[((x)+(w)) & PIM]; \
+ if (startmask) \
+ nlw = (((w) - (PPW - ((x) & PIM))) >> PWSH); \
+ else \
+ nlw = (w) >> PWSH;
+
+#define maskpartialbits(x, w, mask) \
+ mask = partmasks[(x) & PIM][(w) & PIM];
+
+#define maskPPWbits(x, w, startmask, endmask) \
+ startmask = starttab[(x) & PIM]; \
+ endmask = endtab[((x)+(w)) & PIM];
+
+#ifdef __GNUC__ /* XXX don't want for Alpha? */
+#ifdef vax
+#define FASTGETBITS(psrc,x,w,dst) \
+ __asm ("extzv %1,%2,%3,%0" \
+ : "=g" (dst) \
+ : "g" (x), "g" (w), "m" (*(char *)(psrc)))
+#define getbits(psrc,x,w,dst) FASTGETBITS(psrc,x,w,dst)
+
+#define FASTPUTBITS(src, x, w, pdst) \
+ __asm ("insv %3,%1,%2,%0" \
+ : "=m" (*(char *)(pdst)) \
+ : "g" (x), "g" (w), "g" (src))
+#define putbits(src, x, w, pdst) FASTPUTBITS(src, x, w, pdst)
+#endif /* vax */
+#ifdef mc68020
+#define FASTGETBITS(psrc, x, w, dst) \
+ __asm ("bfextu %3{%1:%2},%0" \
+ : "=d" (dst) : "di" (x), "di" (w), "o" (*(char *)(psrc)))
+
+#define getbits(psrc,x,w,dst) \
+{ \
+ FASTGETBITS(psrc, x, w, dst);\
+ dst = SHL(dst,(32-(w))); \
+}
+
+#define FASTPUTBITS(src, x, w, pdst) \
+ __asm ("bfins %3,%0{%1:%2}" \
+ : "=o" (*(char *)(pdst)) \
+ : "di" (x), "di" (w), "d" (src), "0" (*(char *) (pdst)))
+
+#define putbits(src, x, w, pdst) FASTPUTBITS(SHR((src),32-(w)), x, w, pdst)
+
+#endif /* mc68020 */
+#endif /* __GNUC__ */
+
+/* The following flag is used to override a bugfix for sun 3/60+CG4 machines,
+ */
+
+/* We don't need to be careful about this unless we're dealing with sun3's
+ * We will default its usage for those who do not know anything, but will
+ * override its effect if the machine doesn't look like a sun3
+ */
+#if !defined(mc68020) || !defined(sun)
+#define NO_3_60_CG4
+#endif
+
+/* This is gross. We want to #define u_putbits as something which can be used
+ * in the case of the 3/60+CG4, but if we use /bin/cc or are on another
+ * machine type, we want nothing to do with u_putbits. What a hastle. Here
+ * I used slo_putbits as something which either u_putbits or putbits could be
+ * defined as.
+ *
+ * putbits gets it iff it is not already defined with FASTPUTBITS above.
+ * u_putbits gets it if we have FASTPUTBITS (putbits) from above and have not
+ * overridden the NO_3_60_CG4 flag.
+ */
+
+#define slo_putbits(src, x, w, pdst) \
+{ \
+ register int n = (x)+(w)-PPW; \
+ \
+ if (n <= 0) \
+ { \
+ register PixelType tmpmask; \
+ maskpartialbits((x), (w), tmpmask); \
+ *(pdst) = (*(pdst) & ~tmpmask) | \
+ (SCRRIGHT(src, x) & tmpmask); \
+ } \
+ else \
+ { \
+ *(pdst) = (*(pdst) & endtab[x]) | (SCRRIGHT((src), x)); \
+ (pdst)[1] = ((pdst)[1] & starttab[n]) | \
+ (SCRLEFT(src, PPW-(x)) & endtab[n]); \
+ } \
+}
+
+#if defined(putbits) && !defined(NO_3_60_CG4)
+#define u_putbits(src, x, w, pdst) slo_putbits(src, x, w, pdst)
+#else
+#define u_putbits(src, x, w, pdst) putbits(src, x, w, pdst)
+#endif
+
+#if !defined(putbits)
+#define putbits(src, x, w, pdst) slo_putbits(src, x, w, pdst)
+#endif
+
+/* Now if we have not gotten any really good bitfield macros, try some
+ * moderately fast macros. Alas, I don't know how to do asm instructions
+ * without gcc.
+ */
+
+#ifndef getbits
+#define getbits(psrc, x, w, dst) \
+{ \
+ dst = SCRLEFT(*(psrc), (x)); \
+ if ( ((x) + (w)) > PPW) \
+ dst |= (SCRRIGHT(*((psrc)+1), PPW-(x))); \
+}
+#endif
+
+/* We have to special-case putbitsrop because of 3/60+CG4 combos
+ */
+
+#define u_putbitsrop(src, x, w, pdst, rop) \
+{\
+ register PixelType t1, t2; \
+ register int n = (x)+(w)-PPW; \
+ \
+ t1 = SCRRIGHT((src), (x)); \
+ DoRop(t2, rop, t1, *(pdst)); \
+ \
+ if (n <= 0) \
+ { \
+ register PixelType tmpmask; \
+ \
+ maskpartialbits((x), (w), tmpmask); \
+ *(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \
+ } \
+ else \
+ { \
+ int m = PPW-(x); \
+ *(pdst) = (*(pdst) & endtab[x]) | (t2 & starttab[x]); \
+ t1 = SCRLEFT((src), m); \
+ DoRop(t2, rop, t1, (pdst)[1]); \
+ (pdst)[1] = ((pdst)[1] & starttab[n]) | (t2 & endtab[n]); \
+ } \
+}
+
+/* If our getbits and putbits are FAST enough,
+ * do this brute force, it's faster
+ */
+
+#if defined(FASTPUTBITS) && defined(FASTGETBITS) && defined(NO_3_60_CG4)
+#if (BITMAP_BIT_ORDER == MSBFirst)
+#define putbitsrop(src, x, w, pdst, rop) \
+{ \
+ register PixelType _tmp, _tmp2; \
+ FASTGETBITS(pdst, x, w, _tmp); \
+ _tmp2 = SCRRIGHT(src, PPW-(w)); \
+ DoRop(_tmp, rop, _tmp2, _tmp) \
+ FASTPUTBITS(_tmp, x, w, pdst); \
+}
+#define putbitsrrop(src, x, w, pdst, rop) \
+{ \
+ register PixelType _tmp, _tmp2; \
+ \
+ FASTGETBITS(pdst, x, w, _tmp); \
+ _tmp2 = SCRRIGHT(src, PPW-(w)); \
+ _tmp= DoRRop(rop, _tmp2, _tmp); \
+ FASTPUTBITS(_tmp, x, w, pdst); \
+}
+#undef u_putbitsrop
+#else
+#define putbitsrop(src, x, w, pdst, rop) \
+{ \
+ register PixelType _tmp; \
+ FASTGETBITS(pdst, x, w, _tmp); \
+ DoRop(_tmp, rop, src, _tmp) \
+ FASTPUTBITS(_tmp, x, w, pdst); \
+}
+#define putbitsrrop(src, x, w, pdst, rop) \
+{ \
+ register PixelType _tmp; \
+ \
+ FASTGETBITS(pdst, x, w, _tmp); \
+ _tmp= DoRRop(rop, src, _tmp); \
+ FASTPUTBITS(_tmp, x, w, pdst); \
+}
+#undef u_putbitsrop
+#endif
+#endif
+
+#ifndef putbitsrop
+#define putbitsrop(src, x, w, pdst, rop) u_putbitsrop(src, x, w, pdst, rop)
+#endif
+
+#ifndef putbitsrrop
+#define putbitsrrop(src, x, w, pdst, rop) \
+{\
+ register PixelType t1, t2; \
+ register int n = (x)+(w)-PPW; \
+ \
+ t1 = SCRRIGHT((src), (x)); \
+ t2 = DoRRop(rop, t1, *(pdst)); \
+ \
+ if (n <= 0) \
+ { \
+ register PixelType tmpmask; \
+ \
+ maskpartialbits((x), (w), tmpmask); \
+ *(pdst) = (*(pdst) & ~tmpmask) | (t2 & tmpmask); \
+ } \
+ else \
+ { \
+ int m = PPW-(x); \
+ *(pdst) = (*(pdst) & endtab[x]) | (t2 & starttab[x]); \
+ t1 = SCRLEFT((src), m); \
+ t2 = DoRRop(rop, t1, (pdst)[1]); \
+ (pdst)[1] = ((pdst)[1] & starttab[n]) | (t2 & endtab[n]); \
+ } \
+}
+#endif
+
+#if GETLEFTBITS_ALIGNMENT == 1
+#define getleftbits(psrc, w, dst) dst = *((CARD32 *) psrc)
+#endif /* GETLEFTBITS_ALIGNMENT == 1 */
+
+#if GETLEFTBITS_ALIGNMENT == 2
+#define getleftbits(psrc, w, dst) \
+ { \
+ if ( ((int)(psrc)) & 0x01 ) \
+ getbits( ((CARD32 *)(((char *)(psrc))-1)), 8, (w), (dst) ); \
+ else \
+ getbits(psrc, 0, w, dst); \
+ }
+#endif /* GETLEFTBITS_ALIGNMENT == 2 */
+
+#if GETLEFTBITS_ALIGNMENT == 4
+#define getleftbits(psrc, w, dst) \
+ { \
+ int off, off_b; \
+ off_b = (off = ( ((int)(psrc)) & 0x03)) << 3; \
+ getbits( \
+ (CARD32 *)( ((char *)(psrc)) - off), \
+ (off_b), (w), (dst) \
+ ); \
+ }
+#endif /* GETLEFTBITS_ALIGNMENT == 4 */
+
+
+#define getshiftedleftbits(psrc, offset, w, dst) \
+ getleftbits((psrc), (w), (dst)); \
+ dst = SCRLEFT((dst), (offset));
+
+/* FASTGETBITS and FASTPUTBITS are not necessarily correct implementations of
+ * getbits and putbits, but they work if used together.
+ *
+ * On a MSBFirst machine, a cpu bitfield extract instruction (like bfextu)
+ * could normally assign its result to a long word register in the screen
+ * right position. This saves canceling register shifts by not fighting the
+ * natural cpu byte order.
+ *
+ * Unfortunately, these fail on a 3/60+CG4 and cannot be used unmodified. Sigh.
+ */
+#if defined(FASTGETBITS) && defined(FASTPUTBITS)
+#ifdef NO_3_60_CG4
+#define u_FASTPUT(aa, bb, cc, dd) FASTPUTBITS(aa, bb, cc, dd)
+#else
+#define u_FASTPUT(aa, bb, cc, dd) u_putbits(SCRLEFT(aa, PPW-(cc)), bb, cc, dd)
+#endif
+
+#define getandputbits(psrc, srcbit, dstbit, width, pdst) \
+{ \
+ register PixelType _tmpbits; \
+ FASTGETBITS(psrc, srcbit, width, _tmpbits); \
+ u_FASTPUT(_tmpbits, dstbit, width, pdst); \
+}
+
+#define getandputrop(psrc, srcbit, dstbit, width, pdst, rop) \
+{ \
+ register PixelType _tmpsrc, _tmpdst; \
+ FASTGETBITS(pdst, dstbit, width, _tmpdst); \
+ FASTGETBITS(psrc, srcbit, width, _tmpsrc); \
+ DoRop(_tmpdst, rop, _tmpsrc, _tmpdst); \
+ u_FASTPUT(_tmpdst, dstbit, width, pdst); \
+}
+
+#define getandputrrop(psrc, srcbit, dstbit, width, pdst, rop) \
+{ \
+ register PixelType _tmpsrc, _tmpdst; \
+ FASTGETBITS(pdst, dstbit, width, _tmpdst); \
+ FASTGETBITS(psrc, srcbit, width, _tmpsrc); \
+ _tmpdst = DoRRop(rop, _tmpsrc, _tmpdst); \
+ u_FASTPUT(_tmpdst, dstbit, width, pdst); \
+}
+
+#define getandputbits0(psrc, srcbit, width, pdst) \
+ getandputbits(psrc, srcbit, 0, width, pdst)
+
+#define getandputrop0(psrc, srcbit, width, pdst, rop) \
+ getandputrop(psrc, srcbit, 0, width, pdst, rop)
+
+#define getandputrrop0(psrc, srcbit, width, pdst, rop) \
+ getandputrrop(psrc, srcbit, 0, width, pdst, rop)
+
+
+#else /* Slow poke */
+
+/* pairs of getbits/putbits happen frequently. Some of the code can
+ * be shared or avoided in a few specific instances. It gets us a
+ * small advantage, so we do it. The getandput...0 macros are the only ones
+ * which speed things here. The others are here for compatibility w/the above
+ * FAST ones
+ */
+
+#define getandputbits(psrc, srcbit, dstbit, width, pdst) \
+{ \
+ register PixelType _tmpbits; \
+ getbits(psrc, srcbit, width, _tmpbits); \
+ putbits(_tmpbits, dstbit, width, pdst); \
+}
+
+#define getandputrop(psrc, srcbit, dstbit, width, pdst, rop) \
+{ \
+ register PixelType _tmpbits; \
+ getbits(psrc, srcbit, width, _tmpbits) \
+ putbitsrop(_tmpbits, dstbit, width, pdst, rop) \
+}
+
+#define getandputrrop(psrc, srcbit, dstbit, width, pdst, rop) \
+{ \
+ register PixelType _tmpbits; \
+ getbits(psrc, srcbit, width, _tmpbits) \
+ putbitsrrop(_tmpbits, dstbit, width, pdst, rop) \
+}
+
+
+#define getandputbits0(psrc, sbindex, width, pdst) \
+{ /* unroll the whole damn thing to see how it * behaves */ \
+ register int _flag = PPW - (sbindex); \
+ register PixelType _src; \
+ \
+ _src = SCRLEFT (*(psrc), (sbindex)); \
+ if ((width) > _flag) \
+ _src |= SCRRIGHT (*((psrc) + 1), _flag); \
+ \
+ *(pdst) = (*(pdst) & starttab[(width)]) | (_src & endtab[(width)]); \
+}
+
+
+#define getandputrop0(psrc, sbindex, width, pdst, rop) \
+{ \
+ register int _flag = PPW - (sbindex); \
+ register PixelType _src; \
+ \
+ _src = SCRLEFT (*(psrc), (sbindex)); \
+ if ((width) > _flag) \
+ _src |= SCRRIGHT (*((psrc) + 1), _flag); \
+ DoRop(_src, rop, _src, *(pdst)); \
+ \
+ *(pdst) = (*(pdst) & starttab[(width)]) | (_src & endtab[(width)]); \
+}
+
+#define getandputrrop0(psrc, sbindex, width, pdst, rop) \
+{ \
+ int _flag = PPW - (sbindex); \
+ register PixelType _src; \
+ \
+ _src = SCRLEFT (*(psrc), (sbindex)); \
+ if ((width) > _flag) \
+ _src |= SCRRIGHT (*((psrc) + 1), _flag); \
+ _src = DoRRop(rop, _src, *(pdst)); \
+ \
+ *(pdst) = (*(pdst) & starttab[(width)]) | (_src & endtab[(width)]); \
+}
+
+#endif /* FASTGETBITS && FASTPUTBITS */
+
+#endif /* MFB_CONSTS_ONLY */
diff --git a/xc/programs/Xserver/mfb/mergerop.h b/xc/programs/Xserver/mfb/mergerop.h
new file mode 100644
index 000000000..1ba93338e
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mergerop.h
@@ -0,0 +1,411 @@
+/*
+ * $TOG: mergerop.h /main/12 1998/02/09 14:38:03 kaleb $
+ *
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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
+ */
+/* $XFree86: xc/programs/Xserver/mfb/mergerop.h,v 3.7 1999/04/11 13:11:12 dawes Exp $ */
+
+#ifndef _MERGEROP_H_
+#define _MERGEROP_H_
+
+#ifndef GXcopy
+#include "X.h"
+#endif
+
+typedef struct _mergeRopBits {
+ unsigned long ca1, cx1, ca2, cx2;
+} mergeRopRec, *mergeRopPtr;
+
+extern mergeRopRec mergeRopBits[16];
+
+#if PPW != PGSZ /* cfb */
+#define DeclareMergeRop() unsigned long _ca1, _cx1, _ca2, _cx2;
+#define DeclarePrebuiltMergeRop() unsigned long _cca, _ccx;
+#if PSZ == 24 /* both for PGSZ == 32 and 64 */
+#define DeclareMergeRop24() \
+ unsigned long _ca1u[4], _cx1u[4], _ca2u[4], _cx2u[4];
+ /* int _unrollidx[3]={0,0,1,2};*/
+#define DeclarePrebuiltMergeRop24() unsigned long _ccau[4], _ccxu[4];
+#endif /* PSZ == 24 */
+#else /* mfb */
+#define DeclareMergeRop() unsigned long _ca1, _cx1, _ca2, _cx2;
+#define DeclarePrebuiltMergeRop() unsigned long _cca, _ccx;
+#endif
+
+#if PPW != PGSZ /* cfb */
+#define InitializeMergeRop(alu,pm) {\
+ unsigned long _pm; \
+ mergeRopPtr _bits; \
+ _pm = PFILL(pm); \
+ _bits = &mergeRopBits[alu]; \
+ _ca1 = _bits->ca1 & _pm; \
+ _cx1 = _bits->cx1 | ~_pm; \
+ _ca2 = _bits->ca2 & _pm; \
+ _cx2 = _bits->cx2 & _pm; \
+}
+#if PSZ == 24
+#if PGSZ == 64
+#define InitializeMergeRop24(alu,pm) {\
+ register int i; \
+ register unsigned long _pm = (pm) & 0xFFFFFF; \
+ mergeRopPtr _bits = &mergeRopBits[alu]; \
+ unsigned long _bits_ca1 = _bits->ca1; \
+ unsigned long _bits_cx1 = _bits->cx1; \
+ unsigned long _bits_ca2 = _bits->ca2; \
+ unsigned long _bits_cx2 = _bits->cx2; \
+ _pm = (_pm << 40)|(_pm << 16) |(_pm >> 8); \
+ for(i = 0; i < 4; i++){ \
+ _ca1u[i] = _bits_ca1 & _pm; \
+ _cx1u[i] = _bits_cx1 | ~_pm; \
+ _ca2u[i] = _bits_ca2 & _pm; \
+ _cx2u[i] = _bits_cx2 & _pm; \
+ _pm = (_pm << 16)|(_pm >> 8); \
+ } \
+}
+#else /* PGSZ != 64 */
+#if (BITMAP_BIT_ORDER == MSBFirst)
+#define InitializeMergeRop24(alu,pm) {\
+ register int i; \
+ register unsigned long _pm = (pm) & 0xFFFFFF; \
+ mergeRopPtr _bits = &mergeRopBits[alu]; \
+ unsigned long _bits_ca1 = _bits->ca1; \
+ unsigned long _bits_cx1 = _bits->cx1; \
+ unsigned long _bits_ca2 = _bits->ca2; \
+ unsigned long _bits_cx2 = _bits->cx2; \
+ _pm = (_pm << 8) | (_pm >> 16); \
+ for(i = 0; i < 4; i++){ \
+ _ca1u[i] = _bits_ca1 & _pm; \
+ _cx1u[i] = _bits_cx1 | ~_pm; \
+ _ca2u[i] = _bits_ca2 & _pm; \
+ _cx2u[i] = _bits_cx2 & _pm; \
+ _pm = (_pm << 16)|(_pm >> 8); \
+ } \
+}
+#else /*(BITMAP_BIT_ORDER == LSBFirst)*/
+#define InitializeMergeRop24(alu,pm) {\
+ register int i; \
+ register unsigned long _pm = (pm) & cfbmask[0]; \
+ mergeRopPtr _bits = &mergeRopBits[alu]; \
+ unsigned long _bits_ca1 = _bits->ca1 & cfbmask[0]; \
+ unsigned long _bits_cx1 = _bits->cx1 & cfbmask[0]; \
+ unsigned long _bits_ca2 = _bits->ca2 & cfbmask[0]; \
+ unsigned long _bits_cx2 = _bits->cx2 & cfbmask[0]; \
+ _pm |= (_pm << 24); \
+ _bits_ca1 |= (_bits->ca1 << 24); \
+ _bits_cx1 |= (_bits->cx1 << 24); \
+ _bits_ca2 |= (_bits->ca2 << 24); \
+ _bits_cx2 |= (_bits->cx2 << 24); \
+ for(i = 0; i < 4; i++){ \
+ _ca1u[i] = _bits_ca1 & _pm; \
+ _cx1u[i] = _bits_cx1 | ~_pm; \
+ _ca2u[i] = _bits_ca2 & _pm; \
+ _cx2u[i] = _bits_cx2 & _pm; \
+ _pm = (_pm << 16)|(_pm >> 8); \
+ } \
+}
+#endif /*(BITMAP_BIT_ORDER == MSBFirst)*/
+#endif /*PGSZ == 64 */
+#endif /* PSZ == 24 */
+#else /* mfb */
+#define InitializeMergeRop(alu,pm) {\
+ mergeRopPtr _bits; \
+ _bits = &mergeRopBits[alu]; \
+ _ca1 = _bits->ca1; \
+ _cx1 = _bits->cx1; \
+ _ca2 = _bits->ca2; \
+ _cx2 = _bits->cx2; \
+}
+#endif
+
+/* AND has higher precedence than XOR */
+
+#define DoMergeRop(src, dst) \
+ (((dst) & (((src) & _ca1) ^ _cx1)) ^ (((src) & _ca2) ^ _cx2))
+
+#define DoMergeRop24u(src, dst, i) \
+((dst) & ((src) & _ca1u[i] ^ _cx1u[i]) ^ ((src) & _ca2u[i] ^ _cx2u[i]))
+
+#define DoMaskMergeRop24(src, dst, mask, index) {\
+ register int idx = ((index) & 3)<< 1; \
+ unsigned long _src0 = (src);\
+ unsigned long _src1 = _src0 & _ca1 ^ _cx1; \
+ unsigned long _src2 = _src0 & _ca2 ^ _cx2; \
+ *(dst) = (((*(dst)) & cfbrmask[idx]) | (((*(dst)) & cfbmask[idx]) & \
+ (((( _src1 |(~mask))<<cfb24Shift[idx])&cfbmask[idx]) ^ \
+ ((( _src2&(mask))<<cfb24Shift[idx])&cfbmask[idx])))); \
+ idx++; \
+ (dst)++; \
+ *(dst) = (((*(dst)) & cfbrmask[idx]) | (((*(dst)) & cfbmask[idx]) & \
+ ((((_src1 |(~mask))>>cfb24Shift[idx])&cfbmask[idx]) ^ \
+ (((_src2 &(mask))>>cfb24Shift[idx])&cfbmask[idx])))); \
+ (dst)--; \
+ }
+
+#define DoMaskMergeRop(src, dst, mask) \
+ (((dst) & ((((src) & _ca1) ^ _cx1) | ~(mask))) ^ ((((src) & _ca2) ^ _cx2) & (mask)))
+
+#define DoMaskMergeRop24u(src, dst, mask, i) \
+((dst) & (((src) & _ca1u[(i)] ^ _cx1u[(i)]) | ~(mask)) ^ (((src) & _ca2u[(i)] ^ _cx2u[(i)]) & (mask)))
+
+#define DoMergeRop24(src,dst,index) {\
+ register int idx = ((index) & 3)<< 1; \
+ unsigned long _src0 = (src);\
+ unsigned long _src1 = _src0 & _ca1 ^ _cx1; \
+ unsigned long _src2 = _src0 & _ca2 ^ _cx2; \
+ *(dst) = (((*(dst)) & cfbrmask[idx]) | (((*(dst)) & cfbmask[idx]) & \
+ ((_src1 << cfb24Shift[idx])&cfbmask[idx]) ^ \
+ ((_src2 << cfb24Shift[idx])&cfbmask[idx]))); \
+ idx++; \
+ (dst)++; \
+ *(dst) = (((*(dst)) & cfbrmask[idx]) | (((*(dst)) & cfbmask[idx]) & \
+ ((_src1 >> cfb24Shift[idx])&cfbmask[idx]) ^ \
+ ((_src2 >> cfb24Shift[idx])&cfbmask[idx]))); \
+ (dst)--; \
+ }
+
+#define DoPrebuiltMergeRop(dst) ((dst) & _cca ^ _ccx)
+
+#define DoPrebuiltMergeRop24(dst,index) { \
+ register int idx = ((index) & 3)<< 1; \
+ *(dst) = (((*(dst)) & cfbrmask[idx]) | (((*(dst)) & cfbmask[idx]) &\
+ (( _cca <<cfb24Shift[idx])&cfbmask[idx]) ^ \
+ (( _ccx <<cfb24Shift[idx])&cfbmask[idx]))); \
+ idx++; \
+ (dst)++; \
+ *(dst) = (((*(dst)) & cfbrmask[idx]) | (((*(dst)) & cfbmask[idx]) &\
+ (( _cca >>cfb24Shift[idx])&cfbmask[idx]) ^ \
+ (( _ccx >>cfb24Shift[idx])&cfbmask[idx]))); \
+ (dst)--; \
+ }
+
+#define DoMaskPrebuiltMergeRop(dst,mask) \
+ ((dst) & (_cca | ~(mask)) ^ (_ccx & (mask)))
+
+#define PrebuildMergeRop(src) ((_cca = (src) & _ca1 ^ _cx1), \
+ (_ccx = (src) & _ca2 ^ _cx2))
+
+#ifndef MROP
+#define MROP 0
+#endif
+
+#define Mclear (1<<GXclear)
+#define Mand (1<<GXand)
+#define MandReverse (1<<GXandReverse)
+#define Mcopy (1<<GXcopy)
+#define MandInverted (1<<GXandInverted)
+#define Mnoop (1<<GXnoop)
+#define Mxor (1<<GXxor)
+#define Mor (1<<GXor)
+#define Mnor (1<<GXnor)
+#define Mequiv (1<<GXequiv)
+#define Minvert (1<<GXinvert)
+#define MorReverse (1<<GXorReverse)
+#define McopyInverted (1<<GXcopyInverted)
+#define MorInverted (1<<GXorInverted)
+#define Mnand (1<<GXnand)
+#define Mset (1<<GXset)
+
+#define MROP_PIXEL24(pix, idx) \
+ (((*(pix) & cfbmask[(idx)<<1]) >> cfb24Shift[(idx)<<1])| \
+ ((*((pix)+1) & cfbmask[((idx)<<1)+1]) << cfb24Shift[((idx)<<1)+1]))
+
+#define MROP_SOLID24P(src,dst,sindex, index) \
+ MROP_SOLID24(MROP_PIXEL24(src,sindex),dst,index)
+
+#define MROP_MASK24P(src,dst,mask,sindex,index) \
+ MROP_MASK24(MROP_PIXEL24(src,sindex),dst,mask,index)
+
+#if (MROP) == Mcopy
+#define MROP_DECLARE()
+#define MROP_DECLARE_REG()
+#define MROP_INITIALIZE(alu,pm)
+#define MROP_SOLID(src,dst) (src)
+#define MROP_SOLID24(src,dst,index) {\
+ register int idx = ((index) & 3)<< 1; \
+ unsigned long _src = (src); \
+ *(dst) = (*(dst) & cfbrmask[idx])|((_src<<cfb24Shift[idx])&cfbmask[idx]); \
+ idx++; \
+ *((dst)+1) = (*((dst)+1) & cfbrmask[idx])|((_src>>cfb24Shift[idx])&cfbmask[idx]); \
+ }
+#define MROP_MASK(src,dst,mask) (((dst) & ~(mask)) | ((src) & (mask)))
+#define MROP_MASK24(src,dst,mask,index) {\
+ register int idx = ((index) & 3)<< 1; \
+ unsigned long _src = (src); \
+ *(dst) = (*(dst) & cfbrmask[idx] &(~(((mask)<< cfb24Shift[idx])&cfbmask[idx])) | \
+ (((_src &(mask))<<cfb24Shift[idx])&cfbmask[idx])); \
+ idx++; \
+ *((dst)+1) = (*((dst)+1) & cfbrmask[idx] &(~(((mask)>>cfb24Shift[idx])&cfbmask[idx])) | \
+ (((_src&(mask))>>cfb24Shift[idx])&cfbmask[idx])); \
+ }
+#define MROP_NAME(prefix) MROP_NAME_CAT(prefix,Copy)
+#endif
+
+#if (MROP) == McopyInverted
+#define MROP_DECLARE()
+#define MROP_DECLARE_REG()
+#define MROP_INITIALIZE(alu,pm)
+#define MROP_SOLID(src,dst) (~(src))
+#define MROP_SOLID24(src,dst,index) {\
+ register int idx = ((index) & 3)<< 1; \
+ unsigned long _src = ~(src); \
+ *(dst) = (*(dst) & cfbrmask[idx])|((_src << cfb24Shift[idx])&cfbmask[idx]); \
+ idx++; \
+ (dst)++; \
+ *(dst) = (*(dst) & cfbrmask[idx])|((_src >>cfb24Shift[idx])&cfbmask[idx]); \
+ (dst)--; \
+ }
+#define MROP_MASK(src,dst,mask) (((dst) & ~(mask)) | ((~(src)) & (mask)))
+#define MROP_MASK24(src,dst,mask,index) {\
+ register int idx = ((index) & 3)<< 1; \
+ unsigned long _src = ~(src); \
+ *(dst) = (*(dst) & cfbrmask[idx] &(~(((mask)<< cfb24Shift[idx])&cfbmask[idx])) | \
+ (((_src &(mask))<<cfb24Shift[idx])&cfbmask[idx])); \
+ idx++; \
+ (dst)++; \
+ *(dst) = (*(dst) & cfbrmask[idx] &(~(((mask)>>cfb24Shift[idx])&cfbmask[idx])) | \
+ ((((_src & (mask))>>cfb24Shift[idx])&cfbmask[idx])); \
+ (dst)--; \
+ }
+#define MROP_NAME(prefix) MROP_NAME_CAT(prefix,CopyInverted)
+#endif
+
+#if (MROP) == Mxor
+#define MROP_DECLARE()
+#define MROP_DECLARE_REG()
+#define MROP_INITIALIZE(alu,pm)
+#define MROP_SOLID(src,dst) ((src) ^ (dst))
+#define MROP_SOLID24(src,dst,index) {\
+ register int idx = ((index) & 3)<< 1; \
+ unsigned long _src = (src); \
+ *(dst) ^= ((_src << cfb24Shift[idx])&cfbmask[idx]); \
+ idx++; \
+ (dst)++; \
+ *(dst) ^= ((_src >>cfb24Shift[idx])&cfbmask[idx]); \
+ (dst)--; \
+ }
+#define MROP_MASK(src,dst,mask) (((src) & (mask)) ^ (dst))
+#define MROP_MASK24(src,dst,mask,index) {\
+ register int idx = ((index) & 3)<< 1; \
+ *(dst) ^= ((((src)&(mask))<<cfb24Shift[idx])&cfbmask[idx]); \
+ idx++; \
+ (dst)++; \
+ *(dst) ^= ((((src)&(mask))>>cfb24Shift[idx])&cfbmask[idx]); \
+ (dst)--; \
+ }
+#define MROP_NAME(prefix) MROP_NAME_CAT(prefix,Xor)
+#endif
+
+#if (MROP) == Mor
+#define MROP_DECLARE()
+#define MROP_DECLARE_REG()
+#define MROP_INITIALIZE(alu,pm)
+#define MROP_SOLID(src,dst) ((src) | (dst))
+#define MROP_SOLID24(src,dst,index) {\
+ register int idx = ((index) & 3)<< 1; \
+ *(dst) |= (((src)<<cfb24Shift[idx])&cfbmask[idx]); \
+ idx++; \
+ (dst)++; \
+ *(dst) |= (((src)>>cfb24Shift[idx])&cfbmask[idx]); \
+ (dst)--; \
+ }
+#define MROP_MASK(src,dst,mask) (((src) & (mask)) | (dst))
+#define MROP_MASK24(src,dst,mask,index) {\
+ register int idx = ((index) & 3)<< 1; \
+ unsigned long _src = (src); \
+ *(dst) |= (((_src &(mask))<<cfb24Shift[idx])&cfbmask[idx]); \
+ idx++; \
+ (dst)++; \
+ *(dst) |= (((_src &(mask))>>cfb24Shift[idx])&cfbmask[idx]); \
+ (dst)--; \
+ }
+#define MROP_NAME(prefix) MROP_NAME_CAT(prefix,Or)
+#endif
+
+#if (MROP) == (Mcopy|Mxor|MandReverse|Mor)
+#define MROP_DECLARE() unsigned long _ca1, _cx1;
+#define MROP_DECLARE_REG() register MROP_DECLARE()
+#define MROP_INITIALIZE(alu,pm) { \
+ mergeRopPtr _bits; \
+ _bits = &mergeRopBits[alu]; \
+ _ca1 = _bits->ca1; \
+ _cx1 = _bits->cx1; \
+}
+#define MROP_SOLID(src,dst) \
+ ((dst) & ((src) & _ca1 ^ _cx1) ^ (src))
+#define MROP_MASK(src,dst,mask) \
+ (((dst) & (((src) & _ca1 ^ _cx1)) | (~(mask)) ^ ((src) & (mask))))
+#define MROP_NAME(prefix) MROP_NAME_CAT(prefix,CopyXorAndReverseOr)
+#define MROP_PREBUILD(src) PrebuildMergeRop(src)
+#define MROP_PREBUILT_DECLARE() DeclarePrebuiltMergeRop()
+#define MROP_PREBUILT_SOLID(src,dst) DoPrebuiltMergeRop(dst)
+#define MROP_PREBUILT_SOLID24(src,dst,index) DoPrebuiltMergeRop24(dst,index)
+#define MROP_PREBUILT_MASK(src,dst,mask) DoMaskPrebuiltMergeRop(dst,mask)
+#define MROP_PREBUILT_MASK24(src,dst,mask,index) DoMaskPrebuiltMergeRop24(dst,mask,index)
+#endif
+
+#if (MROP) == 0
+#if !defined(PSZ) || (PSZ != 24)
+#define MROP_DECLARE() DeclareMergeRop()
+#define MROP_DECLARE_REG() register DeclareMergeRop()
+#define MROP_INITIALIZE(alu,pm) InitializeMergeRop(alu,pm)
+#define MROP_SOLID(src,dst) DoMergeRop(src,dst)
+#define MROP_MASK(src,dst,mask) DoMaskMergeRop(src, dst, mask)
+#else
+#define MROP_DECLARE() \
+ DeclareMergeRop() \
+ DeclareMergeRop24()
+#define MROP_DECLARE_REG() \
+ register DeclareMergeRop()\
+ DeclareMergeRop24()
+#define MROP_INITIALIZE(alu,pm) \
+ InitializeMergeRop(alu,pm)\
+ InitializeMergeRop24(alu,pm)
+#define MROP_SOLID(src,dst) DoMergeRop24u(src,dst,((int)(&(dst)-pdstBase) % 3))
+#define MROP_MASK(src,dst,mask) DoMaskMergeRop24u(src, dst, mask,((int)(&(dst) - pdstBase)%3))
+#endif
+#define MROP_SOLID24(src,dst,index) DoMergeRop24(src,dst,index)
+#define MROP_MASK24(src,dst,mask,index) DoMaskMergeRop24(src, dst, mask,index)
+#define MROP_NAME(prefix) MROP_NAME_CAT(prefix,General)
+#define MROP_PREBUILD(src) PrebuildMergeRop(src)
+#define MROP_PREBUILT_DECLARE() DeclarePrebuiltMergeRop()
+#define MROP_PREBUILT_SOLID(src,dst) DoPrebuiltMergeRop(dst)
+#define MROP_PREBUILT_SOLID24(src,dst,index) DoPrebuiltMergeRop24(dst,index)
+#define MROP_PREBUILT_MASK(src,dst,mask) DoMaskPrebuiltMergeRop(dst,mask)
+#define MROP_PREBUILT_MASK24(src,dst,mask,index) \
+ DoMaskPrebuiltMergeRop24(dst,mask,index)
+#endif
+
+#ifndef MROP_PREBUILD
+#define MROP_PREBUILD(src)
+#define MROP_PREBUILT_DECLARE()
+#define MROP_PREBUILT_SOLID(src,dst) MROP_SOLID(src,dst)
+#define MROP_PREBUILT_SOLID24(src,dst,index) MROP_SOLID24(src,dst,index)
+#define MROP_PREBUILT_MASK(src,dst,mask) MROP_MASK(src,dst,mask)
+#define MROP_PREBUILT_MASK24(src,dst,mask,index) MROP_MASK24(src,dst,mask,index)
+#endif
+
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define MROP_NAME_CAT(prefix,suffix) prefix##suffix
+#else
+#define MROP_NAME_CAT(prefix,suffix) prefix/**/suffix
+#endif
+
+#endif
diff --git a/xc/programs/Xserver/mfb/mfb.h b/xc/programs/Xserver/mfb/mfb.h
new file mode 100644
index 000000000..dda1e1a52
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfb.h
@@ -0,0 +1,1297 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfb.h,v 1.14 1999/06/06 08:49:13 dawes Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfb.h /main/43 1998/02/09 14:40:38 kaleb $ */
+
+
+#if !defined(_MFB_H_) || defined(MFB_PROTOTYPES_ONLY)
+#ifndef MFB_PROTOTYPES_ONLY
+#define _MFB_H_
+#endif
+
+
+/* Monochrome Frame Buffer definitions
+ written by drewry, september 1986
+*/
+#include "pixmap.h"
+#include "region.h"
+#include "gc.h"
+#include "colormap.h"
+#include "miscstruct.h"
+#include "mibstore.h"
+
+extern int InverseAlu[];
+
+/* warning: PixelType definition duplicated in maskbits.h */
+#ifndef PixelType
+#define PixelType unsigned long
+#endif /* PixelType */
+
+/* mfbbitblt.c */
+
+extern void mfbDoBitblt(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/
+#endif
+);
+
+extern RegionPtr mfbCopyArea(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ GCPtr/*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*width*/,
+ int /*height*/,
+ int /*dstx*/,
+ int /*dsty*/
+#endif
+);
+
+extern Bool mfbRegisterCopyPlaneProc(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ RegionPtr (* /*proc*/)(
+#if NeedNestedPrototypes
+ DrawablePtr /* pSrcDrawable */,
+ DrawablePtr /* pDstDrawable */,
+ GCPtr /* pGC */,
+ int /* srcx */,
+ int /* srcy */,
+ int /* width */,
+ int /* height */,
+ int /* dstx */,
+ int /* dsty */,
+ unsigned long /* bitPlane */
+#endif
+ )
+#endif
+);
+
+extern RegionPtr mfbCopyPlane(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ GCPtr/*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*width*/,
+ int /*height*/,
+ int /*dstx*/,
+ int /*dsty*/,
+ unsigned long /*plane*/
+#endif
+);
+/* mfbbltC.c */
+
+extern void mfbDoBitbltCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/
+#endif
+);
+/* mfbbltCI.c */
+
+extern void mfbDoBitbltCopyInverted(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/
+#endif
+);
+/* mfbbltG.c */
+
+extern void mfbDoBitbltGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/
+#endif
+);
+/* mfbbltO.c */
+
+extern void mfbDoBitbltOr(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/
+#endif
+);
+/* mfbbltX.c */
+
+extern void mfbDoBitbltXor(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrc*/,
+ DrawablePtr /*pDst*/,
+ int /*alu*/,
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*pptSrc*/
+#endif
+);
+/* mfbbres.c */
+
+extern void mfbBresS(
+#if NeedFunctionPrototypes
+ int /*rop*/,
+ PixelType * /*addrl*/,
+ int /*nlwidth*/,
+ int /*signdx*/,
+ int /*signdy*/,
+ int /*axis*/,
+ int /*x1*/,
+ int /*y1*/,
+ int /*e*/,
+ int /*e1*/,
+ int /*e2*/,
+ int /*len*/
+#endif
+);
+/* mfbbresd.c */
+
+extern void mfbBresD(
+#if NeedFunctionPrototypes
+ int /*fgrop*/,
+ int /*bgrop*/,
+ int * /*pdashIndex*/,
+ unsigned char * /*pDash*/,
+ int /*numInDashList*/,
+ int * /*pdashOffset*/,
+ int /*isDoubleDash*/,
+ PixelType * /*addrl*/,
+ int /*nlwidth*/,
+ int /*signdx*/,
+ int /*signdy*/,
+ int /*axis*/,
+ int /*x1*/,
+ int /*y1*/,
+ int /*e*/,
+ int /*e1*/,
+ int /*e2*/,
+ int /*len*/
+#endif
+);
+/* mfbbstore.c */
+
+extern void mfbSaveAreas(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPixmap*/,
+ RegionPtr /*prgnSave*/,
+ int /*xorg*/,
+ int /*yorg*/,
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern void mfbRestoreAreas(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPixmap*/,
+ RegionPtr /*prgnRestore*/,
+ int /*xorg*/,
+ int /*yorg*/,
+ WindowPtr /*pWin*/
+#endif
+);
+/* mfbclip.c */
+
+extern RegionPtr mfbPixmapToRegion(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPix*/
+#endif
+);
+/* mfbcmap.c */
+
+extern int mfbListInstalledColormaps(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ Colormap * /*pmaps*/
+#endif
+);
+
+extern void mfbInstallColormap(
+#if NeedFunctionPrototypes
+ ColormapPtr /*pmap*/
+#endif
+);
+
+extern void mfbUninstallColormap(
+#if NeedFunctionPrototypes
+ ColormapPtr /*pmap*/
+#endif
+);
+
+extern void mfbResolveColor(
+#if NeedFunctionPrototypes
+ unsigned short * /*pred*/,
+ unsigned short * /*pgreen*/,
+ unsigned short * /*pblue*/,
+ VisualPtr /*pVisual*/
+#endif
+);
+
+extern Bool mfbCreateColormap(
+#if NeedFunctionPrototypes
+ ColormapPtr /*pMap*/
+#endif
+);
+
+extern void mfbDestroyColormap(
+#if NeedFunctionPrototypes
+ ColormapPtr /*pMap*/
+#endif
+);
+
+extern Bool mfbCreateDefColormap(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/
+#endif
+);
+/* mfbfillarc.c */
+
+extern void mfbPolyFillArcSolid(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+/* mfbfillrct.c */
+
+extern void mfbPolyFillRect(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nrectFill*/,
+ xRectangle * /*prectInit*/
+#endif
+);
+/* mfbfillsp.c */
+
+extern void mfbBlackSolidFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+extern void mfbWhiteSolidFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+extern void mfbInvertSolidFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+extern void mfbWhiteStippleFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+extern void mfbBlackStippleFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+extern void mfbInvertStippleFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+extern void mfbTileFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+extern void mfbUnnaturalTileFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+
+extern void mfbUnnaturalStippleFS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*nInit*/,
+ DDXPointPtr /*pptInit*/,
+ int * /*pwidthInit*/,
+ int /*fSorted*/
+#endif
+);
+/* mfbfont.c */
+
+extern Bool mfbRealizeFont(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pscr*/,
+ FontPtr /*pFont*/
+#endif
+);
+
+extern Bool mfbUnrealizeFont(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pscr*/,
+ FontPtr /*pFont*/
+#endif
+);
+/* mfbgc.c */
+
+extern Bool mfbCreateGC(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/
+#endif
+);
+
+extern void mfbValidateGC(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/,
+ unsigned long /*changes*/,
+ DrawablePtr /*pDrawable*/
+#endif
+);
+
+extern int mfbReduceRop(
+#if NeedFunctionPrototypes
+ int /*alu*/,
+ Pixel /*src*/
+#endif
+);
+
+/* mfbgetsp.c */
+
+extern void mfbGetSpans(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*wMax*/,
+ DDXPointPtr /*ppt*/,
+ int * /*pwidth*/,
+ int /*nspans*/,
+ char * /*pdstStart*/
+#endif
+);
+/* mfbhrzvert.c */
+
+extern void mfbHorzS(
+#if NeedFunctionPrototypes
+ int /*rop*/,
+ PixelType * /*addrl*/,
+ int /*nlwidth*/,
+ int /*x1*/,
+ int /*y1*/,
+ int /*len*/
+#endif
+);
+
+extern void mfbVertS(
+#if NeedFunctionPrototypes
+ int /*rop*/,
+ PixelType * /*addrl*/,
+ int /*nlwidth*/,
+ int /*x1*/,
+ int /*y1*/,
+ int /*len*/
+#endif
+);
+/* mfbigbblak.c */
+
+extern void mfbImageGlyphBltBlack(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+/* mfbigbwht.c */
+
+extern void mfbImageGlyphBltWhite(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+/* mfbimage.c */
+
+extern void mfbPutImage(
+#if NeedFunctionPrototypes
+ DrawablePtr /*dst*/,
+ GCPtr /*pGC*/,
+ int /*depth*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ int /*leftPad*/,
+ int /*format*/,
+ char * /*pImage*/
+#endif
+);
+
+extern void mfbGetImage(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ int /*sx*/,
+ int /*sy*/,
+ int /*w*/,
+ int /*h*/,
+ unsigned int /*format*/,
+ unsigned long /*planeMask*/,
+ char * /*pdstLine*/
+#endif
+);
+/* mfbline.c */
+
+extern void mfbLineSS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/
+#endif
+);
+
+extern void mfbLineSD(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pptInit*/
+#endif
+);
+
+/* mfbmisc.c */
+
+extern void mfbQueryBestSize(
+#if NeedFunctionPrototypes
+ int /*class*/,
+ unsigned short * /*pwidth*/,
+ unsigned short * /*pheight*/,
+ ScreenPtr /*pScreen*/
+#endif
+);
+/* mfbpablack.c */
+
+extern void mfbSolidBlackArea(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*nop*/
+#endif
+);
+
+extern void mfbStippleBlackArea(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*pstipple*/
+#endif
+);
+/* mfbpainv.c */
+
+extern void mfbSolidInvertArea(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*nop*/
+#endif
+);
+
+extern void mfbStippleInvertArea(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*pstipple*/
+#endif
+);
+/* mfbpawhite.c */
+
+extern void mfbSolidWhiteArea(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*nop*/
+#endif
+);
+
+extern void mfbStippleWhiteArea(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*pstipple*/
+#endif
+);
+/* mfbpgbblak.c */
+
+extern void mfbPolyGlyphBltBlack(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+/* mfbpgbinv.c */
+
+extern void mfbPolyGlyphBltInvert(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+/* mfbpgbwht.c */
+
+extern void mfbPolyGlyphBltWhite(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+/* mfbpixmap.c */
+
+extern PixmapPtr mfbCreatePixmap(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ int /*width*/,
+ int /*height*/,
+ int /*depth*/
+#endif
+);
+
+extern Bool mfbDestroyPixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPixmap*/
+#endif
+);
+
+extern PixmapPtr mfbCopyPixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pSrc*/
+#endif
+);
+
+extern void mfbPadPixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPixmap*/
+#endif
+);
+
+extern void mfbXRotatePixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPix*/,
+ int /*rw*/
+#endif
+);
+
+extern void mfbYRotatePixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPix*/,
+ int /*rh*/
+#endif
+);
+
+extern void mfbCopyRotatePixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr /*psrcPix*/,
+ PixmapPtr * /*ppdstPix*/,
+ int /*xrot*/,
+ int /*yrot*/
+#endif
+);
+/* mfbplyblack.c */
+
+extern void mfbFillPolyBlack(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*shape*/,
+ int /*mode*/,
+ int /*count*/,
+ DDXPointPtr /*ptsIn*/
+#endif
+);
+/* mfbplyinv.c */
+
+extern void mfbFillPolyInvert(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*shape*/,
+ int /*mode*/,
+ int /*count*/,
+ DDXPointPtr /*ptsIn*/
+#endif
+);
+/* mfbplywhite.c */
+
+extern void mfbFillPolyWhite(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*shape*/,
+ int /*mode*/,
+ int /*count*/,
+ DDXPointPtr /*ptsIn*/
+#endif
+);
+/* mfbpntwin.c */
+
+extern void mfbPaintWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ RegionPtr /*pRegion*/,
+ int /*what*/
+#endif
+);
+/* mfbpolypnt.c */
+
+extern void mfbPolyPoint(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ xPoint * /*pptInit*/
+#endif
+);
+/* mfbpushpxl.c */
+
+extern void mfbSolidPP(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/,
+ PixmapPtr /*pBitMap*/,
+ DrawablePtr /*pDrawable*/,
+ int /*dx*/,
+ int /*dy*/,
+ int /*xOrg*/,
+ int /*yOrg*/
+#endif
+);
+
+extern void mfbPushPixels(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/,
+ PixmapPtr /*pBitMap*/,
+ DrawablePtr /*pDrawable*/,
+ int /*dx*/,
+ int /*dy*/,
+ int /*xOrg*/,
+ int /*yOrg*/
+#endif
+);
+/* mfbscrclse.c */
+
+extern Bool mfbCloseScreen(
+#if NeedFunctionPrototypes
+ int /*index*/,
+ ScreenPtr /*pScreen*/
+#endif
+);
+/* mfbscrinit.c */
+
+extern Bool mfbAllocatePrivates(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ int * /*pWinIndex*/,
+ int * /*pGCIndex*/
+#endif
+);
+
+extern Bool mfbScreenInit(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ pointer /*pbits*/,
+ int /*xsize*/,
+ int /*ysize*/,
+ int /*dpix*/,
+ int /*dpiy*/,
+ int /*width*/
+#endif
+);
+
+extern PixmapPtr mfbGetWindowPixmap(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern void mfbSetWindowPixmap(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ PixmapPtr /*pPix*/
+#endif
+);
+
+/* mfbseg.c */
+
+extern void mfbSegmentSS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nseg*/,
+ xSegment * /*pSeg*/
+#endif
+);
+
+extern void mfbSegmentSD(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nseg*/,
+ xSegment * /*pSeg*/
+#endif
+);
+/* mfbsetsp.c */
+
+extern void mfbSetScanline(
+#if NeedFunctionPrototypes
+ int /*y*/,
+ int /*xOrigin*/,
+ int /*xStart*/,
+ int /*xEnd*/,
+ PixelType * /*psrc*/,
+ int /*alu*/,
+ PixelType * /*pdstBase*/,
+ int /*widthDst*/
+#endif
+);
+
+extern void mfbSetSpans(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ char * /*psrc*/,
+ DDXPointPtr /*ppt*/,
+ int * /*pwidth*/,
+ int /*nspans*/,
+ int /*fSorted*/
+#endif
+);
+/* mfbteblack.c */
+
+extern void mfbTEGlyphBltBlack(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+/* mfbtewhite.c */
+
+extern void mfbTEGlyphBltWhite(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr/*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+/* mfbtileC.c */
+
+extern void mfbTileAreaPPWCopy(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*ptile*/
+#endif
+);
+/* mfbtileG.c */
+
+extern void mfbTileAreaPPWGeneral(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*ptile*/
+#endif
+);
+
+extern void mfbTileAreaPPW(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*ptile*/
+#endif
+);
+/* mfbwindow.c */
+
+extern Bool mfbCreateWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern Bool mfbDestroyWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern Bool mfbMapWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWindow*/
+#endif
+);
+
+extern Bool mfbPositionWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ int /*x*/,
+ int /*y*/
+#endif
+);
+
+extern Bool mfbUnmapWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWindow*/
+#endif
+);
+
+extern void mfbCopyWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ DDXPointRec /*ptOldOrg*/,
+ RegionPtr /*prgnSrc*/
+#endif
+);
+
+extern Bool mfbChangeWindowAttributes(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ unsigned long /*mask*/
+#endif
+);
+/* mfbzerarc.c */
+
+extern void mfbZeroPolyArcSS(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+
+#ifndef MFB_PROTOTYPES_ONLY
+/*
+ private filed of pixmap
+ pixmap.devPrivate = (PixelType *)pointer_to_bits
+ pixmap.devKind = width_of_pixmap_in_bytes
+
+ private field of screen
+ a pixmap, for which we allocate storage. devPrivate is a pointer to
+the bits in the hardware framebuffer. note that devKind can be poked to
+make the code work for framebuffers that are wider than their
+displayable screen (e.g. the early vsII, which displayed 960 pixels
+across, but was 1024 in the hardware.)
+
+ private field of GC
+*/
+
+typedef struct {
+ unsigned char rop; /* reduction of rasterop to 1 of 3 */
+ unsigned char ropOpStip; /* rop for opaque stipple */
+ unsigned char ropFillArea; /* == alu, rop, or ropOpStip */
+ unsigned char unused1[sizeof(long) - 3]; /* Alignment */
+ void (* FillArea)( /* fills regions; look at the code */
+#if NeedNestedPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*nbox*/,
+ BoxPtr /*pbox*/,
+ int /*alu*/,
+ PixmapPtr /*nop*/
+#endif
+ );
+ } mfbPrivGC;
+typedef mfbPrivGC *mfbPrivGCPtr;
+#endif
+
+extern int mfbGCPrivateIndex; /* index into GC private array */
+extern int mfbWindowPrivateIndex; /* index into Window private array */
+#ifdef PIXMAP_PER_WINDOW
+extern int frameWindowPrivateIndex; /* index into Window private array */
+#endif
+
+#ifndef MFB_PROTOTYPES_ONLY
+/* private field of window */
+typedef struct {
+ unsigned char fastBorder; /* non-zero if border tile is 32 bits wide */
+ unsigned char fastBackground;
+ unsigned short unused; /* pad for alignment with Sun compiler */
+ DDXPointRec oldRotate;
+ PixmapPtr pRotatedBackground;
+ PixmapPtr pRotatedBorder;
+ } mfbPrivWin;
+
+/* Common macros for extracting drawing information */
+
+#define mfbGetTypedWidth(pDrawable,wtype) (\
+ (((pDrawable)->type == DRAWABLE_WINDOW) ? \
+ (int) (((PixmapPtr)((pDrawable)->pScreen->devPrivate))->devKind) : \
+ (int)(((PixmapPtr)pDrawable)->devKind)) / sizeof (wtype))
+
+#define mfbGetByteWidth(pDrawable) mfbGetTypedWidth(pDrawable, unsigned char)
+
+#define mfbGetPixelWidth(pDrawable) mfbGetTypedWidth(pDrawable, PixelType)
+
+#define mfbGetTypedWidthAndPointer(pDrawable, width, pointer, wtype, ptype) {\
+ PixmapPtr _pPix; \
+ if ((pDrawable)->type == DRAWABLE_WINDOW) \
+ _pPix = (PixmapPtr) (pDrawable)->pScreen->devPrivate; \
+ else \
+ _pPix = (PixmapPtr) (pDrawable); \
+ (pointer) = (ptype *) _pPix->devPrivate.ptr; \
+ (width) = ((int) _pPix->devKind) / sizeof (wtype); \
+}
+
+#define mfbGetByteWidthAndPointer(pDrawable, width, pointer) \
+ mfbGetTypedWidthAndPointer(pDrawable, width, pointer, unsigned char, unsigned char)
+
+#define mfbGetPixelWidthAndPointer(pDrawable, width, pointer) \
+ mfbGetTypedWidthAndPointer(pDrawable, width, pointer, PixelType, PixelType)
+
+#define mfbGetWindowTypedWidthAndPointer(pWin, width, pointer, wtype, ptype) {\
+ PixmapPtr _pPix = (PixmapPtr) (pWin)->drawable.pScreen->devPrivate; \
+ (pointer) = (ptype *) _pPix->devPrivate.ptr; \
+ (width) = ((int) _pPix->devKind) / sizeof (wtype); \
+}
+
+#define mfbGetWindowPixelWidthAndPointer(pWin, width, pointer) \
+ mfbGetWindowTypedWidthAndPointer(pWin, width, pointer, PixelType, PixelType)
+
+#define mfbGetWindowByteWidthAndPointer(pWin, width, pointer) \
+ mfbGetWindowTypedWidthAndPointer(pWin, width, pointer, char, char)
+
+/* mfb uses the following macros to calculate addresses in drawables.
+ * To support banked framebuffers, the macros come in four flavors.
+ * All four collapse into the same definition on unbanked devices.
+ *
+ * mfbScanlineFoo - calculate address and do bank switching
+ * mfbScanlineFooNoBankSwitch - calculate address, don't bank switch
+ * mfbScanlineFooSrc - calculate address, switch source bank
+ * mfbScanlineFooDst - calculate address, switch destination bank
+ */
+
+/* The NoBankSwitch versions are the same for banked and unbanked cases */
+
+#define mfbScanlineIncNoBankSwitch(_ptr, _off) _ptr += (_off)
+#define mfbScanlineOffsetNoBankSwitch(_ptr, _off) ((_ptr) + (_off))
+#define mfbScanlineDeltaNoBankSwitch(_ptr, _y, _w) \
+ mfbScanlineOffsetNoBankSwitch(_ptr, (_y) * (_w))
+#define mfbScanlineNoBankSwitch(_ptr, _x, _y, _w) \
+ mfbScanlineOffsetNoBankSwitch(_ptr, (_y) * (_w) + ((_x) >> MFB_PWSH))
+
+#ifdef MFB_LINE_BANK
+
+#include "mfblinebank.h" /* get macro definitions from this file */
+
+#else /* !MFB_LINE_BANK - unbanked case */
+
+#define mfbScanlineInc(_ptr, _off) mfbScanlineIncNoBankSwitch(_ptr, _off)
+#define mfbScanlineIncSrc(_ptr, _off) mfbScanlineInc(_ptr, _off)
+#define mfbScanlineIncDst(_ptr, _off) mfbScanlineInc(_ptr, _off)
+
+#define mfbScanlineOffset(_ptr, _off) mfbScanlineOffsetNoBankSwitch(_ptr, _off)
+#define mfbScanlineOffsetSrc(_ptr, _off) mfbScanlineOffset(_ptr, _off)
+#define mfbScanlineOffsetDst(_ptr, _off) mfbScanlineOffset(_ptr, _off)
+
+#define mfbScanlineSrc(_ptr, _x, _y, _w) mfbScanline(_ptr, _x, _y, _w)
+#define mfbScanlineDst(_ptr, _x, _y, _w) mfbScanline(_ptr, _x, _y, _w)
+
+#define mfbScanlineDeltaSrc(_ptr, _y, _w) mfbScanlineDelta(_ptr, _y, _w)
+#define mfbScanlineDeltaDst(_ptr, _y, _w) mfbScanlineDelta(_ptr, _y, _w)
+
+#endif /* MFB_LINE_BANK */
+
+#define mfbScanlineDelta(_ptr, _y, _w) \
+ mfbScanlineOffset(_ptr, (_y) * (_w))
+
+#define mfbScanline(_ptr, _x, _y, _w) \
+ mfbScanlineOffset(_ptr, (_y) * (_w) + ((_x) >> MFB_PWSH))
+
+
+/* precomputed information about each glyph for GlyphBlt code.
+ this saves recalculating the per glyph information for each box.
+*/
+typedef struct _pos{
+ int xpos; /* xposition of glyph's origin */
+ int xchar; /* x position mod 32 */
+ int leftEdge;
+ int rightEdge;
+ int topEdge;
+ int bottomEdge;
+ PixelType *pdstBase; /* longword with character origin */
+ int widthGlyph; /* width in bytes of this glyph */
+} TEXTPOS;
+
+/* reduced raster ops for mfb */
+#define RROP_BLACK GXclear
+#define RROP_WHITE GXset
+#define RROP_NOP GXnoop
+#define RROP_INVERT GXinvert
+
+/* macros for mfbbitblt.c, mfbfillsp.c
+ these let the code do one switch on the rop per call, rather
+than a switch on the rop per item (span or rectangle.)
+*/
+
+#define fnCLEAR(src, dst) (0)
+#define fnAND(src, dst) (src & dst)
+#define fnANDREVERSE(src, dst) (src & ~dst)
+#define fnCOPY(src, dst) (src)
+#define fnANDINVERTED(src, dst) (~src & dst)
+#define fnNOOP(src, dst) (dst)
+#define fnXOR(src, dst) (src ^ dst)
+#define fnOR(src, dst) (src | dst)
+#define fnNOR(src, dst) (~(src | dst))
+#define fnEQUIV(src, dst) (~src ^ dst)
+#define fnINVERT(src, dst) (~dst)
+#define fnORREVERSE(src, dst) (src | ~dst)
+#define fnCOPYINVERTED(src, dst)(~src)
+#define fnORINVERTED(src, dst) (~src | dst)
+#define fnNAND(src, dst) (~(src & dst))
+#define fnSET(src, dst) (unsigned long)(~0)
+
+/* Using a "switch" statement is much faster in most cases
+ * since the compiler can do a look-up table or multi-way branch
+ * instruction, depending on the architecture. The result on
+ * A Sun 3/50 is at least 2.5 times faster, assuming a uniform
+ * distribution of RasterOp operation types.
+ *
+ * However, doing some profiling on a running system reveals
+ * GXcopy is the operation over 99.5% of the time and
+ * GXxor is the next most frequent (about .4%), so we make special
+ * checks for those first.
+ *
+ * Note that this requires a change to the "calling sequence"
+ * since we can't engineer a "switch" statement to have an lvalue.
+ */
+#define DoRop(result, alu, src, dst) \
+{ \
+ if (alu == GXcopy) \
+ result = fnCOPY (src, dst); \
+ else if (alu == GXxor) \
+ result = fnXOR (src, dst); \
+ else \
+ switch (alu) \
+ { \
+ case GXclear: \
+ result = fnCLEAR (src, dst); \
+ break; \
+ case GXand: \
+ result = fnAND (src, dst); \
+ break; \
+ case GXandReverse: \
+ result = fnANDREVERSE (src, dst); \
+ break; \
+ case GXandInverted: \
+ result = fnANDINVERTED (src, dst); \
+ break; \
+ default: \
+ case GXnoop: \
+ result = fnNOOP (src, dst); \
+ break; \
+ case GXor: \
+ result = fnOR (src, dst); \
+ break; \
+ case GXnor: \
+ result = fnNOR (src, dst); \
+ break; \
+ case GXequiv: \
+ result = fnEQUIV (src, dst); \
+ break; \
+ case GXinvert: \
+ result = fnINVERT (src, dst); \
+ break; \
+ case GXorReverse: \
+ result = fnORREVERSE (src, dst); \
+ break; \
+ case GXcopyInverted: \
+ result = fnCOPYINVERTED (src, dst); \
+ break; \
+ case GXorInverted: \
+ result = fnORINVERTED (src, dst); \
+ break; \
+ case GXnand: \
+ result = fnNAND (src, dst); \
+ break; \
+ case GXset: \
+ result = fnSET (src, dst); \
+ break; \
+ } \
+}
+
+
+/* C expression fragments for various operations. These get passed in
+ * as -D's on the compile command line. See mfb/Imakefile. This
+ * fixes XBUG 6319.
+ *
+ * This seems like a good place to point out that mfb's use of the
+ * words black and white is an unfortunate misnomer. In mfb code, black
+ * means zero, and white means one.
+ */
+#define MFB_OPEQ_WHITE |=
+#define MFB_OPEQ_BLACK &=~
+#define MFB_OPEQ_INVERT ^=
+#define MFB_EQWHOLEWORD_WHITE =~0
+#define MFB_EQWHOLEWORD_BLACK =0
+#define MFB_EQWHOLEWORD_INVERT ^=~0
+#define MFB_OP_WHITE /* nothing */
+#define MFB_OP_BLACK ~
+
+/*
+ * if MFB is built as a module, it shouldn't call libc functions.
+ */
+#ifdef XFree86LOADER
+#include "xf86_ansic.h"
+#endif
+
+#endif /* MFB_PROTOTYPES_ONLY */
+#endif /* _MFB_H_ */
diff --git a/xc/programs/Xserver/mfb/mfbbitblt.c b/xc/programs/Xserver/mfb/mfbbitblt.c
new file mode 100644
index 000000000..db425c45b
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbbitblt.c
@@ -0,0 +1,481 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbbitblt.c,v 1.3 1998/10/04 09:39:07 dawes Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbbitblt.c /main/47 1998/02/09 14:38:09 kaleb $ */
+#include "X.h"
+#include "Xprotostr.h"
+
+#include "miscstruct.h"
+#include "regionstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+#include "mi.h"
+
+#include "mfb.h"
+#include "maskbits.h"
+
+
+/* CopyArea and CopyPlane for a monchrome frame buffer
+
+
+ clip the source rectangle to the source's available bits. (this
+avoids copying unnecessary pieces that will just get exposed anyway.)
+this becomes the new shape of the destination.
+ clip the destination region to the composite clip in the
+GC. this requires translating the destination region to (dstx, dsty).
+ build a list of source points, one for each rectangle in the
+destination. this is a simple translation.
+ go do the multiple rectangle copies
+ do graphics exposures
+*/
+/** Optimized for drawing pixmaps into windows, especially when drawing into
+ ** unobscured windows. Calls to the general-purpose region code were
+ ** replaced with rectangle-to-rectangle clipping comparisions. This is
+ ** possible, since the pixmap is a single rectangle. In an unobscured
+ ** window, the destination clip is also a single rectangle, and region
+ ** code can be avoided entirely. This is a big savings, since the region
+ ** code uses XAlloc() and makes many function calls.
+ **
+ ** In addition, if source is a pixmap, there is no need to call the
+ ** expensive miHandleExposures() routine. Instead, we simply return NULL.
+ **
+ ** Previously, drawing a pixmap into an unobscured window executed at least
+ ** 8 XAlloc()'s, 30 function calls, and hundreds of lines of code.
+ **
+ ** Now, the same operation requires no XAlloc()'s, no region function calls,
+ ** and much less overhead. Nice for drawing lots of small pixmaps.
+ */
+
+#ifndef LOWMEMFTPT
+
+void
+mfbDoBitblt (pSrc, pDst, alu, prgnDst, pptSrc)
+ DrawablePtr pSrc, pDst;
+ int alu;
+ RegionPtr prgnDst;
+ DDXPointPtr pptSrc;
+{
+ switch (alu)
+ {
+ case GXcopy:
+ mfbDoBitbltCopy (pSrc, pDst, alu, prgnDst, pptSrc);
+ break;
+ case GXxor:
+ mfbDoBitbltXor (pSrc, pDst, alu, prgnDst, pptSrc);
+ break;
+ case GXcopyInverted:
+ mfbDoBitbltCopyInverted (pSrc, pDst, alu, prgnDst, pptSrc);
+ break;
+ case GXor:
+ mfbDoBitbltOr (pSrc, pDst, alu, prgnDst, pptSrc);
+ break;
+ default:
+ mfbDoBitbltGeneral (pSrc, pDst, alu, prgnDst, pptSrc);
+ break;
+ }
+}
+
+RegionPtr
+mfbCopyArea(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty)
+register DrawablePtr pSrcDrawable;
+register DrawablePtr pDstDrawable;
+register GC *pGC;
+int srcx, srcy;
+int width, height;
+int dstx, dsty;
+{
+ RegionPtr prgnSrcClip; /* may be a new region, or just a copy */
+ Bool freeSrcClip = FALSE;
+
+ RegionPtr prgnExposed;
+ RegionRec rgnDst;
+ DDXPointPtr pptSrc;
+ register DDXPointPtr ppt;
+ register BoxPtr pbox;
+ int i;
+ register int dx;
+ register int dy;
+ xRectangle origSource;
+ DDXPointRec origDest;
+ int numRects;
+ BoxRec fastBox;
+ int fastClip = 0; /* for fast clipping with pixmap source */
+ int fastExpose = 0; /* for fast exposures with pixmap source */
+ void (*localDoBitBlt)();
+
+ origSource.x = srcx;
+ origSource.y = srcy;
+ origSource.width = width;
+ origSource.height = height;
+ origDest.x = dstx;
+ origDest.y = dsty;
+
+ if ((pSrcDrawable != pDstDrawable) &&
+ pSrcDrawable->pScreen->SourceValidate)
+ {
+ (*pSrcDrawable->pScreen->SourceValidate) (pSrcDrawable, srcx, srcy, width, height);
+ }
+
+ switch (pGC->alu) {
+ case GXcopy:
+ localDoBitBlt = mfbDoBitbltCopy;
+ break;
+ case GXcopyInverted:
+ localDoBitBlt = mfbDoBitbltCopyInverted;
+ break;
+ case GXxor:
+ localDoBitBlt = mfbDoBitbltXor;
+ break;
+ case GXor:
+ localDoBitBlt = mfbDoBitbltOr;
+ break;
+ default:
+ localDoBitBlt = mfbDoBitbltGeneral;
+ break;
+ }
+
+ srcx += pSrcDrawable->x;
+ srcy += pSrcDrawable->y;
+
+ /* clip the source */
+
+ if (pSrcDrawable->type == DRAWABLE_PIXMAP)
+ {
+ if ((pSrcDrawable == pDstDrawable) &&
+ (pGC->clientClipType == CT_NONE))
+ {
+ prgnSrcClip = pGC->pCompositeClip;
+ }
+ else
+ {
+ fastClip = 1;
+ }
+ }
+ else
+ {
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ if (!((WindowPtr) pSrcDrawable)->parent)
+ {
+ /*
+ * special case bitblt from root window in
+ * IncludeInferiors mode; just like from a pixmap
+ */
+ fastClip = 1;
+ }
+ else if ((pSrcDrawable == pDstDrawable) &&
+ (pGC->clientClipType == CT_NONE))
+ {
+ prgnSrcClip = pGC->pCompositeClip;
+ }
+ else
+ {
+ prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
+ freeSrcClip = TRUE;
+ }
+ }
+ else
+ {
+ prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
+ }
+ }
+
+ fastBox.x1 = srcx;
+ fastBox.y1 = srcy;
+ fastBox.x2 = srcx + width;
+ fastBox.y2 = srcy + height;
+
+ /* Don't create a source region if we are doing a fast clip */
+ if (fastClip)
+ {
+ fastExpose = 1;
+ /*
+ * clip the source; if regions extend beyond the source size,
+ * make sure exposure events get sent
+ */
+ if (fastBox.x1 < pSrcDrawable->x)
+ {
+ fastBox.x1 = pSrcDrawable->x;
+ fastExpose = 0;
+ }
+ if (fastBox.y1 < pSrcDrawable->y)
+ {
+ fastBox.y1 = pSrcDrawable->y;
+ fastExpose = 0;
+ }
+ if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
+ {
+ fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
+ fastExpose = 0;
+ }
+ if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
+ {
+ fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
+ fastExpose = 0;
+ }
+ }
+ else
+ {
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+ REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
+ }
+
+ dstx += pDstDrawable->x;
+ dsty += pDstDrawable->y;
+
+ if (pDstDrawable->type == DRAWABLE_WINDOW)
+ {
+ if (!((WindowPtr)pDstDrawable)->realized)
+ {
+ if (!fastClip)
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return NULL;
+ }
+ }
+
+ dx = srcx - dstx;
+ dy = srcy - dsty;
+
+ /* Translate and clip the dst to the destination composite clip */
+ if (fastClip)
+ {
+ RegionPtr cclip;
+
+ /* Translate the region directly */
+ fastBox.x1 -= dx;
+ fastBox.x2 -= dx;
+ fastBox.y1 -= dy;
+ fastBox.y2 -= dy;
+
+ /* If the destination composite clip is one rectangle we can
+ do the clip directly. Otherwise we have to create a full
+ blown region and call intersect */
+ cclip = pGC->pCompositeClip;
+ if (REGION_NUM_RECTS(cclip) == 1)
+ {
+ BoxPtr pBox = REGION_RECTS(cclip);
+
+ if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
+ if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
+ if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
+ if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
+
+ /* Check to see if the region is empty */
+ if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2)
+ {
+ REGION_INIT(pGC->pScreen, &rgnDst, NullBox, 0);
+ }
+ else
+ {
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+ }
+ }
+ else
+ {
+ /* We must turn off fastClip now, since we must create
+ a full blown region. It is intersected with the
+ composite clip below. */
+ fastClip = 0;
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox,1);
+ }
+ }
+ else
+ {
+ REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
+ }
+
+ if (!fastClip)
+ {
+ REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, pGC->pCompositeClip);
+ }
+
+ /* Do bit blitting */
+ numRects = REGION_NUM_RECTS(&rgnDst);
+ if (numRects && width && height)
+ {
+ if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects *
+ sizeof(DDXPointRec))))
+ {
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return NULL;
+ }
+ pbox = REGION_RECTS(&rgnDst);
+ ppt = pptSrc;
+ for (i = numRects; --i >= 0; pbox++, ppt++)
+ {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ if (pGC->planemask & 1)
+ (*localDoBitBlt) (pSrcDrawable, pDstDrawable, pGC->alu, &rgnDst, pptSrc);
+
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+
+ prgnExposed = NULL;
+ if (pGC->fExpose)
+ {
+ /* Pixmap sources generate a NoExposed (we return NULL to do this) */
+ if (!fastExpose)
+ prgnExposed =
+ miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
+ origSource.x, origSource.y,
+ (int)origSource.width,
+ (int)origSource.height,
+ origDest.x, origDest.y, (unsigned long)0);
+ }
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return prgnExposed;
+}
+
+#endif /* ifndef LOWMEMFTPT */
+
+/*
+ * Devices which use mfb for 1-bit pixmap support
+ * must register a function for n-to-1 copy operations
+ */
+
+static unsigned long copyPlaneGeneration;
+static int copyPlaneScreenIndex = -1;
+
+Bool
+mfbRegisterCopyPlaneProc (pScreen, proc)
+ ScreenPtr pScreen;
+ RegionPtr (*proc)();
+{
+ if (copyPlaneGeneration != serverGeneration)
+ {
+ copyPlaneScreenIndex = AllocateScreenPrivateIndex();
+ if (copyPlaneScreenIndex < 0)
+ return FALSE;
+ copyPlaneGeneration = serverGeneration;
+ }
+ pScreen->devPrivates[copyPlaneScreenIndex].fptr = (pointer (*)()) proc;
+ return TRUE;
+}
+
+/*
+ if fg == 1 and bg ==0, we can do an ordinary CopyArea.
+ if fg == bg, we can do a CopyArea with alu = mfbReduceRop(alu, fg)
+ if fg == 0 and bg == 1, we use the same rasterop, with
+ source operand inverted.
+
+ CopyArea deals with all of the graphics exposure events.
+ This code depends on knowing that we can change the
+alu in the GC without having to call ValidateGC() before calling
+CopyArea().
+
+*/
+
+#ifndef LOWMEMFTPT
+
+RegionPtr
+mfbCopyPlane(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, plane)
+DrawablePtr pSrcDrawable, pDstDrawable;
+register GC *pGC;
+int srcx, srcy;
+int width, height;
+int dstx, dsty;
+unsigned long plane;
+{
+ int alu;
+ RegionPtr prgnExposed;
+ RegionPtr (*copyPlane)();
+
+ if (pSrcDrawable->depth != 1)
+ {
+ if (copyPlaneScreenIndex >= 0 &&
+ (copyPlane = (RegionPtr (*)())
+ pSrcDrawable->pScreen->devPrivates[copyPlaneScreenIndex].fptr)
+ )
+ {
+ return (*copyPlane) (pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, plane);
+ }
+ else
+ {
+ FatalError ("No copyPlane proc registered for depth %d\n",
+ pSrcDrawable->depth);
+ }
+ }
+ if (plane != 1)
+ return NULL;
+
+ if ((pGC->fgPixel & 1) == 1 && (pGC->bgPixel & 1) == 0)
+ {
+ prgnExposed = (*pGC->ops->CopyArea)(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ }
+ else if ((pGC->fgPixel & 1) == (pGC->bgPixel & 1))
+ {
+ alu = pGC->alu;
+ pGC->alu = mfbReduceRop(pGC->alu, pGC->fgPixel);
+ prgnExposed = (*pGC->ops->CopyArea)(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ pGC->alu = alu;
+ }
+ else /* need to invert the src */
+ {
+ alu = pGC->alu;
+ pGC->alu = InverseAlu[alu];
+ prgnExposed = (*pGC->ops->CopyArea)(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ pGC->alu = alu;
+ }
+ return prgnExposed;
+}
+
+#endif /* ifndef LOWMEMFTPT */
diff --git a/xc/programs/Xserver/mfb/mfbblt.c b/xc/programs/Xserver/mfb/mfbblt.c
new file mode 100644
index 000000000..d3886e729
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbblt.c
@@ -0,0 +1,588 @@
+/*
+ * mfb copy area
+ */
+/* $XFree86: xc/programs/Xserver/mfb/mfbblt.c,v 3.1 1998/10/04 09:39:08 dawes Exp $ */
+
+/*
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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
+
+*/
+/* $TOG: mfbblt.c /main/12 1998/02/09 14:38:17 kaleb $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "mfb.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "maskbits.h"
+#include "fastblt.h"
+#include "mergerop.h"
+
+void
+MROP_NAME(mfbDoBitblt)(pSrc, pDst, alu, prgnDst, pptSrc)
+ DrawablePtr pSrc, pDst;
+ int alu;
+ RegionPtr prgnDst;
+ DDXPointPtr pptSrc;
+{
+ PixelType *psrcBase, *pdstBase;
+ /* start of src and dst bitmaps */
+ int widthSrc, widthDst; /* add to get to same position in next line */
+
+ BoxPtr pbox;
+ int nbox;
+
+ BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
+ /* temporaries for shuffling rectangles */
+ DDXPointPtr pptTmp, pptNew1, pptNew2;
+ /* shuffling boxes entails shuffling the
+ source points too */
+ int w, h;
+ int xdir; /* 1 = left right, -1 = right left/ */
+ int ydir; /* 1 = top down, -1 = bottom up */
+
+ PixelType *psrcLine, *pdstLine;
+ /* pointers to line with current src and dst */
+ register PixelType *psrc;/* pointer to current src longword */
+ register PixelType *pdst;/* pointer to current dst longword */
+
+ MROP_DECLARE_REG()
+
+ /* following used for looping through a line */
+ PixelType startmask, endmask; /* masks for writing ends of dst */
+ int nlMiddle; /* whole longwords in dst */
+ int xoffSrc, xoffDst;
+ register int leftShift, rightShift;
+ register PixelType bits;
+ register PixelType bits1;
+ register int nl; /* temp copy of nlMiddle */
+
+ /* place to store full source word */
+ int nstart; /* number of ragged bits at start of dst */
+ int nend; /* number of ragged bits at end of dst */
+ int srcStartOver; /* pulling nstart bits from src
+ overflows into the next word? */
+ int careful;
+ int tmpSrc;
+
+ MROP_INITIALIZE(alu,0);
+
+ mfbGetPixelWidthAndPointer(pSrc, widthSrc, psrcBase);
+
+ mfbGetPixelWidthAndPointer(pDst, widthDst, pdstBase);
+
+ /* XXX we have to err on the side of safety when both are windows,
+ * because we don't know if IncludeInferiors is being used.
+ */
+ careful = ((pSrc == pDst) ||
+ ((pSrc->type == DRAWABLE_WINDOW) &&
+ (pDst->type == DRAWABLE_WINDOW)));
+
+ pbox = REGION_RECTS(prgnDst);
+ nbox = REGION_NUM_RECTS(prgnDst);
+
+ pboxNew1 = NULL;
+ pptNew1 = NULL;
+ pboxNew2 = NULL;
+ pptNew2 = NULL;
+ if (careful && (pptSrc->y < pbox->y1))
+ {
+ /* walk source botttom to top */
+ ydir = -1;
+ widthSrc = -widthSrc;
+ widthDst = -widthDst;
+
+ if (nbox > 1)
+ {
+ /* keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ if(!pboxNew1)
+ return;
+ pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pptNew1)
+ {
+ DEALLOCATE_LOCAL(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox)
+ {
+ while ((pboxNext >= pbox) &&
+ (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp <= pboxBase)
+ {
+ *pboxNew1++ = *pboxTmp++;
+ *pptNew1++ = *pptTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ pptNew1 -= nbox;
+ pptSrc = pptNew1;
+ }
+ }
+ else
+ {
+ /* walk source top to bottom */
+ ydir = 1;
+ }
+
+ if (careful && (pptSrc->x < pbox->x1))
+ {
+ /* walk source right to left */
+ xdir = -1;
+
+ if (nbox > 1)
+ {
+ /* reverse order of rects in each band */
+ pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pboxNew2 || !pptNew2)
+ {
+ if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
+ if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
+ if (pboxNew1)
+ {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox)
+ {
+ while ((pboxNext < pbox+nbox) &&
+ (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp != pboxBase)
+ {
+ *pboxNew2++ = *--pboxTmp;
+ *pptNew2++ = *--pptTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ pptNew2 -= nbox;
+ pptSrc = pptNew2;
+ }
+ }
+ else
+ {
+ /* walk source left to right */
+ xdir = 1;
+ }
+
+ while(nbox--)
+ {
+ w = pbox->x2 - pbox->x1;
+ h = pbox->y2 - pbox->y1;
+
+ if (ydir == -1) /* start at last scanline of rectangle */
+ {
+ psrcLine = mfbScanlineDeltaSrc(psrcBase, -(pptSrc->y+h-1), widthSrc);
+ pdstLine = mfbScanlineDeltaDst(pdstBase, -(pbox->y2-1), widthDst);
+ }
+ else /* start at first scanline */
+ {
+ psrcLine = mfbScanlineDeltaSrc(psrcBase, pptSrc->y, widthSrc);
+ pdstLine = mfbScanlineDeltaDst(pdstBase, pbox->y1, widthDst);
+ }
+ if ((pbox->x1 & PIM) + w <= PPW)
+ {
+ maskpartialbits (pbox->x1, w, startmask);
+ endmask = 0;
+ nlMiddle = 0;
+ }
+ else
+ {
+ maskbits(pbox->x1, w, startmask, endmask, nlMiddle);
+ }
+ if (xdir == 1)
+ {
+ xoffSrc = pptSrc->x & PIM;
+ xoffDst = pbox->x1 & PIM;
+ pdstLine += (pbox->x1 >> PWSH);
+ psrcLine += (pptSrc->x >> PWSH);
+#ifdef DO_UNALIGNED_BITBLT
+ nl = xoffSrc - xoffDst;
+ psrcLine = (PixelType *)
+ (((unsigned char *) psrcLine) + nl);
+#else
+ if (xoffSrc == xoffDst)
+#endif
+ {
+ while (h--)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ if (startmask)
+ {
+ *pdst = MROP_MASK(*psrc, *pdst, startmask);
+ psrc++;
+ pdst++;
+ }
+ nl = nlMiddle;
+
+#ifdef LARGE_INSTRUCTION_CACHE
+#ifdef FAST_CONSTANT_OFFSET_MODE
+
+ psrc += nl & (UNROLL-1);
+ pdst += nl & (UNROLL-1);
+
+#define BodyOdd(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]);
+#define BodyEven(n) pdst[-n] = MROP_SOLID (psrc[-n], pdst[-n]);
+
+#define LoopReset \
+pdst += UNROLL; \
+psrc += UNROLL;
+
+#else
+
+#define BodyOdd(n) *pdst = MROP_SOLID (*psrc, *pdst); pdst++; psrc++;
+#define BodyEven(n) BodyOdd(n)
+
+#define LoopReset ;
+
+#endif
+ PackedLoop
+
+#undef BodyOdd
+#undef BodyEven
+#undef LoopReset
+
+#else
+#ifdef NOTDEF
+ /* you'd think this would be faster --
+ * a single instruction instead of 6
+ * but measurements show it to be ~15% slower
+ */
+ while ((nl -= 6) >= 0)
+ {
+ asm ("moveml %1+,#0x0c0f;moveml#0x0c0f,%0"
+ : "=m" (*(char *)pdst)
+ : "m" (*(char *)psrc)
+ : "d0", "d1", "d2", "d3",
+ "a2", "a3");
+ pdst += 6;
+ }
+ nl += 6;
+ while (nl--)
+ *pdst++ = *psrc++;
+#endif
+ DuffL(nl, label1,
+ *pdst = MROP_SOLID (*psrc, *pdst);
+ pdst++; psrc++;)
+#endif
+
+ if (endmask)
+ *pdst = MROP_MASK(*psrc, *pdst, endmask);
+ mfbScanlineIncDst(pdstLine, widthDst);
+ mfbScanlineIncSrc(psrcLine, widthSrc);
+ }
+ }
+#ifndef DO_UNALIGNED_BITBLT
+ else
+ {
+ if (xoffSrc > xoffDst)
+ {
+ leftShift = (xoffSrc - xoffDst);
+ rightShift = PPW - leftShift;
+ }
+ else
+ {
+ rightShift = (xoffDst - xoffSrc);
+ leftShift = PPW - rightShift;
+ }
+ while (h--)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ bits = 0;
+ if (xoffSrc > xoffDst)
+ bits = *psrc++;
+ if (startmask)
+ {
+ bits1 = BitLeft(bits,leftShift);
+ if (BitLeft(startmask, rightShift)) {
+ bits = *psrc++;
+ bits1 |= BitRight(bits,rightShift);
+ }
+ *pdst = MROP_MASK(bits1, *pdst, startmask);
+ pdst++;
+ }
+ nl = nlMiddle;
+
+#ifdef LARGE_INSTRUCTION_CACHE
+ bits1 = bits;
+
+#ifdef FAST_CONSTANT_OFFSET_MODE
+
+ psrc += nl & (UNROLL-1);
+ pdst += nl & (UNROLL-1);
+
+#define BodyOdd(n) \
+bits = psrc[-n]; \
+pdst[-n] = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), pdst[-n]);
+
+#define BodyEven(n) \
+bits1 = psrc[-n]; \
+pdst[-n] = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), pdst[-n]);
+
+#define LoopReset \
+pdst += UNROLL; \
+psrc += UNROLL;
+
+#else
+
+#define BodyOdd(n) \
+bits = *psrc++; \
+*pdst = MROP_SOLID(BitLeft(bits1, leftShift) | BitRight(bits, rightShift), *pdst); \
+pdst++;
+
+#define BodyEven(n) \
+bits1 = *psrc++; \
+*pdst = MROP_SOLID(BitLeft(bits, leftShift) | BitRight(bits1, rightShift), *pdst); \
+pdst++;
+
+#define LoopReset ;
+
+#endif /* !FAST_CONSTANT_OFFSET_MODE */
+
+ PackedLoop
+
+#undef BodyOdd
+#undef BodyEven
+#undef LoopReset
+
+#else
+ DuffL (nl,label2,
+ bits1 = BitLeft(bits, leftShift);
+ bits = *psrc++;
+ *pdst = MROP_SOLID (bits1 | BitRight(bits, rightShift), *pdst);
+ pdst++;
+ )
+#endif
+
+ if (endmask)
+ {
+ bits1 = BitLeft(bits, leftShift);
+ if (BitLeft(endmask, rightShift))
+ {
+ bits = *psrc;
+ bits1 |= BitRight(bits, rightShift);
+ }
+ *pdst = MROP_MASK (bits1, *pdst, endmask);
+ }
+ mfbScanlineIncDst(pdstLine, widthDst);
+ mfbScanlineIncSrc(psrcLine, widthSrc);
+ }
+ }
+#endif /* DO_UNALIGNED_BITBLT */
+ }
+ else /* xdir == -1 */
+ {
+ xoffSrc = (pptSrc->x + w - 1) & PIM;
+ xoffDst = (pbox->x2 - 1) & PIM;
+ pdstLine += ((pbox->x2-1) >> PWSH) + 1;
+ psrcLine += ((pptSrc->x+w - 1) >> PWSH) + 1;
+#ifdef DO_UNALIGNED_BITBLT
+ nl = xoffSrc - xoffDst;
+ psrcLine = (PixelType *)
+ (((unsigned char *) psrcLine) + nl);
+#else
+ if (xoffSrc == xoffDst)
+#endif
+ {
+ while (h--)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ if (endmask)
+ {
+ pdst--;
+ psrc--;
+ *pdst = MROP_MASK (*psrc, *pdst, endmask);
+ }
+ nl = nlMiddle;
+
+#ifdef LARGE_INSTRUCTION_CACHE
+#ifdef FAST_CONSTANT_OFFSET_MODE
+ psrc -= nl & (UNROLL - 1);
+ pdst -= nl & (UNROLL - 1);
+
+#define BodyOdd(n) pdst[n-1] = MROP_SOLID (psrc[n-1], pdst[n-1]);
+
+#define BodyEven(n) BodyOdd(n)
+
+#define LoopReset \
+pdst -= UNROLL;\
+psrc -= UNROLL;
+
+#else
+
+#define BodyOdd(n) --pdst; --psrc; *pdst = MROP_SOLID(*psrc, *pdst);
+#define BodyEven(n) BodyOdd(n)
+#define LoopReset ;
+
+#endif
+ PackedLoop
+
+#undef BodyOdd
+#undef BodyEven
+#undef LoopReset
+
+#else
+ DuffL(nl,label3,
+ --pdst; --psrc; *pdst = MROP_SOLID (*psrc, *pdst);)
+#endif
+
+ if (startmask)
+ {
+ --pdst;
+ --psrc;
+ *pdst = MROP_MASK(*psrc, *pdst, startmask);
+ }
+ mfbScanlineIncDst(pdstLine, widthDst);
+ mfbScanlineIncSrc(psrcLine, widthSrc);
+ }
+ }
+#ifndef DO_UNALIGNED_BITBLT
+ else
+ {
+ if (xoffDst > xoffSrc)
+ {
+ rightShift = (xoffDst - xoffSrc);
+ leftShift = PPW - rightShift;
+ }
+ else
+ {
+ leftShift = (xoffSrc - xoffDst);
+ rightShift = PPW - leftShift;
+ }
+ while (h--)
+ {
+ psrc = psrcLine;
+ pdst = pdstLine;
+ bits = 0;
+ if (xoffDst > xoffSrc)
+ bits = *--psrc;
+ if (endmask)
+ {
+ bits1 = BitRight(bits, rightShift);
+ if (BitRight(endmask, leftShift)) {
+ bits = *--psrc;
+ bits1 |= BitLeft(bits, leftShift);
+ }
+ pdst--;
+ *pdst = MROP_MASK(bits1, *pdst, endmask);
+ }
+ nl = nlMiddle;
+
+#ifdef LARGE_INSTRUCTION_CACHE
+ bits1 = bits;
+#ifdef FAST_CONSTANT_OFFSET_MODE
+ psrc -= nl & (UNROLL - 1);
+ pdst -= nl & (UNROLL - 1);
+
+#define BodyOdd(n) \
+bits = psrc[n-1]; \
+pdst[n-1] = MROP_SOLID(BitRight(bits1, rightShift) | BitLeft(bits, leftShift),pdst[n-1]);
+
+#define BodyEven(n) \
+bits1 = psrc[n-1]; \
+pdst[n-1] = MROP_SOLID(BitRight(bits, rightShift) | BitLeft(bits1, leftShift),pdst[n-1]);
+
+#define LoopReset \
+pdst -= UNROLL; \
+psrc -= UNROLL;
+
+#else
+
+#define BodyOdd(n) \
+bits = *--psrc; --pdst; \
+*pdst = MROP_SOLID(BitRight(bits1, rightShift) | BitLeft(bits, leftShift),*pdst);
+
+#define BodyEven(n) \
+bits1 = *--psrc; --pdst; \
+*pdst = MROP_SOLID(BitRight(bits, rightShift) | BitLeft(bits1, leftShift),*pdst);
+
+#define LoopReset ;
+
+#endif
+
+ PackedLoop
+
+#undef BodyOdd
+#undef BodyEven
+#undef LoopReset
+
+#else
+ DuffL (nl, label4,
+ bits1 = BitRight(bits, rightShift);
+ bits = *--psrc;
+ --pdst;
+ *pdst = MROP_SOLID(bits1 | BitLeft(bits, leftShift),*pdst);
+ )
+#endif
+
+ if (startmask)
+ {
+ bits1 = BitRight(bits, rightShift);
+ if (BitRight (startmask, leftShift))
+ {
+ bits = *--psrc;
+ bits1 |= BitLeft(bits, leftShift);
+ }
+ --pdst;
+ *pdst = MROP_MASK(bits1, *pdst, startmask);
+ }
+ mfbScanlineIncDst(pdstLine, widthDst);
+ mfbScanlineIncSrc(psrcLine, widthSrc);
+ }
+ }
+#endif
+ }
+ pbox++;
+ pptSrc++;
+ }
+ if (pboxNew2)
+ {
+ DEALLOCATE_LOCAL(pptNew2);
+ DEALLOCATE_LOCAL(pboxNew2);
+ }
+ if (pboxNew1)
+ {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+}
diff --git a/xc/programs/Xserver/mfb/mfbbres.c b/xc/programs/Xserver/mfb/mfbbres.c
new file mode 100644
index 000000000..ec2fefdc2
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbbres.c
@@ -0,0 +1,361 @@
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbbres.c /main/13 1998/02/09 14:38:29 kaleb $ */
+#include "X.h"
+#include "misc.h"
+#include "mfb.h"
+#include "maskbits.h"
+#include "miline.h"
+
+/* Solid bresenham line */
+/* NOTES
+ e2 is used less often than e1, so it's not in a register
+*/
+
+void
+mfbBresS(rop, addrlbase, nlwidth, signdx, signdy, axis, x1, y1, e, e1, e2, len)
+int rop; /* a reduced rasterop */
+PixelType *addrlbase; /* pointer to base of bitmap */
+int nlwidth; /* width in longwords of bitmap */
+int signdx, signdy; /* signs of directions */
+int axis; /* major axis (Y_AXIS or X_AXIS) */
+int x1, y1; /* initial point */
+register int e; /* error accumulator */
+register int e1; /* bresenham increments */
+int e2;
+int len; /* length of line */
+{
+ register int yinc; /* increment to next scanline, in bytes */
+ register PixelType *addrl; /* bitmask long pointer */
+ register PixelType bit; /* current bit being set/cleared/etc. */
+ PixelType leftbit = mask[0]; /* leftmost bit to process in new word */
+ PixelType rightbit = mask[PPW-1]; /* rightmost bit to process in new word */
+
+ register int e3 = e2-e1;
+ PixelType tmp;
+
+ /* point to longword containing first point */
+ addrl = mfbScanline(addrlbase, x1, y1, nlwidth);
+ yinc = signdy * nlwidth;
+ e = e-e1; /* to make looping easier */
+ bit = mask[x1 & PIM];
+
+ if (!len)
+ return;
+ if (rop == RROP_BLACK)
+ {
+ if (axis == X_AXIS)
+ {
+ if (signdx > 0)
+ {
+ tmp = *addrl;
+ for (;;)
+ {
+ tmp &= ~bit;
+ if (!--len)
+ break;
+ bit = SCRRIGHT(bit,1);
+ e += e1;
+ if (e >= 0)
+ {
+ *addrl = tmp;
+ mfbScanlineInc(addrl, yinc);
+ e += e3;
+ if (!bit)
+ {
+ bit = leftbit;
+ addrl ++;
+ }
+ tmp = *addrl;
+ }
+ else if (!bit)
+ {
+ *addrl = tmp;
+ bit = leftbit;
+ addrl ++;
+ tmp = *addrl;
+ }
+ }
+ *addrl = tmp;
+ }
+ else
+ {
+ tmp = *addrl;
+ for (;;)
+ {
+ tmp &= ~bit;
+ if (!--len)
+ break;
+ e += e1;
+ bit = SCRLEFT(bit,1);
+ if (e >= 0)
+ {
+ *addrl = tmp;
+ mfbScanlineInc(addrl, yinc);
+ e += e3;
+ if (!bit)
+ {
+ bit = rightbit;
+ addrl --;
+ }
+ tmp = *addrl;
+ }
+ else if (!bit)
+ {
+ *addrl = tmp;
+ bit = rightbit;
+ addrl --;
+ tmp = *addrl;
+ }
+ }
+ *addrl = tmp;
+ }
+ } /* if X_AXIS */
+ else
+ {
+ if (signdx > 0)
+ {
+ while(len--)
+ {
+ *addrl &= ~bit;
+ e += e1;
+ if (e >= 0)
+ {
+ bit = SCRRIGHT(bit,1);
+ if (!bit) { bit = leftbit;addrl ++; }
+ e += e3;
+ }
+ mfbScanlineInc(addrl, yinc);
+ }
+ }
+ else
+ {
+ while(len--)
+ {
+ *addrl &= ~bit;
+ e += e1;
+ if (e >= 0)
+ {
+ bit = SCRLEFT(bit,1);
+ if (!bit) { bit = rightbit;addrl --; }
+ e += e3;
+ }
+ mfbScanlineInc(addrl, yinc);
+ }
+ }
+ } /* else Y_AXIS */
+ }
+ else if (rop == RROP_WHITE)
+ {
+ if (axis == X_AXIS)
+ {
+ if (signdx > 0)
+ {
+ tmp = *addrl;
+ for (;;)
+ {
+ tmp |= bit;
+ if (!--len)
+ break;
+ e += e1;
+ bit = SCRRIGHT(bit,1);
+ if (e >= 0)
+ {
+ *addrl = tmp;
+ mfbScanlineInc(addrl, yinc);
+ e += e3;
+ if (!bit)
+ {
+ bit = leftbit;
+ addrl ++;
+ }
+ tmp = *addrl;
+ }
+ else if (!bit)
+ {
+ *addrl = tmp;
+ bit = leftbit;
+ addrl ++;
+ tmp = *addrl;
+ }
+ }
+ *addrl = tmp;
+ }
+ else
+ {
+ tmp = *addrl;
+ for (;;)
+ {
+ tmp |= bit;
+ if (!--len)
+ break;
+ e += e1;
+ bit = SCRLEFT(bit,1);
+ if (e >= 0)
+ {
+ *addrl = tmp;
+ mfbScanlineInc(addrl, yinc);
+ e += e3;
+ if (!bit)
+ {
+ bit = rightbit;
+ addrl --;
+ }
+ tmp = *addrl;
+ }
+ else if (!bit)
+ {
+ *addrl = tmp;
+ bit = rightbit;
+ addrl --;
+ tmp = *addrl;
+ }
+ }
+ *addrl = tmp;
+ }
+ } /* if X_AXIS */
+ else
+ {
+ if (signdx > 0)
+ {
+ while(len--)
+ {
+ *addrl |= bit;
+ e += e1;
+ if (e >= 0)
+ {
+ bit = SCRRIGHT(bit,1);
+ if (!bit) { bit = leftbit;addrl ++; }
+ e += e3;
+ }
+ mfbScanlineInc(addrl, yinc);
+ }
+ }
+ else
+ {
+ while(len--)
+ {
+ *addrl |= bit;
+ e += e1;
+ if (e >= 0)
+ {
+ bit = SCRLEFT(bit,1);
+ if (!bit) { bit = rightbit;addrl --; }
+ e += e3;
+ }
+ mfbScanlineInc(addrl, yinc);
+ }
+ }
+ } /* else Y_AXIS */
+ }
+ else if (rop == RROP_INVERT)
+ {
+ if (axis == X_AXIS)
+ {
+ if (signdx > 0)
+ {
+ while(len--)
+ {
+ *addrl ^= bit;
+ e += e1;
+ if (e >= 0)
+ {
+ mfbScanlineInc(addrl, yinc);
+ e += e3;
+ }
+ bit = SCRRIGHT(bit,1);
+ if (!bit) { bit = leftbit;addrl ++; }
+ }
+ }
+ else
+ {
+ while(len--)
+ {
+ *addrl ^= bit;
+ e += e1;
+ if (e >= 0)
+ {
+ mfbScanlineInc(addrl, yinc);
+ e += e3;
+ }
+ bit = SCRLEFT(bit,1);
+ if (!bit) { bit = rightbit;addrl --; }
+ }
+ }
+ } /* if X_AXIS */
+ else
+ {
+ if (signdx > 0)
+ {
+ while(len--)
+ {
+ *addrl ^= bit;
+ e += e1;
+ if (e >= 0)
+ {
+ bit = SCRRIGHT(bit,1);
+ if (!bit) { bit = leftbit;addrl ++; }
+ e += e3;
+ }
+ mfbScanlineInc(addrl, yinc);
+ }
+ }
+ else
+ {
+ while(len--)
+ {
+ *addrl ^= bit;
+ e += e1;
+ if (e >= 0)
+ {
+ bit = SCRLEFT(bit,1);
+ if (!bit) { bit = rightbit; addrl --; }
+ e += e3;
+ }
+ mfbScanlineInc(addrl, yinc);
+ }
+ }
+ } /* else Y_AXIS */
+ }
+}
diff --git a/xc/programs/Xserver/mfb/mfbbresd.c b/xc/programs/Xserver/mfb/mfbbresd.c
new file mode 100644
index 000000000..6bfbaabe0
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbbresd.c
@@ -0,0 +1,200 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbbresd.c /main/11 1998/02/09 14:38:23 kaleb $ */
+#include "X.h"
+#include "misc.h"
+#include "mfb.h"
+#include "maskbits.h"
+#include "miline.h"
+
+/* Dashed bresenham line */
+
+#define StepDash\
+ if (!--dashRemaining) { \
+ if (++ dashIndex == numInDashList) \
+ dashIndex = 0; \
+ dashRemaining = pDash[dashIndex]; \
+ rop = fgrop; \
+ if (dashIndex & 1) \
+ rop = bgrop; \
+ }
+
+void
+mfbBresD(fgrop, bgrop,
+ pdashIndex, pDash, numInDashList, pdashOffset, isDoubleDash,
+ addrlbase, nlwidth,
+ signdx, signdy, axis, x1, y1, e, e1, e2, len)
+int fgrop, bgrop;
+int *pdashIndex; /* current dash */
+unsigned char *pDash; /* dash list */
+int numInDashList; /* total length of dash list */
+int *pdashOffset; /* offset into current dash */
+int isDoubleDash;
+PixelType *addrlbase; /* pointer to base of bitmap */
+int nlwidth; /* width in longwords of bitmap */
+int signdx, signdy; /* signs of directions */
+int axis; /* major axis (Y_AXIS or X_AXIS) */
+int x1, y1; /* initial point */
+register int e; /* error accumulator */
+register int e1; /* bresenham increments */
+int e2;
+int len; /* length of line */
+{
+ register int yinc; /* increment to next scanline, in bytes */
+ register PixelType *addrl;
+ register int e3 = e2-e1;
+ register unsigned long bit;
+ PixelType leftbit = mask[0]; /* leftmost bit to process in new word */
+ PixelType rightbit = mask[PPW-1]; /* rightmost bit to process in new word */
+ int dashIndex;
+ int dashOffset;
+ int dashRemaining;
+ int rop;
+
+ dashOffset = *pdashOffset;
+ dashIndex = *pdashIndex;
+ dashRemaining = pDash[dashIndex] - dashOffset;
+ rop = fgrop;
+ if (!isDoubleDash)
+ bgrop = -1;
+ if (dashIndex & 1)
+ rop = bgrop;
+
+ /* point to longword containing first point */
+ addrl = mfbScanline(addrlbase, x1, y1, nlwidth);
+ yinc = signdy * nlwidth;
+ e = e-e1; /* to make looping easier */
+ bit = mask[x1 & PIM];
+ if (axis == X_AXIS)
+ {
+ if (signdx > 0)
+ {
+ while(len--)
+ {
+ if (rop == RROP_BLACK)
+ *addrl &= ~bit;
+ else if (rop == RROP_WHITE)
+ *addrl |= bit;
+ else if (rop == RROP_INVERT)
+ *addrl ^= bit;
+ e += e1;
+ if (e >= 0)
+ {
+ mfbScanlineInc(addrl, yinc);
+ e += e3;
+ }
+ bit = SCRRIGHT(bit,1);
+ if (!bit) { bit = leftbit;addrl ++; }
+ StepDash
+ }
+ }
+ else
+ {
+ while(len--)
+ {
+ if (rop == RROP_BLACK)
+ *addrl &= ~bit;
+ else if (rop == RROP_WHITE)
+ *addrl |= bit;
+ else if (rop == RROP_INVERT)
+ *addrl ^= bit;
+ e += e1;
+ if (e >= 0)
+ {
+ mfbScanlineInc(addrl, yinc);
+ e += e3;
+ }
+ bit = SCRLEFT(bit,1);
+ if (!bit) { bit = rightbit;addrl --; }
+ StepDash
+ }
+ }
+ } /* if X_AXIS */
+ else
+ {
+ if (signdx > 0)
+ {
+ while(len--)
+ {
+ if (rop == RROP_BLACK)
+ *addrl &= ~bit;
+ else if (rop == RROP_WHITE)
+ *addrl |= bit;
+ else if (rop == RROP_INVERT)
+ *addrl ^= bit;
+ e += e1;
+ if (e >= 0)
+ {
+ bit = SCRRIGHT(bit,1);
+ if (!bit) { bit = leftbit;addrl ++; }
+ e += e3;
+ }
+ mfbScanlineInc(addrl, yinc);
+ StepDash
+ }
+ }
+ else
+ {
+ while(len--)
+ {
+ if (rop == RROP_BLACK)
+ *addrl &= ~bit;
+ else if (rop == RROP_WHITE)
+ *addrl |= bit;
+ else if (rop == RROP_INVERT)
+ *addrl ^= bit;
+ e += e1;
+ if (e >= 0)
+ {
+ bit = SCRLEFT(bit,1);
+ if (!bit) { bit = rightbit;addrl --; }
+ e += e3;
+ }
+ mfbScanlineInc(addrl, yinc);
+ StepDash
+ }
+ }
+ } /* else Y_AXIS */
+ *pdashIndex = dashIndex;
+ *pdashOffset = pDash[dashIndex] - dashRemaining;
+}
diff --git a/xc/programs/Xserver/mfb/mfbbstore.c b/xc/programs/Xserver/mfb/mfbbstore.c
new file mode 100644
index 000000000..993beb7f3
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbbstore.c
@@ -0,0 +1,147 @@
+/* $TOG: mfbbstore.c /main/14 1998/02/09 14:38:34 kaleb $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/*
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+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 "mfb.h"
+#include "X.h"
+#include "mibstore.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+
+/*-
+ *-----------------------------------------------------------------------
+ * mfbSaveAreas --
+ * Function called by miSaveAreas to actually fetch the areas to be
+ * saved into the backing pixmap. This is very simple to do, since
+ * mfbDoBitblt is designed for this very thing. The region to save is
+ * already destination-relative and we're given the offset to the
+ * window origin, so we have only to create an array of points of the
+ * u.l. corners of the boxes in the region translated to the screen
+ * coordinate system and fetch the screen pixmap out of its devPrivate
+ * field....
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Data are copied from the screen into the pixmap.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+mfbSaveAreas(pPixmap, prgnSave, xorg, yorg, pWin)
+ PixmapPtr pPixmap; /* Backing pixmap */
+ RegionPtr prgnSave; /* Region to save (pixmap-relative) */
+ int xorg; /* X origin of region */
+ int yorg; /* Y origin of region */
+ WindowPtr pWin;
+{
+ register DDXPointPtr pPt;
+ DDXPointPtr pPtsInit;
+ register BoxPtr pBox;
+ register int numRects;
+
+ numRects = REGION_NUM_RECTS(prgnSave);
+ pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(numRects * sizeof(DDXPointRec));
+ if (!pPtsInit)
+ return;
+
+ pBox = REGION_RECTS(prgnSave);
+ pPt = pPtsInit;
+ while (numRects--)
+ {
+ pPt->x = pBox->x1 + xorg;
+ pPt->y = pBox->y1 + yorg;
+ pPt++;
+ pBox++;
+ }
+
+ mfbDoBitblt((DrawablePtr)pPixmap->drawable.pScreen->devPrivate,
+ (DrawablePtr)pPixmap,
+ GXcopy,
+ prgnSave,
+ pPtsInit);
+
+ DEALLOCATE_LOCAL(pPtsInit);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * mfbRestoreAreas --
+ * Function called by miRestoreAreas to actually fetch the areas to be
+ * restored from the backing pixmap. This is very simple to do, since
+ * mfbDoBitblt is designed for this very thing. The region to restore is
+ * already destination-relative and we're given the offset to the
+ * window origin, so we have only to create an array of points of the
+ * u.l. corners of the boxes in the region translated to the pixmap
+ * coordinate system and fetch the screen pixmap out of its devPrivate
+ * field....
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Data are copied from the pixmap into the screen.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+mfbRestoreAreas(pPixmap, prgnRestore, xorg, yorg, pWin)
+ PixmapPtr pPixmap; /* Backing pixmap */
+ RegionPtr prgnRestore; /* Region to restore (screen-relative)*/
+ int xorg; /* X origin of window */
+ int yorg; /* Y origin of window */
+ WindowPtr pWin;
+{
+ register DDXPointPtr pPt;
+ DDXPointPtr pPtsInit;
+ register BoxPtr pBox;
+ register int numRects;
+
+ numRects = REGION_NUM_RECTS(prgnRestore);
+ pPtsInit = (DDXPointPtr)ALLOCATE_LOCAL(numRects*sizeof(DDXPointRec));
+ if (!pPtsInit)
+ return;
+
+ pBox = REGION_RECTS(prgnRestore);
+ pPt = pPtsInit;
+ while (numRects--)
+ {
+ pPt->x = pBox->x1 - xorg;
+ pPt->y = pBox->y1 - yorg;
+ pPt++;
+ pBox++;
+ }
+
+ mfbDoBitblt((DrawablePtr)pPixmap,
+ (DrawablePtr)pPixmap->drawable.pScreen->devPrivate,
+ GXcopy,
+ prgnRestore,
+ pPtsInit);
+
+ DEALLOCATE_LOCAL(pPtsInit);
+}
diff --git a/xc/programs/Xserver/mfb/mfbclip.c b/xc/programs/Xserver/mfb/mfbclip.c
new file mode 100644
index 000000000..d467797b4
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbclip.c
@@ -0,0 +1,266 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbclip.c,v 1.3 1999/04/11 13:11:12 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbclip.c /main/15 1998/02/09 14:38:38 kaleb $ */
+#include "X.h"
+#include "miscstruct.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "gc.h"
+#include "maskbits.h"
+#include "mi.h"
+#include "mfb.h"
+
+#define ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2) \
+if (((rx1) < (rx2)) && ((ry1) < (ry2)) && \
+ (!((reg)->data->numRects && \
+ ((r-1)->y1 == (ry1)) && \
+ ((r-1)->y2 == (ry2)) && \
+ ((r-1)->x1 <= (rx1)) && \
+ ((r-1)->x2 >= (rx2))))) \
+{ \
+ if ((reg)->data->numRects == (reg)->data->size) \
+ { \
+ miRectAlloc(reg, 1); \
+ fr = REGION_BOXPTR(reg); \
+ r = fr + (reg)->data->numRects; \
+ } \
+ r->x1 = (rx1); \
+ r->y1 = (ry1); \
+ r->x2 = (rx2); \
+ r->y2 = (ry2); \
+ (reg)->data->numRects++; \
+ if(r->x1 < (reg)->extents.x1) \
+ (reg)->extents.x1 = r->x1; \
+ if(r->x2 > (reg)->extents.x2) \
+ (reg)->extents.x2 = r->x2; \
+ r++; \
+}
+
+/* Convert bitmap clip mask into clipping region.
+ * First, goes through each line and makes boxes by noting the transitions
+ * from 0 to 1 and 1 to 0.
+ * Then it coalesces the current line with the previous if they have boxes
+ * at the same X coordinates.
+ */
+RegionPtr
+mfbPixmapToRegion(pPix)
+ PixmapPtr pPix;
+{
+ register RegionPtr pReg;
+ register PixelType *pw, w;
+ register int ib;
+ int width, h, base, rx1 = 0, crects;
+ PixelType *pwLineEnd;
+ int irectPrevStart, irectLineStart;
+ register BoxPtr prectO, prectN;
+ BoxPtr FirstRect, rects, prectLineStart;
+ Bool fInBox, fSame;
+ register PixelType mask0 = mask[0];
+ PixelType *pwLine;
+ int nWidth;
+
+ pReg = REGION_CREATE(pPix->drawable.pScreen, NULL, 1);
+ if(!pReg)
+ return NullRegion;
+ FirstRect = REGION_BOXPTR(pReg);
+ rects = FirstRect;
+
+ pwLine = (PixelType *) pPix->devPrivate.ptr;
+ nWidth = pPix->devKind / PGSZB;
+
+ width = pPix->drawable.width;
+ pReg->extents.x1 = width - 1;
+ pReg->extents.x2 = 0;
+ irectPrevStart = -1;
+ for(h = 0; h < pPix->drawable.height; h++)
+ {
+ pw = pwLine;
+ pwLine += nWidth;
+ irectLineStart = rects - FirstRect;
+ /* If the Screen left most bit of the word is set, we're starting in
+ * a box */
+ if(*pw & mask0)
+ {
+ fInBox = TRUE;
+ rx1 = 0;
+ }
+ else
+ fInBox = FALSE;
+ /* Process all words which are fully in the pixmap */
+ pwLineEnd = pw + (width >> PWSH);
+ for (base = 0; pw < pwLineEnd; base += PPW)
+ {
+ w = *pw++;
+ if (fInBox)
+ {
+ if (!~w)
+ continue;
+ }
+ else
+ {
+ if (!w)
+ continue;
+ }
+ for(ib = 0; ib < PPW; ib++)
+ {
+ /* If the Screen left most bit of the word is set, we're
+ * starting a box */
+ if(w & mask0)
+ {
+ if(!fInBox)
+ {
+ rx1 = base + ib;
+ /* start new box */
+ fInBox = TRUE;
+ }
+ }
+ else
+ {
+ if(fInBox)
+ {
+ /* end box */
+ ADDRECT(pReg, rects, FirstRect,
+ rx1, h, base + ib, h + 1);
+ fInBox = FALSE;
+ }
+ }
+ /* Shift the word VISUALLY left one. */
+ w = SCRLEFT(w, 1);
+ }
+ }
+ if(width & PIM)
+ {
+ /* Process final partial word on line */
+ w = *pw++;
+ for(ib = 0; ib < (width & PIM); ib++)
+ {
+ /* If the Screen left most bit of the word is set, we're
+ * starting a box */
+ if(w & mask0)
+ {
+ if(!fInBox)
+ {
+ rx1 = base + ib;
+ /* start new box */
+ fInBox = TRUE;
+ }
+ }
+ else
+ {
+ if(fInBox)
+ {
+ /* end box */
+ ADDRECT(pReg, rects, FirstRect,
+ rx1, h, base + ib, h + 1);
+ fInBox = FALSE;
+ }
+ }
+ /* Shift the word VISUALLY left one. */
+ w = SCRLEFT(w, 1);
+ }
+ }
+ /* If scanline ended with last bit set, end the box */
+ if(fInBox)
+ {
+ ADDRECT(pReg, rects, FirstRect,
+ rx1, h, base + (width & PIM), h + 1);
+ }
+ /* if all rectangles on this line have the same x-coords as
+ * those on the previous line, then add 1 to all the previous y2s and
+ * throw away all the rectangles from this line
+ */
+ fSame = FALSE;
+ if(irectPrevStart != -1)
+ {
+ crects = irectLineStart - irectPrevStart;
+ if(crects == ((rects - FirstRect) - irectLineStart))
+ {
+ prectO = FirstRect + irectPrevStart;
+ prectN = prectLineStart = FirstRect + irectLineStart;
+ fSame = TRUE;
+ while(prectO < prectLineStart)
+ {
+ if((prectO->x1 != prectN->x1) || (prectO->x2 != prectN->x2))
+ {
+ fSame = FALSE;
+ break;
+ }
+ prectO++;
+ prectN++;
+ }
+ if (fSame)
+ {
+ prectO = FirstRect + irectPrevStart;
+ while(prectO < prectLineStart)
+ {
+ prectO->y2 += 1;
+ prectO++;
+ }
+ rects -= crects;
+ pReg->data->numRects -= crects;
+ }
+ }
+ }
+ if(!fSame)
+ irectPrevStart = irectLineStart;
+ }
+ if (!pReg->data->numRects)
+ pReg->extents.x1 = pReg->extents.x2 = 0;
+ else
+ {
+ pReg->extents.y1 = REGION_BOXPTR(pReg)->y1;
+ pReg->extents.y2 = REGION_END(pReg)->y2;
+ if (pReg->data->numRects == 1)
+ {
+ xfree(pReg->data);
+ pReg->data = (RegDataPtr)NULL;
+ }
+ }
+#ifdef DEBUG
+ if (!miValidRegion(pReg))
+ FatalError("Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__);
+#endif
+ return(pReg);
+}
diff --git a/xc/programs/Xserver/mfb/mfbcmap.c b/xc/programs/Xserver/mfb/mfbcmap.c
new file mode 100644
index 000000000..609a6e7b9
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbcmap.c
@@ -0,0 +1,155 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbcmap.c,v 1.5 1998/11/22 10:37:42 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbcmap.c /main/13 1998/02/09 14:38:42 kaleb $ */
+#include "X.h"
+#include "scrnintstr.h"
+#include "colormapst.h"
+#include "resource.h"
+#include "micmap.h"
+
+/* A monochrome frame buffer is a static gray colormap with two entries.
+ * We have a "required list" of length 1. Because we can only support 1
+ * colormap, we never have to change it, but we may have to change the
+ * name we call it. If someone installs a new colormap, we know it must
+ * look just like the old one (because we've checked in dispatch that it was
+ * a valid colormap identifier, and all the colormap IDs for this device
+ * look the same). Nevertheless, we still have to uninstall the old colormap
+ * and install the new one. Similarly, if someone uninstalls a colormap,
+ * we have to install the default map, even though we know those two looked
+ * alike.
+ * The required list concept is pretty much irrelevant when you can only
+ * have one map installed at a time.
+ */
+
+int
+mfbListInstalledColormaps(pScreen, pmaps)
+ ScreenPtr pScreen;
+ Colormap *pmaps;
+{
+ return miListInstalledColormaps(pScreen, pmaps);
+}
+
+
+void
+mfbInstallColormap(pmap)
+ ColormapPtr pmap;
+{
+ miInstallColormap(pmap);
+}
+
+void
+mfbUninstallColormap(pmap)
+ ColormapPtr pmap;
+{
+ miUninstallColormap(pmap);
+}
+
+/*ARGSUSED*/
+void
+mfbResolveColor (pred, pgreen, pblue, pVisual)
+ unsigned short *pred;
+ unsigned short *pgreen;
+ unsigned short *pblue;
+ VisualPtr pVisual;
+{
+ /*
+ * Gets intensity from RGB. If intensity is >= half, pick white, else
+ * pick black. This may well be more trouble than it's worth.
+ */
+ *pred = *pgreen = *pblue =
+ (((30L * *pred +
+ 59L * *pgreen +
+ 11L * *pblue) >> 8) >= (((1<<8)-1)*50)) ? ~0 : 0;
+}
+
+Bool
+mfbCreateColormap(pMap)
+ ColormapPtr pMap;
+{
+ ScreenPtr pScreen;
+ unsigned short red0, green0, blue0;
+ unsigned short red1, green1, blue1;
+ Pixel pix;
+
+ pScreen = pMap->pScreen;
+ if (pScreen->whitePixel == 0)
+ {
+ red0 = green0 = blue0 = ~0;
+ red1 = green1 = blue1 = 0;
+ }
+ else
+ {
+ red0 = green0 = blue0 = 0;
+ red1 = green1 = blue1 = ~0;
+ }
+
+ /* this is a monochrome colormap, it only has two entries, just fill
+ * them in by hand. If it were a more complex static map, it would be
+ * worth writing a for loop or three to initialize it */
+
+ /* this will be pixel 0 */
+ pix = 0;
+ if (AllocColor(pMap, &red0, &green0, &blue0, &pix, 0) != Success)
+ return FALSE;
+
+ /* this will be pixel 1 */
+ if (AllocColor(pMap, &red1, &green1, &blue1, &pix, 0) != Success)
+ return FALSE;
+ return TRUE;
+}
+
+/*ARGSUSED*/
+void
+mfbDestroyColormap (pMap)
+ ColormapPtr pMap;
+{
+ return;
+}
+
+Bool
+mfbCreateDefColormap (pScreen)
+ ScreenPtr pScreen;
+{
+ return miCreateDefColormap(pScreen);
+}
diff --git a/xc/programs/Xserver/mfb/mfbfillarc.c b/xc/programs/Xserver/mfb/mfbfillarc.c
new file mode 100644
index 000000000..7caba00ac
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbfillarc.c
@@ -0,0 +1,325 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbfillarc.c,v 1.3 1998/10/04 09:39:09 dawes Exp $ */
+/************************************************************
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+********************************************************/
+
+/* $TOG: mfbfillarc.c /main/17 1998/02/09 14:38:46 kaleb $ */
+
+#include "X.h"
+#include "Xprotostr.h"
+#include "miscstruct.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "mfb.h"
+#include "maskbits.h"
+#include "mifillarc.h"
+#include "mi.h"
+
+static void
+mfbFillEllipseSolid(pDraw, arc, rop)
+ DrawablePtr pDraw;
+ xArc *arc;
+ register int rop;
+{
+ int x, y, e;
+ int yk, xk, ym, xm, dx, dy, xorg, yorg;
+ register int slw;
+ miFillArcRec info;
+ PixelType *addrlt, *addrlb;
+ register PixelType *addrl;
+ register int n;
+ int nlwidth;
+ register int xpos;
+ PixelType startmask, endmask;
+ int nlmiddle;
+
+ mfbGetPixelWidthAndPointer(pDraw, nlwidth, addrlt);
+ miFillArcSetup(arc, &info);
+ MIFILLARCSETUP();
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ addrlb = addrlt;
+ addrlt += nlwidth * (yorg - y);
+ addrlb += nlwidth * (yorg + y + dy);
+ while (y)
+ {
+ addrlt += nlwidth;
+ addrlb -= nlwidth;
+ MIFILLARCSTEP(slw);
+ if (!slw)
+ continue;
+ xpos = xorg - x;
+ addrl = mfbScanlineOffset(addrlt, (xpos >> PWSH));
+ if (((xpos & PIM) + slw) < PPW)
+ {
+ maskpartialbits(xpos, slw, startmask);
+ if (rop == RROP_BLACK)
+ *addrl &= ~startmask;
+ else if (rop == RROP_WHITE)
+ *addrl |= startmask;
+ else
+ *addrl ^= startmask;
+ if (miFillArcLower(slw))
+ {
+ addrl = mfbScanlineOffset(addrlb, (xpos >> PWSH));
+ if (rop == RROP_BLACK)
+ *addrl &= ~startmask;
+ else if (rop == RROP_WHITE)
+ *addrl |= startmask;
+ else
+ *addrl ^= startmask;
+ }
+ continue;
+ }
+ maskbits(xpos, slw, startmask, endmask, nlmiddle);
+ if (startmask)
+ {
+ if (rop == RROP_BLACK)
+ *addrl++ &= ~startmask;
+ else if (rop == RROP_WHITE)
+ *addrl++ |= startmask;
+ else
+ *addrl++ ^= startmask;
+ }
+ n = nlmiddle;
+ if (rop == RROP_BLACK)
+ while (n--)
+ *addrl++ = 0;
+ else if (rop == RROP_WHITE)
+ while (n--)
+ *addrl++ = ~0;
+ else
+ while (n--)
+ *addrl++ ^= ~0;
+ if (endmask)
+ {
+ if (rop == RROP_BLACK)
+ *addrl &= ~endmask;
+ else if (rop == RROP_WHITE)
+ *addrl |= endmask;
+ else
+ *addrl ^= endmask;
+ }
+ if (!miFillArcLower(slw))
+ continue;
+ addrl = mfbScanlineOffset(addrlb, (xpos >> PWSH));
+ if (startmask)
+ {
+ if (rop == RROP_BLACK)
+ *addrl++ &= ~startmask;
+ else if (rop == RROP_WHITE)
+ *addrl++ |= startmask;
+ else
+ *addrl++ ^= startmask;
+ }
+ n = nlmiddle;
+ if (rop == RROP_BLACK)
+ while (n--)
+ *addrl++ = 0;
+ else if (rop == RROP_WHITE)
+ while (n--)
+ *addrl++ = ~0;
+ else
+ while (n--)
+ *addrl++ ^= ~0;
+ if (endmask)
+ {
+ if (rop == RROP_BLACK)
+ *addrl &= ~endmask;
+ else if (rop == RROP_WHITE)
+ *addrl |= endmask;
+ else
+ *addrl ^= endmask;
+ }
+ }
+}
+
+#define FILLSPAN(xl,xr,addr) \
+ if (xr >= xl) \
+ { \
+ width = xr - xl + 1; \
+ addrl = mfbScanlineOffset(addr, (xl >> PWSH)); \
+ if (((xl & PIM) + width) < PPW) \
+ { \
+ maskpartialbits(xl, width, startmask); \
+ if (rop == RROP_BLACK) \
+ *addrl &= ~startmask; \
+ else if (rop == RROP_WHITE) \
+ *addrl |= startmask; \
+ else \
+ *addrl ^= startmask; \
+ } \
+ else \
+ { \
+ maskbits(xl, width, startmask, endmask, nlmiddle); \
+ if (startmask) \
+ { \
+ if (rop == RROP_BLACK) \
+ *addrl++ &= ~startmask; \
+ else if (rop == RROP_WHITE) \
+ *addrl++ |= startmask; \
+ else \
+ *addrl++ ^= startmask; \
+ } \
+ n = nlmiddle; \
+ if (rop == RROP_BLACK) \
+ while (n--) \
+ *addrl++ = 0; \
+ else if (rop == RROP_WHITE) \
+ while (n--) \
+ *addrl++ = ~0; \
+ else \
+ while (n--) \
+ *addrl++ ^= ~0; \
+ if (endmask) \
+ { \
+ if (rop == RROP_BLACK) \
+ *addrl &= ~endmask; \
+ else if (rop == RROP_WHITE) \
+ *addrl |= endmask; \
+ else \
+ *addrl ^= endmask; \
+ } \
+ } \
+ }
+
+#define FILLSLICESPANS(flip,addr) \
+ if (!flip) \
+ { \
+ FILLSPAN(xl, xr, addr); \
+ } \
+ else \
+ { \
+ xc = xorg - x; \
+ FILLSPAN(xc, xr, addr); \
+ xc += slw - 1; \
+ FILLSPAN(xl, xc, addr); \
+ }
+
+static void
+mfbFillArcSliceSolidCopy(pDraw, pGC, arc, rop)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ xArc *arc;
+ register int rop;
+{
+ register PixelType *addrl;
+ register int n;
+ int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
+ register int x, y, e;
+ miFillArcRec info;
+ miArcSliceRec slice;
+ int xl, xr, xc;
+ PixelType *addrlt, *addrlb;
+ int nlwidth;
+ int width;
+ PixelType startmask, endmask;
+ int nlmiddle;
+
+ mfbGetPixelWidthAndPointer(pDraw, nlwidth, addrlt);
+ miFillArcSetup(arc, &info);
+ miFillArcSliceSetup(arc, &slice, pGC);
+ MIFILLARCSETUP();
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ addrlb = addrlt;
+ addrlt = mfbScanlineDeltaNoBankSwitch(addrlt, yorg - y, nlwidth);
+ addrlb = mfbScanlineDeltaNoBankSwitch(addrlb, yorg + y + dy, nlwidth);
+ slice.edge1.x += pDraw->x;
+ slice.edge2.x += pDraw->x;
+ while (y > 0)
+ {
+ mfbScanlineIncNoBankSwitch(addrlt, nlwidth);
+ mfbScanlineIncNoBankSwitch(addrlb, -nlwidth);
+ MIFILLARCSTEP(slw);
+ MIARCSLICESTEP(slice.edge1);
+ MIARCSLICESTEP(slice.edge2);
+ if (miFillSliceUpper(slice))
+ {
+ MIARCSLICEUPPER(xl, xr, slice, slw);
+ FILLSLICESPANS(slice.flip_top, addrlt);
+ }
+ if (miFillSliceLower(slice))
+ {
+ MIARCSLICELOWER(xl, xr, slice, slw);
+ FILLSLICESPANS(slice.flip_bot, addrlb);
+ }
+ }
+}
+
+void
+mfbPolyFillArcSolid(pDraw, pGC, narcs, parcs)
+ register DrawablePtr pDraw;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ mfbPrivGC *priv;
+ register xArc *arc;
+ register int i;
+ BoxRec box;
+ int x2, y2;
+ RegionPtr cclip;
+ int rop;
+
+ priv = (mfbPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr;
+ rop = priv->rop;
+ if ((rop == RROP_NOP) || !(pGC->planemask & 1))
+ return;
+ cclip = pGC->pCompositeClip;
+ for (arc = parcs, i = narcs; --i >= 0; arc++)
+ {
+ if (miFillArcEmpty(arc))
+ continue;
+ if (miCanFillArc(arc))
+ {
+ box.x1 = arc->x + pDraw->x;
+ box.y1 = arc->y + pDraw->y;
+ /*
+ * Because box.x2 and box.y2 get truncated to 16 bits, and the
+ * RECT_IN_REGION test treats the resulting number as a signed
+ * integer, the RECT_IN_REGION test alone can go the wrong way.
+ * This can result in a server crash because the rendering
+ * routines in this file deal directly with cpu addresses
+ * of pixels to be stored, and do not clip or otherwise check
+ * that all such addresses are within their respective pixmaps.
+ * So we only allow the RECT_IN_REGION test to be used for
+ * values that can be expressed correctly in a signed short.
+ */
+ x2 = box.x1 + (int)arc->width + 1;
+ box.x2 = x2;
+ y2 = box.y1 + (int)arc->height + 1;
+ box.y2 = y2;
+ if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) &&
+ (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
+ {
+ if ((arc->angle2 >= FULLCIRCLE) ||
+ (arc->angle2 <= -FULLCIRCLE))
+ mfbFillEllipseSolid(pDraw, arc, rop);
+ else
+ mfbFillArcSliceSolidCopy(pDraw, pGC, arc, rop);
+ continue;
+ }
+ }
+ miPolyFillArc(pDraw, pGC, 1, arc);
+ }
+}
diff --git a/xc/programs/Xserver/mfb/mfbfillrct.c b/xc/programs/Xserver/mfb/mfbfillrct.c
new file mode 100644
index 000000000..9b0dcab37
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbfillrct.c
@@ -0,0 +1,221 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbfillrct.c,v 1.3 1998/10/04 09:39:09 dawes Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbfillrct.c /main/19 1998/02/09 14:38:50 kaleb $ */
+#include "X.h"
+#include "Xprotostr.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "miscstruct.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+
+#include "mfb.h"
+#include "maskbits.h"
+
+#define MODEQ(a, b) ((a) %= (b))
+void mfbPaintOddSize();
+
+/*
+ filled rectangles.
+ translate the rectangles, clip them, and call the
+helper function in the GC.
+*/
+
+#define NUM_STACK_RECTS 1024
+
+void
+mfbPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nrectFill; /* number of rectangles to fill */
+ xRectangle *prectInit; /* Pointer to first rectangle to fill */
+{
+ xRectangle *prect;
+ RegionPtr prgnClip;
+ register BoxPtr pbox;
+ register BoxPtr pboxClipped;
+ BoxPtr pboxClippedBase;
+ BoxPtr pextent;
+ BoxRec stackRects[NUM_STACK_RECTS];
+ int numRects;
+ int n;
+ int xorg, yorg;
+ mfbPrivGC *priv;
+ int alu;
+ void (* pfn) ();
+ PixmapPtr ppix;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ priv = (mfbPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr;
+ alu = priv->ropFillArea;
+ pfn = priv->FillArea;
+ ppix = pGC->pRotatedPixmap;
+ prgnClip = pGC->pCompositeClip;
+
+ prect = prectInit;
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+ if (xorg || yorg)
+ {
+ prect = prectInit;
+ n = nrectFill;
+ Duff (n, prect->x += xorg; prect->y += yorg; prect++);
+ }
+
+
+ prect = prectInit;
+
+ numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
+ if (numRects > NUM_STACK_RECTS)
+ {
+ pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
+ if (!pboxClippedBase)
+ return;
+ }
+ else
+ pboxClippedBase = stackRects;
+
+ pboxClipped = pboxClippedBase;
+
+ if (REGION_NUM_RECTS(prgnClip) == 1)
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_RECTS(prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ if ((pboxClipped->x1 = prect->x) < x1)
+ pboxClipped->x1 = x1;
+
+ if ((pboxClipped->y1 = prect->y) < y1)
+ pboxClipped->y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ pboxClipped->x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ pboxClipped->y2 = by2;
+
+ prect++;
+ if ((pboxClipped->x1 < pboxClipped->x2) &&
+ (pboxClipped->y1 < pboxClipped->y2))
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ else
+ {
+ int x1, y1, x2, y2, bx2, by2;
+
+ pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
+ x1 = pextent->x1;
+ y1 = pextent->y1;
+ x2 = pextent->x2;
+ y2 = pextent->y2;
+ while (nrectFill--)
+ {
+ BoxRec box;
+
+ if ((box.x1 = prect->x) < x1)
+ box.x1 = x1;
+
+ if ((box.y1 = prect->y) < y1)
+ box.y1 = y1;
+
+ bx2 = (int) prect->x + (int) prect->width;
+ if (bx2 > x2)
+ bx2 = x2;
+ box.x2 = bx2;
+
+ by2 = (int) prect->y + (int) prect->height;
+ if (by2 > y2)
+ by2 = y2;
+ box.y2 = by2;
+
+ prect++;
+
+ if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
+ continue;
+
+ n = REGION_NUM_RECTS (prgnClip);
+ pbox = REGION_RECTS(prgnClip);
+
+ /* clip the rectangle to each box in the clip region
+ this is logically equivalent to calling Intersect()
+ */
+ while(n--)
+ {
+ pboxClipped->x1 = max(box.x1, pbox->x1);
+ pboxClipped->y1 = max(box.y1, pbox->y1);
+ pboxClipped->x2 = min(box.x2, pbox->x2);
+ pboxClipped->y2 = min(box.y2, pbox->y2);
+ pbox++;
+
+ /* see if clipping left anything */
+ if(pboxClipped->x1 < pboxClipped->x2 &&
+ pboxClipped->y1 < pboxClipped->y2)
+ {
+ pboxClipped++;
+ }
+ }
+ }
+ }
+ if (pboxClipped != pboxClippedBase)
+ (*pfn) (pDrawable,pboxClipped-pboxClippedBase, pboxClippedBase, alu, ppix);
+ if (pboxClippedBase != stackRects)
+ DEALLOCATE_LOCAL(pboxClippedBase);
+}
diff --git a/xc/programs/Xserver/mfb/mfbfillsp.c b/xc/programs/Xserver/mfb/mfbfillsp.c
new file mode 100644
index 000000000..29769d8b4
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbfillsp.c
@@ -0,0 +1,1020 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbfillsp.c,v 1.5 1999/07/17 09:06:43 dawes Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbfillsp.c /main/26 1998/02/09 14:38:54 kaleb $ */
+#include "X.h"
+#include "Xmd.h"
+#include "gcstruct.h"
+#include "window.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "mfb.h"
+#include "maskbits.h"
+
+#include "mergerop.h"
+
+#include "servermd.h"
+#include "mi.h"
+#include "mispans.h"
+
+/* scanline filling for monochrome frame buffer
+ written by drewry, oct 1986
+
+ these routines all clip. they assume that anything that has called
+them has already translated the points (i.e. pGC->miTranslate is
+non-zero, which is howit gets set in mfbCreateGC().)
+
+ the number of new scnalines created by clipping ==
+MaxRectsPerBand * nSpans.
+
+ FillSolid is overloaded to be used for OpaqueStipple as well,
+if fgPixel == bgPixel.
+
+
+ FillTiled is overloaded to be used for OpaqueStipple, if
+fgPixel != bgPixel. based on the fill style, it uses
+{RotatedPixmap, gc.alu} or {RotatedPixmap, PrivGC.ropOpStip}
+*/
+
+
+void
+mfbBlackSolidFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *addrl;/* pointer to current longword in bitmap */
+ register int nlmiddle;
+ register PixelType startmask;
+ register PixelType endmask;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ while (n--)
+ {
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+
+ if (*pwidth)
+ {
+ if ( ((ppt->x & PIM) + *pwidth) < PPW)
+ {
+ /* all bits inside same longword */
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl &= ~startmask;
+ }
+ else
+ {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ &= ~startmask;
+ Duff (nlmiddle, *addrl++ = 0x0);
+ if (endmask)
+ *addrl &= ~endmask;
+ }
+ }
+ pwidth++;
+ ppt++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+
+
+void
+mfbWhiteSolidFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *addrl;/* pointer to current longword in bitmap */
+ register int nlmiddle;
+ register PixelType startmask;
+ register PixelType endmask;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ while (n--)
+ {
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+
+ if (*pwidth)
+ {
+ if ( ((ppt->x & PIM) + *pwidth) < PPW)
+ {
+ /* all bits inside same longword */
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl |= startmask;
+ }
+ else
+ {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ |= startmask;
+ Duff (nlmiddle, *addrl++ = ~0);
+ if (endmask)
+ *addrl |= endmask;
+ }
+ }
+ pwidth++;
+ ppt++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+
+
+void
+mfbInvertSolidFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *addrl;/* pointer to current longword in bitmap */
+ register int nlmiddle;
+ register PixelType startmask;
+ register PixelType endmask;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ while (n--)
+ {
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+
+ if (*pwidth)
+ {
+ if ( ((ppt->x & PIM) + *pwidth) < PPW)
+ {
+ /* all bits inside same longword */
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl ^= startmask;
+ }
+ else
+ {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ ^= startmask;
+ Duff (nlmiddle, *addrl++ ^= ~0);
+ if (endmask)
+ *addrl ^= endmask;
+ }
+ }
+ pwidth++;
+ ppt++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+
+void
+mfbWhiteStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *addrl;/* pointer to current longword in bitmap */
+ register PixelType src;
+ register int nlmiddle;
+ register PixelType startmask;
+ register PixelType endmask;
+ PixmapPtr pStipple;
+ PixelType *psrc;
+ int tileHeight;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ pStipple = pGC->pRotatedPixmap;
+ tileHeight = pStipple->drawable.height;
+ psrc = (PixelType *)(pStipple->devPrivate.ptr);
+
+ while (n--)
+ {
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+ src = psrc[ppt->y % tileHeight];
+
+ /* all bits inside same longword */
+ if ( ((ppt->x & PIM) + *pwidth) < PPW)
+ {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl |= (src & startmask);
+ }
+ else
+ {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ |= (src & startmask);
+ Duff (nlmiddle, *addrl++ |= src);
+ if (endmask)
+ *addrl |= (src & endmask);
+ }
+ pwidth++;
+ ppt++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+
+void
+mfbBlackStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *addrl; /* pointer to current longword in bitmap */
+ register PixelType src;
+ register int nlmiddle;
+ register PixelType startmask;
+ register PixelType endmask;
+ PixmapPtr pStipple;
+ PixelType *psrc;
+ int tileHeight;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ pStipple = pGC->pRotatedPixmap;
+ tileHeight = pStipple->drawable.height;
+ psrc = (PixelType *)(pStipple->devPrivate.ptr);
+
+ while (n--)
+ {
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+ src = psrc[ppt->y % tileHeight];
+
+ /* all bits inside same longword */
+ if ( ((ppt->x & PIM) + *pwidth) < PPW)
+ {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl &= ~(src & startmask);
+ }
+ else
+ {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ &= ~(src & startmask);
+ Duff (nlmiddle, *addrl++ &= ~src);
+ if (endmask)
+ *addrl &= ~(src & endmask);
+ }
+ pwidth++;
+ ppt++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+
+void
+mfbInvertStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *addrl; /* pointer to current longword in bitmap */
+ register PixelType src;
+ register int nlmiddle;
+ register PixelType startmask;
+ register PixelType endmask;
+ PixmapPtr pStipple;
+ PixelType *psrc;
+ int tileHeight;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ pStipple = pGC->pRotatedPixmap;
+ tileHeight = pStipple->drawable.height;
+ psrc = (PixelType *)(pStipple->devPrivate.ptr);
+
+ while (n--)
+ {
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+ src = psrc[ppt->y % tileHeight];
+
+ /* all bits inside same longword */
+ if ( ((ppt->x & PIM) + *pwidth) < PPW)
+ {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl ^= (src & startmask);
+ }
+ else
+ {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ *addrl++ ^= (src & startmask);
+ Duff(nlmiddle, *addrl++ ^= src);
+ if (endmask)
+ *addrl ^= (src & endmask);
+ }
+ pwidth++;
+ ppt++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+
+/* this works with tiles of width == PPW */
+#define FILLSPANPPW(ROP) \
+ while (n--) \
+ { \
+ if (*pwidth) \
+ { \
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth); \
+ src = psrc[ppt->y % tileHeight]; \
+ if ( ((ppt->x & PIM) + *pwidth) < PPW) \
+ { \
+ maskpartialbits(ppt->x, *pwidth, startmask); \
+ *addrl = (*addrl & ~startmask) | \
+ (ROP(src, *addrl) & startmask); \
+ } \
+ else \
+ { \
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); \
+ if (startmask) \
+ { \
+ *addrl = (*addrl & ~startmask) | \
+ (ROP(src, *addrl) & startmask); \
+ addrl++; \
+ } \
+ while (nlmiddle--) \
+ { \
+ *addrl = ROP(src, *addrl); \
+ addrl++; \
+ } \
+ if (endmask) \
+ *addrl = (*addrl & ~endmask) | \
+ (ROP(src, *addrl) & endmask); \
+ } \
+ } \
+ pwidth++; \
+ ppt++; \
+ }
+
+
+
+void
+mfbTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *addrl; /* pointer to current longword in bitmap */
+ register PixelType src;
+ register int nlmiddle;
+ register PixelType startmask;
+ register PixelType endmask;
+ PixmapPtr pTile;
+ PixelType *psrc;
+ int tileHeight;
+ int rop;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+ unsigned long flip;
+
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ pTile = pGC->pRotatedPixmap;
+ tileHeight = pTile->drawable.height;
+ psrc = (PixelType *)(pTile->devPrivate.ptr);
+ if (pGC->fillStyle == FillTiled)
+ rop = pGC->alu;
+ else
+ rop = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->ropOpStip;
+
+ flip = 0;
+ switch(rop)
+ {
+ case GXcopyInverted: /* for opaque stipples */
+ flip = ~0;
+ case GXcopy:
+ {
+
+#define DoMaskCopyRop(src,dst,mask) (((dst) & ~(mask)) | ((src) & (mask)))
+
+ while (n--)
+ {
+ if (*pwidth)
+ {
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+ src = psrc[ppt->y % tileHeight] ^ flip;
+ if ( ((ppt->x & PIM) + *pwidth) < PPW)
+ {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl = DoMaskCopyRop (src, *addrl, startmask);
+ }
+ else
+ {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ {
+ *addrl = DoMaskCopyRop (src, *addrl, startmask);
+ addrl++;
+ }
+ while (nlmiddle--)
+ {
+ *addrl = src;
+ addrl++;
+ }
+ if (endmask)
+ *addrl = DoMaskCopyRop (src, *addrl, endmask);
+ }
+ }
+ pwidth++;
+ ppt++;
+ }
+ }
+ break;
+ default:
+ {
+ register DeclareMergeRop ();
+
+ InitializeMergeRop(rop,~0);
+ while (n--)
+ {
+ if (*pwidth)
+ {
+ addrl = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+ src = psrc[ppt->y % tileHeight];
+ if ( ((ppt->x & PIM) + *pwidth) < PPW)
+ {
+ maskpartialbits(ppt->x, *pwidth, startmask);
+ *addrl = DoMaskMergeRop (src, *addrl, startmask);
+ }
+ else
+ {
+ maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
+ if (startmask)
+ {
+ *addrl = DoMaskMergeRop (src, *addrl, startmask);
+ addrl++;
+ }
+ while (nlmiddle--)
+ {
+ *addrl = DoMergeRop (src, *addrl);
+ addrl++;
+ }
+ if (endmask)
+ *addrl = DoMaskMergeRop (src, *addrl, endmask);
+ }
+ }
+ pwidth++;
+ ppt++;
+ }
+ }
+ break;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+
+/* Fill spans with tiles that aren't PPW bits wide */
+void
+mfbUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ int iline; /* first line of tile to use */
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *pdst;/* pointer to current word in bitmap */
+ register PixelType *psrc;/* pointer to current word in tile */
+ register int nlMiddle;
+ register int rop, nstart;
+ PixelType startmask;
+ PixmapPtr pTile; /* pointer to tile we want to fill with */
+ int w, width, x, xSrc, ySrc, srcStartOver, nend;
+ int tlwidth, rem, tileWidth, tileHeight, endinc;
+ PixelType endmask, *psrcT;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ if (pGC->fillStyle == FillTiled)
+ {
+ pTile = pGC->tile.pixmap;
+ tlwidth = pTile->devKind / PGSZB;
+ rop = pGC->alu;
+ }
+ else
+ {
+ pTile = pGC->stipple;
+ tlwidth = pTile->devKind / PGSZB;
+ rop = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->ropOpStip;
+ }
+
+ xSrc = pDrawable->x;
+ ySrc = pDrawable->y;
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ tileWidth = pTile->drawable.width;
+ tileHeight = pTile->drawable.height;
+
+ /* this replaces rotating the tile. Instead we just adjust the offset
+ * at which we start grabbing bits from the tile.
+ * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
+ * so that iline and rem always stay within the tile bounds.
+ */
+ xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
+ ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
+
+ while (n--)
+ {
+ iline = (ppt->y - ySrc) % tileHeight;
+ pdst = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+ psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
+ x = ppt->x;
+
+ if (*pwidth)
+ {
+ width = *pwidth;
+ while(width > 0)
+ {
+ psrc = psrcT;
+ w = min(tileWidth, width);
+ if((rem = (x - xSrc) % tileWidth) != 0)
+ {
+ /* if we're in the middle of the tile, get
+ as many bits as will finish the span, or
+ as many as will get to the left edge of the tile,
+ or a longword worth, starting at the appropriate
+ offset in the tile.
+ */
+ w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
+ endinc = rem / BITMAP_SCANLINE_PAD;
+ getandputrop((psrc+endinc), (rem&PIM), (x & PIM), w, pdst, rop);
+ if((x & PIM) + w >= PPW)
+ pdst++;
+ }
+ else if(((x & PIM) + w) < PPW)
+ {
+ /* doing < PPW bits is easy, and worth special-casing */
+ putbitsrop(*psrc, x & PIM, w, pdst, rop);
+ }
+ else
+ {
+ /* start at the left edge of the tile,
+ and put down as much as we can
+ */
+ maskbits(x, w, startmask, endmask, nlMiddle);
+
+ if (startmask)
+ nstart = PPW - (x & PIM);
+ else
+ nstart = 0;
+ if (endmask)
+ nend = (x + w) & PIM;
+ else
+ nend = 0;
+
+ srcStartOver = nstart > PLST;
+
+ if(startmask)
+ {
+ putbitsrop(*psrc, (x & PIM), nstart, pdst, rop);
+ pdst++;
+#ifdef __alpha__
+ /*
+ * XXX workaround an egcs 1.1.2 code generation
+ * bug. This version might actually be faster.
+ */
+ psrc += srcStartOver;
+#else
+ if(srcStartOver)
+ psrc++;
+#endif
+ }
+
+ while(nlMiddle--)
+ {
+ getandputrop0(psrc, nstart, PPW, pdst, rop);
+ pdst++;
+ psrc++;
+ }
+ if(endmask)
+ {
+ getandputrop0(psrc, nstart, nend, pdst, rop);
+ }
+ }
+ x += w;
+ width -= w;
+ }
+ }
+ ppt++;
+ pwidth++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
+
+
+/* Fill spans with stipples that aren't PPW bits wide */
+void
+mfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ /* next three parameters are post-clip */
+ int n; /* number of spans to fill */
+ register DDXPointPtr ppt; /* pointer to list of start points */
+ register int *pwidth; /* pointer to list of n widths */
+ int iline; /* first line of tile to use */
+ PixelType *addrlBase; /* pointer to start of bitmap */
+ int nlwidth; /* width in longwords of bitmap */
+ register PixelType *pdst; /* pointer to current word in bitmap */
+ register PixelType *psrc; /* pointer to current word in tile */
+ register int nlMiddle;
+ register int rop, nstart;
+ PixelType startmask;
+ PixmapPtr pTile; /* pointer to tile we want to fill with */
+ int w, width, x, xSrc, ySrc, srcStartOver, nend;
+ PixelType endmask, *psrcT;
+ int tlwidth, rem, tileWidth, endinc;
+ int tileHeight;
+ int *pwidthFree; /* copies of the pointers to free */
+ DDXPointPtr pptFree;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ n = nInit * miFindMaxBand(pGC->pCompositeClip);
+ pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
+ pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
+ if(!pptFree || !pwidthFree)
+ {
+ if (pptFree) DEALLOCATE_LOCAL(pptFree);
+ if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
+ return;
+ }
+ pwidth = pwidthFree;
+ ppt = pptFree;
+ n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
+ ppt, pwidth, fSorted);
+
+ pTile = pGC->stipple;
+ rop = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->rop;
+ tlwidth = pTile->devKind / PGSZB;
+ xSrc = pDrawable->x;
+ ySrc = pDrawable->y;
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ tileWidth = pTile->drawable.width;
+ tileHeight = pTile->drawable.height;
+
+ /* this replaces rotating the stipple. Instead, we just adjust the offset
+ * at which we start grabbing bits from the stipple.
+ * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
+ * so that iline and rem always stay within the tile bounds.
+ */
+ xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
+ ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
+ while (n--)
+ {
+ iline = (ppt->y - ySrc) % tileHeight;
+ pdst = mfbScanline(addrlBase, ppt->x, ppt->y, nlwidth);
+ psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
+ x = ppt->x;
+
+ if (*pwidth)
+ {
+ width = *pwidth;
+ while(width > 0)
+ {
+ psrc = psrcT;
+ w = min(tileWidth, width);
+ if((rem = (x - xSrc) % tileWidth) != 0)
+ {
+ /* if we're in the middle of the tile, get
+ as many bits as will finish the span, or
+ as many as will get to the left edge of the tile,
+ or a longword worth, starting at the appropriate
+ offset in the tile.
+ */
+ w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
+ endinc = rem / BITMAP_SCANLINE_PAD;
+ getandputrrop((psrc + endinc), (rem & PIM), (x & PIM),
+ w, pdst, rop)
+ if((x & PIM) + w >= PPW)
+ pdst++;
+ }
+
+ else if(((x & PIM) + w) < PPW)
+ {
+ /* doing < PPW bits is easy, and worth special-casing */
+ putbitsrrop(*psrc, x & PIM, w, pdst, rop);
+ }
+ else
+ {
+ /* start at the left edge of the tile,
+ and put down as much as we can
+ */
+ maskbits(x, w, startmask, endmask, nlMiddle);
+
+ if (startmask)
+ nstart = PPW - (x & PIM);
+ else
+ nstart = 0;
+ if (endmask)
+ nend = (x + w) & PIM;
+ else
+ nend = 0;
+
+ srcStartOver = nstart > PLST;
+
+ if(startmask)
+ {
+ putbitsrrop(*psrc, (x & PIM), nstart, pdst, rop);
+ pdst++;
+ if(srcStartOver)
+ psrc++;
+ }
+
+ while(nlMiddle--)
+ {
+ getandputrrop0(psrc, nstart, PPW, pdst, rop);
+ pdst++;
+ psrc++;
+ }
+ if(endmask)
+ {
+ getandputrrop0(psrc, nstart, nend, pdst, rop);
+ }
+ }
+ x += w;
+ width -= w;
+ }
+ }
+ ppt++;
+ pwidth++;
+ }
+ DEALLOCATE_LOCAL(pptFree);
+ DEALLOCATE_LOCAL(pwidthFree);
+}
diff --git a/xc/programs/Xserver/mfb/mfbfont.c b/xc/programs/Xserver/mfb/mfbfont.c
new file mode 100644
index 000000000..9a78d2e73
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbfont.c
@@ -0,0 +1,68 @@
+/*
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+*/
+/* $TOG: mfbfont.c /main/7 1998/02/09 14:38:59 kaleb $ */
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "mfb.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+
+/*ARGSUSED*/
+Bool
+mfbRealizeFont( pscr, pFont)
+ ScreenPtr pscr;
+ FontPtr pFont;
+{
+ return (TRUE);
+}
+
+/*ARGSUSED*/
+Bool
+mfbUnrealizeFont( pscr, pFont)
+ ScreenPtr pscr;
+ FontPtr pFont;
+{
+ return (TRUE);
+}
diff --git a/xc/programs/Xserver/mfb/mfbgc.c b/xc/programs/Xserver/mfb/mfbgc.c
new file mode 100644
index 000000000..48ebe38b0
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbgc.c
@@ -0,0 +1,1524 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbgc.c,v 1.5 1999/04/11 13:11:13 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbgc.c /main/56 1998/02/09 14:39:04 kaleb $ */
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "mfb.h"
+#include "dixfontstr.h"
+#include "fontstruct.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "region.h"
+
+#include "mistruct.h"
+#include "migc.h"
+
+#include "maskbits.h"
+
+static GCFuncs mfbFuncs = {
+ mfbValidateGC,
+ miChangeGC,
+ miCopyGC,
+ miDestroyGC,
+ miChangeClip,
+ miDestroyClip,
+ miCopyClip
+};
+
+#ifndef LOWMEMFTPT
+
+static GCOps whiteTECopyOps = {
+ mfbWhiteSolidFS,
+ mfbSetSpans,
+ mfbPutImage,
+ mfbCopyArea,
+ mfbCopyPlane,
+ mfbPolyPoint,
+ mfbLineSS,
+ mfbSegmentSS,
+ miPolyRectangle,
+ mfbZeroPolyArcSS,
+ mfbFillPolyWhite,
+ mfbPolyFillRect,
+ mfbPolyFillArcSolid,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ mfbTEGlyphBltWhite,
+ mfbPolyGlyphBltWhite,
+ mfbSolidPP
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps blackTECopyOps = {
+ mfbBlackSolidFS,
+ mfbSetSpans,
+ mfbPutImage,
+ mfbCopyArea,
+ mfbCopyPlane,
+ mfbPolyPoint,
+ mfbLineSS,
+ mfbSegmentSS,
+ miPolyRectangle,
+ mfbZeroPolyArcSS,
+ mfbFillPolyBlack,
+ mfbPolyFillRect,
+ mfbPolyFillArcSolid,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ mfbTEGlyphBltBlack,
+ mfbPolyGlyphBltBlack,
+ mfbSolidPP
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps whiteTEInvertOps = {
+ mfbInvertSolidFS,
+ mfbSetSpans,
+ mfbPutImage,
+ miCopyArea,
+ miCopyPlane,
+ mfbPolyPoint,
+ mfbLineSS,
+ mfbSegmentSS,
+ miPolyRectangle,
+ miZeroPolyArc,
+ mfbFillPolyInvert,
+ mfbPolyFillRect,
+ mfbPolyFillArcSolid,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ mfbTEGlyphBltWhite,
+ mfbPolyGlyphBltInvert,
+ mfbSolidPP
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps blackTEInvertOps = {
+ mfbInvertSolidFS,
+ mfbSetSpans,
+ mfbPutImage,
+ mfbCopyArea,
+ mfbCopyPlane,
+ mfbPolyPoint,
+ mfbLineSS,
+ mfbSegmentSS,
+ miPolyRectangle,
+ miZeroPolyArc,
+ mfbFillPolyInvert,
+ mfbPolyFillRect,
+ mfbPolyFillArcSolid,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ mfbTEGlyphBltBlack,
+ mfbPolyGlyphBltInvert,
+ mfbSolidPP
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps whiteCopyOps = {
+ mfbWhiteSolidFS,
+ mfbSetSpans,
+ mfbPutImage,
+ mfbCopyArea,
+ mfbCopyPlane,
+ mfbPolyPoint,
+ mfbLineSS,
+ mfbSegmentSS,
+ miPolyRectangle,
+ mfbZeroPolyArcSS,
+ mfbFillPolyWhite,
+ mfbPolyFillRect,
+ mfbPolyFillArcSolid,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ mfbImageGlyphBltWhite,
+ mfbPolyGlyphBltWhite,
+ mfbSolidPP
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps blackCopyOps = {
+ mfbBlackSolidFS,
+ mfbSetSpans,
+ mfbPutImage,
+ mfbCopyArea,
+ mfbCopyPlane,
+ mfbPolyPoint,
+ mfbLineSS,
+ mfbSegmentSS,
+ miPolyRectangle,
+ mfbZeroPolyArcSS,
+ mfbFillPolyBlack,
+ mfbPolyFillRect,
+ mfbPolyFillArcSolid,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ mfbImageGlyphBltBlack,
+ mfbPolyGlyphBltBlack,
+ mfbSolidPP
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps whiteInvertOps = {
+ mfbInvertSolidFS,
+ mfbSetSpans,
+ mfbPutImage,
+ mfbCopyArea,
+ mfbCopyPlane,
+ mfbPolyPoint,
+ mfbLineSS,
+ mfbSegmentSS,
+ miPolyRectangle,
+ miZeroPolyArc,
+ mfbFillPolyInvert,
+ mfbPolyFillRect,
+ mfbPolyFillArcSolid,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ mfbImageGlyphBltWhite,
+ mfbPolyGlyphBltInvert,
+ mfbSolidPP
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps blackInvertOps = {
+ mfbInvertSolidFS,
+ mfbSetSpans,
+ mfbPutImage,
+ mfbCopyArea,
+ mfbCopyPlane,
+ mfbPolyPoint,
+ mfbLineSS,
+ mfbSegmentSS,
+ miPolyRectangle,
+ miZeroPolyArc,
+ mfbFillPolyInvert,
+ mfbPolyFillRect,
+ mfbPolyFillArcSolid,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ mfbImageGlyphBltBlack,
+ mfbPolyGlyphBltInvert,
+ mfbSolidPP
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps whiteWhiteCopyOps = {
+ mfbWhiteSolidFS,
+ mfbSetSpans,
+ mfbPutImage,
+ mfbCopyArea,
+ mfbCopyPlane,
+ mfbPolyPoint,
+ mfbLineSS,
+ mfbSegmentSS,
+ miPolyRectangle,
+ mfbZeroPolyArcSS,
+ mfbFillPolyWhite,
+ mfbPolyFillRect,
+ mfbPolyFillArcSolid,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ miImageGlyphBlt,
+ mfbPolyGlyphBltWhite,
+ mfbSolidPP
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps blackBlackCopyOps = {
+ mfbBlackSolidFS,
+ mfbSetSpans,
+ mfbPutImage,
+ mfbCopyArea,
+ mfbCopyPlane,
+ mfbPolyPoint,
+ mfbLineSS,
+ mfbSegmentSS,
+ miPolyRectangle,
+ mfbZeroPolyArcSS,
+ mfbFillPolyBlack,
+ mfbPolyFillRect,
+ mfbPolyFillArcSolid,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ miImageGlyphBlt,
+ mfbPolyGlyphBltBlack,
+ mfbSolidPP
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps fgEqBgInvertOps = {
+ mfbInvertSolidFS,
+ mfbSetSpans,
+ mfbPutImage,
+ mfbCopyArea,
+ mfbCopyPlane,
+ mfbPolyPoint,
+ mfbLineSS,
+ mfbSegmentSS,
+ miPolyRectangle,
+ miZeroPolyArc,
+ mfbFillPolyInvert,
+ mfbPolyFillRect,
+ mfbPolyFillArcSolid,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ miImageGlyphBlt,
+ mfbPolyGlyphBltInvert,
+ mfbSolidPP
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+#else
+
+static GCOps whiteTECopyOps = {
+ mfbWhiteSolidFS,
+ mfbSetSpans,
+ miPutImage,
+ miCopyArea,
+ miCopyPlane,
+ miPolyPoint,
+ miZeroLine,
+ miPolySegment,
+ miPolyRectangle,
+ miZeroPolyArc,
+ mfbFillPolyWhite,
+ mfbPolyFillRect,
+ miPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ mfbTEGlyphBltWhite,
+ mfbPolyGlyphBltWhite,
+ miPushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps blackTECopyOps = {
+ mfbBlackSolidFS,
+ mfbSetSpans,
+ miPutImage,
+ miCopyArea,
+ miCopyPlane,
+ miPolyPoint,
+ miZeroLine,
+ miPolySegment,
+ miPolyRectangle,
+ miZeroPolyArc,
+ mfbFillPolyBlack,
+ mfbPolyFillRect,
+ miPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ mfbTEGlyphBltBlack,
+ mfbPolyGlyphBltBlack,
+ miPushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps whiteTEInvertOps = {
+ mfbInvertSolidFS,
+ mfbSetSpans,
+ miPutImage,
+ miCopyArea,
+ miCopyPlane,
+ miPolyPoint,
+ miZeroLine,
+ miPolySegment,
+ miPolyRectangle,
+ miZeroPolyArc,
+ mfbFillPolyInvert,
+ mfbPolyFillRect,
+ miPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ mfbTEGlyphBltWhite,
+ mfbPolyGlyphBltInvert,
+ miPushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps blackTEInvertOps = {
+ mfbInvertSolidFS,
+ mfbSetSpans,
+ miPutImage,
+ miCopyArea,
+ miCopyPlane,
+ miPolyPoint,
+ miZeroLine,
+ miPolySegment,
+ miPolyRectangle,
+ miZeroPolyArc,
+ mfbFillPolyInvert,
+ mfbPolyFillRect,
+ miPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ mfbTEGlyphBltBlack,
+ mfbPolyGlyphBltInvert,
+ miPushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps whiteCopyOps = {
+ mfbWhiteSolidFS,
+ mfbSetSpans,
+ miPutImage,
+ miCopyArea,
+ miCopyPlane,
+ miPolyPoint,
+ miZeroLine,
+ miPolySegment,
+ miPolyRectangle,
+ miZeroPolyArc,
+ mfbFillPolyWhite,
+ mfbPolyFillRect,
+ miPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ mfbImageGlyphBltWhite,
+ mfbPolyGlyphBltWhite,
+ miPushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps blackCopyOps = {
+ mfbBlackSolidFS,
+ mfbSetSpans,
+ miPutImage,
+ miCopyArea,
+ miCopyPlane,
+ miPolyPoint,
+ miZeroLine,
+ miPolySegment,
+ miPolyRectangle,
+ miZeroPolyArc,
+ mfbFillPolyBlack,
+ mfbPolyFillRect,
+ miPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ mfbImageGlyphBltBlack,
+ mfbPolyGlyphBltBlack,
+ miPushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps whiteInvertOps = {
+ mfbInvertSolidFS,
+ mfbSetSpans,
+ miPutImage,
+ miCopyArea,
+ miCopyPlane,
+ miPolyPoint,
+ miZeroLine,
+ miPolySegment,
+ miPolyRectangle,
+ miZeroPolyArc,
+ mfbFillPolyInvert,
+ mfbPolyFillRect,
+ miPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ mfbImageGlyphBltWhite,
+ mfbPolyGlyphBltInvert,
+ miPushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps blackInvertOps = {
+ mfbInvertSolidFS,
+ mfbSetSpans,
+ miPutImage,
+ miCopyArea,
+ miCopyPlane,
+ miPolyPoint,
+ miZeroLine,
+ miPolySegment,
+ miPolyRectangle,
+ miZeroPolyArc,
+ mfbFillPolyInvert,
+ mfbPolyFillRect,
+ miPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ mfbImageGlyphBltBlack,
+ mfbPolyGlyphBltInvert,
+ miPushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps whiteWhiteCopyOps = {
+ mfbWhiteSolidFS,
+ mfbSetSpans,
+ miPutImage,
+ miCopyArea,
+ miCopyPlane,
+ miPolyPoint,
+ miZeroLine,
+ miPolySegment,
+ miPolyRectangle,
+ miZeroPolyArc,
+ mfbFillPolyWhite,
+ mfbPolyFillRect,
+ miPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ miImageGlyphBlt,
+ mfbPolyGlyphBltWhite,
+ miPushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps blackBlackCopyOps = {
+ mfbBlackSolidFS,
+ mfbSetSpans,
+ miPutImage,
+ miCopyArea,
+ miCopyPlane,
+ miPolyPoint,
+ miZeroLine,
+ miPolySegment,
+ miPolyRectangle,
+ miZeroPolyArc,
+ mfbFillPolyBlack,
+ mfbPolyFillRect,
+ miPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ miImageGlyphBlt,
+ mfbPolyGlyphBltBlack,
+ miPushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+static GCOps fgEqBgInvertOps = {
+ mfbInvertSolidFS,
+ mfbSetSpans,
+ miPutImage,
+ miCopyArea,
+ miCopyPlane,
+ miPolyPoint,
+ miZeroLine,
+ miPolySegment,
+ miPolyRectangle,
+ miZeroPolyArc,
+ mfbFillPolyInvert,
+ mfbPolyFillRect,
+ miPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ miImageGlyphBlt,
+ mfbPolyGlyphBltInvert,
+ miPushPixels
+#ifdef NEED_LINEHELPER
+ ,NULL
+#endif
+};
+
+#endif /* ifndef LOWMEMFTPT */
+
+struct commonOps {
+ int fg, bg;
+ int rrop;
+ int terminalFont;
+ GCOps *ops;
+ void (*fillArea)();
+};
+
+static struct commonOps mfbCommonOps[] = {
+ { 1, 0, RROP_WHITE, 1, &whiteTECopyOps, mfbSolidWhiteArea },
+ { 0, 1, RROP_BLACK, 1, &blackTECopyOps, mfbSolidBlackArea },
+ { 1, 0, RROP_INVERT, 1, &whiteTEInvertOps, mfbSolidInvertArea },
+ { 0, 1, RROP_INVERT, 1, &blackTEInvertOps, mfbSolidInvertArea },
+ { 1, 0, RROP_WHITE, 0, &whiteCopyOps, mfbSolidWhiteArea },
+ { 0, 1, RROP_BLACK, 0, &blackCopyOps, mfbSolidBlackArea },
+ { 1, 0, RROP_INVERT, 0, &whiteInvertOps, mfbSolidInvertArea },
+ { 0, 1, RROP_INVERT, 0, &blackInvertOps, mfbSolidInvertArea },
+ { 1, 1, RROP_WHITE, 0, &whiteWhiteCopyOps, mfbSolidWhiteArea },
+ { 0, 0, RROP_BLACK, 0, &blackBlackCopyOps, mfbSolidBlackArea },
+ { 1, 1, RROP_INVERT, 0, &fgEqBgInvertOps, mfbSolidInvertArea },
+ { 0, 0, RROP_INVERT, 0, &fgEqBgInvertOps, mfbSolidInvertArea },
+};
+
+#define numberCommonOps (sizeof (mfbCommonOps) / sizeof (mfbCommonOps[0]))
+
+static GCOps *
+matchCommon (pGC)
+ GCPtr pGC;
+{
+ int i;
+ struct commonOps *cop;
+ mfbPrivGC *priv;
+
+ if (pGC->lineWidth != 0)
+ return 0;
+ if (pGC->lineStyle != LineSolid)
+ return 0;
+ if (pGC->fillStyle != FillSolid)
+ return 0;
+ if (!pGC->font ||
+ FONTMAXBOUNDS(pGC->font,rightSideBearing) -
+ FONTMINBOUNDS(pGC->font,leftSideBearing) > 32 ||
+ FONTMINBOUNDS(pGC->font,characterWidth) < 0)
+ return 0;
+ priv = (mfbPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr;
+ for (i = 0; i < numberCommonOps; i++) {
+ cop = &mfbCommonOps[i];
+ if ((pGC->fgPixel & 1) != cop->fg)
+ continue;
+ if ((pGC->bgPixel & 1) != cop->bg)
+ continue;
+ if (priv->rop != cop->rrop)
+ continue;
+ if (cop->terminalFont && !TERMINALFONT(pGC->font))
+ continue;
+ priv->FillArea = cop->fillArea;
+ return cop->ops;
+ }
+ return 0;
+}
+
+
+Bool
+mfbCreateGC(pGC)
+ register GCPtr pGC;
+{
+ mfbPrivGC *pPriv;
+
+ pGC->clientClip = NULL;
+ pGC->clientClipType = CT_NONE;
+
+ /* some of the output primitives aren't really necessary, since
+ they will be filled in ValidateGC because of dix/CreateGC()
+ setting all the change bits. Others are necessary because although
+ they depend on being a monochrome frame buffer, they don't change
+ */
+
+ pGC->ops = &whiteCopyOps;
+ pGC->funcs = &mfbFuncs;
+
+ /* mfb wants to translate before scan convesion */
+ pGC->miTranslate = 1;
+
+ pPriv = (mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr);
+ pPriv->rop = mfbReduceRop(pGC->alu, pGC->fgPixel);
+ pGC->fExpose = TRUE;
+ pGC->pRotatedPixmap = NullPixmap;
+ pGC->freeCompClip = FALSE;
+ pPriv->FillArea = mfbSolidInvertArea;
+ return TRUE;
+}
+
+/* Clipping conventions
+ if the drawable is a window
+ CT_REGION ==> pCompositeClip really is the composite
+ CT_other ==> pCompositeClip is the window clip region
+ if the drawable is a pixmap
+ CT_REGION ==> pCompositeClip is the translated client region
+ clipped to the pixmap boundary
+ CT_other ==> pCompositeClip is the pixmap bounding box
+*/
+
+/*ARGSUSED*/
+void
+mfbValidateGC(pGC, changes, pDrawable)
+ register GCPtr pGC;
+ unsigned long changes;
+ DrawablePtr pDrawable;
+{
+ register mfbPrivGCPtr devPriv;
+ int mask; /* stateChanges */
+ int index; /* used for stepping through bitfields */
+ int xrot, yrot; /* rotations for tile and stipple pattern */
+ int rrop; /* reduced rasterop */
+ /* flags for changing the proc vector
+ and updating things in devPriv
+ */
+ int new_rotate, new_rrop, new_line, new_text, new_fill;
+ DDXPointRec oldOrg; /* origin of thing GC was last used with */
+
+ oldOrg = pGC->lastWinOrg;
+
+ pGC->lastWinOrg.x = pDrawable->x;
+ pGC->lastWinOrg.y = pDrawable->y;
+
+ /* we need to re-rotate the tile if the previous window/pixmap
+ origin (oldOrg) differs from the new window/pixmap origin
+ (pGC->lastWinOrg)
+ */
+ new_rotate = (oldOrg.x != pGC->lastWinOrg.x) ||
+ (oldOrg.y != pGC->lastWinOrg.y);
+
+ devPriv = ((mfbPrivGCPtr) (pGC->devPrivates[mfbGCPrivateIndex].ptr));
+
+ /*
+ if the client clip is different or moved OR
+ the subwindowMode has changed OR
+ the window's clip has changed since the last validation
+ we need to recompute the composite clip
+ */
+ if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
+ (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
+ )
+ {
+ miComputeCompositeClip(pGC, pDrawable);
+ }
+
+ new_rrop = FALSE;
+ new_line = FALSE;
+ new_text = FALSE;
+ new_fill = FALSE;
+
+ mask = changes;
+ while (mask)
+ {
+ index = lowbit (mask);
+ mask &= ~index;
+
+ /* this switch acculmulates a list of which procedures
+ might have to change due to changes in the GC. in
+ some cases (e.g. changing one 16 bit tile for another)
+ we might not really need a change, but the code is
+ being paranoid.
+ this sort of batching wins if, for example, the alu
+ and the font have been changed, or any other pair
+ of items that both change the same thing.
+ */
+ switch (index)
+ {
+ case GCFunction:
+ case GCForeground:
+ new_rrop = TRUE;
+ break;
+ case GCPlaneMask:
+ break;
+ case GCBackground:
+ new_rrop = TRUE; /* for opaque stipples */
+ break;
+ case GCLineStyle:
+ case GCLineWidth:
+ case GCJoinStyle:
+ new_line = TRUE;
+ break;
+ case GCCapStyle:
+ break;
+ case GCFillStyle:
+ new_fill = TRUE;
+ break;
+ case GCFillRule:
+ break;
+ case GCTile:
+ if(pGC->tileIsPixel)
+ break;
+ new_rotate = TRUE;
+ new_fill = TRUE;
+ break;
+
+ case GCStipple:
+ if(pGC->stipple == (PixmapPtr)NULL)
+ break;
+ new_rotate = TRUE;
+ new_fill = TRUE;
+ break;
+
+ case GCTileStipXOrigin:
+ new_rotate = TRUE;
+ break;
+
+ case GCTileStipYOrigin:
+ new_rotate = TRUE;
+ break;
+
+ case GCFont:
+ new_text = TRUE;
+ break;
+ case GCSubwindowMode:
+ break;
+ case GCGraphicsExposures:
+ break;
+ case GCClipXOrigin:
+ break;
+ case GCClipYOrigin:
+ break;
+ case GCClipMask:
+ break;
+ case GCDashOffset:
+ break;
+ case GCDashList:
+ break;
+ case GCArcMode:
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* deal with the changes we've collected .
+ new_rrop must be done first because subsequent things
+ depend on it.
+ */
+
+ if(new_rotate || new_fill)
+ {
+ Bool new_pix = FALSE;
+
+ /* figure out how much to rotate */
+ xrot = pGC->patOrg.x;
+ yrot = pGC->patOrg.y;
+ xrot += pDrawable->x;
+ yrot += pDrawable->y;
+
+ switch (pGC->fillStyle)
+ {
+ case FillTiled:
+ /* copy current tile and stipple */
+ if (!pGC->tileIsPixel && (pGC->tile.pixmap->drawable.width <= PPW) &&
+ !(pGC->tile.pixmap->drawable.width & (pGC->tile.pixmap->drawable.width - 1)))
+ {
+ mfbCopyRotatePixmap(pGC->tile.pixmap,
+ &pGC->pRotatedPixmap, xrot, yrot);
+ new_pix = TRUE;
+ }
+ break;
+ case FillStippled:
+ case FillOpaqueStippled:
+ if (pGC->stipple && (pGC->stipple->drawable.width <= PPW) &&
+ !(pGC->stipple->drawable.width & (pGC->stipple->drawable.width - 1)))
+ {
+ mfbCopyRotatePixmap(pGC->stipple,
+ &pGC->pRotatedPixmap, xrot, yrot);
+ new_pix = TRUE;
+ }
+ }
+ /* destroy any previously rotated tile or stipple */
+ if (!new_pix && pGC->pRotatedPixmap)
+ {
+ (*pDrawable->pScreen->DestroyPixmap)(pGC->pRotatedPixmap);
+ pGC->pRotatedPixmap = (PixmapPtr)NULL;
+ }
+ }
+
+ /*
+ * duck out here when the GC is unchanged
+ */
+
+ if (!changes)
+ return;
+
+ if (new_rrop || new_fill)
+ {
+ rrop = mfbReduceRop(pGC->alu, pGC->fgPixel);
+ devPriv->rop = rrop;
+ new_fill = TRUE;
+ /* FillArea raster op is GC's for tile filling,
+ and the reduced rop for solid and stipple
+ */
+ if (pGC->fillStyle == FillTiled)
+ devPriv->ropFillArea = pGC->alu;
+ else
+ devPriv->ropFillArea = rrop;
+
+ /* opaque stipples:
+ fg bg ropOpStip fill style
+ 1 0 alu tile
+ 0 1 inverseAlu tile
+ 1 1 rrop(fg, alu) solid
+ 0 0 rrop(fg, alu) solid
+ Note that rrop(fg, alu) == mfbPrivGC.rop, so we don't really need to
+ compute it.
+ */
+ if (pGC->fillStyle == FillOpaqueStippled)
+ {
+ if ((pGC->fgPixel & 1) != (pGC->bgPixel & 1))
+ {
+ if (pGC->fgPixel & 1)
+ devPriv->ropOpStip = pGC->alu;
+ else
+ devPriv->ropOpStip = InverseAlu[pGC->alu];
+ }
+ else
+ devPriv->ropOpStip = rrop;
+ devPriv->ropFillArea = devPriv->ropOpStip;
+ }
+ }
+ else
+ rrop = devPriv->rop;
+
+ if (new_line || new_fill || new_text)
+ {
+ GCOps *newops;
+
+ if ((newops = matchCommon (pGC)))
+ {
+ if (pGC->ops->devPrivate.val)
+ miDestroyGCOps (pGC->ops);
+ pGC->ops = newops;
+ new_line = new_fill = new_text = 0;
+ }
+ else
+ {
+ if (!pGC->ops->devPrivate.val)
+ {
+ pGC->ops = miCreateGCOps (pGC->ops);
+ pGC->ops->devPrivate.val = 1;
+ }
+ }
+ }
+
+ if (new_line || new_fill)
+ {
+ if (pGC->lineWidth == 0)
+ {
+#ifndef LOWMEMFTPT
+ if ((pGC->lineStyle == LineSolid) && (pGC->fillStyle == FillSolid)
+ && ((rrop == RROP_WHITE) || (rrop == RROP_BLACK)))
+ pGC->ops->PolyArc = mfbZeroPolyArcSS;
+ else
+#endif /* ifndef LOWMEMFTPT */
+ pGC->ops->PolyArc = miZeroPolyArc;
+ }
+ else
+ pGC->ops->PolyArc = miPolyArc;
+ if (pGC->lineStyle == LineSolid)
+ {
+ if(pGC->lineWidth == 0)
+ {
+#ifndef LOWMEMFTPT
+ if (pGC->fillStyle == FillSolid)
+ {
+ pGC->ops->PolySegment = mfbSegmentSS;
+ pGC->ops->Polylines = mfbLineSS;
+ }
+ else
+#endif /* ifndef LOWMEMFTPT */
+ {
+ pGC->ops->PolySegment = miPolySegment;
+ pGC->ops->Polylines = miZeroLine;
+ }
+ }
+ else
+ {
+ pGC->ops->PolySegment = miPolySegment;
+ pGC->ops->Polylines = miWideLine;
+ }
+ }
+ else
+ {
+#ifndef LOWMEMFTPT
+ if(pGC->lineWidth == 0 && pGC->fillStyle == FillSolid)
+ {
+ pGC->ops->Polylines = mfbLineSD;
+ pGC->ops->PolySegment = mfbSegmentSD;
+ }
+ else
+#endif /* ifndef LOWMEMFTPT */
+ {
+ pGC->ops->Polylines = miWideDash;
+ pGC->ops->PolySegment = miPolySegment;
+ }
+ }
+ }
+
+ if (new_text || new_fill)
+ {
+ if ((pGC->font) &&
+ (FONTMAXBOUNDS(pGC->font,rightSideBearing) -
+ FONTMINBOUNDS(pGC->font,leftSideBearing) > 32 ||
+ FONTMINBOUNDS(pGC->font,characterWidth) < 0))
+ {
+ pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
+ pGC->ops->ImageGlyphBlt = miImageGlyphBlt;
+ }
+ else
+ {
+ /* special case ImageGlyphBlt for terminal emulator fonts */
+
+#ifndef LOWMEMFTPT
+
+ if ((pGC->font) &&
+ TERMINALFONT(pGC->font) &&
+ ((pGC->fgPixel & 1) != (pGC->bgPixel & 1)))
+ {
+ /* pcc bug makes this not compile...
+ pGC->ops->ImageGlyphBlt = (pGC->fgPixel & 1) ? mfbTEGlyphBltWhite :
+ mfbTEGlyphBltBlack;
+ */
+ if (pGC->fgPixel & 1)
+ pGC->ops->ImageGlyphBlt = mfbTEGlyphBltWhite;
+ else
+ pGC->ops->ImageGlyphBlt = mfbTEGlyphBltBlack;
+ }
+ else
+
+#endif /* ifndef LOWMEMFTPT */
+
+ {
+ if (pGC->fgPixel & 1)
+ pGC->ops->ImageGlyphBlt = mfbImageGlyphBltWhite;
+ else
+ pGC->ops->ImageGlyphBlt = mfbImageGlyphBltBlack;
+ }
+
+ /* now do PolyGlyphBlt */
+ if (pGC->fillStyle == FillSolid ||
+ (pGC->fillStyle == FillOpaqueStippled &&
+ (pGC->fgPixel & 1) == (pGC->bgPixel & 1)
+ )
+ )
+ {
+ if (rrop == RROP_WHITE)
+ pGC->ops->PolyGlyphBlt = mfbPolyGlyphBltWhite;
+ else if (rrop == RROP_BLACK)
+ pGC->ops->PolyGlyphBlt = mfbPolyGlyphBltBlack;
+ else if (rrop == RROP_INVERT)
+ pGC->ops->PolyGlyphBlt = mfbPolyGlyphBltInvert;
+ else
+ pGC->ops->PolyGlyphBlt = (void (*)())NoopDDA;
+ }
+ else
+ {
+ pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
+ }
+ }
+ }
+
+ if (new_fill)
+
+#ifndef LOWMEMFTPT
+
+ {
+ /* install a suitable fillspans and pushpixels */
+ pGC->ops->PushPixels = mfbPushPixels;
+ pGC->ops->FillPolygon = miFillPolygon;
+ if ((pGC->fillStyle == FillSolid) ||
+ ((pGC->fillStyle == FillOpaqueStippled) &&
+ ((pGC->fgPixel & 1) == (pGC->bgPixel & 1))))
+ {
+ pGC->ops->PushPixels = mfbSolidPP;
+ switch(devPriv->rop)
+ {
+ case RROP_WHITE:
+ pGC->ops->FillSpans = mfbWhiteSolidFS;
+ pGC->ops->FillPolygon = mfbFillPolyWhite;
+ break;
+ case RROP_BLACK:
+ pGC->ops->FillSpans = mfbBlackSolidFS;
+ pGC->ops->FillPolygon = mfbFillPolyBlack;
+ break;
+ case RROP_INVERT:
+ pGC->ops->FillSpans = mfbInvertSolidFS;
+ pGC->ops->FillPolygon = mfbFillPolyInvert;
+ break;
+ case RROP_NOP:
+ pGC->ops->FillSpans = (void (*)())NoopDDA;
+ pGC->ops->FillPolygon = (void (*)())NoopDDA;
+ break;
+ }
+ }
+ /* beyond this point, opaqueStippled ==> fg != bg */
+ else if (((pGC->fillStyle == FillTiled) ||
+ (pGC->fillStyle == FillOpaqueStippled)) &&
+ !pGC->pRotatedPixmap)
+ {
+ pGC->ops->FillSpans = mfbUnnaturalTileFS;
+ }
+ else if ((pGC->fillStyle == FillStippled) && !pGC->pRotatedPixmap)
+ {
+ pGC->ops->FillSpans = mfbUnnaturalStippleFS;
+ }
+ else if (pGC->fillStyle == FillStippled)
+ {
+ switch(devPriv->rop)
+ {
+ case RROP_WHITE:
+ pGC->ops->FillSpans = mfbWhiteStippleFS;
+ break;
+ case RROP_BLACK:
+ pGC->ops->FillSpans = mfbBlackStippleFS;
+ break;
+ case RROP_INVERT:
+ pGC->ops->FillSpans = mfbInvertStippleFS;
+ break;
+ case RROP_NOP:
+ pGC->ops->FillSpans = (void (*)())NoopDDA;
+ break;
+ }
+ }
+ else /* overload tiles to do parti-colored opaque stipples */
+ {
+ pGC->ops->FillSpans = mfbTileFS;
+ }
+ if (pGC->fillStyle == FillSolid)
+ pGC->ops->PolyFillArc = mfbPolyFillArcSolid;
+ else
+ pGC->ops->PolyFillArc = miPolyFillArc;
+ /* the rectangle code doesn't deal with opaque stipples that
+ are two colors -- we can fool it for fg==bg, though
+ */
+ if ((((pGC->fillStyle == FillTiled) ||
+ (pGC->fillStyle == FillStippled)) &&
+ !pGC->pRotatedPixmap) ||
+ ((pGC->fillStyle == FillOpaqueStippled) &&
+ ((pGC->fgPixel & 1) != (pGC->bgPixel & 1)))
+ )
+ {
+ pGC->ops->PolyFillRect = miPolyFillRect;
+ }
+ else /* deal with solids and natural stipples and tiles */
+ {
+ pGC->ops->PolyFillRect = mfbPolyFillRect;
+
+ if ((pGC->fillStyle == FillSolid) ||
+ ((pGC->fillStyle == FillOpaqueStippled) &&
+ ((pGC->fgPixel & 1) == (pGC->bgPixel & 1))))
+ {
+ switch(devPriv->rop)
+ {
+ case RROP_WHITE:
+ devPriv->FillArea = mfbSolidWhiteArea;
+ break;
+ case RROP_BLACK:
+ devPriv->FillArea = mfbSolidBlackArea;
+ break;
+ case RROP_INVERT:
+ devPriv->FillArea = mfbSolidInvertArea;
+ break;
+ case RROP_NOP:
+ devPriv->FillArea = (void (*)())NoopDDA;
+ break;
+ }
+ }
+ else if (pGC->fillStyle == FillStippled)
+ {
+ switch(devPriv->rop)
+ {
+ case RROP_WHITE:
+ devPriv->FillArea = mfbStippleWhiteArea;
+ break;
+ case RROP_BLACK:
+ devPriv->FillArea = mfbStippleBlackArea;
+ break;
+ case RROP_INVERT:
+ devPriv->FillArea = mfbStippleInvertArea;
+ break;
+ case RROP_NOP:
+ devPriv->FillArea = (void (*)())NoopDDA;
+ break;
+ }
+ }
+ else /* deal with tiles */
+ {
+ switch (pGC->alu)
+ {
+ case GXcopy:
+ devPriv->FillArea = mfbTileAreaPPWCopy;
+ break;
+ default:
+ devPriv->FillArea = mfbTileAreaPPWGeneral;
+ break;
+ }
+ }
+ } /* end of natural rectangles */
+ } /* end of new_fill */
+
+#else
+
+ {
+ /* install a suitable fillspans and pushpixels */
+ pGC->ops->PushPixels = miPushPixels;
+ pGC->ops->FillPolygon = miFillPolygon;
+ if ((pGC->fillStyle == FillSolid) ||
+ ((pGC->fillStyle == FillOpaqueStippled) &&
+ ((pGC->fgPixel & 1) == (pGC->bgPixel & 1))))
+ {
+ pGC->ops->PushPixels = miPushPixels;
+ switch(devPriv->rop)
+ {
+ case RROP_WHITE:
+ pGC->ops->FillSpans = mfbWhiteSolidFS;
+ pGC->ops->FillPolygon = mfbFillPolyWhite;
+ break;
+ case RROP_BLACK:
+ pGC->ops->FillSpans = mfbBlackSolidFS;
+ pGC->ops->FillPolygon = mfbFillPolyBlack;
+ break;
+ case RROP_INVERT:
+ pGC->ops->FillSpans = mfbInvertSolidFS;
+ pGC->ops->FillPolygon = mfbFillPolyInvert;
+ break;
+ case RROP_NOP:
+ pGC->ops->FillSpans = (void (*)())NoopDDA;
+ pGC->ops->FillPolygon = (void (*)())NoopDDA;
+ break;
+ }
+ }
+ /* beyond this point, opaqueStippled ==> fg != bg */
+ else if (((pGC->fillStyle == FillTiled) ||
+ (pGC->fillStyle == FillOpaqueStippled)) &&
+ !pGC->pRotatedPixmap)
+ {
+ pGC->ops->FillSpans = mfbUnnaturalTileFS;
+ }
+ else if ((pGC->fillStyle == FillStippled) && !pGC->pRotatedPixmap)
+ {
+ pGC->ops->FillSpans = mfbUnnaturalStippleFS;
+ }
+ else if (pGC->fillStyle == FillStippled)
+ {
+ switch(devPriv->rop)
+ {
+ case RROP_WHITE:
+ pGC->ops->FillSpans = mfbWhiteStippleFS;
+ case RROP_BLACK:
+ pGC->ops->FillSpans = mfbBlackStippleFS;
+ case RROP_INVERT:
+ pGC->ops->FillSpans = mfbInvertStippleFS;
+ case RROP_NOP:
+ pGC->ops->FillSpans = (void (*)())NoopDDA;
+ break;
+ }
+ }
+ else /* overload tiles to do parti-colored opaque stipples */
+ {
+ pGC->ops->FillSpans = mfbTileFS;
+ }
+ pGC->ops->PolyFillArc = miPolyFillArc;
+ /* the rectangle code doesn't deal with opaque stipples that
+ are two colors -- we can fool it for fg==bg, though
+ */
+ if ((((pGC->fillStyle == FillTiled) ||
+ (pGC->fillStyle == FillStippled)) &&
+ !pGC->pRotatedPixmap) ||
+ ((pGC->fillStyle == FillOpaqueStippled) &&
+ ((pGC->fgPixel & 1) != (pGC->bgPixel & 1)))
+ )
+ {
+ pGC->ops->PolyFillRect = miPolyFillRect;
+ }
+ else /* deal with solids and natural stipples and tiles */
+ {
+ pGC->ops->PolyFillRect = mfbPolyFillRect;
+
+ if ((pGC->fillStyle == FillSolid) ||
+ ((pGC->fillStyle == FillOpaqueStippled) &&
+ ((pGC->fgPixel & 1) == (pGC->bgPixel & 1))))
+ {
+ switch(devPriv->rop)
+ {
+ case RROP_WHITE:
+ devPriv->FillArea = mfbSolidWhiteArea;
+ break;
+ case RROP_BLACK:
+ devPriv->FillArea = mfbSolidBlackArea;
+ break;
+ case RROP_INVERT:
+ devPriv->FillArea = mfbSolidInvertArea;
+ break;
+ case RROP_NOP:
+ devPriv->FillArea = (void (*)())NoopDDA;
+ break;
+ }
+ }
+ else if (pGC->fillStyle == FillStippled)
+ {
+ switch(devPriv->rop)
+ {
+ case RROP_WHITE:
+ devPriv->FillArea = mfbStippleWhiteArea;
+ break;
+ case RROP_BLACK:
+ devPriv->FillArea = mfbStippleBlackArea;
+ break;
+ case RROP_INVERT:
+ devPriv->FillArea = mfbStippleInvertArea;
+ break;
+ case RROP_NOP:
+ devPriv->FillArea = (void (*)())NoopDDA;
+ break;
+ }
+ }
+ else /* deal with tiles */
+ {
+ switch (pGC->alu)
+ {
+ case GXcopy:
+ devPriv->FillArea = mfbTileAreaPPWCopy;
+ break;
+ default:
+ devPriv->FillArea = mfbTileAreaPPWGeneral;
+ break;
+ }
+ }
+ } /* end of natural rectangles */
+ } /* end of new_fill */
+
+#endif /* ifndef LOWMEMFTPT */
+
+}
+
+/* table to map alu(src, dst) to alu(~src, dst) */
+int InverseAlu[16] = {
+ GXclear,
+ GXandInverted,
+ GXnor,
+ GXcopyInverted,
+ GXand,
+ GXnoop,
+ GXequiv,
+ GXorInverted,
+ GXandReverse,
+ GXxor,
+ GXinvert,
+ GXnand,
+ GXcopy,
+ GXor,
+ GXorReverse,
+ GXset
+};
+
+int
+mfbReduceRop(alu, src)
+ register int alu;
+ register Pixel src;
+{
+ int rop = 0;
+ if ((src & 1) == 0) /* src is black */
+ {
+ switch(alu)
+ {
+ case GXclear:
+ rop = RROP_BLACK;
+ break;
+ case GXand:
+ rop = RROP_BLACK;
+ break;
+ case GXandReverse:
+ rop = RROP_BLACK;
+ break;
+ case GXcopy:
+ rop = RROP_BLACK;
+ break;
+ case GXandInverted:
+ rop = RROP_NOP;
+ break;
+ case GXnoop:
+ rop = RROP_NOP;
+ break;
+ case GXxor:
+ rop = RROP_NOP;
+ break;
+ case GXor:
+ rop = RROP_NOP;
+ break;
+ case GXnor:
+ rop = RROP_INVERT;
+ break;
+ case GXequiv:
+ rop = RROP_INVERT;
+ break;
+ case GXinvert:
+ rop = RROP_INVERT;
+ break;
+ case GXorReverse:
+ rop = RROP_INVERT;
+ break;
+ case GXcopyInverted:
+ rop = RROP_WHITE;
+ break;
+ case GXorInverted:
+ rop = RROP_WHITE;
+ break;
+ case GXnand:
+ rop = RROP_WHITE;
+ break;
+ case GXset:
+ rop = RROP_WHITE;
+ break;
+ }
+ }
+ else /* src is white */
+ {
+ switch(alu)
+ {
+ case GXclear:
+ rop = RROP_BLACK;
+ break;
+ case GXand:
+ rop = RROP_NOP;
+ break;
+ case GXandReverse:
+ rop = RROP_INVERT;
+ break;
+ case GXcopy:
+ rop = RROP_WHITE;
+ break;
+ case GXandInverted:
+ rop = RROP_BLACK;
+ break;
+ case GXnoop:
+ rop = RROP_NOP;
+ break;
+ case GXxor:
+ rop = RROP_INVERT;
+ break;
+ case GXor:
+ rop = RROP_WHITE;
+ break;
+ case GXnor:
+ rop = RROP_BLACK;
+ break;
+ case GXequiv:
+ rop = RROP_NOP;
+ break;
+ case GXinvert:
+ rop = RROP_INVERT;
+ break;
+ case GXorReverse:
+ rop = RROP_WHITE;
+ break;
+ case GXcopyInverted:
+ rop = RROP_BLACK;
+ break;
+ case GXorInverted:
+ rop = RROP_NOP;
+ break;
+ case GXnand:
+ rop = RROP_INVERT;
+ break;
+ case GXset:
+ rop = RROP_WHITE;
+ break;
+ }
+ }
+ return rop;
+}
diff --git a/xc/programs/Xserver/mfb/mfbgetsp.c b/xc/programs/Xserver/mfb/mfbgetsp.c
new file mode 100644
index 000000000..572959cb7
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbgetsp.c
@@ -0,0 +1,150 @@
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbgetsp.c /main/19 1998/02/09 14:39:09 kaleb $ */
+#include "X.h"
+#include "Xmd.h"
+
+#include "misc.h"
+#include "region.h"
+#include "gc.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+#include "mfb.h"
+#include "maskbits.h"
+
+#include "servermd.h"
+
+/* GetSpans -- for each span, gets bits from drawable starting at ppt[i]
+ * and continuing for pwidth[i] bits
+ * Each scanline returned will be server scanline padded, i.e., it will come
+ * out to an integral number of words.
+ */
+/*ARGSUSED*/
+void
+mfbGetSpans(pDrawable, wMax, ppt, pwidth, nspans, pchardstStart)
+ DrawablePtr pDrawable; /* drawable from which to get bits */
+ int wMax; /* largest value of all *pwidths */
+ register DDXPointPtr ppt; /* points to start copying from */
+ int *pwidth; /* list of number of bits to copy */
+ int nspans; /* number of scanlines to copy */
+ char *pchardstStart; /* where to put the bits */
+{
+ PixelType *pdstStart = (PixelType *)pchardstStart;
+ register PixelType *pdst; /* where to put the bits */
+ register PixelType *psrc; /* where to get the bits */
+ register PixelType tmpSrc; /* scratch buffer for bits */
+ PixelType *psrcBase; /* start of src bitmap */
+ int widthSrc; /* width of pixmap in bytes */
+ register DDXPointPtr pptLast; /* one past last point to get */
+ int xEnd; /* last pixel to copy from */
+ register int nstart;
+ int nend;
+ int srcStartOver;
+ PixelType startmask, endmask;
+ unsigned int srcBit;
+ int nlMiddle, nl;
+ int w;
+
+ pptLast = ppt + nspans;
+
+ mfbGetPixelWidthAndPointer(pDrawable, widthSrc, psrcBase);
+ pdst = pdstStart;
+
+ while(ppt < pptLast)
+ {
+ /* XXX should this really be << PWSH, or * 8, or * PGSZB? */
+ xEnd = min(ppt->x + *pwidth, widthSrc << PWSH);
+ pwidth++;
+ psrc = mfbScanline(psrcBase, ppt->x, ppt->y, widthSrc);
+ w = xEnd - ppt->x;
+ srcBit = ppt->x & PIM;
+
+ if (srcBit + w <= PPW)
+ {
+ getandputbits0(psrc, srcBit, w, pdst);
+ pdst++;
+ }
+ else
+ {
+
+ maskbits(ppt->x, w, startmask, endmask, nlMiddle);
+ if (startmask)
+ nstart = PPW - srcBit;
+ else
+ nstart = 0;
+ if (endmask)
+ nend = xEnd & PIM;
+ srcStartOver = srcBit + nstart > PLST;
+ if (startmask)
+ {
+ getandputbits0(psrc, srcBit, nstart, pdst);
+ if(srcStartOver)
+ psrc++;
+ }
+ nl = nlMiddle;
+#ifdef FASTPUTBITS
+ Duff(nl, putbits(*psrc, nstart, PPW, pdst); psrc++; pdst++;);
+#else
+ while (nl--)
+ {
+ tmpSrc = *psrc;
+ putbits(tmpSrc, nstart, PPW, pdst);
+ psrc++;
+ pdst++;
+ }
+#endif
+ if (endmask)
+ {
+ putbits(*psrc, nstart, nend, pdst);
+ if(nstart + nend > PPW)
+ pdst++;
+ }
+ if (startmask || endmask)
+ pdst++;
+ }
+ ppt++;
+ }
+}
diff --git a/xc/programs/Xserver/mfb/mfbhrzvert.c b/xc/programs/Xserver/mfb/mfbhrzvert.c
new file mode 100644
index 000000000..d815e2837
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbhrzvert.c
@@ -0,0 +1,171 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbhrzvert.c,v 1.3 1999/04/11 15:28:10 dawes Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbhrzvert.c /main/9 1998/02/09 14:39:14 kaleb $ */
+#include "X.h"
+
+#include "gc.h"
+#include "window.h"
+#include "pixmap.h"
+#include "region.h"
+
+#include "mfb.h"
+#include "maskbits.h"
+
+/* horizontal solid line
+ abs(len) > 1
+*/
+void
+mfbHorzS(rop, addrl, nlwidth, x1, y1, len)
+int rop; /* a reduced rasterop */
+register PixelType *addrl; /* pointer to base of bitmap */
+register int nlwidth; /* width in longwords of bitmap */
+int x1; /* initial point */
+int y1;
+int len; /* length of line */
+{
+ register PixelType startmask;
+ register PixelType endmask;
+ register int nlmiddle;
+
+
+ /* force the line to go left to right
+ but don't draw the last point
+ */
+ if (len < 0)
+ {
+ x1 += len;
+ x1 += 1;
+ len = -len;
+ }
+
+ addrl = mfbScanline(addrl, x1, y1, nlwidth);
+
+ /* all bits inside same longword */
+ if ( ((x1 & PIM) + len) < PPW)
+ {
+ maskpartialbits(x1, len, startmask);
+ if (rop == RROP_BLACK)
+ {
+ *addrl &= ~startmask;
+ }
+ else if (rop == RROP_WHITE)
+ {
+ *addrl |= startmask;
+ }
+ else if (rop == RROP_INVERT)
+ {
+ *addrl ^= startmask;
+ }
+ }
+ else
+ {
+ maskbits(x1, len, startmask, endmask, nlmiddle);
+ if (rop == RROP_BLACK)
+ {
+ if (startmask)
+ *addrl++ &= ~startmask;
+ Duff (nlmiddle, *addrl++ = 0x0);
+ if (endmask)
+ *addrl &= ~endmask;
+ }
+ else if (rop == RROP_WHITE)
+ {
+ if (startmask)
+ *addrl++ |= startmask;
+ Duff (nlmiddle, *addrl++ = ~0);
+ if (endmask)
+ *addrl |= endmask;
+ }
+ else if (rop == RROP_INVERT)
+ {
+ if (startmask)
+ *addrl++ ^= startmask;
+ Duff (nlmiddle, *addrl++ ^= ~0);
+ if (endmask)
+ *addrl ^= endmask;
+ }
+ }
+}
+
+/* vertical solid line
+ this uses do loops because pcc (Ultrix 1.2, bsd 4.2) generates
+ better code. sigh. we know that len will never be 0 or 1, so
+ it's OK to use it.
+*/
+
+void
+mfbVertS(rop, addrl, nlwidth, x1, y1, len)
+int rop; /* a reduced rasterop */
+register PixelType *addrl; /* pointer to base of bitmap */
+register int nlwidth; /* width in longwords of bitmap */
+int x1, y1; /* initial point */
+register int len; /* length of line */
+{
+ register PixelType bitmask;
+
+ addrl = mfbScanline(addrl, x1, y1, nlwidth);
+
+ if (len < 0)
+ {
+ nlwidth = -nlwidth;
+ len = -len;
+ }
+
+ if (rop == RROP_BLACK)
+ {
+ bitmask = rmask[x1 & PIM];
+ Duff(len, *addrl &= bitmask; mfbScanlineInc(addrl, nlwidth) );
+ }
+ else if (rop == RROP_WHITE)
+ {
+ bitmask = mask[x1 & PIM];
+ Duff(len, *addrl |= bitmask; mfbScanlineInc(addrl, nlwidth) );
+ }
+ else if (rop == RROP_INVERT)
+ {
+ bitmask = mask[x1 & PIM];
+ Duff(len, *addrl ^= bitmask; mfbScanlineInc(addrl, nlwidth) );
+ }
+}
diff --git a/xc/programs/Xserver/mfb/mfbimage.c b/xc/programs/Xserver/mfb/mfbimage.c
new file mode 100644
index 000000000..be2262ec8
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbimage.c
@@ -0,0 +1,169 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbimage.c,v 1.4 1999/04/11 13:11:14 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbimage.c /main/19 1998/02/09 14:39:19 kaleb $ */
+
+#include "X.h"
+
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+
+#include "mfb.h"
+#include "mi.h"
+#include "Xmd.h"
+
+#include "maskbits.h"
+
+#include "servermd.h"
+
+/* Put and Get images on a monochrome frame buffer
+ *
+ * we do this by creating a temporary pixmap and making its
+ * pointer to bits point to the buffer read in from the client.
+ * this works because of the padding rules specified at startup
+ *
+ * Note that CopyArea must know how to copy a bitmap into the server-format
+ * temporary pixmap.
+ *
+ * For speed, mfbPutImage should allocate the temporary pixmap on the stack.
+ *
+ * even though an XYBitmap and an XYPixmap have the same
+ * format (for this device), PutImage has different semantics for the
+ * two. XYPixmap just does the copy; XYBitmap takes gc.fgPixel for
+ * a 1 bit, gc.bgPixel for a 0 bit, which we notice is exactly
+ * like CopyPlane.
+ *
+ * written by drewry, september 1986
+ */
+
+
+
+/*ARGSUSED*/
+void
+mfbPutImage(dst, pGC, depth, x, y, w, h, leftPad, format, pImage)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int depth, x, y, w, h;
+ int leftPad;
+ int format;
+ char *pImage;
+{
+ PixmapPtr pPixmap;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ /* 0 may confuse CreatePixmap, and will sometimes be
+ passed by the mi text code
+ */
+ if ((w == 0) || (h == 0))
+ return;
+
+ pPixmap = GetScratchPixmapHeader(dst->pScreen, w+leftPad, h, 1, 1,
+ BitmapBytePad(w+leftPad), (pointer)pImage);
+ if (!pPixmap)
+ return;
+
+ pGC->fExpose = FALSE;
+ if (format != XYBitmap)
+ (*pGC->ops->CopyArea)((DrawablePtr)pPixmap, dst, pGC, leftPad, 0,
+ w, h, x, y);
+ else
+ (*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, dst, pGC, leftPad, 0,
+ w, h, x, y, 1);
+ pGC->fExpose = TRUE;
+ FreeScratchPixmapHeader(pPixmap);
+}
+
+
+/*
+ * pdstLine points to space allocated by caller, which he can do since
+ * he knows dimensions of the pixmap
+ * we can call mfbDoBitblt because the dispatcher has promised not to send us
+ * anything that would require going over the edge of the screen.
+ *
+ * XYPixmap and ZPixmap are the same for mfb.
+ * For any planemask with bit 0 == 0, just fill the dst with 0.
+ */
+/*ARGSUSED*/
+void
+mfbGetImage( pDrawable, sx, sy, w, h, format, planeMask, pdstLine)
+ DrawablePtr pDrawable;
+ int sx, sy, w, h;
+ unsigned int format;
+ unsigned long planeMask;
+ char *pdstLine;
+{
+ BoxRec box;
+ DDXPointRec ptSrc;
+ RegionRec rgnDst;
+
+ if (planeMask & 0x1)
+ {
+ ScreenPtr pScreen = pDrawable->pScreen;
+ PixmapPtr pPixmap;
+
+ pPixmap = GetScratchPixmapHeader(pScreen, w, h, /*depth*/ 1, /*bpp*/ 1,
+ BitmapBytePad(w), (pointer)pdstLine);
+ if (!pPixmap)
+ return;
+
+ ptSrc.x = sx + pDrawable->x;
+ ptSrc.y = sy + pDrawable->y;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = w;
+ box.y2 = h;
+ REGION_INIT(pScreen, &rgnDst, &box, 1);
+ mfbDoBitblt(pDrawable, (DrawablePtr)pPixmap,
+ GXcopy, &rgnDst, &ptSrc);
+ REGION_UNINIT(pScreen, &rgnDst);
+ FreeScratchPixmapHeader(pPixmap);
+ }
+ else
+ {
+ bzero(pdstLine, BitmapBytePad(w) * h);
+ }
+}
diff --git a/xc/programs/Xserver/mfb/mfbimggblt.c b/xc/programs/Xserver/mfb/mfbimggblt.c
new file mode 100644
index 000000000..b8760b6f6
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbimggblt.c
@@ -0,0 +1,439 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbimggblt.c,v 3.2 1998/10/04 09:39:11 dawes Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbimggblt.c /main/27 1998/02/09 14:39:23 kaleb $ */
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "mfb.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "maskbits.h"
+
+/*
+ we should eventually special-case fixed-width fonts for ImageText.
+
+ this works for fonts with glyphs <= 32 bits wide.
+
+ the clipping calculations are done for worst-case fonts.
+we make no assumptions about the heights, widths, or bearings
+of the glyphs. if we knew that the glyphs are all the same height,
+we could clip the tops and bottoms per clipping box, rather
+than per character per clipping box. if we knew that the glyphs'
+left and right bearings were wlle-behaved, we could clip a single
+character at the start, output until the last unclipped
+character, and then clip the last one. this is all straightforward
+to determine based on max-bounds and min-bounds from the font.
+ there is some inefficiency introduced in the per-character
+clipping to make what's going on clearer.
+
+ (it is possible, for example, for a font to be defined in which the
+next-to-last character in a font would be clipped out, but the last
+one wouldn't. the code below deals with this.)
+
+ Image text looks at the bits in the glyph and the fg and bg in the
+GC. it paints a rectangle, as defined in the protocol dcoument,
+and the paints the characters.
+
+ to avoid source proliferation, this file is compiled
+three times:
+ MFBIMAGEGLYPHBLT OPEQ
+ mfbImageGlyphBltWhite |=
+ mfbImageGlyphBltBlack &=~
+
+ the register allocations for startmask and endmask may not
+be the right thing. are there two other deserving candidates?
+xoff, pdst, pglyph, and tmpSrc seem like the right things, though.
+*/
+
+void
+MFBIMAGEGLYPHBLT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ pointer pglyphBase; /* start of array of glyphs */
+{
+ ExtentInfoRec info; /* used by QueryGlyphExtents() */
+ BoxRec bbox; /* string's bounding box */
+ xRectangle backrect;/* backing rectangle to paint.
+ in the general case, NOT necessarily
+ the same as the string's bounding box
+ */
+
+ CharInfoPtr pci;
+ int xorg, yorg; /* origin of drawable in bitmap */
+ int widthDst; /* width of dst in longwords */
+
+ /* these keep track of the character origin */
+ PixelType *pdstBase;
+ /* points to longword with character origin */
+ int xchar; /* xorigin of char (mod 32) */
+
+ /* these are used for placing the glyph */
+ register int xoff; /* x offset of left edge of glyph (mod 32) */
+ register PixelType *pdst;
+ /* pointer to current longword in dst */
+
+ int w; /* width of glyph in bits */
+ int h; /* height of glyph */
+ int widthGlyph; /* width of glyph, in bytes */
+ register unsigned char *pglyph;
+ /* pointer to current row of glyph */
+
+ /* used for putting down glyph */
+ register PixelType tmpSrc;
+ /* for getting bits from glyph */
+ register PixelType startmask;
+ register PixelType endmask;
+
+ register int nFirst;/* bits of glyph in current longword */
+ void (* oldFillArea)();
+ /* we might temporarily usurp this
+ field in devPriv */
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+ mfbGetPixelWidthAndPointer(pDrawable, widthDst, pdstBase);
+
+ QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info);
+
+ backrect.x = x;
+ backrect.y = y - FONTASCENT(pGC->font);
+ backrect.width = info.overallWidth;
+ backrect.height = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+
+ x += xorg;
+ y += yorg;
+
+ bbox.x1 = x + info.overallLeft;
+ bbox.x2 = x + info.overallRight;
+ bbox.y1 = y - info.overallAscent;
+ bbox.y2 = y + info.overallDescent;
+
+ /* UNCLEAN CODE
+ we know the mfbPolyFillRect uses only two fields in
+ devPrivate[mfbGCPrivateIndex].ptr, one of which (ropFillArea) is
+ irrelevant for solid filling, so we just poke the FillArea
+ field. the GC is now in an inconsistent state, but we'll fix
+ it as soon as PolyFillRect returns. fortunately, the server
+ is single threaded.
+
+ NOTE:
+ if you are not using the standard mfbFillRectangle code, you
+ need to poke any fields in the GC the rectangle stuff need
+ (probably alu, fgPixel, and fillStyle) and in devPrivate[mfbGCPrivateIndex].ptr
+ (probably rop or ropFillArea.) You could just call ValidateGC,
+ but that is usually not a cheap thing to do.
+ */
+
+ oldFillArea = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->FillArea;
+
+/* pcc doesn't like this. why?
+ ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->FillArea =
+ ((pGC->bgPixel & 1) ? mfbSolidWhiteArea : mfbSolidBlackArea);
+*/
+ if (pGC->bgPixel & 1)
+ ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->FillArea = mfbSolidWhiteArea;
+ else
+ ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->FillArea = mfbSolidBlackArea;
+
+#ifndef LOWMEMFTPT
+ mfbPolyFillRect(pDrawable, pGC, 1, &backrect);
+#else
+ miPolyFillRect(pDrawable, pGC, 1, &backrect);
+#endif
+ ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->FillArea = oldFillArea;
+
+ /* the faint-hearted can open their eyes now */
+ switch (RECT_IN_REGION(pGC->pScreen, pGC->pCompositeClip, &bbox))
+ {
+ case rgnOUT:
+ break;
+ case rgnIN:
+ pdstBase = mfbScanlineNoBankSwitch(pdstBase, x, y, widthDst);
+ xchar = x & PIM;
+
+ while(nglyph--)
+ {
+ pci = *ppci;
+ pglyph = FONTGLYPHBITS(pglyphBase, pci);
+ w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ h = pci->metrics.ascent + pci->metrics.descent;
+ widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
+
+ /* start at top scanline of glyph */
+ pdst = pdstBase;
+
+ /* find correct word in scanline and x offset within it
+ for left edge of glyph
+ */
+ xoff = xchar + pci->metrics.leftSideBearing;
+ if (xoff > PLST)
+ {
+ pdst++;
+ xoff &= PIM;
+ }
+ else if (xoff < 0)
+ {
+ xoff += PPW;
+ pdst--;
+ }
+
+ pdst = mfbScanlineDelta(pdst, -pci->metrics.ascent, widthDst);
+
+ if ((xoff + w) <= PPW)
+ {
+ /* glyph all in one longword */
+ maskpartialbits(xoff, w, startmask);
+ while (h--)
+ {
+ getleftbits(pglyph, w, tmpSrc);
+ *pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
+ pglyph += widthGlyph;
+ mfbScanlineInc(pdst, widthDst);
+ }
+ }
+ else
+ {
+ /* glyph crosses longword boundary */
+ maskPPWbits(xoff, w, startmask, endmask);
+ nFirst = PPW - xoff;
+ while (h--)
+ {
+ getleftbits(pglyph, w, tmpSrc);
+ *pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
+ *(pdst+1) OPEQ (SCRLEFT(tmpSrc, nFirst) & endmask);
+ pglyph += widthGlyph;
+ mfbScanlineInc(pdst, widthDst);
+ }
+ } /* glyph crosses longwords boundary */
+
+ /* update character origin */
+ x += pci->metrics.characterWidth;
+ xchar += pci->metrics.characterWidth;
+ if (xchar > PLST)
+ {
+ xchar -= PPW;
+ pdstBase++;
+ }
+ else if (xchar < 0)
+ {
+ xchar += PPW;
+ pdstBase--;
+ }
+ ppci++;
+ } /* while nglyph-- */
+ break;
+ case rgnPART:
+ {
+ TEXTPOS *ppos;
+ int nbox;
+ BoxPtr pbox;
+ RegionPtr cclip;
+ int xpos; /* x position of char origin */
+ int i;
+ BoxRec clip;
+ int leftEdge, rightEdge;
+ int topEdge, bottomEdge;
+ int glyphRow; /* first row of glyph not wholly
+ clipped out */
+ int glyphCol; /* leftmost visible column of glyph */
+ int getWidth; /* bits to get from glyph */
+
+ if(!(ppos = (TEXTPOS *)ALLOCATE_LOCAL(nglyph * sizeof(TEXTPOS))))
+ return;
+
+ pdstBase = mfbScanlineNoBankSwitch(pdstBase, x, y, widthDst);
+ xpos = x;
+ xchar = xpos & PIM;
+
+ for (i=0; i<nglyph; i++)
+ {
+ pci = ppci[i];
+
+ ppos[i].xpos = xpos;
+ ppos[i].xchar = xchar;
+ ppos[i].leftEdge = xpos + pci->metrics.leftSideBearing;
+ ppos[i].rightEdge = xpos + pci->metrics.rightSideBearing;
+ ppos[i].topEdge = y - pci->metrics.ascent;
+ ppos[i].bottomEdge = y + pci->metrics.descent;
+ ppos[i].pdstBase = pdstBase;
+ ppos[i].widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
+
+ xpos += pci->metrics.characterWidth;
+ xchar += pci->metrics.characterWidth;
+ if (xchar > PLST)
+ {
+ xchar &= PIM;
+ pdstBase++;
+ }
+ else if (xchar < 0)
+ {
+ xchar += PPW;
+ pdstBase--;
+ }
+ }
+
+ cclip = pGC->pCompositeClip;
+ pbox = REGION_RECTS(cclip);
+ nbox = REGION_NUM_RECTS(cclip);
+
+ /* HACK ALERT
+ since we continue out of the loop below so often, it
+ is easier to increment pbox at the top than at the end.
+ don't try this at home.
+ */
+ pbox--;
+ while(nbox--)
+ {
+ pbox++;
+ clip.x1 = max(bbox.x1, pbox->x1);
+ clip.y1 = max(bbox.y1, pbox->y1);
+ clip.x2 = min(bbox.x2, pbox->x2);
+ clip.y2 = min(bbox.y2, pbox->y2);
+ if ((clip.x2<=clip.x1) || (clip.y2<=clip.y1))
+ continue;
+
+ for(i=0; i<nglyph; i++)
+ {
+ pci = ppci[i];
+ xchar = ppos[i].xchar;
+
+ /* clip the left and right edges */
+ if (ppos[i].leftEdge < clip.x1)
+ leftEdge = clip.x1;
+ else
+ leftEdge = ppos[i].leftEdge;
+
+ if (ppos[i].rightEdge > clip.x2)
+ rightEdge = clip.x2;
+ else
+ rightEdge = ppos[i].rightEdge;
+
+ w = rightEdge - leftEdge;
+ if (w <= 0)
+ continue;
+
+ /* clip the top and bottom edges */
+ if (ppos[i].topEdge < clip.y1)
+ topEdge = clip.y1;
+ else
+ topEdge = ppos[i].topEdge;
+
+ if (ppos[i].bottomEdge > clip.y2)
+ bottomEdge = clip.y2;
+ else
+ bottomEdge = ppos[i].bottomEdge;
+
+ h = bottomEdge - topEdge;
+ if (h <= 0)
+ continue;
+
+ glyphRow = (topEdge - y) + pci->metrics.ascent;
+ widthGlyph = ppos[i].widthGlyph;
+ pglyph = FONTGLYPHBITS(pglyphBase, pci);
+ pglyph += (glyphRow * widthGlyph);
+
+ pdst = ppos[i].pdstBase;
+
+ glyphCol = (leftEdge - ppos[i].xpos) -
+ (pci->metrics.leftSideBearing);
+ getWidth = w + glyphCol;
+ xoff = xchar + (leftEdge - ppos[i].xpos);
+ if (xoff > PLST)
+ {
+ xoff &= PIM;
+ pdst++;
+ }
+ else if (xoff < 0)
+ {
+ xoff += PPW;
+ pdst--;
+ }
+
+ pdst = mfbScanlineDelta(pdst, -(y-topEdge), widthDst);
+
+ if ((xoff + w) <= PPW)
+ {
+ maskpartialbits(xoff, w, startmask);
+ while (h--)
+ {
+ getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
+ *pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
+ pglyph += widthGlyph;
+ mfbScanlineInc(pdst, widthDst);
+ }
+ }
+ else
+ {
+ maskPPWbits(xoff, w, startmask, endmask);
+ nFirst = PPW - xoff;
+ while (h--)
+ {
+ getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
+ *pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
+ *(pdst+1) OPEQ (SCRLEFT(tmpSrc, nFirst) & endmask);
+ pglyph += widthGlyph;
+ mfbScanlineInc(pdst, widthDst);
+ }
+ }
+ } /* for each glyph */
+ } /* while nbox-- */
+ DEALLOCATE_LOCAL(ppos);
+ break;
+ }
+ default:
+ break;
+ }
+}
diff --git a/xc/programs/Xserver/mfb/mfbline.c b/xc/programs/Xserver/mfb/mfbline.c
new file mode 100644
index 000000000..e30160a11
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbline.c
@@ -0,0 +1,749 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbline.c,v 1.4 1999/04/11 13:11:14 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbline.c /main/28 1998/02/09 14:39:27 kaleb $ */
+#include "X.h"
+
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "mistruct.h"
+
+#include "mfb.h"
+#include "maskbits.h"
+#include "miline.h"
+
+/* single-pixel lines on a color frame buffer
+
+ NON-SLOPED LINES
+ horizontal lines are always drawn left to right; we have to
+move the endpoints right by one after they're swapped.
+ horizontal lines will be confined to a single band of a
+region. the code finds that band (giving up if the lower
+bound of the band is above the line we're drawing); then it
+finds the first box in that band that contains part of the
+line. we clip the line to subsequent boxes in that band.
+ vertical lines are always drawn top to bottom (y-increasing.)
+this requires adding one to the y-coordinate of each endpoint
+after swapping.
+
+ SLOPED LINES
+ when clipping a sloped line, we bring the second point inside
+the clipping box, rather than one beyond it, and then add 1 to
+the length of the line before drawing it. this lets us use
+the same box for finding the outcodes for both endpoints. since
+the equation for clipping the second endpoint to an edge gives us
+1 beyond the edge, we then have to move the point towards the
+first point by one step on the major axis.
+ eventually, there will be a diagram here to explain what's going
+on. the method uses Cohen-Sutherland outcodes to determine
+outsideness, and a method similar to Pike's layers for doing the
+actual clipping.
+
+*/
+
+void
+#ifdef POLYSEGMENT
+mfbSegmentSS (pDrawable, pGC, nseg, pSeg)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nseg;
+ register xSegment *pSeg;
+#else
+mfbLineSS (pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt; /* number of points */
+ DDXPointPtr pptInit;
+#endif
+{
+ int nboxInit;
+ register int nbox;
+ BoxPtr pboxInit;
+ register BoxPtr pbox;
+#ifndef POLYSEGMENT
+ register DDXPointPtr ppt; /* pointer to list of translated points */
+#endif
+
+ unsigned int oc1; /* outcode of point 1 */
+ unsigned int oc2; /* outcode of point 2 */
+
+ PixelType *addrlBase; /* pointer to start of drawable */
+#ifndef POLYSEGMENT
+ PixelType *addrl; /* address of destination pixmap */
+#endif
+ int nlwidth; /* width in longwords of destination pixmap */
+ int xorg, yorg; /* origin of window */
+
+ int adx; /* abs values of dx and dy */
+ int ady;
+ int signdx; /* sign of dx and dy */
+ int signdy;
+ int e, e1, e2; /* bresenham error and increments */
+ int len; /* length of segment */
+ int axis; /* major axis */
+ int octant;
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+
+ /* a bunch of temporaries */
+ register int y1, y2;
+ register int x1, x2;
+ RegionPtr cclip;
+ int alu;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ cclip = pGC->pCompositeClip;
+ alu = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->rop;
+ pboxInit = REGION_RECTS(cclip);
+ nboxInit = REGION_NUM_RECTS(cclip);
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrlBase);
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+#ifdef POLYSEGMENT
+ while (nseg--)
+#else
+ ppt = pptInit;
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+ while(--npt)
+#endif
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+
+#ifdef POLYSEGMENT
+ x1 = pSeg->x1 + xorg;
+ y1 = pSeg->y1 + yorg;
+ x2 = pSeg->x2 + xorg;
+ y2 = pSeg->y2 + yorg;
+ pSeg++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious)
+ {
+ xorg = x1;
+ yorg = y1;
+ }
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+#endif
+
+ if (x1 == x2) /* vertical line */
+ {
+ /* make the line go top to bottom of screen, keeping
+ endpoint semantics
+ */
+ if (y1 > y2)
+ {
+ register int tmp;
+
+ tmp = y2;
+ y2 = y1 + 1;
+ y1 = tmp + 1;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ y1--;
+#endif
+ }
+#ifdef POLYSEGMENT
+ else if (pGC->capStyle != CapNotLast)
+ y2++;
+#endif
+ /* get to first band that might contain part of line */
+ while ((nbox) && (pbox->y2 <= y1))
+ {
+ pbox++;
+ nbox--;
+ }
+
+ if (nbox)
+ {
+ /* stop when lower edge of box is beyond end of line */
+ while((nbox) && (y2 >= pbox->y1))
+ {
+ if ((x1 >= pbox->x1) && (x1 < pbox->x2))
+ {
+ int y1t, y2t;
+ /* this box has part of the line in it */
+ y1t = max(y1, pbox->y1);
+ y2t = min(y2, pbox->y2);
+ if (y1t != y2t)
+ {
+ mfbVertS (alu,
+ addrlBase, nlwidth,
+ x1, y1t, y2t-y1t);
+ }
+ }
+ nbox--;
+ pbox++;
+ }
+ }
+#ifndef POLYSEGMENT
+ y2 = ppt->y + yorg;
+#endif
+ }
+ else if (y1 == y2) /* horizontal line */
+ {
+ /* force line from left to right, keeping
+ endpoint semantics
+ */
+ if (x1 > x2)
+ {
+ register int tmp;
+
+ tmp = x2;
+ x2 = x1 + 1;
+ x1 = tmp + 1;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ x1--;
+#endif
+ }
+#ifdef POLYSEGMENT
+ else if (pGC->capStyle != CapNotLast)
+ x2++;
+#endif
+
+ /* find the correct band */
+ while( (nbox) && (pbox->y2 <= y1))
+ {
+ pbox++;
+ nbox--;
+ }
+
+ /* try to draw the line, if we haven't gone beyond it */
+ if ((nbox) && (pbox->y1 <= y1))
+ {
+ int tmp;
+
+ /* when we leave this band, we're done */
+ tmp = pbox->y1;
+ while((nbox) && (pbox->y1 == tmp))
+ {
+ int x1t, x2t;
+
+ if (pbox->x2 <= x1)
+ {
+ /* skip boxes until one might contain start point */
+ nbox--;
+ pbox++;
+ continue;
+ }
+
+ /* stop if left of box is beyond right of line */
+ if (pbox->x1 >= x2)
+ {
+ nbox = 0;
+ break;
+ }
+
+ x1t = max(x1, pbox->x1);
+ x2t = min(x2, pbox->x2);
+ if (x1t != x2t)
+ {
+ mfbHorzS (alu,
+ addrlBase, nlwidth,
+ x1t, y1, x2t-x1t);
+ }
+ nbox--;
+ pbox++;
+ }
+ }
+#ifndef POLYSEGMENT
+ x2 = ppt->x + xorg;
+#endif
+ }
+ else /* sloped line */
+ {
+ CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy,
+ 1, 1, octant);
+
+ if (adx > ady)
+ {
+ axis = X_AXIS;
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ }
+ else
+ {
+ axis = Y_AXIS;
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ SetYMajorOctant(octant);
+ }
+
+ FIXUP_ERROR(e, octant, bias);
+
+ /* we have bresenham parameters and two points.
+ all we have to do now is clip and draw.
+ */
+
+ while(nbox--)
+ {
+ oc1 = 0;
+ oc2 = 0;
+ OUTCODES(oc1, x1, y1, pbox);
+ OUTCODES(oc2, x2, y2, pbox);
+ if ((oc1 | oc2) == 0)
+ {
+ if (axis == X_AXIS)
+ len = adx;
+ else
+ len = ady;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ len++;
+#endif
+ mfbBresS (alu,
+ addrlBase, nlwidth,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e2, len);
+ break;
+ }
+ else if (oc1 & oc2)
+ {
+ pbox++;
+ }
+ else
+ {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int clipdx, clipdy;
+ int err;
+
+ if (miZeroClipLine(pbox->x1, pbox->y1, pbox->x2-1,
+ pbox->y2-1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pbox++;
+ continue;
+ }
+
+ if (axis == X_AXIS)
+ len = abs(new_x2 - new_x1);
+ else
+ len = abs(new_y2 - new_y1);
+#ifdef POLYSEGMENT
+ if (clip2 != 0 || pGC->capStyle != CapNotLast)
+ len++;
+#else
+ len += (clip2 != 0);
+#endif
+ if (len)
+ {
+ /* unwind bresenham error term to first point */
+ if (clip1)
+ {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ if (axis == X_AXIS)
+ err = e+((clipdy*e2) + ((clipdx-clipdy)*e1));
+ else
+ err = e+((clipdx*e2) + ((clipdy-clipdx)*e1));
+ }
+ else
+ err = e;
+ mfbBresS
+ (alu,
+ addrlBase, nlwidth,
+ signdx, signdy, axis, new_x1, new_y1,
+ err, e1, e2, len);
+ }
+ pbox++;
+ }
+ } /* while (nbox--) */
+ } /* sloped line */
+ } /* while (nline--) */
+
+#ifndef POLYSEGMENT
+
+ /* paint the last point if the end style isn't CapNotLast.
+ (Assume that a projecting, butt, or round cap that is one
+ pixel wide is the same as the single pixel of the endpoint.)
+ */
+
+ if ((pGC->capStyle != CapNotLast) &&
+ ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
+ (ppt->y + yorg != pptInit->y + pDrawable->y) ||
+ (ppt == pptInit + 1)))
+ {
+ PixelType _mask;
+
+ if (alu == RROP_BLACK)
+ _mask = rmask[x2 & PIM];
+ else
+ _mask = mask[x2 & PIM];
+
+ nbox = nboxInit;
+ pbox = pboxInit;
+ while (nbox--)
+ {
+ if ((x2 >= pbox->x1) &&
+ (y2 >= pbox->y1) &&
+ (x2 < pbox->x2) &&
+ (y2 < pbox->y2))
+ {
+ addrl = mfbScanline(addrlBase, x2, y2, nlwidth);
+ switch(alu)
+ {
+ case RROP_BLACK:
+ *addrl &= _mask;
+ break;
+ case RROP_WHITE:
+ *addrl |= _mask;
+ break;
+ case RROP_INVERT:
+ *addrl ^= _mask;
+ break;
+ }
+ break;
+ }
+ else
+ pbox++;
+ }
+ }
+#endif
+}
+
+/*
+ * Draw dashed 1-pixel lines.
+ */
+
+void
+#ifdef POLYSEGMENT
+mfbSegmentSD (pDrawable, pGC, nseg, pSeg)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int nseg;
+ register xSegment *pSeg;
+#else
+mfbLineSD( pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt; /* number of points */
+ DDXPointPtr pptInit;
+#endif
+{
+ int nboxInit;
+ register int nbox;
+ BoxPtr pboxInit;
+ register BoxPtr pbox;
+#ifndef POLYSEGMENT
+ register DDXPointPtr ppt; /* pointer to list of translated points */
+#endif
+
+ register unsigned int oc1; /* outcode of point 1 */
+ register unsigned int oc2; /* outcode of point 2 */
+
+ PixelType *addrl; /* address of destination pixmap */
+ int nlwidth; /* width in longwords of destination pixmap */
+ int xorg, yorg; /* origin of window */
+
+ int adx; /* abs values of dx and dy */
+ int ady;
+ int signdx; /* sign of dx and dy */
+ int signdy;
+ int e, e1, e2; /* bresenham error and increments */
+ int len; /* length of segment */
+ int axis; /* major axis */
+ int octant;
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ int x1, x2, y1, y2;
+ RegionPtr cclip;
+ int fgrop = 0, bgrop = 0;
+ unsigned char *pDash;
+ int dashOffset;
+ int numInDashList;
+ int dashIndex;
+ int isDoubleDash;
+ int dashIndexTmp, dashOffsetTmp;
+ int unclippedlen;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ cclip = pGC->pCompositeClip;
+ fgrop = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->rop;
+ pboxInit = REGION_RECTS(cclip);
+ nboxInit = REGION_NUM_RECTS(cclip);
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrl);
+
+ /* compute initial dash values */
+
+ pDash = (unsigned char *) pGC->dash;
+ numInDashList = pGC->numInDashList;
+ isDoubleDash = (pGC->lineStyle == LineDoubleDash);
+ dashIndex = 0;
+ dashOffset = 0;
+ miStepDash ((int)pGC->dashOffset, &dashIndex, pDash,
+ numInDashList, &dashOffset);
+
+ if (isDoubleDash)
+ bgrop = mfbReduceRop(pGC->alu, pGC->bgPixel);
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+#ifdef POLYSEGMENT
+ while (nseg--)
+#else
+ ppt = pptInit;
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+ while(--npt)
+#endif
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+
+#ifdef POLYSEGMENT
+ x1 = pSeg->x1 + xorg;
+ y1 = pSeg->y1 + yorg;
+ x2 = pSeg->x2 + xorg;
+ y2 = pSeg->y2 + yorg;
+ pSeg++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious)
+ {
+ xorg = x1;
+ yorg = y1;
+ }
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+#endif
+
+ CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);
+
+ if (adx > ady)
+ {
+ axis = X_AXIS;
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ unclippedlen = adx;
+ }
+ else
+ {
+ axis = Y_AXIS;
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ unclippedlen = ady;
+ SetYMajorOctant(octant);
+ }
+
+ FIXUP_ERROR(e, octant, bias);
+
+ /* we have bresenham parameters and two points.
+ all we have to do now is clip and draw.
+ */
+
+ while(nbox--)
+ {
+ oc1 = 0;
+ oc2 = 0;
+ OUTCODES(oc1, x1, y1, pbox);
+ OUTCODES(oc2, x2, y2, pbox);
+ if ((oc1 | oc2) == 0)
+ {
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast)
+ unclippedlen++;
+ dashIndexTmp = dashIndex;
+ dashOffsetTmp = dashOffset;
+ mfbBresD (fgrop, bgrop,
+ &dashIndexTmp, pDash, numInDashList,
+ &dashOffsetTmp, isDoubleDash,
+ addrl, nlwidth,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e2, unclippedlen);
+ break;
+#else
+ mfbBresD (fgrop, bgrop,
+ &dashIndex, pDash, numInDashList,
+ &dashOffset, isDoubleDash,
+ addrl, nlwidth,
+ signdx, signdy, axis, x1, y1,
+ e, e1, e2, unclippedlen);
+ goto dontStep;
+#endif
+ }
+ else if (oc1 & oc2)
+ {
+ pbox++;
+ }
+ else /* have to clip */
+ {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int clipdx, clipdy;
+ int err;
+
+ if (miZeroClipLine(pbox->x1, pbox->y1, pbox->x2-1, pbox->y2-1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pbox++;
+ continue;
+ }
+ dashIndexTmp = dashIndex;
+ dashOffsetTmp = dashOffset;
+ if (clip1)
+ {
+ int dlen;
+
+ if (axis == X_AXIS)
+ dlen = abs(new_x1 - x1);
+ else
+ dlen = abs(new_y1 - y1);
+ miStepDash (dlen, &dashIndexTmp, pDash,
+ numInDashList, &dashOffsetTmp);
+ }
+ if (axis == X_AXIS)
+ len = abs(new_x2 - new_x1);
+ else
+ len = abs(new_y2 - new_y1);
+#ifdef POLYSEGMENT
+ if (clip2 != 0 || pGC->capStyle != CapNotLast)
+ len++;
+#else
+ len += (clip2 != 0);
+#endif
+ if (len)
+ {
+ /* unwind bresenham error term to first point */
+ if (clip1)
+ {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ if (axis == X_AXIS)
+ err = e+((clipdy*e2) + ((clipdx-clipdy)*e1));
+ else
+ err = e+((clipdx*e2) + ((clipdy-clipdx)*e1));
+ }
+ else
+ err = e;
+ mfbBresD (fgrop, bgrop,
+ &dashIndexTmp, pDash, numInDashList,
+ &dashOffsetTmp, isDoubleDash,
+ addrl, nlwidth,
+ signdx, signdy, axis, new_x1, new_y1,
+ err, e1, e2, len);
+ }
+ pbox++;
+ }
+ } /* while (nbox--) */
+#ifndef POLYSEGMENT
+ /*
+ * walk the dash list around to the next line
+ */
+ miStepDash (unclippedlen, &dashIndex, pDash,
+ numInDashList, &dashOffset);
+dontStep: ;
+#endif
+ } /* while (nline--) */
+
+#ifndef POLYSEGMENT
+ /* paint the last point if the end style isn't CapNotLast.
+ (Assume that a projecting, butt, or round cap that is one
+ pixel wide is the same as the single pixel of the endpoint.)
+ */
+
+ if ((pGC->capStyle != CapNotLast) &&
+ ((dashIndex & 1) == 0 || isDoubleDash) &&
+ ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
+ (ppt->y + yorg != pptInit->y + pDrawable->y) ||
+ (ppt == pptInit + 1)))
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+ while (nbox--)
+ {
+ if ((x2 >= pbox->x1) &&
+ (y2 >= pbox->y1) &&
+ (x2 < pbox->x2) &&
+ (y2 < pbox->y2))
+ {
+ unsigned long _mask;
+ int rop;
+
+ rop = fgrop;
+ if (dashIndex & 1)
+ rop = bgrop;
+ if (rop == RROP_BLACK)
+ _mask = rmask[x2 & PIM];
+ else
+ _mask = mask[x2 & PIM];
+ addrl = mfbScanline(addrl, x2, y2, nlwidth);
+ if (rop == RROP_BLACK)
+ *addrl &= _mask;
+ else if (rop == RROP_WHITE)
+ *addrl |= _mask;
+ else
+ *addrl ^= _mask;
+ break;
+ }
+ else
+ pbox++;
+ }
+ }
+#endif
+}
diff --git a/xc/programs/Xserver/mfb/mfbmisc.c b/xc/programs/Xserver/mfb/mfbmisc.c
new file mode 100644
index 000000000..b89919099
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbmisc.c
@@ -0,0 +1,87 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbmisc.c /main/8 1998/02/09 14:39:32 kaleb $ */
+#include "X.h"
+#include "misc.h"
+#include "cursor.h"
+#include "scrnintstr.h"
+
+#include "mfb.h"
+
+/*ARGSUSED*/
+void
+mfbQueryBestSize(class, pwidth, pheight, pScreen)
+int class;
+unsigned short *pwidth;
+unsigned short *pheight;
+ScreenPtr pScreen;
+{
+ unsigned width, test;
+
+ switch(class)
+ {
+ case CursorShape:
+ if (*pwidth > pScreen->width)
+ *pwidth = pScreen->width;
+ if (*pheight > pScreen->height)
+ *pheight = pScreen->height;
+ break;
+ case TileShape:
+ case StippleShape:
+ width = *pwidth;
+ if (!width) break;
+ /* Return the closes power of two not less than what they gave me */
+ test = 0x80000000;
+ /* Find the highest 1 bit in the width given */
+ while(!(test & width))
+ test >>= 1;
+ /* If their number is greater than that, bump up to the next
+ * power of two */
+ if((test - 1) & width)
+ test <<= 1;
+ *pwidth = test;
+ /* We don't care what height they use */
+ break;
+ }
+}
+
diff --git a/xc/programs/Xserver/mfb/mfbmodule.c b/xc/programs/Xserver/mfb/mfbmodule.c
new file mode 100644
index 000000000..0617226d0
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbmodule.c
@@ -0,0 +1,48 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbmodule.c,v 1.7 1999/01/26 05:54:21 dawes Exp $ */
+/*
+ * Copyright (C) 1998 The XFree86 Project, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * XFREE86 PROJECT 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 XFree86 Project 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
+ * XFree86 Project.
+ */
+
+#ifdef XFree86LOADER
+#include "xf86Module.h"
+
+
+static XF86ModuleVersionInfo VersRec =
+{
+ "mfb",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_ANSIC, /* Only need the ansic layer */
+ ABI_ANSIC_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0} /* signature, to be patched into the file by a tool */
+};
+
+XF86ModuleData mfbModuleData = { &VersRec, NULL, NULL };
+
+#endif
diff --git a/xc/programs/Xserver/mfb/mfbpixmap.c b/xc/programs/Xserver/mfb/mfbpixmap.c
new file mode 100644
index 000000000..20a44a403
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbpixmap.c
@@ -0,0 +1,290 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbpixmap.c /main/22 1998/02/09 14:39:36 kaleb $ */
+
+/* pixmap management
+ written by drewry, september 1986
+
+ on a monchrome device, a pixmap is a bitmap.
+*/
+
+#include "Xmd.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "maskbits.h"
+
+#include "mfb.h"
+#include "mi.h"
+
+#include "servermd.h"
+
+#ifndef LOWMEMFTPT
+
+PixmapPtr
+mfbCreatePixmap (pScreen, width, height, depth)
+ ScreenPtr pScreen;
+ int width;
+ int height;
+ int depth;
+{
+ PixmapPtr pPixmap;
+ int datasize;
+ int paddedWidth;
+
+ if (depth != 1)
+ return NullPixmap;
+ paddedWidth = BitmapBytePad(width);
+ datasize = height * paddedWidth;
+ pPixmap = AllocatePixmap(pScreen, datasize);
+ if (!pPixmap)
+ return NullPixmap;
+ pPixmap->drawable.type = DRAWABLE_PIXMAP;
+ pPixmap->drawable.class = 0;
+ pPixmap->drawable.pScreen = pScreen;
+ pPixmap->drawable.depth = depth;
+ pPixmap->drawable.bitsPerPixel = depth;
+ pPixmap->drawable.id = 0;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap->drawable.x = 0;
+ pPixmap->drawable.y = 0;
+ pPixmap->drawable.width = width;
+ pPixmap->drawable.height = height;
+ pPixmap->devKind = paddedWidth;
+ pPixmap->refcnt = 1;
+#ifdef PIXPRIV
+ pPixmap->devPrivate.ptr = datasize ?
+ (pointer)((char *)pPixmap + pScreen->totalPixmapSize) : NULL;
+#else
+ pPixmap->devPrivate.ptr = (pointer)(pPixmap + 1);
+#endif
+ return pPixmap;
+}
+
+#endif /* ifndef LOWMEMFTPT */
+
+Bool
+mfbDestroyPixmap(pPixmap)
+ PixmapPtr pPixmap;
+{
+ if(--pPixmap->refcnt)
+ return TRUE;
+ xfree(pPixmap);
+ return TRUE;
+}
+
+
+PixmapPtr
+mfbCopyPixmap(pSrc)
+ register PixmapPtr pSrc;
+{
+ register PixmapPtr pDst;
+ int size;
+ ScreenPtr pScreen;
+
+ size = pSrc->drawable.height * pSrc->devKind;
+ pScreen = pSrc->drawable.pScreen;
+ pDst = (*pScreen->CreatePixmap) (pScreen, pSrc->drawable.width,
+ pSrc->drawable.height, pSrc->drawable.depth);
+ if (!pDst)
+ return NullPixmap;
+ memmove((char *)pDst->devPrivate.ptr, (char *)pSrc->devPrivate.ptr, size);
+ return pDst;
+}
+
+
+/* replicates a pattern to be a full 32 bits wide.
+ relies on the fact that each scnaline is longword padded.
+ doesn't do anything if pixmap is not a factor of 32 wide.
+ changes width field of pixmap if successful, so that the fast
+ XRotatePixmap code gets used if we rotate the pixmap later.
+
+ calculate number of times to repeat
+ for each scanline of pattern
+ zero out area to be filled with replicate
+ left shift and or in original as many times as needed
+*/
+void
+mfbPadPixmap(pPixmap)
+ PixmapPtr pPixmap;
+{
+ register int width = pPixmap->drawable.width;
+ register int h;
+ register PixelType mask;
+ register PixelType *p;
+ register PixelType bits; /* real pattern bits */
+ register int i;
+ int rep; /* repeat count for pattern */
+
+ if (width >= PPW)
+ return;
+
+ rep = PPW/width;
+ if (rep*width != PPW)
+ return;
+
+ mask = endtab[width];
+
+ p = (PixelType *)(pPixmap->devPrivate.ptr);
+ for (h=0; h < pPixmap->drawable.height; h++)
+ {
+ *p &= mask;
+ bits = *p;
+ for(i=1; i<rep; i++)
+ {
+ bits = SCRRIGHT(bits, width);
+ *p |= bits;
+ }
+ p++;
+ }
+ pPixmap->drawable.width = PPW;
+}
+
+/* Rotates pixmap pPix by w pixels to the right on the screen. Assumes that
+ * words are PPW bits wide, and that the least significant bit appears on the
+ * left.
+ */
+void
+mfbXRotatePixmap(pPix, rw)
+ PixmapPtr pPix;
+ register int rw;
+{
+ register PixelType *pw, *pwFinal;
+ register PixelType t;
+
+ if (pPix == NullPixmap)
+ return;
+
+ pw = (PixelType *)pPix->devPrivate.ptr;
+ rw %= (int)pPix->drawable.width;
+ if (rw < 0)
+ rw += (int)pPix->drawable.width;
+ if(pPix->drawable.width == PPW)
+ {
+ pwFinal = pw + pPix->drawable.height;
+ while(pw < pwFinal)
+ {
+ t = *pw;
+ *pw++ = SCRRIGHT(t, rw) |
+ (SCRLEFT(t, (PPW-rw)) & endtab[rw]);
+ }
+ }
+ else
+ {
+ /* We no longer do this. Validate doesn't try to rotate odd-size
+ * tiles or stipples. mfbUnnatural<tile/stipple>FS works directly off
+ * the unrotate tile/stipple in the GC
+ */
+ ErrorF("X internal error: trying to rotate odd-sized pixmap.\n");
+ }
+
+}
+
+/* Rotates pixmap pPix by h lines. Assumes that h is always less than
+ pPix->height
+ works on any width.
+ */
+void
+mfbYRotatePixmap(pPix, rh)
+ register PixmapPtr pPix;
+ int rh;
+{
+ int nbyDown; /* bytes to move down to row 0; also offset of
+ row rh */
+ int nbyUp; /* bytes to move up to line rh; also
+ offset of first line moved down to 0 */
+ char *pbase;
+ char *ptmp;
+ int height;
+
+ if (pPix == NullPixmap)
+ return;
+ height = (int) pPix->drawable.height;
+ rh %= height;
+ if (rh < 0)
+ rh += height;
+
+ pbase = (char *)pPix->devPrivate.ptr;
+
+ nbyDown = rh * pPix->devKind;
+ nbyUp = (pPix->devKind * height) - nbyDown;
+ if(!(ptmp = (char *)ALLOCATE_LOCAL(nbyUp)))
+ return;
+
+ memmove(ptmp, pbase, nbyUp); /* save the low rows */
+ memmove(pbase, pbase+nbyUp, nbyDown); /* slide the top rows down */
+ memmove(pbase+nbyDown, ptmp, nbyUp); /* move lower rows up to row rh */
+ DEALLOCATE_LOCAL(ptmp);
+}
+
+void
+mfbCopyRotatePixmap(psrcPix, ppdstPix, xrot, yrot)
+ register PixmapPtr psrcPix, *ppdstPix;
+ int xrot, yrot;
+{
+ register PixmapPtr pdstPix;
+
+ if ((pdstPix = *ppdstPix) &&
+ (pdstPix->devKind == psrcPix->devKind) &&
+ (pdstPix->drawable.height == psrcPix->drawable.height))
+ {
+ memmove((char *)pdstPix->devPrivate.ptr,
+ (char *)psrcPix->devPrivate.ptr,
+ psrcPix->drawable.height * psrcPix->devKind);
+ pdstPix->drawable.width = psrcPix->drawable.width;
+ pdstPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ else
+ {
+ if (pdstPix)
+ /* FIX XBUG 6168 */
+ (*pdstPix->drawable.pScreen->DestroyPixmap)(pdstPix);
+ *ppdstPix = pdstPix = mfbCopyPixmap(psrcPix);
+ if (!pdstPix)
+ return;
+ }
+ mfbPadPixmap(pdstPix);
+ if (xrot)
+ mfbXRotatePixmap(pdstPix, xrot);
+ if (yrot)
+ mfbYRotatePixmap(pdstPix, yrot);
+}
diff --git a/xc/programs/Xserver/mfb/mfbply1rct.c b/xc/programs/Xserver/mfb/mfbply1rct.c
new file mode 100644
index 000000000..21d118e72
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbply1rct.c
@@ -0,0 +1,251 @@
+/*
+ * $TOG: mfbply1rct.c /main/11 1998/02/09 14:39:41 kaleb $
+ *
+Copyright 1990, 1998 The Open Group
+
+All Rights Reserved.
+
+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
+ */
+
+/* $XFree86: xc/programs/Xserver/mfb/mfbply1rct.c,v 1.4 1999/03/06 13:12:49 dawes Exp $ */
+
+#include "X.h"
+
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "mistruct.h"
+
+#include "mfb.h"
+#include "maskbits.h"
+
+#if defined(mips) || defined(sparc)
+#define GetHighWord(x) (((int) (x)) >> 16)
+#else
+#define GetHighWord(x) (((int) (x)) / 65536)
+#endif
+
+#if IMAGE_BYTE_ORDER == MSBFirst
+#define intToCoord(i,x,y) (((x) = GetHighWord(i)), ((y) = (int) ((short) (i))))
+#define coordToInt(x,y) (((x) << 16) | ((y) & 0xffff))
+#define intToX(i) (GetHighWord(i))
+#define intToY(i) ((int) ((short) i))
+#else
+#define intToCoord(i,x,y) (((x) = (int) ((short) (i))), ((y) = GetHighWord(i)))
+#define coordToInt(x,y) (((y) << 16) | ((x) & 0xffff))
+#define intToX(i) ((int) ((short) (i)))
+#define intToY(i) (GetHighWord(i))
+#endif
+
+void
+MFBFILLPOLY1RECT (pDrawable, pGC, shape, mode, count, ptsIn)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int count;
+ DDXPointPtr ptsIn;
+{
+ int nlwidth;
+ PixelType *addrl, *addr;
+ int maxy;
+ int origin;
+ register int vertex1, vertex2;
+ int c;
+ BoxPtr extents;
+ int clip;
+ int y;
+ int *vertex1p, *vertex2p;
+ int *endp;
+ int x1, x2;
+ int dx1, dx2;
+ int dy1, dy2;
+ int e1, e2;
+ int step1, step2;
+ int sign1, sign2;
+ int h;
+ int l, r;
+ PixelType mask, bits = ~((PixelType)0);
+ int nmiddle;
+
+ if (mode == CoordModePrevious || shape != Convex ||
+ REGION_NUM_RECTS(pGC->pCompositeClip) != 1)
+ {
+ miFillPolygon (pDrawable, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+ origin = *((int *) &pDrawable->x);
+ vertex2 = origin - ((origin & 0x8000) << 1);
+ extents = &pGC->pCompositeClip->extents;
+ vertex1 = *((int *) &extents->x1) - vertex2;
+ vertex2 = *((int *) &extents->x2) - vertex2 - 0x00010001;
+ clip = 0;
+ y = 32767;
+ maxy = 0;
+ vertex2p = (int *) ptsIn;
+ endp = vertex2p + count;
+ while (count--)
+ {
+ c = *vertex2p;
+ clip |= (c - vertex1) | (vertex2 - c);
+ c = intToY(c);
+ if (c < y)
+ {
+ y = c;
+ vertex1p = vertex2p;
+ }
+ vertex2p++;
+ if (c > maxy)
+ maxy = c;
+ }
+ if (y == maxy)
+ return;
+
+ if (clip & 0x80008000)
+ {
+ miFillPolygon (pDrawable, pGC, shape, mode, vertex2p - (int *) ptsIn, ptsIn);
+ return;
+ }
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrl);
+ addrl = mfbScanlineDelta(addrl, y + pDrawable->y, nlwidth);
+ origin = intToX(origin);
+ vertex2p = vertex1p;
+ vertex2 = vertex1 = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+#define Setup(c,x,vertex,dx,dy,e,sign,step) {\
+ x = intToX(vertex); \
+ if (dy = intToY(c) - y) { \
+ dx = intToX(c) - x; \
+ step = 0; \
+ if (dx >= 0) \
+ { \
+ e = 0; \
+ sign = 1; \
+ if (dx >= dy) {\
+ step = dx / dy; \
+ dx = dx % dy; \
+ } \
+ } \
+ else \
+ { \
+ e = 1 - dy; \
+ sign = -1; \
+ dx = -dx; \
+ if (dx >= dy) { \
+ step = - (dx / dy); \
+ dx = dx % dy; \
+ } \
+ } \
+ } \
+ x += origin; \
+ vertex = c; \
+}
+
+#define Step(x,dx,dy,e,sign,step) {\
+ x += step; \
+ if ((e += dx) > 0) \
+ { \
+ x += sign; \
+ e -= dy; \
+ } \
+}
+ for (;;)
+ {
+ if (y == intToY(vertex1))
+ {
+ do
+ {
+ if (vertex1p == (int *) ptsIn)
+ vertex1p = endp;
+ c = *--vertex1p;
+ Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1)
+ } while (y >= intToY(vertex1));
+ h = dy1;
+ }
+ else
+ {
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ h = intToY(vertex1) - y;
+ }
+ if (y == intToY(vertex2))
+ {
+ do
+ {
+ c = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+ Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2)
+ } while (y >= intToY(vertex2));
+ if (dy2 < h)
+ h = dy2;
+ }
+ else
+ {
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ if ((c = (intToY(vertex2) - y)) < h)
+ h = c;
+ }
+ /* fill spans for this segment */
+ y += h;
+ for (;;)
+ {
+ l = x1;
+ r = x2;
+ nmiddle = x2 - x1;
+ if (nmiddle < 0)
+ {
+ nmiddle = -nmiddle;
+ l = x2;
+ r = x1;
+ }
+ c = l & PIM;
+ l -= c;
+ l = l >> PWSH;
+ addr = addrl + l;
+ if (c + nmiddle < PPW)
+ {
+ mask = SCRRIGHT (bits,c) ^ SCRRIGHT (bits,c+nmiddle);
+ *addr OPEQ mask;
+ }
+ else
+ {
+ if (c)
+ {
+ mask = SCRRIGHT(bits, c);
+ *addr OPEQ mask;
+ nmiddle += c - PPW;
+ addr++;
+ }
+ nmiddle >>= PWSH;
+ Duff (nmiddle, *addr++ EQWHOLEWORD)
+ if (mask = ~SCRRIGHT(bits, r & PIM))
+ *addr OPEQ mask;
+ }
+ if (!--h)
+ break;
+ mfbScanlineInc(addrl, nlwidth);
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ }
+ if (y == maxy)
+ break;
+ mfbScanlineInc(addrl, nlwidth);
+ }
+}
diff --git a/xc/programs/Xserver/mfb/mfbplygblt.c b/xc/programs/Xserver/mfb/mfbplygblt.c
new file mode 100644
index 000000000..4d9deeb29
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbplygblt.c
@@ -0,0 +1,387 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbplygblt.c,v 3.2 1998/10/04 09:39:13 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbplygblt.c /main/21 1998/02/09 14:39:46 kaleb $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "mfb.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "maskbits.h"
+#include "miscstruct.h"
+
+/*
+ we should eventually special-case fixed-width fonts, although
+its more important for ImageText, which is meant for terminal
+emulators.
+
+ this works for fonts with glyphs <= 32 bits wide.
+
+ the clipping calculations are done for worst-case fonts.
+we make no assumptions about the heights, widths, or bearings
+of the glyphs. if we knew that the glyphs are all the same height,
+we could clip the tops and bottoms per clipping box, rather
+than per character per clipping box. if we knew that the glyphs'
+left and right bearings were well-behaved, we could clip a single
+character at the start, output until the last unclipped
+character, and then clip the last one. this is all straightforward
+to determine based on max-bounds and min-bounds from the font.
+ there is some inefficiency introduced in the per-character
+clipping to make what's going on clearer.
+
+ (it is possible, for example, for a font to be defined in which the
+next-to-last character in a font would be clipped out, but the last
+one wouldn't. the code below deals with this.)
+
+ PolyText looks at the fg color and the rasterop; mfbValidateGC
+swaps in the right routine after looking at the reduced ratserop
+in the private field of the GC.
+
+ the register allocations are provisional; in particualr startmask and
+endmask might not be the right things. pglyph, xoff, pdst, and tmpSrc
+are fairly obvious, though.
+
+ to avoid source proliferation, this file is compiled
+three times:
+ MFBPOLYGLYPHBLT OPEQ
+ mfbPolyGlyphBltWhite |=
+ mfbPolyGlyphBltBlack &=~
+ mfbPolyGlyphBltInvert ^=
+*/
+
+void
+MFBPOLYGLYPHBLT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ pointer pglyphBase; /* start of array of glyphs (unused in R5) */
+{
+ ExtentInfoRec info; /* used by QueryGlyphExtents() */
+ BoxRec bbox; /* string's bounding box */
+
+ CharInfoPtr pci;
+ int xorg, yorg; /* origin of drawable in bitmap */
+ int widthDst; /* width of dst in longwords */
+
+ /* these keep track of the character origin */
+ PixelType *pdstBase;
+ /* points to longword with character origin */
+ int xchar; /* xorigin of char (mod 32) */
+
+ /* these are used for placing the glyph */
+ register int xoff; /* x offset of left edge of glyph (mod 32) */
+ register PixelType *pdst;
+ /* pointer to current longword in dst */
+
+ int w; /* width of glyph in bits */
+ int h; /* height of glyph */
+ int widthGlyph; /* width of glyph, in bytes */
+ register unsigned char *pglyph;
+ /* pointer to current row of glyph */
+
+ /* used for putting down glyph */
+ register PixelType tmpSrc;
+ /* for getting bits from glyph */
+ register PixelType startmask;
+ register PixelType endmask;
+ register int nFirst;/* bits of glyph in current longword */
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+ mfbGetPixelWidthAndPointer(pDrawable, widthDst, pdstBase);
+
+ x += xorg;
+ y += yorg;
+
+ QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info);
+ bbox.x1 = x + info.overallLeft;
+ bbox.x2 = x + info.overallRight;
+ bbox.y1 = y - info.overallAscent;
+ bbox.y2 = y + info.overallDescent;
+
+ switch (RECT_IN_REGION(pGC->pScreen, pGC->pCompositeClip, &bbox))
+ {
+ case rgnOUT:
+ break;
+ case rgnIN:
+ pdstBase = mfbScanlineNoBankSwitch(pdstBase, x, y, widthDst);
+ xchar = x & PIM;
+
+ while(nglyph--)
+ {
+ pci = *ppci;
+ pglyph = FONTGLYPHBITS(pglyphBase, pci);
+ w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
+ h = pci->metrics.ascent + pci->metrics.descent;
+ widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
+
+ /* start at top scanline of glyph */
+ pdst = pdstBase;
+
+ /* find correct word in scanline and x offset within it
+ for left edge of glyph
+ */
+ xoff = xchar + pci->metrics.leftSideBearing;
+ if (xoff > PLST)
+ {
+ pdst++;
+ xoff &= PIM;
+ }
+ else if (xoff < 0)
+ {
+ xoff += PPW;
+ pdst--;
+ }
+
+ pdst = mfbScanlineDelta(pdst, -pci->metrics.ascent, widthDst);
+
+ if ((xoff + w) <= PPW)
+ {
+ /* glyph all in one longword */
+ maskpartialbits(xoff, w, startmask);
+ while (h--)
+ {
+ getleftbits(pglyph, w, tmpSrc);
+ *pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
+ pglyph += widthGlyph;
+ mfbScanlineInc(pdst, widthDst);
+ }
+ }
+ else
+ {
+ /* glyph crosses longword boundary */
+ maskPPWbits(xoff, w, startmask, endmask);
+ nFirst = PPW - xoff;
+ while (h--)
+ {
+ getleftbits(pglyph, w, tmpSrc);
+ *pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
+ *(pdst+1) OPEQ (SCRLEFT(tmpSrc, nFirst) & endmask);
+ pglyph += widthGlyph;
+ mfbScanlineInc(pdst, widthDst);
+ }
+ } /* glyph crosses longwords boundary */
+
+ /* update character origin */
+ x += pci->metrics.characterWidth;
+ xchar += pci->metrics.characterWidth;
+ if (xchar > PLST)
+ {
+ xchar -= PPW;
+ pdstBase++;
+ }
+ else if (xchar < 0)
+ {
+ xchar += PPW;
+ pdstBase--;
+ }
+ ppci++;
+ } /* while nglyph-- */
+ break;
+ case rgnPART:
+ {
+ TEXTPOS *ppos;
+ RegionPtr cclip;
+ int nbox;
+ BoxPtr pbox;
+ int xpos; /* x position of char origin */
+ int i;
+ BoxRec clip;
+ int leftEdge, rightEdge;
+ int topEdge, bottomEdge;
+ int glyphRow; /* first row of glyph not wholly
+ clipped out */
+ int glyphCol; /* leftmost visible column of glyph */
+ int getWidth; /* bits to get from glyph */
+
+ if(!(ppos = (TEXTPOS *)ALLOCATE_LOCAL(nglyph * sizeof(TEXTPOS))))
+ return;
+
+ pdstBase = mfbScanlineNoBankSwitch(pdstBase, x, y, widthDst);
+ xpos = x;
+ xchar = xpos & PIM;
+
+ for (i=0; i<nglyph; i++)
+ {
+ pci = ppci[i];
+
+ ppos[i].xpos = xpos;
+ ppos[i].xchar = xchar;
+ ppos[i].leftEdge = xpos + pci->metrics.leftSideBearing;
+ ppos[i].rightEdge = xpos + pci->metrics.rightSideBearing;
+ ppos[i].topEdge = y - pci->metrics.ascent;
+ ppos[i].bottomEdge = y + pci->metrics.descent;
+ ppos[i].pdstBase = pdstBase;
+ ppos[i].widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
+
+ xpos += pci->metrics.characterWidth;
+ xchar += pci->metrics.characterWidth;
+ if (xchar > PLST)
+ {
+ xchar &= PIM;
+ pdstBase++;
+ }
+ else if (xchar < 0)
+ {
+ xchar += PPW;
+ pdstBase--;
+ }
+ }
+
+ cclip = pGC->pCompositeClip;
+ pbox = REGION_RECTS(cclip);
+ nbox = REGION_NUM_RECTS(cclip);
+
+ for (; --nbox >= 0; pbox++)
+ {
+ clip.x1 = max(bbox.x1, pbox->x1);
+ clip.y1 = max(bbox.y1, pbox->y1);
+ clip.x2 = min(bbox.x2, pbox->x2);
+ clip.y2 = min(bbox.y2, pbox->y2);
+ if ((clip.x2<=clip.x1) || (clip.y2<=clip.y1))
+ continue;
+
+ for(i=0; i<nglyph; i++)
+ {
+ pci = ppci[i];
+ xchar = ppos[i].xchar;
+
+ /* clip the left and right edges */
+ if (ppos[i].leftEdge < clip.x1)
+ leftEdge = clip.x1;
+ else
+ leftEdge = ppos[i].leftEdge;
+
+ if (ppos[i].rightEdge > clip.x2)
+ rightEdge = clip.x2;
+ else
+ rightEdge = ppos[i].rightEdge;
+
+ w = rightEdge - leftEdge;
+ if (w <= 0)
+ continue;
+
+ /* clip the top and bottom edges */
+ if (ppos[i].topEdge < clip.y1)
+ topEdge = clip.y1;
+ else
+ topEdge = ppos[i].topEdge;
+
+ if (ppos[i].bottomEdge > clip.y2)
+ bottomEdge = clip.y2;
+ else
+ bottomEdge = ppos[i].bottomEdge;
+
+ h = bottomEdge - topEdge;
+ if (h <= 0)
+ continue;
+
+ glyphRow = (topEdge - y) + pci->metrics.ascent;
+ widthGlyph = ppos[i].widthGlyph;
+ pglyph = FONTGLYPHBITS(pglyphBase, pci);
+ pglyph += (glyphRow * widthGlyph);
+
+ pdst = ppos[i].pdstBase;
+
+ glyphCol = (leftEdge - ppos[i].xpos) -
+ (pci->metrics.leftSideBearing);
+ getWidth = w + glyphCol;
+ xoff = xchar + (leftEdge - ppos[i].xpos);
+ if (xoff > PLST)
+ {
+ xoff &= PIM;
+ pdst++;
+ }
+ else if (xoff < 0)
+ {
+ xoff += PPW;
+ pdst--;
+ }
+
+ pdst = mfbScanlineDelta(pdst, -(y-topEdge), widthDst);
+
+ if ((xoff + w) <= PPW)
+ {
+ maskpartialbits(xoff, w, startmask);
+ while (h--)
+ {
+ getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
+ *pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
+ pglyph += widthGlyph;
+ mfbScanlineInc(pdst, widthDst);
+ }
+ }
+ else
+ {
+ maskPPWbits(xoff, w, startmask, endmask);
+ nFirst = PPW - xoff;
+ while (h--)
+ {
+ getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
+ *pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
+ *(pdst+1) OPEQ (SCRLEFT(tmpSrc, nFirst) & endmask);
+ pglyph += widthGlyph;
+ mfbScanlineInc(pdst, widthDst);
+ }
+ }
+ } /* for each glyph */
+ } /* while nbox-- */
+ DEALLOCATE_LOCAL(ppos);
+ break;
+ }
+ default:
+ break;
+ }
+}
diff --git a/xc/programs/Xserver/mfb/mfbpntarea.c b/xc/programs/Xserver/mfb/mfbpntarea.c
new file mode 100644
index 000000000..c680c98aa
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbpntarea.c
@@ -0,0 +1,292 @@
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbpntarea.c /main/13 1998/02/09 14:39:50 kaleb $ */
+#include "X.h"
+
+#include "windowstr.h"
+#include "regionstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+#include "mfb.h"
+#include "maskbits.h"
+
+/*
+ the solid fillers are called for rectangles and window backgrounds.
+ the boxes are already translated.
+ maybe this should always take a pixmap instead of a drawable?
+
+ NOTE:
+ iy = ++iy < tileHeight ? iy : 0
+is equivalent to iy%= tileheight, and saves a division.
+*/
+
+/*
+ MFBSOLIDFILLAREA OPEQ EQWHOLEOWRD
+ mfbSolidWhiteArea |= = ~0
+ mfbSolidBlackArea &=~ = 0
+ mfbSolidInvertArea ^= ^= ~0
+
+EQWHOLEWORD is used to write whole longwords. it could use OPEQ,
+but *p++ |= ~0 on at least two compilers generates much
+worse code than *p++ = ~0. similarly for *p++ &= ~~0
+and *p++ = 0.
+
+*/
+
+/*ARGSUSED*/
+void
+MFBSOLIDFILLAREA(pDraw, nbox, pbox, alu, nop)
+ DrawablePtr pDraw;
+ int nbox;
+ BoxPtr pbox;
+ int alu;
+ PixmapPtr nop;
+{
+ int nlwidth; /* width in longwords of the drawable */
+ int w; /* width of current box */
+ register int h; /* height of current box */
+ register PixelType *p; /* pointer to bits we're writing */
+ register int nlw; /* loop version of nlwMiddle */
+ register PixelType startmask;
+ register PixelType endmask;/* masks for reggedy bits at either end of line */
+ register int nlwExtra;
+ /* to get from right of box to left of next span */
+ int nlwMiddle; /* number of longwords between sides of boxes */
+ PixelType *pbits; /* pointer to start of drawable */
+
+ mfbGetPixelWidthAndPointer(pDraw, nlwidth, pbits);
+
+ while (nbox--)
+ {
+ w = pbox->x2 - pbox->x1;
+ h = pbox->y2 - pbox->y1;
+ p = mfbScanline(pbits, pbox->x1, pbox->y1, nlwidth);
+
+ if ( ((pbox->x1 & PIM) + w) < PPW)
+ {
+ maskpartialbits(pbox->x1, w, startmask);
+ nlwExtra = nlwidth;
+ Duff(h, *p OPEQ startmask; mfbScanlineInc(p, nlwExtra));
+ }
+ else
+ {
+ maskbits(pbox->x1, w, startmask, endmask, nlwMiddle);
+ nlwExtra = nlwidth - nlwMiddle;
+
+ if (startmask && endmask)
+ {
+ nlwExtra -= 1;
+ while (h--)
+ {
+ nlw = nlwMiddle;
+ *p OPEQ startmask;
+ p++;
+ Duff(nlw, *p++ EQWHOLEWORD);
+ *p OPEQ endmask;
+ mfbScanlineInc(p, nlwExtra);
+ }
+ }
+ else if (startmask && !endmask)
+ {
+ nlwExtra -= 1;
+ while (h--)
+ {
+ nlw = nlwMiddle;
+ *p OPEQ startmask;
+ p++;
+ Duff(nlw, *p++ EQWHOLEWORD);
+ mfbScanlineInc(p, nlwExtra);
+ }
+ }
+ else if (!startmask && endmask)
+ {
+ while (h--)
+ {
+ nlw = nlwMiddle;
+ Duff(nlw, *p++ EQWHOLEWORD);
+ *p OPEQ endmask;
+ mfbScanlineInc(p, nlwExtra);
+ }
+ }
+ else /* no ragged bits at either end */
+ {
+ while (h--)
+ {
+ nlw = nlwMiddle;
+ Duff(nlw, *p++ EQWHOLEWORD);
+ mfbScanlineInc(p, nlwExtra);
+ }
+ }
+ }
+ pbox++;
+ }
+}
+
+
+
+/* stipple a list of boxes
+
+you can use the reduced rasterop for stipples. if rrop is
+black, AND the destination with (not stipple pattern). if rrop is
+white OR the destination with the stipple pattern. if rrop is invert,
+XOR the destination with the stipple pattern.
+
+ MFBSTIPPLEFILLAREA OPEQ
+ mfbStippleWhiteArea |=
+ mfbStippleBlackArea &=~
+ mfbStippleInveryArea ^=
+*/
+
+/*ARGSUSED*/
+void
+MFBSTIPPLEFILLAREA(pDraw, nbox, pbox, alu, pstipple)
+ DrawablePtr pDraw;
+ int nbox;
+ BoxPtr pbox;
+ int alu;
+ PixmapPtr pstipple;
+{
+ register PixelType *psrc;
+ /* pointer to bits in tile, if needed */
+ int tileHeight; /* height of the tile */
+ register PixelType srcpix;
+
+ int nlwidth; /* width in longwords of the drawable */
+ int w; /* width of current box */
+ register int nlw; /* loop version of nlwMiddle */
+ register PixelType *p; /* pointer to bits we're writing */
+ register int h; /* height of current box */
+ PixelType startmask;
+ PixelType endmask; /* masks for reggedy bits at either end of line */
+ int nlwMiddle; /* number of longwords between sides of boxes */
+ int nlwExtra; /* to get from right of box to left of next span */
+ register int iy; /* index of current scanline in tile */
+ PixelType *pbits; /* pointer to start of drawable */
+
+ mfbGetPixelWidthAndPointer(pDraw, nlwidth, pbits);
+
+ tileHeight = pstipple->drawable.height;
+ psrc = (PixelType *)(pstipple->devPrivate.ptr);
+
+ while (nbox--)
+ {
+ w = pbox->x2 - pbox->x1;
+ h = pbox->y2 - pbox->y1;
+ iy = pbox->y1 % tileHeight;
+ p = mfbScanline(pbits, pbox->x1, pbox->y1, nlwidth);
+
+ if ( ((pbox->x1 & PIM) + w) < PPW)
+ {
+ maskpartialbits(pbox->x1, w, startmask);
+ nlwExtra = nlwidth;
+ while (h--)
+ {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ *p OPEQ (srcpix & startmask);
+ mfbScanlineInc(p, nlwExtra);
+ }
+ }
+ else
+ {
+ maskbits(pbox->x1, w, startmask, endmask, nlwMiddle);
+ nlwExtra = nlwidth - nlwMiddle;
+
+ if (startmask && endmask)
+ {
+ nlwExtra -= 1;
+ while (h--)
+ {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ nlw = nlwMiddle;
+ *p OPEQ (srcpix & startmask);
+ p++;
+ Duff (nlw, *p++ OPEQ srcpix);
+ *p OPEQ (srcpix & endmask);
+ mfbScanlineInc(p, nlwExtra);
+ }
+ }
+ else if (startmask && !endmask)
+ {
+ nlwExtra -= 1;
+ while (h--)
+ {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ nlw = nlwMiddle;
+ *p OPEQ (srcpix & startmask);
+ p++;
+ Duff(nlw, *p++ OPEQ srcpix);
+ mfbScanlineInc(p, nlwExtra);
+ }
+ }
+ else if (!startmask && endmask)
+ {
+ while (h--)
+ {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ nlw = nlwMiddle;
+ Duff(nlw, *p++ OPEQ srcpix);
+ *p OPEQ (srcpix & endmask);
+ mfbScanlineInc(p, nlwExtra);
+ }
+ }
+ else /* no ragged bits at either end */
+ {
+ while (h--)
+ {
+ srcpix = psrc[iy];
+ iy = ++iy < tileHeight ? iy : 0;
+ nlw = nlwMiddle;
+ Duff(nlw, *p++ OPEQ srcpix);
+ mfbScanlineInc(p, nlwExtra);
+ }
+ }
+ }
+ pbox++;
+ }
+}
diff --git a/xc/programs/Xserver/mfb/mfbpntwin.c b/xc/programs/Xserver/mfb/mfbpntwin.c
new file mode 100644
index 000000000..dce68c0c1
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbpntwin.c
@@ -0,0 +1,119 @@
+/* $TOG: mfbpntwin.c /main/20 1998/02/09 14:39:55 kaleb $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#include "X.h"
+
+#include "windowstr.h"
+#include "regionstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+#include "mfb.h"
+#include "maskbits.h"
+#include "mi.h"
+
+void
+mfbPaintWindow(pWin, pRegion, what)
+ WindowPtr pWin;
+ RegionPtr pRegion;
+ int what;
+{
+ register mfbPrivWin *pPrivWin;
+
+ pPrivWin = (mfbPrivWin *)(pWin->devPrivates[mfbWindowPrivateIndex].ptr);
+
+ switch (what) {
+ case PW_BACKGROUND:
+ switch (pWin->backgroundState) {
+ case None:
+ return;
+ case ParentRelative:
+ do {
+ pWin = pWin->parent;
+ } while (pWin->backgroundState == ParentRelative);
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
+ what);
+ return;
+ case BackgroundPixmap:
+ if (pPrivWin->fastBackground)
+ {
+ mfbTileAreaPPWCopy((DrawablePtr)pWin, REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion), GXcopy,
+ pPrivWin->pRotatedBackground);
+ return;
+ }
+ break;
+ case BackgroundPixel:
+ if (pWin->background.pixel & 1)
+ mfbSolidWhiteArea((DrawablePtr)pWin, REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion), GXset, NullPixmap);
+ else
+ mfbSolidBlackArea((DrawablePtr)pWin, REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion), GXclear, NullPixmap);
+ return;
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel)
+ {
+ if (pWin->border.pixel & 1)
+ mfbSolidWhiteArea((DrawablePtr)pWin, REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion), GXset, NullPixmap);
+ else
+ mfbSolidBlackArea((DrawablePtr)pWin, REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion), GXclear, NullPixmap);
+ return;
+ }
+ else if (pPrivWin->fastBorder)
+ {
+ mfbTileAreaPPWCopy((DrawablePtr)pWin, REGION_NUM_RECTS(pRegion),
+ REGION_RECTS(pRegion), GXcopy,
+ pPrivWin->pRotatedBorder);
+ return;
+ }
+ break;
+ }
+ miPaintWindow(pWin, pRegion, what);
+}
diff --git a/xc/programs/Xserver/mfb/mfbpolypnt.c b/xc/programs/Xserver/mfb/mfbpolypnt.c
new file mode 100644
index 000000000..bbba1a0ab
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbpolypnt.c
@@ -0,0 +1,137 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbpolypnt.c,v 1.3 1998/10/04 09:39:13 dawes Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbpolypnt.c /main/11 1998/02/09 14:39:59 kaleb $ */
+
+#include "X.h"
+#include "Xprotostr.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "miscstruct.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+
+#include "mfb.h"
+#include "maskbits.h"
+
+void
+mfbPolyPoint(pDrawable, pGC, mode, npt, pptInit)
+ register DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt;
+ xPoint *pptInit;
+{
+
+ register BoxPtr pbox;
+ register int nbox;
+
+ register PixelType *addrl;
+ int nlwidth;
+
+ int nptTmp;
+ register xPoint *ppt;
+
+ register int x;
+ register int y;
+ register int rop;
+ mfbPrivGC *pGCPriv;
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ pGCPriv = (mfbPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr;
+ rop = pGCPriv->rop;
+
+ mfbGetPixelWidthAndPointer(pDrawable, nlwidth, addrl);
+
+ if ((mode == CoordModePrevious) && (npt > 1))
+ {
+ for (ppt = pptInit + 1, nptTmp = npt - 1; --nptTmp >= 0; ppt++)
+ {
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ }
+ }
+
+ nbox = REGION_NUM_RECTS(pGC->pCompositeClip);
+ pbox = REGION_RECTS(pGC->pCompositeClip);
+ for (; --nbox >= 0; pbox++)
+ {
+ if (rop == RROP_BLACK)
+ {
+ for (ppt = pptInit, nptTmp = npt; --nptTmp >= 0; ppt++)
+ {
+ x = ppt->x + pDrawable->x;
+ y = ppt->y + pDrawable->y;
+ if ((x >= pbox->x1) && (x < pbox->x2) &&
+ (y >= pbox->y1) && (y < pbox->y2))
+ *mfbScanline(addrl, x, y, nlwidth) &= rmask[x & PIM];
+ }
+ }
+ else if (rop == RROP_WHITE)
+ {
+ for (ppt = pptInit, nptTmp = npt; --nptTmp >= 0; ppt++)
+ {
+ x = ppt->x + pDrawable->x;
+ y = ppt->y + pDrawable->y;
+ if ((x >= pbox->x1) && (x < pbox->x2) &&
+ (y >= pbox->y1) && (y < pbox->y2))
+ *mfbScanline(addrl, x, y, nlwidth) |= mask[x & PIM];
+ }
+ }
+ else if (rop == RROP_INVERT)
+ {
+ for (ppt = pptInit, nptTmp = npt; --nptTmp >= 0; ppt++)
+ {
+ x = ppt->x + pDrawable->x;
+ y = ppt->y + pDrawable->y;
+ if ((x >= pbox->x1) && (x < pbox->x2) &&
+ (y >= pbox->y1) && (y < pbox->y2))
+ *mfbScanline(addrl, x, y, nlwidth) ^= mask[x & PIM];
+ }
+ }
+ }
+}
diff --git a/xc/programs/Xserver/mfb/mfbpushpxl.c b/xc/programs/Xserver/mfb/mfbpushpxl.c
new file mode 100644
index 000000000..32383da0d
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbpushpxl.c
@@ -0,0 +1,274 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbpushpxl.c,v 1.3 1998/10/04 09:39:14 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbpushpxl.c /main/11 1998/02/09 14:40:03 kaleb $ */
+
+#include "X.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "miscstruct.h"
+#include "maskbits.h"
+#include "regionstr.h"
+#include "mfb.h"
+
+/* mfbSolidPP is courtesy of xhacks@csri.toronto.edu
+
+ For fillStyle==FillSolid, a monochrome PushPixels can be reduced to
+ a ROP in the following way: (Note that the ROP is the same as the
+ result of ROP(src=0x3,dst=0x5))
+
+ src=0011 0000 0011
+ dst=0101 0101 0101
+ rop fg=0 fg=1
+ GXclear 0x0 0000 0100 0100 0
+ GXand 0x1 0001 0100 0101 s&d
+ GXandReverse 0x2 0010 0100 0110 s&~d
+ GXcopy 0x3 0011 0100 0111 s
+ GXandInverted 0x4 0100 0101 0100 ~s&d
+ GXnoop 0x5 0101 0101 0101 d
+ GXxor 0x6 0110 0101 0110 s^d
+ GXor 0x7 0111 0101 0111 s|d
+ GXnor 0x8 1000 0110 0100 ~s&~d
+ GXequiv 0x9 1001 0110 0101 ~s^d
+ GXinvert 0xa 1010 0110 0110 ~d
+ GXorReverse 0xb 1011 0110 0111 s|~d
+ GXcopyInverted 0xc 1100 0111 0100 ~s
+ GXorInverted 0xd 1101 0111 0101 ~s|d
+ GXnand 0xe 1110 0111 0110 ~s|~d
+ GXset 0xf 1111 0111 0111 1
+
+For src=0: newRop = 0x4|(rop>>2)
+For src=1: newRop = 0x4|(rop&3)
+*/
+
+/* mfbSolidPP -- squeegees the forground color of pGC through pBitMap
+ * into pDrawable. pBitMap is a stencil (dx by dy of it is used, it may
+ * be bigger) which is placed on the drawable at xOrg, yOrg. Where a 1 bit
+ * is set in the bitmap, the fill style is put onto the drawable using
+ * the GC's logical function. The drawable is not changed where the bitmap
+ * has a zero bit or outside the area covered by the stencil.
+ */
+void
+mfbSolidPP(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg)
+ GCPtr pGC;
+ PixmapPtr pBitMap;
+ DrawablePtr pDrawable;
+ int dx, dy, xOrg, yOrg;
+{
+ unsigned char alu;
+ RegionRec rgnDst;
+ DDXPointPtr pptSrc;
+ BoxRec srcBox;
+ register DDXPointPtr ppt;
+ register BoxPtr pbox;
+ int i;
+
+ if (!pGC->planemask & 1) return;
+
+ /* compute the reduced rop function */
+ alu = pGC->alu;
+ if (!(pGC->fgPixel&1)) alu >>= 2;
+ alu = (alu & 0x3) | 0x4;
+ if (alu == GXnoop) return;
+
+ srcBox.x1 = xOrg;
+ srcBox.y1 = yOrg;
+ srcBox.x2 = xOrg + dx;
+ srcBox.y2 = yOrg + dy;
+ REGION_INIT(pGC->pScreen, &rgnDst, &srcBox, 1);
+
+ /* clip the shape of the dst to the destination composite clip */
+ REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, pGC->pCompositeClip);
+
+ if (!REGION_NIL(&rgnDst))
+ {
+ i = REGION_NUM_RECTS(&rgnDst);
+ pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(i * sizeof(DDXPointRec));
+ if(pptSrc)
+ {
+ for (pbox = REGION_RECTS(&rgnDst), ppt = pptSrc;
+ --i >= 0;
+ pbox++, ppt++)
+ {
+ ppt->x = pbox->x1 - xOrg;
+ ppt->y = pbox->y1 - yOrg;
+ }
+ mfbDoBitblt((DrawablePtr)pBitMap, pDrawable, alu, &rgnDst, pptSrc);
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+ }
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+}
+
+#define NPT 128
+
+/* mfbPushPixels -- squeegees the forground color of pGC through pBitMap
+ * into pDrawable. pBitMap is a stencil (dx by dy of it is used, it may
+ * be bigger) which is placed on the drawable at xOrg, yOrg. Where a 1 bit
+ * is set in the bitmap, the fill style is put onto the drawable using
+ * the GC's logical function. The drawable is not changed where the bitmap
+ * has a zero bit or outside the area covered by the stencil.
+ */
+void
+mfbPushPixels(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg)
+ GCPtr pGC;
+ PixmapPtr pBitMap;
+ DrawablePtr pDrawable;
+ int dx, dy, xOrg, yOrg;
+{
+ int h, dxDivPPW, ibEnd;
+ PixelType *pwLineStart;
+ register PixelType *pw, *pwEnd;
+ register PixelType mask;
+ register int ib;
+ register PixelType w;
+ register int ipt; /* index into above arrays */
+ Bool fInBox;
+ DDXPointRec pt[NPT];
+ int width[NPT];
+
+ /* Now scan convert the pixmap and use the result to call fillspans in
+ * in the drawable with the original GC */
+ ipt = 0;
+ dxDivPPW = dx/PPW;
+ for(h = 0; h < dy; h++)
+ {
+
+ pw = (PixelType *)
+ (((char *)(pBitMap->devPrivate.ptr))+(h * pBitMap->devKind));
+ pwLineStart = pw;
+ /* Process all words which are fully in the pixmap */
+
+ fInBox = FALSE;
+ pwEnd = pwLineStart + dxDivPPW;
+ while(pw < pwEnd)
+ {
+ w = *pw;
+ mask = endtab[1];
+ for(ib = 0; ib < PPW; ib++)
+ {
+ if(w & mask)
+ {
+ if(!fInBox)
+ {
+ pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
+ pt[ipt].y = h + yOrg;
+ /* start new box */
+ fInBox = TRUE;
+ }
+ }
+ else
+ {
+ if(fInBox)
+ {
+ width[ipt] = ((pw - pwLineStart) << PWSH) +
+ ib + xOrg - pt[ipt].x;
+ if (++ipt >= NPT)
+ {
+ (*pGC->ops->FillSpans)(pDrawable, pGC, NPT, pt,
+ width, TRUE);
+ ipt = 0;
+ }
+ /* end box */
+ fInBox = FALSE;
+ }
+ }
+ mask = SCRRIGHT(mask, 1);
+ }
+ pw++;
+ }
+ ibEnd = dx & PIM;
+ if(ibEnd)
+ {
+ /* Process final partial word on line */
+ w = *pw;
+ mask = endtab[1];
+ for(ib = 0; ib < ibEnd; ib++)
+ {
+ if(w & mask)
+ {
+ if(!fInBox)
+ {
+ /* start new box */
+ pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
+ pt[ipt].y = h + yOrg;
+ fInBox = TRUE;
+ }
+ }
+ else
+ {
+ if(fInBox)
+ {
+ /* end box */
+ width[ipt] = ((pw - pwLineStart) << PWSH) +
+ ib + xOrg - pt[ipt].x;
+ if (++ipt >= NPT)
+ {
+ (*pGC->ops->FillSpans)(pDrawable, pGC, NPT, pt,
+ width, TRUE);
+ ipt = 0;
+ }
+ fInBox = FALSE;
+ }
+ }
+ mask = SCRRIGHT(mask, 1);
+ }
+ }
+ /* If scanline ended with last bit set, end the box */
+ if(fInBox)
+ {
+ width[ipt] = dx + xOrg - pt[ipt].x;
+ if (++ipt >= NPT)
+ {
+ (*pGC->ops->FillSpans)(pDrawable, pGC, NPT, pt, width, TRUE);
+ ipt = 0;
+ }
+ }
+ }
+ /* Flush any remaining spans */
+ if (ipt)
+ {
+ (*pGC->ops->FillSpans)(pDrawable, pGC, ipt, pt, width, TRUE);
+ }
+}
diff --git a/xc/programs/Xserver/mfb/mfbscrclse.c b/xc/programs/Xserver/mfb/mfbscrclse.c
new file mode 100644
index 000000000..f0d5dd706
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbscrclse.c
@@ -0,0 +1,55 @@
+/* $TOG: mfbscrclse.c /main/9 1998/02/09 14:40:07 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#include "scrnintstr.h"
+
+/*ARGSUSED*/
+Bool
+mfbCloseScreen(index, pScreen)
+ register ScreenPtr pScreen;
+{
+ xfree(pScreen->devPrivate);
+ return TRUE;
+}
+
diff --git a/xc/programs/Xserver/mfb/mfbscrinit.c b/xc/programs/Xserver/mfb/mfbscrinit.c
new file mode 100644
index 000000000..c46a70933
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbscrinit.c
@@ -0,0 +1,193 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbscrinit.c,v 3.6 1998/10/04 09:39:14 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbscrinit.c /main/28 1998/02/09 14:40:11 kaleb $ */
+
+#include "X.h"
+#include "Xproto.h" /* for xColorItem */
+#include "Xmd.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "resource.h"
+#include "colormap.h"
+#include "mfb.h"
+#include "mistruct.h"
+#include "dix.h"
+#include "mi.h"
+#include "mibstore.h"
+#include "migc.h"
+#include "servermd.h"
+
+#ifdef PIXMAP_PER_WINDOW
+int frameWindowPrivateIndex;
+#endif
+int mfbWindowPrivateIndex;
+int mfbGCPrivateIndex;
+static unsigned long mfbGeneration = 0;
+
+static VisualRec visual = {
+/* vid class bpRGB cmpE nplan rMask gMask bMask oRed oGreen oBlue */
+ 0, StaticGray, 1, 2, 1, 0, 0, 0, 0, 0, 0
+};
+
+static VisualID VID;
+
+static DepthRec depth = {
+/* depth numVid vids */
+ 1, 1, &VID
+};
+
+#ifndef LOWMEMFTPT
+
+BSFuncRec mfbBSFuncRec = {
+ mfbSaveAreas,
+ mfbRestoreAreas,
+ (BackingStoreSetClipmaskRgnProcPtr) 0,
+ (BackingStoreGetImagePixmapProcPtr) 0,
+ (BackingStoreGetSpansPixmapProcPtr) 0,
+};
+
+#endif /* ifndef LOWMEMFTPT */
+
+Bool
+mfbAllocatePrivates(pScreen, pWinIndex, pGCIndex)
+ ScreenPtr pScreen;
+ int *pWinIndex, *pGCIndex;
+{
+ if (mfbGeneration != serverGeneration)
+ {
+#ifdef PIXMAP_PER_WINDOW
+ frameWindowPrivateIndex = AllocateWindowPrivateIndex();
+#endif
+ mfbWindowPrivateIndex = AllocateWindowPrivateIndex();
+ mfbGCPrivateIndex = miAllocateGCPrivateIndex();
+ visual.vid = FakeClientID(0);
+ VID = visual.vid;
+ mfbGeneration = serverGeneration;
+ }
+ if (pWinIndex)
+ *pWinIndex = mfbWindowPrivateIndex;
+ if (pGCIndex)
+ *pGCIndex = mfbGCPrivateIndex;
+ pScreen->GetWindowPixmap = mfbGetWindowPixmap;
+ pScreen->SetWindowPixmap = mfbSetWindowPixmap;
+ return (AllocateWindowPrivate(pScreen, mfbWindowPrivateIndex,
+ sizeof(mfbPrivWin)) &&
+ AllocateGCPrivate(pScreen, mfbGCPrivateIndex, sizeof(mfbPrivGC)));
+}
+
+#ifndef LOWMEMFTPT
+
+/* dts * (inch/dot) * (25.4 mm / inch) = mm */
+Bool
+mfbScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width)
+ register ScreenPtr pScreen;
+ pointer pbits; /* pointer to screen bitmap */
+ int xsize, ysize; /* in pixels */
+ int dpix, dpiy; /* dots per inch */
+ int width; /* pixel width of frame buffer */
+{
+ if (!mfbAllocatePrivates(pScreen, (int *)NULL, (int *)NULL))
+ return FALSE;
+ pScreen->defColormap = (Colormap) FakeClientID(0);
+ /* whitePixel, blackPixel */
+ pScreen->QueryBestSize = mfbQueryBestSize;
+ /* SaveScreen */
+ pScreen->GetImage = mfbGetImage;
+ pScreen->GetSpans = mfbGetSpans;
+ pScreen->CreateWindow = mfbCreateWindow;
+ pScreen->DestroyWindow = mfbDestroyWindow;
+ pScreen->PositionWindow = mfbPositionWindow;
+ pScreen->ChangeWindowAttributes = mfbChangeWindowAttributes;
+ pScreen->RealizeWindow = mfbMapWindow;
+ pScreen->UnrealizeWindow = mfbUnmapWindow;
+ pScreen->PaintWindowBackground = mfbPaintWindow;
+ pScreen->PaintWindowBorder = mfbPaintWindow;
+ pScreen->CopyWindow = mfbCopyWindow;
+ pScreen->CreatePixmap = mfbCreatePixmap;
+ pScreen->DestroyPixmap = mfbDestroyPixmap;
+ pScreen->RealizeFont = mfbRealizeFont;
+ pScreen->UnrealizeFont = mfbUnrealizeFont;
+ pScreen->CreateGC = mfbCreateGC;
+ pScreen->CreateColormap = mfbCreateColormap;
+ pScreen->DestroyColormap = mfbDestroyColormap;
+ pScreen->InstallColormap = mfbInstallColormap;
+ pScreen->UninstallColormap = mfbUninstallColormap;
+ pScreen->ListInstalledColormaps = mfbListInstalledColormaps;
+ pScreen->StoreColors = (void (*)())NoopDDA;
+ pScreen->ResolveColor = mfbResolveColor;
+ pScreen->BitmapToRegion = mfbPixmapToRegion;
+ if (!miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
+ 1, 1, &depth, VID, 1, &visual))
+ return FALSE;
+ pScreen->BackingStoreFuncs = mfbBSFuncRec;
+ return TRUE;
+}
+#endif /* ifndef LOWMEMFTPT */
+
+PixmapPtr
+mfbGetWindowPixmap(pWin)
+ WindowPtr pWin;
+{
+#ifdef PIXMAP_PER_WINDOW
+ return (PixmapPtr)(pWin->devPrivates[frameWindowPrivateIndex].ptr);
+#else
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ return (* pScreen->GetScreenPixmap)(pScreen);
+#endif
+}
+
+void
+mfbSetWindowPixmap(pWin, pPix)
+ WindowPtr pWin;
+ PixmapPtr pPix;
+{
+#ifdef PIXMAP_PER_WINDOW
+ pWin->devPrivates[frameWindowPrivateIndex].ptr = (pointer)pPix;
+#else
+ (* pWin->drawable.pScreen->SetScreenPixmap)(pPix);
+#endif
+}
+
diff --git a/xc/programs/Xserver/mfb/mfbsetsp.c b/xc/programs/Xserver/mfb/mfbsetsp.c
new file mode 100644
index 000000000..ced199539
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbsetsp.c
@@ -0,0 +1,275 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbsetsp.c,v 1.4 1999/04/11 13:11:14 dawes Exp $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbsetsp.c /main/15 1998/02/09 14:40:16 kaleb $ */
+
+#include "X.h"
+#include "Xmd.h"
+
+#include "misc.h"
+#include "regionstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+#include "mfb.h"
+#include "maskbits.h"
+
+#include "servermd.h"
+
+
+/* mfbSetScanline -- copies the bits from psrc to the drawable starting at
+ * (xStart, y) and continuing to (xEnd, y). xOrigin tells us where psrc
+ * starts on the scanline. (I.e., if this scanline passes through multiple
+ * boxes, we may not want to start grabbing bits at psrc but at some offset
+ * further on.)
+ */
+void
+mfbSetScanline(y, xOrigin, xStart, xEnd, psrc, alu, pdstBase, widthDst)
+ int y;
+ int xOrigin; /* where this scanline starts */
+ int xStart; /* first bit to use from scanline */
+ int xEnd; /* last bit to use from scanline + 1 */
+ register PixelType *psrc;
+ register int alu; /* raster op */
+ PixelType *pdstBase; /* start of the drawable */
+ int widthDst; /* width of drawable in words */
+{
+ int w; /* width of scanline in bits */
+ register PixelType *pdst; /* where to put the bits */
+ register PixelType tmpSrc; /* scratch buffer to collect bits in */
+ int dstBit; /* offset in bits from beginning of
+ * word */
+ register int nstart; /* number of bits from first partial */
+ register int nend; /* " " last partial word */
+ int offSrc;
+ PixelType startmask, endmask;
+ int nlMiddle, nl;
+
+ pdst = mfbScanline(pdstBase, xStart, y, widthDst);
+ psrc += (xStart - xOrigin) >> PWSH;
+ offSrc = (xStart - xOrigin) & PIM;
+ w = xEnd - xStart;
+ dstBit = xStart & PIM;
+
+ if (dstBit + w <= PPW)
+ {
+ getandputrop(psrc, offSrc, dstBit, w, pdst, alu)
+ }
+ else
+ {
+
+ maskbits(xStart, w, startmask, endmask, nlMiddle);
+ if (startmask)
+ nstart = PPW - dstBit;
+ else
+ nstart = 0;
+ if (endmask)
+ nend = xEnd & PIM;
+ else
+ nend = 0;
+ if (startmask)
+ {
+ getandputrop(psrc, offSrc, dstBit, nstart, pdst, alu)
+ pdst++;
+ offSrc += nstart;
+ if (offSrc > PLST)
+ {
+ psrc++;
+ offSrc -= PPW;
+ }
+ }
+ nl = nlMiddle;
+ while (nl--)
+ {
+ getbits(psrc, offSrc, PPW, tmpSrc);
+ DoRop(*pdst, alu, tmpSrc, *pdst);
+ pdst++;
+ psrc++;
+ }
+ if (endmask)
+ {
+ getandputrop0(psrc, offSrc, nend, pdst, alu);
+ }
+
+ }
+}
+
+
+
+/* SetSpans -- for each span copy pwidth[i] bits from psrc to pDrawable at
+ * ppt[i] using the raster op from the GC. If fSorted is TRUE, the scanlines
+ * are in increasing Y order.
+ * Source bit lines are server scanline padded so that they always begin
+ * on a word boundary.
+ */
+void
+mfbSetSpans(pDrawable, pGC, pcharsrc, ppt, pwidth, nspans, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ char *pcharsrc;
+ register DDXPointPtr ppt;
+ int *pwidth;
+ int nspans;
+ int fSorted;
+{
+ PixelType *psrc = (PixelType *)pcharsrc;
+ PixelType *pdstBase; /* start of dst bitmap */
+ int widthDst; /* width of bitmap in words */
+ register BoxPtr pbox, pboxLast, pboxTest;
+ register DDXPointPtr pptLast;
+ int alu;
+ RegionPtr prgnDst;
+ int xStart, xEnd;
+ int yMax;
+
+ alu = pGC->alu;
+ prgnDst = pGC->pCompositeClip;
+
+ pptLast = ppt + nspans;
+
+ yMax = pDrawable->y + (int) pDrawable->height;
+ mfbGetPixelWidthAndPointer(pDrawable, widthDst, pdstBase);
+
+ pbox = REGION_RECTS(prgnDst);
+ pboxLast = pbox + REGION_NUM_RECTS(prgnDst);
+
+ if(fSorted)
+ {
+ /* scan lines sorted in ascending order. Because they are sorted, we
+ * don't have to check each scanline against each clip box. We can be
+ * sure that this scanline only has to be clipped to boxes at or after the
+ * beginning of this y-band
+ */
+ pboxTest = pbox;
+ while(ppt < pptLast)
+ {
+ pbox = pboxTest;
+ if(ppt->y >= yMax)
+ break;
+ while(pbox < pboxLast)
+ {
+ if(pbox->y1 > ppt->y)
+ {
+ /* scanline is before clip box */
+ break;
+ }
+ else if(pbox->y2 <= ppt->y)
+ {
+ /* clip box is before scanline */
+ pboxTest = ++pbox;
+ continue;
+ }
+ else if(pbox->x1 > ppt->x + *pwidth)
+ {
+ /* clip box is to right of scanline */
+ break;
+ }
+ else if(pbox->x2 <= ppt->x)
+ {
+ /* scanline is to right of clip box */
+ pbox++;
+ continue;
+ }
+
+ /* at least some of the scanline is in the current clip box */
+ xStart = max(pbox->x1, ppt->x);
+ xEnd = min(ppt->x + *pwidth, pbox->x2);
+ mfbSetScanline(ppt->y, ppt->x, xStart, xEnd, psrc, alu,
+ pdstBase, widthDst);
+ if(ppt->x + *pwidth <= pbox->x2)
+ {
+ /* End of the line, as it were */
+ break;
+ }
+ else
+ pbox++;
+ }
+ /* We've tried this line against every box; it must be outside them
+ * all. move on to the next point */
+ ppt++;
+ psrc += PixmapWidthInPadUnits(*pwidth, 1);
+ pwidth++;
+ }
+ }
+ else
+ {
+ /* scan lines not sorted. We must clip each line against all the boxes */
+ while(ppt < pptLast)
+ {
+ if(ppt->y >= 0 && ppt->y < yMax)
+ {
+
+ for(pbox = REGION_RECTS(prgnDst); pbox< pboxLast; pbox++)
+ {
+ if(pbox->y1 > ppt->y)
+ {
+ /* rest of clip region is above this scanline,
+ * skip it */
+ break;
+ }
+ if(pbox->y2 <= ppt->y)
+ {
+ /* clip box is below scanline */
+ pbox++;
+ break;
+ }
+ if(pbox->x1 <= ppt->x + *pwidth &&
+ pbox->x2 > ppt->x)
+ {
+ xStart = max(pbox->x1, ppt->x);
+ xEnd = min(pbox->x2, ppt->x + *pwidth);
+ mfbSetScanline(ppt->y, ppt->x, xStart, xEnd,
+ psrc, alu, pdstBase, widthDst);
+ }
+
+ }
+ }
+ psrc += PixmapWidthInPadUnits(*pwidth, 1);
+ ppt++;
+ pwidth++;
+ }
+ }
+}
diff --git a/xc/programs/Xserver/mfb/mfbtegblt.c b/xc/programs/Xserver/mfb/mfbtegblt.c
new file mode 100644
index 000000000..65cb48a21
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbtegblt.c
@@ -0,0 +1,423 @@
+/* $TOG: mfbtegblt.c /main/19 1998/02/09 14:40:20 kaleb $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* $XFree86: xc/programs/Xserver/mfb/mfbtegblt.c,v 1.5 1999/04/11 13:11:15 dawes Exp $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "mfb.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "regionstr.h"
+#include "maskbits.h"
+
+/*
+ this works for fonts with glyphs <= PPW bits wide.
+
+ This should be called only with a terminal-emulator font;
+this means that the FIXED_METRICS flag is set, and that
+glyphbounds == charbounds.
+
+ in theory, this goes faster; even if it doesn't, it reduces the
+flicker caused by writing a string over itself with image text (since
+the background gets repainted per character instead of per string.)
+this seems to be important for some converted X10 applications.
+
+ Image text looks at the bits in the glyph and the fg and bg in the
+GC. it paints a rectangle, as defined in the protocol dcoument,
+and the paints the characters.
+
+ to avoid source proliferation, this file is compiled
+two times:
+ MFBTEGLYPHBLT OP
+ mfbTEGlyphBltWhite (white text, black bg )
+ mfbTEGlyphBltBlack ~ (black text, white bg )
+
+*/
+
+#if defined(NO_3_60_CG4) && defined(FASTPUTBITS) && defined(FASTGETBITS)
+#define FASTCHARS
+#endif
+
+/*
+ * this macro "knows" that only characters <= 8 bits wide will
+ * fit this case (which is why it is independent of GLYPHPADBYTES)
+ */
+
+#if (BITMAP_BIT_ORDER == MSBFirst) && (GLYPHPADBYTES != 4)
+#if GLYPHPADBYTES == 1
+#define ShiftAmnt 24
+#else
+#define ShiftAmnt 16
+#endif
+
+/*
+ * XXX XXX XXX There is something horribly, massively wrong here. There are
+ * hardcoded shifts by 64 below; these cannot work on any present-day
+ * architecture.
+ */
+
+/*
+ * Note: for BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER, SCRRIGHT() evaluates its
+ * first argument more than once. Thus the imbedded char++ have to be moved.
+ * (DHD)
+ */
+#if BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER
+#if PPW == 32
+#define GetBits4 c = (*char1++ << ShiftAmnt) | \
+ SCRRIGHT (*char2++ << ShiftAmnt, xoff2) | \
+ SCRRIGHT (*char3++ << ShiftAmnt, xoff3) | \
+ SCRRIGHT (*char4++ << ShiftAmnt, xoff4);
+#else /* PPW */
+#define GetBits4 c = ((unsigned long)(*char1++ << ShiftAmnt) << 32 ) | \
+ (SCRRIGHT (*char2++ << ShiftAmnt, xoff2) << 32 ) | \
+ (SCRRIGHT (*char3++ << ShiftAmnt, xoff3) << 32 ) | \
+ (SCRRIGHT (*char4++ << ShiftAmnt, xoff4) << 32 ) | \
+ (*char5++ << ShiftAmnt) | \
+ SCRRIGHT (*char6++ << ShiftAmnt, xoff6) | \
+ SCRRIGHT (*char7++ << ShiftAmnt, xoff7) | \
+ SCRRIGHT (*char8++ << ShiftAmnt, xoff8);
+#endif /* PPW */
+#else /* BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER */
+#if PPW == 32
+#define GetBits4 c = (*char1++ << ShiftAmnt) | \
+ SCRRIGHT (*char2 << ShiftAmnt, xoff2) | \
+ SCRRIGHT (*char3 << ShiftAmnt, xoff3) | \
+ SCRRIGHT (*char4 << ShiftAmnt, xoff4); \
+ char2++; char3++; char4++;
+#else /* PPW == 64 */
+#define GetBits4 c = ((unsigned long)(*char1++ << ShiftAmnt) << 32 ) | \
+ (SCRRIGHT (*char2 << ShiftAmnt, xoff2) << 32 ) | \
+ (SCRRIGHT (*char3 << ShiftAmnt, xoff3) << 32 ) | \
+ (SCRRIGHT (*char4 << ShiftAmnt, xoff4) << 32 ) | \
+ (*char5++ << ShiftAmnt) | \
+ SCRRIGHT (*char6 << ShiftAmnt, xoff6) | \
+ SCRRIGHT (*char7 << ShiftAmnt, xoff7) | \
+ SCRRIGHT (*char8 << ShiftAmnt, xoff8); \
+ char2++; char3++; char4++; char6++; char7++; char8++;
+#endif /* PPW */
+#endif /* BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER */
+
+#else /* (BITMAP_BIT_ORDER != MSBFirst) || (GLYPHPADBYTES == 4) */
+
+#if BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER
+#if PPW == 32
+#define GetBits4 c = *char1++ | \
+ SCRRIGHT (*char2++, xoff2) | \
+ SCRRIGHT (*char3++, xoff3) | \
+ SCRRIGHT (*char4++, xoff4);
+#else /* PPW == 64 */
+#define GetBits4 c = (unsigned long)(((*char1++) << 64 ) | \
+ (SCRRIGHT (*char2++, xoff2) << 64 ) | \
+ (SCRRIGHT (*char3++, xoff3) << 64 ) | \
+ (SCRRIGHT (*char4++, xoff4) << 64 ) | \
+ SCRRIGHT (*char5++, xoff5) | \
+ SCRRIGHT (*char6++, xoff6) | \
+ SCRRIGHT (*char7++, xoff7) | \
+ SCRRIGHT (*char8++, xoff8));
+#endif /* PPW */
+#else /* BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER */
+#if PPW == 32
+#define GetBits4 c = *char1++ | \
+ SCRRIGHT (*char2, xoff2) | \
+ SCRRIGHT (*char3, xoff3) | \
+ SCRRIGHT (*char4, xoff4); \
+ char2++; char3++; char4++;
+#else /* PPW == 64 */
+#define GetBits4 c = (unsigned long)(((*char1++) << 64 ) | \
+ (SCRRIGHT (*char2, xoff2) << 64 ) | \
+ (SCRRIGHT (*char3, xoff3) << 64 ) | \
+ (SCRRIGHT (*char4, xoff4) << 64 ) | \
+ SCRRIGHT (*char5, xoff5) | \
+ SCRRIGHT (*char6, xoff6) | \
+ SCRRIGHT (*char7, xoff7) | \
+ SCRRIGHT (*char8, xoff8)); \
+ char2++; char3++; char4++; \
+ char5++; char6++; char7++; char8++;
+#endif /* PPW */
+#endif /* BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER */
+
+#endif /* BITMAP_BIT_ORDER && GLYPHPADBYTES */
+
+
+#if GLYPHPADBYTES == 1
+typedef unsigned char *glyphPointer;
+#define USE_LEFTBITS
+#endif
+
+#if GLYPHPADBYTES == 2
+typedef unsigned short *glyphPointer;
+#define USE_LEFTBITS
+#endif
+
+#if GLYPHPADBYTES == 4
+typedef unsigned int *glyphPointer;
+#endif
+
+#ifdef USE_LEFTBITS
+#define GetBits1 getleftbits (char1, widthGlyph, c); \
+ c &= glyphMask; \
+ char1 = (glyphPointer) (((char *) char1) + glyphBytes);
+#else
+#define GetBits1 c = *char1++;
+#endif
+
+void
+MFBTEGLYPHBLT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ pointer pglyphBase; /* start of array of glyphs */
+{
+ FontPtr pfont = pGC->font;
+ int widthDst;
+ PixelType *pdstBase; /* pointer to longword with top row
+ of current glyph */
+
+ int h; /* height of glyph and char */
+ register int xpos; /* current x */
+ int ypos; /* current y */
+ int widthGlyph;
+
+ int hTmp; /* counter for height */
+ register PixelType startmask, endmask;
+ int nfirst; /* used if glyphs spans a longword boundary */
+ BoxRec bbox; /* for clipping */
+ int widthGlyphs;
+ register PixelType *dst;
+ register PixelType c;
+ register int xoff1, xoff2, xoff3, xoff4;
+ register glyphPointer char1, char2, char3, char4;
+#if PPW == 64
+ register int xoff5, xoff6, xoff7, xoff8;
+ register glyphPointer char5, char6, char7, char8;
+#endif /* PPW */
+
+#ifdef USE_LEFTBITS
+ register PixelType glyphMask;
+ register PixelType tmpSrc;
+ register int glyphBytes;
+#endif
+
+ if (!(pGC->planemask & 1))
+ return;
+
+ mfbGetPixelWidthAndPointer(pDrawable, widthDst, pdstBase);
+
+ xpos = x + pDrawable->x;
+ ypos = y + pDrawable->y;
+
+ widthGlyph = FONTMAXBOUNDS(pfont,characterWidth);
+ h = FONTASCENT(pfont) + FONTDESCENT(pfont);
+
+ xpos += FONTMAXBOUNDS(pfont,leftSideBearing);
+ ypos -= FONTASCENT(pfont);
+
+ bbox.x1 = xpos;
+ bbox.x2 = xpos + (widthGlyph * nglyph);
+ bbox.y1 = ypos;
+ bbox.y2 = ypos + h;
+
+ switch (RECT_IN_REGION(pGC->pScreen, pGC->pCompositeClip, &bbox))
+ {
+ case rgnPART:
+ /* this is the WRONG thing to do, but it works.
+ calling the non-terminal text is easy, but slow, given
+ what we know about the font.
+
+ the right thing to do is something like:
+ for each clip rectangle
+ compute at which row the glyph starts to be in it,
+ and at which row the glyph ceases to be in it
+ compute which is the first glyph inside the left
+ edge, and the last one inside the right edge
+ draw a fractional first glyph, using only
+ the rows we know are in
+ draw all the whole glyphs, using the appropriate rows
+ draw any pieces of the last glyph, using the right rows
+
+ this way, the code would take advantage of knowing that
+ all glyphs are the same height and don't overlap.
+
+ one day...
+ */
+ CLIPTETEXT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ case rgnOUT:
+ return;
+ }
+ pdstBase = mfbScanlineDeltaNoBankSwitch(pdstBase, ypos, widthDst);
+ widthGlyphs = widthGlyph * PGSZB;
+
+#ifdef USE_LEFTBITS
+ glyphMask = endtab[widthGlyph];
+ glyphBytes = GLYPHWIDTHBYTESPADDED(*ppci);
+#endif
+
+ if (nglyph >= PGSZB && widthGlyphs <= PPW)
+ {
+ while (nglyph >= PGSZB)
+ {
+ nglyph -= PGSZB;
+ xoff1 = xpos & PIM;
+ xoff2 = widthGlyph;
+ xoff3 = xoff2 + widthGlyph;
+ xoff4 = xoff3 + widthGlyph;
+#if PPW == 64
+ xoff5 = xoff4 + widthGlyph;
+ xoff6 = xoff5 + widthGlyph;
+ xoff7 = xoff6 + widthGlyph;
+ xoff8 = xoff7 + widthGlyph;
+#endif /* PPW */
+ char1 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
+ char2 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
+ char3 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
+ char4 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
+#if PPW == 64
+ char5 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
+ char6 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
+ char7 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
+ char8 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
+#endif /* PPW */
+
+ hTmp = h;
+ dst = mfbScanlineOffset(pdstBase, (xpos >> PWSH)); /* switch now */
+
+#ifndef FASTCHARS
+ if (xoff1 + widthGlyphs <= PPW)
+ {
+ maskpartialbits (xoff1, widthGlyphs, startmask);
+#endif
+ while (hTmp--)
+ {
+ GetBits4
+#ifdef FASTCHARS
+# if BITMAP_BIT_ORDER == MSBFirst
+ c >>= PPW - widthGlyphs;
+# endif
+ FASTPUTBITS(OP(c), xoff1, widthGlyphs, dst);
+#else
+ *(dst) = ((*dst) & ~startmask) | (OP(SCRRIGHT(c, xoff1)) & startmask);
+#endif
+ mfbScanlineInc(dst, widthDst);
+ }
+#ifndef FASTCHARS
+ }
+ else
+ {
+ maskPPWbits (xoff1, widthGlyphs, startmask, endmask);
+ nfirst = PPW - xoff1;
+ while (hTmp--)
+ {
+ GetBits4
+ dst[0] = (dst[0] & ~startmask) |
+ (OP(SCRRIGHT(c,xoff1)) & startmask);
+ dst[1] = (dst[1] & ~endmask) |
+ (OP(SCRLEFT(c,nfirst)) & endmask);
+ mfbScanlineInc(dst, widthDst);
+ }
+ }
+#endif
+ xpos += widthGlyphs;
+ }
+ }
+
+ while(nglyph--)
+ {
+ xoff1 = xpos & PIM;
+ char1 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
+ hTmp = h;
+ dst = mfbScanlineOffset(pdstBase, (xpos >> PWSH));
+
+#ifndef FASTCHARS
+ if (xoff1 + widthGlyph <= PPW)
+ {
+ maskpartialbits (xoff1, widthGlyph, startmask);
+#endif
+ while (hTmp--)
+ {
+#ifdef FASTCHARS
+#ifdef USE_LEFTBITS
+ FASTGETBITS (char1,0,widthGlyph,c);
+ char1 = (glyphPointer) (((char *) char1) + glyphBytes);
+#else
+ c = *char1++;
+#if BITMAP_BIT_ORDER == MSBFirst
+ c >>= PPW - widthGlyph;
+#endif
+#endif
+ FASTPUTBITS (OP(c),xoff1,widthGlyph,dst);
+#else
+ GetBits1
+ (*dst) = ((*dst) & ~startmask) | (OP(SCRRIGHT(c, xoff1)) & startmask);
+#endif
+ mfbScanlineInc(dst, widthDst);
+ }
+#ifndef FASTCHARS
+ }
+ else
+ {
+ maskPPWbits (xoff1, widthGlyph, startmask, endmask);
+ nfirst = PPW - xoff1;
+ while (hTmp--)
+ {
+ GetBits1
+ dst[0] = (dst[0] & ~startmask) |
+ (OP(SCRRIGHT(c,xoff1)) & startmask);
+ dst[1] = (dst[1] & ~endmask) |
+ (OP(SCRLEFT(c,nfirst)) & endmask);
+ mfbScanlineInc(dst, widthDst);
+ }
+ }
+#endif
+ xpos += widthGlyph;
+ }
+}
diff --git a/xc/programs/Xserver/mfb/mfbtile.c b/xc/programs/Xserver/mfb/mfbtile.c
new file mode 100644
index 000000000..29cce3f2b
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbtile.c
@@ -0,0 +1,226 @@
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mfbtile.c /main/13 1998/02/09 14:40:25 kaleb $ */
+#include "X.h"
+
+#include "windowstr.h"
+#include "regionstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+#include "mfb.h"
+#include "maskbits.h"
+
+#include "mergerop.h"
+/*
+
+ the boxes are already translated.
+
+ NOTE:
+ iy = ++iy < tileHeight ? iy : 0
+is equivalent to iy%= tileheight, and saves a division.
+*/
+
+/*
+ tile area with a PPW bit wide pixmap
+*/
+void
+MROP_NAME(mfbTileAreaPPW)(pDraw, nbox, pbox, alu, ptile)
+ DrawablePtr pDraw;
+ int nbox;
+ BoxPtr pbox;
+ int alu;
+ PixmapPtr ptile;
+{
+ register PixelType *psrc;
+ /* pointer to bits in tile, if needed */
+ int tileHeight; /* height of the tile */
+ register PixelType srcpix;
+ int nlwidth; /* width in longwords of the drawable */
+ int w; /* width of current box */
+ MROP_DECLARE_REG ()
+ register int h; /* height of current box */
+ register int nlw; /* loop version of nlwMiddle */
+ register PixelType *p; /* pointer to bits we're writing */
+ PixelType startmask;
+ PixelType endmask; /* masks for reggedy bits at either end of line */
+ int nlwMiddle; /* number of longwords between sides of boxes */
+ int nlwExtra; /* to get from right of box to left of next span */
+ register int iy; /* index of current scanline in tile */
+ PixelType *pbits; /* pointer to start of drawable */
+
+ mfbGetPixelWidthAndPointer(pDraw, nlwidth, pbits);
+
+ MROP_INITIALIZE(alu,~0)
+
+ tileHeight = ptile->drawable.height;
+ psrc = (PixelType *)(ptile->devPrivate.ptr);
+
+ while (nbox--)
+ {
+ w = pbox->x2 - pbox->x1;
+ h = pbox->y2 - pbox->y1;
+ iy = pbox->y1 % tileHeight;
+ p = mfbScanline(pbits, pbox->x1, pbox->y1, nlwidth);
+
+ if ( ((pbox->x1 & PIM) + w) < PPW)
+ {
+ maskpartialbits(pbox->x1, w, startmask);
+ nlwExtra = nlwidth;
+ while (h--)
+ {
+ srcpix = psrc[iy];
+ iy++;
+ if (iy == tileHeight)
+ iy = 0;
+ *p = MROP_MASK(srcpix,*p,startmask);
+ mfbScanlineInc(p, nlwExtra);
+ }
+ }
+ else
+ {
+ maskbits(pbox->x1, w, startmask, endmask, nlwMiddle);
+ nlwExtra = nlwidth - nlwMiddle;
+
+ if (startmask && endmask)
+ {
+ nlwExtra -= 1;
+ while (h--)
+ {
+ srcpix = psrc[iy];
+ iy++;
+ if (iy == tileHeight)
+ iy = 0;
+ nlw = nlwMiddle;
+ *p = MROP_MASK (srcpix,*p,startmask);
+ p++;
+ while (nlw--)
+ {
+ *p = MROP_SOLID(srcpix,*p);
+ p++;
+ }
+
+ *p = MROP_MASK(srcpix,*p,endmask);
+ mfbScanlineInc(p, nlwExtra);
+ }
+ }
+ else if (startmask && !endmask)
+ {
+ nlwExtra -= 1;
+ while (h--)
+ {
+ srcpix = psrc[iy];
+ iy++;
+ if (iy == tileHeight)
+ iy = 0;
+ nlw = nlwMiddle;
+ *p = MROP_MASK(srcpix,*p,startmask);
+ p++;
+ while (nlw--)
+ {
+ *p = MROP_SOLID(srcpix,*p);
+ p++;
+ }
+ mfbScanlineInc(p, nlwExtra);
+ }
+ }
+ else if (!startmask && endmask)
+ {
+ while (h--)
+ {
+ srcpix = psrc[iy];
+ iy++;
+ if (iy == tileHeight)
+ iy = 0;
+ nlw = nlwMiddle;
+ while (nlw--)
+ {
+ *p = MROP_SOLID(srcpix,*p);
+ p++;
+ }
+
+ *p = MROP_MASK(srcpix,*p,endmask);
+ mfbScanlineInc(p, nlwExtra);
+ }
+ }
+ else /* no ragged bits at either end */
+ {
+ while (h--)
+ {
+ srcpix = psrc[iy];
+ iy++;
+ if (iy == tileHeight)
+ iy = 0;
+ nlw = nlwMiddle;
+ while (nlw--)
+ {
+ *p = MROP_SOLID (srcpix,*p);
+ p++;
+ }
+ mfbScanlineInc(p, nlwExtra);
+ }
+ }
+ }
+ pbox++;
+ }
+}
+
+#if (MROP) == 0
+void
+mfbTileAreaPPW (pDraw, nbox, pbox, alu, ptile)
+ DrawablePtr pDraw;
+ int nbox;
+ BoxPtr pbox;
+ int alu;
+ PixmapPtr ptile;
+{
+ void (*f)(), mfbTileAreaPPWCopy(), mfbTileAreaPPWGeneral();
+
+ if (alu == GXcopy)
+ f = mfbTileAreaPPWCopy;
+ else
+ f = mfbTileAreaPPWGeneral;
+ (*f) (pDraw, nbox, pbox, alu, ptile);
+}
+#endif
diff --git a/xc/programs/Xserver/mfb/mfbwindow.c b/xc/programs/Xserver/mfb/mfbwindow.c
new file mode 100644
index 000000000..58684b916
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbwindow.c
@@ -0,0 +1,334 @@
+/* $TOG: mfbwindow.c /main/33 1998/02/09 14:40:29 kaleb $ */
+/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "mfb.h"
+#include "mistruct.h"
+#include "regionstr.h"
+#include "maskbits.h"
+
+extern WindowPtr *WindowTable;
+
+Bool
+mfbCreateWindow(pWin)
+ register WindowPtr pWin;
+{
+ register mfbPrivWin *pPrivWin;
+
+ pPrivWin = (mfbPrivWin *)(pWin->devPrivates[mfbWindowPrivateIndex].ptr);
+ pPrivWin->pRotatedBorder = NullPixmap;
+ pPrivWin->pRotatedBackground = NullPixmap;
+ pPrivWin->fastBackground = FALSE;
+ pPrivWin->fastBorder = FALSE;
+
+ return (TRUE);
+}
+
+/* This always returns true, because Xfree can't fail. It might be possible
+ * on some devices for Destroy to fail */
+Bool
+mfbDestroyWindow(pWin)
+ WindowPtr pWin;
+{
+ register mfbPrivWin *pPrivWin;
+
+ pPrivWin = (mfbPrivWin *)(pWin->devPrivates[mfbWindowPrivateIndex].ptr);
+
+ if (pPrivWin->pRotatedBorder)
+ (*pWin->drawable.pScreen->DestroyPixmap)(pPrivWin->pRotatedBorder);
+ if (pPrivWin->pRotatedBackground)
+ (*pWin->drawable.pScreen->DestroyPixmap)(pPrivWin->pRotatedBackground);
+ return (TRUE);
+}
+
+/*ARGSUSED*/
+Bool mfbMapWindow(pWindow)
+ WindowPtr pWindow;
+{
+ return (TRUE);
+}
+
+/* (x, y) is the upper left corner of the window on the screen
+ do we really need to pass this? (is it a;ready in pWin->absCorner?)
+ we only do the rotation for pixmaps that are 32 bits wide (padded
+or otherwise.)
+ mfbChangeWindowAttributes() has already put a copy of the pixmap
+in pPrivWin->pRotated*
+*/
+
+/*ARGSUSED*/
+Bool
+mfbPositionWindow(pWin, x, y)
+ register WindowPtr pWin;
+ int x, y;
+{
+ register mfbPrivWin *pPrivWin;
+ int reset = 0;
+
+ pPrivWin = (mfbPrivWin *)(pWin->devPrivates[mfbWindowPrivateIndex].ptr);
+ if (pWin->backgroundState == BackgroundPixmap && pPrivWin->fastBackground)
+ {
+ mfbXRotatePixmap(pPrivWin->pRotatedBackground,
+ pWin->drawable.x - pPrivWin->oldRotate.x);
+ mfbYRotatePixmap(pPrivWin->pRotatedBackground,
+ pWin->drawable.y - pPrivWin->oldRotate.y);
+ reset = 1;
+ }
+
+ if (!pWin->borderIsPixel && pPrivWin->fastBorder)
+ {
+ while (pWin->backgroundState == ParentRelative)
+ pWin = pWin->parent;
+ mfbXRotatePixmap(pPrivWin->pRotatedBorder,
+ pWin->drawable.x - pPrivWin->oldRotate.x);
+ mfbYRotatePixmap(pPrivWin->pRotatedBorder,
+ pWin->drawable.y - pPrivWin->oldRotate.y);
+ reset = 1;
+ }
+ if (reset)
+ {
+ pPrivWin->oldRotate.x = pWin->drawable.x;
+ pPrivWin->oldRotate.y = pWin->drawable.y;
+ }
+
+ /* This is the "wrong" fix to the right problem, but it doesn't really
+ * cost very much. When the window is moved, we need to invalidate any
+ * RotatedPixmap that exists in any GC currently validated against this
+ * window.
+ */
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ /* Again, we have no failure modes indicated by any of the routines
+ * we've called, so we have to assume it worked */
+ return (TRUE);
+}
+
+/*ARGSUSED*/
+Bool
+mfbUnmapWindow(pWindow)
+ WindowPtr pWindow;
+{
+ return (TRUE);
+}
+
+/* UNCLEAN!
+ this code calls the bitblt helper code directly.
+
+ mfbCopyWindow copies only the parts of the destination that are
+visible in the source.
+*/
+
+
+void
+mfbCopyWindow(pWin, ptOldOrg, prgnSrc)
+ WindowPtr pWin;
+ DDXPointRec ptOldOrg;
+ RegionPtr prgnSrc;
+{
+ DDXPointPtr pptSrc;
+ register DDXPointPtr ppt;
+ RegionPtr prgnDst;
+ register BoxPtr pbox;
+ register int dx, dy;
+ register int i, nbox;
+ WindowPtr pwinRoot;
+
+ pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];
+
+ prgnDst = REGION_CREATE(pWin->drawable.pScreen, NULL, 1);
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
+ REGION_INTERSECT(pWin->drawable.pScreen, prgnDst, &pWin->borderClip,
+ prgnSrc);
+
+ pbox = REGION_RECTS(prgnDst);
+ nbox = REGION_NUM_RECTS(prgnDst);
+ if(!(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec))))
+ return;
+ ppt = pptSrc;
+
+ for (i=nbox; --i >= 0; ppt++, pbox++)
+ {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ mfbDoBitblt((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
+ GXcopy, prgnDst, pptSrc);
+ DEALLOCATE_LOCAL(pptSrc);
+ REGION_DESTROY(pWin->drawable.pScreen, prgnDst);
+}
+
+
+
+/* swap in correct PaintWindow* routine. If we can use a fast output
+routine (i.e. the pixmap is paddable to 32 bits), also pre-rotate a copy
+of it in devPrivate.
+*/
+Bool
+mfbChangeWindowAttributes(pWin, mask)
+ register WindowPtr pWin;
+ register unsigned long mask;
+{
+ register unsigned long index;
+ register mfbPrivWin *pPrivWin;
+ WindowPtr pBgWin;
+
+ pPrivWin = (mfbPrivWin *)(pWin->devPrivates[mfbWindowPrivateIndex].ptr);
+ /*
+ * When background state changes from ParentRelative and
+ * we had previously rotated the fast border pixmap to match
+ * the parent relative origin, rerotate to match window
+ */
+ if (mask & (CWBackPixmap | CWBackPixel) &&
+ pWin->backgroundState != ParentRelative &&
+ pPrivWin->fastBorder &&
+ (pPrivWin->oldRotate.x != pWin->drawable.x ||
+ pPrivWin->oldRotate.y != pWin->drawable.y))
+ {
+ mfbXRotatePixmap(pPrivWin->pRotatedBorder,
+ pWin->drawable.x - pPrivWin->oldRotate.x);
+ mfbYRotatePixmap(pPrivWin->pRotatedBorder,
+ pWin->drawable.y - pPrivWin->oldRotate.y);
+ pPrivWin->oldRotate.x = pWin->drawable.x;
+ pPrivWin->oldRotate.y = pWin->drawable.y;
+ }
+ while(mask)
+ {
+ index = lowbit (mask);
+ mask &= ~index;
+ switch(index)
+ {
+ case CWBackPixmap:
+ if (pWin->backgroundState == None)
+ {
+ pPrivWin->fastBackground = FALSE;
+ }
+ else if (pWin->backgroundState == ParentRelative)
+ {
+ pPrivWin->fastBackground = FALSE;
+ /* Rotate border to match parent origin */
+ if (pPrivWin->pRotatedBorder) {
+ for (pBgWin = pWin->parent;
+ pBgWin->backgroundState == ParentRelative;
+ pBgWin = pBgWin->parent);
+ mfbXRotatePixmap(pPrivWin->pRotatedBorder,
+ pBgWin->drawable.x - pPrivWin->oldRotate.x);
+ mfbYRotatePixmap(pPrivWin->pRotatedBorder,
+ pBgWin->drawable.y - pPrivWin->oldRotate.y);
+ pPrivWin->oldRotate.x = pBgWin->drawable.x;
+ pPrivWin->oldRotate.y = pBgWin->drawable.y;
+ }
+ }
+ else if ((pWin->background.pixmap->drawable.width <= PPW) &&
+ !(pWin->background.pixmap->drawable.width &
+ (pWin->background.pixmap->drawable.width - 1)))
+ {
+ mfbCopyRotatePixmap(pWin->background.pixmap,
+ &pPrivWin->pRotatedBackground,
+ pWin->drawable.x,
+ pWin->drawable.y);
+ if (pPrivWin->pRotatedBackground)
+ {
+ pPrivWin->fastBackground = TRUE;
+ pPrivWin->oldRotate.x = pWin->drawable.x;
+ pPrivWin->oldRotate.y = pWin->drawable.y;
+ }
+ else
+ {
+ pPrivWin->fastBackground = FALSE;
+ }
+ }
+ else
+ {
+ pPrivWin->fastBackground = FALSE;
+ }
+ break;
+
+ case CWBackPixel:
+ pPrivWin->fastBackground = FALSE;
+ break;
+
+ case CWBorderPixmap:
+ if ((pWin->border.pixmap->drawable.width <= PPW) &&
+ !(pWin->border.pixmap->drawable.width &
+ (pWin->border.pixmap->drawable.width - 1)))
+ {
+ for (pBgWin = pWin;
+ pBgWin->backgroundState == ParentRelative;
+ pBgWin = pBgWin->parent);
+ mfbCopyRotatePixmap(pWin->border.pixmap,
+ &pPrivWin->pRotatedBorder,
+ pBgWin->drawable.x,
+ pBgWin->drawable.y);
+ if (pPrivWin->pRotatedBorder)
+ {
+ pPrivWin->fastBorder = TRUE;
+ pPrivWin->oldRotate.x = pBgWin->drawable.x;
+ pPrivWin->oldRotate.y = pBgWin->drawable.y;
+ }
+ else
+ {
+ pPrivWin->fastBorder = FALSE;
+ }
+ }
+ else
+ {
+ pPrivWin->fastBorder = FALSE;
+ }
+ break;
+ case CWBorderPixel:
+ pPrivWin->fastBorder = FALSE;
+ break;
+ }
+ }
+ /* Again, we have no failure modes indicated by any of the routines
+ * we've called, so we have to assume it worked */
+ return (TRUE);
+}
diff --git a/xc/programs/Xserver/mfb/mfbzerarc.c b/xc/programs/Xserver/mfb/mfbzerarc.c
new file mode 100644
index 000000000..1c1d5a947
--- /dev/null
+++ b/xc/programs/Xserver/mfb/mfbzerarc.c
@@ -0,0 +1,250 @@
+/* $XFree86: xc/programs/Xserver/mfb/mfbzerarc.c,v 3.3 1998/10/04 09:39:18 dawes Exp $ */
+/************************************************************
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+********************************************************/
+
+/* $TOG: mfbzerarc.c /main/22 1998/02/09 14:40:34 kaleb $ */
+
+/* Derived from:
+ * "Algorithm for drawing ellipses or hyperbolae with a digital plotter"
+ * by M. L. V. Pitteway
+ * The Computer Journal, November 1967, Volume 10, Number 3, pp. 282-289
+ */
+
+#include "X.h"
+#include "Xprotostr.h"
+#include "miscstruct.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "mfb.h"
+#include "maskbits.h"
+#include "mizerarc.h"
+#include "mi.h"
+
+/*
+ * Note: LEFTMOST must be the bit leftmost in the actual screen
+ * representation. This depends also on the IMAGE_BYTE_ORDER.
+ * LONG2CHARS() takes care of the re-ordering as required. (DHD)
+ */
+#if (BITMAP_BIT_ORDER == MSBFirst)
+#define LEFTMOST ((PixelType) LONG2CHARS(((unsigned long)1 << PLST)))
+#else
+#define LEFTMOST ((PixelType) LONG2CHARS(1))
+#endif
+
+#define PixelateWhite(addr,yoff,xoff) \
+ *mfbScanlineOffset(addr, (yoff)+((xoff)>>PWSH)) |= \
+ SCRRIGHT (LEFTMOST, ((xoff) & PIM))
+#define PixelateBlack(addr,yoff,xoff) \
+ *mfbScanlineOffset(addr, (yoff)+((xoff)>>PWSH)) &= \
+ ~(SCRRIGHT (LEFTMOST, ((xoff) & PIM)))
+
+#define Pixelate(base,yoff,xoff) \
+{ \
+ paddr = mfbScanlineOffset(base, (yoff) + ((xoff)>>PWSH)); \
+ pmask = SCRRIGHT(LEFTMOST, (xoff) & PIM); \
+ *paddr = (*paddr & ~pmask) | (pixel & pmask); \
+}
+
+#define DoPix(bit,base,yoff,xoff) if (mask & bit) Pixelate(base,yoff,xoff);
+
+static void
+mfbZeroArcSS(pDraw, pGC, arc)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ xArc *arc;
+{
+ miZeroArcRec info;
+ Bool do360;
+ register int x, y, a, b, d, mask;
+ register int k1, k3, dx, dy;
+ PixelType *addrl;
+ PixelType *yorgl, *yorgol;
+ PixelType pixel;
+ int nlwidth, yoffset, dyoffset;
+ PixelType pmask;
+ register PixelType *paddr;
+
+ if (((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->rop ==
+ RROP_BLACK)
+ pixel = 0;
+ else
+ pixel = ~0;
+
+ mfbGetPixelWidthAndPointer(pDraw, nlwidth, addrl);
+ do360 = miZeroArcSetup(arc, &info, TRUE);
+ yorgl = addrl + ((info.yorg + pDraw->y) * nlwidth);
+ yorgol = addrl + ((info.yorgo + pDraw->y) * nlwidth);
+ info.xorg += pDraw->x;
+ info.xorgo += pDraw->x;
+ MIARCSETUP();
+ yoffset = y ? nlwidth : 0;
+ dyoffset = 0;
+ mask = info.initialMask;
+ if (!(arc->width & 1))
+ {
+ DoPix(2, yorgl, 0, info.xorgo);
+ DoPix(8, yorgol, 0, info.xorgo);
+ }
+ if (!info.end.x || !info.end.y)
+ {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ if (do360 && (arc->width == arc->height) && !(arc->width & 1))
+ {
+ int xoffset = nlwidth;
+ PixelType *yorghl = mfbScanlineDeltaNoBankSwitch(yorgl, info.h, nlwidth);
+ int xorghp = info.xorg + info.h;
+ int xorghn = info.xorg - info.h;
+
+ if (pixel)
+ {
+ while (1)
+ {
+ PixelateWhite(yorgl, yoffset, info.xorg + x);
+ PixelateWhite(yorgl, yoffset, info.xorg - x);
+ PixelateWhite(yorgol, -yoffset, info.xorg - x);
+ PixelateWhite(yorgol, -yoffset, info.xorg + x);
+ if (a < 0)
+ break;
+ PixelateWhite(yorghl, -xoffset, xorghp - y);
+ PixelateWhite(yorghl, -xoffset, xorghn + y);
+ PixelateWhite(yorghl, xoffset, xorghn + y);
+ PixelateWhite(yorghl, xoffset, xorghp - y);
+ xoffset += nlwidth;
+ MIARCCIRCLESTEP(yoffset += nlwidth;);
+ }
+ }
+ else
+ {
+ while (1)
+ {
+ PixelateBlack(yorgl, yoffset, info.xorg + x);
+ PixelateBlack(yorgl, yoffset, info.xorg - x);
+ PixelateBlack(yorgol, -yoffset, info.xorg - x);
+ PixelateBlack(yorgol, -yoffset, info.xorg + x);
+ if (a < 0)
+ break;
+ PixelateBlack(yorghl, -xoffset, xorghp - y);
+ PixelateBlack(yorghl, -xoffset, xorghn + y);
+ PixelateBlack(yorghl, xoffset, xorghn + y);
+ PixelateBlack(yorghl, xoffset, xorghp - y);
+ xoffset += nlwidth;
+ MIARCCIRCLESTEP(yoffset += nlwidth;);
+ }
+ }
+ x = info.w;
+ yoffset = info.h * nlwidth;
+ }
+ else if (do360)
+ {
+ while (y < info.h || x < info.w)
+ {
+ MIARCOCTANTSHIFT(dyoffset = nlwidth;);
+ Pixelate(yorgl, yoffset, info.xorg + x);
+ Pixelate(yorgl, yoffset, info.xorgo - x);
+ Pixelate(yorgol, -yoffset, info.xorgo - x);
+ Pixelate(yorgol, -yoffset, info.xorg + x);
+ MIARCSTEP(yoffset += dyoffset;, yoffset += nlwidth;);
+ }
+ }
+ else
+ {
+ while (y < info.h || x < info.w)
+ {
+ MIARCOCTANTSHIFT(dyoffset = nlwidth;);
+ if ((x == info.start.x) || (y == info.start.y))
+ {
+ mask = info.start.mask;
+ info.start = info.altstart;
+ }
+ DoPix(1, yorgl, yoffset, info.xorg + x);
+ DoPix(2, yorgl, yoffset, info.xorgo - x);
+ DoPix(4, yorgol, -yoffset, info.xorgo - x);
+ DoPix(8, yorgol, -yoffset, info.xorg + x);
+ if ((x == info.end.x) || (y == info.end.y))
+ {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ MIARCSTEP(yoffset += dyoffset;, yoffset += nlwidth;);
+ }
+ }
+ if ((x == info.start.x) || (y == info.start.y))
+ mask = info.start.mask;
+ DoPix(1, yorgl, yoffset, info.xorg + x);
+ DoPix(4, yorgol, -yoffset, info.xorgo - x);
+ if (arc->height & 1)
+ {
+ DoPix(2, yorgl, yoffset, info.xorgo - x);
+ DoPix(8, yorgol, -yoffset, info.xorg + x);
+ }
+}
+
+void
+mfbZeroPolyArcSS(pDraw, pGC, narcs, parcs)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ register xArc *arc;
+ register int i;
+ BoxRec box;
+ int x2, y2;
+ RegionPtr cclip;
+
+ if (!pGC->planemask & 1)
+ return;
+ cclip = pGC->pCompositeClip;
+ for (arc = parcs, i = narcs; --i >= 0; arc++)
+ {
+ if (miCanZeroArc(arc))
+ {
+ box.x1 = arc->x + pDraw->x;
+ box.y1 = arc->y + pDraw->y;
+ /*
+ * Because box.x2 and box.y2 get truncated to 16 bits, and the
+ * RECT_IN_REGION test treats the resulting number as a signed
+ * integer, the RECT_IN_REGION test alone can go the wrong way.
+ * This can result in a server crash because the rendering
+ * routines in this file deal directly with cpu addresses
+ * of pixels to be stored, and do not clip or otherwise check
+ * that all such addresses are within their respective pixmaps.
+ * So we only allow the RECT_IN_REGION test to be used for
+ * values that can be expressed correctly in a signed short.
+ */
+ x2 = box.x1 + (int)arc->width + 1;
+ box.x2 = x2;
+ y2 = box.y1 + (int)arc->height + 1;
+ box.y2 = y2;
+ if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) &&
+ (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
+ mfbZeroArcSS(pDraw, pGC, arc);
+ else
+ miZeroPolyArc(pDraw, pGC, 1, arc);
+ }
+ else
+ miPolyArc(pDraw, pGC, 1, arc);
+ }
+}
diff --git a/xc/programs/Xserver/mi/Imakefile b/xc/programs/Xserver/mi/Imakefile
new file mode 100644
index 000000000..e0c32fcdd
--- /dev/null
+++ b/xc/programs/Xserver/mi/Imakefile
@@ -0,0 +1,77 @@
+XCOMM $XConsortium: Imakefile /main/44 1996/12/02 10:22:16 lehors $
+XCOMM $XFree86: xc/programs/Xserver/mi/Imakefile,v 3.25 1999/08/14 10:50:19 dawes Exp $
+#include <Server.tmpl>
+
+#if ! HasCbrt
+CBRT_SRC = cbrt.c
+CBRT_OBJ = cbrt.o
+#endif
+
+#if DoLoadableServer
+EXTRAMIINITEXTOBJ = miinitext.o
+#else
+MIINITEXTSRC = miinitext.c
+MIINITEXTOBJ = miinitext.o
+#endif
+
+SRCS = $(CBRT_SRC) mivaltree.c mipolyseg.c mipolyrect.c \
+ mipoly.c mipolycon.c mipolygen.c mipolyutil.c \
+ mifillrct.c miwideline.c mispans.c \
+ miarc.c mizerarc.c mifillarc.c \
+ miwindow.c micursor.c miregion.c \
+ mipolytext.c mibitblt.c mipolypnt.c mipushpxl.c \
+ miexpose.c miglblt.c mizerline.c mifpolycon.c \
+ midash.c mibstore.c mibank.c $(MIINITEXTSRC) mieq.c \
+ mipointer.c misprite.c midispcur.c miscrinit.c miclipn.c migc.c \
+ micmap.c
+
+OBJS = $(CBRT_OBJ) mivaltree.o mipolyseg.o mipolyrect.o \
+ mipoly.o mipolycon.o mipolygen.o mipolyutil.o \
+ mifillrct.o miwideline.o mispans.o \
+ miarc.o mizerarc.o mifillarc.o \
+ miwindow.o micursor.o miregion.o \
+ mipolytext.o mibitblt.o mipolypnt.o mipushpxl.o \
+ miexpose.o miglblt.o mizerline.o mifpolycon.o \
+ midash.o mibstore.o mibank.o $(MIINITEXTOBJ) mieq.o \
+ mipointer.o misprite.o midispcur.o miscrinit.o miclipn.o migc.o \
+ micmap.o
+
+#ifdef XFree86Version
+/*
+ * Make sure XINPUT, XF86VidTune, etc aren't defined for the miinitext.o
+ * used by Xnest, Xvfb
+ */
+EXT_DEFINES = ExtensionDefines -UXINPUT -UXF86VIDMODE -UXFreeXDGA -UXF86MISC \
+ -UXFree86LOADER
+#else
+EXT_DEFINES = ExtensionDefines
+#endif
+
+INCLUDES = -I. -I../include -I../../../include/fonts \
+ -I$(XINCLUDESRC) -I$(FONTINCSRC) -I$(EXTINCSRC)
+LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(mi,$(OBJS))
+LintLibraryTarget(mi,$(SRCS))
+NormalLintTarget($(SRCS))
+
+#ifndef Win32Architecture
+NormalLibraryTarget(cbrt,cbrt.o)
+#endif
+
+SpecialCObjectRule(miinitext,$(ICONFIGFILES),$(EXT_DEFINES))
+SpecialCObjectRule(miscrinit,$(ICONFIGFILES),$(EXT_DEFINES))
+
+AllTarget($(EXTRAMIINITEXTOBJ))
+
+DependTarget()
+
+InstallDriverSDKNonExecFile(mi.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(mibank.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(mibstore.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(micmap.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(miline.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(mipointer.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(mipointrst.h,$(DRIVERSDKINCLUDEDIR))
+InstallDriverSDKNonExecFile(mizerarc.h,$(DRIVERSDKINCLUDEDIR))
diff --git a/xc/programs/Xserver/mi/cbrt.c b/xc/programs/Xserver/mi/cbrt.c
new file mode 100644
index 000000000..2fc024d9b
--- /dev/null
+++ b/xc/programs/Xserver/mi/cbrt.c
@@ -0,0 +1,39 @@
+/* $TOG: cbrt.c /main/4 1998/02/09 14:45:52 kaleb $ */
+/*
+
+Copyright 1990, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+/* $XFree86: xc/programs/Xserver/mi/cbrt.c,v 3.1 1998/10/04 09:39:22 dawes Exp $ */
+
+/* simple cbrt, in case your math library doesn't have a good one */
+
+double pow();
+
+double
+cbrt(x)
+ double x;
+{
+ if (x > 0.0)
+ return pow(x, 1.0/3.0);
+ else
+ return -pow(-x, 1.0/3.0);
+}
diff --git a/xc/programs/Xserver/mi/mi.h b/xc/programs/Xserver/mi/mi.h
new file mode 100644
index 000000000..5eda8982d
--- /dev/null
+++ b/xc/programs/Xserver/mi/mi.h
@@ -0,0 +1,768 @@
+/* $TOG: mi.h /main/18 1998/02/09 14:49:50 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/mi/mi.h,v 3.5 1999/04/11 13:11:18 dawes Exp $ */
+
+#ifndef MI_H
+#define MI_H
+#include "X11/X.h"
+#include "region.h"
+#include "validate.h"
+#include "window.h"
+#include "gc.h"
+#include "font.h"
+#include "input.h"
+#include "cursor.h"
+
+typedef struct _miDash *miDashPtr;
+#define EVEN_DASH 0
+#define ODD_DASH ~0
+
+/* miarc.c */
+
+extern void miPolyArc(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+
+/* mibitblt.c */
+
+extern RegionPtr miCopyArea(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ GCPtr /*pGC*/,
+ int /*xIn*/,
+ int /*yIn*/,
+ int /*widthSrc*/,
+ int /*heightSrc*/,
+ int /*xOut*/,
+ int /*yOut*/
+#endif
+);
+
+extern void miOpqStipDrawable(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ RegionPtr /*prgnSrc*/,
+ unsigned long * /*pbits*/,
+ int /*srcx*/,
+ int /*w*/,
+ int /*h*/,
+ int /*dstx*/,
+ int /*dsty*/
+#endif
+);
+
+extern RegionPtr miCopyPlane(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ GCPtr /*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*width*/,
+ int /*height*/,
+ int /*dstx*/,
+ int /*dsty*/,
+ unsigned long /*bitPlane*/
+#endif
+);
+
+extern void miGetImage(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ int /*sx*/,
+ int /*sy*/,
+ int /*w*/,
+ int /*h*/,
+ unsigned int /*format*/,
+ unsigned long /*planeMask*/,
+ char * /*pdstLine*/
+#endif
+);
+
+extern void miPutImage(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*depth*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ int /*leftPad*/,
+ int /*format*/,
+ char * /*pImage*/
+#endif
+);
+
+/* miclipn.c */
+
+extern void miClipNotify(
+#if NeedFunctionPrototypes
+ void (* /*func*/)(
+#if NeedNestedPrototypes
+ WindowPtr /* pWin */,
+ int /* dx */,
+ int /* dy */
+#endif
+ )
+#endif
+);
+
+/* micursor.c */
+
+extern void miRecolorCursor(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScr*/,
+ CursorPtr /*pCurs*/,
+ Bool /*displayed*/
+#endif
+);
+
+/* midash.c */
+
+extern miDashPtr miDashLine(
+#if NeedFunctionPrototypes
+ int /*npt*/,
+ DDXPointPtr /*ppt*/,
+ unsigned int /*nDash*/,
+ unsigned char * /*pDash*/,
+ unsigned int /*offset*/,
+ int * /*pnseg*/
+#endif
+);
+
+extern void miStepDash(
+#if NeedFunctionPrototypes
+ int /*dist*/,
+ int * /*pDashIndex*/,
+ unsigned char * /*pDash*/,
+ int /*numInDashList*/,
+ int * /*pDashOffset*/
+#endif
+);
+
+/* mieq.c */
+
+
+#ifndef INPUT_H
+typedef struct _DeviceRec *DevicePtr;
+#endif
+
+extern Bool mieqInit(
+#if NeedFunctionPrototypes
+ DevicePtr /*pKbd*/,
+ DevicePtr /*pPtr*/
+#endif
+);
+
+extern void mieqEnqueue(
+#if NeedFunctionPrototypes
+ xEventPtr /*e*/
+#endif
+);
+
+extern void mieqSwitchScreen(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ Bool /*fromDIX*/
+#endif
+);
+
+extern int mieqProcessInputEvents(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+/* miexpose.c */
+
+extern RegionPtr miHandleExposures(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pSrcDrawable*/,
+ DrawablePtr /*pDstDrawable*/,
+ GCPtr /*pGC*/,
+ int /*srcx*/,
+ int /*srcy*/,
+ int /*width*/,
+ int /*height*/,
+ int /*dstx*/,
+ int /*dsty*/,
+ unsigned long /*plane*/
+#endif
+);
+
+extern void miSendGraphicsExpose(
+#if NeedFunctionPrototypes
+ ClientPtr /*client*/,
+ RegionPtr /*pRgn*/,
+ XID /*drawable*/,
+ int /*major*/,
+ int /*minor*/
+#endif
+);
+
+extern void miSendExposures(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ RegionPtr /*pRgn*/,
+ int /*dx*/,
+ int /*dy*/
+#endif
+);
+
+extern void miWindowExposures(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ RegionPtr /*prgn*/,
+ RegionPtr /*other_exposed*/
+#endif
+);
+
+extern void miPaintWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ RegionPtr /*prgn*/,
+ int /*what*/
+#endif
+);
+
+extern void miClearDrawable(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/
+#endif
+);
+
+/* mifillrct.c */
+
+extern void miPolyFillRect(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*nrectFill*/,
+ xRectangle * /*prectInit*/
+#endif
+);
+
+/* miglblt.c */
+
+extern void miPolyGlyphBlt(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+
+extern void miImageGlyphBlt(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*nglyph*/,
+ CharInfoPtr * /*ppci*/,
+ pointer /*pglyphBase*/
+#endif
+);
+
+/* mipoly.c */
+
+extern void miFillPolygon(
+#if NeedFunctionPrototypes
+ DrawablePtr /*dst*/,
+ GCPtr /*pgc*/,
+ int /*shape*/,
+ int /*mode*/,
+ int /*count*/,
+ DDXPointPtr /*pPts*/
+#endif
+);
+
+/* mipolycon.c */
+
+extern Bool miFillConvexPoly(
+#if NeedFunctionPrototypes
+ DrawablePtr /*dst*/,
+ GCPtr /*pgc*/,
+ int /*count*/,
+ DDXPointPtr /*ptsIn*/
+#endif
+);
+
+/* mipolygen.c */
+
+extern Bool miFillGeneralPoly(
+#if NeedFunctionPrototypes
+ DrawablePtr /*dst*/,
+ GCPtr /*pgc*/,
+ int /*count*/,
+ DDXPointPtr /*ptsIn*/
+#endif
+);
+
+/* mipolypnt.c */
+
+extern void miPolyPoint(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ xPoint * /*pptInit*/
+#endif
+);
+
+/* mipolyrect.c */
+
+extern void miPolyRectangle(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*nrects*/,
+ xRectangle * /*pRects*/
+#endif
+);
+
+/* mipolyseg.c */
+
+extern void miPolySegment(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*nseg*/,
+ xSegment * /*pSegs*/
+#endif
+);
+
+/* mipolytext.c */
+
+extern int miPolyText(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/,
+ FontEncoding /*fontEncoding*/
+#endif
+);
+
+extern int miPolyText8(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/
+#endif
+);
+
+extern int miPolyText16(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ unsigned short * /*chars*/
+#endif
+);
+
+extern int miImageText(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/,
+ FontEncoding /*fontEncoding*/
+#endif
+);
+
+extern void miImageText8(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ char * /*chars*/
+#endif
+);
+
+extern void miImageText16(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*x*/,
+ int /*y*/,
+ int /*count*/,
+ unsigned short * /*chars*/
+#endif
+);
+
+/* mipushpxl.c */
+
+extern void miPushPixels(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/,
+ PixmapPtr /*pBitMap*/,
+ DrawablePtr /*pDrawable*/,
+ int /*dx*/,
+ int /*dy*/,
+ int /*xOrg*/,
+ int /*yOrg*/
+#endif
+);
+
+/* miregion.c */
+
+/* see also region.h */
+
+extern Bool miRectAlloc(
+#if NeedFunctionPrototypes
+ RegionPtr /*pRgn*/,
+ int /*n*/
+#endif
+);
+
+extern void miSetExtents(
+#if NeedFunctionPrototypes
+ RegionPtr /*pReg*/
+#endif
+);
+
+extern int miFindMaxBand(
+#if NeedFunctionPrototypes
+ RegionPtr /*prgn*/
+#endif
+);
+
+#ifdef DEBUG
+extern Bool miValidRegion(
+#if NeedFunctionPrototypes
+ RegionPtr /*prgn*/
+#endif
+);
+#endif
+
+/* miscrinit.c */
+
+extern Bool miModifyPixmapHeader(
+#if NeedFunctionPrototypes
+ PixmapPtr /*pPixmap*/,
+ int /*width*/,
+ int /*height*/,
+ int /*depth*/,
+ int /*bitsPerPixel*/,
+ int /*devKind*/,
+ pointer /*pPixData*/
+#endif
+);
+
+extern Bool miCloseScreen(
+#if NeedFunctionPrototypes
+ int /*index*/,
+ ScreenPtr /*pScreen*/
+#endif
+);
+
+extern Bool miCreateScreenResources(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/
+#endif
+);
+
+extern Bool miScreenDevPrivateInit(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ int /*width*/,
+ pointer /*pbits*/
+#endif
+);
+
+extern Bool miScreenInit(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ pointer /*pbits*/,
+ int /*xsize*/,
+ int /*ysize*/,
+ int /*dpix*/,
+ int /*dpiy*/,
+ int /*width*/,
+ int /*rootDepth*/,
+ int /*numDepths*/,
+ DepthPtr /*depths*/,
+ VisualID /*rootVisual*/,
+ int /*numVisuals*/,
+ VisualPtr /*visuals*/
+#endif
+);
+
+extern int miAllocateGCPrivateIndex(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern PixmapPtr miGetScreenPixmap(
+#if NeedFunctionPrototypes
+ ScreenPtr pScreen
+#endif
+);
+
+extern void miSetScreenPixmap(
+#if NeedFunctionPrototypes
+ PixmapPtr pPix
+#endif
+);
+
+/* mivaltree.c */
+
+extern int miShapedWindowIn(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ RegionPtr /*universe*/,
+ RegionPtr /*bounding*/,
+ BoxPtr /*rect*/,
+ int /*x*/,
+ int /*y*/
+#endif
+);
+
+extern int miValidateTree(
+#if NeedFunctionPrototypes
+ WindowPtr /*pParent*/,
+ WindowPtr /*pChild*/,
+ VTKind /*kind*/
+#endif
+);
+
+extern void miWideLine(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pPts*/
+#endif
+);
+
+extern void miWideDash(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ int /*mode*/,
+ int /*npt*/,
+ DDXPointPtr /*pPts*/
+#endif
+);
+
+extern void miMiter(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void miNotMiter(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+/* miwindow.c */
+
+extern void miClearToBackground(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ Bool /*generateExposures*/
+#endif
+);
+
+extern Bool miChangeSaveUnder(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ WindowPtr /*first*/
+#endif
+);
+
+extern void miPostChangeSaveUnder(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ WindowPtr /*pFirst*/
+#endif
+);
+
+extern void miMarkWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern Bool miMarkOverlappedWindows(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ WindowPtr /*pFirst*/,
+ WindowPtr * /*ppLayerWin*/
+#endif
+);
+
+extern void miHandleValidateExposures(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern void miMoveWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ int /*x*/,
+ int /*y*/,
+ WindowPtr /*pNextSib*/,
+ VTKind /*kind*/
+#endif
+);
+
+extern void miSlideAndSizeWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned int /*w*/,
+ unsigned int /*h*/,
+ WindowPtr /*pSib*/
+#endif
+);
+
+extern WindowPtr miGetLayerWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern void miSetShape(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/
+#endif
+);
+
+extern void miChangeBorderWidth(
+#if NeedFunctionPrototypes
+ WindowPtr /*pWin*/,
+ unsigned int /*width*/
+#endif
+);
+
+extern void miMarkUnrealizedWindow(
+#if NeedFunctionPrototypes
+ WindowPtr /*pChild*/,
+ WindowPtr /*pWin*/,
+ Bool /*fromConfigure*/
+#endif
+);
+
+extern void miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth);
+
+/* mizerarc.c */
+
+extern void miZeroPolyArc(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+
+/* mizerline.c */
+
+extern void miZeroLine(
+#if NeedFunctionPrototypes
+ DrawablePtr /*dst*/,
+ GCPtr /*pgc*/,
+ int /*mode*/,
+ int /*nptInit*/,
+ DDXPointRec * /*pptInit*/
+#endif
+);
+
+extern void miZeroDashLine(
+#if NeedFunctionPrototypes
+ DrawablePtr /*dst*/,
+ GCPtr /*pgc*/,
+ int /*mode*/,
+ int /*nptInit*/,
+ DDXPointRec * /*pptInit*/
+#endif
+);
+
+extern void miPolyFillArc(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ int /*narcs*/,
+ xArc * /*parcs*/
+#endif
+);
+
+#endif /* MI_H */
diff --git a/xc/programs/Xserver/mi/miarc.c b/xc/programs/Xserver/mi/miarc.c
new file mode 100644
index 000000000..13e1d9e8b
--- /dev/null
+++ b/xc/programs/Xserver/mi/miarc.c
@@ -0,0 +1,3671 @@
+/* $XFree86: xc/programs/Xserver/mi/miarc.c,v 3.6 1998/10/04 09:39:23 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: miarc.c /main/91 1998/02/09 14:45:57 kaleb $ */
+/* Author: Keith Packard and Bob Scheifler */
+/* Warning: this code is toxic, do not dally very long here. */
+
+#ifdef _XOPEN_SOURCE
+#include <math.h>
+#else
+#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */
+#include <math.h>
+#undef _XOPEN_SOURCE
+#endif
+#include "X.h"
+#include "Xprotostr.h"
+#include "misc.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mifpoly.h"
+#include "mi.h"
+#include "mifillarc.h"
+#include "Xfuncproto.h"
+
+static double miDsin(), miDcos(), miDasin(), miDatan2();
+double cbrt(
+#if NeedFunctionPrototypes
+ double
+#endif
+);
+
+#ifdef ICEILTEMPDECL
+ICEILTEMPDECL
+#endif
+
+/*
+ * some interesting sematic interpretation of the protocol:
+ *
+ * Self intersecting arcs (i.e. those spanning 360 degrees)
+ * never join with other arcs, and are drawn without caps
+ * (unless on/off dashed, in which case each dash segment
+ * is capped, except when the last segment meets the
+ * first segment, when no caps are drawn)
+ *
+ * double dash arcs are drawn in two parts, first the
+ * odd dashes (drawn in background) then the even dashes
+ * (drawn in foreground). This means that overlapping
+ * sections of foreground/background are drawn twice,
+ * first in background then in foreground. The double-draw
+ * occurs even when the function uses the destination values
+ * (e.g. xor mode). This is the same way the wide-line
+ * code works and should be "fixed".
+ *
+ */
+
+#undef max
+#undef min
+
+#if defined (__GNUC__) && defined (__STDC__) && !defined (__STRICT_ANSI__)
+#define USE_INLINE
+#endif
+
+#ifdef USE_INLINE
+inline static const int max (const int x, const int y)
+{
+ return x>y? x:y;
+}
+
+inline static const int min (const int x, const int y)
+{
+ return x<y? x:y;
+}
+
+#else
+
+static int
+max (x, y)
+{
+ return x>y? x:y;
+}
+
+static int
+min (x, y)
+{
+ return x<y? x:y;
+}
+
+#endif
+
+struct bound {
+ double min, max;
+};
+
+struct ibound {
+ int min, max;
+};
+
+#define boundedLe(value, bounds)\
+ ((bounds).min <= (value) && (value) <= (bounds).max)
+
+struct line {
+ double m, b;
+ int valid;
+};
+
+#define intersectLine(y,line) (line.m * (y) + line.b)
+
+/*
+ * these are all y value bounds
+ */
+
+struct arc_bound {
+ struct bound ellipse;
+ struct bound inner;
+ struct bound outer;
+ struct bound right;
+ struct bound left;
+ struct ibound inneri;
+ struct ibound outeri;
+};
+
+struct accelerators {
+ double tail_y;
+ double h2;
+ double w2;
+ double h4;
+ double w4;
+ double h2mw2;
+ double h2l;
+ double w2l;
+ double fromIntX;
+ double fromIntY;
+ struct line left, right;
+ int yorgu;
+ int yorgl;
+ int xorg;
+};
+
+struct arc_def {
+ double w, h, l;
+ double a0, a1;
+};
+
+# define todeg(xAngle) (((double) (xAngle)) / 64.0)
+
+# define RIGHT_END 0
+# define LEFT_END 1
+
+typedef struct _miArcJoin {
+ int arcIndex0, arcIndex1;
+ int phase0, phase1;
+ int end0, end1;
+} miArcJoinRec, *miArcJoinPtr;
+
+typedef struct _miArcCap {
+ int arcIndex;
+ int end;
+} miArcCapRec, *miArcCapPtr;
+
+typedef struct _miArcFace {
+ SppPointRec clock;
+ SppPointRec center;
+ SppPointRec counterClock;
+} miArcFaceRec, *miArcFacePtr;
+
+typedef struct _miArcData {
+ xArc arc;
+ int render; /* non-zero means render after drawing */
+ int join; /* related join */
+ int cap; /* related cap */
+ int selfJoin; /* final dash meets first dash */
+ miArcFaceRec bounds[2];
+ double x0, y0, x1, y1;
+} miArcDataRec, *miArcDataPtr;
+
+/*
+ * This is an entire sequence of arcs, computed and categorized according
+ * to operation. miDashArcs generates either one or two of these.
+ */
+
+typedef struct _miPolyArc {
+ int narcs;
+ miArcDataPtr arcs;
+ int ncaps;
+ miArcCapPtr caps;
+ int njoins;
+ miArcJoinPtr joins;
+} miPolyArcRec, *miPolyArcPtr;
+
+#define GCValsFunction 0
+#define GCValsForeground 1
+#define GCValsBackground 2
+#define GCValsLineWidth 3
+#define GCValsCapStyle 4
+#define GCValsJoinStyle 5
+#define GCValsMask (GCFunction | GCForeground | GCBackground | \
+ GCLineWidth | GCCapStyle | GCJoinStyle)
+static CARD32 gcvals[6];
+
+static void fillSpans(), newFinalSpan();
+static void drawArc(), drawQuadrant(), drawZeroArc();
+static void miArcJoin(), miArcCap(), miRoundCap(), miFreeArcs();
+static int computeAngleFromPath();
+static miPolyArcPtr miComputeArcs ();
+static int miGetArcPts();
+
+# define CUBED_ROOT_2 1.2599210498948732038115849718451499938964
+# define CUBED_ROOT_4 1.5874010519681993173435330390930175781250
+
+/*
+ * draw one segment of the arc using the arc spans generation routines
+ */
+
+static void
+miArcSegment(pDraw, pGC, tarc, right, left)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ xArc tarc;
+ miArcFacePtr right, left;
+{
+ int l = pGC->lineWidth;
+ int a0, a1, startAngle, endAngle;
+ miArcFacePtr temp;
+
+ if (!l)
+ l = 1;
+
+ if (tarc.width == 0 || tarc.height == 0) {
+ drawZeroArc (pDraw, pGC, &tarc, l, left, right);
+ return;
+ }
+
+ if (pGC->miTranslate) {
+ tarc.x += pDraw->x;
+ tarc.y += pDraw->y;
+ }
+
+ a0 = tarc.angle1;
+ a1 = tarc.angle2;
+ if (a1 > FULLCIRCLE)
+ a1 = FULLCIRCLE;
+ else if (a1 < -FULLCIRCLE)
+ a1 = -FULLCIRCLE;
+ if (a1 < 0) {
+ startAngle = a0 + a1;
+ endAngle = a0;
+ temp = right;
+ right = left;
+ left = temp;
+ } else {
+ startAngle = a0;
+ endAngle = a0 + a1;
+ }
+ /*
+ * bounds check the two angles
+ */
+ if (startAngle < 0)
+ startAngle = FULLCIRCLE - (-startAngle) % FULLCIRCLE;
+ if (startAngle >= FULLCIRCLE)
+ startAngle = startAngle % FULLCIRCLE;
+ if (endAngle < 0)
+ endAngle = FULLCIRCLE - (-endAngle) % FULLCIRCLE;
+ if (endAngle > FULLCIRCLE)
+ endAngle = (endAngle-1) % FULLCIRCLE + 1;
+ if ((startAngle == endAngle) && a1) {
+ startAngle = 0;
+ endAngle = FULLCIRCLE;
+ }
+
+ drawArc (&tarc, l, startAngle, endAngle, right, left);
+}
+
+/*
+
+Three equations combine to describe the boundaries of the arc
+
+x^2/w^2 + y^2/h^2 = 1 ellipse itself
+(X-x)^2 + (Y-y)^2 = r^2 circle at (x, y) on the ellipse
+(Y-y) = (X-x)*w^2*y/(h^2*x) normal at (x, y) on the ellipse
+
+These lead to a quartic relating Y and y
+
+y^4 - (2Y)y^3 + (Y^2 + (h^4 - w^2*r^2)/(w^2 - h^2))y^2
+ - (2Y*h^4/(w^2 - h^2))y + (Y^2*h^4)/(w^2 - h^2) = 0
+
+The reducible cubic obtained from this quartic is
+
+z^3 - (3N)z^2 - 2V = 0
+
+where
+
+N = (Y^2 + (h^4 - w^2*r^2/(w^2 - h^2)))/6
+V = w^2*r^2*Y^2*h^4/(4 *(w^2 - h^2)^2)
+
+Let
+
+t = z - N
+p = -N^2
+q = -N^3 - V
+
+Then we get
+
+t^3 + 3pt + 2q = 0
+
+The discriminant of this cubic is
+
+D = q^2 + p^3
+
+When D > 0, a real root is obtained as
+
+z = N + cbrt(-q+sqrt(D)) + cbrt(-q-sqrt(D))
+
+When D < 0, a real root is obtained as
+
+z = N - 2m*cos(acos(-q/m^3)/3)
+
+where
+
+m = sqrt(|p|) * sign(q)
+
+Given a real root Z of the cubic, the roots of the quartic are the roots
+of the two quadratics
+
+y^2 + ((b+A)/2)y + (Z + (bZ - d)/A) = 0
+
+where
+
+A = +/- sqrt(8Z + b^2 - 4c)
+b, c, d are the cubic, quadratic, and linear coefficients of the quartic
+
+Some experimentation is then required to determine which solutions
+correspond to the inner and outer boundaries.
+
+*/
+
+typedef struct {
+ short lx, lw, rx, rw;
+} miArcSpan;
+
+typedef struct {
+ miArcSpan *spans;
+ int count1, count2, k;
+ char top, bot, hole;
+} miArcSpanData;
+
+typedef struct {
+ unsigned long lrustamp;
+ unsigned short lw;
+ unsigned short width, height;
+ miArcSpanData *spdata;
+} arcCacheRec;
+
+#define CACHESIZE 25
+
+static arcCacheRec arcCache[CACHESIZE];
+static unsigned long lrustamp;
+static arcCacheRec *lastCacheHit = &arcCache[0];
+static RESTYPE cacheType;
+
+/*
+ * External so it can be called when low on memory.
+ * Call with a zero ID in that case.
+ */
+/*ARGSUSED*/
+int
+miFreeArcCache (data, id)
+ pointer data;
+ XID id;
+{
+ int k;
+ arcCacheRec *cent;
+
+ if (id)
+ cacheType = 0;
+
+ for (k = CACHESIZE, cent = &arcCache[0]; --k >= 0; cent++)
+ {
+ if (cent->spdata)
+ {
+ cent->lrustamp = 0;
+ cent->lw = 0;
+ xfree(cent->spdata);
+ cent->spdata = NULL;
+ }
+ }
+ lrustamp = 0;
+ return Success;
+}
+
+static void
+miComputeCircleSpans(lw, parc, spdata)
+ int lw;
+ xArc *parc;
+ miArcSpanData *spdata;
+{
+ register miArcSpan *span;
+ int doinner;
+ register int x, y, e;
+ int xk, yk, xm, ym, dx, dy;
+ register int slw, inslw;
+ int inx, iny, ine;
+ int inxk, inyk, inxm, inym;
+
+ doinner = -lw;
+ slw = parc->width - doinner;
+ y = parc->height >> 1;
+ dy = parc->height & 1;
+ dx = 1 - dy;
+ MIWIDEARCSETUP(x, y, dy, slw, e, xk, xm, yk, ym);
+ inslw = parc->width + doinner;
+ if (inslw > 0)
+ {
+ spdata->hole = spdata->top;
+ MIWIDEARCSETUP(inx, iny, dy, inslw, ine, inxk, inxm, inyk, inym);
+ }
+ else
+ {
+ spdata->hole = FALSE;
+ doinner = -y;
+ }
+ spdata->count1 = -doinner - spdata->top;
+ spdata->count2 = y + doinner;
+ span = spdata->spans;
+ while (y)
+ {
+ MIFILLARCSTEP(slw);
+ span->lx = dy - x;
+ if (++doinner <= 0)
+ {
+ span->lw = slw;
+ span->rx = 0;
+ span->rw = span->lx + slw;
+ }
+ else
+ {
+ MIFILLINARCSTEP(inslw);
+ span->lw = x - inx;
+ span->rx = dy - inx + inslw;
+ span->rw = inx - x + slw - inslw;
+ }
+ span++;
+ }
+ if (spdata->bot)
+ {
+ if (spdata->count2)
+ spdata->count2--;
+ else
+ {
+ if (lw > (int)parc->height)
+ span[-1].rx = span[-1].rw = -((lw - (int)parc->height) >> 1);
+ else
+ span[-1].rw = 0;
+ spdata->count1--;
+ }
+ }
+}
+
+static void
+miComputeEllipseSpans(lw, parc, spdata)
+ int lw;
+ xArc *parc;
+ miArcSpanData *spdata;
+{
+ register miArcSpan *span;
+ double w, h, r, xorg;
+ double Hs, Hf, WH, K, Vk, Nk, Fk, Vr, N, Nc, Z, rs;
+ double A, T, b, d, x, y, t, inx, outx, hepp, hepm;
+ int flip, solution;
+
+ w = (double)parc->width / 2.0;
+ h = (double)parc->height / 2.0;
+ r = lw / 2.0;
+ rs = r * r;
+ Hs = h * h;
+ WH = w * w - Hs;
+ Nk = w * r;
+ Vk = (Nk * Hs) / (WH + WH);
+ Hf = Hs * Hs;
+ Nk = (Hf - Nk * Nk) / WH;
+ Fk = Hf / WH;
+ hepp = h + EPSILON;
+ hepm = h - EPSILON;
+ K = h + ((lw - 1) >> 1);
+ span = spdata->spans;
+ if (parc->width & 1)
+ xorg = .5;
+ else
+ xorg = 0.0;
+ if (spdata->top)
+ {
+ span->lx = 0;
+ span->lw = 1;
+ span++;
+ }
+ spdata->count1 = 0;
+ spdata->count2 = 0;
+ spdata->hole = (spdata->top &&
+ (int)parc->height * lw <= (int)(parc->width * parc->width) &&
+ lw < (int)parc->height);
+ for (; K > 0.0; K -= 1.0)
+ {
+ N = (K * K + Nk) / 6.0;
+ Nc = N * N * N;
+ Vr = Vk * K;
+ t = Nc + Vr * Vr;
+ d = Nc + t;
+ if (d < 0.0) {
+ d = Nc;
+ b = N;
+ if ( (b < 0.0) == (t < 0.0) )
+ {
+ b = -b;
+ d = -d;
+ }
+ Z = N - 2.0 * b * cos(acos(-t / d) / 3.0);
+ if ( (Z < 0.0) == (Vr < 0.0) )
+ flip = 2;
+ else
+ flip = 1;
+ }
+ else
+ {
+ d = Vr * sqrt(d);
+ Z = N + cbrt(t + d) + cbrt(t - d);
+ flip = 0;
+ }
+ A = sqrt((Z + Z) - Nk);
+ T = (Fk - Z) * K / A;
+ inx = 0.0;
+ solution = FALSE;
+ b = -A + K;
+ d = b * b - 4 * (Z + T);
+ if (d >= 0)
+ {
+ d = sqrt(d);
+ y = (b + d) / 2;
+ if ((y >= 0.0) && (y < hepp))
+ {
+ solution = TRUE;
+ if (y > hepm)
+ y = h;
+ t = y / h;
+ x = w * sqrt(1 - (t * t));
+ t = K - y;
+ if (rs - (t * t) >= 0)
+ t = sqrt(rs - (t * t));
+ else
+ t = 0;
+ if (flip == 2)
+ inx = x - t;
+ else
+ outx = x + t;
+ }
+ }
+ b = A + K;
+ d = b * b - 4 * (Z - T);
+ /* Because of the large magnitudes involved, we lose enough precision
+ * that sometimes we end up with a negative value near the axis, when
+ * it should be positive. This is a workaround.
+ */
+ if (d < 0 && !solution)
+ d = 0.0;
+ if (d >= 0) {
+ d = sqrt(d);
+ y = (b + d) / 2;
+ if (y < hepp)
+ {
+ if (y > hepm)
+ y = h;
+ t = y / h;
+ x = w * sqrt(1 - (t * t));
+ t = K - y;
+ if (rs - (t * t) >= 0)
+ inx = x - sqrt(rs - (t * t));
+ else
+ inx = x;
+ }
+ y = (b - d) / 2;
+ if (y >= 0.0)
+ {
+ if (y > hepm)
+ y = h;
+ t = y / h;
+ x = w * sqrt(1 - (t * t));
+ t = K - y;
+ if (rs - (t * t) >= 0)
+ t = sqrt(rs - (t * t));
+ else
+ t = 0;
+ if (flip == 1)
+ inx = x - t;
+ else
+ outx = x + t;
+ }
+ }
+ span->lx = ICEIL(xorg - outx);
+ if (inx <= 0.0)
+ {
+ spdata->count1++;
+ span->lw = ICEIL(xorg + outx) - span->lx;
+ span->rx = ICEIL(xorg + inx);
+ span->rw = -ICEIL(xorg - inx);
+ }
+ else
+ {
+ spdata->count2++;
+ span->lw = ICEIL(xorg - inx) - span->lx;
+ span->rx = ICEIL(xorg + inx);
+ span->rw = ICEIL(xorg + outx) - span->rx;
+ }
+ span++;
+ }
+ if (spdata->bot)
+ {
+ outx = w + r;
+ if (r >= h && r <= w)
+ inx = 0.0;
+ else if (Nk < 0.0 && -Nk < Hs)
+ {
+ inx = w * sqrt(1 + Nk / Hs) - sqrt(rs + Nk);
+ if (inx > w - r)
+ inx = w - r;
+ }
+ else
+ inx = w - r;
+ span->lx = ICEIL(xorg - outx);
+ if (inx <= 0.0)
+ {
+ span->lw = ICEIL(xorg + outx) - span->lx;
+ span->rx = ICEIL(xorg + inx);
+ span->rw = -ICEIL(xorg - inx);
+ }
+ else
+ {
+ span->lw = ICEIL(xorg - inx) - span->lx;
+ span->rx = ICEIL(xorg + inx);
+ span->rw = ICEIL(xorg + outx) - span->rx;
+ }
+ }
+ if (spdata->hole)
+ {
+ span = &spdata->spans[spdata->count1];
+ span->lw = -span->lx;
+ span->rx = 1;
+ span->rw = span->lw;
+ spdata->count1--;
+ spdata->count2++;
+ }
+}
+
+static double
+tailX(K, def, bounds, acc)
+ double K;
+ struct arc_def *def;
+ struct arc_bound *bounds;
+ struct accelerators *acc;
+{
+ double w, h, r;
+ double Hs, Hf, WH, Vk, Nk, Fk, Vr, N, Nc, Z, rs;
+ double A, T, b, d, x, y, t, hepp, hepm;
+ int flip, solution;
+ double xs[2];
+ double *xp;
+
+ w = def->w;
+ h = def->h;
+ r = def->l;
+ rs = r * r;
+ Hs = acc->h2;
+ WH = -acc->h2mw2;
+ Nk = def->w * r;
+ Vk = (Nk * Hs) / (WH + WH);
+ Hf = acc->h4;
+ Nk = (Hf - Nk * Nk) / WH;
+ if (K == 0.0) {
+ if (Nk < 0.0 && -Nk < Hs) {
+ xs[0] = w * sqrt(1 + Nk / Hs) - sqrt(rs + Nk);
+ xs[1] = w - r;
+ if (acc->left.valid && boundedLe(K, bounds->left) &&
+ !boundedLe(K, bounds->outer) && xs[0] >= 0.0 && xs[1] >= 0.0)
+ return xs[1];
+ if (acc->right.valid && boundedLe(K, bounds->right) &&
+ !boundedLe(K, bounds->inner) && xs[0] <= 0.0 && xs[1] <= 0.0)
+ return xs[1];
+ return xs[0];
+ }
+ return w - r;
+ }
+ Fk = Hf / WH;
+ hepp = h + EPSILON;
+ hepm = h - EPSILON;
+ N = (K * K + Nk) / 6.0;
+ Nc = N * N * N;
+ Vr = Vk * K;
+ xp = xs;
+ xs[0] = 0.0;
+ t = Nc + Vr * Vr;
+ d = Nc + t;
+ if (d < 0.0) {
+ d = Nc;
+ b = N;
+ if ( (b < 0.0) == (t < 0.0) )
+ {
+ b = -b;
+ d = -d;
+ }
+ Z = N - 2.0 * b * cos(acos(-t / d) / 3.0);
+ if ( (Z < 0.0) == (Vr < 0.0) )
+ flip = 2;
+ else
+ flip = 1;
+ }
+ else
+ {
+ d = Vr * sqrt(d);
+ Z = N + cbrt(t + d) + cbrt(t - d);
+ flip = 0;
+ }
+ A = sqrt((Z + Z) - Nk);
+ T = (Fk - Z) * K / A;
+ solution = FALSE;
+ b = -A + K;
+ d = b * b - 4 * (Z + T);
+ if (d >= 0 && flip == 2)
+ {
+ d = sqrt(d);
+ y = (b + d) / 2;
+ if ((y >= 0.0) && (y < hepp))
+ {
+ solution = TRUE;
+ if (y > hepm)
+ y = h;
+ t = y / h;
+ x = w * sqrt(1 - (t * t));
+ t = K - y;
+ if (rs - (t * t) >= 0)
+ t = sqrt(rs - (t * t));
+ else
+ t = 0;
+ *xp++ = x - t;
+ }
+ }
+ b = A + K;
+ d = b * b - 4 * (Z - T);
+ /* Because of the large magnitudes involved, we lose enough precision
+ * that sometimes we end up with a negative value near the axis, when
+ * it should be positive. This is a workaround.
+ */
+ if (d < 0 && !solution)
+ d = 0.0;
+ if (d >= 0) {
+ d = sqrt(d);
+ y = (b + d) / 2;
+ if (y < hepp)
+ {
+ if (y > hepm)
+ y = h;
+ t = y / h;
+ x = w * sqrt(1 - (t * t));
+ t = K - y;
+ if (rs - (t * t) >= 0)
+ *xp++ = x - sqrt(rs - (t * t));
+ else
+ *xp++ = x;
+ }
+ y = (b - d) / 2;
+ if (y >= 0.0 && flip == 1)
+ {
+ if (y > hepm)
+ y = h;
+ t = y / h;
+ x = w * sqrt(1 - (t * t));
+ t = K - y;
+ if (rs - (t * t) >= 0)
+ t = sqrt(rs - (t * t));
+ else
+ t = 0;
+ *xp++ = x - t;
+ }
+ }
+ if (xp > &xs[1]) {
+ if (acc->left.valid && boundedLe(K, bounds->left) &&
+ !boundedLe(K, bounds->outer) && xs[0] >= 0.0 && xs[1] >= 0.0)
+ return xs[1];
+ if (acc->right.valid && boundedLe(K, bounds->right) &&
+ !boundedLe(K, bounds->inner) && xs[0] <= 0.0 && xs[1] <= 0.0)
+ return xs[1];
+ }
+ return xs[0];
+}
+
+static miArcSpanData *
+miComputeWideEllipse(lw, parc, mustFree)
+ int lw;
+ register xArc *parc;
+ Bool *mustFree;
+{
+ register miArcSpanData *spdata;
+ register arcCacheRec *cent, *lruent;
+ register int k;
+ arcCacheRec fakeent;
+
+ if (!lw)
+ lw = 1;
+ if (parc->height <= 1500)
+ {
+ *mustFree = FALSE;
+ cent = lastCacheHit;
+ if (cent->lw == lw &&
+ cent->width == parc->width && cent->height == parc->height)
+ {
+ cent->lrustamp = ++lrustamp;
+ return cent->spdata;
+ }
+ lruent = &arcCache[0];
+ for (k = CACHESIZE, cent = lruent; --k >= 0; cent++)
+ {
+ if (cent->lw == lw &&
+ cent->width == parc->width && cent->height == parc->height)
+ {
+ cent->lrustamp = ++lrustamp;
+ lastCacheHit = cent;
+ return cent->spdata;
+ }
+ if (cent->lrustamp < lruent->lrustamp)
+ lruent = cent;
+ }
+ if (!cacheType)
+ {
+ cacheType = CreateNewResourceType(miFreeArcCache);
+ (void) AddResource(FakeClientID(0), cacheType, NULL);
+ }
+ } else {
+ lruent = &fakeent;
+ lruent->spdata = NULL;
+ *mustFree = TRUE;
+ }
+ k = (parc->height >> 1) + ((lw - 1) >> 1);
+ spdata = lruent->spdata;
+ if (!spdata || spdata->k != k)
+ {
+ if (spdata)
+ xfree(spdata);
+ spdata = (miArcSpanData *)xalloc(sizeof(miArcSpanData) +
+ sizeof(miArcSpan) * (k + 2));
+ lruent->spdata = spdata;
+ if (!spdata)
+ {
+ lruent->lrustamp = 0;
+ lruent->lw = 0;
+ return spdata;
+ }
+ spdata->spans = (miArcSpan *)(spdata + 1);
+ spdata->k = k;
+ }
+ spdata->top = !(lw & 1) && !(parc->width & 1);
+ spdata->bot = !(parc->height & 1);
+ lruent->lrustamp = ++lrustamp;
+ lruent->lw = lw;
+ lruent->width = parc->width;
+ lruent->height = parc->height;
+ if (lruent != &fakeent)
+ lastCacheHit = lruent;
+ if (parc->width == parc->height)
+ miComputeCircleSpans(lw, parc, spdata);
+ else
+ miComputeEllipseSpans(lw, parc, spdata);
+ return spdata;
+}
+
+static void
+miFillWideEllipse(pDraw, pGC, parc)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ xArc *parc;
+{
+ DDXPointPtr points;
+ register DDXPointPtr pts;
+ int *widths;
+ register int *wids;
+ miArcSpanData *spdata;
+ Bool mustFree;
+ register miArcSpan *span;
+ register int xorg, yorgu, yorgl;
+ register int n;
+
+ yorgu = parc->height + pGC->lineWidth;
+ n = (sizeof(int) * 2) * yorgu;
+ widths = (int *)ALLOCATE_LOCAL(n + (sizeof(DDXPointRec) * 2) * yorgu);
+ if (!widths)
+ return;
+ points = (DDXPointPtr)((char *)widths + n);
+ spdata = miComputeWideEllipse((int)pGC->lineWidth, parc, &mustFree);
+ if (!spdata)
+ {
+ DEALLOCATE_LOCAL(widths);
+ return;
+ }
+ pts = points;
+ wids = widths;
+ span = spdata->spans;
+ xorg = parc->x + (parc->width >> 1);
+ yorgu = parc->y + (parc->height >> 1);
+ yorgl = yorgu + (parc->height & 1);
+ if (pGC->miTranslate)
+ {
+ xorg += pDraw->x;
+ yorgu += pDraw->y;
+ yorgl += pDraw->y;
+ }
+ yorgu -= spdata->k;
+ yorgl += spdata->k;
+ if (spdata->top)
+ {
+ pts->x = xorg;
+ pts->y = yorgu - 1;
+ pts++;
+ *wids++ = 1;
+ span++;
+ }
+ for (n = spdata->count1; --n >= 0; )
+ {
+ pts[0].x = xorg + span->lx;
+ pts[0].y = yorgu;
+ wids[0] = span->lw;
+ pts[1].x = pts[0].x;
+ pts[1].y = yorgl;
+ wids[1] = wids[0];
+ yorgu++;
+ yorgl--;
+ pts += 2;
+ wids += 2;
+ span++;
+ }
+ if (spdata->hole)
+ {
+ pts[0].x = xorg;
+ pts[0].y = yorgl;
+ wids[0] = 1;
+ pts++;
+ wids++;
+ }
+ for (n = spdata->count2; --n >= 0; )
+ {
+ pts[0].x = xorg + span->lx;
+ pts[0].y = yorgu;
+ wids[0] = span->lw;
+ pts[1].x = xorg + span->rx;
+ pts[1].y = pts[0].y;
+ wids[1] = span->rw;
+ pts[2].x = pts[0].x;
+ pts[2].y = yorgl;
+ wids[2] = wids[0];
+ pts[3].x = pts[1].x;
+ pts[3].y = pts[2].y;
+ wids[3] = wids[1];
+ yorgu++;
+ yorgl--;
+ pts += 4;
+ wids += 4;
+ span++;
+ }
+ if (spdata->bot)
+ {
+ if (span->rw <= 0)
+ {
+ pts[0].x = xorg + span->lx;
+ pts[0].y = yorgu;
+ wids[0] = span->lw;
+ pts++;
+ wids++;
+ }
+ else
+ {
+ pts[0].x = xorg + span->lx;
+ pts[0].y = yorgu;
+ wids[0] = span->lw;
+ pts[1].x = xorg + span->rx;
+ pts[1].y = pts[0].y;
+ wids[1] = span->rw;
+ pts += 2;
+ wids += 2;
+ }
+ }
+ if (mustFree)
+ xfree(spdata);
+ (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
+
+ DEALLOCATE_LOCAL(widths);
+}
+
+/*
+ * miPolyArc strategy:
+ *
+ * If arc is zero width and solid, we don't have to worry about the rasterop
+ * or join styles. For wide solid circles, we use a fast integer algorithm.
+ * For wide solid ellipses, we use special case floating point code.
+ * Otherwise, we set up pDrawTo and pGCTo according to the rasterop, then
+ * draw using pGCTo and pDrawTo. If the raster-op was "tricky," that is,
+ * if it involves the destination, then we use PushPixels to move the bits
+ * from the scratch drawable to pDraw. (See the wide line code for a
+ * fuller explanation of this.)
+ */
+
+void
+miPolyArc(pDraw, pGC, narcs, parcs)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ register int i;
+ xArc *parc;
+ int xMin, xMax, yMin, yMax;
+ int pixmapWidth, pixmapHeight;
+ int xOrg, yOrg;
+ int width;
+ Bool fTricky;
+ DrawablePtr pDrawTo;
+ CARD32 fg, bg;
+ GCPtr pGCTo;
+ miPolyArcPtr polyArcs;
+ int cap[2], join[2];
+ int iphase;
+ int halfWidth;
+
+ width = pGC->lineWidth;
+ if(width == 0 && pGC->lineStyle == LineSolid)
+ {
+ for(i = narcs, parc = parcs; --i >= 0; parc++)
+ miArcSegment( pDraw, pGC, *parc,
+ (miArcFacePtr) 0, (miArcFacePtr) 0 );
+ fillSpans (pDraw, pGC);
+ }
+ else
+ {
+ if ((pGC->lineStyle == LineSolid) && narcs)
+ {
+ while (parcs->width && parcs->height &&
+ (parcs->angle2 >= FULLCIRCLE ||
+ parcs->angle2 <= -FULLCIRCLE))
+ {
+ miFillWideEllipse(pDraw, pGC, parcs);
+ if (!--narcs)
+ return;
+ parcs++;
+ }
+ }
+
+ /* Set up pDrawTo and pGCTo based on the rasterop */
+ switch(pGC->alu)
+ {
+ case GXclear: /* 0 */
+ case GXcopy: /* src */
+ case GXcopyInverted: /* NOT src */
+ case GXset: /* 1 */
+ fTricky = FALSE;
+ pDrawTo = pDraw;
+ pGCTo = pGC;
+ break;
+ default:
+ fTricky = TRUE;
+
+ /* find bounding box around arcs */
+ xMin = yMin = MAXSHORT;
+ xMax = yMax = MINSHORT;
+
+ for(i = narcs, parc = parcs; --i >= 0; parc++)
+ {
+ xMin = min (xMin, parc->x);
+ yMin = min (yMin, parc->y);
+ xMax = max (xMax, (parc->x + (int) parc->width));
+ yMax = max (yMax, (parc->y + (int) parc->height));
+ }
+
+ /* expand box to deal with line widths */
+ halfWidth = (width + 1)/2;
+ xMin -= halfWidth;
+ yMin -= halfWidth;
+ xMax += halfWidth;
+ yMax += halfWidth;
+
+ /* compute pixmap size; limit it to size of drawable */
+ xOrg = max(xMin, 0);
+ yOrg = max(yMin, 0);
+ pixmapWidth = min(xMax, pDraw->width) - xOrg;
+ pixmapHeight = min(yMax, pDraw->height) - yOrg;
+
+ /* if nothing left, return */
+ if ( (pixmapWidth <= 0) || (pixmapHeight <= 0) ) return;
+
+ for(i = narcs, parc = parcs; --i >= 0; parc++)
+ {
+ parc->x -= xOrg;
+ parc->y -= yOrg;
+ }
+ if (pGC->miTranslate)
+ {
+ xOrg += pDraw->x;
+ yOrg += pDraw->y;
+ }
+
+ /* set up scratch GC */
+
+ pGCTo = GetScratchGC(1, pDraw->pScreen);
+ if (!pGCTo)
+ return;
+ gcvals[GCValsFunction] = GXcopy;
+ gcvals[GCValsForeground] = 1;
+ gcvals[GCValsBackground] = 0;
+ gcvals[GCValsLineWidth] = pGC->lineWidth;
+ gcvals[GCValsCapStyle] = pGC->capStyle;
+ gcvals[GCValsJoinStyle] = pGC->joinStyle;
+ dixChangeGC(NullClient, pGCTo, GCValsMask, gcvals, NULL);
+
+ /* allocate a 1 bit deep pixmap of the appropriate size, and
+ * validate it */
+ pDrawTo = (DrawablePtr)(*pDraw->pScreen->CreatePixmap)
+ (pDraw->pScreen, pixmapWidth, pixmapHeight, 1);
+ if (!pDrawTo)
+ {
+ FreeScratchGC(pGCTo);
+ return;
+ }
+ ValidateGC(pDrawTo, pGCTo);
+ miClearDrawable(pDrawTo, pGCTo);
+ }
+
+ fg = pGC->fgPixel;
+ bg = pGC->bgPixel;
+ if ((pGC->fillStyle == FillTiled) ||
+ (pGC->fillStyle == FillOpaqueStippled))
+ bg = fg; /* the protocol sez these don't cause color changes */
+
+ polyArcs = miComputeArcs (parcs, narcs, pGC);
+
+ if (!polyArcs)
+ {
+ if (fTricky) {
+ (*pDraw->pScreen->DestroyPixmap) ((PixmapPtr)pDrawTo);
+ FreeScratchGC (pGCTo);
+ }
+ return;
+ }
+
+ cap[0] = cap[1] = 0;
+ join[0] = join[1] = 0;
+ for (iphase = ((pGC->lineStyle == LineDoubleDash) ? 1 : 0);
+ iphase >= 0;
+ iphase--)
+ {
+ if (iphase == 1) {
+ dixChangeGC (NullClient, pGC, GCForeground, &bg, NULL);
+ ValidateGC (pDraw, pGC);
+ } else if (pGC->lineStyle == LineDoubleDash) {
+ dixChangeGC (NullClient, pGC, GCForeground, &fg, NULL);
+ ValidateGC (pDraw, pGC);
+ }
+ for (i = 0; i < polyArcs[iphase].narcs; i++) {
+ miArcDataPtr arcData;
+
+ arcData = &polyArcs[iphase].arcs[i];
+ miArcSegment(pDrawTo, pGCTo, arcData->arc,
+ &arcData->bounds[RIGHT_END],
+ &arcData->bounds[LEFT_END]);
+ if (polyArcs[iphase].arcs[i].render) {
+ fillSpans (pDrawTo, pGCTo);
+ /*
+ * don't cap self-joining arcs
+ */
+ if (polyArcs[iphase].arcs[i].selfJoin &&
+ cap[iphase] < polyArcs[iphase].arcs[i].cap)
+ cap[iphase]++;
+ while (cap[iphase] < polyArcs[iphase].arcs[i].cap) {
+ int arcIndex, end;
+ miArcDataPtr arcData0;
+
+ arcIndex = polyArcs[iphase].caps[cap[iphase]].arcIndex;
+ end = polyArcs[iphase].caps[cap[iphase]].end;
+ arcData0 = &polyArcs[iphase].arcs[arcIndex];
+ miArcCap (pDrawTo, pGCTo,
+ &arcData0->bounds[end], end,
+ arcData0->arc.x, arcData0->arc.y,
+ (double) arcData0->arc.width / 2.0,
+ (double) arcData0->arc.height / 2.0);
+ ++cap[iphase];
+ }
+ while (join[iphase] < polyArcs[iphase].arcs[i].join) {
+ int arcIndex0, arcIndex1, end0, end1;
+ int phase0, phase1;
+ miArcDataPtr arcData0, arcData1;
+ miArcJoinPtr joinp;
+
+ joinp = &polyArcs[iphase].joins[join[iphase]];
+ arcIndex0 = joinp->arcIndex0;
+ end0 = joinp->end0;
+ arcIndex1 = joinp->arcIndex1;
+ end1 = joinp->end1;
+ phase0 = joinp->phase0;
+ phase1 = joinp->phase1;
+ arcData0 = &polyArcs[phase0].arcs[arcIndex0];
+ arcData1 = &polyArcs[phase1].arcs[arcIndex1];
+ miArcJoin (pDrawTo, pGCTo,
+ &arcData0->bounds[end0],
+ &arcData1->bounds[end1],
+ arcData0->arc.x, arcData0->arc.y,
+ (double) arcData0->arc.width / 2.0,
+ (double) arcData0->arc.height / 2.0,
+ arcData1->arc.x, arcData1->arc.y,
+ (double) arcData1->arc.width / 2.0,
+ (double) arcData1->arc.height / 2.0);
+ ++join[iphase];
+ }
+ if (fTricky) {
+ if (pGC->serialNumber != pDraw->serialNumber)
+ ValidateGC (pDraw, pGC);
+ (*pGC->ops->PushPixels) (pGC, (PixmapPtr)pDrawTo,
+ pDraw, pixmapWidth, pixmapHeight, xOrg, yOrg);
+ miClearDrawable ((DrawablePtr) pDrawTo, pGCTo);
+ }
+ }
+ }
+ }
+ miFreeArcs(polyArcs, pGC);
+
+ if(fTricky)
+ {
+ (*pGCTo->pScreen->DestroyPixmap)((PixmapPtr)pDrawTo);
+ FreeScratchGC(pGCTo);
+ }
+ }
+}
+
+static double
+angleBetween (center, point1, point2)
+ SppPointRec center, point1, point2;
+{
+ double a1, a2, a;
+
+ /*
+ * reflect from X coordinates back to ellipse
+ * coordinates -- y increasing upwards
+ */
+ a1 = miDatan2 (- (point1.y - center.y), point1.x - center.x);
+ a2 = miDatan2 (- (point2.y - center.y), point2.x - center.x);
+ a = a2 - a1;
+ if (a <= -180.0)
+ a += 360.0;
+ else if (a > 180.0)
+ a -= 360.0;
+ return a;
+}
+
+static void
+translateBounds (b, x, y, fx, fy)
+miArcFacePtr b;
+int x, y;
+double fx, fy;
+{
+ fx += x;
+ fy += y;
+ b->clock.x -= fx;
+ b->clock.y -= fy;
+ b->center.x -= fx;
+ b->center.y -= fy;
+ b->counterClock.x -= fx;
+ b->counterClock.y -= fy;
+}
+
+static void
+miArcJoin (pDraw, pGC, pLeft, pRight,
+ xOrgLeft, yOrgLeft, xFtransLeft, yFtransLeft,
+ xOrgRight, yOrgRight, xFtransRight, yFtransRight)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ miArcFacePtr pRight, pLeft;
+ int xOrgRight, yOrgRight;
+ double xFtransRight, yFtransRight;
+ int xOrgLeft, yOrgLeft;
+ double xFtransLeft, yFtransLeft;
+{
+ SppPointRec center, corner, otherCorner;
+ SppPointRec poly[5], e;
+ SppPointPtr pArcPts;
+ int cpt;
+ SppArcRec arc;
+ miArcFaceRec Right, Left;
+ int polyLen;
+ int xOrg, yOrg;
+ double xFtrans, yFtrans;
+ double a;
+ double ae, ac2, ec2, bc2, de;
+ double width;
+
+ xOrg = (xOrgRight + xOrgLeft) / 2;
+ yOrg = (yOrgRight + yOrgLeft) / 2;
+ xFtrans = (xFtransLeft + xFtransRight) / 2;
+ yFtrans = (yFtransLeft + yFtransRight) / 2;
+ Right = *pRight;
+ translateBounds (&Right, xOrg - xOrgRight, yOrg - yOrgRight,
+ xFtrans - xFtransRight, yFtrans - yFtransRight);
+ Left = *pLeft;
+ translateBounds (&Left, xOrg - xOrgLeft, yOrg - yOrgLeft,
+ xFtrans - xFtransLeft, yFtrans - yFtransLeft);
+ pRight = &Right;
+ pLeft = &Left;
+
+ if (pRight->clock.x == pLeft->counterClock.x &&
+ pRight->clock.y == pLeft->counterClock.y)
+ return;
+ center = pRight->center;
+ if (0 <= (a = angleBetween (center, pRight->clock, pLeft->counterClock))
+ && a <= 180.0)
+ {
+ corner = pRight->clock;
+ otherCorner = pLeft->counterClock;
+ } else {
+ a = angleBetween (center, pLeft->clock, pRight->counterClock);
+ corner = pLeft->clock;
+ otherCorner = pRight->counterClock;
+ }
+ switch (pGC->joinStyle) {
+ case JoinRound:
+ width = (pGC->lineWidth ? (double)pGC->lineWidth : (double)1);
+
+ arc.x = center.x - width/2;
+ arc.y = center.y - width/2;
+ arc.width = width;
+ arc.height = width;
+ arc.angle1 = -miDatan2 (corner.y - center.y, corner.x - center.x);
+ arc.angle2 = a;
+ pArcPts = (SppPointPtr) xalloc (3 * sizeof (SppPointRec));
+ if (!pArcPts)
+ return;
+ pArcPts[0].x = otherCorner.x;
+ pArcPts[0].y = otherCorner.y;
+ pArcPts[1].x = center.x;
+ pArcPts[1].y = center.y;
+ pArcPts[2].x = corner.x;
+ pArcPts[2].y = corner.y;
+ if( (cpt = miGetArcPts(&arc, 3, &pArcPts)) )
+ {
+ /* by drawing with miFillSppPoly and setting the endpoints of the arc
+ * to be the corners, we assure that the cap will meet up with the
+ * rest of the line */
+ miFillSppPoly(pDraw, pGC, cpt, pArcPts, xOrg, yOrg, xFtrans, yFtrans);
+ }
+ xfree(pArcPts);
+ return;
+ case JoinMiter:
+ /*
+ * don't miter arcs with less than 11 degrees between them
+ */
+ if (a < 169.0) {
+ poly[0] = corner;
+ poly[1] = center;
+ poly[2] = otherCorner;
+ bc2 = (corner.x - otherCorner.x) * (corner.x - otherCorner.x) +
+ (corner.y - otherCorner.y) * (corner.y - otherCorner.y);
+ ec2 = bc2 / 4;
+ ac2 = (corner.x - center.x) * (corner.x - center.x) +
+ (corner.y - center.y) * (corner.y - center.y);
+ ae = sqrt (ac2 - ec2);
+ de = ec2 / ae;
+ e.x = (corner.x + otherCorner.x) / 2;
+ e.y = (corner.y + otherCorner.y) / 2;
+ poly[3].x = e.x + de * (e.x - center.x) / ae;
+ poly[3].y = e.y + de * (e.y - center.y) / ae;
+ poly[4] = corner;
+ polyLen = 5;
+ break;
+ }
+ case JoinBevel:
+ poly[0] = corner;
+ poly[1] = center;
+ poly[2] = otherCorner;
+ poly[3] = corner;
+ polyLen = 4;
+ break;
+ }
+ miFillSppPoly (pDraw, pGC, polyLen, poly, xOrg, yOrg, xFtrans, yFtrans);
+}
+
+/*ARGSUSED*/
+static void
+miArcCap (pDraw, pGC, pFace, end, xOrg, yOrg, xFtrans, yFtrans)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ miArcFacePtr pFace;
+ int end;
+ int xOrg, yOrg;
+ double xFtrans, yFtrans;
+{
+ SppPointRec corner, otherCorner, center, endPoint, poly[5];
+
+ corner = pFace->clock;
+ otherCorner = pFace->counterClock;
+ center = pFace->center;
+ switch (pGC->capStyle) {
+ case CapProjecting:
+ poly[0].x = otherCorner.x;
+ poly[0].y = otherCorner.y;
+ poly[1].x = corner.x;
+ poly[1].y = corner.y;
+ poly[2].x = corner.x -
+ (center.y - corner.y);
+ poly[2].y = corner.y +
+ (center.x - corner.x);
+ poly[3].x = otherCorner.x -
+ (otherCorner.y - center.y);
+ poly[3].y = otherCorner.y +
+ (otherCorner.x - center.x);
+ poly[4].x = otherCorner.x;
+ poly[4].y = otherCorner.y;
+ miFillSppPoly (pDraw, pGC, 5, poly, xOrg, yOrg, xFtrans, yFtrans);
+ break;
+ case CapRound:
+ /*
+ * miRoundCap just needs these to be unequal.
+ */
+ endPoint = center;
+ endPoint.x = endPoint.x + 100;
+ miRoundCap (pDraw, pGC, center, endPoint, corner, otherCorner, 0,
+ -xOrg, -yOrg, xFtrans, yFtrans);
+ break;
+ }
+}
+
+/* MIROUNDCAP -- a private helper function
+ * Put Rounded cap on end. pCenter is the center of this end of the line
+ * pEnd is the center of the other end of the line. pCorner is one of the
+ * two corners at this end of the line.
+ * NOTE: pOtherCorner must be counter-clockwise from pCorner.
+ */
+/*ARGSUSED*/
+static void
+miRoundCap(pDraw, pGC, pCenter, pEnd, pCorner, pOtherCorner, fLineEnd,
+ xOrg, yOrg, xFtrans, yFtrans)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ SppPointRec pCenter, pEnd;
+ SppPointRec pCorner, pOtherCorner;
+ int fLineEnd, xOrg, yOrg;
+ double xFtrans, yFtrans;
+{
+ int cpt;
+ double width;
+ double miDatan2 ();
+ SppArcRec arc;
+ SppPointPtr pArcPts;
+
+ width = (pGC->lineWidth ? (double)pGC->lineWidth : (double)1);
+
+ arc.x = pCenter.x - width/2;
+ arc.y = pCenter.y - width/2;
+ arc.width = width;
+ arc.height = width;
+ arc.angle1 = -miDatan2 (pCorner.y - pCenter.y, pCorner.x - pCenter.x);
+ if(PTISEQUAL(pCenter, pEnd))
+ arc.angle2 = - 180.0;
+ else {
+ arc.angle2 = -miDatan2 (pOtherCorner.y - pCenter.y, pOtherCorner.x - pCenter.x) - arc.angle1;
+ if (arc.angle2 < 0)
+ arc.angle2 += 360.0;
+ }
+ pArcPts = (SppPointPtr) NULL;
+ if( (cpt = miGetArcPts(&arc, 0, &pArcPts)) )
+ {
+ /* by drawing with miFillSppPoly and setting the endpoints of the arc
+ * to be the corners, we assure that the cap will meet up with the
+ * rest of the line */
+ miFillSppPoly(pDraw, pGC, cpt, pArcPts, -xOrg, -yOrg, xFtrans, yFtrans);
+ }
+ xfree(pArcPts);
+}
+
+/*
+ * To avoid inaccuracy at the cardinal points, use trig functions
+ * which are exact for those angles
+ */
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+#ifndef M_PI_2
+#define M_PI_2 1.57079632679489661923
+#endif
+
+# define Dsin(d) ((d) == 0.0 ? 0.0 : ((d) == 90.0 ? 1.0 : sin(d*M_PI/180.0)))
+# define Dcos(d) ((d) == 0.0 ? 1.0 : ((d) == 90.0 ? 0.0 : cos(d*M_PI/180.0)))
+# define mod(a,b) ((a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
+
+static double
+miDcos (a)
+double a;
+{
+ int i;
+
+ if (floor (a/90) == a/90) {
+ i = (int) (a/90.0);
+ switch (mod (i, 4)) {
+ case 0: return 1;
+ case 1: return 0;
+ case 2: return -1;
+ case 3: return 0;
+ }
+ }
+ return cos (a * M_PI / 180.0);
+}
+
+static double
+miDsin (a)
+double a;
+{
+ int i;
+
+ if (floor (a/90) == a/90) {
+ i = (int) (a/90.0);
+ switch (mod (i, 4)) {
+ case 0: return 0;
+ case 1: return 1;
+ case 2: return 0;
+ case 3: return -1;
+ }
+ }
+ return sin (a * M_PI / 180.0);
+}
+
+static double
+miDasin (v)
+double v;
+{
+ if (v == 0)
+ return 0.0;
+ if (v == 1.0)
+ return 90.0;
+ if (v == -1.0)
+ return -90.0;
+ return asin(v) * (180.0 / M_PI);
+}
+
+static double
+miDatan2 (dy, dx)
+double dy, dx;
+{
+ if (dy == 0) {
+ if (dx >= 0)
+ return 0.0;
+ return 180.0;
+ } else if (dx == 0) {
+ if (dy > 0)
+ return 90.0;
+ return -90.0;
+ } else if (Fabs (dy) == Fabs (dx)) {
+ if (dy > 0) {
+ if (dx > 0)
+ return 45.0;
+ return 135.0;
+ } else {
+ if (dx > 0)
+ return 315.0;
+ return 225.0;
+ }
+ } else {
+ return atan2 (dy, dx) * (180.0 / M_PI);
+ }
+}
+
+/* MIGETARCPTS -- Converts an arc into a set of line segments -- a helper
+ * routine for filled arc and line (round cap) code.
+ * Returns the number of points in the arc. Note that it takes a pointer
+ * to a pointer to where it should put the points and an index (cpt).
+ * This procedure allocates the space necessary to fit the arc points.
+ * Sometimes it's convenient for those points to be at the end of an existing
+ * array. (For example, if we want to leave a spare point to make sectors
+ * instead of segments.) So we pass in the xalloc()ed chunk that contains the
+ * array and an index saying where we should start stashing the points.
+ * If there isn't an array already, we just pass in a null pointer and
+ * count on xrealloc() to handle the null pointer correctly.
+ */
+static int
+miGetArcPts(parc, cpt, ppPts)
+ SppArcPtr parc; /* points to an arc */
+ int cpt; /* number of points already in arc list */
+ SppPointPtr *ppPts; /* pointer to pointer to arc-list -- modified */
+{
+ double st, /* Start Theta, start angle */
+ et, /* End Theta, offset from start theta */
+ dt, /* Delta Theta, angle to sweep ellipse */
+ cdt, /* Cos Delta Theta, actually 2 cos(dt) */
+ x0, y0, /* the recurrence formula needs two points to start */
+ x1, y1,
+ x2, y2, /* this will be the new point generated */
+ xc, yc; /* the center point */
+ int count, i;
+ SppPointPtr poly;
+ DDXPointRec last; /* last point on integer boundaries */
+
+ /* The spec says that positive angles indicate counterclockwise motion.
+ * Given our coordinate system (with 0,0 in the upper left corner),
+ * the screen appears flipped in Y. The easiest fix is to negate the
+ * angles given */
+
+ st = - parc->angle1;
+
+ et = - parc->angle2;
+
+ /* Try to get a delta theta that is within 1/2 pixel. Then adjust it
+ * so that it divides evenly into the total.
+ * I'm just using cdt 'cause I'm lazy.
+ */
+ cdt = parc->width;
+ if (parc->height > cdt)
+ cdt = parc->height;
+ cdt /= 2.0;
+ if(cdt <= 0)
+ return 0;
+ if (cdt < 1.0)
+ cdt = 1.0;
+ dt = miDasin ( 1.0 / cdt ); /* minimum step necessary */
+ count = et/dt;
+ count = abs(count) + 1;
+ dt = et/count;
+ count++;
+
+ cdt = 2 * miDcos(dt);
+ if (!(poly = (SppPointPtr) xrealloc((pointer)*ppPts,
+ (cpt + count) * sizeof(SppPointRec))))
+ return(0);
+ *ppPts = poly;
+
+ xc = parc->width/2.0; /* store half width and half height */
+ yc = parc->height/2.0;
+
+ x0 = xc * miDcos(st);
+ y0 = yc * miDsin(st);
+ x1 = xc * miDcos(st + dt);
+ y1 = yc * miDsin(st + dt);
+ xc += parc->x; /* by adding initial point, these become */
+ yc += parc->y; /* the center point */
+
+ poly[cpt].x = (xc + x0);
+ poly[cpt].y = (yc + y0);
+ last.x = ROUNDTOINT( poly[cpt + 1].x = (xc + x1) );
+ last.y = ROUNDTOINT( poly[cpt + 1].y = (yc + y1) );
+
+ for(i = 2; i < count; i++)
+ {
+ x2 = cdt * x1 - x0;
+ y2 = cdt * y1 - y0;
+
+ poly[cpt + i].x = (xc + x2);
+ poly[cpt + i].y = (yc + y2);
+
+ x0 = x1; y0 = y1;
+ x1 = x2; y1 = y2;
+ }
+ /* adjust the last point */
+ if (abs(parc->angle2) >= 360.0)
+ poly[cpt +i -1] = poly[0];
+ else {
+ poly[cpt +i -1].x = (miDcos(st + et) * parc->width/2.0 + xc);
+ poly[cpt +i -1].y = (miDsin(st + et) * parc->height/2.0 + yc);
+ }
+
+ return(count);
+}
+
+struct arcData {
+ double x0, y0, x1, y1;
+ int selfJoin;
+};
+
+# define ADD_REALLOC_STEP 20
+
+static void
+addCap (capsp, ncapsp, sizep, end, arcIndex)
+ miArcCapPtr *capsp;
+ int *ncapsp, *sizep;
+ int end, arcIndex;
+{
+ int newsize;
+ miArcCapPtr cap;
+
+ if (*ncapsp == *sizep)
+ {
+ newsize = *sizep + ADD_REALLOC_STEP;
+ cap = (miArcCapPtr) xrealloc (*capsp,
+ newsize * sizeof (**capsp));
+ if (!cap)
+ return;
+ *sizep = newsize;
+ *capsp = cap;
+ }
+ cap = &(*capsp)[*ncapsp];
+ cap->end = end;
+ cap->arcIndex = arcIndex;
+ ++*ncapsp;
+}
+
+static void
+addJoin (joinsp, njoinsp, sizep, end0, index0, phase0, end1, index1, phase1)
+ miArcJoinPtr *joinsp;
+ int *njoinsp, *sizep;
+ int end0, index0, phase0, end1, index1, phase1;
+{
+ int newsize;
+ miArcJoinPtr join;
+
+ if (*njoinsp == *sizep)
+ {
+ newsize = *sizep + ADD_REALLOC_STEP;
+ join = (miArcJoinPtr) xrealloc (*joinsp,
+ newsize * sizeof (**joinsp));
+ if (!join)
+ return;
+ *sizep = newsize;
+ *joinsp = join;
+ }
+ join = &(*joinsp)[*njoinsp];
+ join->end0 = end0;
+ join->arcIndex0 = index0;
+ join->phase0 = phase0;
+ join->end1 = end1;
+ join->arcIndex1 = index1;
+ join->phase1 = phase1;
+ ++*njoinsp;
+}
+
+static miArcDataPtr
+addArc (arcsp, narcsp, sizep, xarc)
+ miArcDataPtr *arcsp;
+ int *narcsp, *sizep;
+ xArc *xarc;
+{
+ int newsize;
+ miArcDataPtr arc;
+
+ if (*narcsp == *sizep)
+ {
+ newsize = *sizep + ADD_REALLOC_STEP;
+ arc = (miArcDataPtr) xrealloc (*arcsp,
+ newsize * sizeof (**arcsp));
+ if (!arc)
+ return (miArcDataPtr)NULL;
+ *sizep = newsize;
+ *arcsp = arc;
+ }
+ arc = &(*arcsp)[*narcsp];
+ arc->arc = *xarc;
+ ++*narcsp;
+ return arc;
+}
+
+static void
+miFreeArcs(arcs, pGC)
+ miPolyArcPtr arcs;
+ GCPtr pGC;
+{
+ int iphase;
+
+ for (iphase = ((pGC->lineStyle == LineDoubleDash) ? 1 : 0);
+ iphase >= 0;
+ iphase--)
+ {
+ if (arcs[iphase].narcs > 0)
+ xfree(arcs[iphase].arcs);
+ if (arcs[iphase].njoins > 0)
+ xfree(arcs[iphase].joins);
+ if (arcs[iphase].ncaps > 0)
+ xfree(arcs[iphase].caps);
+ }
+ xfree(arcs);
+}
+
+/*
+ * map angles to radial distance. This only deals with the first quadrant
+ */
+
+/*
+ * a polygonal approximation to the arc for computing arc lengths
+ */
+
+# define DASH_MAP_SIZE 91
+
+# define dashIndexToAngle(di) ((((double) (di)) * 90.0) / ((double) DASH_MAP_SIZE - 1))
+# define xAngleToDashIndex(xa) ((((long) (xa)) * (DASH_MAP_SIZE - 1)) / (90 * 64))
+# define dashIndexToXAngle(di) ((((long) (di)) * (90 * 64)) / (DASH_MAP_SIZE - 1))
+# define dashXAngleStep (((double) (90 * 64)) / ((double) (DASH_MAP_SIZE - 1)))
+
+typedef struct {
+ double map[DASH_MAP_SIZE];
+} dashMap;
+
+static void
+computeDashMap (arcp, map)
+ xArc *arcp;
+ dashMap *map;
+{
+ int di;
+ double a, x, y, prevx, prevy, dist;
+
+ for (di = 0; di < DASH_MAP_SIZE; di++) {
+ a = dashIndexToAngle (di);
+ x = ((double) arcp->width / 2.0) * miDcos (a);
+ y = ((double) arcp->height / 2.0) * miDsin (a);
+ if (di == 0) {
+ map->map[di] = 0.0;
+ } else {
+ dist = hypot (x - prevx, y - prevy);
+ map->map[di] = map->map[di - 1] + dist;
+ }
+ prevx = x;
+ prevy = y;
+ }
+}
+
+typedef enum {HORIZONTAL, VERTICAL, OTHER} arcTypes;
+
+/* this routine is a bit gory */
+
+static miPolyArcPtr
+miComputeArcs (parcs, narcs, pGC)
+ xArc *parcs;
+ int narcs;
+ GCPtr pGC;
+{
+ int isDashed, isDoubleDash;
+ int dashOffset;
+ miPolyArcPtr arcs;
+ int start, i, j, k, nexti, nextk;
+ int joinSize[2];
+ int capSize[2];
+ int arcSize[2];
+ int angle2;
+ double a0, a1;
+ struct arcData *data;
+ miArcDataPtr arc;
+ xArc xarc;
+ int iphase, prevphase, joinphase;
+ int arcsJoin;
+ int selfJoin;
+
+ int iDash, dashRemaining;
+ int iDashStart, dashRemainingStart, iphaseStart;
+ int startAngle, spanAngle, endAngle, backwards;
+ int prevDashAngle, dashAngle;
+ dashMap map;
+
+ isDashed = !(pGC->lineStyle == LineSolid);
+ isDoubleDash = (pGC->lineStyle == LineDoubleDash);
+ dashOffset = pGC->dashOffset;
+
+ data = (struct arcData *) ALLOCATE_LOCAL (narcs * sizeof (struct arcData));
+ if (!data)
+ return (miPolyArcPtr)NULL;
+ arcs = (miPolyArcPtr) xalloc (sizeof (*arcs) * (isDoubleDash ? 2 : 1));
+ if (!arcs)
+ {
+ DEALLOCATE_LOCAL(data);
+ return (miPolyArcPtr)NULL;
+ }
+ for (i = 0; i < narcs; i++) {
+ a0 = todeg (parcs[i].angle1);
+ angle2 = parcs[i].angle2;
+ if (angle2 > FULLCIRCLE)
+ angle2 = FULLCIRCLE;
+ else if (angle2 < -FULLCIRCLE)
+ angle2 = -FULLCIRCLE;
+ data[i].selfJoin = angle2 == FULLCIRCLE || angle2 == -FULLCIRCLE;
+ a1 = todeg (parcs[i].angle1 + angle2);
+ data[i].x0 = parcs[i].x + (double) parcs[i].width / 2 * (1 + miDcos (a0));
+ data[i].y0 = parcs[i].y + (double) parcs[i].height / 2 * (1 - miDsin (a0));
+ data[i].x1 = parcs[i].x + (double) parcs[i].width / 2 * (1 + miDcos (a1));
+ data[i].y1 = parcs[i].y + (double) parcs[i].height / 2 * (1 - miDsin (a1));
+ }
+
+ for (iphase = 0; iphase < (isDoubleDash ? 2 : 1); iphase++) {
+ arcs[iphase].njoins = 0;
+ arcs[iphase].joins = 0;
+ joinSize[iphase] = 0;
+
+ arcs[iphase].ncaps = 0;
+ arcs[iphase].caps = 0;
+ capSize[iphase] = 0;
+
+ arcs[iphase].narcs = 0;
+ arcs[iphase].arcs = 0;
+ arcSize[iphase] = 0;
+ }
+
+ iphase = 0;
+ if (isDashed) {
+ iDash = 0;
+ dashRemaining = pGC->dash[0];
+ while (dashOffset > 0) {
+ if (dashOffset >= dashRemaining) {
+ dashOffset -= dashRemaining;
+ iphase = iphase ? 0 : 1;
+ iDash++;
+ if (iDash == pGC->numInDashList)
+ iDash = 0;
+ dashRemaining = pGC->dash[iDash];
+ } else {
+ dashRemaining -= dashOffset;
+ dashOffset = 0;
+ }
+ }
+ iDashStart = iDash;
+ dashRemainingStart = dashRemaining;
+ }
+ iphaseStart = iphase;
+
+ for (i = narcs - 1; i >= 0; i--) {
+ j = i + 1;
+ if (j == narcs)
+ j = 0;
+ if (data[i].selfJoin || i == j ||
+ (UNEQUAL (data[i].x1, data[j].x0) ||
+ UNEQUAL (data[i].y1, data[j].y0)))
+ {
+ if (iphase == 0 || isDoubleDash)
+ addCap (&arcs[iphase].caps, &arcs[iphase].ncaps,
+ &capSize[iphase], RIGHT_END, 0);
+ break;
+ }
+ }
+ start = i + 1;
+ if (start == narcs)
+ start = 0;
+ i = start;
+ for (;;) {
+ j = i + 1;
+ if (j == narcs)
+ j = 0;
+ nexti = i+1;
+ if (nexti == narcs)
+ nexti = 0;
+ if (isDashed) {
+ /*
+ ** deal with dashed arcs. Use special rules for certain 0 area arcs.
+ ** Presumably, the other 0 area arcs still aren't done right.
+ */
+ arcTypes arcType = OTHER;
+ CARD16 thisLength;
+
+ if (parcs[i].height == 0
+ && (parcs[i].angle1 % FULLCIRCLE) == 0x2d00
+ && parcs[i].angle2 == 0x2d00)
+ arcType = HORIZONTAL;
+ else if (parcs[i].width == 0
+ && (parcs[i].angle1 % FULLCIRCLE) == 0x1680
+ && parcs[i].angle2 == 0x2d00)
+ arcType = VERTICAL;
+ if (arcType == OTHER) {
+ /*
+ * precompute an approximation map
+ */
+ computeDashMap (&parcs[i], &map);
+ /*
+ * compute each individual dash segment using the path
+ * length function
+ */
+ startAngle = parcs[i].angle1;
+ spanAngle = parcs[i].angle2;
+ if (spanAngle > FULLCIRCLE)
+ spanAngle = FULLCIRCLE;
+ else if (spanAngle < -FULLCIRCLE)
+ spanAngle = -FULLCIRCLE;
+ if (startAngle < 0)
+ startAngle = FULLCIRCLE - (-startAngle) % FULLCIRCLE;
+ if (startAngle >= FULLCIRCLE)
+ startAngle = startAngle % FULLCIRCLE;
+ endAngle = startAngle + spanAngle;
+ backwards = spanAngle < 0;
+ } else {
+ xarc = parcs[i];
+ if (arcType == VERTICAL) {
+ xarc.angle1 = 0x1680;
+ startAngle = parcs[i].y;
+ endAngle = startAngle + parcs[i].height;
+ } else {
+ xarc.angle1 = 0x2d00;
+ startAngle = parcs[i].x;
+ endAngle = startAngle + parcs[i].width;
+ }
+ }
+ dashAngle = startAngle;
+ selfJoin = data[i].selfJoin &&
+ (iphase == 0 || isDoubleDash);
+ /*
+ * add dashed arcs to each bucket
+ */
+ arc = 0;
+ while (dashAngle != endAngle) {
+ prevDashAngle = dashAngle;
+ if (arcType == OTHER) {
+ dashAngle = computeAngleFromPath (prevDashAngle, endAngle,
+ &map, &dashRemaining, backwards);
+ /* avoid troubles with huge arcs and small dashes */
+ if (dashAngle == prevDashAngle) {
+ if (backwards)
+ dashAngle--;
+ else
+ dashAngle++;
+ }
+ } else {
+ thisLength = (dashAngle + dashRemaining <= endAngle) ?
+ dashRemaining : endAngle - dashAngle;
+ if (arcType == VERTICAL) {
+ xarc.y = dashAngle;
+ xarc.height = thisLength;
+ } else {
+ xarc.x = dashAngle;
+ xarc.width = thisLength;
+ }
+ dashAngle += thisLength;
+ dashRemaining -= thisLength;
+ }
+ if (iphase == 0 || isDoubleDash) {
+ if (arcType == OTHER) {
+ xarc = parcs[i];
+ spanAngle = prevDashAngle;
+ if (spanAngle < 0)
+ spanAngle = FULLCIRCLE - (-spanAngle) % FULLCIRCLE;
+ if (spanAngle >= FULLCIRCLE)
+ spanAngle = spanAngle % FULLCIRCLE;
+ xarc.angle1 = spanAngle;
+ spanAngle = dashAngle - prevDashAngle;
+ if (backwards) {
+ if (dashAngle > prevDashAngle)
+ spanAngle = - FULLCIRCLE + spanAngle;
+ } else {
+ if (dashAngle < prevDashAngle)
+ spanAngle = FULLCIRCLE + spanAngle;
+ }
+ if (spanAngle > FULLCIRCLE)
+ spanAngle = FULLCIRCLE;
+ if (spanAngle < -FULLCIRCLE)
+ spanAngle = -FULLCIRCLE;
+ xarc.angle2 = spanAngle;
+ }
+ arc = addArc (&arcs[iphase].arcs, &arcs[iphase].narcs,
+ &arcSize[iphase], &xarc);
+ if (!arc)
+ goto arcfail;
+ /*
+ * cap each end of an on/off dash
+ */
+ if (!isDoubleDash) {
+ if (prevDashAngle != startAngle) {
+ addCap (&arcs[iphase].caps,
+ &arcs[iphase].ncaps,
+ &capSize[iphase], RIGHT_END,
+ arc - arcs[iphase].arcs);
+
+ }
+ if (dashAngle != endAngle) {
+ addCap (&arcs[iphase].caps,
+ &arcs[iphase].ncaps,
+ &capSize[iphase], LEFT_END,
+ arc - arcs[iphase].arcs);
+ }
+ }
+ arc->cap = arcs[iphase].ncaps;
+ arc->join = arcs[iphase].njoins;
+ arc->render = 0;
+ arc->selfJoin = 0;
+ if (dashAngle == endAngle)
+ arc->selfJoin = selfJoin;
+ }
+ prevphase = iphase;
+ if (dashRemaining <= 0) {
+ ++iDash;
+ if (iDash == pGC->numInDashList)
+ iDash = 0;
+ iphase = iphase ? 0:1;
+ dashRemaining = pGC->dash[iDash];
+ }
+ }
+ /*
+ * make sure a place exists for the position data when
+ * drawing a zero-length arc
+ */
+ if (startAngle == endAngle) {
+ prevphase = iphase;
+ if (!isDoubleDash && iphase == 1)
+ prevphase = 0;
+ arc = addArc (&arcs[prevphase].arcs, &arcs[prevphase].narcs,
+ &arcSize[prevphase], &parcs[i]);
+ if (!arc)
+ goto arcfail;
+ arc->join = arcs[prevphase].njoins;
+ arc->cap = arcs[prevphase].ncaps;
+ arc->selfJoin = data[i].selfJoin;
+ }
+ } else {
+ arc = addArc (&arcs[iphase].arcs, &arcs[iphase].narcs,
+ &arcSize[iphase], &parcs[i]);
+ if (!arc)
+ goto arcfail;
+ arc->join = arcs[iphase].njoins;
+ arc->cap = arcs[iphase].ncaps;
+ arc->selfJoin = data[i].selfJoin;
+ prevphase = iphase;
+ }
+ if (prevphase == 0 || isDoubleDash)
+ k = arcs[prevphase].narcs - 1;
+ if (iphase == 0 || isDoubleDash)
+ nextk = arcs[iphase].narcs;
+ if (nexti == start) {
+ nextk = 0;
+ if (isDashed) {
+ iDash = iDashStart;
+ iphase = iphaseStart;
+ dashRemaining = dashRemainingStart;
+ }
+ }
+ arcsJoin = narcs > 1 && i != j &&
+ ISEQUAL (data[i].x1, data[j].x0) &&
+ ISEQUAL (data[i].y1, data[j].y0) &&
+ !data[i].selfJoin && !data[j].selfJoin;
+ if (arc)
+ {
+ if (arcsJoin)
+ arc->render = 0;
+ else
+ arc->render = 1;
+ }
+ if (arcsJoin &&
+ (prevphase == 0 || isDoubleDash) &&
+ (iphase == 0 || isDoubleDash))
+ {
+ joinphase = iphase;
+ if (isDoubleDash) {
+ if (nexti == start)
+ joinphase = iphaseStart;
+ /*
+ * if the join is right at the dash,
+ * draw the join in foreground
+ * This is because the foreground
+ * arcs are computed second, the results
+ * of which are needed to draw the join
+ */
+ if (joinphase != prevphase)
+ joinphase = 0;
+ }
+ if (joinphase == 0 || isDoubleDash) {
+ addJoin (&arcs[joinphase].joins,
+ &arcs[joinphase].njoins,
+ &joinSize[joinphase],
+ LEFT_END, k, prevphase,
+ RIGHT_END, nextk, iphase);
+ arc->join = arcs[prevphase].njoins;
+ }
+ } else {
+ /*
+ * cap the left end of this arc
+ * unless it joins itself
+ */
+ if ((prevphase == 0 || isDoubleDash) &&
+ !arc->selfJoin)
+ {
+ addCap (&arcs[prevphase].caps, &arcs[prevphase].ncaps,
+ &capSize[prevphase], LEFT_END, k);
+ arc->cap = arcs[prevphase].ncaps;
+ }
+ if (isDashed && !arcsJoin) {
+ iDash = iDashStart;
+ iphase = iphaseStart;
+ dashRemaining = dashRemainingStart;
+ }
+ nextk = arcs[iphase].narcs;
+ if (nexti == start) {
+ nextk = 0;
+ iDash = iDashStart;
+ iphase = iphaseStart;
+ dashRemaining = dashRemainingStart;
+ }
+ /*
+ * cap the right end of the next arc. If the
+ * next arc is actually the first arc, only
+ * cap it if it joins with this arc. This
+ * case will occur when the final dash segment
+ * of an on/off dash is off. Of course, this
+ * cap will be drawn at a strange time, but that
+ * hardly matters...
+ */
+ if ((iphase == 0 || isDoubleDash) &&
+ (nexti != start || (arcsJoin && isDashed)))
+ addCap (&arcs[iphase].caps, &arcs[iphase].ncaps,
+ &capSize[iphase], RIGHT_END, nextk);
+ }
+ i = nexti;
+ if (i == start)
+ break;
+ }
+ /*
+ * make sure the last section is rendered
+ */
+ for (iphase = 0; iphase < (isDoubleDash ? 2 : 1); iphase++)
+ if (arcs[iphase].narcs > 0) {
+ arcs[iphase].arcs[arcs[iphase].narcs-1].render = 1;
+ arcs[iphase].arcs[arcs[iphase].narcs-1].join =
+ arcs[iphase].njoins;
+ arcs[iphase].arcs[arcs[iphase].narcs-1].cap =
+ arcs[iphase].ncaps;
+ }
+ DEALLOCATE_LOCAL(data);
+ return arcs;
+arcfail:
+ miFreeArcs(arcs, pGC);
+ DEALLOCATE_LOCAL(data);
+ return (miPolyArcPtr)NULL;
+}
+
+static double
+angleToLength (angle, map)
+ int angle;
+ dashMap *map;
+{
+ double len, excesslen, sidelen = map->map[DASH_MAP_SIZE - 1], totallen;
+ int di;
+ int excess;
+ Bool oddSide = FALSE;
+
+ totallen = 0;
+ if (angle >= 0) {
+ while (angle >= 90 * 64) {
+ angle -= 90 * 64;
+ totallen += sidelen;
+ oddSide = !oddSide;
+ }
+ } else {
+ while (angle < 0) {
+ angle += 90 * 64;
+ totallen -= sidelen;
+ oddSide = !oddSide;
+ }
+ }
+ if (oddSide)
+ angle = 90 * 64 - angle;
+
+ di = xAngleToDashIndex (angle);
+ excess = angle - dashIndexToXAngle (di);
+
+ len = map->map[di];
+ /*
+ * linearly interpolate between this point and the next
+ */
+ if (excess > 0) {
+ excesslen = (map->map[di + 1] - map->map[di]) *
+ ((double) excess) / dashXAngleStep;
+ len += excesslen;
+ }
+ if (oddSide)
+ totallen += (sidelen - len);
+ else
+ totallen += len;
+ return totallen;
+}
+
+/*
+ * len is along the arc, but may be more than one rotation
+ */
+
+static int
+lengthToAngle (len, map)
+ double len;
+ dashMap *map;
+{
+ double sidelen = map->map[DASH_MAP_SIZE - 1];
+ int angle, angleexcess;
+ Bool oddSide = FALSE;
+ int a0, a1, a;
+
+ angle = 0;
+ /*
+ * step around the ellipse, subtracting sidelens and
+ * adding 90 degrees. oddSide will tell if the
+ * map should be interpolated in reverse
+ */
+ if (len >= 0) {
+ if (sidelen == 0)
+ return 2 * FULLCIRCLE; /* infinity */
+ while (len >= sidelen) {
+ angle += 90 * 64;
+ len -= sidelen;
+ oddSide = !oddSide;
+ }
+ } else {
+ if (sidelen == 0)
+ return -2 * FULLCIRCLE; /* infinity */
+ while (len < 0) {
+ angle -= 90 * 64;
+ len += sidelen;
+ oddSide = !oddSide;
+ }
+ }
+ if (oddSide)
+ len = sidelen - len;
+ a0 = 0;
+ a1 = DASH_MAP_SIZE - 1;
+ /*
+ * binary search for the closest pre-computed length
+ */
+ while (a1 - a0 > 1) {
+ a = (a0 + a1) / 2;
+ if (len > map->map[a])
+ a0 = a;
+ else
+ a1 = a;
+ }
+ angleexcess = dashIndexToXAngle (a0);
+ /*
+ * linearly interpolate to the next point
+ */
+ angleexcess += (len - map->map[a0]) /
+ (map->map[a0+1] - map->map[a0]) * dashXAngleStep;
+ if (oddSide)
+ angle += (90 * 64) - angleexcess;
+ else
+ angle += angleexcess;
+ return angle;
+}
+
+/*
+ * compute the angle of an ellipse which cooresponds to
+ * the given path length. Note that the correct solution
+ * to this problem is an eliptic integral, we'll punt and
+ * approximate (it's only for dashes anyway). This
+ * approximation uses a polygon.
+ *
+ * The remaining portion of len is stored in *lenp -
+ * this will be negative if the arc extends beyond
+ * len and positive if len extends beyond the arc.
+ */
+
+static int
+computeAngleFromPath (startAngle, endAngle, map, lenp, backwards)
+ int startAngle, endAngle; /* normalized absolute angles in *64 degrees */
+ dashMap *map;
+ int *lenp;
+ int backwards;
+{
+ int a0, a1, a;
+ double len0;
+ int len;
+
+ a0 = startAngle;
+ a1 = endAngle;
+ len = *lenp;
+ if (backwards) {
+ /*
+ * flip the problem around to always be
+ * forwards
+ */
+ a0 = FULLCIRCLE - a0;
+ a1 = FULLCIRCLE - a1;
+ }
+ if (a1 < a0)
+ a1 += FULLCIRCLE;
+ len0 = angleToLength (a0, map);
+ a = lengthToAngle (len0 + len, map);
+ if (a > a1) {
+ a = a1;
+ len -= angleToLength (a1, map) - len0;
+ } else
+ len = 0;
+ if (backwards)
+ a = FULLCIRCLE - a;
+ *lenp = len;
+ return a;
+}
+
+/*
+ * scan convert wide arcs.
+ */
+
+/*
+ * draw zero width/height arcs
+ */
+
+static void
+drawZeroArc (pDraw, pGC, tarc, lw, left, right)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ xArc *tarc;
+ int lw;
+ miArcFacePtr right, left;
+{
+ double x0, y0, x1, y1, w, h, x, y;
+ double xmax, ymax, xmin, ymin;
+ int a0, a1;
+ double a, startAngle, endAngle;
+ double l, lx, ly;
+
+ l = lw / 2.0;
+ a0 = tarc->angle1;
+ a1 = tarc->angle2;
+ if (a1 > FULLCIRCLE)
+ a1 = FULLCIRCLE;
+ else if (a1 < -FULLCIRCLE)
+ a1 = -FULLCIRCLE;
+ w = (double)tarc->width / 2.0;
+ h = (double)tarc->height / 2.0;
+ /*
+ * play in X coordinates right away
+ */
+ startAngle = - ((double) a0 / 64.0);
+ endAngle = - ((double) (a0 + a1) / 64.0);
+
+ xmax = -w;
+ xmin = w;
+ ymax = -h;
+ ymin = h;
+ a = startAngle;
+ for (;;)
+ {
+ x = w * miDcos(a);
+ y = h * miDsin(a);
+ if (a == startAngle)
+ {
+ x0 = x;
+ y0 = y;
+ }
+ if (a == endAngle)
+ {
+ x1 = x;
+ y1 = y;
+ }
+ if (x > xmax)
+ xmax = x;
+ if (x < xmin)
+ xmin = x;
+ if (y > ymax)
+ ymax = y;
+ if (y < ymin)
+ ymin = y;
+ if (a == endAngle)
+ break;
+ if (a1 < 0) /* clockwise */
+ {
+ if (floor (a / 90.0) == floor (endAngle / 90.0))
+ a = endAngle;
+ else
+ a = 90 * (floor (a/90.0) + 1);
+ }
+ else
+ {
+ if (ceil (a / 90.0) == ceil (endAngle / 90.0))
+ a = endAngle;
+ else
+ a = 90 * (ceil (a/90.0) - 1);
+ }
+ }
+ lx = ly = l;
+ if ((x1 - x0) + (y1 - y0) < 0)
+ lx = ly = -l;
+ if (h)
+ {
+ ly = 0.0;
+ lx = -lx;
+ }
+ else
+ lx = 0.0;
+ if (right)
+ {
+ right->center.x = x0;
+ right->center.y = y0;
+ right->clock.x = x0 - lx;
+ right->clock.y = y0 - ly;
+ right->counterClock.x = x0 + lx;
+ right->counterClock.y = y0 + ly;
+ }
+ if (left)
+ {
+ left->center.x = x1;
+ left->center.y = y1;
+ left->clock.x = x1 + lx;
+ left->clock.y = y1 + ly;
+ left->counterClock.x = x1 - lx;
+ left->counterClock.y = y1 - ly;
+ }
+
+ x0 = xmin;
+ x1 = xmax;
+ y0 = ymin;
+ y1 = ymax;
+ if (ymin != y1) {
+ xmin = -l;
+ xmax = l;
+ } else {
+ ymin = -l;
+ ymax = l;
+ }
+ if (xmax != xmin && ymax != ymin) {
+ int minx, maxx, miny, maxy;
+ xRectangle rect;
+
+ minx = ICEIL (xmin + w) + tarc->x;
+ maxx = ICEIL (xmax + w) + tarc->x;
+ miny = ICEIL (ymin + h) + tarc->y;
+ maxy = ICEIL (ymax + h) + tarc->y;
+ rect.x = minx;
+ rect.y = miny;
+ rect.width = maxx - minx;
+ rect.height = maxy - miny;
+ (*pGC->ops->PolyFillRect) (pDraw, pGC, 1, &rect);
+ }
+}
+
+/*
+ * this computes the ellipse y value associated with the
+ * bottom of the tail.
+ */
+
+static void
+tailEllipseY (def, acc)
+ struct arc_def *def;
+ struct accelerators *acc;
+{
+ double t;
+
+ acc->tail_y = 0.0;
+ if (def->w == def->h)
+ return;
+ t = def->l * def->w;
+ if (def->w > def->h) {
+ if (t < acc->h2)
+ return;
+ } else {
+ if (t > acc->h2)
+ return;
+ }
+ t = 2.0 * def->h * t;
+ t = (CUBED_ROOT_4 * acc->h2 - cbrt(t * t)) / acc->h2mw2;
+ if (t > 0.0)
+ acc->tail_y = def->h / CUBED_ROOT_2 * sqrt(t);
+}
+
+/*
+ * inverse functions -- compute edge coordinates
+ * from the ellipse
+ */
+
+static double
+outerXfromXY (x, y, def, acc)
+ double x, y;
+ struct arc_def *def;
+ struct accelerators *acc;
+{
+ return x + (x * acc->h2l) / sqrt (x*x * acc->h4 + y*y * acc->w4);
+}
+
+static double
+outerYfromXY (x, y, def, acc)
+ double x, y;
+ struct arc_def *def;
+ struct accelerators *acc;
+{
+ return y + (y * acc->w2l) / sqrt (x*x * acc->h4 + y*y * acc->w4);
+}
+
+static double
+innerXfromXY (x, y, def, acc)
+ double x, y;
+ struct arc_def *def;
+ struct accelerators *acc;
+{
+ return x - (x * acc->h2l) / sqrt (x*x * acc->h4 + y*y * acc->w4);
+}
+
+static double
+innerYfromXY (x, y, def, acc)
+ double x, y;
+ struct arc_def *def;
+ struct accelerators *acc;
+{
+ return y - (y * acc->w2l) / sqrt (x*x * acc->h4 + y*y * acc->w4);
+}
+
+static double
+innerYfromY (y, def, acc)
+ double y;
+ struct arc_def *def;
+ struct accelerators *acc;
+{
+ double x;
+
+ x = (def->w / def->h) * sqrt (acc->h2 - y*y);
+
+ return y - (y * acc->w2l) / sqrt (x*x * acc->h4 + y*y * acc->w4);
+}
+
+static void
+computeLine (x1, y1, x2, y2, line)
+ double x1, y1, x2, y2;
+ struct line *line;
+{
+ if (y1 == y2)
+ line->valid = 0;
+ else {
+ line->m = (x1 - x2) / (y1 - y2);
+ line->b = x1 - y1 * line->m;
+ line->valid = 1;
+ }
+}
+
+/*
+ * compute various accelerators for an ellipse. These
+ * are simply values that are used repeatedly in
+ * the computations
+ */
+
+static void
+computeAcc (tarc, lw, def, acc)
+ xArc *tarc;
+ int lw;
+ struct arc_def *def;
+ struct accelerators *acc;
+{
+ def->w = ((double) tarc->width) / 2.0;
+ def->h = ((double) tarc->height) / 2.0;
+ def->l = ((double) lw) / 2.0;
+ acc->h2 = def->h * def->h;
+ acc->w2 = def->w * def->w;
+ acc->h4 = acc->h2 * acc->h2;
+ acc->w4 = acc->w2 * acc->w2;
+ acc->h2l = acc->h2 * def->l;
+ acc->w2l = acc->w2 * def->l;
+ acc->h2mw2 = acc->h2 - acc->w2;
+ acc->fromIntX = (tarc->width & 1) ? 0.5 : 0.0;
+ acc->fromIntY = (tarc->height & 1) ? 0.5 : 0.0;
+ acc->xorg = tarc->x + (tarc->width >> 1);
+ acc->yorgu = tarc->y + (tarc->height >> 1);
+ acc->yorgl = acc->yorgu + (tarc->height & 1);
+ tailEllipseY (def, acc);
+}
+
+/*
+ * compute y value bounds of various portions of the arc,
+ * the outer edge, the ellipse and the inner edge.
+ */
+
+static void
+computeBound (def, bound, acc, right, left)
+ struct arc_def *def;
+ struct arc_bound *bound;
+ struct accelerators *acc;
+ miArcFacePtr right, left;
+{
+ double t;
+ double innerTaily;
+ double tail_y;
+ struct bound innerx, outerx;
+ struct bound ellipsex;
+
+ bound->ellipse.min = Dsin (def->a0) * def->h;
+ bound->ellipse.max = Dsin (def->a1) * def->h;
+ if (def->a0 == 45 && def->w == def->h)
+ ellipsex.min = bound->ellipse.min;
+ else
+ ellipsex.min = Dcos (def->a0) * def->w;
+ if (def->a1 == 45 && def->w == def->h)
+ ellipsex.max = bound->ellipse.max;
+ else
+ ellipsex.max = Dcos (def->a1) * def->w;
+ bound->outer.min = outerYfromXY (ellipsex.min, bound->ellipse.min, def, acc);
+ bound->outer.max = outerYfromXY (ellipsex.max, bound->ellipse.max, def, acc);
+ bound->inner.min = innerYfromXY (ellipsex.min, bound->ellipse.min, def, acc);
+ bound->inner.max = innerYfromXY (ellipsex.max, bound->ellipse.max, def, acc);
+
+ outerx.min = outerXfromXY (ellipsex.min, bound->ellipse.min, def, acc);
+ outerx.max = outerXfromXY (ellipsex.max, bound->ellipse.max, def, acc);
+ innerx.min = innerXfromXY (ellipsex.min, bound->ellipse.min, def, acc);
+ innerx.max = innerXfromXY (ellipsex.max, bound->ellipse.max, def, acc);
+
+ /*
+ * save the line end points for the
+ * cap code to use. Careful here, these are
+ * in cartesean coordinates (y increasing upwards)
+ * while the cap code uses inverted coordinates
+ * (y increasing downwards)
+ */
+
+ if (right) {
+ right->counterClock.y = bound->outer.min;
+ right->counterClock.x = outerx.min;
+ right->center.y = bound->ellipse.min;
+ right->center.x = ellipsex.min;
+ right->clock.y = bound->inner.min;
+ right->clock.x = innerx.min;
+ }
+
+ if (left) {
+ left->clock.y = bound->outer.max;
+ left->clock.x = outerx.max;
+ left->center.y = bound->ellipse.max;
+ left->center.x = ellipsex.max;
+ left->counterClock.y = bound->inner.max;
+ left->counterClock.x = innerx.max;
+ }
+
+ bound->left.min = bound->inner.max;
+ bound->left.max = bound->outer.max;
+ bound->right.min = bound->inner.min;
+ bound->right.max = bound->outer.min;
+
+ computeLine (innerx.min, bound->inner.min, outerx.min, bound->outer.min,
+ &acc->right);
+ computeLine (innerx.max, bound->inner.max, outerx.max, bound->outer.max,
+ &acc->left);
+
+ if (bound->inner.min > bound->inner.max) {
+ t = bound->inner.min;
+ bound->inner.min = bound->inner.max;
+ bound->inner.max = t;
+ }
+ tail_y = acc->tail_y;
+ if (tail_y > bound->ellipse.max)
+ tail_y = bound->ellipse.max;
+ else if (tail_y < bound->ellipse.min)
+ tail_y = bound->ellipse.min;
+ innerTaily = innerYfromY (tail_y, def, acc);
+ if (bound->inner.min > innerTaily)
+ bound->inner.min = innerTaily;
+ if (bound->inner.max < innerTaily)
+ bound->inner.max = innerTaily;
+ bound->inneri.min = ICEIL(bound->inner.min - acc->fromIntY);
+ bound->inneri.max = floor(bound->inner.max - acc->fromIntY);
+ bound->outeri.min = ICEIL(bound->outer.min - acc->fromIntY);
+ bound->outeri.max = floor(bound->outer.max - acc->fromIntY);
+}
+
+/*
+ * this section computes the x value of the span at y
+ * intersected with the specified face of the ellipse.
+ *
+ * this is the min/max X value over the set of normal
+ * lines to the entire ellipse, the equation of the
+ * normal lines is:
+ *
+ * ellipse_x h^2 h^2
+ * x = ------------ y + ellipse_x (1 - --- )
+ * ellipse_y w^2 w^2
+ *
+ * compute the derivative with-respect-to ellipse_y and solve
+ * for zero:
+ *
+ * (w^2 - h^2) ellipse_y^3 + h^4 y
+ * 0 = - ----------------------------------
+ * h w ellipse_y^2 sqrt (h^2 - ellipse_y^2)
+ *
+ * ( h^4 y )
+ * ellipse_y = ( ---------- ) ^ (1/3)
+ * ( (h^2 - w^2) )
+ *
+ * The other two solutions to the equation are imaginary.
+ *
+ * This gives the position on the ellipse which generates
+ * the normal with the largest/smallest x intersection point.
+ *
+ * Now compute the second derivative to check whether
+ * the intersection is a minimum or maximum:
+ *
+ * h (y0^3 (w^2 - h^2) + h^2 y (3y0^2 - 2h^2))
+ * - -------------------------------------------
+ * w y0^3 (sqrt (h^2 - y^2)) ^ 3
+ *
+ * as we only care about the sign,
+ *
+ * - (y0^3 (w^2 - h^2) + h^2 y (3y0^2 - 2h^2))
+ *
+ * or (to use accelerators),
+ *
+ * y0^3 (h^2 - w^2) - h^2 y (3y0^2 - 2h^2)
+ *
+ */
+
+/*
+ * computes the position on the ellipse whose normal line
+ * intersects the given scan line maximally
+ */
+
+static double
+hookEllipseY (scan_y, bound, acc, left)
+ double scan_y;
+ struct arc_bound *bound;
+ struct accelerators *acc;
+ int left;
+{
+ double ret;
+
+ if (acc->h2mw2 == 0) {
+ if ( (scan_y > 0 && !left) || (scan_y < 0 && left) )
+ return bound->ellipse.min;
+ return bound->ellipse.max;
+ }
+ ret = (acc->h4 * scan_y) / (acc->h2mw2);
+ if (ret >= 0)
+ return cbrt (ret);
+ else
+ return -cbrt (-ret);
+}
+
+/*
+ * computes the X value of the intersection of the
+ * given scan line with the right side of the lower hook
+ */
+
+static double
+hookX (scan_y, def, bound, acc, left)
+ double scan_y;
+ struct arc_def *def;
+ struct arc_bound *bound;
+ struct accelerators *acc;
+ int left;
+{
+ double ellipse_y, x;
+ double maxMin;
+
+ if (def->w != def->h) {
+ ellipse_y = hookEllipseY (scan_y, bound, acc, left);
+ if (boundedLe (ellipse_y, bound->ellipse)) {
+ /*
+ * compute the value of the second
+ * derivative
+ */
+ maxMin = ellipse_y*ellipse_y*ellipse_y * acc->h2mw2 -
+ acc->h2 * scan_y * (3 * ellipse_y*ellipse_y - 2*acc->h2);
+ if ((left && maxMin > 0) || (!left && maxMin < 0)) {
+ if (ellipse_y == 0)
+ return def->w + left ? -def->l : def->l;
+ x = (acc->h2 * scan_y - ellipse_y * acc->h2mw2) *
+ sqrt (acc->h2 - ellipse_y * ellipse_y) /
+ (def->h * def->w * ellipse_y);
+ return x;
+ }
+ }
+ }
+ if (left) {
+ if (acc->left.valid && boundedLe (scan_y, bound->left)) {
+ x = intersectLine (scan_y, acc->left);
+ } else {
+ if (acc->right.valid)
+ x = intersectLine (scan_y, acc->right);
+ else
+ x = def->w - def->l;
+ }
+ } else {
+ if (acc->right.valid && boundedLe (scan_y, bound->right)) {
+ x = intersectLine (scan_y, acc->right);
+ } else {
+ if (acc->left.valid)
+ x = intersectLine (scan_y, acc->left);
+ else
+ x = def->w - def->l;
+ }
+ }
+ return x;
+}
+
+/*
+ * generate the set of spans with
+ * the given y coordinate
+ */
+
+static void
+arcSpan (y, lx, lw, rx, rw, def, bounds, acc, mask)
+ int y;
+ int lx;
+ int lw;
+ int rx;
+ int rw;
+ struct arc_def *def;
+ struct arc_bound *bounds;
+ struct accelerators *acc;
+ int mask;
+{
+ int linx, loutx, rinx, routx;
+ double x, altx;
+
+ if (boundedLe (y, bounds->inneri)) {
+ linx = -(lx + lw);
+ rinx = rx;
+ } else {
+ /*
+ * intersection with left face
+ */
+ x = hookX (y + acc->fromIntY, def, bounds, acc, 1);
+ if (acc->right.valid &&
+ boundedLe (y + acc->fromIntY, bounds->right))
+ {
+ altx = intersectLine (y + acc->fromIntY, acc->right);
+ if (altx < x)
+ x = altx;
+ }
+ linx = -ICEIL(acc->fromIntX - x);
+ rinx = ICEIL(acc->fromIntX + x);
+ }
+ if (boundedLe (y, bounds->outeri)) {
+ loutx = -lx;
+ routx = rx + rw;
+ } else {
+ /*
+ * intersection with right face
+ */
+ x = hookX (y + acc->fromIntY, def, bounds, acc, 0);
+ if (acc->left.valid &&
+ boundedLe (y + acc->fromIntY, bounds->left))
+ {
+ altx = x;
+ x = intersectLine (y + acc->fromIntY, acc->left);
+ if (x < altx)
+ x = altx;
+ }
+ loutx = -ICEIL(acc->fromIntX - x);
+ routx = ICEIL(acc->fromIntX + x);
+ }
+ if (routx > rinx) {
+ if (mask & 1)
+ newFinalSpan (acc->yorgu - y,
+ acc->xorg + rinx, acc->xorg + routx);
+ if (mask & 8)
+ newFinalSpan (acc->yorgl + y,
+ acc->xorg + rinx, acc->xorg + routx);
+ }
+ if (loutx > linx) {
+ if (mask & 2)
+ newFinalSpan (acc->yorgu - y,
+ acc->xorg - loutx, acc->xorg - linx);
+ if (mask & 4)
+ newFinalSpan (acc->yorgl + y,
+ acc->xorg - loutx, acc->xorg - linx);
+ }
+}
+
+static void
+arcSpan0 (lx, lw, rx, rw, def, bounds, acc, mask)
+ int lx;
+ int lw;
+ int rx;
+ int rw;
+ struct arc_def *def;
+ struct arc_bound *bounds;
+ struct accelerators *acc;
+ int mask;
+{
+ double x;
+
+ if (boundedLe (0, bounds->inneri) &&
+ acc->left.valid && boundedLe (0, bounds->left) &&
+ acc->left.b > 0)
+ {
+ x = def->w - def->l;
+ if (acc->left.b < x)
+ x = acc->left.b;
+ lw = ICEIL(acc->fromIntX - x) - lx;
+ rw += rx;
+ rx = ICEIL(acc->fromIntX + x);
+ rw -= rx;
+ }
+ arcSpan (0, lx, lw, rx, rw, def, bounds, acc, mask);
+}
+
+static void
+tailSpan (y, lw, rw, def, bounds, acc, mask)
+ int y;
+ int lw;
+ int rw;
+ struct arc_def *def;
+ struct arc_bound *bounds;
+ struct accelerators *acc;
+ int mask;
+{
+ double yy, xalt, x, lx, rx;
+ int n;
+
+ if (boundedLe(y, bounds->outeri))
+ arcSpan (y, 0, lw, -rw, rw, def, bounds, acc, mask);
+ else if (def->w != def->h) {
+ yy = y + acc->fromIntY;
+ x = tailX(yy, def, bounds, acc);
+ if (yy == 0.0 && x == -rw - acc->fromIntX)
+ return;
+ if (acc->right.valid && boundedLe (yy, bounds->right)) {
+ rx = x;
+ lx = -x;
+ xalt = intersectLine (yy, acc->right);
+ if (xalt >= -rw - acc->fromIntX && xalt <= rx)
+ rx = xalt;
+ n = ICEIL(acc->fromIntX + lx);
+ if (lw > n) {
+ if (mask & 2)
+ newFinalSpan (acc->yorgu - y,
+ acc->xorg + n, acc->xorg + lw);
+ if (mask & 4)
+ newFinalSpan (acc->yorgl + y,
+ acc->xorg + n, acc->xorg + lw);
+ }
+ n = ICEIL(acc->fromIntX + rx);
+ if (n > -rw) {
+ if (mask & 1)
+ newFinalSpan (acc->yorgu - y,
+ acc->xorg - rw, acc->xorg + n);
+ if (mask & 8)
+ newFinalSpan (acc->yorgl + y,
+ acc->xorg - rw, acc->xorg + n);
+ }
+ }
+ arcSpan (y,
+ ICEIL(acc->fromIntX - x), 0,
+ ICEIL(acc->fromIntX + x), 0,
+ def, bounds, acc, mask);
+ }
+}
+
+/*
+ * create whole arcs out of pieces. This code is
+ * very bad.
+ */
+
+static struct finalSpan **finalSpans = NULL;
+static int finalMiny = 0, finalMaxy = -1;
+static int finalSize = 0;
+
+static int nspans = 0; /* total spans, not just y coords */
+
+struct finalSpan {
+ struct finalSpan *next;
+ int min, max; /* x values */
+};
+
+static struct finalSpan *freeFinalSpans, *tmpFinalSpan;
+
+# define allocFinalSpan() (freeFinalSpans ?\
+ ((tmpFinalSpan = freeFinalSpans), \
+ (freeFinalSpans = freeFinalSpans->next), \
+ (tmpFinalSpan->next = 0), \
+ tmpFinalSpan) : \
+ realAllocSpan ())
+
+# define SPAN_CHUNK_SIZE 128
+
+struct finalSpanChunk {
+ struct finalSpan data[SPAN_CHUNK_SIZE];
+ struct finalSpanChunk *next;
+};
+
+static struct finalSpanChunk *chunks;
+
+struct finalSpan *
+realAllocSpan ()
+{
+ register struct finalSpanChunk *newChunk;
+ register struct finalSpan *span;
+ register int i;
+
+ newChunk = (struct finalSpanChunk *) xalloc (sizeof (struct finalSpanChunk));
+ if (!newChunk)
+ return (struct finalSpan *) NULL;
+ newChunk->next = chunks;
+ chunks = newChunk;
+ freeFinalSpans = span = newChunk->data + 1;
+ for (i = 1; i < SPAN_CHUNK_SIZE-1; i++) {
+ span->next = span+1;
+ span++;
+ }
+ span->next = 0;
+ span = newChunk->data;
+ span->next = 0;
+ return span;
+}
+
+static void
+disposeFinalSpans ()
+{
+ struct finalSpanChunk *chunk, *next;
+
+ for (chunk = chunks; chunk; chunk = next) {
+ next = chunk->next;
+ xfree (chunk);
+ }
+ chunks = 0;
+ freeFinalSpans = 0;
+ xfree(finalSpans);
+ finalSpans = 0;
+}
+
+static void
+fillSpans (pDrawable, pGC)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+{
+ register struct finalSpan *span;
+ register DDXPointPtr xSpan;
+ register int *xWidth;
+ register int i;
+ register struct finalSpan **f;
+ register int spany;
+ DDXPointPtr xSpans;
+ int *xWidths;
+
+ if (nspans == 0)
+ return;
+ xSpan = xSpans = (DDXPointPtr) ALLOCATE_LOCAL (nspans * sizeof (DDXPointRec));
+ xWidth = xWidths = (int *) ALLOCATE_LOCAL (nspans * sizeof (int));
+ if (xSpans && xWidths)
+ {
+ i = 0;
+ f = finalSpans;
+ for (spany = finalMiny; spany <= finalMaxy; spany++, f++) {
+ for (span = *f; span; span=span->next) {
+ if (span->max <= span->min)
+ continue;
+ xSpan->x = span->min;
+ xSpan->y = spany;
+ ++xSpan;
+ *xWidth++ = span->max - span->min;
+ ++i;
+ }
+ }
+ (*pGC->ops->FillSpans) (pDrawable, pGC, i, xSpans, xWidths, TRUE);
+ }
+ disposeFinalSpans ();
+ if (xSpans)
+ DEALLOCATE_LOCAL (xSpans);
+ if (xWidths)
+ DEALLOCATE_LOCAL (xWidths);
+ finalMiny = 0;
+ finalMaxy = -1;
+ finalSize = 0;
+ nspans = 0;
+}
+
+# define SPAN_REALLOC 100
+
+# define findSpan(y) ((finalMiny <= (y) && (y) <= finalMaxy) ? \
+ &finalSpans[(y) - finalMiny] : \
+ realFindSpan (y))
+
+static struct finalSpan **
+realFindSpan (y)
+ int y;
+{
+ struct finalSpan **newSpans;
+ int newSize, newMiny, newMaxy;
+ int change;
+ int i;
+
+ if (y < finalMiny || y > finalMaxy) {
+ if (!finalSize) {
+ finalMiny = y;
+ finalMaxy = y - 1;
+ }
+ if (y < finalMiny)
+ change = finalMiny - y;
+ else
+ change = y - finalMaxy;
+ if (change >= SPAN_REALLOC)
+ change += SPAN_REALLOC;
+ else
+ change = SPAN_REALLOC;
+ newSize = finalSize + change;
+ newSpans = (struct finalSpan **) xalloc
+ (newSize * sizeof (struct finalSpan *));
+ if (!newSpans)
+ return (struct finalSpan **)NULL;
+ newMiny = finalMiny;
+ newMaxy = finalMaxy;
+ if (y < finalMiny)
+ newMiny = finalMiny - change;
+ else
+ newMaxy = finalMaxy + change;
+ if (finalSpans) {
+ memmove(((char *) newSpans) + (finalMiny-newMiny) * sizeof (struct finalSpan *),
+ (char *) finalSpans,
+ finalSize * sizeof (struct finalSpan *));
+ xfree (finalSpans);
+ }
+ if ((i = finalMiny - newMiny) > 0)
+ bzero ((char *)newSpans, i * sizeof (struct finalSpan *));
+ if ((i = newMaxy - finalMaxy) > 0)
+ bzero ((char *)(newSpans + newSize - i),
+ i * sizeof (struct finalSpan *));
+ finalSpans = newSpans;
+ finalMaxy = newMaxy;
+ finalMiny = newMiny;
+ finalSize = newSize;
+ }
+ return &finalSpans[y - finalMiny];
+}
+
+static void
+newFinalSpan (y, xmin, xmax)
+ int y;
+ register int xmin, xmax;
+{
+ register struct finalSpan *x;
+ register struct finalSpan **f;
+ struct finalSpan *oldx;
+ struct finalSpan *prev;
+
+ f = findSpan (y);
+ if (!f)
+ return;
+ oldx = 0;
+ for (;;) {
+ prev = 0;
+ for (x = *f; x; x=x->next) {
+ if (x == oldx) {
+ prev = x;
+ continue;
+ }
+ if (x->min <= xmax && xmin <= x->max) {
+ if (oldx) {
+ oldx->min = min (x->min, xmin);
+ oldx->max = max (x->max, xmax);
+ if (prev)
+ prev->next = x->next;
+ else
+ *f = x->next;
+ --nspans;
+ } else {
+ x->min = min (x->min, xmin);
+ x->max = max (x->max, xmax);
+ oldx = x;
+ }
+ xmin = oldx->min;
+ xmax = oldx->max;
+ break;
+ }
+ prev = x;
+ }
+ if (!x)
+ break;
+ }
+ if (!oldx) {
+ x = allocFinalSpan ();
+ if (x)
+ {
+ x->min = xmin;
+ x->max = xmax;
+ x->next = *f;
+ *f = x;
+ ++nspans;
+ }
+ }
+}
+
+static void
+mirrorSppPoint (quadrant, sppPoint)
+ int quadrant;
+ SppPointPtr sppPoint;
+{
+ switch (quadrant) {
+ case 0:
+ break;
+ case 1:
+ sppPoint->x = -sppPoint->x;
+ break;
+ case 2:
+ sppPoint->x = -sppPoint->x;
+ sppPoint->y = -sppPoint->y;
+ break;
+ case 3:
+ sppPoint->y = -sppPoint->y;
+ break;
+ }
+ /*
+ * and translate to X coordinate system
+ */
+ sppPoint->y = -sppPoint->y;
+}
+
+/*
+ * split an arc into pieces which are scan-converted
+ * in the first-quadrant and mirrored into position.
+ * This is necessary as the scan-conversion code can
+ * only deal with arcs completely contained in the
+ * first quadrant.
+ */
+
+static void
+drawArc (tarc, l, a0, a1, right, left)
+ xArc *tarc;
+ int l, a0, a1;
+ miArcFacePtr right, left; /* save end line points */
+{
+ struct arc_def def;
+ struct accelerators acc;
+ int startq, endq, curq;
+ int rightq, leftq, righta, lefta;
+ miArcFacePtr passRight, passLeft;
+ int q0, q1, mask;
+ struct band {
+ int a0, a1;
+ int mask;
+ } band[5], sweep[20];
+ int bandno, sweepno;
+ int i, j;
+ int flipRight = 0, flipLeft = 0;
+ int copyEnd = 0;
+ miArcSpanData *spdata;
+ Bool mustFree;
+
+ spdata = miComputeWideEllipse(l, tarc, &mustFree);
+ if (!spdata)
+ return;
+
+ if (a1 < a0)
+ a1 += 360 * 64;
+ startq = a0 / (90 * 64);
+ if (a0 == a1)
+ endq = startq;
+ else
+ endq = (a1-1) / (90 * 64);
+ bandno = 0;
+ curq = startq;
+ rightq = -1;
+ for (;;) {
+ switch (curq) {
+ case 0:
+ if (a0 > 90 * 64)
+ q0 = 0;
+ else
+ q0 = a0;
+ if (a1 < 360 * 64)
+ q1 = min (a1, 90 * 64);
+ else
+ q1 = 90 * 64;
+ if (curq == startq && a0 == q0 && rightq < 0) {
+ righta = q0;
+ rightq = curq;
+ }
+ if (curq == endq && a1 == q1) {
+ lefta = q1;
+ leftq = curq;
+ }
+ break;
+ case 1:
+ if (a1 < 90 * 64)
+ q0 = 0;
+ else
+ q0 = 180 * 64 - min (a1, 180 * 64);
+ if (a0 > 180 * 64)
+ q1 = 90 * 64;
+ else
+ q1 = 180 * 64 - max (a0, 90 * 64);
+ if (curq == startq && 180 * 64 - a0 == q1) {
+ righta = q1;
+ rightq = curq;
+ }
+ if (curq == endq && 180 * 64 - a1 == q0) {
+ lefta = q0;
+ leftq = curq;
+ }
+ break;
+ case 2:
+ if (a0 > 270 * 64)
+ q0 = 0;
+ else
+ q0 = max (a0, 180 * 64) - 180 * 64;
+ if (a1 < 180 * 64)
+ q1 = 90 * 64;
+ else
+ q1 = min (a1, 270 * 64) - 180 * 64;
+ if (curq == startq && a0 - 180*64 == q0) {
+ righta = q0;
+ rightq = curq;
+ }
+ if (curq == endq && a1 - 180 * 64 == q1) {
+ lefta = q1;
+ leftq = curq;
+ }
+ break;
+ case 3:
+ if (a1 < 270 * 64)
+ q0 = 0;
+ else
+ q0 = 360 * 64 - min (a1, 360 * 64);
+ q1 = 360 * 64 - max (a0, 270 * 64);
+ if (curq == startq && 360 * 64 - a0 == q1) {
+ righta = q1;
+ rightq = curq;
+ }
+ if (curq == endq && 360 * 64 - a1 == q0) {
+ lefta = q0;
+ leftq = curq;
+ }
+ break;
+ }
+ band[bandno].a0 = q0;
+ band[bandno].a1 = q1;
+ band[bandno].mask = 1 << curq;
+ bandno++;
+ if (curq == endq)
+ break;
+ curq++;
+ if (curq == 4) {
+ a0 = 0;
+ a1 -= 360 * 64;
+ curq = 0;
+ endq -= 4;
+ }
+ }
+ sweepno = 0;
+ for (;;) {
+ q0 = 90 * 64;
+ mask = 0;
+ /*
+ * find left-most point
+ */
+ for (i = 0; i < bandno; i++)
+ if (band[i].a0 <= q0) {
+ q0 = band[i].a0;
+ q1 = band[i].a1;
+ mask = band[i].mask;
+ }
+ if (!mask)
+ break;
+ /*
+ * locate next point of change
+ */
+ for (i = 0; i < bandno; i++)
+ if (!(mask & band[i].mask)) {
+ if (band[i].a0 == q0) {
+ if (band[i].a1 < q1)
+ q1 = band[i].a1;
+ mask |= band[i].mask;
+ } else if (band[i].a0 < q1)
+ q1 = band[i].a0;
+ }
+ /*
+ * create a new sweep
+ */
+ sweep[sweepno].a0 = q0;
+ sweep[sweepno].a1 = q1;
+ sweep[sweepno].mask = mask;
+ sweepno++;
+ /*
+ * subtract the sweep from the affected bands
+ */
+ for (i = 0; i < bandno; i++)
+ if (band[i].a0 == q0) {
+ band[i].a0 = q1;
+ /*
+ * check if this band is empty
+ */
+ if (band[i].a0 == band[i].a1)
+ band[i].a1 = band[i].a0 = 90 * 64 + 1;
+ }
+ }
+ computeAcc (tarc, l, &def, &acc);
+ for (j = 0; j < sweepno; j++) {
+ mask = sweep[j].mask;
+ passRight = passLeft = 0;
+ if (mask & (1 << rightq)) {
+ if (sweep[j].a0 == righta)
+ passRight = right;
+ else if (sweep[j].a1 == righta) {
+ passLeft = right;
+ flipRight = 1;
+ }
+ }
+ if (mask & (1 << leftq)) {
+ if (sweep[j].a1 == lefta)
+ {
+ if (passLeft)
+ copyEnd = 1;
+ passLeft = left;
+ }
+ else if (sweep[j].a0 == lefta) {
+ if (passRight)
+ copyEnd = 1;
+ passRight = left;
+ flipLeft = 1;
+ }
+ }
+ drawQuadrant (&def, &acc, sweep[j].a0, sweep[j].a1, mask,
+ passRight, passLeft, spdata);
+ }
+ /*
+ * when copyEnd is set, both ends of the arc were computed
+ * at the same time; drawQuadrant only takes one end though,
+ * so the left end will be the only one holding the data. Copy
+ * it from there.
+ */
+ if (copyEnd)
+ *right = *left;
+ /*
+ * mirror the coordinates generated for the
+ * faces of the arc
+ */
+ if (right) {
+ mirrorSppPoint (rightq, &right->clock);
+ mirrorSppPoint (rightq, &right->center);
+ mirrorSppPoint (rightq, &right->counterClock);
+ if (flipRight) {
+ SppPointRec temp;
+
+ temp = right->clock;
+ right->clock = right->counterClock;
+ right->counterClock = temp;
+ }
+ }
+ if (left) {
+ mirrorSppPoint (leftq, &left->counterClock);
+ mirrorSppPoint (leftq, &left->center);
+ mirrorSppPoint (leftq, &left->clock);
+ if (flipLeft) {
+ SppPointRec temp;
+
+ temp = left->clock;
+ left->clock = left->counterClock;
+ left->counterClock = temp;
+ }
+ }
+ if (mustFree)
+ xfree(spdata);
+}
+
+static void
+drawQuadrant (def, acc, a0, a1, mask, right, left, spdata)
+ struct arc_def *def;
+ struct accelerators *acc;
+ int a0, a1;
+ int mask;
+ miArcFacePtr right, left;
+ miArcSpanData *spdata;
+{
+ struct arc_bound bound;
+ double yy, x, xalt;
+ int y, miny, maxy;
+ int n;
+ miArcSpan *span;
+
+ def->a0 = ((double) a0) / 64.0;
+ def->a1 = ((double) a1) / 64.0;
+ computeBound (def, &bound, acc, right, left);
+ yy = bound.inner.min;
+ if (bound.outer.min < yy)
+ yy = bound.outer.min;
+ miny = ICEIL(yy - acc->fromIntY);
+ yy = bound.inner.max;
+ if (bound.outer.max > yy)
+ yy = bound.outer.max;
+ maxy = floor(yy - acc->fromIntY);
+ y = spdata->k;
+ span = spdata->spans;
+ if (spdata->top)
+ {
+ if (a1 == 90 * 64 && (mask & 1))
+ newFinalSpan (acc->yorgu - y - 1, acc->xorg, acc->xorg + 1);
+ span++;
+ }
+ for (n = spdata->count1; --n >= 0; )
+ {
+ if (y < miny)
+ return;
+ if (y <= maxy) {
+ arcSpan (y,
+ span->lx, -span->lx, 0, span->lx + span->lw,
+ def, &bound, acc, mask);
+ if (span->rw + span->rx)
+ tailSpan (y, -span->rw, -span->rx, def, &bound, acc, mask);
+ }
+ y--;
+ span++;
+ }
+ if (y < miny)
+ return;
+ if (spdata->hole)
+ {
+ if (y <= maxy)
+ arcSpan (y, 0, 0, 0, 1, def, &bound, acc, mask & 0xc);
+ }
+ for (n = spdata->count2; --n >= 0; )
+ {
+ if (y < miny)
+ return;
+ if (y <= maxy)
+ arcSpan (y, span->lx, span->lw, span->rx, span->rw,
+ def, &bound, acc, mask);
+ y--;
+ span++;
+ }
+ if (spdata->bot && miny <= y && y <= maxy)
+ {
+ n = mask;
+ if (y == miny)
+ n &= 0xc;
+ if (span->rw <= 0) {
+ arcSpan0 (span->lx, -span->lx, 0, span->lx + span->lw,
+ def, &bound, acc, n);
+ if (span->rw + span->rx)
+ tailSpan (y, -span->rw, -span->rx, def, &bound, acc, n);
+ }
+ else
+ arcSpan0 (span->lx, span->lw, span->rx, span->rw,
+ def, &bound, acc, n);
+ y--;
+ }
+ while (y >= miny) {
+ yy = y + acc->fromIntY;
+ if (def->w == def->h) {
+ xalt = def->w - def->l;
+ x = -sqrt(xalt * xalt - yy * yy);
+ } else {
+ x = tailX(yy, def, &bound, acc);
+ if (acc->left.valid && boundedLe (yy, bound.left)) {
+ xalt = intersectLine (yy, acc->left);
+ if (xalt < x)
+ x = xalt;
+ }
+ if (acc->right.valid && boundedLe (yy, bound.right)) {
+ xalt = intersectLine (yy, acc->right);
+ if (xalt < x)
+ x = xalt;
+ }
+ }
+ arcSpan (y,
+ ICEIL(acc->fromIntX - x), 0,
+ ICEIL(acc->fromIntX + x), 0,
+ def, &bound, acc, mask);
+ y--;
+ }
+}
diff --git a/xc/programs/Xserver/mi/mibank.c b/xc/programs/Xserver/mi/mibank.c
new file mode 100644
index 000000000..cdaf1047f
--- /dev/null
+++ b/xc/programs/Xserver/mi/mibank.c
@@ -0,0 +1,3173 @@
+/*
+ * Copyright 1997,1998 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Copyright 1990,91,92,93 by Thomas Roell, Germany.
+ * Copyright 1991,92,93 by SGCS (Snitily Graphics Consulting Services), USA.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation, and that the name of Thomas Roell nor
+ * SGCS be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Thomas Roell nor SGCS makes no representations about the suitability
+ * of this software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ *
+ * THOMAS ROELL AND SGCS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR SGCS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $XFree86: xc/programs/Xserver/mi/mibank.c,v 1.4 1998/09/19 12:15:02 dawes Exp $ */
+
+/*
+ * This thing originated from an idea of Edwin Goei and his bank switching
+ * code for the DEC TX board.
+ */
+
+/*
+ * Heavily modified for the XFree86 Project to turn this into an mi wrapper.
+ * --- Marc Aurele La France (tsi@ualberta.ca)
+ */
+
+/*
+ * "Heavily modified", indeed! By the time this is finalized, there probably
+ * won't be much left of Roell's code...
+ *
+ * TO DO:
+ * - Pixels with imbedded bank boundaries are required to be off-screen. There
+ * >might< be a way to fool the underlying framebuffer into dealing with
+ * partial pixels.
+ * - Generalize this to do (hardware) colour plane switching.
+ */
+
+/* #define NO_ALLOCA 1 */
+
+#include "servermd.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "mibank.h"
+
+extern WindowPtr *WindowTable;
+
+#define BANK_SINGLE 0
+#define BANK_SHARED 1
+#define BANK_DOUBLE 2
+
+typedef struct _miBankScreen
+{
+ miBankInfoRec BankInfo;
+ unsigned int nBankBPP;
+ int type;
+
+ unsigned long nBitsPerBank;
+ unsigned long nBitsPerScanline;
+ unsigned long nPixelsPerScanlinePadUnit;
+
+ PixmapPtr pScreenPixmap;
+ PixmapPtr pBankPixmap;
+ GCPtr pBankGC;
+
+ int nBanks, maxRects;
+ RegionPtr *pBanks;
+
+ pointer pbits;
+
+ /*
+ * Screen Wrappers
+ */
+ CreateScreenResourcesProcPtr CreateScreenResources;
+ CloseScreenProcPtr CloseScreen;
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ CreateGCProcPtr CreateGC;
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ CopyWindowProcPtr CopyWindow;
+ BSFuncRec BackingStoreFuncs;
+} miBankScreenRec, *miBankScreenPtr;
+
+typedef struct _miBankGC
+{
+ GCOps *wrappedOps;
+ GCFuncs *wrappedFuncs;
+ RegionPtr pBankedClips[1];
+} miBankGCRec, *miBankGCPtr;
+
+typedef struct _miBankQueue
+{
+ Bool fastBlit;
+ unsigned short srcBankNo;
+ unsigned short dstBankNo;
+ short x;
+ short y;
+ short w;
+ short h;
+} miBankQueue;
+
+/*
+ * CAVEAT: This banking scheme requires that the DDX store Pixmap data in the
+ * server's address space. If something other than a Pixmap's
+ * devPrivate field is used to point to this data, the following
+ * #define's should be changed. Ditto, if a Pixmap's devKind isn't used as its
+ * padded byte width. Unfortunately, there currently isn't any DDX-independent
+ * way of doing this. ModifyPixmapHeader can't be used because it clobbers
+ * pBankGC's validation.
+ */
+
+#define GetPixmapData(_pPix) \
+ ((pointer)((_pPix)->devPrivate.ptr))
+
+#define SetPixmapData(_pPix, _pbits) \
+ (_pPix)->devPrivate.ptr = (pointer)(_pbits)
+
+#define SetPixmapWidth(_pPix, _width, _padded) \
+ (_pPix)->drawable.width = (_width); \
+ (_pPix)->devKind = (_padded)
+
+#define SavePixmap \
+ int width = pScreenPriv->pBankPixmap->drawable.width; \
+ int devKind = pScreenPriv->pBankPixmap->devKind; \
+ pointer pbits = GetPixmapData(pScreenPriv->pBankPixmap)
+
+#define RestorePixmap \
+ SetPixmapWidth(pScreenPriv->pBankPixmap, width, devKind); \
+ SetPixmapData(pScreenPriv->pBankPixmap, pbits)
+
+#define SET_SINGLE_BANK(_pPix, _no) \
+ SetPixmapData(_pPix, (char *)pScreenPriv->BankInfo.pBankA + \
+ (*pScreenPriv->BankInfo.SetSourceAndDestinationBanks)(pScreen, (_no)) - \
+ (pScreenPriv->BankInfo.BankSize * (_no)))
+
+#define SET_SOURCE_BANK(_pPix, _no) \
+ SetPixmapData(_pPix, (char *)pScreenPriv->BankInfo.pBankA + \
+ (*pScreenPriv->BankInfo.SetSourceBank)(pScreen, (_no)) - \
+ (pScreenPriv->BankInfo.BankSize * (_no)))
+
+#define SET_DESTINATION_BANK(_pPix, _no) \
+ SetPixmapData(_pPix, (char *)pScreenPriv->BankInfo.pBankB + \
+ (*pScreenPriv->BankInfo.SetDestinationBank)(pScreen, (_no)) - \
+ (pScreenPriv->BankInfo.BankSize * (_no)))
+
+#define ALLOCATE_LOCAL_ARRAY(atype, ntype) \
+ (atype *)ALLOCATE_LOCAL((ntype) * sizeof(atype))
+
+static int miBankScreenIndex;
+static int miBankGCIndex;
+static unsigned long miBankGeneration = 0;
+static GCOps miBankGCOps;
+static GCFuncs miBankGCFuncs;
+
+#define BANK_SCRPRIVLVAL pScreen->devPrivates[miBankScreenIndex].ptr
+
+#define BANK_SCRPRIVATE ((miBankScreenPtr)(BANK_SCRPRIVLVAL))
+
+#define BANK_GCPRIVLVAL(pGC) (pGC)->devPrivates[miBankGCIndex].ptr
+
+#define BANK_GCPRIVATE(pGC) ((miBankGCPtr)(BANK_GCPRIVLVAL(pGC)))
+
+#define SCREEN_SAVE \
+ pointer pbits = GetPixmapData(pScreenPriv->pScreenPixmap)
+
+#define SCREEN_RESTORE \
+ SetPixmapData(pScreenPriv->pScreenPixmap, pbits)
+
+#define SCREEN_INIT \
+ miBankScreenPtr pScreenPriv = BANK_SCRPRIVATE
+
+#define SCREEN_UNWRAP(field) \
+ pScreen->field = pScreenPriv->field
+
+#define SCREEN_WRAP(field, wrapper) \
+ pScreenPriv->field = pScreen->field; \
+ pScreen->field = wrapper
+
+#define GC_INIT(pGC) \
+ miBankGCPtr pGCPriv = BANK_GCPRIVATE(pGC)
+
+#define GC_UNWRAP(pGC) \
+ (pGC)->ops = pGCPriv->wrappedOps; \
+ (pGC)->funcs = pGCPriv->wrappedFuncs
+
+#define GC_WRAP(pGC) \
+ pGCPriv->wrappedOps = (pGC)->ops; \
+ pGCPriv->wrappedFuncs = (pGC)->funcs; \
+ (pGC)->ops = &miBankGCOps; \
+ (pGC)->funcs = &miBankGCFuncs
+
+#define IS_BANKED(pDrawable) \
+ ((GetPixmapData(pScreenPriv->pScreenPixmap) == (pointer)pScreenPriv) && \
+ (((DrawablePtr)(pDrawable))->type == DRAWABLE_WINDOW))
+
+#define CLIP_SAVE \
+ RegionPtr pOrigCompositeClip = pGC->pCompositeClip
+
+#define CLIP_RESTORE \
+ pGC->pCompositeClip = pOrigCompositeClip
+
+#define GCOP_INIT \
+ ScreenPtr pScreen = pGC->pScreen; \
+ SCREEN_INIT; \
+ GC_INIT(pGC)
+
+#define GCOP_UNWRAP \
+ GC_UNWRAP(pGC)
+
+#define GCOP_WRAP \
+ GC_WRAP(pGC)
+
+#define GCOP_TOP_PART \
+ for (i = 0; i < pScreenPriv->nBanks; i++) \
+ { \
+ if (!(pGC->pCompositeClip = pGCPriv->pBankedClips[i])) \
+ continue; \
+ GCOP_UNWRAP; \
+ SET_SINGLE_BANK(pScreenPriv->pScreenPixmap, i)
+
+#define GCOP_BOTTOM_PART \
+ GCOP_WRAP; \
+ }
+
+#define GCOP_SIMPLE(statement) \
+ GCOP_INIT; \
+ SCREEN_SAVE; \
+ if (!IS_BANKED(pDrawable)) \
+ { \
+ GCOP_UNWRAP; \
+ statement; \
+ GCOP_WRAP; \
+ } \
+ else \
+ { \
+ int i; \
+ CLIP_SAVE; \
+ GCOP_TOP_PART; \
+ statement; \
+ GCOP_BOTTOM_PART; \
+ CLIP_RESTORE; \
+ } \
+ SCREEN_RESTORE
+
+/*********************
+ * Utility functions *
+ *********************/
+
+static int
+miBankOf(
+ miBankScreenPtr pScreenPriv,
+ int x,
+ int y
+)
+{
+ int iBank = ((x * (int)pScreenPriv->nBankBPP) +
+ (y * (long)pScreenPriv->nBitsPerScanline)) /
+ (long)pScreenPriv->nBitsPerBank;
+
+ if (iBank < 0)
+ iBank = 0;
+ else if (iBank >= pScreenPriv->nBanks)
+ iBank = pScreenPriv->nBanks - 1;
+
+ return iBank;
+}
+
+#define FirstBankOf(_x, _y) miBankOf(pScreenPriv, (_x), (_y))
+#define LastBankOf(_x, _y) miBankOf(pScreenPriv, (_x) - 1, (_y))
+
+/* Least common multiple */
+static unsigned int
+miLCM(
+ unsigned int x,
+ unsigned int y
+)
+{
+ unsigned int m = x, n = y, o;
+
+ while ((o = m % n))
+ {
+ m = n;
+ n = o;
+ }
+
+ return (x / n) * y;
+}
+
+/******************
+ * GCOps wrappers *
+ ******************/
+
+static void
+miBankFillSpans(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted
+)
+{
+ if (nInit > 0)
+ {
+ GCOP_SIMPLE((*pGC->ops->FillSpans)(pDrawable, pGC,
+ nInit, pptInit, pwidthInit, fSorted));
+ }
+}
+
+static void
+miBankSetSpans(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *psrc,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted
+)
+{
+ if (nspans > 0)
+ {
+ GCOP_SIMPLE((*pGC->ops->SetSpans)(pDrawable, pGC, psrc,
+ ppt, pwidth, nspans, fSorted));
+ }
+}
+
+static void
+miBankPutImage(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage
+)
+{
+ if ((w > 0) && (h > 0))
+ {
+ GCOP_INIT;
+ SCREEN_SAVE;
+
+ if (!IS_BANKED(pDrawable))
+ {
+ GCOP_UNWRAP;
+
+ (*pGC->ops->PutImage)(pDrawable, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+
+ GCOP_WRAP;
+ }
+ else
+ {
+ int i, j;
+
+ CLIP_SAVE;
+
+ i = FirstBankOf(x + pDrawable->x, y + pDrawable->y);
+ j = LastBankOf(x + pDrawable->x + w, y + pDrawable->y + h);
+ for (; i <= j; i++)
+ {
+ if (!(pGC->pCompositeClip = pGCPriv->pBankedClips[i]))
+ continue;
+
+ GCOP_UNWRAP;
+
+ SET_SINGLE_BANK(pScreenPriv->pScreenPixmap, i);
+
+ (*pGC->ops->PutImage)(pDrawable, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+
+ GCOP_WRAP;
+ }
+
+ CLIP_RESTORE;
+ }
+
+ SCREEN_RESTORE;
+ }
+}
+
+/*
+ * Here the CopyArea/CopyPlane wrappers. First off, we have to clip against
+ * the source in order to make the minimal number of copies in case of slow
+ * systems. Also the exposure handling is quite tricky. Special attention
+ * is to be given to the way the copies are sequenced. The list of boxes after
+ * the source clip is used to build a workqueue, that contains the atomic
+ * copies (i.e. only from one bank to one bank). Doing so produces a minimal
+ * list of things to do.
+ */
+static RegionPtr
+miBankCopyArea(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx,
+ int srcy,
+ int w,
+ int h,
+ int dstx,
+ int dsty
+)
+{
+ int cx1, cy1, cx2, cy2;
+ int ns, nd, nse, nde, dx, dy, xorg = 0, yorg = 0;
+ int maxWidth = 0, maxHeight = 0, paddedWidth = 0;
+ int nBox, nBoxClipSrc, nBoxClipDst, nQueue;
+ unsigned long planemask;
+ BoxPtr pBox, pBoxClipSrc, pBoxClipDst;
+ BoxRec fastBox, ccBox;
+ RegionPtr ret, prgnSrcClip = NULL;
+ RegionRec rgnDst;
+ char *pImage = NULL;
+ miBankQueue *pQueue, *pQueueNew, *Queue;
+ miBankQueue *pQueueTmp, *pQueueNext, *pQueueBase;
+ Bool fastBlit, fExpose, freeSrcClip, fastClip, fastExpose;
+
+ GCOP_INIT;
+ SCREEN_SAVE;
+
+ if (!IS_BANKED(pSrc) && !IS_BANKED(pDst))
+ {
+ GCOP_UNWRAP;
+
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst, pGC,
+ srcx, srcy, w, h, dstx, dsty);
+
+ GCOP_WRAP;
+ }
+ else if (!IS_BANKED(pDst))
+ {
+ fExpose = pGC->fExpose;
+ pGC->fExpose = FALSE;
+
+ xorg = pSrc->x;
+ yorg = pSrc->y;
+ dx = dstx - srcx;
+ dy = dsty - srcy;
+ srcx += xorg;
+ srcy += yorg;
+
+ ns = FirstBankOf(srcx, srcy);
+ nse = LastBankOf(srcx + w, srcy + h);
+ for (; ns <= nse; ns++)
+ {
+ if (!pScreenPriv->pBanks[ns])
+ continue;
+
+ nBox = REGION_NUM_RECTS(pScreenPriv->pBanks[ns]);
+ pBox = REGION_RECTS(pScreenPriv->pBanks[ns]);
+
+ for (; nBox--; pBox++)
+ {
+ cx1 = max(pBox->x1, srcx);
+ cy1 = max(pBox->y1, srcy);
+ cx2 = min(pBox->x2, srcx + w);
+ cy2 = min(pBox->y2, srcy + h);
+
+ if ((cx1 >= cx2) || (cy1 >= cy2))
+ continue;
+
+ GCOP_UNWRAP;
+
+ SET_SINGLE_BANK(pScreenPriv->pScreenPixmap, ns);
+
+ (*pGC->ops->CopyArea)(pSrc, pDst, pGC,
+ cx1 - xorg, cy1 - yorg,
+ cx2 - cx1, cy2 - cy1,
+ cx1 + dx - xorg, cy1 + dy - yorg);
+
+ GCOP_WRAP;
+ }
+ }
+
+ pGC->fExpose = fExpose;
+
+ if (fExpose)
+ ret = miHandleExposures(pSrc, pDst, pGC,
+ srcx - xorg, srcy - yorg, w, h, dstx, dsty, 0);
+ else
+ ret = NULL;
+ }
+ else if (!IS_BANKED(pSrc))
+ {
+ CLIP_SAVE;
+
+ if (pGC->miTranslate)
+ {
+ xorg = pDst->x;
+ yorg = pDst->y;
+ }
+ dx = srcx - dstx;
+ dy = srcy - dsty;
+ dstx += xorg;
+ dsty += yorg;
+
+ nd = FirstBankOf(dstx, dsty);
+ nde = LastBankOf(dstx + w, dsty + h);
+ for (; nd <= nde; nd++)
+ {
+ if (!(pGC->pCompositeClip = pGCPriv->pBankedClips[nd]))
+ continue;
+
+ /*
+ * It's faster to let the lower-level CopyArea do the clipping
+ * within each bank.
+ */
+ nBox = REGION_NUM_RECTS(pScreenPriv->pBanks[nd]);
+ pBox = REGION_RECTS(pScreenPriv->pBanks[nd]);
+
+ for (; nBox--; pBox++)
+ {
+ cx1 = max(pBox->x1, dstx);
+ cy1 = max(pBox->y1, dsty);
+ cx2 = min(pBox->x2, dstx + w);
+ cy2 = min(pBox->y2, dsty + h);
+
+ if ((cx1 >= cx2) || (cy1 >= cy2))
+ continue;
+
+ GCOP_UNWRAP;
+
+ SET_SINGLE_BANK(pScreenPriv->pScreenPixmap, nd);
+
+ (*pGC->ops->CopyArea)(pSrc, pDst, pGC,
+ cx1 + dx - xorg, cy1 + dy - yorg,
+ cx2 - cx1, cy2 - cy1,
+ cx1 - xorg, cy1 - yorg);
+
+ GCOP_WRAP;
+ }
+ }
+
+ CLIP_RESTORE;
+
+ ret = NULL;
+ }
+ else /* IS_BANKED(pSrc) && IS_BANKED(pDst) */
+ {
+ CLIP_SAVE;
+
+ fExpose = pGC->fExpose;
+
+ fastBox.x1 = srcx + pSrc->x;
+ fastBox.y1 = srcy + pSrc->y;
+ fastBox.x2 = fastBox.x1 + w;
+ fastBox.y2 = fastBox.y1 + h;
+
+ dx = dstx - fastBox.x1;
+ dy = dsty - fastBox.y1;
+ if (pGC->miTranslate)
+ {
+ xorg = pDst->x;
+ yorg = pDst->y;
+ }
+
+ /*
+ * Clip against the source. Otherwise we will blit too much for SINGLE
+ * and SHARED banked systems.
+ */
+ freeSrcClip = FALSE;
+ fastClip = FALSE;
+ fastExpose = FALSE;
+
+ if (pGC->subWindowMode != IncludeInferiors)
+ prgnSrcClip = &((WindowPtr)pSrc)->clipList;
+ else if (!((WindowPtr)pSrc)->parent)
+ fastClip = TRUE;
+ else if ((pSrc == pDst) && (pGC->clientClipType == CT_NONE))
+ prgnSrcClip = pGC->pCompositeClip;
+ else
+ {
+ prgnSrcClip = NotClippedByChildren((WindowPtr)pSrc);
+ freeSrcClip = TRUE;
+ }
+
+ if (fastClip)
+ {
+ fastExpose = TRUE;
+
+ /*
+ * Clip the source. If regions extend beyond the source size, make
+ * sure exposure events get sent.
+ */
+ if (fastBox.x1 < pSrc->x)
+ {
+ fastBox.x1 = pSrc->x;
+ fastExpose = FALSE;
+ }
+ if (fastBox.y1 < pSrc->y)
+ {
+ fastBox.y1 = pSrc->y;
+ fastExpose = FALSE;
+ }
+ if (fastBox.x2 > pSrc->x + (int) pSrc->width)
+ {
+ fastBox.x2 = pSrc->x + (int) pSrc->width;
+ fastExpose = FALSE;
+ }
+ if (fastBox.y2 > pSrc->y + (int) pSrc->height)
+ {
+ fastBox.y2 = pSrc->y + (int) pSrc->height;
+ fastExpose = FALSE;
+ }
+
+ nBox = 1;
+ pBox = &fastBox;
+ }
+ else
+ {
+ REGION_INIT(pScreen, &rgnDst, &fastBox, 1);
+ REGION_INTERSECT(pScreen, &rgnDst, &rgnDst, prgnSrcClip);
+ pBox = REGION_RECTS(&rgnDst);
+ nBox = REGION_NUM_RECTS(&rgnDst);
+ }
+
+ /*
+ * fastBlit can only be TRUE if we don't need to worry about attempts
+ * to read partial pixels through the destination bank.
+ */
+ fastBlit = FALSE;
+ planemask = (1 << pGC->depth) - 1;
+ if ((pScreenPriv->type == BANK_DOUBLE) ||
+ ((pScreenPriv->type == BANK_SHARED) &&
+ (pDst->depth == pScreen->rootDepth) &&
+ (pDst->depth == pGC->depth) &&
+ ((pGC->planemask & planemask) == planemask) &&
+ ((pGC->alu == GXclear) || (pGC->alu == GXcopy) ||
+ (pGC->alu == GXcopyInverted) || (pGC->alu == GXset))))
+ fastBlit = TRUE;
+
+ nQueue = nBox * pScreenPriv->maxRects * 2;
+ pQueue = Queue = ALLOCATE_LOCAL_ARRAY(miBankQueue, nQueue);
+
+ if (Queue)
+ {
+ for (; nBox--; pBox++)
+ {
+ ns = FirstBankOf(pBox->x1, pBox->y1);
+ nse = LastBankOf(pBox->x2, pBox->y2);
+ for (; ns <= nse; ns++)
+ {
+ if (!pScreenPriv->pBanks[ns])
+ continue;
+
+ nBoxClipSrc = REGION_NUM_RECTS(pScreenPriv->pBanks[ns]);
+ pBoxClipSrc = REGION_RECTS(pScreenPriv->pBanks[ns]);
+
+ for (; nBoxClipSrc--; pBoxClipSrc++)
+ {
+ cx1 = max(pBox->x1, pBoxClipSrc->x1);
+ cy1 = max(pBox->y1, pBoxClipSrc->y1);
+ cx2 = min(pBox->x2, pBoxClipSrc->x2);
+ cy2 = min(pBox->y2, pBoxClipSrc->y2);
+
+ /* Check to see if the region is empty */
+ if ((cx1 >= cx2) || (cy1 >= cy2))
+ continue;
+
+ /* Translate c[xy]* to destination coordinates */
+ cx1 += dx + xorg;
+ cy1 += dy + yorg;
+ cx2 += dx + xorg;
+ cy2 += dy + yorg;
+
+ nd = FirstBankOf(cx1, cy1);
+ nde = LastBankOf(cx2, cy2);
+ for (; nd <= nde; nd++)
+ {
+ if (!pGCPriv->pBankedClips[nd])
+ continue;
+
+ /*
+ * Clients can send quite large clip descriptions,
+ * so use the bank clips here instead.
+ */
+ nBoxClipDst =
+ REGION_NUM_RECTS(pScreenPriv->pBanks[nd]);
+ pBoxClipDst =
+ REGION_RECTS(pScreenPriv->pBanks[nd]);
+
+ for (; nBoxClipDst--; pBoxClipDst++)
+ {
+ ccBox.x1 = max(cx1, pBoxClipDst->x1);
+ ccBox.y1 = max(cy1, pBoxClipDst->y1);
+ ccBox.x2 = min(cx2, pBoxClipDst->x2);
+ ccBox.y2 = min(cy2, pBoxClipDst->y2);
+
+ /* Check to see if the region is empty */
+ if ((ccBox.x1 >= ccBox.x2) ||
+ (ccBox.y1 >= ccBox.y2))
+ continue;
+
+ pQueue->srcBankNo = ns;
+ pQueue->dstBankNo = nd;
+ pQueue->x = ccBox.x1 - xorg;
+ pQueue->y = ccBox.y1 - yorg;
+ pQueue->w = ccBox.x2 - ccBox.x1;
+ pQueue->h = ccBox.y2 - ccBox.y1;
+
+ if (maxWidth < pQueue->w)
+ maxWidth = pQueue->w;
+ if (maxHeight < pQueue->h)
+ maxHeight = pQueue->h;
+
+ /*
+ * When shared banking is used and the source
+ * and destination banks differ, prevent
+ * attempts to fetch partial scanline pad units
+ * through the destination bank.
+ */
+ pQueue->fastBlit = fastBlit;
+ if (fastBlit &&
+ (pScreenPriv->type == BANK_SHARED) &&
+ (ns != nd) &&
+ ((ccBox.x1 %
+ pScreenPriv->nPixelsPerScanlinePadUnit) ||
+ (ccBox.x2 %
+ pScreenPriv->nPixelsPerScanlinePadUnit) ||
+ (RECT_IN_REGION(pScreen,
+ pGCPriv->pBankedClips[nd], &ccBox) !=
+ rgnIN)))
+ pQueue->fastBlit = FALSE;
+ pQueue++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!fastClip)
+ {
+ REGION_UNINIT(pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pScreen, prgnSrcClip);
+ }
+
+ pQueueNew = pQueue;
+ nQueue = pQueue - Queue;
+
+ if (nQueue > 0)
+ {
+ pQueue = Queue;
+
+ if ((nQueue > 1) &&
+ ((pSrc == pDst) || (pGC->subWindowMode == IncludeInferiors)))
+ {
+ if ((srcy + pSrc->y) < (dsty + yorg))
+ {
+ /* Sort from bottom to top */
+ pQueueBase = pQueueNext = pQueue + nQueue - 1;
+
+ while (pQueueBase >= pQueue)
+ {
+ while ((pQueueNext >= pQueue) &&
+ (pQueueBase->y == pQueueNext->y))
+ pQueueNext--;
+
+ pQueueTmp = pQueueNext + 1;
+ while (pQueueTmp <= pQueueBase)
+ *pQueueNew++ = *pQueueTmp++;
+
+ pQueueBase = pQueueNext;
+ }
+
+ pQueueNew -= nQueue;
+ pQueue = pQueueNew;
+ pQueueNew = Queue;
+ }
+
+ if ((srcx + pSrc->x) < (dstx + xorg))
+ {
+ /* Sort from right to left */
+ pQueueBase = pQueueNext = pQueue;
+
+ while (pQueueBase < pQueue + nQueue)
+ {
+ while ((pQueueNext < pQueue + nQueue) &&
+ (pQueueNext->y == pQueueBase->y))
+ pQueueNext++;
+
+ pQueueTmp = pQueueNext;
+ while (pQueueTmp != pQueueBase)
+ *pQueueNew++ = *--pQueueTmp;
+
+ pQueueBase = pQueueNext;
+ }
+
+ pQueueNew -= nQueue;
+ pQueue = pQueueNew;
+ }
+ }
+
+ paddedWidth = PixmapBytePad(maxWidth,
+ pScreenPriv->pScreenPixmap->drawable.depth);
+ pImage = (char *)ALLOCATE_LOCAL(paddedWidth * maxHeight);
+
+ pGC->fExpose = FALSE;
+
+ while (nQueue--)
+ {
+ pGC->pCompositeClip = pGCPriv->pBankedClips[pQueue->dstBankNo];
+
+ GCOP_UNWRAP;
+
+ if (pQueue->srcBankNo == pQueue->dstBankNo)
+ {
+ SET_SINGLE_BANK(pScreenPriv->pScreenPixmap,
+ pQueue->srcBankNo);
+
+ (*pGC->ops->CopyArea)(pSrc, pDst, pGC,
+ pQueue->x - dx - pSrc->x, pQueue->y - dy - pSrc->y,
+ pQueue->w, pQueue->h,
+ pQueue->x, pQueue->y);
+ }
+ else if (pQueue->fastBlit)
+ {
+ SetPixmapWidth(pScreenPriv->pBankPixmap,
+ pScreenPriv->pScreenPixmap->drawable.width,
+ pScreenPriv->pScreenPixmap->devKind);
+
+ SET_SOURCE_BANK (pScreenPriv->pBankPixmap,
+ pQueue->srcBankNo);
+ SET_DESTINATION_BANK(pScreenPriv->pScreenPixmap,
+ pQueue->dstBankNo);
+
+ (*pGC->ops->CopyArea)(
+ (DrawablePtr)pScreenPriv->pBankPixmap,
+ pDst, pGC,
+ pQueue->x - dx, pQueue->y - dy,
+ pQueue->w, pQueue->h,
+ pQueue->x, pQueue->y);
+ }
+ else if (pImage)
+ {
+ SetPixmapWidth(pScreenPriv->pBankPixmap,
+ maxWidth, paddedWidth);
+ SetPixmapData(pScreenPriv->pBankPixmap, pImage);
+
+ SET_SINGLE_BANK(pScreenPriv->pScreenPixmap,
+ pQueue->srcBankNo);
+
+ (*pScreenPriv->pBankGC->ops->CopyArea)(
+ pSrc, (DrawablePtr)pScreenPriv->pBankPixmap,
+ pScreenPriv->pBankGC,
+ pQueue->x - dx - pSrc->x, pQueue->y - dy - pSrc->y,
+ pQueue->w, pQueue->h, 0, 0);
+
+ SET_SINGLE_BANK(pScreenPriv->pScreenPixmap,
+ pQueue->dstBankNo);
+
+ (*pGC->ops->CopyArea)(
+ (DrawablePtr)pScreenPriv->pBankPixmap,
+ pDst, pGC,
+ 0, 0, pQueue->w, pQueue->h, pQueue->x, pQueue->y);
+ }
+
+ GCOP_WRAP;
+
+ pQueue++;
+ }
+
+ if (pImage)
+ DEALLOCATE_LOCAL(pImage);
+ }
+
+ CLIP_RESTORE;
+
+ pGC->fExpose = fExpose;
+
+ if (Queue)
+ DEALLOCATE_LOCAL(Queue);
+
+ if (fExpose && !fastExpose)
+ ret = miHandleExposures(pSrc, pDst, pGC,
+ srcx, srcy, w, h, dstx, dsty, 0);
+ else
+ ret = NULL;
+ }
+
+ SCREEN_RESTORE;
+
+ return ret;
+}
+
+static RegionPtr
+miBankCopyPlane(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx,
+ int srcy,
+ int w,
+ int h,
+ int dstx,
+ int dsty,
+ unsigned long plane
+)
+{
+ int cx1, cy1, cx2, cy2;
+ int ns, nd, nse, nde, dx, dy, xorg = 0, yorg = 0;
+ int maxWidth = 0, maxHeight = 0, paddedWidth = 0;
+ int nBox, nBoxClipSrc, nBoxClipDst, nQueue;
+ BoxPtr pBox, pBoxClipSrc, pBoxClipDst;
+ BoxRec fastBox, ccBox;
+ RegionPtr ret, prgnSrcClip = NULL;
+ RegionRec rgnDst;
+ char *pImage = NULL;
+ miBankQueue *pQueue, *pQueueNew, *Queue;
+ miBankQueue *pQueueTmp, *pQueueNext, *pQueueBase;
+ Bool fastBlit, fExpose, freeSrcClip, fastClip, fastExpose;
+
+ GCOP_INIT;
+ SCREEN_SAVE;
+
+ if (!IS_BANKED(pSrc) && !IS_BANKED(pDst))
+ {
+ GCOP_UNWRAP;
+
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC,
+ srcx, srcy, w, h, dstx, dsty, plane);
+
+ GCOP_WRAP;
+ }
+ else if (!IS_BANKED(pDst))
+ {
+ fExpose = pGC->fExpose;
+ pGC->fExpose = FALSE;
+
+ xorg = pSrc->x;
+ yorg = pSrc->y;
+ dx = dstx - srcx;
+ dy = dsty - srcy;
+ srcx += xorg;
+ srcy += yorg;
+
+ ns = FirstBankOf(srcx, srcy);
+ nse = LastBankOf(srcx + w, srcy + h);
+ for (; ns <= nse; ns++)
+ {
+ if (!pScreenPriv->pBanks[ns])
+ continue;
+
+ nBox = REGION_NUM_RECTS(pScreenPriv->pBanks[ns]);
+ pBox = REGION_RECTS(pScreenPriv->pBanks[ns]);
+
+ for (; nBox--; pBox++)
+ {
+ cx1 = max(pBox->x1, srcx);
+ cy1 = max(pBox->y1, srcy);
+ cx2 = min(pBox->x2, srcx + w);
+ cy2 = min(pBox->y2, srcy + h);
+
+ if ((cx1 >= cx2) || (cy1 >= cy2))
+ continue;
+
+ GCOP_UNWRAP;
+
+ SET_SINGLE_BANK(pScreenPriv->pScreenPixmap, ns);
+
+ (*pGC->ops->CopyPlane)(pSrc, pDst, pGC,
+ cx1 - xorg, cy1 - yorg,
+ cx2 - cx1, cy2 - cy1,
+ cx1 + dx - xorg, cy1 + dy - yorg, plane);
+
+ GCOP_WRAP;
+ }
+ }
+
+ pGC->fExpose = fExpose;
+
+ if (fExpose)
+ ret = miHandleExposures(pSrc, pDst, pGC,
+ srcx - xorg, srcy - yorg, w, h, dstx, dsty, 0);
+ else
+ ret = NULL;
+ }
+ else if (!IS_BANKED(pSrc))
+ {
+ CLIP_SAVE;
+
+ if (pGC->miTranslate)
+ {
+ xorg = pDst->x;
+ yorg = pDst->y;
+ }
+ dx = srcx - dstx;
+ dy = srcy - dsty;
+ dstx += xorg;
+ dsty += yorg;
+
+ nd = FirstBankOf(dstx, dsty);
+ nde = LastBankOf(dstx + w, dsty + h);
+ for (; nd <= nde; nd++)
+ {
+ if (!(pGC->pCompositeClip = pGCPriv->pBankedClips[nd]))
+ continue;
+
+ /*
+ * It's faster to let the lower-level CopyArea do the clipping
+ * within each bank.
+ */
+ nBox = REGION_NUM_RECTS(pScreenPriv->pBanks[nd]);
+ pBox = REGION_RECTS(pScreenPriv->pBanks[nd]);
+
+ for (; nBox--; pBox++)
+ {
+ cx1 = max(pBox->x1, dstx);
+ cy1 = max(pBox->y1, dsty);
+ cx2 = min(pBox->x2, dstx + w);
+ cy2 = min(pBox->y2, dsty + h);
+
+ if ((cx1 >= cx2) || (cy1 >= cy2))
+ continue;
+
+ GCOP_UNWRAP;
+
+ SET_SINGLE_BANK(pScreenPriv->pScreenPixmap, nd);
+
+ (*pGC->ops->CopyPlane)(pSrc, pDst, pGC,
+ cx1 + dx - xorg, cy1 + dy - yorg,
+ cx2 - cx1, cy2 - cy1,
+ cx1 - xorg, cy1 - yorg, plane);
+
+ GCOP_WRAP;
+ }
+ }
+
+ CLIP_RESTORE;
+
+ ret = NULL;
+ }
+ else /* IS_BANKED(pSrc) && IS_BANKED(pDst) */
+ {
+ CLIP_SAVE;
+
+ fExpose = pGC->fExpose;
+
+ fastBox.x1 = srcx + pSrc->x;
+ fastBox.y1 = srcy + pSrc->y;
+ fastBox.x2 = fastBox.x1 + w;
+ fastBox.y2 = fastBox.y1 + h;
+
+ dx = dstx - fastBox.x1;
+ dy = dsty - fastBox.y1;
+ if (pGC->miTranslate)
+ {
+ xorg = pDst->x;
+ yorg = pDst->y;
+ }
+
+ /*
+ * Clip against the source. Otherwise we will blit too much for SINGLE
+ * and SHARED banked systems.
+ */
+ freeSrcClip = FALSE;
+ fastClip = FALSE;
+ fastExpose = FALSE;
+
+ if (pGC->subWindowMode != IncludeInferiors)
+ prgnSrcClip = &((WindowPtr)pSrc)->clipList;
+ else if (!((WindowPtr)pSrc)->parent)
+ fastClip = TRUE;
+ else if ((pSrc == pDst) && (pGC->clientClipType == CT_NONE))
+ prgnSrcClip = pGC->pCompositeClip;
+ else
+ {
+ prgnSrcClip = NotClippedByChildren((WindowPtr)pSrc);
+ freeSrcClip = TRUE;
+ }
+
+ if (fastClip)
+ {
+ fastExpose = TRUE;
+
+ /*
+ * Clip the source. If regions extend beyond the source size, make
+ * sure exposure events get sent.
+ */
+ if (fastBox.x1 < pSrc->x)
+ {
+ fastBox.x1 = pSrc->x;
+ fastExpose = FALSE;
+ }
+ if (fastBox.y1 < pSrc->y)
+ {
+ fastBox.y1 = pSrc->y;
+ fastExpose = FALSE;
+ }
+ if (fastBox.x2 > pSrc->x + (int) pSrc->width)
+ {
+ fastBox.x2 = pSrc->x + (int) pSrc->width;
+ fastExpose = FALSE;
+ }
+ if (fastBox.y2 > pSrc->y + (int) pSrc->height)
+ {
+ fastBox.y2 = pSrc->y + (int) pSrc->height;
+ fastExpose = FALSE;
+ }
+
+ nBox = 1;
+ pBox = &fastBox;
+ }
+ else
+ {
+ REGION_INIT(pScreen, &rgnDst, &fastBox, 1);
+ REGION_INTERSECT(pScreen, &rgnDst, &rgnDst, prgnSrcClip);
+ pBox = REGION_RECTS(&rgnDst);
+ nBox = REGION_NUM_RECTS(&rgnDst);
+ }
+
+ /*
+ * fastBlit can only be TRUE if we don't need to worry about attempts
+ * to read partial pixels through the destination bank.
+ */
+ fastBlit = FALSE;
+ if ((pScreenPriv->type == BANK_DOUBLE) ||
+ ((pScreenPriv->type == BANK_SHARED) &&
+ (pScreen->rootDepth == 1) &&
+ ((pGC->alu == GXclear) || (pGC->alu == GXcopy) ||
+ (pGC->alu == GXcopyInverted) || (pGC->alu == GXset))))
+ fastBlit = TRUE;
+
+ nQueue = nBox * pScreenPriv->maxRects * 2;
+ pQueue = Queue = ALLOCATE_LOCAL_ARRAY(miBankQueue, nQueue);
+
+ if (Queue)
+ {
+ for (; nBox--; pBox++)
+ {
+ ns = FirstBankOf(pBox->x1, pBox->y1);
+ nse = LastBankOf(pBox->x2, pBox->y2);
+ for (; ns <= nse; ns++)
+ {
+ if (!pScreenPriv->pBanks[ns])
+ continue;
+
+ nBoxClipSrc = REGION_NUM_RECTS(pScreenPriv->pBanks[ns]);
+ pBoxClipSrc = REGION_RECTS(pScreenPriv->pBanks[ns]);
+
+ for (; nBoxClipSrc--; pBoxClipSrc++)
+ {
+ cx1 = max(pBox->x1, pBoxClipSrc->x1);
+ cy1 = max(pBox->y1, pBoxClipSrc->y1);
+ cx2 = min(pBox->x2, pBoxClipSrc->x2);
+ cy2 = min(pBox->y2, pBoxClipSrc->y2);
+
+ /* Check to see if the region is empty */
+ if ((cx1 >= cx2) || (cy1 >= cy2))
+ continue;
+
+ /* Translate c[xy]* to destination coordinates */
+ cx1 += dx + xorg;
+ cy1 += dy + yorg;
+ cx2 += dx + xorg;
+ cy2 += dy + yorg;
+
+ nd = FirstBankOf(cx1, cy1);
+ nde = LastBankOf(cx2, cy2);
+ for (; nd <= nde; nd++)
+ {
+ if (!pGCPriv->pBankedClips[nd])
+ continue;
+
+ /*
+ * Clients can send quite large clip descriptions,
+ * so use the bank clips here instead.
+ */
+ nBoxClipDst =
+ REGION_NUM_RECTS(pScreenPriv->pBanks[nd]);
+ pBoxClipDst =
+ REGION_RECTS(pScreenPriv->pBanks[nd]);
+
+ for (; nBoxClipDst--; pBoxClipDst++)
+ {
+ ccBox.x1 = max(cx1, pBoxClipDst->x1);
+ ccBox.y1 = max(cy1, pBoxClipDst->y1);
+ ccBox.x2 = min(cx2, pBoxClipDst->x2);
+ ccBox.y2 = min(cy2, pBoxClipDst->y2);
+
+ /* Check to see if the region is empty */
+ if ((ccBox.x1 >= ccBox.x2) ||
+ (ccBox.y1 >= ccBox.y2))
+ continue;
+
+ pQueue->srcBankNo = ns;
+ pQueue->dstBankNo = nd;
+ pQueue->x = ccBox.x1 - xorg;
+ pQueue->y = ccBox.y1 - yorg;
+ pQueue->w = ccBox.x2 - ccBox.x1;
+ pQueue->h = ccBox.y2 - ccBox.y1;
+
+ if (maxWidth < pQueue->w)
+ maxWidth = pQueue->w;
+ if (maxHeight < pQueue->h)
+ maxHeight = pQueue->h;
+
+ /*
+ * When shared banking is used and the source
+ * and destination banks differ, prevent
+ * attempts to fetch partial scanline pad units
+ * through the destination bank.
+ */
+ pQueue->fastBlit = fastBlit;
+ if (fastBlit &&
+ (pScreenPriv->type == BANK_SHARED) &&
+ (ns != nd) &&
+ ((ccBox.x1 %
+ pScreenPriv->nPixelsPerScanlinePadUnit) ||
+ (ccBox.x2 %
+ pScreenPriv->nPixelsPerScanlinePadUnit) ||
+ (RECT_IN_REGION(pScreen,
+ pGCPriv->pBankedClips[nd], &ccBox) !=
+ rgnIN)))
+ pQueue->fastBlit = FALSE;
+ pQueue++;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (!fastClip)
+ {
+ REGION_UNINIT(pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pScreen, prgnSrcClip);
+ }
+
+ pQueueNew = pQueue;
+ nQueue = pQueue - Queue;
+
+ if (nQueue > 0)
+ {
+ pQueue = Queue;
+
+ if ((nQueue > 1) &&
+ ((pSrc == pDst) || (pGC->subWindowMode == IncludeInferiors)))
+ {
+ if ((srcy + pSrc->y) < (dsty + yorg))
+ {
+ /* Sort from bottom to top */
+ pQueueBase = pQueueNext = pQueue + nQueue - 1;
+
+ while (pQueueBase >= pQueue)
+ {
+ while ((pQueueNext >= pQueue) &&
+ (pQueueBase->y == pQueueNext->y))
+ pQueueNext--;
+
+ pQueueTmp = pQueueNext + 1;
+ while (pQueueTmp <= pQueueBase)
+ *pQueueNew++ = *pQueueTmp++;
+
+ pQueueBase = pQueueNext;
+ }
+
+ pQueueNew -= nQueue;
+ pQueue = pQueueNew;
+ pQueueNew = Queue;
+ }
+
+ if ((srcx + pSrc->x) < (dstx + xorg))
+ {
+ /* Sort from right to left */
+ pQueueBase = pQueueNext = pQueue;
+
+ while (pQueueBase < pQueue + nQueue)
+ {
+ while ((pQueueNext < pQueue + nQueue) &&
+ (pQueueNext->y == pQueueBase->y))
+ pQueueNext++;
+
+ pQueueTmp = pQueueNext;
+ while (pQueueTmp != pQueueBase)
+ *pQueueNew++ = *--pQueueTmp;
+
+ pQueueBase = pQueueNext;
+ }
+
+ pQueueNew -= nQueue;
+ pQueue = pQueueNew;
+ }
+ }
+
+ paddedWidth = PixmapBytePad(maxWidth,
+ pScreenPriv->pScreenPixmap->drawable.depth);
+ pImage = (char *)ALLOCATE_LOCAL(paddedWidth * maxHeight);
+
+ pGC->fExpose = FALSE;
+
+ while (nQueue--)
+ {
+ pGC->pCompositeClip = pGCPriv->pBankedClips[pQueue->dstBankNo];
+
+ GCOP_UNWRAP;
+
+ if (pQueue->srcBankNo == pQueue->dstBankNo)
+ {
+ SET_SINGLE_BANK(pScreenPriv->pScreenPixmap,
+ pQueue->srcBankNo);
+
+ (*pGC->ops->CopyPlane)(pSrc, pDst, pGC,
+ pQueue->x - dx - pSrc->x, pQueue->y - dy - pSrc->y,
+ pQueue->w, pQueue->h, pQueue->x, pQueue->y, plane);
+ }
+ else if (pQueue->fastBlit)
+ {
+ SetPixmapWidth(pScreenPriv->pBankPixmap,
+ pScreenPriv->pScreenPixmap->drawable.width,
+ pScreenPriv->pScreenPixmap->devKind);
+
+ SET_SOURCE_BANK (pScreenPriv->pBankPixmap,
+ pQueue->srcBankNo);
+ SET_DESTINATION_BANK(pScreenPriv->pScreenPixmap,
+ pQueue->dstBankNo);
+
+ (*pGC->ops->CopyPlane)(
+ (DrawablePtr)pScreenPriv->pBankPixmap,
+ pDst, pGC,
+ pQueue->x - dx, pQueue->y - dy,
+ pQueue->w, pQueue->h, pQueue->x, pQueue->y, plane);
+ }
+ else if (pImage)
+ {
+ SetPixmapWidth(pScreenPriv->pBankPixmap,
+ maxWidth, paddedWidth);
+ SetPixmapData(pScreenPriv->pBankPixmap, pImage);
+
+ SET_SINGLE_BANK(pScreenPriv->pScreenPixmap,
+ pQueue->srcBankNo);
+
+ (*pScreenPriv->pBankGC->ops->CopyArea)(
+ pSrc, (DrawablePtr)pScreenPriv->pBankPixmap,
+ pScreenPriv->pBankGC,
+ pQueue->x - dx - pSrc->x, pQueue->y - dy - pSrc->y,
+ pQueue->w, pQueue->h, 0, 0);
+
+ SET_SINGLE_BANK(pScreenPriv->pScreenPixmap,
+ pQueue->dstBankNo);
+
+ (*pGC->ops->CopyPlane)(
+ (DrawablePtr)pScreenPriv->pBankPixmap,
+ pDst, pGC, 0, 0, pQueue->w, pQueue->h,
+ pQueue->x, pQueue->y, plane);
+ }
+
+ GCOP_WRAP;
+
+ pQueue++;
+ }
+
+ if (pImage)
+ DEALLOCATE_LOCAL(pImage);
+ }
+
+ CLIP_RESTORE;
+
+ pGC->fExpose = fExpose;
+
+ if (Queue)
+ DEALLOCATE_LOCAL(Queue);
+
+ if (fExpose && !fastExpose)
+ ret = miHandleExposures(pSrc, pDst, pGC,
+ srcx, srcy, w, h, dstx, dsty, 0);
+ else
+ ret = NULL;
+ }
+
+ SCREEN_RESTORE;
+
+ return ret;
+}
+
+static void
+miBankPolyPoint(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit
+)
+{
+ if (npt > 0)
+ {
+ GCOP_INIT;
+ SCREEN_SAVE;
+
+ if (!IS_BANKED(pDrawable))
+ {
+ GCOP_UNWRAP;
+
+ (*pGC->ops->PolyPoint)(pDrawable, pGC, mode, npt, pptInit);
+
+ GCOP_WRAP;
+ }
+ else
+ {
+ xPoint *ppt;
+ int i;
+
+ CLIP_SAVE;
+
+ if (!(ppt = ALLOCATE_LOCAL_ARRAY(xPoint, npt)))
+ ppt = pptInit;
+
+ GCOP_TOP_PART;
+
+ if (ppt != pptInit)
+ memcpy(ppt, pptInit, npt * sizeof(xPoint));
+
+ (*pGC->ops->PolyPoint)(pDrawable, pGC, mode, npt, ppt);
+
+ GCOP_BOTTOM_PART;
+
+ if (ppt != pptInit)
+ DEALLOCATE_LOCAL(ppt);
+
+ CLIP_RESTORE;
+ }
+
+ SCREEN_RESTORE;
+ }
+}
+
+static void
+miBankPolylines(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit
+)
+{
+ if (npt > 0)
+ {
+ GCOP_INIT;
+ SCREEN_SAVE;
+
+ if (!IS_BANKED(pDrawable))
+ {
+ GCOP_UNWRAP;
+
+ (*pGC->ops->Polylines)(pDrawable, pGC, mode, npt, pptInit);
+
+ GCOP_WRAP;
+ }
+ else
+ {
+ DDXPointPtr ppt;
+ int i;
+
+ CLIP_SAVE;
+
+ if (!(ppt = ALLOCATE_LOCAL_ARRAY(DDXPointRec, npt)))
+ ppt = pptInit;
+
+ GCOP_TOP_PART;
+
+ if (ppt != pptInit)
+ memcpy(ppt, pptInit, npt * sizeof(DDXPointRec));
+
+ (*pGC->ops->Polylines)(pDrawable, pGC, mode, npt, ppt);
+
+ GCOP_BOTTOM_PART;
+
+ if (ppt != pptInit)
+ DEALLOCATE_LOCAL(ppt);
+
+ CLIP_RESTORE;
+ }
+
+ SCREEN_RESTORE;
+ }
+}
+
+static void
+miBankPolySegment(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *psegInit
+)
+{
+ if (nseg > 0)
+ {
+ GCOP_INIT;
+ SCREEN_SAVE;
+
+ if (!IS_BANKED(pDrawable))
+ {
+ GCOP_UNWRAP;
+
+ (*pGC->ops->PolySegment)(pDrawable, pGC, nseg, psegInit);
+
+ GCOP_WRAP;
+ }
+ else
+ {
+ xSegment *pseg;
+ int i;
+
+ CLIP_SAVE;
+
+ if (!(pseg = ALLOCATE_LOCAL_ARRAY(xSegment, nseg)))
+ pseg = psegInit;
+
+ GCOP_TOP_PART;
+
+ if (pseg != psegInit)
+ memcpy(pseg, psegInit, nseg * sizeof(xSegment));
+
+ (*pGC->ops->PolySegment)(pDrawable, pGC, nseg, pseg);
+
+ GCOP_BOTTOM_PART;
+
+ if (pseg != psegInit)
+ DEALLOCATE_LOCAL(pseg);
+
+ CLIP_RESTORE;
+ }
+
+ SCREEN_RESTORE;
+ }
+}
+
+static void
+miBankPolyRectangle(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nrect,
+ xRectangle *prectInit
+)
+{
+ if (nrect > 0)
+ {
+ GCOP_INIT;
+ SCREEN_SAVE;
+
+ if (!IS_BANKED(pDrawable))
+ {
+ GCOP_UNWRAP;
+
+ (*pGC->ops->PolyRectangle)(pDrawable, pGC, nrect, prectInit);
+
+ GCOP_WRAP;
+ }
+ else
+ {
+ xRectangle *prect;
+ int i;
+
+ CLIP_SAVE;
+
+ if (!(prect = ALLOCATE_LOCAL_ARRAY(xRectangle, nrect)))
+ prect = prectInit;
+
+ GCOP_TOP_PART;
+
+ if (prect != prectInit)
+ memcpy(prect, prectInit, nrect * sizeof(xRectangle));
+
+ (*pGC->ops->PolyRectangle)(pDrawable, pGC, nrect, prect);
+
+ GCOP_BOTTOM_PART;
+
+ if (prect != prectInit)
+ DEALLOCATE_LOCAL(prect);
+
+ CLIP_RESTORE;
+ }
+
+ SCREEN_RESTORE;
+ }
+}
+
+static void
+miBankPolyArc(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int narc,
+ xArc *parcInit
+)
+{
+ if (narc > 0)
+ {
+ GCOP_INIT;
+ SCREEN_SAVE;
+
+ if (!IS_BANKED(pDrawable))
+ {
+ GCOP_UNWRAP;
+
+ (*pGC->ops->PolyArc)(pDrawable, pGC, narc, parcInit);
+
+ GCOP_WRAP;
+ }
+ else
+ {
+ xArc *parc;
+ int i;
+
+ CLIP_SAVE;
+
+ if (!(parc = ALLOCATE_LOCAL_ARRAY(xArc, narc)))
+ parc = parcInit;
+
+ GCOP_TOP_PART;
+
+ if (parc != parcInit)
+ memcpy(parc, parcInit, narc * sizeof(xArc));
+
+ (*pGC->ops->PolyArc)(pDrawable, pGC, narc, parc);
+
+ GCOP_BOTTOM_PART;
+
+ if (parc != parcInit)
+ DEALLOCATE_LOCAL(parc);
+
+ CLIP_RESTORE;
+ }
+
+ SCREEN_RESTORE;
+ }
+}
+
+static void
+miBankFillPolygon(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int npt,
+ DDXPointRec *pptInit
+)
+{
+ if (npt > 0)
+ {
+ GCOP_INIT;
+ SCREEN_SAVE;
+
+ if (!IS_BANKED(pDrawable))
+ {
+ GCOP_UNWRAP;
+
+ (*pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, npt, pptInit);
+
+ GCOP_WRAP;
+ }
+ else
+ {
+ DDXPointRec *ppt;
+ int i;
+
+ CLIP_SAVE;
+
+ if (!(ppt = ALLOCATE_LOCAL_ARRAY(DDXPointRec, npt)))
+ ppt = pptInit;
+
+ GCOP_TOP_PART;
+
+ if (ppt != pptInit)
+ memcpy(ppt, pptInit, npt * sizeof(DDXPointRec));
+
+ (*pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, npt, ppt);
+
+ GCOP_BOTTOM_PART;
+
+ if (ppt != pptInit)
+ DEALLOCATE_LOCAL(ppt);
+
+ CLIP_RESTORE;
+ }
+
+ SCREEN_RESTORE;
+ }
+}
+
+static void
+miBankPolyFillRect(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+)
+{
+ if (nrectFill > 0)
+ {
+ GCOP_INIT;
+ SCREEN_SAVE;
+
+ if (!IS_BANKED(pDrawable))
+ {
+ GCOP_UNWRAP;
+
+ (*pGC->ops->PolyFillRect)(pDrawable, pGC, nrectFill, prectInit);
+
+ GCOP_WRAP;
+ }
+ else
+ {
+ xRectangle *prect;
+ int i;
+
+ CLIP_SAVE;
+
+ if (!(prect = ALLOCATE_LOCAL_ARRAY(xRectangle, nrectFill)))
+ prect = prectInit;
+
+ GCOP_TOP_PART;
+
+ if (prect != prectInit)
+ memcpy(prect, prectInit, nrectFill * sizeof(xRectangle));
+
+ (*pGC->ops->PolyFillRect)(pDrawable, pGC, nrectFill, prect);
+
+ GCOP_BOTTOM_PART;
+
+ if (prect != prectInit)
+ DEALLOCATE_LOCAL(prect);
+
+ CLIP_RESTORE;
+ }
+
+ SCREEN_RESTORE;
+ }
+}
+
+static void
+miBankPolyFillArc(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int narc,
+ xArc *parcInit
+)
+{
+ if (narc > 0)
+ {
+ GCOP_INIT;
+ SCREEN_SAVE;
+
+ if (!IS_BANKED(pDrawable))
+ {
+ GCOP_UNWRAP;
+
+ (*pGC->ops->PolyFillArc)(pDrawable, pGC, narc, parcInit);
+
+ GCOP_WRAP;
+ }
+ else
+ {
+ xArc *parc;
+ int i;
+
+ CLIP_SAVE;
+
+ if (!(parc = ALLOCATE_LOCAL_ARRAY(xArc, narc)))
+ parc = parcInit;
+
+ GCOP_TOP_PART;
+
+ if (parc != parcInit)
+ memcpy(parc, parcInit, narc * sizeof(xArc));
+
+ (*pGC->ops->PolyFillArc)(pDrawable, pGC, narc, parc);
+
+ GCOP_BOTTOM_PART;
+
+ if (parc != parcInit)
+ DEALLOCATE_LOCAL(parc);
+
+ CLIP_RESTORE;
+ }
+
+ SCREEN_RESTORE;
+ }
+}
+
+static int
+miBankPolyText8(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int nchar,
+ char *pchar
+)
+{
+ int retval = x;
+
+ if (nchar > 0)
+ {
+ GCOP_INIT;
+ SCREEN_SAVE;
+
+ if (!IS_BANKED(pDrawable))
+ {
+ GCOP_UNWRAP;
+
+ retval = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, nchar, pchar);
+
+ GCOP_WRAP;
+ }
+ else
+ {
+ int i;
+
+ CLIP_SAVE;
+ GCOP_TOP_PART;
+
+ retval = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, nchar, pchar);
+
+ GCOP_BOTTOM_PART;
+ CLIP_RESTORE;
+ }
+
+ SCREEN_RESTORE;
+ }
+
+ return retval;
+}
+
+static int
+miBankPolyText16(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int nchar,
+ unsigned short *pchar
+)
+{
+ int retval = x;
+
+ if (nchar > 0)
+ {
+ GCOP_INIT;
+ SCREEN_SAVE;
+
+ if (!IS_BANKED(pDrawable))
+ {
+ GCOP_UNWRAP;
+
+ retval = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, nchar, pchar);
+
+ GCOP_WRAP;
+ }
+ else
+ {
+ int i;
+
+ CLIP_SAVE;
+ GCOP_TOP_PART;
+
+ retval = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, nchar, pchar);
+
+ GCOP_BOTTOM_PART;
+ CLIP_RESTORE;
+ }
+
+ SCREEN_RESTORE;
+ }
+
+ return retval;
+}
+
+static void
+miBankImageText8(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int nchar,
+ char *pchar
+)
+{
+ if (nchar > 0)
+ {
+ GCOP_SIMPLE((*pGC->ops->ImageText8)(pDrawable, pGC,
+ x, y, nchar, pchar));
+ }
+}
+
+static void
+miBankImageText16(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ int nchar,
+ unsigned short *pchar
+)
+{
+ if (nchar > 0)
+ {
+ GCOP_SIMPLE((*pGC->ops->ImageText16)(pDrawable, pGC,
+ x, y, nchar, pchar));
+ }
+}
+
+static void
+miBankImageGlyphBlt(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+)
+{
+ if (nglyph > 0)
+ {
+ GCOP_SIMPLE((*pGC->ops->ImageGlyphBlt)(pDrawable, pGC,
+ x, y, nglyph, ppci, pglyphBase));
+ }
+}
+
+static void
+miBankPolyGlyphBlt(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+)
+{
+ if (nglyph > 0)
+ {
+ GCOP_SIMPLE((*pGC->ops->PolyGlyphBlt)(pDrawable, pGC,
+ x, y, nglyph, ppci, pglyphBase));
+ }
+}
+
+static void
+miBankPushPixels(
+ GCPtr pGC,
+ PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int w,
+ int h,
+ int x,
+ int y
+)
+{
+ if ((w > 0) && (h > 0))
+ {
+ GCOP_INIT;
+ SCREEN_SAVE;
+
+ if (!IS_BANKED(pDrawable))
+ {
+ GCOP_UNWRAP;
+
+ (*pGC->ops->PushPixels)(pGC, pBitmap, pDrawable, w, h, x, y);
+
+ GCOP_WRAP;
+ }
+ else
+ {
+ int i, j;
+
+ CLIP_SAVE;
+
+ i = FirstBankOf(x, y);
+ j = LastBankOf(x + w, y + h);
+ for (; i <= j; i++)
+ {
+ if (!(pGC->pCompositeClip = pGCPriv->pBankedClips[i]))
+ continue;
+
+ GCOP_UNWRAP;
+
+ SET_SINGLE_BANK(pScreenPriv->pScreenPixmap, i);
+
+ (*pGC->ops->PushPixels)(pGC, pBitmap, pDrawable, w, h, x, y);
+
+ GCOP_WRAP;
+ }
+
+ CLIP_RESTORE;
+ }
+
+ SCREEN_RESTORE;
+ }
+}
+
+static GCOps miBankGCOps =
+{
+ miBankFillSpans,
+ miBankSetSpans,
+ miBankPutImage,
+ miBankCopyArea,
+ miBankCopyPlane,
+ miBankPolyPoint,
+ miBankPolylines,
+ miBankPolySegment,
+ miBankPolyRectangle,
+ miBankPolyArc,
+ miBankFillPolygon,
+ miBankPolyFillRect,
+ miBankPolyFillArc,
+ miBankPolyText8,
+ miBankPolyText16,
+ miBankImageText8,
+ miBankImageText16,
+ miBankImageGlyphBlt,
+ miBankPolyGlyphBlt,
+ miBankPushPixels,
+#ifdef NEED_LINEHELPER
+ NULL, /* LineHelper */
+#endif
+ {NULL} /* devPrivate */
+};
+
+/********************
+ * GCFuncs wrappers *
+ ********************/
+
+static void
+miBankValidateGC(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDrawable
+)
+{
+ GC_INIT(pGC);
+ GC_UNWRAP(pGC);
+
+ (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
+
+ if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
+ (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS)))
+ {
+ ScreenPtr pScreen = pGC->pScreen;
+ RegionPtr prgnClip;
+ int i;
+
+ SCREEN_INIT;
+ SCREEN_SAVE;
+
+ if (IS_BANKED(pDrawable))
+ {
+ for (i = 0; i < pScreenPriv->nBanks; i++)
+ {
+ if (!pScreenPriv->pBanks[i])
+ continue;
+
+ if (!(prgnClip = pGCPriv->pBankedClips[i]))
+ prgnClip = REGION_CREATE(pScreen, NULL, 1);
+
+ REGION_INTERSECT(pScreen, prgnClip,
+ pScreenPriv->pBanks[i], pGC->pCompositeClip);
+
+ if ((REGION_NUM_RECTS(prgnClip) <= 1) &&
+ ((prgnClip->extents.x1 == prgnClip->extents.x2) ||
+ (prgnClip->extents.y1 == prgnClip->extents.y2)))
+ {
+ REGION_DESTROY(pScreen, prgnClip);
+ pGCPriv->pBankedClips[i] = NULL;
+ }
+ else
+ pGCPriv->pBankedClips[i] = prgnClip;
+ }
+ }
+ else
+ {
+ /*
+ * Here we are on a pixmap and don't need all that special clipping
+ * stuff, hence free it.
+ */
+ for (i = 0; i < pScreenPriv->nBanks; i++)
+ {
+ if (!pGCPriv->pBankedClips[i])
+ continue;
+
+ REGION_DESTROY(pScreen, pGCPriv->pBankedClips[i]);
+ pGCPriv->pBankedClips[i] = NULL;
+ }
+ }
+
+ SCREEN_RESTORE;
+ }
+
+ GC_WRAP(pGC);
+}
+
+static void
+miBankChangeGC(
+ GCPtr pGC,
+ unsigned long mask
+)
+{
+ GC_INIT(pGC);
+ GC_UNWRAP(pGC);
+
+ (*pGC->funcs->ChangeGC)(pGC, mask);
+
+ GC_WRAP(pGC);
+}
+
+static void
+miBankCopyGC(
+ GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst
+)
+{
+ GC_INIT(pGCDst);
+ GC_UNWRAP(pGCDst);
+
+ (*pGCDst->funcs->CopyGC)(pGCSrc, mask, pGCDst);
+
+ GC_WRAP(pGCDst);
+}
+
+static void
+miBankDestroyGC(
+ GCPtr pGC
+)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ int i;
+
+ SCREEN_INIT;
+ GC_INIT(pGC);
+ GC_UNWRAP(pGC);
+
+ (*pGC->funcs->DestroyGC)(pGC);
+
+ for (i = 0; i < pScreenPriv->nBanks; i++)
+ {
+ if (!pGCPriv->pBankedClips[i])
+ continue;
+
+ REGION_DESTROY(pScreen, pGCPriv->pBankedClips[i]);
+ pGCPriv->pBankedClips[i] = NULL;
+ }
+
+ GC_WRAP(pGC);
+}
+
+static void
+miBankChangeClip(
+ GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects
+)
+{
+ GC_INIT(pGC);
+ GC_UNWRAP(pGC);
+
+ (*pGC->funcs->ChangeClip)(pGC, type, pvalue, nrects);
+
+ GC_WRAP(pGC);
+}
+
+static void
+miBankDestroyClip(
+ GCPtr pGC
+)
+{
+ GC_INIT(pGC);
+ GC_UNWRAP(pGC);
+
+ (*pGC->funcs->DestroyClip)(pGC);
+
+ GC_WRAP(pGC);
+}
+
+static void
+miBankCopyClip(
+ GCPtr pGCDst,
+ GCPtr pGCSrc
+)
+{
+ GC_INIT(pGCDst);
+ GC_UNWRAP(pGCDst);
+
+ (*pGCDst->funcs->CopyClip)(pGCDst, pGCSrc);
+
+ GC_WRAP(pGCDst);
+}
+
+static GCFuncs miBankGCFuncs =
+{
+ miBankValidateGC,
+ miBankChangeGC,
+ miBankCopyGC,
+ miBankDestroyGC,
+ miBankChangeClip,
+ miBankDestroyClip,
+ miBankCopyClip
+};
+
+/*******************
+ * Screen Wrappers *
+ *******************/
+
+static Bool
+miBankCreateScreenResources(
+ ScreenPtr pScreen
+)
+{
+ Bool retval;
+
+ SCREEN_INIT;
+ SCREEN_UNWRAP(CreateScreenResources);
+
+ if ((retval = (*pScreen->CreateScreenResources)(pScreen)))
+ {
+ /* Set screen buffer address to something recognizable */
+ pScreenPriv->pScreenPixmap = (*pScreen->GetScreenPixmap)(pScreen);
+ pScreenPriv->pbits = GetPixmapData(pScreenPriv->pScreenPixmap);
+ SetPixmapData(pScreenPriv->pScreenPixmap, pScreenPriv);
+
+ /* Get shadow pixmap; width & height of 0 means no pixmap data */
+ pScreenPriv->pBankPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0,
+ pScreenPriv->pScreenPixmap->drawable.depth);
+ if (!pScreenPriv->pBankPixmap)
+ retval = FALSE;
+ }
+
+ /* Shadow the screen */
+ if (retval)
+ retval = (*pScreen->ModifyPixmapHeader)(pScreenPriv->pBankPixmap,
+ pScreenPriv->pScreenPixmap->drawable.width,
+ pScreenPriv->pScreenPixmap->drawable.height,
+ pScreenPriv->pScreenPixmap->drawable.depth,
+ pScreenPriv->pScreenPixmap->drawable.bitsPerPixel,
+ pScreenPriv->pScreenPixmap->devKind, (pointer)pScreenPriv);
+
+ /* Create shadow GC */
+ if (retval)
+ {
+ pScreenPriv->pBankGC = CreateScratchGC(pScreen,
+ pScreenPriv->pBankPixmap->drawable.depth);
+ if (!pScreenPriv->pBankGC)
+ retval = FALSE;
+ }
+
+ /* Validate shadow GC */
+ if (retval)
+ {
+ pScreenPriv->pBankGC->graphicsExposures = FALSE;
+ pScreenPriv->pBankGC->subWindowMode = IncludeInferiors;
+ ValidateGC((DrawablePtr)pScreenPriv->pBankPixmap,
+ pScreenPriv->pBankGC);
+ }
+
+ SCREEN_WRAP(CreateScreenResources, miBankCreateScreenResources);
+
+ return retval;
+}
+
+static Bool
+miBankCloseScreen(
+ int nIndex,
+ ScreenPtr pScreen
+)
+{
+ int i;
+
+ SCREEN_INIT;
+
+ /* Free shadow GC */
+ FreeScratchGC(pScreenPriv->pBankGC);
+
+ /* Free shadow pixmap */
+ SetPixmapData(pScreenPriv->pBankPixmap, NULL);
+ (*pScreen->DestroyPixmap)(pScreenPriv->pBankPixmap);
+
+ /* Restore screen pixmap data pointer */
+ SetPixmapData(pScreenPriv->pScreenPixmap, pScreenPriv->pbits);
+
+ /* Delete bank clips */
+ for (i = 0; i < pScreenPriv->nBanks; i++)
+ if (pScreenPriv->pBanks[i])
+ REGION_DESTROY(pScreen, pScreenPriv->pBanks[i]);
+
+ Xfree(pScreenPriv->pBanks);
+
+ SCREEN_UNWRAP(CreateScreenResources);
+ SCREEN_UNWRAP(CloseScreen);
+ SCREEN_UNWRAP(GetImage);
+ SCREEN_UNWRAP(GetSpans);
+ SCREEN_UNWRAP(CreateGC);
+ SCREEN_UNWRAP(PaintWindowBackground);
+ SCREEN_UNWRAP(PaintWindowBorder);
+ SCREEN_UNWRAP(CopyWindow);
+ SCREEN_UNWRAP(BackingStoreFuncs);
+
+ Xfree(pScreenPriv);
+ return (*pScreen->CloseScreen)(nIndex, pScreen);
+}
+
+static void
+miBankGetImage(
+ DrawablePtr pDrawable,
+ int sx,
+ int sy,
+ int w,
+ int h,
+ unsigned int format,
+ unsigned long planemask,
+ char *pImage
+)
+{
+ if ((w > 0) && (h > 0))
+ {
+ ScreenPtr pScreen = pDrawable->pScreen;
+
+ SCREEN_INIT;
+ SCREEN_SAVE;
+ SCREEN_UNWRAP(GetImage);
+
+ if (!IS_BANKED(pDrawable))
+ {
+ (*pScreen->GetImage)(pDrawable, sx, sy, w, h,
+ format, planemask, pImage);
+ }
+ else
+ {
+ int paddedWidth;
+ char *pBankImage;
+
+ paddedWidth = PixmapBytePad(w,
+ pScreenPriv->pScreenPixmap->drawable.depth);
+ pBankImage = (char *)ALLOCATE_LOCAL(paddedWidth * h);
+
+ if (pBankImage)
+ {
+ SavePixmap;
+
+ SetPixmapWidth(pScreenPriv->pBankPixmap, w, paddedWidth);
+ SetPixmapData(pScreenPriv->pBankPixmap, pBankImage);
+
+ (*pScreenPriv->pBankGC->ops->CopyArea)(
+ (DrawablePtr)WindowTable[pScreen->myNum],
+ (DrawablePtr)pScreenPriv->pBankPixmap,
+ pScreenPriv->pBankGC,
+ sx + pDrawable->x, sy + pDrawable->y, w, h, 0, 0);
+
+ (*pScreen->GetImage)((DrawablePtr)pScreenPriv->pBankPixmap,
+ 0, 0, w, h, format, planemask, pImage);
+
+ RestorePixmap;
+
+ DEALLOCATE_LOCAL(pBankImage);
+ }
+ }
+
+ SCREEN_WRAP(GetImage, miBankGetImage);
+ SCREEN_RESTORE;
+ }
+}
+
+static void
+miBankGetSpans(
+ DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pImage
+)
+{
+ if (nspans > 0)
+ {
+ ScreenPtr pScreen = pDrawable->pScreen;
+
+ SCREEN_INIT;
+ SCREEN_SAVE;
+ SCREEN_UNWRAP(GetSpans);
+
+ if (!IS_BANKED(pDrawable))
+ {
+ (*pScreen->GetSpans)(pDrawable, wMax, ppt, pwidth, nspans, pImage);
+ }
+ else
+ {
+ char *pBankImage;
+ int paddedWidth;
+ DDXPointRec pt;
+
+ pt.x = pt.y = 0;
+
+ paddedWidth =
+ PixmapBytePad(pScreenPriv->pScreenPixmap->drawable.width,
+ pScreenPriv->pScreenPixmap->drawable.depth);
+ pBankImage = (char *)ALLOCATE_LOCAL(paddedWidth);
+
+ if (pBankImage)
+ {
+ SavePixmap;
+
+ SetPixmapWidth(pScreenPriv->pBankPixmap,
+ pScreenPriv->pScreenPixmap->drawable.width, paddedWidth);
+ SetPixmapData(pScreenPriv->pBankPixmap, pBankImage);
+
+ for (; nspans--; ppt++, pwidth++)
+ {
+ if (*pwidth <= 0)
+ continue;
+
+ (*pScreenPriv->pBankGC->ops->CopyArea)(
+ (DrawablePtr)WindowTable[pScreen->myNum],
+ (DrawablePtr)pScreenPriv->pBankPixmap,
+ pScreenPriv->pBankGC,
+ ppt->x, ppt->y, *pwidth, 1, 0, 0);
+
+ (*pScreen->GetSpans)((DrawablePtr)pScreenPriv->pBankPixmap,
+ wMax, &pt, pwidth, 1, pImage);
+
+ pImage = pImage + PixmapBytePad(*pwidth, pDrawable->depth);
+ }
+
+ RestorePixmap;
+
+ DEALLOCATE_LOCAL(pBankImage);
+ }
+ }
+
+ SCREEN_WRAP(GetSpans, miBankGetSpans);
+ SCREEN_RESTORE;
+ }
+}
+
+static Bool
+miBankCreateGC(
+ GCPtr pGC
+)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ miBankGCPtr pGCPriv = BANK_GCPRIVATE(pGC);
+ Bool ret;
+
+ SCREEN_INIT;
+ SCREEN_UNWRAP(CreateGC);
+
+ if ((ret = (*pScreen->CreateGC)(pGC)))
+ {
+ GC_WRAP(pGC);
+
+ memset(&pGCPriv->pBankedClips, 0,
+ pScreenPriv->nBanks * sizeof(pGCPriv->pBankedClips));
+ }
+
+ SCREEN_WRAP(CreateGC, miBankCreateGC);
+
+ return ret;
+}
+
+static void
+miBankPaintWindow(
+ WindowPtr pWin,
+ RegionPtr pRegion,
+ int what
+)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RegionRec tmpReg;
+ int i;
+ PaintWindowProcPtr PaintWindow;
+
+ SCREEN_INIT;
+ SCREEN_SAVE;
+
+ if (what == PW_BORDER)
+ {
+ SCREEN_UNWRAP(PaintWindowBorder);
+ PaintWindow = pScreen->PaintWindowBorder;
+ }
+ else
+ {
+ SCREEN_UNWRAP(PaintWindowBackground);
+ PaintWindow = pScreen->PaintWindowBackground;
+ }
+
+ if (!IS_BANKED(pWin))
+ {
+ (*PaintWindow)(pWin, pRegion, what);
+ }
+ else
+ {
+ REGION_INIT(pScreen, &tmpReg, NullBox, 0);
+
+ for (i = 0; i < pScreenPriv->nBanks; i++)
+ {
+ if (!pScreenPriv->pBanks[i])
+ continue;
+
+ REGION_INTERSECT(pScreen, &tmpReg, pRegion,
+ pScreenPriv->pBanks[i]);
+
+ if (REGION_NIL(&tmpReg))
+ continue;
+
+ SET_SINGLE_BANK(pScreenPriv->pScreenPixmap, i);
+
+ (*PaintWindow)(pWin, &tmpReg, what);
+ }
+
+ REGION_UNINIT(pScreen, &tmpReg);
+ }
+
+ if (what == PW_BORDER)
+ {
+ SCREEN_WRAP(PaintWindowBorder, miBankPaintWindow);
+ }
+ else
+ {
+ SCREEN_WRAP(PaintWindowBackground, miBankPaintWindow);
+ }
+
+ SCREEN_RESTORE;
+}
+
+static void
+miBankCopyWindow(
+ WindowPtr pWindow,
+ DDXPointRec ptOldOrg,
+ RegionPtr pRgnSrc
+)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ GCPtr pGC;
+ int dx, dy, nBox;
+ DrawablePtr pDrawable = (DrawablePtr)WindowTable[pScreen->myNum];
+ RegionPtr pRgnDst;
+ BoxPtr pBox, pBoxTmp, pBoxNext, pBoxBase, pBoxNew1, pBoxNew2;
+ XID subWindowMode = IncludeInferiors;
+
+ pGC = GetScratchGC(pDrawable->depth, pScreen);
+
+ ChangeGC(pGC, GCSubwindowMode, &subWindowMode);
+ ValidateGC(pDrawable, pGC);
+
+ pRgnDst = REGION_CREATE(pScreen, NULL, 1);
+
+ dx = ptOldOrg.x - pWindow->drawable.x;
+ dy = ptOldOrg.y - pWindow->drawable.y;
+ REGION_TRANSLATE(pScreen, pRgnSrc, -dx, -dy);
+ REGION_INTERSECT(pScreen, pRgnDst, &pWindow->borderClip, pRgnSrc);
+
+ pBox = REGION_RECTS(pRgnDst);
+ nBox = REGION_NUM_RECTS(pRgnDst);
+
+ pBoxNew1 = NULL;
+ pBoxNew2 = NULL;
+
+ if (nBox > 1)
+ {
+ if (dy < 0)
+ {
+ /* Sort boxes from bottom to top */
+ pBoxNew1 = ALLOCATE_LOCAL_ARRAY(BoxRec, nBox);
+
+ if (pBoxNew1)
+ {
+ pBoxBase = pBoxNext = pBox + nBox - 1;
+
+ while (pBoxBase >= pBox)
+ {
+ while ((pBoxNext >= pBox) &&
+ (pBoxBase->y1 == pBoxNext->y1))
+ pBoxNext--;
+
+ pBoxTmp = pBoxNext + 1;
+
+ while (pBoxTmp <= pBoxBase)
+ *pBoxNew1++ = *pBoxTmp++;
+
+ pBoxBase = pBoxNext;
+ }
+
+ pBoxNew1 -= nBox;
+ pBox = pBoxNew1;
+ }
+ }
+
+ if (dx < 0)
+ {
+ /* Sort boxes from right to left */
+ pBoxNew2 = ALLOCATE_LOCAL_ARRAY(BoxRec, nBox);
+
+ if (pBoxNew2)
+ {
+ pBoxBase = pBoxNext = pBox;
+
+ while (pBoxBase < pBox + nBox)
+ {
+ while ((pBoxNext < pBox + nBox) &&
+ (pBoxNext->y1 == pBoxBase->y1))
+ pBoxNext++;
+
+ pBoxTmp = pBoxNext;
+
+ while (pBoxTmp != pBoxBase)
+ *pBoxNew2++ = *--pBoxTmp;
+
+ pBoxBase = pBoxNext;
+ }
+
+ pBoxNew2 -= nBox;
+ pBox = pBoxNew2;
+ }
+ }
+ }
+
+ while (nBox--)
+ {
+ (*pGC->ops->CopyArea)(pDrawable, pDrawable, pGC,
+ pBox->x1 + dx, pBox->y1 + dy,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
+ pBox->x1, pBox->y1);
+
+ pBox++;
+ }
+
+ FreeScratchGC(pGC);
+
+ REGION_DESTROY(pScreen, pRgnDst);
+
+ if (pBoxNew2)
+ DEALLOCATE_LOCAL(pBoxNew2);
+ if (pBoxNew1)
+ DEALLOCATE_LOCAL(pBoxNew1);
+}
+
+/**************************
+ * Backing store wrappers *
+ **************************/
+
+static void
+miBankSaveAreas(
+ PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ RegionRec rgnClipped;
+ int i;
+
+ SCREEN_INIT;
+ SCREEN_SAVE;
+ SCREEN_UNWRAP(BackingStoreFuncs.SaveAreas);
+
+ if (!IS_BANKED(pWin))
+ {
+ (*pScreen->BackingStoreFuncs.SaveAreas)(pPixmap, prgnSave, xorg, yorg,
+ pWin);
+ }
+ else
+ {
+ REGION_INIT(pScreen, &rgnClipped, NullBox, 0);
+ REGION_TRANSLATE(pScreen, prgnSave, xorg, yorg);
+
+ for (i = 0; i < pScreenPriv->nBanks; i++)
+ {
+ if (!pScreenPriv->pBanks[i])
+ continue;
+
+ REGION_INTERSECT(pScreen, &rgnClipped,
+ prgnSave, pScreenPriv->pBanks[i]);
+
+ if (REGION_NIL(&rgnClipped))
+ continue;
+
+ SET_SINGLE_BANK(pScreenPriv->pScreenPixmap, i);
+
+ REGION_TRANSLATE(pScreen, &rgnClipped, -xorg, -yorg);
+
+ (*pScreen->BackingStoreFuncs.SaveAreas)(pPixmap, &rgnClipped,
+ xorg, yorg, pWin);
+ }
+
+ REGION_TRANSLATE(pScreen, prgnSave, -xorg, -yorg);
+ REGION_UNINIT(pScreen, &rgnClipped);
+ }
+
+ SCREEN_WRAP(BackingStoreFuncs.SaveAreas, miBankSaveAreas);
+ SCREEN_RESTORE;
+}
+
+static void
+miBankRestoreAreas(
+ PixmapPtr pPixmap,
+ RegionPtr prgnRestore,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ RegionRec rgnClipped;
+ int i;
+
+ SCREEN_INIT;
+ SCREEN_SAVE;
+ SCREEN_UNWRAP(BackingStoreFuncs.RestoreAreas);
+
+ if (!IS_BANKED(pWin))
+ {
+ (*pScreen->BackingStoreFuncs.RestoreAreas)(pPixmap, prgnRestore,
+ xorg, yorg, pWin);
+ }
+ else
+ {
+ REGION_INIT(pScreen, &rgnClipped, NullBox, 0);
+
+ for (i = 0; i < pScreenPriv->nBanks; i++)
+ {
+ if (!pScreenPriv->pBanks[i])
+ continue;
+
+ REGION_INTERSECT(pScreen, &rgnClipped,
+ prgnRestore, pScreenPriv->pBanks[i]);
+
+ if (REGION_NIL(&rgnClipped))
+ continue;
+
+ SET_SINGLE_BANK(pScreenPriv->pScreenPixmap, i);
+
+ (*pScreen->BackingStoreFuncs.RestoreAreas)(pPixmap, &rgnClipped,
+ xorg, yorg, pWin);
+ }
+
+ REGION_UNINIT(pScreen, &rgnClipped);
+ }
+
+ SCREEN_WRAP(BackingStoreFuncs.RestoreAreas, miBankRestoreAreas);
+ SCREEN_RESTORE;
+}
+
+Bool
+miInitializeBanking(
+ ScreenPtr pScreen,
+ unsigned int xsize,
+ unsigned int ysize,
+ unsigned int width,
+ miBankInfoPtr pBankInfo
+)
+{
+ miBankScreenPtr pScreenPriv;
+ unsigned long nBitsPerBank, nBitsPerScanline, nPixelsPerScanlinePadUnit;
+ unsigned long BankBase, ServerPad;
+ unsigned int type, nBanks, maxRects, we, nBankBPP;
+ int i;
+
+ if (!pBankInfo)
+ return TRUE; /* No banking required */
+
+ /* Sanity checks */
+
+ if (!pScreen || !xsize || !ysize || (xsize > width) ||
+ !pBankInfo->SetSourceBank || !pBankInfo->SetDestinationBank ||
+ !pBankInfo->SetSourceAndDestinationBanks ||
+ !pBankInfo->pBankA || !pBankInfo->pBankB ||
+ !pBankInfo->nBankDepth)
+ return FALSE;
+
+ /*
+ * DDX *must* have registered a pixmap format whose depth is
+ * pBankInfo->nBankDepth. This is not necessarily the rootDepth
+ * pixmap format.
+ */
+ i = 0;
+ while (screenInfo.formats[i].depth != pBankInfo->nBankDepth)
+ if (++i >= screenInfo.numPixmapFormats)
+ return FALSE;
+ nBankBPP = screenInfo.formats[i].bitsPerPixel;
+
+ i = 0;
+ while (screenInfo.formats[i].depth != pScreen->rootDepth)
+ if (++i >= screenInfo.numPixmapFormats)
+ return FALSE;
+
+ if (nBankBPP > screenInfo.formats[i].bitsPerPixel)
+ return FALSE;
+
+ if (pBankInfo->pBankA == pBankInfo->pBankB)
+ {
+ if (pBankInfo->SetSourceBank == pBankInfo->SetDestinationBank)
+ {
+ if (pBankInfo->SetSourceAndDestinationBanks !=
+ pBankInfo->SetSourceBank)
+ return FALSE;
+
+ type = BANK_SINGLE;
+ }
+ else
+ {
+ if (pBankInfo->SetSourceAndDestinationBanks ==
+ pBankInfo->SetDestinationBank)
+ return FALSE;
+ if (pBankInfo->SetSourceAndDestinationBanks ==
+ pBankInfo->SetSourceBank)
+ return FALSE;
+
+ type = BANK_SHARED;
+ }
+ }
+ else
+ {
+ if (abs((char *)pBankInfo->pBankA -
+ (char *)pBankInfo->pBankB) < pBankInfo->BankSize)
+ return FALSE;
+
+ if (pBankInfo->SetSourceBank == pBankInfo->SetDestinationBank)
+ {
+ if (pBankInfo->SetSourceAndDestinationBanks !=
+ pBankInfo->SetSourceBank)
+ return FALSE;
+ }
+ else
+ {
+ if (pBankInfo->SetSourceAndDestinationBanks ==
+ pBankInfo->SetDestinationBank)
+ return FALSE;
+ }
+
+ type = BANK_DOUBLE;
+ }
+
+ /*
+ * Internal limitation: Currently, only single banking is supported when
+ * the pixmap format and the screen's pixel format are different. The
+ * following test is only partially successful at detecting this condition.
+ */
+ if (pBankInfo->nBankDepth != pScreen->rootDepth)
+ type = BANK_SINGLE;
+
+ /* Internal data */
+
+ nBitsPerBank = pBankInfo->BankSize * 8;
+ ServerPad = PixmapBytePad(1, pBankInfo->nBankDepth) * 8;
+ if (nBitsPerBank % ServerPad)
+ return FALSE;
+ nBitsPerScanline = PixmapBytePad(width, pBankInfo->nBankDepth) * 8;
+ nBanks = ((nBitsPerScanline * (ysize - 1)) +
+ (nBankBPP * xsize) + nBitsPerBank - 1) / nBitsPerBank;
+ nPixelsPerScanlinePadUnit = miLCM(ServerPad, nBankBPP) / nBankBPP;
+
+ /* Private areas */
+
+ if (miBankGeneration != serverGeneration)
+ {
+ if (((miBankScreenIndex = AllocateScreenPrivateIndex()) < 0) ||
+ ((miBankGCIndex = AllocateGCPrivateIndex()) < 0))
+ return FALSE;
+
+ miBankGeneration = serverGeneration;
+ }
+
+ if (!AllocateGCPrivate(pScreen, miBankGCIndex,
+ (nBanks * sizeof(RegionPtr)) +
+ (sizeof(miBankGCRec) - sizeof(RegionPtr))))
+ return FALSE;
+
+ if (!(pScreenPriv = (miBankScreenPtr)Xcalloc(sizeof(miBankScreenRec))))
+ return FALSE;
+
+ if (!(pScreenPriv->pBanks = /* Allocate and clear */
+ (RegionPtr *)Xcalloc(nBanks * sizeof(RegionPtr))))
+ {
+ Xfree(pScreenPriv);
+ return FALSE;
+ }
+
+ /*
+ * Translate banks into clipping regions which are themselves clipped
+ * against the screen. This also ensures that pixels with imbedded bank
+ * boundaries are off-screen.
+ */
+
+ BankBase = 0;
+ maxRects = 0;
+ we = 0;
+ for (i = 0; i < nBanks; i++)
+ {
+ xRectangle pRects[3], *pRect = pRects;
+ unsigned int xb, yb, xe, ye;
+
+ xb = ((BankBase + nBankBPP - 1) % nBitsPerScanline) / nBankBPP;
+ yb = (BankBase + nBankBPP - 1) / nBitsPerScanline;
+ if (xb >= xsize)
+ {
+ xb = we = 0;
+ yb++;
+ }
+ if (yb >= ysize)
+ {
+ we = 0;
+ break;
+ }
+
+ if (we)
+ break;
+
+ BankBase += nBitsPerBank;
+
+ we = (BankBase % nBitsPerScanline) % nBankBPP;
+ xe = (BankBase % nBitsPerScanline) / nBankBPP;
+ ye = BankBase / nBitsPerScanline;
+ if (xe >= xsize)
+ {
+ we = xe = 0;
+ ye++;
+ }
+ if (ye >= ysize)
+ {
+ we = xe = 0;
+ ye = ysize;
+ }
+
+ if (yb == ye)
+ {
+ if (xb >= xe)
+ continue;
+
+ pRect->x = xb;
+ pRect->y = yb;
+ pRect->width = xe - xb;
+ pRect->height = 1;
+ maxRects += 2;
+ pRect++;
+ }
+ else
+ {
+ if (xb)
+ {
+ pRect->x = xb;
+ pRect->y = yb++;
+ pRect->width = xsize - xb;
+ pRect->height = 1;
+ maxRects += 2;
+ pRect++;
+ }
+
+ if (yb < ye)
+ {
+ pRect->x = 0;
+ pRect->y = yb;
+ pRect->width = xsize;
+ pRect->height = ye - yb;
+ maxRects += min(pRect->height, 3) + 1;
+ pRect++;
+ }
+
+ if (xe)
+ {
+ pRect->x = 0;
+ pRect->y = ye;
+ pRect->width = xe;
+ pRect->height = 1;
+ maxRects += 2;
+ pRect++;
+ }
+ }
+
+ pScreenPriv->pBanks[i] =
+ RECTS_TO_REGION(pScreen, pRect - pRects, pRects, 0);
+ if (!pScreenPriv->pBanks[i])
+ {
+ we = 1;
+ break;
+ }
+ }
+
+ if (we && (i < nBanks))
+ {
+ for (; i >= 0; i--)
+ if (pScreenPriv->pBanks[i])
+ REGION_DESTROY(pScreen, pScreenPriv->pBanks[i]);
+
+ Xfree(pScreenPriv->pBanks);
+ Xfree(pScreenPriv);
+
+ return FALSE;
+ }
+
+ /* Open for business */
+
+ pScreenPriv->type = type;
+ pScreenPriv->nBanks = nBanks;
+ pScreenPriv->maxRects = maxRects;
+ pScreenPriv->nBankBPP = nBankBPP;
+ pScreenPriv->BankInfo = *pBankInfo;
+ pScreenPriv->nBitsPerBank = nBitsPerBank;
+ pScreenPriv->nBitsPerScanline = nBitsPerScanline;
+ pScreenPriv->nPixelsPerScanlinePadUnit = nPixelsPerScanlinePadUnit;
+
+ SCREEN_WRAP(CreateScreenResources, miBankCreateScreenResources);
+ SCREEN_WRAP(CloseScreen, miBankCloseScreen);
+ SCREEN_WRAP(GetImage, miBankGetImage);
+ SCREEN_WRAP(GetSpans, miBankGetSpans);
+ SCREEN_WRAP(CreateGC, miBankCreateGC);
+ SCREEN_WRAP(PaintWindowBackground, miBankPaintWindow);
+ SCREEN_WRAP(PaintWindowBorder, miBankPaintWindow);
+ SCREEN_WRAP(CopyWindow, miBankCopyWindow);
+
+ pScreenPriv->BackingStoreFuncs = pScreen->BackingStoreFuncs;
+
+ pScreen->BackingStoreFuncs.SaveAreas = miBankSaveAreas;
+ pScreen->BackingStoreFuncs.RestoreAreas = miBankRestoreAreas;
+ /* ??????????????????????????????????????????????????????????????
+ pScreen->BackingStoreFuncs.SetClipmaskRgn = miBankSetClipmaskRgn;
+ ?????????????????????????????????????????????????????????????? */
+
+ BANK_SCRPRIVLVAL = (pointer)pScreenPriv;
+
+ return TRUE;
+}
+
+/*
+ * Given various screen attributes, determine the minimum scanline width such
+ * that each scanline is server and DDX padded and any pixels with imbedded
+ * bank boundaries are off-screen. This function returns -1 if such a width
+ * cannot exist. This function exists because the DDX needs to be able to
+ * determine this width before initializing a frame buffer.
+ */
+int
+miScanLineWidth(
+ unsigned int xsize, /* pixels */
+ unsigned int ysize, /* pixels */
+ unsigned int width, /* pixels */
+ unsigned long BankSize, /* char's */
+ PixmapFormatRec *pBankFormat,
+ unsigned int nWidthUnit /* bits */
+)
+{
+ unsigned long nBitsPerBank, nBitsPerScanline, nBitsPerScanlinePadUnit;
+ unsigned long minBitsPerScanline, maxBitsPerScanline;
+
+ /* Sanity checks */
+
+ if (!nWidthUnit || !pBankFormat)
+ return -1;
+
+ nBitsPerBank = BankSize * 8;
+ if (nBitsPerBank % pBankFormat->scanlinePad)
+ return -1;
+
+ if (xsize > width)
+ width = xsize;
+ nBitsPerScanlinePadUnit = miLCM(pBankFormat->scanlinePad, nWidthUnit);
+ nBitsPerScanline =
+ (((width * pBankFormat->bitsPerPixel) + nBitsPerScanlinePadUnit - 1) /
+ nBitsPerScanlinePadUnit) * nBitsPerScanlinePadUnit;
+ width = nBitsPerScanline / pBankFormat->bitsPerPixel;
+
+ if (!xsize || !(nBitsPerBank % pBankFormat->bitsPerPixel))
+ return (int)width;
+
+ /*
+ * Scanlines will be server-pad aligned at this point. They will also be
+ * a multiple of nWidthUnit bits long. Ensure that pixels with imbedded
+ * bank boundaries are off-screen.
+ *
+ * It seems reasonable to limit total frame buffer size to 1/16 of the
+ * theoretical maximum address space size. On a machine with 32-bit
+ * addresses (to 8-bit quantities) this turns out to be 256MB. Not only
+ * does this provide a simple limiting condition for the loops below, but
+ * it also prevents unsigned long wraparounds.
+ */
+ if (!ysize)
+ return -1;
+
+ minBitsPerScanline = xsize * pBankFormat->bitsPerPixel;
+ if (minBitsPerScanline > nBitsPerBank)
+ return -1;
+
+ if (ysize == 1)
+ return (int)width;
+
+ maxBitsPerScanline = (((unsigned long)(-1) >> 1) - minBitsPerScanline) /
+ (ysize - 1);
+ while (nBitsPerScanline <= maxBitsPerScanline)
+ {
+ unsigned long BankBase, BankUnit;
+
+ BankUnit = ((nBitsPerBank + nBitsPerScanline - 1) / nBitsPerBank) *
+ nBitsPerBank;
+ if (!(BankUnit % nBitsPerScanline))
+ return (int)width;
+
+ for (BankBase = BankUnit; ; BankBase += nBitsPerBank)
+ {
+ unsigned long x, y;
+
+ y = BankBase / nBitsPerScanline;
+ if (y >= ysize)
+ return (int)width;
+
+ x = BankBase % nBitsPerScanline;
+ if (!(x % pBankFormat->bitsPerPixel))
+ continue;
+
+ if (x >= minBitsPerScanline)
+ {
+ if (BankBase != BankUnit)
+ continue;
+
+ if (!(nBitsPerBank % x))
+ return (int)width;
+
+ BankBase = ((nBitsPerScanline - minBitsPerScanline) /
+ (nBitsPerScanline - x)) * BankUnit;
+ continue;
+ }
+
+ /*
+ * Skip ahead certain widths by dividing the excess scanline
+ * amongst the y's.
+ */
+ y *= nBitsPerScanlinePadUnit;
+ nBitsPerScanline += ((x + y - 1) / y) * nBitsPerScanlinePadUnit;
+ width = nBitsPerScanline / pBankFormat->bitsPerPixel;
+ break;
+ }
+ }
+
+ return -1;
+}
diff --git a/xc/programs/Xserver/mi/mibank.h b/xc/programs/Xserver/mi/mibank.h
new file mode 100644
index 000000000..ad681b6aa
--- /dev/null
+++ b/xc/programs/Xserver/mi/mibank.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright 1997,1998 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $XFree86: xc/programs/Xserver/mi/mibank.h,v 1.4 1998/09/19 12:15:05 dawes Exp $ */
+
+#ifndef __MIBANK_H__
+#define __MIBANK_H__ 1
+
+#include "scrnintstr.h"
+
+/*
+ * Banking external interface.
+ */
+
+/*
+ * This is the banking function type. The return value is normally zero.
+ * Non-zero returns can be used to implement the likes of scanline interleave,
+ * etc.
+ */
+typedef int miBankProc(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ unsigned int /*iBank*/
+#endif
+);
+
+typedef miBankProc *miBankProcPtr;
+
+typedef struct _miBankInfo
+{
+ /*
+ * Banking refers to the use of one or more apertures (in the server's
+ * address space) to access various parts of a potentially larger hardware
+ * frame buffer.
+ *
+ * Three different banking schemes are supported:
+ *
+ * Single banking is indicated when pBankA and pBankB are equal and all
+ * three miBankProcPtr's point to the same function. Here, both reads and
+ * writes through the aperture access the same hardware location.
+ *
+ * Shared banking is indicated when pBankA and pBankB are equal but the
+ * source and destination functions differ. Here reads through the
+ * aperture do not necessarily access the same hardware location as writes.
+ *
+ * Double banking is indicated when pBankA and pBankB differ. Here two
+ * independent apertures are used to provide read/write access to
+ * potentially different hardware locations.
+ *
+ * Any other combination will result in no banking.
+ */
+ miBankProcPtr SetSourceBank; /* Set pBankA bank number */
+ miBankProcPtr SetDestinationBank; /* Set pBankB bank number */
+ miBankProcPtr SetSourceAndDestinationBanks; /* Set both bank numbers */
+
+ pointer pBankA; /* First aperture location */
+ pointer pBankB; /* First or second aperture location */
+
+ /*
+ * BankSize is in units of sizeof(char) and is the size of each bank.
+ */
+ unsigned long BankSize;
+
+ /*
+ * nBankDepth is the colour depth associated with the maximum number of a
+ * pixel's bits that are simultaneously accessible through the frame buffer
+ * aperture.
+ */
+ unsigned int nBankDepth;
+} miBankInfoRec, *miBankInfoPtr;
+
+Bool
+miInitializeBanking(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ unsigned int /*xsize*/,
+ unsigned int /*ysize*/,
+ unsigned int /*width*/,
+ miBankInfoPtr /*pBankInfo*/
+#endif
+);
+
+/*
+ * This function determines the minimum screen width, given a initial estimate
+ * and various screen attributes. DDX needs to determine this width before
+ * initializing the screen.
+ */
+int
+miScanLineWidth(
+#if NeedFunctionPrototypes
+ unsigned int /*xsize*/,
+ unsigned int /*ysize*/,
+ unsigned int /*width*/,
+ unsigned long /*BankSize*/,
+ PixmapFormatRec * /*pBankFormat*/,
+ unsigned int /*nWidthUnit*/
+#endif
+);
+
+#endif /* __MIBANK_H__ */
diff --git a/xc/programs/Xserver/mi/mibitblt.c b/xc/programs/Xserver/mi/mibitblt.c
new file mode 100644
index 000000000..f3d0da3d9
--- /dev/null
+++ b/xc/programs/Xserver/mi/mibitblt.c
@@ -0,0 +1,829 @@
+/* $XFree86: xc/programs/Xserver/mi/mibitblt.c,v 3.7 1998/10/04 09:39:24 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mibitblt.c /main/56 1998/02/09 14:46:05 kaleb $ */
+/* Author: Todd Newman (aided and abetted by Mr. Drewry) */
+
+#include "X.h"
+#include "Xprotostr.h"
+
+#include "misc.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "Xmd.h"
+#include "servermd.h"
+
+/* MICOPYAREA -- public entry for the CopyArea request
+ * For each rectangle in the source region
+ * get the pixels with GetSpans
+ * set them in the destination with SetSpans
+ * We let SetSpans worry about clipping to the destination.
+ */
+RegionPtr
+miCopyArea(pSrcDrawable, pDstDrawable,
+ pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut)
+ register DrawablePtr pSrcDrawable;
+ register DrawablePtr pDstDrawable;
+ GCPtr pGC;
+ int xIn, yIn;
+ int widthSrc, heightSrc;
+ int xOut, yOut;
+{
+ DDXPointPtr ppt, pptFirst;
+ unsigned int *pwidthFirst, *pwidth, *pbits;
+ BoxRec srcBox, *prect;
+ /* may be a new region, or just a copy */
+ RegionPtr prgnSrcClip;
+ /* non-0 if we've created a src clip */
+ RegionPtr prgnExposed;
+ int realSrcClip = 0;
+ int srcx, srcy, dstx, dsty, i, j, y, width, height,
+ xMin, xMax, yMin, yMax;
+ unsigned int *ordering;
+ int numRects;
+ BoxPtr boxes;
+
+ srcx = xIn + pSrcDrawable->x;
+ srcy = yIn + pSrcDrawable->y;
+
+ /* If the destination isn't realized, this is easy */
+ if (pDstDrawable->type == DRAWABLE_WINDOW &&
+ !((WindowPtr)pDstDrawable)->realized)
+ return (RegionPtr)NULL;
+
+ /* clip the source */
+ if (pSrcDrawable->type == DRAWABLE_PIXMAP)
+ {
+ BoxRec box;
+
+ box.x1 = pSrcDrawable->x;
+ box.y1 = pSrcDrawable->y;
+ box.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
+ box.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
+
+ prgnSrcClip = REGION_CREATE(pGC->pScreen, &box, 1);
+ realSrcClip = 1;
+ }
+ else
+ {
+ if (pGC->subWindowMode == IncludeInferiors) {
+ prgnSrcClip = NotClippedByChildren ((WindowPtr) pSrcDrawable);
+ realSrcClip = 1;
+ } else
+ prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
+ }
+
+ /* If the src drawable is a window, we need to translate the srcBox so
+ * that we can compare it with the window's clip region later on. */
+ srcBox.x1 = srcx;
+ srcBox.y1 = srcy;
+ srcBox.x2 = srcx + widthSrc;
+ srcBox.y2 = srcy + heightSrc;
+
+ dstx = xOut;
+ dsty = yOut;
+ if (pGC->miTranslate)
+ {
+ dstx += pDstDrawable->x;
+ dsty += pDstDrawable->y;
+ }
+
+ pptFirst = ppt = (DDXPointPtr)
+ ALLOCATE_LOCAL(heightSrc * sizeof(DDXPointRec));
+ pwidthFirst = pwidth = (unsigned int *)
+ ALLOCATE_LOCAL(heightSrc * sizeof(unsigned int));
+ numRects = REGION_NUM_RECTS(prgnSrcClip);
+ boxes = REGION_RECTS(prgnSrcClip);
+ ordering = (unsigned int *)
+ ALLOCATE_LOCAL(numRects * sizeof(unsigned int));
+ if(!pptFirst || !pwidthFirst || !ordering)
+ {
+ if (ordering)
+ DEALLOCATE_LOCAL(ordering);
+ if (pwidthFirst)
+ DEALLOCATE_LOCAL(pwidthFirst);
+ if (pptFirst)
+ DEALLOCATE_LOCAL(pptFirst);
+ return (RegionPtr)NULL;
+ }
+
+ /* If not the same drawable then order of move doesn't matter.
+ Following assumes that boxes are sorted from top
+ to bottom and left to right.
+ */
+ if ((pSrcDrawable != pDstDrawable) &&
+ ((pGC->subWindowMode != IncludeInferiors) ||
+ (pSrcDrawable->type == DRAWABLE_PIXMAP) ||
+ (pDstDrawable->type == DRAWABLE_PIXMAP)))
+ for (i=0; i < numRects; i++)
+ ordering[i] = i;
+ else { /* within same drawable, must sequence moves carefully! */
+ if (dsty <= srcBox.y1) { /* Scroll up or stationary vertical.
+ Vertical order OK */
+ if (dstx <= srcBox.x1) /* Scroll left or stationary horizontal.
+ Horizontal order OK as well */
+ for (i=0; i < numRects; i++)
+ ordering[i] = i;
+ else { /* scroll right. must reverse horizontal banding of rects. */
+ for (i=0, j=1, xMax=0; i < numRects; j=i+1, xMax=i) {
+ /* find extent of current horizontal band */
+ y=boxes[i].y1; /* band has this y coordinate */
+ while ((j < numRects) && (boxes[j].y1 == y))
+ j++;
+ /* reverse the horizontal band in the output ordering */
+ for (j-- ; j >= xMax; j--, i++)
+ ordering[i] = j;
+ }
+ }
+ }
+ else { /* Scroll down. Must reverse vertical banding. */
+ if (dstx < srcBox.x1) { /* Scroll left. Horizontal order OK. */
+ for (i=numRects-1, j=i-1, yMin=i, yMax=0;
+ i >= 0;
+ j=i-1, yMin=i) {
+ /* find extent of current horizontal band */
+ y=boxes[i].y1; /* band has this y coordinate */
+ while ((j >= 0) && (boxes[j].y1 == y))
+ j--;
+ /* reverse the horizontal band in the output ordering */
+ for (j++ ; j <= yMin; j++, i--, yMax++)
+ ordering[yMax] = j;
+ }
+ }
+ else /* Scroll right or horizontal stationary.
+ Reverse horizontal order as well (if stationary, horizontal
+ order can be swapped without penalty and this is faster
+ to compute). */
+ for (i=0, j=numRects-1; i < numRects; i++, j--)
+ ordering[i] = j;
+ }
+ }
+
+ for(i = 0; i < numRects; i++)
+ {
+ prect = &boxes[ordering[i]];
+ xMin = max(prect->x1, srcBox.x1);
+ xMax = min(prect->x2, srcBox.x2);
+ yMin = max(prect->y1, srcBox.y1);
+ yMax = min(prect->y2, srcBox.y2);
+ /* is there anything visible here? */
+ if(xMax <= xMin || yMax <= yMin)
+ continue;
+
+ ppt = pptFirst;
+ pwidth = pwidthFirst;
+ y = yMin;
+ height = yMax - yMin;
+ width = xMax - xMin;
+
+ for(j = 0; j < height; j++)
+ {
+ /* We must untranslate before calling GetSpans */
+ ppt->x = xMin;
+ ppt++->y = y++;
+ *pwidth++ = width;
+ }
+ pbits = (unsigned int *)xalloc(height * PixmapBytePad(width,
+ pSrcDrawable->depth));
+ if (pbits)
+ {
+ (*pSrcDrawable->pScreen->GetSpans)(pSrcDrawable, width, pptFirst,
+ (int *)pwidthFirst, height, (char *)pbits);
+ ppt = pptFirst;
+ pwidth = pwidthFirst;
+ xMin -= (srcx - dstx);
+ y = yMin - (srcy - dsty);
+ for(j = 0; j < height; j++)
+ {
+ ppt->x = xMin;
+ ppt++->y = y++;
+ *pwidth++ = width;
+ }
+
+ (*pGC->ops->SetSpans)(pDstDrawable, pGC, (char *)pbits, pptFirst,
+ (int *)pwidthFirst, height, TRUE);
+ xfree(pbits);
+ }
+ }
+ prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, xIn, yIn,
+ widthSrc, heightSrc, xOut, yOut, (unsigned long)0);
+ if(realSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+
+ DEALLOCATE_LOCAL(ordering);
+ DEALLOCATE_LOCAL(pwidthFirst);
+ DEALLOCATE_LOCAL(pptFirst);
+ return prgnExposed;
+}
+
+/* MIGETPLANE -- gets a bitmap representing one plane of pDraw
+ * A helper used for CopyPlane and XY format GetImage
+ * No clever strategy here, we grab a scanline at a time, pull out the
+ * bits and then stuff them in a 1 bit deep map.
+ */
+/*
+ * This should be replaced with something more general. mi shouldn't have to
+ * care about such things as scanline padding et alia.
+ */
+static
+unsigned long *
+miGetPlane(pDraw, planeNum, sx, sy, w, h, result)
+ DrawablePtr pDraw;
+ int planeNum; /* number of the bitPlane */
+ int sx, sy, w, h;
+ unsigned long *result;
+{
+ int i, j, k, width, bitsPerPixel, widthInBytes;
+ DDXPointRec pt;
+ unsigned long pixel;
+ unsigned long bit;
+ unsigned char *pCharsOut;
+
+#if BITMAP_SCANLINE_UNIT == 8
+#define OUT_TYPE unsigned char
+#endif
+#if BITMAP_SCANLINE_UNIT == 16
+#define OUT_TYPE CARD16
+#endif
+#if BITMAP_SCANLINE_UNIT == 32
+#define OUT_TYPE CARD32
+#endif
+#if BITMAP_SCANLINE_UNIT == 64
+#define OUT_TYPE CARD64
+#endif
+
+ OUT_TYPE *pOut;
+ int delta;
+
+ sx += pDraw->x;
+ sy += pDraw->y;
+ widthInBytes = BitmapBytePad(w);
+ if(!result)
+ result = (unsigned long *)xalloc(h * widthInBytes);
+ if (!result)
+ return (unsigned long *)NULL;
+ bitsPerPixel = pDraw->bitsPerPixel;
+ bzero((char *)result, h * widthInBytes);
+ pOut = (OUT_TYPE *) result;
+ if(bitsPerPixel == 1)
+ {
+ pCharsOut = (unsigned char *) result;
+ width = w;
+ }
+ else
+ {
+ delta = (widthInBytes / (BITMAP_SCANLINE_UNIT / 8)) -
+ (w / BITMAP_SCANLINE_UNIT);
+ width = 1;
+#if IMAGE_BYTE_ORDER == MSBFirst
+ planeNum += (32 - bitsPerPixel);
+#endif
+ }
+ pt.y = sy;
+ for (i = h; --i >= 0; pt.y++)
+ {
+ pt.x = sx;
+ if(bitsPerPixel == 1)
+ {
+ (*pDraw->pScreen->GetSpans)(pDraw, width, &pt, &width, 1,
+ (char *)pCharsOut);
+ pCharsOut += widthInBytes;
+ }
+ else
+ {
+ k = 0;
+ for(j = w; --j >= 0; pt.x++)
+ {
+ /* Fetch the next pixel */
+ (*pDraw->pScreen->GetSpans)(pDraw, width, &pt, &width, 1,
+ (char *)&pixel);
+ /*
+ * Now get the bit and insert into a bitmap in XY format.
+ */
+ bit = (pixel >> planeNum) & 1;
+#ifndef XFree86Server
+ /* XXX assuming bit order == byte order */
+#if BITMAP_BIT_ORDER == LSBFirst
+ bit <<= k;
+#else
+ bit <<= ((BITMAP_SCANLINE_UNIT - 1) - k);
+#endif
+#else
+ /* XXX assuming byte order == LSBFirst */
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ bit <<= k;
+ else
+ bit <<= ((screenInfo.bitmapScanlineUnit - 1) -
+ (k % screenInfo.bitmapScanlineUnit)) +
+ ((k / screenInfo.bitmapScanlineUnit) *
+ screenInfo.bitmapScanlineUnit);
+#endif
+ *pOut |= (OUT_TYPE) bit;
+ k++;
+ if (k == BITMAP_SCANLINE_UNIT)
+ {
+ pOut++;
+ k = 0;
+ }
+ }
+ pOut += delta;
+ }
+ }
+ return(result);
+
+}
+
+/* MIOPQSTIPDRAWABLE -- use pbits as an opaque stipple for pDraw.
+ * Drawing through the clip mask we SetSpans() the bits into a
+ * bitmap and stipple those bits onto the destination drawable by doing a
+ * PolyFillRect over the whole drawable,
+ * then we invert the bitmap by copying it onto itself with an alu of
+ * GXinvert, invert the foreground/background colors of the gc, and draw
+ * the background bits.
+ * Note how the clipped out bits of the bitmap are always the background
+ * color so that the stipple never causes FillRect to draw them.
+ */
+void
+miOpqStipDrawable(pDraw, pGC, prgnSrc, pbits, srcx, w, h, dstx, dsty)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ RegionPtr prgnSrc;
+ unsigned long *pbits;
+ int srcx, w, h, dstx, dsty;
+{
+ int oldfill, i;
+ unsigned long oldfg;
+ int *pwidth, *pwidthFirst;
+ ChangeGCVal gcv[6];
+ PixmapPtr pStipple, pPixmap;
+ DDXPointRec oldOrg;
+ GCPtr pGCT;
+ DDXPointPtr ppt, pptFirst;
+ xRectangle rect;
+ RegionPtr prgnSrcClip;
+
+ pPixmap = (*pDraw->pScreen->CreatePixmap)
+ (pDraw->pScreen, w + srcx, h, 1);
+ if (!pPixmap)
+ return;
+
+ /* Put the image into a 1 bit deep pixmap */
+ pGCT = GetScratchGC(1, pDraw->pScreen);
+ if (!pGCT)
+ {
+ (*pDraw->pScreen->DestroyPixmap)(pPixmap);
+ return;
+ }
+ /* First set the whole pixmap to 0 */
+ gcv[0].val = 0;
+ dixChangeGC(NullClient, pGCT, GCBackground, NULL, gcv);
+ ValidateGC((DrawablePtr)pPixmap, pGCT);
+ miClearDrawable((DrawablePtr)pPixmap, pGCT);
+ ppt = pptFirst = (DDXPointPtr)ALLOCATE_LOCAL(h * sizeof(DDXPointRec));
+ pwidth = pwidthFirst = (int *)ALLOCATE_LOCAL(h * sizeof(int));
+ if(!pptFirst || !pwidthFirst)
+ {
+ if (pwidthFirst) DEALLOCATE_LOCAL(pwidthFirst);
+ if (pptFirst) DEALLOCATE_LOCAL(pptFirst);
+ FreeScratchGC(pGCT);
+ return;
+ }
+
+ /* we need a temporary region because ChangeClip must be assumed
+ to destroy what it's sent. note that this means we don't
+ have to free prgnSrcClip ourselves.
+ */
+ prgnSrcClip = REGION_CREATE(pGCT->pScreen, NULL, 0);
+ REGION_COPY(pGCT->pScreen, prgnSrcClip, prgnSrc);
+ REGION_TRANSLATE(pGCT->pScreen, prgnSrcClip, srcx, 0);
+ (*pGCT->funcs->ChangeClip)(pGCT, CT_REGION, prgnSrcClip, 0);
+ ValidateGC((DrawablePtr)pPixmap, pGCT);
+
+ /* Since we know pDraw is always a pixmap, we never need to think
+ * about translation here */
+ for(i = 0; i < h; i++)
+ {
+ ppt->x = 0;
+ ppt++->y = i;
+ *pwidth++ = w + srcx;
+ }
+
+ (*pGCT->ops->SetSpans)((DrawablePtr)pPixmap, pGCT, (char *)pbits,
+ pptFirst, pwidthFirst, h, TRUE);
+ DEALLOCATE_LOCAL(pwidthFirst);
+ DEALLOCATE_LOCAL(pptFirst);
+
+
+ /* Save current values from the client GC */
+ oldfill = pGC->fillStyle;
+ pStipple = pGC->stipple;
+ if(pStipple)
+ pStipple->refcnt++;
+ oldOrg = pGC->patOrg;
+
+ /* Set a new stipple in the drawable */
+ gcv[0].val = FillStippled;
+ gcv[1].ptr = pPixmap;
+ gcv[2].val = dstx - srcx;
+ gcv[3].val = dsty;
+
+ dixChangeGC(NullClient, pGC,
+ GCFillStyle | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin,
+ NULL, gcv);
+ ValidateGC(pDraw, pGC);
+
+ /* Fill the drawable with the stipple. This will draw the
+ * foreground color whereever 1 bits are set, leaving everything
+ * with 0 bits untouched. Note that the part outside the clip
+ * region is all 0s. */
+ rect.x = dstx;
+ rect.y = dsty;
+ rect.width = w;
+ rect.height = h;
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
+
+ /* Invert the tiling pixmap. This sets 0s for 1s and 1s for 0s, only
+ * within the clipping region, the part outside is still all 0s */
+ gcv[0].val = GXinvert;
+ dixChangeGC(NullClient, pGCT, GCFunction, NULL, gcv);
+ ValidateGC((DrawablePtr)pPixmap, pGCT);
+ (*pGCT->ops->CopyArea)((DrawablePtr)pPixmap, (DrawablePtr)pPixmap,
+ pGCT, 0, 0, w + srcx, h, 0, 0);
+
+ /* Swap foreground and background colors on the GC for the drawable.
+ * Now when we fill the drawable, we will fill in the "Background"
+ * values */
+ oldfg = pGC->fgPixel;
+ gcv[0].val = pGC->bgPixel;
+ gcv[1].val = oldfg;
+ gcv[2].ptr = pPixmap;
+ dixChangeGC(NullClient, pGC, GCForeground | GCBackground | GCStipple,
+ NULL, gcv);
+ ValidateGC(pDraw, pGC);
+ /* PolyFillRect might have bashed the rectangle */
+ rect.x = dstx;
+ rect.y = dsty;
+ rect.width = w;
+ rect.height = h;
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
+
+ /* Now put things back */
+ if(pStipple)
+ pStipple->refcnt--;
+ gcv[0].val = oldfg;
+ gcv[1].val = pGC->fgPixel;
+ gcv[2].val = oldfill;
+ gcv[3].ptr = pStipple;
+ gcv[4].val = oldOrg.x;
+ gcv[5].val = oldOrg.y;
+ dixChangeGC(NullClient, pGC,
+ GCForeground | GCBackground | GCFillStyle | GCStipple |
+ GCTileStipXOrigin | GCTileStipYOrigin, NULL, gcv);
+
+ ValidateGC(pDraw, pGC);
+ /* put what we hope is a smaller clip region back in the scratch gc */
+ (*pGCT->funcs->ChangeClip)(pGCT, CT_NONE, NULL, 0);
+ FreeScratchGC(pGCT);
+ (*pDraw->pScreen->DestroyPixmap)(pPixmap);
+
+}
+
+/* MICOPYPLANE -- public entry for the CopyPlane request.
+ * strategy:
+ * First build up a bitmap out of the bits requested
+ * build a source clip
+ * Use the bitmap we've built up as a Stipple for the destination
+ */
+RegionPtr
+miCopyPlane(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane)
+ DrawablePtr pSrcDrawable;
+ DrawablePtr pDstDrawable;
+ GCPtr pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+ unsigned long bitPlane;
+{
+ unsigned long *ptile;
+ BoxRec box;
+ RegionPtr prgnSrc, prgnExposed;
+
+ /* incorporate the source clip */
+
+ box.x1 = srcx + pSrcDrawable->x;
+ box.y1 = srcy + pSrcDrawable->y;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+ /* clip to visible drawable */
+ if (box.x1 < pSrcDrawable->x)
+ box.x1 = pSrcDrawable->x;
+ if (box.y1 < pSrcDrawable->y)
+ box.y1 = pSrcDrawable->y;
+ if (box.x2 > pSrcDrawable->x + (int) pSrcDrawable->width)
+ box.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
+ if (box.y2 > pSrcDrawable->y + (int) pSrcDrawable->height)
+ box.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
+ if (box.x1 > box.x2)
+ box.x2 = box.x1;
+ if (box.y1 > box.y2)
+ box.y2 = box.y1;
+ prgnSrc = REGION_CREATE(pGC->pScreen, &box, 1);
+
+ if (pSrcDrawable->type != DRAWABLE_PIXMAP) {
+ /* clip to visible drawable */
+
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ RegionPtr clipList = NotClippedByChildren ((WindowPtr) pSrcDrawable);
+ REGION_INTERSECT(pGC->pScreen, prgnSrc, prgnSrc, clipList);
+ REGION_DESTROY(pGC->pScreen, clipList);
+ } else
+ REGION_INTERSECT(pGC->pScreen, prgnSrc, prgnSrc,
+ &((WindowPtr)pSrcDrawable)->clipList);
+ }
+
+ box = *REGION_EXTENTS(pGC->pScreen, prgnSrc);
+ REGION_TRANSLATE(pGC->pScreen, prgnSrc, -box.x1, -box.y1);
+
+ if ((box.x2 > box.x1) && (box.y2 > box.y1))
+ {
+ /* minimize the size of the data extracted */
+ /* note that we convert the plane mask bitPlane into a plane number */
+ box.x1 -= pSrcDrawable->x;
+ box.x2 -= pSrcDrawable->x;
+ box.y1 -= pSrcDrawable->y;
+ box.y2 -= pSrcDrawable->y;
+ ptile = miGetPlane(pSrcDrawable, ffs(bitPlane) - 1,
+ box.x1, box.y1,
+ box.x2 - box.x1, box.y2 - box.y1,
+ (unsigned long *) NULL);
+ if (ptile)
+ {
+ miOpqStipDrawable(pDstDrawable, pGC, prgnSrc, ptile, 0,
+ box.x2 - box.x1, box.y2 - box.y1,
+ dstx + box.x1 - srcx, dsty + box.y1 - srcy);
+ xfree(ptile);
+ }
+ }
+ prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, srcx, srcy,
+ width, height, dstx, dsty, bitPlane);
+ REGION_DESTROY(pGC->pScreen, prgnSrc);
+ return prgnExposed;
+}
+
+/* MIGETIMAGE -- public entry for the GetImage Request
+ * We're getting the image into a memory buffer. While we have to use GetSpans
+ * to read a line from the device (since we don't know what that looks like),
+ * we can just write into the destination buffer
+ *
+ * two different strategies are used, depending on whether we're getting the
+ * image in Z format or XY format
+ * Z format:
+ * Line at a time, GetSpans a line into the destination buffer, then if the
+ * planemask is not all ones, we do a SetSpans into a temporary buffer (to get
+ * bits turned off) and then another GetSpans to get stuff back (because
+ * pixmaps are opaque, and we are passed in the memory to write into). This is
+ * pretty ugly and slow but works. Life is hard.
+ * XY format:
+ * get the single plane specified in planemask
+ */
+void
+miGetImage(pDraw, sx, sy, w, h, format, planeMask, pDst)
+ DrawablePtr pDraw;
+ int sx, sy, w, h;
+ unsigned int format;
+ unsigned long planeMask;
+ char * pDst;
+{
+ unsigned char depth;
+ int i, linelength, width, srcx, srcy;
+ DDXPointRec pt;
+ XID gcv[2];
+ PixmapPtr pPixmap = (PixmapPtr)NULL;
+ GCPtr pGC;
+
+ depth = pDraw->depth;
+ if(format == ZPixmap)
+ {
+ if ( (((1<<depth)-1)&planeMask) != (1<<depth)-1 )
+ {
+ xPoint pt;
+
+ pGC = GetScratchGC(depth, pDraw->pScreen);
+ if (!pGC)
+ return;
+ pPixmap = (*pDraw->pScreen->CreatePixmap)
+ (pDraw->pScreen, w, 1, depth);
+ if (!pPixmap)
+ {
+ FreeScratchGC(pGC);
+ return;
+ }
+ /*
+ * Clear the pixmap before doing anything else
+ */
+ ValidateGC((DrawablePtr)pPixmap, pGC);
+ pt.x = pt.y = 0;
+ (*pGC->ops->FillSpans)((DrawablePtr)pPixmap, pGC, 1, &pt, &width,
+ TRUE);
+
+ /* alu is already GXCopy */
+ gcv[0] = (XID)planeMask;
+ DoChangeGC(pGC, GCPlaneMask, gcv, 0);
+ ValidateGC((DrawablePtr)pPixmap, pGC);
+ }
+
+ linelength = PixmapBytePad(w, depth);
+ srcx = sx + pDraw->x;
+ srcy = sy + pDraw->y;
+ for(i = 0; i < h; i++)
+ {
+ pt.x = srcx;
+ pt.y = srcy + i;
+ width = w;
+ (*pDraw->pScreen->GetSpans)(pDraw, w, &pt, &width, 1, pDst);
+ if (pPixmap)
+ {
+ pt.x = 0;
+ pt.y = 0;
+ width = w;
+ (*pGC->ops->SetSpans)((DrawablePtr)pPixmap, pGC, pDst,
+ &pt, &width, 1, TRUE);
+ (*pDraw->pScreen->GetSpans)((DrawablePtr)pPixmap, w, &pt,
+ &width, 1, pDst);
+ }
+ pDst += linelength;
+ }
+ if (pPixmap)
+ {
+ (*pGC->pScreen->DestroyPixmap)(pPixmap);
+ FreeScratchGC(pGC);
+ }
+ }
+ else
+ {
+ (void) miGetPlane(pDraw, ffs(planeMask) - 1, sx, sy, w, h,
+ (unsigned long *)pDst);
+ }
+}
+
+/* MIPUTIMAGE -- public entry for the PutImage request
+ * Here we benefit from knowing the format of the bits pointed to by pImage,
+ * even if we don't know how pDraw represents them.
+ * Three different strategies are used depending on the format
+ * XYBitmap Format:
+ * we just use the Opaque Stipple helper function to cover the destination
+ * Note that this covers all the planes of the drawable with the
+ * foreground color (masked with the GC planemask) where there are 1 bits
+ * and the background color (masked with the GC planemask) where there are
+ * 0 bits
+ * XYPixmap format:
+ * what we're called with is a series of XYBitmaps, but we only want
+ * each XYPixmap to update 1 plane, instead of updating all of them.
+ * we set the foreground color to be all 1s and the background to all 0s
+ * then for each plane, we set the plane mask to only effect that one
+ * plane and recursive call ourself with the format set to XYBitmap
+ * (This clever idea courtesy of RGD.)
+ * ZPixmap format:
+ * This part is simple, just call SetSpans
+ */
+void
+miPutImage(pDraw, pGC, depth, x, y, w, h, leftPad, format, pImage)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int depth, x, y, w, h, leftPad;
+ int format;
+ char *pImage;
+{
+ DDXPointPtr pptFirst, ppt;
+ int *pwidthFirst, *pwidth;
+ RegionPtr prgnSrc;
+ BoxRec box;
+ unsigned long oldFg, oldBg;
+ XID gcv[3];
+ unsigned long oldPlanemask;
+ unsigned long i;
+ long bytesPer;
+
+ if (!w || !h)
+ return;
+ switch(format)
+ {
+ case XYBitmap:
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = w;
+ box.y2 = h;
+ prgnSrc = REGION_CREATE(pGC->pScreen, &box, 1);
+
+ miOpqStipDrawable(pDraw, pGC, prgnSrc, (unsigned long *) pImage,
+ leftPad, w, h, x, y);
+ REGION_DESTROY(pGC->pScreen, prgnSrc);
+ break;
+
+ case XYPixmap:
+ depth = pGC->depth;
+ oldPlanemask = pGC->planemask;
+ oldFg = pGC->fgPixel;
+ oldBg = pGC->bgPixel;
+ gcv[0] = (XID)~0;
+ gcv[1] = (XID)0;
+ DoChangeGC(pGC, GCForeground | GCBackground, gcv, 0);
+ bytesPer = (long)h * BitmapBytePad(w + leftPad);
+
+ for (i = 1 << (depth-1); i != 0; i >>= 1, pImage += bytesPer)
+ {
+ if (i & oldPlanemask)
+ {
+ gcv[0] = (XID)i;
+ DoChangeGC(pGC, GCPlaneMask, gcv, 0);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->PutImage)(pDraw, pGC, 1, x, y, w, h, leftPad,
+ XYBitmap, (char *)pImage);
+ }
+ }
+ gcv[0] = (XID)oldPlanemask;
+ gcv[1] = (XID)oldFg;
+ gcv[2] = (XID)oldBg;
+ DoChangeGC(pGC, GCPlaneMask | GCForeground | GCBackground, gcv, 0);
+ ValidateGC(pDraw, pGC);
+ break;
+
+ case ZPixmap:
+ ppt = pptFirst = (DDXPointPtr)ALLOCATE_LOCAL(h * sizeof(DDXPointRec));
+ pwidth = pwidthFirst = (int *)ALLOCATE_LOCAL(h * sizeof(int));
+ if(!pptFirst || !pwidthFirst)
+ {
+ if (pwidthFirst)
+ DEALLOCATE_LOCAL(pwidthFirst);
+ if (pptFirst)
+ DEALLOCATE_LOCAL(pptFirst);
+ return;
+ }
+ if (pGC->miTranslate)
+ {
+ x += pDraw->x;
+ y += pDraw->y;
+ }
+
+ for(i = 0; i < h; i++)
+ {
+ ppt->x = x;
+ ppt->y = y + i;
+ ppt++;
+ *pwidth++ = w;
+ }
+
+ (*pGC->ops->SetSpans)(pDraw, pGC, (char *)pImage, pptFirst,
+ pwidthFirst, h, TRUE);
+ DEALLOCATE_LOCAL(pwidthFirst);
+ DEALLOCATE_LOCAL(pptFirst);
+ break;
+ }
+}
diff --git a/xc/programs/Xserver/mi/mibstore.c b/xc/programs/Xserver/mi/mibstore.c
new file mode 100644
index 000000000..39712e238
--- /dev/null
+++ b/xc/programs/Xserver/mi/mibstore.c
@@ -0,0 +1,3810 @@
+/* $TOG: mibstore.c /main/95 1998/02/09 14:46:13 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by the Regents of the University of California
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted, provided
+that the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name The Open Group not be used in advertising or publicity
+pertaining to distribution of the software without specific, written prior
+permission.
+
+The University of California makes no representations about the suitability
+of this software for any purpose. It is provided "as is" without express or
+implied warranty.
+
+******************************************************************/
+
+/* $XFree86: xc/programs/Xserver/mi/mibstore.c,v 1.4 1998/12/20 11:57:57 dawes Exp $ */
+
+#define NEED_EVENTS
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "extnsionst.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "dixstruct.h" /* For requestingClient */
+#include "mi.h"
+#include "mibstorest.h"
+
+/*
+ * When the server fails to allocate a backing store pixmap, if you want
+ * it to dynamically retry to allocate backing store on every subsequent
+ * graphics op, you can enable BSEAGER; otherwise, backing store will be
+ * disabled on the window until it is unmapped and then remapped.
+ */
+/* #define BSEAGER */
+
+/*-
+ * NOTES ON USAGE:
+ *
+ * The functions in this file implement a machine-independent backing-store
+ * scheme. To use it, the output library must do the following:
+ * - Provide a SaveAreas function that takes a destination pixmap, a
+ * region of the areas to save (in the pixmap's coordinate system)
+ * and the screen origin of the region. It should copy the areas from
+ * the screen into the pixmap.
+ * - Provide a RestoreAreas function that takes a source pixmap, a region
+ * of the areas to restore (in the screen's coordinate system) and the
+ * origin of the pixmap on the screen. It should copy the areas from
+ * the pixmap into the screen.
+ * - Provide a SetClipmaskRgn function that takes a gc and a region
+ * and merges the region into any CT_PIXMAP client clip that
+ * is specified in the GC. This routine is only needed if
+ * miValidateBackingStore will see CT_PIXMAP clip lists; not
+ * true for any of the sample servers (which convert the PIXMAP
+ * clip lists into CT_REGION clip lists; an expensive but simple
+ * to code option).
+ * - The function placed in a window's ClearToBackground vector must call
+ * pScreen->ClearBackingStore with the window, followed by
+ * the window-relative x and y coordinates, followed by the width and
+ * height of the area to be cleared, followed by the generateExposures
+ * flag. This has been taken care of in miClearToBackground.
+ * - Whatever determines GraphicsExpose events for the CopyArea and
+ * CopyPlane requests should call pWin->backStorage->ExposeCopy
+ * with the source and destination drawables, the GC used, a source-
+ * window-relative region of exposed areas, the source and destination
+ * coordinates and the bitplane copied, if CopyPlane, or 0, if
+ * CopyArea.
+ *
+ * JUSTIFICATION
+ * This is a cross between saving everything and just saving the
+ * obscued areas (as in Pike's layers.) This method has the advantage
+ * of only doing each output operation once per pixel, visible or
+ * invisible, and avoids having to do all the crufty storage
+ * management of keeping several separate rectangles. Since the
+ * ddx layer ouput primitives are required to draw through clipping
+ * rectangles anyway, sending multiple drawing requests for each of
+ * several rectangles isn't necessary. (Of course, it could be argued
+ * that the ddx routines should just take one rectangle each and
+ * get called multiple times, but that would make taking advantage of
+ * smart hardware harder, and probably be slower as well.)
+ */
+
+#define SETUP_BACKING_TERSE(pGC) \
+ miBSGCPtr pGCPrivate = (miBSGCPtr)(pGC)->devPrivates[miBSGCIndex].ptr; \
+ GCFuncs *oldFuncs = pGC->funcs;
+
+#define SETUP_BACKING(pDrawable,pGC) \
+ miBSWindowPtr pBackingStore = \
+ (miBSWindowPtr)((WindowPtr)(pDrawable))->backStorage; \
+ DrawablePtr pBackingDrawable = (DrawablePtr) \
+ pBackingStore->pBackingPixmap; \
+ SETUP_BACKING_TERSE(pGC) \
+ GCPtr pBackingGC = pGCPrivate->pBackingGC;
+
+#define PROLOGUE(pGC) { \
+ pGC->ops = pGCPrivate->wrapOps;\
+ pGC->funcs = pGCPrivate->wrapFuncs; \
+ }
+
+#define EPILOGUE(pGC) { \
+ pGCPrivate->wrapOps = (pGC)->ops; \
+ (pGC)->ops = &miBSGCOps; \
+ (pGC)->funcs = oldFuncs; \
+ }
+
+static void miCreateBSPixmap();
+static void miDestroyBSPixmap();
+static void miTileVirtualBS();
+static void miBSAllocate(), miBSFree();
+static Bool miBSCreateGCPrivate ();
+static void miBSClearBackingRegion ();
+
+#define MoreCopy0 ;
+#define MoreCopy2 *dstCopy++ = *srcCopy++; *dstCopy++ = *srcCopy++;
+#define MoreCopy4 MoreCopy2 MoreCopy2
+
+#define copyData(src,dst,n,morecopy) \
+{ \
+ register short *srcCopy = (short *)(src); \
+ register short *dstCopy = (short *)(dst); \
+ register int i; \
+ register int bsx = pBackingStore->x; \
+ register int bsy = pBackingStore->y; \
+ for (i = n; --i >= 0; ) \
+ { \
+ *dstCopy++ = *srcCopy++ - bsx; \
+ *dstCopy++ = *srcCopy++ - bsy; \
+ morecopy \
+ } \
+}
+
+#define copyPoints(src,dst,n,mode) \
+if (mode == CoordModeOrigin) \
+{ \
+ copyData(src,dst,n,MoreCopy0); \
+} \
+else \
+{ \
+ memmove((char *)(dst), (char *)(src), (n) << 2); \
+ *((short *)(dst)) -= pBackingStore->x; \
+ *((short *)(dst) + 1) -= pBackingStore->y; \
+}
+
+/*
+ * wrappers for screen funcs
+ */
+
+static int miBSScreenIndex;
+static unsigned long miBSGeneration = 0;
+
+static Bool miBSCloseScreen();
+static void miBSGetImage();
+static void miBSGetSpans();
+static Bool miBSChangeWindowAttributes();
+static Bool miBSCreateGC();
+static Bool miBSDestroyWindow();
+
+/*
+ * backing store screen functions
+ */
+
+static void miBSSaveDoomedAreas();
+static RegionPtr miBSRestoreAreas();
+static void miBSExposeCopy();
+static RegionPtr miBSTranslateBackingStore(), miBSClearBackingStore();
+static void miBSDrawGuarantee();
+
+/*
+ * wrapper vectors for GC funcs and ops
+ */
+
+static int miBSGCIndex;
+
+static void miBSValidateGC (), miBSCopyGC (), miBSDestroyGC();
+static void miBSChangeGC();
+static void miBSChangeClip(), miBSDestroyClip(), miBSCopyClip();
+
+static GCFuncs miBSGCFuncs = {
+ miBSValidateGC,
+ miBSChangeGC,
+ miBSCopyGC,
+ miBSDestroyGC,
+ miBSChangeClip,
+ miBSDestroyClip,
+ miBSCopyClip,
+};
+
+static void miBSFillSpans(), miBSSetSpans(), miBSPutImage();
+static RegionPtr miBSCopyArea(), miBSCopyPlane();
+static void miBSPolyPoint(), miBSPolylines(), miBSPolySegment();
+static void miBSPolyRectangle(),miBSPolyArc(), miBSFillPolygon();
+static void miBSPolyFillRect(), miBSPolyFillArc();
+static int miBSPolyText8(), miBSPolyText16();
+static void miBSImageText8(), miBSImageText16();
+static void miBSImageGlyphBlt(),miBSPolyGlyphBlt();
+static void miBSPushPixels();
+#ifdef NEED_LINEHELPER
+static void miBSLineHelper();
+#endif
+
+static GCOps miBSGCOps = {
+ miBSFillSpans, miBSSetSpans, miBSPutImage,
+ miBSCopyArea, miBSCopyPlane, miBSPolyPoint,
+ miBSPolylines, miBSPolySegment, miBSPolyRectangle,
+ miBSPolyArc, miBSFillPolygon, miBSPolyFillRect,
+ miBSPolyFillArc, miBSPolyText8, miBSPolyText16,
+ miBSImageText8, miBSImageText16, miBSImageGlyphBlt,
+ miBSPolyGlyphBlt, miBSPushPixels
+#ifdef NEED_LINEHELPER
+ , miBSLineHelper
+#endif
+};
+
+#define FUNC_PROLOGUE(pGC, pPriv) \
+ ((pGC)->funcs = pPriv->wrapFuncs),\
+ ((pGC)->ops = pPriv->wrapOps)
+
+#define FUNC_EPILOGUE(pGC, pPriv) \
+ ((pGC)->funcs = &miBSGCFuncs),\
+ ((pGC)->ops = &miBSGCOps)
+
+/*
+ * every GC in the server is initially wrapped with these
+ * "cheap" functions. This allocates no memory and is used
+ * to discover GCs used with windows which have backing
+ * store enabled
+ */
+
+static void miBSCheapValidateGC(), miBSCheapCopyGC(), miBSCheapDestroyGC();
+static void miBSCheapChangeGC ();
+static void miBSCheapChangeClip(), miBSCheapDestroyClip();
+static void miBSCheapCopyClip();
+
+static GCFuncs miBSCheapGCFuncs = {
+ miBSCheapValidateGC,
+ miBSCheapChangeGC,
+ miBSCheapCopyGC,
+ miBSCheapDestroyGC,
+ miBSCheapChangeClip,
+ miBSCheapDestroyClip,
+ miBSCheapCopyClip,
+};
+
+#define CHEAP_FUNC_PROLOGUE(pGC) \
+ ((pGC)->funcs = (GCFuncs *) (pGC)->devPrivates[miBSGCIndex].ptr)
+
+#define CHEAP_FUNC_EPILOGUE(pGC) \
+ ((pGC)->funcs = &miBSCheapGCFuncs)
+
+/*
+ * called from device screen initialization proc. Gets a GCPrivateIndex
+ * and wraps appropriate per-screen functions. pScreen->BackingStoreFuncs
+ * must be previously initialized.
+ */
+
+void
+miInitializeBackingStore (pScreen)
+ ScreenPtr pScreen;
+{
+ miBSScreenPtr pScreenPriv;
+
+ if (miBSGeneration != serverGeneration)
+ {
+ miBSScreenIndex = AllocateScreenPrivateIndex ();
+ if (miBSScreenIndex < 0)
+ return;
+ miBSGCIndex = AllocateGCPrivateIndex ();
+ miBSGeneration = serverGeneration;
+ }
+ if (!AllocateGCPrivate(pScreen, miBSGCIndex, 0))
+ return;
+ pScreenPriv = (miBSScreenPtr) xalloc (sizeof (miBSScreenRec));
+ if (!pScreenPriv)
+ return;
+
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreenPriv->GetImage = pScreen->GetImage;
+ pScreenPriv->GetSpans = pScreen->GetSpans;
+ pScreenPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
+ pScreenPriv->CreateGC = pScreen->CreateGC;
+ pScreenPriv->DestroyWindow = pScreen->DestroyWindow;
+
+ pScreen->CloseScreen = miBSCloseScreen;
+ pScreen->GetImage = miBSGetImage;
+ pScreen->GetSpans = miBSGetSpans;
+ pScreen->ChangeWindowAttributes = miBSChangeWindowAttributes;
+ pScreen->CreateGC = miBSCreateGC;
+ pScreen->DestroyWindow = miBSDestroyWindow;
+
+ pScreen->SaveDoomedAreas = miBSSaveDoomedAreas;
+ pScreen->RestoreAreas = miBSRestoreAreas;
+ pScreen->ExposeCopy = miBSExposeCopy;
+ pScreen->TranslateBackingStore = miBSTranslateBackingStore;
+ pScreen->ClearBackingStore = miBSClearBackingStore;
+ pScreen->DrawGuarantee = miBSDrawGuarantee;
+
+ pScreen->devPrivates[miBSScreenIndex].ptr = (pointer) pScreenPriv;
+}
+
+/*
+ * Screen function wrappers
+ */
+
+#define SCREEN_PROLOGUE(pScreen, field)\
+ ((pScreen)->field = \
+ ((miBSScreenPtr) \
+ (pScreen)->devPrivates[miBSScreenIndex].ptr)->field)
+
+#define SCREEN_EPILOGUE(pScreen, field, wrapper)\
+ ((pScreen)->field = wrapper)
+
+/*
+ * CloseScreen wrapper -- unwrap everything, free the private data
+ * and call the wrapped function
+ */
+
+static Bool
+miBSCloseScreen (i, pScreen)
+ int i;
+ ScreenPtr pScreen;
+{
+ miBSScreenPtr pScreenPriv;
+
+ pScreenPriv = (miBSScreenPtr) pScreen->devPrivates[miBSScreenIndex].ptr;
+
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ pScreen->GetImage = pScreenPriv->GetImage;
+ pScreen->GetSpans = pScreenPriv->GetSpans;
+ pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes;
+ pScreen->CreateGC = pScreenPriv->CreateGC;
+
+ xfree ((pointer) pScreenPriv);
+
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+static void miBSFillVirtualBits();
+
+static void
+miBSGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine)
+ DrawablePtr pDrawable;
+ int sx, sy, w, h;
+ unsigned int format;
+ unsigned long planemask;
+ char *pdstLine;
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ BoxRec bounds;
+ unsigned char depth;
+
+ SCREEN_PROLOGUE (pScreen, GetImage);
+
+ if (pDrawable->type != DRAWABLE_PIXMAP &&
+ ((WindowPtr) pDrawable)->visibility != VisibilityUnobscured)
+ {
+ PixmapPtr pPixmap;
+ miBSWindowPtr pWindowPriv;
+ GCPtr pGC;
+ WindowPtr pWin, pSrcWin;
+ int xoff, yoff;
+ RegionRec Remaining;
+ RegionRec Border;
+ RegionRec Inside;
+ BoxPtr pBox;
+ int n;
+
+ pWin = (WindowPtr) pDrawable;
+ pPixmap = 0;
+ depth = pDrawable->depth;
+ bounds.x1 = sx + pDrawable->x;
+ bounds.y1 = sy + pDrawable->y;
+ bounds.x2 = bounds.x1 + w;
+ bounds.y2 = bounds.y1 + h;
+ REGION_INIT(pScreen, &Remaining, &bounds, 0);
+ for (;;)
+ {
+ bounds.x1 = sx + pDrawable->x - pWin->drawable.x;
+ bounds.y1 = sy + pDrawable->y - pWin->drawable.y;
+ bounds.x2 = bounds.x1 + w;
+ bounds.y2 = bounds.y1 + h;
+ if (pWin->viewable && pWin->backStorage &&
+ pWin->drawable.depth == depth &&
+ (RECT_IN_REGION(pScreen, &(pWindowPriv =
+ (miBSWindowPtr) pWin->backStorage)->SavedRegion,
+ &bounds) != rgnOUT ||
+ RECT_IN_REGION(pScreen, &Remaining,
+ REGION_EXTENTS(pScreen, &pWin->borderSize)) != rgnOUT))
+ {
+ if (!pPixmap)
+ {
+ XID subWindowMode = IncludeInferiors;
+ int x, y;
+
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, depth);
+ if (!pPixmap)
+ goto punt;
+ pGC = GetScratchGC (depth, pScreen);
+ if (!pGC)
+ {
+ (*pScreen->DestroyPixmap) (pPixmap);
+ goto punt;
+ }
+ ChangeGC (pGC, GCSubwindowMode, &subWindowMode);
+ ValidateGC ((DrawablePtr)pPixmap, pGC);
+ REGION_INIT(pScreen, &Border, NullBox, 0);
+ REGION_INIT(pScreen, &Inside, NullBox, 0);
+ pSrcWin = (WindowPtr) pDrawable;
+ x = sx;
+ y = sy;
+ if (pSrcWin->parent)
+ {
+ x += pSrcWin->origin.x;
+ y += pSrcWin->origin.y;
+ pSrcWin = pSrcWin->parent;
+ }
+ (*pGC->ops->CopyArea) ((DrawablePtr)pSrcWin,
+ (DrawablePtr)pPixmap, pGC,
+ x, y, w, h,
+ 0, 0);
+ REGION_SUBTRACT(pScreen, &Remaining, &Remaining,
+ &((WindowPtr) pDrawable)->borderClip);
+ }
+
+ REGION_INTERSECT(pScreen, &Inside, &Remaining, &pWin->winSize);
+ REGION_TRANSLATE(pScreen, &Inside,
+ -pWin->drawable.x,
+ -pWin->drawable.y);
+ REGION_INTERSECT(pScreen, &Inside, &Inside,
+ &pWindowPriv->SavedRegion);
+
+ /* offset of sub-window in GetImage pixmap */
+ xoff = pWin->drawable.x - pDrawable->x - sx;
+ yoff = pWin->drawable.y - pDrawable->y - sy;
+
+ if (REGION_NUM_RECTS(&Inside) > 0)
+ {
+ switch (pWindowPriv->status)
+ {
+ case StatusContents:
+ pBox = REGION_RECTS(&Inside);
+ for (n = REGION_NUM_RECTS(&Inside); --n >= 0;)
+ {
+ (*pGC->ops->CopyArea) (
+ (DrawablePtr)pWindowPriv->pBackingPixmap,
+ (DrawablePtr)pPixmap, pGC,
+ pBox->x1 - pWindowPriv->x,
+ pBox->y1 - pWindowPriv->y,
+ pBox->x2 - pBox->x1,
+ pBox->y2 - pBox->y1,
+ pBox->x1 + xoff,
+ pBox->y1 + yoff);
+ ++pBox;
+ }
+ break;
+ case StatusVirtual:
+ case StatusVDirty:
+ if (pWindowPriv->backgroundState == BackgroundPixmap ||
+ pWindowPriv->backgroundState == BackgroundPixel)
+ miBSFillVirtualBits ((DrawablePtr) pPixmap, pGC, &Inside,
+ xoff, yoff,
+ (int) pWindowPriv->backgroundState,
+ pWindowPriv->background, ~0L);
+ break;
+ }
+ }
+ REGION_SUBTRACT(pScreen, &Border, &pWin->borderSize,
+ &pWin->winSize);
+ REGION_INTERSECT(pScreen, &Border, &Border, &Remaining);
+ if (REGION_NUM_RECTS(&Border) > 0)
+ {
+ REGION_TRANSLATE(pScreen, &Border, -pWin->drawable.x,
+ -pWin->drawable.y);
+ miBSFillVirtualBits ((DrawablePtr) pPixmap, pGC, &Border,
+ xoff, yoff,
+ pWin->borderIsPixel ? (int)BackgroundPixel : (int)BackgroundPixmap,
+ pWin->border, ~0L);
+ }
+ }
+
+ if (pWin->viewable && pWin->firstChild)
+ pWin = pWin->firstChild;
+ else
+ {
+ while (!pWin->nextSib && pWin != (WindowPtr) pDrawable)
+ pWin = pWin->parent;
+ if (pWin == (WindowPtr) pDrawable)
+ break;
+ pWin = pWin->nextSib;
+ }
+ }
+
+ REGION_UNINIT(pScreen, &Remaining);
+
+ if (pPixmap)
+ {
+ REGION_UNINIT(pScreen, &Border);
+ REGION_UNINIT(pScreen, &Inside);
+ (*pScreen->GetImage) ((DrawablePtr) pPixmap,
+ 0, 0, w, h, format, planemask, pdstLine);
+ (*pScreen->DestroyPixmap) (pPixmap);
+ FreeScratchGC (pGC);
+ }
+ else
+ {
+ goto punt;
+ }
+ }
+ else
+ {
+punt: ;
+ (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
+ format, planemask, pdstLine);
+ }
+
+ SCREEN_EPILOGUE (pScreen, GetImage, miBSGetImage);
+}
+
+static void
+miBSGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart)
+ DrawablePtr pDrawable;
+ int wMax;
+ DDXPointPtr ppt;
+ int *pwidth;
+ int nspans;
+ char *pdstStart;
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ BoxRec bounds;
+ int i;
+ WindowPtr pWin;
+ int dx, dy;
+
+ SCREEN_PROLOGUE (pScreen, GetSpans);
+
+ if (pDrawable->type != DRAWABLE_PIXMAP && ((WindowPtr) pDrawable)->backStorage)
+ {
+ PixmapPtr pPixmap;
+ miBSWindowPtr pWindowPriv;
+ GCPtr pGC;
+
+ pWin = (WindowPtr) pDrawable;
+ pWindowPriv = (miBSWindowPtr) pWin->backStorage;
+ pPixmap = pWindowPriv->pBackingPixmap;
+
+ bounds.x1 = ppt->x;
+ bounds.y1 = ppt->y;
+ bounds.x2 = bounds.x1 + *pwidth;
+ bounds.y2 = ppt->y;
+ for (i = 0; i < nspans; i++)
+ {
+ if (ppt[i].x < bounds.x1)
+ bounds.x1 = ppt[i].x;
+ if (ppt[i].x + pwidth[i] > bounds.x2)
+ bounds.x2 = ppt[i].x + pwidth[i];
+ if (ppt[i].y < bounds.y1)
+ bounds.y1 = ppt[i].y;
+ else if (ppt[i].y > bounds.y2)
+ bounds.y2 = ppt[i].y;
+ }
+
+ switch (RECT_IN_REGION(pScreen, &pWindowPriv->SavedRegion, &bounds))
+ {
+ case rgnPART:
+ if (!pPixmap)
+ {
+ miCreateBSPixmap (pWin, NullBox);
+ if (!(pPixmap = pWindowPriv->pBackingPixmap))
+ break;
+ }
+ pWindowPriv->status = StatusNoPixmap;
+ pGC = GetScratchGC(pPixmap->drawable.depth,
+ pPixmap->drawable.pScreen);
+ if (pGC)
+ {
+ ValidateGC ((DrawablePtr) pPixmap, pGC);
+ (*pGC->ops->CopyArea)
+ (pDrawable, (DrawablePtr) pPixmap, pGC,
+ bounds.x1, bounds.y1,
+ bounds.x2 - bounds.x1, bounds.y2 - bounds.y1,
+ bounds.x1 + pPixmap->drawable.x - pWin->drawable.x -
+ pWindowPriv->x,
+ bounds.y1 + pPixmap->drawable.y - pWin->drawable.y -
+ pWindowPriv->y);
+ FreeScratchGC(pGC);
+ }
+ pWindowPriv->status = StatusContents;
+ /* fall through */
+ case rgnIN:
+ if (!pPixmap)
+ {
+ miCreateBSPixmap (pWin, NullBox);
+ if (!(pPixmap = pWindowPriv->pBackingPixmap))
+ break;
+ }
+ dx = pPixmap->drawable.x - pWin->drawable.x - pWindowPriv->x;
+ dy = pPixmap->drawable.y - pWin->drawable.y - pWindowPriv->y;
+ for (i = 0; i < nspans; i++)
+ {
+ ppt[i].x += dx;
+ ppt[i].y += dy;
+ }
+ (*pScreen->GetSpans) ((DrawablePtr) pPixmap, wMax, ppt, pwidth,
+ nspans, pdstStart);
+ break;
+ case rgnOUT:
+ (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans,
+ pdstStart);
+ break;
+ }
+ }
+ else
+ {
+ (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+ }
+
+ SCREEN_EPILOGUE (pScreen, GetSpans, miBSGetSpans);
+}
+
+static Bool
+miBSChangeWindowAttributes (pWin, mask)
+ WindowPtr pWin;
+ unsigned long mask;
+{
+ ScreenPtr pScreen;
+ Bool ret;
+
+ pScreen = pWin->drawable.pScreen;
+
+ SCREEN_PROLOGUE (pScreen, ChangeWindowAttributes);
+
+ ret = (*pScreen->ChangeWindowAttributes) (pWin, mask);
+
+ if (ret && (mask & CWBackingStore))
+ {
+ if (pWin->backingStore != NotUseful || pWin->DIXsaveUnder)
+ miBSAllocate (pWin);
+ else
+ miBSFree (pWin);
+ }
+
+ SCREEN_EPILOGUE (pScreen, ChangeWindowAttributes, miBSChangeWindowAttributes);
+
+ return ret;
+}
+
+/*
+ * GC Create wrapper. Set up the cheap GC func wrappers to track
+ * GC validation on BackingStore windows
+ */
+
+static Bool
+miBSCreateGC (pGC)
+ GCPtr pGC;
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ Bool ret;
+
+ SCREEN_PROLOGUE (pScreen, CreateGC);
+
+ if ( (ret = (*pScreen->CreateGC) (pGC)) )
+ {
+ pGC->devPrivates[miBSGCIndex].ptr = (pointer) pGC->funcs;
+ pGC->funcs = &miBSCheapGCFuncs;
+ }
+
+ SCREEN_EPILOGUE (pScreen, CreateGC, miBSCreateGC);
+
+ return ret;
+}
+
+static Bool
+miBSDestroyWindow (pWin)
+ WindowPtr pWin;
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ Bool ret;
+
+ SCREEN_PROLOGUE (pScreen, DestroyWindow);
+
+ ret = (*pScreen->DestroyWindow) (pWin);
+
+ miBSFree (pWin);
+
+ SCREEN_EPILOGUE (pScreen, DestroyWindow, miBSDestroyWindow);
+
+ return ret;
+}
+
+/*
+ * cheap GC func wrappers. Simply track validation on windows
+ * with backing store to enable the real func/op wrappers
+ */
+
+static void
+miBSCheapValidateGC (pGC, stateChanges, pDrawable)
+ GCPtr pGC;
+ unsigned long stateChanges;
+ DrawablePtr pDrawable;
+{
+ CHEAP_FUNC_PROLOGUE (pGC);
+
+ if (pDrawable->type != DRAWABLE_PIXMAP &&
+ ((WindowPtr) pDrawable)->backStorage != NULL &&
+ miBSCreateGCPrivate (pGC))
+ {
+ (*pGC->funcs->ValidateGC) (pGC, stateChanges, pDrawable);
+ }
+ else
+ {
+ (*pGC->funcs->ValidateGC) (pGC, stateChanges, pDrawable);
+
+ /* rewrap funcs as Validate may have changed them */
+ pGC->devPrivates[miBSGCIndex].ptr = (pointer) pGC->funcs;
+
+ CHEAP_FUNC_EPILOGUE (pGC);
+ }
+}
+
+static void
+miBSCheapChangeGC (pGC, mask)
+ GCPtr pGC;
+ unsigned long mask;
+{
+ CHEAP_FUNC_PROLOGUE (pGC);
+
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+
+ CHEAP_FUNC_EPILOGUE (pGC);
+}
+
+static void
+miBSCheapCopyGC (pGCSrc, mask, pGCDst)
+ GCPtr pGCSrc, pGCDst;
+ unsigned long mask;
+{
+ CHEAP_FUNC_PROLOGUE (pGCDst);
+
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+
+ CHEAP_FUNC_EPILOGUE (pGCDst);
+}
+
+static void
+miBSCheapDestroyGC (pGC)
+ GCPtr pGC;
+{
+ CHEAP_FUNC_PROLOGUE (pGC);
+
+ (*pGC->funcs->DestroyGC) (pGC);
+
+ /* leave it unwrapped */
+}
+
+static void
+miBSCheapChangeClip (pGC, type, pvalue, nrects)
+ GCPtr pGC;
+ int type;
+ pointer pvalue;
+ int nrects;
+{
+ CHEAP_FUNC_PROLOGUE (pGC);
+
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+
+ CHEAP_FUNC_EPILOGUE (pGC);
+}
+
+static void
+miBSCheapCopyClip(pgcDst, pgcSrc)
+ GCPtr pgcDst, pgcSrc;
+{
+ CHEAP_FUNC_PROLOGUE (pgcDst);
+
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+
+ CHEAP_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+miBSCheapDestroyClip(pGC)
+ GCPtr pGC;
+{
+ CHEAP_FUNC_PROLOGUE (pGC);
+
+ (* pGC->funcs->DestroyClip)(pGC);
+
+ CHEAP_FUNC_EPILOGUE (pGC);
+}
+
+/*
+ * create the full func/op wrappers for a GC
+ */
+
+static Bool
+miBSCreateGCPrivate (pGC)
+ GCPtr pGC;
+{
+ miBSGCRec *pPriv;
+
+ pPriv = (miBSGCRec *) xalloc (sizeof (miBSGCRec));
+ if (!pPriv)
+ return FALSE;
+ pPriv->pBackingGC = NULL;
+ pPriv->guarantee = GuaranteeNothing;
+ pPriv->serialNumber = 0;
+ pPriv->stateChanges = (1 << (GCLastBit + 1)) - 1;
+ pPriv->wrapOps = pGC->ops;
+ pPriv->wrapFuncs = pGC->funcs;
+ pGC->funcs = &miBSGCFuncs;
+ pGC->ops = &miBSGCOps;
+ pGC->devPrivates[miBSGCIndex].ptr = (pointer) pPriv;
+ return TRUE;
+}
+
+static void
+miBSDestroyGCPrivate (pGC)
+ GCPtr pGC;
+{
+ miBSGCRec *pPriv;
+
+ pPriv = (miBSGCRec *) pGC->devPrivates[miBSGCIndex].ptr;
+ if (pPriv)
+ {
+ pGC->devPrivates[miBSGCIndex].ptr = (pointer) pPriv->wrapFuncs;
+ pGC->funcs = &miBSCheapGCFuncs;
+ pGC->ops = pPriv->wrapOps;
+ if (pPriv->pBackingGC)
+ FreeGC (pPriv->pBackingGC, (GContext) 0);
+ xfree ((pointer) pPriv);
+ }
+}
+
+/*
+ * GC ops -- wrap each GC operation with our own function
+ */
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSFillSpans --
+ * Perform a FillSpans, routing output to backing-store as needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSFillSpans(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ DDXPointPtr pptCopy, pptReset;
+ int *pwidthCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pptCopy = (DDXPointPtr)ALLOCATE_LOCAL(nInit*sizeof(DDXPointRec));
+ pwidthCopy=(int *)ALLOCATE_LOCAL(nInit*sizeof(int));
+ if (pptCopy && pwidthCopy)
+ {
+ copyData(pptInit, pptCopy, nInit, MoreCopy0);
+ memmove((char *)pwidthCopy,(char *)pwidthInit,nInit*sizeof(int));
+
+ (* pGC->ops->FillSpans)(pDrawable, pGC, nInit, pptInit,
+ pwidthInit, fSorted);
+ if (pGC->miTranslate)
+ {
+ int dx, dy;
+ int nReset;
+
+ pptReset = pptCopy;
+ dx = pDrawable->x - pBackingDrawable->x;
+ dy = pDrawable->y - pBackingDrawable->y;
+ nReset = nInit;
+ while (nReset--)
+ {
+ pptReset->x -= dx;
+ pptReset->y -= dy;
+ ++pptReset;
+ }
+ }
+ (* pBackingGC->ops->FillSpans)(pBackingDrawable,
+ pBackingGC, nInit, pptCopy, pwidthCopy,
+ fSorted);
+ }
+ if (pwidthCopy) DEALLOCATE_LOCAL(pwidthCopy);
+ if (pptCopy) DEALLOCATE_LOCAL(pptCopy);
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSSetSpans --
+ * Perform a SetSpans, routing output to backing-store as needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ char *psrc;
+ register DDXPointPtr ppt;
+ int *pwidth;
+ int nspans;
+ int fSorted;
+{
+ DDXPointPtr pptCopy, pptReset;
+ int *pwidthCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pptCopy = (DDXPointPtr)ALLOCATE_LOCAL(nspans*sizeof(DDXPointRec));
+ pwidthCopy=(int *)ALLOCATE_LOCAL(nspans*sizeof(int));
+ if (pptCopy && pwidthCopy)
+ {
+ copyData(ppt, pptCopy, nspans, MoreCopy0);
+ memmove((char *)pwidthCopy,(char *)pwidth,nspans*sizeof(int));
+
+ (* pGC->ops->SetSpans)(pDrawable, pGC, psrc, ppt, pwidth,
+ nspans, fSorted);
+ if (pGC->miTranslate)
+ {
+ int dx, dy;
+ int nReset;
+
+ pptReset = pptCopy;
+ dx = pDrawable->x - pBackingDrawable->x;
+ dy = pDrawable->y - pBackingDrawable->y;
+ nReset = nspans;
+ while (nReset--)
+ {
+ pptReset->x -= dx;
+ pptReset->y -= dy;
+ ++pptReset;
+ }
+ }
+ (* pBackingGC->ops->SetSpans)(pBackingDrawable, pBackingGC,
+ psrc, pptCopy, pwidthCopy, nspans, fSorted);
+ }
+ if (pwidthCopy) DEALLOCATE_LOCAL(pwidthCopy);
+ if (pptCopy) DEALLOCATE_LOCAL(pptCopy);
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPutImage --
+ * Perform a PutImage, routing output to backing-store as needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int depth;
+ int x;
+ int y;
+ int w;
+ int h;
+ int leftPad;
+ int format;
+ char *pBits;
+{
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ (*pGC->ops->PutImage)(pDrawable, pGC,
+ depth, x, y, w, h, leftPad, format, pBits);
+ (*pBackingGC->ops->PutImage)(pBackingDrawable, pBackingGC,
+ depth, x - pBackingStore->x, y - pBackingStore->y,
+ w, h, leftPad, format, pBits);
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSDoCopy --
+ * Perform a CopyArea or CopyPlane within a window that has backing
+ * store enabled.
+ *
+ * Results:
+ * TRUE if the copy was performed or FALSE if a regular one should
+ * be done.
+ *
+ * Side Effects:
+ * Things are copied (no s***!)
+ *
+ * Notes:
+ * The idea here is to form two regions that cover the source box.
+ * One contains the exposed rectangles while the other contains
+ * the obscured ones. An array of <box, drawable> pairs is then
+ * formed where the <box> indicates the area to be copied and the
+ * <drawable> indicates from where it is to be copied (exposed regions
+ * come from the screen while obscured ones come from the backing
+ * pixmap). The array 'sequence' is then filled with the indices of
+ * the pairs in the order in which they should be copied to prevent
+ * things from getting screwed up. A call is also made through the
+ * backingGC to take care of any copying into the backing pixmap.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Bool
+miBSDoCopy(pWin, pGC, srcx, srcy, w, h, dstx, dsty, plane, copyProc, ppRgn)
+ WindowPtr pWin; /* Window being scrolled */
+ GCPtr pGC; /* GC we're called through */
+ int srcx; /* X of source rectangle */
+ int srcy; /* Y of source rectangle */
+ int w; /* Width of source rectangle */
+ int h; /* Height of source rectangle */
+ int dstx; /* X of destination rectangle */
+ int dsty; /* Y of destination rectangle */
+ unsigned long plane; /* Plane to copy (0 for CopyArea) */
+ RegionPtr (*copyProc)(); /* Procedure to call to perform the copy */
+ RegionPtr *ppRgn; /* resultant Graphics Expose region */
+{
+ RegionPtr pRgnExp; /* Exposed region */
+ RegionPtr pRgnObs; /* Obscured region */
+ BoxRec box; /* Source box (screen coord) */
+ struct BoxDraw {
+ BoxPtr pBox; /* Source box */
+ enum {
+ win, pix
+ } source; /* Place from which to copy */
+ } *boxes; /* Array of box/drawable pairs covering
+ * source box. */
+ int *sequence; /* Sequence of boxes to move */
+ register int i, j, k, l, y;
+ register BoxPtr pBox;
+ int dx, dy, nrects;
+ Bool graphicsExposures;
+ RegionPtr (*pixCopyProc)();
+ int numRectsExp, numRectsObs;
+ BoxPtr pBoxExp, pBoxObs;
+
+ SETUP_BACKING (pWin, pGC);
+
+ /*
+ * Create a region of exposed boxes in pRgnExp.
+ */
+ box.x1 = srcx + pWin->drawable.x;
+ box.x2 = box.x1 + w;
+ box.y1 = srcy + pWin->drawable.y;
+ box.y2 = box.y1 + h;
+
+ pRgnExp = REGION_CREATE(pGC->pScreen, &box, 1);
+ REGION_INTERSECT(pGC->pScreen, pRgnExp, pRgnExp, &pWin->clipList);
+ pRgnObs = REGION_CREATE(pGC->pScreen, NULL, 1);
+ REGION_INVERSE( pGC->pScreen, pRgnObs, pRgnExp, &box);
+
+ /*
+ * Translate regions into window coordinates for proper calls
+ * to the copyProc, then make sure none of the obscured region sticks
+ * into invalid areas of the backing pixmap.
+ */
+ REGION_TRANSLATE(pGC->pScreen, pRgnExp,
+ -pWin->drawable.x,
+ -pWin->drawable.y);
+ REGION_TRANSLATE(pGC->pScreen, pRgnObs,
+ -pWin->drawable.x,
+ -pWin->drawable.y);
+ REGION_INTERSECT(pGC->pScreen, pRgnObs, pRgnObs, &pBackingStore->SavedRegion);
+
+ /*
+ * If the obscured region is empty, there's no point being fancy.
+ */
+ if (!REGION_NOTEMPTY(pGC->pScreen, pRgnObs))
+ {
+ REGION_DESTROY(pGC->pScreen, pRgnExp);
+ REGION_DESTROY(pGC->pScreen, pRgnObs);
+
+ return (FALSE);
+ }
+
+ numRectsExp = REGION_NUM_RECTS(pRgnExp);
+ pBoxExp = REGION_RECTS(pRgnExp);
+ pBoxObs = REGION_RECTS(pRgnObs);
+ numRectsObs = REGION_NUM_RECTS(pRgnObs);
+ nrects = numRectsExp + numRectsObs;
+
+ boxes = (struct BoxDraw *)ALLOCATE_LOCAL(nrects * sizeof(struct BoxDraw));
+ sequence = (int *) ALLOCATE_LOCAL(nrects * sizeof(int));
+ *ppRgn = NULL;
+
+ if (!boxes || !sequence)
+ {
+ if (sequence) DEALLOCATE_LOCAL(sequence);
+ if (boxes) DEALLOCATE_LOCAL(boxes);
+ REGION_DESTROY(pGC->pScreen, pRgnExp);
+ REGION_DESTROY(pGC->pScreen, pRgnObs);
+
+ return(TRUE);
+ }
+
+ /*
+ * Order the boxes in the two regions so we know from which drawable
+ * to copy which box, storing the result in the boxes array
+ */
+ for (i = 0, j = 0, k = 0;
+ (i < numRectsExp) && (j < numRectsObs);
+ k++)
+ {
+ if (pBoxExp[i].y1 < pBoxObs[j].y1)
+ {
+ boxes[k].pBox = &pBoxExp[i];
+ boxes[k].source = win;
+ i++;
+ }
+ else if ((pBoxObs[j].y1 < pBoxExp[i].y1) ||
+ (pBoxObs[j].x1 < pBoxExp[i].x1))
+ {
+ boxes[k].pBox = &pBoxObs[j];
+ boxes[k].source = pix;
+ j++;
+ }
+ else
+ {
+ boxes[k].pBox = &pBoxExp[i];
+ boxes[k].source = win;
+ i++;
+ }
+ }
+
+ /*
+ * Catch any leftover boxes from either region (note that only
+ * one can have leftover boxes...)
+ */
+ if (i != numRectsExp)
+ {
+ do
+ {
+ boxes[k].pBox = &pBoxExp[i];
+ boxes[k].source = win;
+ i++;
+ k++;
+ } while (i < numRectsExp);
+
+ }
+ else
+ {
+ do
+ {
+ boxes[k].pBox = &pBoxObs[j];
+ boxes[k].source = pix;
+ j++;
+ k++;
+ } while (j < numRectsObs);
+ }
+
+ if (dsty <= srcy)
+ {
+ /*
+ * Scroll up or vertically stationary, so vertical order is ok.
+ */
+ if (dstx <= srcx)
+ {
+ /*
+ * Scroll left or horizontally stationary, so horizontal order
+ * is ok as well.
+ */
+ for (i = 0; i < nrects; i++)
+ {
+ sequence[i] = i;
+ }
+ }
+ else
+ {
+ /*
+ * Scroll right. Need to reverse the rectangles within each
+ * band.
+ */
+ for (i = 0, j = 1, k = 0;
+ i < nrects;
+ j = i + 1, k = i)
+ {
+ y = boxes[i].pBox->y1;
+ while ((j < nrects) && (boxes[j].pBox->y1 == y))
+ {
+ j++;
+ }
+ for (j--; j >= k; j--, i++)
+ {
+ sequence[i] = j;
+ }
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Scroll down. Must reverse vertical banding, at least.
+ */
+ if (dstx < srcx)
+ {
+ /*
+ * Scroll left. Horizontal order is ok.
+ */
+ for (i = nrects - 1, j = i - 1, k = i, l = 0;
+ i >= 0;
+ j = i - 1, k = i)
+ {
+ /*
+ * Find extent of current horizontal band, then reverse
+ * the order of the whole band.
+ */
+ y = boxes[i].pBox->y1;
+ while ((j >= 0) && (boxes[j].pBox->y1 == y))
+ {
+ j--;
+ }
+ for (j++; j <= k; j++, i--, l++)
+ {
+ sequence[l] = j;
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Scroll right or horizontal stationary.
+ * Reverse horizontal order as well (if stationary, horizontal
+ * order can be swapped without penalty and this is faster
+ * to compute).
+ */
+ for (i = 0, j = nrects - 1; i < nrects; i++, j--)
+ {
+ sequence[i] = j;
+ }
+ }
+ }
+
+ /*
+ * XXX: To avoid getting multiple NoExpose events from this operation,
+ * we turn OFF graphicsExposures in the gc and deal with any uncopied
+ * areas later, if there's something not in backing-store.
+ */
+
+ graphicsExposures = pGC->graphicsExposures;
+ pGC->graphicsExposures = FALSE;
+
+ dx = dstx - srcx;
+ dy = dsty - srcy;
+
+ /*
+ * Figure out which copy procedure to use from the backing GC. Note we
+ * must do this because some implementations (sun's, e.g.) have
+ * pBackingGC a fake GC with the real one below it, thus the devPriv for
+ * pBackingGC won't be what the output library expects.
+ */
+ if (plane != 0)
+ {
+ pixCopyProc = pBackingGC->ops->CopyPlane;
+ }
+ else
+ {
+ pixCopyProc = pBackingGC->ops->CopyArea;
+ }
+
+ for (i = 0; i < nrects; i++)
+ {
+ pBox = boxes[sequence[i]].pBox;
+
+ /*
+ * If we're copying from the pixmap, we need to place its contents
+ * onto the screen before scrolling the pixmap itself. If we're copying
+ * from the window, we need to copy its contents into the pixmap before
+ * we scroll the window itself.
+ */
+ if (boxes[sequence[i]].source == pix)
+ {
+ (void) (* copyProc) (pBackingDrawable, pWin, pGC,
+ pBox->x1 - pBackingStore->x,
+ pBox->y1 - pBackingStore->y,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
+ pBox->x1 + dx, pBox->y1 + dy, plane);
+ (void) (* pixCopyProc) (pBackingDrawable, pBackingDrawable, pBackingGC,
+ pBox->x1 - pBackingStore->x,
+ pBox->y1 - pBackingStore->y,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
+ pBox->x1 + dx - pBackingStore->x,
+ pBox->y1 + dy - pBackingStore->y, plane);
+ }
+ else
+ {
+ (void) (* pixCopyProc) (pWin, pBackingDrawable, pBackingGC,
+ pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
+ pBox->x1 + dx - pBackingStore->x,
+ pBox->y1 + dy - pBackingStore->y, plane);
+ (void) (* copyProc) (pWin, pWin, pGC,
+ pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
+ pBox->x1 + dx, pBox->y1 + dy, plane);
+ }
+ }
+ DEALLOCATE_LOCAL(sequence);
+ DEALLOCATE_LOCAL(boxes);
+
+ pGC->graphicsExposures = graphicsExposures;
+ /*
+ * Form union of rgnExp and rgnObs and see if covers entire area
+ * to be copied. Store the resultant region for miBSCopyArea
+ * to return to dispatch which will send the appropriate expose
+ * events.
+ */
+ REGION_UNION(pGC->pScreen, pRgnExp, pRgnExp, pRgnObs);
+ box.x1 = srcx;
+ box.x2 = srcx + w;
+ box.y1 = srcy;
+ box.y2 = srcy + h;
+ if (RECT_IN_REGION(pGC->pScreen, pRgnExp, &box) == rgnIN)
+ {
+ REGION_EMPTY(pGC->pScreen, pRgnExp);
+ }
+ else
+ {
+ REGION_INVERSE( pGC->pScreen, pRgnExp, pRgnExp, &box);
+ REGION_TRANSLATE( pGC->pScreen, pRgnExp,
+ dx + pWin->drawable.x,
+ dy + pWin->drawable.y);
+ REGION_INTERSECT( pGC->pScreen, pRgnObs, pRgnExp, &pWin->clipList);
+ (*pWin->drawable.pScreen->PaintWindowBackground) (pWin,
+ pRgnObs, PW_BACKGROUND);
+ REGION_TRANSLATE( pGC->pScreen, pRgnExp,
+ -pWin->drawable.x,
+ -pWin->drawable.y);
+ miBSClearBackingRegion (pWin, pRgnExp);
+ }
+ if (graphicsExposures)
+ *ppRgn = pRgnExp;
+ else
+ REGION_DESTROY(pGC->pScreen, pRgnExp);
+ REGION_DESTROY(pGC->pScreen, pRgnObs);
+
+ return (TRUE);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSCopyArea --
+ * Perform a CopyArea from the source to the destination, extracting
+ * from the source's backing-store and storing into the destination's
+ * backing-store without messing anything up. If the source and
+ * destination are different, there's not too much to worry about:
+ * we can just issue several calls to the regular CopyArea function.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static RegionPtr
+miBSCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty)
+ DrawablePtr pSrc;
+ DrawablePtr pDst;
+ GCPtr pGC;
+ int srcx;
+ int srcy;
+ int w;
+ int h;
+ int dstx;
+ int dsty;
+{
+ BoxPtr pExtents;
+ long dx, dy;
+ int bsrcx, bsrcy, bw, bh, bdstx, bdsty;
+ RegionPtr pixExposed = 0, winExposed = 0;
+
+ SETUP_BACKING(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ if ((pSrc != pDst) ||
+ (!miBSDoCopy((WindowPtr)pSrc, pGC, srcx, srcy, w, h, dstx, dsty,
+ (unsigned long) 0, pGC->ops->CopyArea, &winExposed)))
+ {
+ /*
+ * always copy to the backing store first, miBSDoCopy
+ * returns FALSE if the *source* region is disjoint
+ * from the backing store saved region. So, copying
+ * *to* the backing store is always safe
+ */
+ if (pGC->clientClipType != CT_PIXMAP)
+ {
+ /*
+ * adjust srcx, srcy, w, h, dstx, dsty to be clipped to
+ * the backing store. An unnecessary optimisation,
+ * but a useful one when GetSpans is slow.
+ */
+ pExtents = REGION_EXTENTS(pDst->pScreen,
+ (RegionPtr)pBackingGC->clientClip);
+ bsrcx = srcx;
+ bsrcy = srcy;
+ bw = w;
+ bh = h;
+ bdstx = dstx;
+ bdsty = dsty;
+ dx = pExtents->x1 - bdstx;
+ if (dx > 0)
+ {
+ bsrcx += dx;
+ bdstx += dx;
+ bw -= dx;
+ }
+ dy = pExtents->y1 - bdsty;
+ if (dy > 0)
+ {
+ bsrcy += dy;
+ bdsty += dy;
+ bh -= dy;
+ }
+ dx = (bdstx + bw) - pExtents->x2;
+ if (dx > 0)
+ bw -= dx;
+ dy = (bdsty + bh) - pExtents->y2;
+ if (dy > 0)
+ bh -= dy;
+ if (bw > 0 && bh > 0)
+ pixExposed = (* pBackingGC->ops->CopyArea) (pSrc,
+ pBackingDrawable, pBackingGC,
+ bsrcx, bsrcy, bw, bh, bdstx - pBackingStore->x,
+ bdsty - pBackingStore->y);
+ }
+ else
+ pixExposed = (* pBackingGC->ops->CopyArea) (pSrc,
+ pBackingDrawable, pBackingGC,
+ srcx, srcy, w, h,
+ dstx - pBackingStore->x, dsty - pBackingStore->y);
+
+ winExposed = (* pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
+ }
+
+ /*
+ * compute the composite graphics exposure region
+ */
+ if (winExposed)
+ {
+ if (pixExposed){
+ REGION_UNION(pDst->pScreen, winExposed, winExposed, pixExposed);
+ REGION_DESTROY(pDst->pScreen, pixExposed);
+ }
+ } else
+ winExposed = pixExposed;
+
+ EPILOGUE (pGC);
+
+ return winExposed;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSCopyPlane --
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static RegionPtr
+miBSCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, plane)
+ DrawablePtr pSrc;
+ DrawablePtr pDst;
+ register GC *pGC;
+ int srcx,
+ srcy;
+ int w,
+ h;
+ int dstx,
+ dsty;
+ unsigned long plane;
+{
+ BoxPtr pExtents;
+ long dx, dy;
+ int bsrcx, bsrcy, bw, bh, bdstx, bdsty;
+ RegionPtr winExposed = 0, pixExposed = 0;
+ SETUP_BACKING(pDst, pGC);
+
+ PROLOGUE(pGC);
+
+ if ((pSrc != pDst) ||
+ (!miBSDoCopy((WindowPtr)pSrc, pGC, srcx, srcy, w, h, dstx, dsty,
+ plane, pGC->ops->CopyPlane, &winExposed)))
+ {
+ /*
+ * always copy to the backing store first, miBSDoCopy
+ * returns FALSE if the *source* region is disjoint
+ * from the backing store saved region. So, copying
+ * *to* the backing store is always safe
+ */
+ if (pGC->clientClipType != CT_PIXMAP)
+ {
+ /*
+ * adjust srcx, srcy, w, h, dstx, dsty to be clipped to
+ * the backing store. An unnecessary optimisation,
+ * but a useful one when GetSpans is slow.
+ */
+ pExtents = REGION_EXTENTS(pDst->pScreen,
+ (RegionPtr)pBackingGC->clientClip);
+ bsrcx = srcx;
+ bsrcy = srcy;
+ bw = w;
+ bh = h;
+ bdstx = dstx;
+ bdsty = dsty;
+ dx = pExtents->x1 - bdstx;
+ if (dx > 0)
+ {
+ bsrcx += dx;
+ bdstx += dx;
+ bw -= dx;
+ }
+ dy = pExtents->y1 - bdsty;
+ if (dy > 0)
+ {
+ bsrcy += dy;
+ bdsty += dy;
+ bh -= dy;
+ }
+ dx = (bdstx + bw) - pExtents->x2;
+ if (dx > 0)
+ bw -= dx;
+ dy = (bdsty + bh) - pExtents->y2;
+ if (dy > 0)
+ bh -= dy;
+ if (bw > 0 && bh > 0)
+ pixExposed = (* pBackingGC->ops->CopyPlane) (pSrc,
+ pBackingDrawable,
+ pBackingGC, bsrcx, bsrcy, bw, bh,
+ bdstx - pBackingStore->x,
+ bdsty - pBackingStore->y, plane);
+ }
+ else
+ pixExposed = (* pBackingGC->ops->CopyPlane) (pSrc,
+ pBackingDrawable,
+ pBackingGC, srcx, srcy, w, h,
+ dstx - pBackingStore->x,
+ dsty - pBackingStore->y, plane);
+
+ winExposed = (* pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h,
+ dstx, dsty, plane);
+
+ }
+
+ /*
+ * compute the composite graphics exposure region
+ */
+ if (winExposed)
+ {
+ if (pixExposed)
+ {
+ REGION_UNION(pDst->pScreen, winExposed, winExposed, pixExposed);
+ REGION_DESTROY(pDst->pScreen, pixExposed);
+ }
+ } else
+ winExposed = pixExposed;
+
+ EPILOGUE (pGC);
+
+ return winExposed;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyPoint --
+ * Perform a PolyPoint, routing output to backing-store as needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPolyPoint (pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt;
+ xPoint *pptInit;
+{
+ xPoint *pptCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pptCopy = (xPoint *)ALLOCATE_LOCAL(npt*sizeof(xPoint));
+ if (pptCopy)
+ {
+ copyPoints(pptInit, pptCopy, npt, mode);
+
+ (* pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pptInit);
+
+ (* pBackingGC->ops->PolyPoint) (pBackingDrawable,
+ pBackingGC, mode, npt, pptCopy);
+
+ DEALLOCATE_LOCAL(pptCopy);
+ }
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyLines --
+ * Perform a Polylines, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPolylines (pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode;
+ int npt;
+ DDXPointPtr pptInit;
+{
+ DDXPointPtr pptCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pptCopy = (DDXPointPtr)ALLOCATE_LOCAL(npt*sizeof(DDXPointRec));
+ if (pptCopy)
+ {
+ copyPoints(pptInit, pptCopy, npt, mode);
+
+ (* pGC->ops->Polylines)(pDrawable, pGC, mode, npt, pptInit);
+ (* pBackingGC->ops->Polylines)(pBackingDrawable,
+ pBackingGC, mode, npt, pptCopy);
+ DEALLOCATE_LOCAL(pptCopy);
+ }
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolySegment --
+ * Perform a PolySegment, routing output to backing-store as needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPolySegment(pDrawable, pGC, nseg, pSegs)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nseg;
+ xSegment *pSegs;
+{
+ xSegment *pSegsCopy;
+
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pSegsCopy = (xSegment *)ALLOCATE_LOCAL(nseg*sizeof(xSegment));
+ if (pSegsCopy)
+ {
+ copyData(pSegs, pSegsCopy, nseg << 1, MoreCopy0);
+
+ (* pGC->ops->PolySegment)(pDrawable, pGC, nseg, pSegs);
+ (* pBackingGC->ops->PolySegment)(pBackingDrawable,
+ pBackingGC, nseg, pSegsCopy);
+
+ DEALLOCATE_LOCAL(pSegsCopy);
+ }
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyRectangle --
+ * Perform a PolyRectangle, routing output to backing-store as needed.
+ *
+ * Results:
+ * None
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPolyRectangle(pDrawable, pGC, nrects, pRects)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nrects;
+ xRectangle *pRects;
+{
+ xRectangle *pRectsCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pRectsCopy =(xRectangle *)ALLOCATE_LOCAL(nrects*sizeof(xRectangle));
+ if (pRectsCopy)
+ {
+ copyData(pRects, pRectsCopy, nrects, MoreCopy2);
+
+ (* pGC->ops->PolyRectangle)(pDrawable, pGC, nrects, pRects);
+ (* pBackingGC->ops->PolyRectangle)(pBackingDrawable,
+ pBackingGC, nrects, pRectsCopy);
+
+ DEALLOCATE_LOCAL(pRectsCopy);
+ }
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyArc --
+ * Perform a PolyArc, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPolyArc(pDrawable, pGC, narcs, parcs)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ xArc *pArcsCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pArcsCopy = (xArc *)ALLOCATE_LOCAL(narcs*sizeof(xArc));
+ if (pArcsCopy)
+ {
+ copyData(parcs, pArcsCopy, narcs, MoreCopy4);
+
+ (* pGC->ops->PolyArc)(pDrawable, pGC, narcs, parcs);
+ (* pBackingGC->ops->PolyArc)(pBackingDrawable, pBackingGC,
+ narcs, pArcsCopy);
+
+ DEALLOCATE_LOCAL(pArcsCopy);
+ }
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSFillPolygon --
+ * Perform a FillPolygon, routing output to backing-store as needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSFillPolygon(pDrawable, pGC, shape, mode, count, pPts)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int shape, mode;
+ register int count;
+ DDXPointPtr pPts;
+{
+ DDXPointPtr pPtsCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pPtsCopy = (DDXPointPtr)ALLOCATE_LOCAL(count*sizeof(DDXPointRec));
+ if (pPtsCopy)
+ {
+ copyPoints(pPts, pPtsCopy, count, mode);
+ (* pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, count, pPts);
+ (* pBackingGC->ops->FillPolygon)(pBackingDrawable,
+ pBackingGC, shape, mode,
+ count, pPtsCopy);
+
+ DEALLOCATE_LOCAL(pPtsCopy);
+ }
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyFillRect --
+ * Perform a PolyFillRect, routing output to backing-store as needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nrectFill; /* number of rectangles to fill */
+ xRectangle *prectInit; /* Pointer to first rectangle to fill */
+{
+ xRectangle *pRectCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pRectCopy =
+ (xRectangle *)ALLOCATE_LOCAL(nrectFill*sizeof(xRectangle));
+ if (pRectCopy)
+ {
+ copyData(prectInit, pRectCopy, nrectFill, MoreCopy2);
+
+ (* pGC->ops->PolyFillRect)(pDrawable, pGC, nrectFill, prectInit);
+ (* pBackingGC->ops->PolyFillRect)(pBackingDrawable,
+ pBackingGC, nrectFill, pRectCopy);
+
+ DEALLOCATE_LOCAL(pRectCopy);
+ }
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyFillArc --
+ * Perform a PolyFillArc, routing output to backing-store as needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPolyFillArc(pDrawable, pGC, narcs, parcs)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ xArc *pArcsCopy;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ pArcsCopy = (xArc *)ALLOCATE_LOCAL(narcs*sizeof(xArc));
+ if (pArcsCopy)
+ {
+ copyData(parcs, pArcsCopy, narcs, MoreCopy4);
+ (* pGC->ops->PolyFillArc)(pDrawable, pGC, narcs, parcs);
+ (* pBackingGC->ops->PolyFillArc)(pBackingDrawable,
+ pBackingGC, narcs, pArcsCopy);
+ DEALLOCATE_LOCAL(pArcsCopy);
+ }
+
+ EPILOGUE (pGC);
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyText8 --
+ * Perform a PolyText8, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+miBSPolyText8(pDrawable, pGC, x, y, count, chars)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *chars;
+{
+ int result;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ result = (* pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
+ (* pBackingGC->ops->PolyText8)(pBackingDrawable, pBackingGC,
+ x - pBackingStore->x, y - pBackingStore->y,
+ count, chars);
+
+ EPILOGUE (pGC);
+ return result;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyText16 --
+ * Perform a PolyText16, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+miBSPolyText16(pDrawable, pGC, x, y, count, chars)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ unsigned short *chars;
+{
+ int result;
+ SETUP_BACKING (pDrawable, pGC);
+
+ PROLOGUE(pGC);
+
+ result = (* pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
+ (* pBackingGC->ops->PolyText16)(pBackingDrawable, pBackingGC,
+ x - pBackingStore->x, y - pBackingStore->y,
+ count, chars);
+
+ EPILOGUE (pGC);
+
+ return result;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSImageText8 --
+ * Perform a ImageText8, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSImageText8(pDrawable, pGC, x, y, count, chars)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *chars;
+{
+ SETUP_BACKING (pDrawable, pGC);
+ PROLOGUE(pGC);
+
+ (* pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
+ (* pBackingGC->ops->ImageText8)(pBackingDrawable, pBackingGC,
+ x - pBackingStore->x, y - pBackingStore->y,
+ count, chars);
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSImageText16 --
+ * Perform a ImageText16, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSImageText16(pDrawable, pGC, x, y, count, chars)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ unsigned short *chars;
+{
+ SETUP_BACKING (pDrawable, pGC);
+ PROLOGUE(pGC);
+
+ (* pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
+ (* pBackingGC->ops->ImageText16)(pBackingDrawable, pBackingGC,
+ x - pBackingStore->x, y - pBackingStore->y,
+ count, chars);
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSImageGlyphBlt --
+ * Perform a ImageGlyphBlt, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ pointer pglyphBase; /* start of array of glyphs */
+{
+ SETUP_BACKING (pDrawable, pGC);
+ PROLOGUE(pGC);
+
+ (* pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, nglyph, ppci,
+ pglyphBase);
+ (* pBackingGC->ops->ImageGlyphBlt)(pBackingDrawable, pBackingGC,
+ x - pBackingStore->x, y - pBackingStore->y,
+ nglyph, ppci, pglyphBase);
+
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPolyGlyphBlt --
+ * Perform a PolyGlyphBlt, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ pointer pglyphBase; /* start of array of glyphs */
+{
+ SETUP_BACKING (pDrawable, pGC);
+ PROLOGUE(pGC);
+
+ (* pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph,
+ ppci, pglyphBase);
+ (* pBackingGC->ops->PolyGlyphBlt)(pBackingDrawable, pBackingGC,
+ x - pBackingStore->x, y - pBackingStore->y,
+ nglyph, ppci, pglyphBase);
+ EPILOGUE (pGC);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSPushPixels --
+ * Perform a PushPixels, routing output to backing-store as needed.
+ *
+ * Results:
+ *
+ * Side Effects:
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSPushPixels(pGC, pBitMap, pDst, w, h, x, y)
+ GCPtr pGC;
+ PixmapPtr pBitMap;
+ DrawablePtr pDst;
+ int w, h, x, y;
+{
+ SETUP_BACKING (pDst, pGC);
+ PROLOGUE(pGC);
+
+ (* pGC->ops->PushPixels)(pGC, pBitMap, pDst, w, h, x, y);
+ if (pGC->miTranslate) {
+ x -= pDst->x;
+ y -= pDst->y;
+ }
+ (* pBackingGC->ops->PushPixels)(pBackingGC, pBitMap,
+ pBackingDrawable, w, h,
+ x - pBackingStore->x, y - pBackingStore->y);
+
+ EPILOGUE (pGC);
+}
+
+#ifdef NEED_LINEHELPER
+/*-
+ *-----------------------------------------------------------------------
+ * miBSLineHelper --
+ *
+ * Results: should never be called
+ *
+ * Side Effects: server dies
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSLineHelper()
+{
+ FatalError("miBSLineHelper called\n");
+}
+#endif
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSClearBackingStore --
+ * Clear the given area of the backing pixmap with the background of
+ * the window, whatever it is. If generateExposures is TRUE, generate
+ * exposure events for the area. Note that if the area has any
+ * part outside the saved portions of the window, we do not allow the
+ * count in the expose events to be 0, since there will be more
+ * expose events to come.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Areas of pixmap are cleared and Expose events are generated.
+ *
+ *-----------------------------------------------------------------------
+ */
+static RegionPtr
+miBSClearBackingStore(pWin, x, y, w, h, generateExposures)
+ WindowPtr pWin;
+ int x;
+ int y;
+ int w;
+ int h;
+ Bool generateExposures;
+{
+ RegionPtr pRgn;
+ int i;
+ miBSWindowPtr pBackingStore;
+ ScreenPtr pScreen;
+ GCPtr pGC;
+ int ts_x_origin,
+ ts_y_origin;
+ pointer gcvalues[4];
+ unsigned long gcmask;
+ xRectangle *rects;
+ BoxPtr pBox;
+ BoxRec box;
+ PixUnion background;
+ char backgroundState;
+ int numRects;
+
+ pBackingStore = (miBSWindowPtr)pWin->backStorage;
+ pScreen = pWin->drawable.pScreen;
+
+ if ((pBackingStore->status == StatusNoPixmap) ||
+ (pBackingStore->status == StatusBadAlloc))
+ return NullRegion;
+
+ if (w == 0)
+ w = (int) pWin->drawable.width - x;
+ if (h == 0)
+ h = (int) pWin->drawable.height - y;
+
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = x + w;
+ box.y2 = y + h;
+ pRgn = REGION_CREATE(pWin->drawable.pScreen, &box, 1);
+ if (!pRgn)
+ return NullRegion;
+ REGION_INTERSECT( pScreen, pRgn, pRgn, &pBackingStore->SavedRegion);
+
+ if (REGION_NOTEMPTY( pScreen, pRgn))
+ {
+ /*
+ * if clearing entire window, simply make new virtual
+ * tile. For the root window, we also destroy the pixmap
+ * to save a pile of memory
+ */
+ if (x == 0 && y == 0 &&
+ w == pWin->drawable.width &&
+ h == pWin->drawable.height)
+ {
+ if (!pWin->parent)
+ miDestroyBSPixmap (pWin);
+ if (pBackingStore->status != StatusContents)
+ miTileVirtualBS (pWin);
+ }
+
+ ts_x_origin = ts_y_origin = 0;
+
+ backgroundState = pWin->backgroundState;
+ background = pWin->background;
+ if (backgroundState == ParentRelative) {
+ WindowPtr pParent;
+
+ pParent = pWin;
+ while (pParent->backgroundState == ParentRelative) {
+ ts_x_origin -= pParent->origin.x;
+ ts_y_origin -= pParent->origin.y;
+ pParent = pParent->parent;
+ }
+ backgroundState = pParent->backgroundState;
+ background = pParent->background;
+ }
+
+ if ((backgroundState != None) &&
+ ((pBackingStore->status == StatusContents) ||
+ !SameBackground (pBackingStore->backgroundState,
+ pBackingStore->background,
+ backgroundState,
+ background)))
+ {
+ if (!pBackingStore->pBackingPixmap)
+ miCreateBSPixmap(pWin, NullBox);
+
+ pGC = GetScratchGC(pWin->drawable.depth, pScreen);
+ if (pGC && pBackingStore->pBackingPixmap)
+ {
+ /*
+ * 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.
+ */
+
+ if (backgroundState == BackgroundPixel)
+ {
+ gcvalues[0] = (pointer) background.pixel;
+ gcvalues[1] = (pointer)FillSolid;
+ gcmask = GCForeground|GCFillStyle;
+ }
+ else
+ {
+ gcvalues[0] = (pointer)FillTiled;
+ gcvalues[1] = (pointer) background.pixmap;
+ gcmask = GCFillStyle|GCTile;
+ }
+ gcvalues[2] = (pointer)(long)(ts_x_origin - pBackingStore->x);
+ gcvalues[3] = (pointer)(long)(ts_y_origin - pBackingStore->y);
+ gcmask |= GCTileStipXOrigin|GCTileStipYOrigin;
+ DoChangeGC(pGC, gcmask, (XID *)gcvalues, TRUE);
+ ValidateGC((DrawablePtr)pBackingStore->pBackingPixmap, pGC);
+
+ /*
+ * Figure out the array of rectangles to fill and fill them with
+ * PolyFillRect in the proper mode, as set in the GC above.
+ */
+ numRects = REGION_NUM_RECTS(pRgn);
+ rects = (xRectangle *)ALLOCATE_LOCAL(numRects*sizeof(xRectangle));
+
+ if (rects)
+ {
+ for (i = 0, pBox = REGION_RECTS(pRgn);
+ i < numRects;
+ i++, pBox++)
+ {
+ rects[i].x = pBox->x1 - pBackingStore->x;
+ rects[i].y = pBox->y1 - pBackingStore->y;
+ rects[i].width = pBox->x2 - pBox->x1;
+ rects[i].height = pBox->y2 - pBox->y1;
+ }
+ (* pGC->ops->PolyFillRect) (
+ (DrawablePtr)pBackingStore->pBackingPixmap,
+ pGC, numRects, rects);
+ DEALLOCATE_LOCAL(rects);
+ }
+ FreeScratchGC(pGC);
+ }
+ }
+
+ if (!generateExposures)
+ {
+ REGION_DESTROY(pScreen, pRgn);
+ pRgn = NULL;
+ }
+ else
+ {
+ /*
+ * result must be screen relative, but is currently
+ * drawable relative.
+ */
+ REGION_TRANSLATE(pScreen, pRgn, pWin->drawable.x,
+ pWin->drawable.y);
+ }
+ }
+ else
+ {
+ REGION_DESTROY( pScreen, pRgn);
+ pRgn = NULL;
+ }
+ return pRgn;
+}
+
+static void
+miBSClearBackingRegion (pWin, pRgn)
+ WindowPtr pWin;
+ RegionPtr pRgn;
+{
+ BoxPtr pBox;
+ int i;
+
+ i = REGION_NUM_RECTS(pRgn);
+ pBox = REGION_RECTS(pRgn);
+ while (i--)
+ {
+ (void) miBSClearBackingStore(pWin, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1,
+ pBox->y2 - pBox->y1,
+ FALSE);
+ pBox++;
+ }
+}
+
+/*
+ * fill a region of the destination with virtual bits
+ *
+ * pRgn is to be translated by (x,y)
+ */
+
+static void
+miBSFillVirtualBits (pDrawable, pGC, pRgn, x, y, state, pixunion, planeMask)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ RegionPtr pRgn;
+ int x, y;
+ int state;
+ PixUnion pixunion;
+ unsigned long planeMask;
+{
+ int i;
+ BITS32 gcmask;
+ pointer gcval[5];
+ xRectangle *pRect;
+ BoxPtr pBox;
+ WindowPtr pWin;
+ int numRects;
+
+ if (state == None)
+ return;
+ numRects = REGION_NUM_RECTS(pRgn);
+ pRect = (xRectangle *)ALLOCATE_LOCAL(numRects * sizeof(xRectangle));
+ if (!pRect)
+ return;
+ pWin = 0;
+ if (pDrawable->type != DRAWABLE_PIXMAP)
+ {
+ pWin = (WindowPtr) pDrawable;
+ if (!pWin->backStorage)
+ pWin = 0;
+ }
+ i = 0;
+ gcmask = 0;
+ gcval[i++] = (pointer)planeMask;
+ gcmask |= GCPlaneMask;
+ if (state == BackgroundPixel)
+ {
+ if (pGC->fgPixel != pixunion.pixel)
+ {
+ gcval[i++] = (pointer)pixunion.pixel;
+ gcmask |= GCForeground;
+ }
+ if (pGC->fillStyle != FillSolid)
+ {
+ gcval[i++] = (pointer)FillSolid;
+ gcmask |= GCFillStyle;
+ }
+ }
+ else
+ {
+ if (pGC->fillStyle != FillTiled)
+ {
+ gcval[i++] = (pointer)FillTiled;
+ gcmask |= GCFillStyle;
+ }
+ if (pGC->tileIsPixel || pGC->tile.pixmap != pixunion.pixmap)
+ {
+ gcval[i++] = (pointer)pixunion.pixmap;
+ gcmask |= GCTile;
+ }
+ if (pGC->patOrg.x != x)
+ {
+ gcval[i++] = (pointer)(long)x;
+ gcmask |= GCTileStipXOrigin;
+ }
+ if (pGC->patOrg.y != y)
+ {
+ gcval[i++] = (pointer)(long)y;
+ gcmask |= GCTileStipYOrigin;
+ }
+ }
+ if (gcmask)
+ DoChangeGC (pGC, gcmask, (XID *)gcval, 1);
+
+ if (pWin)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
+
+ if (pDrawable->serialNumber != pGC->serialNumber)
+ ValidateGC (pDrawable, pGC);
+
+ pBox = REGION_RECTS(pRgn);
+ for (i = numRects; --i >= 0; pBox++, pRect++)
+ {
+ pRect->x = pBox->x1 + x;
+ pRect->y = pBox->y1 + y;
+ pRect->width = pBox->x2 - pBox->x1;
+ pRect->height = pBox->y2 - pBox->y1;
+ }
+ pRect -= numRects;
+ (*pGC->ops->PolyFillRect) (pDrawable, pGC, numRects, pRect);
+ if (pWin)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
+ DEALLOCATE_LOCAL (pRect);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSAllocate --
+ * Create and install backing store info for a window
+ *
+ *-----------------------------------------------------------------------
+ */
+
+static void
+miBSAllocate(pWin)
+ WindowPtr pWin;
+{
+ register miBSWindowPtr pBackingStore;
+ register ScreenPtr pScreen;
+
+ if (pWin->drawable.pScreen->backingStoreSupport == NotUseful)
+ return;
+ pScreen = pWin->drawable.pScreen;
+ if (!(pBackingStore = (miBSWindowPtr)pWin->backStorage))
+ {
+
+ pBackingStore = (miBSWindowPtr)xalloc(sizeof(miBSWindowRec));
+ if (!pBackingStore)
+ return;
+
+ pBackingStore->pBackingPixmap = NullPixmap;
+ pBackingStore->x = 0;
+ pBackingStore->y = 0;
+ REGION_INIT( pScreen, &pBackingStore->SavedRegion, NullBox, 1);
+ pBackingStore->viewable = (char)pWin->viewable;
+ pBackingStore->status = StatusNoPixmap;
+ pBackingStore->backgroundState = None;
+ pWin->backStorage = (pointer) pBackingStore;
+ }
+
+ /*
+ * Now want to initialize the backing pixmap and SavedRegion if
+ * necessary. The initialization consists of finding all the
+ * currently-obscured regions, by taking the inverse of the window's
+ * clip list, storing the result in SavedRegion, and exposing those
+ * areas of the window.
+ */
+
+ if (pBackingStore->status == StatusNoPixmap &&
+ ((pWin->backingStore == WhenMapped && pWin->viewable) ||
+ (pWin->backingStore == Always)))
+ {
+ BoxRec box;
+ RegionPtr pSavedRegion;
+
+ pSavedRegion = &pBackingStore->SavedRegion;
+
+ box.x1 = pWin->drawable.x;
+ box.x2 = box.x1 + (int) pWin->drawable.width;
+ box.y1 = pWin->drawable.y;
+ box.y2 = pWin->drawable.y + (int) pWin->drawable.height;
+
+ REGION_INVERSE( pScreen, pSavedRegion, &pWin->clipList, &box);
+ REGION_TRANSLATE( pScreen, pSavedRegion,
+ -pWin->drawable.x,
+ -pWin->drawable.y);
+#ifdef SHAPE
+ if (wBoundingShape (pWin))
+ REGION_INTERSECT(pScreen, pSavedRegion, pSavedRegion,
+ wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ REGION_INTERSECT(pScreen, pSavedRegion, pSavedRegion,
+ wClipShape (pWin));
+#endif
+ /* if window is already on-screen, assume it has been drawn to */
+ if (pWin->viewable)
+ pBackingStore->status = StatusVDirty;
+ miTileVirtualBS (pWin);
+
+ /*
+ * deliver all the newly available regions
+ * as exposure events to the window
+ */
+
+ miSendExposures(pWin, pSavedRegion, 0, 0);
+ }
+ else if (!pWin->viewable)
+ {
+ /*
+ * Turn off backing store when we're not supposed to
+ * be saving anything
+ */
+ if (pBackingStore->status != StatusNoPixmap)
+ {
+ REGION_EMPTY( pScreen, &pBackingStore->SavedRegion);
+ miDestroyBSPixmap (pWin);
+ }
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSFree --
+ * Destroy and free all the stuff associated with the backing-store
+ * for the given window.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The backing pixmap and all the regions and GC's are destroyed.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSFree(pWin)
+ WindowPtr pWin;
+{
+ miBSWindowPtr pBackingStore;
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ pBackingStore = (miBSWindowPtr)pWin->backStorage;
+ if (pBackingStore)
+ {
+ miDestroyBSPixmap (pWin);
+
+ REGION_UNINIT( pScreen, &pBackingStore->SavedRegion);
+
+ xfree(pBackingStore);
+ pWin->backStorage = NULL;
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miResizeBackingStore --
+ * Alter the size of the backing pixmap as necessary when the
+ * SavedRegion changes size. The contents of the old pixmap are
+ * copied/shifted into the new/same pixmap.
+ *
+ * Results:
+ * The new Pixmap is created as necessary.
+ *
+ * Side Effects:
+ * The old pixmap is destroyed.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miResizeBackingStore(pWin, dx, dy, saveBits)
+ WindowPtr pWin;
+ int dx, dy; /* bits are moving this far */
+ Bool saveBits; /* bits are useful */
+{
+ miBSWindowPtr pBackingStore;
+ PixmapPtr pBackingPixmap;
+ ScreenPtr pScreen;
+ GC *pGC;
+ BoxPtr extents;
+ PixmapPtr pNewPixmap;
+ int nx, ny;
+ int nw, nh;
+
+ pBackingStore = (miBSWindowPtr)(pWin->backStorage);
+ pBackingPixmap = pBackingStore->pBackingPixmap;
+ if (!pBackingPixmap)
+ return;
+ pScreen = pWin->drawable.pScreen;
+ extents = REGION_EXTENTS(pScreen, &pBackingStore->SavedRegion);
+ pNewPixmap = pBackingPixmap;
+
+ nw = extents->x2 - extents->x1;
+ nh = extents->y2 - extents->y1;
+
+ /* the policy here could be more sophisticated */
+ if (nw != pBackingPixmap->drawable.width ||
+ nh != pBackingPixmap->drawable.height)
+ {
+ if (!saveBits)
+ {
+ pNewPixmap = NullPixmap;
+ pBackingStore->status = StatusNoPixmap;
+ }
+ else
+ {
+ pNewPixmap = (PixmapPtr)(*pScreen->CreatePixmap)
+ (pScreen,
+ nw, nh,
+ pWin->drawable.depth);
+ if (!pNewPixmap)
+ {
+#ifdef BSEAGER
+ pBackingStore->status = StatusNoPixmap;
+#else
+ pBackingStore->status = StatusBadAlloc;
+#endif
+ }
+ }
+ }
+ if (!pNewPixmap)
+ {
+ pBackingStore->x = 0;
+ pBackingStore->y = 0;
+ }
+ else
+ {
+ nx = pBackingStore->x - extents->x1 + dx;
+ ny = pBackingStore->y - extents->y1 + dy;
+ pBackingStore->x = extents->x1;
+ pBackingStore->y = extents->y1;
+
+ if (saveBits && (pNewPixmap != pBackingPixmap || nx != 0 || ny != 0))
+ {
+ pGC = GetScratchGC(pNewPixmap->drawable.depth, pScreen);
+ if (pGC)
+ {
+ ValidateGC((DrawablePtr)pNewPixmap, pGC);
+ /* if we implement a policy where the pixmap can be larger than
+ * the region extents, we might want to optimize this copyarea
+ * by only copying the old extents, rather than the entire
+ * pixmap
+ */
+ (*pGC->ops->CopyArea)((DrawablePtr)pBackingPixmap,
+ (DrawablePtr)pNewPixmap, pGC,
+ 0, 0,
+ pBackingPixmap->drawable.width,
+ pBackingPixmap->drawable.height,
+ nx, ny);
+ FreeScratchGC(pGC);
+ }
+ }
+ }
+ /* SavedRegion is used in the backingGC clip; force an update */
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ if (pNewPixmap != pBackingPixmap)
+ {
+ (* pScreen->DestroyPixmap)(pBackingPixmap);
+ pBackingStore->pBackingPixmap = pNewPixmap;
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSSaveDoomedAreas --
+ * Saved the areas of the given window that are about to be
+ * obscured. If the window has moved, pObscured is expected to
+ * be at the new screen location and (dx,dy) is expected to be the offset
+ * to the window's previous location.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The region is copied from the screen into pBackingPixmap and
+ * SavedRegion is updated.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSSaveDoomedAreas(pWin, pObscured, dx, dy)
+ register WindowPtr pWin;
+ RegionPtr pObscured;
+ int dx, dy;
+{
+ miBSWindowPtr pBackingStore;
+ ScreenPtr pScreen;
+ int x, y;
+
+ pBackingStore = (miBSWindowPtr)pWin->backStorage;
+ pScreen = pWin->drawable.pScreen;
+
+ /*
+ * If the window isn't realized, it's being unmapped, thus we don't
+ * want to save anything if backingStore isn't Always.
+ */
+ if (!pWin->realized)
+ {
+ pBackingStore->viewable = (char)pWin->viewable;
+ if (pWin->backingStore != Always)
+ {
+ REGION_EMPTY( pScreen, &pBackingStore->SavedRegion);
+ miDestroyBSPixmap (pWin);
+ return;
+ }
+ if (pBackingStore->status == StatusBadAlloc)
+ pBackingStore->status = StatusNoPixmap;
+ }
+
+ /* Don't even pretend to save anything for a virtual background None */
+ if ((pBackingStore->status == StatusVirtual) &&
+ (pBackingStore->backgroundState == None))
+ return;
+
+ if (REGION_NOTEMPTY(pScreen, pObscured))
+ {
+ BoxRec oldExtents;
+ x = pWin->drawable.x;
+ y = pWin->drawable.y;
+ REGION_TRANSLATE(pScreen, pObscured, -x, -y);
+ oldExtents = *REGION_EXTENTS(pScreen, &pBackingStore->SavedRegion);
+ REGION_UNION( pScreen, &pBackingStore->SavedRegion,
+ &pBackingStore->SavedRegion,
+ pObscured);
+ /*
+ * only save the bits if we've actually
+ * started using backing store
+ */
+ if (pBackingStore->status != StatusVirtual)
+ {
+ if (!pBackingStore->pBackingPixmap)
+ miCreateBSPixmap (pWin, &oldExtents);
+ else
+ miResizeBackingStore(pWin, 0, 0, TRUE);
+
+ if (pBackingStore->pBackingPixmap) {
+ if (pBackingStore->x | pBackingStore->y)
+ {
+ REGION_TRANSLATE( pScreen, pObscured,
+ -pBackingStore->x,
+ -pBackingStore->y);
+ x += pBackingStore->x;
+ y += pBackingStore->y;
+ }
+ (* pScreen->BackingStoreFuncs.SaveAreas)
+ (pBackingStore->pBackingPixmap, pObscured,
+ x - dx, y - dy, pWin);
+ }
+ }
+ REGION_TRANSLATE(pScreen, pObscured, x, y);
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSRestoreAreas --
+ * Restore areas from backing-store that are no longer obscured.
+ * expects prgnExposed to contain a screen-relative area.
+ *
+ * Results:
+ * The region to generate exposure events on (which may be
+ * different from the region to paint).
+ *
+ * Side Effects:
+ * Areas are copied from pBackingPixmap to the screen. prgnExposed
+ * is altered to contain the region that could not be restored from
+ * backing-store.
+ *
+ * Notes:
+ * This is called before sending any exposure events to the client,
+ * and so might be called if the window has grown. Changing the backing
+ * pixmap doesn't require revalidating the backingGC because the
+ * client's next output request will result in a call to ValidateGC,
+ * since the window clip region has changed, which will in turn call
+ * miValidateBackingStore.
+ *-----------------------------------------------------------------------
+ */
+static RegionPtr
+miBSRestoreAreas(pWin, prgnExposed)
+ register WindowPtr pWin;
+ RegionPtr prgnExposed;
+{
+ PixmapPtr pBackingPixmap;
+ miBSWindowPtr pBackingStore;
+ RegionPtr prgnSaved;
+ RegionPtr prgnRestored;
+ register ScreenPtr pScreen;
+ RegionPtr exposures = prgnExposed;
+
+ pScreen = pWin->drawable.pScreen;
+ pBackingStore = (miBSWindowPtr)pWin->backStorage;
+ pBackingPixmap = pBackingStore->pBackingPixmap;
+
+ prgnSaved = &pBackingStore->SavedRegion;
+
+ if (pBackingStore->status == StatusContents)
+ {
+ REGION_TRANSLATE(pScreen, prgnSaved, pWin->drawable.x,
+ pWin->drawable.y);
+
+ prgnRestored = REGION_CREATE( pScreen, (BoxPtr)NULL, 1);
+ REGION_INTERSECT( pScreen, prgnRestored, prgnExposed, prgnSaved);
+
+ /*
+ * Since prgnExposed is no longer obscured, we no longer
+ * will have a valid copy of it in backing-store, but there is a valid
+ * copy of it on screen, so subtract the area we just restored from
+ * from the area to be exposed.
+ */
+
+ if (REGION_NOTEMPTY( pScreen, prgnRestored))
+ {
+ REGION_SUBTRACT( pScreen, prgnSaved, prgnSaved, prgnExposed);
+ REGION_SUBTRACT( pScreen, prgnExposed, prgnExposed, prgnRestored);
+
+ /*
+ * Do the actual restoration
+ */
+ (* pScreen->BackingStoreFuncs.RestoreAreas) (pBackingPixmap,
+ prgnRestored,
+ pWin->drawable.x + pBackingStore->x,
+ pWin->drawable.y + pBackingStore->y,
+ pWin);
+ /*
+ * if the saved region is completely empty, dispose of the
+ * backing pixmap, otherwise, retranslate the saved
+ * region to window relative
+ */
+
+ if (REGION_NOTEMPTY(pScreen, prgnSaved))
+ {
+ REGION_TRANSLATE(pScreen, prgnSaved,
+ -pWin->drawable.x,
+ -pWin->drawable.y);
+ miResizeBackingStore(pWin, 0, 0, TRUE);
+ }
+ else
+ miDestroyBSPixmap (pWin);
+ }
+ else
+ REGION_TRANSLATE(pScreen, prgnSaved,
+ -pWin->drawable.x, -pWin->drawable.y);
+ REGION_DESTROY( pScreen, prgnRestored);
+
+ }
+ else if ((pBackingStore->status == StatusVirtual) ||
+ (pBackingStore->status == StatusVDirty))
+ {
+ REGION_TRANSLATE(pScreen, prgnSaved,
+ pWin->drawable.x, pWin->drawable.y);
+ exposures = REGION_CREATE( pScreen, NullBox, 1);
+ if (SameBackground (pBackingStore->backgroundState,
+ pBackingStore->background,
+ pWin->backgroundState,
+ pWin->background))
+ {
+ REGION_SUBTRACT( pScreen, exposures, prgnExposed, prgnSaved);
+ }
+ else
+ {
+ miTileVirtualBS(pWin);
+
+ /* we need to expose all we have (virtually) retiled */
+ REGION_UNION( pScreen, exposures, prgnExposed, prgnSaved);
+ }
+ REGION_SUBTRACT( pScreen, prgnSaved, prgnSaved, prgnExposed);
+ REGION_TRANSLATE(pScreen, prgnSaved,
+ -pWin->drawable.x, -pWin->drawable.y);
+ }
+ else if (pWin->viewable && !pBackingStore->viewable &&
+ pWin->backingStore != Always)
+ {
+ /*
+ * The window was just mapped and nothing has been saved in
+ * backing-store from the last time it was mapped. We want to capture
+ * any output to regions that are already obscured but there are no
+ * bits to snag off the screen, so we initialize things just as we did
+ * in miBSAllocate, above.
+ */
+ BoxRec box;
+
+ prgnSaved = &pBackingStore->SavedRegion;
+
+ box.x1 = pWin->drawable.x;
+ box.x2 = box.x1 + (int) pWin->drawable.width;
+ box.y1 = pWin->drawable.y;
+ box.y2 = box.y1 + (int) pWin->drawable.height;
+
+ REGION_INVERSE( pScreen, prgnSaved, &pWin->clipList, &box);
+ REGION_TRANSLATE( pScreen, prgnSaved,
+ -pWin->drawable.x,
+ -pWin->drawable.y);
+#ifdef SHAPE
+ if (wBoundingShape (pWin))
+ REGION_INTERSECT(pScreen, prgnSaved, prgnSaved,
+ wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ REGION_INTERSECT(pScreen, prgnSaved, prgnSaved,
+ wClipShape (pWin));
+#endif
+ miTileVirtualBS(pWin);
+
+ exposures = REGION_CREATE( pScreen, &box, 1);
+ }
+ pBackingStore->viewable = (char)pWin->viewable;
+ return exposures;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSTranslateBackingStore --
+ * Shift the backing-store in the given direction. Called when bit
+ * gravity is shifting things around.
+ *
+ * Results:
+ * An occluded region of the window which should be sent exposure events.
+ * This region should be in absolute coordinates (i.e. include
+ * new window position).
+ *
+ * Side Effects:
+ * If the window changed size as well as position, the backing pixmap
+ * is resized. The contents of the backing pixmap are shifted
+ *
+ * Warning:
+ * Bob and I have rewritten this routine quite a few times, each
+ * time it gets a few more cases correct, and introducing some
+ * interesting bugs. Naturally, I think the code is correct this
+ * time.
+ *
+ * Let me try to explain what this routine is for:
+ *
+ * It's called from SlideAndSizeWindow whenever a window
+ * with backing store is resized. There are two separate
+ * possibilities:
+ *
+ * a) The window has ForgetGravity
+ *
+ * In this case, windx, windy will be 0 and oldClip will
+ * be NULL. This indicates that all of the window contents
+ * currently saved offscreen should be discarded, and the
+ * entire window exposed. TranslateBackingStore, then, should
+ * prepare a completely new backing store region based on the
+ * new window clipList and return that region for exposure.
+ *
+ * b) The window has some other gravity
+ *
+ * In this case, windx, windy will be set to the distance
+ * that the bits should move within the window. oldClip
+ * will be set to the old visible portion of the window.
+ * TranslateBackingStore, then, should adjust the backing
+ * store to accommodate the portion of the existing backing
+ * store bits which coorespond to backing store bits which
+ * will still be occluded in the new configuration. oldx,oldy
+ * are set to the old position of the window on the screen.
+ *
+ * Furthermore, in this case any contents of the screen which
+ * are about to become occluded should be fetched from the screen
+ * and placed in backing store. This is to avoid the eventual
+ * occlusion by the win gravity shifting the child window bits around
+ * on top of this window, and potentially losing information
+ *
+ * It's also called from SetShape, but I think (he says not
+ * really knowing for sure) that this code will even work
+ * in that case.
+ *-----------------------------------------------------------------------
+ */
+
+static RegionPtr
+miBSTranslateBackingStore(pWin, windx, windy, oldClip, oldx, oldy)
+ WindowPtr pWin;
+ int windx; /* bit translation distance in window */
+ int windy;
+ RegionPtr oldClip; /* Region being copied */
+ int oldx; /* old window position */
+ int oldy;
+{
+ register miBSWindowPtr pBackingStore;
+ register RegionPtr pSavedRegion;
+ register RegionPtr newSaved, doomed;
+ register ScreenPtr pScreen;
+ BoxRec extents;
+ int scrdx; /* bit translation distance on screen */
+ int scrdy;
+ int dx; /* distance window moved on screen */
+ int dy;
+
+ pScreen = pWin->drawable.pScreen;
+ pBackingStore = (miBSWindowPtr)(pWin->backStorage);
+ if ((pBackingStore->status == StatusNoPixmap) ||
+ (pBackingStore->status == StatusBadAlloc))
+ return NullRegion;
+
+ /*
+ * Compute the new saved region
+ */
+
+ newSaved = REGION_CREATE( pScreen, NullBox, 1);
+ extents.x1 = pWin->drawable.x;
+ extents.x2 = pWin->drawable.x + (int) pWin->drawable.width;
+ extents.y1 = pWin->drawable.y;
+ extents.y2 = pWin->drawable.y + (int) pWin->drawable.height;
+ REGION_INVERSE( pScreen, newSaved, &pWin->clipList, &extents);
+
+ REGION_TRANSLATE( pScreen, newSaved,
+ -pWin->drawable.x, -pWin->drawable.y);
+#ifdef SHAPE
+ if (wBoundingShape (pWin) || wClipShape (pWin)) {
+ if (wBoundingShape (pWin))
+ REGION_INTERSECT( pScreen, newSaved, newSaved,
+ wBoundingShape (pWin));
+ if (wClipShape (pWin))
+ REGION_INTERSECT( pScreen, newSaved, newSaved, wClipShape (pWin));
+ }
+#endif
+
+ pSavedRegion = &pBackingStore->SavedRegion;
+
+ /* now find any visible areas we can save from the screen */
+ /* and then translate newSaved to old local coordinates */
+ if (oldClip)
+ {
+ /* bit gravity makes things virtually too hard, punt */
+ if (((windx != 0) || (windy != 0)) &&
+ (pBackingStore->status != StatusContents))
+ miCreateBSPixmap(pWin, NullBox);
+
+ /*
+ * The window is moving this far on the screen
+ */
+ dx = pWin->drawable.x - oldx;
+ dy = pWin->drawable.y - oldy;
+ /*
+ * The bits will be moving on the screen by the
+ * amount the window is moving + the amount the
+ * bits are moving within the window
+ */
+ scrdx = windx + dx;
+ scrdy = windy + dy;
+
+ /*
+ * intersect at old bit position to discover the
+ * bits on the screen which can be put into the
+ * new backing store
+ */
+ REGION_TRANSLATE( pScreen, oldClip, windx - oldx, windy - oldy);
+ doomed = REGION_CREATE( pScreen, NullBox, 1);
+ REGION_INTERSECT( pScreen, doomed, oldClip, newSaved);
+ REGION_TRANSLATE( pScreen, oldClip, oldx - windx, oldy - windy);
+
+ /*
+ * Translate the old saved region to the position in the
+ * window where it will appear to be
+ */
+ REGION_TRANSLATE( pScreen, pSavedRegion, windx, windy);
+
+ /*
+ * Add the old saved region to the new saved region, so
+ * that calls to RestoreAreas will be able to fetch those
+ * bits back
+ */
+ REGION_UNION( pScreen, newSaved, newSaved, pSavedRegion);
+
+ /*
+ * Swap the new saved region into the window
+ */
+ {
+ RegionRec tmp;
+
+ tmp = *pSavedRegion;
+ *pSavedRegion = *newSaved;
+ *newSaved = tmp;
+ }
+ miResizeBackingStore (pWin, windx, windy, TRUE);
+
+ /*
+ * Compute the newly enabled region
+ * of backing store. This region will be
+ * set to background in the backing pixmap and
+ * sent as exposure events to the client.
+ */
+ REGION_SUBTRACT( pScreen, newSaved, pSavedRegion, newSaved);
+
+ /*
+ * Fetch bits which will be obscured from
+ * the screen
+ */
+ if (REGION_NOTEMPTY( pScreen, doomed))
+ {
+ /*
+ * Don't clear regions which have bits on the
+ * screen
+ */
+ REGION_SUBTRACT( pScreen, newSaved, newSaved, doomed);
+
+ /*
+ * Make the region to SaveDoomedAreas absolute, instead
+ * of window relative.
+ */
+ REGION_TRANSLATE( pScreen, doomed,
+ pWin->drawable.x, pWin->drawable.y);
+ (* pScreen->SaveDoomedAreas) (pWin, doomed, scrdx, scrdy);
+ }
+
+ REGION_DESTROY(pScreen, doomed);
+
+ /*
+ * and clear whatever there is that's new
+ */
+ if (REGION_NOTEMPTY( pScreen, newSaved))
+ {
+ miBSClearBackingRegion (pWin, newSaved);
+ /*
+ * Make the exposed region absolute
+ */
+ REGION_TRANSLATE(pScreen, newSaved,
+ pWin->drawable.x,
+ pWin->drawable.y);
+ }
+ else
+ {
+ REGION_DESTROY(pScreen, newSaved);
+ newSaved = NullRegion;
+ }
+ }
+ else
+ {
+ /*
+ * ForgetGravity: just reset backing store and
+ * expose the whole mess
+ */
+ REGION_COPY( pScreen, pSavedRegion, newSaved);
+ REGION_TRANSLATE( pScreen, newSaved,
+ pWin->drawable.x, pWin->drawable.y);
+
+ miResizeBackingStore (pWin, 0, 0, FALSE);
+ (void) miBSClearBackingStore (pWin, 0, 0, 0, 0, FALSE);
+ }
+
+ return newSaved;
+}
+
+/*
+ * Inform the backing store layer that you are about to validate
+ * a gc with a window, and that subsequent output to the window
+ * is (or is not) guaranteed to be already clipped to the visible
+ * regions of the window.
+ */
+
+static void
+miBSDrawGuarantee (pWin, pGC, guarantee)
+ WindowPtr pWin;
+ GCPtr pGC;
+ int guarantee;
+{
+ miBSGCPtr pPriv;
+
+ if (pWin->backStorage)
+ {
+ pPriv = (miBSGCPtr)pGC->devPrivates[miBSGCIndex].ptr;
+ if (!pPriv)
+ (void) miBSCreateGCPrivate (pGC);
+ pPriv = (miBSGCPtr)pGC->devPrivates[miBSGCIndex].ptr;
+ if (pPriv)
+ {
+ /*
+ * XXX KLUDGE ALERT
+ *
+ * when the GC is Cheap pPriv will point
+ * at some device's gc func structure. guarantee
+ * will point at the ChangeGC entry of that struct
+ * and will never match a valid guarantee value.
+ */
+ switch (pPriv->guarantee)
+ {
+ case GuaranteeNothing:
+ case GuaranteeVisBack:
+ pPriv->guarantee = guarantee;
+ break;
+ }
+ }
+ }
+}
+
+#define noBackingCopy (GCGraphicsExposures|GCClipXOrigin|GCClipYOrigin| \
+ GCClipMask|GCSubwindowMode| \
+ GCTileStipXOrigin|GCTileStipYOrigin)
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSValidateGC --
+ * Wrapper around output-library's ValidateGC routine
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ *
+ * Notes:
+ * The idea here is to perform several functions:
+ * - All the output calls must be intercepted and routed to
+ * backing-store as necessary.
+ * - pGC in the window's devBackingStore must be set up with the
+ * clip list appropriate for writing to pBackingPixmap (i.e.
+ * the inverse of the window's clipList intersected with the
+ * clientClip of the GC). Since the destination for this GC is
+ * a pixmap, it is sufficient to set the clip list as its
+ * clientClip.
+ *-----------------------------------------------------------------------
+ */
+
+static void
+miBSValidateGC (pGC, stateChanges, pDrawable)
+ GCPtr pGC;
+ unsigned long stateChanges;
+ DrawablePtr pDrawable;
+{
+ GCPtr pBackingGC;
+ miBSWindowPtr pWindowPriv;
+ miBSGCPtr pPriv;
+ WindowPtr pWin;
+ int lift_functions;
+ RegionPtr backingCompositeClip = NULL;
+
+ if (pDrawable->type != DRAWABLE_PIXMAP)
+ {
+ pWin = (WindowPtr) pDrawable;
+ pWindowPriv = (miBSWindowPtr) pWin->backStorage;
+ lift_functions = (pWindowPriv == (miBSWindowPtr) NULL);
+ }
+ else
+ {
+ pWin = (WindowPtr) NULL;
+ lift_functions = TRUE;
+ }
+
+ pPriv = (miBSGCPtr)pGC->devPrivates[miBSGCIndex].ptr;
+
+ FUNC_PROLOGUE (pGC, pPriv);
+
+ (*pGC->funcs->ValidateGC) (pGC, stateChanges, pDrawable);
+
+ /*
+ * rewrap funcs and ops as Validate may have changed them
+ */
+
+ pPriv->wrapFuncs = pGC->funcs;
+ pPriv->wrapOps = pGC->ops;
+
+ if (!lift_functions && ((pPriv->guarantee == GuaranteeVisBack) ||
+ (pWindowPriv->status == StatusNoPixmap) ||
+ (pWindowPriv->status == StatusBadAlloc)))
+ lift_functions = TRUE;
+
+ /*
+ * check to see if a new backingCompositeClip region must
+ * be generated
+ */
+
+ if (!lift_functions &&
+ ((pDrawable->serialNumber != pPriv->serialNumber) ||
+ (stateChanges&(GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode))))
+ {
+ if (REGION_NOTEMPTY(pGC->pScreen, &pWindowPriv->SavedRegion))
+ {
+ backingCompositeClip = REGION_CREATE(pGC->pScreen, NULL, 1);
+ if ((pGC->clientClipType == CT_NONE) ||
+ (pGC->clientClipType == CT_PIXMAP))
+ {
+ REGION_COPY(pGC->pScreen, backingCompositeClip,
+ &pWindowPriv->SavedRegion);
+ }
+ else
+ {
+ /*
+ * Make a new copy of the client clip, translated to
+ * its proper origin.
+ */
+
+ REGION_COPY(pGC->pScreen, backingCompositeClip,
+ pGC->clientClip);
+ REGION_TRANSLATE(pGC->pScreen, backingCompositeClip,
+ pGC->clipOrg.x,
+ pGC->clipOrg.y);
+ REGION_INTERSECT(pGC->pScreen, backingCompositeClip,
+ backingCompositeClip,
+ &pWindowPriv->SavedRegion);
+ }
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ RegionPtr translatedClip;
+
+ /* XXX
+ * any output in IncludeInferiors mode will not
+ * be redirected to Inferiors backing store. This
+ * can be fixed only at great cost to the shadow routines.
+ */
+ translatedClip = NotClippedByChildren (pWin);
+ REGION_TRANSLATE(pGC->pScreen, translatedClip,
+ -pDrawable->x,
+ -pDrawable->y);
+ REGION_SUBTRACT(pGC->pScreen, backingCompositeClip,
+ backingCompositeClip, translatedClip);
+ REGION_DESTROY(pGC->pScreen, translatedClip);
+ }
+ if (!REGION_NOTEMPTY(pGC->pScreen, backingCompositeClip))
+ lift_functions = TRUE;
+ }
+ else
+ {
+ lift_functions = TRUE;
+ }
+
+ /* Reset the status when drawing to an unoccluded window so that
+ * future SaveAreas will actually copy bits from the screen. Note that
+ * output to root window in IncludeInferiors mode will not cause this
+ * to change. This causes all transient graphics by the window
+ * manager to the root window to not enable backing store.
+ */
+ if (lift_functions && (pWindowPriv->status == StatusVirtual) &&
+ (pWin->parent || pGC->subWindowMode != IncludeInferiors))
+ pWindowPriv->status = StatusVDirty;
+ }
+
+ /*
+ * if no backing store has been allocated, and it's needed,
+ * create it now.
+ */
+
+ if (!lift_functions && !pWindowPriv->pBackingPixmap)
+ {
+ miCreateBSPixmap (pWin, NullBox);
+ if (!pWindowPriv->pBackingPixmap)
+ lift_functions = TRUE;
+ }
+
+ /*
+ * create the backing GC if needed, lift functions
+ * if the creation fails
+ */
+
+ if (!lift_functions && !pPriv->pBackingGC)
+ {
+ int status;
+ XID noexpose = xFalse;
+
+ /* We never want ops with the backingGC to generate GraphicsExpose */
+ pBackingGC = CreateGC ((DrawablePtr)pWindowPriv->pBackingPixmap,
+ GCGraphicsExposures, &noexpose, &status);
+ if (status != Success)
+ lift_functions = TRUE;
+ else
+ pPriv->pBackingGC = pBackingGC;
+ }
+
+ pBackingGC = pPriv->pBackingGC;
+
+ pPriv->stateChanges |= stateChanges;
+
+ if (lift_functions)
+ {
+ if (backingCompositeClip)
+ REGION_DESTROY( pGC->pScreen, backingCompositeClip);
+
+ /* unwrap the GC again */
+ miBSDestroyGCPrivate (pGC);
+
+ return;
+ }
+
+ /*
+ * the rest of this function gets the pBackingGC
+ * into shape for possible draws
+ */
+
+ pPriv->stateChanges &= ~noBackingCopy;
+ if (pPriv->stateChanges)
+ CopyGC(pGC, pBackingGC, pPriv->stateChanges);
+ if ((pGC->patOrg.x - pWindowPriv->x) != pBackingGC->patOrg.x ||
+ (pGC->patOrg.y - pWindowPriv->y) != pBackingGC->patOrg.y)
+ {
+ XID vals[2];
+ vals[0] = pGC->patOrg.x - pWindowPriv->x;
+ vals[1] = pGC->patOrg.y - pWindowPriv->y;
+ DoChangeGC(pBackingGC, GCTileStipXOrigin|GCTileStipYOrigin, vals, 0);
+ }
+ pPriv->stateChanges = 0;
+
+ if (backingCompositeClip)
+ {
+ XID vals[2];
+
+ if (pGC->clientClipType == CT_PIXMAP)
+ {
+ (*pBackingGC->funcs->CopyClip)(pBackingGC, pGC);
+ REGION_TRANSLATE(pGC->pScreen, backingCompositeClip,
+ -pGC->clipOrg.x, -pGC->clipOrg.y);
+ vals[0] = pGC->clipOrg.x - pWindowPriv->x;
+ vals[1] = pGC->clipOrg.y - pWindowPriv->y;
+ DoChangeGC(pBackingGC, GCClipXOrigin|GCClipYOrigin, vals, 0);
+ (* pGC->pScreen->BackingStoreFuncs.SetClipmaskRgn)
+ (pBackingGC, backingCompositeClip);
+ REGION_DESTROY( pGC->pScreen, backingCompositeClip);
+ }
+ else
+ {
+ vals[0] = -pWindowPriv->x;
+ vals[1] = -pWindowPriv->y;
+ DoChangeGC(pBackingGC, GCClipXOrigin|GCClipYOrigin, vals, 0);
+ (*pBackingGC->funcs->ChangeClip) (pBackingGC, CT_REGION, backingCompositeClip, 0);
+ }
+ pPriv->serialNumber = pDrawable->serialNumber;
+ }
+
+ if (pWindowPriv->pBackingPixmap->drawable.serialNumber
+ != pBackingGC->serialNumber)
+ {
+ ValidateGC((DrawablePtr)pWindowPriv->pBackingPixmap, pBackingGC);
+ }
+
+ if (pBackingGC->clientClip == 0)
+ ErrorF ("backing store clip list nil");
+
+ FUNC_EPILOGUE (pGC, pPriv);
+}
+
+static void
+miBSChangeGC (pGC, mask)
+ GCPtr pGC;
+ unsigned long mask;
+{
+ miBSGCPtr pPriv = (miBSGCPtr) (pGC)->devPrivates[miBSGCIndex].ptr;
+
+ FUNC_PROLOGUE (pGC, pPriv);
+
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+
+ FUNC_EPILOGUE (pGC, pPriv);
+}
+
+static void
+miBSCopyGC (pGCSrc, mask, pGCDst)
+ GCPtr pGCSrc, pGCDst;
+ unsigned long mask;
+{
+ miBSGCPtr pPriv = (miBSGCPtr) (pGCDst)->devPrivates[miBSGCIndex].ptr;
+
+ FUNC_PROLOGUE (pGCDst, pPriv);
+
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+
+ FUNC_EPILOGUE (pGCDst, pPriv);
+}
+
+static void
+miBSDestroyGC (pGC)
+ GCPtr pGC;
+{
+ miBSGCPtr pPriv = (miBSGCPtr) (pGC)->devPrivates[miBSGCIndex].ptr;
+
+ FUNC_PROLOGUE (pGC, pPriv);
+
+ if (pPriv->pBackingGC)
+ FreeGC(pPriv->pBackingGC, (GContext)0);
+
+ (*pGC->funcs->DestroyGC) (pGC);
+
+ FUNC_EPILOGUE (pGC, pPriv);
+
+ xfree(pPriv);
+}
+
+static void
+miBSChangeClip(pGC, type, pvalue, nrects)
+ GCPtr pGC;
+ int type;
+ pointer pvalue;
+ int nrects;
+{
+ miBSGCPtr pPriv = (miBSGCPtr) (pGC)->devPrivates[miBSGCIndex].ptr;
+
+ FUNC_PROLOGUE (pGC, pPriv);
+
+ (* pGC->funcs->ChangeClip)(pGC, type, pvalue, nrects);
+
+ FUNC_EPILOGUE (pGC, pPriv);
+}
+
+static void
+miBSCopyClip(pgcDst, pgcSrc)
+ GCPtr pgcDst, pgcSrc;
+{
+ miBSGCPtr pPriv = (miBSGCPtr) (pgcDst)->devPrivates[miBSGCIndex].ptr;
+
+ FUNC_PROLOGUE (pgcDst, pPriv);
+
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+
+ FUNC_EPILOGUE (pgcDst, pPriv);
+}
+
+static void
+miBSDestroyClip(pGC)
+ GCPtr pGC;
+{
+ miBSGCPtr pPriv = (miBSGCPtr) (pGC)->devPrivates[miBSGCIndex].ptr;
+
+ FUNC_PROLOGUE (pGC, pPriv);
+
+ (* pGC->funcs->DestroyClip)(pGC);
+
+ FUNC_EPILOGUE (pGC, pPriv);
+}
+
+static void
+miDestroyBSPixmap (pWin)
+ WindowPtr pWin;
+{
+ miBSWindowPtr pBackingStore;
+ ScreenPtr pScreen;
+
+ pScreen = pWin->drawable.pScreen;
+ pBackingStore = (miBSWindowPtr) pWin->backStorage;
+ if (pBackingStore->pBackingPixmap)
+ (* pScreen->DestroyPixmap)(pBackingStore->pBackingPixmap);
+ pBackingStore->pBackingPixmap = NullPixmap;
+ pBackingStore->x = 0;
+ pBackingStore->y = 0;
+ if (pBackingStore->backgroundState == BackgroundPixmap)
+ (* pScreen->DestroyPixmap)(pBackingStore->background.pixmap);
+ pBackingStore->backgroundState = None;
+ pBackingStore->status = StatusNoPixmap;
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+}
+
+static void
+miTileVirtualBS (pWin)
+ WindowPtr pWin;
+{
+ miBSWindowPtr pBackingStore;
+
+ pBackingStore = (miBSWindowPtr) pWin->backStorage;
+ if (pBackingStore->backgroundState == BackgroundPixmap)
+ (* pWin->drawable.pScreen->DestroyPixmap)
+ (pBackingStore->background.pixmap);
+ pBackingStore->backgroundState = pWin->backgroundState;
+ pBackingStore->background = pWin->background;
+ if (pBackingStore->backgroundState == BackgroundPixmap)
+ pBackingStore->background.pixmap->refcnt++;
+
+ if (pBackingStore->status != StatusVDirty)
+ pBackingStore->status = StatusVirtual;
+
+ /*
+ * punt parent relative tiles and do it now
+ */
+ if (pBackingStore->backgroundState == ParentRelative)
+ miCreateBSPixmap (pWin, NullBox);
+}
+
+#ifdef DEBUG
+static int BSAllocationsFailed = 0;
+#define FAILEDSIZE 32
+static struct { int w, h; } failedRecord[FAILEDSIZE];
+static int failedIndex;
+#endif
+
+static void
+miCreateBSPixmap (pWin, pExtents)
+ WindowPtr pWin;
+ BoxPtr pExtents;
+{
+ miBSWindowPtr pBackingStore;
+ ScreenPtr pScreen;
+ PixUnion background;
+ char backgroundState;
+ BoxPtr extents;
+ Bool backSet;
+
+ pScreen = pWin->drawable.pScreen;
+ pBackingStore = (miBSWindowPtr) pWin->backStorage;
+ if (pBackingStore->status == StatusBadAlloc)
+ return;
+ backSet = ((pBackingStore->status == StatusVirtual) ||
+ (pBackingStore->status == StatusVDirty));
+
+ extents = REGION_EXTENTS( pScreen, &pBackingStore->SavedRegion);
+
+ if (!pBackingStore->pBackingPixmap)
+ {
+ /* the policy here could be more sophisticated */
+ pBackingStore->x = extents->x1;
+ pBackingStore->y = extents->y1;
+ pBackingStore->pBackingPixmap =
+ (PixmapPtr)(* pScreen->CreatePixmap)
+ (pScreen,
+ extents->x2 - extents->x1,
+ extents->y2 - extents->y1,
+ pWin->drawable.depth);
+ }
+ if (!pBackingStore->pBackingPixmap)
+ {
+#ifdef DEBUG
+ BSAllocationsFailed++;
+ /*
+ * record failed allocations
+ */
+ failedRecord[failedIndex].w = pWin->drawable.width;
+ failedRecord[failedIndex].h = pWin->drawable.height;
+ failedIndex++;
+ if (failedIndex == FAILEDSIZE)
+ failedIndex = 0;
+#endif
+#ifdef BSEAGER
+ pBackingStore->status = StatusNoPixmap;
+#else
+ pBackingStore->status = StatusBadAlloc;
+#endif
+ return;
+ }
+
+ pBackingStore->status = StatusContents;
+
+ if (backSet)
+ {
+ backgroundState = pWin->backgroundState;
+ background = pWin->background;
+
+ pWin->backgroundState = pBackingStore->backgroundState;
+ pWin->background = pBackingStore->background;
+ if (pWin->backgroundState == BackgroundPixmap)
+ pWin->background.pixmap->refcnt++;
+ }
+
+ if (!pExtents)
+ pExtents = extents;
+
+ if (pExtents->y1 != pExtents->y2)
+ {
+ RegionPtr exposed;
+
+ exposed = miBSClearBackingStore(pWin,
+ pExtents->x1, pExtents->y1,
+ pExtents->x2 - pExtents->x1,
+ pExtents->y2 - pExtents->y1,
+ !backSet);
+ if (exposed)
+ {
+ miSendExposures(pWin, exposed, pWin->drawable.x, pWin->drawable.y);
+ REGION_DESTROY( pScreen, exposed);
+ }
+ }
+
+ if (backSet)
+ {
+ if (pWin->backgroundState == BackgroundPixmap)
+ (* pScreen->DestroyPixmap) (pWin->background.pixmap);
+ pWin->backgroundState = backgroundState;
+ pWin->background = background;
+ if (pBackingStore->backgroundState == BackgroundPixmap)
+ (* pScreen->DestroyPixmap) (pBackingStore->background.pixmap);
+ pBackingStore->backgroundState = None;
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miBSExposeCopy --
+ * Handle the restoration of areas exposed by graphics operations.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * prgnExposed has the areas exposed from backing-store removed
+ * from it.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miBSExposeCopy (pSrc, pDst, pGC, prgnExposed, srcx, srcy, dstx, dsty, plane)
+ WindowPtr pSrc;
+ DrawablePtr pDst;
+ GCPtr pGC;
+ RegionPtr prgnExposed;
+ int srcx, srcy;
+ int dstx, dsty;
+ unsigned long plane;
+{
+ RegionRec tempRgn;
+ miBSWindowPtr pBackingStore;
+ RegionPtr (*copyProc)();
+ GCPtr pScratchGC;
+ register BoxPtr pBox;
+ register int i;
+ register int dx, dy;
+ BITS32 gcMask;
+
+ if (!REGION_NOTEMPTY(pGC->pScreen, prgnExposed))
+ return;
+ pBackingStore = (miBSWindowPtr)pSrc->backStorage;
+
+ if ((pBackingStore->status == StatusNoPixmap) ||
+ (pBackingStore->status == StatusBadAlloc))
+ return;
+
+ REGION_INIT( pGC->pScreen, &tempRgn, NullBox, 0);
+ REGION_INTERSECT( pGC->pScreen, &tempRgn, prgnExposed,
+ &pBackingStore->SavedRegion);
+ REGION_SUBTRACT( pGC->pScreen, prgnExposed, prgnExposed, &tempRgn);
+
+ if (plane != 0) {
+ copyProc = pGC->ops->CopyPlane;
+ } else {
+ copyProc = pGC->ops->CopyArea;
+ }
+
+ dx = dstx - srcx;
+ dy = dsty - srcy;
+
+ switch (pBackingStore->status) {
+ case StatusVirtual:
+ case StatusVDirty:
+ pScratchGC = GetScratchGC (pDst->depth, pDst->pScreen);
+ if (pScratchGC)
+ {
+ gcMask = 0;
+ if (pGC->alu != pScratchGC->alu)
+ gcMask = GCFunction;
+ if (pGC->planemask != pScratchGC->planemask)
+ gcMask |= GCPlaneMask;
+ if (gcMask)
+ CopyGC (pGC, pScratchGC, gcMask);
+ miBSFillVirtualBits (pDst, pScratchGC, &tempRgn, dx, dy,
+ (int) pBackingStore->backgroundState,
+ pBackingStore->background,
+ ~0L);
+ FreeScratchGC (pScratchGC);
+ }
+ break;
+ case StatusContents:
+ for (i = REGION_NUM_RECTS(&tempRgn), pBox = REGION_RECTS(&tempRgn);
+ --i >= 0;
+ pBox++)
+ {
+ (* copyProc) (pBackingStore->pBackingPixmap, pDst, pGC,
+ pBox->x1 - pBackingStore->x,
+ pBox->y1 - pBackingStore->y,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1,
+ pBox->x1 + dx, pBox->y1 + dy, plane);
+ }
+ break;
+ }
+ REGION_UNINIT( pGC->pScreen, &tempRgn);
+}
diff --git a/xc/programs/Xserver/mi/mibstore.h b/xc/programs/Xserver/mi/mibstore.h
new file mode 100644
index 000000000..12579e2a7
--- /dev/null
+++ b/xc/programs/Xserver/mi/mibstore.h
@@ -0,0 +1,32 @@
+/*-
+ * mibstore.h --
+ * Header file for users of the MI backing-store scheme.
+ *
+ * Copyright (c) 1987 by the Regents of the University of California
+ *
+ * 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. The University of California
+ * makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ *
+ * "$XConsortium: mibstore.h,v 5.2 93/10/12 11:41:12 dpw Exp $ SPRITE (Berkeley)"
+ */
+
+
+/* $XFree86: xc/programs/Xserver/mi/mibstore.h,v 1.3 1998/04/05 16:42:31 robin Exp $ */
+
+#ifndef _MIBSTORE_H
+#define _MIBSTORE_H
+
+#include "screenint.h"
+
+extern void miInitializeBackingStore(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/
+#endif
+);
+
+#endif /* _MIBSTORE_H */
diff --git a/xc/programs/Xserver/mi/mibstorest.h b/xc/programs/Xserver/mi/mibstorest.h
new file mode 100644
index 000000000..b2bf8af2c
--- /dev/null
+++ b/xc/programs/Xserver/mi/mibstorest.h
@@ -0,0 +1,85 @@
+/*
+ * mibstorest.h
+ *
+ * internal structure definitions for mi backing store
+ */
+
+/* $TOG: mibstorest.h /main/13 1998/02/09 14:46:10 kaleb $ */
+
+/*
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+*/
+
+/* $XFree86: xc/programs/Xserver/mi/mibstorest.h,v 1.3 1998/10/04 09:39:25 dawes Exp $ */
+
+#include "mibstore.h"
+#include "regionstr.h"
+
+/*
+ * One of these structures is allocated per GC used with a backing-store
+ * drawable.
+ */
+
+typedef struct {
+ GCPtr pBackingGC; /* Copy of the GC but with graphicsExposures
+ * set FALSE and the clientClip set to
+ * clip output to the valid regions of the
+ * backing pixmap. */
+ int guarantee; /* GuaranteeNothing, etc. */
+ unsigned long serialNumber; /* clientClip computed time */
+ unsigned long stateChanges; /* changes in parent gc since last copy */
+ GCOps *wrapOps; /* wrapped ops */
+ GCFuncs *wrapFuncs; /* wrapped funcs */
+} miBSGCRec, *miBSGCPtr;
+
+/*
+ * one of these structures is allocated per Window with backing store
+ */
+
+typedef struct {
+ PixmapPtr pBackingPixmap; /* Pixmap for saved areas */
+ short x; /* origin of pixmap relative to window */
+ short y;
+ RegionRec SavedRegion; /* Valid area in pBackingPixmap */
+ char viewable; /* Tracks pWin->viewable so SavedRegion may
+ * be initialized correctly when the window
+ * is first mapped */
+ char status; /* StatusNoPixmap, etc. */
+ char backgroundState; /* background type */
+ PixUnion background; /* background pattern */
+} miBSWindowRec, *miBSWindowPtr;
+
+#define StatusNoPixmap 1 /* pixmap has not been created */
+#define StatusVirtual 2 /* pixmap is virtual, tiled with background */
+#define StatusVDirty 3 /* pixmap is virtual, visiblt has contents */
+#define StatusBadAlloc 4 /* pixmap create failed, do not try again */
+#define StatusContents 5 /* pixmap is created, has valid contents */
+
+typedef struct {
+ /*
+ * screen func wrappers
+ */
+ CloseScreenProcPtr CloseScreen;
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+ CreateGCProcPtr CreateGC;
+ DestroyWindowProcPtr DestroyWindow;
+} miBSScreenRec, *miBSScreenPtr;
diff --git a/xc/programs/Xserver/mi/miclipn.c b/xc/programs/Xserver/mi/miclipn.c
new file mode 100644
index 000000000..576b35d96
--- /dev/null
+++ b/xc/programs/Xserver/mi/miclipn.c
@@ -0,0 +1,69 @@
+/* $TOG: miclipn.c /main/3 1998/02/09 14:46:26 kaleb $ */
+/*
+
+Copyright 1990, 1998 The Open Group
+
+All Rights Reserved.
+
+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 "windowstr.h"
+#include "scrnintstr.h"
+
+static void (*clipNotify)() = 0;
+static void (*ClipNotifies[MAXSCREENS])();
+
+static void
+miClipNotifyWrapper(pWin, dx, dy)
+ WindowPtr pWin;
+ int dx, dy;
+{
+ if (clipNotify)
+ (*clipNotify)(pWin, dx, dy);
+ if (ClipNotifies[pWin->drawable.pScreen->myNum])
+ (*ClipNotifies[pWin->drawable.pScreen->myNum])(pWin, dx, dy);
+}
+
+/*
+ * miClipNotify --
+ * Hook to let DDX request notification when the clipList of
+ * a window is recomputed on any screen. For R4 compatibility;
+ * better if you wrap the ClipNotify screen proc yourself.
+ */
+
+static unsigned long clipGeneration = 0;
+
+void
+miClipNotify (func)
+ void (*func)();
+{
+ int i;
+
+ clipNotify = func;
+ if (clipGeneration != serverGeneration)
+ {
+ clipGeneration = serverGeneration;
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ ClipNotifies[i] = screenInfo.screens[i]->ClipNotify;
+ screenInfo.screens[i]->ClipNotify = miClipNotifyWrapper;
+ }
+ }
+}
diff --git a/xc/programs/Xserver/mi/micmap.c b/xc/programs/Xserver/mi/micmap.c
new file mode 100644
index 000000000..176e6dffd
--- /dev/null
+++ b/xc/programs/Xserver/mi/micmap.c
@@ -0,0 +1,628 @@
+/* $XConsortium: cfbcmap.c,v 4.19 94/04/17 20:28:46 dpw Exp $ */
+/************************************************************
+Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
+
+ 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 no-
+tice appear in all copies and that both that copyright no-
+tice and this permission notice appear in supporting docu-
+mentation, and that the names of Sun or X Consortium
+not be used in advertising or publicity pertaining to
+distribution of the software without specific prior
+written permission. Sun and X Consortium make no
+representations about the suitability of this software for
+any purpose. It is provided "as is" without any express or
+implied warranty.
+
+SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
+NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
+ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+/* $XFree86: xc/programs/Xserver/mi/micmap.c,v 1.8 1999/04/11 13:11:19 dawes Exp $ */
+
+/*
+ * This is based on cfbcmap.c. The functions here are useful independently
+ * of cfb, which is the reason for including them here. How "mi" these
+ * are may be debatable.
+ */
+
+
+#include "X.h"
+#include "Xproto.h"
+#include "scrnintstr.h"
+#include "colormapst.h"
+#include "resource.h"
+#include "globals.h"
+#include "micmap.h"
+
+ColormapPtr miInstalledMaps[MAXSCREENS];
+
+static Bool miDoInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp,
+ int *ndepthp, int *rootDepthp, VisualID *defaultVisp,
+ unsigned long sizes, int bitsPerRGB, int preferredVis);
+
+miInitVisualsProcPtr miInitVisualsProc = miDoInitVisuals;
+
+int
+miListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
+{
+ /* By the time we are processing requests, we can guarantee that there
+ * is always a colormap installed */
+ *pmaps = miInstalledMaps[pScreen->myNum]->mid;
+ return (1);
+}
+
+void
+miInstallColormap(ColormapPtr pmap)
+{
+ int index = pmap->pScreen->myNum;
+ ColormapPtr oldpmap = miInstalledMaps[index];
+
+ if(pmap != oldpmap)
+ {
+ /* Uninstall pInstalledMap. No hardware changes required, just
+ * notify all interested parties. */
+ if(oldpmap != (ColormapPtr)None)
+ WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
+ /* Install pmap */
+ miInstalledMaps[index] = pmap;
+ WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
+
+ }
+}
+
+void
+miUninstallColormap(ColormapPtr pmap)
+{
+ int index = pmap->pScreen->myNum;
+ ColormapPtr curpmap = miInstalledMaps[index];
+
+ if(pmap == curpmap)
+ {
+ if (pmap->mid != pmap->pScreen->defColormap)
+ {
+ curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
+ RT_COLORMAP);
+ (*pmap->pScreen->InstallColormap)(curpmap);
+ }
+ }
+}
+
+void
+miResolveColor(unsigned short *pred, unsigned short *pgreen,
+ unsigned short *pblue, VisualPtr pVisual)
+{
+ int shift = 16 - pVisual->bitsPerRGBValue;
+ unsigned lim = (1 << pVisual->bitsPerRGBValue) - 1;
+
+ if ((pVisual->class == PseudoColor) || (pVisual->class == DirectColor))
+ {
+ /* rescale to rgb bits */
+ *pred = ((*pred >> shift) * 65535) / lim;
+ *pgreen = ((*pgreen >> shift) * 65535) / lim;
+ *pblue = ((*pblue >> shift) * 65535) / lim;
+ }
+ else if (pVisual->class == GrayScale)
+ {
+ /* rescale to gray then rgb bits */
+ *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100;
+ *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim;
+ }
+ else if (pVisual->class == StaticGray)
+ {
+ unsigned limg = pVisual->ColormapEntries - 1;
+ /* rescale to gray then [0..limg] then [0..65535] then rgb bits */
+ *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100;
+ *pred = ((((*pred * (limg + 1))) >> 16) * 65535) / limg;
+ *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim;
+ }
+ else
+ {
+ unsigned limr, limg, limb;
+
+ limr = pVisual->redMask >> pVisual->offsetRed;
+ limg = pVisual->greenMask >> pVisual->offsetGreen;
+ limb = pVisual->blueMask >> pVisual->offsetBlue;
+ /* rescale to [0..limN] then [0..65535] then rgb bits */
+ *pred = ((((((*pred * (limr + 1)) >> 16) *
+ 65535) / limr) >> shift) * 65535) / lim;
+ *pgreen = ((((((*pgreen * (limg + 1)) >> 16) *
+ 65535) / limg) >> shift) * 65535) / lim;
+ *pblue = ((((((*pblue * (limb + 1)) >> 16) *
+ 65535) / limb) >> shift) * 65535) / lim;
+ }
+}
+
+Bool
+miInitializeColormap(ColormapPtr pmap)
+{
+ register unsigned i;
+ register VisualPtr pVisual;
+ unsigned lim, maxent, shift;
+
+ pVisual = pmap->pVisual;
+ lim = (1 << pVisual->bitsPerRGBValue) - 1;
+ shift = 16 - pVisual->bitsPerRGBValue;
+ maxent = pVisual->ColormapEntries - 1;
+ if (pVisual->class == TrueColor)
+ {
+ unsigned limr, limg, limb;
+
+ limr = pVisual->redMask >> pVisual->offsetRed;
+ limg = pVisual->greenMask >> pVisual->offsetGreen;
+ limb = pVisual->blueMask >> pVisual->offsetBlue;
+ for(i = 0; i <= maxent; i++)
+ {
+ /* rescale to [0..65535] then rgb bits */
+ pmap->red[i].co.local.red =
+ ((((i * 65535) / limr) >> shift) * 65535) / lim;
+ pmap->green[i].co.local.green =
+ ((((i * 65535) / limg) >> shift) * 65535) / lim;
+ pmap->blue[i].co.local.blue =
+ ((((i * 65535) / limb) >> shift) * 65535) / lim;
+ }
+ }
+ else if (pVisual->class == StaticColor)
+ {
+ unsigned limr, limg, limb;
+
+ limr = pVisual->redMask >> pVisual->offsetRed;
+ limg = pVisual->greenMask >> pVisual->offsetGreen;
+ limb = pVisual->blueMask >> pVisual->offsetBlue;
+ for(i = 0; i <= maxent; i++)
+ {
+ /* rescale to [0..65535] then rgb bits */
+ pmap->red[i].co.local.red =
+ ((((((i & pVisual->redMask) >> pVisual->offsetRed)
+ * 65535) / limr) >> shift) * 65535) / lim;
+ pmap->red[i].co.local.green =
+ ((((((i & pVisual->greenMask) >> pVisual->offsetGreen)
+ * 65535) / limg) >> shift) * 65535) / lim;
+ pmap->red[i].co.local.blue =
+ ((((((i & pVisual->blueMask) >> pVisual->offsetBlue)
+ * 65535) / limb) >> shift) * 65535) / lim;
+ }
+ }
+ else if (pVisual->class == StaticGray)
+ {
+ for(i = 0; i <= maxent; i++)
+ {
+ /* rescale to [0..65535] then rgb bits */
+ pmap->red[i].co.local.red = ((((i * 65535) / maxent) >> shift)
+ * 65535) / lim;
+ pmap->red[i].co.local.green = pmap->red[i].co.local.red;
+ pmap->red[i].co.local.blue = pmap->red[i].co.local.red;
+ }
+ }
+ return TRUE;
+}
+
+/* When simulating DirectColor on PseudoColor hardware, multiple
+ entries of the colormap must be updated
+ */
+
+#define AddElement(mask) { \
+ pixel = red | green | blue; \
+ for (i = 0; i < nresult; i++) \
+ if (outdefs[i].pixel == pixel) \
+ break; \
+ if (i == nresult) \
+ { \
+ nresult++; \
+ outdefs[i].pixel = pixel; \
+ outdefs[i].flags = 0; \
+ } \
+ outdefs[i].flags |= (mask); \
+ outdefs[i].red = pmap->red[red >> pVisual->offsetRed].co.local.red; \
+ outdefs[i].green = pmap->green[green >> pVisual->offsetGreen].co.local.green; \
+ outdefs[i].blue = pmap->blue[blue >> pVisual->offsetBlue].co.local.blue; \
+}
+
+int
+miExpandDirectColors(ColormapPtr pmap, int ndef, xColorItem *indefs,
+ xColorItem *outdefs)
+{
+ register int red, green, blue;
+ int maxred, maxgreen, maxblue;
+ int stepred, stepgreen, stepblue;
+ VisualPtr pVisual;
+ register int pixel;
+ register int nresult;
+ register int i;
+
+ pVisual = pmap->pVisual;
+
+ stepred = 1 << pVisual->offsetRed;
+ stepgreen = 1 << pVisual->offsetGreen;
+ stepblue = 1 << pVisual->offsetBlue;
+ maxred = pVisual->redMask;
+ maxgreen = pVisual->greenMask;
+ maxblue = pVisual->blueMask;
+ nresult = 0;
+ for (;ndef--; indefs++)
+ {
+ if (indefs->flags & DoRed)
+ {
+ red = indefs->pixel & pVisual->redMask;
+ for (green = 0; green <= maxgreen; green += stepgreen)
+ {
+ for (blue = 0; blue <= maxblue; blue += stepblue)
+ {
+ AddElement (DoRed)
+ }
+ }
+ }
+ if (indefs->flags & DoGreen)
+ {
+ green = indefs->pixel & pVisual->greenMask;
+ for (red = 0; red <= maxred; red += stepred)
+ {
+ for (blue = 0; blue <= maxblue; blue += stepblue)
+ {
+ AddElement (DoGreen)
+ }
+ }
+ }
+ if (indefs->flags & DoBlue)
+ {
+ blue = indefs->pixel & pVisual->blueMask;
+ for (red = 0; red <= maxred; red += stepred)
+ {
+ for (green = 0; green <= maxgreen; green += stepgreen)
+ {
+ AddElement (DoBlue)
+ }
+ }
+ }
+ }
+ return nresult;
+}
+
+Bool
+miCreateDefColormap(ScreenPtr pScreen)
+{
+/*
+ * In the following sources PC X server vendors may want to delete
+ * "_not_tog" from "#ifdef WIN32_not_tog"
+ */
+#ifdef WIN32_not_tog
+ /*
+ * these are the MS-Windows desktop colors, adjusted for X's 16-bit
+ * color specifications.
+ */
+ static xColorItem citems[] = {
+ { 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 }
+ };
+#define NUM_DESKTOP_COLORS sizeof citems / sizeof citems[0]
+ int i;
+#else
+ unsigned short zero = 0, ones = 0xFFFF;
+#endif
+ Pixel wp, bp;
+ VisualPtr pVisual;
+ ColormapPtr cmap;
+ int alloctype;
+
+ for (pVisual = pScreen->visuals;
+ pVisual->vid != pScreen->rootVisual;
+ pVisual++)
+ ;
+
+ if (pScreen->rootDepth == 1 || (pVisual->class & DynamicClass))
+ alloctype = AllocNone;
+ else
+ alloctype = AllocAll;
+
+ if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap,
+ alloctype, 0) != Success)
+ return FALSE;
+
+ if (pScreen->rootDepth > 1) {
+ wp = pScreen->whitePixel;
+ bp = pScreen->blackPixel;
+#ifdef WIN32_not_tog
+ for (i = 0; i < NUM_DESKTOP_COLORS; i++) {
+ if (AllocColor (cmap,
+ &citems[i].red, &citems[i].green, &citems[i].blue,
+ &citems[i].pixel, 0) != Success)
+ return FALSE;
+ }
+#else
+ if ((AllocColor(cmap, &ones, &ones, &ones, &wp, 0) !=
+ Success) ||
+ (AllocColor(cmap, &zero, &zero, &zero, &bp, 0) !=
+ Success))
+ return FALSE;
+ pScreen->whitePixel = wp;
+ pScreen->blackPixel = bp;
+#endif
+ }
+
+ (*pScreen->InstallColormap)(cmap);
+ return TRUE;
+}
+
+#define _RZ(d) ((d + 2) / 3)
+#define _RS(d) 0
+#define _RM(d) ((1 << _RZ(d)) - 1)
+#define _GZ(d) ((d - _RZ(d) + 1) / 2)
+#define _GS(d) _RZ(d)
+#define _GM(d) (((1 << _GZ(d)) - 1) << _GS(d))
+#define _BZ(d) (d - _RZ(d) - _GZ(d))
+#define _BS(d) (_RZ(d) + _GZ(d))
+#define _BM(d) (((1 << _BZ(d)) - 1) << _BS(d))
+#define _CE(d) (1 << _RZ(d))
+
+typedef struct _miVisuals {
+ struct _miVisuals *next;
+ int depth;
+ int bitsPerRGB;
+ int visuals;
+ int count;
+ int preferredCVC;
+} miVisualsRec, *miVisualsPtr;
+
+static int miVisualPriority[] = {
+ PseudoColor, GrayScale, StaticColor, TrueColor, DirectColor, StaticGray
+};
+
+#define NUM_PRIORITY 6
+
+static miVisualsPtr miVisuals;
+
+void
+miClearVisualTypes()
+{
+ miVisualsPtr v;
+
+ while ((v = miVisuals)) {
+ miVisuals = v->next;
+ xfree(v);
+ }
+}
+
+
+Bool
+miSetVisualTypes(int depth, int visuals, int bitsPerRGB, int preferredCVC)
+{
+ miVisualsPtr new, *prev, v;
+ int count;
+
+ new = (miVisualsPtr) xalloc (sizeof *new);
+ if (!new)
+ return FALSE;
+ new->next = 0;
+ new->depth = depth;
+ new->visuals = visuals;
+ new->bitsPerRGB = bitsPerRGB;
+ new->preferredCVC = preferredCVC;
+ count = (visuals >> 1) & 033333333333;
+ count = visuals - count - ((count >> 1) & 033333333333);
+ count = (((count + (count >> 3)) & 030707070707) % 077); /* HAKMEM 169 */
+ new->count = count;
+ for (prev = &miVisuals; (v = *prev); prev = &v->next);
+ *prev = new;
+ return TRUE;
+}
+
+int
+miGetDefaultVisualMask(int depth)
+{
+ if (depth > MAX_PSEUDO_DEPTH)
+ return LARGE_VISUALS;
+ else if (depth >= MIN_TRUE_DEPTH)
+ return ALL_VISUALS;
+ else if (depth == 1)
+ return StaticGrayMask;
+ else
+ return SMALL_VISUALS;
+}
+
+
+Bool
+miInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp,
+ int *ndepthp, int *rootDepthp, VisualID *defaultVisp,
+ unsigned long sizes, int bitsPerRGB, int preferredVis)
+
+{
+ if (miInitVisualsProc)
+ return miInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
+ rootDepthp, defaultVisp, sizes, bitsPerRGB,
+ preferredVis);
+ else
+ return FALSE;
+}
+
+
+/*
+ * Given a list of formats for a screen, create a list
+ * of visuals and depths for the screen which corespond to
+ * the set which can be used with this version of cfb.
+ */
+
+static Bool
+miDoInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp,
+ int *ndepthp, int *rootDepthp, VisualID *defaultVisp,
+ unsigned long sizes, int bitsPerRGB, int preferredVis)
+{
+ int i, j = 0, k;
+ VisualPtr visual;
+ DepthPtr depth;
+ VisualID *vid;
+ int d, b;
+ int f;
+ int ndepth, nvisual;
+ int nvtype;
+ int vtype;
+ miVisualsPtr visuals, nextVisuals;
+ int *preferredCVCs, *prefp;
+
+ /* none specified, we'll guess from pixmap formats */
+ if (!miVisuals)
+ {
+ for (f = 0; f < screenInfo.numPixmapFormats; f++)
+ {
+ d = screenInfo.formats[f].depth;
+ b = screenInfo.formats[f].bitsPerPixel;
+ if (sizes & (1 << (b - 1)))
+ vtype = miGetDefaultVisualMask(d);
+ else
+ vtype = 0;
+ if (!miSetVisualTypes (d, vtype, bitsPerRGB, -1))
+ return FALSE;
+ }
+ }
+ nvisual = 0;
+ ndepth = 0;
+ for (visuals = miVisuals; visuals; visuals = nextVisuals)
+ {
+ nextVisuals = visuals->next;
+ ndepth++;
+ nvisual += visuals->count;
+ }
+ depth = (DepthPtr) xalloc (ndepth * sizeof (DepthRec));
+ visual = (VisualPtr) xalloc (nvisual * sizeof (VisualRec));
+ preferredCVCs = (int *)xalloc(ndepth * sizeof(int));
+ if (!depth || !visual || !preferredCVCs)
+ {
+ xfree (depth);
+ xfree (visual);
+ xfree (preferredCVCs);
+ return FALSE;
+ }
+ *depthp = depth;
+ *visualp = visual;
+ *ndepthp = ndepth;
+ *nvisualp = nvisual;
+ prefp = preferredCVCs;
+ for (visuals = miVisuals; visuals; visuals = nextVisuals)
+ {
+ nextVisuals = visuals->next;
+ d = visuals->depth;
+ vtype = visuals->visuals;
+ nvtype = visuals->count;
+ *prefp = visuals->preferredCVC;
+ prefp++;
+ vid = NULL;
+ if (nvtype)
+ {
+ vid = (VisualID *) xalloc (nvtype * sizeof (VisualID));
+ if (!vid)
+ return FALSE;
+ }
+ depth->depth = d;
+ depth->numVids = nvtype;
+ depth->vids = vid;
+ depth++;
+ for (i = 0; i < NUM_PRIORITY; i++) {
+ if (! (vtype & (1 << miVisualPriority[i])))
+ continue;
+ visual->class = miVisualPriority[i];
+ visual->bitsPerRGBValue = visuals->bitsPerRGB;
+ visual->ColormapEntries = 1 << d;
+ visual->nplanes = d;
+ visual->vid = *vid = FakeClientID (0);
+ switch (visual->class) {
+ case PseudoColor:
+ case GrayScale:
+ case StaticGray:
+ visual->redMask = 0;
+ visual->greenMask = 0;
+ visual->blueMask = 0;
+ visual->offsetRed = 0;
+ visual->offsetGreen = 0;
+ visual->offsetBlue = 0;
+ break;
+ case DirectColor:
+ case TrueColor:
+ visual->ColormapEntries = _CE(d);
+ /* fall through */
+ case StaticColor:
+ visual->redMask = _RM(d);
+ visual->greenMask = _GM(d);
+ visual->blueMask = _BM(d);
+ visual->offsetRed = _RS(d);
+ visual->offsetGreen = _GS(d);
+ visual->offsetBlue = _BS(d);
+ }
+ vid++;
+ visual++;
+ }
+ xfree (visuals);
+ }
+ miVisuals = NULL;
+ visual = *visualp;
+ depth = *depthp;
+ for (i = 0; i < ndepth; i++)
+ {
+ int prefColorVisualClass = -1;
+
+ if (defaultColorVisualClass >= 0)
+ prefColorVisualClass = defaultColorVisualClass;
+ else if (preferredVis >= 0)
+ prefColorVisualClass = preferredVis;
+ else if (preferredCVCs[i] >= 0)
+ prefColorVisualClass = preferredCVCs[i];
+
+ if (*rootDepthp && *rootDepthp != depth[i].depth)
+ continue;
+
+ for (j = 0; j < depth[i].numVids; j++)
+ {
+ for (k = 0; k < nvisual; k++)
+ if (visual[k].vid == depth[i].vids[j])
+ break;
+ if (k == nvisual)
+ continue;
+ if (prefColorVisualClass < 0 ||
+ visual[k].class == prefColorVisualClass)
+ break;
+ }
+ if (j != depth[i].numVids)
+ break;
+ }
+ if (i == ndepth) {
+ i = 0;
+ j = 0;
+ }
+ *rootDepthp = depth[i].depth;
+ *defaultVisp = depth[i].vids[j];
+ xfree(preferredCVCs);
+
+ return TRUE;
+}
+
+void
+miResetInitVisuals()
+{
+ miInitVisualsProc = miDoInitVisuals;
+}
+
diff --git a/xc/programs/Xserver/mi/micmap.h b/xc/programs/Xserver/mi/micmap.h
new file mode 100644
index 000000000..828b776b5
--- /dev/null
+++ b/xc/programs/Xserver/mi/micmap.h
@@ -0,0 +1,61 @@
+/* $XFree86: xc/programs/Xserver/mi/micmap.h,v 1.5 1999/06/14 07:32:11 dawes Exp $ */
+
+#include "colormapst.h"
+
+#ifndef _MICMAP_H_
+#define _MICMAP_H_
+
+extern ColormapPtr miInstalledMaps[MAXSCREENS];
+
+typedef Bool (* miInitVisualsProcPtr)(VisualPtr *, DepthPtr *, int *, int *,
+ int *, VisualID *, unsigned long, int,
+ int);
+
+extern miInitVisualsProcPtr miInitVisualsProc;
+
+int miListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps);
+void miInstallColormap(ColormapPtr pmap);
+void miUninstallColormap(ColormapPtr pmap);
+
+void miResolveColor(unsigned short *, unsigned short *, unsigned short *,
+ VisualPtr);
+Bool miInitializeColormap(ColormapPtr);
+int miExpandDirectColors(ColormapPtr, int, xColorItem *, xColorItem *);
+Bool miCreateDefColormap(ScreenPtr);
+void miClearVisualTypes(void);
+Bool miSetVisualTypes(int, int, int, int);
+int miGetDefaultVisualMask(int);
+Bool miInitVisuals(VisualPtr *, DepthPtr *, int *, int *, int *, VisualID *,
+ unsigned long, int, int);
+void miResetInitVisuals(void);
+
+void miHookInitVisuals(void (**old)(miInitVisualsProcPtr *),
+ void (*new)(miInitVisualsProcPtr *));
+
+
+#define MAX_PSEUDO_DEPTH 10
+#define MIN_TRUE_DEPTH 6
+
+#define StaticGrayMask (1 << StaticGray)
+#define GrayScaleMask (1 << GrayScale)
+#define StaticColorMask (1 << StaticColor)
+#define PseudoColorMask (1 << PseudoColor)
+#define TrueColorMask (1 << TrueColor)
+#define DirectColorMask (1 << DirectColor)
+
+#define ALL_VISUALS (StaticGrayMask|\
+ GrayScaleMask|\
+ StaticColorMask|\
+ PseudoColorMask|\
+ TrueColorMask|\
+ DirectColorMask)
+
+#define LARGE_VISUALS (TrueColorMask|\
+ DirectColorMask)
+
+#define SMALL_VISUALS (StaticGrayMask|\
+ GrayScaleMask|\
+ StaticColorMask|\
+ PseudoColorMask)
+
+#endif /* _MICMAP_H_ */
diff --git a/xc/programs/Xserver/mi/micursor.c b/xc/programs/Xserver/mi/micursor.c
new file mode 100644
index 000000000..cbe68f9ad
--- /dev/null
+++ b/xc/programs/Xserver/mi/micursor.c
@@ -0,0 +1,67 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: micursor.c /main/5 1998/02/09 14:46:31 kaleb $ */
+#include "scrnintstr.h"
+#include "cursor.h"
+#include "misc.h"
+
+extern Bool Must_have_memory;
+
+void
+miRecolorCursor( pScr, pCurs, displayed)
+ ScreenPtr pScr;
+ CursorPtr pCurs;
+ Bool displayed;
+{
+ /*
+ * This is guaranteed to correct any color-dependent state which may have
+ * been bound up in private state created by RealizeCursor
+ */
+ (* pScr->UnrealizeCursor)( pScr, pCurs);
+ Must_have_memory = TRUE; /* XXX */
+ (* pScr->RealizeCursor)( pScr, pCurs);
+ Must_have_memory = FALSE; /* XXX */
+ if ( displayed)
+ (* pScr->DisplayCursor)( pScr, pCurs);
+
+}
diff --git a/xc/programs/Xserver/mi/midash.c b/xc/programs/Xserver/mi/midash.c
new file mode 100644
index 000000000..68c783e52
--- /dev/null
+++ b/xc/programs/Xserver/mi/midash.c
@@ -0,0 +1,306 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: midash.c /main/14 1998/02/09 14:46:34 kaleb $ */
+#include "miscstruct.h"
+#include "mistruct.h"
+#include "mifpoly.h"
+
+static miDashPtr CheckDashStorage();
+
+/* return a list of DashRec. there will be an extra
+entry at the end holding the last point of the polyline.
+ this means that the code that actually draws dashes can
+get a pair of points for every dash. only the point in the last
+dash record is useful; the other fields are not used.
+ nseg is the number of segments, not the number of points.
+
+example:
+
+ dash1.start
+ dash2.start
+ dash3.start
+ last-point
+
+defines a list of segments
+ (dash1.pt, dash2.pt)
+ (dash2.pt, dash3.pt)
+ (dash3.pt, last-point)
+and nseg == 3.
+
+NOTE:
+ EVEN_DASH == ~ODD_DASH
+
+NOTE ALSO:
+ miDashLines may return 0 segments, going from pt[0] to pt[0] with one dash.
+*/
+
+miDashPtr
+miDashLine(npt, ppt, nDash, pDash, offset, pnseg)
+int npt;
+DDXPointPtr ppt;
+unsigned int nDash;
+unsigned char *pDash;
+unsigned int offset;
+int *pnseg;
+{
+ DDXPointRec pt1, pt2;
+ int lenCur; /* npt used from this dash */
+ int lenMax; /* npt in this dash */
+ int iDash = 0; /* index of current dash */
+ int which; /* EVEN_DASH or ODD_DASH */
+ miDashPtr pseg; /* list of dash segments */
+ miDashPtr psegBase; /* start of list */
+ int nseg = 0; /* number of dashes so far */
+ int nsegMax = 0; /* num segs we can fit in this list */
+
+ int x, y, len;
+ int adx, ady, signdx, signdy;
+ int du, dv, e1, e2, e, base_e = 0;
+
+ lenCur = offset;
+ which = EVEN_DASH;
+ while(lenCur >= pDash[iDash])
+ {
+ lenCur -= pDash[iDash];
+ iDash++;
+ if (iDash >= nDash)
+ iDash = 0;
+ which = ~which;
+ }
+ lenMax = pDash[iDash];
+
+ psegBase = (miDashPtr)NULL;
+ pt2 = ppt[0]; /* just in case there is only one point */
+
+ while(--npt)
+ {
+ if (PtEqual(ppt[0], ppt[1]))
+ {
+ ppt++;
+ continue; /* no duplicated points in polyline */
+ }
+ pt1 = *ppt++;
+ pt2 = *ppt;
+
+ adx = pt2.x - pt1.x;
+ ady = pt2.y - pt1.y;
+ signdx = sign(adx);
+ signdy = sign(ady);
+ adx = abs(adx);
+ ady = abs(ady);
+
+ if (adx > ady)
+ {
+ du = adx;
+ dv = ady;
+ len = adx;
+ }
+ else
+ {
+ du = ady;
+ dv = adx;
+ len = ady;
+ }
+
+ e1 = dv * 2;
+ e2 = e1 - 2*du;
+ e = e1 - du;
+ x = pt1.x;
+ y = pt1.y;
+
+ nseg++;
+ pseg = CheckDashStorage(&psegBase, nseg, &nsegMax);
+ if (!pseg)
+ return (miDashPtr)NULL;
+ pseg->pt = pt1;
+ pseg->e1 = e1;
+ pseg->e2 = e2;
+ base_e = pseg->e = e;
+ pseg->which = which;
+ pseg->newLine = 1;
+
+ while (len--)
+ {
+ if (adx > ady)
+ {
+ /* X_AXIS */
+ if (((signdx > 0) && (e < 0)) ||
+ ((signdx <=0) && (e <=0))
+ )
+ {
+ e += e1;
+ }
+ else
+ {
+ y += signdy;
+ e += e2;
+ }
+ x += signdx;
+ }
+ else
+ {
+ /* Y_AXIS */
+ if (((signdx > 0) && (e < 0)) ||
+ ((signdx <=0) && (e <=0))
+ )
+ {
+ e +=e1;
+ }
+ else
+ {
+ x += signdx;
+ e += e2;
+ }
+ y += signdy;
+ }
+
+ lenCur++;
+ if (lenCur >= lenMax && (len || npt <= 1))
+ {
+ nseg++;
+ pseg = CheckDashStorage(&psegBase, nseg, &nsegMax);
+ if (!pseg)
+ return (miDashPtr)NULL;
+ pseg->pt.x = x;
+ pseg->pt.y = y;
+ pseg->e1 = e1;
+ pseg->e2 = e2;
+ pseg->e = e;
+ which = ~which;
+ pseg->which = which;
+ pseg->newLine = 0;
+
+ /* move on to next dash */
+ iDash++;
+ if (iDash >= nDash)
+ iDash = 0;
+ lenMax = pDash[iDash];
+ lenCur = 0;
+ }
+ } /* while len-- */
+ } /* while --npt */
+
+ if (lenCur == 0 && nseg != 0)
+ {
+ nseg--;
+ which = ~which;
+ }
+ *pnseg = nseg;
+ pseg = CheckDashStorage(&psegBase, nseg+1, &nsegMax);
+ if (!pseg)
+ return (miDashPtr)NULL;
+ pseg->pt = pt2;
+ pseg->e = base_e;
+ pseg->which = which;
+ pseg->newLine = 0;
+ return psegBase;
+}
+
+
+#define NSEGDELTA 16
+
+/* returns a pointer to the pseg[nseg-1], growing the storage as
+necessary. this interface seems unnecessarily cumbersome.
+
+*/
+
+static
+miDashPtr
+CheckDashStorage(ppseg, nseg, pnsegMax)
+miDashPtr *ppseg; /* base pointer */
+int nseg; /* number of segment we want to write to */
+int *pnsegMax; /* size (in segments) of list so far */
+{
+ if (nseg > *pnsegMax)
+ {
+ miDashPtr newppseg;
+
+ *pnsegMax += NSEGDELTA;
+ newppseg = (miDashPtr)xrealloc(*ppseg,
+ (*pnsegMax)*sizeof(miDashRec));
+ if (!newppseg)
+ {
+ xfree(*ppseg);
+ return (miDashPtr)NULL;
+ }
+ *ppseg = newppseg;
+ }
+ return(*ppseg+(nseg-1));
+}
+
+void
+miStepDash (dist, pDashIndex, pDash, numInDashList, pDashOffset)
+ int dist; /* distance to step */
+ int *pDashIndex; /* current dash */
+ unsigned char *pDash; /* dash list */
+ int numInDashList; /* total length of dash list */
+ int *pDashOffset; /* offset into current dash */
+{
+ int dashIndex, dashOffset;
+ int totallen;
+ int i;
+
+ dashIndex = *pDashIndex;
+ dashOffset = *pDashOffset;
+ if (dist < pDash[dashIndex] - dashOffset)
+ {
+ *pDashOffset = dashOffset + dist;
+ return;
+ }
+ dist -= pDash[dashIndex] - dashOffset;
+ if (++dashIndex == numInDashList)
+ dashIndex = 0;
+ totallen = 0;
+ for (i = 0; i < numInDashList; i++)
+ totallen += pDash[i];
+ if (totallen <= dist)
+ dist = dist % totallen;
+ while (dist >= pDash[dashIndex])
+ {
+ dist -= pDash[dashIndex];
+ if (++dashIndex == numInDashList)
+ dashIndex = 0;
+ }
+ *pDashIndex = dashIndex;
+ *pDashOffset = dist;
+}
diff --git a/xc/programs/Xserver/mi/midispcur.c b/xc/programs/Xserver/mi/midispcur.c
new file mode 100644
index 000000000..0b52880cb
--- /dev/null
+++ b/xc/programs/Xserver/mi/midispcur.c
@@ -0,0 +1,610 @@
+/*
+ * midispcur.c
+ *
+ * machine independent cursor display routines
+ */
+
+/* $TOG: midispcur.c /main/16 1998/02/09 14:46:39 kaleb $ */
+
+/*
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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_EVENTS
+# include "X.h"
+# include "misc.h"
+# include "input.h"
+# include "cursorstr.h"
+# include "windowstr.h"
+# include "regionstr.h"
+# include "dixstruct.h"
+# include "scrnintstr.h"
+# include "servermd.h"
+# include "mipointer.h"
+# include "misprite.h"
+# include "gcstruct.h"
+
+extern WindowPtr *WindowTable;
+
+/* per-screen private data */
+
+static int miDCScreenIndex;
+static unsigned long miDCGeneration = 0;
+
+static Bool miDCCloseScreen();
+
+typedef struct {
+ GCPtr pSourceGC, pMaskGC;
+ GCPtr pSaveGC, pRestoreGC;
+ GCPtr pMoveGC;
+ GCPtr pPixSourceGC, pPixMaskGC;
+ CloseScreenProcPtr CloseScreen;
+ PixmapPtr pSave, pTemp;
+} miDCScreenRec, *miDCScreenPtr;
+
+/* per-cursor per-screen private data */
+typedef struct {
+ PixmapPtr sourceBits; /* source bits */
+ PixmapPtr maskBits; /* mask bits */
+} miDCCursorRec, *miDCCursorPtr;
+
+/*
+ * sprite/cursor method table
+ */
+
+static Bool miDCRealizeCursor(), miDCUnrealizeCursor();
+static Bool miDCPutUpCursor(), miDCSaveUnderCursor();
+static Bool miDCRestoreUnderCursor(), miDCMoveCursor();
+static Bool miDCChangeSave();
+
+static miSpriteCursorFuncRec miDCFuncs = {
+ miDCRealizeCursor,
+ miDCUnrealizeCursor,
+ miDCPutUpCursor,
+ miDCSaveUnderCursor,
+ miDCRestoreUnderCursor,
+ miDCMoveCursor,
+ miDCChangeSave,
+};
+
+Bool
+miDCInitialize (pScreen, screenFuncs)
+ ScreenPtr pScreen;
+ miPointerScreenFuncPtr screenFuncs;
+{
+ miDCScreenPtr pScreenPriv;
+
+ if (miDCGeneration != serverGeneration)
+ {
+ miDCScreenIndex = AllocateScreenPrivateIndex ();
+ if (miDCScreenIndex < 0)
+ return FALSE;
+ miDCGeneration = serverGeneration;
+ }
+ pScreenPriv = (miDCScreenPtr) xalloc (sizeof (miDCScreenRec));
+ if (!pScreenPriv)
+ return FALSE;
+
+ /*
+ * initialize the entire private structure to zeros
+ */
+
+ pScreenPriv->pSourceGC =
+ pScreenPriv->pMaskGC =
+ pScreenPriv->pSaveGC =
+ pScreenPriv->pRestoreGC =
+ pScreenPriv->pMoveGC =
+ pScreenPriv->pPixSourceGC =
+ pScreenPriv->pPixMaskGC = NULL;
+
+ pScreenPriv->pSave = pScreenPriv->pTemp = NULL;
+
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = miDCCloseScreen;
+
+ pScreen->devPrivates[miDCScreenIndex].ptr = (pointer) pScreenPriv;
+
+ if (!miSpriteInitialize (pScreen, &miDCFuncs, screenFuncs))
+ {
+ xfree ((pointer) pScreenPriv);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+#define tossGC(gc) (gc ? FreeGC (gc, (GContext) 0) : 0)
+#define tossPix(pix) (pix ? (*pScreen->DestroyPixmap) (pix) : TRUE)
+
+static Bool
+miDCCloseScreen (index, pScreen)
+ ScreenPtr pScreen;
+{
+ miDCScreenPtr pScreenPriv;
+
+ pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ tossGC (pScreenPriv->pSourceGC);
+ tossGC (pScreenPriv->pMaskGC);
+ tossGC (pScreenPriv->pSaveGC);
+ tossGC (pScreenPriv->pRestoreGC);
+ tossGC (pScreenPriv->pMoveGC);
+ tossGC (pScreenPriv->pPixSourceGC);
+ tossGC (pScreenPriv->pPixMaskGC);
+ tossPix (pScreenPriv->pSave);
+ tossPix (pScreenPriv->pTemp);
+ xfree ((pointer) pScreenPriv);
+ return (*pScreen->CloseScreen) (index, pScreen);
+}
+
+static Bool
+miDCRealizeCursor (pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ if (pCursor->bits->refcnt <= 1)
+ pCursor->bits->devPriv[pScreen->myNum] = (pointer)NULL;
+ return TRUE;
+}
+
+static miDCCursorPtr
+miDCRealize (pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ miDCCursorPtr pPriv;
+ GCPtr pGC;
+ XID gcvals[3];
+
+ pPriv = (miDCCursorPtr) xalloc (sizeof (miDCCursorRec));
+ if (!pPriv)
+ return (miDCCursorPtr)NULL;
+ pPriv->sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1);
+ if (!pPriv->sourceBits)
+ {
+ xfree ((pointer) pPriv);
+ return (miDCCursorPtr)NULL;
+ }
+ pPriv->maskBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1);
+ if (!pPriv->maskBits)
+ {
+ (*pScreen->DestroyPixmap) (pPriv->sourceBits);
+ xfree ((pointer) pPriv);
+ return (miDCCursorPtr)NULL;
+ }
+ pCursor->bits->devPriv[pScreen->myNum] = (pointer) pPriv;
+
+ /* create the two sets of bits, clipping as appropriate */
+
+ pGC = GetScratchGC (1, pScreen);
+ if (!pGC)
+ {
+ (void) miDCUnrealizeCursor (pScreen, pCursor);
+ return (miDCCursorPtr)NULL;
+ }
+
+ ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC);
+ (*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1,
+ 0, 0, pCursor->bits->width, pCursor->bits->height,
+ 0, XYPixmap, (char *)pCursor->bits->source);
+ gcvals[0] = GXand;
+ ChangeGC (pGC, GCFunction, gcvals);
+ ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC);
+ (*pGC->ops->PutImage) ((DrawablePtr)pPriv->sourceBits, pGC, 1,
+ 0, 0, pCursor->bits->width, pCursor->bits->height,
+ 0, XYPixmap, (char *)pCursor->bits->mask);
+
+ /* mask bits -- pCursor->mask & ~pCursor->source */
+ gcvals[0] = GXcopy;
+ ChangeGC (pGC, GCFunction, gcvals);
+ ValidateGC ((DrawablePtr)pPriv->maskBits, pGC);
+ (*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1,
+ 0, 0, pCursor->bits->width, pCursor->bits->height,
+ 0, XYPixmap, (char *)pCursor->bits->mask);
+ gcvals[0] = GXandInverted;
+ ChangeGC (pGC, GCFunction, gcvals);
+ ValidateGC ((DrawablePtr)pPriv->maskBits, pGC);
+ (*pGC->ops->PutImage) ((DrawablePtr)pPriv->maskBits, pGC, 1,
+ 0, 0, pCursor->bits->width, pCursor->bits->height,
+ 0, XYPixmap, (char *)pCursor->bits->source);
+ FreeScratchGC (pGC);
+ return pPriv;
+}
+
+static Bool
+miDCUnrealizeCursor (pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ miDCCursorPtr pPriv;
+
+ pPriv = (miDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
+ if (pPriv && (pCursor->bits->refcnt <= 1))
+ {
+ (*pScreen->DestroyPixmap) (pPriv->sourceBits);
+ (*pScreen->DestroyPixmap) (pPriv->maskBits);
+ xfree ((pointer) pPriv);
+ pCursor->bits->devPriv[pScreen->myNum] = (pointer)NULL;
+ }
+ return TRUE;
+}
+
+static void
+miDCPutBits (pDrawable, pPriv, sourceGC, maskGC, x, y, w, h, source, mask)
+ DrawablePtr pDrawable;
+ GCPtr sourceGC, maskGC;
+ int x, y;
+ unsigned w, h;
+ miDCCursorPtr pPriv;
+ unsigned long source, mask;
+{
+ XID gcvals[1];
+
+ if (sourceGC->fgPixel != source)
+ {
+ gcvals[0] = source;
+ DoChangeGC (sourceGC, GCForeground, gcvals, 0);
+ }
+ if (sourceGC->serialNumber != pDrawable->serialNumber)
+ ValidateGC (pDrawable, sourceGC);
+ (*sourceGC->ops->PushPixels) (sourceGC, pPriv->sourceBits, pDrawable, w, h, x, y);
+ if (maskGC->fgPixel != mask)
+ {
+ gcvals[0] = mask;
+ DoChangeGC (maskGC, GCForeground, gcvals, 0);
+ }
+ if (maskGC->serialNumber != pDrawable->serialNumber)
+ ValidateGC (pDrawable, maskGC);
+ (*maskGC->ops->PushPixels) (maskGC, pPriv->maskBits, pDrawable, w, h, x, y);
+}
+
+#define EnsureGC(gc,win) (gc || miDCMakeGC(&gc, win))
+
+static GCPtr
+miDCMakeGC(ppGC, pWin)
+ GCPtr *ppGC;
+ WindowPtr pWin;
+{
+ GCPtr pGC;
+ int status;
+ XID gcvals[2];
+
+ gcvals[0] = IncludeInferiors;
+ gcvals[1] = FALSE;
+ pGC = CreateGC((DrawablePtr)pWin,
+ GCSubwindowMode|GCGraphicsExposures, gcvals, &status);
+ if (pGC)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
+ *ppGC = pGC;
+ return pGC;
+}
+
+static Bool
+miDCPutUpCursor (pScreen, pCursor, x, y, source, mask)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+ int x, y;
+ unsigned long source, mask;
+{
+ miDCScreenPtr pScreenPriv;
+ miDCCursorPtr pPriv;
+ WindowPtr pWin;
+
+ pPriv = (miDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
+ if (!pPriv)
+ {
+ pPriv = miDCRealize(pScreen, pCursor);
+ if (!pPriv)
+ return FALSE;
+ }
+ pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
+ pWin = WindowTable[pScreen->myNum];
+ if (!EnsureGC(pScreenPriv->pSourceGC, pWin))
+ return FALSE;
+ if (!EnsureGC(pScreenPriv->pMaskGC, pWin))
+ {
+ FreeGC (pScreenPriv->pSourceGC, (GContext) 0);
+ pScreenPriv->pSourceGC = 0;
+ return FALSE;
+ }
+ miDCPutBits ((DrawablePtr)pWin, pPriv,
+ pScreenPriv->pSourceGC, pScreenPriv->pMaskGC,
+ x, y, pCursor->bits->width, pCursor->bits->height,
+ source, mask);
+ return TRUE;
+}
+
+static Bool
+miDCSaveUnderCursor (pScreen, x, y, w, h)
+ ScreenPtr pScreen;
+ int x, y, w, h;
+{
+ miDCScreenPtr pScreenPriv;
+ PixmapPtr pSave;
+ WindowPtr pWin;
+ GCPtr pGC;
+
+ pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
+ pSave = pScreenPriv->pSave;
+ pWin = WindowTable[pScreen->myNum];
+ if (!pSave || pSave->drawable.width < w || pSave->drawable.height < h)
+ {
+ if (pSave)
+ (*pScreen->DestroyPixmap) (pSave);
+ pScreenPriv->pSave = pSave =
+ (*pScreen->CreatePixmap) (pScreen, w, h, pScreen->rootDepth);
+ if (!pSave)
+ return FALSE;
+ }
+ if (!EnsureGC(pScreenPriv->pSaveGC, pWin))
+ return FALSE;
+ pGC = pScreenPriv->pSaveGC;
+ if (pSave->drawable.serialNumber != pGC->serialNumber)
+ ValidateGC ((DrawablePtr) pSave, pGC);
+ (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
+ x, y, w, h, 0, 0);
+ return TRUE;
+}
+
+static Bool
+miDCRestoreUnderCursor (pScreen, x, y, w, h)
+ ScreenPtr pScreen;
+ int x, y, w, h;
+{
+ miDCScreenPtr pScreenPriv;
+ PixmapPtr pSave;
+ WindowPtr pWin;
+ GCPtr pGC;
+
+ pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
+ pSave = pScreenPriv->pSave;
+ pWin = WindowTable[pScreen->myNum];
+ if (!pSave)
+ return FALSE;
+ if (!EnsureGC(pScreenPriv->pRestoreGC, pWin))
+ return FALSE;
+ pGC = pScreenPriv->pRestoreGC;
+ if (pWin->drawable.serialNumber != pGC->serialNumber)
+ ValidateGC ((DrawablePtr) pWin, pGC);
+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
+ 0, 0, w, h, x, y);
+ return TRUE;
+}
+
+static Bool
+miDCChangeSave (pScreen, x, y, w, h, dx, dy)
+ ScreenPtr pScreen;
+ int x, y, w, h, dx, dy;
+{
+ miDCScreenPtr pScreenPriv;
+ PixmapPtr pSave;
+ WindowPtr pWin;
+ GCPtr pGC;
+ int sourcex, sourcey, destx, desty, copyw, copyh;
+
+ pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
+ pSave = pScreenPriv->pSave;
+ pWin = WindowTable[pScreen->myNum];
+ /*
+ * restore the bits which are about to get trashed
+ */
+ if (!pSave)
+ return FALSE;
+ if (!EnsureGC(pScreenPriv->pRestoreGC, pWin))
+ return FALSE;
+ pGC = pScreenPriv->pRestoreGC;
+ if (pWin->drawable.serialNumber != pGC->serialNumber)
+ ValidateGC ((DrawablePtr) pWin, pGC);
+ /*
+ * copy the old bits to the screen.
+ */
+ if (dy > 0)
+ {
+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
+ 0, h - dy, w, dy, x + dx, y + h);
+ }
+ else if (dy < 0)
+ {
+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
+ 0, 0, w, -dy, x + dx, y + dy);
+ }
+ if (dy >= 0)
+ {
+ desty = y + dy;
+ sourcey = 0;
+ copyh = h - dy;
+ }
+ else
+ {
+ desty = y;
+ sourcey = - dy;
+ copyh = h + dy;
+ }
+ if (dx > 0)
+ {
+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
+ w - dx, sourcey, dx, copyh, x + w, desty);
+ }
+ else if (dx < 0)
+ {
+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
+ 0, sourcey, -dx, copyh, x + dx, desty);
+ }
+ if (!EnsureGC(pScreenPriv->pSaveGC, pWin))
+ return FALSE;
+ pGC = pScreenPriv->pSaveGC;
+ if (pSave->drawable.serialNumber != pGC->serialNumber)
+ ValidateGC ((DrawablePtr) pSave, pGC);
+ /*
+ * move the bits that are still valid within the pixmap
+ */
+ if (dx >= 0)
+ {
+ sourcex = 0;
+ destx = dx;
+ copyw = w - dx;
+ }
+ else
+ {
+ destx = 0;
+ sourcex = - dx;
+ copyw = w + dx;
+ }
+ if (dy >= 0)
+ {
+ sourcey = 0;
+ desty = dy;
+ copyh = h - dy;
+ }
+ else
+ {
+ desty = 0;
+ sourcey = -dy;
+ copyh = h + dy;
+ }
+ (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pSave, pGC,
+ sourcex, sourcey, copyw, copyh, destx, desty);
+ /*
+ * copy the new bits from the screen into the remaining areas of the
+ * pixmap
+ */
+ if (dy > 0)
+ {
+ (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
+ x, y, w, dy, 0, 0);
+ }
+ else if (dy < 0)
+ {
+ (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
+ x, y + h + dy, w, -dy, 0, h + dy);
+ }
+ if (dy >= 0)
+ {
+ desty = dy;
+ sourcey = y + dy;
+ copyh = h - dy;
+ }
+ else
+ {
+ desty = 0;
+ sourcey = y;
+ copyh = h + dy;
+ }
+ if (dx > 0)
+ {
+ (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
+ x, sourcey, dx, copyh, 0, desty);
+ }
+ else if (dx < 0)
+ {
+ (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
+ x + w + dx, sourcey, -dx, copyh, w + dx, desty);
+ }
+ return TRUE;
+}
+
+static Bool
+miDCMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+ int x, y, w, h, dx, dy;
+ unsigned long source, mask;
+{
+ miDCCursorPtr pPriv;
+ miDCScreenPtr pScreenPriv;
+ int status;
+ WindowPtr pWin;
+ GCPtr pGC;
+ XID gcval = FALSE;
+ PixmapPtr pTemp;
+
+ pPriv = (miDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
+ if (!pPriv)
+ {
+ pPriv = miDCRealize(pScreen, pCursor);
+ if (!pPriv)
+ return FALSE;
+ }
+ pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
+ pWin = WindowTable[pScreen->myNum];
+ pTemp = pScreenPriv->pTemp;
+ if (!pTemp ||
+ pTemp->drawable.width != pScreenPriv->pSave->drawable.width ||
+ pTemp->drawable.height != pScreenPriv->pSave->drawable.height)
+ {
+ if (pTemp)
+ (*pScreen->DestroyPixmap) (pTemp);
+ pScreenPriv->pTemp = pTemp = (*pScreen->CreatePixmap)
+ (pScreen, w, h, pScreenPriv->pSave->drawable.depth);
+ if (!pTemp)
+ return FALSE;
+ }
+ if (!pScreenPriv->pMoveGC)
+ {
+ pScreenPriv->pMoveGC = CreateGC ((DrawablePtr)pTemp,
+ GCGraphicsExposures, &gcval, &status);
+ if (!pScreenPriv->pMoveGC)
+ return FALSE;
+ }
+ /*
+ * copy the saved area to a temporary pixmap
+ */
+ pGC = pScreenPriv->pMoveGC;
+ if (pGC->serialNumber != pTemp->drawable.serialNumber)
+ ValidateGC ((DrawablePtr) pTemp, pGC);
+ (*pGC->ops->CopyArea)((DrawablePtr)pScreenPriv->pSave,
+ (DrawablePtr)pTemp, pGC, 0, 0, w, h, 0, 0);
+
+ /*
+ * draw the cursor in the temporary pixmap
+ */
+ if (!pScreenPriv->pPixSourceGC)
+ {
+ pScreenPriv->pPixSourceGC = CreateGC ((DrawablePtr)pTemp,
+ GCGraphicsExposures, &gcval, &status);
+ if (!pScreenPriv->pPixSourceGC)
+ return FALSE;
+ }
+ if (!pScreenPriv->pPixMaskGC)
+ {
+ pScreenPriv->pPixMaskGC = CreateGC ((DrawablePtr)pTemp,
+ GCGraphicsExposures, &gcval, &status);
+ if (!pScreenPriv->pPixMaskGC)
+ return FALSE;
+ }
+ miDCPutBits ((DrawablePtr)pTemp, pPriv,
+ pScreenPriv->pPixSourceGC, pScreenPriv->pPixMaskGC,
+ dx, dy, pCursor->bits->width, pCursor->bits->height,
+ source, mask);
+
+ /*
+ * copy the temporary pixmap onto the screen
+ */
+
+ if (!EnsureGC(pScreenPriv->pRestoreGC, pWin))
+ return FALSE;
+ pGC = pScreenPriv->pRestoreGC;
+ if (pWin->drawable.serialNumber != pGC->serialNumber)
+ ValidateGC ((DrawablePtr) pWin, pGC);
+
+ (*pGC->ops->CopyArea) ((DrawablePtr) pTemp, (DrawablePtr) pWin,
+ pGC,
+ 0, 0, w, h, x, y);
+ return TRUE;
+}
diff --git a/xc/programs/Xserver/mi/mieq.c b/xc/programs/Xserver/mi/mieq.c
new file mode 100644
index 000000000..8427c33be
--- /dev/null
+++ b/xc/programs/Xserver/mi/mieq.c
@@ -0,0 +1,187 @@
+/*
+ * $TOG: mieq.c /main/9 1998/02/09 14:46:43 kaleb $
+ *
+Copyright 1990, 1998 The Open Group
+
+All Rights Reserved.
+
+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
+ */
+
+/*
+ * mieq.c
+ *
+ * Machine independent event queue
+ *
+ */
+
+# define NEED_EVENTS
+# include "X.h"
+# include "Xmd.h"
+# include "Xproto.h"
+# include "misc.h"
+# include "windowstr.h"
+# include "pixmapstr.h"
+# include "inputstr.h"
+# include "mi.h"
+# include "scrnintstr.h"
+
+#define QUEUE_SIZE 256
+
+typedef struct _Event {
+ xEvent event;
+ ScreenPtr pScreen;
+} EventRec, *EventPtr;
+
+typedef struct _EventQueue {
+ HWEventQueueType head, tail; /* long for SetInputCheck */
+ CARD32 lastEventTime; /* to avoid time running backwards */
+ Bool lastMotion;
+ EventRec events[QUEUE_SIZE]; /* static allocation for signals */
+ DevicePtr pKbd, pPtr; /* device pointer, to get funcs */
+ ScreenPtr pEnqueueScreen; /* screen events are being delivered to */
+ ScreenPtr pDequeueScreen; /* screen events are being dispatched to */
+} EventQueueRec, *EventQueuePtr;
+
+static EventQueueRec miEventQueue;
+
+Bool
+mieqInit (pKbd, pPtr)
+ DevicePtr pKbd, pPtr;
+{
+ miEventQueue.head = miEventQueue.tail = 0;
+ miEventQueue.lastEventTime = GetTimeInMillis ();
+ miEventQueue.pKbd = pKbd;
+ miEventQueue.pPtr = pPtr;
+ miEventQueue.lastMotion = FALSE;
+ miEventQueue.pEnqueueScreen = screenInfo.screens[0];
+ miEventQueue.pDequeueScreen = miEventQueue.pEnqueueScreen;
+ SetInputCheck (&miEventQueue.head, &miEventQueue.tail);
+ return TRUE;
+}
+
+/*
+ * Must be reentrant with ProcessInputEvents. Assumption: mieqEnqueue
+ * will never be interrupted. If this is called from both signal
+ * handlers and regular code, make sure the signal is suspended when
+ * called from regular code.
+ */
+
+void
+mieqEnqueue (e)
+ xEvent *e;
+{
+ HWEventQueueType oldtail, newtail, prevtail;
+ Bool isMotion;
+
+ oldtail = miEventQueue.tail;
+ isMotion = e->u.u.type == MotionNotify;
+ if (isMotion && miEventQueue.lastMotion && oldtail != miEventQueue.head)
+ {
+ if (oldtail == 0)
+ oldtail = QUEUE_SIZE;
+ oldtail = oldtail - 1;
+ }
+ else
+ {
+ newtail = oldtail + 1;
+ if (newtail == QUEUE_SIZE)
+ newtail = 0;
+ /* Toss events which come in late */
+ if (newtail == miEventQueue.head)
+ return;
+ miEventQueue.tail = newtail;
+ }
+ miEventQueue.lastMotion = isMotion;
+ miEventQueue.events[oldtail].event = *e;
+ /*
+ * Make sure that event times don't go backwards - this
+ * is "unnecessary", but very useful
+ */
+ if (e->u.keyButtonPointer.time < miEventQueue.lastEventTime &&
+ miEventQueue.lastEventTime - e->u.keyButtonPointer.time < 10000)
+ {
+ miEventQueue.events[oldtail].event.u.keyButtonPointer.time =
+ miEventQueue.lastEventTime;
+ }
+ miEventQueue.events[oldtail].pScreen = miEventQueue.pEnqueueScreen;
+}
+
+void
+mieqSwitchScreen (pScreen, fromDIX)
+ ScreenPtr pScreen;
+ Bool fromDIX;
+{
+ miEventQueue.pEnqueueScreen = pScreen;
+ if (fromDIX)
+ miEventQueue.pDequeueScreen = pScreen;
+}
+
+/*
+ * Call this from ProcessInputEvents()
+ */
+
+mieqProcessInputEvents ()
+{
+ EventRec *e;
+ int x, y;
+ xEvent xe;
+
+ while (miEventQueue.head != miEventQueue.tail)
+ {
+ extern int screenIsSaved;
+
+ if (screenIsSaved == SCREEN_SAVER_ON)
+ SaveScreens (SCREEN_SAVER_OFF, ScreenSaverReset);
+
+ e = &miEventQueue.events[miEventQueue.head];
+ /*
+ * Assumption - screen switching can only occur on motion events
+ */
+ if (e->pScreen != miEventQueue.pDequeueScreen)
+ {
+ miEventQueue.pDequeueScreen = e->pScreen;
+ x = e->event.u.keyButtonPointer.rootX;
+ y = e->event.u.keyButtonPointer.rootY;
+ if (miEventQueue.head == QUEUE_SIZE - 1)
+ miEventQueue.head = 0;
+ else
+ ++miEventQueue.head;
+ NewCurrentScreen (miEventQueue.pDequeueScreen, x, y);
+ }
+ else
+ {
+ xe = e->event;
+ if (miEventQueue.head == QUEUE_SIZE - 1)
+ miEventQueue.head = 0;
+ else
+ ++miEventQueue.head;
+ switch (xe.u.u.type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ (*miEventQueue.pKbd->processInputProc)
+ (&xe, (DeviceIntPtr)miEventQueue.pKbd, 1);
+ break;
+ default:
+ (*miEventQueue.pPtr->processInputProc)
+ (&xe, (DeviceIntPtr)miEventQueue.pPtr, 1);
+ break;
+ }
+ }
+ }
+}
diff --git a/xc/programs/Xserver/mi/miexpose.c b/xc/programs/Xserver/mi/miexpose.c
new file mode 100644
index 000000000..de027e7ba
--- /dev/null
+++ b/xc/programs/Xserver/mi/miexpose.c
@@ -0,0 +1,899 @@
+/* $XFree86: xc/programs/Xserver/mi/miexpose.c,v 3.5 1999/04/11 13:11:19 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* The panoramix components contained the following notice */
+/****************************************************************
+* *
+* Copyright (c) Digital Equipment Corporation, 1991, 1997 *
+* *
+* All Rights Reserved. Unpublished rights reserved under *
+* the copyright laws of the United States. *
+* *
+* The software contained on this media is proprietary to *
+* and embodies the confidential technology of Digital *
+* Equipment Corporation. Possession, use, duplication or *
+* dissemination of the software and media is authorized only *
+* pursuant to a valid written license from Digital Equipment *
+* Corporation. *
+* *
+* RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure *
+* by the U.S. Government is subject to restrictions as set *
+* forth in Subparagraph (c)(1)(ii) of DFARS 252.227-7013, *
+* or in FAR 52.227-19, as applicable. *
+* *
+*****************************************************************/
+
+
+/* $TOG: miexpose.c /main/44 1998/02/09 14:46:47 kaleb $ */
+
+#include "X.h"
+#define NEED_EVENTS
+#include "Xproto.h"
+#include "Xprotostr.h"
+
+#include "misc.h"
+#include "regionstr.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmap.h"
+#include "input.h"
+
+#include "dixstruct.h"
+#include "mi.h"
+#include "Xmd.h"
+
+#include "globals.h"
+
+extern WindowPtr *WindowTable;
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#endif
+
+/*
+ machine-independent graphics exposure code. any device that uses
+the region package can call this.
+*/
+
+#ifndef RECTLIMIT
+#define RECTLIMIT 25 /* pick a number, any number > 8 */
+#endif
+
+/* miHandleExposures
+ generate a region for exposures for areas that were copied from obscured or
+non-existent areas to non-obscured areas of the destination. Paint the
+background for the region, if the destination is a window.
+
+NOTE:
+ this should generally be called, even if graphicsExposures is false,
+because this is where bits get recovered from backing store.
+
+NOTE:
+ added argument 'plane' is used to indicate how exposures from backing
+store should be accomplished. If plane is 0 (i.e. no bit plane), CopyArea
+should be used, else a CopyPlane of the indicated plane will be used. The
+exposing is done by the backing store's GraphicsExpose function, of course.
+
+*/
+
+RegionPtr
+miHandleExposures(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty, plane)
+ register DrawablePtr pSrcDrawable;
+ register DrawablePtr pDstDrawable;
+ GCPtr pGC;
+ int srcx, srcy;
+ int width, height;
+ int dstx, dsty;
+ unsigned long plane;
+{
+ register ScreenPtr pscr = pGC->pScreen;
+ RegionPtr prgnSrcClip; /* drawable-relative source clip */
+ RegionRec rgnSrcRec;
+ RegionPtr prgnDstClip; /* drawable-relative dest clip */
+ RegionRec rgnDstRec;
+ BoxRec srcBox; /* unclipped source */
+ RegionRec rgnExposed; /* exposed region, calculated source-
+ relative, made dst relative to
+ intersect with visible parts of
+ dest and send events to client,
+ and then screen relative to paint
+ the window background
+ */
+ WindowPtr pSrcWin;
+ BoxRec expBox;
+ Bool extents;
+
+ /* avoid work if we can */
+ if (!pGC->graphicsExposures &&
+ (pDstDrawable->type == DRAWABLE_PIXMAP) &&
+ ((pSrcDrawable->type == DRAWABLE_PIXMAP) ||
+ (((WindowPtr)pSrcDrawable)->backStorage == NULL)))
+ return NULL;
+
+ srcBox.x1 = srcx;
+ srcBox.y1 = srcy;
+ srcBox.x2 = srcx+width;
+ srcBox.y2 = srcy+height;
+
+ if (pSrcDrawable->type != DRAWABLE_PIXMAP)
+ {
+ BoxRec TsrcBox;
+
+ TsrcBox.x1 = srcx + pSrcDrawable->x;
+ TsrcBox.y1 = srcy + pSrcDrawable->y;
+ TsrcBox.x2 = TsrcBox.x1 + width;
+ TsrcBox.y2 = TsrcBox.y1 + height;
+ pSrcWin = (WindowPtr) pSrcDrawable;
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ prgnSrcClip = NotClippedByChildren (pSrcWin);
+ if ((RECT_IN_REGION(pscr, prgnSrcClip, &TsrcBox)) == rgnIN)
+ {
+ REGION_DESTROY(pscr, prgnSrcClip);
+ return NULL;
+ }
+ }
+ else
+ {
+ if ((RECT_IN_REGION(pscr, &pSrcWin->clipList, &TsrcBox)) == rgnIN)
+ return NULL;
+ prgnSrcClip = &rgnSrcRec;
+ REGION_INIT(pscr, prgnSrcClip, NullBox, 0);
+ REGION_COPY(pscr, prgnSrcClip, &pSrcWin->clipList);
+ }
+ REGION_TRANSLATE(pscr, prgnSrcClip,
+ -pSrcDrawable->x, -pSrcDrawable->y);
+ }
+ else
+ {
+ BoxRec box;
+
+ if ((srcBox.x1 >= 0) && (srcBox.y1 >= 0) &&
+ (srcBox.x2 <= pSrcDrawable->width) &&
+ (srcBox.y2 <= pSrcDrawable->height))
+ return NULL;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pSrcDrawable->width;
+ box.y2 = pSrcDrawable->height;
+ prgnSrcClip = &rgnSrcRec;
+ REGION_INIT(pscr, prgnSrcClip, &box, 1);
+ pSrcWin = (WindowPtr)NULL;
+ }
+
+ if (pDstDrawable == pSrcDrawable)
+ {
+ prgnDstClip = prgnSrcClip;
+ }
+ else if (pDstDrawable->type != DRAWABLE_PIXMAP)
+ {
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ prgnDstClip = NotClippedByChildren((WindowPtr)pDstDrawable);
+ }
+ else
+ {
+ prgnDstClip = &rgnDstRec;
+ REGION_INIT(pscr, prgnDstClip, NullBox, 0);
+ REGION_COPY(pscr, prgnDstClip,
+ &((WindowPtr)pDstDrawable)->clipList);
+ }
+ REGION_TRANSLATE(pscr, prgnDstClip,
+ -pDstDrawable->x, -pDstDrawable->y);
+ }
+ else
+ {
+ BoxRec box;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pDstDrawable->width;
+ box.y2 = pDstDrawable->height;
+ prgnDstClip = &rgnDstRec;
+ REGION_INIT(pscr, prgnDstClip, &box, 1);
+ }
+
+ /* drawable-relative source region */
+ REGION_INIT(pscr, &rgnExposed, &srcBox, 1);
+
+ /* now get the hidden parts of the source box*/
+ REGION_SUBTRACT(pscr, &rgnExposed, &rgnExposed, prgnSrcClip);
+
+ if (pSrcWin && pSrcWin->backStorage)
+ {
+ /*
+ * Copy any areas from the source backing store. Modifies
+ * rgnExposed.
+ */
+ (* pSrcWin->drawable.pScreen->ExposeCopy) ((WindowPtr)pSrcDrawable,
+ pDstDrawable,
+ pGC,
+ &rgnExposed,
+ srcx, srcy,
+ dstx, dsty,
+ plane);
+ }
+
+ /* move them over the destination */
+ REGION_TRANSLATE(pscr, &rgnExposed, dstx-srcx, dsty-srcy);
+
+ /* intersect with visible areas of dest */
+ REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, prgnDstClip);
+
+ /*
+ * If we have LOTS of rectangles, we decide to take the extents
+ * and force an exposure on that. This should require much less
+ * work overall, on both client and server. This is cheating, but
+ * isn't prohibited by the protocol ("spontaneous combustion" :-)
+ * for windows.
+ */
+ extents = pGC->graphicsExposures &&
+ (REGION_NUM_RECTS(&rgnExposed) > RECTLIMIT) &&
+ (pDstDrawable->type != DRAWABLE_PIXMAP);
+#ifdef SHAPE
+ if (pSrcWin)
+ {
+ RegionPtr region;
+ if (!(region = wClipShape (pSrcWin)))
+ region = wBoundingShape (pSrcWin);
+ /*
+ * If you try to CopyArea the extents of a shaped window, compacting the
+ * exposed region will undo all our work!
+ */
+ if (extents && pSrcWin && region &&
+ (RECT_IN_REGION(pscr, region, &srcBox) != rgnIN))
+ extents = FALSE;
+ }
+#endif
+ if (extents)
+ {
+ WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+ expBox = *REGION_EXTENTS(pscr, &rgnExposed);
+ REGION_RESET(pscr, &rgnExposed, &expBox);
+ /* need to clear out new areas of backing store */
+ if (pWin->backStorage)
+ (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+ pWin,
+ expBox.x1,
+ expBox.y1,
+ expBox.x2 - expBox.x1,
+ expBox.y2 - expBox.y1,
+ FALSE);
+ }
+ if ((pDstDrawable->type != DRAWABLE_PIXMAP) &&
+ (((WindowPtr)pDstDrawable)->backgroundState != None))
+ {
+ WindowPtr pWin = (WindowPtr)pDstDrawable;
+
+ /* make the exposed area screen-relative */
+ REGION_TRANSLATE(pscr, &rgnExposed,
+ pDstDrawable->x, pDstDrawable->y);
+
+ if (extents)
+ {
+ /* PaintWindowBackground doesn't clip, so we have to */
+ REGION_INTERSECT(pscr, &rgnExposed, &rgnExposed, &pWin->clipList);
+ }
+ (*pWin->drawable.pScreen->PaintWindowBackground)(
+ (WindowPtr)pDstDrawable, &rgnExposed, PW_BACKGROUND);
+
+ if (extents)
+ {
+ REGION_RESET(pscr, &rgnExposed, &expBox);
+ }
+ else
+ REGION_TRANSLATE(pscr, &rgnExposed,
+ -pDstDrawable->x, -pDstDrawable->y);
+ }
+ if (prgnDstClip == &rgnDstRec)
+ {
+ REGION_UNINIT(pscr, prgnDstClip);
+ }
+ else if (prgnDstClip != prgnSrcClip)
+ {
+ REGION_DESTROY(pscr, prgnDstClip);
+ }
+
+ if (prgnSrcClip == &rgnSrcRec)
+ {
+ REGION_UNINIT(pscr, prgnSrcClip);
+ }
+ else
+ {
+ REGION_DESTROY(pscr, prgnSrcClip);
+ }
+
+ if (pGC->graphicsExposures)
+ {
+ /* don't look */
+ RegionPtr exposed = REGION_CREATE(pscr, NullBox, 0);
+ *exposed = rgnExposed;
+ return exposed;
+ }
+ else
+ {
+ REGION_UNINIT(pscr, &rgnExposed);
+ return NULL;
+ }
+}
+
+/* send GraphicsExpose events, or a NoExpose event, based on the region */
+
+void
+miSendGraphicsExpose (client, pRgn, drawable, major, minor)
+ ClientPtr client;
+ RegionPtr pRgn;
+ XID drawable;
+ int major;
+ int minor;
+{
+ if (pRgn && !REGION_NIL(pRgn))
+ {
+ xEvent *pEvent;
+ register xEvent *pe;
+ register BoxPtr pBox;
+ register int i;
+ int numRects;
+
+ numRects = REGION_NUM_RECTS(pRgn);
+ pBox = REGION_RECTS(pRgn);
+ if(!(pEvent = (xEvent *)ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+ return;
+ pe = pEvent;
+
+ for (i=1; i<=numRects; i++, pe++, pBox++)
+ {
+ pe->u.u.type = GraphicsExpose;
+ pe->u.graphicsExposure.drawable = drawable;
+ pe->u.graphicsExposure.x = pBox->x1;
+ pe->u.graphicsExposure.y = pBox->y1;
+ pe->u.graphicsExposure.width = pBox->x2 - pBox->x1;
+ pe->u.graphicsExposure.height = pBox->y2 - pBox->y1;
+ pe->u.graphicsExposure.count = numRects - i;
+ pe->u.graphicsExposure.majorEvent = major;
+ pe->u.graphicsExposure.minorEvent = minor;
+ }
+ TryClientEvents(client, pEvent, numRects,
+ (Mask)0, NoEventMask, NullGrab);
+ DEALLOCATE_LOCAL(pEvent);
+ }
+ else
+ {
+ xEvent event;
+ event.u.u.type = NoExpose;
+ event.u.noExposure.drawable = drawable;
+ event.u.noExposure.majorEvent = major;
+ event.u.noExposure.minorEvent = minor;
+ TryClientEvents(client, &event, 1,
+ (Mask)0, NoEventMask, NullGrab);
+ }
+}
+#ifdef PANORAMIX
+Bool
+PanoramiXBoxOffScreen(pWin, pBox)
+ register WindowPtr pWin;
+ RegionPtr pBox;
+{
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+ BoxRec box;
+
+ box = *(REGION_EXTENTS(pScreen, &pWin->winSize));
+
+ if ((pBox->extents.x2 < box.x1) && (pBox->extents.x1 < box.x1))
+ return TRUE;
+ if ((pBox->extents.x1 > box.x2) && (pBox->extents.x2 > box.x2))
+ return TRUE;
+ if ((pBox->extents.y2 < box.y1) && (pBox->extents.y1 < box.y1))
+ return TRUE;
+ if ((pBox->extents.y1 > box.y2) && (pBox->extents.y2 > box.y2))
+ return TRUE;
+
+ return FALSE;
+}
+#endif
+
+void
+miSendExposures(pWin, pRgn, dx, dy)
+ WindowPtr pWin;
+ RegionPtr pRgn;
+ register int dx, dy;
+{
+ register BoxPtr pBox;
+ int numRects;
+ register xEvent *pEvent, *pe;
+ register int i;
+
+ pBox = REGION_RECTS(pRgn);
+ numRects = REGION_NUM_RECTS(pRgn);
+ if(!(pEvent = (xEvent *) ALLOCATE_LOCAL(numRects * sizeof(xEvent))))
+ return;
+
+ for (i=numRects, pe = pEvent; --i >= 0; pe++, pBox++)
+ {
+ pe->u.u.type = Expose;
+ pe->u.expose.window = pWin->drawable.id;
+ pe->u.expose.x = pBox->x1 - dx;
+ pe->u.expose.y = pBox->y1 - dy;
+ pe->u.expose.width = pBox->x2 - pBox->x1;
+ pe->u.expose.height = pBox->y2 - pBox->y1;
+ pe->u.expose.count = i;
+ }
+#ifdef PANORAMIX
+ /* In the case where a window is split between one
+ or more screen, an expose event will be written
+ to the client describing the section of the window
+ which is exposed per screen. This causes a failure
+ in the vsw test CH07/grbbtn because the test is
+ poorly written and expects 1 expose event and fails
+ when it reads more than 1 expose event when the
+ window is split. The server is in fact doing the
+ expected and correct behavior. -mad 08/29/96
+ */
+ if (!noPanoramiXExtension){
+ if (PanoramiXMapped){
+ if (!PanoramiXBoxOffScreen(pWin,pRgn))
+ DeliverEvents(pWin, pEvent, numRects, NullWindow);
+ }else
+ DeliverEvents(pWin, pEvent, numRects, NullWindow);
+ } else
+ DeliverEvents(pWin, pEvent, numRects, NullWindow);
+#else
+ DeliverEvents(pWin, pEvent, numRects, NullWindow);
+#endif
+
+ DEALLOCATE_LOCAL(pEvent);
+}
+
+void
+miWindowExposures(pWin, prgn, other_exposed)
+ WindowPtr pWin;
+ register RegionPtr prgn, other_exposed;
+{
+ RegionPtr exposures = prgn;
+ if (pWin->backStorage && prgn)
+ /*
+ * in some cases, backing store will cause a different
+ * region to be exposed than needs to be repainted
+ * (like when a window is mapped). RestoreAreas is
+ * allowed to return a region other than prgn,
+ * in which case this routine will free the resultant
+ * region. If exposures is null, then no events will
+ * be sent to the client; if prgn is empty
+ * no areas will be repainted.
+ */
+ exposures = (*pWin->drawable.pScreen->RestoreAreas)(pWin, prgn);
+ if ((prgn && !REGION_NIL(prgn)) ||
+ (exposures && !REGION_NIL(exposures)) || other_exposed)
+ {
+ RegionRec expRec;
+ int clientInterested;
+
+ /*
+ * Restore from backing-store FIRST.
+ */
+ clientInterested = (pWin->eventMask|wOtherEventMasks(pWin)) & ExposureMask;
+ if (other_exposed)
+ {
+ if (exposures)
+ {
+ REGION_UNION(pWin->drawable.pScreen, other_exposed,
+ exposures,
+ other_exposed);
+ if (exposures != prgn)
+ REGION_DESTROY(pWin->drawable.pScreen, exposures);
+ }
+ exposures = other_exposed;
+ }
+ if (clientInterested && exposures && (REGION_NUM_RECTS(exposures) > RECTLIMIT))
+ {
+ /*
+ * If we have LOTS of rectangles, we decide to take the extents
+ * and force an exposure on that. This should require much less
+ * work overall, on both client and server. This is cheating, but
+ * isn't prohibited by the protocol ("spontaneous combustion" :-).
+ */
+ BoxRec box;
+
+ box = *REGION_EXTENTS( pWin->drawable.pScreen, exposures);
+ if (exposures == prgn) {
+ exposures = &expRec;
+ REGION_INIT( pWin->drawable.pScreen, exposures, &box, 1);
+ REGION_RESET( pWin->drawable.pScreen, prgn, &box);
+ } else {
+ REGION_RESET( pWin->drawable.pScreen, exposures, &box);
+ REGION_UNION( pWin->drawable.pScreen, prgn, prgn, exposures);
+ }
+ /* PaintWindowBackground doesn't clip, so we have to */
+ REGION_INTERSECT( pWin->drawable.pScreen, prgn, prgn, &pWin->clipList);
+ /* need to clear out new areas of backing store, too */
+ if (pWin->backStorage)
+ (void) (* pWin->drawable.pScreen->ClearBackingStore)(
+ pWin,
+ box.x1 - pWin->drawable.x,
+ box.y1 - pWin->drawable.y,
+ box.x2 - box.x1,
+ box.y2 - box.y1,
+ FALSE);
+ }
+ if (prgn && !REGION_NIL(prgn))
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, PW_BACKGROUND);
+ if (clientInterested && exposures && !REGION_NIL(exposures))
+ miSendExposures(pWin, exposures,
+ pWin->drawable.x, pWin->drawable.y);
+ if (exposures == &expRec)
+ {
+ REGION_UNINIT( pWin->drawable.pScreen, exposures);
+ }
+ else if (exposures && exposures != prgn && exposures != other_exposed)
+ REGION_DESTROY( pWin->drawable.pScreen, exposures);
+ if (prgn)
+ REGION_EMPTY( pWin->drawable.pScreen, prgn);
+ }
+ else if (exposures && exposures != prgn)
+ REGION_DESTROY( pWin->drawable.pScreen, exposures);
+}
+
+
+/*
+ this code is highly unlikely. it is not haile selassie.
+
+ there is some hair here. we can't just use the window's
+clip region as it is, because if we are painting the border,
+the border is not in the client area and so we will be excluded
+when we validate the GC, and if we are painting a parent-relative
+background, the area we want to paint is in some other window.
+since we trust the code calling us to tell us to paint only areas
+that are really ours, we will temporarily give the window a
+clipList the size of the whole screen and an origin at (0,0).
+this more or less assumes that ddX code will do translation
+based on the window's absolute position, and that ValidateGC will
+look at clipList, and that no other fields from the
+window will be used. it's not possible to just draw
+in the root because it may be a different depth.
+
+to get the tile to align correctly we set the GC's tile origin to
+be the (x,y) of the window's upper left corner, after which we
+get the right bits when drawing into the root.
+
+because the clip_mask is being set to None, we may call DoChangeGC with
+fPointer set true, thus we no longer need to install the background or
+border tile in the resource table.
+*/
+
+static RESTYPE ResType = 0;
+static int numGCs = 0;
+static GCPtr screenContext[MAXSCREENS];
+
+/*ARGSUSED*/
+static int
+tossGC (value, id)
+pointer value;
+XID id;
+{
+ GCPtr pGC = (GCPtr)value;
+ screenContext[pGC->pScreen->myNum] = (GCPtr)NULL;
+ FreeGC (pGC, id);
+ numGCs--;
+ if (!numGCs)
+ ResType = 0;
+}
+
+
+void
+miPaintWindow(pWin, prgn, what)
+register WindowPtr pWin;
+RegionPtr prgn;
+int what;
+{
+ int status;
+
+ Bool usingScratchGC = FALSE;
+ WindowPtr pRoot;
+
+#define FUNCTION 0
+#define FOREGROUND 1
+#define TILE 2
+#define FILLSTYLE 3
+#define ABSX 4
+#define ABSY 5
+#define CLIPMASK 6
+#define SUBWINDOW 7
+#define COUNT_BITS 8
+
+ ChangeGCVal gcval[7];
+ ChangeGCVal newValues [COUNT_BITS];
+
+ BITS32 gcmask, index, mask;
+ RegionRec prgnWin;
+ DDXPointRec oldCorner;
+ BoxRec box;
+ WindowPtr pBgWin;
+ GCPtr pGC;
+ register int i;
+ register BoxPtr pbox;
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+ register xRectangle *prect;
+ int numRects;
+
+ gcmask = 0;
+
+ if (what == PW_BACKGROUND)
+ {
+ switch (pWin->backgroundState) {
+ case None:
+ return;
+ case ParentRelative:
+ (*pWin->parent->drawable.pScreen->PaintWindowBackground)(pWin->parent, prgn, what);
+ return;
+ case BackgroundPixel:
+ newValues[FOREGROUND].val = pWin->background.pixel;
+ newValues[FILLSTYLE].val = FillSolid;
+ gcmask |= GCForeground | GCFillStyle;
+ break;
+ case BackgroundPixmap:
+ newValues[TILE].ptr = (pointer)pWin->background.pixmap;
+ newValues[FILLSTYLE].val = FillTiled;
+ gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+ break;
+ }
+ }
+ else
+ {
+ if (pWin->borderIsPixel)
+ {
+ newValues[FOREGROUND].val = pWin->border.pixel;
+ newValues[FILLSTYLE].val = FillSolid;
+ gcmask |= GCForeground | GCFillStyle;
+ }
+ else
+ {
+ newValues[TILE].ptr = (pointer)pWin->border.pixmap;
+ newValues[FILLSTYLE].val = FillTiled;
+ gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+ }
+ }
+
+ prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(prgn) *
+ sizeof(xRectangle));
+ if (!prect)
+ return;
+
+ newValues[FUNCTION].val = GXcopy;
+ gcmask |= GCFunction | GCClipMask;
+
+ i = pScreen->myNum;
+ pRoot = WindowTable[i];
+
+ pBgWin = pWin;
+ if (what == PW_BORDER)
+ {
+ while (pBgWin->backgroundState == ParentRelative)
+ pBgWin = pBgWin->parent;
+ }
+
+ if ((pWin->drawable.depth != pRoot->drawable.depth) ||
+ (pWin->drawable.bitsPerPixel != pRoot->drawable.bitsPerPixel))
+ {
+ usingScratchGC = TRUE;
+ pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen);
+ if (!pGC)
+ {
+ DEALLOCATE_LOCAL(prect);
+ return;
+ }
+ /*
+ * mash the clip list so we can paint the border by
+ * mangling the window in place, pretending it
+ * spans the entire screen
+ */
+ if (what == PW_BORDER)
+ {
+ prgnWin = pWin->clipList;
+ oldCorner.x = pWin->drawable.x;
+ oldCorner.y = pWin->drawable.y;
+ pWin->drawable.x = pWin->drawable.y = 0;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ REGION_INIT(pScreen, &pWin->clipList, &box, 1);
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ newValues[ABSX].val = pBgWin->drawable.x;
+ newValues[ABSY].val = pBgWin->drawable.y;
+ }
+ else
+ {
+ newValues[ABSX].val = 0;
+ newValues[ABSY].val = 0;
+ }
+ } else {
+ /*
+ * draw the background to the root window
+ */
+ if (screenContext[i] == (GCPtr)NULL)
+ {
+ if (!ResType && !(ResType = CreateNewResourceType(tossGC)))
+ return;
+ screenContext[i] = CreateGC((DrawablePtr)pWin, (BITS32) 0,
+ (XID *)NULL, &status);
+ if (!screenContext[i])
+ return;
+ numGCs++;
+ if (!AddResource(FakeClientID(0), ResType,
+ (pointer)screenContext[i]))
+ return;
+ }
+ pGC = screenContext[i];
+ newValues[SUBWINDOW].val = IncludeInferiors;
+ newValues[ABSX].val = pBgWin->drawable.x;
+ newValues[ABSY].val = pBgWin->drawable.y;
+ gcmask |= GCSubwindowMode;
+ pWin = pRoot;
+ }
+
+ if (pWin->backStorage)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack);
+
+ mask = gcmask;
+ gcmask = 0;
+ i = 0;
+ while (mask) {
+ index = lowbit (mask);
+ mask &= ~index;
+ switch (index) {
+ case GCFunction:
+ if (pGC->alu != newValues[FUNCTION].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FUNCTION].val;
+ }
+ break;
+ case GCTileStipXOrigin:
+ if ( pGC->patOrg.x != newValues[ABSX].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[ABSX].val;
+ }
+ break;
+ case GCTileStipYOrigin:
+ if ( pGC->patOrg.y != newValues[ABSY].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[ABSY].val;
+ }
+ break;
+ case GCClipMask:
+ if ( pGC->clientClipType != CT_NONE) {
+ gcmask |= index;
+ gcval[i++].val = CT_NONE;
+ }
+ break;
+ case GCSubwindowMode:
+ if ( pGC->subWindowMode != newValues[SUBWINDOW].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[SUBWINDOW].val;
+ }
+ break;
+ case GCTile:
+ if (pGC->tileIsPixel || pGC->tile.pixmap != newValues[TILE].ptr)
+ {
+ gcmask |= index;
+ gcval[i++].ptr = newValues[TILE].ptr;
+ }
+ break;
+ case GCFillStyle:
+ if ( pGC->fillStyle != newValues[FILLSTYLE].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FILLSTYLE].val;
+ }
+ break;
+ case GCForeground:
+ if ( pGC->fgPixel != newValues[FOREGROUND].val) {
+ gcmask |= index;
+ gcval[i++].val = newValues[FOREGROUND].val;
+ }
+ break;
+ }
+ }
+
+ if (gcmask)
+ dixChangeGC(NullClient, pGC, gcmask, NULL, gcval);
+
+ if (pWin->drawable.serialNumber != pGC->serialNumber)
+ ValidateGC((DrawablePtr)pWin, pGC);
+
+ numRects = REGION_NUM_RECTS(prgn);
+ pbox = REGION_RECTS(prgn);
+ for (i= numRects; --i >= 0; pbox++, prect++)
+ {
+ prect->x = pbox->x1 - pWin->drawable.x;
+ prect->y = pbox->y1 - pWin->drawable.y;
+ prect->width = pbox->x2 - pbox->x1;
+ prect->height = pbox->y2 - pbox->y1;
+ }
+ prect -= numRects;
+ (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect);
+ DEALLOCATE_LOCAL(prect);
+
+ if (pWin->backStorage)
+ (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing);
+
+ if (usingScratchGC)
+ {
+ if (what == PW_BORDER)
+ {
+ REGION_UNINIT(pScreen, &pWin->clipList);
+ pWin->clipList = prgnWin;
+ pWin->drawable.x = oldCorner.x;
+ pWin->drawable.y = oldCorner.y;
+ pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ FreeScratchGC(pGC);
+ }
+}
+
+
+/* MICLEARDRAWABLE -- sets the entire drawable to the background color of
+ * the GC. Useful when we have a scratch drawable and need to initialize
+ * it. */
+void
+miClearDrawable(pDraw, pGC)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+{
+ XID fg = pGC->fgPixel;
+ XID bg = pGC->bgPixel;
+ xRectangle rect;
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = pDraw->width;
+ rect.height = pDraw->height;
+ DoChangeGC(pGC, GCForeground, &bg, 0);
+ ValidateGC(pDraw, pGC);
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, 1, &rect);
+ DoChangeGC(pGC, GCForeground, &fg, 0);
+ ValidateGC(pDraw, pGC);
+}
diff --git a/xc/programs/Xserver/mi/mifillarc.c b/xc/programs/Xserver/mi/mifillarc.c
new file mode 100644
index 000000000..c19d315e7
--- /dev/null
+++ b/xc/programs/Xserver/mi/mifillarc.c
@@ -0,0 +1,807 @@
+/* $XFree86: xc/programs/Xserver/mi/mifillarc.c,v 3.4 1999/04/11 13:11:20 dawes Exp $ */
+/************************************************************
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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: Bob Scheifler, MIT X Consortium
+
+********************************************************/
+
+/* $TOG: mifillarc.c /main/20 1998/02/09 14:46:52 kaleb $ */
+
+#include <math.h>
+#include "X.h"
+#include "Xprotostr.h"
+#include "miscstruct.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "mifpoly.h"
+#include "mi.h"
+#include "mifillarc.h"
+
+#define QUADRANT (90 * 64)
+#define HALFCIRCLE (180 * 64)
+#define QUADRANT3 (270 * 64)
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define Dsin(d) sin((double)d*(M_PI/11520.0))
+#define Dcos(d) cos((double)d*(M_PI/11520.0))
+
+void
+miFillArcSetup(arc, info)
+ register xArc *arc;
+ register miFillArcRec *info;
+{
+ info->y = arc->height >> 1;
+ info->dy = arc->height & 1;
+ info->yorg = arc->y + info->y;
+ info->dx = arc->width & 1;
+ info->xorg = arc->x + (arc->width >> 1) + info->dx;
+ info->dx = 1 - info->dx;
+ if (arc->width == arc->height)
+ {
+ /* (2x - 2xorg)^2 = d^2 - (2y - 2yorg)^2 */
+ /* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */
+ info->ym = 8;
+ info->xm = 8;
+ info->yk = info->y << 3;
+ if (!info->dx)
+ {
+ info->xk = 0;
+ info->e = -1;
+ }
+ else
+ {
+ info->y++;
+ info->yk += 4;
+ info->xk = -4;
+ info->e = - (info->y << 3);
+ }
+ }
+ else
+ {
+ /* h^2 * (2x - 2xorg)^2 = w^2 * h^2 - w^2 * (2y - 2yorg)^2 */
+ /* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */
+ info->ym = (arc->width * arc->width) << 3;
+ info->xm = (arc->height * arc->height) << 3;
+ info->yk = info->y * info->ym;
+ if (!info->dy)
+ info->yk -= info->ym >> 1;
+ if (!info->dx)
+ {
+ info->xk = 0;
+ info->e = - (info->xm >> 3);
+ }
+ else
+ {
+ info->y++;
+ info->yk += info->ym;
+ info->xk = -(info->xm >> 1);
+ info->e = info->xk - info->yk;
+ }
+ }
+}
+
+void
+miFillArcDSetup(arc, info)
+ register xArc *arc;
+ register miFillArcDRec *info;
+{
+ /* h^2 * (2x - 2xorg)^2 = w^2 * h^2 - w^2 * (2y - 2yorg)^2 */
+ /* even: xorg = yorg = 0 odd: xorg = .5, yorg = -.5 */
+ info->y = arc->height >> 1;
+ info->dy = arc->height & 1;
+ info->yorg = arc->y + info->y;
+ info->dx = arc->width & 1;
+ info->xorg = arc->x + (arc->width >> 1) + info->dx;
+ info->dx = 1 - info->dx;
+ info->ym = ((double)arc->width) * (arc->width * 8);
+ info->xm = ((double)arc->height) * (arc->height * 8);
+ info->yk = info->y * info->ym;
+ if (!info->dy)
+ info->yk -= info->ym / 2.0;
+ if (!info->dx)
+ {
+ info->xk = 0;
+ info->e = - (info->xm / 8.0);
+ }
+ else
+ {
+ info->y++;
+ info->yk += info->ym;
+ info->xk = -info->xm / 2.0;
+ info->e = info->xk - info->yk;
+ }
+}
+
+static void
+miGetArcEdge(arc, edge, k, top, left)
+ register xArc *arc;
+ register miSliceEdgePtr edge;
+ int k;
+ Bool top, left;
+{
+ register int xady, y;
+
+ y = arc->height >> 1;
+ if (!(arc->width & 1))
+ y++;
+ if (!top)
+ {
+ y = -y;
+ if (arc->height & 1)
+ y--;
+ }
+ xady = k + y * edge->dx;
+ if (xady <= 0)
+ edge->x = - ((-xady) / edge->dy + 1);
+ else
+ edge->x = (xady - 1) / edge->dy;
+ edge->e = xady - edge->x * edge->dy;
+ if ((top && (edge->dx < 0)) || (!top && (edge->dx > 0)))
+ edge->e = edge->dy - edge->e + 1;
+ if (left)
+ edge->x++;
+ edge->x += arc->x + (arc->width >> 1);
+ if (edge->dx > 0)
+ {
+ edge->deltax = 1;
+ edge->stepx = edge->dx / edge->dy;
+ edge->dx = edge->dx % edge->dy;
+ }
+ else
+ {
+ edge->deltax = -1;
+ edge->stepx = - ((-edge->dx) / edge->dy);
+ edge->dx = (-edge->dx) % edge->dy;
+ }
+ if (!top)
+ {
+ edge->deltax = -edge->deltax;
+ edge->stepx = -edge->stepx;
+ }
+}
+
+void
+miEllipseAngleToSlope (angle, width, height, dxp, dyp, d_dxp, d_dyp)
+ int angle;
+ int width;
+ int height;
+ int *dxp;
+ int *dyp;
+ double *d_dxp;
+ double *d_dyp;
+{
+ int dx, dy;
+ double d_dx, d_dy, scale;
+ Bool negative_dx, negative_dy;
+
+ switch (angle) {
+ case 0:
+ *dxp = -1;
+ *dyp = 0;
+ if (d_dxp) {
+ *d_dxp = width / 2.0;
+ *d_dyp = 0;
+ }
+ break;
+ case QUADRANT:
+ *dxp = 0;
+ *dyp = 1;
+ if (d_dxp) {
+ *d_dxp = 0;
+ *d_dyp = - height / 2.0;
+ }
+ break;
+ case HALFCIRCLE:
+ *dxp = 1;
+ *dyp = 0;
+ if (d_dxp) {
+ *d_dxp = - width / 2.0;
+ *d_dyp = 0;
+ }
+ break;
+ case QUADRANT3:
+ *dxp = 0;
+ *dyp = -1;
+ if (d_dxp) {
+ *d_dxp = 0;
+ *d_dyp = height / 2.0;
+ }
+ break;
+ default:
+ d_dx = Dcos(angle) * width;
+ d_dy = Dsin(angle) * height;
+ if (d_dxp) {
+ *d_dxp = d_dx / 2.0;
+ *d_dyp = - d_dy / 2.0;
+ }
+ negative_dx = FALSE;
+ if (d_dx < 0.0)
+ {
+ d_dx = -d_dx;
+ negative_dx = TRUE;
+ }
+ negative_dy = FALSE;
+ if (d_dy < 0.0)
+ {
+ d_dy = -d_dy;
+ negative_dy = TRUE;
+ }
+ scale = d_dx;
+ if (d_dy > d_dx)
+ scale = d_dy;
+ dx = floor ((d_dx * 32768) / scale + 0.5);
+ if (negative_dx)
+ dx = -dx;
+ *dxp = dx;
+ dy = floor ((d_dy * 32768) / scale + 0.5);
+ if (negative_dy)
+ dy = -dy;
+ *dyp = dy;
+ break;
+ }
+}
+
+static void
+miGetPieEdge(arc, angle, edge, top, left)
+ register xArc *arc;
+ register int angle;
+ register miSliceEdgePtr edge;
+ Bool top, left;
+{
+ register int k;
+ int dx, dy;
+
+ miEllipseAngleToSlope (angle, arc->width, arc->height, &dx, &dy, 0, 0);
+
+ if (dy == 0)
+ {
+ edge->x = left ? -65536 : 65536;
+ edge->stepx = 0;
+ edge->e = 0;
+ edge->dx = -1;
+ return;
+ }
+ if (dx == 0)
+ {
+ edge->x = arc->x + (arc->width >> 1);
+ if (left && (arc->width & 1))
+ edge->x++;
+ else if (!left && !(arc->width & 1))
+ edge->x--;
+ edge->stepx = 0;
+ edge->e = 0;
+ edge->dx = -1;
+ return;
+ }
+ if (dy < 0) {
+ dx = -dx;
+ dy = -dy;
+ }
+ k = (arc->height & 1) ? dx : 0;
+ if (arc->width & 1)
+ k += dy;
+ edge->dx = dx << 1;
+ edge->dy = dy << 1;
+ miGetArcEdge(arc, edge, k, top, left);
+}
+
+void
+miFillArcSliceSetup(arc, slice, pGC)
+ register xArc *arc;
+ register miArcSliceRec *slice;
+ GCPtr pGC;
+{
+ register int angle1, angle2;
+
+ angle1 = arc->angle1;
+ if (arc->angle2 < 0)
+ {
+ angle2 = angle1;
+ angle1 += arc->angle2;
+ }
+ else
+ angle2 = angle1 + arc->angle2;
+ while (angle1 < 0)
+ angle1 += FULLCIRCLE;
+ while (angle1 >= FULLCIRCLE)
+ angle1 -= FULLCIRCLE;
+ while (angle2 < 0)
+ angle2 += FULLCIRCLE;
+ while (angle2 >= FULLCIRCLE)
+ angle2 -= FULLCIRCLE;
+ slice->min_top_y = 0;
+ slice->max_top_y = arc->height >> 1;
+ slice->min_bot_y = 1 - (arc->height & 1);
+ slice->max_bot_y = slice->max_top_y - 1;
+ slice->flip_top = FALSE;
+ slice->flip_bot = FALSE;
+ if (pGC->arcMode == ArcPieSlice)
+ {
+ slice->edge1_top = (angle1 < HALFCIRCLE);
+ slice->edge2_top = (angle2 <= HALFCIRCLE);
+ if ((angle2 == 0) || (angle1 == HALFCIRCLE))
+ {
+ if (angle2 ? slice->edge2_top : slice->edge1_top)
+ slice->min_top_y = slice->min_bot_y;
+ else
+ slice->min_top_y = arc->height;
+ slice->min_bot_y = 0;
+ }
+ else if ((angle1 == 0) || (angle2 == HALFCIRCLE))
+ {
+ slice->min_top_y = slice->min_bot_y;
+ if (angle1 ? slice->edge1_top : slice->edge2_top)
+ slice->min_bot_y = arc->height;
+ else
+ slice->min_bot_y = 0;
+ }
+ else if (slice->edge1_top == slice->edge2_top)
+ {
+ if (angle2 < angle1)
+ {
+ slice->flip_top = slice->edge1_top;
+ slice->flip_bot = !slice->edge1_top;
+ }
+ else if (slice->edge1_top)
+ {
+ slice->min_top_y = 1;
+ slice->min_bot_y = arc->height;
+ }
+ else
+ {
+ slice->min_bot_y = 0;
+ slice->min_top_y = arc->height;
+ }
+ }
+ miGetPieEdge(arc, angle1, &slice->edge1,
+ slice->edge1_top, !slice->edge1_top);
+ miGetPieEdge(arc, angle2, &slice->edge2,
+ slice->edge2_top, slice->edge2_top);
+ }
+ else
+ {
+ double w2, h2, x1, y1, x2, y2, dx, dy, scale;
+ int signdx, signdy, y, k;
+ Bool isInt1 = TRUE, isInt2 = TRUE;
+
+ w2 = (double)arc->width / 2.0;
+ h2 = (double)arc->height / 2.0;
+ if ((angle1 == 0) || (angle1 == HALFCIRCLE))
+ {
+ x1 = angle1 ? -w2 : w2;
+ y1 = 0.0;
+ }
+ else if ((angle1 == QUADRANT) || (angle1 == QUADRANT3))
+ {
+ x1 = 0.0;
+ y1 = (angle1 == QUADRANT) ? h2 : -h2;
+ }
+ else
+ {
+ isInt1 = FALSE;
+ x1 = Dcos(angle1) * w2;
+ y1 = Dsin(angle1) * h2;
+ }
+ if ((angle2 == 0) || (angle2 == HALFCIRCLE))
+ {
+ x2 = angle2 ? -w2 : w2;
+ y2 = 0.0;
+ }
+ else if ((angle2 == QUADRANT) || (angle2 == QUADRANT3))
+ {
+ x2 = 0.0;
+ y2 = (angle2 == QUADRANT) ? h2 : -h2;
+ }
+ else
+ {
+ isInt2 = FALSE;
+ x2 = Dcos(angle2) * w2;
+ y2 = Dsin(angle2) * h2;
+ }
+ dx = x2 - x1;
+ dy = y2 - y1;
+ if (arc->height & 1)
+ {
+ y1 -= 0.5;
+ y2 -= 0.5;
+ }
+ if (arc->width & 1)
+ {
+ x1 += 0.5;
+ x2 += 0.5;
+ }
+ if (dy < 0.0)
+ {
+ dy = -dy;
+ signdy = -1;
+ }
+ else
+ signdy = 1;
+ if (dx < 0.0)
+ {
+ dx = -dx;
+ signdx = -1;
+ }
+ else
+ signdx = 1;
+ if (isInt1 && isInt2)
+ {
+ slice->edge1.dx = dx * 2;
+ slice->edge1.dy = dy * 2;
+ }
+ else
+ {
+ scale = (dx > dy) ? dx : dy;
+ slice->edge1.dx = floor((dx * 32768) / scale + .5);
+ slice->edge1.dy = floor((dy * 32768) / scale + .5);
+ }
+ if (!slice->edge1.dy)
+ {
+ if (signdx < 0)
+ {
+ y = floor(y1 + 1.0);
+ if (y >= 0)
+ {
+ slice->min_top_y = y;
+ slice->min_bot_y = arc->height;
+ }
+ else
+ {
+ slice->max_bot_y = -y - (arc->height & 1);
+ }
+ }
+ else
+ {
+ y = floor(y1);
+ if (y >= 0)
+ slice->max_top_y = y;
+ else
+ {
+ slice->min_top_y = arc->height;
+ slice->min_bot_y = -y - (arc->height & 1);
+ }
+ }
+ slice->edge1_top = TRUE;
+ slice->edge1.x = 65536;
+ slice->edge1.stepx = 0;
+ slice->edge1.e = 0;
+ slice->edge1.dx = -1;
+ slice->edge2 = slice->edge1;
+ slice->edge2_top = FALSE;
+ }
+ else if (!slice->edge1.dx)
+ {
+ if (signdy < 0)
+ x1 -= 1.0;
+ slice->edge1.x = ceil(x1);
+ slice->edge1_top = signdy < 0;
+ slice->edge1.x += arc->x + (arc->width >> 1);
+ slice->edge1.stepx = 0;
+ slice->edge1.e = 0;
+ slice->edge1.dx = -1;
+ slice->edge2_top = !slice->edge1_top;
+ slice->edge2 = slice->edge1;
+ }
+ else
+ {
+ if (signdx < 0)
+ slice->edge1.dx = -slice->edge1.dx;
+ if (signdy < 0)
+ slice->edge1.dx = -slice->edge1.dx;
+ k = ceil(((x1 + x2) * slice->edge1.dy - (y1 + y2) * slice->edge1.dx) / 2.0);
+ slice->edge2.dx = slice->edge1.dx;
+ slice->edge2.dy = slice->edge1.dy;
+ slice->edge1_top = signdy < 0;
+ slice->edge2_top = !slice->edge1_top;
+ miGetArcEdge(arc, &slice->edge1, k,
+ slice->edge1_top, !slice->edge1_top);
+ miGetArcEdge(arc, &slice->edge2, k,
+ slice->edge2_top, slice->edge2_top);
+ }
+ }
+}
+
+#define ADDSPANS() \
+ pts->x = xorg - x; \
+ pts->y = yorg - y; \
+ *wids = slw; \
+ pts++; \
+ wids++; \
+ if (miFillArcLower(slw)) \
+ { \
+ pts->x = xorg - x; \
+ pts->y = yorg + y + dy; \
+ pts++; \
+ *wids++ = slw; \
+ }
+
+static void
+miFillEllipseI(pDraw, pGC, arc)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ xArc *arc;
+{
+ register int x, y, e;
+ int yk, xk, ym, xm, dx, dy, xorg, yorg;
+ int slw;
+ miFillArcRec info;
+ DDXPointPtr points;
+ register DDXPointPtr pts;
+ int *widths;
+ register int *wids;
+
+ points = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * arc->height);
+ if (!points)
+ return;
+ widths = (int *)ALLOCATE_LOCAL(sizeof(int) * arc->height);
+ if (!widths)
+ {
+ DEALLOCATE_LOCAL(points);
+ return;
+ }
+ miFillArcSetup(arc, &info);
+ MIFILLARCSETUP();
+ if (pGC->miTranslate)
+ {
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ }
+ pts = points;
+ wids = widths;
+ while (y > 0)
+ {
+ MIFILLARCSTEP(slw);
+ ADDSPANS();
+ }
+ (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
+ DEALLOCATE_LOCAL(widths);
+ DEALLOCATE_LOCAL(points);
+}
+
+static void
+miFillEllipseD(pDraw, pGC, arc)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ xArc *arc;
+{
+ register int x, y;
+ int xorg, yorg, dx, dy, slw;
+ double e, yk, xk, ym, xm;
+ miFillArcDRec info;
+ DDXPointPtr points;
+ register DDXPointPtr pts;
+ int *widths;
+ register int *wids;
+
+ points = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * arc->height);
+ if (!points)
+ return;
+ widths = (int *)ALLOCATE_LOCAL(sizeof(int) * arc->height);
+ if (!widths)
+ {
+ DEALLOCATE_LOCAL(points);
+ return;
+ }
+ miFillArcDSetup(arc, &info);
+ MIFILLARCSETUP();
+ if (pGC->miTranslate)
+ {
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ }
+ pts = points;
+ wids = widths;
+ while (y > 0)
+ {
+ MIFILLARCSTEP(slw);
+ ADDSPANS();
+ }
+ (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
+ DEALLOCATE_LOCAL(widths);
+ DEALLOCATE_LOCAL(points);
+}
+
+#define ADDSPAN(l,r) \
+ if (r >= l) \
+ { \
+ pts->x = l; \
+ pts->y = ya; \
+ pts++; \
+ *wids++ = r - l + 1; \
+ }
+
+#define ADDSLICESPANS(flip) \
+ if (!flip) \
+ { \
+ ADDSPAN(xl, xr); \
+ } \
+ else \
+ { \
+ xc = xorg - x; \
+ ADDSPAN(xc, xr); \
+ xc += slw - 1; \
+ ADDSPAN(xl, xc); \
+ }
+
+static void
+miFillArcSliceI(pDraw, pGC, arc)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ xArc *arc;
+{
+ int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
+ register int x, y, e;
+ miFillArcRec info;
+ miArcSliceRec slice;
+ int ya, xl, xr, xc;
+ DDXPointPtr points;
+ register DDXPointPtr pts;
+ int *widths;
+ register int *wids;
+
+ miFillArcSetup(arc, &info);
+ miFillArcSliceSetup(arc, &slice, pGC);
+ MIFILLARCSETUP();
+ slw = arc->height;
+ if (slice.flip_top || slice.flip_bot)
+ slw += (arc->height >> 1) + 1;
+ points = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * slw);
+ if (!points)
+ return;
+ widths = (int *)ALLOCATE_LOCAL(sizeof(int) * slw);
+ if (!widths)
+ {
+ DEALLOCATE_LOCAL(points);
+ return;
+ }
+ if (pGC->miTranslate)
+ {
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ slice.edge1.x += pDraw->x;
+ slice.edge2.x += pDraw->x;
+ }
+ pts = points;
+ wids = widths;
+ while (y > 0)
+ {
+ MIFILLARCSTEP(slw);
+ MIARCSLICESTEP(slice.edge1);
+ MIARCSLICESTEP(slice.edge2);
+ if (miFillSliceUpper(slice))
+ {
+ ya = yorg - y;
+ MIARCSLICEUPPER(xl, xr, slice, slw);
+ ADDSLICESPANS(slice.flip_top);
+ }
+ if (miFillSliceLower(slice))
+ {
+ ya = yorg + y + dy;
+ MIARCSLICELOWER(xl, xr, slice, slw);
+ ADDSLICESPANS(slice.flip_bot);
+ }
+ }
+ (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
+ DEALLOCATE_LOCAL(widths);
+ DEALLOCATE_LOCAL(points);
+}
+
+static void
+miFillArcSliceD(pDraw, pGC, arc)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ xArc *arc;
+{
+ register int x, y;
+ int dx, dy, xorg, yorg, slw;
+ double e, yk, xk, ym, xm;
+ miFillArcDRec info;
+ miArcSliceRec slice;
+ int ya, xl, xr, xc;
+ DDXPointPtr points;
+ register DDXPointPtr pts;
+ int *widths;
+ register int *wids;
+
+ miFillArcDSetup(arc, &info);
+ miFillArcSliceSetup(arc, &slice, pGC);
+ MIFILLARCSETUP();
+ slw = arc->height;
+ if (slice.flip_top || slice.flip_bot)
+ slw += (arc->height >> 1) + 1;
+ points = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * slw);
+ if (!points)
+ return;
+ widths = (int *)ALLOCATE_LOCAL(sizeof(int) * slw);
+ if (!widths)
+ {
+ DEALLOCATE_LOCAL(points);
+ return;
+ }
+ if (pGC->miTranslate)
+ {
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ slice.edge1.x += pDraw->x;
+ slice.edge2.x += pDraw->x;
+ }
+ pts = points;
+ wids = widths;
+ while (y > 0)
+ {
+ MIFILLARCSTEP(slw);
+ MIARCSLICESTEP(slice.edge1);
+ MIARCSLICESTEP(slice.edge2);
+ if (miFillSliceUpper(slice))
+ {
+ ya = yorg - y;
+ MIARCSLICEUPPER(xl, xr, slice, slw);
+ ADDSLICESPANS(slice.flip_top);
+ }
+ if (miFillSliceLower(slice))
+ {
+ ya = yorg + y + dy;
+ MIARCSLICELOWER(xl, xr, slice, slw);
+ ADDSLICESPANS(slice.flip_bot);
+ }
+ }
+ (*pGC->ops->FillSpans)(pDraw, pGC, pts - points, points, widths, FALSE);
+ DEALLOCATE_LOCAL(widths);
+ DEALLOCATE_LOCAL(points);
+}
+
+/* MIPOLYFILLARC -- The public entry for the PolyFillArc request.
+ * Since we don't have to worry about overlapping segments, we can just
+ * fill each arc as it comes.
+ */
+void
+miPolyFillArc(pDraw, pGC, narcs, parcs)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ register int i;
+ register xArc *arc;
+
+ for(i = narcs, arc = parcs; --i >= 0; arc++)
+ {
+ if (miFillArcEmpty(arc))
+ continue;;
+ if ((arc->angle2 >= FULLCIRCLE) || (arc->angle2 <= -FULLCIRCLE))
+ {
+ if (miCanFillArc(arc))
+ miFillEllipseI(pDraw, pGC, arc);
+ else
+ miFillEllipseD(pDraw, pGC, arc);
+ }
+ else
+ {
+ if (miCanFillArc(arc))
+ miFillArcSliceI(pDraw, pGC, arc);
+ else
+ miFillArcSliceD(pDraw, pGC, arc);
+ }
+ }
+}
diff --git a/xc/programs/Xserver/mi/mifillarc.h b/xc/programs/Xserver/mi/mifillarc.h
new file mode 100644
index 000000000..b6e1120a2
--- /dev/null
+++ b/xc/programs/Xserver/mi/mifillarc.h
@@ -0,0 +1,220 @@
+/* $XFree86: xc/programs/Xserver/mi/mifillarc.h,v 3.3 1998/10/04 09:39:27 dawes Exp $ */
+/************************************************************
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+********************************************************/
+
+/* $TOG: mifillarc.h /main/11 1998/02/09 14:46:57 kaleb $ */
+
+#define FULLCIRCLE (360 * 64)
+
+typedef struct _miFillArc {
+ int xorg, yorg;
+ int y;
+ int dx, dy;
+ int e;
+ int ym, yk, xm, xk;
+} miFillArcRec;
+
+/* could use 64-bit integers */
+typedef struct _miFillArcD {
+ int xorg, yorg;
+ int y;
+ int dx, dy;
+ double e;
+ double ym, yk, xm, xk;
+} miFillArcDRec;
+
+#define miFillArcEmpty(arc) (!(arc)->angle2 || \
+ !(arc)->width || !(arc)->height || \
+ (((arc)->width == 1) && ((arc)->height & 1)))
+
+#define miCanFillArc(arc) (((arc)->width == (arc)->height) || \
+ (((arc)->width <= 800) && ((arc)->height <= 800)))
+
+#define MIFILLARCSETUP() \
+ x = 0; \
+ y = info.y; \
+ e = info.e; \
+ xk = info.xk; \
+ xm = info.xm; \
+ yk = info.yk; \
+ ym = info.ym; \
+ dx = info.dx; \
+ dy = info.dy; \
+ xorg = info.xorg; \
+ yorg = info.yorg
+
+#define MIFILLARCSTEP(slw) \
+ e += yk; \
+ while (e >= 0) \
+ { \
+ x++; \
+ xk -= xm; \
+ e += xk; \
+ } \
+ y--; \
+ yk -= ym; \
+ slw = (x << 1) + dx; \
+ if ((e == xk) && (slw > 1)) \
+ slw--
+
+#define MIFILLCIRCSTEP(slw) MIFILLARCSTEP(slw)
+#define MIFILLELLSTEP(slw) MIFILLARCSTEP(slw)
+
+#define miFillArcLower(slw) (((y + dy) != 0) && ((slw > 1) || (e != xk)))
+
+typedef struct _miSliceEdge {
+ int x;
+ int stepx;
+ int deltax;
+ int e;
+ int dy;
+ int dx;
+} miSliceEdgeRec, *miSliceEdgePtr;
+
+typedef struct _miArcSlice {
+ miSliceEdgeRec edge1, edge2;
+ int min_top_y, max_top_y;
+ int min_bot_y, max_bot_y;
+ Bool edge1_top, edge2_top;
+ Bool flip_top, flip_bot;
+} miArcSliceRec;
+
+#define MIARCSLICESTEP(edge) \
+ edge.x -= edge.stepx; \
+ edge.e -= edge.dx; \
+ if (edge.e <= 0) \
+ { \
+ edge.x -= edge.deltax; \
+ edge.e += edge.dy; \
+ }
+
+#define miFillSliceUpper(slice) \
+ ((y >= slice.min_top_y) && (y <= slice.max_top_y))
+
+#define miFillSliceLower(slice) \
+ ((y >= slice.min_bot_y) && (y <= slice.max_bot_y))
+
+#define MIARCSLICEUPPER(xl,xr,slice,slw) \
+ xl = xorg - x; \
+ xr = xl + slw - 1; \
+ if (slice.edge1_top && (slice.edge1.x < xr)) \
+ xr = slice.edge1.x; \
+ if (slice.edge2_top && (slice.edge2.x > xl)) \
+ xl = slice.edge2.x;
+
+#define MIARCSLICELOWER(xl,xr,slice,slw) \
+ xl = xorg - x; \
+ xr = xl + slw - 1; \
+ if (!slice.edge1_top && (slice.edge1.x > xl)) \
+ xl = slice.edge1.x; \
+ if (!slice.edge2_top && (slice.edge2.x < xr)) \
+ xr = slice.edge2.x;
+
+#define MIWIDEARCSETUP(x,y,dy,slw,e,xk,xm,yk,ym) \
+ x = 0; \
+ y = slw >> 1; \
+ yk = y << 3; \
+ xm = 8; \
+ ym = 8; \
+ if (dy) \
+ { \
+ xk = 0; \
+ if (slw & 1) \
+ e = -1; \
+ else \
+ e = -(y << 2) - 2; \
+ } \
+ else \
+ { \
+ y++; \
+ yk += 4; \
+ xk = -4; \
+ if (slw & 1) \
+ e = -(y << 2) - 3; \
+ else \
+ e = - (y << 3); \
+ }
+
+#define MIFILLINARCSTEP(slw) \
+ ine += inyk; \
+ while (ine >= 0) \
+ { \
+ inx++; \
+ inxk -= inxm; \
+ ine += inxk; \
+ } \
+ iny--; \
+ inyk -= inym; \
+ slw = (inx << 1) + dx; \
+ if ((ine == inxk) && (slw > 1)) \
+ slw--
+
+#define miFillInArcLower(slw) (((iny + dy) != 0) && \
+ ((slw > 1) || (ine != inxk)))
+
+extern int miFreeArcCache(
+#if NeedFunctionPrototypes
+ pointer /*data*/,
+ XID /*id*/
+#endif
+);
+
+extern struct finalSpan *realAllocSpan(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void miFillArcSetup(
+#if NeedFunctionPrototypes
+ xArc * /*arc*/,
+ miFillArcRec * /*info*/
+#endif
+);
+
+extern void miFillArcDSetup(
+#if NeedFunctionPrototypes
+ xArc * /*arc*/,
+ miFillArcDRec * /*info*/
+#endif
+);
+
+extern void miEllipseAngleToSlope(
+#if NeedFunctionPrototypes
+ int /*angle*/,
+ int /*width*/,
+ int /*height*/,
+ int * /*dxp*/,
+ int * /*dyp*/,
+ double * /*d_dxp*/,
+ double * /*d_dyp*/
+#endif
+);
+
+extern void miFillArcSliceSetup(
+#if NeedFunctionPrototypes
+ xArc * /*arc*/,
+ miArcSliceRec * /*slice*/,
+ GCPtr /*pGC*/
+#endif
+);
+
diff --git a/xc/programs/Xserver/mi/mifillrct.c b/xc/programs/Xserver/mi/mifillrct.c
new file mode 100644
index 000000000..c26bc9202
--- /dev/null
+++ b/xc/programs/Xserver/mi/mifillrct.c
@@ -0,0 +1,135 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mifillrct.c /main/6 1998/02/09 14:47:01 kaleb $ */
+
+#include "X.h"
+#include "Xprotostr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmap.h"
+
+#include "misc.h"
+
+/* mi rectangles
+ written by newman, with debts to all and sundry
+*/
+
+/* MIPOLYFILLRECT -- public entry for PolyFillRect request
+ * very straight forward: translate rectangles if necessary
+ * then call FillSpans to fill each rectangle. We let FillSpans worry about
+ * clipping to the destination
+ */
+void
+miPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nrectFill; /* number of rectangles to fill */
+ xRectangle *prectInit; /* Pointer to first rectangle to fill */
+{
+ int i;
+ register int height;
+ register int width;
+ register xRectangle *prect;
+ int xorg;
+ register int yorg;
+ int maxheight;
+ DDXPointPtr pptFirst;
+ register DDXPointPtr ppt;
+ int *pwFirst;
+ register int *pw;
+
+ if (pGC->miTranslate)
+ {
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+ prect = prectInit;
+ maxheight = 0;
+ for (i = 0; i<nrectFill; i++, prect++)
+ {
+ prect->x += xorg;
+ prect->y += yorg;
+ maxheight = max(maxheight, prect->height);
+ }
+ }
+ else
+ {
+ prect = prectInit;
+ maxheight = 0;
+ for (i = 0; i<nrectFill; i++, prect++)
+ maxheight = max(maxheight, prect->height);
+ }
+
+ pptFirst = (DDXPointPtr) ALLOCATE_LOCAL(maxheight * sizeof(DDXPointRec));
+ pwFirst = (int *) ALLOCATE_LOCAL(maxheight * sizeof(int));
+ if(!pptFirst || !pwFirst)
+ {
+ if (pwFirst) DEALLOCATE_LOCAL(pwFirst);
+ if (pptFirst) DEALLOCATE_LOCAL(pptFirst);
+ return;
+ }
+
+ prect = prectInit;
+ while(nrectFill--)
+ {
+ ppt = pptFirst;
+ pw = pwFirst;
+ height = prect->height;
+ width = prect->width;
+ xorg = prect->x;
+ yorg = prect->y;
+ while(height--)
+ {
+ *pw++ = width;
+ ppt->x = xorg;
+ ppt->y = yorg;
+ ppt++;
+ yorg++;
+ }
+ (* pGC->ops->FillSpans)(pDrawable, pGC,
+ prect->height, pptFirst, pwFirst,
+ 1);
+ prect++;
+ }
+ DEALLOCATE_LOCAL(pwFirst);
+ DEALLOCATE_LOCAL(pptFirst);
+}
diff --git a/xc/programs/Xserver/mi/mifpoly.h b/xc/programs/Xserver/mi/mifpoly.h
new file mode 100644
index 000000000..2077e91ba
--- /dev/null
+++ b/xc/programs/Xserver/mi/mifpoly.h
@@ -0,0 +1,104 @@
+/* $TOG: mifpoly.h /main/10 1998/02/09 14:47:09 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#define EPSILON 0.000001
+#define ISEQUAL(a,b) (Fabs((a) - (b)) <= EPSILON)
+#define UNEQUAL(a,b) (Fabs((a) - (b)) > EPSILON)
+#define WITHINHALF(a, b) (((a) - (b) > 0.0) ? (a) - (b) < 0.5 : \
+ (b) - (a) <= 0.5)
+#define ROUNDTOINT(x) ((int) (((x) > 0.0) ? ((x) + 0.5) : ((x) - 0.5)))
+#define ISZERO(x) (Fabs((x)) <= EPSILON)
+#define PTISEQUAL(a,b) (ISEQUAL(a.x,b.x) && ISEQUAL(a.y,b.y))
+#define PTUNEQUAL(a,b) (UNEQUAL(a.x,b.x) || UNEQUAL(a.y,b.y))
+#define PtEqual(a, b) (((a).x == (b).x) && ((a).y == (b).y))
+
+#define NotEnd 0
+#define FirstEnd 1
+#define SecondEnd 2
+
+#define SQSECANT 108.856472512142 /* 1/sin^2(11/2) - for 11o miter cutoff */
+#define D2SECANT 5.21671526231167 /* 1/2*sin(11/2) - max extension per width */
+
+#ifdef NOINLINEICEIL
+#define ICEIL(x) ((int)ceil(x))
+#else
+#ifdef __GNUC__
+static __inline int ICEIL(x)
+ double x;
+{
+ int _cTmp = x;
+ return ((x == _cTmp) || (x < 0.0)) ? _cTmp : _cTmp+1;
+}
+#else
+#define ICEIL(x) ((((x) == (_cTmp = (x))) || ((x) < 0.0)) ? _cTmp : _cTmp+1)
+#define ICEILTEMPDECL static int _cTmp;
+#endif
+#endif
+
+/* Point with sub-pixel positioning. In this case we use doubles, but
+ * see mifpolycon.c for other suggestions
+ */
+typedef struct _SppPoint {
+ double x, y;
+} SppPointRec, *SppPointPtr;
+
+typedef struct _SppArc {
+ double x, y, width, height;
+ double angle1, angle2;
+} SppArcRec, *SppArcPtr;
+
+/* mifpolycon.c */
+
+extern void miFillSppPoly(
+#if NeedFunctionPrototypes
+ DrawablePtr /*dst*/,
+ GCPtr /*pgc*/,
+ int /*count*/,
+ SppPointPtr /*ptsIn*/,
+ int /*xTrans*/,
+ int /*yTrans*/,
+ double /*xFtrans*/,
+ double /*yFtrans*/
+#endif
+);
diff --git a/xc/programs/Xserver/mi/mifpolycon.c b/xc/programs/Xserver/mi/mifpolycon.c
new file mode 100644
index 000000000..dfa08ecd8
--- /dev/null
+++ b/xc/programs/Xserver/mi/mifpolycon.c
@@ -0,0 +1,273 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mifpolycon.c /main/13 1998/02/09 14:47:05 kaleb $ */
+#include <math.h>
+#include "X.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "mifpoly.h"
+
+static int GetFPolyYBounds();
+
+#ifdef ICEILTEMPDECL
+ICEILTEMPDECL
+#endif
+
+/*
+ * Written by Todd Newman; April. 1987.
+ *
+ * Fill a convex polygon. If the given polygon
+ * is not convex, then the result is undefined.
+ * The algorithm is to order the edges from smallest
+ * y to largest by partitioning the array into a left
+ * edge list and a right edge list. The algorithm used
+ * to traverse each edge is digital differencing analyzer
+ * line algorithm with y as the major axis. There's some funny linear
+ * interpolation involved because of the subpixel postioning.
+ */
+void
+miFillSppPoly(dst, pgc, count, ptsIn, xTrans, yTrans, xFtrans, yFtrans)
+ DrawablePtr dst;
+ GCPtr pgc;
+ int count; /* number of points */
+ SppPointPtr ptsIn; /* the points */
+ int xTrans, yTrans; /* Translate each point by this */
+ double xFtrans, yFtrans; /* translate before conversion
+ by this amount. This provides
+ a mechanism to match rounding
+ errors with any shape that must
+ meet the polygon exactly.
+ */
+{
+ double xl, xr, /* x vals of left and right edges */
+ ml, /* left edge slope */
+ mr, /* right edge slope */
+ dy, /* delta y */
+ i; /* loop counter */
+ int y, /* current scanline */
+ j,
+ imin, /* index of vertex with smallest y */
+ ymin, /* y-extents of polygon */
+ ymax,
+ *width,
+ *FirstWidth, /* output buffer */
+ *Marked; /* set if this vertex has been used */
+ register int left, right, /* indices to first endpoints */
+ nextleft,
+ nextright; /* indices to second endpoints */
+ DDXPointPtr ptsOut,
+ FirstPoint; /* output buffer */
+
+ if (pgc->miTranslate)
+ {
+ xTrans += dst->x;
+ yTrans += dst->y;
+ }
+
+ imin = GetFPolyYBounds(ptsIn, count, yFtrans, &ymin, &ymax);
+
+ y = ymax - ymin + 1;
+ if ((count < 3) || (y <= 0))
+ return;
+ ptsOut = FirstPoint = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * y);
+ width = FirstWidth = (int *) ALLOCATE_LOCAL(sizeof(int) * y);
+ Marked = (int *) ALLOCATE_LOCAL(sizeof(int) * count);
+
+ if(!ptsOut || !width || !Marked)
+ {
+ if (Marked) DEALLOCATE_LOCAL(Marked);
+ if (width) DEALLOCATE_LOCAL(width);
+ if (ptsOut) DEALLOCATE_LOCAL(ptsOut);
+ return;
+ }
+
+ for(j = 0; j < count; j++)
+ Marked[j] = 0;
+ nextleft = nextright = imin;
+ Marked[imin] = -1;
+ y = ICEIL(ptsIn[nextleft].y + yFtrans);
+
+ /*
+ * loop through all edges of the polygon
+ */
+ do
+ {
+ /* add a left edge if we need to */
+ if ((y > (ptsIn[nextleft].y + yFtrans) ||
+ ISEQUAL(y, ptsIn[nextleft].y + yFtrans)) &&
+ Marked[nextleft] != 1)
+ {
+ Marked[nextleft]++;
+ left = nextleft++;
+
+ /* find the next edge, considering the end conditions */
+ if (nextleft >= count)
+ nextleft = 0;
+
+ /* now compute the starting point and slope */
+ dy = ptsIn[nextleft].y - ptsIn[left].y;
+ if (dy != 0.0)
+ {
+ ml = (ptsIn[nextleft].x - ptsIn[left].x) / dy;
+ dy = y - (ptsIn[left].y + yFtrans);
+ xl = (ptsIn[left].x + xFtrans) + ml * max(dy, 0);
+ }
+ }
+
+ /* add a right edge if we need to */
+ if ((y > ptsIn[nextright].y + yFtrans) ||
+ ISEQUAL(y, ptsIn[nextright].y + yFtrans)
+ && Marked[nextright] != 1)
+ {
+ Marked[nextright]++;
+ right = nextright--;
+
+ /* find the next edge, considering the end conditions */
+ if (nextright < 0)
+ nextright = count - 1;
+
+ /* now compute the starting point and slope */
+ dy = ptsIn[nextright].y - ptsIn[right].y;
+ if (dy != 0.0)
+ {
+ mr = (ptsIn[nextright].x - ptsIn[right].x) / dy;
+ dy = y - (ptsIn[right].y + yFtrans);
+ xr = (ptsIn[right].x + xFtrans) + mr * max(dy, 0);
+ }
+ }
+
+
+ /*
+ * generate scans to fill while we still have
+ * a right edge as well as a left edge.
+ */
+ i = (min(ptsIn[nextleft].y, ptsIn[nextright].y) + yFtrans) - y;
+
+ if (i < EPSILON)
+ {
+ if(Marked[nextleft] && Marked[nextright])
+ {
+ /* Arrgh, we're trapped! (no more points)
+ * Out, we've got to get out of here before this decadence saps
+ * our will completely! */
+ break;
+ }
+ continue;
+ }
+ else
+ {
+ j = (int) i;
+ if(!j)
+ j++;
+ }
+ while (j > 0)
+ {
+ int cxl, cxr;
+
+ ptsOut->y = (y) + yTrans;
+
+ cxl = ICEIL(xl);
+ cxr = ICEIL(xr);
+ /* reverse the edges if necessary */
+ if (xl < xr)
+ {
+ *(width++) = cxr - cxl;
+ (ptsOut++)->x = cxl + xTrans;
+ }
+ else
+ {
+ *(width++) = cxl - cxr;
+ (ptsOut++)->x = cxr + xTrans;
+ }
+ y++;
+
+ /* increment down the edges */
+ xl += ml;
+ xr += mr;
+ j--;
+ }
+ } while (y <= ymax);
+
+ /* Finally, fill the spans we've collected */
+ (*pgc->ops->FillSpans)(dst, pgc,
+ ptsOut-FirstPoint, FirstPoint, FirstWidth, 1);
+ DEALLOCATE_LOCAL(Marked);
+ DEALLOCATE_LOCAL(FirstWidth);
+ DEALLOCATE_LOCAL(FirstPoint);
+}
+
+
+/* Find the index of the point with the smallest y.also return the
+ * smallest and largest y */
+static
+int
+GetFPolyYBounds(pts, n, yFtrans, by, ty)
+ register SppPointPtr pts;
+ int n;
+ double yFtrans;
+ int *by, *ty;
+{
+ register SppPointPtr ptMin;
+ double ymin, ymax;
+ SppPointPtr ptsStart = pts;
+
+ ptMin = pts;
+ ymin = ymax = (pts++)->y;
+
+ while (--n > 0) {
+ if (pts->y < ymin)
+ {
+ ptMin = pts;
+ ymin = pts->y;
+ }
+ if(pts->y > ymax)
+ ymax = pts->y;
+
+ pts++;
+ }
+
+ *by = ICEIL(ymin + yFtrans);
+ *ty = ICEIL(ymax + yFtrans - 1);
+ return(ptMin-ptsStart);
+}
diff --git a/xc/programs/Xserver/mi/migc.c b/xc/programs/Xserver/mi/migc.c
new file mode 100644
index 000000000..fdf24dd96
--- /dev/null
+++ b/xc/programs/Xserver/mi/migc.c
@@ -0,0 +1,291 @@
+/* $TOG: migc.c /main/6 1998/02/09 14:47:13 kaleb $ */
+/*
+
+Copyright 1993, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+
+/* $XFree86: xc/programs/Xserver/mi/migc.c,v 1.6 1998/12/06 06:08:47 dawes Exp $ */
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "migc.h"
+
+/* ARGSUSED */
+void
+miChangeGC(pGC, mask)
+ GCPtr pGC;
+ unsigned long mask;
+{
+ return;
+}
+
+void
+miDestroyGC(pGC)
+ GCPtr pGC;
+{
+ if (pGC->pRotatedPixmap)
+ (*pGC->pScreen->DestroyPixmap) (pGC->pRotatedPixmap);
+ if (pGC->freeCompClip)
+ REGION_DESTROY(pGC->pScreen, pGC->pCompositeClip);
+ miDestroyGCOps(pGC->ops);
+}
+
+/*
+ * create a private op array for a gc
+ */
+
+GCOpsPtr
+miCreateGCOps(prototype)
+ GCOpsPtr prototype;
+{
+ GCOpsPtr ret;
+ extern Bool Must_have_memory;
+
+ /* XXX */ Must_have_memory = TRUE;
+ ret = (GCOpsPtr) xalloc(sizeof(GCOps));
+ /* XXX */ Must_have_memory = FALSE;
+ if (!ret)
+ return 0;
+ *ret = *prototype;
+ ret->devPrivate.val = 1;
+ return ret;
+}
+
+void
+miDestroyGCOps(ops)
+ GCOpsPtr ops;
+{
+ if (ops->devPrivate.val)
+ xfree(ops);
+}
+
+
+void
+miDestroyClip(pGC)
+ GCPtr pGC;
+{
+ if (pGC->clientClipType == CT_NONE)
+ return;
+ else if (pGC->clientClipType == CT_PIXMAP)
+ {
+ (*pGC->pScreen->DestroyPixmap) ((PixmapPtr) (pGC->clientClip));
+ }
+ else
+ {
+ /*
+ * we know we'll never have a list of rectangles, since ChangeClip
+ * immediately turns them into a region
+ */
+ REGION_DESTROY(pGC->pScreen, pGC->clientClip);
+ }
+ pGC->clientClip = NULL;
+ pGC->clientClipType = CT_NONE;
+}
+
+void
+miChangeClip(pGC, type, pvalue, nrects)
+ GCPtr pGC;
+ int type;
+ pointer pvalue;
+ int nrects;
+{
+ (*pGC->funcs->DestroyClip) (pGC);
+ if (type == CT_PIXMAP)
+ {
+ /* convert the pixmap to a region */
+ pGC->clientClip = (pointer) BITMAP_TO_REGION(pGC->pScreen,
+ (PixmapPtr) pvalue);
+ (*pGC->pScreen->DestroyPixmap) (pvalue);
+ }
+ else if (type == CT_REGION)
+ {
+ /* stuff the region in the GC */
+ pGC->clientClip = pvalue;
+ }
+ else if (type != CT_NONE)
+ {
+ pGC->clientClip = (pointer) RECTS_TO_REGION(pGC->pScreen, nrects,
+ (xRectangle *) pvalue,
+ type);
+ xfree(pvalue);
+ }
+ pGC->clientClipType = (type != CT_NONE && pGC->clientClip) ? CT_REGION : CT_NONE;
+ pGC->stateChanges |= GCClipMask;
+}
+
+void
+miCopyClip(pgcDst, pgcSrc)
+ GCPtr pgcDst, pgcSrc;
+{
+ RegionPtr prgnNew;
+
+ switch (pgcSrc->clientClipType)
+ {
+ case CT_PIXMAP:
+ ((PixmapPtr) pgcSrc->clientClip)->refcnt++;
+ /* Fall through !! */
+ case CT_NONE:
+ (*pgcDst->funcs->ChangeClip) (pgcDst, (int) pgcSrc->clientClipType,
+ pgcSrc->clientClip, 0);
+ break;
+ case CT_REGION:
+ prgnNew = REGION_CREATE(pgcSrc->pScreen, NULL, 1);
+ REGION_COPY(pgcDst->pScreen, prgnNew,
+ (RegionPtr) (pgcSrc->clientClip));
+ (*pgcDst->funcs->ChangeClip) (pgcDst, CT_REGION, (pointer) prgnNew, 0);
+ break;
+ }
+}
+
+/* ARGSUSED */
+void
+miCopyGC(pGCSrc, changes, pGCDst)
+ GCPtr pGCSrc;
+ unsigned long changes;
+ GCPtr pGCDst;
+{
+ return;
+}
+
+void
+miComputeCompositeClip(pGC, pDrawable)
+ GCPtr pGC;
+ DrawablePtr pDrawable;
+{
+ ScreenPtr pScreen = pGC->pScreen;
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWin = (WindowPtr) pDrawable;
+ RegionPtr pregWin;
+ Bool freeTmpClip, freeCompClip;
+
+ if (pGC->subWindowMode == IncludeInferiors)
+ {
+ pregWin = NotClippedByChildren(pWin);
+ freeTmpClip = TRUE;
+ }
+ else
+ {
+ pregWin = &pWin->clipList;
+ freeTmpClip = FALSE;
+ }
+ freeCompClip = pGC->freeCompClip;
+
+ /*
+ * if there is no client clip, we can get by with just keeping the
+ * pointer we got, and remembering whether or not should destroy (or
+ * maybe re-use) it later. this way, we avoid unnecessary copying of
+ * regions. (this wins especially if many clients clip by children
+ * and have no client clip.)
+ */
+ if (pGC->clientClipType == CT_NONE)
+ {
+ if (freeCompClip)
+ REGION_DESTROY(pScreen, pGC->pCompositeClip);
+ pGC->pCompositeClip = pregWin;
+ pGC->freeCompClip = freeTmpClip;
+ }
+ else
+ {
+ /*
+ * we need one 'real' region to put into the composite clip. if
+ * pregWin the current composite clip are real, we can get rid of
+ * one. if pregWin is real and the current composite clip isn't,
+ * use pregWin for the composite clip. if the current composite
+ * clip is real and pregWin isn't, use the current composite
+ * clip. if neither is real, create a new region.
+ */
+
+ REGION_TRANSLATE(pScreen, pGC->clientClip,
+ pDrawable->x + pGC->clipOrg.x,
+ pDrawable->y + pGC->clipOrg.y);
+
+ if (freeCompClip)
+ {
+ REGION_INTERSECT(pGC->pScreen, pGC->pCompositeClip,
+ pregWin, pGC->clientClip);
+ if (freeTmpClip)
+ REGION_DESTROY(pScreen, pregWin);
+ }
+ else if (freeTmpClip)
+ {
+ REGION_INTERSECT(pScreen, pregWin, pregWin, pGC->clientClip);
+ pGC->pCompositeClip = pregWin;
+ }
+ else
+ {
+ pGC->pCompositeClip = REGION_CREATE(pScreen, NullBox, 0);
+ REGION_INTERSECT(pScreen, pGC->pCompositeClip,
+ pregWin, pGC->clientClip);
+ }
+ pGC->freeCompClip = TRUE;
+ REGION_TRANSLATE(pScreen, pGC->clientClip,
+ -(pDrawable->x + pGC->clipOrg.x),
+ -(pDrawable->y + pGC->clipOrg.y));
+ }
+ } /* end of composite clip for a window */
+ else
+ {
+ BoxRec pixbounds;
+
+ /* XXX should we translate by drawable.x/y here ? */
+ /* If you want pixmaps in offscreen memory, yes */
+ pixbounds.x1 = pDrawable->x;
+ pixbounds.y1 = pDrawable->y;
+ pixbounds.x2 = pDrawable->x + pDrawable->width;
+ pixbounds.y2 = pDrawable->y + pDrawable->height;
+
+ if (pGC->freeCompClip)
+ {
+ REGION_RESET(pScreen, pGC->pCompositeClip, &pixbounds);
+ }
+ else
+ {
+ pGC->freeCompClip = TRUE;
+ pGC->pCompositeClip = REGION_CREATE(pScreen, &pixbounds, 1);
+ }
+
+ if (pGC->clientClipType == CT_REGION)
+ {
+ if(pDrawable->x || pDrawable->y) {
+ REGION_TRANSLATE(pScreen, pGC->clientClip,
+ pDrawable->x + pGC->clipOrg.x,
+ pDrawable->y + pGC->clipOrg.y);
+ REGION_INTERSECT(pScreen, pGC->pCompositeClip,
+ pGC->pCompositeClip, pGC->clientClip);
+ REGION_TRANSLATE(pScreen, pGC->clientClip,
+ -(pDrawable->x + pGC->clipOrg.x),
+ -(pDrawable->y + pGC->clipOrg.y));
+ } else {
+ REGION_TRANSLATE(pScreen, pGC->pCompositeClip,
+ -pGC->clipOrg.x, -pGC->clipOrg.y);
+ REGION_INTERSECT(pScreen, pGC->pCompositeClip,
+ pGC->pCompositeClip, pGC->clientClip);
+ REGION_TRANSLATE(pScreen, pGC->pCompositeClip,
+ pGC->clipOrg.x, pGC->clipOrg.y);
+ }
+ }
+ } /* end of composite clip for pixmap */
+} /* end miComputeCompositeClip */
diff --git a/xc/programs/Xserver/mi/migc.h b/xc/programs/Xserver/mi/migc.h
new file mode 100644
index 000000000..ce69aa67b
--- /dev/null
+++ b/xc/programs/Xserver/mi/migc.h
@@ -0,0 +1,88 @@
+/* $TOG: migc.h /main/5 1998/02/09 14:47:18 kaleb $ */
+/*
+
+Copyright 1993, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+
+/* $XFree86: xc/programs/Xserver/mi/migc.h,v 1.5 1998/10/04 09:39:28 dawes Exp $ */
+
+extern void miChangeGC(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/,
+ unsigned long /*mask*/
+#endif
+);
+
+extern void miDestroyGC(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/
+#endif
+);
+
+extern GCOpsPtr miCreateGCOps(
+#if NeedFunctionPrototypes
+ GCOpsPtr /*prototype*/
+#endif
+);
+
+extern void miDestroyGCOps(
+#if NeedFunctionPrototypes
+ GCOpsPtr /*ops*/
+#endif
+);
+
+extern void miDestroyClip(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/
+#endif
+);
+
+extern void miChangeClip(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/,
+ int /*type*/,
+ pointer /*pvalue*/,
+ int /*nrects*/
+#endif
+);
+
+extern void miCopyClip(
+#if NeedFunctionPrototypes
+ GCPtr /*pgcDst*/,
+ GCPtr /*pgcSrc*/
+#endif
+);
+
+extern void miCopyGC(
+#if NeedFunctionPrototypes
+ GCPtr /*pGCSrc*/,
+ unsigned long /*changes*/,
+ GCPtr /*pGCDst*/
+#endif
+);
+
+extern void miComputeCompositeClip(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/,
+ DrawablePtr /*pDrawable*/
+#endif
+);
diff --git a/xc/programs/Xserver/mi/miglblt.c b/xc/programs/Xserver/mi/miglblt.c
new file mode 100644
index 000000000..f4e39fafd
--- /dev/null
+++ b/xc/programs/Xserver/mi/miglblt.c
@@ -0,0 +1,246 @@
+/* $XFree86: xc/programs/Xserver/mi/miglblt.c,v 1.3 1998/10/04 09:39:29 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* $TOG: miglblt.c /main/19 1998/02/09 14:47:22 kaleb $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmap.h"
+#include "servermd.h"
+
+/*
+ machine-independent glyph blt.
+ assumes that glyph bits in snf are written in bytes,
+have same bit order as the server's bitmap format,
+and are byte padded. this corresponds to the snf distributed
+with the sample server.
+
+ get a scratch GC.
+ in the scratch GC set alu = GXcopy, fg = 1, bg = 0
+ allocate a bitmap big enough to hold the largest glyph in the font
+ validate the scratch gc with the bitmap
+ for each glyph
+ carefully put the bits of the glyph in a buffer,
+ padded to the server pixmap scanline padding rules
+ fake a call to PutImage from the buffer into the bitmap
+ use the bitmap in a call to PushPixels
+*/
+
+void
+miPolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ unsigned char *pglyphBase; /* start of array of glyphs */
+{
+ int width, height;
+ PixmapPtr pPixmap;
+ int nbyLine; /* bytes per line of padded pixmap */
+ FontPtr pfont;
+ GCPtr pGCtmp;
+ register int i;
+ register int j;
+ unsigned char *pbits; /* buffer for PutImage */
+ register unsigned char *pb; /* temp pointer into buffer */
+ register CharInfoPtr pci; /* currect char info */
+ register unsigned char *pglyph; /* pointer bits in glyph */
+ int gWidth, gHeight; /* width and height of glyph */
+ register int nbyGlyphWidth; /* bytes per scanline of glyph */
+ int nbyPadGlyph; /* server padded line of glyph */
+
+ XID gcvals[3];
+
+ if (pGC->miTranslate)
+ {
+ x += pDrawable->x;
+ y += pDrawable->y;
+ }
+
+ pfont = pGC->font;
+ width = FONTMAXBOUNDS(pfont,rightSideBearing) -
+ FONTMINBOUNDS(pfont,leftSideBearing);
+ height = FONTMAXBOUNDS(pfont,ascent) +
+ FONTMAXBOUNDS(pfont,descent);
+
+ pPixmap = (*pDrawable->pScreen->CreatePixmap)(pDrawable->pScreen,
+ width, height, 1);
+ if (!pPixmap)
+ return;
+
+ pGCtmp = GetScratchGC(1, pDrawable->pScreen);
+ if (!pGCtmp)
+ {
+ (*pDrawable->pScreen->DestroyPixmap)(pPixmap);
+ return;
+ }
+
+ gcvals[0] = GXcopy;
+ gcvals[1] = 1;
+ gcvals[2] = 0;
+
+ DoChangeGC(pGCtmp, GCFunction|GCForeground|GCBackground, gcvals, 0);
+
+ nbyLine = BitmapBytePad(width);
+ pbits = (unsigned char *)ALLOCATE_LOCAL(height*nbyLine);
+ if (!pbits)
+ {
+ (*pDrawable->pScreen->DestroyPixmap)(pPixmap);
+ FreeScratchGC(pGCtmp);
+ return;
+ }
+ while(nglyph--)
+ {
+ pci = *ppci++;
+ pglyph = FONTGLYPHBITS(pglyphBase, pci);
+ gWidth = GLYPHWIDTHPIXELS(pci);
+ gHeight = GLYPHHEIGHTPIXELS(pci);
+ if (gWidth && gHeight)
+ {
+ nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci);
+ nbyPadGlyph = BitmapBytePad(gWidth);
+
+ if (nbyGlyphWidth == nbyPadGlyph
+#if GLYPHPADBYTES != 4
+ && (((int) pglyph) & 3) == 0
+#endif
+ )
+ {
+ pb = pglyph;
+ }
+ else
+ {
+ for (i=0, pb = pbits; i<gHeight; i++, pb = pbits+(i*nbyPadGlyph))
+ for (j = 0; j < nbyGlyphWidth; j++)
+ *pb++ = *pglyph++;
+ pb = pbits;
+ }
+
+ if ((pGCtmp->serialNumber) != (pPixmap->drawable.serialNumber))
+ ValidateGC((DrawablePtr)pPixmap, pGCtmp);
+ (*pGCtmp->ops->PutImage)((DrawablePtr)pPixmap, pGCtmp,
+ pPixmap->drawable.depth,
+ 0, 0, gWidth, gHeight,
+ 0, XYBitmap, (char *)pb);
+
+ if ((pGC->serialNumber) != (pDrawable->serialNumber))
+ ValidateGC(pDrawable, pGC);
+ (*pGC->ops->PushPixels)(pGC, pPixmap, pDrawable,
+ gWidth, gHeight,
+ x + pci->metrics.leftSideBearing,
+ y - pci->metrics.ascent);
+ }
+ x += pci->metrics.characterWidth;
+ }
+ (*pDrawable->pScreen->DestroyPixmap)(pPixmap);
+ DEALLOCATE_LOCAL(pbits);
+ FreeScratchGC(pGCtmp);
+}
+
+
+void
+miImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GC *pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ unsigned char *pglyphBase; /* start of array of glyphs */
+{
+ ExtentInfoRec info; /* used by QueryGlyphExtents() */
+ XID gcvals[3];
+ int oldAlu, oldFS;
+ unsigned long oldFG;
+ xRectangle backrect;
+
+ QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info);
+
+ if (info.overallWidth >= 0)
+ {
+ backrect.x = x;
+ backrect.width = info.overallWidth;
+ }
+ else
+ {
+ backrect.x = x + info.overallWidth;
+ backrect.width = -info.overallWidth;
+ }
+ backrect.y = y - FONTASCENT(pGC->font);
+ backrect.height = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+
+ oldAlu = pGC->alu;
+ oldFG = pGC->fgPixel;
+ oldFS = pGC->fillStyle;
+
+ /* fill in the background */
+ gcvals[0] = GXcopy;
+ gcvals[1] = pGC->bgPixel;
+ gcvals[2] = FillSolid;
+ DoChangeGC(pGC, GCFunction|GCForeground|GCFillStyle, gcvals, 0);
+ ValidateGC(pDrawable, pGC);
+ (*pGC->ops->PolyFillRect)(pDrawable, pGC, 1, &backrect);
+
+ /* put down the glyphs */
+ gcvals[0] = oldFG;
+ DoChangeGC(pGC, GCForeground, gcvals, 0);
+ ValidateGC(pDrawable, pGC);
+ (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph, ppci,
+ (char *)pglyphBase);
+
+ /* put all the toys away when done playing */
+ gcvals[0] = oldAlu;
+ gcvals[1] = oldFG;
+ gcvals[2] = oldFS;
+ DoChangeGC(pGC, GCFunction|GCForeground|GCFillStyle, gcvals, 0);
+ ValidateGC(pDrawable, pGC);
+
+}
diff --git a/xc/programs/Xserver/mi/miinitext.c b/xc/programs/Xserver/mi/miinitext.c
new file mode 100644
index 000000000..6e93fef7c
--- /dev/null
+++ b/xc/programs/Xserver/mi/miinitext.c
@@ -0,0 +1,457 @@
+/* $XFree86: xc/programs/Xserver/mi/miinitext.c,v 3.41 1999/06/14 07:32:11 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: miinitext.c /main/47 1998/02/09 14:47:26 kaleb $ */
+
+#include "misc.h"
+#include "extension.h"
+#include "micmap.h"
+
+#ifdef NOPEXEXT /* sleaze for Solaris cpp building XsunMono */
+#undef PEXEXT
+#endif
+#ifdef PANORAMIX
+extern Bool noPanoramiXExtension;
+#endif
+extern Bool noTestExtensions;
+#ifdef XKB
+extern Bool noXkbExtension;
+#endif
+
+#ifndef XFree86LOADER
+#if NeedFunctionPrototypes
+#define INITARGS void
+#else
+#define INITARGS /*nothing*/
+#endif
+typedef void (*InitExtension)(INITARGS);
+#else /* XFree86Loader */
+#include "xf86Module.h"
+#endif
+
+/* FIXME: this whole block of externs should be from the appropriate headers */
+#ifdef BEZIER
+extern void BezierExtensionInit(INITARGS);
+#endif
+#ifdef XTESTEXT1
+extern void XTestExtension1Init(INITARGS);
+#endif
+#ifdef SHAPE
+extern void ShapeExtensionInit(INITARGS);
+#endif
+#ifdef EVI
+extern void EVIExtensionInit(INITARGS);
+#endif
+#ifdef MITSHM
+extern void ShmExtensionInit(INITARGS);
+#endif
+#ifdef PEXEXT
+extern void PexExtensionInit(INITARGS);
+#endif
+#ifdef MULTIBUFFER
+extern void MultibufferExtensionInit(INITARGS);
+#endif
+#ifdef PANORAMIX
+extern void PanoramiXExtensionInit(INITARGS);
+#endif
+#ifdef XINPUT
+extern void XInputExtensionInit(INITARGS);
+#endif
+#ifdef XTEST
+extern void XTestExtensionInit(INITARGS);
+#endif
+#ifdef BIGREQS
+extern void BigReqExtensionInit(INITARGS);
+#endif
+#ifdef MITMISC
+extern void MITMiscExtensionInit(INITARGS);
+#endif
+#ifdef XIDLE
+extern void XIdleExtensionInit(INITARGS);
+#endif
+#ifdef XTRAP
+extern void DEC_XTRAPInit(INITARGS);
+#endif
+#ifdef SCREENSAVER
+extern void ScreenSaverExtensionInit (INITARGS);
+#endif
+#ifdef XV
+extern void XvExtensionInit(INITARGS);
+#endif
+#ifdef XIE
+extern void XieInit(INITARGS);
+#endif
+#ifdef XSYNC
+extern void SyncExtensionInit(INITARGS);
+#endif
+#ifdef XKB
+extern void XkbExtensionInit(INITARGS);
+#endif
+#ifdef XCMISC
+extern void XCMiscExtensionInit(INITARGS);
+#endif
+#ifdef XRECORD
+extern void RecordExtensionInit(INITARGS);
+#endif
+#ifdef LBX
+extern void LbxExtensionInit(INITARGS);
+#endif
+#ifdef DBE
+extern void DbeExtensionInit(INITARGS);
+#endif
+#ifdef XAPPGROUP
+extern void XagExtensionInit(INITARGS);
+#endif
+#ifdef XCSECURITY
+extern void SecurityExtensionInit(INITARGS);
+#endif
+#ifdef XPRINT
+extern void XpExtensionInit(INITARGS);
+#endif
+#ifdef XF86VIDMODE
+extern void XFree86VidModeExtensionInit(INITARGS);
+#endif
+#ifdef XF86MISC
+extern void XFree86MiscExtensionInit(INITARGS);
+#endif
+#ifdef XFreeXDGA
+extern void XFree86DGAExtensionInit(INITARGS);
+#endif
+#ifdef GLXEXT
+extern void GlxExtensionInit(INITARGS);
+extern void GlxWrapInitVisuals(miInitVisualsProcPtr *);
+#endif
+#ifdef XF86DRI
+extern void XFree86DRIExtensionInit(INITARGS);
+#endif
+#ifdef TOGCUP
+extern void XcupExtensionInit(INITARGS);
+#endif
+#ifdef DPMSExtension
+extern void DPMSExtensionInit(INITARGS);
+#endif
+#ifdef XANTI
+extern void XAntiExtensionInit(INITARGS);
+#endif
+
+#ifndef XFree86LOADER
+
+/*ARGSUSED*/
+void
+InitExtensions(argc, argv)
+ int argc;
+ char *argv[];
+{
+#ifdef PANORAMIX
+#if !defined(PRINT_ONLY_SERVER) && !defined(NO_PANORAMIX)
+ if (!noPanoramiXExtension) PanoramiXExtensionInit();
+#endif
+#endif
+#ifdef BEZIER
+ BezierExtensionInit();
+#endif
+#ifdef XTESTEXT1
+ if (!noTestExtensions) XTestExtension1Init();
+#endif
+#ifdef SHAPE
+ ShapeExtensionInit();
+#endif
+#ifdef MITSHM
+ ShmExtensionInit();
+#endif
+#ifdef EVI
+ EVIExtensionInit();
+#endif
+#ifdef PEXEXT
+ PexExtensionInit();
+#endif
+#ifdef MULTIBUFFER
+ MultibufferExtensionInit();
+#endif
+#if defined(XINPUT) && !defined(NO_HW_ONLY_EXTS)
+ XInputExtensionInit();
+#endif
+#ifdef XTEST
+ if (!noTestExtensions) XTestExtensionInit();
+#endif
+#ifdef BIGREQS
+ BigReqExtensionInit();
+#endif
+#ifdef MITMISC
+ MITMiscExtensionInit();
+#endif
+#ifdef XIDLE
+ XIdleExtensionInit();
+#endif
+#ifdef XTRAP
+ if (!noTestExtensions) DEC_XTRAPInit();
+#endif
+#if defined(SCREENSAVER) && !defined(PRINT_ONLY_SERVER)
+ ScreenSaverExtensionInit ();
+#endif
+#ifdef XV
+ XvExtensionInit();
+#endif
+#ifdef XIE
+ XieInit();
+#endif
+#ifdef XSYNC
+ SyncExtensionInit();
+#endif
+#if defined(XKB) && !defined(PRINT_ONLY_SERVER) && !defined(NO_HW_ONLY_EXTS)
+ if (!noXkbExtension) XkbExtensionInit();
+#endif
+#ifdef XCMISC
+ XCMiscExtensionInit();
+#endif
+#ifdef XRECORD
+ if (!noTestExtensions) RecordExtensionInit();
+#endif
+#ifdef LBX
+ LbxExtensionInit();
+#endif
+#ifdef DBE
+ DbeExtensionInit();
+#endif
+#ifdef XAPPGROUP
+ XagExtensionInit();
+#endif
+#ifdef XCSECURITY
+ SecurityExtensionInit();
+#endif
+#ifdef XPRINT
+ XpExtensionInit();
+#endif
+#ifdef TOGCUP
+ XcupExtensionInit();
+#endif
+#if defined(DPMSExtension) && !defined(NO_HW_ONLY_EXTS)
+ DPMSExtensionInit();
+#endif
+#ifdef XANTI
+ XAntiExtensionInit();
+#endif
+#if !defined(PRINT_ONLY_SERVER) && !defined(NO_HW_ONLY_EXTS)
+#if defined(XF86VIDMODE)
+ XFree86VidModeExtensionInit();
+#endif
+#if defined(XF86MISC)
+ XFree86MiscExtensionInit();
+#endif
+#if defined(XFreeXDGA)
+ XFree86DGAExtensionInit();
+#endif
+#endif
+#ifdef XF86DRI
+#ifndef XPRINT /* we don't want Glx in the Xprint server */
+ XFree86DRIExtensionInit();
+#endif
+#endif
+#ifdef GLXEXT
+#ifndef XPRINT /* we don't want Glx in the Xprint server */
+ GlxExtensionInit();
+#endif
+#endif
+}
+
+void
+InitVisualWrap()
+{
+ miResetInitVisuals();
+#ifdef GLXEXT
+#ifndef XPRINT
+ GlxWrapInitVisuals(&miInitVisualsProc);
+#endif
+#endif
+}
+
+#else /* XFree86LOADER */
+/* FIXME:The names here must come from the headers. those with ?? are
+ not included in X11R6.3 sample implementation, so there's a problem... */
+/* XXX use the correct #ifdefs for symbols not present when an extension
+ is disabled */
+ExtensionModule extension[] =
+{
+ { NULL, "BEZIER", NULL, NULL }, /* ?? */
+ { NULL, "XTEST1", &noTestExtensions, NULL }, /* ?? */
+ { NULL, "SHAPE", NULL, NULL },
+ { NULL, "MIT-SHM", NULL, NULL },
+ { NULL, "X3D-PEX", NULL, NULL },
+ { NULL, "Multi-Buffering", NULL, NULL },
+ { NULL, "XInputExtension", NULL, NULL },
+ { NULL, "XTEST", &noTestExtensions, NULL },
+ { NULL, "BIG-REQUESTS", NULL, NULL },
+ { NULL, "MIT-SUNDRY-NONSTANDARD", NULL, NULL },
+ { NULL, "XIDLE", NULL, NULL }, /* ?? */
+ { NULL, "XTRAP", &noTestExtensions, NULL }, /* ?? */
+ { NULL, "MIT-SCREEN-SAVER", NULL, NULL },
+ { NULL, "XVideo", NULL, NULL }, /* ?? */
+ { NULL, "XIE", NULL, NULL },
+ { NULL, "SYNC", NULL, NULL },
+#ifdef XKB
+ { NULL, "XKEYBOARD", &noXkbExtension, NULL },
+#else
+ { NULL, "NOXKEYBOARD", NULL, NULL },
+#endif
+ { NULL, "XC-MISC", NULL, NULL },
+ { NULL, "RECORD", &noTestExtensions, NULL },
+ { NULL, "LBX", NULL, NULL },
+ { NULL, "DOUBLE-BUFFER", NULL, NULL },
+ { NULL, "XC-APPGROUP", NULL, NULL },
+ { NULL, "SECURITY", NULL, NULL },
+ { NULL, "XpExtension", NULL, NULL },
+ { NULL, "XFree86-VidModeExtension", NULL, NULL },
+ { NULL, "XFree86-Misc", NULL, NULL },
+ { NULL, "XFree86-DGA", NULL, NULL },
+ { NULL, "DPMS", NULL, NULL },
+ { NULL, "GLX", NULL, NULL },
+ { NULL, "TOG-CUP", NULL, NULL },
+ { NULL, "Extended-Visual-Information", NULL, NULL },
+#ifdef PANORAMIX
+ { NULL, "XINERAMA", &noPanoramiXExtension, NULL },
+#else
+ { NULL, "NOXINERAMA", NULL, NULL },
+#endif
+ { NULL, "XAnti", NULL, NULL },
+ { NULL, "XFree86-DRI", NULL, NULL },
+ { NULL, NULL, NULL, NULL }
+};
+
+/*ARGSUSED*/
+void
+InitExtensions(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int i;
+#if 1
+ /* Add static extensions */
+#ifdef BEZIER
+ extension[0].initFunc = BezierExtensionInit;
+#endif
+#ifdef XTESTEXT1
+ extension[1].initFunc = XTestExtension1Init;
+#endif
+ /* 2 - SHAPE */
+#ifdef MITSHM
+ extension[3].initFunc = ShmExtensionInit;
+#endif
+ /* 4 - pex */
+ /* 5 - multibuf */
+#ifdef XINPUT
+ extension[6].initFunc = XInputExtensionInit;
+#endif
+#ifdef XTEST
+ extension[7].initFunc = XTestExtensionInit;
+#endif
+ /* 8 - BigReqs */
+ /* 9 - MITMisc */
+#ifdef XIDLE
+ extension[10].initFunc = XIdleExtensionInit;
+#endif
+#ifdef XTRAP
+ extension[11].initFunc = DEC_XTRAPIbit;
+#endif
+ /* 12 - ScreenSaver */
+ /* 13 - XVideo */
+ /* 14 - XIE */
+ /* 15 - XSYNC */
+#ifdef XKB
+ extension[16].initFunc = XkbExtensionInit;
+#endif
+ /* 17 - XCMISC */
+ /* 18 - XRECORD */
+#ifdef LBX
+ extension[19].initFunc = LbxExtensionInit;
+#endif
+ /* 20 - DBE */
+#ifdef XAPPGROUP
+ extension[21].initFunc = XagExtensionInit;
+#endif
+#ifdef XCSECURITY
+ extension[22].initFunc = SecurityExtensionInit;
+#endif
+#ifdef XPRINT
+ extension[23].initFunc = XpExtensionInit;
+#endif
+ /* 24 - XF86VidMode */
+ /* 25 - XF86Misc */
+ /* 26 - XF86DGA */
+ /* 27 - DPMS */
+ /* 28 - GLX */
+ /* 29 - TOG-CUP */
+ /* 30 - EVI */
+#ifdef PANORAMIX
+ extension[31].initFunc = PanoramiXExtensionInit;
+#endif
+ /* 31 - XAnti */
+ /* 32 - XF86DRI */
+
+#endif
+ for (i = 0; extension[i].name != NULL; i++)
+ if (extension[i].initFunc != NULL &&
+ (extension[i].disablePtr == NULL ||
+ (extension[i].disablePtr != NULL && !*extension[i].disablePtr))) {
+ (*extension[i].initFunc)();
+ }
+}
+
+static void (*__miHookInitVisualsFunction)(miInitVisualsProcPtr *);
+
+void
+InitVisualWrap()
+{
+ miResetInitVisuals();
+ if (__miHookInitVisualsFunction)
+ (*__miHookInitVisualsFunction)(&miInitVisualsProc);
+}
+
+void miHookInitVisuals(void (**old)(miInitVisualsProcPtr *),
+ void (*new)(miInitVisualsProcPtr *))
+{
+ if (old)
+ *old = __miHookInitVisualsFunction;
+ __miHookInitVisualsFunction = new;
+}
+
+#endif /* XFree86LOADER */
diff --git a/xc/programs/Xserver/mi/miline.h b/xc/programs/Xserver/mi/miline.h
new file mode 100644
index 000000000..16f0de662
--- /dev/null
+++ b/xc/programs/Xserver/mi/miline.h
@@ -0,0 +1,166 @@
+/* $TOG: miline.h /main/7 1998/02/09 14:47:30 kaleb $ */
+
+/*
+
+Copyright 1994, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+/* $XFree86: xc/programs/Xserver/mi/miline.h,v 1.3 1998/10/04 09:39:30 dawes Exp $ */
+
+#ifndef MILINE_H
+
+#include "screenint.h"
+
+/*
+ * Public definitions used for configuring basic pixelization aspects
+ * of the sample implementation line-drawing routines provided in
+ * {mfb,mi,cfb*} at run-time.
+ */
+
+#define XDECREASING 4
+#define YDECREASING 2
+#define YMAJOR 1
+
+#define OCTANT1 (1 << (YDECREASING))
+#define OCTANT2 (1 << (YDECREASING|YMAJOR))
+#define OCTANT3 (1 << (XDECREASING|YDECREASING|YMAJOR))
+#define OCTANT4 (1 << (XDECREASING|YDECREASING))
+#define OCTANT5 (1 << (XDECREASING))
+#define OCTANT6 (1 << (XDECREASING|YMAJOR))
+#define OCTANT7 (1 << (YMAJOR))
+#define OCTANT8 (1 << (0))
+
+#define XMAJOROCTANTS (OCTANT1 | OCTANT4 | OCTANT5 | OCTANT8)
+
+#define DEFAULTZEROLINEBIAS (OCTANT2 | OCTANT3 | OCTANT4 | OCTANT5)
+
+/*
+ * Devices can configure the rendering of routines in mi, mfb, and cfb*
+ * by specifying a thin line bias to be applied to a particular screen
+ * using the following function. The bias parameter is an OR'ing of
+ * the appropriate OCTANT constants defined above to indicate which
+ * octants to bias a line to prefer an axial step when the Bresenham
+ * error term is exactly zero. The octants are mapped as follows:
+ *
+ * \ | /
+ * \ 3 | 2 /
+ * \ | /
+ * 4 \ | / 1
+ * \|/
+ * -----------
+ * /|\
+ * 5 / | \ 8
+ * / | \
+ * / 6 | 7 \
+ * / | \
+ *
+ * For more information, see "Ambiguities in Incremental Line Rastering,"
+ * Jack E. Bresenham, IEEE CG&A, May 1987.
+ */
+
+extern void miSetZeroLineBias(
+#if NeedFunctionPrototypes
+ ScreenPtr /* pScreen */,
+ unsigned int /* bias */
+#endif
+);
+
+/*
+ * Private definitions needed for drawing thin (zero width) lines
+ * Used by the mi, mfb, and all cfb* components.
+ */
+
+#define X_AXIS 0
+#define Y_AXIS 1
+
+#define OUT_LEFT 0x08
+#define OUT_RIGHT 0x04
+#define OUT_ABOVE 0x02
+#define OUT_BELOW 0x01
+
+#define OUTCODES(_result, _x, _y, _pbox) \
+ if ( (_x) < (_pbox)->x1) (_result) |= OUT_LEFT; \
+ else if ( (_x) >= (_pbox)->x2) (_result) |= OUT_RIGHT; \
+ if ( (_y) < (_pbox)->y1) (_result) |= OUT_ABOVE; \
+ else if ( (_y) >= (_pbox)->y2) (_result) |= OUT_BELOW;
+
+#define SWAPINT(i, j) \
+{ register int _t = i; i = j; j = _t; }
+
+#define SWAPPT(i, j) \
+{ DDXPointRec _t; _t = i; i = j; j = _t; }
+
+#define SWAPINT_PAIR(x1, y1, x2, y2)\
+{ int t = x1; x1 = x2; x2 = t;\
+ t = y1; y1 = y2; y2 = t;\
+}
+
+#define miGetZeroLineBias(_pScreen) \
+ ((miZeroLineScreenIndex < 0) ? \
+ 0 : ((_pScreen)->devPrivates[miZeroLineScreenIndex].uval))
+
+#define CalcLineDeltas(_x1,_y1,_x2,_y2,_adx,_ady,_sx,_sy,_SX,_SY,_octant) \
+ (_octant) = 0; \
+ (_sx) = (_SX); \
+ if (((_adx) = (_x2) - (_x1)) < 0) { \
+ (_adx) = -(_adx); \
+ (_sx = -(_sx)); \
+ (_octant) |= XDECREASING; \
+ } \
+ (_sy) = (_SY); \
+ if (((_ady) = (_y2) - (_y1)) < 0) { \
+ (_ady) = -(_ady); \
+ (_sy = -(_sy)); \
+ (_octant) |= YDECREASING; \
+ }
+
+#define SetYMajorOctant(_octant) ((_octant) |= YMAJOR)
+
+#define FIXUP_ERROR(_e, _octant, _bias) \
+ (_e) -= (((_bias) >> (_octant)) & 1)
+
+#define IsXMajorOctant(_octant) (!((_octant) & YMAJOR))
+#define IsYMajorOctant(_octant) ((_octant) & YMAJOR)
+#define IsXDecreasingOctant(_octant) ((_octant) & XDECREASING)
+#define IsYDecreasingOctant(_octant) ((_octant) & YDECREASING)
+
+extern int miZeroLineScreenIndex;
+
+extern int miZeroClipLine(
+#if NeedFunctionPrototypes
+ int /*xmin*/,
+ int /*ymin*/,
+ int /*xmax*/,
+ int /*ymax*/,
+ int * /*new_x1*/,
+ int * /*new_y1*/,
+ int * /*new_x2*/,
+ int * /*new_y2*/,
+ unsigned int /*adx*/,
+ unsigned int /*ady*/,
+ int * /*pt1_clipped*/,
+ int * /*pt2_clipped*/,
+ int /*octant*/,
+ unsigned int /*bias*/,
+ int /*oc1*/,
+ int /*oc2*/
+#endif
+);
+
+#endif /* MILINE_H */
diff --git a/xc/programs/Xserver/mi/mipointer.c b/xc/programs/Xserver/mi/mipointer.c
new file mode 100644
index 000000000..e61179af5
--- /dev/null
+++ b/xc/programs/Xserver/mi/mipointer.c
@@ -0,0 +1,532 @@
+/*
+ * mipointer.c
+ */
+
+/* $TOG: mipointer.c /main/26 1998/02/09 14:47:34 kaleb $ */
+
+/*
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+*/
+/* $XFree86: xc/programs/Xserver/mi/mipointer.c,v 3.5 1998/12/05 14:40:28 dawes Exp $ */
+
+# define NEED_EVENTS
+# include "X.h"
+# include "Xmd.h"
+# include "Xproto.h"
+# include "misc.h"
+# include "windowstr.h"
+# include "pixmapstr.h"
+# include "mi.h"
+# include "scrnintstr.h"
+# include "mipointrst.h"
+# include "cursorstr.h"
+# include "dixstruct.h"
+
+int miPointerScreenIndex;
+static unsigned long miPointerGeneration = 0;
+
+#define GetScreenPrivate(s) ((miPointerScreenPtr) ((s)->devPrivates[miPointerScreenIndex].ptr))
+#define SetupScreen(s) miPointerScreenPtr pScreenPriv = GetScreenPrivate(s)
+
+/*
+ * until more than one pointer device exists.
+ */
+
+static miPointerRec miPointer;
+
+static Bool miPointerRealizeCursor (), miPointerUnrealizeCursor ();
+static Bool miPointerDisplayCursor ();
+static void miPointerConstrainCursor (), miPointerPointerNonInterestBox();
+static void miPointerCursorLimits ();
+static Bool miPointerSetCursorPosition ();
+
+static Bool miPointerCloseScreen();
+
+static void miPointerMove ();
+
+Bool
+miPointerInitialize (pScreen, spriteFuncs, screenFuncs, waitForUpdate)
+ ScreenPtr pScreen;
+ miPointerSpriteFuncPtr spriteFuncs;
+ miPointerScreenFuncPtr screenFuncs;
+ Bool waitForUpdate;
+{
+ miPointerScreenPtr pScreenPriv;
+
+ if (miPointerGeneration != serverGeneration)
+ {
+ miPointerScreenIndex = AllocateScreenPrivateIndex();
+ if (miPointerScreenIndex < 0)
+ return FALSE;
+ miPointerGeneration = serverGeneration;
+ }
+ pScreenPriv = (miPointerScreenPtr) xalloc (sizeof (miPointerScreenRec));
+ if (!pScreenPriv)
+ return FALSE;
+ pScreenPriv->spriteFuncs = spriteFuncs;
+ pScreenPriv->screenFuncs = screenFuncs;
+ /*
+ * check for uninitialized methods
+ */
+ if (!screenFuncs->EnqueueEvent)
+ screenFuncs->EnqueueEvent = mieqEnqueue;
+ if (!screenFuncs->NewEventScreen)
+ screenFuncs->NewEventScreen = mieqSwitchScreen;
+ pScreenPriv->waitForUpdate = waitForUpdate;
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = miPointerCloseScreen;
+ pScreen->devPrivates[miPointerScreenIndex].ptr = (pointer) pScreenPriv;
+ /*
+ * set up screen cursor method table
+ */
+ pScreen->ConstrainCursor = miPointerConstrainCursor;
+ pScreen->CursorLimits = miPointerCursorLimits;
+ pScreen->DisplayCursor = miPointerDisplayCursor;
+ pScreen->RealizeCursor = miPointerRealizeCursor;
+ pScreen->UnrealizeCursor = miPointerUnrealizeCursor;
+ pScreen->SetCursorPosition = miPointerSetCursorPosition;
+ pScreen->RecolorCursor = miRecolorCursor;
+ pScreen->PointerNonInterestBox = miPointerPointerNonInterestBox;
+ /*
+ * set up the pointer object
+ */
+ miPointer.pScreen = NULL;
+ miPointer.pSpriteScreen = NULL;
+ miPointer.pCursor = NULL;
+ miPointer.pSpriteCursor = NULL;
+ miPointer.limits.x1 = 0;
+ miPointer.limits.x2 = 32767;
+ miPointer.limits.y1 = 0;
+ miPointer.limits.y2 = 32767;
+ miPointer.confined = FALSE;
+ miPointer.x = 0;
+ miPointer.y = 0;
+ miPointer.history_start = miPointer.history_end = 0;
+ return TRUE;
+}
+
+static Bool
+miPointerCloseScreen (index, pScreen)
+ int index;
+ ScreenPtr pScreen;
+{
+ SetupScreen(pScreen);
+
+ if (pScreen == miPointer.pScreen)
+ miPointer.pScreen = 0;
+ if (pScreen == miPointer.pSpriteScreen)
+ miPointer.pSpriteScreen = 0;
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ xfree ((pointer) pScreenPriv);
+ return (*pScreen->CloseScreen) (index, pScreen);
+}
+
+/*
+ * DIX/DDX interface routines
+ */
+
+static Bool
+miPointerRealizeCursor (pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ SetupScreen(pScreen);
+
+ return (*pScreenPriv->spriteFuncs->RealizeCursor) (pScreen, pCursor);
+}
+
+static Bool
+miPointerUnrealizeCursor (pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ SetupScreen(pScreen);
+
+ return (*pScreenPriv->spriteFuncs->UnrealizeCursor) (pScreen, pCursor);
+}
+
+static Bool
+miPointerDisplayCursor (pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ SetupScreen(pScreen);
+
+ miPointer.pCursor = pCursor;
+ miPointer.pScreen = pScreen;
+ miPointerUpdate ();
+ return TRUE;
+}
+
+static void
+miPointerConstrainCursor (pScreen, pBox)
+ ScreenPtr pScreen;
+ BoxPtr pBox;
+{
+ miPointer.limits = *pBox;
+ miPointer.confined = PointerConfinedToScreen();
+}
+
+/*ARGSUSED*/
+static void
+miPointerPointerNonInterestBox (pScreen, pBox)
+ ScreenPtr pScreen;
+ BoxPtr pBox;
+{
+ /* until DIX uses this, this will remain a stub */
+}
+
+/*ARGSUSED*/
+static void
+miPointerCursorLimits(pScreen, pCursor, pHotBox, pTopLeftBox)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+ BoxPtr pHotBox;
+ BoxPtr pTopLeftBox;
+{
+ *pTopLeftBox = *pHotBox;
+}
+
+static Bool GenerateEvent;
+
+static Bool
+miPointerSetCursorPosition(pScreen, x, y, generateEvent)
+ ScreenPtr pScreen;
+ int x, y;
+ Bool generateEvent;
+{
+ SetupScreen (pScreen);
+
+ GenerateEvent = generateEvent;
+ /* device dependent - must pend signal and call miPointerWarpCursor */
+ (*pScreenPriv->screenFuncs->WarpCursor) (pScreen, x, y);
+ if (!generateEvent)
+ miPointerUpdate();
+ return TRUE;
+}
+
+/* Once signals are ignored, the WarpCursor function can call this */
+
+void
+miPointerWarpCursor (pScreen, x, y)
+ ScreenPtr pScreen;
+ int x, y;
+{
+ SetupScreen (pScreen);
+
+ if (miPointer.pScreen != pScreen)
+ (*pScreenPriv->screenFuncs->NewEventScreen) (pScreen, TRUE);
+
+ if (GenerateEvent)
+ {
+ miPointerMove (pScreen, x, y, GetTimeInMillis());
+ }
+ else
+ {
+ /* everything from miPointerMove except the event and history */
+
+ if (!pScreenPriv->waitForUpdate && pScreen == miPointer.pSpriteScreen)
+ {
+ miPointer.devx = x;
+ miPointer.devy = y;
+ if(!miPointer.pCursor->bits->emptyMask)
+ (*pScreenPriv->spriteFuncs->MoveCursor) (pScreen, x, y);
+ }
+ miPointer.x = x;
+ miPointer.y = y;
+ miPointer.pScreen = pScreen;
+ }
+}
+
+/*
+ * Pointer/CursorDisplay interface routines
+ */
+
+int
+miPointerGetMotionBufferSize ()
+{
+ return MOTION_SIZE;
+}
+
+int
+miPointerGetMotionEvents (pPtr, coords, start, stop, pScreen)
+ DeviceIntPtr pPtr;
+ xTimecoord *coords;
+ unsigned long start, stop;
+ ScreenPtr pScreen;
+{
+ int i;
+ int count = 0;
+ miHistoryPtr h;
+
+ for (i = miPointer.history_start; i != miPointer.history_end;)
+ {
+ h = &miPointer.history[i];
+ if (h->event.time >= stop)
+ break;
+ if (h->event.time >= start)
+ {
+ *coords++ = h->event;
+ count++;
+ }
+ if (++i == MOTION_SIZE) i = 0;
+ }
+ return count;
+}
+
+
+/*
+ * miPointerUpdate
+ *
+ * Syncronize the sprite with the cursor - called from ProcessInputEvents
+ */
+
+void
+miPointerUpdate ()
+{
+ ScreenPtr pScreen;
+ miPointerScreenPtr pScreenPriv;
+ int x, y, devx, devy;
+
+ pScreen = miPointer.pScreen;
+ x = miPointer.x;
+ y = miPointer.y;
+ devx = miPointer.devx;
+ devy = miPointer.devy;
+ if (!pScreen)
+ return;
+ pScreenPriv = GetScreenPrivate (pScreen);
+ /*
+ * if the cursor has switched screens, disable the sprite
+ * on the old screen
+ */
+ if (pScreen != miPointer.pSpriteScreen)
+ {
+ if (miPointer.pSpriteScreen)
+ {
+ miPointerScreenPtr pOldPriv;
+
+ pOldPriv = GetScreenPrivate (miPointer.pSpriteScreen);
+ if (miPointer.pCursor)
+ {
+ (*pOldPriv->spriteFuncs->SetCursor)
+ (miPointer.pSpriteScreen, NullCursor, 0, 0);
+ }
+ (*pOldPriv->screenFuncs->CrossScreen) (miPointer.pSpriteScreen, FALSE);
+ }
+ (*pScreenPriv->screenFuncs->CrossScreen) (pScreen, TRUE);
+ (*pScreenPriv->spriteFuncs->SetCursor)
+ (pScreen, miPointer.pCursor, x, y);
+ miPointer.devx = x;
+ miPointer.devy = y;
+ miPointer.pSpriteCursor = miPointer.pCursor;
+ miPointer.pSpriteScreen = pScreen;
+ }
+ /*
+ * if the cursor has changed, display the new one
+ */
+ else if (miPointer.pCursor != miPointer.pSpriteCursor)
+ {
+ (*pScreenPriv->spriteFuncs->SetCursor) (pScreen,
+ miPointer.pCursor->bits->emptyMask ?
+ NullCursor : miPointer.pCursor, x, y);
+
+ miPointer.devx = x;
+ miPointer.devy = y;
+ miPointer.pSpriteCursor = miPointer.pCursor;
+ }
+ else if (x != devx || y != devy)
+ {
+ miPointer.devx = x;
+ miPointer.devy = y;
+ if(!miPointer.pCursor->bits->emptyMask)
+ (*pScreenPriv->spriteFuncs->MoveCursor) (pScreen, x, y);
+ }
+}
+
+/*
+ * miPointerDeltaCursor. The pointer has moved dx,dy from it's previous
+ * position.
+ */
+
+void
+miPointerDeltaCursor (dx, dy, time)
+ int dx, dy;
+ unsigned long time;
+{
+ miPointerAbsoluteCursor (miPointer.x + dx, miPointer.y + dy, time);
+}
+
+void
+miPointerSetNewScreen(int screen_no, int x, int y)
+{
+ miPointerScreenPtr pScreenPriv;
+ ScreenPtr pScreen;
+
+ pScreen = screenInfo.screens[screen_no];
+ pScreenPriv = GetScreenPrivate (pScreen);
+ (*pScreenPriv->screenFuncs->NewEventScreen) (pScreen, FALSE);
+ NewCurrentScreen (pScreen, x, y);
+ miPointer.limits.x2 = pScreen->width;
+ miPointer.limits.y2 = pScreen->height;
+}
+
+ScreenPtr
+miPointerCurrentScreen ()
+{
+ return (miPointer.pScreen);
+}
+
+/*
+ * miPointerAbsoluteCursor. The pointer has moved to x,y
+ */
+
+void
+miPointerAbsoluteCursor (x, y, time)
+ int x, y;
+ unsigned long time;
+{
+ miPointerScreenPtr pScreenPriv;
+ ScreenPtr pScreen;
+ ScreenPtr newScreen;
+
+ pScreen = miPointer.pScreen;
+ if (!pScreen)
+ return; /* called before ready */
+ if (x < 0 || x >= pScreen->width || y < 0 || y >= pScreen->height)
+ {
+ pScreenPriv = GetScreenPrivate (pScreen);
+ if (!miPointer.confined)
+ {
+ newScreen = pScreen;
+ (*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, &x, &y);
+ if (newScreen != pScreen)
+ {
+ pScreen = newScreen;
+ (*pScreenPriv->screenFuncs->NewEventScreen) (pScreen, FALSE);
+ pScreenPriv = GetScreenPrivate (pScreen);
+ /* Smash the confine to the new screen */
+ miPointer.limits.x2 = pScreen->width;
+ miPointer.limits.y2 = pScreen->height;
+ }
+ }
+ }
+ /*
+ * constrain the hot-spot to the current
+ * limits
+ */
+ if (x < miPointer.limits.x1)
+ x = miPointer.limits.x1;
+ if (x >= miPointer.limits.x2)
+ x = miPointer.limits.x2 - 1;
+ if (y < miPointer.limits.y1)
+ y = miPointer.limits.y1;
+ if (y >= miPointer.limits.y2)
+ y = miPointer.limits.y2 - 1;
+ if (miPointer.x == x && miPointer.y == y && miPointer.pScreen == pScreen)
+ return;
+ miPointerMove (pScreen, x, y, time);
+}
+
+void
+miPointerPosition (x, y)
+ int *x, *y;
+{
+ *x = miPointer.x;
+ *y = miPointer.y;
+}
+
+/*
+ * miPointerMove. The pointer has moved to x,y on current screen
+ */
+
+static void
+miPointerMove (pScreen, x, y, time)
+ ScreenPtr pScreen;
+ int x, y;
+ unsigned long time;
+{
+ SetupScreen(pScreen);
+ xEvent xE;
+ miHistoryPtr history;
+ int prev, end, start;
+
+ if (!pScreenPriv->waitForUpdate && pScreen == miPointer.pSpriteScreen)
+ {
+ miPointer.devx = x;
+ miPointer.devy = y;
+ if(!miPointer.pCursor->bits->emptyMask)
+ (*pScreenPriv->spriteFuncs->MoveCursor) (pScreen, x, y);
+ }
+ miPointer.x = x;
+ miPointer.y = y;
+ miPointer.pScreen = pScreen;
+
+ xE.u.u.type = MotionNotify;
+ xE.u.keyButtonPointer.rootX = x;
+ xE.u.keyButtonPointer.rootY = y;
+ xE.u.keyButtonPointer.time = time;
+ (*pScreenPriv->screenFuncs->EnqueueEvent) (&xE);
+
+ end = miPointer.history_end;
+ start = miPointer.history_start;
+ prev = end - 1;
+ if (end == 0)
+ prev = MOTION_SIZE - 1;
+ history = &miPointer.history[prev];
+ if (end == start || history->event.time != time)
+ {
+ history = &miPointer.history[end];
+ if (++end == MOTION_SIZE)
+ end = 0;
+ if (end == start)
+ {
+ start = end + 1;
+ if (start == MOTION_SIZE)
+ start = 0;
+ miPointer.history_start = start;
+ }
+ miPointer.history_end = end;
+ }
+ history->event.x = x;
+ history->event.y = y;
+ history->event.time = time;
+ history->pScreen = pScreen;
+}
+
+void
+_miRegisterPointerDevice (pScreen, pDevice)
+ ScreenPtr pScreen;
+ DeviceIntPtr pDevice;
+{
+ miPointer.pPointer = (DevicePtr)pDevice;
+}
+
+/* obsolete: for binary compatibility */
+#ifdef miRegisterPointerDevice
+#undef miRegisterPointerDevice
+void
+miRegisterPointerDevice (pScreen, pDevice)
+ ScreenPtr pScreen;
+ DevicePtr pDevice;
+{
+ miPointer.pPointer = pDevice;
+}
+#endif /* miRegisterPointerDevice */
diff --git a/xc/programs/Xserver/mi/mipointer.h b/xc/programs/Xserver/mi/mipointer.h
new file mode 100644
index 000000000..90da7deda
--- /dev/null
+++ b/xc/programs/Xserver/mi/mipointer.h
@@ -0,0 +1,199 @@
+/*
+ * mipointer.h
+ *
+ */
+
+/* $TOG: mipointer.h /main/10 1998/02/09 14:47:38 kaleb $ */
+
+/*
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+*/
+/* $XFree86: xc/programs/Xserver/mi/mipointer.h,v 3.5 1998/12/05 14:40:28 dawes Exp $ */
+
+#ifndef MIPOINTER_H
+#define MIPOINTER_H
+
+typedef struct _miPointerSpriteFuncRec {
+ Bool (*RealizeCursor)(
+#if NeedFunctionPrototypes
+ ScreenPtr /* pScr */,
+ CursorPtr /* pCurs */
+#endif
+ );
+ Bool (*UnrealizeCursor)(
+#if NeedFunctionPrototypes
+ ScreenPtr /* pScr */,
+ CursorPtr /* pCurs */
+#endif
+ );
+ void (*SetCursor)(
+#if NeedFunctionPrototypes
+ ScreenPtr /* pScr */,
+ CursorPtr /* pCurs */,
+ int /* x */,
+ int /* y */
+#endif
+ );
+ void (*MoveCursor)(
+#if NeedFunctionPrototypes
+ ScreenPtr /* pScr */,
+ int /* x */,
+ int /* y */
+#endif
+ );
+} miPointerSpriteFuncRec, *miPointerSpriteFuncPtr;
+
+typedef struct _miPointerScreenFuncRec {
+ Bool (*CursorOffScreen)(
+#if NeedFunctionPrototypes
+ ScreenPtr* /* ppScr */,
+ int* /* px */,
+ int* /* py */
+#endif
+ );
+ void (*CrossScreen)(
+#if NeedFunctionPrototypes
+ ScreenPtr /* pScr */,
+ int /* entering */
+#endif
+ );
+ void (*WarpCursor)(
+#if NeedFunctionPrototypes
+ ScreenPtr /* pScr */,
+ int /* x */,
+ int /* y */
+#endif
+ );
+ void (*EnqueueEvent)(
+#if NeedFunctionPrototypes
+ xEventPtr /* event */
+#endif
+ );
+ void (*NewEventScreen)(
+#if NeedFunctionPrototypes
+ ScreenPtr /* pScr */,
+ Bool /* fromDIX */
+#endif
+ );
+} miPointerScreenFuncRec, *miPointerScreenFuncPtr;
+
+extern Bool miDCInitialize(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ miPointerScreenFuncPtr /*screenFuncs*/
+#endif
+);
+
+extern Bool miPointerInitialize(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ miPointerSpriteFuncPtr /*spriteFuncs*/,
+ miPointerScreenFuncPtr /*screenFuncs*/,
+ Bool /*waitForUpdate*/
+#endif
+);
+
+extern void miPointerWarpCursor(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ int /*x*/,
+ int /*y*/
+#endif
+);
+
+extern int miPointerGetMotionBufferSize(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern int miPointerGetMotionEvents(
+#if NeedFunctionPrototypes
+ DeviceIntPtr /*pPtr*/,
+ xTimecoord * /*coords*/,
+ unsigned long /*start*/,
+ unsigned long /*stop*/,
+ ScreenPtr /*pScreen*/
+#endif
+);
+
+extern void miPointerUpdate(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void miPointerDeltaCursor(
+#if NeedFunctionPrototypes
+ int /*dx*/,
+ int /*dy*/,
+ unsigned long /*time*/
+#endif
+);
+
+extern void miPointerAbsoluteCursor(
+#if NeedFunctionPrototypes
+ int /*x*/,
+ int /*y*/,
+ unsigned long /*time*/
+#endif
+);
+
+extern void miPointerPosition(
+#if NeedFunctionPrototypes
+ int * /*x*/,
+ int * /*y*/
+#endif
+);
+
+#undef miRegisterPointerDevice
+extern void miRegisterPointerDevice(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ DevicePtr /*pDevice*/
+#endif
+);
+
+extern void miPointerSetNewScreen(
+#if NeedFunctionPrototypes
+ int, /*screen_no*/
+ int, /*x*/
+ int /*y*/
+#endif
+);
+extern ScreenPtr miPointerCurrentScreen(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+#define miRegisterPointerDevice(pScreen,pDevice) \
+ _miRegisterPointerDevice(pScreen,pDevice)
+
+extern void _miRegisterPointerDevice(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ DeviceIntPtr /*pDevice*/
+#endif
+);
+
+extern int miPointerScreenIndex;
+
+#endif /* MIPOINTER_H */
diff --git a/xc/programs/Xserver/mi/mipointrst.h b/xc/programs/Xserver/mi/mipointrst.h
new file mode 100644
index 000000000..4528c8af6
--- /dev/null
+++ b/xc/programs/Xserver/mi/mipointrst.h
@@ -0,0 +1,58 @@
+/*
+ * mipointrst.h
+ *
+ */
+
+/* $TOG: mipointrst.h /main/10 1998/02/09 14:47:42 kaleb $ */
+
+/*
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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 <mipointer.h>
+# include <input.h>
+
+#define MOTION_SIZE 256
+
+typedef struct {
+ xTimecoord event;
+ ScreenPtr pScreen;
+} miHistoryRec, *miHistoryPtr;
+
+typedef struct {
+ ScreenPtr pScreen; /* current screen */
+ ScreenPtr pSpriteScreen;/* screen containing current sprite */
+ CursorPtr pCursor; /* current cursor */
+ CursorPtr pSpriteCursor;/* cursor on screen */
+ BoxRec limits; /* current constraints */
+ Bool confined; /* pointer can't change screens */
+ int x, y; /* hot spot location */
+ int devx, devy; /* sprite position */
+ DevicePtr pPointer; /* pointer device structure */
+ miHistoryRec history[MOTION_SIZE];
+ int history_start, history_end;
+} miPointerRec, *miPointerPtr;
+
+typedef struct {
+ miPointerSpriteFuncPtr spriteFuncs; /* sprite-specific methods */
+ miPointerScreenFuncPtr screenFuncs; /* screen-specific methods */
+ CloseScreenProcPtr CloseScreen;
+ Bool waitForUpdate; /* don't move cursor in SIGIO */
+} miPointerScreenRec, *miPointerScreenPtr;
diff --git a/xc/programs/Xserver/mi/mipoly.c b/xc/programs/Xserver/mi/mipoly.c
new file mode 100644
index 000000000..fa6e12a26
--- /dev/null
+++ b/xc/programs/Xserver/mi/mipoly.c
@@ -0,0 +1,120 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mipoly.c /main/5 1998/02/09 14:48:16 kaleb $ */
+/*
+ * mipoly.c
+ *
+ * Written by Brian Kelleher; June 1986
+ *
+ * Draw polygons. This routine translates the point by the
+ * origin if pGC->miTranslate is non-zero, and calls
+ * to the appropriate routine to actually scan convert the
+ * polygon.
+ */
+#include "X.h"
+#include "windowstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "mi.h"
+#include "miscstruct.h"
+
+
+void
+miFillPolygon(dst, pgc, shape, mode, count, pPts)
+ DrawablePtr dst;
+ register GCPtr pgc;
+ int shape, mode;
+ register int count;
+ DDXPointPtr pPts;
+{
+ int i;
+ register int xorg, yorg;
+ register DDXPointPtr ppt;
+
+ if (count == 0)
+ return;
+
+ ppt = pPts;
+ if (pgc->miTranslate)
+ {
+ xorg = dst->x;
+ yorg = dst->y;
+
+ if (mode == CoordModeOrigin)
+ {
+ for (i = 0; i<count; i++)
+ {
+ ppt->x += xorg;
+ ppt++->y += yorg;
+ }
+ }
+ else
+ {
+ ppt->x += xorg;
+ ppt++->y += yorg;
+ for (i = 1; i<count; i++)
+ {
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ ppt++;
+ }
+ }
+ }
+ else
+ {
+ if (mode == CoordModePrevious)
+ {
+ ppt++;
+ for (i = 1; i<count; i++)
+ {
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ ppt++;
+ }
+ }
+ }
+ if (shape == Convex)
+ miFillConvexPoly(dst, pgc, count, pPts);
+ else
+ miFillGeneralPoly(dst, pgc, count, pPts);
+}
diff --git a/xc/programs/Xserver/mi/mipoly.h b/xc/programs/Xserver/mi/mipoly.h
new file mode 100644
index 000000000..8095bc374
--- /dev/null
+++ b/xc/programs/Xserver/mi/mipoly.h
@@ -0,0 +1,224 @@
+/* $TOG: mipoly.h /main/6 1998/02/09 14:48:20 kaleb $ */
+/*
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+
+
+/*
+ * fill.h
+ *
+ * Created by Brian Kelleher; Oct 1985
+ *
+ * Include file for filled polygon routines.
+ *
+ * These are the data structures needed to scan
+ * convert regions. Two different scan conversion
+ * methods are available -- the even-odd method, and
+ * the winding number method.
+ * The even-odd rule states that a point is inside
+ * the polygon if a ray drawn from that point in any
+ * direction will pass through an odd number of
+ * path segments.
+ * By the winding number rule, a point is decided
+ * to be inside the polygon if a ray drawn from that
+ * point in any direction passes through a different
+ * number of clockwise and counter-clockwise path
+ * segments.
+ *
+ * These data structures are adapted somewhat from
+ * the algorithm in (Foley/Van Dam) for scan converting
+ * polygons.
+ * The basic algorithm is to start at the top (smallest y)
+ * of the polygon, stepping down to the bottom of
+ * the polygon by incrementing the y coordinate. We
+ * keep a list of edges which the current scanline crosses,
+ * sorted by x. This list is called the Active Edge Table (AET)
+ * As we change the y-coordinate, we update each entry in
+ * in the active edge table to reflect the edges new xcoord.
+ * This list must be sorted at each scanline in case
+ * two edges intersect.
+ * We also keep a data structure known as the Edge Table (ET),
+ * which keeps track of all the edges which the current
+ * scanline has not yet reached. The ET is basically a
+ * list of ScanLineList structures containing a list of
+ * edges which are entered at a given scanline. There is one
+ * ScanLineList per scanline at which an edge is entered.
+ * When we enter a new edge, we move it from the ET to the AET.
+ *
+ * From the AET, we can implement the even-odd rule as in
+ * (Foley/Van Dam).
+ * The winding number rule is a little trickier. We also
+ * keep the EdgeTableEntries in the AET linked by the
+ * nextWETE (winding EdgeTableEntry) link. This allows
+ * the edges to be linked just as before for updating
+ * purposes, but only uses the edges linked by the nextWETE
+ * link as edges representing spans of the polygon to
+ * drawn (as with the even-odd rule).
+ */
+
+/*
+ * for the winding number rule
+ */
+#define CLOCKWISE 1
+#define COUNTERCLOCKWISE -1
+
+typedef struct _EdgeTableEntry {
+ int ymax; /* ycoord at which we exit this edge. */
+ BRESINFO bres; /* Bresenham info to run the edge */
+ struct _EdgeTableEntry *next; /* next in the list */
+ struct _EdgeTableEntry *back; /* for insertion sort */
+ struct _EdgeTableEntry *nextWETE; /* for winding num rule */
+ int ClockWise; /* flag for winding number rule */
+} EdgeTableEntry;
+
+
+typedef struct _ScanLineList{
+ int scanline; /* the scanline represented */
+ EdgeTableEntry *edgelist; /* header node */
+ struct _ScanLineList *next; /* next in the list */
+} ScanLineList;
+
+
+typedef struct {
+ int ymax; /* ymax for the polygon */
+ int ymin; /* ymin for the polygon */
+ ScanLineList scanlines; /* header node */
+} EdgeTable;
+
+
+/*
+ * Here is a struct to help with storage allocation
+ * so we can allocate a big chunk at a time, and then take
+ * pieces from this heap when we need to.
+ */
+#define SLLSPERBLOCK 25
+
+typedef struct _ScanLineListBlock {
+ ScanLineList SLLs[SLLSPERBLOCK];
+ struct _ScanLineListBlock *next;
+} ScanLineListBlock;
+
+/*
+ * number of points to buffer before sending them off
+ * to scanlines() : Must be an even number
+ */
+#define NUMPTSTOBUFFER 200
+
+
+/*
+ *
+ * a few macros for the inner loops of the fill code where
+ * performance considerations don't allow a procedure call.
+ *
+ * Evaluate the given edge at the given scanline.
+ * If the edge has expired, then we leave it and fix up
+ * the active edge table; otherwise, we increment the
+ * x value to be ready for the next scanline.
+ * The winding number rule is in effect, so we must notify
+ * the caller when the edge has been removed so he
+ * can reorder the Winding Active Edge Table.
+ */
+#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) { \
+ if (pAET->ymax == y) { /* leaving this edge */ \
+ pPrevAET->next = pAET->next; \
+ pAET = pPrevAET->next; \
+ fixWAET = 1; \
+ if (pAET) \
+ pAET->back = pPrevAET; \
+ } \
+ else { \
+ BRESINCRPGONSTRUCT(pAET->bres); \
+ pPrevAET = pAET; \
+ pAET = pAET->next; \
+ } \
+}
+
+
+/*
+ * Evaluate the given edge at the given scanline.
+ * If the edge has expired, then we leave it and fix up
+ * the active edge table; otherwise, we increment the
+ * x value to be ready for the next scanline.
+ * The even-odd rule is in effect.
+ */
+#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) { \
+ if (pAET->ymax == y) { /* leaving this edge */ \
+ pPrevAET->next = pAET->next; \
+ pAET = pPrevAET->next; \
+ if (pAET) \
+ pAET->back = pPrevAET; \
+ } \
+ else { \
+ BRESINCRPGONSTRUCT(pAET->bres); \
+ pPrevAET = pAET; \
+ pAET = pAET->next; \
+ } \
+}
+
+/* mipolyutil.c */
+
+extern Bool miInsertEdgeInET(
+#if NeedFunctionPrototypes
+ EdgeTable * /*ET*/,
+ EdgeTableEntry * /*ETE*/,
+ int /*scanline*/,
+ ScanLineListBlock ** /*SLLBlock*/,
+ int * /*iSLLBlock*/
+#endif
+);
+
+extern Bool miCreateETandAET(
+#if NeedFunctionPrototypes
+ int /*count*/,
+ DDXPointPtr /*pts*/,
+ EdgeTable * /*ET*/,
+ EdgeTableEntry * /*AET*/,
+ EdgeTableEntry * /*pETEs*/,
+ ScanLineListBlock * /*pSLLBlock*/
+#endif
+);
+
+extern void miloadAET(
+#if NeedFunctionPrototypes
+ EdgeTableEntry * /*AET*/,
+ EdgeTableEntry * /*ETEs*/
+#endif
+);
+
+extern void micomputeWAET(
+#if NeedFunctionPrototypes
+ EdgeTableEntry * /*AET*/
+#endif
+);
+
+extern int miInsertionSort(
+#if NeedFunctionPrototypes
+ EdgeTableEntry * /*AET*/
+#endif
+);
+
+extern void miFreeStorage(
+#if NeedFunctionPrototypes
+ ScanLineListBlock * /*pSLLBlock*/
+#endif
+);
diff --git a/xc/programs/Xserver/mi/mipolycon.c b/xc/programs/Xserver/mi/mipolycon.c
new file mode 100644
index 000000000..38202e1da
--- /dev/null
+++ b/xc/programs/Xserver/mi/mipolycon.c
@@ -0,0 +1,241 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mipolycon.c /main/8 1998/02/09 14:47:47 kaleb $ */
+#include "gcstruct.h"
+#include "pixmap.h"
+#include "miscanfill.h"
+
+static int getPolyYBounds();
+
+/*
+ * convexpoly.c
+ *
+ * Written by Brian Kelleher; Dec. 1985.
+ *
+ * Fill a convex polygon. If the given polygon
+ * is not convex, then the result is undefined.
+ * The algorithm is to order the edges from smallest
+ * y to largest by partitioning the array into a left
+ * edge list and a right edge list. The algorithm used
+ * to traverse each edge is an extension of Bresenham's
+ * line algorithm with y as the major axis.
+ * For a derivation of the algorithm, see the author of
+ * this code.
+ */
+Bool
+miFillConvexPoly(dst, pgc, count, ptsIn)
+ DrawablePtr dst;
+ GCPtr pgc;
+ int count; /* number of points */
+ DDXPointPtr ptsIn; /* the points */
+{
+ register int xl, xr; /* x vals of left and right edges */
+ register int dl, dr; /* decision variables */
+ register int ml, m1l; /* left edge slope and slope+1 */
+ int mr, m1r; /* right edge slope and slope+1 */
+ int incr1l, incr2l; /* left edge error increments */
+ int incr1r, incr2r; /* right edge error increments */
+ int dy; /* delta y */
+ int y; /* current scanline */
+ int left, right; /* indices to first endpoints */
+ int i; /* loop counter */
+ int nextleft, nextright; /* indices to second endpoints */
+ DDXPointPtr ptsOut, FirstPoint; /* output buffer */
+ int *width, *FirstWidth; /* output buffer */
+ int imin; /* index of smallest vertex (in y) */
+ int ymin; /* y-extents of polygon */
+ int ymax;
+
+ /*
+ * find leftx, bottomy, rightx, topy, and the index
+ * of bottomy. Also translate the points.
+ */
+ imin = getPolyYBounds(ptsIn, count, &ymin, &ymax);
+
+ dy = ymax - ymin + 1;
+ if ((count < 3) || (dy < 0))
+ return(TRUE);
+ ptsOut = FirstPoint = (DDXPointPtr )ALLOCATE_LOCAL(sizeof(DDXPointRec)*dy);
+ width = FirstWidth = (int *)ALLOCATE_LOCAL(sizeof(int) * dy);
+ if(!FirstPoint || !FirstWidth)
+ {
+ if (FirstWidth) DEALLOCATE_LOCAL(FirstWidth);
+ if (FirstPoint) DEALLOCATE_LOCAL(FirstPoint);
+ return(FALSE);
+ }
+
+ nextleft = nextright = imin;
+ y = ptsIn[nextleft].y;
+
+ /*
+ * loop through all edges of the polygon
+ */
+ do {
+ /*
+ * add a left edge if we need to
+ */
+ if (ptsIn[nextleft].y == y) {
+ left = nextleft;
+
+ /*
+ * find the next edge, considering the end
+ * conditions of the array.
+ */
+ nextleft++;
+ if (nextleft >= count)
+ nextleft = 0;
+
+ /*
+ * now compute all of the random information
+ * needed to run the iterative algorithm.
+ */
+ BRESINITPGON(ptsIn[nextleft].y-ptsIn[left].y,
+ ptsIn[left].x,ptsIn[nextleft].x,
+ xl, dl, ml, m1l, incr1l, incr2l);
+ }
+
+ /*
+ * add a right edge if we need to
+ */
+ if (ptsIn[nextright].y == y) {
+ right = nextright;
+
+ /*
+ * find the next edge, considering the end
+ * conditions of the array.
+ */
+ nextright--;
+ if (nextright < 0)
+ nextright = count-1;
+
+ /*
+ * now compute all of the random information
+ * needed to run the iterative algorithm.
+ */
+ BRESINITPGON(ptsIn[nextright].y-ptsIn[right].y,
+ ptsIn[right].x,ptsIn[nextright].x,
+ xr, dr, mr, m1r, incr1r, incr2r);
+ }
+
+ /*
+ * generate scans to fill while we still have
+ * a right edge as well as a left edge.
+ */
+ i = min(ptsIn[nextleft].y, ptsIn[nextright].y) - y;
+ /* in case we're called with non-convex polygon */
+ if(i < 0)
+ {
+ DEALLOCATE_LOCAL(FirstWidth);
+ DEALLOCATE_LOCAL(FirstPoint);
+ return(TRUE);
+ }
+ while (i-- > 0)
+ {
+ ptsOut->y = y;
+
+ /*
+ * reverse the edges if necessary
+ */
+ if (xl < xr)
+ {
+ *(width++) = xr - xl;
+ (ptsOut++)->x = xl;
+ }
+ else
+ {
+ *(width++) = xl - xr;
+ (ptsOut++)->x = xr;
+ }
+ y++;
+
+ /* increment down the edges */
+ BRESINCRPGON(dl, xl, ml, m1l, incr1l, incr2l);
+ BRESINCRPGON(dr, xr, mr, m1r, incr1r, incr2r);
+ }
+ } while (y != ymax);
+
+ /*
+ * Finally, fill the <remaining> spans
+ */
+ (*pgc->ops->FillSpans)(dst, pgc,
+ ptsOut-FirstPoint,FirstPoint,FirstWidth,
+ 1);
+ DEALLOCATE_LOCAL(FirstWidth);
+ DEALLOCATE_LOCAL(FirstPoint);
+ return(TRUE);
+}
+
+
+/*
+ * Find the index of the point with the smallest y.
+ */
+static
+int
+getPolyYBounds(pts, n, by, ty)
+ DDXPointPtr pts;
+ int n;
+ int *by, *ty;
+{
+ register DDXPointPtr ptMin;
+ int ymin, ymax;
+ DDXPointPtr ptsStart = pts;
+
+ ptMin = pts;
+ ymin = ymax = (pts++)->y;
+
+ while (--n > 0) {
+ if (pts->y < ymin)
+ {
+ ptMin = pts;
+ ymin = pts->y;
+ }
+ if(pts->y > ymax)
+ ymax = pts->y;
+
+ pts++;
+ }
+
+ *by = ymin;
+ *ty = ymax;
+ return(ptMin-ptsStart);
+}
diff --git a/xc/programs/Xserver/mi/mipolygen.c b/xc/programs/Xserver/mi/mipolygen.c
new file mode 100644
index 000000000..594a0b067
--- /dev/null
+++ b/xc/programs/Xserver/mi/mipolygen.c
@@ -0,0 +1,222 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mipolygen.c /main/9 1998/02/09 14:47:51 kaleb $ */
+#include "X.h"
+#include "gcstruct.h"
+#include "miscanfill.h"
+#include "mipoly.h"
+#include "pixmap.h"
+
+/*
+ *
+ * Written by Brian Kelleher; Oct. 1985
+ *
+ * Routine to fill a polygon. Two fill rules are
+ * supported: frWINDING and frEVENODD.
+ *
+ * See fillpoly.h for a complete description of the algorithm.
+ */
+
+Bool
+miFillGeneralPoly(dst, pgc, count, ptsIn)
+ DrawablePtr dst;
+ GCPtr pgc;
+ int count; /* number of points */
+ DDXPointPtr ptsIn; /* the points */
+{
+ register EdgeTableEntry *pAET; /* the Active Edge Table */
+ register int y; /* the current scanline */
+ register int nPts = 0; /* number of pts in buffer */
+ register EdgeTableEntry *pWETE; /* Winding Edge Table */
+ register ScanLineList *pSLL; /* Current ScanLineList */
+ register DDXPointPtr ptsOut; /* ptr to output buffers */
+ int *width;
+ DDXPointRec FirstPoint[NUMPTSTOBUFFER]; /* the output buffers */
+ int FirstWidth[NUMPTSTOBUFFER];
+ EdgeTableEntry *pPrevAET; /* previous AET entry */
+ EdgeTable ET; /* Edge Table header node */
+ EdgeTableEntry AET; /* Active ET header node */
+ EdgeTableEntry *pETEs; /* Edge Table Entries buff */
+ ScanLineListBlock SLLBlock; /* header for ScanLineList */
+ int fixWAET = 0;
+
+ if (count < 3)
+ return(TRUE);
+
+ if(!(pETEs = (EdgeTableEntry *)
+ ALLOCATE_LOCAL(sizeof(EdgeTableEntry) * count)))
+ return(FALSE);
+ ptsOut = FirstPoint;
+ width = FirstWidth;
+ if (!miCreateETandAET(count, ptsIn, &ET, &AET, pETEs, &SLLBlock))
+ {
+ DEALLOCATE_LOCAL(pETEs);
+ return(FALSE);
+ }
+ pSLL = ET.scanlines.next;
+
+ if (pgc->fillRule == EvenOddRule)
+ {
+ /*
+ * for each scanline
+ */
+ for (y = ET.ymin; y < ET.ymax; y++)
+ {
+ /*
+ * Add a new edge to the active edge table when we
+ * get to the next edge.
+ */
+ if (pSLL && y == pSLL->scanline)
+ {
+ miloadAET(&AET, pSLL->edgelist);
+ pSLL = pSLL->next;
+ }
+ pPrevAET = &AET;
+ pAET = AET.next;
+
+ /*
+ * for each active edge
+ */
+ while (pAET)
+ {
+ ptsOut->x = pAET->bres.minor;
+ ptsOut++->y = y;
+ *width++ = pAET->next->bres.minor - pAET->bres.minor;
+ nPts++;
+
+ /*
+ * send out the buffer when its full
+ */
+ if (nPts == NUMPTSTOBUFFER)
+ {
+ (*pgc->ops->FillSpans)(dst, pgc,
+ nPts, FirstPoint, FirstWidth,
+ 1);
+ ptsOut = FirstPoint;
+ width = FirstWidth;
+ nPts = 0;
+ }
+ EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
+ EVALUATEEDGEEVENODD(pAET, pPrevAET, y);
+ }
+ miInsertionSort(&AET);
+ }
+ }
+ else /* default to WindingNumber */
+ {
+ /*
+ * for each scanline
+ */
+ for (y = ET.ymin; y < ET.ymax; y++)
+ {
+ /*
+ * Add a new edge to the active edge table when we
+ * get to the next edge.
+ */
+ if (pSLL && y == pSLL->scanline)
+ {
+ miloadAET(&AET, pSLL->edgelist);
+ micomputeWAET(&AET);
+ pSLL = pSLL->next;
+ }
+ pPrevAET = &AET;
+ pAET = AET.next;
+ pWETE = pAET;
+
+ /*
+ * for each active edge
+ */
+ while (pAET)
+ {
+ /*
+ * if the next edge in the active edge table is
+ * also the next edge in the winding active edge
+ * table.
+ */
+ if (pWETE == pAET)
+ {
+ ptsOut->x = pAET->bres.minor;
+ ptsOut++->y = y;
+ *width++ = pAET->nextWETE->bres.minor - pAET->bres.minor;
+ nPts++;
+
+ /*
+ * send out the buffer
+ */
+ if (nPts == NUMPTSTOBUFFER)
+ {
+ (*pgc->ops->FillSpans)(dst, pgc, nPts, FirstPoint,
+ FirstWidth, 1);
+ ptsOut = FirstPoint;
+ width = FirstWidth;
+ nPts = 0;
+ }
+
+ pWETE = pWETE->nextWETE;
+ while (pWETE != pAET)
+ EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
+ pWETE = pWETE->nextWETE;
+ }
+ EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
+ }
+
+ /*
+ * reevaluate the Winding active edge table if we
+ * just had to resort it or if we just exited an edge.
+ */
+ if (miInsertionSort(&AET) || fixWAET)
+ {
+ micomputeWAET(&AET);
+ fixWAET = 0;
+ }
+ }
+ }
+
+ /*
+ * Get any spans that we missed by buffering
+ */
+ (*pgc->ops->FillSpans)(dst, pgc, nPts, FirstPoint, FirstWidth, 1);
+ DEALLOCATE_LOCAL(pETEs);
+ miFreeStorage(SLLBlock.next);
+ return(TRUE);
+}
diff --git a/xc/programs/Xserver/mi/mipolypnt.c b/xc/programs/Xserver/mi/mipolypnt.c
new file mode 100644
index 000000000..b0c77030e
--- /dev/null
+++ b/xc/programs/Xserver/mi/mipolypnt.c
@@ -0,0 +1,115 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mipolypnt.c /main/7 1998/02/09 14:47:55 kaleb $ */
+#include "X.h"
+#include "Xprotostr.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+
+void
+miPolyPoint(pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt;
+ xPoint *pptInit;
+{
+
+ int xorg;
+ int yorg;
+ int nptTmp;
+ XID fsOld, fsNew;
+ int *pwidthInit, *pwidth;
+ int i;
+ register xPoint *ppt;
+
+ /* make pointlist origin relative */
+ if (mode == CoordModePrevious)
+ {
+ ppt = pptInit;
+ nptTmp = npt;
+ nptTmp--;
+ while(nptTmp--)
+ {
+ ppt++;
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ }
+ }
+
+ if(pGC->miTranslate)
+ {
+ ppt = pptInit;
+ nptTmp = npt;
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+ while(nptTmp--)
+ {
+ ppt->x += xorg;
+ ppt++->y += yorg;
+ }
+ }
+
+ fsOld = pGC->fillStyle;
+ fsNew = FillSolid;
+ if(pGC->fillStyle != FillSolid)
+ {
+ DoChangeGC(pGC, GCFillStyle, &fsNew, 0);
+ ValidateGC(pDrawable, pGC);
+ }
+ if(!(pwidthInit = (int *)ALLOCATE_LOCAL(npt * sizeof(int))))
+ return;
+ pwidth = pwidthInit;
+ for(i = 0; i < npt; i++)
+ *pwidth++ = 1;
+ (*pGC->ops->FillSpans)(pDrawable, pGC, npt, pptInit, pwidthInit, FALSE);
+
+ if(fsOld != FillSolid)
+ {
+ DoChangeGC(pGC, GCFillStyle, &fsOld, 0);
+ ValidateGC(pDrawable, pGC);
+ }
+ DEALLOCATE_LOCAL(pwidthInit);
+}
+
diff --git a/xc/programs/Xserver/mi/mipolyrect.c b/xc/programs/Xserver/mi/mipolyrect.c
new file mode 100644
index 000000000..cd74a4831
--- /dev/null
+++ b/xc/programs/Xserver/mi/mipolyrect.c
@@ -0,0 +1,183 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mipolyrect.c /main/12 1998/02/09 14:47:59 kaleb $ */
+#include "X.h"
+#include "Xprotostr.h"
+#include "miscstruct.h"
+#include "gcstruct.h"
+#include "pixmap.h"
+
+void
+miPolyRectangle(pDraw, pGC, nrects, pRects)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int nrects;
+ xRectangle *pRects;
+{
+ int i;
+ xRectangle *pR = pRects;
+ DDXPointRec rect[5];
+ int bound_tmp;
+
+#define MINBOUND(dst,eqn) bound_tmp = eqn; \
+ if (bound_tmp < -32768) \
+ bound_tmp = -32768; \
+ dst = bound_tmp;
+
+#define MAXBOUND(dst,eqn) bound_tmp = eqn; \
+ if (bound_tmp > 32767) \
+ bound_tmp = 32767; \
+ dst = bound_tmp;
+
+#define MAXUBOUND(dst,eqn) bound_tmp = eqn; \
+ if (bound_tmp > 65535) \
+ bound_tmp = 65535; \
+ dst = bound_tmp;
+
+ if (pGC->lineStyle == LineSolid && pGC->joinStyle == JoinMiter &&
+ pGC->lineWidth != 0)
+ {
+ xRectangle *tmp, *t;
+ int ntmp;
+ int offset1, offset2, offset3;
+ int x, y, width, height;
+
+ ntmp = (nrects << 2);
+ offset2 = pGC->lineWidth;
+ offset1 = offset2 >> 1;
+ offset3 = offset2 - offset1;
+ tmp = (xRectangle *) ALLOCATE_LOCAL(ntmp * sizeof (xRectangle));
+ if (!tmp)
+ return;
+ t = tmp;
+ for (i = 0; i < nrects; i++)
+ {
+ x = pR->x;
+ y = pR->y;
+ width = pR->width;
+ height = pR->height;
+ pR++;
+ if (width == 0 && height == 0)
+ {
+ rect[0].x = x;
+ rect[0].y = y;
+ rect[1].x = x;
+ rect[1].y = y;
+ (*pGC->ops->Polylines)(pDraw, pGC, CoordModeOrigin, 2, rect);
+ }
+ else if (height < offset2 || width < offset1)
+ {
+ if (height == 0)
+ {
+ t->x = x;
+ t->width = width;
+ }
+ else
+ {
+ MINBOUND (t->x, x - offset1)
+ MAXUBOUND (t->width, width + offset2)
+ }
+ if (width == 0)
+ {
+ t->y = y;
+ t->height = height;
+ }
+ else
+ {
+ MINBOUND (t->y, y - offset1)
+ MAXUBOUND (t->height, height + offset2)
+ }
+ t++;
+ }
+ else
+ {
+ MINBOUND(t->x, x - offset1)
+ MINBOUND(t->y, y - offset1)
+ MAXUBOUND(t->width, width + offset2)
+ t->height = offset2;
+ t++;
+ MINBOUND(t->x, x - offset1)
+ MAXBOUND(t->y, y + offset3);
+ t->width = offset2;
+ t->height = height - offset2;
+ t++;
+ MAXBOUND(t->x, x + width - offset1);
+ MAXBOUND(t->y, y + offset3)
+ t->width = offset2;
+ t->height = height - offset2;
+ t++;
+ MINBOUND(t->x, x - offset1)
+ MAXBOUND(t->y, y + height - offset1)
+ MAXUBOUND(t->width, width + offset2)
+ t->height = offset2;
+ t++;
+ }
+ }
+ (*pGC->ops->PolyFillRect) (pDraw, pGC, t - tmp, tmp);
+ DEALLOCATE_LOCAL ((pointer) tmp);
+ }
+ else
+ {
+
+ for (i=0; i<nrects; i++)
+ {
+ rect[0].x = pR->x;
+ rect[0].y = pR->y;
+
+ MAXBOUND(rect[1].x, pR->x + (int) pR->width)
+ rect[1].y = rect[0].y;
+
+ rect[2].x = rect[1].x;
+ MAXBOUND(rect[2].y, pR->y + (int) pR->height);
+
+ rect[3].x = rect[0].x;
+ rect[3].y = rect[2].y;
+
+ rect[4].x = rect[0].x;
+ rect[4].y = rect[0].y;
+
+ (*pGC->ops->Polylines)(pDraw, pGC, CoordModeOrigin, 5, rect);
+ pR++;
+ }
+ }
+}
diff --git a/xc/programs/Xserver/mi/mipolyseg.c b/xc/programs/Xserver/mi/mipolyseg.c
new file mode 100644
index 000000000..a4a46779e
--- /dev/null
+++ b/xc/programs/Xserver/mi/mipolyseg.c
@@ -0,0 +1,75 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mipolyseg.c /main/5 1998/02/09 14:48:03 kaleb $ */
+#include "X.h"
+#include "Xprotostr.h"
+#include "miscstruct.h"
+#include "gcstruct.h"
+#include "pixmap.h"
+
+/*****************************************************************
+ * miPolySegment
+ *
+ * For each segment, draws a line between (x1, y1) and (x2, y2). The
+ * lines are drawn in the order listed.
+ *
+ * Walks the segments, compressing them into format for PolyLines.
+ *
+ *****************************************************************/
+
+
+void
+miPolySegment(pDraw, pGC, nseg, pSegs)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int nseg;
+ xSegment *pSegs;
+{
+ int i;
+
+ for (i=0; i<nseg; i++)
+ {
+ (*pGC->ops->Polylines)(pDraw, pGC, CoordModeOrigin, 2,(DDXPointPtr)pSegs);
+ pSegs++;
+ }
+}
diff --git a/xc/programs/Xserver/mi/mipolytext.c b/xc/programs/Xserver/mi/mipolytext.c
new file mode 100644
index 000000000..cc1db54a0
--- /dev/null
+++ b/xc/programs/Xserver/mi/mipolytext.c
@@ -0,0 +1,192 @@
+/*******************************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+************************************************************************/
+/* $TOG: mipolytext.c /main/13 1998/02/09 14:48:08 kaleb $ */
+/*
+ * mipolytext.c - text routines
+ *
+ * Author: haynes
+ * Digital Equipment Corporation
+ * Western Software Laboratory
+ * Date: Thu Feb 5 1987
+ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "gcstruct.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+
+int
+miPolyText(pDraw, pGC, x, y, count, chars, fontEncoding)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *chars;
+ FontEncoding fontEncoding;
+{
+ unsigned long n, i;
+ int w;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
+ fontEncoding, &n, charinfo);
+ w = 0;
+ for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
+ if (n != 0)
+ (*pGC->ops->PolyGlyphBlt)(
+ pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));
+ return x+w;
+}
+
+
+int
+miPolyText8(pDraw, pGC, x, y, count, chars)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *chars;
+{
+ unsigned long n, i;
+ int w;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
+ Linear8Bit, &n, charinfo);
+ w = 0;
+ for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
+ if (n != 0)
+ (*pGC->ops->PolyGlyphBlt)(
+ pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));
+ return x+w;
+}
+
+
+int
+miPolyText16(pDraw, pGC, x, y, count, chars)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ unsigned short *chars;
+{
+ unsigned long n, i;
+ int w;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, charinfo);
+ w = 0;
+ for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
+ if (n != 0)
+ (*pGC->ops->PolyGlyphBlt)(
+ pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));
+ return x+w;
+}
+
+
+int
+miImageText(pDraw, pGC, x, y, count, chars, fontEncoding)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *chars;
+ FontEncoding fontEncoding;
+{
+ unsigned long n, i;
+ FontPtr font = pGC->font;
+ int w;
+ CharInfoPtr charinfo[255];
+
+ GetGlyphs(font, (unsigned long)count, (unsigned char *)chars,
+ fontEncoding, &n, charinfo);
+ w = 0;
+ for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth;
+ if (n !=0 )
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(font));
+ return x+w;
+}
+
+
+void
+miImageText8(pDraw, pGC, x, y, count, chars)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *chars;
+{
+ unsigned long n;
+ FontPtr font = pGC->font;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ GetGlyphs(font, (unsigned long)count, (unsigned char *)chars,
+ Linear8Bit, &n, charinfo);
+ if (n !=0 )
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(font));
+}
+
+
+void
+miImageText16(pDraw, pGC, x, y, count, chars)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ unsigned short *chars;
+{
+ unsigned long n;
+ FontPtr font = pGC->font;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ GetGlyphs(font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, charinfo);
+ if (n !=0 )
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(font));
+}
diff --git a/xc/programs/Xserver/mi/mipolyutil.c b/xc/programs/Xserver/mi/mipolyutil.c
new file mode 100644
index 000000000..0bac71bbf
--- /dev/null
+++ b/xc/programs/Xserver/mi/mipolyutil.c
@@ -0,0 +1,393 @@
+/* $XFree86: xc/programs/Xserver/mi/mipolyutil.c,v 1.7 1998/10/04 09:39:31 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mipolyutil.c /main/6 1998/02/09 14:48:12 kaleb $ */
+#include "miscstruct.h"
+#include "gc.h"
+#include "miscanfill.h"
+#include "mipoly.h"
+#include "misc.h" /* MAXINT */
+
+/*
+ * fillUtils.c
+ *
+ * Written by Brian Kelleher; Oct. 1985
+ *
+ * This module contains all of the utility functions
+ * needed to scan convert a polygon.
+ *
+ */
+
+/*
+ * InsertEdgeInET
+ *
+ * Insert the given edge into the edge table.
+ * First we must find the correct bucket in the
+ * Edge table, then find the right slot in the
+ * bucket. Finally, we can insert it.
+ *
+ */
+Bool
+miInsertEdgeInET(ET, ETE, scanline, SLLBlock, iSLLBlock)
+ EdgeTable *ET;
+ EdgeTableEntry *ETE;
+ int scanline;
+ ScanLineListBlock **SLLBlock;
+ int *iSLLBlock;
+{
+ register EdgeTableEntry *start, *prev;
+ register ScanLineList *pSLL, *pPrevSLL;
+ ScanLineListBlock *tmpSLLBlock;
+
+ /*
+ * find the right bucket to put the edge into
+ */
+ pPrevSLL = &ET->scanlines;
+ pSLL = pPrevSLL->next;
+ while (pSLL && (pSLL->scanline < scanline))
+ {
+ pPrevSLL = pSLL;
+ pSLL = pSLL->next;
+ }
+
+ /*
+ * reassign pSLL (pointer to ScanLineList) if necessary
+ */
+ if ((!pSLL) || (pSLL->scanline > scanline))
+ {
+ if (*iSLLBlock > SLLSPERBLOCK-1)
+ {
+ tmpSLLBlock =
+ (ScanLineListBlock *)xalloc(sizeof(ScanLineListBlock));
+ if (!tmpSLLBlock)
+ return FALSE;
+ (*SLLBlock)->next = tmpSLLBlock;
+ tmpSLLBlock->next = (ScanLineListBlock *)NULL;
+ *SLLBlock = tmpSLLBlock;
+ *iSLLBlock = 0;
+ }
+ pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);
+
+ pSLL->next = pPrevSLL->next;
+ pSLL->edgelist = (EdgeTableEntry *)NULL;
+ pPrevSLL->next = pSLL;
+ }
+ pSLL->scanline = scanline;
+
+ /*
+ * now insert the edge in the right bucket
+ */
+ prev = (EdgeTableEntry *)NULL;
+ start = pSLL->edgelist;
+ while (start && (start->bres.minor < ETE->bres.minor))
+ {
+ prev = start;
+ start = start->next;
+ }
+ ETE->next = start;
+
+ if (prev)
+ prev->next = ETE;
+ else
+ pSLL->edgelist = ETE;
+ return TRUE;
+}
+
+/*
+ * CreateEdgeTable
+ *
+ * This routine creates the edge table for
+ * scan converting polygons.
+ * The Edge Table (ET) looks like:
+ *
+ * EdgeTable
+ * --------
+ * | ymax | ScanLineLists
+ * |scanline|-->------------>-------------->...
+ * -------- |scanline| |scanline|
+ * |edgelist| |edgelist|
+ * --------- ---------
+ * | |
+ * | |
+ * V V
+ * list of ETEs list of ETEs
+ *
+ * where ETE is an EdgeTableEntry data structure,
+ * and there is one ScanLineList per scanline at
+ * which an edge is initially entered.
+ *
+ */
+
+Bool
+miCreateETandAET(count, pts, ET, AET, pETEs, pSLLBlock)
+ register int count;
+ register DDXPointPtr pts;
+ EdgeTable *ET;
+ EdgeTableEntry *AET;
+ register EdgeTableEntry *pETEs;
+ ScanLineListBlock *pSLLBlock;
+{
+ register DDXPointPtr top, bottom;
+ register DDXPointPtr PrevPt, CurrPt;
+ int iSLLBlock = 0;
+
+ int dy;
+
+ if (count < 2) return TRUE;
+
+ /*
+ * initialize the Active Edge Table
+ */
+ AET->next = (EdgeTableEntry *)NULL;
+ AET->back = (EdgeTableEntry *)NULL;
+ AET->nextWETE = (EdgeTableEntry *)NULL;
+ AET->bres.minor = MININT;
+
+ /*
+ * initialize the Edge Table.
+ */
+ ET->scanlines.next = (ScanLineList *)NULL;
+ ET->ymax = MININT;
+ ET->ymin = MAXINT;
+ pSLLBlock->next = (ScanLineListBlock *)NULL;
+
+ PrevPt = &pts[count-1];
+
+ /*
+ * for each vertex in the array of points.
+ * In this loop we are dealing with two vertices at
+ * a time -- these make up one edge of the polygon.
+ */
+ while (count--)
+ {
+ CurrPt = pts++;
+
+ /*
+ * find out which point is above and which is below.
+ */
+ if (PrevPt->y > CurrPt->y)
+ {
+ bottom = PrevPt, top = CurrPt;
+ pETEs->ClockWise = 0;
+ }
+ else
+ {
+ bottom = CurrPt, top = PrevPt;
+ pETEs->ClockWise = 1;
+ }
+
+ /*
+ * don't add horizontal edges to the Edge table.
+ */
+ if (bottom->y != top->y)
+ {
+ pETEs->ymax = bottom->y-1; /* -1 so we don't get last scanline */
+
+ /*
+ * initialize integer edge algorithm
+ */
+ dy = bottom->y - top->y;
+ BRESINITPGONSTRUCT(dy, top->x, bottom->x, pETEs->bres);
+
+ if (!miInsertEdgeInET(ET, pETEs, top->y, &pSLLBlock, &iSLLBlock))
+ {
+ miFreeStorage(pSLLBlock->next);
+ return FALSE;
+ }
+
+ ET->ymax = max(ET->ymax, PrevPt->y);
+ ET->ymin = min(ET->ymin, PrevPt->y);
+ pETEs++;
+ }
+
+ PrevPt = CurrPt;
+ }
+ return TRUE;
+}
+
+/*
+ * loadAET
+ *
+ * This routine moves EdgeTableEntries from the
+ * EdgeTable into the Active Edge Table,
+ * leaving them sorted by smaller x coordinate.
+ *
+ */
+
+void
+miloadAET(AET, ETEs)
+ register EdgeTableEntry *AET, *ETEs;
+{
+ register EdgeTableEntry *pPrevAET;
+ register EdgeTableEntry *tmp;
+
+ pPrevAET = AET;
+ AET = AET->next;
+ while (ETEs)
+ {
+ while (AET && (AET->bres.minor < ETEs->bres.minor))
+ {
+ pPrevAET = AET;
+ AET = AET->next;
+ }
+ tmp = ETEs->next;
+ ETEs->next = AET;
+ if (AET)
+ AET->back = ETEs;
+ ETEs->back = pPrevAET;
+ pPrevAET->next = ETEs;
+ pPrevAET = ETEs;
+
+ ETEs = tmp;
+ }
+}
+
+/*
+ * computeWAET
+ *
+ * This routine links the AET by the
+ * nextWETE (winding EdgeTableEntry) link for
+ * use by the winding number rule. The final
+ * Active Edge Table (AET) might look something
+ * like:
+ *
+ * AET
+ * ---------- --------- ---------
+ * |ymax | |ymax | |ymax |
+ * | ... | |... | |... |
+ * |next |->|next |->|next |->...
+ * |nextWETE| |nextWETE| |nextWETE|
+ * --------- --------- ^--------
+ * | | |
+ * V-------------------> V---> ...
+ *
+ */
+void
+micomputeWAET(AET)
+ register EdgeTableEntry *AET;
+{
+ register EdgeTableEntry *pWETE;
+ register int inside = 1;
+ register int isInside = 0;
+
+ AET->nextWETE = (EdgeTableEntry *)NULL;
+ pWETE = AET;
+ AET = AET->next;
+ while (AET)
+ {
+ if (AET->ClockWise)
+ isInside++;
+ else
+ isInside--;
+
+ if ((!inside && !isInside) ||
+ ( inside && isInside))
+ {
+ pWETE->nextWETE = AET;
+ pWETE = AET;
+ inside = !inside;
+ }
+ AET = AET->next;
+ }
+ pWETE->nextWETE = (EdgeTableEntry *)NULL;
+}
+
+/*
+ * InsertionSort
+ *
+ * Just a simple insertion sort using
+ * pointers and back pointers to sort the Active
+ * Edge Table.
+ *
+ */
+
+int
+miInsertionSort(AET)
+ register EdgeTableEntry *AET;
+{
+ register EdgeTableEntry *pETEchase;
+ register EdgeTableEntry *pETEinsert;
+ register EdgeTableEntry *pETEchaseBackTMP;
+ register int changed = 0;
+
+ AET = AET->next;
+ while (AET)
+ {
+ pETEinsert = AET;
+ pETEchase = AET;
+ while (pETEchase->back->bres.minor > AET->bres.minor)
+ pETEchase = pETEchase->back;
+
+ AET = AET->next;
+ if (pETEchase != pETEinsert)
+ {
+ pETEchaseBackTMP = pETEchase->back;
+ pETEinsert->back->next = AET;
+ if (AET)
+ AET->back = pETEinsert->back;
+ pETEinsert->next = pETEchase;
+ pETEchase->back->next = pETEinsert;
+ pETEchase->back = pETEinsert;
+ pETEinsert->back = pETEchaseBackTMP;
+ changed = 1;
+ }
+ }
+ return(changed);
+}
+
+/*
+ * Clean up our act.
+ */
+void
+miFreeStorage(pSLLBlock)
+ register ScanLineListBlock *pSLLBlock;
+{
+ register ScanLineListBlock *tmpSLLBlock;
+
+ while (pSLLBlock)
+ {
+ tmpSLLBlock = pSLLBlock->next;
+ xfree(pSLLBlock);
+ pSLLBlock = tmpSLLBlock;
+ }
+}
diff --git a/xc/programs/Xserver/mi/mipushpxl.c b/xc/programs/Xserver/mi/mipushpxl.c
new file mode 100644
index 000000000..f2fabd7a9
--- /dev/null
+++ b/xc/programs/Xserver/mi/mipushpxl.c
@@ -0,0 +1,252 @@
+/* $XFree86: xc/programs/Xserver/mi/mipushpxl.c,v 3.9 1998/12/20 11:57:58 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mipushpxl.c /main/12 1998/02/09 14:48:25 kaleb $ */
+#include "X.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "miscstruct.h"
+#include "../mfb/maskbits.h"
+
+#define NPT 128
+
+/* miPushPixels -- squeegees the fill style of pGC through pBitMap
+ * into pDrawable. pBitMap is a stencil (dx by dy of it is used, it may
+ * be bigger) which is placed on the drawable at xOrg, yOrg. Where a 1 bit
+ * is set in the bitmap, the fill style is put onto the drawable using
+ * the GC's logical function. The drawable is not changed where the bitmap
+ * has a zero bit or outside the area covered by the stencil.
+
+WARNING:
+ this code works if the 1-bit deep pixmap format returned by GetSpans
+is the same as the format defined by the mfb code (i.e. 32-bit padding
+per scanline, scanline unit = 32 bits; later, this might mean
+bitsizeof(int) padding and sacnline unit == bitsizeof(int).)
+
+ */
+
+/*
+ * in order to have both (MSB_FIRST and LSB_FIRST) versions of this
+ * in the server, we need to rename one of them
+ */
+void
+miPushPixels(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg)
+ GCPtr pGC;
+ PixmapPtr pBitMap;
+ DrawablePtr pDrawable;
+ int dx, dy, xOrg, yOrg;
+{
+ int h, dxDivPPW, ibEnd;
+ unsigned long *pwLineStart;
+ register unsigned long *pw, *pwEnd;
+ register unsigned long msk;
+ register int ib, w;
+ register int ipt; /* index into above arrays */
+ Bool fInBox;
+ DDXPointRec pt[NPT], ptThisLine;
+ int width[NPT];
+#ifdef XFree86Server
+ PixelType startmask;
+ if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ startmask = (unsigned long)(-1) ^
+ LONG2CHARSSAMEORDER((unsigned long)(-1) << 1);
+ else
+ startmask = (unsigned long)(-1) ^
+ LONG2CHARSSAMEORDER((unsigned long)(-1) >> 1);
+ else
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ startmask = (unsigned long)(-1) ^
+ LONG2CHARSDIFFORDER((unsigned long)(-1) << 1);
+ else
+ startmask = (unsigned long)(-1) ^
+ LONG2CHARSDIFFORDER((unsigned long)(-1) >> 1);
+#endif
+
+ pwLineStart = (unsigned long *)xalloc(BitmapBytePad(dx));
+ if (!pwLineStart)
+ return;
+ ipt = 0;
+ dxDivPPW = dx/PPW;
+
+ for(h = 0, ptThisLine.x = 0, ptThisLine.y = 0;
+ h < dy;
+ h++, ptThisLine.y++)
+ {
+
+ (*pBitMap->drawable.pScreen->GetSpans)((DrawablePtr)pBitMap, dx,
+ &ptThisLine, &dx, 1, (char *)pwLineStart);
+
+ pw = pwLineStart;
+ /* Process all words which are fully in the pixmap */
+
+ fInBox = FALSE;
+ pwEnd = pwLineStart + dxDivPPW;
+ while(pw < pwEnd)
+ {
+ w = *pw;
+#ifdef XFree86Server
+ msk = startmask;
+#else
+ msk = (unsigned long)(-1) ^ SCRRIGHT((unsigned long)(-1), 1);
+#endif
+ for(ib = 0; ib < PPW; ib++)
+ {
+ if(w & msk)
+ {
+ if(!fInBox)
+ {
+ pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
+ pt[ipt].y = h + yOrg;
+ /* start new box */
+ fInBox = TRUE;
+ }
+ }
+ else
+ {
+ if(fInBox)
+ {
+ width[ipt] = ((pw - pwLineStart) << PWSH) +
+ ib + xOrg - pt[ipt].x;
+ if (++ipt >= NPT)
+ {
+ (*pGC->ops->FillSpans)(pDrawable, pGC,
+ NPT, pt, width, TRUE);
+ ipt = 0;
+ }
+ /* end box */
+ fInBox = FALSE;
+ }
+ }
+#ifdef XFree86Server
+ /* This is not quite right, but it'll do for now */
+ if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1);
+ else
+ msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1);
+ else
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1);
+ else
+ msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1);
+#else
+ msk = SCRRIGHT(msk, 1);
+#endif
+ }
+ pw++;
+ }
+ ibEnd = dx & PIM;
+ if(ibEnd)
+ {
+ /* Process final partial word on line */
+ w = *pw;
+#ifdef XFree86Server
+ msk = startmask;
+#else
+ msk = (unsigned long)(-1) ^ SCRRIGHT((unsigned long)(-1), 1);
+#endif
+ for(ib = 0; ib < ibEnd; ib++)
+ {
+ if(w & msk)
+ {
+ if(!fInBox)
+ {
+ /* start new box */
+ pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg;
+ pt[ipt].y = h + yOrg;
+ fInBox = TRUE;
+ }
+ }
+ else
+ {
+ if(fInBox)
+ {
+ /* end box */
+ width[ipt] = ((pw - pwLineStart) << PWSH) +
+ ib + xOrg - pt[ipt].x;
+ if (++ipt >= NPT)
+ {
+ (*pGC->ops->FillSpans)(pDrawable,
+ pGC, NPT, pt, width, TRUE);
+ ipt = 0;
+ }
+ fInBox = FALSE;
+ }
+ }
+#ifdef XFree86Server
+ /* This is not quite right, but it'll do for now */
+ if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER)
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1);
+ else
+ msk = LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1);
+ else
+ if (screenInfo.bitmapBitOrder == LSBFirst)
+ msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1);
+ else
+ msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1);
+#else
+ msk = SCRRIGHT(msk, 1);
+#endif
+ }
+ }
+ /* If scanline ended with last bit set, end the box */
+ if(fInBox)
+ {
+ width[ipt] = dx + xOrg - pt[ipt].x;
+ if (++ipt >= NPT)
+ {
+ (*pGC->ops->FillSpans)(pDrawable, pGC, NPT, pt, width, TRUE);
+ ipt = 0;
+ }
+ }
+ }
+ xfree(pwLineStart);
+ /* Flush any remaining spans */
+ if (ipt)
+ {
+ (*pGC->ops->FillSpans)(pDrawable, pGC, ipt, pt, width, TRUE);
+ }
+}
diff --git a/xc/programs/Xserver/mi/miregion.c b/xc/programs/Xserver/mi/miregion.c
new file mode 100644
index 000000000..386b21de1
--- /dev/null
+++ b/xc/programs/Xserver/mi/miregion.c
@@ -0,0 +1,2468 @@
+/* $XFree86: xc/programs/Xserver/mi/miregion.c,v 1.4 1999/02/12 22:52:12 hohndel Exp $ */
+/***********************************************************
+
+Copyright 1987, 1988, 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987, 1988, 1989 by
+Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* The panoramix components contained the following notice */
+/****************************************************************
+* *
+* Copyright (c) Digital Equipment Corporation, 1991, 1997 *
+* *
+* All Rights Reserved. Unpublished rights reserved under *
+* the copyright laws of the United States. *
+* *
+* The software contained on this media is proprietary to *
+* and embodies the confidential technology of Digital *
+* Equipment Corporation. Possession, use, duplication or *
+* dissemination of the software and media is authorized only *
+* pursuant to a valid written license from Digital Equipment *
+* Corporation. *
+* *
+* RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure *
+* by the U.S. Government is subject to restrictions as set *
+* forth in Subparagraph (c)(1)(ii) of DFARS 252.227-7013, *
+* or in FAR 52.227-19, as applicable. *
+* *
+*****************************************************************/
+
+/* $TOG: miregion.c /main/40 1998/02/09 14:48:29 kaleb $ */
+
+#include "miscstruct.h"
+#include "regionstr.h"
+#include "Xprotostr.h"
+#include "gc.h"
+
+#if defined (__GNUC__) && !defined (NO_INLINES)
+#define INLINE __inline
+#else
+#define INLINE
+#endif
+
+/*
+ * hack until callers of these functions can deal with out-of-memory
+ */
+
+extern Bool Must_have_memory;
+
+#undef assert
+#ifdef DEBUG
+#define assert(expr) {if (!(expr)) \
+ FatalError("Assertion failed file %s, line %d: expr\n", \
+ __FILE__, __LINE__); }
+#else
+#define assert(expr)
+#endif
+
+#define good(reg) assert(miValidRegion(reg))
+
+/*
+ * The functions in this file implement the Region abstraction used extensively
+ * throughout the X11 sample server. A Region is simply a set of disjoint
+ * (non-overlapping) rectangles, plus an "extent" rectangle which is the
+ * smallest single rectangle that contains all the non-overlapping rectangles.
+ *
+ * A Region is implemented as a "y-x-banded" array of rectangles. This array
+ * imposes two degrees of order. First, all rectangles are sorted by top side
+ * y coordinate first (y1), and then by left side x coordinate (x1).
+ *
+ * Furthermore, the rectangles are grouped into "bands". Each rectangle in a
+ * band has the same top y coordinate (y1), and each has the same bottom y
+ * coordinate (y2). Thus all rectangles in a band differ only in their left
+ * and right side (x1 and x2). Bands are implicit in the array of rectangles:
+ * there is no separate list of band start pointers.
+ *
+ * The y-x band representation does not minimize rectangles. In particular,
+ * if a rectangle vertically crosses a band (the rectangle has scanlines in
+ * the y1 to y2 area spanned by the band), then the rectangle may be broken
+ * down into two or more smaller rectangles stacked one atop the other.
+ *
+ * ----------- -----------
+ * | | | | band 0
+ * | | -------- ----------- --------
+ * | | | | in y-x banded | | | | band 1
+ * | | | | form is | | | |
+ * ----------- | | ----------- --------
+ * | | | | band 2
+ * -------- --------
+ *
+ * An added constraint on the rectangles is that they must cover as much
+ * horizontal area as possible: no two rectangles within a band are allowed
+ * to touch.
+ *
+ * Whenever possible, bands will be merged together to cover a greater vertical
+ * distance (and thus reduce the number of rectangles). Two bands can be merged
+ * only if the bottom of one touches the top of the other and they have
+ * rectangles in the same places (of the same width, of course).
+ *
+ * Adam de Boor wrote most of the original region code. Joel McCormack
+ * substantially modified or rewrote most of the core arithmetic routines,
+ * and added miRegionValidate in order to support several speed improvements
+ * to miValidateTree. Bob Scheifler changed the representation to be more
+ * compact when empty or a single rectangle, and did a bunch of gratuitous
+ * reformatting.
+ */
+
+/* true iff two Boxes overlap */
+#define EXTENTCHECK(r1,r2) \
+ (!( ((r1)->x2 <= (r2)->x1) || \
+ ((r1)->x1 >= (r2)->x2) || \
+ ((r1)->y2 <= (r2)->y1) || \
+ ((r1)->y1 >= (r2)->y2) ) )
+
+/* true iff (x,y) is in Box */
+#define INBOX(r,x,y) \
+ ( ((r)->x2 > x) && \
+ ((r)->x1 <= x) && \
+ ((r)->y2 > y) && \
+ ((r)->y1 <= y) )
+
+/* true iff Box r1 contains Box r2 */
+#define SUBSUMES(r1,r2) \
+ ( ((r1)->x1 <= (r2)->x1) && \
+ ((r1)->x2 >= (r2)->x2) && \
+ ((r1)->y1 <= (r2)->y1) && \
+ ((r1)->y2 >= (r2)->y2) )
+
+#define xallocData(n) (RegDataPtr)xalloc(REGION_SZOF(n))
+#define xfreeData(reg) if ((reg)->data && (reg)->data->size) xfree((reg)->data)
+
+#define RECTALLOC(pReg,n) \
+if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \
+ miRectAlloc(pReg, n)
+
+#define ADDRECT(pNextRect,nx1,ny1,nx2,ny2) \
+{ \
+ pNextRect->x1 = nx1; \
+ pNextRect->y1 = ny1; \
+ pNextRect->x2 = nx2; \
+ pNextRect->y2 = ny2; \
+ pNextRect++; \
+}
+
+#define NEWRECT(pReg,pNextRect,nx1,ny1,nx2,ny2) \
+{ \
+ if (!(pReg)->data || ((pReg)->data->numRects == (pReg)->data->size))\
+ { \
+ miRectAlloc(pReg, 1); \
+ pNextRect = REGION_TOP(pReg); \
+ } \
+ ADDRECT(pNextRect,nx1,ny1,nx2,ny2); \
+ pReg->data->numRects++; \
+ assert(pReg->data->numRects<=pReg->data->size); \
+}
+
+
+#define DOWNSIZE(reg,numRects) \
+if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \
+{ \
+ RegDataPtr NewData; \
+ NewData = (RegDataPtr)xrealloc((reg)->data, REGION_SZOF(numRects)); \
+ if (NewData) \
+ { \
+ NewData->size = (numRects); \
+ (reg)->data = NewData; \
+ } \
+}
+
+
+BoxRec miEmptyBox = {0, 0, 0, 0};
+RegDataRec miEmptyData = {0, 0};
+
+#ifdef DEBUG
+int
+miPrintRegion(rgn)
+ RegionPtr rgn;
+{
+ int num, size;
+ register int i;
+ BoxPtr rects;
+
+ num = REGION_NUM_RECTS(rgn);
+ size = REGION_SIZE(rgn);
+ rects = REGION_RECTS(rgn);
+ ErrorF("num: %d size: %d\n", num, size);
+ ErrorF("extents: %d %d %d %d\n",
+ rgn->extents.x1, rgn->extents.y1, rgn->extents.x2, rgn->extents.y2);
+ for (i = 0; i < num; i++)
+ ErrorF("%d %d %d %d \n",
+ rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2);
+ ErrorF("\n");
+ return(num);
+}
+
+
+Bool
+miRegionsEqual(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;
+}
+
+Bool
+miValidRegion(reg)
+ RegionPtr reg;
+{
+ register int i, numRects;
+
+ if ((reg->extents.x1 > reg->extents.x2) ||
+ (reg->extents.y1 > reg->extents.y2))
+ return FALSE;
+ numRects = REGION_NUM_RECTS(reg);
+ if (!numRects)
+ return ((reg->extents.x1 == reg->extents.x2) &&
+ (reg->extents.y1 == reg->extents.y2) &&
+ (reg->data->size || (reg->data == &miEmptyData)));
+ else if (numRects == 1)
+ return (!reg->data);
+ else
+ {
+ register BoxPtr pboxP, pboxN;
+ BoxRec box;
+
+ pboxP = REGION_RECTS(reg);
+ box = *pboxP;
+ box.y2 = pboxP[numRects-1].y2;
+ pboxN = pboxP + 1;
+ for (i = numRects; --i > 0; pboxP++, pboxN++)
+ {
+ if ((pboxN->x1 >= pboxN->x2) ||
+ (pboxN->y1 >= pboxN->y2))
+ return FALSE;
+ if (pboxN->x1 < box.x1)
+ box.x1 = pboxN->x1;
+ if (pboxN->x2 > box.x2)
+ box.x2 = pboxN->x2;
+ if ((pboxN->y1 < pboxP->y1) ||
+ ((pboxN->y1 == pboxP->y1) &&
+ ((pboxN->x1 < pboxP->x2) || (pboxN->y2 != pboxP->y2))))
+ return FALSE;
+ }
+ return ((box.x1 == reg->extents.x1) &&
+ (box.x2 == reg->extents.x2) &&
+ (box.y1 == reg->extents.y1) &&
+ (box.y2 == reg->extents.y2));
+ }
+}
+
+#endif /* DEBUG */
+
+
+/*****************************************************************
+ * RegionCreate(rect, size)
+ * This routine does a simple malloc to make a structure of
+ * REGION of "size" number of rectangles.
+ *****************************************************************/
+
+RegionPtr
+miRegionCreate(rect, size)
+ BoxPtr rect;
+ int size;
+{
+ register RegionPtr pReg;
+
+ Must_have_memory = TRUE; /* XXX */
+ pReg = (RegionPtr)xalloc(sizeof(RegionRec));
+ Must_have_memory = FALSE; /* XXX */
+ if (rect)
+ {
+ pReg->extents = *rect;
+ pReg->data = (RegDataPtr)NULL;
+ }
+ else
+ {
+ pReg->extents = miEmptyBox;
+ if ((size > 1) && (pReg->data = xallocData(size)))
+ {
+ pReg->data->size = size;
+ pReg->data->numRects = 0;
+ }
+ else
+ pReg->data = &miEmptyData;
+ }
+ return(pReg);
+}
+
+/*****************************************************************
+ * RegionInit(pReg, rect, size)
+ * Outer region rect is statically allocated.
+ *****************************************************************/
+
+void
+miRegionInit(pReg, rect, size)
+ RegionPtr pReg;
+ BoxPtr rect;
+ int size;
+{
+ if (rect)
+ {
+ pReg->extents = *rect;
+ pReg->data = (RegDataPtr)NULL;
+ }
+ else
+ {
+ pReg->extents = miEmptyBox;
+ if ((size > 1) && (pReg->data = xallocData(size)))
+ {
+ pReg->data->size = size;
+ pReg->data->numRects = 0;
+ }
+ else
+ pReg->data = &miEmptyData;
+ }
+}
+
+void
+miRegionDestroy(pReg)
+ RegionPtr pReg;
+{
+ good(pReg);
+ xfreeData(pReg);
+ xfree(pReg);
+}
+
+void
+miRegionUninit(pReg)
+ RegionPtr pReg;
+{
+ good(pReg);
+ xfreeData(pReg);
+}
+
+Bool
+miRectAlloc(pRgn, n)
+ register RegionPtr pRgn;
+ int n;
+{
+ Must_have_memory = TRUE; /* XXX */
+ if (!pRgn->data)
+ {
+ n++;
+ pRgn->data = xallocData(n);
+ pRgn->data->numRects = 1;
+ *REGION_BOXPTR(pRgn) = pRgn->extents;
+ }
+ else if (!pRgn->data->size)
+ {
+ pRgn->data = xallocData(n);
+ pRgn->data->numRects = 0;
+ }
+ else
+ {
+ if (n == 1)
+ {
+ n = pRgn->data->numRects;
+ if (n > 500) /* XXX pick numbers out of a hat */
+ n = 250;
+ }
+ n += pRgn->data->numRects;
+ pRgn->data = (RegDataPtr)xrealloc(pRgn->data, REGION_SZOF(n));
+ }
+ Must_have_memory = FALSE; /* XXX */
+ pRgn->data->size = n;
+ return TRUE;
+}
+
+Bool
+miRegionCopy(dst, src)
+ register RegionPtr dst;
+ register RegionPtr src;
+{
+ good(dst);
+ good(src);
+ if (dst == src)
+ return TRUE;
+ dst->extents = src->extents;
+ if (!src->data || !src->data->size)
+ {
+ xfreeData(dst);
+ dst->data = src->data;
+ return TRUE;
+ }
+ if (!dst->data || (dst->data->size < src->data->numRects))
+ {
+ xfreeData(dst);
+ Must_have_memory = TRUE; /* XXX */
+ dst->data = xallocData(src->data->numRects);
+ Must_have_memory = FALSE; /* XXX */
+ dst->data->size = src->data->numRects;
+ }
+ dst->data->numRects = src->data->numRects;
+ memmove((char *)REGION_BOXPTR(dst),(char *)REGION_BOXPTR(src),
+ dst->data->numRects * sizeof(BoxRec));
+ return TRUE;
+}
+
+
+/*======================================================================
+ * Generic Region Operator
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * miCoalesce --
+ * Attempt to merge the boxes in the current band with those in the
+ * previous one. We are guaranteed that the current band extends to
+ * the end of the rects array. Used only by miRegionOp.
+ *
+ * Results:
+ * The new index for the previous band.
+ *
+ * Side Effects:
+ * If coalescing takes place:
+ * - rectangles in the previous band will have their y2 fields
+ * altered.
+ * - pReg->data->numRects will be decreased.
+ *
+ *-----------------------------------------------------------------------
+ */
+INLINE static int
+miCoalesce (pReg, prevStart, curStart)
+ register RegionPtr pReg; /* Region to coalesce */
+ int prevStart; /* Index of start of previous band */
+ int curStart; /* Index of start of current band */
+{
+ register BoxPtr pPrevBox; /* Current box in previous band */
+ register BoxPtr pCurBox; /* Current box in current band */
+ register int numRects; /* Number rectangles in both bands */
+ register int y2; /* Bottom of current band */
+ /*
+ * Figure out how many rectangles are in the band.
+ */
+ numRects = curStart - prevStart;
+ assert(numRects == pReg->data->numRects - curStart);
+
+ if (!numRects) return curStart;
+
+ /*
+ * The bands may only be coalesced if the bottom of the previous
+ * matches the top scanline of the current.
+ */
+ pPrevBox = REGION_BOX(pReg, prevStart);
+ pCurBox = REGION_BOX(pReg, curStart);
+ if (pPrevBox->y2 != pCurBox->y1) return curStart;
+
+ /*
+ * Make sure the bands have boxes in the same places. This
+ * assumes that boxes have been added in such a way that they
+ * cover the most area possible. I.e. two boxes in a band must
+ * have some horizontal space between them.
+ */
+ y2 = pCurBox->y2;
+
+ do {
+ if ((pPrevBox->x1 != pCurBox->x1) || (pPrevBox->x2 != pCurBox->x2)) {
+ return (curStart);
+ }
+ pPrevBox++;
+ pCurBox++;
+ numRects--;
+ } while (numRects);
+
+ /*
+ * The bands may be merged, so set the bottom y of each box
+ * in the previous band to the bottom y of the current band.
+ */
+ numRects = curStart - prevStart;
+ pReg->data->numRects -= numRects;
+ do {
+ pPrevBox--;
+ pPrevBox->y2 = y2;
+ numRects--;
+ } while (numRects);
+ return prevStart;
+}
+
+
+/* Quicky macro to avoid trivial reject procedure calls to miCoalesce */
+
+#define Coalesce(newReg, prevBand, curBand) \
+ if (curBand - prevBand == newReg->data->numRects - curBand) { \
+ prevBand = miCoalesce(newReg, prevBand, curBand); \
+ } else { \
+ prevBand = curBand; \
+ }
+
+/*-
+ *-----------------------------------------------------------------------
+ * miAppendNonO --
+ * Handle a non-overlapping band for the union and subtract operations.
+ * Just adds the (top/bottom-clipped) rectangles into the region.
+ * Doesn't have to check for subsumption or anything.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * pReg->data->numRects is incremented and the rectangles overwritten
+ * with the rectangles we're passed.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+INLINE static Bool
+miAppendNonO (pReg, r, rEnd, y1, y2)
+ register RegionPtr pReg;
+ register BoxPtr r;
+ BoxPtr rEnd;
+ register int y1;
+ register int y2;
+{
+ register BoxPtr pNextRect;
+ register int newRects;
+
+ newRects = rEnd - r;
+
+ assert(y1 < y2);
+ assert(newRects != 0);
+
+ /* Make sure we have enough space for all rectangles to be added */
+ RECTALLOC(pReg, newRects);
+ pNextRect = REGION_TOP(pReg);
+ pReg->data->numRects += newRects;
+ do {
+ assert(r->x1 < r->x2);
+ ADDRECT(pNextRect, r->x1, y1, r->x2, y2);
+ r++;
+ } while (r != rEnd);
+
+ return TRUE;
+}
+
+#define FindBand(r, rBandEnd, rEnd, ry1) \
+{ \
+ ry1 = r->y1; \
+ rBandEnd = r+1; \
+ while ((rBandEnd != rEnd) && (rBandEnd->y1 == ry1)) { \
+ rBandEnd++; \
+ } \
+}
+
+#define AppendRegions(newReg, r, rEnd) \
+{ \
+ int newRects; \
+ if (newRects = rEnd - r) { \
+ RECTALLOC(newReg, newRects); \
+ memmove((char *)REGION_TOP(newReg),(char *)r, \
+ newRects * sizeof(BoxRec)); \
+ newReg->data->numRects += newRects; \
+ } \
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miRegionOp --
+ * Apply an operation to two regions. Called by miUnion, miInverse,
+ * miSubtract, miIntersect.... Both regions MUST have at least one
+ * rectangle, and cannot be the same object.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * The new region is overwritten.
+ * pOverlap set to TRUE if overlapFunc ever returns TRUE.
+ *
+ * Notes:
+ * The idea behind this function is to view the two regions as sets.
+ * Together they cover a rectangle of area that this function divides
+ * into horizontal bands where points are covered only by one region
+ * or by both. For the first case, the nonOverlapFunc is called with
+ * each the band and the band's upper and lower extents. For the
+ * second, the overlapFunc is called to process the entire band. It
+ * is responsible for clipping the rectangles in the band, though
+ * this function provides the boundaries.
+ * At the end of each band, the new region is coalesced, if possible,
+ * to reduce the number of rectangles in the region.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Bool
+miRegionOp(newReg, reg1, reg2, overlapFunc, appendNon1, appendNon2, pOverlap)
+ RegionPtr newReg; /* Place to store result */
+ RegionPtr reg1; /* First region in operation */
+ RegionPtr reg2; /* 2d region in operation */
+ Bool (*overlapFunc)(); /* Function to call for over-
+ * lapping bands */
+ Bool appendNon1; /* Append non-overlapping bands */
+ /* in region 1 ? */
+ Bool appendNon2; /* Append non-overlapping bands */
+ /* in region 2 ? */
+ Bool *pOverlap;
+{
+ register BoxPtr r1; /* Pointer into first region */
+ register BoxPtr r2; /* Pointer into 2d region */
+ BoxPtr r1End; /* End of 1st region */
+ BoxPtr r2End; /* End of 2d region */
+ short ybot; /* Bottom of intersection */
+ short ytop; /* Top of intersection */
+ RegDataPtr oldData; /* Old data for newReg */
+ int prevBand; /* Index of start of
+ * previous band in newReg */
+ int curBand; /* Index of start of current
+ * band in newReg */
+ register BoxPtr r1BandEnd; /* End of current band in r1 */
+ register BoxPtr r2BandEnd; /* End of current band in r2 */
+ short top; /* Top of non-overlapping band */
+ short bot; /* Bottom of non-overlapping band*/
+ register int r1y1; /* Temps for r1->y1 and r2->y1 */
+ register int r2y1;
+ int newSize;
+ int numRects;
+
+ /*
+ * Initialization:
+ * set r1, r2, r1End and r2End appropriately, save the rectangles
+ * of the destination region until the end in case it's one of
+ * the two source regions, then mark the "new" region empty, allocating
+ * another array of rectangles for it to use.
+ */
+
+ r1 = REGION_RECTS(reg1);
+ newSize = REGION_NUM_RECTS(reg1);
+ r1End = r1 + newSize;
+ numRects = REGION_NUM_RECTS(reg2);
+ r2 = REGION_RECTS(reg2);
+ r2End = r2 + numRects;
+ assert(r1 != r1End);
+ assert(r2 != r2End);
+
+ oldData = (RegDataPtr)NULL;
+ if (((newReg == reg1) && (newSize > 1)) ||
+ ((newReg == reg2) && (numRects > 1)))
+ {
+ oldData = newReg->data;
+ newReg->data = &miEmptyData;
+ }
+ /* guess at new size */
+ if (numRects > newSize)
+ newSize = numRects;
+ newSize <<= 1;
+ if (!newReg->data)
+ newReg->data = &miEmptyData;
+ else if (newReg->data->size)
+ newReg->data->numRects = 0;
+ if (newSize > newReg->data->size)
+ miRectAlloc(newReg, newSize);
+
+ /*
+ * Initialize ybot.
+ * In the upcoming loop, ybot and ytop serve different functions depending
+ * on whether the band being handled is an overlapping or non-overlapping
+ * band.
+ * In the case of a non-overlapping band (only one of the regions
+ * has points in the band), ybot is the bottom of the most recent
+ * intersection and thus clips the top of the rectangles in that band.
+ * ytop is the top of the next intersection between the two regions and
+ * serves to clip the bottom of the rectangles in the current band.
+ * For an overlapping band (where the two regions intersect), ytop clips
+ * the top of the rectangles of both regions and ybot clips the bottoms.
+ */
+
+ ybot = min(r1->y1, r2->y1);
+
+ /*
+ * prevBand serves to mark the start of the previous band so rectangles
+ * can be coalesced into larger rectangles. qv. miCoalesce, above.
+ * In the beginning, there is no previous band, so prevBand == curBand
+ * (curBand is set later on, of course, but the first band will always
+ * start at index 0). prevBand and curBand must be indices because of
+ * the possible expansion, and resultant moving, of the new region's
+ * array of rectangles.
+ */
+ prevBand = 0;
+
+ do {
+ /*
+ * This algorithm proceeds one source-band (as opposed to a
+ * destination band, which is determined by where the two regions
+ * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the
+ * rectangle after the last one in the current band for their
+ * respective regions.
+ */
+ assert(r1 != r1End);
+ assert(r2 != r2End);
+
+ FindBand(r1, r1BandEnd, r1End, r1y1);
+ FindBand(r2, r2BandEnd, r2End, r2y1);
+
+ /*
+ * First handle the band that doesn't intersect, if any.
+ *
+ * Note that attention is restricted to one band in the
+ * non-intersecting region at once, so if a region has n
+ * bands between the current position and the next place it overlaps
+ * the other, this entire loop will be passed through n times.
+ */
+ if (r1y1 < r2y1) {
+ if (appendNon1) {
+ top = max(r1y1, ybot);
+ bot = min(r1->y2, r2y1);
+ if (top != bot) {
+ curBand = newReg->data->numRects;
+ miAppendNonO(newReg, r1, r1BandEnd, top, bot);
+ Coalesce(newReg, prevBand, curBand);
+ }
+ }
+ ytop = r2y1;
+ } else if (r2y1 < r1y1) {
+ if (appendNon2) {
+ top = max(r2y1, ybot);
+ bot = min(r2->y2, r1y1);
+ if (top != bot) {
+ curBand = newReg->data->numRects;
+ miAppendNonO(newReg, r2, r2BandEnd, top, bot);
+ Coalesce(newReg, prevBand, curBand);
+ }
+ }
+ ytop = r1y1;
+ } else {
+ ytop = r1y1;
+ }
+
+ /*
+ * Now see if we've hit an intersecting band. The two bands only
+ * intersect if ybot > ytop
+ */
+ ybot = min(r1->y2, r2->y2);
+ if (ybot > ytop) {
+ curBand = newReg->data->numRects;
+ (* overlapFunc)(newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot,
+ pOverlap);
+ Coalesce(newReg, prevBand, curBand);
+ }
+
+ /*
+ * If we've finished with a band (y2 == ybot) we skip forward
+ * in the region to the next band.
+ */
+ if (r1->y2 == ybot) r1 = r1BandEnd;
+ if (r2->y2 == ybot) r2 = r2BandEnd;
+
+ } while (r1 != r1End && r2 != r2End);
+
+ /*
+ * Deal with whichever region (if any) still has rectangles left.
+ *
+ * We only need to worry about banding and coalescing for the very first
+ * band left. After that, we can just group all remaining boxes,
+ * regardless of how many bands, into one final append to the list.
+ */
+
+ if ((r1 != r1End) && appendNon1) {
+ /* Do first nonOverlap1Func call, which may be able to coalesce */
+ FindBand(r1, r1BandEnd, r1End, r1y1);
+ curBand = newReg->data->numRects;
+ miAppendNonO(newReg, r1, r1BandEnd, max(r1y1, ybot), r1->y2);
+ Coalesce(newReg, prevBand, curBand);
+ /* Just append the rest of the boxes */
+ AppendRegions(newReg, r1BandEnd, r1End);
+
+ } else if ((r2 != r2End) && appendNon2) {
+ /* Do first nonOverlap2Func call, which may be able to coalesce */
+ FindBand(r2, r2BandEnd, r2End, r2y1);
+ curBand = newReg->data->numRects;
+ miAppendNonO(newReg, r2, r2BandEnd, max(r2y1, ybot), r2->y2);
+ Coalesce(newReg, prevBand, curBand);
+ /* Append rest of boxes */
+ AppendRegions(newReg, r2BandEnd, r2End);
+ }
+
+ if (oldData)
+ xfree(oldData);
+
+ if (!(numRects = newReg->data->numRects))
+ {
+ xfreeData(newReg);
+ newReg->data = &miEmptyData;
+ }
+ else if (numRects == 1)
+ {
+ newReg->extents = *REGION_BOXPTR(newReg);
+ xfreeData(newReg);
+ newReg->data = (RegDataPtr)NULL;
+ }
+ else
+ {
+ DOWNSIZE(newReg, numRects);
+ }
+
+ return TRUE;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miSetExtents --
+ * Reset the extents of a region to what they should be. Called by
+ * miSubtract and miIntersect as they can't figure it out along the
+ * way or do so easily, as miUnion can.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The region's 'extents' structure is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+miSetExtents (pReg)
+ register RegionPtr pReg;
+{
+ register BoxPtr pBox, pBoxEnd;
+
+ if (!pReg->data)
+ return;
+ if (!pReg->data->size)
+ {
+ pReg->extents.x2 = pReg->extents.x1;
+ pReg->extents.y2 = pReg->extents.y1;
+ return;
+ }
+
+ pBox = REGION_BOXPTR(pReg);
+ pBoxEnd = REGION_END(pReg);
+
+ /*
+ * Since pBox is the first rectangle in the region, it must have the
+ * smallest y1 and since pBoxEnd is the last rectangle in the region,
+ * it must have the largest y2, because of banding. Initialize x1 and
+ * x2 from pBox and pBoxEnd, resp., as good things to initialize them
+ * to...
+ */
+ pReg->extents.x1 = pBox->x1;
+ pReg->extents.y1 = pBox->y1;
+ pReg->extents.x2 = pBoxEnd->x2;
+ pReg->extents.y2 = pBoxEnd->y2;
+
+ assert(pReg->extents.y1 < pReg->extents.y2);
+ while (pBox <= pBoxEnd) {
+ if (pBox->x1 < pReg->extents.x1)
+ pReg->extents.x1 = pBox->x1;
+ if (pBox->x2 > pReg->extents.x2)
+ pReg->extents.x2 = pBox->x2;
+ pBox++;
+ };
+
+ assert(pReg->extents.x1 < pReg->extents.x2);
+}
+
+/*======================================================================
+ * Region Intersection
+ *====================================================================*/
+/*-
+ *-----------------------------------------------------------------------
+ * miIntersectO --
+ * Handle an overlapping band for miIntersect.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * Rectangles may be added to the region.
+ *
+ *-----------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Bool
+miIntersectO (pReg, r1, r1End, r2, r2End, y1, y2, pOverlap)
+ register RegionPtr pReg;
+ register BoxPtr r1;
+ BoxPtr r1End;
+ register BoxPtr r2;
+ BoxPtr r2End;
+ short y1;
+ short y2;
+ Bool *pOverlap;
+{
+ register int x1;
+ register int x2;
+ register BoxPtr pNextRect;
+
+ pNextRect = REGION_TOP(pReg);
+
+ assert(y1 < y2);
+ assert(r1 != r1End && r2 != r2End);
+
+ do {
+ x1 = max(r1->x1, r2->x1);
+ x2 = min(r1->x2, r2->x2);
+
+ /*
+ * If there's any overlap between the two rectangles, add that
+ * overlap to the new region.
+ */
+ if (x1 < x2)
+ NEWRECT(pReg, pNextRect, x1, y1, x2, y2);
+
+ /*
+ * Advance the pointer(s) with the leftmost right side, since the next
+ * rectangle on that list may still overlap the other region's
+ * current rectangle.
+ */
+ if (r1->x2 == x2) {
+ r1++;
+ }
+ if (r2->x2 == x2) {
+ r2++;
+ }
+ } while ((r1 != r1End) && (r2 != r2End));
+
+ return TRUE;
+}
+
+
+Bool
+miIntersect(newReg, reg1, reg2)
+ register RegionPtr newReg; /* destination Region */
+ register RegionPtr reg1;
+ register RegionPtr reg2; /* source regions */
+{
+ good(reg1);
+ good(reg2);
+ good(newReg);
+ /* check for trivial reject */
+ if (REGION_NIL(reg1) || REGION_NIL(reg2) ||
+ !EXTENTCHECK(&reg1->extents, &reg2->extents))
+ {
+ /* Covers about 20% of all cases */
+ xfreeData(newReg);
+ newReg->extents.x2 = newReg->extents.x1;
+ newReg->extents.y2 = newReg->extents.y1;
+ newReg->data = &miEmptyData;
+ }
+ else if (!reg1->data && !reg2->data)
+ {
+ /* Covers about 80% of cases that aren't trivially rejected */
+ newReg->extents.x1 = max(reg1->extents.x1, reg2->extents.x1);
+ newReg->extents.y1 = max(reg1->extents.y1, reg2->extents.y1);
+ newReg->extents.x2 = min(reg1->extents.x2, reg2->extents.x2);
+ newReg->extents.y2 = min(reg1->extents.y2, reg2->extents.y2);
+ xfreeData(newReg);
+ newReg->data = (RegDataPtr)NULL;
+ }
+ else if (!reg2->data && SUBSUMES(&reg2->extents, &reg1->extents))
+ {
+ return miRegionCopy(newReg, reg1);
+ }
+ else if (!reg1->data && SUBSUMES(&reg1->extents, &reg2->extents))
+ {
+ return miRegionCopy(newReg, reg2);
+ }
+ else if (reg1 == reg2)
+ {
+ return miRegionCopy(newReg, reg1);
+ }
+ else
+ {
+ /* General purpose intersection */
+ Bool overlap; /* result ignored */
+ if (!miRegionOp(newReg, reg1, reg2, miIntersectO, FALSE, FALSE,
+ &overlap))
+ return FALSE;
+ miSetExtents(newReg);
+ }
+
+ good(newReg);
+ return(TRUE);
+}
+
+#define MERGERECT(r) \
+{ \
+ if (r->x1 <= x2) { \
+ /* Merge with current rectangle */ \
+ if (r->x1 < x2) *pOverlap = TRUE; \
+ if (x2 < r->x2) x2 = r->x2; \
+ } else { \
+ /* Add current rectangle, start new one */ \
+ NEWRECT(pReg, pNextRect, x1, y1, x2, y2); \
+ x1 = r->x1; \
+ x2 = r->x2; \
+ } \
+ r++; \
+}
+
+/*======================================================================
+ * Region Union
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * miUnionO --
+ * Handle an overlapping band for the union operation. Picks the
+ * left-most rectangle each time and merges it into the region.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * pReg is overwritten.
+ * pOverlap is set to TRUE if any boxes overlap.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Bool
+miUnionO (pReg, r1, r1End, r2, r2End, y1, y2, pOverlap)
+ register RegionPtr pReg;
+ register BoxPtr r1;
+ BoxPtr r1End;
+ register BoxPtr r2;
+ BoxPtr r2End;
+ short y1;
+ short y2;
+ Bool *pOverlap;
+{
+ register BoxPtr pNextRect;
+ register int x1; /* left and right side of current union */
+ register int x2;
+
+ assert (y1 < y2);
+ assert(r1 != r1End && r2 != r2End);
+
+ pNextRect = REGION_TOP(pReg);
+
+ /* Start off current rectangle */
+ if (r1->x1 < r2->x1)
+ {
+ x1 = r1->x1;
+ x2 = r1->x2;
+ r1++;
+ }
+ else
+ {
+ x1 = r2->x1;
+ x2 = r2->x2;
+ r2++;
+ }
+ while (r1 != r1End && r2 != r2End)
+ {
+ if (r1->x1 < r2->x1) MERGERECT(r1) else MERGERECT(r2);
+ }
+
+ /* Finish off whoever (if any) is left */
+ if (r1 != r1End)
+ {
+ do
+ {
+ MERGERECT(r1);
+ } while (r1 != r1End);
+ }
+ else if (r2 != r2End)
+ {
+ do
+ {
+ MERGERECT(r2);
+ } while (r2 != r2End);
+ }
+
+ /* Add current rectangle */
+ NEWRECT(pReg, pNextRect, x1, y1, x2, y2);
+
+ return TRUE;
+}
+
+Bool
+miUnion(newReg, reg1, reg2)
+ RegionPtr newReg; /* destination Region */
+ register RegionPtr reg1;
+ register RegionPtr reg2; /* source regions */
+{
+ Bool overlap; /* result ignored */
+
+ /* Return TRUE if some overlap between reg1, reg2 */
+ good(reg1);
+ good(reg2);
+ good(newReg);
+ /* checks all the simple cases */
+
+ /*
+ * Region 1 and 2 are the same
+ */
+ if (reg1 == reg2)
+ {
+ return miRegionCopy(newReg, reg1);
+ }
+
+ /*
+ * Region 1 is empty
+ */
+ if (REGION_NIL(reg1))
+ {
+ if (newReg != reg2)
+ return miRegionCopy(newReg, reg2);
+ return TRUE;
+ }
+
+ /*
+ * Region 2 is empty
+ */
+ if (REGION_NIL(reg2))
+ {
+ if (newReg != reg1)
+ return miRegionCopy(newReg, reg1);
+ return TRUE;
+ }
+
+ /*
+ * Region 1 completely subsumes region 2
+ */
+ if (!reg1->data && SUBSUMES(&reg1->extents, &reg2->extents))
+ {
+ if (newReg != reg1)
+ return miRegionCopy(newReg, reg1);
+ return TRUE;
+ }
+
+ /*
+ * Region 2 completely subsumes region 1
+ */
+ if (!reg2->data && SUBSUMES(&reg2->extents, &reg1->extents))
+ {
+ if (newReg != reg2)
+ return miRegionCopy(newReg, reg2);
+ return TRUE;
+ }
+
+ if (!miRegionOp(newReg, reg1, reg2, miUnionO, TRUE, TRUE, &overlap))
+ return FALSE;
+
+ newReg->extents.x1 = min(reg1->extents.x1, reg2->extents.x1);
+ newReg->extents.y1 = min(reg1->extents.y1, reg2->extents.y1);
+ newReg->extents.x2 = max(reg1->extents.x2, reg2->extents.x2);
+ newReg->extents.y2 = max(reg1->extents.y2, reg2->extents.y2);
+ good(newReg);
+ return TRUE;
+}
+
+
+/*======================================================================
+ * Batch Rectangle Union
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * miRegionAppend --
+ *
+ * "Append" the rgn rectangles onto the end of dstrgn, maintaining
+ * knowledge of YX-banding when it's easy. Otherwise, dstrgn just
+ * becomes a non-y-x-banded random collection of rectangles, and not
+ * yet a true region. After a sequence of appends, the caller must
+ * call miRegionValidate to ensure that a valid region is constructed.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * dstrgn is modified if rgn has rectangles.
+ *
+ */
+Bool
+miRegionAppend(dstrgn, rgn)
+ register RegionPtr dstrgn;
+ register RegionPtr rgn;
+{
+ int numRects, dnumRects, size;
+ BoxPtr new, old;
+ Bool prepend;
+
+ if (!rgn->data && (dstrgn->data == &miEmptyData))
+ {
+ dstrgn->extents = rgn->extents;
+ dstrgn->data = (RegDataPtr)NULL;
+ return TRUE;
+ }
+
+ numRects = REGION_NUM_RECTS(rgn);
+ if (!numRects)
+ return TRUE;
+ prepend = FALSE;
+ size = numRects;
+ dnumRects = REGION_NUM_RECTS(dstrgn);
+ if (!dnumRects && (size < 200))
+ size = 200; /* XXX pick numbers out of a hat */
+ RECTALLOC(dstrgn, size);
+ old = REGION_RECTS(rgn);
+ if (!dnumRects)
+ dstrgn->extents = rgn->extents;
+ else if (dstrgn->extents.x2 > dstrgn->extents.x1)
+ {
+ register BoxPtr first, last;
+
+ first = old;
+ last = REGION_BOXPTR(dstrgn) + (dnumRects - 1);
+ if ((first->y1 > last->y2) ||
+ ((first->y1 == last->y1) && (first->y2 == last->y2) &&
+ (first->x1 > last->x2)))
+ {
+ if (rgn->extents.x1 < dstrgn->extents.x1)
+ dstrgn->extents.x1 = rgn->extents.x1;
+ if (rgn->extents.x2 > dstrgn->extents.x2)
+ dstrgn->extents.x2 = rgn->extents.x2;
+ dstrgn->extents.y2 = rgn->extents.y2;
+ }
+ else
+ {
+ first = REGION_BOXPTR(dstrgn);
+ last = old + (numRects - 1);
+ if ((first->y1 > last->y2) ||
+ ((first->y1 == last->y1) && (first->y2 == last->y2) &&
+ (first->x1 > last->x2)))
+ {
+ prepend = TRUE;
+ if (rgn->extents.x1 < dstrgn->extents.x1)
+ dstrgn->extents.x1 = rgn->extents.x1;
+ if (rgn->extents.x2 > dstrgn->extents.x2)
+ dstrgn->extents.x2 = rgn->extents.x2;
+ dstrgn->extents.y1 = rgn->extents.y1;
+ }
+ else
+ dstrgn->extents.x2 = dstrgn->extents.x1;
+ }
+ }
+ if (prepend)
+ {
+ new = REGION_BOX(dstrgn, numRects);
+ if (dnumRects == 1)
+ *new = *REGION_BOXPTR(dstrgn);
+ else
+ memmove((char *)new,(char *)REGION_BOXPTR(dstrgn),
+ dnumRects * sizeof(BoxRec));
+ new = REGION_BOXPTR(dstrgn);
+ }
+ else
+ new = REGION_BOXPTR(dstrgn) + dnumRects;
+ if (numRects == 1)
+ *new = *old;
+ else
+ memmove((char *)new, (char *)old, numRects * sizeof(BoxRec));
+ dstrgn->data->numRects += numRects;
+ return TRUE;
+}
+
+
+#define ExchangeRects(a, b) \
+{ \
+ BoxRec t; \
+ t = rects[a]; \
+ rects[a] = rects[b]; \
+ rects[b] = t; \
+}
+
+static void
+QuickSortRects(rects, numRects)
+ register BoxRec rects[];
+ register int numRects;
+{
+ register int y1;
+ register int x1;
+ register int i, j;
+ register BoxPtr r;
+
+ /* Always called with numRects > 1 */
+
+ do
+ {
+ if (numRects == 2)
+ {
+ if (rects[0].y1 > rects[1].y1 ||
+ (rects[0].y1 == rects[1].y1 && rects[0].x1 > rects[1].x1))
+ ExchangeRects(0, 1);
+ return;
+ }
+
+ /* Choose partition element, stick in location 0 */
+ ExchangeRects(0, numRects >> 1);
+ y1 = rects[0].y1;
+ x1 = rects[0].x1;
+
+ /* Partition array */
+ i = 0;
+ j = numRects;
+ do
+ {
+ r = &(rects[i]);
+ do
+ {
+ r++;
+ i++;
+ } while (i != numRects &&
+ (r->y1 < y1 || (r->y1 == y1 && r->x1 < x1)));
+ r = &(rects[j]);
+ do
+ {
+ r--;
+ j--;
+ } while (y1 < r->y1 || (y1 == r->y1 && x1 < r->x1));
+ if (i < j)
+ ExchangeRects(i, j);
+ } while (i < j);
+
+ /* Move partition element back to middle */
+ ExchangeRects(0, j);
+
+ /* Recurse */
+ if (numRects-j-1 > 1)
+ QuickSortRects(&rects[j+1], numRects-j-1);
+ numRects = j;
+ } while (numRects > 1);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miRegionValidate --
+ *
+ * Take a ``region'' which is a non-y-x-banded random collection of
+ * rectangles, and compute a nice region which is the union of all the
+ * rectangles.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * The passed-in ``region'' may be modified.
+ * pOverlap set to TRUE if any retangles overlapped, else FALSE;
+ *
+ * Strategy:
+ * Step 1. Sort the rectangles into ascending order with primary key y1
+ * and secondary key x1.
+ *
+ * Step 2. Split the rectangles into the minimum number of proper y-x
+ * banded regions. This may require horizontally merging
+ * rectangles, and vertically coalescing bands. With any luck,
+ * this step in an identity tranformation (ala the Box widget),
+ * or a coalescing into 1 box (ala Menus).
+ *
+ * Step 3. Merge the separate regions down to a single region by calling
+ * miUnion. Maximize the work each miUnion call does by using
+ * a binary merge.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+Bool
+miRegionValidate(badreg, pOverlap)
+ RegionPtr badreg;
+ Bool *pOverlap;
+{
+ /* Descriptor for regions under construction in Step 2. */
+ typedef struct {
+ RegionRec reg;
+ int prevBand;
+ int curBand;
+ } RegionInfo;
+
+ int numRects; /* Original numRects for badreg */
+ RegionInfo *ri; /* Array of current regions */
+ int numRI; /* Number of entries used in ri */
+ int sizeRI; /* Number of entries available in ri */
+ int i; /* Index into rects */
+ register int j; /* Index into ri */
+ register RegionInfo *rit; /* &ri[j] */
+ register RegionPtr reg; /* ri[j].reg */
+ register BoxPtr box; /* Current box in rects */
+ register BoxPtr riBox; /* Last box in ri[j].reg */
+ register RegionPtr hreg; /* ri[j_half].reg */
+
+ *pOverlap = FALSE;
+ if (!badreg->data)
+ {
+ good(badreg);
+ return TRUE;
+ }
+ numRects = badreg->data->numRects;
+ if (!numRects)
+ {
+ good(badreg);
+ return TRUE;
+ }
+ if (badreg->extents.x1 < badreg->extents.x2)
+ {
+ if ((numRects) == 1)
+ {
+ xfreeData(badreg);
+ badreg->data = (RegDataPtr) NULL;
+ }
+ else
+ {
+ DOWNSIZE(badreg, numRects);
+ }
+ good(badreg);
+ return TRUE;
+ }
+
+ /* Step 1: Sort the rects array into ascending (y1, x1) order */
+ QuickSortRects(REGION_BOXPTR(badreg), numRects);
+
+ /* Step 2: Scatter the sorted array into the minimum number of regions */
+
+ /* Set up the first region to be the first rectangle in badreg */
+ /* Note that step 2 code will never overflow the ri[0].reg rects array */
+ Must_have_memory = TRUE; /* XXX */
+ ri = (RegionInfo *) xalloc(4 * sizeof(RegionInfo));
+ Must_have_memory = FALSE; /* XXX */
+ sizeRI = 4;
+ numRI = 1;
+ ri[0].prevBand = 0;
+ ri[0].curBand = 0;
+ ri[0].reg = *badreg;
+ box = REGION_BOXPTR(&ri[0].reg);
+ ri[0].reg.extents = *box;
+ ri[0].reg.data->numRects = 1;
+
+ /* Now scatter rectangles into the minimum set of valid regions. If the
+ next rectangle to be added to a region would force an existing rectangle
+ in the region to be split up in order to maintain y-x banding, just
+ forget it. Try the next region. If it doesn't fit cleanly into any
+ region, make a new one. */
+
+ for (i = numRects; --i > 0;)
+ {
+ box++;
+ /* Look for a region to append box to */
+ for (j = numRI, rit = ri; --j >= 0; rit++)
+ {
+ reg = &rit->reg;
+ riBox = REGION_END(reg);
+
+ if (box->y1 == riBox->y1 && box->y2 == riBox->y2)
+ {
+ /* box is in same band as riBox. Merge or append it */
+ if (box->x1 <= riBox->x2)
+ {
+ /* Merge it with riBox */
+ if (box->x1 < riBox->x2) *pOverlap = TRUE;
+ if (box->x2 > riBox->x2) riBox->x2 = box->x2;
+ }
+ else
+ {
+ RECTALLOC(reg, 1);
+ *REGION_TOP(reg) = *box;
+ reg->data->numRects++;
+ }
+ goto NextRect; /* So sue me */
+ }
+ else if (box->y1 >= riBox->y2)
+ {
+ /* Put box into new band */
+ if (reg->extents.x2 < riBox->x2) reg->extents.x2 = riBox->x2;
+ if (reg->extents.x1 > box->x1) reg->extents.x1 = box->x1;
+ Coalesce(reg, rit->prevBand, rit->curBand);
+ rit->curBand = reg->data->numRects;
+ RECTALLOC(reg, 1);
+ *REGION_TOP(reg) = *box;
+ reg->data->numRects++;
+ goto NextRect;
+ }
+ /* Well, this region was inappropriate. Try the next one. */
+ } /* for j */
+
+ /* Uh-oh. No regions were appropriate. Create a new one. */
+ if (sizeRI == numRI)
+ {
+ /* Oops, allocate space for new region information */
+ sizeRI <<= 1;
+ Must_have_memory = TRUE; /* XXX */
+ ri = (RegionInfo *) xrealloc(ri, sizeRI * sizeof(RegionInfo));
+ Must_have_memory = FALSE; /* XXX */
+ rit = &ri[numRI];
+ }
+ numRI++;
+ rit->prevBand = 0;
+ rit->curBand = 0;
+ rit->reg.extents = *box;
+ rit->reg.data = (RegDataPtr)NULL;
+ miRectAlloc(&rit->reg, (i+numRI) / numRI); /* MUST force allocation */
+NextRect: ;
+ } /* for i */
+
+ /* Make a final pass over each region in order to Coalesce and set
+ extents.x2 and extents.y2 */
+
+ for (j = numRI, rit = ri; --j >= 0; rit++)
+ {
+ reg = &rit->reg;
+ riBox = REGION_END(reg);
+ reg->extents.y2 = riBox->y2;
+ if (reg->extents.x2 < riBox->x2) reg->extents.x2 = riBox->x2;
+ Coalesce(reg, rit->prevBand, rit->curBand);
+ if (reg->data->numRects == 1) /* keep unions happy below */
+ {
+ xfreeData(reg);
+ reg->data = (RegDataPtr)NULL;
+ }
+ }
+
+ /* Step 3: Union all regions into a single region */
+ while (numRI > 1)
+ {
+ int half = numRI/2;
+ for (j = numRI & 1; j < (half + (numRI & 1)); j++)
+ {
+ reg = &ri[j].reg;
+ hreg = &ri[j+half].reg;
+ miRegionOp(reg, reg, hreg, miUnionO, TRUE, TRUE, pOverlap);
+ if (hreg->extents.x1 < reg->extents.x1)
+ reg->extents.x1 = hreg->extents.x1;
+ if (hreg->extents.y1 < reg->extents.y1)
+ reg->extents.y1 = hreg->extents.y1;
+ if (hreg->extents.x2 > reg->extents.x2)
+ reg->extents.x2 = hreg->extents.x2;
+ if (hreg->extents.y2 > reg->extents.y2)
+ reg->extents.y2 = hreg->extents.y2;
+ xfreeData(hreg);
+ }
+ numRI -= half;
+ }
+ *badreg = ri[0].reg;
+ xfree(ri);
+ good(badreg);
+ return TRUE;
+}
+
+RegionPtr
+miRectsToRegion(nrects, prect, ctype)
+ int nrects;
+ register xRectangle *prect;
+ int ctype;
+{
+ register RegionPtr pRgn;
+ register RegDataPtr pData;
+ register BoxPtr pBox;
+ register int i;
+ int x1, y1, x2, y2;
+
+ pRgn = miRegionCreate(NullBox, 0);
+ if (!nrects)
+ return pRgn;
+ if (nrects == 1)
+ {
+ x1 = prect->x;
+ y1 = prect->y;
+ if ((x2 = x1 + (int) prect->width) > MAXSHORT)
+ x2 = MAXSHORT;
+ if ((y2 = y1 + (int) prect->height) > MAXSHORT)
+ y2 = MAXSHORT;
+ if (x1 != x2 && y1 != y2)
+ {
+ pRgn->extents.x1 = x1;
+ pRgn->extents.y1 = y1;
+ pRgn->extents.x2 = x2;
+ pRgn->extents.y2 = y2;
+ pRgn->data = (RegDataPtr)NULL;
+ }
+ return pRgn;
+ }
+ Must_have_memory = TRUE; /* XXX */
+ pData = xallocData(nrects);
+ pBox = (BoxPtr) (pData + 1);
+ Must_have_memory = FALSE; /* XXX */
+ for (i = nrects; --i >= 0; prect++)
+ {
+ x1 = prect->x;
+ y1 = prect->y;
+ if ((x2 = x1 + (int) prect->width) > MAXSHORT)
+ x2 = MAXSHORT;
+ if ((y2 = y1 + (int) prect->height) > MAXSHORT)
+ y2 = MAXSHORT;
+ if (x1 != x2 && y1 != y2)
+ {
+ pBox->x1 = x1;
+ pBox->y1 = y1;
+ pBox->x2 = x2;
+ pBox->y2 = y2;
+ pBox++;
+ }
+ }
+ if (pBox != (BoxPtr) (pData + 1))
+ {
+ pData->size = nrects;
+ pData->numRects = pBox - (BoxPtr) (pData + 1);
+ pRgn->data = pData;
+ if (ctype != CT_YXBANDED)
+ {
+ Bool overlap; /* result ignored */
+ pRgn->extents.x1 = pRgn->extents.x2 = 0;
+ miRegionValidate(pRgn, &overlap);
+ }
+ else
+ miSetExtents(pRgn);
+ good(pRgn);
+ }
+ else
+ {
+ xfree (pData);
+ }
+ return pRgn;
+}
+
+/*======================================================================
+ * Region Subtraction
+ *====================================================================*/
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miSubtractO --
+ * Overlapping band subtraction. x1 is the left-most point not yet
+ * checked.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * pReg may have rectangles added to it.
+ *
+ *-----------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+static Bool
+miSubtractO (pReg, r1, r1End, r2, r2End, y1, y2, pOverlap)
+ register RegionPtr pReg;
+ register BoxPtr r1;
+ BoxPtr r1End;
+ register BoxPtr r2;
+ BoxPtr r2End;
+ register int y1;
+ int y2;
+ Bool *pOverlap;
+{
+ register BoxPtr pNextRect;
+ register int x1;
+
+ x1 = r1->x1;
+
+ assert(y1<y2);
+ assert(r1 != r1End && r2 != r2End);
+
+ pNextRect = REGION_TOP(pReg);
+
+ do
+ {
+ if (r2->x2 <= x1)
+ {
+ /*
+ * Subtrahend entirely to left of minuend: go to next subtrahend.
+ */
+ r2++;
+ }
+ else if (r2->x1 <= x1)
+ {
+ /*
+ * Subtrahend preceeds minuend: nuke left edge of minuend.
+ */
+ x1 = r2->x2;
+ if (x1 >= r1->x2)
+ {
+ /*
+ * Minuend completely covered: advance to next minuend and
+ * reset left fence to edge of new minuend.
+ */
+ r1++;
+ if (r1 != r1End)
+ x1 = r1->x1;
+ }
+ else
+ {
+ /*
+ * Subtrahend now used up since it doesn't extend beyond
+ * minuend
+ */
+ r2++;
+ }
+ }
+ else if (r2->x1 < r1->x2)
+ {
+ /*
+ * Left part of subtrahend covers part of minuend: add uncovered
+ * part of minuend to region and skip to next subtrahend.
+ */
+ assert(x1<r2->x1);
+ NEWRECT(pReg, pNextRect, x1, y1, r2->x1, y2);
+
+ x1 = r2->x2;
+ if (x1 >= r1->x2)
+ {
+ /*
+ * Minuend used up: advance to new...
+ */
+ r1++;
+ if (r1 != r1End)
+ x1 = r1->x1;
+ }
+ else
+ {
+ /*
+ * Subtrahend used up
+ */
+ r2++;
+ }
+ }
+ else
+ {
+ /*
+ * Minuend used up: add any remaining piece before advancing.
+ */
+ if (r1->x2 > x1)
+ NEWRECT(pReg, pNextRect, x1, y1, r1->x2, y2);
+ r1++;
+ if (r1 != r1End)
+ x1 = r1->x1;
+ }
+ } while ((r1 != r1End) && (r2 != r2End));
+
+
+ /*
+ * Add remaining minuend rectangles to region.
+ */
+ while (r1 != r1End)
+ {
+ assert(x1<r1->x2);
+ NEWRECT(pReg, pNextRect, x1, y1, r1->x2, y2);
+ r1++;
+ if (r1 != r1End)
+ x1 = r1->x1;
+ }
+ return TRUE;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miSubtract --
+ * Subtract regS from regM and leave the result in regD.
+ * S stands for subtrahend, M for minuend and D for difference.
+ *
+ * Results:
+ * TRUE if successful.
+ *
+ * Side Effects:
+ * regD is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+Bool
+miSubtract(regD, regM, regS)
+ register RegionPtr regD;
+ register RegionPtr regM;
+ register RegionPtr regS;
+{
+ Bool overlap; /* result ignored */
+
+ good(regM);
+ good(regS);
+ good(regD);
+ /* check for trivial rejects */
+ if (REGION_NIL(regM) || REGION_NIL(regS) ||
+ !EXTENTCHECK(&regM->extents, &regS->extents))
+ {
+ return miRegionCopy(regD, regM);
+ }
+ else if (regM == regS)
+ {
+ xfreeData(regD);
+ regD->extents.x2 = regD->extents.x1;
+ regD->extents.y2 = regD->extents.y1;
+ regD->data = &miEmptyData;
+ return TRUE;
+ }
+
+ /* Add those rectangles in region 1 that aren't in region 2,
+ do yucky substraction for overlaps, and
+ just throw away rectangles in region 2 that aren't in region 1 */
+ if (!miRegionOp(regD, regM, regS, miSubtractO, TRUE, FALSE, &overlap))
+ return FALSE;
+
+ /*
+ * Can't alter RegD's extents before we call miRegionOp because
+ * it might be one of the source regions and miRegionOp depends
+ * on the extents of those regions being unaltered. Besides, this
+ * way there's no checking against rectangles that will be nuked
+ * due to coalescing, so we have to examine fewer rectangles.
+ */
+ miSetExtents(regD);
+ good(regD);
+ return TRUE;
+}
+
+/*======================================================================
+ * Region Inversion
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * miInverse --
+ * Take a region and a box and return a region that is everything
+ * in the box but not in the region. The careful reader will note
+ * that this is the same as subtracting the region from the box...
+ *
+ * Results:
+ * TRUE.
+ *
+ * Side Effects:
+ * newReg is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+Bool
+miInverse(newReg, reg1, invRect)
+ RegionPtr newReg; /* Destination region */
+ RegionPtr reg1; /* Region to invert */
+ BoxPtr invRect; /* Bounding box for inversion */
+{
+ RegionRec invReg; /* Quick and dirty region made from the
+ * bounding box */
+ Bool overlap; /* result ignored */
+
+ good(reg1);
+ good(newReg);
+ /* check for trivial rejects */
+ if (REGION_NIL(reg1) || !EXTENTCHECK(invRect, &reg1->extents))
+ {
+ newReg->extents = *invRect;
+ xfreeData(newReg);
+ newReg->data = (RegDataPtr)NULL;
+ return TRUE;
+ }
+
+ /* Add those rectangles in region 1 that aren't in region 2,
+ do yucky substraction for overlaps, and
+ just throw away rectangles in region 2 that aren't in region 1 */
+ invReg.extents = *invRect;
+ invReg.data = (RegDataPtr)NULL;
+ if (!miRegionOp(newReg, &invReg, reg1, miSubtractO, TRUE, FALSE, &overlap))
+ return FALSE;
+
+ /*
+ * Can't alter newReg's extents before we call miRegionOp because
+ * it might be one of the source regions and miRegionOp depends
+ * on the extents of those regions being unaltered. Besides, this
+ * way there's no checking against rectangles that will be nuked
+ * due to coalescing, so we have to examine fewer rectangles.
+ */
+ miSetExtents(newReg);
+ good(newReg);
+ return TRUE;
+}
+
+/*
+ * RectIn(region, rect)
+ * This routine takes a pointer to a region and a pointer to a box
+ * and determines if the box is outside/inside/partly inside the region.
+ *
+ * The idea is to travel through the list of rectangles trying to cover the
+ * passed box with them. Anytime a piece of the rectangle isn't covered
+ * by a band of rectangles, partOut is set TRUE. Any time a rectangle in
+ * the region covers part of the box, partIn is set TRUE. The process ends
+ * when either the box has been completely covered (we reached a band that
+ * doesn't overlap the box, partIn is TRUE and partOut is false), the
+ * box has been partially covered (partIn == partOut == TRUE -- because of
+ * the banding, the first time this is true we know the box is only
+ * partially in the region) or is outside the region (we reached a band
+ * that doesn't overlap the box at all and partIn is false)
+ */
+
+int
+miRectIn(region, prect)
+ register RegionPtr region;
+ register BoxPtr prect;
+{
+ register int x;
+ register int y;
+ register BoxPtr pbox;
+ register BoxPtr pboxEnd;
+ int partIn, partOut;
+ int numRects;
+
+ good(region);
+ numRects = REGION_NUM_RECTS(region);
+ /* useful optimization */
+ if (!numRects || !EXTENTCHECK(&region->extents, prect))
+ return(rgnOUT);
+
+ if (numRects == 1)
+ {
+ /* We know that it must be rgnIN or rgnPART */
+ if (SUBSUMES(&region->extents, prect))
+ return(rgnIN);
+ else
+ return(rgnPART);
+ }
+
+ partOut = FALSE;
+ partIn = FALSE;
+
+ /* (x,y) starts at upper left of rect, moving to the right and down */
+ x = prect->x1;
+ y = prect->y1;
+
+ /* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */
+ for (pbox = REGION_BOXPTR(region), pboxEnd = pbox + numRects;
+ pbox != pboxEnd;
+ pbox++)
+ {
+
+ if (pbox->y2 <= y)
+ continue; /* getting up to speed or skipping remainder of band */
+
+ if (pbox->y1 > y)
+ {
+ partOut = TRUE; /* missed part of rectangle above */
+ if (partIn || (pbox->y1 >= prect->y2))
+ break;
+ y = pbox->y1; /* x guaranteed to be == prect->x1 */
+ }
+
+ if (pbox->x2 <= x)
+ continue; /* not far enough over yet */
+
+ if (pbox->x1 > x)
+ {
+ partOut = TRUE; /* missed part of rectangle to left */
+ if (partIn)
+ break;
+ }
+
+ if (pbox->x1 < prect->x2)
+ {
+ partIn = TRUE; /* definitely overlap */
+ if (partOut)
+ break;
+ }
+
+ if (pbox->x2 >= prect->x2)
+ {
+ y = pbox->y2; /* finished with this band */
+ if (y >= prect->y2)
+ break;
+ x = prect->x1; /* reset x out to left again */
+ }
+ else
+ {
+ /*
+ * Because boxes in a band are maximal width, if the first box
+ * to overlap the rectangle doesn't completely cover it in that
+ * band, the rectangle must be partially out, since some of it
+ * will be uncovered in that band. partIn will have been set true
+ * by now...
+ */
+ partOut = TRUE;
+ break;
+ }
+ }
+
+ return(partIn ? ((y < prect->y2) ? rgnPART : rgnIN) : rgnOUT);
+}
+
+/* TranslateRegion(pReg, x, y)
+ translates in place
+*/
+
+void
+miTranslateRegion(pReg, x, y)
+ register RegionPtr pReg;
+ register int x;
+ register int y;
+{
+ int x1, x2, y1, y2;
+ register int nbox;
+ register BoxPtr pbox;
+
+ good(pReg);
+ pReg->extents.x1 = x1 = pReg->extents.x1 + x;
+ pReg->extents.y1 = y1 = pReg->extents.y1 + y;
+ pReg->extents.x2 = x2 = pReg->extents.x2 + x;
+ pReg->extents.y2 = y2 = pReg->extents.y2 + y;
+ if (((x1 - MINSHORT)|(y1 - MINSHORT)|(MAXSHORT - x2)|(MAXSHORT - y2)) >= 0)
+ {
+ if (pReg->data && (nbox = pReg->data->numRects))
+ {
+ for (pbox = REGION_BOXPTR(pReg); nbox--; pbox++)
+ {
+ pbox->x1 += x;
+ pbox->y1 += y;
+ pbox->x2 += x;
+ pbox->y2 += y;
+ }
+ }
+ return;
+ }
+ if (((x2 - MINSHORT)|(y2 - MINSHORT)|(MAXSHORT - x1)|(MAXSHORT - y1)) <= 0)
+ {
+ pReg->extents.x2 = pReg->extents.x1;
+ pReg->extents.y2 = pReg->extents.y1;
+ xfreeData(pReg);
+ pReg->data = &miEmptyData;
+ return;
+ }
+ if (x1 < MINSHORT)
+ pReg->extents.x1 = MINSHORT;
+ else if (x2 > MAXSHORT)
+ pReg->extents.x2 = MAXSHORT;
+ if (y1 < MINSHORT)
+ pReg->extents.y1 = MINSHORT;
+ else if (y2 > MAXSHORT)
+ pReg->extents.y2 = MAXSHORT;
+ if (pReg->data && (nbox = pReg->data->numRects))
+ {
+ register BoxPtr pboxout;
+
+ for (pboxout = pbox = REGION_BOXPTR(pReg); nbox--; pbox++)
+ {
+ pboxout->x1 = x1 = pbox->x1 + x;
+ pboxout->y1 = y1 = pbox->y1 + y;
+ pboxout->x2 = x2 = pbox->x2 + x;
+ pboxout->y2 = y2 = pbox->y2 + y;
+ if (((x2 - MINSHORT)|(y2 - MINSHORT)|
+ (MAXSHORT - x1)|(MAXSHORT - y1)) <= 0)
+ {
+ pReg->data->numRects--;
+ continue;
+ }
+ if (x1 < MINSHORT)
+ pboxout->x1 = MINSHORT;
+ else if (x2 > MAXSHORT)
+ pboxout->x2 = MAXSHORT;
+ if (y1 < MINSHORT)
+ pboxout->y1 = MINSHORT;
+ else if (y2 > MAXSHORT)
+ pboxout->y2 = MAXSHORT;
+ pboxout++;
+ }
+ if (pboxout != pbox)
+ {
+ if (pReg->data->numRects == 1)
+ {
+ pReg->extents = *REGION_BOXPTR(pReg);
+ xfreeData(pReg);
+ pReg->data = (RegDataPtr)NULL;
+ }
+ else
+ miSetExtents(pReg);
+ }
+ }
+}
+
+Bool
+miRegionDataCopy(dst, src)
+ register RegionPtr dst;
+ register RegionPtr src;
+{
+ good(dst);
+ good(src);
+ if (dst->data)
+ return TRUE;
+ if (dst == src)
+ return TRUE;
+ if (!src->data || !src->data->size)
+ {
+ xfreeData(dst);
+ dst->data = (RegDataPtr)NULL;
+ return TRUE;
+ }
+ if (!dst->data || (dst->data->size < src->data->numRects))
+ {
+ xfreeData(dst);
+ Must_have_memory = TRUE; /* XXX */
+ dst->data = xallocData(src->data->numRects);
+ Must_have_memory = FALSE; /* XXX */
+ }
+ dst->data->size = src->data->size;
+ dst->data->numRects = src->data->numRects;
+ return TRUE;
+}
+
+void
+miRegionReset(pReg, pBox)
+ RegionPtr pReg;
+ BoxPtr pBox;
+{
+ good(pReg);
+ assert(pBox->x1<=pBox->x2);
+ assert(pBox->y1<=pBox->y2);
+ pReg->extents = *pBox;
+ xfreeData(pReg);
+ pReg->data = (RegDataPtr)NULL;
+}
+
+Bool
+miPointInRegion(pReg, x, y, box)
+ register RegionPtr pReg;
+ register int x, y;
+ BoxPtr box; /* "return" value */
+{
+ register BoxPtr pbox, pboxEnd;
+ int numRects;
+
+ good(pReg);
+ numRects = REGION_NUM_RECTS(pReg);
+ if (!numRects || !INBOX(&pReg->extents, x, y))
+ return(FALSE);
+ if (numRects == 1)
+ {
+ *box = pReg->extents;
+ return(TRUE);
+ }
+ for (pbox = REGION_BOXPTR(pReg), pboxEnd = pbox + numRects;
+ pbox != pboxEnd;
+ pbox++)
+ {
+ if (y >= pbox->y2)
+ continue; /* not there yet */
+ if ((y < pbox->y1) || (x < pbox->x1))
+ break; /* missed it */
+ if (x >= pbox->x2)
+ continue; /* not there yet */
+ *box = *pbox;
+ return(TRUE);
+ }
+ return(FALSE);
+}
+
+Bool
+miRegionNotEmpty(pReg)
+ RegionPtr pReg;
+{
+ good(pReg);
+ return(!REGION_NIL(pReg));
+}
+
+
+void
+miRegionEmpty(pReg)
+ RegionPtr pReg;
+{
+ good(pReg);
+ xfreeData(pReg);
+ pReg->extents.x2 = pReg->extents.x1;
+ pReg->extents.y2 = pReg->extents.y1;
+ pReg->data = &miEmptyData;
+}
+
+BoxPtr
+miRegionExtents(pReg)
+ RegionPtr pReg;
+{
+ good(pReg);
+ return(&pReg->extents);
+}
+
+#define ExchangeSpans(a, b) \
+{ \
+ DDXPointRec tpt; \
+ register int tw; \
+ \
+ tpt = spans[a]; spans[a] = spans[b]; spans[b] = tpt; \
+ tw = widths[a]; widths[a] = widths[b]; widths[b] = tw; \
+}
+
+/* ||| I should apply the merge sort code to rectangle sorting above, and see
+ if mapping time can be improved. But right now I've been at work 12 hours,
+ so forget it.
+*/
+
+static void QuickSortSpans(spans, widths, numSpans)
+ register DDXPointRec spans[];
+ register int widths[];
+ register int numSpans;
+{
+ register int y;
+ register int i, j, m;
+ register DDXPointPtr r;
+
+ /* Always called with numSpans > 1 */
+ /* Sorts only by y, doesn't bother to sort by x */
+
+ do
+ {
+ if (numSpans < 9)
+ {
+ /* Do insertion sort */
+ register int yprev;
+
+ yprev = spans[0].y;
+ i = 1;
+ do
+ { /* while i != numSpans */
+ y = spans[i].y;
+ if (yprev > y)
+ {
+ /* spans[i] is out of order. Move into proper location. */
+ DDXPointRec tpt;
+ int tw, k;
+
+ for (j = 0; y >= spans[j].y; j++) {}
+ tpt = spans[i];
+ tw = widths[i];
+ for (k = i; k != j; k--)
+ {
+ spans[k] = spans[k-1];
+ widths[k] = widths[k-1];
+ }
+ spans[j] = tpt;
+ widths[j] = tw;
+ y = spans[i].y;
+ } /* if out of order */
+ yprev = y;
+ i++;
+ } while (i != numSpans);
+ return;
+ }
+
+ /* Choose partition element, stick in location 0 */
+ m = numSpans / 2;
+ if (spans[m].y > spans[0].y) ExchangeSpans(m, 0);
+ if (spans[m].y > spans[numSpans-1].y) ExchangeSpans(m, numSpans-1);
+ if (spans[m].y > spans[0].y) ExchangeSpans(m, 0);
+ y = spans[0].y;
+
+ /* Partition array */
+ i = 0;
+ j = numSpans;
+ do
+ {
+ r = &(spans[i]);
+ do
+ {
+ r++;
+ i++;
+ } while (i != numSpans && r->y < y);
+ r = &(spans[j]);
+ do
+ {
+ r--;
+ j--;
+ } while (y < r->y);
+ if (i < j)
+ ExchangeSpans(i, j);
+ } while (i < j);
+
+ /* Move partition element back to middle */
+ ExchangeSpans(0, j);
+
+ /* Recurse */
+ if (numSpans-j-1 > 1)
+ QuickSortSpans(&spans[j+1], &widths[j+1], numSpans-j-1);
+ numSpans = j;
+ } while (numSpans > 1);
+}
+
+#define NextBand() \
+{ \
+ clipy1 = pboxBandStart->y1; \
+ clipy2 = pboxBandStart->y2; \
+ pboxBandEnd = pboxBandStart + 1; \
+ while (pboxBandEnd != pboxLast && pboxBandEnd->y1 == clipy1) { \
+ pboxBandEnd++; \
+ } \
+ for (; ppt != pptLast && ppt->y < clipy1; ppt++, pwidth++) {} \
+}
+
+/*
+ Clip a list of scanlines to a region. The caller has allocated the
+ space. FSorted is non-zero if the scanline origins are in ascending
+ order.
+ returns the number of new, clipped scanlines.
+*/
+
+int
+miClipSpans(prgnDst, ppt, pwidth, nspans, pptNew, pwidthNew, fSorted)
+ RegionPtr prgnDst;
+ register DDXPointPtr ppt;
+ register int *pwidth;
+ int nspans;
+ register DDXPointPtr pptNew;
+ int *pwidthNew;
+ int fSorted;
+{
+ register DDXPointPtr pptLast;
+ int *pwidthNewStart; /* the vengeance of Xerox! */
+ register int y, x1, x2;
+ register int numRects;
+
+ good(prgnDst);
+ pptLast = ppt + nspans;
+ pwidthNewStart = pwidthNew;
+
+ if (!prgnDst->data)
+ {
+ /* Do special fast code with clip boundaries in registers(?) */
+ /* It doesn't pay much to make use of fSorted in this case,
+ so we lump everything together. */
+
+ register int clipx1, clipx2, clipy1, clipy2;
+
+ clipx1 = prgnDst->extents.x1;
+ clipy1 = prgnDst->extents.y1;
+ clipx2 = prgnDst->extents.x2;
+ clipy2 = prgnDst->extents.y2;
+
+ for (; ppt != pptLast; ppt++, pwidth++)
+ {
+ y = ppt->y;
+ x1 = ppt->x;
+ if (clipy1 <= y && y < clipy2)
+ {
+ x2 = x1 + *pwidth;
+ if (x1 < clipx1) x1 = clipx1;
+ if (x2 > clipx2) x2 = clipx2;
+ if (x1 < x2)
+ {
+ /* part of span in clip rectangle */
+ pptNew->x = x1;
+ pptNew->y = y;
+ *pwidthNew = x2 - x1;
+ pptNew++;
+ pwidthNew++;
+ }
+ }
+ } /* end for */
+
+ }
+ else if (numRects = prgnDst->data->numRects)
+ {
+ /* Have to clip against many boxes */
+ BoxPtr pboxBandStart, pboxBandEnd;
+ register BoxPtr pbox;
+ register BoxPtr pboxLast;
+ register int clipy1, clipy2;
+
+ /* In this case, taking advantage of sorted spans gains more than
+ the sorting costs. */
+ if ((! fSorted) && (nspans > 1))
+ QuickSortSpans(ppt, pwidth, nspans);
+
+ pboxBandStart = REGION_BOXPTR(prgnDst);
+ pboxLast = pboxBandStart + numRects;
+
+ NextBand();
+
+ for (; ppt != pptLast; )
+ {
+ y = ppt->y;
+ if (y < clipy2)
+ {
+ /* span is in the current band */
+ pbox = pboxBandStart;
+ x1 = ppt->x;
+ x2 = x1 + *pwidth;
+ do
+ { /* For each box in band */
+ register int newx1, newx2;
+
+ newx1 = x1;
+ newx2 = x2;
+ if (newx1 < pbox->x1) newx1 = pbox->x1;
+ if (newx2 > pbox->x2) newx2 = pbox->x2;
+ if (newx1 < newx2)
+ {
+ /* Part of span in clip rectangle */
+ pptNew->x = newx1;
+ pptNew->y = y;
+ *pwidthNew = newx2 - newx1;
+ pptNew++;
+ pwidthNew++;
+ }
+ pbox++;
+ } while (pbox != pboxBandEnd);
+ ppt++;
+ pwidth++;
+ }
+ else
+ {
+ /* Move to next band, adjust ppt as needed */
+ pboxBandStart = pboxBandEnd;
+ if (pboxBandStart == pboxLast)
+ break; /* We're completely done */
+ NextBand();
+ }
+ }
+ }
+ return (pwidthNew - pwidthNewStart);
+}
+
+/* find the band in a region with the most rectangles */
+int
+miFindMaxBand(prgn)
+ RegionPtr prgn;
+{
+ register int nbox;
+ register BoxPtr pbox;
+ register int nThisBand;
+ register int nMaxBand = 0;
+ short yThisBand;
+
+ good(prgn);
+ nbox = REGION_NUM_RECTS(prgn);
+ pbox = REGION_RECTS(prgn);
+
+ while(nbox > 0)
+ {
+ yThisBand = pbox->y1;
+ nThisBand = 0;
+ while((nbox > 0) && (pbox->y1 == yThisBand))
+ {
+ nbox--;
+ pbox++;
+ nThisBand++;
+ }
+ if (nThisBand > nMaxBand)
+ nMaxBand = nThisBand;
+ }
+ return (nMaxBand);
+}
diff --git a/xc/programs/Xserver/mi/miscanfill.h b/xc/programs/Xserver/mi/miscanfill.h
new file mode 100644
index 000000000..94a02e6b4
--- /dev/null
+++ b/xc/programs/Xserver/mi/miscanfill.h
@@ -0,0 +1,140 @@
+/* $TOG: miscanfill.h /main/6 1998/02/09 14:48:35 kaleb $ */
+/*
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+
+
+#ifndef SCANFILLINCLUDED
+#define SCANFILLINCLUDED
+/*
+ * scanfill.h
+ *
+ * Written by Brian Kelleher; Jan 1985
+ *
+ * This file contains a few macros to help track
+ * the edge of a filled object. The object is assumed
+ * to be filled in scanline order, and thus the
+ * algorithm used is an extension of Bresenham's line
+ * drawing algorithm which assumes that y is always the
+ * major axis.
+ * Since these pieces of code are the same for any filled shape,
+ * it is more convenient to gather the library in one
+ * place, but since these pieces of code are also in
+ * the inner loops of output primitives, procedure call
+ * overhead is out of the question.
+ * See the author for a derivation if needed.
+ */
+
+
+/*
+ * In scan converting polygons, we want to choose those pixels
+ * which are inside the polygon. Thus, we add .5 to the starting
+ * x coordinate for both left and right edges. Now we choose the
+ * first pixel which is inside the pgon for the left edge and the
+ * first pixel which is outside the pgon for the right edge.
+ * Draw the left pixel, but not the right.
+ *
+ * How to add .5 to the starting x coordinate:
+ * If the edge is moving to the right, then subtract dy from the
+ * error term from the general form of the algorithm.
+ * If the edge is moving to the left, then add dy to the error term.
+ *
+ * The reason for the difference between edges moving to the left
+ * and edges moving to the right is simple: If an edge is moving
+ * to the right, then we want the algorithm to flip immediately.
+ * If it is moving to the left, then we don't want it to flip until
+ * we traverse an entire pixel.
+ */
+#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2) { \
+ int dx; /* local storage */ \
+\
+ /* \
+ * if the edge is horizontal, then it is ignored \
+ * and assumed not to be processed. Otherwise, do this stuff. \
+ */ \
+ if ((dy) != 0) { \
+ xStart = (x1); \
+ dx = (x2) - xStart; \
+ if (dx < 0) { \
+ m = dx / (dy); \
+ m1 = m - 1; \
+ incr1 = -2 * dx + 2 * (dy) * m1; \
+ incr2 = -2 * dx + 2 * (dy) * m; \
+ d = 2 * m * (dy) - 2 * dx - 2 * (dy); \
+ } else { \
+ m = dx / (dy); \
+ m1 = m + 1; \
+ incr1 = 2 * dx - 2 * (dy) * m1; \
+ incr2 = 2 * dx - 2 * (dy) * m; \
+ d = -2 * m * (dy) + 2 * dx; \
+ } \
+ } \
+}
+
+#define BRESINCRPGON(d, minval, m, m1, incr1, incr2) { \
+ if (m1 > 0) { \
+ if (d > 0) { \
+ minval += m1; \
+ d += incr1; \
+ } \
+ else { \
+ minval += m; \
+ d += incr2; \
+ } \
+ } else {\
+ if (d >= 0) { \
+ minval += m1; \
+ d += incr1; \
+ } \
+ else { \
+ minval += m; \
+ d += incr2; \
+ } \
+ } \
+}
+
+
+/*
+ * This structure contains all of the information needed
+ * to run the bresenham algorithm.
+ * The variables may be hardcoded into the declarations
+ * instead of using this structure to make use of
+ * register declarations.
+ */
+typedef struct {
+ int minor; /* minor axis */
+ int d; /* decision variable */
+ int m, m1; /* slope and slope+1 */
+ int incr1, incr2; /* error increments */
+} BRESINFO;
+
+
+#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres) \
+ BRESINITPGON(dmaj, min1, min2, bres.minor, bres.d, \
+ bres.m, bres.m1, bres.incr1, bres.incr2)
+
+#define BRESINCRPGONSTRUCT(bres) \
+ BRESINCRPGON(bres.d, bres.minor, bres.m, bres.m1, bres.incr1, bres.incr2)
+
+
+#endif
diff --git a/xc/programs/Xserver/mi/miscrinit.c b/xc/programs/Xserver/mi/miscrinit.c
new file mode 100644
index 000000000..644405d96
--- /dev/null
+++ b/xc/programs/Xserver/mi/miscrinit.c
@@ -0,0 +1,306 @@
+/* $TOG: miscrinit.c /main/14 1998/02/09 14:48:39 kaleb $ */
+/*
+
+Copyright 1990, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+/* $XFree86: xc/programs/Xserver/mi/miscrinit.c,v 3.7 1999/03/20 08:59:34 dawes Exp $ */
+
+#include "X.h"
+#include "servermd.h"
+#include "misc.h"
+#include "mi.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "dix.h"
+#include "miline.h"
+
+/* We use this structure to propogate some information from miScreenInit to
+ * miCreateScreenResources. miScreenInit allocates the structure, fills it
+ * in, and puts it into pScreen->devPrivate. miCreateScreenResources
+ * extracts the info and frees the structure. We could've accomplished the
+ * same thing by adding fields to the screen structure, but they would have
+ * ended up being redundant, and would have exposed this mi implementation
+ * detail to the whole server.
+ */
+
+typedef struct
+{
+ pointer pbits; /* pointer to framebuffer */
+ int width; /* delta to add to a framebuffer addr to move one row down */
+} miScreenInitParmsRec, *miScreenInitParmsPtr;
+
+
+/* this plugs into pScreen->ModifyPixmapHeader */
+Bool
+miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, devKind,
+ pPixData)
+ PixmapPtr pPixmap;
+ int width;
+ int height;
+ int depth;
+ int bitsPerPixel;
+ int devKind;
+ pointer pPixData;
+{
+ if (!pPixmap)
+ return FALSE;
+ pPixmap->drawable.depth = depth;
+ pPixmap->drawable.bitsPerPixel = bitsPerPixel;
+ pPixmap->drawable.id = 0;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap->drawable.x = 0;
+ pPixmap->drawable.y = 0;
+ pPixmap->drawable.width = width;
+ pPixmap->drawable.height = height;
+ pPixmap->devKind = devKind;
+ pPixmap->refcnt = 1;
+ pPixmap->devPrivate.ptr = pPixData;
+ return TRUE;
+}
+
+
+/*ARGSUSED*/
+Bool
+miCloseScreen (index, pScreen)
+ int index;
+ ScreenPtr pScreen;
+{
+ return ((*pScreen->DestroyPixmap)((PixmapPtr)pScreen->devPrivate));
+}
+
+/* With the introduction of pixmap privates, the "screen pixmap" can no
+ * longer be created in miScreenInit, since all the modules that could
+ * possibly ask for pixmap private space have not been initialized at
+ * that time. pScreen->CreateScreenResources is called after all
+ * possible private-requesting modules have been inited; we create the
+ * screen pixmap here.
+ */
+Bool
+miCreateScreenResources(pScreen)
+ ScreenPtr pScreen;
+{
+ miScreenInitParmsPtr pScrInitParms;
+ pointer value;
+
+ pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate;
+
+ /* if width is non-zero, pScreen->devPrivate will be a pixmap
+ * else it will just take the value pbits
+ */
+ if (pScrInitParms->width)
+ {
+ PixmapPtr pPixmap;
+
+ /* create a pixmap with no data, then redirect it to point to
+ * the screen
+ */
+ pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth);
+ if (!pPixmap)
+ return FALSE;
+
+ if (!(*pScreen->ModifyPixmapHeader)(pPixmap, pScreen->width,
+ pScreen->height, pScreen->rootDepth,
+ BitsPerPixel(pScreen->rootDepth),
+ PixmapBytePad(pScrInitParms->width, pScreen->rootDepth),
+ pScrInitParms->pbits))
+ return FALSE;
+ value = (pointer)pPixmap;
+ }
+ else
+ {
+ value = pScrInitParms->pbits;
+ }
+ xfree(pScreen->devPrivate); /* freeing miScreenInitParmsRec */
+ pScreen->devPrivate = value; /* pPixmap or pbits */
+ return TRUE;
+}
+
+Bool
+miScreenDevPrivateInit(pScreen, width, pbits)
+ register ScreenPtr pScreen;
+ int width;
+ pointer pbits;
+{
+ miScreenInitParmsPtr pScrInitParms;
+
+ /* Stash pbits and width in a short-lived miScreenInitParmsRec attached
+ * to the screen, until CreateScreenResources can put them in the
+ * screen pixmap.
+ */
+ pScrInitParms = (miScreenInitParmsPtr)xalloc(sizeof(miScreenInitParmsRec));
+ if (!pScrInitParms)
+ return FALSE;
+ pScrInitParms->pbits = pbits;
+ pScrInitParms->width = width;
+ pScreen->devPrivate = (pointer)pScrInitParms;
+ return TRUE;
+}
+
+Bool
+miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
+ rootDepth, numDepths, depths, rootVisual, numVisuals, visuals)
+ register ScreenPtr pScreen;
+ pointer pbits; /* pointer to screen bits */
+ int xsize, ysize; /* in pixels */
+ int dpix, dpiy; /* dots per inch */
+ int width; /* pixel width of frame buffer */
+ int rootDepth; /* depth of root window */
+ int numDepths; /* number of depths supported */
+ DepthRec *depths; /* supported depths */
+ VisualID rootVisual; /* root visual */
+ int numVisuals; /* number of visuals supported */
+ VisualRec *visuals; /* supported visuals */
+{
+ pScreen->width = xsize;
+ pScreen->height = ysize;
+ pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10);
+ pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10);
+ pScreen->numDepths = numDepths;
+ pScreen->rootDepth = rootDepth;
+ pScreen->allowedDepths = depths;
+ pScreen->rootVisual = rootVisual;
+ /* defColormap */
+ pScreen->minInstalledCmaps = 1;
+ pScreen->maxInstalledCmaps = 1;
+ pScreen->backingStoreSupport = NotUseful;
+ pScreen->saveUnderSupport = NotUseful;
+ /* whitePixel, blackPixel */
+ pScreen->ModifyPixmapHeader = miModifyPixmapHeader;
+ pScreen->CreateScreenResources = miCreateScreenResources;
+ pScreen->GetScreenPixmap = miGetScreenPixmap;
+ pScreen->SetScreenPixmap = miSetScreenPixmap;
+ pScreen->numVisuals = numVisuals;
+ pScreen->visuals = visuals;
+ if (width)
+ {
+#ifdef MITSHM
+ ShmRegisterFbFuncs(pScreen);
+#endif
+ pScreen->CloseScreen = miCloseScreen;
+ }
+ /* else CloseScreen */
+ /* QueryBestSize, SaveScreen, GetImage, GetSpans */
+ pScreen->PointerNonInterestBox = (void (*)()) 0;
+ pScreen->SourceValidate = (void (*)()) 0;
+ /* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */
+ /* RealizeWindow, UnrealizeWindow */
+ pScreen->ValidateTree = miValidateTree;
+ pScreen->PostValidateTree = (void (*)()) 0;
+ pScreen->WindowExposures = miWindowExposures;
+ /* PaintWindowBackground, PaintWindowBorder, CopyWindow */
+ pScreen->ClearToBackground = miClearToBackground;
+ pScreen->ClipNotify = (void (*)()) 0;
+ /* CreatePixmap, DestroyPixmap */
+ /* RealizeFont, UnrealizeFont */
+ /* CreateGC */
+ /* CreateColormap, DestroyColormap, InstallColormap, UninstallColormap */
+ /* ListInstalledColormaps, StoreColors, ResolveColor */
+ pScreen->RegionCreate = miRegionCreate;
+ pScreen->RegionInit = miRegionInit;
+ pScreen->RegionCopy = miRegionCopy;
+ pScreen->RegionDestroy = miRegionDestroy;
+ pScreen->RegionUninit = miRegionUninit;
+ pScreen->Intersect = miIntersect;
+ pScreen->Union = miUnion;
+ pScreen->Subtract = miSubtract;
+ pScreen->Inverse = miInverse;
+ pScreen->RegionReset = miRegionReset;
+ pScreen->TranslateRegion = miTranslateRegion;
+ pScreen->RectIn = miRectIn;
+ pScreen->PointInRegion = miPointInRegion;
+ pScreen->RegionNotEmpty = miRegionNotEmpty;
+ pScreen->RegionEmpty = miRegionEmpty;
+ pScreen->RegionExtents = miRegionExtents;
+ pScreen->RegionAppend = miRegionAppend;
+ pScreen->RegionValidate = miRegionValidate;
+ /* BitmapToRegion */
+ pScreen->RectsToRegion = miRectsToRegion;
+ pScreen->SendGraphicsExpose = miSendGraphicsExpose;
+ pScreen->BlockHandler = (void (*)())NoopDDA;
+ pScreen->WakeupHandler = (void (*)())NoopDDA;
+ pScreen->blockData = (pointer)0;
+ pScreen->wakeupData = (pointer)0;
+ pScreen->MarkWindow = miMarkWindow;
+ pScreen->MarkOverlappedWindows = miMarkOverlappedWindows;
+ pScreen->ChangeSaveUnder = miChangeSaveUnder;
+ pScreen->PostChangeSaveUnder = miPostChangeSaveUnder;
+ pScreen->MoveWindow = miMoveWindow;
+ pScreen->ResizeWindow = miSlideAndSizeWindow;
+ pScreen->GetLayerWindow = miGetLayerWindow;
+ pScreen->HandleExposures = miHandleValidateExposures;
+ pScreen->ReparentWindow = (void (*)())0;
+ pScreen->ChangeBorderWidth = miChangeBorderWidth;
+#ifdef SHAPE
+ pScreen->SetShape = miSetShape;
+#endif
+ pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow;
+
+ miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS);
+
+ return miScreenDevPrivateInit(pScreen, width, pbits);
+}
+
+int
+miAllocateGCPrivateIndex()
+{
+ static int privateIndex = -1;
+ static unsigned long miGeneration = 0;
+
+ if (miGeneration != serverGeneration)
+ {
+ privateIndex = AllocateGCPrivateIndex();
+ miGeneration = serverGeneration;
+ }
+ return privateIndex;
+}
+
+int miZeroLineScreenIndex;
+int miZeroLineGeneration;
+
+void
+miSetZeroLineBias(pScreen, bias)
+ ScreenPtr pScreen;
+ unsigned int bias;
+{
+ if (miZeroLineGeneration != serverGeneration)
+ {
+ miZeroLineScreenIndex = AllocateScreenPrivateIndex();
+ miZeroLineGeneration = serverGeneration;
+ }
+ if (miZeroLineScreenIndex >= 0)
+ pScreen->devPrivates[miZeroLineScreenIndex].uval = bias;
+}
+
+PixmapPtr
+miGetScreenPixmap(pScreen)
+ ScreenPtr pScreen;
+{
+ return (PixmapPtr)(pScreen->devPrivate);
+}
+
+void
+miSetScreenPixmap(pPix)
+ PixmapPtr pPix;
+{
+ if (pPix)
+ pPix->drawable.pScreen->devPrivate = (pointer)pPix;
+}
diff --git a/xc/programs/Xserver/mi/mispans.c b/xc/programs/Xserver/mi/mispans.c
new file mode 100644
index 000000000..abf34adc2
--- /dev/null
+++ b/xc/programs/Xserver/mi/mispans.c
@@ -0,0 +1,555 @@
+/* $XFree86: xc/programs/Xserver/mi/mispans.c,v 3.1 1998/10/04 09:39:33 dawes Exp $ */
+/***********************************************************
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* $TOG: mispans.c /main/7 1998/02/09 14:48:44 kaleb $ */
+
+#include "misc.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "mispans.h"
+
+/*
+
+These routines maintain lists of Spans, in order to implement the
+``touch-each-pixel-once'' rules of wide lines and arcs.
+
+Written by Joel McCormack, Summer 1989.
+
+*/
+
+
+void miInitSpanGroup(spanGroup)
+ SpanGroup *spanGroup;
+{
+ spanGroup->size = 0;
+ spanGroup->count = 0;
+ spanGroup->group = NULL;
+ spanGroup->ymin = MAXSHORT;
+ spanGroup->ymax = MINSHORT;
+} /* InitSpanGroup */
+
+#define YMIN(spans) (spans->points[0].y)
+#define YMAX(spans) (spans->points[spans->count-1].y)
+
+void miSubtractSpans (spanGroup, sub)
+ SpanGroup *spanGroup;
+ Spans *sub;
+{
+ int i, subCount, spansCount;
+ int ymin, ymax, xmin, xmax;
+ Spans *spans;
+ DDXPointPtr subPt, spansPt;
+ int *subWid, *spansWid;
+ int extra;
+
+ ymin = YMIN(sub);
+ ymax = YMAX(sub);
+ spans = spanGroup->group;
+ for (i = spanGroup->count; i; i--, spans++) {
+ if (YMIN(spans) <= ymax && ymin <= YMAX(spans)) {
+ subCount = sub->count;
+ subPt = sub->points;
+ subWid = sub->widths;
+ spansCount = spans->count;
+ spansPt = spans->points;
+ spansWid = spans->widths;
+ extra = 0;
+ for (;;)
+ {
+ while (spansCount && spansPt->y < subPt->y)
+ {
+ spansPt++; spansWid++; spansCount--;
+ }
+ if (!spansCount)
+ break;
+ while (subCount && subPt->y < spansPt->y)
+ {
+ subPt++; subWid++; subCount--;
+ }
+ if (!subCount)
+ break;
+ if (subPt->y == spansPt->y)
+ {
+ xmin = subPt->x;
+ xmax = xmin + *subWid;
+ if (xmin >= spansPt->x + *spansWid || spansPt->x >= xmax)
+ {
+ ;
+ }
+ else if (xmin <= spansPt->x)
+ {
+ if (xmax >= spansPt->x + *spansWid)
+ {
+ memmove (spansPt, spansPt + 1, sizeof *spansPt * (spansCount - 1));
+ memmove (spansWid, spansWid + 1, sizeof *spansWid * (spansCount - 1));
+ spansPt--;
+ spansWid--;
+ spans->count--;
+ extra++;
+ }
+ else
+ {
+ *spansWid = *spansWid - (xmax - spansPt->x);
+ spansPt->x = xmax;
+ }
+ }
+ else
+ {
+ if (xmax >= spansPt->x + *spansWid)
+ {
+ *spansWid = xmin - spansPt->x;
+ }
+ else
+ {
+ if (!extra) {
+ DDXPointPtr newPt;
+ int *newwid;
+
+#define EXTRA 8
+ newPt = (DDXPointPtr) xrealloc (spans->points, (spans->count + EXTRA) * sizeof (DDXPointRec));
+ if (!newPt)
+ break;
+ spansPt = newPt + (spansPt - spans->points);
+ spans->points = newPt;
+ newwid = (int *) xrealloc (spans->widths, (spans->count + EXTRA) * sizeof (int));
+ if (!newwid)
+ break;
+ spansWid = newwid + (spansWid - spans->widths);
+ spans->widths = newwid;
+ extra = EXTRA;
+ }
+ memmove (spansPt + 1, spansPt, sizeof *spansPt * (spansCount));
+ memmove (spansWid + 1, spansWid, sizeof *spansWid * (spansCount));
+ spans->count++;
+ extra--;
+ *spansWid = xmin - spansPt->x;
+ spansWid++;
+ spansPt++;
+ *spansWid = *spansWid - (xmax - spansPt->x);
+ spansPt->x = xmax;
+ }
+ }
+ }
+ spansPt++; spansWid++; spansCount--;
+ }
+ }
+ }
+}
+
+void miAppendSpans(spanGroup, otherGroup, spans)
+ SpanGroup *spanGroup;
+ SpanGroup *otherGroup;
+ Spans *spans;
+{
+ register int ymin, ymax;
+ register int spansCount;
+
+ spansCount = spans->count;
+ if (spansCount > 0) {
+ if (spanGroup->size == spanGroup->count) {
+ spanGroup->size = (spanGroup->size + 8) * 2;
+ spanGroup->group = (Spans *)
+ xrealloc(spanGroup->group, sizeof(Spans) * spanGroup->size);
+ }
+
+ spanGroup->group[spanGroup->count] = *spans;
+ (spanGroup->count)++;
+ ymin = spans->points[0].y;
+ if (ymin < spanGroup->ymin) spanGroup->ymin = ymin;
+ ymax = spans->points[spansCount - 1].y;
+ if (ymax > spanGroup->ymax) spanGroup->ymax = ymax;
+ if (otherGroup &&
+ otherGroup->ymin < ymax &&
+ ymin < otherGroup->ymax)
+ {
+ miSubtractSpans (otherGroup, spans);
+ }
+ }
+ else
+ {
+ xfree (spans->points);
+ xfree (spans->widths);
+ }
+} /* AppendSpans */
+
+void miFreeSpanGroup(spanGroup)
+ SpanGroup *spanGroup;
+{
+ if (spanGroup->group != NULL) xfree(spanGroup->group);
+}
+
+static void QuickSortSpansX(points, widths, numSpans)
+ register DDXPointRec points[];
+ register int widths[];
+ register int numSpans;
+{
+ register int x;
+ register int i, j, m;
+ register DDXPointPtr r;
+
+/* Always called with numSpans > 1 */
+/* Sorts only by x, as all y should be the same */
+
+#define ExchangeSpans(a, b) \
+{ \
+ DDXPointRec tpt; \
+ register int tw; \
+ \
+ tpt = points[a]; points[a] = points[b]; points[b] = tpt; \
+ tw = widths[a]; widths[a] = widths[b]; widths[b] = tw; \
+}
+
+ do {
+ if (numSpans < 9) {
+ /* Do insertion sort */
+ register int xprev;
+
+ xprev = points[0].x;
+ i = 1;
+ do { /* while i != numSpans */
+ x = points[i].x;
+ if (xprev > x) {
+ /* points[i] is out of order. Move into proper location. */
+ DDXPointRec tpt;
+ int tw, k;
+
+ for (j = 0; x >= points[j].x; j++) {}
+ tpt = points[i];
+ tw = widths[i];
+ for (k = i; k != j; k--) {
+ points[k] = points[k-1];
+ widths[k] = widths[k-1];
+ }
+ points[j] = tpt;
+ widths[j] = tw;
+ x = points[i].x;
+ } /* if out of order */
+ xprev = x;
+ i++;
+ } while (i != numSpans);
+ return;
+ }
+
+ /* Choose partition element, stick in location 0 */
+ m = numSpans / 2;
+ if (points[m].x > points[0].x) ExchangeSpans(m, 0);
+ if (points[m].x > points[numSpans-1].x) ExchangeSpans(m, numSpans-1);
+ if (points[m].x > points[0].x) ExchangeSpans(m, 0);
+ x = points[0].x;
+
+ /* Partition array */
+ i = 0;
+ j = numSpans;
+ do {
+ r = &(points[i]);
+ do {
+ r++;
+ i++;
+ } while (i != numSpans && r->x < x);
+ r = &(points[j]);
+ do {
+ r--;
+ j--;
+ } while (x < r->x);
+ if (i < j) ExchangeSpans(i, j);
+ } while (i < j);
+
+ /* Move partition element back to middle */
+ ExchangeSpans(0, j);
+
+ /* Recurse */
+ if (numSpans-j-1 > 1)
+ QuickSortSpansX(&points[j+1], &widths[j+1], numSpans-j-1);
+ numSpans = j;
+ } while (numSpans > 1);
+} /* QuickSortSpans */
+
+
+static int UniquifySpansX(spans, newPoints, newWidths)
+ Spans *spans;
+ register DDXPointRec *newPoints;
+ register int *newWidths;
+{
+ register int newx1, newx2, oldpt, i, y;
+ register DDXPointRec *oldPoints;
+ register int *oldWidths;
+ int *startNewWidths;
+
+/* Always called with numSpans > 1 */
+/* Uniquify the spans, and stash them into newPoints and newWidths. Return the
+ number of unique spans. */
+
+
+ startNewWidths = newWidths;
+
+ oldPoints = spans->points;
+ oldWidths = spans->widths;
+
+ y = oldPoints->y;
+ newx1 = oldPoints->x;
+ newx2 = newx1 + *oldWidths;
+
+ for (i = spans->count-1; i != 0; i--) {
+ oldPoints++;
+ oldWidths++;
+ oldpt = oldPoints->x;
+ if (oldpt > newx2) {
+ /* Write current span, start a new one */
+ newPoints->x = newx1;
+ newPoints->y = y;
+ *newWidths = newx2 - newx1;
+ newPoints++;
+ newWidths++;
+ newx1 = oldpt;
+ newx2 = oldpt + *oldWidths;
+ } else {
+ /* extend current span, if old extends beyond new */
+ oldpt = oldpt + *oldWidths;
+ if (oldpt > newx2) newx2 = oldpt;
+ }
+ } /* for */
+
+ /* Write final span */
+ newPoints->x = newx1;
+ *newWidths = newx2 - newx1;
+ newPoints->y = y;
+
+ return (newWidths - startNewWidths) + 1;
+} /* UniquifySpansX */
+
+void
+miDisposeSpanGroup (spanGroup)
+ SpanGroup *spanGroup;
+{
+ int i;
+ Spans *spans;
+
+ for (i = 0; i < spanGroup->count; i++)
+ {
+ spans = spanGroup->group + i;
+ xfree (spans->points);
+ xfree (spans->widths);
+ }
+}
+
+void miFillUniqueSpanGroup(pDraw, pGC, spanGroup)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ SpanGroup *spanGroup;
+{
+ register int i;
+ register Spans *spans;
+ register Spans *yspans;
+ register int *ysizes;
+ register int ymin, ylength;
+
+ /* Outgoing spans for one big call to FillSpans */
+ register DDXPointPtr points;
+ register int *widths;
+ register int count;
+
+ if (spanGroup->count == 0) return;
+
+ if (spanGroup->count == 1) {
+ /* Already should be sorted, unique */
+ spans = spanGroup->group;
+ (*pGC->ops->FillSpans)
+ (pDraw, pGC, spans->count, spans->points, spans->widths, TRUE);
+ xfree(spans->points);
+ xfree(spans->widths);
+ }
+ else
+ {
+ /* Yuck. Gross. Radix sort into y buckets, then sort x and uniquify */
+ /* This seems to be the fastest thing to do. I've tried sorting on
+ both x and y at the same time rather than creating into all those
+ y buckets, but it was somewhat slower. */
+
+ ymin = spanGroup->ymin;
+ ylength = spanGroup->ymax - ymin + 1;
+
+ /* Allocate Spans for y buckets */
+ yspans = (Spans *) xalloc(ylength * sizeof(Spans));
+ ysizes = (int *) xalloc(ylength * sizeof (int));
+
+ if (!yspans || !ysizes)
+ {
+ if (yspans)
+ xfree (yspans);
+ if (ysizes)
+ xfree (ysizes);
+ miDisposeSpanGroup (spanGroup);
+ return;
+ }
+
+ for (i = 0; i != ylength; i++) {
+ ysizes[i] = 0;
+ yspans[i].count = 0;
+ yspans[i].points = NULL;
+ yspans[i].widths = NULL;
+ }
+
+ /* Go through every single span and put it into the correct bucket */
+ count = 0;
+ for (i = 0, spans = spanGroup->group;
+ i != spanGroup->count;
+ i++, spans++) {
+ int index;
+ int j;
+
+ for (j = 0, points = spans->points, widths = spans->widths;
+ j != spans->count;
+ j++, points++, widths++) {
+ index = points->y - ymin;
+ if (index >= 0 && index < ylength) {
+ Spans *newspans = &(yspans[index]);
+ if (newspans->count == ysizes[index]) {
+ DDXPointPtr newpoints;
+ int *newwidths;
+ ysizes[index] = (ysizes[index] + 8) * 2;
+ newpoints = (DDXPointPtr) xrealloc(
+ newspans->points,
+ ysizes[index] * sizeof(DDXPointRec));
+ newwidths = (int *) xrealloc(
+ newspans->widths,
+ ysizes[index] * sizeof(int));
+ if (!newpoints || !newwidths)
+ {
+ int i;
+
+ for (i = 0; i < ylength; i++)
+ {
+ xfree (yspans[i].points);
+ xfree (yspans[i].widths);
+ }
+ xfree (yspans);
+ xfree (ysizes);
+ miDisposeSpanGroup (spanGroup);
+ return;
+ }
+ newspans->points = newpoints;
+ newspans->widths = newwidths;
+ }
+ newspans->points[newspans->count] = *points;
+ newspans->widths[newspans->count] = *widths;
+ (newspans->count)++;
+ } /* if y value of span in range */
+ } /* for j through spans */
+ count += spans->count;
+ xfree(spans->points);
+ spans->points = NULL;
+ xfree(spans->widths);
+ spans->widths = NULL;
+ } /* for i thorough Spans */
+
+ /* Now sort by x and uniquify each bucket into the final array */
+ points = (DDXPointPtr) xalloc(count * sizeof(DDXPointRec));
+ widths = (int *) xalloc(count * sizeof(int));
+ if (!points || !widths)
+ {
+ int i;
+
+ for (i = 0; i < ylength; i++)
+ {
+ xfree (yspans[i].points);
+ xfree (yspans[i].widths);
+ }
+ xfree (yspans);
+ xfree (ysizes);
+ if (points)
+ xfree (points);
+ if (widths)
+ xfree (widths);
+ return;
+ }
+ count = 0;
+ for (i = 0; i != ylength; i++) {
+ int ycount = yspans[i].count;
+ if (ycount > 0) {
+ if (ycount > 1) {
+ QuickSortSpansX(yspans[i].points, yspans[i].widths, ycount);
+ count += UniquifySpansX
+ (&(yspans[i]), &(points[count]), &(widths[count]));
+ } else {
+ points[count] = yspans[i].points[0];
+ widths[count] = yspans[i].widths[0];
+ count++;
+ }
+ xfree(yspans[i].points);
+ xfree(yspans[i].widths);
+ }
+ }
+
+ (*pGC->ops->FillSpans) (pDraw, pGC, count, points, widths, TRUE);
+ xfree(points);
+ xfree(widths);
+ xfree(yspans);
+ xfree(ysizes); /* use (DE)ALLOCATE_LOCAL for these? */
+ }
+
+ spanGroup->count = 0;
+ spanGroup->ymin = MAXSHORT;
+ spanGroup->ymax = MINSHORT;
+}
+
+
+void miFillSpanGroup(pDraw, pGC, spanGroup)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ SpanGroup *spanGroup;
+{
+ register int i;
+ register Spans *spans;
+
+ for (i = 0, spans = spanGroup->group; i != spanGroup->count; i++, spans++) {
+ (*pGC->ops->FillSpans)
+ (pDraw, pGC, spans->count, spans->points, spans->widths, TRUE);
+ xfree(spans->points);
+ xfree(spans->widths);
+ }
+
+ spanGroup->count = 0;
+ spanGroup->ymin = MAXSHORT;
+ spanGroup->ymax = MINSHORT;
+} /* FillSpanGroup */
diff --git a/xc/programs/Xserver/mi/mispans.h b/xc/programs/Xserver/mi/mispans.h
new file mode 100644
index 000000000..2892cf862
--- /dev/null
+++ b/xc/programs/Xserver/mi/mispans.h
@@ -0,0 +1,128 @@
+/***********************************************************
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* $TOG: mispans.h /main/5 1998/02/09 14:48:48 kaleb $ */
+
+typedef struct {
+ int count; /* number of spans */
+ DDXPointPtr points; /* pointer to list of start points */
+ int *widths; /* pointer to list of widths */
+} Spans;
+
+typedef struct {
+ int size; /* Total number of *Spans allocated */
+ int count; /* Number of *Spans actually in group */
+ Spans *group; /* List of Spans */
+ int ymin, ymax; /* Min, max y values encountered */
+} SpanGroup;
+
+/* Initialize SpanGroup. MUST BE DONE before use. */
+extern void miInitSpanGroup(
+#if NeedFunctionPrototypes
+ SpanGroup * /*spanGroup*/
+#endif
+);
+
+/* Add a Spans to a SpanGroup. The spans MUST BE in y-sorted order */
+extern void miAppendSpans(
+#if NeedFunctionPrototypes
+ SpanGroup * /*spanGroup*/,
+ SpanGroup * /*otherGroup*/,
+ Spans * /*spans*/
+#endif
+);
+
+/* Paint a span group, possibly with some overlap */
+extern void miFillSpanGroup(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ SpanGroup * /*spanGroup*/
+#endif
+);
+
+/* Paint a span group, insuring that each pixel is painted at most once */
+extern void miFillUniqueSpanGroup(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDraw*/,
+ GCPtr /*pGC*/,
+ SpanGroup * /*spanGroup*/
+#endif
+);
+
+/* Free up data in a span group. MUST BE DONE or you'll suffer memory leaks */
+extern void miFreeSpanGroup(
+#if NeedFunctionPrototypes
+ SpanGroup * /*spanGroup*/
+#endif
+);
+
+extern void miSubtractSpans(
+#if NeedFunctionPrototypes
+ SpanGroup * /*spanGroup*/,
+ Spans * /*sub*/
+#endif
+);
+
+extern void miDisposeSpanGroup(
+#if NeedFunctionPrototypes
+ SpanGroup * /*spanGroup*/
+#endif
+);
+
+extern int miClipSpans(
+#if NeedFunctionPrototypes
+ RegionPtr /*prgnDst*/,
+ DDXPointPtr /*ppt*/,
+ int * /*pwidth*/,
+ int /*nspans*/,
+ DDXPointPtr /*pptNew*/,
+ int * /*pwidthNew*/,
+ int /*fSorted*/
+#endif
+);
+
+/* Rops which must use span groups */
+#define miSpansCarefulRop(rop) (((rop) & 0xc) == 0x8 || ((rop) & 0x3) == 0x2)
+#define miSpansEasyRop(rop) (!miSpansCarefulRop(rop))
+
diff --git a/xc/programs/Xserver/mi/misprite.c b/xc/programs/Xserver/mi/misprite.c
new file mode 100644
index 000000000..a97f7c6e9
--- /dev/null
+++ b/xc/programs/Xserver/mi/misprite.c
@@ -0,0 +1,2064 @@
+/*
+ * misprite.c
+ *
+ * machine independent software sprite routines
+ */
+
+/* $TOG: misprite.c /main/49 1998/02/09 14:48:56 kaleb $ */
+
+/*
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+*/
+/* $XFree86: xc/programs/Xserver/mi/misprite.c,v 3.1 1998/10/04 09:39:33 dawes Exp $ */
+
+# include "X.h"
+# include "Xproto.h"
+# include "misc.h"
+# include "pixmapstr.h"
+# include "input.h"
+# include "mi.h"
+# include "cursorstr.h"
+# include "font.h"
+# include "scrnintstr.h"
+# include "colormapst.h"
+# include "windowstr.h"
+# include "gcstruct.h"
+# include "mipointer.h"
+# include "mispritest.h"
+# include "dixfontstr.h"
+# include "fontstruct.h"
+
+/*
+ * screen wrappers
+ */
+
+static int miSpriteScreenIndex;
+static unsigned long miSpriteGeneration = 0;
+
+static Bool miSpriteCloseScreen();
+static void miSpriteGetImage();
+static void miSpriteGetSpans();
+static void miSpriteSourceValidate();
+static Bool miSpriteCreateGC();
+static void miSpriteBlockHandler();
+static void miSpriteInstallColormap();
+static void miSpriteStoreColors();
+
+static void miSpritePaintWindowBackground();
+static void miSpritePaintWindowBorder();
+static void miSpriteCopyWindow();
+static void miSpriteClearToBackground();
+
+static void miSpriteSaveDoomedAreas();
+static RegionPtr miSpriteRestoreAreas();
+static void miSpriteComputeSaved();
+
+#define SCREEN_PROLOGUE(pScreen, field)\
+ ((pScreen)->field = \
+ ((miSpriteScreenPtr) (pScreen)->devPrivates[miSpriteScreenIndex].ptr)->field)
+
+#define SCREEN_EPILOGUE(pScreen, field, wrapper)\
+ ((pScreen)->field = wrapper)
+
+/*
+ * GC func wrappers
+ */
+
+static int miSpriteGCIndex;
+
+static void miSpriteValidateGC (), miSpriteCopyGC ();
+static void miSpriteDestroyGC(), miSpriteChangeGC();
+static void miSpriteChangeClip(), miSpriteDestroyClip();
+static void miSpriteCopyClip();
+
+static GCFuncs miSpriteGCFuncs = {
+ miSpriteValidateGC,
+ miSpriteChangeGC,
+ miSpriteCopyGC,
+ miSpriteDestroyGC,
+ miSpriteChangeClip,
+ miSpriteDestroyClip,
+ miSpriteCopyClip,
+};
+
+#define GC_FUNC_PROLOGUE(pGC) \
+ miSpriteGCPtr pGCPriv = \
+ (miSpriteGCPtr) (pGC)->devPrivates[miSpriteGCIndex].ptr;\
+ (pGC)->funcs = pGCPriv->wrapFuncs; \
+ if (pGCPriv->wrapOps) \
+ (pGC)->ops = pGCPriv->wrapOps;
+
+#define GC_FUNC_EPILOGUE(pGC) \
+ pGCPriv->wrapFuncs = (pGC)->funcs; \
+ (pGC)->funcs = &miSpriteGCFuncs; \
+ if (pGCPriv->wrapOps) \
+ { \
+ pGCPriv->wrapOps = (pGC)->ops; \
+ (pGC)->ops = &miSpriteGCOps; \
+ }
+
+/*
+ * GC op wrappers
+ */
+
+static void miSpriteFillSpans(), miSpriteSetSpans();
+static void miSpritePutImage();
+static RegionPtr miSpriteCopyArea(), miSpriteCopyPlane();
+static void miSpritePolyPoint(), miSpritePolylines();
+static void miSpritePolySegment(), miSpritePolyRectangle();
+static void miSpritePolyArc(), miSpriteFillPolygon();
+static void miSpritePolyFillRect(), miSpritePolyFillArc();
+static int miSpritePolyText8(), miSpritePolyText16();
+static void miSpriteImageText8(), miSpriteImageText16();
+static void miSpriteImageGlyphBlt(), miSpritePolyGlyphBlt();
+static void miSpritePushPixels();
+#ifdef NEED_LINEHELPER
+static void miSpriteLineHelper();
+#endif
+
+static GCOps miSpriteGCOps = {
+ miSpriteFillSpans, miSpriteSetSpans, miSpritePutImage,
+ miSpriteCopyArea, miSpriteCopyPlane, miSpritePolyPoint,
+ miSpritePolylines, miSpritePolySegment, miSpritePolyRectangle,
+ miSpritePolyArc, miSpriteFillPolygon, miSpritePolyFillRect,
+ miSpritePolyFillArc, miSpritePolyText8, miSpritePolyText16,
+ miSpriteImageText8, miSpriteImageText16, miSpriteImageGlyphBlt,
+ miSpritePolyGlyphBlt, miSpritePushPixels
+#ifdef NEED_LINEHELPER
+ , miSpriteLineHelper
+#endif
+};
+
+/*
+ * testing only -- remove cursor for every draw. Eventually,
+ * each draw operation will perform a bounding box check against
+ * the saved cursor area
+ */
+
+#define GC_SETUP_CHEAP(pDrawable) \
+ miSpriteScreenPtr pScreenPriv = (miSpriteScreenPtr) \
+ (pDrawable)->pScreen->devPrivates[miSpriteScreenIndex].ptr; \
+
+#define GC_SETUP(pDrawable, pGC) \
+ GC_SETUP_CHEAP(pDrawable) \
+ miSpriteGCPtr pGCPrivate = (miSpriteGCPtr) \
+ (pGC)->devPrivates[miSpriteGCIndex].ptr; \
+ GCFuncs *oldFuncs = pGC->funcs;
+
+#define GC_SETUP_AND_CHECK(pDrawable, pGC) \
+ GC_SETUP(pDrawable, pGC); \
+ if (GC_CHECK((WindowPtr)pDrawable)) \
+ miSpriteRemoveCursor (pDrawable->pScreen);
+
+#define GC_CHECK(pWin) \
+ (pScreenPriv->isUp && \
+ (pScreenPriv->pCacheWin == pWin ? \
+ pScreenPriv->isInCacheWin : ( \
+ (pScreenPriv->pCacheWin = (pWin)), \
+ (pScreenPriv->isInCacheWin = \
+ (pWin)->drawable.x < pScreenPriv->saved.x2 && \
+ pScreenPriv->saved.x1 < (pWin)->drawable.x + \
+ (int) (pWin)->drawable.width && \
+ (pWin)->drawable.y < pScreenPriv->saved.y2 && \
+ pScreenPriv->saved.y1 < (pWin)->drawable.y + \
+ (int) (pWin)->drawable.height &&\
+ RECT_IN_REGION((pWin)->drawable.pScreen, &(pWin)->borderClip, \
+ &pScreenPriv->saved) != rgnOUT))))
+
+#define GC_OP_PROLOGUE(pGC) { \
+ (pGC)->funcs = pGCPrivate->wrapFuncs; \
+ (pGC)->ops = pGCPrivate->wrapOps; \
+ }
+
+#define GC_OP_EPILOGUE(pGC) { \
+ pGCPrivate->wrapOps = (pGC)->ops; \
+ (pGC)->funcs = oldFuncs; \
+ (pGC)->ops = &miSpriteGCOps; \
+ }
+
+/*
+ * pointer-sprite method table
+ */
+
+static Bool miSpriteRealizeCursor (), miSpriteUnrealizeCursor ();
+static void miSpriteSetCursor (), miSpriteMoveCursor ();
+
+miPointerSpriteFuncRec miSpritePointerFuncs = {
+ miSpriteRealizeCursor,
+ miSpriteUnrealizeCursor,
+ miSpriteSetCursor,
+ miSpriteMoveCursor,
+};
+
+/*
+ * other misc functions
+ */
+
+static void miSpriteRemoveCursor (), miSpriteRestoreCursor();
+
+/*
+ * miSpriteInitialize -- called from device-dependent screen
+ * initialization proc after all of the function pointers have
+ * been stored in the screen structure.
+ */
+
+Bool
+miSpriteInitialize (pScreen, cursorFuncs, screenFuncs)
+ ScreenPtr pScreen;
+ miSpriteCursorFuncPtr cursorFuncs;
+ miPointerScreenFuncPtr screenFuncs;
+{
+ miSpriteScreenPtr pPriv;
+ VisualPtr pVisual;
+
+ if (miSpriteGeneration != serverGeneration)
+ {
+ miSpriteScreenIndex = AllocateScreenPrivateIndex ();
+ if (miSpriteScreenIndex < 0)
+ return FALSE;
+ miSpriteGeneration = serverGeneration;
+ miSpriteGCIndex = AllocateGCPrivateIndex ();
+ }
+ if (!AllocateGCPrivate(pScreen, miSpriteGCIndex, sizeof(miSpriteGCRec)))
+ return FALSE;
+ pPriv = (miSpriteScreenPtr) xalloc (sizeof (miSpriteScreenRec));
+ if (!pPriv)
+ return FALSE;
+ if (!miPointerInitialize (pScreen, &miSpritePointerFuncs, screenFuncs,TRUE))
+ {
+ xfree ((pointer) pPriv);
+ return FALSE;
+ }
+ for (pVisual = pScreen->visuals;
+ pVisual->vid != pScreen->rootVisual;
+ pVisual++)
+ ;
+ pPriv->pVisual = pVisual;
+ pPriv->CloseScreen = pScreen->CloseScreen;
+ pPriv->GetImage = pScreen->GetImage;
+ pPriv->GetSpans = pScreen->GetSpans;
+ pPriv->SourceValidate = pScreen->SourceValidate;
+ pPriv->CreateGC = pScreen->CreateGC;
+ pPriv->BlockHandler = pScreen->BlockHandler;
+ pPriv->InstallColormap = pScreen->InstallColormap;
+ pPriv->StoreColors = pScreen->StoreColors;
+
+ pPriv->PaintWindowBackground = pScreen->PaintWindowBackground;
+ pPriv->PaintWindowBorder = pScreen->PaintWindowBorder;
+ pPriv->CopyWindow = pScreen->CopyWindow;
+ pPriv->ClearToBackground = pScreen->ClearToBackground;
+
+ pPriv->SaveDoomedAreas = pScreen->SaveDoomedAreas;
+ pPriv->RestoreAreas = pScreen->RestoreAreas;
+
+ pPriv->pCursor = NULL;
+ pPriv->x = 0;
+ pPriv->y = 0;
+ pPriv->isUp = FALSE;
+ pPriv->shouldBeUp = FALSE;
+ pPriv->pCacheWin = NullWindow;
+ pPriv->isInCacheWin = FALSE;
+ pPriv->checkPixels = TRUE;
+ pPriv->pInstalledMap = NULL;
+ pPriv->pColormap = NULL;
+ pPriv->funcs = cursorFuncs;
+ pPriv->colors[SOURCE_COLOR].red = 0;
+ pPriv->colors[SOURCE_COLOR].green = 0;
+ pPriv->colors[SOURCE_COLOR].blue = 0;
+ pPriv->colors[MASK_COLOR].red = 0;
+ pPriv->colors[MASK_COLOR].green = 0;
+ pPriv->colors[MASK_COLOR].blue = 0;
+ pScreen->devPrivates[miSpriteScreenIndex].ptr = (pointer) pPriv;
+ pScreen->CloseScreen = miSpriteCloseScreen;
+ pScreen->GetImage = miSpriteGetImage;
+ pScreen->GetSpans = miSpriteGetSpans;
+ pScreen->SourceValidate = miSpriteSourceValidate;
+ pScreen->CreateGC = miSpriteCreateGC;
+ pScreen->BlockHandler = miSpriteBlockHandler;
+ pScreen->InstallColormap = miSpriteInstallColormap;
+ pScreen->StoreColors = miSpriteStoreColors;
+
+ pScreen->PaintWindowBackground = miSpritePaintWindowBackground;
+ pScreen->PaintWindowBorder = miSpritePaintWindowBorder;
+ pScreen->CopyWindow = miSpriteCopyWindow;
+ pScreen->ClearToBackground = miSpriteClearToBackground;
+
+ pScreen->SaveDoomedAreas = miSpriteSaveDoomedAreas;
+ pScreen->RestoreAreas = miSpriteRestoreAreas;
+
+ return TRUE;
+}
+
+/*
+ * Screen wrappers
+ */
+
+/*
+ * CloseScreen wrapper -- unwrap everything, free the private data
+ * and call the wrapped function
+ */
+
+static Bool
+miSpriteCloseScreen (i, pScreen)
+ ScreenPtr pScreen;
+{
+ miSpriteScreenPtr pScreenPriv;
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ pScreen->GetImage = pScreenPriv->GetImage;
+ pScreen->GetSpans = pScreenPriv->GetSpans;
+ pScreen->SourceValidate = pScreenPriv->SourceValidate;
+ pScreen->CreateGC = pScreenPriv->CreateGC;
+ pScreen->BlockHandler = pScreenPriv->BlockHandler;
+ pScreen->InstallColormap = pScreenPriv->InstallColormap;
+ pScreen->StoreColors = pScreenPriv->StoreColors;
+
+ pScreen->PaintWindowBackground = pScreenPriv->PaintWindowBackground;
+ pScreen->PaintWindowBorder = pScreenPriv->PaintWindowBorder;
+ pScreen->CopyWindow = pScreenPriv->CopyWindow;
+ pScreen->ClearToBackground = pScreenPriv->ClearToBackground;
+
+ pScreen->SaveDoomedAreas = pScreenPriv->SaveDoomedAreas;
+ pScreen->RestoreAreas = pScreenPriv->RestoreAreas;
+
+ xfree ((pointer) pScreenPriv);
+
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+static void
+miSpriteGetImage (pDrawable, sx, sy, w, h, format, planemask, pdstLine)
+ DrawablePtr pDrawable;
+ int sx, sy, w, h;
+ unsigned int format;
+ unsigned long planemask;
+ char *pdstLine;
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ miSpriteScreenPtr pScreenPriv;
+
+ SCREEN_PROLOGUE (pScreen, GetImage);
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+ if (pDrawable->type == DRAWABLE_WINDOW &&
+ pScreenPriv->isUp &&
+ ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y, sx, sy, w, h))
+ {
+ miSpriteRemoveCursor (pScreen);
+ }
+
+ (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
+ format, planemask, pdstLine);
+
+ SCREEN_EPILOGUE (pScreen, GetImage, miSpriteGetImage);
+}
+
+static void
+miSpriteGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart)
+ DrawablePtr pDrawable;
+ int wMax;
+ DDXPointPtr ppt;
+ int *pwidth;
+ int nspans;
+ char *pdstStart;
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ miSpriteScreenPtr pScreenPriv;
+
+ SCREEN_PROLOGUE (pScreen, GetSpans);
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+ if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp)
+ {
+ register DDXPointPtr pts;
+ register int *widths;
+ register int nPts;
+ register int xorg,
+ yorg;
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+
+ for (pts = ppt, widths = pwidth, nPts = nspans;
+ nPts--;
+ pts++, widths++)
+ {
+ if (SPN_OVERLAP(&pScreenPriv->saved,pts->y+yorg,
+ pts->x+xorg,*widths))
+ {
+ miSpriteRemoveCursor (pScreen);
+ break;
+ }
+ }
+ }
+
+ (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+
+ SCREEN_EPILOGUE (pScreen, GetSpans, miSpriteGetSpans);
+}
+
+static void
+miSpriteSourceValidate (pDrawable, x, y, width, height)
+ DrawablePtr pDrawable;
+ int x, y, width, height;
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ miSpriteScreenPtr pScreenPriv;
+
+ SCREEN_PROLOGUE (pScreen, SourceValidate);
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+ if (pDrawable->type == DRAWABLE_WINDOW && pScreenPriv->isUp &&
+ ORG_OVERLAP(&pScreenPriv->saved, pDrawable->x, pDrawable->y,
+ x, y, width, height))
+ {
+ miSpriteRemoveCursor (pScreen);
+ }
+
+ if (pScreen->SourceValidate)
+ (*pScreen->SourceValidate) (pDrawable, x, y, width, height);
+
+ SCREEN_EPILOGUE (pScreen, SourceValidate, miSpriteSourceValidate);
+}
+
+static Bool
+miSpriteCreateGC (pGC)
+ GCPtr pGC;
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ Bool ret;
+ miSpriteGCPtr pPriv;
+
+ SCREEN_PROLOGUE (pScreen, CreateGC);
+
+ pPriv = (miSpriteGCPtr)pGC->devPrivates[miSpriteGCIndex].ptr;
+
+ ret = (*pScreen->CreateGC) (pGC);
+
+ pPriv->wrapOps = NULL;
+ pPriv->wrapFuncs = pGC->funcs;
+ pGC->funcs = &miSpriteGCFuncs;
+
+ SCREEN_EPILOGUE (pScreen, CreateGC, miSpriteCreateGC);
+
+ return ret;
+}
+
+static void
+miSpriteBlockHandler (i, blockData, pTimeout, pReadmask)
+ int i;
+ pointer blockData;
+ OSTimePtr pTimeout;
+ pointer pReadmask;
+{
+ ScreenPtr pScreen = screenInfo.screens[i];
+ miSpriteScreenPtr pPriv;
+
+ pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+ SCREEN_PROLOGUE(pScreen, BlockHandler);
+
+ (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
+
+ SCREEN_EPILOGUE(pScreen, BlockHandler, miSpriteBlockHandler);
+
+ if (!pPriv->isUp && pPriv->shouldBeUp)
+ miSpriteRestoreCursor (pScreen);
+}
+
+static void
+miSpriteInstallColormap (pMap)
+ ColormapPtr pMap;
+{
+ ScreenPtr pScreen = pMap->pScreen;
+ miSpriteScreenPtr pPriv;
+
+ pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+ SCREEN_PROLOGUE(pScreen, InstallColormap);
+
+ (*pScreen->InstallColormap) (pMap);
+
+ SCREEN_EPILOGUE(pScreen, InstallColormap, miSpriteInstallColormap);
+
+ pPriv->pInstalledMap = pMap;
+ if (pPriv->pColormap != pMap)
+ {
+ pPriv->checkPixels = TRUE;
+ if (pPriv->isUp)
+ miSpriteRemoveCursor (pScreen);
+ }
+}
+
+static void
+miSpriteStoreColors (pMap, ndef, pdef)
+ ColormapPtr pMap;
+ int ndef;
+ xColorItem *pdef;
+{
+ ScreenPtr pScreen = pMap->pScreen;
+ miSpriteScreenPtr pPriv;
+ int i;
+ int updated;
+ VisualPtr pVisual;
+
+ pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+
+ SCREEN_PROLOGUE(pScreen, StoreColors);
+
+ (*pScreen->StoreColors) (pMap, ndef, pdef);
+
+ SCREEN_EPILOGUE(pScreen, StoreColors, miSpriteStoreColors);
+
+ if (pPriv->pColormap == pMap)
+ {
+ updated = 0;
+ pVisual = pMap->pVisual;
+ if (pVisual->class == DirectColor)
+ {
+ /* Direct color - match on any of the subfields */
+
+#define MaskMatch(a,b,mask) ((a) & (pVisual->mask) == (b) & (pVisual->mask))
+
+#define UpdateDAC(plane,dac,mask) {\
+ if (MaskMatch (pPriv->colors[plane].pixel,pdef[i].pixel,mask)) {\
+ pPriv->colors[plane].dac = pdef[i].dac; \
+ updated = 1; \
+ } \
+}
+
+#define CheckDirect(plane) \
+ UpdateDAC(plane,red,redMask) \
+ UpdateDAC(plane,green,greenMask) \
+ UpdateDAC(plane,blue,blueMask)
+
+ for (i = 0; i < ndef; i++)
+ {
+ CheckDirect (SOURCE_COLOR)
+ CheckDirect (MASK_COLOR)
+ }
+ }
+ else
+ {
+ /* PseudoColor/GrayScale - match on exact pixel */
+ for (i = 0; i < ndef; i++)
+ {
+ if (pdef[i].pixel == pPriv->colors[SOURCE_COLOR].pixel)
+ {
+ pPriv->colors[SOURCE_COLOR] = pdef[i];
+ if (++updated == 2)
+ break;
+ }
+ if (pdef[i].pixel == pPriv->colors[MASK_COLOR].pixel)
+ {
+ pPriv->colors[MASK_COLOR] = pdef[i];
+ if (++updated == 2)
+ break;
+ }
+ }
+ }
+ if (updated)
+ {
+ pPriv->checkPixels = TRUE;
+ if (pPriv->isUp)
+ miSpriteRemoveCursor (pScreen);
+ }
+ }
+}
+
+static void
+miSpriteFindColors (pScreen)
+ ScreenPtr pScreen;
+{
+ miSpriteScreenPtr pScreenPriv = (miSpriteScreenPtr)
+ pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ CursorPtr pCursor;
+ xColorItem *sourceColor, *maskColor;
+
+ pCursor = pScreenPriv->pCursor;
+ sourceColor = &pScreenPriv->colors[SOURCE_COLOR];
+ maskColor = &pScreenPriv->colors[MASK_COLOR];
+ if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap ||
+ !(pCursor->foreRed == sourceColor->red &&
+ pCursor->foreGreen == sourceColor->green &&
+ pCursor->foreBlue == sourceColor->blue &&
+ pCursor->backRed == maskColor->red &&
+ pCursor->backGreen == maskColor->green &&
+ pCursor->backBlue == maskColor->blue))
+ {
+ pScreenPriv->pColormap = pScreenPriv->pInstalledMap;
+ sourceColor->red = pCursor->foreRed;
+ sourceColor->green = pCursor->foreGreen;
+ sourceColor->blue = pCursor->foreBlue;
+ FakeAllocColor (pScreenPriv->pColormap, sourceColor);
+ maskColor->red = pCursor->backRed;
+ maskColor->green = pCursor->backGreen;
+ maskColor->blue = pCursor->backBlue;
+ FakeAllocColor (pScreenPriv->pColormap, maskColor);
+ /* "free" the pixels right away, don't let this confuse you */
+ FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel);
+ FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel);
+ }
+ pScreenPriv->checkPixels = FALSE;
+}
+
+/*
+ * BackingStore wrappers
+ */
+
+static void
+miSpriteSaveDoomedAreas (pWin, pObscured, dx, dy)
+ WindowPtr pWin;
+ RegionPtr pObscured;
+ int dx, dy;
+{
+ ScreenPtr pScreen;
+ miSpriteScreenPtr pScreenPriv;
+ BoxRec cursorBox;
+
+ pScreen = pWin->drawable.pScreen;
+
+ SCREEN_PROLOGUE (pScreen, SaveDoomedAreas);
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ if (pScreenPriv->isUp)
+ {
+ cursorBox = pScreenPriv->saved;
+
+ if (dx || dy)
+ {
+ cursorBox.x1 += dx;
+ cursorBox.y1 += dy;
+ cursorBox.x2 += dx;
+ cursorBox.y2 += dy;
+ }
+ if (RECT_IN_REGION( pScreen, pObscured, &cursorBox) != rgnOUT)
+ miSpriteRemoveCursor (pScreen);
+ }
+
+ (*pScreen->SaveDoomedAreas) (pWin, pObscured, dx, dy);
+
+ SCREEN_EPILOGUE (pScreen, SaveDoomedAreas, miSpriteSaveDoomedAreas);
+}
+
+static RegionPtr
+miSpriteRestoreAreas (pWin, prgnExposed)
+ WindowPtr pWin;
+ RegionPtr prgnExposed;
+{
+ ScreenPtr pScreen;
+ miSpriteScreenPtr pScreenPriv;
+ RegionPtr result;
+
+ pScreen = pWin->drawable.pScreen;
+
+ SCREEN_PROLOGUE (pScreen, RestoreAreas);
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ if (pScreenPriv->isUp)
+ {
+ if (RECT_IN_REGION( pScreen, prgnExposed, &pScreenPriv->saved) != rgnOUT)
+ miSpriteRemoveCursor (pScreen);
+ }
+
+ result = (*pScreen->RestoreAreas) (pWin, prgnExposed);
+
+ SCREEN_EPILOGUE (pScreen, RestoreAreas, miSpriteRestoreAreas);
+
+ return result;
+}
+
+/*
+ * Window wrappers
+ */
+
+static void
+miSpritePaintWindowBackground (pWin, pRegion, what)
+ WindowPtr pWin;
+ RegionPtr pRegion;
+ int what;
+{
+ ScreenPtr pScreen;
+ miSpriteScreenPtr pScreenPriv;
+
+ pScreen = pWin->drawable.pScreen;
+
+ SCREEN_PROLOGUE (pScreen, PaintWindowBackground);
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ if (pScreenPriv->isUp)
+ {
+ /*
+ * If the cursor is on the same screen as the window, check the
+ * region to paint for the cursor and remove it as necessary
+ */
+ if (RECT_IN_REGION( pScreen, pRegion, &pScreenPriv->saved) != rgnOUT)
+ miSpriteRemoveCursor (pScreen);
+ }
+
+ (*pScreen->PaintWindowBackground) (pWin, pRegion, what);
+
+ SCREEN_EPILOGUE (pScreen, PaintWindowBackground, miSpritePaintWindowBackground);
+}
+
+static void
+miSpritePaintWindowBorder (pWin, pRegion, what)
+ WindowPtr pWin;
+ RegionPtr pRegion;
+ int what;
+{
+ ScreenPtr pScreen;
+ miSpriteScreenPtr pScreenPriv;
+
+ pScreen = pWin->drawable.pScreen;
+
+ SCREEN_PROLOGUE (pScreen, PaintWindowBorder);
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ if (pScreenPriv->isUp)
+ {
+ /*
+ * If the cursor is on the same screen as the window, check the
+ * region to paint for the cursor and remove it as necessary
+ */
+ if (RECT_IN_REGION( pScreen, pRegion, &pScreenPriv->saved) != rgnOUT)
+ miSpriteRemoveCursor (pScreen);
+ }
+
+ (*pScreen->PaintWindowBorder) (pWin, pRegion, what);
+
+ SCREEN_EPILOGUE (pScreen, PaintWindowBorder, miSpritePaintWindowBorder);
+}
+
+static void
+miSpriteCopyWindow (pWin, ptOldOrg, pRegion)
+ WindowPtr pWin;
+ DDXPointRec ptOldOrg;
+ RegionPtr pRegion;
+{
+ ScreenPtr pScreen;
+ miSpriteScreenPtr pScreenPriv;
+ BoxRec cursorBox;
+ int dx, dy;
+
+ pScreen = pWin->drawable.pScreen;
+
+ SCREEN_PROLOGUE (pScreen, CopyWindow);
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ if (pScreenPriv->isUp)
+ {
+ /*
+ * check both the source and the destination areas. The given
+ * region is source relative, so offset the cursor box by
+ * the delta position
+ */
+ cursorBox = pScreenPriv->saved;
+ dx = pWin->drawable.x - ptOldOrg.x;
+ dy = pWin->drawable.y - ptOldOrg.y;
+ cursorBox.x1 -= dx;
+ cursorBox.x2 -= dx;
+ cursorBox.y1 -= dy;
+ cursorBox.y2 -= dy;
+ if (RECT_IN_REGION( pScreen, pRegion, &pScreenPriv->saved) != rgnOUT ||
+ RECT_IN_REGION( pScreen, pRegion, &cursorBox) != rgnOUT)
+ miSpriteRemoveCursor (pScreen);
+ }
+
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, pRegion);
+
+ SCREEN_EPILOGUE (pScreen, CopyWindow, miSpriteCopyWindow);
+}
+
+static void
+miSpriteClearToBackground (pWin, x, y, w, h, generateExposures)
+ WindowPtr pWin;
+ short x,y;
+ unsigned short w,h;
+ Bool generateExposures;
+{
+ ScreenPtr pScreen;
+ miSpriteScreenPtr pScreenPriv;
+ int realw, realh;
+
+ pScreen = pWin->drawable.pScreen;
+
+ SCREEN_PROLOGUE (pScreen, ClearToBackground);
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ if (GC_CHECK(pWin))
+ {
+ if (!(realw = w))
+ realw = (int) pWin->drawable.width - x;
+ if (!(realh = h))
+ realh = (int) pWin->drawable.height - y;
+ if (ORG_OVERLAP(&pScreenPriv->saved, pWin->drawable.x, pWin->drawable.y,
+ x, y, realw, realh))
+ {
+ miSpriteRemoveCursor (pScreen);
+ }
+ }
+
+ (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
+
+ SCREEN_EPILOGUE (pScreen, ClearToBackground, miSpriteClearToBackground);
+}
+
+/*
+ * GC Func wrappers
+ */
+
+static void
+miSpriteValidateGC (pGC, changes, pDrawable)
+ GCPtr pGC;
+ Mask changes;
+ DrawablePtr pDrawable;
+{
+ GC_FUNC_PROLOGUE (pGC);
+
+ (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
+
+ pGCPriv->wrapOps = NULL;
+ if (pDrawable->type == DRAWABLE_WINDOW && ((WindowPtr) pDrawable)->viewable)
+ {
+ WindowPtr pWin;
+ RegionPtr pRegion;
+
+ pWin = (WindowPtr) pDrawable;
+ pRegion = &pWin->clipList;
+ if (pGC->subWindowMode == IncludeInferiors)
+ pRegion = &pWin->borderClip;
+ if (REGION_NOTEMPTY(pDrawable->pScreen, pRegion))
+ pGCPriv->wrapOps = pGC->ops;
+ }
+
+ GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+miSpriteChangeGC (pGC, mask)
+ GCPtr pGC;
+ unsigned long mask;
+{
+ GC_FUNC_PROLOGUE (pGC);
+
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+
+ GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+miSpriteCopyGC (pGCSrc, mask, pGCDst)
+ GCPtr pGCSrc, pGCDst;
+ unsigned long mask;
+{
+ GC_FUNC_PROLOGUE (pGCDst);
+
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+
+ GC_FUNC_EPILOGUE (pGCDst);
+}
+
+static void
+miSpriteDestroyGC (pGC)
+ GCPtr pGC;
+{
+ GC_FUNC_PROLOGUE (pGC);
+
+ (*pGC->funcs->DestroyGC) (pGC);
+
+ GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+miSpriteChangeClip (pGC, type, pvalue, nrects)
+ GCPtr pGC;
+ int type;
+ pointer pvalue;
+ int nrects;
+{
+ GC_FUNC_PROLOGUE (pGC);
+
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+
+ GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+miSpriteCopyClip(pgcDst, pgcSrc)
+ GCPtr pgcDst, pgcSrc;
+{
+ GC_FUNC_PROLOGUE (pgcDst);
+
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+
+ GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+miSpriteDestroyClip(pGC)
+ GCPtr pGC;
+{
+ GC_FUNC_PROLOGUE (pGC);
+
+ (* pGC->funcs->DestroyClip)(pGC);
+
+ GC_FUNC_EPILOGUE (pGC);
+}
+
+/*
+ * GC Op wrappers
+ */
+
+static void
+miSpriteFillSpans(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nInit; /* number of spans to fill */
+ DDXPointPtr pptInit; /* pointer to list of start points */
+ int *pwidthInit; /* pointer to list of n widths */
+ int fSorted;
+{
+ GC_SETUP(pDrawable, pGC);
+
+ if (GC_CHECK((WindowPtr) pDrawable))
+ {
+ register DDXPointPtr pts;
+ register int *widths;
+ register int nPts;
+
+ for (pts = pptInit, widths = pwidthInit, nPts = nInit;
+ nPts--;
+ pts++, widths++)
+ {
+ if (SPN_OVERLAP(&pScreenPriv->saved,pts->y,pts->x,*widths))
+ {
+ miSpriteRemoveCursor (pDrawable->pScreen);
+ break;
+ }
+ }
+ }
+
+ GC_OP_PROLOGUE (pGC);
+
+ (*pGC->ops->FillSpans) (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
+
+ GC_OP_EPILOGUE (pGC);
+}
+
+static void
+miSpriteSetSpans(pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ char *psrc;
+ register DDXPointPtr ppt;
+ int *pwidth;
+ int nspans;
+ int fSorted;
+{
+ GC_SETUP(pDrawable, pGC);
+
+ if (GC_CHECK((WindowPtr) pDrawable))
+ {
+ register DDXPointPtr pts;
+ register int *widths;
+ register int nPts;
+
+ for (pts = ppt, widths = pwidth, nPts = nspans;
+ nPts--;
+ pts++, widths++)
+ {
+ if (SPN_OVERLAP(&pScreenPriv->saved,pts->y,pts->x,*widths))
+ {
+ miSpriteRemoveCursor(pDrawable->pScreen);
+ break;
+ }
+ }
+ }
+
+ GC_OP_PROLOGUE (pGC);
+
+ (*pGC->ops->SetSpans) (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
+
+ GC_OP_EPILOGUE (pGC);
+}
+
+static void
+miSpritePutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int depth;
+ int x;
+ int y;
+ int w;
+ int h;
+ int format;
+ char *pBits;
+{
+ GC_SETUP(pDrawable, pGC);
+
+ if (GC_CHECK((WindowPtr) pDrawable))
+ {
+ if (ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y,
+ x,y,w,h))
+ {
+ miSpriteRemoveCursor (pDrawable->pScreen);
+ }
+ }
+
+ GC_OP_PROLOGUE (pGC);
+
+ (*pGC->ops->PutImage) (pDrawable, pGC, depth, x, y, w, h, leftPad, format, pBits);
+
+ GC_OP_EPILOGUE (pGC);
+}
+
+static RegionPtr
+miSpriteCopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty)
+ DrawablePtr pSrc;
+ DrawablePtr pDst;
+ GCPtr pGC;
+ int srcx;
+ int srcy;
+ int w;
+ int h;
+ int dstx;
+ int dsty;
+{
+ RegionPtr rgn;
+
+ GC_SETUP(pDst, pGC);
+
+ /* check destination/source overlap. */
+ if (GC_CHECK((WindowPtr) pDst) &&
+ (ORG_OVERLAP(&pScreenPriv->saved,pDst->x,pDst->y,dstx,dsty,w,h) ||
+ ((pDst == pSrc) &&
+ ORG_OVERLAP(&pScreenPriv->saved,pSrc->x,pSrc->y,srcx,srcy,w,h))))
+ {
+ miSpriteRemoveCursor (pDst->pScreen);
+ }
+
+ GC_OP_PROLOGUE (pGC);
+
+ rgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, srcx, srcy, w, h,
+ dstx, dsty);
+
+ GC_OP_EPILOGUE (pGC);
+
+ return rgn;
+}
+
+static RegionPtr
+miSpriteCopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, plane)
+ DrawablePtr pSrc;
+ DrawablePtr pDst;
+ register GCPtr pGC;
+ int srcx,
+ srcy;
+ int w,
+ h;
+ int dstx,
+ dsty;
+ unsigned long plane;
+{
+ RegionPtr rgn;
+
+ GC_SETUP(pDst, pGC);
+
+ /*
+ * check destination/source for overlap.
+ */
+ if (GC_CHECK((WindowPtr) pDst) &&
+ (ORG_OVERLAP(&pScreenPriv->saved,pDst->x,pDst->y,dstx,dsty,w,h) ||
+ ((pDst == pSrc) &&
+ ORG_OVERLAP(&pScreenPriv->saved,pSrc->x,pSrc->y,srcx,srcy,w,h))))
+ {
+ miSpriteRemoveCursor (pDst->pScreen);
+ }
+
+ GC_OP_PROLOGUE (pGC);
+
+ rgn = (*pGC->ops->CopyPlane) (pSrc, pDst, pGC, srcx, srcy, w, h,
+ dstx, dsty, plane);
+
+ GC_OP_EPILOGUE (pGC);
+
+ return rgn;
+}
+
+static void
+miSpritePolyPoint (pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt;
+ xPoint *pptInit;
+{
+ xPoint t;
+ int n;
+ BoxRec cursor;
+ register xPoint *pts;
+
+ GC_SETUP (pDrawable, pGC);
+
+ if (npt && GC_CHECK((WindowPtr) pDrawable))
+ {
+ cursor.x1 = pScreenPriv->saved.x1 - pDrawable->x;
+ cursor.y1 = pScreenPriv->saved.y1 - pDrawable->y;
+ cursor.x2 = pScreenPriv->saved.x2 - pDrawable->x;
+ cursor.y2 = pScreenPriv->saved.y2 - pDrawable->y;
+
+ if (mode == CoordModePrevious)
+ {
+ t.x = 0;
+ t.y = 0;
+ for (pts = pptInit, n = npt; n--; pts++)
+ {
+ t.x += pts->x;
+ t.y += pts->y;
+ if (cursor.x1 <= t.x && t.x <= cursor.x2 &&
+ cursor.y1 <= t.y && t.y <= cursor.y2)
+ {
+ miSpriteRemoveCursor (pDrawable->pScreen);
+ break;
+ }
+ }
+ }
+ else
+ {
+ for (pts = pptInit, n = npt; n--; pts++)
+ {
+ if (cursor.x1 <= pts->x && pts->x <= cursor.x2 &&
+ cursor.y1 <= pts->y && pts->y <= cursor.y2)
+ {
+ miSpriteRemoveCursor (pDrawable->pScreen);
+ break;
+ }
+ }
+ }
+ }
+
+ GC_OP_PROLOGUE (pGC);
+
+ (*pGC->ops->PolyPoint) (pDrawable, pGC, mode, npt, pptInit);
+
+ GC_OP_EPILOGUE (pGC);
+}
+
+static void
+miSpritePolylines (pDrawable, pGC, mode, npt, pptInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int mode;
+ int npt;
+ DDXPointPtr pptInit;
+{
+ BoxPtr cursor;
+ register DDXPointPtr pts;
+ int n;
+ int x, y, x1, y1, x2, y2;
+ int lw;
+ int extra;
+
+ GC_SETUP (pDrawable, pGC);
+
+ if (npt && GC_CHECK((WindowPtr) pDrawable))
+ {
+ cursor = &pScreenPriv->saved;
+ lw = pGC->lineWidth;
+ x = pptInit->x + pDrawable->x;
+ y = pptInit->y + pDrawable->y;
+
+ if (npt == 1)
+ {
+ extra = lw >> 1;
+ if (LINE_OVERLAP(cursor, x, y, x, y, extra))
+ miSpriteRemoveCursor (pDrawable->pScreen);
+ }
+ else
+ {
+ extra = lw >> 1;
+ /*
+ * mitered joins can project quite a way from
+ * the line end; the 11 degree miter limit limits
+ * this extension to 10.43 * lw / 2, rounded up
+ * and converted to int yields 6 * lw
+ */
+ if (pGC->joinStyle == JoinMiter)
+ extra = 6 * lw;
+ else if (pGC->capStyle == CapProjecting)
+ extra = lw;
+ for (pts = pptInit + 1, n = npt - 1; n--; pts++)
+ {
+ x1 = x;
+ y1 = y;
+ if (mode == CoordModeOrigin)
+ {
+ x2 = pDrawable->x + pts->x;
+ y2 = pDrawable->y + pts->y;
+ }
+ else
+ {
+ x2 = x + pts->x;
+ y2 = y + pts->y;
+ }
+ x = x2;
+ y = y2;
+ LINE_SORT(x1, y1, x2, y2);
+ if (LINE_OVERLAP(cursor, x1, y1, x2, y2, extra))
+ {
+ miSpriteRemoveCursor (pDrawable->pScreen);
+ break;
+ }
+ }
+ }
+ }
+ GC_OP_PROLOGUE (pGC);
+
+ (*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, pptInit);
+
+ GC_OP_EPILOGUE (pGC);
+}
+
+static void
+miSpritePolySegment(pDrawable, pGC, nseg, pSegs)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nseg;
+ xSegment *pSegs;
+{
+ int n;
+ register xSegment *segs;
+ BoxPtr cursor;
+ int x1, y1, x2, y2;
+ int extra;
+
+ GC_SETUP(pDrawable, pGC);
+
+ if (nseg && GC_CHECK((WindowPtr) pDrawable))
+ {
+ cursor = &pScreenPriv->saved;
+ extra = pGC->lineWidth >> 1;
+ if (pGC->capStyle == CapProjecting)
+ extra = pGC->lineWidth;
+ for (segs = pSegs, n = nseg; n--; segs++)
+ {
+ x1 = segs->x1 + pDrawable->x;
+ y1 = segs->y1 + pDrawable->y;
+ x2 = segs->x2 + pDrawable->x;
+ y2 = segs->y2 + pDrawable->y;
+ LINE_SORT(x1, y1, x2, y2);
+ if (LINE_OVERLAP(cursor, x1, y1, x2, y2, extra))
+ {
+ miSpriteRemoveCursor (pDrawable->pScreen);
+ break;
+ }
+ }
+ }
+
+ GC_OP_PROLOGUE (pGC);
+
+ (*pGC->ops->PolySegment) (pDrawable, pGC, nseg, pSegs);
+
+ GC_OP_EPILOGUE (pGC);
+}
+
+static void
+miSpritePolyRectangle(pDrawable, pGC, nrects, pRects)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nrects;
+ xRectangle *pRects;
+{
+ register xRectangle *rects;
+ BoxPtr cursor;
+ int lw;
+ int n;
+ int x1, y1, x2, y2;
+
+ GC_SETUP (pDrawable, pGC);
+
+ if (GC_CHECK((WindowPtr) pDrawable))
+ {
+ lw = pGC->lineWidth >> 1;
+ cursor = &pScreenPriv->saved;
+ for (rects = pRects, n = nrects; n--; rects++)
+ {
+ x1 = rects->x + pDrawable->x;
+ y1 = rects->y + pDrawable->y;
+ x2 = x1 + (int)rects->width;
+ y2 = y1 + (int)rects->height;
+ if (LINE_OVERLAP(cursor, x1, y1, x2, y1, lw) ||
+ LINE_OVERLAP(cursor, x2, y1, x2, y2, lw) ||
+ LINE_OVERLAP(cursor, x1, y2, x2, y2, lw) ||
+ LINE_OVERLAP(cursor, x1, y1, x1, y2, lw))
+ {
+ miSpriteRemoveCursor (pDrawable->pScreen);
+ break;
+ }
+ }
+ }
+
+ GC_OP_PROLOGUE (pGC);
+
+ (*pGC->ops->PolyRectangle) (pDrawable, pGC, nrects, pRects);
+
+ GC_OP_EPILOGUE (pGC);
+}
+
+static void
+miSpritePolyArc(pDrawable, pGC, narcs, parcs)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ BoxPtr cursor;
+ int lw;
+ int n;
+ register xArc *arcs;
+
+ GC_SETUP (pDrawable, pGC);
+
+ if (GC_CHECK((WindowPtr) pDrawable))
+ {
+ lw = pGC->lineWidth >> 1;
+ cursor = &pScreenPriv->saved;
+ for (arcs = parcs, n = narcs; n--; arcs++)
+ {
+ if (ORG_OVERLAP (cursor, pDrawable->x, pDrawable->y,
+ arcs->x - lw, arcs->y - lw,
+ (int) arcs->width + pGC->lineWidth,
+ (int) arcs->height + pGC->lineWidth))
+ {
+ miSpriteRemoveCursor (pDrawable->pScreen);
+ break;
+ }
+ }
+ }
+
+ GC_OP_PROLOGUE (pGC);
+
+ (*pGC->ops->PolyArc) (pDrawable, pGC, narcs, parcs);
+
+ GC_OP_EPILOGUE (pGC);
+}
+
+static void
+miSpriteFillPolygon(pDrawable, pGC, shape, mode, count, pPts)
+ register DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int shape, mode;
+ int count;
+ DDXPointPtr pPts;
+{
+ int x, y, minx, miny, maxx, maxy;
+ register DDXPointPtr pts;
+ int n;
+
+ GC_SETUP (pDrawable, pGC);
+
+ if (count && GC_CHECK((WindowPtr) pDrawable))
+ {
+ x = pDrawable->x;
+ y = pDrawable->y;
+ pts = pPts;
+ minx = maxx = pts->x;
+ miny = maxy = pts->y;
+ pts++;
+ n = count - 1;
+
+ if (mode == CoordModeOrigin)
+ {
+ for (; n--; pts++)
+ {
+ if (pts->x < minx)
+ minx = pts->x;
+ else if (pts->x > maxx)
+ maxx = pts->x;
+ if (pts->y < miny)
+ miny = pts->y;
+ else if (pts->y > maxy)
+ maxy = pts->y;
+ }
+ minx += x;
+ miny += y;
+ maxx += x;
+ maxy += y;
+ }
+ else
+ {
+ x += minx;
+ y += miny;
+ minx = maxx = x;
+ miny = maxy = y;
+ for (; n--; pts++)
+ {
+ x += pts->x;
+ y += pts->y;
+ if (x < minx)
+ minx = x;
+ else if (x > maxx)
+ maxx = x;
+ if (y < miny)
+ miny = y;
+ else if (y > maxy)
+ maxy = y;
+ }
+ }
+ if (BOX_OVERLAP(&pScreenPriv->saved,minx,miny,maxx,maxy))
+ miSpriteRemoveCursor (pDrawable->pScreen);
+ }
+
+ GC_OP_PROLOGUE (pGC);
+
+ (*pGC->ops->FillPolygon) (pDrawable, pGC, shape, mode, count, pPts);
+
+ GC_OP_EPILOGUE (pGC);
+}
+
+static void
+miSpritePolyFillRect(pDrawable, pGC, nrectFill, prectInit)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int nrectFill; /* number of rectangles to fill */
+ xRectangle *prectInit; /* Pointer to first rectangle to fill */
+{
+ GC_SETUP(pDrawable, pGC);
+
+ if (GC_CHECK((WindowPtr) pDrawable))
+ {
+ register int nRect;
+ register xRectangle *pRect;
+ register int xorg, yorg;
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+
+ for (nRect = nrectFill, pRect = prectInit; nRect--; pRect++) {
+ if (ORGRECT_OVERLAP(&pScreenPriv->saved,xorg,yorg,pRect)){
+ miSpriteRemoveCursor(pDrawable->pScreen);
+ break;
+ }
+ }
+ }
+
+ GC_OP_PROLOGUE (pGC);
+
+ (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrectFill, prectInit);
+
+ GC_OP_EPILOGUE (pGC);
+}
+
+static void
+miSpritePolyFillArc(pDrawable, pGC, narcs, parcs)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ GC_SETUP(pDrawable, pGC);
+
+ if (GC_CHECK((WindowPtr) pDrawable))
+ {
+ register int n;
+ BoxPtr cursor;
+ register xArc *arcs;
+
+ cursor = &pScreenPriv->saved;
+
+ for (arcs = parcs, n = narcs; n--; arcs++)
+ {
+ if (ORG_OVERLAP(cursor, pDrawable->x, pDrawable->y,
+ arcs->x, arcs->y,
+ (int) arcs->width, (int) arcs->height))
+ {
+ miSpriteRemoveCursor (pDrawable->pScreen);
+ break;
+ }
+ }
+ }
+
+ GC_OP_PROLOGUE (pGC);
+
+ (*pGC->ops->PolyFillArc) (pDrawable, pGC, narcs, parcs);
+
+ GC_OP_EPILOGUE (pGC);
+}
+
+/*
+ * general Poly/Image text function. Extract glyph information,
+ * compute bounding box and remove cursor if it is overlapped.
+ */
+
+static Bool
+miSpriteTextOverlap (pDraw, font, x, y, n, charinfo, imageblt, w, cursorBox)
+ DrawablePtr pDraw;
+ FontPtr font;
+ int x, y;
+ unsigned int n;
+ CharInfoPtr *charinfo;
+ Bool imageblt;
+ unsigned int w;
+ BoxPtr cursorBox;
+{
+ ExtentInfoRec extents;
+
+ x += pDraw->x;
+ y += pDraw->y;
+
+ if (FONTMINBOUNDS(font,characterWidth) >= 0)
+ {
+ /* compute an approximate (but covering) bounding box */
+ if (!imageblt || (charinfo[0]->metrics.leftSideBearing < 0))
+ extents.overallLeft = charinfo[0]->metrics.leftSideBearing;
+ else
+ extents.overallLeft = 0;
+ if (w)
+ extents.overallRight = w - charinfo[n-1]->metrics.characterWidth;
+ else
+ extents.overallRight = FONTMAXBOUNDS(font,characterWidth)
+ * (n - 1);
+ if (imageblt && (charinfo[n-1]->metrics.characterWidth >
+ charinfo[n-1]->metrics.rightSideBearing))
+ extents.overallRight += charinfo[n-1]->metrics.characterWidth;
+ else
+ extents.overallRight += charinfo[n-1]->metrics.rightSideBearing;
+ if (imageblt && FONTASCENT(font) > FONTMAXBOUNDS(font,ascent))
+ extents.overallAscent = FONTASCENT(font);
+ else
+ extents.overallAscent = FONTMAXBOUNDS(font, ascent);
+ if (imageblt && FONTDESCENT(font) > FONTMAXBOUNDS(font,descent))
+ extents.overallDescent = FONTDESCENT(font);
+ else
+ extents.overallDescent = FONTMAXBOUNDS(font,descent);
+ if (!BOX_OVERLAP(cursorBox,
+ x + extents.overallLeft,
+ y - extents.overallAscent,
+ x + extents.overallRight,
+ y + extents.overallDescent))
+ return FALSE;
+ else if (imageblt && w)
+ return TRUE;
+ /* if it does overlap, fall through and compute exactly, because
+ * taking down the cursor is expensive enough to make this worth it
+ */
+ }
+ QueryGlyphExtents(font, charinfo, n, &extents);
+ if (imageblt)
+ {
+ if (extents.overallWidth > extents.overallRight)
+ extents.overallRight = extents.overallWidth;
+ if (extents.overallWidth < extents.overallLeft)
+ extents.overallLeft = extents.overallWidth;
+ if (extents.overallLeft > 0)
+ extents.overallLeft = 0;
+ if (extents.fontAscent > extents.overallAscent)
+ extents.overallAscent = extents.fontAscent;
+ if (extents.fontDescent > extents.overallDescent)
+ extents.overallDescent = extents.fontDescent;
+ }
+ return (BOX_OVERLAP(cursorBox,
+ x + extents.overallLeft,
+ y - extents.overallAscent,
+ x + extents.overallRight,
+ y + extents.overallDescent));
+}
+
+/*
+ * values for textType:
+ */
+#define TT_POLY8 0
+#define TT_IMAGE8 1
+#define TT_POLY16 2
+#define TT_IMAGE16 3
+
+static int
+miSpriteText (pDraw, pGC, x, y, count, chars, fontEncoding, textType, cursorBox)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int x,
+ y;
+ unsigned long count;
+ char *chars;
+ FontEncoding fontEncoding;
+ Bool textType;
+ BoxPtr cursorBox;
+{
+ CharInfoPtr *charinfo;
+ register CharInfoPtr *info;
+ unsigned long i;
+ unsigned int n;
+ int w;
+ void (*drawFunc)();
+
+ Bool imageblt;
+
+ imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16);
+
+ charinfo = (CharInfoPtr *) ALLOCATE_LOCAL(count * sizeof(CharInfoPtr));
+ if (!charinfo)
+ return x;
+
+ GetGlyphs(pGC->font, count, (unsigned char *)chars,
+ fontEncoding, &i, charinfo);
+ n = (unsigned int)i;
+ w = 0;
+ if (!imageblt)
+ for (info = charinfo; i--; info++)
+ w += (*info)->metrics.characterWidth;
+
+ if (n != 0) {
+ if (miSpriteTextOverlap(pDraw, pGC->font, x, y, n, charinfo, imageblt, w, cursorBox))
+ miSpriteRemoveCursor(pDraw->pScreen);
+
+#ifdef AVOID_GLYPHBLT
+ /*
+ * On displays like Apollos, which do not optimize the GlyphBlt functions because they
+ * convert fonts to their internal form in RealizeFont and optimize text directly, we
+ * want to invoke the text functions here, not the GlyphBlt functions.
+ */
+ switch (textType)
+ {
+ case TT_POLY8:
+ drawFunc = (void (*)())pGC->ops->PolyText8;
+ break;
+ case TT_IMAGE8:
+ drawFunc = pGC->ops->ImageText8;
+ break;
+ case TT_POLY16:
+ drawFunc = (void (*)())pGC->ops->PolyText16;
+ break;
+ case TT_IMAGE16:
+ drawFunc = pGC->ops->ImageText16;
+ break;
+ }
+ (*drawFunc) (pDraw, pGC, x, y, (int) count, chars);
+#else /* don't AVOID_GLYPHBLT */
+ /*
+ * On the other hand, if the device does use GlyphBlt ultimately to do text, we
+ * don't want to slow it down by invoking the text functions and having them call
+ * GetGlyphs all over again, so we go directly to the GlyphBlt functions here.
+ */
+ drawFunc = imageblt ? pGC->ops->ImageGlyphBlt : pGC->ops->PolyGlyphBlt;
+ (*drawFunc) (pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));
+#endif /* AVOID_GLYPHBLT */
+ }
+ DEALLOCATE_LOCAL(charinfo);
+ return x + w;
+}
+
+static int
+miSpritePolyText8(pDrawable, pGC, x, y, count, chars)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *chars;
+{
+ int ret;
+
+ GC_SETUP (pDrawable, pGC);
+
+ GC_OP_PROLOGUE (pGC);
+
+ if (GC_CHECK((WindowPtr) pDrawable))
+ ret = miSpriteText (pDrawable, pGC, x, y, (unsigned long)count, chars,
+ Linear8Bit, TT_POLY8, &pScreenPriv->saved);
+ else
+ ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars);
+
+ GC_OP_EPILOGUE (pGC);
+ return ret;
+}
+
+static int
+miSpritePolyText16(pDrawable, pGC, x, y, count, chars)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ unsigned short *chars;
+{
+ int ret;
+
+ GC_SETUP(pDrawable, pGC);
+
+ GC_OP_PROLOGUE (pGC);
+
+ if (GC_CHECK((WindowPtr) pDrawable))
+ ret = miSpriteText (pDrawable, pGC, x, y, (unsigned long)count,
+ (char *)chars,
+ FONTLASTROW(pGC->font) == 0 ?
+ Linear16Bit : TwoD16Bit, TT_POLY16, &pScreenPriv->saved);
+ else
+ ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars);
+
+ GC_OP_EPILOGUE (pGC);
+ return ret;
+}
+
+static void
+miSpriteImageText8(pDrawable, pGC, x, y, count, chars)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ char *chars;
+{
+ GC_SETUP(pDrawable, pGC);
+
+ GC_OP_PROLOGUE (pGC);
+
+ if (GC_CHECK((WindowPtr) pDrawable))
+ (void) miSpriteText (pDrawable, pGC, x, y, (unsigned long)count,
+ chars, Linear8Bit, TT_IMAGE8, &pScreenPriv->saved);
+ else
+ (*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars);
+
+ GC_OP_EPILOGUE (pGC);
+}
+
+static void
+miSpriteImageText16(pDrawable, pGC, x, y, count, chars)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ int count;
+ unsigned short *chars;
+{
+ GC_SETUP(pDrawable, pGC);
+
+ GC_OP_PROLOGUE (pGC);
+
+ if (GC_CHECK((WindowPtr) pDrawable))
+ (void) miSpriteText (pDrawable, pGC, x, y, (unsigned long)count,
+ (char *)chars,
+ FONTLASTROW(pGC->font) == 0 ?
+ Linear16Bit : TwoD16Bit, TT_IMAGE16, &pScreenPriv->saved);
+ else
+ (*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars);
+
+ GC_OP_EPILOGUE (pGC);
+}
+
+static void
+miSpriteImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ pointer pglyphBase; /* start of array of glyphs */
+{
+ GC_SETUP(pDrawable, pGC);
+
+ GC_OP_PROLOGUE (pGC);
+
+ if (GC_CHECK((WindowPtr) pDrawable) &&
+ miSpriteTextOverlap (pDrawable, pGC->font, x, y, nglyph, ppci, TRUE, 0, &pScreenPriv->saved))
+ {
+ miSpriteRemoveCursor(pDrawable->pScreen);
+ }
+ (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+
+ GC_OP_EPILOGUE (pGC);
+}
+
+static void
+miSpritePolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ int x, y;
+ unsigned int nglyph;
+ CharInfoPtr *ppci; /* array of character info */
+ pointer pglyphBase; /* start of array of glyphs */
+{
+ GC_SETUP (pDrawable, pGC);
+
+ GC_OP_PROLOGUE (pGC);
+
+ if (GC_CHECK((WindowPtr) pDrawable) &&
+ miSpriteTextOverlap (pDrawable, pGC->font, x, y, nglyph, ppci, FALSE, 0, &pScreenPriv->saved))
+ {
+ miSpriteRemoveCursor(pDrawable->pScreen);
+ }
+ (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+
+ GC_OP_EPILOGUE (pGC);
+}
+
+static void
+miSpritePushPixels(pGC, pBitMap, pDrawable, w, h, x, y)
+ GCPtr pGC;
+ PixmapPtr pBitMap;
+ DrawablePtr pDrawable;
+ int w, h, x, y;
+{
+ GC_SETUP(pDrawable, pGC);
+
+ if (GC_CHECK((WindowPtr) pDrawable) &&
+ ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y,x,y,w,h))
+ {
+ miSpriteRemoveCursor (pDrawable->pScreen);
+ }
+
+ GC_OP_PROLOGUE (pGC);
+
+ (*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y);
+
+ GC_OP_EPILOGUE (pGC);
+}
+
+#ifdef NEED_LINEHELPER
+/*
+ * I don't expect this routine will ever be called, as the GC
+ * will have been unwrapped for the line drawing
+ */
+
+static void
+miSpriteLineHelper()
+{
+ FatalError("miSpriteLineHelper called\n");
+}
+#endif
+
+/*
+ * miPointer interface routines
+ */
+
+#define SPRITE_PAD 8
+
+static Bool
+miSpriteRealizeCursor (pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ miSpriteScreenPtr pScreenPriv;
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ if (pCursor == pScreenPriv->pCursor)
+ pScreenPriv->checkPixels = TRUE;
+ return (*pScreenPriv->funcs->RealizeCursor) (pScreen, pCursor);
+}
+
+static Bool
+miSpriteUnrealizeCursor (pScreen, pCursor)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ miSpriteScreenPtr pScreenPriv;
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ return (*pScreenPriv->funcs->UnrealizeCursor) (pScreen, pCursor);
+}
+
+static void
+miSpriteSetCursor (pScreen, pCursor, x, y)
+ ScreenPtr pScreen;
+ CursorPtr pCursor;
+{
+ miSpriteScreenPtr pScreenPriv;
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ pScreenPriv->shouldBeUp = TRUE;
+ if (pScreenPriv->x == x &&
+ pScreenPriv->y == y &&
+ pScreenPriv->pCursor == pCursor &&
+ !pScreenPriv->checkPixels)
+ {
+ return;
+ }
+ if (!pCursor)
+ {
+ pScreenPriv->shouldBeUp = FALSE;
+ if (pScreenPriv->isUp)
+ miSpriteRemoveCursor (pScreen);
+ pScreenPriv->pCursor = 0;
+ return;
+ }
+ pScreenPriv->x = x;
+ pScreenPriv->y = y;
+ pScreenPriv->pCacheWin = NullWindow;
+ if (pScreenPriv->checkPixels || pScreenPriv->pCursor != pCursor)
+ {
+ pScreenPriv->pCursor = pCursor;
+ miSpriteFindColors (pScreen);
+ }
+ if (pScreenPriv->isUp) {
+ int sx, sy;
+ /*
+ * check to see if the old saved region
+ * encloses the new sprite, in which case we use
+ * the flicker-free MoveCursor primitive.
+ */
+ sx = pScreenPriv->x - (int)pCursor->bits->xhot;
+ sy = pScreenPriv->y - (int)pCursor->bits->yhot;
+ if (sx + (int) pCursor->bits->width >= pScreenPriv->saved.x1 &&
+ sx < pScreenPriv->saved.x2 &&
+ sy + (int) pCursor->bits->height >= pScreenPriv->saved.y1 &&
+ sy < pScreenPriv->saved.y2 &&
+ (int) pCursor->bits->width + (2 * SPRITE_PAD) ==
+ pScreenPriv->saved.x2 - pScreenPriv->saved.x1 &&
+ (int) pCursor->bits->height + (2 * SPRITE_PAD) ==
+ pScreenPriv->saved.y2 - pScreenPriv->saved.y1
+ )
+ {
+ pScreenPriv->isUp = FALSE;
+ if (!(sx >= pScreenPriv->saved.x1 &&
+ sx + (int)pCursor->bits->width < pScreenPriv->saved.x2 &&
+ sy >= pScreenPriv->saved.y1 &&
+ sy + (int)pCursor->bits->height < pScreenPriv->saved.y2))
+ {
+ int oldx1, oldy1, dx, dy;
+
+ oldx1 = pScreenPriv->saved.x1;
+ oldy1 = pScreenPriv->saved.y1;
+ dx = oldx1 - (sx - SPRITE_PAD);
+ dy = oldy1 - (sy - SPRITE_PAD);
+ pScreenPriv->saved.x1 -= dx;
+ pScreenPriv->saved.y1 -= dy;
+ pScreenPriv->saved.x2 -= dx;
+ pScreenPriv->saved.y2 -= dy;
+ (void) (*pScreenPriv->funcs->ChangeSave) (pScreen,
+ pScreenPriv->saved.x1,
+ pScreenPriv->saved.y1,
+ pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
+ pScreenPriv->saved.y2 - pScreenPriv->saved.y1,
+ dx, dy);
+ }
+ (void) (*pScreenPriv->funcs->MoveCursor) (pScreen, pCursor,
+ pScreenPriv->saved.x1,
+ pScreenPriv->saved.y1,
+ pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
+ pScreenPriv->saved.y2 - pScreenPriv->saved.y1,
+ sx - pScreenPriv->saved.x1,
+ sy - pScreenPriv->saved.y1,
+ pScreenPriv->colors[SOURCE_COLOR].pixel,
+ pScreenPriv->colors[MASK_COLOR].pixel);
+ pScreenPriv->isUp = TRUE;
+ }
+ else
+ {
+ miSpriteRemoveCursor (pScreen);
+ }
+ }
+ if (!pScreenPriv->isUp && pScreenPriv->pCursor)
+ miSpriteRestoreCursor (pScreen);
+}
+
+static void
+miSpriteMoveCursor (pScreen, x, y)
+ ScreenPtr pScreen;
+ int x, y;
+{
+ miSpriteScreenPtr pScreenPriv;
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ miSpriteSetCursor (pScreen, pScreenPriv->pCursor, x, y);
+}
+
+/*
+ * undraw/draw cursor
+ */
+
+static void
+miSpriteRemoveCursor (pScreen)
+ ScreenPtr pScreen;
+{
+ miSpriteScreenPtr pScreenPriv;
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ pScreenPriv->isUp = FALSE;
+ pScreenPriv->pCacheWin = NullWindow;
+ if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pScreen,
+ pScreenPriv->saved.x1,
+ pScreenPriv->saved.y1,
+ pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
+ pScreenPriv->saved.y2 - pScreenPriv->saved.y1))
+ {
+ pScreenPriv->isUp = TRUE;
+ }
+}
+
+/*
+ * Called from the block handler, restores the cursor
+ * before waiting for something to do.
+ */
+
+static void
+miSpriteRestoreCursor (pScreen)
+ ScreenPtr pScreen;
+{
+ miSpriteScreenPtr pScreenPriv;
+ int x, y;
+ CursorPtr pCursor;
+
+ miSpriteComputeSaved (pScreen);
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ pCursor = pScreenPriv->pCursor;
+ x = pScreenPriv->x - (int)pCursor->bits->xhot;
+ y = pScreenPriv->y - (int)pCursor->bits->yhot;
+ if ((*pScreenPriv->funcs->SaveUnderCursor) (pScreen,
+ pScreenPriv->saved.x1,
+ pScreenPriv->saved.y1,
+ pScreenPriv->saved.x2 - pScreenPriv->saved.x1,
+ pScreenPriv->saved.y2 - pScreenPriv->saved.y1))
+ {
+ if (pScreenPriv->checkPixels)
+ miSpriteFindColors (pScreen);
+ if ((*pScreenPriv->funcs->PutUpCursor) (pScreen, pCursor, x, y,
+ pScreenPriv->colors[SOURCE_COLOR].pixel,
+ pScreenPriv->colors[MASK_COLOR].pixel))
+ pScreenPriv->isUp = TRUE;
+ }
+}
+
+/*
+ * compute the desired area of the screen to save
+ */
+
+static void
+miSpriteComputeSaved (pScreen)
+ ScreenPtr pScreen;
+{
+ miSpriteScreenPtr pScreenPriv;
+ int x, y, w, h;
+ int wpad, hpad;
+ CursorPtr pCursor;
+
+ pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
+ pCursor = pScreenPriv->pCursor;
+ x = pScreenPriv->x - (int)pCursor->bits->xhot;
+ y = pScreenPriv->y - (int)pCursor->bits->yhot;
+ w = pCursor->bits->width;
+ h = pCursor->bits->height;
+ wpad = SPRITE_PAD;
+ hpad = SPRITE_PAD;
+ pScreenPriv->saved.x1 = x - wpad;
+ pScreenPriv->saved.y1 = y - hpad;
+ pScreenPriv->saved.x2 = pScreenPriv->saved.x1 + w + wpad * 2;
+ pScreenPriv->saved.y2 = pScreenPriv->saved.y1 + h + hpad * 2;
+}
diff --git a/xc/programs/Xserver/mi/misprite.h b/xc/programs/Xserver/mi/misprite.h
new file mode 100644
index 000000000..8c9564651
--- /dev/null
+++ b/xc/programs/Xserver/mi/misprite.h
@@ -0,0 +1,107 @@
+/*
+ * misprite.h
+ *
+ * software-sprite/sprite drawing interface spec
+ *
+ * mi versions of these routines exist.
+ */
+
+/* $TOG: misprite.h /main/8 1998/02/09 14:49:03 kaleb $ */
+
+/*
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+*/
+
+typedef struct {
+ Bool (*RealizeCursor)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/
+#endif
+);
+ Bool (*UnrealizeCursor)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/
+#endif
+);
+ Bool (*PutUpCursor)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/,
+ int /*x*/,
+ int /*y*/,
+ unsigned long /*source*/,
+ unsigned long /*mask*/
+#endif
+);
+ Bool (*SaveUnderCursor)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/
+#endif
+);
+ Bool (*RestoreUnderCursor)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/
+#endif
+);
+ Bool (*MoveCursor)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ CursorPtr /*pCursor*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ int /*dx*/,
+ int /*dy*/,
+ unsigned long /*source*/,
+ unsigned long /*mask*/
+#endif
+);
+ Bool (*ChangeSave)(
+#if NeedNestedPrototypes
+ ScreenPtr /*pScreen*/,
+ int /*x*/,
+ int /*y*/,
+ int /*w*/,
+ int /*h*/,
+ int /*dx*/,
+ int /*dy*/
+#endif
+);
+
+} miSpriteCursorFuncRec, *miSpriteCursorFuncPtr;
+
+extern Bool miSpriteInitialize(
+#if NeedFunctionPrototypes
+ ScreenPtr /*pScreen*/,
+ miSpriteCursorFuncPtr /*cursorFuncs*/,
+ miPointerScreenFuncPtr /*screenFuncs*/
+#endif
+);
diff --git a/xc/programs/Xserver/mi/mispritest.h b/xc/programs/Xserver/mi/mispritest.h
new file mode 100644
index 000000000..b77c357cf
--- /dev/null
+++ b/xc/programs/Xserver/mi/mispritest.h
@@ -0,0 +1,106 @@
+/*
+ * mispritest.h
+ *
+ * mi sprite structures
+ */
+
+/* $TOG: mispritest.h /main/17 1998/02/09 14:48:52 kaleb $ */
+
+/*
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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 "misprite.h"
+
+/*
+ * per screen information
+ */
+
+typedef struct {
+ CloseScreenProcPtr CloseScreen;
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ SourceValidateProcPtr SourceValidate;
+ CreateGCProcPtr CreateGC;
+ ScreenBlockHandlerProcPtr BlockHandler;
+ InstallColormapProcPtr InstallColormap;
+ StoreColorsProcPtr StoreColors;
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ CopyWindowProcPtr CopyWindow;
+ ClearToBackgroundProcPtr ClearToBackground;
+ SaveDoomedAreasProcPtr SaveDoomedAreas;
+ RestoreAreasProcPtr RestoreAreas;
+
+ CursorPtr pCursor;
+ int x;
+ int y;
+ BoxRec saved;
+ Bool isUp;
+ Bool shouldBeUp;
+ WindowPtr pCacheWin;
+ Bool isInCacheWin;
+ Bool checkPixels;
+ xColorItem colors[2];
+ ColormapPtr pInstalledMap;
+ ColormapPtr pColormap;
+ VisualPtr pVisual;
+ miSpriteCursorFuncPtr funcs;
+} miSpriteScreenRec, *miSpriteScreenPtr;
+
+#define SOURCE_COLOR 0
+#define MASK_COLOR 1
+
+typedef struct {
+ GCFuncs *wrapFuncs;
+ GCOps *wrapOps;
+} miSpriteGCRec, *miSpriteGCPtr;
+
+/*
+ * Overlap BoxPtr and Box elements
+ */
+#define BOX_OVERLAP(pCbox,X1,Y1,X2,Y2) \
+ (((pCbox)->x1 <= (X2)) && ((X1) <= (pCbox)->x2) && \
+ ((pCbox)->y1 <= (Y2)) && ((Y1) <= (pCbox)->y2))
+
+/*
+ * Overlap BoxPtr, origins, and rectangle
+ */
+#define ORG_OVERLAP(pCbox,xorg,yorg,x,y,w,h) \
+ BOX_OVERLAP((pCbox),(x)+(xorg),(y)+(yorg),(x)+(xorg)+(w),(y)+(yorg)+(h))
+
+/*
+ * Overlap BoxPtr, origins and RectPtr
+ */
+#define ORGRECT_OVERLAP(pCbox,xorg,yorg,pRect) \
+ ORG_OVERLAP((pCbox),(xorg),(yorg),(pRect)->x,(pRect)->y, \
+ (int)((pRect)->width), (int)((pRect)->height))
+/*
+ * Overlap BoxPtr and horizontal span
+ */
+#define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y))
+
+#define LINE_SORT(x1,y1,x2,y2) \
+{ int _t; \
+ if (x1 > x2) { _t = x1; x1 = x2; x2 = _t; } \
+ if (y1 > y2) { _t = y1; y1 = y2; y2 = _t; } }
+
+#define LINE_OVERLAP(pCbox,x1,y1,x2,y2,lw2) \
+ BOX_OVERLAP((pCbox), (x1)-(lw2), (y1)-(lw2), (x2)+(lw2), (y2)+(lw2))
diff --git a/xc/programs/Xserver/mi/mistruct.h b/xc/programs/Xserver/mi/mistruct.h
new file mode 100644
index 000000000..b29ac58cf
--- /dev/null
+++ b/xc/programs/Xserver/mi/mistruct.h
@@ -0,0 +1,59 @@
+/* $TOG: mistruct.h /main/4 1998/02/09 14:49:07 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+#ifndef MISTRUCT_H
+#define MISTRUCT_H
+
+#include "mi.h"
+#include "miscstruct.h"
+
+/* information about dashes */
+typedef struct _miDash {
+ DDXPointRec pt;
+ int e1, e2; /* keep these, so we don't have to do it again */
+ int e; /* bresenham error term for this point on line */
+ int which;
+ int newLine;/* 0 if part of same original line as previous dash */
+ } miDashRec;
+
+#endif /* MISTRUCT_H */
diff --git a/xc/programs/Xserver/mi/mivalidate.h b/xc/programs/Xserver/mi/mivalidate.h
new file mode 100644
index 000000000..33acb5ec7
--- /dev/null
+++ b/xc/programs/Xserver/mi/mivalidate.h
@@ -0,0 +1,47 @@
+/* $TOG: mivalidate.h /main/4 1998/02/09 14:49:11 kaleb $ */
+/*
+
+Copyright 1993, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+
+
+#ifndef MIVALIDATE_H
+#define MIVALIDATE_H
+
+#include "miscstruct.h"
+#include "regionstr.h"
+
+typedef union _Validate {
+ struct BeforeValidate {
+ DDXPointRec oldAbsCorner; /* old window position */
+ RegionPtr borderVisible; /* visible region of border, */
+ /* non-null when size changes */
+ Bool resized; /* unclipped winSize has changed - */
+ /* don't call SaveDoomedAreas */
+ } before;
+ struct AfterValidate {
+ RegionRec exposed; /* exposed regions, absolute pos */
+ RegionRec borderExposed;
+ } after;
+} ValidateRec;
+
+#endif /* MIVALIDATE_H */
diff --git a/xc/programs/Xserver/mi/mivaltree.c b/xc/programs/Xserver/mi/mivaltree.c
new file mode 100644
index 000000000..9a5e458e2
--- /dev/null
+++ b/xc/programs/Xserver/mi/mivaltree.c
@@ -0,0 +1,1286 @@
+/* $TOG: mivaltree.c /main/52 1998/02/09 14:49:15 kaleb $ */
+/*
+ * mivaltree.c --
+ * Functions for recalculating window clip lists. Main function
+ * is miValidateTree.
+ *
+
+Copyright 1987, 1988, 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ *
+ * Copyright 1987, 1988, 1989 by
+ * Digital Equipment Corporation, Maynard, Massachusetts,
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Digital not be
+ * used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ *
+ * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ ******************************************************************/
+
+/* The panoramix components contained the following notice */
+/****************************************************************
+* *
+* Copyright (c) Digital Equipment Corporation, 1991, 1997 *
+* *
+* All Rights Reserved. Unpublished rights reserved under *
+* the copyright laws of the United States. *
+* *
+* The software contained on this media is proprietary to *
+* and embodies the confidential technology of Digital *
+* Equipment Corporation. Possession, use, duplication or *
+* dissemination of the software and media is authorized only *
+* pursuant to a valid written license from Digital Equipment *
+* Corporation. *
+* *
+* RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure *
+* by the U.S. Government is subject to restrictions as set *
+* forth in Subparagraph (c)(1)(ii) of DFARS 252.227-7013, *
+* or in FAR 52.227-19, as applicable. *
+* *
+*****************************************************************/
+
+/* $XFree86: xc/programs/Xserver/mi/mivaltree.c,v 1.4 1999/04/11 13:11:20 dawes Exp $ */
+
+ /*
+ * Aug '86: Susan Angebranndt -- original code
+ * July '87: Adam de Boor -- substantially modified and commented
+ * Summer '89: Joel McCormack -- so fast you wouldn't believe it possible.
+ * In particular, much improved code for window mapping and
+ * circulating.
+ * Bob Scheifler -- avoid miComputeClips for unmapped windows,
+ * valdata changes
+ */
+#include "X.h"
+#include "scrnintstr.h"
+#include "validate.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "regionstr.h"
+#include "mivalidate.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+#include "globals.h"
+
+#ifdef SHAPE
+/*
+ * Compute the visibility of a shaped window
+ */
+int
+miShapedWindowIn (pScreen, universe, bounding, rect, x, y)
+ ScreenPtr pScreen;
+ RegionPtr universe, bounding;
+ BoxPtr rect;
+ register int x, y;
+{
+ BoxRec box;
+ register BoxPtr boundBox;
+ int nbox;
+ Bool someIn, someOut;
+ register int t, x1, y1, x2, y2;
+
+ nbox = REGION_NUM_RECTS (bounding);
+ boundBox = REGION_RECTS (bounding);
+ someIn = someOut = FALSE;
+ x1 = rect->x1;
+ y1 = rect->y1;
+ x2 = rect->x2;
+ y2 = rect->y2;
+ while (nbox--)
+ {
+ if ((t = boundBox->x1 + x) < x1)
+ t = x1;
+ box.x1 = t;
+ if ((t = boundBox->y1 + y) < y1)
+ t = y1;
+ box.y1 = t;
+ if ((t = boundBox->x2 + x) > x2)
+ t = x2;
+ box.x2 = t;
+ if ((t = boundBox->y2 + y) > y2)
+ t = y2;
+ box.y2 = t;
+ if (box.x1 > box.x2)
+ box.x2 = box.x1;
+ if (box.y1 > box.y2)
+ box.y2 = box.y1;
+ switch (RECT_IN_REGION(pScreen, universe, &box))
+ {
+ case rgnIN:
+ if (someOut)
+ return rgnPART;
+ someIn = TRUE;
+ break;
+ case rgnOUT:
+ if (someIn)
+ return rgnPART;
+ someOut = TRUE;
+ break;
+ default:
+ return rgnPART;
+ }
+ boundBox++;
+ }
+ if (someIn)
+ return rgnIN;
+ return rgnOUT;
+}
+#endif
+
+#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
+ HasBorder(w) && \
+ (w)->backgroundState == ParentRelative)
+
+
+/*
+ *-----------------------------------------------------------------------
+ * miComputeClips --
+ * Recompute the clipList, borderClip, exposed and borderExposed
+ * regions for pParent and its children. Only viewable windows are
+ * taken into account.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * clipList, borderClip, exposed and borderExposed are altered.
+ * A VisibilityNotify event may be generated on the parent window.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miComputeClips (pParent, pScreen, universe, kind, exposed)
+ register WindowPtr pParent;
+ register ScreenPtr pScreen;
+ register RegionPtr universe;
+ VTKind kind;
+ RegionPtr exposed; /* for intermediate calculations */
+{
+ int dx,
+ dy;
+ RegionRec childUniverse;
+ register WindowPtr pChild;
+ int oldVis, newVis;
+ BoxRec borderSize;
+ RegionRec childUnion;
+ Bool overlap;
+ RegionPtr borderVisible;
+ Bool resized;
+ /*
+ * Figure out the new visibility of this window.
+ * The extent of the universe should be the same as the extent of
+ * the borderSize region. If the window is unobscured, this rectangle
+ * will be completely inside the universe (the universe will cover it
+ * completely). If the window is completely obscured, none of the
+ * universe will cover the rectangle.
+ */
+ borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
+ borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
+ dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent);
+ if (dx > 32767)
+ dx = 32767;
+ borderSize.x2 = dx;
+ dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent);
+ if (dy > 32767)
+ dy = 32767;
+ borderSize.y2 = dy;
+
+ oldVis = pParent->visibility;
+ switch (RECT_IN_REGION( pScreen, universe, &borderSize))
+ {
+ case rgnIN:
+ newVis = VisibilityUnobscured;
+ break;
+ case rgnPART:
+ newVis = VisibilityPartiallyObscured;
+#ifdef SHAPE
+ {
+ RegionPtr pBounding;
+
+ if ((pBounding = wBoundingShape (pParent)))
+ {
+ switch (miShapedWindowIn (pScreen, universe, pBounding,
+ &borderSize,
+ pParent->drawable.x,
+ pParent->drawable.y))
+ {
+ case rgnIN:
+ newVis = VisibilityUnobscured;
+ break;
+ case rgnOUT:
+ newVis = VisibilityFullyObscured;
+ break;
+ }
+ }
+ }
+#endif
+ break;
+ default:
+ newVis = VisibilityFullyObscured;
+ break;
+ }
+ pParent->visibility = newVis;
+ if (oldVis != newVis &&
+ ((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
+ SendVisibilityNotify(pParent);
+
+ dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
+ dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
+
+ /*
+ * avoid computations when dealing with simple operations
+ */
+
+ switch (kind) {
+ case VTMap:
+ case VTStack:
+ case VTUnmap:
+ break;
+ case VTMove:
+ if ((oldVis == newVis) &&
+ ((oldVis == VisibilityFullyObscured) ||
+ (oldVis == VisibilityUnobscured)))
+ {
+ pChild = pParent;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ if (pChild->visibility != VisibilityFullyObscured)
+ {
+ REGION_TRANSLATE( pScreen, &pChild->borderClip,
+ dx, dy);
+ REGION_TRANSLATE( pScreen, &pChild->clipList,
+ dx, dy);
+ pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ if (pScreen->ClipNotify)
+ (* pScreen->ClipNotify) (pChild, dx, dy);
+
+ }
+ if (pChild->valdata)
+ {
+ REGION_INIT(pScreen,
+ &pChild->valdata->after.borderExposed,
+ NullBox, 0);
+ if (HasParentRelativeBorder(pChild))
+ {
+ REGION_SUBTRACT(pScreen,
+ &pChild->valdata->after.borderExposed,
+ &pChild->borderClip,
+ &pChild->winSize);
+ }
+ REGION_INIT( pScreen, &pChild->valdata->after.exposed,
+ NullBox, 0);
+ }
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pParent))
+ pChild = pChild->parent;
+ if (pChild == pParent)
+ break;
+ pChild = pChild->nextSib;
+ }
+ return;
+ }
+ /* fall through */
+ default:
+ /*
+ * To calculate exposures correctly, we have to translate the old
+ * borderClip and clipList regions to the window's new location so there
+ * is a correspondence between pieces of the new and old clipping regions.
+ */
+ if (dx || dy)
+ {
+ /*
+ * We translate the old clipList because that will be exposed or copied
+ * if gravity is right.
+ */
+ REGION_TRANSLATE( pScreen, &pParent->borderClip, dx, dy);
+ REGION_TRANSLATE( pScreen, &pParent->clipList, dx, dy);
+ }
+ break;
+ }
+
+ borderVisible = pParent->valdata->before.borderVisible;
+ resized = pParent->valdata->before.resized;
+ REGION_INIT( pScreen, &pParent->valdata->after.borderExposed, NullBox, 0);
+ REGION_INIT( pScreen, &pParent->valdata->after.exposed, NullBox, 0);
+
+ /*
+ * Since the borderClip must not be clipped by the children, we do
+ * the border exposure first...
+ *
+ * 'universe' is the window's borderClip. To figure the exposures, remove
+ * the area that used to be exposed from the new.
+ * This leaves a region of pieces that weren't exposed before.
+ */
+
+ if (HasBorder (pParent))
+ {
+ if (borderVisible)
+ {
+ /*
+ * when the border changes shape, the old visible portions
+ * of the border will be saved by DIX in borderVisible --
+ * use that region and destroy it
+ */
+ REGION_SUBTRACT( pScreen, exposed, universe, borderVisible);
+ REGION_DESTROY( pScreen, borderVisible);
+ }
+ else
+ {
+ REGION_SUBTRACT( pScreen, exposed, universe, &pParent->borderClip);
+ }
+ if (HasParentRelativeBorder(pParent) && (dx || dy))
+ REGION_SUBTRACT( pScreen, &pParent->valdata->after.borderExposed,
+ universe,
+ &pParent->winSize);
+ else
+ REGION_SUBTRACT( pScreen, &pParent->valdata->after.borderExposed,
+ exposed, &pParent->winSize);
+
+ REGION_COPY( pScreen, &pParent->borderClip, universe);
+
+ /*
+ * To get the right clipList for the parent, and to make doubly sure
+ * that no child overlaps the parent's border, we remove the parent's
+ * border from the universe before proceeding.
+ */
+
+ REGION_INTERSECT( pScreen, universe, universe, &pParent->winSize);
+ }
+ else
+ REGION_COPY( pScreen, &pParent->borderClip, universe);
+
+ if ((pChild = pParent->firstChild) && pParent->mapped)
+ {
+ REGION_INIT(pScreen, &childUniverse, NullBox, 0);
+ REGION_INIT(pScreen, &childUnion, NullBox, 0);
+ if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
+ ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
+ (pChild->drawable.x < pParent->lastChild->drawable.x)))
+ {
+ for (; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->viewable)
+ REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
+ }
+ }
+ else
+ {
+ for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib)
+ {
+ if (pChild->viewable)
+ REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
+ }
+ }
+ REGION_VALIDATE( pScreen, &childUnion, &overlap);
+
+ for (pChild = pParent->firstChild;
+ pChild;
+ pChild = pChild->nextSib)
+ {
+ if (pChild->viewable) {
+ /*
+ * If the child is viewable, we want to remove its extents
+ * from the current universe, but we only re-clip it if
+ * it's been marked.
+ */
+ if (pChild->valdata) {
+ /*
+ * Figure out the new universe from the child's
+ * perspective and recurse.
+ */
+ REGION_INTERSECT( pScreen, &childUniverse,
+ universe,
+ &pChild->borderSize);
+ miComputeClips (pChild, pScreen, &childUniverse, kind,
+ exposed);
+ }
+ /*
+ * Once the child has been processed, we remove its extents
+ * from the current universe, thus denying its space to any
+ * other sibling.
+ */
+ if (overlap)
+ REGION_SUBTRACT( pScreen, universe, universe,
+ &pChild->borderSize);
+ }
+ }
+ if (!overlap)
+ REGION_SUBTRACT( pScreen, universe, universe, &childUnion);
+ REGION_UNINIT( pScreen, &childUnion);
+ REGION_UNINIT( pScreen, &childUniverse);
+ } /* if any children */
+
+ /*
+ * 'universe' now contains the new clipList for the parent window.
+ *
+ * To figure the exposure of the window we subtract the old clip from the
+ * new, just as for the border.
+ */
+
+ if (oldVis == VisibilityFullyObscured ||
+ oldVis == VisibilityNotViewable)
+ {
+ REGION_COPY( pScreen, &pParent->valdata->after.exposed, universe);
+ }
+ else if (newVis != VisibilityFullyObscured &&
+ newVis != VisibilityNotViewable)
+ {
+ REGION_SUBTRACT( pScreen, &pParent->valdata->after.exposed,
+ universe, &pParent->clipList);
+ }
+
+ /*
+ * One last thing: backing storage. We have to try to save what parts of
+ * the window are about to be obscured. We can just subtract the universe
+ * from the old clipList and get the areas that were in the old but aren't
+ * in the new and, hence, are about to be obscured.
+ */
+ if (pParent->backStorage && !resized)
+ {
+ REGION_SUBTRACT( pScreen, exposed, &pParent->clipList, universe);
+ (* pScreen->SaveDoomedAreas)(pParent, exposed, dx, dy);
+ }
+
+ /* HACK ALERT - copying contents of regions, instead of regions */
+ {
+ RegionRec tmp;
+
+ tmp = pParent->clipList;
+ pParent->clipList = *universe;
+ *universe = tmp;
+ }
+
+#ifdef NOTDEF
+ REGION_COPY( pScreen, &pParent->clipList, universe);
+#endif
+
+ pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ if (pScreen->ClipNotify)
+ (* pScreen->ClipNotify) (pParent, dx, dy);
+}
+
+#ifdef PANORAMIX
+static void
+PanoramiXComputeClips (pParent, pScreen, universe, panoramiXuniverse, kind, exposed)
+ register WindowPtr pParent;
+ register ScreenPtr pScreen;
+ register RegionPtr universe;
+ register RegionPtr panoramiXuniverse;
+ VTKind kind;
+ RegionPtr exposed; /* for intermediate calculations */
+{
+ int dx,
+ dy;
+ RegionRec childUniverse;
+ register WindowPtr pChild;
+ int oldVis, newVis, PanoramiXoldVis, PanoramiXnewVis;
+ BoxRec borderSize;
+ RegionRec childUnion;
+ Bool overlap;
+ RegionPtr borderVisible;
+ Bool resized;
+ RegionRec PanoramiXchildUniverse;
+ int j;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ RegionRec PanoramiXborderSize;
+
+ /*
+ * Figure out the new visibility of this window.
+ * The extent of the universe should be the same as the extent of
+ * the borderSize region. If the window is unobscured, this rectangle
+ * will be completely inside the universe (the universe will cover it
+ * completely). If the window is completely obscured, none of the
+ * universe will cover the rectangle.
+ */
+ borderSize.x1 = pParent->drawable.x - wBorderWidth(pParent);
+ borderSize.y1 = pParent->drawable.y - wBorderWidth(pParent);
+ dx = (int) pParent->drawable.x + (int) pParent->drawable.width + wBorderWidth(pParent);
+ if (dx > 32767)
+ dx = 32767;
+ borderSize.x2 = dx;
+ dy = (int) pParent->drawable.y + (int) pParent->drawable.height + wBorderWidth(pParent);
+ if (dy > 32767)
+ dy = 32767;
+ borderSize.y2 = dy;
+
+ /* Use the panoramiX values to determine visibility */
+
+ oldVis = pParent->visibility;
+ /* Get the visibility save in the PanoramiX data structure */
+ j = pScreen->myNum;
+ PANORAMIXFIND_ID_BY_SCRNUM(pPanoramiXWin, pParent->drawable.id, j);
+ if ( pPanoramiXWin )
+ PanoramiXoldVis = pPanoramiXWin->visibility;
+ else
+ PanoramiXoldVis = pParent->visibility;
+ if (oldVis == VisibilityNotViewable)
+ PanoramiXoldVis = oldVis;
+ switch (RECT_IN_REGION( pScreen, panoramiXuniverse, &borderSize))
+ {
+ case rgnIN:
+ PanoramiXnewVis = VisibilityUnobscured;
+ break;
+ case rgnPART:
+ PanoramiXnewVis = VisibilityPartiallyObscured;
+#ifdef SHAPE
+ {
+ RegionPtr pBounding;
+
+ if ((pBounding = wBoundingShape (pParent)))
+ {
+ switch (miShapedWindowIn (pScreen, panoramiXuniverse, pBounding,
+ &borderSize,
+ pParent->drawable.x,
+ pParent->drawable.y))
+ {
+ case rgnIN:
+ PanoramiXnewVis = VisibilityUnobscured;
+ break;
+ case rgnOUT:
+ PanoramiXnewVis = VisibilityFullyObscured;
+ break;
+ }
+ }
+ }
+#endif
+ break;
+ default:
+ PanoramiXnewVis = VisibilityFullyObscured;
+ break;
+ }
+ if (pPanoramiXWin) {
+ pPanoramiXWin->visibility = PanoramiXnewVis;
+ PanoramiXVisibilityNotifySent = pPanoramiXWin->VisibilitySent;
+ }else
+ PanoramiXVisibilityNotifySent = FALSE;
+
+ if (PanoramiXoldVis != PanoramiXnewVis && (!PanoramiXVisibilityNotifySent)
+&&
+ ((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask)) {
+ pParent->visibility = PanoramiXnewVis;
+ pPanoramiXWin->VisibilitySent = TRUE;
+ SendVisibilityNotify(pParent);
+ pParent->visibility = oldVis;
+ }
+
+ switch (RECT_IN_REGION( pScreen, universe, &borderSize))
+ {
+ case rgnIN:
+ newVis = VisibilityUnobscured;
+ break;
+ case rgnPART:
+ newVis = VisibilityPartiallyObscured;
+#ifdef SHAPE
+ {
+ RegionPtr pBounding;
+
+ if ((pBounding = wBoundingShape (pParent)))
+ {
+ switch (miShapedWindowIn (pScreen, universe, pBounding,
+ &borderSize,
+ pParent->drawable.x,
+ pParent->drawable.y))
+ {
+ case rgnIN:
+ newVis = VisibilityUnobscured;
+ break;
+ case rgnOUT:
+ newVis = VisibilityFullyObscured;
+ break;
+ }
+ }
+ }
+#endif
+ break;
+ default:
+ newVis = VisibilityFullyObscured;
+ break;
+ }
+ pParent->visibility = newVis;
+ /*
+ if (oldVis != newVis &&
+ ((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
+ SendVisibilityNotify(pParent);
+ */
+ dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
+ dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
+
+ /*
+ * avoid computations when dealing with simple operations
+ */
+
+ switch (kind) {
+ case VTMap:
+ case VTStack:
+ case VTUnmap:
+ break;
+ case VTMove:
+ if ((oldVis == newVis) &&
+ ((oldVis == VisibilityFullyObscured) ||
+ (oldVis == VisibilityUnobscured)))
+ {
+ pChild = pParent;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ if (pChild->visibility != VisibilityFullyObscured)
+ {
+ REGION_TRANSLATE( pScreen, &pChild->borderClip,
+ dx, dy);
+ REGION_TRANSLATE( pScreen, &pChild->clipList,
+ dx, dy);
+ pChild->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ if (pScreen->ClipNotify)
+ (* pScreen->ClipNotify) (pChild, dx, dy);
+
+ }
+ if (pChild->valdata)
+ {
+ REGION_INIT(pScreen,
+ &pChild->valdata->after.borderExposed,
+ NullBox, 0);
+ if (HasParentRelativeBorder(pChild))
+ {
+ REGION_SUBTRACT(pScreen,
+ &pChild->valdata->after.borderExposed,
+ &pChild->borderClip,
+ &pChild->winSize);
+ }
+ REGION_INIT( pScreen, &pChild->valdata->after.exposed,
+ NullBox, 0);
+ }
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pParent))
+ pChild = pChild->parent;
+ if (pChild == pParent)
+ break;
+ pChild = pChild->nextSib;
+ }
+ return;
+ }
+ /* fall through */
+ default:
+ /*
+ * To calculate exposures correctly, we have to translate the old
+ * borderClip and clipList regions to the window's new location so there
+ * is a correspondence between pieces of the new and old clipping regions.
+ */
+ if (dx || dy)
+ {
+ /*
+ * We translate the old clipList because that will be exposed or copied
+ * if gravity is right.
+ */
+ REGION_TRANSLATE( pScreen, &pParent->borderClip, dx, dy);
+ REGION_TRANSLATE( pScreen, &pParent->clipList, dx, dy);
+ }
+ break;
+ }
+
+ borderVisible = pParent->valdata->before.borderVisible;
+ resized = pParent->valdata->before.resized;
+ REGION_INIT( pScreen, &pParent->valdata->after.borderExposed, NullBox, 0);
+ REGION_INIT( pScreen, &pParent->valdata->after.exposed, NullBox, 0);
+
+ /*
+ * Since the borderClip must not be clipped by the children, we do
+ * the border exposure first...
+ *
+ * 'universe' is the window's borderClip. To figure the exposures, remove
+ * the area that used to be exposed from the new.
+ * This leaves a region of pieces that weren't exposed before.
+ */
+
+ if (HasBorder (pParent))
+ {
+ if (borderVisible)
+ {
+ /*
+ * when the border changes shape, the old visible portions
+ * of the border will be saved by DIX in borderVisible --
+ * use that region and destroy it
+ */
+ REGION_SUBTRACT( pScreen, exposed, universe, borderVisible);
+ REGION_DESTROY( pScreen, borderVisible);
+ }
+ else
+ {
+ REGION_SUBTRACT( pScreen, exposed, universe, &pParent->borderClip);
+ }
+ if (HasParentRelativeBorder(pParent) && (dx || dy))
+ REGION_SUBTRACT( pScreen, &pParent->valdata->after.borderExposed,
+ universe,
+ &pParent->winSize);
+ else
+ REGION_SUBTRACT( pScreen, &pParent->valdata->after.borderExposed,
+ exposed, &pParent->winSize);
+
+ REGION_COPY( pScreen, &pParent->borderClip, universe);
+
+ /*
+ * To get the right clipList for the parent, and to make doubly sure
+ * that no child overlaps the parent's border, we remove the parent's
+ * border from the universe before proceeding.
+ */
+
+ REGION_INTERSECT( pScreen, universe, universe, &pParent->winSize);
+ }
+ else
+ REGION_COPY( pScreen, &pParent->borderClip, universe);
+
+ if ((pChild = pParent->firstChild) && pParent->mapped)
+ {
+ REGION_INIT(pScreen, &childUniverse, NullBox, 0);
+ REGION_INIT(pScreen, &PanoramiXchildUniverse, NullBox, 0);
+ REGION_INIT(pScreen, &childUnion, NullBox, 0);
+ if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
+ ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
+ (pChild->drawable.x < pParent->lastChild->drawable.x)))
+ {
+ for (; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->viewable)
+ REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
+ }
+ }
+ else
+ {
+ for (pChild = pParent->lastChild; pChild; pChild = pChild->prevSib)
+ {
+ if (pChild->viewable)
+ REGION_APPEND( pScreen, &childUnion, &pChild->borderSize);
+ }
+ }
+ REGION_VALIDATE( pScreen, &childUnion, &overlap);
+
+ for (pChild = pParent->firstChild;
+ pChild;
+ pChild = pChild->nextSib)
+ {
+ if (pChild->viewable) {
+ /*
+ * If the child is viewable, we want to remove its extents
+ * from the current universe, but we only re-clip it if
+ * it's been marked.
+ */
+ if (pChild->valdata) {
+ /*
+ * Figure out the new universe from the child's
+ * perspective and recurse.
+ */
+ REGION_INTERSECT( pScreen, &childUniverse, universe,
+ &pChild->borderSize);
+ REGION_INIT(pScreen, &PanoramiXborderSize, NullBox, 0);
+ if ( kind == VTMove )
+ PanoramiXClippedRegion(pChild, &PanoramiXborderSize,
+ (pChild->borderSize.extents.x2 - wBorderWidth(pChild)),
+ (pChild->borderSize.extents.y2 - wBorderWidth(pChild)),
+ (pChild->drawable.width + (2*wBorderWidth(pChild))),
+ (pChild->drawable.height + (2*wBorderWidth(pChild))));
+ else
+ PanoramiXClippedRegion(pChild, &PanoramiXborderSize,
+ (pChild->drawable.x - wBorderWidth(pChild)),
+ (pChild->drawable.y - wBorderWidth(pChild)),
+ (pChild->drawable.width + (2*wBorderWidth(pChild))),
+ (pChild->drawable.height + (2*wBorderWidth(pChild))));
+
+ REGION_UNION(pScreen, &PanoramiXchildUniverse, panoramiXuniverse,
+ &PanoramiXborderSize);
+
+ PanoramiXComputeClips (pChild, pScreen, &childUniverse, &PanoramiXchildUniverse, kind, exposed);
+ }
+ /*
+ * Once the child has been processed, we remove its extents
+ * from the current universe, thus denying its space to any
+ * other sibling.
+ */
+ if (overlap)
+ REGION_SUBTRACT( pScreen, universe, universe,
+ &pChild->borderSize);
+ }
+ }
+ if (!overlap)
+ REGION_SUBTRACT( pScreen, universe, universe, &childUnion);
+ REGION_UNINIT( pScreen, &childUnion);
+ REGION_UNINIT( pScreen, &childUniverse);
+ } /* if any children */
+
+ /*
+ * 'universe' now contains the new clipList for the parent window.
+ *
+ * To figure the exposure of the window we subtract the old clip from the
+ * new, just as for the border.
+ */
+
+ if (oldVis == VisibilityFullyObscured ||
+ oldVis == VisibilityNotViewable)
+ {
+ REGION_COPY( pScreen, &pParent->valdata->after.exposed, universe);
+ }
+ else if (newVis != VisibilityFullyObscured &&
+ newVis != VisibilityNotViewable)
+ {
+ REGION_SUBTRACT( pScreen, &pParent->valdata->after.exposed,
+ universe, &pParent->clipList);
+ }
+
+ /*
+ * One last thing: backing storage. We have to try to save what parts of
+ * the window are about to be obscured. We can just subtract the universe
+ * from the old clipList and get the areas that were in the old but aren't
+ * in the new and, hence, are about to be obscured.
+ */
+ if (pParent->backStorage && !resized)
+ {
+ REGION_SUBTRACT( pScreen, exposed, &pParent->clipList, universe);
+ (* pScreen->SaveDoomedAreas)(pParent, exposed, dx, dy);
+ }
+
+ /* HACK ALERT - copying contents of regions, instead of regions */
+ {
+ RegionRec tmp;
+
+ tmp = pParent->clipList;
+ pParent->clipList = *universe;
+ *universe = tmp;
+ }
+
+#ifdef NOTDEF
+ REGION_COPY( pScreen, &pParent->clipList, universe);
+#endif
+
+ pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ if (pScreen->ClipNotify)
+ (* pScreen->ClipNotify) (pParent, dx, dy);
+}
+#endif
+
+static void
+miTreeObscured(pParent)
+ register WindowPtr pParent;
+{
+ register WindowPtr pChild;
+ register int oldVis;
+
+ pChild = pParent;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ oldVis = pChild->visibility;
+ if (oldVis != (pChild->visibility = VisibilityFullyObscured) &&
+ ((pChild->eventMask | wOtherEventMasks(pChild)) & VisibilityChangeMask))
+ SendVisibilityNotify(pChild);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pParent))
+ pChild = pChild->parent;
+ if (pChild == pParent)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
+
+/*
+ *-----------------------------------------------------------------------
+ * miValidateTree --
+ * Recomputes the clip list for pParent and all its inferiors.
+ *
+ * Results:
+ * Always returns 1.
+ *
+ * Side Effects:
+ * The clipList, borderClip, exposed, and borderExposed regions for
+ * each marked window are altered.
+ *
+ * Notes:
+ * This routine assumes that all affected windows have been marked
+ * (valdata created) and their winSize and borderSize regions
+ * adjusted to correspond to their new positions. The borderClip and
+ * clipList regions should not have been touched.
+ *
+ * The top-most level is treated differently from all lower levels
+ * because pParent is unchanged. For the top level, we merge the
+ * regions taken up by the marked children back into the clipList
+ * for pParent, thus forming a region from which the marked children
+ * can claim their areas. For lower levels, where the old clipList
+ * and borderClip are invalid, we can't do this and have to do the
+ * extra operations done in miComputeClips, but this is much faster
+ * e.g. when only one child has moved...
+ *
+ *-----------------------------------------------------------------------
+ */
+/*ARGSUSED*/
+int
+miValidateTree (pParent, pChild, kind)
+ WindowPtr pParent; /* Parent to validate */
+ WindowPtr pChild; /* First child of pParent that was
+ * affected */
+ VTKind kind; /* What kind of configuration caused call */
+{
+ RegionRec totalClip; /* Total clipping region available to
+ * the marked children. pParent's clipList
+ * merged with the borderClips of all
+ * the marked children. */
+ RegionRec childClip; /* The new borderClip for the current
+ * child */
+ RegionRec childUnion; /* the space covered by borderSize for
+ * all marked children */
+ RegionRec exposed; /* For intermediate calculations */
+ register ScreenPtr pScreen;
+ register WindowPtr pWin;
+ Bool overlap;
+ int viewvals;
+ Bool forward;
+#ifdef PANORAMIX
+ RegionRec PanoramiXtotalClip; /* Total PanoramiX clipping region
+ * available to the marked children. */
+ RegionRec PanoramiXborderSize;
+ RegionRec PanoramiXborderClip;
+ RegionRec PanoramiXclipList;
+ RegionRec PanoramiXchildClip;
+#endif
+
+ pScreen = pParent->drawable.pScreen;
+ if (pChild == NullWindow)
+ pChild = pParent->firstChild;
+
+ REGION_INIT(pScreen, &childClip, NullBox, 0);
+ REGION_INIT(pScreen, &exposed, NullBox, 0);
+
+ /*
+ * compute the area of the parent window occupied
+ * by the marked children + the parent itself. This
+ * is the area which can be divied up among the marked
+ * children in their new configuration.
+ */
+ REGION_INIT(pScreen, &totalClip, NullBox, 0);
+#ifdef PANORAMIX
+ REGION_INIT(pScreen, &PanoramiXtotalClip, NullBox, 0);
+ REGION_INIT(pScreen, &PanoramiXborderSize, NullBox, 0);
+ REGION_INIT(pScreen, &PanoramiXborderClip, NullBox, 0);
+ REGION_INIT(pScreen, &PanoramiXclipList, NullBox, 0);
+ REGION_INIT(pScreen, &PanoramiXchildClip, NullBox, 0);
+#endif
+ viewvals = 0;
+ if ((pChild->drawable.y < pParent->lastChild->drawable.y) ||
+ ((pChild->drawable.y == pParent->lastChild->drawable.y) &&
+ (pChild->drawable.x < pParent->lastChild->drawable.x)))
+ {
+ forward = TRUE;
+ for (pWin = pChild; pWin; pWin = pWin->nextSib)
+ {
+ if (pWin->valdata)
+ {
+ REGION_APPEND( pScreen, &totalClip, &pWin->borderClip);
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ REGION_INIT(pScreen, &PanoramiXborderClip, NullBox, 0);
+ if ( kind == VTMove )
+ PanoramiXClippedRegion(pWin, &PanoramiXborderClip,
+ (pWin->borderClip.extents.x2 - pWin->drawable.width
+ - wBorderWidth(pWin) ),
+ (pWin->borderClip.extents.y2 - pWin->drawable.height
+ - wBorderWidth(pWin) ),
+ (pWin->drawable.width + (2*wBorderWidth(pWin))),
+ (pWin->drawable.height + (2*wBorderWidth(pWin))));
+ else
+ PanoramiXClippedRegion(pWin, &PanoramiXborderClip,
+ (pWin->drawable.x - wBorderWidth(pWin)),
+ (pWin->drawable.y - wBorderWidth(pWin)),
+ (pWin->drawable.width + (2*wBorderWidth(pWin))),
+ (pWin->drawable.height + (2*wBorderWidth(pWin))));
+ REGION_APPEND( pScreen, &PanoramiXtotalClip, &PanoramiXborderClip);
+
+ }
+#endif
+ if (pWin->viewable)
+ viewvals++;
+ }
+ }
+ }
+ else
+ {
+ forward = FALSE;
+ pWin = pParent->lastChild;
+ while (1)
+ {
+ if (pWin->valdata)
+ {
+ REGION_APPEND( pScreen, &totalClip, &pWin->borderClip);
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ REGION_INIT(pScreen, &PanoramiXborderClip, NullBox, 0);
+ if ( kind == VTMove )
+ PanoramiXClippedRegion(pWin, &PanoramiXborderClip,
+ (pWin->borderClip.extents.x2 - pWin->drawable.width
+ - wBorderWidth(pWin) ),
+ (pWin->borderClip.extents.y2 - pWin->drawable.height
+ - wBorderWidth(pWin) ),
+ (pWin->drawable.width + (2*wBorderWidth(pWin))),
+ (pWin->drawable.height + (2*wBorderWidth(pWin))));
+ else
+ PanoramiXClippedRegion(pWin, &PanoramiXborderClip,
+ (pWin->drawable.x - wBorderWidth(pWin)),
+ (pWin->drawable.y - wBorderWidth(pWin)),
+ (pWin->drawable.width + (2*wBorderWidth(pWin))),
+ (pWin->drawable.height + (2*wBorderWidth(pWin))));
+ REGION_APPEND( pScreen, &PanoramiXtotalClip, &PanoramiXborderClip);
+ }
+#endif
+ if (pWin->viewable)
+ viewvals++;
+ }
+ if (pWin == pChild)
+ break;
+ pWin = pWin->prevSib;
+ }
+ }
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ REGION_VALIDATE( pScreen, &PanoramiXtotalClip, &overlap);
+ }
+#endif
+ REGION_VALIDATE( pScreen, &totalClip, &overlap);
+
+ /*
+ * Now go through the children of the root and figure their new
+ * borderClips from the totalClip, passing that off to miComputeClips
+ * to handle recursively. Once that's done, we remove the child
+ * from the totalClip to clip any siblings below it.
+ */
+
+ overlap = TRUE;
+ if (kind != VTStack)
+ {
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ REGION_INIT(pScreen, &PanoramiXclipList, NullBox, 0);
+ /* This should be the Root window, use clipList if its a Move
+ otherwise use the drawable x,y and widths, the areas might
+ have been clipped away, assign clipList to get data section */
+ if ( kind == VTMove )
+ PanoramiXClippedRegion(pParent, &PanoramiXclipList,
+ (pParent->clipList.extents.x2 - pParent->drawable.width
+ - wBorderWidth(pParent) ),
+ (pParent->clipList.extents.y2 - pParent->drawable.height
+ - wBorderWidth(pParent) ),
+ (pParent->drawable.width + (2*wBorderWidth(pParent))),
+ (pParent->drawable.height + (2*wBorderWidth(pParent))));
+ else
+ PanoramiXClippedRegion(pParent, &PanoramiXclipList,
+ (pParent->drawable.x - wBorderWidth(pParent)),
+ (pParent->drawable.y - wBorderWidth(pParent)),
+ (pParent->drawable.width + (2*wBorderWidth(pParent))),
+ (pParent->drawable.height + (2*wBorderWidth(pParent))));
+ REGION_UNION( pScreen, &PanoramiXtotalClip, &PanoramiXtotalClip,
+&PanoramiXclipList);
+ }
+#endif
+ REGION_UNION( pScreen, &totalClip, &totalClip, &pParent->clipList);
+ if (viewvals > 1)
+ {
+ /*
+ * precompute childUnion to discover whether any of them
+ * overlap. This seems redundant, but performance studies
+ * have demonstrated that the cost of this loop is
+ * lower than the cost of multiple Subtracts in the
+ * loop below.
+ */
+ REGION_INIT(pScreen, &childUnion, NullBox, 0);
+ if (forward)
+ {
+ for (pWin = pChild; pWin; pWin = pWin->nextSib)
+ if (pWin->valdata && pWin->viewable)
+ REGION_APPEND( pScreen, &childUnion,
+ &pWin->borderSize);
+ }
+ else
+ {
+ pWin = pParent->lastChild;
+ while (1)
+ {
+ if (pWin->valdata && pWin->viewable)
+ REGION_APPEND( pScreen, &childUnion,
+ &pWin->borderSize);
+ if (pWin == pChild)
+ break;
+ pWin = pWin->prevSib;
+ }
+ }
+ REGION_VALIDATE(pScreen, &childUnion, &overlap);
+ if (overlap)
+ REGION_UNINIT(pScreen, &childUnion);
+ }
+ }
+
+ for (pWin = pChild;
+ pWin != NullWindow;
+ pWin = pWin->nextSib)
+ {
+ if (pWin->viewable) {
+ if (pWin->valdata) {
+ REGION_INTERSECT( pScreen, &childClip,
+ &totalClip,
+ &pWin->borderSize);
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ REGION_INIT(pScreen, &PanoramiXborderSize, NullBox, 0);
+ if (( kind == VTMove ) && (pWin->borderSize.extents.x2 != 0 &&
+ pWin->borderSize.extents.y2 != 0)) {
+ PanoramiXClippedRegion(pWin, &PanoramiXborderSize,
+ (pWin->borderSize.extents.x2 - pWin->drawable.width
+ - wBorderWidth(pWin) ),
+ (pWin->borderSize.extents.y2 - pWin->drawable.height
+ - wBorderWidth(pWin) ),
+ (pWin->drawable.width + (2*wBorderWidth(pWin))),
+ (pWin->drawable.height + (2*wBorderWidth(pWin))));
+ }else {
+ PanoramiXClippedRegion(pWin, &PanoramiXborderSize,
+ (pWin->drawable.x - wBorderWidth(pWin)),
+ (pWin->drawable.y - wBorderWidth(pWin)),
+ (pWin->drawable.width + (2*wBorderWidth(pWin))),
+ (pWin->drawable.height + (2*wBorderWidth(pWin))));
+ }
+ if (miRegionDataCopy(&PanoramiXtotalClip, &totalClip) ) {
+ REGION_UNION( pScreen, &PanoramiXchildClip, &PanoramiXtotalClip, &PanoramiXborderSize);
+ PanoramiXComputeClips (pWin, pScreen, &childClip, &PanoramiXchildClip, kind, &exposed);
+ }else
+ miComputeClips (pWin, pScreen, &childClip, kind, &exposed);
+ }else
+ miComputeClips (pWin, pScreen, &childClip, kind, &exposed);
+
+#else
+ miComputeClips (pWin, pScreen, &childClip, kind, &exposed);
+#endif
+ if (overlap)
+ {
+ REGION_SUBTRACT( pScreen, &totalClip,
+ &totalClip,
+ &pWin->borderSize);
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension){
+ REGION_SUBTRACT( pScreen, &PanoramiXtotalClip,
+ &PanoramiXtotalClip,
+ &PanoramiXborderSize);
+ }
+#endif
+ }
+ } else if (pWin->visibility == VisibilityNotViewable) {
+ miTreeObscured(pWin);
+ }
+ } else {
+ if (pWin->valdata) {
+ REGION_EMPTY( pScreen, &pWin->clipList);
+ if (pScreen->ClipNotify)
+ (* pScreen->ClipNotify) (pWin, 0, 0);
+ REGION_EMPTY( pScreen, &pWin->borderClip);
+ pWin->valdata = (ValidatePtr)NULL;
+ }
+ }
+ }
+
+ REGION_UNINIT( pScreen, &childClip);
+#ifdef PANORAMIX
+ REGION_UNINIT(pScreen, &PanoramiXchildClip);
+#endif
+ if (!overlap)
+ {
+ REGION_SUBTRACT(pScreen, &totalClip, &totalClip, &childUnion);
+ REGION_UNINIT(pScreen, &childUnion);
+ }
+
+ REGION_INIT( pScreen, &pParent->valdata->after.exposed, NullBox, 0);
+ REGION_INIT( pScreen, &pParent->valdata->after.borderExposed, NullBox, 0);
+
+ /*
+ * each case below is responsible for updating the
+ * clipList and serial number for the parent window
+ */
+
+ switch (kind) {
+ case VTStack:
+ break;
+ default:
+ /*
+ * totalClip contains the new clipList for the parent. Figure out
+ * exposures and obscures as per miComputeClips and reset the parent's
+ * clipList.
+ */
+ REGION_SUBTRACT( pScreen, &pParent->valdata->after.exposed,
+ &totalClip, &pParent->clipList);
+ /* fall through */
+ case VTMap:
+ if (pParent->backStorage) {
+ REGION_SUBTRACT( pScreen, &exposed, &pParent->clipList, &totalClip);
+ (* pScreen->SaveDoomedAreas)(pParent, &exposed, 0, 0);
+ }
+
+ REGION_COPY( pScreen, &pParent->clipList, &totalClip);
+ pParent->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ break;
+ }
+
+ REGION_UNINIT( pScreen, &totalClip);
+ REGION_UNINIT( pScreen, &exposed);
+#ifdef PANORAMIX
+ REGION_UNINIT(pScreen, &PanoramiXtotalClip);
+ REGION_UNINIT(pScreen, &PanoramiXborderSize);
+ REGION_UNINIT(pScreen, &PanoramiXborderClip);
+ REGION_UNINIT(pScreen, &PanoramiXclipList);
+#endif
+ if (pScreen->ClipNotify)
+ (*pScreen->ClipNotify) (pParent, 0, 0);
+ return (1);
+}
diff --git a/xc/programs/Xserver/mi/miwideline.c b/xc/programs/Xserver/mi/miwideline.c
new file mode 100644
index 000000000..d3102e213
--- /dev/null
+++ b/xc/programs/Xserver/mi/miwideline.c
@@ -0,0 +1,2201 @@
+/* $TOG: miwideline.c /main/60 1998/03/07 17:40:23 kaleb $ */
+/*
+
+Copyright 1988, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+/* $XFree86: xc/programs/Xserver/mi/miwideline.c,v 1.6 1999/04/11 13:11:21 dawes Exp $ */
+
+/* Author: Keith Packard, MIT X Consortium */
+
+/*
+ * Mostly integer wideline code. Uses a technique similar to
+ * bresenham zero-width lines, except walks an X edge
+ */
+
+#include <stdio.h>
+#ifdef _XOPEN_SOURCE
+#include <math.h>
+#else
+#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */
+#include <math.h>
+#undef _XOPEN_SOURCE
+#endif
+#include "X.h"
+#include "windowstr.h"
+#include "gcstruct.h"
+#include "miscstruct.h"
+#include "miwideline.h"
+#include "mi.h"
+
+#ifdef ICEILTEMPDECL
+ICEILTEMPDECL
+#endif
+
+static void miLineArc();
+
+/*
+ * spans-based polygon filler
+ */
+
+void
+miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, overall_height,
+ left, right, left_count, right_count)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ unsigned long pixel;
+ SpanDataPtr spanData;
+ int y; /* start y coordinate */
+ int overall_height; /* height of entire segment */
+ PolyEdgePtr left, right;
+ int left_count, right_count;
+{
+ register int left_x = 0, left_e = 0;
+ int left_stepx = 0;
+ int left_signdx = 0;
+ int left_dy = 0, left_dx = 0;
+
+ register int right_x = 0, right_e = 0;
+ int right_stepx = 0;
+ int right_signdx = 0;
+ int right_dy = 0, right_dx = 0;
+
+ int height = 0;
+ int left_height = 0, right_height = 0;
+
+ register DDXPointPtr ppt;
+ DDXPointPtr pptInit;
+ register int *pwidth;
+ int *pwidthInit;
+ XID oldPixel;
+ int xorg;
+ Spans spanRec;
+
+ left_height = 0;
+ right_height = 0;
+
+ if (!spanData)
+ {
+ pptInit = (DDXPointPtr) ALLOCATE_LOCAL (overall_height * sizeof(*ppt));
+ if (!pptInit)
+ return;
+ pwidthInit = (int *) ALLOCATE_LOCAL (overall_height * sizeof(*pwidth));
+ if (!pwidthInit)
+ {
+ DEALLOCATE_LOCAL (pptInit);
+ return;
+ }
+ ppt = pptInit;
+ pwidth = pwidthInit;
+ oldPixel = pGC->fgPixel;
+ if (pixel != oldPixel)
+ {
+ DoChangeGC (pGC, GCForeground, (XID *)&pixel, FALSE);
+ ValidateGC (pDrawable, pGC);
+ }
+ }
+ else
+ {
+ spanRec.points = (DDXPointPtr) xalloc (overall_height * sizeof (*ppt));
+ if (!spanRec.points)
+ return;
+ spanRec.widths = (int *) xalloc (overall_height * sizeof (int));
+ if (!spanRec.widths)
+ {
+ xfree (spanRec.points);
+ return;
+ }
+ ppt = spanRec.points;
+ pwidth = spanRec.widths;
+ }
+
+ xorg = 0;
+ if (pGC->miTranslate)
+ {
+ y += pDrawable->y;
+ xorg = pDrawable->x;
+ }
+ while ((left_count || left_height) &&
+ (right_count || right_height))
+ {
+ MIPOLYRELOADLEFT
+ MIPOLYRELOADRIGHT
+
+ height = left_height;
+ if (height > right_height)
+ height = right_height;
+
+ left_height -= height;
+ right_height -= height;
+
+ while (--height >= 0)
+ {
+ if (right_x >= left_x)
+ {
+ ppt->y = y;
+ ppt->x = left_x + xorg;
+ ppt++;
+ *pwidth++ = right_x - left_x + 1;
+ }
+ y++;
+
+ MIPOLYSTEPLEFT
+
+ MIPOLYSTEPRIGHT
+ }
+ }
+ if (!spanData)
+ {
+ (*pGC->ops->FillSpans) (pDrawable, pGC, ppt - pptInit, pptInit, pwidthInit, TRUE);
+ DEALLOCATE_LOCAL (pwidthInit);
+ DEALLOCATE_LOCAL (pptInit);
+ if (pixel != oldPixel)
+ {
+ DoChangeGC (pGC, GCForeground, &oldPixel, FALSE);
+ ValidateGC (pDrawable, pGC);
+ }
+ }
+ else
+ {
+ spanRec.count = ppt - spanRec.points;
+ AppendSpanGroup (pGC, pixel, &spanRec, spanData)
+ }
+}
+
+static void
+miFillRectPolyHelper (pDrawable, pGC, pixel, spanData, x, y, w, h)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ unsigned long pixel;
+ SpanDataPtr spanData;
+ int x, y, w, h;
+{
+ register DDXPointPtr ppt;
+ register int *pwidth;
+ XID oldPixel;
+ Spans spanRec;
+ xRectangle rect;
+
+ if (!spanData)
+ {
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+ oldPixel = pGC->fgPixel;
+ if (pixel != oldPixel)
+ {
+ DoChangeGC (pGC, GCForeground, (XID *)&pixel, FALSE);
+ ValidateGC (pDrawable, pGC);
+ }
+ (*pGC->ops->PolyFillRect) (pDrawable, pGC, 1, &rect);
+ if (pixel != oldPixel)
+ {
+ DoChangeGC (pGC, GCForeground, &oldPixel, FALSE);
+ ValidateGC (pDrawable, pGC);
+ }
+ }
+ else
+ {
+ spanRec.points = (DDXPointPtr) xalloc (h * sizeof (*ppt));
+ if (!spanRec.points)
+ return;
+ spanRec.widths = (int *) xalloc (h * sizeof (int));
+ if (!spanRec.widths)
+ {
+ xfree (spanRec.points);
+ return;
+ }
+ ppt = spanRec.points;
+ pwidth = spanRec.widths;
+
+ if (pGC->miTranslate)
+ {
+ y += pDrawable->y;
+ x += pDrawable->x;
+ }
+ while (h--)
+ {
+ ppt->x = x;
+ ppt->y = y;
+ ppt++;
+ *pwidth++ = w;
+ y++;
+ }
+ spanRec.count = ppt - spanRec.points;
+ AppendSpanGroup (pGC, pixel, &spanRec, spanData)
+ }
+}
+
+/* static */ int
+miPolyBuildEdge (x0, y0, k, dx, dy, xi, yi, left, edge)
+ double x0, y0;
+ double k; /* x0 * dy - y0 * dx */
+ register int dx, dy;
+ int xi, yi;
+ int left;
+ register PolyEdgePtr edge;
+{
+ int x, y, e;
+ int xady;
+
+ if (dy < 0)
+ {
+ dy = -dy;
+ dx = -dx;
+ k = -k;
+ }
+
+#ifdef NOTDEF
+ {
+ double realk, kerror;
+ realk = x0 * dy - y0 * dx;
+ kerror = Fabs (realk - k);
+ if (kerror > .1)
+ printf ("realk: %g k: %g\n", realk, k);
+ }
+#endif
+ y = ICEIL (y0);
+ xady = ICEIL (k) + y * dx;
+
+ if (xady <= 0)
+ x = - (-xady / dy) - 1;
+ else
+ x = (xady - 1) / dy;
+
+ e = xady - x * dy;
+
+ if (dx >= 0)
+ {
+ edge->signdx = 1;
+ edge->stepx = dx / dy;
+ edge->dx = dx % dy;
+ }
+ else
+ {
+ edge->signdx = -1;
+ edge->stepx = - (-dx / dy);
+ edge->dx = -dx % dy;
+ e = dy - e + 1;
+ }
+ edge->dy = dy;
+ edge->x = x + left + xi;
+ edge->e = e - dy; /* bias to compare against 0 instead of dy */
+ return y + yi;
+}
+
+#define StepAround(v, incr, max) (((v) + (incr) < 0) ? (max - 1) : ((v) + (incr) == max) ? 0 : ((v) + (incr)))
+
+/* static */ int
+miPolyBuildPoly (vertices, slopes, count, xi, yi, left, right, pnleft, pnright, h)
+ register PolyVertexPtr vertices;
+ register PolySlopePtr slopes;
+ int count;
+ int xi, yi;
+ PolyEdgePtr left, right;
+ int *pnleft, *pnright;
+ int *h;
+{
+ int top, bottom;
+ double miny, maxy;
+ register int i;
+ int j;
+ int clockwise;
+ int slopeoff;
+ register int s;
+ register int nright, nleft;
+ int y, lasty = 0, bottomy, topy = 0;
+
+ /* find the top of the polygon */
+ maxy = miny = vertices[0].y;
+ bottom = top = 0;
+ for (i = 1; i < count; i++)
+ {
+ if (vertices[i].y < miny)
+ {
+ top = i;
+ miny = vertices[i].y;
+ }
+ if (vertices[i].y >= maxy)
+ {
+ bottom = i;
+ maxy = vertices[i].y;
+ }
+ }
+ clockwise = 1;
+ slopeoff = 0;
+
+ i = top;
+ j = StepAround (top, -1, count);
+
+ if (slopes[j].dy * slopes[i].dx > slopes[i].dy * slopes[j].dx)
+ {
+ clockwise = -1;
+ slopeoff = -1;
+ }
+
+ bottomy = ICEIL (maxy) + yi;
+
+ nright = 0;
+
+ s = StepAround (top, slopeoff, count);
+ i = top;
+ while (i != bottom)
+ {
+ if (slopes[s].dy != 0)
+ {
+ y = miPolyBuildEdge (vertices[i].x, vertices[i].y,
+ slopes[s].k,
+ slopes[s].dx, slopes[s].dy,
+ xi, yi, 0,
+ &right[nright]);
+ if (nright != 0)
+ right[nright-1].height = y - lasty;
+ else
+ topy = y;
+ nright++;
+ lasty = y;
+ }
+
+ i = StepAround (i, clockwise, count);
+ s = StepAround (s, clockwise, count);
+ }
+ if (nright != 0)
+ right[nright-1].height = bottomy - lasty;
+
+ if (slopeoff == 0)
+ slopeoff = -1;
+ else
+ slopeoff = 0;
+
+ nleft = 0;
+ s = StepAround (top, slopeoff, count);
+ i = top;
+ while (i != bottom)
+ {
+ if (slopes[s].dy != 0)
+ {
+ y = miPolyBuildEdge (vertices[i].x, vertices[i].y,
+ slopes[s].k,
+ slopes[s].dx, slopes[s].dy, xi, yi, 1,
+ &left[nleft]);
+
+ if (nleft != 0)
+ left[nleft-1].height = y - lasty;
+ nleft++;
+ lasty = y;
+ }
+ i = StepAround (i, -clockwise, count);
+ s = StepAround (s, -clockwise, count);
+ }
+ if (nleft != 0)
+ left[nleft-1].height = bottomy - lasty;
+ *pnleft = nleft;
+ *pnright = nright;
+ *h = bottomy - topy;
+ return topy;
+}
+
+static void
+miLineOnePoint (pDrawable, pGC, pixel, spanData, x, y)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ unsigned long pixel;
+ SpanDataPtr spanData;
+ int x, y;
+{
+ DDXPointRec pt;
+ int wid;
+ unsigned long oldPixel;
+
+ MILINESETPIXEL (pDrawable, pGC, pixel, oldPixel);
+ if (pGC->fillStyle == FillSolid)
+ {
+ pt.x = x;
+ pt.y = y;
+ (*pGC->ops->PolyPoint) (pDrawable, pGC, CoordModeOrigin, 1, &pt);
+ }
+ else
+ {
+ wid = 1;
+ if (pGC->miTranslate)
+ {
+ x += pDrawable->x;
+ y += pDrawable->y;
+ }
+ pt.x = x;
+ pt.y = y;
+ (*pGC->ops->FillSpans) (pDrawable, pGC, 1, &pt, &wid, TRUE);
+ }
+ MILINERESETPIXEL (pDrawable, pGC, pixel, oldPixel);
+}
+
+static void
+miLineJoin (pDrawable, pGC, pixel, spanData, pLeft, pRight)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ unsigned long pixel;
+ SpanDataPtr spanData;
+ register LineFacePtr pLeft, pRight;
+{
+ double mx, my;
+ double denom = 0.0;
+ PolyVertexRec vertices[4];
+ PolySlopeRec slopes[4];
+ int edgecount;
+ PolyEdgeRec left[4], right[4];
+ int nleft, nright;
+ int y, height;
+ int swapslopes;
+ int joinStyle = pGC->joinStyle;
+ int lw = pGC->lineWidth;
+
+ if (lw == 1 && !spanData) {
+ /* Lines going in the same direction have no join */
+ if (pLeft->dx >= 0 == pRight->dx <= 0)
+ return;
+ if (joinStyle != JoinRound) {
+ denom = - pLeft->dx * (double)pRight->dy + pRight->dx * (double)pLeft->dy;
+ if (denom == 0)
+ return; /* no join to draw */
+ }
+ if (joinStyle != JoinMiter) {
+ miLineOnePoint (pDrawable, pGC, pixel, spanData, pLeft->x, pLeft->y);
+ return;
+ }
+ } else {
+ if (joinStyle == JoinRound)
+ {
+ miLineArc(pDrawable, pGC, pixel, spanData,
+ pLeft, pRight,
+ (double)0.0, (double)0.0, TRUE);
+ return;
+ }
+ denom = - pLeft->dx * (double)pRight->dy + pRight->dx * (double)pLeft->dy;
+ if (denom == 0.0)
+ return; /* no join to draw */
+ }
+
+ swapslopes = 0;
+ if (denom > 0)
+ {
+ pLeft->xa = -pLeft->xa;
+ pLeft->ya = -pLeft->ya;
+ pLeft->dx = -pLeft->dx;
+ pLeft->dy = -pLeft->dy;
+ }
+ else
+ {
+ swapslopes = 1;
+ pRight->xa = -pRight->xa;
+ pRight->ya = -pRight->ya;
+ pRight->dx = -pRight->dx;
+ pRight->dy = -pRight->dy;
+ }
+
+ vertices[0].x = pRight->xa;
+ vertices[0].y = pRight->ya;
+ slopes[0].dx = -pRight->dy;
+ slopes[0].dy = pRight->dx;
+ slopes[0].k = 0;
+
+ vertices[1].x = 0;
+ vertices[1].y = 0;
+ slopes[1].dx = pLeft->dy;
+ slopes[1].dy = -pLeft->dx;
+ slopes[1].k = 0;
+
+ vertices[2].x = pLeft->xa;
+ vertices[2].y = pLeft->ya;
+
+ if (joinStyle == JoinMiter)
+ {
+ my = (pLeft->dy * (pRight->xa * pRight->dy - pRight->ya * pRight->dx) -
+ pRight->dy * (pLeft->xa * pLeft->dy - pLeft->ya * pLeft->dx )) /
+ denom;
+ if (pLeft->dy != 0)
+ {
+ mx = pLeft->xa + (my - pLeft->ya) *
+ (double) pLeft->dx / (double) pLeft->dy;
+ }
+ else
+ {
+ mx = pRight->xa + (my - pRight->ya) *
+ (double) pRight->dx / (double) pRight->dy;
+ }
+ /* check miter limit */
+ if ((mx * mx + my * my) * 4 > SQSECANT * lw * lw)
+ joinStyle = JoinBevel;
+ }
+
+ if (joinStyle == JoinMiter)
+ {
+ slopes[2].dx = pLeft->dx;
+ slopes[2].dy = pLeft->dy;
+ slopes[2].k = pLeft->k;
+ if (swapslopes)
+ {
+ slopes[2].dx = -slopes[2].dx;
+ slopes[2].dy = -slopes[2].dy;
+ slopes[2].k = -slopes[2].k;
+ }
+ vertices[3].x = mx;
+ vertices[3].y = my;
+ slopes[3].dx = pRight->dx;
+ slopes[3].dy = pRight->dy;
+ slopes[3].k = pRight->k;
+ if (swapslopes)
+ {
+ slopes[3].dx = -slopes[3].dx;
+ slopes[3].dy = -slopes[3].dy;
+ slopes[3].k = -slopes[3].k;
+ }
+ edgecount = 4;
+ }
+ else
+ {
+ double scale, dx, dy, adx, ady;
+
+ adx = dx = pRight->xa - pLeft->xa;
+ ady = dy = pRight->ya - pLeft->ya;
+ if (adx < 0)
+ adx = -adx;
+ if (ady < 0)
+ ady = -ady;
+ scale = ady;
+ if (adx > ady)
+ scale = adx;
+ slopes[2].dx = (dx * 65536) / scale;
+ slopes[2].dy = (dy * 65536) / scale;
+ slopes[2].k = ((pLeft->xa + pRight->xa) * slopes[2].dy -
+ (pLeft->ya + pRight->ya) * slopes[2].dx) / 2.0;
+ edgecount = 3;
+ }
+
+ y = miPolyBuildPoly (vertices, slopes, edgecount, pLeft->x, pLeft->y,
+ left, right, &nleft, &nright, &height);
+ miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, height, left, right, nleft, nright);
+}
+
+static int
+miLineArcI (pDraw, pGC, xorg, yorg, points, widths)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int xorg, yorg;
+ DDXPointPtr points;
+ int *widths;
+{
+ register DDXPointPtr tpts, bpts;
+ register int *twids, *bwids;
+ register int x, y, e, ex, slw;
+
+ tpts = points;
+ twids = widths;
+ if (pGC->miTranslate)
+ {
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ }
+ slw = pGC->lineWidth;
+ if (slw == 1)
+ {
+ tpts->x = xorg;
+ tpts->y = yorg;
+ *twids = 1;
+ return 1;
+ }
+ bpts = tpts + slw;
+ bwids = twids + slw;
+ y = (slw >> 1) + 1;
+ if (slw & 1)
+ e = - ((y << 2) + 3);
+ else
+ e = - (y << 3);
+ ex = -4;
+ x = 0;
+ while (y)
+ {
+ e += (y << 3) - 4;
+ while (e >= 0)
+ {
+ x++;
+ e += (ex = -((x << 3) + 4));
+ }
+ y--;
+ slw = (x << 1) + 1;
+ if ((e == ex) && (slw > 1))
+ slw--;
+ tpts->x = xorg - x;
+ tpts->y = yorg - y;
+ tpts++;
+ *twids++ = slw;
+ if ((y != 0) && ((slw > 1) || (e != ex)))
+ {
+ bpts--;
+ bpts->x = xorg - x;
+ bpts->y = yorg + y;
+ *--bwids = slw;
+ }
+ }
+ return (pGC->lineWidth);
+}
+
+#define CLIPSTEPEDGE(edgey,edge,edgeleft) \
+ if (ybase == edgey) \
+ { \
+ if (edgeleft) \
+ { \
+ if (edge->x > xcl) \
+ xcl = edge->x; \
+ } \
+ else \
+ { \
+ if (edge->x < xcr) \
+ xcr = edge->x; \
+ } \
+ edgey++; \
+ edge->x += edge->stepx; \
+ edge->e += edge->dx; \
+ if (edge->e > 0) \
+ { \
+ edge->x += edge->signdx; \
+ edge->e -= edge->dy; \
+ } \
+ }
+
+static int
+miLineArcD (pDraw, pGC, xorg, yorg, points, widths,
+ edge1, edgey1, edgeleft1, edge2, edgey2, edgeleft2)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ double xorg, yorg;
+ DDXPointPtr points;
+ int *widths;
+ PolyEdgePtr edge1, edge2;
+ int edgey1, edgey2;
+ Bool edgeleft1, edgeleft2;
+{
+ register DDXPointPtr pts;
+ register int *wids;
+ double radius, x0, y0, el, er, yk, xlk, xrk, k;
+ int xbase, ybase, y, boty, xl, xr, xcl, xcr;
+ int ymin, ymax;
+ Bool edge1IsMin, edge2IsMin;
+ int ymin1, ymin2;
+
+ pts = points;
+ wids = widths;
+ xbase = floor(xorg);
+ x0 = xorg - xbase;
+ ybase = ICEIL (yorg);
+ y0 = yorg - ybase;
+ if (pGC->miTranslate)
+ {
+ xbase += pDraw->x;
+ ybase += pDraw->y;
+ edge1->x += pDraw->x;
+ edge2->x += pDraw->x;
+ edgey1 += pDraw->y;
+ edgey2 += pDraw->y;
+ }
+ xlk = x0 + x0 + 1.0;
+ xrk = x0 + x0 - 1.0;
+ yk = y0 + y0 - 1.0;
+ radius = ((double)pGC->lineWidth) / 2.0;
+ y = floor(radius - y0 + 1.0);
+ ybase -= y;
+ ymin = ybase;
+ ymax = 65536;
+ edge1IsMin = FALSE;
+ ymin1 = edgey1;
+ if (edge1->dy >= 0)
+ {
+ if (!edge1->dy)
+ {
+ if (edgeleft1)
+ edge1IsMin = TRUE;
+ else
+ ymax = edgey1;
+ edgey1 = 65536;
+ }
+ else
+ {
+ if ((edge1->signdx < 0) == edgeleft1)
+ edge1IsMin = TRUE;
+ }
+ }
+ edge2IsMin = FALSE;
+ ymin2 = edgey2;
+ if (edge2->dy >= 0)
+ {
+ if (!edge2->dy)
+ {
+ if (edgeleft2)
+ edge2IsMin = TRUE;
+ else
+ ymax = edgey2;
+ edgey2 = 65536;
+ }
+ else
+ {
+ if ((edge2->signdx < 0) == edgeleft2)
+ edge2IsMin = TRUE;
+ }
+ }
+ if (edge1IsMin)
+ {
+ ymin = ymin1;
+ if (edge2IsMin && ymin1 > ymin2)
+ ymin = ymin2;
+ } else if (edge2IsMin)
+ ymin = ymin2;
+ el = radius * radius - ((y + y0) * (y + y0)) - (x0 * x0);
+ er = el + xrk;
+ xl = 1;
+ xr = 0;
+ if (x0 < 0.5)
+ {
+ xl = 0;
+ el -= xlk;
+ }
+ boty = (y0 < -0.5) ? 1 : 0;
+ if (ybase + y - boty > ymax)
+ boty = ymax - ybase - y;
+ while (y > boty)
+ {
+ k = (y << 1) + yk;
+ er += k;
+ while (er > 0.0)
+ {
+ xr++;
+ er += xrk - (xr << 1);
+ }
+ el += k;
+ while (el >= 0.0)
+ {
+ xl--;
+ el += (xl << 1) - xlk;
+ }
+ y--;
+ ybase++;
+ if (ybase < ymin)
+ continue;
+ xcl = xl + xbase;
+ xcr = xr + xbase;
+ CLIPSTEPEDGE(edgey1, edge1, edgeleft1);
+ CLIPSTEPEDGE(edgey2, edge2, edgeleft2);
+ if (xcr >= xcl)
+ {
+ pts->x = xcl;
+ pts->y = ybase;
+ pts++;
+ *wids++ = xcr - xcl + 1;
+ }
+ }
+ er = xrk - (xr << 1) - er;
+ el = (xl << 1) - xlk - el;
+ boty = floor(-y0 - radius + 1.0);
+ if (ybase + y - boty > ymax)
+ boty = ymax - ybase - y;
+ while (y > boty)
+ {
+ k = (y << 1) + yk;
+ er -= k;
+ while ((er >= 0.0) && (xr >= 0))
+ {
+ xr--;
+ er += xrk - (xr << 1);
+ }
+ el -= k;
+ while ((el > 0.0) && (xl <= 0))
+ {
+ xl++;
+ el += (xl << 1) - xlk;
+ }
+ y--;
+ ybase++;
+ if (ybase < ymin)
+ continue;
+ xcl = xl + xbase;
+ xcr = xr + xbase;
+ CLIPSTEPEDGE(edgey1, edge1, edgeleft1);
+ CLIPSTEPEDGE(edgey2, edge2, edgeleft2);
+ if (xcr >= xcl)
+ {
+ pts->x = xcl;
+ pts->y = ybase;
+ pts++;
+ *wids++ = xcr - xcl + 1;
+ }
+ }
+ return (pts - points);
+}
+
+int
+miRoundJoinFace (face, edge, leftEdge)
+ register LineFacePtr face;
+ register PolyEdgePtr edge;
+ Bool *leftEdge;
+{
+ int y;
+ int dx, dy;
+ double xa, ya;
+ Bool left;
+
+ dx = -face->dy;
+ dy = face->dx;
+ xa = face->xa;
+ ya = face->ya;
+ left = 1;
+ if (ya > 0)
+ {
+ ya = 0.0;
+ xa = 0.0;
+ }
+ if (dy < 0 || dy == 0 && dx > 0)
+ {
+ dx = -dx;
+ dy = -dy;
+ left = !left;
+ }
+ if (dx == 0 && dy == 0)
+ dy = 1;
+ if (dy == 0)
+ {
+ y = ICEIL (face->ya) + face->y;
+ edge->x = -32767;
+ edge->stepx = 0;
+ edge->signdx = 0;
+ edge->e = -1;
+ edge->dy = 0;
+ edge->dx = 0;
+ edge->height = 0;
+ }
+ else
+ {
+ y = miPolyBuildEdge (xa, ya, 0.0, dx, dy, face->x, face->y, !left, edge);
+ edge->height = 32767;
+ }
+ *leftEdge = !left;
+ return y;
+}
+
+void
+miRoundJoinClip (pLeft, pRight, edge1, edge2, y1, y2, left1, left2)
+ register LineFacePtr pLeft, pRight;
+ PolyEdgePtr edge1, edge2;
+ int *y1, *y2;
+ Bool *left1, *left2;
+{
+ double denom;
+
+ denom = - pLeft->dx * (double)pRight->dy + pRight->dx * (double)pLeft->dy;
+
+ if (denom >= 0)
+ {
+ pLeft->xa = -pLeft->xa;
+ pLeft->ya = -pLeft->ya;
+ }
+ else
+ {
+ pRight->xa = -pRight->xa;
+ pRight->ya = -pRight->ya;
+ }
+ *y1 = miRoundJoinFace (pLeft, edge1, left1);
+ *y2 = miRoundJoinFace (pRight, edge2, left2);
+}
+
+int
+miRoundCapClip (face, isInt, edge, leftEdge)
+ register LineFacePtr face;
+ Bool isInt;
+ register PolyEdgePtr edge;
+ Bool *leftEdge;
+{
+ int y;
+ register int dx, dy;
+ double xa, ya, k;
+ Bool left;
+
+ dx = -face->dy;
+ dy = face->dx;
+ xa = face->xa;
+ ya = face->ya;
+ k = 0.0;
+ if (!isInt)
+ k = face->k;
+ left = 1;
+ if (dy < 0 || dy == 0 && dx > 0)
+ {
+ dx = -dx;
+ dy = -dy;
+ xa = -xa;
+ ya = -ya;
+ left = !left;
+ }
+ if (dx == 0 && dy == 0)
+ dy = 1;
+ if (dy == 0)
+ {
+ y = ICEIL (face->ya) + face->y;
+ edge->x = -32767;
+ edge->stepx = 0;
+ edge->signdx = 0;
+ edge->e = -1;
+ edge->dy = 0;
+ edge->dx = 0;
+ edge->height = 0;
+ }
+ else
+ {
+ y = miPolyBuildEdge (xa, ya, k, dx, dy, face->x, face->y, !left, edge);
+ edge->height = 32767;
+ }
+ *leftEdge = !left;
+ return y;
+}
+
+static void
+miLineArc (pDraw, pGC, pixel, spanData, leftFace, rightFace, xorg, yorg, isInt)
+ DrawablePtr pDraw;
+ register GCPtr pGC;
+ unsigned long pixel;
+ SpanDataPtr spanData;
+ register LineFacePtr leftFace, rightFace;
+ double xorg, yorg;
+ Bool isInt;
+{
+ DDXPointPtr points;
+ int *widths;
+ int xorgi = 0, yorgi = 0;
+ XID oldPixel;
+ Spans spanRec;
+ int n;
+ PolyEdgeRec edge1, edge2;
+ int edgey1, edgey2;
+ Bool edgeleft1, edgeleft2;
+
+ if (isInt)
+ {
+ xorgi = leftFace ? leftFace->x : rightFace->x;
+ yorgi = leftFace ? leftFace->y : rightFace->y;
+ }
+ edgey1 = 65536;
+ edgey2 = 65536;
+ edge1.x = 0; /* not used, keep memory checkers happy */
+ edge1.dy = -1;
+ edge2.x = 0; /* not used, keep memory checkers happy */
+ edge2.dy = -1;
+ edgeleft1 = FALSE;
+ edgeleft2 = FALSE;
+ if ((pGC->lineStyle != LineSolid || pGC->lineWidth > 2) &&
+ (pGC->capStyle == CapRound && pGC->joinStyle != JoinRound ||
+ pGC->joinStyle == JoinRound && pGC->capStyle == CapButt))
+ {
+ if (isInt)
+ {
+ xorg = (double) xorgi;
+ yorg = (double) yorgi;
+ }
+ if (leftFace && rightFace)
+ {
+ miRoundJoinClip (leftFace, rightFace, &edge1, &edge2,
+ &edgey1, &edgey2, &edgeleft1, &edgeleft2);
+ }
+ else if (leftFace)
+ {
+ edgey1 = miRoundCapClip (leftFace, isInt, &edge1, &edgeleft1);
+ }
+ else if (rightFace)
+ {
+ edgey2 = miRoundCapClip (rightFace, isInt, &edge2, &edgeleft2);
+ }
+ isInt = FALSE;
+ }
+ if (!spanData)
+ {
+ points = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * pGC->lineWidth);
+ if (!points)
+ return;
+ widths = (int *)ALLOCATE_LOCAL(sizeof(int) * pGC->lineWidth);
+ if (!widths)
+ {
+ DEALLOCATE_LOCAL(points);
+ return;
+ }
+ oldPixel = pGC->fgPixel;
+ if (pixel != oldPixel)
+ {
+ DoChangeGC(pGC, GCForeground, (XID *)&pixel, FALSE);
+ ValidateGC (pDraw, pGC);
+ }
+ }
+ else
+ {
+ points = (DDXPointPtr) xalloc (pGC->lineWidth * sizeof (DDXPointRec));
+ if (!points)
+ return;
+ widths = (int *) xalloc (pGC->lineWidth * sizeof (int));
+ if (!widths)
+ {
+ xfree (points);
+ return;
+ }
+ spanRec.points = points;
+ spanRec.widths = widths;
+ }
+ if (isInt)
+ n = miLineArcI(pDraw, pGC, xorgi, yorgi, points, widths);
+ else
+ n = miLineArcD(pDraw, pGC, xorg, yorg, points, widths,
+ &edge1, edgey1, edgeleft1,
+ &edge2, edgey2, edgeleft2);
+
+ if (!spanData)
+ {
+ (*pGC->ops->FillSpans)(pDraw, pGC, n, points, widths, TRUE);
+ DEALLOCATE_LOCAL(widths);
+ DEALLOCATE_LOCAL(points);
+ if (pixel != oldPixel)
+ {
+ DoChangeGC(pGC, GCForeground, &oldPixel, FALSE);
+ ValidateGC (pDraw, pGC);
+ }
+ }
+ else
+ {
+ spanRec.count = n;
+ AppendSpanGroup (pGC, pixel, &spanRec, spanData)
+ }
+}
+
+void
+miLineProjectingCap (pDrawable, pGC, pixel, spanData, face, isLeft, xorg, yorg, isInt)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ unsigned long pixel;
+ SpanDataPtr spanData;
+ register LineFacePtr face;
+ Bool isLeft;
+ double xorg, yorg;
+ Bool isInt;
+{
+ int xorgi = 0, yorgi = 0;
+ int lw;
+ PolyEdgeRec lefts[2], rights[2];
+ int lefty, righty, topy, bottomy;
+ PolyEdgePtr left, right;
+ PolyEdgePtr top, bottom;
+ double xa,ya;
+ double k;
+ double xap, yap;
+ int dx, dy;
+ double projectXoff, projectYoff;
+ double maxy;
+ int finaly;
+
+ if (isInt)
+ {
+ xorgi = face->x;
+ yorgi = face->y;
+ }
+ lw = pGC->lineWidth;
+ dx = face->dx;
+ dy = face->dy;
+ k = face->k;
+ if (dy == 0)
+ {
+ lefts[0].height = lw;
+ lefts[0].x = xorgi;
+ if (isLeft)
+ lefts[0].x -= (lw >> 1);
+ lefts[0].stepx = 0;
+ lefts[0].signdx = 1;
+ lefts[0].e = -lw;
+ lefts[0].dx = 0;
+ lefts[0].dy = lw;
+ rights[0].height = lw;
+ rights[0].x = xorgi;
+ if (!isLeft)
+ rights[0].x += ((lw + 1) >> 1);
+ rights[0].stepx = 0;
+ rights[0].signdx = 1;
+ rights[0].e = -lw;
+ rights[0].dx = 0;
+ rights[0].dy = lw;
+ miFillPolyHelper (pDrawable, pGC, pixel, spanData, yorgi - (lw >> 1), lw,
+ lefts, rights, 1, 1);
+ }
+ else if (dx == 0)
+ {
+ topy = yorgi;
+ bottomy = yorgi + dy;
+ if (isLeft)
+ topy -= (lw >> 1);
+ else
+ bottomy += (lw >> 1);
+ lefts[0].height = bottomy - topy;
+ lefts[0].x = xorgi - (lw >> 1);
+ lefts[0].stepx = 0;
+ lefts[0].signdx = 1;
+ lefts[0].e = -dy;
+ lefts[0].dx = dx;
+ lefts[0].dy = dy;
+
+ rights[0].height = bottomy - topy;
+ rights[0].x = lefts[0].x + (lw-1);
+ rights[0].stepx = 0;
+ rights[0].signdx = 1;
+ rights[0].e = -dy;
+ rights[0].dx = dx;
+ rights[0].dy = dy;
+ miFillPolyHelper (pDrawable, pGC, pixel, spanData, topy, bottomy - topy, lefts, rights, 1, 1);
+ }
+ else
+ {
+ xa = face->xa;
+ ya = face->ya;
+ projectXoff = -ya;
+ projectYoff = xa;
+ if (dx < 0)
+ {
+ right = &rights[1];
+ left = &lefts[0];
+ top = &rights[0];
+ bottom = &lefts[1];
+ }
+ else
+ {
+ right = &rights[0];
+ left = &lefts[1];
+ top = &lefts[0];
+ bottom = &rights[1];
+ }
+ if (isLeft)
+ {
+ righty = miPolyBuildEdge (xa, ya,
+ k, dx, dy, xorgi, yorgi, 0, right);
+
+ xa = -xa;
+ ya = -ya;
+ k = -k;
+ lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
+ k, dx, dy, xorgi, yorgi, 1, left);
+ if (dx > 0)
+ {
+ ya = -ya;
+ xa = -xa;
+ }
+ xap = xa - projectXoff;
+ yap = ya - projectYoff;
+ topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
+ -dy, dx, xorgi, yorgi, dx > 0, top);
+ bottomy = miPolyBuildEdge (xa, ya,
+ 0.0, -dy, dx, xorgi, yorgi, dx < 0, bottom);
+ maxy = -ya;
+ }
+ else
+ {
+ righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
+ k, dx, dy, xorgi, yorgi, 0, right);
+
+ xa = -xa;
+ ya = -ya;
+ k = -k;
+ lefty = miPolyBuildEdge (xa, ya,
+ k, dx, dy, xorgi, yorgi, 1, left);
+ if (dx > 0)
+ {
+ ya = -ya;
+ xa = -xa;
+ }
+ xap = xa - projectXoff;
+ yap = ya - projectYoff;
+ topy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, xorgi, xorgi, dx > 0, top);
+ bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
+ -dy, dx, xorgi, xorgi, dx < 0, bottom);
+ maxy = -ya + projectYoff;
+ }
+ finaly = ICEIL(maxy) + yorgi;
+ if (dx < 0)
+ {
+ left->height = bottomy - lefty;
+ right->height = finaly - righty;
+ top->height = righty - topy;
+ }
+ else
+ {
+ right->height = bottomy - righty;
+ left->height = finaly - lefty;
+ top->height = lefty - topy;
+ }
+ bottom->height = finaly - bottomy;
+ miFillPolyHelper (pDrawable, pGC, pixel, spanData, topy,
+ bottom->height + bottomy - topy, lefts, rights, 2, 2);
+ }
+}
+
+static void
+miWideSegment (pDrawable, pGC, pixel, spanData,
+ x1, y1, x2, y2, projectLeft, projectRight, leftFace, rightFace)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ unsigned long pixel;
+ SpanDataPtr spanData;
+ register int x1, y1, x2, y2;
+ Bool projectLeft, projectRight;
+ register LineFacePtr leftFace, rightFace;
+{
+ double l, L, r;
+ double xa, ya;
+ double projectXoff = 0.0, projectYoff = 0.0;
+ double k;
+ double maxy;
+ int x, y;
+ int dx, dy;
+ int finaly;
+ PolyEdgePtr left, right;
+ PolyEdgePtr top, bottom;
+ int lefty, righty, topy, bottomy;
+ int signdx;
+ PolyEdgeRec lefts[2], rights[2];
+ LineFacePtr tface;
+ int lw = pGC->lineWidth;
+
+ /* draw top-to-bottom always */
+ if (y2 < y1 || y2 == y1 && x2 < x1)
+ {
+ x = x1;
+ x1 = x2;
+ x2 = x;
+
+ y = y1;
+ y1 = y2;
+ y2 = y;
+
+ x = projectLeft;
+ projectLeft = projectRight;
+ projectRight = x;
+
+ tface = leftFace;
+ leftFace = rightFace;
+ rightFace = tface;
+ }
+
+ dy = y2 - y1;
+ signdx = 1;
+ dx = x2 - x1;
+ if (dx < 0)
+ signdx = -1;
+
+ leftFace->x = x1;
+ leftFace->y = y1;
+ leftFace->dx = dx;
+ leftFace->dy = dy;
+
+ rightFace->x = x2;
+ rightFace->y = y2;
+ rightFace->dx = -dx;
+ rightFace->dy = -dy;
+
+ if (dy == 0)
+ {
+ rightFace->xa = 0;
+ rightFace->ya = (double) lw / 2.0;
+ rightFace->k = -(double) (lw * dx) / 2.0;
+ leftFace->xa = 0;
+ leftFace->ya = -rightFace->ya;
+ leftFace->k = rightFace->k;
+ x = x1;
+ if (projectLeft)
+ x -= (lw >> 1);
+ y = y1 - (lw >> 1);
+ dx = x2 - x;
+ if (projectRight)
+ dx += ((lw + 1) >> 1);
+ dy = lw;
+ miFillRectPolyHelper (pDrawable, pGC, pixel, spanData,
+ x, y, dx, dy);
+ }
+ else if (dx == 0)
+ {
+ leftFace->xa = (double) lw / 2.0;
+ leftFace->ya = 0;
+ leftFace->k = (double) (lw * dy) / 2.0;
+ rightFace->xa = -leftFace->xa;
+ rightFace->ya = 0;
+ rightFace->k = leftFace->k;
+ y = y1;
+ if (projectLeft)
+ y -= lw >> 1;
+ x = x1 - (lw >> 1);
+ dy = y2 - y;
+ if (projectRight)
+ dy += ((lw + 1) >> 1);
+ dx = lw;
+ miFillRectPolyHelper (pDrawable, pGC, pixel, spanData,
+ x, y, dx, dy);
+ }
+ else
+ {
+ l = ((double) lw) / 2.0;
+ L = hypot ((double) dx, (double) dy);
+
+ if (dx < 0)
+ {
+ right = &rights[1];
+ left = &lefts[0];
+ top = &rights[0];
+ bottom = &lefts[1];
+ }
+ else
+ {
+ right = &rights[0];
+ left = &lefts[1];
+ top = &lefts[0];
+ bottom = &rights[1];
+ }
+ r = l / L;
+
+ /* coord of upper bound at integral y */
+ ya = -r * dx;
+ xa = r * dy;
+
+ if (projectLeft | projectRight)
+ {
+ projectXoff = -ya;
+ projectYoff = xa;
+ }
+
+ /* xa * dy - ya * dx */
+ k = l * L;
+
+ leftFace->xa = xa;
+ leftFace->ya = ya;
+ leftFace->k = k;
+ rightFace->xa = -xa;
+ rightFace->ya = -ya;
+ rightFace->k = k;
+
+ if (projectLeft)
+ righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
+ k, dx, dy, x1, y1, 0, right);
+ else
+ righty = miPolyBuildEdge (xa, ya,
+ k, dx, dy, x1, y1, 0, right);
+
+ /* coord of lower bound at integral y */
+ ya = -ya;
+ xa = -xa;
+
+ /* xa * dy - ya * dx */
+ k = - k;
+
+ if (projectLeft)
+ lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
+ k, dx, dy, x1, y1, 1, left);
+ else
+ lefty = miPolyBuildEdge (xa, ya,
+ k, dx, dy, x1, y1, 1, left);
+
+ /* coord of top face at integral y */
+
+ if (signdx > 0)
+ {
+ ya = -ya;
+ xa = -xa;
+ }
+
+ if (projectLeft)
+ {
+ double xap = xa - projectXoff;
+ double yap = ya - projectYoff;
+ topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
+ -dy, dx, x1, y1, dx > 0, top);
+ }
+ else
+ topy = miPolyBuildEdge (xa, ya, 0.0, -dy, dx, x1, y1, dx > 0, top);
+
+ /* coord of bottom face at integral y */
+
+ if (projectRight)
+ {
+ double xap = xa + projectXoff;
+ double yap = ya + projectYoff;
+ bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
+ -dy, dx, x2, y2, dx < 0, bottom);
+ maxy = -ya + projectYoff;
+ }
+ else
+ {
+ bottomy = miPolyBuildEdge (xa, ya,
+ 0.0, -dy, dx, x2, y2, dx < 0, bottom);
+ maxy = -ya;
+ }
+
+ finaly = ICEIL (maxy) + y2;
+
+ if (dx < 0)
+ {
+ left->height = bottomy - lefty;
+ right->height = finaly - righty;
+ top->height = righty - topy;
+ }
+ else
+ {
+ right->height = bottomy - righty;
+ left->height = finaly - lefty;
+ top->height = lefty - topy;
+ }
+ bottom->height = finaly - bottomy;
+ miFillPolyHelper (pDrawable, pGC, pixel, spanData, topy,
+ bottom->height + bottomy - topy, lefts, rights, 2, 2);
+ }
+}
+
+SpanDataPtr
+miSetupSpanData (pGC, spanData, npt)
+ register GCPtr pGC;
+ SpanDataPtr spanData;
+ int npt;
+{
+ if (npt < 3 && pGC->capStyle != CapRound || miSpansEasyRop(pGC->alu))
+ return (SpanDataPtr) NULL;
+ if (pGC->lineStyle == LineDoubleDash)
+ miInitSpanGroup (&spanData->bgGroup);
+ miInitSpanGroup (&spanData->fgGroup);
+ return spanData;
+}
+
+void
+miCleanupSpanData (pDrawable, pGC, spanData)
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ SpanDataPtr spanData;
+{
+ if (pGC->lineStyle == LineDoubleDash)
+ {
+ XID oldPixel, pixel;
+
+ pixel = pGC->bgPixel;
+ oldPixel = pGC->fgPixel;
+ if (pixel != oldPixel)
+ {
+ DoChangeGC (pGC, GCForeground, &pixel, FALSE);
+ ValidateGC (pDrawable, pGC);
+ }
+ miFillUniqueSpanGroup (pDrawable, pGC, &spanData->bgGroup);
+ miFreeSpanGroup (&spanData->bgGroup);
+ if (pixel != oldPixel)
+ {
+ DoChangeGC (pGC, GCForeground, &oldPixel, FALSE);
+ ValidateGC (pDrawable, pGC);
+ }
+ }
+ miFillUniqueSpanGroup (pDrawable, pGC, &spanData->fgGroup);
+ miFreeSpanGroup (&spanData->fgGroup);
+}
+
+void
+miWideLine (pDrawable, pGC, mode, npt, pPts)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int mode;
+ register int npt;
+ register DDXPointPtr pPts;
+{
+ int x1, y1, x2, y2;
+ SpanDataRec spanDataRec;
+ SpanDataPtr spanData;
+ unsigned long pixel;
+ Bool projectLeft, projectRight;
+ LineFaceRec leftFace, rightFace, prevRightFace;
+ LineFaceRec firstFace;
+ register int first;
+ Bool somethingDrawn = FALSE;
+ Bool selfJoin;
+
+ spanData = miSetupSpanData (pGC, &spanDataRec, npt);
+ pixel = pGC->fgPixel;
+ x2 = pPts->x;
+ y2 = pPts->y;
+ first = TRUE;
+ selfJoin = FALSE;
+ if (npt > 1)
+ {
+ if (mode == CoordModePrevious)
+ {
+ int nptTmp;
+ DDXPointPtr pPtsTmp;
+
+ x1 = x2;
+ y1 = y2;
+ nptTmp = npt;
+ pPtsTmp = pPts + 1;
+ while (--nptTmp)
+ {
+ x1 += pPtsTmp->x;
+ y1 += pPtsTmp->y;
+ ++pPtsTmp;
+ }
+ if (x2 == x1 && y2 == y1)
+ selfJoin = TRUE;
+ }
+ else if (x2 == pPts[npt-1].x && y2 == pPts[npt-1].y)
+ {
+ selfJoin = TRUE;
+ }
+ }
+ projectLeft = pGC->capStyle == CapProjecting && !selfJoin;
+ projectRight = FALSE;
+ while (--npt)
+ {
+ x1 = x2;
+ y1 = y2;
+ ++pPts;
+ x2 = pPts->x;
+ y2 = pPts->y;
+ if (mode == CoordModePrevious)
+ {
+ x2 += x1;
+ y2 += y1;
+ }
+ if (x1 != x2 || y1 != y2)
+ {
+ somethingDrawn = TRUE;
+ if (npt == 1 && pGC->capStyle == CapProjecting && !selfJoin)
+ projectRight = TRUE;
+ miWideSegment (pDrawable, pGC, pixel, spanData, x1, y1, x2, y2,
+ projectLeft, projectRight, &leftFace, &rightFace);
+ if (first)
+ {
+ if (selfJoin)
+ firstFace = leftFace;
+ else if (pGC->capStyle == CapRound)
+ {
+ if (pGC->lineWidth == 1 && !spanData)
+ miLineOnePoint (pDrawable, pGC, pixel, spanData, x1, y1);
+ else
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ &leftFace, (LineFacePtr) NULL,
+ (double)0.0, (double)0.0,
+ TRUE);
+ }
+ }
+ else
+ {
+ miLineJoin (pDrawable, pGC, pixel, spanData, &leftFace,
+ &prevRightFace);
+ }
+ prevRightFace = rightFace;
+ first = FALSE;
+ projectLeft = FALSE;
+ }
+ if (npt == 1 && somethingDrawn)
+ {
+ if (selfJoin)
+ miLineJoin (pDrawable, pGC, pixel, spanData, &firstFace,
+ &rightFace);
+ else if (pGC->capStyle == CapRound)
+ {
+ if (pGC->lineWidth == 1 && !spanData)
+ miLineOnePoint (pDrawable, pGC, pixel, spanData, x2, y2);
+ else
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ (LineFacePtr) NULL, &rightFace,
+ (double)0.0, (double)0.0,
+ TRUE);
+ }
+ }
+ }
+ /* handle crock where all points are coincedent */
+ if (!somethingDrawn)
+ {
+ projectLeft = pGC->capStyle == CapProjecting;
+ miWideSegment (pDrawable, pGC, pixel, spanData,
+ x2, y2, x2, y2, projectLeft, projectLeft,
+ &leftFace, &rightFace);
+ if (pGC->capStyle == CapRound)
+ {
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ &leftFace, (LineFacePtr) NULL,
+ (double)0.0, (double)0.0,
+ TRUE);
+ rightFace.dx = -1; /* sleezy hack to make it work */
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ (LineFacePtr) NULL, &rightFace,
+ (double)0.0, (double)0.0,
+ TRUE);
+ }
+ }
+ if (spanData)
+ miCleanupSpanData (pDrawable, pGC, spanData);
+}
+
+#define V_TOP 0
+#define V_RIGHT 1
+#define V_BOTTOM 2
+#define V_LEFT 3
+
+static void
+miWideDashSegment (pDrawable, pGC, spanData, pDashOffset, pDashIndex,
+ x1, y1, x2, y2, projectLeft, projectRight, leftFace, rightFace)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int *pDashOffset, *pDashIndex;
+ SpanDataPtr spanData;
+ int x1, y1, x2, y2;
+ Bool projectLeft, projectRight;
+ LineFacePtr leftFace, rightFace;
+{
+ int dashIndex, dashRemain;
+ unsigned char *pDash;
+ double L, l;
+ double k;
+ PolyVertexRec vertices[4];
+ PolyVertexRec saveRight, saveBottom;
+ PolySlopeRec slopes[4];
+ PolyEdgeRec left[2], right[2];
+ LineFaceRec lcapFace, rcapFace;
+ int nleft, nright;
+ int h;
+ int y;
+ int dy, dx;
+ unsigned long pixel;
+ double LRemain;
+ double r;
+ double rdx, rdy;
+ double dashDx, dashDy;
+ double saveK = 0.0;
+ Bool first = TRUE;
+ double lcenterx, lcentery, rcenterx = 0.0, rcentery = 0.0;
+ unsigned long fgPixel, bgPixel;
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+ dashIndex = *pDashIndex;
+ pDash = pGC->dash;
+ dashRemain = pDash[dashIndex] - *pDashOffset;
+ fgPixel = pGC->fgPixel;
+ bgPixel = pGC->bgPixel;
+ if (pGC->fillStyle == FillOpaqueStippled ||
+ pGC->fillStyle == FillTiled)
+ {
+ bgPixel = fgPixel;
+ }
+
+ l = ((double) pGC->lineWidth) / 2.0;
+ if (dx == 0)
+ {
+ L = dy;
+ rdx = 0;
+ rdy = l;
+ if (dy < 0)
+ {
+ L = -dy;
+ rdy = -l;
+ }
+ }
+ else if (dy == 0)
+ {
+ L = dx;
+ rdx = l;
+ rdy = 0;
+ if (dx < 0)
+ {
+ L = -dx;
+ rdx = -l;
+ }
+ }
+ else
+ {
+ L = hypot ((double) dx, (double) dy);
+ r = l / L;
+
+ rdx = r * dx;
+ rdy = r * dy;
+ }
+ k = l * L;
+ LRemain = L;
+ /* All position comments are relative to a line with dx and dy > 0,
+ * but the code does not depend on this */
+ /* top */
+ slopes[V_TOP].dx = dx;
+ slopes[V_TOP].dy = dy;
+ slopes[V_TOP].k = k;
+ /* right */
+ slopes[V_RIGHT].dx = -dy;
+ slopes[V_RIGHT].dy = dx;
+ slopes[V_RIGHT].k = 0;
+ /* bottom */
+ slopes[V_BOTTOM].dx = -dx;
+ slopes[V_BOTTOM].dy = -dy;
+ slopes[V_BOTTOM].k = k;
+ /* left */
+ slopes[V_LEFT].dx = dy;
+ slopes[V_LEFT].dy = -dx;
+ slopes[V_LEFT].k = 0;
+
+ /* preload the start coordinates */
+ vertices[V_RIGHT].x = vertices[V_TOP].x = rdy;
+ vertices[V_RIGHT].y = vertices[V_TOP].y = -rdx;
+
+ vertices[V_BOTTOM].x = vertices[V_LEFT].x = -rdy;
+ vertices[V_BOTTOM].y = vertices[V_LEFT].y = rdx;
+
+ if (projectLeft)
+ {
+ vertices[V_TOP].x -= rdx;
+ vertices[V_TOP].y -= rdy;
+
+ vertices[V_LEFT].x -= rdx;
+ vertices[V_LEFT].y -= rdy;
+
+ slopes[V_LEFT].k = rdx * dx + rdy * dy;
+ }
+
+ lcenterx = x1;
+ lcentery = y1;
+
+ if (pGC->capStyle == CapRound)
+ {
+ lcapFace.dx = dx;
+ lcapFace.dy = dy;
+ lcapFace.x = x1;
+ lcapFace.y = y1;
+
+ rcapFace.dx = -dx;
+ rcapFace.dy = -dy;
+ rcapFace.x = x1;
+ rcapFace.y = y1;
+ }
+ while (LRemain > dashRemain)
+ {
+ dashDx = (dashRemain * dx) / L;
+ dashDy = (dashRemain * dy) / L;
+
+ rcenterx = lcenterx + dashDx;
+ rcentery = lcentery + dashDy;
+
+ vertices[V_RIGHT].x += dashDx;
+ vertices[V_RIGHT].y += dashDy;
+
+ vertices[V_BOTTOM].x += dashDx;
+ vertices[V_BOTTOM].y += dashDy;
+
+ slopes[V_RIGHT].k = vertices[V_RIGHT].x * dx + vertices[V_RIGHT].y * dy;
+
+ if (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1))
+ {
+ if (pGC->lineStyle == LineOnOffDash &&
+ pGC->capStyle == CapProjecting)
+ {
+ saveRight = vertices[V_RIGHT];
+ saveBottom = vertices[V_BOTTOM];
+ saveK = slopes[V_RIGHT].k;
+
+ if (!first)
+ {
+ vertices[V_TOP].x -= rdx;
+ vertices[V_TOP].y -= rdy;
+
+ vertices[V_LEFT].x -= rdx;
+ vertices[V_LEFT].y -= rdy;
+
+ slopes[V_LEFT].k = vertices[V_LEFT].x *
+ slopes[V_LEFT].dy -
+ vertices[V_LEFT].y *
+ slopes[V_LEFT].dx;
+ }
+
+ vertices[V_RIGHT].x += rdx;
+ vertices[V_RIGHT].y += rdy;
+
+ vertices[V_BOTTOM].x += rdx;
+ vertices[V_BOTTOM].y += rdy;
+
+ slopes[V_RIGHT].k = vertices[V_RIGHT].x *
+ slopes[V_RIGHT].dy -
+ vertices[V_RIGHT].y *
+ slopes[V_RIGHT].dx;
+ }
+ y = miPolyBuildPoly (vertices, slopes, 4, x1, y1,
+ left, right, &nleft, &nright, &h);
+ pixel = (dashIndex & 1) ? bgPixel : fgPixel;
+ miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, h, left, right, nleft, nright);
+
+ if (pGC->lineStyle == LineOnOffDash)
+ {
+ switch (pGC->capStyle)
+ {
+ case CapProjecting:
+ vertices[V_BOTTOM] = saveBottom;
+ vertices[V_RIGHT] = saveRight;
+ slopes[V_RIGHT].k = saveK;
+ break;
+ case CapRound:
+ if (!first)
+ {
+ if (dx < 0)
+ {
+ lcapFace.xa = -vertices[V_LEFT].x;
+ lcapFace.ya = -vertices[V_LEFT].y;
+ lcapFace.k = slopes[V_LEFT].k;
+ }
+ else
+ {
+ lcapFace.xa = vertices[V_TOP].x;
+ lcapFace.ya = vertices[V_TOP].y;
+ lcapFace.k = -slopes[V_LEFT].k;
+ }
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ &lcapFace, (LineFacePtr) NULL,
+ lcenterx, lcentery, FALSE);
+ }
+ if (dx < 0)
+ {
+ rcapFace.xa = vertices[V_BOTTOM].x;
+ rcapFace.ya = vertices[V_BOTTOM].y;
+ rcapFace.k = slopes[V_RIGHT].k;
+ }
+ else
+ {
+ rcapFace.xa = -vertices[V_RIGHT].x;
+ rcapFace.ya = -vertices[V_RIGHT].y;
+ rcapFace.k = -slopes[V_RIGHT].k;
+ }
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ (LineFacePtr) NULL, &rcapFace,
+ rcenterx, rcentery, FALSE);
+ break;
+ }
+ }
+ }
+ LRemain -= dashRemain;
+ ++dashIndex;
+ if (dashIndex == pGC->numInDashList)
+ dashIndex = 0;
+ dashRemain = pDash[dashIndex];
+
+ lcenterx = rcenterx;
+ lcentery = rcentery;
+
+ vertices[V_TOP] = vertices[V_RIGHT];
+ vertices[V_LEFT] = vertices[V_BOTTOM];
+ slopes[V_LEFT].k = -slopes[V_RIGHT].k;
+ first = FALSE;
+ }
+
+ if (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1))
+ {
+ vertices[V_TOP].x -= dx;
+ vertices[V_TOP].y -= dy;
+
+ vertices[V_LEFT].x -= dx;
+ vertices[V_LEFT].y -= dy;
+
+ vertices[V_RIGHT].x = rdy;
+ vertices[V_RIGHT].y = -rdx;
+
+ vertices[V_BOTTOM].x = -rdy;
+ vertices[V_BOTTOM].y = rdx;
+
+
+ if (projectRight)
+ {
+ vertices[V_RIGHT].x += rdx;
+ vertices[V_RIGHT].y += rdy;
+
+ vertices[V_BOTTOM].x += rdx;
+ vertices[V_BOTTOM].y += rdy;
+ slopes[V_RIGHT].k = vertices[V_RIGHT].x *
+ slopes[V_RIGHT].dy -
+ vertices[V_RIGHT].y *
+ slopes[V_RIGHT].dx;
+ }
+ else
+ slopes[V_RIGHT].k = 0;
+
+ if (!first && pGC->lineStyle == LineOnOffDash &&
+ pGC->capStyle == CapProjecting)
+ {
+ vertices[V_TOP].x -= rdx;
+ vertices[V_TOP].y -= rdy;
+
+ vertices[V_LEFT].x -= rdx;
+ vertices[V_LEFT].y -= rdy;
+ slopes[V_LEFT].k = vertices[V_LEFT].x *
+ slopes[V_LEFT].dy -
+ vertices[V_LEFT].y *
+ slopes[V_LEFT].dx;
+ }
+ else
+ slopes[V_LEFT].k += dx * dx + dy * dy;
+
+
+ y = miPolyBuildPoly (vertices, slopes, 4, x2, y2,
+ left, right, &nleft, &nright, &h);
+
+ pixel = (dashIndex & 1) ? pGC->bgPixel : pGC->fgPixel;
+ miFillPolyHelper (pDrawable, pGC, pixel, spanData, y, h, left, right, nleft, nright);
+ if (!first && pGC->lineStyle == LineOnOffDash &&
+ pGC->capStyle == CapRound)
+ {
+ lcapFace.x = x2;
+ lcapFace.y = y2;
+ if (dx < 0)
+ {
+ lcapFace.xa = -vertices[V_LEFT].x;
+ lcapFace.ya = -vertices[V_LEFT].y;
+ lcapFace.k = slopes[V_LEFT].k;
+ }
+ else
+ {
+ lcapFace.xa = vertices[V_TOP].x;
+ lcapFace.ya = vertices[V_TOP].y;
+ lcapFace.k = -slopes[V_LEFT].k;
+ }
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ &lcapFace, (LineFacePtr) NULL,
+ rcenterx, rcentery, FALSE);
+ }
+ }
+ dashRemain = ((double) dashRemain) - LRemain;
+ if (dashRemain == 0)
+ {
+ dashIndex++;
+ if (dashIndex == pGC->numInDashList)
+ dashIndex = 0;
+ dashRemain = pDash[dashIndex];
+ }
+
+ leftFace->x = x1;
+ leftFace->y = y1;
+ leftFace->dx = dx;
+ leftFace->dy = dy;
+ leftFace->xa = rdy;
+ leftFace->ya = -rdx;
+ leftFace->k = k;
+
+ rightFace->x = x2;
+ rightFace->y = y2;
+ rightFace->dx = -dx;
+ rightFace->dy = -dy;
+ rightFace->xa = -rdy;
+ rightFace->ya = rdx;
+ rightFace->k = k;
+
+ *pDashIndex = dashIndex;
+ *pDashOffset = pDash[dashIndex] - dashRemain;
+}
+
+void
+miWideDash (pDrawable, pGC, mode, npt, pPts)
+ DrawablePtr pDrawable;
+ register GCPtr pGC;
+ int mode;
+ register int npt;
+ register DDXPointPtr pPts;
+{
+ int x1, y1, x2, y2;
+ unsigned long pixel;
+ Bool projectLeft, projectRight;
+ LineFaceRec leftFace, rightFace, prevRightFace;
+ LineFaceRec firstFace;
+ int first;
+ int dashIndex, dashOffset;
+ register int prevDashIndex;
+ SpanDataRec spanDataRec;
+ SpanDataPtr spanData;
+ Bool somethingDrawn = FALSE;
+ Bool selfJoin;
+ Bool endIsFg = FALSE, startIsFg = FALSE;
+ Bool firstIsFg = FALSE, prevIsFg = FALSE;
+
+ /* XXX backward compatibility */
+ if (pGC->lineWidth == 0)
+ {
+ miZeroDashLine (pDrawable, pGC, mode, npt, pPts);
+ return;
+ }
+ if (pGC->lineStyle == LineDoubleDash &&
+ (pGC->fillStyle == FillOpaqueStippled || pGC->fillStyle == FillTiled))
+ {
+ miWideLine (pDrawable, pGC, mode, npt, pPts);
+ return;
+ }
+ if (npt == 0)
+ return;
+ spanData = miSetupSpanData (pGC, &spanDataRec, npt);
+ x2 = pPts->x;
+ y2 = pPts->y;
+ first = TRUE;
+ selfJoin = FALSE;
+ if (mode == CoordModePrevious)
+ {
+ int nptTmp;
+ DDXPointPtr pPtsTmp;
+
+ x1 = x2;
+ y1 = y2;
+ nptTmp = npt;
+ pPtsTmp = pPts + 1;
+ while (--nptTmp)
+ {
+ x1 += pPtsTmp->x;
+ y1 += pPtsTmp->y;
+ ++pPtsTmp;
+ }
+ if (x2 == x1 && y2 == y1)
+ selfJoin = TRUE;
+ }
+ else if (x2 == pPts[npt-1].x && y2 == pPts[npt-1].y)
+ {
+ selfJoin = TRUE;
+ }
+ projectLeft = pGC->capStyle == CapProjecting && !selfJoin;
+ projectRight = FALSE;
+ dashIndex = 0;
+ dashOffset = 0;
+ miStepDash ((int)pGC->dashOffset, &dashIndex,
+ pGC->dash, (int)pGC->numInDashList, &dashOffset);
+ while (--npt)
+ {
+ x1 = x2;
+ y1 = y2;
+ ++pPts;
+ x2 = pPts->x;
+ y2 = pPts->y;
+ if (mode == CoordModePrevious)
+ {
+ x2 += x1;
+ y2 += y1;
+ }
+ if (x1 != x2 || y1 != y2)
+ {
+ somethingDrawn = TRUE;
+ if (npt == 1 && pGC->capStyle == CapProjecting &&
+ (!selfJoin || !firstIsFg))
+ projectRight = TRUE;
+ prevDashIndex = dashIndex;
+ miWideDashSegment (pDrawable, pGC, spanData, &dashOffset, &dashIndex,
+ x1, y1, x2, y2,
+ projectLeft, projectRight, &leftFace, &rightFace);
+ startIsFg = !(prevDashIndex & 1);
+ endIsFg = (dashIndex & 1) ^ (dashOffset != 0);
+ if (pGC->lineStyle == LineDoubleDash || startIsFg)
+ {
+ pixel = startIsFg ? pGC->fgPixel : pGC->bgPixel;
+ if (first || (pGC->lineStyle == LineOnOffDash && !prevIsFg))
+ {
+ if (first && selfJoin)
+ {
+ firstFace = leftFace;
+ firstIsFg = startIsFg;
+ }
+ else if (pGC->capStyle == CapRound)
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ &leftFace, (LineFacePtr) NULL,
+ (double)0.0, (double)0.0, TRUE);
+ }
+ else
+ {
+ miLineJoin (pDrawable, pGC, pixel, spanData, &leftFace,
+ &prevRightFace);
+ }
+ }
+ prevRightFace = rightFace;
+ prevIsFg = endIsFg;
+ first = FALSE;
+ projectLeft = FALSE;
+ }
+ if (npt == 1 && somethingDrawn)
+ {
+ if (pGC->lineStyle == LineDoubleDash || endIsFg)
+ {
+ pixel = endIsFg ? pGC->fgPixel : pGC->bgPixel;
+ if (selfJoin && (pGC->lineStyle == LineDoubleDash || firstIsFg))
+ {
+ miLineJoin (pDrawable, pGC, pixel, spanData, &firstFace,
+ &rightFace);
+ }
+ else
+ {
+ if (pGC->capStyle == CapRound)
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ (LineFacePtr) NULL, &rightFace,
+ (double)0.0, (double)0.0, TRUE);
+ }
+ }
+ else
+ {
+ /* glue a cap to the start of the line if
+ * we're OnOffDash and ended on odd dash
+ */
+ if (selfJoin && firstIsFg)
+ {
+ pixel = pGC->fgPixel;
+ if (pGC->capStyle == CapProjecting)
+ miLineProjectingCap (pDrawable, pGC, pixel, spanData,
+ &firstFace, TRUE,
+ (double)0.0, (double)0.0, TRUE);
+ else if (pGC->capStyle == CapRound)
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ &firstFace, (LineFacePtr) NULL,
+ (double)0.0, (double)0.0, TRUE);
+ }
+ }
+ }
+ }
+ /* handle crock where all points are coincident */
+ if (!somethingDrawn && (pGC->lineStyle == LineDoubleDash || !(dashIndex & 1)))
+ {
+ /* not the same as endIsFg computation above */
+ pixel = (dashIndex & 1) ? pGC->bgPixel : pGC->fgPixel;
+ switch (pGC->capStyle) {
+ case CapRound:
+ miLineArc (pDrawable, pGC, pixel, spanData,
+ (LineFacePtr) NULL, (LineFacePtr) NULL,
+ (double)x2, (double)y2,
+ FALSE);
+ break;
+ case CapProjecting:
+ x1 = pGC->lineWidth;
+ miFillRectPolyHelper (pDrawable, pGC, pixel, spanData,
+ x2 - (x1 >> 1), y2 - (x1 >> 1), x1, x1);
+ break;
+ }
+ }
+ if (spanData)
+ miCleanupSpanData (pDrawable, pGC, spanData);
+}
+
+/* these are stubs to allow old ddx ValidateGCs to work without change */
+
+void
+miMiter()
+{
+}
+
+void
+miNotMiter()
+{
+}
diff --git a/xc/programs/Xserver/mi/miwideline.h b/xc/programs/Xserver/mi/miwideline.h
new file mode 100644
index 000000000..dd66eed08
--- /dev/null
+++ b/xc/programs/Xserver/mi/miwideline.h
@@ -0,0 +1,249 @@
+/* $TOG: miwideline.h /main/12 1998/02/09 14:49:26 kaleb $ */
+/*
+
+Copyright 1988, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+/* $XFree86: xc/programs/Xserver/mi/miwideline.h,v 1.7 1998/10/04 09:39:35 dawes Exp $ */
+
+/* Author: Keith Packard, MIT X Consortium */
+
+#include "mispans.h"
+
+/*
+ * interface data to span-merging polygon filler
+ */
+
+typedef struct _SpanData {
+ SpanGroup fgGroup, bgGroup;
+} SpanDataRec, *SpanDataPtr;
+
+#define AppendSpanGroup(pGC, pixel, spanPtr, spanData) { \
+ SpanGroup *group, *othergroup = NULL; \
+ if (pixel == pGC->fgPixel) \
+ { \
+ group = &spanData->fgGroup; \
+ if (pGC->lineStyle == LineDoubleDash) \
+ othergroup = &spanData->bgGroup; \
+ } \
+ else \
+ { \
+ group = &spanData->bgGroup; \
+ othergroup = &spanData->fgGroup; \
+ } \
+ miAppendSpans (group, othergroup, spanPtr); \
+}
+
+/*
+ * Polygon edge description for integer wide-line routines
+ */
+
+typedef struct _PolyEdge {
+ int height; /* number of scanlines to process */
+ int x; /* starting x coordinate */
+ int stepx; /* fixed integral dx */
+ int signdx; /* variable dx sign */
+ int e; /* initial error term */
+ int dy;
+ int dx;
+} PolyEdgeRec, *PolyEdgePtr;
+
+#define SQSECANT 108.856472512142 /* 1/sin^2(11/2) - miter limit constant */
+
+/*
+ * types for general polygon routines
+ */
+
+typedef struct _PolyVertex {
+ double x, y;
+} PolyVertexRec, *PolyVertexPtr;
+
+typedef struct _PolySlope {
+ int dx, dy;
+ double k; /* x0 * dy - y0 * dx */
+} PolySlopeRec, *PolySlopePtr;
+
+/*
+ * Line face description for caps/joins
+ */
+
+typedef struct _LineFace {
+ double xa, ya;
+ int dx, dy;
+ int x, y;
+ double k;
+} LineFaceRec, *LineFacePtr;
+
+/*
+ * macros for polygon fillers
+ */
+
+#define MIPOLYRELOADLEFT if (!left_height && left_count) { \
+ left_height = left->height; \
+ left_x = left->x; \
+ left_stepx = left->stepx; \
+ left_signdx = left->signdx; \
+ left_e = left->e; \
+ left_dy = left->dy; \
+ left_dx = left->dx; \
+ --left_count; \
+ ++left; \
+ }
+
+#define MIPOLYRELOADRIGHT if (!right_height && right_count) { \
+ right_height = right->height; \
+ right_x = right->x; \
+ right_stepx = right->stepx; \
+ right_signdx = right->signdx; \
+ right_e = right->e; \
+ right_dy = right->dy; \
+ right_dx = right->dx; \
+ --right_count; \
+ ++right; \
+ }
+
+#define MIPOLYSTEPLEFT left_x += left_stepx; \
+ left_e += left_dx; \
+ if (left_e > 0) \
+ { \
+ left_x += left_signdx; \
+ left_e -= left_dy; \
+ }
+
+#define MIPOLYSTEPRIGHT right_x += right_stepx; \
+ right_e += right_dx; \
+ if (right_e > 0) \
+ { \
+ right_x += right_signdx; \
+ right_e -= right_dy; \
+ }
+
+#define MILINESETPIXEL(pDrawable, pGC, pixel, oldPixel) { \
+ oldPixel = pGC->fgPixel; \
+ if (pixel != oldPixel) { \
+ DoChangeGC (pGC, GCForeground, (XID *) &pixel, FALSE); \
+ ValidateGC (pDrawable, pGC); \
+ } \
+}
+#define MILINERESETPIXEL(pDrawable, pGC, pixel, oldPixel) { \
+ if (pixel != oldPixel) { \
+ DoChangeGC (pGC, GCForeground, (XID *) &oldPixel, FALSE); \
+ ValidateGC (pDrawable, pGC); \
+ } \
+}
+
+#ifdef NOINLINEICEIL
+#define ICEIL(x) ((int)ceil(x))
+#else
+#ifdef __GNUC__
+static __inline int ICEIL(x)
+ double x;
+{
+ int _cTmp = x;
+ return ((x == _cTmp) || (x < 0.0)) ? _cTmp : _cTmp+1;
+}
+#else
+#define ICEIL(x) ((((x) == (_cTmp = (x))) || ((x) < 0.0)) ? _cTmp : _cTmp+1)
+#define ICEILTEMPDECL static int _cTmp;
+#endif
+#endif
+
+extern void miFillPolyHelper(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ unsigned long /*pixel*/,
+ SpanDataPtr /*spanData*/,
+ int /*y*/,
+ int /*overall_height*/,
+ PolyEdgePtr /*left*/,
+ PolyEdgePtr /*right*/,
+ int /*left_count*/,
+ int /*right_count*/
+#endif
+);
+extern int miRoundJoinFace(
+#if NeedFunctionPrototypes
+ LineFacePtr /*face*/,
+ PolyEdgePtr /*edge*/,
+ Bool * /*leftEdge*/
+#endif
+);
+
+extern void miRoundJoinClip(
+#if NeedFunctionPrototypes
+ LineFacePtr /*pLeft*/,
+ LineFacePtr /*pRight*/,
+ PolyEdgePtr /*edge1*/,
+ PolyEdgePtr /*edge2*/,
+ int * /*y1*/,
+ int * /*y2*/,
+ Bool * /*left1*/,
+ Bool * /*left2*/
+#endif
+);
+
+extern int miRoundCapClip(
+#if NeedFunctionPrototypes
+ LineFacePtr /*face*/,
+ Bool /*isInt*/,
+ PolyEdgePtr /*edge*/,
+ Bool * /*leftEdge*/
+#endif
+);
+
+extern void miLineProjectingCap(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ unsigned long /*pixel*/,
+ SpanDataPtr /*spanData*/,
+ LineFacePtr /*face*/,
+ Bool /*isLeft*/,
+ double /*xorg*/,
+ double /*yorg*/,
+ Bool /*isInt*/
+#endif
+);
+
+extern SpanDataPtr miSetupSpanData(
+#if NeedFunctionPrototypes
+ GCPtr /*pGC*/,
+ SpanDataPtr /*spanData*/,
+ int /*npt*/
+#endif
+);
+
+extern void miCleanupSpanData(
+#if NeedFunctionPrototypes
+ DrawablePtr /*pDrawable*/,
+ GCPtr /*pGC*/,
+ SpanDataPtr /*spanData*/
+#endif
+);
+
+extern int miPolyBuildEdge(double x0, double y0, double k, int dx, int dy,
+ int xi, int yi, int left, PolyEdgePtr edge);
+extern int miPolyBuildPoly(PolyVertexPtr vertices, PolySlopePtr slopes,
+ int count, int xi, int yi, PolyEdgePtr left,
+ PolyEdgePtr right, int *pnleft, int *pnright,
+ int *h);
+
diff --git a/xc/programs/Xserver/mi/miwindow.c b/xc/programs/Xserver/mi/miwindow.c
new file mode 100644
index 000000000..954deda0f
--- /dev/null
+++ b/xc/programs/Xserver/mi/miwindow.c
@@ -0,0 +1,1157 @@
+/* $XFree86: xc/programs/Xserver/mi/miwindow.c,v 1.2 1999/01/03 08:06:41 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: miwindow.c /main/23 1998/02/09 14:49:30 kaleb $ */
+#include "X.h"
+#include "miscstruct.h"
+#include "region.h"
+#include "mi.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "mivalidate.h"
+
+void
+miClearToBackground(pWin, x, y, w, h, generateExposures)
+ WindowPtr pWin;
+ int x,y;
+ int w,h;
+ Bool generateExposures;
+{
+ BoxRec box;
+ RegionRec reg;
+ RegionPtr pBSReg = NullRegion;
+ ScreenPtr pScreen;
+ BoxPtr extents;
+ int x1, y1, x2, y2;
+
+ /* compute everything using ints to avoid overflow */
+
+ x1 = pWin->drawable.x + x;
+ y1 = pWin->drawable.y + y;
+ if (w)
+ x2 = x1 + (int) w;
+ else
+ x2 = x1 + (int) pWin->drawable.width - (int) x;
+ if (h)
+ y2 = y1 + h;
+ else
+ y2 = y1 + (int) pWin->drawable.height - (int) y;
+
+ extents = &pWin->clipList.extents;
+
+ /* clip the resulting rectangle to the window clipList extents. This
+ * makes sure that the result will fit in a box, given that the
+ * screen is < 32768 on a side.
+ */
+
+ if (x1 < extents->x1)
+ x1 = extents->x1;
+ if (x2 > extents->x2)
+ x2 = extents->x2;
+ if (y1 < extents->y1)
+ y1 = extents->y1;
+ if (y2 > extents->y2)
+ y2 = extents->y2;
+
+ if (x2 <= x1 || y2 <= y1)
+ {
+ x2 = x1 = 0;
+ y2 = y1 = 0;
+ }
+
+ box.x1 = x1;
+ box.x2 = x2;
+ box.y1 = y1;
+ box.y2 = y2;
+
+ pScreen = pWin->drawable.pScreen;
+ REGION_INIT(pScreen, &reg, &box, 1);
+ if (pWin->backStorage)
+ {
+ /*
+ * If the window has backing-store on, call through the
+ * ClearToBackground vector to handle the special semantics
+ * (i.e. things backing store is to be cleared out and
+ * an Expose event is to be generated for those areas in backing
+ * store if generateExposures is TRUE).
+ */
+ pBSReg = (* pScreen->ClearBackingStore)(pWin, x, y, w, h,
+ generateExposures);
+ }
+
+ REGION_INTERSECT(pScreen, &reg, &reg, &pWin->clipList);
+ if (generateExposures)
+ (*pScreen->WindowExposures)(pWin, &reg, pBSReg);
+ else if (pWin->backgroundState != None)
+ (*pScreen->PaintWindowBackground)(pWin, &reg, PW_BACKGROUND);
+ REGION_UNINIT(pScreen, &reg);
+ if (pBSReg)
+ REGION_DESTROY(pScreen, pBSReg);
+}
+
+/*
+ * For SaveUnders using backing-store. The idea is that when a window is mapped
+ * with saveUnder set TRUE, any windows it obscures will have its backing
+ * store turned on setting the DIXsaveUnder bit,
+ * The backing-store code must be written to allow for this
+ */
+
+/*-
+ *-----------------------------------------------------------------------
+ * miCheckSubSaveUnder --
+ * Check all the inferiors of a window for coverage by saveUnder
+ * windows. Called from ChangeSaveUnder and CheckSaveUnder.
+ * This code is very inefficient.
+ *
+ * Results:
+ * TRUE if any windows need to have backing-store removed.
+ *
+ * Side Effects:
+ * Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+static Bool
+miCheckSubSaveUnder(pParent, pFirst, pRegion)
+ register WindowPtr pParent; /* Parent to check */
+ WindowPtr pFirst; /* first reconfigured window */
+ RegionPtr pRegion; /* Initial area obscured by saveUnder */
+{
+ register WindowPtr pChild; /* Current child */
+ register ScreenPtr pScreen; /* Screen to use */
+ RegionRec SubRegion; /* Area of children obscured */
+ Bool res = FALSE; /* result */
+ Bool subInited=FALSE;/* SubRegion initialized */
+
+ pScreen = pParent->drawable.pScreen;
+ if ( (pChild = pParent->firstChild) )
+ {
+ /*
+ * build region above first changed window
+ */
+
+ for (; pChild != pFirst; pChild = pChild->nextSib)
+ if (pChild->viewable && pChild->saveUnder)
+ REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+
+ /*
+ * check region below and including first changed window
+ */
+
+ for (; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->viewable)
+ {
+ /*
+ * don't save under nephew/niece windows;
+ * use a separate region
+ */
+
+ if (pChild->firstChild)
+ {
+ if (!subInited)
+ {
+ REGION_INIT(pScreen, &SubRegion, NullBox, 0);
+ subInited = TRUE;
+ }
+ REGION_COPY(pScreen, &SubRegion, pRegion);
+ res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+ &SubRegion);
+ }
+ else
+ {
+ res |= miCheckSubSaveUnder(pChild, pChild->firstChild,
+ pRegion);
+ }
+
+ if (pChild->saveUnder)
+ REGION_UNION(pScreen, pRegion, pRegion, &pChild->borderSize);
+ }
+ }
+
+ if (subInited)
+ REGION_UNINIT(pScreen, &SubRegion);
+ }
+
+ /*
+ * Check the state of this window. DIX save unders are
+ * enabled for viewable windows with some client expressing
+ * exposure interest and which intersect the save under region
+ */
+
+ if (pParent->viewable &&
+ ((pParent->eventMask | wOtherEventMasks(pParent)) & ExposureMask) &&
+ REGION_NOTEMPTY(pScreen, &pParent->borderSize) &&
+ RECT_IN_REGION(pScreen, pRegion, REGION_EXTENTS(pScreen,
+ &pParent->borderSize)) != rgnOUT)
+ {
+ if (!pParent->DIXsaveUnder)
+ {
+ pParent->DIXsaveUnder = TRUE;
+ (*pScreen->ChangeWindowAttributes) (pParent, CWBackingStore);
+ }
+ }
+ else
+ {
+ if (pParent->DIXsaveUnder)
+ {
+ res = TRUE;
+ pParent->DIXsaveUnder = FALSE;
+ }
+ }
+ return res;
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miChangeSaveUnder --
+ * Change the save-under state of a tree of windows. Called when
+ * a window with saveUnder TRUE is mapped/unmapped/reconfigured.
+ *
+ * Results:
+ * TRUE if any windows need to have backing-store removed (which
+ * means that PostChangeSaveUnder needs to be called later to
+ * finish the job).
+ *
+ * Side Effects:
+ * Windows may have backing-store turned on or off.
+ *
+ *-----------------------------------------------------------------------
+ */
+Bool
+miChangeSaveUnder(pWin, first)
+ register WindowPtr pWin;
+ WindowPtr first; /* First window to check.
+ * Used when pWin was restacked */
+{
+ RegionRec rgn; /* Area obscured by saveUnder windows */
+ register ScreenPtr pScreen;
+ Bool res;
+
+ if (!deltaSaveUndersViewable && !numSaveUndersViewable)
+ return FALSE;
+ numSaveUndersViewable += deltaSaveUndersViewable;
+ deltaSaveUndersViewable = 0;
+ pScreen = pWin->drawable.pScreen;
+ REGION_INIT(pScreen, &rgn, NullBox, 1);
+ res = miCheckSubSaveUnder (pWin->parent,
+ pWin->saveUnder ? first : pWin->nextSib,
+ &rgn);
+ REGION_UNINIT(pScreen, &rgn);
+ return res;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miPostChangeSaveUnder --
+ * Actually turn backing-store off for those windows that no longer
+ * need to have it on.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Backing-store and SAVE_UNDER_CHANGE_BIT are turned off for those
+ * windows affected.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+miPostChangeSaveUnder(pWin, pFirst)
+ WindowPtr pWin;
+ WindowPtr pFirst;
+{
+ register WindowPtr pParent, pChild;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+
+ if (!(pParent = pWin->parent))
+ return;
+ ChangeWindowAttributes = pParent->drawable.pScreen->ChangeWindowAttributes;
+ if (!pParent->DIXsaveUnder &&
+ (pParent->backingStore == NotUseful) && pParent->backStorage)
+ (*ChangeWindowAttributes)(pParent, CWBackingStore);
+ if (!(pChild = pFirst))
+ return;
+ while (1)
+ {
+ if (!pChild->DIXsaveUnder &&
+ (pChild->backingStore == NotUseful) && pChild->backStorage)
+ (*ChangeWindowAttributes)(pChild, CWBackingStore);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib)
+ {
+ pChild = pChild->parent;
+ if (pChild == pParent)
+ return;
+ }
+ pChild = pChild->nextSib;
+ }
+}
+
+void
+miMarkWindow(pWin)
+ register WindowPtr pWin;
+{
+ register ValidatePtr val;
+
+ if (pWin->valdata)
+ return;
+ val = (ValidatePtr)xnfalloc(sizeof(ValidateRec));
+ val->before.oldAbsCorner.x = pWin->drawable.x;
+ val->before.oldAbsCorner.y = pWin->drawable.y;
+ val->before.borderVisible = NullRegion;
+ val->before.resized = FALSE;
+ pWin->valdata = val;
+}
+
+Bool
+miMarkOverlappedWindows(pWin, pFirst, ppLayerWin)
+ WindowPtr pWin;
+ WindowPtr pFirst;
+ WindowPtr *ppLayerWin;
+{
+ register BoxPtr box;
+ register WindowPtr pChild, pLast;
+ Bool anyMarked = FALSE;
+ void (* MarkWindow)() = pWin->drawable.pScreen->MarkWindow;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ /* single layered systems are easy */
+ if (ppLayerWin) *ppLayerWin = pWin;
+
+ if (pWin == pFirst)
+ {
+ /* Blindly mark pWin and all of its inferiors. This is a slight
+ * overkill if there are mapped windows that outside pWin's border,
+ * but it's better than wasting time on RectIn checks.
+ */
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->viewable)
+ {
+ (* MarkWindow)(pChild);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+ anyMarked = TRUE;
+ pFirst = pFirst->nextSib;
+ }
+ if ( (pChild = pFirst) )
+ {
+ box = REGION_EXTENTS(pChild->drawable.pScreen, &pWin->borderSize);
+ pLast = pChild->parent->lastChild;
+ while (1)
+ {
+ if (pChild->viewable && RECT_IN_REGION(pScreen, &pChild->borderSize,
+ box))
+ {
+ (* MarkWindow)(pChild);
+ anyMarked = TRUE;
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pLast))
+ pChild = pChild->parent;
+ if (pChild == pLast)
+ break;
+ pChild = pChild->nextSib;
+ }
+ }
+ if (anyMarked)
+ (* MarkWindow)(pWin->parent);
+ return anyMarked;
+}
+
+/*****
+ * miHandleValidateExposures(pWin)
+ * starting at pWin, draw background in any windows that have exposure
+ * regions, translate the regions, restore any backing store,
+ * and then send any regions still exposed to the client
+ *****/
+void
+miHandleValidateExposures(pWin)
+ WindowPtr pWin;
+{
+ register WindowPtr pChild;
+ register ValidatePtr val;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ void (* WindowExposures)();
+
+ pChild = pWin;
+ WindowExposures = pChild->drawable.pScreen->WindowExposures;
+ while (1)
+ {
+ if ( (val = pChild->valdata) )
+ {
+ if (REGION_NOTEMPTY(pScreen, &val->after.borderExposed))
+ (*pChild->drawable.pScreen->PaintWindowBorder)(pChild,
+ &val->after.borderExposed,
+ PW_BORDER);
+ REGION_UNINIT(pScreen, &val->after.borderExposed);
+ (*WindowExposures)(pChild, &val->after.exposed, NullRegion);
+ REGION_UNINIT(pScreen, &val->after.exposed);
+ xfree(val);
+ pChild->valdata = (ValidatePtr)NULL;
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
+
+void
+miMoveWindow(pWin, x, y, pNextSib, kind)
+ register WindowPtr pWin;
+ int x,y;
+ WindowPtr pNextSib;
+ VTKind kind;
+{
+ WindowPtr pParent;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ short bw;
+ RegionPtr oldRegion;
+ DDXPointRec oldpt;
+ Bool anyMarked;
+ register ScreenPtr pScreen;
+ WindowPtr windowToValidate;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ /* if this is a root window, can't be moved */
+ if (!(pParent = pWin->parent))
+ return ;
+ pScreen = pWin->drawable.pScreen;
+ bw = wBorderWidth (pWin);
+
+ oldpt.x = pWin->drawable.x;
+ oldpt.y = pWin->drawable.y;
+ if (WasViewable)
+ {
+ oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, oldRegion, &pWin->borderClip);
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+ }
+ pWin->origin.x = x + (int)bw;
+ pWin->origin.y = y + (int)bw;
+ x = pWin->drawable.x = pParent->drawable.x + x + (int)bw;
+ y = pWin->drawable.y = pParent->drawable.y + y + (int)bw;
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ (*pScreen->PositionWindow)(pWin, x, y);
+
+ windowToValidate = MoveWindowInStack(pWin, pNextSib);
+
+ ResizeChildrenWinSize(pWin, x - oldpt.x, y - oldpt.y, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pLayerWin == pWin)
+ anyMarked |= (*pScreen->MarkOverlappedWindows)
+ (pWin, windowToValidate, (WindowPtr *)NULL);
+ else
+ anyMarked |= (*pScreen->MarkOverlappedWindows)
+ (pWin, pLayerWin, (WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, windowToValidate);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, kind);
+ (* pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, oldRegion);
+ REGION_DESTROY(pScreen, oldRegion);
+ /* XXX need to retile border if ParentRelative origin */
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, windowToValidate);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, kind);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+
+/*
+ * pValid is a region of the screen which has been
+ * successfully copied -- recomputed exposed regions for affected windows
+ */
+
+static int
+miRecomputeExposures (pWin, value)
+ register WindowPtr pWin;
+ pointer value; /* must conform to VisitWindowProcPtr */
+{
+ register ScreenPtr pScreen;
+ RegionPtr pValid = (RegionPtr)value;
+
+ if (pWin->valdata)
+ {
+ pScreen = pWin->drawable.pScreen;
+ /*
+ * compute exposed regions of this window
+ */
+ REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+ &pWin->clipList, pValid);
+ /*
+ * compute exposed regions of the border
+ */
+ REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+ &pWin->borderClip, &pWin->winSize);
+ REGION_SUBTRACT(pScreen, &pWin->valdata->after.borderExposed,
+ &pWin->valdata->after.borderExposed, pValid);
+ return WT_WALKCHILDREN;
+ }
+ return WT_NOMATCH;
+}
+
+void
+miSlideAndSizeWindow(pWin, x, y, w, h, pSib)
+ register WindowPtr pWin;
+ int x,y;
+ unsigned int w, h;
+ WindowPtr pSib;
+{
+ WindowPtr pParent;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ unsigned short width = pWin->drawable.width,
+ height = pWin->drawable.height;
+ short oldx = pWin->drawable.x,
+ oldy = pWin->drawable.y;
+ int bw = wBorderWidth (pWin);
+ short dw, dh;
+ DDXPointRec oldpt;
+ RegionPtr oldRegion;
+ Bool anyMarked;
+ register ScreenPtr pScreen;
+ WindowPtr pFirstChange;
+ register WindowPtr pChild;
+ RegionPtr gravitate[StaticGravity + 1];
+ register unsigned g;
+ int nx, ny; /* destination x,y */
+ int newx, newy; /* new inner window position */
+ RegionPtr pRegion;
+ RegionPtr destClip; /* portions of destination already written */
+ RegionPtr oldWinClip; /* old clip list for window */
+ RegionPtr borderVisible = NullRegion; /* visible area of the border */
+ RegionPtr bsExposed = NullRegion; /* backing store exposures */
+ Bool shrunk = FALSE; /* shrunk in an inner dimension */
+ Bool moved = FALSE; /* window position changed */
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ /* if this is a root window, can't be resized */
+ if (!(pParent = pWin->parent))
+ return ;
+
+ pScreen = pWin->drawable.pScreen;
+ newx = pParent->drawable.x + x + bw;
+ newy = pParent->drawable.y + y + bw;
+ if (WasViewable)
+ {
+ anyMarked = FALSE;
+ /*
+ * save the visible region of the window
+ */
+ oldRegion = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, oldRegion, &pWin->winSize);
+
+ /*
+ * categorize child windows into regions to be moved
+ */
+ for (g = 0; g <= StaticGravity; g++)
+ gravitate[g] = (RegionPtr) NULL;
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ g = pChild->winGravity;
+ if (g != UnmapGravity)
+ {
+ if (!gravitate[g])
+ gravitate[g] = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_UNION(pScreen, gravitate[g],
+ gravitate[g], &pChild->borderClip);
+ }
+ else
+ {
+ UnmapWindow(pChild, TRUE);
+ anyMarked = TRUE;
+ }
+ }
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+
+ oldWinClip = NULL;
+ if (pWin->bitGravity != ForgetGravity)
+ {
+ oldWinClip = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, oldWinClip, &pWin->clipList);
+ }
+ /*
+ * if the window is changing size, borderExposed
+ * can't be computed correctly without some help.
+ */
+ if (pWin->drawable.height > h || pWin->drawable.width > w)
+ shrunk = TRUE;
+
+ if (newx != oldx || newy != oldy)
+ moved = TRUE;
+
+ if ((pWin->drawable.height != h || pWin->drawable.width != w) &&
+ HasBorder (pWin))
+ {
+ borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+ /* for tiled borders, we punt and draw the whole thing */
+ if (pWin->borderIsPixel || !moved)
+ {
+ if (shrunk || moved)
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip,
+ &pWin->winSize);
+ else
+ REGION_COPY(pScreen, borderVisible,
+ &pWin->borderClip);
+ }
+ }
+ }
+ pWin->origin.x = x + bw;
+ pWin->origin.y = y + bw;
+ pWin->drawable.height = h;
+ pWin->drawable.width = w;
+
+ x = pWin->drawable.x = newx;
+ y = pWin->drawable.y = newy;
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ dw = (int)w - (int)width;
+ dh = (int)h - (int)height;
+ ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);
+
+ /* let the hardware adjust background and border pixmaps, if any */
+ (*pScreen->PositionWindow)(pWin, x, y);
+
+ pFirstChange = MoveWindowInStack(pWin, pSib);
+
+ if (WasViewable)
+ {
+ pRegion = REGION_CREATE(pScreen, NullBox, 1);
+ if (pWin->backStorage)
+ REGION_COPY(pScreen, pRegion, &pWin->clipList);
+
+ if (pLayerWin == pWin)
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pFirstChange,
+ (WindowPtr *)NULL);
+ else
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pLayerWin,
+ (WindowPtr *)NULL);
+
+ if (pWin->valdata)
+ {
+ pWin->valdata->before.resized = TRUE;
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pFirstChange);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pLayerWin->parent, pFirstChange, VTOther);
+ /*
+ * the entire window is trashed unless bitGravity
+ * recovers portions of it
+ */
+ REGION_COPY(pScreen, &pWin->valdata->after.exposed, &pWin->clipList);
+ }
+
+ GravityTranslate (x, y, oldx, oldy, dw, dh, pWin->bitGravity, &nx, &ny);
+
+ if (pWin->backStorage &&
+ ((pWin->backingStore == Always) || WasViewable))
+ {
+ if (!WasViewable)
+ pRegion = &pWin->clipList; /* a convenient empty region */
+ if (pWin->bitGravity == ForgetGravity)
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, 0, 0, NullRegion, oldx, oldy);
+ else
+ {
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, nx - x, ny - y, pRegion, oldx, oldy);
+ }
+ }
+
+ if (WasViewable)
+ {
+ /* avoid the border */
+ if (HasBorder (pWin))
+ {
+ int offx, offy, dx, dy;
+
+ /* kruft to avoid double translates for each gravity */
+ offx = 0;
+ offy = 0;
+ for (g = 0; g <= StaticGravity; g++)
+ {
+ if (!gravitate[g])
+ continue;
+
+ /* align winSize to gravitate[g].
+ * winSize is in new coordinates,
+ * gravitate[g] is still in old coordinates */
+ GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+ dx = (oldx - nx) - offx;
+ dy = (oldy - ny) - offy;
+ if (dx || dy)
+ {
+ REGION_TRANSLATE(pScreen, &pWin->winSize, dx, dy);
+ offx += dx;
+ offy += dy;
+ }
+ REGION_INTERSECT(pScreen, gravitate[g], gravitate[g],
+ &pWin->winSize);
+ }
+ /* get winSize back where it belongs */
+ if (offx || offy)
+ REGION_TRANSLATE(pScreen, &pWin->winSize, -offx, -offy);
+ }
+ /*
+ * add screen bits to the appropriate bucket
+ */
+
+ if (oldWinClip)
+ {
+ /*
+ * clip to new clipList
+ */
+ REGION_COPY(pScreen, pRegion, oldWinClip);
+ REGION_TRANSLATE(pScreen, pRegion, nx - oldx, ny - oldy);
+ REGION_INTERSECT(pScreen, oldWinClip, pRegion, &pWin->clipList);
+ /*
+ * don't step on any gravity bits which will be copied after this
+ * region. Note -- this assumes that the regions will be copied
+ * in gravity order.
+ */
+ for (g = pWin->bitGravity + 1; g <= StaticGravity; g++)
+ {
+ if (gravitate[g])
+ REGION_SUBTRACT(pScreen, oldWinClip, oldWinClip,
+ gravitate[g]);
+ }
+ REGION_TRANSLATE(pScreen, oldWinClip, oldx - nx, oldy - ny);
+ g = pWin->bitGravity;
+ if (!gravitate[g])
+ gravitate[g] = oldWinClip;
+ else
+ {
+ REGION_UNION(pScreen, gravitate[g], gravitate[g], oldWinClip);
+ REGION_DESTROY(pScreen, oldWinClip);
+ }
+ }
+
+ /*
+ * move the bits on the screen
+ */
+
+ destClip = NULL;
+
+ for (g = 0; g <= StaticGravity; g++)
+ {
+ if (!gravitate[g])
+ continue;
+
+ GravityTranslate (x, y, oldx, oldy, dw, dh, g, &nx, &ny);
+
+ oldpt.x = oldx + (x - nx);
+ oldpt.y = oldy + (y - ny);
+
+ /* Note that gravitate[g] is *translated* by CopyWindow */
+
+ /* only copy the remaining useful bits */
+
+ REGION_INTERSECT(pScreen, gravitate[g], gravitate[g], oldRegion);
+
+ /* clip to not overwrite already copied areas */
+
+ if (destClip) {
+ REGION_TRANSLATE(pScreen, destClip, oldpt.x - x, oldpt.y - y);
+ REGION_SUBTRACT(pScreen, gravitate[g], gravitate[g], destClip);
+ REGION_TRANSLATE(pScreen, destClip, x - oldpt.x, y - oldpt.y);
+ }
+
+ /* and move those bits */
+
+ if (oldpt.x != x || oldpt.y != y)
+ (*pWin->drawable.pScreen->CopyWindow)(pWin, oldpt, gravitate[g]);
+
+ /* remove any overwritten bits from the remaining useful bits */
+
+ REGION_SUBTRACT(pScreen, oldRegion, oldRegion, gravitate[g]);
+
+ /*
+ * recompute exposed regions of child windows
+ */
+
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->winGravity != g)
+ continue;
+ REGION_INTERSECT(pScreen, pRegion,
+ &pChild->borderClip, gravitate[g]);
+ TraverseTree (pChild, miRecomputeExposures, (pointer)pRegion);
+ }
+
+ /*
+ * remove the successfully copied regions of the
+ * window from its exposed region
+ */
+
+ if (g == pWin->bitGravity)
+ REGION_SUBTRACT(pScreen, &pWin->valdata->after.exposed,
+ &pWin->valdata->after.exposed, gravitate[g]);
+ if (!destClip)
+ destClip = gravitate[g];
+ else
+ {
+ REGION_UNION(pScreen, destClip, destClip, gravitate[g]);
+ REGION_DESTROY(pScreen, gravitate[g]);
+ }
+ }
+
+ REGION_DESTROY(pScreen, oldRegion);
+ REGION_DESTROY(pScreen, pRegion);
+ if (destClip)
+ REGION_DESTROY(pScreen, destClip);
+ if (bsExposed)
+ {
+ RegionPtr valExposed = NullRegion;
+
+ if (pWin->valdata)
+ valExposed = &pWin->valdata->after.exposed;
+ (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+ if (valExposed)
+ REGION_EMPTY(pScreen, valExposed);
+ REGION_DESTROY(pScreen, bsExposed);
+ }
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ {
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pFirstChange);
+ }
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pFirstChange,
+ VTOther);
+ }
+ else if (bsExposed)
+ {
+ (*pScreen->WindowExposures) (pWin, NullRegion, bsExposed);
+ REGION_DESTROY(pScreen, bsExposed);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+WindowPtr
+miGetLayerWindow(pWin)
+ WindowPtr pWin;
+{
+ return pWin->firstChild;
+}
+
+#ifdef SHAPE
+/******
+ *
+ * miSetShape
+ * The border/window shape has changed. Recompute winSize/borderSize
+ * and send appropriate exposure events
+ */
+
+void
+miSetShape(pWin)
+ register WindowPtr pWin;
+{
+ Bool WasViewable = (Bool)(pWin->viewable);
+ register ScreenPtr pScreen = pWin->drawable.pScreen;
+ Bool anyMarked;
+ WindowPtr pParent = pWin->parent;
+ RegionPtr pOldClip, bsExposed;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ if (WasViewable)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+ if (pWin->valdata)
+ {
+ if (HasBorder (pWin))
+ {
+ RegionPtr borderVisible;
+
+ borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ pWin->valdata->before.resized = TRUE;
+ }
+ }
+
+ SetWinSize (pWin);
+ SetBorderSize (pWin);
+
+ ResizeChildrenWinSize(pWin, 0, 0, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pWin->backStorage)
+ {
+ pOldClip = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, pOldClip, &pWin->clipList);
+ }
+
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ (WindowPtr *)NULL);
+
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pLayerWin);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+ }
+
+ if (pWin->backStorage &&
+ ((pWin->backingStore == Always) || WasViewable))
+ {
+ if (!WasViewable)
+ pOldClip = &pWin->clipList; /* a convenient empty region */
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, 0, 0, pOldClip,
+ pWin->drawable.x, pWin->drawable.y);
+ if (WasViewable)
+ REGION_DESTROY(pScreen, pOldClip);
+ if (bsExposed)
+ {
+ RegionPtr valExposed = NullRegion;
+
+ if (pWin->valdata)
+ valExposed = &pWin->valdata->after.exposed;
+ (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+ if (valExposed)
+ REGION_EMPTY(pScreen, valExposed);
+ REGION_DESTROY(pScreen, bsExposed);
+ }
+ }
+ if (WasViewable)
+ {
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pLayerWin);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, NullWindow, VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+ CheckCursorConfinement(pWin);
+}
+#endif
+
+/* Keeps the same inside(!) origin */
+
+void
+miChangeBorderWidth(pWin, width)
+ register WindowPtr pWin;
+ unsigned int width;
+{
+ WindowPtr pParent;
+ int oldwidth;
+ Bool anyMarked;
+ register ScreenPtr pScreen;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ Bool HadBorder;
+#ifdef DO_SAVE_UNDERS
+ Bool dosave = FALSE;
+#endif
+ WindowPtr pLayerWin;
+
+ oldwidth = wBorderWidth (pWin);
+ if (oldwidth == width)
+ return;
+ HadBorder = HasBorder(pWin);
+ pScreen = pWin->drawable.pScreen;
+ pParent = pWin->parent;
+ if (WasViewable && width < oldwidth)
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+
+ pWin->borderWidth = width;
+ SetBorderSize (pWin);
+
+ if (WasViewable)
+ {
+ if (width > oldwidth)
+ {
+ anyMarked = (*pScreen->MarkOverlappedWindows)(pWin, pWin,
+ &pLayerWin);
+ /*
+ * save the old border visible region to correctly compute
+ * borderExposed.
+ */
+ if (pWin->valdata && HadBorder)
+ {
+ RegionPtr borderVisible;
+ borderVisible = REGION_CREATE(pScreen, NULL, 1);
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ }
+#ifdef DO_SAVE_UNDERS
+ if (DO_SAVE_UNDERS(pWin))
+ {
+ dosave = (*pScreen->ChangeSaveUnder)(pLayerWin, pWin->nextSib);
+ }
+#endif /* DO_SAVE_UNDERS */
+
+ if (anyMarked)
+ {
+ (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
+ (*pScreen->HandleExposures)(pLayerWin->parent);
+ }
+#ifdef DO_SAVE_UNDERS
+ if (dosave)
+ (*pScreen->PostChangeSaveUnder)(pLayerWin, pWin->nextSib);
+#endif /* DO_SAVE_UNDERS */
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin,
+ VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+void
+miMarkUnrealizedWindow(pChild, pWin, fromConfigure)
+ WindowPtr pChild;
+ WindowPtr pWin;
+ Bool fromConfigure;
+{
+ if ((pChild != pWin) || fromConfigure)
+ {
+ REGION_EMPTY(pChild->drawable.pScreen, &pChild->clipList);
+ if (pChild->drawable.pScreen->ClipNotify)
+ (* pChild->drawable.pScreen->ClipNotify)(pChild, 0, 0);
+ REGION_EMPTY(pChild->drawable.pScreen, &pChild->borderClip);
+ }
+}
+
+void
+miSegregateChildren(WindowPtr pWin, RegionPtr pReg, int depth)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pChild;
+
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ if (pChild->drawable.depth == depth)
+ REGION_UNION(pScreen, pReg, pReg, &pChild->borderClip);
+
+ if (pChild->firstChild)
+ miSegregateChildren(pChild, pReg, depth);
+ }
+}
diff --git a/xc/programs/Xserver/mi/mizerarc.c b/xc/programs/Xserver/mi/mizerarc.c
new file mode 100644
index 000000000..78fccb90c
--- /dev/null
+++ b/xc/programs/Xserver/mi/mizerarc.c
@@ -0,0 +1,844 @@
+/************************************************************
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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: Bob Scheifler, MIT X Consortium
+
+********************************************************/
+
+/* $TOG: mizerarc.c /main/38 1998/02/09 14:49:36 kaleb $ */
+
+/* Derived from:
+ * "Algorithm for drawing ellipses or hyperbolae with a digital plotter"
+ * by M. L. V. Pitteway
+ * The Computer Journal, November 1967, Volume 10, Number 3, pp. 282-289
+ */
+
+#include <math.h>
+#include "X.h"
+#include "Xprotostr.h"
+#include "miscstruct.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "mi.h"
+#include "mizerarc.h"
+
+#define FULLCIRCLE (360 * 64)
+#define OCTANT (45 * 64)
+#define QUADRANT (90 * 64)
+#define HALFCIRCLE (180 * 64)
+#define QUADRANT3 (270 * 64)
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define Dsin(d) ((d) == 0 ? 0.0 : ((d) == QUADRANT ? 1.0 : \
+ ((d) == HALFCIRCLE ? 0.0 : \
+ ((d) == QUADRANT3 ? -1.0 : sin((double)d*(M_PI/11520.0))))))
+
+#define Dcos(d) ((d) == 0 ? 1.0 : ((d) == QUADRANT ? 0.0 : \
+ ((d) == HALFCIRCLE ? -1.0 : \
+ ((d) == QUADRANT3 ? 0.0 : cos((double)d*(M_PI/11520.0))))))
+
+#define EPSILON45 64
+
+typedef struct {
+ int skipStart;
+ int haveStart;
+ DDXPointRec startPt;
+ int haveLast;
+ int skipLast;
+ DDXPointRec endPt;
+ int dashIndex;
+ int dashOffset;
+ int dashIndexInit;
+ int dashOffsetInit;
+} DashInfo;
+
+static miZeroArcPtRec oob = {65536, 65536, 0};
+
+/*
+ * (x - l)^2 / (W/2)^2 + (y + H/2)^2 / (H/2)^2 = 1
+ *
+ * where l is either 0 or .5
+ *
+ * alpha = 4(W^2)
+ * beta = 4(H^2)
+ * gamma = 0
+ * u = 2(W^2)H
+ * v = 4(H^2)l
+ * k = -4(H^2)(l^2)
+ *
+ */
+
+Bool
+miZeroArcSetup(arc, info, ok360)
+ register xArc *arc;
+ register miZeroArcRec *info;
+ Bool ok360;
+{
+ int l;
+ int angle1, angle2;
+ int startseg, endseg;
+ int startAngle, endAngle;
+ int i, overlap;
+ miZeroArcPtRec start, end;
+
+ l = arc->width & 1;
+ if (arc->width == arc->height)
+ {
+ info->alpha = 4;
+ info->beta = 4;
+ info->k1 = -8;
+ info->k3 = -16;
+ info->b = 12;
+ info->a = (arc->width << 2) - 12;
+ info->d = 17 - (arc->width << 1);
+ if (l)
+ {
+ info->b -= 4;
+ info->a += 4;
+ info->d -= 7;
+ }
+ }
+ else if (!arc->width || !arc->height)
+ {
+ info->alpha = 0;
+ info->beta = 0;
+ info->k1 = 0;
+ info->k3 = 0;
+ info->a = -(int)arc->height;
+ info->b = 0;
+ info->d = -1;
+ }
+ else
+ {
+ /* initial conditions */
+ info->alpha = (arc->width * arc->width) << 2;
+ info->beta = (arc->height * arc->height) << 2;
+ info->k1 = info->beta << 1;
+ info->k3 = info->k1 + (info->alpha << 1);
+ info->b = l ? 0 : -info->beta;
+ info->a = info->alpha * arc->height;
+ info->d = info->b - (info->a >> 1) - (info->alpha >> 2);
+ if (l)
+ info->d -= info->beta >> 2;
+ info->a -= info->b;
+ /* take first step, d < 0 always */
+ info->b -= info->k1;
+ info->a += info->k1;
+ info->d += info->b;
+ /* octant change, b < 0 always */
+ info->k1 = -info->k1;
+ info->k3 = -info->k3;
+ info->b = -info->b;
+ info->d = info->b - info->a - info->d;
+ info->a = info->a - (info->b << 1);
+ }
+ info->dx = 1;
+ info->dy = 0;
+ info->w = (arc->width + 1) >> 1;
+ info->h = arc->height >> 1;
+ info->xorg = arc->x + (arc->width >> 1);
+ info->yorg = arc->y;
+ info->xorgo = info->xorg + l;
+ info->yorgo = info->yorg + arc->height;
+ if (!arc->width)
+ {
+ if (!arc->height)
+ {
+ info->x = 0;
+ info->y = 0;
+ info->initialMask = 0;
+ info->startAngle = 0;
+ info->endAngle = 0;
+ info->start = oob;
+ info->end = oob;
+ return FALSE;
+ }
+ info->x = 0;
+ info->y = 1;
+ }
+ else
+ {
+ info->x = 1;
+ info->y = 0;
+ }
+ angle1 = arc->angle1;
+ angle2 = arc->angle2;
+ if ((angle1 == 0) && (angle2 >= FULLCIRCLE))
+ {
+ startAngle = 0;
+ endAngle = 0;
+ }
+ else
+ {
+ if (angle2 > FULLCIRCLE)
+ angle2 = FULLCIRCLE;
+ else if (angle2 < -FULLCIRCLE)
+ angle2 = -FULLCIRCLE;
+ if (angle2 < 0)
+ {
+ startAngle = angle1 + angle2;
+ endAngle = angle1;
+ }
+ else
+ {
+ startAngle = angle1;
+ endAngle = angle1 + angle2;
+ }
+ if (startAngle < 0)
+ startAngle = FULLCIRCLE - (-startAngle) % FULLCIRCLE;
+ if (startAngle >= FULLCIRCLE)
+ startAngle = startAngle % FULLCIRCLE;
+ if (endAngle < 0)
+ endAngle = FULLCIRCLE - (-endAngle) % FULLCIRCLE;
+ if (endAngle >= FULLCIRCLE)
+ endAngle = endAngle % FULLCIRCLE;
+ }
+ info->startAngle = startAngle;
+ info->endAngle = endAngle;
+ if (ok360 && (startAngle == endAngle) && arc->angle2 &&
+ arc->width && arc->height)
+ {
+ info->initialMask = 0xf;
+ info->start = oob;
+ info->end = oob;
+ return TRUE;
+ }
+ startseg = startAngle / OCTANT;
+ if (!arc->height || (((startseg + 1) & 2) && arc->width))
+ {
+ start.x = Dcos(startAngle) * ((arc->width + 1) / 2.0);
+ if (start.x < 0)
+ start.x = -start.x;
+ start.y = -1;
+ }
+ else
+ {
+ start.y = Dsin(startAngle) * (arc->height / 2.0);
+ if (start.y < 0)
+ start.y = -start.y;
+ start.y = info->h - start.y;
+ start.x = 65536;
+ }
+ endseg = endAngle / OCTANT;
+ if (!arc->height || (((endseg + 1) & 2) && arc->width))
+ {
+ end.x = Dcos(endAngle) * ((arc->width + 1) / 2.0);
+ if (end.x < 0)
+ end.x = -end.x;
+ end.y = -1;
+ }
+ else
+ {
+ end.y = Dsin(endAngle) * (arc->height / 2.0);
+ if (end.y < 0)
+ end.y = -end.y;
+ end.y = info->h - end.y;
+ end.x = 65536;
+ }
+ info->firstx = start.x;
+ info->firsty = start.y;
+ info->initialMask = 0;
+ overlap = arc->angle2 && (endAngle <= startAngle);
+ for (i = 0; i < 4; i++)
+ {
+ if (overlap ?
+ ((i * QUADRANT <= endAngle) || ((i + 1) * QUADRANT > startAngle)) :
+ ((i * QUADRANT <= endAngle) && ((i + 1) * QUADRANT > startAngle)))
+ info->initialMask |= (1 << i);
+ }
+ start.mask = info->initialMask;
+ end.mask = info->initialMask;
+ startseg >>= 1;
+ endseg >>= 1;
+ overlap = overlap && (endseg == startseg);
+ if (start.x != end.x || start.y != end.y || !overlap)
+ {
+ if (startseg & 1)
+ {
+ if (!overlap)
+ info->initialMask &= ~(1 << startseg);
+ if (start.x > end.x || start.y > end.y)
+ end.mask &= ~(1 << startseg);
+ }
+ else
+ {
+ start.mask &= ~(1 << startseg);
+ if (((start.x < end.x || start.y < end.y) ||
+ (start.x == end.x && start.y == end.y && (endseg & 1))) &&
+ !overlap)
+ end.mask &= ~(1 << startseg);
+ }
+ if (endseg & 1)
+ {
+ end.mask &= ~(1 << endseg);
+ if (((start.x > end.x || start.y > end.y) ||
+ (start.x == end.x && start.y == end.y && !(startseg & 1))) &&
+ !overlap)
+ start.mask &= ~(1 << endseg);
+ }
+ else
+ {
+ if (!overlap)
+ info->initialMask &= ~(1 << endseg);
+ if (start.x < end.x || start.y < end.y)
+ start.mask &= ~(1 << endseg);
+ }
+ }
+ /* take care of case when start and stop are both near 45 */
+ /* handle here rather than adding extra code to pixelization loops */
+ if (startAngle &&
+ ((start.y < 0 && end.y >= 0) || (start.y >= 0 && end.y < 0)))
+ {
+ i = (startAngle + OCTANT) % OCTANT;
+ if (i < EPSILON45 || i > OCTANT - EPSILON45)
+ {
+ i = (endAngle + OCTANT) % OCTANT;
+ if (i < EPSILON45 || i > OCTANT - EPSILON45)
+ {
+ if (start.y < 0)
+ {
+ i = Dsin(startAngle) * (arc->height / 2.0);
+ if (i < 0)
+ i = -i;
+ if (info->h - i == end.y)
+ start.mask = end.mask;
+ }
+ else
+ {
+ i = Dsin(endAngle) * (arc->height / 2.0);
+ if (i < 0)
+ i = -i;
+ if (info->h - i == start.y)
+ end.mask = start.mask;
+ }
+ }
+ }
+ }
+ if (startseg & 1)
+ {
+ info->start = start;
+ info->end = oob;
+ }
+ else
+ {
+ info->end = start;
+ info->start = oob;
+ }
+ if (endseg & 1)
+ {
+ info->altend = end;
+ if (info->altend.x < info->end.x || info->altend.y < info->end.y)
+ {
+ miZeroArcPtRec tmp;
+ tmp = info->altend;
+ info->altend = info->end;
+ info->end = tmp;
+ }
+ info->altstart = oob;
+ }
+ else
+ {
+ info->altstart = end;
+ if (info->altstart.x < info->start.x ||
+ info->altstart.y < info->start.y)
+ {
+ miZeroArcPtRec tmp;
+ tmp = info->altstart;
+ info->altstart = info->start;
+ info->start = tmp;
+ }
+ info->altend = oob;
+ }
+ if (!info->start.x || !info->start.y)
+ {
+ info->initialMask = info->start.mask;
+ info->start = info->altstart;
+ }
+ if (!arc->width && (arc->height == 1))
+ {
+ /* kludge! */
+ info->initialMask |= info->end.mask;
+ info->initialMask |= info->initialMask << 1;
+ info->end.x = 0;
+ info->end.mask = 0;
+ }
+ return FALSE;
+}
+
+#define Pixelate(xval,yval) \
+ { \
+ pts->x = xval; \
+ pts->y = yval; \
+ pts++; \
+ }
+
+#define DoPix(idx,xval,yval) if (mask & (1 << idx)) Pixelate(xval, yval);
+
+DDXPointPtr
+miZeroArcPts(arc, pts)
+ xArc *arc;
+ register DDXPointPtr pts;
+{
+ miZeroArcRec info;
+ register int x, y, a, b, d, mask;
+ register int k1, k3, dx, dy;
+ Bool do360;
+
+ do360 = miZeroArcSetup(arc, &info, TRUE);
+ MIARCSETUP();
+ mask = info.initialMask;
+ if (!(arc->width & 1))
+ {
+ DoPix(1, info.xorgo, info.yorg);
+ DoPix(3, info.xorgo, info.yorgo);
+ }
+ if (!info.end.x || !info.end.y)
+ {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ if (do360 && (arc->width == arc->height) && !(arc->width & 1))
+ {
+ int yorgh = info.yorg + info.h;
+ int xorghp = info.xorg + info.h;
+ int xorghn = info.xorg - info.h;
+
+ while (1)
+ {
+ Pixelate(info.xorg + x, info.yorg + y);
+ Pixelate(info.xorg - x, info.yorg + y);
+ Pixelate(info.xorg - x, info.yorgo - y);
+ Pixelate(info.xorg + x, info.yorgo - y);
+ if (a < 0)
+ break;
+ Pixelate(xorghp - y, yorgh - x);
+ Pixelate(xorghn + y, yorgh - x);
+ Pixelate(xorghn + y, yorgh + x);
+ Pixelate(xorghp - y, yorgh + x);
+ MIARCCIRCLESTEP(;);
+ }
+ if (x > 1 && pts[-1].x == pts[-5].x && pts[-1].y == pts[-5].y)
+ pts -= 4;
+ x = info.w;
+ y = info.h;
+ }
+ else if (do360)
+ {
+ while (y < info.h || x < info.w)
+ {
+ MIARCOCTANTSHIFT(;);
+ Pixelate(info.xorg + x, info.yorg + y);
+ Pixelate(info.xorgo - x, info.yorg + y);
+ Pixelate(info.xorgo - x, info.yorgo - y);
+ Pixelate(info.xorg + x, info.yorgo - y);
+ MIARCSTEP(;,;);
+ }
+ }
+ else
+ {
+ while (y < info.h || x < info.w)
+ {
+ MIARCOCTANTSHIFT(;);
+ if ((x == info.start.x) || (y == info.start.y))
+ {
+ mask = info.start.mask;
+ info.start = info.altstart;
+ }
+ DoPix(0, info.xorg + x, info.yorg + y);
+ DoPix(1, info.xorgo - x, info.yorg + y);
+ DoPix(2, info.xorgo - x, info.yorgo - y);
+ DoPix(3, info.xorg + x, info.yorgo - y);
+ if ((x == info.end.x) || (y == info.end.y))
+ {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ MIARCSTEP(;,;);
+ }
+ }
+ if ((x == info.start.x) || (y == info.start.y))
+ mask = info.start.mask;
+ DoPix(0, info.xorg + x, info.yorg + y);
+ DoPix(2, info.xorgo - x, info.yorgo - y);
+ if (arc->height & 1)
+ {
+ DoPix(1, info.xorgo - x, info.yorg + y);
+ DoPix(3, info.xorg + x, info.yorgo - y);
+ }
+ return pts;
+}
+
+#undef DoPix
+#define DoPix(idx,xval,yval) \
+ if (mask & (1 << idx)) \
+ { \
+ arcPts[idx]->x = xval; \
+ arcPts[idx]->y = yval; \
+ arcPts[idx]++; \
+ }
+
+static void
+miZeroArcDashPts(pGC, arc, dinfo, points, maxPts, evenPts, oddPts)
+ GCPtr pGC;
+ xArc *arc;
+ DashInfo *dinfo;
+ int maxPts;
+ register DDXPointPtr points, *evenPts, *oddPts;
+{
+ miZeroArcRec info;
+ register int x, y, a, b, d, mask;
+ register int k1, k3, dx, dy;
+ int dashRemaining;
+ DDXPointPtr arcPts[4];
+ DDXPointPtr startPts[5], endPts[5];
+ int deltas[5];
+ DDXPointPtr startPt, pt, lastPt, pts;
+ int i, j, delta, ptsdelta, seg, startseg;
+
+ for (i = 0; i < 4; i++)
+ arcPts[i] = points + (i * maxPts);
+ (void)miZeroArcSetup(arc, &info, FALSE);
+ MIARCSETUP();
+ mask = info.initialMask;
+ startseg = info.startAngle / QUADRANT;
+ startPt = arcPts[startseg];
+ if (!(arc->width & 1))
+ {
+ DoPix(1, info.xorgo, info.yorg);
+ DoPix(3, info.xorgo, info.yorgo);
+ }
+ if (!info.end.x || !info.end.y)
+ {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ while (y < info.h || x < info.w)
+ {
+ MIARCOCTANTSHIFT(;);
+ if ((x == info.firstx) || (y == info.firsty))
+ startPt = arcPts[startseg];
+ if ((x == info.start.x) || (y == info.start.y))
+ {
+ mask = info.start.mask;
+ info.start = info.altstart;
+ }
+ DoPix(0, info.xorg + x, info.yorg + y);
+ DoPix(1, info.xorgo - x, info.yorg + y);
+ DoPix(2, info.xorgo - x, info.yorgo - y);
+ DoPix(3, info.xorg + x, info.yorgo - y);
+ if ((x == info.end.x) || (y == info.end.y))
+ {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ MIARCSTEP(;,;);
+ }
+ if ((x == info.firstx) || (y == info.firsty))
+ startPt = arcPts[startseg];
+ if ((x == info.start.x) || (y == info.start.y))
+ mask = info.start.mask;
+ DoPix(0, info.xorg + x, info.yorg + y);
+ DoPix(2, info.xorgo - x, info.yorgo - y);
+ if (arc->height & 1)
+ {
+ DoPix(1, info.xorgo - x, info.yorg + y);
+ DoPix(3, info.xorg + x, info.yorgo - y);
+ }
+ for (i = 0; i < 4; i++)
+ {
+ seg = (startseg + i) & 3;
+ pt = points + (seg * maxPts);
+ if (seg & 1)
+ {
+ startPts[i] = pt;
+ endPts[i] = arcPts[seg];
+ deltas[i] = 1;
+ }
+ else
+ {
+ startPts[i] = arcPts[seg] - 1;
+ endPts[i] = pt - 1;
+ deltas[i] = -1;
+ }
+ }
+ startPts[4] = startPts[0];
+ endPts[4] = startPt;
+ startPts[0] = startPt;
+ if (startseg & 1)
+ {
+ if (startPts[4] != endPts[4])
+ endPts[4]--;
+ deltas[4] = 1;
+ }
+ else
+ {
+ if (startPts[0] > startPts[4])
+ startPts[0]--;
+ if (startPts[4] < endPts[4])
+ endPts[4]--;
+ deltas[4] = -1;
+ }
+ if (arc->angle2 < 0)
+ {
+ DDXPointPtr tmps, tmpe;
+ int tmpd;
+
+ tmpd = deltas[0];
+ tmps = startPts[0] - tmpd;
+ tmpe = endPts[0] - tmpd;
+ startPts[0] = endPts[4] - deltas[4];
+ endPts[0] = startPts[4] - deltas[4];
+ deltas[0] = -deltas[4];
+ startPts[4] = tmpe;
+ endPts[4] = tmps;
+ deltas[4] = -tmpd;
+ tmpd = deltas[1];
+ tmps = startPts[1] - tmpd;
+ tmpe = endPts[1] - tmpd;
+ startPts[1] = endPts[3] - deltas[3];
+ endPts[1] = startPts[3] - deltas[3];
+ deltas[1] = -deltas[3];
+ startPts[3] = tmpe;
+ endPts[3] = tmps;
+ deltas[3] = -tmpd;
+ tmps = startPts[2] - deltas[2];
+ startPts[2] = endPts[2] - deltas[2];
+ endPts[2] = tmps;
+ deltas[2] = -deltas[2];
+ }
+ for (i = 0; i < 5 && startPts[i] == endPts[i]; i++)
+ ;
+ if (i == 5)
+ return;
+ pt = startPts[i];
+ for (j = 4; startPts[j] == endPts[j]; j--)
+ ;
+ lastPt = endPts[j] - deltas[j];
+ if (dinfo->haveLast &&
+ (pt->x == dinfo->endPt.x) && (pt->y == dinfo->endPt.y))
+ {
+ startPts[i] += deltas[i];
+ }
+ else
+ {
+ dinfo->dashIndex = dinfo->dashIndexInit;
+ dinfo->dashOffset = dinfo->dashOffsetInit;
+ }
+ if (!dinfo->skipStart && (info.startAngle != info.endAngle))
+ {
+ dinfo->startPt = *pt;
+ dinfo->haveStart = TRUE;
+ }
+ else if (!dinfo->skipLast && dinfo->haveStart &&
+ (lastPt->x == dinfo->startPt.x) &&
+ (lastPt->y == dinfo->startPt.y) &&
+ (lastPt != startPts[i]))
+ endPts[j] = lastPt;
+ if (info.startAngle != info.endAngle)
+ {
+ dinfo->haveLast = TRUE;
+ dinfo->endPt = *lastPt;
+ }
+ dashRemaining = pGC->dash[dinfo->dashIndex] - dinfo->dashOffset;
+ for (i = 0; i < 5; i++)
+ {
+ pt = startPts[i];
+ lastPt = endPts[i];
+ delta = deltas[i];
+ while (pt != lastPt)
+ {
+ if (dinfo->dashIndex & 1)
+ {
+ pts = *oddPts;
+ ptsdelta = -1;
+ }
+ else
+ {
+ pts = *evenPts;
+ ptsdelta = 1;
+ }
+ while ((pt != lastPt) && --dashRemaining >= 0)
+ {
+ *pts = *pt;
+ pts += ptsdelta;
+ pt += delta;
+ }
+ if (dinfo->dashIndex & 1)
+ *oddPts = pts;
+ else
+ *evenPts = pts;
+ if (dashRemaining <= 0)
+ {
+ if (++(dinfo->dashIndex) == pGC->numInDashList)
+ dinfo->dashIndex = 0;
+ dashRemaining = pGC->dash[dinfo->dashIndex];
+ }
+ }
+ }
+ dinfo->dashOffset = pGC->dash[dinfo->dashIndex] - dashRemaining;
+}
+
+void
+miZeroPolyArc(pDraw, pGC, narcs, parcs)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ int maxPts = 0;
+ register int n, maxw;
+ register xArc *arc;
+ register int i;
+ DDXPointPtr points, pts, oddPts;
+ register DDXPointPtr pt;
+ int numPts;
+ Bool dospans;
+ int *widths;
+ XID fgPixel = pGC->fgPixel;
+ DashInfo dinfo;
+
+ for (arc = parcs, i = narcs; --i >= 0; arc++)
+ {
+ if (!miCanZeroArc(arc))
+ miPolyArc(pDraw, pGC, 1, arc);
+ else
+ {
+ if (arc->width > arc->height)
+ n = arc->width + (arc->height >> 1);
+ else
+ n = arc->height + (arc->width >> 1);
+ if (n > maxPts)
+ maxPts = n;
+ }
+ }
+ if (!maxPts)
+ return;
+ numPts = maxPts << 2;
+ dospans = (pGC->lineStyle != LineSolid) || (pGC->fillStyle != FillSolid);
+ if (dospans)
+ {
+ widths = (int *)ALLOCATE_LOCAL(sizeof(int) * numPts);
+ if (!widths)
+ return;
+ maxw = 0;
+ }
+ if (pGC->lineStyle != LineSolid)
+ {
+ numPts <<= 1;
+ dinfo.haveStart = FALSE;
+ dinfo.skipStart = FALSE;
+ dinfo.haveLast = FALSE;
+ dinfo.dashIndexInit = 0;
+ dinfo.dashOffsetInit = 0;
+ miStepDash((int)pGC->dashOffset, &dinfo.dashIndexInit,
+ (unsigned char *) pGC->dash, (int)pGC->numInDashList,
+ &dinfo.dashOffsetInit);
+ }
+ points = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * numPts);
+ if (!points)
+ {
+ if (dospans)
+ {
+ DEALLOCATE_LOCAL(widths);
+ }
+ return;
+ }
+ for (arc = parcs, i = narcs; --i >= 0; arc++)
+ {
+ if (miCanZeroArc(arc))
+ {
+ if (pGC->lineStyle == LineSolid)
+ pts = miZeroArcPts(arc, points);
+ else
+ {
+ pts = points;
+ oddPts = &points[(numPts >> 1) - 1];
+ dinfo.skipLast = i;
+ miZeroArcDashPts(pGC, arc, &dinfo,
+ oddPts + 1, maxPts, &pts, &oddPts);
+ dinfo.skipStart = TRUE;
+ }
+ n = pts - points;
+ if (!dospans)
+ (*pGC->ops->PolyPoint)(pDraw, pGC, CoordModeOrigin, n, points);
+ else
+ {
+ if (n > maxw)
+ {
+ while (maxw < n)
+ widths[maxw++] = 1;
+ }
+ if (pGC->miTranslate)
+ {
+ for (pt = points; pt != pts; pt++)
+ {
+ pt->x += pDraw->x;
+ pt->y += pDraw->y;
+ }
+ }
+ (*pGC->ops->FillSpans)(pDraw, pGC, n, points, widths, FALSE);
+ }
+ if (pGC->lineStyle != LineDoubleDash)
+ continue;
+ if ((pGC->fillStyle == FillSolid) ||
+ (pGC->fillStyle == FillStippled))
+ {
+ DoChangeGC(pGC, GCForeground, (XID *)&pGC->bgPixel, 0);
+ ValidateGC(pDraw, pGC);
+ }
+ pts = &points[numPts >> 1];
+ oddPts++;
+ n = pts - oddPts;
+ if (!dospans)
+ (*pGC->ops->PolyPoint)(pDraw, pGC, CoordModeOrigin, n, oddPts);
+ else
+ {
+ if (n > maxw)
+ {
+ while (maxw < n)
+ widths[maxw++] = 1;
+ }
+ if (pGC->miTranslate)
+ {
+ for (pt = oddPts; pt != pts; pt++)
+ {
+ pt->x += pDraw->x;
+ pt->y += pDraw->y;
+ }
+ }
+ (*pGC->ops->FillSpans)(pDraw, pGC, n, oddPts, widths, FALSE);
+ }
+ if ((pGC->fillStyle == FillSolid) ||
+ (pGC->fillStyle == FillStippled))
+ {
+ DoChangeGC(pGC, GCForeground, &fgPixel, 0);
+ ValidateGC(pDraw, pGC);
+ }
+ }
+ }
+ DEALLOCATE_LOCAL(points);
+ if (dospans)
+ {
+ DEALLOCATE_LOCAL(widths);
+ }
+}
diff --git a/xc/programs/Xserver/mi/mizerarc.h b/xc/programs/Xserver/mi/mizerarc.h
new file mode 100644
index 000000000..7e539cb97
--- /dev/null
+++ b/xc/programs/Xserver/mi/mizerarc.h
@@ -0,0 +1,133 @@
+/************************************************************
+
+Copyright 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+********************************************************/
+
+/* $TOG: mizerarc.h /main/15 1998/02/09 14:49:41 kaleb $ */
+
+typedef struct {
+ int x;
+ int y;
+ int mask;
+} miZeroArcPtRec;
+
+typedef struct {
+ int x, y, k1, k3, a, b, d, dx, dy;
+ int alpha, beta;
+ int xorg, yorg;
+ int xorgo, yorgo;
+ int w, h;
+ int initialMask;
+ miZeroArcPtRec start, altstart, end, altend;
+ int firstx, firsty;
+ int startAngle, endAngle;
+} miZeroArcRec;
+
+#define miCanZeroArc(arc) (((arc)->width == (arc)->height) || \
+ (((arc)->width <= 800) && ((arc)->height <= 800)))
+
+#define MIARCSETUP() \
+ x = info.x; \
+ y = info.y; \
+ k1 = info.k1; \
+ k3 = info.k3; \
+ a = info.a; \
+ b = info.b; \
+ d = info.d; \
+ dx = info.dx; \
+ dy = info.dy
+
+#define MIARCOCTANTSHIFT(clause) \
+ if (a < 0) \
+ { \
+ if (y == info.h) \
+ { \
+ d = -1; \
+ a = b = k1 = 0; \
+ } \
+ else \
+ { \
+ dx = (k1 << 1) - k3; \
+ k1 = dx - k1; \
+ k3 = -k3; \
+ b = b + a - (k1 >> 1); \
+ d = b + ((-a) >> 1) - d + (k3 >> 3); \
+ if (dx < 0) \
+ a = -((-dx) >> 1) - a; \
+ else \
+ a = (dx >> 1) - a; \
+ dx = 0; \
+ dy = 1; \
+ clause \
+ } \
+ }
+
+#define MIARCSTEP(move1,move2) \
+ b -= k1; \
+ if (d < 0) \
+ { \
+ x += dx; \
+ y += dy; \
+ a += k1; \
+ d += b; \
+ move1 \
+ } \
+ else \
+ { \
+ x++; \
+ y++; \
+ a += k3; \
+ d -= a; \
+ move2 \
+ }
+
+#define MIARCCIRCLESTEP(clause) \
+ b -= k1; \
+ x++; \
+ if (d < 0) \
+ { \
+ a += k1; \
+ d += b; \
+ } \
+ else \
+ { \
+ y++; \
+ a += k3; \
+ d -= a; \
+ clause \
+ }
+
+/* mizerarc.c */
+
+extern Bool miZeroArcSetup(
+#if NeedFunctionPrototypes
+ xArc * /*arc*/,
+ miZeroArcRec * /*info*/,
+ Bool /*ok360*/
+#endif
+);
+
+extern DDXPointPtr miZeroArcPts(
+#if NeedFunctionPrototypes
+ xArc * /*arc*/,
+ DDXPointPtr /*pts*/
+#endif
+);
+
diff --git a/xc/programs/Xserver/mi/mizerline.c b/xc/programs/Xserver/mi/mizerline.c
new file mode 100644
index 000000000..43ff9826f
--- /dev/null
+++ b/xc/programs/Xserver/mi/mizerline.c
@@ -0,0 +1,956 @@
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: mizerline.c /main/18 1998/02/09 14:49:45 kaleb $ */
+#include "X.h"
+
+#include "misc.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmap.h"
+#include "mi.h"
+#include "miline.h"
+
+/*
+
+The bresenham error equation used in the mi/mfb/cfb line routines is:
+
+ e = error
+ dx = difference in raw X coordinates
+ dy = difference in raw Y coordinates
+ M = # of steps in X direction
+ N = # of steps in Y direction
+ B = 0 to prefer diagonal steps in a given octant,
+ 1 to prefer axial steps in a given octant
+
+ For X major lines:
+ e = 2Mdy - 2Ndx - dx - B
+ -2dx <= e < 0
+
+ For Y major lines:
+ e = 2Ndx - 2Mdy - dy - B
+ -2dy <= e < 0
+
+At the start of the line, we have taken 0 X steps and 0 Y steps,
+so M = 0 and N = 0:
+
+ X major e = 2Mdy - 2Ndx - dx - B
+ = -dx - B
+
+ Y major e = 2Ndx - 2Mdy - dy - B
+ = -dy - B
+
+At the end of the line, we have taken dx X steps and dy Y steps,
+so M = dx and N = dy:
+
+ X major e = 2Mdy - 2Ndx - dx - B
+ = 2dxdy - 2dydx - dx - B
+ = -dx - B
+ Y major e = 2Ndx - 2Mdy - dy - B
+ = 2dydx - 2dxdy - dy - B
+ = -dy - B
+
+Thus, the error term is the same at the start and end of the line.
+
+Let us consider clipping an X coordinate. There are 4 cases which
+represent the two independent cases of clipping the start vs. the
+end of the line and an X major vs. a Y major line. In any of these
+cases, we know the number of X steps (M) and we wish to find the
+number of Y steps (N). Thus, we will solve our error term equation.
+If we are clipping the start of the line, we will find the smallest
+N that satisfies our error term inequality. If we are clipping the
+end of the line, we will find the largest number of Y steps that
+satisfies the inequality. In that case, since we are representing
+the Y steps as (dy - N), we will actually want to solve for the
+smallest N in that equation.
+
+Case 1: X major, starting X coordinate moved by M steps
+
+ -2dx <= 2Mdy - 2Ndx - dx - B < 0
+ 2Ndx <= 2Mdy - dx - B + 2dx 2Ndx > 2Mdy - dx - B
+ 2Ndx <= 2Mdy + dx - B N > (2Mdy - dx - B) / 2dx
+ N <= (2Mdy + dx - B) / 2dx
+
+Since we are trying to find the smallest N that satisfies these
+equations, we should use the > inequality to find the smallest:
+
+ N = floor((2Mdy - dx - B) / 2dx) + 1
+ = floor((2Mdy - dx - B + 2dx) / 2dx)
+ = floor((2Mdy + dx - B) / 2dx)
+
+Case 1b: X major, ending X coordinate moved to M steps
+
+Same derivations as Case 1, but we want the largest N that satisfies
+the equations, so we use the <= inequality:
+
+ N = floor((2Mdy + dx - B) / 2dx)
+
+Case 2: X major, ending X coordinate moved by M steps
+
+ -2dx <= 2(dx - M)dy - 2(dy - N)dx - dx - B < 0
+ -2dx <= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B < 0
+ -2dx <= 2Ndx - 2Mdy - dx - B < 0
+ 2Ndx >= 2Mdy + dx + B - 2dx 2Ndx < 2Mdy + dx + B
+ 2Ndx >= 2Mdy - dx + B N < (2Mdy + dx + B) / 2dx
+ N >= (2Mdy - dx + B) / 2dx
+
+Since we are trying to find the highest number of Y steps that
+satisfies these equations, we need to find the smallest N, so
+we should use the >= inequality to find the smallest:
+
+ N = ceiling((2Mdy - dx + B) / 2dx)
+ = floor((2Mdy - dx + B + 2dx - 1) / 2dx)
+ = floor((2Mdy + dx + B - 1) / 2dx)
+
+Case 2b: X major, starting X coordinate moved to M steps from end
+
+Same derivations as Case 2, but we want the smallest number of Y
+steps, so we want the highest N, so we use the < inequality:
+
+ N = ceiling((2Mdy + dx + B) / 2dx) - 1
+ = floor((2Mdy + dx + B + 2dx - 1) / 2dx) - 1
+ = floor((2Mdy + dx + B + 2dx - 1 - 2dx) / 2dx)
+ = floor((2Mdy + dx + B - 1) / 2dx)
+
+Case 3: Y major, starting X coordinate moved by M steps
+
+ -2dy <= 2Ndx - 2Mdy - dy - B < 0
+ 2Ndx >= 2Mdy + dy + B - 2dy 2Ndx < 2Mdy + dy + B
+ 2Ndx >= 2Mdy - dy + B N < (2Mdy + dy + B) / 2dx
+ N >= (2Mdy - dy + B) / 2dx
+
+Since we are trying to find the smallest N that satisfies these
+equations, we should use the >= inequality to find the smallest:
+
+ N = ceiling((2Mdy - dy + B) / 2dx)
+ = floor((2Mdy - dy + B + 2dx - 1) / 2dx)
+ = floor((2Mdy - dy + B - 1) / 2dx) + 1
+
+Case 3b: Y major, ending X coordinate moved to M steps
+
+Same derivations as Case 3, but we want the largest N that satisfies
+the equations, so we use the < inequality:
+
+ N = ceiling((2Mdy + dy + B) / 2dx) - 1
+ = floor((2Mdy + dy + B + 2dx - 1) / 2dx) - 1
+ = floor((2Mdy + dy + B + 2dx - 1 - 2dx) / 2dx)
+ = floor((2Mdy + dy + B - 1) / 2dx)
+
+Case 4: Y major, ending X coordinate moved by M steps
+
+ -2dy <= 2(dy - N)dx - 2(dx - M)dy - dy - B < 0
+ -2dy <= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B < 0
+ -2dy <= 2Mdy - 2Ndx - dy - B < 0
+ 2Ndx <= 2Mdy - dy - B + 2dy 2Ndx > 2Mdy - dy - B
+ 2Ndx <= 2Mdy + dy - B N > (2Mdy - dy - B) / 2dx
+ N <= (2Mdy + dy - B) / 2dx
+
+Since we are trying to find the highest number of Y steps that
+satisfies these equations, we need to find the smallest N, so
+we should use the > inequality to find the smallest:
+
+ N = floor((2Mdy - dy - B) / 2dx) + 1
+
+Case 4b: Y major, starting X coordinate moved to M steps from end
+
+Same analysis as Case 4, but we want the smallest number of Y steps
+which means the largest N, so we use the <= inequality:
+
+ N = floor((2Mdy + dy - B) / 2dx)
+
+Now let's try the Y coordinates, we have the same 4 cases.
+
+Case 5: X major, starting Y coordinate moved by N steps
+
+ -2dx <= 2Mdy - 2Ndx - dx - B < 0
+ 2Mdy >= 2Ndx + dx + B - 2dx 2Mdy < 2Ndx + dx + B
+ 2Mdy >= 2Ndx - dx + B M < (2Ndx + dx + B) / 2dy
+ M >= (2Ndx - dx + B) / 2dy
+
+Since we are trying to find the smallest M, we use the >= inequality:
+
+ M = ceiling((2Ndx - dx + B) / 2dy)
+ = floor((2Ndx - dx + B + 2dy - 1) / 2dy)
+ = floor((2Ndx - dx + B - 1) / 2dy) + 1
+
+Case 5b: X major, ending Y coordinate moved to N steps
+
+Same derivations as Case 5, but we want the largest M that satisfies
+the equations, so we use the < inequality:
+
+ M = ceiling((2Ndx + dx + B) / 2dy) - 1
+ = floor((2Ndx + dx + B + 2dy - 1) / 2dy) - 1
+ = floor((2Ndx + dx + B + 2dy - 1 - 2dy) / 2dy)
+ = floor((2Ndx + dx + B - 1) / 2dy)
+
+Case 6: X major, ending Y coordinate moved by N steps
+
+ -2dx <= 2(dx - M)dy - 2(dy - N)dx - dx - B < 0
+ -2dx <= 2dxdy - 2Mdy - 2dxdy + 2Ndx - dx - B < 0
+ -2dx <= 2Ndx - 2Mdy - dx - B < 0
+ 2Mdy <= 2Ndx - dx - B + 2dx 2Mdy > 2Ndx - dx - B
+ 2Mdy <= 2Ndx + dx - B M > (2Ndx - dx - B) / 2dy
+ M <= (2Ndx + dx - B) / 2dy
+
+Largest # of X steps means smallest M, so use the > inequality:
+
+ M = floor((2Ndx - dx - B) / 2dy) + 1
+
+Case 6b: X major, starting Y coordinate moved to N steps from end
+
+Same derivations as Case 6, but we want the smallest # of X steps
+which means the largest M, so use the <= inequality:
+
+ M = floor((2Ndx + dx - B) / 2dy)
+
+Case 7: Y major, starting Y coordinate moved by N steps
+
+ -2dy <= 2Ndx - 2Mdy - dy - B < 0
+ 2Mdy <= 2Ndx - dy - B + 2dy 2Mdy > 2Ndx - dy - B
+ 2Mdy <= 2Ndx + dy - B M > (2Ndx - dy - B) / 2dy
+ M <= (2Ndx + dy - B) / 2dy
+
+To find the smallest M, use the > inequality:
+
+ M = floor((2Ndx - dy - B) / 2dy) + 1
+ = floor((2Ndx - dy - B + 2dy) / 2dy)
+ = floor((2Ndx + dy - B) / 2dy)
+
+Case 7b: Y major, ending Y coordinate moved to N steps
+
+Same derivations as Case 7, but we want the largest M that satisfies
+the equations, so use the <= inequality:
+
+ M = floor((2Ndx + dy - B) / 2dy)
+
+Case 8: Y major, ending Y coordinate moved by N steps
+
+ -2dy <= 2(dy - N)dx - 2(dx - M)dy - dy - B < 0
+ -2dy <= 2dxdy - 2Ndx - 2dxdy + 2Mdy - dy - B < 0
+ -2dy <= 2Mdy - 2Ndx - dy - B < 0
+ 2Mdy >= 2Ndx + dy + B - 2dy 2Mdy < 2Ndx + dy + B
+ 2Mdy >= 2Ndx - dy + B M < (2Ndx + dy + B) / 2dy
+ M >= (2Ndx - dy + B) / 2dy
+
+To find the highest X steps, find the smallest M, use the >= inequality:
+
+ M = ceiling((2Ndx - dy + B) / 2dy)
+ = floor((2Ndx - dy + B + 2dy - 1) / 2dy)
+ = floor((2Ndx + dy + B - 1) / 2dy)
+
+Case 8b: Y major, starting Y coordinate moved to N steps from the end
+
+Same derivations as Case 8, but we want to find the smallest # of X
+steps which means the largest M, so we use the < inequality:
+
+ M = ceiling((2Ndx + dy + B) / 2dy) - 1
+ = floor((2Ndx + dy + B + 2dy - 1) / 2dy) - 1
+ = floor((2Ndx + dy + B + 2dy - 1 - 2dy) / 2dy)
+ = floor((2Ndx + dy + B - 1) / 2dy)
+
+So, our equations are:
+
+ 1: X major move x1 to x1+M floor((2Mdy + dx - B) / 2dx)
+ 1b: X major move x2 to x1+M floor((2Mdy + dx - B) / 2dx)
+ 2: X major move x2 to x2-M floor((2Mdy + dx + B - 1) / 2dx)
+ 2b: X major move x1 to x2-M floor((2Mdy + dx + B - 1) / 2dx)
+
+ 3: Y major move x1 to x1+M floor((2Mdy - dy + B - 1) / 2dx) + 1
+ 3b: Y major move x2 to x1+M floor((2Mdy + dy + B - 1) / 2dx)
+ 4: Y major move x2 to x2-M floor((2Mdy - dy - B) / 2dx) + 1
+ 4b: Y major move x1 to x2-M floor((2Mdy + dy - B) / 2dx)
+
+ 5: X major move y1 to y1+N floor((2Ndx - dx + B - 1) / 2dy) + 1
+ 5b: X major move y2 to y1+N floor((2Ndx + dx + B - 1) / 2dy)
+ 6: X major move y2 to y2-N floor((2Ndx - dx - B) / 2dy) + 1
+ 6b: X major move y1 to y2-N floor((2Ndx + dx - B) / 2dy)
+
+ 7: Y major move y1 to y1+N floor((2Ndx + dy - B) / 2dy)
+ 7b: Y major move y2 to y1+N floor((2Ndx + dy - B) / 2dy)
+ 8: Y major move y2 to y2-N floor((2Ndx + dy + B - 1) / 2dy)
+ 8b: Y major move y1 to y2-N floor((2Ndx + dy + B - 1) / 2dy)
+
+We have the following constraints on all of the above terms:
+
+ 0 < M,N <= 2^15 2^15 can be imposed by miZeroClipLine
+ 0 <= dx/dy <= 2^16 - 1
+ 0 <= B <= 1
+
+The floor in all of the above equations can be accomplished with a
+simple C divide operation provided that both numerator and denominator
+are positive.
+
+Since dx,dy >= 0 and since moving an X coordinate implies that dx != 0
+and moving a Y coordinate implies dy != 0, we know that the denominators
+are all > 0.
+
+For all lines, (-B) and (B-1) are both either 0 or -1, depending on the
+bias. Thus, we have to show that the 2MNdxy +/- dxy terms are all >= 1
+or > 0 to prove that the numerators are positive (or zero).
+
+For X Major lines we know that dx > 0 and since 2Mdy is >= 0 due to the
+constraints, the first four equations all have numerators >= 0.
+
+For the second four equations, M > 0, so 2Mdy >= 2dy so (2Mdy - dy) >= dy
+So (2Mdy - dy) > 0, since they are Y major lines. Also, (2Mdy + dy) >= 3dy
+or (2Mdy + dy) > 0. So all of their numerators are >= 0.
+
+For the third set of four equations, N > 0, so 2Ndx >= 2dx so (2Ndx - dx)
+>= dx > 0. Similarly (2Ndx + dx) >= 3dx > 0. So all numerators >= 0.
+
+For the fourth set of equations, dy > 0 and 2Ndx >= 0, so all numerators
+are > 0.
+
+To consider overflow, consider the case of 2 * M,N * dx,dy + dx,dy. This
+is bounded <= 2 * 2^15 * (2^16 - 1) + (2^16 - 1)
+ <= 2^16 * (2^16 - 1) + (2^16 - 1)
+ <= 2^32 - 2^16 + 2^16 - 1
+ <= 2^32 - 1
+Since the (-B) and (B-1) terms are all 0 or -1, the maximum value of
+the numerator is therefore (2^32 - 1), which does not overflow an unsigned
+32 bit variable.
+
+*/
+
+#define MIOUTCODES(outcode, x, y, xmin, ymin, xmax, ymax) \
+{\
+ if (x < xmin) outcode |= OUT_LEFT;\
+ if (x > xmax) outcode |= OUT_RIGHT;\
+ if (y < ymin) outcode |= OUT_ABOVE;\
+ if (y > ymax) outcode |= OUT_BELOW;\
+}
+
+/* Bit codes for the terms of the 16 clipping equations defined below. */
+
+#define T_2NDX (1 << 0)
+#define T_2MDY (0) /* implicit term */
+#define T_DXNOTY (1 << 1)
+#define T_DYNOTX (0) /* implicit term */
+#define T_SUBDXORY (1 << 2)
+#define T_ADDDX (T_DXNOTY) /* composite term */
+#define T_SUBDX (T_DXNOTY | T_SUBDXORY) /* composite term */
+#define T_ADDDY (T_DYNOTX) /* composite term */
+#define T_SUBDY (T_DYNOTX | T_SUBDXORY) /* composite term */
+#define T_BIASSUBONE (1 << 3)
+#define T_SUBBIAS (0) /* implicit term */
+#define T_DIV2DX (1 << 4)
+#define T_DIV2DY (0) /* implicit term */
+#define T_ADDONE (1 << 5)
+
+/* Bit masks defining the 16 equations used in miZeroClipLine. */
+
+#define EQN1 (T_2MDY | T_ADDDX | T_SUBBIAS | T_DIV2DX)
+#define EQN1B (T_2MDY | T_ADDDX | T_SUBBIAS | T_DIV2DX)
+#define EQN2 (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX)
+#define EQN2B (T_2MDY | T_ADDDX | T_BIASSUBONE | T_DIV2DX)
+
+#define EQN3 (T_2MDY | T_SUBDY | T_BIASSUBONE | T_DIV2DX | T_ADDONE)
+#define EQN3B (T_2MDY | T_ADDDY | T_BIASSUBONE | T_DIV2DX)
+#define EQN4 (T_2MDY | T_SUBDY | T_SUBBIAS | T_DIV2DX | T_ADDONE)
+#define EQN4B (T_2MDY | T_ADDDY | T_SUBBIAS | T_DIV2DX)
+
+#define EQN5 (T_2NDX | T_SUBDX | T_BIASSUBONE | T_DIV2DY | T_ADDONE)
+#define EQN5B (T_2NDX | T_ADDDX | T_BIASSUBONE | T_DIV2DY)
+#define EQN6 (T_2NDX | T_SUBDX | T_SUBBIAS | T_DIV2DY | T_ADDONE)
+#define EQN6B (T_2NDX | T_ADDDX | T_SUBBIAS | T_DIV2DY)
+
+#define EQN7 (T_2NDX | T_ADDDY | T_SUBBIAS | T_DIV2DY)
+#define EQN7B (T_2NDX | T_ADDDY | T_SUBBIAS | T_DIV2DY)
+#define EQN8 (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY)
+#define EQN8B (T_2NDX | T_ADDDY | T_BIASSUBONE | T_DIV2DY)
+
+/* miZeroClipLine
+ *
+ * returns: 1 for partially clipped line
+ * -1 for completely clipped line
+ *
+ */
+int
+miZeroClipLine(xmin, ymin, xmax, ymax,
+ new_x1, new_y1, new_x2, new_y2,
+ adx, ady,
+ pt1_clipped, pt2_clipped, octant, bias, oc1, oc2)
+ int xmin, ymin, xmax, ymax;
+ int *new_x1, *new_y1, *new_x2, *new_y2;
+ int *pt1_clipped, *pt2_clipped;
+ unsigned int adx, ady;
+ int octant;
+ unsigned int bias;
+ int oc1, oc2;
+{
+ int swapped = 0;
+ int clipDone = 0;
+ CARD32 utmp;
+ int clip1, clip2;
+ int x1, y1, x2, y2;
+ int x1_orig, y1_orig, x2_orig, y2_orig;
+ int xmajor;
+ int negslope, anchorval;
+ unsigned int eqn;
+
+ x1 = x1_orig = *new_x1;
+ y1 = y1_orig = *new_y1;
+ x2 = x2_orig = *new_x2;
+ y2 = y2_orig = *new_y2;
+
+ clip1 = 0;
+ clip2 = 0;
+
+ xmajor = IsXMajorOctant(octant);
+ bias = ((bias >> octant) & 1);
+
+ while (1)
+ {
+ if ((oc1 & oc2) != 0) /* trivial reject */
+ {
+ clipDone = -1;
+ clip1 = oc1;
+ clip2 = oc2;
+ break;
+ }
+ else if ((oc1 | oc2) == 0) /* trivial accept */
+ {
+ clipDone = 1;
+ if (swapped)
+ {
+ SWAPINT_PAIR(x1, y1, x2, y2);
+ SWAPINT(clip1, clip2);
+ }
+ break;
+ }
+ else /* have to clip */
+ {
+ /* only clip one point at a time */
+ if (oc1 == 0)
+ {
+ SWAPINT_PAIR(x1, y1, x2, y2);
+ SWAPINT_PAIR(x1_orig, y1_orig, x2_orig, y2_orig);
+ SWAPINT(oc1, oc2);
+ SWAPINT(clip1, clip2);
+ swapped = !swapped;
+ }
+
+ clip1 |= oc1;
+ if (oc1 & OUT_LEFT)
+ {
+ negslope = IsYDecreasingOctant(octant);
+ utmp = xmin - x1_orig;
+ if (utmp <= 32767) /* clip based on near endpt */
+ {
+ if (xmajor)
+ eqn = (swapped) ? EQN2 : EQN1;
+ else
+ eqn = (swapped) ? EQN4 : EQN3;
+ anchorval = y1_orig;
+ }
+ else /* clip based on far endpt */
+ {
+ utmp = x2_orig - xmin;
+ if (xmajor)
+ eqn = (swapped) ? EQN1B : EQN2B;
+ else
+ eqn = (swapped) ? EQN3B : EQN4B;
+ anchorval = y2_orig;
+ negslope = !negslope;
+ }
+ x1 = xmin;
+ }
+ else if (oc1 & OUT_ABOVE)
+ {
+ negslope = IsXDecreasingOctant(octant);
+ utmp = ymin - y1_orig;
+ if (utmp <= 32767) /* clip based on near endpt */
+ {
+ if (xmajor)
+ eqn = (swapped) ? EQN6 : EQN5;
+ else
+ eqn = (swapped) ? EQN8 : EQN7;
+ anchorval = x1_orig;
+ }
+ else /* clip based on far endpt */
+ {
+ utmp = y2_orig - ymin;
+ if (xmajor)
+ eqn = (swapped) ? EQN5B : EQN6B;
+ else
+ eqn = (swapped) ? EQN7B : EQN8B;
+ anchorval = x2_orig;
+ negslope = !negslope;
+ }
+ y1 = ymin;
+ }
+ else if (oc1 & OUT_RIGHT)
+ {
+ negslope = IsYDecreasingOctant(octant);
+ utmp = x1_orig - xmax;
+ if (utmp <= 32767) /* clip based on near endpt */
+ {
+ if (xmajor)
+ eqn = (swapped) ? EQN2 : EQN1;
+ else
+ eqn = (swapped) ? EQN4 : EQN3;
+ anchorval = y1_orig;
+ }
+ else /* clip based on far endpt */
+ {
+ /*
+ * Technically since the equations can handle
+ * utmp == 32768, this overflow code isn't
+ * needed since X11 protocol can't generate
+ * a line which goes more than 32768 pixels
+ * to the right of a clip rectangle.
+ */
+ utmp = xmax - x2_orig;
+ if (xmajor)
+ eqn = (swapped) ? EQN1B : EQN2B;
+ else
+ eqn = (swapped) ? EQN3B : EQN4B;
+ anchorval = y2_orig;
+ negslope = !negslope;
+ }
+ x1 = xmax;
+ }
+ else if (oc1 & OUT_BELOW)
+ {
+ negslope = IsXDecreasingOctant(octant);
+ utmp = y1_orig - ymax;
+ if (utmp <= 32767) /* clip based on near endpt */
+ {
+ if (xmajor)
+ eqn = (swapped) ? EQN6 : EQN5;
+ else
+ eqn = (swapped) ? EQN8 : EQN7;
+ anchorval = x1_orig;
+ }
+ else /* clip based on far endpt */
+ {
+ /*
+ * Technically since the equations can handle
+ * utmp == 32768, this overflow code isn't
+ * needed since X11 protocol can't generate
+ * a line which goes more than 32768 pixels
+ * below the bottom of a clip rectangle.
+ */
+ utmp = ymax - y2_orig;
+ if (xmajor)
+ eqn = (swapped) ? EQN5B : EQN6B;
+ else
+ eqn = (swapped) ? EQN7B : EQN8B;
+ anchorval = x2_orig;
+ negslope = !negslope;
+ }
+ y1 = ymax;
+ }
+
+ if (swapped)
+ negslope = !negslope;
+
+ utmp <<= 1; /* utmp = 2N or 2M */
+ if (eqn & T_2NDX)
+ utmp = (utmp * adx);
+ else /* (eqn & T_2MDY) */
+ utmp = (utmp * ady);
+ if (eqn & T_DXNOTY)
+ if (eqn & T_SUBDXORY)
+ utmp -= adx;
+ else
+ utmp += adx;
+ else /* (eqn & T_DYNOTX) */
+ if (eqn & T_SUBDXORY)
+ utmp -= ady;
+ else
+ utmp += ady;
+ if (eqn & T_BIASSUBONE)
+ utmp += bias - 1;
+ else /* (eqn & T_SUBBIAS) */
+ utmp -= bias;
+ if (eqn & T_DIV2DX)
+ utmp /= (adx << 1);
+ else /* (eqn & T_DIV2DY) */
+ utmp /= (ady << 1);
+ if (eqn & T_ADDONE)
+ utmp++;
+
+ if (negslope)
+ utmp = -utmp;
+
+ if (eqn & T_2NDX) /* We are calculating X steps */
+ x1 = anchorval + utmp;
+ else /* else, Y steps */
+ y1 = anchorval + utmp;
+
+ oc1 = 0;
+ MIOUTCODES(oc1, x1, y1, xmin, ymin, xmax, ymax);
+ }
+ }
+
+ *new_x1 = x1;
+ *new_y1 = y1;
+ *new_x2 = x2;
+ *new_y2 = y2;
+
+ *pt1_clipped = clip1;
+ *pt2_clipped = clip2;
+
+ return clipDone;
+}
+
+
+/* Draw lineSolid, fillStyle-independent zero width lines.
+ *
+ * Must keep X and Y coordinates in "ints" at least until after they're
+ * translated and clipped to accomodate CoordModePrevious lines with very
+ * large coordinates.
+ *
+ * Draws the same pixels regardless of sign(dx) or sign(dy).
+ *
+ * Ken Whaley
+ *
+ */
+
+/* largest positive value that can fit into a component of a point.
+ * Assumes that the point structure is {type x, y;} where type is
+ * a signed type.
+ */
+#define MAX_COORDINATE ((1 << (((sizeof(DDXPointRec) >> 1) << 3) - 1)) - 1)
+
+#define MI_OUTPUT_POINT(xx, yy)\
+{\
+ if ( !new_span && yy == current_y)\
+ {\
+ if (xx < spans->x)\
+ spans->x = xx;\
+ ++*widths;\
+ }\
+ else\
+ {\
+ ++Nspans;\
+ ++spans;\
+ ++widths;\
+ spans->x = xx;\
+ spans->y = yy;\
+ *widths = 1;\
+ current_y = yy;\
+ new_span = FALSE;\
+ }\
+}
+
+void
+miZeroLine(pDraw, pGC, mode, npt, pptInit)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int mode; /* Origin or Previous */
+ int npt; /* number of points */
+ DDXPointPtr pptInit;
+{
+ int Nspans, current_y;
+ DDXPointPtr ppt;
+ DDXPointPtr pspanInit, spans;
+ int *pwidthInit, *widths, list_len;
+ int xleft, ytop, xright, ybottom;
+ int new_x1, new_y1, new_x2, new_y2;
+ int x, y, x1, y1, x2, y2, xstart, ystart;
+ int oc1, oc2;
+ int result;
+ int pt1_clipped, pt2_clipped = 0;
+ Bool new_span;
+ int signdx, signdy;
+ int clipdx, clipdy;
+ int width, height;
+ int adx, ady;
+ int octant;
+ unsigned int bias = miGetZeroLineBias(pDraw->pScreen);
+ int e, e1, e2, e3; /* Bresenham error terms */
+ int length; /* length of lines == # of pixels on major axis */
+
+ xleft = pDraw->x;
+ ytop = pDraw->y;
+ xright = pDraw->x + pDraw->width - 1;
+ ybottom = pDraw->y + pDraw->height - 1;
+
+ if (!pGC->miTranslate)
+ {
+ /* do everything in drawable-relative coordinates */
+ xleft = 0;
+ ytop = 0;
+ xright -= pDraw->x;
+ ybottom -= pDraw->y;
+ }
+
+ /* it doesn't matter whether we're in drawable or screen coordinates,
+ * FillSpans simply cannot take starting coordinates outside of the
+ * range of a DDXPointRec component.
+ */
+ if (xright > MAX_COORDINATE)
+ xright = MAX_COORDINATE;
+ if (ybottom > MAX_COORDINATE)
+ ybottom = MAX_COORDINATE;
+
+ /* since we're clipping to the drawable's boundaries & coordinate
+ * space boundaries, we're guaranteed that the larger of width/height
+ * is the longest span we'll need to output
+ */
+ width = xright - xleft + 1;
+ height = ybottom - ytop + 1;
+ list_len = (height >= width) ? height : width;
+ pspanInit = (DDXPointPtr)ALLOCATE_LOCAL(list_len * sizeof(DDXPointRec));
+ pwidthInit = (int *)ALLOCATE_LOCAL(list_len * sizeof(int));
+ if (!pspanInit || !pwidthInit)
+ return;
+
+ Nspans = 0;
+ new_span = TRUE;
+ spans = pspanInit - 1;
+ widths = pwidthInit - 1;
+ ppt = pptInit;
+
+ xstart = ppt->x;
+ ystart = ppt->y;
+ if (pGC->miTranslate)
+ {
+ xstart += pDraw->x;
+ ystart += pDraw->y;
+ }
+
+ /* x2, y2, oc2 copied to x1, y1, oc1 at top of loop to simplify
+ * iteration logic
+ */
+ x2 = xstart;
+ y2 = ystart;
+ oc2 = 0;
+ MIOUTCODES(oc2, x2, y2, xleft, ytop, xright, ybottom);
+
+ while (--npt > 0)
+ {
+ if (Nspans > 0)
+ (*pGC->ops->FillSpans)(pDraw, pGC, Nspans, pspanInit,
+ pwidthInit, FALSE);
+ Nspans = 0;
+ new_span = TRUE;
+ spans = pspanInit - 1;
+ widths = pwidthInit - 1;
+
+ x1 = x2;
+ y1 = y2;
+ oc1 = oc2;
+ ++ppt;
+
+ x2 = ppt->x;
+ y2 = ppt->y;
+ if (pGC->miTranslate && (mode != CoordModePrevious))
+ {
+ x2 += pDraw->x;
+ y2 += pDraw->y;
+ }
+ else if (mode == CoordModePrevious)
+ {
+ x2 += x1;
+ y2 += y1;
+ }
+
+ oc2 = 0;
+ MIOUTCODES(oc2, x2, y2, xleft, ytop, xright, ybottom);
+
+ CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);
+
+ if (adx > ady)
+ {
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ length = adx; /* don't draw endpoint in main loop */
+
+ FIXUP_ERROR(e, octant, bias);
+
+ new_x1 = x1;
+ new_y1 = y1;
+ new_x2 = x2;
+ new_y2 = y2;
+ pt1_clipped = 0;
+ pt2_clipped = 0;
+
+ if ((oc1 | oc2) != 0)
+ {
+ result = miZeroClipLine(xleft, ytop, xright, ybottom,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady,
+ &pt1_clipped, &pt2_clipped,
+ octant, bias, oc1, oc2);
+ if (result == -1)
+ continue;
+
+ length = abs(new_x2 - new_x1);
+
+ /* if we've clipped the endpoint, always draw the full length
+ * of the segment, because then the capstyle doesn't matter
+ */
+ if (pt2_clipped)
+ length++;
+
+ if (pt1_clipped)
+ {
+ /* must calculate new error terms */
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ e += (clipdy * e2) + ((clipdx - clipdy) * e1);
+ }
+ }
+
+ /* draw the segment */
+
+ x = new_x1;
+ y = new_y1;
+
+ e3 = e2 - e1;
+ e = e - e1;
+
+ while (length--)
+ {
+ MI_OUTPUT_POINT(x, y);
+ e += e1;
+ if (e >= 0)
+ {
+ y += signdy;
+ e += e3;
+ }
+ x += signdx;
+ }
+ }
+ else /* Y major line */
+ {
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ length = ady; /* don't draw endpoint in main loop */
+
+ SetYMajorOctant(octant);
+ FIXUP_ERROR(e, octant, bias);
+
+ new_x1 = x1;
+ new_y1 = y1;
+ new_x2 = x2;
+ new_y2 = y2;
+ pt1_clipped = 0;
+ pt2_clipped = 0;
+
+ if ((oc1 | oc2) != 0)
+ {
+ result = miZeroClipLine(xleft, ytop, xright, ybottom,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady,
+ &pt1_clipped, &pt2_clipped,
+ octant, bias, oc1, oc2);
+ if (result == -1)
+ continue;
+
+ length = abs(new_y2 - new_y1);
+
+ /* if we've clipped the endpoint, always draw the full length
+ * of the segment, because then the capstyle doesn't matter
+ */
+ if (pt2_clipped)
+ length++;
+
+ if (pt1_clipped)
+ {
+ /* must calculate new error terms */
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+ e += (clipdx * e2) + ((clipdy - clipdx) * e1);
+ }
+ }
+
+ /* draw the segment */
+
+ x = new_x1;
+ y = new_y1;
+
+ e3 = e2 - e1;
+ e = e - e1;
+
+ while (length--)
+ {
+ MI_OUTPUT_POINT(x, y);
+ e += e1;
+ if (e >= 0)
+ {
+ x += signdx;
+ e += e3;
+ }
+ y += signdy;
+ }
+ }
+ }
+
+ /* only do the capnotlast check on the last segment
+ * and only if the endpoint wasn't clipped. And then, if the last
+ * point is the same as the first point, do not draw it, unless the
+ * line is degenerate
+ */
+ if ( (! pt2_clipped) && (pGC->capStyle != CapNotLast) &&
+ (((xstart != x2) || (ystart != y2)) || (ppt == pptInit + 1)))
+ {
+ MI_OUTPUT_POINT(x, y);
+ }
+
+ if (Nspans > 0)
+ (*pGC->ops->FillSpans)(pDraw, pGC, Nspans, pspanInit,
+ pwidthInit, FALSE);
+
+ DEALLOCATE_LOCAL(pwidthInit);
+ DEALLOCATE_LOCAL(pspanInit);
+}
+
+void
+miZeroDashLine(dst, pgc, mode, nptInit, pptInit)
+DrawablePtr dst;
+GCPtr pgc;
+int mode;
+int nptInit; /* number of points in polyline */
+DDXPointRec *pptInit; /* points in the polyline */
+{
+ /* XXX kludge until real zero-width dash code is written */
+ pgc->lineWidth = 1;
+ miWideDash (dst, pgc, mode, nptInit, pptInit);
+ pgc->lineWidth = 0;
+}
diff --git a/xc/programs/Xserver/os/Imakefile b/xc/programs/Xserver/os/Imakefile
new file mode 100644
index 000000000..cf060c60a
--- /dev/null
+++ b/xc/programs/Xserver/os/Imakefile
@@ -0,0 +1,157 @@
+XCOMM $TOG: Imakefile /main/85 1997/12/07 18:26:23 kaleb $
+XCOMM $XFree86: xc/programs/Xserver/os/Imakefile,v 3.25 1999/07/10 14:42:56 dawes Exp $
+#include <Server.tmpl>
+
+/*
+ * If you have any extra files to be put into the library, define them here.
+ */
+
+#ifdef HPArchitecture
+#define OtherSources hpsocket.c
+#define OtherObjects hpsocket.o
+#endif
+
+#ifdef AmoebaArchitecture
+#define OtherSources iopreader.c
+#define OtherObjects iopreader.o
+#endif
+
+/*
+ * do not modify the following two definitions
+ */
+
+#ifndef OtherSources
+#define OtherSources
+#endif
+
+#ifndef OtherObjects
+#define OtherObjects
+#endif
+
+#if HasXdmAuth
+XDMAUTHDEFS = -DHASXDMAUTH
+XDMAUTHOBJS = xdmauth.o
+XDMAUTHSRCS = xdmauth.c
+#else
+XDMAUTHDEFS =
+XDMAUTHOBJS =
+XDMAUTHSCRS =
+#endif
+
+#if HasSecureRPC
+RPCDEFS = -DSECURE_RPC
+RPCOBJS = rpcauth.o
+RPCSRCS = rpcauth.c
+#else
+RPCDEFS =
+RPCOBJS =
+RPCSRCS =
+#endif
+
+#if HasKrb5
+KRB5OBJS = k5auth.o k5encode.o
+KRB5SRCS = k5auth.c k5encode.c
+#endif
+
+#if HasBSD44Sockets
+ SOCK_DEFINES = -DBSD44SOCKETS
+#endif
+
+#if BuildLBX
+ LBX_SRCS = lbxio.c
+ LBX_OBJS = lbxio.o
+#else
+ LBX_SRCS =
+ LBX_OBJS =
+#endif
+
+BOOTSTRAPCFLAGS =
+ SRCS = WaitFor.c access.c connection.c io.c oscolor.c \
+ osinit.c utils.c auth.c mitauth.c secauth.c $(XDMAUTHSRCS) \
+ $(RPCSRCS) $(KRB5SRCS) xdmcp.c decompress.c OtherSources \
+ transport.c xalloc.c $(LBX_SRCS)
+ OBJS = WaitFor.o access.o connection.o io.o oscolor.o \
+ osinit.o utils.o auth.o mitauth.o secauth.o $(XDMAUTHOBJS) \
+ $(RPCOBJS) $(KRB5OBJS) xdmcp.o decompress.o OtherObjects \
+ transport.o xalloc.o $(LBX_OBJS)
+
+#if SpecialMalloc
+ MEM_DEFINES = -DSPECIAL_MALLOC
+#endif /* SpecialMalloc */
+#if UseInternalMalloc
+ MEM_DEFINES = -DINTERNAL_MALLOC
+#endif
+#if UseMemLeak
+ MEM_DEFINES = -DMEMBUG
+#endif
+#if UseRgbTxt
+ RGB_DEFINES = -DUSE_RGB_TXT
+#endif
+ DBM_DEFINES = NdbmDefines
+ ADM_DEFINES = -DADMPATH=\"$(ADMDIR)/X\%smsgs\"
+ EXT_DEFINES = ExtensionDefines
+ XDMCP_DEFINES = ServerXdmcpDefines
+ OS_DEFINES = ServerOSDefines
+ KRB5_DEFINES = Krb5Defines
+ XALLOC_DEFINES = XallocDefines
+ ERROR_DEFINES = ServerErrorDefines
+ DEFINES = -DXSERV_t -DTRANS_SERVER $(CONNECTION_FLAGS) $(MEM_DEFINES) $(XDMAUTHDEFS) $(RPCDEFS) $(SIGNAL_DEFINES) $(OS_DEFINES) $(KRB5_DEFINES) $(RGB_DEFINES)
+ INCLUDES = -I. -I../include -I$(XINCLUDESRC) -I$(EXTINCSRC) -I$(TOP)/lib/Xau -I../lbx Krb5Includes
+ DEPEND_DEFINES = $(DBM_DEFINES) $(XDMCP_DEFINES) $(EXT_DEFINES) $(TRANS_INCLUDES) $(CONNECTION_FLAGS)
+ LINTLIBS = ../dix/llib-ldix.ln
+
+#ifdef NEED_ALLOCA_FROM_LIBPW
+ PWLIB = /lib/libPW.a
+#endif /* NEED_ALLOCA_FROM_LIBPW */
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(os,$(OBJS))
+LintLibraryTarget(os,$(SRCS))
+NormalLintTarget($(SRCS))
+
+#ifdef NEED_ALLOCA_FROM_LIBPW
+XCOMM
+XCOMM And this one is to get the version of alloca that lives in /lib/libPW.a
+XCOMM without getting all of the rest of the stuff in there.
+XCOMM
+alloca.o: $(PWLIB)
+ rm -f alloca.o
+ ar x $(PWLIB) alloca.o
+#endif /* NEED_ALLOCA_FROM_LIBPW */
+
+SpecialCObjectRule(access,$(ICONFIGFILES),$(XDMCP_DEFINES) $(SOCK_DEFINES))
+SpecialCObjectRule(auth,$(ICONFIGFILES),$(XDMCP_DEFINES))
+SpecialCObjectRule(xdmauth,$(ICONFIGFILES),$(XDMCP_DEFINES))
+SpecialCObjectRule(xdmcp,$(ICONFIGFILES),$(SOCK_DEFINES) $(XDMCP_DEFINES))
+SpecialCObjectRule(connection,$(ICONFIGFILES),$(SOCK_DEFINES) $(XDMCP_DEFINES))
+SpecialCObjectRule(transport,$(ICONFIGFILES),$(TRANS_INCLUDES) $(CONN_DEFINES) $(SOCK_DEFINES))
+LinkSourceFile(transport.c,$(TRANSCOMMSRC))
+SpecialCObjectRule(osinit,$(ICONFIGFILES),$(ADM_DEFINES))
+SpecialCObjectRule(WaitFor,$(ICONFIGFILES),$(EXT_DEFINES))
+SpecialCObjectRule(io,$(ICONFIGFILES),$(EXT_DEFINES))
+#if BuildLBX
+SpecialCObjectRule(lbxio,$(ICONFIGFILES),$(EXT_DEFINES))
+#endif
+SpecialCObjectRule(utils,$(ICONFIGFILES),$(XDMCP_DEFINES) $(EXT_DEFINES) $(ERROR_DEFINES))
+SpecialCObjectRule(xalloc,$(ICONFIGFILES),$(XALLOC_DEFINES))
+#if defined(SparcArchitecture) && HasGcc && !HasGcc2
+oscolor.o: oscolor.c $(ICONFIGFILES)
+ $(RM) $@
+ cc -c $(DBM_DEFINES) $(CDEBUGFLAGS) $(ALLDEFINES) $*.c
+#else
+SpecialCObjectRule(oscolor,$(ICONFIGFILES),$(DBM_DEFINES))
+#endif
+
+#if HasKrb5
+LinkSourceFile(k5encode.c,$(XAUTHSRC))
+#endif
+
+#if DoLoadableServer
+AllTarget(libcwrapper.o)
+ObjectFromSpecialSource(libcwrapper,$(XF86OSSRC)/shared/libc_wrapper,-DSELF_CONTAINED_WRAPPER)
+#if !HasSnprintf
+LinkSourceFile(snprintf.c,$(LIBSRC)/misc)
+#endif
+#endif
+
+DependTarget()
diff --git a/xc/programs/Xserver/os/WaitFor.c b/xc/programs/Xserver/os/WaitFor.c
new file mode 100644
index 000000000..b9105fc93
--- /dev/null
+++ b/xc/programs/Xserver/os/WaitFor.c
@@ -0,0 +1,773 @@
+/* $XFree86: xc/programs/Xserver/os/WaitFor.c,v 3.22 1999/04/18 13:49:10 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+/* $TOG: WaitFor.c /main/58 1998/02/09 15:13:07 kaleb $ */
+
+/*****************************************************************
+ * OS Dependent input routines:
+ *
+ * WaitForSomething
+ * TimerForce, TimerSet, TimerCheck, TimerFree
+ *
+ *****************************************************************/
+
+#ifdef WIN32
+#include <X11/Xwinsock.h>
+#endif
+#include "Xos.h" /* for strings, fcntl, time */
+
+#include <errno.h>
+#ifdef X_NOT_STDC_ENV
+extern int errno;
+#endif
+
+#include <stdio.h>
+#include "X.h"
+#include "misc.h"
+
+#ifdef MINIX
+#include <sys/nbio.h>
+#define select(n,r,w,x,t) nbio_select(n,r,w,x,t)
+#endif
+#ifdef __EMX__
+#define select(n,r,w,x,t) os2PseudoSelect(n,r,w,x,t)
+#endif
+#include <X11/Xpoll.h>
+#include "osdep.h"
+#include "dixstruct.h"
+#include "opaque.h"
+
+/* modifications by raphael */
+int
+mffs(fd_mask mask)
+{
+ int i;
+
+ if (!mask) return 0;
+ i = 1;
+ while (!(mask & 1))
+ {
+ i++;
+ mask >>= 1;
+ }
+ return i;
+}
+
+#ifdef DPMSExtension
+#define DPMS_SERVER
+#include "dpms.h"
+extern void DPMSSet();
+#endif
+
+#ifdef XTESTEXT1
+/*
+ * defined in xtestext1dd.c
+ */
+extern int playback_on;
+#endif /* XTESTEXT1 */
+
+struct _OsTimerRec {
+ OsTimerPtr next;
+ CARD32 expires;
+ OsTimerCallback callback;
+ pointer arg;
+};
+
+static void DoTimer();
+static OsTimerPtr timers;
+
+/*****************
+ * WaitForSomething:
+ * Make the server suspend until there is
+ * 1. data from clients or
+ * 2. input events available or
+ * 3. ddx notices something of interest (graphics
+ * queue ready, etc.) or
+ * 4. clients that have buffered replies/events are ready
+ *
+ * If the time between INPUT events is
+ * greater than ScreenSaverTime, the display is turned off (or
+ * saved, depending on the hardware). So, WaitForSomething()
+ * has to handle this also (that's why the select() has a timeout.
+ * For more info on ClientsWithInput, see ReadRequestFromClient().
+ * pClientsReady is an array to store ready client->index values into.
+ *****************/
+
+static INT32 timeTilFrob = 0; /* while screen saving */
+
+#if !defined(AMOEBA)
+
+int
+WaitForSomething(pClientsReady)
+ int *pClientsReady;
+{
+ int i;
+ struct timeval waittime, *wt;
+ INT32 timeout;
+#ifdef DPMSExtension
+ INT32 standbyTimeout, suspendTimeout, offTimeout;
+#endif
+ fd_set clientsReadable;
+ fd_set clientsWritable;
+ int curclient;
+ int selecterr;
+ int nready;
+ fd_set devicesReadable;
+ CARD32 now;
+
+ FD_ZERO(&clientsReadable);
+
+ /* We need a while loop here to handle
+ crashed connections and the screen saver timeout */
+ while (1)
+ {
+ /* deal with any blocked jobs */
+ if (workQueue)
+ ProcessWorkQueue();
+
+ if (XFD_ANYSET (&ClientsWithInput))
+ {
+ XFD_COPYSET (&ClientsWithInput, &clientsReadable);
+ break;
+ }
+#ifdef DPMSExtension
+ if (ScreenSaverTime > 0 || DPMSEnabled || timers)
+#else
+ if (ScreenSaverTime > 0 || timers)
+#endif
+ now = GetTimeInMillis();
+ wt = NULL;
+ if (timers)
+ {
+ while (timers && timers->expires <= now)
+ DoTimer(timers, now, &timers);
+ if (timers)
+ {
+ timeout = timers->expires - now;
+ waittime.tv_sec = timeout / MILLI_PER_SECOND;
+ waittime.tv_usec = (timeout % MILLI_PER_SECOND) *
+ (1000000 / MILLI_PER_SECOND);
+ wt = &waittime;
+ }
+ }
+ if (ScreenSaverTime > 0
+#ifdef DPMSExtension
+ || (DPMSEnabled &&
+ (DPMSStandbyTime > 0 || DPMSSuspendTime > 0 || DPMSOffTime > 0))
+#endif
+ ) {
+#ifdef DPMSExtension
+ if (ScreenSaverTime > 0)
+#endif
+ timeout = (ScreenSaverTime -
+ (now - lastDeviceEventTime.milliseconds));
+#ifdef DPMSExtension
+ if (DPMSStandbyTime > 0)
+ standbyTimeout = (DPMSStandbyTime -
+ (now - lastDeviceEventTime.milliseconds));
+ if (DPMSSuspendTime > 0)
+ suspendTimeout = (DPMSSuspendTime -
+ (now - lastDeviceEventTime.milliseconds));
+ if (DPMSOffTime > 0)
+ offTimeout = (DPMSOffTime -
+ (now - lastDeviceEventTime.milliseconds));
+#endif /* DPMSExtension */
+
+ if (timeout <= 0
+#ifdef DPMSExtension
+ && ScreenSaverTime > 0
+#endif /* DPMSExtension */
+ ) {
+ INT32 timeSinceSave;
+
+ timeSinceSave = -timeout;
+ if (timeSinceSave >= timeTilFrob && timeTilFrob >= 0)
+ {
+ ResetOsBuffers(); /* not ideal, but better than nothing */
+ SaveScreens(SCREEN_SAVER_ON, ScreenSaverActive);
+#ifdef DPMSExtension
+ if (ScreenSaverInterval > 0 &&
+ DPMSPowerLevel == DPMSModeOn)
+#else
+ if (ScreenSaverInterval)
+#endif /* DPMSExtension */
+ /* round up to the next ScreenSaverInterval */
+ timeTilFrob = ScreenSaverInterval *
+ ((timeSinceSave + ScreenSaverInterval) /
+ ScreenSaverInterval);
+ else
+ timeTilFrob = -1;
+ }
+ timeout = timeTilFrob - timeSinceSave;
+ }
+ else
+ {
+ if (ScreenSaverTime > 0 && timeout > ScreenSaverTime)
+ timeout = ScreenSaverTime;
+ timeTilFrob = 0;
+ }
+#ifdef DPMSExtension
+ if (DPMSEnabled)
+ {
+ if (standbyTimeout > 0
+ && (timeout <= 0 || timeout > standbyTimeout))
+ timeout = standbyTimeout;
+ if (suspendTimeout > 0
+ && (timeout <= 0 || timeout > suspendTimeout))
+ timeout = suspendTimeout;
+ if (offTimeout > 0
+ && (timeout <= 0 || timeout > offTimeout))
+ timeout = offTimeout;
+ }
+#endif
+ if (timeout > 0 && (!wt || timeout < (timers->expires - now)))
+ {
+ waittime.tv_sec = timeout / MILLI_PER_SECOND;
+ waittime.tv_usec = (timeout % MILLI_PER_SECOND) *
+ (1000000 / MILLI_PER_SECOND);
+ wt = &waittime;
+ }
+#ifdef DPMSExtension
+ /* don't bother unless it's switched on */
+ if (DPMSEnabled) {
+ /*
+ * If this mode's enabled, and if the time's come
+ * and if we're still at a lesser mode, do it now.
+ */
+ if (DPMSStandbyTime > 0) {
+ if (standbyTimeout <= 0) {
+ if (DPMSPowerLevel < DPMSModeStandby) {
+ DPMSSet(DPMSModeStandby);
+ }
+ }
+ }
+ /*
+ * and ditto. Note that since these modes can have the
+ * same timeouts, they can happen at the same time.
+ */
+ if (DPMSSuspendTime > 0) {
+ if (suspendTimeout <= 0) {
+ if (DPMSPowerLevel < DPMSModeSuspend) {
+ DPMSSet(DPMSModeSuspend);
+ }
+ }
+ }
+ if (DPMSOffTime > 0) {
+ if (offTimeout <= 0) {
+ if (DPMSPowerLevel < DPMSModeOff) {
+ DPMSSet(DPMSModeOff);
+ }
+ }
+ }
+ }
+#endif
+ }
+ XFD_COPYSET(&AllSockets, &LastSelectMask);
+ BlockHandler((pointer)&wt, (pointer)&LastSelectMask);
+ if (NewOutputPending)
+ FlushAllOutput();
+#ifdef XTESTEXT1
+ /* XXX how does this interact with new write block handling? */
+ if (playback_on) {
+ wt = &waittime;
+ XTestComputeWaitTime (&waittime);
+ }
+#endif /* XTESTEXT1 */
+ /* keep this check close to select() call to minimize race */
+ if (dispatchException)
+ i = -1;
+ else if (AnyClientsWriteBlocked)
+ {
+ XFD_COPYSET(&ClientsWriteBlocked, &clientsWritable);
+ i = Select (MaxClients, &LastSelectMask, &clientsWritable, NULL, wt);
+ }
+ else
+ i = Select (MaxClients, &LastSelectMask, NULL, NULL, wt);
+ selecterr = errno;
+ WakeupHandler(i, (pointer)&LastSelectMask);
+#ifdef XTESTEXT1
+ if (playback_on) {
+ i = XTestProcessInputAction (i, &waittime);
+ }
+#endif /* XTESTEXT1 */
+ if (i <= 0) /* An error or timeout occurred */
+ {
+
+ if (dispatchException)
+ return 0;
+ FD_ZERO(&clientsWritable);
+ if (i < 0)
+ if (selecterr == EBADF) /* Some client disconnected */
+ {
+ CheckConnections ();
+ if (! XFD_ANYSET (&AllClients))
+ return 0;
+ }
+ else if (selecterr == EINVAL)
+ {
+ FatalError("WaitForSomething(): select: errno=%d\n",
+ selecterr);
+ }
+ else if (selecterr != EINTR)
+ {
+ ErrorF("WaitForSomething(): select: errno=%d\n",
+ selecterr);
+ }
+ if (timers)
+ {
+ now = GetTimeInMillis();
+ while (timers && timers->expires <= now)
+ DoTimer(timers, now, &timers);
+ }
+ if (*checkForInput[0] != *checkForInput[1])
+ return 0;
+ }
+ else
+ {
+ fd_set tmp_set;
+ if (AnyClientsWriteBlocked && XFD_ANYSET (&clientsWritable))
+ {
+ NewOutputPending = TRUE;
+ XFD_ORSET(&OutputPending, &clientsWritable, &OutputPending);
+ XFD_UNSET(&ClientsWriteBlocked, &clientsWritable);
+ if (! XFD_ANYSET(&ClientsWriteBlocked))
+ AnyClientsWriteBlocked = FALSE;
+ }
+
+ XFD_ANDSET(&devicesReadable, &LastSelectMask, &EnabledDevices);
+ XFD_ANDSET(&clientsReadable, &LastSelectMask, &AllClients);
+ XFD_ANDSET(&tmp_set, &LastSelectMask, &WellKnownConnections);
+ if (XFD_ANYSET(&tmp_set))
+ QueueWorkProc(EstablishNewConnections, NULL,
+ (pointer)&LastSelectMask);
+#ifdef DPMSExtension
+ if (XFD_ANYSET (&devicesReadable) && (DPMSPowerLevel != DPMSModeOn))
+ DPMSSet(DPMSModeOn);
+#endif
+ if (XFD_ANYSET (&devicesReadable) || XFD_ANYSET (&clientsReadable))
+ break;
+ }
+ }
+
+ nready = 0;
+ if (XFD_ANYSET (&clientsReadable))
+ {
+#ifndef WIN32
+ for (i=0; i<howmany(XFD_SETSIZE, NFDBITS); i++)
+ {
+ int highest_priority;
+
+ while (clientsReadable.fds_bits[i])
+ {
+ int client_priority, client_index;
+
+ curclient = ffs (clientsReadable.fds_bits[i]) - 1;
+ client_index = /* raphael: modified */
+ ConnectionTranslation[curclient + (i * (sizeof(fd_mask) * 8))];
+#else
+ int highest_priority;
+ fd_set savedClientsReadable;
+ XFD_COPYSET(&clientsReadable, &savedClientsReadable);
+ for (i = 0; i < XFD_SETCOUNT(&savedClientsReadable); i++)
+ {
+ int client_priority, client_index;
+
+ curclient = XFD_FD(&savedClientsReadable, i);
+ client_index = ConnectionTranslation[curclient];
+#endif
+#ifdef XSYNC
+ /* We implement "strict" priorities.
+ * Only the highest priority client is returned to
+ * dix. If multiple clients at the same priority are
+ * ready, they are all returned. This means that an
+ * aggressive client could take over the server.
+ * This was not considered a big problem because
+ * aggressive clients can hose the server in so many
+ * other ways :)
+ */
+ client_priority = clients[client_index]->priority;
+ if (nready == 0 || client_priority > highest_priority)
+ {
+ /* Either we found the first client, or we found
+ * a client whose priority is greater than all others
+ * that have been found so far. Either way, we want
+ * to initialize the list of clients to contain just
+ * this client.
+ */
+ pClientsReady[0] = client_index;
+ highest_priority = client_priority;
+ nready = 1;
+ }
+ /* the following if makes sure that multiple same-priority
+ * clients get batched together
+ */
+ else if (client_priority == highest_priority)
+#endif
+ {
+ pClientsReady[nready++] = client_index;
+ }
+#ifndef WIN32
+ clientsReadable.fds_bits[i] &= ~(((fd_mask)1L) << curclient);
+ }
+#else
+ FD_CLR(curclient, &clientsReadable);
+#endif
+ }
+ }
+ return nready;
+}
+
+#if 0
+/*
+ * This is not always a macro.
+ */
+ANYSET(src)
+ FdMask *src;
+{
+ int i;
+
+ for (i=0; i<mskcnt; i++)
+ if (src[ i ])
+ return (TRUE);
+ return (FALSE);
+}
+#endif
+
+#else /* AMOEBA */
+
+#define dbprintf(list) /* printf list */
+
+int
+WaitForSomething(pClientsReady)
+ int *pClientsReady;
+{
+ register int i, wt, nt;
+ struct timeval *wtp;
+ long alwaysCheckForInput[2];
+ int nready;
+ int timeout;
+ unsigned long now;
+
+ WakeupInitWaiters();
+
+ /* Be sure to check for input on every sweep in the dispatcher.
+ * This routine should be in InitInput, but since this is more
+ * or less a device dependent routine, and the semantics of it
+ * are device independent I decided to put it here.
+ */
+ alwaysCheckForInput[0] = 0;
+ alwaysCheckForInput[1] = 1;
+ SetInputCheck(&alwaysCheckForInput[0], &alwaysCheckForInput[1]);
+
+ while (1) {
+ /* deal with any blocked jobs */
+ if (workQueue)
+ ProcessWorkQueue();
+
+ if (ANYSET(ClientsWithInput)) {
+ FdSet clientsReadable;
+ int highest_priority;
+
+ COPYBITS(ClientsWithInput, clientsReadable);
+ dbprintf(("WaitFor: "));
+ nready = 0;
+ for (i=0; i < mskcnt; i++) {
+ while (clientsReadable[i]) {
+ int client_priority, curclient, client_index;
+
+ curclient = ffs (clientsReadable[i]) - 1;
+ client_index = ConnectionTranslation[curclient + (i * (sizeof(fd_mask)*8))];
+ dbprintf(("%d has input\n", curclient));
+#ifdef XSYNC
+ client_priority = clients[client_index]->priority;
+ if (nready == 0 || client_priority > highest_priority)
+ {
+ pClientsReady[0] = client_index;
+ highest_priority = client_priority;
+ nready = 1;
+ }
+ else if (client_priority == highest_priority)
+#endif
+ {
+ pClientsReady[nready++] = client_index;
+ }
+ clientsReadable[i] &= ~(((FdMask)1L) << curclient);
+ }
+ }
+ break;
+ }
+
+ wt = -1;
+ now = GetTimeInMillis();
+ if (timers)
+ {
+ while (timers && timers->expires <= now)
+ DoTimer(timers, now, &timers);
+ if (timers)
+ {
+ timeout = timers->expires - now;
+ wt = timeout;
+ }
+ }
+ if (ScreenSaverTime) {
+ timeout = ScreenSaverTime - TimeSinceLastInputEvent();
+ if (timeout <= 0) { /* may be forced by AutoResetServer() */
+ long timeSinceSave;
+
+ timeSinceSave = -timeout;
+ if ((timeSinceSave >= timeTilFrob) && (timeTilFrob >= 0)) {
+ SaveScreens(SCREEN_SAVER_ON, ScreenSaverActive);
+ if (ScreenSaverInterval)
+ /* round up to the next ScreenSaverInterval */
+ timeTilFrob = ScreenSaverInterval *
+ ((timeSinceSave + ScreenSaverInterval) /
+ ScreenSaverInterval);
+ else
+ timeTilFrob = -1;
+ }
+ timeout = timeTilFrob - timeSinceSave;
+ } else {
+ if (timeout > ScreenSaverTime)
+ timeout = ScreenSaverTime;
+ timeTilFrob = 0;
+ }
+
+ if (wt < 0 || (timeTilFrob >= 0 && wt > timeout)) {
+ wt = timeout;
+ }
+ }
+
+ /* Check for new clients. We do this here and not in the listener
+ * threads because we cannot be sure that dix is re-entrant, and
+ * we need to call some dix routines during startup.
+ */
+ if (nNewConns) {
+ QueueWorkProc(EstablishNewConnections, NULL,
+ (pointer) 0);
+ }
+
+ /* Call device dependent block handlers, which may want to
+ * specify a different timeout (e.g. used for key auto-repeat).
+ */
+ wtp = (struct timeval *) NULL;
+ BlockHandler((pointer)&wtp, (pointer)NULL);
+ if (wtp) wt = (wtp->tv_sec * 1000) + (wtp->tv_usec / 1000);
+
+ if (NewOutputPending)
+ FlushAllOutput();
+
+ /* TODO: XTESTEXT1 */
+
+ nready = AmFindReadyClients(pClientsReady, AllSockets);
+
+ /* If we found some work, or the iop server has us informed about
+ * new device events, we return.
+ */
+ if (nready || AmoebaEventsAvailable())
+ break;
+
+ if (dispatchException)
+ return 0;
+
+ /* Nothing interesting is available. Go to sleep with a timeout.
+ * The other threads will wake us when needed.
+ */
+ i = SleepMainThread(wt);
+
+ /* Wake up any of the sleeping handlers */
+ WakeupHandler((unsigned long)0, (pointer)NULL);
+
+ /* TODO: XTESTEXT1 */
+
+ if (dispatchException)
+ return 0;
+
+ if (i == -1) {
+ /* An error or timeout occurred */
+ return 0;
+ }
+ }
+
+ dbprintf(("WaitForSomething: %d clients ready\n", nready));
+ return nready;
+}
+
+#endif /* AMOEBA */
+
+
+static void
+DoTimer(timer, now, prev)
+ register OsTimerPtr timer;
+ CARD32 now;
+ OsTimerPtr *prev;
+{
+ CARD32 newTime;
+
+ *prev = timer->next;
+ timer->next = NULL;
+ newTime = (*timer->callback)(timer, now, timer->arg);
+ if (newTime)
+ TimerSet(timer, 0, newTime, timer->callback, timer->arg);
+}
+
+OsTimerPtr
+TimerSet(timer, flags, millis, func, arg)
+ register OsTimerPtr timer;
+ int flags;
+ CARD32 millis;
+ OsTimerCallback func;
+ pointer arg;
+{
+ register OsTimerPtr *prev;
+ CARD32 now = GetTimeInMillis();
+
+ if (!timer)
+ {
+ timer = (OsTimerPtr)xalloc(sizeof(struct _OsTimerRec));
+ if (!timer)
+ return NULL;
+ }
+ else
+ {
+ for (prev = &timers; *prev; prev = &(*prev)->next)
+ {
+ if (*prev == timer)
+ {
+ *prev = timer->next;
+ if (flags & TimerForceOld)
+ (void)(*timer->callback)(timer, now, timer->arg);
+ break;
+ }
+ }
+ }
+ if (!millis)
+ return timer;
+ if (!(flags & TimerAbsolute))
+ millis += now;
+ timer->expires = millis;
+ timer->callback = func;
+ timer->arg = arg;
+ if (millis <= now)
+ {
+ timer->next = NULL;
+ millis = (*timer->callback)(timer, now, timer->arg);
+ if (!millis)
+ return timer;
+ }
+ for (prev = &timers;
+ *prev && millis > (*prev)->expires;
+ prev = &(*prev)->next)
+ ;
+ timer->next = *prev;
+ *prev = timer;
+ return timer;
+}
+
+Bool
+TimerForce(timer)
+ register OsTimerPtr timer;
+{
+ register OsTimerPtr *prev;
+ register CARD32 newTime;
+
+ for (prev = &timers; *prev; prev = &(*prev)->next)
+ {
+ if (*prev == timer)
+ {
+ DoTimer(timer, GetTimeInMillis(), prev);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+void
+TimerCancel(timer)
+ register OsTimerPtr timer;
+{
+ register OsTimerPtr *prev;
+
+ if (!timer)
+ return;
+ for (prev = &timers; *prev; prev = &(*prev)->next)
+ {
+ if (*prev == timer)
+ {
+ *prev = timer->next;
+ break;
+ }
+ }
+}
+
+void
+TimerFree(timer)
+ register OsTimerPtr timer;
+{
+ if (!timer)
+ return;
+ TimerCancel(timer);
+ xfree(timer);
+}
+
+void
+TimerCheck()
+{
+ register CARD32 now = GetTimeInMillis();
+
+ while (timers && timers->expires <= now)
+ DoTimer(timers, now, &timers);
+}
+
+void
+TimerInit()
+{
+ OsTimerPtr timer;
+
+ while (timer = timers)
+ {
+ timers = timer->next;
+ xfree(timer);
+ }
+}
diff --git a/xc/programs/Xserver/os/access.c b/xc/programs/Xserver/os/access.c
new file mode 100644
index 000000000..df6106779
--- /dev/null
+++ b/xc/programs/Xserver/os/access.c
@@ -0,0 +1,1405 @@
+/* $TOG: access.c /main/72 1998/04/22 16:31:03 msr $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/os/access.c,v 3.30 1999/07/18 03:27:03 dawes Exp $ */
+
+#ifdef WIN32
+#include <X11/Xwinsock.h>
+#endif
+
+#include <stdio.h>
+#include <X11/Xtrans.h>
+#include <X11/Xauth.h>
+#include <X.h>
+#include <Xproto.h>
+#include "misc.h"
+#include "site.h"
+#include <errno.h>
+#include <sys/types.h>
+#ifndef WIN32
+#if !defined(AMOEBA) && !defined(MINIX)
+#ifdef ESIX
+#include <lan/socket.h>
+#else
+#ifndef Lynx
+#include <sys/socket.h>
+#else
+#include <socket.h>
+#endif
+#endif
+#include <sys/ioctl.h>
+#else
+#ifdef AMOEBA
+#define port am_port_t
+#include <amoeba.h>
+#include <cmdreg.h>
+#include <stdcom.h>
+#include <stderr.h>
+#include <ampolicy.h>
+#include <server/ip/hton.h>
+#include <server/ip/types.h>
+#include <server/ip/tcpip.h>
+#include <server/ip/tcp_io.h>
+#include <server/ip/gen/in.h>
+#include <server/ip/gen/tcp.h>
+#include <server/ip/gen/tcp_io.h>
+#include <server/ip/gen/socket.h>
+#undef port
+#endif
+#endif /* AMOEBA || MINIX */
+#include <ctype.h>
+
+#if defined(TCPCONN) || defined(STREAMSCONN) || defined(ISC) || defined(SCO)
+#include <netinet/in.h>
+#endif /* TCPCONN || STREAMSCONN || ISC || SCO */
+#ifdef DNETCONN
+#include <netdnet/dn.h>
+#include <netdnet/dnetdb.h>
+#endif
+
+
+#if defined(DGUX)
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <ctype.h>
+#include <sys/utsname.h>
+#include <sys/stream.h>
+#include <sys/stropts.h>
+#include <sys/param.h>
+#include <sys/sockio.h>
+#endif
+
+
+#if !defined(AMOEBA)
+#ifdef hpux
+# include <sys/utsname.h>
+# ifdef HAS_IFREQ
+# include <net/if.h>
+# endif
+#else
+#if defined(SVR4) || (defined(SYSV) && defined(i386)) || defined(MINIX) || defined(__GNU__)
+# include <sys/utsname.h>
+#endif
+#if defined(SYSV) && defined(i386)
+# include <sys/stream.h>
+# ifdef ISC
+# include <sys/stropts.h>
+# include <sys/sioctl.h>
+# endif /* ISC */
+#endif
+#ifdef ESIX
+# include <lan/if.h>
+#else
+#ifdef __GNU__
+#undef SIOCGIFCONF
+#include <netdb.h>
+#else /*!__GNU__*/
+#ifndef MINIX
+# include <net/if.h>
+#endif
+#endif /*__GNU__ */
+#endif
+#endif /* hpux */
+#endif /* !AMOEBA */
+
+#ifdef SVR4
+#ifndef SCO
+#include <sys/sockio.h>
+#endif
+#include <sys/stropts.h>
+#endif
+
+#ifdef ESIX
+#include <lan/netdb.h>
+#else
+#if !defined(AMOEBA) && !defined(MINIX)
+#include <netdb.h>
+#else
+#ifdef AMOEBA
+#include <server/ip/gen/netdb.h>
+#endif
+#ifdef MINIX
+#include <net/hton.h>
+#include <net/gen/netdb.h>
+#define INADDR_BROADCAST 0xFFFFFFFF
+#endif
+#endif /* AMOEBA || MINIX */
+#endif /* ESIX */
+
+#ifdef CSRG_BASED
+#include <sys/param.h>
+#if (BSD >= 199103)
+#define VARIABLE_IFREQ
+#endif
+#endif
+
+#ifdef BSD44SOCKETS
+#ifndef VARIABLE_IFREQ
+#define VARIABLE_IFREQ
+#endif
+#endif
+
+#endif /* WIN32 */
+
+#ifndef PATH_MAX
+#ifndef Lynx
+#include <sys/param.h>
+#else
+#include <param.h>
+#endif
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+#endif
+
+#include "dixstruct.h"
+#include "osdep.h"
+
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "extensions/security.h"
+#endif
+
+Bool defeatAccessControl = FALSE;
+
+#define acmp(a1, a2, len) memcmp((char *)(a1), (char *)(a2), len)
+#define acopy(a1, a2, len) memmove((char *)(a2), (char *)(a1), len)
+#define addrEqual(fam, address, length, host) \
+ ((fam) == (host)->family &&\
+ (length) == (host)->len &&\
+ !acmp (address, (host)->addr, length))
+
+static int ConvertAddr(
+#if NeedFunctionPrototypes
+ struct sockaddr */*saddr*/,
+ int */*len*/,
+ pointer */*addr*/
+#endif
+);
+
+static int CheckAddr(
+#if NeedFunctionPrototypes
+ int /*family*/,
+ pointer /*pAddr*/,
+ unsigned /*length*/
+#endif
+);
+
+static Bool NewHost(
+#if NeedFunctionPrototypes
+ int /*family*/,
+ pointer /*addr*/,
+ int /*len*/
+#endif
+);
+
+typedef struct _host {
+ short family;
+ short len;
+ unsigned char *addr;
+ struct _host *next;
+} HOST;
+
+#define MakeHost(h,l) (h)=(HOST *) xalloc(sizeof *(h)+(l));\
+ if((h))\
+ (h)->addr=(unsigned char *) ((h) + 1);
+#define FreeHost(h) xfree(h)
+static HOST *selfhosts = NULL;
+static HOST *validhosts = NULL;
+static int AccessEnabled = DEFAULT_ACCESS_CONTROL;
+static int LocalHostEnabled = FALSE;
+static int UsingXdmcp = FALSE;
+
+
+/*
+ * called when authorization is not enabled to add the
+ * local host to the access list
+ */
+
+void
+EnableLocalHost (void)
+{
+ if (!UsingXdmcp)
+ {
+ LocalHostEnabled = TRUE;
+ AddLocalHosts ();
+ }
+}
+
+/*
+ * called when authorization is enabled to keep us secure
+ */
+void
+DisableLocalHost (void)
+{
+ HOST *self;
+
+ LocalHostEnabled = FALSE;
+ for (self = selfhosts; self; self = self->next)
+ (void) RemoveHost ((ClientPtr)NULL, self->family, self->len, (pointer)self->addr);
+}
+
+/*
+ * called at init time when XDMCP will be used; xdmcp always
+ * adds local hosts manually when needed
+ */
+
+void
+AccessUsingXdmcp (void)
+{
+ UsingXdmcp = TRUE;
+ LocalHostEnabled = FALSE;
+}
+
+
+#if ((defined(SVR4) && !defined(DGUX) && !defined(SCO325) && !defined(sun) && !defined(NCR)) || defined(ISC)) && defined(SIOCGIFCONF)
+
+/* Deal with different SIOCGIFCONF ioctl semantics on these OSs */
+
+static int
+ifioctl (int fd, int cmd, char *arg)
+{
+ struct strioctl ioc;
+ int ret;
+
+ bzero((char *) &ioc, sizeof(ioc));
+ ioc.ic_cmd = cmd;
+ ioc.ic_timout = 0;
+ if (cmd == SIOCGIFCONF)
+ {
+ ioc.ic_len = ((struct ifconf *) arg)->ifc_len;
+ ioc.ic_dp = ((struct ifconf *) arg)->ifc_buf;
+#ifdef ISC
+ /* SIOCGIFCONF is somewhat brain damaged on ISC. The argument
+ * buffer must contain the ifconf structure as header. Ifc_req
+ * is also not a pointer but a one element array of ifreq
+ * structures. On return this array is extended by enough
+ * ifreq fields to hold all interfaces. The return buffer length
+ * is placed in the buffer header.
+ */
+ ((struct ifconf *) ioc.ic_dp)->ifc_len =
+ ioc.ic_len - sizeof(struct ifconf);
+#endif
+ }
+ else
+ {
+ ioc.ic_len = sizeof(struct ifreq);
+ ioc.ic_dp = arg;
+ }
+ ret = ioctl(fd, I_STR, (char *) &ioc);
+ if (ret >= 0 && cmd == SIOCGIFCONF)
+#ifdef SVR4
+ ((struct ifconf *) arg)->ifc_len = ioc.ic_len;
+#endif
+#ifdef ISC
+ {
+ ((struct ifconf *) arg)->ifc_len =
+ ((struct ifconf *)ioc.ic_dp)->ifc_len;
+ ((struct ifconf *) arg)->ifc_buf =
+ (caddr_t)((struct ifconf *)ioc.ic_dp)->ifc_req;
+ }
+#endif
+ return(ret);
+}
+#else /* Case DGUX, sun, SCO325 NCR and others */
+#define ifioctl ioctl
+#endif /* ((SVR4 && !DGUX !sun !SCO325 !NCR) || ISC) && SIOCGIFCONF */
+
+/*
+ * DefineSelf (fd):
+ *
+ * Define this host for access control. Find all the hosts the OS knows about
+ * for this fd and add them to the selfhosts list.
+ */
+
+#ifdef WINTCP /* NCR Wollongong based TCP */
+
+#include <sys/un.h>
+#include <stropts.h>
+#include <tiuser.h>
+
+#include <sys/stream.h>
+#include <net/if.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+
+void
+DefineSelf (int fd)
+{
+ /*
+ * The Wolongong drivers used by NCR SVR4/MP-RAS don't understand the
+ * socket IO calls that most other drivers seem to like. Because of
+ * this, this routine must be special cased for NCR. Eventually,
+ * this will be cleared up.
+ */
+
+ struct ipb ifnet;
+ struct in_ifaddr ifaddr;
+ struct strioctl str;
+ unsigned char *addr;
+ register HOST *host;
+ int family, len;
+
+ if ((fd = open ("/dev/ip", O_RDWR, 0 )) < 0)
+ Error ("Getting interface configuration (1)");
+
+ /* Indicate that we want to start at the begining */
+ ifnet.ib_next = (struct ipb *) 1;
+
+ while (ifnet.ib_next)
+ {
+ str.ic_cmd = IPIOC_GETIPB;
+ str.ic_timout = 0;
+ str.ic_len = sizeof (struct ipb);
+ str.ic_dp = (char *) &ifnet;
+
+ if (ioctl (fd, (int) I_STR, (char *) &str) < 0)
+ {
+ close (fd);
+ Error ("Getting interface configuration (2)");
+ }
+
+ ifaddr.ia_next = (struct in_ifaddr *) ifnet.if_addrlist;
+ str.ic_cmd = IPIOC_GETINADDR;
+ str.ic_timout = 0;
+ str.ic_len = sizeof (struct in_ifaddr);
+ str.ic_dp = (char *) &ifaddr;
+
+ if (ioctl (fd, (int) I_STR, (char *) &str) < 0)
+ {
+ close (fd);
+ Error ("Getting interface configuration (3)");
+ }
+
+ len = sizeof(struct sockaddr_in);
+ family = ConvertAddr (IA_SIN(&ifaddr), &len, (pointer *)&addr);
+ if (family == -1 || family == FamilyLocal)
+ continue;
+ for (host = selfhosts;
+ host && !addrEqual (family, addr, len, host);
+ host = host->next)
+ ;
+ if (host)
+ continue;
+ MakeHost(host,len)
+ if (host)
+ {
+ host->family = family;
+ host->len = len;
+ acopy(addr, host->addr, len);
+ host->next = selfhosts;
+ selfhosts = host;
+ }
+#ifdef XDMCP
+ {
+ struct sockaddr broad_addr;
+
+ /*
+ * If this isn't an Internet Address, don't register it.
+ */
+ if (family != FamilyInternet)
+ continue;
+
+ /*
+ * ignore 'localhost' entries as they're not useful
+ * on the other end of the wire
+ */
+ if (len == 4 &&
+ addr[0] == 127 && addr[1] == 0 &&
+ addr[2] == 0 && addr[3] == 1)
+ continue;
+
+ XdmcpRegisterConnection (family, (char *)addr, len);
+
+
+#define IA_BROADADDR(ia) ((struct sockaddr_in *)(&((struct in_ifaddr *)ia)->ia_broadaddr))
+
+ XdmcpRegisterBroadcastAddress (
+ (struct sockaddr_in *) IA_BROADADDR(&ifaddr));
+
+#undef IA_BROADADDR
+ }
+#endif /* XDMCP */
+ }
+
+ close(fd);
+
+ /*
+ * add something of FamilyLocalHost
+ */
+ for (host = selfhosts;
+ host && !addrEqual(FamilyLocalHost, "", 0, host);
+ host = host->next);
+ if (!host)
+ {
+ MakeHost(host, 0);
+ if (host)
+ {
+ host->family = FamilyLocalHost;
+ host->len = 0;
+ acopy("", host->addr, 0);
+ host->next = selfhosts;
+ selfhosts = host;
+ }
+ }
+}
+
+#else /* WINTCP */
+
+#if !defined(SIOCGIFCONF) || (defined (hpux) && ! defined (HAS_IFREQ))
+void
+DefineSelf (int fd)
+{
+#if !defined(TCPCONN) && !defined(STREAMSCONN) && !defined(UNIXCONN) && !defined(MNX_TCPCONN)
+ return;
+#else
+ register int n;
+ int len;
+ caddr_t addr;
+ int family;
+ register HOST *host;
+
+ struct utsname name;
+ register struct hostent *hp;
+
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in in;
+ } saddr;
+
+ struct sockaddr_in *inetaddr;
+ struct sockaddr_in broad_addr;
+
+ /* Why not use gethostname()? Well, at least on my system, I've had to
+ * make an ugly kernel patch to get a name longer than 8 characters, and
+ * uname() lets me access to the whole string (it smashes release, you
+ * see), whereas gethostname() kindly truncates it for me.
+ */
+ uname(&name);
+ hp = gethostbyname (name.nodename);
+ if (hp != NULL)
+ {
+ saddr.sa.sa_family = hp->h_addrtype;
+ inetaddr = (struct sockaddr_in *) (&(saddr.sa));
+ acopy ( hp->h_addr, &(inetaddr->sin_addr), hp->h_length);
+ len = sizeof(saddr.sa);
+ family = ConvertAddr ( &(saddr.sa), &len, (pointer *)&addr);
+ if ( family != -1 && family != FamilyLocal )
+ {
+ for (host = selfhosts;
+ host && !addrEqual (family, addr, len, host);
+ host = host->next) ;
+ if (!host)
+ {
+ /* add this host to the host list. */
+ MakeHost(host,len)
+ if (host)
+ {
+ host->family = family;
+ host->len = len;
+ acopy ( addr, host->addr, len);
+ host->next = selfhosts;
+ selfhosts = host;
+ }
+#ifdef XDMCP
+ /*
+ * If this is an Internet Address, but not the localhost
+ * address (127.0.0.1), register it.
+ */
+ if (family == FamilyInternet &&
+ !(len == 4 && addr[0] == 127 && addr[1] == 0 &&
+ addr[2] == 0 && addr[3] == 1)
+ )
+ {
+ XdmcpRegisterConnection (family, (char *)addr, len);
+ broad_addr = *inetaddr;
+ ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
+ htonl (INADDR_BROADCAST);
+ XdmcpRegisterBroadcastAddress ((struct sockaddr_in *)
+ &broad_addr);
+ }
+#endif /* XDMCP */
+ }
+ }
+ }
+ /*
+ * now add a host of family FamilyLocalHost...
+ */
+ for (host = selfhosts;
+ host && !addrEqual(FamilyLocalHost, "", 0, host);
+ host = host->next);
+ if (!host)
+ {
+ MakeHost(host, 0);
+ if (host)
+ {
+ host->family = FamilyLocalHost;
+ host->len = 0;
+ acopy("", host->addr, 0);
+ host->next = selfhosts;
+ selfhosts = host;
+ }
+ }
+#endif /* !TCPCONN && !STREAMSCONN && !UNIXCONN && !MNX_TCPCONN */
+}
+
+#else
+
+#ifdef VARIABLE_IFREQ
+#define ifr_size(p) (sizeof (struct ifreq) + \
+ (p->ifr_addr.sa_len > sizeof (p->ifr_addr) ? \
+ p->ifr_addr.sa_len - sizeof (p->ifr_addr) : 0))
+#define ifraddr_size(a) (a.sa_len)
+#else
+#define ifr_size(p) (sizeof (struct ifreq))
+#define ifraddr_size(a) (sizeof (a))
+#endif
+
+void
+DefineSelf (int fd)
+{
+ char buf[2048], *cp, *cplim;
+ struct ifconf ifc;
+ int len;
+ unsigned char * addr;
+ int family;
+ register HOST *host;
+ register struct ifreq *ifr;
+
+#ifdef DNETCONN
+ struct dn_naddr *dnaddr = getnodeadd();
+ /*
+ * AF_DECnet may not be listed in the interface list. Instead use
+ * the supported library call to find out the local address (if any).
+ */
+ if (dnaddr)
+ {
+ addr = (unsigned char *) dnaddr;
+ len = dnaddr->a_len + sizeof(dnaddr->a_len);
+ family = FamilyDECnet;
+ for (host = selfhosts;
+ host && !addrEqual (family, addr, len, host);
+ host = host->next)
+ ;
+ if (!host)
+ {
+ MakeHost(host,len)
+ if (host)
+ {
+ host->family = family;
+ host->len = len;
+ acopy(addr, host->addr, len);
+ host->next = selfhosts;
+ selfhosts = host;
+ }
+ }
+ }
+#endif
+ ifc.ifc_len = sizeof (buf);
+ ifc.ifc_buf = buf;
+ if (ifioctl (fd, SIOCGIFCONF, (pointer) &ifc) < 0)
+ Error ("Getting interface configuration (4)");
+
+#ifdef ISC
+#define IFC_IFC_REQ (struct ifreq *) ifc.ifc_buf
+#else
+#define IFC_IFC_REQ ifc.ifc_req
+#endif
+
+ cplim = (char *) IFC_IFC_REQ + ifc.ifc_len;
+
+ for (cp = (char *) IFC_IFC_REQ; cp < cplim; cp += ifr_size (ifr))
+ {
+ ifr = (struct ifreq *) cp;
+ len = ifraddr_size (ifr->ifr_addr);
+#ifdef DNETCONN
+ /*
+ * DECnet was handled up above.
+ */
+ if (ifr->ifr_addr.sa_family == AF_DECnet)
+ continue;
+#endif /* DNETCONN */
+ family = ConvertAddr (&ifr->ifr_addr, &len, (pointer *)&addr);
+ if (family == -1 || family == FamilyLocal)
+ continue;
+#ifdef DEF_SELF_DEBUG
+ if (family == FamilyInternet)
+ ErrorF("Xserver: DefineSelf(): ifname = %s, addr = %d.%d.%d.%d\n",
+ ifr->ifr_name, addr[0], addr[1], addr[2], addr[3]);
+#endif
+ for (host = selfhosts;
+ host && !addrEqual (family, addr, len, host);
+ host = host->next)
+ ;
+ if (host)
+ continue;
+ MakeHost(host,len)
+ if (host)
+ {
+ host->family = family;
+ host->len = len;
+ acopy(addr, host->addr, len);
+ host->next = selfhosts;
+ selfhosts = host;
+ }
+#ifdef XDMCP
+ {
+ struct sockaddr broad_addr;
+
+ /*
+ * If this isn't an Internet Address, don't register it.
+ */
+ if (family != FamilyInternet)
+ continue;
+
+ /*
+ * ignore 'localhost' entries as they're not useful
+ * on the other end of the wire
+ */
+ if (len == 4 &&
+ addr[0] == 127 && addr[1] == 0 &&
+ addr[2] == 0 && addr[3] == 1)
+ continue;
+
+ XdmcpRegisterConnection (family, (char *)addr, len);
+ broad_addr = ifr->ifr_addr;
+ ((struct sockaddr_in *) &broad_addr)->sin_addr.s_addr =
+ htonl (INADDR_BROADCAST);
+#ifdef SIOCGIFBRDADDR
+ {
+ struct ifreq broad_req;
+
+ broad_req = *ifr;
+ if (ifioctl (fd, SIOCGIFFLAGS, (char *) &broad_req) != -1 &&
+ (broad_req.ifr_flags & IFF_BROADCAST) &&
+ (broad_req.ifr_flags & IFF_UP)
+ )
+ {
+ broad_req = *ifr;
+ if (ifioctl (fd, SIOCGIFBRDADDR, &broad_req) != -1)
+ broad_addr = broad_req.ifr_addr;
+ else
+ continue;
+ }
+ else
+ continue;
+ }
+#endif
+#ifdef DEF_SELF_DEBUG
+ ErrorF("Xserver: DefineSelf(): ifname = %s, baddr = %s\n",
+ ifr->ifr_name,
+ inet_ntoa(((struct sockaddr_in *) &broad_addr)->sin_addr));
+#endif
+ XdmcpRegisterBroadcastAddress ((struct sockaddr_in *) &broad_addr);
+ }
+#endif
+ }
+ /*
+ * add something of FamilyLocalHost
+ */
+ for (host = selfhosts;
+ host && !addrEqual(FamilyLocalHost, "", 0, host);
+ host = host->next);
+ if (!host)
+ {
+ MakeHost(host, 0);
+ if (host)
+ {
+ host->family = FamilyLocalHost;
+ host->len = 0;
+ acopy("", host->addr, 0);
+ host->next = selfhosts;
+ selfhosts = host;
+ }
+ }
+}
+#endif /* hpux && !HAS_IFREQ */
+#endif /* WINTCP */
+
+#ifdef XDMCP
+void
+AugmentSelf(pointer from, int len)
+{
+ int family;
+ pointer addr;
+ register HOST *host;
+
+ family = ConvertAddr(from, &len, (pointer *)&addr);
+ if (family == -1 || family == FamilyLocal)
+ return;
+ for (host = selfhosts; host; host = host->next)
+ {
+ if (addrEqual(family, addr, len, host))
+ return;
+ }
+ MakeHost(host,len)
+ if (!host)
+ return;
+ host->family = family;
+ host->len = len;
+ acopy(addr, host->addr, len);
+ host->next = selfhosts;
+ selfhosts = host;
+}
+#endif
+
+void
+AddLocalHosts (void)
+{
+ HOST *self;
+
+ for (self = selfhosts; self; self = self->next)
+ (void) NewHost (self->family, self->addr, self->len);
+}
+
+/* Reset access control list to initial hosts */
+void
+ResetHosts (char *display)
+{
+ register HOST *host;
+ char lhostname[120], ohostname[120];
+ char *hostname = ohostname;
+ char fname[PATH_MAX + 1];
+ int fnamelen;
+ FILE *fd;
+ char *ptr;
+ int i, hostlen;
+#ifndef AMOEBA
+ union {
+ struct sockaddr sa;
+#if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
+ struct sockaddr_in in;
+#endif /* TCPCONN || STREAMSCONN */
+#ifdef DNETCONN
+ struct sockaddr_dn dn;
+#endif
+ } saddr;
+#endif /* AMOEBA */
+#ifdef DNETCONN
+ struct nodeent *np;
+ struct dn_naddr dnaddr, *dnaddrp, *dnet_addr();
+#endif
+#ifdef K5AUTH
+ krb5_principal princ;
+ krb5_data kbuf;
+#endif
+ int family = 0;
+ pointer addr;
+ int len;
+ register struct hostent *hp;
+
+ AccessEnabled = defeatAccessControl ? FALSE : DEFAULT_ACCESS_CONTROL;
+ LocalHostEnabled = FALSE;
+ while ((host = validhosts) != 0)
+ {
+ validhosts = host->next;
+ FreeHost (host);
+ }
+#ifndef __EMX__
+#define ETC_HOST_PREFIX "/etc/X"
+#define ETC_HOST_SUFFIX ".hosts"
+#else
+#define ETC_HOST_PREFIX "/XFree86/lib/X11/X"
+#define ETC_HOST_SUFFIX ".hosts"
+#endif /* __EMX__ */
+ fnamelen = strlen(ETC_HOST_PREFIX) + strlen(ETC_HOST_SUFFIX) +
+ strlen(display) + 1;
+ if (fnamelen > sizeof(fname))
+ FatalError("Display name `%s' is too long\n", display);
+ sprintf(fname, ETC_HOST_PREFIX "%s" ETC_HOST_SUFFIX, display);
+#ifdef __EMX__
+ strcpy(fname, (char*)__XOS2RedirRoot(fname));
+#endif /* __EMX__ */
+
+ if ((fd = fopen (fname, "r")) != 0)
+ {
+ while (fgets (ohostname, sizeof (ohostname), fd))
+ {
+ if (*ohostname == '#')
+ continue;
+ if ((ptr = strchr(ohostname, '\n')) != 0)
+ *ptr = 0;
+#ifdef __EMX__
+ if ((ptr = strchr(ohostname, '\r')) != 0)
+ *ptr = 0;
+#endif
+ hostlen = strlen(ohostname) + 1;
+ for (i = 0; i < hostlen; i++)
+ lhostname[i] = tolower(ohostname[i]);
+ hostname = ohostname;
+ if (!strncmp("local:", lhostname, 6))
+ {
+ family = FamilyLocalHost;
+ NewHost(family, "", 0);
+ }
+#if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
+ else if (!strncmp("inet:", lhostname, 5))
+ {
+ family = FamilyInternet;
+ hostname = ohostname + 5;
+ }
+#endif
+#ifdef DNETCONN
+ else if (!strncmp("dnet:", lhostname, 5))
+ {
+ family = FamilyDECnet;
+ hostname = ohostname + 5;
+ }
+#endif
+#ifdef SECURE_RPC
+ else if (!strncmp("nis:", lhostname, 4))
+ {
+ family = FamilyNetname;
+ hostname = ohostname + 4;
+ }
+#endif
+#ifdef K5AUTH
+ else if (!strncmp("krb:", lhostname, 4))
+ {
+ family = FamilyKrb5Principal;
+ hostname = ohostname + 4;
+ }
+#endif
+#ifdef DNETCONN
+ if ((family == FamilyDECnet) ||
+ (ptr = strchr(hostname, ':')) && (*(ptr + 1) == ':') &&
+ !(*ptr = '\0')) /* bash trailing colons if necessary */
+ {
+ /* node name (DECnet names end in "::") */
+ dnaddrp = dnet_addr(hostname);
+ if (!dnaddrp && (np = getnodebyname (hostname)))
+ {
+ /* node was specified by name */
+ saddr.sa.sa_family = np->n_addrtype;
+ len = sizeof(saddr.sa);
+ if (ConvertAddr (&saddr.sa, &len, (pointer *)&addr) == FamilyDECnet)
+ {
+ bzero ((char *) &dnaddr, sizeof (dnaddr));
+ dnaddr.a_len = np->n_length;
+ acopy (np->n_addr, dnaddr.a_addr, np->n_length);
+ dnaddrp = &dnaddr;
+ }
+ }
+ if (dnaddrp)
+ (void) NewHost(FamilyDECnet, (pointer)dnaddrp,
+ (int)(dnaddrp->a_len + sizeof(dnaddrp->a_len)));
+ }
+ else
+#endif /* DNETCONN */
+#ifdef K5AUTH
+ if (family == FamilyKrb5Principal)
+ {
+ krb5_parse_name(hostname, &princ);
+ XauKrb5Encode(princ, &kbuf);
+ (void) NewHost(FamilyKrb5Principal, kbuf.data, kbuf.length);
+ krb5_free_principal(princ);
+ }
+ else
+#endif
+#ifdef SECURE_RPC
+ if ((family == FamilyNetname) || (strchr(hostname, '@')))
+ {
+ SecureRPCInit ();
+ (void) NewHost (FamilyNetname, hostname, strlen (hostname));
+ }
+ else
+#endif /* SECURE_RPC */
+#if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
+ {
+ /* host name */
+ if ((family == FamilyInternet
+ && ((hp = gethostbyname (hostname)) != 0))
+ || ((hp = gethostbyname (hostname)) != 0))
+ {
+ saddr.sa.sa_family = hp->h_addrtype;
+ len = sizeof(saddr.sa);
+ if ((family = ConvertAddr (&saddr.sa, &len, (pointer *)&addr)) != -1)
+ {
+#ifdef h_addr /* new 4.3bsd version of gethostent */
+ char **list;
+
+ /* iterate over the addresses */
+ for (list = hp->h_addr_list; *list; list++)
+ (void) NewHost (family, (pointer)*list, len);
+#else
+ (void) NewHost (family, (pointer)hp->h_addr, len);
+#endif
+ }
+ }
+ }
+#endif /* TCPCONN || STREAMSCONN */
+ family = FamilyWild;
+ }
+ fclose (fd);
+ }
+}
+
+/* Is client on the local host */
+Bool LocalClient(ClientPtr client)
+{
+ int alen, family, notused;
+ Xtransaddr *from = NULL;
+ pointer addr;
+ register HOST *host;
+
+#ifdef XCSECURITY
+ /* untrusted clients can't change host access */
+ if (client->trustLevel != XSecurityClientTrusted)
+ {
+ SecurityAudit("client %d attempted to change host access\n",
+ client->index);
+ return FALSE;
+ }
+#endif
+#ifdef LBX
+ if (!((OsCommPtr)client->osPrivate)->trans_conn)
+ return FALSE;
+#endif
+ if (!_XSERVTransGetPeerAddr (((OsCommPtr)client->osPrivate)->trans_conn,
+ &notused, &alen, &from))
+ {
+ family = ConvertAddr ((struct sockaddr *) from,
+ &alen, (pointer *)&addr);
+ if (family == -1)
+ {
+ xfree ((char *) from);
+ return FALSE;
+ }
+ if (family == FamilyLocal)
+ {
+ xfree ((char *) from);
+ return TRUE;
+ }
+ for (host = selfhosts; host; host = host->next)
+ {
+ if (addrEqual (family, addr, alen, host))
+ return TRUE;
+ }
+ xfree ((char *) from);
+ }
+ return FALSE;
+}
+
+static Bool
+AuthorizedClient(ClientPtr client)
+{
+ if (!client || defeatAccessControl)
+ return TRUE;
+ return LocalClient(client);
+}
+
+/* Add a host to the access control list. This is the external interface
+ * called from the dispatcher */
+
+int
+AddHost (
+ ClientPtr client,
+ int family,
+ unsigned length, /* of bytes in pAddr */
+ pointer pAddr)
+{
+ int len;
+
+ if (!AuthorizedClient(client))
+ return(BadAccess);
+ switch (family) {
+ case FamilyLocalHost:
+ len = length;
+ LocalHostEnabled = TRUE;
+ break;
+#ifdef K5AUTH
+ case FamilyKrb5Principal:
+ len = length;
+ break;
+#endif
+#ifdef SECURE_RPC
+ case FamilyNetname:
+ len = length;
+ SecureRPCInit ();
+ break;
+#endif
+ case FamilyInternet:
+ case FamilyDECnet:
+ case FamilyChaos:
+ if ((len = CheckAddr (family, pAddr, length)) < 0)
+ {
+ client->errorValue = length;
+ return (BadValue);
+ }
+ break;
+ case FamilyLocal:
+ default:
+ client->errorValue = family;
+ return (BadValue);
+ }
+ if (NewHost (family, pAddr, len))
+ return Success;
+ return BadAlloc;
+}
+
+Bool
+#if NeedFunctionPrototypes
+ForEachHostInFamily (
+ int family,
+ Bool (*func)(
+#if NeedNestedPrototypes
+ unsigned char * /* addr */,
+ short /* len */,
+ pointer /* closure */
+#endif
+ ),
+ pointer closure)
+#else
+ForEachHostInFamily (family, func, closure)
+ int family;
+ Bool (*func)();
+ pointer closure;
+#endif
+{
+ HOST *host;
+
+ for (host = validhosts; host; host = host->next)
+ if (family == host->family && func (host->addr, host->len, closure))
+ return TRUE;
+ return FALSE;
+}
+
+/* Add a host to the access control list. This is the internal interface
+ * called when starting or resetting the server */
+static Bool
+NewHost (
+ int family,
+ pointer addr,
+ int len)
+{
+ register HOST *host;
+
+ for (host = validhosts; host; host = host->next)
+ {
+ if (addrEqual (family, addr, len, host))
+ return TRUE;
+ }
+ MakeHost(host,len)
+ if (!host)
+ return FALSE;
+ host->family = family;
+ host->len = len;
+ acopy(addr, host->addr, len);
+ host->next = validhosts;
+ validhosts = host;
+ return TRUE;
+}
+
+/* Remove a host from the access control list */
+
+int
+RemoveHost (
+ ClientPtr client,
+ int family,
+ unsigned length, /* of bytes in pAddr */
+ pointer pAddr)
+{
+ int len;
+ register HOST *host, **prev;
+
+ if (!AuthorizedClient(client))
+ return(BadAccess);
+ switch (family) {
+ case FamilyLocalHost:
+ len = length;
+ LocalHostEnabled = FALSE;
+ break;
+#ifdef K5AUTH
+ case FamilyKrb5Principal:
+ len = length;
+ break;
+#endif
+#ifdef SECURE_RPC
+ case FamilyNetname:
+ len = length;
+ break;
+#endif
+ case FamilyInternet:
+ case FamilyDECnet:
+ case FamilyChaos:
+ if ((len = CheckAddr (family, pAddr, length)) < 0)
+ {
+ client->errorValue = length;
+ return(BadValue);
+ }
+ break;
+ case FamilyLocal:
+ default:
+ client->errorValue = family;
+ return(BadValue);
+ }
+ for (prev = &validhosts;
+ (host = *prev) && (!addrEqual (family, pAddr, len, host));
+ prev = &host->next)
+ ;
+ if (host)
+ {
+ *prev = host->next;
+ FreeHost (host);
+ }
+ return (Success);
+}
+
+/* Get all hosts in the access control list */
+int
+GetHosts (
+ pointer *data,
+ int *pnHosts,
+ int *pLen,
+ BOOL *pEnabled)
+{
+ int len;
+ register int n = 0;
+ register unsigned char *ptr;
+ register HOST *host;
+ int nHosts = 0;
+
+ *pEnabled = AccessEnabled ? EnableAccess : DisableAccess;
+ for (host = validhosts; host; host = host->next)
+ {
+ nHosts++;
+ n += (((host->len + 3) >> 2) << 2) + sizeof(xHostEntry);
+ }
+ if (n)
+ {
+ *data = ptr = (pointer) xalloc (n);
+ if (!ptr)
+ {
+ return(BadAlloc);
+ }
+ for (host = validhosts; host; host = host->next)
+ {
+ len = host->len;
+ ((xHostEntry *)ptr)->family = host->family;
+ ((xHostEntry *)ptr)->length = len;
+ ptr += sizeof(xHostEntry);
+ acopy (host->addr, ptr, len);
+ ptr += ((len + 3) >> 2) << 2;
+ }
+ } else {
+ *data = NULL;
+ }
+ *pnHosts = nHosts;
+ *pLen = n;
+ return(Success);
+}
+
+/* Check for valid address family and length, and return address length. */
+
+/*ARGSUSED*/
+static int
+CheckAddr (
+ int family,
+ pointer pAddr,
+ unsigned length)
+{
+ int len;
+
+ switch (family)
+ {
+#if defined(TCPCONN) || defined(STREAMSCONN) || defined(AMTCPCONN) || defined(MNX_TCPCONN)
+ case FamilyInternet:
+#if !defined(AMOEBA)
+ if (length == sizeof (struct in_addr))
+#else
+ if (length == sizeof(ipaddr_t))
+#endif
+ len = length;
+ else
+ len = -1;
+ break;
+#endif
+#ifdef DNETCONN
+ case FamilyDECnet:
+ {
+ struct dn_naddr *dnaddr = (struct dn_naddr *) pAddr;
+
+ if ((length < sizeof(dnaddr->a_len)) ||
+ (length < dnaddr->a_len + sizeof(dnaddr->a_len)))
+ len = -1;
+ else
+ len = dnaddr->a_len + sizeof(dnaddr->a_len);
+ if (len > sizeof(struct dn_naddr))
+ len = -1;
+ }
+ break;
+#endif
+ default:
+ len = -1;
+ }
+ return (len);
+}
+
+/* Check if a host is not in the access control list.
+ * Returns 1 if host is invalid, 0 if we've found it. */
+
+int
+InvalidHost (
+#ifndef AMOEBA_ORIG
+ register struct sockaddr *saddr,
+#else
+ register ipaddr_t *saddr,
+#endif
+ int len)
+{
+ int family;
+ pointer addr;
+ register HOST *selfhost, *host;
+
+ if (!AccessEnabled) /* just let them in */
+ return(0);
+ family = ConvertAddr (saddr, &len, (pointer *)&addr);
+ if (family == -1)
+ return 1;
+ if (family == FamilyLocal)
+ {
+ if (!LocalHostEnabled)
+ {
+ /*
+ * check to see if any local address is enabled. This
+ * implicitly enables local connections.
+ */
+ for (selfhost = selfhosts; selfhost; selfhost=selfhost->next)
+ {
+ for (host = validhosts; host; host=host->next)
+ {
+ if (addrEqual (selfhost->family, selfhost->addr,
+ selfhost->len, host))
+ return 0;
+ }
+ }
+ return 1;
+ } else
+ return 0;
+ }
+ for (host = validhosts; host; host = host->next)
+ {
+ if (addrEqual (family, addr, len, host))
+ return (0);
+ }
+ return (1);
+}
+
+static int
+ConvertAddr (
+#ifndef AMOEBA_ORIG
+ register struct sockaddr *saddr,
+#else
+ register ipaddr_t *saddr,
+#endif
+ int *len,
+ pointer *addr)
+{
+#ifndef AMOEBA
+ if (*len == 0)
+ return (FamilyLocal);
+ switch (saddr->sa_family)
+ {
+ case AF_UNSPEC:
+#if defined(UNIXCONN) || defined(LOCALCONN) || defined(OS2PIPECONN)
+ case AF_UNIX:
+#endif
+ return FamilyLocal;
+#if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
+ case AF_INET:
+ *len = sizeof (struct in_addr);
+ *addr = (pointer) &(((struct sockaddr_in *) saddr)->sin_addr);
+ return FamilyInternet;
+#endif
+#ifdef DNETCONN
+ case AF_DECnet:
+ {
+ struct sockaddr_dn *sdn = (struct sockaddr_dn *) saddr;
+ *len = sdn->sdn_nodeaddrl + sizeof(sdn->sdn_nodeaddrl);
+ *addr = (pointer) &(sdn->sdn_add);
+ }
+ return FamilyDECnet;
+#endif
+#ifdef CHAOSCONN
+ case AF_CHAOS:
+ {
+ not implemented
+ }
+ return FamilyChaos;
+#endif
+ default:
+ return -1;
+ }
+#else /* AMOEBA */
+ if (*len == 0) return -1;
+ *len = sizeof (ipaddr_t);
+ *addr = (pointer) saddr;
+ return FamilyInternet;
+#endif /* AMOEBA */
+}
+
+int
+ChangeAccessControl(
+ ClientPtr client,
+ int fEnabled)
+{
+ if (!AuthorizedClient(client))
+ return BadAccess;
+ AccessEnabled = fEnabled;
+ return Success;
+}
+
+/* returns FALSE if xhost + in effect, else TRUE */
+int
+GetAccessControl(void)
+{
+ return AccessEnabled;
+}
diff --git a/xc/programs/Xserver/os/auth.c b/xc/programs/Xserver/os/auth.c
new file mode 100644
index 000000000..0d40e088e
--- /dev/null
+++ b/xc/programs/Xserver/os/auth.c
@@ -0,0 +1,381 @@
+/* $TOG: auth.c /main/28 1998/02/09 15:11:49 kaleb $ */
+/*
+
+Copyright 1988, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+/* $XFree86: xc/programs/Xserver/os/auth.c,v 1.4 1998/12/06 06:08:47 dawes Exp $ */
+
+/*
+ * authorization hooks for the server
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifdef K5AUTH
+# include <krb5/krb5.h>
+#endif
+# include "X.h"
+# include "Xauth.h"
+# include "misc.h"
+# include "osdep.h"
+# include "dixstruct.h"
+# include <sys/types.h>
+# include <sys/stat.h>
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+# include "extensions/security.h"
+#endif
+#ifdef WIN32
+#include "Xw32defs.h"
+#endif
+
+struct protocol {
+ unsigned short name_length;
+ char *name;
+ AuthAddCFunc Add; /* new authorization data */
+ AuthCheckFunc Check; /* verify client authorization data */
+ AuthRstCFunc Reset; /* delete all authorization data entries */
+ AuthToIDFunc ToID; /* convert cookie to ID */
+ AuthFromIDFunc FromID; /* convert ID to cookie */
+ AuthRemCFunc Remove; /* remove a specific cookie */
+#ifdef XCSECURITY
+ AuthGenCFunc Generate;
+#endif
+};
+
+static struct protocol protocols[] = {
+{ (unsigned short) 18, "MIT-MAGIC-COOKIE-1",
+ MitAddCookie, MitCheckCookie, MitResetCookie,
+ MitToID, MitFromID, MitRemoveCookie,
+#ifdef XCSECURITY
+ MitGenerateCookie
+#endif
+},
+#ifdef HASXDMAUTH
+{ (unsigned short) 19, "XDM-AUTHORIZATION-1",
+ XdmAddCookie, XdmCheckCookie, XdmResetCookie,
+ XdmToID, XdmFromID, XdmRemoveCookie,
+#ifdef XCSECURITY
+ NULL
+#endif
+},
+#endif
+#ifdef SECURE_RPC
+{ (unsigned short) 9, "SUN-DES-1",
+ SecureRPCAdd, SecureRPCCheck, SecureRPCReset,
+ SecureRPCToID, SecureRPCFromID,SecureRPCRemove,
+#ifdef XCSECURITY
+ NULL
+#endif
+},
+#endif
+#ifdef K5AUTH
+{ (unsigned short) 14, "MIT-KERBEROS-5",
+ K5Add, K5Check, K5Reset,
+ K5ToID, K5FromID, K5Remove,
+#ifdef XCSECURITY
+ NULL
+#endif
+},
+#endif
+#ifdef XCSECURITY
+{ (unsigned short) XSecurityAuthorizationNameLen,
+ XSecurityAuthorizationName,
+ NULL, AuthSecurityCheck, NULL,
+ NULL, NULL, NULL,
+ NULL
+},
+#endif
+};
+
+# define NUM_AUTHORIZATION (sizeof (protocols) /\
+ sizeof (struct protocol))
+
+/*
+ * Initialize all classes of authorization by reading the
+ * specified authorization file
+ */
+
+static char *authorization_file = (char *)NULL;
+
+static Bool ShouldLoadAuth = TRUE;
+
+void
+InitAuthorization (char *file_name)
+{
+ authorization_file = file_name;
+}
+
+int
+LoadAuthorization (void)
+{
+ FILE *f;
+ Xauth *auth;
+ int i;
+ int count = 0;
+#if !defined(WIN32) && !defined(__EMX__)
+ char *buf;
+#endif
+
+ ShouldLoadAuth = FALSE;
+ if (!authorization_file)
+ return 0;
+#if !defined(WIN32) && !defined(__EMX__)
+ buf = xalloc (strlen(authorization_file) + 5);
+ if (!buf)
+ return 0;
+ sprintf (buf, "cat %s", authorization_file);
+ f = Popen (buf, "r");
+ xfree (buf);
+#else
+ f = fopen (authorization_file, "r");
+#endif
+ if (!f)
+ return 0;
+ while ((auth = XauReadAuth (f)) != 0) {
+ for (i = 0; i < NUM_AUTHORIZATION; i++) {
+ if (protocols[i].name_length == auth->name_length &&
+ memcmp (protocols[i].name, auth->name, (int) auth->name_length) == 0 &&
+ protocols[i].Add)
+ {
+ ++count;
+ (*protocols[i].Add) (auth->data_length, auth->data,
+ FakeClientID(0));
+ }
+ }
+ XauDisposeAuth (auth);
+ }
+#if !defined(WIN32) && !defined(__EMX__)
+ Pclose (f);
+#else
+ fclose (f);
+#endif
+ return count;
+}
+
+#ifdef XDMCP
+/*
+ * XdmcpInit calls this function to discover all authorization
+ * schemes supported by the display
+ */
+void
+RegisterAuthorizations (void)
+{
+ int i;
+
+ for (i = 0; i < NUM_AUTHORIZATION; i++)
+ XdmcpRegisterAuthorization (protocols[i].name,
+ (int)protocols[i].name_length);
+}
+#endif
+
+XID
+CheckAuthorization (
+ unsigned int name_length,
+ char *name,
+ unsigned int data_length,
+ char *data,
+ ClientPtr client,
+ char **reason) /* failure message. NULL for default msg */
+{
+ int i;
+ struct stat buf;
+ static time_t lastmod = 0;
+
+ if (!authorization_file || stat(authorization_file, &buf))
+ {
+ lastmod = 0;
+ ShouldLoadAuth = TRUE; /* stat lost, so force reload */
+ }
+ else if (buf.st_mtime > lastmod)
+ {
+ lastmod = buf.st_mtime;
+ ShouldLoadAuth = TRUE;
+ }
+ if (ShouldLoadAuth)
+ {
+ if (LoadAuthorization())
+ DisableLocalHost(); /* got at least one */
+ else
+ EnableLocalHost ();
+ }
+ if (name_length)
+ for (i = 0; i < NUM_AUTHORIZATION; i++) {
+ if (protocols[i].name_length == name_length &&
+ memcmp (protocols[i].name, name, (int) name_length) == 0)
+ {
+ return (*protocols[i].Check) (data_length, data, client, reason);
+ }
+ }
+ return (XID) ~0L;
+}
+
+void
+ResetAuthorization (void)
+{
+ int i;
+
+ for (i = 0; i < NUM_AUTHORIZATION; i++)
+ if (protocols[i].Reset)
+ (*protocols[i].Reset)();
+ ShouldLoadAuth = TRUE;
+}
+
+XID
+AuthorizationToID (
+ unsigned short name_length,
+ char *name,
+ unsigned short data_length,
+ char *data)
+{
+ int i;
+
+ for (i = 0; i < NUM_AUTHORIZATION; i++) {
+ if (protocols[i].name_length == name_length &&
+ memcmp (protocols[i].name, name, (int) name_length) == 0 &&
+ protocols[i].ToID)
+ {
+ return (*protocols[i].ToID) (data_length, data);
+ }
+ }
+ return (XID) ~0L;
+}
+
+int
+AuthorizationFromID (
+ XID id,
+ unsigned short *name_lenp,
+ char **namep,
+ unsigned short *data_lenp,
+ char **datap)
+{
+ int i;
+
+ for (i = 0; i < NUM_AUTHORIZATION; i++) {
+ if (protocols[i].FromID &&
+ (*protocols[i].FromID) (id, data_lenp, datap)) {
+ *name_lenp = protocols[i].name_length;
+ *namep = protocols[i].name;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int
+RemoveAuthorization (
+ unsigned short name_length,
+ char *name,
+ unsigned short data_length,
+ char *data)
+{
+ int i;
+
+ for (i = 0; i < NUM_AUTHORIZATION; i++) {
+ if (protocols[i].name_length == name_length &&
+ memcmp (protocols[i].name, name, (int) name_length) == 0 &&
+ protocols[i].Remove)
+ {
+ return (*protocols[i].Remove) (data_length, data);
+ }
+ }
+ return 0;
+}
+
+int
+AddAuthorization (unsigned name_length, char *name, unsigned data_length, char *data)
+{
+ int i;
+
+ for (i = 0; i < NUM_AUTHORIZATION; i++) {
+ if (protocols[i].name_length == name_length &&
+ memcmp (protocols[i].name, name, (int) name_length) == 0 &&
+ protocols[i].Add)
+ {
+ return (*protocols[i].Add) (data_length, data, FakeClientID(0));
+ }
+ }
+ return 0;
+}
+
+#ifdef XCSECURITY
+
+XID
+GenerateAuthorization(
+ unsigned name_length,
+ char *name,
+ unsigned data_length,
+ char *data,
+ unsigned *data_length_return,
+ char **data_return)
+{
+ int i;
+
+ for (i = 0; i < NUM_AUTHORIZATION; i++) {
+ if (protocols[i].name_length == name_length &&
+ memcmp (protocols[i].name, name, (int) name_length) == 0 &&
+ protocols[i].Generate)
+ {
+ return (*protocols[i].Generate) (data_length, data,
+ FakeClientID(0), data_length_return, data_return);
+ }
+ }
+ return -1;
+}
+
+/* A random number generator that is more unpredictable
+ than that shipped with some systems.
+ This code is taken from the C standard. */
+
+static unsigned long int next = 1;
+
+static int
+xdm_rand(void)
+{
+ next = next * 1103515245 + 12345;
+ return (unsigned int)(next/65536) % 32768;
+}
+
+static void
+xdm_srand(unsigned int seed)
+{
+ next = seed;
+}
+
+void
+GenerateRandomData (int len, char *buf)
+{
+ static int seed;
+ int value;
+ int i;
+
+ seed += GetTimeInMillis();
+ xdm_srand (seed);
+ for (i = 0; i < len; i++)
+ {
+ value = xdm_rand ();
+ buf[i] ^= (value & 0xff00) >> 8;
+ }
+
+ /* XXX add getrusage, popen("ps -ale") */
+}
+
+#endif /* XCSECURITY */
diff --git a/xc/programs/Xserver/os/connection.c b/xc/programs/Xserver/os/connection.c
new file mode 100644
index 000000000..ae38a7925
--- /dev/null
+++ b/xc/programs/Xserver/os/connection.c
@@ -0,0 +1,1398 @@
+/* $TOG: connection.c /main/159 1998/02/09 15:11:54 kaleb $ */
+/***********************************************************
+
+Copyright 1987, 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $XFree86: xc/programs/Xserver/os/connection.c,v 3.38 1999/05/15 12:10:35 dawes Exp $ */
+/*****************************************************************
+ * Stuff to create connections --- OS dependent
+ *
+ * EstablishNewConnections, CreateWellKnownSockets, ResetWellKnownSockets,
+ * CloseDownConnection, CheckConnections, AddEnabledDevice,
+ * RemoveEnabledDevice, OnlyListToOneClient,
+ * ListenToAllClients,
+ *
+ * (WaitForSomething is in its own file)
+ *
+ * In this implementation, a client socket table is not kept.
+ * Instead, what would be the index into the table is just the
+ * file descriptor of the socket. This won't work for if the
+ * socket ids aren't small nums (0 - 2^8)
+ *
+ *****************************************************************/
+
+#ifdef WIN32
+#include <X11/Xwinsock.h>
+#endif
+#include "X.h"
+#include "Xproto.h"
+#include <X11/Xtrans.h>
+#include <errno.h>
+#ifdef X_NOT_STDC_ENV
+extern int errno;
+#endif
+
+#include <signal.h>
+#include <stdio.h>
+
+#ifndef WIN32
+#ifndef MINIX
+#ifndef Lynx
+#include <sys/socket.h>
+#else
+#include <socket.h>
+#endif
+#endif
+
+#ifdef hpux
+#include <sys/utsname.h>
+#include <sys/ioctl.h>
+#endif
+
+#if defined(DGUX)
+#include <sys/ioctl.h>
+#include <sys/utsname.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/param.h>
+#include <unistd.h>
+#endif
+
+
+#ifdef AIXV3
+#include <sys/ioctl.h>
+#endif
+
+#ifdef MINIX
+#include <sys/nbio.h>
+
+#define select(n,r,w,x,t) nbio_select(n,r,w,x,t)
+#endif
+
+#ifdef __EMX__
+#define select(n,r,w,x,t) os2PseudoSelect(n,r,w,x,t)
+extern __const__ int _nfiles;
+#endif
+
+#if defined(TCPCONN) || defined(STREAMSCONN)
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# ifndef hpux
+# ifdef apollo
+# ifndef NO_TCP_H
+# include <netinet/tcp.h>
+# endif
+# else
+# ifdef CSRG_BASED
+# include <sys/param.h>
+# endif
+# ifndef __EMX__
+# include <netinet/tcp.h>
+# endif
+# endif
+# endif
+#endif
+
+#ifdef AMTCPCONN
+#include <server/ip/types.h>
+#include <server/ip/gen/in.h>
+#include <server/ip/gen/inet.h>
+#endif
+
+#if !defined(AMOEBA) && !defined(_MINIX) && !defined(__EMX__)
+#ifndef Lynx
+#include <sys/uio.h>
+#else
+#include <uio.h>
+#endif
+#endif
+#endif /* WIN32 */
+#include "misc.h" /* for typedef of pointer */
+#include <X11/Xpoll.h>
+#include "osdep.h"
+#include "opaque.h"
+#include "dixstruct.h"
+#ifdef XAPPGROUP
+#include "extensions/Xagsrv.h"
+#endif
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "extensions/security.h"
+#endif
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+#ifdef X_NOT_POSIX
+#define Pid_t int
+#else
+#define Pid_t pid_t
+#endif
+
+#ifdef DNETCONN
+#include <netdnet/dn.h>
+#endif /* DNETCONN */
+
+extern char *display; /* The display number */
+int lastfdesc; /* maximum file descriptor */
+
+fd_set WellKnownConnections; /* Listener mask */
+fd_set EnabledDevices; /* mask for input devices that are on */
+fd_set AllSockets; /* select on this */
+fd_set AllClients; /* available clients */
+fd_set LastSelectMask; /* mask returned from last select call */
+fd_set ClientsWithInput; /* clients with FULL requests in buffer */
+fd_set ClientsWriteBlocked; /* clients who cannot receive output */
+fd_set OutputPending; /* clients with reply/event data ready to go */
+int MaxClients = 0;
+Bool NewOutputPending; /* not yet attempted to write some new output */
+Bool AnyClientsWriteBlocked; /* true if some client blocked on write */
+
+Bool RunFromSmartParent; /* send SIGUSR1 to parent process */
+Bool PartialNetwork; /* continue even if unable to bind all addrs */
+char *protNoListen; /* don't listen on this protocol */
+static Pid_t ParentProcess;
+
+static Bool debug_conns = FALSE;
+
+fd_set IgnoredClientsWithInput;
+static fd_set GrabImperviousClients;
+static fd_set SavedAllClients;
+static fd_set SavedAllSockets;
+static fd_set SavedClientsWithInput;
+int GrabInProgress = 0;
+
+int *ConnectionTranslation = NULL;
+#ifdef WIN32
+/* SPAM ALERT !!!
+ * On NT fds are not between 0 and MAXSOCKS, they are unrelated, and there is
+ * not even a known maximum value, so use something quite arbitrary for now.
+ * This is clearly boggus and another form of storage which doesn't use the fd
+ * as a direct index should really be implemented for NT.
+ */
+#define MAXFD 500
+#endif
+
+XtransConnInfo *ListenTransConns = NULL;
+int *ListenTransFds = NULL;
+int ListenTransCount;
+
+extern int auditTrailLevel;
+
+static void ErrorConnMax(
+#if NeedFunctionPrototypes
+XtransConnInfo /* trans_conn */
+#endif
+);
+
+#ifndef LBX
+static
+#endif
+void CloseDownFileDescriptor(
+#if NeedFunctionPrototypes
+#ifdef LBX
+ ClientPtr client
+#else
+ register OsCommPtr /*oc*/
+#endif
+#endif
+);
+
+#ifdef LBX
+extern int LbxFlushClient();
+extern void LbxCloseClient();
+#endif /* LBX */
+
+static XtransConnInfo
+lookup_trans_conn (fd)
+ int fd;
+{
+ if (ListenTransFds)
+ {
+ int i;
+ for (i = 0; i < ListenTransCount; i++)
+ if (ListenTransFds[i] == fd)
+ return ListenTransConns[i];
+ }
+
+ return (NULL);
+}
+
+#ifdef XDMCP
+void XdmcpOpenDisplay(), XdmcpInit(), XdmcpReset(), XdmcpCloseDisplay();
+#endif
+
+/* Set MaxClients and lastfdesc, and allocate ConnectionTranslation */
+
+void
+InitConnectionLimits()
+{
+ lastfdesc = -1;
+
+#ifndef __EMX__
+
+#if !defined(XNO_SYSCONF) && defined(_SC_OPEN_MAX)
+ lastfdesc = sysconf(_SC_OPEN_MAX) - 1;
+#endif
+
+#ifdef HAS_GETDTABLESIZE
+ if (lastfdesc < 0)
+ lastfdesc = getdtablesize() - 1;
+#endif
+
+#ifdef _NFILE
+ if (lastfdesc < 0)
+ lastfdesc = _NFILE - 1;
+#endif
+
+#else /* __EMX__ */
+ lastfdesc = _nfiles - 1;
+#endif
+
+ /* This is the fallback */
+ if (lastfdesc < 0)
+ lastfdesc = MAXSOCKS;
+
+ if (lastfdesc > MAXSELECT)
+ lastfdesc = MAXSELECT;
+
+ if (lastfdesc > MAXCLIENTS)
+ {
+ lastfdesc = MAXCLIENTS;
+ if (debug_conns)
+ ErrorF( "REACHED MAXIMUM CLIENTS LIMIT %d\n", MAXCLIENTS);
+ }
+ MaxClients = lastfdesc;
+
+#ifdef DEBUG
+ ErrorF("InitConnectionLimits: MaxClients = %d\n", MaxClients);
+#endif
+
+#ifndef WIN32
+ ConnectionTranslation = (int *)xnfalloc(sizeof(int)*(lastfdesc + 1));
+#else
+ ConnectionTranslation = (int *)xnfalloc(sizeof(int)*(MAXFD));
+#endif
+}
+
+
+/*****************
+ * CreateWellKnownSockets
+ * At initialization, create the sockets to listen on for new clients.
+ *****************/
+
+void
+CreateWellKnownSockets()
+{
+ int request, i;
+ int partial;
+ char port[20];
+
+ FD_ZERO(&AllSockets);
+ FD_ZERO(&AllClients);
+ FD_ZERO(&LastSelectMask);
+ FD_ZERO(&ClientsWithInput);
+
+#ifndef WIN32
+ for (i=0; i<MaxClients; i++) ConnectionTranslation[i] = 0;
+#else
+ for (i=0; i<MAXFD; i++) ConnectionTranslation[i] = 0;
+#endif
+
+ FD_ZERO (&WellKnownConnections);
+
+ sprintf (port, "%d", atoi (display));
+
+ if (protNoListen)
+ if (_XSERVTransNoListen(protNoListen))
+ {
+ FatalError ("Failed to disable listen for %s", protNoListen);
+ }
+
+ if ((_XSERVTransMakeAllCOTSServerListeners (port, &partial,
+ &ListenTransCount, &ListenTransConns) >= 0) &&
+ (ListenTransCount >= 1))
+ {
+ if (!PartialNetwork && partial)
+ {
+ FatalError ("Failed to establish all listening sockets");
+ }
+ else
+ {
+ ListenTransFds = (int *) xalloc (ListenTransCount * sizeof (int));
+
+ for (i = 0; i < ListenTransCount; i++)
+ {
+ int fd = _XSERVTransGetConnectionNumber (ListenTransConns[i]);
+
+ ListenTransFds[i] = fd;
+ FD_SET (fd, &WellKnownConnections);
+
+ if (!_XSERVTransIsLocal (ListenTransConns[i]))
+ {
+ DefineSelf (fd);
+ }
+ }
+ }
+ }
+
+ if (!XFD_ANYSET (&WellKnownConnections))
+ FatalError ("Cannot establish any listening sockets - Make sure an X server isn't already running");
+#ifndef WIN32
+ OsSignal (SIGPIPE, SIG_IGN);
+ OsSignal (SIGHUP, AutoResetServer);
+#endif
+ OsSignal (SIGINT, GiveUp);
+ OsSignal (SIGTERM, GiveUp);
+ XFD_COPYSET (&WellKnownConnections, &AllSockets);
+ ResetHosts(display);
+ /*
+ * Magic: If SIGUSR1 was set to SIG_IGN when
+ * the server started, assume that either
+ *
+ * a- The parent process is ignoring SIGUSR1
+ *
+ * or
+ *
+ * b- The parent process is expecting a SIGUSR1
+ * when the server is ready to accept connections
+ *
+ * In the first case, the signal will be harmless,
+ * in the second case, the signal will be quite
+ * useful
+ */
+#ifndef WIN32
+ if (OsSignal (SIGUSR1, SIG_IGN) == SIG_IGN)
+ RunFromSmartParent = TRUE;
+ ParentProcess = getppid ();
+ if (RunFromSmartParent) {
+ if (ParentProcess > 0) {
+ kill (ParentProcess, SIGUSR1);
+ }
+ }
+#endif
+#ifdef XDMCP
+ XdmcpInit ();
+#endif
+}
+
+void
+ResetWellKnownSockets ()
+{
+ int i;
+
+ ResetOsBuffers();
+
+ for (i = 0; i < ListenTransCount; i++)
+ {
+ int status = _XSERVTransResetListener (ListenTransConns[i]);
+
+ if (status != TRANS_RESET_NOOP)
+ {
+ if (status == TRANS_RESET_FAILURE)
+ {
+ /*
+ * ListenTransConns[i] freed by xtrans.
+ * Remove it from out list.
+ */
+
+ FD_CLR (ListenTransFds[i], &WellKnownConnections);
+ ListenTransFds[i] = ListenTransFds[ListenTransCount - 1];
+ ListenTransConns[i] = ListenTransConns[ListenTransCount - 1];
+ ListenTransCount -= 1;
+ i -= 1;
+ }
+ else if (status == TRANS_RESET_NEW_FD)
+ {
+ /*
+ * A new file descriptor was allocated (the old one was closed)
+ */
+
+ int newfd = _XSERVTransGetConnectionNumber (ListenTransConns[i]);
+
+ FD_CLR (ListenTransFds[i], &WellKnownConnections);
+ ListenTransFds[i] = newfd;
+ FD_SET(newfd, &WellKnownConnections);
+ }
+ }
+ }
+
+ ResetAuthorization ();
+ ResetHosts(display);
+ /*
+ * See above in CreateWellKnownSockets about SIGUSR1
+ */
+#ifndef WIN32
+ if (RunFromSmartParent) {
+ if (ParentProcess > 0) {
+ kill (ParentProcess, SIGUSR1);
+ }
+ }
+#endif
+ /*
+ * restart XDMCP
+ */
+#ifdef XDMCP
+ XdmcpReset ();
+#endif
+}
+
+void
+CloseWellKnownConnections()
+{
+ int i;
+
+ for (i = 0; i < ListenTransCount; i++)
+ _XSERVTransClose (ListenTransConns[i]);
+}
+
+static void
+AuthAudit (client, letin, saddr, len, proto_n, auth_proto, auth_id)
+ ClientPtr client;
+ Bool letin;
+ struct sockaddr *saddr;
+ int len;
+ unsigned short proto_n;
+ char *auth_proto;
+ int auth_id;
+{
+ char addr[128];
+ char *out = addr;
+
+ if (!((OsCommPtr)client->osPrivate)->trans_conn) {
+ strcpy(addr, "LBX proxy at ");
+ out += strlen(addr);
+ }
+ if (!len)
+ strcpy(out, "local host");
+ else
+ switch (saddr->sa_family)
+ {
+ case AF_UNSPEC:
+#if defined(UNIXCONN) || defined(LOCALCONN) || defined(OS2PIPECONN)
+ case AF_UNIX:
+#endif
+ strcpy(out, "local host");
+ break;
+#if defined(TCPCONN) || defined(STREAMSCONN) || defined(MNX_TCPCONN)
+ case AF_INET:
+ sprintf(out, "IP %s port %d",
+ inet_ntoa(((struct sockaddr_in *) saddr)->sin_addr),
+ ntohs(((struct sockaddr_in *) saddr)->sin_port));
+ break;
+#endif
+#ifdef DNETCONN
+ case AF_DECnet:
+ sprintf(out, "DN %s",
+ dnet_ntoa(&((struct sockaddr_dn *) saddr)->sdn_add));
+ break;
+#endif
+#ifdef AMRPCCONN
+ case FamilyAmoeba:
+ sprintf(addr, "AM %s", saddr);
+ break;
+#endif
+#if defined(AMTCPCONN) && !(defined(TCPCONN) || defined(STREAMSCONN))
+ case AF_INET:
+ sprintf(addr, "AMIP %s", inet_ntoa(*((ipaddr_t *) saddr)));
+ break;
+#endif
+ default:
+ strcpy(out, "unknown address");
+ }
+ if (letin)
+ AuditF("client %d connected from %s\n", client->index, addr);
+ else
+ AuditF("client %d rejected from %s\n", client->index, addr);
+ if (proto_n)
+ AuditF(" Auth name: %.*s ID: %d\n", proto_n, auth_proto, auth_id);
+}
+
+XID
+AuthorizationIDOfClient(client)
+ ClientPtr client;
+{
+ if (client->osPrivate)
+ return ((OsCommPtr)client->osPrivate)->auth_id;
+ else
+ return None;
+}
+
+
+/*****************************************************************
+ * ClientAuthorized
+ *
+ * Sent by the client at connection setup:
+ * typedef struct _xConnClientPrefix {
+ * CARD8 byteOrder;
+ * BYTE pad;
+ * CARD16 majorVersion, minorVersion;
+ * CARD16 nbytesAuthProto;
+ * CARD16 nbytesAuthString;
+ * } xConnClientPrefix;
+ *
+ * It is hoped that eventually one protocol will be agreed upon. In the
+ * mean time, a server that implements a different protocol than the
+ * client expects, or a server that only implements the host-based
+ * mechanism, will simply ignore this information.
+ *
+ *****************************************************************/
+
+char *
+ClientAuthorized(client, proto_n, auth_proto, string_n, auth_string)
+ ClientPtr client;
+ char *auth_proto, *auth_string;
+ unsigned int proto_n, string_n;
+{
+ register OsCommPtr priv;
+ Xtransaddr *from = NULL;
+ int family;
+ int fromlen;
+ XID auth_id;
+ char *reason = NULL;
+ XtransConnInfo trans_conn;
+ int restore_trans_conn = 0;
+ ClientPtr lbxpc;
+
+ priv = (OsCommPtr)client->osPrivate;
+ trans_conn = priv->trans_conn;
+
+#ifdef LBX
+ if (!trans_conn) {
+ /*
+ * Since trans_conn is NULL, this must be a proxy's client for
+ * which we have NO address. Therefore, we will temporarily
+ * set the client's trans_conn to the proxy's trans_conn and
+ * after CheckAuthorization the client's trans_conn will be
+ * restored.
+ *
+ * If XDM-AUTHORIZATION-1 is being used, CheckAuthorization
+ * will eventually call XdmAuthorizationValidate and this
+ * later function may use the client's trans_conn to get the
+ * client's address. Since a XDM-AUTH-1 auth string includes
+ * the client's address, this address is compared to the address
+ * in the client's trans_conn. If the proxy and client are
+ * on the same host, the comparison will fail; otherwise the
+ * comparison will fail and the client will not be authorized
+ * to connect to the server.
+ *
+ * The basis for this additional code is to prevent a
+ * NULL pointer dereference of the client's trans_conn.
+ * The fundamental problem - the fact that the client's
+ * trans_conn is NULL - is because the NewClient
+ * request in version 1.0 of the LBX protocol does not
+ * send the client's address to the server. When the
+ * spec is changed and the client's address is sent to
+ * server in the NewClient request, this additional code
+ * should be removed.
+ *
+ * See defect number XWSog08218 for more information.
+ */
+ lbxpc = LbxProxyClient(priv->proxy);
+ trans_conn = ((OsCommPtr)lbxpc->osPrivate)->trans_conn;
+ priv->trans_conn = trans_conn;
+ restore_trans_conn = 1;
+ }
+#endif
+
+ auth_id = CheckAuthorization (proto_n, auth_proto,
+ string_n, auth_string, client, &reason);
+
+#ifdef LBX
+ if (restore_trans_conn) {
+ /*
+ * Restore client's trans_conn state
+ */
+ priv = (OsCommPtr)client->osPrivate;
+ priv->trans_conn = NULL;
+
+ trans_conn = NULL;
+ }
+
+#endif
+
+#ifdef LBX
+ if (!trans_conn) {
+ /*
+ * Use the proxy's trans_conn
+ */
+ trans_conn = ((OsCommPtr)lbxpc->osPrivate)->trans_conn;
+ if (auth_id == (XID) ~0L && !GetAccessControl())
+ auth_id = ((OsCommPtr)lbxpc->osPrivate)->auth_id;
+#ifdef XCSECURITY
+ else if (auth_id != (XID) ~0L && !SecuritySameLevel(lbxpc, auth_id)) {
+ auth_id = (XID) ~0L;
+ reason = "Client trust level differs from that of LBX Proxy";
+ }
+#endif
+ }
+#endif
+ if (auth_id == (XID) ~0L)
+ {
+ if (
+#ifdef XCSECURITY
+ (proto_n == 0 ||
+ strncmp (auth_proto, XSecurityAuthorizationName, proto_n) != 0) &&
+#endif
+ _XSERVTransGetPeerAddr (trans_conn,
+ &family, &fromlen, &from) != -1)
+ {
+#ifdef AMRPCCONN
+ /* Amoeba RPC connections are already checked by the capability. */
+ if (family == FamilyAmoeba) {
+ auth_id = (XID) 0;
+ }
+ else
+#endif
+ if (
+#ifdef LBX
+ !priv->trans_conn ||
+#endif
+ InvalidHost ((struct sockaddr *) from, fromlen))
+ AuthAudit(client, FALSE, (struct sockaddr *) from,
+ fromlen, proto_n, auth_proto, auth_id);
+ else
+ {
+ auth_id = (XID) 0;
+ if (auditTrailLevel > 1)
+ AuthAudit(client, TRUE,
+ (struct sockaddr *) from, fromlen,
+ proto_n, auth_proto, auth_id);
+ }
+
+ xfree ((char *) from);
+ }
+
+ if (auth_id == (XID) ~0L)
+ if (reason)
+ return reason;
+ else
+ return "Client is not authorized to connect to Server";
+ }
+ else if (auditTrailLevel > 1)
+ {
+ if (_XSERVTransGetPeerAddr (trans_conn,
+ &family, &fromlen, &from) != -1)
+ {
+ AuthAudit(client, TRUE, (struct sockaddr *) from, fromlen,
+ proto_n, auth_proto, auth_id);
+
+ xfree ((char *) from);
+ }
+ }
+ priv->auth_id = auth_id;
+ priv->conn_time = 0;
+
+#ifdef XDMCP
+ /* indicate to Xdmcp protocol that we've opened new client */
+ XdmcpOpenDisplay(priv->fd);
+#endif /* XDMCP */
+#ifdef XAPPGROUP
+ if (ClientStateCallback)
+ XagCallClientStateChange (client);
+#endif
+ /* At this point, if the client is authorized to change the access control
+ * list, we should getpeername() information, and add the client to
+ * the selfhosts list. It's not really the host machine, but the
+ * true purpose of the selfhosts list is to see who may change the
+ * access control list.
+ */
+ return((char *)NULL);
+}
+
+static ClientPtr
+#ifdef LBX
+AllocNewConnection (trans_conn, fd, conn_time, Flush, Close, proxy)
+#else
+AllocNewConnection (trans_conn, fd, conn_time)
+#endif
+ XtransConnInfo trans_conn;
+ int fd;
+ CARD32 conn_time;
+#ifdef LBX
+ int (*Flush)();
+ void (*Close)();
+ LbxProxyPtr proxy;
+#endif
+{
+ OsCommPtr oc;
+ ClientPtr client;
+
+ if (
+#ifdef LBX
+ trans_conn &&
+#endif
+#ifndef WIN32
+ fd >= lastfdesc
+#else
+ XFD_SETCOUNT(&AllClients) >= MaxClients
+#endif
+ )
+ return NullClient;
+ oc = (OsCommPtr)xalloc(sizeof(OsCommRec));
+ if (!oc)
+ return NullClient;
+ oc->trans_conn = trans_conn;
+ oc->fd = fd;
+ oc->input = (ConnectionInputPtr)NULL;
+ oc->output = (ConnectionOutputPtr)NULL;
+ oc->auth_id = None;
+ oc->conn_time = conn_time;
+#ifdef LBX
+ oc->proxy = proxy;
+ oc->Flush = Flush;
+ oc->Close = Close;
+ oc->largereq = (ConnectionInputPtr) NULL;
+#endif
+ if (!(client = NextAvailableClient((pointer)oc)))
+ {
+ xfree (oc);
+ return NullClient;
+ }
+#ifdef LBX
+ if (trans_conn)
+#endif
+ {
+ ConnectionTranslation[fd] = client->index;
+ if (GrabInProgress)
+ {
+ FD_SET(fd, &SavedAllClients);
+ FD_SET(fd, &SavedAllSockets);
+ }
+ else
+ {
+ FD_SET(fd, &AllClients);
+ FD_SET(fd, &AllSockets);
+ }
+ }
+
+#ifdef DEBUG
+ ErrorF("AllocNewConnection: client index = %d, socket fd = %d\n",
+ client->index, fd);
+#endif
+
+ return client;
+}
+
+#ifdef LBX
+
+int
+ClientConnectionNumber (client)
+ ClientPtr client;
+{
+ OsCommPtr oc = (OsCommPtr) client->osPrivate;
+
+ return oc->fd;
+}
+
+ClientPtr
+AllocLbxClientConnection (client, proxy)
+ ClientPtr client;
+ LbxProxyPtr proxy;
+{
+ OsCommPtr oc = (OsCommPtr) client->osPrivate;
+
+ return AllocNewConnection ((XtransConnInfo)NULL, oc->fd, GetTimeInMillis(),
+ LbxFlushClient, LbxCloseClient, proxy);
+}
+
+void
+LbxProxyConnection (client, proxy)
+ ClientPtr client;
+ LbxProxyPtr proxy;
+{
+ OsCommPtr oc = (OsCommPtr) client->osPrivate;
+
+ FlushClient(client, oc, (char *)NULL, 0);
+ oc->proxy = proxy;
+ oc->Flush = LbxFlushClient;
+ oc->Close = LbxCloseClient;
+ LbxPrimeInput(client, proxy);
+}
+
+#endif
+
+/*****************
+ * EstablishNewConnections
+ * If anyone is waiting on listened sockets, accept them.
+ * Returns a mask with indices of new clients. Updates AllClients
+ * and AllSockets.
+ *****************/
+
+/*ARGSUSED*/
+Bool
+EstablishNewConnections(clientUnused, closure)
+ ClientPtr clientUnused;
+ pointer closure;
+{
+ fd_set readyconnections; /* set of listeners that are ready */
+ int curconn; /* fd of listener that's ready */
+ register int newconn; /* fd of new client */
+ CARD32 connect_time;
+ register int i;
+ register ClientPtr client;
+ register OsCommPtr oc;
+ fd_set tmask;
+
+#ifndef AMOEBA
+ XFD_ANDSET (&tmask, (fd_set*)closure, &WellKnownConnections);
+ XFD_COPYSET(&tmask, &readyconnections);
+ if (!XFD_ANYSET(&readyconnections))
+ return TRUE;
+ connect_time = GetTimeInMillis();
+ /* kill off stragglers */
+ for (i=1; i<currentMaxClients; i++)
+ {
+ if (client = clients[i])
+ {
+ oc = (OsCommPtr)(client->osPrivate);
+ if (oc && (oc->conn_time != 0) &&
+ (connect_time - oc->conn_time) >= TimeOutValue ||
+ client->noClientException != Success && !client->clientGone)
+ CloseDownClient(client);
+ }
+ }
+#else /* AMOEBA */
+ /* EstablishNewConnections is only called when there is one new
+ * connection waiting on the first transport.
+ */
+ readyconnections = 1;
+#endif /* AMOEBA */
+#ifndef WIN32
+ for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++)
+ {
+ while (readyconnections.fds_bits[i])
+#else
+ for (i = 0; i < XFD_SETCOUNT(&readyconnections); i++)
+#endif
+ {
+ XtransConnInfo trans_conn, new_trans_conn;
+ int status;
+
+#ifndef WIN32
+ curconn = ffs (readyconnections.fds_bits[i]) - 1;
+ readyconnections.fds_bits[i] &= ~(1L << curconn);
+ curconn += (i * (sizeof(fd_mask)*8));
+#else
+ curconn = XFD_FD(&readyconnections, i);
+#endif
+
+ if ((trans_conn = lookup_trans_conn (curconn)) == NULL)
+ continue;
+
+ if ((new_trans_conn = _XSERVTransAccept (trans_conn, &status)) == NULL)
+ continue;
+
+ newconn = _XSERVTransGetConnectionNumber (new_trans_conn);
+
+ _XSERVTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1);
+
+ if (!AllocNewConnection (new_trans_conn, newconn, connect_time
+#ifdef LBX
+ , StandardFlushClient,
+ CloseDownFileDescriptor, (LbxProxyPtr)NULL
+#endif
+ ))
+ {
+ ErrorConnMax(new_trans_conn);
+ _XSERVTransClose(new_trans_conn);
+ }
+ }
+#ifndef WIN32
+ }
+#endif
+ return TRUE;
+}
+
+#define NOROOM "Maximum number of clients reached"
+
+/************
+ * ErrorConnMax
+ * Fail a connection due to lack of client or file descriptor space
+ ************/
+
+static void
+ErrorConnMax(trans_conn)
+XtransConnInfo trans_conn;
+{
+ register int fd = _XSERVTransGetConnectionNumber (trans_conn);
+ xConnSetupPrefix csp;
+ char pad[3];
+ struct iovec iov[3];
+ char byteOrder = 0;
+ int whichbyte = 1;
+#ifndef AMOEBA
+ struct timeval waittime;
+ fd_set mask;
+
+ /* if these seems like a lot of trouble to go to, it probably is */
+ waittime.tv_sec = BOTIMEOUT / MILLI_PER_SECOND;
+ waittime.tv_usec = (BOTIMEOUT % MILLI_PER_SECOND) *
+ (1000000 / MILLI_PER_SECOND);
+ FD_ZERO(&mask);
+ FD_SET(fd, &mask);
+ (void)Select(fd + 1, &mask, NULL, NULL, &waittime);
+#endif
+ /* try to read the byte-order of the connection */
+ (void)_XSERVTransRead(trans_conn, &byteOrder, 1);
+ if ((byteOrder == 'l') || (byteOrder == 'B'))
+ {
+ csp.success = xFalse;
+ csp.lengthReason = sizeof(NOROOM) - 1;
+ csp.length = (sizeof(NOROOM) + 2) >> 2;
+ csp.majorVersion = X_PROTOCOL;
+ csp.minorVersion = X_PROTOCOL_REVISION;
+ if (((*(char *) &whichbyte) && (byteOrder == 'B')) ||
+ (!(*(char *) &whichbyte) && (byteOrder == 'l')))
+ {
+ swaps(&csp.majorVersion, whichbyte);
+ swaps(&csp.minorVersion, whichbyte);
+ swaps(&csp.length, whichbyte);
+ }
+ iov[0].iov_len = sz_xConnSetupPrefix;
+ iov[0].iov_base = (char *) &csp;
+ iov[1].iov_len = csp.lengthReason;
+ iov[1].iov_base = NOROOM;
+ iov[2].iov_len = (4 - (csp.lengthReason & 3)) & 3;
+ iov[2].iov_base = pad;
+ (void)_XSERVTransWritev(trans_conn, iov, 3);
+ }
+}
+
+/************
+ * CloseDownFileDescriptor:
+ * Remove this file descriptor and it's I/O buffers, etc.
+ ************/
+
+#ifdef LBX
+void
+CloseDownFileDescriptor(client)
+ ClientPtr client;
+#else
+static void
+CloseDownFileDescriptor(oc)
+ register OsCommPtr oc;
+#endif
+{
+#ifdef LBX
+ register OsCommPtr oc = (OsCommPtr) client->osPrivate;
+#endif
+ int connection = oc->fd;
+
+ if (oc->trans_conn) {
+ _XSERVTransDisconnect(oc->trans_conn);
+ _XSERVTransClose(oc->trans_conn);
+ }
+#ifdef LBX
+ ConnectionTranslation[connection] = 0;
+#else
+ FreeOsBuffers(oc);
+#endif
+ FD_CLR(connection, &AllSockets);
+ FD_CLR(connection, &AllClients);
+ FD_CLR(connection, &ClientsWithInput);
+ FD_CLR(connection, &GrabImperviousClients);
+ if (GrabInProgress)
+ {
+ FD_CLR(connection, &SavedAllSockets);
+ FD_CLR(connection, &SavedAllClients);
+ FD_CLR(connection, &SavedClientsWithInput);
+ }
+ FD_CLR(connection, &ClientsWriteBlocked);
+ if (!XFD_ANYSET(&ClientsWriteBlocked))
+ AnyClientsWriteBlocked = FALSE;
+ FD_CLR(connection, &OutputPending);
+#ifndef LBX
+ xfree(oc);
+#endif
+}
+
+/*****************
+ * CheckConections
+ * Some connection has died, go find which one and shut it down
+ * The file descriptor has been closed, but is still in AllClients.
+ * If would truly be wonderful if select() would put the bogus
+ * file descriptors in the exception mask, but nooooo. So we have
+ * to check each and every socket individually.
+ *****************/
+
+void
+CheckConnections()
+{
+#ifndef WIN32
+ fd_mask mask;
+#endif
+ fd_set tmask;
+ register int curclient, curoff;
+ int i;
+ struct timeval notime;
+ int r;
+#ifdef WIN32
+ fd_set savedAllClients;
+#endif
+
+#ifndef AMOEBA
+ notime.tv_sec = 0;
+ notime.tv_usec = 0;
+
+#ifndef WIN32
+ for (i=0; i<howmany(XFD_SETSIZE, NFDBITS); i++)
+ {
+ mask = AllClients.fds_bits[i];
+ while (mask)
+ {
+ curoff = ffs (mask) - 1;
+ curclient = curoff + (i * (sizeof(fd_mask)*8));
+ FD_ZERO(&tmask);
+ FD_SET(curclient, &tmask);
+ r = Select (curclient + 1, &tmask, NULL, NULL, &notime);
+ if (r < 0)
+ CloseDownClient(clients[ConnectionTranslation[curclient]]);
+ mask &= ~(1L << curoff);
+ }
+ }
+#else
+ XFD_COPYSET(&AllClients, &savedAllClients);
+ for (i = 0; i < XFD_SETCOUNT(&savedAllClients); i++)
+ {
+ curclient = XFD_FD(&savedAllClients, i);
+ FD_ZERO(&tmask);
+ FD_SET(curclient, &tmask);
+ r = Select (curclient + 1, &tmask, NULL, NULL, &notime);
+ if (r < 0)
+ CloseDownClient(clients[ConnectionTranslation[curclient]]);
+ }
+#endif
+#endif
+}
+
+
+/*****************
+ * CloseDownConnection
+ * Delete client from AllClients and free resources
+ *****************/
+
+void
+CloseDownConnection(client)
+ ClientPtr client;
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+
+ if (oc->output && oc->output->count)
+ FlushClient(client, oc, (char *)NULL, 0);
+#ifdef XDMCP
+ XdmcpCloseDisplay(oc->fd);
+#endif
+#ifndef LBX
+ CloseDownFileDescriptor(oc);
+#else
+ (*oc->Close) (client);
+ FreeOsBuffers(oc);
+ xfree(oc);
+#endif
+ client->osPrivate = (pointer)NULL;
+ if (auditTrailLevel > 1)
+ AuditF("client %d disconnected\n", client->index);
+}
+
+
+AddEnabledDevice(fd)
+ int fd;
+{
+ FD_SET(fd, &EnabledDevices);
+ FD_SET(fd, &AllSockets);
+ if (GrabInProgress)
+ FD_SET(fd, &SavedAllSockets);
+}
+
+
+RemoveEnabledDevice(fd)
+ int fd;
+{
+ FD_CLR(fd, &EnabledDevices);
+ FD_CLR(fd, &AllSockets);
+ if (GrabInProgress)
+ FD_CLR(fd, &SavedAllSockets);
+}
+
+/*****************
+ * OnlyListenToOneClient:
+ * Only accept requests from one client. Continue to handle new
+ * connections, but don't take any protocol requests from the new
+ * ones. Note that if GrabInProgress is set, EstablishNewConnections
+ * needs to put new clients into SavedAllSockets and SavedAllClients.
+ * Note also that there is no timeout for this in the protocol.
+ * This routine is "undone" by ListenToAllClients()
+ *****************/
+
+OnlyListenToOneClient(client)
+ ClientPtr client;
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ int connection = oc->fd;
+
+ if (! GrabInProgress)
+ {
+ XFD_COPYSET(&ClientsWithInput, &SavedClientsWithInput);
+ XFD_ANDSET(&ClientsWithInput,
+ &ClientsWithInput, &GrabImperviousClients);
+ if (FD_ISSET(connection, &SavedClientsWithInput))
+ {
+ FD_CLR(connection, &SavedClientsWithInput);
+ FD_SET(connection, &ClientsWithInput);
+ }
+ XFD_UNSET(&SavedClientsWithInput, &GrabImperviousClients);
+ XFD_COPYSET(&AllSockets, &SavedAllSockets);
+ XFD_COPYSET(&AllClients, &SavedAllClients);
+ XFD_UNSET(&AllSockets, &AllClients);
+ XFD_ANDSET(&AllClients, &AllClients, &GrabImperviousClients);
+ FD_SET(connection, &AllClients);
+ XFD_ORSET(&AllSockets, &AllSockets, &AllClients);
+ GrabInProgress = client->index;
+ }
+}
+
+/****************
+ * ListenToAllClients:
+ * Undoes OnlyListentToOneClient()
+ ****************/
+
+ListenToAllClients()
+{
+ if (GrabInProgress)
+ {
+ XFD_ORSET(&AllSockets, &AllSockets, &SavedAllSockets);
+ XFD_ORSET(&AllClients, &AllClients, &SavedAllClients);
+ XFD_ORSET(&ClientsWithInput, &ClientsWithInput, &SavedClientsWithInput);
+ GrabInProgress = 0;
+ }
+}
+
+/****************
+ * IgnoreClient
+ * Removes one client from input masks.
+ * Must have cooresponding call to AttendClient.
+ ****************/
+
+IgnoreClient (client)
+ ClientPtr client;
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ int connection = oc->fd;
+#ifdef LBX
+ LbxClientPtr lbxClient = LbxClient(client);
+#endif
+
+ isItTimeToYield = TRUE;
+#ifdef LBX
+ if (lbxClient) {
+ lbxClient->ignored = TRUE;
+ return;
+ }
+#endif
+ if (!GrabInProgress || FD_ISSET(connection, &AllClients))
+ {
+ if (FD_ISSET (connection, &ClientsWithInput))
+ FD_SET(connection, &IgnoredClientsWithInput);
+ else
+ FD_CLR(connection, &IgnoredClientsWithInput);
+ FD_CLR(connection, &ClientsWithInput);
+ FD_CLR(connection, &AllSockets);
+ FD_CLR(connection, &AllClients);
+ FD_CLR(connection, &LastSelectMask);
+ }
+ else
+ {
+ if (FD_ISSET (connection, &SavedClientsWithInput))
+ FD_SET(connection, &IgnoredClientsWithInput);
+ else
+ FD_CLR(connection, &IgnoredClientsWithInput);
+ FD_CLR(connection, &SavedClientsWithInput);
+ FD_CLR(connection, &SavedAllSockets);
+ FD_CLR(connection, &SavedAllClients);
+ }
+}
+
+/****************
+ * AttendClient
+ * Adds one client back into the input masks.
+ ****************/
+
+AttendClient (client)
+ ClientPtr client;
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ int connection = oc->fd;
+#ifdef LBX
+ LbxClientPtr lbxClient = LbxClient(client);
+
+ if (lbxClient) {
+ lbxClient->ignored = FALSE;
+ return;
+ }
+#endif
+ if (!GrabInProgress || GrabInProgress == client->index ||
+ FD_ISSET(connection, &GrabImperviousClients))
+ {
+ FD_SET(connection, &AllClients);
+ FD_SET(connection, &AllSockets);
+ FD_SET(connection, &LastSelectMask);
+ if (FD_ISSET (connection, &IgnoredClientsWithInput))
+ FD_SET(connection, &ClientsWithInput);
+ }
+ else
+ {
+ FD_SET(connection, &SavedAllClients);
+ FD_SET(connection, &SavedAllSockets);
+ if (FD_ISSET(connection, &IgnoredClientsWithInput))
+ FD_SET(connection, &SavedClientsWithInput);
+ }
+}
+
+/* make client impervious to grabs; assume only executing client calls this */
+
+MakeClientGrabImpervious(client)
+ ClientPtr client;
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ int connection = oc->fd;
+
+ FD_SET(connection, &GrabImperviousClients);
+
+ if (ServerGrabCallback)
+ {
+ ServerGrabInfoRec grabinfo;
+ grabinfo.client = client;
+ grabinfo.grabstate = CLIENT_IMPERVIOUS;
+ CallCallbacks(&ServerGrabCallback, &grabinfo);
+ }
+}
+
+/* make client pervious to grabs; assume only executing client calls this */
+
+MakeClientGrabPervious(client)
+ ClientPtr client;
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ int connection = oc->fd;
+
+ FD_CLR(connection, &GrabImperviousClients);
+ if (GrabInProgress && (GrabInProgress != client->index))
+ {
+ if (FD_ISSET(connection, &ClientsWithInput))
+ {
+ FD_SET(connection, &SavedClientsWithInput);
+ FD_CLR(connection, &ClientsWithInput);
+ }
+ FD_CLR(connection, &AllSockets);
+ FD_CLR(connection, &AllClients);
+ isItTimeToYield = TRUE;
+ }
+
+ if (ServerGrabCallback)
+ {
+ ServerGrabInfoRec grabinfo;
+ grabinfo.client = client;
+ grabinfo.grabstate = CLIENT_PERVIOUS;
+ CallCallbacks(&ServerGrabCallback, &grabinfo);
+ }
+}
+
+#ifdef AIXV3
+
+static fd_set pendingActiveClients;
+static BOOL reallyGrabbed;
+
+/****************
+* DontListenToAnybody:
+* Don't listen to requests from any clients. Continue to handle new
+* connections, but don't take any protocol requests from anybody.
+* We have to take care if there is already a grab in progress, though.
+* Undone by PayAttentionToClientsAgain. We also have to be careful
+* not to accept any more input from the currently dispatched client.
+* we do this be telling dispatch it is time to yield.
+
+* We call this when the server loses access to the glass
+* (user hot-keys away). This looks like a grab by the
+* server itself, but gets a little tricky if there is already
+* a grab in progress.
+******************/
+
+void
+DontListenToAnybody()
+{
+ if (!GrabInProgress)
+ {
+ XFD_COPYSET(&ClientsWithInput, &SavedClientsWithInput);
+ XFD_COPYSET(&AllSockets, &SavedAllSockets);
+ XFD_COPYSET(&AllClients, &SavedAllClients);
+ GrabInProgress = TRUE;
+ reallyGrabbed = FALSE;
+ }
+ else
+ {
+ XFD_COPYSET(&AllClients, &pendingActiveClients);
+ reallyGrabbed = TRUE;
+ }
+ FD_ZERO(&ClientsWithInput);
+ XFD_UNSET(&AllSockets, &AllClients);
+ FD_ZERO(&AllClients);
+ isItTimeToYield = TRUE;
+}
+
+void
+PayAttentionToClientsAgain()
+{
+ if (reallyGrabbed)
+ {
+ XFD_ORSET(&AllSockets, &AllSockets, &pendingActiveClients);
+ XFD_ORSET(&AllClients, &AllClients, &pendingActiveClients);
+ }
+ else
+ {
+ ListenToAllClients();
+ }
+ reallyGrabbed = FALSE;
+}
+
+#endif
diff --git a/xc/programs/Xserver/os/decompress.c b/xc/programs/Xserver/os/decompress.c
new file mode 100644
index 000000000..31fd9109a
--- /dev/null
+++ b/xc/programs/Xserver/os/decompress.c
@@ -0,0 +1,383 @@
+/* $TOG: decompress.c /main/6 1998/02/09 15:12:01 kaleb $ */
+/*
+
+Copyright 1990, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+/* $XFree86: xc/programs/Xserver/os/decompress.c,v 1.2 1999/01/31 12:22:20 dawes Exp $ */
+
+/*
+ * decompress - cat a compressed file
+ */
+
+#include <stdio.h>
+
+#ifdef TEST
+#define xalloc(s) malloc(s)
+#define xfree(s) free(s)
+
+typedef char *FID;
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ctype.h>
+
+#else
+#include "Xos.h"
+#include "misc.h"
+#endif
+
+#undef BITS
+#define BITS 16
+
+/*
+ * a code_int must be able to hold 2**BITS values of type int, and also -1
+ */
+#if BITS > 15
+typedef long int code_int;
+#else
+typedef int code_int;
+#endif
+
+typedef long int count_int;
+
+#ifdef NO_UCHAR
+ typedef char char_type;
+#else
+ typedef unsigned char char_type;
+#endif /* UCHAR */
+
+static char_type magic_header[] = { "\037\235" }; /* 1F 9D */
+
+/* Defines for third byte of header */
+#define BIT_MASK 0x1f
+#define BLOCK_MASK 0x80
+/* Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is
+ a fourth header byte (for expansion).
+*/
+
+#define INIT_BITS 9 /* initial number of bits/code */
+
+#ifdef COMPATIBLE /* But wrong! */
+# define MAXCODE(n_bits) (1 << (n_bits) - 1)
+#else
+# define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
+#endif /* COMPATIBLE */
+
+static code_int getcode();
+
+/*
+ * the next two codes should not be changed lightly, as they must not
+ * lie within the contiguous general code space.
+ */
+#define FIRST 257 /* first free entry */
+#define CLEAR 256 /* table clear output code */
+
+#define STACK_SIZE 8192
+
+typedef struct _compressedFILE {
+ FILE *file;
+
+ char_type *stackp;
+ code_int oldcode;
+ char_type finchar;
+
+ int block_compress;
+ int maxbits;
+ code_int maxcode, maxmaxcode;
+
+ code_int free_ent;
+ int clear_flg;
+ int n_bits;
+
+ /* bit buffer */
+ int offset, size;
+ char_type buf[BITS];
+
+ char_type de_stack[STACK_SIZE];
+ char_type *tab_suffix;
+ unsigned short *tab_prefix;
+} CompressedFile;
+
+static int hsize_table[] = {
+ 5003, /* 12 bits - 80% occupancy */
+ 9001, /* 13 bits - 91% occupancy */
+ 18013, /* 14 bits - 91% occupancy */
+ 35023, /* 15 bits - 94% occupancy */
+ 69001 /* 16 bits - 95% occupancy */
+};
+
+FID
+CompressedFontFileInit (f)
+ FILE *f;
+{
+ int code;
+ int maxbits;
+ int hsize;
+ CompressedFile *file;
+ int extra;
+
+ if ((getc(f) != (magic_header[0] & 0xFF)) ||
+ (getc(f) != (magic_header[1] & 0xFF)))
+ {
+ return 0;
+ }
+ code = getc (f);
+ maxbits = code & BIT_MASK;
+ if (maxbits > BITS || maxbits < 12)
+ return 0;
+ hsize = hsize_table[maxbits - 12];
+ extra = (1 << maxbits) * sizeof (char_type) +
+ hsize * sizeof (unsigned short);
+ file = (CompressedFile *) xalloc (sizeof (CompressedFile) + extra);
+ if (!file)
+ return 0;
+ file->file = f;
+ file->maxbits = maxbits;
+ file->block_compress = code & BLOCK_MASK;
+ file->maxmaxcode = 1 << file->maxbits;
+ file->tab_suffix = (char_type *) &file[1];
+ file->tab_prefix = (unsigned short *) (file->tab_suffix + file->maxmaxcode);
+ /*
+ * As above, initialize the first 256 entries in the table.
+ */
+ file->maxcode = MAXCODE(file->n_bits = INIT_BITS);
+ for ( code = 255; code >= 0; code-- ) {
+ file->tab_prefix[code] = 0;
+ file->tab_suffix[code] = (char_type) code;
+ }
+ file->free_ent = ((file->block_compress) ? FIRST : 256 );
+ file->clear_flg = 0;
+ file->offset = 0;
+ file->size = 0;
+ file->stackp = file->de_stack;
+ file->finchar = file->oldcode = getcode (file);
+ if (file->oldcode != -1)
+ *file->stackp++ = file->finchar;
+ return (FID) file;
+}
+
+FILE *
+CompressedFontFileDone (fid)
+ FID fid;
+{
+ CompressedFile *file;
+ FILE *f;
+
+ file = (CompressedFile *) fid;
+ f = file->file;
+ xfree (file);
+ return f;
+}
+
+#define getdcchar(file) ((file)->stackp > (file)->de_stack ? (*--((file)->stackp)) : _filldcbuf (file))
+
+_filldcbuf (file)
+ CompressedFile *file;
+{
+ register char_type *stackp;
+ register code_int code, incode;
+
+ if (file->stackp > file->de_stack)
+ return *--file->stackp;
+
+ if (file->oldcode == -1)
+ return EOF;
+
+ stackp = file->stackp;
+ code = getcode (file);
+ if (code == -1)
+ return EOF;
+
+ if ( (code == CLEAR) && file->block_compress ) {
+ for ( code = 255; code >= 0; code-- )
+ file->tab_prefix[code] = 0;
+ file->clear_flg = 1;
+ file->free_ent = FIRST - 1;
+ if ( (code = getcode (file)) == -1 ) /* O, untimely death! */
+ return EOF;
+ }
+ incode = code;
+ /*
+ * Special case for KwKwK string.
+ */
+ if ( code >= file->free_ent ) {
+ *stackp++ = file->finchar;
+ code = file->oldcode;
+ }
+
+ /*
+ * Generate output characters in reverse order
+ */
+ while ( code >= 256 )
+ {
+ *stackp++ = file->tab_suffix[code];
+ code = file->tab_prefix[code];
+ }
+ file->finchar = file->tab_suffix[code];
+
+ /*
+ * Generate the new entry.
+ */
+ if ( (code=file->free_ent) < file->maxmaxcode ) {
+ file->tab_prefix[code] = (unsigned short)file->oldcode;
+ file->tab_suffix[code] = file->finchar;
+ file->free_ent = code+1;
+ }
+ /*
+ * Remember previous code.
+ */
+ file->oldcode = incode;
+ file->stackp = stackp;
+ return file->finchar;
+}
+
+/*****************************************************************
+ * TAG( getcode )
+ *
+ * Read one code from the standard input. If EOF, return -1.
+ * Inputs:
+ * stdin
+ * Outputs:
+ * code or -1 is returned.
+ */
+
+static char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
+
+static code_int
+getcode(file)
+ CompressedFile *file;
+{
+ register code_int code;
+ register int r_off, bits;
+ register char_type *bp = file->buf;
+ register FILE *fp;
+
+ if ( file->clear_flg > 0 || file->offset >= file->size ||
+ file->free_ent > file->maxcode )
+ {
+ /*
+ * If the next entry will be too big for the current code
+ * size, then we must increase the size. This implies reading
+ * a new buffer full, too.
+ */
+ if ( file->free_ent > file->maxcode ) {
+ file->n_bits++;
+ if ( file->n_bits == file->maxbits )
+ file->maxcode = file->maxmaxcode; /* won't get any bigger now */
+ else
+ file->maxcode = MAXCODE(file->n_bits);
+ }
+ if ( file->clear_flg > 0) {
+ file->maxcode = MAXCODE (file->n_bits = INIT_BITS);
+ file->clear_flg = 0;
+ }
+ bits = file->n_bits;
+ fp = file->file;
+ while (bits > 0 && (code = getc (fp)) != EOF)
+ {
+ *bp++ = code;
+ --bits;
+ }
+ bp = file->buf;
+ if (bits == file->n_bits)
+ return -1; /* end of file */
+ file->size = file->n_bits - bits;
+ file->offset = 0;
+ /* Round size down to integral number of codes */
+ file->size = (file->size << 3) - (file->n_bits - 1);
+ }
+ r_off = file->offset;
+ bits = file->n_bits;
+ /*
+ * Get to the first byte.
+ */
+ bp += (r_off >> 3);
+ r_off &= 7;
+ /* Get first part (low order bits) */
+#ifdef NO_UCHAR
+ code = ((*bp++ >> r_off) & rmask[8 - r_off]) & 0xff;
+#else
+ code = (*bp++ >> r_off);
+#endif /* NO_UCHAR */
+ bits -= (8 - r_off);
+ r_off = 8 - r_off; /* now, offset into code word */
+ /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
+ if ( bits >= 8 ) {
+#ifdef NO_UCHAR
+ code |= (*bp++ & 0xff) << r_off;
+#else
+ code |= *bp++ << r_off;
+#endif /* NO_UCHAR */
+ r_off += 8;
+ bits -= 8;
+ }
+ /* high order bits. */
+ code |= (*bp & rmask[bits]) << r_off;
+ file->offset += file->n_bits;
+
+ return code;
+}
+
+CompressedFontFileRead (buf, itemsize, nitems, fid)
+ char *buf;
+ unsigned itemsize;
+ unsigned nitems;
+ FID fid;
+{
+ CompressedFile *file;
+ int c;
+ int nbytes;
+
+ file = (CompressedFile *) fid;
+ nbytes = nitems * itemsize;
+ while (nbytes)
+ {
+ if ((c = getdcchar (file)) == EOF)
+ break;
+ *buf++ = c;
+ --nbytes;
+ }
+ return nitems - nbytes / itemsize;
+}
+
+CompressedFontFileSkip (bytes, fid)
+ unsigned bytes;
+ FID fid;
+{
+ int c;
+
+ while (bytes-- && ((c = getdcchar((CompressedFile *)fid)) != EOF))
+ ;
+ return c;
+}
+
+#ifdef TEST
+main ()
+{
+ CompressedFile *input;
+ int c;
+
+ input = (CompressedFile *) CompressedFontFileInit (stdin);
+ while ((c = getdcchar (input)) != -1)
+ putchar (c);
+}
+#endif
diff --git a/xc/programs/Xserver/os/genalloca.c b/xc/programs/Xserver/os/genalloca.c
new file mode 100644
index 000000000..ae4d2d7e1
--- /dev/null
+++ b/xc/programs/Xserver/os/genalloca.c
@@ -0,0 +1,189 @@
+/*
+ alloca -- (mostly) portable public-domain implementation -- D A Gwyn
+
+ This implementation of the PWB library alloca() function,
+ which is used to allocate space off the run-time stack so
+ that it is automatically reclaimed upon procedure exit,
+ was inspired by discussions with J. Q. Johnson of Cornell.
+
+ It should work under any C implementation that uses an
+ actual procedure stack (as opposed to a linked list of
+ frames). There are some preprocessor constants that can
+ be defined when compiling for your specific system, for
+ improved efficiency; however, the defaults should be okay.
+
+ The general concept of this implementation is to keep
+ track of all alloca()-allocated blocks, and reclaim any
+ that are found to be deeper in the stack than the current
+ invocation. This heuristic does not reclaim storage as
+ soon as it becomes invalid, but it will do so eventually.
+
+ As a special case, alloca(0) reclaims storage without
+ allocating any. It is a good idea to use alloca(0) in
+ your main control loop, etc. to force garbage collection.
+*/
+#ifndef lint
+static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */
+#endif
+
+#ifdef emacs
+#include "config.h"
+#ifdef static
+/* actually, only want this if static is defined as ""
+ -- this is for usg, in which emacs must undefine static
+ in order to make unexec workable
+ */
+#ifndef STACK_DIRECTION
+you
+lose
+-- must know STACK_DIRECTION at compile-time
+#endif /* STACK_DIRECTION undefined */
+#endif /* static */
+#endif /* emacs */
+
+#ifdef X3J11
+typedef void *pointer; /* generic pointer type */
+#else
+typedef char *pointer; /* generic pointer type */
+#endif
+
+#define NULL 0 /* null pointer constant */
+
+extern void Xfree();
+extern pointer Xalloc();
+
+/*
+ Define STACK_DIRECTION if you know the direction of stack
+ growth for your system; otherwise it will be automatically
+ deduced at run-time.
+
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+*/
+
+#ifndef STACK_DIRECTION
+#define STACK_DIRECTION 0 /* direction unknown */
+#endif
+
+#if STACK_DIRECTION != 0
+
+#define STACK_DIR STACK_DIRECTION /* known at compile-time */
+
+#else /* STACK_DIRECTION == 0; need run-time code */
+
+static int stack_dir; /* 1 or -1 once known */
+#define STACK_DIR stack_dir
+
+static void
+find_stack_direction (/* void */)
+{
+ static char *addr = NULL; /* address of first
+ `dummy', once known */
+ auto char dummy; /* to get stack address */
+
+ if (addr == NULL)
+ { /* initial entry */
+ addr = &dummy;
+
+ find_stack_direction (); /* recurse once */
+ }
+ else /* second entry */
+ if (&dummy > addr)
+ stack_dir = 1; /* stack grew upward */
+ else
+ stack_dir = -1; /* stack grew downward */
+}
+
+#endif /* STACK_DIRECTION == 0 */
+
+/*
+ An "alloca header" is used to:
+ (a) chain together all alloca()ed blocks;
+ (b) keep track of stack depth.
+
+ It is very important that sizeof(header) agree with malloc()
+ alignment chunk size. The following default should work okay.
+*/
+
+#ifndef ALIGN_SIZE
+#define ALIGN_SIZE sizeof(double)
+#endif
+
+typedef union hdr
+{
+ char align[ALIGN_SIZE]; /* to force sizeof(header) */
+ struct
+ {
+ union hdr *next; /* for chaining headers */
+ char *deep; /* for stack depth measure */
+ } h;
+} header;
+
+/*
+ alloca( size ) returns a pointer to at least `size' bytes of
+ storage which will be automatically reclaimed upon exit from
+ the procedure that called alloca(). Originally, this space
+ was supposed to be taken from the current stack frame of the
+ caller, but that method cannot be made to work for some
+ implementations of C, for example under Gould's UTX/32.
+*/
+
+static header *last_alloca_header = NULL; /* -> last alloca header */
+
+pointer
+alloca (size) /* returns pointer to storage */
+ unsigned size; /* # bytes to allocate */
+{
+ auto char probe; /* probes stack depth: */
+ register char *depth = &probe;
+
+#if STACK_DIRECTION == 0
+ if (STACK_DIR == 0) /* unknown growth direction */
+ find_stack_direction ();
+#endif
+
+ /* Reclaim garbage, defined as all alloca()ed storage that
+ was allocated from deeper in the stack than currently. */
+
+ {
+ register header *hp; /* traverses linked list */
+
+ for (hp = last_alloca_header; hp != NULL;)
+ if (STACK_DIR > 0 && hp->h.deep > depth
+ || STACK_DIR < 0 && hp->h.deep < depth)
+ {
+ register header *np = hp->h.next;
+
+ Xfree ((pointer) hp); /* collect garbage */
+
+ hp = np; /* -> next header */
+ }
+ else
+ break; /* rest are not deeper */
+
+ last_alloca_header = hp; /* -> last valid storage */
+ }
+
+ if (size == 0)
+ return NULL; /* no allocation required */
+
+ /* Allocate combined header + user data storage. */
+
+ {
+ register pointer new = Xalloc (sizeof (header) + size);
+ if (!new)
+ return NULL;
+ /* address of header */
+
+ ((header *)new)->h.next = last_alloca_header;
+ ((header *)new)->h.deep = depth;
+
+ last_alloca_header = (header *)new;
+
+ /* User storage begins just after header. */
+
+ return (pointer)((char *)new + sizeof(header));
+ }
+}
+
diff --git a/xc/programs/Xserver/os/hpsocket.c b/xc/programs/Xserver/os/hpsocket.c
new file mode 100644
index 000000000..88828ae3f
--- /dev/null
+++ b/xc/programs/Xserver/os/hpsocket.c
@@ -0,0 +1,62 @@
+/* $TOG: hpsocket.c /main/4 1998/02/09 15:12:11 kaleb $ */
+/*
+
+Copyright 1988, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+
+/*
+ * special socket routine for hp
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int
+set_socket_option (socket_id, option)
+int socket_id;
+char option;
+{
+ int optlen = 1;
+ char optval = 0x0;
+
+ getsockopt (socket_id, SOL_SOCKET, option, &optval, &optlen);
+
+ optval |= option;
+
+ setsockopt (socket_id, SOL_SOCKET, option, &optval, 1);
+}
+
+
+int
+unset_socket_option (socket_id, option)
+int socket_id;
+char option;
+{
+ int optlen = 1;
+ char optval = 0x0;
+
+ getsockopt (socket_id, SOL_SOCKET, option, &optval, &optlen);
+
+ optval &= ~option;
+
+ setsockopt (socket_id, SOL_SOCKET, option, &optval, 1);
+}
diff --git a/xc/programs/Xserver/os/io.c b/xc/programs/Xserver/os/io.c
new file mode 100644
index 000000000..bd675e22f
--- /dev/null
+++ b/xc/programs/Xserver/os/io.c
@@ -0,0 +1,1274 @@
+/***********************************************************
+
+Copyright 1987, 1989, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: io.c /main/74 1998/02/09 15:12:19 kaleb $ */
+/*****************************************************************
+ * i/o functions
+ *
+ * WriteToClient, ReadRequestFromClient
+ * InsertFakeRequest, ResetCurrentRequest
+ *
+ *****************************************************************/
+/* $XFree86: xc/programs/Xserver/os/io.c,v 3.20 1998/10/04 09:39:43 dawes Exp $ */
+
+#ifdef WIN32
+#include <X11/Xwinsock.h>
+#endif
+#include <stdio.h>
+#include <X11/Xtrans.h>
+#ifdef X_NOT_STDC_ENV
+extern int errno;
+#endif
+#include "Xmd.h"
+#include <errno.h>
+#if !defined(AMOEBA) && !defined(MINIX) && !defined(__EMX__) && !defined(WIN32)
+#ifndef Lynx
+#include <sys/uio.h>
+#else
+#include <uio.h>
+#endif
+#endif
+#include "X.h"
+#define NEED_REPLIES
+#include "Xproto.h"
+#include "os.h"
+#include "Xpoll.h"
+#include "osdep.h"
+#include "opaque.h"
+#include "dixstruct.h"
+#include "misc.h"
+#ifdef LBX
+#include "lbxserve.h"
+#endif
+
+CallbackListPtr ReplyCallback;
+CallbackListPtr FlushCallback;
+
+/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
+ * systems are broken and return EWOULDBLOCK when they should return EAGAIN
+ */
+#ifndef __EMX__
+#if defined(EAGAIN) && defined(EWOULDBLOCK)
+#define ETEST(err) (err == EAGAIN || err == EWOULDBLOCK)
+#else
+#ifdef EAGAIN
+#define ETEST(err) (err == EAGAIN)
+#else
+#define ETEST(err) (err == EWOULDBLOCK)
+#endif
+#endif
+#else /* __EMX__ Writing to full pipes may return ENOSPC */
+#define ETEST(err) (err == EAGAIN || err == EWOULDBLOCK || err == ENOSPC)
+#endif
+
+Bool CriticalOutputPending;
+int timesThisConnection = 0;
+ConnectionInputPtr FreeInputs = (ConnectionInputPtr)NULL;
+ConnectionOutputPtr FreeOutputs = (ConnectionOutputPtr)NULL;
+OsCommPtr AvailableInput = (OsCommPtr)NULL;
+
+#define get_req_len(req,cli) ((cli)->swapped ? \
+ lswaps((req)->length) : (req)->length)
+
+#ifdef BIGREQS
+#include "bigreqstr.h"
+
+#define get_big_req_len(req,cli) ((cli)->swapped ? \
+ lswapl(((xBigReq *)(req))->length) : \
+ ((xBigReq *)(req))->length)
+#endif
+
+#define MAX_TIMES_PER 10
+
+/*
+ * A lot of the code in this file manipulates a ConnectionInputPtr:
+ *
+ * -----------------------------------------------
+ * |------- bufcnt ------->| | |
+ * | |- gotnow ->| | |
+ * | |-------- needed ------>| |
+ * |-----------+--------- size --------+---------->|
+ * -----------------------------------------------
+ * ^ ^
+ * | |
+ * buffer bufptr
+ *
+ * buffer is a pointer to the start of the buffer.
+ * bufptr points to the start of the current request.
+ * bufcnt counts how many bytes are in the buffer.
+ * size is the size of the buffer in bytes.
+ *
+ * In several of the functions, gotnow and needed are local variables
+ * that do the following:
+ *
+ * gotnow is the number of bytes of the request that we're
+ * trying to read that are currently in the buffer.
+ * Typically, gotnow = (buffer + bufcnt) - bufptr
+ *
+ * needed = the length of the request that we're trying to
+ * read. Watch out: needed sometimes counts bytes and sometimes
+ * counts CARD32's.
+ */
+
+
+/*****************************************************************
+ * ReadRequestFromClient
+ * Returns one request in client->requestBuffer. The request
+ * length will be in client->req_len. Return status is:
+ *
+ * > 0 if successful, specifies length in bytes of the request
+ * = 0 if entire request is not yet available
+ * < 0 if client should be terminated
+ *
+ * The request returned must be contiguous so that it can be
+ * cast in the dispatcher to the correct request type. Because requests
+ * are variable length, ReadRequestFromClient() must look at the first 4
+ * or 8 bytes of a request to determine the length (the request length is
+ * in the 3rd and 4th bytes of the request unless it is a Big Request
+ * (see the Big Request Extension), in which case the 3rd and 4th bytes
+ * are zero and the following 4 bytes are the request length.
+ *
+ * Note: in order to make the server scheduler (WaitForSomething())
+ * "fair", the ClientsWithInput mask is used. This mask tells which
+ * clients have FULL requests left in their buffers. Clients with
+ * partial requests require a read. Basically, client buffers
+ * are drained before select() is called again. But, we can't keep
+ * reading from a client that is sending buckets of data (or has
+ * a partial request) because others clients need to be scheduled.
+ *****************************************************************/
+
+#define YieldControl() \
+ { isItTimeToYield = TRUE; \
+ timesThisConnection = 0; }
+#define YieldControlNoInput() \
+ { YieldControl(); \
+ FD_CLR(fd, &ClientsWithInput); }
+#define YieldControlDeath() \
+ { timesThisConnection = 0; }
+
+#ifdef hpux_not_tog
+#define LBX_NEED_OLD_SYMBOL_FOR_LOADABLES
+#endif
+
+#ifdef LBX
+#ifdef LBX_NEED_OLD_SYMBOL_FOR_LOADABLES
+#undef ReadRequestFromClient
+int
+ReadRequestFromClient(client)
+ ClientPtr client;
+{
+ return (*client->readRequest)(client);
+}
+#endif
+int
+StandardReadRequestFromClient(client)
+ ClientPtr client;
+#else
+int
+ReadRequestFromClient(client)
+ ClientPtr client;
+#endif
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ register ConnectionInputPtr oci = oc->input;
+ int fd = oc->fd;
+ register int gotnow, needed;
+ int result;
+ register xReq *request;
+ Bool need_header;
+#ifdef BIGREQS
+ Bool move_header;
+#endif
+
+ /* If an input buffer was empty, either free it if it is too big
+ * or link it into our list of free input buffers. This means that
+ * different clients can share the same input buffer (at different
+ * times). This was done to save memory.
+ */
+
+ if (AvailableInput)
+ {
+ if (AvailableInput != oc)
+ {
+ register ConnectionInputPtr aci = AvailableInput->input;
+ if (aci->size > BUFWATERMARK)
+ {
+ xfree(aci->buffer);
+ xfree(aci);
+ }
+ else
+ {
+ aci->next = FreeInputs;
+ FreeInputs = aci;
+ }
+ AvailableInput->input = (ConnectionInputPtr)NULL;
+ }
+ AvailableInput = (OsCommPtr)NULL;
+ }
+
+ /* make sure we have an input buffer */
+
+ if (!oci)
+ {
+ if (oci = FreeInputs)
+ {
+ FreeInputs = oci->next;
+ }
+ else if (!(oci = AllocateInputBuffer()))
+ {
+ YieldControlDeath();
+ return -1;
+ }
+ oc->input = oci;
+ }
+
+ /* advance to start of next request */
+
+ oci->bufptr += oci->lenLastReq;
+
+ need_header = FALSE;
+#ifdef BIGREQS
+ move_header = FALSE;
+#endif
+ gotnow = oci->bufcnt + oci->buffer - oci->bufptr;
+ if (gotnow < sizeof(xReq))
+ {
+ /* We don't have an entire xReq yet. Can't tell how big
+ * the request will be until we get the whole xReq.
+ */
+ needed = sizeof(xReq);
+ need_header = TRUE;
+ }
+ else
+ {
+ /* We have a whole xReq. We can tell how big the whole
+ * request will be unless it is a Big Request.
+ */
+ request = (xReq *)oci->bufptr;
+ needed = get_req_len(request, client);
+#ifdef BIGREQS
+ if (!needed && client->big_requests)
+ {
+ /* It's a Big Request. */
+ move_header = TRUE;
+ if (gotnow < sizeof(xBigReq))
+ {
+ /* Still need more data to tell just how big. */
+ needed = sizeof(xBigReq) >> 2; /* needed is in CARD32s now */
+ need_header = TRUE;
+ }
+ else
+ needed = get_big_req_len(request, client);
+ }
+#endif
+ client->req_len = needed;
+ needed <<= 2; /* needed is in bytes now */
+ }
+ if (gotnow < needed)
+ {
+ /* Need to read more data, either so that we can get a
+ * complete xReq (if need_header is TRUE), a complete
+ * xBigReq (if move_header is TRUE), or the rest of the
+ * request (if need_header and move_header are both FALSE).
+ */
+
+ oci->lenLastReq = 0;
+ if (needed > MAXBUFSIZE)
+ {
+ /* request is too big for us to handle */
+ YieldControlDeath();
+ return -1;
+ }
+ if ((gotnow == 0) ||
+ ((oci->bufptr - oci->buffer + needed) > oci->size))
+ {
+ /* no data, or the request is too big to fit in the buffer */
+
+ if ((gotnow > 0) && (oci->bufptr != oci->buffer))
+ /* save the data we've already read */
+ memmove(oci->buffer, oci->bufptr, gotnow);
+ if (needed > oci->size)
+ {
+ /* make buffer bigger to accomodate request */
+ char *ibuf;
+
+ ibuf = (char *)xrealloc(oci->buffer, needed);
+ if (!ibuf)
+ {
+ YieldControlDeath();
+ return -1;
+ }
+ oci->size = needed;
+ oci->buffer = ibuf;
+ }
+ oci->bufptr = oci->buffer;
+ oci->bufcnt = gotnow;
+ }
+ /* XXX this is a workaround. This function is sometimes called
+ * after the trans_conn has been freed. In this case trans_conn
+ * will be null. Really ought to restructure things so that we
+ * never get here in those circumstances.
+ */
+ if (!oc->trans_conn)
+ {
+ /* treat as if an error occured on the read, which is what
+ * used to happen
+ */
+ YieldControlDeath();
+ return -1;
+ }
+#ifdef LBX
+ if (oc->proxy && oc->proxy->compHandle)
+ result = (*oc->proxy->streamOpts.streamCompRead)(fd,
+ (unsigned char *)oci->buffer + oci->bufcnt,
+ oci->size - oci->bufcnt);
+ else
+#endif
+ result = _XSERVTransRead(oc->trans_conn, oci->buffer + oci->bufcnt,
+ oci->size - oci->bufcnt);
+ if (result <= 0)
+ {
+ if ((result < 0) && ETEST(errno))
+ {
+#if defined(SVR4) && defined(i386) && !defined(sun)
+#if defined(LBX) && 0
+ /*
+ * For LBX connections, we can get a valid EWOULDBLOCK
+ * There is probably a better way of distinguishing LBX
+ * connections, but this works. (DHD)
+ */
+ extern int LbxRead();
+ if (oc->Read == LbxRead)
+#else
+ if (0)
+#endif
+#endif
+ {
+ YieldControlNoInput();
+ return 0;
+ }
+ }
+ YieldControlDeath();
+ return -1;
+ }
+ oci->bufcnt += result;
+ gotnow += result;
+ /* free up some space after huge requests */
+ if ((oci->size > BUFWATERMARK) &&
+ (oci->bufcnt < BUFSIZE) && (needed < BUFSIZE))
+ {
+ char *ibuf;
+
+ ibuf = (char *)xrealloc(oci->buffer, BUFSIZE);
+ if (ibuf)
+ {
+ oci->size = BUFSIZE;
+ oci->buffer = ibuf;
+ oci->bufptr = ibuf + oci->bufcnt - gotnow;
+ }
+ }
+ if (need_header && gotnow >= needed)
+ {
+ /* We wanted an xReq, now we've gotten it. */
+ request = (xReq *)oci->bufptr;
+ needed = get_req_len(request, client);
+#ifdef BIGREQS
+ if (!needed && client->big_requests)
+ {
+ move_header = TRUE;
+ if (gotnow < sizeof(xBigReq))
+ needed = sizeof(xBigReq) >> 2;
+ else
+ needed = get_big_req_len(request, client);
+ }
+#endif
+ client->req_len = needed;
+ needed <<= 2;
+ }
+ if (gotnow < needed)
+ {
+ /* Still don't have enough; punt. */
+ YieldControlNoInput();
+ return 0;
+ }
+ }
+ if (needed == 0)
+ {
+#ifdef BIGREQS
+ if (client->big_requests)
+ needed = sizeof(xBigReq);
+ else
+#endif
+ needed = sizeof(xReq);
+ }
+ oci->lenLastReq = needed;
+
+ /*
+ * Check to see if client has at least one whole request in the
+ * buffer beyond the request we're returning to the caller.
+ * If there is only a partial request, treat like buffer
+ * is empty so that select() will be called again and other clients
+ * can get into the queue.
+ */
+
+ gotnow -= needed;
+ if (gotnow >= sizeof(xReq))
+ {
+ request = (xReq *)(oci->bufptr + needed);
+ if (gotnow >= (result = (get_req_len(request, client) << 2))
+#ifdef BIGREQS
+ && (result ||
+ (client->big_requests &&
+ (gotnow >= sizeof(xBigReq) &&
+ gotnow >= (get_big_req_len(request, client) << 2))))
+#endif
+ )
+ FD_SET(fd, &ClientsWithInput);
+ else
+ YieldControlNoInput();
+ }
+ else
+ {
+ if (!gotnow)
+ AvailableInput = oc;
+ YieldControlNoInput();
+ }
+ if (++timesThisConnection >= MAX_TIMES_PER)
+ YieldControl();
+#ifdef BIGREQS
+ if (move_header)
+ {
+ request = (xReq *)oci->bufptr;
+ oci->bufptr += (sizeof(xBigReq) - sizeof(xReq));
+ *(xReq *)oci->bufptr = *request;
+ oci->lenLastReq -= (sizeof(xBigReq) - sizeof(xReq));
+ client->req_len -= (sizeof(xBigReq) - sizeof(xReq)) >> 2;
+ }
+#endif
+ client->requestBuffer = (pointer)oci->bufptr;
+ return needed;
+}
+
+/*****************************************************************
+ * InsertFakeRequest
+ * Splice a consed up (possibly partial) request in as the next request.
+ *
+ **********************/
+
+Bool
+InsertFakeRequest(client, data, count)
+ ClientPtr client;
+ char *data;
+ int count;
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ register ConnectionInputPtr oci = oc->input;
+ int fd = oc->fd;
+ register int gotnow, moveup;
+
+ if (AvailableInput)
+ {
+ if (AvailableInput != oc)
+ {
+ register ConnectionInputPtr aci = AvailableInput->input;
+ if (aci->size > BUFWATERMARK)
+ {
+ xfree(aci->buffer);
+ xfree(aci);
+ }
+ else
+ {
+ aci->next = FreeInputs;
+ FreeInputs = aci;
+ }
+ AvailableInput->input = (ConnectionInputPtr)NULL;
+ }
+ AvailableInput = (OsCommPtr)NULL;
+ }
+ if (!oci)
+ {
+ if (oci = FreeInputs)
+ FreeInputs = oci->next;
+ else if (!(oci = AllocateInputBuffer()))
+ return FALSE;
+ oc->input = oci;
+ }
+ oci->bufptr += oci->lenLastReq;
+ oci->lenLastReq = 0;
+ gotnow = oci->bufcnt + oci->buffer - oci->bufptr;
+ if ((gotnow + count) > oci->size)
+ {
+ char *ibuf;
+
+ ibuf = (char *)xrealloc(oci->buffer, gotnow + count);
+ if (!ibuf)
+ return(FALSE);
+ oci->size = gotnow + count;
+ oci->buffer = ibuf;
+ oci->bufptr = ibuf + oci->bufcnt - gotnow;
+ }
+ moveup = count - (oci->bufptr - oci->buffer);
+ if (moveup > 0)
+ {
+ if (gotnow > 0)
+ memmove(oci->bufptr + moveup, oci->bufptr, gotnow);
+ oci->bufptr += moveup;
+ oci->bufcnt += moveup;
+ }
+ memmove(oci->bufptr - count, data, count);
+ oci->bufptr -= count;
+ gotnow += count;
+ if ((gotnow >= sizeof(xReq)) &&
+ (gotnow >= (int)(get_req_len((xReq *)oci->bufptr, client) << 2)))
+ FD_SET(fd, &ClientsWithInput);
+ else
+ YieldControlNoInput();
+ return(TRUE);
+}
+
+/*****************************************************************
+ * ResetRequestFromClient
+ * Reset to reexecute the current request, and yield.
+ *
+ **********************/
+
+ResetCurrentRequest(client)
+ ClientPtr client;
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ register ConnectionInputPtr oci = oc->input;
+ int fd = oc->fd;
+ register xReq *request;
+ int gotnow, needed;
+#ifdef LBX
+ Bool part;
+ LbxClientPtr lbxClient = LbxClient(client);
+
+ if (lbxClient) {
+ LbxSetForBlock(lbxClient);
+ if (!oci) {
+ AppendFakeRequest(client,
+ client->requestBuffer, client->req_len << 2);
+ return;
+ }
+ }
+#endif
+ if (AvailableInput == oc)
+ AvailableInput = (OsCommPtr)NULL;
+ oci->lenLastReq = 0;
+ gotnow = oci->bufcnt + oci->buffer - oci->bufptr;
+ if (gotnow < sizeof(xReq))
+ {
+ YieldControlNoInput();
+ }
+ else
+ {
+ request = (xReq *)oci->bufptr;
+ needed = get_req_len(request, client);
+#ifdef BIGREQS
+ if (!needed && client->big_requests)
+ {
+ oci->bufptr -= sizeof(xBigReq) - sizeof(xReq);
+ *(xReq *)oci->bufptr = *request;
+ ((xBigReq *)oci->bufptr)->length = client->req_len;
+ if (client->swapped)
+ {
+ char n;
+ swapl(&((xBigReq *)oci->bufptr)->length, n);
+ }
+ }
+#endif
+ if (gotnow >= (needed << 2))
+ {
+ if (FD_ISSET(fd, &AllClients))
+ {
+ FD_SET(fd, &ClientsWithInput);
+ }
+ else
+ {
+ FD_SET(fd, &IgnoredClientsWithInput);
+ }
+ YieldControl();
+ }
+ else
+ YieldControlNoInput();
+ }
+}
+
+
+
+/*****************************************************************
+ * PeekNextRequest and SkipRequests were implemented to support DBE
+ * idioms, but can certainly be used outside of DBE. There are two
+ * related macros in os.h, ReqLen and CastxReq. See the porting
+ * layer document for more details.
+ *
+ **********************/
+
+
+/*****************************************************************
+ * PeekNextRequest
+ * lets you look ahead at the unexecuted requests in a
+ * client's request buffer.
+ *
+ * Note: this implementation of PeekNextRequest ignores the
+ * readmore parameter.
+ *
+ **********************/
+
+xReqPtr
+PeekNextRequest(req, client, readmore)
+ xReqPtr req; /* request we're starting from */
+ ClientPtr client; /* client whose requests we're skipping */
+ Bool readmore; /* attempt to read more if next request isn't there? */
+{
+ register ConnectionInputPtr oci = ((OsCommPtr)client->osPrivate)->input;
+ xReqPtr pnextreq;
+ int needed, gotnow, reqlen;
+
+ if (!oci) return NULL;
+
+ if (!req)
+ {
+ /* caller wants the request after the one currently being executed */
+ pnextreq = (xReqPtr)
+ (((CARD32 *)client->requestBuffer) + client->req_len);
+ }
+ else
+ {
+ /* caller wants the request after the one specified by req */
+ reqlen = get_req_len(req, client);
+#ifdef BIGREQS
+ if (!reqlen) reqlen = get_big_req_len(req, client);
+#endif
+ pnextreq = (xReqPtr)(((char *)req) + (reqlen << 2));
+ }
+
+ /* see how much of the next request we have available */
+
+ gotnow = oci->bufcnt - (((char *)pnextreq) - oci->buffer);
+
+ if (gotnow < sizeof(xReq))
+ return NULL;
+
+ needed = get_req_len(pnextreq, client) << 2;
+#ifdef BIGREQS
+ if (!needed)
+ {
+ /* it's a big request */
+ if (gotnow < sizeof(xBigReq))
+ return NULL;
+ needed = get_big_req_len(pnextreq, client) << 2;
+ }
+#endif
+
+ /* if we have less than we need, return NULL */
+
+ return (gotnow < needed) ? NULL : pnextreq;
+}
+
+/*****************************************************************
+ * SkipRequests
+ * lets you skip over some of the requests in a client's
+ * request buffer. Presumably the caller has used PeekNextRequest
+ * to examine the requests being skipped and has performed whatever
+ * actions they dictate.
+ *
+ **********************/
+
+CallbackListPtr SkippedRequestsCallback = NULL;
+
+void
+SkipRequests(req, client, numskipped)
+ xReqPtr req; /* last request being skipped */
+ ClientPtr client; /* client whose requests we're skipping */
+ int numskipped; /* how many requests we're skipping */
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ register ConnectionInputPtr oci = oc->input;
+ int reqlen;
+
+ /* see if anyone wants to snoop the skipped requests */
+
+ if (SkippedRequestsCallback)
+ {
+ SkippedRequestInfoRec skipinfo;
+ skipinfo.req = req;
+ skipinfo.client = client;
+ skipinfo.numskipped = numskipped;
+ CallCallbacks(&SkippedRequestsCallback, &skipinfo);
+ }
+
+ /* adjust the sequence number */
+ client->sequence += numskipped;
+
+ /* twiddle the oci to skip over the requests */
+
+ reqlen = get_req_len(req, client);
+#ifdef BIGREQS
+ if (!reqlen) reqlen = get_big_req_len(req, client);
+#endif
+ reqlen <<= 2;
+ oci->bufptr = (char *)req;
+ oci->lenLastReq = reqlen;
+
+ /* see if any requests left in the buffer */
+
+ if ( ((char *)req + reqlen) == (oci->buffer + oci->bufcnt) )
+ {
+ /* no requests; mark input buffer as available and client
+ * as having no input
+ */
+ int fd = oc->fd;
+ AvailableInput = oc;
+ YieldControlNoInput();
+ }
+}
+
+
+ /* lookup table for adding padding bytes to data that is read from
+ or written to the X socket. */
+static int padlength[4] = {0, 3, 2, 1};
+
+ /********************
+ * FlushAllOutput()
+ * Flush all clients with output. However, if some client still
+ * has input in the queue (more requests), then don't flush. This
+ * will prevent the output queue from being flushed every time around
+ * the round robin queue. Now, some say that it SHOULD be flushed
+ * every time around, but...
+ *
+ **********************/
+
+void
+FlushAllOutput()
+{
+ register int index, base;
+ register fd_mask mask; /* raphael */
+ OsCommPtr oc;
+ register ClientPtr client;
+ Bool newoutput = NewOutputPending;
+#ifdef WIN32
+ fd_set newOutputPending;
+#endif
+
+ if (FlushCallback)
+ CallCallbacks(&FlushCallback, NULL);
+
+ if (!newoutput)
+ return;
+
+ /*
+ * It may be that some client still has critical output pending,
+ * but he is not yet ready to receive it anyway, so we will
+ * simply wait for the select to tell us when he's ready to receive.
+ */
+ CriticalOutputPending = FALSE;
+ NewOutputPending = FALSE;
+
+#ifndef WIN32
+ for (base = 0; base < howmany(XFD_SETSIZE, NFDBITS); base++)
+ {
+ mask = OutputPending.fds_bits[ base ];
+ OutputPending.fds_bits[ base ] = 0;
+ while (mask)
+ {
+ index = ffs(mask) - 1;
+ mask &= ~lowbit(mask);
+ if ((index = ConnectionTranslation[(base * (sizeof(fd_mask)*8)) + index]) == 0)
+ continue;
+ client = clients[index];
+ if (client->clientGone)
+ continue;
+ oc = (OsCommPtr)client->osPrivate;
+ if (
+#ifdef LBX
+ !oc->proxy &&
+#endif
+ FD_ISSET(oc->fd, &ClientsWithInput))
+ {
+ FD_SET(oc->fd, &OutputPending); /* set the bit again */
+ NewOutputPending = TRUE;
+ }
+ else
+ (void)FlushClient(client, oc, (char *)NULL, 0);
+ }
+ }
+#else /* WIN32 */
+ FD_ZERO(&newOutputPending);
+ for (base = 0; base < XFD_SETCOUNT(&OutputPending); base++)
+ {
+ index = XFD_FD(&OutputPending, base);
+ if ((index = ConnectionTranslation[index]) == 0)
+ continue;
+ client = clients[index];
+ if (client->clientGone)
+ continue;
+ oc = (OsCommPtr)client->osPrivate;
+ if (
+#ifdef LBX
+ !oc->proxy &&
+#endif
+ FD_ISSET(oc->fd, &ClientsWithInput))
+ {
+ FD_SET(oc->fd, &newOutputPending); /* set the bit again */
+ NewOutputPending = TRUE;
+ }
+ else
+ (void)FlushClient(client, oc, (char *)NULL, 0);
+ }
+ XFD_COPYSET(&newOutputPending, &OutputPending);
+#endif /* WIN32 */
+}
+
+void
+FlushIfCriticalOutputPending()
+{
+ if (CriticalOutputPending)
+ FlushAllOutput();
+}
+
+void
+SetCriticalOutputPending()
+{
+ CriticalOutputPending = TRUE;
+}
+
+/*****************
+ * WriteToClient
+ * Copies buf into ClientPtr.buf if it fits (with padding), else
+ * flushes ClientPtr.buf and buf to client. As of this writing,
+ * every use of WriteToClient is cast to void, and the result
+ * is ignored. Potentially, this could be used by requests
+ * that are sending several chunks of data and want to break
+ * out of a loop on error. Thus, we will leave the type of
+ * this routine as int.
+ *****************/
+
+int
+WriteToClient (who, count, buf)
+ ClientPtr who;
+ char *buf;
+ int count;
+{
+ OsCommPtr oc = (OsCommPtr)who->osPrivate;
+ register ConnectionOutputPtr oco = oc->output;
+ int padBytes;
+
+ if (!count)
+ return(0);
+
+ if (!oco)
+ {
+ if (oco = FreeOutputs)
+ {
+ FreeOutputs = oco->next;
+ }
+ else if (!(oco = AllocateOutputBuffer()))
+ {
+ if (oc->trans_conn) {
+ _XSERVTransDisconnect(oc->trans_conn);
+ _XSERVTransClose(oc->trans_conn);
+ oc->trans_conn = NULL;
+ }
+ MarkClientException(who);
+ return -1;
+ }
+ oc->output = oco;
+ }
+
+ padBytes = padlength[count & 3];
+
+ if(ReplyCallback)
+ {
+ ReplyInfoRec replyinfo;
+
+ replyinfo.client = who;
+ replyinfo.replyData = buf;
+ replyinfo.dataLenBytes = count + padBytes;
+ if (who->replyBytesRemaining)
+ { /* still sending data of an earlier reply */
+ who->replyBytesRemaining -= count + padBytes;
+ replyinfo.startOfReply = FALSE;
+ replyinfo.bytesRemaining = who->replyBytesRemaining;
+ CallCallbacks((&ReplyCallback), (pointer)&replyinfo);
+ }
+ else if (who->clientState == ClientStateRunning
+ && buf[0] == X_Reply)
+ { /* start of new reply */
+ CARD32 replylen;
+ unsigned long bytesleft;
+ char n;
+
+ replylen = ((xGenericReply *)buf)->length;
+ if (who->swapped)
+ swapl(&replylen, n);
+ bytesleft = (replylen * 4) + SIZEOF(xReply) - count - padBytes;
+ replyinfo.startOfReply = TRUE;
+ replyinfo.bytesRemaining = who->replyBytesRemaining = bytesleft;
+ CallCallbacks((&ReplyCallback), (pointer)&replyinfo);
+ }
+ }
+
+ if (oco->count + count + padBytes > oco->size)
+ {
+ FD_CLR(oc->fd, &OutputPending);
+ CriticalOutputPending = FALSE;
+ NewOutputPending = FALSE;
+ return FlushClient(who, oc, buf, count);
+ }
+
+ NewOutputPending = TRUE;
+ FD_SET(oc->fd, &OutputPending);
+ memmove((char *)oco->buf + oco->count, buf, count);
+ oco->count += count + padBytes;
+ return(count);
+}
+
+ /********************
+ * FlushClient()
+ * If the client isn't keeping up with us, then we try to continue
+ * buffering the data and set the apropriate bit in ClientsWritable
+ * (which is used by WaitFor in the select). If the connection yields
+ * a permanent error, or we can't allocate any more space, we then
+ * close the connection.
+ *
+ **********************/
+
+#ifdef LBX
+#ifdef LBX_NEED_OLD_SYMBOL_FOR_LOADABLES
+#undef FlushClient
+int
+FlushClient(who, oc, extraBuf, extraCount)
+ ClientPtr who;
+ OsCommPtr oc;
+ char *extraBuf;
+ int extraCount;
+{
+ return (*oc->Flush)(who, oc, extraBuf, extraCount);
+}
+#endif
+int
+StandardFlushClient(who, oc, extraBuf, extraCount)
+#else
+int
+FlushClient(who, oc, extraBuf, extraCount)
+#endif
+ ClientPtr who;
+ OsCommPtr oc;
+ char *extraBuf;
+ int extraCount; /* do not modify... returned below */
+{
+ register ConnectionOutputPtr oco = oc->output;
+ int connection = oc->fd;
+ XtransConnInfo trans_conn = oc->trans_conn;
+ struct iovec iov[3];
+ static char padBuffer[3];
+ long written;
+ long padsize;
+ long notWritten;
+ long todo;
+
+ if (!oco)
+ return 0;
+ written = 0;
+ padsize = padlength[extraCount & 3];
+ notWritten = oco->count + extraCount + padsize;
+ todo = notWritten;
+ while (notWritten) {
+ long before = written; /* amount of whole thing written */
+ long remain = todo; /* amount to try this time, <= notWritten */
+ int i = 0;
+ long len;
+
+ /* You could be very general here and have "in" and "out" iovecs
+ * and write a loop without using a macro, but what the heck. This
+ * translates to:
+ *
+ * how much of this piece is new?
+ * if more new then we are trying this time, clamp
+ * if nothing new
+ * then bump down amount already written, for next piece
+ * else put new stuff in iovec, will need all of next piece
+ *
+ * Note that todo had better be at least 1 or else we'll end up
+ * writing 0 iovecs.
+ */
+#define InsertIOV(pointer, length) \
+ len = (length) - before; \
+ if (len > remain) \
+ len = remain; \
+ if (len <= 0) { \
+ before = (-len); \
+ } else { \
+ iov[i].iov_len = len; \
+ iov[i].iov_base = (pointer) + before; \
+ i++; \
+ remain -= len; \
+ before = 0; \
+ }
+
+ InsertIOV ((char *)oco->buf, oco->count)
+ InsertIOV (extraBuf, extraCount)
+ InsertIOV (padBuffer, padsize)
+
+ errno = 0;
+ if (trans_conn && (len = _XSERVTransWritev(trans_conn, iov, i)) >= 0)
+ {
+ written += len;
+ notWritten -= len;
+ todo = notWritten;
+ }
+ else if (ETEST(errno)
+#ifdef SUNSYSV /* check for another brain-damaged OS bug */
+ || (errno == 0)
+#endif
+#ifdef EMSGSIZE /* check for another brain-damaged OS bug */
+ || ((errno == EMSGSIZE) && (todo == 1))
+#endif
+ )
+ {
+ /* If we've arrived here, then the client is stuffed to the gills
+ and not ready to accept more. Make a note of it and buffer
+ the rest. */
+ FD_SET(connection, &ClientsWriteBlocked);
+ AnyClientsWriteBlocked = TRUE;
+
+ if (written < oco->count)
+ {
+ if (written > 0)
+ {
+ oco->count -= written;
+ memmove((char *)oco->buf,
+ (char *)oco->buf + written,
+ oco->count);
+ written = 0;
+ }
+ }
+ else
+ {
+ written -= oco->count;
+ oco->count = 0;
+ }
+
+ if (notWritten > oco->size)
+ {
+ unsigned char *obuf;
+
+ obuf = (unsigned char *)xrealloc(oco->buf,
+ notWritten + BUFSIZE);
+ if (!obuf)
+ {
+ _XSERVTransDisconnect(oc->trans_conn);
+ _XSERVTransClose(oc->trans_conn);
+ oc->trans_conn = NULL;
+ MarkClientException(who);
+ oco->count = 0;
+ return(-1);
+ }
+ oco->size = notWritten + BUFSIZE;
+ oco->buf = obuf;
+ }
+
+ /* If the amount written extended into the padBuffer, then the
+ difference "extraCount - written" may be less than 0 */
+ if ((len = extraCount - written) > 0)
+ memmove ((char *)oco->buf + oco->count,
+ extraBuf + written,
+ len);
+
+ oco->count = notWritten; /* this will include the pad */
+ /* return only the amount explicitly requested */
+ return extraCount;
+ }
+#ifdef EMSGSIZE /* check for another brain-damaged OS bug */
+ else if (errno == EMSGSIZE)
+ {
+ todo >>= 1;
+ }
+#endif
+ else
+ {
+ if (oc->trans_conn)
+ {
+ _XSERVTransDisconnect(oc->trans_conn);
+ _XSERVTransClose(oc->trans_conn);
+ oc->trans_conn = NULL;
+ }
+ MarkClientException(who);
+ oco->count = 0;
+ return(-1);
+ }
+ }
+
+ /* everything was flushed out */
+ oco->count = 0;
+ /* check to see if this client was write blocked */
+ if (AnyClientsWriteBlocked)
+ {
+ FD_CLR(oc->fd, &ClientsWriteBlocked);
+ if (! XFD_ANYSET(&ClientsWriteBlocked))
+ AnyClientsWriteBlocked = FALSE;
+ }
+ if (oco->size > BUFWATERMARK)
+ {
+ xfree(oco->buf);
+ xfree(oco);
+ }
+ else
+ {
+ oco->next = FreeOutputs;
+ FreeOutputs = oco;
+ }
+ oc->output = (ConnectionOutputPtr)NULL;
+ return extraCount; /* return only the amount explicitly requested */
+}
+
+ConnectionInputPtr
+AllocateInputBuffer()
+{
+ register ConnectionInputPtr oci;
+
+ oci = (ConnectionInputPtr)xalloc(sizeof(ConnectionInput));
+ if (!oci)
+ return (ConnectionInputPtr)NULL;
+ oci->buffer = (char *)xalloc(BUFSIZE);
+ if (!oci->buffer)
+ {
+ xfree(oci);
+ return (ConnectionInputPtr)NULL;
+ }
+ oci->size = BUFSIZE;
+ oci->bufptr = oci->buffer;
+ oci->bufcnt = 0;
+ oci->lenLastReq = 0;
+ return oci;
+}
+
+ConnectionOutputPtr
+AllocateOutputBuffer()
+{
+ register ConnectionOutputPtr oco;
+
+ oco = (ConnectionOutputPtr)xalloc(sizeof(ConnectionOutput));
+ if (!oco)
+ return (ConnectionOutputPtr)NULL;
+ oco->buf = (unsigned char *) xalloc(BUFSIZE);
+ if (!oco->buf)
+ {
+ xfree(oco);
+ return (ConnectionOutputPtr)NULL;
+ }
+ oco->size = BUFSIZE;
+ oco->count = 0;
+#ifdef LBX
+ oco->nocompress = FALSE;
+#endif
+ return oco;
+}
+
+void
+FreeOsBuffers(oc)
+ OsCommPtr oc;
+{
+ register ConnectionInputPtr oci;
+ register ConnectionOutputPtr oco;
+
+ if (AvailableInput == oc)
+ AvailableInput = (OsCommPtr)NULL;
+ if (oci = oc->input)
+ {
+ if (FreeInputs)
+ {
+ xfree(oci->buffer);
+ xfree(oci);
+ }
+ else
+ {
+ FreeInputs = oci;
+ oci->next = (ConnectionInputPtr)NULL;
+ oci->bufptr = oci->buffer;
+ oci->bufcnt = 0;
+ oci->lenLastReq = 0;
+ }
+ }
+ if (oco = oc->output)
+ {
+ if (FreeOutputs)
+ {
+ xfree(oco->buf);
+ xfree(oco);
+ }
+ else
+ {
+ FreeOutputs = oco;
+ oco->next = (ConnectionOutputPtr)NULL;
+ oco->count = 0;
+ }
+ }
+#ifdef LBX
+ if (oci = oc->largereq) {
+ xfree(oci->buffer);
+ xfree(oci);
+ }
+#endif
+}
+
+void
+ResetOsBuffers()
+{
+ register ConnectionInputPtr oci;
+ register ConnectionOutputPtr oco;
+
+ while (oci = FreeInputs)
+ {
+ FreeInputs = oci->next;
+ xfree(oci->buffer);
+ xfree(oci);
+ }
+ while (oco = FreeOutputs)
+ {
+ FreeOutputs = oco->next;
+ xfree(oco->buf);
+ xfree(oco);
+ }
+}
diff --git a/xc/programs/Xserver/os/iopreader.c b/xc/programs/Xserver/os/iopreader.c
new file mode 100644
index 000000000..092c7a7ab
--- /dev/null
+++ b/xc/programs/Xserver/os/iopreader.c
@@ -0,0 +1,179 @@
+/* $XConsortium: iopreader.c,v 1.2 94/04/12 17:24:33 dpw Exp $ */
+
+/* Copyright (c) 1987 by the Regents of the University of California
+ * Copyright (c) 1994 by the Vrije Universiteit, Amsterdam.
+ *
+ * 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. The University of California
+ * and the Vrije Universiteit make no representations about
+ * the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#ifdef AMOEBA
+/*
+ * iopreader.c
+ *
+ */
+#define port am_port_t
+#include <amoeba.h>
+#include <ampolicy.h>
+#include <cmdreg.h>
+#include <stdcom.h>
+#include <stderr.h>
+#include <server/iop/iop.h>
+#undef port
+
+#include "osdep.h"
+
+#define DEVREADER_STACK 8000
+#define MAXEVENTQUEUE 32
+
+capability iopcap;
+
+static mutex lock;
+static semaphore empty, filled;
+
+static IOPEvent event_queue[MAXEVENTQUEUE];
+static int event_qin, event_qout;
+
+void IOPCleanUp();
+static void IOPServerReader();
+
+/*
+ * Initialize the IOP server
+ */
+void
+InitializeIOPServerReader()
+{
+ capability hostcap;
+ errstat err;
+
+ /*
+ * Initialize event queue
+ */
+ event_qin = event_qout = 0;
+ sema_init(&empty, MAXEVENTQUEUE);
+ sema_init(&filled, 0);
+ mu_init(&lock);
+
+ /*
+ * Get IOP capability, and enable the server
+ */
+ if (XServerHostName == NULL)
+ FatalError("No hostname, no screen\n");
+
+ if ((err = host_lookup(XServerHostName, &hostcap)) != STD_OK ||
+ (err = dir_lookup(&hostcap, DEF_IOPSVRNAME, &iopcap)) != STD_OK)
+ {
+ FatalError("Cannot find IOP server for %s: %s\n",
+ XServerHostName, err_why(err));
+ }
+
+ /*
+ * Enable IOP server
+ */
+ if ((err = iop_enable(&iopcap)) != STD_OK)
+ FatalError("iop_enable failed (%s)\n", err_why(err));
+
+ /*
+ * Start IOP reader thread
+ */
+ atexit(IOPCleanUp);
+ if (thread_newthread(IOPServerReader, DEVREADER_STACK, 0, 0) <= 0)
+ FatalError("Cannot start IOP reader thread\n");
+}
+
+/*
+ * IOP clean up, actuall disable the IOP server. Its the IOP's own choice
+ * what do do (perhaps restore the screen?).
+ */
+void
+IOPCleanUp()
+{
+ errstat err;
+
+ if ((err = iop_disable(&iopcap)) != STD_OK)
+ ErrorF("iop_disable failed (%s)\n", err_why(err));
+}
+
+/*
+ * This threads polls the IOP server for events. Once an event (or a
+ * number of events) are read, they are queued up using a traditional
+ * producer/consumer approach.
+ */
+static void
+IOPServerReader()
+{
+ IOPEvent queue[MAXEVENTQUEUE-1];
+ int nevents, i;
+ errstat err;
+
+ WaitForInitialization();
+
+#ifdef XDEBUG
+ if (amDebug) ErrorF("IOPServerReader() running ...\n");
+#endif
+
+ for (;;) {
+ do {
+ nevents = MAXEVENTQUEUE - 1;
+ err = iop_getevents(&iopcap, queue, &nevents);
+ if (err != STD_OK) {
+ if (err != RPC_FAILURE) {
+ ErrorF("iop_getevents failed (%s)\n", err_why(err));
+ }
+ nevents = 0;
+ }
+ } while (nevents <= 0);
+
+ /* store event(s) in the global event queue */
+ sema_mdown(&empty, nevents);
+ mu_lock(&lock);
+ for (i = 0; i < nevents; i++) {
+ event_queue[event_qin] = queue[i];
+ event_qin = (event_qin + 1) % MAXEVENTQUEUE;
+ }
+ mu_unlock(&lock);
+ sema_mup(&filled, nevents);
+ WakeUpMainThread();
+ }
+}
+
+/*
+ * Return the number of IOP events waiting
+ */
+int
+AmoebaEventsAvailable()
+{
+ return sema_level(&filled);
+}
+
+/*
+ * Get the IOP events from the queue. ``size'' is the maximum the
+ * requestor cares to handle, the actual size read is returned as
+ * result.
+ */
+int
+AmoebaGetEvents(queue, size)
+ IOPEvent *queue;
+ int size;
+{
+ int nevents, i;
+
+ if (sema_level(&filled) <= 0) return 0;
+ if ((nevents = sema_level(&filled)) > size)
+ nevents = size;
+ sema_mdown(&filled, nevents);
+ mu_lock(&lock);
+ for (i = 0; i < nevents; i++) {
+ queue[i] = event_queue[event_qout];
+ event_qout = (event_qout + 1) % MAXEVENTQUEUE;
+ }
+ mu_unlock(&lock);
+ sema_mup(&empty, nevents);
+ return nevents;
+}
+#endif /* AMOEBA */
diff --git a/xc/programs/Xserver/os/k5auth.c b/xc/programs/Xserver/os/k5auth.c
new file mode 100644
index 000000000..46c9b8f5b
--- /dev/null
+++ b/xc/programs/Xserver/os/k5auth.c
@@ -0,0 +1,793 @@
+/* $TOG: k5auth.c /main/10 1998/02/09 15:12:25 kaleb $ */
+/*
+
+Copyright 1993, 1994, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+/* $XFree86: xc/programs/Xserver/os/k5auth.c,v 3.3 1998/10/04 09:39:43 dawes Exp $ */
+
+/*
+ * Kerberos V5 authentication scheme
+ * Author: Tom Yu <tlyu@MIT.EDU>
+ *
+ * Mostly snarfed wholesale from the user_user demo in the
+ * krb5 distribution. (At least the checking part)
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifdef TCPCONN
+#include <netinet/in.h>
+#endif
+#ifdef DNETCONN
+#include <netdnet/dn.h>
+#endif
+#include <arpa/inet.h>
+#include <krb5/krb5.h>
+/* 9/93: krb5.h leaks some symbols */
+#undef BITS32
+#undef xfree
+#include <krb5/los-proto.h>
+#include "X.h"
+#include "os.h"
+#include "osdep.h"
+#include "Xproto.h"
+#include "Xfuncs.h"
+#include "dixstruct.h"
+#include <com_err.h>
+#include "Xauth.h"
+
+extern int (*k5_Vector[256])();
+extern int SendConnSetup();
+extern char *display; /* need this to generate rcache name */
+
+static XID krb5_id = ~0L;
+static krb5_principal srvname = NULL; /* service name */
+static char *ccname = NULL;
+static char *ktname = NULL; /* key table name */
+static char kerror[256];
+
+/*
+ * tgt_keyproc:
+ *
+ * extract session key from a credentials struct
+ */
+krb5_error_code tgt_keyproc(keyprocarg, principal, vno, key)
+ krb5_pointer keyprocarg;
+ krb5_principal principal;
+ krb5_kvno vno;
+ krb5_keyblock **key;
+{
+ krb5_creds *creds = (krb5_creds *)keyprocarg;
+
+ return krb5_copy_keyblock(&creds->keyblock, key);
+}
+
+/*
+ * k5_cmpenc:
+ *
+ * compare "encoded" principals
+ */
+Bool k5_cmpenc(pname, plen, buf)
+ unsigned char *pname;
+ short plen;
+ krb5_data *buf;
+{
+ return (plen == buf->length &&
+ memcmp(pname, buf->data, plen) == 0);
+}
+
+/*
+ * K5Check:
+ *
+ * This is stage 0 of the krb5 authentication protocol. It
+ * goes through the current credentials cache and extracts the
+ * primary principal and tgt to send to the client, or as
+ * appropriate, extracts from a keytab.
+ *
+ * The packet sent to the client has the following format:
+ *
+ * CARD8 reqType = 2
+ * CARD8 data = 0
+ * CARD16 length = total length of packet (in 32 bit units)
+ * CARD16 plen = length of encoded principal following
+ * STRING8 princ = encoded principal
+ * STRING8 ticket = server tgt
+ *
+ * For client-server authentication, the packet is as follows:
+ *
+ * CARD8 reqType = 3
+ * CARD8 data = 0
+ * CARD16 length = total length
+ * STRING8 princ = encoded principal of server
+ */
+XID K5Check(data_length, data, client, reason)
+ unsigned short data_length;
+ char *data;
+ ClientPtr client;
+ char **reason;
+{
+ krb5_error_code retval;
+ CARD16 tlen;
+ krb5_principal sprinc, cprinc;
+ krb5_ccache cc;
+ krb5_creds *creds;
+ char *outbuf, *cp;
+ krb5_data princ;
+ register char n;
+ xReq prefix;
+
+ if (krb5_id == ~0L)
+ return ~0L;
+ if (!ccname && !srvname)
+ return ~0L;
+ if (ccname)
+ {
+ if ((creds = (krb5_creds *)malloc(sizeof(krb5_creds))) == NULL)
+ return ~0L;
+ if (retval = krb5_cc_resolve(ccname, &cc))
+ return ~0L;
+ bzero((char*)creds, sizeof (krb5_creds));
+ if (retval = krb5_cc_get_principal(cc, &cprinc))
+ {
+ krb5_free_creds(creds);
+ krb5_cc_close(cc);
+ return ~0L;
+ }
+ creds->client = cprinc;
+ if (retval =
+ krb5_build_principal_ext(&sprinc,
+ krb5_princ_realm(creds->client)->length,
+ krb5_princ_realm(creds->client)->data,
+ 6, "krbtgt",
+ krb5_princ_realm(creds->client)->length,
+ krb5_princ_realm(creds->client)->data,
+ 0))
+ {
+ krb5_free_creds(creds);
+ krb5_cc_close(cc);
+ return ~0L;
+ }
+ creds->server = sprinc;
+ retval = krb5_get_credentials(KRB5_GC_CACHED, cc, creds);
+ krb5_cc_close(cc);
+ if (retval)
+ {
+ krb5_free_creds(creds);
+ return ~0L;
+ }
+ if (retval = XauKrb5Encode(cprinc, &princ))
+ {
+ krb5_free_creds(creds);
+ return ~0L;
+ }
+ tlen = sz_xReq + 2 + princ.length + creds->ticket.length;
+ prefix.reqType = 2; /* opcode = authenticate user-to-user */
+ }
+ else if (srvname)
+ {
+ if (retval = XauKrb5Encode(srvname, &princ))
+ {
+ return ~0L;
+ }
+ tlen = sz_xReq + princ.length;
+ prefix.reqType = 3; /* opcode = authenticate client-server */
+ }
+ prefix.data = 0; /* stage = 0 */
+ prefix.length = (tlen + 3) >> 2; /* round up to nearest multiple
+ of 4 bytes */
+ if (client->swapped)
+ {
+ swaps(&prefix.length, n);
+ }
+ if ((cp = outbuf = (char *)malloc(tlen)) == NULL)
+ {
+ if (ccname)
+ {
+ krb5_free_creds(creds);
+ }
+ free(princ.data);
+ return ~0L;
+ }
+ memcpy(cp, &prefix, sz_xReq);
+ cp += sz_xReq;
+ if (ccname)
+ {
+ memcpy(cp, &princ.length, 2);
+ if (client->swapped)
+ {
+ swaps((CARD16 *)cp, n);
+ }
+ cp += 2;
+ }
+ memcpy(cp, princ.data, princ.length);
+ cp += princ.length;
+ free(princ.data); /* we don't need that anymore */
+ if (ccname)
+ memcpy(cp, creds->ticket.data, creds->ticket.length);
+ WriteToClient(client, tlen, outbuf);
+ free(outbuf);
+ client->requestVector = k5_Vector; /* hack in our dispatch vector */
+ client->clientState = ClientStateAuthenticating;
+ if (ccname)
+ {
+ ((OsCommPtr)client->osPrivate)->authstate.srvcreds = (pointer)creds; /* save tgt creds */
+ ((OsCommPtr)client->osPrivate)->authstate.ktname = NULL;
+ ((OsCommPtr)client->osPrivate)->authstate.srvname = NULL;
+ }
+ if (srvname)
+ {
+ ((OsCommPtr)client->osPrivate)->authstate.srvcreds = NULL;
+ ((OsCommPtr)client->osPrivate)->authstate.ktname = (pointer)ktname;
+ ((OsCommPtr)client->osPrivate)->authstate.srvname = (pointer)srvname;
+ }
+ ((OsCommPtr)client->osPrivate)->authstate.stageno = 1; /* next stage is 1 */
+ return krb5_id;
+}
+
+/*
+ * k5_stage1:
+ *
+ * This gets called out of the dispatcher after K5Check frobs with the
+ * client->requestVector. It accepts the ap_req from the client and verifies
+ * it. In addition, if the client has set AP_OPTS_MUTUAL_REQUIRED, it then
+ * sends an ap_rep to the client to achieve mutual authentication.
+ *
+ * client stage1 packet format is as follows:
+ *
+ * CARD8 reqType = 1
+ * CARD8 data = ignored
+ * CARD16 length = total length
+ * STRING8 data = the actual ap_req
+ *
+ * stage2 packet sent back to client for mutual authentication:
+ *
+ * CARD8 reqType = 2
+ * CARD8 data = 2
+ * CARD16 length = total length
+ * STRING8 data = the ap_rep
+ */
+int k5_stage1(client)
+ register ClientPtr client;
+{
+ long addrlen;
+ krb5_error_code retval, retval2;
+ register char n;
+ struct sockaddr cli_net_addr;
+ xReq prefix;
+ krb5_principal cprinc;
+ krb5_data buf;
+ krb5_creds *creds = (krb5_creds *)((OsCommPtr)client->osPrivate)->authstate.srvcreds;
+ krb5_keyblock *skey;
+ krb5_address cli_addr, **localaddrs = NULL;
+ krb5_tkt_authent *authdat;
+ krb5_ap_rep_enc_part rep;
+ krb5_int32 ctime, cusec;
+ krb5_rcache rcache = NULL;
+ char *cachename = NULL, *rc_type = NULL, *rc_base = "rcX", *kt = NULL;
+ REQUEST(xReq);
+
+ if (((OsCommPtr)client->osPrivate)->authstate.stageno != 1)
+ {
+ if (creds)
+ krb5_free_creds(creds);
+ return(SendConnSetup(client, "expected Krb5 stage1 packet"));
+ }
+ addrlen = sizeof (cli_net_addr);
+ if (getpeername(((OsCommPtr)client->osPrivate)->fd,
+ &cli_net_addr, &addrlen) == -1)
+ {
+ if (creds)
+ krb5_free_creds(creds);
+ return(SendConnSetup(client, "Krb5 stage1: getpeername failed"));
+ }
+ if (cli_net_addr.sa_family == AF_UNSPEC
+#if defined(UNIXCONN) || defined(LOCALCONN) || defined(OS2PIPECONN)
+ || cli_net_addr.sa_family == AF_UNIX
+#endif
+ ) /* assume local host */
+ {
+ krb5_os_localaddr(&localaddrs);
+ if (!localaddrs || !localaddrs[0])
+ {
+ if (creds)
+ krb5_free_creds(creds);
+ return(SendConnSetup(client, "Krb5 failed to get localaddrs"));
+ }
+ cli_addr.addrtype = localaddrs[0]->addrtype;
+ cli_addr.length = localaddrs[0]->length;
+ cli_addr.contents = localaddrs[0]->contents;
+ }
+ else
+ {
+ cli_addr.addrtype = cli_net_addr.sa_family; /* the values
+ are compatible */
+ switch (cli_net_addr.sa_family)
+ {
+#ifdef TCPCONN
+ case AF_INET:
+ cli_addr.length = sizeof (struct in_addr);
+ cli_addr.contents =
+ (krb5_octet *)&((struct sockaddr_in *)&cli_net_addr)->sin_addr;
+ break;
+#endif
+#ifdef DNETCONN
+ case AF_DECnet:
+ cli_addr.length = sizeof (struct dn_naddr);
+ cli_addr.contents =
+ (krb5_octet *)&((struct sockaddr_dn *)&cli_net_addr)->sdn_add;
+ break;
+#endif
+ default:
+ if (localaddrs)
+ krb5_free_addresses(localaddrs);
+ if (creds)
+ krb5_free_creds(creds);
+ sprintf(kerror, "Krb5 stage1: unknown address family %d from getpeername",
+ cli_net_addr.sa_family);
+ return(SendConnSetup(client, kerror));
+ }
+ }
+ if ((rcache = (krb5_rcache)malloc(sizeof(*rcache))) == NULL)
+ {
+ if (localaddrs)
+ krb5_free_addresses(localaddrs);
+ if (creds)
+ krb5_free_creds(creds);
+ return(SendConnSetup(client, "malloc bombed for krb5_rcache"));
+ }
+ if ((rc_type = krb5_rc_default_type()) == NULL)
+ rc_type = "dfl";
+ if (retval = krb5_rc_resolve_type(&rcache, rc_type))
+ {
+ if (localaddrs)
+ krb5_free_addresses(localaddrs);
+ if (creds)
+ krb5_free_creds(creds);
+ free(rcache);
+ strcpy(kerror, "krb5_rc_resolve_type failed: ");
+ strncat(kerror, error_message(retval), 231);
+ return(SendConnSetup(client, kerror));
+ }
+ if ((cachename = (char *)malloc(strlen(rc_base) + strlen(display) + 1))
+ == NULL)
+ {
+ if (localaddrs)
+ krb5_free_addresses(localaddrs);
+ if (creds)
+ krb5_free_creds(creds);
+ free(rcache);
+ return(SendConnSetup(client, "Krb5: malloc bombed for cachename"));
+ }
+ strcpy(cachename, rc_base);
+ strcat(cachename, display);
+ if (retval = krb5_rc_resolve(rcache, cachename))
+ {
+ if (localaddrs)
+ krb5_free_addresses(localaddrs);
+ if (creds)
+ krb5_free_creds(creds);
+ free(rcache);
+ free(cachename);
+ strcpy(kerror, "krb5_rc_resolve failed: ");
+ strncat(kerror, error_message(retval), 236);
+ return(SendConnSetup(client, kerror));
+ }
+ free(cachename);
+ if (krb5_rc_recover(rcache))
+ {
+ extern krb5_deltat krb5_clockskew;
+ if (retval = krb5_rc_initialize(rcache, krb5_clockskew))
+ {
+ if (localaddrs)
+ krb5_free_addresses(localaddrs);
+ if (creds)
+ krb5_free_creds(creds);
+ if (retval2 = krb5_rc_close(rcache))
+ {
+ strcpy(kerror, "krb5_rc_close failed: ");
+ strncat(kerror, error_message(retval2), 238);
+ return(SendConnSetup(client, kerror));
+ }
+ free(rcache);
+ strcpy(kerror, "krb5_rc_initialize failed: ");
+ strncat(kerror, error_message(retval), 233);
+ return(SendConnSetup(client, kerror));
+ }
+ }
+ buf.length = (stuff->length << 2) - sz_xReq;
+ buf.data = (char *)stuff + sz_xReq;
+ if (creds)
+ {
+ retval = krb5_rd_req(&buf,
+ NULL, /* don't bother with server name */
+ &cli_addr,
+ NULL, /* no fetchfrom */
+ tgt_keyproc,
+ creds, /* credentials as arg to
+ keyproc */
+ rcache,
+ &authdat);
+ krb5_free_creds(creds);
+ }
+ else if (kt = (char *)((OsCommPtr)client->osPrivate)->authstate.ktname)
+ {
+ retval = krb5_rd_req(&buf, srvname, &cli_addr, kt, NULL, NULL,
+ rcache, &authdat);
+ ((OsCommPtr)client->osPrivate)->authstate.ktname = NULL;
+ }
+ else
+ {
+ if (localaddrs)
+ krb5_free_addresses(localaddrs);
+ return(SendConnSetup(client, "Krb5: neither srvcreds nor ktname set"));
+ }
+ if (localaddrs)
+ krb5_free_addresses(localaddrs);
+ if (rcache)
+ {
+ if (retval2 = krb5_rc_close(rcache))
+ {
+ strcpy(kerror, "krb5_rc_close failed (2): ");
+ strncat(kerror, error_message(retval2), 230);
+ return(SendConnSetup(client, kerror));
+ }
+ free(rcache);
+ }
+ if (retval)
+ {
+ strcpy(kerror, "Krb5: Bad application request: ");
+ strncat(kerror, error_message(retval), 224);
+ return(SendConnSetup(client, kerror));
+ }
+ cprinc = authdat->ticket->enc_part2->client;
+ skey = authdat->ticket->enc_part2->session;
+ if (XauKrb5Encode(cprinc, &buf))
+ {
+ krb5_free_tkt_authent(authdat);
+ return(SendConnSetup(client, "XauKrb5Encode bombed"));
+ }
+ /*
+ * Now check to see if the principal we got is one that we want to let in
+ */
+ if (ForEachHostInFamily(FamilyKrb5Principal, k5_cmpenc, (pointer)&buf))
+ {
+ free(buf.data);
+ /*
+ * The following deals with sending an ap_rep to the client to
+ * achieve mutual authentication. The client sends back a stage 3
+ * packet if all is ok.
+ */
+ if (authdat->ap_options | AP_OPTS_MUTUAL_REQUIRED)
+ {
+ /*
+ * stage 2: send ap_rep to client
+ */
+ if (retval = krb5_us_timeofday(&ctime, &cusec))
+ {
+ krb5_free_tkt_authent(authdat);
+ strcpy(kerror, "error in krb5_us_timeofday: ");
+ strncat(kerror, error_message(retval), 234);
+ return(SendConnSetup(client, kerror));
+ }
+ rep.ctime = ctime;
+ rep.cusec = cusec;
+ rep.subkey = NULL;
+ rep.seq_number = 0;
+ if (retval = krb5_mk_rep(&rep, skey, &buf))
+ {
+ krb5_free_tkt_authent(authdat);
+ strcpy(kerror, "error in krb5_mk_rep: ");
+ strncat(kerror, error_message(retval), 238);
+ return(SendConnSetup(client, kerror));
+ }
+ prefix.reqType = 2; /* opcode = authenticate */
+ prefix.data = 2; /* stage = 2 */
+ prefix.length = (buf.length + sz_xReq + 3) >> 2;
+ if (client->swapped)
+ {
+ swaps(&prefix.length, n);
+ }
+ WriteToClient(client, sz_xReq, (char *)&prefix);
+ WriteToClient(client, buf.length, buf.data);
+ free(buf.data);
+ krb5_free_tkt_authent(authdat);
+ ((OsCommPtr)client->osPrivate)->authstate.stageno = 3; /* expect stage3 packet */
+ return(Success);
+ }
+ else
+ {
+ free(buf.data);
+ krb5_free_tkt_authent(authdat);
+ return(SendConnSetup(client, NULL)); /* success! */
+ }
+ }
+ else
+ {
+ char *kname;
+
+ krb5_free_tkt_authent(authdat);
+ free(buf.data);
+ retval = krb5_unparse_name(cprinc, &kname);
+ if (retval == 0)
+ {
+ sprintf(kerror, "Principal \"%s\" is not authorized to connect",
+ kname);
+ if (kname)
+ free(kname);
+ return(SendConnSetup(client, kerror));
+ }
+ else
+ return(SendConnSetup(client,"Principal is not authorized to connect to Server"));
+ }
+}
+
+/*
+ * k5_stage3:
+ *
+ * Get the short ack packet from the client. This packet can conceivably
+ * be expanded to allow for switching on end-to-end encryption.
+ *
+ * stage3 packet format:
+ *
+ * CARD8 reqType = 3
+ * CARD8 data = ignored (for now)
+ * CARD16 length = should be zero
+ */
+int k5_stage3(client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+
+ if (((OsCommPtr)client->osPrivate)->authstate.stageno != 3)
+ {
+ return(SendConnSetup(client, "expected Krb5 stage3 packet"));
+ }
+ else
+ return(SendConnSetup(client, NULL)); /* success! */
+}
+
+k5_bad(client)
+ register ClientPtr client;
+{
+ if (((OsCommPtr)client->osPrivate)->authstate.srvcreds)
+ krb5_free_creds((krb5_creds *)((OsCommPtr)client->osPrivate)->authstate.srvcreds);
+ sprintf(kerror, "unrecognized Krb5 auth packet %d, expecting %d",
+ ((xReq *)client->requestBuffer)->reqType,
+ ((OsCommPtr)client->osPrivate)->authstate.stageno);
+ return(SendConnSetup(client, kerror));
+}
+
+/*
+ * K5Add:
+ *
+ * Takes the name of a credentials cache and resolves it. Also adds the
+ * primary principal of the ccache to the acl.
+ *
+ * Now will also take a service name.
+ */
+int K5Add(data_length, data, id)
+ unsigned short data_length;
+ char *data;
+ XID id;
+{
+ krb5_principal princ;
+ krb5_error_code retval;
+ krb5_keytab_entry tmp_entry;
+ krb5_keytab keytab;
+ krb5_kvno kvno = 0;
+ krb5_ccache cc;
+ char *nbuf, *cp;
+ krb5_data kbuf;
+ int i, ktlen;
+
+ krb5_init_ets(); /* can't think of a better place to put it */
+ krb5_id = ~0L;
+ if (data_length < 3)
+ return 0;
+ if ((nbuf = (char *)malloc(data_length - 2)) == NULL)
+ return 0;
+ memcpy(nbuf, data + 3, data_length - 3);
+ nbuf[data_length - 3] = '\0';
+ if (ccname)
+ {
+ free(ccname);
+ ccname = NULL;
+ }
+ if (srvname)
+ {
+ krb5_free_principal(srvname);
+ srvname = NULL;
+ }
+ if (ktname)
+ {
+ free(ktname);
+ ktname = NULL;
+ }
+ if (!strncmp(data, "UU:", 3))
+ {
+ if (retval = krb5_cc_resolve(nbuf, &cc))
+ {
+ ErrorF("K5Add: krb5_cc_resolve of \"%s\" failed: %s\n",
+ nbuf, error_message(retval));
+ free(nbuf);
+ return 0;
+ }
+ if (cc && !(retval = krb5_cc_get_principal(cc, &princ)))
+ {
+ if (XauKrb5Encode(princ, &kbuf))
+ {
+ free(nbuf);
+ krb5_free_principal(princ);
+ krb5_cc_close(cc);
+ return 0;
+ }
+ if (krb5_cc_close(cc))
+ return 0;
+ AddHost(NULL, FamilyKrb5Principal, kbuf.length, kbuf.data);
+ krb5_free_principal(princ);
+ free(kbuf.data);
+ ccname = nbuf;
+ krb5_id = id;
+ return 1;
+ }
+ else
+ {
+ ErrorF("K5Add: getting principal from cache \"%s\" failed: %s\n",
+ nbuf, error_message(retval));
+ }
+ }
+ else if (!strncmp(data, "CS:", 3))
+ {
+ if ((cp = strchr(nbuf, ',')) == NULL)
+ {
+ free(nbuf);
+ return 0;
+ }
+ *cp = '\0'; /* gross but it works :-) */
+ ktlen = strlen(cp + 1);
+ if ((ktname = (char *)malloc(ktlen + 1)) == NULL)
+ {
+ free(nbuf);
+ return 0;
+ }
+ strcpy(ktname, cp + 1);
+ retval = krb5_sname_to_principal(NULL, /* NULL for hostname uses
+ local host name*/
+ nbuf, KRB5_NT_SRV_HST,
+ &srvname);
+ free(nbuf);
+ if (retval)
+ {
+ free(ktname);
+ ktname = NULL;
+ return 0;
+ }
+ if (retval = krb5_kt_resolve(ktname, &keytab))
+ {
+ free(ktname);
+ ktname = NULL;
+ krb5_free_principal(srvname);
+ srvname = NULL;
+ return 0;
+ }
+ retval = krb5_kt_get_entry(keytab, srvname, kvno, &tmp_entry);
+ krb5_kt_free_entry(&tmp_entry);
+ if (retval)
+ {
+ free(ktname);
+ ktname = NULL;
+ krb5_free_principal(srvname);
+ srvname = NULL;
+ return 0;
+ }
+ if (XauKrb5Encode(srvname, &kbuf))
+ {
+ free(ktname);
+ ktname = NULL;
+ krb5_free_principal(srvname);
+ srvname = NULL;
+ return 0;
+ }
+ AddHost(NULL, FamilyKrb5Principal, kbuf.length, kbuf.data);
+ krb5_id = id;
+ return 1;
+ }
+ else
+ {
+ ErrorF("K5Add: credentials cache name \"%.*s\" in auth file: unknown type\n",
+ data_length, data);
+ }
+ return 0;
+}
+
+/*
+ * K5Reset:
+ *
+ * Reset krb5_id, also nuke the current principal from the acl.
+ */
+int K5Reset()
+{
+ krb5_principal princ;
+ krb5_error_code retval;
+ krb5_ccache cc;
+ krb5_data kbuf;
+ int i;
+
+ if (ccname)
+ {
+ if (retval = krb5_cc_resolve(ccname, &cc))
+ {
+ free(ccname);
+ ccname = NULL;
+ }
+ if (cc && !(retval = krb5_cc_get_principal(cc, &princ)))
+ {
+ if (XauKrb5Encode(princ, &kbuf))
+ return 1;
+ RemoveHost(NULL, FamilyKrb5Principal, kbuf.length, kbuf.data);
+ krb5_free_principal(princ);
+ free(kbuf.data);
+ if (krb5_cc_close(cc))
+ return 1;
+ free(ccname);
+ ccname = NULL;
+ }
+ }
+ if (srvname)
+ {
+ if (XauKrb5Encode(srvname, &kbuf))
+ return 1;
+ RemoveHost(NULL, FamilyKrb5Principal, kbuf.length, kbuf.data);
+ krb5_free_principal(srvname);
+ free(kbuf.data);
+ srvname = NULL;
+ }
+ if (ktname)
+ {
+ free(ktname);
+ ktname = NULL;
+ }
+ krb5_id = ~0L;
+ return 0;
+}
+
+XID K5ToID(data_length, data)
+ unsigned short data_length;
+ char *data;
+{
+ return krb5_id;
+}
+
+int K5FromID(id, data_lenp, datap)
+ XID id;
+ unsigned short *data_lenp;
+ char **datap;
+{
+ return 0;
+}
+
+int K5Remove(data_length, data)
+ unsigned short data_length;
+ char *data;
+{
+ return 0;
+}
diff --git a/xc/programs/Xserver/os/lbxio.c b/xc/programs/Xserver/os/lbxio.c
new file mode 100644
index 000000000..cccd00823
--- /dev/null
+++ b/xc/programs/Xserver/os/lbxio.c
@@ -0,0 +1,575 @@
+/* $XFree86: xc/programs/Xserver/os/lbxio.c,v 3.10 1998/10/04 09:39:44 dawes Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/***********************************************************
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: lbxio.c /main/11 1998/02/09 15:12:30 kaleb $ */
+
+#include <stdio.h>
+#include <X11/Xtrans.h>
+#ifdef X_NOT_STDC_ENV
+extern int errno;
+#endif
+#include "Xmd.h"
+#include <errno.h>
+#ifndef Lynx
+#include <sys/param.h>
+#ifndef __EMX__
+#include <sys/uio.h>
+#endif
+#else
+#include <uio.h>
+#endif
+#include "X.h"
+#include "Xproto.h"
+#include "os.h"
+#include "Xpoll.h"
+#include "osdep.h"
+#include "opaque.h"
+#include "dixstruct.h"
+#include "misc.h"
+#include "lbxserve.h"
+
+/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
+ * systems are broken and return EWOULDBLOCK when they should return EAGAIN
+ */
+#if defined(EAGAIN) && defined(EWOULDBLOCK)
+#define ETEST(err) (err == EAGAIN || err == EWOULDBLOCK)
+#else
+#ifdef EAGAIN
+#define ETEST(err) (err == EAGAIN)
+#else
+#define ETEST(err) (err == EWOULDBLOCK)
+#endif
+#endif
+
+#define get_req_len(req,cli) ((cli)->swapped ? \
+ lswaps((req)->length) : (req)->length)
+
+#define YieldControl() \
+ { isItTimeToYield = TRUE; \
+ timesThisConnection = 0; }
+#define YieldControlNoInput() \
+ { YieldControl(); \
+ FD_CLR(fd, &ClientsWithInput); }
+
+void
+SwitchClientInput (client, pending)
+ ClientPtr client;
+ Bool pending;
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+
+ ConnectionTranslation[oc->fd] = client->index;
+ if (pending)
+ FD_SET(oc->fd, &ClientsWithInput);
+ else
+ YieldControl();
+}
+
+void
+LbxPrimeInput(client, proxy)
+ ClientPtr client;
+ LbxProxyPtr proxy;
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ ConnectionInputPtr oci = oc->input;
+
+ if (oci && proxy->compHandle) {
+ char *extra = oci->bufptr + oci->lenLastReq;
+ int left = oci->bufcnt + oci->buffer - extra;
+
+ (*proxy->streamOpts.streamCompStuffInput)(oc->fd,
+ (unsigned char *)extra,
+ left);
+ oci->bufcnt -= left;
+ AvailableInput = oc;
+ }
+}
+
+void
+AvailableClientInput (client)
+ ClientPtr client;
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+
+ if (FD_ISSET(oc->fd, &AllSockets))
+ FD_SET(oc->fd, &ClientsWithInput);
+}
+
+/*****************************************************************
+ * AppendFakeRequest
+ * Append a (possibly partial) request in as the last request.
+ *
+ **********************/
+
+Bool
+AppendFakeRequest (client, data, count)
+ ClientPtr client;
+ char *data;
+ int count;
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ register ConnectionInputPtr oci = oc->input;
+ int fd = oc->fd;
+ register int gotnow;
+
+ if (!oci)
+ {
+ if (oci = FreeInputs)
+ FreeInputs = oci->next;
+ else if (!(oci = AllocateInputBuffer()))
+ return FALSE;
+ oc->input = oci;
+ } else if (AvailableInput == oc)
+ AvailableInput = (OsCommPtr)NULL;
+ /* do not free AvailableInput here, it could be proxy's */
+ oci->bufptr += oci->lenLastReq;
+ oci->lenLastReq = 0;
+ gotnow = oci->bufcnt + oci->buffer - oci->bufptr;
+ if ((gotnow + count) > oci->size)
+ {
+ char *ibuf;
+
+ ibuf = (char *)xrealloc(oci->buffer, gotnow + count);
+ if (!ibuf)
+ return(FALSE);
+ oci->size = gotnow + count;
+ oci->buffer = ibuf;
+ oci->bufptr = ibuf + oci->bufcnt - gotnow;
+ }
+ if (oci->bufcnt + count > oci->size) {
+ memmove(oci->buffer, oci->bufptr, gotnow);
+ oci->bufcnt = gotnow;
+ oci->bufptr = oci->buffer;
+ }
+ memmove(oci->bufptr + gotnow, data, count);
+ oci->bufcnt += count;
+ gotnow += count;
+ if ((gotnow >= sizeof(xReq)) &&
+ (gotnow >= (int)(get_req_len((xReq *)oci->bufptr, client) << 2)))
+ FD_SET(fd, &ClientsWithInput);
+ else
+ YieldControlNoInput();
+ return(TRUE);
+}
+
+static int
+LbxWrite(trans_conn, proxy, buf, len)
+ XtransConnInfo trans_conn;
+ LbxProxyPtr proxy;
+ char *buf;
+ int len;
+{
+ struct iovec iov;
+ int n;
+ int notWritten;
+
+ notWritten = len;
+ iov.iov_base = buf;
+ iov.iov_len = len;
+ while (notWritten) {
+ errno = 0;
+ if (proxy->compHandle)
+ n = (*proxy->streamOpts.streamCompWriteV)(proxy->fd, &iov, 1);
+ else
+ n = _XSERVTransWritev(trans_conn, &iov, 1);
+ if (n >= 0) {
+ iov.iov_base = (char *)iov.iov_base + n;
+ notWritten -= n;
+ iov.iov_len = notWritten;
+ }
+ else if (ETEST(errno)
+#ifdef SUNSYSV /* check for another brain-damaged OS bug */
+ || (errno == 0)
+#endif
+#ifdef EMSGSIZE /* check for another brain-damaged OS bug */
+ || ((errno == EMSGSIZE) && (iov.iov_len == 1))
+#endif
+ )
+ break;
+#ifdef EMSGSIZE /* check for another brain-damaged OS bug */
+ else if (errno == EMSGSIZE)
+ iov.iov_len >>= 1;
+#endif
+ else
+ return -1;
+ }
+ return len - notWritten;
+}
+
+static Bool
+LbxAppendOutput(proxy, client, oco)
+ LbxProxyPtr proxy;
+ ClientPtr client;
+ ConnectionOutputPtr oco;
+{
+ ConnectionOutputPtr noco = proxy->olast;
+ LbxClientPtr lbxClient = LbxClient(client);
+
+ if (!lbxClient) {
+ xfree(oco->buf);
+ xfree(oco);
+ return TRUE;
+ }
+ if (noco)
+ LbxReencodeOutput(client,
+ (char *)noco->buf, &noco->count,
+ (char *)oco->buf, &oco->count);
+ else
+ LbxReencodeOutput(client,
+ (char *)NULL, (int *)NULL,
+ (char *)oco->buf, &oco->count);
+ if (!oco->count) {
+ if (oco->size > BUFWATERMARK)
+ {
+ xfree(oco->buf);
+ xfree(oco);
+ }
+ else
+ {
+ oco->next = FreeOutputs;
+ FreeOutputs = oco;
+ }
+ return TRUE;
+ }
+ if ((lbxClient->id != proxy->cur_send_id) && proxy->lbxClients[0]) {
+ xLbxSwitchEvent *ev;
+ int n;
+
+ if (!noco || (noco->size - noco->count) < sz_xLbxSwitchEvent) {
+ if (noco = FreeOutputs)
+ FreeOutputs = noco->next;
+ else
+ noco = AllocateOutputBuffer();
+ if (!noco) {
+ MarkClientException(client);
+ return FALSE;
+ }
+ noco->next = NULL;
+ if (proxy->olast)
+ proxy->olast->next = noco;
+ else
+ proxy->ofirst = noco;
+ proxy->olast = noco;
+ }
+ ev = (xLbxSwitchEvent *) (noco->buf + noco->count);
+ noco->count += sz_xLbxSwitchEvent;
+ proxy->cur_send_id = lbxClient->id;
+ ev->type = LbxEventCode;
+ ev->lbxType = LbxSwitchEvent;
+ ev->pad = 0;
+ ev->client = proxy->cur_send_id;
+ if (LbxProxyClient(proxy)->swapped) {
+ swapl(&ev->client, n);
+ }
+ }
+ oco->next = NULL;
+ if (proxy->olast)
+ proxy->olast->next = oco;
+ else
+ proxy->ofirst = oco;
+ proxy->olast = oco;
+ return TRUE;
+}
+
+static int
+LbxClientOutput(client, oc, extraBuf, extraCount, nocompress)
+ ClientPtr client;
+ OsCommPtr oc;
+ char *extraBuf;
+ int extraCount;
+ Bool nocompress;
+{
+ ConnectionOutputPtr oco;
+ int len;
+
+ if (oco = oc->output) {
+ oc->output = NULL;
+ if (!LbxAppendOutput(oc->proxy, client, oco))
+ return -1;
+ }
+
+ if (extraCount) {
+ NewOutputPending = TRUE;
+ FD_SET(oc->fd, &OutputPending);
+ len = (extraCount + 3) & ~3;
+ if ((oco = FreeOutputs) && (oco->size >= len))
+ FreeOutputs = oco->next;
+ else {
+ oco = (ConnectionOutputPtr)xalloc(sizeof(ConnectionOutput));
+ if (!oco) {
+ MarkClientException(client);
+ return -1;
+ }
+ oco->size = len;
+ if (oco->size < BUFSIZE)
+ oco->size = BUFSIZE;
+ oco->buf = (unsigned char *) xalloc(oco->size);
+ if (!oco->buf) {
+ xfree(oco);
+ MarkClientException(client);
+ return -1;
+ }
+ }
+ oco->count = len;
+ oco->nocompress = nocompress;
+ memmove((char *)oco->buf, extraBuf, extraCount);
+ if (!nocompress && oco->count < oco->size)
+ oc->output = oco;
+ else if (!LbxAppendOutput(oc->proxy, client, oco))
+ return -1;
+ }
+ return extraCount;
+}
+
+void
+LbxForceOutput(proxy)
+ LbxProxyPtr proxy;
+{
+ int i;
+ LbxClientPtr lbxClient;
+ OsCommPtr coc;
+ ConnectionOutputPtr oco;
+
+ for (i = proxy->maxIndex; i >= 0; i--) { /* proxy must be last */
+ lbxClient = proxy->lbxClients[i];
+ if (!lbxClient)
+ continue;
+ coc = (OsCommPtr)lbxClient->client->osPrivate;
+ if (oco = coc->output) {
+ coc->output = NULL;
+ LbxAppendOutput(proxy, lbxClient->client, oco);
+ }
+ }
+}
+
+int
+LbxFlushClient(who, oc, extraBuf, extraCount)
+ ClientPtr who;
+ OsCommPtr oc;
+ char *extraBuf;
+ int extraCount;
+{
+ LbxProxyPtr proxy;
+ ConnectionOutputPtr oco;
+ int n;
+ XtransConnInfo trans_conn;
+
+ if (extraBuf)
+ return LbxClientOutput(who, oc, extraBuf, extraCount, FALSE);
+ proxy = oc->proxy;
+ if (!proxy->lbxClients[0])
+ return 0;
+ LbxForceOutput(proxy);
+ if (!proxy->compHandle)
+ trans_conn = ((OsCommPtr)LbxProxyClient(proxy)->osPrivate)->trans_conn;
+ while (oco = proxy->ofirst) {
+ /* XXX bundle up into writev someday */
+ if (proxy->compHandle) {
+ if (oco->nocompress)
+ (*proxy->streamOpts.streamCompOff)(proxy->fd);
+ n = LbxWrite(NULL, proxy, (char *)oco->buf, oco->count);
+ if (oco->nocompress)
+ (*proxy->streamOpts.streamCompOn)(proxy->fd);
+ } else
+ n = LbxWrite(trans_conn, proxy, (char *)oco->buf, oco->count);
+ if (n < 0) {
+ ClientPtr pclient = LbxProxyClient(proxy);
+ if (proxy->compHandle)
+ trans_conn = ((OsCommPtr)pclient->osPrivate)->trans_conn;
+ _XSERVTransDisconnect(trans_conn);
+ _XSERVTransClose(trans_conn);
+ ((OsCommPtr)pclient->osPrivate)->trans_conn = NULL;
+ MarkClientException(pclient);
+ return 0;
+ } else if (n == oco->count) {
+ proxy->ofirst = oco->next;
+ if (!proxy->ofirst)
+ proxy->olast = NULL;
+ if (oco->size > BUFWATERMARK)
+ {
+ xfree(oco->buf);
+ xfree(oco);
+ }
+ else
+ {
+ oco->next = FreeOutputs;
+ oco->count = 0;
+ FreeOutputs = oco;
+ }
+ } else {
+ if (n) {
+ oco->count -= n;
+ memmove((char *)oco->buf, (char *)oco->buf + n, oco->count);
+ }
+ break;
+ }
+ }
+ if ((proxy->compHandle &&
+ (*proxy->streamOpts.streamCompFlush)(proxy->fd)) ||
+ proxy->ofirst) {
+ FD_SET(proxy->fd, &ClientsWriteBlocked);
+ AnyClientsWriteBlocked = TRUE;
+ }
+ return 0;
+}
+
+int
+UncompressedWriteToClient (who, count, buf)
+ ClientPtr who;
+ char *buf;
+ int count;
+{
+ return LbxClientOutput(who, (OsCommPtr)who->osPrivate, buf, count, TRUE);
+}
+
+LbxFreeOsBuffers(proxy)
+ LbxProxyPtr proxy;
+{
+ ConnectionOutputPtr oco;
+
+ while (oco = proxy->ofirst) {
+ proxy->ofirst = oco->next;
+ xfree(oco->buf);
+ xfree(oco);
+ }
+}
+
+Bool
+AllocateLargeReqBuffer(client, size)
+ ClientPtr client;
+ int size;
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ register ConnectionInputPtr oci;
+
+ if (!(oci = oc->largereq)) {
+ if (oci = FreeInputs)
+ FreeInputs = oci->next;
+ else {
+ oci = (ConnectionInputPtr)xalloc(sizeof(ConnectionInput));
+ if (!oci)
+ return FALSE;
+ oci->buffer = NULL;
+ oci->size = 0;
+ }
+ }
+ if (oci->size < size) {
+ char *ibuf;
+
+ oci->size = size;
+ if (size < BUFSIZE)
+ oci->size = BUFSIZE;
+ if (!(ibuf = (char *)xrealloc(oci->buffer, oci->size)))
+ {
+ xfree(oci->buffer);
+ xfree(oci);
+ oc->largereq = NULL;
+ return FALSE;
+ }
+ oci->buffer = ibuf;
+ }
+ oci->bufptr = oci->buffer;
+ oci->bufcnt = 0;
+ oci->lenLastReq = size;
+ oc->largereq = oci;
+ return TRUE;
+}
+
+Bool
+AddToLargeReqBuffer(client, data, size)
+ ClientPtr client;
+ char *data;
+ int size;
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ register ConnectionInputPtr oci = oc->largereq;
+
+ if (!oci || (oci->bufcnt + size > oci->lenLastReq))
+ return FALSE;
+ memcpy(oci->buffer + oci->bufcnt, data, size);
+ oci->bufcnt += size;
+ return TRUE;
+}
+
+static OsCommRec lbxAvailableInput;
+
+int
+PrepareLargeReqBuffer(client)
+ ClientPtr client;
+{
+ OsCommPtr oc = (OsCommPtr)client->osPrivate;
+ register ConnectionInputPtr oci = oc->largereq;
+
+ if (!oci)
+ return client->req_len << 2;
+ oc->largereq = NULL;
+ if (oci->bufcnt != oci->lenLastReq) {
+ xfree(oci->buffer);
+ xfree(oci);
+ return client->req_len << 2;
+ }
+ client->requestBuffer = oci->buffer;
+ client->req_len = oci->lenLastReq >> 2;
+ oci->bufcnt = 0;
+ oci->lenLastReq = 0;
+ if (AvailableInput)
+ {
+ register ConnectionInputPtr aci = AvailableInput->input;
+ if (aci->size > BUFWATERMARK)
+ {
+ xfree(aci->buffer);
+ xfree(aci);
+ }
+ else
+ {
+ aci->next = FreeInputs;
+ FreeInputs = aci;
+ }
+ AvailableInput->input = (ConnectionInputPtr)NULL;
+ }
+ lbxAvailableInput.input = oci;
+ AvailableInput = &lbxAvailableInput;
+ return client->req_len << 2;
+}
diff --git a/xc/programs/Xserver/os/mitauth.c b/xc/programs/Xserver/os/mitauth.c
new file mode 100644
index 000000000..fc02febcd
--- /dev/null
+++ b/xc/programs/Xserver/os/mitauth.c
@@ -0,0 +1,191 @@
+/* $TOG: mitauth.c /main/12 1998/02/09 15:12:34 kaleb $ */
+/*
+
+Copyright 1988, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+/* $XFree86: xc/programs/Xserver/os/mitauth.c,v 1.3 1998/10/11 11:23:44 dawes Exp $ */
+
+/*
+ * MIT-MAGIC-COOKIE-1 authorization scheme
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#include "X.h"
+#include "os.h"
+#include "osdep.h"
+#include "dixstruct.h"
+
+static struct auth {
+ struct auth *next;
+ unsigned short len;
+ char *data;
+ XID id;
+} *mit_auth;
+
+int
+MitAddCookie (
+ unsigned short data_length,
+ char *data,
+ XID id)
+{
+ struct auth *new;
+
+ new = (struct auth *) xalloc (sizeof (struct auth));
+ if (!new)
+ return 0;
+ new->data = (char *) xalloc ((unsigned) data_length);
+ if (!new->data) {
+ xfree(new);
+ return 0;
+ }
+ new->next = mit_auth;
+ mit_auth = new;
+ memmove(new->data, data, (int) data_length);
+ new->len = data_length;
+ new->id = id;
+ return 1;
+}
+
+XID
+MitCheckCookie (
+ unsigned short data_length,
+ char *data,
+ ClientPtr client,
+ char **reason)
+{
+ struct auth *auth;
+
+ for (auth = mit_auth; auth; auth=auth->next) {
+ if (data_length == auth->len &&
+ memcmp (data, auth->data, (int) data_length) == 0)
+ return auth->id;
+ }
+ *reason = "Invalid MIT-MAGIC-COOKIE-1 key";
+ return (XID) -1;
+}
+
+int
+MitResetCookie (void)
+{
+ struct auth *auth, *next;
+
+ for (auth = mit_auth; auth; auth=next) {
+ next = auth->next;
+ xfree (auth->data);
+ xfree (auth);
+ }
+ mit_auth = 0;
+ return 0;
+}
+
+XID
+MitToID (
+ unsigned short data_length,
+ char *data)
+{
+ struct auth *auth;
+
+ for (auth = mit_auth; auth; auth=auth->next) {
+ if (data_length == auth->len &&
+ memcmp (data, auth->data, data_length) == 0)
+ return auth->id;
+ }
+ return (XID) -1;
+}
+
+int
+MitFromID (
+ XID id,
+ unsigned short *data_lenp,
+ char **datap)
+{
+ struct auth *auth;
+
+ for (auth = mit_auth; auth; auth=auth->next) {
+ if (id == auth->id) {
+ *data_lenp = auth->len;
+ *datap = auth->data;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int
+MitRemoveCookie (
+ unsigned short data_length,
+ char *data)
+{
+ struct auth *auth, *prev;
+
+ prev = 0;
+ for (auth = mit_auth; auth; prev = auth, auth=auth->next) {
+ if (data_length == auth->len &&
+ memcmp (data, auth->data, data_length) == 0)
+ {
+ if (prev)
+ prev->next = auth->next;
+ else
+ mit_auth = auth->next;
+ xfree (auth->data);
+ xfree (auth);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+#ifdef XCSECURITY
+
+static char cookie[16]; /* 128 bits */
+
+XID
+MitGenerateCookie (
+ unsigned data_length,
+ char *data,
+ XID id,
+ unsigned *data_length_return,
+ char **data_return)
+{
+ int i = 0;
+ int status;
+
+ while (data_length--)
+ {
+ cookie[i++] += *data++;
+ if (i >= sizeof (cookie)) i = 0;
+ }
+ GenerateRandomData(sizeof (cookie), cookie);
+ status = MitAddCookie(sizeof (cookie), cookie, id);
+ if (!status)
+ {
+ id = -1;
+ }
+ else
+ {
+ *data_return = cookie;
+ *data_length_return = sizeof (cookie);
+ }
+ return id;
+}
+
+#endif /* XCSECURITY */
diff --git a/xc/programs/Xserver/os/oscolor.c b/xc/programs/Xserver/os/oscolor.c
new file mode 100644
index 000000000..b7978eaa1
--- /dev/null
+++ b/xc/programs/Xserver/os/oscolor.c
@@ -0,0 +1,300 @@
+/* $XFree86: xc/programs/Xserver/os/oscolor.c,v 3.4 1998/10/04 09:39:45 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: oscolor.c /main/17 1998/02/09 15:12:39 kaleb $ */
+
+#ifndef USE_RGB_TXT
+
+#ifdef NDBM
+#include <ndbm.h>
+#else
+#ifdef SVR4
+#include <rpcsvc/dbm.h>
+#else
+#include <dbm.h>
+#endif
+#endif
+#include "rgb.h"
+#include "os.h"
+#include "opaque.h"
+
+/* Note that we are assuming there is only one database for all the screens. */
+
+#ifdef NDBM
+DBM *rgb_dbm = (DBM *)NULL;
+#else
+int rgb_dbm = 0;
+#endif
+
+extern void CopyISOLatin1Lowered();
+
+int
+OsInitColors()
+{
+ if (!rgb_dbm)
+ {
+#ifdef NDBM
+ rgb_dbm = dbm_open(rgbPath, 0, 0);
+#else
+ if (dbminit(rgbPath) == 0)
+ rgb_dbm = 1;
+#endif
+ if (!rgb_dbm) {
+ ErrorF( "Couldn't open RGB_DB '%s'\n", rgbPath );
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/*ARGSUSED*/
+int
+OsLookupColor(screen, name, len, pred, pgreen, pblue)
+ int screen;
+ char *name;
+ unsigned len;
+ unsigned short *pred, *pgreen, *pblue;
+
+{
+ datum dbent;
+ RGB rgb;
+ char buf[64];
+ char *lowername;
+
+ if(!rgb_dbm)
+ return(0);
+
+ /* we use xalloc here so that we can compile with cc without alloca
+ * when otherwise using gcc */
+ if (len < sizeof(buf))
+ lowername = buf;
+ else if (!(lowername = (char *)xalloc(len + 1)))
+ return(0);
+ CopyISOLatin1Lowered ((unsigned char *) lowername, (unsigned char *) name,
+ (int)len);
+
+ dbent.dptr = lowername;
+ dbent.dsize = len;
+#ifdef NDBM
+ dbent = dbm_fetch(rgb_dbm, dbent);
+#else
+ dbent = fetch (dbent);
+#endif
+
+ if (len >= sizeof(buf))
+ xfree(lowername);
+
+ if(dbent.dptr)
+ {
+ memmove((char *) &rgb, dbent.dptr, sizeof (RGB));
+ *pred = rgb.red;
+ *pgreen = rgb.green;
+ *pblue = rgb.blue;
+ return (1);
+ }
+ return(0);
+}
+
+#else /* USE_RGB_TXT */
+
+
+/*
+ * The dbm routines are a porting hassle. This implementation will do
+ * the same thing by reading the rgb.txt file directly, which is much
+ * more portable.
+ */
+
+#include <stdio.h>
+#include "os.h"
+#include "opaque.h"
+
+#define HASHSIZE 511
+
+typedef struct _dbEntry * dbEntryPtr;
+typedef struct _dbEntry {
+ dbEntryPtr link;
+ unsigned short red;
+ unsigned short green;
+ unsigned short blue;
+ char name[1]; /* some compilers complain if [0] */
+} dbEntry;
+
+
+extern void CopyISOLatin1Lowered();
+
+static dbEntryPtr hashTab[HASHSIZE];
+
+
+static dbEntryPtr
+lookup(name, len, create)
+ char *name;
+ int len;
+ Bool create;
+{
+ unsigned int h = 0, g;
+ dbEntryPtr entry, *prev;
+ char *str = name;
+
+ if (!(name = (char*)ALLOCATE_LOCAL(len +1))) return NULL;
+ CopyISOLatin1Lowered(name, str, len);
+ name[len] = '\0';
+
+ for(str = name; *str; str++) {
+ h = (h << 4) + *str;
+ if ((g = h) & 0xf0000000) h ^= (g >> 24);
+ h &= g;
+ }
+ h %= HASHSIZE;
+
+ if ( entry = hashTab[h] )
+ {
+ for( ; entry; prev = (dbEntryPtr*)entry, entry = entry->link )
+ if (! strcmp(name, entry->name) ) break;
+ }
+ else
+ prev = &(hashTab[h]);
+
+ if (!entry && create && (entry = (dbEntryPtr)xalloc(sizeof(dbEntry) +len)))
+ {
+ *prev = entry;
+ entry->link = NULL;
+ strcpy( entry->name, name );
+ }
+
+ DEALLOCATE_LOCAL(name);
+
+ return entry;
+}
+
+
+Bool
+OsInitColors()
+{
+ FILE *rgb;
+ char *path;
+ char line[BUFSIZ];
+ char name[BUFSIZ];
+ int red, green, blue, lineno = 0;
+ dbEntryPtr entry;
+
+ static Bool was_here = FALSE;
+
+ if (!was_here)
+ {
+#ifndef __EMX__
+ path = (char*)ALLOCATE_LOCAL(strlen(rgbPath) +5);
+ strcpy(path, rgbPath);
+ strcat(path, ".txt");
+#else
+ char *tmp = (char*)__XOS2RedirRoot(rgbPath);
+ path = (char*)ALLOCATE_LOCAL(strlen(tmp) +5);
+ strcpy(path, tmp);
+ strcat(path, ".txt");
+#endif
+ if (!(rgb = fopen(path, "r")))
+ {
+ ErrorF( "Couldn't open RGB_DB '%s'\n", rgbPath );
+ DEALLOCATE_LOCAL(path);
+ return FALSE;
+ }
+
+ while(fgets(line, sizeof(line), rgb))
+ {
+ lineno++;
+#ifndef __EMX__
+ if (sscanf(line,"%d %d %d %[^\n]\n", &red, &green, &blue, name) == 4)
+#else
+ if (sscanf(line,"%d %d %d %[^\n\r]\n", &red, &green, &blue, name) == 4)
+#endif
+ {
+ if (red >= 0 && red <= 0xff &&
+ green >= 0 && green <= 0xff &&
+ blue >= 0 && blue <= 0xff)
+ {
+ if (entry = lookup(name, strlen(name), TRUE))
+ {
+ entry->red = (red * 65535) / 255;
+ entry->green = (green * 65535) / 255;
+ entry->blue = (blue * 65535) / 255;
+ }
+ }
+ else
+ ErrorF("Value out of range: %s:%d\n", path, lineno);
+ }
+ else if (*line && *line != '#' && *line != '!')
+ ErrorF("Syntax Error: %s:%d\n", path, lineno);
+ }
+
+ fclose(rgb);
+ DEALLOCATE_LOCAL(path);
+
+ was_here = TRUE;
+ }
+
+ return TRUE;
+}
+
+
+
+Bool
+OsLookupColor(screen, name, len, pred, pgreen, pblue)
+ int screen;
+ char *name;
+ unsigned len;
+ unsigned short *pred, *pgreen, *pblue;
+
+{
+ dbEntryPtr entry;
+
+ if (entry = lookup(name, len, FALSE))
+ {
+ *pred = entry->red;
+ *pgreen = entry->green;
+ *pblue = entry->blue;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+#endif /* USE_RGB_TXT */
diff --git a/xc/programs/Xserver/os/osdep.h b/xc/programs/Xserver/os/osdep.h
new file mode 100644
index 000000000..2ef404d50
--- /dev/null
+++ b/xc/programs/Xserver/os/osdep.h
@@ -0,0 +1,359 @@
+/* $XFree86: xc/programs/Xserver/os/osdep.h,v 3.9 1998/10/10 15:25:27 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: osdep.h /main/43 1998/02/09 15:12:43 kaleb $ */
+
+#ifndef _OSDEP_H_
+#define _OSDEP_H_ 1
+
+#ifdef AMOEBA
+#include <stddef.h>
+#define port am_port_t
+#include <amoeba.h>
+#include <stdio.h>
+#include <assert.h>
+#include <semaphore.h>
+#include <circbuf.h>
+#include <exception.h>
+#include <vc.h>
+#include <fault.h>
+#include <module/signals.h>
+#include <server/x11/Xamoeba.h>
+#undef port
+#endif
+
+#define BOTIMEOUT 200 /* in milliseconds */
+#define BUFSIZE 4096
+#define BUFWATERMARK 8192
+#ifndef MAXBUFSIZE
+#define MAXBUFSIZE (1 << 22)
+#endif
+
+#include <X11/Xdmcp.h>
+
+#ifndef sgi /* SGI defines OPEN_MAX in a useless way */
+#ifndef X_NOT_POSIX
+#ifdef _POSIX_SOURCE
+#include <limits.h>
+#else
+#define _POSIX_SOURCE
+#include <limits.h>
+#undef _POSIX_SOURCE
+#endif
+#else /* X_NOT_POSIX */
+#ifdef WIN32
+#define _POSIX_
+#include <limits.h>
+#undef _POSIX_
+#endif
+#endif /* X_NOT_POSIX */
+#endif
+
+#ifndef OPEN_MAX
+#ifdef SVR4
+#define OPEN_MAX 128
+#else
+#include <sys/param.h>
+#ifndef OPEN_MAX
+#if defined(NOFILE) && !defined(NOFILES_MAX)
+#define OPEN_MAX NOFILE
+#else
+#ifndef __EMX__
+#define OPEN_MAX NOFILES_MAX
+#else
+#define OPEN_MAX 256
+#endif
+#endif
+#endif
+#endif
+#endif
+
+#include <X11/Xpoll.h>
+
+/*
+ * MAXSOCKS is used only for initialising MaxClients when no other method
+ * like sysconf(_SC_OPEN_MAX) is not supported.
+ */
+
+#if OPEN_MAX <= 128
+#define MAXSOCKS (OPEN_MAX - 1)
+#else
+#define MAXSOCKS 128
+#endif
+
+/* MAXSELECT is the number of fds that select() can handle */
+#define MAXSELECT (sizeof(fd_set) * NBBY)
+
+#if !defined(hpux) && !defined(SVR4) && !defined(SYSV)
+#define HAS_GETDTABLESIZE
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifdef AMOEBA
+#include "X.h"
+#include "misc.h"
+
+#define FamilyAmoeba 33
+
+extern char *XServerHostName; /* X server host name */
+extern char *XTcpServerName; /* TCP/IP server name */
+extern int maxClient; /* Highest client# */
+extern int nNewConns; /* # of new clients */
+#endif /* AMOEBA */
+
+typedef Bool (*ValidatorFunc)(ARRAY8Ptr Auth, ARRAY8Ptr Data, int packet_type);
+typedef Bool (*GeneratorFunc)(ARRAY8Ptr Auth, ARRAY8Ptr Data, int packet_type);
+typedef Bool (*AddAuthorFunc)(unsigned name_length, char *name, unsigned data_length, char *data);
+
+typedef struct _connectionInput {
+ struct _connectionInput *next;
+ char *buffer; /* contains current client input */
+ char *bufptr; /* pointer to current start of data */
+ int bufcnt; /* count of bytes in buffer */
+ int lenLastReq;
+ int size;
+} ConnectionInput, *ConnectionInputPtr;
+
+typedef struct _connectionOutput {
+ struct _connectionOutput *next;
+ int size;
+ unsigned char *buf;
+ int count;
+#ifdef LBX
+ Bool nocompress;
+#endif
+} ConnectionOutput, *ConnectionOutputPtr;
+
+#ifdef K5AUTH
+typedef struct _k5_state {
+ int stageno; /* current stage of auth protocol */
+ pointer srvcreds; /* server credentials */
+ pointer srvname; /* server principal name */
+ pointer ktname; /* key table: principal-key pairs */
+ pointer skey; /* session key */
+} k5_state;
+#endif
+
+#ifdef LBX
+typedef struct _LbxProxy *OsProxyPtr;
+#endif
+
+struct _osComm;
+
+#define AuthAddCArgs unsigned short data_length, char *data, XID id
+typedef int (*AuthAddCFunc) (AuthAddCArgs);
+
+#define AuthCheckArgs unsigned short data_length, char *data, ClientPtr client, char **reason
+typedef XID (*AuthCheckFunc) (AuthCheckArgs);
+
+#define AuthFromIDArgs XID id, unsigned short *data_lenp, char **datap
+typedef int (*AuthFromIDFunc) (AuthFromIDArgs);
+
+#define AuthGenCArgs unsigned data_length, char *data, XID id, unsigned *data_length_return, char **data_return
+typedef XID (*AuthGenCFunc) (AuthGenCArgs);
+
+#define AuthRemCArgs unsigned short data_length, char *data
+typedef int (*AuthRemCFunc) (AuthRemCArgs);
+
+#define AuthRstCArgs void
+typedef int (*AuthRstCFunc) (AuthRstCArgs);
+
+#define AuthToIDArgs unsigned short data_length, char *data
+typedef XID (*AuthToIDFunc) (AuthToIDArgs);
+
+typedef void (*OsCloseFunc)(ClientPtr);
+
+typedef int (*OsFlushFunc)(ClientPtr who, struct _osComm * oc, char* extraBuf, int extraCount);
+
+typedef struct _osComm {
+ int fd;
+ ConnectionInputPtr input;
+ ConnectionOutputPtr output;
+ XID auth_id; /* authorization id */
+#ifdef K5AUTH
+ k5_state authstate; /* state of setup auth conversation */
+#endif
+ CARD32 conn_time; /* timestamp if not established, else 0 */
+ struct _XtransConnInfo *trans_conn; /* transport connection object */
+#ifdef LBX
+ OsProxyPtr proxy;
+ ConnectionInputPtr largereq;
+ OsCloseFunc Close;
+ OsFlushFunc Flush;
+#endif
+} OsCommRec, *OsCommPtr;
+
+#ifdef LBX
+#define FlushClient(who, oc, extraBuf, extraCount) \
+ (*(oc)->Flush)(who, oc, extraBuf, extraCount)
+extern int StandardFlushClient(
+ ClientPtr /*who*/,
+ OsCommPtr /*oc*/,
+ char* /*extraBuf*/,
+ int /*extraCount*/
+);
+#else
+extern int FlushClient(
+ ClientPtr /*who*/,
+ OsCommPtr /*oc*/,
+ char* /*extraBuf*/,
+ int /*extraCount*/
+);
+#endif
+
+extern void FreeOsBuffers(
+ OsCommPtr /*oc*/
+);
+
+#include "dix.h"
+
+extern ConnectionInputPtr AllocateInputBuffer(void);
+
+extern ConnectionOutputPtr AllocateOutputBuffer(void);
+
+extern fd_set AllSockets;
+extern fd_set AllClients;
+extern fd_set LastSelectMask;
+extern fd_set WellKnownConnections;
+extern fd_set EnabledDevices;
+extern fd_set ClientsWithInput;
+extern fd_set ClientsWriteBlocked;
+extern fd_set OutputPending;
+extern fd_set IgnoredClientsWithInput;
+
+extern int *ConnectionTranslation;
+
+extern Bool NewOutputPending;
+extern Bool AnyClientsWriteBlocked;
+extern Bool CriticalOutputPending;
+
+extern int timesThisConnection;
+extern ConnectionInputPtr FreeInputs;
+extern ConnectionOutputPtr FreeOutputs;
+extern OsCommPtr AvailableInput;
+
+extern WorkQueuePtr workQueue;
+
+/* added by raphael */
+#define ffs mffs
+extern int mffs(fd_mask);
+
+/* in auth.c */
+extern void GenerateRandomData (int len, char *buf);
+
+/* in mitauth.c */
+extern XID MitCheckCookie (AuthCheckArgs);
+extern XID MitGenerateCookie (AuthGenCArgs);
+extern XID MitToID (AuthToIDArgs);
+extern int MitAddCookie (AuthAddCArgs);
+extern int MitFromID (AuthFromIDArgs);
+extern int MitRemoveCookie (AuthRemCArgs);
+extern int MitResetCookie (AuthRstCArgs);
+
+/* in xdmauth.c */
+#ifdef HASXDMAUTH
+extern XID XdmCheckCookie (AuthCheckArgs);
+extern XID XdmToID (AuthToIDArgs);
+extern int XdmAddCookie (AuthAddCArgs);
+extern int XdmFromID (AuthFromIDArgs);
+extern int XdmRemoveCookie (AuthRemCArgs);
+extern int XdmResetCookie (AuthRstCArgs);
+#endif
+
+/* in rpcauth.c */
+#ifdef SECURE_RPC
+extern XID SecureRPCCheck (AuthCheckArgs);
+extern XID SecureRPCToID (AuthToIDArgs);
+extern int SecureRPCAdd (AuthAddCArgs);
+extern int SecureRPCFromID (AuthFromIDArgs);
+extern int SecureRPCRemove (AuthRemCArgs);
+extern int SecureRPCReset (AuthRstCArgs);
+#endif
+
+/* in k5auth.c */
+#ifdef K5AUTH
+extern XID K5Check (AuthCheckArgs);
+extern XID K5ToID (AuthToIDArgs);
+extern int K5Add (AuthAddCArgs);
+extern int K5FromID (AuthFromIDArgs);
+extern int K5Remove (AuthRemCArgs);
+extern int K5Reset (AuthRstCArgs);
+#endif
+
+/* in secauth.c */
+extern XID AuthSecurityCheck (AuthCheckArgs);
+
+/* in xdmcp.c */
+extern void XdmcpUseMsg (void);
+extern int XdmcpOptions(int argc, char **argv, int i);
+extern void XdmcpSetAuthentication (ARRAY8Ptr name);
+extern void XdmcpRegisterConnection (
+ int type,
+ char *address,
+ int addrlen);
+extern void XdmcpRegisterAuthorizations (void);
+extern void XdmcpRegisterAuthorization (char *name, int namelen);
+extern void XdmcpRegisterDisplayClass (char *name, int length);
+extern void XdmcpInit (void);
+extern void XdmcpReset (void);
+extern void XdmcpOpenDisplay(int sock);
+extern void XdmcpCloseDisplay(int sock);
+extern void XdmcpRegisterAuthentication (
+ char *name,
+ int namelen,
+ char *data,
+ int datalen,
+ ValidatorFunc Validator,
+ GeneratorFunc Generator,
+ AddAuthorFunc AddAuth);
+extern int XdmcpCheckAuthentication (ARRAY8Ptr Name, ARRAY8Ptr Data, int packet_type);
+extern int XdmcpAddAuthorization (ARRAY8Ptr name, ARRAY8Ptr data);
+
+#if 0
+extern void XdmcpRegisterBroadcastAddress (struct sockaddr_in *addr);
+#endif
+
+#endif /* _OSDEP_H_ */
diff --git a/xc/programs/Xserver/os/osinit.c b/xc/programs/Xserver/os/osinit.c
new file mode 100644
index 000000000..ac30145ec
--- /dev/null
+++ b/xc/programs/Xserver/os/osinit.c
@@ -0,0 +1,219 @@
+/* $XFree86: xc/programs/Xserver/os/osinit.c,v 3.17 1999/03/21 12:46:43 dawes Exp $ */
+/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+/* $TOG: osinit.c /main/47 1998/02/09 15:12:48 kaleb $ */
+
+#include <stdio.h>
+#include "X.h"
+#include "os.h"
+#include "osdep.h"
+#include "Xos.h"
+
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+
+#if !defined(SYSV) && !defined(AMOEBA) && !defined(_MINIX) && !defined(WIN32) && !defined(Lynx)
+#include <sys/resource.h>
+#endif
+
+#ifndef ADMPATH
+#define ADMPATH "/usr/adm/X%smsgs"
+#endif
+
+extern char *display;
+#ifdef RLIMIT_DATA
+int limitDataSpace = -1;
+#endif
+#ifdef RLIMIT_STACK
+int limitStackSpace = -1;
+#endif
+#ifdef RLIMIT_NOFILE
+int limitNoFile = -1;
+#endif
+
+Bool OsDelayInitColors = FALSE;
+
+#ifdef XFree86LOADER
+extern void xf86WrapperInit(void);
+#endif
+
+void
+OsInit()
+{
+#ifndef AMOEBA
+ static Bool been_here = FALSE;
+ static char* admpath = ADMPATH;
+ static char* devnull = "/dev/null";
+ char fname[PATH_MAX];
+
+#ifdef macII
+ set42sig();
+#endif
+
+ if (!been_here) {
+#ifdef XFree86LOADER
+ xf86WrapperInit();
+#endif
+#if !defined(MINIX) && !defined(SCO)
+ fclose(stdin);
+ fclose(stdout);
+#endif
+ /*
+ * If a write of zero bytes to stderr returns non-zero, i.e. -1,
+ * then writing to stderr failed, and we'll write somewhere else
+ * instead. (Apparently this never happens in the Real World.)
+ */
+ if (write (2, fname, 0) == -1)
+ {
+ FILE *err;
+
+ if (strlen (display) + strlen (admpath) + 1 < sizeof fname)
+ sprintf (fname, admpath, display);
+ else
+ strcpy (fname, devnull);
+ /*
+ * uses stdio to avoid os dependencies here,
+ * a real os would use
+ * open (fname, O_WRONLY|O_APPEND|O_CREAT, 0666)
+ */
+ if (!(err = fopen (fname, "a+")))
+ err = fopen (devnull, "w");
+ if (err && (fileno(err) != 2)) {
+ dup2 (fileno (err), 2);
+ fclose (err);
+ }
+#if defined(SYSV) || defined(SVR4) || defined(MINIX) || defined(__EMX__) || defined(WIN32)
+ {
+ static char buf[BUFSIZ];
+ setvbuf (stderr, buf, _IOLBF, BUFSIZ);
+ }
+#else
+ setlinebuf(stderr);
+#endif
+ }
+
+#ifndef X_NOT_POSIX
+ if (getpgrp () == 0)
+ setpgid (0, 0);
+#else
+#if !defined(SYSV) && !defined(WIN32)
+ if (getpgrp (0) == 0)
+ setpgrp (0, getpid ());
+#endif
+#endif
+
+#ifdef RLIMIT_DATA
+ if (limitDataSpace >= 0)
+ {
+ struct rlimit rlim;
+
+ if (!getrlimit(RLIMIT_DATA, &rlim))
+ {
+ if ((limitDataSpace > 0) && (limitDataSpace < rlim.rlim_max))
+ rlim.rlim_cur = limitDataSpace;
+ else
+ rlim.rlim_cur = rlim.rlim_max;
+ (void)setrlimit(RLIMIT_DATA, &rlim);
+ }
+ }
+#endif
+#ifdef RLIMIT_STACK
+ if (limitStackSpace >= 0)
+ {
+ struct rlimit rlim;
+
+ if (!getrlimit(RLIMIT_STACK, &rlim))
+ {
+ if ((limitStackSpace > 0) && (limitStackSpace < rlim.rlim_max))
+ rlim.rlim_cur = limitStackSpace;
+ else
+ rlim.rlim_cur = rlim.rlim_max;
+ (void)setrlimit(RLIMIT_STACK, &rlim);
+ }
+ }
+#endif
+#ifdef RLIMIT_NOFILE
+ if (limitNoFile >= 0)
+ {
+ struct rlimit rlim;
+
+ if (!getrlimit(RLIMIT_NOFILE, &rlim))
+ {
+ if ((limitNoFile > 0) && (limitNoFile < rlim.rlim_max))
+ rlim.rlim_cur = limitNoFile;
+ else
+ rlim.rlim_cur = rlim.rlim_max;
+#if 0
+ if (rlim.rlim_cur > MAXSOCKS)
+ rlim.rlim_cur = MAXSOCKS;
+#endif
+ (void)setrlimit(RLIMIT_NOFILE, &rlim);
+ }
+ }
+#endif
+#ifdef SERVER_LOCK
+ LockServer();
+#endif
+ been_here = TRUE;
+ }
+#endif /* AMOEBA */
+ TimerInit();
+#ifdef DDXOSINIT
+ OsVendorInit();
+#endif
+ OsInitAllocator();
+ if (!OsDelayInitColors) OsInitColors();
+}
+
+void
+OsCleanup()
+{
+#ifdef SERVER_LOCK
+ UnlockServer();
+#endif
+}
diff --git a/xc/programs/Xserver/os/rpcauth.c b/xc/programs/Xserver/os/rpcauth.c
new file mode 100644
index 000000000..934e8ea81
--- /dev/null
+++ b/xc/programs/Xserver/os/rpcauth.c
@@ -0,0 +1,204 @@
+/* $TOG: rpcauth.c /main/10 1998/02/09 15:12:52 kaleb $ */
+/*
+
+Copyright 1991, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+/* $XFree86: xc/programs/Xserver/os/rpcauth.c,v 3.2 1998/12/13 07:37:48 dawes Exp $ */
+
+/*
+ * SUN-DES-1 authentication mechanism
+ * Author: Mayank Choudhary, Sun Microsystems
+ */
+
+
+#ifdef SECURE_RPC
+
+#include "X.h"
+#include "Xauth.h"
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+
+#include <rpc/rpc.h>
+
+#if defined(DGUX)
+#include <time.h>
+#include <rpc/auth_des.h>
+#endif /* DGUX */
+
+#ifdef ultrix
+#include <time.h>
+#include <rpc/auth_des.h>
+#endif
+
+static enum auth_stat why;
+
+static char *
+authdes_ezdecode(inmsg, len)
+char *inmsg;
+int len;
+{
+ struct rpc_msg msg;
+ char cred_area[MAX_AUTH_BYTES];
+ char verf_area[MAX_AUTH_BYTES];
+ char *temp_inmsg;
+ struct svc_req r;
+ bool_t res0, res1;
+ XDR xdr;
+ SVCXPRT xprt;
+
+ temp_inmsg = (char *) xalloc(len);
+ memmove(temp_inmsg, inmsg, len);
+
+ memset((char *)&msg, 0, sizeof(msg));
+ memset((char *)&r, 0, sizeof(r));
+ memset(cred_area, 0, sizeof(cred_area));
+ memset(verf_area, 0, sizeof(verf_area));
+
+ msg.rm_call.cb_cred.oa_base = cred_area;
+ msg.rm_call.cb_verf.oa_base = verf_area;
+ why = AUTH_FAILED;
+ xdrmem_create(&xdr, temp_inmsg, len, XDR_DECODE);
+
+ if ((r.rq_clntcred = (caddr_t) xalloc(MAX_AUTH_BYTES)) == NULL)
+ goto bad1;
+ r.rq_xprt = &xprt;
+
+ /* decode into msg */
+ res0 = xdr_opaque_auth(&xdr, &(msg.rm_call.cb_cred));
+ res1 = xdr_opaque_auth(&xdr, &(msg.rm_call.cb_verf));
+ if ( ! (res0 && res1) )
+ goto bad2;
+
+ /* do the authentication */
+
+ r.rq_cred = msg.rm_call.cb_cred; /* read by opaque stuff */
+ if (r.rq_cred.oa_flavor != AUTH_DES) {
+ why = AUTH_TOOWEAK;
+ goto bad2;
+ }
+#ifdef SVR4
+ if ((why = __authenticate(&r, &msg)) != AUTH_OK) {
+#else
+ if ((why = _authenticate(&r, &msg)) != AUTH_OK) {
+#endif
+ goto bad2;
+ }
+ return (((struct authdes_cred *) r.rq_clntcred)->adc_fullname.name);
+
+bad2:
+ xfree(r.rq_clntcred);
+bad1:
+ return ((char *)0); /* ((struct authdes_cred *) NULL); */
+}
+
+static XID rpc_id = (XID) ~0L;
+
+static Bool
+CheckNetName (addr, len, closure)
+ unsigned char *addr;
+ int len;
+ pointer closure;
+{
+ return (len == strlen ((char *) closure) &&
+ strncmp ((char *) addr, (char *) closure, len) == 0);
+}
+
+static char rpc_error[MAXNETNAMELEN+50];
+
+XID
+SecureRPCCheck (data_length, data, client, reason)
+ register unsigned short data_length;
+ char *data;
+ ClientPtr client;
+ char **reason;
+{
+ char *fullname;
+
+ if (rpc_id == (XID) ~0L) {
+ *reason = "Secure RPC authorization not initialized";
+ } else {
+ fullname = authdes_ezdecode(data, data_length);
+ if (fullname == (char *)0) {
+ sprintf(rpc_error, "Unable to authenticate secure RPC client (why=%d)", why);
+ *reason = rpc_error;
+ } else {
+ if (ForEachHostInFamily (FamilyNetname, CheckNetName,
+ (pointer) fullname))
+ return rpc_id;
+ else {
+ sprintf(rpc_error, "Principal \"%s\" is not authorized to connect",
+ fullname);
+ *reason = rpc_error;
+ }
+ }
+ }
+ return (XID) ~0L;
+}
+
+
+SecureRPCInit ()
+{
+ if (rpc_id == ~0L)
+ AddAuthorization (9, "SUN-DES-1", 0, (char *) 0);
+}
+
+int
+SecureRPCAdd (data_length, data, id)
+unsigned short data_length;
+char *data;
+XID id;
+{
+ if (data_length)
+ AddHost ((pointer) 0, FamilyNetname, data_length, data);
+ rpc_id = id;
+}
+
+int
+SecureRPCReset ()
+{
+ rpc_id = (XID) ~0L;
+}
+
+XID
+SecureRPCToID (data_length, data)
+ unsigned short data_length;
+ char *data;
+{
+ return rpc_id;
+}
+
+SecureRPCFromID (id, data_lenp, datap)
+ XID id;
+ unsigned short *data_lenp;
+ char **datap;
+{
+ return 0;
+}
+
+SecureRPCRemove (data_length, data)
+ unsigned short data_length;
+ char *data;
+{
+ return 0;
+}
+#endif /* SECURE_RPC */
diff --git a/xc/programs/Xserver/os/secauth.c b/xc/programs/Xserver/os/secauth.c
new file mode 100644
index 000000000..678423a56
--- /dev/null
+++ b/xc/programs/Xserver/os/secauth.c
@@ -0,0 +1,196 @@
+/* $TOG: secauth.c /main/6 1998/02/09 15:12:57 kaleb $ */
+/*
+Copyright 1996, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+*/
+/* $XFree86: xc/programs/Xserver/os/secauth.c,v 1.5 1998/10/11 11:23:44 dawes Exp $ */
+
+#include "X.h"
+#include "os.h"
+#include "osdep.h"
+#include "dixstruct.h"
+
+#ifdef XCSECURITY
+#define _SECURITY_SERVER
+#include "extensions/security.h"
+#endif
+
+static char InvalidPolicyReason[] = "invalid policy specification";
+static char PolicyViolationReason[] = "policy violation";
+
+static Bool
+AuthCheckSitePolicy(
+ unsigned short *data_lengthP,
+ char **dataP,
+ ClientPtr client,
+ char **reason)
+{
+ char *policy = *dataP;
+ int length;
+ Bool permit;
+ int nPolicies;
+ char **sitePolicies;
+ int nSitePolicies;
+ Bool found = FALSE;
+
+ if ((length = *data_lengthP) < 2) {
+ *reason = InvalidPolicyReason;
+ return FALSE;
+ }
+
+ permit = (*policy++ == 0);
+ nPolicies = *policy++;
+
+ length -= 2;
+
+ sitePolicies = SecurityGetSitePolicyStrings(&nSitePolicies);
+
+ while (nPolicies) {
+ int strLen, sitePolicy;
+
+ if (length == 0) {
+ *reason = InvalidPolicyReason;
+ return FALSE;
+ }
+
+ strLen = *policy++;
+ if (--length < strLen) {
+ *reason = InvalidPolicyReason;
+ return FALSE;
+ }
+
+ if (!found)
+ {
+ for (sitePolicy = 0; sitePolicy < nSitePolicies; sitePolicy++)
+ {
+ char *testPolicy = sitePolicies[sitePolicy];
+ if ((strLen == strlen(testPolicy)) &&
+ (strncmp(policy, testPolicy, strLen) == 0))
+ {
+ found = TRUE; /* need to continue parsing the policy... */
+ break;
+ }
+ }
+ }
+
+ policy += strLen;
+ length -= strLen;
+ nPolicies--;
+ }
+
+ if (found != permit)
+ {
+ *reason = PolicyViolationReason;
+ return FALSE;
+ }
+
+ *data_lengthP = length;
+ *dataP = policy;
+ return TRUE;
+}
+
+XID
+AuthSecurityCheck (
+ unsigned short data_length,
+ char *data,
+ ClientPtr client,
+ char **reason)
+{
+#ifdef XCSECURITY
+ xConnSetupPrefix csp;
+ xReq freq;
+
+ if (client->clientState == ClientStateCheckedSecurity)
+ {
+ *reason = "repeated security check not permitted";
+ return (XID) -1;
+ }
+ else if (data_length > 0)
+ {
+ char policy_mask = *data++;
+
+ if (--data_length == 1) {
+ *reason = InvalidPolicyReason;
+ return (XID) -1;
+ }
+
+ if (policy_mask & 0x01) /* Extensions policy */
+ {
+ /* AuthCheckExtensionPolicy(&data_length, &data, client, reason) */
+ *reason = "security policy not implemented";
+ return (XID) -1;
+ }
+
+ if (policy_mask & 0x02) /* Site policy */
+ {
+ if (!AuthCheckSitePolicy(&data_length, &data, client, reason))
+ return (XID) -1;
+ }
+
+ if (data_length > 0) { /* did we consume the whole policy? */
+ *reason = InvalidPolicyReason;
+ return (XID) -1;
+ }
+
+ }
+ else if (!GetAccessControl())
+ {
+ /*
+ * The client - possibly the X FireWall Proxy - gave
+ * no auth data and host-based authorization is turned
+ * off. In this case, the client should be denied
+ * access to the X server.
+ */
+ *reason = "server host access control is disabled";
+ return (XID) -1;
+ }
+
+ client->clientState = ClientStateCheckingSecurity;
+
+ csp.success = 2 /* Authenticate */;
+ csp.lengthReason = 0;
+ csp.length = 0;
+ csp.majorVersion = X_PROTOCOL;
+ csp.minorVersion = X_PROTOCOL_REVISION;
+ if (client->swapped)
+ WriteSConnSetupPrefix(client, &csp);
+ else
+ (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
+
+ /*
+ * Next time the client sends the real auth data, we want
+ * ProcEstablishConnection to be called.
+ */
+
+ freq.reqType = 1;
+ freq.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
+ client->swapped = FALSE;
+ if (!InsertFakeRequest(client, (char *)&freq, sz_xReq))
+ {
+ *reason = "internal error";
+ return (XID) -1;
+ }
+
+ return (XID) 0;
+#else
+ *reason = "method not supported";
+ return (XID) -1;
+#endif
+}
diff --git a/xc/programs/Xserver/os/utils.c b/xc/programs/Xserver/os/utils.c
new file mode 100644
index 000000000..de6d851c7
--- /dev/null
+++ b/xc/programs/Xserver/os/utils.c
@@ -0,0 +1,1692 @@
+/* $TOG: utils.c /main/138 1998/04/22 16:32:51 msr $ */
+/*
+
+Copyright 1987, 1998 The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
+Copyright 1994 Quarterdeck Office Systems.
+
+ 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 and
+Quarterdeck not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+DIGITAL AND QUARTERDECK DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT
+OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
+OR PERFORMANCE OF THIS SOFTWARE.
+
+*/
+/* $XFree86: xc/programs/Xserver/os/utils.c,v 3.52 1999/05/15 12:10:35 dawes Exp $ */
+
+#ifdef WIN32
+#include <X11/Xwinsock.h>
+#endif
+#include "Xos.h"
+#include <stdio.h>
+#include "misc.h"
+#include "X.h"
+#include "input.h"
+#ifdef X_POSIX_C_SOURCE
+#define _POSIX_C_SOURCE X_POSIX_C_SOURCE
+#include <signal.h>
+#undef _POSIX_C_SOURCE
+#else
+#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
+#include <signal.h>
+#else
+#define _POSIX_SOURCE
+#include <signal.h>
+#undef _POSIX_SOURCE
+#endif
+#endif
+#include <sys/wait.h>
+#if !defined(SYSV) && !defined(AMOEBA) && !defined(_MINIX) && !defined(WIN32) && !defined(Lynx) && !defined(QNX)
+#include <sys/resource.h>
+#endif
+#include <time.h>
+#include <sys/stat.h>
+#include <ctype.h> /* for isspace */
+#if NeedVarargsPrototypes
+#include <stdarg.h>
+#endif
+
+#if defined(DGUX)
+#include <sys/resource.h>
+#include <netdb.h>
+#endif
+
+#ifdef AMOEBA
+#include "osdep.h"
+#include <amoeba.h>
+#include <module/mutex.h>
+
+static mutex print_lock;
+#endif
+
+#if defined(__STDC__) || defined(AMOEBA)
+/* DHD: SVR4.0 has a prototype for abs() in stdlib.h */
+/* DHD: might be better to move this include higher up? */
+#ifdef abs
+#undef abs
+#endif
+#ifndef NOSTDHDRS
+#include <stdlib.h> /* for malloc() */
+#endif
+#endif
+
+#if defined(TCPCONN) || defined(STREAMSCONN)
+# ifndef WIN32
+# include <netdb.h>
+# endif
+#endif
+
+#include "opaque.h"
+
+#include <errno.h>
+extern int errno;
+
+Bool CoreDump;
+Bool noTestExtensions;
+
+Bool noPanoramiXExtension = TRUE;
+#ifdef PANORAMIX
+Bool PanoramiXVisibilityNotifySent = FALSE;
+Bool PanoramiXMapped = FALSE;
+Bool PanoramiXWindowExposureSent = FALSE;
+Bool PanoramiXOneExposeRequest = FALSE;
+#endif
+
+#ifdef DDXOSVERRORF
+void (*OsVendorVErrorFProc)(const char *, va_list args) = NULL;
+#endif
+
+int auditTrailLevel = 1;
+
+Bool Must_have_memory = FALSE;
+
+#ifdef AIXV3
+int SyncOn = 0;
+extern int SelectWaitTime;
+#endif
+
+#ifdef DEBUG
+#ifndef SPECIAL_MALLOC
+#define MEMBUG
+#endif
+#endif
+
+#ifdef MEMBUG
+#define MEM_FAIL_SCALE 100000
+long Memory_fail = 0;
+#ifdef linux
+#include <stdlib.h> /* for random() */
+#endif
+#endif
+
+#ifdef sgi
+int userdefinedfontpath = 0;
+#endif /* sgi */
+
+char *dev_tty_from_init = NULL; /* since we need to parse it anyway */
+
+OsSigHandlerPtr
+OsSignal(sig, handler)
+ int sig;
+ OsSigHandlerPtr handler;
+{
+#ifdef X_NOT_POSIX
+ return signal(sig, handler);
+#else
+ struct sigaction act, oact;
+
+ sigemptyset(&act.sa_mask);
+ if (handler != SIG_IGN)
+ sigaddset(&act.sa_mask, sig);
+ act.sa_flags = 0;
+ act.sa_handler = handler;
+ sigaction(sig, &act, &oact);
+ return oact.sa_handler;
+#endif
+}
+
+#ifdef SERVER_LOCK
+/*
+ * Explicit support for a server lock file like the ones used for UUCP.
+ * For architectures with virtual terminals that can run more than one
+ * server at a time. This keeps the servers from stomping on each other
+ * if the user forgets to give them different display numbers.
+ */
+#ifndef __EMX__
+#define LOCK_DIR "/tmp"
+#define LOCK_TMP_PREFIX "/.tX"
+#define LOCK_PREFIX "/.X"
+#define LOCK_SUFFIX "-lock"
+#else
+#define LOCK_TMP_PREFIX "/xf86$"
+#define LOCK_PREFIX "/xf86_"
+#define LOCK_SUFFIX ".lck"
+#endif
+
+#if defined(DGUX)
+#include <limits.h>
+#include <sys/param.h>
+#endif
+
+#ifdef _MINIX
+#include <limits.h> /* For PATH_MAX */
+#endif
+
+#ifdef __EMX__
+#define link rename
+#endif
+
+#ifndef PATH_MAX
+#ifndef Lynx
+#include <sys/param.h>
+#else
+#include <param.h>
+#endif
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+#endif
+
+static Bool StillLocking = FALSE;
+static char LockFile[PATH_MAX];
+
+/*
+ * LockServer --
+ * Check if the server lock file exists. If so, check if the PID
+ * contained inside is valid. If so, then die. Otherwise, create
+ * the lock file containing the PID.
+ */
+void
+LockServer()
+{
+#ifndef AMOEBA
+ char tmp[PATH_MAX], pid_str[12];
+ int lfd, i, haslock, l_pid, t;
+ char *tmppath = NULL;
+ int len;
+
+ if (nolock) return;
+ /*
+ * Path names
+ */
+#ifndef __EMX__
+ tmppath = LOCK_DIR;
+#else
+ /* OS/2 uses TMP directory, must also prepare for 8.3 names */
+ tmppath = getenv("TMP");
+ if (!tmppath)
+ FatalError("No TMP dir found\n");
+#endif
+
+ len = strlen(LOCK_PREFIX) > strlen(LOCK_TMP_PREFIX) ? strlen(LOCK_PREFIX) :
+ strlen(LOCK_TMP_PREFIX);
+ len += strlen(tmppath) + strlen(display) + strlen(LOCK_SUFFIX) + 1;
+ if (len > sizeof(LockFile))
+ FatalError("Display name `%s' is too long\n");
+ (void)sprintf(tmp, "%s" LOCK_TMP_PREFIX "%s" LOCK_SUFFIX, tmppath, display);
+ (void)sprintf(LockFile, "%s" LOCK_PREFIX "%s" LOCK_SUFFIX, tmppath, display);
+
+ /*
+ * Create a temporary file containing our PID. Attempt three times
+ * to create the file.
+ */
+ StillLocking = TRUE;
+ i = 0;
+ do {
+ i++;
+ lfd = open(tmp, O_CREAT | O_EXCL | O_WRONLY, 0644);
+ if (lfd < 0)
+ sleep(2);
+ else
+ break;
+ } while (i < 3);
+ if (lfd < 0) {
+ unlink(tmp);
+ i = 0;
+ do {
+ i++;
+ lfd = open(tmp, O_CREAT | O_EXCL | O_WRONLY, 0644);
+ if (lfd < 0)
+ sleep(2);
+ else
+ break;
+ } while (i < 3);
+ }
+ if (lfd < 0)
+ FatalError("Could not create lock file in %s\n", tmp);
+ (void) sprintf(pid_str, "%10d\n", getpid());
+ (void) write(lfd, pid_str, 11);
+#ifndef __EMX__
+#ifndef USE_CHMOD
+ (void) fchmod(lfd, 0444);
+#else
+ (void) chmod(tmp, 0444);
+#endif
+#endif
+ (void) close(lfd);
+
+ /*
+ * OK. Now the tmp file exists. Try three times to move it in place
+ * for the lock.
+ */
+ i = 0;
+ haslock = 0;
+ while ((!haslock) && (i++ < 3)) {
+ haslock = (link(tmp,LockFile) == 0);
+ if (haslock) {
+ /*
+ * We're done.
+ */
+ break;
+ }
+ else {
+ /*
+ * Read the pid from the existing file
+ */
+ lfd = open(LockFile, O_RDONLY);
+ if (lfd < 0) {
+ unlink(tmp);
+ FatalError("Can't read lock file %s\n", LockFile);
+ }
+ pid_str[0] = '\0';
+ if (read(lfd, pid_str, 11) != 11) {
+ /*
+ * Bogus lock file.
+ */
+ unlink(LockFile);
+ close(lfd);
+ continue;
+ }
+ pid_str[11] = '\0';
+ sscanf(pid_str, "%d", &l_pid);
+ close(lfd);
+
+ /*
+ * Now try to kill the PID to see if it exists.
+ */
+ errno = 0;
+ t = kill(l_pid, 0);
+ if ((t< 0) && (errno == ESRCH)) {
+ /*
+ * Stale lock file.
+ */
+ unlink(LockFile);
+ continue;
+ }
+ else if (((t < 0) && (errno == EPERM)) || (t == 0)) {
+ /*
+ * Process is still active.
+ */
+ unlink(tmp);
+ FatalError("Server is already active for display %s\n%s %s\n%s\n",
+ display, "\tIf this server is no longer running, remove",
+ LockFile, "\tand start again.");
+ }
+ }
+ }
+ unlink(tmp);
+ if (!haslock)
+ FatalError("Could not create server lock file: %s\n", LockFile);
+ StillLocking = FALSE;
+#endif /* !AMOEBA */
+}
+
+/*
+ * UnlockServer --
+ * Remove the server lock file.
+ */
+void
+UnlockServer()
+{
+#ifndef AMOEBA
+ if (nolock) return;
+
+ if (!StillLocking){
+
+#ifdef __EMX__
+ (void) chmod(LockFile,S_IREAD|S_IWRITE);
+#endif /* __EMX__ */
+ (void) unlink(LockFile);
+ }
+#endif
+
+}
+#endif /* SERVER_LOCK */
+
+/* Force connections to close on SIGHUP from init */
+
+/*ARGSUSED*/
+SIGVAL
+AutoResetServer (sig)
+ int sig;
+{
+ dispatchException |= DE_RESET;
+ isItTimeToYield = TRUE;
+#ifdef GPROF
+ chdir ("/tmp");
+ exit (0);
+#endif
+#if defined(SYSV) && defined(X_NOT_POSIX)
+ OsSignal (SIGHUP, AutoResetServer);
+#endif
+#ifdef AMOEBA
+ WakeUpMainThread();
+#endif
+}
+
+/* Force connections to close and then exit on SIGTERM, SIGINT */
+
+/*ARGSUSED*/
+SIGVAL
+GiveUp(sig)
+ int sig;
+{
+ dispatchException |= DE_TERMINATE;
+ isItTimeToYield = TRUE;
+#if defined(SYSV) && defined(X_NOT_POSIX)
+ if (sig)
+ OsSignal(sig, SIG_IGN);
+#endif
+#ifdef AMOEBA
+ WakeUpMainThread();
+#endif
+}
+
+#if __GNUC__
+static void AbortServer() __attribute__((noreturn));
+#endif
+
+static void
+AbortServer()
+{
+ OsCleanup();
+ AbortDDX();
+ fflush(stderr);
+#ifdef AMOEBA
+ IOPCleanUp();
+#endif
+ if (CoreDump)
+ abort();
+ exit (1);
+}
+
+void
+Error(str)
+ char *str;
+{
+#ifdef AMOEBA
+ mu_lock(&print_lock);
+#endif
+ perror(str);
+#ifdef AMOEBA
+ mu_unlock(&print_lock);
+#endif
+}
+
+#ifndef DDXTIME
+CARD32
+GetTimeInMillis()
+{
+#ifndef AMOEBA
+ struct timeval tp;
+
+ X_GETTIMEOFDAY(&tp);
+ return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
+#else
+ return sys_milli();
+#endif
+}
+#endif
+
+void
+AdjustWaitForDelay (waitTime, newdelay)
+ pointer waitTime;
+ unsigned long newdelay;
+{
+ static struct timeval delay_val;
+ struct timeval **wt = (struct timeval **) waitTime;
+ unsigned long olddelay;
+
+ if (*wt == NULL)
+ {
+ delay_val.tv_sec = newdelay / 1000;
+ delay_val.tv_usec = 1000 * (newdelay % 1000);
+ *wt = &delay_val;
+ }
+ else
+ {
+ olddelay = (*wt)->tv_sec * 1000 + (*wt)->tv_usec / 1000;
+ if (newdelay < olddelay)
+ {
+ (*wt)->tv_sec = newdelay / 1000;
+ (*wt)->tv_usec = 1000 * (newdelay % 1000);
+ }
+ }
+}
+
+void UseMsg()
+{
+#if !defined(AIXrt) && !defined(AIX386)
+#ifndef AMOEBA
+ ErrorF("use: X [:<display>] [option]\n");
+#else
+ ErrorF("use: X [[<host>]:<display>] [option]\n");
+#endif
+ ErrorF("-a # mouse acceleration (pixels)\n");
+ ErrorF("-ac disable access control restrictions\n");
+#ifdef MEMBUG
+ ErrorF("-alloc int chance alloc should fail\n");
+#endif
+ ErrorF("-audit int set audit trail level\n");
+ ErrorF("-auth file select authorization file\n");
+ ErrorF("bc enable bug compatibility\n");
+ ErrorF("+bs enable any backing store support\n");
+ ErrorF("-bs disable any backing store support\n");
+ ErrorF("-c turns off key-click\n");
+ ErrorF("c # key-click volume (0-100)\n");
+ ErrorF("-cc int default color visual class\n");
+ ErrorF("-co file color database file\n");
+#ifdef COMMANDLINE_CHALLENGED_OPERATING_SYSTEMS
+ ErrorF("-config file read options from file\n");
+#endif
+ ErrorF("-core generate core dump on fatal error\n");
+ ErrorF("-dpi int screen resolution in dots per inch\n");
+#ifdef DPMSExtension
+ ErrorF("dpms enables VESA DPMS monitor control\n");
+ ErrorF("-dpms disables VESA DPMS monitor control\n");
+#endif
+ ErrorF("-deferglyphs [none|all|16] defer loading of [no|all|16-bit] glyphs\n");
+ ErrorF("-f # bell base (0-100)\n");
+ ErrorF("-fc string cursor font\n");
+ ErrorF("-fn string default font name\n");
+ ErrorF("-fp string default font path\n");
+ ErrorF("-help prints message with these options\n");
+ ErrorF("-I ignore all remaining arguments\n");
+#ifdef RLIMIT_DATA
+ ErrorF("-ld int limit data space to N Kb\n");
+#endif
+#ifdef RLIMIT_NOFILE
+ ErrorF("-lf int limit number of open files to N\n");
+#endif
+#ifdef RLIMIT_STACK
+ ErrorF("-ls int limit stack space to N Kb\n");
+#endif
+#ifdef SERVER_LOCK
+ ErrorF("-nolock disable the locking mechanism\n");
+#endif
+#ifndef NOLOGOHACK
+ ErrorF("-logo enable logo in screen saver\n");
+ ErrorF("nologo disable logo in screen saver\n");
+#endif
+ ErrorF("-nolisten string don't listen on protocol\n");
+ ErrorF("-p # screen-saver pattern duration (minutes)\n");
+ ErrorF("-pn accept failure to listen on all ports\n");
+ ErrorF("-nopn reject failure to listen on all ports\n");
+ ErrorF("-r turns off auto-repeat\n");
+ ErrorF("r turns on auto-repeat \n");
+ ErrorF("-s # screen-saver timeout (minutes)\n");
+#ifdef XCSECURITY
+ ErrorF("-sp file security policy file\n");
+#endif
+ ErrorF("-su disable any save under support\n");
+ ErrorF("-t # mouse threshold (pixels)\n");
+#ifdef AMOEBA
+ ErrorF("-tcp capability specify TCP/IP server capability\n");
+#endif
+ ErrorF("-terminate terminate at server reset\n");
+ ErrorF("-to # connection time out\n");
+ ErrorF("-tst disable testing extensions\n");
+ ErrorF("ttyxx server started from init on /dev/ttyxx\n");
+ ErrorF("v video blanking for screen-saver\n");
+ ErrorF("-v screen-saver without video blanking\n");
+ ErrorF("-wm WhenMapped default backing-store\n");
+ ErrorF("-x string loads named extension at init time \n");
+#ifdef PANORAMIX
+ ErrorF("+xinerama Enable XINERAMA extension\n");
+ ErrorF("-xinerama Disable XINERAMA extension\n");
+#endif
+#ifdef XDMCP
+ XdmcpUseMsg();
+#endif
+#endif /* !AIXrt && ! AIX386 */
+#ifdef XKB
+ XkbUseMsg();
+#endif
+ ddxUseMsg();
+}
+
+/* This function performs a rudimentary sanity check
+ * on the display name passed in on the command-line,
+ * since this string is used to generate filenames.
+ * It is especially important that the display name
+ * not contain a "/" and not start with a "-".
+ * --kvajk
+ */
+int VerifyDisplayName( d )
+char *d;
+{
+ if ( d == (char *)0 ) return( 0 ); /* null */
+ if ( *d == '\0' ) return( 0 ); /* empty */
+ if ( *d == '-' ) return( 0 ); /* could be confused for an option */
+ if ( *d == '.' ) return( 0 ); /* must not equal "." or ".." */
+ if ( strchr(d, '/') != (char *)0 ) return( 0 ); /* very important!!! */
+ return( 1 );
+}
+
+/*
+ * This function parses the command line. Handles device-independent fields
+ * and allows ddx to handle additional fields. It is not allowed to modify
+ * argc or any of the strings pointed to by argv.
+ */
+void
+ProcessCommandLine ( argc, argv )
+int argc;
+char *argv[];
+
+{
+ int i, skip;
+
+#ifdef AMOEBA
+ mu_init(&print_lock);
+#endif
+
+ defaultKeyboardControl.autoRepeat = TRUE;
+
+#ifdef PART_NET
+ PartialNetwork = TRUE;
+#endif
+
+ for ( i = 1; i < argc; i++ )
+ {
+ /* call ddx first, so it can peek/override if it wants */
+ if((skip = ddxProcessArgument(argc, argv, i)))
+ {
+ i += (skip - 1);
+ }
+ else if(argv[i][0] == ':')
+ {
+ /* initialize display */
+ display = argv[i];
+ display++;
+ if( ! VerifyDisplayName( display ) ) {
+ ErrorF("Bad display name: %s\n", display);
+ UseMsg();
+ exit(1);
+ }
+ }
+#ifdef AMOEBA
+ else if (strchr(argv[i], ':') != NULL) {
+ char *p;
+
+ XServerHostName = argv[i];
+ if ((p = strchr(argv[i], ':')) != NULL) {
+ *p++ = '\0';
+ display = p;
+ if( ! VerifyDisplayName( display ) ) {
+ ErrorF("Bad display name: %s\n", display);
+ UseMsg();
+ exit(1);
+ }
+ }
+ } else if (strcmp( argv[i], "-tcp") == 0) {
+ if (++i < argc)
+ XTcpServerName = argv[i];
+ else
+ UseMsg();
+ }
+#endif /* AMOEBA */
+ else if ( strcmp( argv[i], "-a") == 0)
+ {
+ if(++i < argc)
+ defaultPointerControl.num = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-ac") == 0)
+ {
+ defeatAccessControl = TRUE;
+ }
+#ifdef MEMBUG
+ else if ( strcmp( argv[i], "-alloc") == 0)
+ {
+ if(++i < argc)
+ Memory_fail = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+#endif
+ else if ( strcmp( argv[i], "-audit") == 0)
+ {
+ if(++i < argc)
+ auditTrailLevel = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-auth") == 0)
+ {
+ if(++i < argc)
+ InitAuthorization (argv[i]);
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "bc") == 0)
+ permitOldBugs = TRUE;
+ else if ( strcmp( argv[i], "+bs") == 0)
+ enableBackingStore = TRUE;
+ else if ( strcmp( argv[i], "-bs") == 0)
+ disableBackingStore = TRUE;
+ else if ( strcmp( argv[i], "c") == 0)
+ {
+ if(++i < argc)
+ defaultKeyboardControl.click = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-c") == 0)
+ {
+ defaultKeyboardControl.click = 0;
+ }
+ else if ( strcmp( argv[i], "-cc") == 0)
+ {
+ if(++i < argc)
+ defaultColorVisualClass = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-co") == 0)
+ {
+ if(++i < argc)
+ rgbPath = argv[i];
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-core") == 0)
+ CoreDump = TRUE;
+ else if ( strcmp( argv[i], "-dpi") == 0)
+ {
+ if(++i < argc)
+ monitorResolution = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+#ifdef DPMSExtension
+ else if ( strcmp( argv[i], "dpms") == 0)
+ DPMSEnabledSwitch = TRUE;
+ else if ( strcmp( argv[i], "-dpms") == 0)
+ DPMSDisabledSwitch = TRUE;
+#endif
+ else if ( strcmp( argv[i], "-deferglyphs") == 0)
+ {
+ if(++i >= argc || !ParseGlyphCachingMode(argv[i]))
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-f") == 0)
+ {
+ if(++i < argc)
+ defaultKeyboardControl.bell = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-fc") == 0)
+ {
+ if(++i < argc)
+ defaultCursorFont = argv[i];
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-fn") == 0)
+ {
+ if(++i < argc)
+ defaultTextFont = argv[i];
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-fp") == 0)
+ {
+ if(++i < argc)
+ {
+#ifdef sgi
+ userdefinedfontpath = 1;
+#endif /* sgi */
+ defaultFontPath = argv[i];
+ }
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-help") == 0)
+ {
+ UseMsg();
+ exit(0);
+ }
+#ifdef XKB
+ else if ( (skip=XkbProcessArguments(argc,argv,i))!=0 ) {
+ if (skip>0)
+ i+= skip-1;
+ else UseMsg();
+ }
+#endif
+#ifdef RLIMIT_DATA
+ else if ( strcmp( argv[i], "-ld") == 0)
+ {
+ if(++i < argc)
+ {
+ limitDataSpace = atoi(argv[i]);
+ if (limitDataSpace > 0)
+ limitDataSpace *= 1024;
+ }
+ else
+ UseMsg();
+ }
+#endif
+#ifdef RLIMIT_NOFILE
+ else if ( strcmp( argv[i], "-lf") == 0)
+ {
+ if(++i < argc)
+ limitNoFile = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+#endif
+#ifdef RLIMIT_STACK
+ else if ( strcmp( argv[i], "-ls") == 0)
+ {
+ if(++i < argc)
+ {
+ limitStackSpace = atoi(argv[i]);
+ if (limitStackSpace > 0)
+ limitStackSpace *= 1024;
+ }
+ else
+ UseMsg();
+ }
+#endif
+#ifdef SERVER_LOCK
+ else if ( strcmp ( argv[i], "-nolock") == 0)
+ {
+#if !defined(WIN32) && !defined(__EMX__)
+ if (getuid() != 0)
+ ErrorF("Warning: the -nolock option can only be used by root\n");
+ else
+#endif
+ nolock = TRUE;
+ }
+#endif
+#ifndef NOLOGOHACK
+ else if ( strcmp( argv[i], "-logo") == 0)
+ {
+ logoScreenSaver = 1;
+ }
+ else if ( strcmp( argv[i], "nologo") == 0)
+ {
+ logoScreenSaver = 0;
+ }
+#endif
+ else if ( strcmp( argv[i], "-nolisten") == 0)
+ {
+ if(++i < argc)
+ protNoListen = argv[i];
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-noreset") == 0)
+ {
+ extern char dispatchExceptionAtReset;
+
+ dispatchExceptionAtReset = 0;
+ }
+ else if ( strcmp( argv[i], "-p") == 0)
+ {
+ if(++i < argc)
+ defaultScreenSaverInterval = ((CARD32)atoi(argv[i])) *
+ MILLI_PER_MIN;
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-pn") == 0)
+ PartialNetwork = TRUE;
+ else if ( strcmp( argv[i], "-nopn") == 0)
+ PartialNetwork = FALSE;
+ else if ( strcmp( argv[i], "r") == 0)
+ defaultKeyboardControl.autoRepeat = TRUE;
+ else if ( strcmp( argv[i], "-r") == 0)
+ defaultKeyboardControl.autoRepeat = FALSE;
+ else if ( strcmp( argv[i], "-s") == 0)
+ {
+ if(++i < argc)
+ defaultScreenSaverTime = ((CARD32)atoi(argv[i])) *
+ MILLI_PER_MIN;
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-su") == 0)
+ disableSaveUnders = TRUE;
+ else if ( strcmp( argv[i], "-t") == 0)
+ {
+ if(++i < argc)
+ defaultPointerControl.threshold = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-terminate") == 0)
+ {
+ extern char dispatchExceptionAtReset;
+
+ dispatchExceptionAtReset = DE_TERMINATE;
+ }
+ else if ( strcmp( argv[i], "-to") == 0)
+ {
+ if(++i < argc)
+ TimeOutValue = ((CARD32)atoi(argv[i])) * MILLI_PER_SECOND;
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-tst") == 0)
+ {
+ noTestExtensions = TRUE;
+ }
+ else if ( strcmp( argv[i], "v") == 0)
+ defaultScreenSaverBlanking = PreferBlanking;
+ else if ( strcmp( argv[i], "-v") == 0)
+ defaultScreenSaverBlanking = DontPreferBlanking;
+ else if ( strcmp( argv[i], "-wm") == 0)
+ defaultBackingStore = WhenMapped;
+#ifdef PANORAMIX
+ else if ( strcmp( argv[i], "+xinerama") == 0){
+ noPanoramiXExtension = FALSE;
+ }
+ else if ( strcmp( argv[i], "-xinerama") == 0){
+ noPanoramiXExtension = TRUE;
+ }
+#endif
+ else if ( strcmp( argv[i], "-x") == 0)
+ {
+ if(++i >= argc)
+ UseMsg();
+ /* For U**x, which doesn't support dynamic loading, there's nothing
+ * to do when we see a -x. Either the extension is linked in or
+ * it isn't */
+ }
+ else if ( strcmp( argv[i], "-I") == 0)
+ {
+ /* ignore all remaining arguments */
+ break;
+ }
+ else if (strncmp (argv[i], "tty", 3) == 0)
+ {
+ /* just in case any body is interested */
+ dev_tty_from_init = argv[i];
+ }
+#ifdef XDMCP
+ else if ((skip = XdmcpOptions(argc, argv, i)) != i)
+ {
+ i = skip - 1;
+ }
+#endif
+#ifdef XPRINT
+ else if ((skip = XprintOptions(argc, argv, i)) != i)
+ {
+ i = skip - 1;
+ }
+#endif
+#ifdef XCSECURITY
+ else if ((skip = XSecurityOptions(argc, argv, i)) != i)
+ {
+ i = skip - 1;
+ }
+#endif
+#ifdef AIXV3
+ else if ( strcmp( argv[i], "-timeout") == 0)
+ {
+ if(++i < argc)
+ SelectWaitTime = atoi(argv[i]);
+ else
+ UseMsg();
+ }
+ else if ( strcmp( argv[i], "-sync") == 0)
+ {
+ SyncOn++;
+ }
+#endif
+ else
+ {
+ ErrorF("Unrecognized option: %s\n", argv[i]);
+ UseMsg();
+ exit (1);
+ }
+ }
+}
+
+#ifdef COMMANDLINE_CHALLENGED_OPERATING_SYSTEMS
+static void
+InsertFileIntoCommandLine(resargc, resargv, prefix_argc, prefix_argv,
+ filename, suffix_argc, suffix_argv)
+ int *resargc;
+ char ***resargv;
+ int prefix_argc;
+ char **prefix_argv;
+ char *filename;
+ int suffix_argc;
+ char **suffix_argv;
+{
+ struct stat st;
+ FILE *f;
+ char *p;
+ char *q;
+ int insert_argc;
+ char *buf;
+ int len;
+ int i;
+
+ f = fopen(filename, "r");
+ if (!f)
+ FatalError("Can't open option file %s\n", filename);
+
+ fstat(fileno(f), &st);
+
+ buf = (char *) xalloc((unsigned) st.st_size + 1);
+ if (!buf)
+ FatalError("Out of Memory\n");
+
+ len = fread(buf, 1, (unsigned) st.st_size, f);
+
+ fclose(f);
+
+ if (len < 0)
+ FatalError("Error reading option file %s\n", filename);
+
+ buf[len] = '\0';
+
+ p = buf;
+ q = buf;
+ insert_argc = 0;
+
+ while (*p)
+ {
+ while (isspace(*p))
+ p++;
+ if (!*p)
+ break;
+ if (*p == '#')
+ {
+ while (*p && *p != '\n')
+ p++;
+ } else
+ {
+ while (*p && !isspace(*p))
+ *q++ = *p++;
+ /* Since p and q might still be pointing at the same place, we */
+ /* need to step p over the whitespace now before we add the null. */
+ if (*p)
+ p++;
+ *q++ = '\0';
+ insert_argc++;
+ }
+ }
+
+ buf = (char *) xrealloc(buf, q - buf);
+ if (!buf)
+ FatalError("Out of memory reallocing option buf\n");
+
+ *resargc = prefix_argc + insert_argc + suffix_argc;
+ *resargv = (char **) xalloc((*resargc + 1) * sizeof(char *));
+ if (!*resargv)
+ FatalError("Out of Memory\n");
+
+ memcpy(*resargv, prefix_argv, prefix_argc * sizeof(char *));
+
+ p = buf;
+ for (i = 0; i < insert_argc; i++)
+ {
+ (*resargv)[prefix_argc + i] = p;
+ p += strlen(p) + 1;
+ }
+
+ memcpy(*resargv + prefix_argc + insert_argc,
+ suffix_argv, suffix_argc * sizeof(char *));
+
+ (*resargv)[*resargc] = NULL;
+} /* end InsertFileIntoCommandLine */
+
+
+void
+ExpandCommandLine(pargc, pargv)
+ int *pargc;
+ char ***pargv;
+{
+ int i;
+
+#if !defined(WIN32) && !defined(__EMX__)
+ if (getuid() != geteuid())
+ return;
+#endif
+
+ for (i = 1; i < *pargc; i++)
+ {
+ if ( (0 == strcmp((*pargv)[i], "-config")) && (i < (*pargc - 1)) )
+ {
+ InsertFileIntoCommandLine(pargc, pargv,
+ i, *pargv,
+ (*pargv)[i+1], /* filename */
+ *pargc - i - 2, *pargv + i + 2);
+ i--;
+ }
+ }
+} /* end ExpandCommandLine */
+#endif
+
+/* Implement a simple-minded font authorization scheme. The authorization
+ name is "hp-hostname-1", the contents are simply the host name. */
+int
+set_font_authorizations(authorizations, authlen, client)
+char **authorizations;
+int *authlen;
+pointer client;
+{
+#define AUTHORIZATION_NAME "hp-hostname-1"
+#if defined(TCPCONN) || defined(STREAMSCONN)
+ static char result[1024];
+ static char *p = NULL;
+
+ if (p == NULL)
+ {
+ char hname[1024], *hnameptr;
+ struct hostent *host;
+ int len;
+
+ gethostname(hname, 1024);
+ host = gethostbyname(hname);
+ if (host == NULL)
+ hnameptr = hname;
+ else
+ hnameptr = host->h_name;
+
+ p = result;
+ *p++ = sizeof(AUTHORIZATION_NAME) >> 8;
+ *p++ = sizeof(AUTHORIZATION_NAME) & 0xff;
+ *p++ = (len = strlen(hnameptr) + 1) >> 8;
+ *p++ = (len & 0xff);
+
+ memmove(p, AUTHORIZATION_NAME, sizeof(AUTHORIZATION_NAME));
+ p += sizeof(AUTHORIZATION_NAME);
+ memmove(p, hnameptr, len);
+ p += len;
+ }
+ *authlen = p - result;
+ *authorizations = result;
+ return 1;
+#else /* TCPCONN */
+ return 0;
+#endif /* TCPCONN */
+}
+
+/* XALLOC -- X's internal memory allocator. Why does it return unsigned
+ * long * instead of the more common char *? Well, if you read K&R you'll
+ * see they say that alloc must return a pointer "suitable for conversion"
+ * to whatever type you really want. In a full-blown generic allocator
+ * there's no way to solve the alignment problems without potentially
+ * wasting lots of space. But we have a more limited problem. We know
+ * we're only ever returning pointers to structures which will have to
+ * be long word aligned. So we are making a stronger guarantee. It might
+ * have made sense to make Xalloc return char * to conform with people's
+ * expectations of malloc, but this makes lint happier.
+ */
+
+#ifndef INTERNAL_MALLOC
+
+void *
+Xalloc (amount)
+ unsigned long amount;
+{
+#if !defined(__STDC__) && !defined(AMOEBA)
+ char *malloc();
+#endif
+ register pointer ptr;
+
+ if ((long)amount <= 0) {
+ return (unsigned long *)NULL;
+ }
+ /* aligned extra on long word boundary */
+ amount = (amount + (sizeof(long) - 1)) & ~(sizeof(long) - 1);
+#ifdef MEMBUG
+ if (!Must_have_memory && Memory_fail &&
+ ((random() % MEM_FAIL_SCALE) < Memory_fail))
+ return (unsigned long *)NULL;
+#endif
+ if ((ptr = (pointer)malloc(amount))) {
+ return (unsigned long *)ptr;
+ }
+ if (Must_have_memory)
+ FatalError("Out of memory");
+ return (unsigned long *)NULL;
+}
+
+/*****************
+ * XNFalloc
+ * "no failure" realloc, alternate interface to Xalloc w/o Must_have_memory
+ *****************/
+
+void *
+XNFalloc (amount)
+ unsigned long amount;
+{
+#if !defined(__STDC__) && !defined(AMOEBA)
+ char *malloc();
+#endif
+ register pointer ptr;
+
+ if ((long)amount <= 0)
+ {
+ return (unsigned long *)NULL;
+ }
+ /* aligned extra on long word boundary */
+ amount = (amount + (sizeof(long) - 1)) & ~(sizeof(long) - 1);
+ ptr = (pointer)malloc(amount);
+ if (!ptr)
+ {
+ FatalError("Out of memory");
+ }
+ return ((unsigned long *)ptr);
+}
+
+/*****************
+ * Xcalloc
+ *****************/
+
+void *
+Xcalloc (amount)
+ unsigned long amount;
+{
+ unsigned long *ret;
+
+ ret = Xalloc (amount);
+ if (ret)
+ bzero ((char *) ret, (int) amount);
+ return ret;
+}
+
+/*****************
+ * XNFcalloc
+ *****************/
+
+void *
+XNFcalloc (amount)
+ unsigned long amount;
+{
+ unsigned long *ret;
+
+ ret = Xalloc (amount);
+ if (ret)
+ bzero ((char *) ret, (int) amount);
+ else if ((long)amount > 0)
+ FatalError("Out of memory");
+ return ret;
+}
+
+/*****************
+ * Xrealloc
+ *****************/
+
+void *
+Xrealloc (ptr, amount)
+ register pointer ptr;
+ unsigned long amount;
+{
+#if !defined(__STDC__) && !defined(AMOEBA)
+ char *malloc();
+ char *realloc();
+#endif
+
+#ifdef MEMBUG
+ if (!Must_have_memory && Memory_fail &&
+ ((random() % MEM_FAIL_SCALE) < Memory_fail))
+ return (unsigned long *)NULL;
+#endif
+ if ((long)amount <= 0)
+ {
+ if (ptr && !amount)
+ free(ptr);
+ return (unsigned long *)NULL;
+ }
+ amount = (amount + (sizeof(long) - 1)) & ~(sizeof(long) - 1);
+ if (ptr)
+ ptr = (pointer)realloc((char *)ptr, amount);
+ else
+ ptr = (pointer)malloc(amount);
+ if (ptr)
+ return (unsigned long *)ptr;
+ if (Must_have_memory)
+ FatalError("Out of memory");
+ return (unsigned long *)NULL;
+}
+
+/*****************
+ * XNFrealloc
+ * "no failure" realloc, alternate interface to Xrealloc w/o Must_have_memory
+ *****************/
+
+void *
+XNFrealloc (ptr, amount)
+ register pointer ptr;
+ unsigned long amount;
+{
+ if (( ptr = (pointer)Xrealloc( ptr, amount ) ) == NULL)
+ {
+ if ((long)amount > 0)
+ FatalError( "Out of memory" );
+ }
+ return ((unsigned long *)ptr);
+}
+
+/*****************
+ * Xfree
+ * calls free
+ *****************/
+
+void
+Xfree(ptr)
+ register pointer ptr;
+{
+ if (ptr)
+ free((char *)ptr);
+}
+
+void
+OsInitAllocator ()
+{
+#ifdef MEMBUG
+ static int been_here;
+
+ /* Check the memory system after each generation */
+ if (been_here)
+ CheckMemory ();
+ else
+ been_here = 1;
+#endif
+}
+#endif /* !INTERNAL_MALLOC */
+
+
+char *
+Xstrdup(const char *s)
+{
+ char *sd;
+
+ if (s == NULL)
+ return NULL;
+
+ sd = (char *)Xalloc(strlen(s) + 1);
+ if (sd != NULL)
+ strcpy(sd, s);
+ return sd;
+}
+
+
+char *
+XNFstrdup(const char *s)
+{
+ char *sd;
+
+ if (s == NULL)
+ return NULL;
+
+ sd = (char *)XNFalloc(strlen(s) + 1);
+ strcpy(sd, s);
+ return sd;
+}
+
+
+void
+AuditPrefix(f)
+ char *f;
+{
+#ifdef X_NOT_STDC_ENV
+ long tm;
+#else
+ time_t tm;
+#endif
+ char *autime, *s;
+ if (*f != ' ')
+ {
+ time(&tm);
+ autime = ctime(&tm);
+ if ((s = strchr(autime, '\n')))
+ *s = '\0';
+ if ((s = strrchr(argvGlobal[0], '/')))
+ s++;
+ else
+ s = argvGlobal[0];
+ ErrorF("AUDIT: %s: %d %s: ", autime, getpid(), s);
+ }
+}
+
+/*VARARGS1*/
+void
+AuditF(
+#if NeedVarargsPrototypes
+ const char * f, ...)
+#else
+ f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) /* limit of ten args */
+ char *f;
+ char *s0, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9;
+#endif
+{
+#if NeedVarargsPrototypes
+ va_list args;
+#endif
+
+ AuditPrefix(f);
+
+#if NeedVarargsPrototypes
+ va_start(args, f);
+ VErrorF(f, args);
+ va_end(args);
+#else
+ ErrorF(f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9);
+#endif
+}
+
+/*VARARGS1*/
+void
+FatalError(
+#if NeedVarargsPrototypes
+ const char *f, ...)
+#else
+f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) /* limit of ten args */
+ const char *f;
+ char *s0, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9;
+#endif
+{
+#if NeedVarargsPrototypes
+ va_list args;
+#endif
+ static beenhere = 0;
+
+ if (beenhere)
+ ErrorF("\nFatalError re-entered, aborting\n");
+ else
+ ErrorF("\nFatal server error:\n");
+#if NeedVarargsPrototypes
+ va_start(args, f);
+ VErrorF(f, args);
+ va_end(args);
+#else
+ ErrorF(f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9);
+#endif
+ ErrorF("\n");
+#ifdef DDXOSFATALERROR
+ if (!beenhere)
+ OsVendorFatalError();
+#endif
+#ifdef ABORTONFATALERROR
+ abort();
+#endif
+ if (!beenhere)
+ AbortServer();
+ else
+ abort();
+ /*NOTREACHED*/
+}
+
+#if NeedVarargsPrototypes
+void
+VErrorF(f, args)
+ const char *f;
+ va_list args;
+{
+#ifdef AIXV3
+ if (SyncOn)
+ sync();
+#else
+#ifdef DDXOSVERRORF
+ if (OsVendorVErrorFProc)
+ OsVendorVErrorFProc(f, args);
+ else
+ vfprintf(stderr, f, args);
+#else
+ vfprintf(stderr, f, args);
+#endif
+#endif /* AIXV3 */
+}
+
+void
+VFatalError(const char *msg, va_list args)
+{
+ VErrorF(msg, args);
+ ErrorF("\n");
+#ifdef DDXOSFATALERROR
+ OsVendorFatalError();
+#endif
+ AbortServer();
+ /*NOTREACHED*/
+}
+#endif /* NeedVarargsPrototypes */
+
+/*VARARGS1*/
+void
+ErrorF(
+#if NeedVarargsPrototypes
+ const char * f, ...)
+#else
+ f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) /* limit of ten args */
+ char *f;
+ char *s0, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9;
+#endif
+{
+#if NeedVarargsPrototypes
+ va_list args;
+ va_start(args, f);
+ VErrorF(f, args);
+ va_end(args);
+#else
+#ifdef AIXV3
+ if (SyncOn)
+ sync();
+#else /* not AIXV3 */
+#ifdef AMOEBA
+ mu_lock(&print_lock);
+#endif
+ fprintf( stderr, f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9);
+#ifdef AMOEBA
+ mu_unlock(&print_lock);
+#endif
+#endif /* AIXV3 */
+#endif
+}
+
+#if !defined(WIN32) && !defined(__EMX__)
+/*
+ * "safer" versions of system(3), popen(3) and pclose(3) which give up
+ * all privs before running a command.
+ *
+ * This is based on the code in FreeBSD 2.2 libc.
+ */
+
+int
+System(command)
+ char *command;
+{
+ int pid, p;
+ void (*csig)();
+ int status;
+
+ if (!command)
+ return(1);
+
+#ifdef SIGCHLD
+ csig = signal(SIGCHLD, SIG_DFL);
+#endif
+
+ ErrorF("System: `%s'\n", command);
+
+ switch (pid = fork()) {
+ case -1: /* error */
+ p = -1;
+ case 0: /* child */
+ setgid(getgid());
+ setuid(getuid());
+ execl("/bin/sh", "sh", "-c", command, (char *)NULL);
+ _exit(127);
+ default: /* parent */
+ do {
+ p = waitpid(pid, &status, 0);
+ } while (p == -1 && errno == EINTR);
+
+ }
+
+#ifdef SIGCHLD
+ signal(SIGCHLD, csig);
+#endif
+
+ return p == -1 ? -1 : status;
+}
+
+static struct pid {
+ struct pid *next;
+ FILE *fp;
+ int pid;
+} *pidlist;
+
+pointer
+Popen(command, type)
+ char *command;
+ char *type;
+{
+ struct pid *cur;
+ FILE *iop;
+ int pdes[2], pid;
+ void (*csig)();
+
+ if (command == NULL || type == NULL)
+ return NULL;
+
+ if ((*type != 'r' && *type != 'w') || type[1])
+ return NULL;
+
+ if ((cur = (struct pid *)xalloc(sizeof(struct pid))) == NULL)
+ return NULL;
+
+ if (pipe(pdes) < 0) {
+ xfree(cur);
+ return NULL;
+ }
+
+ switch (pid = fork()) {
+ case -1: /* error */
+ close(pdes[0]);
+ close(pdes[1]);
+ xfree(cur);
+ return NULL;
+ case 0: /* child */
+ setgid(getgid());
+ setuid(getuid());
+ if (*type == 'r') {
+ if (pdes[1] != 1) {
+ /* stdout */
+ dup2(pdes[1], 1);
+ close(pdes[1]);
+ }
+ close(pdes[0]);
+ } else {
+ if (pdes[0] != 0) {
+ /* stdin */
+ dup2(pdes[0], 0);
+ close(pdes[0]);
+ }
+ close(pdes[1]);
+ }
+ execl("/bin/sh", "sh", "-c", command, (char *)NULL);
+ _exit(127);
+ }
+
+ /* parent */
+ if (*type == 'r') {
+ iop = fdopen(pdes[0], type);
+ close(pdes[1]);
+ } else {
+ iop = fdopen(pdes[1], type);
+ close(pdes[0]);
+ }
+
+ cur->fp = iop;
+ cur->pid = pid;
+ cur->next = pidlist;
+ pidlist = cur;
+
+#if 0
+ ErrorF("Popen: `%s', fp = %p\n", command, iop);
+#endif
+
+ return iop;
+}
+
+int
+Pclose(iop)
+ pointer iop;
+{
+ struct pid *cur, *last;
+ int omask;
+ int pstat;
+ int pid;
+
+#if 0
+ ErrorF("Pclose: fp = %p\n", iop);
+#endif
+
+ fclose(iop);
+
+ for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
+ if (cur->fp == iop)
+ break;
+ if (cur == NULL)
+ return -1;
+
+ do {
+ pid = waitpid(cur->pid, &pstat, 0);
+ } while (pid == -1 && errno == EINTR);
+
+ if (last == NULL)
+ pidlist = cur->next;
+ else
+ last->next = cur->next;
+ xfree(cur);
+
+ return pid == -1 ? -1 : pstat;
+}
+#endif /* !WIN32 && !__EMX__ */
diff --git a/xc/programs/Xserver/os/xalloc.c b/xc/programs/Xserver/os/xalloc.c
new file mode 100644
index 000000000..102807b99
--- /dev/null
+++ b/xc/programs/Xserver/os/xalloc.c
@@ -0,0 +1,792 @@
+/*
+Copyright (C) 1995 Pascal Haible. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+PASCAL HAIBLE 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 Pascal Haible shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from
+Pascal Haible.
+*/
+
+/* $XFree86: xc/programs/Xserver/os/xalloc.c,v 3.22 1999/07/04 06:40:08 dawes Exp $ */
+
+/* Only used if INTERNAL_MALLOC is defined
+ * - otherwise xalloc() in utils.c is used
+ */
+#ifdef INTERNAL_MALLOC
+
+#if defined(__STDC__) || defined(AMOEBA)
+#ifndef NOSTDHDRS
+#include <stdlib.h> /* for malloc() etc. */
+#endif
+#else
+extern char *malloc();
+extern char *calloc();
+extern char *realloc();
+#endif
+
+#include "Xos.h"
+#include "misc.h"
+#include "X.h"
+
+#ifdef XALLOC_LOG
+#include <stdio.h>
+#endif
+
+extern Bool Must_have_memory;
+
+/*
+ ***** New malloc approach for the X server *****
+ * Pascal Haible 1995
+ *
+ * Some statistics about memory allocation of the X server
+ * The test session included several clients of different size, including
+ * xv, emacs and xpaint with a new canvas of 3000x2000, zoom 5.
+ * All clients were running together.
+ * A protocolling version of Xalloc recorded 318917 allocating actions
+ * (191573 Xalloc, 85942 XNFalloc, 41438 Xrealloc, 279727 Xfree).
+ * Results grouped by size, excluding the next lower size
+ * (i.e. size=32 means 16<size<=32):
+ *
+ * size nr of alloc max nr of blocks allocated together
+ * 8 1114 287
+ * 16 17341 4104
+ * 32 147352 2068
+ * 64 59053 2518
+ * 128 46882 1230
+ * 256 20544 1217
+ * 512 6808 117
+ * 1024 8254 171
+ * 2048 4841 287
+ * 4096 2429 84
+ * 8192 3364 85
+ * 16384 573 22
+ * 32768 49 7
+ * 65536 45 5
+ * 131072 48 2
+ * 262144 209 2
+ * 524288 7 4
+ * 1048576 2 1
+ * 8388608 2 2
+ *
+ * The most used sizes:
+ * count size
+ * 24 136267
+ * 40 37055
+ * 72 17278
+ * 56 13504
+ * 80 9372
+ * 16 8966
+ * 32 8411
+ * 136 8399
+ * 104 7690
+ * 12 7630
+ * 120 5512
+ * 88 4634
+ * 152 3062
+ * 52 2881
+ * 48 2736
+ * 156 1569
+ * 168 1487
+ * 160 1483
+ * 28 1446
+ * 1608 1379
+ * 184 1305
+ * 552 1270
+ * 64 934
+ * 320 891
+ * 8 754
+ *
+ * Conclusions: more than the half of all allocations are <= 32 bytes.
+ * But of these about 150,000 blocks, only a maximum of about 6,000 are
+ * allocated together (including memory leaks..).
+ * On the other side, only 935 of the 191573 or 0.5% were larger than 8kB
+ * (362 or 0.2% larger than 16k).
+ *
+ * What makes the server really grow is the fragmentation of the heap,
+ * and the fact that it can't shrink.
+ * To cure this, we do the following:
+ * - large blocks (>=11k) are mmapped on xalloc, and unmapped on xfree,
+ * so we don't need any free lists etc.
+ * As this needs 2 system calls, we only do this for the quite
+ * infrequent large (>=11k) blocks.
+ * - instead of reinventing the wheel, we use system malloc for medium
+ * sized blocks (>256, <11k).
+ * - for small blocks (<=256) we use an other approach:
+ * As we need many small blocks, and most ones for a short time,
+ * we don't go through the system malloc:
+ * for each fixed sizes a seperate list of free blocks is kept.
+ * to KISS (Keep it Small and Simple), we don't free them
+ * (not freeing a block of 32 bytes won't be worse than having fragmented
+ * a larger area on allocation).
+ * This way, we (almost) allways have a fitting free block right at hand,
+ * and don't have to walk any lists.
+ */
+
+/*
+ * structure layout of a allocated block
+ * unsigned long size:
+ * rounded up netto size for small and medium blocks
+ * brutto size == mmap'ed area for large blocks
+ * unsigned long DEBUG ? MAGIC : unused
+ * .... data
+ * ( unsigned long MAGIC2 ) only if SIZE_TAIL defined
+ *
+ */
+
+/* use otherwise unused long in the header to store a magic */
+/* shouldn't this be removed for production release ? */
+#define XALLOC_DEBUG
+
+#ifdef XALLOC_DEBUG
+/* Xfree fills the memory with a certain pattern (currently 0xF0) */
+/* this should really be removed for production release! */
+#define XFREE_ERASES
+#endif
+
+/* this must be a multiple of SIZE_STEPS below */
+#define MAX_SMALL 264 /* quite many blocks of 264 */
+
+#define MIN_LARGE (11*1024)
+/* worst case is 25% loss with a page size of 4k */
+
+/* SIZE_STEPS defines the granularity of size of small blocks -
+ * this makes blocks align to that, too! */
+#define SIZE_STEPS (sizeof(double))
+#define SIZE_HEADER (2*sizeof(long)) /* = sizeof(double) for 32bit */
+#ifdef XALLOC_DEBUG
+#if defined(__sparc__)
+#define SIZE_TAIL (2*sizeof(long)) /* = sizeof(double) for 32bit */
+#else
+#define SIZE_TAIL (sizeof(long))
+#endif
+#endif
+
+#undef TAIL_SIZE
+#ifdef SIZE_TAIL
+#define TAIL_SIZE SIZE_TAIL
+#else
+#define TAIL_SIZE 0
+#endif
+
+#ifdef __alpha__
+#define MAGIC 0x1404196414071968
+#define MAGIC_FREE 0x1506196615061966
+#define MAGIC2 0x2515207525182079
+#else
+#define MAGIC 0x14071968
+#define MAGIC_FREE 0x15061966
+#define MAGIC2 0x25182079
+#endif
+
+/* To get some statistics about memory allocation */
+
+#ifdef XALLOC_LOG
+#define XALLOC_LOG_FILE "/tmp/Xalloc.log" /* unsecure... */
+#define LOG_BODY(_body) \
+ { FILE *f; \
+ f = fopen(XALLOC_LOG_FILE, "a"); \
+ if (NULL!=f) { \
+ _body; \
+ fclose(f); \
+ } \
+ }
+#if defined(linux) && defined(i386)
+#define LOG_ALLOC(_fun, _size, _ret) \
+ { unsigned long *from; \
+ __asm__("movl %%ebp,%0" : /*OUT*/ "=r" (from) : /*IN*/ ); \
+ LOG_BODY(fprintf(f, "%s\t%i\t%p\t[%lu]\n", _fun, _size, _ret, *(from+1))) \
+ }
+#else
+#define LOG_ALLOC(_fun, _size, _ret) \
+ LOG_BODY(fprintf(f, "%s\t%i\t%p\n", _fun, _size, _ret))
+#endif
+#define LOG_REALLOC(_fun, _ptr, _size, _ret) \
+ LOG_BODY(fprintf(f, "%s\t%p\t%i\t%p\n", _fun, _ptr, _size, _ret))
+#define LOG_FREE(_fun, _ptr) \
+ LOG_BODY(fprintf(f, "%s\t%p\n", _fun, _ptr))
+#else
+#define LOG_ALLOC(_fun, _size, _ret)
+#define LOG_REALLOC(_fun, _ptr, _size, _ret)
+#define LOG_FREE(_fun, _ptr)
+#endif /* XALLOC_LOG */
+
+static unsigned long *free_lists[MAX_SMALL/SIZE_STEPS];
+
+/*
+ * systems that support it should define HAS_MMAP_ANON or MMAP_DEV_ZERO
+ * and include the appropriate header files for
+ * mmap(), munmap(), PROT_READ, PROT_WRITE, MAP_PRIVATE,
+ * PAGE_SIZE or _SC_PAGESIZE (and MAP_ANON for HAS_MMAP_ANON).
+ *
+ * systems that don't support MAP_ANON fall through to the 2 fold behaviour
+ */
+
+#if defined(linux)
+#define HAS_MMAP_ANON
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <asm/page.h> /* PAGE_SIZE */
+#define HAS_SC_PAGESIZE /* _SC_PAGESIZE may be an enum for Linux */
+#define HAS_GETPAGESIZE
+#endif /* linux */
+
+#if defined(CSRG_BASED)
+#define HAS_MMAP_ANON
+#define HAS_GETPAGESIZE
+#include <sys/types.h>
+#include <sys/mman.h>
+#endif /* CSRG_BASED */
+
+#if defined(DGUX)
+#define HAS_GETPAGESIZE
+#define MMAP_DEV_ZERO
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#endif /* DGUX */
+
+#if defined(SVR4) && !defined(DGUX)
+#define MMAP_DEV_ZERO
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#endif /* SVR4 && !DGUX */
+
+#if defined(sun) && !defined(SVR4) /* SunOS */
+#define MMAP_DEV_ZERO /* doesn't SunOS have MAP_ANON ?? */
+#define HAS_GETPAGESIZE
+#include <sys/types.h>
+#include <sys/mman.h>
+#endif /* sun && !SVR4 */
+
+#ifdef XNO_SYSCONF
+#undef _SC_PAGESIZE
+#endif
+
+#if defined(HAS_MMAP_ANON) || defined (MMAP_DEV_ZERO)
+static int pagesize;
+#endif
+
+#ifdef MMAP_DEV_ZERO
+static int devzerofd = -1;
+#include <errno.h>
+#ifdef X_NOT_STDC_ENV
+extern int errno;
+#endif
+#endif
+
+/*
+ * empty trap function for gdb. Breakpoint here
+ * to find who tries to free a free area
+ */
+void XfreeTrap(void)
+{
+}
+
+void *
+Xalloc (unsigned long amount)
+{
+ register unsigned long *ptr;
+ int indx;
+
+ /* sanity checks */
+
+ /* zero size requested */
+ if (amount == 0) {
+ LOG_ALLOC("Xalloc=0", amount, 0);
+ return NULL;
+ }
+ /* negative size (or size > 2GB) - what do we do? */
+ if ((long)amount < 0) {
+ /* Diagnostic */
+#ifdef FATALERRORS
+ FatalError("Xalloc: Xalloc(<0)\n");
+#else
+ ErrorF("Xalloc warning: Xalloc(<0) ignored..\n");
+#endif
+ LOG_ALLOC("Xalloc<0", amount, 0);
+ return NULL;
+ }
+
+ /* alignment check */
+#if defined(__alpha__) || defined(__sparc__) || defined(__mips__) || defined(__powerpc__) || defined(__arm32__)
+ amount = (amount + (sizeof(long)-1)) & ~(sizeof(long)-1);
+#endif
+
+ if (amount <= MAX_SMALL) {
+ /*
+ * small block
+ */
+ /* pick a ready to use small chunk */
+ indx = (amount-1) / SIZE_STEPS;
+ ptr = free_lists[indx];
+ if (NULL == ptr) {
+ /* list empty - get 20 or 40 more */
+ /* amount = size rounded up */
+ amount = (indx+1) * SIZE_STEPS;
+ ptr = (unsigned long *)calloc(1,(amount+SIZE_HEADER+TAIL_SIZE)
+ * (amount<100 ? 40 : 20));
+ if (NULL!=ptr) {
+ int i;
+ unsigned long *p1, *p2;
+ p1 = 0;
+ p2 = (unsigned long *)((char *)ptr + SIZE_HEADER);
+ for (i=0; i<(amount<100 ? 40 : 20); i++) {
+ p1 = p2;
+ p1[-2] = amount;
+#ifdef XALLOC_DEBUG
+ p1[-1] = MAGIC_FREE;
+#endif /* XALLOC_DEBUG */
+#ifdef SIZE_TAIL
+ *(unsigned long *)((unsigned char *)p1 + amount) = MAGIC2;
+#endif /* SIZE_TAIL */
+ p2 = (unsigned long *)((char *)p1 + SIZE_HEADER + amount + TAIL_SIZE);
+ *(unsigned long **)p1 = p2;
+ }
+ /* last one has no next one */
+ *(unsigned long **)p1 = NULL;
+ /* put the second in the list */
+ free_lists[indx] = (unsigned long *)((char *)ptr + SIZE_HEADER + amount + TAIL_SIZE + SIZE_HEADER);
+ /* take the fist one */
+ ptr = (unsigned long *)((char *)ptr + SIZE_HEADER);
+ LOG_ALLOC("Xalloc-S", amount, ptr);
+ ptr[-1] = MAGIC;
+ return (void *)ptr;
+ } /* else fall through to 'Out of memory' */
+ } else {
+ /* take that piece of mem out of the list */
+ free_lists[indx] = *((unsigned long **)ptr);
+ /* already has size (and evtl. magic) filled in */
+#ifdef XALLOC_DEBUG
+ ptr[-1] = MAGIC;
+#endif /* XALLOC_DEBUG */
+ LOG_ALLOC("Xalloc-S", amount, ptr);
+ return (void *)ptr;
+ }
+
+#if defined(HAS_MMAP_ANON) || defined(MMAP_DEV_ZERO)
+ } else if (amount >= MIN_LARGE) {
+ /*
+ * large block
+ */
+ /* mmapped malloc */
+ /* round up amount */
+ amount += SIZE_HEADER + TAIL_SIZE;
+ /* round up brutto amount to a multiple of the page size */
+ amount = (amount + pagesize-1) & ~(pagesize-1);
+#ifdef MMAP_DEV_ZERO
+ ptr = (unsigned long *)mmap((caddr_t)0,
+ (size_t)amount,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE,
+ devzerofd,
+ (off_t)0);
+#else
+ ptr = (unsigned long *)mmap((caddr_t)0,
+ (size_t)amount,
+ PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE,
+ -1,
+ (off_t)0);
+#endif
+ if (-1!=(long)ptr) {
+ ptr[0] = amount - SIZE_HEADER - TAIL_SIZE;
+#ifdef XALLOC_DEBUG
+ ptr[1] = MAGIC;
+#endif /* XALLOC_DEBUG */
+#ifdef SIZE_TAIL
+ ((unsigned long *)((char *)ptr + amount))[-1] = MAGIC2;
+#endif /* SIZE_TAIL */
+ ptr = (unsigned long *)((char *)ptr + SIZE_HEADER);
+ LOG_ALLOC("Xalloc-L", amount, ptr);
+ return (void *)ptr;
+ } /* else fall through to 'Out of memory' */
+#endif /* HAS_MMAP_ANON || MMAP_DEV_ZERO */
+ } else {
+ /*
+ * medium sized block
+ */
+ /* 'normal' malloc() */
+ ptr=(unsigned long *)calloc(1,amount+SIZE_HEADER+TAIL_SIZE);
+ if (ptr != (unsigned long *)NULL) {
+ ptr[0] = amount;
+#ifdef XALLOC_DEBUG
+ ptr[1] = MAGIC;
+#endif /* XALLOC_DEBUG */
+#ifdef SIZE_TAIL
+ *(unsigned long *)((char *)ptr + amount + SIZE_HEADER) = MAGIC2;
+#endif /* SIZE_TAIL */
+ ptr = (unsigned long *)((char *)ptr + SIZE_HEADER);
+ LOG_ALLOC("Xalloc-M", amount, ptr);
+ return (void *)ptr;
+ }
+ }
+ if (Must_have_memory)
+ FatalError("Out of memory");
+ LOG_ALLOC("Xalloc-oom", amount, 0);
+ return NULL;
+}
+
+/*****************
+ * XNFalloc
+ * "no failure" realloc, alternate interface to Xalloc w/o Must_have_memory
+ *****************/
+
+pointer
+XNFalloc (unsigned long amount)
+{
+ register pointer ptr;
+
+ /* zero size requested */
+ if (amount == 0) {
+ LOG_ALLOC("XNFalloc=0", amount, 0);
+ return NULL;
+ }
+ /* negative size (or size > 2GB) - what do we do? */
+ if ((long)amount < 0) {
+ /* Diagnostic */
+#ifdef FATALERRORS
+ FatalError("Xalloc: XNFalloc(<0)\n");
+#else
+ ErrorF("Xalloc warning: XNFalloc(<0) ignored..\n");
+#endif
+ LOG_ALLOC("XNFalloc<0", amount, 0);
+ return (unsigned long *)NULL;
+ }
+ ptr = Xalloc(amount);
+ if (!ptr)
+ {
+ FatalError("Out of memory");
+ }
+ return ptr;
+}
+
+/*****************
+ * Xcalloc
+ *****************/
+
+pointer
+Xcalloc (unsigned long amount)
+{
+ pointer ret;
+
+ ret = Xalloc (amount);
+ if (ret != 0
+#if defined(HAS_MMAP_ANON) || defined(MMAP_DEV_ZERO)
+ && (amount < MIN_LARGE) /* mmaped anonymous mem is already cleared */
+#endif
+ )
+ bzero ((char *) ret, (int) amount);
+ return ret;
+}
+
+/*****************
+ * XNFcalloc
+ *****************/
+void *
+XNFcalloc (unsigned long amount)
+{
+ pointer ret;
+
+ ret = XNFalloc (amount);
+ if (ret != 0
+#if defined(HAS_MMAP_ANON) || defined(MMAP_DEV_ZERO)
+ && (amount < MIN_LARGE) /* mmaped anonymous mem is already cleared */
+#endif
+ )
+ bzero ((char *) ret, (int) amount);
+ return ret;
+}
+
+/*****************
+ * Xrealloc
+ *****************/
+
+void *
+Xrealloc (pointer ptr, unsigned long amount)
+{
+ register unsigned long *new_ptr;
+
+ /* zero size requested */
+ if (amount == 0) {
+ if (ptr)
+ Xfree(ptr);
+ LOG_REALLOC("Xrealloc=0", ptr, amount, 0);
+ return NULL;
+ }
+ /* negative size (or size > 2GB) - what do we do? */
+ if ((long)amount < 0) {
+ /* Diagnostic */
+#ifdef FATALERRORS
+ FatalError("Xalloc: Xrealloc(<0)\n");
+#else
+ ErrorF("Xalloc warning: Xrealloc(<0) ignored..\n");
+#endif
+ if (ptr)
+ Xfree(ptr); /* ?? */
+ LOG_REALLOC("Xrealloc<0", ptr, amount, 0);
+ return NULL;
+ }
+
+ new_ptr = Xalloc(amount);
+ if ( (new_ptr) && (ptr) ) {
+ unsigned long old_size;
+ old_size = ((unsigned long *)ptr)[-2];
+#ifdef XALLOC_DEBUG
+ if (MAGIC != ((unsigned long *)ptr)[-1]) {
+ if (MAGIC_FREE == ((unsigned long *)ptr)[-1]) {
+#ifdef FATALERRORS
+ XfreeTrap();
+ FatalError("Xalloc error: range already freed in Xrealloc() :-(\n");
+#else
+ ErrorF("Xalloc error: range already freed in Xrealloc() :-(\a\n");
+ sleep(5);
+ XfreeTrap();
+#endif
+ LOG_REALLOC("Xalloc error: ranged already freed in Xrealloc() :-(",
+ ptr, amount, 0);
+ return NULL;
+ }
+#ifdef FATALERRORS
+ FatalError("Xalloc error: header corrupt in Xrealloc() :-(\n");
+#else
+ ErrorF("Xalloc error: header corrupt in Xrealloc() :-(\n");
+#endif
+ LOG_REALLOC("Xalloc error: header corrupt in Xrealloc() :-(",
+ ptr, amount, 0);
+ return NULL;
+ }
+#endif /* XALLOC_DEBUG */
+ /* copy min(old size, new size) */
+ memcpy((char *)new_ptr, (char *)ptr, (amount < old_size ? amount : old_size));
+ }
+ if (ptr)
+ Xfree(ptr);
+ if (new_ptr) {
+ LOG_REALLOC("Xrealloc", ptr, amount, new_ptr);
+ return (void *)new_ptr;
+ }
+ if (Must_have_memory)
+ FatalError("Out of memory");
+ LOG_REALLOC("Xrealloc", ptr, amount, 0);
+ return NULL;
+}
+
+/*****************
+ * XNFrealloc
+ * "no failure" realloc, alternate interface to Xrealloc w/o Must_have_memory
+ *****************/
+
+void *
+XNFrealloc (pointer ptr, unsigned long amount)
+{
+ if (( ptr = (pointer)Xrealloc( ptr, amount ) ) == NULL)
+ {
+ FatalError( "Out of memory" );
+ }
+ return ptr;
+}
+
+/*****************
+ * Xfree
+ * calls free
+ *****************/
+
+void
+Xfree(pointer ptr)
+{
+ unsigned long size;
+ unsigned long *pheader;
+
+ /* free(NULL) IS valid :-( - and widely used throughout the server.. */
+ if (!ptr)
+ return;
+
+ pheader = (unsigned long *)((char *)ptr - SIZE_HEADER);
+#ifdef XALLOC_DEBUG
+ if (MAGIC != pheader[1]) {
+ /* Diagnostic */
+ if (MAGIC_FREE == pheader[1]) {
+#ifdef FATALERRORS
+ XfreeTrap();
+ FatalError("Xalloc error: range already freed in Xrealloc() :-(\n");
+#else
+ ErrorF("Xalloc error: range already freed in Xrealloc() :-(\a\n");
+ sleep(5);
+ XfreeTrap();
+#endif
+ LOG_REALLOC("Xalloc error: ranged already freed in Xrealloc() :-(",
+ ptr, amount, 0);
+ return;
+ }
+#ifdef FATALERRORS
+ FatalError("Xalloc error: Header corrupt in Xfree() :-(\n");
+#else
+ ErrorF("Xalloc error: Header corrupt in Xfree() :-(\n");
+#endif
+ LOG_FREE("Xalloc error: Header corrupt in Xfree() :-(", ptr);
+ return;
+ }
+#endif /* XALLOC_DEBUG */
+
+ size = pheader[0];
+ if (size <= MAX_SMALL) {
+ int indx;
+ /*
+ * small block
+ */
+#ifdef SIZE_TAIL
+ if (MAGIC2 != *(unsigned long *)((char *)ptr + size)) {
+ /* Diagnostic */
+#ifdef FATALERRORS
+ FatalError("Xalloc error: Tail corrupt in Xfree() for small block (adr=0x%x, val=0x%x)\n",(char *)ptr + size,*(unsigned long *)((char *)ptr + size));
+#else
+ ErrorF("Xalloc error: Tail corrupt in Xfree() for small block (adr=0x%x, val=0x%x)\n",(char *)ptr + size,*(unsigned long *)((char *)ptr + size));
+#endif
+ LOG_FREE("Xalloc error: Tail corrupt in Xfree() for small block", ptr);
+ return;
+ }
+#endif /* SIZE_TAIL */
+
+#ifdef XFREE_ERASES
+ memset(ptr,0xF0,size);
+#endif /* XFREE_ERASES */
+#ifdef XALLOC_DEBUG
+ pheader[1] = MAGIC_FREE;
+#endif
+ /* put this small block at the head of the list */
+ indx = (size-1) / SIZE_STEPS;
+ *(unsigned long **)(ptr) = free_lists[indx];
+ free_lists[indx] = (unsigned long *)ptr;
+ LOG_FREE("Xfree", ptr);
+ return;
+
+#if defined(HAS_MMAP_ANON) || defined(MMAP_DEV_ZERO)
+ } else if (size >= MIN_LARGE) {
+ /*
+ * large block
+ */
+#ifdef SIZE_TAIL
+ if (MAGIC2 != ((unsigned long *)((char *)ptr + size))[0]) {
+ /* Diagnostic */
+#ifdef FATALERRORS
+ FatalError("Xalloc error: Tail corrupt in Xfree() for big block (adr=0x%x, val=0x%x)\n",(char *)ptr+size,((unsigned long *)((char *)ptr + size))[0]);
+#else
+ ErrorF("Xalloc error: Tail corrupt in Xfree() for big block (adr=0x%x, val=0x%x)\n",(char *)ptr+size,((unsigned long *)((char *)ptr + size))[0]);
+#endif
+ LOG_FREE("Xalloc error: Tail corrupt in Xfree() for big block", ptr);
+ return;
+ }
+ size += SIZE_TAIL;
+#endif /* SIZE_TAIL */
+
+ LOG_FREE("Xfree", ptr);
+ size += SIZE_HEADER;
+ munmap((caddr_t)pheader, (size_t)size);
+ /* no need to clear - mem is inaccessible after munmap.. */
+#endif /* HAS_MMAP_ANON */
+
+ } else {
+ /*
+ * medium sized block
+ */
+#ifdef SIZE_TAIL
+ if (MAGIC2 != *(unsigned long *)((char *)ptr + size)) {
+ /* Diagnostic */
+#ifdef FATALERRORS
+ FatalError("Xalloc error: Tail corrupt in Xfree() for medium block (adr=0x%x, val=0x%x)\n",(char *)ptr + size,*(unsigned long *)((char *)ptr + size));
+#else
+ ErrorF("Xalloc error: Tail corrupt in Xfree() for medium block (adr=0x%x, val=0x%x)\n",(char *)ptr + size,*(unsigned long *)((char *)ptr + size));
+#endif
+ LOG_FREE("Xalloc error: Tail corrupt in Xfree() for medium block", ptr);
+ return;
+ }
+#endif /* SIZE_TAIL */
+
+#ifdef XFREE_ERASES
+ memset(pheader,0xF0,size+SIZE_HEADER);
+#endif /* XFREE_ERASES */
+#ifdef XALLOC_DEBUG
+ pheader[1] = MAGIC_FREE;
+#endif
+
+ LOG_FREE("Xfree", ptr);
+ free((char *)pheader);
+ }
+}
+
+void
+OsInitAllocator (void)
+{
+ static Bool beenhere = FALSE;
+
+ if (beenhere)
+ return;
+ beenhere = TRUE;
+
+#if defined(HAS_MMAP_ANON) || defined (MMAP_DEV_ZERO)
+ pagesize = -1;
+#if defined(_SC_PAGESIZE) || defined(HAS_SC_PAGESIZE)
+ pagesize = sysconf(_SC_PAGESIZE);
+#endif
+#ifdef _SC_PAGE_SIZE
+ if (pagesize == -1)
+ pagesize = sysconf(_SC_PAGE_SIZE);
+#endif
+#ifdef HAS_GETPAGESIZE
+ if (pagesize == -1)
+ pagesize = getpagesize();
+#endif
+#ifdef PAGE_SIZE
+ if (pagesize == -1)
+ pagesize = PAGE_SIZE;
+#endif
+ if (pagesize == -1)
+ FatalError("OsInitAllocator: Cannot determine page size\n");
+#endif
+
+ /* set up linked lists of free blocks */
+ bzero ((char *) free_lists, MAX_SMALL/SIZE_STEPS*sizeof(unsigned long *));
+
+#ifdef MMAP_DEV_ZERO
+ /* open /dev/zero on systems that have mmap, but not MAP_ANON */
+ if (devzerofd < 0) {
+ if ((devzerofd = open("/dev/zero", O_RDWR, 0)) < 0)
+ FatalError("OsInitAllocator: Cannot open /dev/zero (errno=%d)\n",
+ errno);
+ }
+#endif
+
+#ifdef XALLOC_LOG
+ /* reset the log file to zero length */
+ {
+ FILE *f;
+ f = fopen(XALLOC_LOG_FILE, "w");
+ if (NULL!=f)
+ fclose(f);
+ }
+#endif
+}
+
+#else /* !INTERNAL_MALLOC */
+/* This is to avoid an empty .o */
+static int no_internal_xalloc;
+#endif /* INTERNAL_MALLOC */
diff --git a/xc/programs/Xserver/os/xdmauth.c b/xc/programs/Xserver/os/xdmauth.c
new file mode 100644
index 000000000..8a6f93360
--- /dev/null
+++ b/xc/programs/Xserver/os/xdmauth.c
@@ -0,0 +1,514 @@
+/* $TOG: xdmauth.c /main/16 1998/02/09 15:13:11 kaleb $ */
+/*
+
+Copyright 1988, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+
+/*
+ * XDM-AUTHENTICATION-1 (XDMCP authentication) and
+ * XDM-AUTHORIZATION-1 (client authorization) protocols
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#include <stdio.h>
+#include "X.h"
+#include "Xtrans.h"
+#include "os.h"
+#include "osdep.h"
+#include "dixstruct.h"
+
+#ifdef HASXDMAUTH
+
+static Bool authFromXDMCP;
+
+#ifdef XDMCP
+#include "Xmd.h"
+#undef REQUEST
+#include "Xdmcp.h"
+
+/* XDM-AUTHENTICATION-1 */
+
+static XdmAuthKeyRec privateKey;
+static char XdmAuthenticationName[] = "XDM-AUTHENTICATION-1";
+#define XdmAuthenticationNameLen (sizeof XdmAuthenticationName - 1)
+static XdmAuthKeyRec rho;
+
+static Bool XdmAuthenticationValidator (privateData, incomingData, packet_type)
+ ARRAY8Ptr privateData, incomingData;
+ xdmOpCode packet_type;
+{
+ XdmAuthKeyPtr incoming;
+
+ XdmcpUnwrap (incomingData->data, &privateKey,
+ incomingData->data,incomingData->length);
+ switch (packet_type)
+ {
+ case ACCEPT:
+ if (incomingData->length != 8)
+ return FALSE;
+ incoming = (XdmAuthKeyPtr) incomingData->data;
+ XdmcpDecrementKey (incoming);
+ return XdmcpCompareKeys (incoming, &rho);
+ }
+ return FALSE;
+}
+
+static Bool
+XdmAuthenticationGenerator (privateData, outgoingData, packet_type)
+ ARRAY8Ptr privateData, outgoingData;
+ xdmOpCode packet_type;
+{
+ outgoingData->length = 0;
+ outgoingData->data = 0;
+ switch (packet_type)
+ {
+ case REQUEST:
+ if (XdmcpAllocARRAY8 (outgoingData, 8))
+ XdmcpWrap (&rho, &privateKey, outgoingData->data, 8);
+ }
+ return TRUE;
+}
+
+static Bool
+XdmAuthenticationAddAuth (name_len, name, data_len, data)
+ int name_len, data_len;
+ char *name, *data;
+{
+ Bool ret;
+ XdmcpUnwrap (data, &privateKey, data, data_len);
+ authFromXDMCP = TRUE;
+ ret = AddAuthorization (name_len, name, data_len, data);
+ authFromXDMCP = FALSE;
+ return ret;
+}
+
+
+#define atox(c) ('0' <= c && c <= '9' ? c - '0' : \
+ 'a' <= c && c <= 'f' ? c - 'a' + 10 : \
+ 'A' <= c && c <= 'F' ? c - 'A' + 10 : -1)
+
+static int
+HexToBinary (in, out, len)
+ char *out, *in;
+ int len;
+{
+ int top, bottom;
+
+ while (len > 0)
+ {
+ top = atox(in[0]);
+ if (top == -1)
+ return 0;
+ bottom = atox(in[1]);
+ if (bottom == -1)
+ return 0;
+ *out++ = (top << 4) | bottom;
+ in += 2;
+ len -= 2;
+ }
+ if (len)
+ return 0;
+ *out++ = '\0';
+ return 1;
+}
+
+void
+XdmAuthenticationInit (cookie, cookie_len)
+ char *cookie;
+ int cookie_len;
+{
+ bzero (privateKey.data, 8);
+ if (!strncmp (cookie, "0x", 2) || !strncmp (cookie, "0X", 2))
+ {
+ if (cookie_len > 2 + 2 * 8)
+ cookie_len = 2 + 2 * 8;
+ HexToBinary (cookie + 2, (char *)privateKey.data, cookie_len - 2);
+ }
+ else
+ {
+ if (cookie_len > 7)
+ cookie_len = 7;
+ memmove (privateKey.data + 1, cookie, cookie_len);
+ }
+ XdmcpGenerateKey (&rho);
+ XdmcpRegisterAuthentication (XdmAuthenticationName, XdmAuthenticationNameLen,
+ &rho,
+ sizeof (rho),
+ XdmAuthenticationValidator,
+ XdmAuthenticationGenerator,
+ XdmAuthenticationAddAuth);
+}
+
+#endif /* XDMCP */
+
+/* XDM-AUTHORIZATION-1 */
+typedef struct _XdmAuthorization {
+ struct _XdmAuthorization *next;
+ XdmAuthKeyRec rho;
+ XdmAuthKeyRec key;
+ XID id;
+} XdmAuthorizationRec, *XdmAuthorizationPtr;
+
+static XdmAuthorizationPtr xdmAuth;
+
+typedef struct _XdmClientAuth {
+ struct _XdmClientAuth *next;
+ XdmAuthKeyRec rho;
+ char client[6];
+ long time;
+} XdmClientAuthRec, *XdmClientAuthPtr;
+
+static XdmClientAuthPtr xdmClients;
+static long clockOffset;
+static Bool gotClock;
+
+#define TwentyMinutes (20 * 60)
+#define TwentyFiveMinutes (25 * 60)
+
+static Bool
+XdmClientAuthCompare (a, b)
+ XdmClientAuthPtr a, b;
+{
+ int i;
+
+ if (!XdmcpCompareKeys (&a->rho, &b->rho))
+ return FALSE;
+ for (i = 0; i < 6; i++)
+ if (a->client[i] != b->client[i])
+ return FALSE;
+ return a->time == b->time;
+}
+
+static void
+XdmClientAuthDecode (plain, auth)
+ unsigned char *plain;
+ XdmClientAuthPtr auth;
+{
+ int i, j;
+
+ j = 0;
+ for (i = 0; i < 8; i++)
+ {
+ auth->rho.data[i] = plain[j];
+ ++j;
+ }
+ for (i = 0; i < 6; i++)
+ {
+ auth->client[i] = plain[j];
+ ++j;
+ }
+ auth->time = 0;
+ for (i = 0; i < 4; i++)
+ {
+ auth->time |= plain[j] << ((3 - i) << 3);
+ j++;
+ }
+}
+
+static void
+XdmClientAuthTimeout (now)
+ long now;
+{
+ XdmClientAuthPtr client, next, prev;
+
+ prev = 0;
+ for (client = xdmClients; client; client=next)
+ {
+ next = client->next;
+ if (abs (now - client->time) > TwentyFiveMinutes)
+ {
+ if (prev)
+ prev->next = next;
+ else
+ xdmClients = next;
+ xfree (client);
+ }
+ else
+ prev = client;
+ }
+}
+
+static XdmClientAuthPtr
+XdmAuthorizationValidate (plain, length, rho, xclient, reason)
+ unsigned char *plain;
+ int length;
+ XdmAuthKeyPtr rho;
+ ClientPtr xclient;
+ char **reason;
+{
+ XdmClientAuthPtr client, existing;
+ long now;
+ int i;
+
+ if (length != (192 / 8)) {
+ if (reason)
+ *reason = "Bad XDM authorization key length";
+ return NULL;
+ }
+ client = (XdmClientAuthPtr) xalloc (sizeof (XdmClientAuthRec));
+ if (!client)
+ return NULL;
+ XdmClientAuthDecode (plain, client);
+ if (!XdmcpCompareKeys (&client->rho, rho))
+ {
+ xfree (client);
+ if (reason)
+ *reason = "Invalid XDM-AUTHORIZATION-1 key (failed key comparison)";
+ return NULL;
+ }
+ for (i = 18; i < 24; i++)
+ if (plain[i] != 0) {
+ xfree (client);
+ if (reason)
+ *reason = "Invalid XDM-AUTHORIZATION-1 key (failed NULL check)";
+ return NULL;
+ }
+ if (xclient) {
+ int family, addr_len;
+ Xtransaddr *addr;
+
+ if (_XSERVTransGetPeerAddr(((OsCommPtr)xclient->osPrivate)->trans_conn,
+ &family, &addr_len, &addr) == 0
+ && _XSERVTransConvertAddress(&family, &addr_len, &addr) == 0) {
+#if defined(TCPCONN) || defined(STREAMSCONN)
+ if (family == FamilyInternet &&
+ memcmp((char *)addr, client->client, 4) != 0) {
+ xfree (client);
+ xfree (addr);
+ if (reason)
+ *reason = "Invalid XDM-AUTHORIZATION-1 key (failed address comparison)";
+ return NULL;
+
+ }
+#endif
+ xfree (addr);
+ }
+ }
+ now = time(0);
+ if (!gotClock)
+ {
+ clockOffset = client->time - now;
+ gotClock = TRUE;
+ }
+ now += clockOffset;
+ XdmClientAuthTimeout (now);
+ if (abs (client->time - now) > TwentyMinutes)
+ {
+ xfree (client);
+ if (reason)
+ *reason = "Excessive XDM-AUTHORIZATION-1 time offset";
+ return NULL;
+ }
+ for (existing = xdmClients; existing; existing=existing->next)
+ {
+ if (XdmClientAuthCompare (existing, client))
+ {
+ xfree (client);
+ if (reason)
+ *reason = "XDM authorization key matches an existing client!";
+ return NULL;
+ }
+ }
+ return client;
+}
+
+int
+XdmAddCookie (data_length, data, id)
+unsigned short data_length;
+char *data;
+XID id;
+{
+ XdmAuthorizationPtr new;
+ unsigned char *rho_bits, *key_bits;
+
+ switch (data_length)
+ {
+ case 16: /* auth from files is 16 bytes long */
+ if (authFromXDMCP)
+ {
+ /* R5 xdm sent bogus authorization data in the accept packet,
+ * but we can recover */
+ rho_bits = rho.data;
+ key_bits = (unsigned char *) data;
+ key_bits[0] = '\0';
+ }
+ else
+ {
+ rho_bits = (unsigned char *) data;
+ key_bits = (unsigned char *) (data + 8);
+ }
+ break;
+ case 8: /* auth from XDMCP is 8 bytes long */
+ rho_bits = rho.data;
+ key_bits = (unsigned char *) data;
+ break;
+ default:
+ return 0;
+ }
+ /* the first octet of the key must be zero */
+ if (key_bits[0] != '\0')
+ return 0;
+ new = (XdmAuthorizationPtr) xalloc (sizeof (XdmAuthorizationRec));
+ if (!new)
+ return 0;
+ new->next = xdmAuth;
+ xdmAuth = new;
+ memmove (new->key.data, key_bits, (int) 8);
+ memmove (new->rho.data, rho_bits, (int) 8);
+ new->id = id;
+ return 1;
+}
+
+XID
+XdmCheckCookie (cookie_length, cookie, xclient, reason)
+ unsigned short cookie_length;
+ char *cookie;
+ ClientPtr xclient;
+ char **reason;
+{
+ XdmAuthorizationPtr auth;
+ XdmClientAuthPtr client;
+ unsigned char *plain;
+
+ /* Auth packets must be a multiple of 8 bytes long */
+ if (cookie_length & 7)
+ return (XID) -1;
+ plain = (unsigned char *) xalloc (cookie_length);
+ if (!plain)
+ return (XID) -1;
+ for (auth = xdmAuth; auth; auth=auth->next) {
+ XdmcpUnwrap (cookie, &auth->key, plain, cookie_length);
+ if (client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, xclient, reason))
+ {
+ client->next = xdmClients;
+ xdmClients = client;
+ xfree (plain);
+ return auth->id;
+ }
+ }
+ xfree (plain);
+ return (XID) -1;
+}
+
+int
+XdmResetCookie ()
+{
+ XdmAuthorizationPtr auth, next_auth;
+ XdmClientAuthPtr client, next_client;
+
+ for (auth = xdmAuth; auth; auth=next_auth)
+ {
+ next_auth = auth->next;
+ xfree (auth);
+ }
+ xdmAuth = 0;
+ for (client = xdmClients; client; client=next_client)
+ {
+ next_client = client->next;
+ xfree (client);
+ }
+ xdmClients = (XdmClientAuthPtr) 0;
+ return 1;
+}
+
+XID
+XdmToID (cookie_length, cookie)
+unsigned short cookie_length;
+char *cookie;
+{
+ XdmAuthorizationPtr auth;
+ XdmClientAuthPtr client;
+ unsigned char *plain;
+
+ plain = (unsigned char *) xalloc (cookie_length);
+ if (!plain)
+ return (XID) -1;
+ for (auth = xdmAuth; auth; auth=auth->next) {
+ XdmcpUnwrap (cookie, &auth->key, plain, cookie_length);
+ if (client = XdmAuthorizationValidate (plain, cookie_length, &auth->rho, NULL, NULL))
+ {
+ xfree (client);
+ xfree (cookie);
+ return auth->id;
+ }
+ }
+ xfree (cookie);
+ return (XID) -1;
+}
+
+int
+XdmFromID (id, data_lenp, datap)
+XID id;
+unsigned short *data_lenp;
+char **datap;
+{
+ XdmAuthorizationPtr auth;
+
+ for (auth = xdmAuth; auth; auth=auth->next) {
+ if (id == auth->id) {
+ *data_lenp = 16;
+ *datap = (char *) &auth->rho;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int
+XdmRemoveCookie (data_length, data)
+unsigned short data_length;
+char *data;
+{
+ XdmAuthorizationPtr auth, prev;
+ XdmAuthKeyPtr key_bits, rho_bits;
+
+ prev = 0;
+ switch (data_length)
+ {
+ case 16:
+ rho_bits = (XdmAuthKeyPtr) data;
+ key_bits = (XdmAuthKeyPtr) (data + 8);
+ break;
+ case 8:
+ rho_bits = &rho;
+ key_bits = (XdmAuthKeyPtr) data;
+ break;
+ default:
+ return 0;
+ }
+ for (auth = xdmAuth; auth; auth=auth->next) {
+ if (XdmcpCompareKeys (rho_bits, &auth->rho) &&
+ XdmcpCompareKeys (key_bits, &auth->key))
+ {
+ if (prev)
+ prev->next = auth->next;
+ else
+ xdmAuth = auth->next;
+ xfree (auth);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+#endif
diff --git a/xc/programs/Xserver/os/xdmcp.c b/xc/programs/Xserver/os/xdmcp.c
new file mode 100644
index 000000000..81c0512c2
--- /dev/null
+++ b/xc/programs/Xserver/os/xdmcp.c
@@ -0,0 +1,1546 @@
+/* $XConsortium: xdmcp.c /main/34 1996/12/02 10:23:29 lehors $ */
+/* $XFree86: xc/programs/Xserver/os/xdmcp.c,v 3.12 1999/02/24 03:21:58 dawes Exp $ */
+/*
+ * Copyright 1989 Network Computing Devices, Inc., Mountain View, California.
+ *
+ * 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 N.C.D. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. N.C.D. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ */
+
+#ifdef WIN32
+/* avoid conflicting definitions */
+#define BOOL wBOOL
+#define ATOM wATOM
+#define FreeResource wFreeResource
+#include <winsock.h>
+#undef BOOL
+#undef ATOM
+#undef FreeResource
+#undef CreateWindowA
+#undef RT_FONT
+#undef RT_CURSOR
+#endif
+
+#include "Xos.h"
+
+#if !defined(MINIX) && !defined(WIN32)
+#ifndef Lynx
+#include <sys/param.h>
+#include <sys/socket.h>
+#else
+#include <socket.h>
+#endif
+#include <netinet/in.h>
+#include <netdb.h>
+#else
+#if defined(MINIX)
+#include <net/hton.h>
+#include <net/netlib.h>
+#include <net/gen/netdb.h>
+#include <net/gen/udp.h>
+#include <net/gen/udp_io.h>
+#include <sys/nbio.h>
+#include <sys/ioctl.h>
+#endif
+#endif
+#include <stdio.h>
+#include "X.h"
+#include "Xmd.h"
+#include "misc.h"
+#include "Xpoll.h"
+#include "osdep.h"
+#include "input.h"
+#include "dixstruct.h"
+#include "opaque.h"
+
+#if defined(DGUX)
+#include <net/net_ioctl.h>
+#include <sys/ioctl.h>
+#endif
+
+#ifdef STREAMSCONN
+#include <tiuser.h>
+#include <netconfig.h>
+#include <netdir.h>
+#endif
+
+#ifdef XDMCP
+#undef REQUEST
+#include "Xdmcp.h"
+
+extern char *display;
+extern fd_set EnabledDevices;
+extern fd_set AllClients;
+extern char *defaultDisplayClass;
+
+static int xdmcpSocket, sessionSocket;
+static xdmcp_states state;
+static struct sockaddr_in req_sockaddr;
+static int req_socklen;
+static CARD32 SessionID;
+static CARD32 timeOutTime;
+static int timeOutRtx;
+static CARD32 defaultKeepaliveDormancy = XDM_DEF_DORMANCY;
+static CARD32 keepaliveDormancy = XDM_DEF_DORMANCY;
+static CARD16 DisplayNumber;
+static xdmcp_states XDM_INIT_STATE = XDM_OFF;
+#ifdef HASXDMAUTH
+static char *xdmAuthCookie;
+#endif
+
+static XdmcpBuffer buffer;
+
+static struct sockaddr_in ManagerAddress;
+static struct sockaddr_in FromAddress;
+
+static void XdmcpAddHost(
+ struct sockaddr_in *from,
+ int fromlen,
+ ARRAY8Ptr AuthenticationName,
+ ARRAY8Ptr hostname,
+ ARRAY8Ptr status);
+
+static void XdmcpSelectHost(
+ struct sockaddr_in *host_sockaddr,
+ int host_len,
+ ARRAY8Ptr AuthenticationName);
+
+static void get_xdmcp_sock(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+static void send_query_msg(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+static void recv_willing_msg(
+#if NeedFunctionPrototypes
+ struct sockaddr_in */*from*/,
+ int /*fromlen*/,
+ unsigned /*length*/
+#endif
+);
+
+static void send_request_msg(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+static void recv_accept_msg(
+#if NeedFunctionPrototypes
+ unsigned /*length*/
+#endif
+);
+
+static void recv_decline_msg(
+#if NeedFunctionPrototypes
+ unsigned /*length*/
+#endif
+);
+
+static void send_manage_msg(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+static void recv_refuse_msg(
+#if NeedFunctionPrototypes
+ unsigned /*length*/
+#endif
+);
+
+static void recv_failed_msg(
+#if NeedFunctionPrototypes
+ unsigned /*length*/
+#endif
+);
+
+static void send_keepalive_msg(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+static void recv_alive_msg(
+#if NeedFunctionPrototypes
+ unsigned /*length*/
+#endif
+);
+
+static void XdmcpFatal(
+#if NeedFunctionPrototypes
+ char */*type*/,
+ ARRAY8Ptr /*status*/
+#endif
+);
+
+static void XdmcpWarning(
+#if NeedFunctionPrototypes
+ char */*str*/
+#endif
+);
+
+static void get_manager_by_name(
+#if NeedFunctionPrototypes
+ int /*argc*/,
+ char **/*argv*/,
+ int /*i*/
+#endif
+);
+
+static void get_fromaddr_by_name(int /*argc*/, char **/*argv*/, int /*i*/);
+
+static void receive_packet(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+static void send_packet(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+extern void XdmcpDeadSession(
+#if NeedFunctionPrototypes
+ char */*reason*/
+#endif
+);
+
+static void timeout(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+static void restart(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+static void XdmcpBlockHandler(
+#if NeedFunctionPrototypes
+ pointer /*data*/,
+ struct timeval **/*wt*/,
+ pointer /*LastSelectMask*/
+#endif
+);
+
+static void XdmcpWakeupHandler(
+#if NeedFunctionPrototypes
+ pointer /*data*/,
+ int /*i*/,
+ pointer /*LastSelectMask*/
+#endif
+);
+
+void XdmcpRegisterManufacturerDisplayID(
+#if NeedFunctionPrototypes
+ char * /*name*/,
+ int /*length*/
+#endif
+);
+
+#ifdef MINIX
+static void read_cb(
+#if NeedFunctionPrototypes
+ nbio_ref_t /*ref*/,
+ int /*res*/,
+ int /*err*/
+#endif
+);
+#endif
+
+static short xdm_udp_port = XDM_UDP_PORT;
+static Bool OneSession = FALSE;
+static const char *xdm_from = NULL;
+
+void
+XdmcpUseMsg (void)
+{
+ ErrorF("-query host-name contact named host for XDMCP\n");
+ ErrorF("-broadcast broadcast for XDMCP\n");
+ ErrorF("-indirect host-name contact named host for indirect XDMCP\n");
+ ErrorF("-port port-num UDP port number to send messages to\n");
+ ErrorF("-from local-address specify the local address to connect from\n");
+ ErrorF("-once Terminate server after one session\n");
+ ErrorF("-class display-class specify display class to send in manage\n");
+#ifdef HASXDMAUTH
+ ErrorF("-cookie xdm-auth-bits specify the magic cookie for XDMCP\n");
+#endif
+ ErrorF("-displayID display-id manufacturer display ID for request\n");
+}
+
+int
+XdmcpOptions(int argc, char **argv, int i)
+{
+ if (strcmp(argv[i], "-query") == 0) {
+ get_manager_by_name(argc, argv, ++i);
+ XDM_INIT_STATE = XDM_QUERY;
+ AccessUsingXdmcp ();
+ return (i + 1);
+ }
+ if (strcmp(argv[i], "-broadcast") == 0) {
+ XDM_INIT_STATE = XDM_BROADCAST;
+ AccessUsingXdmcp ();
+ return (i + 1);
+ }
+ if (strcmp(argv[i], "-indirect") == 0) {
+ get_manager_by_name(argc, argv, ++i);
+ XDM_INIT_STATE = XDM_INDIRECT;
+ AccessUsingXdmcp ();
+ return (i + 1);
+ }
+ if (strcmp(argv[i], "-port") == 0) {
+ ++i;
+ xdm_udp_port = atoi(argv[i]);
+ return (i + 1);
+ }
+ if (strcmp(argv[i], "-from") == 0) {
+ get_fromaddr_by_name(argc, argv, ++i);
+ return (i + 1);
+ }
+ if (strcmp(argv[i], "-once") == 0) {
+ OneSession = TRUE;
+ return (i + 1);
+ }
+ if (strcmp(argv[i], "-class") == 0) {
+ ++i;
+ defaultDisplayClass = argv[i];
+ return (i + 1);
+ }
+#ifdef HASXDMAUTH
+ if (strcmp(argv[i], "-cookie") == 0) {
+ ++i;
+ xdmAuthCookie = argv[i];
+ return (i + 1);
+ }
+#endif
+ if (strcmp(argv[i], "-displayID") == 0) {
+ ++i;
+ XdmcpRegisterManufacturerDisplayID (argv[i], strlen (argv[i]));
+ return (i + 1);
+ }
+ return (i);
+}
+
+/*
+ * This section is a collection of routines for
+ * registering server-specific data with the XDMCP
+ * state machine.
+ */
+
+
+/*
+ * Save all broadcast addresses away so BroadcastQuery
+ * packets get sent everywhere
+ */
+
+#define MAX_BROADCAST 10
+
+static struct sockaddr_in BroadcastAddresses[MAX_BROADCAST];
+static int NumBroadcastAddresses;
+
+void
+XdmcpRegisterBroadcastAddress (struct sockaddr_in *addr)
+{
+ struct sockaddr_in *bcast;
+ if (NumBroadcastAddresses >= MAX_BROADCAST)
+ return;
+ bcast = &BroadcastAddresses[NumBroadcastAddresses++];
+ bzero (bcast, sizeof (struct sockaddr_in));
+#ifdef BSD44SOCKETS
+ bcast->sin_len = addr->sin_len;
+#endif
+ bcast->sin_family = addr->sin_family;
+ bcast->sin_port = htons (xdm_udp_port);
+ bcast->sin_addr = addr->sin_addr;
+}
+
+/*
+ * Each authentication type is registered here; Validator
+ * will be called to check all access attempts using
+ * the specified authentication type
+ */
+
+static ARRAYofARRAY8 AuthenticationNames, AuthenticationDatas;
+typedef struct _AuthenticationFuncs {
+ ValidatorFunc Validator;
+ GeneratorFunc Generator;
+ AddAuthorFunc AddAuth;
+} AuthenticationFuncsRec, *AuthenticationFuncsPtr;
+
+static AuthenticationFuncsPtr AuthenticationFuncsList;
+
+void
+XdmcpRegisterAuthentication (
+ char *name,
+ int namelen,
+ char *data,
+ int datalen,
+ ValidatorFunc Validator,
+ GeneratorFunc Generator,
+ AddAuthorFunc AddAuth)
+{
+ int i;
+ ARRAY8 AuthenticationName, AuthenticationData;
+ static AuthenticationFuncsPtr newFuncs;
+
+ if (!XdmcpAllocARRAY8 (&AuthenticationName, namelen))
+ return;
+ if (!XdmcpAllocARRAY8 (&AuthenticationData, datalen))
+ {
+ XdmcpDisposeARRAY8 (&AuthenticationName);
+ return;
+ }
+ for (i = 0; i < namelen; i++)
+ AuthenticationName.data[i] = name[i];
+ for (i = 0; i < datalen; i++)
+ AuthenticationData.data[i] = data[i];
+ if (!(XdmcpReallocARRAYofARRAY8 (&AuthenticationNames,
+ AuthenticationNames.length + 1) &&
+ XdmcpReallocARRAYofARRAY8 (&AuthenticationDatas,
+ AuthenticationDatas.length + 1) &&
+ (newFuncs = (AuthenticationFuncsPtr) xalloc (
+ (AuthenticationNames.length + 1) * sizeof (AuthenticationFuncsRec)))))
+ {
+ XdmcpDisposeARRAY8 (&AuthenticationName);
+ XdmcpDisposeARRAY8 (&AuthenticationData);
+ return;
+ }
+ for (i = 0; i < AuthenticationNames.length - 1; i++)
+ newFuncs[i] = AuthenticationFuncsList[i];
+ newFuncs[AuthenticationNames.length-1].Validator = Validator;
+ newFuncs[AuthenticationNames.length-1].Generator = Generator;
+ newFuncs[AuthenticationNames.length-1].AddAuth = AddAuth;
+ xfree (AuthenticationFuncsList);
+ AuthenticationFuncsList = newFuncs;
+ AuthenticationNames.data[AuthenticationNames.length-1] = AuthenticationName;
+ AuthenticationDatas.data[AuthenticationDatas.length-1] = AuthenticationData;
+}
+
+/*
+ * Select the authentication type to be used; this is
+ * set by the manager of the host to be connected to.
+ */
+
+ARRAY8 noAuthenticationName = {(CARD16) 0, (CARD8Ptr) 0};
+ARRAY8 noAuthenticationData = {(CARD16) 0, (CARD8Ptr) 0};
+ARRAY8Ptr AuthenticationName = &noAuthenticationName;
+ARRAY8Ptr AuthenticationData = &noAuthenticationData;
+AuthenticationFuncsPtr AuthenticationFuncs;
+
+void
+XdmcpSetAuthentication (ARRAY8Ptr name)
+{
+ int i;
+
+ for (i = 0; i < AuthenticationNames.length; i++)
+ if (XdmcpARRAY8Equal (&AuthenticationNames.data[i], name))
+ {
+ AuthenticationName = &AuthenticationNames.data[i];
+ AuthenticationData = &AuthenticationDatas.data[i];
+ AuthenticationFuncs = &AuthenticationFuncsList[i];
+ break;
+ }
+}
+
+/*
+ * Register the host address for the display
+ */
+
+static ARRAY16 ConnectionTypes;
+static ARRAYofARRAY8 ConnectionAddresses;
+static long xdmcpGeneration;
+
+void
+XdmcpRegisterConnection (
+ int type,
+ char *address,
+ int addrlen)
+{
+ int i;
+ CARD8 *newAddress;
+
+ if (xdmcpGeneration != serverGeneration)
+ {
+ XdmcpDisposeARRAY16 (&ConnectionTypes);
+ XdmcpDisposeARRAYofARRAY8 (&ConnectionAddresses);
+ xdmcpGeneration = serverGeneration;
+ }
+ if (addrlen == sizeof(struct in_addr) && xdm_from != NULL)
+ {
+ /* Only register the requested address */
+ if (memcmp(address, &FromAddress.sin_addr, addrlen) != 0) {
+ return;
+ }
+ }
+ newAddress = (CARD8 *) xalloc (addrlen * sizeof (CARD8));
+ if (!newAddress)
+ return;
+ if (!XdmcpReallocARRAY16 (&ConnectionTypes, ConnectionTypes.length + 1))
+ {
+ xfree (newAddress);
+ return;
+ }
+ if (!XdmcpReallocARRAYofARRAY8 (&ConnectionAddresses,
+ ConnectionAddresses.length + 1))
+ {
+ xfree (newAddress);
+ return;
+ }
+ ConnectionTypes.data[ConnectionTypes.length - 1] = (CARD16) type;
+ for (i = 0; i < addrlen; i++)
+ newAddress[i] = address[i];
+ ConnectionAddresses.data[ConnectionAddresses.length-1].data = newAddress;
+ ConnectionAddresses.data[ConnectionAddresses.length-1].length = addrlen;
+}
+
+/*
+ * Register an Authorization Name. XDMCP advertises this list
+ * to the manager.
+ */
+
+static ARRAYofARRAY8 AuthorizationNames;
+
+void
+XdmcpRegisterAuthorizations (void)
+{
+ XdmcpDisposeARRAYofARRAY8 (&AuthorizationNames);
+ RegisterAuthorizations ();
+}
+
+void
+XdmcpRegisterAuthorization (char *name, int namelen)
+{
+ ARRAY8 authName;
+ int i;
+
+ authName.data = (CARD8 *) xalloc (namelen * sizeof (CARD8));
+ if (!authName.data)
+ return;
+ if (!XdmcpReallocARRAYofARRAY8 (&AuthorizationNames, AuthorizationNames.length +1))
+ {
+ xfree (authName.data);
+ return;
+ }
+ for (i = 0; i < namelen; i++)
+ authName.data[i] = (CARD8) name[i];
+ authName.length = namelen;
+ AuthorizationNames.data[AuthorizationNames.length-1] = authName;
+}
+
+/*
+ * Register the DisplayClass string
+ */
+
+ARRAY8 DisplayClass;
+
+void
+XdmcpRegisterDisplayClass (char *name, int length)
+{
+ int i;
+
+ XdmcpDisposeARRAY8 (&DisplayClass);
+ if (!XdmcpAllocARRAY8 (&DisplayClass, length))
+ return;
+ for (i = 0; i < length; i++)
+ DisplayClass.data[i] = (CARD8) name[i];
+}
+
+/*
+ * Register the Manufacturer display ID
+ */
+
+ARRAY8 ManufacturerDisplayID;
+
+void
+XdmcpRegisterManufacturerDisplayID (char *name, int length)
+{
+ int i;
+
+ XdmcpDisposeARRAY8 (&ManufacturerDisplayID);
+ if (!XdmcpAllocARRAY8 (&ManufacturerDisplayID, length))
+ return;
+ for (i = 0; i < length; i++)
+ ManufacturerDisplayID.data[i] = (CARD8) name[i];
+}
+
+/*
+ * initialize XDMCP; create the socket, compute the display
+ * number, set up the state machine
+ */
+
+void
+XdmcpInit(void)
+{
+ state = XDM_INIT_STATE;
+#ifdef HASXDMAUTH
+ if (xdmAuthCookie)
+ XdmAuthenticationInit (xdmAuthCookie, strlen (xdmAuthCookie));
+#endif
+ if (state != XDM_OFF)
+ {
+ XdmcpRegisterAuthorizations();
+ XdmcpRegisterDisplayClass (defaultDisplayClass, strlen (defaultDisplayClass));
+ AccessUsingXdmcp();
+ RegisterBlockAndWakeupHandlers (XdmcpBlockHandler, XdmcpWakeupHandler,
+ (pointer) 0);
+ timeOutRtx = 0;
+ DisplayNumber = (CARD16) atoi(display);
+ get_xdmcp_sock();
+ send_packet();
+ }
+}
+
+void
+XdmcpReset (void)
+{
+ state = XDM_INIT_STATE;
+ if (state != XDM_OFF)
+ {
+ RegisterBlockAndWakeupHandlers (XdmcpBlockHandler, XdmcpWakeupHandler,
+ (pointer) 0);
+ timeOutRtx = 0;
+ send_packet();
+ }
+}
+
+/*
+ * Called whenever a new connection is created; notices the
+ * first connection and saves it to terminate the session
+ * when it is closed
+ */
+
+void
+XdmcpOpenDisplay(int sock)
+{
+ if (state != XDM_AWAIT_MANAGE_RESPONSE)
+ return;
+ state = XDM_RUN_SESSION;
+ sessionSocket = sock;
+}
+
+void
+XdmcpCloseDisplay(int sock)
+{
+ if ((state != XDM_RUN_SESSION && state != XDM_AWAIT_ALIVE_RESPONSE)
+ || sessionSocket != sock)
+ return;
+ state = XDM_INIT_STATE;
+ if (OneSession)
+ dispatchException |= DE_TERMINATE;
+ else
+ dispatchException |= DE_RESET;
+ isItTimeToYield = TRUE;
+}
+
+/*
+ * called before going to sleep, this routine
+ * may modify the timeout value about to be sent
+ * to select; in this way XDMCP can do appropriate things
+ * dynamically while starting up
+ */
+
+/*ARGSUSED*/
+static void
+XdmcpBlockHandler(
+ pointer data, /* unused */
+ struct timeval **wt,
+ pointer pReadmask)
+{
+ fd_set *LastSelectMask = (fd_set*)pReadmask;
+ CARD32 millisToGo, wtMillis;
+ static struct timeval waittime;
+
+ if (state == XDM_OFF)
+ return;
+ FD_SET(xdmcpSocket, LastSelectMask);
+ if (timeOutTime == 0)
+ return;
+ millisToGo = GetTimeInMillis();
+ if (millisToGo < timeOutTime)
+ millisToGo = timeOutTime - millisToGo;
+ else
+ millisToGo = 0;
+ if (*wt == NULL)
+ {
+ waittime.tv_sec = (millisToGo) / 1000;
+ waittime.tv_usec = 1000 * (millisToGo % 1000);
+ *wt = &waittime;
+ }
+ else
+ {
+ wtMillis = (*wt)->tv_sec * 1000 + (*wt)->tv_usec / 1000;
+ if (millisToGo < wtMillis)
+ {
+ (*wt)->tv_sec = (millisToGo) / 1000;
+ (*wt)->tv_usec = 1000 * (millisToGo % 1000);
+ }
+ }
+}
+
+/*
+ * called after select returns; this routine will
+ * recognise when XDMCP packets await and
+ * process them appropriately
+ */
+
+/*ARGSUSED*/
+static void
+XdmcpWakeupHandler(
+ pointer data, /* unused */
+ int i,
+ pointer pReadmask)
+{
+ fd_set* LastSelectMask = (fd_set*)pReadmask;
+ fd_set devicesReadable;
+
+ if (state == XDM_OFF)
+ return;
+ if (i > 0)
+ {
+ if (FD_ISSET(xdmcpSocket, LastSelectMask))
+ {
+ receive_packet();
+ FD_CLR(xdmcpSocket, LastSelectMask);
+ }
+ XFD_ANDSET(&devicesReadable, LastSelectMask, &EnabledDevices);
+ if (XFD_ANYSET(&devicesReadable))
+ {
+ if (state == XDM_AWAIT_USER_INPUT)
+ restart();
+ else if (state == XDM_RUN_SESSION)
+ keepaliveDormancy = defaultKeepaliveDormancy;
+ }
+ if (XFD_ANYSET(&AllClients) && state == XDM_RUN_SESSION)
+ timeOutTime = GetTimeInMillis() + keepaliveDormancy * 1000;
+ }
+ else if (timeOutTime && GetTimeInMillis() >= timeOutTime)
+ {
+ if (state == XDM_RUN_SESSION)
+ {
+ state = XDM_KEEPALIVE;
+ send_packet();
+ }
+ else
+ timeout();
+ }
+}
+
+/*
+ * This routine should be called from the routine that drives the
+ * user's host menu when the user selects a host
+ */
+
+static void
+XdmcpSelectHost(
+ struct sockaddr_in *host_sockaddr,
+ int host_len,
+ ARRAY8Ptr AuthenticationName)
+{
+ state = XDM_START_CONNECTION;
+ memmove(&req_sockaddr, host_sockaddr, host_len);
+ req_socklen = host_len;
+ XdmcpSetAuthentication (AuthenticationName);
+ send_packet();
+}
+
+/*
+ * !!! this routine should be replaced by a routine that adds
+ * the host to the user's host menu. the current version just
+ * selects the first host to respond with willing message.
+ */
+
+/*ARGSUSED*/
+static void
+XdmcpAddHost(
+ struct sockaddr_in *from,
+ int fromlen,
+ ARRAY8Ptr AuthenticationName,
+ ARRAY8Ptr hostname,
+ ARRAY8Ptr status)
+{
+ XdmcpSelectHost(from, fromlen, AuthenticationName);
+}
+
+/*
+ * A message is queued on the socket; read it and
+ * do the appropriate thing
+ */
+
+ARRAY8 UnwillingMessage = { (CARD8) 14, (CARD8 *) "Host unwilling" };
+
+static void
+receive_packet(void)
+{
+ struct sockaddr_in from;
+ int fromlen = sizeof(struct sockaddr_in);
+ XdmcpHeader header;
+
+ /* read message off socket */
+ if (!XdmcpFill (xdmcpSocket, &buffer, (XdmcpNetaddr) &from, &fromlen))
+ return;
+
+ /* reset retransmission backoff */
+ timeOutRtx = 0;
+
+ if (!XdmcpReadHeader (&buffer, &header))
+ return;
+
+ if (header.version != XDM_PROTOCOL_VERSION)
+ return;
+
+ switch (header.opcode) {
+ case WILLING:
+ recv_willing_msg(&from, fromlen, header.length);
+ break;
+ case UNWILLING:
+ XdmcpFatal("Manager unwilling", &UnwillingMessage);
+ break;
+ case ACCEPT:
+ recv_accept_msg(header.length);
+ break;
+ case DECLINE:
+ recv_decline_msg(header.length);
+ break;
+ case REFUSE:
+ recv_refuse_msg(header.length);
+ break;
+ case FAILED:
+ recv_failed_msg(header.length);
+ break;
+ case ALIVE:
+ recv_alive_msg(header.length);
+ break;
+ }
+}
+
+/*
+ * send the appropriate message given the current state
+ */
+
+static void
+send_packet(void)
+{
+ int rtx;
+ switch (state) {
+ case XDM_QUERY:
+ case XDM_BROADCAST:
+ case XDM_INDIRECT:
+ send_query_msg();
+ break;
+ case XDM_START_CONNECTION:
+ send_request_msg();
+ break;
+ case XDM_MANAGE:
+ send_manage_msg();
+ break;
+ case XDM_KEEPALIVE:
+ send_keepalive_msg();
+ break;
+ default:
+ break;
+ }
+ rtx = (XDM_MIN_RTX << timeOutRtx);
+ if (rtx > XDM_MAX_RTX)
+ rtx = XDM_MAX_RTX;
+ timeOutTime = GetTimeInMillis() + rtx * 1000;
+}
+
+/*
+ * The session is declared dead for some reason; too many
+ * timeouts, or Keepalive failure.
+ */
+
+void
+XdmcpDeadSession (char *reason)
+{
+ ErrorF ("XDM: %s, declaring session dead\n", reason);
+ state = XDM_INIT_STATE;
+ isItTimeToYield = TRUE;
+ dispatchException |= DE_RESET;
+ timeOutTime = 0;
+ timeOutRtx = 0;
+ send_packet();
+}
+
+/*
+ * Timeout waiting for an XDMCP response.
+ */
+
+static void
+timeout(void)
+{
+ timeOutRtx++;
+ if (state == XDM_AWAIT_ALIVE_RESPONSE && timeOutRtx >= XDM_KA_RTX_LIMIT )
+ {
+ XdmcpDeadSession ("too many keepalive retransmissions");
+ return;
+ }
+ else if (timeOutRtx >= XDM_RTX_LIMIT)
+ {
+ ErrorF("XDM: too many retransmissions\n");
+ state = XDM_AWAIT_USER_INPUT;
+ timeOutTime = 0;
+ timeOutRtx = 0;
+ return;
+ }
+
+ switch (state) {
+ case XDM_COLLECT_QUERY:
+ state = XDM_QUERY;
+ break;
+ case XDM_COLLECT_BROADCAST_QUERY:
+ state = XDM_BROADCAST;
+ break;
+ case XDM_COLLECT_INDIRECT_QUERY:
+ state = XDM_INDIRECT;
+ break;
+ case XDM_AWAIT_REQUEST_RESPONSE:
+ state = XDM_START_CONNECTION;
+ break;
+ case XDM_AWAIT_MANAGE_RESPONSE:
+ state = XDM_MANAGE;
+ break;
+ case XDM_AWAIT_ALIVE_RESPONSE:
+ state = XDM_KEEPALIVE;
+ break;
+ default:
+ break;
+ }
+ send_packet();
+}
+
+static void
+restart(void)
+{
+ state = XDM_INIT_STATE;
+ timeOutRtx = 0;
+ send_packet();
+}
+
+int
+XdmcpCheckAuthentication (
+ ARRAY8Ptr Name,
+ ARRAY8Ptr Data,
+ int packet_type)
+{
+ return (XdmcpARRAY8Equal (Name, AuthenticationName) &&
+ (AuthenticationName->length == 0 ||
+ (*AuthenticationFuncs->Validator) (AuthenticationData, Data, packet_type)));
+}
+
+int
+XdmcpAddAuthorization (
+ ARRAY8Ptr name,
+ ARRAY8Ptr data)
+{
+ AddAuthorFunc AddAuth;
+
+ if (AuthenticationFuncs && AuthenticationFuncs->AddAuth)
+ AddAuth = AuthenticationFuncs->AddAuth;
+ else
+ AddAuth = AddAuthorization;
+ return (*AddAuth) ((unsigned short)name->length,
+ (char *)name->data,
+ (unsigned short)data->length,
+ (char *)data->data);
+}
+
+/*
+ * from here to the end of this file are routines private
+ * to the state machine.
+ */
+
+static void
+get_xdmcp_sock(void)
+{
+#ifdef STREAMSCONN
+ struct netconfig *nconf;
+
+ if ((xdmcpSocket = t_open("/dev/udp", O_RDWR, 0)) < 0) {
+ XdmcpWarning("t_open() of /dev/udp failed");
+ return;
+ }
+
+ if( t_bind(xdmcpSocket,NULL,NULL) < 0 ) {
+ XdmcpWarning("UDP socket creation failed");
+ t_error("t_bind(xdmcpSocket) failed" );
+ t_close(xdmcpSocket);
+ return;
+ }
+
+ /*
+ * This part of the code looks contrived. It will actually fit in nicely
+ * when the CLTS part of Xtrans is implemented.
+ */
+
+ if( (nconf=getnetconfigent("udp")) == NULL ) {
+ XdmcpWarning("UDP socket creation failed: getnetconfigent()");
+ t_unbind(xdmcpSocket);
+ t_close(xdmcpSocket);
+ return;
+ }
+
+ if( netdir_options(nconf, ND_SET_BROADCAST, xdmcpSocket, NULL) ) {
+ XdmcpWarning("UDP set broadcast option failed: netdir_options()");
+ freenetconfigent(nconf);
+ t_unbind(xdmcpSocket);
+ t_close(xdmcpSocket);
+ return;
+ }
+
+ freenetconfigent(nconf);
+#else
+#ifndef _MINIX
+ int soopts = 1;
+
+ if ((xdmcpSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+#else /* MINIX */
+ char *udp_device;
+ int r, s_errno;
+ nwio_udpopt_t udpopt;
+ nbio_ref_t ref;
+
+ udp_device= getenv("UDP_DEVICE");
+ if (udp_device == NULL)
+ udp_device= UDP_DEVICE;
+ xdmcpSocket= open(udp_device, O_RDWR);
+ if (xdmcpSocket != -1)
+ {
+ udpopt.nwuo_flags= NWUO_COPY | NWUO_LP_SEL | NWUO_EN_LOC |
+ NWUO_DI_BROAD | NWUO_RP_ANY | NWUO_RA_ANY | NWUO_RWDATALL |
+ NWUO_DI_IPOPT;
+ r= ioctl(xdmcpSocket, NWIOSUDPOPT, &udpopt);
+ if (r == -1)
+ {
+ s_errno= errno;
+ close(xdmcpSocket);
+ xdmcpSocket= -1;
+ errno= s_errno;
+ }
+ ioctl(xdmcpSocket, NWIOGUDPOPT, &udpopt);
+ ErrorF("0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
+ udpopt.nwuo_flags,
+ udpopt.nwuo_locport,
+ udpopt.nwuo_remport,
+ udpopt.nwuo_locaddr,
+ udpopt.nwuo_remaddr);
+ }
+ if (xdmcpSocket != -1)
+ {
+ fcntl(xdmcpSocket, F_SETFD, fcntl(xdmcpSocket, F_GETFD) |
+ FD_ASYNCHIO);
+ nbio_register(xdmcpSocket);
+ ref.ref_int= xdmcpSocket;
+ nbio_setcallback(xdmcpSocket, ASIO_READ, read_cb, ref);
+ }
+ if (xdmcpSocket == -1)
+#endif /* !MINIX */
+ XdmcpWarning("UDP socket creation failed");
+#ifdef SO_BROADCAST
+ else if (setsockopt(xdmcpSocket, SOL_SOCKET, SO_BROADCAST, (char *)&soopts,
+ sizeof(soopts)) < 0)
+ XdmcpWarning("UDP set broadcast socket-option failed");
+#endif /* SO_BROADCAST */
+ if (xdmcpSocket >= 0 && xdm_from != NULL) {
+ if (bind(xdmcpSocket, (struct sockaddr *)&FromAddress,
+ sizeof(FromAddress)) < 0) {
+ ErrorF("Xserver: failed to bind to -from address: %s\n", xdm_from);
+ exit(1);
+ }
+ }
+#endif /* STREAMSCONN */
+}
+
+static void
+send_query_msg(void)
+{
+ XdmcpHeader header;
+ Bool broadcast = FALSE;
+ int i;
+
+ header.version = XDM_PROTOCOL_VERSION;
+ switch(state){
+ case XDM_QUERY:
+ header.opcode = (CARD16) QUERY;
+ state = XDM_COLLECT_QUERY;
+ break;
+ case XDM_BROADCAST:
+ header.opcode = (CARD16) BROADCAST_QUERY;
+ state = XDM_COLLECT_BROADCAST_QUERY;
+ broadcast = TRUE;
+ break;
+ case XDM_INDIRECT:
+ header.opcode = (CARD16) INDIRECT_QUERY;
+ state = XDM_COLLECT_INDIRECT_QUERY;
+ break;
+ default:
+ break;
+ }
+ header.length = 1;
+ for (i = 0; i < AuthenticationNames.length; i++)
+ header.length += 2 + AuthenticationNames.data[i].length;
+
+ XdmcpWriteHeader (&buffer, &header);
+ XdmcpWriteARRAYofARRAY8 (&buffer, &AuthenticationNames);
+ if (broadcast)
+ {
+ int i;
+
+ for (i = 0; i < NumBroadcastAddresses; i++)
+ XdmcpFlush (xdmcpSocket, &buffer, (XdmcpNetaddr) &BroadcastAddresses[i],
+ sizeof (struct sockaddr_in));
+ }
+ else
+ {
+ XdmcpFlush (xdmcpSocket, &buffer, (XdmcpNetaddr) &ManagerAddress,
+ sizeof (ManagerAddress));
+ }
+}
+
+static void
+recv_willing_msg(
+ struct sockaddr_in *from,
+ int fromlen,
+ unsigned length)
+{
+ ARRAY8 authenticationName;
+ ARRAY8 hostname;
+ ARRAY8 status;
+
+ authenticationName.data = 0;
+ hostname.data = 0;
+ status.data = 0;
+ if (XdmcpReadARRAY8 (&buffer, &authenticationName) &&
+ XdmcpReadARRAY8 (&buffer, &hostname) &&
+ XdmcpReadARRAY8 (&buffer, &status))
+ {
+ if (length == 6 + authenticationName.length +
+ hostname.length + status.length)
+ {
+ switch (state)
+ {
+ case XDM_COLLECT_QUERY:
+ XdmcpSelectHost(from, fromlen, &authenticationName);
+ break;
+ case XDM_COLLECT_BROADCAST_QUERY:
+ case XDM_COLLECT_INDIRECT_QUERY:
+ XdmcpAddHost(from, fromlen, &authenticationName, &hostname, &status);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ XdmcpDisposeARRAY8 (&authenticationName);
+ XdmcpDisposeARRAY8 (&hostname);
+ XdmcpDisposeARRAY8 (&status);
+}
+
+static void
+send_request_msg(void)
+{
+ XdmcpHeader header;
+ int length;
+ int i;
+ ARRAY8 authenticationData;
+
+ header.version = XDM_PROTOCOL_VERSION;
+ header.opcode = (CARD16) REQUEST;
+
+ length = 2; /* display number */
+ length += 1 + 2 * ConnectionTypes.length; /* connection types */
+ length += 1; /* connection addresses */
+ for (i = 0; i < ConnectionAddresses.length; i++)
+ length += 2 + ConnectionAddresses.data[i].length;
+ authenticationData.length = 0;
+ authenticationData.data = 0;
+ if (AuthenticationFuncs)
+ {
+ (*AuthenticationFuncs->Generator) (AuthenticationData,
+ &authenticationData,
+ REQUEST);
+ }
+ length += 2 + AuthenticationName->length; /* authentication name */
+ length += 2 + authenticationData.length; /* authentication data */
+ length += 1; /* authorization names */
+ for (i = 0; i < AuthorizationNames.length; i++)
+ length += 2 + AuthorizationNames.data[i].length;
+ length += 2 + ManufacturerDisplayID.length; /* display ID */
+ header.length = length;
+
+ if (!XdmcpWriteHeader (&buffer, &header))
+ {
+ XdmcpDisposeARRAY8 (&authenticationData);
+ return;
+ }
+ XdmcpWriteCARD16 (&buffer, DisplayNumber);
+ XdmcpWriteARRAY16 (&buffer, &ConnectionTypes);
+ XdmcpWriteARRAYofARRAY8 (&buffer, &ConnectionAddresses);
+
+ XdmcpWriteARRAY8 (&buffer, AuthenticationName);
+ XdmcpWriteARRAY8 (&buffer, &authenticationData);
+ XdmcpDisposeARRAY8 (&authenticationData);
+ XdmcpWriteARRAYofARRAY8 (&buffer, &AuthorizationNames);
+ XdmcpWriteARRAY8 (&buffer, &ManufacturerDisplayID);
+ if (XdmcpFlush (xdmcpSocket, &buffer, (XdmcpNetaddr) &req_sockaddr, req_socklen))
+ state = XDM_AWAIT_REQUEST_RESPONSE;
+}
+
+static void
+recv_accept_msg(unsigned length)
+{
+ CARD32 AcceptSessionID;
+ ARRAY8 AcceptAuthenticationName, AcceptAuthenticationData;
+ ARRAY8 AcceptAuthorizationName, AcceptAuthorizationData;
+
+ if (state != XDM_AWAIT_REQUEST_RESPONSE)
+ return;
+ AcceptAuthenticationName.data = 0;
+ AcceptAuthenticationData.data = 0;
+ AcceptAuthorizationName.data = 0;
+ AcceptAuthorizationData.data = 0;
+ if (XdmcpReadCARD32 (&buffer, &AcceptSessionID) &&
+ XdmcpReadARRAY8 (&buffer, &AcceptAuthenticationName) &&
+ XdmcpReadARRAY8 (&buffer, &AcceptAuthenticationData) &&
+ XdmcpReadARRAY8 (&buffer, &AcceptAuthorizationName) &&
+ XdmcpReadARRAY8 (&buffer, &AcceptAuthorizationData))
+ {
+ if (length == 12 + AcceptAuthenticationName.length +
+ AcceptAuthenticationData.length +
+ AcceptAuthorizationName.length +
+ AcceptAuthorizationData.length)
+ {
+ if (!XdmcpCheckAuthentication (&AcceptAuthenticationName,
+ &AcceptAuthenticationData, ACCEPT))
+ {
+ XdmcpFatal ("Authentication Failure", &AcceptAuthenticationName);
+ }
+ /* permit access control manipulations from this host */
+ AugmentSelf (&req_sockaddr, req_socklen);
+ /* if the authorization specified in the packet fails
+ * to be acceptable, enable the local addresses
+ */
+ if (!XdmcpAddAuthorization (&AcceptAuthorizationName,
+ &AcceptAuthorizationData))
+ {
+ AddLocalHosts ();
+ }
+ SessionID = AcceptSessionID;
+ state = XDM_MANAGE;
+ send_packet();
+ }
+ }
+ XdmcpDisposeARRAY8 (&AcceptAuthenticationName);
+ XdmcpDisposeARRAY8 (&AcceptAuthenticationData);
+ XdmcpDisposeARRAY8 (&AcceptAuthorizationName);
+ XdmcpDisposeARRAY8 (&AcceptAuthorizationData);
+}
+
+static void
+recv_decline_msg(unsigned length)
+{
+ ARRAY8 status, DeclineAuthenticationName, DeclineAuthenticationData;
+
+ status.data = 0;
+ DeclineAuthenticationName.data = 0;
+ DeclineAuthenticationData.data = 0;
+ if (XdmcpReadARRAY8 (&buffer, &status) &&
+ XdmcpReadARRAY8 (&buffer, &DeclineAuthenticationName) &&
+ XdmcpReadARRAY8 (&buffer, &DeclineAuthenticationData))
+ {
+ if (length == 6 + status.length +
+ DeclineAuthenticationName.length +
+ DeclineAuthenticationData.length &&
+ XdmcpCheckAuthentication (&DeclineAuthenticationName,
+ &DeclineAuthenticationData, DECLINE))
+ {
+ XdmcpFatal ("Session declined", &status);
+ }
+ }
+ XdmcpDisposeARRAY8 (&status);
+ XdmcpDisposeARRAY8 (&DeclineAuthenticationName);
+ XdmcpDisposeARRAY8 (&DeclineAuthenticationData);
+}
+
+static void
+send_manage_msg(void)
+{
+ XdmcpHeader header;
+
+ header.version = XDM_PROTOCOL_VERSION;
+ header.opcode = (CARD16) MANAGE;
+ header.length = 8 + DisplayClass.length;
+
+ if (!XdmcpWriteHeader (&buffer, &header))
+ return;
+ XdmcpWriteCARD32 (&buffer, SessionID);
+ XdmcpWriteCARD16 (&buffer, DisplayNumber);
+ XdmcpWriteARRAY8 (&buffer, &DisplayClass);
+ state = XDM_AWAIT_MANAGE_RESPONSE;
+ XdmcpFlush (xdmcpSocket, &buffer, (XdmcpNetaddr) &req_sockaddr, req_socklen);
+}
+
+static void
+recv_refuse_msg(unsigned length)
+{
+ CARD32 RefusedSessionID;
+
+ if (state != XDM_AWAIT_MANAGE_RESPONSE)
+ return;
+ if (length != 4)
+ return;
+ if (XdmcpReadCARD32 (&buffer, &RefusedSessionID))
+ {
+ if (RefusedSessionID == SessionID)
+ {
+ state = XDM_START_CONNECTION;
+ send_packet();
+ }
+ }
+}
+
+static void
+recv_failed_msg(unsigned length)
+{
+ CARD32 FailedSessionID;
+ ARRAY8 status;
+
+ if (state != XDM_AWAIT_MANAGE_RESPONSE)
+ return;
+ status.data = 0;
+ if (XdmcpReadCARD32 (&buffer, &FailedSessionID) &&
+ XdmcpReadARRAY8 (&buffer, &status))
+ {
+ if (length == 6 + status.length &&
+ SessionID == FailedSessionID)
+ {
+ XdmcpFatal ("Session failed", &status);
+ }
+ }
+ XdmcpDisposeARRAY8 (&status);
+}
+
+static void
+send_keepalive_msg(void)
+{
+ XdmcpHeader header;
+
+ header.version = XDM_PROTOCOL_VERSION;
+ header.opcode = (CARD16) KEEPALIVE;
+ header.length = 6;
+
+ XdmcpWriteHeader (&buffer, &header);
+ XdmcpWriteCARD16 (&buffer, DisplayNumber);
+ XdmcpWriteCARD32 (&buffer, SessionID);
+
+ state = XDM_AWAIT_ALIVE_RESPONSE;
+ XdmcpFlush (xdmcpSocket, &buffer, (XdmcpNetaddr) &req_sockaddr, req_socklen);
+}
+
+static void
+recv_alive_msg (unsigned length)
+{
+ CARD8 SessionRunning;
+ CARD32 AliveSessionID;
+
+ if (state != XDM_AWAIT_ALIVE_RESPONSE)
+ return;
+ if (length != 5)
+ return;
+ if (XdmcpReadCARD8 (&buffer, &SessionRunning) &&
+ XdmcpReadCARD32 (&buffer, &AliveSessionID))
+ {
+ if (SessionRunning && AliveSessionID == SessionID)
+ {
+ /* backoff dormancy period */
+ state = XDM_RUN_SESSION;
+ if ((GetTimeInMillis() - lastDeviceEventTime.milliseconds) >
+ keepaliveDormancy * 1000)
+ {
+ keepaliveDormancy <<= 1;
+ if (keepaliveDormancy > XDM_MAX_DORMANCY)
+ keepaliveDormancy = XDM_MAX_DORMANCY;
+ }
+ timeOutTime = GetTimeInMillis() + keepaliveDormancy * 1000;
+ }
+ else
+ {
+ XdmcpDeadSession ("Alive respose indicates session dead");
+ }
+ }
+}
+
+static void
+XdmcpFatal (
+ char *type,
+ ARRAY8Ptr status)
+{
+ FatalError ("XDMCP fatal error: %s %*.*s\n", type,
+ status->length, status->length, status->data);
+}
+
+static void
+XdmcpWarning(char *str)
+{
+ ErrorF("XDMCP warning: %s\n", str);
+}
+
+static void
+get_manager_by_name(
+ int argc,
+ char **argv,
+ int i)
+{
+ struct hostent *hep;
+
+ if (i == argc)
+ {
+ ErrorF("Xserver: missing host name in command line\n");
+ exit(1);
+ }
+ if (!(hep = gethostbyname(argv[i])))
+ {
+ ErrorF("Xserver: unknown host: %s\n", argv[i]);
+ exit(1);
+ }
+#ifndef _MINIX
+ if (hep->h_length == sizeof (struct in_addr))
+#else
+ if (hep->h_length == sizeof (ipaddr_t))
+#endif
+ {
+ memmove(&ManagerAddress.sin_addr, hep->h_addr, hep->h_length);
+#ifdef BSD44SOCKETS
+ ManagerAddress.sin_len = sizeof(ManagerAddress);
+#endif
+ ManagerAddress.sin_family = AF_INET;
+ ManagerAddress.sin_port = htons (xdm_udp_port);
+ }
+ else
+ {
+ ErrorF ("Xserver: host on strange network %s\n", argv[i]);
+ exit (1);
+ }
+}
+
+static void
+get_fromaddr_by_name(
+ int argc,
+ char **argv,
+ int i)
+{
+ struct hostent *hep;
+
+ if (i == argc)
+ {
+ ErrorF("Xserver: missing -from host name in command line\n");
+ exit(1);
+ }
+ if (!(hep = gethostbyname(argv[i])))
+ {
+ ErrorF("Xserver: unknown host: %s\n", argv[i]);
+ exit(1);
+ }
+#ifndef _MINIX
+ if (hep->h_length == sizeof (struct in_addr))
+#else
+ if (hep->h_length == sizeof (ipaddr_t))
+#endif
+ {
+ memset(&FromAddress, 0, sizeof(FromAddress));
+ memmove(&FromAddress.sin_addr, hep->h_addr, hep->h_length);
+#ifdef BSD44SOCKETS
+ FromAddress.sin_len = sizeof(FromAddress);
+#endif
+ FromAddress.sin_family = AF_INET;
+ FromAddress.sin_port = 0;
+ }
+ else
+ {
+ ErrorF ("Xserver: -from host on strange network %s\n", argv[i]);
+ exit (1);
+ }
+ xdm_from = argv[i];
+}
+
+#ifdef MINIX
+static char read_buffer[XDM_MAX_MSGLEN+sizeof(udp_io_hdr_t)];
+static int read_inprogress;
+static int read_size;
+
+int
+XdmcpFill (
+int fd,
+XdmcpBufferPtr buffer,
+XdmcpNetaddr from, /* return */
+int *fromlen) /* return */
+{
+ int r;
+
+ if (read_inprogress)
+ return 0;
+
+ if (read_size != 0)
+ {
+ r= read_size;
+ read_size= 0;
+ return MNX_XdmcpFill(fd, buffer, from, fromlen, read_buffer,
+ r);
+ }
+
+ r= read(fd, read_buffer, sizeof(read_buffer));
+ if (r > 0)
+ {
+ return MNX_XdmcpFill(fd, buffer, from, fromlen, read_buffer,
+ r);
+ }
+ else if (r == -1 && errno == EINPROGRESS)
+ {
+ read_inprogress= 1;
+ nbio_inprogress(fd, ASIO_READ, 1 /* read */, 0 /* write */,
+ 0 /* except */);
+ return 0;
+ }
+ else
+ FatalError("XdmcpFill: read failed: %s\n",
+ r == 0 ? "EOF" : strerror(errno));
+ return 0;
+}
+
+static void read_cb(ref, res, err)
+nbio_ref_t ref;
+int res;
+int err;
+{
+ if (res <= 0)
+ {
+ FatalError("xdmcp'read_cb: read failed: %s\n",
+ res == 0 ? "EOF" : strerror(err));
+ }
+ read_inprogress= 0;
+ read_size= res;
+}
+#endif
+
+#else
+static int xdmcp_non_empty; /* avoid complaint by ranlib */
+#endif /* XDMCP */
diff --git a/xc/programs/Xserver/record/Imakefile b/xc/programs/Xserver/record/Imakefile
new file mode 100644
index 000000000..a1952b420
--- /dev/null
+++ b/xc/programs/Xserver/record/Imakefile
@@ -0,0 +1,29 @@
+XCOMM $XFree86: xc/programs/Xserver/record/Imakefile,v 1.8 1999/08/14 10:50:20 dawes Exp $
+XCOMM
+XCOMM
+XCOMM $XConsortium: Imakefile /main/3 1996/09/28 17:15:43 rws $
+
+#define IHaveModules
+#include <Server.tmpl>
+
+#if DoLoadableServer
+ MSRCS = recordmod.c
+ MOBJS = recordmod.o
+#endif
+
+ SRCS = record.c set.c $(MSRCS)
+ OBJS = record.o set.o $(MOBJS)
+ INCLUDES = -I../include -I$(XINCLUDESRC) -I$(EXTINCSRC)
+ LINTLIBS = ../dix/llib-ldix.ln
+ DEFINES = -DNDEBUG
+
+ModuleObjectRule()
+LibraryModuleTarget(record,$(OBJS))
+LintLibraryTarget(record,$(SRCS))
+NormalLintTarget($(SRCS))
+
+InstallLibraryModule(record,$(MODULEDIR),extensions)
+
+DependTarget()
+
+InstallDriverSDKLibraryModule(record,$(DRIVERSDKMODULEDIR),extensions)
diff --git a/xc/programs/Xserver/record/record.c b/xc/programs/Xserver/record/record.c
new file mode 100644
index 000000000..bdb7a8111
--- /dev/null
+++ b/xc/programs/Xserver/record/record.c
@@ -0,0 +1,3024 @@
+/* $TOG: record.c /main/9 1998/02/09 15:17:09 kaleb $ */
+
+/*
+
+Copyright 1995, 1998 The Open Group
+
+All Rights Reserved.
+
+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: David P. Wiggins, The Open Group
+
+This work benefited from earlier work done by Martha Zimet of NCD
+and Jim Haggerty of Metheus.
+
+*/
+/* $XFree86: xc/programs/Xserver/record/record.c,v 1.6 1998/10/04 09:39:53 dawes Exp $ */
+
+#define NEED_EVENTS
+#include "dixstruct.h"
+#include "extnsionst.h"
+#define _XRECORD_SERVER_
+#include "recordstr.h"
+#include "set.h"
+
+#ifndef XFree86LOADER
+#include <stdio.h>
+#include <assert.h>
+#else
+#include "xf86_ansic.h"
+#endif
+
+static RESTYPE RTContext; /* internal resource type for Record contexts */
+static int RecordErrorBase; /* first Record error number */
+
+/* How many bytes of protocol data to buffer in a context. Don't set to less
+ * than 32.
+ */
+#define REPLY_BUF_SIZE 1024
+
+/* Record Context structure */
+
+typedef struct {
+ XID id; /* resource id of context */
+ ClientPtr pRecordingClient; /* client that has context enabled */
+ struct _RecordClientsAndProtocolRec *pListOfRCAP; /* all registered info */
+ ClientPtr pBufClient; /* client whose protocol is in replyBuffer*/
+ unsigned int continuedReply:1; /* recording a reply that is split up? */
+ char elemHeaders; /* element header flags (time/seq no.) */
+ char bufCategory; /* category of protocol in replyBuffer */
+ int numBufBytes; /* number of bytes in replyBuffer */
+ char replyBuffer[REPLY_BUF_SIZE]; /* buffered recorded protocol */
+} RecordContextRec, *RecordContextPtr;
+
+/* RecordMinorOpRec - to hold minor opcode selections for extension requests
+ * and replies
+ */
+
+typedef union {
+ int count; /* first element of array: how many "major" structs to follow */
+ struct { /* rest of array elements are this */
+ short first; /* first major opcode */
+ short last; /* last major opcode */
+ RecordSetPtr pMinOpSet; /* minor opcode set for above major range */
+ } major;
+} RecordMinorOpRec, *RecordMinorOpPtr;
+
+
+/* RecordClientsAndProtocolRec, nicknamed RCAP - holds all the client and
+ * protocol selections passed in a single CreateContext or RegisterClients.
+ * Generally, a context will have one of these from the create and an
+ * additional one for each RegisterClients. RCAPs are freed when all their
+ * clients are unregistered.
+ */
+
+typedef struct _RecordClientsAndProtocolRec {
+ RecordContextPtr pContext; /* context that owns this RCAP */
+ struct _RecordClientsAndProtocolRec *pNextRCAP; /* next RCAP on context */
+ RecordSetPtr pRequestMajorOpSet; /* requests to record */
+ RecordMinorOpPtr pRequestMinOpInfo; /* extension requests to record */
+ RecordSetPtr pReplyMajorOpSet; /* replies to record */
+ RecordMinorOpPtr pReplyMinOpInfo; /* extension replies to record */
+ RecordSetPtr pDeviceEventSet; /* device events to record */
+ RecordSetPtr pDeliveredEventSet; /* delivered events to record */
+ RecordSetPtr pErrorSet; /* errors to record */
+ XID * pClientIDs; /* array of clients to record */
+ short numClients; /* number of clients in pClientIDs */
+ short sizeClients; /* size of pClientIDs array */
+ unsigned int clientStarted:1; /* record new client connections? */
+ unsigned int clientDied:1; /* record client disconnections? */
+ unsigned int clientIDsSeparatelyAllocated:1; /* pClientIDs malloced? */
+} RecordClientsAndProtocolRec, *RecordClientsAndProtocolPtr;
+
+/* how much bigger to make pRCAP->pClientIDs when reallocing */
+#define CLIENT_ARRAY_GROWTH_INCREMENT 4
+
+/* counts the total number of RCAPs belonging to enabled contexts. */
+static int numEnabledRCAPs;
+
+/* void VERIFY_CONTEXT(RecordContextPtr, XID, ClientPtr)
+ * In the spirit of the VERIFY_* macros in dix.h, this macro fills in
+ * the context pointer if the given ID is a valid Record Context, else it
+ * returns an error.
+ */
+#define VERIFY_CONTEXT(_pContext, _contextid, _client) { \
+ (_pContext) = (RecordContextPtr)LookupIDByType((_contextid), RTContext); \
+ if (!(_pContext)) { \
+ (_client)->errorValue = (_contextid); \
+ return RecordErrorBase + XRecordBadContext; \
+ } \
+}
+
+static int RecordDeleteContext(
+#if NeedFunctionPrototypes
+ pointer /*value*/,
+ XID /*id*/
+#endif
+);
+
+
+/***************************************************************************/
+
+/* client private stuff */
+
+/* To make declarations less obfuscated, have a typedef for a pointer to a
+ * Proc function.
+ */
+typedef int (*ProcFunctionPtr)(
+#if NeedFunctionPrototypes
+ ClientPtr /*pClient*/
+#endif
+);
+
+/* Record client private. Generally a client only has one of these if
+ * any of its requests are being recorded.
+ */
+typedef struct {
+/* ptr to client's proc vector before Record stuck its nose in */
+ ProcFunctionPtr *originalVector;
+
+/* proc vector with pointers for recorded requests redirected to the
+ * function RecordARequest
+ */
+ ProcFunctionPtr recordVector[256];
+} RecordClientPrivateRec, *RecordClientPrivatePtr;
+
+static int RecordClientPrivateIndex;
+
+/* RecordClientPrivatePtr RecordClientPrivate(ClientPtr)
+ * gets the client private of the given client. Syntactic sugar.
+ */
+#define RecordClientPrivate(_pClient) (RecordClientPrivatePtr) \
+ ((_pClient)->devPrivates[RecordClientPrivateIndex].ptr)
+
+
+/***************************************************************************/
+
+/* global list of all contexts */
+
+static RecordContextPtr *ppAllContexts;
+
+static int numContexts;/* number of contexts in ppAllContexts */
+
+/* number of currently enabled contexts. All enabled contexts are bunched
+ * up at the front of the ppAllContexts array, from ppAllContexts[0] to
+ * ppAllContexts[numEnabledContexts-1], to eliminate time spent skipping
+ * past disabled contexts.
+ */
+static int numEnabledContexts;
+
+/* RecordFindContextOnAllContexts
+ *
+ * Arguments:
+ * pContext is the context to search for.
+ *
+ * Returns:
+ * The index into the array ppAllContexts at which pContext is stored.
+ * If pContext is not found in ppAllContexts, returns -1.
+ *
+ * Side Effects: none.
+ */
+static int
+RecordFindContextOnAllContexts(pContext)
+ RecordContextPtr pContext;
+{
+ int i;
+
+ assert(numContexts >= numEnabledContexts);
+ for (i = 0; i < numContexts; i++)
+ {
+ if (ppAllContexts[i] == pContext)
+ return i;
+ }
+ return -1;
+} /* RecordFindContextOnAllContexts */
+
+
+/***************************************************************************/
+
+/* RecordFlushReplyBuffer
+ *
+ * Arguments:
+ * pContext is the context to flush.
+ * data1 is a pointer to additional data, and len1 is its length in bytes.
+ * data2 is a pointer to additional data, and len2 is its length in bytes.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * If the context is enabled, any buffered (recorded) protocol is written
+ * to the recording client, and the number of buffered bytes is set to
+ * zero. If len1 is not zero, data1/len1 are then written to the
+ * recording client, and similarly for data2/len2 (written after
+ * data1/len1).
+ */
+static void
+RecordFlushReplyBuffer(pContext, data1, len1, data2, len2)
+ RecordContextPtr pContext;
+ pointer data1;
+ int len1;
+ pointer data2;
+ int len2;
+{
+ if (!pContext->pRecordingClient || pContext->pRecordingClient->clientGone)
+ return;
+ if (pContext->numBufBytes)
+ WriteToClient(pContext->pRecordingClient, pContext->numBufBytes,
+ (char *)pContext->replyBuffer);
+ pContext->numBufBytes = 0;
+ if (len1)
+ WriteToClient(pContext->pRecordingClient, len1, (char *)data1);
+ if (len2)
+ WriteToClient(pContext->pRecordingClient, len2, (char *)data2);
+} /* RecordFlushReplyBuffer */
+
+
+/* RecordAProtocolElement
+ *
+ * Arguments:
+ * pContext is the context that is recording a protocol element.
+ * pClient is the client whose protocol is being recorded. For
+ * device events and EndOfData, pClient is NULL.
+ * category is the category of the protocol element, as defined
+ * by the RECORD spec.
+ * data is a pointer to the protocol data, and datalen is its length
+ * in bytes.
+ * futurelen is the number of bytes that will be sent in subsequent
+ * calls to this function to complete this protocol element.
+ * In those subsequent calls, futurelen will be -1 to indicate
+ * that the current data is a continuation of the same protocol
+ * element.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * The context may be flushed. The new protocol element will be
+ * added to the context's protocol buffer with appropriate element
+ * headers prepended (sequence number and timestamp). If the data
+ * is continuation data (futurelen == -1), element headers won't
+ * be added. If the protocol element and headers won't fit in
+ * the context's buffer, it is sent directly to the recording
+ * client (after any buffered data).
+ */
+static void
+RecordAProtocolElement(pContext, pClient, category, data, datalen, futurelen)
+ RecordContextPtr pContext;
+ ClientPtr pClient;
+ int category;
+ pointer data;
+ int datalen;
+ int futurelen;
+{
+ CARD32 elemHeaderData[2];
+ int numElemHeaders = 0;
+ Bool recordingClientSwapped = pContext->pRecordingClient->swapped;
+ int n;
+ CARD32 serverTime;
+ Bool gotServerTime = FALSE;
+ int replylen;
+
+ if (futurelen >= 0)
+ { /* start of new protocol element */
+ xRecordEnableContextReply *pRep = (xRecordEnableContextReply *)
+ pContext->replyBuffer;
+ if (pContext->pBufClient != pClient ||
+ pContext->bufCategory != category)
+ {
+ RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0);
+ pContext->pBufClient = pClient;
+ pContext->bufCategory = category;
+ }
+
+ if (!pContext->numBufBytes)
+ {
+ serverTime = GetTimeInMillis();
+ gotServerTime = TRUE;
+ pRep->type = X_Reply;
+ pRep->category = category;
+ pRep->sequenceNumber = pContext->pRecordingClient->sequence;
+ pRep->length = 0;
+ pRep->elementHeader = pContext->elemHeaders;
+ pRep->serverTime = serverTime;
+ if (pClient)
+ {
+ pRep->clientSwapped =
+ (pClient->swapped != recordingClientSwapped);
+ pRep->idBase = pClient->clientAsMask;
+ pRep->recordedSequenceNumber = pClient->sequence;
+ }
+ else /* it's a device event, StartOfData, or EndOfData */
+ {
+ pRep->clientSwapped = (category != XRecordFromServer) &&
+ recordingClientSwapped;
+ pRep->idBase = 0;
+ pRep->recordedSequenceNumber = 0;
+ }
+
+ if (recordingClientSwapped)
+ {
+ swaps(&pRep->sequenceNumber, n);
+ swapl(&pRep->length, n);
+ swapl(&pRep->idBase, n);
+ swapl(&pRep->serverTime, n);
+ swapl(&pRep->recordedSequenceNumber, n);
+ }
+ pContext->numBufBytes = SIZEOF(xRecordEnableContextReply);
+ }
+
+ /* generate element headers if needed */
+
+ if ( ( (pContext->elemHeaders & XRecordFromClientTime)
+ && category == XRecordFromClient)
+ ||
+ ( (pContext->elemHeaders & XRecordFromServerTime)
+ && category == XRecordFromServer))
+ {
+ if (gotServerTime)
+ elemHeaderData[numElemHeaders] = serverTime;
+ else
+ elemHeaderData[numElemHeaders] = GetTimeInMillis();
+ if (recordingClientSwapped)
+ swapl(&elemHeaderData[numElemHeaders], n);
+ numElemHeaders++;
+ }
+
+ if ( (pContext->elemHeaders & XRecordFromClientSequence)
+ &&
+ (category == XRecordFromClient || category == XRecordClientDied))
+ {
+ elemHeaderData[numElemHeaders] = pClient->sequence;
+ if (recordingClientSwapped)
+ swapl(&elemHeaderData[numElemHeaders], n);
+ numElemHeaders++;
+ }
+
+ /* adjust reply length */
+
+ replylen = pRep->length;
+ if (recordingClientSwapped) swapl(&replylen, n);
+ replylen += numElemHeaders + (datalen >> 2) + (futurelen >> 2);
+ if (recordingClientSwapped) swapl(&replylen, n);
+ pRep->length = replylen;
+ } /* end if not continued reply */
+
+ numElemHeaders *= 4;
+
+ /* if space available >= space needed, buffer the data */
+
+ if (REPLY_BUF_SIZE - pContext->numBufBytes >= datalen + numElemHeaders)
+ {
+ if (numElemHeaders)
+ {
+ memcpy(pContext->replyBuffer + pContext->numBufBytes,
+ elemHeaderData, numElemHeaders);
+ pContext->numBufBytes += numElemHeaders;
+ }
+ if (datalen)
+ {
+ memcpy(pContext->replyBuffer + pContext->numBufBytes,
+ data, datalen);
+ pContext->numBufBytes += datalen;
+ }
+ }
+ else
+ RecordFlushReplyBuffer(pContext, (pointer)elemHeaderData,
+ numElemHeaders, (pointer)data, datalen);
+
+} /* RecordAProtocolElement */
+
+
+/* RecordFindClientOnContext
+ *
+ * Arguments:
+ * pContext is the context to search.
+ * clientspec is the resource ID mask identifying the client to search
+ * for, or XRecordFutureClients.
+ * pposition is a pointer to an int, or NULL. See Returns.
+ *
+ * Returns:
+ * The RCAP on which clientspec was found, or NULL if not found on
+ * any RCAP on the given context.
+ * If pposition was not NULL and the returned RCAP is not NULL,
+ * *pposition will be set to the index into the returned the RCAP's
+ * pClientIDs array that holds clientspec.
+ *
+ * Side Effects: none.
+ */
+static RecordClientsAndProtocolPtr
+RecordFindClientOnContext(pContext, clientspec, pposition)
+ RecordContextPtr pContext;
+ XID clientspec;
+ int *pposition;
+{
+ RecordClientsAndProtocolPtr pRCAP;
+
+ for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
+ {
+ int i;
+ for (i = 0; i < pRCAP->numClients; i++)
+ {
+ if (pRCAP->pClientIDs[i] == clientspec)
+ {
+ if (pposition)
+ *pposition = i;
+ return pRCAP;
+ }
+ }
+ }
+ return NULL;
+} /* RecordFindClientOnContext */
+
+
+/* RecordABigRequest
+ *
+ * Arguments:
+ * pContext is the recording context.
+ * client is the client being recorded.
+ * stuff is a pointer to the big request of client (see the Big Requests
+ * extension for details.)
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * The big request is recorded with the correct length field re-inserted.
+ *
+ * Note: this function exists mainly to make RecordARequest smaller.
+ */
+static void
+RecordABigRequest(pContext, client, stuff)
+ RecordContextPtr pContext;
+ ClientPtr client;
+ xReq *stuff;
+{
+ CARD32 bigLength;
+ char n;
+ int bytesLeft;
+
+ /* note: client->req_len has been frobbed by ReadRequestFromClient
+ * (os/io.c) to discount the extra 4 bytes taken by the extended length
+ * field in a big request. The actual request length to record is
+ * client->req_len + 1 (measured in CARD32s).
+ */
+
+ /* record the request header */
+ bytesLeft = client->req_len << 2;
+ RecordAProtocolElement(pContext, client, XRecordFromClient,
+ (pointer)stuff, SIZEOF(xReq), bytesLeft);
+
+ /* reinsert the extended length field that was squished out */
+ bigLength = client->req_len + (sizeof(bigLength) >> 2);
+ if (client->swapped)
+ swapl(&bigLength, n);
+ RecordAProtocolElement(pContext, client, XRecordFromClient,
+ (pointer)&bigLength, sizeof(bigLength), /* continuation */ -1);
+ bytesLeft -= sizeof(bigLength);
+
+ /* record the rest of the request after the length */
+ RecordAProtocolElement(pContext, client, XRecordFromClient,
+ (pointer)(stuff + 1), bytesLeft, /* continuation */ -1);
+} /* RecordABigRequest */
+
+
+/* RecordARequest
+ *
+ * Arguments:
+ * client is a client that the server has dispatched a request to by
+ * calling client->requestVector[request opcode] .
+ * The request is in client->requestBuffer.
+ *
+ * Returns:
+ * Whatever is returned by the "real" Proc function for this request.
+ * The "real" Proc function is the function that was in
+ * client->requestVector[request opcode] before it was replaced by
+ * RecordARequest. (See the function RecordInstallHooks.)
+ *
+ * Side Effects:
+ * The request is recorded by all contexts that have registered this
+ * request for this client. The real Proc function is called.
+ */
+static int
+RecordARequest(client)
+ ClientPtr client;
+{
+ RecordContextPtr pContext;
+ RecordClientsAndProtocolPtr pRCAP;
+ int i;
+ RecordClientPrivatePtr pClientPriv;
+ REQUEST(xReq);
+ int majorop;
+
+ majorop = stuff->reqType;
+ for (i = 0; i < numEnabledContexts; i++)
+ {
+ pContext = ppAllContexts[i];
+ pRCAP = RecordFindClientOnContext(pContext, client->clientAsMask,
+ NULL);
+ if (pRCAP && pRCAP->pRequestMajorOpSet &&
+ RecordIsMemberOfSet(pRCAP->pRequestMajorOpSet, majorop))
+ {
+ if (majorop <= 127)
+ { /* core request */
+
+ if (stuff->length == 0)
+ RecordABigRequest(pContext, client, stuff);
+ else
+ RecordAProtocolElement(pContext, client, XRecordFromClient,
+ (pointer)stuff, client->req_len << 2, 0);
+ }
+ else /* extension, check minor opcode */
+ {
+ int minorop = MinorOpcodeOfRequest(client);
+ int numMinOpInfo;
+ RecordMinorOpPtr pMinorOpInfo = pRCAP->pRequestMinOpInfo;
+
+ assert (pMinorOpInfo);
+ numMinOpInfo = pMinorOpInfo->count;
+ pMinorOpInfo++;
+ assert (numMinOpInfo);
+ for ( ; numMinOpInfo; numMinOpInfo--, pMinorOpInfo++)
+ {
+ if (majorop >= pMinorOpInfo->major.first &&
+ majorop <= pMinorOpInfo->major.last &&
+ RecordIsMemberOfSet(pMinorOpInfo->major.pMinOpSet,
+ minorop))
+ {
+ if (stuff->length == 0)
+ RecordABigRequest(pContext, client, stuff);
+ else
+ RecordAProtocolElement(pContext, client,
+ XRecordFromClient, (pointer)stuff,
+ client->req_len << 2, 0);
+ break;
+ }
+ } /* end for each minor op info */
+ } /* end extension request */
+ } /* end this RCAP wants this major opcode */
+ } /* end for each context */
+ pClientPriv = RecordClientPrivate(client);
+ assert(pClientPriv);
+ return (* pClientPriv->originalVector[majorop])(client);
+} /* RecordARequest */
+
+
+/* RecordASkippedRequest
+ *
+ * Arguments:
+ * pcbl is &SkippedRequestCallback.
+ * nulldata is NULL.
+ * calldata is a pointer to a SkippedRequestInfoRec (include/os.h)
+ * which provides information about requests that the server is
+ * skipping. The client's proc vector won't be called for skipped
+ * requests, so that's why we have to catch them here.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * The skipped requests are recorded by all contexts that have
+ * registered those requests for this client.
+ *
+ * Note: most servers don't skip requests, so calls to this will probably
+ * be rare. For more information on skipped requests, search for
+ * the word skip in ddx.tbl.ms (the porting layer document).
+ */
+static void
+RecordASkippedRequest(pcbl , nulldata, calldata)
+ CallbackListPtr *pcbl;
+ pointer nulldata;
+ pointer calldata;
+{
+ SkippedRequestInfoRec *psi = (SkippedRequestInfoRec *)calldata;
+ RecordContextPtr pContext;
+ RecordClientsAndProtocolPtr pRCAP;
+ xReqPtr stuff = psi->req;
+ ClientPtr client = psi->client;
+ int numSkippedRequests = psi->numskipped;
+ int reqlen;
+ int i;
+ int majorop;
+
+ while (numSkippedRequests--)
+ {
+ majorop = stuff->reqType;
+ reqlen = ReqLen(stuff, client);
+ /* handle big request */
+ if (stuff->length == 0)
+ reqlen += 4;
+ for (i = 0; i < numEnabledContexts; i++)
+ {
+ pContext = ppAllContexts[i];
+ pRCAP = RecordFindClientOnContext(pContext, client->clientAsMask,
+ NULL);
+ if (pRCAP && pRCAP->pRequestMajorOpSet &&
+ RecordIsMemberOfSet(pRCAP->pRequestMajorOpSet, majorop))
+ {
+ if (majorop <= 127)
+ { /* core request */
+
+ RecordAProtocolElement(pContext, client, XRecordFromClient,
+ (pointer)stuff, reqlen, 0);
+ }
+ else /* extension, check minor opcode */
+ {
+ int minorop = MinorOpcodeOfRequest(client);
+ int numMinOpInfo;
+ RecordMinorOpPtr pMinorOpInfo = pRCAP->pRequestMinOpInfo;
+
+ assert (pMinorOpInfo);
+ numMinOpInfo = pMinorOpInfo->count;
+ pMinorOpInfo++;
+ assert (numMinOpInfo);
+ for ( ; numMinOpInfo; numMinOpInfo--, pMinorOpInfo++)
+ {
+ if (majorop >= pMinorOpInfo->major.first &&
+ majorop <= pMinorOpInfo->major.last &&
+ RecordIsMemberOfSet(pMinorOpInfo->major.pMinOpSet,
+ minorop))
+ {
+ RecordAProtocolElement(pContext, client,
+ XRecordFromClient, (pointer)stuff,
+ reqlen, 0);
+ break;
+ }
+ } /* end for each minor op info */
+ } /* end extension request */
+ } /* end this RCAP wants this major opcode */
+ } /* end for each context */
+
+ /* go to next request */
+ stuff = (xReqPtr)( ((char *)stuff) + reqlen);
+
+ } /* end for each skipped request */
+} /* RecordASkippedRequest */
+
+
+/* RecordAReply
+ *
+ * Arguments:
+ * pcbl is &ReplyCallback.
+ * nulldata is NULL.
+ * calldata is a pointer to a ReplyInfoRec (include/os.h)
+ * which provides information about replies that are being sent
+ * to clients.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * The reply is recorded by all contexts that have registered this
+ * reply type for this client. If more data belonging to the same
+ * reply is expected, and if the reply is being recorded by any
+ * context, pContext->continuedReply is set to 1.
+ * If pContext->continuedReply was already 1 and this is the last
+ * chunk of data belonging to this reply, it is set to 0.
+ */
+static void
+RecordAReply(pcbl, nulldata, calldata)
+ CallbackListPtr *pcbl;
+ pointer nulldata;
+ pointer calldata;
+{
+ RecordContextPtr pContext;
+ RecordClientsAndProtocolPtr pRCAP;
+ int eci;
+ int majorop;
+ ReplyInfoRec *pri = (ReplyInfoRec *)calldata;
+ ClientPtr client = pri->client;
+ REQUEST(xReq);
+
+ majorop = stuff->reqType;
+ for (eci = 0; eci < numEnabledContexts; eci++)
+ {
+ pContext = ppAllContexts[eci];
+ pRCAP = RecordFindClientOnContext(pContext, client->clientAsMask,
+ NULL);
+ if (pRCAP)
+ {
+ if (pContext->continuedReply)
+ {
+ RecordAProtocolElement(pContext, client, XRecordFromServer,
+ pri->replyData, pri->dataLenBytes, /* continuation */ -1);
+ if (!pri->bytesRemaining)
+ pContext->continuedReply = 0;
+ }
+ else if (pri->startOfReply && pRCAP->pReplyMajorOpSet &&
+ RecordIsMemberOfSet(pRCAP->pReplyMajorOpSet, majorop))
+ {
+ if (majorop <= 127)
+ { /* core reply */
+ RecordAProtocolElement(pContext, client, XRecordFromServer,
+ pri->replyData, pri->dataLenBytes, pri->bytesRemaining);
+ if (pri->bytesRemaining)
+ pContext->continuedReply = 1;
+ }
+ else /* extension, check minor opcode */
+ {
+ int minorop = MinorOpcodeOfRequest(client);
+ int numMinOpInfo;
+ RecordMinorOpPtr pMinorOpInfo = pRCAP->pReplyMinOpInfo;
+ assert (pMinorOpInfo);
+ numMinOpInfo = pMinorOpInfo->count;
+ pMinorOpInfo++;
+ assert (numMinOpInfo);
+ for ( ; numMinOpInfo; numMinOpInfo--, pMinorOpInfo++)
+ {
+ if (majorop >= pMinorOpInfo->major.first &&
+ majorop <= pMinorOpInfo->major.last &&
+ RecordIsMemberOfSet(pMinorOpInfo->major.pMinOpSet,
+ minorop))
+ {
+ RecordAProtocolElement(pContext, client,
+ XRecordFromServer, pri->replyData,
+ pri->dataLenBytes, pri->bytesRemaining);
+ if (pri->bytesRemaining)
+ pContext->continuedReply = 1;
+ break;
+ }
+ } /* end for each minor op info */
+ } /* end extension reply */
+ } /* end continued reply vs. start of reply */
+ } /* end client is registered on this context */
+ } /* end for each context */
+} /* RecordAReply */
+
+
+/* RecordADeliveredEventOrError
+ *
+ * Arguments:
+ * pcbl is &EventCallback.
+ * nulldata is NULL.
+ * calldata is a pointer to a EventInfoRec (include/dix.h)
+ * which provides information about events that are being sent
+ * to clients.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * The event or error is recorded by all contexts that have registered
+ * it for this client.
+ */
+static void
+RecordADeliveredEventOrError(pcbl, nulldata, calldata)
+ CallbackListPtr *pcbl;
+ pointer nulldata;
+ pointer calldata;
+{
+ EventInfoRec *pei = (EventInfoRec *)calldata;
+ RecordContextPtr pContext;
+ RecordClientsAndProtocolPtr pRCAP;
+ int eci; /* enabled context index */
+ ClientPtr pClient = pei->client;
+
+ for (eci = 0; eci < numEnabledContexts; eci++)
+ {
+ pContext = ppAllContexts[eci];
+ pRCAP = RecordFindClientOnContext(pContext, pClient->clientAsMask,
+ NULL);
+ if (pRCAP && (pRCAP->pDeliveredEventSet || pRCAP->pErrorSet))
+ {
+ int ev; /* event index */
+ xEvent *pev = pei->events;
+ for (ev = 0; ev < pei->count; ev++, pev++)
+ {
+ int recordit;
+ if (pev->u.u.type == X_Error)
+ {
+ recordit = RecordIsMemberOfSet(pRCAP->pErrorSet,
+ ((xError *)(pev))->errorCode);
+ }
+ else
+ {
+ recordit = RecordIsMemberOfSet(pRCAP->pDeliveredEventSet,
+ pev->u.u.type & 0177);
+ }
+ if (recordit)
+ {
+ xEvent swappedEvent;
+ xEvent *pEvToRecord = pev;
+
+ if (pClient->swapped)
+ {
+ (*EventSwapVector[pev->u.u.type & 0177])
+ (pev, &swappedEvent);
+ pEvToRecord = &swappedEvent;
+
+ }
+ RecordAProtocolElement(pContext, pClient,
+ XRecordFromServer, pEvToRecord, SIZEOF(xEvent), 0);
+ }
+ } /* end for each event */
+ } /* end this client is on this context */
+ } /* end for each enabled context */
+} /* RecordADeliveredEventOrError */
+
+
+/* RecordADeviceEvent
+ *
+ * Arguments:
+ * pcbl is &DeviceEventCallback.
+ * nulldata is NULL.
+ * calldata is a pointer to a DeviceEventInfoRec (include/dix.h)
+ * which provides information about device events that occur.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * The device event is recorded by all contexts that have registered
+ * it for this client.
+ */
+static void
+RecordADeviceEvent(pcbl, nulldata, calldata)
+ CallbackListPtr *pcbl;
+ pointer nulldata;
+ pointer calldata;
+{
+ DeviceEventInfoRec *pei = (DeviceEventInfoRec *)calldata;
+ RecordContextPtr pContext;
+ RecordClientsAndProtocolPtr pRCAP;
+ int eci; /* enabled context index */
+
+ for (eci = 0; eci < numEnabledContexts; eci++)
+ {
+ pContext = ppAllContexts[eci];
+ for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
+ {
+ if (pRCAP->pDeviceEventSet)
+ {
+ int ev; /* event index */
+ xEvent *pev = pei->events;
+ for (ev = 0; ev < pei->count; ev++, pev++)
+ {
+ if (RecordIsMemberOfSet(pRCAP->pDeviceEventSet,
+ pev->u.u.type & 0177))
+ {
+ xEvent swappedEvent;
+ xEvent *pEvToRecord = pev;
+
+ if (pContext->pRecordingClient->swapped)
+ {
+ (*EventSwapVector[pev->u.u.type & 0177])
+ (pev, &swappedEvent);
+ pEvToRecord = &swappedEvent;
+ }
+
+ RecordAProtocolElement(pContext, NULL,
+ XRecordFromServer, pEvToRecord, SIZEOF(xEvent), 0);
+ /* make sure device events get flushed in the absence
+ * of other client activity
+ */
+ SetCriticalOutputPending();
+ }
+ } /* end for each event */
+ } /* end this RCAP selects device events */
+ } /* end for each RCAP on this context */
+ } /* end for each enabled context */
+} /* RecordADeviceEvent */
+
+
+/* RecordFlushAllContexts
+ *
+ * Arguments:
+ * pcbl is &FlushCallback.
+ * nulldata and calldata are NULL.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * All buffered reply data of all enabled contexts is written to
+ * the recording clients.
+ */
+static void
+RecordFlushAllContexts(pcbl, nulldata, calldata)
+ CallbackListPtr *pcbl;
+ pointer nulldata;
+ pointer calldata;
+{
+ int eci; /* enabled context index */
+ RecordContextPtr pContext;
+
+ for (eci = 0; eci < numEnabledContexts; eci++)
+ {
+ pContext = ppAllContexts[eci];
+
+ /* In most cases we leave it to RecordFlushReplyBuffer to make
+ * this check, but this function could be called very often, so we
+ * check before calling hoping to save the function call cost
+ * most of the time.
+ */
+ if (pContext->numBufBytes)
+ RecordFlushReplyBuffer(ppAllContexts[eci], NULL, 0, NULL, 0);
+ }
+} /* RecordFlushAllContexts */
+
+
+/* RecordInstallHooks
+ *
+ * Arguments:
+ * pRCAP is an RCAP on an enabled or being-enabled context.
+ * oneclient can be zero or the resource ID mask identifying a client.
+ *
+ * Returns: BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ * Recording hooks needed by RCAP are installed.
+ * If oneclient is zero, recording hooks needed for all clients and
+ * protocol on the RCAP are installed. If oneclient is non-zero,
+ * only those hooks needed for the specified client are installed.
+ *
+ * Client requestVectors may be altered. numEnabledRCAPs will be
+ * incremented if oneclient == 0. Callbacks may be added to
+ * various callback lists.
+ */
+static int
+RecordInstallHooks(pRCAP, oneclient)
+ RecordClientsAndProtocolPtr pRCAP;
+ XID oneclient;
+{
+ int i = 0;
+ XID client;
+
+ if (oneclient)
+ client = oneclient;
+ else
+ client = pRCAP->numClients ? pRCAP->pClientIDs[i++] : 0;
+
+ while (client)
+ {
+ if (client != XRecordFutureClients)
+ {
+ if (pRCAP->pRequestMajorOpSet)
+ {
+ RecordSetIteratePtr pIter = NULL;
+ RecordSetInterval interval;
+ ClientPtr pClient = clients[CLIENT_ID(client)];
+
+ if (pClient && !RecordClientPrivate(pClient))
+ {
+ RecordClientPrivatePtr pClientPriv;
+ /* no Record proc vector; allocate one */
+ pClientPriv = (RecordClientPrivatePtr)
+ xalloc(sizeof(RecordClientPrivateRec));
+ if (!pClientPriv)
+ return BadAlloc;
+ /* copy old proc vector to new */
+ memcpy(pClientPriv->recordVector, pClient->requestVector,
+ sizeof (pClientPriv->recordVector));
+ pClientPriv->originalVector = pClient->requestVector;
+ pClient->devPrivates[RecordClientPrivateIndex].ptr =
+ (pointer)pClientPriv;
+ pClient->requestVector = pClientPriv->recordVector;
+ }
+ while (pIter = RecordIterateSet(pRCAP->pRequestMajorOpSet,
+ pIter, &interval))
+ {
+ unsigned int j;
+ for (j = interval.first; j <= interval.last; j++)
+ pClient->requestVector[j] = RecordARequest;
+ }
+ }
+ }
+ if (oneclient)
+ client = 0;
+ else
+ client = (i < pRCAP->numClients) ? pRCAP->pClientIDs[i++] : 0;
+ }
+
+ assert(numEnabledRCAPs >= 0);
+ if (!oneclient && ++numEnabledRCAPs == 1)
+ { /* we're enabling the first context */
+ if (!AddCallback(&EventCallback, RecordADeliveredEventOrError, NULL))
+ return BadAlloc;
+ if (!AddCallback(&DeviceEventCallback, RecordADeviceEvent, NULL))
+ return BadAlloc;
+ if (!AddCallback(&ReplyCallback, RecordAReply, NULL))
+ return BadAlloc;
+ if (!AddCallback(&SkippedRequestsCallback, RecordASkippedRequest,
+ NULL))
+ return BadAlloc;
+ if (!AddCallback(&FlushCallback, RecordFlushAllContexts, NULL))
+ return BadAlloc;
+ /* Alternate context flushing scheme: delete the line above
+ * and call RegisterBlockAndWakeupHandlers here passing
+ * RecordFlushAllContexts. Is this any better?
+ */
+ }
+ return Success;
+} /* RecordInstallHooks */
+
+
+/* RecordUninstallHooks
+ *
+ * Arguments:
+ * pRCAP is an RCAP on an enabled or being-disabled context.
+ * oneclient can be zero or the resource ID mask identifying a client.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Recording hooks needed by RCAP may be uninstalled.
+ * If oneclient is zero, recording hooks needed for all clients and
+ * protocol on the RCAP may be uninstalled. If oneclient is non-zero,
+ * only those hooks needed for the specified client may be uninstalled.
+ *
+ * Client requestVectors may be altered. numEnabledRCAPs will be
+ * decremented if oneclient == 0. Callbacks may be deleted from
+ * various callback lists.
+ */
+static void
+RecordUninstallHooks(pRCAP, oneclient)
+ RecordClientsAndProtocolPtr pRCAP;
+ XID oneclient;
+{
+ int i = 0;
+ XID client;
+
+ if (oneclient)
+ client = oneclient;
+ else
+ client = pRCAP->numClients ? pRCAP->pClientIDs[i++] : 0;
+
+ while (client)
+ {
+ if (client != XRecordFutureClients)
+ {
+ if (pRCAP->pRequestMajorOpSet)
+ {
+ ClientPtr pClient = clients[CLIENT_ID(client)];
+ int c;
+ Bool otherRCAPwantsProcVector = FALSE;
+ RecordClientPrivatePtr pClientPriv =
+ RecordClientPrivate(pClient);
+
+ assert (pClient && RecordClientPrivate(pClient));
+ memcpy(pClientPriv->recordVector, pClientPriv->originalVector,
+ sizeof (pClientPriv->recordVector));
+
+ for (c = 0; c < numEnabledContexts; c++)
+ {
+ RecordClientsAndProtocolPtr pOtherRCAP;
+ RecordContextPtr pContext = ppAllContexts[c];
+
+ if (pContext == pRCAP->pContext) continue;
+ pOtherRCAP = RecordFindClientOnContext(pContext, client,
+ NULL);
+ if (pOtherRCAP && pOtherRCAP->pRequestMajorOpSet)
+ {
+ RecordSetIteratePtr pIter = NULL;
+ RecordSetInterval interval;
+
+ otherRCAPwantsProcVector = TRUE;
+ while (pIter = RecordIterateSet(
+ pOtherRCAP->pRequestMajorOpSet,
+ pIter, &interval))
+ {
+ unsigned int j;
+ for (j = interval.first; j <= interval.last; j++)
+ pClient->requestVector[j] = RecordARequest;
+ }
+ }
+ }
+ if (!otherRCAPwantsProcVector)
+ { /* nobody needs it, so free it */
+ pClient->requestVector = pClientPriv->originalVector;
+ pClient->devPrivates[RecordClientPrivateIndex].ptr = NULL;
+ xfree(pClientPriv);
+ }
+ } /* end if this RCAP specifies any requests */
+ } /* end if not future clients */
+ if (oneclient)
+ client = 0;
+ else
+ client = (i < pRCAP->numClients) ? pRCAP->pClientIDs[i++] : 0;
+ }
+
+ assert(numEnabledRCAPs >= 1);
+ if (!oneclient && --numEnabledRCAPs == 0)
+ { /* we're disabling the last context */
+ DeleteCallback(&EventCallback, RecordADeliveredEventOrError, NULL);
+ DeleteCallback(&DeviceEventCallback, RecordADeviceEvent, NULL);
+ DeleteCallback(&ReplyCallback, RecordAReply, NULL);
+ DeleteCallback(&SkippedRequestsCallback, RecordASkippedRequest, NULL);
+ DeleteCallback(&FlushCallback, RecordFlushAllContexts, NULL);
+ /* Alternate context flushing scheme: delete the line above
+ * and call RemoveBlockAndWakeupHandlers here passing
+ * RecordFlushAllContexts. Is this any better?
+ */
+ /* Having deleted the callback, call it one last time. -gildea */
+ RecordFlushAllContexts(&FlushCallback, NULL, NULL);
+ }
+} /* RecordUninstallHooks */
+
+
+/* RecordDeleteClientFromRCAP
+ *
+ * Arguments:
+ * pRCAP is an RCAP to delete the client from.
+ * position is the index into the array pRCAP->pClientIDs of the
+ * client to delete.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Recording hooks needed by client will be uninstalled if the context
+ * is enabled. The designated client will be removed from the
+ * pRCAP->pClientIDs array. If it was the only client on the RCAP,
+ * the RCAP is removed from the context and freed. (Invariant: RCAPs
+ * have at least one client.)
+ */
+static void
+RecordDeleteClientFromRCAP(pRCAP, position)
+ RecordClientsAndProtocolPtr pRCAP;
+ int position;
+{
+ if (pRCAP->pContext->pRecordingClient)
+ RecordUninstallHooks(pRCAP, pRCAP->pClientIDs[position]);
+ if (position != pRCAP->numClients - 1)
+ pRCAP->pClientIDs[position] = pRCAP->pClientIDs[pRCAP->numClients - 1];
+ if (--pRCAP->numClients == 0)
+ { /* no more clients; remove RCAP from context's list */
+ RecordContextPtr pContext = pRCAP->pContext;
+ if (pContext->pRecordingClient)
+ RecordUninstallHooks(pRCAP, 0);
+ if (pContext->pListOfRCAP == pRCAP)
+ pContext->pListOfRCAP = pRCAP->pNextRCAP;
+ else
+ {
+ RecordClientsAndProtocolPtr prevRCAP;
+ for (prevRCAP = pContext->pListOfRCAP;
+ prevRCAP->pNextRCAP != pRCAP;
+ prevRCAP = prevRCAP->pNextRCAP)
+ ;
+ prevRCAP->pNextRCAP = pRCAP->pNextRCAP;
+ }
+ /* free the RCAP */
+ if (pRCAP->clientIDsSeparatelyAllocated)
+ xfree(pRCAP->pClientIDs);
+ xfree(pRCAP);
+ }
+} /* RecordDeleteClientFromRCAP */
+
+
+/* RecordAddClientToRCAP
+ *
+ * Arguments:
+ * pRCAP is an RCAP to add the client to.
+ * clientspec is the resource ID mask identifying a client, or
+ * XRecordFutureClients.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Recording hooks needed by client will be installed if the context
+ * is enabled. The designated client will be added to the
+ * pRCAP->pClientIDs array, which may be realloced.
+ * pRCAP->clientIDsSeparatelyAllocated may be set to 1 if there
+ * is no more room to hold clients internal to the RCAP.
+ */
+static void
+RecordAddClientToRCAP(pRCAP, clientspec)
+ RecordClientsAndProtocolPtr pRCAP;
+ XID clientspec;
+{
+ if (pRCAP->numClients == pRCAP->sizeClients)
+ {
+ if (pRCAP->clientIDsSeparatelyAllocated)
+ {
+ XID *pNewIDs = (XID *)xrealloc(pRCAP->pClientIDs,
+ (pRCAP->sizeClients + CLIENT_ARRAY_GROWTH_INCREMENT) *
+ sizeof(XID));
+ if (!pNewIDs)
+ return;
+ pRCAP->pClientIDs = pNewIDs;
+ pRCAP->sizeClients += CLIENT_ARRAY_GROWTH_INCREMENT;
+ }
+ else
+ {
+ XID *pNewIDs = (XID *)xalloc((pRCAP->sizeClients +
+ CLIENT_ARRAY_GROWTH_INCREMENT) * sizeof(XID));
+ if (!pNewIDs)
+ return;
+ memcpy(pNewIDs, pRCAP->pClientIDs, pRCAP->numClients *sizeof(XID));
+ pRCAP->pClientIDs = pNewIDs;
+ pRCAP->sizeClients += CLIENT_ARRAY_GROWTH_INCREMENT;
+ pRCAP->clientIDsSeparatelyAllocated = 1;
+ }
+ }
+ pRCAP->pClientIDs[pRCAP->numClients++] = clientspec;
+ if (pRCAP->pContext->pRecordingClient)
+ RecordInstallHooks(pRCAP, clientspec);
+} /* RecordDeleteClientFromRCAP */
+
+
+/* RecordDeleteClientFromContext
+ *
+ * Arguments:
+ * pContext is the context to delete from.
+ * clientspec is the resource ID mask identifying a client, or
+ * XRecordFutureClients.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * If clientspec is on any RCAP of the context, it is deleted from that
+ * RCAP. (A given clientspec can only be on one RCAP of a context.)
+ */
+static void
+RecordDeleteClientFromContext(pContext, clientspec)
+ RecordContextPtr pContext;
+ XID clientspec;
+{
+ RecordClientsAndProtocolPtr pRCAP;
+ int position;
+
+ if (pRCAP = RecordFindClientOnContext(pContext, clientspec, &position))
+ RecordDeleteClientFromRCAP(pRCAP, position);
+} /* RecordDeleteClientFromContext */
+
+
+/* RecordSanityCheckClientSpecifiers
+ *
+ * Arguments:
+ * clientspecs is an array of alleged CLIENTSPECs passed by the client.
+ * nspecs is the number of elements in clientspecs.
+ * errorspec, if non-zero, is the resource id base of a client that
+ * must not appear in clienspecs.
+ *
+ * Returns: BadMatch if any of the clientspecs are invalid, else Success.
+ *
+ * Side Effects: none.
+ */
+static int
+RecordSanityCheckClientSpecifiers(clientspecs, nspecs, errorspec)
+ XID *clientspecs;
+ int nspecs;
+ XID errorspec;
+{
+ int i;
+ int clientIndex;
+
+ for (i = 0; i < nspecs; i++)
+ {
+ if (clientspecs[i] == XRecordCurrentClients ||
+ clientspecs[i] == XRecordFutureClients ||
+ clientspecs[i] == XRecordAllClients)
+ continue;
+ if (errorspec && (CLIENT_BITS(clientspecs[i]) == errorspec) )
+ return BadMatch;
+ clientIndex = CLIENT_ID(clientspecs[i]);
+ if (clientIndex && clients[clientIndex] &&
+ clients[clientIndex]->clientState == ClientStateRunning)
+ {
+ if (clientspecs[i] == clients[clientIndex]->clientAsMask)
+ continue;
+ if (!LookupIDByClass(clientspecs[i], RC_ANY))
+ return BadMatch;
+ }
+ else
+ return BadMatch;
+ }
+ return Success;
+} /* RecordSanityCheckClientSpecifiers */
+
+
+/* RecordCanonicalizeClientSpecifiers
+ *
+ * Arguments:
+ * pClientspecs is an array of CLIENTSPECs that have been sanity
+ * checked.
+ * pNumClientspecs is a pointer to the number of elements in pClientspecs.
+ * excludespec, if non-zero, is the resource id base of a client that
+ * should not be included in the expansion of XRecordAllClients or
+ * XRecordCurrentClients.
+ *
+ * Returns:
+ * A pointer to an array of CLIENTSPECs that is the same as the
+ * passed array with the following modifications:
+ * - all but the client id bits of resource IDs are stripped off.
+ * - duplicates removed.
+ * - XRecordAllClients expanded to a list of all currently connected
+ * clients + XRecordFutureClients - excludespec (if non-zero)
+ * - XRecordCurrentClients expanded to a list of all currently
+ * connected clients - excludespec (if non-zero)
+ * The returned array may be the passed array modified in place, or
+ * it may be an Xalloc'ed array. The caller should keep a pointer to the
+ * original array and free the returned array if it is different.
+ *
+ * *pNumClientspecs is set to the number of elements in the returned
+ * array.
+ *
+ * Side Effects:
+ * pClientspecs may be modified in place.
+ */
+static XID *
+RecordCanonicalizeClientSpecifiers(pClientspecs, pNumClientspecs, excludespec)
+ XID *pClientspecs;
+ int *pNumClientspecs;
+ XID excludespec;
+{
+ int i;
+ int numClients = *pNumClientspecs;
+
+ /* first pass strips off the resource index bits, leaving just the
+ * client id bits. This makes searching for a particular client simpler
+ * (and faster.)
+ */
+ for (i = 0; i < numClients; i++)
+ {
+ XID cs = pClientspecs[i];
+ if (cs > XRecordAllClients)
+ pClientspecs[i] = CLIENT_BITS(cs);
+ }
+
+ for (i = 0; i < numClients; i++)
+ {
+ if (pClientspecs[i] == XRecordAllClients ||
+ pClientspecs[i] == XRecordCurrentClients)
+ { /* expand All/Current */
+ int j, nc;
+ XID *pCanon = (XID *)xalloc(sizeof(XID) * (currentMaxClients + 1));
+ if (!pCanon) return NULL;
+ for (nc = 0, j = 1; j < currentMaxClients; j++)
+ {
+ ClientPtr client = clients[j];
+ if (client != NullClient &&
+ client->clientState == ClientStateRunning &&
+ client->clientAsMask != excludespec)
+ {
+ pCanon[nc++] = client->clientAsMask;
+ }
+ }
+ if (pClientspecs[i] == XRecordAllClients)
+ pCanon[nc++] = XRecordFutureClients;
+ *pNumClientspecs = nc;
+ return pCanon;
+ }
+ else /* not All or Current */
+ {
+ int j;
+ for (j = i + 1; j < numClients; )
+ {
+ if (pClientspecs[i] == pClientspecs[j])
+ {
+ pClientspecs[j] = pClientspecs[--numClients];
+ }
+ else
+ j++;
+ }
+ }
+ } /* end for each clientspec */
+ *pNumClientspecs = numClients;
+ return pClientspecs;
+} /* RecordCanonicalizeClientSpecifiers */
+
+
+/****************************************************************************/
+
+/* stuff for RegisterClients */
+
+/* RecordPadAlign
+ *
+ * Arguments:
+ * size is the number of bytes taken by an object.
+ * align is a byte boundary (e.g. 4, 8)
+ *
+ * Returns:
+ * the number of pad bytes to add at the end of an object of the
+ * given size so that an object placed immediately behind it will
+ * begin on an <align>-byte boundary.
+ *
+ * Side Effects: none.
+ */
+static int
+RecordPadAlign(size, align)
+ int size;
+ int align;
+{
+ return (align - (size & (align - 1))) & (align - 1);
+} /* RecordPadAlign */
+
+
+/* RecordSanityCheckRegisterClients
+ *
+ * Arguments:
+ * pContext is the context being registered on.
+ * client is the client that issued a RecordCreateContext or
+ * RecordRegisterClients request.
+ * stuff is a pointer to the request.
+ *
+ * Returns:
+ * Any one of several possible error values if any of the request
+ * arguments are invalid. Success if everything is OK.
+ *
+ * Side Effects: none.
+ */
+static int
+RecordSanityCheckRegisterClients(pContext, client, stuff)
+ RecordContextPtr pContext;
+ ClientPtr client;
+ xRecordRegisterClientsReq *stuff;
+{
+ int err;
+ xRecordRange *pRange;
+ int i;
+ XID recordingClient;
+
+ if (((client->req_len << 2) - SIZEOF(xRecordRegisterClientsReq)) !=
+ 4 * stuff->nClients + SIZEOF(xRecordRange) * stuff->nRanges)
+ return BadLength;
+
+ if (stuff->elementHeader &
+ ~(XRecordFromClientSequence|XRecordFromClientTime|XRecordFromServerTime))
+ {
+ client->errorValue = stuff->elementHeader;
+ return BadValue;
+ }
+
+ recordingClient = pContext->pRecordingClient ?
+ pContext->pRecordingClient->clientAsMask : 0;
+ err = RecordSanityCheckClientSpecifiers((XID *)&stuff[1], stuff->nClients,
+ recordingClient);
+ if (err != Success) return err;
+
+ pRange = (xRecordRange *)(((XID *)&stuff[1]) + stuff->nClients);
+ for (i = 0; i < stuff->nRanges; i++, pRange++)
+ {
+ if (pRange->coreRequestsFirst > pRange->coreRequestsLast)
+ {
+ client->errorValue = pRange->coreRequestsFirst;
+ return BadValue;
+ }
+ if (pRange->coreRepliesFirst > pRange->coreRepliesLast)
+ {
+ client->errorValue = pRange->coreRepliesFirst;
+ return BadValue;
+ }
+ if ((pRange->extRequestsMajorFirst || pRange->extRequestsMajorLast) &&
+ (pRange->extRequestsMajorFirst < 128 ||
+ pRange->extRequestsMajorLast < 128 ||
+ pRange->extRequestsMajorFirst > pRange->extRequestsMajorLast))
+ {
+ client->errorValue = pRange->extRequestsMajorFirst;
+ return BadValue;
+ }
+ if (pRange->extRequestsMinorFirst > pRange->extRequestsMinorLast)
+ {
+ client->errorValue = pRange->extRequestsMinorFirst;
+ return BadValue;
+ }
+ if ((pRange->extRepliesMajorFirst || pRange->extRepliesMajorLast) &&
+ (pRange->extRepliesMajorFirst < 128 ||
+ pRange->extRepliesMajorLast < 128 ||
+ pRange->extRepliesMajorFirst > pRange->extRepliesMajorLast))
+ {
+ client->errorValue = pRange->extRepliesMajorFirst;
+ return BadValue;
+ }
+ if (pRange->extRepliesMinorFirst > pRange->extRepliesMinorLast)
+ {
+ client->errorValue = pRange->extRepliesMinorFirst;
+ return BadValue;
+ }
+ if ((pRange->deliveredEventsFirst || pRange->deliveredEventsLast) &&
+ (pRange->deliveredEventsFirst < 2 ||
+ pRange->deliveredEventsLast < 2 ||
+ pRange->deliveredEventsFirst > pRange->deliveredEventsLast))
+ {
+ client->errorValue = pRange->deliveredEventsFirst;
+ return BadValue;
+ }
+ if ((pRange->deviceEventsFirst || pRange->deviceEventsLast) &&
+ (pRange->deviceEventsFirst < 2 ||
+ pRange->deviceEventsLast < 2 ||
+ pRange->deviceEventsFirst > pRange->deviceEventsLast))
+ {
+ client->errorValue = pRange->deviceEventsFirst;
+ return BadValue;
+ }
+ if (pRange->errorsFirst > pRange->errorsLast)
+ {
+ client->errorValue = pRange->errorsFirst;
+ return BadValue;
+ }
+ if (pRange->clientStarted != xFalse && pRange->clientStarted != xTrue)
+ {
+ client->errorValue = pRange->clientStarted;
+ return BadValue;
+ }
+ if (pRange->clientDied != xFalse && pRange->clientDied != xTrue)
+ {
+ client->errorValue = pRange->clientDied;
+ return BadValue;
+ }
+ } /* end for each range */
+ return Success;
+} /* end RecordSanityCheckRegisterClients */
+
+/* This is a tactical structure used to gather information about all the sets
+ * (RecordSetPtr) that need to be created for an RCAP in the process of
+ * digesting a list of RECORDRANGEs (converting it to the internal
+ * representation).
+ */
+typedef struct
+{
+ int nintervals; /* number of intervals in following array */
+ RecordSetInterval *intervals; /* array of intervals for this set */
+ int size; /* size of intevals array; >= nintervals */
+ int align; /* alignment restriction for set */
+ int offset; /* where to store set pointer rel. to start of RCAP */
+ short first, last; /* if for extension, major opcode interval */
+} SetInfoRec, *SetInfoPtr;
+
+/* These constant are used to index into an array of SetInfoRec. */
+enum {REQ, /* set info for requests */
+ REP, /* set info for replies */
+ ERR, /* set info for errors */
+ DEV, /* set info for device events */
+ DLEV, /* set info for delivered events */
+ PREDEFSETS}; /* number of predefined array entries */
+
+
+/* RecordAllocIntervals
+ *
+ * Arguments:
+ * psi is a pointer to a SetInfoRec whose intervals pointer is NULL.
+ * nIntervals is the desired size of the intervals array.
+ *
+ * Returns: BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ * If Success is returned, psi->intervals is a pointer to size
+ * RecordSetIntervals, all zeroed, and psi->size is set to size.
+ */
+static int
+RecordAllocIntervals(psi, nIntervals)
+ SetInfoPtr psi;
+ int nIntervals;
+{
+ assert(!psi->intervals);
+ psi->intervals = (RecordSetInterval *)
+ xalloc(nIntervals * sizeof(RecordSetInterval));
+ if (!psi->intervals)
+ return BadAlloc;
+ bzero(psi->intervals, nIntervals * sizeof(RecordSetInterval));
+ psi->size = nIntervals;
+ return Success;
+} /* end RecordAllocIntervals */
+
+
+/* RecordConvertRangesToIntervals
+ *
+ * Arguments:
+ * psi is a pointer to the SetInfoRec we are building.
+ * pRanges is an array of xRecordRanges.
+ * nRanges is the number of elements in pRanges.
+ * byteoffset is the offset from the start of an xRecordRange of the
+ * two bytes (1 for first, 1 for last) we are interested in.
+ * pExtSetInfo, if non-NULL, indicates that the two bytes mentioned
+ * above are followed by four bytes (2 for first, 2 for last)
+ * representing a minor opcode range, and this information should be
+ * stored in one of the SetInfoRecs starting at pExtSetInfo.
+ * pnExtSetInfo is the number of elements in the pExtSetInfo array.
+ *
+ * Returns: BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ * The slice of pRanges indicated by byteoffset is stored in psi.
+ * If pExtSetInfo is non-NULL, minor opcode intervals are stored
+ * in an existing SetInfoRec if the major opcode interval matches, else
+ * they are stored in a new SetInfoRec, and *pnExtSetInfo is
+ * increased accordingly.
+ */
+static int
+RecordConvertRangesToIntervals(psi, pRanges, nRanges, byteoffset,
+ pExtSetInfo, pnExtSetInfo)
+ SetInfoPtr psi;
+ xRecordRange *pRanges;
+ int nRanges;
+ int byteoffset;
+ SetInfoPtr pExtSetInfo;
+ int *pnExtSetInfo;
+{
+ int i;
+ CARD8 *pCARD8;
+ int first, last;
+ int err;
+
+ for (i = 0; i < nRanges; i++, pRanges++)
+ {
+ pCARD8 = ((CARD8 *)pRanges) + byteoffset;
+ first = pCARD8[0];
+ last = pCARD8[1];
+ if (first || last)
+ {
+ if (!psi->intervals)
+ {
+ err = RecordAllocIntervals(psi, 2 * (nRanges - i));
+ if (err != Success)
+ return err;
+ }
+ psi->intervals[psi->nintervals].first = first;
+ psi->intervals[psi->nintervals].last = last;
+ psi->nintervals++;
+ assert(psi->nintervals <= psi->size);
+ if (pExtSetInfo)
+ {
+ SetInfoPtr pesi = pExtSetInfo;
+ CARD16 *pCARD16 = (CARD16 *)(pCARD8 + 2);
+ int j;
+
+ for (j = 0; j < *pnExtSetInfo; j++, pesi++)
+ {
+ if ( (first == pesi->first) && (last == pesi->last) )
+ break;
+ }
+ if (j == *pnExtSetInfo)
+ {
+ err = RecordAllocIntervals(pesi, 2 * (nRanges - i));
+ if (err != Success)
+ return err;
+ pesi->first = first;
+ pesi->last = last;
+ (*pnExtSetInfo)++;
+ }
+ pesi->intervals[pesi->nintervals].first = pCARD16[0];
+ pesi->intervals[pesi->nintervals].last = pCARD16[1];
+ pesi->nintervals++;
+ assert(pesi->nintervals <= pesi->size);
+ }
+ }
+ }
+ return Success;
+} /* end RecordConvertRangesToIntervals */
+
+#define offset_of(_structure, _field) \
+ ((char *)(& (_structure . _field)) - (char *)(&_structure))
+
+/* RecordRegisterClients
+ *
+ * Arguments:
+ * pContext is the context on which to register the clients.
+ * client is the client that issued the RecordCreateContext or
+ * RecordRegisterClients request.
+ * stuff is a pointer to the request.
+ *
+ * Returns:
+ * Any one of several possible error values defined by the protocol.
+ * Success if everything is OK.
+ *
+ * Side Effects:
+ * If different element headers are specified, the context is flushed.
+ * If any of the specified clients are already registered on the
+ * context, they are first unregistered. A new RCAP is created to
+ * hold the specified protocol and clients, and it is linked onto the
+ * context. If the context is enabled, appropriate hooks are installed
+ * to record the new clients and protocol.
+ */
+static int
+RecordRegisterClients(pContext, client, stuff)
+ RecordContextPtr pContext;
+ ClientPtr client;
+ xRecordRegisterClientsReq *stuff;
+{
+ int err;
+ int i;
+ SetInfoPtr si;
+ int maxSets;
+ int nExtReqSets = 0;
+ int nExtRepSets = 0;
+ int extReqSetsOffset;
+ int extRepSetsOffset;
+ SetInfoPtr pExtReqSets, pExtRepSets;
+ int clientListOffset;
+ XID *pCanonClients;
+ int clientStarted = 0, clientDied = 0;
+ xRecordRange *pRanges, rr;
+ int nClients;
+ int sizeClients;
+ int totRCAPsize;
+ RecordClientsAndProtocolPtr pRCAP;
+ int pad;
+ XID recordingClient;
+
+ /* do all sanity checking up front */
+
+ err = RecordSanityCheckRegisterClients(pContext, client, stuff);
+ if (err != Success)
+ return err;
+
+ /* if element headers changed, flush buffer */
+
+ if (pContext->elemHeaders != stuff->elementHeader)
+ {
+ RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0);
+ pContext->elemHeaders = stuff->elementHeader;
+ }
+
+ nClients = stuff->nClients;
+ if (!nClients)
+ /* if empty clients list, we're done. */
+ return Success;
+
+ recordingClient = pContext->pRecordingClient ?
+ pContext->pRecordingClient->clientAsMask : 0;
+ pCanonClients = RecordCanonicalizeClientSpecifiers((XID *)&stuff[1],
+ &nClients, recordingClient);
+ if (!pCanonClients)
+ return BadAlloc;
+
+ /* We may have to create as many as one set for each "predefined"
+ * protocol types, plus one per range for extension reuests, plus one per
+ * range for extension replies.
+ */
+ maxSets = PREDEFSETS + 2 * stuff->nRanges;
+ si = (SetInfoPtr)ALLOCATE_LOCAL(sizeof(SetInfoRec) * maxSets);
+ if (!si)
+ {
+ err = BadAlloc;
+ goto bailout;
+ }
+ bzero(si, sizeof(SetInfoRec) * maxSets);
+
+ /* theoretically you must do this because NULL may not be all-bits-zero */
+ for (i = 0; i < maxSets; i++)
+ si[i].intervals = NULL;
+
+ pExtReqSets = si + PREDEFSETS;
+ pExtRepSets = pExtReqSets + stuff->nRanges;
+
+ pRanges = (xRecordRange *)(((XID *)&stuff[1]) + stuff->nClients);
+
+ err = RecordConvertRangesToIntervals(&si[REQ], pRanges, stuff->nRanges,
+ offset_of(rr, coreRequestsFirst), NULL, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertRangesToIntervals(&si[REQ], pRanges, stuff->nRanges,
+ offset_of(rr, extRequestsMajorFirst), pExtReqSets, &nExtReqSets);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertRangesToIntervals(&si[REP], pRanges, stuff->nRanges,
+ offset_of(rr, coreRepliesFirst), NULL, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertRangesToIntervals(&si[REP], pRanges, stuff->nRanges,
+ offset_of(rr, extRepliesMajorFirst), pExtRepSets, &nExtRepSets);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertRangesToIntervals(&si[ERR], pRanges, stuff->nRanges,
+ offset_of(rr, errorsFirst), NULL, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertRangesToIntervals(&si[DLEV], pRanges, stuff->nRanges,
+ offset_of(rr, deliveredEventsFirst), NULL, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertRangesToIntervals(&si[DEV], pRanges, stuff->nRanges,
+ offset_of(rr, deviceEventsFirst), NULL, NULL);
+ if (err != Success) goto bailout;
+
+ /* collect client-started and client-died */
+
+ for (i = 0; i < stuff->nRanges; i++)
+ {
+ if (pRanges[i].clientStarted) clientStarted = TRUE;
+ if (pRanges[i].clientDied) clientDied = TRUE;
+ }
+
+ /* We now have all the information collected to create all the sets,
+ * and we can compute the total memory required for the RCAP.
+ */
+
+ totRCAPsize = sizeof(RecordClientsAndProtocolRec);
+
+ /* leave a little room to grow before forcing a separate allocation */
+ sizeClients = nClients + CLIENT_ARRAY_GROWTH_INCREMENT;
+ pad = RecordPadAlign(totRCAPsize, sizeof(XID));
+ clientListOffset = totRCAPsize + pad;
+ totRCAPsize += pad + sizeClients * sizeof(XID);
+
+ if (nExtReqSets)
+ {
+ pad = RecordPadAlign(totRCAPsize, sizeof(RecordSetPtr));
+ extReqSetsOffset = totRCAPsize + pad;
+ totRCAPsize += pad + (nExtReqSets + 1) * sizeof(RecordMinorOpRec);
+ }
+ if (nExtRepSets)
+ {
+ pad = RecordPadAlign(totRCAPsize, sizeof(RecordSetPtr));
+ extRepSetsOffset = totRCAPsize + pad;
+ totRCAPsize += pad + (nExtRepSets + 1) * sizeof(RecordMinorOpRec);
+ }
+
+ for (i = 0; i < maxSets; i++)
+ {
+ if (si[i].nintervals)
+ {
+ si[i].size = RecordSetMemoryRequirements(
+ si[i].intervals, si[i].nintervals, &si[i].align);
+ pad = RecordPadAlign(totRCAPsize, si[i].align);
+ si[i].offset = pad + totRCAPsize;
+ totRCAPsize += pad + si[i].size;
+ }
+ }
+
+ /* allocate memory for the whole RCAP */
+
+ pRCAP = (RecordClientsAndProtocolPtr)xalloc(totRCAPsize);
+ if (!pRCAP)
+ {
+ err = BadAlloc;
+ goto bailout;
+ }
+
+ /* fill in the RCAP */
+
+ pRCAP->pContext = pContext;
+ pRCAP->pClientIDs = (XID *)((char *)pRCAP + clientListOffset);
+ pRCAP->numClients = nClients;
+ pRCAP->sizeClients = sizeClients;
+ pRCAP->clientIDsSeparatelyAllocated = 0;
+ for (i = 0; i < nClients; i++)
+ {
+ RecordDeleteClientFromContext(pContext, pCanonClients[i]);
+ pRCAP->pClientIDs[i] = pCanonClients[i];
+ }
+
+ /* create all the sets */
+
+ if (si[REQ].intervals)
+ {
+ pRCAP->pRequestMajorOpSet =
+ RecordCreateSet(si[REQ].intervals, si[REQ].nintervals,
+ (RecordSetPtr)((char *)pRCAP + si[REQ].offset), si[REQ].size);
+ }
+ else pRCAP->pRequestMajorOpSet = NULL;
+
+ if (si[REP].intervals)
+ {
+ pRCAP->pReplyMajorOpSet =
+ RecordCreateSet(si[REP].intervals, si[REP].nintervals,
+ (RecordSetPtr)((char *)pRCAP + si[REP].offset), si[REP].size);
+ }
+ else pRCAP->pReplyMajorOpSet = NULL;
+
+ if (si[ERR].intervals)
+ {
+ pRCAP->pErrorSet =
+ RecordCreateSet(si[ERR].intervals, si[ERR].nintervals,
+ (RecordSetPtr)((char *)pRCAP + si[ERR].offset), si[ERR].size);
+ }
+ else pRCAP->pErrorSet = NULL;
+
+ if (si[DEV].intervals)
+ {
+ pRCAP->pDeviceEventSet =
+ RecordCreateSet(si[DEV].intervals, si[DEV].nintervals,
+ (RecordSetPtr)((char *)pRCAP + si[DEV].offset), si[DEV].size);
+ }
+ else pRCAP->pDeviceEventSet = NULL;
+
+ if (si[DLEV].intervals)
+ {
+ pRCAP->pDeliveredEventSet =
+ RecordCreateSet(si[DLEV].intervals, si[DLEV].nintervals,
+ (RecordSetPtr)((char *)pRCAP + si[DLEV].offset), si[DLEV].size);
+ }
+ else pRCAP->pDeliveredEventSet = NULL;
+
+ if (nExtReqSets)
+ {
+ pRCAP->pRequestMinOpInfo = (RecordMinorOpPtr)
+ ((char *)pRCAP + extReqSetsOffset);
+ pRCAP->pRequestMinOpInfo[0].count = nExtReqSets;
+ for (i = 0; i < nExtReqSets; i++, pExtReqSets++)
+ {
+ pRCAP->pRequestMinOpInfo[i+1].major.first = pExtReqSets->first;
+ pRCAP->pRequestMinOpInfo[i+1].major.last = pExtReqSets->last;
+ pRCAP->pRequestMinOpInfo[i+1].major.pMinOpSet =
+ RecordCreateSet(pExtReqSets->intervals,
+ pExtReqSets->nintervals,
+ (RecordSetPtr)((char *)pRCAP + pExtReqSets->offset),
+ pExtReqSets->size);
+ }
+ }
+ else pRCAP->pRequestMinOpInfo = NULL;
+
+ if (nExtRepSets)
+ {
+ pRCAP->pReplyMinOpInfo = (RecordMinorOpPtr)
+ ((char *)pRCAP + extRepSetsOffset);
+ pRCAP->pReplyMinOpInfo[0].count = nExtRepSets;
+ for (i = 0; i < nExtRepSets; i++, pExtRepSets++)
+ {
+ pRCAP->pReplyMinOpInfo[i+1].major.first = pExtRepSets->first;
+ pRCAP->pReplyMinOpInfo[i+1].major.last = pExtRepSets->last;
+ pRCAP->pReplyMinOpInfo[i+1].major.pMinOpSet =
+ RecordCreateSet(pExtRepSets->intervals,
+ pExtRepSets->nintervals,
+ (RecordSetPtr)((char *)pRCAP + pExtRepSets->offset),
+ pExtRepSets->size);
+ }
+ }
+ else pRCAP->pReplyMinOpInfo = NULL;
+
+ pRCAP->clientStarted = clientStarted;
+ pRCAP->clientDied = clientDied;
+
+ /* link the RCAP onto the context */
+
+ pRCAP->pNextRCAP = pContext->pListOfRCAP;
+ pContext->pListOfRCAP = pRCAP;
+
+ if (pContext->pRecordingClient) /* context enabled */
+ RecordInstallHooks(pRCAP, 0);
+
+bailout:
+ if (si)
+ {
+ for (i = 0; i < maxSets; i++)
+ if (si[i].intervals)
+ xfree(si[i].intervals);
+ DEALLOCATE_LOCAL(si);
+ }
+ if (pCanonClients && pCanonClients != (XID *)&stuff[1])
+ xfree(pCanonClients);
+ return err;
+} /* RecordRegisterClients */
+
+
+/* Proc functions all take a client argument, execute the request in
+ * client->requestBuffer, and return a protocol error status.
+ */
+
+static int
+ProcRecordQueryVersion(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordQueryVersionReq);
+ xRecordQueryVersionReply rep;
+ int n;
+
+ REQUEST_SIZE_MATCH(xRecordQueryVersionReq);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.majorVersion = RECORD_MAJOR_VERSION;
+ rep.minorVersion = RECORD_MINOR_VERSION;
+ if(client->swapped)
+ {
+ swaps(&rep.sequenceNumber, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ }
+ (void)WriteToClient(client, sizeof(xRecordQueryVersionReply),
+ (char *)&rep);
+ return (client->noClientException);
+} /* ProcRecordQueryVersion */
+
+
+static int
+ProcRecordCreateContext(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordCreateContextReq);
+ RecordContextPtr pContext;
+ RecordContextPtr *ppNewAllContexts = NULL;
+ int err = BadAlloc;
+
+ REQUEST_AT_LEAST_SIZE(xRecordCreateContextReq);
+ LEGAL_NEW_RESOURCE(stuff->context, client);
+
+ pContext = (RecordContextPtr)xalloc(sizeof(RecordContextRec));
+ if (!pContext)
+ goto bailout;
+
+ /* make sure there is room in ppAllContexts to store the new context */
+
+ ppNewAllContexts = (RecordContextPtr *)
+ xrealloc(ppAllContexts, sizeof(RecordContextPtr) * (numContexts + 1));
+ if (!ppNewAllContexts)
+ goto bailout;
+ ppAllContexts = ppNewAllContexts;
+
+ pContext->id = stuff->context;
+ pContext->pRecordingClient = NULL;
+ pContext->pListOfRCAP = NULL;
+ pContext->elemHeaders = 0;
+ pContext->bufCategory = 0;
+ pContext->numBufBytes = 0;
+ pContext->pBufClient = NULL;
+ pContext->continuedReply = 0;
+
+ err = RecordRegisterClients(pContext, client,
+ (xRecordRegisterClientsReq *)stuff);
+ if (err != Success)
+ goto bailout;
+
+ if (AddResource(pContext->id, RTContext, pContext))
+ {
+ ppAllContexts[numContexts++] = pContext;
+ return Success;
+ }
+ else
+ {
+ RecordDeleteContext((pointer)pContext, pContext->id);
+ err = BadAlloc;
+ }
+bailout:
+ if (pContext)
+ xfree(pContext);
+ return err;
+} /* ProcRecordCreateContext */
+
+
+static int
+ProcRecordRegisterClients(client)
+ ClientPtr client;
+{
+ RecordContextPtr pContext;
+ REQUEST(xRecordRegisterClientsReq);
+
+ REQUEST_AT_LEAST_SIZE(xRecordRegisterClientsReq);
+ VERIFY_CONTEXT(pContext, stuff->context, client);
+
+ return RecordRegisterClients(pContext, client, stuff);
+} /* ProcRecordRegisterClients */
+
+
+static int
+ProcRecordUnregisterClients(client)
+ ClientPtr client;
+{
+ RecordContextPtr pContext;
+ int err;
+ REQUEST(xRecordUnregisterClientsReq);
+ XID *pCanonClients;
+ int nClients;
+ int i;
+
+ REQUEST_AT_LEAST_SIZE(xRecordUnregisterClientsReq);
+ if ((client->req_len << 2) - SIZEOF(xRecordUnregisterClientsReq) !=
+ 4 * stuff->nClients)
+ return BadLength;
+ VERIFY_CONTEXT(pContext, stuff->context, client);
+ err = RecordSanityCheckClientSpecifiers((XID *)&stuff[1],
+ stuff->nClients, 0);
+ if (err != Success)
+ return err;
+
+ nClients = stuff->nClients;
+ pCanonClients = RecordCanonicalizeClientSpecifiers((XID *)&stuff[1],
+ &nClients, 0);
+ if (!pCanonClients)
+ return BadAlloc;
+
+ for (i = 0; i < nClients; i++)
+ {
+ RecordDeleteClientFromContext(pContext, pCanonClients[i]);
+ }
+ if (pCanonClients != (XID *)&stuff[1])
+ xfree(pCanonClients);
+ return Success;
+} /* ProcRecordUnregisterClients */
+
+
+/****************************************************************************/
+
+/* stuff for GetContext */
+
+/* This is a tactical structure used to hold the xRecordRanges as they are
+ * being reconstituted from the sets in the RCAPs.
+ */
+
+typedef struct {
+ xRecordRange *pRanges; /* array of xRecordRanges for one RCAP */
+ int size; /* number of elements in pRanges, >= nRanges */
+ int nRanges; /* number of occupied element of pRanges */
+} GetContextRangeInfoRec, *GetContextRangeInfoPtr;
+
+
+/* RecordAllocRanges
+ *
+ * Arguments:
+ * pri is a pointer to a GetContextRangeInfoRec to allocate for.
+ * nRanges is the number of xRecordRanges desired for pri.
+ *
+ * Returns: BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ * If Success is returned, pri->pRanges points to at least nRanges
+ * ranges. pri->nRanges is set to nRanges. pri->size is the actual
+ * number of ranges. Newly allocated ranges are zeroed.
+ */
+static int
+RecordAllocRanges(pri, nRanges)
+ GetContextRangeInfoPtr pri;
+ int nRanges;
+{
+ int newsize;
+ xRecordRange *pNewRange;
+#define SZINCR 8
+
+ newsize = max(pri->size + SZINCR, nRanges);
+ pNewRange = (xRecordRange *)xrealloc(pri->pRanges,
+ newsize * sizeof(xRecordRange));
+ if (!pNewRange)
+ return BadAlloc;
+
+ pri->pRanges = pNewRange;
+ pri->size = newsize;
+ bzero(&pri->pRanges[pri->size - SZINCR], SZINCR * sizeof(xRecordRange));
+ if (pri->nRanges < nRanges)
+ pri->nRanges = nRanges;
+ return Success;
+} /* RecordAllocRanges */
+
+
+/* RecordConvertSetToRanges
+ *
+ * Arguments:
+ * pSet is the set to be converted.
+ * pri is where the result should be stored.
+ * byteoffset is the offset from the start of an xRecordRange of the
+ * two vales (first, last) we are interested in.
+ * card8 is TRUE if the vales are one byte each and FALSE if two bytes
+ * each.
+ * imax is the largest set value to store in pri->pRanges.
+ * pStartIndex, if non-NULL, is the index of the first range in
+ * pri->pRanges that should be stored to. If NULL,
+ * start at index 0.
+ *
+ * Returns: BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ * If Success is returned, the slice of pri->pRanges indicated by
+ * byteoffset and card8 is filled in with the intervals from pSet.
+ * if pStartIndex was non-NULL, *pStartIndex is filled in with one
+ * more than the index of the last xRecordRange that was touched.
+ */
+static int
+RecordConvertSetToRanges(pSet, pri, byteoffset, card8, imax, pStartIndex)
+ RecordSetPtr pSet;
+ GetContextRangeInfoPtr pri;
+ int byteoffset;
+ Bool card8;
+ unsigned int imax;
+ int *pStartIndex;
+{
+ int nRanges;
+ RecordSetIteratePtr pIter = NULL;
+ RecordSetInterval interval;
+ CARD8 *pCARD8;
+ CARD16 *pCARD16;
+ int err;
+
+ if (!pSet)
+ return Success;
+
+ nRanges = pStartIndex ? *pStartIndex : 0;
+ while (pIter = RecordIterateSet(pSet, pIter, &interval))
+ {
+ if (interval.first > imax) break;
+ if (interval.last > imax) interval.last = imax;
+ nRanges++;
+ if (nRanges > pri->size)
+ {
+ err = RecordAllocRanges(pri, nRanges);
+ if (err != Success)
+ return err;
+ }
+ else
+ pri->nRanges = max(pri->nRanges, nRanges);
+ if (card8)
+ {
+ pCARD8 = ((CARD8 *)&pri->pRanges[nRanges-1]) + byteoffset;
+ *pCARD8++ = interval.first;
+ *pCARD8 = interval.last;
+ }
+ else
+ {
+ pCARD16 = (CARD16 *)
+ (((char *)&pri->pRanges[nRanges-1]) + byteoffset);
+ *pCARD16++ = interval.first;
+ *pCARD16 = interval.last;
+ }
+ }
+ if (pStartIndex)
+ *pStartIndex = nRanges;
+ return Success;
+} /* RecordConvertSetToRanges */
+
+
+/* RecordConvertMinorOpInfoToRanges
+ *
+ * Arguments:
+ * pMinOpInfo is the minor opcode info to convert to xRecordRanges.
+ * pri is where the result should be stored.
+ * byteoffset is the offset from the start of an xRecordRange of the
+ * four vales (CARD8 major_first, CARD8 major_last,
+ * CARD16 minor_first, CARD16 minor_last) we are going to store.
+ *
+ * Returns: BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ * If Success is returned, the slice of pri->pRanges indicated by
+ * byteoffset is filled in with the information from pMinOpInfo.
+ */
+static int
+RecordConvertMinorOpInfoToRanges(pMinOpInfo, pri, byteoffset)
+ RecordMinorOpPtr pMinOpInfo;
+ GetContextRangeInfoPtr pri;
+ int byteoffset;
+{
+ int nsets;
+ int start;
+ int i;
+ int err;
+
+ if (!pMinOpInfo)
+ return Success;
+
+ nsets = pMinOpInfo->count;
+ pMinOpInfo++;
+ start = 0;
+ for (i = 0; i < nsets; i++)
+ {
+ int j, s;
+ s = start;
+ err = RecordConvertSetToRanges(pMinOpInfo[i].major.pMinOpSet, pri,
+ byteoffset + 2, FALSE, 65535, &start);
+ if (err != Success) return err;
+ for (j = s; j < start; j++)
+ {
+ CARD8 *pCARD8 = ((CARD8 *)&pri->pRanges[j]) + byteoffset;
+ *pCARD8++ = pMinOpInfo[i].major.first;
+ *pCARD8 = pMinOpInfo[i].major.last;
+ }
+ }
+ return Success;
+} /* RecordConvertMinorOpInfoToRanges */
+
+
+/* RecordSwapRanges
+ *
+ * Arguments:
+ * pRanges is an array of xRecordRanges.
+ * nRanges is the number of elements in pRanges.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * The 16 bit fields of each xRecordRange are byte swapped.
+ */
+static void
+RecordSwapRanges(pRanges, nRanges)
+ xRecordRange *pRanges;
+ int nRanges;
+{
+ int i;
+ register char n;
+ for (i = 0; i < nRanges; i++, pRanges++)
+ {
+ swaps(&pRanges->extRequestsMinorFirst, n);
+ swaps(&pRanges->extRequestsMinorLast, n);
+ swaps(&pRanges->extRepliesMinorFirst, n);
+ swaps(&pRanges->extRepliesMinorLast, n);
+ }
+} /* RecordSwapRanges */
+
+
+static int
+ProcRecordGetContext(client)
+ ClientPtr client;
+{
+ RecordContextPtr pContext;
+ REQUEST(xRecordGetContextReq);
+ xRecordGetContextReply rep;
+ int n;
+ RecordClientsAndProtocolPtr pRCAP;
+ int nRCAPs = 0;
+ GetContextRangeInfoPtr pRangeInfo;
+ GetContextRangeInfoPtr pri;
+ int i;
+ int err;
+
+ REQUEST_SIZE_MATCH(xRecordGetContextReq);
+ VERIFY_CONTEXT(pContext, stuff->context, client);
+
+ /* how many RCAPs are there on this context? */
+
+ for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
+ nRCAPs++;
+
+ /* allocate and initialize space for record range info */
+
+ pRangeInfo = (GetContextRangeInfoPtr)ALLOCATE_LOCAL(
+ nRCAPs * sizeof(GetContextRangeInfoRec));
+ if (!pRangeInfo && nRCAPs > 0)
+ return BadAlloc;
+ for (i = 0; i < nRCAPs; i++)
+ {
+ pRangeInfo[i].pRanges = NULL;
+ pRangeInfo[i].size = 0;
+ pRangeInfo[i].nRanges = 0;
+ }
+
+ /* convert the RCAP (internal) representation of the recorded protocol
+ * to the wire protocol (external) representation, storing the information
+ * for the ith RCAP in pri[i]
+ */
+
+ for (pRCAP = pContext->pListOfRCAP, pri = pRangeInfo;
+ pRCAP;
+ pRCAP = pRCAP->pNextRCAP, pri++)
+ {
+ xRecordRange rr;
+
+ err = RecordConvertSetToRanges(pRCAP->pRequestMajorOpSet, pri,
+ offset_of(rr, coreRequestsFirst), TRUE, 127, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertSetToRanges(pRCAP->pReplyMajorOpSet, pri,
+ offset_of(rr, coreRepliesFirst), TRUE, 127, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertSetToRanges(pRCAP->pDeliveredEventSet, pri,
+ offset_of(rr, deliveredEventsFirst), TRUE, 255, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertSetToRanges(pRCAP->pDeviceEventSet, pri,
+ offset_of(rr, deviceEventsFirst), TRUE, 255, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertSetToRanges(pRCAP->pErrorSet, pri,
+ offset_of(rr, errorsFirst), TRUE, 255, NULL);
+ if (err != Success) goto bailout;
+
+ err = RecordConvertMinorOpInfoToRanges(pRCAP->pRequestMinOpInfo,
+ pri, offset_of(rr, extRequestsMajorFirst));
+ if (err != Success) goto bailout;
+
+ err = RecordConvertMinorOpInfoToRanges(pRCAP->pReplyMinOpInfo,
+ pri, offset_of(rr, extRepliesMajorFirst));
+ if (err != Success) goto bailout;
+
+ if (pRCAP->clientStarted || pRCAP->clientDied)
+ {
+ if (pri->nRanges == 0)
+ RecordAllocRanges(pri, 1);
+ pri->pRanges[0].clientStarted = pRCAP->clientStarted;
+ pri->pRanges[0].clientDied = pRCAP->clientDied;
+ }
+ }
+
+ /* calculate number of clients and reply length */
+
+ rep.nClients = 0;
+ rep.length = 0;
+ for (pRCAP = pContext->pListOfRCAP, pri = pRangeInfo;
+ pRCAP;
+ pRCAP = pRCAP->pNextRCAP, pri++)
+ {
+ rep.nClients += pRCAP->numClients;
+ rep.length += pRCAP->numClients *
+ ( (sizeof(xRecordClientInfo) >> 2) +
+ pri->nRanges * (sizeof(xRecordRange) >> 2));
+ }
+
+ /* write the reply header */
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.enabled = pContext->pRecordingClient != NULL;
+ rep.elementHeader = pContext->elemHeaders;
+ if(client->swapped)
+ {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.nClients, n);
+ }
+ (void)WriteToClient(client, sizeof(xRecordGetContextReply),
+ (char *)&rep);
+
+ /* write all the CLIENT_INFOs */
+
+ for (pRCAP = pContext->pListOfRCAP, pri = pRangeInfo;
+ pRCAP;
+ pRCAP = pRCAP->pNextRCAP, pri++)
+ {
+ xRecordClientInfo rci;
+ rci.nRanges = pri->nRanges;
+ if (client->swapped)
+ {
+ swapl(&rci.nRanges, n);
+ RecordSwapRanges(pri->pRanges, pri->nRanges);
+ }
+ for (i = 0; i < pRCAP->numClients; i++)
+ {
+ rci.clientResource = pRCAP->pClientIDs[i];
+ if (client->swapped) swapl(&rci.clientResource, n);
+ WriteToClient(client, sizeof(xRecordClientInfo), (char *)&rci);
+ WriteToClient(client, sizeof(xRecordRange) * pri->nRanges,
+ (char *)pri->pRanges);
+ }
+ }
+ err = client->noClientException;
+
+bailout:
+ for (i = 0; i < nRCAPs; i++)
+ {
+ if (pRangeInfo[i].pRanges) xfree(pRangeInfo[i].pRanges);
+ }
+ DEALLOCATE_LOCAL(pRangeInfo);
+ return err;
+} /* ProcRecordGetContext */
+
+
+static int
+ProcRecordEnableContext(client)
+ ClientPtr client;
+{
+ RecordContextPtr pContext;
+ REQUEST(xRecordEnableContextReq);
+ int i;
+ RecordClientsAndProtocolPtr pRCAP;
+
+ REQUEST_SIZE_MATCH(xRecordGetContextReq);
+ VERIFY_CONTEXT(pContext, stuff->context, client);
+ if (pContext->pRecordingClient)
+ return BadMatch; /* already enabled */
+
+ /* install record hooks for each RCAP */
+
+ for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
+ {
+ int err = RecordInstallHooks(pRCAP, 0);
+ if (err != Success)
+ { /* undo the previous installs */
+ RecordClientsAndProtocolPtr pUninstallRCAP;
+ for (pUninstallRCAP = pContext->pListOfRCAP;
+ pUninstallRCAP != pRCAP;
+ pUninstallRCAP = pUninstallRCAP->pNextRCAP)
+ {
+ RecordUninstallHooks(pUninstallRCAP, 0);
+ }
+ return err;
+ }
+ }
+
+ /* Disallow further request processing on this connection until
+ * the context is disabled.
+ */
+ IgnoreClient(client);
+ pContext->pRecordingClient = client;
+
+ /* Don't allow the data connection to record itself; unregister it. */
+ RecordDeleteClientFromContext(pContext,
+ pContext->pRecordingClient->clientAsMask);
+
+ /* move the newly enabled context to the front part of ppAllContexts,
+ * where all the enabled contexts are
+ */
+ i = RecordFindContextOnAllContexts(pContext);
+ assert(i >= numEnabledContexts);
+ if (i != numEnabledContexts)
+ {
+ ppAllContexts[i] = ppAllContexts[numEnabledContexts];
+ ppAllContexts[numEnabledContexts] = pContext;
+ }
+
+ ++numEnabledContexts;
+ assert(numEnabledContexts > 0);
+
+ /* send StartOfData */
+ RecordAProtocolElement(pContext, NULL, XRecordStartOfData, NULL, 0, 0);
+ RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0);
+ return Success;
+} /* ProcRecordEnableContext */
+
+
+/* RecordDisableContext
+ *
+ * Arguments:
+ * pContext is the context to disable.
+ * nRanges is the number of elements in pRanges.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * If the context was enabled, it is disabled. An EndOfData
+ * message is sent to the recording client. Recording hooks for
+ * this context are uninstalled. The context is moved to the
+ * rear part of the ppAllContexts array. numEnabledContexts is
+ * decremented. Request processing for the formerly recording client
+ * is resumed.
+ */
+static void
+RecordDisableContext(pContext)
+ RecordContextPtr pContext;
+{
+ RecordClientsAndProtocolPtr pRCAP;
+ int i;
+
+ if (!pContext->pRecordingClient) return;
+ if (!pContext->pRecordingClient->clientGone)
+ {
+ RecordAProtocolElement(pContext, NULL, XRecordEndOfData, NULL, 0, 0);
+ RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0);
+ /* Re-enable request processing on this connection. */
+ AttendClient(pContext->pRecordingClient);
+ }
+
+ for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
+ {
+ RecordUninstallHooks(pRCAP, 0);
+ }
+
+ pContext->pRecordingClient = NULL;
+
+ /* move the newly disabled context to the rear part of ppAllContexts,
+ * where all the disabled contexts are
+ */
+ i = RecordFindContextOnAllContexts(pContext);
+ assert( (i != -1) && (i < numEnabledContexts) );
+ if (i != (numEnabledContexts - 1) )
+ {
+ ppAllContexts[i] = ppAllContexts[numEnabledContexts-1];
+ ppAllContexts[numEnabledContexts-1] = pContext;
+ }
+ --numEnabledContexts;
+ assert(numEnabledContexts >= 0);
+} /* RecordDisableContext */
+
+
+static int
+ProcRecordDisableContext(client)
+ ClientPtr client;
+{
+ RecordContextPtr pContext;
+ REQUEST(xRecordDisableContextReq);
+
+ REQUEST_SIZE_MATCH(xRecordDisableContextReq);
+ VERIFY_CONTEXT(pContext, stuff->context, client);
+ RecordDisableContext(pContext);
+ return Success;
+} /* ProcRecordDisableContext */
+
+
+/* RecordDeleteContext
+ *
+ * Arguments:
+ * value is the context to delete.
+ * id is its resource ID.
+ *
+ * Returns: Success.
+ *
+ * Side Effects:
+ * Disables the context, frees all associated memory, and removes
+ * it from the ppAllContexts array.
+ */
+static int
+RecordDeleteContext(value, id)
+ pointer value;
+ XID id;
+{
+ int i;
+ RecordContextPtr pContext = (RecordContextPtr)value;
+ RecordClientsAndProtocolPtr pRCAP;
+
+ RecordDisableContext(pContext);
+
+ /* Remove all the clients from all the RCAPs.
+ * As a result, the RCAPs will be freed.
+ */
+
+ while (pRCAP = pContext->pListOfRCAP)
+ {
+ int numClients = pRCAP->numClients;
+ /* when the last client is deleted, the RCAP will go away. */
+ while(numClients--)
+ {
+ RecordDeleteClientFromRCAP(pRCAP, numClients);
+ }
+ }
+
+ xfree(pContext);
+
+ /* remove context from AllContexts list */
+
+ if (-1 != (i = RecordFindContextOnAllContexts(pContext)))
+ {
+ ppAllContexts[i] = ppAllContexts[numContexts - 1];
+ if (--numContexts == 0)
+ {
+ xfree(ppAllContexts);
+ ppAllContexts = NULL;
+ }
+ }
+ return Success;
+} /* RecordDeleteContext */
+
+
+static int
+ProcRecordFreeContext(client)
+ ClientPtr client;
+{
+ RecordContextPtr pContext;
+ REQUEST(xRecordFreeContextReq);
+
+ REQUEST_SIZE_MATCH(xRecordFreeContextReq);
+ VERIFY_CONTEXT(pContext, stuff->context, client);
+ FreeResource(stuff->context, RT_NONE);
+ return Success;
+} /* ProcRecordFreeContext */
+
+
+static int
+ProcRecordDispatch(client)
+ ClientPtr client;
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_RecordQueryVersion:
+ return ProcRecordQueryVersion(client);
+ case X_RecordCreateContext:
+ return ProcRecordCreateContext(client);
+ case X_RecordRegisterClients:
+ return ProcRecordRegisterClients(client);
+ case X_RecordUnregisterClients:
+ return ProcRecordUnregisterClients(client);
+ case X_RecordGetContext:
+ return ProcRecordGetContext(client);
+ case X_RecordEnableContext:
+ return ProcRecordEnableContext(client);
+ case X_RecordDisableContext:
+ return ProcRecordDisableContext(client);
+ case X_RecordFreeContext:
+ return ProcRecordFreeContext(client);
+ default:
+ return BadRequest;
+ }
+} /* ProcRecordDispatch */
+
+
+static int
+SProcRecordQueryVersion(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordQueryVersionReq);
+ register char n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xRecordQueryVersionReq);
+ swaps(&stuff->majorVersion, n);
+ swaps(&stuff->minorVersion,n);
+ return ProcRecordQueryVersion(client);
+} /* SProcRecordQueryVersion */
+
+
+static void
+SwapCreateRegister(stuff)
+ xRecordRegisterClientsReq *stuff;
+{
+ register char n;
+ int i;
+ XID *pClientID;
+ xRecordRange *pRange;
+
+ swapl(&stuff->context, n);
+ swapl(&stuff->nClients, n);
+ swapl(&stuff->nRanges, n);
+ pClientID = (XID *)&stuff[1];
+ for (i = 0; i < stuff->nClients; i++, pClientID++)
+ {
+ swapl(pClientID, n);
+ }
+ pRange = (xRecordRange *)pClientID;
+ RecordSwapRanges((xRecordRange *)pClientID, stuff->nRanges);
+} /* SwapCreateRegister */
+
+
+static int
+SProcRecordCreateContext(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordCreateContextReq);
+ register char n;
+
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xRecordCreateContextReq);
+ SwapCreateRegister(stuff);
+ return ProcRecordCreateContext(client);
+} /* SProcRecordCreateContext */
+
+
+static int
+SProcRecordRegisterClients(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordRegisterClientsReq);
+ register char n;
+
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xRecordRegisterClientsReq);
+ SwapCreateRegister(stuff);
+ return ProcRecordRegisterClients(client);
+} /* SProcRecordRegisterClients */
+
+
+static int
+SProcRecordUnregisterClients(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordUnregisterClientsReq);
+ register char n;
+
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xRecordUnregisterClientsReq);
+ swapl(&stuff->context, n);
+ swapl(&stuff->nClients, n);
+ SwapRestL(stuff);
+ return ProcRecordUnregisterClients(client);
+} /* SProcRecordUnregisterClients */
+
+
+static int
+SProcRecordGetContext(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordGetContextReq);
+ register char n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xRecordGetContextReq);
+ swapl(&stuff->context, n);
+ return ProcRecordGetContext(client);
+} /* SProcRecordGetContext */
+
+static int
+SProcRecordEnableContext(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordEnableContextReq);
+ register char n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xRecordEnableContextReq);
+ swapl(&stuff->context, n);
+ return ProcRecordEnableContext(client);
+} /* SProcRecordEnableContext */
+
+
+static int
+SProcRecordDisableContext(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordDisableContextReq);
+ register char n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xRecordDisableContextReq);
+ swapl(&stuff->context, n);
+ return ProcRecordDisableContext(client);
+} /* SProcRecordDisableContext */
+
+
+static int
+SProcRecordFreeContext(client)
+ ClientPtr client;
+{
+ REQUEST(xRecordFreeContextReq);
+ register char n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xRecordFreeContextReq);
+ swapl(&stuff->context, n);
+ return ProcRecordFreeContext(client);
+} /* SProcRecordFreeContext */
+
+
+static int
+SProcRecordDispatch(client)
+ ClientPtr client;
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_RecordQueryVersion:
+ return SProcRecordQueryVersion(client);
+ case X_RecordCreateContext:
+ return SProcRecordCreateContext(client);
+ case X_RecordRegisterClients:
+ return SProcRecordRegisterClients(client);
+ case X_RecordUnregisterClients:
+ return SProcRecordUnregisterClients(client);
+ case X_RecordGetContext:
+ return SProcRecordGetContext(client);
+ case X_RecordEnableContext:
+ return SProcRecordEnableContext(client);
+ case X_RecordDisableContext:
+ return SProcRecordDisableContext(client);
+ case X_RecordFreeContext:
+ return SProcRecordFreeContext(client);
+ default:
+ return BadRequest;
+ }
+} /* SProcRecordDispatch */
+
+/* XXX goes in header file */
+extern void SwapConnSetupInfo(), SwapConnSetupPrefix();
+
+/* RecordConnectionSetupInfo
+ *
+ * Arguments:
+ * pContext is an enabled context that specifies recording of
+ * connection setup info.
+ * pci holds the connection setup info.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * The connection setup info is sent to the recording client.
+ */
+static void
+RecordConnectionSetupInfo(pContext, pci)
+ RecordContextPtr pContext;
+ NewClientInfoRec *pci;
+{
+ int prefixsize = SIZEOF(xConnSetupPrefix);
+ int restsize = pci->prefix->length * 4;
+
+ if (pci->client->swapped)
+ {
+ char * pConnSetup = (char *)ALLOCATE_LOCAL(prefixsize + restsize);
+ if (!pConnSetup)
+ return;
+ SwapConnSetupPrefix(pci->prefix, pConnSetup);
+ SwapConnSetupInfo(pci->setup, pConnSetup + prefixsize);
+ RecordAProtocolElement(pContext, pci->client, XRecordClientStarted,
+ (pointer)pConnSetup, prefixsize + restsize, 0);
+ DEALLOCATE_LOCAL(pConnSetup);
+ }
+ else
+ {
+ /* don't alloc and copy as in the swapped case; just send the
+ * data in two pieces
+ */
+ RecordAProtocolElement(pContext, pci->client, XRecordClientStarted,
+ (pointer)pci->prefix, prefixsize, restsize);
+ RecordAProtocolElement(pContext, pci->client, XRecordClientStarted,
+ (pointer)pci->setup, restsize, /* continuation */ -1);
+ }
+} /* RecordConnectionSetupInfo */
+
+
+/* RecordDeleteContext
+ *
+ * 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 has connected and any contexts have specified
+ * XRecordFutureClients, the new client is registered on those contexts.
+ * If any of those contexts specify recording of the connection setup
+ * info, it is recorded.
+ *
+ * If an existing client has disconnected, it is deleted from any
+ * contexts that it was registered on. If any of those contexts
+ * specified XRecordClientDied, they record a ClientDied protocol element.
+ * If the disconnectiong client happened to be the data connection of an
+ * enabled context, the context is disabled.
+ */
+
+static void
+RecordAClientStateChange(pcbl, nulldata, calldata)
+ CallbackListPtr *pcbl;
+ pointer nulldata;
+ pointer calldata;
+{
+ NewClientInfoRec *pci = (NewClientInfoRec *)calldata;
+ int i;
+ ClientPtr pClient = pci->client;
+
+ switch (pClient->clientState)
+ {
+ case ClientStateRunning: /* new client */
+ for (i = 0; i < numContexts; i++)
+ {
+ RecordClientsAndProtocolPtr pRCAP;
+ RecordContextPtr pContext = ppAllContexts[i];
+
+ if (pRCAP = RecordFindClientOnContext(pContext,
+ XRecordFutureClients, NULL))
+ {
+ RecordAddClientToRCAP(pRCAP, pClient->clientAsMask);
+ if (pContext->pRecordingClient && pRCAP->clientStarted)
+ RecordConnectionSetupInfo(pContext, pci);
+ }
+ }
+ break;
+
+ case ClientStateGone:
+ case ClientStateRetained: /* client disconnected */
+ for (i = 0; i < numContexts; i++)
+ {
+ RecordClientsAndProtocolPtr pRCAP;
+ RecordContextPtr pContext = ppAllContexts[i];
+ int pos;
+
+ if (pContext->pRecordingClient == pClient)
+ RecordDisableContext(pContext);
+ if (pRCAP = RecordFindClientOnContext(pContext,
+ pClient->clientAsMask, &pos))
+ {
+ if (pContext->pRecordingClient && pRCAP->clientDied)
+ RecordAProtocolElement(pContext, pClient,
+ XRecordClientDied, NULL, 0, 0);
+ RecordDeleteClientFromRCAP(pRCAP, pos);
+ }
+ }
+ break;
+
+ } /* end switch on client state */
+} /* RecordAClientStateChange */
+
+
+/* RecordCloseDown
+ *
+ * Arguments:
+ * extEntry is the extension information for RECORD.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Performs any cleanup needed by RECORD at server shutdown time.
+ *
+ */
+static void
+RecordCloseDown(extEntry)
+ ExtensionEntry *extEntry;
+{
+ DeleteCallback(&ClientStateCallback, RecordAClientStateChange, NULL);
+} /* RecordCloseDown */
+
+
+/* RecordExtensionInit
+ *
+ * Arguments: none.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Enables the RECORD extension if possible.
+ */
+void
+RecordExtensionInit()
+{
+ ExtensionEntry *extentry;
+
+ RTContext = CreateNewResourceType(RecordDeleteContext);
+ if (!RTContext)
+ return;
+
+ RecordClientPrivateIndex = AllocateClientPrivateIndex();
+ if (!AllocateClientPrivate(RecordClientPrivateIndex, 0))
+ return;
+
+ ppAllContexts = NULL;
+ numContexts = numEnabledContexts = numEnabledRCAPs = 0;
+
+ if (!AddCallback(&ClientStateCallback, RecordAClientStateChange, NULL))
+ return;
+
+ extentry = AddExtension(RECORD_NAME, RecordNumEvents, RecordNumErrors,
+ ProcRecordDispatch, SProcRecordDispatch,
+ RecordCloseDown, StandardMinorOpcode);
+ if (!extentry)
+ {
+ DeleteCallback(&ClientStateCallback, RecordAClientStateChange, NULL);
+ return;
+ }
+ RecordErrorBase = extentry->errorBase;
+
+} /* RecordExtensionInit */
+
diff --git a/xc/programs/Xserver/record/recordmod.c b/xc/programs/Xserver/record/recordmod.c
new file mode 100644
index 000000000..53e2a4674
--- /dev/null
+++ b/xc/programs/Xserver/record/recordmod.c
@@ -0,0 +1,41 @@
+/* $XFree86: xc/programs/Xserver/record/recordmod.c,v 1.5 1999/01/26 05:54:21 dawes Exp $ */
+
+#include "xf86Module.h"
+
+extern Bool noTestExtensions;
+
+static MODULESETUPPROTO(recordSetup);
+
+extern void RecordExtensionInit(INITARGS);
+
+ExtensionModule recordExt = {
+ RecordExtensionInit,
+ "RECORD",
+ &noTestExtensions,
+ NULL
+};
+
+static XF86ModuleVersionInfo VersRec = {
+ "record",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 13, 0,
+ ABI_CLASS_EXTENSION,
+ ABI_EXTENSION_VERSION,
+ MOD_CLASS_EXTENSION,
+ {0,0,0,0}
+};
+
+XF86ModuleData recordModuleData = { &VersRec, recordSetup, NULL };
+
+static pointer
+recordSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ LoadExtension(&recordExt);
+
+ /* Need a non-NULL return value to indicate success */
+ return (pointer)1;
+}
+
diff --git a/xc/programs/Xserver/record/set.c b/xc/programs/Xserver/record/set.c
new file mode 100644
index 000000000..b5797f029
--- /dev/null
+++ b/xc/programs/Xserver/record/set.c
@@ -0,0 +1,704 @@
+/* $TOG: set.c /main/3 1998/02/09 15:17:17 kaleb $ */
+
+/*
+
+Copyright 1995, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+/* $XFree86: xc/programs/Xserver/record/set.c,v 1.5 1998/12/20 11:58:03 dawes Exp $ */
+
+/*
+
+ See the header set.h for a description of the set ADT.
+
+ Implementation Strategy
+
+ A bit vector is an obvious choice to represent the set, but may take
+ too much memory, depending on the numerically largest member in the
+ set. One expected common case is for the client to ask for *all*
+ protocol. This means it would ask for minor opcodes 0 through 65535.
+ Representing this as a bit vector takes 8K -- and there may be
+ multiple minor opcode intervals, as many as one per major (extension)
+ opcode). In such cases, a list-of-intervals representation would be
+ preferable to reduce memory consumption. Both representations will be
+ implemented, and RecordCreateSet will decide heuristically which one
+ to use based on the set members.
+
+ Note: When compiling for use in the server, do not use -DTESTING.
+ When compiling for stand-alone testing of the set ADT, use -DTESTING.
+
+*/
+
+#ifndef TESTING
+#include "misc.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* stuff that you normally get from the X Server's environment */
+
+typedef int Bool;
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+typedef unsigned short CARD16;
+
+#define xalloc malloc
+#define xfree free
+#define ALLOCATE_LOCAL malloc
+#define DEALLOCATE_LOCAL free
+
+void *Xcalloc(size)
+ int size;
+{
+ void *p = malloc(size);
+ if (p) memset(p, 0, size);
+ return p;
+}
+
+#ifndef max
+#define max(_a, _b) ( ((_a) > (_b)) ? (_a) : (_b) )
+#endif
+
+#endif /* TESTING */
+
+#include "set.h"
+
+#ifdef XFree86LOADER
+#include "xf86_libc.h"
+#include "xf86_ansic.h"
+#endif
+
+static int
+maxMemberInInterval(pIntervals, nIntervals)
+ RecordSetInterval *pIntervals;
+ int nIntervals;
+{
+ int i;
+ int maxMember = -1;
+ for (i = 0; i < nIntervals; i++)
+ {
+ if (maxMember < (int)pIntervals[i].last)
+ maxMember = pIntervals[i].last;
+ }
+ return maxMember;
+}
+
+static void
+NoopDestroySet(pSet)
+ RecordSetPtr pSet;
+{
+}
+
+/***************************************************************************/
+
+/* set operations for bit vector representation */
+
+typedef struct {
+ RecordSetRec baseSet;
+ int maxMember;
+ /* followed by the bit vector itself */
+} BitVectorSet, *BitVectorSetPtr;
+
+#define BITS_PER_LONG (sizeof(unsigned long) * 8)
+
+static void
+BitVectorDestroySet(pSet)
+ RecordSetPtr pSet;
+{
+ xfree(pSet);
+}
+
+static unsigned long
+BitVectorIsMemberOfSet(pSet, pm)
+ RecordSetPtr pSet;
+ int pm;
+{
+ BitVectorSetPtr pbvs = (BitVectorSetPtr)pSet;
+ unsigned long *pbitvec;
+
+ if ((int)pm > pbvs->maxMember) return FALSE;
+ pbitvec = (unsigned long *)(&pbvs[1]);
+ return (pbitvec[pm / BITS_PER_LONG] & ((unsigned long)1 << (pm % BITS_PER_LONG)));
+}
+
+
+static int
+BitVectorFindBit(pSet, iterbit, bitval)
+ RecordSetPtr pSet;
+ int iterbit;
+ Bool bitval;
+{
+ BitVectorSetPtr pbvs = (BitVectorSetPtr)pSet;
+ unsigned long *pbitvec = (unsigned long *)(&pbvs[1]);
+ int startlong;
+ int startbit;
+ int walkbit;
+ int maxMember;
+ unsigned long skipval;
+ unsigned long bits;
+ unsigned long usefulbits;
+
+ startlong = iterbit / BITS_PER_LONG;
+ pbitvec += startlong;
+ startbit = startlong * BITS_PER_LONG;
+ skipval = bitval ? 0L : ~0L;
+ maxMember = pbvs->maxMember;
+
+
+ if (startbit > maxMember) return -1;
+ bits = *pbitvec;
+ usefulbits = ~(((unsigned long)1 << (iterbit - startbit)) - 1);
+ if ( (bits & usefulbits) == (skipval & usefulbits) )
+ {
+ pbitvec++;
+ startbit += BITS_PER_LONG;
+
+ while (startbit <= maxMember && *pbitvec == skipval)
+ {
+ pbitvec++;
+ startbit += BITS_PER_LONG;
+ }
+ if (startbit > maxMember) return -1;
+ }
+
+ walkbit = (startbit < iterbit) ? iterbit - startbit : 0;
+
+ bits = *pbitvec;
+ while (walkbit < BITS_PER_LONG && ((!(bits & ((unsigned long)1 << walkbit))) == bitval))
+ walkbit++;
+
+ return startbit + walkbit;
+}
+
+
+static RecordSetIteratePtr
+BitVectorIterateSet(pSet, pIter, pInterval)
+ RecordSetPtr pSet;
+ RecordSetIteratePtr pIter;
+ RecordSetInterval *pInterval;
+{
+ int iterbit = (int)(long)pIter;
+ int b;
+
+ b = BitVectorFindBit(pSet, iterbit, TRUE);
+ if (b == -1) return (RecordSetIteratePtr)0;
+ pInterval->first = b;
+
+ b = BitVectorFindBit(pSet, b, FALSE);
+ pInterval->last = (b < 0) ? ((BitVectorSetPtr)pSet)->maxMember : b - 1;
+ return (RecordSetIteratePtr)(long)(pInterval->last + 1);
+}
+
+RecordSetOperations BitVectorSetOperations = {
+ BitVectorDestroySet, BitVectorIsMemberOfSet, BitVectorIterateSet };
+
+RecordSetOperations BitVectorNoFreeOperations = {
+ NoopDestroySet, BitVectorIsMemberOfSet, BitVectorIterateSet };
+
+static int
+BitVectorSetMemoryRequirements(pIntervals, nIntervals, maxMember, alignment)
+ RecordSetInterval *pIntervals;
+ int nIntervals;
+ int maxMember;
+ int *alignment;
+{
+ int nlongs;
+
+ *alignment = sizeof(unsigned long);
+ nlongs = (maxMember + BITS_PER_LONG) / BITS_PER_LONG;
+ return (sizeof(BitVectorSet) + nlongs * sizeof(unsigned long));
+}
+
+static RecordSetPtr
+BitVectorCreateSet(pIntervals, nIntervals, pMem, memsize)
+ RecordSetInterval *pIntervals;
+ int nIntervals;
+ void *pMem;
+ int memsize;
+{
+ BitVectorSetPtr pbvs;
+ int i, j;
+ unsigned long *pbitvec;
+
+ /* allocate all storage needed by this set in one chunk */
+
+ if (pMem)
+ {
+ memset(pMem, 0, memsize);
+ pbvs = (BitVectorSetPtr)pMem;
+ pbvs->baseSet.ops = &BitVectorNoFreeOperations;
+ }
+ else
+ {
+ pbvs = (BitVectorSetPtr)Xcalloc(memsize);
+ if (!pbvs) return NULL;
+ pbvs->baseSet.ops = &BitVectorSetOperations;
+ }
+
+ pbvs->maxMember = maxMemberInInterval(pIntervals, nIntervals);
+
+ /* fill in the set */
+
+ pbitvec = (unsigned long *)(&pbvs[1]);
+ for (i = 0; i < nIntervals; i++)
+ {
+ for (j = pIntervals[i].first; j <= (int)pIntervals[i].last; j++)
+ {
+ pbitvec[j/BITS_PER_LONG] |= ((unsigned long)1 << (j % BITS_PER_LONG));
+ }
+ }
+ return (RecordSetPtr)pbvs;
+}
+
+
+/***************************************************************************/
+
+/* set operations for interval list representation */
+
+typedef struct {
+ RecordSetRec baseSet;
+ int nIntervals;
+ /* followed by the intervals (RecordSetInterval) */
+} IntervalListSet, *IntervalListSetPtr;
+
+static void
+IntervalListDestroySet(pSet)
+ RecordSetPtr pSet;
+{
+ xfree(pSet);
+}
+
+static unsigned long
+IntervalListIsMemberOfSet(pSet, pm)
+ RecordSetPtr pSet;
+ int pm;
+{
+ IntervalListSetPtr prls = (IntervalListSetPtr)pSet;
+ RecordSetInterval *pInterval = (RecordSetInterval *)(&prls[1]);
+ int hi, lo, probe;
+
+ /* binary search */
+ lo = 0; hi = prls->nIntervals - 1;
+ while (lo <= hi)
+ {
+ probe = (hi + lo) / 2;
+ if (pm >= pInterval[probe].first && pm <= pInterval[probe].last) return 1;
+ else if (pm < pInterval[probe].first) hi = probe - 1;
+ else lo = probe + 1;
+ }
+ return 0;
+}
+
+
+static RecordSetIteratePtr
+IntervalListIterateSet(pSet, pIter, pIntervalReturn)
+ RecordSetPtr pSet;
+ RecordSetIteratePtr pIter;
+ RecordSetInterval *pIntervalReturn;
+{
+ RecordSetInterval *pInterval = (RecordSetInterval *)pIter;
+ IntervalListSetPtr prls = (IntervalListSetPtr)pSet;
+
+ if (pInterval == NULL)
+ {
+ pInterval = (RecordSetInterval *)(&prls[1]);
+ }
+
+ if ( (pInterval - (RecordSetInterval *)(&prls[1])) < prls->nIntervals )
+ {
+ *pIntervalReturn = *pInterval;
+ return (RecordSetIteratePtr)(++pInterval);
+ }
+ else
+ return (RecordSetIteratePtr)NULL;
+}
+
+RecordSetOperations IntervalListSetOperations = {
+ IntervalListDestroySet, IntervalListIsMemberOfSet, IntervalListIterateSet };
+
+RecordSetOperations IntervalListNoFreeOperations = {
+ NoopDestroySet, IntervalListIsMemberOfSet, IntervalListIterateSet };
+
+static int
+IntervalListMemoryRequirements(pIntervals, nIntervals, maxMember, alignment)
+ RecordSetInterval *pIntervals;
+ int nIntervals;
+ int maxMember;
+ int *alignment;
+{
+ *alignment = sizeof(unsigned long);
+ return sizeof(IntervalListSet) + nIntervals * sizeof(RecordSetInterval);
+}
+
+static RecordSetPtr
+IntervalListCreateSet(pIntervals, nIntervals, pMem, memsize)
+ RecordSetInterval *pIntervals;
+ int nIntervals;
+ void *pMem;
+ int memsize;
+{
+ IntervalListSetPtr prls;
+ int i, j, k;
+ RecordSetInterval *stackIntervals = NULL;
+ CARD16 first;
+
+ if (nIntervals > 0)
+ {
+ stackIntervals = (RecordSetInterval *)ALLOCATE_LOCAL(
+ sizeof(RecordSetInterval) * nIntervals);
+ if (!stackIntervals) return NULL;
+
+ /* sort intervals, store in stackIntervals (insertion sort) */
+
+ for (i = 0; i < nIntervals; i++)
+ {
+ first = pIntervals[i].first;
+ for (j = 0; j < i; j++)
+ {
+ if (first < stackIntervals[j].first)
+ break;
+ }
+ for (k = i; k > j; k--)
+ {
+ stackIntervals[k] = stackIntervals[k-1];
+ }
+ stackIntervals[j] = pIntervals[i];
+ }
+
+ /* merge abutting/overlapping intervals */
+
+ for (i = 0; i < nIntervals - 1; )
+ {
+ if ( (stackIntervals[i].last + (unsigned int)1) <
+ stackIntervals[i + 1].first)
+ {
+ i++; /* disjoint intervals */
+ }
+ else
+ {
+ stackIntervals[i].last = max(stackIntervals[i].last,
+ stackIntervals[i + 1].last);
+ nIntervals--;
+ for (j = i + 1; j < nIntervals; j++)
+ stackIntervals[j] = stackIntervals[j + 1];
+ }
+ }
+ }
+
+ /* allocate and fill in set structure */
+
+ if (pMem)
+ {
+ prls = (IntervalListSetPtr)pMem;
+ prls->baseSet.ops = &IntervalListNoFreeOperations;
+ }
+ else
+ {
+ prls = (IntervalListSetPtr)
+ xalloc(sizeof(IntervalListSet) + nIntervals * sizeof(RecordSetInterval));
+ if (!prls) goto bailout;
+ prls->baseSet.ops = &IntervalListSetOperations;
+ }
+ memcpy(&prls[1], stackIntervals, nIntervals * sizeof(RecordSetInterval));
+ prls->nIntervals = nIntervals;
+bailout:
+ if (stackIntervals) DEALLOCATE_LOCAL(stackIntervals);
+ return (RecordSetPtr)prls;
+}
+
+#ifdef TESTING
+typedef enum {
+ BitVectorImplementation, IntervalListImplementation} RecordSetImplementation;
+
+RecordSetImplementation _RecordSetImpl;
+
+static void
+_RecordForceSetImplementation(setimpl)
+ RecordSetImplementation setimpl;
+{
+ _RecordSetImpl = setimpl;
+}
+#endif
+
+typedef RecordSetPtr (*RecordCreateSetProcPtr)(
+#if NeedNestedPrototypes
+ RecordSetInterval *pIntervals,
+ int nIntervals,
+ void *pMem,
+ int memsize
+#endif
+);
+
+static int
+_RecordSetMemoryRequirements(pIntervals, nIntervals, alignment, ppCreateSet)
+ RecordSetInterval *pIntervals;
+ int nIntervals;
+ int *alignment;
+ RecordCreateSetProcPtr *ppCreateSet;
+{
+ int bmsize, rlsize, bma, rla;
+ int maxMember;
+
+ /* find maximum member of set so we know how big to make the bit vector */
+ maxMember = maxMemberInInterval(pIntervals, nIntervals);
+
+ bmsize = BitVectorSetMemoryRequirements(pIntervals, nIntervals, maxMember,
+ &bma);
+ rlsize = IntervalListMemoryRequirements(pIntervals, nIntervals, maxMember,
+ &rla);
+#ifdef TESTING
+ if (_RecordSetImpl == BitVectorImplementation)
+#else
+ if ( ( (nIntervals > 1) && (maxMember <= 255) )
+ || (bmsize < rlsize) )
+#endif
+ {
+ *alignment = bma;
+ *ppCreateSet = BitVectorCreateSet;
+ return bmsize;
+ }
+ else
+ {
+ *alignment = rla;
+ *ppCreateSet = IntervalListCreateSet;
+ return rlsize;
+ }
+}
+
+/***************************************************************************/
+
+/* user-visible functions */
+
+int
+RecordSetMemoryRequirements(pIntervals, nIntervals, alignment)
+ RecordSetInterval *pIntervals;
+ int nIntervals;
+ int *alignment;
+{
+ RecordCreateSetProcPtr pCreateSet;
+ return _RecordSetMemoryRequirements(pIntervals, nIntervals, alignment,
+ &pCreateSet);
+}
+
+RecordSetPtr
+RecordCreateSet(pIntervals, nIntervals, pMem, memsize)
+ RecordSetInterval *pIntervals;
+ int nIntervals;
+ void *pMem;
+ int memsize;
+{
+ RecordCreateSetProcPtr pCreateSet;
+ int alignment;
+ int size;
+
+ size = _RecordSetMemoryRequirements(pIntervals, nIntervals, &alignment,
+ &pCreateSet);
+ if (pMem)
+ {
+ if ( ((long)pMem & (alignment-1) ) || memsize < size)
+ return NULL;
+ }
+ return (*pCreateSet)(pIntervals, nIntervals, pMem, size);
+}
+
+/***************************************************************************/
+
+#ifdef TESTING
+
+/*
+
+Test Strategy
+
+Having two set representations is convenient for testing because we
+can play them against each other. The test code will be able to
+specify which implementation to use. This breaks the encapsulation,
+but that seems acceptable for testing. The crux of the test loop
+looks like this:
+
+loop:
+ generate random list of Intervals
+
+ create set A using bit vector implementation
+ create set B using Interval list implementation
+
+ for each possible set member
+ if set A and set B disagree on whether this is a member error;
+
+ iterate over both sets, comparing the intervals returned by each.
+ if intervals or number of intervals are different error;
+
+ iterate over intervals of set A
+ for i = interval.first to interval.last
+ if i is not a member of set B error;
+
+ iterate over intervals of set B
+ for i = interval.first to interval.last
+ if i is not a member of set A error;
+
+ destroy sets A, B
+
+*/
+
+int GenerateRandomIntervals(pIntervals, maxintervals)
+ RecordSetInterval *pIntervals;
+ int maxintervals;
+{
+ int i, nIntervals;
+
+ nIntervals = rand() % maxintervals;
+
+ for (i = 0; i < nIntervals; i++)
+ {
+ pIntervals[i].first = rand();
+ pIntervals[i].last = pIntervals[i].first + rand();
+ }
+ return nIntervals;
+}
+
+#define MAXINTERVALS 100
+
+int main(argc, argv)
+ int argc;
+ char **argv;
+{
+ RecordSetPtr bs, rs;
+ RecordSetInterval br, rr;
+ RecordSetIteratePtr bi, ri;
+ CARD16 i;
+ int testcount;
+ RecordSetInterval intervals[MAXINTERVALS];
+ int nIntervals;
+ int bsize, rsize;
+ int balign, ralign;
+ int pad;
+
+ for (testcount = 0; 1; testcount++)
+ {
+ nIntervals = GenerateRandomIntervals(intervals, MAXINTERVALS);
+ printf("%d nIntervals %d\n", testcount, nIntervals);
+
+ if (testcount & 1)
+ {
+ _RecordForceSetImplementation(BitVectorImplementation);
+ bsize = RecordSetMemoryRequirements(intervals, nIntervals, &balign);
+ _RecordForceSetImplementation(IntervalListImplementation);
+ rsize = RecordSetMemoryRequirements(intervals, nIntervals, &ralign);
+ pad = (ralign - (bsize & (ralign - 1))) & (ralign - 1);
+ bs = (RecordSetPtr)xalloc(bsize + pad + rsize );
+ if (!bs)
+ {
+ fprintf(stderr, "%d: failed to alloc memory for sets\n",
+ testcount);
+ continue;
+ }
+ rs = (RecordSetPtr)(((char *)bs) + bsize + pad);
+ }
+ else
+ {
+ bs = rs = NULL;
+ bsize = rsize = 0;
+ }
+
+ _RecordForceSetImplementation(BitVectorImplementation);
+ bs = RecordCreateSet(intervals, nIntervals, bs, bsize);
+ _RecordForceSetImplementation(IntervalListImplementation);
+ rs = RecordCreateSet(intervals, nIntervals, rs, rsize);
+
+ if (!bs || !rs)
+ {
+ fprintf(stderr, "%d: failed to create sets\n", testcount);
+ continue;
+ }
+
+ for (i = 0; i < 65535; i++)
+ {
+ unsigned long b, r;
+
+ b = RecordIsMemberOfSet(bs, i);
+ r = RecordIsMemberOfSet(rs, i);
+ if ( (b && !r) || (!b && r) )
+ {
+ fprintf(stderr, "%d: isMemberOfSet %d\n",
+ testcount, (int)i);
+ }
+ }
+
+ bi = RecordIterateSet(bs, NULL, &br);
+ ri = RecordIterateSet(rs, NULL, &rr);
+
+ while (bi && ri)
+ {
+ if ( (rr.first != br.first) || (rr.last != br.last) )
+ {
+ fprintf(stderr, "%d: iterateSet interval value mismatch\n",
+ testcount);
+ }
+ bi = RecordIterateSet(bs, bi, &br);
+ ri = RecordIterateSet(rs, ri, &rr);
+ }
+ if (bi != ri)
+ {
+ fprintf(stderr, "%d: iterateSet interval count mismatch\n",
+ testcount);
+ }
+
+
+ bi = NULL;
+ while (bi = RecordIterateSet(bs, bi, &br))
+ {
+ for (i = br.first; i <= br.last; i++)
+ {
+ if (!RecordIsMemberOfSet(rs, i))
+ {
+ fprintf(stderr, "%d: iterateSet b / isMemberOfSet r %d\n",
+ testcount, (int)i);
+ }
+ }
+ }
+
+ ri = NULL;
+ while (ri = RecordIterateSet(rs, ri, &rr))
+ {
+ for (i = rr.first; i <= rr.last; i++)
+ {
+ if (!RecordIsMemberOfSet(bs, i) )
+ {
+ fprintf(stderr, "%d: iterateSet r / isMemberOfSet b %d\n",
+ testcount, (int)i);
+ }
+ }
+ }
+
+ RecordDestroySet(bs);
+ RecordDestroySet(rs);
+
+ if (testcount & 1)
+ {
+ xfree(bs);
+ }
+ }
+}
+
+#endif /* TESTING */
diff --git a/xc/programs/Xserver/record/set.h b/xc/programs/Xserver/record/set.h
new file mode 100644
index 000000000..e208f96f4
--- /dev/null
+++ b/xc/programs/Xserver/record/set.h
@@ -0,0 +1,155 @@
+/* $TOG: set.h /main/2 1998/02/09 15:17:23 kaleb $ */
+
+/*
+
+Copyright 1995, 1998 The Open Group
+
+All Rights Reserved.
+
+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.
+
+*/
+
+/*
+ A Set Abstract Data Type (ADT) for the RECORD Extension
+ David P. Wiggins
+ 7/25/95
+
+ The RECORD extension server code needs to maintain sets of numbers
+ that designate protocol message types. In most cases the interval of
+ numbers starts at 0 and does not exceed 255, but in a few cases (minor
+ opcodes of extension requests) the maximum is 65535. This disparity
+ suggests that a single set representation may not be suitable for all
+ sets, especially given that server memory is precious. We introduce a
+ set ADT to hide implementation differences so that multiple
+ simultaneous set representations can exist. A single interface is
+ presented to the set user regardless of the implementation in use for
+ a particular set.
+
+ The existing RECORD SI appears to require only four set operations:
+ create (given a list of members), destroy, see if a particular number
+ is a member of the set, and iterate over the members of a set. Though
+ many more set operations are imaginable, to keep the code space down,
+ we won't provide any more operations than are needed.
+
+ The following types and functions/macros define the ADT.
+*/
+
+/* an interval of set members */
+typedef struct {
+ CARD16 first;
+ CARD16 last;
+} RecordSetInterval;
+
+typedef struct _RecordSetRec *RecordSetPtr; /* primary set type */
+
+typedef void *RecordSetIteratePtr;
+
+/* table of function pointers for set operations.
+ set users should never declare a variable of this type.
+*/
+typedef struct {
+ void (*DestroySet)(
+#if NeedNestedPrototypes
+ RecordSetPtr pSet
+#endif
+);
+ unsigned long (*IsMemberOfSet)(
+#if NeedNestedPrototypes
+ RecordSetPtr pSet,
+ int possible_member
+#endif
+);
+ RecordSetIteratePtr (*IterateSet)(
+#if NeedNestedPrototypes
+RecordSetPtr pSet,
+ RecordSetIteratePtr pIter,
+ RecordSetInterval *interval
+#endif
+);
+} RecordSetOperations;
+
+/* "base class" for sets.
+ set users should never declare a variable of this type.
+ */
+typedef struct _RecordSetRec {
+ RecordSetOperations *ops;
+} RecordSetRec;
+
+RecordSetPtr RecordCreateSet(
+#if NeedFunctionPrototypes
+ RecordSetInterval *intervals,
+ int nintervals,
+ void *pMem,
+ int memsize
+#endif
+);
+/*
+ RecordCreateSet creates and returns a new set having members specified
+ by intervals and nintervals. nintervals is the number of RecordSetInterval
+ structures pointed to by intervals. The elements belonging to the new
+ set are determined as follows. For each RecordSetInterval structure, the
+ elements between first and last inclusive are members of the new set.
+ If a RecordSetInterval's first field is greater than its last field, the
+ results are undefined. It is valid to create an empty set (nintervals ==
+ 0). If RecordCreateSet returns NULL, the set could not be created due
+ to resource constraints.
+*/
+
+int RecordSetMemoryRequirements(
+#if NeedFunctionPrototypes
+ RecordSetInterval * /*pIntervals*/,
+ int /*nintervals*/,
+ int * /*alignment*/
+#endif
+);
+
+#define RecordDestroySet(_pSet) \
+ /* void */ (*_pSet->ops->DestroySet)(/* RecordSetPtr */ _pSet)
+/*
+ RecordDestroySet frees all resources used by _pSet. _pSet should not be
+ used after it is destroyed.
+*/
+
+#define RecordIsMemberOfSet(_pSet, _m) \
+ /* unsigned long */ (*_pSet->ops->IsMemberOfSet)(/* RecordSetPtr */ _pSet, \
+ /* int */ _m)
+/*
+ RecordIsMemberOfSet returns a non-zero value if _m is a member of
+ _pSet, else it returns zero.
+*/
+
+#define RecordIterateSet(_pSet, _pIter, _interval) \
+ /* RecordSetIteratePtr */ (*_pSet->ops->IterateSet)(/* RecordSetPtr */ _pSet,\
+ /* RecordSetIteratePtr */ _pIter, /* RecordSetInterval */ _interval)
+/*
+ RecordIterateSet returns successive intervals of members of _pSet. If
+ _pIter is NULL, the first interval of set members is copied into _interval.
+ The return value should be passed as _pIter in the next call to
+ RecordIterateSet to obtain the next interval. When the return value is
+ NULL, there were no more intervals in the set, and nothing is copied into
+ the _interval parameter. Intervals appear in increasing numerical order
+ with no overlap between intervals. As such, the list of intervals produced
+ by RecordIterateSet may not match the list of intervals that were passed
+ in RecordCreateSet. Typical usage:
+
+ pIter = NULL;
+ while (pIter = RecordIterateSet(pSet, pIter, &interval))
+ {
+ process interval;
+ }
+*/
diff --git a/xc/programs/Xserver/xkb/Imakefile b/xc/programs/Xserver/xkb/Imakefile
new file mode 100644
index 000000000..58ed69bc7
--- /dev/null
+++ b/xc/programs/Xserver/xkb/Imakefile
@@ -0,0 +1,69 @@
+XCOMM $TOG: Imakefile /main/12 1997/07/16 14:51:50 kaleb $
+XCOMM $XFree86: xc/programs/Xserver/xkb/Imakefile,v 3.12 1999/04/17 09:08:51 dawes Exp $
+#define SGIHyperOpt
+#include <Server.tmpl>
+
+#ifdef SGIArchitecture
+EXTRA_ALLOC_DEFINES = -DFORCE_ALLOCA
+#endif
+
+#if BuildXInputExt
+XKBXI_SRCS = xkbPrOtherEv.c
+#ifdef OS2Architecture
+XKBXI_OBJS =
+#else
+XKBXI_OBJS = xkbPrOtherEv.o
+#endif
+#endif
+
+#ifdef DfltDisableXKB
+XKB_DISABLE = -DXKB_DFLT_DISABLED=1
+#else
+XKB_DISABLE = -DXKB_DFLT_DISABLED=0
+#endif
+
+XKB_DDXDEFS = XkbServerDefines
+
+ DDX_SRCS = ddxBeep.c ddxCtrls.c ddxFakeBtn.c ddxFakeMtn.c ddxInit.c \
+ ddxKeyClick.c ddxKillSrv.c ddxLEDs.c ddxVT.c ddxLoad.c \
+ ddxList.c ddxConfig.c ddxDevBtn.c xkbconfig.c
+ DDX_OBJS = ddxBeep.o ddxCtrls.o ddxFakeBtn.o ddxFakeMtn.o ddxInit.o \
+ ddxKeyClick.o ddxKillSrv.o ddxLEDs.o ddxVT.o ddxLoad.o \
+ ddxList.o ddxConfig.o ddxDevBtn.o xkbconfig.o
+ SRCS = xkb.c xkbUtils.c xkbEvents.c xkbAccessX.c xkbSwap.c \
+ xkbLEDs.c xkbInit.c xkbActions.c xkbPrKeyEv.c \
+ xkmread.c xkbtext.c xkbfmisc.c xkberrs.c xkbout.c maprules.c \
+ XKBMisc.c XKBMAlloc.c XKBAlloc.c XKBGAlloc.c \
+ $(XKBXI_SRCS) $(DDX_SRCS)
+ OBJS = xkb.o xkbUtils.o xkbEvents.o xkbAccessX.o xkbSwap.o \
+ xkbLEDs.o xkbInit.o xkbActions.o xkbPrKeyEv.o \
+ xkmread.o xkbtext.o xkbfmisc.o xkberrs.o xkbout.o maprules.o \
+ XKBMisc.o XKBMAlloc.o XKBAlloc.o XKBGAlloc.o \
+ $(XKBXI_OBJS) $(DDX_OBJS)
+ INCLUDES = -I../include -I$(XINCLUDESRC) -I$(EXTINCSRC)
+ LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln
+
+DEFINES = -DXKB_IN_SERVER $(EXTRA_ALLOC_DEFINES) $(XKB_DDXDEFS)
+XKB_DEFINES = -DXKB_BASE_DIRECTORY=\"$(LIBDIR)/xkb\" $(XKB_DISABLE)
+
+NormalLibraryObjectRule()
+NormalLibraryTarget(xkb,$(OBJS))
+LintLibraryTarget(xkb,$(SRCS))
+NormalLintTarget($(SRCS))
+
+SpecialCObjectRule(xkbInit,$(ICONFIGFILES),$(XKB_DEFINES))
+
+LinkSourceFile(maprules.c,$(XKBFILELIBSRC))
+LinkSourceFile(xkmread.c,$(XKBFILELIBSRC))
+LinkSourceFile(xkbtext.c,$(XKBFILELIBSRC))
+XCOMM avoid clash between XKBMisc.c and xkbmisc.c on NT
+LinkFile(xkbfmisc.c,$(XKBFILELIBSRC)/xkbmisc.c)
+LinkSourceFile(xkberrs.c,$(XKBFILELIBSRC))
+LinkSourceFile(xkbconfig.c,$(XKBFILELIBSRC))
+LinkSourceFile(xkbout.c,$(XKBFILELIBSRC))
+LinkSourceFile(XKBMisc.c,$(XLIBSRC))
+LinkSourceFile(XKBMAlloc.c,$(XLIBSRC))
+LinkSourceFile(XKBAlloc.c,$(XLIBSRC))
+LinkSourceFile(XKBGAlloc.c,$(XLIBSRC))
+
+DependTarget()
diff --git a/xc/programs/Xserver/xkb/ddxBeep.c b/xc/programs/Xserver/xkb/ddxBeep.c
new file mode 100644
index 000000000..538e321c3
--- /dev/null
+++ b/xc/programs/Xserver/xkb/ddxBeep.c
@@ -0,0 +1,359 @@
+/* $TOG: ddxBeep.c /main/5 1997/06/10 06:53:42 kaleb $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#include <stdio.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "XKBsrv.h"
+#include "XI.h"
+
+#if (defined(__osf__) && defined(__alpha))
+#include <sys/sysinfo.h>
+#include <alpha/hal_sysinfo.h>
+#include <alpha/prom.h>
+#endif
+
+/*#define FALLING_TONE 1*/
+/*#define RISING_TONE 1*/
+#define FALLING_TONE 10
+#define RISING_TONE 10
+#define SHORT_TONE 50
+#define SHORT_DELAY 60
+#define LONG_TONE 75
+#define VERY_LONG_TONE 100
+#define LONG_DELAY 85
+#define CLICK_DURATION 1
+
+#define DEEP_PITCH 250
+#define LOW_PITCH 500
+#define MID_PITCH 1000
+#define HIGH_PITCH 2000
+#define CLICK_PITCH 1500
+
+static unsigned long atomGeneration= -1;
+static Atom featureOn;
+static Atom featureOff;
+static Atom featureChange;
+static Atom ledOn;
+static Atom ledOff;
+static Atom ledChange;
+static Atom slowWarn;
+static Atom slowPress;
+static Atom slowReject;
+static Atom slowAccept;
+static Atom slowRelease;
+static Atom stickyLatch;
+static Atom stickyLock;
+static Atom stickyUnlock;
+static Atom bounceReject;
+static char doesPitch = 1;
+
+#define FEATURE_ON "AX_FeatureOn"
+#define FEATURE_OFF "AX_FeatureOff"
+#define FEATURE_CHANGE "AX_FeatureChange"
+#define LED_ON "AX_IndicatorOn"
+#define LED_OFF "AX_IndicatorOff"
+#define LED_CHANGE "AX_IndicatorChange"
+#define SLOW_WARN "AX_SlowKeysWarning"
+#define SLOW_PRESS "AX_SlowKeyPress"
+#define SLOW_REJECT "AX_SlowKeyReject"
+#define SLOW_ACCEPT "AX_SlowKeyAccept"
+#define SLOW_RELEASE "AX_SlowKeyRelease"
+#define STICKY_LATCH "AX_StickyLatch"
+#define STICKY_LOCK "AX_StickyLock"
+#define STICKY_UNLOCK "AX_StickyUnlock"
+#define BOUNCE_REJECT "AX_BounceKeyReject"
+
+#define MAKE_ATOM(a) MakeAtom(a,sizeof(a)-1,True)
+
+static void
+#if NeedFunctionPrototypes
+_XkbDDXBeepInitAtoms(void)
+#else
+_XkbDDXBeepInitAtoms()
+#endif
+{
+ featureOn= MAKE_ATOM(FEATURE_ON);
+ featureOff= MAKE_ATOM(FEATURE_OFF);
+ featureChange= MAKE_ATOM(FEATURE_CHANGE);
+ ledOn= MAKE_ATOM(LED_ON);
+ ledOff= MAKE_ATOM(LED_OFF);
+ ledChange= MAKE_ATOM(LED_CHANGE);
+ slowWarn= MAKE_ATOM(SLOW_WARN);
+ slowPress= MAKE_ATOM(SLOW_PRESS);
+ slowReject= MAKE_ATOM(SLOW_REJECT);
+ slowAccept= MAKE_ATOM(SLOW_ACCEPT);
+ slowRelease= MAKE_ATOM(SLOW_RELEASE);
+ stickyLatch= MAKE_ATOM(STICKY_LATCH);
+ stickyLock= MAKE_ATOM(STICKY_LOCK);
+ stickyUnlock= MAKE_ATOM(STICKY_UNLOCK);
+ bounceReject= MAKE_ATOM(BOUNCE_REJECT);
+#if (defined(__osf__) && defined(__alpha))
+ /* [[[ WDW - Some bells do not allow for pitch changes.
+ * Maybe this could become part of the keymap? ]]]
+ */
+ {
+ char keyboard[8];
+
+ /* Find the class of keyboard being used.
+ */
+ keyboard[0] = '\0';
+ if (-1 == getsysinfo(GSI_KEYBOARD,
+ keyboard, sizeof(keyboard),
+ 0, NULL))
+ keyboard[0] = '\0';
+
+ if ((strcmp(keyboard,"LK201") == 0) ||
+ (strcmp(keyboard,"LK401") == 0) ||
+ (strcmp(keyboard,"LK421") == 0) ||
+ (strcmp(keyboard,"LK443") == 0))
+ doesPitch = 0;
+ }
+#endif
+ return;
+}
+
+static CARD32
+#if NeedFunctionPrototypes
+_XkbDDXBeepExpire(OsTimerPtr timer,CARD32 now,pointer arg)
+#else
+_XkbDDXBeepExpire(timer,now,arg)
+ OsTimerPtr timer;
+ CARD32 now;
+ pointer arg;
+#endif
+{
+DeviceIntPtr dev= (DeviceIntPtr)arg;
+KbdFeedbackPtr feed;
+KeybdCtrl * ctrl;
+XkbSrvInfoPtr xkbInfo;
+CARD32 next;
+int pitch,duration;
+int oldPitch,oldDuration;
+Atom name;
+
+ if ((dev==NULL)||(dev->key==NULL)||(dev->key->xkbInfo==NULL)||
+ (dev->kbdfeed==NULL))
+ return 0;
+ if (atomGeneration!=serverGeneration) {
+ _XkbDDXBeepInitAtoms();
+ atomGeneration= serverGeneration;
+ }
+
+ feed= dev->kbdfeed;
+ ctrl= &feed->ctrl;
+ xkbInfo= dev->key->xkbInfo;
+ next= 0;
+ pitch= oldPitch= ctrl->bell_pitch;
+ duration= oldDuration= ctrl->bell_duration;
+#ifdef DEBUG
+ if (xkbDebugFlags>1)
+ ErrorF("beep: %d (count= %d)\n",xkbInfo->beepType,xkbInfo->beepCount);
+#endif
+ name= None;
+ switch (xkbInfo->beepType) {
+ default:
+ ErrorF("Unknown beep type %d\n",xkbInfo->beepType);
+ case _BEEP_NONE:
+ duration= 0;
+ break;
+
+ /* When an LED is turned on, we want a high-pitched beep.
+ * When the LED it turned off, we want a low-pitched beep.
+ * If we cannot do pitch, we want a single beep for on and two
+ * beeps for off.
+ */
+ case _BEEP_LED_ON:
+ if (name==None) name= ledOn;
+ duration= SHORT_TONE;
+ pitch= HIGH_PITCH;
+ break;
+ case _BEEP_LED_OFF:
+ if (name==None) name= ledOff;
+ duration= SHORT_TONE;
+ pitch= LOW_PITCH;
+ if (!doesPitch && xkbInfo->beepCount<1)
+ next = SHORT_DELAY;
+ break;
+
+ /* When a Feature is turned on, we want an up-siren.
+ * When a Feature is turned off, we want a down-siren.
+ * If we cannot do pitch, we want a single beep for on and two
+ * beeps for off.
+ */
+ case _BEEP_FEATURE_ON:
+ if (name==None) name= featureOn;
+ if (xkbInfo->beepCount<1) {
+ pitch= LOW_PITCH;
+ duration= VERY_LONG_TONE;
+ if (doesPitch)
+ next= SHORT_DELAY;
+ }
+ else {
+ pitch= MID_PITCH;
+ duration= SHORT_TONE;
+ }
+ break;
+
+ case _BEEP_FEATURE_OFF:
+ if (name==None) name= featureOff;
+ if (xkbInfo->beepCount<1) {
+ pitch= MID_PITCH;
+ if (doesPitch)
+ duration= VERY_LONG_TONE;
+ else duration= SHORT_TONE;
+ next= SHORT_DELAY;
+ }
+ else {
+ pitch= LOW_PITCH;
+ duration= SHORT_TONE;
+ }
+ break;
+
+ /* Two high beeps indicate an LED or Feature changed
+ * state, but that another LED or Feature is also on.
+ * [[[WDW - This is not in AccessDOS ]]]
+ */
+ case _BEEP_LED_CHANGE:
+ if (name==None) name= ledChange;
+ case _BEEP_FEATURE_CHANGE:
+ if (name==None) name= featureChange;
+ duration= SHORT_TONE;
+ pitch= HIGH_PITCH;
+ if (xkbInfo->beepCount<1) {
+ next= SHORT_DELAY;
+ }
+ break;
+
+ /* Three high-pitched beeps are the warning that SlowKeys
+ * is going to be turned on or off.
+ */
+ case _BEEP_SLOW_WARN:
+ if (name==None) name= slowWarn;
+ duration= SHORT_TONE;
+ pitch= HIGH_PITCH;
+ if (xkbInfo->beepCount<2)
+ next= SHORT_DELAY;
+ break;
+
+ /* Click on SlowKeys press and accept.
+ * Deep pitch when a SlowKey or BounceKey is rejected.
+ * [[[WDW - Rejects are not in AccessDOS ]]]
+ * If we cannot do pitch, we want single beeps.
+ */
+ case _BEEP_SLOW_PRESS:
+ if (name==None) name= slowPress;
+ case _BEEP_SLOW_ACCEPT:
+ if (name==None) name= slowAccept;
+ case _BEEP_SLOW_RELEASE:
+ if (name==None) name= slowRelease;
+ duration= CLICK_DURATION;
+ pitch= CLICK_PITCH;
+ break;
+ case _BEEP_BOUNCE_REJECT:
+ if (name==None) name= bounceReject;
+ case _BEEP_SLOW_REJECT:
+ if (name==None) name= slowReject;
+ duration= SHORT_TONE;
+ pitch= DEEP_PITCH;
+ break;
+
+ /* Low followed by high pitch when a StickyKey is latched.
+ * High pitch when a StickyKey is locked.
+ * Low pitch when unlocked.
+ * If we cannot do pitch, two beeps for latch, nothing for
+ * lock, and two for unlock.
+ */
+ case _BEEP_STICKY_LATCH:
+ if (name==None) name= stickyLatch;
+ duration= SHORT_TONE;
+ if (xkbInfo->beepCount<1) {
+ next= SHORT_DELAY;
+ pitch= LOW_PITCH;
+ }
+ else pitch= HIGH_PITCH;
+ break;
+ case _BEEP_STICKY_LOCK:
+ if (name==None) name= stickyLock;
+ if (doesPitch) {
+ duration= SHORT_TONE;
+ pitch= HIGH_PITCH;
+ }
+ break;
+ case _BEEP_STICKY_UNLOCK:
+ if (name==None) name= stickyUnlock;
+ duration= SHORT_TONE;
+ pitch= LOW_PITCH;
+ if (!doesPitch && xkbInfo->beepCount<1)
+ next = SHORT_DELAY;
+ break;
+ }
+ if (duration>0) {
+ ctrl->bell_duration= duration;
+ ctrl->bell_pitch= pitch;
+ if (xkbInfo->beepCount==0) {
+ XkbHandleBell(0,0,dev,ctrl->bell,(pointer)ctrl,KbdFeedbackClass,name,None,
+ NULL);
+ }
+ else if (xkbInfo->desc->ctrls->enabled_ctrls&XkbAudibleBellMask) {
+ (*dev->kbdfeed->BellProc)(ctrl->bell,dev,(pointer)ctrl,KbdFeedbackClass);
+ }
+ ctrl->bell_duration= oldDuration;
+ ctrl->bell_pitch= oldPitch;
+ xkbInfo->beepCount++;
+ }
+ return next;
+}
+
+int
+#if NeedFunctionPrototypes
+XkbDDXAccessXBeep(DeviceIntPtr dev,unsigned what,unsigned which)
+#else
+XkbDDXAccessXBeep(dev,what,which)
+ DeviceIntPtr dev;
+ unsigned what;
+ unsigned which;
+#endif
+{
+XkbSrvInfoRec *xkbInfo= dev->key->xkbInfo;
+CARD32 next;
+
+ xkbInfo->beepType= what;
+ xkbInfo->beepCount= 0;
+ next= _XkbDDXBeepExpire(NULL,0,(pointer)dev);
+ if (next>0) {
+ xkbInfo->beepTimer= TimerSet(xkbInfo->beepTimer,
+ 0, next,
+ _XkbDDXBeepExpire, (pointer)dev);
+ }
+ return 1;
+}
diff --git a/xc/programs/Xserver/xkb/ddxConfig.c b/xc/programs/Xserver/xkb/ddxConfig.c
new file mode 100644
index 000000000..e3fdb10e9
--- /dev/null
+++ b/xc/programs/Xserver/xkb/ddxConfig.c
@@ -0,0 +1,221 @@
+/* $XConsortium: ddxConfig.c /main/8 1996/09/28 17:15:56 rws $ */
+/* $XFree86: xc/programs/Xserver/xkb/ddxConfig.c,v 3.3 1996/12/23 07:10:06 dawes Exp $ */
+/************************************************************
+Copyright (c) 1995 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 <stdio.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "os.h"
+#define XKBSRV_NEED_FILE_FUNCS
+#include "XKBsrv.h"
+#include <X11/extensions/XKBconfig.h>
+
+Bool
+#if NeedFunctionPrototypes
+XkbDDXApplyConfig(XPointer cfg_in,XkbSrvInfoPtr info)
+#else
+XkbDDXApplyConfig(cfg_in,info)
+ XPointer cfg_in;
+ XkbSrvInfoPtr info;
+#endif
+{
+XkbConfigRtrnPtr rtrn;
+XkbDescPtr xkb;
+Bool ok;
+XkbEventCauseRec cause;
+
+ xkb= info->desc;
+ rtrn= (XkbConfigRtrnPtr)cfg_in;
+ if (rtrn==NULL)
+ return True;
+ ok= XkbCFApplyRtrnValues(rtrn,XkbCFDflts,xkb);
+ if (rtrn->initial_mods.replace) {
+ info->state.locked_mods= rtrn->initial_mods.mods;
+ }
+ else {
+ info->state.locked_mods|= rtrn->initial_mods.mods;
+ if (rtrn->initial_mods.mods_clear)
+ info->state.locked_mods&= ~rtrn->initial_mods.mods_clear;
+ }
+ XkbComputeDerivedState(info);
+ XkbSetCauseUnknown(&cause);
+ XkbUpdateIndicators(info->device,XkbAllIndicatorsMask,False,NULL,&cause);
+ if (info->device && info->device->kbdfeed) {
+ DeviceIntPtr dev;
+ KeybdCtrl newCtrl;
+ dev= info->device;
+ newCtrl= dev->kbdfeed->ctrl;
+ if (rtrn->click_volume>=0)
+ newCtrl.click= rtrn->click_volume;
+ if (rtrn->bell_volume>=0)
+ newCtrl.bell= rtrn->bell_volume;
+ if (rtrn->bell_pitch>0)
+ newCtrl.bell_pitch= rtrn->bell_pitch;
+ if (rtrn->bell_duration>0)
+ newCtrl.bell_duration= rtrn->bell_duration;
+ if (dev->kbdfeed->CtrlProc)
+ (*dev->kbdfeed->CtrlProc)(dev,&newCtrl);
+ }
+ XkbCFFreeRtrn(rtrn,XkbCFDflts,xkb);
+ return ok;
+}
+
+XPointer
+#if NeedFunctionPrototypes
+XkbDDXPreloadConfig( char ** rulesRtrn,
+ XkbRF_VarDefsPtr defs,
+ XkbComponentNamesPtr names,
+ DeviceIntPtr dev)
+#else
+XkbDDXPreloadConfig(rulesRtrn,defs,names,dev)
+ char ** rulesRtrn;
+ XkbRF_VarDefsPtr defs;
+ XkbComponentNamesPtr names;
+ DeviceIntPtr dev;
+#endif
+{
+char buf[PATH_MAX];
+char * dName;
+FILE * file;
+XkbConfigRtrnPtr rtrn;
+extern char * display;
+
+#if defined(MetroLink)
+ if (dev && dev->name)
+ dName= dev->name;
+ else dName= "";
+ /* It doesn't appear that XkbBaseDirectory could ever get set to NULL */
+ sprintf(buf,"%s/X%s-config%s%s",XkbBaseDirectory,display,
+ (dName[0]?".":""),dName);
+#else
+ if (dev && dev->name)
+ dName= dev->name;
+ else dName= "";
+ if (XkbBaseDirectory!=NULL) {
+ if (strlen(XkbBaseDirectory)+strlen(display)
+ +strlen(dName)+10+(dName[0]?1:0) > PATH_MAX)
+ {
+#ifdef DEBUG
+ ErrorF("path exceeds max length\n");
+#endif
+ return NULL;
+ }
+ sprintf(buf,"%s/X%s-config%s%s",XkbBaseDirectory,display,
+ (dName[0]?".":""),dName);
+ }
+ else {
+ if (strlen(display)+strlen(dName)+10+(dName[0]?1:0) > PATH_MAX)
+ {
+#ifdef DEBUG
+ ErrorF("path exceeds max length\n");
+#endif
+ return NULL;
+ }
+ sprintf(buf,"X%s-config%s%s",display,(dName[0]?".":""),dName);
+ }
+#endif
+#ifdef __EMX__
+ strcpy(buf,(char*)__XOS2RedirRoot(buf));
+#endif
+#ifdef DEBUG
+ ErrorF("Looking for keyboard configuration in %s...",buf);
+#endif
+ file= fopen(buf,"r");
+ if (file==NULL) {
+#ifdef DEBUG
+ ErrorF("file not found\n");
+#endif
+ return NULL;
+ }
+ rtrn= _XkbTypedCalloc(1,XkbConfigRtrnRec);
+ if (rtrn!=NULL) {
+ if (!XkbCFParse(file,XkbCFDflts,NULL,rtrn)) {
+#ifdef DEBUG
+ ErrorF("error\n");
+#endif
+ ErrorF("Error parsing config file: ");
+ XkbCFReportError(stderr,buf,rtrn->error,rtrn->line);
+ _XkbFree(rtrn);
+ fclose(file);
+ return NULL;
+ }
+#ifdef DEBUG
+ ErrorF("found it\n");
+#endif
+ if (rtrn->rules_file) {
+ *rulesRtrn= rtrn->rules_file;
+ rtrn->rules_file= NULL;
+ }
+ if (rtrn->model) {
+ defs->model= rtrn->model;
+ rtrn->model= NULL;
+ }
+ if (rtrn->layout) {
+ defs->layout= rtrn->layout;
+ rtrn->layout= NULL;
+ }
+ if (rtrn->variant) {
+ defs->variant= rtrn->variant;
+ rtrn->variant= NULL;
+ }
+ if (rtrn->options) {
+ defs->options= rtrn->options;
+ rtrn->options= NULL;
+ }
+ XkbSetRulesUsed(defs);
+
+ if (rtrn->keycodes!=NULL) {
+ names->keycodes= rtrn->keycodes;
+ rtrn->keycodes= NULL;
+ }
+ if (rtrn->geometry!=NULL) {
+ names->geometry= rtrn->geometry;
+ rtrn->geometry= NULL;
+ }
+ if (rtrn->symbols!=NULL) {
+ if (rtrn->phys_symbols==NULL)
+ rtrn->phys_symbols= _XkbDupString(names->symbols);
+ names->symbols= rtrn->symbols;
+ rtrn->symbols= NULL;
+ }
+ if (rtrn->types!=NULL) {
+ names->types= rtrn->types;
+ rtrn->types= NULL;
+ }
+ if (rtrn->compat!=NULL) {
+ names->compat= rtrn->compat;
+ rtrn->compat= NULL;
+ }
+ }
+ fclose(file);
+ return (XPointer)rtrn;
+}
diff --git a/xc/programs/Xserver/xkb/ddxCtrls.c b/xc/programs/Xserver/xkb/ddxCtrls.c
new file mode 100644
index 000000000..b8000fd95
--- /dev/null
+++ b/xc/programs/Xserver/xkb/ddxCtrls.c
@@ -0,0 +1,133 @@
+/* $XConsortium: ddxCtrls.c /main/4 1996/02/02 14:39:24 kaleb $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#include <stdio.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "XKBsrv.h"
+#include "XI.h"
+
+void
+#if NeedFunctionPrototypes
+XkbDDXKeybdCtrlProc(DeviceIntPtr dev,KeybdCtrl *ctrl)
+#else
+XkbDDXKeybdCtrlProc(dev,ctrl)
+ DeviceIntPtr dev;
+ KeybdCtrl * ctrl;
+#endif
+{
+int realRepeat;
+
+ realRepeat= ctrl->autoRepeat;
+ if ((dev->kbdfeed)&&(XkbDDXUsesSoftRepeat(dev)))
+ ctrl->autoRepeat= 0;
+#ifdef DEBUG
+if (xkbDebugFlags&0x4) {
+ ErrorF("XkbDDXKeybdCtrlProc: setting repeat to %d (real repeat is %d)\n",
+ ctrl->autoRepeat,realRepeat);
+}
+#endif
+ if (dev->key && dev->key->xkbInfo && dev->key->xkbInfo->kbdProc)
+ (*dev->key->xkbInfo->kbdProc)(dev,ctrl);
+ ctrl->autoRepeat= realRepeat;
+ return;
+}
+
+
+int
+#if NeedFunctionPrototypes
+XkbDDXUsesSoftRepeat(DeviceIntPtr pXDev)
+#else
+XkbDDXUsesSoftRepeat(pXDev)
+ DeviceIntPtr pXDev;
+#endif
+{
+#ifndef XKB_ALWAYS_USES_SOFT_REPEAT
+ if (pXDev && pXDev->kbdfeed ) {
+ if (pXDev->kbdfeed->ctrl.autoRepeat) {
+ if (pXDev->key && pXDev->key->xkbInfo) {
+ XkbDescPtr xkb;
+ xkb= pXDev->key->xkbInfo->desc;
+ if ((xkb->ctrls->repeat_delay == 660) &&
+ (xkb->ctrls->repeat_interval == 40) &&
+ ((xkb->ctrls->enabled_ctrls&(XkbSlowKeysMask|
+ XkbBounceKeysMask|
+ XkbMouseKeysMask))==0)) {
+ return 0;
+ }
+ return ((xkb->ctrls->enabled_ctrls&XkbRepeatKeysMask)!=0);
+ }
+ }
+ }
+ return 0;
+#else
+ return 1;
+#endif
+}
+
+void
+#if NeedFunctionPrototypes
+XkbDDXChangeControls(DeviceIntPtr dev,XkbControlsPtr old,XkbControlsPtr new)
+#else
+XkbDDXChangeControls(dev,old,new)
+ DeviceIntPtr dev;
+ XkbControlsPtr old;
+ XkbControlsPtr new;
+#endif
+{
+unsigned changed;
+
+ changed= new->enabled_ctrls^old->enabled_ctrls;
+#ifdef NOTDEF
+ if (changed&XkbRepeatKeysMask) {
+ if (dev->kbdfeed) {
+ int realRepeat;
+
+ if (new->enabled_ctrls&XkbRepeatKeysMask)
+ dev->kbdfeed->ctrl.autoRepeat= realRepeat= 1;
+ else dev->kbdfeed->ctrl.autoRepeat= realRepeat= 0;
+
+ if (XkbDDXUsesSoftRepeat(dev))
+ dev->kbdfeed->ctrl.autoRepeat= FALSE;
+ if (dev->kbdfeed->CtrlProc)
+ (*dev->kbdfeed->CtrlProc)(dev,&dev->kbdfeed->ctrl);
+ dev->kbdfeed->ctrl.autoRepeat= realRepeat;
+ }
+ }
+#endif
+ if (changed&XkbPerKeyRepeatMask) {
+ if (dev->kbdfeed->CtrlProc)
+ (*dev->kbdfeed->CtrlProc)(dev,&dev->kbdfeed->ctrl);
+ }
+ return;
+}
+
diff --git a/xc/programs/Xserver/xkb/ddxDevBtn.c b/xc/programs/Xserver/xkb/ddxDevBtn.c
new file mode 100644
index 000000000..5f933276b
--- /dev/null
+++ b/xc/programs/Xserver/xkb/ddxDevBtn.c
@@ -0,0 +1,104 @@
+/* $XConsortium: ddxDevBtn.c /main/2 1996/03/01 14:30:47 kaleb $ */
+/************************************************************
+Copyright (c) 1995 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 <stdio.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "XKBsrv.h"
+#include "XI.h"
+#include "XIproto.h"
+
+extern int DeviceButtonPress,DeviceButtonRelease,DeviceValuator;
+
+void
+#if NeedFunctionPrototypes
+XkbDDXFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
+#else
+XkbDDXFakeDeviceButton(dev,press,button)
+ DeviceIntPtr dev;
+ Bool press;
+ int button;
+#endif
+{
+int * devVal;
+INT32 * evVal;
+xEvent events[2];
+deviceKeyButtonPointer *btn;
+deviceValuator * val;
+int x,y;
+int nAxes, i, count;
+
+ if ((dev==(DeviceIntPtr)LookupPointerDevice())||(!dev->public.on))
+ return;
+
+ nAxes = (dev->valuator?dev->valuator->numAxes:0);
+ if (nAxes > 6)
+ nAxes = 6;
+
+ GetSpritePosition(&x,&y);
+ btn= (deviceKeyButtonPointer *) &events[0];
+ val= (deviceValuator *) &events[1];
+ if (press) btn->type= DeviceButtonPress;
+ else btn->type= DeviceButtonRelease;
+ btn->detail= button;
+ btn->time= GetTimeInMillis();
+ btn->root_x= x;
+ btn->root_y= y;
+ btn->deviceid= dev->id;
+ count= 1;
+ if (nAxes>0) {
+ btn->deviceid|= 0x80;
+ val->type = DeviceValuator;
+ val->deviceid = dev->id;
+ val->first_valuator = 0;
+
+ evVal= &val->valuator0;
+ devVal= dev->valuator->axisVal;
+ for (i=nAxes;i>0;i--) {
+ *evVal++ = *devVal++;
+ if (evVal > &val->valuator5) {
+ int tmp = val->first_valuator+6;
+ val->num_valuators = 6;
+ val++;
+ evVal= &val->valuator0;
+ val->first_valuator= tmp;
+ }
+ }
+ if ((nAxes % 6) != 0) {
+ val->num_valuators = (nAxes % 6);
+ }
+ count= 1+((nAxes+5)/6);
+ }
+
+ (*dev->public.processInputProc)((xEventPtr)btn, dev, count);
+ return;
+}
diff --git a/xc/programs/Xserver/xkb/ddxFakeBtn.c b/xc/programs/Xserver/xkb/ddxFakeBtn.c
new file mode 100644
index 000000000..103a4498a
--- /dev/null
+++ b/xc/programs/Xserver/xkb/ddxFakeBtn.c
@@ -0,0 +1,62 @@
+/* $XConsortium: ddxFakeBtn.c /main/2 1996/01/01 10:55:09 kaleb $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#include <stdio.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "XKBsrv.h"
+#include "XI.h"
+
+void
+#if NeedFunctionPrototypes
+XkbDDXFakePointerButton(int event,int button)
+#else
+XkbDDXFakePointerButton(event,button)
+ int event;
+ int button;
+#endif
+{
+xEvent ev;
+int x,y;
+DevicePtr ptr;
+
+ if ((ptr = LookupPointerDevice())==NULL)
+ return;
+ GetSpritePosition(&x,&y);
+ ev.u.u.type = event;
+ ev.u.u.detail = button;
+ ev.u.keyButtonPointer.time = GetTimeInMillis();
+ ev.u.keyButtonPointer.rootX = x;
+ ev.u.keyButtonPointer.rootY = y;
+ (*ptr->processInputProc)( &ev, (DeviceIntPtr)ptr, 1 );
+ return;
+}
diff --git a/xc/programs/Xserver/xkb/ddxFakeMtn.c b/xc/programs/Xserver/xkb/ddxFakeMtn.c
new file mode 100644
index 000000000..d864ce2d2
--- /dev/null
+++ b/xc/programs/Xserver/xkb/ddxFakeMtn.c
@@ -0,0 +1,76 @@
+/* $XConsortium: ddxFakeMtn.c /main/2 1996/01/01 10:55:18 kaleb $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#include <stdio.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "XKBsrv.h"
+#include "XI.h"
+
+extern WindowPtr GetSpriteWindow(
+#if NeedFunctionPrototypes
+ void
+#endif
+);
+
+void
+#if NeedFunctionPrototypes
+XkbDDXFakePointerMotion(unsigned flags,int x,int y)
+#else
+XkbDDXFakePointerMotion(flags,x,y)
+ unsigned flags;
+ int x;
+ int y;
+#endif
+{
+ScreenPtr pScreen;
+int oldX,oldY;
+
+ pScreen= GetSpriteWindow()->drawable.pScreen;
+ GetSpritePosition(&oldX,&oldY);
+ if (flags&XkbSA_MoveAbsoluteX)
+ oldX= x;
+ else oldX+= x;
+ if (flags&XkbSA_MoveAbsoluteY)
+ oldY= y;
+ else oldY+= y;
+
+ if (oldX<0) oldX= 0;
+ else if (oldX>=pScreen->width) oldX= pScreen->width-1;
+ if (oldY<0) oldY= 0;
+ else if (oldY>=pScreen->height) oldY= pScreen->height-1;
+
+ if (pScreen->SetCursorPosition)
+ (*pScreen->SetCursorPosition)(pScreen, oldX, oldY, TRUE);
+ return;
+}
+
diff --git a/xc/programs/Xserver/xkb/ddxInit.c b/xc/programs/Xserver/xkb/ddxInit.c
new file mode 100644
index 000000000..ebe698811
--- /dev/null
+++ b/xc/programs/Xserver/xkb/ddxInit.c
@@ -0,0 +1,48 @@
+/* $XConsortium: ddxInit.c /main/2 1996/01/01 10:55:27 kaleb $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#include <stdio.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "XKBsrv.h"
+#include "XI.h"
+
+int
+#if NeedFunctionPrototypes
+XkbDDXInitDevice(DeviceIntPtr dev)
+#else
+XkbDDXInitDevice(dev)
+ DeviceIntPtr dev;
+#endif
+{
+ return 1;
+}
diff --git a/xc/programs/Xserver/xkb/ddxKeyClick.c b/xc/programs/Xserver/xkb/ddxKeyClick.c
new file mode 100644
index 000000000..8b285188a
--- /dev/null
+++ b/xc/programs/Xserver/xkb/ddxKeyClick.c
@@ -0,0 +1,54 @@
+/* $XConsortium: ddxKeyClick.c /main/2 1996/01/01 10:55:36 kaleb $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#include <stdio.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "XKBsrv.h"
+#include "XI.h"
+
+void
+#if NeedFunctionPrototypes
+XkbDDXKeyClick(DeviceIntPtr pXDev,int keycode,int synthetic)
+#else
+XkbDDXKeyClick(pXDev,keycode,synthetic)
+ DeviceIntPtr pXDev;
+ int keycode;
+ int synthetic;
+#endif
+{
+#ifdef DEBUG
+ if (xkbDebugFlags)
+ ErrorF("Click.\n");
+#endif
+ return;
+}
diff --git a/xc/programs/Xserver/xkb/ddxKillSrv.c b/xc/programs/Xserver/xkb/ddxKillSrv.c
new file mode 100644
index 000000000..ed49b93a3
--- /dev/null
+++ b/xc/programs/Xserver/xkb/ddxKillSrv.c
@@ -0,0 +1,51 @@
+/* $XConsortium: ddxKillSrv.c /main/2 1996/01/01 10:55:46 kaleb $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#include <stdio.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "XKBsrv.h"
+#include "XI.h"
+
+int
+#if NeedFunctionPrototypes
+XkbDDXTerminateServer(DeviceIntPtr dev,KeyCode key,XkbAction *act)
+#else
+XkbDDXTerminateServer(dev,key,act)
+ DeviceIntPtr dev;
+ KeyCode key;
+ XkbAction *act;
+#endif
+{
+ GiveUp(1);
+ return 0;
+}
diff --git a/xc/programs/Xserver/xkb/ddxLEDs.c b/xc/programs/Xserver/xkb/ddxLEDs.c
new file mode 100644
index 000000000..3149aa505
--- /dev/null
+++ b/xc/programs/Xserver/xkb/ddxLEDs.c
@@ -0,0 +1,82 @@
+/* $XConsortium: ddxLEDs.c /main/3 1996/01/14 16:45:52 kaleb $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#include <stdio.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "XKBsrv.h"
+#include "XI.h"
+
+void
+#if NeedFunctionPrototypes
+XkbDDXUpdateIndicators(DeviceIntPtr dev,CARD32 new)
+#else
+XkbDDXUpdateIndicators(dev,new)
+ DeviceIntPtr dev;
+ CARD32 new;
+#endif
+{
+ dev->kbdfeed->ctrl.leds= new;
+ (*dev->kbdfeed->CtrlProc)(dev,&dev->kbdfeed->ctrl);
+ return;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbDDXUpdateDeviceIndicators( DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ CARD32 new)
+#else
+XkbDDXUpdateDeviceIndicators(dev,sli,new)
+ DeviceIntPtr dev;
+ XkbSrvLedInfoPtr sli;
+ CARD32 new;
+#endif
+{
+ if (sli->fb.kf==dev->kbdfeed)
+ XkbDDXUpdateIndicators(dev,new);
+ else if (sli->class==KbdFeedbackClass) {
+ KbdFeedbackPtr kf;
+ kf= sli->fb.kf;
+ if (kf && kf->CtrlProc) {
+ (*kf->CtrlProc)(dev,&kf->ctrl);
+ }
+ }
+ else if (sli->class==LedFeedbackClass) {
+ LedFeedbackPtr lf;
+ lf= sli->fb.lf;
+ if (lf && lf->CtrlProc) {
+ (*lf->CtrlProc)(dev,&lf->ctrl);
+ }
+ }
+ return;
+}
diff --git a/xc/programs/Xserver/xkb/ddxList.c b/xc/programs/Xserver/xkb/ddxList.c
new file mode 100644
index 000000000..954319085
--- /dev/null
+++ b/xc/programs/Xserver/xkb/ddxList.c
@@ -0,0 +1,310 @@
+/* $TOG: ddxList.c /main/6 1997/06/10 06:53:45 kaleb $ */
+/************************************************************
+Copyright (c) 1995 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+/* $XFree86: xc/programs/Xserver/xkb/ddxList.c,v 3.5 1997/09/14 13:15:09 dawes Exp $ */
+
+#include <stdio.h>
+#include <ctype.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xos.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include <X11/extensions/XKM.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#define XKBSRV_NEED_FILE_FUNCS
+#include "XKBsrv.h"
+#include "XI.h"
+
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+
+/***====================================================================***/
+
+static char *componentDirs[_XkbListNumComponents] = {
+ "keymap", "keycodes", "types", "compat", "symbols", "geometry"
+};
+
+/***====================================================================***/
+
+Status
+#if NeedFunctionPrototypes
+_AddListComponent( XkbSrvListInfoPtr list,
+ int what,
+ unsigned flags,
+ char * str,
+ ClientPtr client)
+#else
+_AddListComponent(list,what,flags,str,client)
+ XkbSrvListInfoPtr list;
+ int what;
+ unsigned flags;
+ char * str;
+ ClientPtr client;
+#endif
+{
+int slen,wlen;
+unsigned char * wire8;
+unsigned short *wire16;
+char * tmp;
+
+ if (list->nTotal>=list->maxRtrn) {
+ list->nTotal++;
+ return Success;
+ }
+ tmp= strchr(str,')');
+ if ((tmp==NULL)&&((tmp=strchr(str,'('))==NULL)) {
+ slen= strlen(str);
+ while ((slen>0) && isspace(str[slen-1])) {
+ slen--;
+ }
+ }
+ else {
+ slen= (tmp-str+1);
+ }
+ wlen= (((slen+1)/2)*2)+4; /* four bytes for flags and length, pad to */
+ /* 2-byte boundary */
+ if ((list->szPool-list->nPool)<wlen) {
+ if (wlen>1024) list->szPool+= XkbPaddedSize(wlen*2);
+ else list->szPool+= 1024;
+ list->pool= _XkbTypedRealloc(list->pool,list->szPool,char);
+ if (!list->pool)
+ return BadAlloc;
+ }
+ wire16= (unsigned short *)&list->pool[list->nPool];
+ wire8= (unsigned char *)&wire16[2];
+ wire16[0]= flags;
+ wire16[1]= slen;
+ memcpy(wire8,str,slen);
+ if (client->swapped) {
+ register int n;
+ swaps(&wire16[0],n);
+ swaps(&wire16[1],n);
+ }
+ list->nPool+= wlen;
+ list->nFound[what]++;
+ list->nTotal++;
+ return Success;
+}
+
+/***====================================================================***/
+static Status
+#if NeedFunctionPrototypes
+XkbDDXListComponent( DeviceIntPtr dev,
+ int what,
+ XkbSrvListInfoPtr list,
+ ClientPtr client)
+#else
+XkbDDXListComponent(dev,what,list,client)
+ DeviceIntPtr dev;
+ int what;
+ XkbSrvListInfoPtr list;
+ ClientPtr client;
+#endif
+{
+char *file,*map,*tmp,buf[PATH_MAX];
+FILE *in;
+Status status;
+int rval;
+Bool haveDir;
+#ifdef WIN32
+char tmpname[32];
+#endif
+
+ if ((list->pattern[what]==NULL)||(list->pattern[what][0]=='\0'))
+ return Success;
+ file= list->pattern[what];
+ map= strrchr(file,'(');
+ if (map!=NULL) {
+ char *tmp;
+ map++;
+ tmp= strrchr(map,')');
+ if ((tmp==NULL)||(tmp[1]!='\0')) {
+ /* illegal pattern. No error, but no match */
+ return Success;
+ }
+ }
+
+ in= NULL;
+ haveDir= True;
+#ifdef WIN32
+ strcpy(tmpname, "\\temp\\xkb_XXXXXX");
+ (void) mktemp(tmpname);
+#endif
+ if (XkbBaseDirectory!=NULL) {
+ if (strlen(XkbBaseDirectory)+strlen(componentDirs[what])+6 > PATH_MAX)
+ return BadImplementation;
+ if ((list->pattern[what][0]=='*')&&(list->pattern[what][1]=='\0')) {
+ sprintf(buf,"%s/%s.dir",XkbBaseDirectory,componentDirs[what]);
+ in= fopen(buf,"r");
+ }
+ if (!in) {
+ haveDir= False;
+ if (strlen(XkbBaseDirectory)*2+strlen(componentDirs[what])
+ +(xkbDebugFlags>9?2:1)+strlen(file)+31 > PATH_MAX)
+ return BadImplementation;
+#ifndef WIN32
+ sprintf(buf,"%s/xkbcomp -R%s/%s -w %d -l -vlfhpR '%s'",
+ XkbBaseDirectory,XkbBaseDirectory,componentDirs[what],
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:xkbDebugFlags)),
+ file);
+#else
+ sprintf(buf,"%s/xkbcomp -R%s/%s -w %d -l -vlfhpR '%s' %s",
+ XkbBaseDirectory,XkbBaseDirectory,componentDirs[what],
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:xkbDebugFlags)),
+ file, tmpname);
+#endif
+ }
+ }
+ else {
+ if (strlen(XkbBaseDirectory)+strlen(componentDirs[what])+6 > PATH_MAX)
+ return BadImplementation;
+ if ((list->pattern[what][0]=='*')&&(list->pattern[what][1]=='\0')) {
+ sprintf(buf,"%s.dir",componentDirs[what]);
+ in= fopen(buf,"r");
+ }
+ if (!in) {
+ haveDir= False;
+ if (strlen(componentDirs[what])
+ +(xkbDebugFlags>9?2:1)+strlen(file)+29 > PATH_MAX)
+ return BadImplementation;
+#ifndef WIN32
+ sprintf(buf,"xkbcomp -R%s -w %d -l -vlfhpR '%s'",
+ componentDirs[what],
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:xkbDebugFlags)),
+ file);
+#else
+ sprintf(buf,"xkbcomp -R%s -w %d -l -vlfhpR '%s' %s",
+ componentDirs[what],
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:xkbDebugFlags)),
+ file, tmpname);
+#endif
+ }
+ }
+ status= Success;
+ if (!haveDir)
+#ifndef WIN32
+ in= Popen(buf,"r");
+#else
+ {
+ if (System(buf) < 0)
+ ErrorF("Could not invoke keymap compiler\n");
+ else
+ in= fopen(tmpname, "r");
+ }
+#endif
+ if (!in)
+ return BadImplementation;
+ list->nFound[what]= 0;
+ while ((status==Success)&&((tmp=fgets(buf,PATH_MAX,in))!=NULL)) {
+ unsigned flags;
+ register unsigned int i;
+ if (*tmp=='#') /* comment, skip it */
+ continue;
+ if (!strncmp(tmp, "Warning:", 8) || !strncmp(tmp, " ", 8))
+ /* skip warnings too */
+ continue;
+ flags= 0;
+ /* each line in the listing is supposed to start with two */
+ /* groups of eight characters, which specify the general */
+ /* flags and the flags that are specific to the component */
+ /* if they're missing, fail with BadImplementation */
+ for (i=0;(i<8)&&(status==Success);i++) { /* read the general flags */
+ if (isalpha(*tmp)) flags|= (1L<<i);
+ else if (*tmp!='-') status= BadImplementation;
+ tmp++;
+ }
+ if (status != Success) break;
+ if (!isspace(*tmp)) {
+ status= BadImplementation;
+ break;
+ }
+ else tmp++;
+ for (i=0;(i<8)&&(status==Success);i++) { /* read the component flags */
+ if (isalpha(*tmp)) flags|= (1L<<(i+8));
+ else if (*tmp!='-') status= BadImplementation;
+ tmp++;
+ }
+ if (status != Success) break;
+ if (isspace(*tmp)) {
+ while (isspace(*tmp)) {
+ tmp++;
+ }
+ }
+ else {
+ status= BadImplementation;
+ break;
+ }
+ status= _AddListComponent(list,what,flags,tmp,client);
+ }
+#ifndef WIN32
+ if (haveDir)
+ fclose(in);
+ else if ((rval=pclose(in))!=0) {
+ if (xkbDebugFlags)
+ ErrorF("xkbcomp returned exit code %d\n",rval);
+ }
+#else
+ fclose(in);
+#endif
+ return status;
+}
+
+/***====================================================================***/
+
+/* ARGSUSED */
+Status
+#if NeedFunctionPrototypes
+XkbDDXList(DeviceIntPtr dev,XkbSrvListInfoPtr list,ClientPtr client)
+#else
+XkbDDXList(dev,list,client)
+ DeviceIntPtr dev;
+ XkbSrvListInfoPtr list;
+ ClientPtr client;
+#endif
+{
+Status status;
+
+ status= XkbDDXListComponent(dev,_XkbListKeymaps,list,client);
+ if (status==Success)
+ status= XkbDDXListComponent(dev,_XkbListKeycodes,list,client);
+ if (status==Success)
+ status= XkbDDXListComponent(dev,_XkbListTypes,list,client);
+ if (status==Success)
+ status= XkbDDXListComponent(dev,_XkbListCompat,list,client);
+ if (status==Success)
+ status= XkbDDXListComponent(dev,_XkbListSymbols,list,client);
+ if (status==Success)
+ status= XkbDDXListComponent(dev,_XkbListGeometry,list,client);
+ return status;
+}
diff --git a/xc/programs/Xserver/xkb/ddxLoad.c b/xc/programs/Xserver/xkb/ddxLoad.c
new file mode 100644
index 000000000..811944203
--- /dev/null
+++ b/xc/programs/Xserver/xkb/ddxLoad.c
@@ -0,0 +1,557 @@
+/* $TOG: ddxLoad.c /main/21 1997/06/18 07:33:24 kaleb $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+/* $XFree86: xc/programs/Xserver/xkb/ddxLoad.c,v 3.24 1999/01/31 12:22:21 dawes Exp $ */
+
+#include <stdio.h>
+#include <ctype.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xos.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include <X11/extensions/XKM.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#define XKBSRV_NEED_FILE_FUNCS
+#include "XKBsrv.h"
+#include "XI.h"
+
+#if defined(CSRG_BASED) || defined(linux) || defined(__sgi) || defined(AIXV3) || defined(__osf__)
+#include <paths.h>
+#endif
+
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+
+ /*
+ * If XKM_OUTPUT_DIR specifies a path without a leading slash, it is
+ * relative to the top-level XKB configuration directory.
+ * Making the server write to a subdirectory of that directory
+ * requires some work in the general case (install procedure
+ * has to create links to /var or somesuch on many machines),
+ * so we just compile into /usr/tmp for now.
+ */
+#ifndef XKM_OUTPUT_DIR
+#define XKM_OUTPUT_DIR "compiled/"
+#endif
+
+#define PRE_ERROR_MSG "\"The XKEYBOARD keymap compiler (xkbcomp) reports:\""
+#define ERROR_PREFIX "\"> \""
+#define POST_ERROR_MSG1 "\"Errors from xkbcomp are not fatal to the X server\""
+#define POST_ERROR_MSG2 "\"End of messages from xkbcomp\""
+
+static void
+OutputDirectory (outdir)
+ char* outdir;
+{
+#ifndef WIN32
+ if (getuid() == 0) {
+ /* if server running as root it *may* be able to write */
+ /* FIXME: check whether directory is writable at all */
+ (void) strcpy (outdir, XKM_OUTPUT_DIR);
+ } else
+#endif
+ {
+#ifdef _PATH_VARTMP
+ (void) strcpy (outdir, _PATH_VARTMP);
+ if (outdir[strlen(outdir) - 1] != '/') /* Hi IBM, Digital */
+ (void) strcat (outdir, "/");
+#else
+ (void) strcpy (outdir, "/tmp/");
+#endif
+ }
+}
+
+Bool
+#if NeedFunctionPrototypes
+XkbDDXCompileNamedKeymap( XkbDescPtr xkb,
+ XkbComponentNamesPtr names,
+ char * nameRtrn,
+ int nameRtrnLen)
+#else
+XkbDDXCompileNamedKeymap(xkb,names,nameRtrn,nameRtrnLen)
+ XkbDescPtr xkb;
+ XkbComponentNamesPtr names;
+ char * nameRtrn;
+ int nameRtrnLen;
+#endif
+{
+char cmd[PATH_MAX],file[PATH_MAX],xkm_output_dir[PATH_MAX],*map,*outFile;
+
+ if (names->keymap==NULL)
+ return False;
+ strncpy(file,names->keymap,PATH_MAX); file[PATH_MAX-1]= '\0';
+ if ((map= strrchr(file,'('))!=NULL) {
+ char *tmp;
+ if ((tmp= strrchr(map,')'))!=NULL) {
+ *map++= '\0';
+ *tmp= '\0';
+ }
+ else {
+ map= NULL;
+ }
+ }
+ if ((outFile= strrchr(file,'/'))!=NULL)
+ outFile= _XkbDupString(&outFile[1]);
+ else outFile= _XkbDupString(file);
+ XkbEnsureSafeMapName(outFile);
+ OutputDirectory(xkm_output_dir);
+
+ if (XkbBaseDirectory!=NULL) {
+#ifdef __EMX__
+ char *tmpbase = (char*)__XOS2RedirRoot(XkbBaseDirectory);
+ int i;
+ if (strlen(tmpbase)*2+(xkbDebugFlags>9?2:1)
+#else
+ if (strlen(XkbBaseDirectory)*2+(xkbDebugFlags>9?2:1)
+#endif
+ +(map?strlen(map)+3:0)+strlen(PRE_ERROR_MSG)
+ +strlen(ERROR_PREFIX)+strlen(POST_ERROR_MSG1)
+ +strlen(file)+strlen(xkm_output_dir)
+ +strlen(outFile)+53 > PATH_MAX)
+ {
+#ifdef DEBUG
+ ErrorF("compiler command for keymap (%s) exceeds max length\n",
+ names->keymap);
+#endif
+ return False;
+ }
+#ifndef __EMX__
+ sprintf(cmd,"%s/xkbcomp -w %d -R%s -xkm %s%s -em1 %s -emp %s -eml %s keymap/%s %s%s.xkm",
+ XkbBaseDirectory,
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)),
+ XkbBaseDirectory,(map?"-m ":""),(map?map:""),
+ PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,file,
+ xkm_output_dir,outFile);
+#else
+ for (i=0; i<strlen(tmpbase); i++) if (tmpbase[i]=='/') tmpbase[i]='\\';
+ sprintf(cmd,"%s\\xkbcomp -w %d -R%s -xkm %s%s -em1 %s -emp %s -eml %s keymap/%s %s%s.xkm",
+ tmpbase,
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)),
+ tmpbase,(map?"-m ":""),(map?map:""),
+ PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,file,
+ xkm_output_dir,outFile);
+ ErrorF("Command line for XKB is %s\n",cmd);
+#endif
+ }
+ else {
+ if ((xkbDebugFlags>9?2:1)+(map?strlen(map)+3:0)+strlen(PRE_ERROR_MSG)
+ +strlen(ERROR_PREFIX)+strlen(POST_ERROR_MSG1)
+ +strlen(file)+strlen(xkm_output_dir)
+ +strlen(outFile)+49 > PATH_MAX)
+ {
+#ifdef DEBUG
+ ErrorF("compiler command for keymap (%s) exceeds max length\n",
+ names->keymap);
+#endif
+ return False;
+ }
+ sprintf(cmd,"xkbcomp -w %d -xkm %s%s -em1 %s -emp %s -eml %s keymap/%s %s%s.xkm",
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)),
+ (map?"-m ":""),(map?map:""),
+ PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,file,
+ xkm_output_dir,outFile);
+ }
+#ifdef DEBUG
+ if (xkbDebugFlags) {
+ ErrorF("XkbDDXCompileNamedKeymap compiling keymap using:\n");
+ ErrorF(" \"cmd\"\n");
+ }
+#endif
+ if (System(cmd)==0) {
+ if (nameRtrn) {
+ strncpy(nameRtrn,outFile,nameRtrnLen);
+ nameRtrn[nameRtrnLen-1]= '\0';
+ }
+ if (outFile!=NULL)
+ _XkbFree(outFile);
+ return True;
+ }
+#ifdef DEBUG
+ ErrorF("Error compiling keymap (%s)\n",names->keymap);
+#endif
+ if (outFile!=NULL)
+ _XkbFree(outFile);
+ return False;
+}
+
+Bool
+#if NeedFunctionPrototypes
+XkbDDXCompileKeymapByNames( XkbDescPtr xkb,
+ XkbComponentNamesPtr names,
+ unsigned want,
+ unsigned need,
+ char * nameRtrn,
+ int nameRtrnLen)
+#else
+XkbDDXCompileKeymapByNames(xkb,names,want,need,nameRtrn,nameRtrnLen)
+ XkbDescPtr xkb;
+ XkbComponentNamesPtr names;
+ unsigned want;
+ unsigned need;
+ char * nameRtrn;
+ int nameRtrnLen;
+#endif
+{
+FILE * out;
+char buf[PATH_MAX],keymap[PATH_MAX],xkm_output_dir[PATH_MAX];
+#ifdef WIN32
+char tmpname[32];
+#endif
+#ifdef __EMX__
+char *tmpbase;
+int i;
+#endif
+ if ((names->keymap==NULL)||(names->keymap[0]=='\0')) {
+ extern char *display;
+ sprintf(keymap,"server-%s",display);
+ }
+ else {
+ strcpy(keymap,names->keymap);
+ }
+
+ XkbEnsureSafeMapName(keymap);
+ OutputDirectory(xkm_output_dir);
+#ifdef WIN32
+ strcpy(tmpname, "\\temp\\xkb_XXXXXX");
+ (void) mktemp(tmpname);
+#endif
+#ifdef __EMX__
+ tmpbase = (char*)__XOS2RedirRoot(XkbBaseDirectory);
+#endif
+ if (XkbBaseDirectory!=NULL) {
+ if (strlen(XkbBaseDirectory)*2+(xkbDebugFlags>9?2:1)
+ +strlen(PRE_ERROR_MSG)+strlen(ERROR_PREFIX)
+ +strlen(POST_ERROR_MSG1)+strlen(xkm_output_dir)
+ +strlen(keymap)+48 > PATH_MAX)
+ {
+#ifdef DEBUG
+ ErrorF("compiler command for keymap (%s) exceeds max length\n",
+ names->keymap);
+#endif
+ return False;
+ }
+#ifndef WIN32
+#ifndef __EMX__
+ sprintf(buf,
+ "%s/xkbcomp -w %d -R%s -xkm - -em1 %s -emp %s -eml %s \"%s%s.xkm\"",
+ XkbBaseDirectory,
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)),
+ XkbBaseDirectory,
+ PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,
+ xkm_output_dir,keymap);
+#else
+ for (i=0; i<strlen(tmpbase); i++) if (tmpbase[i]=='/') tmpbase[i]='\\';
+ sprintf(buf,
+ "%s\\xkbcomp -w %d -R%s -xkm - -em1 %s -emp %s -eml %s \"%s%s.xkm\"",
+ tmpbase,
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)),
+ tmpbase,
+ PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,
+ xkm_output_dir,keymap);
+#endif
+#else
+ sprintf(buf,
+ "%s/xkbcomp -w %d -R%s -xkm - -em1 %s -emp %s -eml %s \"%s%s.xkm\" < %s",
+ XkbBaseDirectory,
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)),
+ XkbBaseDirectory,
+ PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,
+ xkm_output_dir,keymap,tmpname);
+#endif
+ }
+ else {
+ if ((xkbDebugFlags>9?2:1)+strlen(PRE_ERROR_MSG)
+ +strlen(ERROR_PREFIX)+strlen(POST_ERROR_MSG1)
+ +strlen(xkm_output_dir)+strlen(keymap)+44 > PATH_MAX)
+ {
+#ifdef DEBUG
+ ErrorF("compiler command for keymap (%s) exceeds max length\n",
+ names->keymap);
+#endif
+ return False;
+ }
+#ifndef WIN32
+ sprintf(buf,
+ "xkbcomp -w %d -xkm - -em1 %s -emp %s -eml %s \"%s%s.xkm\"",
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)),
+ PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,
+ xkm_output_dir,keymap);
+#else
+ sprintf(buf,
+ "xkbcomp -w %d -xkm - -em1 %s -emp %s -eml %s \"%s%s.xkm\" < %s",
+ ((xkbDebugFlags<2)?1:((xkbDebugFlags>10)?10:(int)xkbDebugFlags)),
+ PRE_ERROR_MSG,ERROR_PREFIX,POST_ERROR_MSG1,
+ xkm_output_dir,keymap,tmpname);
+#endif
+ }
+#ifndef WIN32
+ out= Popen(buf,"w");
+#else
+ out= fopen(tmpname, "w");
+#endif
+ if (out!=NULL) {
+#ifdef DEBUG
+ if (xkbDebugFlags) {
+ ErrorF("XkbDDXCompileKeymapByNames compiling keymap:\n");
+ XkbWriteXKBKeymapForNames(stderr,names,NULL,xkb,want,need);
+ }
+#endif
+ XkbWriteXKBKeymapForNames(out,names,NULL,xkb,want,need);
+#ifndef WIN32
+ if (Pclose(out)==0)
+#else
+ if (fclose(out)==0)
+#endif
+ {
+#ifdef WIN32
+ if (System(buf) < 0)
+ ErrorF("Could not invoke keymap compiler\n");
+ else {
+#endif
+ if (nameRtrn) {
+ strncpy(nameRtrn,keymap,nameRtrnLen);
+ nameRtrn[nameRtrnLen-1]= '\0';
+ }
+#if defined(Lynx) && defined(__i386__) && defined(NEED_POPEN_WORKAROUND)
+ /* somehow popen/pclose is broken on LynxOS AT 2.3.0/2.4.0!
+ * the problem usually shows up with XF86Setup
+ * this hack waits at max 5 seconds after pclose() returns
+ * for the output of the xkbcomp output file.
+ * I didn't manage to get a patch in time for the 3.2 release
+ */
+ {
+ int i;
+ char name[PATH_MAX];
+ if (XkbBaseDirectory!=NULL)
+ sprintf(name,"%s/%s%s.xkm", XkbBaseDirectory
+ ,xkm_output_dir, keymap);
+ else
+ sprintf(name,"%s%s.xkm", xkm_output_dir, keymap);
+ for (i = 0; i < 10; i++) {
+ if (access(name, 0) == 0) break;
+ usleep(500000);
+ }
+#ifdef DEBUG
+ if (i) ErrorF(">>>> Waited %d times for %s\n", i, name);
+#endif
+ }
+#endif
+ return True;
+#ifdef WIN32
+ }
+#endif
+ }
+#ifdef DEBUG
+ else
+ ErrorF("Error compiling keymap (%s)\n",keymap);
+#endif
+ }
+#ifdef DEBUG
+ else {
+#ifndef WIN32
+ ErrorF("Could not invoke keymap compiler\n");
+#else
+ ErrorF("Could not open file %s\n", tmpname);
+#endif
+ }
+#endif
+ if (nameRtrn)
+ nameRtrn[0]= '\0';
+ return False;
+}
+
+FILE *
+#if NeedFunctionPrototypes
+XkbDDXOpenConfigFile(char *mapName,char *fileNameRtrn,int fileNameRtrnLen)
+#else
+XkbDDXOpenConfigFile(mapName,fileNameRtrn,fileNameRtrnLen)
+ char * mapName;
+ char * fileNameRtrn;
+ int fileNameRtrnLen;
+#endif
+{
+char buf[PATH_MAX],xkm_output_dir[PATH_MAX];
+FILE * file;
+
+ buf[0]= '\0';
+ if (mapName!=NULL) {
+ OutputDirectory(xkm_output_dir);
+ if ((XkbBaseDirectory!=NULL)&&(xkm_output_dir[0]!='/')) {
+ if (strlen(XkbBaseDirectory)+strlen(xkm_output_dir)
+ +strlen(mapName)+6 <= PATH_MAX)
+ {
+ sprintf(buf,"%s/%s%s.xkm",XkbBaseDirectory,
+ xkm_output_dir,mapName);
+ }
+ }
+ else if (strlen(xkm_output_dir)+strlen(mapName)+5 <= PATH_MAX)
+ sprintf(buf,"%s%s.xkm",xkm_output_dir,mapName);
+ if (buf[0] != '\0')
+ file= fopen(buf,"r");
+ else file= NULL;
+ }
+ else file= NULL;
+ if ((fileNameRtrn!=NULL)&&(fileNameRtrnLen>0)) {
+ strncpy(fileNameRtrn,buf,fileNameRtrnLen);
+ buf[fileNameRtrnLen-1]= '\0';
+ }
+ return file;
+}
+
+unsigned
+#if NeedFunctionPrototypes
+XkbDDXLoadKeymapByNames( DeviceIntPtr keybd,
+ XkbComponentNamesPtr names,
+ unsigned want,
+ unsigned need,
+ XkbFileInfo * finfoRtrn,
+ char * nameRtrn,
+ int nameRtrnLen)
+#else
+XkbDDXLoadKeymapByNames(keybd,names,want,need,finfoRtrn,nameRtrn,nameRtrnLen)
+ DeviceIntPtr keybd;
+ XkbComponentNamesPtr names;
+ unsigned want;
+ unsigned need;
+ XkbFileInfo * finfoRtrn;
+ char * nameRtrn;
+ int nameRtrnLen;
+#endif
+{
+XkbDescPtr xkb;
+FILE * file;
+char fileName[PATH_MAX];
+unsigned missing;
+
+ bzero(finfoRtrn,sizeof(XkbFileInfo));
+ if ((keybd==NULL)||(keybd->key==NULL)||(keybd->key->xkbInfo==NULL))
+ xkb= NULL;
+ else xkb= keybd->key->xkbInfo->desc;
+ if ((names->keycodes==NULL)&&(names->types==NULL)&&
+ (names->compat==NULL)&&(names->symbols==NULL)&&
+ (names->geometry==NULL)) {
+ if (names->keymap==NULL) {
+ bzero(finfoRtrn,sizeof(XkbFileInfo));
+ if (xkb && XkbDetermineFileType(finfoRtrn,XkbXKMFile,NULL) &&
+ ((finfoRtrn->defined&need)==need) ) {
+ finfoRtrn->xkb= xkb;
+ nameRtrn[0]= '\0';
+ return finfoRtrn->defined;
+ }
+ return 0;
+ }
+ else if (!XkbDDXCompileNamedKeymap(xkb,names,nameRtrn,nameRtrnLen)) {
+#ifdef NOISY
+ ErrorF("Couldn't compile keymap file\n");
+#endif
+ return 0;
+ }
+ }
+ else if (!XkbDDXCompileKeymapByNames(xkb,names,want,need,
+ nameRtrn,nameRtrnLen)){
+#ifdef NOISY
+ ErrorF("Couldn't compile keymap file\n");
+#endif
+ return 0;
+ }
+ file= XkbDDXOpenConfigFile(nameRtrn,fileName,PATH_MAX);
+ if (file==NULL) {
+ ErrorF("Couldn't open compiled keymap file %s\n",fileName);
+ return 0;
+ }
+ missing= XkmReadFile(file,need,want,finfoRtrn);
+ if (finfoRtrn->xkb==NULL) {
+ ErrorF("Error loading keymap %s\n",fileName);
+ fclose(file);
+ (void) unlink (fileName);
+ return 0;
+ }
+#ifdef DEBUG
+ else if (xkbDebugFlags) {
+ ErrorF("Loaded %s, defined=0x%x\n",fileName,finfoRtrn->defined);
+ }
+#endif
+ fclose(file);
+ (void) unlink (fileName);
+ return (need|want)&(~missing);
+}
+
+Bool
+#if NeedFunctionPrototypes
+XkbDDXNamesFromRules( DeviceIntPtr keybd,
+ char * rules_name,
+ XkbRF_VarDefsPtr defs,
+ XkbComponentNamesPtr names)
+#else
+XkbDDXNamesFromRules(keybd,rules_name,defs,names)
+ DeviceIntPtr keybd;
+ char * rules_name;
+ XkbRF_VarDefsPtr defs;
+ XkbComponentNamesPtr names;
+#endif
+{
+char buf[PATH_MAX];
+FILE * file;
+Bool complete;
+XkbRF_RulesPtr rules;
+
+ if (!rules_name)
+ return False;
+ if (XkbBaseDirectory==NULL) {
+ if (strlen(rules_name)+7 > PATH_MAX)
+ return False;
+ sprintf(buf,"rules/%s",rules_name);
+ }
+ else {
+ if (strlen(XkbBaseDirectory)+strlen(rules_name)+8 > PATH_MAX)
+ return False;
+ sprintf(buf,"%s/rules/%s",XkbBaseDirectory,rules_name);
+ }
+ if ((file= fopen(buf,"r"))==NULL)
+ return False;
+ if ((rules= XkbRF_Create(0,0))==NULL) {
+ fclose(file);
+ return False;
+ }
+ if (!XkbRF_LoadRules(file,rules)) {
+ fclose(file);
+ XkbRF_Free(rules,True);
+ return False;
+ }
+ bzero((char *)names,sizeof(XkbComponentNamesRec));
+ complete= XkbRF_GetComponents(rules,defs,names);
+ fclose(file);
+ XkbRF_Free(rules,True);
+ return complete;
+}
diff --git a/xc/programs/Xserver/xkb/ddxVT.c b/xc/programs/Xserver/xkb/ddxVT.c
new file mode 100644
index 000000000..9b4c9e2ac
--- /dev/null
+++ b/xc/programs/Xserver/xkb/ddxVT.c
@@ -0,0 +1,50 @@
+/* $XConsortium: ddxVT.c /main/2 1996/01/01 10:56:13 kaleb $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#include <stdio.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "XKBsrv.h"
+#include "XI.h"
+
+int
+#if NeedFunctionPrototypes
+XkbDDXSwitchScreen(DeviceIntPtr dev,KeyCode key,XkbAction *act)
+#else
+XkbDDXSwitchScreen(dev,key,act)
+ DeviceIntPtr dev;
+ KeyCode key;
+ XkbAction *act;
+#endif
+{
+ return 1;
+}
diff --git a/xc/programs/Xserver/xkb/xkb.c b/xc/programs/Xserver/xkb/xkb.c
new file mode 100644
index 000000000..8628eccbe
--- /dev/null
+++ b/xc/programs/Xserver/xkb/xkb.c
@@ -0,0 +1,6930 @@
+/* $TOG: xkb.c /main/22 1997/06/10 06:53:48 kaleb $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+/* $XFree86: xc/programs/Xserver/xkb/xkb.c,v 3.12 1997/06/22 10:16:59 dawes Exp $ */
+
+#include <stdio.h>
+#include "X.h"
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include "Xproto.h"
+#include "misc.h"
+#include "inputstr.h"
+#define XKBSRV_NEED_FILE_FUNCS
+#include "XKBsrv.h"
+#include "extnsionst.h"
+
+#include "XI.h"
+
+ int XkbEventBase;
+ int XkbErrorBase;
+ int XkbReqCode;
+ int XkbKeyboardErrorCode;
+Atom xkbONE_LEVEL;
+Atom xkbTWO_LEVEL;
+Atom xkbKEYPAD;
+CARD32 xkbDebugFlags = 0;
+CARD32 xkbDebugCtrls = 0;
+
+#ifndef XKB_SRV_UNSUPPORTED_XI_FEATURES
+#define XKB_SRV_UNSUPPORTED_XI_FEATURES XkbXI_KeyboardsMask
+#endif
+
+unsigned XkbXIUnsupported= XKB_SRV_UNSUPPORTED_XI_FEATURES;
+
+RESTYPE RT_XKBCLIENT;
+
+/***====================================================================***/
+
+#define CHK_DEVICE(d,sp,lf) {\
+ int why;\
+ d = (DeviceIntPtr)lf((sp),&why);\
+ if (!dev) {\
+ client->errorValue = _XkbErrCode2(why,(sp));\
+ return XkbKeyboardErrorCode;\
+ }\
+}
+
+#define CHK_KBD_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupKeyboard)
+#define CHK_LED_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupLedDevice)
+#define CHK_BELL_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupBellDevice)
+#define CHK_ANY_DEVICE(d,sp) CHK_DEVICE(d,sp,_XkbLookupAnyDevice)
+
+#define CHK_ATOM_ONLY2(a,ev,er) {\
+ if (((a)==None)||(!ValidAtom((a)))) {\
+ (ev)= (XID)(a);\
+ return er;\
+ }\
+}
+#define CHK_ATOM_ONLY(a) \
+ CHK_ATOM_ONLY2(a,client->errorValue,BadAtom)
+
+#define CHK_ATOM_OR_NONE3(a,ev,er,ret) {\
+ if (((a)!=None)&&(!ValidAtom((a)))) {\
+ (ev)= (XID)(a);\
+ (er)= BadAtom;\
+ return ret;\
+ }\
+}
+#define CHK_ATOM_OR_NONE2(a,ev,er) {\
+ if (((a)!=None)&&(!ValidAtom((a)))) {\
+ (ev)= (XID)(a);\
+ return er;\
+ }\
+}
+#define CHK_ATOM_OR_NONE(a) \
+ CHK_ATOM_OR_NONE2(a,client->errorValue,BadAtom)
+
+#define CHK_MASK_LEGAL3(err,mask,legal,ev,er,ret) {\
+ if ((mask)&(~(legal))) { \
+ (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
+ (er)= BadValue;\
+ return ret;\
+ }\
+}
+#define CHK_MASK_LEGAL2(err,mask,legal,ev,er) {\
+ if ((mask)&(~(legal))) { \
+ (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
+ return er;\
+ }\
+}
+#define CHK_MASK_LEGAL(err,mask,legal) \
+ CHK_MASK_LEGAL2(err,mask,legal,client->errorValue,BadValue)
+
+#define CHK_MASK_MATCH(err,affect,value) {\
+ if ((value)&(~(affect))) { \
+ client->errorValue= _XkbErrCode2((err),((value)&(~(affect))));\
+ return BadMatch;\
+ }\
+}
+#define CHK_MASK_OVERLAP(err,m1,m2) {\
+ if ((m1)&(m2)) { \
+ client->errorValue= _XkbErrCode2((err),((m1)&(m2)));\
+ return BadMatch;\
+ }\
+}
+#define CHK_KEY_RANGE2(err,first,num,x,ev,er) {\
+ if (((unsigned)(first)+(num)-1)>(x)->max_key_code) {\
+ (ev)=_XkbErrCode4(err,(first),(num),(x)->max_key_code);\
+ return er;\
+ }\
+ else if ( (first)<(x)->min_key_code ) {\
+ (ev)=_XkbErrCode3(err+1,(first),xkb->min_key_code);\
+ return er;\
+ }\
+}
+#define CHK_KEY_RANGE(err,first,num,x) \
+ CHK_KEY_RANGE2(err,first,num,x,client->errorValue,BadValue)
+
+#define CHK_REQ_KEY_RANGE2(err,first,num,r,ev,er) {\
+ if (((unsigned)(first)+(num)-1)>(r)->maxKeyCode) {\
+ (ev)=_XkbErrCode4(err,(first),(num),(r)->maxKeyCode);\
+ return er;\
+ }\
+ else if ( (first)<(r)->minKeyCode ) {\
+ (ev)=_XkbErrCode3(err+1,(first),(r)->minKeyCode);\
+ return er;\
+ }\
+}
+#define CHK_REQ_KEY_RANGE(err,first,num,r) \
+ CHK_REQ_KEY_RANGE2(err,first,num,r,client->errorValue,BadValue)
+
+/***====================================================================***/
+
+int
+#if NeedFunctionPrototypes
+ProcXkbUseExtension(ClientPtr client)
+#else
+ProcXkbUseExtension(client)
+ ClientPtr client;
+#endif
+{
+ REQUEST(xkbUseExtensionReq);
+ xkbUseExtensionReply rep;
+ register int n;
+ int supported;
+
+ REQUEST_SIZE_MATCH(xkbUseExtensionReq);
+ if (stuff->wantedMajor != XkbMajorVersion) {
+ /* pre-release version 0.65 is compatible with 1.00 */
+ supported= ((XkbMajorVersion==1)&&
+ (stuff->wantedMajor==0)&&(stuff->wantedMinor==65));
+ }
+ else supported = 1;
+
+#ifdef XKB_SWAPPING_BUSTED
+ if (client->swapped)
+ supported= 0;
+#endif
+
+ if ((supported) && (!(client->xkbClientFlags&_XkbClientInitialized))) {
+ client->xkbClientFlags= _XkbClientInitialized;
+ client->vMajor= stuff->wantedMajor;
+ client->vMinor= stuff->wantedMinor;
+ }
+ else if (xkbDebugFlags&0x1) {
+ ErrorF("Rejecting client %d (0x%x) (wants %d.%02d, have %d.%02d)\n",
+ client->index, client->clientAsMask,
+ stuff->wantedMajor,stuff->wantedMinor,
+ XkbMajorVersion,XkbMinorVersion);
+ }
+ rep.type = X_Reply;
+ rep.supported = supported;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.serverMajor = XkbMajorVersion;
+ rep.serverMinor = XkbMinorVersion;
+ if ( client->swapped ) {
+ swaps(&rep.sequenceNumber, n);
+ swaps(&rep.serverMajor, n);
+ swaps(&rep.serverMinor, n);
+ }
+ WriteToClient(client,SIZEOF(xkbUseExtensionReply), (char *)&rep);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+#if NeedFunctionPrototypes
+ProcXkbSelectEvents(ClientPtr client)
+#else
+ProcXkbSelectEvents(client)
+ ClientPtr client;
+#endif
+{
+ unsigned legal;
+ DeviceIntPtr dev;
+ XkbInterestPtr masks;
+ REQUEST(xkbSelectEventsReq);
+
+ REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_ANY_DEVICE(dev,stuff->deviceSpec);
+
+ if (((stuff->affectWhich&XkbMapNotifyMask)!=0)&&(stuff->affectMap)) {
+ client->mapNotifyMask&= ~stuff->affectMap;
+ client->mapNotifyMask|= (stuff->affectMap&stuff->map);
+ }
+ if (stuff->affectWhich&(~XkbMapNotifyMask)==0)
+ return client->noClientException;
+
+ masks = XkbFindClientResource((DevicePtr)dev,client);
+ if (!masks){
+ XID id = FakeClientID(client->index);
+ AddResource(id,RT_XKBCLIENT,dev);
+ masks= XkbAddClientResource((DevicePtr)dev,client,id);
+ }
+ if (masks) {
+ union {
+ CARD8 *c8;
+ CARD16 *c16;
+ CARD32 *c32;
+ } from,to;
+ register unsigned bit,ndx,maskLeft,dataLeft,size;
+
+ from.c8= (CARD8 *)&stuff[1];
+ dataLeft= (stuff->length*4)-SIZEOF(xkbSelectEventsReq);
+ maskLeft= (stuff->affectWhich&(~XkbMapNotifyMask));
+ for (ndx=0,bit=1; (maskLeft!=0); ndx++, bit<<=1) {
+ if ((bit&maskLeft)==0)
+ continue;
+ maskLeft&= ~bit;
+ switch (ndx) {
+ case XkbNewKeyboardNotify:
+ to.c16= &client->newKeyboardNotifyMask;
+ legal= XkbAllNewKeyboardEventsMask;
+ size= 2;
+ break;
+ case XkbStateNotify:
+ to.c16= &masks->stateNotifyMask;
+ legal= XkbAllStateEventsMask;
+ size= 2;
+ break;
+ case XkbControlsNotify:
+ to.c32= &masks->ctrlsNotifyMask;
+ legal= XkbAllControlEventsMask;
+ size= 4;
+ break;
+ case XkbIndicatorStateNotify:
+ to.c32= &masks->iStateNotifyMask;
+ legal= XkbAllIndicatorEventsMask;
+ size= 4;
+ break;
+ case XkbIndicatorMapNotify:
+ to.c32= &masks->iMapNotifyMask;
+ legal= XkbAllIndicatorEventsMask;
+ size= 4;
+ break;
+ case XkbNamesNotify:
+ to.c16= &masks->namesNotifyMask;
+ legal= XkbAllNameEventsMask;
+ size= 2;
+ break;
+ case XkbCompatMapNotify:
+ to.c8= &masks->compatNotifyMask;
+ legal= XkbAllCompatMapEventsMask;
+ size= 1;
+ break;
+ case XkbBellNotify:
+ to.c8= &masks->bellNotifyMask;
+ legal= XkbAllBellEventsMask;
+ size= 1;
+ break;
+ case XkbActionMessage:
+ to.c8= &masks->actionMessageMask;
+ legal= XkbAllActionMessagesMask;
+ size= 1;
+ break;
+ case XkbAccessXNotify:
+ to.c16= &masks->accessXNotifyMask;
+ legal= XkbAllAccessXEventsMask;
+ size= 2;
+ break;
+ case XkbExtensionDeviceNotify:
+ to.c16= &masks->extDevNotifyMask;
+ legal= XkbAllExtensionDeviceEventsMask;
+ size= 2;
+ break;
+ default:
+ client->errorValue = _XkbErrCode2(33,bit);
+ return BadValue;
+ }
+
+ if (stuff->clear&bit) {
+ if (size==2) to.c16[0]= 0;
+ else if (size==4) to.c32[0]= 0;
+ else to.c8[0]= 0;
+ }
+ else if (stuff->selectAll&bit) {
+ if (size==2) to.c16[0]= ~0;
+ else if (size==4) to.c32[0]= ~0;
+ else to.c8[0]= ~0;
+ }
+ else {
+ if (dataLeft<(size*2))
+ return BadLength;
+ if (size==2) {
+ CHK_MASK_MATCH(ndx,from.c16[0],from.c16[1]);
+ CHK_MASK_LEGAL(ndx,from.c16[0],legal);
+ to.c16[0]&= ~from.c16[0];
+ to.c16[0]|= (from.c16[0]&from.c16[1]);
+ }
+ else if (size==4) {
+ CHK_MASK_MATCH(ndx,from.c32[0],from.c32[1]);
+ CHK_MASK_LEGAL(ndx,from.c32[0],legal);
+ to.c32[0]&= ~from.c32[0];
+ to.c32[0]|= (from.c32[0]&from.c32[1]);
+ }
+ else {
+ CHK_MASK_MATCH(ndx,from.c8[0],from.c8[1]);
+ CHK_MASK_LEGAL(ndx,from.c8[0],legal);
+ to.c8[0]&= ~from.c8[0];
+ to.c8[0]|= (from.c8[0]&from.c8[1]);
+ size= 2;
+ }
+ from.c8+= (size*2);
+ dataLeft-= (size*2);
+ }
+ }
+ if (dataLeft>2) {
+ ErrorF("Extra data (%d bytes) after SelectEvents\n",dataLeft);
+ return BadLength;
+ }
+ return client->noClientException;
+ }
+ return BadAlloc;
+}
+
+/***====================================================================***/
+
+int
+#if NeedFunctionPrototypes
+ProcXkbBell(ClientPtr client)
+#else
+ProcXkbBell(client)
+ ClientPtr client;
+#endif
+{
+ REQUEST(xkbBellReq);
+ DeviceIntPtr dev;
+ WindowPtr pWin;
+ int base;
+ int newPercent,oldPitch,oldDuration;
+ pointer ctrl;
+
+ REQUEST_SIZE_MATCH(xkbBellReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_BELL_DEVICE(dev,stuff->deviceSpec);
+ CHK_ATOM_OR_NONE(stuff->name);
+
+ if ((stuff->forceSound)&&(stuff->eventOnly)) {
+ client->errorValue=_XkbErrCode3(0x1,stuff->forceSound,stuff->eventOnly);
+ return BadMatch;
+ }
+ if (stuff->percent < -100 || stuff->percent > 100) {
+ client->errorValue = _XkbErrCode2(0x2,stuff->percent);
+ return BadValue;
+ }
+ if (stuff->duration<-1) {
+ client->errorValue = _XkbErrCode2(0x3,stuff->duration);
+ return BadValue;
+ }
+ if (stuff->pitch<-1) {
+ client->errorValue = _XkbErrCode2(0x4,stuff->pitch);
+ return BadValue;
+ }
+
+ if (stuff->bellClass == XkbDfltXIClass) {
+ if (dev->kbdfeed!=NULL)
+ stuff->bellClass= KbdFeedbackClass;
+ else stuff->bellClass= BellFeedbackClass;
+ }
+ if (stuff->bellClass == KbdFeedbackClass) {
+ KbdFeedbackPtr k;
+ if (stuff->bellID==XkbDfltXIId)
+ k= dev->kbdfeed;
+ else {
+ for (k=dev->kbdfeed; k; k=k->next) {
+ if (k->ctrl.id == stuff->bellID)
+ break;
+ }
+ }
+ if (!k) {
+ client->errorValue= _XkbErrCode2(0x5,stuff->bellID);
+ return BadValue;
+ }
+ base = k->ctrl.bell;
+ ctrl = (pointer) &(k->ctrl);
+ oldPitch= k->ctrl.bell_pitch;
+ oldDuration= k->ctrl.bell_duration;
+ if (stuff->pitch!=0) {
+ if (stuff->pitch==-1)
+ k->ctrl.bell_pitch= defaultKeyboardControl.bell_pitch;
+ else k->ctrl.bell_pitch= stuff->pitch;
+ }
+ if (stuff->duration!=0) {
+ if (stuff->duration==-1)
+ k->ctrl.bell_duration= defaultKeyboardControl.bell_duration;
+ else k->ctrl.bell_duration= stuff->duration;
+ }
+ }
+ else if (stuff->bellClass == BellFeedbackClass) {
+ BellFeedbackPtr b;
+ if (stuff->bellID==XkbDfltXIId)
+ b= dev->bell;
+ else {
+ for (b=dev->bell; b; b=b->next) {
+ if (b->ctrl.id == stuff->bellID)
+ break;
+ }
+ }
+ if (!b) {
+ client->errorValue = _XkbErrCode2(0x6,stuff->bellID);
+ return BadValue;
+ }
+ base = b->ctrl.percent;
+ ctrl = (pointer) &(b->ctrl);
+ oldPitch= b->ctrl.pitch;
+ oldDuration= b->ctrl.duration;
+ if (stuff->pitch!=0) {
+ if (stuff->pitch==-1)
+ b->ctrl.pitch= defaultKeyboardControl.bell_pitch;
+ else b->ctrl.pitch= stuff->pitch;
+ }
+ if (stuff->duration!=0) {
+ if (stuff->duration==-1)
+ b->ctrl.duration= defaultKeyboardControl.bell_duration;
+ else b->ctrl.duration= stuff->duration;
+ }
+ }
+ else {
+ client->errorValue = _XkbErrCode2(0x7,stuff->bellClass);;
+ return BadValue;
+ }
+ if (stuff->window!=None) {
+ pWin= (WindowPtr)LookupIDByType(stuff->window,RT_WINDOW);
+ if (pWin==NULL) {
+ client->errorValue= stuff->window;
+ return BadValue;
+ }
+ }
+ else pWin= NULL;
+
+ newPercent= (base*stuff->percent)/100;
+ if (stuff->percent < 0)
+ newPercent= base+newPercent;
+ else newPercent= base-newPercent+stuff->percent;
+ XkbHandleBell(stuff->forceSound, stuff->eventOnly,
+ dev, newPercent, ctrl, stuff->bellClass,
+ stuff->name, pWin, client);
+ if ((stuff->pitch!=0)||(stuff->duration!=0)) {
+ if (stuff->bellClass == KbdFeedbackClass) {
+ KbdFeedbackPtr k;
+ k= (KbdFeedbackPtr)ctrl;
+ if (stuff->pitch!=0)
+ k->ctrl.bell_pitch= oldPitch;
+ if (stuff->duration!=0)
+ k->ctrl.bell_duration= oldDuration;
+ }
+ else {
+ BellFeedbackPtr b;
+ b= (BellFeedbackPtr)ctrl;
+ if (stuff->pitch!=0)
+ b->ctrl.pitch= oldPitch;
+ if (stuff->duration!=0)
+ b->ctrl.duration= oldDuration;
+ }
+ }
+ return Success;
+}
+
+/***====================================================================***/
+
+int
+#if NeedFunctionPrototypes
+ProcXkbGetState(ClientPtr client)
+#else
+ProcXkbGetState(client)
+ ClientPtr client;
+#endif
+{
+ REQUEST(xkbGetStateReq);
+ DeviceIntPtr dev;
+ xkbGetStateReply rep;
+ XkbStateRec *xkb;
+
+ REQUEST_SIZE_MATCH(xkbGetStateReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+
+ xkb= &dev->key->xkbInfo->state;
+ bzero(&rep,sizeof(xkbGetStateReply));
+ rep.type= X_Reply;
+ rep.sequenceNumber= client->sequence;
+ rep.length = 0;
+ rep.deviceID = dev->id;
+ rep.mods = dev->key->state&0xff;
+ rep.baseMods = xkb->base_mods;
+ rep.lockedMods = xkb->locked_mods;
+ rep.latchedMods = xkb->latched_mods;
+ rep.group = xkb->group;
+ rep.baseGroup = xkb->base_group;
+ rep.latchedGroup = xkb->latched_group;
+ rep.lockedGroup = xkb->locked_group;
+ rep.compatState = xkb->compat_state;
+ rep.ptrBtnState = xkb->ptr_buttons;
+ if (client->swapped) {
+ register int n;
+ swaps(&rep.sequenceNumber,n);
+ swaps(&rep.ptrBtnState,n);
+ }
+ WriteToClient(client, SIZEOF(xkbGetStateReply), (char *)&rep);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+#if NeedFunctionPrototypes
+ProcXkbLatchLockState(ClientPtr client)
+#else
+ProcXkbLatchLockState(client)
+ ClientPtr client;
+#endif
+{
+ int status;
+ DeviceIntPtr dev;
+ XkbStateRec oldState,*newState;
+ CARD16 changed;
+
+ REQUEST(xkbLatchLockStateReq);
+ REQUEST_SIZE_MATCH(xkbLatchLockStateReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_MATCH(0x01,stuff->affectModLocks,stuff->modLocks);
+ CHK_MASK_MATCH(0x01,stuff->affectModLatches,stuff->modLatches);
+
+ status = Success;
+ oldState= dev->key->xkbInfo->state;
+ newState= &dev->key->xkbInfo->state;
+ if ( stuff->affectModLocks ) {
+ newState->locked_mods&= ~stuff->affectModLocks;
+ newState->locked_mods|= (stuff->affectModLocks&stuff->modLocks);
+ }
+ if (( status == Success ) && stuff->lockGroup )
+ newState->locked_group = stuff->groupLock;
+ if (( status == Success ) && stuff->affectModLatches )
+ status=XkbLatchModifiers(dev,stuff->affectModLatches,stuff->modLatches);
+ if (( status == Success ) && stuff->latchGroup )
+ status=XkbLatchGroup(dev,stuff->groupLatch);
+
+ if ( status != Success )
+ return status;
+
+ XkbComputeDerivedState(dev->key->xkbInfo);
+ dev->key->state= XkbStateFieldFromRec(newState);
+
+ changed = XkbStateChangedFlags(&oldState,newState);
+ if (changed) {
+ xkbStateNotify sn;
+ sn.keycode= 0;
+ sn.eventType= 0;
+ sn.requestMajor = XkbReqCode;
+ sn.requestMinor = X_kbLatchLockState;
+ sn.changed= changed;
+ XkbSendStateNotify(dev,&sn);
+ changed= XkbIndicatorsToUpdate(dev,changed,False);
+ if (changed) {
+ XkbEventCauseRec cause;
+ XkbSetCauseXkbReq(&cause,X_kbLatchLockState,client);
+ XkbUpdateIndicators(dev,changed,True,NULL,&cause);
+ }
+ }
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+#if NeedFunctionPrototypes
+ProcXkbGetControls(ClientPtr client)
+#else
+ProcXkbGetControls(client)
+ ClientPtr client;
+#endif
+{
+ xkbGetControlsReply rep;
+ XkbControlsPtr xkb;
+ DeviceIntPtr dev;
+ register int n;
+
+ REQUEST(xkbGetControlsReq);
+ REQUEST_SIZE_MATCH(xkbGetControlsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+
+ xkb = dev->key->xkbInfo->desc->ctrls;
+ rep.type = X_Reply;
+ rep.length = (SIZEOF(xkbGetControlsReply)-
+ SIZEOF(xGenericReply)) >> 2;
+ rep.sequenceNumber = client->sequence;
+ rep.deviceID = ((DeviceIntPtr)dev)->id;
+ rep.numGroups = xkb->num_groups;
+ rep.groupsWrap = xkb->groups_wrap;
+ rep.internalMods = xkb->internal.mask;
+ rep.ignoreLockMods = xkb->ignore_lock.mask;
+ rep.internalRealMods = xkb->internal.real_mods;
+ rep.ignoreLockRealMods = xkb->ignore_lock.real_mods;
+ rep.internalVMods = xkb->internal.vmods;
+ rep.ignoreLockVMods = xkb->ignore_lock.vmods;
+ rep.enabledCtrls = xkb->enabled_ctrls;
+ rep.repeatDelay = xkb->repeat_delay;
+ rep.repeatInterval = xkb->repeat_interval;
+ rep.slowKeysDelay = xkb->slow_keys_delay;
+ rep.debounceDelay = xkb->debounce_delay;
+ rep.mkDelay = xkb->mk_delay;
+ rep.mkInterval = xkb->mk_interval;
+ rep.mkTimeToMax = xkb->mk_time_to_max;
+ rep.mkMaxSpeed = xkb->mk_max_speed;
+ rep.mkCurve = xkb->mk_curve;
+ rep.mkDfltBtn = xkb->mk_dflt_btn;
+ rep.axTimeout = xkb->ax_timeout;
+ rep.axtCtrlsMask = xkb->axt_ctrls_mask;
+ rep.axtCtrlsValues = xkb->axt_ctrls_values;
+ rep.axtOptsMask = xkb->axt_opts_mask;
+ rep.axtOptsValues = xkb->axt_opts_values;
+ rep.axOptions = xkb->ax_options;
+ memcpy(rep.perKeyRepeat,xkb->per_key_repeat,XkbPerKeyBitArraySize);
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length,n);
+ swaps(&rep.internalVMods, n);
+ swaps(&rep.ignoreLockVMods, n);
+ swapl(&rep.enabledCtrls, n);
+ swaps(&rep.repeatDelay, n);
+ swaps(&rep.repeatInterval, n);
+ swaps(&rep.slowKeysDelay, n);
+ swaps(&rep.debounceDelay, n);
+ swaps(&rep.mkDelay, n);
+ swaps(&rep.mkInterval, n);
+ swaps(&rep.mkTimeToMax, n);
+ swaps(&rep.mkMaxSpeed, n);
+ swaps(&rep.mkCurve, n);
+ swaps(&rep.axTimeout, n);
+ swapl(&rep.axtCtrlsMask, n);
+ swapl(&rep.axtCtrlsValues, n);
+ swaps(&rep.axtOptsMask, n);
+ swaps(&rep.axtOptsValues, n);
+ swaps(&rep.axOptions, n);
+ }
+ WriteToClient(client, SIZEOF(xkbGetControlsReply), (char *)&rep);
+ return(client->noClientException);
+}
+
+int
+#if NeedFunctionPrototypes
+ProcXkbSetControls(ClientPtr client)
+#else
+ProcXkbSetControls(client)
+ ClientPtr client;
+#endif
+{
+ DeviceIntPtr dev;
+ XkbSrvInfoPtr xkbi;
+ XkbControlsPtr ctrl;
+ XkbControlsRec new,old;
+ xkbControlsNotify cn;
+ XkbEventCauseRec cause;
+ XkbSrvLedInfoPtr sli;
+
+ REQUEST(xkbSetControlsReq);
+ REQUEST_SIZE_MATCH(xkbSetControlsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_LEGAL(0x01,stuff->changeCtrls,XkbAllControlsMask);
+
+ xkbi = dev->key->xkbInfo;
+ ctrl = xkbi->desc->ctrls;
+ new = *ctrl;
+ XkbSetCauseXkbReq(&cause,X_kbSetControls,client);
+ if (stuff->changeCtrls&XkbInternalModsMask) {
+ CHK_MASK_MATCH(0x02,stuff->affectInternalMods,stuff->internalMods);
+ CHK_MASK_MATCH(0x03,stuff->affectInternalVMods,stuff->internalVMods);
+ new.internal.real_mods&=~stuff->affectInternalMods;
+ new.internal.real_mods|=(stuff->affectInternalMods&stuff->internalMods);
+ new.internal.vmods&=~stuff->affectInternalVMods;
+ new.internal.vmods|= (stuff->affectInternalVMods&stuff->internalVMods);
+ new.internal.mask= new.internal.real_mods|
+ XkbMaskForVMask(xkbi->desc,new.internal.vmods);
+ }
+ if (stuff->changeCtrls&XkbIgnoreLockModsMask) {
+ CHK_MASK_MATCH(0x4,stuff->affectIgnoreLockMods,stuff->ignoreLockMods);
+ CHK_MASK_MATCH(0x5,stuff->affectIgnoreLockVMods,stuff->ignoreLockVMods);
+ new.ignore_lock.real_mods&=~stuff->affectIgnoreLockMods;
+ new.ignore_lock.real_mods|=
+ (stuff->affectIgnoreLockMods&stuff->ignoreLockMods);
+ new.ignore_lock.vmods&= ~stuff->affectIgnoreLockVMods;
+ new.ignore_lock.vmods|=
+ (stuff->affectIgnoreLockVMods&stuff->ignoreLockVMods);
+ new.ignore_lock.mask= new.ignore_lock.real_mods|
+ XkbMaskForVMask(xkbi->desc,new.ignore_lock.vmods);
+ }
+ CHK_MASK_MATCH(0x06,stuff->affectEnabledCtrls,stuff->enabledCtrls);
+ if (stuff->affectEnabledCtrls) {
+ CHK_MASK_LEGAL(0x07,stuff->affectEnabledCtrls,XkbAllBooleanCtrlsMask);
+ new.enabled_ctrls&= ~stuff->affectEnabledCtrls;
+ new.enabled_ctrls|= (stuff->affectEnabledCtrls&stuff->enabledCtrls);
+ }
+ if (stuff->changeCtrls&XkbRepeatKeysMask) {
+ if ((stuff->repeatDelay<1)||(stuff->repeatInterval<1)) {
+ client->errorValue = _XkbErrCode3(0x08,stuff->repeatDelay,
+ stuff->repeatInterval);
+ return BadValue;
+ }
+ new.repeat_delay = stuff->repeatDelay;
+ new.repeat_interval = stuff->repeatInterval;
+ }
+ if (stuff->changeCtrls&XkbSlowKeysMask) {
+ if (stuff->slowKeysDelay<1) {
+ client->errorValue = _XkbErrCode2(0x09,stuff->slowKeysDelay);
+ return BadValue;
+ }
+ new.slow_keys_delay = stuff->slowKeysDelay;
+ }
+ if (stuff->changeCtrls&XkbBounceKeysMask) {
+ if (stuff->debounceDelay<1) {
+ client->errorValue = _XkbErrCode2(0x0A,stuff->debounceDelay);
+ return BadValue;
+ }
+ new.debounce_delay = stuff->debounceDelay;
+ }
+ if (stuff->changeCtrls&XkbMouseKeysMask) {
+ if (stuff->mkDfltBtn>XkbMaxMouseKeysBtn) {
+ client->errorValue = _XkbErrCode2(0x0B,stuff->mkDfltBtn);
+ return BadValue;
+ }
+ new.mk_dflt_btn = stuff->mkDfltBtn;
+ }
+ if (stuff->changeCtrls&XkbMouseKeysAccelMask) {
+ if ((stuff->mkDelay<1) || (stuff->mkInterval<1) ||
+ (stuff->mkTimeToMax<1) || (stuff->mkMaxSpeed<1)||
+ (stuff->mkCurve<-1000)) {
+ client->errorValue = _XkbErrCode2(0x0C,0);
+ return BadValue;
+ }
+ new.mk_delay = stuff->mkDelay;
+ new.mk_interval = stuff->mkInterval;
+ new.mk_time_to_max = stuff->mkTimeToMax;
+ new.mk_max_speed = stuff->mkMaxSpeed;
+ new.mk_curve = stuff->mkCurve;
+ AccessXComputeCurveFactor(xkbi,&new);
+ }
+ if (stuff->changeCtrls&XkbGroupsWrapMask) {
+ unsigned act,num;
+ act= XkbOutOfRangeGroupAction(stuff->groupsWrap);
+ switch (act) {
+ case XkbRedirectIntoRange:
+ num= XkbOutOfRangeGroupNumber(stuff->groupsWrap);
+ if (num>=new.num_groups) {
+ client->errorValue= _XkbErrCode3(0x0D,new.num_groups,num);
+ return BadValue;
+ }
+ case XkbWrapIntoRange:
+ case XkbClampIntoRange:
+ break;
+ default:
+ client->errorValue= _XkbErrCode2(0x0E,act);
+ return BadValue;
+ }
+ new.groups_wrap= stuff->groupsWrap;
+ }
+ CHK_MASK_LEGAL(0x0F,stuff->axOptions,XkbAX_AllOptionsMask);
+ if (stuff->changeCtrls&XkbAccessXKeysMask)
+ new.ax_options = stuff->axOptions&XkbAX_AllOptionsMask;
+ else {
+ if (stuff->changeCtrls&XkbStickyKeysMask) {
+ new.ax_options&= ~XkbAX_SKOptionsMask;
+ new.ax_options|= stuff->axOptions&XkbAX_SKOptionsMask;
+ }
+ if (stuff->changeCtrls&XkbAccessXFeedbackMask) {
+ new.ax_options&= ~XkbAX_FBOptionsMask;
+ new.ax_options|= stuff->axOptions&XkbAX_FBOptionsMask;
+ }
+ }
+
+ if (stuff->changeCtrls&XkbAccessXTimeoutMask) {
+ if (stuff->axTimeout<1) {
+ client->errorValue = _XkbErrCode2(0x10,stuff->axTimeout);
+ return BadValue;
+ }
+ CHK_MASK_MATCH(0x11,stuff->axtCtrlsMask,stuff->axtCtrlsValues);
+ CHK_MASK_LEGAL(0x12,stuff->axtCtrlsMask,XkbAllBooleanCtrlsMask);
+ CHK_MASK_MATCH(0x13,stuff->axtOptsMask,stuff->axtOptsValues);
+ CHK_MASK_LEGAL(0x14,stuff->axtOptsMask,XkbAX_AllOptionsMask);
+ new.ax_timeout = stuff->axTimeout;
+ new.axt_ctrls_mask = stuff->axtCtrlsMask;
+ new.axt_ctrls_values = (stuff->axtCtrlsValues&stuff->axtCtrlsMask);
+ new.axt_opts_mask = stuff->axtOptsMask;
+ new.axt_opts_values= (stuff->axtOptsValues&stuff->axtOptsMask);
+ }
+ if (stuff->changeCtrls&XkbPerKeyRepeatMask) {
+ memcpy(new.per_key_repeat,stuff->perKeyRepeat,XkbPerKeyBitArraySize);
+ }
+ old= *ctrl;
+ *ctrl= new;
+ XkbDDXChangeControls(dev,&old,ctrl);
+ if (XkbComputeControlsNotify(dev,&old,ctrl,&cn,False)) {
+ cn.keycode= 0;
+ cn.eventType = 0;
+ cn.requestMajor = XkbReqCode;
+ cn.requestMinor = X_kbSetControls;
+ XkbSendControlsNotify(dev,&cn);
+ }
+ if ((sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0))!=NULL)
+ XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause);
+#ifndef NO_CLEAR_LATCHES_FOR_STICKY_KEYS_OFF
+ /* If sticky keys were disabled, clear all locks and latches */
+ if ((old.enabled_ctrls&XkbStickyKeysMask)&&
+ (!(ctrl->enabled_ctrls&XkbStickyKeysMask))) {
+ XkbClearAllLatchesAndLocks(dev,xkbi,True,&cause);
+ }
+#endif
+ return client->noClientException;
+}
+
+int
+#if NeedFunctionPrototypes
+XkbSetRepeatRate(DeviceIntPtr dev,int timeout,int interval,int major,int minor)
+#else
+XkbSetRepeatRate(dev,timeout,interval,major,minor)
+ DeviceIntPtr dev;
+ int timeout;
+ int interval;
+ int major;
+ int minor;
+#endif
+{
+int changed= 0;
+XkbControlsRec old,*xkb;
+
+ if ((!dev)||(!dev->key)||(!dev->key->xkbInfo))
+ return 0;
+ xkb= dev->key->xkbInfo->desc->ctrls;
+ old= *xkb;
+ if ((timeout!=0) && (xkb->repeat_delay!=timeout)) {
+ xkb->repeat_delay= timeout;
+ changed++;
+ }
+ if ((interval!=0) && (xkb->repeat_interval!=interval)) {
+ xkb->repeat_interval= interval;
+ changed++;
+ }
+ if (changed) {
+ xkbControlsNotify cn;
+ XkbDDXChangeControls(dev,&old,xkb);
+ if (XkbComputeControlsNotify(dev,&old,xkb,&cn,False)) {
+ cn.keycode= 0;
+ cn.eventType = 0;
+ cn.requestMajor = major;
+ cn.requestMinor = minor;
+ XkbSendControlsNotify(dev,&cn);
+ }
+ }
+ return 1;
+}
+
+int
+#if NeedFunctionPrototypes
+XkbGetRepeatRate(DeviceIntPtr dev,int *timeout,int *interval)
+#else
+XkbGetRepeatRate(dev,timeout,interval)
+ DeviceIntPtr dev;
+ int * timeout;
+ int * interval;
+#endif
+{
+XkbControlsPtr xkb;
+
+ if ((!dev)||(!dev->key)||(!dev->key->xkbInfo))
+ return 0;
+ xkb= dev->key->xkbInfo->desc->ctrls;
+ if (timeout) *timeout= xkb->repeat_delay;
+ if (interval) *interval= xkb->repeat_interval;
+ return 1;
+}
+
+/***====================================================================***/
+
+static int
+#if NeedFunctionPrototypes
+XkbSizeKeyTypes(XkbDescPtr xkb,xkbGetMapReply *rep)
+#else
+XkbSizeKeyTypes(xkb,rep)
+ XkbDescPtr xkb;
+ xkbGetMapReply * rep;
+#endif
+{
+ XkbKeyTypeRec *type;
+ unsigned i,len;
+
+ len= 0;
+ if (((rep->present&XkbKeyTypesMask)==0)||(rep->nTypes<1)||
+ (!xkb)||(!xkb->map)||(!xkb->map->types)) {
+ rep->present&= ~XkbKeyTypesMask;
+ rep->firstType= rep->nTypes= 0;
+ return 0;
+ }
+ type= &xkb->map->types[rep->firstType];
+ for (i=0;i<rep->nTypes;i++,type++){
+ len+= SIZEOF(xkbKeyTypeWireDesc);
+ if (type->map_count>0) {
+ len+= (type->map_count*SIZEOF(xkbKTMapEntryWireDesc));
+ if (type->preserve)
+ len+= (type->map_count*SIZEOF(xkbModsWireDesc));
+ }
+ }
+ return len;
+}
+
+static char *
+#if NeedFunctionPrototypes
+XkbWriteKeyTypes( XkbDescPtr xkb,
+ xkbGetMapReply * rep,
+ char * buf,
+ ClientPtr client)
+#else
+XkbWriteKeyTypes(xkb,rep,buf,client)
+ XkbDescPtr xkb;
+ xkbGetMapReply * rep;
+ char * buf;
+ ClientPtr client;
+#endif
+{
+ XkbKeyTypePtr type;
+ unsigned i;
+ xkbKeyTypeWireDesc *wire;
+
+ type= &xkb->map->types[rep->firstType];
+ for (i=0;i<rep->nTypes;i++,type++) {
+ register unsigned n;
+ wire= (xkbKeyTypeWireDesc *)buf;
+ wire->mask = type->mods.mask;
+ wire->realMods = type->mods.real_mods;
+ wire->virtualMods = type->mods.vmods;
+ wire->numLevels = type->num_levels;
+ wire->nMapEntries = type->map_count;
+ wire->preserve = (type->preserve!=NULL);
+ if (client->swapped) {
+ register int n;
+ swaps(&wire->virtualMods,n);
+ }
+
+ buf= (char *)&wire[1];
+ if (wire->nMapEntries>0) {
+ xkbKTMapEntryWireDesc * wire;
+ XkbKTMapEntryPtr entry;
+ wire= (xkbKTMapEntryWireDesc *)buf;
+ entry= type->map;
+ for (n=0;n<type->map_count;n++,wire++,entry++) {
+ wire->active= entry->active;
+ wire->mask= entry->mods.mask;
+ wire->level= entry->level;
+ wire->realMods= entry->mods.real_mods;
+ wire->virtualMods= entry->mods.vmods;
+ if (client->swapped) {
+ register int n;
+ swaps(&wire->virtualMods,n);
+ }
+ }
+ buf= (char *)wire;
+ if (type->preserve!=NULL) {
+ xkbModsWireDesc * pwire;
+ XkbModsPtr preserve;
+ pwire= (xkbModsWireDesc *)buf;
+ preserve= type->preserve;
+ for (n=0;n<type->map_count;n++,pwire++,preserve++) {
+ pwire->mask= preserve->mask;
+ pwire->realMods= preserve->real_mods;
+ pwire->virtualMods= preserve->vmods;
+ if (client->swapped) {
+ register int n;
+ swaps(&pwire->virtualMods,n);
+ }
+ }
+ buf= (char *)pwire;
+ }
+ }
+ }
+ return buf;
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbSizeKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep)
+#else
+XkbSizeKeySyms(xkb,rep)
+ XkbDescPtr xkb;
+ xkbGetMapReply * rep;
+#endif
+{
+ XkbSymMapPtr symMap;
+ unsigned i,len;
+ unsigned nSyms,nSymsThisKey;
+
+ if (((rep->present&XkbKeySymsMask)==0)||(rep->nKeySyms<1)||
+ (!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)) {
+ rep->present&= ~XkbKeySymsMask;
+ rep->firstKeySym= rep->nKeySyms= 0;
+ rep->totalSyms= 0;
+ return 0;
+ }
+ len= rep->nKeySyms*SIZEOF(xkbSymMapWireDesc);
+ symMap = &xkb->map->key_sym_map[rep->firstKeySym];
+ for (i=nSyms=0;i<rep->nKeySyms;i++,symMap++) {
+ if (symMap->offset!=0) {
+ nSymsThisKey= XkbNumGroups(symMap->group_info)*symMap->width;
+ nSyms+= nSymsThisKey;
+ }
+ }
+ len+= nSyms*4;
+ rep->totalSyms= nSyms;
+ return len;
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbSizeVirtualMods(XkbDescPtr xkb,xkbGetMapReply *rep)
+#else
+XkbSizeVirtualMods(xkb,rep)
+ XkbDescPtr xkb;
+ xkbGetMapReply * rep;
+#endif
+{
+register unsigned i,nMods,bit;
+
+ if (((rep->present&XkbVirtualModsMask)==0)||(rep->virtualMods==0)||
+ (!xkb)||(!xkb->server)) {
+ rep->present&= ~XkbVirtualModsMask;
+ rep->virtualMods= 0;
+ return 0;
+ }
+ for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (rep->virtualMods&bit)
+ nMods++;
+ }
+ return XkbPaddedSize(nMods);
+}
+
+static char *
+#if NeedFunctionPrototypes
+XkbWriteKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client)
+#else
+XkbWriteKeySyms(xkb,rep,buf,client)
+ XkbDescPtr xkb;
+ xkbGetMapReply * rep;
+ char * buf;
+ ClientPtr client;
+#endif
+{
+register KeySym * pSym;
+XkbSymMapPtr symMap;
+xkbSymMapWireDesc * outMap;
+register unsigned i;
+
+ symMap = &xkb->map->key_sym_map[rep->firstKeySym];
+ for (i=0;i<rep->nKeySyms;i++,symMap++) {
+ outMap = (xkbSymMapWireDesc *)buf;
+ outMap->ktIndex[0] = symMap->kt_index[0];
+ outMap->ktIndex[1] = symMap->kt_index[1];
+ outMap->ktIndex[2] = symMap->kt_index[2];
+ outMap->ktIndex[3] = symMap->kt_index[3];
+ outMap->groupInfo = symMap->group_info;
+ outMap->width= symMap->width;
+ outMap->nSyms = symMap->width*XkbNumGroups(symMap->group_info);
+ buf= (char *)&outMap[1];
+ if (outMap->nSyms==0)
+ continue;
+
+ pSym = &xkb->map->syms[symMap->offset];
+ memcpy((char *)buf,(char *)pSym,outMap->nSyms*4);
+ if (client->swapped) {
+ register int n,nSyms= outMap->nSyms;
+ swaps(&outMap->nSyms,n);
+ while (nSyms-->0) {
+ swapl(buf,n);
+ buf+= 4;
+ }
+ }
+ else buf+= outMap->nSyms*4;
+ }
+ return buf;
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbSizeKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep)
+#else
+XkbSizeKeyActions(xkb,rep)
+ XkbDescPtr xkb;
+ xkbGetMapReply * rep;
+#endif
+{
+ unsigned i,len,nActs;
+ register KeyCode firstKey;
+
+ if (((rep->present&XkbKeyActionsMask)==0)||(rep->nKeyActs<1)||
+ (!xkb)||(!xkb->server)||(!xkb->server->key_acts)) {
+ rep->present&= ~XkbKeyActionsMask;
+ rep->firstKeyAct= rep->nKeyActs= 0;
+ rep->totalActs= 0;
+ return 0;
+ }
+ firstKey= rep->firstKeyAct;
+ for (nActs=i=0;i<rep->nKeyActs;i++) {
+ if (xkb->server->key_acts[i+firstKey]!=0)
+ nActs+= XkbKeyNumActions(xkb,i+firstKey);
+ }
+ len= XkbPaddedSize(rep->nKeyActs)+(nActs*SIZEOF(xkbActionWireDesc));
+ rep->totalActs= nActs;
+ return len;
+}
+
+static char *
+#if NeedFunctionPrototypes
+XkbWriteKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
+ ClientPtr client)
+#else
+XkbWriteKeyActions(xkb,rep,buf,client)
+ XkbDescPtr xkb;
+ xkbGetMapReply * rep;
+ char * buf;
+ ClientPtr client;
+#endif
+{
+ unsigned i;
+ CARD8 * numDesc;
+ XkbAnyAction * actDesc;
+
+ numDesc = (CARD8 *)buf;
+ for (i=0;i<rep->nKeyActs;i++) {
+ if (xkb->server->key_acts[i+rep->firstKeyAct]==0)
+ numDesc[i] = 0;
+ else numDesc[i] = XkbKeyNumActions(xkb,(i+rep->firstKeyAct));
+ }
+ buf+= XkbPaddedSize(rep->nKeyActs);
+
+ actDesc = (XkbAnyAction *)buf;
+ for (i=0;i<rep->nKeyActs;i++) {
+ if (xkb->server->key_acts[i+rep->firstKeyAct]!=0) {
+ unsigned int num;
+ num = XkbKeyNumActions(xkb,(i+rep->firstKeyAct));
+ memcpy((char *)actDesc,
+ (char*)XkbKeyActionsPtr(xkb,(i+rep->firstKeyAct)),
+ num*SIZEOF(xkbActionWireDesc));
+ actDesc+= num;
+ }
+ }
+ buf = (char *)actDesc;
+ return buf;
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbSizeKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep)
+#else
+XkbSizeKeyBehaviors(xkb,rep)
+ XkbDescPtr xkb;
+ xkbGetMapReply * rep;
+#endif
+{
+ unsigned i,len,nBhvr;
+ XkbBehavior * bhv;
+
+ if (((rep->present&XkbKeyBehaviorsMask)==0)||(rep->nKeyBehaviors<1)||
+ (!xkb)||(!xkb->server)||(!xkb->server->behaviors)) {
+ rep->present&= ~XkbKeyBehaviorsMask;
+ rep->firstKeyBehavior= rep->nKeyBehaviors= 0;
+ rep->totalKeyBehaviors= 0;
+ return 0;
+ }
+ bhv= &xkb->server->behaviors[rep->firstKeyBehavior];
+ for (nBhvr=i=0;i<rep->nKeyBehaviors;i++,bhv++) {
+ if (bhv->type!=XkbKB_Default)
+ nBhvr++;
+ }
+ len= nBhvr*SIZEOF(xkbBehaviorWireDesc);
+ rep->totalKeyBehaviors= nBhvr;
+ return len;
+}
+
+static char *
+#if NeedFunctionPrototypes
+XkbWriteKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
+ ClientPtr client)
+#else
+XkbWriteKeyBehaviors(xkb,rep,buf,client)
+ XkbDescRec *xkb;
+ xkbGetMapReply *rep;
+ char *buf;
+ ClientPtr client;
+#endif
+{
+ unsigned i;
+ xkbBehaviorWireDesc *wire;
+ XkbBehavior *pBhvr;
+
+ wire = (xkbBehaviorWireDesc *)buf;
+ pBhvr= &xkb->server->behaviors[rep->firstKeyBehavior];
+ for (i=0;i<rep->nKeyBehaviors;i++,pBhvr++) {
+ if (pBhvr->type!=XkbKB_Default) {
+ wire->key= i+rep->firstKeyBehavior;
+ wire->type= pBhvr->type;
+ wire->data= pBhvr->data;
+ wire++;
+ }
+ }
+ buf = (char *)wire;
+ return buf;
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbSizeExplicit(XkbDescPtr xkb,xkbGetMapReply *rep)
+#else
+XkbSizeExplicit(xkb,rep)
+ XkbDescPtr xkb;
+ xkbGetMapReply * rep;
+#endif
+{
+ unsigned i,len,nRtrn;
+
+ if (((rep->present&XkbExplicitComponentsMask)==0)||(rep->nKeyExplicit<1)||
+ (!xkb)||(!xkb->server)||(!xkb->server->explicit)) {
+ rep->present&= ~XkbExplicitComponentsMask;
+ rep->firstKeyExplicit= rep->nKeyExplicit= 0;
+ rep->totalKeyExplicit= 0;
+ return 0;
+ }
+ for (nRtrn=i=0;i<rep->nKeyExplicit;i++) {
+ if (xkb->server->explicit[i+rep->firstKeyExplicit]!=0)
+ nRtrn++;
+ }
+ rep->totalKeyExplicit= nRtrn;
+ len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero explicit component */
+ return len;
+}
+
+static char *
+#if NeedFunctionPrototypes
+XkbWriteExplicit(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client)
+#else
+XkbWriteExplicit(xkb,rep,buf,client)
+ XkbDescPtr xkb;
+ xkbGetMapReply *rep;
+ char *buf;
+ ClientPtr client;
+#endif
+{
+unsigned i;
+char * start;
+unsigned char * pExp;
+
+ start= buf;
+ pExp= &xkb->server->explicit[rep->firstKeyExplicit];
+ for (i=0;i<rep->nKeyExplicit;i++,pExp++) {
+ if (*pExp!=0) {
+ *buf++= i+rep->firstKeyExplicit;
+ *buf++= *pExp;
+ }
+ }
+ i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */
+ return buf+i;
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbSizeModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep)
+#else
+XkbSizeModifierMap(xkb,rep)
+ XkbDescPtr xkb;
+ xkbGetMapReply * rep;
+#endif
+{
+ unsigned i,len,nRtrn;
+
+ if (((rep->present&XkbModifierMapMask)==0)||(rep->nModMapKeys<1)||
+ (!xkb)||(!xkb->map)||(!xkb->map->modmap)) {
+ rep->present&= ~XkbModifierMapMask;
+ rep->firstModMapKey= rep->nModMapKeys= 0;
+ rep->totalModMapKeys= 0;
+ return 0;
+ }
+ for (nRtrn=i=0;i<rep->nModMapKeys;i++) {
+ if (xkb->map->modmap[i+rep->firstModMapKey]!=0)
+ nRtrn++;
+ }
+ rep->totalModMapKeys= nRtrn;
+ len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero modmap component */
+ return len;
+}
+
+static char *
+#if NeedFunctionPrototypes
+XkbWriteModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
+ ClientPtr client)
+#else
+XkbWriteModifierMap(xkb,rep,buf,client)
+ XkbDescPtr xkb;
+ xkbGetMapReply *rep;
+ char *buf;
+ ClientPtr client;
+#endif
+{
+unsigned i;
+char * start;
+unsigned char * pMap;
+
+ start= buf;
+ pMap= &xkb->map->modmap[rep->firstModMapKey];
+ for (i=0;i<rep->nModMapKeys;i++,pMap++) {
+ if (*pMap!=0) {
+ *buf++= i+rep->firstModMapKey;
+ *buf++= *pMap;
+ }
+ }
+ i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */
+ return buf+i;
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbSizeVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep)
+#else
+XkbSizeVirtualModMap(xkb,rep)
+ XkbDescPtr xkb;
+ xkbGetMapReply * rep;
+#endif
+{
+ unsigned i,len,nRtrn;
+
+ if (((rep->present&XkbVirtualModMapMask)==0)||(rep->nVModMapKeys<1)||
+ (!xkb)||(!xkb->server)||(!xkb->server->vmodmap)) {
+ rep->present&= ~XkbVirtualModMapMask;
+ rep->firstVModMapKey= rep->nVModMapKeys= 0;
+ rep->totalVModMapKeys= 0;
+ return 0;
+ }
+ for (nRtrn=i=0;i<rep->nVModMapKeys;i++) {
+ if (xkb->server->vmodmap[i+rep->firstVModMapKey]!=0)
+ nRtrn++;
+ }
+ rep->totalVModMapKeys= nRtrn;
+ len= nRtrn*SIZEOF(xkbVModMapWireDesc);
+ return len;
+}
+
+static char *
+#if NeedFunctionPrototypes
+XkbWriteVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
+ ClientPtr client)
+#else
+XkbWriteVirtualModMap(xkb,rep,buf,client)
+ XkbDescPtr xkb;
+ xkbGetMapReply *rep;
+ char *buf;
+ ClientPtr client;
+#endif
+{
+unsigned i;
+xkbVModMapWireDesc * wire;
+unsigned short * pMap;
+
+ wire= (xkbVModMapWireDesc *)buf;
+ pMap= &xkb->server->vmodmap[rep->firstVModMapKey];
+ for (i=0;i<rep->nVModMapKeys;i++,pMap++) {
+ if (*pMap!=0) {
+ wire->key= i+rep->firstVModMapKey;
+ wire->vmods= *pMap;
+ wire++;
+ }
+ }
+ return (char *)wire;
+}
+
+static Status
+#if NeedFunctionPrototypes
+XkbComputeGetMapReplySize(XkbDescPtr xkb,xkbGetMapReply *rep)
+#else
+XkbComputeGetMapReplySize(xkb,rep)
+ XkbDescPtr xkb;
+ xkbGetMapReply * rep;
+#endif
+{
+int len;
+
+ rep->minKeyCode= xkb->min_key_code;
+ rep->maxKeyCode= xkb->max_key_code;
+ len= XkbSizeKeyTypes(xkb,rep);
+ len+= XkbSizeKeySyms(xkb,rep);
+ len+= XkbSizeKeyActions(xkb,rep);
+ len+= XkbSizeKeyBehaviors(xkb,rep);
+ len+= XkbSizeVirtualMods(xkb,rep);
+ len+= XkbSizeExplicit(xkb,rep);
+ len+= XkbSizeModifierMap(xkb,rep);
+ len+= XkbSizeVirtualModMap(xkb,rep);
+ rep->length+= (len/4);
+ return Success;
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbSendMap(ClientPtr client,XkbDescPtr xkb,xkbGetMapReply *rep)
+#else
+XkbSendMap(client,xkb,rep)
+ ClientPtr client;
+ XkbDescPtr xkb;
+ xkbGetMapReply * rep;
+#endif
+{
+unsigned i,len;
+char *desc,*start;
+
+ len= (rep->length*4)-(SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply));
+ start= desc= (char *)ALLOCATE_LOCAL(len);
+ if (!start)
+ return BadAlloc;
+ if ( rep->nTypes>0 )
+ desc = XkbWriteKeyTypes(xkb,rep,desc,client);
+ if ( rep->nKeySyms>0 )
+ desc = XkbWriteKeySyms(xkb,rep,desc,client);
+ if ( rep->nKeyActs>0 )
+ desc = XkbWriteKeyActions(xkb,rep,desc,client);
+ if ( rep->totalKeyBehaviors>0 )
+ desc = XkbWriteKeyBehaviors(xkb,rep,desc,client);
+ if ( rep->virtualMods ) {
+ register int sz,bit;
+ for (i=sz=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (rep->virtualMods&bit) {
+ desc[sz++]= xkb->server->vmods[i];
+ }
+ }
+ desc+= XkbPaddedSize(sz);
+ }
+ if ( rep->totalKeyExplicit>0 )
+ desc= XkbWriteExplicit(xkb,rep,desc,client);
+ if ( rep->totalModMapKeys>0 )
+ desc= XkbWriteModifierMap(xkb,rep,desc,client);
+ if ( rep->totalVModMapKeys>0 )
+ desc= XkbWriteVirtualModMap(xkb,rep,desc,client);
+ if ((desc-start)!=(len)) {
+ ErrorF("BOGUS LENGTH in write keyboard desc, expected %d, got %d\n",
+ len, desc-start);
+ }
+ if (client->swapped) {
+ register int n;
+ swaps(&rep->sequenceNumber,n);
+ swapl(&rep->length,n);
+ swaps(&rep->present,n);
+ swaps(&rep->totalSyms,n);
+ swaps(&rep->totalActs,n);
+ }
+ WriteToClient(client, (i=SIZEOF(xkbGetMapReply)), (char *)rep);
+ WriteToClient(client, len, start);
+ DEALLOCATE_LOCAL((char *)start);
+ return client->noClientException;
+}
+
+int
+#if NeedFunctionPrototypes
+ProcXkbGetMap(ClientPtr client)
+#else
+ProcXkbGetMap(client)
+ ClientPtr client;
+#endif
+{
+ DeviceIntPtr dev;
+ xkbGetMapReply rep;
+ XkbDescRec *xkb;
+ int n,status;
+
+ REQUEST(xkbGetMapReq);
+ REQUEST_SIZE_MATCH(xkbGetMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_OVERLAP(0x01,stuff->full,stuff->partial);
+ CHK_MASK_LEGAL(0x02,stuff->full,XkbAllMapComponentsMask);
+ CHK_MASK_LEGAL(0x03,stuff->partial,XkbAllMapComponentsMask);
+
+ xkb= dev->key->xkbInfo->desc;
+ bzero(&rep,sizeof(xkbGetMapReply));
+ rep.type= X_Reply;
+ rep.sequenceNumber= client->sequence;
+ rep.length = (SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2;
+ rep.deviceID = dev->id;
+ rep.present = stuff->partial|stuff->full;
+ rep.minKeyCode = xkb->min_key_code;
+ rep.maxKeyCode = xkb->max_key_code;
+ if ( stuff->full&XkbKeyTypesMask ) {
+ rep.firstType = 0;
+ rep.nTypes = xkb->map->num_types;
+ }
+ else if (stuff->partial&XkbKeyTypesMask) {
+ if (((unsigned)stuff->firstType+stuff->nTypes)>xkb->map->num_types) {
+ client->errorValue = _XkbErrCode4(0x04,xkb->map->num_types,
+ stuff->firstType,stuff->nTypes);
+ return BadValue;
+ }
+ rep.firstType = stuff->firstType;
+ rep.nTypes = stuff->nTypes;
+ }
+ else rep.nTypes = 0;
+ rep.totalTypes = xkb->map->num_types;
+
+ n= XkbNumKeys(xkb);
+ if ( stuff->full&XkbKeySymsMask ) {
+ rep.firstKeySym = xkb->min_key_code;
+ rep.nKeySyms = n;
+ }
+ else if (stuff->partial&XkbKeySymsMask) {
+ CHK_KEY_RANGE(0x05,stuff->firstKeySym,stuff->nKeySyms,xkb);
+ rep.firstKeySym = stuff->firstKeySym;
+ rep.nKeySyms = stuff->nKeySyms;
+ }
+ else rep.nKeySyms = 0;
+ rep.totalSyms= 0;
+
+ if ( stuff->full&XkbKeyActionsMask ) {
+ rep.firstKeyAct= xkb->min_key_code;
+ rep.nKeyActs= n;
+ }
+ else if (stuff->partial&XkbKeyActionsMask) {
+ CHK_KEY_RANGE(0x07,stuff->firstKeyAct,stuff->nKeyActs,xkb);
+ rep.firstKeyAct= stuff->firstKeyAct;
+ rep.nKeyActs= stuff->nKeyActs;
+ }
+ else rep.nKeyActs= 0;
+ rep.totalActs= 0;
+
+ if ( stuff->full&XkbKeyBehaviorsMask ) {
+ rep.firstKeyBehavior = xkb->min_key_code;
+ rep.nKeyBehaviors = n;
+ }
+ else if (stuff->partial&XkbKeyBehaviorsMask) {
+ CHK_KEY_RANGE(0x09,stuff->firstKeyBehavior,stuff->nKeyBehaviors,xkb);
+ rep.firstKeyBehavior= stuff->firstKeyBehavior;
+ rep.nKeyBehaviors= stuff->nKeyBehaviors;
+ }
+ else rep.nKeyBehaviors = 0;
+ rep.totalKeyBehaviors= 0;
+
+ if (stuff->full&XkbVirtualModsMask)
+ rep.virtualMods= ~0;
+ else if (stuff->partial&XkbVirtualModsMask)
+ rep.virtualMods= stuff->virtualMods;
+
+ if (stuff->full&XkbExplicitComponentsMask) {
+ rep.firstKeyExplicit= xkb->min_key_code;
+ rep.nKeyExplicit= n;
+ }
+ else if (stuff->partial&XkbExplicitComponentsMask) {
+ CHK_KEY_RANGE(0x0B,stuff->firstKeyExplicit,stuff->nKeyExplicit,xkb);
+ rep.firstKeyExplicit= stuff->firstKeyExplicit;
+ rep.nKeyExplicit= stuff->nKeyExplicit;
+ }
+ else rep.nKeyExplicit = 0;
+ rep.totalKeyExplicit= 0;
+
+ if (stuff->full&XkbModifierMapMask) {
+ rep.firstModMapKey= xkb->min_key_code;
+ rep.nModMapKeys= n;
+ }
+ else if (stuff->partial&XkbModifierMapMask) {
+ CHK_KEY_RANGE(0x0D,stuff->firstModMapKey,stuff->nModMapKeys,xkb);
+ rep.firstModMapKey= stuff->firstModMapKey;
+ rep.nModMapKeys= stuff->nModMapKeys;
+ }
+ else rep.nModMapKeys = 0;
+ rep.totalModMapKeys= 0;
+
+ if (stuff->full&XkbVirtualModMapMask) {
+ rep.firstVModMapKey= xkb->min_key_code;
+ rep.nVModMapKeys= n;
+ }
+ else if (stuff->partial&XkbVirtualModMapMask) {
+ CHK_KEY_RANGE(0x0F,stuff->firstVModMapKey,stuff->nVModMapKeys,xkb);
+ rep.firstVModMapKey= stuff->firstVModMapKey;
+ rep.nVModMapKeys= stuff->nVModMapKeys;
+ }
+ else rep.nVModMapKeys = 0;
+ rep.totalVModMapKeys= 0;
+
+ if ((status=XkbComputeGetMapReplySize(xkb,&rep))!=Success)
+ return status;
+ return XkbSendMap(client,xkb,&rep);
+}
+
+/***====================================================================***/
+
+static int
+#if NeedFunctionPrototypes
+CheckKeyTypes( ClientPtr client,
+ XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ xkbKeyTypeWireDesc **wireRtrn,
+ int * nMapsRtrn,
+ CARD8 * mapWidthRtrn)
+#else
+CheckKeyTypes(client,xkb,req,wireRtrn,nMapsRtrn,mapWidthRtrn)
+ ClientPtr client;
+ XkbDescPtr xkb;
+ xkbSetMapReq * req;
+ xkbKeyTypeWireDesc **wireRtrn;
+ int * nMapsRtrn;
+ CARD8 * mapWidthRtrn;
+#endif
+{
+unsigned nMaps;
+register unsigned i,n;
+register CARD8 * map;
+register xkbKeyTypeWireDesc *wire = *wireRtrn;
+
+ if (req->firstType>((unsigned)xkb->map->num_types)) {
+ *nMapsRtrn = _XkbErrCode3(0x01,req->firstType,xkb->map->num_types);
+ return 0;
+ }
+ if (req->flags&XkbSetMapResizeTypes) {
+ nMaps = req->firstType+req->nTypes;
+ if (nMaps<XkbNumRequiredTypes) { /* canonical types must be there */
+ *nMapsRtrn= _XkbErrCode4(0x02,req->firstType,req->nTypes,4);
+ return 0;
+ }
+ }
+ else if (req->present&XkbKeyTypesMask) {
+ nMaps = xkb->map->num_types;
+ if ((req->firstType+req->nTypes)>nMaps) {
+ *nMapsRtrn = req->firstType+req->nTypes;
+ return 0;
+ }
+ }
+ else {
+ *nMapsRtrn = xkb->map->num_types;
+ for (i=0;i<xkb->map->num_types;i++) {
+ mapWidthRtrn[i] = xkb->map->types[i].num_levels;
+ }
+ return 1;
+ }
+
+ for (i=0;i<req->firstType;i++) {
+ mapWidthRtrn[i] = xkb->map->types[i].num_levels;
+ }
+ for (i=0;i<req->nTypes;i++) {
+ unsigned width;
+ if (client->swapped) {
+ register int s;
+ swaps(&wire->virtualMods,s);
+ }
+ n= i+req->firstType;
+ width= wire->numLevels;
+ if (width<1) {
+ *nMapsRtrn= _XkbErrCode3(0x04,n,width);
+ return 0;
+ }
+ else if ((n==XkbOneLevelIndex)&&(width!=1)) { /* must be width 1 */
+ *nMapsRtrn= _XkbErrCode3(0x05,n,width);
+ return 0;
+ }
+ else if ((width!=2)&&
+ ((n==XkbTwoLevelIndex)||(n==XkbKeypadIndex)||
+ (n==XkbAlphabeticIndex))) {
+ /* TWO_LEVEL, ALPHABETIC and KEYPAD must be width 2 */
+ *nMapsRtrn= _XkbErrCode3(0x05,n,width);
+ return 0;
+ }
+ if (wire->nMapEntries>0) {
+ xkbKTSetMapEntryWireDesc * mapWire;
+ xkbModsWireDesc * preWire;
+ mapWire= (xkbKTSetMapEntryWireDesc *)&wire[1];
+ preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries];
+ for (n=0;n<wire->nMapEntries;n++) {
+ if (client->swapped) {
+ register int s;
+ swaps(&mapWire[n].virtualMods,s);
+ }
+ if (mapWire[n].realMods&(~wire->realMods)) {
+ *nMapsRtrn= _XkbErrCode4(0x06,n,mapWire[n].realMods,
+ wire->realMods);
+ return 0;
+ }
+ if (mapWire[n].virtualMods&(~wire->virtualMods)) {
+ *nMapsRtrn= _XkbErrCode3(0x07,n,mapWire[n].virtualMods);
+ return 0;
+ }
+ if (mapWire[n].level>=wire->numLevels) {
+ *nMapsRtrn= _XkbErrCode4(0x08,n,wire->numLevels,
+ mapWire[n].level);
+ return 0;
+ }
+ if (wire->preserve) {
+ if (client->swapped) {
+ register int s;
+ swaps(&preWire[n].virtualMods,s);
+ }
+ if (preWire[n].realMods&(~mapWire[n].realMods)) {
+ *nMapsRtrn= _XkbErrCode4(0x09,n,preWire[n].realMods,
+ mapWire[n].realMods);
+ return 0;
+ }
+ if (preWire[n].virtualMods&(~mapWire[n].virtualMods)) {
+ *nMapsRtrn=_XkbErrCode3(0x0a,n,preWire[n].virtualMods);
+ return 0;
+ }
+ }
+ }
+ if (wire->preserve)
+ map= (CARD8 *)&preWire[wire->nMapEntries];
+ else map= (CARD8 *)&mapWire[wire->nMapEntries];
+ }
+ else map= (CARD8 *)&wire[1];
+ mapWidthRtrn[i+req->firstType] = wire->numLevels;
+ wire= (xkbKeyTypeWireDesc *)map;
+ }
+ for (i=req->firstType+req->nTypes;i<nMaps;i++) {
+ mapWidthRtrn[i] = xkb->map->types[i].num_levels;
+ }
+ *nMapsRtrn = nMaps;
+ *wireRtrn = wire;
+ return 1;
+}
+
+static int
+#if NeedFunctionPrototypes
+CheckKeySyms( ClientPtr client,
+ XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ int nTypes,
+ CARD8 * mapWidths,
+ CARD16 * symsPerKey,
+ xkbSymMapWireDesc ** wireRtrn,
+ int * errorRtrn)
+#else
+CheckKeySyms(client,xkb,req,nTypes,mapWidths,symsPerKey,wireRtrn,errorRtrn)
+ ClientPtr client;
+ XkbDescPtr xkb;
+ xkbSetMapReq * req;
+ int nTypes;
+ CARD8 * mapWidths;
+ CARD16 * symsPerKey;
+ xkbSymMapWireDesc **wireRtrn;
+ int * errorRtrn;
+#endif
+{
+register unsigned i;
+XkbSymMapPtr map;
+xkbSymMapWireDesc* wire = *wireRtrn;
+
+ if (!(XkbKeySymsMask&req->present))
+ return 1;
+ CHK_REQ_KEY_RANGE2(0x11,req->firstKeySym,req->nKeySyms,req,(*errorRtrn),0);
+ map = &xkb->map->key_sym_map[xkb->min_key_code];
+ for (i=xkb->min_key_code;i<(unsigned)req->firstKeySym;i++,map++) {
+ register int g,ng,w;
+ ng= XkbNumGroups(map->group_info);
+ for (w=g=0;g<ng;g++) {
+ if (map->kt_index[g]>=(unsigned)nTypes) {
+ *errorRtrn = _XkbErrCode4(0x13,i,g,map->kt_index[g]);
+ return 0;
+ }
+ if (mapWidths[map->kt_index[g]]>w)
+ w= mapWidths[map->kt_index[g]];
+ }
+ symsPerKey[i] = w*ng;
+ }
+ for (i=0;i<req->nKeySyms;i++) {
+ KeySym *pSyms;
+ register unsigned nG;
+ if (client->swapped) {
+ swaps(&wire->nSyms,nG);
+ }
+ nG = XkbNumGroups(wire->groupInfo);
+ if (nG>XkbNumKbdGroups) {
+ *errorRtrn = _XkbErrCode3(0x14,i+req->firstKeySym,nG);
+ return 0;
+ }
+ if (nG>0) {
+ register int g,w;
+ for (g=w=0;g<nG;g++) {
+ if (wire->ktIndex[g]>=(unsigned)nTypes) {
+ *errorRtrn= _XkbErrCode4(0x15,i+req->firstKeySym,g,
+ wire->ktIndex[g]);
+ return 0;
+ }
+ if (mapWidths[wire->ktIndex[g]]>w)
+ w= mapWidths[wire->ktIndex[g]];
+ }
+ if (wire->width!=w) {
+ *errorRtrn= _XkbErrCode3(0x16,i+req->firstKeySym,wire->width);
+ return 0;
+ }
+ w*= nG;
+ symsPerKey[i+req->firstKeySym] = w;
+ if (w!=wire->nSyms) {
+ *errorRtrn=_XkbErrCode4(0x16,i+req->firstKeySym,wire->nSyms,w);
+ return 0;
+ }
+ }
+ else if (wire->nSyms!=0) {
+ *errorRtrn = _XkbErrCode3(0x17,i+req->firstKeySym,wire->nSyms);
+ return 0;
+ }
+ pSyms = (KeySym *)&wire[1];
+ wire = (xkbSymMapWireDesc *)&pSyms[wire->nSyms];
+ }
+
+ map = &xkb->map->key_sym_map[i];
+ for (;i<=(unsigned)xkb->max_key_code;i++,map++) {
+ register int g,nG,w;
+ nG= XkbKeyNumGroups(xkb,i);
+ for (w=g=0;g<nG;g++) {
+ if (map->kt_index[g]>=(unsigned)nTypes) {
+ *errorRtrn = _XkbErrCode4(0x18,i,g,map->kt_index[g]);
+ return 0;
+ }
+ if (mapWidths[map->kt_index[g]]>w)
+ w= mapWidths[map->kt_index[g]];
+ }
+ symsPerKey[i] = w*nG;
+ }
+ *wireRtrn = wire;
+ return 1;
+}
+
+static int
+#if NeedFunctionPrototypes
+CheckKeyActions( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ int nTypes,
+ CARD8 * mapWidths,
+ CARD16 * symsPerKey,
+ CARD8 ** wireRtrn,
+ int * nActsRtrn)
+#else
+CheckKeyActions(xkb,req,nTypes,mapWidths,symsPerKey,wireRtrn,nActsRtrn)
+ XkbDescRec *xkb;
+ xkbSetMapReq *req;
+ int nTypes;
+ CARD8 *mapWidths;
+ CARD16 *symsPerKey;
+ CARD8 **wireRtrn;
+ int *nActsRtrn;
+#endif
+{
+int nActs;
+CARD8 * wire = *wireRtrn;
+register unsigned i;
+
+ if (!(XkbKeyActionsMask&req->present))
+ return 1;
+ CHK_REQ_KEY_RANGE2(0x21,req->firstKeyAct,req->nKeyActs,req,(*nActsRtrn),0);
+ for (nActs=i=0;i<req->nKeyActs;i++) {
+ if (wire[0]!=0) {
+ if (wire[0]==symsPerKey[i+req->firstKeyAct])
+ nActs+= wire[0];
+ else {
+ *nActsRtrn= _XkbErrCode3(0x23,i+req->firstKeyAct,wire[0]);
+ return 0;
+ }
+ }
+ wire++;
+ }
+ if (req->nKeyActs%4)
+ wire+= 4-(req->nKeyActs%4);
+ *wireRtrn = (CARD8 *)(((XkbAnyAction *)wire)+nActs);
+ *nActsRtrn = nActs;
+ return 1;
+}
+
+static int
+#if NeedFunctionPrototypes
+CheckKeyBehaviors( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ xkbBehaviorWireDesc ** wireRtrn,
+ int * errorRtrn)
+#else
+CheckKeyBehaviors(xkb,req,wireRtrn,errorRtrn)
+ XkbDescRec *xkb;
+ xkbSetMapReq *req;
+ xkbBehaviorWireDesc **wireRtrn;
+ int *errorRtrn;
+#endif
+{
+register xkbBehaviorWireDesc * wire = *wireRtrn;
+register XkbServerMapPtr server = xkb->server;
+register unsigned i;
+unsigned first,last;
+
+ if ((req->present&XkbKeyBehaviorsMask==0)||(req->nKeyBehaviors<1)) {
+ req->present&= ~XkbKeyBehaviorsMask;
+ req->nKeyBehaviors= 0;
+ return 1;
+ }
+ first= req->firstKeyBehavior;
+ last= req->firstKeyBehavior+req->nKeyBehaviors-1;
+ if (first<req->minKeyCode) {
+ *errorRtrn = _XkbErrCode3(0x31,first,req->minKeyCode);
+ return 0;
+ }
+ if (last>req->maxKeyCode) {
+ *errorRtrn = _XkbErrCode3(0x32,last,req->maxKeyCode);
+ return 0;
+ }
+
+ for (i=0;i<req->totalKeyBehaviors;i++,wire++) {
+ if ((wire->key<first)||(wire->key>last)) {
+ *errorRtrn = _XkbErrCode4(0x33,first,last,wire->key);
+ return 0;
+ }
+ if ((wire->type&XkbKB_Permanent)&&
+ ((server->behaviors[wire->key].type!=wire->type)||
+ (server->behaviors[wire->key].data!=wire->data))) {
+ *errorRtrn = _XkbErrCode3(0x33,wire->key,wire->type);
+ return 0;
+ }
+ if ((wire->type==XkbKB_RadioGroup)&&
+ ((wire->data&(~XkbKB_RGAllowNone))>XkbMaxRadioGroups)) {
+ *errorRtrn= _XkbErrCode4(0x34,wire->key,wire->data,
+ XkbMaxRadioGroups);
+ return 0;
+ }
+ if ((wire->type==XkbKB_Overlay1)||(wire->type==XkbKB_Overlay2)) {
+ CHK_KEY_RANGE2(0x35,wire->key,1,xkb,*errorRtrn,0);
+ }
+ }
+ *wireRtrn = wire;
+ return 1;
+}
+
+static int
+#if NeedFunctionPrototypes
+CheckVirtualMods( XkbDescRec * xkb,
+ xkbSetMapReq * req,
+ CARD8 ** wireRtrn,
+ int * errorRtrn)
+#else
+CheckVirtualMods(xkb,req,wireRtrn,errorRtrn)
+ XkbDescPtr xkb;
+ xkbSetMapReq * req;
+ CARD8 ** wireRtrn;
+ int * errorRtrn;
+#endif
+{
+register CARD8 *wire = *wireRtrn;
+register unsigned i,nMods,bit;
+
+ if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0))
+ return 1;
+ for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (req->virtualMods&bit)
+ nMods++;
+ }
+ *wireRtrn= (wire+XkbPaddedSize(nMods));
+ return 1;
+}
+
+static int
+#if NeedFunctionPrototypes
+CheckKeyExplicit( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ CARD8 ** wireRtrn,
+ int * errorRtrn)
+#else
+CheckKeyExplicit(xkb,req,wireRtrn,errorRtrn)
+ XkbDescPtr xkb;
+ xkbSetMapReq * req;
+ CARD8 ** wireRtrn;
+ int * errorRtrn;
+#endif
+{
+register CARD8 * wire = *wireRtrn;
+CARD8 * start;
+register unsigned i;
+int first,last;
+
+ if (((req->present&XkbExplicitComponentsMask)==0)||(req->nKeyExplicit<1)) {
+ req->present&= ~XkbExplicitComponentsMask;
+ req->nKeyExplicit= 0;
+ return 1;
+ }
+ first= req->firstKeyExplicit;
+ last= first+req->nKeyExplicit-1;
+ if (first<req->minKeyCode) {
+ *errorRtrn = _XkbErrCode3(0x51,first,req->minKeyCode);
+ return 0;
+ }
+ if (last>req->maxKeyCode) {
+ *errorRtrn = _XkbErrCode3(0x52,last,req->maxKeyCode);
+ return 0;
+ }
+ start= wire;
+ for (i=0;i<req->totalKeyExplicit;i++,wire+=2) {
+ if ((wire[0]<first)||(wire[0]>last)) {
+ *errorRtrn = _XkbErrCode4(0x53,first,last,wire[0]);
+ return 0;
+ }
+ if (wire[1]&(~XkbAllExplicitMask)) {
+ *errorRtrn= _XkbErrCode3(0x52,~XkbAllExplicitMask,wire[1]);
+ return 0;
+ }
+ }
+ wire+= XkbPaddedSize(wire-start)-(wire-start);
+ *wireRtrn= wire;
+ return 1;
+}
+
+static int
+#if NeedFunctionPrototypes
+CheckModifierMap(XkbDescPtr xkb,xkbSetMapReq *req,CARD8 **wireRtrn,int *errRtrn)
+#else
+CheckModifierMap(xkb,req,wireRtrn,errRtrn)
+ XkbDescPtr xkb;
+ xkbSetMapReq * req;
+ CARD8 ** wireRtrn;
+ int * errRtrn;
+#endif
+{
+register CARD8 * wire = *wireRtrn;
+CARD8 * start;
+register unsigned i;
+int first,last;
+
+ if (((req->present&XkbModifierMapMask)==0)||(req->nModMapKeys<1)) {
+ req->present&= ~XkbModifierMapMask;
+ req->nModMapKeys= 0;
+ return 1;
+ }
+ first= req->firstModMapKey;
+ last= first+req->nModMapKeys-1;
+ if (first<req->minKeyCode) {
+ *errRtrn = _XkbErrCode3(0x61,first,req->minKeyCode);
+ return 0;
+ }
+ if (last>req->maxKeyCode) {
+ *errRtrn = _XkbErrCode3(0x62,last,req->maxKeyCode);
+ return 0;
+ }
+ start= wire;
+ for (i=0;i<req->totalModMapKeys;i++,wire+=2) {
+ if ((wire[0]<first)||(wire[0]>last)) {
+ *errRtrn = _XkbErrCode4(0x63,first,last,wire[0]);
+ return 0;
+ }
+ }
+ wire+= XkbPaddedSize(wire-start)-(wire-start);
+ *wireRtrn= wire;
+ return 1;
+}
+
+static int
+#if NeedFunctionPrototypes
+CheckVirtualModMap( XkbDescPtr xkb,
+ xkbSetMapReq *req,
+ xkbVModMapWireDesc **wireRtrn,
+ int *errRtrn)
+#else
+CheckVirtualModMap(xkb,req,wireRtrn,errRtrn)
+ XkbDescPtr xkb;
+ xkbSetMapReq * req;
+ xkbVModMapWireDesc ** wireRtrn;
+ int * errRtrn;
+#endif
+{
+register xkbVModMapWireDesc * wire = *wireRtrn;
+register unsigned i;
+int first,last;
+
+ if (((req->present&XkbVirtualModMapMask)==0)||(req->nVModMapKeys<1)) {
+ req->present&= ~XkbVirtualModMapMask;
+ req->nVModMapKeys= 0;
+ return 1;
+ }
+ first= req->firstVModMapKey;
+ last= first+req->nVModMapKeys-1;
+ if (first<req->minKeyCode) {
+ *errRtrn = _XkbErrCode3(0x71,first,req->minKeyCode);
+ return 0;
+ }
+ if (last>req->maxKeyCode) {
+ *errRtrn = _XkbErrCode3(0x72,last,req->maxKeyCode);
+ return 0;
+ }
+ for (i=0;i<req->totalVModMapKeys;i++,wire++) {
+ if ((wire->key<first)||(wire->key>last)) {
+ *errRtrn = _XkbErrCode4(0x73,first,last,wire->key);
+ return 0;
+ }
+ }
+ *wireRtrn= wire;
+ return 1;
+}
+
+static char *
+#if NeedFunctionPrototypes
+SetKeyTypes( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ xkbKeyTypeWireDesc * wire,
+ XkbChangesPtr changes)
+#else
+SetKeyTypes(xkb,req,wire,changes)
+ XkbDescPtr xkb;
+ xkbSetMapReq * req;
+ xkbKeyTypeWireDesc *wire;
+ XkbChangesPtr changes;
+#endif
+{
+register unsigned i;
+unsigned first,last;
+CARD8 *map;
+
+ if ((unsigned)(req->firstType+req->nTypes)>xkb->map->size_types) {
+ i= req->firstType+req->nTypes;
+ if (XkbAllocClientMap(xkb,XkbKeyTypesMask,i)!=Success) {
+ return NULL;
+ }
+ }
+ if ((unsigned)(req->firstType+req->nTypes)>xkb->map->num_types)
+ xkb->map->num_types= req->firstType+req->nTypes;
+
+ for (i=0;i<req->nTypes;i++) {
+ XkbKeyTypePtr pOld;
+ register unsigned n;
+
+ if (XkbResizeKeyType(xkb,i+req->firstType,wire->nMapEntries,
+ wire->preserve,wire->numLevels)!=Success) {
+ return NULL;
+ }
+ pOld = &xkb->map->types[i+req->firstType];
+ map = (CARD8 *)&wire[1];
+
+ pOld->mods.real_mods = wire->realMods;
+ pOld->mods.vmods= wire->virtualMods;
+ pOld->num_levels = wire->numLevels;
+ pOld->map_count= wire->nMapEntries;
+
+ pOld->mods.mask= pOld->mods.real_mods|
+ XkbMaskForVMask(xkb,pOld->mods.vmods);
+
+ if (wire->nMapEntries) {
+ xkbKTSetMapEntryWireDesc *mapWire;
+ xkbModsWireDesc *preWire;
+ unsigned tmp;
+ mapWire= (xkbKTSetMapEntryWireDesc *)map;
+ preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries];
+ for (n=0;n<wire->nMapEntries;n++) {
+ pOld->map[n].active= 1;
+ pOld->map[n].mods.mask= mapWire[n].realMods;
+ pOld->map[n].mods.real_mods= mapWire[n].realMods;
+ pOld->map[n].mods.vmods= mapWire[n].virtualMods;
+ pOld->map[n].level= mapWire[n].level;
+ if (mapWire[n].virtualMods!=0) {
+ tmp= XkbMaskForVMask(xkb,mapWire[n].virtualMods);
+ pOld->map[n].active= (tmp!=0);
+ pOld->map[n].mods.mask|= tmp;
+ }
+ if (wire->preserve) {
+ pOld->preserve[n].real_mods= preWire[n].realMods;
+ pOld->preserve[n].vmods= preWire[n].virtualMods;
+ tmp= XkbMaskForVMask(xkb,preWire[n].virtualMods);
+ pOld->preserve[n].mask= preWire[n].realMods|tmp;
+ }
+ }
+ if (wire->preserve)
+ map= (CARD8 *)&preWire[wire->nMapEntries];
+ else map= (CARD8 *)&mapWire[wire->nMapEntries];
+ }
+ else map= (CARD8 *)&wire[1];
+ wire = (xkbKeyTypeWireDesc *)map;
+ }
+ first= req->firstType;
+ last= first+req->nTypes-1; /* last changed type */
+ if (changes->map.changed&XkbKeyTypesMask) {
+ int oldLast;
+ oldLast= changes->map.first_type+changes->map.num_types-1;
+ if (changes->map.first_type<first)
+ first= changes->map.first_type;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.changed|= XkbKeyTypesMask;
+ changes->map.first_type = first;
+ changes->map.num_types = (last-first)+1;
+ return (char *)wire;
+}
+
+static char *
+#if NeedFunctionPrototypes
+SetKeySyms( ClientPtr client,
+ XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ xkbSymMapWireDesc * wire,
+ XkbChangesPtr changes,
+ DeviceIntPtr dev)
+#else
+SetKeySyms(client,xkb,req,wire,changes,dev)
+ ClientPtr client;
+ XkbDescPtr xkb;
+ xkbSetMapReq * req;
+ xkbSymMapWireDesc * wire;
+ XkbChangesPtr changes;
+ DeviceIntPtr dev;
+#endif
+{
+register unsigned i,s;
+XkbSymMapPtr oldMap;
+KeySym * newSyms;
+KeySym * pSyms;
+unsigned first,last;
+
+ oldMap = &xkb->map->key_sym_map[req->firstKeySym];
+ for (i=0;i<req->nKeySyms;i++,oldMap++) {
+ pSyms = (KeySym *)&wire[1];
+ if (wire->nSyms>0) {
+ newSyms = XkbResizeKeySyms(xkb,i+req->firstKeySym,wire->nSyms);
+ for (s=0;s<wire->nSyms;s++) {
+ newSyms[s]= pSyms[s];
+ }
+ if (client->swapped) {
+ int n;
+ for (s=0;s<wire->nSyms;s++) {
+ swapl(&newSyms[s],n);
+ }
+ }
+ }
+ oldMap->kt_index[0] = wire->ktIndex[0];
+ oldMap->kt_index[1] = wire->ktIndex[1];
+ oldMap->kt_index[2] = wire->ktIndex[2];
+ oldMap->kt_index[3] = wire->ktIndex[3];
+ oldMap->group_info = wire->groupInfo;
+ oldMap->width = wire->width;
+ wire= (xkbSymMapWireDesc *)&pSyms[wire->nSyms];
+ }
+ first= req->firstKeySym;
+ last= first+req->nKeySyms-1;
+ if (changes->map.changed&XkbKeySymsMask) {
+ int oldLast= (changes->map.first_key_sym+changes->map.num_key_syms-1);
+ if (changes->map.first_key_sym<first)
+ first= changes->map.first_key_sym;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.changed|= XkbKeySymsMask;
+ changes->map.first_key_sym = first;
+ changes->map.num_key_syms = (last-first+1);
+
+ s= 0;
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ if (XkbKeyNumGroups(xkb,i)>s)
+ s= XkbKeyNumGroups(xkb,i);
+ }
+ if (s!=xkb->ctrls->num_groups) {
+ xkbControlsNotify cn;
+ XkbControlsRec old;
+ cn.keycode= 0;
+ cn.eventType= 0;
+ cn.requestMajor= XkbReqCode;
+ cn.requestMinor= X_kbSetMap;
+ old= *xkb->ctrls;
+ xkb->ctrls->num_groups= s;
+ if (XkbComputeControlsNotify(dev,&old,xkb->ctrls,&cn,False))
+ XkbSendControlsNotify(dev,&cn);
+ }
+ return (char *)wire;
+}
+
+static char *
+#if NeedFunctionPrototypes
+SetKeyActions( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ CARD8 * wire,
+ XkbChangesPtr changes)
+#else
+SetKeyActions(xkb,req,wire,changes)
+ XkbDescPtr xkb;
+ xkbSetMapReq * req;
+ CARD8 * wire;
+ XkbChangesPtr changes;
+#endif
+{
+register unsigned i,first,last;
+CARD8 * nActs = wire;
+XkbAction * newActs;
+
+ wire+= XkbPaddedSize(req->nKeyActs);
+ for (i=0;i<req->nKeyActs;i++) {
+ if (nActs[i]==0)
+ xkb->server->key_acts[i+req->firstKeyAct]= 0;
+ else {
+ newActs= XkbResizeKeyActions(xkb,i+req->firstKeyAct,nActs[i]);
+ memcpy((char *)newActs,(char *)wire,
+ nActs[i]*SIZEOF(xkbActionWireDesc));
+ wire+= nActs[i]*SIZEOF(xkbActionWireDesc);
+ }
+ }
+ first= req->firstKeyAct;
+ last= (first+req->nKeyActs-1);
+ if (changes->map.changed&XkbKeyActionsMask) {
+ int oldLast;
+ oldLast= changes->map.first_key_act+changes->map.num_key_acts-1;
+ if (changes->map.first_key_act<first)
+ first= changes->map.first_key_act;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.changed|= XkbKeyActionsMask;
+ changes->map.first_key_act= first;
+ changes->map.num_key_acts= (last-first+1);
+ return (char *)wire;
+}
+
+static char *
+#if NeedFunctionPrototypes
+SetKeyBehaviors( XkbSrvInfoPtr xkbi,
+ xkbSetMapReq *req,
+ xkbBehaviorWireDesc *wire,
+ XkbChangesPtr changes)
+#else
+SetKeyBehaviors(xkbi,req,wire,changes)
+ XkbSrvInfoPtr xkbi;
+ xkbSetMapReq * req;
+ xkbBehaviorWireDesc*wire;
+ XkbChangesPtr changes;
+#endif
+{
+register unsigned i;
+int maxRG = -1;
+XkbDescPtr xkb = xkbi->desc;
+XkbServerMapPtr server = xkb->server;
+unsigned first,last;
+
+ first= req->firstKeyBehavior;
+ last= req->firstKeyBehavior+req->nKeyBehaviors-1;
+ bzero(&server->behaviors[first],req->nKeyBehaviors*sizeof(XkbBehavior));
+ for (i=0;i<req->totalKeyBehaviors;i++) {
+ if ((server->behaviors[wire->key].type&XkbKB_Permanent)==0) {
+ server->behaviors[wire->key].type= wire->type;
+ server->behaviors[wire->key].data= wire->data;
+ if ((wire->type==XkbKB_RadioGroup)&&(((int)wire->data)>maxRG))
+ maxRG= wire->data;
+ }
+ wire++;
+ }
+
+ if (maxRG>(int)xkbi->nRadioGroups) {
+ int sz = (maxRG+1)*sizeof(XkbRadioGroupRec);
+ if (xkbi->radioGroups)
+ xkbi->radioGroups=(XkbRadioGroupPtr)_XkbRealloc(xkbi->radioGroups,sz);
+ else xkbi->radioGroups= (XkbRadioGroupPtr)_XkbCalloc(1, sz);
+ if (xkbi->radioGroups) {
+ if (xkbi->nRadioGroups)
+ bzero(&xkbi->radioGroups[xkbi->nRadioGroups],
+ (maxRG-xkbi->nRadioGroups)*sizeof(XkbRadioGroupRec));
+ xkbi->nRadioGroups= maxRG+1;
+ }
+ else xkbi->nRadioGroups= 0;
+ /* should compute members here */
+ }
+ if (changes->map.changed&XkbKeyBehaviorsMask) {
+ unsigned oldLast;
+ oldLast= changes->map.first_key_behavior+
+ changes->map.num_key_behaviors-1;
+ if (changes->map.first_key_behavior<req->firstKeyBehavior)
+ first= changes->map.first_key_behavior;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.changed|= XkbKeyBehaviorsMask;
+ changes->map.first_key_behavior = first;
+ changes->map.num_key_behaviors = (last-first+1);
+ return (char *)wire;
+}
+
+static char *
+#if NeedFunctionPrototypes
+SetVirtualMods(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire,
+ XkbChangesPtr changes)
+#else
+SetVirtualMods(xkbi,req,wire,changes)
+ XkbSrvInfoPtr xkbi;
+ xkbSetMapReq * req;
+ CARD8 * wire;
+ XkbChangesPtr changes;
+#endif
+{
+register int i,bit,nMods;
+XkbServerMapPtr srv = xkbi->desc->server;
+
+ if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0))
+ return (char *)wire;
+ for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (req->virtualMods&bit) {
+ if (srv->vmods[i]!=wire[nMods]) {
+ changes->map.changed|= XkbVirtualModsMask;
+ changes->map.vmods|= bit;
+ srv->vmods[i]= wire[nMods];
+ }
+ nMods++;
+ }
+ }
+ return (char *)(wire+XkbPaddedSize(nMods));
+}
+
+static char *
+#if NeedFunctionPrototypes
+SetKeyExplicit(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire,
+ XkbChangesPtr changes)
+#else
+SetKeyExplicit(xkbi,req,wire,changes)
+ XkbSrvInfoPtr xkbi;
+ xkbSetMapReq * req;
+ CARD8 * wire;
+ XkbChangesPtr changes;
+#endif
+{
+register unsigned i,first,last;
+XkbServerMapPtr xkb = xkbi->desc->server;
+CARD8 * start;
+
+ start= wire;
+ first= req->firstKeyExplicit;
+ last= req->firstKeyExplicit+req->nKeyExplicit-1;
+ bzero(&xkb->explicit[first],req->nKeyExplicit);
+ for (i=0;i<req->totalKeyExplicit;i++,wire+= 2) {
+ xkb->explicit[wire[0]]= wire[1];
+ }
+ if (first>0) {
+ if (changes->map.changed&XkbExplicitComponentsMask) {
+ int oldLast;
+ oldLast= changes->map.first_key_explicit+
+ changes->map.num_key_explicit-1;
+ if (changes->map.first_key_explicit<first)
+ first= changes->map.first_key_explicit;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.first_key_explicit= first;
+ changes->map.num_key_explicit= (last-first)+1;
+ }
+ wire+= XkbPaddedSize(wire-start)-(wire-start);
+ return (char *)wire;
+}
+
+static char *
+#if NeedFunctionPrototypes
+SetModifierMap( XkbSrvInfoPtr xkbi,
+ xkbSetMapReq * req,
+ CARD8 * wire,
+ XkbChangesPtr changes)
+#else
+SetModifierMap(xkbi,req,wire,changes)
+ XkbSrvInfoPtr xkbi;
+ xkbSetMapReq * req;
+ CARD8 * wire;
+ XkbChangesPtr changes;
+#endif
+{
+register unsigned i,first,last;
+XkbClientMapPtr xkb = xkbi->desc->map;
+CARD8 * start;
+
+ start= wire;
+ first= req->firstModMapKey;
+ last= req->firstModMapKey+req->nModMapKeys-1;
+ bzero(&xkb->modmap[first],req->nModMapKeys);
+ for (i=0;i<req->totalModMapKeys;i++,wire+= 2) {
+ xkb->modmap[wire[0]]= wire[1];
+ }
+ if (first>0) {
+ if (changes->map.changed&XkbModifierMapMask) {
+ int oldLast;
+ oldLast= changes->map.first_modmap_key+
+ changes->map.num_modmap_keys-1;
+ if (changes->map.first_modmap_key<first)
+ first= changes->map.first_modmap_key;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.first_modmap_key= first;
+ changes->map.num_modmap_keys= (last-first)+1;
+ }
+ wire+= XkbPaddedSize(wire-start)-(wire-start);
+ return (char *)wire;
+}
+
+static char *
+#if NeedFunctionPrototypes
+SetVirtualModMap( XkbSrvInfoPtr xkbi,
+ xkbSetMapReq * req,
+ xkbVModMapWireDesc * wire,
+ XkbChangesPtr changes)
+#else
+SetVirtualModMap(xkbi,req,wire,changes)
+ XkbSrvInfoPtr xkbi;
+ xkbSetMapReq * req;
+ xkbVModMapWireDesc *wire;
+ XkbChangesPtr changes;
+#endif
+{
+register unsigned i,first,last;
+XkbServerMapPtr srv = xkbi->desc->server;
+
+ first= req->firstVModMapKey;
+ last= req->firstVModMapKey+req->nVModMapKeys-1;
+ bzero(&srv->vmodmap[first],req->nVModMapKeys*sizeof(unsigned short));
+ for (i=0;i<req->totalVModMapKeys;i++,wire++) {
+ srv->vmodmap[wire->key]= wire->vmods;
+ }
+ if (first>0) {
+ if (changes->map.changed&XkbVirtualModMapMask) {
+ int oldLast;
+ oldLast= changes->map.first_vmodmap_key+
+ changes->map.num_vmodmap_keys-1;
+ if (changes->map.first_vmodmap_key<first)
+ first= changes->map.first_vmodmap_key;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.first_vmodmap_key= first;
+ changes->map.num_vmodmap_keys= (last-first)+1;
+ }
+ return (char *)wire;
+}
+
+int
+#if NeedFunctionPrototypes
+ProcXkbSetMap(ClientPtr client)
+#else
+ProcXkbSetMap(client)
+ ClientPtr client;
+#endif
+{
+ DeviceIntPtr dev;
+ XkbSrvInfoPtr xkbi;
+ XkbDescPtr xkb;
+ XkbChangesRec change;
+ XkbEventCauseRec cause;
+ int nTypes,nActions,error;
+ char * tmp;
+ CARD8 mapWidths[XkbMaxLegalKeyCode+1];
+ CARD16 symsPerKey[XkbMaxLegalKeyCode+1];
+ Bool sentNKN;
+
+ REQUEST(xkbSetMapReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_LEGAL(0x01,stuff->present,XkbAllMapComponentsMask);
+
+ XkbSetCauseXkbReq(&cause,X_kbSetMap,client);
+ xkbi= dev->key->xkbInfo;
+ xkb = xkbi->desc;
+
+ if ((xkb->min_key_code!=stuff->minKeyCode)||
+ (xkb->max_key_code!=stuff->maxKeyCode)) {
+ if (client->vMajor!=1) { /* pre 1.0 versions of Xlib have a bug */
+ stuff->minKeyCode= xkb->min_key_code;
+ stuff->maxKeyCode= xkb->max_key_code;
+ }
+ else {
+ if ((stuff->minKeyCode<XkbMinLegalKeyCode)||
+ (stuff->maxKeyCode>XkbMaxLegalKeyCode)) {
+ client->errorValue= _XkbErrCode3(2,stuff->minKeyCode,
+ stuff->maxKeyCode);
+ return BadValue;
+ }
+ if (stuff->minKeyCode>stuff->maxKeyCode) {
+ client->errorValue= _XkbErrCode3(3,stuff->minKeyCode,
+ stuff->maxKeyCode);
+ return BadMatch;
+ }
+ }
+ }
+
+ tmp = (char *)&stuff[1];
+ if ((stuff->present&XkbKeyTypesMask)&&
+ (!CheckKeyTypes(client,xkb,stuff,(xkbKeyTypeWireDesc **)&tmp,
+ &nTypes,mapWidths))) {
+ client->errorValue = nTypes;
+ return BadValue;
+ }
+ if ((stuff->present&XkbKeySymsMask)&&
+ (!CheckKeySyms(client,xkb,stuff,nTypes,mapWidths,symsPerKey,
+ (xkbSymMapWireDesc **)&tmp,&error))) {
+ client->errorValue = error;
+ return BadValue;
+ }
+
+ if ((stuff->present&XkbKeyActionsMask)&&
+ (!CheckKeyActions(xkb,stuff,nTypes,mapWidths,symsPerKey,
+ (CARD8 **)&tmp,&nActions))) {
+ client->errorValue = nActions;
+ return BadValue;
+ }
+
+ if ((stuff->present&XkbKeyBehaviorsMask)&&
+ (!CheckKeyBehaviors(xkb,stuff,(xkbBehaviorWireDesc**)&tmp,&error))) {
+ client->errorValue = error;
+ return BadValue;
+ }
+
+ if ((stuff->present&XkbVirtualModsMask)&&
+ (!CheckVirtualMods(xkb,stuff,(CARD8 **)&tmp,&error))) {
+ client->errorValue= error;
+ return BadValue;
+ }
+ if ((stuff->present&XkbExplicitComponentsMask)&&
+ (!CheckKeyExplicit(xkb,stuff,(CARD8 **)&tmp,&error))) {
+ client->errorValue= error;
+ return BadValue;
+ }
+ if ((stuff->present&XkbModifierMapMask)&&
+ (!CheckModifierMap(xkb,stuff,(CARD8 **)&tmp,&error))) {
+ client->errorValue= error;
+ return BadValue;
+ }
+ if ((stuff->present&XkbVirtualModMapMask)&&
+ (!CheckVirtualModMap(xkb,stuff,(xkbVModMapWireDesc **)&tmp,&error))) {
+ client->errorValue= error;
+ return BadValue;
+ }
+ if (((tmp-((char *)stuff))/4)!=stuff->length) {
+ ErrorF("Internal error! Bad length in XkbSetMap (after check)\n");
+ client->errorValue = tmp-((char *)&stuff[1]);
+ return BadLength;
+ }
+ bzero(&change,sizeof(change));
+ sentNKN= False;
+ if ((xkb->min_key_code!=stuff->minKeyCode)||
+ (xkb->max_key_code!=stuff->maxKeyCode)) {
+ Status status;
+ xkbNewKeyboardNotify nkn;
+ nkn.deviceID= nkn.oldDeviceID= dev->id;
+ nkn.oldMinKeyCode= xkb->min_key_code;
+ nkn.oldMaxKeyCode= xkb->max_key_code;
+ status= XkbChangeKeycodeRange(xkb,stuff->minKeyCode,stuff->maxKeyCode,
+ &change);
+ if (status!=Success)
+ return status;
+ nkn.minKeyCode= xkb->min_key_code;
+ nkn.maxKeyCode= xkb->max_key_code;
+ nkn.requestMajor= XkbReqCode;
+ nkn.requestMinor= X_kbSetMap;
+ nkn.changed= XkbNKN_KeycodesMask;
+ XkbSendNewKeyboardNotify(dev,&nkn);
+ sentNKN= True;
+ }
+ tmp = (char *)&stuff[1];
+ if (stuff->present&XkbKeyTypesMask) {
+ tmp = SetKeyTypes(xkb,stuff,(xkbKeyTypeWireDesc *)tmp,&change);
+ if (!tmp) goto allocFailure;
+ }
+ if (stuff->present&XkbKeySymsMask) {
+ tmp = SetKeySyms(client,xkb,stuff,(xkbSymMapWireDesc *)tmp,&change,dev);
+ if (!tmp) goto allocFailure;
+ }
+ if (stuff->present&XkbKeyActionsMask) {
+ tmp = SetKeyActions(xkb,stuff,(CARD8 *)tmp,&change);
+ if (!tmp) goto allocFailure;
+ }
+ if (stuff->present&XkbKeyBehaviorsMask) {
+ tmp= SetKeyBehaviors(xkbi,stuff,(xkbBehaviorWireDesc *)tmp,&change);
+ if (!tmp) goto allocFailure;
+ }
+ if (stuff->present&XkbVirtualModsMask)
+ tmp= SetVirtualMods(xkbi,stuff,(CARD8 *)tmp,&change);
+ if (stuff->present&XkbExplicitComponentsMask)
+ tmp= SetKeyExplicit(xkbi,stuff,(CARD8 *)tmp,&change);
+ if (stuff->present&XkbModifierMapMask)
+ tmp= SetModifierMap(xkbi,stuff,(CARD8 *)tmp,&change);
+ if (stuff->present&XkbVirtualModMapMask)
+ tmp= SetVirtualModMap(xkbi,stuff,(xkbVModMapWireDesc *)tmp,&change);
+ if (((tmp-((char *)stuff))/4)!=stuff->length) {
+ ErrorF("Internal error! Bad length in XkbSetMap (after set)\n");
+ client->errorValue = tmp-((char *)&stuff[1]);
+ return BadLength;
+ }
+ if (stuff->flags&XkbSetMapRecomputeActions) {
+ KeyCode first,last,firstMM,lastMM;
+ if (change.map.num_key_syms>0) {
+ first= change.map.first_key_sym;
+ last= first+change.map.num_key_syms-1;
+ }
+ else first= last= 0;
+ if (change.map.num_modmap_keys>0) {
+ firstMM= change.map.first_modmap_key;
+ lastMM= first+change.map.num_modmap_keys-1;
+ }
+ else firstMM= lastMM= 0;
+ if ((last>0) && (lastMM>0)) {
+ if (firstMM<first)
+ first= firstMM;
+ if (lastMM>last)
+ last= lastMM;
+ }
+ else if (lastMM>0) {
+ first= firstMM;
+ last= lastMM;
+ }
+ if (last>0) {
+ unsigned check= 0;
+ XkbUpdateActions(dev,first,(last-first+1),&change,&check,&cause);
+ if (check)
+ XkbCheckSecondaryEffects(xkbi,check,&change,&cause);
+ }
+ }
+ if (!sentNKN)
+ XkbSendNotification(dev,&change,&cause);
+
+ XkbUpdateCoreDescription(dev,False);
+ return client->noClientException;
+allocFailure:
+ return BadAlloc;
+}
+
+/***====================================================================***/
+
+static Status
+#if NeedFunctionPrototypes
+XkbComputeGetCompatMapReplySize( XkbCompatMapPtr compat,
+ xkbGetCompatMapReply * rep)
+#else
+XkbComputeGetCompatMapReplySize(compat,rep)
+ XkbCompatMapPtr compat;
+ xkbGetCompatMapReply * rep;
+#endif
+{
+unsigned size,nGroups;
+
+ nGroups= 0;
+ if (rep->groups!=0) {
+ register int i,bit;
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (rep->groups&bit)
+ nGroups++;
+ }
+ }
+ size= nGroups*SIZEOF(xkbModsWireDesc);
+ size+= (rep->nSI*SIZEOF(xkbSymInterpretWireDesc));
+ rep->length= size/4;
+ return Success;
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbSendCompatMap( ClientPtr client,
+ XkbCompatMapPtr compat,
+ xkbGetCompatMapReply * rep)
+#else
+XkbSendCompatMap(client,compat,rep)
+ ClientPtr client;
+ XkbCompatMapPtr compat;
+ xkbGetCompatMapReply * rep;
+#endif
+{
+char * data;
+int size;
+
+ size= rep->length*4;
+ if (size>0) {
+ data = (char *)ALLOCATE_LOCAL(size);
+ if (data) {
+ register unsigned i,bit;
+ xkbModsWireDesc * grp;
+ XkbSymInterpretPtr sym= &compat->sym_interpret[rep->firstSI];
+ xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data;
+ for (i=0;i<rep->nSI;i++,sym++,wire++) {
+ wire->sym= sym->sym;
+ wire->mods= sym->mods;
+ wire->match= sym->match;
+ wire->virtualMod= sym->virtual_mod;
+ wire->flags= sym->flags;
+ memcpy((char*)&wire->act,(char*)&sym->act,sz_xkbActionWireDesc);
+ if (client->swapped) {
+ register int n;
+ swapl(&wire->sym,n);
+ }
+ }
+ if (rep->groups) {
+ grp = (xkbModsWireDesc *)wire;
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (rep->groups&bit) {
+ grp->mask= compat->groups[i].mask;
+ grp->realMods= compat->groups[i].real_mods;
+ grp->virtualMods= compat->groups[i].vmods;
+ if (client->swapped) {
+ register int n;
+ swaps(&grp->virtualMods,n);
+ }
+ grp++;
+ }
+ }
+ wire= (xkbSymInterpretWireDesc*)grp;
+ }
+ }
+ else return BadAlloc;
+ }
+ else data= NULL;
+
+ if (client->swapped) {
+ register int n;
+ swaps(&rep->sequenceNumber,n);
+ swapl(&rep->length,n);
+ swaps(&rep->firstSI,n);
+ swaps(&rep->nSI,n);
+ swaps(&rep->nTotalSI,n);
+ }
+
+ WriteToClient(client, SIZEOF(xkbGetCompatMapReply), (char *)rep);
+ if (data) {
+ WriteToClient(client, size, data);
+ DEALLOCATE_LOCAL((char *)data);
+ }
+ return client->noClientException;
+}
+
+int
+#if NeedFunctionPrototypes
+ProcXkbGetCompatMap(ClientPtr client)
+#else
+ProcXkbGetCompatMap(client)
+ ClientPtr client;
+#endif
+{
+ xkbGetCompatMapReply rep;
+ DeviceIntPtr dev;
+ XkbDescPtr xkb;
+ XkbCompatMapPtr compat;
+
+ REQUEST(xkbGetCompatMapReq);
+ REQUEST_SIZE_MATCH(xkbGetCompatMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+
+ xkb = dev->key->xkbInfo->desc;
+ compat= xkb->compat;
+
+ rep.type = X_Reply;
+ rep.deviceID = dev->id;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.firstSI = stuff->firstSI;
+ rep.nSI = stuff->nSI;
+ if (stuff->getAllSI) {
+ rep.firstSI = 0;
+ rep.nSI = compat->num_si;
+ }
+ else if ((((unsigned)stuff->nSI)>0)&&
+ ((unsigned)(stuff->firstSI+stuff->nSI-1)>=compat->num_si)) {
+ client->errorValue = _XkbErrCode2(0x05,compat->num_si);
+ return BadValue;
+ }
+ rep.nTotalSI = compat->num_si;
+ rep.groups= stuff->groups;
+ XkbComputeGetCompatMapReplySize(compat,&rep);
+ return XkbSendCompatMap(client,compat,&rep);
+}
+
+int
+#if NeedFunctionPrototypes
+ProcXkbSetCompatMap(ClientPtr client)
+#else
+ProcXkbSetCompatMap(client)
+ ClientPtr client;
+#endif
+{
+ DeviceIntPtr dev;
+ XkbSrvInfoPtr xkbi;
+ XkbDescPtr xkb;
+ XkbCompatMapPtr compat;
+ char * data;
+ int nGroups;
+ register unsigned i,bit;
+
+ REQUEST(xkbSetCompatMapReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+
+ data = (char *)&stuff[1];
+ xkbi = dev->key->xkbInfo;
+ xkb= xkbi->desc;
+ compat= xkb->compat;
+ if ((stuff->nSI>0)||(stuff->truncateSI)) {
+ xkbSymInterpretWireDesc *wire;
+ if (stuff->firstSI>compat->num_si) {
+ client->errorValue = _XkbErrCode2(0x02,compat->num_si);
+ return BadValue;
+ }
+ wire= (xkbSymInterpretWireDesc *)data;
+ wire+= stuff->nSI;
+ data = (char *)wire;
+ }
+ nGroups= 0;
+ if (stuff->groups!=0) {
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if ( stuff->groups&bit )
+ nGroups++;
+ }
+ }
+ data+= nGroups*SIZEOF(xkbModsWireDesc);
+ if (((data-((char *)stuff))/4)!=stuff->length) {
+ return BadLength;
+ }
+ data = (char *)&stuff[1];
+ if (stuff->nSI>0) {
+ xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data;
+ XkbSymInterpretPtr sym;
+ if ((unsigned)(stuff->firstSI+stuff->nSI)>compat->num_si) {
+ compat->num_si= stuff->firstSI+stuff->nSI;
+ compat->sym_interpret= _XkbTypedRealloc(compat->sym_interpret,
+ compat->num_si,
+ XkbSymInterpretRec);
+ if (!compat->sym_interpret) {
+ compat->num_si= 0;
+ return BadAlloc;
+ }
+ }
+ else if (stuff->truncateSI) {
+ compat->num_si = stuff->firstSI+stuff->nSI;
+ }
+ sym = &compat->sym_interpret[stuff->firstSI];
+ for (i=0;i<stuff->nSI;i++,wire++,sym++) {
+ if (client->swapped) {
+ register int n;
+ swapl(&wire->sym,n);
+ }
+ sym->sym= wire->sym;
+ sym->mods= wire->mods;
+ sym->match= wire->match;
+ sym->flags= wire->flags;
+ sym->virtual_mod= wire->virtualMod;
+ memcpy((char *)&sym->act,(char *)&wire->act,
+ SIZEOF(xkbActionWireDesc));
+ }
+ data = (char *)wire;
+ }
+ else if (stuff->truncateSI) {
+ compat->num_si = stuff->firstSI;
+ }
+
+ if (stuff->groups!=0) {
+ register unsigned i,bit;
+ xkbModsWireDesc *wire = (xkbModsWireDesc *)data;
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (stuff->groups&bit) {
+ if (client->swapped) {
+ register int n;
+ swaps(&wire->virtualMods,n);
+ }
+ compat->groups[i].mask= wire->realMods;
+ compat->groups[i].real_mods= wire->realMods;
+ compat->groups[i].vmods= wire->virtualMods;
+ if (wire->virtualMods!=0) {
+ unsigned tmp;
+ tmp= XkbMaskForVMask(xkb,wire->virtualMods);
+ compat->groups[i].mask|= tmp;
+ }
+ data+= SIZEOF(xkbModsWireDesc);
+ wire= (xkbModsWireDesc *)data;
+ }
+ }
+ }
+ i= XkbPaddedSize((data-((char *)stuff)));
+ if ((i/4)!=stuff->length) {
+ ErrorF("Internal length error on read in ProcXkbSetCompatMap\n");
+ return BadLength;
+ }
+
+ if (dev->xkb_interest) {
+ xkbCompatMapNotify ev;
+ ev.deviceID = dev->id;
+ ev.changedGroups = stuff->groups;
+ ev.firstSI = stuff->firstSI;
+ ev.nSI = stuff->nSI;
+ ev.nTotalSI = compat->num_si;
+ XkbSendCompatMapNotify(dev,&ev);
+ }
+
+ if (stuff->recomputeActions) {
+ XkbChangesRec change;
+ unsigned check;
+ XkbEventCauseRec cause;
+
+ XkbSetCauseXkbReq(&cause,X_kbSetCompatMap,client);
+ bzero(&change,sizeof(XkbChangesRec));
+ XkbUpdateActions(dev,xkb->min_key_code,XkbNumKeys(xkb),&change,&check,
+ &cause);
+ if (check)
+ XkbCheckSecondaryEffects(xkbi,check,&change,&cause);
+ XkbUpdateCoreDescription(dev,False);
+ XkbSendNotification(dev,&change,&cause);
+ }
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+#if NeedFunctionPrototypes
+ProcXkbGetIndicatorState(ClientPtr client)
+#else
+ProcXkbGetIndicatorState(client)
+ ClientPtr client;
+#endif
+{
+ xkbGetIndicatorStateReply rep;
+ XkbSrvLedInfoPtr sli;
+ DeviceIntPtr dev;
+ register int i;
+
+ REQUEST(xkbGetIndicatorStateReq);
+ REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,
+ XkbXI_IndicatorStateMask);
+ if (!sli)
+ return BadAlloc;
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.deviceID = dev->id;
+ rep.state = sli->effectiveState;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber,i);
+ swapl(&rep.state,i);
+ }
+ WriteToClient(client, SIZEOF(xkbGetIndicatorStateReply), (char *)&rep);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+Status
+#if NeedFunctionPrototypes
+XkbComputeGetIndicatorMapReplySize(
+ XkbIndicatorPtr indicators,
+ xkbGetIndicatorMapReply *rep)
+#else
+XkbComputeGetIndicatorMapReplySize(indicators,rep)
+ XkbIndicatorPtr indicators;
+ xkbGetIndicatorMapReply *rep;
+#endif
+{
+register int i,bit;
+int nIndicators;
+
+ rep->realIndicators = indicators->phys_indicators;
+ for (i=nIndicators=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (rep->which&bit)
+ nIndicators++;
+ }
+ rep->length = (nIndicators*SIZEOF(xkbIndicatorMapWireDesc))/4;
+ return Success;
+}
+
+int
+#if NeedFunctionPrototypes
+XkbSendIndicatorMap( ClientPtr client,
+ XkbIndicatorPtr indicators,
+ xkbGetIndicatorMapReply * rep)
+#else
+XkbSendIndicatorMap(client,indicators,rep)
+ ClientPtr client;
+ XkbIndicatorPtr indicators;
+ xkbGetIndicatorMapReply * rep;
+#endif
+{
+int length;
+CARD8 * map;
+register int i;
+register unsigned bit;
+
+ length = rep->length*4;
+ if (length>0) {
+ CARD8 *to;
+ to= map= (CARD8 *)ALLOCATE_LOCAL(length);
+ if (map) {
+ xkbIndicatorMapWireDesc *wire = (xkbIndicatorMapWireDesc *)to;
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (rep->which&bit) {
+ wire->flags= indicators->maps[i].flags;
+ wire->whichGroups= indicators->maps[i].which_groups;
+ wire->groups= indicators->maps[i].groups;
+ wire->whichMods= indicators->maps[i].which_mods;
+ wire->mods= indicators->maps[i].mods.mask;
+ wire->realMods= indicators->maps[i].mods.real_mods;
+ wire->virtualMods= indicators->maps[i].mods.vmods;
+ wire->ctrls= indicators->maps[i].ctrls;
+ if (client->swapped) {
+ register int n;
+ swaps(&wire->virtualMods,n);
+ swapl(&wire->ctrls,n);
+ }
+ wire++;
+ }
+ }
+ to = (CARD8 *)wire;
+ if ((to-map)!=length) {
+ client->errorValue = _XkbErrCode2(0xff,length);
+ return BadLength;
+ }
+ }
+ else return BadAlloc;
+ }
+ else map = NULL;
+ if (client->swapped) {
+ swaps(&rep->sequenceNumber,i);
+ swapl(&rep->length,i);
+ swapl(&rep->which,i);
+ swapl(&rep->realIndicators,i);
+ }
+ WriteToClient(client, SIZEOF(xkbGetIndicatorMapReply), (char *)rep);
+ if (map) {
+ WriteToClient(client, length, (char *)map);
+ DEALLOCATE_LOCAL((char *)map);
+ }
+ return client->noClientException;
+}
+
+int
+#if NeedFunctionPrototypes
+ProcXkbGetIndicatorMap(ClientPtr client)
+#else
+ProcXkbGetIndicatorMap(client)
+ ClientPtr client;
+#endif
+{
+xkbGetIndicatorMapReply rep;
+DeviceIntPtr dev;
+XkbDescPtr xkb;
+XkbIndicatorPtr leds;
+
+ REQUEST(xkbGetIndicatorMapReq);
+ REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+
+ xkb= dev->key->xkbInfo->desc;
+ leds= xkb->indicators;
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.deviceID = dev->id;
+ rep.which = stuff->which;
+ XkbComputeGetIndicatorMapReplySize(leds,&rep);
+ return XkbSendIndicatorMap(client,leds,&rep);
+}
+
+int
+#if NeedFunctionPrototypes
+ProcXkbSetIndicatorMap(ClientPtr client)
+#else
+ProcXkbSetIndicatorMap(client)
+ ClientPtr client;
+#endif
+{
+ register int i,bit;
+ int nIndicators,why;
+ DeviceIntPtr dev;
+ XkbSrvInfoPtr xkbi;
+ xkbIndicatorMapWireDesc *from;
+ XkbSrvLedInfoPtr sli;
+ XkbEventCauseRec cause;
+
+ REQUEST(xkbSetIndicatorMapReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ dev = _XkbLookupKeyboard(stuff->deviceSpec,&why);
+ if (!dev) {
+ client->errorValue = _XkbErrCode2(why,stuff->deviceSpec);
+ return XkbKeyboardErrorCode;
+ }
+ xkbi= dev->key->xkbInfo;
+
+ if (stuff->which==0)
+ return client->noClientException;
+
+ for (nIndicators=i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (stuff->which&bit)
+ nIndicators++;
+ }
+ if (stuff->length!=((SIZEOF(xkbSetIndicatorMapReq)+
+ (nIndicators*SIZEOF(xkbIndicatorMapWireDesc)))/4)) {
+ return BadLength;
+ }
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,
+ XkbXI_IndicatorMapsMask);
+ if (!sli)
+ return BadAlloc;
+
+ from = (xkbIndicatorMapWireDesc *)&stuff[1];
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (stuff->which&bit) {
+ if (client->swapped) {
+ register int n;
+ swaps(&from->virtualMods,n);
+ swapl(&from->ctrls,n);
+ }
+ CHK_MASK_LEGAL(i,from->whichGroups,XkbIM_UseAnyGroup);
+ CHK_MASK_LEGAL(i,from->whichMods,XkbIM_UseAnyMods);
+ from++;
+ }
+ }
+
+ from = (xkbIndicatorMapWireDesc *)&stuff[1];
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (stuff->which&bit) {
+ sli->maps[i].flags = from->flags;
+ sli->maps[i].which_groups = from->whichGroups;
+ sli->maps[i].groups = from->groups;
+ sli->maps[i].which_mods = from->whichMods;
+ sli->maps[i].mods.mask = from->mods;
+ sli->maps[i].mods.real_mods = from->mods;
+ sli->maps[i].mods.vmods= from->virtualMods;
+ sli->maps[i].ctrls = from->ctrls;
+ if (from->virtualMods!=0) {
+ unsigned tmp;
+ tmp= XkbMaskForVMask(xkbi->desc,from->virtualMods);
+ sli->maps[i].mods.mask= from->mods|tmp;
+ }
+ from++;
+ }
+ }
+
+ XkbSetCauseXkbReq(&cause,X_kbSetIndicatorMap,client);
+ XkbApplyLedMapChanges(dev,sli,stuff->which,NULL,NULL,&cause);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+#if NeedFunctionPrototypes
+ProcXkbGetNamedIndicator(ClientPtr client)
+#else
+ProcXkbGetNamedIndicator(client)
+ ClientPtr client;
+#endif
+{
+ DeviceIntPtr dev;
+ xkbGetNamedIndicatorReply rep;
+ register int i;
+ XkbSrvLedInfoPtr sli;
+ XkbIndicatorMapPtr map;
+ Bool supported;
+
+ REQUEST(xkbGetNamedIndicatorReq);
+ REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_LED_DEVICE(dev,stuff->deviceSpec);
+ CHK_ATOM_ONLY(stuff->indicator);
+
+ sli= XkbFindSrvLedInfo(dev,stuff->ledClass,stuff->ledID,0);
+ if (!sli)
+ return BadAlloc;
+
+ supported= True;
+ if (XkbXIUnsupported&XkbXI_IndicatorsMask) {
+ if ((dev!=(DeviceIntPtr)LookupKeyboardDevice())||
+ ((sli->flags&XkbSLI_IsDefault)==0)) {
+ supported= False;
+ }
+ }
+
+ if (supported) {
+ i= 0;
+ map= NULL;
+ if ((sli->names)&&(sli->maps)) {
+ for (i=0;i<XkbNumIndicators;i++) {
+ if (stuff->indicator==sli->names[i]) {
+ map= &sli->maps[i];
+ break;
+ }
+ }
+ }
+ }
+
+ rep.type= X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.deviceID = dev->id;
+ rep.indicator= stuff->indicator;
+ if ((map!=NULL)&&(supported)) {
+ rep.found= True;
+ rep.on= ((sli->effectiveState&(1<<i))!=0);
+ rep.realIndicator= ((sli->physIndicators&(1<<i))!=0);
+ rep.ndx= i;
+ rep.flags= map->flags;
+ rep.whichGroups= map->which_groups;
+ rep.groups= map->groups;
+ rep.whichMods= map->which_mods;
+ rep.mods= map->mods.mask;
+ rep.realMods= map->mods.real_mods;
+ rep.virtualMods= map->mods.vmods;
+ rep.ctrls= map->ctrls;
+ rep.supported= True;
+ }
+ else {
+ rep.found= False;
+ rep.on= False;
+ rep.realIndicator= False;
+ rep.ndx= XkbNoIndicator;
+ rep.flags= 0;
+ rep.whichGroups= 0;
+ rep.groups= 0;
+ rep.whichMods= 0;
+ rep.mods= 0;
+ rep.realMods= 0;
+ rep.virtualMods= 0;
+ rep.ctrls= 0;
+ rep.supported= supported;
+ }
+ if ( client->swapped ) {
+ register int n;
+ swapl(&rep.length,n);
+ swaps(&rep.sequenceNumber,n);
+ swapl(&rep.indicator,n);
+ swaps(&rep.virtualMods,n);
+ swapl(&rep.ctrls,n);
+ }
+
+ WriteToClient(client,SIZEOF(xkbGetNamedIndicatorReply), (char *)&rep);
+ if (!supported) {
+ xkbExtensionDeviceNotify edev;
+
+ bzero(&edev,sizeof(xkbExtensionDeviceNotify));
+ edev.reason= XkbXI_UnsupportedFeatureMask;
+ edev.ledClass= stuff->ledClass;
+ edev.ledID= stuff->ledID;
+ edev.ledsDefined= sli->namesPresent|sli->mapsPresent;
+ edev.ledState= sli->effectiveState;
+ edev.firstBtn= 0;
+ edev.nBtns= 0;
+ edev.unsupported= XkbXIUnsupported&XkbXI_IndicatorsMask;
+ edev.supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported);
+ XkbSendExtensionDeviceNotify(dev,client,&edev);
+ }
+ return client->noClientException;
+}
+
+int
+#if NeedFunctionPrototypes
+ProcXkbSetNamedIndicator(ClientPtr client)
+#else
+ProcXkbSetNamedIndicator(client)
+ ClientPtr client;
+#endif
+{
+ DeviceIntPtr dev,kbd;
+ XkbIndicatorMapPtr map;
+ XkbSrvLedInfoPtr sli;
+ register int led;
+ unsigned extDevReason;
+ unsigned statec,namec,mapc;
+ XkbEventCauseRec cause;
+ xkbExtensionDeviceNotify ed;
+ XkbChangesRec changes;
+
+ REQUEST(xkbSetNamedIndicatorReq);
+ REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_LED_DEVICE(dev,stuff->deviceSpec);
+ CHK_ATOM_ONLY(stuff->indicator);
+ CHK_MASK_LEGAL(0x10,stuff->whichGroups,XkbIM_UseAnyGroup);
+ CHK_MASK_LEGAL(0x11,stuff->whichMods,XkbIM_UseAnyMods);
+
+ extDevReason= 0;
+
+ sli= XkbFindSrvLedInfo(dev,stuff->ledClass,stuff->ledID,
+ XkbXI_IndicatorsMask);
+ if (!sli)
+ return BadAlloc;
+
+ if (XkbXIUnsupported&XkbXI_IndicatorsMask) {
+ if ((dev!=(DeviceIntPtr)LookupKeyboardDevice())||
+ ((sli->flags&XkbSLI_IsDefault)==0)) {
+ bzero(&ed,sizeof(xkbExtensionDeviceNotify));
+ ed.reason= XkbXI_UnsupportedFeatureMask;
+ ed.ledClass= stuff->ledClass;
+ ed.ledID= stuff->ledID;
+ ed.ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed.ledState= sli->effectiveState;
+ ed.firstBtn= 0;
+ ed.nBtns= 0;
+ ed.unsupported= XkbXIUnsupported&XkbXI_IndicatorsMask;
+ ed.supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported);
+ XkbSendExtensionDeviceNotify(dev,client,&ed);
+ return client->noClientException;
+ }
+ }
+
+ statec= mapc= namec= 0;
+ map= NULL;
+ if (sli->names && sli->maps) {
+ for (led=0;(led<XkbNumIndicators)&&(map==NULL);led++) {
+ if (sli->names[led]==stuff->indicator) {
+ map= &sli->maps[led];
+ break;
+ }
+ }
+ }
+ if (map==NULL) {
+ if (!stuff->createMap)
+ return client->noClientException;
+ for (led=0,map=NULL;(led<XkbNumIndicators)&&(map==NULL);led++) {
+ if ((sli->names[led]==None)&&(!XkbIM_InUse(&sli->maps[led]))) {
+ map= &sli->maps[led];
+ sli->names[led]= stuff->indicator;
+ break;
+ }
+ }
+ if (map==NULL)
+ return client->noClientException;
+ namec|= (1<<led);
+ sli->namesPresent|= ((stuff->indicator!=None)?(1<<led):0);
+ extDevReason|= XkbXI_IndicatorNamesMask;
+ }
+
+ if (stuff->setMap) {
+ map->flags = stuff->flags;
+ map->which_groups = stuff->whichGroups;
+ map->groups = stuff->groups;
+ map->which_mods = stuff->whichMods;
+ map->mods.mask = stuff->realMods;
+ map->mods.real_mods = stuff->realMods;
+ map->mods.vmods= stuff->virtualMods;
+ map->ctrls = stuff->ctrls;
+ mapc|= (1<<led);
+ }
+ if ((stuff->setState)&&((map->flags&XkbIM_NoExplicit)==0)) {
+ if (stuff->on) sli->explicitState|= (1<<led);
+ else sli->explicitState&= ~(1<<led);
+ statec|= ((sli->effectiveState^sli->explicitState)&(1<<led));
+ }
+ bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
+ bzero((char *)&changes,sizeof(XkbChangesRec));
+ XkbSetCauseXkbReq(&cause,X_kbSetNamedIndicator,client);
+ if (namec)
+ XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause);
+ if (mapc)
+ XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause);
+ if (statec)
+ XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause);
+
+ kbd= dev;
+ if ((sli->flags&XkbSLI_HasOwnState)==0)
+ kbd= (DeviceIntPtr)LookupKeyboardDevice();
+ XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+static CARD32
+#if NeedFunctionPrototypes
+_XkbCountAtoms(Atom *atoms,int maxAtoms,int *count)
+#else
+_XkbCountAtoms(atoms,maxAtoms,count)
+ Atom *atoms;
+ int maxAtoms;
+ int *count;
+#endif
+{
+register unsigned int i,bit,nAtoms;
+register CARD32 atomsPresent;
+
+ for (i=nAtoms=atomsPresent=0,bit=1;i<maxAtoms;i++,bit<<=1) {
+ if (atoms[i]!=None) {
+ atomsPresent|= bit;
+ nAtoms++;
+ }
+ }
+ if (count)
+ *count= nAtoms;
+ return atomsPresent;
+}
+
+static char *
+#if NeedFunctionPrototypes
+_XkbWriteAtoms(char *wire,Atom *atoms,int maxAtoms,int swap)
+#else
+_XkbWriteAtoms(wire,atoms,maxAtoms,swap)
+ char *wire;
+ Atom *atoms;
+ int maxAtoms;
+ int swap;
+#endif
+{
+register unsigned int i;
+Atom *atm;
+
+ atm = (Atom *)wire;
+ for (i=0;i<maxAtoms;i++) {
+ if (atoms[i]!=None) {
+ *atm= atoms[i];
+ if (swap) {
+ register int n;
+ swapl(atm,n);
+ }
+ atm++;
+ }
+ }
+ return (char *)atm;
+}
+
+static Status
+#if NeedFunctionPrototypes
+XkbComputeGetNamesReplySize(XkbDescPtr xkb,xkbGetNamesReply *rep)
+#else
+XkbComputeGetNamesReplySize(xkb,rep)
+ XkbDescPtr xkb;
+ xkbGetNamesReply * rep;
+#endif
+{
+register unsigned which,length;
+register int i;
+
+ rep->minKeyCode= xkb->min_key_code;
+ rep->maxKeyCode= xkb->max_key_code;
+ which= rep->which;
+ length= 0;
+ if (xkb->names!=NULL) {
+ if (which&XkbKeycodesNameMask) length++;
+ if (which&XkbGeometryNameMask) length++;
+ if (which&XkbSymbolsNameMask) length++;
+ if (which&XkbPhysSymbolsNameMask) length++;
+ if (which&XkbTypesNameMask) length++;
+ if (which&XkbCompatNameMask) length++;
+ }
+ else which&= ~XkbComponentNamesMask;
+
+ if (xkb->map!=NULL) {
+ if (which&XkbKeyTypeNamesMask)
+ length+= xkb->map->num_types;
+ rep->nTypes= xkb->map->num_types;
+ if (which&XkbKTLevelNamesMask) {
+ XkbKeyTypePtr pType = xkb->map->types;
+ int nKTLevels = 0;
+
+ length+= XkbPaddedSize(xkb->map->num_types)/4;
+ for (i=0;i<xkb->map->num_types;i++,pType++) {
+ if (pType->level_names!=NULL)
+ nKTLevels+= pType->num_levels;
+ }
+ rep->nKTLevels= nKTLevels;
+ length+= nKTLevels;
+ }
+ }
+ else {
+ rep->nTypes= 0;
+ rep->nKTLevels= 0;
+ which&= ~(XkbKeyTypeNamesMask|XkbKTLevelNamesMask);
+ }
+
+ rep->minKeyCode= xkb->min_key_code;
+ rep->maxKeyCode= xkb->max_key_code;
+ rep->indicators= 0;
+ rep->virtualMods= 0;
+ rep->groupNames= 0;
+ if (xkb->names!=NULL) {
+ if (which&XkbIndicatorNamesMask) {
+ int nLeds;
+ rep->indicators=
+ _XkbCountAtoms(xkb->names->indicators,XkbNumIndicators,&nLeds);
+ length+= nLeds;
+ if (nLeds==0)
+ which&= ~XkbIndicatorNamesMask;
+ }
+
+ if (which&XkbVirtualModNamesMask) {
+ int nVMods;
+ rep->virtualMods=
+ _XkbCountAtoms(xkb->names->vmods,XkbNumVirtualMods,&nVMods);
+ length+= nVMods;
+ if (nVMods==0)
+ which&= ~XkbVirtualModNamesMask;
+ }
+
+ if (which&XkbGroupNamesMask) {
+ int nGroups;
+ rep->groupNames=
+ _XkbCountAtoms(xkb->names->groups,XkbNumKbdGroups,&nGroups);
+ length+= nGroups;
+ if (nGroups==0)
+ which&= ~XkbGroupNamesMask;
+ }
+
+ if ((which&XkbKeyNamesMask)&&(xkb->names->keys))
+ length+= rep->nKeys;
+ else which&= ~XkbKeyNamesMask;
+
+ if ((which&XkbKeyAliasesMask)&&
+ (xkb->names->key_aliases)&&(xkb->names->num_key_aliases>0)) {
+ rep->nKeyAliases= xkb->names->num_key_aliases;
+ length+= rep->nKeyAliases*2;
+ }
+ else {
+ which&= ~XkbKeyAliasesMask;
+ rep->nKeyAliases= 0;
+ }
+
+ if ((which&XkbRGNamesMask)&&(xkb->names->num_rg>0))
+ length+= xkb->names->num_rg;
+ else which&= ~XkbRGNamesMask;
+ }
+ else {
+ which&= ~(XkbIndicatorNamesMask|XkbVirtualModNamesMask);
+ which&= ~(XkbGroupNamesMask|XkbKeyNamesMask|XkbKeyAliasesMask);
+ which&= ~XkbRGNamesMask;
+ }
+
+ rep->length= length;
+ rep->which= which;
+ return Success;
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbSendNames(ClientPtr client,XkbDescPtr xkb,xkbGetNamesReply *rep)
+#else
+XkbSendNames(client,xkb,rep)
+ ClientPtr client;
+ XkbDescPtr xkb;
+ xkbGetNamesReply * rep;
+#endif
+{
+register unsigned i,length,which;
+char * start;
+char * desc;
+
+ length= rep->length*4;
+ which= rep->which;
+ if (client->swapped) {
+ register int n;
+ swaps(&rep->sequenceNumber,n);
+ swapl(&rep->length,n);
+ swapl(&rep->which,n);
+ swaps(&rep->virtualMods,n);
+ swapl(&rep->indicators,n);
+ }
+
+ start = desc = (char *)ALLOCATE_LOCAL(length);
+ if ( !start )
+ return BadAlloc;
+ if (which&XkbKeycodesNameMask) {
+ *((CARD32 *)desc)= xkb->names->keycodes;
+ if (client->swapped) {
+ register int n;
+ swapl(desc,n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbGeometryNameMask) {
+ *((CARD32 *)desc)= xkb->names->geometry;
+ if (client->swapped) {
+ register int n;
+ swapl(desc,n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbSymbolsNameMask) {
+ *((CARD32 *)desc)= xkb->names->symbols;
+ if (client->swapped) {
+ register int n;
+ swapl(desc,n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbPhysSymbolsNameMask) {
+ register CARD32 *atm= (CARD32 *)desc;
+ atm[0]= (CARD32)xkb->names->phys_symbols;
+ if (client->swapped) {
+ register int n;
+ swapl(&atm[0],n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbTypesNameMask) {
+ *((CARD32 *)desc)= (CARD32)xkb->names->types;
+ if (client->swapped) {
+ register int n;
+ swapl(desc,n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbCompatNameMask) {
+ *((CARD32 *)desc)= (CARD32)xkb->names->compat;
+ if (client->swapped) {
+ register int n;
+ swapl(desc,n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbKeyTypeNamesMask) {
+ register CARD32 *atm= (CARD32 *)desc;
+ register XkbKeyTypePtr type= xkb->map->types;
+
+ for (i=0;i<xkb->map->num_types;i++,atm++,type++) {
+ *atm= (CARD32)type->name;
+ if (client->swapped) {
+ register int n;
+ swapl(atm,n);
+ }
+ }
+ desc= (char *)atm;
+ }
+ if (which&XkbKTLevelNamesMask) {
+ XkbKeyTypePtr type = xkb->map->types;
+ register CARD32 *atm;
+ for (i=0;i<rep->nTypes;i++,type++) {
+ *desc++ = type->num_levels;
+ }
+ desc+= XkbPaddedSize(rep->nTypes)-rep->nTypes;
+
+ atm= (CARD32 *)desc;
+ type = xkb->map->types;
+ for (i=0;i<xkb->map->num_types;i++,type++) {
+ register unsigned l;
+ if (type->level_names) {
+ for (l=0;l<type->num_levels;l++,atm++) {
+ *atm= type->level_names[l];
+ if (client->swapped) {
+ register unsigned n;
+ swapl(atm,n);
+ }
+ }
+ desc+= type->num_levels*4;
+ }
+ }
+ }
+ if (which&XkbIndicatorNamesMask) {
+ desc= _XkbWriteAtoms(desc,xkb->names->indicators,XkbNumIndicators,
+ client->swapped);
+ }
+ if (which&XkbVirtualModNamesMask) {
+ desc= _XkbWriteAtoms(desc,xkb->names->vmods,XkbNumVirtualMods,
+ client->swapped);
+ }
+ if (which&XkbGroupNamesMask) {
+ desc= _XkbWriteAtoms(desc,xkb->names->groups,XkbNumKbdGroups,
+ client->swapped);
+ }
+ if (which&XkbKeyNamesMask) {
+ for (i=0;i<rep->nKeys;i++,desc+= sizeof(XkbKeyNameRec)) {
+ *((XkbKeyNamePtr)desc)= xkb->names->keys[i+rep->firstKey];
+ }
+ }
+ if (which&XkbKeyAliasesMask) {
+ XkbKeyAliasPtr pAl;
+ pAl= xkb->names->key_aliases;
+ for (i=0;i<rep->nKeyAliases;i++,pAl++,desc+=2*XkbKeyNameLength) {
+ *((XkbKeyAliasPtr)desc)= *pAl;
+ }
+ }
+ if ((which&XkbRGNamesMask)&&(rep->nRadioGroups>0)) {
+ register CARD32 *atm= (CARD32 *)desc;
+ for (i=0;i<rep->nRadioGroups;i++,atm++) {
+ *atm= (CARD32)xkb->names->radio_groups[i];
+ if (client->swapped) {
+ register unsigned n;
+ swapl(atm,n);
+ }
+ }
+ desc+= rep->nRadioGroups*4;
+ }
+ if ((desc-start)!=(length)) {
+ ErrorF("BOGUS LENGTH in write names, expected %d, got %d\n",
+ length, desc-start);
+ }
+ WriteToClient(client, SIZEOF(xkbGetNamesReply), (char *)rep);
+ WriteToClient(client, length, start);
+ DEALLOCATE_LOCAL((char *)start);
+ return client->noClientException;
+}
+
+int
+#if NeedFunctionPrototypes
+ProcXkbGetNames(ClientPtr client)
+#else
+ProcXkbGetNames(client)
+ ClientPtr client;
+#endif
+{
+ DeviceIntPtr dev;
+ XkbDescPtr xkb;
+ xkbGetNamesReply rep;
+
+ REQUEST(xkbGetNamesReq);
+ REQUEST_SIZE_MATCH(xkbGetNamesReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask);
+
+ xkb = dev->key->xkbInfo->desc;
+ rep.type= X_Reply;
+ rep.sequenceNumber= client->sequence;
+ rep.length = 0;
+ rep.deviceID = dev->id;
+ rep.which = stuff->which;
+ rep.nTypes = xkb->map->num_types;
+ rep.firstKey = xkb->min_key_code;
+ rep.nKeys = XkbNumKeys(xkb);
+ if (xkb->names!=NULL) {
+ rep.nKeyAliases= xkb->names->num_key_aliases;
+ rep.nRadioGroups = xkb->names->num_rg;
+ }
+ else {
+ rep.nKeyAliases= rep.nRadioGroups= 0;
+ }
+ XkbComputeGetNamesReplySize(xkb,&rep);
+ return XkbSendNames(client,xkb,&rep);
+}
+
+/***====================================================================***/
+
+static CARD32 *
+#if NeedFunctionPrototypes
+_XkbCheckAtoms(CARD32 *wire,int nAtoms,int swapped,Atom *pError)
+#else
+_XkbCheckAtoms(wire,nAtoms,swapped,pError)
+ CARD32 *wire;
+ int nAtoms;
+ int swapped;
+ Atom *pError;
+#endif
+{
+register int i;
+
+ for (i=0;i<nAtoms;i++,wire++) {
+ if (swapped) {
+ register int n;
+ swapl(wire,n);
+ }
+ if ((((Atom)*wire)!=None)&&(!ValidAtom((Atom)*wire))) {
+ *pError= ((Atom)*wire);
+ return NULL;
+ }
+ }
+ return wire;
+}
+
+static CARD32 *
+#if NeedFunctionPrototypes
+_XkbCheckMaskedAtoms(CARD32 *wire,int nAtoms,CARD32 present,int swapped,
+ Atom *pError)
+#else
+_XkbCheckMaskedAtoms(wire,nAtoms,present,swapped,pError)
+ CARD32 *wire;
+ int nAtoms;
+ CARD32 present;
+ int swapped;
+ Atom *pError;
+#endif
+{
+register unsigned i,bit;
+
+ for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) {
+ if ((present&bit)==0)
+ continue;
+ if (swapped) {
+ register int n;
+ swapl(wire,n);
+ }
+ if ((((Atom)*wire)!=None)&&(!ValidAtom(((Atom)*wire)))) {
+ *pError= (Atom)*wire;
+ return NULL;
+ }
+ wire++;
+ }
+ return wire;
+}
+
+static Atom *
+#if NeedFunctionPrototypes
+_XkbCopyMaskedAtoms( Atom *wire,
+ Atom *dest,
+ int nAtoms,
+ CARD32 present)
+#else
+_XkbCopyMaskedAtoms(wire,dest,nAtoms,present)
+ Atom *wire;
+ Atom *dest;
+ int nAtoms;
+ CARD32 present;
+#endif
+{
+register int i,bit;
+
+ for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) {
+ if ((present&bit)==0)
+ continue;
+ dest[i]= *wire++;
+ }
+ return wire;
+}
+
+static Bool
+#if NeedFunctionPrototypes
+_XkbCheckTypeName(Atom name,int typeNdx)
+#else
+_XkbCheckTypeName(name,typeNdx)
+ Atom name;
+ int typeNdx;
+#endif
+{
+char * str;
+
+ str= NameForAtom(name);
+ if ((strcmp(str,"ONE_LEVEL")==0)||(strcmp(str,"TWO_LEVEL")==0)||
+ (strcmp(str,"ALPHABETIC")==0)||(strcmp(str,"KEYPAD")==0))
+ return False;
+ return True;
+}
+
+int
+#if NeedFunctionPrototypes
+ProcXkbSetNames(ClientPtr client)
+#else
+ProcXkbSetNames(client)
+ ClientPtr client;
+#endif
+{
+ DeviceIntPtr dev;
+ XkbDescRec *xkb;
+ XkbNamesRec *names;
+ xkbNamesNotify nn;
+ CARD32 *tmp;
+ Atom bad;
+
+ REQUEST(xkbSetNamesReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetNamesReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask);
+
+ xkb = dev->key->xkbInfo->desc;
+ names = xkb->names;
+ tmp = (CARD32 *)&stuff[1];
+
+ if (stuff->which&XkbKeycodesNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbGeometryNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbSymbolsNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbPhysSymbolsNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbTypesNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbCompatNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbKeyTypeNamesMask) {
+ register int i;
+ CARD32 *old;
+ if ( stuff->nTypes<1 ) {
+ client->errorValue = _XkbErrCode2(0x02,stuff->nTypes);
+ return BadValue;
+ }
+ if ((unsigned)(stuff->firstType+stuff->nTypes-1)>=xkb->map->num_types) {
+ client->errorValue = _XkbErrCode4(0x03,stuff->firstType,
+ stuff->nTypes,
+ xkb->map->num_types);
+ return BadValue;
+ }
+ if (((unsigned)stuff->firstType)<=XkbLastRequiredType) {
+ client->errorValue = _XkbErrCode2(0x04,stuff->firstType);
+ return BadAccess;
+ }
+ old= tmp;
+ tmp= _XkbCheckAtoms(tmp,stuff->nTypes,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ for (i=0;i<stuff->nTypes;i++,old++) {
+ if (!_XkbCheckTypeName((Atom)*old,stuff->firstType+i))
+ client->errorValue= _XkbErrCode2(0x05,i);
+ }
+ }
+ if (stuff->which&XkbKTLevelNamesMask) {
+ register unsigned i;
+ XkbKeyTypePtr type;
+ CARD8 * width;
+ if ( stuff->nKTLevels<1 ) {
+ client->errorValue = _XkbErrCode2(0x05,stuff->nKTLevels);
+ return BadValue;
+ }
+ if ((unsigned)(stuff->firstKTLevel+stuff->nKTLevels-1)>=
+ xkb->map->num_types) {
+ client->errorValue = _XkbErrCode4(0x06,stuff->firstKTLevel,
+ stuff->nKTLevels,xkb->map->num_types);
+ return BadValue;
+ }
+ width = (CARD8 *)tmp;
+ tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels));
+ type = &xkb->map->types[stuff->firstKTLevel];
+ for (i=0;i<stuff->nKTLevels;i++,type++) {
+ if (width[i]==0)
+ continue;
+ else if (width[i]!=type->num_levels) {
+ client->errorValue= _XkbErrCode4(0x07,i+stuff->firstKTLevel,
+ type->num_levels,width[i]);
+ return BadMatch;
+ }
+ tmp= _XkbCheckAtoms(tmp,width[i],client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ }
+ }
+ if (stuff->which&XkbIndicatorNamesMask) {
+ if (stuff->indicators==0) {
+ client->errorValue= 0x08;
+ return BadMatch;
+ }
+ tmp= _XkbCheckMaskedAtoms(tmp,XkbNumIndicators,stuff->indicators,
+ client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbVirtualModNamesMask) {
+ if (stuff->virtualMods==0) {
+ client->errorValue= 0x09;
+ return BadMatch;
+ }
+ tmp= _XkbCheckMaskedAtoms(tmp,XkbNumVirtualMods,
+ (CARD32)stuff->virtualMods,
+ client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbGroupNamesMask) {
+ if (stuff->groupNames==0) {
+ client->errorValue= 0x0a;
+ return BadMatch;
+ }
+ tmp= _XkbCheckMaskedAtoms(tmp,XkbNumKbdGroups,
+ (CARD32)stuff->groupNames,
+ client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbKeyNamesMask) {
+ if (stuff->firstKey<(unsigned)xkb->min_key_code) {
+ client->errorValue= _XkbErrCode3(0x0b,xkb->min_key_code,
+ stuff->firstKey);
+ return BadValue;
+ }
+ if (((unsigned)(stuff->firstKey+stuff->nKeys-1)>xkb->max_key_code)||
+ (stuff->nKeys<1)) {
+ client->errorValue= _XkbErrCode4(0x0c,xkb->max_key_code,
+ stuff->firstKey,stuff->nKeys);
+ return BadValue;
+ }
+ tmp+= stuff->nKeys;
+ }
+ if ((stuff->which&XkbKeyAliasesMask)&&(stuff->nKeyAliases>0)) {
+ tmp+= stuff->nKeyAliases*2;
+ }
+ if (stuff->which&XkbRGNamesMask) {
+ if ( stuff->nRadioGroups<1 ) {
+ client->errorValue= _XkbErrCode2(0x0d,stuff->nRadioGroups);
+ return BadValue;
+ }
+ tmp= _XkbCheckAtoms(tmp,stuff->nRadioGroups,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ }
+ if ((tmp-((CARD32 *)stuff))!=stuff->length) {
+ client->errorValue = stuff->length;
+ return BadLength;
+ }
+ if (XkbAllocNames(xkb,stuff->which,stuff->nRadioGroups,
+ stuff->nKeyAliases)!=Success) {
+ return BadAlloc;
+ }
+
+ /* everything is okay -- update names */
+ bzero(&nn,sizeof(xkbNamesNotify));
+ nn.changed= stuff->which;
+ tmp = (CARD32 *)&stuff[1];
+ if (stuff->which&XkbKeycodesNameMask)
+ names->keycodes= *tmp++;
+ if (stuff->which&XkbGeometryNameMask)
+ names->geometry= *tmp++;
+ if (stuff->which&XkbSymbolsNameMask)
+ names->symbols= *tmp++;
+ if (stuff->which&XkbPhysSymbolsNameMask)
+ names->phys_symbols= *tmp++;
+ if (stuff->which&XkbTypesNameMask)
+ names->types= *tmp++;
+ if (stuff->which&XkbCompatNameMask)
+ names->compat= *tmp++;
+ if ((stuff->which&XkbKeyTypeNamesMask)&&(stuff->nTypes>0)) {
+ register unsigned i;
+ register XkbKeyTypePtr type;
+
+ type= &xkb->map->types[stuff->firstType];
+ for (i=0;i<stuff->nTypes;i++,type++) {
+ type->name= *tmp++;
+ }
+ nn.firstType= stuff->firstType;
+ nn.nTypes= stuff->nTypes;
+ }
+ if (stuff->which&XkbKTLevelNamesMask) {
+ register XkbKeyTypePtr type;
+ register unsigned i;
+ CARD8 *width;
+
+ width = (CARD8 *)tmp;
+ tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels));
+ type= &xkb->map->types[stuff->firstKTLevel];
+ for (i=0;i<stuff->nKTLevels;i++,type++) {
+ if (width[i]>0) {
+ if (type->level_names) {
+ register unsigned n;
+ for (n=0;n<width[i];n++) {
+ type->level_names[n]= tmp[n];
+ }
+ }
+ tmp+= width[i];
+ }
+ }
+ nn.firstLevelName= 0;
+ nn.nLevelNames= stuff->nTypes;
+ }
+ if (stuff->which&XkbIndicatorNamesMask) {
+ tmp= _XkbCopyMaskedAtoms(tmp,names->indicators,XkbNumIndicators,
+ stuff->indicators);
+ nn.changedIndicators= stuff->indicators;
+ }
+ if (stuff->which&XkbVirtualModNamesMask) {
+ tmp= _XkbCopyMaskedAtoms(tmp,names->vmods,XkbNumVirtualMods,
+ stuff->virtualMods);
+ nn.changedVirtualMods= stuff->virtualMods;
+ }
+ if (stuff->which&XkbGroupNamesMask) {
+ tmp= _XkbCopyMaskedAtoms(tmp,names->groups,XkbNumKbdGroups,
+ stuff->groupNames);
+ nn.changedVirtualMods= stuff->groupNames;
+ }
+ if (stuff->which&XkbKeyNamesMask) {
+ memcpy((char*)&names->keys[stuff->firstKey],(char *)tmp,
+ stuff->nKeys*XkbKeyNameLength);
+ tmp+= stuff->nKeys;
+ nn.firstKey= stuff->firstKey;
+ nn.nKeys= stuff->nKeys;
+ }
+ if (stuff->which&XkbKeyAliasesMask) {
+ if (stuff->nKeyAliases>0) {
+ register int na= stuff->nKeyAliases;
+ if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,na)!=Success)
+ return BadAlloc;
+ memcpy((char *)names->key_aliases,(char *)tmp,
+ stuff->nKeyAliases*sizeof(XkbKeyAliasRec));
+ tmp+= stuff->nKeyAliases*2;
+ }
+ else if (names->key_aliases!=NULL) {
+ _XkbFree(names->key_aliases);
+ names->key_aliases= NULL;
+ names->num_key_aliases= 0;
+ }
+ nn.nAliases= names->num_key_aliases;
+ }
+ if (stuff->which&XkbRGNamesMask) {
+ if (stuff->nRadioGroups>0) {
+ register unsigned i,nrg;
+ nrg= stuff->nRadioGroups;
+ if (XkbAllocNames(xkb,XkbRGNamesMask,nrg,0)!=Success)
+ return BadAlloc;
+
+ for (i=0;i<stuff->nRadioGroups;i++) {
+ names->radio_groups[i]= tmp[i];
+ }
+ tmp+= stuff->nRadioGroups;
+ }
+ else if (names->radio_groups) {
+ _XkbFree(names->radio_groups);
+ names->radio_groups= NULL;
+ names->num_rg= 0;
+ }
+ nn.nRadioGroups= names->num_rg;
+ }
+ if (nn.changed) {
+ Bool needExtEvent;
+ needExtEvent= (nn.changed&XkbIndicatorNamesMask)!=0;
+ XkbSendNamesNotify(dev,&nn);
+ if (needExtEvent) {
+ XkbSrvLedInfoPtr sli;
+ xkbExtensionDeviceNotify edev;
+ register int i;
+ register unsigned bit;
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,
+ XkbXI_IndicatorsMask);
+ sli->namesPresent= 0;
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (names->indicators[i]!=None)
+ sli->namesPresent|= bit;
+ }
+ bzero(&edev,sizeof(xkbExtensionDeviceNotify));
+ edev.reason= XkbXI_IndicatorNamesMask;
+ edev.ledClass= KbdFeedbackClass;
+ edev.ledID= dev->kbdfeed->ctrl.id;
+ edev.ledsDefined= sli->namesPresent|sli->mapsPresent;
+ edev.ledState= sli->effectiveState;
+ edev.firstBtn= 0;
+ edev.nBtns= 0;
+ edev.supported= XkbXI_AllFeaturesMask;
+ edev.unsupported= 0;
+ XkbSendExtensionDeviceNotify(dev,client,&edev);
+ }
+ }
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+#include "XKBgeom.h"
+
+#define XkbSizeCountedString(s) ((s)?((((2+strlen(s))+3)/4)*4):4)
+
+static char *
+#if NeedFunctionPrototypes
+XkbWriteCountedString(char *wire,char *str,Bool swap)
+#else
+XkbWriteCountedString(wire,str,swap)
+ char * wire;
+ char * str;
+ Bool swap;
+#endif
+{
+CARD16 len,*pLen;
+
+ len= (str?strlen(str):0);
+ pLen= (CARD16 *)wire;
+ *pLen= len;
+ if (swap) {
+ register int n;
+ swaps(pLen,n);
+ }
+ memcpy(&wire[2],str,len);
+ wire+= ((2+len+3)/4)*4;
+ return wire;
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbSizeGeomProperties(XkbGeometryPtr geom)
+#else
+XkbSizeGeomProperties(geom)
+ XkbGeometryPtr geom;
+#endif
+{
+register int i,size;
+XkbPropertyPtr prop;
+
+ for (size=i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
+ size+= XkbSizeCountedString(prop->name);
+ size+= XkbSizeCountedString(prop->value);
+ }
+ return size;
+}
+
+static char *
+#if NeedFunctionPrototypes
+XkbWriteGeomProperties(char *wire,XkbGeometryPtr geom,Bool swap)
+#else
+XkbWriteGeomProperties(wire,geom,swap)
+ char * wire;
+ XkbGeometryPtr geom;
+ Bool swap;
+#endif
+{
+register int i;
+register XkbPropertyPtr prop;
+
+ for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
+ wire= XkbWriteCountedString(wire,prop->name,swap);
+ wire= XkbWriteCountedString(wire,prop->value,swap);
+ }
+ return wire;
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbSizeGeomKeyAliases(XkbGeometryPtr geom)
+#else
+XkbSizeGeomKeyAliases(geom)
+ XkbGeometryPtr geom;
+#endif
+{
+ return geom->num_key_aliases*(2*XkbKeyNameLength);
+}
+
+static char *
+#if NeedFunctionPrototypes
+XkbWriteGeomKeyAliases(char *wire,XkbGeometryPtr geom,Bool swap)
+#else
+XkbWriteGeomKeyAliases(wire,geom,swap)
+ char * wire;
+ XkbGeometryPtr geom;
+ Bool swap;
+#endif
+{
+register int sz;
+
+ sz= geom->num_key_aliases*(XkbKeyNameLength*2);
+ if (sz>0) {
+ memcpy(wire,(char *)geom->key_aliases,sz);
+ wire+= sz;
+ }
+ return wire;
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbSizeGeomColors(XkbGeometryPtr geom)
+#else
+XkbSizeGeomColors(geom)
+ XkbGeometryPtr geom;
+#endif
+{
+register int i,size;
+register XkbColorPtr color;
+
+ for (i=size=0,color=geom->colors;i<geom->num_colors;i++,color++) {
+ size+= XkbSizeCountedString(color->spec);
+ }
+ return size;
+}
+
+static char *
+#if NeedFunctionPrototypes
+XkbWriteGeomColors(char *wire,XkbGeometryPtr geom,Bool swap)
+#else
+XkbWriteGeomColors(wire,geom,swap)
+ char * wire;
+ XkbGeometryPtr geom;
+ Bool swap;
+#endif
+{
+register int i;
+register XkbColorPtr color;
+
+ for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
+ wire= XkbWriteCountedString(wire,color->spec,swap);
+ }
+ return wire;
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbSizeGeomShapes(XkbGeometryPtr geom)
+#else
+XkbSizeGeomShapes(geom)
+ XkbGeometryPtr geom;
+#endif
+{
+register int i,size;
+register XkbShapePtr shape;
+
+ for (i=size=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
+ register int n;
+ register XkbOutlinePtr ol;
+ size+= SIZEOF(xkbShapeWireDesc);
+ for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) {
+ size+= SIZEOF(xkbOutlineWireDesc);
+ size+= ol->num_points*SIZEOF(xkbPointWireDesc);
+ }
+ }
+ return size;
+}
+
+static char *
+#if NeedFunctionPrototypes
+XkbWriteGeomShapes(char *wire,XkbGeometryPtr geom,Bool swap)
+#else
+XkbWriteGeomShapes(wire,geom,swap)
+ char * wire;
+ XkbGeometryPtr geom;
+ Bool swap;
+#endif
+{
+int i;
+XkbShapePtr shape;
+xkbShapeWireDesc * shapeWire;
+
+ for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
+ register int o;
+ XkbOutlinePtr ol;
+ xkbOutlineWireDesc * olWire;
+ shapeWire= (xkbShapeWireDesc *)wire;
+ shapeWire->name= shape->name;
+ shapeWire->nOutlines= shape->num_outlines;
+ if (shape->primary!=NULL)
+ shapeWire->primaryNdx= XkbOutlineIndex(shape,shape->primary);
+ else shapeWire->primaryNdx= XkbNoShape;
+ if (shape->approx!=NULL)
+ shapeWire->approxNdx= XkbOutlineIndex(shape,shape->approx);
+ else shapeWire->approxNdx= XkbNoShape;
+ if (swap) {
+ register int n;
+ swapl(&shapeWire->name,n);
+ }
+ wire= (char *)&shapeWire[1];
+ for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) {
+ register int p;
+ XkbPointPtr pt;
+ xkbPointWireDesc * ptWire;
+ olWire= (xkbOutlineWireDesc *)wire;
+ olWire->nPoints= ol->num_points;
+ olWire->cornerRadius= ol->corner_radius;
+ wire= (char *)&olWire[1];
+ ptWire= (xkbPointWireDesc *)wire;
+ for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) {
+ ptWire[p].x= pt->x;
+ ptWire[p].y= pt->y;
+ if (swap) {
+ register int n;
+ swaps(&ptWire[p].x,n);
+ swaps(&ptWire[p].y,n);
+ }
+ }
+ wire= (char *)&ptWire[ol->num_points];
+ }
+ }
+ return wire;
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbSizeGeomDoodads(int num_doodads,XkbDoodadPtr doodad)
+#else
+XkbSizeGeomDoodads(num_doodads,doodad)
+ int num_doodads;
+ XkbDoodadPtr doodad;
+#endif
+{
+register int i,size;
+
+ for (i=size=0;i<num_doodads;i++,doodad++) {
+ size+= SIZEOF(xkbAnyDoodadWireDesc);
+ if (doodad->any.type==XkbTextDoodad) {
+ size+= XkbSizeCountedString(doodad->text.text);
+ size+= XkbSizeCountedString(doodad->text.font);
+ }
+ else if (doodad->any.type==XkbLogoDoodad) {
+ size+= XkbSizeCountedString(doodad->logo.logo_name);
+ }
+ }
+ return size;
+}
+
+static char *
+#if NeedFunctionPrototypes
+XkbWriteGeomDoodads(char *wire,int num_doodads,XkbDoodadPtr doodad,Bool swap)
+#else
+XkbWriteGeomDoodads(wire,num_doodads,doodad,swap)
+ char * wire;
+ int num_doodads;
+ XkbDoodadPtr doodad;
+ Bool swap;
+#endif
+{
+register int i;
+xkbDoodadWireDesc * doodadWire;
+
+ for (i=0;i<num_doodads;i++,doodad++) {
+ doodadWire= (xkbDoodadWireDesc *)wire;
+ wire= (char *)&doodadWire[1];
+ bzero(doodadWire,SIZEOF(xkbDoodadWireDesc));
+ doodadWire->any.name= doodad->any.name;
+ doodadWire->any.type= doodad->any.type;
+ doodadWire->any.priority= doodad->any.priority;
+ doodadWire->any.top= doodad->any.top;
+ doodadWire->any.left= doodad->any.left;
+ if (swap) {
+ register int n;
+ swapl(&doodadWire->any.name,n);
+ swaps(&doodadWire->any.top,n);
+ swaps(&doodadWire->any.left,n);
+ }
+ switch (doodad->any.type) {
+ case XkbOutlineDoodad:
+ case XkbSolidDoodad:
+ doodadWire->shape.angle= doodad->shape.angle;
+ doodadWire->shape.colorNdx= doodad->shape.color_ndx;
+ doodadWire->shape.shapeNdx= doodad->shape.shape_ndx;
+ if (swap) {
+ register int n;
+ swaps(&doodadWire->shape.angle,n);
+ }
+ break;
+ case XkbTextDoodad:
+ doodadWire->text.angle= doodad->text.angle;
+ doodadWire->text.width= doodad->text.width;
+ doodadWire->text.height= doodad->text.height;
+ doodadWire->text.colorNdx= doodad->text.color_ndx;
+ if (swap) {
+ register int n;
+ swaps(&doodadWire->text.angle,n);
+ swaps(&doodadWire->text.width,n);
+ swaps(&doodadWire->text.height,n);
+ }
+ wire= XkbWriteCountedString(wire,doodad->text.text,swap);
+ wire= XkbWriteCountedString(wire,doodad->text.font,swap);
+ break;
+ case XkbIndicatorDoodad:
+ doodadWire->indicator.shapeNdx= doodad->indicator.shape_ndx;
+ doodadWire->indicator.onColorNdx=doodad->indicator.on_color_ndx;
+ doodadWire->indicator.offColorNdx=
+ doodad->indicator.off_color_ndx;
+ break;
+ case XkbLogoDoodad:
+ doodadWire->logo.angle= doodad->logo.angle;
+ doodadWire->logo.colorNdx= doodad->logo.color_ndx;
+ doodadWire->logo.shapeNdx= doodad->logo.shape_ndx;
+ wire= XkbWriteCountedString(wire,doodad->logo.logo_name,swap);
+ break;
+ default:
+ ErrorF("Unknown doodad type %d in XkbWriteGeomDoodads\n");
+ ErrorF("Ignored\n");
+ break;
+ }
+ }
+ return wire;
+}
+
+static char *
+#if NeedFunctionPrototypes
+XkbWriteGeomOverlay(char *wire,XkbOverlayPtr ol,Bool swap)
+#else
+XkbWriteGeomOverlay(wire,ol,swap)
+ char * wire;
+ XkbOverlayPtr ol;
+ Bool swap;
+#endif
+{
+register int r;
+XkbOverlayRowPtr row;
+xkbOverlayWireDesc * olWire;
+
+ olWire= (xkbOverlayWireDesc *)wire;
+ olWire->name= ol->name;
+ olWire->nRows= ol->num_rows;
+ if (swap) {
+ register int n;
+ swapl(&olWire->name,n);
+ }
+ wire= (char *)&olWire[1];
+ for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
+ unsigned int k;
+ XkbOverlayKeyPtr key;
+ xkbOverlayRowWireDesc * rowWire;
+ rowWire= (xkbOverlayRowWireDesc *)wire;
+ rowWire->rowUnder= row->row_under;
+ rowWire->nKeys= row->num_keys;
+ wire= (char *)&rowWire[1];
+ for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
+ xkbOverlayKeyWireDesc * keyWire;
+ keyWire= (xkbOverlayKeyWireDesc *)wire;
+ memcpy(keyWire->over,key->over.name,XkbKeyNameLength);
+ memcpy(keyWire->under,key->under.name,XkbKeyNameLength);
+ wire= (char *)&keyWire[1];
+ }
+ }
+ return wire;
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbSizeGeomSections(XkbGeometryPtr geom)
+#else
+XkbSizeGeomSections(geom)
+ XkbGeometryPtr geom;
+#endif
+{
+register int i,size;
+XkbSectionPtr section;
+
+ for (i=size=0,section=geom->sections;i<geom->num_sections;i++,section++) {
+ size+= SIZEOF(xkbSectionWireDesc);
+ if (section->rows) {
+ int r;
+ XkbRowPtr row;
+ for (r=0,row=section->rows;r<section->num_rows;row++,r++) {
+ size+= SIZEOF(xkbRowWireDesc);
+ size+= row->num_keys*SIZEOF(xkbKeyWireDesc);
+ }
+ }
+ if (section->doodads)
+ size+= XkbSizeGeomDoodads(section->num_doodads,section->doodads);
+ if (section->overlays) {
+ int o;
+ XkbOverlayPtr ol;
+ for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) {
+ int r;
+ XkbOverlayRowPtr row;
+ size+= SIZEOF(xkbOverlayWireDesc);
+ for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
+ size+= SIZEOF(xkbOverlayRowWireDesc);
+ size+= row->num_keys*SIZEOF(xkbOverlayKeyWireDesc);
+ }
+ }
+ }
+ }
+ return size;
+}
+
+static char *
+#if NeedFunctionPrototypes
+XkbWriteGeomSections(char *wire,XkbGeometryPtr geom,Bool swap)
+#else
+XkbWriteGeomSections(wire,geom,swap)
+ char * wire;
+ XkbGeometryPtr geom;
+ Bool swap;
+#endif
+{
+register int i;
+XkbSectionPtr section;
+xkbSectionWireDesc * sectionWire;
+
+ for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
+ sectionWire= (xkbSectionWireDesc *)wire;
+ sectionWire->name= section->name;
+ sectionWire->top= section->top;
+ sectionWire->left= section->left;
+ sectionWire->width= section->width;
+ sectionWire->height= section->height;
+ sectionWire->angle= section->angle;
+ sectionWire->priority= section->priority;
+ sectionWire->nRows= section->num_rows;
+ sectionWire->nDoodads= section->num_doodads;
+ sectionWire->nOverlays= section->num_overlays;
+ sectionWire->pad= 0;
+ if (swap) {
+ register int n;
+ swapl(&sectionWire->name,n);
+ swaps(&sectionWire->top,n);
+ swaps(&sectionWire->left,n);
+ swaps(&sectionWire->width,n);
+ swaps(&sectionWire->height,n);
+ swaps(&sectionWire->angle,n);
+ }
+ wire= (char *)&sectionWire[1];
+ if (section->rows) {
+ int r;
+ XkbRowPtr row;
+ xkbRowWireDesc * rowWire;
+ for (r=0,row=section->rows;r<section->num_rows;r++,row++) {
+ rowWire= (xkbRowWireDesc *)wire;
+ rowWire->top= row->top;
+ rowWire->left= row->left;
+ rowWire->nKeys= row->num_keys;
+ rowWire->vertical= row->vertical;
+ rowWire->pad= 0;
+ if (swap) {
+ register int n;
+ swaps(&rowWire->top,n);
+ swaps(&rowWire->left,n);
+ }
+ wire= (char *)&rowWire[1];
+ if (row->keys) {
+ int k;
+ XkbKeyPtr key;
+ xkbKeyWireDesc * keyWire;
+ keyWire= (xkbKeyWireDesc *)wire;
+ for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
+ memcpy(keyWire[k].name,key->name.name,XkbKeyNameLength);
+ keyWire[k].gap= key->gap;
+ keyWire[k].shapeNdx= key->shape_ndx;
+ keyWire[k].colorNdx= key->color_ndx;
+ if (swap) {
+ register int n;
+ swaps(&keyWire[k].gap,n);
+ }
+ }
+ wire= (char *)&keyWire[row->num_keys];
+ }
+ }
+ }
+ if (section->doodads) {
+ wire= XkbWriteGeomDoodads(wire,
+ section->num_doodads,section->doodads,
+ swap);
+ }
+ if (section->overlays) {
+ register int o;
+ for (o=0;o<section->num_overlays;o++) {
+ wire= XkbWriteGeomOverlay(wire,&section->overlays[o],swap);
+ }
+ }
+ }
+ return wire;
+}
+
+static Status
+#if NeedFunctionPrototypes
+XkbComputeGetGeometryReplySize( XkbGeometryPtr geom,
+ xkbGetGeometryReply * rep,
+ Atom name)
+#else
+XkbComputeGetGeometryReplySize(geom,rep,name)
+ XkbGeometryPtr geom;
+ xkbGetGeometryReply * rep;
+ Atom name;
+#endif
+{
+int len;
+
+ if (geom!=NULL) {
+ len= XkbSizeCountedString(geom->label_font);
+ len+= XkbSizeGeomProperties(geom);
+ len+= XkbSizeGeomColors(geom);
+ len+= XkbSizeGeomShapes(geom);
+ len+= XkbSizeGeomSections(geom);
+ len+= XkbSizeGeomDoodads(geom->num_doodads,geom->doodads);
+ len+= XkbSizeGeomKeyAliases(geom);
+ rep->length= len/4;
+ rep->found= True;
+ rep->name= geom->name;
+ rep->widthMM= geom->width_mm;
+ rep->heightMM= geom->height_mm;
+ rep->nProperties= geom->num_properties;
+ rep->nColors= geom->num_colors;
+ rep->nShapes= geom->num_shapes;
+ rep->nSections= geom->num_sections;
+ rep->nDoodads= geom->num_doodads;
+ rep->nKeyAliases= geom->num_key_aliases;
+ rep->baseColorNdx= XkbGeomColorIndex(geom,geom->base_color);
+ rep->labelColorNdx= XkbGeomColorIndex(geom,geom->label_color);
+ }
+ else {
+ rep->length= 0;
+ rep->found= False;
+ rep->name= name;
+ rep->widthMM= rep->heightMM= 0;
+ rep->nProperties= rep->nColors= rep->nShapes= 0;
+ rep->nSections= rep->nDoodads= 0;
+ rep->nKeyAliases= 0;
+ rep->labelColorNdx= rep->baseColorNdx= 0;
+ }
+ return Success;
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbSendGeometry( ClientPtr client,
+ XkbGeometryPtr geom,
+ xkbGetGeometryReply * rep,
+ Bool freeGeom)
+#else
+XkbSendGeometry(client,geom,rep,freeGeom)
+ ClientPtr client;
+ XkbGeometryPtr geom;
+ xkbGetGeometryReply *rep;
+ Bool freeGeom;
+#endif
+{
+ char *desc,*start;
+ int len;
+
+ if (geom!=NULL) {
+ len= rep->length*4;
+ start= desc= (char *)ALLOCATE_LOCAL(len);
+ if (!start)
+ return BadAlloc;
+ desc= XkbWriteCountedString(desc,geom->label_font,client->swapped);
+ if ( rep->nProperties>0 )
+ desc = XkbWriteGeomProperties(desc,geom,client->swapped);
+ if ( rep->nColors>0 )
+ desc = XkbWriteGeomColors(desc,geom,client->swapped);
+ if ( rep->nShapes>0 )
+ desc = XkbWriteGeomShapes(desc,geom,client->swapped);
+ if ( rep->nSections>0 )
+ desc = XkbWriteGeomSections(desc,geom,client->swapped);
+ if ( rep->nDoodads>0 )
+ desc = XkbWriteGeomDoodads(desc,geom->num_doodads,geom->doodads,
+ client->swapped);
+ if ( rep->nKeyAliases>0 )
+ desc = XkbWriteGeomKeyAliases(desc,geom,client->swapped);
+ if ((desc-start)!=(len)) {
+ ErrorF("BOGUS LENGTH in XkbSendGeometry, expected %d, got %d\n",
+ len, desc-start);
+ }
+ }
+ else {
+ len= 0;
+ start= NULL;
+ }
+ if (client->swapped) {
+ register int n;
+ swaps(&rep->sequenceNumber,n);
+ swapl(&rep->length,n);
+ swapl(&rep->name,n);
+ swaps(&rep->widthMM,n);
+ swaps(&rep->heightMM,n);
+ swaps(&rep->nProperties,n);
+ swaps(&rep->nColors,n);
+ swaps(&rep->nShapes,n);
+ swaps(&rep->nSections,n);
+ swaps(&rep->nDoodads,n);
+ swaps(&rep->nKeyAliases,n);
+ }
+ WriteToClient(client, SIZEOF(xkbGetGeometryReply), (char *)rep);
+ if (len>0)
+ WriteToClient(client, len, start);
+ if (start!=NULL)
+ DEALLOCATE_LOCAL((char *)start);
+ if (freeGeom)
+ XkbFreeGeometry(geom,XkbGeomAllMask,True);
+ return client->noClientException;
+}
+
+int
+#if NeedFunctionPrototypes
+ProcXkbGetGeometry(ClientPtr client)
+#else
+ProcXkbGetGeometry(client)
+ ClientPtr client;
+#endif
+{
+ DeviceIntPtr dev;
+ xkbGetGeometryReply rep;
+ XkbGeometryPtr geom;
+ Bool shouldFree;
+ Status status;
+
+ REQUEST(xkbGetGeometryReq);
+ REQUEST_SIZE_MATCH(xkbGetGeometryReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_ATOM_OR_NONE(stuff->name);
+
+ geom= XkbLookupNamedGeometry(dev,stuff->name,&shouldFree);
+ rep.type= X_Reply;
+ rep.deviceID= dev->id;
+ rep.sequenceNumber= client->sequence;
+ rep.length= 0;
+ status= XkbComputeGetGeometryReplySize(geom,&rep,stuff->name);
+ if (status!=Success)
+ return status;
+ else return XkbSendGeometry(client,geom,&rep,shouldFree);
+}
+
+/***====================================================================***/
+
+static char *
+#if NeedFunctionPrototypes
+_GetCountedString(char **wire_inout,Bool swap)
+#else
+_GetCountedString(wire_inout,swap)
+ char ** wire_inout;
+ Bool swap;
+#endif
+{
+char * wire,*str;
+CARD16 len,*plen;
+
+ wire= *wire_inout;
+ plen= (CARD16 *)wire;
+ if (swap) {
+ register int n;
+ swaps(plen,n);
+ }
+ len= *plen;
+ str= (char *)_XkbAlloc(len+1);
+ if (str) {
+ memcpy(str,&wire[2],len);
+ str[len]= '\0';
+ }
+ wire+= XkbPaddedSize(len+2);
+ *wire_inout= wire;
+ return str;
+}
+
+static Status
+#if NeedFunctionPrototypes
+_CheckSetDoodad( char ** wire_inout,
+ XkbGeometryPtr geom,
+ XkbSectionPtr section,
+ ClientPtr client)
+#else
+_CheckSetDoodad(wire_inout,geom,section,client)
+ char ** wire_inout;
+ XkbGeometryPtr geom;
+ XkbSectionPtr section;
+ ClientPtr client;
+#endif
+{
+char * wire;
+xkbDoodadWireDesc * dWire;
+XkbDoodadPtr doodad;
+
+ dWire= (xkbDoodadWireDesc *)(*wire_inout);
+ wire= (char *)&dWire[1];
+ if (client->swapped) {
+ register int n;
+ swapl(&dWire->any.name,n);
+ swaps(&dWire->any.top,n);
+ swaps(&dWire->any.left,n);
+ swaps(&dWire->any.angle,n);
+ }
+ CHK_ATOM_ONLY(dWire->any.name);
+ doodad= XkbAddGeomDoodad(geom,section,dWire->any.name);
+ if (!doodad)
+ return BadAlloc;
+ doodad->any.type= dWire->any.type;
+ doodad->any.priority= dWire->any.priority;
+ doodad->any.top= dWire->any.top;
+ doodad->any.left= dWire->any.left;
+ doodad->any.angle= dWire->any.angle;
+ switch (doodad->any.type) {
+ case XkbOutlineDoodad:
+ case XkbSolidDoodad:
+ if (dWire->shape.colorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x40,geom->num_colors,
+ dWire->shape.colorNdx);
+ return BadMatch;
+ }
+ if (dWire->shape.shapeNdx>=geom->num_shapes) {
+ client->errorValue= _XkbErrCode3(0x41,geom->num_shapes,
+ dWire->shape.shapeNdx);
+ return BadMatch;
+ }
+ doodad->shape.color_ndx= dWire->shape.colorNdx;
+ doodad->shape.shape_ndx= dWire->shape.shapeNdx;
+ break;
+ case XkbTextDoodad:
+ if (dWire->text.colorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x42,geom->num_colors,
+ dWire->text.colorNdx);
+ return BadMatch;
+ }
+ if (client->swapped) {
+ register int n;
+ swaps(&dWire->text.width,n);
+ swaps(&dWire->text.height,n);
+ }
+ doodad->text.width= dWire->text.width;
+ doodad->text.height= dWire->text.height;
+ doodad->text.color_ndx= dWire->text.colorNdx;
+ doodad->text.text= _GetCountedString(&wire,client->swapped);
+ doodad->text.font= _GetCountedString(&wire,client->swapped);
+ break;
+ case XkbIndicatorDoodad:
+ if (dWire->indicator.onColorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x43,geom->num_colors,
+ dWire->indicator.onColorNdx);
+ return BadMatch;
+ }
+ if (dWire->indicator.offColorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x44,geom->num_colors,
+ dWire->indicator.offColorNdx);
+ return BadMatch;
+ }
+ if (dWire->indicator.shapeNdx>=geom->num_shapes) {
+ client->errorValue= _XkbErrCode3(0x45,geom->num_shapes,
+ dWire->indicator.shapeNdx);
+ return BadMatch;
+ }
+ doodad->indicator.shape_ndx= dWire->indicator.shapeNdx;
+ doodad->indicator.on_color_ndx= dWire->indicator.onColorNdx;
+ doodad->indicator.off_color_ndx= dWire->indicator.offColorNdx;
+ break;
+ case XkbLogoDoodad:
+ if (dWire->logo.colorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x46,geom->num_colors,
+ dWire->logo.colorNdx);
+ return BadMatch;
+ }
+ if (dWire->logo.shapeNdx>=geom->num_shapes) {
+ client->errorValue= _XkbErrCode3(0x47,geom->num_shapes,
+ dWire->logo.shapeNdx);
+ return BadMatch;
+ }
+ doodad->logo.color_ndx= dWire->logo.colorNdx;
+ doodad->logo.shape_ndx= dWire->logo.shapeNdx;
+ doodad->logo.logo_name= _GetCountedString(&wire,client->swapped);
+ break;
+ default:
+ client->errorValue= _XkbErrCode2(0x4F,dWire->any.type);
+ return BadValue;
+ }
+ *wire_inout= wire;
+ return Success;
+}
+
+static Status
+#if NeedFunctionPrototypes
+_CheckSetOverlay( char ** wire_inout,
+ XkbGeometryPtr geom,
+ XkbSectionPtr section,
+ ClientPtr client)
+#else
+_CheckSetOverlay(wire_inout,geom,section,client)
+ char ** wire_inout;
+ XkbGeometryPtr geom;
+ XkbSectionPtr section;
+ ClientPtr client;
+#endif
+{
+register int r;
+char * wire;
+XkbOverlayPtr ol;
+xkbOverlayWireDesc * olWire;
+xkbOverlayRowWireDesc * rWire;
+
+ wire= *wire_inout;
+ olWire= (xkbOverlayWireDesc *)wire;
+ if (client->swapped) {
+ register int n;
+ swapl(&olWire->name,n);
+ }
+ CHK_ATOM_ONLY(olWire->name);
+ ol= XkbAddGeomOverlay(section,olWire->name,olWire->nRows);
+ rWire= (xkbOverlayRowWireDesc *)&olWire[1];
+ for (r=0;r<olWire->nRows;r++) {
+ register int k;
+ xkbOverlayKeyWireDesc * kWire;
+ XkbOverlayRowPtr row;
+
+ if (rWire->rowUnder>section->num_rows) {
+ client->errorValue= _XkbErrCode4(0x20,r,section->num_rows,
+ rWire->rowUnder);
+ return BadMatch;
+ }
+ row= XkbAddGeomOverlayRow(ol,rWire->rowUnder,rWire->nKeys);
+ kWire= (xkbOverlayKeyWireDesc *)&rWire[1];
+ for (k=0;k<rWire->nKeys;k++,kWire++) {
+ if (XkbAddGeomOverlayKey(ol,row,
+ (char *)kWire->over,(char *)kWire->under)==NULL) {
+ client->errorValue= _XkbErrCode3(0x21,r,k);
+ return BadMatch;
+ }
+ }
+ rWire= (xkbOverlayRowWireDesc *)kWire;
+ }
+ olWire= (xkbOverlayWireDesc *)rWire;
+ wire= (char *)olWire;
+ *wire_inout= wire;
+ return Success;
+}
+
+static Status
+#if NeedFunctionPrototypes
+_CheckSetSections( XkbGeometryPtr geom,
+ xkbSetGeometryReq * req,
+ char ** wire_inout,
+ ClientPtr client)
+#else
+_CheckSetSections(geom,req,wire_inout,client)
+ XkbGeometryPtr geom;
+ xkbSetGeometryReq * req;
+ char ** wire_inout;
+ ClientPtr client;
+#endif
+{
+Status status;
+register int s;
+char * wire;
+xkbSectionWireDesc * sWire;
+XkbSectionPtr section;
+
+ wire= *wire_inout;
+ if (req->nSections<1)
+ return Success;
+ sWire= (xkbSectionWireDesc *)wire;
+ for (s=0;s<req->nSections;s++) {
+ register int r;
+ xkbRowWireDesc * rWire;
+ if (client->swapped) {
+ register int n;
+ swapl(&sWire->name,n);
+ swaps(&sWire->top,n);
+ swaps(&sWire->left,n);
+ swaps(&sWire->width,n);
+ swaps(&sWire->height,n);
+ swaps(&sWire->angle,n);
+ }
+ CHK_ATOM_ONLY(sWire->name);
+ section= XkbAddGeomSection(geom,sWire->name,sWire->nRows,
+ sWire->nDoodads,sWire->nOverlays);
+ if (!section)
+ return BadAlloc;
+ section->priority= sWire->priority;
+ section->top= sWire->top;
+ section->left= sWire->left;
+ section->width= sWire->width;
+ section->height= sWire->height;
+ section->angle= sWire->angle;
+ rWire= (xkbRowWireDesc *)&sWire[1];
+ for (r=0;r<sWire->nRows;r++) {
+ register int k;
+ XkbRowPtr row;
+ xkbKeyWireDesc * kWire;
+ if (client->swapped) {
+ register int n;
+ swaps(&rWire->top,n);
+ swaps(&rWire->left,n);
+ }
+ row= XkbAddGeomRow(section,rWire->nKeys);
+ if (!row)
+ return BadAlloc;
+ row->top= rWire->top;
+ row->left= rWire->left;
+ row->vertical= rWire->vertical;
+ kWire= (xkbKeyWireDesc *)&rWire[1];
+ for (k=0;k<rWire->nKeys;k++) {
+ XkbKeyPtr key;
+ key= XkbAddGeomKey(row);
+ if (!key)
+ return BadAlloc;
+ memcpy(key->name.name,kWire[k].name,XkbKeyNameLength);
+ key->gap= kWire[k].gap;
+ key->shape_ndx= kWire[k].shapeNdx;
+ key->color_ndx= kWire[k].colorNdx;
+ if (key->shape_ndx>=geom->num_shapes) {
+ client->errorValue= _XkbErrCode3(0x10,key->shape_ndx,
+ geom->num_shapes);
+ return BadMatch;
+ }
+ if (key->color_ndx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x11,key->color_ndx,
+ geom->num_colors);
+ return BadMatch;
+ }
+ }
+ rWire= (xkbRowWireDesc *)&kWire[rWire->nKeys];
+ }
+ wire= (char *)rWire;
+ if (sWire->nDoodads>0) {
+ register int d;
+ for (d=0;d<sWire->nDoodads;d++) {
+ status=_CheckSetDoodad(&wire,geom,section,client);
+ if (status!=Success)
+ return status;
+ }
+ }
+ if (sWire->nOverlays>0) {
+ register int o;
+ for (o=0;o<sWire->nOverlays;o++) {
+ status= _CheckSetOverlay(&wire,geom,section,client);
+ if (status!=Success)
+ return status;
+ }
+ }
+ sWire= (xkbSectionWireDesc *)wire;
+ }
+ wire= (char *)sWire;
+ *wire_inout= wire;
+ return Success;
+}
+
+static Status
+#if NeedFunctionPrototypes
+_CheckSetShapes( XkbGeometryPtr geom,
+ xkbSetGeometryReq * req,
+ char ** wire_inout,
+ ClientPtr client)
+#else
+_CheckSetShapes(geom,req,wire_inout,client)
+ XkbGeometryPtr geom;
+ xkbSetGeometryReq * req;
+ char ** wire_inout;
+ ClientPtr client;
+#endif
+{
+register int i;
+char * wire;
+
+ wire= *wire_inout;
+ if (req->nShapes<1) {
+ client->errorValue= _XkbErrCode2(0x06,req->nShapes);
+ return BadValue;
+ }
+ else {
+ xkbShapeWireDesc * shapeWire;
+ XkbShapePtr shape;
+ register int o;
+ shapeWire= (xkbShapeWireDesc *)wire;
+ for (i=0;i<req->nShapes;i++) {
+ xkbOutlineWireDesc * olWire;
+ XkbOutlinePtr ol;
+ shape= XkbAddGeomShape(geom,shapeWire->name,shapeWire->nOutlines);
+ if (!shape)
+ return BadAlloc;
+ olWire= (xkbOutlineWireDesc *)(&shapeWire[1]);
+ for (o=0;o<shapeWire->nOutlines;o++) {
+ register int p;
+ XkbPointPtr pt;
+ xkbPointWireDesc * ptWire;
+
+ ol= XkbAddGeomOutline(shape,olWire->nPoints);
+ if (!ol)
+ return BadAlloc;
+ ol->corner_radius= olWire->cornerRadius;
+ ptWire= (xkbPointWireDesc *)&olWire[1];
+ for (p=0,pt=ol->points;p<olWire->nPoints;p++,pt++) {
+ pt->x= ptWire[p].x;
+ pt->y= ptWire[p].y;
+ if (client->swapped) {
+ register int n;
+ swaps(&pt->x,n);
+ swaps(&pt->y,n);
+ }
+ }
+ ol->num_points= olWire->nPoints;
+ olWire= (xkbOutlineWireDesc *)(&ptWire[olWire->nPoints]);
+ }
+ if (shapeWire->primaryNdx!=XkbNoShape)
+ shape->primary= &shape->outlines[shapeWire->primaryNdx];
+ if (shapeWire->approxNdx!=XkbNoShape)
+ shape->approx= &shape->outlines[shapeWire->approxNdx];
+ shapeWire= (xkbShapeWireDesc *)olWire;
+ }
+ wire= (char *)shapeWire;
+ }
+ if (geom->num_shapes!=req->nShapes) {
+ client->errorValue= _XkbErrCode3(0x07,geom->num_shapes,req->nShapes);
+ return BadMatch;
+ }
+
+ *wire_inout= wire;
+ return Success;
+}
+
+static Status
+#if NeedFunctionPrototypes
+_CheckSetGeom( XkbGeometryPtr geom,
+ xkbSetGeometryReq * req,
+ ClientPtr client)
+#else
+_CheckSetGeom(geom,req,client)
+ XkbGeometryPtr geom;
+ xkbSetGeometryReq * req;
+ ClientPtr client;
+#endif
+{
+register int i;
+Status status;
+char * wire;
+
+ wire= (char *)&req[1];
+ geom->label_font= _GetCountedString(&wire,client->swapped);
+
+ for (i=0;i<req->nProperties;i++) {
+ char *name,*val;
+ name= _GetCountedString(&wire,client->swapped);
+ val= _GetCountedString(&wire,client->swapped);
+ if ((!name)||(!val)||(XkbAddGeomProperty(geom,name,val)==NULL))
+ return BadAlloc;
+ }
+
+ if (req->nColors<2) {
+ client->errorValue= _XkbErrCode3(0x01,2,req->nColors);
+ return BadValue;
+ }
+ if (req->baseColorNdx>req->nColors) {
+ client->errorValue=_XkbErrCode3(0x03,req->nColors,req->baseColorNdx);
+ return BadMatch;
+ }
+ if (req->labelColorNdx>req->nColors) {
+ client->errorValue= _XkbErrCode3(0x03,req->nColors,req->labelColorNdx);
+ return BadMatch;
+ }
+ if (req->labelColorNdx==req->baseColorNdx) {
+ client->errorValue= _XkbErrCode3(0x04,req->baseColorNdx,
+ req->labelColorNdx);
+ return BadMatch;
+ }
+
+ for (i=0;i<req->nColors;i++) {
+ char *name;
+ name= _GetCountedString(&wire,client->swapped);
+ if ((!name)||(!XkbAddGeomColor(geom,name,geom->num_colors)))
+ return BadAlloc;
+ }
+ if (req->nColors!=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x05,req->nColors,geom->num_colors);
+ return BadMatch;
+ }
+ geom->label_color= &geom->colors[req->labelColorNdx];
+ geom->base_color= &geom->colors[req->baseColorNdx];
+
+ if ((status=_CheckSetShapes(geom,req,&wire,client))!=Success)
+ return status;
+
+ if ((status=_CheckSetSections(geom,req,&wire,client))!=Success)
+ return status;
+
+ for (i=0;i<req->nDoodads;i++) {
+ status=_CheckSetDoodad(&wire,geom,NULL,client);
+ if (status!=Success)
+ return status;
+ }
+
+ for (i=0;i<req->nKeyAliases;i++) {
+ if (XkbAddGeomKeyAlias(geom,&wire[XkbKeyNameLength],wire)==NULL)
+ return BadAlloc;
+ wire+= 2*XkbKeyNameLength;
+ }
+ return Success;
+}
+
+int
+#if NeedFunctionPrototypes
+ProcXkbSetGeometry(ClientPtr client)
+#else
+ProcXkbSetGeometry(client)
+ ClientPtr client;
+#endif
+{
+ DeviceIntPtr dev;
+ XkbGeometryPtr geom,old;
+ XkbGeometrySizesRec sizes;
+ Status status;
+ XkbDescPtr xkb;
+ Bool new_name;
+ xkbNewKeyboardNotify nkn;
+
+ REQUEST(xkbSetGeometryReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_ATOM_OR_NONE(stuff->name);
+
+ xkb= dev->key->xkbInfo->desc;
+ old= xkb->geom;
+ xkb->geom= NULL;
+
+ sizes.which= XkbGeomAllMask;
+ sizes.num_properties= stuff->nProperties;
+ sizes.num_colors= stuff->nColors;
+ sizes.num_shapes= stuff->nShapes;
+ sizes.num_sections= stuff->nSections;
+ sizes.num_doodads= stuff->nDoodads;
+ sizes.num_key_aliases= stuff->nKeyAliases;
+ if ((status= XkbAllocGeometry(xkb,&sizes))!=Success) {
+ xkb->geom= old;
+ return status;
+ }
+ geom= xkb->geom;
+ geom->name= stuff->name;
+ geom->width_mm= stuff->widthMM;
+ geom->height_mm= stuff->heightMM;
+ if ((status= _CheckSetGeom(geom,stuff,client))!=Success) {
+ XkbFreeGeometry(geom,XkbGeomAllMask,True);
+ xkb->geom= old;
+ return status;
+ }
+ new_name= (xkb->names->geometry!=geom->name);
+ xkb->names->geometry= geom->name;
+ if (old)
+ XkbFreeGeometry(old,XkbGeomAllMask,True);
+ if (new_name) {
+ xkbNamesNotify nn;
+ bzero(&nn,sizeof(xkbNamesNotify));
+ nn.changed= XkbGeometryNameMask;
+ XkbSendNamesNotify(dev,&nn);
+ }
+ nkn.deviceID= nkn.oldDeviceID= dev->id;
+ nkn.minKeyCode= nkn.oldMinKeyCode= xkb->min_key_code;
+ nkn.maxKeyCode= nkn.oldMaxKeyCode= xkb->max_key_code;
+ nkn.requestMajor= XkbReqCode;
+ nkn.requestMinor= X_kbSetGeometry;
+ nkn.changed= XkbNKN_GeometryMask;
+ XkbSendNewKeyboardNotify(dev,&nkn);
+ return Success;
+}
+
+/***====================================================================***/
+
+int
+#if NeedFunctionPrototypes
+ProcXkbPerClientFlags(ClientPtr client)
+#else
+ProcXkbPerClientFlags(client)
+ ClientPtr client;
+#endif
+{
+ DeviceIntPtr dev;
+ xkbPerClientFlagsReply rep;
+ XkbInterestPtr interest;
+
+ REQUEST(xkbPerClientFlagsReq);
+ REQUEST_SIZE_MATCH(xkbPerClientFlagsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_LEGAL(0x01,stuff->change,XkbPCF_AllFlagsMask);
+ CHK_MASK_MATCH(0x02,stuff->change,stuff->value);
+
+ interest = XkbFindClientResource((DevicePtr)dev,client);
+ rep.type= X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (stuff->change) {
+ client->xkbClientFlags&= ~stuff->change;
+ client->xkbClientFlags|= stuff->value;
+ }
+ if (stuff->change&XkbPCF_AutoResetControlsMask) {
+ Bool want;
+ want= stuff->value&XkbPCF_AutoResetControlsMask;
+ if (interest && !want) {
+ interest->autoCtrls= interest->autoCtrlValues= 0;
+ }
+ else if (want && (!interest)) {
+ XID id = FakeClientID(client->index);
+ AddResource(id,RT_XKBCLIENT,dev);
+ interest= XkbAddClientResource((DevicePtr)dev,client,id);
+ if (!interest)
+ return BadAlloc;
+ }
+ if (interest && want ) {
+ register unsigned affect;
+ affect= stuff->ctrlsToChange;
+
+ CHK_MASK_LEGAL(0x03,affect,XkbAllBooleanCtrlsMask);
+ CHK_MASK_MATCH(0x04,affect,stuff->autoCtrls);
+ CHK_MASK_MATCH(0x05,stuff->autoCtrls,stuff->autoCtrlValues);
+
+ interest->autoCtrls&= ~affect;
+ interest->autoCtrlValues&= ~affect;
+ interest->autoCtrls|= stuff->autoCtrls&affect;
+ interest->autoCtrlValues|= stuff->autoCtrlValues&affect;
+ }
+ }
+ rep.supported = XkbPCF_AllFlagsMask;
+ rep.value= client->xkbClientFlags&XkbPCF_AllFlagsMask;
+ if (interest) {
+ rep.autoCtrls= interest->autoCtrls;
+ rep.autoCtrlValues= interest->autoCtrlValues;
+ }
+ else {
+ rep.autoCtrls= rep.autoCtrlValues= 0;
+ }
+ if ( client->swapped ) {
+ register int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.supported,n);
+ swapl(&rep.value,n);
+ swapl(&rep.autoCtrls,n);
+ swapl(&rep.autoCtrlValues,n);
+ }
+ WriteToClient(client,SIZEOF(xkbPerClientFlagsReply), (char *)&rep);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+/* all latin-1 alphanumerics, plus parens, minus, underscore, slash */
+/* and wildcards */
+static unsigned char componentSpecLegal[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83,
+ 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
+};
+
+/* same as above but accepts percent, plus and bar too */
+static unsigned char componentExprLegal[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0xaf, 0xff, 0x83,
+ 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x17,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
+};
+
+static char *
+#if NeedFunctionPrototypes
+GetComponentSpec(unsigned char **pWire,Bool allowExpr,int *errRtrn)
+#else
+GetComponentSpec(pWire,allowExpr,errRtrn)
+ unsigned char ** pWire;
+ Bool allowExpr;
+ int * errRtrn;
+#endif
+{
+int len;
+register int i;
+unsigned char *wire,*str,*tmp,*legal;
+
+ if (allowExpr) legal= &componentExprLegal[0];
+ else legal= &componentSpecLegal[0];
+
+ wire= *pWire;
+ len= (*(unsigned char *)wire++);
+ if (len>0) {
+ str= (unsigned char *)_XkbCalloc(1, len+1);
+ if (str) {
+ tmp= str;
+ for (i=0;i<len;i++) {
+ if (legal[(*wire)/8]&(1<<((*wire)%8)))
+ *tmp++= *wire++;
+ else wire++;
+ }
+ if (tmp!=str)
+ *tmp++= '\0';
+ else {
+ _XkbFree(str);
+ str= NULL;
+ }
+ }
+ else {
+ *errRtrn= BadAlloc;
+ }
+ }
+ else {
+ str= NULL;
+ }
+ *pWire= wire;
+ return (char *)str;
+}
+
+/***====================================================================***/
+
+int
+#if NeedFunctionPrototypes
+ProcXkbListComponents(ClientPtr client)
+#else
+ProcXkbListComponents(client)
+ ClientPtr client;
+#endif
+{
+ DeviceIntPtr dev;
+ xkbListComponentsReply rep;
+ unsigned len;
+ int status;
+ unsigned char * str;
+ XkbSrvListInfoRec list;
+
+ REQUEST(xkbListComponentsReq);
+ REQUEST_AT_LEAST_SIZE(xkbListComponentsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+
+ status= Success;
+ str= (unsigned char *)&stuff[1];
+ bzero(&list,sizeof(XkbSrvListInfoRec));
+ list.maxRtrn= stuff->maxNames;
+ list.pattern[_XkbListKeymaps]= GetComponentSpec(&str,False,&status);
+ list.pattern[_XkbListKeycodes]= GetComponentSpec(&str,False,&status);
+ list.pattern[_XkbListTypes]= GetComponentSpec(&str,False,&status);
+ list.pattern[_XkbListCompat]= GetComponentSpec(&str,False,&status);
+ list.pattern[_XkbListSymbols]= GetComponentSpec(&str,False,&status);
+ list.pattern[_XkbListGeometry]= GetComponentSpec(&str,False,&status);
+ if (status!=Success)
+ return status;
+ len= str-((unsigned char *)stuff);
+ if ((XkbPaddedSize(len)/4)!=stuff->length)
+ return BadLength;
+ if ((status=XkbDDXList(dev,&list,client))!=Success) {
+ if (list.pool) {
+ _XkbFree(list.pool);
+ list.pool= NULL;
+ }
+ return status;
+ }
+ bzero(&rep,sizeof(xkbListComponentsReply));
+ rep.type= X_Reply;
+ rep.deviceID = dev->id;
+ rep.sequenceNumber = client->sequence;
+ rep.length = XkbPaddedSize(list.nPool)/4;
+ rep.nKeymaps = list.nFound[_XkbListKeymaps];
+ rep.nKeycodes = list.nFound[_XkbListKeycodes];
+ rep.nTypes = list.nFound[_XkbListTypes];
+ rep.nCompatMaps = list.nFound[_XkbListCompat];
+ rep.nSymbols = list.nFound[_XkbListSymbols];
+ rep.nGeometries = list.nFound[_XkbListGeometry];
+ rep.extra= 0;
+ if (list.nTotal>list.maxRtrn)
+ rep.extra = (list.nTotal-list.maxRtrn);
+ if (client->swapped) {
+ register int n;
+ swaps(&rep.sequenceNumber,n);
+ swapl(&rep.length,n);
+ swaps(&rep.nKeymaps,n);
+ swaps(&rep.nKeycodes,n);
+ swaps(&rep.nTypes,n);
+ swaps(&rep.nCompatMaps,n);
+ swaps(&rep.nSymbols,n);
+ swaps(&rep.nGeometries,n);
+ swaps(&rep.extra,n);
+ }
+ WriteToClient(client,SIZEOF(xkbListComponentsReply),(char *)&rep);
+ if (list.nPool && list.pool) {
+ WriteToClient(client,XkbPaddedSize(list.nPool), (char *)list.pool);
+ _XkbFree(list.pool);
+ list.pool= NULL;
+ }
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+#if NeedFunctionPrototypes
+ProcXkbGetKbdByName(ClientPtr client)
+#else
+ProcXkbGetKbdByName(client)
+ ClientPtr client;
+#endif
+{
+ DeviceIntPtr dev;
+ XkbFileInfo finfo;
+ xkbGetKbdByNameReply rep;
+ xkbGetMapReply mrep;
+ xkbGetCompatMapReply crep;
+ xkbGetIndicatorMapReply irep;
+ xkbGetNamesReply nrep;
+ xkbGetGeometryReply grep;
+ XkbComponentNamesRec names;
+ XkbDescPtr xkb;
+ unsigned char * str;
+ char mapFile[PATH_MAX];
+ unsigned len;
+ unsigned fwant,fneed,reported;
+ int status;
+ Bool geom_changed;
+
+ REQUEST(xkbGetKbdByNameReq);
+ REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev,stuff->deviceSpec);
+
+ xkb = dev->key->xkbInfo->desc;
+ status= Success;
+ str= (unsigned char *)&stuff[1];
+ names.keymap= GetComponentSpec(&str,True,&status);
+ names.keycodes= GetComponentSpec(&str,True,&status);
+ names.types= GetComponentSpec(&str,True,&status);
+ names.compat= GetComponentSpec(&str,True,&status);
+ names.symbols= GetComponentSpec(&str,True,&status);
+ names.geometry= GetComponentSpec(&str,True,&status);
+ if (status!=Success)
+ return status;
+ len= str-((unsigned char *)stuff);
+ if ((XkbPaddedSize(len)/4)!=stuff->length)
+ return BadLength;
+
+ CHK_MASK_LEGAL(0x01,stuff->want,XkbGBN_AllComponentsMask);
+ CHK_MASK_LEGAL(0x02,stuff->need,XkbGBN_AllComponentsMask);
+
+ if (stuff->load)
+ fwant= XkbGBN_AllComponentsMask;
+ else fwant= stuff->want|stuff->need;
+ if (!names.keymap) {
+ if ((!names.compat)&&
+ (fwant&(XkbGBN_CompatMapMask|XkbGBN_IndicatorMapMask))) {
+ names.compat= _XkbDupString("%");
+ }
+ if ((!names.types)&&(fwant&(XkbGBN_TypesMask))) {
+ names.types= _XkbDupString("%");
+ }
+ if ((!names.symbols)&&(fwant&XkbGBN_SymbolsMask)) {
+ names.symbols= _XkbDupString("%");
+ }
+ geom_changed= ((names.geometry!=NULL)&&(strcmp(names.geometry,"%")!=0));
+ if ((!names.geometry)&&(fwant&XkbGBN_GeometryMask)) {
+ names.geometry= _XkbDupString("%");
+ geom_changed= False;
+ }
+ }
+ else {
+ geom_changed= True;
+ }
+
+ bzero(mapFile,PATH_MAX);
+ rep.type= X_Reply;
+ rep.deviceID = dev->id;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.minKeyCode = xkb->min_key_code;
+ rep.maxKeyCode = xkb->max_key_code;
+ rep.loaded= False;
+ fwant= XkbConvertGetByNameComponents(True,stuff->want)|XkmVirtualModsMask;
+ fneed= XkbConvertGetByNameComponents(True,stuff->need);
+ rep.reported= XkbConvertGetByNameComponents(False,fwant|fneed);
+ if (stuff->load) {
+ fneed|= XkmKeymapRequired;
+ fwant|= XkmKeymapLegal;
+ }
+ if ((fwant|fneed)&XkmSymbolsMask) {
+ fneed|= XkmKeyNamesIndex|XkmTypesIndex;
+ fwant|= XkmIndicatorsIndex;
+ }
+ rep.found = XkbDDXLoadKeymapByNames(dev,&names,fwant,fneed,&finfo,
+ mapFile,PATH_MAX);
+ rep.newKeyboard= False;
+ rep.pad1= rep.pad2= rep.pad3= rep.pad4= 0;
+
+ stuff->want|= stuff->need;
+ if (finfo.xkb==NULL)
+ rep.reported= 0;
+ else {
+ if (stuff->load)
+ rep.loaded= True;
+ if (stuff->load ||
+ ((rep.reported&XkbGBN_SymbolsMask) && (finfo.xkb->compat))) {
+ XkbChangesRec changes;
+ bzero(&changes,sizeof(changes));
+ XkbUpdateDescActions(finfo.xkb,
+ finfo.xkb->min_key_code,XkbNumKeys(finfo.xkb),
+ &changes);
+ }
+
+ if (finfo.xkb->map==NULL)
+ rep.reported&= ~(XkbGBN_SymbolsMask|XkbGBN_TypesMask);
+ else if (rep.reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) {
+ mrep.type= X_Reply;
+ mrep.deviceID = dev->id;
+ mrep.sequenceNumber= client->sequence;
+ mrep.length = ((SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2);
+ mrep.minKeyCode = finfo.xkb->min_key_code;
+ mrep.maxKeyCode = finfo.xkb->max_key_code;
+ mrep.present = 0;
+ mrep.totalSyms = mrep.totalActs =
+ mrep.totalKeyBehaviors= mrep.totalKeyExplicit=
+ mrep.totalModMapKeys= 0;
+ if (rep.reported&(XkbGBN_TypesMask|XkbGBN_ClientSymbolsMask)) {
+ mrep.present|= XkbKeyTypesMask;
+ mrep.firstType = 0;
+ mrep.nTypes = mrep.totalTypes= finfo.xkb->map->num_types;
+ }
+ else {
+ mrep.firstType = mrep.nTypes= 0;
+ mrep.totalTypes= 0;
+ }
+ if (rep.reported&XkbGBN_ClientSymbolsMask) {
+ mrep.present|= (XkbKeySymsMask|XkbModifierMapMask);
+ mrep.firstKeySym = mrep.firstModMapKey= finfo.xkb->min_key_code;
+ mrep.nKeySyms = mrep.nModMapKeys= XkbNumKeys(finfo.xkb);
+ }
+ else {
+ mrep.firstKeySym= mrep.firstModMapKey= 0;
+ mrep.nKeySyms= mrep.nModMapKeys= 0;
+ }
+ if (rep.reported&XkbGBN_ServerSymbolsMask) {
+ mrep.present|= XkbAllServerInfoMask;
+ mrep.virtualMods= ~0;
+ mrep.firstKeyAct = mrep.firstKeyBehavior =
+ mrep.firstKeyExplicit = finfo.xkb->min_key_code;
+ mrep.nKeyActs = mrep.nKeyBehaviors =
+ mrep.nKeyExplicit = XkbNumKeys(finfo.xkb);
+ }
+ else {
+ mrep.virtualMods= 0;
+ mrep.firstKeyAct= mrep.firstKeyBehavior=
+ mrep.firstKeyExplicit = 0;
+ mrep.nKeyActs= mrep.nKeyBehaviors= mrep.nKeyExplicit= 0;
+ }
+ XkbComputeGetMapReplySize(finfo.xkb,&mrep);
+ rep.length+= SIZEOF(xGenericReply)/4+mrep.length;
+ }
+ if (finfo.xkb->compat==NULL)
+ rep.reported&= ~XkbGBN_CompatMapMask;
+ else if (rep.reported&XkbGBN_CompatMapMask) {
+ crep.type= X_Reply;
+ crep.deviceID= dev->id;
+ crep.sequenceNumber= client->sequence;
+ crep.length= 0;
+ crep.groups= XkbAllGroupsMask;
+ crep.firstSI= 0;
+ crep.nSI= crep.nTotalSI= finfo.xkb->compat->num_si;
+ XkbComputeGetCompatMapReplySize(finfo.xkb->compat,&crep);
+ rep.length+= SIZEOF(xGenericReply)/4+crep.length;
+ }
+ if (finfo.xkb->indicators==NULL)
+ rep.reported&= ~XkbGBN_IndicatorMapMask;
+ else if (rep.reported&XkbGBN_IndicatorMapMask) {
+ irep.type= X_Reply;
+ irep.deviceID= dev->id;
+ irep.sequenceNumber= client->sequence;
+ irep.length= 0;
+ irep.which= XkbAllIndicatorsMask;
+ XkbComputeGetIndicatorMapReplySize(finfo.xkb->indicators,&irep);
+ rep.length+= SIZEOF(xGenericReply)/4+irep.length;
+ }
+ if (finfo.xkb->names==NULL)
+ rep.reported&= ~(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask);
+ else if (rep.reported&(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask)) {
+ nrep.type= X_Reply;
+ nrep.deviceID= dev->id;
+ nrep.sequenceNumber= client->sequence;
+ nrep.length= 0;
+ nrep.minKeyCode= finfo.xkb->min_key_code;
+ nrep.maxKeyCode= finfo.xkb->max_key_code;
+ if (rep.reported&XkbGBN_OtherNamesMask) {
+ nrep.which= XkbAllNamesMask;
+ if (finfo.xkb->map!=NULL)
+ nrep.nTypes= finfo.xkb->map->num_types;
+ else nrep.nTypes= 0;
+ nrep.nKTLevels= 0;
+ nrep.groupNames= XkbAllGroupsMask;
+ nrep.virtualMods= XkbAllVirtualModsMask;
+ nrep.indicators= XkbAllIndicatorsMask;
+ nrep.nRadioGroups= finfo.xkb->names->num_rg;
+ }
+ else {
+ nrep.which= 0;
+ nrep.nTypes= 0;
+ nrep.nKTLevels= 0;
+ nrep.groupNames= 0;
+ nrep.virtualMods= 0;
+ nrep.indicators= 0;
+ nrep.nRadioGroups= 0;
+ }
+ if (rep.reported&XkbGBN_KeyNamesMask) {
+ nrep.which|= XkbKeyNamesMask;
+ nrep.firstKey= finfo.xkb->min_key_code;
+ nrep.nKeys= XkbNumKeys(finfo.xkb);
+ nrep.nKeyAliases= finfo.xkb->names->num_key_aliases;
+ if (nrep.nKeyAliases)
+ nrep.which|= XkbKeyAliasesMask;
+ }
+ else {
+ nrep.which&= ~(XkbKeyNamesMask|XkbKeyAliasesMask);
+ nrep.firstKey= nrep.nKeys= 0;
+ nrep.nKeyAliases= 0;
+ }
+ XkbComputeGetNamesReplySize(finfo.xkb,&nrep);
+ rep.length+= SIZEOF(xGenericReply)/4+nrep.length;
+ }
+ if (finfo.xkb->geom==NULL)
+ rep.reported&= ~XkbGBN_GeometryMask;
+ else if (rep.reported&XkbGBN_GeometryMask) {
+ grep.type= X_Reply;
+ grep.deviceID= dev->id;
+ grep.sequenceNumber= client->sequence;
+ grep.length= 0;
+ grep.found= True;
+ grep.pad= 0;
+ grep.widthMM= grep.heightMM= 0;
+ grep.nProperties= grep.nColors= grep.nShapes= 0;
+ grep.nSections= grep.nDoodads= 0;
+ grep.baseColorNdx= grep.labelColorNdx= 0;
+ XkbComputeGetGeometryReplySize(finfo.xkb->geom,&grep,None);
+ rep.length+= SIZEOF(xGenericReply)/4+grep.length;
+ }
+ }
+
+ reported= rep.reported;
+ if ( client->swapped ) {
+ register int n;
+ swaps(&rep.sequenceNumber,n);
+ swapl(&rep.length,n);
+ swaps(&rep.found,n);
+ swaps(&rep.reported,n);
+ }
+ WriteToClient(client,SIZEOF(xkbGetKbdByNameReply), (char *)&rep);
+ if (reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask))
+ XkbSendMap(client,finfo.xkb,&mrep);
+ if (reported&XkbGBN_CompatMapMask)
+ XkbSendCompatMap(client,finfo.xkb->compat,&crep);
+ if (reported&XkbGBN_IndicatorMapMask)
+ XkbSendIndicatorMap(client,finfo.xkb->indicators,&irep);
+ if (reported&(XkbGBN_KeyNamesMask|XkbGBN_OtherNamesMask))
+ XkbSendNames(client,finfo.xkb,&nrep);
+ if (reported&XkbGBN_GeometryMask)
+ XkbSendGeometry(client,finfo.xkb->geom,&grep,False);
+ if (rep.loaded) {
+ XkbDescPtr old_xkb;
+ xkbNewKeyboardNotify nkn;
+ int i,nG,nTG;
+ old_xkb= xkb;
+ xkb= finfo.xkb;
+ dev->key->xkbInfo->desc= xkb;
+ finfo.xkb= old_xkb; /* so it'll get freed automatically */
+
+ if (dev->kbdfeed && dev->kbdfeed->xkb_sli) {
+ XkbFreeSrvLedInfo(dev->kbdfeed->xkb_sli);
+ dev->kbdfeed->xkb_sli= NULL;
+ }
+ *xkb->ctrls= *old_xkb->ctrls;
+ for (nG=nTG=0,i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ nG= XkbKeyNumGroups(xkb,i);
+ if (nG>=XkbNumKbdGroups) {
+ nTG= XkbNumKbdGroups;
+ break;
+ }
+ if (nG>nTG) {
+ nTG= nG;
+ }
+ }
+ xkb->ctrls->num_groups= nTG;
+
+ memcpy(dev->key->modifierMap,xkb->map->modmap,xkb->max_key_code+1);
+ XkbUpdateCoreDescription(dev,True);
+
+ nkn.deviceID= nkn.oldDeviceID= dev->id;
+ nkn.minKeyCode= finfo.xkb->min_key_code;
+ nkn.maxKeyCode= finfo.xkb->max_key_code;
+ nkn.oldMinKeyCode= xkb->min_key_code;
+ nkn.oldMaxKeyCode= xkb->max_key_code;
+ nkn.requestMajor= XkbReqCode;
+ nkn.requestMinor= X_kbGetKbdByName;
+ nkn.changed= XkbNKN_KeycodesMask;
+ if (geom_changed)
+ nkn.changed|= XkbNKN_GeometryMask;
+ XkbSendNewKeyboardNotify(dev,&nkn);
+ }
+ if ((finfo.xkb!=NULL)&&(finfo.xkb!=xkb)) {
+ XkbFreeKeyboard(finfo.xkb,XkbAllComponentsMask,True);
+ finfo.xkb= NULL;
+ }
+ if (names.keymap) { _XkbFree(names.keymap); names.keymap= NULL; }
+ if (names.keycodes) { _XkbFree(names.keycodes); names.keycodes= NULL; }
+ if (names.types) { _XkbFree(names.types); names.types= NULL; }
+ if (names.compat) { _XkbFree(names.compat); names.compat= NULL; }
+ if (names.symbols) { _XkbFree(names.symbols); names.symbols= NULL; }
+ if (names.geometry) { _XkbFree(names.geometry); names.geometry= NULL; }
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+static int
+#if NeedFunctionPrototypes
+ComputeDeviceLedInfoSize( DeviceIntPtr dev,
+ unsigned int what,
+ XkbSrvLedInfoPtr sli)
+#else
+ComputeDeviceLedInfoSize(dev,what,sli)
+ DeviceIntPtr dev;
+ unsigned int what;
+ XkbSrvLedInfoPtr sli;
+#endif
+{
+int nNames,nMaps;
+register unsigned n,bit;
+
+ if (sli==NULL)
+ return 0;
+ nNames= nMaps= 0;
+ if ((what&XkbXI_IndicatorNamesMask)==0)
+ sli->namesPresent= 0;
+ if ((what&XkbXI_IndicatorMapsMask)==0)
+ sli->mapsPresent= 0;
+
+ for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
+ if (sli->names && sli->names[n]!=None) {
+ sli->namesPresent|= bit;
+ nNames++;
+ }
+ if (sli->maps && XkbIM_InUse(&sli->maps[n])) {
+ sli->mapsPresent|= bit;
+ nMaps++;
+ }
+ }
+ return (nNames*4)+(nMaps*SIZEOF(xkbIndicatorMapWireDesc));
+}
+
+static int
+#if NeedFunctionPrototypes
+CheckDeviceLedFBs( DeviceIntPtr dev,
+ int class,
+ int id,
+ xkbGetDeviceInfoReply * rep,
+ ClientPtr client)
+#else
+CheckDeviceLedFBs(dev,class,id,rep,client)
+ DeviceIntPtr dev;
+ int class;
+ int id;
+ xkbGetDeviceInfoReply * rep;
+ ClientPtr client;
+#endif
+{
+int nFBs= 0;
+int length= 0;
+Bool classOk;
+
+ if (class==XkbDfltXIClass) {
+ if (dev->kbdfeed) class= KbdFeedbackClass;
+ else if (dev->leds) class= LedFeedbackClass;
+ else {
+ client->errorValue= _XkbErrCode2(XkbErr_BadClass,class);
+ return XkbKeyboardErrorCode;
+ }
+ }
+ classOk= False;
+ if ((dev->kbdfeed)&&((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) {
+ KbdFeedbackPtr kf;
+ classOk= True;
+ for (kf= dev->kbdfeed;(kf);kf=kf->next) {
+ if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=kf->ctrl.id))
+ continue;
+ nFBs++;
+ length+= SIZEOF(xkbDeviceLedsWireDesc);
+ if (!kf->xkb_sli)
+ kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,0);
+ length+= ComputeDeviceLedInfoSize(dev,rep->present,kf->xkb_sli);
+ if (id!=XkbAllXIIds)
+ break;
+ }
+ }
+ if ((dev->leds)&&((class==LedFeedbackClass)||(class==XkbAllXIClasses))) {
+ LedFeedbackPtr lf;
+ classOk= True;
+ for (lf= dev->leds;(lf);lf=lf->next) {
+ if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=lf->ctrl.id))
+ continue;
+ nFBs++;
+ length+= SIZEOF(xkbDeviceLedsWireDesc);
+ if (!lf->xkb_sli)
+ lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,0);
+ length+= ComputeDeviceLedInfoSize(dev,rep->present,lf->xkb_sli);
+ if (id!=XkbAllXIIds)
+ break;
+ }
+ }
+ if (nFBs>0) {
+ if (rep->supported&XkbXI_IndicatorsMask) {
+ rep->nDeviceLedFBs= nFBs;
+ rep->length+= (length/4);
+ }
+ return Success;
+ }
+ if (classOk) client->errorValue= _XkbErrCode2(XkbErr_BadId,id);
+ else client->errorValue= _XkbErrCode2(XkbErr_BadClass,class);
+ return XkbKeyboardErrorCode;
+}
+
+static int
+#if NeedFunctionPrototypes
+SendDeviceLedInfo( XkbSrvLedInfoPtr sli,
+ ClientPtr client)
+#else
+SendDeviceLedInfo(sli,client)
+ XkbSrvLedInfoPtr sli;
+ ClientPtr client;
+#endif
+{
+xkbDeviceLedsWireDesc wire;
+int length;
+
+ length= 0;
+ wire.ledClass= sli->class;
+ wire.ledID= sli->id;
+ wire.namesPresent= sli->namesPresent;
+ wire.mapsPresent= sli->mapsPresent;
+ wire.physIndicators= sli->physIndicators;
+ wire.state= sli->effectiveState;
+ if (client->swapped) {
+ register int n;
+ swaps(&wire.ledClass,n);
+ swaps(&wire.ledID,n);
+ swapl(&wire.namesPresent,n);
+ swapl(&wire.mapsPresent,n);
+ swapl(&wire.physIndicators,n);
+ swapl(&wire.state,n);
+ }
+ WriteToClient(client,SIZEOF(xkbDeviceLedsWireDesc),(char *)&wire);
+ length+= SIZEOF(xkbDeviceLedsWireDesc);
+ if (sli->namesPresent|sli->mapsPresent) {
+ register unsigned i,bit;
+ if (sli->namesPresent) {
+ CARD32 awire;
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (sli->namesPresent&bit) {
+ awire= (CARD32)sli->names[i];
+ if (client->swapped) {
+ register int n;
+ swapl(&awire,n);
+ }
+ WriteToClient(client,4,(char *)&awire);
+ length+= 4;
+ }
+ }
+ }
+ if (sli->mapsPresent) {
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ xkbIndicatorMapWireDesc iwire;
+ if (sli->mapsPresent&bit) {
+ iwire.flags= sli->maps[i].flags;
+ iwire.whichGroups= sli->maps[i].which_groups;
+ iwire.groups= sli->maps[i].groups;
+ iwire.whichMods= sli->maps[i].which_mods;
+ iwire.mods= sli->maps[i].mods.mask;
+ iwire.realMods= sli->maps[i].mods.real_mods;
+ iwire.virtualMods= sli->maps[i].mods.vmods;
+ iwire.ctrls= sli->maps[i].ctrls;
+ if (client->swapped) {
+ register int n;
+ swaps(&iwire.virtualMods,n);
+ swapl(&iwire.ctrls,n);
+ }
+ WriteToClient(client,SIZEOF(xkbIndicatorMapWireDesc),
+ (char *)&iwire);
+ length+= SIZEOF(xkbIndicatorMapWireDesc);
+ }
+ }
+ }
+ }
+ return length;
+}
+
+static int
+#if NeedFunctionPrototypes
+SendDeviceLedFBs( DeviceIntPtr dev,
+ int class,
+ int id,
+ unsigned wantLength,
+ ClientPtr client)
+#else
+SendDeviceLedFBs(dev,class,id,wantLength,client)
+ DeviceIntPtr dev;
+ int class;
+ int id;
+ unsigned wantLength;
+ ClientPtr client;
+#endif
+{
+int length= 0;
+
+ if (class==XkbDfltXIClass) {
+ if (dev->kbdfeed) class= KbdFeedbackClass;
+ else if (dev->leds) class= LedFeedbackClass;
+ }
+ if ((dev->kbdfeed)&&
+ ((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) {
+ KbdFeedbackPtr kf;
+ for (kf= dev->kbdfeed;(kf);kf=kf->next) {
+ if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==kf->ctrl.id)) {
+ length+= SendDeviceLedInfo(kf->xkb_sli,client);
+ if (id!=XkbAllXIIds)
+ break;
+ }
+ }
+ }
+ if ((dev->leds)&&
+ ((class==LedFeedbackClass)||(class==XkbAllXIClasses))) {
+ LedFeedbackPtr lf;
+ for (lf= dev->leds;(lf);lf=lf->next) {
+ if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==lf->ctrl.id)) {
+ length+= SendDeviceLedInfo(lf->xkb_sli,client);
+ if (id!=XkbAllXIIds)
+ break;
+ }
+ }
+ }
+ if (length==wantLength)
+ return Success;
+ else return BadLength;
+}
+
+int
+#if NeedFunctionPrototypes
+ProcXkbGetDeviceInfo(ClientPtr client)
+#else
+ProcXkbGetDeviceInfo(client)
+ ClientPtr client;
+#endif
+{
+DeviceIntPtr dev;
+xkbGetDeviceInfoReply rep;
+int status,nDeviceLedFBs;
+unsigned length,nameLen;
+CARD16 ledClass,ledID;
+unsigned wanted,supported;
+char * str;
+
+ REQUEST(xkbGetDeviceInfoReq);
+ REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ wanted= stuff->wanted;
+
+ CHK_ANY_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_LEGAL(0x01,wanted,XkbXI_AllDeviceFeaturesMask);
+
+ if ((!dev->button)||((stuff->nBtns<1)&&(!stuff->allBtns)))
+ wanted&= ~XkbXI_ButtonActionsMask;
+ if ((!dev->kbdfeed)&&(!dev->leds))
+ wanted&= ~XkbXI_IndicatorsMask;
+ wanted&= ~XkbXIUnsupported;
+
+ nameLen= XkbSizeCountedString(dev->name);
+ bzero((char *)&rep,SIZEOF(xkbGetDeviceInfoReply));
+ rep.type = X_Reply;
+ rep.deviceID= dev->id;
+ rep.sequenceNumber = client->sequence;
+ rep.length = nameLen/4;
+ rep.present = wanted;
+ rep.supported = XkbXI_AllDeviceFeaturesMask&(~XkbXIUnsupported);
+ rep.unsupported = XkbXIUnsupported;
+ rep.firstBtnWanted = rep.nBtnsWanted = 0;
+ rep.firstBtnRtrn = rep.nBtnsRtrn = 0;
+ if (dev->button)
+ rep.totalBtns= dev->button->numButtons;
+ else rep.totalBtns= 0;
+ rep.devType= dev->type;
+ rep.hasOwnState= (dev->key && dev->key->xkbInfo);
+ rep.nDeviceLedFBs = 0;
+ if (dev->kbdfeed) rep.dfltKbdFB= dev->kbdfeed->ctrl.id;
+ else rep.dfltKbdFB= XkbXINone;
+ if (dev->leds) rep.dfltLedFB= dev->leds->ctrl.id;
+ else rep.dfltLedFB= XkbXINone;
+
+ ledClass= stuff->ledClass;
+ ledID= stuff->ledID;
+
+ rep.firstBtnWanted= rep.nBtnsWanted= 0;
+ rep.firstBtnRtrn= rep.nBtnsRtrn= 0;
+ if (wanted&XkbXI_ButtonActionsMask) {
+ if (stuff->allBtns) {
+ stuff->firstBtn= 0;
+ stuff->nBtns= dev->button->numButtons;
+ }
+
+ if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) {
+ client->errorValue = _XkbErrCode4(0x02,dev->button->numButtons,
+ stuff->firstBtn,
+ stuff->nBtns);
+ return BadValue;
+ }
+ else {
+ rep.firstBtnWanted= stuff->firstBtn;
+ rep.nBtnsWanted= stuff->nBtns;
+ if (dev->button->xkb_acts!=NULL) {
+ XkbAction *act;
+ register int i;
+
+ rep.firstBtnRtrn= stuff->firstBtn;
+ rep.nBtnsRtrn= stuff->nBtns;
+ act= &dev->button->xkb_acts[rep.firstBtnWanted];
+ for (i=0;i<rep.nBtnsRtrn;i++,act++) {
+ if (act->type!=XkbSA_NoAction)
+ break;
+ }
+ rep.firstBtnRtrn+= i;
+ rep.nBtnsRtrn-= i;
+ act= &dev->button->xkb_acts[rep.firstBtnRtrn+rep.nBtnsRtrn-1];
+ for (i=0;i<rep.nBtnsRtrn;i++,act--) {
+ if (act->type!=XkbSA_NoAction)
+ break;
+ }
+ rep.nBtnsRtrn-= i;
+ }
+ rep.length+= (rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc))/4;
+ }
+ }
+
+ if (wanted&XkbXI_IndicatorsMask) {
+ status= CheckDeviceLedFBs(dev,ledClass,ledID,&rep,client);
+ if (status!=Success)
+ return status;
+ }
+ length= rep.length*4;
+ supported= rep.supported;
+ nDeviceLedFBs = rep.nDeviceLedFBs;
+ if (client->swapped) {
+ register int n;
+ swaps(&rep.sequenceNumber,n);
+ swapl(&rep.length,n);
+ swaps(&rep.present,n);
+ swaps(&rep.supported,n);
+ swaps(&rep.unsupported,n);
+ swaps(&rep.nDeviceLedFBs,n);
+ swapl(&rep.type,n);
+ }
+ WriteToClient(client,SIZEOF(xkbGetDeviceInfoReply), (char *)&rep);
+
+ str= (char*) ALLOCATE_LOCAL(nameLen);
+ if (!str)
+ return BadAlloc;
+ XkbWriteCountedString(str,dev->name,client->swapped);
+ WriteToClient(client,nameLen,str);
+ DEALLOCATE_LOCAL(str);
+ length-= nameLen;
+
+ if (rep.nBtnsRtrn>0) {
+ int sz;
+ xkbActionWireDesc * awire;
+ sz= rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc);
+ awire= (xkbActionWireDesc *)&dev->button->xkb_acts[rep.firstBtnRtrn];
+ WriteToClient(client,sz,(char *)awire);
+ length-= sz;
+ }
+ if (nDeviceLedFBs>0) {
+ status= SendDeviceLedFBs(dev,ledClass,ledID,length,client);
+ if (status!=Success)
+ return status;
+ }
+ else if (length!=0) {
+#ifdef DEBUG
+ ErrorF("Internal Error! BadLength in ProcXkbGetDeviceInfo\n");
+ ErrorF(" Wrote %d fewer bytes than expected\n",length);
+#endif
+ return BadLength;
+ }
+ if (stuff->wanted&(~supported)) {
+ xkbExtensionDeviceNotify ed;
+ bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify));
+ ed.ledClass= ledClass;
+ ed.ledID= ledID;
+ ed.ledsDefined= 0;
+ ed.ledState= 0;
+ ed.firstBtn= ed.nBtns= 0;
+ ed.reason= XkbXI_UnsupportedFeatureMask;
+ ed.supported= supported;
+ ed.unsupported= stuff->wanted&(~supported);
+ XkbSendExtensionDeviceNotify(dev,client,&ed);
+ }
+ return client->noClientException;
+}
+
+static char *
+#if NeedFunctionPrototypes
+CheckSetDeviceIndicators( char * wire,
+ DeviceIntPtr dev,
+ int num,
+ int * status_rtrn,
+ ClientPtr client)
+#else
+CheckSetDeviceIndicators(wire,dev,num,status_rtrn,client)
+ char * wire;
+ DeviceIntPtr dev;
+ int num;
+ int * status_rtrn;
+ ClientPtr client;
+#endif
+{
+xkbDeviceLedsWireDesc * ledWire;
+int i;
+XkbSrvLedInfoPtr sli;
+
+ ledWire= (xkbDeviceLedsWireDesc *)wire;
+ for (i=0;i<num;i++) {
+ if (client->swapped) {
+ register int n;
+ swaps(&ledWire->ledClass,n);
+ swaps(&ledWire->ledID,n);
+ swapl(&ledWire->namesPresent,n);
+ swapl(&ledWire->mapsPresent,n);
+ swapl(&ledWire->physIndicators,n);
+ }
+
+ sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID,
+ XkbXI_IndicatorsMask);
+ if (sli!=NULL) {
+ register int n;
+ register unsigned bit;
+ int nMaps,nNames;
+ CARD32 *atomWire;
+ xkbIndicatorMapWireDesc *mapWire;
+
+ nMaps= nNames= 0;
+ for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
+ if (ledWire->namesPresent&bit)
+ nNames++;
+ if (ledWire->mapsPresent&bit)
+ nMaps++;
+ }
+ atomWire= (CARD32 *)&ledWire[1];
+ if (nNames>0) {
+ for (n=0;n<nNames;n++) {
+ if (client->swapped) {
+ register int t;
+ swapl(atomWire,t);
+ }
+ CHK_ATOM_OR_NONE3(((Atom)(*atomWire)),client->errorValue,
+ *status_rtrn,NULL);
+ atomWire++;
+ }
+ }
+ mapWire= (xkbIndicatorMapWireDesc *)atomWire;
+ if (nMaps>0) {
+ for (n=0;n<nMaps;n++) {
+ if (client->swapped) {
+ register int t;
+ swaps(&mapWire->virtualMods,t);
+ swapl(&mapWire->ctrls,t);
+ }
+ CHK_MASK_LEGAL3(0x21,mapWire->whichGroups,
+ XkbIM_UseAnyGroup,
+ client->errorValue,
+ *status_rtrn,NULL);
+ CHK_MASK_LEGAL3(0x22,mapWire->whichMods,XkbIM_UseAnyMods,
+ client->errorValue,
+ *status_rtrn,NULL);
+ mapWire++;
+ }
+ }
+ ledWire= (xkbDeviceLedsWireDesc *)mapWire;
+ }
+ else {
+ /* SHOULD NEVER HAPPEN */
+ return (char *)ledWire;
+ }
+ }
+ return (char *)ledWire;
+}
+
+static char *
+#if NeedFunctionPrototypes
+SetDeviceIndicators( char * wire,
+ DeviceIntPtr dev,
+ unsigned changed,
+ int num,
+ int * status_rtrn,
+ ClientPtr client,
+ xkbExtensionDeviceNotify *ev)
+#else
+SetDeviceIndicators(wire,dev,changed,num,status_rtrn,client,ev)
+ char * wire;
+ DeviceIntPtr dev;
+ unsigned changed;
+ int num;
+ ClientPtr client;
+ int * status_rtrn;
+ xkbExtensionDeviceNotify *ev;
+#endif
+{
+xkbDeviceLedsWireDesc * ledWire;
+int i;
+XkbEventCauseRec cause;
+unsigned namec,mapc,statec;
+xkbExtensionDeviceNotify ed;
+XkbChangesRec changes;
+DeviceIntPtr kbd;
+
+ bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
+ bzero((char *)&changes,sizeof(XkbChangesRec));
+ XkbSetCauseXkbReq(&cause,X_kbSetDeviceInfo,client);
+ ledWire= (xkbDeviceLedsWireDesc *)wire;
+ for (i=0;i<num;i++) {
+ register int n;
+ register unsigned bit;
+ CARD32 * atomWire;
+ xkbIndicatorMapWireDesc * mapWire;
+ XkbSrvLedInfoPtr sli;
+
+ namec= mapc= statec= 0;
+ sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID,
+ XkbXI_IndicatorMapsMask);
+ if (!sli) {
+ /* SHOULD NEVER HAPPEN!! */
+ return (char *)ledWire;
+ }
+
+ atomWire= (CARD32 *)&ledWire[1];
+ if (changed&XkbXI_IndicatorNamesMask) {
+ namec= sli->namesPresent|ledWire->namesPresent;
+ bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom));
+ }
+ if (ledWire->namesPresent) {
+ sli->namesPresent= ledWire->namesPresent;
+ bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom));
+ for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
+ if (ledWire->namesPresent&bit) {
+ sli->names[n]= (Atom)*atomWire;
+ if (sli->names[n]==None)
+ ledWire->namesPresent&= ~bit;
+ atomWire++;
+ }
+ }
+ }
+ mapWire= (xkbIndicatorMapWireDesc *)atomWire;
+ if (changed&XkbXI_IndicatorMapsMask) {
+ mapc= sli->mapsPresent|ledWire->mapsPresent;
+ sli->mapsPresent= ledWire->mapsPresent;
+ bzero((char*)sli->maps,XkbNumIndicators*sizeof(XkbIndicatorMapRec));
+ }
+ if (ledWire->mapsPresent) {
+ for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
+ if (ledWire->mapsPresent&bit) {
+ sli->maps[n].flags= mapWire->flags;
+ sli->maps[n].which_groups= mapWire->whichGroups;
+ sli->maps[n].groups= mapWire->groups;
+ sli->maps[n].which_mods= mapWire->whichMods;
+ sli->maps[n].mods.mask= mapWire->mods;
+ sli->maps[n].mods.real_mods=mapWire->realMods;
+ sli->maps[n].mods.vmods= mapWire->virtualMods;
+ sli->maps[n].ctrls= mapWire->ctrls;
+ mapWire++;
+ }
+ }
+ }
+ if (changed&XkbXI_IndicatorStateMask) {
+ statec= sli->effectiveState^ledWire->state;
+ sli->explicitState&= ~statec;
+ sli->explicitState|= (ledWire->state&statec);
+ }
+ if (namec)
+ XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause);
+ if (mapc)
+ XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause);
+ if (statec)
+ XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause);
+
+ kbd= dev;
+ if ((sli->flags&XkbSLI_HasOwnState)==0)
+ kbd= (DeviceIntPtr)LookupKeyboardDevice();
+
+ XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause);
+ ledWire= (xkbDeviceLedsWireDesc *)mapWire;
+ }
+ return (char *)ledWire;
+}
+
+int
+#if NeedFunctionPrototypes
+ProcXkbSetDeviceInfo(ClientPtr client)
+#else
+ProcXkbSetDeviceInfo(client)
+ ClientPtr client;
+#endif
+{
+DeviceIntPtr dev;
+unsigned change;
+char * wire;
+xkbExtensionDeviceNotify ed;
+
+ REQUEST(xkbSetDeviceInfoReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ change= stuff->change;
+
+ CHK_ANY_DEVICE(dev,stuff->deviceSpec);
+ CHK_MASK_LEGAL(0x01,change,(XkbXI_AllFeaturesMask&(~XkbXI_KeyboardsMask)));
+
+ wire= (char *)&stuff[1];
+ if (change&XkbXI_ButtonActionsMask) {
+ if (!dev->button) {
+ client->errorValue = _XkbErrCode2(XkbErr_BadClass,ButtonClass);
+ return XkbKeyboardErrorCode;
+ }
+ if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) {
+ client->errorValue= _XkbErrCode4(0x02,stuff->firstBtn,stuff->nBtns,
+ dev->button->numButtons);
+ return BadMatch;
+ }
+ wire+= (stuff->nBtns*SIZEOF(xkbActionWireDesc));
+ }
+ if (stuff->change&XkbXI_IndicatorsMask) {
+ int status= Success;
+ wire= CheckSetDeviceIndicators(wire,dev,stuff->nDeviceLedFBs,
+ &status,client);
+ if (status!=Success)
+ return status;
+ }
+ if (((wire-((char *)stuff))/4)!=stuff->length)
+ return BadLength;
+
+ bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify));
+ ed.deviceID= dev->id;
+ wire= (char *)&stuff[1];
+ if (change&XkbXI_ButtonActionsMask) {
+ int nBtns,sz,i;
+ XkbAction * acts;
+ DeviceIntPtr kbd;
+
+ nBtns= dev->button->numButtons;
+ acts= dev->button->xkb_acts;
+ if (acts==NULL) {
+ acts= _XkbTypedCalloc(nBtns,XkbAction);
+ if (!acts)
+ return BadAlloc;
+ dev->button->xkb_acts= acts;
+ }
+ sz= stuff->nBtns*SIZEOF(xkbActionWireDesc);
+ memcpy((char *)&acts[stuff->firstBtn],(char *)wire,sz);
+ wire+= sz;
+ ed.reason|= XkbXI_ButtonActionsMask;
+ ed.firstBtn= stuff->firstBtn;
+ ed.nBtns= stuff->nBtns;
+
+ if (dev->key) kbd= dev;
+ else kbd= (DeviceIntPtr)LookupKeyboardDevice();
+ acts= &dev->button->xkb_acts[stuff->firstBtn];
+ for (i=0;i<stuff->nBtns;i++,acts++) {
+ if (acts->type!=XkbSA_NoAction)
+ XkbSetActionKeyMods(kbd->key->xkbInfo->desc,acts,0);
+ }
+ }
+ if (stuff->change&XkbXI_IndicatorsMask) {
+ int status= Success;
+ wire= SetDeviceIndicators(wire,dev,change,stuff->nDeviceLedFBs,
+ &status,client,&ed);
+ if (status!=Success)
+ return status;
+ }
+ if ((stuff->change)&&(ed.reason))
+ XkbSendExtensionDeviceNotify(dev,client,&ed);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+#if NeedFunctionPrototypes
+ProcXkbSetDebuggingFlags(ClientPtr client)
+#else
+ProcXkbSetDebuggingFlags(client)
+ ClientPtr client;
+#endif
+{
+CARD32 newFlags,newCtrls,extraLength;
+xkbSetDebuggingFlagsReply rep;
+
+ REQUEST(xkbSetDebuggingFlagsReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq);
+
+ newFlags= xkbDebugFlags&(~stuff->affectFlags);
+ newFlags|= (stuff->flags&stuff->affectFlags);
+ newCtrls= xkbDebugCtrls&(~stuff->affectCtrls);
+ newCtrls|= (stuff->ctrls&stuff->affectCtrls);
+ if (xkbDebugFlags || newFlags || stuff->msgLength) {
+ ErrorF("XkbDebug: Setting debug flags to 0x%x\n",newFlags);
+ if (newCtrls!=xkbDebugCtrls)
+ ErrorF("XkbDebug: Setting debug controls to 0x%x\n",newCtrls);
+ }
+ extraLength= (stuff->length<<2)-sz_xkbSetDebuggingFlagsReq;
+ if (stuff->msgLength>0) {
+ char *msg;
+ if (extraLength<XkbPaddedSize(stuff->msgLength)) {
+ ErrorF("XkbDebug: msgLength= %d, length= %d (should be %d)\n",
+ stuff->msgLength,extraLength,
+ XkbPaddedSize(stuff->msgLength));
+ return BadLength;
+ }
+ msg= (char *)&stuff[1];
+ if (msg[stuff->msgLength-1]!='\0') {
+ ErrorF("XkbDebug: message not null-terminated\n");
+ return BadValue;
+ }
+ ErrorF("XkbDebug: %s\n",msg);
+ }
+ xkbDebugFlags = newFlags;
+ xkbDebugCtrls = newCtrls;
+
+ XkbDisableLockActions= (xkbDebugCtrls&XkbDF_DisableLocks);
+
+ rep.type= X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.currentFlags = newFlags;
+ rep.currentCtrls = newCtrls;
+ rep.supportedFlags = ~0;
+ rep.supportedCtrls = ~0;
+ if ( client->swapped ) {
+ register int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.currentFlags, n);
+ swapl(&rep.currentCtrls, n);
+ swapl(&rep.supportedFlags, n);
+ swapl(&rep.supportedCtrls, n);
+ }
+ WriteToClient(client,SIZEOF(xkbSetDebuggingFlagsReply), (char *)&rep);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+static int
+#if NeedFunctionPrototypes
+ProcXkbDispatch (ClientPtr client)
+#else
+ProcXkbDispatch (client)
+ ClientPtr client;
+#endif
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_kbUseExtension:
+ return ProcXkbUseExtension(client);
+ case X_kbSelectEvents:
+ return ProcXkbSelectEvents(client);
+ case X_kbBell:
+ return ProcXkbBell(client);
+ case X_kbGetState:
+ return ProcXkbGetState(client);
+ case X_kbLatchLockState:
+ return ProcXkbLatchLockState(client);
+ case X_kbGetControls:
+ return ProcXkbGetControls(client);
+ case X_kbSetControls:
+ return ProcXkbSetControls(client);
+ case X_kbGetMap:
+ return ProcXkbGetMap(client);
+ case X_kbSetMap:
+ return ProcXkbSetMap(client);
+ case X_kbGetCompatMap:
+ return ProcXkbGetCompatMap(client);
+ case X_kbSetCompatMap:
+ return ProcXkbSetCompatMap(client);
+ case X_kbGetIndicatorState:
+ return ProcXkbGetIndicatorState(client);
+ case X_kbGetIndicatorMap:
+ return ProcXkbGetIndicatorMap(client);
+ case X_kbSetIndicatorMap:
+ return ProcXkbSetIndicatorMap(client);
+ case X_kbGetNamedIndicator:
+ return ProcXkbGetNamedIndicator(client);
+ case X_kbSetNamedIndicator:
+ return ProcXkbSetNamedIndicator(client);
+ case X_kbGetNames:
+ return ProcXkbGetNames(client);
+ case X_kbSetNames:
+ return ProcXkbSetNames(client);
+ case X_kbGetGeometry:
+ return ProcXkbGetGeometry(client);
+ case X_kbSetGeometry:
+ return ProcXkbSetGeometry(client);
+ case X_kbPerClientFlags:
+ return ProcXkbPerClientFlags(client);
+ case X_kbListComponents:
+ return ProcXkbListComponents(client);
+ case X_kbGetKbdByName:
+ return ProcXkbGetKbdByName(client);
+ case X_kbGetDeviceInfo:
+ return ProcXkbGetDeviceInfo(client);
+ case X_kbSetDeviceInfo:
+ return ProcXkbSetDeviceInfo(client);
+ case X_kbSetDebuggingFlags:
+ return ProcXkbSetDebuggingFlags(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+#if NeedFunctionPrototypes
+XkbClientGone(pointer data,XID id)
+#else
+XkbClientGone(data,id)
+ pointer data;
+ XID id;
+#endif
+{
+ DevicePtr pXDev = (DevicePtr)data;
+
+ if (!XkbRemoveResourceClient(pXDev,id)) {
+ ErrorF("Internal Error! bad RemoveResourceClient in XkbClientGone\n");
+ }
+ return 1;
+}
+
+/*ARGSUSED*/
+static void
+#if NeedFunctionPrototypes
+XkbResetProc(ExtensionEntry *extEntry)
+#else
+XkbResetProc(extEntry)
+ ExtensionEntry *extEntry;
+#endif
+{
+}
+
+void
+#if NeedFunctionPrototypes
+XkbExtensionInit(void)
+#else
+XkbExtensionInit()
+#endif
+{
+ ExtensionEntry *extEntry;
+
+ if (extEntry = AddExtension(XkbName, XkbNumberEvents, XkbNumberErrors,
+ ProcXkbDispatch, SProcXkbDispatch,
+ XkbResetProc, StandardMinorOpcode)) {
+ XkbReqCode = (unsigned char)extEntry->base;
+ XkbEventBase = (unsigned char)extEntry->eventBase;
+ XkbErrorBase = (unsigned char)extEntry->errorBase;
+ XkbKeyboardErrorCode = XkbErrorBase+XkbKeyboard;
+ RT_XKBCLIENT = CreateNewResourceType(XkbClientGone);
+ }
+ return;
+}
+
+
diff --git a/xc/programs/Xserver/xkb/xkbAccessX.c b/xc/programs/Xserver/xkb/xkbAccessX.c
new file mode 100644
index 000000000..919b8af8b
--- /dev/null
+++ b/xc/programs/Xserver/xkb/xkbAccessX.c
@@ -0,0 +1,851 @@
+/* $XConsortium: xkbAccessX.c /main/13 1996/12/02 10:24:00 lehors $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+/* $XFree86: xc/programs/Xserver/xkb/xkbAccessX.c,v 1.3 1997/01/18 07:18:41 dawes Exp $ */
+
+#include <stdio.h>
+#include <math.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "inputstr.h"
+#include "XKBsrv.h"
+#if !defined(WIN32) && !defined(Lynx)
+#include <sys/time.h>
+#endif
+
+int XkbDfltRepeatDelay= 660;
+int XkbDfltRepeatInterval= 40;
+pointer XkbLastRepeatEvent= NULL;
+
+#define DFLT_TIMEOUT_CTRLS (XkbAX_KRGMask|XkbStickyKeysMask|XkbMouseKeysMask)
+#define DFLT_TIMEOUT_OPTS (XkbAX_IndicatorFBMask)
+
+unsigned short XkbDfltAccessXTimeout= 120;
+unsigned int XkbDfltAccessXTimeoutMask= DFLT_TIMEOUT_CTRLS;
+unsigned int XkbDfltAccessXTimeoutValues= 0;
+unsigned int XkbDfltAccessXTimeoutOptionsMask= DFLT_TIMEOUT_OPTS;
+unsigned int XkbDfltAccessXTimeoutOptionsValues= 0;
+unsigned int XkbDfltAccessXFeedback= XkbAccessXFeedbackMask;
+unsigned short XkbDfltAccessXOptions= XkbAX_AllOptionsMask & ~(XkbAX_IndicatorFBMask|XkbAX_SKReleaseFBMask|XkbAX_SKRejectFBMask);
+
+void
+#if NeedFunctionPrototypes
+AccessXComputeCurveFactor(XkbSrvInfoPtr xkbi,XkbControlsPtr ctrls)
+#else
+AccessXComputeCurveFactor(xkbi,ctrls)
+ XkbSrvInfoPtr xkbi;
+ XkbControlsPtr ctrls;
+#endif
+{
+ xkbi->mouseKeysCurve= 1.0+(((double)ctrls->mk_curve)*0.001);
+ xkbi->mouseKeysCurveFactor= ( ((double)ctrls->mk_max_speed)/
+ pow((double)ctrls->mk_time_to_max,xkbi->mouseKeysCurve));
+ return;
+}
+
+void
+#if NeedFunctionPrototypes
+AccessXInit(DeviceIntPtr keybd)
+#else
+AccessXInit(keybd)
+ DeviceIntPtr keybd;
+#endif
+{
+XkbSrvInfoPtr xkbi = keybd->key->xkbInfo;
+XkbControlsPtr ctrls = xkbi->desc->ctrls;
+
+ xkbi->shiftKeyCount= 0;
+ xkbi->mouseKeysCounter= 0;
+ xkbi->inactiveKey= 0;
+ xkbi->slowKey= 0;
+ xkbi->repeatKey= 0;
+ xkbi->krgTimerActive= _OFF_TIMER;
+ xkbi->beepType= _BEEP_NONE;
+ xkbi->beepCount= 0;
+ xkbi->mouseKeyTimer= NULL;
+ xkbi->slowKeysTimer= NULL;
+ xkbi->bounceKeysTimer= NULL;
+ xkbi->repeatKeyTimer= NULL;
+ xkbi->krgTimer= NULL;
+ xkbi->beepTimer= NULL;
+ ctrls->repeat_delay = XkbDfltRepeatDelay;
+ ctrls->repeat_interval = XkbDfltRepeatInterval;
+ ctrls->debounce_delay = 300;
+ ctrls->slow_keys_delay = 300;
+ ctrls->mk_delay = 160;
+ ctrls->mk_interval = 40;
+ ctrls->mk_time_to_max = 30;
+ ctrls->mk_max_speed = 30;
+ ctrls->mk_curve = 500;
+ ctrls->mk_dflt_btn = 1;
+ ctrls->ax_timeout = XkbDfltAccessXTimeout;
+ ctrls->axt_ctrls_mask = XkbDfltAccessXTimeoutMask;
+ ctrls->axt_ctrls_values = XkbDfltAccessXTimeoutValues;
+ ctrls->axt_opts_mask = XkbDfltAccessXTimeoutOptionsMask;
+ ctrls->axt_opts_values = XkbDfltAccessXTimeoutOptionsValues;
+ if (XkbDfltAccessXTimeout)
+ ctrls->enabled_ctrls |= XkbAccessXTimeoutMask;
+ else
+ ctrls->enabled_ctrls &= ~XkbAccessXTimeoutMask;
+ ctrls->enabled_ctrls |= XkbDfltAccessXFeedback;
+ ctrls->ax_options = XkbDfltAccessXOptions;
+ AccessXComputeCurveFactor(xkbi,ctrls);
+ return;
+}
+
+/************************************************************************/
+/* */
+/* AccessXKeyboardEvent */
+/* */
+/* Generate a synthetic keyboard event. */
+/* */
+/************************************************************************/
+static void
+#if NeedFunctionPrototypes
+AccessXKeyboardEvent(DeviceIntPtr keybd,
+ BYTE type,
+ BYTE keyCode,
+ Bool isRepeat)
+#else
+AccessXKeyboardEvent(keybd,type,keyCode,isRepeat)
+ DeviceIntPtr keybd;
+ BYTE type;
+ BYTE keyCode;
+ Bool isRepeat;
+#endif
+{
+xEvent xE;
+#ifdef XINPUT
+extern int DeviceKeyPress;
+#endif
+
+ xE.u.u.type = type;
+ xE.u.u.detail = keyCode;
+ xE.u.keyButtonPointer.time = GetTimeInMillis();
+#ifdef DEBUG
+ if (xkbDebugFlags&0x8) {
+ ErrorF("AXKE: Key %d %s\n",keyCode,(xE.u.u.type==KeyPress?"down":"up"));
+ }
+#endif
+
+ if (_XkbIsPressEvent(type))
+ XkbDDXKeyClick(keybd,keyCode,TRUE);
+ else if (isRepeat)
+ XkbLastRepeatEvent= (pointer)&xE;
+ XkbProcessKeyboardEvent(&xE,keybd,1L);
+ XkbLastRepeatEvent= NULL;
+ return;
+
+} /* AccessXKeyboardEvent */
+
+/************************************************************************/
+/* */
+/* AccessXKRGTurnOn */
+/* */
+/* Turn the keyboard response group on. */
+/* */
+/************************************************************************/
+static void
+#if NeedFunctionPrototypes
+AccessXKRGTurnOn(DeviceIntPtr dev,CARD16 KRGControl,xkbControlsNotify *pCN)
+#else
+AccessXKRGTurnOn(dev,KRGControl,pCN)
+ DeviceIntPtr dev;
+ CARD16 KRGControl;
+ xkbControlsNotify *pCN;
+#endif
+{
+XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
+XkbControlsPtr ctrls = xkbi->desc->ctrls;
+XkbControlsRec old;
+XkbEventCauseRec cause;
+XkbSrvLedInfoPtr sli;
+
+ old= *ctrls;
+ ctrls->enabled_ctrls |= (KRGControl&XkbAX_KRGMask);
+ if (XkbComputeControlsNotify(dev,&old,ctrls,pCN,False))
+ XkbSendControlsNotify(dev,pCN);
+ cause.kc= pCN->keycode;
+ cause.event= pCN->eventType;
+ cause.mjr= pCN->requestMajor;
+ cause.mnr= pCN->requestMinor;
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
+ XkbDDXAccessXBeep(dev,_BEEP_FEATURE_ON,KRGControl);
+ return;
+
+} /* AccessXKRGTurnOn */
+
+/************************************************************************/
+/* */
+/* AccessXKRGTurnOff */
+/* */
+/* Turn the keyboard response group off. */
+/* */
+/************************************************************************/
+static void
+#if NeedFunctionPrototypes
+AccessXKRGTurnOff(DeviceIntPtr dev,xkbControlsNotify *pCN)
+#else
+AccessXKRGTurnOff(dev,pCN)
+ DeviceIntPtr dev;
+ xkbControlsNotify *pCN;
+#endif
+{
+XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
+XkbControlsPtr ctrls = xkbi->desc->ctrls;
+XkbControlsRec old;
+XkbEventCauseRec cause;
+XkbSrvLedInfoPtr sli;
+
+ old = *ctrls;
+ ctrls->enabled_ctrls &= ~XkbAX_KRGMask;
+ if (XkbComputeControlsNotify(dev,&old,ctrls,pCN,False))
+ XkbSendControlsNotify(dev,pCN);
+ cause.kc= pCN->keycode;
+ cause.event= pCN->eventType;
+ cause.mjr= pCN->requestMajor;
+ cause.mnr= pCN->requestMinor;
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) {
+ unsigned changes= old.enabled_ctrls^ctrls->enabled_ctrls;
+ XkbDDXAccessXBeep(dev,_BEEP_FEATURE_OFF,changes);
+ }
+ return;
+
+} /* AccessXKRGTurnOff */
+
+/************************************************************************/
+/* */
+/* AccessXStickyKeysTurnOn */
+/* */
+/* Turn StickyKeys on. */
+/* */
+/************************************************************************/
+static void
+#if NeedFunctionPrototypes
+AccessXStickyKeysTurnOn(DeviceIntPtr dev,xkbControlsNotify *pCN)
+#else
+AccessXStickyKeysTurnOn(dev,pCN)
+ DeviceIntPtr dev;
+ xkbControlsNotify *pCN;
+#endif
+{
+XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
+XkbControlsPtr ctrls = xkbi->desc->ctrls;
+XkbControlsRec old;
+XkbEventCauseRec cause;
+XkbSrvLedInfoPtr sli;
+
+ old = *ctrls;
+ ctrls->enabled_ctrls |= XkbStickyKeysMask;
+ xkbi->shiftKeyCount = 0;
+ if (XkbComputeControlsNotify(dev,&old,ctrls,pCN,False))
+ XkbSendControlsNotify(dev,pCN);
+ cause.kc= pCN->keycode;
+ cause.event= pCN->eventType;
+ cause.mjr= pCN->requestMajor;
+ cause.mnr= pCN->requestMinor;
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) {
+ XkbDDXAccessXBeep(dev,_BEEP_FEATURE_ON,XkbStickyKeysMask);
+ }
+ return;
+
+} /* AccessXStickyKeysTurnOn */
+
+/************************************************************************/
+/* */
+/* AccessXStickyKeysTurnOff */
+/* */
+/* Turn StickyKeys off. */
+/* */
+/************************************************************************/
+static void
+#if NeedFunctionPrototypes
+AccessXStickyKeysTurnOff(DeviceIntPtr dev,xkbControlsNotify *pCN)
+#else
+AccessXStickyKeysTurnOff(dev,pCN)
+ DeviceIntPtr dev;
+ xkbControlsNotify *pCN;
+#endif
+{
+XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
+XkbControlsPtr ctrls = xkbi->desc->ctrls;
+XkbControlsRec old;
+XkbEventCauseRec cause;
+XkbSrvLedInfoPtr sli;
+
+ old = *ctrls;
+ ctrls->enabled_ctrls &= ~XkbStickyKeysMask;
+ xkbi->shiftKeyCount = 0;
+ if (XkbComputeControlsNotify(dev,&old,ctrls,pCN,False))
+ XkbSendControlsNotify(dev,pCN);
+
+ cause.kc= pCN->keycode;
+ cause.event= pCN->eventType;
+ cause.mjr= pCN->requestMajor;
+ cause.mnr= pCN->requestMinor;
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) {
+ XkbDDXAccessXBeep(dev,_BEEP_FEATURE_OFF,XkbStickyKeysMask);
+ }
+#ifndef NO_CLEAR_LATCHES_FOR_STICKY_KEYS_OFF
+ XkbClearAllLatchesAndLocks(dev,xkbi,False,&cause);
+#endif
+ return;
+} /* AccessXStickyKeysTurnOff */
+
+static CARD32
+#if NeedFunctionPrototypes
+AccessXKRGExpire(OsTimerPtr timer,CARD32 now,pointer arg)
+#else
+AccessXKRGExpire(timer,now,arg)
+ OsTimerPtr timer;
+ CARD32 now;
+ pointer arg;
+#endif
+{
+XkbSrvInfoPtr xkbi= ((DeviceIntPtr)arg)->key->xkbInfo;
+xkbControlsNotify cn;
+
+ if (xkbi->krgTimerActive==_KRG_WARN_TIMER) {
+ XkbDDXAccessXBeep((DeviceIntPtr)arg,_BEEP_SLOW_WARN,XkbStickyKeysMask);
+ xkbi->krgTimerActive= _KRG_TIMER;
+ return 4000;
+ }
+ xkbi->krgTimerActive= _OFF_TIMER;
+ cn.keycode = 0;
+ cn.eventType = 0;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ if (xkbi->desc->ctrls->enabled_ctrls&XkbSlowKeysMask)
+ AccessXKRGTurnOff((DeviceIntPtr)arg,&cn);
+ else AccessXKRGTurnOn((DeviceIntPtr)arg,XkbSlowKeysMask,&cn);
+ return 0;
+}
+
+static CARD32
+#if NeedFunctionPrototypes
+AccessXRepeatKeyExpire(OsTimerPtr timer,CARD32 now,pointer arg)
+#else
+AccessXRepeatKeyExpire(timer,now,arg)
+ OsTimerPtr timer;
+ CARD32 now;
+ pointer arg;
+#endif
+{
+XkbSrvInfoPtr xkbi= ((DeviceIntPtr)arg)->key->xkbInfo;
+KeyCode key;
+
+ if (xkbi->repeatKey==0)
+ return 0;
+ key= xkbi->repeatKey;
+ AccessXKeyboardEvent((DeviceIntPtr)arg,KeyRelease,key,True);
+ AccessXKeyboardEvent((DeviceIntPtr)arg,KeyPress,key,True);
+ return xkbi->desc->ctrls->repeat_interval;
+}
+
+void
+#if NeedFunctionPrototypes
+AccessXCancelRepeatKey(XkbSrvInfoPtr xkbi,KeyCode key)
+#else
+AccessXCancelRepeatKey(xkbi,key)
+ XkbSrvInfoPtr xkbi;
+ KeyCode key;
+#endif
+{
+ if (xkbi->repeatKey==key)
+ xkbi->repeatKey= 0;
+ return;
+}
+
+static CARD32
+#if NeedFunctionPrototypes
+AccessXSlowKeyExpire(OsTimerPtr timer,CARD32 now,pointer arg)
+#else
+AccessXSlowKeyExpire(timer,now,arg)
+ OsTimerPtr timer;
+ CARD32 now;
+ pointer arg;
+#endif
+{
+DeviceIntPtr keybd;
+XkbSrvInfoPtr xkbi;
+XkbDescPtr xkb;
+XkbControlsPtr ctrls;
+
+ keybd= (DeviceIntPtr)arg;
+ xkbi= keybd->key->xkbInfo;
+ xkb= xkbi->desc;
+ ctrls= xkb->ctrls;
+ if (xkbi->slowKey!=0) {
+ xkbAccessXNotify ev;
+ KeySym *sym= XkbKeySymsPtr(xkb,xkbi->slowKey);
+ ev.detail= XkbAXN_SKAccept;
+ ev.keycode= xkbi->slowKey;
+ ev.slowKeysDelay= ctrls->slow_keys_delay;
+ ev.debounceDelay= ctrls->debounce_delay;
+ XkbSendAccessXNotify(keybd,&ev);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_SKAcceptFBMask))
+ XkbDDXAccessXBeep(keybd,_BEEP_SLOW_ACCEPT,XkbSlowKeysMask);
+ AccessXKeyboardEvent(keybd,KeyPress,xkbi->slowKey,False);
+ /* check for magic sequences */
+ if ((ctrls->enabled_ctrls&XkbAccessXKeysMask) &&
+ ((sym[0]==XK_Shift_R)||(sym[0]==XK_Shift_L)))
+ xkbi->shiftKeyCount++;
+
+ /* Start repeating if necessary. Stop autorepeating if the user
+ * presses a non-modifier key that doesn't autorepeat.
+ */
+ if (keybd->kbdfeed->ctrl.autoRepeat &&
+ ((xkbi->slowKey != xkbi->mouseKey) || (!xkbi->mouseKeysAccel)) &&
+ (ctrls->enabled_ctrls&XkbRepeatKeysMask)) {
+#ifndef AIXV3
+ if (BitIsOn(keybd->kbdfeed->ctrl.autoRepeats,xkbi->slowKey))
+#endif
+ {
+ xkbi->repeatKey = xkbi->slowKey;
+ xkbi->repeatKeyTimer= TimerSet(xkbi->repeatKeyTimer,
+ 0, ctrls->repeat_delay,
+ AccessXRepeatKeyExpire, (pointer)keybd);
+ }
+ }
+ }
+ return 0;
+}
+
+static CARD32
+#if NeedFunctionPrototypes
+AccessXBounceKeyExpire(OsTimerPtr timer,CARD32 now,pointer arg)
+#else
+AccessXBounceKeyExpire(timer,now,arg)
+ OsTimerPtr timer;
+ CARD32 now;
+ pointer arg;
+#endif
+{
+XkbSrvInfoPtr xkbi= ((DeviceIntPtr)arg)->key->xkbInfo;
+
+ xkbi->inactiveKey= 0;
+ return 0;
+}
+
+static CARD32
+#if NeedFunctionPrototypes
+AccessXTimeoutExpire(OsTimerPtr timer,CARD32 now,pointer arg)
+#else
+AccessXTimeoutExpire(timer,now,arg)
+ OsTimerPtr timer;
+ CARD32 now;
+ pointer arg;
+#endif
+{
+DeviceIntPtr dev = (DeviceIntPtr)arg;
+XkbSrvInfoPtr xkbi= dev->key->xkbInfo;
+XkbControlsPtr ctrls= xkbi->desc->ctrls;
+XkbControlsRec old;
+xkbControlsNotify cn;
+XkbEventCauseRec cause;
+XkbSrvLedInfoPtr sli;
+
+ if (xkbi->lastPtrEventTime) {
+ unsigned timeToWait = (ctrls->ax_timeout*1000);
+ unsigned timeElapsed = (now-xkbi->lastPtrEventTime);
+
+ if (timeToWait > timeElapsed)
+ return (timeToWait - timeElapsed);
+ }
+ old= *ctrls;
+ xkbi->shiftKeyCount= 0;
+ ctrls->enabled_ctrls&= ~ctrls->axt_ctrls_mask;
+ ctrls->enabled_ctrls|=
+ (ctrls->axt_ctrls_values&ctrls->axt_ctrls_mask);
+ if (ctrls->axt_opts_mask) {
+ ctrls->ax_options&= ~ctrls->axt_opts_mask;
+ ctrls->ax_options|= (ctrls->axt_opts_values&ctrls->axt_opts_mask);
+ }
+ if (XkbComputeControlsNotify(dev,&old,ctrls,&cn,False)) {
+ cn.keycode = 0;
+ cn.eventType = 0;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ XkbSendControlsNotify(dev,&cn);
+ }
+ XkbSetCauseUnknown(&cause);
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(dev,sli->usesControls,True,NULL,&cause);
+ if (ctrls->ax_options!=old.ax_options) {
+ unsigned set,cleared,bell;
+ set= ctrls->ax_options&(~old.ax_options);
+ cleared= (~ctrls->ax_options)&old.ax_options;
+ if (set && cleared) bell= _BEEP_FEATURE_CHANGE;
+ else if (set) bell= _BEEP_FEATURE_ON;
+ else bell= _BEEP_FEATURE_OFF;
+ XkbDDXAccessXBeep(dev,bell,XkbAccessXTimeoutMask);
+ }
+ xkbi->krgTimerActive= _OFF_TIMER;
+ return 0;
+}
+
+
+/************************************************************************/
+/* */
+/* AccessXFilterPressEvent */
+/* */
+/* Filter events before they get any further if SlowKeys is turned on. */
+/* In addition, this routine handles the ever so popular magic key */
+/* acts for turning various accessibility features on/off. */
+/* */
+/* Returns TRUE if this routine has discarded the event. */
+/* Returns FALSE if the event needs further processing. */
+/* */
+/************************************************************************/
+Bool
+#if NeedFunctionPrototypes
+AccessXFilterPressEvent( register xEvent * xE,
+ register DeviceIntPtr keybd,
+ int count)
+#else
+AccessXFilterPressEvent(xE,keybd,count)
+ register xEvent *xE;
+ register DeviceIntPtr keybd;
+ int count;
+#endif
+{
+XkbSrvInfoPtr xkbi = keybd->key->xkbInfo;
+XkbControlsPtr ctrls = xkbi->desc->ctrls;
+Bool ignoreKeyEvent = FALSE;
+KeyCode key = xE->u.u.detail;
+KeySym * sym = XkbKeySymsPtr(xkbi->desc,key);
+
+ if (ctrls->enabled_ctrls&XkbAccessXKeysMask) {
+ /* check for magic sequences */
+ if ((sym[0]==XK_Shift_R)||(sym[0]==XK_Shift_L)) {
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_SlowWarnFBMask)) {
+ xkbi->krgTimerActive = _KRG_WARN_TIMER;
+ xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0, 4000,
+ AccessXKRGExpire, (pointer)keybd);
+ }
+ else {
+ xkbi->krgTimerActive = _KRG_TIMER;
+ xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0, 8000,
+ AccessXKRGExpire, (pointer)keybd);
+ }
+ if (!(ctrls->enabled_ctrls & XkbSlowKeysMask)) {
+ CARD32 now= GetTimeInMillis();
+ if ((now-xkbi->lastShiftEventTime)>15000)
+ xkbi->shiftKeyCount= 1;
+ else xkbi->shiftKeyCount++;
+ xkbi->lastShiftEventTime= now;
+ }
+ }
+ else {
+ if (xkbi->krgTimerActive) {
+ xkbi->krgTimer= TimerSet(xkbi->krgTimer,0, 0, NULL, NULL);
+ xkbi->krgTimerActive= _OFF_TIMER;
+ }
+ }
+ }
+
+ /* Don't transmit the KeyPress if SlowKeys is turned on;
+ * The wakeup handler will synthesize one for us if the user
+ * has held the key long enough.
+ */
+ if (ctrls->enabled_ctrls & XkbSlowKeysMask) {
+ xkbAccessXNotify ev;
+ ev.detail= XkbAXN_SKPress;
+ ev.keycode= key;
+ ev.slowKeysDelay= ctrls->slow_keys_delay;
+ ev.debounceDelay= ctrls->debounce_delay;
+ XkbSendAccessXNotify(keybd,&ev);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_SKPressFBMask))
+ XkbDDXAccessXBeep(keybd,_BEEP_SLOW_PRESS,XkbSlowKeysMask);
+ xkbi->slowKey= key;
+ xkbi->slowKeysTimer = TimerSet(xkbi->slowKeysTimer,
+ 0, ctrls->slow_keys_delay,
+ AccessXSlowKeyExpire, (pointer)keybd);
+ ignoreKeyEvent = TRUE;
+ }
+
+ /* Don't transmit the KeyPress if BounceKeys is turned on
+ * and the user pressed the same key within a given time period
+ * from the last release.
+ */
+ else if ((ctrls->enabled_ctrls & XkbBounceKeysMask) &&
+ (key == xkbi->inactiveKey)) {
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_BKRejectFBMask))
+ XkbDDXAccessXBeep(keybd,_BEEP_BOUNCE_REJECT,XkbBounceKeysMask);
+ ignoreKeyEvent = TRUE;
+ }
+
+ /* Start repeating if necessary. Stop autorepeating if the user
+ * presses a non-modifier key that doesn't autorepeat.
+ */
+ if (XkbDDXUsesSoftRepeat(keybd)) {
+ if ((keybd->kbdfeed->ctrl.autoRepeat) &&
+ ((ctrls->enabled_ctrls&(XkbSlowKeysMask|XkbRepeatKeysMask))==
+ XkbRepeatKeysMask)) {
+#ifndef AIXV3
+ if (BitIsOn(keybd->kbdfeed->ctrl.autoRepeats,key))
+#endif
+ {
+#ifdef DEBUG
+ if (xkbDebugFlags&0x10)
+ ErrorF("Starting software autorepeat...\n");
+#endif
+ xkbi->repeatKey = key;
+ xkbi->repeatKeyTimer= TimerSet(xkbi->repeatKeyTimer,
+ 0, ctrls->repeat_delay,
+ AccessXRepeatKeyExpire, (pointer)keybd);
+ }
+ }
+ }
+
+ /* Check for two keys being pressed at the same time. This section
+ * essentially says the following:
+ *
+ * If StickyKeys is on, and a modifier is currently being held down,
+ * and one of the following is true: the current key is not a modifier
+ * or the currentKey is a modifier, but not the only modifier being
+ * held down, turn StickyKeys off if the TwoKeys off ctrl is set.
+ */
+ if ((ctrls->enabled_ctrls & XkbStickyKeysMask) &&
+ (xkbi->state.base_mods!=0) &&
+ (XkbAX_NeedOption(ctrls,XkbAX_TwoKeysMask))) {
+ xkbControlsNotify cn;
+ cn.keycode = key;
+ cn.eventType = KeyPress;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ AccessXStickyKeysTurnOff(keybd,&cn);
+ }
+
+ if (!ignoreKeyEvent)
+ XkbProcessKeyboardEvent(xE,keybd,count);
+ return ignoreKeyEvent;
+} /* AccessXFilterPressEvent */
+
+/************************************************************************/
+/* */
+/* AccessXFilterReleaseEvent */
+/* */
+/* Filter events before they get any further if SlowKeys is turned on. */
+/* In addition, this routine handles the ever so popular magic key */
+/* acts for turning various accessibility features on/off. */
+/* */
+/* Returns TRUE if this routine has discarded the event. */
+/* Returns FALSE if the event needs further processing. */
+/* */
+/************************************************************************/
+Bool
+#if NeedFunctionPrototypes
+AccessXFilterReleaseEvent( register xEvent * xE,
+ register DeviceIntPtr keybd,
+ int count)
+#else
+AccessXFilterReleaseEvent(xE,keybd,count)
+ register xEvent *xE;
+ register DeviceIntPtr keybd;
+ int count;
+#endif
+{
+XkbSrvInfoPtr xkbi = keybd->key->xkbInfo;
+XkbControlsPtr ctrls = xkbi->desc->ctrls;
+KeyCode key = xE->u.u.detail;
+Bool ignoreKeyEvent = FALSE;
+
+ /* Don't transmit the KeyRelease if BounceKeys is on and
+ * this is the release of a key that was ignored due to
+ * BounceKeys.
+ */
+ if (ctrls->enabled_ctrls & XkbBounceKeysMask) {
+ if ((key!=xkbi->mouseKey)&&(!BitIsOn(keybd->key->down,key)))
+ ignoreKeyEvent = TRUE;
+ xkbi->inactiveKey= key;
+ xkbi->bounceKeysTimer= TimerSet(xkbi->bounceKeysTimer, 0,
+ ctrls->debounce_delay,
+ AccessXBounceKeyExpire, (pointer)keybd);
+ }
+
+ /* Don't transmit the KeyRelease if SlowKeys is turned on and
+ * the user didn't hold the key long enough. We know we passed
+ * the key if the down bit was set by CoreProcessKeyboadEvent.
+ */
+ if (ctrls->enabled_ctrls & XkbSlowKeysMask) {
+ xkbAccessXNotify ev;
+ unsigned beep_type;
+ ev.keycode= key;
+ ev.slowKeysDelay= ctrls->slow_keys_delay;
+ ev.debounceDelay= ctrls->debounce_delay;
+ if (BitIsOn(keybd->key->down,key) | (xkbi->mouseKey == key)) {
+ ev.detail= XkbAXN_SKRelease;
+ beep_type= _BEEP_SLOW_RELEASE;
+ }
+ else {
+ ev.detail= XkbAXN_SKReject;
+ beep_type= _BEEP_SLOW_REJECT;
+ ignoreKeyEvent = TRUE;
+ }
+ XkbSendAccessXNotify(keybd,&ev);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_SKRejectFBMask)) {
+ XkbDDXAccessXBeep(keybd,beep_type,XkbSlowKeysMask);
+ }
+ if (xkbi->slowKey==key)
+ xkbi->slowKey= 0;
+ }
+
+ /* Stop Repeating if the user releases the key that is currently
+ * repeating.
+ */
+ if (xkbi->repeatKey==key) {
+ xkbi->repeatKey= 0;
+ }
+
+ if ((ctrls->enabled_ctrls&XkbAccessXTimeoutMask)&&(ctrls->ax_timeout>0)) {
+ xkbi->lastPtrEventTime= 0;
+ xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0,
+ ctrls->ax_timeout*1000,
+ AccessXTimeoutExpire, (pointer)keybd);
+ xkbi->krgTimerActive= _ALL_TIMEOUT_TIMER;
+ }
+ else if (xkbi->krgTimerActive!=_OFF_TIMER) {
+ xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0, 0, NULL, NULL);
+ xkbi->krgTimerActive= _OFF_TIMER;
+ }
+
+ /* Keep track of how many times the Shift key has been pressed.
+ * If it has been pressed and released 5 times in a row, toggle
+ * the state of StickyKeys.
+ */
+ if ((!ignoreKeyEvent)&&(xkbi->shiftKeyCount)) {
+ KeySym *pSym= XkbKeySymsPtr(xkbi->desc,key);
+ if ((pSym[0]!=XK_Shift_L)&&(pSym[0]!=XK_Shift_R)) {
+ xkbi->shiftKeyCount= 0;
+ }
+ else if (xkbi->shiftKeyCount>=5) {
+ xkbControlsNotify cn;
+ cn.keycode = key;
+ cn.eventType = KeyPress;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ if (ctrls->enabled_ctrls & XkbStickyKeysMask)
+ AccessXStickyKeysTurnOff(keybd,&cn);
+ else
+ AccessXStickyKeysTurnOn(keybd,&cn);
+ xkbi->shiftKeyCount= 0;
+ }
+ }
+
+ if (!ignoreKeyEvent)
+ XkbProcessKeyboardEvent(xE,keybd,count);
+ return ignoreKeyEvent;
+
+} /* AccessXFilterReleaseEvent */
+
+/************************************************************************/
+/* */
+/* ProcessPointerEvent */
+/* */
+/* This routine merely sets the shiftKeyCount and clears the keyboard */
+/* response group timer (if necessary) on a mouse event. This is so */
+/* multiple shifts with just the mouse and shift-drags with the mouse */
+/* don't accidentally turn on StickyKeys or the Keyboard Response Group.*/
+/* */
+/************************************************************************/
+void
+#if NeedFunctionPrototypes
+ProcessPointerEvent( register xEvent * xE,
+ register DeviceIntPtr mouse,
+ int count)
+#else
+ProcessPointerEvent(xE,mouse,count)
+ register xEvent *xE;
+ register DeviceIntPtr mouse;
+ int count;
+#endif
+{
+DeviceIntPtr dev = (DeviceIntPtr)LookupKeyboardDevice();
+XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
+unsigned changed = 0;
+
+ xkbi->shiftKeyCount = 0;
+ xkbi->lastPtrEventTime= xE->u.keyButtonPointer.time;
+
+ if (xE->u.u.type==ButtonPress) {
+ changed |= XkbPointerButtonMask;
+ }
+ else if (xE->u.u.type==ButtonRelease) {
+ xkbi->lockedPtrButtons&= ~(1<<(xE->u.u.detail&0x7));
+ changed |= XkbPointerButtonMask;
+ }
+ CoreProcessPointerEvent(xE,mouse,count);
+
+ xkbi->state.ptr_buttons = mouse->button->state;
+
+ /* clear any latched modifiers */
+ if ( xkbi->state.latched_mods && (xE->u.u.type==ButtonRelease) ) {
+ unsigned changed_leds;
+ XkbStateRec oldState;
+ XkbSrvLedInfoPtr sli;
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ oldState= xkbi->state;
+ XkbLatchModifiers(dev,0xFF,0x00);
+
+ XkbComputeDerivedState(xkbi);
+ changed |= XkbStateChangedFlags(&oldState,&xkbi->state);
+ if (changed&sli->usedComponents) {
+ changed_leds= XkbIndicatorsToUpdate(dev,changed,False);
+ if (changed_leds) {
+ XkbEventCauseRec cause;
+ XkbSetCauseKey(&cause,(xE->u.u.detail&0x7),xE->u.u.type);
+ XkbUpdateIndicators(dev,changed_leds,True,NULL,&cause);
+ }
+ }
+ dev->key->state= XkbStateFieldFromRec(&xkbi->state);
+ }
+
+ if (((xkbi->flags&_XkbStateNotifyInProgress)==0)&&(changed!=0)) {
+ xkbStateNotify sn;
+ sn.keycode= xE->u.u.detail;
+ sn.eventType= xE->u.u.type;
+ sn.requestMajor = sn.requestMinor = 0;
+ sn.changed= changed;
+ XkbSendStateNotify(dev,&sn);
+ }
+
+} /* ProcessPointerEvent */
+
+
+
+
diff --git a/xc/programs/Xserver/xkb/xkbActions.c b/xc/programs/Xserver/xkb/xkbActions.c
new file mode 100644
index 000000000..ebdbcdd2f
--- /dev/null
+++ b/xc/programs/Xserver/xkb/xkbActions.c
@@ -0,0 +1,1463 @@
+/* $XConsortium: xkbActions.c /main/3 1996/03/01 14:31:12 kaleb $ */
+/* $XFree86: xc/programs/Xserver/xkb/xkbActions.c,v 3.1 1996/09/24 13:59:37 dawes Exp $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#include <stdio.h>
+#include <math.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "XKBsrv.h"
+#include <ctype.h>
+
+#ifdef XINPUT
+extern void ProcessOtherEvent(
+#if NeedFunctionPrototypes
+ xEvent * /* xE */,
+ DeviceIntPtr /* dev */,
+ int /* count */
+#endif
+);
+#endif
+
+/***====================================================================***/
+
+static XkbAction
+#if NeedFunctionPrototypes
+_FixUpAction(XkbDescPtr xkb,XkbAction *act)
+#else
+_FixUpAction(xkb,act)
+ XkbDescPtr xkb;
+ XkbAction * act;
+#endif
+{
+static XkbAction fake;
+
+ if (XkbIsPtrAction(act)&&(!(xkb->ctrls->enabled_ctrls&XkbMouseKeysMask))) {
+ fake.type = XkbSA_NoAction;
+ return fake;
+ }
+ if (XkbDisableLockActions) {
+ switch (act->type) {
+ case XkbSA_LockMods:
+ fake.mods.type = XkbSA_SetMods;
+ fake.mods.flags = 0;
+ fake.mods.mask = act->mods.mask;
+ return fake;
+ case XkbSA_LatchMods:
+ fake.mods.type = XkbSA_SetMods;
+ fake.mods.flags = 0;
+ fake.mods.mask = act->mods.mask;
+ return fake;
+ case XkbSA_ISOLock:
+ if (act->iso.flags&XkbSA_ISODfltIsGroup) {
+ fake.group.type = XkbSA_SetGroup;
+ fake.group.flags = act->iso.flags&XkbSA_GroupAbsolute;
+ XkbSASetGroup(&fake.group,XkbSAGroup(&act->iso));
+ }
+ else {
+ fake.mods.type = XkbSA_SetMods;
+ fake.mods.flags = 0;
+ fake.mods.mask = act->iso.mask;
+ }
+ return fake;
+ case XkbSA_LockGroup:
+ case XkbSA_LatchGroup:
+ /* We want everything from the latch/lock action except the
+ * type should be changed to set.
+ */
+ fake = *act;
+ fake.group.type = XkbSA_SetGroup;
+ return fake;
+ }
+ }
+ else
+ if (xkb->ctrls->enabled_ctrls&XkbStickyKeysMask) {
+ if (act->any.type==XkbSA_SetMods) {
+ fake.mods.type = XkbSA_LatchMods;
+ fake.mods.mask = act->mods.mask;
+ if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
+ fake.mods.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
+ else fake.mods.flags= XkbSA_ClearLocks;
+ return fake;
+ }
+ if (act->any.type==XkbSA_SetGroup) {
+ fake.group.type = XkbSA_LatchGroup;
+ if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
+ fake.group.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
+ else fake.group.flags= XkbSA_ClearLocks;
+ XkbSASetGroup(&fake.group,XkbSAGroup(&act->group));
+ return fake;
+ }
+ }
+ return *act;
+}
+
+static XkbAction
+#if NeedFunctionPrototypes
+XkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key)
+#else
+XkbGetKeyAction(xkbi,xkbState,key)
+ XkbSrvInfoPtr xkbi;
+ XkbStatePtr xkbState;
+ CARD8 key;
+#endif
+{
+int effectiveGroup;
+int col;
+XkbDescPtr xkb;
+XkbKeyTypePtr type;
+XkbAction * pActs;
+static XkbAction fake;
+
+ xkb= xkbi->desc;
+ if (!XkbKeyHasActions(xkb,key)) {
+ fake.type = XkbSA_NoAction;
+ return fake;
+ }
+ pActs= XkbKeyActionsPtr(xkb,key);
+ col= 0;
+ effectiveGroup= xkbState->group;
+ if (effectiveGroup!=XkbGroup1Index) {
+ if (XkbKeyNumGroups(xkb,key)>(unsigned)1) {
+ if (effectiveGroup>=XkbKeyNumGroups(xkb,key)) {
+ unsigned gi= XkbKeyGroupInfo(xkb,key);
+ switch (XkbOutOfRangeGroupAction(gi)) {
+ default:
+ case XkbWrapIntoRange:
+ effectiveGroup %= XkbKeyNumGroups(xkb,key);
+ break;
+ case XkbClampIntoRange:
+ effectiveGroup = XkbKeyNumGroups(xkb,key)-1;
+ break;
+ case XkbRedirectIntoRange:
+ effectiveGroup= XkbOutOfRangeGroupInfo(gi);
+ if (effectiveGroup>=XkbKeyNumGroups(xkb,key))
+ effectiveGroup= 0;
+ break;
+ }
+ }
+ }
+ else effectiveGroup= XkbGroup1Index;
+ col+= (effectiveGroup*XkbKeyGroupsWidth(xkb,key));
+ }
+ type= XkbKeyKeyType(xkb,key,effectiveGroup);
+ if (type->map!=NULL) {
+ register unsigned i,mods;
+ register XkbKTMapEntryPtr entry;
+ mods= xkbState->mods&type->mods.mask;
+ for (entry= type->map,i=0;i<type->map_count;i++,entry++) {
+ if ((entry->active)&&(entry->mods.mask==mods)) {
+ col+= entry->level;
+ break;
+ }
+ }
+ }
+ if (pActs[col].any.type==XkbSA_NoAction)
+ return pActs[col];
+ fake= _FixUpAction(xkb,&pActs[col]);
+ return fake;
+}
+
+XkbAction
+#if NeedFunctionPrototypes
+XkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button)
+#else
+XkbGetButtonAction(kbd,dev,button)
+ DeviceIntPtr kbd;
+ DeviceIntPtr dev;
+ int button;
+#endif
+{
+XkbAction fake;
+ if ((dev->button)&&(dev->button->xkb_acts)) {
+ if (dev->button->xkb_acts[button-1].any.type!=XkbSA_NoAction) {
+ fake= _FixUpAction(kbd->key->xkbInfo->desc,
+ &dev->button->xkb_acts[button-1]);
+ return fake;
+ }
+ }
+ fake.any.type= XkbSA_NoAction;
+ return fake;
+}
+
+/***====================================================================***/
+
+#define SYNTHETIC_KEYCODE 1
+#define BTN_ACT_FLAG 0x100
+
+typedef struct _XkbFilter {
+ CARD16 keycode;
+ CARD8 what;
+ CARD8 active;
+ CARD8 filterOthers;
+ CARD32 priv;
+ XkbAction upAction;
+ int (*filter)(
+#if NeedFunctionPrototypes
+ XkbSrvInfoPtr /* xkbi */,
+ struct _XkbFilter * /* filter */,
+ unsigned /* keycode */,
+ XkbAction * /* action */
+#endif
+ );
+ struct _XkbFilter *next;
+} XkbFilterRec,*XkbFilterPtr;
+
+static int
+#if NeedFunctionPrototypes
+_XkbFilterSetState( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction *pAction)
+#else
+_XkbFilterSetState(xkbi,filter,keycode,pAction)
+ XkbSrvInfoPtr xkbi;
+ XkbFilterPtr filter;
+ unsigned keycode;
+ XkbAction * pAction;
+#endif
+{
+
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = ((pAction->mods.mask&XkbSA_ClearLocks)!=0);
+ filter->priv = 0;
+ filter->filter = _XkbFilterSetState;
+ if (pAction->type==XkbSA_SetMods) {
+ filter->upAction = *pAction;
+ xkbi->setMods= pAction->mods.mask;
+ }
+ else {
+ xkbi->groupChange = XkbSAGroup(&pAction->group);
+ if (pAction->group.flags&XkbSA_GroupAbsolute)
+ xkbi->groupChange-= xkbi->state.base_group;
+ filter->upAction= *pAction;
+ XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
+ }
+ }
+ else if (filter->keycode==keycode) {
+ if (filter->upAction.type==XkbSA_SetMods) {
+ xkbi->clearMods = filter->upAction.mods.mask;
+ if (filter->upAction.mods.flags&XkbSA_ClearLocks) {
+ xkbi->state.locked_mods&= ~filter->upAction.mods.mask;
+ }
+ }
+ else {
+ if (filter->upAction.group.flags&XkbSA_ClearLocks) {
+ xkbi->state.locked_group = 0;
+ }
+ xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
+ }
+ filter->active = 0;
+ }
+ else {
+ filter->upAction.mods.flags&= ~XkbSA_ClearLocks;
+ filter->filterOthers = 0;
+ }
+ return 1;
+}
+
+#define LATCH_KEY_DOWN 1
+#define LATCH_PENDING 2
+#define NO_LATCH 3
+
+static int
+#if NeedFunctionPrototypes
+_XkbFilterLatchState( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+#else
+_XkbFilterLatchState(xkbi,filter,keycode,pAction)
+ XkbSrvInfoPtr xkbi;
+ XkbFilterPtr filter;
+ unsigned keycode;
+ XkbAction * pAction;
+#endif
+{
+
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 1;
+ filter->priv = LATCH_KEY_DOWN;
+ filter->filter = _XkbFilterLatchState;
+ if (pAction->type==XkbSA_LatchMods) {
+ filter->upAction = *pAction;
+ xkbi->setMods = pAction->mods.mask;
+ }
+ else {
+ xkbi->groupChange = XkbSAGroup(&pAction->group);
+ if (pAction->group.flags&XkbSA_GroupAbsolute)
+ xkbi->groupChange-= xkbi->state.base_group;
+ filter->upAction= *pAction;
+ XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
+ }
+ }
+ else if ( pAction && (filter->priv==LATCH_PENDING) ) {
+ if (((1<<pAction->type)&XkbSA_BreakLatch)!=0) {
+ filter->active = 0;
+ if (filter->upAction.type==XkbSA_LatchMods)
+ xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
+ else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
+ }
+ else if ((pAction->type==filter->upAction.type)&&
+ (pAction->mods.flags==filter->upAction.mods.flags)&&
+ (pAction->mods.mask==filter->upAction.mods.mask)) {
+ if (filter->upAction.mods.flags&XkbSA_LatchToLock) {
+ XkbControlsPtr ctrls= xkbi->desc->ctrls;
+ if (filter->upAction.type==XkbSA_LatchMods)
+ pAction->mods.type= XkbSA_LockMods;
+ else pAction->group.type= XkbSA_LockGroup;
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)&&
+ (ctrls->enabled_ctrls&XkbStickyKeysMask)) {
+ XkbDDXAccessXBeep(xkbi->device,_BEEP_STICKY_LOCK,
+ XkbStickyKeysMask);
+ }
+ }
+ else {
+ if (filter->upAction.type==XkbSA_LatchMods)
+ pAction->mods.type= XkbSA_SetMods;
+ else pAction->group.type= XkbSA_SetGroup;
+ }
+ if (filter->upAction.type==XkbSA_LatchMods)
+ xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
+ else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
+ filter->active = 0;
+ }
+ }
+ else if (filter->keycode==keycode) { /* release */
+ XkbControlsPtr ctrls= xkbi->desc->ctrls;
+ int needBeep;
+ int beepType= _BEEP_NONE;
+
+ needBeep= ((ctrls->enabled_ctrls&XkbStickyKeysMask)&&
+ XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask));
+ if (filter->upAction.type==XkbSA_LatchMods) {
+ xkbi->clearMods = filter->upAction.mods.mask;
+ if ((filter->upAction.mods.flags&XkbSA_ClearLocks)&&
+ (xkbi->clearMods&xkbi->state.locked_mods)==xkbi->clearMods) {
+ xkbi->state.locked_mods&= ~xkbi->clearMods;
+ filter->priv= NO_LATCH;
+ beepType= _BEEP_STICKY_UNLOCK;
+ }
+ }
+ else {
+ xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
+ if ((filter->upAction.group.flags&XkbSA_ClearLocks)&&
+ (xkbi->state.locked_group)) {
+ xkbi->state.locked_group = 0;
+ filter->priv = NO_LATCH;
+ beepType= _BEEP_STICKY_UNLOCK;
+ }
+ }
+ if (filter->priv==NO_LATCH) {
+ filter->active= 0;
+ }
+ else {
+ filter->priv= LATCH_PENDING;
+ if (filter->upAction.type==XkbSA_LatchMods) {
+ xkbi->state.latched_mods |= filter->upAction.mods.mask;
+ needBeep = xkbi->state.latched_mods ? needBeep : 0;
+ xkbi->state.latched_mods |= filter->upAction.mods.mask;
+ }
+ else {
+ xkbi->state.latched_group+= XkbSAGroup(&filter->upAction.group);
+ }
+ if (needBeep && (beepType==_BEEP_NONE))
+ beepType= _BEEP_STICKY_LATCH;
+ }
+ if (needBeep && (beepType!=_BEEP_NONE))
+ XkbDDXAccessXBeep(xkbi->device,beepType,XkbStickyKeysMask);
+ }
+ else if (filter->priv==LATCH_KEY_DOWN) {
+ filter->priv= NO_LATCH;
+ filter->filterOthers = 0;
+ }
+ return 1;
+}
+
+static int
+#if NeedFunctionPrototypes
+_XkbFilterLockState( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+#else
+_XkbFilterLockState(xkbi,filter,keycode,pAction)
+ XkbSrvInfoPtr xkbi;
+ XkbFilterPtr filter;
+ unsigned keycode;
+ XkbAction * pAction;
+#endif
+{
+
+ if (pAction&&(pAction->type==XkbSA_LockGroup)) {
+ if (pAction->group.flags&XkbSA_GroupAbsolute)
+ xkbi->state.locked_group= XkbSAGroup(&pAction->group);
+ else xkbi->state.locked_group+= XkbSAGroup(&pAction->group);
+ return 1;
+ }
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv = 0;
+ filter->filter = _XkbFilterLockState;
+ filter->upAction = *pAction;
+ xkbi->state.locked_mods^= pAction->mods.mask;
+ xkbi->setMods = pAction->mods.mask;
+ }
+ else if (filter->keycode==keycode) {
+ filter->active = 0;
+ xkbi->clearMods = filter->upAction.mods.mask;
+ }
+ return 1;
+}
+
+#define ISO_KEY_DOWN 0
+#define NO_ISO_LOCK 1
+
+static int
+#if NeedFunctionPrototypes
+_XkbFilterISOLock( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+#else
+_XkbFilterISOLock(xkbi,filter,keycode,pAction)
+ XkbSrvInfoPtr xkbi;
+ XkbFilterPtr filter;
+ unsigned keycode;
+ XkbAction * pAction;
+#endif
+{
+
+ if (filter->keycode==0) { /* initial press */
+ CARD8 flags= pAction->iso.flags;
+
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 1;
+ filter->priv = ISO_KEY_DOWN;
+ filter->upAction = *pAction;
+ filter->filter = _XkbFilterISOLock;
+ if (flags&XkbSA_ISODfltIsGroup) {
+ xkbi->groupChange = XkbSAGroup(&pAction->iso);
+ xkbi->setMods = 0;
+ }
+ else {
+ xkbi->setMods = pAction->iso.mask;
+ xkbi->groupChange = 0;
+ }
+ if ((!(flags&XkbSA_ISONoAffectMods))&&(xkbi->state.base_mods)) {
+ filter->priv= NO_ISO_LOCK;
+ xkbi->state.locked_mods^= xkbi->state.base_mods;
+ }
+ if ((!(flags&XkbSA_ISONoAffectGroup))&&(xkbi->state.base_group)) {
+/* 6/22/93 (ef) -- lock groups if group key is down first */
+ }
+ if (!(flags&XkbSA_ISONoAffectPtr)) {
+/* 6/22/93 (ef) -- lock mouse buttons if they're down */
+ }
+ }
+ else if (filter->keycode==keycode) {
+ CARD8 flags= filter->upAction.iso.flags;
+
+ if (flags&XkbSA_ISODfltIsGroup) {
+ xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso);
+ xkbi->clearMods = 0;
+ if (filter->priv==ISO_KEY_DOWN)
+ xkbi->state.locked_group+= XkbSAGroup(&filter->upAction.iso);
+ }
+ else {
+ xkbi->clearMods= filter->upAction.iso.mask;
+ xkbi->groupChange= 0;
+ if (filter->priv==ISO_KEY_DOWN)
+ xkbi->state.locked_mods^= filter->upAction.iso.mask;
+ }
+ filter->active = 0;
+ }
+ else if (pAction) {
+ CARD8 flags= filter->upAction.iso.flags;
+
+ switch (pAction->type) {
+ case XkbSA_SetMods: case XkbSA_LatchMods:
+ if (!(flags&XkbSA_ISONoAffectMods)) {
+ pAction->type= XkbSA_LockMods;
+ filter->priv= NO_ISO_LOCK;
+ }
+ break;
+ case XkbSA_SetGroup: case XkbSA_LatchGroup:
+ if (!(flags&XkbSA_ISONoAffectGroup)) {
+ pAction->type= XkbSA_LockGroup;
+ filter->priv= NO_ISO_LOCK;
+ }
+ break;
+ case XkbSA_PtrBtn:
+ if (!(flags&XkbSA_ISONoAffectPtr)) {
+ pAction->type= XkbSA_LockPtrBtn;
+ filter->priv= NO_ISO_LOCK;
+ }
+ break;
+ case XkbSA_SetControls:
+ if (!(flags&XkbSA_ISONoAffectCtrls)) {
+ pAction->type= XkbSA_LockControls;
+ filter->priv= NO_ISO_LOCK;
+ }
+ break;
+ }
+ }
+ return 1;
+}
+
+
+static CARD32
+#if NeedFunctionPrototypes
+_XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,pointer arg)
+#else
+_XkbPtrAccelExpire(timer,now,arg)
+ OsTimerPtr timer;
+ CARD32 now;
+ pointer arg;
+#endif
+{
+XkbSrvInfoPtr xkbi= (XkbSrvInfoPtr)arg;
+XkbControlsPtr ctrls= xkbi->desc->ctrls;
+int dx,dy;
+
+ if (xkbi->mouseKey==0)
+ return 0;
+
+ if (xkbi->mouseKeysAccel) {
+ if ((xkbi->mouseKeysCounter)<ctrls->mk_time_to_max) {
+ double step;
+ xkbi->mouseKeysCounter++;
+ step= xkbi->mouseKeysCurveFactor*
+ pow((double)xkbi->mouseKeysCounter,xkbi->mouseKeysCurve);
+ if (xkbi->mouseKeysDX<0)
+ dx= floor( ((double)xkbi->mouseKeysDX)*step );
+ else dx= ceil( ((double)xkbi->mouseKeysDX)*step );
+ if (xkbi->mouseKeysDY<0)
+ dy= floor( ((double)xkbi->mouseKeysDY)*step );
+ else dy= ceil( ((double)xkbi->mouseKeysDY)*step );
+ }
+ else {
+ dx= xkbi->mouseKeysDX*ctrls->mk_max_speed;
+ dy= xkbi->mouseKeysDY*ctrls->mk_max_speed;
+ }
+ if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteX)
+ dx= xkbi->mouseKeysDX;
+ if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteY)
+ dy= xkbi->mouseKeysDY;
+ }
+ else {
+ dx= xkbi->mouseKeysDX;
+ dy= xkbi->mouseKeysDY;
+ }
+ XkbDDXFakePointerMotion(xkbi->mouseKeysFlags,dx,dy);
+ return xkbi->desc->ctrls->mk_interval;
+}
+
+static int
+#if NeedFunctionPrototypes
+_XkbFilterPointerMove( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+#else
+_XkbFilterPointerMove(xkbi,filter,keycode,pAction)
+ XkbSrvInfoPtr xkbi;
+ XkbFilterPtr filter;
+ unsigned keycode;
+ XkbAction * pAction;
+#endif
+{
+int x,y;
+Bool accel;
+
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv=0;
+ filter->filter = _XkbFilterPointerMove;
+ filter->upAction= *pAction;
+ xkbi->mouseKeysCounter= 0;
+ xkbi->mouseKey= keycode;
+ accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0);
+ x= XkbPtrActionX(&pAction->ptr);
+ y= XkbPtrActionY(&pAction->ptr);
+ XkbDDXFakePointerMotion(pAction->ptr.flags,x,y);
+ AccessXCancelRepeatKey(xkbi,keycode);
+ xkbi->mouseKeysAccel= accel&&
+ (xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask);
+ if (xkbi->mouseKeysAccel) {
+ xkbi->mouseKeysFlags= pAction->ptr.flags;
+ xkbi->mouseKeysDX= XkbPtrActionX(&pAction->ptr);
+ xkbi->mouseKeysDY= XkbPtrActionY(&pAction->ptr);
+ xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0,
+ xkbi->desc->ctrls->mk_delay,
+ _XkbPtrAccelExpire,(pointer)xkbi);
+ }
+ }
+ else if (filter->keycode==keycode) {
+ filter->active = 0;
+ if (xkbi->mouseKey==keycode) {
+ xkbi->mouseKey= 0;
+ xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 0,
+ NULL, NULL);
+ }
+ }
+ return 0;
+}
+
+static int
+#if NeedFunctionPrototypes
+_XkbFilterPointerBtn( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+#else
+_XkbFilterPointerBtn(xkbi,filter,keycode,pAction)
+ XkbSrvInfoPtr xkbi;
+ XkbFilterPtr filter;
+ unsigned keycode;
+ XkbAction * pAction;
+#endif
+{
+ if (filter->keycode==0) { /* initial press */
+ int button= pAction->btn.button;
+
+ if (button==XkbSA_UseDfltButton)
+ button = xkbi->desc->ctrls->mk_dflt_btn;
+
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv=0;
+ filter->filter = _XkbFilterPointerBtn;
+ filter->upAction= *pAction;
+ filter->upAction.btn.button= button;
+ switch (pAction->type) {
+ case XkbSA_LockPtrBtn:
+ if (((xkbi->lockedPtrButtons&(1<<button))==0)&&
+ ((pAction->btn.flags&XkbSA_LockNoLock)==0)) {
+ xkbi->lockedPtrButtons|= (1<<button);
+ AccessXCancelRepeatKey(xkbi,keycode);
+ XkbDDXFakePointerButton(ButtonPress,button);
+ filter->upAction.type= XkbSA_NoAction;
+ }
+ break;
+ case XkbSA_PtrBtn:
+ {
+ register int i,nClicks;
+ AccessXCancelRepeatKey(xkbi,keycode);
+ if (pAction->btn.count>0) {
+ nClicks= pAction->btn.count;
+ for (i=0;i<nClicks;i++) {
+ XkbDDXFakePointerButton(ButtonPress,button);
+ XkbDDXFakePointerButton(ButtonRelease,button);
+ }
+ filter->upAction.type= XkbSA_NoAction;
+ }
+ else XkbDDXFakePointerButton(ButtonPress,button);
+ }
+ break;
+ case XkbSA_SetPtrDflt:
+ {
+ XkbControlsPtr ctrls= xkbi->desc->ctrls;
+ XkbControlsRec old;
+ xkbControlsNotify cn;
+
+ old= *ctrls;
+ AccessXCancelRepeatKey(xkbi,keycode);
+ switch (pAction->dflt.affect) {
+ case XkbSA_AffectDfltBtn:
+ if (pAction->dflt.flags&XkbSA_DfltBtnAbsolute)
+ ctrls->mk_dflt_btn=
+ XkbSAPtrDfltValue(&pAction->dflt);
+ else {
+ ctrls->mk_dflt_btn+=
+ XkbSAPtrDfltValue(&pAction->dflt);
+ if (ctrls->mk_dflt_btn>5)
+ ctrls->mk_dflt_btn= 5;
+ else if (ctrls->mk_dflt_btn<1)
+ ctrls->mk_dflt_btn= 1;
+ }
+ break;
+ default:
+ ErrorF(
+ "Attempt to change unknown pointer default (%d) ignored\n",
+ pAction->dflt.affect);
+ break;
+ }
+ if (XkbComputeControlsNotify(xkbi->device,
+ &old,xkbi->desc->ctrls,
+ &cn,False)) {
+ cn.keycode = keycode;
+ cn.eventType = KeyPress;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ XkbSendControlsNotify(xkbi->device,&cn);
+ }
+ }
+ break;
+ }
+ }
+ else if (filter->keycode==keycode) {
+ int button= filter->upAction.btn.button;
+
+ switch (filter->upAction.type) {
+ case XkbSA_LockPtrBtn:
+ if (((filter->upAction.btn.flags&XkbSA_LockNoUnlock)!=0)||
+ ((xkbi->lockedPtrButtons&(1<<button))==0)) {
+ break;
+ }
+ xkbi->lockedPtrButtons&= ~(1<<button);
+ case XkbSA_PtrBtn:
+ XkbDDXFakePointerButton(ButtonRelease,button);
+ break;
+ }
+ filter->active = 0;
+ }
+ return 0;
+}
+
+static int
+#if NeedFunctionPrototypes
+_XkbFilterControls( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+#else
+_XkbFilterControls(xkbi,filter,keycode,pAction)
+ XkbSrvInfoPtr xkbi;
+ XkbFilterPtr filter;
+ unsigned keycode;
+ XkbAction * pAction;
+#endif
+{
+XkbControlsRec old;
+XkbControlsPtr ctrls;
+DeviceIntPtr kbd;
+unsigned int change;
+XkbEventCauseRec cause;
+
+ kbd= xkbi->device;
+ ctrls= xkbi->desc->ctrls;
+ old= *ctrls;
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ change= XkbActionCtrls(&pAction->ctrls);
+ filter->priv = change;
+ filter->filter = _XkbFilterControls;
+ filter->upAction = *pAction;
+
+ if (pAction->type==XkbSA_LockControls) {
+ filter->priv= (ctrls->enabled_ctrls&change);
+ change&= ~ctrls->enabled_ctrls;
+ }
+
+ if (change) {
+ xkbControlsNotify cn;
+ XkbSrvLedInfoPtr sli;
+
+ ctrls->enabled_ctrls|= change;
+ if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,False)) {
+ cn.keycode = keycode;
+ cn.eventType = KeyPress;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ XkbSendControlsNotify(kbd,&cn);
+ }
+
+ XkbSetCauseKey(&cause,keycode,KeyPress);
+
+ /* If sticky keys were disabled, clear all locks and latches */
+ if ((old.enabled_ctrls&XkbStickyKeysMask)&&
+ (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
+ XkbClearAllLatchesAndLocks(kbd,xkbi,False,&cause);
+ }
+ sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(kbd,sli->usesControls,True,NULL,&cause);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
+ XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_ON,change);
+ }
+ }
+ else if (filter->keycode==keycode) {
+ change= filter->priv;
+ if (change) {
+ xkbControlsNotify cn;
+ XkbSrvLedInfoPtr sli;
+
+ ctrls->enabled_ctrls&= ~change;
+ if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,False)) {
+ cn.keycode = keycode;
+ cn.eventType = KeyRelease;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ XkbSendControlsNotify(kbd,&cn);
+ }
+
+ XkbSetCauseKey(&cause,keycode,KeyRelease);
+ /* If sticky keys were disabled, clear all locks and latches */
+ if ((old.enabled_ctrls&XkbStickyKeysMask)&&
+ (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
+ XkbClearAllLatchesAndLocks(kbd,xkbi,False,&cause);
+ }
+ sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(kbd,sli->usesControls,True,NULL,&cause);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
+ XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_OFF,change);
+ }
+ filter->keycode= 0;
+ filter->active= 0;
+ }
+ return 0;
+}
+
+static int
+#if NeedFunctionPrototypes
+_XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+#else
+_XkbFilterActionMessage(xkbi,filter,keycode,pAction)
+ XkbSrvInfoPtr xkbi;
+ XkbFilterPtr filter;
+ unsigned keycode;
+ XkbAction * pAction;
+#endif
+{
+XkbMessageAction * pMsg;
+DeviceIntPtr kbd;
+
+ kbd= xkbi->device;
+ if (filter->keycode==0) { /* initial press */
+ pMsg= &pAction->msg;
+ if ((pMsg->flags&XkbSA_MessageOnRelease)||
+ ((pMsg->flags&XkbSA_MessageGenKeyEvent)==0)) {
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv = 0;
+ filter->filter = _XkbFilterActionMessage;
+ filter->upAction = *pAction;
+ }
+ if (pMsg->flags&XkbSA_MessageOnPress) {
+ xkbActionMessage msg;
+
+ msg.keycode= keycode;
+ msg.press= 1;
+ msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
+ memcpy((char *)msg.message,
+ (char *)pMsg->message,XkbActionMessageLength);
+ XkbSendActionMessage(kbd,&msg);
+ }
+ return ((pAction->msg.flags&XkbSA_MessageGenKeyEvent)!=0);
+ }
+ else if (filter->keycode==keycode) {
+ pMsg= &filter->upAction.msg;
+ if (pMsg->flags&XkbSA_MessageOnRelease) {
+ xkbActionMessage msg;
+
+ msg.keycode= keycode;
+ msg.press= 0;
+ msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
+ memcpy((char *)msg.message,(char *)pMsg->message,
+ XkbActionMessageLength);
+ XkbSendActionMessage(kbd,&msg);
+ }
+ filter->keycode= 0;
+ filter->active= 0;
+ return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
+ }
+ return 0;
+}
+
+static int
+#if NeedFunctionPrototypes
+_XkbFilterRedirectKey( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+#else
+_XkbFilterRedirectKey(xkbi,filter,keycode,pAction)
+ XkbSrvInfoPtr xkbi;
+ XkbFilterPtr filter;
+ unsigned keycode;
+ XkbAction * pAction;
+#endif
+{
+unsigned realMods;
+xEvent ev;
+int x,y,kc;
+XkbStateRec old;
+unsigned mods,mask,oldCoreState,oldCorePrevState;
+
+ if ((filter->keycode!=0)&&(filter->keycode!=keycode))
+ return 0;
+
+ GetSpritePosition(&x,&y);
+ ev.u.keyButtonPointer.time = GetTimeInMillis();
+ ev.u.keyButtonPointer.rootX = x;
+ ev.u.keyButtonPointer.rootY = y;
+
+ mask= XkbSARedirectVModsMask(&pAction->redirect);
+ mods= XkbSARedirectVMods(&pAction->redirect);
+ if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask);
+ if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods);
+ mask|= pAction->redirect.mods_mask;
+ mods|= pAction->redirect.mods;
+
+ if (filter->keycode==0) { /* initial press */
+ if ((pAction->redirect.new_key<xkbi->desc->min_key_code)||
+ (pAction->redirect.new_key>xkbi->desc->max_key_code)) {
+ return 1;
+ }
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv = 0;
+ filter->filter = _XkbFilterRedirectKey;
+ filter->upAction = *pAction;
+
+ ev.u.u.type = KeyPress;
+ ev.u.u.detail = pAction->redirect.new_key;
+
+ if ( mask || mods ) {
+ old= xkbi->state;
+ oldCoreState= xkbi->device->key->state;
+ oldCorePrevState= xkbi->device->key->prev_state;
+ xkbi->state.base_mods&= ~mask;
+ xkbi->state.base_mods|= (mods&mask);
+ xkbi->state.latched_mods&= ~mask;
+ xkbi->state.latched_mods|= (mods&mask);
+ xkbi->state.locked_mods&= ~mask;
+ xkbi->state.locked_mods|= (mods&mask);
+ XkbComputeDerivedState(xkbi);
+ xkbi->device->key->state= xkbi->device->key->prev_state=
+ xkbi->state.mods;
+ }
+
+ realMods = xkbi->device->key->modifierMap[ev.u.u.detail];
+ xkbi->device->key->modifierMap[ev.u.u.detail] = 0;
+ CoreProcessKeyboardEvent(&ev,xkbi->device,1);
+ xkbi->device->key->modifierMap[ev.u.u.detail] = realMods;
+
+ if ( mask || mods ) {
+ xkbi->device->key->state= oldCoreState;
+ xkbi->device->key->prev_state= oldCorePrevState;
+ xkbi->state= old;
+ }
+
+ return 0;
+ }
+ else if (filter->keycode==keycode) {
+
+ ev.u.u.type = KeyRelease;
+ ev.u.u.detail = filter->upAction.redirect.new_key;
+
+ if ( mask || mods ) {
+ old= xkbi->state;
+ oldCoreState= xkbi->device->key->state;
+ oldCorePrevState= xkbi->device->key->prev_state;
+ xkbi->state.base_mods&= ~mask;
+ xkbi->state.base_mods|= (mods&mask);
+ xkbi->state.latched_mods&= ~mask;
+ xkbi->state.latched_mods|= (mods&mask);
+ xkbi->state.locked_mods&= ~mask;
+ xkbi->state.locked_mods|= (mods&mask);
+ XkbComputeDerivedState(xkbi);
+ xkbi->device->key->state= xkbi->device->key->prev_state=
+ xkbi->state.mods;
+ }
+
+ realMods = xkbi->device->key->modifierMap[ev.u.u.detail];
+ xkbi->device->key->modifierMap[ev.u.u.detail] = 0;
+ CoreProcessKeyboardEvent(&ev,xkbi->device,1);
+ xkbi->device->key->modifierMap[ev.u.u.detail] = realMods;
+
+ if ( mask || mods ) {
+ xkbi->device->key->state= oldCoreState;
+ xkbi->device->key->prev_state= oldCorePrevState;
+ xkbi->state= old;
+ }
+
+ filter->keycode= 0;
+ filter->active= 0;
+ return 0;
+ }
+ return 0;
+}
+
+#ifdef XINPUT
+
+static int
+#if NeedFunctionPrototypes
+_XkbFilterDeviceBtn( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+#else
+_XkbFilterDeviceBtn(xkbi,filter,keycode,pAction)
+ XkbSrvInfoPtr xkbi;
+ XkbFilterPtr filter;
+ unsigned keycode;
+ XkbAction * pAction;
+#endif
+{
+DeviceIntPtr dev;
+int button;
+
+ if (filter->keycode==0) { /* initial press */
+ dev= _XkbLookupButtonDevice(pAction->devbtn.device,NULL);
+ if ((!dev)||(!dev->public.on)||(&dev->public==LookupPointerDevice()))
+ return 1;
+
+ button= pAction->devbtn.button;
+ if ((button<1)||(button>dev->button->numButtons))
+ return 1;
+
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv=0;
+ filter->filter = _XkbFilterDeviceBtn;
+ filter->upAction= *pAction;
+ switch (pAction->type) {
+ case XkbSA_LockDeviceBtn:
+ if ((pAction->devbtn.flags&XkbSA_LockNoLock)||
+ (dev->button->down[button/8]&(1L<<(button%8))))
+ return 0;
+ XkbDDXFakeDeviceButton(dev,True,button);
+ filter->upAction.type= XkbSA_NoAction;
+ break;
+ case XkbSA_DeviceBtn:
+ if (pAction->devbtn.count>0) {
+ int nClicks,i;
+ nClicks= pAction->btn.count;
+ for (i=0;i<nClicks;i++) {
+ XkbDDXFakeDeviceButton(dev,True,button);
+ XkbDDXFakeDeviceButton(dev,False,button);
+ }
+ filter->upAction.type= XkbSA_NoAction;
+ }
+ else XkbDDXFakeDeviceButton(dev,True,button);
+ break;
+ }
+ }
+ else if (filter->keycode==keycode) {
+ int button;
+
+ filter->active= 0;
+ dev= _XkbLookupButtonDevice(filter->upAction.devbtn.device,NULL);
+ if ((!dev)||(!dev->public.on)||(&dev->public==LookupPointerDevice()))
+ return 1;
+
+ button= filter->upAction.btn.button;
+ switch (filter->upAction.type) {
+ case XkbSA_LockDeviceBtn:
+ if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)||
+ ((dev->button->down[button/8]&(1L<<(button%8)))==0))
+ return 0;
+ XkbDDXFakeDeviceButton(dev,False,button);
+ break;
+ case XkbSA_DeviceBtn:
+ XkbDDXFakeDeviceButton(dev,False,button);
+ break;
+ }
+ filter->active = 0;
+ }
+ return 0;
+}
+#endif
+
+static int szFilters = 0;
+static XkbFilterPtr filters = NULL;
+
+static XkbFilterPtr
+_XkbNextFreeFilter(
+#if NeedFunctionPrototypes
+ void
+#endif
+)
+{
+register int i;
+
+ if (szFilters==0) {
+ szFilters = 4;
+ filters = _XkbTypedCalloc(szFilters,XkbFilterRec);
+ /* 6/21/93 (ef) -- XXX! deal with allocation failure */
+ }
+ for (i=0;i<szFilters;i++) {
+ if (!filters[i].active) {
+ filters[i].keycode = 0;
+ return &filters[i];
+ }
+ }
+ szFilters*=2;
+ filters= _XkbTypedRealloc(filters,szFilters,XkbFilterRec);
+ /* 6/21/93 (ef) -- XXX! deal with allocation failure */
+ bzero(&filters[szFilters/2],(szFilters/2)*sizeof(XkbFilterRec));
+ return &filters[szFilters/2];
+}
+
+static int
+#if NeedFunctionPrototypes
+_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction)
+#else
+_XkbApplyFilters(xkbi,kc,pAction)
+ XkbSrvInfoPtr xkbi;
+ unsigned kc;
+ XkbAction * pAction;
+#endif
+{
+register int i,send;
+
+ send= 1;
+ for (i=0;i<szFilters;i++) {
+ if ((filters[i].active)&&(filters[i].filter))
+ send= ((*filters[i].filter)(xkbi,&filters[i],kc,pAction)&&send);
+ }
+ return send;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbHandleActions(DeviceIntPtr dev,DeviceIntPtr kbd,xEvent *xE,int count)
+#else
+XkbHandleActions(dev,kbd,xE,count)
+ DeviceIntPtr dev;
+ DeviceIntPtr kbd;
+ xEvent * xE;
+ int count;
+#endif
+{
+int key,bit,i;
+CARD8 realMods;
+XkbSrvInfoPtr xkbi;
+KeyClassPtr keyc;
+int changed,sendEvent;
+Bool genStateNotify;
+XkbStateRec oldState;
+XkbAction act;
+XkbFilterPtr filter;
+Bool keyEvent;
+Bool pressEvent;
+#ifdef XINPUT
+Bool xiEvent;
+#endif
+
+ keyc= kbd->key;
+ xkbi= keyc->xkbInfo;
+ key= xE->u.u.detail;
+ if ((xkbi->flags&_XkbStateNotifyInProgress)==0) {
+ oldState= xkbi->state;
+ xkbi->flags|= _XkbStateNotifyInProgress;
+ genStateNotify= True;
+ }
+ else genStateNotify= False;
+
+ xkbi->clearMods = xkbi->setMods = 0;
+ xkbi->groupChange = 0;
+
+ sendEvent = 1;
+#ifdef XINPUT
+ keyEvent= ((xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress)||
+ (xE->u.u.type==KeyRelease)||(xE->u.u.type==DeviceKeyRelease));
+ pressEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress)||
+ (xE->u.u.type==ButtonPress)||(xE->u.u.type==DeviceButtonPress);
+ xiEvent= (xE->u.u.type==DeviceKeyPress)||(xE->u.u.type==DeviceKeyRelease)||
+ (xE->u.u.type==DeviceButtonPress)||
+ (xE->u.u.type==DeviceButtonRelease);
+#else
+ keyEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease);
+ pressEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==ButtonPress);
+#endif
+
+ if (pressEvent) {
+ if (keyEvent)
+ act = XkbGetKeyAction(xkbi,&xkbi->state,key);
+ else {
+ act = XkbGetButtonAction(kbd,dev,key);
+ key|= BTN_ACT_FLAG;
+ }
+ sendEvent = _XkbApplyFilters(xkbi,key,&act);
+ if (sendEvent) {
+ switch (act.type) {
+ case XkbSA_SetMods:
+ case XkbSA_SetGroup:
+ filter = _XkbNextFreeFilter();
+ sendEvent = _XkbFilterSetState(xkbi,filter,key,&act);
+ break;
+ case XkbSA_LatchMods:
+ case XkbSA_LatchGroup:
+ filter = _XkbNextFreeFilter();
+ sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act);
+ break;
+ case XkbSA_LockMods:
+ case XkbSA_LockGroup:
+ filter = _XkbNextFreeFilter();
+ sendEvent=_XkbFilterLockState(xkbi,filter,key,&act);
+ break;
+ case XkbSA_ISOLock:
+ filter = _XkbNextFreeFilter();
+ sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act);
+ break;
+ case XkbSA_MovePtr:
+ filter = _XkbNextFreeFilter();
+ sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act);
+ break;
+ case XkbSA_PtrBtn:
+ case XkbSA_LockPtrBtn:
+ case XkbSA_SetPtrDflt:
+ filter = _XkbNextFreeFilter();
+ sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act);
+ break;
+ case XkbSA_Terminate:
+ sendEvent= XkbDDXTerminateServer(dev,key,&act);
+ break;
+ case XkbSA_SwitchScreen:
+ sendEvent= XkbDDXSwitchScreen(dev,key,&act);
+ break;
+ case XkbSA_SetControls:
+ case XkbSA_LockControls:
+ filter = _XkbNextFreeFilter();
+ sendEvent=_XkbFilterControls(xkbi,filter,key,&act);
+ break;
+ case XkbSA_ActionMessage:
+ filter = _XkbNextFreeFilter();
+ sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act);
+ break;
+ case XkbSA_RedirectKey:
+ filter = _XkbNextFreeFilter();
+ sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act);
+ break;
+#ifdef XINPUT
+ case XkbSA_DeviceBtn:
+ case XkbSA_LockDeviceBtn:
+ filter = _XkbNextFreeFilter();
+ sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act);
+ break;
+#endif
+ }
+ }
+ }
+ else {
+ if (!keyEvent)
+ key|= BTN_ACT_FLAG;
+ sendEvent = _XkbApplyFilters(xkbi,key,NULL);
+ }
+
+ if (xkbi->groupChange!=0)
+ xkbi->state.base_group+= xkbi->groupChange;
+ if (xkbi->setMods) {
+ for (i=0,bit=1; xkbi->setMods; i++,bit<<=1 ) {
+ if (xkbi->setMods&bit) {
+ keyc->modifierKeyCount[i]++;
+ xkbi->state.base_mods|= bit;
+ xkbi->setMods&= ~bit;
+ }
+ }
+ }
+ if (xkbi->clearMods) {
+ for (i=0,bit=1; xkbi->clearMods; i++,bit<<=1 ) {
+ if (xkbi->clearMods&bit) {
+ keyc->modifierKeyCount[i]--;
+ if (keyc->modifierKeyCount[i]<=0) {
+ xkbi->state.base_mods&= ~bit;
+ keyc->modifierKeyCount[i] = 0;
+ }
+ xkbi->clearMods&= ~bit;
+ }
+ }
+ }
+
+ if (sendEvent) {
+#ifdef XINPUT
+ if (xiEvent)
+ ProcessOtherEvent(xE,dev,count);
+ else
+#endif
+ if (keyEvent) {
+ realMods = keyc->modifierMap[key];
+ keyc->modifierMap[key] = 0;
+ CoreProcessKeyboardEvent(xE,dev,count);
+ keyc->modifierMap[key] = realMods;
+ }
+ else CoreProcessPointerEvent(xE,dev,count);
+ }
+ xkbi->prev_state= oldState;
+ XkbComputeDerivedState(xkbi);
+ keyc->prev_state= keyc->state;
+ keyc->state= XkbStateFieldFromRec(&xkbi->state);
+ changed = XkbStateChangedFlags(&oldState,&xkbi->state);
+ if (genStateNotify) {
+ if (changed) {
+ xkbStateNotify sn;
+ sn.keycode= key;
+ sn.eventType= xE->u.u.type;
+ sn.requestMajor = sn.requestMinor = 0;
+ sn.changed= changed;
+ XkbSendStateNotify(dev,&sn);
+ }
+ xkbi->flags&= ~_XkbStateNotifyInProgress;
+ }
+ changed= XkbIndicatorsToUpdate(dev,changed,False);
+ if (changed) {
+ XkbEventCauseRec cause;
+ XkbSetCauseKey(&cause,key,xE->u.u.type);
+ XkbUpdateIndicators(dev,changed,True,NULL,&cause);
+ }
+ return;
+}
+
+int
+#if NeedFunctionPrototypes
+XkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches)
+#else
+XkbLatchModifiers(pXDev,mask,latches)
+ DeviceIntPtr pXDev;
+ CARD8 mask;
+ CARD8 latches;
+#endif
+{
+XkbSrvInfoPtr xkbi;
+XkbFilterPtr filter;
+XkbAction act;
+unsigned clear;
+
+ if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
+ xkbi = pXDev->key->xkbInfo;
+ clear= (mask&(~latches));
+ xkbi->state.latched_mods&= ~clear;
+ /* Clear any pending latch to locks.
+ */
+ act.type = XkbSA_NoAction;
+ _XkbApplyFilters(xkbi,SYNTHETIC_KEYCODE,&act);
+ act.type = XkbSA_LatchMods;
+ act.mods.flags = 0;
+ act.mods.mask = mask&latches;
+ filter = _XkbNextFreeFilter();
+ _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
+ _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
+ return Success;
+ }
+ return BadValue;
+}
+
+int
+#if NeedFunctionPrototypes
+XkbLatchGroup(DeviceIntPtr pXDev,int group)
+#else
+XkbLatchGroup(pXDev,group)
+ DeviceIntPtr pXDev;
+ int group;
+#endif
+{
+XkbSrvInfoPtr xkbi;
+XkbFilterPtr filter;
+XkbAction act;
+
+ if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
+ xkbi = pXDev->key->xkbInfo;
+ act.type = XkbSA_LatchGroup;
+ act.group.flags = 0;
+ XkbSASetGroup(&act.group,group);
+ filter = _XkbNextFreeFilter();
+ _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
+ _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
+ return Success;
+ }
+ return BadValue;
+}
+
+/***====================================================================***/
+
+void
+#if NeedFunctionPrototypes
+XkbClearAllLatchesAndLocks( DeviceIntPtr dev,
+ XkbSrvInfoPtr xkbi,
+ Bool genEv,
+ XkbEventCausePtr cause)
+#else
+XkbClearAllLatchesAndLocks(dev,xkbi,genEv,cause)
+ DeviceIntPtr dev;
+ XkbSrvInfoPtr xkbi;
+ Bool genEv;
+ XkbEventCausePtr cause;
+#endif
+{
+XkbStateRec os;
+xkbStateNotify sn;
+
+ sn.changed= 0;
+ os= xkbi->state;
+ if (os.latched_mods) { /* clear all latches */
+ XkbLatchModifiers(dev,~0,0);
+ sn.changed|= XkbModifierLatchMask;
+ }
+ if (os.latched_group) {
+ XkbLatchGroup(dev,0);
+ sn.changed|= XkbGroupLatchMask;
+ }
+ if (os.locked_mods) {
+ xkbi->state.locked_mods= 0;
+ sn.changed|= XkbModifierLockMask;
+ }
+ if (os.locked_group) {
+ xkbi->state.locked_group= 0;
+ sn.changed|= XkbGroupLockMask;
+ }
+ if ( genEv && sn.changed) {
+ CARD32 changed;
+
+ XkbComputeDerivedState(xkbi);
+ sn.keycode= cause->kc;
+ sn.eventType= cause->event;
+ sn.requestMajor= cause->mjr;
+ sn.requestMinor= cause->mnr;
+ sn.changed= XkbStateChangedFlags(&os,&xkbi->state);
+ XkbSendStateNotify(dev,&sn);
+ changed= XkbIndicatorsToUpdate(dev,sn.changed,False);
+ if (changed) {
+ XkbUpdateIndicators(dev,changed,True,NULL,cause);
+ }
+ }
+ return;
+}
+
diff --git a/xc/programs/Xserver/xkb/xkbDflts.h b/xc/programs/Xserver/xkb/xkbDflts.h
new file mode 100644
index 000000000..b24637070
--- /dev/null
+++ b/xc/programs/Xserver/xkb/xkbDflts.h
@@ -0,0 +1,519 @@
+/* $XConsortium: xkbDflts.h /main/6 1995/12/07 21:22:44 kaleb $ */
+/* This file generated automatically by xkbcomp */
+/* DO NOT EDIT */
+#ifndef DEFAULT_H
+#define DEFAULT_H 1
+
+#ifndef XKB_IN_SERVER
+#define GET_ATOM(d,s) XInternAtom(d,s,0)
+#define DPYTYPE Display *
+#else
+#define GET_ATOM(d,s) MakeAtom(s,strlen(s),1)
+#define DPYTYPE char *
+#endif
+#define NUM_KEYS 1
+
+#define vmod_NumLock 0
+#define vmod_Alt 1
+#define vmod_LevelThree 2
+#define vmod_AltGr 3
+#define vmod_ScrollLock 4
+
+#define vmod_NumLockMask (1<<0)
+#define vmod_AltMask (1<<1)
+#define vmod_LevelThreeMask (1<<2)
+#define vmod_AltGrMask (1<<3)
+#define vmod_ScrollLockMask (1<<4)
+
+/* types name is "default" */
+static Atom lnames_ONE_LEVEL[1];
+
+static XkbKTMapEntryRec map_TWO_LEVEL[1]= {
+ { 1, 1, { ShiftMask, ShiftMask, 0 } }
+};
+static Atom lnames_TWO_LEVEL[2];
+
+static XkbKTMapEntryRec map_ALPHABETIC[2]= {
+ { 1, 1, { ShiftMask, ShiftMask, 0 } },
+ { 1, 0, { LockMask, LockMask, 0 } }
+};
+static XkbModsRec preserve_ALPHABETIC[2]= {
+ { 0, 0, 0 },
+ { LockMask, LockMask, 0 }
+};
+static Atom lnames_ALPHABETIC[2];
+
+static XkbKTMapEntryRec map_KEYPAD[2]= {
+ { 1, 1, { ShiftMask, ShiftMask, 0 } },
+ { 0, 1, { 0, 0, vmod_NumLockMask } }
+};
+static Atom lnames_KEYPAD[2];
+
+static XkbKTMapEntryRec map_PC_BREAK[1]= {
+ { 1, 1, { ControlMask, ControlMask, 0 } }
+};
+static Atom lnames_PC_BREAK[2];
+
+static XkbKTMapEntryRec map_PC_SYSRQ[1]= {
+ { 0, 1, { 0, 0, vmod_AltMask } }
+};
+static Atom lnames_PC_SYSRQ[2];
+
+static XkbKTMapEntryRec map_CTRL_ALT[1]= {
+ { 0, 1, { ControlMask, ControlMask, vmod_AltMask } }
+};
+static Atom lnames_CTRL_ALT[2];
+
+static XkbKTMapEntryRec map_THREE_LEVEL[3]= {
+ { 1, 1, { ShiftMask, ShiftMask, 0 } },
+ { 0, 2, { 0, 0, vmod_LevelThreeMask } },
+ { 0, 2, { ShiftMask, ShiftMask, vmod_LevelThreeMask } }
+};
+static Atom lnames_THREE_LEVEL[3];
+
+static XkbKTMapEntryRec map_SHIFT_ALT[1]= {
+ { 0, 1, { ShiftMask, ShiftMask, vmod_AltMask } }
+};
+static Atom lnames_SHIFT_ALT[2];
+
+static XkbKeyTypeRec dflt_types[]= {
+ {
+ { 0, 0, 0 },
+ 1,
+ 0, NULL, NULL,
+ None, lnames_ONE_LEVEL
+ },
+ {
+ { ShiftMask, ShiftMask, 0 },
+ 2,
+ 1, map_TWO_LEVEL, NULL,
+ None, lnames_TWO_LEVEL
+ },
+ {
+ { ShiftMask|LockMask, ShiftMask|LockMask, 0 },
+ 2,
+ 2, map_ALPHABETIC, preserve_ALPHABETIC,
+ None, lnames_ALPHABETIC
+ },
+ {
+ { ShiftMask, ShiftMask, vmod_NumLockMask },
+ 2,
+ 2, map_KEYPAD, NULL,
+ None, lnames_KEYPAD
+ },
+ {
+ { ControlMask, ControlMask, 0 },
+ 2,
+ 1, map_PC_BREAK, NULL,
+ None, lnames_PC_BREAK
+ },
+ {
+ { 0, 0, vmod_AltMask },
+ 2,
+ 1, map_PC_SYSRQ, NULL,
+ None, lnames_PC_SYSRQ
+ },
+ {
+ { ControlMask, ControlMask, vmod_AltMask },
+ 2,
+ 1, map_CTRL_ALT, NULL,
+ None, lnames_CTRL_ALT
+ },
+ {
+ { ShiftMask, ShiftMask, vmod_LevelThreeMask },
+ 3,
+ 3, map_THREE_LEVEL, NULL,
+ None, lnames_THREE_LEVEL
+ },
+ {
+ { ShiftMask, ShiftMask, vmod_AltMask },
+ 2,
+ 1, map_SHIFT_ALT, NULL,
+ None, lnames_SHIFT_ALT
+ }
+};
+#define num_dflt_types (sizeof(dflt_types)/sizeof(XkbKeyTypeRec))
+
+
+static void
+#if NeedFunctionPrototypes
+initTypeNames(DPYTYPE dpy)
+#else
+initTypeNames(dpy)
+DPYTYPE dpy;
+#endif
+{
+ dflt_types[0].name= GET_ATOM(dpy,"ONE_LEVEL");
+ lnames_ONE_LEVEL[0]= GET_ATOM(dpy,"Any");
+ dflt_types[1].name= GET_ATOM(dpy,"TWO_LEVEL");
+ lnames_TWO_LEVEL[0]= GET_ATOM(dpy,"Base");
+ lnames_TWO_LEVEL[1]= GET_ATOM(dpy,"Shift");
+ dflt_types[2].name= GET_ATOM(dpy,"ALPHABETIC");
+ lnames_ALPHABETIC[0]= GET_ATOM(dpy,"Base");
+ lnames_ALPHABETIC[1]= GET_ATOM(dpy,"Caps");
+ dflt_types[3].name= GET_ATOM(dpy,"KEYPAD");
+ lnames_KEYPAD[0]= GET_ATOM(dpy,"Base");
+ lnames_KEYPAD[1]= GET_ATOM(dpy,"Number");
+ dflt_types[4].name= GET_ATOM(dpy,"PC_BREAK");
+ lnames_PC_BREAK[0]= GET_ATOM(dpy,"Base");
+ lnames_PC_BREAK[1]= GET_ATOM(dpy,"Control");
+ dflt_types[5].name= GET_ATOM(dpy,"PC_SYSRQ");
+ lnames_PC_SYSRQ[0]= GET_ATOM(dpy,"Base");
+ lnames_PC_SYSRQ[1]= GET_ATOM(dpy,"Alt");
+ dflt_types[6].name= GET_ATOM(dpy,"CTRL+ALT");
+ lnames_CTRL_ALT[0]= GET_ATOM(dpy,"Base");
+ lnames_CTRL_ALT[1]= GET_ATOM(dpy,"Ctrl+Alt");
+ dflt_types[7].name= GET_ATOM(dpy,"THREE_LEVEL");
+ lnames_THREE_LEVEL[0]= GET_ATOM(dpy,"Base");
+ lnames_THREE_LEVEL[1]= GET_ATOM(dpy,"Shift");
+ lnames_THREE_LEVEL[2]= GET_ATOM(dpy,"Level3");
+ dflt_types[8].name= GET_ATOM(dpy,"SHIFT+ALT");
+ lnames_SHIFT_ALT[0]= GET_ATOM(dpy,"Base");
+ lnames_SHIFT_ALT[1]= GET_ATOM(dpy,"Shift+Alt");
+}
+/* compat name is "default" */
+static XkbSymInterpretRec dfltSI[69]= {
+ { XK_ISO_Level2_Latch, 0x0000,
+ XkbSI_LevelOneOnly|XkbSI_Exactly, ShiftMask,
+ 255,
+ { XkbSA_LatchMods, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Eisu_Shift, 0x0000,
+ XkbSI_Exactly, LockMask,
+ 255,
+ { XkbSA_NoAction, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Eisu_toggle, 0x0000,
+ XkbSI_Exactly, LockMask,
+ 255,
+ { XkbSA_NoAction, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Kana_Shift, 0x0000,
+ XkbSI_Exactly, LockMask,
+ 255,
+ { XkbSA_NoAction, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Kana_Lock, 0x0000,
+ XkbSI_Exactly, LockMask,
+ 255,
+ { XkbSA_NoAction, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Shift_Lock, 0x0000,
+ XkbSI_AnyOf, ShiftMask|LockMask,
+ 255,
+ { XkbSA_LockMods, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Num_Lock, 0x0000,
+ XkbSI_AnyOf, 0xff,
+ 0,
+ { XkbSA_LockMods, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 } },
+ { XK_Alt_L, 0x0000,
+ XkbSI_AnyOf, 0xff,
+ 1,
+ { XkbSA_SetMods, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Alt_R, 0x0000,
+ XkbSI_AnyOf, 0xff,
+ 1,
+ { XkbSA_SetMods, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Scroll_Lock, 0x0000,
+ XkbSI_AnyOf, 0xff,
+ 4,
+ { XkbSA_LockMods, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_ISO_Lock, 0x0000,
+ XkbSI_AnyOf, 0xff,
+ 255,
+ { XkbSA_ISOLock, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_ISO_Level3_Shift, 0x0000,
+ XkbSI_LevelOneOnly|XkbSI_AnyOf, 0xff,
+ 2,
+ { XkbSA_SetMods, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00 } },
+ { XK_ISO_Level3_Latch, 0x0000,
+ XkbSI_LevelOneOnly|XkbSI_AnyOf, 0xff,
+ 2,
+ { XkbSA_LatchMods, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00 } },
+ { XK_Mode_switch, 0x0000,
+ XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff,
+ 3,
+ { XkbSA_SetGroup, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_1, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00 } },
+ { XK_KP_End, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00 } },
+ { XK_KP_2, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 } },
+ { XK_KP_Down, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 } },
+ { XK_KP_3, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00 } },
+ { XK_KP_Next, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00 } },
+ { XK_KP_4, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_Left, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_6, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_Right, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_7, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } },
+ { XK_KP_Home, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } },
+ { XK_KP_8, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 } },
+ { XK_KP_Up, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 } },
+ { XK_KP_9, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 } },
+ { XK_KP_Prior, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_MovePtr, 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00 } },
+ { XK_KP_5, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_Begin, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_F1, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_SetPtrDflt, 0x04, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_Divide, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_SetPtrDflt, 0x04, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_F2, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_SetPtrDflt, 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_Multiply, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_SetPtrDflt, 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_F3, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_SetPtrDflt, 0x04, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_Subtract, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_SetPtrDflt, 0x04, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_Separator, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_Add, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_0, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockPtrBtn, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_Insert, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockPtrBtn, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_Decimal, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockPtrBtn, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_KP_Delete, 0x0001,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockPtrBtn, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Pointer_Button_Dflt, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Pointer_Button1, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Pointer_Button2, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Pointer_Button3, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Pointer_DblClick_Dflt, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Pointer_DblClick1, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Pointer_DblClick2, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Pointer_DblClick3, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_PtrBtn, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Pointer_Drag_Dflt, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockPtrBtn, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Pointer_Drag1, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockPtrBtn, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Pointer_Drag2, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockPtrBtn, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Pointer_Drag3, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockPtrBtn, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Pointer_EnableKeys, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockControls, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00 } },
+ { XK_Pointer_Accelerate, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockControls, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00 } },
+ { XK_Pointer_DfltBtnNext, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_SetPtrDflt, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_Pointer_DfltBtnPrev, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_SetPtrDflt, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_AccessX_Enable, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockControls, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00 } },
+ { XK_Terminate_Server, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_Terminate, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_ISO_Group_Latch, 0x0000,
+ XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff,
+ 3,
+ { XkbSA_LatchGroup, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_ISO_Next_Group, 0x0000,
+ XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff,
+ 3,
+ { XkbSA_LockGroup, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_ISO_Prev_Group, 0x0000,
+ XkbSI_LevelOneOnly|XkbSI_AnyOfOrNone, 0xff,
+ 3,
+ { XkbSA_LockGroup, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_ISO_First_Group, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockGroup, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { XK_ISO_Last_Group, 0x0000,
+ XkbSI_AnyOfOrNone, 0xff,
+ 255,
+ { XkbSA_LockGroup, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 } },
+ { NoSymbol, 0x0000,
+ XkbSI_Exactly, LockMask,
+ 255,
+ { XkbSA_LockMods, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00 } },
+ { NoSymbol, 0x0000,
+ XkbSI_AnyOf, 0xff,
+ 255,
+ { XkbSA_SetMods, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
+};
+#define num_dfltSI (sizeof(dfltSI)/sizeof(XkbSymInterpretRec))
+
+static XkbCompatMapRec compatMap= {
+ dfltSI,
+ { /* group compatibility */
+ { 0, 0, 0 },
+ { 0, 0, vmod_AltGrMask },
+ { 0, 0, vmod_AltGrMask },
+ { 0, 0, vmod_AltGrMask }
+ },
+ num_dfltSI, num_dfltSI
+};
+
+static XkbIndicatorRec indicators= {
+ 0x0,
+ {
+ { 0x80, 0, 0x00, XkbIM_UseEffective, LockMask, LockMask, 0, 0 },
+ { 0x80, 0, 0x00, XkbIM_UseEffective, 0, 0, vmod_NumLockMask, 0 },
+ { 0x80, 0, 0x00, XkbIM_UseLocked, ShiftMask, ShiftMask, 0, 0 },
+ { 0x80, 0, 0x00, 0, 0, 0, 0, XkbMouseKeysMask },
+ { 0x80, 0, 0x00, XkbIM_UseLocked, 0, 0, vmod_ScrollLockMask, 0 },
+ { 0x80, XkbIM_UseEffective, 0xfe, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 },
+ { 0x00, 0, 0x00, 0, 0, 0, 0, 0 }
+ }
+};
+static void
+#if NeedFunctionPrototypes
+initIndicatorNames(DPYTYPE dpy,XkbDescPtr xkb)
+#else
+initIndicatorNames(dpy,xkb)
+ DPYTYPE dpy;
+ XkbDescPtr xkb;
+#endif
+{
+ xkb->names->indicators[ 0]= GET_ATOM(dpy,"Caps Lock");
+ xkb->names->indicators[ 1]= GET_ATOM(dpy,"Num Lock");
+ xkb->names->indicators[ 2]= GET_ATOM(dpy,"Shift Lock");
+ xkb->names->indicators[ 3]= GET_ATOM(dpy,"Mouse Keys");
+ xkb->names->indicators[ 4]= GET_ATOM(dpy,"Scroll Lock");
+ xkb->names->indicators[ 5]= GET_ATOM(dpy,"Group 2");
+}
+#endif /* DEFAULT_H */
diff --git a/xc/programs/Xserver/xkb/xkbEvents.c b/xc/programs/Xserver/xkb/xkbEvents.c
new file mode 100644
index 000000000..cc18dd974
--- /dev/null
+++ b/xc/programs/Xserver/xkb/xkbEvents.c
@@ -0,0 +1,1155 @@
+/* $TOG: xkbEvents.c /main/21 1997/11/25 12:31:37 kaleb $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+/* $XFree86: xc/programs/Xserver/xkb/xkbEvents.c,v 3.4 1997/12/14 02:55:42 dawes Exp $ */
+
+#include <stdio.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "XI.h"
+#include "inputstr.h"
+#include "windowstr.h"
+#include "XKBsrv.h"
+
+extern int (*InitialVector[3])();
+
+/***====================================================================***/
+
+void
+#if NeedFunctionPrototypes
+XkbSendNewKeyboardNotify(DeviceIntPtr kbd,xkbNewKeyboardNotify *pNKN)
+#else
+XkbSendNewKeyboardNotify(kbd,pNKN)
+ DeviceIntPtr kbd;
+ xkbNewKeyboardNotify * pNKN;
+#endif
+{
+register int i;
+Time time;
+CARD16 changed;
+XkbChangesRec changes;
+
+ pNKN->type = XkbEventCode + XkbEventBase;
+ pNKN->xkbType = XkbNewKeyboardNotify;
+ pNKN->time = time = GetTimeInMillis();
+ changed = pNKN->changed;
+
+ for (i=1; i<currentMaxClients; i++) {
+ if ((!clients[i]) || clients[i]->clientGone ||
+ (clients[i]->requestVector==InitialVector)) {
+ continue;
+ }
+
+ if (clients[i]->xkbClientFlags&_XkbClientInitialized) {
+ if (clients[i]->newKeyboardNotifyMask&changed) {
+ pNKN->sequenceNumber = clients[i]->sequence;
+ pNKN->time = time;
+ pNKN->changed = changed;
+ if ( clients[i]->swapped ) {
+ register int n;
+ swaps(&pNKN->sequenceNumber,n);
+ swapl(&pNKN->time,n);
+ swaps(&pNKN->changed,n);
+ }
+ WriteToClient(clients[i],sizeof(xEvent),(char *)pNKN);
+ if (changed&XkbNKN_KeycodesMask) {
+ clients[i]->minKC= pNKN->minKeyCode;
+ clients[i]->maxKC= pNKN->maxKeyCode;
+ }
+ }
+ }
+ else if (changed&XkbNKN_KeycodesMask) {
+ xEvent event;
+ event.u.u.type= MappingNotify;
+ event.u.mappingNotify.request= MappingKeyboard;
+ event.u.mappingNotify.firstKeyCode= clients[i]->minKC;
+ event.u.mappingNotify.count= clients[i]->maxKC-clients[i]->minKC+1;
+ event.u.u.sequenceNumber= clients[i]->sequence;
+ if (clients[i]->swapped) {
+ int n;
+ swaps(&event.u.u.sequenceNumber,n);
+ }
+ WriteToClient(clients[i],SIZEOF(xEvent), (char *)&event);
+ event.u.mappingNotify.request= MappingModifier;
+ WriteToClient(clients[i],SIZEOF(xEvent), (char *)&event);
+ }
+ }
+ return;
+}
+
+/***====================================================================***/
+
+void
+#if NeedFunctionPrototypes
+XkbSendStateNotify(DeviceIntPtr kbd,xkbStateNotify *pSN)
+#else
+XkbSendStateNotify(kbd,pSN)
+ DeviceIntPtr kbd;
+ xkbStateNotify *pSN;
+#endif
+{
+XkbSrvInfoPtr xkbi;
+XkbStatePtr state;
+XkbInterestPtr interest;
+Time time;
+register CARD16 changed,bState;
+
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+ xkbi = kbd->key->xkbInfo;
+ state= &xkbi->state;
+
+ pSN->type = XkbEventCode + XkbEventBase;
+ pSN->xkbType = XkbStateNotify;
+ pSN->deviceID = kbd->id;
+ pSN->time = time = GetTimeInMillis();
+ pSN->mods = state->mods;
+ pSN->baseMods = state->base_mods;
+ pSN->latchedMods = state->latched_mods;
+ pSN->lockedMods = state->locked_mods;
+ pSN->group = state->group;
+ pSN->baseGroup = state->base_group;
+ pSN->latchedGroup = state->latched_group;
+ pSN->lockedGroup = state->locked_group;
+ pSN->compatState = state->compat_state;
+ pSN->grabMods = state->grab_mods;
+ pSN->compatGrabMods = state->compat_grab_mods;
+ pSN->lookupMods = state->lookup_mods;
+ pSN->compatLookupMods = state->compat_lookup_mods;
+ pSN->ptrBtnState = state->ptr_buttons;
+ changed = pSN->changed;
+ bState= pSN->ptrBtnState;
+
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->stateNotifyMask&changed)) {
+ pSN->sequenceNumber = interest->client->sequence;
+ pSN->time = time;
+ pSN->changed = changed;
+ pSN->ptrBtnState = bState;
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&pSN->sequenceNumber,n);
+ swapl(&pSN->time,n);
+ swaps(&pSN->changed,n);
+ swaps(&pSN->ptrBtnState,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)pSN);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+/***====================================================================***/
+
+void
+#if NeedFunctionPrototypes
+XkbSendMapNotify(DeviceIntPtr kbd,xkbMapNotify *pMN)
+#else
+XkbSendMapNotify(kbd,pMN)
+ DeviceIntPtr kbd;
+ xkbMapNotify *pMN;
+#endif
+{
+int i;
+XkbSrvInfoPtr xkbi;
+unsigned time,initialized;
+CARD16 changed;
+
+ xkbi = kbd->key->xkbInfo;
+ initialized= 0;
+
+ changed = pMN->changed;
+ pMN->minKeyCode= xkbi->desc->min_key_code;
+ pMN->maxKeyCode= xkbi->desc->max_key_code;
+ for (i=1; i<currentMaxClients; i++) {
+ if (clients[i] && ! clients[i]->clientGone &&
+ (clients[i]->requestVector != InitialVector) &&
+ (clients[i]->xkbClientFlags&_XkbClientInitialized) &&
+ (clients[i]->mapNotifyMask&changed))
+ {
+ if (!initialized) {
+ pMN->type = XkbEventCode + XkbEventBase;
+ pMN->xkbType = XkbMapNotify;
+ pMN->deviceID = kbd->id;
+ time = GetTimeInMillis();
+ initialized= 1;
+ }
+ pMN->time= time;
+ pMN->sequenceNumber = clients[i]->sequence;
+ pMN->changed = changed;
+ if ( clients[i]->swapped ) {
+ register int n;
+ swaps(&pMN->sequenceNumber,n);
+ swapl(&pMN->time,n);
+ swaps(&pMN->changed,n);
+ }
+ WriteToClient(clients[i],sizeof(xEvent),(char *)pMN);
+ }
+ }
+ return;
+}
+
+int
+#if NeedFunctionPrototypes
+XkbComputeControlsNotify( DeviceIntPtr kbd,
+ XkbControlsPtr old,
+ XkbControlsPtr new,
+ xkbControlsNotify * pCN,
+ Bool forceCtrlProc)
+#else
+XkbComputeControlsNotify(kbd,old,new,pCN,forceCtrlProc)
+ DeviceIntPtr kbd;
+ XkbControlsPtr old;
+ XkbControlsPtr new;
+ xkbControlsNotify *pCN;
+ Bool forceCtrlProc;
+#endif
+{
+int i;
+CARD32 changedControls;
+
+ changedControls= 0;
+ if (old->enabled_ctrls!=new->enabled_ctrls)
+ changedControls|= XkbControlsEnabledMask;
+ if ((old->repeat_delay!=new->repeat_delay)||
+ (old->repeat_interval!=new->repeat_interval))
+ changedControls|= XkbRepeatKeysMask;
+ for (i = 0; i < XkbPerKeyBitArraySize; i++)
+ if (old->per_key_repeat[i] != new->per_key_repeat[i])
+ changedControls|= XkbPerKeyRepeatMask;
+ if (old->slow_keys_delay!=new->slow_keys_delay)
+ changedControls|= XkbSlowKeysMask;
+ if (old->debounce_delay!=new->debounce_delay)
+ changedControls|= XkbBounceKeysMask;
+ if ((old->mk_delay!=new->mk_delay)||
+ (old->mk_interval!=new->mk_interval)||
+ (old->mk_dflt_btn!=new->mk_dflt_btn))
+ changedControls|= XkbMouseKeysMask;
+ if ((old->mk_time_to_max!=new->mk_time_to_max)||
+ (old->mk_curve!=new->mk_curve)||
+ (old->mk_max_speed!=new->mk_max_speed))
+ changedControls|= XkbMouseKeysAccelMask;
+ if (old->ax_options!=new->ax_options)
+ changedControls|= XkbAccessXKeysMask;
+ if ((old->ax_timeout!=new->ax_timeout)||
+ (old->axt_ctrls_mask!=new->axt_ctrls_mask)||
+ (old->axt_ctrls_values!=new->axt_ctrls_values)||
+ (old->axt_opts_mask!=new->axt_opts_mask)||
+ (old->axt_opts_values!= new->axt_opts_values)) {
+ changedControls|= XkbAccessXTimeoutMask;
+ }
+ if ((old->internal.mask!=new->internal.mask)||
+ (old->internal.real_mods!=new->internal.real_mods)||
+ (old->internal.vmods!=new->internal.vmods))
+ changedControls|= XkbInternalModsMask;
+ if ((old->ignore_lock.mask!=new->ignore_lock.mask)||
+ (old->ignore_lock.real_mods!=new->ignore_lock.real_mods)||
+ (old->ignore_lock.vmods!=new->ignore_lock.vmods))
+ changedControls|= XkbIgnoreLockModsMask;
+
+ if (new->enabled_ctrls&XkbRepeatKeysMask)
+ kbd->kbdfeed->ctrl.autoRepeat=TRUE;
+ else kbd->kbdfeed->ctrl.autoRepeat=FALSE;
+
+ if (kbd->kbdfeed && kbd->kbdfeed->CtrlProc &&
+ (changedControls || forceCtrlProc))
+ (*kbd->kbdfeed->CtrlProc)(kbd, &kbd->kbdfeed->ctrl);
+
+ if ((!changedControls)&&(old->num_groups==new->num_groups))
+ return 0;
+
+ if (!kbd->xkb_interest)
+ return 0;
+
+ pCN->changedControls = changedControls;
+ pCN->enabledControls = new->enabled_ctrls;
+ pCN->enabledControlChanges = (new->enabled_ctrls^old->enabled_ctrls);
+ pCN->numGroups = new->num_groups;
+
+ return 1;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbSendControlsNotify(DeviceIntPtr kbd,xkbControlsNotify *pCN)
+#else
+XkbSendControlsNotify(kbd,pCN)
+ DeviceIntPtr kbd;
+ xkbControlsNotify *pCN;
+#endif
+{
+int initialized;
+CARD32 changedControls,enabledControls,enabledChanges;
+XkbSrvInfoPtr xkbi;
+XkbInterestPtr interest;
+Time time;
+
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+ xkbi = kbd->key->xkbInfo;
+
+ initialized = 0;
+ enabledControls = xkbi->desc->ctrls->enabled_ctrls;
+ changedControls = pCN->changedControls;
+ pCN->numGroups= xkbi->desc->ctrls->num_groups;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->ctrlsNotifyMask&changedControls)) {
+ if (!initialized) {
+ pCN->type = XkbEventCode + XkbEventBase;
+ pCN->xkbType = XkbControlsNotify;
+ pCN->deviceID = kbd->id;
+ pCN->time = time = GetTimeInMillis();
+ enabledChanges = pCN->enabledControlChanges;
+ initialized= 1;
+ }
+ pCN->changedControls = changedControls;
+ pCN->enabledControls = enabledControls;
+ pCN->enabledControlChanges = enabledChanges;
+ pCN->sequenceNumber = interest->client->sequence;
+ pCN->time = time;
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&pCN->sequenceNumber,n);
+ swapl(&pCN->changedControls,n);
+ swapl(&pCN->enabledControls,n);
+ swapl(&pCN->enabledControlChanges,n);
+ swapl(&pCN->time,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)pCN);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbSendIndicatorNotify(DeviceIntPtr kbd,int xkbType,xkbIndicatorNotify *pEv)
+#else
+XkbSendIndicatorNotify(kbd,xkbType,pEv)
+ DeviceIntPtr kbd;
+ int xkbType;
+ xkbIndicatorNotify *pEv;
+#endif
+{
+int initialized;
+XkbInterestPtr interest;
+Time time;
+CARD32 state,changed;
+
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+
+ initialized = 0;
+ state = pEv->state;
+ changed = pEv->changed;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (((xkbType==XkbIndicatorStateNotify)&&
+ (interest->iStateNotifyMask&changed))||
+ ((xkbType==XkbIndicatorMapNotify)&&
+ (interest->iMapNotifyMask&changed)))) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = xkbType;
+ pEv->deviceID = kbd->id;
+ pEv->time = time = GetTimeInMillis();
+ initialized= 1;
+ }
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ pEv->changed = changed;
+ pEv->state = state;
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&pEv->sequenceNumber,n);
+ swapl(&pEv->time,n);
+ swapl(&pEv->changed,n);
+ swapl(&pEv->state,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+
+void
+#if NeedFunctionPrototypes
+XkbHandleBell( BOOL force,
+ BOOL eventOnly,
+ DeviceIntPtr kbd,
+ CARD8 percent,
+ pointer pCtrl,
+ CARD8 class,
+ Atom name,
+ WindowPtr pWin,
+ ClientPtr pClient)
+#else
+XkbHandleBell(force,eventOnly,kbd,percent,pCtrl,class,name,pWin,pClient)
+ BOOL force;
+ BOOL eventOnly;
+ DeviceIntPtr kbd;
+ CARD8 percent;
+ pointer *pCtrl;
+ CARD8 class;
+ Atom name;
+ WindowPtr pWin;
+ ClientPtr pClient;
+#endif
+{
+xkbBellNotify bn;
+int initialized;
+XkbSrvInfoPtr xkbi;
+XkbInterestPtr interest;
+CARD8 id;
+CARD16 pitch,duration;
+Time time;
+XID winID;
+
+ xkbi = kbd->key->xkbInfo;
+
+ if ((force||(xkbi->desc->ctrls->enabled_ctrls&XkbAudibleBellMask))&&
+ (!eventOnly)) {
+ (*kbd->kbdfeed->BellProc)(percent,kbd,(pointer)pCtrl,class);
+ }
+ interest = kbd->xkb_interest;
+ if ((!interest)||(force))
+ return;
+
+ if ((class==0)||(class==KbdFeedbackClass)) {
+ KeybdCtrl *pKeyCtrl= (KeybdCtrl *)pCtrl;
+ id= pKeyCtrl->id;
+ pitch= pKeyCtrl->bell_pitch;
+ duration= pKeyCtrl->bell_duration;
+ }
+ else if (class==BellFeedbackClass) {
+ BellCtrl *pBellCtrl= (BellCtrl *)pCtrl;
+ id= pBellCtrl->id;
+ pitch= pBellCtrl->pitch;
+ duration= pBellCtrl->duration;
+ }
+ else return;
+
+ initialized = 0;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->bellNotifyMask)) {
+ if (!initialized) {
+ time = GetTimeInMillis();
+ bn.type = XkbEventCode + XkbEventBase;
+ bn.xkbType = XkbBellNotify;
+ bn.deviceID = kbd->id;
+ bn.bellClass = class;
+ bn.bellID = id;
+ bn.percent= percent;
+ bn.eventOnly = (eventOnly!=0);
+ winID= (pWin?pWin->drawable.id:None);
+ initialized= 1;
+ }
+ bn.sequenceNumber = interest->client->sequence;
+ bn.time = time;
+ bn.pitch = pitch;
+ bn.duration = duration;
+ bn.name = name;
+ bn.window= winID;
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&bn.sequenceNumber,n);
+ swapl(&bn.time,n);
+ swaps(&bn.pitch,n);
+ swaps(&bn.duration,n);
+ swapl(&bn.name,n);
+ swapl(&bn.window,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)&bn);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbSendAccessXNotify(DeviceIntPtr kbd,xkbAccessXNotify *pEv)
+#else
+XkbSendAccessXNotify(kbd,pEv)
+ DeviceIntPtr kbd;
+ xkbAccessXNotify *pEv;
+#endif
+{
+int initialized;
+XkbInterestPtr interest;
+Time time;
+CARD16 sk_delay,db_delay;
+
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+
+ initialized = 0;
+ sk_delay= pEv->slowKeysDelay;
+ db_delay= pEv->debounceDelay;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->accessXNotifyMask&(1<<pEv->detail))) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = XkbAccessXNotify;
+ pEv->deviceID = kbd->id;
+ pEv->time = time = GetTimeInMillis();
+ initialized= 1;
+ }
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ pEv->slowKeysDelay = sk_delay;
+ pEv->debounceDelay = db_delay;
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&pEv->sequenceNumber,n);
+ swapl(&pEv->time,n);
+ swaps(&pEv->slowKeysDelay,n);
+ swaps(&pEv->debounceDelay,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbSendNamesNotify(DeviceIntPtr kbd,xkbNamesNotify *pEv)
+#else
+XkbSendNamesNotify(kbd,pEv)
+ DeviceIntPtr kbd;
+ xkbNamesNotify *pEv;
+#endif
+{
+int initialized;
+XkbInterestPtr interest;
+Time time;
+CARD16 changed,changedVirtualMods;
+CARD32 changedIndicators;
+
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+
+ initialized = 0;
+ changed= pEv->changed;
+ changedIndicators= pEv->changedIndicators;
+ changedVirtualMods= pEv->changedVirtualMods;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->namesNotifyMask&pEv->changed)) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = XkbNamesNotify;
+ pEv->deviceID = kbd->id;
+ pEv->time = time = GetTimeInMillis();
+ initialized= 1;
+ }
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ pEv->changed = changed;
+ pEv->changedIndicators = changedIndicators;
+ pEv->changedVirtualMods= changedVirtualMods;
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&pEv->sequenceNumber,n);
+ swapl(&pEv->time,n);
+ swaps(&pEv->changed,n);
+ swapl(&pEv->changedIndicators,n);
+ swaps(&pEv->changedVirtualMods,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbSendCompatMapNotify(DeviceIntPtr kbd,xkbCompatMapNotify *pEv)
+#else
+XkbSendCompatMapNotify(kbd,pEv)
+ DeviceIntPtr kbd;
+ xkbCompatMapNotify *pEv;
+#endif
+{
+int initialized;
+XkbInterestPtr interest;
+Time time;
+CARD16 firstSI,nSI,nTotalSI;
+
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+
+ initialized = 0;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->compatNotifyMask)) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = XkbCompatMapNotify;
+ pEv->deviceID = kbd->id;
+ pEv->time = time = GetTimeInMillis();
+ firstSI= pEv->firstSI;
+ nSI= pEv->nSI;
+ nTotalSI= pEv->nTotalSI;
+ initialized= 1;
+ }
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ pEv->firstSI = firstSI;
+ pEv->nSI = nSI;
+ pEv->nTotalSI = nTotalSI;
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&pEv->sequenceNumber,n);
+ swapl(&pEv->time,n);
+ swaps(&pEv->firstSI,n);
+ swaps(&pEv->nSI,n);
+ swaps(&pEv->nTotalSI,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbSendActionMessage(DeviceIntPtr kbd,xkbActionMessage *pEv)
+#else
+XkbSendActionMessage(kbd,pEv)
+ DeviceIntPtr kbd;
+ xkbActionMessage * pEv;
+#endif
+{
+int initialized;
+XkbSrvInfoPtr xkbi;
+XkbInterestPtr interest;
+Time time;
+
+ xkbi = kbd->key->xkbInfo;
+ interest = kbd->xkb_interest;
+ if (!interest)
+ return;
+
+ initialized = 0;
+ pEv->mods= xkbi->state.mods;
+ pEv->group= xkbi->state.group;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->actionMessageMask)) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = XkbActionMessage;
+ pEv->deviceID = kbd->id;
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time = GetTimeInMillis();
+ initialized= 1;
+ }
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&pEv->sequenceNumber,n);
+ swapl(&pEv->time,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbSendExtensionDeviceNotify( DeviceIntPtr dev,
+ ClientPtr client,
+ xkbExtensionDeviceNotify * pEv)
+#else
+XkbSendExtensionDeviceNotify(dev,client,pEv)
+ DeviceIntPtr dev;
+ ClientPtr client;
+ xkbExtensionDeviceNotify * pEv;
+#endif
+{
+int initialized;
+XkbInterestPtr interest;
+Time time;
+CARD32 defined,state;
+CARD16 reason,supported;
+
+ interest = dev->xkb_interest;
+ if (!interest)
+ return;
+
+ initialized = 0;
+ reason= pEv->reason;
+ defined= pEv->ledsDefined;
+ state= pEv->ledState;
+ while (interest) {
+ if ((!interest->client->clientGone) &&
+ (interest->client->requestVector != InitialVector) &&
+ (interest->client->xkbClientFlags&_XkbClientInitialized) &&
+ (interest->extDevNotifyMask&reason)) {
+ if (!initialized) {
+ pEv->type = XkbEventCode + XkbEventBase;
+ pEv->xkbType = XkbExtensionDeviceNotify;
+ pEv->deviceID = dev->id;
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time = GetTimeInMillis();
+ supported= pEv->supported;
+ initialized= 1;
+ }
+ else {
+ pEv->sequenceNumber = interest->client->sequence;
+ pEv->time = time;
+ pEv->ledsDefined= defined;
+ pEv->ledState= state;
+ pEv->reason= reason;
+ pEv->supported= supported;
+ }
+ if (client!=interest->client) {
+ /* only report UnsupportedFeature to the client that */
+ /* issued the failing request */
+ pEv->reason&= ~XkbXI_UnsupportedFeatureMask;
+ if ((interest->extDevNotifyMask&reason)==0)
+ continue;
+ }
+ if ( interest->client->swapped ) {
+ register int n;
+ swaps(&pEv->sequenceNumber,n);
+ swapl(&pEv->time,n);
+ swapl(&pEv->ledsDefined,n);
+ swapl(&pEv->ledState,n);
+ swaps(&pEv->reason,n);
+ swaps(&pEv->supported,n);
+ }
+ WriteToClient(interest->client, sizeof(xEvent), (char *)pEv);
+ }
+ interest= interest->next;
+ }
+ return;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbSendNotification( DeviceIntPtr kbd,
+ XkbChangesPtr pChanges,
+ XkbEventCausePtr cause)
+#else
+XkbSendNotification(kbd,pChanges,cause)
+ DeviceIntPtr kbd;
+ XkbChangesPtr pChanges;
+ XkbEventCausePtr cause;
+#endif
+{
+XkbSrvLedInfoPtr sli;
+
+ sli= NULL;
+ if (pChanges->state_changes) {
+ xkbStateNotify sn;
+ sn.changed= pChanges->state_changes;
+ sn.keycode= cause->kc;
+ sn.eventType= cause->event;
+ sn.requestMajor= cause->mjr;
+ sn.requestMinor= cause->mnr;
+ XkbSendStateNotify(kbd,&sn);
+ }
+ if (pChanges->map.changed) {
+ xkbMapNotify mn;
+ mn.changed= pChanges->map.changed;
+ mn.firstType= pChanges->map.first_type;
+ mn.nTypes= pChanges->map.num_types;
+ mn.firstKeySym= pChanges->map.first_key_sym;
+ mn.nKeySyms= pChanges->map.num_key_syms;
+ mn.firstKeyAct= pChanges->map.first_key_act;
+ mn.nKeyActs= pChanges->map.num_key_acts;
+ mn.firstKeyBehavior= pChanges->map.first_key_behavior;
+ mn.nKeyBehaviors= pChanges->map.num_key_behaviors;
+ mn.virtualMods= pChanges->map.vmods;
+ mn.firstKeyExplicit= pChanges->map.first_key_explicit;
+ mn.nKeyExplicit= pChanges->map.num_key_explicit;
+ mn.firstModMapKey= pChanges->map.first_modmap_key;
+ mn.nModMapKeys= pChanges->map.num_modmap_keys;
+ mn.firstVModMapKey= pChanges->map.first_vmodmap_key;
+ mn.nVModMapKeys= pChanges->map.num_vmodmap_keys;
+ XkbSendMapNotify(kbd,&mn);
+ }
+ if ((pChanges->ctrls.changed_ctrls)||
+ (pChanges->ctrls.enabled_ctrls_changes)) {
+ xkbControlsNotify cn;
+ cn.changedControls= pChanges->ctrls.changed_ctrls;
+ cn.enabledControlChanges= pChanges->ctrls.enabled_ctrls_changes;
+ cn.keycode= cause->kc;
+ cn.eventType= cause->event;
+ cn.requestMajor= cause->mjr;
+ cn.requestMinor= cause->mnr;
+ XkbSendControlsNotify(kbd,&cn);
+ }
+ if (pChanges->indicators.map_changes) {
+ xkbIndicatorNotify in;
+ if (sli==NULL)
+ sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
+ in.state= sli->effectiveState;
+ in.changed= pChanges->indicators.map_changes;
+ XkbSendIndicatorNotify(kbd,XkbIndicatorMapNotify,&in);
+ }
+ if (pChanges->indicators.state_changes) {
+ xkbIndicatorNotify in;
+ if (sli==NULL)
+ sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
+ in.state= sli->effectiveState;
+ in.changed= pChanges->indicators.state_changes;
+ XkbSendIndicatorNotify(kbd,XkbIndicatorStateNotify,&in);
+ }
+ if (pChanges->names.changed) {
+ xkbNamesNotify nn;
+ nn.changed= pChanges->names.changed;
+ nn.firstType= pChanges->names.first_type;
+ nn.nTypes= pChanges->names.num_types;
+ nn.firstLevelName= pChanges->names.first_lvl;
+ nn.nLevelNames= pChanges->names.num_lvls;
+ nn.nRadioGroups= pChanges->names.num_rg;
+ nn.changedVirtualMods= pChanges->names.changed_vmods;
+ nn.changedIndicators= pChanges->names.changed_indicators;
+ XkbSendNamesNotify(kbd,&nn);
+ }
+ if ((pChanges->compat.changed_groups)||(pChanges->compat.num_si>0)) {
+ xkbCompatMapNotify cmn;
+ cmn.changedGroups= pChanges->compat.changed_groups;
+ cmn.firstSI= pChanges->compat.first_si;
+ cmn.nSI= pChanges->compat.num_si;
+ cmn.nTotalSI= kbd->key->xkbInfo->desc->compat->num_si;
+ XkbSendCompatMapNotify(kbd,&cmn);
+ }
+ return;
+}
+
+/***====================================================================***/
+
+Bool
+#if NeedFunctionPrototypes
+XkbFilterEvents(ClientPtr pClient,int nEvents,xEvent *xE)
+#else
+XkbFilterEvents(pClient,nEvents,xE)
+ ClientPtr pClient;
+ int nEvents;
+ xEvent *xE;
+#endif
+{
+int i;
+DeviceIntPtr pXDev = (DeviceIntPtr)LookupKeyboardDevice();
+XkbSrvInfoPtr xkbi;
+
+ xkbi= pXDev->key->xkbInfo;
+ if ( pClient->xkbClientFlags & _XkbClientInitialized ) {
+#ifdef DEBUG
+ if ((xkbDebugFlags&0x10)&&
+ ((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease))) {
+ ErrorF("XKbFilterWriteEvents:\n");
+ ErrorF(" Event state= 0x%04x\n",xE[0].u.keyButtonPointer.state);
+ ErrorF(" XkbLastRepeatEvent!=xE (0x%x!=0x%x) %s\n",
+ XkbLastRepeatEvent,xE,
+ ((XkbLastRepeatEvent!=(pointer)xE)?"True":"False"));
+ ErrorF(" (xkbClientEventsFlags&XWDA)==0 (0x%x) %s\n",
+ pClient->xkbClientFlags,
+ (_XkbWantsDetectableAutoRepeat(pClient)?"True":"False"));
+ ErrorF(" !IsRelease(%d) %s\n",xE[0].u.u.type,
+ (!_XkbIsReleaseEvent(xE[0].u.u.type))?"True":"False");
+ }
+#endif /* DEBUG */
+ if ( (XkbLastRepeatEvent==(pointer)xE) &&
+ (_XkbWantsDetectableAutoRepeat(pClient)) &&
+ (_XkbIsReleaseEvent(xE[0].u.u.type)) ) {
+ return False;
+ }
+ if ((pXDev->grab != NullGrab) &&
+ ((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease))) {
+ register unsigned state,flags;
+
+ flags= pClient->xkbClientFlags;
+ state= xkbi->state.compat_grab_mods;
+ if (flags & XkbPCF_GrabsUseXKBStateMask) {
+ int group;
+ if (flags&XkbPCF_LookupStateWhenGrabbed) {
+ group= xkbi->state.group;
+ state= xkbi->state.lookup_mods;
+ }
+ else {
+ state= xkbi->state.grab_mods;
+ group= xkbi->state.base_group+xkbi->state.latched_group;
+ if ((group<0)||(group>=xkbi->desc->ctrls->num_groups)) {
+ group= XkbAdjustGroup(group,xkbi->desc->ctrls);
+ }
+ }
+ state = XkbBuildCoreState(state, group);
+ }
+ else if (flags&XkbPCF_LookupStateWhenGrabbed)
+ state= xkbi->state.compat_lookup_mods;
+ xE[0].u.keyButtonPointer.state= state;
+ }
+ }
+ else {
+ register CARD8 type;
+
+ for (i=0;i<nEvents;i++) {
+ type= xE[i].u.u.type;
+#ifdef DEBUG
+ if ((xkbDebugFlags&0x4)&&
+ ((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease))) {
+ XkbStatePtr s= &xkbi->state;
+ ErrorF("XKbFilterWriteEvents (non-XKB):\n");
+ ErrorF("event= 0x%04x\n",xE[0].u.keyButtonPointer.state);
+ ErrorF("lookup= 0x%02x, grab= 0x%02x\n",s->lookup_mods,
+ s->grab_mods);
+ ErrorF("compat lookup= 0x%02x, grab= 0x%02x\n",
+ s->compat_lookup_mods,
+ s->compat_grab_mods);
+ }
+#endif
+ if ( (type>=KeyPress)&&(type<=MotionNotify) ) {
+ CARD16 old,new;
+
+ old= xE[i].u.keyButtonPointer.state&(~0x1f00);
+ new= xE[i].u.keyButtonPointer.state&0x1F00;
+
+ if (old==XkbStateFieldFromRec(&xkbi->state))
+ new|= xkbi->state.compat_lookup_mods;
+ else new|= xkbi->state.compat_grab_mods;
+ xE[i].u.keyButtonPointer.state= new;
+ }
+ else if ((type==EnterNotify)||(type==LeaveNotify)) {
+ xE->u.enterLeave.state&= 0x1F00;
+ xE->u.enterLeave.state|= xkbi->state.compat_grab_mods;
+ }
+ }
+ }
+ return True;
+}
+
+/***====================================================================***/
+
+XkbInterestPtr
+#if NeedFunctionPrototypes
+XkbFindClientResource(DevicePtr inDev,ClientPtr client)
+#else
+XkbFindClientResource(inDev,client)
+ DevicePtr inDev;
+ ClientPtr client;
+#endif
+{
+DeviceIntPtr dev = (DeviceIntPtr)inDev;
+XkbInterestPtr interest;
+
+ if ( dev->xkb_interest ) {
+ interest = dev->xkb_interest;
+ while (interest){
+ if (interest->client==client) {
+ return interest;
+ }
+ interest = interest->next;
+ }
+ }
+ return NULL;
+}
+
+XkbInterestPtr
+#if NeedFunctionPrototypes
+XkbAddClientResource(DevicePtr inDev,ClientPtr client,XID id)
+#else
+XkbAddClientResource(inDev,client,id)
+ DevicePtr inDev;
+ ClientPtr client;
+ XID id;
+#endif
+{
+DeviceIntPtr dev = (DeviceIntPtr)inDev;
+XkbInterestPtr interest;
+
+ interest = dev->xkb_interest;
+ while (interest) {
+ if (interest->client==client)
+ return ((interest->resource==id)?interest:NULL);
+ interest = interest->next;
+ }
+ interest = _XkbTypedAlloc(XkbInterestRec);
+ bzero(interest,sizeof(XkbInterestRec));
+ if (interest) {
+ interest->dev = dev;
+ interest->client = client;
+ interest->resource = id;
+ interest->stateNotifyMask= 0;
+ interest->ctrlsNotifyMask= 0;
+ interest->namesNotifyMask= 0;
+ interest->compatNotifyMask= 0;
+ interest->bellNotifyMask= FALSE;
+ interest->accessXNotifyMask= 0;
+ interest->iStateNotifyMask= 0;
+ interest->iMapNotifyMask= 0;
+ interest->altSymsNotifyMask= 0;
+ interest->next = dev->xkb_interest;
+ dev->xkb_interest= interest;
+ return interest;
+ }
+ return NULL;
+}
+
+int
+#if NeedFunctionPrototypes
+XkbRemoveClient(DevicePtr inDev,ClientPtr client)
+#else
+XkbRemoveClient(inDev,client)
+DevicePtr inDev;
+ClientPtr client;
+#endif
+{
+XkbSrvInfoPtr xkbi;
+DeviceIntPtr dev = (DeviceIntPtr)inDev;
+XkbInterestPtr interest;
+unsigned long autoCtrls,autoValues;
+Bool found;
+
+ found= False;
+ autoCtrls= autoValues= 0;
+ if ( dev->xkb_interest ) {
+ interest = dev->xkb_interest;
+ if (interest && (interest->client==client)){
+ dev->xkb_interest = interest->next;
+ autoCtrls= interest->autoCtrls;
+ autoValues= interest->autoCtrlValues;
+ _XkbFree(interest);
+ found= True;
+ }
+ while ((!found)&&(interest->next)) {
+ if (interest->next->client==client) {
+ XkbInterestPtr victim = interest->next;
+ interest->next = victim->next;
+ autoCtrls= victim->autoCtrls;
+ autoValues= victim->autoCtrlValues;
+ _XkbFree(victim);
+ found= True;
+ }
+ interest = interest->next;
+ }
+ }
+ if (found && autoCtrls && dev->key && dev->key->xkbInfo ) {
+ XkbEventCauseRec cause;
+
+ xkbi= dev->key->xkbInfo;
+ XkbSetCauseXkbReq(&cause,X_kbPerClientFlags,client);
+ XkbEnableDisableControls(xkbi,autoCtrls,autoValues,NULL,&cause);
+ }
+ return found;
+}
+
+int
+#if NeedFunctionPrototypes
+XkbRemoveResourceClient(DevicePtr inDev,XID id)
+#else
+XkbRemoveResourceClient(inDev,id)
+ DevicePtr inDev;
+ XID id;
+#endif
+{
+XkbSrvInfoPtr xkbi;
+DeviceIntPtr dev = (DeviceIntPtr)inDev;
+XkbInterestPtr interest;
+Bool found;
+unsigned long autoCtrls,autoValues;
+ClientPtr client;
+
+ found= False;
+ autoCtrls= autoValues= 0;
+ if ( dev->xkb_interest ) {
+ interest = dev->xkb_interest;
+ if (interest && (interest->resource==id)){
+ dev->xkb_interest = interest->next;
+ autoCtrls= interest->autoCtrls;
+ autoValues= interest->autoCtrlValues;
+ client= interest->client;
+ _XkbFree(interest);
+ found= True;
+ }
+ while ((!found)&&(interest->next)) {
+ if (interest->next->resource==id) {
+ XkbInterestPtr victim = interest->next;
+ interest->next = victim->next;
+ autoCtrls= victim->autoCtrls;
+ autoValues= victim->autoCtrlValues;
+ client= victim->client;
+ _XkbFree(victim);
+ found= True;
+ }
+ interest = interest->next;
+ }
+ }
+ if (found && autoCtrls && dev->key && dev->key->xkbInfo ) {
+ XkbEventCauseRec cause;
+
+ xkbi= dev->key->xkbInfo;
+ XkbSetCauseXkbReq(&cause,X_kbPerClientFlags,client);
+ XkbEnableDisableControls(xkbi,autoCtrls,autoValues,NULL,&cause);
+ }
+ return found;
+}
+
+
+
diff --git a/xc/programs/Xserver/xkb/xkbInit.c b/xc/programs/Xserver/xkb/xkbInit.c
new file mode 100644
index 000000000..61204c1d0
--- /dev/null
+++ b/xc/programs/Xserver/xkb/xkbInit.c
@@ -0,0 +1,1003 @@
+/* $TOG: xkbInit.c /main/25 1997/09/26 14:26:56 kaleb $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+/* $XFree86: xc/programs/Xserver/xkb/xkbInit.c,v 3.15 1998/10/04 09:39:55 dawes Exp $ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <math.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include <X11/Xatom.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "property.h"
+#define XKBSRV_NEED_FILE_FUNCS
+#include "XKBsrv.h"
+#include "XKBgeom.h"
+#include <X11/extensions/XKMformat.h>
+#include <X11/extensions/XKBfile.h>
+
+
+#define CREATE_ATOM(s) MakeAtom(s,sizeof(s)-1,1)
+
+#ifdef sgi
+#define LED_CAPS 5
+#define LED_NUM 6
+#define LED_SCROLL 7
+#define PHYS_LEDS 0x7f
+#define LED_COMPOSE 8
+#else
+#if defined(ultrix) || defined(__osf__) || defined(__alpha) || defined(__alpha__)
+#define LED_COMPOSE 2
+#define LED_CAPS 3
+#define LED_SCROLL 4
+#define LED_NUM 5
+#define PHYS_LEDS 0x1f
+#else
+#ifdef sun
+#define LED_NUM 1
+#define LED_SCROLL 2
+#define LED_COMPOSE 3
+#define LED_CAPS 4
+#define PHYS_LEDS 0x0f
+#else
+#define LED_CAPS 1
+#define LED_NUM 2
+#define LED_SCROLL 3
+#define PHYS_LEDS 0x07
+#endif
+#endif
+#endif
+
+#define MAX_TOC 16
+typedef struct _SrvXkmInfo {
+ DeviceIntPtr dev;
+ FILE * file;
+ XkbFileInfo xkbinfo;
+} SrvXkmInfo;
+
+
+/***====================================================================***/
+
+#ifndef XKB_BASE_DIRECTORY
+#define XKB_BASE_DIRECTORY "/usr/lib/X11/xkb"
+#endif
+#ifndef XKB_DFLT_RULES_FILE
+#define XKB_DFLT_RULES_FILE "rules"
+#endif
+#ifndef XKB_DFLT_KB_LAYOUT
+#define XKB_DFLT_KB_LAYOUT "us"
+#endif
+#ifndef XKB_DFLT_KB_MODEL
+#define XKB_DFLT_KB_MODEL "dflt"
+#endif
+#ifndef XKB_DFLT_KB_VARIANT
+#define XKB_DFLT_KB_VARIANT NULL
+#endif
+#ifndef XKB_DFLT_KB_OPTIONS
+#define XKB_DFLT_KB_OPTIONS NULL
+#endif
+#ifndef XKB_DFLT_DISABLED
+#define XKB_DFLT_DISABLED True
+#endif
+#ifndef XKB_DFLT_RULES_PROP
+#define XKB_DFLT_RULES_PROP True
+#endif
+
+char * XkbBaseDirectory= XKB_BASE_DIRECTORY;
+char * XkbInitialMap= NULL;
+int XkbWantAccessX= 0;
+static XkbFileInfo * _XkbInitFileInfo= NULL;
+char * XkbDB= NULL;
+int XkbAutoLoad= 1;
+
+static Bool rulesDefined= False;
+static char * XkbRulesFile= NULL;
+static char * XkbModelDflt= NULL;
+static char * XkbLayoutDflt= NULL;
+static char * XkbVariantDflt= NULL;
+static char * XkbOptionsDflt= NULL;
+
+char * XkbModelUsed= NULL;
+char * XkbLayoutUsed= NULL;
+char * XkbVariantUsed= NULL;
+char * XkbOptionsUsed= NULL;
+
+int _XkbClientMajor= XkbMajorVersion;
+int _XkbClientMinor= XkbMinorVersion;
+
+Bool noXkbExtension= XKB_DFLT_DISABLED;
+Bool XkbWantRulesProp= XKB_DFLT_RULES_PROP;
+
+/***====================================================================***/
+
+char *
+#if NeedFunctionPrototypes
+XkbGetRulesDflts(XkbRF_VarDefsPtr defs)
+#else
+XkbGetRulesDflts(defs)
+ XkbRF_VarDefsPtr defs;
+#endif
+{
+ if (XkbModelDflt) defs->model= XkbModelDflt;
+ else defs->model= XKB_DFLT_KB_MODEL;
+ if (XkbLayoutDflt) defs->layout= XkbLayoutDflt;
+ else defs->layout= XKB_DFLT_KB_LAYOUT;
+ if (XkbVariantDflt) defs->variant= XkbVariantDflt;
+ else defs->variant= XKB_DFLT_KB_VARIANT;
+ if (XkbOptionsDflt) defs->options= XkbOptionsDflt;
+ else defs->options= XKB_DFLT_KB_OPTIONS;
+ return (rulesDefined?XkbRulesFile:XKB_DFLT_RULES_FILE);
+}
+
+Bool
+#if NeedFunctionPrototypes
+XkbWriteRulesProp(ClientPtr client, pointer closure)
+#else
+XkbWriteRulesProp(client, closure)
+ ClientPtr client;
+ pointer closure;
+#endif
+{
+int len,out;
+extern WindowPtr * WindowTable;
+Atom name;
+char * pval;
+
+ if (rulesDefined && (!XkbRulesFile))
+ return False;
+ len= (XkbRulesFile?strlen(XkbRulesFile):strlen(XKB_DFLT_RULES_FILE));
+ len+= (XkbModelUsed?strlen(XkbModelUsed):0);
+ len+= (XkbLayoutUsed?strlen(XkbLayoutUsed):0);
+ len+= (XkbVariantUsed?strlen(XkbVariantUsed):0);
+ len+= (XkbOptionsUsed?strlen(XkbOptionsUsed):0);
+ if (len<1)
+ return True;
+
+ len+= 5; /* trailing NULs */
+
+ name= MakeAtom(_XKB_RF_NAMES_PROP_ATOM,strlen(_XKB_RF_NAMES_PROP_ATOM),1);
+ if (name==None) {
+ ErrorF("Atom error: %s not created\n",_XKB_RF_NAMES_PROP_ATOM);
+ return True;
+ }
+ pval= (char*) ALLOCATE_LOCAL(len);
+ if (!pval) {
+ ErrorF("Allocation error: %s proprerty not created\n",
+ _XKB_RF_NAMES_PROP_ATOM);
+ return True;
+ }
+ out= 0;
+ if (XkbRulesFile) {
+ strcpy(&pval[out],XkbRulesFile);
+ out+= strlen(XkbRulesFile);
+ }
+ pval[out++]= '\0';
+ if (XkbModelUsed) {
+ strcpy(&pval[out],XkbModelUsed);
+ out+= strlen(XkbModelUsed);
+ }
+ pval[out++]= '\0';
+ if (XkbLayoutUsed) {
+ strcpy(&pval[out],XkbLayoutUsed);
+ out+= strlen(XkbLayoutUsed);
+ }
+ pval[out++]= '\0';
+ if (XkbVariantUsed) {
+ strcpy(&pval[out],XkbVariantUsed);
+ out+= strlen(XkbVariantUsed);
+ }
+ pval[out++]= '\0';
+ if (XkbOptionsUsed) {
+ strcpy(&pval[out],XkbOptionsUsed);
+ out+= strlen(XkbOptionsUsed);
+ }
+ pval[out++]= '\0';
+ if (out!=len) {
+ ErrorF("Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n",
+ out,len);
+ }
+ ChangeWindowProperty(WindowTable[0],name,XA_STRING,8,PropModeReplace,
+ len,pval,True);
+ DEALLOCATE_LOCAL(pval);
+ return True;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbSetRulesUsed(XkbRF_VarDefsPtr defs)
+#else
+XkbSetRulesUsed(defs)
+ XkbRF_VarDefsPtr defs;
+#endif
+{
+ if (XkbModelUsed)
+ _XkbFree(XkbModelUsed);
+ XkbModelUsed= (defs->model?_XkbDupString(defs->model):NULL);
+ if (XkbLayoutUsed)
+ _XkbFree(XkbLayoutUsed);
+ XkbLayoutUsed= (defs->layout?_XkbDupString(defs->layout):NULL);
+ if (XkbVariantUsed)
+ _XkbFree(XkbVariantUsed);
+ XkbVariantUsed= (defs->variant?_XkbDupString(defs->variant):NULL);
+ if (XkbOptionsUsed)
+ _XkbFree(XkbOptionsUsed);
+ XkbOptionsUsed= (defs->options?_XkbDupString(defs->options):NULL);
+ if (XkbWantRulesProp)
+ QueueWorkProc(XkbWriteRulesProp,NULL,NULL);
+ return;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbSetRulesDflts(char *rulesFile,char *model,char *layout,
+ char *variant,char *options)
+#else
+XkbSetRulesDflts(rulesFile,model,layout,variant,options)
+ char * rulesFile;
+ char * model;
+ char * layout;
+ char * variant;
+ char * options;
+#endif
+{
+ if (XkbRulesFile)
+ _XkbFree(XkbRulesFile);
+ XkbRulesFile= _XkbDupString(rulesFile);
+ rulesDefined= True;
+ if (model) {
+ if (XkbModelDflt)
+ _XkbFree(XkbModelDflt);
+ XkbModelDflt= _XkbDupString(model);
+ }
+ if (layout) {
+ if (XkbLayoutDflt)
+ _XkbFree(XkbLayoutDflt);
+ XkbLayoutDflt= _XkbDupString(layout);
+ }
+ if (variant) {
+ if (XkbVariantDflt)
+ _XkbFree(XkbVariantDflt);
+ XkbVariantDflt= _XkbDupString(variant);
+ }
+ if (options) {
+ if (XkbOptionsDflt)
+ _XkbFree(XkbOptionsDflt);
+ XkbOptionsDflt= _XkbDupString(options);
+ }
+ return;
+}
+
+/***====================================================================***/
+
+#if defined(luna)
+#define XKB_DDX_PERMANENT_LOCK 1
+#endif
+
+#include "xkbDflts.h"
+
+static Bool
+#if NeedFunctionPrototypes
+XkbInitKeyTypes(XkbDescPtr xkb,SrvXkmInfo *file)
+#else
+XkbInitKeyTypes(xkb,file)
+ XkbDescPtr xkb;
+ SrvXkmInfo * file;
+#endif
+{
+ if (file->xkbinfo.defined&XkmTypesMask)
+ return True;
+ initTypeNames(NULL);
+ if (XkbAllocClientMap(xkb,XkbKeyTypesMask,num_dflt_types)!=Success)
+ return False;
+ if (XkbCopyKeyTypes(dflt_types,xkb->map->types,num_dflt_types)!=
+ Success) {
+ return False;
+ }
+ xkb->map->size_types= xkb->map->num_types= num_dflt_types;
+ return True;
+}
+
+static void
+#if NeedFunctionPrototypes
+XkbInitRadioGroups(XkbSrvInfoPtr xkbi,SrvXkmInfo *file)
+#else
+XkbInitRadioGroups(xkbi,file)
+ XkbSrvInfoPtr xkbi;
+ SrvXkmInfo * file;
+#endif
+{
+ xkbi->nRadioGroups = 0;
+ xkbi->radioGroups = NULL;
+ return;
+}
+
+
+static Status
+#if NeedFunctionPrototypes
+XkbInitCompatStructs(XkbDescPtr xkb,SrvXkmInfo *file)
+#else
+XkbInitCompatStructs(xkb,file)
+ XkbDescPtr xkb;
+ SrvXkmInfo * file;
+#endif
+{
+register int i;
+XkbCompatMapPtr compat;
+
+ if (file->xkbinfo.defined&XkmCompatMapMask)
+ return Success;
+ if (XkbAllocCompatMap(xkb,XkbAllCompatMask,num_dfltSI)!=Success)
+ return BadAlloc;
+ compat = xkb->compat;
+ if (compat->sym_interpret) {
+ compat->num_si = num_dfltSI;
+ memcpy((char *)compat->sym_interpret,(char *)dfltSI,sizeof(dfltSI));
+ }
+ for (i=0;i<XkbNumKbdGroups;i++) {
+ compat->groups[i]= compatMap.groups[i];
+ if (compat->groups[i].vmods!=0) {
+ unsigned mask;
+ mask= XkbMaskForVMask(xkb,compat->groups[i].vmods);
+ compat->groups[i].mask= compat->groups[i].real_mods|mask;
+ }
+ else compat->groups[i].mask= compat->groups[i].real_mods;
+ }
+ return Success;
+}
+
+static void
+#if NeedFunctionPrototypes
+XkbInitSemantics(XkbDescPtr xkb,SrvXkmInfo *file)
+#else
+XkbInitSemantics(xkb,file)
+ XkbDescPtr xkb;
+ SrvXkmInfo * file;
+#endif
+{
+ XkbInitKeyTypes(xkb,file);
+ XkbInitCompatStructs(xkb,file);
+ return;
+}
+
+/***====================================================================***/
+
+static Status
+#if NeedFunctionPrototypes
+XkbInitNames(XkbSrvInfoPtr xkbi,SrvXkmInfo *file)
+#else
+XkbInitNames(xkbi,file)
+ XkbSrvInfoPtr xkbi;
+ SrvXkmInfo * file;
+#endif
+{
+XkbDescPtr xkb;
+XkbNamesPtr names;
+Status rtrn;
+Atom unknown;
+
+ xkb= xkbi->desc;
+ if ((rtrn=XkbAllocNames(xkb,XkbAllNamesMask,0,0))!=Success)
+ return rtrn;
+ unknown= CREATE_ATOM("unknown");
+ names = xkb->names;
+ if (names->keycodes==None) names->keycodes= unknown;
+ if (names->geometry==None) names->geometry= unknown;
+ if (names->phys_symbols==None) names->phys_symbols= unknown;
+ if (names->symbols==None) names->symbols= unknown;
+ if (names->types==None) names->types= unknown;
+ if (names->compat==None) names->compat= unknown;
+ if ((file->xkbinfo.defined&XkmVirtualModsMask)==0) {
+ if (names->vmods[vmod_NumLock]==None)
+ names->vmods[vmod_NumLock]= CREATE_ATOM("NumLock");
+ if (names->vmods[vmod_Alt]==None)
+ names->vmods[vmod_Alt]= CREATE_ATOM("Alt");
+ if (names->vmods[vmod_AltGr]==None)
+ names->vmods[vmod_AltGr]= CREATE_ATOM("ModeSwitch");
+ }
+
+ if (((file->xkbinfo.defined&XkmIndicatorsMask)==0)||
+ ((file->xkbinfo.defined&XkmGeometryMask)==0)) {
+ initIndicatorNames(NULL,xkb);
+ if (names->indicators[LED_CAPS-1]==None)
+ names->indicators[LED_CAPS-1] = CREATE_ATOM("Caps Lock");
+ if (names->indicators[LED_NUM-1]==None)
+ names->indicators[LED_NUM-1] = CREATE_ATOM("Num Lock");
+ if (names->indicators[LED_SCROLL-1]==None)
+ names->indicators[LED_SCROLL-1] = CREATE_ATOM("Scroll Lock");
+#ifdef LED_COMPOSE
+ if (names->indicators[LED_COMPOSE-1]==None)
+ names->indicators[LED_COMPOSE-1] = CREATE_ATOM("Compose");
+#endif
+ }
+#ifdef DEBUG_RADIO_GROUPS
+ if (names->num_rg<1) {
+ names->radio_groups= (Atom *)_XkbCalloc(RG_COUNT, sizeof(Atom));
+ if (names->radio_groups) {
+ names->num_rg = RG_COUNT;
+ names->radio_groups[RG_BOGUS_FUNCTION_GROUP]= CREATE_ATOM("BOGUS");
+ }
+ }
+#endif
+ if (xkb->geom!=NULL)
+ names->geometry= xkb->geom->name;
+ else names->geometry= unknown;
+ return Success;
+}
+
+static Status
+#if NeedFunctionPrototypes
+XkbInitIndicatorMap(XkbSrvInfoPtr xkbi,SrvXkmInfo *file)
+#else
+XkbInitIndicatorMap(xkbi,file)
+ XkbSrvInfoPtr xkbi;
+ SrvXkmInfo * file;
+#endif
+{
+XkbDescPtr xkb;
+XkbIndicatorPtr map;
+XkbSrvLedInfoPtr sli;
+
+ xkb= xkbi->desc;
+ if (XkbAllocIndicatorMaps(xkb)!=Success)
+ return BadAlloc;
+ if ((file->xkbinfo.defined&XkmIndicatorsMask)==0) {
+ map= xkb->indicators;
+ map->phys_indicators = PHYS_LEDS;
+ map->maps[LED_CAPS-1].flags= XkbIM_NoExplicit;
+ map->maps[LED_CAPS-1].which_mods= XkbIM_UseLocked;
+ map->maps[LED_CAPS-1].mods.mask= LockMask;
+ map->maps[LED_CAPS-1].mods.real_mods= LockMask;
+
+ map->maps[LED_NUM-1].flags= XkbIM_NoExplicit;
+ map->maps[LED_NUM-1].which_mods= XkbIM_UseLocked;
+ map->maps[LED_NUM-1].mods.mask= 0;
+ map->maps[LED_NUM-1].mods.real_mods= 0;
+ map->maps[LED_NUM-1].mods.vmods= vmod_NumLockMask;
+
+/* Metro Link */
+ map->maps[LED_SCROLL-1].flags= XkbIM_NoExplicit;
+ map->maps[LED_SCROLL-1].which_mods= XkbIM_UseLocked;
+ map->maps[LED_SCROLL-1].mods.mask= Mod3Mask;
+ map->maps[LED_SCROLL-1].mods.real_mods= Mod3Mask;
+/* Metro Link */
+ }
+ sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0);
+ if (sli)
+ XkbCheckIndicatorMaps(xkbi->device,sli,XkbAllIndicatorsMask);
+ return Success;
+}
+
+static Status
+#if NeedFunctionPrototypes
+XkbInitControls(DeviceIntPtr pXDev,XkbSrvInfoPtr xkbi,SrvXkmInfo *file)
+#else
+XkbInitControls(pXDev,xkbi,file)
+ DeviceIntPtr pXDev;
+ XkbSrvInfoPtr xkbi;
+ SrvXkmInfo * file;
+#endif
+{
+XkbDescPtr xkb;
+XkbControlsPtr ctrls;
+
+ xkb= xkbi->desc;
+ /* 12/31/94 (ef) -- XXX! Should check if controls loaded from file */
+ if (XkbAllocControls(xkb,XkbAllControlsMask)!=Success)
+ FatalError("Couldn't allocate keyboard controls\n");
+ ctrls= xkb->ctrls;
+ if ((file->xkbinfo.defined&XkmSymbolsMask)==0)
+ ctrls->num_groups = 1;
+ ctrls->groups_wrap = XkbSetGroupInfo(1,XkbWrapIntoRange,0);
+ ctrls->internal.mask = 0;
+ ctrls->internal.real_mods = 0;
+ ctrls->internal.vmods = 0;
+ ctrls->ignore_lock.mask = 0;
+ ctrls->ignore_lock.real_mods = 0;
+ ctrls->ignore_lock.vmods = 0;
+ ctrls->enabled_ctrls = XkbAccessXTimeoutMask|XkbRepeatKeysMask|
+ XkbMouseKeysAccelMask|XkbAudibleBellMask|
+ XkbIgnoreGroupLockMask;
+ if (XkbWantAccessX)
+ ctrls->enabled_ctrls|= XkbAccessXKeysMask;
+ AccessXInit(pXDev);
+ return Success;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbInitDevice(DeviceIntPtr pXDev)
+#else
+XkbInitDevice(pXDev)
+ DeviceIntPtr pXDev;
+#endif
+{
+int i;
+XkbSrvInfoPtr xkbi;
+XkbChangesRec changes;
+SrvXkmInfo file;
+unsigned check;
+XkbEventCauseRec cause;
+
+ file.dev= pXDev;
+ file.file=NULL;
+ bzero(&file.xkbinfo,sizeof(XkbFileInfo));
+ bzero(&changes,sizeof(XkbChangesRec));
+ if (XkbAutoLoad && (XkbInitialMap!=NULL)) {
+ if ((file.file=XkbDDXOpenConfigFile(XkbInitialMap,NULL,0))!=NULL) {
+ XkmReadFile(file.file,0,XkmKeymapLegal,&file.xkbinfo);
+ if (file.xkbinfo.xkb==NULL) {
+ ErrorF("Error loading keymap file %s (%s in %s)\n",
+ XkbInitialMap, _XkbErrMessages[_XkbErrCode],
+ (_XkbErrLocation?_XkbErrLocation:"unknown"));
+ ErrorF(" reverting to defaults\n");
+ fclose(file.file);
+ file.file= NULL;
+ bzero(&file.xkbinfo,sizeof(XkbFileInfo));
+ }
+ else {
+ if (_XkbInitFileInfo!=NULL) {
+ XkbDescPtr tmp;
+ if ((tmp=_XkbInitFileInfo->xkb)!=NULL) {
+ XkbFreeKeyboard(tmp,XkbAllComponentsMask,True);
+ _XkbInitFileInfo->xkb= NULL;
+ }
+ }
+ _XkbInitFileInfo= &file.xkbinfo;
+ }
+ }
+ else {
+ ErrorF("Error opening keymap file %s, reverting to defaults\n",
+ XkbInitialMap);
+ }
+ }
+ pXDev->key->xkbInfo= xkbi= _XkbTypedCalloc(1,XkbSrvInfoRec);
+ if ( xkbi ) {
+ XkbDescPtr xkb;
+ if ((_XkbInitFileInfo!=NULL)&&(_XkbInitFileInfo->xkb!=NULL)) {
+ file.xkbinfo= *_XkbInitFileInfo;
+ xkbi->desc= _XkbInitFileInfo->xkb;
+ _XkbInitFileInfo= NULL;
+ }
+ else {
+ xkbi->desc= XkbAllocKeyboard();
+ if (!xkbi->desc)
+ FatalError("Couldn't allocate keyboard description\n");
+ xkbi->desc->min_key_code = pXDev->key->curKeySyms.minKeyCode;
+ xkbi->desc->max_key_code = pXDev->key->curKeySyms.maxKeyCode;
+ }
+ xkb= xkbi->desc;
+ if (xkb->min_key_code == 0)
+ xkb->min_key_code = pXDev->key->curKeySyms.minKeyCode;
+ if (xkb->max_key_code == 0)
+ xkb->max_key_code = pXDev->key->curKeySyms.maxKeyCode;
+ if ((pXDev->key->curKeySyms.minKeyCode!=xkbi->desc->min_key_code)||
+ (pXDev->key->curKeySyms.maxKeyCode!=xkbi->desc->max_key_code)) {
+ /* 12/9/95 (ef) -- XXX! Maybe we should try to fix up one or */
+ /* the other here, but for now just complain */
+ /* can't just update the core range without */
+ /* reallocating the KeySymsRec (pain) */
+ ErrorF("Internal Error!! XKB and core keymap have different range\n");
+ }
+ if (XkbAllocClientMap(xkb,XkbAllClientInfoMask,0)!=Success)
+ FatalError("Couldn't allocate client map in XkbInitDevice\n");
+ i= XkbNumKeys(xkb)/3+1;
+ if (XkbAllocServerMap(xkb,XkbAllServerInfoMask,i)!=Success)
+ FatalError("Couldn't allocate server map in XkbInitDevice\n");
+
+ xkbi->dfltPtrDelta=1;
+ xkbi->device = pXDev;
+
+ file.xkbinfo.xkb= xkb;
+ XkbInitSemantics(xkb,&file);
+ XkbInitNames(xkbi,&file);
+ XkbInitRadioGroups(xkbi,&file);
+
+ /* 12/31/94 (ef) -- XXX! Should check if state loaded from file */
+ bzero(&xkbi->state,sizeof(XkbStateRec));
+
+ XkbInitControls(pXDev,xkbi,&file);
+
+ if (file.xkbinfo.defined&XkmSymbolsMask)
+ memcpy(pXDev->key->modifierMap,xkb->map->modmap,xkb->max_key_code+1);
+ else
+ memcpy(xkb->map->modmap,pXDev->key->modifierMap,xkb->max_key_code+1);
+
+ XkbInitIndicatorMap(xkbi,&file);
+
+ XkbDDXInitDevice(pXDev);
+
+ if (!(file.xkbinfo.defined&XkmSymbolsMask)) {
+ XkbUpdateKeyTypesFromCore(pXDev,xkb->min_key_code,XkbNumKeys(xkb),
+ &changes);
+ }
+ else {
+ XkbUpdateCoreDescription(pXDev,True);
+ }
+ XkbSetCauseUnknown(&cause);
+ XkbUpdateActions(pXDev,xkb->min_key_code, XkbNumKeys(xkb),&changes,
+ &check,&cause);
+ /* For sanity. The first time the connection
+ * is opened, the client side min and max are set
+ * using QueryMinMaxKeyCodes() which grabs them
+ * from pXDev.
+ */
+ pXDev->key->curKeySyms.minKeyCode = xkb->min_key_code;
+ pXDev->key->curKeySyms.maxKeyCode = xkb->max_key_code;
+ }
+ if (file.file!=NULL)
+ fclose(file.file);
+ return;
+}
+
+#if MAP_LENGTH > XkbMaxKeyCount
+#undef XkbMaxKeyCount
+#define XkbMaxKeyCount MAP_LENGTH
+#endif
+
+Bool
+#if NeedFunctionPrototypes
+XkbInitKeyboardDeviceStruct( DeviceIntPtr dev,
+ XkbComponentNamesPtr names,
+ KeySymsPtr pSymsIn,
+ CARD8 pModsIn[],
+ void (*bellProc)(),
+ void (*ctrlProc)())
+#else
+XkbInitKeyboardDeviceStruct( dev,names,pSymsIn,pModsIn,bellProc,ctrlProc )
+ DeviceIntPtr dev;
+ XkbComponentNamesPtr names;
+ KeySymsPtr pSymsIn;
+ CARD8 pModsIn[];
+ void (*bellProc)();
+ void (*ctrlProc)();
+#endif
+{
+XkbFileInfo finfo;
+KeySymsRec tmpSyms,*pSyms;
+CARD8 tmpMods[XkbMaxLegalKeyCode+1],*pMods;
+char name[PATH_MAX],*rules;
+Bool ok;
+XPointer config;
+XkbComponentNamesRec cfgNames;
+XkbRF_VarDefsRec defs;
+
+ if ((dev->key!=NULL)||(dev->kbdfeed!=NULL))
+ return False;
+ pSyms= pSymsIn;
+ pMods= pModsIn;
+ bzero(&defs,sizeof(XkbRF_VarDefsRec));
+ bzero(&cfgNames,sizeof(XkbComponentNamesRec));
+ rules= XkbGetRulesDflts(&defs);
+ config= XkbDDXPreloadConfig(&rules,&defs,&cfgNames,dev);
+
+ if (defs.model && defs.layout && rules) {
+ XkbComponentNamesRec rNames;
+ bzero(&rNames,sizeof(XkbComponentNamesRec));
+ if (XkbDDXNamesFromRules(dev,rules,&defs,&rNames)) {
+ if (rNames.keymap) names->keymap= rNames.keymap;
+ if (rNames.keycodes) names->keycodes= rNames.keycodes;
+ if (rNames.types) names->types= rNames.types;
+ if (rNames.compat) names->compat= rNames.compat;
+ if (rNames.symbols) names->symbols= rNames.symbols;
+ if (rNames.geometry) names->geometry= rNames.geometry;
+ XkbSetRulesUsed(&defs);
+ }
+ }
+ if (cfgNames.keymap) names->keymap= cfgNames.keymap;
+ if (cfgNames.keycodes) names->keycodes= cfgNames.keycodes;
+ if (cfgNames.types) names->types= cfgNames.types;
+ if (cfgNames.compat) names->compat= cfgNames.compat;
+ if (cfgNames.symbols) names->symbols= cfgNames.symbols;
+ if (cfgNames.geometry) names->geometry= cfgNames.geometry;
+
+ if ((XkbDDXLoadKeymapByNames(dev,names,XkmAllIndicesMask,0,
+ &finfo,name,PATH_MAX))&&
+ (finfo.xkb!=NULL)) {
+ XkbDescPtr xkb;
+ int minKC,maxKC;
+
+ xkb= finfo.xkb;
+ minKC= xkb->min_key_code;
+ maxKC= xkb->max_key_code;
+ if (XkbIsLegalKeycode(minKC)&&XkbIsLegalKeycode(maxKC)&&(minKC<=maxKC)&&
+ ((minKC!=pSyms->minKeyCode)||(maxKC!=pSyms->maxKeyCode))) {
+ if (xkb->map!=NULL) {
+ KeySym *inSym,*outSym;
+ int width= pSymsIn->mapWidth;
+
+ tmpSyms.minKeyCode= minKC;
+ tmpSyms.maxKeyCode= maxKC;
+
+ if (minKC<pSymsIn->minKeyCode)
+ minKC= pSymsIn->minKeyCode;
+ if (maxKC>pSymsIn->maxKeyCode)
+ maxKC= pSymsIn->maxKeyCode;
+
+ tmpSyms.mapWidth= width;
+ tmpSyms.map= _XkbTypedCalloc(width*XkbNumKeys(xkb),KeySym);
+ inSym= &pSymsIn->map[(minKC-pSymsIn->minKeyCode)*width];
+ outSym= &tmpSyms.map[(minKC-tmpSyms.minKeyCode)*width];
+ memcpy(outSym,inSym,((maxKC-minKC+1)*width)*sizeof(KeySym));
+ pSyms= &tmpSyms;
+ }
+ if ((xkb->map!=NULL)&&(xkb->map->modmap!=NULL)) {
+ bzero(tmpMods,XkbMaxKeyCount);
+ memcpy(tmpMods,xkb->map->modmap,maxKC+1);
+ pMods= tmpMods;
+ }
+ }
+ _XkbInitFileInfo= &finfo;
+ }
+ else {
+ ErrorF("Couldn't load XKB keymap, falling back to pre-XKB keymap\n");
+ }
+ ok= InitKeyboardDeviceStruct((DevicePtr)dev,pSyms,pMods,bellProc,ctrlProc);
+ if ((config!=NULL)&&(dev && dev->key && dev->key->xkbInfo))
+ XkbDDXApplyConfig(config,dev->key->xkbInfo);
+ _XkbInitFileInfo= NULL;
+ if ((pSyms==&tmpSyms)&&(pSyms->map!=NULL)) {
+ _XkbFree(pSyms->map);
+ pSyms->map= NULL;
+ }
+ return ok;
+}
+
+/***====================================================================***/
+
+ /*
+ * InitKeyClassDeviceStruct initializes the key class before it
+ * initializes the keyboard feedback class for a device.
+ * UpdateActions can't set up the correct autorepeat for keyboard
+ * initialization because the keyboard feedback isn't created yet.
+ * Instead, UpdateActions notes the "correct" autorepeat in the
+ * SrvInfo structure and InitKbdFeedbackClass calls UpdateAutoRepeat
+ * to apply the computed autorepeat once the feedback class exists.
+ *
+ * DIX will apply the changed autorepeat, so there's no need to
+ * do so here. This function returns True if both RepeatKeys and
+ * the core protocol autorepeat ctrls are set (i.e. should use
+ * software autorepeat), false otherwise.
+ *
+ * This function also computes the autorepeat accelerators for the
+ * default indicator feedback.
+ */
+int
+#if NeedFunctionPrototypes
+XkbFinishDeviceInit(DeviceIntPtr pXDev)
+#else
+XkbFinishDeviceInit(pXDev)
+ DeviceIntPtr pXDev;
+#endif
+{
+XkbSrvInfoPtr xkbi;
+XkbDescPtr xkb;
+int softRepeat;
+XkbSrvLedInfoPtr sli;
+
+ xkbi = NULL;
+ if (pXDev && pXDev->key && pXDev->key->xkbInfo && pXDev->kbdfeed) {
+ xkbi= pXDev->key->xkbInfo;
+ xkb= xkbi->desc;
+ if (pXDev->kbdfeed) {
+ xkbi->kbdProc= pXDev->kbdfeed->CtrlProc;
+ pXDev->kbdfeed->CtrlProc= XkbDDXKeybdCtrlProc;
+ }
+ if (pXDev->kbdfeed->ctrl.autoRepeat)
+ xkb->ctrls->enabled_ctrls|= XkbRepeatKeysMask;
+ softRepeat= (xkb->ctrls->enabled_ctrls&XkbRepeatKeysMask)!=0;
+ if (pXDev->kbdfeed) {
+ memcpy(pXDev->kbdfeed->ctrl.autoRepeats,
+ xkb->ctrls->per_key_repeat,XkbPerKeyBitArraySize);
+ softRepeat= softRepeat&&pXDev->kbdfeed->ctrl.autoRepeat;
+ }
+ }
+ else softRepeat= 0;
+ sli= XkbFindSrvLedInfo(pXDev,XkbDfltXIClass,XkbDfltXIId,0);
+ if (sli && xkbi)
+ XkbCheckIndicatorMaps(xkbi->device,sli,XkbAllIndicatorsMask);
+#ifdef DEBUG
+ else ErrorF("No indicator feedback in XkbFinishInit (shouldn't happen)!\n");
+#endif
+ return softRepeat;
+}
+
+ /*
+ * Be very careful about what does and doesn't get freed by this
+ * function. To reduce fragmentation, XkbInitDevice allocates a
+ * single huge block per device and divides it up into most of the
+ * fixed-size structures for the device. Don't free anything that
+ * is part of this larger block.
+ */
+void
+#if NeedFunctionPrototypes
+XkbFreeInfo(XkbSrvInfoPtr xkbi)
+#else
+XkbFreeInfo(xkbi)
+ XkbSrvInfoPtr xkbi;
+#endif
+{
+ if (xkbi->radioGroups) {
+ _XkbFree(xkbi->radioGroups);
+ xkbi->radioGroups= NULL;
+ }
+ if (xkbi->mouseKeyTimer) {
+ TimerFree(xkbi->mouseKeyTimer);
+ xkbi->mouseKeyTimer= NULL;
+ }
+ if (xkbi->slowKeysTimer) {
+ TimerFree(xkbi->slowKeysTimer);
+ xkbi->slowKeysTimer= NULL;
+ }
+ if (xkbi->bounceKeysTimer) {
+ TimerFree(xkbi->bounceKeysTimer);
+ xkbi->bounceKeysTimer= NULL;
+ }
+ if (xkbi->repeatKeyTimer) {
+ TimerFree(xkbi->repeatKeyTimer);
+ xkbi->repeatKeyTimer= NULL;
+ }
+ if (xkbi->krgTimer) {
+ TimerFree(xkbi->krgTimer);
+ xkbi->krgTimer= NULL;
+ }
+ xkbi->beepType= _BEEP_NONE;
+ if (xkbi->beepTimer) {
+ TimerFree(xkbi->beepTimer);
+ xkbi->beepTimer= NULL;
+ }
+ if (xkbi->desc) {
+ XkbFreeKeyboard(xkbi->desc,XkbAllComponentsMask,True);
+ xkbi->desc= NULL;
+ }
+ _XkbFree(xkbi);
+ return;
+}
+
+/***====================================================================***/
+
+extern int XkbDfltRepeatDelay;
+extern int XkbDfltRepeatInterval;
+
+extern unsigned short XkbDfltAccessXTimeout;
+extern unsigned int XkbDfltAccessXTimeoutMask;
+extern unsigned int XkbDfltAccessXFeedback;
+extern unsigned char XkbDfltAccessXOptions;
+
+int
+#if NeedFunctionPrototypes
+XkbProcessArguments(int argc,char *argv[],int i)
+#else
+XkbProcessArguments(argc,argv,i)
+ int argc;
+ char * argv[];
+ int i;
+#endif
+{
+ if (strcmp(argv[i],"-kb")==0) {
+ noXkbExtension= True;
+ return 1;
+ }
+ else if (strcmp(argv[i],"+kb")==0) {
+ noXkbExtension= False;
+ return 1;
+ }
+ else if (strncmp(argv[i], "-xkbmap", 7) == 0) {
+ if(++i < argc) {
+ XkbInitialMap= argv[i];
+ return 2;
+ }
+ else {
+ return -1;
+ }
+ }
+ else if (strncmp(argv[i], "-xkbdb", 7) == 0) {
+ if(++i < argc) {
+ XkbDB= argv[i];
+ return 2;
+ }
+ else {
+ return -1;
+ }
+ }
+ else if (strncmp(argv[i], "-noloadxkb", 7) == 0) {
+ XkbAutoLoad= 0;
+ return 1;
+ }
+ else if ((strncmp(argv[i],"-accessx",8)==0)||
+ (strncmp(argv[i],"+accessx",8)==0)) {
+ int j=1;
+ if (argv[i][0]=='-')
+ XkbWantAccessX= 0;
+ else {
+ XkbWantAccessX= 1;
+
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ XkbDfltAccessXTimeout = atoi(argv[++i]);
+ j++;
+
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ /*
+ * presumption that the reasonably useful range of
+ * values fits in 0..MAXINT since SunOS 4 doesn't
+ * have strtoul.
+ */
+ XkbDfltAccessXTimeoutMask=(unsigned int)
+ strtol(argv[++i],NULL,16);
+ j++;
+ }
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ if (argv[++i][0] == '1' )
+ XkbDfltAccessXFeedback=XkbAccessXFeedbackMask;
+ else
+ XkbDfltAccessXFeedback=0;
+ j++;
+ }
+ if ( ((i+1)<argc) && (isdigit(argv[i+1][0])) ) {
+ XkbDfltAccessXOptions=(unsigned char)
+ strtol(argv[++i],NULL,16);
+ j++;
+ }
+ }
+ }
+ return j;
+ }
+ if (strcmp (argv[i], "-ar1") == 0) { /* -ar1 int */
+ if (++i >= argc) UseMsg ();
+ XkbDfltRepeatDelay = (long)atoi(argv[i]);
+ return 2;
+ }
+ if (strcmp (argv[i], "-ar2") == 0) { /* -ar2 int */
+ if (++i >= argc) UseMsg ();
+ XkbDfltRepeatInterval = (long)atoi(argv[i]);
+ return 2;
+ }
+ return 0;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbUseMsg(void)
+#else
+XkbUseMsg()
+#endif
+{
+ ErrorF("The X Keyboard Extension adds the following arguments:\n");
+ ErrorF("-kb disable the X Keyboard Extension\n");
+ ErrorF("+kb enable the X Keyboard Extension\n");
+ ErrorF("[+-]accessx [ timeout [ timeout_mask [ feedback [ options_mask] ] ] ]\n");
+ ErrorF(" enable/disable accessx key sequences\n");
+ ErrorF("-ar1 set XKB autorepeat delay\n");
+ ErrorF("-ar2 set XKB autorepeat interval\n");
+ ErrorF("-noloadxkb don't load XKB keymap description\n");
+ ErrorF("-xkbcomp default keymap compiler\n");
+ ErrorF("-xkbdb file that contains default XKB keymaps\n");
+ ErrorF("-xkbmap XKB keyboard description to load on startup\n");
+}
diff --git a/xc/programs/Xserver/xkb/xkbLEDs.c b/xc/programs/Xserver/xkb/xkbLEDs.c
new file mode 100644
index 000000000..4ac6afa0e
--- /dev/null
+++ b/xc/programs/Xserver/xkb/xkbLEDs.c
@@ -0,0 +1,1212 @@
+/* $XConsortium: xkbLEDs.c /main/3 1996/08/31 12:44:48 kaleb $ */
+/************************************************************
+Copyright (c) 1995 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 <stdio.h>
+#include <ctype.h>
+#include <math.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+
+#include "XI.h"
+#include "XKBsrv.h"
+
+extern InputInfo inputInfo;
+
+/***====================================================================***/
+
+ /*
+ * unsigned
+ * XkbIndicatorsToUpdate(dev,changed,check_devs_rtrn)
+ *
+ * Given a keyboard and a set of state components that have changed,
+ * this function returns the indicators on the default keyboard
+ * feedback that might be affected. It also reports whether or not
+ * any extension devices might be affected in check_devs_rtrn.
+ */
+
+unsigned
+#if NeedFunctionPrototypes
+XkbIndicatorsToUpdate( DeviceIntPtr dev,
+ unsigned long state_changes,
+ Bool enable_changes)
+#else
+XkbIndicatorsToUpdate(dev,state_changes,enable_changes)
+ DeviceIntPtr dev;
+ unsigned long state_changes;
+ Bool enable_changes;
+#endif
+{
+register unsigned update= 0;
+XkbSrvLedInfoPtr sli;
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+
+ if (state_changes&(XkbModifierStateMask|XkbGroupStateMask))
+ update|= sli->usesEffective;
+ if (state_changes&(XkbModifierBaseMask|XkbGroupBaseMask))
+ update|= sli->usesBase;
+ if (state_changes&(XkbModifierLatchMask|XkbGroupLatchMask))
+ update|= sli->usesLatched;
+ if (state_changes&(XkbModifierLockMask|XkbGroupLockMask))
+ update|= sli->usesLocked;
+ if (state_changes&XkbCompatStateMask)
+ update|= sli->usesCompat;
+ if (enable_changes)
+ update|= sli->usesControls;
+ return update;
+}
+
+/***====================================================================***/
+
+ /*
+ * Bool
+ * XkbApplyLEDChangeToKeyboard(xkbi,map,on,change)
+ *
+ * Some indicators "drive" the keyboard when their state is explicitly
+ * changed, as described in section 9.2.1 of the XKB protocol spec.
+ * This function updates the state and controls for the keyboard
+ * specified by 'xkbi' to reflect any changes that are required
+ * when the indicator described by 'map' is turned on or off. The
+ * extent of the changes is reported in change, which must be defined.
+ */
+Bool
+#if NeedFunctionPrototypes
+XkbApplyLEDChangeToKeyboard( XkbSrvInfoPtr xkbi,
+ XkbIndicatorMapPtr map,
+ Bool on,
+ XkbChangesPtr change)
+#else
+XkbApplyLEDChangeToKeyboard(xkbi,map,on,change)
+ XkbSrvInfoPtr xkbi;
+ XkbIndicatorMapPtr map;
+ Bool on;
+ XkbChangesPtr change;
+#endif
+{
+Bool ctrlChange,stateChange;
+XkbStatePtr state;
+
+ if ((map->flags&XkbIM_NoExplicit)||((map->flags&XkbIM_LEDDrivesKB)==0))
+ return False;
+ ctrlChange= stateChange= False;
+ if (map->ctrls) {
+ XkbControlsPtr ctrls= xkbi->desc->ctrls;
+ unsigned old;
+
+ old= ctrls->enabled_ctrls;
+ if (on) ctrls->enabled_ctrls|= map->ctrls;
+ else ctrls->enabled_ctrls&= ~map->ctrls;
+ if (old!=ctrls->enabled_ctrls) {
+ change->ctrls.changed_ctrls= XkbControlsEnabledMask;
+ change->ctrls.enabled_ctrls_changes= old^ctrls->enabled_ctrls;
+ ctrlChange= True;
+ }
+ }
+ state= &xkbi->state;
+ if ((map->groups)&&((map->which_groups&(~XkbIM_UseBase))!=0)) {
+ register int i;
+ register unsigned bit,match;
+
+ if (on) match= (map->groups)&XkbAllGroupsMask;
+ else match= (~map->groups)&XkbAllGroupsMask;
+ if (map->which_groups&(XkbIM_UseLocked|XkbIM_UseEffective)) {
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (bit&match)
+ break;
+ }
+ if (map->which_groups&XkbIM_UseLatched)
+ XkbLatchGroup(xkbi->device,0); /* unlatch group */
+ state->locked_group= i;
+ stateChange= True;
+ }
+ else if (map->which_groups&(XkbIM_UseLatched|XkbIM_UseEffective)) {
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (bit&match)
+ break;
+ }
+ state->locked_group= 0;
+ XkbLatchGroup(xkbi->device,i);
+ stateChange= True;
+ }
+ }
+ if ((map->mods.mask)&&((map->which_mods&(~XkbIM_UseBase))!=0)) {
+ if (map->which_mods&(XkbIM_UseLocked|XkbIM_UseEffective)) {
+ register unsigned long old;
+ old= state->locked_mods;
+ if (on) state->locked_mods|= map->mods.mask;
+ else state->locked_mods&= ~map->mods.mask;
+ if (state->locked_mods!=old)
+ stateChange= True;
+ }
+ if (map->which_mods&(XkbIM_UseLatched|XkbIM_UseEffective)) {
+ register unsigned long newmods;
+ newmods= state->latched_mods;
+ if (on) newmods|= map->mods.mask;
+ else newmods&= ~map->mods.mask;
+ if (newmods!=state->locked_mods) {
+ newmods&= map->mods.mask;
+ XkbLatchModifiers(xkbi->device,map->mods.mask,newmods);
+ stateChange= True;
+ }
+ }
+ }
+ return (stateChange || ctrlChange);
+}
+
+/***====================================================================***/
+
+ /*
+ * void
+ * XkbSetIndicators(dev,affect,values,cause)
+ *
+ * Attempts to change the indicators specified in 'affect' to the
+ * states specified in 'values' for the default keyboard feedback
+ * on the keyboard specified by 'dev.' Attempts to change indicator
+ * state might be ignored or have no affect, depending on the XKB
+ * indicator map for any affected indicators, as described in section
+ * 9.2 of the XKB protocol specification.
+ *
+ * If 'changes' is non-NULL, this function notes any changes to the
+ * keyboard state, controls, or indicator state that result from this
+ * attempted change. If 'changes' is NULL, this function generates
+ * XKB events to report any such changes to interested clients.
+ *
+ * If 'cause' is non-NULL, it specifies the reason for the change,
+ * as reported in some XKB events. If it is NULL, this function
+ * assumes that the change is the result of a core protocol
+ * ChangeKeyboardMapping request.
+ */
+
+void
+#if NeedFunctionPrototypes
+XkbSetIndicators( DeviceIntPtr dev,
+ CARD32 affect,
+ CARD32 values,
+ XkbEventCausePtr cause)
+#else
+XkbSetIndicators(dev,affect,values,cause)
+ DeviceIntPtr dev;
+ CARD32 affect;
+ CARD32 values;
+ XkbEventCausePtr cause;
+#endif
+{
+XkbSrvLedInfoPtr sli;
+XkbChangesRec changes;
+xkbExtensionDeviceNotify ed;
+unsigned side_affected;
+
+ bzero((char *)&changes,sizeof(XkbChangesRec));
+ bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ sli->explicitState&= ~affect;
+ sli->explicitState|= (affect&values);
+ XkbApplyLedStateChanges(dev,sli,affect,&ed,&changes,cause);
+
+ side_affected= 0;
+ if (changes.state_changes!=0)
+ side_affected|= XkbIndicatorsToUpdate(dev,changes.state_changes,False);
+ if (changes.ctrls.enabled_ctrls_changes)
+ side_affected|= sli->usesControls;
+
+ if (side_affected) {
+ XkbUpdateLedAutoState(dev,sli,side_affected,&ed,&changes,cause);
+ affect|= side_affected;
+ }
+ XkbSendNotification(dev,&changes,cause);
+ if (ed.reason)
+ XkbSendExtensionDeviceNotify(dev,cause->client,&ed);
+ if (changes.state_changes || changes.ctrls.enabled_ctrls_changes)
+ XkbUpdateAllDeviceIndicators(NULL,cause);
+ return;
+}
+
+/***====================================================================***/
+
+ /*
+ * Bool
+ * ComputeAutoState(map,state,ctrls)
+ *
+ * This function reports the effect of applying the specified
+ * indicator map given the specified state and controls, as
+ * described in section 9.2 of the XKB protocol specification.
+ */
+
+static Bool
+#if NeedFunctionPrototypes
+ComputeAutoState( XkbIndicatorMapPtr map,
+ XkbStatePtr state,
+ XkbControlsPtr ctrls)
+#else
+ComputeAutoState(map,state,ctrls)
+ XkbIndicatorMapPtr map;
+ XkbStatePtr state;
+ XkbControlsPtr ctrls;
+#endif
+{
+Bool on;
+CARD8 mods,group;
+
+ on= False;
+ mods= group= 0;
+ if (map->which_mods&XkbIM_UseAnyMods) {
+ if (map->which_mods&XkbIM_UseBase)
+ mods|= state->base_mods;
+ if (map->which_mods&XkbIM_UseLatched)
+ mods|= state->latched_mods;
+ if (map->which_mods&XkbIM_UseLocked)
+ mods|= state->locked_mods;
+ if (map->which_mods&XkbIM_UseEffective)
+ mods|= state->mods;
+ if (map->which_mods&XkbIM_UseCompat)
+ mods|= state->compat_state;
+ on = ((map->mods.mask&mods)!=0);
+ on = on||((mods==0)&&(map->mods.mask==0)&&(map->mods.vmods==0));
+ }
+ if (map->which_groups&XkbIM_UseAnyGroup) {
+ if (map->which_groups&XkbIM_UseBase)
+ group|= (1L << state->base_group);
+ if (map->which_groups&XkbIM_UseLatched)
+ group|= (1L << state->latched_group);
+ if (map->which_groups&XkbIM_UseLocked)
+ group|= (1L << state->locked_group);
+ if (map->which_groups&XkbIM_UseEffective)
+ group|= (1L << state->group);
+ on = on||(((map->groups&group)!=0)||(map->groups==0));
+ }
+ if (map->ctrls)
+ on = on||(ctrls->enabled_ctrls&map->ctrls);
+ return on;
+}
+
+/***====================================================================***/
+
+ /*
+ * void
+ * XkbUpdateIndicators(dev,update,check_edevs,changes,cause)
+ *
+ * Applies the indicator maps for any indicators specified in
+ * 'update' from the default keyboard feedback on the device
+ * specified by 'dev.'
+ *
+ * If 'changes' is NULL, this function generates and XKB events
+ * required to report the necessary changes, otherwise it simply
+ * notes the indicators with changed state.
+ *
+ * If 'check_edevs' is True, this function also checks the indicator
+ * maps for any open extension devices that have them, and updates
+ * the state of any extension device indicators as necessary.
+ */
+
+void
+#if NeedFunctionPrototypes
+XkbUpdateIndicators( DeviceIntPtr dev,
+ register CARD32 update,
+ Bool check_edevs,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+#else
+XkbUpdateIndicators(dev,update,check_edevs,changes,cause)
+ DeviceIntPtr dev;
+ register CARD32 update;
+ Bool check_edevs;
+ XkbChangesPtr changes;
+ XkbEventCausePtr cause;
+#endif
+{
+XkbSrvLedInfoPtr sli;
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateLedAutoState(dev,sli,update,NULL,changes,cause);
+ if (check_edevs)
+ XkbUpdateAllDeviceIndicators(changes,cause);
+ return;
+}
+
+/***====================================================================***/
+
+void
+#if NeedFunctionPrototypes
+XkbUpdateAllDeviceIndicators(XkbChangesPtr changes,XkbEventCausePtr cause)
+#else
+XkbUpdateAllDeviceIndicators(changes,cause)
+ XkbChangesPtr changes;
+ XkbEventCausePtr cause;
+#endif
+{
+DeviceIntPtr edev;
+XkbSrvLedInfoPtr sli;
+
+ for (edev=inputInfo.devices;edev!=NULL;edev=edev->next) {
+ if (edev->kbdfeed) {
+ KbdFeedbackPtr kf;
+ for (kf=edev->kbdfeed;kf!=NULL;kf=kf->next) {
+ if ((kf->xkb_sli==NULL)||(kf->xkb_sli->maps==NULL))
+ continue;
+ sli= kf->xkb_sli;
+ XkbUpdateLedAutoState(edev,sli,sli->mapsPresent,NULL,
+ changes,cause);
+
+ }
+ }
+ if (edev->leds) {
+ LedFeedbackPtr lf;
+ for (lf=edev->leds;lf!=NULL;lf=lf->next) {
+ if ((lf->xkb_sli==NULL)||(lf->xkb_sli->maps==NULL))
+ continue;
+ sli= lf->xkb_sli;
+ XkbUpdateLedAutoState(edev,sli,sli->mapsPresent,NULL,
+ changes,cause);
+
+ }
+ }
+ }
+ return;
+}
+
+/***====================================================================***/
+
+ /*
+ * void
+ * XkbCheckIndicatorMaps(dev,sli,which)
+ *
+ * Updates the 'indicator accelerators' for the indicators specified
+ * by 'which' in the feedback specified by 'sli.' The indicator
+ * accelerators are internal to the server and are used to simplify
+ * and speed up the process of figuring out which indicators might
+ * be affected by a particular change in keyboard state or controls.
+ */
+
+void
+#if NeedFunctionPrototypes
+XkbCheckIndicatorMaps(DeviceIntPtr dev,XkbSrvLedInfoPtr sli,unsigned which)
+#else
+XkbCheckIndicatorMaps(dev,sli,which)
+ DeviceIntPtr dev;
+ XkbSrvLedInfoPtr sli;
+ unsigned which;
+#endif
+{
+register unsigned i,bit;
+XkbIndicatorMapPtr map;
+XkbDescPtr xkb;
+
+ if ((sli->flags&XkbSLI_HasOwnState)==0)
+ dev= (DeviceIntPtr)LookupKeyboardDevice();
+
+ sli->usesBase&= ~which;
+ sli->usesLatched&= ~which;
+ sli->usesLocked&= ~which;
+ sli->usesEffective&= ~which;
+ sli->usesCompat&= ~which;
+ sli->usesControls&= ~which;
+ sli->mapsPresent&= ~which;
+
+ xkb= dev->key->xkbInfo->desc;
+ for (i=0,bit=1,map=sli->maps;i<XkbNumIndicators;i++,bit<<=1,map++) {
+ if (which&bit) {
+ CARD8 what;
+
+ if (!XkbIM_InUse(map))
+ continue;
+ sli->mapsPresent|= bit;
+
+ what= (map->which_mods|map->which_groups);
+ if (what&XkbIM_UseBase)
+ sli->usesBase|= bit;
+ if (what&XkbIM_UseLatched)
+ sli->usesLatched|= bit;
+ if (what&XkbIM_UseLocked)
+ sli->usesLocked|= bit;
+ if (what&XkbIM_UseEffective)
+ sli->usesEffective|= bit;
+ if (what&XkbIM_UseCompat)
+ sli->usesCompat|= bit;
+ if (map->ctrls)
+ sli->usesControls|= bit;
+
+ map->mods.mask= map->mods.real_mods;
+ if (map->mods.vmods!=0) {
+ map->mods.mask|= XkbMaskForVMask(xkb,map->mods.vmods);
+ }
+ }
+ }
+ sli->usedComponents= 0;
+ if (sli->usesBase)
+ sli->usedComponents|= XkbModifierBaseMask|XkbGroupBaseMask;
+ if (sli->usesLatched)
+ sli->usedComponents|= XkbModifierLatchMask|XkbGroupLatchMask;
+ if (sli->usesLocked)
+ sli->usedComponents|= XkbModifierLockMask|XkbGroupLockMask;
+ if (sli->usesEffective)
+ sli->usedComponents|= XkbModifierStateMask|XkbGroupStateMask;
+ if (sli->usesCompat)
+ sli->usedComponents|= XkbCompatStateMask;
+ return;
+}
+
+/***====================================================================***/
+
+ /*
+ * XkbSrvLedInfoPtr
+ * XkbAllocSrvLedInfo(dev,kf,lf,needed_parts)
+ *
+ * Allocates an XkbSrvLedInfoPtr for the feedback specified by either
+ * 'kf' or 'lf' on the keyboard specified by 'dev.'
+ *
+ * If 'needed_parts' is non-zero, this function makes sure that any
+ * of the parts speicified therein are allocated.
+ */
+XkbSrvLedInfoPtr
+#if NeedFunctionPrototypes
+XkbAllocSrvLedInfo( DeviceIntPtr dev,
+ KbdFeedbackPtr kf,
+ LedFeedbackPtr lf,
+ unsigned needed_parts)
+#else
+XkbAllocSrvLedInfo(dev,kf,lf,needed_parts)
+ DeviceIntPtr dev;
+ KbdFeedbackPtr kf;
+ LedFeedbackPtr lf;
+ unsigned needed_parts;
+#endif
+{
+XkbSrvLedInfoPtr sli;
+Bool checkAccel;
+Bool checkNames;
+
+ sli= NULL;
+ checkAccel= checkNames= False;
+ if ((kf!=NULL)&&(kf->xkb_sli==NULL)) {
+ kf->xkb_sli= sli= _XkbTypedCalloc(1,XkbSrvLedInfoRec);
+ if (sli==NULL)
+ return NULL; /* ALLOCATION ERROR */
+ if (dev->key && dev->key->xkbInfo)
+ sli->flags= XkbSLI_HasOwnState;
+ else sli->flags= 0;
+ sli->class= KbdFeedbackClass;
+ sli->id= kf->ctrl.id;
+ sli->fb.kf= kf;
+
+ sli->autoState= 0;
+ sli->explicitState= kf->ctrl.leds;
+ sli->effectiveState= kf->ctrl.leds;
+
+ if ((kf==dev->kbdfeed) && (dev->key) && (dev->key->xkbInfo)) {
+ XkbDescPtr xkb;
+ xkb= dev->key->xkbInfo->desc;
+ sli->flags|= XkbSLI_IsDefault;
+ sli->physIndicators= xkb->indicators->phys_indicators;
+ sli->names= xkb->names->indicators;
+ sli->maps= xkb->indicators->maps;
+ checkNames= checkAccel= True;
+ }
+ else {
+ sli->physIndicators= XkbAllIndicatorsMask;
+ sli->names= NULL;
+ sli->maps= NULL;
+ }
+ }
+ else if ((kf!=NULL)&&((kf->xkb_sli->flags&XkbSLI_IsDefault)!=0)) {
+ XkbDescPtr xkb;
+ xkb= dev->key->xkbInfo->desc;
+ sli->physIndicators= xkb->indicators->phys_indicators;
+ if (xkb->names->indicators!=sli->names) {
+ checkNames= True;
+ sli->names= xkb->names->indicators;
+ }
+ if (xkb->indicators->maps!=sli->maps) {
+ checkAccel= True;
+ sli->maps= xkb->indicators->maps;
+ }
+ }
+ else if ((lf!=NULL)&&(lf->xkb_sli==NULL)) {
+ lf->xkb_sli= sli= _XkbTypedCalloc(1,XkbSrvLedInfoRec);
+ if (sli==NULL)
+ return NULL; /* ALLOCATION ERROR */
+ if (dev->key && dev->key->xkbInfo)
+ sli->flags= XkbSLI_HasOwnState;
+ else sli->flags= 0;
+ sli->class= LedFeedbackClass;
+ sli->id= lf->ctrl.id;
+ sli->fb.lf= lf;
+
+ sli->physIndicators= lf->ctrl.led_mask;
+ sli->autoState= 0;
+ sli->explicitState= lf->ctrl.led_values;
+ sli->effectiveState= lf->ctrl.led_values;
+ sli->maps= NULL;
+ sli->names= NULL;
+ }
+ if ((sli->names==NULL)&&(needed_parts&XkbXI_IndicatorNamesMask))
+ sli->names= _XkbTypedCalloc(XkbNumIndicators,Atom);
+ if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask))
+ sli->maps= _XkbTypedCalloc(XkbNumIndicators,XkbIndicatorMapRec);
+ if (checkNames) {
+ register unsigned i,bit;
+ sli->namesPresent= 0;
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (sli->names[i]!=None)
+ sli->namesPresent|= bit;
+ }
+ }
+ if (checkAccel)
+ XkbCheckIndicatorMaps(dev,sli,XkbAllIndicatorsMask);
+ return sli;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbFreeSrvLedInfo(XkbSrvLedInfoPtr sli)
+#else
+XkbFreeSrvLedInfo(sli)
+ XkbSrvLedInfoPtr sli;
+#endif
+{
+ if ((sli->flags&XkbSLI_IsDefault)==0) {
+ if (sli->maps) _XkbFree(sli->maps);
+ if (sli->names) _XkbFree(sli->names);
+ }
+ sli->maps= NULL;
+ sli->names= NULL;
+ _XkbFree(sli);
+ return;
+}
+
+
+/***====================================================================***/
+
+ /*
+ * XkbSrvLedInfoPtr
+ * XkbFindSrvLedInfo(dev,class,id,needed_parts)
+ *
+ * Finds the XkbSrvLedInfoPtr for the specified 'class' and 'id'
+ * on the device specified by 'dev.' If the class and id specify
+ * a valid device feedback, this function returns the existing
+ * feedback or allocates a new one.
+ *
+ */
+
+XkbSrvLedInfoPtr
+#if NeedFunctionPrototypes
+XkbFindSrvLedInfo( DeviceIntPtr dev,
+ unsigned class,
+ unsigned id,
+ unsigned needed_parts)
+#else
+XkbFindSrvLedInfo(dev,class,id,needed_parts)
+ DeviceIntPtr dev;
+ unsigned class;
+ unsigned id;
+ unsigned needed_parts;
+#endif
+{
+XkbSrvLedInfoPtr sli;
+
+ /* optimization to check for most common case */
+ if (((class==XkbDfltXIClass)&&(id==XkbDfltXIId))&&(dev->kbdfeed)) {
+ XkbSrvLedInfoPtr sli;
+ sli= dev->kbdfeed->xkb_sli;
+ if (dev->kbdfeed->xkb_sli==NULL) {
+ sli= XkbAllocSrvLedInfo(dev,dev->kbdfeed,NULL,needed_parts);
+ dev->kbdfeed->xkb_sli= sli;
+ }
+ return dev->kbdfeed->xkb_sli;
+ }
+
+ sli= NULL;
+ if (class==XkbDfltXIClass) {
+ if (dev->kbdfeed) class= KbdFeedbackClass;
+ else if (dev->leds) class= LedFeedbackClass;
+ else return NULL;
+ }
+ if (class==KbdFeedbackClass) {
+ KbdFeedbackPtr kf;
+ for (kf=dev->kbdfeed;kf!=NULL;kf=kf->next) {
+ if ((id==XkbDfltXIId)||(id==kf->ctrl.id)) {
+ if (kf->xkb_sli==NULL)
+ kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,needed_parts);
+ sli= kf->xkb_sli;
+ break;
+ }
+ }
+ }
+ else if (class==LedFeedbackClass) {
+ LedFeedbackPtr lf;
+ for (lf=dev->leds;lf!=NULL;lf=lf->next) {
+ if ((id==XkbDfltXIId)||(id==lf->ctrl.id)) {
+ if (lf->xkb_sli==NULL)
+ lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,needed_parts);
+ sli= lf->xkb_sli;
+ break;
+ }
+ }
+ }
+ if ((sli->names==NULL)&&(needed_parts&XkbXI_IndicatorNamesMask))
+ sli->names= _XkbTypedCalloc(XkbNumIndicators,Atom);
+ if ((sli->maps==NULL)&&(needed_parts&XkbXI_IndicatorMapsMask))
+ sli->maps= _XkbTypedCalloc(XkbNumIndicators,XkbIndicatorMapRec);
+ return sli;
+}
+
+/***====================================================================***/
+
+void
+#if NeedFunctionPrototypes
+XkbFlushLedEvents( DeviceIntPtr dev,
+ DeviceIntPtr kbd,
+ XkbSrvLedInfoPtr sli,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+#else
+XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause)
+ DeviceIntPtr dev;
+ DeviceIntPtr kbd;
+ XkbSrvLedInfoPtr sli;
+ xkbExtensionDeviceNotify * ed;
+ XkbChangesPtr changes;
+ XkbEventCausePtr cause;
+#endif
+{
+ if (changes) {
+ if (changes->indicators.state_changes)
+ XkbDDXUpdateDeviceIndicators(dev,sli,sli->effectiveState);
+ XkbSendNotification(kbd,changes,cause);
+ bzero((char *)changes,sizeof(XkbChangesRec));
+ }
+ if (ed && (ed->reason)) {
+ if ((dev!=kbd)&&(ed->reason&XkbXI_IndicatorStateMask))
+ XkbDDXUpdateDeviceIndicators(dev,sli,sli->effectiveState);
+ XkbSendExtensionDeviceNotify(dev,cause->client,ed);
+ }
+ bzero((char *)ed,sizeof(XkbExtensionDeviceNotify));
+ return;
+}
+
+/***====================================================================***/
+
+void
+#if NeedFunctionPrototypes
+XkbApplyLedNameChanges( DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ unsigned changed_names,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+#else
+XkbApplyLedNameChanges(dev,sli,changed_names,ed,changes,cause)
+ DeviceIntPtr dev;
+ XkbSrvLedInfoPtr sli;
+ unsigned changed_names;
+ xkbExtensionDeviceNotify * ed;
+ XkbChangesPtr changes;
+ XkbEventCausePtr cause;
+#endif
+{
+DeviceIntPtr kbd;
+XkbChangesRec my_changes;
+xkbExtensionDeviceNotify my_ed;
+
+ if (changed_names==0)
+ return;
+ if (dev->key && dev->key->xkbInfo)
+ kbd= dev;
+ else kbd= (DeviceIntPtr)LookupKeyboardDevice();
+
+ if (ed==NULL) {
+ ed= &my_ed;
+ bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
+ }
+ else if ((ed->reason&XkbXI_IndicatorsMask)&&
+ ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ }
+
+ if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
+ if (changes==NULL) {
+ changes= &my_changes;
+ bzero((char *)changes,sizeof(XkbChangesRec));
+ }
+ changes->names.changed|= XkbIndicatorNamesMask;
+ changes->names.changed_indicators|= changed_names;
+ }
+
+ ed->reason|= (XkbXI_IndicatorNamesMask&(~XkbXIUnsupported));
+ ed->ledClass= sli->class;
+ ed->ledID= sli->id;
+ ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed->ledState= sli->effectiveState;
+ ed->unsupported|= XkbXIUnsupported&XkbXI_IndicatorNamesMask;
+ ed->supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported);
+
+ if (changes!=&my_changes) changes= NULL;
+ if (ed!=&my_ed) ed= NULL;
+ if (changes || ed)
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ return;
+}
+/***====================================================================***/
+
+ /*
+ * void
+ * XkbApplyLedMapChanges(dev,sli,changed_maps,changes,cause)
+ *
+ * Handles all of the secondary effects of the changes to the
+ * feedback specified by 'sli' on the device specified by 'dev.'
+ *
+ * If 'changed_maps' specifies any indicators, this function generates
+ * XkbExtensionDeviceNotify events and possibly IndicatorMapNotify
+ * events to report the changes, and recalculates the effective
+ * state of each indicator with a changed map. If any indicators
+ * change state, the server generates XkbExtensionDeviceNotify and
+ * XkbIndicatorStateNotify events as appropriate.
+ *
+ * If 'changes' is non-NULL, this function updates it to reflect
+ * any changes to the keyboard state or controls or to the 'core'
+ * indicator names, maps, or state. If 'changes' is NULL, this
+ * function generates XKB events as needed to report the changes.
+ * If 'dev' is not a keyboard device, any changes are reported
+ * for the core keyboard.
+ *
+ * The 'cause' specifies the reason for the event (key event or
+ * request) for the change, as reported in some XKB events.
+ */
+
+void
+#if NeedFunctionPrototypes
+XkbApplyLedMapChanges( DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ unsigned changed_maps,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+#else
+XkbApplyLedMapChanges(dev,sli,changed_maps,ed,changes,cause)
+ DeviceIntPtr dev;
+ XkbSrvLedInfoPtr sli;
+ unsigned changed_maps;
+ xkbExtensionDeviceNotify * ed;
+ XkbChangesPtr changes;
+ XkbEventCausePtr cause;
+#endif
+{
+DeviceIntPtr kbd;
+XkbChangesRec my_changes;
+xkbExtensionDeviceNotify my_ed;
+
+ if (changed_maps==0)
+ return;
+ if (dev->key && dev->key->xkbInfo)
+ kbd= dev;
+ else kbd= (DeviceIntPtr)LookupKeyboardDevice();
+
+ if (ed==NULL) {
+ ed= &my_ed;
+ bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
+ }
+ else if ((ed->reason&XkbXI_IndicatorsMask)&&
+ ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ }
+
+ if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
+ if (changes==NULL) {
+ changes= &my_changes;
+ bzero((char *)changes,sizeof(XkbChangesRec));
+ }
+ changes->indicators.map_changes|= changed_maps;
+ }
+
+ XkbCheckIndicatorMaps(dev,sli,changed_maps);
+
+ ed->reason|= (XkbXI_IndicatorMapsMask&(~XkbXIUnsupported));
+ ed->ledClass= sli->class;
+ ed->ledID= sli->id;
+ ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed->ledState= sli->effectiveState;
+ ed->unsupported|= XkbXIUnsupported&XkbXI_IndicatorMapsMask;
+ ed->supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported);
+
+ XkbUpdateLedAutoState(dev,sli,changed_maps,ed,changes,cause);
+
+ if (changes!=&my_changes) changes= NULL;
+ if (ed!=&my_ed) ed= NULL;
+ if (changes || ed)
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ return;
+}
+
+/***====================================================================***/
+
+void
+#if NeedFunctionPrototypes
+XkbApplyLedStateChanges(DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ unsigned changed_leds,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+#else
+XkbApplyLedStateChanges(dev,sli,changed_leds,ed,changes,cause)
+ DeviceIntPtr dev;
+ XkbSrvLedInfoPtr sli;
+ unsigned changed_leds;
+ xkbExtensionDeviceNotify * ed;
+ XkbChangesPtr changes;
+ XkbEventCausePtr cause;
+#endif
+{
+XkbSrvInfoPtr xkbi;
+DeviceIntPtr kbd;
+XkbChangesRec my_changes;
+xkbExtensionDeviceNotify my_ed;
+register unsigned i,bit,affected;
+XkbIndicatorMapPtr map;
+unsigned oldState;
+Bool kb_changed;
+
+ if (changed_leds==0)
+ return;
+ if (dev->key && dev->key->xkbInfo)
+ kbd= dev;
+ else kbd= (DeviceIntPtr)LookupKeyboardDevice();
+ xkbi= kbd->key->xkbInfo;
+
+ if (changes==NULL) {
+ changes= &my_changes;
+ bzero((char *)changes,sizeof(XkbChangesRec));
+ }
+
+ kb_changed= False;
+ affected= changed_leds;
+ oldState= sli->effectiveState;
+ for (i=0,bit=1;(i<XkbNumIndicators)&&(affected);i++,bit<<=1) {
+ if ((affected&bit)==0)
+ continue;
+ affected&= ~bit;
+ map= &sli->maps[i];
+ if (map->flags&XkbIM_NoExplicit) {
+ sli->explicitState&= ~bit;
+ continue;
+ }
+ if (map->flags&XkbIM_LEDDrivesKB) {
+ Bool on= ((sli->explicitState&bit)!=0);
+ if (XkbApplyLEDChangeToKeyboard(xkbi,map,on,changes))
+ kb_changed= True;
+ }
+ }
+ sli->effectiveState= (sli->autoState|sli->explicitState);
+ affected= sli->effectiveState^oldState;
+
+ if (ed==NULL) {
+ ed= &my_ed;
+ bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
+ }
+ else if (affected&&(ed->reason&XkbXI_IndicatorsMask)&&
+ ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ }
+
+ if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault))
+ changes->indicators.state_changes|= affected;
+ if (affected) {
+ ed->reason|= (XkbXI_IndicatorStateMask&(~XkbXIUnsupported));
+ ed->ledClass= sli->class;
+ ed->ledID= sli->id;
+ ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed->ledState= sli->effectiveState;
+ ed->unsupported|= XkbXIUnsupported&XkbXI_IndicatorStateMask;
+ ed->supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported);
+ }
+
+ if (kb_changed) {
+ XkbComputeDerivedState(kbd->key->xkbInfo);
+ XkbUpdateLedAutoState(dev,sli,sli->mapsPresent,ed,changes,cause);
+ }
+
+ if (changes!=&my_changes) changes= NULL;
+ if (ed!=&my_ed) ed= NULL;
+ if (changes || ed)
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ if (kb_changed)
+ XkbUpdateAllDeviceIndicators(NULL,cause);
+ return;
+}
+
+/***====================================================================***/
+
+void
+#if NeedFunctionPrototypes
+XkbUpdateLedAutoState( DeviceIntPtr dev,
+ XkbSrvLedInfoPtr sli,
+ unsigned maps_to_check,
+ xkbExtensionDeviceNotify * ed,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+#else
+XkbUpdateLedAutoState(dev,sli,maps_to_check,ed,changes,cause)
+ DeviceIntPtr dev;
+ XkbSrvLedInfoPtr sli;
+ unsigned maps_to_check;
+ xkbExtensionDeviceNotify * ed;
+ XkbChangesPtr changes;
+ XkbEventCausePtr cause;
+#endif
+{
+DeviceIntPtr kbd;
+XkbStatePtr state;
+XkbControlsPtr ctrls;
+XkbChangesRec my_changes;
+xkbExtensionDeviceNotify my_ed;
+register unsigned i,bit,affected;
+register XkbIndicatorMapPtr map;
+unsigned oldState;
+
+ if ((maps_to_check==0)||(sli->maps==NULL)||(sli->mapsPresent==0))
+ return;
+
+ if (dev->key && dev->key->xkbInfo)
+ kbd= dev;
+ else kbd= (DeviceIntPtr)LookupKeyboardDevice();
+
+ state= &kbd->key->xkbInfo->state;
+ ctrls= kbd->key->xkbInfo->desc->ctrls;
+ affected= maps_to_check;
+ oldState= sli->effectiveState;
+ sli->autoState&= ~affected;
+ for (i=0,bit=1;(i<XkbNumIndicators)&&(affected);i++,bit<<=1) {
+ if ((affected&bit)==0)
+ continue;
+ affected&= ~bit;
+ map= &sli->maps[i];
+ if((!(map->flags&XkbIM_NoAutomatic))&&ComputeAutoState(map,state,ctrls))
+ sli->autoState|= bit;
+ }
+ sli->effectiveState= (sli->autoState|sli->explicitState);
+ affected= sli->effectiveState^oldState;
+ if (affected==0)
+ return;
+
+ if (ed==NULL) {
+ ed= &my_ed;
+ bzero((char *)ed,sizeof(xkbExtensionDeviceNotify));
+ }
+ else if ((ed->reason&XkbXI_IndicatorsMask)&&
+ ((ed->ledClass!=sli->class)||(ed->ledID!=sli->id))) {
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ }
+
+ if ((kbd==dev)&&(sli->flags&XkbSLI_IsDefault)) {
+ if (changes==NULL) {
+ changes= &my_changes;
+ bzero((char *)changes,sizeof(XkbChangesRec));
+ }
+ changes->indicators.state_changes|= affected;
+ }
+
+ ed->reason|= (XkbXI_IndicatorStateMask&(~XkbXIUnsupported));
+ ed->ledClass= sli->class;
+ ed->ledID= sli->id;
+ ed->ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed->ledState= sli->effectiveState;
+ ed->unsupported|= XkbXIUnsupported&XkbXI_IndicatorStateMask;
+ ed->supported= XkbXI_AllFeaturesMask&(~XkbXIUnsupported);
+
+ if (changes!=&my_changes) changes= NULL;
+ if (ed!=&my_ed) ed= NULL;
+ if (changes || ed)
+ XkbFlushLedEvents(dev,kbd,sli,ed,changes,cause);
+ return;
+}
+
+/***====================================================================***/
+
+static void
+#if NeedFunctionPrototypes
+_UpdateButtonVMods( XkbDescPtr xkb,
+ unsigned num_btns,
+ XkbAction * acts,
+ unsigned changed,
+ xkbExtensionDeviceNotify * ed_inout)
+#else
+_UpdateButtonVMods(xkb,num_btns,acts,changed,ed_inout)
+ XkbDescPtr xkb;
+ unsigned num_btns;
+ XkbAction * acts;
+ unsigned changed;
+ xkbExtensionDeviceNotify * ed_inout;
+#endif
+{
+register int i;
+
+ for (i=0;i<num_btns;i++,acts++) {
+ if ((acts->any.type!=XkbSA_NoAction)&&
+ XkbUpdateActionVirtualMods(xkb,acts,changed)) {
+ if ((ed_inout->reason&XkbXI_ButtonActionsMask)==0) {
+ ed_inout->reason|= XkbXI_ButtonActionsMask;
+ ed_inout->firstBtn= i;
+ ed_inout->nBtns= 1;
+ }
+ else {
+ ed_inout->nBtns= (i-ed_inout->firstBtn)+1;
+ }
+ }
+ }
+ return;
+}
+
+static void
+#if NeedFunctionPrototypes
+_UpdateMapVMods( XkbDescPtr xkb,
+ register XkbIndicatorMapPtr map,
+ unsigned changed_vmods,
+ unsigned * changed_maps_rtrn)
+#else
+_UpdateMapVMods(xkb,map,changed_vmods,changed_maps_rtrn)
+ XkbDescPtr xkb;
+ register XkbIndicatorMapPtr map;
+ unsigned changed_vmods;
+ unsigned * changed_maps_rtrn;
+#endif
+{
+register int i;
+
+ *changed_maps_rtrn= 0;
+ for (i=0;i<XkbNumIndicators;i++,map++) {
+ if (map->mods.vmods&changed_vmods) {
+ map->mods.mask= map->mods.real_mods;
+ map->mods.mask|= XkbMaskForVMask(xkb,map->mods.vmods);
+ *changed_maps_rtrn|= (1L<<i);
+ }
+ }
+ return;
+}
+
+static void
+#if NeedFunctionPrototypes
+_UpdateDeviceVMods( DeviceIntPtr dev,
+ XkbDescPtr xkb,
+ unsigned changed,
+ XkbEventCausePtr cause)
+#else
+_UpdateDeviceVMods(dev,xkb,changed,cause)
+ DeviceIntPtr dev;
+ XkbDescPtr xkb;
+ unsigned changed;
+ XkbEventCausePtr cause;
+#endif
+{
+xkbExtensionDeviceNotify ed;
+XkbSrvLedInfoPtr sli;
+unsigned changed_maps;
+
+ bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
+ ed.deviceID= dev->id;
+ if ((dev->button)&&(dev->button->xkb_acts)) {
+ _UpdateButtonVMods(xkb,dev->button->numButtons,
+ dev->button->xkb_acts,changed,&ed);
+ }
+ if (dev->kbdfeed) {
+ KbdFeedbackPtr kf;
+ for (kf=dev->kbdfeed;kf!=NULL;kf=kf->next) {
+ if ((kf->xkb_sli==NULL)||(kf->xkb_sli->maps==NULL))
+ continue;
+ sli= kf->xkb_sli;
+ _UpdateMapVMods(xkb,sli->maps,changed,&changed_maps);
+ if (changed_maps) {
+ if (ed.reason&XkbXI_IndicatorsMask) {
+ XkbSendExtensionDeviceNotify(dev,NULL,&ed);
+ ed.reason= 0;
+ ed.firstBtn= ed.nBtns;
+ }
+ ed.ledClass= sli->class;
+ ed.ledID= sli->id;
+ ed.ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed.reason|= XkbXI_IndicatorMapsMask;
+ XkbUpdateLedAutoState(dev,sli,changed_maps,&ed,NULL,cause);
+ }
+ }
+ }
+ if (dev->leds) {
+ LedFeedbackPtr lf;
+ for (lf=dev->leds;lf!=NULL;lf=lf->next) {
+ if ((lf->xkb_sli==NULL)||(lf->xkb_sli->maps==NULL))
+ continue;
+ sli= lf->xkb_sli;
+ _UpdateMapVMods(xkb,sli->maps,changed,&changed_maps);
+ if (changed_maps) {
+ if (ed.reason&XkbXI_IndicatorsMask) {
+ XkbSendExtensionDeviceNotify(dev,NULL,&ed);
+ ed.reason= 0;
+ ed.firstBtn= ed.nBtns;
+ }
+ ed.ledClass= sli->class;
+ ed.ledID= sli->id;
+ ed.ledsDefined= sli->namesPresent|sli->mapsPresent;
+ ed.reason|= XkbXI_IndicatorMapsMask;
+ XkbUpdateLedAutoState(dev,sli,changed_maps,&ed,NULL,cause);
+ }
+ }
+ }
+ if (ed.reason!=0)
+ XkbSendExtensionDeviceNotify(dev,NULL,&ed);
+ return;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbApplyVModChangesToAllDevices( DeviceIntPtr dev,
+ XkbDescPtr xkb,
+ unsigned changed,
+ XkbEventCausePtr cause)
+#else
+XkbApplyVModChangesToAllDevices(dev,xkb,changed,cause)
+ DeviceIntPtr dev;
+ XkbDescPtr xkb;
+ unsigned changed;
+ XkbEventCausePtr cause;
+#endif
+{
+DeviceIntPtr edev;
+ if (dev!=(DeviceIntPtr)LookupKeyboardDevice())
+ return;
+ for (edev=inputInfo.devices;edev!=NULL;edev=edev->next) {
+ if (edev->key)
+ continue;
+ _UpdateDeviceVMods(edev,xkb,changed,cause);
+ }
+ for (edev=inputInfo.off_devices;edev!=NULL;edev=edev->next) {
+ if (edev->key)
+ continue;
+ _UpdateDeviceVMods(edev,xkb,changed,cause);
+ }
+ return;
+}
diff --git a/xc/programs/Xserver/xkb/xkbPrKeyEv.c b/xc/programs/Xserver/xkb/xkbPrKeyEv.c
new file mode 100644
index 000000000..e52bfda72
--- /dev/null
+++ b/xc/programs/Xserver/xkb/xkbPrKeyEv.c
@@ -0,0 +1,198 @@
+/* $XConsortium: xkbPrKeyEv.c /main/6 1996/02/05 10:18:46 kaleb $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+/* $XFree86: xc/programs/Xserver/xkb/xkbPrKeyEv.c,v 3.6 1997/07/12 12:09:42 hohndel Exp $ */
+
+#include <stdio.h>
+#include <math.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "XKBsrv.h"
+#include <ctype.h>
+
+
+/***====================================================================***/
+
+void
+#if NeedFunctionPrototypes
+XkbProcessKeyboardEvent(xEvent *xE,DeviceIntPtr keybd,int count)
+#else
+XkbProcessKeyboardEvent(xE,keybd,count)
+ xEvent * xE;
+ DeviceIntPtr keybd;
+ int count;
+#endif
+{
+KeyClassPtr keyc = keybd->key;
+XkbSrvInfoPtr xkbi;
+int key;
+XkbBehavior behavior;
+
+ xkbi= keyc->xkbInfo;
+ key= xE->u.u.detail;
+#ifdef DEBUG
+ if (xkbDebugFlags&0x8) {
+ ErrorF("XkbPKE: Key %d %s\n",key,(xE->u.u.type==KeyPress?"down":"up"));
+ }
+#endif
+
+ if ( (xkbi->repeatKey==key) && (xE->u.u.type==KeyRelease) &&
+ ((xkbi->desc->ctrls->enabled_ctrls&XkbRepeatKeysMask)==0) ) {
+ AccessXCancelRepeatKey(xkbi,key);
+ }
+
+ behavior= xkbi->desc->server->behaviors[key];
+ /* The "permanent" flag indicates a hard-wired behavior that occurs */
+ /* below XKB, such as a key that physically locks. XKB does not */
+ /* do anything to implement the behavior, but it *does* report that */
+ /* key is hardwired */
+ if ((behavior.type&XkbKB_Permanent)==0) {
+ switch (behavior.type) {
+ case XkbKB_Default:
+ if (( xE->u.u.type == KeyPress ) &&
+ (keyc->down[key>>3] & (1<<(key&7)))) {
+ XkbLastRepeatEvent= (pointer)xE;
+ xE->u.u.type = KeyRelease;
+ XkbHandleActions(keybd,keybd,xE,count);
+ xE->u.u.type = KeyPress;
+ XkbHandleActions(keybd,keybd,xE,count);
+ XkbLastRepeatEvent= NULL;
+ return;
+ }
+ else if ((xE->u.u.type==KeyRelease) &&
+ (!(keyc->down[key>>3]&(1<<(key&7))))) {
+ XkbLastRepeatEvent= (pointer)&xE;
+ xE->u.u.type = KeyPress;
+ XkbHandleActions(keybd,keybd,xE,count);
+ xE->u.u.type = KeyRelease;
+ XkbHandleActions(keybd,keybd,xE,count);
+ XkbLastRepeatEvent= NULL;
+ return;
+ }
+ break;
+ case XkbKB_Lock:
+ if ( xE->u.u.type == KeyRelease )
+ return;
+ else {
+ int bit= 1<<(key&7);
+ if ( keyc->down[key>>3]&bit )
+ xE->u.u.type= KeyRelease;
+ }
+ break;
+ case XkbKB_RadioGroup:
+ if ( xE->u.u.type == KeyRelease )
+ return;
+ else {
+ unsigned ndx= (behavior.data&(~XkbKB_RGAllowNone));
+ if ( ndx<xkbi->nRadioGroups ) {
+ XkbRadioGroupPtr rg;
+
+ rg = &xkbi->radioGroups[ndx];
+ if ( rg->currentDown == xE->u.u.detail ) {
+ if (behavior.data&XkbKB_RGAllowNone) {
+ xE->u.u.type = KeyRelease;
+ XkbHandleActions(keybd,keybd,xE,count);
+ rg->currentDown= 0;
+ }
+ return;
+ }
+ if ( rg->currentDown!=0 ) {
+ int key = xE->u.u.detail;
+ xE->u.u.type= KeyRelease;
+ xE->u.u.detail= rg->currentDown;
+ XkbHandleActions(keybd,keybd,xE,count);
+ xE->u.u.type= KeyPress;
+ xE->u.u.detail= key;
+ }
+ rg->currentDown= key;
+ }
+ else ErrorF("InternalError! Illegal radio group %d\n",ndx);
+ }
+ break;
+ case XkbKB_Overlay1: case XkbKB_Overlay2:
+ {
+ unsigned which;
+ if (behavior.type==XkbKB_Overlay1) which= XkbOverlay1Mask;
+ else which= XkbOverlay2Mask;
+ if ( (xkbi->desc->ctrls->enabled_ctrls&which)==0 )
+ break;
+ if ((behavior.data>=xkbi->desc->min_key_code)&&
+ (behavior.data<=xkbi->desc->max_key_code)) {
+ xE->u.u.detail= behavior.data;
+ /* 9/11/94 (ef) -- XXX! need to match release with */
+ /* press even if the state of the */
+ /* corresponding overlay control */
+ /* changes while the key is down */
+ }
+ }
+ break;
+ default:
+ ErrorF("unknown key behavior 0x%04x\n",behavior.type);
+#if defined(MetroLink)
+ return;
+#else
+ break;
+#endif
+ }
+ }
+ XkbHandleActions(keybd,keybd,xE,count);
+ return;
+}
+
+void
+#if NeedFunctionPrototypes
+ProcessKeyboardEvent(xEvent *xE,DeviceIntPtr keybd,int count)
+#else
+ProcessKeyboardEvent(xE,keybd,count)
+ xEvent * xE;
+ DeviceIntPtr keybd;
+ int count;
+#endif
+{
+KeyClassPtr keyc = keybd->key;
+XkbSrvInfoPtr xkbi;
+
+ xkbi= keyc->xkbInfo;
+
+#ifdef DEBUG
+ if (xkbDebugFlags&0x8) {
+ int key= xE->u.u.detail;
+ ErrorF("PKE: Key %d %s\n",key,(xE->u.u.type==KeyPress?"down":"up"));
+ }
+#endif
+ if ((xkbi->desc->ctrls->enabled_ctrls&XkbAllFilteredEventsMask)==0)
+ XkbProcessKeyboardEvent(xE,keybd,count);
+ else if (xE->u.u.type==KeyPress)
+ AccessXFilterPressEvent(xE,keybd,count);
+ else if (xE->u.u.type==KeyRelease)
+ AccessXFilterReleaseEvent(xE,keybd,count);
+ return;
+}
+
diff --git a/xc/programs/Xserver/xkb/xkbPrOtherEv.c b/xc/programs/Xserver/xkb/xkbPrOtherEv.c
new file mode 100644
index 000000000..309f0eca2
--- /dev/null
+++ b/xc/programs/Xserver/xkb/xkbPrOtherEv.c
@@ -0,0 +1,88 @@
+/* $XConsortium: xkbPrOtherEv.c /main/1 1996/01/14 16:46:43 kaleb $ */
+/************************************************************
+Copyright (c) 1995 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 <stdio.h>
+#include <math.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "XKBsrv.h"
+
+#include "XI.h"
+#include "XIproto.h"
+
+extern void ProcessOtherEvent(
+#if NeedFunctionPrototypes
+ xEvent * /* xE */,
+ DeviceIntPtr /* dev */,
+ int /* count */
+#endif
+);
+
+/***====================================================================***/
+
+void
+#if NeedFunctionPrototypes
+XkbProcessOtherEvent(xEvent *xE,DeviceIntPtr dev,int count)
+#else
+XkbProcessOtherEvent(xE,dev,count)
+ xEvent * xE;
+ DeviceIntPtr dev;
+ int count;
+#endif
+{
+Bool xkbCares,isBtn;
+
+ xkbCares= True;
+ isBtn= False;
+ switch ( xE->u.u.type ) {
+ case KeyPress: xE->u.u.type= DeviceKeyPress; break;
+ case KeyRelease: xE->u.u.type= DeviceKeyRelease; break;
+ case ButtonPress: xE->u.u.type= DeviceButtonPress;
+ isBtn= True;
+ break;
+ case ButtonRelease: xE->u.u.type= DeviceButtonRelease;
+ isBtn= True;
+ break;
+ default: xkbCares= False; break;
+ }
+ if (xkbCares) {
+ if ((!isBtn)||((dev->button)&&(dev->button->xkb_acts))) {
+ DeviceIntPtr kbd;
+ if (dev->key) kbd= dev;
+ else kbd= (DeviceIntPtr)LookupKeyboardDevice();
+ XkbHandleActions(dev,kbd,xE,count);
+ return;
+ }
+ }
+ ProcessOtherEvent(xE,dev,count);
+ return;
+}
+
diff --git a/xc/programs/Xserver/xkb/xkbSwap.c b/xc/programs/Xserver/xkb/xkbSwap.c
new file mode 100644
index 000000000..c22b77cdc
--- /dev/null
+++ b/xc/programs/Xserver/xkb/xkbSwap.c
@@ -0,0 +1,760 @@
+/* $XConsortium: xkbSwap.c /main/9 1996/02/02 14:39:39 kaleb $ */
+/* $XFree86: xc/programs/Xserver/xkb/xkbSwap.c,v 3.0 1996/08/25 14:14:04 dawes Exp $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#include "stdio.h"
+#include "X.h"
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include "Xproto.h"
+#include "misc.h"
+#include "inputstr.h"
+#include "XKBsrv.h"
+#include "XKBstr.h"
+#include "extnsionst.h"
+
+#if NeedFunctionPrototypes
+#define PROC_EXTERN(pfunc) extern int pfunc(ClientPtr)
+#else
+#define PROC_EXTERN(pfunc) extern int pfunc()
+#endif
+
+PROC_EXTERN(ProcXkbUseExtension);
+PROC_EXTERN(ProcXkbSelectEvents);
+PROC_EXTERN(ProcXkbBell);
+PROC_EXTERN(ProcXkbGetState);
+PROC_EXTERN(ProcXkbLatchLockState);
+PROC_EXTERN(ProcXkbGetControls);
+PROC_EXTERN(ProcXkbSetControls);
+PROC_EXTERN(ProcXkbGetMap);
+PROC_EXTERN(ProcXkbSetMap);
+PROC_EXTERN(ProcXkbGetCompatMap);
+PROC_EXTERN(ProcXkbSetCompatMap);
+PROC_EXTERN(ProcXkbGetIndicatorState);
+PROC_EXTERN(ProcXkbGetIndicatorMap);
+PROC_EXTERN(ProcXkbSetIndicatorMap);
+PROC_EXTERN(ProcXkbGetNamedIndicator);
+PROC_EXTERN(ProcXkbSetNamedIndicator);
+PROC_EXTERN(ProcXkbGetNames);
+PROC_EXTERN(ProcXkbSetNames);
+PROC_EXTERN(ProcXkbGetGeometry);
+PROC_EXTERN(ProcXkbSetGeometry);
+PROC_EXTERN(ProcXkbPerClientFlags);
+PROC_EXTERN(ProcXkbListComponents);
+PROC_EXTERN(ProcXkbGetKbdByName);
+PROC_EXTERN(ProcXkbGetDeviceInfo);
+PROC_EXTERN(ProcXkbSetDeviceInfo);
+PROC_EXTERN(ProcXkbSetDebuggingFlags);
+
+ /*
+ * REQUEST SWAPPING
+ */
+static int
+#if NeedFunctionPrototypes
+SProcXkbUseExtension(ClientPtr client)
+#else
+SProcXkbUseExtension(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbUseExtensionReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH(xkbUseExtensionReq);
+ swaps(&stuff->wantedMajor,n);
+ swaps(&stuff->wantedMinor,n);
+ return ProcXkbUseExtension(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbSelectEvents(ClientPtr client)
+#else
+SProcXkbSelectEvents(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbSelectEventsReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq);
+ swaps(&stuff->deviceSpec,n);
+ swaps(&stuff->affectWhich,n);
+ swaps(&stuff->clear,n);
+ swaps(&stuff->selectAll,n);
+ swaps(&stuff->affectMap,n);
+ swaps(&stuff->map,n);
+ if (stuff->affectWhich&(~XkbMapNotifyMask)!=0) {
+ union {
+ BOOL *b;
+ CARD8 *c8;
+ CARD16 *c16;
+ CARD32 *c32;
+ } from;
+ register unsigned bit,ndx,maskLeft,dataLeft,size;
+
+ from.c8= (CARD8 *)&stuff[1];
+ dataLeft= (stuff->length*4)-SIZEOF(xkbSelectEventsReq);
+ maskLeft= (stuff->affectWhich&(~XkbMapNotifyMask));
+ for (ndx=0,bit=1; (maskLeft!=0); ndx++, bit<<=1) {
+ if (((bit&maskLeft)==0)||(ndx==XkbMapNotify))
+ continue;
+ maskLeft&= ~bit;
+ if ((stuff->selectAll&bit)||(stuff->clear&bit))
+ continue;
+ switch (ndx) {
+ case XkbNewKeyboardNotify:
+ case XkbStateNotify:
+ case XkbNamesNotify:
+ case XkbAccessXNotify:
+ case XkbExtensionDeviceNotify:
+ size= 2;
+ break;
+ case XkbControlsNotify:
+ case XkbIndicatorStateNotify:
+ case XkbIndicatorMapNotify:
+ size= 4;
+ break;
+ case XkbBellNotify:
+ case XkbActionMessage:
+ case XkbCompatMapNotify:
+ size= 1;
+ break;
+ default:
+ client->errorValue = _XkbErrCode2(0x1,bit);
+ return BadValue;
+ }
+ if (dataLeft<(size*2))
+ return BadLength;
+ if (size==2) {
+ swaps(&from.c16[0],n);
+ swaps(&from.c16[1],n);
+ }
+ else if (size==4) {
+ swapl(&from.c32[0],n);
+ swapl(&from.c32[1],n);
+ }
+ else {
+ size= 2;
+ }
+ from.c8+= (size*2);
+ dataLeft-= (size*2);
+ }
+ if (dataLeft>2) {
+ ErrorF("Extra data (%d bytes) after SelectEvents\n",dataLeft);
+ return BadLength;
+ }
+ }
+ return ProcXkbSelectEvents(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbBell(ClientPtr client)
+#else
+SProcXkbBell(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbBellReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH(xkbBellReq);
+ swaps(&stuff->deviceSpec,n);
+ swaps(&stuff->bellClass,n);
+ swaps(&stuff->bellID,n);
+ swapl(&stuff->name,n);
+ swapl(&stuff->window,n);
+ swaps(&stuff->pitch,n);
+ swaps(&stuff->duration,n);
+ return ProcXkbBell(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbGetState(ClientPtr client)
+#else
+SProcXkbGetState(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbGetStateReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH(xkbGetStateReq);
+ swaps(&stuff->deviceSpec,n);
+ return ProcXkbGetState(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbLatchLockState(ClientPtr client)
+#else
+SProcXkbLatchLockState(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbLatchLockStateReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH(xkbLatchLockStateReq);
+ swaps(&stuff->deviceSpec,n);
+ swaps(&stuff->groupLatch,n);
+ return ProcXkbLatchLockState(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbGetControls(ClientPtr client)
+#else
+SProcXkbGetControls(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbGetControlsReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH(xkbGetControlsReq);
+ swaps(&stuff->deviceSpec,n);
+ return ProcXkbGetControls(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbSetControls(ClientPtr client)
+#else
+SProcXkbSetControls(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbSetControlsReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH(xkbSetControlsReq);
+ swaps(&stuff->deviceSpec,n);
+ swaps(&stuff->affectInternalVMods,n);
+ swaps(&stuff->internalVMods,n);
+ swaps(&stuff->affectIgnoreLockVMods,n);
+ swaps(&stuff->ignoreLockVMods,n);
+ swaps(&stuff->axOptions,n);
+ swapl(&stuff->affectEnabledCtrls,n);
+ swapl(&stuff->enabledCtrls,n);
+ swapl(&stuff->changeCtrls,n);
+ swaps(&stuff->repeatDelay,n);
+ swaps(&stuff->repeatInterval,n);
+ swaps(&stuff->slowKeysDelay,n);
+ swaps(&stuff->debounceDelay,n);
+ swaps(&stuff->mkDelay,n);
+ swaps(&stuff->mkInterval,n);
+ swaps(&stuff->mkTimeToMax,n);
+ swaps(&stuff->mkMaxSpeed,n);
+ swaps(&stuff->mkCurve,n);
+ swaps(&stuff->axTimeout,n);
+ swapl(&stuff->axtCtrlsMask,n);
+ swapl(&stuff->axtCtrlsValues,n);
+ swaps(&stuff->axtOptsMask,n);
+ swaps(&stuff->axtOptsValues,n);
+ return ProcXkbSetControls(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbGetMap(ClientPtr client)
+#else
+SProcXkbGetMap(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbGetMapReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH(xkbGetMapReq);
+ swaps(&stuff->deviceSpec,n);
+ swaps(&stuff->full,n);
+ swaps(&stuff->partial,n);
+ swaps(&stuff->virtualMods,n);
+ return ProcXkbGetMap(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbSetMap(ClientPtr client)
+#else
+SProcXkbSetMap(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbSetMapReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_AT_LEAST_SIZE(xkbSetMapReq);
+ swaps(&stuff->deviceSpec,n);
+ swaps(&stuff->present,n);
+ swaps(&stuff->flags,n);
+ swaps(&stuff->totalSyms,n);
+ swaps(&stuff->totalActs,n);
+ swaps(&stuff->virtualMods,n);
+ return ProcXkbSetMap(client);
+}
+
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbGetCompatMap(ClientPtr client)
+#else
+SProcXkbGetCompatMap(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbGetCompatMapReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH(xkbGetCompatMapReq);
+ swaps(&stuff->deviceSpec,n);
+ swaps(&stuff->firstSI,n);
+ swaps(&stuff->nSI,n);
+ return ProcXkbGetCompatMap(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbSetCompatMap(ClientPtr client)
+#else
+SProcXkbSetCompatMap(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbSetCompatMapReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq);
+ swaps(&stuff->deviceSpec,n);
+ swaps(&stuff->firstSI,n);
+ swaps(&stuff->nSI,n);
+ return ProcXkbSetCompatMap(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbGetIndicatorState(ClientPtr client)
+#else
+SProcXkbGetIndicatorState(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbGetIndicatorStateReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq);
+ swaps(&stuff->deviceSpec,n);
+ return ProcXkbGetIndicatorState(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbGetIndicatorMap(ClientPtr client)
+#else
+SProcXkbGetIndicatorMap(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbGetIndicatorMapReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq);
+ swaps(&stuff->deviceSpec,n);
+ swapl(&stuff->which,n);
+ return ProcXkbGetIndicatorMap(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbSetIndicatorMap(ClientPtr client)
+#else
+SProcXkbSetIndicatorMap(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbSetIndicatorMapReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq);
+ swaps(&stuff->deviceSpec,n);
+ swapl(&stuff->which,n);
+ return ProcXkbSetIndicatorMap(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbGetNamedIndicator(ClientPtr client)
+#else
+SProcXkbGetNamedIndicator(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbGetNamedIndicatorReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq);
+ swaps(&stuff->deviceSpec,n);
+ swaps(&stuff->ledClass,n);
+ swaps(&stuff->ledID,n);
+ swapl(&stuff->indicator,n);
+ return ProcXkbGetNamedIndicator(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbSetNamedIndicator(ClientPtr client)
+#else
+SProcXkbSetNamedIndicator(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbSetNamedIndicatorReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq);
+ swaps(&stuff->deviceSpec,n);
+ swaps(&stuff->ledClass,n);
+ swaps(&stuff->ledID,n);
+ swapl(&stuff->indicator,n);
+ swaps(&stuff->virtualMods,n);
+ swapl(&stuff->ctrls,n);
+ return ProcXkbSetNamedIndicator(client);
+}
+
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbGetNames(ClientPtr client)
+#else
+SProcXkbGetNames(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbGetNamesReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH(xkbGetNamesReq);
+ swaps(&stuff->deviceSpec,n);
+ swapl(&stuff->which,n);
+ return ProcXkbGetNames(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbSetNames(ClientPtr client)
+#else
+SProcXkbSetNames(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbSetNamesReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_AT_LEAST_SIZE(xkbSetNamesReq);
+ swaps(&stuff->deviceSpec,n);
+ swaps(&stuff->virtualMods,n);
+ swapl(&stuff->which,n);
+ swapl(&stuff->indicators,n);
+ swaps(&stuff->totalKTLevelNames,n);
+ return ProcXkbSetNames(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbGetGeometry(ClientPtr client)
+#else
+SProcXkbGetGeometry(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbGetGeometryReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH(xkbGetGeometryReq);
+ swaps(&stuff->deviceSpec,n);
+ swapl(&stuff->name,n);
+ return ProcXkbGetGeometry(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbSetGeometry(ClientPtr client)
+#else
+SProcXkbSetGeometry(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbSetGeometryReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq);
+ swaps(&stuff->deviceSpec,n);
+ swapl(&stuff->name,n);
+ swaps(&stuff->widthMM,n);
+ swaps(&stuff->heightMM,n);
+ swaps(&stuff->nProperties,n);
+ swaps(&stuff->nColors,n);
+ swaps(&stuff->nDoodads,n);
+ swaps(&stuff->nKeyAliases,n);
+ return ProcXkbSetGeometry(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbPerClientFlags(ClientPtr client)
+#else
+SProcXkbPerClientFlags(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbPerClientFlagsReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH(xkbPerClientFlagsReq);
+ swaps(&stuff->deviceSpec,n);
+ swapl(&stuff->change,n);
+ swapl(&stuff->value,n);
+ swapl(&stuff->ctrlsToChange,n);
+ swapl(&stuff->autoCtrls,n);
+ swapl(&stuff->autoCtrlValues,n);
+ return ProcXkbPerClientFlags(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbListComponents(ClientPtr client)
+#else
+SProcXkbListComponents(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbListComponentsReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_AT_LEAST_SIZE(xkbListComponentsReq);
+ swaps(&stuff->deviceSpec,n);
+ swaps(&stuff->maxNames,n);
+ return ProcXkbListComponents(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbGetKbdByName(ClientPtr client)
+#else
+SProcXkbGetKbdByName(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbGetKbdByNameReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq);
+ swaps(&stuff->deviceSpec,n);
+ swaps(&stuff->want,n);
+ swaps(&stuff->need,n);
+ return ProcXkbGetKbdByName(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbGetDeviceInfo(ClientPtr client)
+#else
+SProcXkbGetDeviceInfo(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbGetDeviceInfoReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq);
+ swaps(&stuff->deviceSpec,n);
+ swaps(&stuff->wanted,n);
+ swaps(&stuff->ledClass,n);
+ swaps(&stuff->ledID,n);
+ return ProcXkbGetDeviceInfo(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbSetDeviceInfo(ClientPtr client)
+#else
+SProcXkbSetDeviceInfo(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbSetDeviceInfoReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq);
+ swaps(&stuff->deviceSpec,n);
+ swaps(&stuff->change,n);
+ swaps(&stuff->nDeviceLedFBs,n);
+ return ProcXkbSetDeviceInfo(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcXkbSetDebuggingFlags(ClientPtr client)
+#else
+SProcXkbSetDebuggingFlags(client)
+ ClientPtr client;
+#endif
+{
+register int n;
+
+ REQUEST(xkbSetDebuggingFlagsReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq);
+ swapl(&stuff->affectFlags,n);
+ swapl(&stuff->flags,n);
+ swapl(&stuff->affectCtrls,n);
+ swapl(&stuff->ctrls,n);
+ swaps(&stuff->msgLength,n);
+ return ProcXkbSetDebuggingFlags(client);
+}
+
+int
+#if NeedFunctionPrototypes
+SProcXkbDispatch (ClientPtr client)
+#else
+SProcXkbDispatch (client)
+ ClientPtr client;
+#endif
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_kbUseExtension:
+ return SProcXkbUseExtension(client);
+ case X_kbSelectEvents:
+ return SProcXkbSelectEvents(client);
+ case X_kbBell:
+ return SProcXkbBell(client);
+ case X_kbGetState:
+ return SProcXkbGetState(client);
+ case X_kbLatchLockState:
+ return SProcXkbLatchLockState(client);
+ case X_kbGetControls:
+ return SProcXkbGetControls(client);
+ case X_kbSetControls:
+ return SProcXkbSetControls(client);
+ case X_kbGetMap:
+ return SProcXkbGetMap(client);
+ case X_kbSetMap:
+ return SProcXkbSetMap(client);
+ case X_kbGetCompatMap:
+ return SProcXkbGetCompatMap(client);
+ case X_kbSetCompatMap:
+ return SProcXkbSetCompatMap(client);
+ case X_kbGetIndicatorState:
+ return SProcXkbGetIndicatorState(client);
+ case X_kbGetIndicatorMap:
+ return SProcXkbGetIndicatorMap(client);
+ case X_kbSetIndicatorMap:
+ return SProcXkbSetIndicatorMap(client);
+ case X_kbGetNamedIndicator:
+ return SProcXkbGetNamedIndicator(client);
+ case X_kbSetNamedIndicator:
+ return SProcXkbSetNamedIndicator(client);
+ case X_kbGetNames:
+ return SProcXkbGetNames(client);
+ case X_kbSetNames:
+ return SProcXkbSetNames(client);
+ case X_kbGetGeometry:
+ return SProcXkbGetGeometry(client);
+ case X_kbSetGeometry:
+ return SProcXkbSetGeometry(client);
+ case X_kbPerClientFlags:
+ return SProcXkbPerClientFlags(client);
+ case X_kbListComponents:
+ return SProcXkbListComponents(client);
+ case X_kbGetKbdByName:
+ return SProcXkbGetKbdByName(client);
+ case X_kbGetDeviceInfo:
+ return SProcXkbGetDeviceInfo(client);
+ case X_kbSetDeviceInfo:
+ return SProcXkbSetDeviceInfo(client);
+ case X_kbSetDebuggingFlags:
+ return SProcXkbSetDebuggingFlags(client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/xc/programs/Xserver/xkb/xkbUtils.c b/xc/programs/Xserver/xkb/xkbUtils.c
new file mode 100644
index 000000000..1f86b4b4e
--- /dev/null
+++ b/xc/programs/Xserver/xkb/xkbUtils.c
@@ -0,0 +1,1140 @@
+/* $XConsortium: xkbUtils.c /main/24 1996/09/28 17:16:26 rws $ */
+/* $XFree86: xc/programs/Xserver/xkb/xkbUtils.c,v 3.10 1997/07/10 08:17:47 hohndel Exp $ */
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+#define NEED_EVENTS 1
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#define XK_CYRILLIC
+#include <X11/keysym.h>
+#include "misc.h"
+#include "inputstr.h"
+
+#define XKBSRV_NEED_FILE_FUNCS
+#include "XKBsrv.h"
+#include "extensions/XKBgeom.h"
+
+#ifdef MODE_SWITCH
+extern Bool noKME; /* defined in os/utils.c */
+#endif
+
+ int XkbDisableLockActions = 0;
+
+/***====================================================================***/
+
+#ifndef RETURN_SHOULD_REPEAT
+#if (defined(__osf__) && defined(__alpha))
+#define RETURN_SHOULD_REPEAT 1
+#else
+#define RETURN_SHOULD_REPEAT 0
+#endif
+#endif
+
+/***====================================================================***/
+
+DeviceIntPtr
+#if NeedFunctionPrototypes
+_XkbLookupAnyDevice(int id,int *why_rtrn)
+#else
+_XkbLookupAnyDevice(id,why_rtrn)
+ int id;
+ int *why_rtrn;
+#endif
+{
+DeviceIntPtr dev = NULL;
+
+ dev= (DeviceIntPtr)LookupKeyboardDevice();
+ if ((id==XkbUseCoreKbd)||(dev->id==id))
+ return dev;
+
+ dev= (DeviceIntPtr)LookupPointerDevice();
+ if ((id==XkbUseCorePtr)||(dev->id==id))
+ return dev;
+
+ if (id&(~0xff))
+ dev = NULL;
+
+ dev= (DeviceIntPtr)LookupDevice(id);
+ if (dev!=NULL)
+ return dev;
+ if ((!dev)&&(why_rtrn))
+ *why_rtrn= XkbErr_BadDevice;
+ return dev;
+}
+
+DeviceIntPtr
+#if NeedFunctionPrototypes
+_XkbLookupKeyboard(int id,int *why_rtrn)
+#else
+_XkbLookupKeyboard(id,why_rtrn)
+ int id;
+ int *why_rtrn;
+#endif
+{
+DeviceIntPtr dev = NULL;
+
+ if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL)
+ return NULL;
+ else if ((!dev->key)||(!dev->key->xkbInfo)) {
+ if (why_rtrn)
+ *why_rtrn= XkbErr_BadClass;
+ return NULL;
+ }
+ return dev;
+}
+
+DeviceIntPtr
+#if NeedFunctionPrototypes
+_XkbLookupBellDevice(int id,int *why_rtrn)
+#else
+_XkbLookupBellDevice(id,why_rtrn)
+ int id;
+ int *why_rtrn;
+#endif
+{
+DeviceIntPtr dev = NULL;
+
+ if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL)
+ return NULL;
+ else if ((!dev->kbdfeed)&&(!dev->bell)) {
+ if (why_rtrn)
+ *why_rtrn= XkbErr_BadClass;
+ return NULL;
+ }
+ return dev;
+}
+
+DeviceIntPtr
+#if NeedFunctionPrototypes
+_XkbLookupLedDevice(int id,int *why_rtrn)
+#else
+_XkbLookupLedDevice(id,why_rtrn)
+ int id;
+ int *why_rtrn;
+#endif
+{
+DeviceIntPtr dev = NULL;
+
+ if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL)
+ return NULL;
+ else if ((!dev->kbdfeed)&&(!dev->leds)) {
+ if (why_rtrn)
+ *why_rtrn= XkbErr_BadClass;
+ return NULL;
+ }
+ return dev;
+}
+
+DeviceIntPtr
+#if NeedFunctionPrototypes
+_XkbLookupButtonDevice(int id,int *why_rtrn)
+#else
+_XkbLookupButtonDevice(id,why_rtrn)
+ int id;
+ int *why_rtrn;
+#endif
+{
+DeviceIntPtr dev = NULL;
+
+ if ((dev= _XkbLookupAnyDevice(id,why_rtrn))==NULL)
+ return NULL;
+ else if (!dev->button) {
+ if (why_rtrn)
+ *why_rtrn= XkbErr_BadClass;
+ return NULL;
+ }
+ return dev;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbSetActionKeyMods(XkbDescPtr xkb,XkbAction *act,unsigned mods)
+#else
+XkbSetActionKeyMods(xkb,act,mods)
+ XkbDescPtr xkb;
+ XkbAction * act;
+ unsigned mods;
+#endif
+{
+register unsigned tmp;
+
+ switch (act->type) {
+ case XkbSA_SetMods: case XkbSA_LatchMods: case XkbSA_LockMods:
+ if (act->mods.flags&XkbSA_UseModMapMods)
+ act->mods.real_mods= act->mods.mask= mods;
+ if ((tmp= XkbModActionVMods(&act->mods))!=0)
+ act->mods.mask|= XkbMaskForVMask(xkb,tmp);
+ break;
+ case XkbSA_ISOLock:
+ if (act->iso.flags&XkbSA_UseModMapMods)
+ act->iso.real_mods= act->iso.mask= mods;
+ if ((tmp= XkbModActionVMods(&act->iso))!=0)
+ act->iso.mask|= XkbMaskForVMask(xkb,tmp);
+ break;
+ }
+ return;
+}
+
+unsigned
+#if NeedFunctionPrototypes
+XkbMaskForVMask(XkbDescPtr xkb,unsigned vmask)
+#else
+XkbMaskForVMask(xkb,vmask)
+ XkbDescPtr xkb;
+ unsigned vmask;
+#endif
+{
+register int i,bit;
+register unsigned mask;
+
+ for (mask=i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (vmask&bit)
+ mask|= xkb->server->vmods[i];
+ }
+ return mask;
+}
+
+
+Bool
+#if NeedFunctionPrototypes
+XkbApplyVModChanges( XkbSrvInfoPtr xkbi,
+ unsigned changed,
+ XkbChangesPtr changes,
+ unsigned * needChecksRtrn,
+ XkbEventCausePtr cause)
+#else
+XkbApplyVModChanges(xkbi,changed,changes,needChecksRtrn,cause)
+ XkbSrvInfoPtr xkbi;
+ unsigned changed;
+ XkbChangesPtr changes;
+ unsigned * needChecksRtrn;
+ XkbEventCausePtr cause;
+#endif
+{
+XkbDescPtr xkb;
+Bool check;
+
+ xkb= xkbi->desc;
+#ifdef DEBUG
+{
+register unsigned i,bit;
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if ((changed&bit)==0)
+ continue;
+ if (xkbDebugFlags)
+ ErrorF("Should be applying: change vmod %d to 0x%x\n",i,
+ xkb->server->vmods[i]);
+ }
+}
+#endif
+ check= XkbApplyVirtualModChanges(xkb,changed,changes);
+ XkbApplyVModChangesToAllDevices(xkbi->device,xkb,changed,cause);
+
+ if (needChecksRtrn!=NULL) {
+ if (check)
+ *needChecksRtrn= XkbStateNotifyMask|XkbIndicatorStateNotifyMask;
+ else *needChecksRtrn= 0;
+ }
+ else if (check) {
+ /* 7/12/95 (ef) -- XXX check compatibility and/or indicator state */
+ }
+ return 1;
+}
+
+/***====================================================================***/
+
+#if NeedFunctionPrototypes
+void
+XkbUpdateKeyTypesFromCore( DeviceIntPtr pXDev,
+ KeyCode first,
+ CARD8 num,
+ XkbChangesPtr changes)
+#else
+void
+XkbUpdateKeyTypesFromCore(pXDev,first,num,changes)
+ DeviceIntPtr pXDev;
+ KeyCode first;
+ CARD8 num;
+ XkbChangesPtr changes;
+#endif
+{
+XkbDescPtr xkb;
+unsigned key,nG,explicit;
+KeySymsPtr pCore;
+int types[XkbNumKbdGroups];
+KeySym tsyms[XkbMaxSymsPerKey],*syms;
+XkbMapChangesPtr mc;
+
+ xkb= pXDev->key->xkbInfo->desc;
+#ifdef NOTYET
+ if (first<xkb->min_key_code) {
+ if (first>=XkbMinLegalKeyCode) {
+ xkb->min_key_code= first;
+ /* 1/12/95 (ef) -- XXX! should zero out the new maps */
+ changes->map.changed|= XkbKeycodesMask;
+generate a NewKeyboard notify here?
+ }
+ }
+#endif
+ if (first+num-1>xkb->max_key_code) {
+ /* 1/12/95 (ef) -- XXX! should allow XKB structures to grow */
+ num= xkb->max_key_code-first+1;
+ }
+
+ mc= (changes?(&changes->map):NULL);
+
+ pCore= &pXDev->key->curKeySyms;
+ syms= &pCore->map[(first-xkb->min_key_code)*pCore->mapWidth];
+ for (key=first; key<(first+num); key++,syms+= pCore->mapWidth) {
+ explicit= xkb->server->explicit[key]&XkbExplicitKeyTypesMask;
+ types[XkbGroup1Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup1Index);
+ types[XkbGroup2Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup2Index);
+ types[XkbGroup3Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup3Index);
+ types[XkbGroup4Index]= XkbKeyKeyTypeIndex(xkb,key,XkbGroup4Index);
+ nG= XkbKeyTypesForCoreSymbols(xkb,pCore->mapWidth,syms,explicit,types,
+ tsyms);
+ XkbChangeTypesOfKey(xkb,key,nG,XkbAllGroupsMask,types,mc);
+ memcpy((char *)XkbKeySymsPtr(xkb,key),(char *)tsyms,
+ XkbKeyNumSyms(xkb,key)*sizeof(KeySym));
+ }
+ if (changes->map.changed&XkbKeySymsMask) {
+ CARD8 oldLast,newLast;
+ oldLast = changes->map.first_key_sym+changes->map.num_key_syms-1;
+ newLast = first+num-1;
+
+ if (first<changes->map.first_key_sym)
+ changes->map.first_key_sym = first;
+ if (oldLast>newLast)
+ newLast= oldLast;
+ changes->map.num_key_syms = newLast-changes->map.first_key_sym+1;
+ }
+ else {
+ changes->map.changed|= XkbKeySymsMask;
+ changes->map.first_key_sym = first;
+ changes->map.num_key_syms = num;
+ }
+ return;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbUpdateDescActions( XkbDescPtr xkb,
+ KeyCode first,
+ CARD8 num,
+ XkbChangesPtr changes)
+#else
+XkbUpdateDescActions(xkb,first,num,changes)
+ XkbDescPtr xkb;
+ KeyCode first;
+ CARD8 num;
+ XkbChangesPtr changes;
+#endif
+{
+register unsigned key;
+
+ for (key=first;key<(first+num);key++) {
+ XkbApplyCompatMapToKey(xkb,key,changes);
+ }
+
+ if (changes->map.changed&XkbVirtualModMapMask|XkbModifierMapMask) {
+ unsigned char newVMods[XkbNumVirtualMods];
+ register unsigned bit,i;
+ unsigned present;
+
+ bzero(newVMods,XkbNumVirtualMods);
+ present= 0;
+ for (key=xkb->min_key_code;key<=xkb->max_key_code;key++) {
+ if (xkb->server->vmodmap[key]==0)
+ continue;
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (bit&xkb->server->vmodmap[key]) {
+ present|= bit;
+ newVMods[i]|= xkb->map->modmap[key];
+ }
+ }
+ }
+ for (i=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if ((bit&present)&&(newVMods[i]!=xkb->server->vmods[i])) {
+ changes->map.changed|= XkbVirtualModsMask;
+ changes->map.vmods|= bit;
+ xkb->server->vmods[i]= newVMods[i];
+ }
+ }
+ }
+ if (changes->map.changed&XkbVirtualModsMask)
+ XkbApplyVirtualModChanges(xkb,changes->map.vmods,changes);
+
+ if (changes->map.changed&XkbKeyActionsMask) {
+ CARD8 oldLast,newLast;
+ oldLast= changes->map.first_key_act+changes->map.num_key_acts-1;
+ newLast = first+num-1;
+
+ if (first<changes->map.first_key_act)
+ changes->map.first_key_act = first;
+ if (newLast>oldLast)
+ newLast= oldLast;
+ changes->map.num_key_acts= newLast-changes->map.first_key_act+1;
+ }
+ else {
+ changes->map.changed|= XkbKeyActionsMask;
+ changes->map.first_key_act = first;
+ changes->map.num_key_acts = num;
+ }
+ return;
+}
+
+#if NeedFunctionPrototypes
+void
+XkbUpdateActions( DeviceIntPtr pXDev,
+ KeyCode first,
+ CARD8 num,
+ XkbChangesPtr changes,
+ unsigned * needChecksRtrn,
+ XkbEventCausePtr cause)
+#else
+void
+XkbUpdateActions(pXDev,first,num,changes,needChecksRtrn,cause)
+ DeviceIntPtr pXDev;
+ KeyCode first;
+ CARD8 num;
+ XkbChangesPtr changes;
+ unsigned * needChecksRtrn;
+ XkbEventCausePtr cause;
+#endif
+{
+XkbSrvInfoPtr xkbi;
+XkbDescPtr xkb;
+CARD8 * repeat;
+
+ if (needChecksRtrn)
+ *needChecksRtrn= 0;
+ xkbi= pXDev->key->xkbInfo;
+ xkb= xkbi->desc;
+ repeat= xkb->ctrls->per_key_repeat;
+
+ if (pXDev->kbdfeed)
+ memcpy(repeat,pXDev->kbdfeed->ctrl.autoRepeats,32);
+
+ XkbUpdateDescActions(xkb,first,num,changes);
+
+ if ((pXDev->kbdfeed)&&
+ (changes->ctrls.enabled_ctrls_changes&XkbPerKeyRepeatMask)) {
+ memcpy(pXDev->kbdfeed->ctrl.autoRepeats,repeat, 32);
+ (*pXDev->kbdfeed->CtrlProc)(pXDev, &pXDev->kbdfeed->ctrl);
+ }
+ return;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbUpdateCoreDescription(DeviceIntPtr keybd,Bool resize)
+#else
+XkbUpdateCoreDescription(keybd,resize)
+ DeviceIntPtr keybd;
+ Bool resize;
+#endif
+{
+register int key,tmp;
+int maxSymsPerKey,maxKeysPerMod;
+int first,last,firstCommon,lastCommon;
+XkbDescPtr xkb;
+KeyClassPtr keyc;
+CARD8 keysPerMod[XkbNumModifiers];
+
+ if (!keybd || !keybd->key || !keybd->key->xkbInfo)
+ return;
+ xkb= keybd->key->xkbInfo->desc;
+ keyc= keybd->key;
+ maxSymsPerKey= maxKeysPerMod= 0;
+ bzero(keysPerMod,sizeof(keysPerMod));
+ memcpy(keyc->modifierMap,xkb->map->modmap,xkb->max_key_code+1);
+ if ((xkb->min_key_code==keyc->curKeySyms.minKeyCode)&&
+ (xkb->max_key_code==keyc->curKeySyms.maxKeyCode)) {
+ first= firstCommon= xkb->min_key_code;
+ last= lastCommon= xkb->max_key_code;
+ }
+ else if (resize) {
+ keyc->curKeySyms.minKeyCode= xkb->min_key_code;
+ keyc->curKeySyms.maxKeyCode= xkb->max_key_code;
+ tmp= keyc->curKeySyms.mapWidth*_XkbCoreNumKeys(keyc);
+ keyc->curKeySyms.map= _XkbTypedRealloc(keyc->curKeySyms.map,tmp,KeySym);
+ if (!keyc->curKeySyms.map)
+ FatalError("Couldn't allocate keysyms\n");
+ first= firstCommon= xkb->min_key_code;
+ last= lastCommon= xkb->max_key_code;
+ }
+ else {
+ if (xkb->min_key_code<keyc->curKeySyms.minKeyCode) {
+ first= xkb->min_key_code;
+ firstCommon= keyc->curKeySyms.minKeyCode;
+ }
+ else {
+ firstCommon= xkb->min_key_code;
+ first= keyc->curKeySyms.minKeyCode;
+ }
+ if (xkb->max_key_code>keyc->curKeySyms.maxKeyCode) {
+ lastCommon= keyc->curKeySyms.maxKeyCode;
+ last= xkb->max_key_code;
+ }
+ else {
+ lastCommon= xkb->max_key_code;
+ last= keyc->curKeySyms.maxKeyCode;
+ }
+ }
+
+ /* determine sizes */
+ for (key=first;key<=last;key++) {
+ if (XkbKeycodeInRange(xkb,key)) {
+ int nGroups;
+ int w;
+ nGroups= XkbKeyNumGroups(xkb,key);
+ tmp= 0;
+ if (nGroups>0) {
+ if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup1Index))<2)
+ tmp+= 2;
+ else tmp+= w;
+ }
+ if (nGroups>1) {
+ if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup2Index))<2)
+ tmp+= 2;
+ else tmp+= w;
+ }
+ if (nGroups>2)
+ tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup3Index);
+ if (nGroups>3)
+ tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup4Index);
+ if (tmp>maxSymsPerKey)
+ maxSymsPerKey= tmp;
+ }
+ if (_XkbCoreKeycodeInRange(keyc,key)) {
+ if (keyc->modifierMap[key]!=0) {
+ register unsigned bit,i,mask;
+ mask= keyc->modifierMap[key];
+ for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) {
+ if (mask&bit) {
+ keysPerMod[i]++;
+ if (keysPerMod[i]>maxKeysPerMod)
+ maxKeysPerMod= keysPerMod[i];
+ }
+ }
+ }
+ }
+ }
+
+ if (maxKeysPerMod>0) {
+ tmp= maxKeysPerMod*XkbNumModifiers;
+ if (keyc->modifierKeyMap==NULL)
+ keyc->modifierKeyMap= (KeyCode *)_XkbCalloc(1, tmp);
+ else if (keyc->maxKeysPerModifier<maxKeysPerMod)
+ keyc->modifierKeyMap= (KeyCode *)_XkbRealloc(keyc->modifierKeyMap,tmp);
+ if (keyc->modifierKeyMap==NULL)
+ FatalError("Couldn't allocate modifierKeyMap in UpdateCore\n");
+ bzero(keyc->modifierKeyMap,tmp);
+ }
+ else if ((keyc->maxKeysPerModifier>0)&&(keyc->modifierKeyMap!=NULL)) {
+ _XkbFree(keyc->modifierKeyMap);
+ keyc->modifierKeyMap= NULL;
+ }
+ keyc->maxKeysPerModifier= maxKeysPerMod;
+
+ if (maxSymsPerKey>0) {
+ tmp= maxSymsPerKey*_XkbCoreNumKeys(keyc);
+ keyc->curKeySyms.map= _XkbTypedRealloc(keyc->curKeySyms.map,tmp,KeySym);
+ if (keyc->curKeySyms.map==NULL)
+ FatalError("Couldn't allocate symbols map in UpdateCore\n");
+ }
+ else if ((keyc->curKeySyms.mapWidth>0)&&(keyc->curKeySyms.map!=NULL)) {
+ _XkbFree(keyc->curKeySyms.map);
+ keyc->curKeySyms.map= NULL;
+ }
+ keyc->curKeySyms.mapWidth= maxSymsPerKey;
+
+ bzero(keysPerMod,sizeof(keysPerMod));
+ for (key=firstCommon;key<=lastCommon;key++) {
+ if (keyc->curKeySyms.map!=NULL) {
+ KeySym *pCore,*pXKB;
+ unsigned nGroups,groupWidth,n,nOut;
+
+ nGroups= XkbKeyNumGroups(xkb,key);
+ n= (key-keyc->curKeySyms.minKeyCode)*maxSymsPerKey;
+ pCore= &keyc->curKeySyms.map[n];
+ bzero(pCore,maxSymsPerKey*sizeof(KeySym));
+ pXKB= XkbKeySymsPtr(xkb,key);
+ nOut= 2;
+ if (nGroups>0) {
+ groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup1Index);
+ if (groupWidth>0) pCore[0]= pXKB[0];
+ if (groupWidth>1) pCore[1]= pXKB[1];
+ for (n=2;n<groupWidth;n++) {
+ pCore[2+n]= pXKB[n];
+ }
+ if (groupWidth>2)
+ nOut= groupWidth;
+ }
+ pXKB+= XkbKeyGroupsWidth(xkb,key);
+ nOut+= 2;
+ if (nGroups>1) {
+ groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup2Index);
+ if (groupWidth>0) pCore[2]= pXKB[0];
+ if (groupWidth>1) pCore[3]= pXKB[1];
+ for (n=2;n<groupWidth;n++) {
+ pCore[nOut+(n-2)]= pXKB[n];
+ }
+ if (groupWidth>2)
+ nOut+= (groupWidth-2);
+ }
+ pXKB+= XkbKeyGroupsWidth(xkb,key);
+ for (n=XkbGroup3Index;n<nGroups;n++) {
+ register int s;
+ groupWidth= XkbKeyGroupWidth(xkb,key,XkbGroup2Index);
+ for (s=0;s<groupWidth;s++) {
+ pCore[nOut++]= pXKB[s];
+ }
+ pXKB+= XkbKeyGroupsWidth(xkb,key);
+ }
+ }
+ if (keyc->modifierMap[key]!=0) {
+ register unsigned bit,i,mask;
+ mask= keyc->modifierMap[key];
+ for (i=0,bit=1;i<XkbNumModifiers;i++,bit<<=1) {
+ if (mask&bit) {
+ tmp= i*maxKeysPerMod+keysPerMod[i];
+ keyc->modifierKeyMap[tmp]= key;
+ keysPerMod[i]++;
+ }
+ }
+ }
+ }
+#ifdef MODE_SWITCH
+ /* Fix up any of the KME stuff if we changed the core description.
+ */
+ if (!noKME)
+ HandleKeyBinding(keyc, &keyc->curKeySyms);
+#endif
+ return;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbSetRepeatKeys(DeviceIntPtr pXDev,int key,int onoff)
+#else
+XkbSetRepeatKeys(pXDev,key,onoff)
+ DeviceIntPtr pXDev;
+ int key;
+ int onoff;
+#endif
+{
+ if (pXDev && pXDev->key && pXDev->key->xkbInfo) {
+ xkbControlsNotify cn;
+ XkbControlsPtr ctrls = pXDev->key->xkbInfo->desc->ctrls;
+ XkbControlsRec old;
+ old = *ctrls;
+
+ if (key== -1) { /* global autorepeat setting changed */
+ if (onoff) ctrls->enabled_ctrls |= XkbRepeatKeysMask;
+ else ctrls->enabled_ctrls &= ~XkbRepeatKeysMask;
+ }
+ else if (pXDev->kbdfeed) {
+ ctrls->per_key_repeat[key/8] =
+ pXDev->kbdfeed->ctrl.autoRepeats[key/8];
+ }
+
+ if (XkbComputeControlsNotify(pXDev,&old,ctrls,&cn,True))
+ XkbSendControlsNotify(pXDev,&cn);
+ }
+ return;
+}
+
+#if NeedFunctionPrototypes
+void
+XkbApplyMappingChange( DeviceIntPtr kbd,
+ CARD8 request,
+ KeyCode firstKey,
+ CARD8 num,
+ ClientPtr client)
+#else
+void
+XkbApplyMappingChange(kbd,request,firstKey,num,client)
+ DeviceIntPtr kbd;
+ CARD8 request;
+ KeyCode firstKey;
+ CARD8 num;
+ ClientPtr client;
+#endif
+{
+XkbEventCauseRec cause;
+XkbChangesRec changes;
+unsigned check;
+
+ if (kbd->key->xkbInfo==NULL)
+ XkbInitDevice(kbd);
+ bzero(&changes,sizeof(XkbChangesRec));
+ check= 0;
+ if (request==MappingKeyboard) {
+ XkbSetCauseCoreReq(&cause,X_ChangeKeyboardMapping,client);
+ XkbUpdateKeyTypesFromCore(kbd,firstKey,num,&changes);
+ XkbUpdateActions(kbd,firstKey,num,&changes,&check,&cause);
+ if (check)
+ XkbCheckSecondaryEffects(kbd->key->xkbInfo,check,&changes,&cause);
+ }
+ else if (request==MappingModifier) {
+ XkbDescPtr xkb= kbd->key->xkbInfo->desc;
+
+ XkbSetCauseCoreReq(&cause,X_SetModifierMapping,client);
+
+ num = xkb->max_key_code-xkb->min_key_code+1;
+ memcpy(xkb->map->modmap,kbd->key->modifierMap,xkb->max_key_code+1);
+
+ changes.map.changed|= XkbModifierMapMask;
+ changes.map.first_modmap_key= xkb->min_key_code;
+ changes.map.num_modmap_keys= num;
+ XkbUpdateActions(kbd,xkb->min_key_code,num,&changes,&check,&cause);
+ if (check)
+ XkbCheckSecondaryEffects(kbd->key->xkbInfo,check,&changes,&cause);
+ }
+ /* 3/26/94 (ef) -- XXX! Doesn't deal with input extension requests */
+ XkbSendNotification(kbd,&changes,&cause);
+ return;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbDisableComputedAutoRepeats(DeviceIntPtr dev,unsigned key)
+#else
+XkbDisableComputedAutoRepeats(dev,key)
+ DeviceIntPtr dev;
+ unsigned key;
+#endif
+{
+XkbSrvInfoPtr xkbi = dev->key->xkbInfo;
+xkbMapNotify mn;
+
+ xkbi->desc->server->explicit[key]|= XkbExplicitAutoRepeatMask;
+ bzero(&mn,sizeof(mn));
+ mn.changed= XkbExplicitComponentsMask;
+ mn.firstKeyExplicit= key;
+ mn.nKeyExplicit= 1;
+ XkbSendMapNotify(dev,&mn);
+ return;
+}
+
+unsigned
+#if NeedFunctionPrototypes
+XkbStateChangedFlags(XkbStatePtr old,XkbStatePtr new)
+#else
+XkbStateChangedFlags(old,new)
+ XkbStatePtr old;
+ XkbStatePtr new;
+#endif
+{
+int changed;
+
+ changed=(old->group!=new->group?XkbGroupStateMask:0);
+ changed|=(old->base_group!=new->base_group?XkbGroupBaseMask:0);
+ changed|=(old->latched_group!=new->latched_group?XkbGroupLatchMask:0);
+ changed|=(old->locked_group!=new->locked_group?XkbGroupLockMask:0);
+ changed|=(old->mods!=new->mods?XkbModifierStateMask:0);
+ changed|=(old->base_mods!=new->base_mods?XkbModifierBaseMask:0);
+ changed|=(old->latched_mods!=new->latched_mods?XkbModifierLatchMask:0);
+ changed|=(old->locked_mods!=new->locked_mods?XkbModifierLockMask:0);
+ changed|=(old->compat_state!=new->compat_state?XkbCompatStateMask:0);
+ changed|=(old->grab_mods!=new->grab_mods?XkbGrabModsMask:0);
+ if (old->compat_grab_mods!=new->compat_grab_mods)
+ changed|= XkbCompatGrabModsMask;
+ changed|=(old->lookup_mods!=new->lookup_mods?XkbLookupModsMask:0);
+ if (old->compat_lookup_mods!=new->compat_lookup_mods)
+ changed|= XkbCompatLookupModsMask;
+ changed|=(old->ptr_buttons!=new->ptr_buttons?XkbPointerButtonMask:0);
+ return changed;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbComputeCompatState(XkbSrvInfoPtr xkbi)
+#else
+XkbComputeCompatState(xkbi)
+ XkbSrvInfoPtr xkbi;
+#endif
+{
+CARD16 grp_mask;
+XkbStatePtr state= &xkbi->state;
+XkbCompatMapPtr map;
+
+ map= xkbi->desc->compat;
+ grp_mask= map->groups[state->group].mask;
+ state->compat_state = state->mods|grp_mask;
+ state->compat_lookup_mods= state->lookup_mods|grp_mask;
+
+ if (xkbi->desc->ctrls->enabled_ctrls&XkbIgnoreGroupLockMask)
+ grp_mask= map->groups[state->base_group].mask;
+ state->compat_grab_mods= state->grab_mods|grp_mask;
+ return;
+}
+
+unsigned
+#if NeedFunctionPrototypes
+XkbAdjustGroup(int group,XkbControlsPtr ctrls)
+#else
+XkbAdjustGroup(group,ctrls)
+ int group;
+ XkbControlsPtr ctrls;
+#endif
+{
+unsigned act;
+
+ act= XkbOutOfRangeGroupAction(ctrls->groups_wrap);
+ if (group<0) {
+ while ( group < 0 ) {
+ if (act==XkbClampIntoRange) {
+ group= XkbGroup1Index;
+ }
+ else if (act==XkbRedirectIntoRange) {
+ int newGroup;
+ newGroup= XkbOutOfRangeGroupNumber(ctrls->groups_wrap);
+ if (newGroup>=ctrls->num_groups)
+ group= XkbGroup1Index;
+ else group= newGroup;
+ }
+ else {
+ group+= ctrls->num_groups;
+ }
+ }
+ }
+ else if (group>=ctrls->num_groups) {
+ if (act==XkbClampIntoRange) {
+ group= ctrls->num_groups-1;
+ }
+ else if (act==XkbRedirectIntoRange) {
+ int newGroup;
+ newGroup= XkbOutOfRangeGroupNumber(ctrls->groups_wrap);
+ if (newGroup>=ctrls->num_groups)
+ group= XkbGroup1Index;
+ else group= newGroup;
+ }
+ else {
+ group%= ctrls->num_groups;
+ }
+ }
+ return group;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbComputeDerivedState(XkbSrvInfoPtr xkbi)
+#else
+XkbComputeDerivedState(xkbi)
+ XkbSrvInfoPtr xkbi;
+#endif
+{
+XkbStatePtr state= &xkbi->state;
+XkbControlsPtr ctrls= xkbi->desc->ctrls;
+unsigned grp;
+
+ state->mods= (state->base_mods|state->latched_mods);
+ state->mods|= state->locked_mods;
+ state->lookup_mods= state->mods&(~ctrls->internal.mask);
+ state->grab_mods= state->lookup_mods&(~ctrls->ignore_lock.mask);
+ state->grab_mods|=
+ (state->base_mods|state->latched_mods&ctrls->ignore_lock.mask);
+
+
+ grp= state->locked_group;
+ if (grp>=ctrls->num_groups)
+ state->locked_group= XkbAdjustGroup(grp,ctrls);
+
+ grp= state->locked_group+state->base_group+state->latched_group;
+ if (grp>=ctrls->num_groups)
+ state->group= XkbAdjustGroup(grp,ctrls);
+ else state->group= grp;
+ XkbComputeCompatState(xkbi);
+ return;
+}
+
+/***====================================================================***/
+
+void
+#if NeedFunctionPrototypes
+XkbCheckSecondaryEffects( XkbSrvInfoPtr xkbi,
+ unsigned which,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+#else
+XkbCheckSecondaryEffects(xkbi,which,changes,cause)
+ XkbSrvInfoPtr xkbi;
+ unsigned which;
+ XkbChangesPtr changes;
+ XkbEventCausePtr cause;
+#endif
+{
+ if (which&XkbStateNotifyMask) {
+ XkbStateRec old;
+ old= xkbi->state;
+ changes->state_changes|= XkbStateChangedFlags(&old,&xkbi->state);
+ XkbComputeDerivedState(xkbi);
+ }
+ if (which&XkbIndicatorStateNotifyMask)
+ XkbUpdateIndicators(xkbi->device,XkbAllIndicatorsMask,True,changes,
+ cause);
+ return;
+}
+
+/***====================================================================***/
+
+void
+#if NeedFunctionPrototypes
+XkbSetPhysicalLockingKey(DeviceIntPtr dev,unsigned key)
+#else
+XkbSetPhysicalLockingKey(dev,key)
+ DeviceIntPtr dev;
+ unsigned key;
+#endif
+{
+XkbDescPtr xkb;
+
+ xkb= dev->key->xkbInfo->desc;
+ if ((key>=xkb->min_key_code) && (key<=xkb->max_key_code)) {
+ xkb->server->behaviors[key].type= XkbKB_Lock|XkbKB_Permanent;
+ }
+ else ErrorF("Internal Error! Bad XKB info in SetPhysicalLockingKey\n");
+ return;
+}
+
+/***====================================================================***/
+
+Bool
+#if NeedFunctionPrototypes
+XkbEnableDisableControls( XkbSrvInfoPtr xkbi,
+ unsigned long change,
+ unsigned long newValues,
+ XkbChangesPtr changes,
+ XkbEventCausePtr cause)
+#else
+XkbEnableDisableControls(xkbi,change,newValues,changes,cause)
+ XkbSrvInfoPtr xkbi;
+ unsigned long change;
+ unsigned long newValues;
+ XkbChangesPtr changes;
+ XkbEventCausePtr cause;
+#endif
+{
+XkbControlsPtr ctrls;
+unsigned old;
+XkbSrvLedInfoPtr sli;
+
+ ctrls= xkbi->desc->ctrls;
+ old= ctrls->enabled_ctrls;
+ ctrls->enabled_ctrls&= ~change;
+ ctrls->enabled_ctrls|= (change&newValues);
+ if (old==ctrls->enabled_ctrls)
+ return False;
+ if (cause!=NULL) {
+ xkbControlsNotify cn;
+ cn.numGroups= ctrls->num_groups;
+ cn.changedControls|= XkbControlsEnabledMask;
+ cn.enabledControls= ctrls->enabled_ctrls;
+ cn.enabledControlChanges= (ctrls->enabled_ctrls^old);
+ cn.keycode= cause->kc;
+ cn.eventType= cause->event;
+ cn.requestMajor= cause->mjr;
+ cn.requestMinor= cause->mnr;
+ XkbSendControlsNotify(xkbi->device,&cn);
+ }
+ else {
+ /* Yes, this really should be an XOR. If ctrls->enabled_ctrls_changes*/
+ /* is non-zero, the controls in question changed already in "this" */
+ /* request and this change merely undoes the previous one. By the */
+ /* same token, we have to figure out whether or not ControlsEnabled */
+ /* should be set or not in the changes structure */
+ changes->ctrls.enabled_ctrls_changes^= (ctrls->enabled_ctrls^old);
+ if (changes->ctrls.enabled_ctrls_changes)
+ changes->ctrls.changed_ctrls|= XkbControlsEnabledMask;
+ else changes->ctrls.changed_ctrls&= ~XkbControlsEnabledMask;
+ }
+ sli= XkbFindSrvLedInfo(xkbi->device,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(xkbi->device,sli->usesControls,True,changes,cause);
+ return True;
+}
+
+/***====================================================================***/
+
+#define MAX_TOC 16
+
+XkbGeometryPtr
+#if NeedFunctionPrototypes
+XkbLookupNamedGeometry(DeviceIntPtr dev,Atom name,Bool *shouldFree)
+#else
+XkbLookupNamedGeometry(dev,name,shouldFree)
+ DeviceIntPtr dev;
+ Atom name;
+ Bool * shouldFree;
+#endif
+{
+XkbSrvInfoPtr xkbi= dev->key->xkbInfo;
+XkbDescPtr xkb= xkbi->desc;
+
+ *shouldFree= 0;
+ if (name==None) {
+ if (xkb->geom!=NULL)
+ return xkb->geom;
+ name= xkb->names->geometry;
+ }
+ if ((xkb->geom!=NULL)&&(xkb->geom->name==name))
+ return xkb->geom;
+ else if ((name==xkb->names->geometry)&&(xkb->geom==NULL)) {
+ FILE *file= XkbDDXOpenConfigFile(XkbInitialMap,NULL,0);
+ if (file!=NULL) {
+ XkbFileInfo xkbFInfo;
+ xkmFileInfo finfo;
+ xkmSectionInfo toc[MAX_TOC],*entry;
+ bzero(&xkbFInfo,sizeof(xkbFInfo));
+ xkbFInfo.xkb= xkb;
+ if (XkmReadTOC(file,&finfo,MAX_TOC,toc)) {
+ entry= XkmFindTOCEntry(&finfo,toc,XkmGeometryIndex);
+ if (entry!=NULL)
+ XkmReadFileSection(file,entry,&xkbFInfo,NULL);
+ }
+ fclose(file);
+ if (xkb->geom) {
+ *shouldFree= 0;
+ return xkb->geom;
+ }
+ }
+ }
+ *shouldFree= 1;
+ return NULL;
+}
+
+void
+#if NeedFunctionPrototypes
+XkbConvertCase(register KeySym sym, KeySym *lower, KeySym *upper)
+#else
+XkbConvertCase(sym, lower, upper)
+ register KeySym sym;
+ KeySym *lower;
+ KeySym *upper;
+#endif
+{
+ *lower = sym;
+ *upper = sym;
+ switch(sym >> 8) {
+ case 0: /* Latin 1 */
+ if ((sym >= XK_A) && (sym <= XK_Z))
+ *lower += (XK_a - XK_A);
+ else if ((sym >= XK_a) && (sym <= XK_z))
+ *upper -= (XK_a - XK_A);
+ else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
+ *lower += (XK_agrave - XK_Agrave);
+ else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
+ *upper -= (XK_agrave - XK_Agrave);
+ else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
+ *lower += (XK_oslash - XK_Ooblique);
+ else if ((sym >= XK_oslash) && (sym <= XK_thorn))
+ *upper -= (XK_oslash - XK_Ooblique);
+ break;
+ case 1: /* Latin 2 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym == XK_Aogonek)
+ *lower = XK_aogonek;
+ else if (sym >= XK_Lstroke && sym <= XK_Sacute)
+ *lower += (XK_lstroke - XK_Lstroke);
+ else if (sym >= XK_Scaron && sym <= XK_Zacute)
+ *lower += (XK_scaron - XK_Scaron);
+ else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
+ *lower += (XK_zcaron - XK_Zcaron);
+ else if (sym == XK_aogonek)
+ *upper = XK_Aogonek;
+ else if (sym >= XK_lstroke && sym <= XK_sacute)
+ *upper -= (XK_lstroke - XK_Lstroke);
+ else if (sym >= XK_scaron && sym <= XK_zacute)
+ *upper -= (XK_scaron - XK_Scaron);
+ else if (sym >= XK_zcaron && sym <= XK_zabovedot)
+ *upper -= (XK_zcaron - XK_Zcaron);
+ else if (sym >= XK_Racute && sym <= XK_Tcedilla)
+ *lower += (XK_racute - XK_Racute);
+ else if (sym >= XK_racute && sym <= XK_tcedilla)
+ *upper -= (XK_racute - XK_Racute);
+ break;
+ case 2: /* Latin 3 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
+ *lower += (XK_hstroke - XK_Hstroke);
+ else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
+ *lower += (XK_gbreve - XK_Gbreve);
+ else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
+ *upper -= (XK_hstroke - XK_Hstroke);
+ else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
+ *upper -= (XK_gbreve - XK_Gbreve);
+ else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
+ *lower += (XK_cabovedot - XK_Cabovedot);
+ else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
+ *upper -= (XK_cabovedot - XK_Cabovedot);
+ break;
+ case 3: /* Latin 4 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Rcedilla && sym <= XK_Tslash)
+ *lower += (XK_rcedilla - XK_Rcedilla);
+ else if (sym >= XK_rcedilla && sym <= XK_tslash)
+ *upper -= (XK_rcedilla - XK_Rcedilla);
+ else if (sym == XK_ENG)
+ *lower = XK_eng;
+ else if (sym == XK_eng)
+ *upper = XK_ENG;
+ else if (sym >= XK_Amacron && sym <= XK_Umacron)
+ *lower += (XK_amacron - XK_Amacron);
+ else if (sym >= XK_amacron && sym <= XK_umacron)
+ *upper -= (XK_amacron - XK_Amacron);
+ break;
+ case 6: /* Cyrillic */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
+ *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
+ else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
+ *upper += (XK_Serbian_DJE - XK_Serbian_dje);
+ else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
+ *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
+ else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
+ *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
+ break;
+ case 7: /* Greek */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
+ *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
+ else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
+ sym != XK_Greek_iotaaccentdieresis &&
+ sym != XK_Greek_upsilonaccentdieresis)
+ *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
+ else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
+ *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
+ else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&
+ sym != XK_Greek_finalsmallsigma)
+ *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
+ break;
+ }
+}
diff --git a/xc/util/compress/Makefile b/xc/util/compress/Makefile
new file mode 100644
index 000000000..8fd79e577
--- /dev/null
+++ b/xc/util/compress/Makefile
@@ -0,0 +1,66 @@
+#
+# Copyright (c) 1987 The Regents of the University of California.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are permitted
+# provided that the above copyright notice and this paragraph are
+# duplicated in all such forms and that any documentation,
+# advertising materials, and other materials related to such
+# distribution and use acknowledge that the software was developed
+# by the University of California, Berkeley. The name of the
+# University may not be used to endorse or promote products derived
+# from this software without specific prior written permission.
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+#
+# @(#)Makefile 5.9 (Berkeley) 10/15/88
+#
+CFLAGS= -O -DBSD4_2 -DSACREDMEM=256000 -DUSERMEM=`cat USERMEM`
+LIBC= /lib/libc.a
+SRCS= compress.c
+OBJS=
+MAN= compress.0
+
+all: compress
+
+compress: USERMEM ${LIBC}
+ ${CC} ${CFLAGS} -o $@ $@.c
+
+#this one is for OS/2, change location of BINMODE
+BINMODE=/emx/lib/binmode.o
+compress.exe: compress.c
+ gcc -O -o compress.exe compress.c ${BINMODE}
+
+# USERMEM may have to be set by hand. It should contain the amount of
+# available user memory in bytes. Set it to zero, for physical memory
+# less than 1 Meg.
+USERMEM: FRC
+ sh usermem.sh > USERMEM
+
+clean:
+ rm -f ${OBJS} core compress
+
+cleandir: clean
+ rm -f ${MAN} tags .depend
+
+depend: ${SRCS}
+ mkdep -p ${CFLAGS} ${SRCS}
+
+install: ${MAN}
+ install -s -o bin -g bin -m 755 compress ${DESTDIR}/usr/ucb/compress
+ rm -f ${DESTDIR}/usr/ucb/uncompress ${DESTDIR}/usr/ucb/zcat
+ ln ${DESTDIR}/usr/ucb/compress ${DESTDIR}/usr/ucb/uncompress
+ ln ${DESTDIR}/usr/ucb/compress ${DESTDIR}/usr/ucb/zcat
+ rm -f ${DESTDIR}/usr/man/cat1/uncompress.0 ${DESTDIR}/usr/man/cat1/zcat.0
+ install -c -o bin -g bin -m 444 compress.0 ${DESTDIR}/usr/man/cat1
+ ln ${DESTDIR}/usr/man/cat1/compress.0 ${DESTDIR}/usr/man/cat1/uncompress.0
+ ln ${DESTDIR}/usr/man/cat1/compress.0 ${DESTDIR}/usr/man/cat1/zcat.0
+
+lint: ${SRCS}
+ lint ${CFLAGS} ${SRCS}
+
+tags: ${SRCS}
+ ctags ${SRCS}
+
+FRC:
diff --git a/xc/util/compress/README b/xc/util/compress/README
new file mode 100644
index 000000000..c8375c85c
--- /dev/null
+++ b/xc/util/compress/README
@@ -0,0 +1,283 @@
+
+ @(#)README 5.3 (Berkeley) 9/17/85
+
+Compress version 4.0 improvements over 3.0:
+ o compress() speedup (10-50%) by changing division hash to xor
+ o decompress() speedup (5-10%)
+ o Memory requirements reduced (3-30%)
+ o Stack requirements reduced to less than 4kb
+ o Removed 'Big+Fast' compress code (FBITS) because of compress speedup
+ o Portability mods for Z8000 and PC/XT (but not zeus 3.2)
+ o Default to 'quiet' mode
+ o Unification of 'force' flags
+ o Manual page overhaul
+ o Portability enhancement for M_XENIX
+ o Removed text on #else and #endif
+ o Added "-V" switch to print version and options
+ o Added #defines for SIGNED_COMPARE_SLOW
+ o Added Makefile and "usermem" program
+ o Removed all floating point computations
+ o New programs: [deleted]
+
+The "usermem" script attempts to determine the maximum process size. Some
+editing of the script may be necessary (see the comments). [It should work
+fine on 4.3 bsd.] If you can't get it to work at all, just create file
+"USERMEM" containing the maximum process size in decimal.
+
+The following preprocessor symbols control the compilation of "compress.c":
+
+ o USERMEM Maximum process memory on the system
+ o SACREDMEM Amount to reserve for other proceses
+ o SIGNED_COMPARE_SLOW Unsigned compare instructions are faster
+ o NO_UCHAR Don't use "unsigned char" types
+ o BITS Overrules default set by USERMEM-SACREDMEM
+ o vax Generate inline assembler
+ o interdata Defines SIGNED_COMPARE_SLOW
+ o M_XENIX Makes arrays < 65536 bytes each
+ o pdp11 BITS=12, NO_UCHAR
+ o z8000 BITS=12
+ o pcxt BITS=12
+ o BSD4_2 Allow long filenames ( > 14 characters) &
+ Call setlinebuf(stderr)
+
+The difference "usermem-sacredmem" determines the maximum BITS that can be
+specified with the "-b" flag.
+
+memory: at least BITS
+------ -- ----- ----
+ 433,484 16
+ 229,600 15
+ 127,536 14
+ 73,464 13
+ 0 12
+
+The default is BITS=16.
+
+The maximum bits can be overrulled by specifying "-DBITS=bits" at
+compilation time.
+
+WARNING: files compressed on a large machine with more bits than allowed by
+a version of compress on a smaller machine cannot be decompressed! Use the
+"-b12" flag to generate a file on a large machine that can be uncompressed
+on a 16-bit machine.
+
+The output of compress 4.0 is fully compatible with that of compress 3.0.
+In other words, the output of compress 4.0 may be fed into uncompress 3.0 or
+the output of compress 3.0 may be fed into uncompress 4.0.
+
+The output of compress 4.0 not compatible with that of
+compress 2.0. However, compress 4.0 still accepts the output of
+compress 2.0. To generate output that is compatible with compress
+2.0, use the undocumented "-C" flag.
+
+ -from mod.sources, submitted by vax135!petsd!joe (Joe Orost), 8/1/85
+--------------------------------
+
+Enclosed is compress version 3.0 with the following changes:
+
+1. "Block" compression is performed. After the BITS run out, the
+ compression ratio is checked every so often. If it is decreasing,
+ the table is cleared and a new set of substrings are generated.
+
+ This makes the output of compress 3.0 not compatible with that of
+ compress 2.0. However, compress 3.0 still accepts the output of
+ compress 2.0. To generate output that is compatible with compress
+ 2.0, use the undocumented "-C" flag.
+
+2. A quiet "-q" flag has been added for use by the news system.
+
+3. The character chaining has been deleted and the program now uses
+ hashing. This improves the speed of the program, especially
+ during decompression. Other speed improvements have been made,
+ such as using putc() instead of fwrite().
+
+4. A large table is used on large machines when a relatively small
+ number of bits is specified. This saves much time when compressing
+ for a 16-bit machine on a 32-bit virtual machine. Note that the
+ speed improvement only occurs when the input file is > 30000
+ characters, and the -b BITS is less than or equal to the cutoff
+ described below.
+
+Most of these changes were made by James A. Woods (ames!jaw). Thank you
+James!
+
+To compile compress:
+
+ cc -O -DUSERMEM=usermem -o compress compress.c
+
+Where "usermem" is the amount of physical user memory available (in bytes).
+If any physical memory is to be reserved for other processes, put in
+"-DSACREDMEM sacredmem", where "sacredmem" is the amount to be reserved.
+
+The difference "usermem-sacredmem" determines the maximum BITS that can be
+specified, and the cutoff bits where the large+fast table is used.
+
+memory: at least BITS cutoff
+------ -- ----- ---- ------
+ 4,718,592 16 13
+ 2,621,440 16 12
+ 1,572,864 16 11
+ 1,048,576 16 10
+ 631,808 16 --
+ 329,728 15 --
+ 178,176 14 --
+ 99,328 13 --
+ 0 12 --
+
+The default memory size is 750,000 which gives a maximum BITS=16 and no
+large+fast table.
+
+The maximum bits can be overruled by specifying "-DBITS=bits" at
+compilation time.
+
+If your machine doesn't support unsigned characters, define "NO_UCHAR"
+when compiling.
+
+If your machine has "int" as 16-bits, define "SHORT_INT" when compiling.
+
+After compilation, move "compress" to a standard executable location, such
+as /usr/local. Then:
+ cd /usr/local
+ ln compress uncompress
+ ln compress zcat
+
+On machines that have a fixed stack size (such as Perkin-Elmer), set the
+stack to at least 12kb. ("setstack compress 12" on Perkin-Elmer).
+
+Next, install the manual (compress.l).
+ cp compress.l /usr/man/manl
+ cd /usr/man/manl
+ ln compress.l uncompress.l
+ ln compress.l zcat.l
+
+ - or -
+
+ cp compress.l /usr/man/man1/compress.1
+ cd /usr/man/man1
+ ln compress.1 uncompress.1
+ ln compress.1 zcat.1
+
+ regards,
+ petsd!joe
+
+Here is a note from the net:
+
+>From hplabs!pesnta!amd!turtlevax!ken Sat Jan 5 03:35:20 1985
+Path: ames!hplabs!pesnta!amd!turtlevax!ken
+From: ken@turtlevax.UUCP (Ken Turkowski)
+Newsgroups: net.sources
+Subject: Re: Compress release 3.0 : sample Makefile
+Organization: CADLINC, Inc. @ Menlo Park, CA
+
+In the compress 3.0 source recently posted to mod.sources, there is a
+#define variable which can be set for optimum performance on a machine
+with a large amount of memory. A program (usermem) to calculate the
+useable amount of physical user memory is enclosed, as well as a sample
+4.2bsd Vax Makefile for compress.
+
+Here is the README file from the previous version of compress (2.0):
+
+>Enclosed is compress.c version 2.0 with the following bugs fixed:
+>
+>1. The packed files produced by compress are different on different
+> machines and dependent on the vax sysgen option.
+> The bug was in the different byte/bit ordering on the
+> various machines. This has been fixed.
+>
+> This version is NOT compatible with the original vax posting
+> unless the '-DCOMPATIBLE' option is specified to the C
+> compiler. The original posting has a bug which I fixed,
+> causing incompatible files. I recommend you NOT to use this
+> option unless you already have a lot of packed files from
+> the original posting by thomas.
+>2. The exit status is not well defined (on some machines) causing the
+> scripts to fail.
+> The exit status is now 0,1 or 2 and is documented in
+> compress.l.
+>3. The function getopt() is not available in all C libraries.
+> The function getopt() is no longer referenced by the
+> program.
+>4. Error status is not being checked on the fwrite() and fflush() calls.
+> Fixed.
+>
+>The following enhancements have been made:
+>
+>1. Added facilities of "compact" into the compress program. "Pack",
+> "Unpack", and "Pcat" are no longer required (no longer supplied).
+>2. Installed work around for C compiler bug with "-O".
+>3. Added a magic number header (\037\235). Put the bits specified
+> in the file.
+>4. Added "-f" flag to force overwrite of output file.
+>5. Added "-c" flag and "zcat" program. 'ln compress zcat' after you
+> compile.
+>6. The 'uncompress' script has been deleted; simply
+> 'ln compress uncompress' after you compile and it will work.
+>7. Removed extra bit masking for machines that support unsigned
+> characters. If your machine doesn't support unsigned characters,
+> define "NO_UCHAR" when compiling.
+>
+>Compile "compress.c" with "-O -o compress" flags. Move "compress" to a
+>standard executable location, such as /usr/local. Then:
+> cd /usr/local
+> ln compress uncompress
+> ln compress zcat
+>
+>On machines that have a fixed stack size (such as Perkin-Elmer), set the
+>stack to at least 12kb. ("setstack compress 12" on Perkin-Elmer).
+>
+>Next, install the manual (compress.l).
+> cp compress.l /usr/man/manl - or -
+> cp compress.l /usr/man/man1/compress.1
+>
+>Here is the README that I sent with my first posting:
+>
+>>Enclosed is a modified version of compress.c, along with scripts to make it
+>>run identically to pack(1), unpack(1), an pcat(1). Here is what I
+>>(petsd!joe) and a colleague (petsd!peora!srd) did:
+>>
+>>1. Removed VAX dependencies.
+>>2. Changed the struct to separate arrays; saves mucho memory.
+>>3. Did comparisons in unsigned, where possible. (Faster on Perkin-Elmer.)
+>>4. Sorted the character next chain and changed the search to stop
+>>prematurely. This saves a lot on the execution time when compressing.
+>>
+>>This version is totally compatible with the original version. Even though
+>>lint(1) -p has no complaints about compress.c, it won't run on a 16-bit
+>>machine, due to the size of the arrays.
+>>
+>>Here is the README file from the original author:
+>>
+>>>Well, with all this discussion about file compression (for news batching
+>>>in particular) going around, I decided to implement the text compression
+>>>algorithm described in the June Computer magazine. The author claimed
+>>>blinding speed and good compression ratios. It's certainly faster than
+>>>compact (but, then, what wouldn't be), but it's also the same speed as
+>>>pack, and gets better compression than both of them. On 350K bytes of
+>>>unix-wizards, compact took about 8 minutes of CPU, pack took about 80
+>>>seconds, and compress (herein) also took 80 seconds. But, compact and
+>>>pack got about 30% compression, whereas compress got over 50%. So, I
+>>>decided I had something, and that others might be interested, too.
+>>>
+>>>As is probably true of compact and pack (although I haven't checked),
+>>>the byte order within a word is probably relevant here, but as long as
+>>>you stay on a single machine type, you should be ok. (Can anybody
+>>>elucidate on this?) There are a couple of asm's in the code (extv and
+>>>insv instructions), so anyone porting it to another machine will have to
+>>>deal with this anyway (and could probably make it compatible with Vax
+>>>byte order at the same time). Anyway, I've linted the code (both with
+>>>and without -p), so it should run elsewhere. Note the longs in the
+>>>code, you can take these out if you reduce BITS to <= 15.
+>>>
+>>>Have fun, and as always, if you make good enhancements, or bug fixes,
+>>>I'd like to see them.
+>>>
+>>>=Spencer (thomas@utah-20, {harpo,hplabs,arizona}!utah-cs!thomas)
+>>
+>> regards,
+>> joe
+>>
+>>--
+>>Full-Name: Joseph M. Orost
+>>UUCP: ..!{decvax,ucbvax,ihnp4}!vax135!petsd!joe
+>>US Mail: MS 313; Perkin-Elmer; 106 Apple St; Tinton Falls, NJ 07724
+>>Phone: (201) 870-5844
diff --git a/xc/util/compress/USERMEM b/xc/util/compress/USERMEM
new file mode 100644
index 000000000..79ee5ef74
--- /dev/null
+++ b/xc/util/compress/USERMEM
@@ -0,0 +1 @@
+6144000
diff --git a/xc/util/compress/compress.1 b/xc/util/compress/compress.1
new file mode 100644
index 000000000..572e078f9
--- /dev/null
+++ b/xc/util/compress/compress.1
@@ -0,0 +1,252 @@
+.\" Copyright (c) 1986 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" James A. Woods, derived from original work by Spencer Thomas
+.\" and Joseph Orost.
+.\"
+.\" Redistribution and use in source and binary forms are permitted
+.\" provided that the above copyright notice and this paragraph are
+.\" duplicated in all such forms and that any documentation,
+.\" advertising materials, and other materials related to such
+.\" distribution and use acknowledge that the software was developed
+.\" by the University of California, Berkeley. The name of the
+.\" University may not be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.\" @(#)compress.1 6.6 (Berkeley) 10/15/88
+.\"
+.TH COMPRESS 1 "October 15, 1988"
+.UC 6
+.SH NAME
+compress, uncompress, zcat \- compress and expand data
+.SH SYNOPSIS
+.PU
+.ll +8
+.B compress
+[
+.B \-f
+] [
+.B \-v
+] [
+.B \-c
+] [
+.B \-b
+.I bits
+] [
+.I "name \&..."
+]
+.ll -8
+.br
+.B uncompress
+[
+.B \-f
+] [
+.B \-v
+] [
+.B \-c
+] [
+.I "name \&..."
+]
+.br
+.B zcat
+[
+.I "name \&..."
+]
+.SH DESCRIPTION
+.I Compress
+reduces the size of the named files using adaptive Lempel-Ziv coding.
+Whenever possible,
+each file is replaced by one with the extension
+.B "\&.Z,"
+while keeping the same ownership modes, access and modification times.
+If no files are specified, the standard input is compressed to the
+standard output.
+Compressed files can be restored to their original form using
+.I uncompress
+or
+.I zcat.
+.PP
+The
+.B \-f
+option will force compression of
+.IR name ,
+even if it does not actually shrink
+or the corresponding
+.IR name .Z
+file already exists.
+Except when run in the background under
+.IR /bin/sh ,
+if
+.B \-f
+is not given the user is prompted as to whether an existing
+.IR name .Z
+file should be overwritten.
+.PP
+The
+.B \-c
+(``cat'') option makes
+.I compress/uncompress
+write to the standard output; no files are changed.
+The nondestructive behavior of
+.I zcat
+is identical to that of
+.I uncompress
+.B \-c.
+.PP
+.I Compress
+uses the modified Lempel-Ziv algorithm popularized in
+"A Technique for High Performance Data Compression",
+Terry A. Welch,
+.I "IEEE Computer,"
+vol. 17, no. 6 (June 1984), pp. 8-19.
+Common substrings in the file are first replaced by 9-bit codes 257 and up.
+When code 512 is reached, the algorithm switches to 10-bit codes and
+continues to use more bits until the
+limit specified by the
+.B \-b
+flag is reached (default 16).
+.I Bits
+must be between 9 and 16. The default can be changed in the source to allow
+.I compress
+to be run on a smaller machine.
+.PP
+After the
+.I bits
+limit is attained,
+.I compress
+periodically checks the compression ratio. If it is increasing,
+.I compress
+continues to use the existing code dictionary. However,
+if the compression ratio decreases,
+.I compress
+discards the table of substrings and rebuilds it from scratch. This allows
+the algorithm to adapt to the next "block" of the file.
+.PP
+Note that the
+.B \-b
+flag is omitted for
+.I uncompress,
+since the
+.I bits
+parameter specified during compression
+is encoded within the output, along with
+a magic number to ensure that neither decompression of random data nor
+recompression of compressed data is attempted.
+.PP
+.ne 8
+The amount of compression obtained depends on the size of the
+input, the number of
+.I bits
+per code, and the distribution of common substrings.
+Typically, text such as source code or English
+is reduced by 50\-60%.
+Compression is generally much better than that achieved by
+Huffman coding (as used in
+.IR pack ),
+or adaptive Huffman coding
+.RI ( compact ),
+and takes less time to compute.
+.PP
+The
+.B \-v
+option causes
+the printing of the percentage reduction of each file.
+.PP
+If an error occurs, exit status is 1, else
+if the last file was not compressed because it became larger, the status
+is 2; else the status is 0.
+.SH "DIAGNOSTICS"
+Usage: compress [\-fvc] [\-b maxbits] [file ...]
+.in +8
+Invalid options were specified on the command line.
+.in -8
+Missing maxbits
+.in +8
+Maxbits must follow
+.BR \-b \.
+.in -8
+.IR file :
+not in compressed format
+.in +8
+The file specified to
+.I uncompress
+has not been compressed.
+.in -8
+.IR file :
+compressed with
+.I xx
+bits, can only handle
+.I yy
+bits
+.in +8
+.I File
+was compressed by a program that could deal with
+more
+.I bits
+than the compress code on this machine.
+Recompress the file with smaller
+.IR bits \.
+.in -8
+.IR file :
+already has .Z suffix -- no change
+.in +8
+The file is assumed to be already compressed.
+Rename the file and try again.
+.in -8
+.IR file :
+filename too long to tack on .Z
+.in +8
+The file cannot be compressed because its name is longer than
+12 characters.
+Rename and try again.
+This message does not occur on BSD systems.
+.in -8
+.I file
+already exists; do you wish to overwrite (y or n)?
+.in +8
+Respond "y" if you want the output file to be replaced; "n" if not.
+.in -8
+uncompress: corrupt input
+.in +8
+A SIGSEGV violation was detected which usually means that the input file is
+corrupted.
+.in -8
+Compression:
+.I "xx.xx%"
+.in +8
+Percentage of the input saved by compression.
+(Relevant only for
+.BR \-v \.)
+.in -8
+-- not a regular file: unchanged
+.in +8
+When the input file is not a regular file,
+(e.g. a directory), it is
+left unaltered.
+.in -8
+-- has
+.I xx
+other links: unchanged
+.in +8
+The input file has links; it is left unchanged. See
+.IR ln "(1)"
+for more information.
+.in -8
+-- file unchanged
+.in +8
+No savings is achieved by
+compression. The input remains virgin.
+.in -8
+.SH "BUGS"
+Although compressed files are compatible between machines with large memory,
+.BR \-b \12
+should be used for file transfer to architectures with
+a small process data space (64KB or less, as exhibited by the DEC PDP
+series, the Intel 80286, etc.)
+.PP
+.I compress
+should be more flexible about the existence of the `.Z' suffix.
diff --git a/xc/util/compress/compress.c b/xc/util/compress/compress.c
new file mode 100644
index 000000000..1d4fb1ed3
--- /dev/null
+++ b/xc/util/compress/compress.c
@@ -0,0 +1,1550 @@
+/*
+ * Copyright (c) 1985, 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * James A. Woods, derived from original work by Spencer Thomas
+ * and Joseph Orost.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1985, 1986 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)compress.c 5.10 (Berkeley) 10/15/88";
+#endif /* not lint */
+
+/*
+ * Compress - data compression program
+ */
+#define min(a,b) ((a>b) ? b : a)
+
+/*
+ * machine variants which require cc -Dmachine: pdp11, z8000, pcxt
+ */
+
+/*
+ * Set USERMEM to the maximum amount of physical user memory available
+ * in bytes. USERMEM is used to determine the maximum BITS that can be used
+ * for compression.
+ *
+ * SACREDMEM is the amount of physical memory saved for others; compress
+ * will hog the rest.
+ */
+#ifndef SACREDMEM
+#define SACREDMEM 0
+#endif
+
+#ifndef USERMEM
+# define USERMEM 450000 /* default user memory */
+#endif
+
+#ifdef interdata /* (Perkin-Elmer) */
+#define SIGNED_COMPARE_SLOW /* signed compare is slower than unsigned */
+#endif
+
+#ifdef pdp11
+# define BITS 12 /* max bits/code for 16-bit machine */
+# define NO_UCHAR /* also if "unsigned char" functions as signed char */
+# undef USERMEM
+#endif /* pdp11 */ /* don't forget to compile with -i */
+
+#ifdef z8000
+# define BITS 12
+# undef vax /* weird preprocessor */
+# undef USERMEM
+#endif /* z8000 */
+
+#ifdef pcxt
+# define BITS 12
+# undef USERMEM
+#endif /* pcxt */
+
+#ifdef USERMEM
+# if USERMEM >= (433484+SACREDMEM)
+# define PBITS 16
+# else
+# if USERMEM >= (229600+SACREDMEM)
+# define PBITS 15
+# else
+# if USERMEM >= (127536+SACREDMEM)
+# define PBITS 14
+# else
+# if USERMEM >= (73464+SACREDMEM)
+# define PBITS 13
+# else
+# define PBITS 12
+# endif
+# endif
+# endif
+# endif
+# undef USERMEM
+#endif /* USERMEM */
+
+#ifdef PBITS /* Preferred BITS for this memory size */
+# ifndef BITS
+# define BITS PBITS
+# endif /* BITS */
+#endif /* PBITS */
+
+#if BITS == 16
+# define HSIZE 69001 /* 95% occupancy */
+#endif
+#if BITS == 15
+# define HSIZE 35023 /* 94% occupancy */
+#endif
+#if BITS == 14
+# define HSIZE 18013 /* 91% occupancy */
+#endif
+#if BITS == 13
+# define HSIZE 9001 /* 91% occupancy */
+#endif
+#if BITS <= 12
+# define HSIZE 5003 /* 80% occupancy */
+#endif
+
+#ifdef M_XENIX /* Stupid compiler can't handle arrays with */
+# if BITS == 16 /* more than 65535 bytes - so we fake it */
+# define XENIX_16
+# else
+# if BITS > 13 /* Code only handles BITS = 12, 13, or 16 */
+# define BITS 13
+# endif
+# endif
+#endif
+
+/*
+ * a code_int must be able to hold 2**BITS values of type int, and also -1
+ */
+#if BITS > 15
+typedef long int code_int;
+#else
+typedef int code_int;
+#endif
+
+#ifdef SIGNED_COMPARE_SLOW
+typedef unsigned long int count_int;
+typedef unsigned short int count_short;
+#else
+typedef long int count_int;
+#endif
+
+#ifdef NO_UCHAR
+ typedef char char_type;
+#else
+ typedef unsigned char char_type;
+#endif /* UCHAR */
+char_type magic_header[] = { "\037\235" }; /* 1F 9D */
+
+/* Defines for third byte of header */
+#define BIT_MASK 0x1f
+#define BLOCK_MASK 0x80
+/* Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is
+ a fourth header byte (for expansion).
+*/
+#define INIT_BITS 9 /* initial number of bits/code */
+
+/*
+ * compress.c - File compression ala IEEE Computer, June 1984.
+ *
+ * Authors: Spencer W. Thomas (decvax!utah-cs!thomas)
+ * Jim McKie (decvax!mcvax!jim)
+ * Steve Davies (decvax!vax135!petsd!peora!srd)
+ * Ken Turkowski (decvax!decwrl!turtlevax!ken)
+ * James A. Woods (decvax!ihnp4!ames!jaw)
+ * Joe Orost (decvax!vax135!petsd!joe)
+ *
+ * Header: compress.c,v 4.0 85/07/30 12:50:00 joe Release
+ * Log: compress.c,v
+ * Revision 4.0 85/07/30 12:50:00 joe
+ * Removed ferror() calls in output routine on every output except first.
+ * Prepared for release to the world.
+ *
+ * Revision 3.6 85/07/04 01:22:21 joe
+ * Remove much wasted storage by overlaying hash table with the tables
+ * used by decompress: tab_suffix[1<<BITS], stack[8000]. Updated USERMEM
+ * computations. Fixed dump_tab() DEBUG routine.
+ *
+ * Revision 3.5 85/06/30 20:47:21 jaw
+ * Change hash function to use exclusive-or. Rip out hash cache. These
+ * speedups render the megamemory version defunct, for now. Make decoder
+ * stack global. Parts of the RCS trunks 2.7, 2.6, and 2.1 no longer apply.
+ *
+ * Revision 3.4 85/06/27 12:00:00 ken
+ * Get rid of all floating-point calculations by doing all compression ratio
+ * calculations in fixed point.
+ *
+ * Revision 3.3 85/06/24 21:53:24 joe
+ * Incorporate portability suggestion for M_XENIX. Got rid of text on #else
+ * and #endif lines. Cleaned up #ifdefs for vax and interdata.
+ *
+ * Revision 3.2 85/06/06 21:53:24 jaw
+ * Incorporate portability suggestions for Z8000, IBM PC/XT from mailing list.
+ * Default to "quiet" output (no compression statistics).
+ *
+ * Revision 3.1 85/05/12 18:56:13 jaw
+ * Integrate decompress() stack speedups (from early pointer mods by McKie).
+ * Repair multi-file USERMEM gaffe. Unify 'force' flags to mimic semantics
+ * of SVR2 'pack'. Streamline block-compress table clear logic. Increase
+ * output byte count by magic number size.
+ *
+ * Revision 3.0 84/11/27 11:50:00 petsd!joe
+ * Set HSIZE depending on BITS. Set BITS depending on USERMEM. Unrolled
+ * loops in clear routines. Added "-C" flag for 2.0 compatibility. Used
+ * unsigned compares on Perkin-Elmer. Fixed foreground check.
+ *
+ * Revision 2.7 84/11/16 19:35:39 ames!jaw
+ * Cache common hash codes based on input statistics; this improves
+ * performance for low-density raster images. Pass on #ifdef bundle
+ * from Turkowski.
+ *
+ * Revision 2.6 84/11/05 19:18:21 ames!jaw
+ * Vary size of hash tables to reduce time for small files.
+ * Tune PDP-11 hash function.
+ *
+ * Revision 2.5 84/10/30 20:15:14 ames!jaw
+ * Junk chaining; replace with the simpler (and, on the VAX, faster)
+ * double hashing, discussed within. Make block compression standard.
+ *
+ * Revision 2.4 84/10/16 11:11:11 ames!jaw
+ * Introduce adaptive reset for block compression, to boost the rate
+ * another several percent. (See mailing list notes.)
+ *
+ * Revision 2.3 84/09/22 22:00:00 petsd!joe
+ * Implemented "-B" block compress. Implemented REVERSE sorting of tab_next.
+ * Bug fix for last bits. Changed fwrite to putchar loop everywhere.
+ *
+ * Revision 2.2 84/09/18 14:12:21 ames!jaw
+ * Fold in news changes, small machine typedef from thomas,
+ * #ifdef interdata from joe.
+ *
+ * Revision 2.1 84/09/10 12:34:56 ames!jaw
+ * Configured fast table lookup for 32-bit machines.
+ * This cuts user time in half for b <= FBITS, and is useful for news batching
+ * from VAX to PDP sites. Also sped up decompress() [fwrite->putc] and
+ * added signal catcher [plus beef in writeerr()] to delete effluvia.
+ *
+ * Revision 2.0 84/08/28 22:00:00 petsd!joe
+ * Add check for foreground before prompting user. Insert maxbits into
+ * compressed file. Force file being uncompressed to end with ".Z".
+ * Added "-c" flag and "zcat". Prepared for release.
+ *
+ * Revision 1.10 84/08/24 18:28:00 turtlevax!ken
+ * Will only compress regular files (no directories), added a magic number
+ * header (plus an undocumented -n flag to handle old files without headers),
+ * added -f flag to force overwriting of possibly existing destination file,
+ * otherwise the user is prompted for a response. Will tack on a .Z to a
+ * filename if it doesn't have one when decompressing. Will only replace
+ * file if it was compressed.
+ *
+ * Revision 1.9 84/08/16 17:28:00 turtlevax!ken
+ * Removed scanargs(), getopt(), added .Z extension and unlimited number of
+ * filenames to compress. Flags may be clustered (-Ddvb12) or separated
+ * (-D -d -v -b 12), or combination thereof. Modes and other status is
+ * copied with copystat(). -O bug for 4.2 seems to have disappeared with
+ * 1.8.
+ *
+ * Revision 1.8 84/08/09 23:15:00 joe
+ * Made it compatible with vax version, installed jim's fixes/enhancements
+ *
+ * Revision 1.6 84/08/01 22:08:00 joe
+ * Sped up algorithm significantly by sorting the compress chain.
+ *
+ * Revision 1.5 84/07/13 13:11:00 srd
+ * Added C version of vax asm routines. Changed structure to arrays to
+ * save much memory. Do unsigned compares where possible (faster on
+ * Perkin-Elmer)
+ *
+ * Revision 1.4 84/07/05 03:11:11 thomas
+ * Clean up the code a little and lint it. (Lint complains about all
+ * the regs used in the asm, but I'm not going to "fix" this.)
+ *
+ * Revision 1.3 84/07/05 02:06:54 thomas
+ * Minor fixes.
+ *
+ * Revision 1.2 84/07/05 00:27:27 thomas
+ * Add variable bit length output.
+ *
+ */
+static char rcs_ident[] = "Header: compress.c,v 4.0 85/07/30 12:50:00 joe Release";
+
+#include <stdio.h>
+#include <ctype.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef notdef
+#include <sys/ioctl.h>
+#endif
+
+#define ARGVAL() (*++(*argv) || (--argc && *++argv))
+
+int n_bits; /* number of bits/code */
+int maxbits = BITS; /* user settable max # bits/code */
+code_int maxcode; /* maximum code, given n_bits */
+code_int maxmaxcode = 1 << BITS; /* should NEVER generate this code */
+#ifdef COMPATIBLE /* But wrong! */
+# define MAXCODE(n_bits) (1 << (n_bits) - 1)
+#else
+# define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
+#endif /* COMPATIBLE */
+
+#ifdef XENIX_16
+count_int htab0[8192];
+count_int htab1[8192];
+count_int htab2[8192];
+count_int htab3[8192];
+count_int htab4[8192];
+count_int htab5[8192];
+count_int htab6[8192];
+count_int htab7[8192];
+count_int htab8[HSIZE-65536];
+count_int * htab[9] = {
+ htab0, htab1, htab2, htab3, htab4, htab5, htab6, htab7, htab8 };
+
+#define htabof(i) (htab[(i) >> 13][(i) & 0x1fff])
+unsigned short code0tab[16384];
+unsigned short code1tab[16384];
+unsigned short code2tab[16384];
+unsigned short code3tab[16384];
+unsigned short code4tab[16384];
+unsigned short * codetab[5] = {
+ code0tab, code1tab, code2tab, code3tab, code4tab };
+
+#define codetabof(i) (codetab[(i) >> 14][(i) & 0x3fff])
+
+#else /* Normal machine */
+
+#ifdef sel /* gould base register braindamage */
+/*NOBASE*/
+count_int htab [HSIZE];
+unsigned short codetab [HSIZE];
+/*NOBASE*/
+#else
+count_int htab [HSIZE];
+unsigned short codetab [HSIZE];
+#endif /* sel */
+
+#define htabof(i) htab[i]
+#define codetabof(i) codetab[i]
+#endif /* XENIX_16 */
+code_int hsize = HSIZE; /* for dynamic table sizing */
+count_int fsize;
+
+/*
+ * To save much memory, we overlay the table used by compress() with those
+ * used by decompress(). The tab_prefix table is the same size and type
+ * as the codetab. The tab_suffix table needs 2**BITS characters. We
+ * get this from the beginning of htab. The output stack uses the rest
+ * of htab, and contains characters. There is plenty of room for any
+ * possible stack (stack used to be 8000 characters).
+ */
+
+#define tab_prefixof(i) codetabof(i)
+#ifdef XENIX_16
+# define tab_suffixof(i) ((char_type *)htab[(i)>>15])[(i) & 0x7fff]
+# define de_stack ((char_type *)(htab2))
+#else /* Normal machine */
+# define tab_suffixof(i) ((char_type *)(htab))[i]
+# define de_stack ((char_type *)&tab_suffixof(1<<BITS))
+#endif /* XENIX_16 */
+
+code_int free_ent = 0; /* first unused entry */
+int exit_stat = 0; /* per-file status */
+int perm_stat = 0; /* permanent status */
+
+code_int getcode();
+
+Usage() {
+#ifdef DEBUG
+fprintf(stderr,"Usage: compress [-dDVfc] [-b maxbits] [file ...]\n");
+}
+int debug = 0;
+#else
+fprintf(stderr,"Usage: compress [-fvc] [-b maxbits] [file ...]\n");
+}
+#endif /* DEBUG */
+int nomagic = 0; /* Use a 3-byte magic number header, unless old file */
+int zcat_flg = 0; /* Write output on stdout, suppress messages */
+int precious = 1; /* Don't unlink output file on interrupt */
+int quiet = 1; /* don't tell me about compression */
+
+/*
+ * block compression parameters -- after all codes are used up,
+ * and compression rate changes, start over.
+ */
+int block_compress = BLOCK_MASK;
+int clear_flg = 0;
+long int ratio = 0;
+#define CHECK_GAP 10000 /* ratio check interval */
+count_int checkpoint = CHECK_GAP;
+/*
+ * the next two codes should not be changed lightly, as they must not
+ * lie within the contiguous general code space.
+ */
+#define FIRST 257 /* first free entry */
+#define CLEAR 256 /* table clear output code */
+
+int force = 0;
+char ofname [100];
+#ifdef DEBUG
+int verbose = 0;
+#endif /* DEBUG */
+int (*oldint)();
+int bgnd_flag;
+
+int do_decomp = 0;
+
+/*****************************************************************
+ * TAG( main )
+ *
+ * Algorithm from "A Technique for High Performance Data Compression",
+ * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.
+ *
+ * Usage: compress [-dfvc] [-b bits] [file ...]
+ * Inputs:
+ * -d: If given, decompression is done instead.
+ *
+ * -c: Write output on stdout, don't remove original.
+ *
+ * -b: Parameter limits the max number of bits/code.
+ *
+ * -f: Forces output file to be generated, even if one already
+ * exists, and even if no space is saved by compressing.
+ * If -f is not used, the user will be prompted if stdin is
+ * a tty, otherwise, the output file will not be overwritten.
+ *
+ * -v: Write compression statistics
+ *
+ * file ...: Files to be compressed. If none specified, stdin
+ * is used.
+ * Outputs:
+ * file.Z: Compressed form of file with same mode, owner, and utimes
+ * or stdout (if stdin used as input)
+ *
+ * Assumptions:
+ * When filenames are given, replaces with the compressed version
+ * (.Z suffix) only if the file decreases in size.
+ * Algorithm:
+ * Modified Lempel-Ziv method (LZW). Basically finds common
+ * substrings and replaces them with a variable size code. This is
+ * deterministic, and can be done on the fly. Thus, the decompression
+ * procedure needs no input table, but tracks the way the table was built.
+ */
+
+main( argc, argv )
+register int argc; char **argv;
+{
+ int overwrite = 0; /* Do not overwrite unless given -f flag */
+ char tempname[100];
+ char **filelist, **fileptr;
+ char *cp, *rindex(), *malloc();
+ struct stat statbuf;
+ extern onintr(), oops();
+
+ /* This bg check only works for sh. */
+ if ( (oldint = signal ( SIGINT, SIG_IGN )) != SIG_IGN ) {
+ signal ( SIGINT, onintr );
+ signal ( SIGSEGV, oops );
+ }
+ bgnd_flag = oldint != SIG_DFL;
+#ifdef notdef /* This works for csh but we don't want it. */
+ { int tgrp;
+ if (bgnd_flag == 0 && ioctl(2, TIOCGPGRP, (char *)&tgrp) == 0 &&
+ getpgrp(0) != tgrp)
+ bgnd_flag = 1;
+ }
+#endif
+
+#ifdef COMPATIBLE
+ nomagic = 1; /* Original didn't have a magic number */
+#endif /* COMPATIBLE */
+
+ filelist = fileptr = (char **)(malloc(argc * sizeof(*argv)));
+ *filelist = NULL;
+
+ if((cp = rindex(argv[0], '/')) != 0) {
+ cp++;
+ } else {
+ cp = argv[0];
+ }
+ if(strcmp(cp, "uncompress") == 0) {
+ do_decomp = 1;
+ } else if(strcmp(cp, "zcat") == 0) {
+ do_decomp = 1;
+ zcat_flg = 1;
+ }
+
+#if defined(BSD4_2) && !defined(__EMX__)
+ /* 4.2BSD dependent - take it out if not */
+ setlinebuf( stderr );
+#endif /* BSD4_2 */
+
+ /* Argument Processing
+ * All flags are optional.
+ * -D => debug
+ * -V => print Version; debug verbose
+ * -d => do_decomp
+ * -v => unquiet
+ * -f => force overwrite of output file
+ * -n => no header: useful to uncompress old files
+ * -b maxbits => maxbits. If -b is specified, then maxbits MUST be
+ * given also.
+ * -c => cat all output to stdout
+ * -C => generate output compatible with compress 2.0.
+ * if a string is left, must be an input filename.
+ */
+ for (argc--, argv++; argc > 0; argc--, argv++) {
+ if (**argv == '-') { /* A flag argument */
+ while (*++(*argv)) { /* Process all flags in this arg */
+ switch (**argv) {
+#ifdef DEBUG
+ case 'D':
+ debug = 1;
+ break;
+ case 'V':
+ verbose = 1;
+ version();
+ break;
+#else
+ case 'V':
+ version();
+ break;
+#endif /* DEBUG */
+ case 'v':
+ quiet = 0;
+ break;
+ case 'd':
+ do_decomp = 1;
+ break;
+ case 'f':
+ case 'F':
+ overwrite = 1;
+ force = 1;
+ break;
+ case 'n':
+ nomagic = 1;
+ break;
+ case 'C':
+ block_compress = 0;
+ break;
+ case 'b':
+ if (!ARGVAL()) {
+ fprintf(stderr, "Missing maxbits\n");
+ Usage();
+ exit(1);
+ }
+ maxbits = atoi(*argv);
+ goto nextarg;
+ case 'c':
+ zcat_flg = 1;
+ break;
+ case 'q':
+ quiet = 1;
+ break;
+ default:
+ fprintf(stderr, "Unknown flag: '%c'; ", **argv);
+ Usage();
+ exit(1);
+ }
+ }
+ }
+ else { /* Input file name */
+ *fileptr++ = *argv; /* Build input file list */
+ *fileptr = NULL;
+ /* process nextarg; */
+ }
+ nextarg: continue;
+ }
+
+ if(maxbits < INIT_BITS) maxbits = INIT_BITS;
+ if (maxbits > BITS) maxbits = BITS;
+ maxmaxcode = 1 << maxbits;
+
+ if (*filelist != NULL) {
+ for (fileptr = filelist; *fileptr; fileptr++) {
+ exit_stat = 0;
+ if (do_decomp) { /* DECOMPRESSION */
+ /* Check for .Z suffix */
+ if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") != 0) {
+ /* No .Z: tack one on */
+ strcpy(tempname, *fileptr);
+ strcat(tempname, ".Z");
+ *fileptr = tempname;
+ }
+ /* Open input file */
+ if ((freopen(*fileptr, "r", stdin)) == NULL) {
+ perror(*fileptr);
+ perm_stat = 1;
+ continue;
+ }
+ /* Check the magic number */
+ if (nomagic == 0) {
+ if ((getchar() != (magic_header[0] & 0xFF))
+ || (getchar() != (magic_header[1] & 0xFF))) {
+ fprintf(stderr, "%s: not in compressed format\n",
+ *fileptr);
+ continue;
+ }
+ maxbits = getchar(); /* set -b from file */
+ block_compress = maxbits & BLOCK_MASK;
+ maxbits &= BIT_MASK;
+ maxmaxcode = 1 << maxbits;
+ if(maxbits > BITS) {
+ fprintf(stderr,
+ "%s: compressed with %d bits, can only handle %d bits\n",
+ *fileptr, maxbits, BITS);
+ continue;
+ }
+ }
+ /* Generate output filename */
+ strcpy(ofname, *fileptr);
+ ofname[strlen(*fileptr) - 2] = '\0'; /* Strip off .Z */
+ } else { /* COMPRESSION */
+ if (strcmp(*fileptr + strlen(*fileptr) - 2, ".Z") == 0) {
+ fprintf(stderr, "%s: already has .Z suffix -- no change\n",
+ *fileptr);
+ continue;
+ }
+ /* Open input file */
+ if ((freopen(*fileptr, "r", stdin)) == NULL) {
+ perror(*fileptr);
+ perm_stat = 1;
+ continue;
+ }
+ stat ( *fileptr, &statbuf );
+ fsize = (long) statbuf.st_size;
+ /*
+ * tune hash table size for small files -- ad hoc,
+ * but the sizes match earlier #defines, which
+ * serve as upper bounds on the number of output codes.
+ */
+ hsize = HSIZE;
+ if ( fsize < (1 << 12) )
+ hsize = min ( 5003, HSIZE );
+ else if ( fsize < (1 << 13) )
+ hsize = min ( 9001, HSIZE );
+ else if ( fsize < (1 << 14) )
+ hsize = min ( 18013, HSIZE );
+ else if ( fsize < (1 << 15) )
+ hsize = min ( 35023, HSIZE );
+ else if ( fsize < 47000 )
+ hsize = min ( 50021, HSIZE );
+
+ /* Generate output filename */
+ strcpy(ofname, *fileptr);
+#ifndef BSD4_2 /* Short filenames */
+ if ((cp=rindex(ofname,'/')) != NULL) cp++;
+ else cp = ofname;
+ if (strlen(cp) > 12) {
+ fprintf(stderr,"%s: filename too long to tack on .Z\n",cp);
+ continue;
+ }
+#endif /* BSD4_2 Long filenames allowed */
+ strcat(ofname, ".Z");
+ }
+ /* Check for overwrite of existing file */
+ if (overwrite == 0 && zcat_flg == 0) {
+ if (stat(ofname, &statbuf) == 0) {
+ char response[2];
+ response[0] = 'n';
+ fprintf(stderr, "%s already exists;", ofname);
+ if (bgnd_flag == 0 && isatty(2)) {
+ fprintf(stderr, " do you wish to overwrite %s (y or n)? ",
+ ofname);
+ fflush(stderr);
+ read(2, response, 2);
+ while (response[1] != '\n') {
+ if (read(2, response+1, 1) < 0) { /* Ack! */
+ perror("stderr"); break;
+ }
+ }
+ }
+ if (response[0] != 'y') {
+ fprintf(stderr, "\tnot overwritten\n");
+ continue;
+ }
+ }
+ }
+ if(zcat_flg == 0) { /* Open output file */
+ if (freopen(ofname, "w", stdout) == NULL) {
+ perror(ofname);
+ perm_stat = 1;
+ continue;
+ }
+ precious = 0;
+ if(!quiet)
+ fprintf(stderr, "%s: ", *fileptr);
+ }
+
+#ifdef __EMX__
+ /* force setting binary mode */
+ _fsetmode(stdin,"b");
+ _fsetmode(stdout,"b");
+#endif
+
+ /* Actually do the compression/decompression */
+ if (do_decomp == 0) compress();
+#ifndef DEBUG
+ else decompress();
+#else
+ else if (debug == 0) decompress();
+ else printcodes();
+ if (verbose) dump_tab();
+#endif /* DEBUG */
+ if(zcat_flg == 0) {
+ copystat(*fileptr, ofname); /* Copy stats */
+ precious = 1;
+ if((exit_stat == 1) || (!quiet))
+ putc('\n', stderr);
+ }
+ }
+ } else { /* Standard input */
+#ifdef __EMX__
+ /* force setting binary mode */
+ _fsetmode(stdin,"b");
+ _fsetmode(stdout,"b");
+#endif
+ if (do_decomp == 0) {
+ compress();
+#ifdef DEBUG
+ if(verbose) dump_tab();
+#endif /* DEBUG */
+ if(!quiet)
+ putc('\n', stderr);
+ } else {
+ /* Check the magic number */
+ if (nomagic == 0) {
+ if ((getchar()!=(magic_header[0] & 0xFF))
+ || (getchar()!=(magic_header[1] & 0xFF))) {
+ fprintf(stderr, "stdin: not in compressed format\n");
+ exit(1);
+ }
+ maxbits = getchar(); /* set -b from file */
+ block_compress = maxbits & BLOCK_MASK;
+ maxbits &= BIT_MASK;
+ maxmaxcode = 1 << maxbits;
+ fsize = 100000; /* assume stdin large for USERMEM */
+ if(maxbits > BITS) {
+ fprintf(stderr,
+ "stdin: compressed with %d bits, can only handle %d bits\n",
+ maxbits, BITS);
+ exit(1);
+ }
+ }
+#ifndef DEBUG
+ decompress();
+#else
+ if (debug == 0) decompress();
+ else printcodes();
+ if (verbose) dump_tab();
+#endif /* DEBUG */
+ }
+ }
+ exit(perm_stat ? perm_stat : exit_stat);
+}
+
+static int offset;
+long int in_count = 1; /* length of input */
+long int bytes_out; /* length of compressed output */
+long int out_count = 0; /* # of codes output (for debugging) */
+
+/*
+ * compress stdin to stdout
+ *
+ * Algorithm: use open addressing double hashing (no chaining) on the
+ * prefix code / next character combination. We do a variant of Knuth's
+ * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
+ * secondary probe. Here, the modular division first probe is gives way
+ * to a faster exclusive-or manipulation. Also do block compression with
+ * an adaptive reset, whereby the code table is cleared when the compression
+ * ratio decreases, but after the table fills. The variable-length output
+ * codes are re-sized at this point, and a special CLEAR code is generated
+ * for the decompressor. Late addition: construct the table according to
+ * file size for noticeable speed improvement on small files. Please direct
+ * questions about this implementation to ames!jaw.
+ */
+
+compress() {
+ register long fcode;
+ register code_int i = 0;
+ register int c;
+ register code_int ent;
+#ifdef XENIX_16
+ register code_int disp;
+#else /* Normal machine */
+ register int disp;
+#endif
+ register code_int hsize_reg;
+ register int hshift;
+
+#ifndef COMPATIBLE
+ if (nomagic == 0) {
+ putchar(magic_header[0]); putchar(magic_header[1]);
+ putchar((char)(maxbits | block_compress));
+ if(ferror(stdout))
+ writeerr();
+ }
+#endif /* COMPATIBLE */
+
+ offset = 0;
+ bytes_out = 3; /* includes 3-byte header mojo */
+ out_count = 0;
+ clear_flg = 0;
+ ratio = 0;
+ in_count = 1;
+ checkpoint = CHECK_GAP;
+ maxcode = MAXCODE(n_bits = INIT_BITS);
+ free_ent = ((block_compress) ? FIRST : 256 );
+
+ ent = getchar ();
+
+ hshift = 0;
+ for ( fcode = (long) hsize; fcode < 65536L; fcode *= 2L )
+ hshift++;
+ hshift = 8 - hshift; /* set hash code range bound */
+
+ hsize_reg = hsize;
+ cl_hash( (count_int) hsize_reg); /* clear hash table */
+
+#ifdef SIGNED_COMPARE_SLOW
+ while ( (c = getchar()) != (unsigned) EOF ) {
+#else
+ while ( (c = getchar()) != EOF ) {
+#endif
+ in_count++;
+ fcode = (long) (((long) c << maxbits) + ent);
+ i = ((c << hshift) ^ ent); /* xor hashing */
+
+ if ( htabof (i) == fcode ) {
+ ent = codetabof (i);
+ continue;
+ } else if ( (long)htabof (i) < 0 ) /* empty slot */
+ goto nomatch;
+ disp = hsize_reg - i; /* secondary hash (after G. Knott) */
+ if ( i == 0 )
+ disp = 1;
+probe:
+ if ( (i -= disp) < 0 )
+ i += hsize_reg;
+
+ if ( htabof (i) == fcode ) {
+ ent = codetabof (i);
+ continue;
+ }
+ if ( (long)htabof (i) > 0 )
+ goto probe;
+nomatch:
+ output ( (code_int) ent );
+ out_count++;
+ ent = c;
+#ifdef SIGNED_COMPARE_SLOW
+ if ( (unsigned) free_ent < (unsigned) maxmaxcode) {
+#else
+ if ( free_ent < maxmaxcode ) {
+#endif
+ codetabof (i) = free_ent++; /* code -> hashtable */
+ htabof (i) = fcode;
+ }
+ else if ( (count_int)in_count >= checkpoint && block_compress )
+ cl_block ();
+ }
+ /*
+ * Put out the final code.
+ */
+ output( (code_int)ent );
+ out_count++;
+ output( (code_int)-1 );
+
+ /*
+ * Print out stats on stderr
+ */
+ if(zcat_flg == 0 && !quiet) {
+#ifdef DEBUG
+ fprintf( stderr,
+ "%ld chars in, %ld codes (%ld bytes) out, compression factor: ",
+ in_count, out_count, bytes_out );
+ prratio( stderr, in_count, bytes_out );
+ fprintf( stderr, "\n");
+ fprintf( stderr, "\tCompression as in compact: " );
+ prratio( stderr, in_count-bytes_out, in_count );
+ fprintf( stderr, "\n");
+ fprintf( stderr, "\tLargest code (of last block) was %d (%d bits)\n",
+ free_ent - 1, n_bits );
+#else /* !DEBUG */
+ fprintf( stderr, "Compression: " );
+ prratio( stderr, in_count-bytes_out, in_count );
+#endif /* DEBUG */
+ }
+ if(bytes_out > in_count) /* exit(2) if no savings */
+ exit_stat = 2;
+ return;
+}
+
+/*****************************************************************
+ * TAG( output )
+ *
+ * Output the given code.
+ * Inputs:
+ * code: A n_bits-bit integer. If == -1, then EOF. This assumes
+ * that n_bits =< (long)wordsize - 1.
+ * Outputs:
+ * Outputs code to the file.
+ * Assumptions:
+ * Chars are 8 bits long.
+ * Algorithm:
+ * Maintain a BITS character long buffer (so that 8 codes will
+ * fit in it exactly). Use the VAX insv instruction to insert each
+ * code in turn. When the buffer fills up empty it and start over.
+ */
+
+static char buf[BITS];
+
+#ifndef vax
+char_type lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
+char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
+#endif /* vax */
+
+output( code )
+code_int code;
+{
+#ifdef DEBUG
+ static int col = 0;
+#endif /* DEBUG */
+
+ /*
+ * On the VAX, it is important to have the register declarations
+ * in exactly the order given, or the asm will break.
+ */
+ register int r_off = offset, bits= n_bits;
+ register char * bp = buf;
+
+#ifdef DEBUG
+ if ( verbose )
+ fprintf( stderr, "%5d%c", code,
+ (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
+#endif /* DEBUG */
+ if ( code >= 0 ) {
+#ifdef vax
+ /* VAX DEPENDENT!! Implementation on other machines is below.
+ *
+ * Translation: Insert BITS bits from the argument starting at
+ * offset bits from the beginning of buf.
+ */
+ 0; /* Work around for pcc -O bug with asm and if stmt */
+ asm( "insv 4(ap),r11,r10,(r9)" );
+#else /* not a vax */
+/*
+ * byte/bit numbering on the VAX is simulated by the following code
+ */
+ /*
+ * Get to the first byte.
+ */
+ bp += (r_off >> 3);
+ r_off &= 7;
+ /*
+ * Since code is always >= 8 bits, only need to mask the first
+ * hunk on the left.
+ */
+ *bp = (*bp & rmask[r_off]) | (code << r_off) & lmask[r_off];
+ bp++;
+ bits -= (8 - r_off);
+ code >>= 8 - r_off;
+ /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
+ if ( bits >= 8 ) {
+ *bp++ = code;
+ code >>= 8;
+ bits -= 8;
+ }
+ /* Last bits. */
+ if(bits)
+ *bp = code;
+#endif /* vax */
+ offset += n_bits;
+ if ( offset == (n_bits << 3) ) {
+ bp = buf;
+ bits = n_bits;
+ bytes_out += bits;
+ do
+ putchar(*bp++);
+ while(--bits);
+ offset = 0;
+ }
+
+ /*
+ * If the next entry is going to be too big for the code size,
+ * then increase it, if possible.
+ */
+ if ( free_ent > maxcode || (clear_flg > 0))
+ {
+ /*
+ * Write the whole buffer, because the input side won't
+ * discover the size increase until after it has read it.
+ */
+ if ( offset > 0 ) {
+ if( fwrite( buf, 1, n_bits, stdout ) != n_bits)
+ writeerr();
+ bytes_out += n_bits;
+ }
+ offset = 0;
+
+ if ( clear_flg ) {
+ maxcode = MAXCODE (n_bits = INIT_BITS);
+ clear_flg = 0;
+ }
+ else {
+ n_bits++;
+ if ( n_bits == maxbits )
+ maxcode = maxmaxcode;
+ else
+ maxcode = MAXCODE(n_bits);
+ }
+#ifdef DEBUG
+ if ( debug ) {
+ fprintf( stderr, "\nChange to %d bits\n", n_bits );
+ col = 0;
+ }
+#endif /* DEBUG */
+ }
+ } else {
+ /*
+ * At EOF, write the rest of the buffer.
+ */
+ if ( offset > 0 )
+ fwrite( buf, 1, (offset + 7) / 8, stdout );
+ bytes_out += (offset + 7) / 8;
+ offset = 0;
+ fflush( stdout );
+#ifdef DEBUG
+ if ( verbose )
+ fprintf( stderr, "\n" );
+#endif /* DEBUG */
+ if( ferror( stdout ) )
+ writeerr();
+ }
+}
+
+/*
+ * Decompress stdin to stdout. This routine adapts to the codes in the
+ * file building the "string" table on-the-fly; requiring no table to
+ * be stored in the compressed file. The tables used herein are shared
+ * with those of the compress() routine. See the definitions above.
+ */
+
+decompress() {
+ register char_type *stackp;
+ register int finchar;
+ register code_int code, oldcode, incode;
+
+ /*
+ * As above, initialize the first 256 entries in the table.
+ */
+ maxcode = MAXCODE(n_bits = INIT_BITS);
+ for ( code = 255; code >= 0; code-- ) {
+ tab_prefixof(code) = 0;
+ tab_suffixof(code) = (char_type)code;
+ }
+ free_ent = ((block_compress) ? FIRST : 256 );
+
+ finchar = oldcode = getcode();
+ if(oldcode == -1) /* EOF already? */
+ return; /* Get out of here */
+ putchar( (char)finchar ); /* first code must be 8 bits = char */
+ if(ferror(stdout)) /* Crash if can't write */
+ writeerr();
+ stackp = de_stack;
+
+ while ( (code = getcode()) > -1 ) {
+
+ if ( (code == CLEAR) && block_compress ) {
+ for ( code = 255; code >= 0; code-- )
+ tab_prefixof(code) = 0;
+ clear_flg = 1;
+ free_ent = FIRST - 1;
+ if ( (code = getcode ()) == -1 ) /* O, untimely death! */
+ break;
+ }
+ incode = code;
+ /*
+ * Special case for KwKwK string.
+ */
+ if ( code >= free_ent ) {
+ *stackp++ = finchar;
+ code = oldcode;
+ }
+
+ /*
+ * Generate output characters in reverse order
+ */
+#ifdef SIGNED_COMPARE_SLOW
+ while ( ((unsigned long)code) >= ((unsigned long)256) ) {
+#else
+ while ( code >= 256 ) {
+#endif
+ *stackp++ = tab_suffixof(code);
+ code = tab_prefixof(code);
+ }
+ *stackp++ = finchar = tab_suffixof(code);
+
+ /*
+ * And put them out in forward order
+ */
+ do
+ putchar ( *--stackp );
+ while ( stackp > de_stack );
+
+ /*
+ * Generate the new entry.
+ */
+ if ( (code=free_ent) < maxmaxcode ) {
+ tab_prefixof(code) = (unsigned short)oldcode;
+ tab_suffixof(code) = finchar;
+ free_ent = code+1;
+ }
+ /*
+ * Remember previous code.
+ */
+ oldcode = incode;
+ }
+ fflush( stdout );
+ if(ferror(stdout))
+ writeerr();
+}
+
+/*****************************************************************
+ * TAG( getcode )
+ *
+ * Read one code from the standard input. If EOF, return -1.
+ * Inputs:
+ * stdin
+ * Outputs:
+ * code or -1 is returned.
+ */
+
+code_int
+getcode() {
+ /*
+ * On the VAX, it is important to have the register declarations
+ * in exactly the order given, or the asm will break.
+ */
+ register code_int code;
+ static int offset = 0, size = 0;
+ static char_type buf[BITS];
+ register int r_off, bits;
+ register char_type *bp = buf;
+
+ if ( clear_flg > 0 || offset >= size || free_ent > maxcode ) {
+ /*
+ * If the next entry will be too big for the current code
+ * size, then we must increase the size. This implies reading
+ * a new buffer full, too.
+ */
+ if ( free_ent > maxcode ) {
+ n_bits++;
+ if ( n_bits == maxbits )
+ maxcode = maxmaxcode; /* won't get any bigger now */
+ else
+ maxcode = MAXCODE(n_bits);
+ }
+ if ( clear_flg > 0) {
+ maxcode = MAXCODE (n_bits = INIT_BITS);
+ clear_flg = 0;
+ }
+ size = fread( buf, 1, n_bits, stdin );
+ if ( size <= 0 )
+ return -1; /* end of file */
+ offset = 0;
+ /* Round size down to integral number of codes */
+ size = (size << 3) - (n_bits - 1);
+ }
+ r_off = offset;
+ bits = n_bits;
+#ifdef vax
+ asm( "extzv r10,r9,(r8),r11" );
+#else /* not a vax */
+ /*
+ * Get to the first byte.
+ */
+ bp += (r_off >> 3);
+ r_off &= 7;
+ /* Get first part (low order bits) */
+#ifdef NO_UCHAR
+ code = ((*bp++ >> r_off) & rmask[8 - r_off]) & 0xff;
+#else
+ code = (*bp++ >> r_off);
+#endif /* NO_UCHAR */
+ bits -= (8 - r_off);
+ r_off = 8 - r_off; /* now, offset into code word */
+ /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
+ if ( bits >= 8 ) {
+#ifdef NO_UCHAR
+ code |= (*bp++ & 0xff) << r_off;
+#else
+ code |= *bp++ << r_off;
+#endif /* NO_UCHAR */
+ r_off += 8;
+ bits -= 8;
+ }
+ /* high order bits. */
+ code |= (*bp & rmask[bits]) << r_off;
+#endif /* vax */
+ offset += n_bits;
+
+ return code;
+}
+
+char *
+rindex(s, c) /* For those who don't have it in libc.a */
+register char *s, c;
+{
+ char *p;
+ for (p = NULL; *s; s++)
+ if (*s == c)
+ p = s;
+ return(p);
+}
+
+#ifdef DEBUG
+printcodes()
+{
+ /*
+ * Just print out codes from input file. For debugging.
+ */
+ code_int code;
+ int col = 0, bits;
+
+ bits = n_bits = INIT_BITS;
+ maxcode = MAXCODE(n_bits);
+ free_ent = ((block_compress) ? FIRST : 256 );
+ while ( ( code = getcode() ) >= 0 ) {
+ if ( (code == CLEAR) && block_compress ) {
+ free_ent = FIRST - 1;
+ clear_flg = 1;
+ }
+ else if ( free_ent < maxmaxcode )
+ free_ent++;
+ if ( bits != n_bits ) {
+ fprintf(stderr, "\nChange to %d bits\n", n_bits );
+ bits = n_bits;
+ col = 0;
+ }
+ fprintf(stderr, "%5d%c", code, (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
+ }
+ putc( '\n', stderr );
+ exit( 0 );
+}
+
+code_int sorttab[1<<BITS]; /* sorted pointers into htab */
+
+dump_tab() /* dump string table */
+{
+ register int i, first;
+ register ent;
+#define STACK_SIZE 15000
+ int stack_top = STACK_SIZE;
+ register c;
+
+ if(do_decomp == 0) { /* compressing */
+ register int flag = 1;
+
+ for(i=0; i<hsize; i++) { /* build sort pointers */
+ if((long)htabof(i) >= 0) {
+ sorttab[codetabof(i)] = i;
+ }
+ }
+ first = block_compress ? FIRST : 256;
+ for(i = first; i < free_ent; i++) {
+ fprintf(stderr, "%5d: \"", i);
+ de_stack[--stack_top] = '\n';
+ de_stack[--stack_top] = '"';
+ stack_top = in_stack((htabof(sorttab[i])>>maxbits)&0xff,
+ stack_top);
+ for(ent=htabof(sorttab[i]) & ((1<<maxbits)-1);
+ ent > 256;
+ ent=htabof(sorttab[ent]) & ((1<<maxbits)-1)) {
+ stack_top = in_stack(htabof(sorttab[ent]) >> maxbits,
+ stack_top);
+ }
+ stack_top = in_stack(ent, stack_top);
+ fwrite( &de_stack[stack_top], 1, STACK_SIZE-stack_top, stderr);
+ stack_top = STACK_SIZE;
+ }
+ } else if(!debug) { /* decompressing */
+
+ for ( i = 0; i < free_ent; i++ ) {
+ ent = i;
+ c = tab_suffixof(ent);
+ if ( isascii(c) && isprint(c) )
+ fprintf( stderr, "%5d: %5d/'%c' \"",
+ ent, tab_prefixof(ent), c );
+ else
+ fprintf( stderr, "%5d: %5d/\\%03o \"",
+ ent, tab_prefixof(ent), c );
+ de_stack[--stack_top] = '\n';
+ de_stack[--stack_top] = '"';
+ for ( ; ent != NULL;
+ ent = (ent >= FIRST ? tab_prefixof(ent) : NULL) ) {
+ stack_top = in_stack(tab_suffixof(ent), stack_top);
+ }
+ fwrite( &de_stack[stack_top], 1, STACK_SIZE - stack_top, stderr );
+ stack_top = STACK_SIZE;
+ }
+ }
+}
+
+int
+in_stack(c, stack_top)
+ register c, stack_top;
+{
+ if ( (isascii(c) && isprint(c) && c != '\\') || c == ' ' ) {
+ de_stack[--stack_top] = c;
+ } else {
+ switch( c ) {
+ case '\n': de_stack[--stack_top] = 'n'; break;
+ case '\t': de_stack[--stack_top] = 't'; break;
+ case '\b': de_stack[--stack_top] = 'b'; break;
+ case '\f': de_stack[--stack_top] = 'f'; break;
+ case '\r': de_stack[--stack_top] = 'r'; break;
+ case '\\': de_stack[--stack_top] = '\\'; break;
+ default:
+ de_stack[--stack_top] = '0' + c % 8;
+ de_stack[--stack_top] = '0' + (c / 8) % 8;
+ de_stack[--stack_top] = '0' + c / 64;
+ break;
+ }
+ de_stack[--stack_top] = '\\';
+ }
+ return stack_top;
+}
+#endif /* DEBUG */
+
+writeerr()
+{
+ perror ( ofname );
+ unlink ( ofname );
+ exit ( 1 );
+}
+
+copystat(ifname, ofname)
+char *ifname, *ofname;
+{
+ struct stat statbuf;
+ int mode;
+ time_t timep[2];
+
+ fclose(stdout);
+ if (stat(ifname, &statbuf)) { /* Get stat on input file */
+ perror(ifname);
+ return;
+ }
+ if ((statbuf.st_mode & S_IFMT/*0170000*/) != S_IFREG/*0100000*/) {
+ if(quiet)
+ fprintf(stderr, "%s: ", ifname);
+ fprintf(stderr, " -- not a regular file: unchanged");
+ exit_stat = 1;
+ perm_stat = 1;
+ } else if (statbuf.st_nlink > 1) {
+ if(quiet)
+ fprintf(stderr, "%s: ", ifname);
+ fprintf(stderr, " -- has %d other links: unchanged",
+ statbuf.st_nlink - 1);
+ exit_stat = 1;
+ perm_stat = 1;
+ } else if (exit_stat == 2 && (!force)) { /* No compression: remove file.Z */
+ if(!quiet)
+ fprintf(stderr, " -- file unchanged");
+ } else { /* ***** Successful Compression ***** */
+ exit_stat = 0;
+ mode = statbuf.st_mode & 07777;
+ if (chmod(ofname, mode)) /* Copy modes */
+ perror(ofname);
+#ifndef __EMX__
+ chown(ofname, statbuf.st_uid, statbuf.st_gid); /* Copy ownership */
+#endif
+ timep[0] = statbuf.st_atime;
+ timep[1] = statbuf.st_mtime;
+ utime(ofname, timep); /* Update last accessed and modified times */
+#ifdef __EMX__
+ fclose(stdin);
+#endif
+ if (unlink(ifname)) /* Remove input file */
+ perror(ifname);
+ if(!quiet)
+ fprintf(stderr, " -- replaced with %s", ofname);
+ return; /* Successful return */
+ }
+
+ /* Unsuccessful return -- one of the tests failed */
+ if (unlink(ofname))
+ perror(ofname);
+}
+
+onintr ( )
+{
+ if (!precious)
+ unlink ( ofname );
+ exit ( 1 );
+}
+
+oops ( ) /* wild pointer -- assume bad input */
+{
+ if ( do_decomp )
+ fprintf ( stderr, "uncompress: corrupt input\n" );
+ unlink ( ofname );
+ exit ( 1 );
+}
+
+cl_block () /* table clear for block compress */
+{
+ register long int rat;
+
+ checkpoint = in_count + CHECK_GAP;
+#ifdef DEBUG
+ if ( debug ) {
+ fprintf ( stderr, "count: %ld, ratio: ", in_count );
+ prratio ( stderr, in_count, bytes_out );
+ fprintf ( stderr, "\n");
+ }
+#endif /* DEBUG */
+
+ if(in_count > 0x007fffff) { /* shift will overflow */
+ rat = bytes_out >> 8;
+ if(rat == 0) { /* Don't divide by zero */
+ rat = 0x7fffffff;
+ } else {
+ rat = in_count / rat;
+ }
+ } else {
+ rat = (in_count << 8) / bytes_out; /* 8 fractional bits */
+ }
+ if ( rat > ratio ) {
+ ratio = rat;
+ } else {
+ ratio = 0;
+#ifdef DEBUG
+ if(verbose)
+ dump_tab(); /* dump string table */
+#endif
+ cl_hash ( (count_int) hsize );
+ free_ent = FIRST;
+ clear_flg = 1;
+ output ( (code_int) CLEAR );
+#ifdef DEBUG
+ if(debug)
+ fprintf ( stderr, "clear\n" );
+#endif /* DEBUG */
+ }
+}
+
+cl_hash(hsize) /* reset code table */
+ register count_int hsize;
+{
+#ifndef XENIX_16 /* Normal machine */
+ register count_int *htab_p = htab+hsize;
+#else
+ register j;
+ register long k = hsize;
+ register count_int *htab_p;
+#endif
+ register long i;
+ register long m1 = -1;
+
+#ifdef XENIX_16
+ for(j=0; j<=8 && k>=0; j++,k-=8192) {
+ i = 8192;
+ if(k < 8192) {
+ i = k;
+ }
+ htab_p = &(htab[j][i]);
+ i -= 16;
+ if(i > 0) {
+#else
+ i = hsize - 16;
+#endif
+ do { /* might use Sys V memset(3) here */
+ *(htab_p-16) = m1;
+ *(htab_p-15) = m1;
+ *(htab_p-14) = m1;
+ *(htab_p-13) = m1;
+ *(htab_p-12) = m1;
+ *(htab_p-11) = m1;
+ *(htab_p-10) = m1;
+ *(htab_p-9) = m1;
+ *(htab_p-8) = m1;
+ *(htab_p-7) = m1;
+ *(htab_p-6) = m1;
+ *(htab_p-5) = m1;
+ *(htab_p-4) = m1;
+ *(htab_p-3) = m1;
+ *(htab_p-2) = m1;
+ *(htab_p-1) = m1;
+ htab_p -= 16;
+ } while ((i -= 16) >= 0);
+#ifdef XENIX_16
+ }
+ }
+#endif
+ for ( i += 16; i > 0; i-- )
+ *--htab_p = m1;
+}
+
+prratio(stream, num, den)
+FILE *stream;
+long int num, den;
+{
+ register int q; /* Doesn't need to be long */
+
+ if(num > 214748L) { /* 2147483647/10000 */
+ q = num / (den / 10000L);
+ } else {
+ q = 10000L * num / den; /* Long calculations, though */
+ }
+ if (q < 0) {
+ putc('-', stream);
+ q = -q;
+ }
+ fprintf(stream, "%d.%02d%%", q / 100, q % 100);
+}
+
+version()
+{
+ fprintf(stderr, "%s, Berkeley 5.10 10/15/88\n", rcs_ident);
+ fprintf(stderr, "Options: ");
+#ifdef vax
+ fprintf(stderr, "vax, ");
+#endif
+#ifdef NO_UCHAR
+ fprintf(stderr, "NO_UCHAR, ");
+#endif
+#ifdef SIGNED_COMPARE_SLOW
+ fprintf(stderr, "SIGNED_COMPARE_SLOW, ");
+#endif
+#ifdef XENIX_16
+ fprintf(stderr, "XENIX_16, ");
+#endif
+#ifdef COMPATIBLE
+ fprintf(stderr, "COMPATIBLE, ");
+#endif
+#ifdef DEBUG
+ fprintf(stderr, "DEBUG, ");
+#endif
+#ifdef BSD4_2
+ fprintf(stderr, "BSD4_2, ");
+#endif
+ fprintf(stderr, "BITS = %d\n", BITS);
+}
diff --git a/xc/util/compress/usermem.sh b/xc/util/compress/usermem.sh
new file mode 100644
index 000000000..e6e976325
--- /dev/null
+++ b/xc/util/compress/usermem.sh
@@ -0,0 +1,94 @@
+#!/bin/sh -
+#
+# Copyright (c) 1985 The Regents of the University of California.
+# All rights reserved.
+#
+# This code is derived from software contributed to Berkeley by
+# James A. Woods, derived from original work by Spencer Thomas
+# and Joseph Orost.
+#
+# Redistribution and use in source and binary forms are permitted
+# provided that the above copyright notice and this paragraph are
+# duplicated in all such forms and that any documentation,
+# advertising materials, and other materials related to such
+# distribution and use acknowledge that the software was developed
+# by the University of California, Berkeley. The name of the
+# University may not be used to endorse or promote products derived
+# from this software without specific prior written permission.
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+#
+# @(#)usermem.sh 5.5 (Berkeley) 10/15/88
+#
+: This shell script snoops around to find the maximum amount of available
+: user memory. These variables need to be set only if there is no
+: /usr/adm/messages. KMEM, UNIX, and CLICKSIZE can be set on the command
+: line, if desired, e.g. UNIX=/unix
+KMEM=/dev/kmem # User needs read access to KMEM
+UNIX=
+# VAX CLICKSIZE=512, UNIX=/vmunix
+# PDP-11 CLICKSIZE=64, UNIX=/unix
+# CADLINC 68000 CLICKSIZE=4096, UNIX=/unix
+# Perkin-Elmer 3205 CLICKSIZE=4096, UNIX=/edition7
+# Perkin-Elmer all others, CLICKSIZE=2048, UNIX=/edition7
+CLICKSIZE=512
+eval $*
+
+if test -n "$UNIX"
+then
+ : User must have specified it already.
+elif test -r /vmunix
+then
+ UNIX=/vmunix
+ CLICKSIZE=512 # Probably VAX
+elif test -r /edition7
+then
+ UNIX=/edition7
+ CLICKSIZE=2048 # Perkin-Elmer: change to 4096 on a 3205
+elif test -r /unix
+then
+ UNIX=/unix # Could be anything
+fi
+
+SIZE=0
+# messages: probably the most transportable
+if test -r /usr/adm/messages -a -s /usr/adm/messages
+then
+ SIZE=`grep avail /usr/adm/messages | sed -n '$s/.*[ ]//p'`
+fi
+
+if test 0$SIZE -le 0 # no SIZE in /usr/adm/messages
+then
+ if test -r $KMEM # Readable KMEM
+ then
+ if test -n "$UNIX"
+ then
+ SIZE=`echo maxmem/D | adb $UNIX $KMEM | sed -n '$s/.*[ ]//p'`
+ if test 0$SIZE -le 0
+ then
+ SIZE=`echo physmem/D | adb $UNIX $KMEM | sed -n '$s/.*[ ]//p'`
+ fi
+ SIZE=`expr 0$SIZE '*' $CLICKSIZE`
+ fi
+ fi
+fi
+
+case $UNIX in
+ /vmunix) # Assume 4.2bsd: check for resource limits
+ MAXSIZE=`csh -c limit | awk 'BEGIN { MAXSIZE = 1000000 }
+/datasize|memoryuse/ && NF == 3 { if ($2 < MAXSIZE) MAXSIZE = $2 }
+END { print MAXSIZE * 1000 }'`
+ if test $MAXSIZE -lt $SIZE
+ then
+ SIZE=$MAXSIZE
+ fi
+ ;;
+esac
+
+if test 0$SIZE -le 0
+then
+ echo 0;exit 1
+else
+ echo $SIZE
+fi
diff --git a/xc/util/memleak/Imakefile b/xc/util/memleak/Imakefile
new file mode 100644
index 000000000..cfab3781b
--- /dev/null
+++ b/xc/util/memleak/Imakefile
@@ -0,0 +1,71 @@
+XCOMM $XConsortium: Imakefile /main/9 1996/09/28 17:19:05 rws $
+XCOMM $XFree86: xc/util/memleak/Imakefile,v 3.2 1996/12/23 07:19:34 dawes Exp $
+#define DoNormalLib YES
+#define DoSharedLib NO
+#define DoDebugLib NO
+#define DoProfileLib NO
+#define IncSubdir X11
+#include <Library.tmpl>
+
+#ifdef MipsArchitecture
+#define TopOfStack 0x7fffbbb0
+#define BottomOfData 0x10000000
+#define HasGetReturnAddress YES
+GRA_OBJS = getretmips.o mipsstack.o
+GRA_SRCS = getretmips.c
+#endif
+
+#ifdef SparcArchitecture
+#define HasGetReturnAddress YES
+#define BottomOfData \&environ
+#ifdef SystemV4
+GRA_OBJS = getretspar.o sparcsolstack.o
+#define TopOfStack 0xeffffc70
+#else
+LOCAL_DEFS = -Datexit=on_exit
+GRA_OBJS = getretspar.o sparcstack.o
+#define TopOfStack 0xf7fffbdc
+#endif
+GRA_SRCS = getretspar.c
+#endif
+
+#ifdef i386BsdArchitecture
+#define HasGetReturnAddress YES
+#define TopOfStack 'GC_get_stack_base()'
+#define BottomOfData \&etext
+GRA_OBJS = getreti386.o stackbottom.o
+GRA_SRCS = getreti386.c stackbottom.c
+#endif
+
+#ifndef HasGetReturnAddress
+#define HasGetReturnAddress NO
+#endif
+
+#if HasGetReturnAddress
+ GRA_DEFS = -DHAS_GET_RETURN_ADDRESS
+#endif
+
+DEFINES = -DTOP_OF_STACK=TopOfStack -DBOTTOM_OF_DATA=BottomOfData\
+ $(GRA_DEFS) $(LOCAL_DEFS)
+
+CDEBUGFLAGS = DebuggableCDebugFlags
+
+SRCS = fmalloc.c $(GRA_SRCS)
+
+OBJS = fmalloc.o $(GRA_OBJS)
+
+LibraryObjectRule()
+
+#if DoNormalLib
+NormalLibraryTarget(memleak,$(OBJS))
+InstallLibrary(memleak,$(USRLIBDIR))
+#endif
+
+InstallNamedProg(find-rtns.sh,find-routines,$(BINDIR))
+
+LintLibraryTarget(memleak,$(SRCS))
+InstallLintLibrary(memleak,$(LINTLIBDIR))
+
+DependTarget()
+
+NormalLintTarget($(SRCS))
diff --git a/xc/util/memleak/README b/xc/util/memleak/README
new file mode 100644
index 000000000..70bbaae6b
--- /dev/null
+++ b/xc/util/memleak/README
@@ -0,0 +1,70 @@
+.\" $XConsortium: README,v 1.3 92/05/15 14:04:04 keith Exp $
+
+This library replaces the C library allocator;
+providing malloc, free, realloc and calloc (sorry, no valloc)
+
+In doing so, it provides extensive memory bug checking, locating:
+
+ Lost memory; memory which has not been freed and which has no
+ references
+
+ In use free memory; memorhy which has been freed and still has
+ references to it.
+
+ Stores to freed memory
+
+ free/realloc with invalid pointers -- if you pass in a pointer to
+ the middle of an allocated block, it will even tell you which one
+
+For each of these errors, a report entry is generated which includes
+the stack backtrace of either the allocation or free (which ever occured
+last) along with the current stack, when relevant.
+
+Unreferenced allocated memory, stores to freed memory and referenced freed
+memory are only caught when CheckMemory is called. It is automatically
+called each time 1m of data has been freed, and is called when the program
+exits (by registering with atexit(3)/on_exit(3)). You can call it whenever
+you want.
+
+Both the X server and font servers call CheckMemory after each reset when
+their respective os/utils.c are compiled -DMEMBUG.
+
+There are a few global variables you can set with the debugger to
+help isolate problems:
+
+ FindLeakWarnMiddlePointers
+ Normally, memleak ignores pointers to the middle of
+ freed memory. These are frequently simply random data
+ which happens to look like a pointer. Turning this
+ on will generate additional messages.
+ FindLeakAllocBreakpoint
+ At each allocation, memleak increments a serial number
+ and stores it in the allocation header. By rerunning
+ the program, you can stop when that piece of memory
+ is going to be allocated. Store the serial number
+ in this global variable and put a debugger breakpoint inside
+ AddActiveBlock at the indicated line.
+ FindLeakFreeBreakpoint
+ Similarly for freeing memory.
+ FindLeakTime
+ The current serial number
+ FindLeakCheckAlways
+ When set, memleak checks the entire memory system after
+ each allocation or free. This is very expensive, but
+ may catch errors not otherwise found until too late.
+
+To include this in your application, simply place libmemleak.a before the
+end of the link line; it will then override the C library allocator.
+
+To port this system to a new machine, you must provide two values, one
+indicating the lowest data address in a program and one indicating the
+highest stack address. In addition, to get return stack traces (which are
+almost essential for debugging), you must provide the function
+getReturnStack. Samples for MIPS and SPARC are included already.
+
+The output from the leak tracer includes only PC values in the stack
+traces. To convert these into useful values, run the output of
+the leak tracer through the find-routines script; after making sure you have
+built the modified version of gdb-4.4 on your machine.
+
+-keith
diff --git a/xc/util/memleak/find-rtns.sh b/xc/util/memleak/find-rtns.sh
new file mode 100755
index 000000000..1d5ee62ee
--- /dev/null
+++ b/xc/util/memleak/find-rtns.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# $TOG: find-rtns.sh /main/2 1998/02/09 11:39:44 kaleb $
+#
+# find-routines - convert leak tracer stack traces into file/lineno traces
+# using a modified version of gdb-4.4
+#
+# Usage: find-routines <program-name> {leak-tracing-output-files}
+#
+TMP1=find-routine.tmp1
+TMP=find-routine.tmp
+trap "rm -f $TMP $TMP1" 0
+OBJ=$1
+shift
+grep 'return stack:' $* |
+ tr ' ' '\012' |
+ grep 0x | sort -u | sed 's;^;x/i ;' |
+ gdb $OBJ | grep '>:' |
+ sed 's/>.*$/>/' | sed 's/(gdb) //' > $TMP1
+
+awk '/^"/ { printf("s;%s;%s line %s %s;\n", $4, $1, $3, $5) }
+/^0/ { printf("s;%s;%s %s;\n", $1, $2, $1);}' $TMP1 > $TMP
+
+awk '/return stack/ { printf ("return stack\n");
+ for (i = 3; i <= NF; i++)
+ printf ("\troutine %s\n", $i); }
+ /^[A-Z]/ { print }' $* |
+ sed -f $TMP
diff --git a/xc/util/memleak/fmalloc.c b/xc/util/memleak/fmalloc.c
new file mode 100644
index 000000000..abad3452a
--- /dev/null
+++ b/xc/util/memleak/fmalloc.c
@@ -0,0 +1,1135 @@
+/*
+ * $TOG: fmalloc.c /main/8 1998/02/09 11:39:50 kaleb $
+ *
+Copyright 1992, 1998 The Open Group
+
+All Rights Reserved.
+
+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
+ */
+
+/* $XFree86: xc/util/memleak/fmalloc.c,v 3.4 1998/10/04 08:19:36 dawes Exp $ */
+
+
+/*
+ * Leak tracing allocator -- using C lib malloc/free, tracks
+ * all allocations. When requested, performs a garbage-collection
+ * style mark/sweep on static memory (data and stack), locating
+ * objects referenced therein. Recursively marks objects.
+ * Sweeps through all allocations, warning of possible violations
+ * (unreferenced allocated, referenced freed etc).
+ */
+
+#include <stdio.h>
+
+extern char **environ;
+extern etext;
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifdef X_NOT_POSIX
+#define NO_ATEXIT
+#endif
+
+typedef unsigned long mem;
+
+#ifdef HAS_GET_RETURN_ADDRESS
+#define MAX_RETURN_STACK 16
+#endif
+
+#define MAX_FREED_MEMORY (1*1024*1024)
+
+#define ACTIVE_HEAD_MAGIC 0xff1111ff
+#define ACTIVE_TAIL_MAGIC 0xee2222ee
+#define ACTIVE_DATA_MAGIC 0xdd3333dd
+#define FREED_HEAD_MAGIC 0xcc4444cc
+#define FREED_TAIL_MAGIC 0xbb5555bb
+#define FREED_DATA_MAGIC 0xcc6666cc
+
+/*
+ * the marked fields in each head have two bits - one indicating
+ * references to the head of the block, and one indicating references
+ * to the middle of the block
+ */
+#define UNREFERENCED 0
+#define REFERENCED_HEAD 1
+#define REFERENCED_MIDDLE 2
+
+typedef struct _head {
+ struct _head *left, *right;
+ struct _head *next;
+ int balance;
+#ifdef HAS_GET_RETURN_ADDRESS
+ mem returnStack[MAX_RETURN_STACK];
+#endif
+ mem *from;
+ unsigned long allocTime;
+ unsigned long freeTime;
+ int size;
+ int desiredsize;
+ int actualSize;
+ int marked;
+ int headMagic;
+} HeadRec, *HeadPtr;
+
+typedef struct _tail {
+ int tailMagic;
+#if defined(__alpha) || defined(__alpha__)
+ int tailPad;
+#endif
+} TailRec, *TailPtr;
+
+#define Header(p) ((HeadPtr) (((char *) (p)) - sizeof (HeadRec)))
+#define DataForHead(h) ((mem *) ((h) + 1))
+#define Tailer(p) ((TailPtr) (((char *) (p)) + Header(p)->size))
+#define TailForHead(h) (Tailer(DataForHead(h)))
+#define RoundSize (sizeof (mem))
+#define RoundUp(s) (((s) + RoundSize - 1) & ~(RoundSize - 1))
+#define TotalSize(s) ((s) + sizeof (HeadRec) + sizeof (TailRec))
+#define CheckInit() if (!endOfStaticMemory) endOfStaticMemory = sbrk(0)
+#define BlockContains(h,p) (DataForHead(h) <= (p) && (p) < (mem *) TailForHead(h))
+
+typedef HeadRec tree;
+typedef mem *tree_data;
+
+#define COMPARE_ADDR(a,b,op) (((unsigned) (a)) op ((unsigned) (b)))
+#define COMPARE(a,b,op,s) ((!s) ? \
+ COMPARE_ADDR(a,b,op) :\
+ (((a)->actualSize op (b)->actualSize) || \
+ ((a)->actualSize == (b)->actualSize && \
+ COMPARE_ADDR(a,b,op))))
+
+
+#define LESS_THAN(a,b,s) COMPARE(a,b,<,s)
+#define GREATER_THAN(a,b,s) COMPARE(a,b,>,s)
+
+#define SEARCH(top,result,p) for (result = top; result;) {\
+ if ((mem *) (p) < DataForHead(result)) \
+ result = result->left; \
+ else if ((mem *) TailForHead(result) < (mem *) (p)) \
+ result = result->right; \
+ else \
+ break; \
+}
+
+
+static tree *activeMemory, *freedMemory, *deadMemory;
+
+static mem *endOfStaticMemory;
+static mem *highestAllocatedMemory;
+
+static int freedMemoryTotal;
+static int freedMemoryCount;
+static int activeMemoryTotal;
+static int activeMemoryCount;
+static int deadMemoryTotal;
+
+int FindLeakWarnMiddlePointers = 0;
+unsigned long FindLeakAllocBreakpoint = ~0;
+unsigned long FindLeakFreeBreakpoint = ~0;
+unsigned long FindLeakTime;
+int FindLeakCheckAlways = 0;
+
+static void MarkActiveBlock ();
+static int tree_insert (), tree_delete ();
+void CheckMemory ();
+char *malloc (), *realloc (), *calloc ();
+void free ();
+extern char *sbrk ();
+
+#ifdef HAS_GET_RETURN_ADDRESS
+static void
+PrintReturnStack (m, ra)
+ char *m;
+ mem *ra;
+{
+ int i;
+
+ fprintf (stderr, " %s:", m);
+ for (i = 0; i < MAX_RETURN_STACK && ra[i]; i++)
+ fprintf (stderr, " 0x%lx", ra[i]);
+ fprintf (stderr, "\n");
+}
+#endif
+
+static void
+MemError (s, h, ourRet)
+ char *s;
+ HeadPtr h;
+ int ourRet;
+{
+ mem *ra;
+ int i;
+
+ if (h)
+ {
+ fprintf (stderr, "%s 0x%08lx (size %d) (from 0x%lx)\n",
+ s, DataForHead(h), h->desiredsize, h->from);
+#ifdef HAS_GET_RETURN_ADDRESS
+ PrintReturnStack ("Saved return stack", h->returnStack);
+#endif
+ }
+ else
+ fprintf (stderr, "%s\n", s);
+#ifdef HAS_GET_RETURN_ADDRESS
+ if (ourRet)
+ {
+ mem returnStack[MAX_RETURN_STACK];
+
+ getStackTrace (returnStack, MAX_RETURN_STACK);
+ PrintReturnStack ("Current return stack", returnStack);
+ }
+#endif
+}
+
+static void
+MarkMemoryRegion (low, high)
+ mem *low, *high;
+{
+ mem **start = (mem **) low, **end = (mem **) high;
+ mem *p;
+
+ while (start < end) {
+ p = *start;
+ if (endOfStaticMemory <= p && p < highestAllocatedMemory)
+ MarkActiveBlock (p, (mem *) start);
+ start++;
+ }
+}
+
+static void
+MarkActiveBlock (p, from)
+ mem *p, *from;
+{
+ HeadPtr h;
+ int marked;
+ int oldMarked;
+
+ SEARCH(activeMemory, h, p)
+ if (h) {
+ marked = REFERENCED_HEAD;
+ if (p != DataForHead(h))
+ marked = REFERENCED_MIDDLE;
+ oldMarked = h->marked;
+ if (!(oldMarked & marked))
+ {
+ h->marked |= marked;
+ h->from = from;
+ if (!oldMarked)
+ MarkMemoryRegion (DataForHead(h), (mem *) TailForHead(h));
+ }
+ return;
+ }
+ SEARCH(freedMemory, h, p)
+ if (h)
+ {
+ marked = REFERENCED_HEAD;
+ if (p != DataForHead(h))
+ marked = REFERENCED_MIDDLE;
+ if (!(h->marked & marked))
+ {
+ h->marked |= marked;
+ h->from = from;
+ }
+ return;
+ }
+}
+
+static void
+ClearTree (t)
+ tree *t;
+{
+ if (!t)
+ return;
+ ClearTree (t->left);
+ t->marked = 0;
+ t->from = 0;
+ ClearTree (t->right);
+}
+
+static void
+SweepActiveTree (t)
+ tree *t;
+{
+ if (!t)
+ return;
+ SweepActiveTree (t->left);
+ if (!t->marked)
+ MemError ("Unreferenced allocated", t, FALSE);
+ else if (!(t->marked & REFERENCED_HEAD))
+ MemError ("Referenced allocated middle", t, FALSE);
+ SweepActiveTree (t->right);
+}
+
+/*
+ * run a thread through the tree at the same time
+ * - the thread runs
+ *
+ * root -> left_child ... -> right_child ... -> null
+ */
+
+static tree *
+SweepFreedTree (t)
+ tree *t;
+{
+ tree *left_last, *right_last;
+
+ if (!t)
+ return 0;
+
+ left_last = SweepFreedTree (t->left);
+ if (t->marked)
+ {
+ if (t->marked & REFERENCED_HEAD)
+ MemError ("Referenced freed base", t, FALSE);
+ else if (FindLeakWarnMiddlePointers)
+ MemError ("Referenced freed middle", t, FALSE);
+ }
+ right_last = SweepFreedTree (t->right);
+
+ if (t->left)
+ t->next = t->left;
+ else
+ t->next = t->right;
+ if (left_last)
+ left_last->next = t->right;
+ if (!right_last)
+ right_last = left_last;
+ if (!right_last)
+ right_last = t;
+ return right_last;
+}
+
+static void
+SweepFreedMemory ()
+{
+ tree *t, *n;
+ int count, shouldCount;
+
+ (void) SweepFreedTree (freedMemory);
+ count = 0;
+ shouldCount = freedMemoryCount;
+ for (t = freedMemory; t; t = n) {
+ n = t->next;
+ count++;
+ if (!t->marked)
+ {
+ (void) tree_delete (&freedMemory, t, FALSE);
+ freedMemoryTotal -= t->desiredsize;
+ freedMemoryCount--;
+ tree_insert (&deadMemory, t, TRUE);
+ }
+ }
+ if (count != shouldCount)
+ abort ();
+}
+
+static void
+ValidateTree (head, headMagic, tailMagic, bodyMagic, mesg)
+ tree *head;
+ mem headMagic, tailMagic, bodyMagic;
+ char *mesg;
+{
+ TailPtr tail;
+ mem *p;
+ int i;
+
+ if (!head)
+ return;
+ ValidateTree (head->left, headMagic, tailMagic, bodyMagic, mesg);
+ tail = TailForHead (head);
+ if (head->headMagic != headMagic)
+ MemError (mesg, head, FALSE);
+ if (tail->tailMagic != tailMagic)
+ MemError (mesg, head, FALSE);
+ if (bodyMagic) {
+ i = head->size / sizeof (mem);
+ p = DataForHead(head);
+ while (i--) {
+ if (*p++ != bodyMagic)
+ MemError (mesg, head, FALSE);
+ }
+ }
+ ValidateTree (head->right, headMagic, tailMagic, bodyMagic, mesg);
+}
+
+static void
+ValidateActiveMemory ()
+{
+ ValidateTree (activeMemory, ACTIVE_HEAD_MAGIC, ACTIVE_TAIL_MAGIC,
+ 0, "Store outside of active memory");
+}
+
+static void
+ValidateFreedMemory ()
+{
+ ValidateTree (freedMemory, FREED_HEAD_MAGIC, FREED_TAIL_MAGIC,
+ FREED_DATA_MAGIC, "Store into freed memory");
+}
+
+static void
+AddActiveBlock (h)
+ HeadPtr h;
+{
+ TailPtr t = TailForHead(h);
+ mem *p;
+ int i;
+
+ tree_insert (&activeMemory, h, FALSE);
+ if ((mem *) t > highestAllocatedMemory)
+ highestAllocatedMemory = (mem *) t;
+
+ /*
+ * Breakpoint position - assign FindLeakAllocBreakpoint with
+ * debugger and set a breakpoint in the conditional clause below
+ */
+ if (FindLeakTime == FindLeakAllocBreakpoint)
+ h->headMagic = ACTIVE_HEAD_MAGIC; /* set breakpoint here */
+
+ h->allocTime = FindLeakTime++;
+
+ h->headMagic = ACTIVE_HEAD_MAGIC;
+ t->tailMagic = ACTIVE_TAIL_MAGIC;
+ i = h->size / sizeof (mem);
+ p = DataForHead(h);
+ while (i--)
+ *p++ = ACTIVE_DATA_MAGIC;
+ activeMemoryTotal += h->desiredsize;
+ activeMemoryCount++;
+}
+
+static void
+RemoveActiveBlock (h)
+ HeadPtr h;
+{
+ activeMemoryTotal -= h->desiredsize;
+ activeMemoryCount--;
+ tree_delete (&activeMemory, h, FALSE);
+}
+
+static void
+AddFreedBlock (h)
+ HeadPtr h;
+{
+ TailPtr t = TailForHead(h);
+ int i;
+ mem *p;
+
+ tree_insert (&freedMemory, h, FALSE);
+
+ /*
+ * Breakpoint position - assign FindLeakFreeBreakpoint with
+ * debugger and set a breakpoint in the conditional clause below
+ */
+ if (FindLeakTime == FindLeakFreeBreakpoint)
+ h->headMagic = FREED_HEAD_MAGIC; /* set breakpoint here */
+
+ h->freeTime = FindLeakTime++;
+
+ h->headMagic = FREED_HEAD_MAGIC;
+ t->tailMagic = FREED_TAIL_MAGIC;
+ i = h->size / sizeof (mem);
+ p = DataForHead(h);
+ while (i--)
+ *p++ = FREED_DATA_MAGIC;
+ freedMemoryTotal += h->desiredsize;
+ freedMemoryCount++;
+ /* GC if we've got piles of unused memory */
+ if (freedMemoryTotal - deadMemoryTotal >= MAX_FREED_MEMORY)
+ CheckMemory ();
+}
+
+/*
+ * Entry points:
+ *
+ * CheckMemory () -- Verifies heap
+ * malloc (size) -- Allocates memory
+ * free (old) -- Deallocates memory
+ * realloc (old, size) -- Allocate, copy, free
+ * calloc (num, size_per) -- Allocate and zero
+ */
+
+void
+CheckMemory ()
+{
+ mem foo;
+
+ fprintf (stderr, "\nCheckMemory\n");
+ fprintf (stderr, "%d bytes active memory in %d allocations\n",
+ activeMemoryTotal, activeMemoryCount);
+ fprintf (stderr, "%d bytes freed memory held from %d allocations\n",
+ freedMemoryTotal, freedMemoryCount);
+ ValidateActiveMemory ();
+ ValidateFreedMemory ();
+ ClearTree (activeMemory);
+ ClearTree (freedMemory);
+ MarkMemoryRegion (BOTTOM_OF_DATA, endOfStaticMemory);
+ MarkMemoryRegion (&foo, TOP_OF_STACK);
+ SweepActiveTree (activeMemory);
+ SweepFreedMemory ();
+ fprintf (stderr, "%d bytes freed memory still held from %d allocations\n",
+ freedMemoryTotal, freedMemoryCount);
+ deadMemoryTotal = freedMemoryTotal;
+ fprintf (stderr, "CheckMemory done\n");
+}
+
+/*
+ * Allocator interface -- malloc and free (others in separate files)
+ */
+
+#define CORE_CHUNK 16384
+
+static char *core;
+static unsigned core_left;
+static unsigned total_core_used;
+
+static char *
+morecore (size)
+ unsigned size;
+{
+ unsigned alloc_size;
+ char *alloc, *newcore;
+
+ if (core_left < size)
+ {
+ alloc_size = (size + CORE_CHUNK - 1) & ~(CORE_CHUNK-1);
+ newcore = sbrk (alloc_size);
+ if (((int) newcore) == -1)
+ return 0;
+ core = newcore;
+ core_left = alloc_size;
+ total_core_used += alloc_size;
+ }
+ alloc = core;
+ core += size;
+ core_left -= size;
+ return alloc;
+}
+
+char *
+malloc (desiredsize)
+ unsigned desiredsize;
+{
+ char *ret;
+ unsigned size;
+ unsigned totalsize;
+ HeadPtr h;
+
+ if (!endOfStaticMemory)
+ endOfStaticMemory = (mem *) sbrk(0);
+ if (FindLeakCheckAlways)
+ CheckMemory ();
+ size = RoundUp(desiredsize);
+ totalsize = TotalSize (size);
+
+ h = deadMemory;
+ while (h)
+ {
+ if (h->actualSize == size)
+ break;
+ else if (h->actualSize < size)
+ h = h->right;
+ else {
+ if (!h->left)
+ break;
+ h = h->left;
+ }
+ }
+ if (h)
+ {
+ tree_delete (&deadMemory, h, TRUE);
+ }
+ else
+ {
+ h = (HeadPtr) morecore (totalsize);
+ if (!h)
+ return NULL;
+ h->actualSize = size;
+ }
+ h->desiredsize = desiredsize;
+ h->size = size;
+#ifdef HAS_GET_RETURN_ADDRESS
+ getStackTrace (h->returnStack, MAX_RETURN_STACK);
+#endif
+ AddActiveBlock (h);
+ return (char *) DataForHead(h);
+}
+
+void
+free (p)
+ char *p;
+{
+ HeadPtr h;
+ static int beenHere;
+
+#ifndef NO_ATEXIT
+ /* do it at free instead of malloc to avoid recursion? */
+ if (!beenHere)
+ {
+ beenHere = TRUE;
+ atexit (CheckMemory);
+ }
+#endif
+ if (!p)
+ {
+ MemError ("Freeing NULL", (HeadPtr) 0, TRUE);
+ return;
+ }
+ SEARCH (activeMemory, h, p);
+ if (!h)
+ {
+ SEARCH(freedMemory, h, p);
+ if (h)
+ MemError ("Freeing something twice", h, TRUE);
+ else
+ MemError ("Freeing something never allocated", h, TRUE);
+ return;
+ }
+ if (DataForHead(h) != (mem *) p)
+ {
+ MemError ("Freeing pointer to middle of allocated block", h, TRUE);
+ return;
+ }
+ if (h->headMagic != ACTIVE_HEAD_MAGIC ||
+ TailForHead(h)->tailMagic != ACTIVE_TAIL_MAGIC)
+ MemError ("Freeing corrupted data", h, TRUE);
+ RemoveActiveBlock (h);
+#ifdef HAS_GET_RETURN_ADDRESS
+ getStackTrace (h->returnStack, MAX_RETURN_STACK);
+#endif
+ AddFreedBlock (h);
+ if (FindLeakCheckAlways)
+ CheckMemory ();
+}
+
+char *
+realloc (old, desiredsize)
+ char *old;
+ unsigned desiredsize;
+{
+ char *new;
+ HeadPtr h, fh;
+ int copysize;
+
+ new = malloc (desiredsize);
+ if (!new)
+ return NULL;
+ SEARCH(activeMemory, h, old);
+ if (!h)
+ {
+ SEARCH(freedMemory, fh, old);
+ if (fh)
+ MemError ("Reallocing from freed data", fh, TRUE);
+ else
+ MemError ("Reallocing from something not allocated", h, TRUE);
+ }
+ else
+ {
+ if (DataForHead(h) != (mem *) old)
+ {
+ MemError ("Reallocing from pointer to middle of allocated block", h, TRUE);
+ }
+ else
+ {
+ if (h->headMagic != ACTIVE_HEAD_MAGIC ||
+ TailForHead(h)->tailMagic != ACTIVE_TAIL_MAGIC)
+ MemError ("Reallocing corrupted data", h, TRUE);
+ copysize = desiredsize;
+ if (h->desiredsize < desiredsize)
+ copysize = h->desiredsize;
+#ifdef SVR4
+ memmove (new, old, copysize);
+#else
+ bcopy (old, new, copysize);
+#endif
+ RemoveActiveBlock (h);
+#ifdef HAS_GET_RETURN_ADDRESS
+ getStackTrace (h->returnStack, MAX_RETURN_STACK);
+#endif
+ AddFreedBlock (h);
+ }
+ }
+ return new;
+}
+
+char *
+calloc (num, size)
+ unsigned num, size;
+{
+ char *ret;
+
+ size *= num;
+ ret = malloc (size);
+ if (!ret)
+ return NULL;
+#ifdef SVR4
+ memset (ret, 0, size);
+#else
+ bzero (ret, size);
+#endif
+ return ret;
+}
+
+/*
+ * Semi-Balanced trees (avl). This only contains two
+ * routines - insert and delete. Searching is
+ * reserved for the client to write.
+ */
+
+static rebalance_right (), rebalance_left ();
+
+/*
+ * insert a new node
+ *
+ * this routine returns non-zero if the tree has grown
+ * taller
+ */
+
+static int
+tree_insert (treep, new, bySize)
+tree **treep;
+tree *new;
+int bySize;
+{
+ if (!(*treep)) {
+ (*treep) = new;
+ (*treep)->left = 0;
+ (*treep)->right = 0;
+ (*treep)->balance = 0;
+ return 1;
+ } else {
+ if (LESS_THAN (*treep, new, bySize)) {
+ if (tree_insert (&((*treep)->right), new, bySize))
+ switch (++(*treep)->balance) {
+ case 0:
+ return 0;
+ case 1:
+ return 1;
+ case 2:
+ (void) rebalance_right (treep);
+ }
+ return 0;
+ } else if (GREATER_THAN(*treep, new, bySize)) {
+ if (tree_insert (&((*treep)->left), new, bySize))
+ switch (--(*treep)->balance) {
+ case 0:
+ return 0;
+ case -1:
+ return 1;
+ case -2:
+ (void) rebalance_left (treep);
+ }
+ return 0;
+ } else {
+ return 0;
+ }
+ }
+ /*NOTREACHED*/
+}
+
+/*
+ * delete a node from a tree
+ *
+ * this routine return non-zero if the tree has been shortened
+ */
+
+static int
+tree_delete (treep, old, bySize)
+tree **treep;
+tree *old;
+int bySize;
+{
+ tree *to_be_deleted;
+ tree *replacement;
+ tree *replacement_parent;
+ int replacement_direction;
+ int delete_direction;
+ tree *swap_temp;
+ int balance_temp;
+
+ if (!*treep)
+ /* node not found */
+ return 0;
+ if (LESS_THAN(*treep, old, bySize)) {
+ if (tree_delete (&(*treep)->right, old, bySize))
+ /*
+ * check the balance factors
+ * Note that the conditions are
+ * inverted from the insertion case
+ */
+ switch (--(*treep)->balance) {
+ case 0:
+ return 1;
+ case -1:
+ return 0;
+ case -2:
+ return rebalance_left (treep);
+ }
+ return 0;
+ } else if (GREATER_THAN(*treep, old, bySize)) {
+ if (tree_delete (&(*treep)->left, old, bySize))
+ switch (++(*treep)->balance) {
+ case 0:
+ return 1;
+ case 1:
+ return 0;
+ case 2:
+ return rebalance_right (treep);
+ }
+ return 0;
+ } else {
+ to_be_deleted = *treep;
+ /*
+ * find an empty down pointer (if any)
+ * and rehook the tree
+ */
+ if (!to_be_deleted->right) {
+ (*treep) = to_be_deleted->left;
+ return 1;
+ } else if (!to_be_deleted->left) {
+ (*treep) = to_be_deleted->right;
+ return 1;
+ } else {
+ /*
+ * if both down pointers are full, then
+ * move a node from the bottom of the tree up here.
+ *
+ * This builds an incorrect tree -- the replacement
+ * node and the to_be_deleted node will not
+ * be in correct order. This doesn't matter as
+ * the to_be_deleted node will obviously not leave
+ * this routine alive.
+ */
+ /*
+ * if the tree is left heavy, then go left
+ * else go right
+ */
+ replacement_parent = to_be_deleted;
+ if (to_be_deleted->balance == -1) {
+ delete_direction = -1;
+ replacement_direction = -1;
+ replacement = to_be_deleted->left;
+ while (replacement->right) {
+ replacement_parent = replacement;
+ replacement_direction = 1;
+ replacement = replacement->right;
+ }
+ } else {
+ delete_direction = 1;
+ replacement_direction = 1;
+ replacement = to_be_deleted->right;
+ while (replacement->left) {
+ replacement_parent = replacement;
+ replacement_direction = -1;
+ replacement = replacement->left;
+ }
+ }
+ /*
+ * swap the replacement node into
+ * the tree where the node is to be removed
+ *
+ * this would be faster if only the data
+ * element was swapped -- but that
+ * won't work for findleak. The alternate
+ * code would be:
+ data_temp = to_be_deleted->data;
+ to _be_deleted->data = replacement->data;
+ replacement->data = data_temp;
+ */
+ swap_temp = to_be_deleted->left;
+ to_be_deleted->left = replacement->left;
+ replacement->left = swap_temp;
+ swap_temp = to_be_deleted->right;
+ to_be_deleted->right = replacement->right;
+ replacement->right = swap_temp;
+ balance_temp = to_be_deleted->balance;
+ to_be_deleted->balance = replacement->balance;
+ replacement->balance = balance_temp;
+ /*
+ * if the replacement node is directly below
+ * the to-be-removed node, hook the to_be_deleted
+ * node below it (instead of below itself!)
+ */
+ if (replacement_parent == to_be_deleted)
+ replacement_parent = replacement;
+ if (replacement_direction == -1)
+ replacement_parent->left = to_be_deleted;
+ else
+ replacement_parent->right = to_be_deleted;
+ (*treep) = replacement;
+ /*
+ * delete the node from the sub-tree
+ */
+ if (delete_direction == -1) {
+ if (tree_delete (&(*treep)->left, old, bySize)) {
+ switch (++(*treep)->balance) {
+ case 2:
+ abort ();
+ case 1:
+ return 0;
+ case 0:
+ return 1;
+ }
+ }
+ return 0;
+ } else {
+ if (tree_delete (&(*treep)->right, old, bySize)) {
+ switch (--(*treep)->balance) {
+ case -2:
+ abort ();
+ case -1:
+ return 0;
+ case 0:
+ return 1;
+ }
+ }
+ return 0;
+ }
+ }
+ }
+ /*NOTREACHED*/
+}
+
+/*
+ * two routines to rebalance the tree.
+ *
+ * rebalance_right -- the right sub-tree is too long
+ * rebalance_left -- the left sub-tree is too long
+ *
+ * These routines are the heart of avl trees, I've tried
+ * to make their operation reasonably clear with comments,
+ * but some study will be necessary to understand the
+ * algorithm.
+ *
+ * these routines return non-zero if the resultant
+ * tree is shorter than the un-balanced version. This
+ * is only of interest to the delete routine as the
+ * balance after insertion can never actually shorten
+ * the tree.
+ */
+
+static
+rebalance_right (treep)
+tree **treep;
+{
+ tree *temp;
+ /*
+ * rebalance the tree
+ */
+ if ((*treep)->right->balance == -1) {
+ /*
+ * double whammy -- the inner sub-sub tree
+ * is longer than the outer sub-sub tree
+ *
+ * this is the "double rotation" from
+ * knuth. Scheme: replace the tree top node
+ * with the inner sub-tree top node and
+ * adjust the maze of pointers and balance
+ * factors accordingly.
+ */
+ temp = (*treep)->right->left;
+ (*treep)->right->left = temp->right;
+ temp->right = (*treep)->right;
+ switch (temp->balance) {
+ case -1:
+ temp->right->balance = 1;
+ (*treep)->balance = 0;
+ break;
+ case 0:
+ temp->right->balance = 0;
+ (*treep)->balance = 0;
+ break;
+ case 1:
+ temp->right->balance = 0;
+ (*treep)->balance = -1;
+ break;
+ }
+ temp->balance = 0;
+ (*treep)->right = temp->left;
+ temp->left = (*treep);
+ (*treep) = temp;
+ return 1;
+ } else {
+ /*
+ * a simple single rotation
+ *
+ * Scheme: replace the tree top node
+ * with the sub-tree top node
+ */
+ temp = (*treep)->right->left;
+ (*treep)->right->left = (*treep);
+ (*treep) = (*treep)->right;
+ (*treep)->left->right = temp;
+ /*
+ * only two possible configurations --
+ * if the right sub-tree was balanced, then
+ * *both* sides of it were longer than the
+ * left side, so the resultant tree will
+ * have a long leg (the left inner leg being
+ * the same length as the right leg)
+ */
+ if ((*treep)->balance == 0) {
+ (*treep)->balance = -1;
+ (*treep)->left->balance = 1;
+ return 0;
+ } else {
+ (*treep)->balance = 0;
+ (*treep)->left->balance = 0;
+ return 1;
+ }
+ }
+}
+
+static
+rebalance_left (treep)
+tree **treep;
+{
+ tree *temp;
+ /*
+ * rebalance the tree
+ */
+ if ((*treep)->left->balance == 1) {
+ /*
+ * double whammy -- the inner sub-sub tree
+ * is longer than the outer sub-sub tree
+ *
+ * this is the "double rotation" from
+ * knuth. Scheme: replace the tree top node
+ * with the inner sub-tree top node and
+ * adjust the maze of pointers and balance
+ * factors accordingly.
+ */
+ temp = (*treep)->left->right;
+ (*treep)->left->right = temp->left;
+ temp->left = (*treep)->left;
+ switch (temp->balance) {
+ case 1:
+ temp->left->balance = -1;
+ (*treep)->balance = 0;
+ break;
+ case 0:
+ temp->left->balance = 0;
+ (*treep)->balance = 0;
+ break;
+ case -1:
+ temp->left->balance = 0;
+ (*treep)->balance = 1;
+ break;
+ }
+ temp->balance = 0;
+ (*treep)->left = temp->right;
+ temp->right = (*treep);
+ (*treep) = temp;
+ return 1;
+ } else {
+ /*
+ * a simple single rotation
+ *
+ * Scheme: replace the tree top node
+ * with the sub-tree top node
+ */
+ temp = (*treep)->left->right;
+ (*treep)->left->right = (*treep);
+ (*treep) = (*treep)->left;
+ (*treep)->right->left = temp;
+ /*
+ * only two possible configurations --
+ * if the left sub-tree was balanced, then
+ * *both* sides of it were longer than the
+ * right side, so the resultant tree will
+ * have a long leg (the right inner leg being
+ * the same length as the left leg)
+ */
+ if ((*treep)->balance == 0) {
+ (*treep)->balance = 1;
+ (*treep)->right->balance = -1;
+ return 0;
+ } else {
+ (*treep)->balance = 0;
+ (*treep)->right->balance = 0;
+ return 1;
+ }
+ }
+}
+
+#ifdef DEBUG
+
+static
+depth (treep)
+tree *treep;
+{
+ int ldepth, rdepth;
+
+ if (!treep)
+ return 0;
+ ldepth = depth (treep->left);
+ rdepth = depth (treep->right);
+ if (ldepth > rdepth)
+ return ldepth + 1;
+ return rdepth + 1;
+}
+
+static tree *
+left_most (treep)
+tree *treep;
+{
+ while (treep && treep->left)
+ treep = treep->left;
+ return treep;
+}
+
+static tree *
+right_most (treep)
+tree *treep;
+{
+ while (treep && treep->right)
+ treep = treep->right;
+ return treep;
+}
+
+tree_verify (treep)
+tree *treep;
+{
+ tree_data left_data, right_data;
+
+ if (!treep)
+ return 1;
+ if (treep->left)
+ left_data = right_most (treep->left)->data;
+ else
+ left_data = treep->data - 1;
+ if (treep->right)
+ right_data = left_most (treep->right)->data;
+ else
+ right_data = treep->data + 1;
+ if (treep->data < left_data || treep->data > right_data) {
+ abort ();
+ return 0;
+ }
+ if (treep->balance != depth (treep->right) - depth (treep->left)) {
+ abort ();
+ return 0;
+ }
+ return tree_verify (treep->left) && tree_verify (treep->right);
+}
+
+#endif
diff --git a/xc/util/memleak/ftest.c b/xc/util/memleak/ftest.c
new file mode 100644
index 000000000..13d3030d8
--- /dev/null
+++ b/xc/util/memleak/ftest.c
@@ -0,0 +1,49 @@
+/*
+ * $TOG: ftest.c /main/5 1998/02/09 11:39:56 kaleb $
+ *
+Copyright 1992, 1998 The Open Group
+
+All Rights Reserved.
+
+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
+ */
+
+static char *foo, *bar, *bletch;
+static char *glorf[100];
+
+extern char *malloc ();
+
+main ()
+{
+ int i;
+
+ foo = malloc (1000);
+ bar = malloc (2000);
+ bletch = malloc (3000);
+ for (i = 0; i < 100; i++)
+ glorf[i] = malloc (i * 200);
+ for (i = 0; i < 100; i++) {
+ free (glorf[i]);
+ glorf[i] = 0;
+ }
+ free (foo);
+ free (bletch);
+ bletch = 0;
+ *foo = 'a';
+ bar = 0;
+ CheckMemory ();
+}
diff --git a/xc/util/memleak/getreti386.c b/xc/util/memleak/getreti386.c
new file mode 100644
index 000000000..77ac82a05
--- /dev/null
+++ b/xc/util/memleak/getreti386.c
@@ -0,0 +1,36 @@
+/*
+ * some bits copied from mprof by Ben Zorn
+ *
+ * Copyright (c) 1995 Jeffrey Hsu
+ */
+
+/* $XFree86: xc/util/memleak/getreti386.c,v 3.2 1996/10/16 14:46:28 dawes Exp $ */
+
+#define get_current_fp(first_local) ((unsigned)&(first_local) + 4)
+#define prev_fp_from_fp(fp) *((unsigned *) fp)
+#define ret_addr_from_fp(fp) *((unsigned *) (fp+4))
+
+#ifdef __FreeBSD__
+#define CRT0_ADDRESS 0x10d3
+#endif
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+#define CRT0_ADDRESS 0x109a
+#endif
+
+void
+getStackTrace(unsigned long *results, int max)
+{
+
+ int first_local;
+ unsigned long fp, ret_addr;
+
+ fp = get_current_fp(first_local);
+ ret_addr = ret_addr_from_fp(fp);
+
+ while (ret_addr > CRT0_ADDRESS && max--) {
+ *results++ = ret_addr;
+ fp = prev_fp_from_fp(fp);
+ ret_addr = ret_addr_from_fp(fp);
+ }
+
+}
diff --git a/xc/util/memleak/getretmips.c b/xc/util/memleak/getretmips.c
new file mode 100644
index 000000000..7a65fb887
--- /dev/null
+++ b/xc/util/memleak/getretmips.c
@@ -0,0 +1,191 @@
+/*
+ * $TOG: getretmips.c /main/5 1998/02/09 11:40:00 kaleb $
+ *
+Copyright 1992, 1998 The Open Group
+
+All Rights Reserved.
+
+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
+ */
+
+/* Return stack generation for MIPS processors
+ * This is tricky as MIPS stack frames aren't
+ * easily unrolled -- we look for pc restoration
+ * and stack adjustment instructions beyond the return
+ * address to discover the correct values
+ */
+
+/* lw $31,const($sp) is : 100 011 11101 11111 const */
+/* 1000 1111 1011 1111 */
+
+#define RESTORE_RETURNVAL 0x8fbf0000
+#define RESTORE_RETURNVAL_MASK 0xffff0000
+
+/* addiu $sp, $sp, const is 001 001 11101 11101 const */
+/* 0010 0111 1011 1101 const */
+
+#define ADJUST_STACKP_C 0x27bd0000
+#define ADJUST_STACKP_C_MASK 0xffff0000
+
+/* addu $sp, $sp, $at is 000 000 11101 00001 11101 00000 100 001 */
+/* 0000 0011 1010 0001 1110 1000 0010 0001 */
+
+#define ADJUST_STACKP_V 0x03a1e821
+#define ADJUST_STACKP_V_MASK 0xffffffff
+
+/* lui $at, const is 001 111 00000 00001 const */
+/* 0011 1100 0000 0001 const */
+
+#define SET_UPPER_C 0x3c010000
+#define SET_UPPER_C_MASK 0xffff0000
+
+/* ori $at, $at, const is 001 101 00001 00001 const */
+/* 0011 0100 0010 0001 const */
+
+#define OR_LOWER_C 0x34210000
+#define OR_LOWER_C_MASK 0xffff0000
+
+/* ori $at, $zero, const is 001 101 00000 00001 const */
+/* 0011 0100 0000 0001 const */
+
+#define SET_LOWER_C 0x34010000
+#define SET_LOWER_C_MASK 0xffff0000
+
+/* jr $ra */
+#define RETURN 0x03e00008
+
+#define CALL(f) (0x0c000000 | (((int) (f)) >> 2))
+
+/*
+ * This computation is expensive, so we cache the results;
+ * a simple hash function and straight-forward replacement.
+ */
+
+#define HASH_SIZE 256
+
+typedef struct _returnCache {
+ unsigned long *returnAddress;
+ long raOffset;
+ long spAdjust;
+} ReturnCacheRec, *ReturnCachePtr;
+
+static ReturnCacheRec returnCache[HASH_SIZE];
+
+#define HASH(ra) ((((int) (ra)) >> 2) & (HASH_SIZE - 1))
+
+typedef int Bool;
+
+#define TRUE 1
+#define FALSE 0
+
+getStackTrace (results, max)
+ unsigned long *results;
+ int max;
+{
+ extern unsigned long *getReturnAddress (), *getStackPointer ();
+ extern int main ();
+ unsigned long *ra, *ra_limit;
+ unsigned long *sp;
+ unsigned long inst;
+ unsigned long mainCall;
+ unsigned short const_upper;
+ unsigned short const_lower;
+ long ra_offset;
+ long sp_adjust;
+ Bool found_ra_offset, found_sp_adjust;
+ Bool found_const_upper, found_const_lower;
+ ReturnCachePtr rc;
+
+ ra = getReturnAddress ();
+ sp = getStackPointer ();
+ mainCall = CALL(main);
+ while (ra && max) {
+ rc = &returnCache[HASH(ra)];
+ if (rc->returnAddress != ra)
+ {
+ found_ra_offset = FALSE;
+ found_sp_adjust = FALSE;
+ found_const_upper = FALSE;
+ found_const_lower = FALSE;
+ const_upper = 0;
+ const_lower = 0;
+ rc->returnAddress = ra;
+ ra_limit = (unsigned long *) 0x10000000;
+ ra_offset = 0;
+ sp_adjust = -1;
+ while ((!found_ra_offset || !found_sp_adjust) && ra < ra_limit)
+ {
+ inst = *ra;
+ /* look for the offset of the PC in the stack frame */
+ if ((inst & RESTORE_RETURNVAL_MASK) == RESTORE_RETURNVAL)
+ {
+ ra_offset = inst & ~RESTORE_RETURNVAL_MASK;
+ found_ra_offset = TRUE;
+ }
+ else if ((inst & ADJUST_STACKP_C_MASK) == ADJUST_STACKP_C)
+ {
+ sp_adjust = inst & ~ADJUST_STACKP_C_MASK;
+ found_sp_adjust = TRUE;
+ }
+ else if ((inst & ADJUST_STACKP_V_MASK) == ADJUST_STACKP_V)
+ {
+ sp_adjust = 0;
+ found_sp_adjust = TRUE;
+ }
+ else if ((inst & SET_UPPER_C_MASK) == SET_UPPER_C)
+ {
+ const_upper = inst & ~SET_UPPER_C_MASK;
+ const_lower = 0;
+ found_const_upper = TRUE;
+ }
+ else if ((inst & OR_LOWER_C_MASK) == OR_LOWER_C)
+ {
+ const_lower = inst & ~OR_LOWER_C_MASK;
+ found_const_lower = TRUE;
+ }
+ else if ((inst & SET_LOWER_C_MASK) == SET_LOWER_C)
+ {
+ const_lower = inst & ~SET_LOWER_C_MASK;
+ const_upper = 0;
+ found_const_lower = TRUE;
+ }
+ else if (inst == RETURN)
+ ra_limit = ra + 2;
+ ra++;
+ }
+ if (sp_adjust == 0 && (found_const_upper || found_const_lower))
+ sp_adjust = (const_upper << 16) | const_lower;
+ rc->raOffset = ra_offset;
+ rc->spAdjust = sp_adjust;
+ }
+ /* if something went wrong, punt */
+ if (rc->spAdjust <= 0)
+ {
+ *results++ = 0;
+ break;
+ }
+ ra = (unsigned long *) sp[rc->raOffset>>2];
+ sp += rc->spAdjust >> 2;
+ *results++ = ((unsigned long) ra) - 8;
+ if (ra[-2] == mainCall)
+ {
+ *results++ = 0;
+ break;
+ }
+ max--;
+ }
+}
diff --git a/xc/util/memleak/getretspar.c b/xc/util/memleak/getretspar.c
new file mode 100644
index 000000000..c72b1e394
--- /dev/null
+++ b/xc/util/memleak/getretspar.c
@@ -0,0 +1,62 @@
+/*
+ * $TOG: getretspar.c /main/3 1998/02/09 11:40:04 kaleb $
+ *
+Copyright 1992, 1998 The Open Group
+
+All Rights Reserved.
+
+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
+ */
+
+/* Trace up the stack and build a call history -- SPARC specific code */
+
+/* hack -- flush out the register windows by recursing */
+
+static void
+flushWindows (depth)
+{
+ if (depth == 0)
+ return;
+ flushWindows (depth-1);
+}
+
+getStackTrace (results, max)
+ unsigned long *results;
+ int max;
+{
+ unsigned long *sp, *getStackPointer (), *getFramePointer();
+ unsigned long *ra, mainCall;
+ extern int main ();
+
+ flushWindows (32);
+ sp = getFramePointer ();
+ while (max)
+ {
+ /* sparc stack traces are easy -- chain up the saved FP/SP values */
+ ra = (unsigned long *) sp[15];
+ sp = (unsigned long *) sp[14];
+ /* stop when we get the call to main */
+ mainCall = ((((unsigned long) main) - ((unsigned long) ra)) >> 2) | 0x40000000;
+ if (ra[0] == mainCall)
+ {
+ *results++ = 0;
+ break;
+ }
+ *results++ = (unsigned long) ra;
+ max--;
+ }
+}
diff --git a/xc/util/memleak/getrettest.c b/xc/util/memleak/getrettest.c
new file mode 100644
index 000000000..671a0b429
--- /dev/null
+++ b/xc/util/memleak/getrettest.c
@@ -0,0 +1,44 @@
+/*
+ * $TOG: getrettest.c /main/5 1998/02/09 11:40:08 kaleb $
+ *
+Copyright 1992, 1998 The Open Group
+
+All Rights Reserved.
+
+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
+ */
+
+main ()
+{
+ f ();
+}
+
+f ()
+{
+ g ();
+}
+
+
+g ()
+{
+ unsigned long returnStack[16];
+ int i;
+
+ getStackTrace (returnStack, 16);
+ for (i = 0; i < 16 && returnStack[i]; i++)
+ printf ("%2d: 0x%lx\n", i, returnStack[i]);
+}
diff --git a/xc/util/memleak/mipsstack.s b/xc/util/memleak/mipsstack.s
new file mode 100644
index 000000000..9dfb94d41
--- /dev/null
+++ b/xc/util/memleak/mipsstack.s
@@ -0,0 +1,39 @@
+/*
+ * $TOG: mipsstack.s /main/4 1998/02/09 11:40:17 kaleb $
+ *
+Copyright 1992, 1998 The Open Group
+
+All Rights Reserved.
+
+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
+ */
+
+ .globl getReturnAddress
+ .ent getReturnAddress
+getReturnAddress:
+ .frame $sp, 0, $31
+ move $2,$31
+ j $31
+ .end getReturnAddress
+
+ .globl getStackPointer
+ .ent getStackPointer
+getStackPointer:
+ .frame $sp, 0, $31
+ move $2,$29
+ j $31
+ .end getStackPointer
diff --git a/xc/util/memleak/sparcsolstack.s b/xc/util/memleak/sparcsolstack.s
new file mode 100644
index 000000000..4eac4ed5f
--- /dev/null
+++ b/xc/util/memleak/sparcsolstack.s
@@ -0,0 +1,11 @@
+! $XConsortium: sparcsolstack.s,v 1.1 93/12/03 09:26:24 kaleb Exp $
+ .seg "text"
+ .proc 16
+ .globl getStackPointer
+getStackPointer:
+ retl
+ mov %sp,%o0
+ .globl getFramePointer
+getFramePointer:
+ retl
+ mov %fp,%o0
diff --git a/xc/util/memleak/sparcstack.s b/xc/util/memleak/sparcstack.s
new file mode 100644
index 000000000..99f5221eb
--- /dev/null
+++ b/xc/util/memleak/sparcstack.s
@@ -0,0 +1,11 @@
+# $XConsortium: sparcstack.s,v 1.2 92/04/08 17:19:18 keith Exp $
+ .seg "text"
+ .proc 16
+ .globl _getStackPointer
+_getStackPointer:
+ retl
+ mov %sp,%o0
+ .globl _getFramePointer
+_getFramePointer:
+ retl
+ mov %fp,%o0
diff --git a/xc/util/memleak/stackbottom.c b/xc/util/memleak/stackbottom.c
new file mode 100644
index 000000000..b29400eb6
--- /dev/null
+++ b/xc/util/memleak/stackbottom.c
@@ -0,0 +1,123 @@
+/*
+ * cut and paste from gc 4.4 by Hans-J. Boehm and Alan J. Demers
+ *
+ * Cutter and Paster: Jeffrey Hsu
+ */
+
+/* $XFree86: xc/util/memleak/stackbottom.c,v 3.1 1996/12/31 05:02:27 dawes Exp $ */
+
+#include <signal.h>
+
+typedef char * ptr_t; /* A generic pointer to which we can add */
+ /* byte displacements. */
+ /* Preferably identical to caddr_t, if it */
+ /* exists. */
+
+#ifndef bool
+typedef int bool;
+#endif
+
+#define VOLATILE volatile
+
+# ifndef STACK_GROWS_UP
+# define STACK_GROWS_DOWN
+# endif
+
+typedef unsigned long word;
+
+#define TRUE 1
+
+#if defined(__alpha) || defined(__alpha__)
+ extern __start
+# define HEURISTIC2_LIMIT ((ptr_t)((word)(&__start) & ~(getpagesize()-1)))
+#endif
+
+void GC_noop() {}
+
+ /* Some tools to implement HEURISTIC2 */
+# define MIN_PAGE_SIZE 256 /* Smallest conceivable page size, bytes */
+# include <setjmp.h>
+ /* static */ jmp_buf GC_jmp_buf;
+
+ /*ARGSUSED*/
+ void GC_fault_handler(sig)
+ int sig;
+ {
+ longjmp(GC_jmp_buf, 1);
+ }
+
+# ifdef __STDC__
+ typedef void (*handler)(int);
+# else
+ typedef void (*handler)();
+# endif
+
+ /* Return the first nonaddressible location > p (up) or */
+ /* the smallest location q s.t. [q,p] is addressible (!up). */
+ ptr_t GC_find_limit(p, up)
+ ptr_t p;
+ bool up;
+ {
+ static VOLATILE ptr_t result;
+ /* Needs to be static, since otherwise it may not be */
+ /* preserved across the longjmp. Can safely be */
+ /* static since it's only called once, with the */
+ /* allocation lock held. */
+
+ static handler old_segv_handler, old_bus_handler;
+ /* See above for static declaration. */
+
+ old_segv_handler = signal(SIGSEGV, GC_fault_handler);
+# ifdef SIGBUS
+ old_bus_handler = signal(SIGBUS, GC_fault_handler);
+# endif
+ if (setjmp(GC_jmp_buf) == 0) {
+ result = (ptr_t)(((word)(p))
+ & ~(MIN_PAGE_SIZE-1));
+ for (;;) {
+ if (up) {
+ result += MIN_PAGE_SIZE;
+ } else {
+ result -= MIN_PAGE_SIZE;
+ }
+ GC_noop(*result);
+ }
+ }
+ (void) signal(SIGSEGV, old_segv_handler);
+# ifdef SIGBUS
+ (void) signal(SIGBUS, old_bus_handler);
+# endif
+ if (!up) {
+ result += MIN_PAGE_SIZE;
+ }
+ return(result);
+ }
+
+ptr_t GC_get_stack_base()
+{
+ word dummy;
+ static ptr_t result;
+
+ if (!result) {
+
+# ifdef STACK_GROWS_DOWN
+ result = GC_find_limit((ptr_t)(&dummy), TRUE);
+# ifdef HEURISTIC2_LIMIT
+ if (result > HEURISTIC2_LIMIT
+ && (ptr_t)(&dummy) < HEURISTIC2_LIMIT) {
+ result = HEURISTIC2_LIMIT;
+ }
+# endif
+# else
+ result = GC_find_limit((ptr_t)(&dummy), FALSE);
+# ifdef HEURISTIC2_LIMIT
+ if (result < HEURISTIC2_LIMIT
+ && (ptr_t)(&dummy) > HEURISTIC2_LIMIT) {
+ result = HEURISTIC2_LIMIT;
+ }
+# endif
+# endif
+ }
+
+ return(result);
+}
diff --git a/xc/util/misc/dlsym.c b/xc/util/misc/dlsym.c
new file mode 100644
index 000000000..2e66d42a4
--- /dev/null
+++ b/xc/util/misc/dlsym.c
@@ -0,0 +1,29 @@
+/* $XConsortium: dlsym.c,v 1.1 93/12/06 16:24:15 kaleb Exp $ */
+/*
+ * Stub interface to dynamic linker routines
+ * that SunOS uses but didn't ship with 4.1.
+ *
+ * The C library routine wcstombs in SunOS 4.1 tries to dynamically
+ * load some routines using the dlsym interface, described in dlsym(3x).
+ * Unfortunately SunOS 4.1 does not include the necessary library, libdl.
+ *
+ * The R5 Xlib uses wcstombs. If you link dynamcally, your program can
+ * run even with the unresolved reference to dlsym. However, if you
+ * link statically, you will encounter this bug. One workaround
+ * is to include these stub routines when you link.
+ */
+
+void *dlopen()
+{
+ return 0;
+}
+
+void *dlsym()
+{
+ return 0;
+}
+
+int dlclose()
+{
+ return -1;
+}
diff --git a/xc/util/misc/rt.stdarg.h b/xc/util/misc/rt.stdarg.h
new file mode 100644
index 000000000..99cc06e7d
--- /dev/null
+++ b/xc/util/misc/rt.stdarg.h
@@ -0,0 +1,8 @@
+/* $XConsortium: rt.stdarg.h,v 1.1 93/12/06 16:24:27 kaleb Exp $ */
+#ifndef _STDARG_H
+#define _STDARG_H
+typedef int *va_list;
+#define va_start(ap, arg) ap = ((int *)&arg) + ((sizeof(arg) + 3) / 4)
+#define va_end(ap)
+#define va_arg(ap, type) ((type *)(ap += (sizeof(type)+3)/4))[-1]
+#endif
diff --git a/xc/util/misc/thr_stubs.c b/xc/util/misc/thr_stubs.c
new file mode 100644
index 000000000..3e841dc21
--- /dev/null
+++ b/xc/util/misc/thr_stubs.c
@@ -0,0 +1,27 @@
+/* $XConsortium: thr_stubs.c,v 1.3 94/01/13 13:59:50 kaleb Exp $ */
+/*
+ * Stub interface to thread routines that Solaris needs but shipped
+ * broken/buggy versions in 5.2 and 5.3
+ *
+ * One workaround is to include this stub routine when you link.
+ *
+ * These routines don't need to have accurate interfaces -- they will
+ * never be called. They just need to be there in order to be resolved
+ * at link time by non-threaded programs.
+ */
+
+extern int errno;
+
+typedef int thread_t;
+
+thread_t thr_self(void) { errno = -1; return 0; }
+int thr_create(void) { errno = -1; return -1; }
+int mutex_init(void) { errno = -1; return -1; }
+int mutex_destroy(void) { errno = -1; return -1; }
+int mutex_lock(void) { errno = -1; return -1; }
+int mutex_unlock(void) { errno = -1; return -1; }
+int cond_init(void) { errno = -1; return -1; }
+int cond_destroy(void) { errno = -1; return -1; }
+int cond_wait(void) { errno = -1; return -1; }
+int cond_signal(void) { errno = -1; return -1; }
+int cond_broadcast(void) { errno = -1; return -1; }
diff --git a/xc/util/patch/ChangeLog b/xc/util/patch/ChangeLog
new file mode 100644
index 000000000..305293787
--- /dev/null
+++ b/xc/util/patch/ChangeLog
@@ -0,0 +1,290 @@
+Mon May 31 00:49:40 1993 Paul Eggert (eggert@twinsun.com)
+
+ * patchlevel.h: PATCHLEVEL 12u9.
+
+ * inp.c (plan_a): Don't lock the checked-out file if `patch -o'
+ redirected the output elsewhere.
+ * common.h (CHECKOUT_LOCKED, GET_LOCKED): New macros. GET and
+ CHECKOUT now just checkout unlocked copies.
+
+ * Makefile (dist): Use gzip, not compress.
+
+Fri May 28 08:44:50 1993 Paul Eggert (eggert@twinsun.com)
+
+ * backupfile.c (basename): Define even if NODIR isn't defined.
+ * patch.c (main): Ask just once to apply a reversed patch.
+
+Tue Sep 15 00:36:15 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * patchlevel.h: PATCHLEVEL 12u8.
+
+Mon Sep 14 22:01:23 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * Makefile.SH: Add uninstall target. Simplify install target.
+
+ * util.c (fatal, pfatal): Add some asterisks to make fatal
+ messages stand out more.
+
+Tue Aug 25 22:13:36 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * patch.c (main, get_some_switches), common.h, inp.c (plan_a,
+ plan_b), pch.c (there_is_another_patch): Add -t option,
+ similar to -f.
+
+Mon Jul 27 11:27:07 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * inp.c (plan_a, util.c (fetchname): Use a macro to simplify code.
+ * common.h: Define SCCSDIFF and RCSDIFF.
+ * inp.c (plan_a): Use them to make sure it's safe to check out
+ the default RCS or SCCS version.
+ From Paul Eggert.
+
+Wed Jul 22 14:37:08 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * patch.man: Use the standard comment syntax -- '\" -- instead
+ of '''.
+
+Tue Jul 21 15:26:01 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * Configure: Add /etc /usr/lib /lib to pth.
+
+Mon Jul 20 14:10:32 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * util.h: Declare basename.
+ * inp.c (plan_a), util.c (fetchname): Use it to isolate the
+ leading path when testing for RCS and SCCS files.
+
+Sat Jul 11 18:03:26 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * Configure: Use the user's PATH and build pth from it.
+
+Fri Jul 10 16:03:23 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * Configure: Change cc -S to cc -c and tr '[ - ]' '[\012-\012]'
+ to tr ' ' '\012' for AIX 3.2.
+ From chip@tct.com (Chip Salzenberg).
+
+ * util.c (makedirs): Only make the directories that don't exist.
+ From chip@tct.com (Chip Salzenberg).
+
+Wed Jul 8 01:21:15 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * util.c (fatal, pfatal): Print "patch: " before message.
+ * pch.c, inp.c, patch.c, util.c: Remove "patch: " from the
+ callers that had it.
+
+ * util.c (pfatal): New function.
+ * util.h: Declare it and pfatal[1-4] macros.
+ * various files: Use it instead of fatal where appropriate.
+
+ * Configure: Make /usr/local/man/man1 the first choice for the
+ man pages.
+
+ * patch.c (main): Open ofp after checking for ed script.
+ Close ofp and rejfp before trying plan B.
+ From epang@sfu.ca (Eugene Pang).
+
+ * backupfile.h: Declare get_version.
+
+ * Move decls of rindex and popen to common.h.
+
+ * common.h (myuid): New variable.
+ * patch.c (main): Initialize it.
+ * inp.c (myuid): Function removed.
+ (plan_a): Use the variable, not the function.
+
+ * patch.c: Reinstate -E option.
+
+Tue Jul 7 23:19:28 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * inp.c (myuid): New function.
+ (plan_a): Call it. Optimize stat calls. Be smarter about
+ detecting checked out RCS and SCCS files.
+ From Paul Eggert (eggert@twinsun.com).
+
+ * inp.c, util.c, patch.c: Don't bother checking for stat() > 0.
+
+Mon Jul 6 13:01:52 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * version.c (version): Don't print the RCS stuff, since we're
+ not updating it regularly.
+
+ * patch.c (get_some_switches): Make the usage message more accurate.
+
+ * patchlevel.h: PATCHLEVEL 12u7.
+
+ * Makefile.SH (dist): New target.
+ Makedist: File removed.
+
+ * inp.c (plan_a): Check whether the user can write to the
+ file, not whether anyone can write to the file.
+
+Sat Jul 4 00:06:58 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * inp.c (plan_a): Try to check out read-only files from RCS or SCCS.
+
+ * util.c (move_file): If backing up by linking fails, try copying.
+ From cek@sdc.boeing.com (Conrad Kimball).
+
+ * patch.c (get_some_switches): Eliminate -E option; always
+ remove empty output files.
+
+ * util.c (fetchname): Only undo slash removal for relative
+ paths if -p was not given.
+
+ * Makefile.sh: Add mostlyclean target.
+
+Fri Jul 3 23:48:14 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * util.c (fetchname): Accept whitespace between `Index:' and filename.
+ Also plug a small memory leak for diffs against /dev/null.
+ From eggert@twinsun.com (Paul Eggert).
+
+ * common.h: Don't define TRUE and FALSE if already defined.
+ From phk@data.fls.dk (Poul-Henning Kamp).
+
+Wed Apr 29 10:19:33 1992 David J. MacKenzie (djm@churchy.gnu.ai.mit.edu)
+
+ * backupfile.c (get_version): Exit if given a bad backup type.
+
+Fri Mar 27 09:57:14 1992 Karl Berry (karl at hayley)
+
+ * common.h (S_ISDIR, S_ISREG): define these.
+ * inp.c (plan_a): use S_ISREG, not S_IFREG.
+ * util.c (fetchname): use S_ISDIR, not S_IFDIR.
+
+Mon Mar 16 14:10:42 1992 David J. MacKenzie (djm@wookumz.gnu.ai.mit.edu)
+
+ * patchlevel.h: PATCHLEVEL 12u6.
+
+Sat Mar 14 13:13:29 1992 David J. MacKenzie (djm at frob.eng.umd.edu)
+
+ * Configure, config.h.SH: Check for directory header and unistd.h.
+
+ * patch.c (main): If -E was given and output file is empty after
+ patching, remove it.
+ (get_some_switches): Recognize -E option.
+
+ * patch.c (copy_till): Make garbled output an error, not a warning
+ that doesn't change the exit status.
+
+ * common.h: Protect against system declarations of malloc and realloc.
+
+ * Makedist: Add backupfile.[ch].
+
+ * Configure: Look for C library where NeXT and SVR4 put it.
+ Look in /usr/ucb after /bin and /usr/bin for utilities,
+ and look in /usr/ccs/bin, to make SVR4 happier.
+ Recognize m68k predefine.
+
+ * util.c (fetchname): Test of stat return value was backward.
+ From csss@scheme.cs.ubc.ca.
+
+ * version.c (version): Exit with status 0, not 1.
+
+ * Makefile.SH: Add backupfile.[cho].
+ * patch.c (main): Initialize backup file generation.
+ (get_some_switches): Add -V option.
+ * common.h, util,c, patch.c: Replace origext with simple_backup_suffix.
+ * util.c (move_file): Use find_backup_file_name.
+
+Tue Dec 3 11:27:16 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu)
+
+ * patchlevel.h: PATCHLEVEL 12u5.
+
+ * Makefile.SH: Change clean, distclean, and realclean targets a
+ little so they agree with the GNU coding standards.
+ Add Makefile to addedbyconf, so distclean removes it.
+
+ * Configure: Recognize Domain/OS C library in /lib/libc.
+ From mmuegel@mot.com (Michael S. Muegel).
+
+ * pch.c: Fixes from Wayne Davison:
+ Patch now accepts no-context context diffs that are
+ specified with an assumed one line hunk (e.g. "*** 10 ****").
+ Fixed a bug in both context and unified diff processing that would
+ put a zero-context hunk in the wrong place (one line too soon).
+ Fixed a minor problem with p_max in unified diffs where it would
+ set p_max to hunkmax unnecessarily (the only adverse effect was to
+ not supply empty lines at eof by assuming they were truncated).
+
+Tue Jul 2 03:25:51 1991 David J. MacKenzie (djm at geech.gnu.ai.mit.edu)
+
+ * Configure: Check for signal declaration in
+ /usr/include/sys/signal.h as well as /usr/include/signal.h.
+
+ * Configure, common.h, config.h.SH: Comment out the sprintf
+ declaration and tests to determine its return value type. It
+ conflicts with ANSI C systems' prototypes in stdio.h and the
+ return value of sprintf is never used anyway -- it's always cast
+ to void.
+
+Thu Jun 27 13:05:32 1991 David J. MacKenzie (djm at churchy.gnu.ai.mit.edu)
+
+ * patchlevel.h: PATCHLEVEL 12u4.
+
+Thu Feb 21 15:18:14 1991 David J. MacKenzie (djm at geech.ai.mit.edu)
+
+ * pch.c (another_hunk): Fix off by 1 error. From
+ iverson@xstor.com (Tim Iverson).
+
+Sun Jan 20 20:18:58 1991 David J. MacKenzie (djm at geech.ai.mit.edu)
+
+ * Makefile.SH (all): Don't make a dummy `all' file.
+
+ * patchlevel.h: PATCHLEVEL 12u3.
+
+ * patch.c (nextarg): New function.
+ (get_some_switches): Use it, to prevent dereferencing a null
+ pointer if an option that takes an arg is not given one (is last
+ on the command line). From Paul Eggert.
+
+ * pch.c (another_hunk): Fix from Wayne Davison to recognize
+ single-line hunks in unified diffs (with a single line number
+ instead of a range).
+
+ * inp.c (rev_in_string): Don't use `s' before defining it. From
+ Wayne Davison.
+
+Mon Jan 7 06:25:11 1991 David J. MacKenzie (djm at geech.ai.mit.edu)
+
+ * patchlevel.h: PATCHLEVEL 12u2.
+
+ * pch.c (intuit_diff_type): Recognize `+++' in diff headers, for
+ unified diff format. From unidiff patch 1.
+
+Mon Dec 3 00:14:25 1990 David J. MacKenzie (djm at albert.ai.mit.edu)
+
+ * patch.c (get_some_switches): Make the usage message more
+ informative.
+
+Sun Dec 2 23:20:18 1990 David J. MacKenzie (djm at albert.ai.mit.edu)
+
+ * Configure: When checking for C preprocessor, look for 'abc.*xyz'
+ instead of 'abc.xyz', so ANSI C preprocessors work.
+
+ * Apply fix for -D from ksb@mentor.cc.purdue.edu (Kevin Braunsdorf).
+
+ * Apply unidiff patches from davison@dri.com (Wayne Davison).
+
+Wed Mar 7 23:47:25 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * pch.c: Call malformed instead of goto malformed
+ (just allows easier debugging).
+
+Tue Jan 23 21:27:00 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * common.h (TMP*NAME): Make these char *, not char [].
+ patch.c (main): Use TMPDIR (if present) to set TMP*NAME.
+ common.h: Declare getenv.
+
+Sun Dec 17 17:29:48 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
+
+ * patch.c (reverse_flag_specified): New variable.
+ (get_some_switches, reinitialize_almost_everything): Use it.
+
+Local Variables:
+mode: indented-text
+left-margin: 8
+version-control: never
+end:
diff --git a/xc/util/patch/Configure b/xc/util/patch/Configure
new file mode 100755
index 000000000..0636a7258
--- /dev/null
+++ b/xc/util/patch/Configure
@@ -0,0 +1,1476 @@
+#! /bin/sh
+#
+# If these # comments don't work, trim them. Don't worry about any other
+# shell scripts, Configure will trim # comments from them for you.
+#
+# (If you are trying to port this package to a machine without sh, I would
+# suggest you cut out the prototypical config.h from the end of Configure
+# and edit it to reflect your system. Some packages may include samples
+# of config.h for certain machines, so you might look for one of those.)
+#
+# oldHeader: Head.U,v 1.0 87/05/22 12:28:10 lwall Exp $
+# $XConsortium: Configure,v 1.1 94/09/09 20:04:01 gildea Exp $
+#
+# Yes, you may rip this off to use in other distribution packages.
+# (Note: this Configure script was generated automatically. Rather than
+# working with this copy of Configure, you may wish to get metaconfig.)
+
+: sanity checks
+: the user has a better chance than we do of setting a reasonable PATH
+: but add some directories we need that are probably not there
+PATH=.:${PATH}:/etc:/usr/lib:/lib
+export PATH || (echo "OOPS, this isn't sh. Desperation time. I will feed myself to sh."; sh $0; kill $$)
+
+if test ! -t 0; then
+ echo "Say 'sh Configure', not 'sh <Configure'"
+ exit 1
+fi
+
+(alias) >/dev/null 2>&1 && \
+ echo "(I see you are using the Korn shell. Some ksh's blow up on Configure," && \
+ echo "especially on exotic machines. If yours does, try the Bourne shell instead.)"
+
+if test ! -d ../UU; then
+ if test ! -d UU; then
+ mkdir UU
+ fi
+ cd UU
+fi
+
+case "$1" in
+-d) shift; fastread='yes';;
+esac
+
+d_eunice=''
+eunicefix=''
+define=''
+loclist=''
+expr=''
+sed=''
+echo=''
+cat=''
+rm=''
+mv=''
+cp=''
+tail=''
+tr=''
+mkdir=''
+sort=''
+uniq=''
+grep=''
+trylist=''
+test=''
+inews=''
+egrep=''
+more=''
+pg=''
+Mcc=''
+vi=''
+mailx=''
+mail=''
+cpp=''
+Log=''
+Header=''
+bin=''
+cc=''
+contains=''
+cppstdin=''
+cppminus=''
+d_charsprf=''
+d_flexfnam=''
+d_index=''
+d_voidsig=''
+d_dirheader=''
+d_unistd=''
+libc=''
+mansrc=''
+manext=''
+models=''
+split=''
+small=''
+medium=''
+large=''
+huge=''
+ccflags=''
+ldflags=''
+n=''
+c=''
+package=''
+registers=''
+reg1=''
+reg2=''
+reg3=''
+reg4=''
+reg5=''
+reg6=''
+reg7=''
+reg8=''
+reg9=''
+reg10=''
+reg11=''
+reg12=''
+reg13=''
+reg14=''
+reg15=''
+reg16=''
+spitshell=''
+shsharp=''
+sharpbang=''
+startsh=''
+voidflags=''
+defvoidused=''
+CONFIG=''
+: set package name
+package=patch
+
+echo " "
+echo "Beginning of configuration questions for $package kit."
+: Eunice requires " " instead of "", can you believe it
+echo " "
+
+define='define'
+undef='/*undef'
+libpth='/usr/lib /usr/local/lib /lib /usr/ccs/lib'
+smallmach='pdp11 i8086 z8000 i80286 iAPX286'
+rmlist='kit[1-9]isdone kit[1-9][0-9]isdone'
+trap 'echo " "; rm -f $rmlist; exit 1' 1 2 3
+
+: We must find out about Eunice early
+eunicefix=':'
+if test -f /etc/unixtovms; then
+ eunicefix=/etc/unixtovms
+fi
+if test -f /etc/unixtovms.exe; then
+ eunicefix=/etc/unixtovms.exe
+fi
+
+attrlist="mc68000 sun gcos unix ibm gimpel interdata tss os mert pyr"
+attrlist="$attrlist vax pdp11 i8086 z8000 u3b2 u3b5 u3b20 u3b200"
+attrlist="$attrlist ns32000 ns16000 iAPX286 mc300 mc500 mc700 sparc"
+attrlist="$attrlist nsc32000 sinix xenix venix posix ansi M_XENIX"
+attrlist="$attrlist mc68k m68k __STDC__"
+pth=`echo $PATH | tr : ' '`
+d_newshome="../../NeWS"
+defvoidused=7
+
+: some greps do not return status, grrr.
+echo "grimblepritz" >grimble
+if grep blurfldyick grimble >/dev/null 2>&1 ; then
+ contains=contains
+elif grep grimblepritz grimble >/dev/null 2>&1 ; then
+ contains=grep
+else
+ contains=contains
+fi
+rm -f grimble
+: the following should work in any shell
+case "$contains" in
+contains*)
+ echo " "
+ echo "AGH! Grep doesn't return a status. Attempting remedial action."
+ cat >contains <<'EOSS'
+grep "$1" "$2" >.greptmp && cat .greptmp && test -s .greptmp
+EOSS
+chmod +x contains
+esac
+
+: first determine how to suppress newline on echo command
+echo "Checking echo to see how to suppress newlines..."
+(echo "hi there\c" ; echo " ") >.echotmp
+if $contains c .echotmp >/dev/null 2>&1 ; then
+ echo "...using -n."
+ n='-n'
+ c=''
+else
+ cat <<'EOM'
+...using \c
+EOM
+ n=''
+ c='\c'
+fi
+echo $n "Type carriage return to continue. Your cursor should be here-->$c"
+read ans
+rm -f .echotmp
+
+: now set up to do reads with possible shell escape and default assignment
+cat <<EOSC >myread
+case "\$fastread" in
+yes) ans=''; echo " " ;;
+*) ans='!';;
+esac
+while expr "X\$ans" : "X!" >/dev/null; do
+ read ans
+ case "\$ans" in
+ !)
+ sh
+ echo " "
+ echo $n "\$rp $c"
+ ;;
+ !*)
+ set \`expr "X\$ans" : "X!\(.*\)\$"\`
+ sh -c "\$*"
+ echo " "
+ echo $n "\$rp $c"
+ ;;
+ esac
+done
+rp='Your answer:'
+case "\$ans" in
+'') ans="\$dflt";;
+esac
+EOSC
+
+: general instructions
+cat <<EOH
+
+This installation shell script will examine your system and ask you questions
+to determine how the $package package should be installed. If you get stuck
+on a question, you may use a ! shell escape to start a subshell or execute
+a command. Many of the questions will have default answers in square
+brackets--typing carriage return will give you the default.
+
+On some of the questions which ask for file or directory names you are
+allowed to use the ~name construct to specify the login directory belonging
+to "name", even if you don't have a shell which knows about that. Questions
+where this is allowed will be marked "(~name ok)".
+
+EOH
+rp="[Type carriage return to continue]"
+echo $n "$rp $c"
+. myread
+cat <<EOH
+
+Much effort has been expended to ensure that this shell script will run
+on any Unix system. If despite that it blows up on you, your best bet is
+to edit Configure and run it again. Also, let me (lwall@netlabs.com)
+know how I blew it. If you can't run Configure for some reason, you'll have
+to generate a config.sh file by hand.
+
+This installation script affects things in two ways: 1) it may do direct
+variable substitutions on some of the files included in this kit, and
+2) it builds a config.h file for inclusion in C programs. You may edit
+any of these files as the need arises after running this script.
+
+If you make a mistake on a question, there is no easy way to back up to it
+currently. The easiest thing to do is to edit config.sh and rerun all the
+SH files. Configure will offer to let you do this before it runs the SH files.
+
+EOH
+rp="[Type carriage return to continue]"
+echo $n "$rp $c"
+. myread
+
+: get old answers, if there is a config file out there
+if test -f ../config.sh; then
+ echo " "
+ dflt=y
+ rp="I see a config.sh file. Did Configure make it on THIS system? [$dflt]"
+ echo $n "$rp $c"
+ . myread
+ case "$ans" in
+ n*) echo "OK, I'll ignore it.";;
+ *) echo "Fetching default answers from your old config.sh file..."
+ tmp="$n"
+ ans="$c"
+ . ../config.sh
+ n="$tmp"
+ c="$ans"
+ ;;
+ esac
+fi
+
+: find out where common programs are
+echo " "
+echo "Locating common programs..."
+cat <<EOSC >loc
+$startsh
+case \$# in
+0) exit 1;;
+esac
+thing=\$1
+shift
+dflt=\$1
+shift
+for dir in \$*; do
+ case "\$thing" in
+ .)
+ if test -d \$dir/\$thing; then
+ echo \$dir
+ exit 0
+ fi
+ ;;
+ *)
+ if test -f \$dir/\$thing; then
+ echo \$dir/\$thing
+ exit 0
+ elif test -f \$dir/\$thing.exe; then
+ : on Eunice apparently
+ echo \$dir/\$thing
+ exit 0
+ fi
+ ;;
+ esac
+done
+echo \$dflt
+exit 1
+EOSC
+chmod +x loc
+$eunicefix loc
+loclist="
+expr
+sed
+echo
+cat
+rm
+tr
+grep
+"
+trylist="
+test
+Mcc
+cpp
+"
+for file in $loclist; do
+ xxx=`loc $file $file $pth`
+ eval $file=$xxx
+ eval _$file=$xxx
+ case "$xxx" in
+ /*)
+ echo $file is in $xxx.
+ ;;
+ *)
+ echo "I don't know where $file is. I hope it's in everyone's PATH."
+ ;;
+ esac
+done
+echo " "
+echo "Don't worry if any of the following aren't found..."
+ans=offhand
+for file in $trylist; do
+ xxx=`loc $file $file $pth`
+ eval $file=$xxx
+ eval _$file=$xxx
+ case "$xxx" in
+ /*)
+ echo $file is in $xxx.
+ ;;
+ *)
+ echo "I don't see $file out there, $ans."
+ ans=either
+ ;;
+ esac
+done
+case "$egrep" in
+egrep)
+ echo "Substituting grep for egrep."
+ egrep=$grep
+ ;;
+esac
+case "$test" in
+test)
+ echo "Hopefully test is built into your sh."
+ ;;
+/bin/test)
+ echo " "
+ dflt=n
+ rp="Is your "'"'"test"'"'" built into sh? [$dflt] (OK to guess)"
+ echo $n "$rp $c"
+ . myread
+ case "$ans" in
+ y*) test=test ;;
+ esac
+ ;;
+*)
+ test=test
+ ;;
+esac
+case "$echo" in
+echo)
+ echo "Hopefully echo is built into your sh."
+ ;;
+/bin/echo)
+ echo " "
+ echo "Checking compatibility between /bin/echo and builtin echo (if any)..."
+ $echo $n "hi there$c" >foo1
+ echo $n "hi there$c" >foo2
+ if cmp foo1 foo2 >/dev/null 2>&1; then
+ echo "They are compatible. In fact, they may be identical."
+ else
+ case "$n" in
+ '-n') n='' c='\c' ans='\c' ;;
+ *) n='-n' c='' ans='-n' ;;
+ esac
+ cat <<FOO
+They are not compatible! You are probably running ksh on a non-USG system.
+I'll have to use /bin/echo instead of the builtin, since Bourne shell doesn't
+have echo built in and we may have to run some Bourne shell scripts. That
+means I'll have to use $ans to suppress newlines now. Life is ridiculous.
+
+FOO
+ rp="Your cursor should be here-->"
+ $echo $n "$rp$c"
+ . myread
+ fi
+ $rm -f foo1 foo2
+ ;;
+*)
+ : cross your fingers
+ echo=echo
+ ;;
+esac
+rmlist="$rmlist loc"
+
+: get list of predefined functions in a handy place
+echo " "
+if test -f /lib/libc.a; then
+ echo "Your C library is in /lib/libc.a. You're normal."
+ libc=/lib/libc.a
+else
+ if test -f /lib/clib -a -f /lib/libc; then
+ echo "Your standard C library is in /lib/libc. Must be Domain/OS."
+ libc=/lib/libc
+ elif test -f /lib/libsys_s.a; then
+ echo "Your C library is in /lib/libsys_s.a. Must be a NeXT."
+ libc=/lib/libsys_s.a
+ else
+ ans=`loc libc.a blurfl/dyick $libpth`
+ if test ! -f $ans; then
+ ans=`loc clib blurfl/dyick $libpth`
+ fi
+ if test ! -f $ans; then
+ ans=`loc libc blurfl/dyick $libpth`
+ fi
+ if test -f $ans; then
+ echo "Your C library is in $ans, of all places."
+ libc=$ans
+ else
+ if test -f "$libc"; then
+ echo "Your C library is in $libc, like you said before."
+ else
+ cat <<EOM
+
+I can't seem to find your C library. I've looked in the following places:
+
+ $libpth
+
+None of these seems to contain your C library. What is the full name
+EOM
+ dflt=None
+ $echo $n "of your C library? $c"
+ rp='C library full name?'
+ . myread
+ libc="$ans"
+ fi
+ fi
+ fi
+fi
+echo " "
+$echo $n "Extracting names from $libc for later perusal...$c"
+nm $libc 2>/dev/null | sed -n -e 's/^.* T _//p' -e 's/^.* T //p' > libc.list
+if $contains '^printf$' libc.list >/dev/null 2>&1; then
+ echo "done"
+else
+ nm $libc 2>/dev/null | sed -n -e 's/^.* D _//p' -e 's/^.* D //p' > libc.list
+ if $contains '^printf$' libc.list >/dev/null 2>&1; then
+ echo "done"
+ else
+ echo " "
+ echo "nm didn't seem to work right."
+ echo "Trying ar instead..."
+ if ar t $libc | sed -e 's/\.o$//' > libc.list; then
+ echo "Ok."
+ else
+ echo "That didn't work either. Giving up."
+ exit 1
+ fi
+ fi
+fi
+rmlist="$rmlist libc.list"
+
+: make some quick guesses about what we are up against
+echo " "
+$echo $n "Hmm... $c"
+if $contains SIGTSTP /usr/include/signal.h >/dev/null 2>&1 ; then
+ echo "Looks kind of like a BSD system, but we'll see..."
+ echo exit 0 >bsd
+ echo exit 1 >usg
+ echo exit 1 >v7
+elif $contains '^fcntl$' libc.list >/dev/null 2>&1 ; then
+ echo "Looks kind of like a USG system, but we'll see..."
+ echo exit 1 >bsd
+ echo exit 0 >usg
+ echo exit 1 >v7
+else
+ echo "Looks kind of like a version 7 system, but we'll see..."
+ echo exit 1 >bsd
+ echo exit 1 >usg
+ echo exit 0 >v7
+fi
+if $contains '^vmssystem$' libc.list >/dev/null 2>&1 ; then
+ cat <<'EOI'
+There is, however, a strange, musty smell in the air that reminds me of
+something...hmm...yes...I've got it...there's a VMS nearby, or I'm a Blit.
+EOI
+ echo "exit 0" >eunice
+ eunicefix=unixtovms
+ d_eunice="$define"
+: it so happens the Eunice I know will not run shell scripts in Unix format
+else
+ echo " "
+ echo "Congratulations. You aren't running Eunice."
+ eunicefix=':'
+ d_eunice="$undef"
+ echo "exit 1" >eunice
+fi
+if test -f /xenix; then
+ echo "Actually, this looks more like a XENIX system..."
+ echo "exit 0" >xenix
+else
+ echo " "
+ echo "It's not Xenix..."
+ echo "exit 1" >xenix
+fi
+chmod +x xenix
+$eunicefix xenix
+if test -f /venix; then
+ echo "Actually, this looks more like a VENIX system..."
+ echo "exit 0" >venix
+else
+ echo " "
+ if xenix; then
+ : null
+ else
+ echo "Nor is it Venix..."
+ fi
+ echo "exit 1" >venix
+fi
+chmod +x bsd usg v7 eunice venix
+$eunicefix bsd usg v7 eunice venix
+rmlist="$rmlist bsd usg v7 eunice venix xenix"
+
+: see if sh knows # comments
+echo " "
+echo "Checking your sh to see if it knows about # comments..."
+if sh -c '#' >/dev/null 2>&1 ; then
+ echo "Your sh handles # comments correctly."
+ shsharp=true
+ spitshell=cat
+ echo " "
+ echo "Okay, let's see if #! works on this system..."
+ echo "#!/bin/echo hi" > try
+ $eunicefix try
+ chmod +x try
+ try > today
+ if $contains hi today >/dev/null 2>&1; then
+ echo "It does."
+ sharpbang='#!'
+ else
+ echo "#! /bin/echo hi" > try
+ $eunicefix try
+ chmod +x try
+ try > today
+ if test -s today; then
+ echo "It does."
+ sharpbang='#! '
+ else
+ echo "It doesn't."
+ sharpbang=': use '
+ fi
+ fi
+else
+ echo "Your sh doesn't grok # comments--I will strip them later on."
+ shsharp=false
+ echo "exec grep -v '^#'" >spitshell
+ chmod +x spitshell
+ $eunicefix spitshell
+ spitshell=`pwd`/spitshell
+ echo "I presume that if # doesn't work, #! won't work either!"
+ sharpbang=': use '
+fi
+
+: figure out how to guarantee sh startup
+echo " "
+echo "Checking out how to guarantee sh startup..."
+startsh=$sharpbang'/bin/sh'
+echo "Let's see if '$startsh' works..."
+cat >try <<EOSS
+$startsh
+set abc
+test "$?abc" != 1
+EOSS
+
+chmod +x try
+$eunicefix try
+if try; then
+ echo "Yup, it does."
+else
+ echo "Nope. You may have to fix up the shell scripts to make sure sh runs them."
+fi
+rm -f try today
+
+#: see if sprintf is declared as int or pointer to char
+#echo " "
+#cat >.ucbsprf.c <<'EOF'
+#main() { char buf[10]; exit((unsigned long)sprintf(buf,"%s","foo") > 10L); }
+#EOF
+#if cc .ucbsprf.c -o .ucbsprf >/dev/null 2>&1 && .ucbsprf; then
+# echo "Your sprintf() returns (int)."
+# d_charsprf="$undef"
+#else
+# echo "Your sprintf() returns (char*)."
+# d_charsprf="$define"
+#fi
+#/bin/rm -f .ucbsprf.c .ucbsprf
+
+: see if we can have long filenames
+echo " "
+rm -f 123456789abcde
+if (echo hi >123456789abcdef) 2>/dev/null; then
+ : not version 8
+ if test -f 123456789abcde; then
+ echo 'You cannot have filenames longer than 14 characters. Sigh.'
+ d_flexfnam="$undef"
+ else
+ echo 'You can have filenames longer than 14 characters.'
+ d_flexfnam="$define"
+ fi
+else
+ : version 8 probably
+ echo "You can't have filenames longer than 14 chars. V8 can't even think about them!"
+ d_flexfnam="$undef"
+fi
+: index or strcpy
+echo " "
+case "$d_index" in
+n) dflt=n;;
+*) dflt=y;;
+esac
+if $contains '^index$' libc.list >/dev/null 2>&1 ; then
+ if $contains '^strchr$' libc.list >/dev/null 2>&1 ; then
+ echo "Your system has both index() and strchr(). Shall I use"
+ rp="index() rather than strchr()? [$dflt]"
+ $echo $n "$rp $c"
+ . myread
+ case "$ans" in
+ n*) d_index="$define" ;;
+ *) d_index="$undef" ;;
+ esac
+ else
+ d_index="$undef"
+ echo "index() found."
+ fi
+else
+ if $contains '^strchr$' libc.list >/dev/null 2>&1 ; then
+ d_index="$define"
+ echo "strchr() found."
+ else
+ echo "No index() or strchr() found!"
+ d_index="$undef"
+ fi
+fi
+
+: see if signal is declared as pointer to function returning int or void
+echo " "
+if $contains 'void.*signal' /usr/include/signal.h >/dev/null 2>&1 ||
+$contains 'void.*signal' /usr/include/sys/signal.h >/dev/null 2>&1 ; then
+ echo "You have void (*signal())() instead of int."
+ d_voidsig="$define"
+else
+ echo "You have int (*signal())() instead of void."
+ d_voidsig="$undef"
+fi
+
+: check for directory library
+echo " "
+if test -f /usr/include/dirent.h; then
+ echo "You have dirent.h."
+ d_dirheader="#define DIRENT"
+elif test -f /usr/include/ndir.h; then
+ echo "You have ndir.h."
+ d_dirheader="#define USG"
+elif test -f /usr/include/sys/ndir.h; then
+ echo "You have sys/ndir.h."
+ d_dirheader="#define SYSNDIR
+#define USG"
+elif test -f /usr/include/sys/dir.h; then
+ echo "You have sys/dir.h; I hope that's the BSD version."
+ d_dirheader="#define SYSDIR"
+else
+ echo "I can't find a directory library header file.
+That means you won't have numbered backups available."
+ d_dirheader="#define NODIR"
+fi
+
+: check for unistd.h
+echo " "
+if test -f /usr/include/unistd.h; then
+ echo "You have unistd.h."
+ d_unistd="$define"
+else
+ echo "I don't see unistd.h, but that's OK."
+ d_unistd="$undef"
+fi
+
+: check for void type
+echo " "
+$cat <<EOM
+Checking to see how well your C compiler groks the void type...
+
+ Support flag bits are:
+ 1: basic void declarations.
+ 2: arrays of pointers to functions returning void.
+ 4: operations between pointers to and addresses of void functions.
+
+EOM
+case "$voidflags" in
+'')
+ $cat >try.c <<'EOCP'
+#if TRY & 1
+void main() {
+#else
+main() {
+#endif
+ extern void *moo();
+ void *(*goo)();
+#if TRY & 2
+ void (*foo[10])();
+#endif
+
+#if TRY & 4
+ if(*goo == moo) {
+ exit(0);
+ }
+#endif
+ exit(0);
+}
+EOCP
+ : Argh -- AIX 3.2 does not have cc -S!
+ if cc -c -DTRY=7 try.c >.out 2>&1 ; then
+ voidflags=7
+ echo "It appears to support void fully."
+ if $contains warning .out >/dev/null 2>&1; then
+ echo "However, you might get some warnings that look like this:"
+ $cat .out
+ fi
+ else
+ echo "Hmm, you compiler has some difficulty with void. Checking further..."
+ if cc -c -DTRY=1 try.c >/dev/null 2>&1 ; then
+ echo "It supports 1..."
+ if cc -c -DTRY=3 try.c >/dev/null 2>&1 ; then
+ voidflags=3
+ echo "And it supports 2 but not 4."
+ else
+ echo "It doesn't support 2..."
+ if cc -c -DTRY=3 try.c >/dev/null 2>&1 ; then
+ voidflags=5
+ echo "But it supports 4."
+ else
+ voidflags=1
+ echo "And it doesn't support 4."
+ fi
+ fi
+ else
+ echo "There is no support at all for void."
+ voidflags=0
+ fi
+ fi
+esac
+dflt="$voidflags";
+rp="Your void support flags add up to what? [$dflt]"
+$echo $n "$rp $c"
+. myread
+voidflags="$ans"
+$rm -f try.* .out
+
+: see how we invoke the C preprocessor
+echo " "
+echo "Now, how can we feed standard input to your C preprocessor..."
+cat <<'EOT' >testcpp.c
+#define ABC abc
+#define XYZ xyz
+ABC.XYZ
+EOT
+echo 'Maybe "'$cpp'" will work...'
+$cpp <testcpp.c >testcpp.out 2>&1
+if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
+ echo "Yup, it does."
+ cppstdin="$cpp"
+ cppminus='';
+else
+ echo 'Nope, maybe "'$cpp' -" will work...'
+ $cpp - <testcpp.c >testcpp.out 2>&1
+ if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
+ echo "Yup, it does."
+ cppstdin="$cpp"
+ cppminus='-';
+ else
+ echo 'No such luck...maybe "cc -E" will work...'
+ cc -E <testcpp.c >testcpp.out 2>&1
+ if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
+ echo "It works!"
+ cppstdin='cc -E'
+ cppminus='';
+ else
+ echo 'Nixed again...maybe "cc -E -" will work...'
+ cc -E - <testcpp.c >testcpp.out 2>&1
+ if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
+ echo "Hooray, it works! I was beginning to wonder."
+ cppstdin='cc -E'
+ cppminus='-';
+ else
+ echo 'Nope...maybe "cc -P" will work...'
+ cc -P <testcpp.c >testcpp.out 2>&1
+ if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
+ echo "Yup, that does."
+ cppstdin='cc -P'
+ cppminus='';
+ else
+ echo 'Nope...maybe "cc -P -" will work...'
+ cc -P - <testcpp.c >testcpp.out 2>&1
+ if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
+ echo "Yup, that does."
+ cppstdin='cc -P'
+ cppminus='-';
+ else
+ echo 'Hmm...perhaps you already told me...'
+ case "$cppstdin" in
+ '') ;;
+ *) $cppstdin $cppminus <testcpp.c >testcpp.out 2>&1;;
+ esac
+ if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
+ echo "Hooray, you did! I was beginning to wonder."
+ else
+ echo 'Uh-uh. Time to get fancy...'
+ echo 'Trying (cat >/tmp/$$.c; cc -E /tmp/$$.c; rm /tmp/$$.c)'
+ cppstdin='(cat >/tmp/$$.c; cc -E /tmp/$$.c; rm /tmp/$$.c)'
+ cppminus='';
+ $cppstdin <testcpp.c >testcpp.out 2>&1
+ if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
+ echo "Eureka!."
+ else
+ dflt=blurfl
+ $echo $n "No dice. I can't find a C preprocessor. Name one: $c"
+ rp='Name a C preprocessor:'
+ . myread
+ cppstdin="$ans"
+ $cppstdin <testcpp.c >testcpp.out 2>&1
+ if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
+ echo "OK, that will do."
+ else
+ echo "Sorry, I can't get that to work. Go find one."
+ exit 1
+ fi
+ fi
+ fi
+ fi
+ fi
+ fi
+ fi
+ fi
+fi
+rm -f testcpp.c testcpp.out
+
+: get C preprocessor symbols handy
+echo " "
+: AIX 3.2 rejects tr '[ - ]' because the range endpoints are the same.
+echo $attrlist | $tr ' ' '\012' >Cppsym.know
+$cat <<EOSS >Cppsym
+$startsh
+case "\$1" in
+-l) list=true
+ shift
+ ;;
+esac
+unknown=''
+case "\$list\$#" in
+1|2)
+ for sym do
+ if $contains "^\$1$" Cppsym.true >/dev/null 2>&1; then
+ exit 0
+ elif $contains "^\$1$" Cppsym.know >/dev/null 2>&1; then
+ :
+ else
+ unknown="\$unknown \$sym"
+ fi
+ done
+ set X \$unknown
+ shift
+ ;;
+esac
+case \$# in
+0) exit 1;;
+esac
+echo \$* | $tr ' ' '\012' | $sed -e 's/\(.*\)/\\
+#ifdef \1\\
+exit 0; _ _ _ _\1\\ \1\\
+#endif\\
+/' >/tmp/Cppsym\$\$
+echo exit 1 >>/tmp/Cppsym\$\$
+$cppstdin $cppminus </tmp/Cppsym\$\$ >/tmp/Cppsym2\$\$
+case "\$list" in
+true) awk 'NF > 5 {print substr(\$6,2,100)}' </tmp/Cppsym2\$\$ ;;
+*)
+ sh /tmp/Cppsym2\$\$
+ status=\$?
+ ;;
+esac
+$rm -f /tmp/Cppsym\$\$ /tmp/Cppsym2\$\$
+exit \$status
+EOSS
+chmod +x Cppsym
+$eunicefix Cppsym
+echo "Your C preprocessor defines the following symbols:"
+Cppsym -l $attrlist >Cppsym.true
+cat Cppsym.true
+rmlist="$rmlist Cppsym Cppsym.know Cppsym.true"
+
+: see how many register declarations we want to use
+case "$registers" in
+'')
+ if Cppsym vax; then
+ dflt=6
+ elif Cppsym sun mc68000 mc68k m68k; then
+ dflt=10
+ elif Cppsym pyr; then
+ dflt=14
+ elif Cppsym ns32000 ns16000; then
+ dflt=5
+ elif Cppsym $smallmach; then
+ dflt=3
+ else
+ : if you have any other numbers for me, send them in
+ dflt=6
+ fi
+ ;;
+*) dflt=$registers ;;
+esac
+cat <<EOM
+
+Different C compilers on different machines pay attention to different
+numbers of register declarations. About how many register declarations in
+EOM
+$echo $n "each routine does your C compiler pay attention to? (OK to guess) [$dflt] $c"
+rp="# register declarations used? [$dflt]"
+. myread
+registers=$ans
+reg1=''
+awk "BEGIN { for (i=1; i<=16; i++) printf \"reg%d=''\n\", i}" </dev/null >.foo
+. .foo
+awk "BEGIN { for (i=1; i<=$registers; i++) printf \"reg%d=register\n\", i}" \
+ </dev/null >.foo
+. .foo
+rm -f .foo
+
+: preserve RCS keywords in files with variable substitution, grrr
+Log='$Log'
+Header='$Header'
+
+: set up shell script to do ~ expansion
+cat >filexp <<EOSS
+$startsh
+: expand filename
+case "\$1" in
+ ~/*|~)
+ echo \$1 | $sed "s|~|\${HOME-\$LOGDIR}|"
+ ;;
+ ~*)
+ if $test -f /bin/csh; then
+ /bin/csh -f -c "glob \$1"
+ echo ""
+ else
+ name=\`$expr x\$1 : '..\([^/]*\)'\`
+ dir=\`$sed -n -e "/^\${name}:/{s/^[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:\([^:]*\).*"'\$'"/\1/" -e p -e q -e '}' </etc/passwd\`
+ if $test ! -d "\$dir"; then
+ me=\`basename \$0\`
+ echo "\$me: can't locate home directory for: \$name" >&2
+ exit 1
+ fi
+ case "\$1" in
+ */*)
+ echo \$dir/\`$expr x\$1 : '..[^/]*/\(.*\)'\`
+ ;;
+ *)
+ echo \$dir
+ ;;
+ esac
+ fi
+ ;;
+*)
+ echo \$1
+ ;;
+esac
+EOSS
+chmod +x filexp
+$eunicefix filexp
+
+: determine where public executables go
+case "$bin" in
+'')
+ dflt=`loc . /bin /usr/local/bin /usr/lbin /usr/local /usr/bin`
+ ;;
+*) dflt="$bin"
+ ;;
+esac
+cont=true
+while $test "$cont" ; do
+ echo " "
+ rp="Where do you want to put the public executables? [$dflt]"
+ $echo $n "$rp $c"
+ . myread
+ bin="$ans"
+ bin=`filexp $bin`
+ if test -d $bin; then
+ cont=''
+ else
+ dflt=n
+ rp="Directory $bin doesn't exist. Use that name anyway? [$dflt]"
+ $echo $n "$rp $c"
+ . myread
+ dflt=''
+ case "$ans" in
+ y*) cont='';;
+ esac
+ fi
+done
+
+: determine where manual pages go
+case "$mansrc" in
+'')
+ dflt=`loc . /usr/man/man1 /usr/local/man/man1 /usr/man/mann /usr/man/local/man1 /usr/man/u_man/man1`
+ ;;
+*) dflt="$mansrc"
+ ;;
+esac
+cont=true
+while $test "$cont" ; do
+ echo " "
+ rp="Where do the manual pages (source) go? [$dflt]"
+ $echo $n "$rp $c"
+ . myread
+ mansrc=`filexp "$ans"`
+ if test -d $mansrc; then
+ cont=''
+ else
+ dflt=n
+ rp="Directory $mansrc doesn't exist. Use that name anyway? [$dflt]"
+ $echo $n "$rp $c"
+ . myread
+ dflt=''
+ case "$ans" in
+ y*) cont='';;
+ esac
+ fi
+done
+case "$mansrc" in
+*l)
+ manext=l
+ ;;
+*n)
+ manext=n
+ ;;
+*C)
+ manext=C
+ ;;
+*)
+ manext=1
+ ;;
+esac
+
+: see what memory models we can support
+case "$models" in
+'')
+ if Cppsym pdp11; then
+ dflt='unsplit split'
+ else
+ ans=`loc . X /lib/small /lib/large /usr/lib/small /usr/lib/large /lib/medium /usr/lib/medium /lib/huge`
+ case "$ans" in
+ X) dflt='none';;
+ *) if $test -d /lib/small || $test -d /usr/lib/small; then
+ dflt='small'
+ else
+ dflt=''
+ fi
+ if $test -d /lib/medium || $test -d /usr/lib/medium; then
+ dflt="$dflt medium"
+ fi
+ if $test -d /lib/large || $test -d /usr/lib/large; then
+ dflt="$dflt large"
+ fi
+ if $test -d /lib/huge || $test -d /usr/lib/huge; then
+ dflt="$dflt huge"
+ fi
+ esac
+ fi
+ ;;
+*) dflt="$models" ;;
+esac
+$cat <<EOM
+
+Some systems have different model sizes. On most systems they are called
+small, medium, large, and huge. On the PDP11 they are called unsplit and
+split. If your system doesn't support different memory models, say "none".
+If you wish to force everything to one memory model, say "none" here and
+put the appropriate flags later when it asks you for other cc and ld flags.
+Venix systems may wish to put "none" and let the compiler figure things out.
+(In the following question multiple model names should be space separated.)
+
+EOM
+rp="Which models are supported? [$dflt]"
+$echo $n "$rp $c"
+. myread
+models="$ans"
+
+case "$models" in
+none)
+ small=''
+ medium=''
+ large=''
+ huge=''
+ unsplit=''
+ split=''
+ ;;
+*split)
+ case "$split" in
+ '')
+ if $contains '-i' $mansrc/ld.1 >/dev/null 2>&1 || \
+ $contains '-i' $mansrc/cc.1 >/dev/null 2>&1; then
+ dflt='-i'
+ else
+ dflt='none'
+ fi
+ ;;
+ *) dflt="$split";;
+ esac
+ rp="What flag indicates separate I and D space? [$dflt]"
+ $echo $n "$rp $c"
+ . myread
+ case "$ans" in
+ none) ans='';;
+ esac
+ split="$ans"
+ unsplit=''
+ ;;
+*large*|*small*|*medium*|*huge*)
+ case "$model" in
+ *large*)
+ case "$large" in
+ '') dflt='-Ml';;
+ *) dflt="$large";;
+ esac
+ rp="What flag indicates large model? [$dflt]"
+ $echo $n "$rp $c"
+ . myread
+ case "$ans" in
+ none) ans='';
+ esac
+ large="$ans"
+ ;;
+ *) large='';;
+ esac
+ case "$model" in
+ *huge*)
+ case "$huge" in
+ '') dflt='-Mh';;
+ *) dflt="$huge";;
+ esac
+ rp="What flag indicates huge model? [$dflt]"
+ $echo $n "$rp $c"
+ . myread
+ case "$ans" in
+ none) ans='';
+ esac
+ huge="$ans"
+ ;;
+ *) huge="$large";;
+ esac
+ case "$model" in
+ *medium*)
+ case "$medium" in
+ '') dflt='-Mm';;
+ *) dflt="$medium";;
+ esac
+ rp="What flag indicates medium model? [$dflt]"
+ $echo $n "$rp $c"
+ . myread
+ case "$ans" in
+ none) ans='';
+ esac
+ medium="$ans"
+ ;;
+ *) medium="$large";;
+ esac
+ case "$model" in
+ *small*)
+ case "$small" in
+ '') dflt='none';;
+ *) dflt="$small";;
+ esac
+ rp="What flag indicates small model? [$dflt]"
+ $echo $n "$rp $c"
+ . myread
+ case "$ans" in
+ none) ans='';
+ esac
+ small="$ans"
+ ;;
+ *) small='';;
+ esac
+ ;;
+*)
+ echo "Unrecognized memory models--you may have to edit Makefile.SH"
+ ;;
+esac
+
+case "$ccflags" in
+'') dflt='none';;
+*) dflt="$ccflags";;
+esac
+echo " "
+rp="Any additional cc flags? [$dflt]"
+$echo $n "$rp $c"
+. myread
+case "$ans" in
+none) ans='';
+esac
+ccflags="$ans"
+
+case "$ldflags" in
+'') if venix; then
+ dflt='-i -z'
+ elif xenix; then
+ if test -f /usr/include/dirent.h; then
+ dflt='-ldir -lx'
+ else
+ dflt='-lx'
+ fi
+ else
+ dflt='none'
+ fi
+ ;;
+*) dflt="$ldflags";;
+esac
+echo " "
+rp="Any additional ld flags? [$dflt]"
+$echo $n "$rp $c"
+. myread
+case "$ans" in
+none) ans='';
+esac
+ldflags="$ans"
+
+: see if we need a special compiler
+echo " "
+if usg; then
+ case "$cc" in
+ '')
+ case "$Mcc" in
+ /*) dflt='Mcc'
+ ;;
+ *)
+ case "$large" in
+ -M*)
+ dflt='cc'
+ ;;
+ *)
+ if $contains '\-M' $mansrc/cc.1 >/dev/null 2>&1 ; then
+ dflt='cc -M'
+ else
+ dflt='cc'
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ *) dflt="$cc";;
+ esac
+ $cat <<'EOM'
+
+On some systems the default C compiler will not resolve multiple global
+references that happen to have the same name. On some such systems the
+"Mcc" command may be used to force these to be resolved. On other systems
+a "cc -M" command is required. (Note that the -M flag on other systems
+indicates a memory model to use!) What command will force resolution on
+EOM
+ $echo $n "this system? [$dflt] $c"
+ rp="Command to resolve multiple refs? [$dflt]"
+ . myread
+ cc="$ans"
+else
+ echo "Not a USG system--assuming cc can resolve multiple definitions."
+ cc=cc
+fi
+
+echo " "
+echo "End of configuration questions."
+echo " "
+
+: create config.sh file
+echo " "
+if test -d ../UU; then
+ cd ..
+fi
+echo "Creating config.sh..."
+$spitshell <<EOT >config.sh
+$startsh
+# config.sh
+# This file was produced by running the Configure script.
+
+d_eunice='$d_eunice'
+eunicefix='$eunicefix'
+define='$define'
+loclist='$loclist'
+expr='$expr'
+sed='$sed'
+echo='$echo'
+cat='$cat'
+rm='$rm'
+mv='$mv'
+cp='$cp'
+tail='$tail'
+tr='$tr'
+mkdir='$mkdir'
+sort='$sort'
+uniq='$uniq'
+grep='$grep'
+trylist='$trylist'
+test='$test'
+inews='$inews'
+egrep='$egrep'
+more='$more'
+pg='$pg'
+Mcc='$Mcc'
+vi='$vi'
+mailx='$mailx'
+mail='$mail'
+cpp='$cpp'
+Log='$Log'
+Header='$Header'
+bin='$bin'
+cc='$cc'
+contains='$contains'
+cppstdin='$cppstdin'
+cppminus='$cppminus'
+d_charsprf='$d_charsprf'
+d_flexfnam='$d_flexfnam'
+d_index='$d_index'
+d_voidsig='$d_voidsig'
+d_dirheader='$d_dirheader'
+d_unistd='$d_unistd'
+libc='$libc'
+mansrc='$mansrc'
+manext='$manext'
+models='$models'
+split='$split'
+small='$small'
+medium='$medium'
+large='$large'
+huge='$huge'
+ccflags='$ccflags'
+ldflags='$ldflags'
+n='$n'
+c='$c'
+package='$package'
+registers='$registers'
+reg1='$reg1'
+reg2='$reg2'
+reg3='$reg3'
+reg4='$reg4'
+reg5='$reg5'
+reg6='$reg6'
+reg7='$reg7'
+reg8='$reg8'
+reg9='$reg9'
+reg10='$reg10'
+reg11='$reg11'
+reg12='$reg12'
+reg13='$reg13'
+reg14='$reg14'
+reg15='$reg15'
+reg16='$reg16'
+spitshell='$spitshell'
+shsharp='$shsharp'
+sharpbang='$sharpbang'
+startsh='$startsh'
+voidflags='$voidflags'
+defvoidused='$defvoidused'
+CONFIG=true
+EOT
+
+CONFIG=true
+
+echo " "
+dflt=''
+fastread=''
+echo "If you didn't make any mistakes, then just type a carriage return here."
+rp="If you need to edit config.sh, do it as a shell escape here:"
+$echo $n "$rp $c"
+. UU/myread
+case "$ans" in
+'') ;;
+*) : in case they cannot read
+ eval $ans;;
+esac
+. ./config.sh
+
+echo " "
+echo "Doing variable substitutions on .SH files..."
+set x `awk '{print $1}' <MANIFEST | $grep '\.SH'`
+shift
+case $# in
+0) set x *.SH; shift;;
+esac
+if test ! -f $1; then
+ shift
+fi
+for file in $*; do
+ case "$file" in
+ */*)
+ dir=`$expr X$file : 'X\(.*\)/'`
+ file=`$expr X$file : 'X.*/\(.*\)'`
+ (cd $dir && . $file)
+ ;;
+ *)
+ . $file
+ ;;
+ esac
+done
+if test -f config.h.SH; then
+ if test ! -f config.h; then
+ : oops, they left it out of MANIFEST, probably, so do it anyway.
+ . config.h.SH
+ fi
+fi
+
+if $contains '^depend:' Makefile >/dev/null 2>&1; then
+ dflt=n
+ $cat <<EOM
+
+Now you need to generate make dependencies by running "make depend".
+You might prefer to run it in background: "make depend > makedepend.out &"
+It can take a while, so you might not want to run it right now.
+
+EOM
+ rp="Run make depend now? [$dflt]"
+ $echo $n "$rp $c"
+ . UU/myread
+ case "$ans" in
+ y*) make depend
+ echo "Now you must run a make."
+ ;;
+ *) echo "You must run 'make depend' then 'make'."
+ ;;
+ esac
+elif test -f Makefile; then
+ echo " "
+ echo "Now you must run a make."
+else
+ echo "Done."
+fi
+
+$rm -f kit*isdone
+: the following is currently useless
+cd UU && $rm -f $rmlist
+: since this removes it all anyway
+cd .. && $rm -rf UU
+: end of Configure
diff --git a/xc/util/patch/EXTERN.h b/xc/util/patch/EXTERN.h
new file mode 100644
index 000000000..1f0a6da23
--- /dev/null
+++ b/xc/util/patch/EXTERN.h
@@ -0,0 +1,21 @@
+/* oldHeader: EXTERN.h,v 2.0 86/09/17 15:35:37 lwall Exp $
+ * $XConsortium: EXTERN.h,v 2.1 94/09/09 20:04:44 gildea Exp $
+ *
+ * Revision 2.0 86/09/17 15:35:37 lwall
+ * Baseline for netwide release.
+ *
+ */
+
+#ifdef EXT
+#undef EXT
+#endif
+#define EXT extern
+
+#ifdef INIT
+#undef INIT
+#endif
+#define INIT(x)
+
+#ifdef DOINIT
+#undef DOINIT
+#endif
diff --git a/xc/util/patch/INTERN.h b/xc/util/patch/INTERN.h
new file mode 100644
index 000000000..abaa57adf
--- /dev/null
+++ b/xc/util/patch/INTERN.h
@@ -0,0 +1,19 @@
+/* oldHeader: INTERN.h,v 2.0 86/09/17 15:35:58 lwall Exp $
+ * $XConsortium: INTERN.h,v 2.1 94/09/09 20:08:54 gildea Exp $
+ *
+ * Revision 2.0 86/09/17 15:35:58 lwall
+ * Baseline for netwide release.
+ *
+ */
+
+#ifdef EXT
+#undef EXT
+#endif
+#define EXT
+
+#ifdef INIT
+#undef INIT
+#endif
+#define INIT(x) = x
+
+#define DOINIT
diff --git a/xc/util/patch/MANIFEST b/xc/util/patch/MANIFEST
new file mode 100644
index 000000000..05fc9417c
--- /dev/null
+++ b/xc/util/patch/MANIFEST
@@ -0,0 +1,27 @@
+After all the patch kits are run you should have the following files:
+
+Filename Kit Description
+-------- --- -----------
+Configure 1 A shell script that installs everything system dependent.
+EXTERN.h 4 Toggle .h files to look foreign.
+INTERN.h 4 Toggle .h files to look domestic.
+MANIFEST 2 This list of files.
+Makefile.SH 2 The makefile.
+README 1 Installation instructions.
+backupfile.c 4 Make Emacs style backup file names.
+backupfile.h 4 Declarations to make Emacs style backup file names.
+common.h 3 Common definitions.
+config.H 4 Sample config.h, in case Configure won't run.
+config.h.SH 3 Produces config.h.
+inp.c 3 Input file abstract data type routines.
+inp.h 3 Public defs for above.
+malloc.c 1 An optional malloc package.
+patch.c 3 The patch program.
+patch.man 2 Manual page for patch.
+patchlevel.h 4 The patch level of the patch program.
+pch.c 2 Patch abstract data type routines.
+pch.h 3 Public defs for above.
+util.c 3 Utility routines.
+util.h 3 Public defs for above.
+version.c 1 Version number routine.
+version.h 4 Public defs for above.
diff --git a/xc/util/patch/Makefile.SH b/xc/util/patch/Makefile.SH
new file mode 100644
index 000000000..ab5d049fd
--- /dev/null
+++ b/xc/util/patch/Makefile.SH
@@ -0,0 +1,116 @@
+case $CONFIG in
+ '') . config.sh ;;
+esac
+echo "Extracting Makefile (with variable substitutions)"
+cat >Makefile <<!GROK!THIS!
+# oldHeader: Makefile.SH,v 2.0.1.2 88/06/22 20:43:40 lwall Locked $
+# $XConsortium: Makefile.SH,v 3.1 94/09/09 20:04:28 gildea Exp $
+#
+# Revision 2.0.1.2 88/06/22 20:43:40 lwall
+# patch12: config.h now depends on config.h.SH
+#
+# Revision 2.0.1.1 88/06/03 15:00:48 lwall
+# patch10: upgraded to match some new metaconfig stuff
+#
+# Revision 2.0 86/09/17 15:36:15 lwall
+# Baseline for netwide release.
+#
+# Revision 1.2 86/09/08 14:07:42 lwall
+# Split up patch.c.
+#
+# Revision 1.1 86/08/01 20:18:35 lwall
+# Initial revision
+#
+
+CC = $cc
+bin = $bin
+mansrc = $mansrc
+manext = $manext
+CFLAGS = $ccflags -O
+LDFLAGS = $ldflags
+SMALL = $small
+LARGE = $large $split
+
+!GROK!THIS!
+cat >>Makefile <<'!NO!SUBS!'
+
+public = patch
+private =
+manpages = patch.man
+util = Makefile
+
+c = patch.c pch.c inp.c util.c version.c backupfile.c
+
+obj = patch.o pch.o inp.o util.o version.o backupfile.o
+
+lintflags = -phbvxac
+
+addedbyconf = Makefile Makefile.old bsd config.h config.sh eunice loc pdp11 usg v7
+
+# grrr
+SHELL = /bin/sh
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(LARGE) $*.c
+
+all: $(public) $(private) $(util)
+ @echo Done.
+
+patch: $(obj)
+ $(CC) $(LDFLAGS) $(obj) $(libs) -o patch
+
+config.h: config.h.SH
+ sh config.h.SH
+
+# won't work with csh
+install: patch
+ export PATH || exit 1
+ -mv $(bin)/patch $(bin)/patch.old
+ cp patch $(bin)/patch
+ chmod 755 $(bin)/patch
+ -cp patch.man $(mansrc)/patch.$(manext)
+
+uninstall:
+ rm -f $(bin)/patch $(mansrc)/patch.$(manext)
+ test ! -f $(bin)/patch.old || mv $(bin)/patch.old $(bin)/patch
+
+clean:
+ rm -f patch *.o core
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f $(addedbyconf)
+
+realclean: distclean
+
+DISTFILES=ChangeLog Configure EXTERN.h INTERN.h MANIFEST Makefile.SH \
+README common.h config.H config.h.SH inp.c inp.h malloc.c patch.c patch.man \
+patchlevel.h pch.c pch.h util.c util.h version.c version.h backupfile.c \
+backupfile.h
+
+dist: $(DISTFILES)
+ echo patch-2.0.`sed -e '/PATCHLEVEL/!d' -e 's/[^0-9]*\([0-9a-z.]*\).*/\1/' -e q patchlevel.h` > .fname
+ rm -rf `cat .fname`
+ mkdir `cat .fname`
+ ln $(DISTFILES) `cat .fname`
+ tar chZf `cat .fname`.tar.Z `cat .fname`
+ rm -rf `cat .fname` .fname
+
+# The following lint has practically everything turned on. Unfortunately,
+# you have to wade through a lot of mumbo jumbo that can't be suppressed.
+# If the source file has a /*NOSTRICT*/ somewhere, ignore the lint message
+# for that spot.
+
+lint:
+ lint $(lintflags) $(defs) $(c) > patch.fuzz
+
+patch.o: config.h common.h patch.c inp.h pch.h util.h version.h backupfile.h
+pch.o: config.h common.h pch.c pch.h util.h
+inp.o: config.h common.h inp.c inp.h util.h
+util.o: config.h common.h util.c util.h backupfile.h
+version.o: config.h common.h version.c version.h patchlevel.h util.h
+backupfile.o: config.h backupfile.c backupfile.h
+
+!NO!SUBS!
+$eunicefix Makefile
diff --git a/xc/util/patch/Makefile.nt b/xc/util/patch/Makefile.nt
new file mode 100644
index 000000000..34c9df897
--- /dev/null
+++ b/xc/util/patch/Makefile.nt
@@ -0,0 +1,41 @@
+# $XConsortium: Makefile.nt,v 1.2 94/09/12 20:19:31 kaleb Exp $
+
+# Simple Makefile for MS Windows NT.
+
+CC = cl
+
+LIBS = crtdll.lib kernel32.lib
+
+CFLAGS = -Zi -Od -DWIN32 -D_DLL -D_MT -D__STDC__ -DX_86_ -nologo
+LDFLAGS = -link -debug:full -debugtype:cv
+
+SRCS = backupfile.c getopt.c getopt1.c inp.c patch.c pch.c util.c \
+ version.c
+
+OBJS = backupfile.obj getopt.obj getopt1.obj inp.obj patch.obj pch.obj \
+ util.obj version.obj
+
+HDRS = EXTERN.h INTERN.h backupfile.h common.h getopt.h \
+ inp.h patchlevel.h pch.h util.h version.h
+
+all: patch.exe
+
+patch.exe: $(OBJS)
+ $(CC) $(OBJS) $(LIBS) -o $@ $(LDFLAGS)
+
+.c.obj:
+ if exist $@ del $@
+ $(CC) -c -DHAVE_CONFIG_H -I. $(CPPFLAGS) $(CFLAGS) $<
+
+clean:
+ rm -f patch.exe *.obj
+
+backupfile.obj: $(HDRS)
+getopt.obj: $(HDRS)
+getopt1.obj: $(HDRS)
+inp.obj: $(HDRS)
+patch.obj: $(HDRS)
+pch.obj: $(HDRS)
+util.obj: $(HDRS)
+version.obj: $(HDRS)
+
diff --git a/xc/util/patch/README b/xc/util/patch/README
new file mode 100644
index 000000000..c8bd0e9c4
--- /dev/null
+++ b/xc/util/patch/README
@@ -0,0 +1,98 @@
+This version of patch contains modifications made by the Free Software
+Foundation, summarized in the file ChangeLog. Primarily they are to
+support the unified context diff format that GNU diff can produce, and
+to support making GNU Emacs-style backup files. They also include
+fixes for some bugs.
+
+There are two GNU variants of patch: this one, which retains Larry
+Wall's interactive Configure script and has patchlevels starting with
+`12u'; and another one that has a GNU-style non-interactive configure
+script and accepts long-named options, and has patchlevels starting
+with `12g'. Unlike the 12g variant, the 12u variant contains no
+copylefted code, for the paranoid. The two variants are otherwise the
+same. They should be available from the same places.
+
+The FSF is distributing this version of patch independently because as
+of this writing, Larry Wall has not released a new version of patch
+since mid-1988. I have heard that he has been too busy working on
+other things, like Perl.
+
+Here is a wish list of some projects to improve patch:
+
+1. Correctly handle files and patchfiles that contain NUL characters.
+This is hard to do straightforwardly; it would be less work to
+adopt a kind of escape encoding internally.
+Let ESC be a "control prefix". ESC @ stands for NUL. ESC [ stands for ESC.
+You need to crunch this when reading input (replace fgets),
+and when writing the output file (replace fputs),
+but otherwise everything can go along as it does now.
+Be careful to handle reject files correctly;
+I think they are currently created using `write', not `fputs'.
+
+2. Correctly handle patches produced by GNU diff for files that do
+not end with a newline.
+
+Please send bug reports for this version of patch to
+bug-gnu-utils@prep.ai.mit.edu as well as to Larry Wall (lwall@netlabs.com).
+ --djm@gnu.ai.mit.edu (David MacKenzie)
+
+ Patch Kit, Version 2.0
+
+ Copyright (c) 1988, Larry Wall
+
+You may copy the patch kit in whole or in part as long as you don't try to
+make money off it, or pretend that you wrote it.
+--------------------------------------------------------------------------
+
+Please read all the directions below before you proceed any further, and
+then follow them carefully. Failure to do so may void your warranty. :-)
+
+After you have unpacked your kit, you should have all the files listed
+in MANIFEST.
+
+Installation
+
+1) Run Configure. This will figure out various things about your system.
+ Some things Configure will figure out for itself, other things it will
+ ask you about. It will then proceed to make config.h, config.sh, and
+ Makefile.
+
+ You might possibly have to trim # comments from the front of Configure
+ if your sh doesn't handle them, but all other # comments will be taken
+ care of.
+
+ If you don't have sh, you'll have to rip the prototype of config.h out
+ of Configure and generate the defines by hand.
+
+2) Glance through config.h to make sure system dependencies are correct.
+ Most of them should have been taken care of by running the
+ Configure script.
+
+ If you have any additional changes to make to the C definitions, they
+ can be done in the Makefile, or in config.h. Bear in mind that they may
+ get undone next time you run Configure.
+
+3) make
+
+ This will attempt to make patch in the current directory.
+
+4) make install
+
+ This will put patch into a public directory (normally /usr/local/bin).
+ It will also try to put the man pages in a reasonable place. It will not
+ nroff the man page, however.
+
+5) Read the manual entry before running patch.
+
+6) IMPORTANT! Help save the world! Communicate any problems and
+ suggested patches to me, lwall@netlabs.com (Larry Wall),
+ so we can keep the world in sync. If you have a problem, there's
+ someone else out there who either has had or will have the same problem.
+
+ If possible, send in patches such that the patch program will apply them.
+ Context diffs are the best, then normal diffs. Don't send ed scripts--
+ I've probably changed my copy since the version you have.
+
+ Watch for patch patches in comp.sources.bugs. Patches will generally be
+ in a form usable by the patch program. Your current patch level
+ is shown in patchlevel.h.
diff --git a/xc/util/patch/backupfile.c b/xc/util/patch/backupfile.c
new file mode 100644
index 000000000..d3862e336
--- /dev/null
+++ b/xc/util/patch/backupfile.c
@@ -0,0 +1,340 @@
+/* backupfile.c -- make Emacs style backup file names
+ Copyright (C) 1990 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it without restriction.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */
+
+/* $XConsortium: backupfile.c,v 3.1 94/09/09 20:33:43 kaleb Exp $ */
+
+/* David MacKenzie <djm@ai.mit.edu>.
+ Some algorithms adapted from GNU Emacs. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include "backupfile.h"
+#include "config.h"
+char *index ();
+char *rindex ();
+char *malloc ();
+
+#ifdef DIRENT
+#include <dirent.h>
+#ifdef direct
+#undef direct
+#endif
+#define direct dirent
+#define NLENGTH(direct) (strlen((direct)->d_name))
+#else /* !DIRENT */
+#define NLENGTH(direct) ((direct)->d_namlen)
+#ifdef USG
+#ifdef SYSNDIR
+#include <sys/ndir.h>
+#else /* !SYSNDIR */
+#include <ndir.h>
+#endif /* !SYSNDIR */
+#else /* !USG */
+#ifdef SYSDIR
+#include <sys/dir.h>
+#endif /* SYSDIR */
+#endif /* !USG */
+#endif /* !DIRENT */
+
+#ifndef isascii
+#define ISDIGIT(c) (isdigit ((unsigned char) (c)))
+#else
+#define ISDIGIT(c) (isascii (c) && isdigit (c))
+#endif
+
+#if defined (HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+
+#if defined (_POSIX_VERSION)
+/* POSIX does not require that the d_ino field be present, and some
+ systems do not provide it. */
+#define REAL_DIR_ENTRY(dp) 1
+#else
+#define REAL_DIR_ENTRY(dp) ((dp)->d_ino != 0)
+#endif
+
+/* Which type of backup file names are generated. */
+enum backup_type backup_type = none;
+
+/* The extension added to file names to produce a simple (as opposed
+ to numbered) backup file name. */
+char *simple_backup_suffix = "~";
+
+char *basename ();
+char *dirname ();
+static char *concat ();
+char *find_backup_file_name ();
+static char *make_version_name ();
+static int max_backup_version ();
+static int version_number ();
+
+/* Return NAME with any leading path stripped off. */
+
+char *
+basename (name)
+ char *name;
+{
+ char *base;
+
+ base = rindex (name, '/');
+ return base ? base + 1 : name;
+}
+
+#ifndef NODIR
+/* Return the name of the new backup file for file FILE,
+ allocated with malloc. Return 0 if out of memory.
+ FILE must not end with a '/' unless it is the root directory.
+ Do not call this function if backup_type == none. */
+
+char *
+find_backup_file_name (file)
+ char *file;
+{
+ char *dir;
+ char *base_versions;
+ int highest_backup;
+
+ if (backup_type == simple)
+ return concat (file, simple_backup_suffix);
+ base_versions = concat (basename (file), ".~");
+ if (base_versions == 0)
+ return 0;
+ dir = dirname (file);
+ if (dir == 0)
+ {
+ free (base_versions);
+ return 0;
+ }
+ highest_backup = max_backup_version (base_versions, dir);
+ free (base_versions);
+ free (dir);
+ if (backup_type == numbered_existing && highest_backup == 0)
+ return concat (file, simple_backup_suffix);
+ return make_version_name (file, highest_backup + 1);
+}
+
+/* Return the number of the highest-numbered backup file for file
+ FILE in directory DIR. If there are no numbered backups
+ of FILE in DIR, or an error occurs reading DIR, return 0.
+ FILE should already have ".~" appended to it. */
+
+static int
+max_backup_version (file, dir)
+ char *file, *dir;
+{
+ DIR *dirp;
+ struct direct *dp;
+ int highest_version;
+ int this_version;
+ int file_name_length;
+
+ dirp = opendir (dir);
+ if (!dirp)
+ return 0;
+
+ highest_version = 0;
+ file_name_length = strlen (file);
+
+ while ((dp = readdir (dirp)) != 0)
+ {
+ if (!REAL_DIR_ENTRY (dp) || NLENGTH (dp) <= file_name_length)
+ continue;
+
+ this_version = version_number (file, dp->d_name, file_name_length);
+ if (this_version > highest_version)
+ highest_version = this_version;
+ }
+ closedir (dirp);
+ return highest_version;
+}
+
+/* Return a string, allocated with malloc, containing
+ "FILE.~VERSION~". Return 0 if out of memory. */
+
+static char *
+make_version_name (file, version)
+ char *file;
+ int version;
+{
+ char *backup_name;
+
+ backup_name = malloc (strlen (file) + 16);
+ if (backup_name == 0)
+ return 0;
+ sprintf (backup_name, "%s.~%d~", file, version);
+ return backup_name;
+}
+
+/* If BACKUP is a numbered backup of BASE, return its version number;
+ otherwise return 0. BASE_LENGTH is the length of BASE.
+ BASE should already have ".~" appended to it. */
+
+static int
+version_number (base, backup, base_length)
+ char *base;
+ char *backup;
+ int base_length;
+{
+ int version;
+ char *p;
+
+ version = 0;
+ if (!strncmp (base, backup, base_length) && ISDIGIT (backup[base_length]))
+ {
+ for (p = &backup[base_length]; ISDIGIT (*p); ++p)
+ version = version * 10 + *p - '0';
+ if (p[0] != '~' || p[1])
+ version = 0;
+ }
+ return version;
+}
+
+/* Return the newly-allocated concatenation of STR1 and STR2.
+ If out of memory, return 0. */
+
+static char *
+concat (str1, str2)
+ char *str1, *str2;
+{
+ char *newstr;
+ char str1_length = strlen (str1);
+
+ newstr = malloc (str1_length + strlen (str2) + 1);
+ if (newstr == 0)
+ return 0;
+ strcpy (newstr, str1);
+ strcpy (newstr + str1_length, str2);
+ return newstr;
+}
+
+/* Return the leading directories part of PATH,
+ allocated with malloc. If out of memory, return 0.
+ Assumes that trailing slashes have already been
+ removed. */
+
+char *
+dirname (path)
+ char *path;
+{
+ char *newpath;
+ char *slash;
+ int length; /* Length of result, not including NUL. */
+
+ slash = rindex (path, '/');
+ if (slash == 0)
+ {
+ /* File is in the current directory. */
+ path = ".";
+ length = 1;
+ }
+ else
+ {
+ /* Remove any trailing slashes from result. */
+ while (slash > path && *slash == '/')
+ --slash;
+
+ length = slash - path + 1;
+ }
+ newpath = malloc (length + 1);
+ if (newpath == 0)
+ return 0;
+ strncpy (newpath, path, length);
+ newpath[length] = 0;
+ return newpath;
+}
+
+/* If ARG is an unambiguous match for an element of the
+ null-terminated array OPTLIST, return the index in OPTLIST
+ of the matched element, else -1 if it does not match any element
+ or -2 if it is ambiguous (is a prefix of more than one element). */
+
+int
+argmatch (arg, optlist)
+ char *arg;
+ char **optlist;
+{
+ int i; /* Temporary index in OPTLIST. */
+ int arglen; /* Length of ARG. */
+ int matchind = -1; /* Index of first nonexact match. */
+ int ambiguous = 0; /* If nonzero, multiple nonexact match(es). */
+
+ arglen = strlen (arg);
+
+ /* Test all elements for either exact match or abbreviated matches. */
+ for (i = 0; optlist[i]; i++)
+ {
+ if (!strncmp (optlist[i], arg, arglen))
+ {
+ if (strlen (optlist[i]) == arglen)
+ /* Exact match found. */
+ return i;
+ else if (matchind == -1)
+ /* First nonexact match found. */
+ matchind = i;
+ else
+ /* Second nonexact match found. */
+ ambiguous = 1;
+ }
+ }
+ if (ambiguous)
+ return -2;
+ else
+ return matchind;
+}
+
+/* Error reporting for argmatch.
+ KIND is a description of the type of entity that was being matched.
+ VALUE is the invalid value that was given.
+ PROBLEM is the return value from argmatch. */
+
+void
+invalid_arg (kind, value, problem)
+ char *kind;
+ char *value;
+ int problem;
+{
+ fprintf (stderr, "patch: ");
+ if (problem == -1)
+ fprintf (stderr, "invalid");
+ else /* Assume -2. */
+ fprintf (stderr, "ambiguous");
+ fprintf (stderr, " %s `%s'\n", kind, value);
+}
+
+static char *backup_args[] =
+{
+ "never", "simple", "nil", "existing", "t", "numbered", 0
+};
+
+static enum backup_type backup_types[] =
+{
+ simple, simple, numbered_existing, numbered_existing, numbered, numbered
+};
+
+/* Return the type of backup indicated by VERSION.
+ Unique abbreviations are accepted. */
+
+enum backup_type
+get_version (version)
+ char *version;
+{
+ int i;
+
+ if (version == 0 || *version == 0)
+ return numbered_existing;
+ i = argmatch (version, backup_args);
+ if (i >= 0)
+ return backup_types[i];
+ invalid_arg ("version control type", version, i);
+ exit (1);
+}
+#endif /* NODIR */
diff --git a/xc/util/patch/backupfile.h b/xc/util/patch/backupfile.h
new file mode 100644
index 000000000..43240a130
--- /dev/null
+++ b/xc/util/patch/backupfile.h
@@ -0,0 +1,37 @@
+/* backupfile.h -- declarations for making Emacs style backup file names
+ Copyright (C) 1990 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it without restriction.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */
+
+/* When to make backup files. */
+enum backup_type
+{
+ /* Never make backups. */
+ none,
+
+ /* Make simple backups of every file. */
+ simple,
+
+ /* Make numbered backups of files that already have numbered backups,
+ and simple backups of the others. */
+ numbered_existing,
+
+ /* Make numbered backups of every file. */
+ numbered
+};
+
+extern enum backup_type backup_type;
+extern char *simple_backup_suffix;
+
+#ifdef __STDC__
+char *find_backup_file_name (char *file);
+enum backup_type get_version (char *version);
+#else
+char *find_backup_file_name ();
+enum backup_type get_version ();
+#endif
diff --git a/xc/util/patch/common.h b/xc/util/patch/common.h
new file mode 100644
index 000000000..7209d6f90
--- /dev/null
+++ b/xc/util/patch/common.h
@@ -0,0 +1,214 @@
+/* oldHeader: common.h,v 2.0.1.2 88/06/22 20:44:53 lwall Locked $
+ * $XConsortium: common.h,v 3.3 94/09/14 21:13:08 gildea Exp $
+ *
+ * Revision 2.0.1.2 88/06/22 20:44:53 lwall
+ * patch12: sprintf was declared wrong
+ *
+ * Revision 2.0.1.1 88/06/03 15:01:56 lwall
+ * patch10: support for shorter extensions.
+ *
+ * Revision 2.0 86/09/17 15:36:39 lwall
+ * Baseline for netwide release.
+ *
+ */
+
+#define DEBUGGING
+
+#define VOIDUSED 7
+#include "config.h"
+
+/* shut lint up about the following when return value ignored */
+
+#define Signal (void)signal
+#define Unlink (void)unlink
+#define Lseek (void)lseek
+#define Fseek (void)fseek
+#define Fstat (void)fstat
+#define Pclose (void)pclose
+#define Close (void)close
+#define Fclose (void)fclose
+#define Fflush (void)fflush
+#define Sprintf (void)sprintf
+#define Mktemp (void)mktemp
+#define Strcpy (void)strcpy
+#define Strcat (void)strcat
+
+/* NeXT declares malloc and realloc incompatibly from us in some of
+ these files. Temporarily redefine them to prevent errors. */
+#define malloc system_malloc
+#define realloc system_realloc
+#include <stdio.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <signal.h>
+#include <fcntl.h>
+#undef malloc
+#undef realloc
+
+#ifdef WIN32
+#include "winnt.h"
+#endif
+
+/* constants */
+
+/* AIX predefines these. */
+#ifdef TRUE
+#undef TRUE
+#endif
+#ifdef FALSE
+#undef FALSE
+#endif
+#define TRUE (1)
+#define FALSE (0)
+
+#define MAXHUNKSIZE 100000 /* is this enough lines? */
+#define INITHUNKMAX 125 /* initial dynamic allocation size */
+#define MAXLINELEN 1024
+#define BUFFERSIZE 1024
+
+#define SCCSPREFIX "s."
+#define GET "get %s"
+#define GET_LOCKED "get -e %s"
+#define SCCSDIFF "get -p %s | diff - %s >/dev/null"
+
+#define RCSSUFFIX ",v"
+#define CHECKOUT "co %s"
+#define CHECKOUT_LOCKED "co -l %s"
+#define RCSDIFF "rcsdiff %s > /dev/null"
+
+#ifdef FLEXFILENAMES
+#define ORIGEXT ".orig"
+#define REJEXT ".rej"
+#else
+#define ORIGEXT "~"
+#define REJEXT "#"
+#endif
+
+/* handy definitions */
+
+#define Null(t) ((t)0)
+#define Nullch Null(char *)
+#define Nullfp Null(FILE *)
+#define Nulline Null(LINENUM)
+
+#define Ctl(ch) ((ch) & 037)
+
+#define strNE(s1,s2) (strcmp(s1, s2))
+#define strEQ(s1,s2) (!strcmp(s1, s2))
+#define strnNE(s1,s2,l) (strncmp(s1, s2, l))
+#define strnEQ(s1,s2,l) (!strncmp(s1, s2, l))
+
+/* typedefs */
+
+typedef char bool;
+typedef long LINENUM; /* must be signed */
+typedef unsigned MEM; /* what to feed malloc */
+
+/* globals */
+
+EXT int Argc; /* guess */
+EXT char **Argv;
+EXT int Argc_last; /* for restarting plan_b */
+EXT char **Argv_last;
+
+EXT struct stat filestat; /* file statistics area */
+EXT int filemode INIT(0644);
+
+EXT char buf[MAXLINELEN]; /* general purpose buffer */
+EXT FILE *ofp INIT(Nullfp); /* output file pointer */
+EXT FILE *rejfp INIT(Nullfp); /* reject file pointer */
+
+#ifndef WIN32
+EXT int myuid; /* cache getuid return value */
+#endif
+
+EXT bool using_plan_a INIT(TRUE); /* try to keep everything in memory */
+EXT bool out_of_mem INIT(FALSE); /* ran out of memory in plan a */
+
+#define MAXFILEC 2
+EXT int filec INIT(0); /* how many file arguments? */
+EXT char *filearg[MAXFILEC];
+EXT bool ok_to_create_file INIT(FALSE);
+EXT char *bestguess INIT(Nullch); /* guess at correct filename */
+
+EXT char *outname INIT(Nullch);
+EXT char rejname[128];
+
+EXT char *origprae INIT(Nullch);
+
+EXT char *TMPOUTNAME;
+EXT char *TMPINNAME;
+EXT char *TMPREJNAME;
+EXT char *TMPPATNAME;
+EXT bool toutkeep INIT(FALSE);
+EXT bool trejkeep INIT(FALSE);
+
+EXT LINENUM last_offset INIT(0);
+#ifdef DEBUGGING
+EXT int debug INIT(0);
+#endif
+EXT LINENUM maxfuzz INIT(2);
+EXT bool force INIT(FALSE);
+EXT bool batch INIT(FALSE);
+EXT bool verbose INIT(TRUE);
+EXT bool reverse INIT(FALSE);
+EXT bool noreverse INIT(FALSE);
+EXT bool skip_rest_of_patch INIT(FALSE);
+EXT int strippath INIT(957);
+EXT bool canonicalize INIT(FALSE);
+
+#define CONTEXT_DIFF 1
+#define NORMAL_DIFF 2
+#define ED_DIFF 3
+#define NEW_CONTEXT_DIFF 4
+#define UNI_DIFF 5
+EXT int diff_type INIT(0);
+
+EXT bool do_defines INIT(FALSE); /* patch using ifdef, ifndef, etc. */
+EXT char if_defined[128]; /* #ifdef xyzzy */
+EXT char not_defined[128]; /* #ifndef xyzzy */
+EXT char else_defined[] INIT("#else\n");/* #else */
+EXT char end_defined[128]; /* #endif xyzzy */
+
+EXT char *revision INIT(Nullch); /* prerequisite revision, if any */
+
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+
+FILE *popen();
+char *malloc();
+char *realloc();
+long atol();
+char *getenv();
+char *strcpy();
+char *strcat();
+char *rindex();
+#if 0
+long lseek();
+#endif
+char *mktemp();
+#if 0 /* This can cause a prototype conflict. */
+#ifdef CHARSPRINTF
+char *sprintf();
+#else
+int sprintf();
+#endif
+#endif
+
+#ifndef WIN32
+#if !defined(S_ISDIR) && defined(S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+#if !defined(S_ISREG) && defined(S_IFREG)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+#else
+#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
+#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
+#endif
+
+
diff --git a/xc/util/patch/config.H b/xc/util/patch/config.H
new file mode 100644
index 000000000..93cdf0327
--- /dev/null
+++ b/xc/util/patch/config.H
@@ -0,0 +1,33 @@
+/* config.h
+ * This file was produced by running the Configure script.
+ * Feel free to modify any of this as the need arises.
+ */
+
+
+#/*undef EUNICE /* no file linking? */
+#/*undef VMS
+
+#/*undef index strchr /* cultural */
+#/*undef rindex strrchr /* differences? */
+
+#/*undef void int /* is void to be avoided? */
+
+/* How many register declarations are paid attention to? */
+
+#define Reg1 register
+#define Reg2 register
+#define Reg3 register
+#define Reg4 register
+#define Reg5 register
+#define Reg6 register
+#define Reg7
+#define Reg8
+#define Reg9
+#define Reg10
+#define Reg11
+#define Reg12
+#define Reg13
+#define Reg14
+#define Reg15
+#define Reg16
+
diff --git a/xc/util/patch/config.h.SH b/xc/util/patch/config.h.SH
new file mode 100644
index 000000000..e34562fcc
--- /dev/null
+++ b/xc/util/patch/config.h.SH
@@ -0,0 +1,146 @@
+case $CONFIG in
+'')
+ if test ! -f config.sh; then
+ ln ../config.sh . || \
+ ln ../../config.sh . || \
+ ln ../../../config.sh . || \
+ (echo "Can't find config.sh."; exit 1)
+ echo "Using config.sh from above..."
+ fi
+ . ./config.sh
+ ;;
+esac
+echo "Extracting config.h (with variable substitutions)"
+cat <<!GROK!THIS! >config.h
+/* config.h
+ * This file was produced by running the config.h.SH script, which
+ * gets its values from config.sh, which is generally produced by
+ * running Configure.
+ *
+ * Feel free to modify any of this as the need arises. Note, however,
+ * that running config.h.SH again will wipe out any changes you've made.
+ * For a more permanent change edit config.sh and rerun config.h.SH.
+ */
+
+
+/* EUNICE:
+ * This symbol, if defined, indicates that the program is being compiled
+ * under the EUNICE package under VMS. The program will need to handle
+ * things like files that don't go away the first time you unlink them,
+ * due to version numbering. It will also need to compensate for lack
+ * of a respectable link() command.
+ */
+/* VMS:
+ * This symbol, if defined, indicates that the program is running under
+ * VMS. It is currently only set in conjunction with the EUNICE symbol.
+ */
+#$d_eunice EUNICE /**/
+#$d_eunice VMS /**/
+
+/* CPPSTDIN:
+ * This symbol contains the first part of the string which will invoke
+ * the C preprocessor on the standard input and produce to standard
+ * output. Typical value of "cc -E" or "/lib/cpp".
+ */
+/* CPPMINUS:
+ * This symbol contains the second part of the string which will invoke
+ * the C preprocessor on the standard input and produce to standard
+ * output. This symbol will have the value "-" if CPPSTDIN needs a minus
+ * to specify standard input, otherwise the value is "".
+ */
+#define CPPSTDIN "$cppstdin"
+#define CPPMINUS "$cppminus"
+
+/* CHARSPRINTF:
+ * This symbol is defined if this system declares "char *sprintf()" in
+ * stdio.h. The trend seems to be to declare it as "int sprintf()". It
+ * is up to the package author to declare sprintf correctly based on the
+ * symbol.
+ */
+/* #$d_charsprf CHARSPRINTF /**/
+
+/* FLEXFILENAMES:
+ * This symbol, if defined, indicates that the system supports filenames
+ * longer than 14 characters.
+ */
+#$d_flexfnam FLEXFILENAMES /**/
+
+/* index:
+ * This preprocessor symbol is defined, along with rindex, if the system
+ * uses the strchr and strrchr routines instead.
+ */
+/* rindex:
+ * This preprocessor symbol is defined, along with index, if the system
+ * uses the strchr and strrchr routines instead.
+ */
+#$d_index index strchr /* cultural */
+#$d_index rindex strrchr /* differences? */
+
+/* VOIDSIG:
+ * This symbol is defined if this system declares "void (*signal())()" in
+ * signal.h. The old way was to declare it as "int (*signal())()". It
+ * is up to the package author to declare things correctly based on the
+ * symbol.
+ */
+#$d_voidsig VOIDSIG /**/
+
+/* DIRHEADER:
+ * This definition indicates which directory library header to use.
+ */
+$d_dirheader
+
+/* HAVE_UNISTD_H:
+ * This is defined if the system has unistd.h.
+ */
+#$d_unistd HAVE_UNISTD_H /**/
+
+/* Reg1:
+ * This symbol, along with Reg2, Reg3, etc. is either the word "register"
+ * or null, depending on whether the C compiler pays attention to this
+ * many register declarations. The intent is that you don't have to
+ * order your register declarations in the order of importance, so you
+ * can freely declare register variables in sub-blocks of code and as
+ * function parameters. Do not use Reg<n> more than once per routine.
+ */
+
+#define Reg1 $reg1 /**/
+#define Reg2 $reg2 /**/
+#define Reg3 $reg3 /**/
+#define Reg4 $reg4 /**/
+#define Reg5 $reg5 /**/
+#define Reg6 $reg6 /**/
+#define Reg7 $reg7 /**/
+#define Reg8 $reg8 /**/
+#define Reg9 $reg9 /**/
+#define Reg10 $reg10 /**/
+#define Reg11 $reg11 /**/
+#define Reg12 $reg12 /**/
+#define Reg13 $reg13 /**/
+#define Reg14 $reg14 /**/
+#define Reg15 $reg15 /**/
+#define Reg16 $reg16 /**/
+
+/* VOIDFLAGS:
+ * This symbol indicates how much support of the void type is given by this
+ * compiler. What various bits mean:
+ *
+ * 1 = supports declaration of void
+ * 2 = supports arrays of pointers to functions returning void
+ * 4 = supports comparisons between pointers to void functions and
+ * addresses of void functions
+ *
+ * The package designer should define VOIDUSED to indicate the requirements
+ * of the package. This can be done either by #defining VOIDUSED before
+ * including config.h, or by defining defvoidused in Myinit.U. If the
+ * level of void support necessary is not present, defines void to int.
+ */
+#ifndef VOIDUSED
+#define VOIDUSED $defvoidused
+#endif
+#define VOIDFLAGS $voidflags
+#if (VOIDFLAGS & VOIDUSED) != VOIDUSED
+#$define void int /* is void to be avoided? */
+#$define M_VOID /* Xenix strikes again */
+#endif
+
+!GROK!THIS!
diff --git a/xc/util/patch/config.h.nt b/xc/util/patch/config.h.nt
new file mode 100644
index 000000000..b346523b9
--- /dev/null
+++ b/xc/util/patch/config.h.nt
@@ -0,0 +1,82 @@
+
+/* $XConsortium: config.h.nt,v 1.1 94/09/09 20:26:16 kaleb Exp $ */
+
+/* Portability variables. -*- C -*- */
+
+/* Define if the system does not support the `const' keyword. */
+#undef const
+
+/* Define if the system supports file names longer than 14 characters. */
+#define HAVE_LONG_FILE_NAMES 1
+
+/* Define if the system has pathconf(). */
+#undef HAVE_PATHCONF
+
+/* Define if the system has strerror(). */
+#define HAVE_STRERROR
+
+/* Define if the system has ANSI C header files and library functions. */
+#define STDC_HEADERS
+
+/* Define if the system uses strchr instead of index
+ and strrchr instead of rindex. */
+#define HAVE_STRING_H
+
+#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
+#define index strchr
+#define rindex strrchr
+#endif
+
+/* Define if the system has unistd.h. */
+#undef HAVE_UNISTD_H
+
+/* Define as either int or void -- the type that signal handlers return. */
+#undef RETSIGTYPE
+
+#ifndef RETSIGTYPE
+#define RETSIGTYPE void
+#endif
+
+/* Which directory library header to use. */
+#undef DIRENT /* dirent.h */
+#undef SYSNDIR /* sys/ndir.h */
+#undef SYSDIR /* sys/dir.h */
+#undef NDIR /* ndir.h */
+#define DIRECT /* Windoze NT direct.h */
+#define NODIR /* none -- don't make numbered backup files */
+
+/* Define if the system lets you pass fewer arguments to a function
+ than the function actually accepts (in the absence of a prototype).
+ Defining it makes I/O calls slightly more efficient.
+ You need not bother defining it unless your C preprocessor chokes on
+ multi-line arguments to macros. */
+#undef CANVARARG
+
+/* Define Reg* as either `register' or nothing, depending on whether
+ the C compiler pays attention to this many register declarations.
+ The intent is that you don't have to order your register declarations
+ in the order of importance, so you can freely declare register variables
+ in sub-blocks of code and as function parameters.
+ Do not use Reg<n> more than once per routine.
+
+ These don't really matter a lot, since most modern C compilers ignore
+ register declarations and often do a better job of allocating
+ registers than people do. */
+
+#define Reg1
+#define Reg2
+#define Reg3
+#define Reg4
+#define Reg5
+#define Reg6
+#define Reg7
+#define Reg8
+#define Reg9
+#define Reg10
+#define Reg11
+#define Reg12
+#define Reg13
+#define Reg14
+#define Reg15
+#define Reg16
+
diff --git a/xc/util/patch/inp.c b/xc/util/patch/inp.c
new file mode 100644
index 000000000..20e5709a7
--- /dev/null
+++ b/xc/util/patch/inp.c
@@ -0,0 +1,387 @@
+/* $XConsortium: inp.c,v 3.4 94/09/14 21:18:35 gildea Exp $
+ *
+ * Revision 3.1 94/03/29 13:39:15 gildea
+ * check that a patch that creates a file has not already been applied.
+ * version "XC1"
+ *
+ * Revision 2.0.1.1 88/06/03 15:06:13 lwall
+ * patch10: made a little smarter about sccs files
+ *
+ * Revision 2.0 86/09/17 15:37:02 lwall
+ * Baseline for netwide release.
+ *
+ */
+
+#include "EXTERN.h"
+#include "common.h"
+#include "util.h"
+#include "pch.h"
+#include "INTERN.h"
+#include "inp.h"
+
+/* Input-file-with-indexable-lines abstract type */
+
+static long i_size; /* size of the input file */
+static char *i_womp; /* plan a buffer for entire file */
+static char **i_ptr; /* pointers to lines in i_womp */
+
+static int tifd = -1; /* plan b virtual string array */
+static char *tibuf[2]; /* plan b buffers */
+static LINENUM tiline[2] = {-1, -1}; /* 1st line in each buffer */
+static LINENUM lines_per_buf; /* how many lines per buffer */
+static int tireclen; /* length of records in tmp file */
+
+/* New patch--prepare to edit another file. */
+
+void
+re_input()
+{
+ if (using_plan_a) {
+ i_size = 0;
+#ifndef lint
+ if (i_ptr != Null(char**))
+ free((char *)i_ptr);
+#endif
+ if (i_womp != Nullch)
+ free(i_womp);
+ i_womp = Nullch;
+ i_ptr = Null(char **);
+ }
+ else {
+ using_plan_a = TRUE; /* maybe the next one is smaller */
+ Close(tifd);
+ tifd = -1;
+ free(tibuf[0]);
+ free(tibuf[1]);
+ tibuf[0] = tibuf[1] = Nullch;
+ tiline[0] = tiline[1] = -1;
+ tireclen = 0;
+ }
+}
+
+/* Constuct the line index, somehow or other. */
+
+void
+scan_input(filename)
+char *filename;
+{
+ if (!plan_a(filename))
+ plan_b(filename);
+ if (verbose) {
+ say3("Patching file %s using Plan %s...\n", filename,
+ (using_plan_a ? "A" : "B") );
+ }
+}
+
+/* Try keeping everything in memory. */
+
+bool
+plan_a(filename)
+char *filename;
+{
+ int ifd, statfailed;
+ Reg1 char *s;
+ Reg2 LINENUM iline;
+ char lbuf[MAXLINELEN];
+ int output_elsewhere = strcmp(filename, outname);
+
+ statfailed = stat(filename, &filestat);
+ if (statfailed && ok_to_create_file) {
+ if (verbose)
+ say2("(Creating file %s...)\n",filename);
+ makedirs(filename, TRUE);
+ close(creat(filename, 0666));
+ statfailed = stat(filename, &filestat);
+ } else if (!statfailed && ok_to_create_file) {
+ /* ok_to_create_file means the file either doesn't exist
+ or is zero-length. Since there is no context in the patch,
+ avoid doubling the file if the patch has already been applied
+ by bailing out here if these conditions are not met. */
+ if (filestat.st_size != 0)
+ fatal2("supposedly new file \"%s\" already exists\n", filename);
+ }
+#ifndef WIN32
+ /* For nonexistent or read-only files, look for RCS or SCCS versions. */
+ if (statfailed
+ || (! output_elsewhere
+ && (/* No one can write to it. */
+ (filestat.st_mode & 0222) == 0
+ /* I can't write to it. */
+ || ((filestat.st_mode & 0022) == 0
+ && filestat.st_uid != myuid)))) {
+ struct stat cstat;
+ char *cs = Nullch;
+ char *filebase;
+ int pathlen;
+
+ filebase = basename(filename);
+ pathlen = filebase - filename;
+
+ /* Put any leading path into `s'.
+ Leave room in lbuf for the diff command. */
+ s = lbuf + 20;
+ strncpy(s, filename, pathlen);
+
+#define try(f, a1, a2) (Sprintf(s + pathlen, f, a1, a2), stat(s, &cstat) == 0)
+ if ( try("RCS/%s%s", filebase, RCSSUFFIX)
+ || try("RCS/%s" , filebase, 0)
+ || try( "%s%s", filebase, RCSSUFFIX)) {
+ Sprintf(buf, output_elsewhere?CHECKOUT:CHECKOUT_LOCKED, filename);
+ Sprintf(lbuf, RCSDIFF, filename);
+ cs = "RCS";
+ } else if ( try("SCCS/%s%s", SCCSPREFIX, filebase)
+ || try( "%s%s", SCCSPREFIX, filebase)) {
+ Sprintf(buf, output_elsewhere?GET:GET_LOCKED, s);
+ Sprintf(lbuf, SCCSDIFF, s, filename);
+ cs = "SCCS";
+ } else if (statfailed)
+ fatal2("can't find %s\n", filename);
+ /* else we can't write to it but it's not under a version
+ control system, so just proceed. */
+ if (cs) {
+ if (!statfailed) {
+ if ((filestat.st_mode & 0222) != 0)
+ /* The owner can write to it. */
+ fatal3("file %s seems to be locked by somebody else under %s\n",
+ filename, cs);
+ /* It might be checked out unlocked. See if it's safe to
+ check out the default version locked. */
+ if (verbose)
+ say3("Comparing file %s to default %s version...\n",
+ filename, cs);
+ if (system(lbuf))
+ fatal3("can't check out file %s: differs from default %s version\n",
+ filename, cs);
+ }
+ if (verbose)
+ say3("Checking out file %s from %s...\n", filename, cs);
+ if (system(buf) || stat(filename, &filestat))
+ fatal3("can't check out file %s from %s\n", filename, cs);
+ }
+ }
+#endif
+ filemode = filestat.st_mode;
+ if (!S_ISREG(filemode))
+ fatal2("%s is not a normal file--can't patch\n", filename);
+ i_size = filestat.st_size;
+ if (out_of_mem) {
+ set_hunkmax(); /* make sure dynamic arrays are allocated */
+ out_of_mem = FALSE;
+ return FALSE; /* force plan b because plan a bombed */
+ }
+#ifdef lint
+ i_womp = Nullch;
+#else
+ i_womp = malloc((MEM)(i_size+2)); /* lint says this may alloc less than */
+ /* i_size, but that's okay, I think. */
+#endif
+ if (i_womp == Nullch)
+ return FALSE;
+#ifndef WIN32
+ if ((ifd = open(filename, 0)) < 0)
+#else
+ if ((ifd = open(filename, _O_RDONLY | _O_BINARY)) < 0)
+#endif
+ pfatal2("can't open file %s", filename);
+#ifndef lint
+ if (read(ifd, i_womp, (int)i_size) != i_size) {
+ Close(ifd); /* probably means i_size > 15 or 16 bits worth */
+ free(i_womp); /* at this point it doesn't matter if i_womp was */
+ return FALSE; /* undersized. */
+ }
+#endif
+ Close(ifd);
+ if (i_size && i_womp[i_size-1] != '\n')
+ i_womp[i_size++] = '\n';
+ i_womp[i_size] = '\0';
+
+ /* count the lines in the buffer so we know how many pointers we need */
+
+ iline = 0;
+ for (s=i_womp; *s; s++) {
+ if (*s == '\n')
+ iline++;
+ }
+#ifdef lint
+ i_ptr = Null(char**);
+#else
+ i_ptr = (char **)malloc((MEM)((iline + 2) * sizeof(char *)));
+#endif
+ if (i_ptr == Null(char **)) { /* shucks, it was a near thing */
+ free((char *)i_womp);
+ return FALSE;
+ }
+
+ /* now scan the buffer and build pointer array */
+
+ iline = 1;
+ i_ptr[iline] = i_womp;
+ for (s=i_womp; *s; s++) {
+ if (*s == '\n')
+ i_ptr[++iline] = s+1; /* these are NOT null terminated */
+ }
+ input_lines = iline - 1;
+
+ /* now check for revision, if any */
+
+ if (revision != Nullch) {
+ if (!rev_in_string(i_womp)) {
+ if (force) {
+ if (verbose)
+ say2(
+"Warning: this file doesn't appear to be the %s version--patching anyway.\n",
+ revision);
+ }
+ else if (batch) {
+ fatal2(
+"this file doesn't appear to be the %s version--aborting.\n", revision);
+ }
+ else {
+ ask2(
+"This file doesn't appear to be the %s version--patch anyway? [n] ",
+ revision);
+ if (*buf != 'y')
+ fatal1("aborted\n");
+ }
+ }
+ else if (verbose)
+ say2("Good. This file appears to be the %s version.\n",
+ revision);
+ }
+ return TRUE; /* plan a will work */
+}
+
+/* Keep (virtually) nothing in memory. */
+
+void
+plan_b(filename)
+char *filename;
+{
+ Reg3 FILE *ifp;
+ Reg1 int i = 0;
+ Reg2 int maxlen = 1;
+ Reg4 bool found_revision = (revision == Nullch);
+
+ using_plan_a = FALSE;
+#ifndef WIN32
+ if ((ifp = fopen(filename, "r")) == Nullfp)
+#else
+ if ((ifp = fopen(filename, "rb")) == Nullfp)
+#endif
+ pfatal2("can't open file %s", filename);
+#ifndef WIN32
+ if ((tifd = creat(TMPINNAME, 0666)) < 0)
+#else
+ if ((tifd = open(TMPINNAME, _O_CREAT | _O_TRUNC | _O_BINARY, _S_IWRITE)) < 0)
+#endif
+ pfatal2("can't open file %s", TMPINNAME);
+ while (fgets(buf, sizeof buf, ifp) != Nullch) {
+ if (revision != Nullch && !found_revision && rev_in_string(buf))
+ found_revision = TRUE;
+ if ((i = strlen(buf)) > maxlen)
+ maxlen = i; /* find longest line */
+ }
+ if (revision != Nullch) {
+ if (!found_revision) {
+ if (force) {
+ if (verbose)
+ say2(
+"Warning: this file doesn't appear to be the %s version--patching anyway.\n",
+ revision);
+ }
+ else if (batch) {
+ fatal2(
+"this file doesn't appear to be the %s version--aborting.\n", revision);
+ }
+ else {
+ ask2(
+"This file doesn't appear to be the %s version--patch anyway? [n] ",
+ revision);
+ if (*buf != 'y')
+ fatal1("aborted\n");
+ }
+ }
+ else if (verbose)
+ say2("Good. This file appears to be the %s version.\n",
+ revision);
+ }
+ Fseek(ifp, 0L, 0); /* rewind file */
+ lines_per_buf = BUFFERSIZE / maxlen;
+ tireclen = maxlen;
+ tibuf[0] = malloc((MEM)(BUFFERSIZE + 1));
+ tibuf[1] = malloc((MEM)(BUFFERSIZE + 1));
+ if (tibuf[1] == Nullch)
+ fatal1("out of memory\n");
+ for (i=1; ; i++) {
+ if (! (i % lines_per_buf)) /* new block */
+ if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
+ pfatal1("can't write temp file");
+ if (fgets(tibuf[0] + maxlen * (i%lines_per_buf), maxlen + 1, ifp)
+ == Nullch) {
+ input_lines = i - 1;
+ if (i % lines_per_buf)
+ if (write(tifd, tibuf[0], BUFFERSIZE) < BUFFERSIZE)
+ pfatal1("can't write temp file");
+ break;
+ }
+ }
+ Fclose(ifp);
+ Close(tifd);
+ if ((tifd = open(TMPINNAME, 0)) < 0) {
+ pfatal2("can't reopen file %s", TMPINNAME);
+ }
+}
+
+/* Fetch a line from the input file, \n terminated, not necessarily \0. */
+
+char *
+ifetch(line,whichbuf)
+Reg1 LINENUM line;
+int whichbuf; /* ignored when file in memory */
+{
+ if (line < 1 || line > input_lines)
+ return "";
+ if (using_plan_a)
+ return i_ptr[line];
+ else {
+ LINENUM offline = line % lines_per_buf;
+ LINENUM baseline = line - offline;
+
+ if (tiline[0] == baseline)
+ whichbuf = 0;
+ else if (tiline[1] == baseline)
+ whichbuf = 1;
+ else {
+ tiline[whichbuf] = baseline;
+#ifndef lint /* complains of long accuracy */
+ Lseek(tifd, (long)baseline / lines_per_buf * BUFFERSIZE, 0);
+#endif
+ if (read(tifd, tibuf[whichbuf], BUFFERSIZE) < 0)
+ pfatal2("error reading tmp file %s", TMPINNAME);
+ }
+ return tibuf[whichbuf] + (tireclen*offline);
+ }
+}
+
+/* True if the string argument contains the revision number we want. */
+
+bool
+rev_in_string(string)
+char *string;
+{
+ Reg1 char *s;
+ Reg2 int patlen;
+
+ if (revision == Nullch)
+ return TRUE;
+ patlen = strlen(revision);
+ if (strnEQ(string,revision,patlen) && isspace(string[patlen]))
+ return TRUE;
+ for (s = string; *s; s++) {
+ if (isspace(*s) && strnEQ(s+1, revision, patlen) &&
+ isspace(s[patlen+1] )) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
diff --git a/xc/util/patch/inp.h b/xc/util/patch/inp.h
new file mode 100644
index 000000000..6fd4ec8f2
--- /dev/null
+++ b/xc/util/patch/inp.h
@@ -0,0 +1,18 @@
+/* oldHeader: inp.h,v 2.0 86/09/17 15:37:25 lwall Exp $
+ * $XConsortium: inp.h,v 2.1 94/09/09 20:04:28 gildea Exp $
+ *
+ * Revision 2.0 86/09/17 15:37:25 lwall
+ * Baseline for netwide release.
+ *
+ */
+
+EXT LINENUM input_lines INIT(0); /* how long is input file in lines */
+EXT LINENUM last_frozen_line INIT(0); /* how many input lines have been */
+ /* irretractibly output */
+
+bool rev_in_string();
+void scan_input();
+bool plan_a(); /* returns false if insufficient memory */
+void plan_b();
+char *ifetch();
+
diff --git a/xc/util/patch/malloc.c b/xc/util/patch/malloc.c
new file mode 100644
index 000000000..a8436c440
--- /dev/null
+++ b/xc/util/patch/malloc.c
@@ -0,0 +1,469 @@
+/*
+ * @(#)nmalloc.c 1 (Caltech) 2/21/82
+ *
+ * U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs
+ *
+ * Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD.
+ *
+ * This is a very fast storage allocator. It allocates blocks of a small
+ * number of different sizes, and keeps free lists of each size. Blocks
+ * that don't exactly fit are passed up to the next larger size. In this
+ * implementation, the available sizes are (2^n)-4 (or -16) bytes long.
+ * This is designed for use in a program that uses vast quantities of
+ * memory, but bombs when it runs out. To make it a little better, it
+ * warns the user when he starts to get near the end.
+ *
+ * June 84, ACT: modified rcheck code to check the range given to malloc,
+ * rather than the range determined by the 2-power used.
+ *
+ * Jan 85, RMS: calls malloc_warning to issue warning on nearly full.
+ * No longer Emacs-specific; can serve as all-purpose malloc for GNU.
+ * You should call malloc_init to reinitialize after loading dumped Emacs.
+ * Call malloc_stats to get info on memory stats if MSTATS turned on.
+ * realloc knows how to return same block given, just changing its size,
+ * if the power of 2 is correct.
+ */
+
+/*
+ * nextf[i] is the pointer to the next free block of size 2^(i+3). The
+ * smallest allocatable block is 8 bytes. The overhead information will
+ * go in the first int of the block, and the returned pointer will point
+ * to the second.
+ *
+#ifdef MSTATS
+ * nmalloc[i] is the difference between the number of mallocs and frees
+ * for a given block size.
+#endif
+ */
+
+#define ISALLOC ((char) 0xf7) /* magic byte that implies allocation */
+#define ISFREE ((char) 0x54) /* magic byte that implies free block */
+ /* this is for error checking only */
+
+extern char etext;
+
+/* end of the program; can be changed by calling init_malloc */
+static char *endofpure = &etext;
+
+#ifdef MSTATS
+static int nmalloc[30];
+static int nmal, nfre;
+#endif /* MSTATS */
+
+/* If range checking is not turned on, all we have is a flag indicating
+ whether memory is allocated, an index in nextf[], and a size field; to
+ realloc() memory we copy either size bytes or 1<<(index+3) bytes depending
+ on whether the former can hold the exact size (given the value of
+ 'index'). If range checking is on, we always need to know how much space
+ is allocated, so the 'size' field is never used. */
+
+struct mhead {
+ char mh_alloc; /* ISALLOC or ISFREE */
+ char mh_index; /* index in nextf[] */
+/* Remainder are valid only when block is allocated */
+ unsigned short mh_size; /* size, if < 0x10000 */
+#ifdef rcheck
+ unsigned mh_nbytes; /* number of bytes allocated */
+ int mh_magic4; /* should be == MAGIC4 */
+#endif /* rcheck */
+ };
+
+/* Access free-list pointer of a block.
+ It is stored at block + 4.
+ This is not a field in the mhead structure
+ because we want sizeof (struct mhead)
+ to describe the overhead for when the block is in use,
+ and we do not want the free-list pointer to count in that. */
+
+#define CHAIN(a) \
+ (*(struct mhead **) (sizeof (char *) + (char *) (a)))
+
+#ifdef rcheck
+
+/* To implement range checking, we write magic values in at the beginning and
+ end of each allocated block, and make sure they are undisturbed whenever a
+ free or a realloc occurs. */
+/* Written in each of the 4 bytes following the block's real space */
+#define MAGIC1 0x55
+/* Written in the 4 bytes before the block's real space */
+#define MAGIC4 0x55555555
+#define ASSERT(p) if (!(p)) botch("p"); else
+static
+botch(s)
+ char *s;
+{
+
+ printf("assertion botched: %s\n", s);
+ abort();
+}
+#define EXTRA 4 /* 4 bytes extra for MAGIC1s */
+#else
+#define ASSERT(p)
+#define EXTRA 0
+#endif /* rcheck */
+
+/* nextf[i] is free list of blocks of size 2**(i + 3) */
+
+static struct mhead *nextf[30];
+
+#ifdef M_WARN
+/* Number of bytes of writable memory we can expect to be able to get */
+static int lim_data;
+/* Level number of warnings already issued.
+ 0 -- no warnings issued.
+ 1 -- 75% warning already issued.
+ 2 -- 85% warning already issued.
+*/
+static int warnlevel;
+#endif /* M_WARN */
+
+/* nonzero once initial bunch of free blocks made */
+static int gotpool;
+
+/* Cause reinitialization based on job parameters;
+ also declare where the end of pure storage is. */
+malloc_init (end)
+ char *end; {
+ endofpure = end;
+#ifdef M_WARN
+ lim_data = 0;
+ warnlevel = 0;
+#endif /* M_WARN */
+ }
+
+static
+morecore (nu) /* ask system for more memory */
+ register int nu; { /* size index to get more of */
+ char *sbrk ();
+ register char *cp;
+ register int nblks;
+ register int siz;
+
+#ifdef M_WARN
+#ifndef BSD42
+#ifdef USG
+ extern long ulimit ();
+ if (lim_data == 0) /* find out how much we can get */
+ lim_data = ulimit (3, 0) - TEXT_START;
+#else /*HMS: was endif */
+ if (lim_data == 0) /* find out how much we can get */
+ lim_data = vlimit (LIM_DATA, -1);
+#endif /* USG */ /HMS:* was not here */
+#else
+ if (lim_data == 0) {
+ struct rlimit XXrlimit;
+
+ getrlimit (RLIMIT_DATA, &XXrlimit);
+ lim_data = XXrlimit.rlim_cur;} /* soft limit */
+#endif /* BSD42 */
+#endif /* M_WARN */
+
+ /* On initial startup, get two blocks of each size up to 1k bytes */
+ if (!gotpool)
+ getpool (), getpool (), gotpool = 1;
+
+ /* Find current end of memory and issue warning if getting near max */
+
+ cp = sbrk (0);
+ siz = cp - endofpure;
+#ifdef M_WARN
+ switch (warnlevel) {
+ case 0:
+ if (siz > (lim_data / 4) * 3) {
+ warnlevel++;
+ malloc_warning ("Warning: past 75% of memory limit");}
+ break;
+ case 1:
+ if (siz > (lim_data / 20) * 17) {
+ warnlevel++;
+ malloc_warning ("Warning: past 85% of memory limit");}
+ break;
+ case 2:
+ if (siz > (lim_data / 20) * 19) {
+ warnlevel++;
+ malloc_warning ("Warning: past 95% of memory limit");}
+ break;}
+#endif /* M_WARN */
+
+ if ((int) cp & 0x3ff) /* land on 1K boundaries */
+ sbrk (1024 - ((int) cp & 0x3ff));
+
+ /* Take at least 2k, and figure out how many blocks of the desired size we're about to get */
+ nblks = 1;
+ if ((siz = nu) < 8)
+ nblks = 1 << ((siz = 8) - nu);
+
+ if ((cp = sbrk (1 << (siz + 3))) == (char *) -1)
+ return; /* no more room! */
+ if ((int) cp & 7) { /* shouldn't happen, but just in case */
+ cp = (char *) (((int) cp + 8) & ~7);
+ nblks--;}
+
+ /* save new header and link the nblks blocks together */
+ nextf[nu] = (struct mhead *) cp;
+ siz = 1 << (nu + 3);
+ while (1) {
+ ((struct mhead *) cp) -> mh_alloc = ISFREE;
+ ((struct mhead *) cp) -> mh_index = nu;
+ if (--nblks <= 0) break;
+ CHAIN ((struct mhead *) cp) = (struct mhead *) (cp + siz);
+ cp += siz;}
+#if 0
+ CHAIN ((struct mhead *) cp) = 0; /* since sbrk() returns cleared core, this is already set */
+#endif
+ }
+
+static
+getpool () {
+ register int nu;
+ register char *cp = sbrk (0);
+
+ if ((int) cp & 0x3ff) /* land on 1K boundaries */
+ sbrk (1024 - ((int) cp & 0x3ff));
+
+ /* Get 2k of storage */
+
+ cp = sbrk (04000);
+ if (cp == (char *) -1)
+ return;
+
+ /* Divide it into an initial 8-word block
+ plus one block of size 2**nu for nu = 3 ... 10. */
+
+ CHAIN (cp) = nextf[0];
+ nextf[0] = (struct mhead *) cp;
+ ((struct mhead *) cp) -> mh_alloc = ISFREE;
+ ((struct mhead *) cp) -> mh_index = 0;
+ cp += 8;
+
+ for (nu = 0; nu < 7; nu++) {
+ CHAIN (cp) = nextf[nu];
+ nextf[nu] = (struct mhead *) cp;
+ ((struct mhead *) cp) -> mh_alloc = ISFREE;
+ ((struct mhead *) cp) -> mh_index = nu;
+ cp += 8 << nu;}}
+
+char *
+malloc (n) /* get a block */
+ unsigned n; {
+ register struct mhead *p;
+ register unsigned int nbytes;
+ register int nunits = 0;
+
+ /* Figure out how many bytes are required, rounding up to the nearest
+ multiple of 4, then figure out which nextf[] area to use */
+ nbytes = (n + sizeof *p + EXTRA + 3) & ~3;
+ {
+ register unsigned int shiftr = (nbytes - 1) >> 2;
+
+ while (shiftr >>= 1)
+ nunits++;
+ }
+
+ /* If there are no blocks of the appropriate size, go get some */
+ /* COULD SPLIT UP A LARGER BLOCK HERE ... ACT */
+ if (nextf[nunits] == 0)
+ morecore (nunits);
+
+ /* Get one block off the list, and set the new list head */
+ if ((p = nextf[nunits]) == 0)
+ return 0;
+ nextf[nunits] = CHAIN (p);
+
+ /* Check for free block clobbered */
+ /* If not for this check, we would gobble a clobbered free chain ptr */
+ /* and bomb out on the NEXT allocate of this size block */
+ if (p -> mh_alloc != ISFREE || p -> mh_index != nunits)
+#ifdef rcheck
+ botch ("block on free list clobbered");
+#else
+ abort ();
+#endif /* rcheck */
+
+ /* Fill in the info, and if range checking, set up the magic numbers */
+ p -> mh_alloc = ISALLOC;
+#ifdef rcheck
+ p -> mh_nbytes = n;
+ p -> mh_magic4 = MAGIC4;
+ {
+ register char *m = (char *) (p + 1) + n;
+
+ *m++ = MAGIC1, *m++ = MAGIC1, *m++ = MAGIC1, *m = MAGIC1;
+ }
+#else
+ p -> mh_size = n;
+#endif /* rcheck */
+#ifdef MSTATS
+ nmalloc[nunits]++;
+ nmal++;
+#endif /* MSTATS */
+ return (char *) (p + 1);}
+
+free (mem)
+ char *mem; {
+ register struct mhead *p;
+ {
+ register char *ap = mem;
+
+ ASSERT (ap != 0);
+ p = (struct mhead *) ap - 1;
+ ASSERT (p -> mh_alloc == ISALLOC);
+#ifdef rcheck
+ ASSERT (p -> mh_magic4 == MAGIC4);
+ ap += p -> mh_nbytes;
+ ASSERT (*ap++ == MAGIC1); ASSERT (*ap++ == MAGIC1);
+ ASSERT (*ap++ == MAGIC1); ASSERT (*ap == MAGIC1);
+#endif /* rcheck */
+ }
+ {
+ register int nunits = p -> mh_index;
+
+ ASSERT (nunits <= 29);
+ p -> mh_alloc = ISFREE;
+ CHAIN (p) = nextf[nunits];
+ nextf[nunits] = p;
+#ifdef MSTATS
+ nmalloc[nunits]--;
+ nfre++;
+#endif /* MSTATS */
+ }
+ }
+
+char *
+realloc (mem, n)
+ char *mem;
+ register unsigned n; {
+ register struct mhead *p;
+ register unsigned int tocopy;
+ register int nbytes;
+ register int nunits;
+
+ if ((p = (struct mhead *) mem) == 0)
+ return malloc (n);
+ p--;
+ nunits = p -> mh_index;
+ ASSERT (p -> mh_alloc == ISALLOC);
+#ifdef rcheck
+ ASSERT (p -> mh_magic4 == MAGIC4);
+ {
+ register char *m = mem + (tocopy = p -> mh_nbytes);
+ ASSERT (*m++ == MAGIC1); ASSERT (*m++ == MAGIC1);
+ ASSERT (*m++ == MAGIC1); ASSERT (*m == MAGIC1);
+ }
+#else
+ if (p -> mh_index >= 13)
+ tocopy = (1 << (p -> mh_index + 3)) - sizeof *p;
+ else
+ tocopy = p -> mh_size;
+#endif /* rcheck */
+
+ /* See if desired size rounds to same power of 2 as actual size. */
+ nbytes = (n + sizeof *p + EXTRA + 7) & ~7;
+
+ /* If ok, use the same block, just marking its size as changed. */
+ if (nbytes > (4 << nunits) && nbytes <= (8 << nunits)) {
+#ifdef rcheck
+ register char *m = mem + tocopy;
+ *m++ = 0; *m++ = 0; *m++ = 0; *m++ = 0;
+ p-> mh_nbytes = n;
+ m = mem + n;
+ *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1;
+#else
+ p -> mh_size = n;
+#endif /* rcheck */
+ return mem;}
+
+ if (n < tocopy)
+ tocopy = n;
+ {
+ register char *new;
+ void bcopy(); /*HMS: here? */
+
+ if ((new = malloc (n)) == 0)
+ return 0;
+ bcopy (mem, new, tocopy);
+ free (mem);
+ return new;
+ }
+ }
+
+#ifdef MSTATS
+/* Return statistics describing allocation of blocks of size 2**n. */
+
+struct mstats_value {
+ int blocksize;
+ int nfree;
+ int nused;
+ };
+
+struct mstats_value
+malloc_stats (size)
+ int size; {
+ struct mstats_value v;
+ register int i;
+ register struct mhead *p;
+
+ v.nfree = 0;
+
+ if (size < 0 || size >= 30) {
+ v.blocksize = 0;
+ v.nused = 0;
+ return v;}
+
+ v.blocksize = 1 << (size + 3);
+ v.nused = nmalloc[size];
+
+ for (p = nextf[size]; p; p = CHAIN (p))
+ v.nfree++;
+
+ return v;}
+#endif
+
+/* how much space is available? */
+
+unsigned freespace() {
+ register int i, j;
+ register struct mhead *p;
+ register unsigned space = 0;
+ int local; /* address only is used */
+
+ space = (char *)&local - sbrk(0); /* stack space */
+
+ for (i = 0; i < 30; i++) {
+ for (j = 0, p = nextf[i]; p; p = CHAIN (p), j++) ;
+ space += j * (1 << (i + 3));}
+
+ return(space);}
+
+/* How big is this cell? */
+
+unsigned mc_size(cp)
+ char *cp;{
+ register struct mhead *p;
+
+ if ((p = (struct mhead *) cp) == 0) {
+ /*HMS? */
+ }
+ p--;
+#ifdef rcheck
+ return p -> mh_nbytes;
+#else
+ return (1 << (p -> mh_index + 3)) - sizeof *p;
+#if 0
+ if (p -> mh_index >= 13)
+ return (1 << (p -> mh_index + 3)) - sizeof *p;
+ else
+ return p -> mh_size;
+#endif
+#endif /* rcheck */
+ }
+
+/*HMS: Really should use memcpy, if available... */
+
+void bcopy(source, dest, len)
+ register char *source, *dest;
+ register len; {
+ register i;
+
+ for (i = 0; i < len; i++)
+ *dest++ = *source++;}
diff --git a/xc/util/patch/patch.c b/xc/util/patch/patch.c
new file mode 100644
index 000000000..28048be97
--- /dev/null
+++ b/xc/util/patch/patch.c
@@ -0,0 +1,941 @@
+char rcsid[] =
+ "$XConsortium: patch.c,v 3.3 94/09/14 21:21:33 gildea Exp $";
+/* "oldHeader: patch.c,v 2.0.2.0 90/05/01 22:17:50 davison Locked $"; */
+
+/* patch - a program to apply diffs to original files
+ *
+ * Copyright 1986, Larry Wall
+ *
+ * This program may be copied as long as you don't try to make any
+ * money off of it, or pretend that you wrote it.
+ *
+ * Revision 2.0.2.0 90/05/01 22:17:50 davison
+ * patch12u: unidiff support added
+ *
+ * Revision 2.0.1.6 88/06/22 20:46:39 lwall
+ * patch12: rindex() wasn't declared
+ *
+ * Revision 2.0.1.5 88/06/03 15:09:37 lwall
+ * patch10: exit code improved.
+ * patch10: better support for non-flexfilenames.
+ *
+ * Revision 2.0.1.4 87/02/16 14:00:04 lwall
+ * Short replacement caused spurious "Out of sync" message.
+ *
+ * Revision 2.0.1.3 87/01/30 22:45:50 lwall
+ * Improved diagnostic on sync error.
+ * Moved do_ed_script() to pch.c.
+ *
+ * Revision 2.0.1.2 86/11/21 09:39:15 lwall
+ * Fuzz factor caused offset of installed lines.
+ *
+ * Revision 2.0.1.1 86/10/29 13:10:22 lwall
+ * Backwards search could terminate prematurely.
+ *
+ * Revision 2.0 86/09/17 15:37:32 lwall
+ * Baseline for netwide release.
+ *
+ * Revision 1.5 86/08/01 20:53:24 lwall
+ * Changed some %d's to %ld's.
+ * Linted.
+ *
+ * Revision 1.4 86/08/01 19:17:29 lwall
+ * Fixes for machines that can't vararg.
+ * Added fuzz factor.
+ * Generalized -p.
+ * General cleanup.
+ *
+ * 85/08/15 van%ucbmonet@berkeley
+ * Changes for 4.3bsd diff -c.
+ *
+ * Revision 1.3 85/03/26 15:07:43 lwall
+ * Frozen.
+ *
+ * Revision 1.2.1.9 85/03/12 17:03:35 lwall
+ * Changed pfp->_file to fileno(pfp).
+ *
+ * Revision 1.2.1.8 85/03/12 16:30:43 lwall
+ * Check i_ptr and i_womp to make sure they aren't null before freeing.
+ * Also allow ed output to be suppressed.
+ *
+ * Revision 1.2.1.7 85/03/12 15:56:13 lwall
+ * Added -p option from jromine@uci-750a.
+ *
+ * Revision 1.2.1.6 85/03/12 12:12:51 lwall
+ * Now checks for normalness of file to patch.
+ *
+ * Revision 1.2.1.5 85/03/12 11:52:12 lwall
+ * Added -D (#ifdef) option from joe@fluke.
+ *
+ * Revision 1.2.1.4 84/12/06 11:14:15 lwall
+ * Made smarter about SCCS subdirectories.
+ *
+ * Revision 1.2.1.3 84/12/05 11:18:43 lwall
+ * Added -l switch to do loose string comparison.
+ *
+ * Revision 1.2.1.2 84/12/04 09:47:13 lwall
+ * Failed hunk count not reset on multiple patch file.
+ *
+ * Revision 1.2.1.1 84/12/04 09:42:37 lwall
+ * Branch for sdcrdcf changes.
+ *
+ * Revision 1.2 84/11/29 13:29:51 lwall
+ * Linted. Identifiers uniqified. Fixed i_ptr malloc() bug. Fixed
+ * multiple calls to mktemp(). Will now work on machines that can only
+ * read 32767 chars. Added -R option for diffs with new and old swapped.
+ * Various cosmetic changes.
+ *
+ * Revision 1.1 84/11/09 17:03:58 lwall
+ * Initial revision
+ *
+ */
+
+#include "INTERN.h"
+#include "common.h"
+#include "EXTERN.h"
+#include "version.h"
+#include "util.h"
+#include "pch.h"
+#include "inp.h"
+#include "backupfile.h"
+
+/* procedures */
+
+void reinitialize_almost_everything();
+void get_some_switches();
+LINENUM locate_hunk();
+void abort_hunk();
+void apply_hunk();
+void init_output();
+void init_reject();
+void copy_till();
+void spew_output();
+void dump_line();
+bool patch_match();
+bool similar();
+void re_input();
+void my_exit();
+
+/* TRUE if -E was specified on command line. */
+static int remove_empty_files = FALSE;
+
+/* TRUE if -R was specified on command line. */
+static int reverse_flag_specified = FALSE;
+
+/* Apply a set of diffs as appropriate. */
+
+int
+main(argc,argv)
+int argc;
+char **argv;
+{
+ LINENUM where;
+ LINENUM newwhere;
+ LINENUM fuzz;
+ LINENUM mymaxfuzz;
+ int hunk = 0;
+ int failed = 0;
+ int failtotal = 0;
+ bool rev_okayed = 0;
+ int i;
+
+ setbuf(stderr, serrbuf);
+ for (i = 0; i<MAXFILEC; i++)
+ filearg[i] = Nullch;
+
+#ifndef WIN32
+ myuid = getuid();
+#endif
+
+ /* Cons up the names of the temporary files. */
+ {
+ /* Directory for temporary files. */
+ char *tmpdir;
+ int tmpname_len;
+
+ tmpdir = getenv ("TMPDIR");
+ if (tmpdir == NULL) {
+ tmpdir = "/tmp";
+ }
+ tmpname_len = strlen (tmpdir) + 20;
+
+ TMPOUTNAME = (char *) malloc (tmpname_len);
+ strcpy (TMPOUTNAME, tmpdir);
+ strcat (TMPOUTNAME, "/patchoXXXXXX");
+ Mktemp(TMPOUTNAME);
+
+ TMPINNAME = (char *) malloc (tmpname_len);
+ strcpy (TMPINNAME, tmpdir);
+ strcat (TMPINNAME, "/patchiXXXXXX");
+ Mktemp(TMPINNAME);
+
+ TMPREJNAME = (char *) malloc (tmpname_len);
+ strcpy (TMPREJNAME, tmpdir);
+ strcat (TMPREJNAME, "/patchrXXXXXX");
+ Mktemp(TMPREJNAME);
+
+ TMPPATNAME = (char *) malloc (tmpname_len);
+ strcpy (TMPPATNAME, tmpdir);
+ strcat (TMPPATNAME, "/patchpXXXXXX");
+ Mktemp(TMPPATNAME);
+ }
+
+ {
+ char *v;
+
+ v = getenv ("SIMPLE_BACKUP_SUFFIX");
+ if (v)
+ simple_backup_suffix = v;
+ else
+ simple_backup_suffix = ORIGEXT;
+#ifndef NODIR
+ v = getenv ("VERSION_CONTROL");
+ backup_type = get_version (v); /* OK to pass NULL. */
+#endif
+ }
+
+ /* parse switches */
+ Argc = argc;
+ Argv = argv;
+ get_some_switches();
+
+ /* make sure we clean up /tmp in case of disaster */
+ set_signals(0);
+
+ for (
+ open_patch_file(filearg[1]);
+ there_is_another_patch();
+ reinitialize_almost_everything()
+ ) { /* for each patch in patch file */
+
+ if (outname == Nullch)
+ outname = savestr(filearg[0]);
+
+#ifndef WIN32
+ /* for ed script just up and do it and exit */
+ if (diff_type == ED_DIFF) {
+ do_ed_script();
+ continue;
+ }
+#endif
+
+ /* initialize the patched file */
+ if (!skip_rest_of_patch)
+ init_output(TMPOUTNAME);
+
+ /* initialize reject file */
+ init_reject(TMPREJNAME);
+
+ /* find out where all the lines are */
+ if (!skip_rest_of_patch)
+ scan_input(filearg[0]);
+
+ /* from here on, open no standard i/o files, because malloc */
+ /* might misfire and we can't catch it easily */
+
+ /* apply each hunk of patch */
+ hunk = 0;
+ failed = 0;
+ rev_okayed = FALSE;
+ out_of_mem = FALSE;
+ while (another_hunk()) {
+ hunk++;
+ fuzz = Nulline;
+ mymaxfuzz = pch_context();
+ if (maxfuzz < mymaxfuzz)
+ mymaxfuzz = maxfuzz;
+ if (!skip_rest_of_patch) {
+ do {
+ where = locate_hunk(fuzz);
+ if (hunk == 1 && where == Nulline && !(force|rev_okayed)) {
+ /* dwim for reversed patch? */
+ if (!pch_swap()) {
+ if (fuzz == Nulline)
+ say1(
+"Not enough memory to try swapped hunk! Assuming unswapped.\n");
+ continue;
+ }
+ reverse = !reverse;
+ where = locate_hunk(fuzz); /* try again */
+ if (where == Nulline) { /* didn't find it swapped */
+ if (!pch_swap()) /* put it back to normal */
+ fatal1("lost hunk on alloc error!\n");
+ reverse = !reverse;
+ }
+ else if (noreverse) {
+ if (!pch_swap()) /* put it back to normal */
+ fatal1("lost hunk on alloc error!\n");
+ reverse = !reverse;
+ say1(
+"Ignoring previously applied (or reversed) patch.\n");
+ skip_rest_of_patch = TRUE;
+ }
+ else if (batch) {
+ if (verbose)
+ say3(
+"%seversed (or previously applied) patch detected! %s -R.",
+ reverse ? "R" : "Unr",
+ reverse ? "Assuming" : "Ignoring");
+ }
+ else {
+ ask3(
+"%seversed (or previously applied) patch detected! %s -R? [y] ",
+ reverse ? "R" : "Unr",
+ reverse ? "Assume" : "Ignore");
+ if (*buf == 'n') {
+ ask1("Apply anyway? [n] ");
+ if (*buf == 'y')
+ rev_okayed = TRUE;
+ else
+ skip_rest_of_patch = TRUE;
+ where = Nulline;
+ reverse = !reverse;
+ if (!pch_swap()) /* put it back to normal */
+ fatal1("lost hunk on alloc error!\n");
+ }
+ }
+ }
+ } while (!skip_rest_of_patch && where == Nulline &&
+ ++fuzz <= mymaxfuzz);
+
+ if (skip_rest_of_patch) { /* just got decided */
+ Fclose(ofp);
+ ofp = Nullfp;
+ }
+ }
+
+ newwhere = pch_newfirst() + last_offset;
+ if (skip_rest_of_patch) {
+ abort_hunk();
+ failed++;
+ if (verbose)
+ say3("Hunk #%d ignored at %ld.\n", hunk, newwhere);
+ }
+ else if (where == Nulline) {
+ abort_hunk();
+ failed++;
+ if (verbose)
+ say3("Hunk #%d failed at %ld.\n", hunk, newwhere);
+ }
+ else {
+ apply_hunk(where);
+ if (verbose) {
+ say3("Hunk #%d succeeded at %ld", hunk, newwhere);
+ if (fuzz)
+ say2(" with fuzz %ld", fuzz);
+ if (last_offset)
+ say3(" (offset %ld line%s)",
+ last_offset, last_offset==1L?"":"s");
+ say1(".\n");
+ }
+ }
+ }
+
+ if (out_of_mem && using_plan_a) {
+ Argc = Argc_last;
+ Argv = Argv_last;
+ say1("\n\nRan out of memory using Plan A--trying again...\n\n");
+ if (ofp)
+ Fclose(ofp);
+ ofp = Nullfp;
+ if (rejfp)
+ Fclose(rejfp);
+ rejfp = Nullfp;
+ continue;
+ }
+
+ assert(hunk);
+
+ /* finish spewing out the new file */
+ if (!skip_rest_of_patch)
+ spew_output();
+
+ /* and put the output where desired */
+ ignore_signals();
+ if (!skip_rest_of_patch) {
+ struct stat statbuf;
+ char *realout = outname;
+
+ if (move_file(TMPOUTNAME, outname) < 0) {
+ toutkeep = TRUE;
+ realout = TMPOUTNAME;
+ chmod(TMPOUTNAME, filemode);
+ }
+ else
+ chmod(outname, filemode);
+
+ if (remove_empty_files && stat(realout, &statbuf) == 0
+ && statbuf.st_size == 0) {
+ if (verbose)
+ say2("Removing %s (empty after patching).\n", realout);
+ while (unlink(realout) >= 0) ; /* while is for Eunice. */
+ }
+ }
+ Fclose(rejfp);
+ rejfp = Nullfp;
+ if (failed) {
+ failtotal += failed;
+ if (!*rejname) {
+ Strcpy(rejname, outname);
+#ifndef FLEXFILENAMES
+ {
+ char *s = rindex(rejname,'/');
+
+ if (!s)
+ s = rejname;
+ if (strlen(s) > 13)
+ if (s[12] == '.') /* try to preserve difference */
+ s[12] = s[13]; /* between .h, .c, .y, etc. */
+ s[13] = '\0';
+ }
+#endif
+ Strcat(rejname, REJEXT);
+ }
+ if (skip_rest_of_patch) {
+ say4("%d out of %d hunks ignored--saving rejects to %s\n",
+ failed, hunk, rejname);
+ }
+ else {
+ say4("%d out of %d hunks failed--saving rejects to %s\n",
+ failed, hunk, rejname);
+ }
+ if (move_file(TMPREJNAME, rejname) < 0)
+ trejkeep = TRUE;
+ }
+ set_signals(1);
+ }
+ my_exit(failtotal);
+}
+
+/* Prepare to find the next patch to do in the patch file. */
+
+void
+reinitialize_almost_everything()
+{
+ re_patch();
+ re_input();
+
+ input_lines = 0;
+ last_frozen_line = 0;
+
+ filec = 0;
+ if (filearg[0] != Nullch && !out_of_mem) {
+ free(filearg[0]);
+ filearg[0] = Nullch;
+ }
+
+ if (outname != Nullch) {
+ free(outname);
+ outname = Nullch;
+ }
+
+ last_offset = 0;
+
+ diff_type = 0;
+
+ if (revision != Nullch) {
+ free(revision);
+ revision = Nullch;
+ }
+
+ reverse = reverse_flag_specified;
+ skip_rest_of_patch = FALSE;
+
+ get_some_switches();
+
+ if (filec >= 2)
+ fatal1("you may not change to a different patch file\n");
+}
+
+static char *
+nextarg()
+{
+ if (!--Argc)
+ fatal2("missing argument after `%s'\n", *Argv);
+ return *++Argv;
+}
+
+/* Process switches and filenames up to next '+' or end of list. */
+
+void
+get_some_switches()
+{
+ Reg1 char *s;
+
+ rejname[0] = '\0';
+ Argc_last = Argc;
+ Argv_last = Argv;
+ if (!Argc)
+ return;
+ for (Argc--,Argv++; Argc; Argc--,Argv++) {
+ s = Argv[0];
+ if (strEQ(s, "+")) {
+ return; /* + will be skipped by for loop */
+ }
+ if (*s != '-' || !s[1]) {
+ if (filec == MAXFILEC)
+ fatal1("too many file arguments\n");
+ filearg[filec++] = savestr(s);
+ }
+ else {
+ switch (*++s) {
+ case 'b':
+ simple_backup_suffix = savestr(nextarg());
+ break;
+ case 'B':
+ origprae = savestr(nextarg());
+ break;
+ case 'c':
+ diff_type = CONTEXT_DIFF;
+ break;
+ case 'd':
+ if (!*++s)
+ s = nextarg();
+ if (chdir(s) < 0)
+ pfatal2("can't cd to %s", s);
+ break;
+ case 'D':
+ do_defines = TRUE;
+ if (!*++s)
+ s = nextarg();
+ if (!isalpha(*s) && '_' != *s)
+ fatal1("argument to -D is not an identifier\n");
+ Sprintf(if_defined, "#ifdef %s\n", s);
+ Sprintf(not_defined, "#ifndef %s\n", s);
+ Sprintf(end_defined, "#endif /* %s */\n", s);
+ break;
+#ifndef WIN32
+ case 'e':
+ diff_type = ED_DIFF;
+ break;
+#endif
+ case 'E':
+ remove_empty_files = TRUE;
+ break;
+ case 'f':
+ force = TRUE;
+ break;
+ case 'F':
+ if (*++s == '=')
+ s++;
+ maxfuzz = atoi(s);
+ break;
+ case 'l':
+ canonicalize = TRUE;
+ break;
+ case 'n':
+ diff_type = NORMAL_DIFF;
+ break;
+ case 'N':
+ noreverse = TRUE;
+ break;
+ case 'o':
+ outname = savestr(nextarg());
+ break;
+ case 'p':
+ if (*++s == '=')
+ s++;
+ strippath = atoi(s);
+ break;
+ case 'r':
+ Strcpy(rejname, nextarg());
+ break;
+ case 'R':
+ reverse = TRUE;
+ reverse_flag_specified = TRUE;
+ break;
+ case 's':
+ verbose = FALSE;
+ break;
+ case 'S':
+ skip_rest_of_patch = TRUE;
+ break;
+ case 't':
+ batch = TRUE;
+ break;
+ case 'u':
+ diff_type = UNI_DIFF;
+ break;
+ case 'v':
+ version();
+ break;
+ case 'V':
+#ifndef NODIR
+ backup_type = get_version (nextarg ());
+#endif
+ break;
+#ifdef DEBUGGING
+ case 'x':
+ debug = atoi(s+1);
+ break;
+#endif
+ default:
+ fprintf(stderr, "patch: unrecognized option `%s'\n", Argv[0]);
+ fprintf(stderr, "\
+Usage: patch [options] [origfile [patchfile]] [+ [options] [origfile]]...\n\
+Options:\n\
+ [-ceEflnNRsStuv] [-b backup-ext] [-B backup-prefix] [-d directory]\n\
+ [-D symbol] [-Fmax-fuzz] [-o out-file] [-p[strip-count]]\n\
+ [-r rej-name] [-V {numbered,existing,simple}]\n");
+ my_exit(1);
+ }
+ }
+ }
+}
+
+/* Attempt to find the right place to apply this hunk of patch. */
+
+LINENUM
+locate_hunk(fuzz)
+LINENUM fuzz;
+{
+ Reg1 LINENUM first_guess = pch_first() + last_offset;
+ Reg2 LINENUM offset;
+ LINENUM pat_lines = pch_ptrn_lines();
+ Reg3 LINENUM max_pos_offset = input_lines - first_guess
+ - pat_lines + 1;
+ Reg4 LINENUM max_neg_offset = first_guess - last_frozen_line - 1
+ + pch_context();
+
+ if (!pat_lines) /* null range matches always */
+ return first_guess;
+ if (max_neg_offset >= first_guess) /* do not try lines < 0 */
+ max_neg_offset = first_guess - 1;
+ if (first_guess <= input_lines && patch_match(first_guess, Nulline, fuzz))
+ return first_guess;
+ for (offset = 1; ; offset++) {
+ Reg5 bool check_after = (offset <= max_pos_offset);
+ Reg6 bool check_before = (offset <= max_neg_offset);
+
+ if (check_after && patch_match(first_guess, offset, fuzz)) {
+#ifdef DEBUGGING
+ if (debug & 1)
+ say3("Offset changing from %ld to %ld\n", last_offset, offset);
+#endif
+ last_offset = offset;
+ return first_guess+offset;
+ }
+ else if (check_before && patch_match(first_guess, -offset, fuzz)) {
+#ifdef DEBUGGING
+ if (debug & 1)
+ say3("Offset changing from %ld to %ld\n", last_offset, -offset);
+#endif
+ last_offset = -offset;
+ return first_guess-offset;
+ }
+ else if (!check_before && !check_after)
+ return Nulline;
+ }
+}
+
+/* We did not find the pattern, dump out the hunk so they can handle it. */
+
+void
+abort_hunk()
+{
+ Reg1 LINENUM i;
+ Reg2 LINENUM pat_end = pch_end();
+ /* add in last_offset to guess the same as the previous successful hunk */
+ LINENUM oldfirst = pch_first() + last_offset;
+ LINENUM newfirst = pch_newfirst() + last_offset;
+ LINENUM oldlast = oldfirst + pch_ptrn_lines() - 1;
+ LINENUM newlast = newfirst + pch_repl_lines() - 1;
+ char *stars = (diff_type >= NEW_CONTEXT_DIFF ? " ****" : "");
+ char *minuses = (diff_type >= NEW_CONTEXT_DIFF ? " ----" : " -----");
+
+ fprintf(rejfp, "***************\n");
+ for (i=0; i<=pat_end; i++) {
+ switch (pch_char(i)) {
+ case '*':
+ if (oldlast < oldfirst)
+ fprintf(rejfp, "*** 0%s\n", stars);
+ else if (oldlast == oldfirst)
+ fprintf(rejfp, "*** %ld%s\n", oldfirst, stars);
+ else
+ fprintf(rejfp, "*** %ld,%ld%s\n", oldfirst, oldlast, stars);
+ break;
+ case '=':
+ if (newlast < newfirst)
+ fprintf(rejfp, "--- 0%s\n", minuses);
+ else if (newlast == newfirst)
+ fprintf(rejfp, "--- %ld%s\n", newfirst, minuses);
+ else
+ fprintf(rejfp, "--- %ld,%ld%s\n", newfirst, newlast, minuses);
+ break;
+ case '\n':
+ fprintf(rejfp, "%s", pfetch(i));
+ break;
+ case ' ': case '-': case '+': case '!':
+ fprintf(rejfp, "%c %s", pch_char(i), pfetch(i));
+ break;
+ default:
+ fatal1("fatal internal error in abort_hunk\n");
+ }
+ }
+}
+
+/* We found where to apply it (we hope), so do it. */
+
+void
+apply_hunk(where)
+LINENUM where;
+{
+ Reg1 LINENUM old = 1;
+ Reg2 LINENUM lastline = pch_ptrn_lines();
+ Reg3 LINENUM new = lastline+1;
+#define OUTSIDE 0
+#define IN_IFNDEF 1
+#define IN_IFDEF 2
+#define IN_ELSE 3
+ Reg4 int def_state = OUTSIDE;
+ Reg5 bool R_do_defines = do_defines;
+ Reg6 LINENUM pat_end = pch_end();
+
+ where--;
+ while (pch_char(new) == '=' || pch_char(new) == '\n')
+ new++;
+
+ while (old <= lastline) {
+ if (pch_char(old) == '-') {
+ copy_till(where + old - 1);
+ if (R_do_defines) {
+ if (def_state == OUTSIDE) {
+ fputs(not_defined, ofp);
+ def_state = IN_IFNDEF;
+ }
+ else if (def_state == IN_IFDEF) {
+ fputs(else_defined, ofp);
+ def_state = IN_ELSE;
+ }
+ fputs(pfetch(old), ofp);
+ }
+ last_frozen_line++;
+ old++;
+ }
+ else if (new > pat_end) {
+ break;
+ }
+ else if (pch_char(new) == '+') {
+ copy_till(where + old - 1);
+ if (R_do_defines) {
+ if (def_state == IN_IFNDEF) {
+ fputs(else_defined, ofp);
+ def_state = IN_ELSE;
+ }
+ else if (def_state == OUTSIDE) {
+ fputs(if_defined, ofp);
+ def_state = IN_IFDEF;
+ }
+ }
+ fputs(pfetch(new), ofp);
+ new++;
+ }
+ else if (pch_char(new) != pch_char(old)) {
+ say3("Out-of-sync patch, lines %ld,%ld--mangled text or line numbers, maybe?\n",
+ pch_hunk_beg() + old,
+ pch_hunk_beg() + new);
+#ifdef DEBUGGING
+ say3("oldchar = '%c', newchar = '%c'\n",
+ pch_char(old), pch_char(new));
+#endif
+ my_exit(1);
+ }
+ else if (pch_char(new) == '!') {
+ copy_till(where + old - 1);
+ if (R_do_defines) {
+ fputs(not_defined, ofp);
+ def_state = IN_IFNDEF;
+ }
+ while (pch_char(old) == '!') {
+ if (R_do_defines) {
+ fputs(pfetch(old), ofp);
+ }
+ last_frozen_line++;
+ old++;
+ }
+ if (R_do_defines) {
+ fputs(else_defined, ofp);
+ def_state = IN_ELSE;
+ }
+ while (pch_char(new) == '!') {
+ fputs(pfetch(new), ofp);
+ new++;
+ }
+ }
+ else {
+ assert(pch_char(new) == ' ');
+ old++;
+ new++;
+ if (R_do_defines && def_state != OUTSIDE) {
+ fputs(end_defined, ofp);
+ def_state = OUTSIDE;
+ }
+ }
+ }
+ if (new <= pat_end && pch_char(new) == '+') {
+ copy_till(where + old - 1);
+ if (R_do_defines) {
+ if (def_state == OUTSIDE) {
+ fputs(if_defined, ofp);
+ def_state = IN_IFDEF;
+ }
+ else if (def_state == IN_IFNDEF) {
+ fputs(else_defined, ofp);
+ def_state = IN_ELSE;
+ }
+ }
+ while (new <= pat_end && pch_char(new) == '+') {
+ fputs(pfetch(new), ofp);
+ new++;
+ }
+ }
+ if (R_do_defines && def_state != OUTSIDE) {
+ fputs(end_defined, ofp);
+ }
+}
+
+/* Open the new file. */
+
+void
+init_output(name)
+char *name;
+{
+#ifndef WIN32
+ ofp = fopen(name, "w");
+#else
+ ofp = fopen(name, "wb");
+#endif
+ if (ofp == Nullfp)
+ pfatal2("can't create %s", name);
+}
+
+/* Open a file to put hunks we can't locate. */
+
+void
+init_reject(name)
+char *name;
+{
+#ifndef WIN32
+ rejfp = fopen(name, "w");
+#else
+ rejfp = fopen(name, "wb");
+#endif
+ if (rejfp == Nullfp)
+ pfatal2("can't create %s", name);
+}
+
+/* Copy input file to output, up to wherever hunk is to be applied. */
+
+void
+copy_till(lastline)
+Reg1 LINENUM lastline;
+{
+ Reg2 LINENUM R_last_frozen_line = last_frozen_line;
+
+ if (R_last_frozen_line > lastline)
+ fatal1("misordered hunks! output would be garbled\n");
+ while (R_last_frozen_line < lastline) {
+ dump_line(++R_last_frozen_line);
+ }
+ last_frozen_line = R_last_frozen_line;
+}
+
+/* Finish copying the input file to the output file. */
+
+void
+spew_output()
+{
+#ifdef DEBUGGING
+ if (debug & 256)
+ say3("il=%ld lfl=%ld\n",input_lines,last_frozen_line);
+#endif
+ if (input_lines)
+ copy_till(input_lines); /* dump remainder of file */
+ Fclose(ofp);
+ ofp = Nullfp;
+}
+
+/* Copy one line from input to output. */
+
+void
+dump_line(line)
+LINENUM line;
+{
+ Reg1 char *s;
+ Reg2 char R_newline = '\n';
+
+ /* Note: string is not null terminated. */
+ for (s=ifetch(line, 0); putc(*s, ofp) != R_newline; s++) ;
+}
+
+/* Does the patch pattern match at line base+offset? */
+
+bool
+patch_match(base, offset, fuzz)
+LINENUM base;
+LINENUM offset;
+LINENUM fuzz;
+{
+ Reg1 LINENUM pline = 1 + fuzz;
+ Reg2 LINENUM iline;
+ Reg3 LINENUM pat_lines = pch_ptrn_lines() - fuzz;
+
+ for (iline=base+offset+fuzz; pline <= pat_lines; pline++,iline++) {
+ if (canonicalize) {
+ if (!similar(ifetch(iline, (offset >= 0)),
+ pfetch(pline),
+ pch_line_len(pline) ))
+ return FALSE;
+ }
+ else if (strnNE(ifetch(iline, (offset >= 0)),
+ pfetch(pline),
+ pch_line_len(pline) ))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Do two lines match with canonicalized white space? */
+
+bool
+similar(a,b,len)
+Reg1 char *a;
+Reg2 char *b;
+Reg3 int len;
+{
+ while (len) {
+ if (isspace(*b)) { /* whitespace (or \n) to match? */
+ if (!isspace(*a)) /* no corresponding whitespace? */
+ return FALSE;
+ while (len && isspace(*b) && *b != '\n')
+ b++,len--; /* skip pattern whitespace */
+ while (isspace(*a) && *a != '\n')
+ a++; /* skip target whitespace */
+ if (*a == '\n' || *b == '\n')
+ return (*a == *b); /* should end in sync */
+ }
+ else if (*a++ != *b++) /* match non-whitespace chars */
+ return FALSE;
+ else
+ len--; /* probably not necessary */
+ }
+ return TRUE; /* actually, this is not reached */
+ /* since there is always a \n */
+}
+
+/* Exit with cleanup. */
+
+void
+my_exit(status)
+int status;
+{
+ Unlink(TMPINNAME);
+ if (!toutkeep) {
+ Unlink(TMPOUTNAME);
+ }
+ if (!trejkeep) {
+ Unlink(TMPREJNAME);
+ }
+ Unlink(TMPPATNAME);
+ exit(status);
+}
diff --git a/xc/util/patch/patch.man b/xc/util/patch/patch.man
new file mode 100644
index 000000000..653647b25
--- /dev/null
+++ b/xc/util/patch/patch.man
@@ -0,0 +1,551 @@
+.\" -*- nroff -*-
+.rn '' }`
+'\" $XConsortium: patch.man,v 1.2 94/09/09 20:04:28 gildea Exp $
+'\"
+'\" Revision 2.0.1.2 88/06/22 20:47:18 lwall
+'\" patch12: now avoids Bell System Logo
+'\"
+'\" Revision 2.0.1.1 88/06/03 15:12:51 lwall
+'\" patch10: -B switch was contributed.
+'\"
+'\" Revision 2.0 86/09/17 15:39:09 lwall
+'\" Baseline for netwide release.
+'\"
+'\" Revision 1.4 86/08/01 19:23:22 lwall
+'\" Documented -v, -p, -F.
+'\" Added notes to patch senders.
+'\"
+'\" Revision 1.3 85/03/26 15:11:06 lwall
+'\" Frozen.
+'\"
+'\" Revision 1.2.1.4 85/03/12 16:14:27 lwall
+'\" Documented -p.
+'\"
+'\" Revision 1.2.1.3 85/03/12 16:09:41 lwall
+'\" Documented -D.
+'\"
+'\" Revision 1.2.1.2 84/12/05 11:06:55 lwall
+'\" Added -l switch, and noted bistability bug.
+'\"
+'\" Revision 1.2.1.1 84/12/04 17:23:39 lwall
+'\" Branch for sdcrdcf changes.
+'\"
+'\" Revision 1.2 84/12/04 17:22:02 lwall
+'\" Baseline version.
+'\"
+.de Sh
+.br
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp
+.if t .sp .5v
+.if n .sp
+..
+'\"
+'\" Set up \*(-- to give an unbreakable dash;
+'\" string Tr holds user defined translation string.
+'\" Bell System Logo is used as a dummy character.
+'\"
+'\" Shut up a groff -ww warning.
+.if \n(.g .if !dTr .ds Tr
+.ie n \{\
+.tr \(*W-\*(Tr
+.ds -- \(*W-
+.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+.ds L" ""
+.ds R" ""
+.ds L' '
+.ds R' '
+'br \}
+.el \{\
+.ds -- \(em\|
+.tr \*(Tr
+.ds L" ``
+.ds R" ''
+.ds L' `
+.ds R' '
+'br\}
+.TH PATCH 1 LOCAL
+.SH NAME
+patch - apply a diff file to an original
+.SH SYNOPSIS
+.B patch
+[options] [origfile [patchfile]] [+ [options] [origfile]]...
+.sp
+but usually just
+.sp
+.B patch
+<patchfile
+.SH DESCRIPTION
+.I Patch
+will take a patch file containing any of the four forms of difference
+listing produced by the
+.I diff
+program and apply those differences to an original file, producing a patched
+version.
+By default, the patched version is put in place of the original, with
+the original file backed up to the same name with the
+extension \*(L".orig\*(R" (\*(L"~\*(R" on systems that do not
+support long filenames), or as specified by the
+.BR -b ,
+.BR -B ,
+or
+.B -V
+switches.
+The extension used for making backup files may also be specified in the
+.B SIMPLE_BACKUP_SUFFIX
+environment variable, which is overridden by above switches.
+.PP
+If the backup file already exists,
+.B patch
+creates a new backup file name by changing the first lowercase letter
+in the last component of the file's name into uppercase. If there are
+no more lowercase letters in the name, it removes the first character
+from the name. It repeats this process until it comes up with a
+backup file that does not already exist.
+.PP
+You may also specify where you want the output to go with a
+.B -o
+switch; if that file already exists, it is backed up first.
+.PP
+If
+.I patchfile
+is omitted, or is a hyphen, the patch will be read from standard input.
+.PP
+Upon startup, patch will attempt to determine the type of the diff listing,
+unless over-ruled by a
+.BR -c ,
+.BR -e ,
+.BR -n ,
+or
+.B -u
+switch.
+Context diffs (old-style, new-style, and unified) and
+normal diffs are applied by the
+.I patch
+program itself, while ed diffs are simply fed to the
+.I ed
+editor via a pipe.
+.PP
+.I Patch
+will try to skip any leading garbage, apply the diff,
+and then skip any trailing garbage.
+Thus you could feed an article or message containing a
+diff listing to
+.IR patch ,
+and it should work.
+If the entire diff is indented by a consistent amount,
+this will be taken into account.
+.PP
+With context diffs, and to a lesser extent with normal diffs,
+.I patch
+can detect when the line numbers mentioned in the patch are incorrect,
+and will attempt to find the correct place to apply each hunk of the patch.
+As a first guess, it takes the line number mentioned for the hunk, plus or
+minus any offset used in applying the previous hunk.
+If that is not the correct place,
+.I patch
+will scan both forwards and backwards for a set of lines matching the context
+given in the hunk.
+First
+.I patch
+looks for a place where all lines of the context match.
+If no such place is found, and it's a context diff, and the maximum fuzz factor
+is set to 1 or more, then another scan takes place ignoring the first and last
+line of context.
+If that fails, and the maximum fuzz factor is set to 2 or more,
+the first two and last two lines of context are ignored,
+and another scan is made.
+(The default maximum fuzz factor is 2.)
+If
+.I patch
+cannot find a place to install that hunk of the patch, it will put the
+hunk out to a reject file, which normally is the name of the output file
+plus \*(L".rej\*(R" (\*(L"#\*(R" on systems that do not support
+long filenames).
+(Note that the rejected hunk will come out in context diff form whether the
+input patch was a context diff or a normal diff.
+If the input was a normal diff, many of the contexts will simply be null.)
+The line numbers on the hunks in the reject file may be different than
+in the patch file: they reflect the approximate location patch thinks the
+failed hunks belong in the new file rather than the old one.
+.PP
+As each hunk is completed, you will be told whether the hunk succeeded or
+failed, and which line (in the new file)
+.I patch
+thought the hunk should go on.
+If this is different from the line number specified in the diff you will
+be told the offset.
+A single large offset MAY be an indication that a hunk was installed in the
+wrong place.
+You will also be told if a fuzz factor was used to make the match, in which
+case you should also be slightly suspicious.
+.PP
+If no original file is specified on the command line,
+.I patch
+will try to figure out from the leading garbage what the name of the file
+to edit is.
+In the header of a context diff, the filename is found from lines beginning
+with \*(L"***\*(R" or \*(L"---\*(R", with the shortest name of an existing
+file winning.
+Only context diffs have lines like that, but if there is an \*(L"Index:\*(R"
+line in the leading garbage,
+.I patch
+will try to use the filename from that line.
+The context diff header takes precedence over an Index line.
+If no filename can be intuited from the leading garbage, you will be asked
+for the name of the file to patch.
+.PP
+If the original file cannot be found or is read-only, but a suitable
+SCCS or RCS file is handy,
+.I patch
+will attempt to get or check out the file.
+.PP
+Additionally, if the leading garbage contains a \*(L"Prereq: \*(R" line,
+.I patch
+will take the first word from the prerequisites line (normally a version
+number) and check the input file to see if that word can be found.
+If not,
+.I patch
+will ask for confirmation before proceeding.
+.PP
+The upshot of all this is that you should be able to say, while in a news
+interface, the following:
+.Sp
+ | patch -d /usr/src/local/blurfl
+.Sp
+and patch a file in the blurfl directory directly from the article containing
+the patch.
+.PP
+If the patch file contains more than one patch,
+.I patch
+will try to apply each of them as if they came from separate patch files.
+This means, among other things, that it is assumed that the name of the file
+to patch must be determined for each diff listing,
+and that the garbage before each diff listing will
+be examined for interesting things such as filenames and revision level, as
+mentioned previously.
+You can give switches (and another original file name) for the second and
+subsequent patches by separating the corresponding argument lists
+by a \*(L'+\*(R'.
+(The argument list for a second or subsequent patch may not specify a new
+patch file, however.)
+.PP
+.I Patch
+recognizes the following switches:
+.TP 5
+.B \-b
+causes the next argument to be interpreted as the backup extension, to be
+used in place of \*(L".orig\*(R" or \*(L"~\*(R".
+.TP 5
+.B \-B
+causes the next argument to be interpreted as a prefix to the backup file
+name. If this argument is specified any argument from -b will be ignored.
+.TP 5
+.B \-c
+forces
+.I patch
+to interpret the patch file as a context diff.
+.TP 5
+.B \-d
+causes
+.I patch
+to interpret the next argument as a directory, and cd to it before doing
+anything else.
+.TP 5
+.B \-D
+causes
+.I patch
+to use the "#ifdef...#endif" construct to mark changes.
+The argument following will be used as the differentiating symbol.
+Note that, unlike the C compiler, there must be a space between the
+.B \-D
+and the argument.
+.TP 5
+.B \-e
+forces
+.I patch
+to interpret the patch file as an ed script.
+.TP 5
+.B \-E
+causes
+.I patch
+to remove output files that are empty after the patches have been applied.
+.TP 5
+.B \-f
+forces
+.I patch
+to assume that the user knows exactly what he or she is doing, and to not
+ask any questions. It assumes the following: skip patches for which a
+file to patch can't be found; patch files even though they have the
+wrong version for the ``Prereq:'' line in the patch; and assume that
+patches are not reversed even if they look like they are.
+This option does not suppress commentary; use
+.B \-s
+for that.
+.TP 5
+.B \-t
+similar to
+.BR \-f ,
+in that it suppresses questions, but makes some different assumptions:
+skip patches for which a file to patch can't be found (the same as \fB\-f\fP);
+skip patches for which the file has the wrong version for the ``Prereq:'' line
+in the patch; and assume that patches are reversed if they look like
+they are.
+.TP 5
+.B \-F<number>
+sets the maximum fuzz factor.
+This switch only applies to context diffs, and causes
+.I patch
+to ignore up to that many lines in looking for places to install a hunk.
+Note that a larger fuzz factor increases the odds of a faulty patch.
+The default fuzz factor is 2, and it may not be set to more than
+the number of lines of context in the context diff, ordinarily 3.
+.TP 5
+.B \-l
+causes the pattern matching to be done loosely, in case the tabs and
+spaces have been munged in your input file.
+Any sequence of whitespace in the pattern line will match any sequence
+in the input file.
+Normal characters must still match exactly.
+Each line of the context must still match a line in the input file.
+.TP 5
+.B \-n
+forces
+.I patch
+to interpret the patch file as a normal diff.
+.TP 5
+.B \-N
+causes
+.I patch
+to ignore patches that it thinks are reversed or already applied.
+See also
+.B \-R .
+.TP 5
+.B \-o
+causes the next argument to be interpreted as the output file name.
+.TP 5
+.B \-p<number>
+sets the pathname strip count,
+which controls how pathnames found in the patch file are treated, in case
+the you keep your files in a different directory than the person who sent
+out the patch.
+The strip count specifies how many slashes are to be stripped from
+the front of the pathname.
+(Any intervening directory names also go away.)
+For example, supposing the filename in the patch file was
+.sp
+ /u/howard/src/blurfl/blurfl.c
+.sp
+setting
+.B \-p
+or
+.B \-p0
+gives the entire pathname unmodified,
+.B \-p1
+gives
+.sp
+ u/howard/src/blurfl/blurfl.c
+.sp
+without the leading slash,
+.B \-p4
+gives
+.sp
+ blurfl/blurfl.c
+.sp
+and not specifying
+.B \-p
+at all just gives you "blurfl.c", unless all of the directories in the
+leading path (u/howard/src/blurfl) exist and that path is relative,
+in which case you get the entire pathname unmodified.
+Whatever you end up with is looked for either in the current directory,
+or the directory specified by the
+.B \-d
+switch.
+.TP 5
+.B \-r
+causes the next argument to be interpreted as the reject file name.
+.TP 5
+.B \-R
+tells
+.I patch
+that this patch was created with the old and new files swapped.
+(Yes, I'm afraid that does happen occasionally, human nature being what it
+is.)
+.I Patch
+will attempt to swap each hunk around before applying it.
+Rejects will come out in the swapped format.
+The
+.B \-R
+switch will not work with ed diff scripts because there is too little
+information to reconstruct the reverse operation.
+.Sp
+If the first hunk of a patch fails,
+.I patch
+will reverse the hunk to see if it can be applied that way.
+If it can, you will be asked if you want to have the
+.B \-R
+switch set.
+If it can't, the patch will continue to be applied normally.
+(Note: this method cannot detect a reversed patch if it is a normal diff
+and if the first command is an append (i.e. it should have been a delete)
+since appends always succeed, due to the fact that a null context will match
+anywhere.
+Luckily, most patches add or change lines rather than delete them, so most
+reversed normal diffs will begin with a delete, which will fail, triggering
+the heuristic.)
+.TP 5
+.B \-s
+makes
+.I patch
+do its work silently, unless an error occurs.
+.TP 5
+.B \-S
+causes
+.I patch
+to ignore this patch from the patch file, but continue on looking
+for the next patch in the file.
+Thus
+.sp
+ patch -S + -S + <patchfile
+.sp
+will ignore the first and second of three patches.
+.TP 5
+.B \-u
+forces
+.I patch
+to interpret the patch file as a unified context diff (a unidiff).
+.TP 5
+.B \-v
+causes
+.I patch
+to print out its revision header and patch level.
+.TP 5
+.B \-V
+causes the next argument to be interpreted as a method for creating
+backup file names. The type of backups made can also be given in the
+.B VERSION_CONTROL
+environment variable, which is overridden by this option.
+The
+.B -B
+option overrides this option, causing the prefix to always be used for
+making backup file names.
+The value of the
+.B VERSION_CONTROL
+environment variable and the argument to the
+.B -V
+option are like the GNU
+Emacs `version-control' variable; they also recognize synonyms that
+are more descriptive. The valid values are (unique abbreviations are
+accepted):
+.RS
+.TP
+`t' or `numbered'
+Always make numbered backups.
+.TP
+`nil' or `existing'
+Make numbered backups of files that already
+have them, simple backups of the others.
+This is the default.
+.TP
+`never' or `simple'
+Always make simple backups.
+.RE
+.TP 5
+.B \-x<number>
+sets internal debugging flags, and is of interest only to
+.I patch
+patchers.
+.SH AUTHOR
+Larry Wall <lwall@netlabs.com>
+.br
+with many other contributors.
+.SH ENVIRONMENT
+.TP
+.B TMPDIR
+Directory to put temporary files in; default is /tmp.
+.TP
+.B SIMPLE_BACKUP_SUFFIX
+Extension to use for backup file names instead of \*(L".orig\*(R" or
+\*(L"~\*(R".
+.TP
+.B VERSION_CONTROL
+Selects when numbered backup files are made.
+.SH FILES
+$TMPDIR/patch*
+.SH SEE ALSO
+diff(1)
+.SH NOTES FOR PATCH SENDERS
+There are several things you should bear in mind if you are going to
+be sending out patches.
+First, you can save people a lot of grief by keeping a patchlevel.h file
+which is patched to increment the patch level as the first diff in the
+patch file you send out.
+If you put a Prereq: line in with the patch, it won't let them apply
+patches out of order without some warning.
+Second, make sure you've specified the filenames right, either in a
+context diff header, or with an Index: line.
+If you are patching something in a subdirectory, be sure to tell the patch
+user to specify a
+.B \-p
+switch as needed.
+Third, you can create a file by sending out a diff that compares a
+null file to the file you want to create.
+This will only work if the file you want to create doesn't exist already in
+the target directory.
+Fourth, take care not to send out reversed patches, since it makes people wonder
+whether they already applied the patch.
+Fifth, while you may be able to get away with putting 582 diff listings into
+one file, it is probably wiser to group related patches into separate files in
+case something goes haywire.
+.SH DIAGNOSTICS
+Too many to list here, but generally indicative that
+.I patch
+couldn't parse your patch file.
+.PP
+The message \*(L"Hmm...\*(R" indicates that there is unprocessed text in
+the patch file and that
+.I patch
+is attempting to intuit whether there is a patch in that text and, if so,
+what kind of patch it is.
+.PP
+.I Patch
+will exit with a non-zero status if any reject files were created.
+When applying a set of patches in a loop it behooves you to check this
+exit status so you don't apply a later patch to a partially patched file.
+.SH CAVEATS
+.I Patch
+cannot tell if the line numbers are off in an ed script, and can only detect
+bad line numbers in a normal diff when it finds a \*(L"change\*(R" or
+a \*(L"delete\*(R" command.
+A context diff using fuzz factor 3 may have the same problem.
+Until a suitable interactive interface is added, you should probably do
+a context diff in these cases to see if the changes made sense.
+Of course, compiling without errors is a pretty good indication that the patch
+worked, but not always.
+.PP
+.I Patch
+usually produces the correct results, even when it has to do a lot of
+guessing.
+However, the results are guaranteed to be correct only when the patch is
+applied to exactly the same version of the file that the patch was
+generated from.
+.SH BUGS
+Could be smarter about partial matches, excessively \&deviant offsets and
+swapped code, but that would take an extra pass.
+.PP
+If code has been duplicated (for instance with #ifdef OLDCODE ... #else ...
+#endif),
+.I patch
+is incapable of patching both versions, and, if it works at all, will likely
+patch the wrong one, and tell you that it succeeded to boot.
+.PP
+If you apply a patch you've already applied,
+.I patch
+will think it is a reversed patch, and offer to un-apply the patch.
+This could be construed as a feature.
+.rn }` ''
diff --git a/xc/util/patch/patchlevel.h b/xc/util/patch/patchlevel.h
new file mode 100644
index 000000000..c1169f19a
--- /dev/null
+++ b/xc/util/patch/patchlevel.h
@@ -0,0 +1,2 @@
+/* $XConsortium: patchlevel.h,v 3.2 94/09/14 21:31:55 gildea Exp $ */
+#define PATCHLEVEL "12u9.XC2"
diff --git a/xc/util/patch/pch.c b/xc/util/patch/pch.c
new file mode 100644
index 000000000..5bb7fd141
--- /dev/null
+++ b/xc/util/patch/pch.c
@@ -0,0 +1,1313 @@
+/* oldHeader: pch.c,v 2.0.1.7 88/06/03 15:13:28 lwall Locked $
+ * $XConsortium: pch.c,v 3.3 94/09/14 21:22:55 gildea Exp $
+ *
+ * Revision 2.0.2.0 90/05/01 22:17:51 davison
+ * patch12u: unidiff support added
+ *
+ * Revision 2.0.1.7 88/06/03 15:13:28 lwall
+ * patch10: Can now find patches in shar scripts.
+ * patch10: Hunks that swapped and then swapped back could core dump.
+ *
+ * Revision 2.0.1.6 87/06/04 16:18:13 lwall
+ * pch_swap didn't swap p_bfake and p_efake.
+ *
+ * Revision 2.0.1.5 87/01/30 22:47:42 lwall
+ * Improved responses to mangled patches.
+ *
+ * Revision 2.0.1.4 87/01/05 16:59:53 lwall
+ * New-style context diffs caused double call to free().
+ *
+ * Revision 2.0.1.3 86/11/14 10:08:33 lwall
+ * Fixed problem where a long pattern wouldn't grow the hunk.
+ * Also restored p_input_line when backtracking so error messages are right.
+ *
+ * Revision 2.0.1.2 86/11/03 17:49:52 lwall
+ * New-style delete triggers spurious assertion error.
+ *
+ * Revision 2.0.1.1 86/10/29 15:52:08 lwall
+ * Could falsely report new-style context diff.
+ *
+ * Revision 2.0 86/09/17 15:39:37 lwall
+ * Baseline for netwide release.
+ *
+ */
+
+#include "EXTERN.h"
+#include "common.h"
+#include "util.h"
+#include "INTERN.h"
+#include "pch.h"
+
+/* Patch (diff listing) abstract type. */
+
+static long p_filesize; /* size of the patch file */
+static LINENUM p_first; /* 1st line number */
+static LINENUM p_newfirst; /* 1st line number of replacement */
+static LINENUM p_ptrn_lines; /* # lines in pattern */
+static LINENUM p_repl_lines; /* # lines in replacement text */
+static LINENUM p_end = -1; /* last line in hunk */
+static LINENUM p_max; /* max allowed value of p_end */
+static LINENUM p_context = 3; /* # of context lines */
+static LINENUM p_input_line = 0; /* current line # from patch file */
+static char **p_line = Null(char**); /* the text of the hunk */
+static short *p_len = Null(short*); /* length of each line */
+static char *p_char = Nullch; /* +, -, and ! */
+static int hunkmax = INITHUNKMAX; /* size of above arrays to begin with */
+static int p_indent; /* indent to patch */
+static LINENUM p_base; /* where to intuit this time */
+static LINENUM p_bline; /* line # of p_base */
+static LINENUM p_start; /* where intuit found a patch */
+static LINENUM p_sline; /* and the line number for it */
+static LINENUM p_hunk_beg; /* line number of current hunk */
+static LINENUM p_efake = -1; /* end of faked up lines--don't free */
+static LINENUM p_bfake = -1; /* beg of faked up lines */
+
+/* Prepare to look for the next patch in the patch file. */
+
+void
+re_patch()
+{
+ p_first = Nulline;
+ p_newfirst = Nulline;
+ p_ptrn_lines = Nulline;
+ p_repl_lines = Nulline;
+ p_end = (LINENUM)-1;
+ p_max = Nulline;
+ p_indent = 0;
+}
+
+/* Open the patch file at the beginning of time. */
+
+void
+open_patch_file(filename)
+char *filename;
+{
+ if (filename == Nullch || !*filename || strEQ(filename, "-")) {
+ pfp = fopen(TMPPATNAME, "w");
+ if (pfp == Nullfp)
+ pfatal2("can't create %s", TMPPATNAME);
+ while (fgets(buf, sizeof buf, stdin) != Nullch)
+ fputs(buf, pfp);
+ Fclose(pfp);
+ filename = TMPPATNAME;
+ }
+ pfp = fopen(filename, "r");
+ if (pfp == Nullfp)
+ pfatal2("patch file %s not found", filename);
+ Fstat(fileno(pfp), &filestat);
+ p_filesize = filestat.st_size;
+ next_intuit_at(0L,1L); /* start at the beginning */
+ set_hunkmax();
+}
+
+/* Make sure our dynamically realloced tables are malloced to begin with. */
+
+void
+set_hunkmax()
+{
+#ifndef lint
+ if (p_line == Null(char**))
+ p_line = (char**) malloc((MEM)hunkmax * sizeof(char *));
+ if (p_len == Null(short*))
+ p_len = (short*) malloc((MEM)hunkmax * sizeof(short));
+#endif
+ if (p_char == Nullch)
+ p_char = (char*) malloc((MEM)hunkmax * sizeof(char));
+}
+
+/* Enlarge the arrays containing the current hunk of patch. */
+
+void
+grow_hunkmax()
+{
+ hunkmax *= 2;
+ /*
+ * Note that on most systems, only the p_line array ever gets fresh memory
+ * since p_len can move into p_line's old space, and p_char can move into
+ * p_len's old space. Not on PDP-11's however. But it doesn't matter.
+ */
+ assert(p_line != Null(char**) && p_len != Null(short*) && p_char != Nullch);
+#ifndef lint
+ p_line = (char**) realloc((char*)p_line, (MEM)hunkmax * sizeof(char *));
+ p_len = (short*) realloc((char*)p_len, (MEM)hunkmax * sizeof(short));
+ p_char = (char*) realloc((char*)p_char, (MEM)hunkmax * sizeof(char));
+#endif
+ if (p_line != Null(char**) && p_len != Null(short*) && p_char != Nullch)
+ return;
+ if (!using_plan_a)
+ fatal1("out of memory\n");
+ out_of_mem = TRUE; /* whatever is null will be allocated again */
+ /* from within plan_a(), of all places */
+}
+
+/* True if the remainder of the patch file contains a diff of some sort. */
+
+bool
+there_is_another_patch()
+{
+ if (p_base != 0L && p_base >= p_filesize) {
+ if (verbose)
+ say1("done\n");
+ return FALSE;
+ }
+ if (verbose)
+ say1("Hmm...");
+ diff_type = intuit_diff_type();
+ if (!diff_type) {
+ if (p_base != 0L) {
+ if (verbose)
+ say1(" Ignoring the trailing garbage.\ndone\n");
+ }
+ else
+ say1(" I can't seem to find a patch in there anywhere.\n");
+ return FALSE;
+ }
+ if (verbose)
+ say3(" %sooks like %s to me...\n",
+ (p_base == 0L ? "L" : "The next patch l"),
+ diff_type == UNI_DIFF ? "a unified diff" :
+ diff_type == CONTEXT_DIFF ? "a context diff" :
+ diff_type == NEW_CONTEXT_DIFF ? "a new-style context diff" :
+ diff_type == NORMAL_DIFF ? "a normal diff" :
+ "an ed script" );
+ if (p_indent && verbose)
+ say3("(Patch is indented %d space%s.)\n", p_indent, p_indent==1?"":"s");
+ skip_to(p_start,p_sline);
+ while (filearg[0] == Nullch) {
+ if (force || batch) {
+ say1("No file to patch. Skipping...\n");
+ filearg[0] = savestr(bestguess);
+ skip_rest_of_patch = TRUE;
+ return TRUE;
+ }
+ ask1("File to patch: ");
+ if (*buf != '\n') {
+ if (bestguess)
+ free(bestguess);
+ bestguess = savestr(buf);
+ filearg[0] = fetchname(buf, 0, FALSE);
+ }
+ if (filearg[0] == Nullch) {
+#ifndef WIN32
+ ask1("No file found--skip this patch? [n] ");
+ if (*buf != 'y') {
+ continue;
+ }
+ if (verbose)
+ say1("Skipping patch...\n");
+#else
+ if (verbose)
+ say1("File not found--skipping patch...\n");
+#endif
+ filearg[0] = fetchname(bestguess, 0, TRUE);
+ skip_rest_of_patch = TRUE;
+ return TRUE;
+ }
+ }
+ return TRUE;
+}
+
+/* Determine what kind of diff is in the remaining part of the patch file. */
+
+int
+intuit_diff_type()
+{
+ Reg4 long this_line = 0;
+ Reg5 long previous_line;
+ Reg6 long first_command_line = -1;
+ long fcl_line;
+ Reg7 bool last_line_was_command = FALSE;
+ Reg8 bool this_is_a_command = FALSE;
+ Reg9 bool stars_last_line = FALSE;
+ Reg10 bool stars_this_line = FALSE;
+ Reg3 int indent;
+ Reg1 char *s;
+ Reg2 char *t;
+ char *indtmp = Nullch;
+ char *oldtmp = Nullch;
+ char *newtmp = Nullch;
+ char *indname = Nullch;
+ char *oldname = Nullch;
+ char *newname = Nullch;
+ Reg11 int retval;
+ bool no_filearg = (filearg[0] == Nullch);
+
+ ok_to_create_file = FALSE;
+ Fseek(pfp, p_base, 0);
+ p_input_line = p_bline - 1;
+ for (;;) {
+ previous_line = this_line;
+ last_line_was_command = this_is_a_command;
+ stars_last_line = stars_this_line;
+ this_line = ftell(pfp);
+ indent = 0;
+ p_input_line++;
+ if (fgets(buf, sizeof buf, pfp) == Nullch) {
+ if (first_command_line >= 0L) {
+ /* nothing but deletes!? */
+ p_start = first_command_line;
+ p_sline = fcl_line;
+ retval = ED_DIFF;
+ goto scan_exit;
+ }
+ else {
+ p_start = this_line;
+ p_sline = p_input_line;
+ retval = 0;
+ goto scan_exit;
+ }
+ }
+ for (s = buf; *s == ' ' || *s == '\t' || *s == 'X'; s++) {
+ if (*s == '\t')
+ indent += 8 - (indent % 8);
+ else
+ indent++;
+ }
+ for (t=s; isdigit(*t) || *t == ','; t++) ;
+ this_is_a_command = (isdigit(*s) &&
+ (*t == 'd' || *t == 'c' || *t == 'a') );
+ if (first_command_line < 0L && this_is_a_command) {
+ first_command_line = this_line;
+ fcl_line = p_input_line;
+ p_indent = indent; /* assume this for now */
+ }
+ if (!stars_last_line && strnEQ(s, "*** ", 4))
+ oldtmp = savestr(s+4);
+ else if (strnEQ(s, "--- ", 4))
+ newtmp = savestr(s+4);
+ else if (strnEQ(s, "+++ ", 4))
+ oldtmp = savestr(s+4); /* pretend it is the old name */
+ else if (strnEQ(s, "Index:", 6))
+ indtmp = savestr(s+6);
+ else if (strnEQ(s, "Prereq:", 7)) {
+ for (t=s+7; isspace(*t); t++) ;
+ revision = savestr(t);
+ for (t=revision; *t && !isspace(*t); t++) ;
+ *t = '\0';
+ if (!*revision) {
+ free(revision);
+ revision = Nullch;
+ }
+ }
+ if ((!diff_type || diff_type == ED_DIFF) &&
+ first_command_line >= 0L &&
+ strEQ(s, ".\n") ) {
+ p_indent = indent;
+ p_start = first_command_line;
+ p_sline = fcl_line;
+ retval = ED_DIFF;
+ goto scan_exit;
+ }
+ if ((!diff_type || diff_type == UNI_DIFF) && strnEQ(s, "@@ -", 4)) {
+ if (!atol(s+3))
+ ok_to_create_file = TRUE;
+ p_indent = indent;
+ p_start = this_line;
+ p_sline = p_input_line;
+ retval = UNI_DIFF;
+ goto scan_exit;
+ }
+ stars_this_line = strnEQ(s, "********", 8);
+ if ((!diff_type || diff_type == CONTEXT_DIFF) && stars_last_line &&
+ strnEQ(s, "*** ", 4)) {
+ if (!atol(s+4))
+ ok_to_create_file = TRUE;
+ /* if this is a new context diff the character just before */
+ /* the newline is a '*'. */
+ while (*s != '\n')
+ s++;
+ p_indent = indent;
+ p_start = previous_line;
+ p_sline = p_input_line - 1;
+ retval = (*(s-1) == '*' ? NEW_CONTEXT_DIFF : CONTEXT_DIFF);
+ goto scan_exit;
+ }
+ if ((!diff_type || diff_type == NORMAL_DIFF) &&
+ last_line_was_command &&
+ (strnEQ(s, "< ", 2) || strnEQ(s, "> ", 2)) ) {
+ p_start = previous_line;
+ p_sline = p_input_line - 1;
+ p_indent = indent;
+ retval = NORMAL_DIFF;
+ goto scan_exit;
+ }
+ }
+ scan_exit:
+ if (no_filearg) {
+ if (indtmp != Nullch)
+ indname = fetchname(indtmp, strippath, ok_to_create_file);
+ if (oldtmp != Nullch)
+ oldname = fetchname(oldtmp, strippath, ok_to_create_file);
+ if (newtmp != Nullch)
+ newname = fetchname(newtmp, strippath, ok_to_create_file);
+ if (oldname && newname) {
+ if (strlen(oldname) < strlen(newname))
+ filearg[0] = savestr(oldname);
+ else
+ filearg[0] = savestr(newname);
+ }
+ else if (oldname)
+ filearg[0] = savestr(oldname);
+ else if (newname)
+ filearg[0] = savestr(newname);
+ else if (indname)
+ filearg[0] = savestr(indname);
+ }
+ if (bestguess) {
+ free(bestguess);
+ bestguess = Nullch;
+ }
+ if (filearg[0] != Nullch)
+ bestguess = savestr(filearg[0]);
+ else if (indtmp != Nullch)
+ bestguess = fetchname(indtmp, strippath, TRUE);
+ else {
+ if (oldtmp != Nullch)
+ oldname = fetchname(oldtmp, strippath, TRUE);
+ if (newtmp != Nullch)
+ newname = fetchname(newtmp, strippath, TRUE);
+ if (oldname && newname) {
+ if (strlen(oldname) < strlen(newname))
+ bestguess = savestr(oldname);
+ else
+ bestguess = savestr(newname);
+ }
+ else if (oldname)
+ bestguess = savestr(oldname);
+ else if (newname)
+ bestguess = savestr(newname);
+ }
+ if (indtmp != Nullch)
+ free(indtmp);
+ if (oldtmp != Nullch)
+ free(oldtmp);
+ if (newtmp != Nullch)
+ free(newtmp);
+ if (indname != Nullch)
+ free(indname);
+ if (oldname != Nullch)
+ free(oldname);
+ if (newname != Nullch)
+ free(newname);
+ return retval;
+}
+
+/* Remember where this patch ends so we know where to start up again. */
+
+void
+next_intuit_at(file_pos,file_line)
+long file_pos;
+long file_line;
+{
+ p_base = file_pos;
+ p_bline = file_line;
+}
+
+/* Basically a verbose fseek() to the actual diff listing. */
+
+void
+skip_to(file_pos,file_line)
+long file_pos;
+long file_line;
+{
+ char *ret;
+
+ assert(p_base <= file_pos);
+ if (verbose && p_base < file_pos) {
+ Fseek(pfp, p_base, 0);
+ say1("The text leading up to this was:\n--------------------------\n");
+ while (ftell(pfp) < file_pos) {
+ ret = fgets(buf, sizeof buf, pfp);
+ assert(ret != Nullch);
+ say2("|%s", buf);
+ }
+ say1("--------------------------\n");
+ }
+ else
+ Fseek(pfp, file_pos, 0);
+ p_input_line = file_line - 1;
+}
+
+/* Make this a function for better debugging. */
+static void
+malformed ()
+{
+ fatal3("malformed patch at line %ld: %s", p_input_line, buf);
+ /* about as informative as "Syntax error" in C */
+}
+
+/* True if there is more of the current diff listing to process. */
+
+bool
+another_hunk()
+{
+ Reg1 char *s;
+ Reg8 char *ret;
+ Reg2 int context = 0;
+
+ while (p_end >= 0) {
+ if (p_end == p_efake)
+ p_end = p_bfake; /* don't free twice */
+ else
+ free(p_line[p_end]);
+ p_end--;
+ }
+ assert(p_end == -1);
+ p_efake = -1;
+
+ p_max = hunkmax; /* gets reduced when --- found */
+ if (diff_type == CONTEXT_DIFF || diff_type == NEW_CONTEXT_DIFF) {
+ long line_beginning = ftell(pfp);
+ /* file pos of the current line */
+ LINENUM repl_beginning = 0; /* index of --- line */
+ Reg4 LINENUM fillcnt = 0; /* #lines of missing ptrn or repl */
+ Reg5 LINENUM fillsrc; /* index of first line to copy */
+ Reg6 LINENUM filldst; /* index of first missing line */
+ bool ptrn_spaces_eaten = FALSE; /* ptrn was slightly misformed */
+ Reg9 bool repl_could_be_missing = TRUE;
+ /* no + or ! lines in this hunk */
+ bool repl_missing = FALSE; /* we are now backtracking */
+ long repl_backtrack_position = 0;
+ /* file pos of first repl line */
+ LINENUM repl_patch_line; /* input line number for same */
+ Reg7 LINENUM ptrn_copiable = 0;
+ /* # of copiable lines in ptrn */
+
+ ret = pgets(buf, sizeof buf, pfp);
+ p_input_line++;
+ if (ret == Nullch || strnNE(buf, "********", 8)) {
+ next_intuit_at(line_beginning,p_input_line);
+ return FALSE;
+ }
+ p_context = 100;
+ p_hunk_beg = p_input_line + 1;
+ while (p_end < p_max) {
+ line_beginning = ftell(pfp);
+ ret = pgets(buf, sizeof buf, pfp);
+ p_input_line++;
+ if (ret == Nullch) {
+ if (p_max - p_end < 4)
+ Strcpy(buf, " \n"); /* assume blank lines got chopped */
+ else {
+ if (repl_beginning && repl_could_be_missing) {
+ repl_missing = TRUE;
+ goto hunk_done;
+ }
+ fatal1("unexpected end of file in patch\n");
+ }
+ }
+ p_end++;
+ assert(p_end < hunkmax);
+ p_char[p_end] = *buf;
+#ifdef zilog
+ p_line[(short)p_end] = Nullch;
+#else
+ p_line[p_end] = Nullch;
+#endif
+ switch (*buf) {
+ case '*':
+ if (strnEQ(buf, "********", 8)) {
+ if (repl_beginning && repl_could_be_missing) {
+ repl_missing = TRUE;
+ goto hunk_done;
+ }
+ else
+ fatal2("unexpected end of hunk at line %ld\n",
+ p_input_line);
+ }
+ if (p_end != 0) {
+ if (repl_beginning && repl_could_be_missing) {
+ repl_missing = TRUE;
+ goto hunk_done;
+ }
+ fatal3("unexpected *** at line %ld: %s", p_input_line, buf);
+ }
+ context = 0;
+ p_line[p_end] = savestr(buf);
+ if (out_of_mem) {
+ p_end--;
+ return FALSE;
+ }
+ for (s=buf; *s && !isdigit(*s); s++) ;
+ if (!*s)
+ malformed ();
+ if (strnEQ(s,"0,0",3))
+ strcpy(s,s+2);
+ p_first = (LINENUM) atol(s);
+ while (isdigit(*s)) s++;
+ if (*s == ',') {
+ for (; *s && !isdigit(*s); s++) ;
+ if (!*s)
+ malformed ();
+ p_ptrn_lines = ((LINENUM)atol(s)) - p_first + 1;
+ }
+ else if (p_first)
+ p_ptrn_lines = 1;
+ else {
+ p_ptrn_lines = 0;
+ p_first = 1;
+ }
+ p_max = p_ptrn_lines + 6; /* we need this much at least */
+ while (p_max >= hunkmax)
+ grow_hunkmax();
+ p_max = hunkmax;
+ break;
+ case '-':
+ if (buf[1] == '-') {
+ if (repl_beginning ||
+ (p_end != p_ptrn_lines + 1 + (p_char[p_end-1] == '\n')))
+ {
+ if (p_end == 1) {
+ /* `old' lines were omitted - set up to fill */
+ /* them in from 'new' context lines. */
+ p_end = p_ptrn_lines + 1;
+ fillsrc = p_end + 1;
+ filldst = 1;
+ fillcnt = p_ptrn_lines;
+ }
+ else {
+ if (repl_beginning) {
+ if (repl_could_be_missing){
+ repl_missing = TRUE;
+ goto hunk_done;
+ }
+ fatal3(
+"duplicate \"---\" at line %ld--check line numbers at line %ld\n",
+ p_input_line, p_hunk_beg + repl_beginning);
+ }
+ else {
+ fatal4(
+"%s \"---\" at line %ld--check line numbers at line %ld\n",
+ (p_end <= p_ptrn_lines
+ ? "Premature"
+ : "Overdue" ),
+ p_input_line, p_hunk_beg);
+ }
+ }
+ }
+ repl_beginning = p_end;
+ repl_backtrack_position = ftell(pfp);
+ repl_patch_line = p_input_line;
+ p_line[p_end] = savestr(buf);
+ if (out_of_mem) {
+ p_end--;
+ return FALSE;
+ }
+ p_char[p_end] = '=';
+ for (s=buf; *s && !isdigit(*s); s++) ;
+ if (!*s)
+ malformed ();
+ p_newfirst = (LINENUM) atol(s);
+ while (isdigit(*s)) s++;
+ if (*s == ',') {
+ for (; *s && !isdigit(*s); s++) ;
+ if (!*s)
+ malformed ();
+ p_repl_lines = ((LINENUM)atol(s)) - p_newfirst + 1;
+ }
+ else if (p_newfirst)
+ p_repl_lines = 1;
+ else {
+ p_repl_lines = 0;
+ p_newfirst = 1;
+ }
+ p_max = p_repl_lines + p_end;
+ if (p_max > MAXHUNKSIZE)
+ fatal4("hunk too large (%ld lines) at line %ld: %s",
+ p_max, p_input_line, buf);
+ while (p_max >= hunkmax)
+ grow_hunkmax();
+ if (p_repl_lines != ptrn_copiable
+ && (p_context != 0 || p_repl_lines != 1))
+ repl_could_be_missing = FALSE;
+ break;
+ }
+ goto change_line;
+ case '+': case '!':
+ repl_could_be_missing = FALSE;
+ change_line:
+ if (buf[1] == '\n' && canonicalize)
+ strcpy(buf+1," \n");
+ if (!isspace(buf[1]) && buf[1] != '>' && buf[1] != '<' &&
+ repl_beginning && repl_could_be_missing) {
+ repl_missing = TRUE;
+ goto hunk_done;
+ }
+ if (context >= 0) {
+ if (context < p_context)
+ p_context = context;
+ context = -1000;
+ }
+ p_line[p_end] = savestr(buf+2);
+ if (out_of_mem) {
+ p_end--;
+ return FALSE;
+ }
+ break;
+ case '\t': case '\n': /* assume the 2 spaces got eaten */
+ if (repl_beginning && repl_could_be_missing &&
+ (!ptrn_spaces_eaten || diff_type == NEW_CONTEXT_DIFF) ) {
+ repl_missing = TRUE;
+ goto hunk_done;
+ }
+ p_line[p_end] = savestr(buf);
+ if (out_of_mem) {
+ p_end--;
+ return FALSE;
+ }
+ if (p_end != p_ptrn_lines + 1) {
+ ptrn_spaces_eaten |= (repl_beginning != 0);
+ context++;
+ if (!repl_beginning)
+ ptrn_copiable++;
+ p_char[p_end] = ' ';
+ }
+ break;
+ case ' ':
+ if (!isspace(buf[1]) &&
+ repl_beginning && repl_could_be_missing) {
+ repl_missing = TRUE;
+ goto hunk_done;
+ }
+ context++;
+ if (!repl_beginning)
+ ptrn_copiable++;
+ p_line[p_end] = savestr(buf+2);
+ if (out_of_mem) {
+ p_end--;
+ return FALSE;
+ }
+ break;
+ default:
+ if (repl_beginning && repl_could_be_missing) {
+ repl_missing = TRUE;
+ goto hunk_done;
+ }
+ malformed ();
+ }
+ /* set up p_len for strncmp() so we don't have to */
+ /* assume null termination */
+ if (p_line[p_end])
+ p_len[p_end] = strlen(p_line[p_end]);
+ else
+ p_len[p_end] = 0;
+ }
+
+ hunk_done:
+ if (p_end >=0 && !repl_beginning)
+ fatal2("no --- found in patch at line %ld\n", pch_hunk_beg());
+
+ if (repl_missing) {
+
+ /* reset state back to just after --- */
+ p_input_line = repl_patch_line;
+ for (p_end--; p_end > repl_beginning; p_end--)
+ free(p_line[p_end]);
+ Fseek(pfp, repl_backtrack_position, 0);
+
+ /* redundant 'new' context lines were omitted - set */
+ /* up to fill them in from the old file context */
+ if (!p_context && p_repl_lines == 1) {
+ p_repl_lines = 0;
+ p_max--;
+ }
+ fillsrc = 1;
+ filldst = repl_beginning+1;
+ fillcnt = p_repl_lines;
+ p_end = p_max;
+ }
+ else if (!p_context && fillcnt == 1) {
+ /* the first hunk was a null hunk with no context */
+ /* and we were expecting one line -- fix it up. */
+ while (filldst < p_end) {
+ p_line[filldst] = p_line[filldst+1];
+ p_char[filldst] = p_char[filldst+1];
+ p_len[filldst] = p_len[filldst+1];
+ filldst++;
+ }
+#if 0
+ repl_beginning--; /* this doesn't need to be fixed */
+#endif
+ p_end--;
+ p_first++; /* do append rather than insert */
+ fillcnt = 0;
+ p_ptrn_lines = 0;
+ }
+
+ if (diff_type == CONTEXT_DIFF &&
+ (fillcnt || (p_first > 1 && ptrn_copiable > 2*p_context)) ) {
+ if (verbose)
+ say4("%s\n%s\n%s\n",
+"(Fascinating--this is really a new-style context diff but without",
+"the telltale extra asterisks on the *** line that usually indicate",
+"the new style...)");
+ diff_type = NEW_CONTEXT_DIFF;
+ }
+
+ /* if there were omitted context lines, fill them in now */
+ if (fillcnt) {
+ p_bfake = filldst; /* remember where not to free() */
+ p_efake = filldst + fillcnt - 1;
+ while (fillcnt-- > 0) {
+ while (fillsrc <= p_end && p_char[fillsrc] != ' ')
+ fillsrc++;
+ if (fillsrc > p_end)
+ fatal2("replacement text or line numbers mangled in hunk at line %ld\n",
+ p_hunk_beg);
+ p_line[filldst] = p_line[fillsrc];
+ p_char[filldst] = p_char[fillsrc];
+ p_len[filldst] = p_len[fillsrc];
+ fillsrc++; filldst++;
+ }
+ while (fillsrc <= p_end && fillsrc != repl_beginning &&
+ p_char[fillsrc] != ' ')
+ fillsrc++;
+#ifdef DEBUGGING
+ if (debug & 64)
+ printf("fillsrc %ld, filldst %ld, rb %ld, e+1 %ld\n",
+ fillsrc,filldst,repl_beginning,p_end+1);
+#endif
+ assert(fillsrc==p_end+1 || fillsrc==repl_beginning);
+ assert(filldst==p_end+1 || filldst==repl_beginning);
+ }
+ }
+ else if (diff_type == UNI_DIFF) {
+ long line_beginning = ftell(pfp);
+ /* file pos of the current line */
+ Reg4 LINENUM fillsrc; /* index of old lines */
+ Reg5 LINENUM filldst; /* index of new lines */
+ char ch;
+
+ ret = pgets(buf, sizeof buf, pfp);
+ p_input_line++;
+ if (ret == Nullch || strnNE(buf, "@@ -", 4)) {
+ next_intuit_at(line_beginning,p_input_line);
+ return FALSE;
+ }
+ s = buf+4;
+ if (!*s)
+ malformed ();
+ p_first = (LINENUM) atol(s);
+ while (isdigit(*s)) s++;
+ if (*s == ',') {
+ p_ptrn_lines = (LINENUM) atol(++s);
+ while (isdigit(*s)) s++;
+ } else
+ p_ptrn_lines = 1;
+ if (*s == ' ') s++;
+ if (*s != '+' || !*++s)
+ malformed ();
+ p_newfirst = (LINENUM) atol(s);
+ while (isdigit(*s)) s++;
+ if (*s == ',') {
+ p_repl_lines = (LINENUM) atol(++s);
+ while (isdigit(*s)) s++;
+ } else
+ p_repl_lines = 1;
+ if (*s == ' ') s++;
+ if (*s != '@')
+ malformed ();
+ if (!p_ptrn_lines)
+ p_first++; /* do append rather than insert */
+ p_max = p_ptrn_lines + p_repl_lines + 1;
+ while (p_max >= hunkmax)
+ grow_hunkmax();
+ fillsrc = 1;
+ filldst = fillsrc + p_ptrn_lines;
+ p_end = filldst + p_repl_lines;
+ Sprintf(buf,"*** %ld,%ld ****\n",p_first,p_first + p_ptrn_lines - 1);
+ p_line[0] = savestr(buf);
+ if (out_of_mem) {
+ p_end = -1;
+ return FALSE;
+ }
+ p_char[0] = '*';
+ Sprintf(buf,"--- %ld,%ld ----\n",p_newfirst,p_newfirst+p_repl_lines-1);
+ p_line[filldst] = savestr(buf);
+ if (out_of_mem) {
+ p_end = 0;
+ return FALSE;
+ }
+ p_char[filldst++] = '=';
+ p_context = 100;
+ context = 0;
+ p_hunk_beg = p_input_line + 1;
+ while (fillsrc <= p_ptrn_lines || filldst <= p_end) {
+ line_beginning = ftell(pfp);
+ ret = pgets(buf, sizeof buf, pfp);
+ p_input_line++;
+ if (ret == Nullch) {
+ if (p_max - filldst < 3)
+ Strcpy(buf, " \n"); /* assume blank lines got chopped */
+ else {
+ fatal1("unexpected end of file in patch\n");
+ }
+ }
+ if (*buf == '\t' || *buf == '\n') {
+ ch = ' '; /* assume the space got eaten */
+ s = savestr(buf);
+ }
+ else {
+ ch = *buf;
+ s = savestr(buf+1);
+ }
+ if (out_of_mem) {
+ while (--filldst > p_ptrn_lines)
+ free(p_line[filldst]);
+ p_end = fillsrc-1;
+ return FALSE;
+ }
+ switch (ch) {
+ case '-':
+ if (fillsrc > p_ptrn_lines) {
+ free(s);
+ p_end = filldst-1;
+ malformed ();
+ }
+ p_char[fillsrc] = ch;
+ p_line[fillsrc] = s;
+ p_len[fillsrc++] = strlen(s);
+ break;
+ case '=':
+ ch = ' ';
+ /* FALL THROUGH */
+ case ' ':
+ if (fillsrc > p_ptrn_lines) {
+ free(s);
+ while (--filldst > p_ptrn_lines)
+ free(p_line[filldst]);
+ p_end = fillsrc-1;
+ malformed ();
+ }
+ context++;
+ p_char[fillsrc] = ch;
+ p_line[fillsrc] = s;
+ p_len[fillsrc++] = strlen(s);
+ s = savestr(s);
+ if (out_of_mem) {
+ while (--filldst > p_ptrn_lines)
+ free(p_line[filldst]);
+ p_end = fillsrc-1;
+ return FALSE;
+ }
+ /* FALL THROUGH */
+ case '+':
+ if (filldst > p_end) {
+ free(s);
+ while (--filldst > p_ptrn_lines)
+ free(p_line[filldst]);
+ p_end = fillsrc-1;
+ malformed ();
+ }
+ p_char[filldst] = ch;
+ p_line[filldst] = s;
+ p_len[filldst++] = strlen(s);
+ break;
+ default:
+ p_end = filldst;
+ malformed ();
+ }
+ if (ch != ' ' && context > 0) {
+ if (context < p_context)
+ p_context = context;
+ context = -1000;
+ }
+ }/* while */
+ }
+ else { /* normal diff--fake it up */
+ char hunk_type;
+ Reg3 int i;
+ LINENUM min, max;
+ long line_beginning = ftell(pfp);
+
+ p_context = 0;
+ ret = pgets(buf, sizeof buf, pfp);
+ p_input_line++;
+ if (ret == Nullch || !isdigit(*buf)) {
+ next_intuit_at(line_beginning,p_input_line);
+ return FALSE;
+ }
+ p_first = (LINENUM)atol(buf);
+ for (s=buf; isdigit(*s); s++) ;
+ if (*s == ',') {
+ p_ptrn_lines = (LINENUM)atol(++s) - p_first + 1;
+ while (isdigit(*s)) s++;
+ }
+ else
+ p_ptrn_lines = (*s != 'a');
+ hunk_type = *s;
+ if (hunk_type == 'a')
+ p_first++; /* do append rather than insert */
+ min = (LINENUM)atol(++s);
+ for (; isdigit(*s); s++) ;
+ if (*s == ',')
+ max = (LINENUM)atol(++s);
+ else
+ max = min;
+ if (hunk_type == 'd')
+ min++;
+ p_end = p_ptrn_lines + 1 + max - min + 1;
+ if (p_end > MAXHUNKSIZE)
+ fatal4("hunk too large (%ld lines) at line %ld: %s",
+ p_end, p_input_line, buf);
+ while (p_end >= hunkmax)
+ grow_hunkmax();
+ p_newfirst = min;
+ p_repl_lines = max - min + 1;
+ Sprintf(buf, "*** %ld,%ld\n", p_first, p_first + p_ptrn_lines - 1);
+ p_line[0] = savestr(buf);
+ if (out_of_mem) {
+ p_end = -1;
+ return FALSE;
+ }
+ p_char[0] = '*';
+ for (i=1; i<=p_ptrn_lines; i++) {
+ ret = pgets(buf, sizeof buf, pfp);
+ p_input_line++;
+ if (ret == Nullch)
+ fatal2("unexpected end of file in patch at line %ld\n",
+ p_input_line);
+ if (*buf != '<')
+ fatal2("< expected at line %ld of patch\n", p_input_line);
+ p_line[i] = savestr(buf+2);
+ if (out_of_mem) {
+ p_end = i-1;
+ return FALSE;
+ }
+ p_len[i] = strlen(p_line[i]);
+ p_char[i] = '-';
+ }
+ if (hunk_type == 'c') {
+ ret = pgets(buf, sizeof buf, pfp);
+ p_input_line++;
+ if (ret == Nullch)
+ fatal2("unexpected end of file in patch at line %ld\n",
+ p_input_line);
+ if (*buf != '-')
+ fatal2("--- expected at line %ld of patch\n", p_input_line);
+ }
+ Sprintf(buf, "--- %ld,%ld\n", min, max);
+ p_line[i] = savestr(buf);
+ if (out_of_mem) {
+ p_end = i-1;
+ return FALSE;
+ }
+ p_char[i] = '=';
+ for (i++; i<=p_end; i++) {
+ ret = pgets(buf, sizeof buf, pfp);
+ p_input_line++;
+ if (ret == Nullch)
+ fatal2("unexpected end of file in patch at line %ld\n",
+ p_input_line);
+ if (*buf != '>')
+ fatal2("> expected at line %ld of patch\n", p_input_line);
+ p_line[i] = savestr(buf+2);
+ if (out_of_mem) {
+ p_end = i-1;
+ return FALSE;
+ }
+ p_len[i] = strlen(p_line[i]);
+ p_char[i] = '+';
+ }
+ }
+ if (reverse) /* backwards patch? */
+ if (!pch_swap())
+ say1("Not enough memory to swap next hunk!\n");
+#ifdef DEBUGGING
+ if (debug & 2) {
+ int i;
+ char special;
+
+ for (i=0; i <= p_end; i++) {
+ if (i == p_ptrn_lines)
+ special = '^';
+ else
+ special = ' ';
+ fprintf(stderr, "%3d %c %c %s", i, p_char[i], special, p_line[i]);
+ Fflush(stderr);
+ }
+ }
+#endif
+ if (p_end+1 < hunkmax) /* paranoia reigns supreme... */
+ p_char[p_end+1] = '^'; /* add a stopper for apply_hunk */
+ return TRUE;
+}
+
+/* Input a line from the patch file, worrying about indentation. */
+
+char *
+pgets(bf,sz,fp)
+char *bf;
+int sz;
+FILE *fp;
+{
+ char *ret = fgets(bf, sz, fp);
+ Reg1 char *s;
+ Reg2 int indent = 0;
+
+ if (p_indent && ret != Nullch) {
+ for (s=buf;
+ indent < p_indent && (*s == ' ' || *s == '\t' || *s == 'X'); s++) {
+ if (*s == '\t')
+ indent += 8 - (indent % 7);
+ else
+ indent++;
+ }
+ if (buf != s)
+ Strcpy(buf, s);
+ }
+ return ret;
+}
+
+/* Reverse the old and new portions of the current hunk. */
+
+bool
+pch_swap()
+{
+ char **tp_line; /* the text of the hunk */
+ short *tp_len; /* length of each line */
+ char *tp_char; /* +, -, and ! */
+ Reg1 LINENUM i;
+ Reg2 LINENUM n;
+ bool blankline = FALSE;
+ Reg3 char *s;
+
+ i = p_first;
+ p_first = p_newfirst;
+ p_newfirst = i;
+
+ /* make a scratch copy */
+
+ tp_line = p_line;
+ tp_len = p_len;
+ tp_char = p_char;
+ p_line = Null(char**); /* force set_hunkmax to allocate again */
+ p_len = Null(short*);
+ p_char = Nullch;
+ set_hunkmax();
+ if (p_line == Null(char**) || p_len == Null(short*) || p_char == Nullch) {
+#ifndef lint
+ if (p_line == Null(char**))
+ free((char*)p_line);
+ p_line = tp_line;
+ if (p_len == Null(short*))
+ free((char*)p_len);
+ p_len = tp_len;
+#endif
+ if (p_char == Nullch)
+ free((char*)p_char);
+ p_char = tp_char;
+ return FALSE; /* not enough memory to swap hunk! */
+ }
+
+ /* now turn the new into the old */
+
+ i = p_ptrn_lines + 1;
+ if (tp_char[i] == '\n') { /* account for possible blank line */
+ blankline = TRUE;
+ i++;
+ }
+ if (p_efake >= 0) { /* fix non-freeable ptr range */
+ if (p_efake <= i)
+ n = p_end - i + 1;
+ else
+ n = -i;
+ p_efake += n;
+ p_bfake += n;
+ }
+ for (n=0; i <= p_end; i++,n++) {
+ p_line[n] = tp_line[i];
+ p_char[n] = tp_char[i];
+ if (p_char[n] == '+')
+ p_char[n] = '-';
+ p_len[n] = tp_len[i];
+ }
+ if (blankline) {
+ i = p_ptrn_lines + 1;
+ p_line[n] = tp_line[i];
+ p_char[n] = tp_char[i];
+ p_len[n] = tp_len[i];
+ n++;
+ }
+ assert(p_char[0] == '=');
+ p_char[0] = '*';
+ for (s=p_line[0]; *s; s++)
+ if (*s == '-')
+ *s = '*';
+
+ /* now turn the old into the new */
+
+ assert(tp_char[0] == '*');
+ tp_char[0] = '=';
+ for (s=tp_line[0]; *s; s++)
+ if (*s == '*')
+ *s = '-';
+ for (i=0; n <= p_end; i++,n++) {
+ p_line[n] = tp_line[i];
+ p_char[n] = tp_char[i];
+ if (p_char[n] == '-')
+ p_char[n] = '+';
+ p_len[n] = tp_len[i];
+ }
+ assert(i == p_ptrn_lines + 1);
+ i = p_ptrn_lines;
+ p_ptrn_lines = p_repl_lines;
+ p_repl_lines = i;
+#ifndef lint
+ if (tp_line == Null(char**))
+ free((char*)tp_line);
+ if (tp_len == Null(short*))
+ free((char*)tp_len);
+#endif
+ if (tp_char == Nullch)
+ free((char*)tp_char);
+ return TRUE;
+}
+
+/* Return the specified line position in the old file of the old context. */
+
+LINENUM
+pch_first()
+{
+ return p_first;
+}
+
+/* Return the number of lines of old context. */
+
+LINENUM
+pch_ptrn_lines()
+{
+ return p_ptrn_lines;
+}
+
+/* Return the probable line position in the new file of the first line. */
+
+LINENUM
+pch_newfirst()
+{
+ return p_newfirst;
+}
+
+/* Return the number of lines in the replacement text including context. */
+
+LINENUM
+pch_repl_lines()
+{
+ return p_repl_lines;
+}
+
+/* Return the number of lines in the whole hunk. */
+
+LINENUM
+pch_end()
+{
+ return p_end;
+}
+
+/* Return the number of context lines before the first changed line. */
+
+LINENUM
+pch_context()
+{
+ return p_context;
+}
+
+/* Return the length of a particular patch line. */
+
+short
+pch_line_len(line)
+LINENUM line;
+{
+ return p_len[line];
+}
+
+/* Return the control character (+, -, *, !, etc) for a patch line. */
+
+char
+pch_char(line)
+LINENUM line;
+{
+ return p_char[line];
+}
+
+/* Return a pointer to a particular patch line. */
+
+char *
+pfetch(line)
+LINENUM line;
+{
+ return p_line[line];
+}
+
+/* Return where in the patch file this hunk began, for error messages. */
+
+LINENUM
+pch_hunk_beg()
+{
+ return p_hunk_beg;
+}
+
+/* Apply an ed script by feeding ed itself. */
+
+#ifndef WIN32
+void
+do_ed_script()
+{
+ Reg1 char *t;
+ Reg2 long beginning_of_this_line;
+ Reg3 bool this_line_is_command = FALSE;
+ Reg4 FILE *pipefp;
+
+ if (!skip_rest_of_patch) {
+ Unlink(TMPOUTNAME);
+ copy_file(filearg[0], TMPOUTNAME);
+ if (verbose)
+ Sprintf(buf, "/bin/ed %s", TMPOUTNAME);
+ else
+ Sprintf(buf, "/bin/ed - %s", TMPOUTNAME);
+ pipefp = popen(buf, "w");
+ }
+ for (;;) {
+ beginning_of_this_line = ftell(pfp);
+ if (pgets(buf, sizeof buf, pfp) == Nullch) {
+ next_intuit_at(beginning_of_this_line,p_input_line);
+ break;
+ }
+ p_input_line++;
+ for (t=buf; isdigit(*t) || *t == ','; t++) ;
+ this_line_is_command = (isdigit(*buf) &&
+ (*t == 'd' || *t == 'c' || *t == 'a') );
+ if (this_line_is_command) {
+ if (!skip_rest_of_patch)
+ fputs(buf, pipefp);
+ if (*t != 'd') {
+ while (pgets(buf, sizeof buf, pfp) != Nullch) {
+ p_input_line++;
+ if (!skip_rest_of_patch)
+ fputs(buf, pipefp);
+ if (strEQ(buf, ".\n"))
+ break;
+ }
+ }
+ }
+ else {
+ next_intuit_at(beginning_of_this_line,p_input_line);
+ break;
+ }
+ }
+ if (skip_rest_of_patch)
+ return;
+ fprintf(pipefp, "w\n");
+ fprintf(pipefp, "q\n");
+ Fflush(pipefp);
+ Pclose(pipefp);
+ ignore_signals();
+ if (move_file(TMPOUTNAME, outname) < 0) {
+ toutkeep = TRUE;
+ chmod(TMPOUTNAME, filemode);
+ }
+ else
+ chmod(outname, filemode);
+ set_signals(1);
+}
+#endif
diff --git a/xc/util/patch/pch.h b/xc/util/patch/pch.h
new file mode 100644
index 000000000..3873f28a5
--- /dev/null
+++ b/xc/util/patch/pch.h
@@ -0,0 +1,38 @@
+/* oldHeader: pch.h,v 2.0.1.1 87/01/30 22:47:16 lwall Exp $
+ * $XConsortium: pch.h,v 3.3 94/09/14 21:24:15 gildea Exp $
+ *
+ * Revision 2.0.1.1 87/01/30 22:47:16 lwall
+ * Added do_ed_script().
+ *
+ * Revision 2.0 86/09/17 15:39:57 lwall
+ * Baseline for netwide release.
+ *
+ */
+
+EXT FILE *pfp INIT(Nullfp); /* patch file pointer */
+
+void re_patch();
+void open_patch_file();
+void set_hunkmax();
+void grow_hunkmax();
+bool there_is_another_patch();
+int intuit_diff_type();
+void next_intuit_at();
+void skip_to();
+bool another_hunk();
+bool pch_swap();
+char *pfetch();
+short pch_line_len();
+LINENUM pch_first();
+LINENUM pch_ptrn_lines();
+LINENUM pch_newfirst();
+LINENUM pch_repl_lines();
+LINENUM pch_end();
+LINENUM pch_context();
+LINENUM pch_hunk_beg();
+char pch_char();
+char *pfetch();
+char *pgets();
+#ifndef WIN32
+void do_ed_script();
+#endif
diff --git a/xc/util/patch/util.c b/xc/util/patch/util.c
new file mode 100644
index 000000000..ef70642a9
--- /dev/null
+++ b/xc/util/patch/util.c
@@ -0,0 +1,474 @@
+/* $XConsortium: util.c,v 3.3 94/09/14 21:26:09 gildea Exp $ */
+
+#define const /*nothing*/
+
+#include "EXTERN.h"
+#include "common.h"
+#include "INTERN.h"
+#include "util.h"
+#include "backupfile.h"
+
+void my_exit();
+
+static char *
+private_strerror (errnum)
+ int errnum;
+{
+ extern char *sys_errlist[];
+ extern int sys_nerr;
+
+ if (errnum > 0 && errnum <= sys_nerr)
+ return sys_errlist[errnum];
+ return "Unknown system error";
+}
+#define strerror private_strerror
+
+/* Rename a file, copying it if necessary. */
+
+int
+move_file(from,to)
+char *from, *to;
+{
+ char bakname[512];
+ Reg1 char *s;
+ Reg2 int i;
+ Reg3 int fromfd;
+
+ /* to stdout? */
+
+ if (strEQ(to, "-")) {
+#ifdef DEBUGGING
+ if (debug & 4)
+ say2("Moving %s to stdout.\n", from);
+#endif
+ fromfd = open(from, 0);
+ if (fromfd < 0)
+ pfatal2("internal error, can't reopen %s", from);
+ while ((i=read(fromfd, buf, sizeof buf)) > 0)
+ if (write(1, buf, i) != 1)
+ pfatal1("write failed");
+ Close(fromfd);
+ return 0;
+ }
+
+ if (origprae) {
+ Strcpy(bakname, origprae);
+ Strcat(bakname, to);
+ } else {
+#ifndef NODIR
+ char *backupname = find_backup_file_name(to);
+ if (backupname == (char *) 0)
+ fatal1("out of memory\n");
+ Strcpy(bakname, backupname);
+ free(backupname);
+#else /* NODIR */
+ Strcpy(bakname, to);
+ Strcat(bakname, simple_backup_suffix);
+#endif /* NODIR */
+ }
+
+ if (stat(to, &filestat) == 0) { /* output file exists */
+ dev_t to_device = filestat.st_dev;
+ ino_t to_inode = filestat.st_ino;
+ char *simplename = bakname;
+
+ for (s=bakname; *s; s++) {
+ if (*s == '/')
+ simplename = s+1;
+ }
+ /* Find a backup name that is not the same file.
+ Change the first lowercase char into uppercase;
+ if that isn't sufficient, chop off the first char and try again. */
+ while (stat(bakname, &filestat) == 0 &&
+ to_device == filestat.st_dev && to_inode == filestat.st_ino) {
+ /* Skip initial non-lowercase chars. */
+ for (s=simplename; *s && !islower(*s); s++) ;
+ if (*s)
+ *s = toupper(*s);
+ else
+ Strcpy(simplename, simplename+1);
+ }
+ while (unlink(bakname) >= 0) ; /* while() is for benefit of Eunice */
+#ifdef DEBUGGING
+ if (debug & 4)
+ say3("Moving %s to %s.\n", to, bakname);
+#endif
+#ifndef WIN32
+ if (link(to, bakname) < 0) {
+ /* Maybe `to' is a symlink into a different file system.
+ Copying replaces the symlink with a file; using rename
+ would be better. */
+ Reg4 int tofd;
+ Reg5 int bakfd;
+
+ bakfd = creat(bakname, 0666);
+ if (bakfd < 0) {
+ say4("Can't backup %s, output is in %s: %s\n", to, from,
+ strerror(errno));
+ return -1;
+ }
+ tofd = open(to, 0);
+ if (tofd < 0)
+ pfatal2("internal error, can't open %s", to);
+ while ((i=read(tofd, buf, sizeof buf)) > 0)
+ if (write(bakfd, buf, i) != i)
+ pfatal1("write failed");
+ Close(tofd);
+ Close(bakfd);
+ }
+#endif
+ while (unlink(to) >= 0) ;
+ }
+#ifdef DEBUGGING
+ if (debug & 4)
+ say3("Moving %s to %s.\n", from, to);
+#endif
+#ifndef WIN32
+ if (link(from, to) < 0) { /* different file system? */
+ Reg4 int tofd;
+
+ tofd = creat(to, 0666);
+ if (tofd < 0) {
+ say4("Can't create %s, output is in %s: %s\n",
+ to, from, strerror(errno));
+ return -1;
+ }
+ fromfd = open(from, 0);
+ if (fromfd < 0)
+ pfatal2("internal error, can't reopen %s", from);
+ while ((i=read(fromfd, buf, sizeof buf)) > 0)
+ if (write(tofd, buf, i) != i)
+ pfatal1("write failed");
+ Close(fromfd);
+ Close(tofd);
+ }
+ Unlink(from);
+#else
+ rename (from, to);
+#endif
+ return 0;
+}
+
+/* Copy a file. */
+
+void
+copy_file(from,to)
+char *from, *to;
+{
+ Reg3 int tofd;
+ Reg2 int fromfd;
+ Reg1 int i;
+
+ tofd = creat(to, 0666);
+ if (tofd < 0)
+ pfatal2("can't create %s", to);
+ fromfd = open(from, 0);
+ if (fromfd < 0)
+ pfatal2("internal error, can't reopen %s", from);
+ while ((i=read(fromfd, buf, sizeof buf)) > 0)
+ if (write(tofd, buf, i) != i)
+ pfatal2("write to %s failed", to);
+ Close(fromfd);
+ Close(tofd);
+}
+
+/* Allocate a unique area for a string. */
+
+char *
+savestr(s)
+Reg1 char *s;
+{
+ Reg3 char *rv;
+ Reg2 char *t;
+
+ if (!s)
+ s = "Oops";
+ t = s;
+ while (*t++);
+ rv = malloc((MEM) (t - s));
+ if (rv == Nullch) {
+ if (using_plan_a)
+ out_of_mem = TRUE;
+ else
+ fatal1("out of memory\n");
+ }
+ else {
+ t = rv;
+ while (*t++ = *s++);
+ }
+ return rv;
+}
+
+#if defined(lint) && defined(CANVARARG)
+
+/*VARARGS ARGSUSED*/
+say(pat) char *pat; { ; }
+/*VARARGS ARGSUSED*/
+fatal(pat) char *pat; { ; }
+/*VARARGS ARGSUSED*/
+pfatal(pat) char *pat; { ; }
+/*VARARGS ARGSUSED*/
+ask(pat) char *pat; { ; }
+
+#else
+
+/* Vanilla terminal output (buffered). */
+
+void
+say(pat,arg1,arg2,arg3)
+char *pat;
+long arg1,arg2,arg3;
+{
+ fprintf(stderr, pat, arg1, arg2, arg3);
+ Fflush(stderr);
+}
+
+/* Terminal output, pun intended. */
+
+void /* very void */
+fatal(pat,arg1,arg2,arg3)
+char *pat;
+long arg1,arg2,arg3;
+{
+ fprintf(stderr, "patch: **** ");
+ fprintf(stderr, pat, arg1, arg2, arg3);
+ my_exit(1);
+}
+
+/* Say something from patch, something from the system, then silence . . . */
+
+void /* very void */
+pfatal(pat,arg1,arg2,arg3)
+char *pat;
+long arg1,arg2,arg3;
+{
+ int errnum = errno;
+
+ fprintf(stderr, "patch: **** ");
+ fprintf(stderr, pat, arg1, arg2, arg3);
+ fprintf(stderr, ": %s\n", strerror(errnum));
+ my_exit(1);
+}
+
+/* Get a response from the user, somehow or other. */
+
+void
+ask(pat,arg1,arg2,arg3)
+char *pat;
+long arg1,arg2,arg3;
+{
+#ifndef WIN32
+ int ttyfd;
+ int r;
+ bool tty2 = isatty(2);
+
+ Sprintf(buf, pat, arg1, arg2, arg3);
+ Fflush(stderr);
+ write(2, buf, strlen(buf));
+ if (tty2) { /* might be redirected to a file */
+ r = read(2, buf, sizeof buf);
+ }
+ else if (isatty(1)) { /* this may be new file output */
+ Fflush(stdout);
+ write(1, buf, strlen(buf));
+ r = read(1, buf, sizeof buf);
+ }
+ else if ((ttyfd = open("/dev/tty", 2)) >= 0 && isatty(ttyfd)) {
+ /* might be deleted or unwriteable */
+ write(ttyfd, buf, strlen(buf));
+ r = read(ttyfd, buf, sizeof buf);
+ Close(ttyfd);
+ }
+ else if (isatty(0)) { /* this is probably patch input */
+ Fflush(stdin);
+ write(0, buf, strlen(buf));
+ r = read(0, buf, sizeof buf);
+ }
+ else { /* no terminal at all--default it */
+ buf[0] = '\n';
+ r = 1;
+ }
+ if (r <= 0)
+ buf[0] = 0;
+ else
+ buf[r] = '\0';
+ if (!tty2)
+ say1(buf);
+#else
+ buf[0] = '\n'; buf[1] = '\0';
+#endif
+}
+#endif /* lint */
+
+/* How to handle certain events when not in a critical region. */
+
+void
+set_signals(reset)
+int reset;
+{
+#ifndef lint
+#ifdef VOIDSIG
+ static void (*hupval)(),(*intval)();
+#else
+ static int (*hupval)(),(*intval)();
+#endif
+
+ if (!reset) {
+#ifndef WIN32
+ hupval = signal(SIGHUP, SIG_IGN);
+ if (hupval != SIG_IGN)
+#ifdef VOIDSIG
+ hupval = my_exit;
+#else
+ hupval = (int(*)())my_exit;
+#endif
+#endif
+ intval = signal(SIGINT, SIG_IGN);
+ if (intval != SIG_IGN)
+#ifdef VOIDSIG
+ intval = my_exit;
+#else
+ intval = (int(*)())my_exit;
+#endif
+ }
+#ifndef WIN32
+ Signal(SIGHUP, hupval);
+#endif
+ Signal(SIGINT, intval);
+#endif
+}
+
+/* How to handle certain events when in a critical region. */
+
+void
+ignore_signals()
+{
+#ifndef lint
+#ifndef WIN32
+ Signal(SIGHUP, SIG_IGN);
+#endif
+ Signal(SIGINT, SIG_IGN);
+#endif
+}
+
+/* Make sure we'll have the directories to create a file.
+ If `striplast' is TRUE, ignore the last element of `filename'. */
+
+void
+makedirs(filename,striplast)
+Reg1 char *filename;
+bool striplast;
+{
+ char tmpbuf[256];
+ Reg2 char *s = tmpbuf;
+ char *dirv[20]; /* Point to the NULs between elements. */
+ Reg3 int i;
+ Reg4 int dirvp = 0; /* Number of finished entries in dirv. */
+
+ /* Copy `filename' into `tmpbuf' with a NUL instead of a slash
+ between the directories. */
+ while (*filename) {
+ if (*filename == '/') {
+ filename++;
+ dirv[dirvp++] = s;
+ *s++ = '\0';
+ }
+ else {
+ *s++ = *filename++;
+ }
+ }
+ *s = '\0';
+ dirv[dirvp] = s;
+ if (striplast)
+ dirvp--;
+ if (dirvp < 0)
+ return;
+
+ strcpy(buf, "mkdir");
+ s = buf;
+ for (i=0; i<=dirvp; i++) {
+ struct stat sbuf;
+
+ if (stat(tmpbuf, &sbuf) && errno == ENOENT) {
+ while (*s) s++;
+ *s++ = ' ';
+ strcpy(s, tmpbuf);
+ }
+#ifndef WIN32
+ *dirv[i] = '/';
+#else
+ *dirv[i] = '\\';
+#endif
+ }
+ if (s != buf)
+ system(buf);
+}
+
+/* Make filenames more reasonable. */
+
+char *
+fetchname(at,strip_leading,assume_exists)
+char *at;
+int strip_leading;
+int assume_exists;
+{
+ char *fullname;
+ char *name;
+ Reg1 char *t;
+ char tmpbuf[200];
+ int sleading = strip_leading;
+
+ if (!at)
+ return Nullch;
+ while (isspace(*at))
+ at++;
+#ifdef DEBUGGING
+ if (debug & 128)
+ say4("fetchname %s %d %d\n",at,strip_leading,assume_exists);
+#endif
+ if (strnEQ(at, "/dev/null", 9)) /* so files can be created by diffing */
+ return Nullch; /* against /dev/null. */
+ name = fullname = t = savestr(at);
+
+ /* Strip off up to `sleading' leading slashes and null terminate. */
+ for (; *t && !isspace(*t); t++)
+ if (*t == '/')
+ if (--sleading >= 0)
+ name = t+1;
+ *t = '\0';
+
+ /* If no -p option was given (957 is the default value!),
+ we were given a relative pathname,
+ and the leading directories that we just stripped off all exist,
+ put them back on. */
+ if (strip_leading == 957 && name != fullname && *fullname != '/') {
+ name[-1] = '\0';
+ if (stat(fullname, &filestat) == 0 && S_ISDIR (filestat.st_mode)) {
+ name[-1] = '/';
+ name=fullname;
+ }
+ }
+
+ name = savestr(name);
+ free(fullname);
+
+ if (stat(name, &filestat) && !assume_exists) {
+ char *filebase = basename(name);
+ int pathlen = filebase - name;
+
+ /* Put any leading path into `tmpbuf'. */
+ strncpy(tmpbuf, name, pathlen);
+
+#define try(f, a1, a2) (Sprintf(tmpbuf + pathlen, f, a1, a2), stat(tmpbuf, &filestat) == 0)
+ if ( try("RCS/%s%s", filebase, RCSSUFFIX)
+ || try("RCS/%s" , filebase, 0)
+ || try( "%s%s", filebase, RCSSUFFIX)
+ || try("SCCS/%s%s", SCCSPREFIX, filebase)
+ || try( "%s%s", SCCSPREFIX, filebase))
+ return name;
+ free(name);
+ name = Nullch;
+ }
+
+ return name;
+}
diff --git a/xc/util/patch/util.h b/xc/util/patch/util.h
new file mode 100644
index 000000000..ad385c30c
--- /dev/null
+++ b/xc/util/patch/util.h
@@ -0,0 +1,88 @@
+/* oldHeader: util.h,v 2.0 86/09/17 15:40:06 lwall Exp $
+ * $XConsortium: util.h,v 2.1 94/09/09 20:04:28 gildea Exp $
+ *
+ * Revision 2.0 86/09/17 15:40:06 lwall
+ * Baseline for netwide release.
+ *
+ */
+
+/* and for those machine that can't handle a variable argument list */
+
+#ifdef CANVARARG
+
+#define say1 say
+#define say2 say
+#define say3 say
+#define say4 say
+#define ask1 ask
+#define ask2 ask
+#define ask3 ask
+#define ask4 ask
+#define fatal1 fatal
+#define fatal2 fatal
+#define fatal3 fatal
+#define fatal4 fatal
+#define pfatal1 pfatal
+#define pfatal2 pfatal
+#define pfatal3 pfatal
+#define pfatal4 pfatal
+
+#else /* hope they allow multi-line macro actual arguments */
+
+#ifdef lint
+
+#define say1(a) say(a, 0, 0, 0)
+#define say2(a,b) say(a, (b)==(b), 0, 0)
+#define say3(a,b,c) say(a, (b)==(b), (c)==(c), 0)
+#define say4(a,b,c,d) say(a, (b)==(b), (c)==(c), (d)==(d))
+#define ask1(a) ask(a, 0, 0, 0)
+#define ask2(a,b) ask(a, (b)==(b), 0, 0)
+#define ask3(a,b,c) ask(a, (b)==(b), (c)==(c), 0)
+#define ask4(a,b,c,d) ask(a, (b)==(b), (c)==(c), (d)==(d))
+#define fatal1(a) fatal(a, 0, 0, 0)
+#define fatal2(a,b) fatal(a, (b)==(b), 0, 0)
+#define fatal3(a,b,c) fatal(a, (b)==(b), (c)==(c), 0)
+#define fatal4(a,b,c,d) fatal(a, (b)==(b), (c)==(c), (d)==(d))
+#define pfatal1(a) pfatal(a, 0, 0, 0)
+#define pfatal2(a,b) pfatal(a, (b)==(b), 0, 0)
+#define pfatal3(a,b,c) pfatal(a, (b)==(b), (c)==(c), 0)
+#define pfatal4(a,b,c,d) pfatal(a, (b)==(b), (c)==(c), (d)==(d))
+
+#else /* lint */
+ /* if this doesn't work, try defining CANVARARG above */
+#define say1(a) say(a, Nullch, Nullch, Nullch)
+#define say2(a,b) say(a, b, Nullch, Nullch)
+#define say3(a,b,c) say(a, b, c, Nullch)
+#define say4 say
+#define ask1(a) ask(a, Nullch, Nullch, Nullch)
+#define ask2(a,b) ask(a, b, Nullch, Nullch)
+#define ask3(a,b,c) ask(a, b, c, Nullch)
+#define ask4 ask
+#define fatal1(a) fatal(a, Nullch, Nullch, Nullch)
+#define fatal2(a,b) fatal(a, b, Nullch, Nullch)
+#define fatal3(a,b,c) fatal(a, b, c, Nullch)
+#define fatal4 fatal
+#define pfatal1(a) pfatal(a, Nullch, Nullch, Nullch)
+#define pfatal2(a,b) pfatal(a, b, Nullch, Nullch)
+#define pfatal3(a,b,c) pfatal(a, b, c, Nullch)
+#define pfatal4 pfatal
+
+#endif /* lint */
+
+/* if neither of the above work, join all multi-line macro calls. */
+#endif
+
+EXT char serrbuf[BUFSIZ]; /* buffer for stderr */
+
+char *fetchname();
+int move_file();
+void copy_file();
+void say();
+void fatal();
+void pfatal();
+void ask();
+char *savestr();
+void set_signals();
+void ignore_signals();
+void makedirs();
+char *basename();
diff --git a/xc/util/patch/version.c b/xc/util/patch/version.c
new file mode 100644
index 000000000..86e86842a
--- /dev/null
+++ b/xc/util/patch/version.c
@@ -0,0 +1,25 @@
+/* oldHeader: version.c,v 2.0 86/09/17 15:40:11 lwall Exp $
+ * $XConsortium: version.c,v 2.1 94/09/09 20:04:28 gildea Exp $
+ *
+ * Revision 2.0 86/09/17 15:40:11 lwall
+ * Baseline for netwide release.
+ *
+ */
+
+#include "EXTERN.h"
+#include "common.h"
+#include "util.h"
+#include "INTERN.h"
+#include "patchlevel.h"
+#include "version.h"
+
+void my_exit();
+
+/* Print out the version number and die. */
+
+void
+version()
+{
+ fprintf(stderr, "Patch version 2.0, patch level %s\n", PATCHLEVEL);
+ my_exit(0);
+}
diff --git a/xc/util/patch/version.h b/xc/util/patch/version.h
new file mode 100644
index 000000000..bc249e0f8
--- /dev/null
+++ b/xc/util/patch/version.h
@@ -0,0 +1,9 @@
+/* oldHeader: version.h,v 2.0 86/09/17 15:40:14 lwall Exp $
+ * $XConsortium: version.h,v 2.1 94/09/09 20:04:28 gildea Exp $
+ *
+ * Revision 2.0 86/09/17 15:40:14 lwall
+ * Baseline for netwide release.
+ *
+ */
+
+void version();
diff --git a/xc/util/patch/winnt.h b/xc/util/patch/winnt.h
new file mode 100644
index 000000000..3f45159f0
--- /dev/null
+++ b/xc/util/patch/winnt.h
@@ -0,0 +1,25 @@
+
+/* $XConsortium: winnt.h,v 1.1 94/09/09 20:27:49 kaleb Exp $ */
+
+
+#define stat _stat
+#define dev_t _dev_t
+#define ino_t _ino_t
+#define chdir _chdir
+#define chmod(p1,p2) _chmod(p1,_S_IWRITE)
+#define open _open
+#define close _close
+#define creat(p1,p2) _creat(p1,_S_IWRITE)
+#define fileno _fileno
+#define fstat _fstat
+#define isatty _isatty
+#define lseek _lseek
+#define mktemp _mktemp
+#define pclose _pclose
+#define popen _popen
+#define read _read
+#define write _write
+#define unlink _unlink
+#define sys_errlist _sys_errlist
+#define sys_nerr (*_sys_nerr_dll)
+